snd-16.1/0000755000076400007640000000000012626170361010337 5ustar bilbilsnd-16.1/DotEmacs0000644000076400007640000001636512306421672011773 0ustar bilbil;;; DotEmacs Version 1.0 ;;; Copyright 2001 Fernando Lopez-Lezcano ;;; Tested under RedHat Linux 7.0 (rpm: xemacs-21.1.14-2.7): ;;; xemacs 21.1 patch 14, ilisp 5.10.1 ;;; ;;; this .emacs file should work correctly with the PlanetCCRMA ;;; cm/clm/cmn rpms and should autodetect which binary rpm has ;;; been installed, setting the correct path for executing it. ;;; Getting all this work has been a REAL pain, most of the time ;;; trying to interpret emacs lisp code in the ilisp module... ;;; ;;; Todo: more key bindings should be local for the buffer, this ;;; is a problem when using several lisps concurrently... ;;; For standard gnu emacs and Xemacs ;;; figure out which flavor we are running (defvar xemacs-flavor (string-match "XEmacs\\|Lucid" emacs-version)) ;;; For Xemacs only (cond (xemacs-flavor ;; if you always want partial minibuffer completion (require 'completer) ;; configuration of Erik Naggum's HyperSpec access package. (setq common-lisp-hyperspec-root "file:/usr/lib/lisp/reference/HyperSpec/") ;; don't send output to a separate frame (setq ilisp-*use-frame-for-output* nil) ;; arglist will end up on minibuffer (setq ilisp-*use-frame-for-arglist-output-p* nil) ;; no message on startup (setq ilisp-motd nil) ;; activate fsf keybindings (setq ilisp-*use-fsf-compliant-keybindings* t) ;; initialization and load hooks (add-hook 'ilisp-load-hook '(lambda () ;; Change default key prefix to C-c (setq ilisp-*prefix* "\C-c") ;; do not do arglist expansion by default ;; necessary to avoid errors on .lisp buffers ;; (define-key ilisp-mode-map " " 'self-insert-command) ;; output to minibuffer for arglist expansion (setq lisp-no-popper t) ;; by default disable arglist expansion on #\\Space (setq ilisp-*arglist-message-lisp-space-p* nil))) (add-hook 'ilisp-mode-hook '(lambda ())) ;; HACK: we set window-system to nil temporarily while we load ilisp ;; so that it does not create extra frames for its output. There is ;; currently no way to turn this off with configuration variables ;; for ilisp 5.10.1 (AFAIK). The code for the output functions is in: ;; /usr/lib/xemacs/xemacs-packages/lisp/ilisp/ilis-out.el (let ((window-system nil)) ;; now we load ilisp, we need it active to define our dialects (require 'ilisp)) ;; define a dialect for Snd's guile interpreter (defdialect snd "Snd" guile (setq comint-prompt-regexp "^>+") (setq ilisp-complete-command nil) ;; try to autodetect the binary (unless snd-program (cond ((file-executable-p "/usr/bin/snd") (setq snd-program "/usr/bin/snd")) (t (setq snd-program "snd"))))) (add-hook 'snd-hook (lambda () )) ;; if you have the binary somewhere else: ;; (setq snd-program "snd") ;; define a dialect for CM/CLM/CMN (under allegro common lisp) (defdialect acl "AclLisp" allegro ;; try to autodetect the binary (at ccrma) (unless acl-program (cond ;;((file-executable-p "/usr/ccrma/lbin/cm2-clm2") ;; (setq acl-program "/usr/ccrma/lbin/cm2-clm2")) ((file-executable-p "/usr/ccrma/lbin/acl5.0") (setq acl-program "/usr/ccrma/lbin/acl5.0")) (t (setq acl-program "cm2-clm2"))))) (add-hook 'acl-hook (lambda () ;; the following is necessary so that we can have separate ;; keymaps for snd and other lisps, if we run them concurrently ;; we need to have some local (to the buffer) key bindings. (make-local-variable 'overriding-local-map) (setq overriding-local-map (copy-keymap ilisp-mode-map)) (define-key overriding-local-map " " 'ilisp-arglist-message-lisp-space) ;; enable arglist expansion on this buffer (make-local-variable 'ilisp-*arglist-message-lisp-space-p*) (setq ilisp-*arglist-message-lisp-space-p* t))) ;; if you have the binary somewhere else ;; (setq acl-program "/usr/ccrma/lbin/cm2-clm2") ;; define a dialect for CmuCL; ;; we need to patch the cmuclisp.lisp init file including CMU18 in the ;; #+ #- switches if we want the symbol description to work correctly, ;; see /usr/lib/xemacs/xemacs-packages/lisp/ilisp/cmulisp.lisp (defdialect cmucl "CmuLisp" cmulisp ;; set the correct file name (setq ilisp-cmulisp-init-file "cmulisp.lisp") ;; try to autodetect the binary (unless cmucl-program (cond ((file-executable-p "/usr/bin/cmucl-cm-clm-cmn") (setq cmucl-program "/usr/bin/cmucl-cm-clm-cmn")) ((file-executable-p "/usr/bin/cmucl-cm-clm") (setq cmucl-program "/usr/bin/cmucl-cm-clm")) ((file-executable-p "/usr/bin/cmucl-clm") (setq cmucl-program "/usr/bin/cmucl-clm")) (t (setq cmucl-program "lisp"))))) (add-hook 'cmucl-hook (lambda () (make-local-variable 'overriding-local-map) (setq overriding-local-map (copy-keymap ilisp-mode-map)) (define-key overriding-local-map " " 'ilisp-arglist-message-lisp-space) ;; enable arglist expansion on this buffer (make-local-variable 'ilisp-*arglist-message-lisp-space-p*) (setq ilisp-*arglist-message-lisp-space-p* t))) ;; if you have the binary somewhere else: ;; (setq cmucl-program "lisp") ;; define a dialect for Clisp (defdialect clisp "CLisp" clisp-hs ;; try to autodetect the binary (unless clisp-program (cond ((file-executable-p "/usr/bin/clisp-cm-clm-cmn") (setq clisp-program "/usr/bin/clisp-cm-clm-cmn")) ((file-executable-p "/usr/bin/clisp-cm-clm") (setq clisp-program "/usr/bin/clisp-cm-clm")) ((file-executable-p "/usr/bin/clisp-clm") (setq clisp-program "/usr/bin/clisp-clm")) (t (setq clisp-program "clisp"))))) (add-hook 'clisp-hook (lambda () (make-local-variable 'overriding-local-map) (setq overriding-local-map (copy-keymap ilisp-mode-map)) (define-key overriding-local-map " " 'ilisp-arglist-message-lisp-space) ;; enable arglist expansion on this buffer (make-local-variable 'ilisp-*arglist-message-lisp-space-p*) (setq ilisp-*arglist-message-lisp-space-p* t))) ;; if you have the binary somewhere else: ;; (setq clisp-program "clisp") ;; Bind acl startup (global-set-key "\C-x\C-l" 'acl) (global-set-key "\C-x\L" 'acl) )) ;;; End Xemacs customization snd-16.1/env.scm0000644000076400007640000004504712623712467011653 0ustar bilbil;;; various envelope functions ;;; ;;; window-envelope (beg end env) -> portion of env lying between x axis values beg and end ;;; map-envelopes (func env1 env2) maps func over the breakpoints in env1 and env2 returning a new envelope ;;; multiply-envelopes (env1 env2) multiplies break-points of env1 and env2 returning a new envelope ;;; add-envelopes (env1 env2) adds break-points of env1 and env2 returning a new envelope ;;; max-envelope (env) -> max y value in env, min-envelope ;;; integrate-envelope (env) -> area under env ;;; envelope-last-x (env) -> max x axis break point position ;;; stretch-envelope env old-attack new-attack old-decay new-decay -> divseg-like envelope mangler ;;; scale-envelope (env scaler offset) scales y axis values by 'scaler' and optionally adds 'offset' ;;; reverse-envelope (env) reverses the breakpoints in 'env' ;;; concatenate-envelopes (:rest envs) concatenates its arguments into a new envelope ;;; repeat-envelope env repeats (reflected #f) (normalized #f) repeats an envelope ;;; power-env: generator for extended envelopes (each segment has its own base) ;;; envelope-exp: interpolate segments into envelope to give exponential curves ;;; rms-envelope ;;; normalize-envelope ;;; simplify-envelope (provide 'snd-env.scm) ;;; -------- window-envelope (a kinda brute-force translation from the CL version in env.lisp) (define window-envelope (let ((documentation "(window-envelope beg end e) -> portion of e lying between x axis values beg and end: (window-envelope 1.0 3.0 '(0.0 0.0 5.0 1.0)) -> '(1.0 0.2 3.0 0.6)")) (lambda (beg end e) (let ((nenv ()) (lasty (if e (cadr e) 0.0)) (len (length e))) (call-with-exit (lambda (return-early) (do ((i 0 (+ i 2))) ((>= i len)) (let ((x (e i)) (y (e (+ i 1)))) (set! lasty y) (if (null? nenv) (if (>= x beg) (begin (set! nenv (append nenv (list beg (envelope-interp beg e)))) (if (not (= x beg)) (if (>= x end) (return-early (append nenv (list end (envelope-interp end e)))) (set! nenv (append nenv (list x y))))))) (if (<= x end) (begin (set! nenv (append nenv (list x y))) (if (= x end) (return-early nenv))) (if (> x end) (return-early (append nenv (list end (envelope-interp end e))))))))) (append nenv (list end lasty)))))))) ;;; -------- map-envelopes like map-across-envelopes in env.lisp (define map-envelopes (let ((documentation "(map-envelopes func env1 env2) maps func over the breakpoints in env1 and env2 returning a new envelope")) (lambda (op e1 e2) (let ((xs ())) (letrec ((at0 (lambda (e) (let* ((diff (car e)) (len (length e)) (lastx (e (- len 2))) (newe (copy e))) (do ((i 0 (+ i 2))) ((>= i len) newe) (let ((x (/ (- (newe i) diff) lastx))) (set! xs (cons x xs)) (set! (newe i) x)))))) (remove-duplicates (lambda (lst) (letrec ((rem-dup (lambda (lst nlst) (cond ((null? lst) nlst) ((member (car lst) nlst) (rem-dup (cdr lst) nlst)) (else (rem-dup (cdr lst) (cons (car lst) nlst))))))) (rem-dup lst ()))))) (if (null? e1) (at0 e2) (if (null? e2) (at0 e1) (let ((ee1 (at0 e1)) (ee2 (at0 e2)) (newe ())) (set! xs (sort! (remove-duplicates xs) <)) (let ((len (length xs))) (do ((i 0 (+ i 1))) ((= i len)) (let ((x (xs i))) (set! newe (append newe (list x (op (envelope-interp x ee1) (envelope-interp x ee2))))))) newe))))))))) ;;; -------- multiply-envelopes, add-envelopes (define multiply-envelopes (let ((documentation "(multiply-envelopes env1 env2) multiplies break-points of env1 and env2 returning a new envelope: (multiply-envelopes '(0 0 2 .5) '(0 0 1 2 2 1)) -> '(0 0 0.5 0.5 1.0 0.5)")) (lambda (e1 e2) (map-envelopes * e1 e2)))) (define add-envelopes (let ((documentation "(add-envelopes env1 env2) adds break-points of env1 and env2 returning a new envelope")) (lambda (e1 e2) (map-envelopes + e1 e2)))) ;;; -------- max-envelope (define max-envelope (let ((documentation "(max-envelope env) -> max y value in env")) (lambda (env1) (define (max-envelope-1 e mx) (if (null? e) mx (max-envelope-1 (cddr e) (max mx (cadr e))))) (max-envelope-1 (cddr env1) (cadr env1))))) ;;; -------- min-envelope (define min-envelope (let ((documentation "(min-envelope env) -> min y value in env")) (lambda (env1) (define (min-envelope-1 e mx) (if (null? e) mx (min-envelope-1 (cddr e) (min mx (cadr e))))) (min-envelope-1 (cddr env1) (cadr env1))))) ;;; -------- integrate-envelope (define integrate-envelope (let ((documentation "(integrate-envelope env) -> area under env")) (lambda (env1) (define (integrate-envelope-1 e sum) (if (or (null? e) (null? (cddr e))) sum (integrate-envelope-1 (cddr e) (+ sum (* (+ (cadr e) (cadddr e)) .5 (- (caddr e) (car e))))))) (integrate-envelope-1 env1 0.0)))) ;;; -------- envelope-last-x (define envelope-last-x (let ((documentation "(envelope-last-x env) -> max x axis break point position")) (lambda (e) (if (null? (cddr e)) (car e) (envelope-last-x (cddr e)))))) ;;; -------- stretch-envelope (define stretch-envelope (let ((documentation "(stretch-envelope env old-attack new-attack old-decay new-decay) takes 'env' and returns a new envelope based on it but with the attack and optionally decay portions stretched or squeezed; 'old-attack' is the original x axis attack end point, 'new-attack' is where that section should end in the new envelope. Similarly for 'old-decay' and 'new-decay'. This mimics divseg in early versions of CLM and its antecedents in Sambox and Mus10 (linen). (stretch-envelope '(0 0 1 1) .1 .2) -> (0 0 0.2 0.1 1.0 1) (stretch-envelope '(0 0 1 1 2 0) .1 .2 1.5 1.6) -> (0 0 0.2 0.1 1.1 1 1.6 0.5 2.0 0)")) (lambda* (fn old-att new-att old-dec new-dec) (if (and old-att (not new-att)) (error 'wrong-number-of-args (list "stretch-envelope" old-att "old-attack but no new-attack?")) (if (not new-att) fn (if (and old-dec (not new-dec)) (error 'wrong-number-of-args (list "stretch-envelope" old-att new-att old-dec "old-decay but no new-decay?")) (let* ((x0 (car fn)) (new-x x0) (last-x (fn (- (length fn) 2))) (y0 (cadr fn)) (new-fn (list y0 x0)) (scl (/ (- new-att x0) (max .0001 (- old-att x0))))) (define (stretch-envelope-1 new-fn old-fn) (if (null? old-fn) new-fn (let ((x1 (car old-fn)) (y1 (cadr old-fn))) (if (and (< x0 old-att) (>= x1 old-att)) (begin (if (= x1 old-att) (set! y0 y1) (set! y0 (+ y0 (* (- y1 y0) (/ (- old-att x0) (- x1 x0)))))) (set! x0 old-att) (set! new-x new-att) (set! new-fn (cons y0 (cons new-x new-fn))) (set! scl (if old-dec (/ (- new-dec new-att) (- old-dec old-att)) (/ (- last-x new-att) (- last-x old-att)))))) (if (and old-dec (< x0 old-dec) (>= x1 old-dec)) (begin (if (= x1 old-dec) (set! y0 y1) (set! y0 (+ y0 (* (- y1 y0) (/ (- old-dec x0) (- x1 x0)))))) (set! x0 old-dec) (set! new-x new-dec) (set! new-fn (cons y0 (cons new-x new-fn))) (set! scl (/ (- last-x new-dec) (- last-x old-dec))))) (if (not (= x0 x1)) (begin (set! new-x (+ new-x (* scl (- x1 x0)))) (set! new-fn (cons y1 (cons new-x new-fn))) (set! x0 x1) (set! y0 y1))) (stretch-envelope-1 new-fn (cddr old-fn))))) (if (and old-dec (= old-dec old-att)) (set! old-dec (* .000001 last-x))) (reverse (stretch-envelope-1 new-fn (cddr fn)))))))))) ;;; -------- scale-envelope (define scale-envelope (let ((documentation "(scale-envelope env scaler (offset 0)) scales y axis values by 'scaler' and optionally adds 'offset'")) (lambda* (e scl (offset 0)) (if (null? e) () (append (list (car e) (+ offset (* scl (cadr e)))) (scale-envelope (cddr e) scl offset)))))) ;;; -------- reverse-envelope (define reverse-envelope (let ((documentation "(reverse-envelope env) reverses the breakpoints in 'env'")) (lambda (e) (define (reverse-env-1 e newe xd) (if (null? e) newe (reverse-env-1 (cddr e) (cons (- xd (car e)) (cons (cadr e) newe)) xd))) (let ((len (length e))) (if (memv len '(0 2)) e (let ((xmax (e (- len 2)))) (reverse-env-1 e () xmax))))))) ;;; -------- concatenate-envelopes (define concatenate-envelopes (let ((documentation "(concatenate-envelopes :rest envs) concatenates its arguments into a new envelope")) (lambda envs (define (cat-1 e newe xoff x0) (if (null? e) newe (cat-1 (cddr e) (cons (cadr e) (cons (+ (- (car e) x0) xoff) newe)) xoff x0))) (let ((ne ()) (xoff 0.0)) (for-each (lambda (e) (if (and (pair? ne) (= (car ne) (cadr e))) (begin (set! xoff (- xoff .01)) (set! ne (cat-1 (cddr e) ne xoff (car e)))) (set! ne (cat-1 e ne xoff (car e)))) (set! xoff (+ xoff .01 (cadr ne)))) envs) (reverse ne))))) (define repeat-envelope (let ((documentation "(repeat-envelope env repeats (reflected #f) (normalized #f)) repeats 'env' 'repeats' times. (repeat-envelope '(0 0 100 1) 2) -> (0 0 100 1 101 0 201 1). If the final y value is different from the first y value, a quick ramp is inserted between repeats. 'normalized' causes the new envelope's x axis to have the same extent as the original's. 'reflected' causes every other repetition to be in reverse.")) (lambda* (ur-env repeats reflected normalized) (let* ((times (if reflected (floor (/ repeats 2)) repeats)) (e (if reflected (let ((lastx (ur-env (- (length ur-env) 2))) (rev-env (cddr (reverse ur-env))) (new-env (reverse ur-env))) (while (pair? rev-env) (set! new-env (cons (+ lastx (- lastx (cadr rev-env))) new-env)) (set! new-env (cons (car rev-env) new-env)) (set! rev-env (cddr rev-env))) (reverse new-env)) ur-env)) (first-y (cadr e)) (x-max (e (- (length e) 2))) (x (car e)) (first-y-is-last-y (= first-y (e (- (length e) 1)))) (new-env (list first-y x)) (len (length e))) (do ((i 0 (+ i 1))) ((= i times)) (do ((j 2 (+ j 2))) ((>= j len)) (set! x (+ x (- (e j) (e (- j 2))))) (set! new-env (cons (e (+ j 1)) (cons x new-env)))) (if (and (< i (- times 1)) (not first-y-is-last-y)) (begin (set! x (+ x (/ x-max 100.0))) (set! new-env (cons first-y (cons x new-env)))))) (set! new-env (reverse new-env)) (if normalized (let ((scl (/ x-max x)) (new-len (length new-env))) (do ((i 0 (+ i 2))) ((>= i new-len)) (set! (new-env i) (* scl (new-env i)))))) new-env)))) ;;; -------- power-env ;;; ;;; (this could also be done using multi-expt-env (based on env-any) in generators.scm) (if (provided? 'snd) (require snd-ws.scm) (require sndlib-ws.scm)) ;;; (define pe (make-power-env '(0 0 1 1 2 0) :duration 1.0)) ;;; :(power-env pe) ;;; 0.0 ;;; :(power-env pe) ;;; 4.5352502324316e-05 ;;; :(power-env pe) ;;; 9.0705004648631e-05 ;;; :(power-env pe) ;;; 0.00013605750697295 (defgenerator penv (envs #f) (total-envs 0) (current-env 0) (current-pass 0)) (define (power-env pe) (with-let pe (let ((val (env (vector-ref envs current-env)))) (set! current-pass (- current-pass 1)) (when (and (= current-pass 0) (< current-env (- total-envs 1))) (set! current-env (+ current-env 1)) (set! current-pass (- (length (vector-ref envs current-env)) 1))) val))) (define* (make-power-env envelope (scaler 1.0) (offset 0.0) duration) (let* ((len (- (floor (/ (length envelope) 3)) 1)) (pe (make-penv :envs (make-vector len) :total-envs len :current-env 0 :current-pass 0)) (xext (- (envelope (- (length envelope) 3)) (car envelope)))) (do ((i 0 (+ i 1)) (j 0 (+ j 3))) ((= i len)) (let ((x0 (envelope j)) (x1 (envelope (+ j 3))) (y0 (envelope (+ j 1))) (y1 (envelope (+ j 4))) (base (envelope (+ j 2)))) (vector-set! (pe 'envs) i (make-env (list 0.0 y0 1.0 y1) :base base :scaler scaler :offset offset :duration (* duration (/ (- x1 x0) xext)))))) (set! (pe 'current-pass) (- (length (vector-ref (pe 'envs) 0)) 1)) pe)) (define* (power-env-channel pe (beg 0) snd chn edpos (edname "power-env-channel")) ;; split into successive calls on env-channel (let ((curbeg beg)) ; sample number (as-one-edit (lambda () (do ((i 0 (+ i 1))) ((= i (pe 'total-envs))) (let* ((e (vector-ref (pe 'envs) i)) (len (length e))) (env-channel e curbeg len snd chn edpos) (set! curbeg (+ curbeg len))))) edname))) ;;; here's a simpler version that takes the breakpoint list, rather than the power-env structure: (define powenv-channel (let ((documentation "(powenv-channel envelope (beg 0) dur snd chn edpos) returns an envelope with a separate base for \ each segment: (powenv-channel '(0 0 .325 1 1 32.0 2 0 32.0))")) (lambda* (envelope (beg 0) dur snd chn edpos) (let* ((curbeg beg) (fulldur (or dur (framples snd chn edpos))) (len (length envelope)) (x1 (car envelope)) (xrange (- (envelope (- len 3)) x1)) (y1 (cadr envelope)) (base (caddr envelope)) (x0 0.0) (y0 0.0)) (if (= len 3) (scale-channel y1 beg dur snd chn edpos) (as-one-edit (lambda () (do ((i 3 (+ i 3))) ((= i len)) (set! x0 x1) (set! y0 y1) (set! x1 (envelope i)) (set! y1 (envelope (+ i 1))) (let ((curdur (round (* fulldur (/ (- x1 x0) xrange))))) (xramp-channel y0 y1 base curbeg curdur snd chn edpos) (set! curbeg (+ curbeg curdur))) (set! base (envelope (+ i 2))))))))))) ;;; by Anders Vinjar: ;;; ;;; envelope-exp can be used to create exponential segments to include in ;;; envelopes. Given 2 or more breakpoints, it approximates the ;;; curve between them using 'xgrid linesegments and 'power as the ;;; exponent. ;;; ;;; env is a list of x-y-breakpoint-pairs, ;;; power applies to whole envelope, ;;; xgrid is how fine a solution to sample our new envelope with. (define envelope-exp (let ((documentation "(envelope-exp e (power 1.0) (xgrid 100)) approximates an exponential curve connecting the breakpoints")) (lambda* (e (power 1.0) (xgrid 100)) (let* ((mn (min-envelope e)) (largest-diff (* 1.0 (- (max-envelope e) mn))) (x-min (car e)) (len (length e)) (x-max (e (- len 2))) (x-incr (* 1.0 (/ (- x-max x-min) xgrid))) (new-e ())) (do ((x x-min (+ x x-incr))) ((>= x x-max)) (let ((y (envelope-interp x e))) (set! new-e (cons (if (= largest-diff 0.0) y (+ mn (* largest-diff (expt (/ (- y mn) largest-diff) power)))) (cons x new-e))))) (reverse new-e))))) ;;; rms-envelope (define rms-envelope (let ((documentation "(rms-envelope file (beg 0.0) (dur #f) (rfreq 30.0) (db #f)) returns an envelope of RMS values in 'file'")) (lambda* (file (beg 0.0) dur (rfreq 30.0) db) ;; based on rmsenv.ins by Bret Battey (let* ((e ()) (incr (/ 1.0 rfreq)) (fsr (srate file)) (incrsamps (round (* incr fsr))) (start (round (* beg fsr))) (reader (make-sampler start file)) (end (if dur (min (* 1.0 (+ start (round (* fsr dur)))) (mus-sound-framples file)) (mus-sound-framples file))) (rms (make-moving-average incrsamps)) ; this could use make-moving-rms from dsp.scm (rms-val 0.0) (jend 0)) (let* ((len (+ 1 (- end start))) (data (make-float-vector len))) (do ((i 0 (+ i 1))) ((= i len)) (float-vector-set! data i (next-sample reader))) (float-vector-multiply! data data) (do ((i 0 (+ i incrsamps))) ((>= i end) (reverse e)) (set! jend (min end (+ i incrsamps))) (do ((j i (+ j 1))) ((= j jend)) (moving-average rms (float-vector-ref data j))) (set! e (cons (* 1.0 (/ i fsr)) e)) (set! rms-val (sqrt (* (mus-scaler rms) (mus-increment rms)))) (if db (if (< rms-val .00001) (set! e (cons -100.0 e)) (set! e (cons (* 20.0 (log rms-val 10.0)) e))) (set! e (cons rms-val e))))))))) (define* (normalize-envelope env1 (new-max 1.0)) (define (abs-max-envelope-1 e mx) (if (null? e) mx (abs-max-envelope-1 (cddr e) (max mx (abs (cadr e)))))) (let ((peak (abs-max-envelope-1 (cddr env1) (abs (cadr env1))))) (scale-envelope env1 (/ new-max peak)))) ;;; simplify-envelope ;;; ;;; this is not very good... (define* (simplify-envelope env1 (ygrid 10) (xgrid 100)) ;; grid = how fine a fluctuation we will allow. ;; the smaller the grid, the less likely a given bump will get through ;; original x and y values are not changed, just sometimes omitted. (define (point-on-line? px py qx qy tx ty) ;; is point tx ty on line defined by px py and qx qy -- ;; #f if no, :before if on ray from p, :after if on ray from q, :within if between p and q ;; (these are looking at the "line" as a fat vector drawn on a grid) ;; taken from "Graphics Gems" by Glassner, code by A Paeth (if (or (= py qy ty) (= px qx tx)) :within (and (< (abs (- (* (- qy py) (- tx px)) (* (- ty py) (- qx px)))) (max (abs (- qx px)) (abs (- qy py)))) (if (or (< qx px tx) (< qy py ty) (< tx px qx) (< ty py qy)) :before (if (or (< px qx tx) (< py qy ty) (< tx qx px) (< ty qy py)) :after :within))))) (if (and env1 (> (length env1) 4)) (let ((new-env (list (cadr env1) (car env1))) (ymax (max-envelope env1)) (ymin (min-envelope env1)) (xmax (env1 (- (length env1) 2))) (xmin (car env1))) (if (= ymin ymax) (list xmin ymin xmax ymax) (let ((y-scl (/ ygrid (- ymax ymin))) (x-scl (/ (or xgrid ygrid) (- xmax xmin))) (px #f) (py #f) (qx #f) (qy #f) (tx #f) (ty #f) (qtx #f) (qty #f)) (do ((i 0 (+ i 2))) ((>= i (length env1))) (let ((ttx (env1 i)) (tty (env1 (+ i 1)))) (set! tx (round (* ttx x-scl))) (set! ty (round (* tty y-scl))) (if px (if (not (point-on-line? px py qx qy tx ty)) (begin (set! new-env (cons qty (cons qtx new-env))) (set! px qx) (set! py qy))) (begin (set! px qx) (set! py qy))) (set! qx tx) (set! qy ty) (set! qtx ttx) (set! qty tty))) (set! new-env (cons qty (cons qtx new-env))) (reverse new-env)))) env1)) snd-16.1/snd.10000644000076400007640000000153212306421672011205 0ustar bilbil.\" Written by Bill Schottstaedt (bil@ccrma.stanford.edu) .TH SND 1 "April 2001" "4.13" .SH NAME snd \- a sound editor .SH SYNOPSIS .B snd .I [\-l FILE] [\-p DIR] [\-v] [\-h] [\-notebook] [\-separate] [\-noglob] [\-noinit] [\-\-help] [\-\-version] .SH DESCRIPTION Snd is a sound editor. .PP .B Snd is free software. It's available at ftp://ccrma-ftp.stanford.edu/pub/Lisp/. .SH USAGE snd oboe.snd loads oboe.snd into Snd. .SH OPTIONS .IP \-l file Load extension language code in file. .IP \-p dir Preload sound files found in directory dir. .IP \-noinit Don't load any initialization files (~/.snd et al). .IP \-\-help Give some help. .IP \-\-version Describe current Snd. .SH FILES .I ~/.snd a file that can contain local customization code. .SH AUTHORS Bill Schottstaedt Michael Scholz with many generous far-flung helpers. snd-16.1/new-effects.scm0000644000076400007640000034516612622705137013271 0ustar bilbil(if (not (provided? 'snd-motif)) (snd-error "new-effects.scm is Motif-specific")) (provide 'snd-new-effects.scm) (require snd-effects-utils.scm snd-xm-enved.scm snd-moog.scm snd-rubber.scm snd-dsp.scm) (with-let (sublet *motif*) (define effects-list ()) ; menu labels are updated to show current settings (define effects-menu (add-to-main-menu "Effects" (lambda () (update-label effects-list)))) (define plausible-mark-samples (let ((documentation "(plausible-mark-samples) finds two marks in the current channel in or nearest to current window")) (lambda () (let* ((snd (selected-sound)) (chn (selected-channel)) (ms (sort! (map mark-sample (marks snd chn)) <))) (if (< (length ms) 2) (error 'no-such-mark (list "mark-related action requires two marks")) (if (= (length ms) 2) ms (let* ((lw (left-sample snd chn)) (rw (right-sample snd chn)) (cw (cursor snd chn)) (favor (if (>= rw cw lw) cw (* .5 (+ lw rw))))) ;; favor is the point we center the search on (define (centered-points points) (if (= (length points) 2) points (let ((p1 (car points)) (p2 (cadr points)) (p3 (caddr points))) (if (< (abs (- p1 favor)) (abs (- p3 favor))) (list p1 p2) (centered-points (cdr points)))))) (centered-points ms)))))))) (define map-chan-over-target-with-sync ;; target: 'marks -> beg=closest marked sample, dur=samples to next mark ;; 'sound -> beg=0, dur=all samples in sound ;; 'selection -> beg=selection-position, dur=selection-framples ;; 'cursor -> beg=cursor, dur=samples to end of sound ;; decay is how long to run the effect past the end of the sound (lambda (func target origin decay) (if (and (eq? target 'selection) (not (selection?))) (snd-print ";no selection") (if (and (eq? target 'sound) (null? (sounds))) (snd-print ";no sound") (if (and (eq? target 'marks) (or (null? (sounds)) (< (length (marks (selected-sound) (selected-channel))) 2))) (snd-print ";no marks") (let* ((snc (sync)) (ms (and (eq? target 'marks) (plausible-mark-samples))) (beg (if (eq? target 'sound) 0 (if (eq? target 'selection) (selection-position) (if (eq? target 'cursor) (cursor (selected-sound) (selected-channel)) (car ms))))) (overlap (if decay (floor (* (srate) decay)) 0))) (apply for-each (lambda (snd chn) (let ((end (if (memq target '(sound cursor)) (- (framples snd chn) 1) (if (eq? target 'selection) (+ (selection-position) (selection-framples)) (cadr ms))))) (if (= (sync snd) snc) (map-channel (func (- end beg)) beg (+ end overlap 1) snd chn #f (format #f "~A ~A ~A" (origin target (- end beg)) (if (eq? target 'sound) 0 beg) (and (not (eq? target 'sound)) (+ 1 (- end beg)))))))) (if (> snc 0) (all-chans) (list (list (selected-sound)) (list (selected-channel))))))))))) (define yellow-pixel (let ((pix #f)) (lambda () (if (not pix) (let* ((shell (cadr (main-widgets))) (dpy (XtDisplay shell)) (scr (DefaultScreen dpy)) (cmap (DefaultColormap dpy scr)) (col (XColor))) (if (= (XAllocNamedColor dpy cmap "yellow" col col) 0) (snd-error "can't allocate yellow!") (set! pix (.pixel col))))) pix))) (define (add-target mainform target-callback truncate-callback) ;; add a set of 3 radio buttons at the bottom of the main section for choice between sound, selection, between-marks ;; target-callback should take one arg, a symbol: 'sound, 'selection, 'marks, and apply the effect accordingly (upon "DoIt") ;; truncate-callback (if any) takes one arg: boolean representing toggle state (#t = on) (XtCreateManagedWidget "sep" xmSeparatorWidgetClass mainform (list XmNorientation XmHORIZONTAL XmNseparatorType XmSHADOW_ETCHED_OUT XmNbackground *basic-color*)) (let ((rc (XtCreateManagedWidget "rc" xmRowColumnWidgetClass mainform (list XmNorientation XmHORIZONTAL XmNbackground *basic-color* XmNradioBehavior #t XmNradioAlwaysOne #t XmNbottomAttachment XmATTACH_FORM XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNentryClass xmToggleButtonWidgetClass XmNisHomogeneous #t)))) (for-each (lambda (name type on) (XtCreateManagedWidget name xmToggleButtonWidgetClass rc (list XmNbackground *basic-color* XmNset on XmNselectColor (yellow-pixel) XmNindicatorType XmONE_OF_MANY_ROUND XmNarmCallback (list (lambda (w c i) (target-callback type)) #f)))) (list "entire sound" "selection" "between marks") (list 'sound 'selection 'marks) (list #t #f #f)) (if truncate-callback (XtCreateManagedWidget "trsep" xmSeparatorWidgetClass mainform (list XmNorientation XmHORIZONTAL)) (let ((trbutton (XtCreateManagedWidget "truncate at end" xmToggleButtonWidgetClass mainform (list XmNbackground *basic-color* XmNset #t XmNselectColor (yellow-pixel))))) (XtAddCallback trbutton XmNvalueChangedCallback (lambda (w c i) (truncate-callback (.set i)))))) rc)) (define (effect-framples target) (if (eq? target 'sound) (- (framples) 1) (if (eq? target 'selection) (selection-framples) (+ 1 (abs (apply - (plausible-mark-samples))))))) ;;; (Bill) changed 12-Oct-04 to make detached edit lists work (need globally accessible effect functions, etc) ;;; (Bill) changed 12-Oct-06 for new watcher mechanism, rather than the selection-button list, selection-changed-hook etc ;;; ******************************* ;;; ** ;;; BEGIN PARAMETRIZED EFFECTS ** ;;; ** ;;; ******************************* ;;; AMPLITUDE EFFECTS (define* (effects-squelch-channel amp gate-size snd chn no-silence) (let ((f0 (make-moving-average gate-size)) (f1 (make-moving-average gate-size :initial-element 1.0))) (if no-silence (map-channel (lambda (y) (let ((val (* y (moving-average f1 (ceiling (- (moving-average f0 (* y y)) amp)))))) (and (not (zero? val)) val))) 0 #f snd chn #f (format #f "effects-squelch-channel ~A ~A" amp gate-size)) (map-channel (lambda (y) (* y (moving-average f1 (ceiling (- (moving-average f0 (* y y)) amp))))) 0 #f snd chn #f (format #f "effects-squelch-channel ~A ~A" amp gate-size))))) (let* ((amp-menu-list ()) (amp-menu (XmCreatePulldownMenu (main-menu effects-menu) "Amplitude Effects" (list XmNbackground *basic-color*))) (amp-cascade (XtCreateManagedWidget "Amplitude Effects" xmCascadeButtonWidgetClass (main-menu effects-menu) (list XmNsubMenuId amp-menu XmNbackground *basic-color*)))) (XtAddCallback amp-cascade XmNcascadingCallback (lambda (w c i) (update-label amp-menu-list))) ;;; -------- Gain (gain set by gain-amount) (let ((gain-amount 1.0) (gain-label "Gain") (gain-dialog #f) (gain-target 'sound) (gain-envelope #f)) (define (scale-envelope e scl) (if (null? e) () (append (list (car e) (* scl (cadr e))) (scale-envelope (cddr e) scl)))) (define (post-gain-dialog) (if (not (Widget? gain-dialog)) ;; if gain-dialog doesn't exist, create it (let ((initial-gain-amount 1.0) (sliders ()) (fr #f)) (set! gain-dialog (make-effect-dialog gain-label (lambda (w context info) (let ((with-env (and (not (equal? (xe-envelope gain-envelope) (list 0.0 1.0 1.0 1.0))) (scale-envelope (xe-envelope gain-envelope) gain-amount)))) (if (eq? gain-target 'sound) (if with-env (env-sound with-env) (scale-by gain-amount)) (if (eq? gain-target 'selection) (if (selection?) (if with-env (env-selection with-env) (scale-selection-by gain-amount)) (snd-print ";no selection")) (let ((pts (catch 'no-such-mark plausible-mark-samples (lambda args #f)))) (if pts (if with-env (env-sound with-env (car pts) (- (cadr pts) (car pts))) (scale-by gain-amount (car pts) (- (cadr pts) (car pts)))) (snd-print ";no marks"))))))) (lambda (w context info) (help-dialog "Gain" "Move the slider to change the gain scaling amount.")) (lambda (w c i) (set! gain-amount initial-gain-amount) (set! (xe-envelope gain-envelope) (list 0.0 1.0 1.0 1.0)) (XtSetValues (car sliders) (list XmNvalue (floor (* gain-amount 100))))) (lambda () (effect-target-ok gain-target)))) (set! sliders (add-sliders gain-dialog (list (list "gain" 0.0 initial-gain-amount 5.0 (lambda (w context info) (set! gain-amount (/ (.value info) 100.0))) 100)))) (set! fr (XtCreateManagedWidget "fr" xmFrameWidgetClass (XtParent (XtParent (car sliders))) (list XmNheight 200 XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_WIDGET XmNtopWidget (sliders (- (length sliders) 1)) XmNshadowThickness 4 XmNshadowType XmSHADOW_ETCHED_OUT))) (let ((target-row (add-target (XtParent (XtParent (car sliders))) (lambda (target) (set! gain-target target) (XtSetSensitive (XmMessageBoxGetChild gain-dialog XmDIALOG_OK_BUTTON) (effect-target-ok target))) #f))) (activate-dialog gain-dialog) (set! gain-envelope (xe-create-enved "gain" fr (list XmNheight 200) '(0.0 1.0 0.0 1.0))) (set! (xe-envelope gain-envelope) (list 0.0 1.0 1.0 1.0)) (XtVaSetValues fr (list XmNbottomAttachment XmATTACH_WIDGET XmNbottomWidget target-row))) ) (activate-dialog gain-dialog))) (let ((child (XtCreateManagedWidget "Gain" xmPushButtonWidgetClass amp-menu (list XmNbackground *basic-color*)))) (XtAddCallback child XmNactivateCallback (lambda (w c i) (post-gain-dialog))) (set! amp-menu-list (cons (lambda () (let ((new-label (format #f "Gain (~1,2F)" gain-amount))) (change-label child new-label))) amp-menu-list)))) ;;; -------- Normalize ;;; (let ((normalize-amount 1.0) (normalize-label "Normalize") (normalize-dialog #f) (normalize-target 'sound)) (define (post-normalize-dialog) (if (not (Widget? normalize-dialog)) ;; if normalize-dialog doesn't exist, create it (let ((initial-normalize-amount 1.0) (sliders ())) (set! normalize-dialog (make-effect-dialog normalize-label (lambda (w context info) (if (eq? normalize-target 'sound) (scale-to normalize-amount) (if (eq? normalize-target 'selection) (if (selection?) (scale-selection-to normalize-amount) (snd-print ";no selection")) (let ((pts (plausible-mark-samples))) (if pts (scale-to normalize-amount (car pts) (- (cadr pts) (car pts)))))))) (lambda (w context info) (help-dialog "Normalize" "Normalize scales amplitude to the normalize amount. Move the slider to change the scaling amount.")) (lambda (w c i) (set! normalize-amount initial-normalize-amount) (XtSetValues (car sliders) (list XmNvalue (floor (* normalize-amount 100))))) (lambda () (effect-target-ok normalize-target)))) (set! sliders (add-sliders normalize-dialog (list (list "normalize" 0.0 initial-normalize-amount 1.0 (lambda (w context info) (set! normalize-amount (/ (.value info) 100.0))) 100)))) (add-target (XtParent (car sliders)) (lambda (target) (set! normalize-target target) (XtSetSensitive (XmMessageBoxGetChild normalize-dialog XmDIALOG_OK_BUTTON) (effect-target-ok target))) #f))) (activate-dialog normalize-dialog)) (let ((child (XtCreateManagedWidget "Normalize" xmPushButtonWidgetClass amp-menu (list XmNbackground *basic-color*)))) (XtAddCallback child XmNactivateCallback (lambda (w c i) (post-normalize-dialog))) (set! amp-menu-list (cons (lambda () (let ((new-label (format #f "Normalize (~1,2F)" normalize-amount))) (change-label child new-label))) amp-menu-list)))) ;;; -------- Gate (gate set by gate-amount) ;;; (let ((gate-amount 0.01) (gate-label "Gate") (gate-dialog #f) (gate-size 128) (omit-silence #f)) (define (post-gate-dialog) (if (not (Widget? gate-dialog)) ;; if gate-dialog doesn't exist, create it (let ((initial-gate-amount 0.01) (sliders ())) (set! gate-dialog (make-effect-dialog gate-label (lambda (w context info) (let ((snc (sync))) (if (> snc 0) (apply map (lambda (snd chn) (if (= (sync snd) snc) (effects-squelch-channel (* gate-amount gate-amount) gate-size snd chn omit-silence))) (all-chans)) (effects-squelch-channel (* gate-amount gate-amount) gate-size (selected-sound) (selected-channel) omit-silence)))) (lambda (w context info) (help-dialog "Gate" "Move the slider to change the gate intensity. Higher values gate more of the sound.")) (lambda (w c i) (set! gate-amount initial-gate-amount) (XtSetValues (car sliders) (list XmNvalue (floor (* gate-amount 1000))))) (lambda () (pair? (sounds))))) (set! sliders (add-sliders gate-dialog (list (list "gate" 0.0 initial-gate-amount 0.1 (lambda (w context info) (set! gate-amount (/ (.value info) 1000.0))) 1000)))) ;; now add a toggle button setting omit-silence ;; (need to use XtParent here because the containing RowColumn widget is ;; hidden in add-sliders -- perhaps it should be returned in the slider list) (let* ((s1 (XmStringCreateLocalized "Omit silence")) (toggle (XtCreateManagedWidget "Omit silence" xmToggleButtonWidgetClass (XtParent (car sliders)) (list XmNselectColor *selection-color* XmNbackground *basic-color* XmNvalue (if omit-silence 1 0) XmNlabelString s1)))) (XmStringFree s1) (XtAddCallback toggle XmNvalueChangedCallback (lambda (w c i) (set! omit-silence (.set i))))))) (activate-dialog gate-dialog)) (let ((child (XtCreateManagedWidget "Gate" xmPushButtonWidgetClass amp-menu (list XmNbackground *basic-color*)))) (XtAddCallback child XmNactivateCallback (lambda (w c i) (post-gate-dialog))) (set! amp-menu-list (cons (lambda () (let ((new-label (format #f "Gate (~1,4F)" gate-amount))) (change-label child new-label))) amp-menu-list)))) ) ;;; DELAY EFFECTS ;;; (define effects-echo (let ((documentation "(effects-echo input-samps-1 delay-time echo-amount beg dur snd chn) is used by the effects dialog to tie into edit-list->function")) (lambda* (input-samps-1 delay-time echo-amount beg dur snd chn) (let* ((del (make-delay (round (* delay-time (srate snd))))) (len (or dur (framples snd chn))) (input-samps (or input-samps-1 len))) (as-one-edit (lambda () (map-channel (lambda (inval) (+ inval (delay del (* echo-amount (+ (tap del) inval))))) beg input-samps snd chn) (if (> len input-samps) (map-channel (lambda (inval) (+ inval (delay del (* echo-amount (tap del))))) (+ beg input-samps) (- dur input-samps) snd chn))) (format #f "effects-echo ~A ~A ~A ~A ~A" input-samps-1 delay-time echo-amount beg dur)))))) (define effects-flecho-1 (let ((documentation "(effects-flecho-1 scaler secs input-samps-1 beg dur snd chn) is used by the effects dialog to tie into edit-list->function")) (lambda* (scaler secs input-samps-1 beg dur snd chn) (let ((flt (make-fir-filter :order 4 :xcoeffs (float-vector .125 .25 .25 .125))) (del (make-delay (round (* secs (srate snd)))))) (if (and (not input-samps-1) (not dur)) (map-channel (lambda (inval) (+ inval (delay del (fir-filter flt (* scaler (+ (tap del) inval)))))) beg #f snd chn #f (format #f "effects-flecho-1 ~A ~A ~A ~A ~A" scaler secs input-samps-1 beg #f)) (let* ((cutoff (- (or input-samps-1 dur (framples snd chn)) 1)) (genv (make-env (list 0.0 1.0 cutoff 1.0 (+ cutoff 1) 0.0 (+ cutoff 100) 0.0) :length (+ cutoff 100)))) (map-channel (lambda (inval) (+ inval (delay del (fir-filter flt (* scaler (+ (tap del) (* (env genv) inval))))))) beg dur snd chn #f (format #f "effects-flecho-1 ~A ~A ~A ~A ~A" scaler secs input-samps-1 beg dur)))))))) (define effects-zecho-1 (let ((documentation "(effects-zecho-1 scaler secs frq amp input-samps-1 beg dur snd chn) is used by the effects dialog to tie into edit-list->function")) (lambda* (scaler secs frq amp input-samps-1 beg dur snd chn) (let* ((os (make-oscil frq)) (len (round (* secs (srate snd)))) (del (make-delay len :max-size (round (+ len amp 1)))) (cutoff (- (or input-samps-1 dur (framples snd chn)) 1)) (genv (make-env (list 0.0 1.0 cutoff 1.0 (+ cutoff 1) 0.0 (+ cutoff 100) 0.0) :length (+ cutoff 100)))) (map-channel (lambda (inval) (+ inval (delay del (* scaler (+ (tap del) (* (env genv) inval))) (* amp (oscil os))))) beg dur snd chn #f (format #f "effects-zecho-1 ~A ~A ~A ~A ~A ~A ~A" scaler secs frq amp input-samps-1 beg dur)))))) (let* ((delay-menu-list ()) (delay-menu (XmCreatePulldownMenu (main-menu effects-menu) "Delay Effects" (list XmNbackground *basic-color*))) (delay-cascade (XtCreateManagedWidget "Delay Effects" xmCascadeButtonWidgetClass (main-menu effects-menu) (list XmNsubMenuId delay-menu XmNbackground *basic-color*)))) (XtAddCallback delay-cascade XmNcascadingCallback (lambda (w c i) (update-label delay-menu-list))) ;;; -------- Echo (controlled by delay-time and echo-amount) (let ((delay-time .5) ; i.e. delay between echoes (echo-amount .2) (echo-label "Echo") (echo-dialog #f) (echo-target 'sound) (echo-truncate #t)) (define (post-echo-dialog) (if (not (Widget? echo-dialog)) ;; if echo-dialog doesn't exist, create it (let ((initial-delay-time 0.5) (initial-echo-amount 0.2) (sliders ())) (set! echo-dialog (make-effect-dialog echo-label (lambda (w context info) (map-chan-over-target-with-sync (lambda (cutoff) (let ((del (make-delay (round (* delay-time (srate))))) (genv (make-env (list 0.0 1.0 cutoff 1.0 (+ cutoff 1) 0.0 (+ cutoff 100) 0.0) :length (+ cutoff 100)))) (lambda (inval) (+ inval (delay del (* echo-amount (+ (tap del) (* (env genv) inval)))))))) echo-target (lambda (target input-samps) (format #f "effects-echo ~A ~A ~A" (and (not (eq? target 'sound)) input-samps) delay-time echo-amount)) (and (not echo-truncate) (* 4 delay-time)))) (lambda (w context info) (help-dialog "Echo" "The sliders change the delay time and echo amount.")) (lambda (w c i) (set! delay-time initial-delay-time) (XtSetValues (car sliders) (list XmNvalue (floor (* delay-time 100)))) (set! echo-amount initial-echo-amount) (XtSetValues (cadr sliders) (list XmNvalue (floor (* echo-amount 100))))) (lambda () (effect-target-ok echo-target)))) (set! sliders (add-sliders echo-dialog (list (list "delay time" 0.0 initial-delay-time 2.0 (lambda (w context info) (set! delay-time (/ (.value info) 100.0))) 100) (list "echo amount" 0.0 initial-echo-amount 1.0 (lambda (w context info) (set! echo-amount (/ (.value info) 100.0))) 100)))) (add-target (XtParent (car sliders)) (lambda (target) (set! echo-target target) (XtSetSensitive (XmMessageBoxGetChild echo-dialog XmDIALOG_OK_BUTTON) (effect-target-ok target))) (lambda (truncate) (set! echo-truncate truncate))))) (activate-dialog echo-dialog)) (let ((child (XtCreateManagedWidget "Echo" xmPushButtonWidgetClass delay-menu (list XmNbackground *basic-color*)))) (XtAddCallback child XmNactivateCallback (lambda (w c i) (post-echo-dialog))) (set! delay-menu-list (cons (lambda () (let ((new-label (format #f "Echo (~1,2F ~1,2F)" delay-time echo-amount))) (change-label child new-label))) delay-menu-list)))) ;;; -------- Filtered echo (let ((flecho-scaler 0.5) (flecho-delay 0.9) (flecho-label "Filtered echo") (flecho-dialog #f) (flecho-target 'sound) (flecho-truncate #t)) (define flecho-1 (lambda (scaler secs cutoff) (let ((flt (make-fir-filter :order 4 :xcoeffs (float-vector .125 .25 .25 .125))) (del (make-delay (round (* secs (srate))))) (genv (make-env (list 0.0 1.0 cutoff 1.0 (+ cutoff 1) 0.0 (+ cutoff 100) 0.0) :length (+ cutoff 100)))) (lambda (inval) (+ inval (delay del (fir-filter flt (* scaler (+ (tap del) (* (env genv) inval)))))))))) (define (post-flecho-dialog) (if (not (Widget? flecho-dialog)) ;; if flecho-dialog doesn't exist, create it (let ((initial-flecho-scaler 0.5) (initial-flecho-delay 0.9) (sliders ())) (set! flecho-dialog (make-effect-dialog flecho-label (lambda (w context info) (map-chan-over-target-with-sync (lambda (input-samps) (flecho-1 flecho-scaler flecho-delay input-samps)) flecho-target (lambda (target input-samps) (format #f "effects-flecho-1 ~A ~A ~A" flecho-scaler flecho-delay (and (not (eq? target 'sound)) input-samps))) (and (not flecho-truncate) (* 4 flecho-delay)))) (lambda (w context info) (help-dialog "Filtered echo" "Move the sliders to set the filter scaler and the delay time in seconds.")) (lambda (w c i) (set! flecho-scaler initial-flecho-scaler) (XtSetValues (sliders 0) (list XmNvalue (floor (* flecho-scaler 100)))) (set! flecho-delay initial-flecho-delay) (XtSetValues (sliders 1) (list XmNvalue (floor (* flecho-delay 100))))) (lambda () (effect-target-ok flecho-target)))) (set! sliders (add-sliders flecho-dialog (list (list "filter scaler" 0.0 initial-flecho-scaler 1.0 (lambda (w context info) (set! flecho-scaler (/ (.value info) 100.0))) 100) (list "delay time (secs)" 0.0 initial-flecho-delay 3.0 (lambda (w context info) (set! flecho-delay (/ (.value info) 100.0))) 100)))) (add-target (XtParent (car sliders)) (lambda (target) (set! flecho-target target) (XtSetSensitive (XmMessageBoxGetChild flecho-dialog XmDIALOG_OK_BUTTON) (effect-target-ok target))) (lambda (truncate) (set! flecho-truncate truncate))))) (activate-dialog flecho-dialog)) (let ((child (XtCreateManagedWidget "Filtered echo" xmPushButtonWidgetClass delay-menu (list XmNbackground *basic-color*)))) (XtAddCallback child XmNactivateCallback (lambda (w c i) (post-flecho-dialog))) (set! delay-menu-list (cons (lambda () (let ((new-label (format #f "Filtered echo (~1,2F ~1,2F)" flecho-scaler flecho-delay))) (change-label child new-label))) delay-menu-list)))) ;;; -------- Modulated echo ;;; -------- very slick (let ((zecho-scaler 0.5) (zecho-delay 0.75) (zecho-freq 6) (zecho-amp 10.0) (zecho-label "Modulated echo") (zecho-dialog #f) (zecho-target 'sound) (zecho-truncate #t)) (define zecho-1 (lambda (scaler secs frq amp cutoff) (let* ((os (make-oscil frq)) (len (round (* secs (srate)))) (del (make-delay len :max-size (round (+ len amp 1)))) (genv (make-env (list 0.0 1.0 cutoff 1.0 (+ cutoff 1) 0.0 (+ cutoff 100) 0.0) :length (+ cutoff 100)))) (lambda (inval) (+ inval (delay del (* scaler (+ (tap del) (* (env genv) inval))) (* amp (oscil os)))))))) (define (post-zecho-dialog) (if (not (Widget? zecho-dialog)) ;; if zecho-dialog doesn't exist, create it (let ((initial-zecho-scaler 0.5) (initial-zecho-delay 0.75) (initial-zecho-freq 6) (initial-zecho-amp 10.0) (sliders ())) (set! zecho-dialog (make-effect-dialog zecho-label (lambda (w context info) (map-chan-over-target-with-sync (lambda (input-samps) (zecho-1 zecho-scaler zecho-delay zecho-freq zecho-amp input-samps)) zecho-target (lambda (target input-samps) (format #f "effects-zecho-1 ~A ~A ~A ~A ~A" zecho-scaler zecho-delay zecho-freq zecho-amp (and (not (eq? target 'sound)) input-samps))) (and (not zecho-truncate) (* 4 zecho-delay)))) (lambda (w context info) (help-dialog "Modulated echo" "Move the sliders to set the echo scaler, the delay time in seconds, the modulation frequency, and the echo amplitude.")) (lambda (w c i) (set! zecho-scaler initial-zecho-scaler) (XtSetValues (sliders 0) (list XmNvalue (floor (* zecho-scaler 100)))) (set! zecho-delay initial-zecho-delay) (XtSetValues (sliders 1) (list XmNvalue (floor (* zecho-delay 100)))) (set! zecho-freq initial-zecho-freq) (XtSetValues (sliders 2) (list XmNvalue (floor (* zecho-freq 100)))) (set! zecho-amp initial-zecho-amp) (XtSetValues (sliders 3) (list XmNvalue (floor (* zecho-amp 100))))) (lambda () (effect-target-ok zecho-target)))) (set! sliders (add-sliders zecho-dialog (list (list "echo scaler" 0.0 initial-zecho-scaler 1.0 (lambda (w context info) (set! zecho-scaler (/ (.value info) 100.0))) 100) (list "delay time (secs)" 0.0 initial-zecho-delay 3.0 (lambda (w context info) (set! zecho-delay (/ (.value info) 100.0))) 100) (list "modulation frequency" 0.0 initial-zecho-freq 100.0 (lambda (w context info) (set! zecho-freq (/ (.value info) 100.0))) 100) (list "modulation amplitude" 0.0 initial-zecho-amp 100.0 (lambda (w context info) (set! zecho-amp (/ (.value info) 100.0))) 100)))) (add-target (XtParent (car sliders)) (lambda (target) (set! zecho-target target) (XtSetSensitive (XmMessageBoxGetChild zecho-dialog XmDIALOG_OK_BUTTON) (effect-target-ok target))) (lambda (truncate) (set! zecho-truncate truncate))))) (activate-dialog zecho-dialog)) (let ((child (XtCreateManagedWidget "Modulated echo" xmPushButtonWidgetClass delay-menu (list XmNbackground *basic-color*)))) (XtAddCallback child XmNactivateCallback (lambda (w c i) (post-zecho-dialog))) (set! delay-menu-list (cons (lambda () (let ((new-label (format #f "Modulated echo (~1,2F ~1,2F ~1,2F ~1,2F)" zecho-scaler zecho-delay zecho-freq zecho-amp))) (change-label child new-label))) delay-menu-list)))) ) ;;; FILTERS ;;; (define effects-comb-filter (let ((documentation "(effects-comb-filter scaler-1 size beg dur snd chn) is used by the effects dialog to tie into edit-list->function")) (lambda* (scaler size beg dur snd chn) (let ((delay-line (make-float-vector size 0.0)) (delay-loc 0)) (lambda (x) (let ((result (delay-line delay-loc))) (set! (delay-line delay-loc) (+ x (* scaler result))) (set! delay-loc (+ 1 delay-loc)) (if (= delay-loc size) (set! delay-loc 0)) result)))))) (define effects-comb-chord (let ((documentation "(effects-comb-chord scaler size amp interval-one interval-two beg dur snd chn) is used by the effects dialog to tie into edit-list->function")) (lambda* (scaler size amp interval-one interval-two beg dur snd chn) (let ((cs (make-comb-bank (vector (make-comb scaler size) (make-comb scaler (* size interval-one)) (make-comb scaler (* size interval-two)))))) (map-channel (lambda (x) (* amp (comb-bank cs x))) beg dur snd chn #f (format #f "effects-comb-chord ~A ~A ~A ~A ~A ~A ~A" scaler size amp interval-one interval-two beg dur)))))) (define effects-moog (let ((documentation "(effects-moog freq Q beg dur snd chn) is used by the effects dialog to tie into edit-list->function")) (lambda* (freq Q beg dur snd chn) (let ((gen (make-moog-filter freq Q))) (map-channel (lambda (inval) (moog-filter gen inval)) beg dur snd chn #f (format #f "effects-moog ~A ~A ~A ~A" freq Q beg dur)))))) (define effects-bbp (let ((documentation "(effects-bbp freq bw beg dur snd chn) is used by the effects dialog to tie into edit-list->function")) (lambda* (freq bw beg dur snd chn) (let ((flt (make-butter-band-pass freq bw))) (clm-channel flt beg dur snd chn #f #f (format #f "effects-bbp ~A ~A ~A ~A" freq bw beg dur)))))) (define effects-bbr (let ((documentation "(effects-bbr freq bw beg dur snd chn) is used by the effects dialog to tie into edit-list->function")) (lambda* (freq bw beg dur snd chn) (let ((flt (make-butter-band-reject freq bw))) (clm-channel flt beg dur snd chn #f #f (format #f "effects-bbr ~A ~A ~A ~A" freq bw beg dur)))))) (define effects-bhp (let ((documentation "(effects-bhp freq beg dur snd chn) is used by the effects dialog to tie into edit-list->function")) (lambda* (freq beg dur snd chn) (let ((flt (make-butter-high-pass freq))) (clm-channel flt beg dur snd chn #f #f (format #f "effects-bhp ~A ~A ~A" freq beg dur)))))) (define effects-blp (let ((documentation "(effects-blp freq beg dur snd chn) is used by the effects dialog to tie into edit-list->function")) (lambda* (freq beg dur snd chn) (let ((flt (make-butter-low-pass freq))) (clm-channel flt beg dur snd chn #f #f (format #f "effects-blp ~A ~A ~A" freq beg dur)))))) (let* ((filter-menu-list ()) (filter-menu (XmCreatePulldownMenu (main-menu effects-menu) "Filter Effects" (list XmNbackground *basic-color*))) (filter-cascade (XtCreateManagedWidget "Filter Effects" xmCascadeButtonWidgetClass (main-menu effects-menu) (list XmNsubMenuId filter-menu XmNbackground *basic-color*)))) (XtAddCallback filter-cascade XmNcascadingCallback (lambda (w c i) (update-label filter-menu-list))) ;;; -------- Butterworth band-pass filter (let ((band-pass-freq 1000) (band-pass-bw 100) (band-pass-label "Band-pass filter") (band-pass-dialog #f) (band-pass-target 'sound)) (define (post-band-pass-dialog) (if (not (Widget? band-pass-dialog)) ;; if band-pass-dialog doesn't exist, create it (let ((initial-band-pass-freq 1000) (initial-band-pass-bw 100) (sliders ())) (set! band-pass-dialog (make-effect-dialog band-pass-label (lambda (w context info) (let ((flt (make-butter-band-pass band-pass-freq band-pass-bw))) (if (eq? band-pass-target 'sound) (filter-sound flt #f #f #f #f (format #f "effects-bbp ~A ~A 0 #f" band-pass-freq band-pass-bw)) (if (eq? band-pass-target 'selection) (filter-selection flt) (let* ((ms (plausible-mark-samples)) (bg (car ms)) (nd (+ 1 (- (cadr ms) (car ms))))) (clm-channel flt bg nd #f #f #f #f (format #f "effects-bbp ~A ~A ~A ~A" band-pass-freq band-pass-bw bg nd))))))) (lambda (w context info) (help-dialog "Band-pass filter" "Butterworth band-pass filter. Move the sliders to change the center frequency and bandwidth.")) (lambda (w c i) (set! band-pass-freq initial-band-pass-freq) (XtSetValues (car sliders) (list XmNvalue (scale-log->linear 20 band-pass-freq 22050))) (set! band-pass-bw initial-band-pass-bw) (XtSetValues (cadr sliders) (list XmNvalue (floor band-pass-bw)))) (lambda () (effect-target-ok band-pass-target)))) (set! sliders (add-sliders band-pass-dialog (list (list "center frequency" 20 initial-band-pass-freq 22050 (lambda (w context info) (set! band-pass-freq (scale-linear->log 20 (.value info) 22050))) 1 'log) (list "bandwidth" 0 initial-band-pass-bw 1000 (lambda (w context info) (set! band-pass-bw (.value info))) 1)))) (add-target (XtParent (car sliders)) (lambda (target) (set! band-pass-target target) (XtSetSensitive (XmMessageBoxGetChild band-pass-dialog XmDIALOG_OK_BUTTON) (effect-target-ok target))) #f))) (activate-dialog band-pass-dialog)) (let ((child (XtCreateManagedWidget "Band-pass filter" xmPushButtonWidgetClass filter-menu (list XmNbackground *basic-color*)))) (XtAddCallback child XmNactivateCallback (lambda (w c i) (post-band-pass-dialog))) (set! filter-menu-list (cons (lambda () (let ((new-label (format #f "Band-pass filter (~,2F ~D" band-pass-freq band-pass-bw))) (change-label child new-label))) filter-menu-list)))) ;;; -------- Butterworth band-reject (notch) filter (let ((notch-freq 100) (notch-bw 100) (notch-label "Band-reject filter") (notch-dialog #f) (notch-target 'sound)) (define (post-notch-dialog) (if (not (Widget? notch-dialog)) ;; if notch-dialog doesn't exist, create it (let ((initial-notch-freq 100) (initial-notch-bw 100) (sliders ())) (set! notch-dialog (make-effect-dialog notch-label (lambda (w context info) (let ((flt (make-butter-band-reject notch-freq notch-bw))) (if (eq? notch-target 'sound) (filter-sound flt #f #f #f #f (format #f "effects-bbr ~A ~A 0 #f" notch-freq notch-bw)) (if (eq? notch-target 'selection) (filter-selection flt) (let* ((ms (plausible-mark-samples)) (bg (car ms)) (nd (+ 1 (- (cadr ms) (car ms))))) (clm-channel flt bg nd #f #f #f #f (format #f "effects-bbr ~A ~A ~A ~A" notch-freq notch-bw bg nd))))))) (lambda (w context info) (help-dialog "Band-reject filter" "Butterworth band-reject filter. Move the sliders to change the center frequency and bandwidth.")) (lambda (w c i) (set! notch-freq initial-notch-freq) (XtSetValues (car sliders) (list XmNvalue (scale-log->linear 20 notch-freq 22050))) (set! notch-bw initial-notch-bw) (XtSetValues (cadr sliders) (list XmNvalue (floor notch-bw)))) (lambda () (effect-target-ok notch-target)))) (set! sliders (add-sliders notch-dialog (list (list "center frequency" 20 initial-notch-freq 22050 (lambda (w context info) (set! notch-freq (scale-linear->log 20 (.value info) 22050))) 1 'log) (list "bandwidth" 0 initial-notch-bw 1000 (lambda (w context info) (set! notch-bw (.value info))) 1)))) (add-target (XtParent (car sliders)) (lambda (target) (set! notch-target target) (XtSetSensitive (XmMessageBoxGetChild notch-dialog XmDIALOG_OK_BUTTON) (effect-target-ok target))) #f))) (activate-dialog notch-dialog)) (let ((child (XtCreateManagedWidget "Band-reject filter" xmPushButtonWidgetClass filter-menu (list XmNbackground *basic-color*)))) (XtAddCallback child XmNactivateCallback (lambda (w c i) (post-notch-dialog))) (set! filter-menu-list (cons (lambda () (let ((new-label (format #f "Band-reject filter (~,2F ~D)" notch-freq notch-bw))) (change-label child new-label))) filter-menu-list)))) ;;; -------- Butterworth high-pass filter (let ((high-pass-freq 100) (high-pass-label "High-pass filter") (high-pass-dialog #f) (high-pass-target 'sound)) (define (post-high-pass-dialog) (if (not (Widget? high-pass-dialog)) ;; if high-pass-dialog doesn't exist, create it (let ((initial-high-pass-freq 100) (sliders ())) (set! high-pass-dialog (make-effect-dialog high-pass-label (lambda (w context info) (let ((flt (make-butter-high-pass high-pass-freq))) (if (eq? high-pass-target 'sound) (filter-sound flt #f #f #f #f (format #f "effects-bhp ~A 0 #f" high-pass-freq)) (if (eq? high-pass-target 'selection) (filter-selection flt) (let* ((ms (plausible-mark-samples)) (bg (car ms)) (nd (+ 1 (- (cadr ms) (car ms))))) (clm-channel flt bg nd #f #f #f #f (format #f "effects-bhp ~A ~A ~A" high-pass-freq bg nd))))))) (lambda (w context info) (help-dialog "High-pass filter" "Butterworth high-pass filter. Move the slider to change the high-pass cutoff frequency.")) (lambda (w c i) (set! high-pass-freq initial-high-pass-freq) (XtSetValues (car sliders) (list XmNvalue (scale-log->linear 20 high-pass-freq 22050)))) (lambda () (effect-target-ok high-pass-target)))) (set! sliders (add-sliders high-pass-dialog (list (list "high-pass cutoff frequency" 20 initial-high-pass-freq 22050 (lambda (w context info) (set! high-pass-freq (scale-linear->log 20 (.value info) 22050))) 1 'log)))) (add-target (XtParent (car sliders)) (lambda (target) (set! high-pass-target target) (XtSetSensitive (XmMessageBoxGetChild high-pass-dialog XmDIALOG_OK_BUTTON) (effect-target-ok target))) #f))) (activate-dialog high-pass-dialog)) (let ((child (XtCreateManagedWidget "High-pass filter" xmPushButtonWidgetClass filter-menu (list XmNbackground *basic-color*)))) (XtAddCallback child XmNactivateCallback (lambda (w c i) (post-high-pass-dialog))) (set! filter-menu-list (cons (lambda () (let ((new-label (format #f "High-pass filter (~,2F)" high-pass-freq))) (change-label child new-label))) filter-menu-list)))) ;;; -------- Butterworth low-pass filter (let ((low-pass-freq 1000) (low-pass-label "Low-pass filter") (low-pass-dialog #f) (low-pass-target 'sound)) (define (post-low-pass-dialog) (if (not (Widget? low-pass-dialog)) ;; if low-pass-dialog doesn't exist, create it (let ((initial-low-pass-freq 1000) (sliders ())) (set! low-pass-dialog (make-effect-dialog low-pass-label (lambda (w context info) (let ((flt (make-butter-low-pass low-pass-freq))) (if (eq? low-pass-target 'sound) (filter-sound flt #f #f #f #f (format #f "effects-blp ~A 0 #f" low-pass-freq)) (if (eq? low-pass-target 'selection) (filter-selection flt) (let* ((ms (plausible-mark-samples)) (bg (car ms)) (nd (+ 1 (- (cadr ms) (car ms))))) (clm-channel flt bg nd #f #f #f #f (format #f "effects-blp ~A ~A ~A" low-pass-freq bg nd))))))) (lambda (w context info) (help-dialog "Low-pass filter" "Butterworth low-pass filter. Move the slider to change the low-pass cutoff frequency.")) (lambda (w c i) (set! low-pass-freq initial-low-pass-freq) (XtSetValues (car sliders) (list XmNvalue (scale-log->linear 20 low-pass-freq 22050)))) (lambda () (effect-target-ok low-pass-target)))) (set! sliders (add-sliders low-pass-dialog (list (list "low-pass cutoff frequency" 20 initial-low-pass-freq 22050 (lambda (w context info) (set! low-pass-freq (scale-linear->log 20 (.value info) 22050))) 1 'log)))) (add-target (XtParent (car sliders)) (lambda (target) (set! low-pass-target target) (XtSetSensitive (XmMessageBoxGetChild low-pass-dialog XmDIALOG_OK_BUTTON) (effect-target-ok target))) #f))) (activate-dialog low-pass-dialog)) (let ((child (XtCreateManagedWidget "Low-pass filter" xmPushButtonWidgetClass filter-menu (list XmNbackground *basic-color*)))) (XtAddCallback child XmNactivateCallback (lambda (w c i) (post-low-pass-dialog))) (set! filter-menu-list (cons (lambda () (let ((new-label (format #f "Low-pass filter (~,2F)" low-pass-freq))) (change-label child new-label))) filter-menu-list)))) ;;; more filters ;;; -------- Comb filter ;;; ;;; (truncate) (let ((comb-scaler 0.1) (comb-size 50) (comb-label "Comb filter") (comb-dialog #f) (comb-target 'sound)) (define (post-comb-dialog) (if (not (Widget? comb-dialog)) ;; if comb-dialog doesn't exist, create it (let ((initial-comb-scaler 0.1) (initial-comb-size 50) (sliders ())) (set! comb-dialog (make-effect-dialog comb-label (lambda (w context info) (map-chan-over-target-with-sync (lambda (ignored) (effects-comb-filter comb-scaler comb-size)) comb-target (lambda (target samps) (format #f "effects-comb-filter ~A ~A" comb-scaler comb-size)) #f)) (lambda (w context info) (help-dialog "Comb filter" "Move the sliders to change the comb scaler and size.")) (lambda (w c i) (set! comb-scaler initial-comb-scaler) (XtSetValues (car sliders) (list XmNvalue (floor (* comb-scaler 100)))) (set! comb-size initial-comb-size) (XtSetValues (cadr sliders) (list XmNvalue (floor comb-size)))) (lambda () (effect-target-ok comb-target)))) (set! sliders (add-sliders comb-dialog (list (list "scaler" 0.0 initial-comb-scaler 1.0 (lambda (w context info) (set! comb-scaler (/ (.value info) 100.0))) 100) (list "size" 0 initial-comb-size 100 (lambda (w context info) (set! comb-size (.value info))) 1)))) (add-target (XtParent (car sliders)) (lambda (target) (set! comb-target target) (XtSetSensitive (XmMessageBoxGetChild comb-dialog XmDIALOG_OK_BUTTON) (effect-target-ok target))) #f))) (activate-dialog comb-dialog)) (let ((child (XtCreateManagedWidget "Comb filter" xmPushButtonWidgetClass filter-menu (list XmNbackground *basic-color*)))) (XtAddCallback child XmNactivateCallback (lambda (w c i) (post-comb-dialog))) (set! filter-menu-list (cons (lambda () (let ((new-label (format #f "Comb filter (~1,2F ~D)" comb-scaler comb-size))) (change-label child new-label))) filter-menu-list)))) ;;; -------- Comb-chord filter ;;; ;;; (truncate) (let ((new-comb-chord-scaler 0.95) (new-comb-chord-size 60) (new-comb-chord-amp 0.3) (new-comb-chord-interval-one 0.75) (new-comb-chord-interval-two 1.20) (new-comb-chord-label "Comb chord filter") (new-comb-chord-dialog #f) (new-comb-chord-target 'sound)) (define new-comb-chord (lambda (scaler size amp interval-one interval-two) ;; Comb chord filter: create chords by using filters at harmonically related sizes. (let ((cs (make-comb-bank (vector (make-comb scaler size) (make-comb scaler (* size interval-one)) (make-comb scaler (* size interval-two)))))) (lambda (x) (* amp (comb-bank cs x)))))) (define (post-new-comb-chord-dialog) (if (not (Widget? new-comb-chord-dialog)) ;; if new-comb-chord-dialog doesn't exist, create it (let ((initial-new-comb-chord-scaler 0.95) (initial-new-comb-chord-size 60) (initial-new-comb-chord-amp 0.3) (initial-new-comb-chord-interval-one 0.75) (initial-new-comb-chord-interval-two 1.20) (sliders ())) (set! new-comb-chord-dialog (make-effect-dialog new-comb-chord-label (lambda (w context info) (map-chan-over-target-with-sync (lambda (ignored) (new-comb-chord new-comb-chord-scaler new-comb-chord-size new-comb-chord-amp new-comb-chord-interval-one new-comb-chord-interval-two)) new-comb-chord-target (lambda (target samps) (format #f "effects-comb-chord ~A ~A ~A ~A ~A" new-comb-chord-scaler new-comb-chord-size new-comb-chord-amp new-comb-chord-interval-one new-comb-chord-interval-two)) #f)) (lambda (w context info) (help-dialog "Comb chord filter" "Creates chords by using filters at harmonically related sizes. Move the sliders to set the comb chord parameters.")) (lambda (w c i) (set! new-comb-chord-scaler initial-new-comb-chord-scaler) (XtSetValues (sliders 0) (list XmNvalue (floor (* new-comb-chord-scaler 100)))) (set! new-comb-chord-size initial-new-comb-chord-size) (XtSetValues (sliders 1) (list XmNvalue new-comb-chord-size)) (set! new-comb-chord-amp initial-new-comb-chord-amp) (XtSetValues (sliders 2) (list XmNvalue (floor (* new-comb-chord-amp 100)))) (set! new-comb-chord-interval-one initial-new-comb-chord-interval-one) (XtSetValues (sliders 3) (list XmNvalue (floor (* new-comb-chord-interval-one 100)))) (set! new-comb-chord-interval-two initial-new-comb-chord-interval-two) (XtSetValues (sliders 4) (list XmNvalue (floor (* new-comb-chord-interval-two 100))))) (lambda () (effect-target-ok new-comb-chord-target)))) (set! sliders (add-sliders new-comb-chord-dialog (list (list "chord scaler" 0.0 initial-new-comb-chord-scaler 1.0 (lambda (w context info) (set! new-comb-chord-scaler (/ (.value info) 100.0))) 100) (list "chord size" 0 initial-new-comb-chord-size 100 (lambda (w context info) (set! new-comb-chord-size (.value info))) 1) (list "amplitude" 0.0 initial-new-comb-chord-amp 1.0 (lambda (w context info) (set! new-comb-chord-amp (/ (.value info) 100.0))) 100) (list "interval one" 0.0 initial-new-comb-chord-interval-one 2.0 (lambda (w context info) (set! new-comb-chord-interval-one (/ (.value info) 100.0))) 100) (list "interval two" 0.0 initial-new-comb-chord-interval-two 2.0 (lambda (w context info) (set! new-comb-chord-interval-two (/ (.value info) 100.0))) 100)))) (add-target (XtParent (car sliders)) (lambda (target) (set! new-comb-chord-target target) (XtSetSensitive (XmMessageBoxGetChild new-comb-chord-dialog XmDIALOG_OK_BUTTON) (effect-target-ok target))) #f))) (activate-dialog new-comb-chord-dialog)) (let ((child (XtCreateManagedWidget "Comb chord filter" xmPushButtonWidgetClass filter-menu (list XmNbackground *basic-color*)))) (XtAddCallback child XmNactivateCallback (lambda (w c i) (post-new-comb-chord-dialog))) (set! filter-menu-list (cons (lambda () (let ((new-label (format #f "Comb chord filter (~1,2F ~D ~1,2F ~1,2F ~1,2F)" new-comb-chord-scaler new-comb-chord-size new-comb-chord-amp new-comb-chord-interval-one new-comb-chord-interval-two))) (change-label child new-label))) filter-menu-list)))) ;;; -------- Moog filter ;;; (let ((moog-cutoff-frequency 10000) (moog-resonance 0.5) (moog-label "Moog filter") (moog-dialog #f) (moog-target 'sound)) (define (moog freq Q) (let ((gen (make-moog-filter freq Q))) (lambda (inval) (moog-filter gen inval)))) (define (post-moog-dialog) (if (not (Widget? moog-dialog)) ;; if moog-dialog doesn't exist, create it (let ((initial-moog-cutoff-frequency 10000) (initial-moog-resonance 0.5) (sliders ())) (set! moog-dialog (make-effect-dialog moog-label (lambda (w context info) (map-chan-over-target-with-sync (lambda (ignored) (moog moog-cutoff-frequency moog-resonance)) moog-target (lambda (target samps) (format #f "effects-moog-filter ~A ~A" moog-cutoff-frequency moog-resonance)) #f)) (lambda (w context info) (help-dialog "Moog filter" "Moog-style 4-pole lowpass filter with 24db/oct rolloff and variable resonance. Move the sliders to set the filter cutoff frequency and resonance.")) (lambda (w c i) (set! moog-cutoff-frequency initial-moog-cutoff-frequency) (XtSetValues (car sliders) (list XmNvalue (scale-log->linear 20 moog-cutoff-frequency 22050))) (set! moog-resonance initial-moog-resonance) (XtSetValues (cadr sliders) (list XmNvalue (floor (* moog-resonance 100))))) (lambda () (effect-target-ok moog-target)))) (set! sliders (add-sliders moog-dialog (list (list "cutoff frequency" 20 initial-moog-cutoff-frequency 22050 (lambda (w context info) (set! moog-cutoff-frequency (scale-linear->log 20 (.value info) 22050))) 1 'log) (list "resonance" 0.0 initial-moog-resonance 1.0 (lambda (w context info) (set! moog-resonance (/ (.value info) 100.0))) 100)))) (add-target (XtParent (car sliders)) (lambda (target) (set! moog-target target) (XtSetSensitive (XmMessageBoxGetChild moog-dialog XmDIALOG_OK_BUTTON) (effect-target-ok target))) #f))) (activate-dialog moog-dialog)) (let ((child (XtCreateManagedWidget "Moog filter" xmPushButtonWidgetClass filter-menu (list XmNbackground *basic-color*)))) (XtAddCallback child XmNactivateCallback (lambda (w c i) (post-moog-dialog))) (set! filter-menu-list (cons (lambda () (let ((new-label (format #f "Moog filter (~,2F ~1,2F)" moog-cutoff-frequency moog-resonance))) (change-label child new-label))) filter-menu-list)))) ) ;;; FREQUENCY EFFECTS ;;; (let* ((freq-menu-list ()) (freq-menu (XmCreatePulldownMenu (main-menu effects-menu) "Frequency Effects" (list XmNbackground *basic-color*))) (freq-cascade (XtCreateManagedWidget "Frequency Effects" xmCascadeButtonWidgetClass (main-menu effects-menu) (list XmNsubMenuId freq-menu XmNbackground *basic-color*)))) (XtAddCallback freq-cascade XmNcascadingCallback (lambda (w c i) (update-label freq-menu-list))) ;;; -------- Sample rate conversion (resample) ;;; (let ((src-amount 0.0) (src-label "Sample rate conversion") (src-dialog #f) (src-target 'sound)) (define (post-src-dialog) (if (not (Widget? src-dialog)) ;; if src-dialog doesn't exist, create it (let ((initial-src-amount 0.0) (sliders ())) (set! src-dialog (make-effect-dialog src-label (lambda (w context info) (if (eq? src-target 'sound) (src-sound src-amount) (if (eq? src-target 'selection) (if (selection?) (src-selection src-amount) (snd-print ";no selection")) (snd-print "can't apply src between marks yet")))) (lambda (w context info) (help-dialog "Sample rate conversion" "Move the slider to change the sample rate. Values greater than 1.0 speed up file play, negative values reverse it.")) (lambda (w c i) (set! src-amount initial-src-amount) (XtSetValues (car sliders) (list XmNvalue (floor (* src-amount 100))))) (lambda () (effect-target-ok src-target)))) (set! sliders (add-sliders src-dialog (list (list "sample rate" -2.0 initial-src-amount 2.0 (lambda (w context info) (set! src-amount (/ (.value info) 100.0))) 100)))) (add-target (XtParent (car sliders)) (lambda (target) (set! src-target target) (XtSetSensitive (XmMessageBoxGetChild src-dialog XmDIALOG_OK_BUTTON) (effect-target-ok target))) #f))) (activate-dialog src-dialog)) (let ((child (XtCreateManagedWidget "Sample rate scaling" xmPushButtonWidgetClass freq-menu (list XmNbackground *basic-color*)))) (XtAddCallback child XmNactivateCallback (lambda (w c i) (post-src-dialog))) (set! freq-menu-list (cons (lambda () (let ((new-label (format #f "Sample rate scaling (~1,2F)" src-amount))) (change-label child new-label))) freq-menu-list)))) ;;; -------- Time and pitch scaling by granular synthesis and sampling rate conversion ;;; (let ((time-scale 1.0) (hop-size 0.05) (segment-length 0.15) (ramp-scale 0.5) (pitch-scale 1.0) (expsrc-label "Time/pitch scaling") (expsrc-dialog #f) (expsrc-target 'sound)) (define (post-expsrc-dialog) (if (not (Widget? expsrc-dialog)) (let ((initial-time-scale 1.0) (initial-hop-size 0.05) (initial-segment-length 0.15) (initial-ramp-scale 0.5) (initial-pitch-scale 1.0) (sliders ())) (set! expsrc-dialog (make-effect-dialog expsrc-label (lambda (w context info) (let ((snd (selected-sound))) (save-controls snd) (reset-controls snd) (set! (speed-control snd) pitch-scale) (let ((new-time (* pitch-scale time-scale))) (if (not (= new-time 1.0)) (begin (set! (expand-control? snd) #t) (set! (expand-control snd) new-time) (set! (expand-control-hop snd) hop-size) (set! (expand-control-length snd) segment-length) (set! (expand-control-ramp snd) ramp-scale)))) (if (eq? expsrc-target 'marks) (let ((ms (plausible-mark-samples))) (apply-controls snd 0 (car ms) (+ 1 (- (cadr ms) (car ms))))) (apply-controls snd (if (eq? expsrc-target 'sound) 0 2))) (restore-controls snd))) (lambda (w context info) (help-dialog "Time/pitch scaling" "Move the sliders to change the time/pitch scaling parameters.")) (lambda (w c i) (set! time-scale initial-time-scale) (XtSetValues (sliders 0) (list XmNvalue (floor (* time-scale 100)))) (set! hop-size initial-hop-size) (XtSetValues (sliders 1) (list XmNvalue (floor (* hop-size 100)))) (set! segment-length initial-segment-length) (XtSetValues (sliders 2) (list XmNvalue (floor (* segment-length 100)))) (set! ramp-scale initial-ramp-scale) (XtSetValues (sliders 3) (list XmNvalue (floor (* ramp-scale 100)))) (set! pitch-scale initial-pitch-scale) (XtSetValues (sliders 4) (list XmNvalue (floor (* pitch-scale 100))))) (lambda () (effect-target-ok expsrc-target)))) (set! sliders (add-sliders expsrc-dialog (list (list "time scale" 0.0 initial-time-scale 5.0 (lambda (w context info) (set! time-scale (/ (.value info) 100.0))) 100) (list "hop size" 0.0 initial-hop-size 1.0 (lambda (w context info) (set! hop-size (/ (.value info) 100.0))) 100) (list "segment length" 0.0 initial-segment-length 0.5 (lambda (w context info) (set! segment-length (/ (.value info) 100.0))) 100) (list "ramp scale" 0.0 initial-ramp-scale 0.5 (lambda (w context info) (set! ramp-scale (/ (.value info) 100.0))) 1000) (list "pitch scale" 0.0 initial-pitch-scale 5.0 (lambda (w context info) (set! pitch-scale (/ (.value info) 100.0))) 100)))) (add-target (XtParent (car sliders)) (lambda (target) (set! expsrc-target target) (XtSetSensitive (XmMessageBoxGetChild expsrc-dialog XmDIALOG_OK_BUTTON) (effect-target-ok target))) #f))) (activate-dialog expsrc-dialog)) (let ((child (XtCreateManagedWidget "Time/pitch scaling" xmPushButtonWidgetClass freq-menu (list XmNbackground *basic-color*)))) (XtAddCallback child XmNactivateCallback (lambda (w c i) (post-expsrc-dialog))) (set! freq-menu-list (cons (lambda () (let ((new-label (format #f "Time/pitch scaling (~1,2F ~1,2F)" time-scale pitch-scale))) (change-label child new-label))) freq-menu-list)))) ;;; -------- Time-varying sample rate conversion (resample) ;;; (KSM) (let ((src-timevar-scale 1.0) (src-timevar-label "Src-Timevar") (src-timevar-dialog #f) (src-timevar-target 'sound) (src-timevar-envelope #f)) (define (scale-envelope e scl) (if (null? e) () (append (list (car e) (* scl (cadr e))) (scale-envelope (cddr e) scl)))) (define (post-src-timevar-dialog) (if (not (Widget? src-timevar-dialog)) ;; if src-timevar-dialog doesn't exist, create it (let ((initial-src-timevar-scale 1.0) (sliders ()) (fr #f)) (set! src-timevar-dialog (make-effect-dialog src-timevar-label (lambda (w context info) (let ((env (scale-envelope (xe-envelope src-timevar-envelope) src-timevar-scale))) (if (eq? src-timevar-target 'sound) (src-sound env) (if (eq? src-timevar-target 'selection) (if (selection-member? (selected-sound)) (src-selection env) (display ";no selection")) (let ((pts (plausible-mark-samples))) (if pts (let* ((beg (car pts)) (end (cadr pts)) (len (- end beg))) (src-channel (make-env env :length len) beg len (selected-sound))))))))) (lambda (w context info) (help-dialog "Src-Timevar" "Move the slider to change the src-timevar scaling amount.")) (lambda (w c i) (set! src-timevar-scale initial-src-timevar-scale) (set! (xe-envelope src-timevar-envelope) (list 0.0 1.0 1.0 1.0)) (XtSetValues (car sliders) (list XmNvalue (* src-timevar-scale 100)))) (lambda () (effect-target-ok src-timevar-target)))) (set! sliders (add-sliders src-timevar-dialog (list (list "Resample factor" 0.0 initial-src-timevar-scale 10.0 (lambda (w context info) (set! src-timevar-scale (/ (.value info) 100.0))) 100)))) (set! fr (XtCreateManagedWidget "fr" xmFrameWidgetClass (XtParent (XtParent (car sliders))) (list XmNheight 200 XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_WIDGET XmNtopWidget (sliders (- (length sliders) 1)) XmNshadowThickness 4 XmNshadowType XmSHADOW_ETCHED_OUT))) (let ((target-row (add-target (XtParent (XtParent (car sliders))) (lambda (target) (set! src-timevar-target target) (XtSetSensitive (XmMessageBoxGetChild src-timevar-dialog XmDIALOG_OK_BUTTON) (effect-target-ok target))) #f))) (activate-dialog src-timevar-dialog) (set! src-timevar-envelope (xe-create-enved "src-timevar" fr (list XmNheight 200) '(0.0 1.0 0.0 1.0))) (set! (xe-envelope src-timevar-envelope) (list 0.0 1.0 1.0 1.0)) (XtVaSetValues fr (list XmNbottomAttachment XmATTACH_WIDGET XmNbottomWidget target-row))) ) (activate-dialog src-timevar-dialog))) (let ((child (XtCreateManagedWidget "Time-varying sample rate scaling" xmPushButtonWidgetClass freq-menu (list XmNbackground *basic-color*)))) (XtAddCallback child XmNactivateCallback (lambda (w c i) (post-src-timevar-dialog))) (set! freq-menu-list (cons (lambda () (let ((new-label "Time-varying sample rate scaling")) (change-label child new-label))) freq-menu-list)))) ;-------------------------------------------------------------------------------- ) ;;; MODULATION EFFECTS ;;; (define effects-am (let ((documentation "(effects-am freq en beg dur snd chn) is used by the effects dialog to tie into edit-list->function")) (lambda* (freq en beg dur snd chn) (let ((os (make-oscil freq)) (e (and en (make-env en :length dur)))) (map-channel (if e (lambda (inval) (amplitude-modulate 1.0 inval (* (env e) (oscil os)))) (lambda (inval) (amplitude-modulate 1.0 inval (oscil os)))) beg dur snd chn #f (format #f "effects-am ~A ~A ~A ~A" freq (and en (format #f "'~A" en)) beg dur)))))) (define effects-rm (let ((documentation "(effects-rm freq gliss-env beg dur snd chn) is used by the effects dialog to tie into edit-list->function")) (lambda* (freq gliss-env beg dur snd chn) (let ((os (make-oscil freq)) (e (and gliss-env (make-env gliss-env :length dur)))) (map-channel (if e (lambda (inval) (* inval (env e) (oscil os))) (lambda (inval) (* inval (oscil os)))) beg dur snd chn #f (format #f "effects-rm ~A ~A ~A ~A" freq (and gliss-env (format #f "'~A" gliss-env)) beg dur)))))) (let* ((mod-menu-list ()) (mod-menu (XmCreatePulldownMenu (main-menu effects-menu) "Modulation Effects" (list XmNbackground *basic-color*))) (mod-cascade (XtCreateManagedWidget "Modulation Effects" xmCascadeButtonWidgetClass (main-menu effects-menu) (list XmNsubMenuId mod-menu XmNbackground *basic-color*)))) (XtAddCallback mod-cascade XmNcascadingCallback (lambda (w c i) (update-label mod-menu-list))) ;;; -------- Amplitude modulation ;;; (let ((am-effect-amount 100.0) (am-effect-label "Amplitude modulation") (am-effect-dialog #f) (am-effect-target 'sound) (am-effect-envelope #f)) (define am-effect (lambda (freq) (let* ((os (make-oscil freq)) (need-env (not (equal? (xe-envelope am-effect-envelope) (list 0.0 1.0 1.0 1.0)))) (e (and need-env (make-env (xe-envelope am-effect-envelope) :length (effect-framples am-effect-target))))) (if need-env (lambda (inval) (amplitude-modulate 1.0 inval (* (env e) (oscil os)))) (lambda (inval) (amplitude-modulate 1.0 inval (oscil os))))))) (define (post-am-effect-dialog) (if (not (Widget? am-effect-dialog)) ;; if am-effect-dialog doesn't exist, create it (let ((initial-am-effect-amount 100.0) (sliders ()) (fr #f)) (set! am-effect-dialog (make-effect-dialog am-effect-label (lambda (w context info) (map-chan-over-target-with-sync (lambda (ignored) (am-effect am-effect-amount)) am-effect-target (lambda (target samps) (format #f "effects-am ~A ~A" am-effect-amount (let* ((need-env (not (equal? (xe-envelope am-effect-envelope) (list 0.0 1.0 1.0 1.0)))) (e (and need-env (xe-envelope am-effect-envelope)))) (and e (format #f "'~A" e))))) #f)) (lambda (w context info) (help-dialog "Amplitude modulation" "Move the slider to change the modulation amount.")) (lambda (w c i) (set! am-effect-amount initial-am-effect-amount) (set! (xe-envelope am-effect-envelope) (list 0.0 1.0 1.0 1.0)) (XtSetValues (car sliders) (list XmNvalue (floor am-effect-amount)))) (lambda () (effect-target-ok am-effect-target)))) (set! sliders (add-sliders am-effect-dialog (list (list "amplitude modulation" 0.0 initial-am-effect-amount 1000.0 (lambda (w context info) (set! am-effect-amount (.value info))) 1)))) (set! fr (XtCreateManagedWidget "fr" xmFrameWidgetClass (XtParent (XtParent (car sliders))) (list XmNheight 200 XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_WIDGET XmNtopWidget (sliders (- (length sliders) 1)) XmNshadowThickness 4 XmNshadowType XmSHADOW_ETCHED_OUT))) (let ((target-row (add-target (XtParent (XtParent (car sliders))) (lambda (target) (set! am-effect-target target) (XtSetSensitive (XmMessageBoxGetChild am-effect-dialog XmDIALOG_OK_BUTTON) (effect-target-ok target))) #f))) (activate-dialog am-effect-dialog) (set! am-effect-envelope (xe-create-enved "am" fr (list XmNheight 200) '(0.0 1.0 0.0 1.0))) (set! (xe-envelope am-effect-envelope) (list 0.0 1.0 1.0 1.0)) (XtVaSetValues fr (list XmNbottomAttachment XmATTACH_WIDGET XmNbottomWidget target-row))) ) (activate-dialog am-effect-dialog))) (let ((child (XtCreateManagedWidget "Amplitude modulation" xmPushButtonWidgetClass mod-menu (list XmNbackground *basic-color*)))) (XtAddCallback child XmNactivateCallback (lambda (w c i) (post-am-effect-dialog))) (set! mod-menu-list (cons (lambda () (let ((new-label (format #f "Amplitude modulation (~1,2F)" am-effect-amount))) (change-label child new-label))) mod-menu-list)))) ;;; -------- Ring modulation ;;; (let ((rm-frequency 100) (rm-radians 100) (rm-label "Ring modulation") (rm-dialog #f) (rm-target 'sound) (rm-envelope #f)) (define rm-effect ; avoid collision with examp.scm (lambda (freq gliss-env) (let* ((os (make-oscil freq)) (need-env (and rm-envelope (not (equal? (xe-envelope rm-envelope) (list 0.0 1.0 1.0 1.0))))) (e (and need-env (make-env (xe-envelope rm-envelope) :length (effect-framples rm-target))))) (if need-env (lambda (inval) (* inval (env e) (oscil os))) (lambda (inval) (* inval (oscil os))))))) (define (post-rm-dialog) (if (not (Widget? rm-dialog)) ;; if rm-dialog doesn't exist, create it (let ((initial-rm-frequency 100) (initial-rm-radians 100) (sliders ()) (fr #f)) (set! rm-dialog (make-effect-dialog rm-label (lambda (w context info) (map-chan-over-target-with-sync (lambda (ignored) (rm-effect rm-frequency (list 0 0 1 (hz->radians rm-radians)))) rm-target (lambda (target samps) (format #f "effects-rm ~A ~A" rm-frequency (let* ((need-env (not (equal? (xe-envelope rm-envelope) (list 0.0 1.0 1.0 1.0)))) (e (and need-env (xe-envelope rm-envelope)))) (and e (format #f "'~A" e))))) #f)) (lambda (w context info) (help-dialog "Ring modulation" "Move the slider to change the ring modulation parameters.")) (lambda (w c i) (set! rm-frequency initial-rm-frequency) (set! (xe-envelope rm-envelope) (list 0.0 1.0 1.0 1.0)) (XtSetValues (car sliders) (list XmNvalue rm-frequency)) (set! rm-radians initial-rm-radians) (XtSetValues (cadr sliders) (list XmNvalue rm-radians))) (lambda () (effect-target-ok rm-target)))) (set! sliders (add-sliders rm-dialog (list (list "modulation frequency" 0 initial-rm-frequency 1000 (lambda (w context info) (set! rm-frequency (.value info))) 1) (list "modulation radians" 0 initial-rm-radians 360 (lambda (w context info) (set! rm-radians (.value info))) 1)))) (set! fr (XtCreateManagedWidget "fr" xmFrameWidgetClass (XtParent (XtParent (car sliders))) (list XmNheight 200 XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_WIDGET XmNtopWidget (sliders (- (length sliders) 1)) XmNshadowThickness 4 XmNshadowType XmSHADOW_ETCHED_OUT))) (let ((target-row (add-target (XtParent (XtParent (car sliders))) (lambda (target) (set! rm-target target) (XtSetSensitive (XmMessageBoxGetChild rm-dialog XmDIALOG_OK_BUTTON) (effect-target-ok target))) #f))) (activate-dialog rm-dialog) (set! rm-envelope (xe-create-enved "rm frequency" fr (list XmNheight 200) '(0.0 1.0 0.0 1.0))) (set! (xe-envelope rm-envelope) (list 0.0 1.0 1.0 1.0)) (XtVaSetValues fr (list XmNbottomAttachment XmATTACH_WIDGET XmNbottomWidget target-row))) ) (activate-dialog rm-dialog))) (let ((child (XtCreateManagedWidget "Ring modulation" xmPushButtonWidgetClass mod-menu (list XmNbackground *basic-color*)))) (XtAddCallback child XmNactivateCallback (lambda (w c i) (post-rm-dialog))) (set! mod-menu-list (cons (lambda () (let ((new-label (format #f "Ring modulation (~D ~D)" rm-frequency rm-radians))) (change-label child new-label))) mod-menu-list)))) ) ;;; REVERBS ;;; (define effects-cnv (let ((documentation "(effects-cnv snd0-1 amp snd chn) is used by the effects dialog to tie into edit-list->function")) (lambda* (snd0-1 amp snd chn) (let* ((snd0 (if (sound? snd0-1) snd0-1 (car (sounds)))) (flt-len (framples snd0)) (total-len (+ flt-len (framples snd chn))) (cnv (make-convolve :filter (channel->float-vector 0 flt-len snd0) :input (make-sampler 0 snd chn))) (out-data (make-float-vector total-len))) (do ((i 0 (+ i 1))) ((= i total-len)) (set! (out-data i) (convolve cnv))) (float-vector-scale! out-data amp) (let ((max-samp (float-vector-peak out-data))) (float-vector->channel out-data 0 total-len snd chn #f (format #f "effects-cnv ~A ~A" snd0 amp)) (if (> max-samp 1.0) (set! (y-bounds snd chn) (list (- max-samp) max-samp))) max-samp))))) (define effects-jc-reverb (let ((documentation "(effects-jc-reverb volume beg dur snd chn) is used by the effects dialog to tie into edit-list->function")) (lambda* (volume beg dur snd chn) (let ((allpass1 (make-all-pass -0.700 0.700 1051)) (allpass2 (make-all-pass -0.700 0.700 337)) (allpass3 (make-all-pass -0.700 0.700 113)) (comb1 (make-comb 0.742 4799)) (comb2 (make-comb 0.733 4999)) (comb3 (make-comb 0.715 5399)) (comb4 (make-comb 0.697 5801)) (outdel1 (make-delay (round (* .013 (srate))))) (e (make-env '(0 1 1 0) :scaler volume :base 0.0 :length dur))) (let ((combs (make-comb-bank (vector comb1 comb2 comb3 comb4))) (allpasses (make-all-pass-bank (vector allpass1 allpass2 allpass3)))) (lambda (inval) (+ inval (delay outdel1 (comb-bank combs (all-pass-bank allpasses (* inval (env e)))))))))))) (define* (effects-jc-reverb-1 volume beg dur snd chn) (map-channel (effects-jc-reverb volume (or beg 0) (or dur (framples snd chn)) snd chn) (or beg 0) dur snd chn #f (format #f "effects-jc-reverb-1 ~A ~A ~A" volume beg dur))) (let* ((reverb-menu-list ()) (reverb-menu (XmCreatePulldownMenu (main-menu effects-menu) "Reverbs" (list XmNbackground *basic-color*))) (reverb-cascade (XtCreateManagedWidget "Reverbs" xmCascadeButtonWidgetClass (main-menu effects-menu) (list XmNsubMenuId reverb-menu XmNbackground *basic-color*)))) (XtAddCallback reverb-cascade XmNcascadingCallback (lambda (w c i) (update-label reverb-menu-list))) ;;; -------- Reverb from Michael McNabb's Nrev ;;; -------- very nice reverb actually ;;; ;;; (truncate) (let ((reverb-amount 0.1) (reverb-filter 0.5) (reverb-feedback 1.09) (reverb-label "McNabb reverb") (reverb-dialog #f) (reverb-target 'sound)) ;; add reverb-control-decay (with ramp?) and reverb-truncate (define (post-reverb-dialog) (if (not (Widget? reverb-dialog)) ;; if reverb-dialog doesn't exist, create it (let ((initial-reverb-amount 0.1) (initial-reverb-filter 0.5) (initial-reverb-feedback 1.09) (sliders ())) (set! reverb-dialog (make-effect-dialog reverb-label (lambda (w context info) (let ((snd (selected-sound))) (save-controls snd) (reset-controls snd) (set! (reverb-control? snd) #t) (set! (reverb-control-scale snd) reverb-amount) (set! (reverb-control-lowpass snd) reverb-filter) (set! (reverb-control-feedback snd) reverb-feedback) (if (eq? reverb-target 'marks) (let ((ms (plausible-mark-samples))) (apply-controls snd 0 (car ms) (+ 1 (- (cadr ms) (car ms))))) (apply-controls snd (if (eq? reverb-target 'sound) 0 2))) (restore-controls snd))) (lambda (w context info) (help-dialog "McNabb reverb" "Reverberator from Michael McNabb. Adds reverberation scaled by reverb amount, lowpass filtering, and feedback. Move the sliders to change the reverb parameters.")) (lambda (w c i) (set! reverb-amount initial-reverb-amount) (XtSetValues (car sliders) (list XmNvalue (floor (* reverb-amount 100)))) (set! reverb-filter initial-reverb-filter) (XtSetValues (cadr sliders) (list XmNvalue (floor (* reverb-filter 100)))) (set! reverb-feedback initial-reverb-feedback) (XtSetValues (caddr sliders) (list XmNvalue (floor (* reverb-feedback 100))))) (lambda () (effect-target-ok reverb-target)))) (set! sliders (add-sliders reverb-dialog (list (list "reverb amount" 0.0 initial-reverb-amount 1.0 (lambda (w context info) (set! reverb-amount (/ (.value info) 100.0))) 100) (list "reverb filter" 0.0 initial-reverb-filter 1.0 (lambda (w context info) (set! reverb-filter (/ (.value info) 100.0))) 100) (list "reverb feedback" 0.0 initial-reverb-feedback 1.25 (lambda (w context info) (set! reverb-feedback (/ (.value info) 100.0))) 100)))) (add-target (XtParent (car sliders)) (lambda (target) (set! reverb-target target) (XtSetSensitive (XmMessageBoxGetChild reverb-dialog XmDIALOG_OK_BUTTON) (effect-target-ok target))) #f))) (activate-dialog reverb-dialog)) (let ((child (XtCreateManagedWidget "McNabb reverb" xmPushButtonWidgetClass reverb-menu (list XmNbackground *basic-color*)))) (XtAddCallback child XmNactivateCallback (lambda (w c i) (post-reverb-dialog))) (set! reverb-menu-list (cons (lambda () (let ((new-label (format #f "McNabb reverb (~1,2F ~1,2F ~1,2F)" reverb-amount reverb-filter reverb-feedback))) (change-label child new-label))) reverb-menu-list)))) ;;; -------- Chowning reverb ;;; (let ((jc-reverb-decay 2.0) (jc-reverb-volume 0.1) (jc-reverb-label "Chowning reverb") (jc-reverb-dialog #f) (jc-reverb-target 'sound) (jc-reverb-truncate #f)) (define (post-jc-reverb-dialog) (if (not (Widget? jc-reverb-dialog)) ;; if jc-reverb-dialog doesn't exist, create it (let ((initial-jc-reverb-decay 2.0) (initial-jc-reverb-volume 0.1) (sliders ())) (set! jc-reverb-dialog (make-effect-dialog jc-reverb-label (lambda (w context info) ;(pad-channel (- (framples) 1) (srate)) (map-chan-over-target-with-sync (lambda (samps) (effects-jc-reverb jc-reverb-volume samps (framples))) jc-reverb-target (lambda (target samps) (format #f "effects-jc-reverb-1 ~A" jc-reverb-volume)) (and (not jc-reverb-truncate) jc-reverb-decay))) (lambda (w context info) (help-dialog "Chowning reverb" "Nice reverb from John Chowning. Move the sliders to set the reverb parameters.")) (lambda (w c i) (set! jc-reverb-decay initial-jc-reverb-decay) (XtSetValues (sliders 0) (list XmNvalue (floor (* jc-reverb-decay 100)))) (set! jc-reverb-volume initial-jc-reverb-volume) (XtSetValues (sliders 1) (list XmNvalue (floor (* jc-reverb-volume 100))))) (lambda () (effect-target-ok jc-reverb-target)))) (set! sliders (add-sliders jc-reverb-dialog (list (list "decay duration" 0.0 initial-jc-reverb-decay 10.0 (lambda (w context info) (set! jc-reverb-decay (/ (.value info) 100))) 100) (list "reverb volume" 0.0 initial-jc-reverb-volume 1.0 (lambda (w context info) (set! jc-reverb-volume (/ (.value info) 100))) 100)))) (add-target (XtParent (car sliders)) (lambda (target) (set! jc-reverb-target target) (XtSetSensitive (XmMessageBoxGetChild jc-reverb-dialog XmDIALOG_OK_BUTTON) (effect-target-ok target))) (lambda (truncate) (set! jc-reverb-truncate truncate))))) (activate-dialog jc-reverb-dialog)) (let ((child (XtCreateManagedWidget "Chowning reverb" xmPushButtonWidgetClass reverb-menu (list XmNbackground *basic-color*)))) (XtAddCallback child XmNactivateCallback (lambda (w c i) (post-jc-reverb-dialog))) (set! reverb-menu-list (cons (lambda () (let ((new-label (format #f "Chowning reverb (~1,2F ~1,2F)" jc-reverb-decay jc-reverb-volume))) (change-label child new-label))) reverb-menu-list)))) ;;; -------- Convolution ;;; ;;; (progress report? truncate?) (let ((convolve-sound-one 0) (convolve-sound-two 1) (convolve-amp 0.01) (convolve-label "Convolution") (convolve-dialog #f)) (define (post-convolve-dialog) (if (not (Widget? convolve-dialog)) ;; if convolve-dialog doesn't exist, create it (let ((initial-convolve-sound-one 0) (initial-convolve-sound-two 1) (initial-convolve-amp 0.01) (sliders ())) (set! convolve-dialog (make-effect-dialog convolve-label (lambda (w context info) (effects-cnv convolve-sound-one convolve-amp convolve-sound-two)) (lambda (w context info) (help-dialog "Convolution" "Very simple convolution. Move the sliders to set the numbers of the soundfiles to be convolved and the amount for the amplitude scaler. Output will be scaled to floating-point values, resulting in very large (but not clipped) amplitudes. Use the Normalize amplitude effect to rescale the output. The convolution data file typically defines a natural reverberation source, and the output from this effect can provide very striking reverb effects. You can find convolution data files on sites listed at http://www.bright.net/~dlphilp/linux_csound.html under Impulse Response Data.")) (lambda (w c i) (set! convolve-sound-one initial-convolve-sound-one) (XtSetValues (sliders 0) (list XmNvalue convolve-sound-one)) (set! convolve-sound-two initial-convolve-sound-two) (XtSetValues (sliders 1) (list XmNvalue convolve-sound-two)) (set! convolve-amp initial-convolve-amp) (XtSetValues (sliders 2) (list XmNvalue (floor (* convolve-amp 100))))) (lambda () (pair? (sounds))))) (set! sliders (add-sliders convolve-dialog (list (list "impulse response file" 0 initial-convolve-sound-one 24 (lambda (w context info) (set! convolve-sound-one (.value info))) 1) (list "sound file" 0 initial-convolve-sound-two 24 (lambda (w context info) (set! convolve-sound-two (.value info))) 1) (list "amplitude" 0.0 initial-convolve-amp 0.10 (lambda (w context info) (set! convolve-amp (/ (.value info) 100.0))) 1000)))))) (activate-dialog convolve-dialog)) (let ((child (XtCreateManagedWidget "Convolution" xmPushButtonWidgetClass reverb-menu (list XmNbackground *basic-color*)))) (XtAddCallback child XmNactivateCallback (lambda (w c i) (post-convolve-dialog))) (set! reverb-menu-list (cons (lambda () (let ((new-label (format #f "Convolution (~D ~D ~1,2F)" convolve-sound-one convolve-sound-two convolve-amp))) (change-label child new-label))) reverb-menu-list)))) ) ;;; VARIOUS AND MISCELLANEOUS ;;; (define effects-hello-dentist (let ((documentation "(hello-dentist frq amp snd chn) varies the sampling rate randomly, making a voice sound quavery: (hello-dentist 40.0 .1)")) (lambda* (frq amp beg dur snd chn) (let* ((rn (make-rand-interp :frequency frq :amplitude amp)) (len (or dur (- (framples snd chn) beg))) (sf (make-sampler beg snd chn)) (rd (make-src :srate 1.0 :input (lambda (dir) (read-sample-with-direction sf dir))))) (map-channel (lambda (y) (src rd (rand-interp rn))) beg len snd chn #f (format #f "effects-hello-dentist ~A ~A ~A ~A" frq amp beg (and (not (= len (framples snd chn))) len))))))) (define* (effects-fp sr osamp osfrq beg dur snd chn) (let* ((os (make-oscil osfrq)) (len (framples snd chn)) (sf (make-sampler beg snd chn)) (s (make-src :srate sr :input (lambda (dir) (read-sample-with-direction sf dir))))) (map-channel (lambda (y) (src s (* osamp (oscil os)))) beg len snd chn #f (format #f "effects-fp ~A ~A ~A ~A ~A" sr osamp osfrq beg (and (not (= len (framples snd chn))) len))))) (define effects-position-sound (let ((documentation "(effects-position-sound mono-snd pos-1 snd chn) is used by the effects dialog to tie into edit-list->function")) (lambda* (mono-snd pos snd chn) (let ((len (framples mono-snd)) (reader1 (make-sampler 0 mono-snd))) (if (number? pos) (map-channel (lambda (y) (+ y (* pos (read-sample reader1)))) 0 len snd chn #f (format #f "effects-position-sound ~A ~A" mono-snd pos)) (let ((e1 (make-env pos :length len))) (if (and (number? chn) (= chn 1)) (map-channel (lambda (y) (+ y (* (env e1) (read-sample reader1)))) 0 len snd chn #f (format #f "effects-position-sound ~A '~A" mono-snd pos)) (map-channel (lambda (y) (+ y (* (- 1.0 (env e1)) (read-sample reader1)))) 0 len snd chn #f (format #f "effects-position-sound ~A '~A" mono-snd pos))))))))) (define effects-flange (let ((documentation "(effects-flange amount speed time beg dur snd chn) is used by the effects dialog to tie into edit-list->function")) (lambda* (amount speed time beg dur snd chn) (let* ((ri (make-rand-interp :frequency speed :amplitude amount)) (len (round (* time (srate snd)))) (del (make-delay len :max-size (round (+ len amount 1))))) (map-channel (lambda (inval) (* .75 (+ inval (delay del inval (rand-interp ri))))) beg dur snd chn #f (format #f "effects-flange ~A ~A ~A ~A ~A" amount speed time beg (and (number? dur) (not (= dur (framples snd chn))) dur))))))) (define effects-cross-synthesis (let ((documentation "(effects-cross-synthesis cross-snd amp fftsize r) is used by the effects dialog to tie into edit-list->function")) (lambda (cross-snd amp fftsize r) ;; cross-snd is the index of the other sound (as opposed to the map-channel sound) (let* ((freq-inc (/ fftsize 2)) (fdr (make-float-vector fftsize)) (fdi (make-float-vector fftsize)) (spectr (make-float-vector freq-inc)) (inctr 0) (ctr freq-inc) (radius (- 1.0 (/ r fftsize))) (bin (/ (srate) fftsize)) (formants (make-vector freq-inc))) (do ((i 0 (+ 1 i))) ((= i freq-inc)) (set! (formants i) (make-formant (* i bin) radius))) (set! formants (make-formant-bank formants spectr)) (lambda (inval) (if (= ctr freq-inc) (begin (set! fdr (channel->float-vector inctr fftsize cross-snd 0)) (set! inctr (+ inctr freq-inc)) (spectrum fdr fdi #f 2) (float-vector-subtract! fdr spectr) (float-vector-scale! fdr (/ 1.0 freq-inc)) (set! ctr 0))) (set! ctr (+ ctr 1)) (float-vector-add! spectr fdr) (* amp (formant-bank formants inval))))))) (define effects-cross-synthesis-1 (let ((documentation "(effects-cross-synthesis-1 cross-snd amp fftsize r beg dur snd chn) is used by the effects dialog to tie into edit-list->function")) (lambda* (cross-snd amp fftsize r beg dur snd chn) (map-channel (effects-cross-synthesis (if (sound? cross-snd) cross-snd (car (sounds))) amp fftsize r) beg dur snd chn #f (format #f "effects-cross-synthesis-1 ~A ~A ~A ~A ~A ~A" cross-snd amp fftsize r beg dur))))) (let* ((misc-menu-list ()) (misc-menu (XmCreatePulldownMenu (main-menu effects-menu) "Various" (list XmNbackground *basic-color*))) (misc-cascade (XtCreateManagedWidget "Various" xmCascadeButtonWidgetClass (main-menu effects-menu) (list XmNsubMenuId misc-menu XmNbackground *basic-color*)))) (XtAddCallback misc-cascade XmNcascadingCallback (lambda (w c i) (update-label misc-menu-list))) ;;; -------- Place sound ;;; (let ((mono-snd 0) (stereo-snd 1) (pan-pos 45) (place-sound-label "Place sound") (place-sound-dialog #f) (place-sound-target 'sound) (place-sound-envelope #f)) (define (place-sound mono-snd stereo-snd pan-env) ;; (place-sound mono-snd stereo-snd pan-env) mixes a mono sound into a stereo sound, splitting ;; it into two copies whose amplitudes depend on the envelope 'pan-env'. If 'pan-env' is ;; a number, the sound is split such that 0 is all in channel 0 and 90 is all in channel 1. (if (number? pan-env) (let ((pos (/ pan-env 90.0))) (effects-position-sound mono-snd pos stereo-snd 1) (effects-position-sound mono-snd (- 1.0 pos) stereo-snd 0)) (begin (effects-position-sound mono-snd pan-env stereo-snd 1) (effects-position-sound mono-snd pan-env stereo-snd 0)))) (define (post-place-sound-dialog) (if (not (Widget? place-sound-dialog)) (let ((initial-mono-snd 0) (initial-stereo-snd 1) (initial-pan-pos 45) (sliders ()) (fr #f)) (set! place-sound-dialog (make-effect-dialog place-sound-label (lambda (w context info) (let ((e (xe-envelope place-sound-envelope))) (if (not (equal? e (list 0.0 1.0 1.0 1.0))) (place-sound mono-snd stereo-snd e) (place-sound mono-snd stereo-snd pan-pos)))) (lambda (w context info) (help-dialog "Place sound" "Mixes mono sound into stereo sound field.")) (lambda (w c i) (set! mono-snd initial-mono-snd) (XtSetValues (sliders 0) (list XmNvalue mono-snd)) (set! stereo-snd initial-stereo-snd) (XtSetValues (sliders 1) (list XmNvalue stereo-snd)) (set! pan-pos initial-pan-pos) (XtSetValues (sliders 2) (list XmNvalue pan-pos))) (lambda () (effect-target-ok place-sound-target)))) (set! sliders (add-sliders place-sound-dialog (list (list "mono sound" 0 initial-mono-snd 50 (lambda (w context info) (set! mono-snd (.value info))) 1) (list "stereo sound" 0 initial-stereo-snd 50 (lambda (w context info) (set! stereo-snd (.value info))) 1) (list "pan position" 0 initial-pan-pos 90 (lambda (w context info) (set! pan-pos (.value info))) 1)))) (set! fr (XtCreateManagedWidget "fr" xmFrameWidgetClass (XtParent (XtParent (car sliders))) (list XmNheight 200 XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_WIDGET XmNbottomAttachment XmATTACH_FORM XmNtopWidget (sliders (- (length sliders) 1)) XmNshadowThickness 4 XmNshadowType XmSHADOW_ETCHED_OUT))) (activate-dialog place-sound-dialog) (set! place-sound-envelope (xe-create-enved "panning" fr (list XmNheight 200 XmNbottomAttachment XmATTACH_FORM ) '(0.0 1.0 0.0 1.0))) (set! (xe-envelope place-sound-envelope) (list 0.0 1.0 1.0 1.0)) )) (activate-dialog place-sound-dialog)) (let ((child (XtCreateManagedWidget "Place sound" xmPushButtonWidgetClass misc-menu (list XmNbackground *basic-color*)))) (XtAddCallback child XmNactivateCallback (lambda (w c i) (post-place-sound-dialog))) (set! misc-menu-list (cons (lambda () (let ((new-label (format #f "Place sound (~D ~D ~D)" mono-snd stereo-snd pan-pos))) (change-label child new-label))) misc-menu-list)))) ;;; -------- Insert silence (at cursor, silence-amount in secs) ;;; (let ((silence-amount 1.0) (silence-label "Add silence") (silence-dialog #f)) (define (post-silence-dialog) (if (not (Widget? silence-dialog)) ;; if silence-dialog doesn't exist, create it (let ((initial-silence-amount 1.0) (sliders ())) (set! silence-dialog (make-effect-dialog silence-label (lambda (w context info) (insert-silence (cursor) (floor (* (srate) silence-amount)))) (lambda (w context info) (help-dialog "Add silence" "Move the slider to change the number of seconds of silence added at the cursor position.")) (lambda (w c i) (set! silence-amount initial-silence-amount) (XtSetValues (car sliders) (list XmNvalue (floor (* silence-amount 100))))) (lambda () (pair? (sounds))))) (set! sliders (add-sliders silence-dialog (list (list "silence" 0.0 initial-silence-amount 5.0 (lambda (w context info) (set! silence-amount (/ (.value info) 100.0))) 100)))))) (activate-dialog silence-dialog)) (let ((child (XtCreateManagedWidget "Add silence" xmPushButtonWidgetClass misc-menu (list XmNbackground *basic-color*)))) (XtAddCallback child XmNactivateCallback (lambda (w c i) (post-silence-dialog))) (set! misc-menu-list (cons (lambda () (let ((new-label (format #f "Add silence (~1,2F)" silence-amount))) (change-label child new-label))) misc-menu-list)))) ;;; -------- Contrast (brightness control) ;;; (let ((contrast-amount 1.0) (contrast-label "Contrast enhancement") (contrast-dialog #f) (contrast-target 'sound)) (define (post-contrast-dialog) (if (not (Widget? contrast-dialog)) ;; if contrast-dialog doesn't exist, create it (let ((initial-contrast-amount 1.0) (sliders ())) (set! contrast-dialog (make-effect-dialog contrast-label (lambda (w context info) (let ((peak (maxamp)) (snd (selected-sound))) (save-controls snd) (reset-controls snd) (set! (contrast-control? snd) #t) (set! (contrast-control snd) contrast-amount) (set! (contrast-control-amp snd) (/ 1.0 peak)) (set! (amp-control snd) peak) (if (eq? contrast-target 'marks) (let ((ms (plausible-mark-samples))) (apply-controls snd 0 (car ms) (+ 1 (- (cadr ms) (car ms))))) (apply-controls snd (if (eq? contrast-target 'sound) 0 2))) (restore-controls snd))) (lambda (w context info) (help-dialog "Contrast enhancement" "Move the slider to change the contrast intensity.")) (lambda (w c i) (set! contrast-amount initial-contrast-amount) (XtSetValues (car sliders) (list XmNvalue (floor (* contrast-amount 100))))) (lambda () (effect-target-ok contrast-target)))) (set! sliders (add-sliders contrast-dialog (list (list "contrast enhancement" 0.0 initial-contrast-amount 10.0 (lambda (w context info) (set! contrast-amount (/ (.value info) 100.0))) 100)))) (add-target (XtParent (car sliders)) (lambda (target) (set! contrast-target target) (XtSetSensitive (XmMessageBoxGetChild contrast-dialog XmDIALOG_OK_BUTTON) (effect-target-ok target))) #f))) (activate-dialog contrast-dialog)) (let ((child (XtCreateManagedWidget "Contrast enhancement" xmPushButtonWidgetClass misc-menu (list XmNbackground *basic-color*)))) (XtAddCallback child XmNactivateCallback (lambda (w c i) (post-contrast-dialog))) (set! misc-menu-list (cons (lambda () (let ((new-label (format #f "Contrast enhancement (~1,2F)" contrast-amount))) (change-label child new-label))) misc-menu-list)))) ;;; -------- Cross synthesis ;;; (let ((cross-synth-sound 1) (cross-synth-amp .5) (cross-synth-fft-size 128) (cross-synth-radius 6.0) (cross-synth-label "Cross synthesis") (cross-synth-dialog #f) (cross-synth-default-fft-widget #f) (cross-synth-target 'sound)) (define (post-cross-synth-dialog) (if (not (Widget? cross-synth-dialog)) ;; if cross-synth-dialog doesn't exist, create it (let ((initial-cross-synth-sound 1) (initial-cross-synth-amp .5) (initial-cross-synth-fft-size 128) (initial-cross-synth-radius 6.0) (sliders ())) (set! cross-synth-dialog (make-effect-dialog cross-synth-label (lambda (w context info) (map-chan-over-target-with-sync (lambda (ignored) (effects-cross-synthesis cross-synth-sound cross-synth-amp cross-synth-fft-size cross-synth-radius)) cross-synth-target (lambda (target samps) (format #f "effects-cross-synthesis-1 ~A ~A ~A ~A" cross-synth-sound cross-synth-amp cross-synth-fft-size cross-synth-radius)) #f)) (lambda (w context info) (help-dialog "Cross synthesis" "The sliders set the number of the soundfile to be cross-synthesized, the synthesis amplitude, the FFT size, and the radius value.")) (lambda (w c i) (set! cross-synth-sound initial-cross-synth-sound) (XtSetValues (sliders 0) (list XmNvalue cross-synth-sound)) (set! cross-synth-amp initial-cross-synth-amp) (XtSetValues (sliders 1) (list XmNvalue (floor (* cross-synth-amp 100)))) (set! cross-synth-fft-size initial-cross-synth-fft-size) (if use-combo-box-for-fft-size ; defined in effects-utils.scm (XtSetValues cross-synth-default-fft-widget (list XmNselectedPosition 1)) (XmToggleButtonSetState cross-synth-default-fft-widget #t #t)) (set! cross-synth-radius initial-cross-synth-radius) (XtSetValues (sliders 2) (list XmNvalue (floor (* cross-synth-radius 100))))) (lambda () (effect-target-ok cross-synth-target)))) (set! sliders (add-sliders cross-synth-dialog (list (list "input sound" 0 initial-cross-synth-sound 20 (lambda (w context info) (set! cross-synth-sound (.value info))) 1) (list "amplitude" 0.0 initial-cross-synth-amp 1.0 (lambda (w context info) (set! cross-synth-amp (/ (.value info) 100))) 100) (list "radius" 0.0 initial-cross-synth-radius 360.0 (lambda (w context info) (set! cross-synth-radius (/ (.value info) 100))) 100)))) ;; now add either a radio-button box or a combo-box for the fft size ;; need to use XtParent here since "mainform" isn't returned by add-sliders (if use-combo-box-for-fft-size ;; this block creates a "combo box" to handle the fft size (let* ((s1 (XmStringCreateLocalized "FFT size")) (frame (XtCreateManagedWidget "frame" xmFrameWidgetClass (XtParent (car sliders)) (list XmNborderWidth 1 XmNshadowType XmSHADOW_ETCHED_IN XmNpositionIndex 2))) (frm (XtCreateManagedWidget "frm" xmFormWidgetClass frame (list XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_FORM XmNbackground *basic-color*))) (lab (XtCreateManagedWidget "FFT size" xmLabelWidgetClass frm (list XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_NONE XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_FORM XmNlabelString s1 XmNbackground *basic-color*))) (fft-labels (map XmStringCreateLocalized (list "64" "128" "256" "512" "1024" "4096"))) (combo (XtCreateManagedWidget "fftsize" xmComboBoxWidgetClass frm (list XmNleftAttachment XmATTACH_WIDGET XmNleftWidget lab XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_FORM XmNitems fft-labels XmNitemCount (length fft-labels) XmNcomboBoxType XmDROP_DOWN_COMBO_BOX XmNbackground *basic-color*)))) (set! cross-synth-default-fft-widget combo) (for-each XmStringFree fft-labels) (XmStringFree s1) (XtSetValues combo (list XmNselectedPosition 1)) (XtAddCallback combo XmNselectionCallback (lambda (w c i) (let* ((selected (.item_or_text i)) (size-as-string (XmStringUnparse selected #f XmCHARSET_TEXT XmCHARSET_TEXT #f 0 XmOUTPUT_ALL))) (set! cross-synth-fft-size (string->number size-as-string)))))) ;; this block creates a "radio button box" (let* ((s1 (XmStringCreateLocalized "FFT size")) (frame (XtCreateManagedWidget "frame" xmFrameWidgetClass (XtParent (car sliders)) (list XmNborderWidth 1 XmNshadowType XmSHADOW_ETCHED_IN XmNpositionIndex 2))) (frm (XtCreateManagedWidget "frm" xmFormWidgetClass frame (list XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_FORM XmNbackground *basic-color*))) (rc (XtCreateManagedWidget "rc" xmRowColumnWidgetClass frm (list XmNorientation XmHORIZONTAL XmNradioBehavior #t XmNradioAlwaysOne #t XmNentryClass xmToggleButtonWidgetClass XmNisHomogeneous #t XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_NONE XmNbackground *basic-color*)))) (XtCreateManagedWidget "FFT size" xmLabelWidgetClass frm (list XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_WIDGET XmNtopWidget rc XmNbottomAttachment XmATTACH_FORM XmNlabelString s1 XmNalignment XmALIGNMENT_BEGINNING XmNbackground *basic-color*)) (for-each (lambda (size) (let ((button (XtCreateManagedWidget (format #f "~D" size) xmToggleButtonWidgetClass rc (list XmNbackground *basic-color* XmNvalueChangedCallback (list (lambda (w c i) (if (.set i) (set! cross-synth-fft-size c))) size) XmNset (= size cross-synth-fft-size))))) (if (= size cross-synth-fft-size) (set! cross-synth-default-fft-widget button)))) (list 64 128 256 512 1024 4096)) (XmStringFree s1))) (add-target (XtParent (car sliders)) (lambda (target) (set! cross-synth-target target) (XtSetSensitive (XmMessageBoxGetChild cross-synth-dialog XmDIALOG_OK_BUTTON) (effect-target-ok target))) #f))) (activate-dialog cross-synth-dialog)) (let ((child (XtCreateManagedWidget "Cross synthesis" xmPushButtonWidgetClass misc-menu (list XmNbackground *basic-color*)))) (XtAddCallback child XmNactivateCallback (lambda (w c i) (post-cross-synth-dialog))) (set! misc-menu-list (cons (lambda () (let ((new-label (format #f "Cross synthesis (~D ~1,2F ~D ~1,2F)" cross-synth-sound cross-synth-amp cross-synth-fft-size cross-synth-radius))) (change-label child new-label))) misc-menu-list)))) ;;; -------- Flange and phasing ;;; (let ((flange-speed 2.0) (flange-amount 5.0) (flange-time 0.001) (flange-label "Flange") (flange-dialog #f) (flange-target 'sound)) (define (post-flange-dialog) (if (not (Widget? flange-dialog)) ;; if flange-dialog doesn't exist, create it (let ((initial-flange-speed 2.0) (initial-flange-amount 5.0) (initial-flange-time 0.001) (sliders ())) (set! flange-dialog (make-effect-dialog flange-label (lambda (w context info) (map-chan-over-target-with-sync (lambda (ignored) (let* ((ri (make-rand-interp :frequency flange-speed :amplitude flange-amount)) (len (round (* flange-time (srate)))) (del (make-delay len :max-size (round (+ len flange-amount 1))))) (lambda (inval) (* .75 (+ inval (delay del inval (rand-interp ri))))))) flange-target (lambda (target samps) (format #f "effects-flange ~A ~A ~A" flange-amount flange-speed flange-time)) #f)) (lambda (w context info) (help-dialog "Flange" "Move the sliders to change the flange speed, amount, and time")) (lambda (w c i) (set! flange-speed initial-flange-speed) (XtSetValues (car sliders) (list XmNvalue (floor (* flange-speed 10)))) (set! flange-amount initial-flange-amount) (XtSetValues (cadr sliders) (list XmNvalue (floor (* flange-amount 10)))) (set! flange-time initial-flange-time) (XtSetValues (caddr sliders) (list XmNvalue (floor (* flange-time 100))))) (lambda () (effect-target-ok flange-target)))) (set! sliders (add-sliders flange-dialog (list (list "flange speed" 0.0 initial-flange-speed 100.0 (lambda (w context info) (set! flange-speed (/ (.value info) 10.0))) 10) (list "flange amount" 0.0 initial-flange-amount 100.0 (lambda (w context info) (set! flange-amount (/ (.value info) 10.0))) 10) ;; flange time ought to use a non-linear scale (similar to amp in control panel) (list "flange time" 0.0 initial-flange-time 1.0 (lambda (w context info) (set! flange-time (/ (.value info) 100.0))) 100)))) (add-target (XtParent (car sliders)) (lambda (target) (set! flange-target target) (XtSetSensitive (XmMessageBoxGetChild flange-dialog XmDIALOG_OK_BUTTON) (effect-target-ok target))) #f))) (activate-dialog flange-dialog)) (let ((child (XtCreateManagedWidget "Flange" xmPushButtonWidgetClass misc-menu (list XmNbackground *basic-color*)))) (XtAddCallback child XmNactivateCallback (lambda (w c i) (post-flange-dialog))) (set! misc-menu-list (cons (lambda () (let ((new-label (format #f "Flange (~1,2F ~1,2F ~1,3F)" flange-speed flange-amount flange-time))) (change-label child new-label))) misc-menu-list)))) ;;; -------- Randomize phase ;;; ;;; (source, progress, target) (let ((random-phase-amp-scaler 3.14) (random-phase-label "Randomize phase") (random-phase-dialog #f)) (define (post-random-phase-dialog) (if (not (Widget? random-phase-dialog)) ;; if random-phase-dialog doesn't exist, create it (let ((initial-random-phase-amp-scaler 3.14) (sliders ())) (set! random-phase-dialog (make-effect-dialog random-phase-label (lambda (w context info) (rotate-phase (lambda (x) (random random-phase-amp-scaler)))) (lambda (w context info) (help-dialog "Randomize phase" "Move the slider to change the randomization amplitude scaler.")) (lambda (w c i) (set! random-phase-amp-scaler initial-random-phase-amp-scaler) (XtSetValues (car sliders) (list XmNvalue (floor (* random-phase-amp-scaler 100))))) (lambda () (pair? (sounds))))) (set! sliders (add-sliders random-phase-dialog (list (list "amplitude scaler" 0.0 initial-random-phase-amp-scaler 100.0 (lambda (w context info) (set! random-phase-amp-scaler (/ (.value info) 100.0))) 100)))))) (activate-dialog random-phase-dialog)) (let ((child (XtCreateManagedWidget "Randomize phase" xmPushButtonWidgetClass misc-menu (list XmNbackground *basic-color*)))) (XtAddCallback child XmNactivateCallback (lambda (w c i) (post-random-phase-dialog))) (set! misc-menu-list (cons (lambda () (let ((new-label (format #f "Randomize phase (~1,2F)" random-phase-amp-scaler))) (change-label child new-label))) misc-menu-list)))) ;;; -------- Robotize ;;; ;;; (progress report?) (let ((samp-rate 1.0) (osc-amp 0.3) (osc-freq 20) (robotize-label "Robotize") (robotize-dialog #f) (robotize-target 'sound)) (define (post-robotize-dialog) (if (not (Widget? robotize-dialog)) ;; if robotize-dialog doesn't exist, create it (let ((initial-samp-rate 1.0) (initial-osc-amp 0.3) (initial-osc-freq 20) (sliders ())) (set! robotize-dialog (make-effect-dialog robotize-label (lambda (w context info) (let ((ms (and (eq? robotize-target 'marks) (plausible-mark-samples)))) (effects-fp samp-rate osc-amp osc-freq (if (eq? robotize-target 'sound) 0 (if (eq? robotize-target 'selection) (selection-position) (car ms))) (if (eq? robotize-target 'sound) (framples) (if (eq? robotize-target 'selection) (selection-framples) (- (cadr ms) (car ms))))))) (lambda (w context info) (help-dialog "Robotize" "Move the sliders to set the sample rate, oscillator amplitude, and oscillator frequency.")) (lambda (w c i) (set! samp-rate initial-samp-rate) (XtSetValues (car sliders) (list XmNvalue (floor (* samp-rate 100)))) (set! osc-amp initial-osc-amp) (XtSetValues (cadr sliders) (list XmNvalue (floor (* osc-amp 100)))) (set! osc-freq initial-osc-freq) (XtSetValues (caddr sliders) (list XmNvalue (floor (* osc-freq 100))))) (lambda () (effect-target-ok robotize-target)))) (set! sliders (add-sliders robotize-dialog (list (list "sample rate" 0.0 initial-samp-rate 2.0 (lambda (w context info) (set! samp-rate (/ (.value info) 100.0))) 100) (list "oscillator amplitude" 0.0 initial-osc-amp 1.0 (lambda (w context info) (set! osc-amp (/ (.value info) 100.0))) 100) (list "oscillator frequency" 0.0 initial-osc-freq 60 (lambda (w context info) (set! osc-freq (/ (.value info) 100.0))) 100)))) (add-target (XtParent (car sliders)) (lambda (target) (set! robotize-target target) (XtSetSensitive (XmMessageBoxGetChild robotize-dialog XmDIALOG_OK_BUTTON) (effect-target-ok target))) #f))) (activate-dialog robotize-dialog)) (let ((child (XtCreateManagedWidget "Robotize" xmPushButtonWidgetClass misc-menu (list XmNbackground *basic-color*)))) (XtAddCallback child XmNactivateCallback (lambda (w c i) (post-robotize-dialog))) (set! misc-menu-list (cons (lambda () (let ((new-label (format #f "Robotize (~1,2F ~1,2F ~1,2F)" samp-rate osc-amp osc-freq))) (change-label child new-label))) misc-menu-list)))) ;;; -------- Rubber sound ;;; (let ((rubber-factor 1.0) (rubber-label "Rubber sound") (rubber-dialog #f) (rubber-target 'sound)) (define (post-rubber-dialog) (if (not (Widget? rubber-dialog)) ;; if rubber-dialog doesn't exist, create it (let ((initial-rubber-factor 1.0) (sliders ())) (set! rubber-dialog (make-effect-dialog rubber-label (lambda (w context info) (rubber-sound rubber-factor)) (lambda (w context info) (help-dialog "Rubber sound" "Stretches or contracts the time of a sound. Move the slider to change the stretch factor.")) (lambda (w c i) (set! rubber-factor initial-rubber-factor) (XtSetValues (car sliders) (list XmNvalue (floor (* rubber-factor 100))))) (lambda () (effect-target-ok rubber-target)))) (set! sliders (add-sliders rubber-dialog (list (list "stretch factor" 0.0 initial-rubber-factor 5.0 (lambda (w context info) (set! rubber-factor (/ (.value info) 100.0))) 100)))) (add-target (XtParent (car sliders)) (lambda (target) (set! rubber-target target) (XtSetSensitive (XmMessageBoxGetChild rubber-dialog XmDIALOG_OK_BUTTON) (effect-target-ok target))) #f))) (activate-dialog rubber-dialog)) (let ((child (XtCreateManagedWidget "Rubber sound" xmPushButtonWidgetClass misc-menu (list XmNbackground *basic-color*)))) (XtAddCallback child XmNactivateCallback (lambda (w c i) (post-rubber-dialog))) (set! misc-menu-list (cons (lambda () (let ((new-label (format #f "Rubber sound (~1,2F)" rubber-factor))) (change-label child new-label))) misc-menu-list)))) ;;; -------- Wobble ;;; ;;; (progress report) (let ((wobble-frequency 50) (wobble-amplitude 0.5) (wobble-label "Wobble") (wobble-dialog #f) (wobble-target 'sound)) (define (post-wobble-dialog) (if (not (Widget? wobble-dialog)) ;; if wobble-dialog doesn't exist, create it (let ((initial-wobble-frequency 50) (initial-wobble-amplitude 0.5) (sliders ())) (set! wobble-dialog (make-effect-dialog wobble-label (lambda (w context info) (let ((ms (and (eq? wobble-target 'marks) (plausible-mark-samples)))) (effects-hello-dentist wobble-frequency wobble-amplitude (if (eq? wobble-target 'sound) 0 (if (eq? wobble-target 'selection) (selection-position) (car ms))) (if (eq? wobble-target 'sound) (framples) (if (eq? wobble-target 'selection) (selection-framples) (- (cadr ms) (car ms))))))) (lambda (w context info) (help-dialog "Wobble" "Move the sliders to set the wobble frequency and amplitude.")) (lambda (w c i) (set! wobble-frequency initial-wobble-frequency) (XtSetValues (car sliders) (list XmNvalue (floor (* wobble-frequency 100)))) (set! wobble-amplitude initial-wobble-amplitude) (XtSetValues (cadr sliders) (list XmNvalue (floor (* wobble-amplitude 100))))) (lambda () (effect-target-ok wobble-target)))) (set! sliders (add-sliders wobble-dialog (list (list "wobble frequency" 0 initial-wobble-frequency 100 (lambda (w context info) (set! wobble-frequency (/ (.value info) 100.0))) 100) (list "wobble amplitude" 0.0 initial-wobble-amplitude 1.0 (lambda (w context info) (set! wobble-amplitude (/ (.value info) 100.0))) 100)))) (add-target (XtParent (car sliders)) (lambda (target) (set! wobble-target target) (XtSetSensitive (XmMessageBoxGetChild wobble-dialog XmDIALOG_OK_BUTTON) (effect-target-ok target))) #f))) (activate-dialog wobble-dialog)) (let ((child (XtCreateManagedWidget "Wobble" xmPushButtonWidgetClass misc-menu (list XmNbackground *basic-color*)))) (XtAddCallback child XmNactivateCallback (lambda (w c i) (post-wobble-dialog))) (set! misc-menu-list (cons (lambda () (let ((new-label (format #f "Wobble (~1,2F ~1,2F)" wobble-frequency wobble-amplitude))) (change-label child new-label))) misc-menu-list)))) ) ;;; ;;; END PARAMETRIZED EFFECTS ;;; (add-to-menu effects-menu #f #f) (add-to-menu effects-menu "Octave-down" (lambda () (down-oct 2))) (add-to-menu effects-menu "Remove clicks" (lambda () (define (find-click loc) (let ((reader (make-sampler loc)) (mmax (make-moving-max 10)) (samp0 0.0) (samp1 0.0) (samp2 0.0) (len (framples))) (call-with-exit (lambda (return) (do ((ctr loc (+ ctr 1))) ((= ctr len) #f) (set! samp0 samp1) (set! samp1 samp2) (set! samp2 (next-sample reader)) (let ((local-max (max .1 (moving-max mmax samp0)))) (if (and (> (abs (- samp0 samp1)) local-max) (> (abs (- samp1 samp2)) local-max) (< (abs (- samp0 samp2)) (/ local-max 2))) (return (- ctr 1))))))))) (define (remove-click loc) (let ((click (find-click loc))) (if click (begin (smooth-sound (- click 2) 4) (remove-click (+ click 2)))))) (remove-click 0))) (define* (effects-remove-dc snd chn) (let* ((len (framples snd chn)) (data (make-float-vector len)) (reader (make-sampler 0 snd chn))) (let ((lastx 0.0) (lasty 0.0)) (do ((i 0 (+ i 1))) ((= i len)) (let ((inval (next-sample reader))) (set! lasty (+ inval (- (* 0.999 lasty) lastx))) (set! lastx inval) (float-vector-set! data i lasty)))) (float-vector->channel data 0 len snd chn current-edit-position "effects-remove-dc"))) (add-to-menu effects-menu "Remove DC" effects-remove-dc) (add-to-menu effects-menu "Spiker" spike) (define* (effects-compand snd chn) (let ((tbl (float-vector -1.000 -0.960 -0.900 -0.820 -0.720 -0.600 -0.450 -0.250 0.000 0.250 0.450 0.600 0.720 0.820 0.900 0.960 1.000))) (let ((len (framples snd chn))) (let ((reader (make-sampler 0 snd chn)) (data (make-float-vector len))) (do ((i 0 (+ i 1))) ((= i len)) (float-vector-set! data i (array-interp tbl (+ 8.0 (* 8.0 (next-sample reader))) 17))) (float-vector->channel data 0 len snd chn current-edit-position "effects-compand"))))) (add-to-menu effects-menu "Compand" effects-compand) (add-to-menu effects-menu "Invert" (lambda () (scale-by -1))) (add-to-menu effects-menu "Reverse" reverse-sound) (add-to-menu effects-menu "Null phase" zero-phase) )snd-16.1/snd-ghelp.c0000644000076400007640000002215612512761107012370 0ustar bilbil#include "snd.h" /* ---------------- HELP MONOLOG ---------------- */ static GtkWidget *help_dialog = NULL; static void dismiss_help_dialog(GtkWidget *w, gpointer context) { gtk_widget_hide(help_dialog); } static gint delete_help_dialog(GtkWidget *w, GdkEvent *event, gpointer context) { gtk_widget_hide(help_dialog); return(true); } #define HELP_ROWS 12 #define HELP_COLUMNS 72 /* these set the initial size of the help dialog text area */ static GtkWidget *help_text = NULL; slist *related_items = NULL; static char *original_help_text = NULL; static const char **help_urls = NULL; static void add_help_text(GtkWidget *text, const char *message) { sg_text_insert(text, (char *)message); } int help_text_width(const char *txt, int start, int end) { #if 0 char *buf; int len; buf = (char *)calloc(end - start + 2, sizeof(char)); strncpy(buf, txt, end - start); len = sg_text_width(buf, LISTENER_FONT(ss)); free(buf); if (len > 0) return(len); #endif return((end - start) * 8); } static with_word_wrap_t outer_with_wrap = WITHOUT_WORD_WRAP; static int old_help_text_width = 0; static gboolean help_expose_callback(GtkWidget *w, GdkEventExpose *ev, gpointer data) { int curwid; curwid = widget_width(help_dialog); /* was help_text, but I'm getting shivering in expose events */ if (old_help_text_width == 0) old_help_text_width = curwid; else { if ((outer_with_wrap == WITH_WORD_WRAP) && (abs(curwid - old_help_text_width) > 50)) { char *cur_help_str = NULL, *new_help_str = NULL; cur_help_str = sg_get_text(help_text, 0, -1); new_help_str = word_wrap(original_help_text, curwid); gtk_text_buffer_set_text(gtk_text_view_get_buffer(GTK_TEXT_VIEW(help_text)), "", 0); sg_text_insert(help_text, new_help_str); if (new_help_str) free(new_help_str); if (cur_help_str) g_free(cur_help_str); old_help_text_width = curwid; } } return(false); } static bool new_help(const char *pattern, bool complain) { const char *url; const char **xrefs; url = snd_url(pattern); if (url) { /* given name, find doc string, if any */ Xen xstr; xstr = g_snd_help(C_string_to_Xen_string(pattern), 0); if (Xen_is_string(xstr)) { int gc_loc; gc_loc = snd_protect(xstr); xrefs = help_name_to_xrefs(pattern); snd_help_with_xrefs(pattern, Xen_string_to_C_string(xstr), WITH_WORD_WRAP, xrefs, NULL); snd_unprotect_at(gc_loc); if (xrefs) free(xrefs); return(true); } url_to_html_viewer(url); return(true); } if ((!(snd_topic_help(pattern))) && (complain)) { xrefs = help_name_to_xrefs(pattern); if (xrefs) { snd_help_with_xrefs(pattern, "(no help found)", WITH_WORD_WRAP, xrefs, NULL); free(xrefs); return(true); } else snd_help_with_xrefs(pattern, "(no help found)", WITH_WORD_WRAP, NULL, NULL); } return(false); } static char *find_highlighted_text(const char *value) { int i, len, start = -1; len = mus_strlen(value); for (i = 0; i < len; i++) if (value[i] == '{') start = i + 1; else { if (value[i] == '}') { int end; end = i; if ((start > 0) && ((end - start) > 0)) { int k; char *topic; topic = (char *)calloc(end - start + 1, sizeof(char)); for (i = start, k = 0; i < end; i++, k++) topic[k] = value[i]; return(topic); } } } return(NULL); } static void help_browse_callback(const char *name, int row, void *data) { if ((help_urls) && (help_urls[row])) url_to_html_viewer(help_urls[row]); else { char *topic = NULL; topic = find_highlighted_text(name); if (topic) { name_to_html_viewer(topic); free(topic); } else { if (name) new_help(name, true); } } } static gboolean text_release_callback(GtkTreeSelection *selection, gpointer *gp) { /* this needs to be bool return false -- otherwise, apparently, the mouse-drag->selection never gets turned off! */ GtkTextIter start, end; #define HELP_BUFFER gtk_text_view_get_buffer(GTK_TEXT_VIEW(help_text)) if (gtk_text_buffer_get_selection_bounds(HELP_BUFFER, &start, &end)) { char *txt; txt = gtk_text_buffer_get_text(HELP_BUFFER, &start, &end, true); /* only change help text display if it's one word in the selection, and we can find new help */ if (txt) { int i, len; bool one_word = true; len = mus_strlen(txt); for (i = 0; i < len; i++) if (isspace((int)txt[i])) { one_word = false; break; } if (one_word) new_help(txt, false); g_free(txt); } } return(false); } static void search_activated(GtkWidget *w, gpointer context) { char *str = NULL; str = (char *)gtk_entry_get_text(GTK_ENTRY(w)); /* no free, I think */ if (new_help(str, true)) gtk_entry_set_text(GTK_ENTRY(w), ""); } static void create_help_monolog(void) { /* create scrollable but not editable text window */ GtkWidget *ok_button, *search, *frame; help_dialog = snd_gtk_dialog_new(); #if GTK_CHECK_VERSION(3, 14, 0) gtk_window_set_transient_for(GTK_WINDOW(help_dialog), GTK_WINDOW(MAIN_SHELL(ss))); #endif SG_SIGNAL_CONNECT(help_dialog, "delete_event", delete_help_dialog, NULL); gtk_window_set_title(GTK_WINDOW(help_dialog), I_HELP); sg_make_resizable(help_dialog); gtk_container_set_border_width (GTK_CONTAINER(help_dialog), 10); gtk_window_resize(GTK_WINDOW(help_dialog), HELP_COLUMNS * 9, HELP_ROWS * 40); gtk_widget_realize(help_dialog); ok_button = gtk_dialog_add_button(GTK_DIALOG(help_dialog), "Go Away", GTK_RESPONSE_NONE); gtk_widget_set_name(ok_button, "dialog_button"); SG_SIGNAL_CONNECT(ok_button, "clicked", dismiss_help_dialog, NULL); #if GTK_CHECK_VERSION(3, 0, 0) add_highlight_button_style(ok_button); #endif gtk_widget_show(ok_button); frame = gtk_frame_new(NULL); gtk_box_pack_start(GTK_BOX(DIALOG_CONTENT_AREA(help_dialog)), frame, true, true, 10); gtk_widget_show(frame); help_text = make_scrolled_text(frame, false, CONTAINER_ADD, false); /* last arg ignored */ gtk_widget_add_events(help_text, GDK_BUTTON_RELEASE); gtk_text_view_set_left_margin(GTK_TEXT_VIEW(help_text), 10); SG_SIGNAL_CONNECT(help_text, "button_release_event", text_release_callback, NULL); related_items = slist_new_with_title("related topics", DIALOG_CONTENT_AREA(help_dialog), NULL, 0, BOX_PACK); related_items->select_callback = help_browse_callback; { GtkWidget *label, *hbox; #if (!HAVE_GTK_GRID_NEW) hbox = gtk_hbox_new(false, 0); gtk_box_pack_start(GTK_BOX(DIALOG_CONTENT_AREA(help_dialog)), hbox, false, false, 10); gtk_widget_show(hbox); label = gtk_label_new("help topic:"); gtk_box_pack_start(GTK_BOX(hbox), label, false, false, 0); gtk_widget_show(label); search = snd_entry_new(hbox, NULL, WITH_WHITE_BACKGROUND); #else GtkWidget *content_area; content_area = gtk_dialog_get_content_area(GTK_DIALOG(help_dialog)); hbox = gtk_grid_new(); gtk_container_add(GTK_CONTAINER(content_area), hbox); gtk_widget_show(hbox); label = gtk_label_new("help topic:"); gtk_widget_set_halign(label, GTK_ALIGN_CENTER); gtk_widget_set_hexpand(label, false); g_object_set(label, "margin", 10, NULL); gtk_grid_attach(GTK_GRID(hbox), label, 0, 0, 1, 1); gtk_widget_show(label); search = snd_entry_new(hbox, label, WITH_WHITE_BACKGROUND); #endif } SG_SIGNAL_CONNECT(search, "activate", search_activated, NULL); gtk_widget_show(help_dialog); SG_SIGNAL_CONNECT((gpointer)help_dialog, DRAW_SIGNAL, help_expose_callback, NULL); set_dialog_widget(HELP_DIALOG, help_dialog); } GtkWidget *snd_help(const char *subject, const char *helpstr, with_word_wrap_t with_wrap) { /* place help string in scrollable help window */ /* if window is already active, add this help at the top and reposition */ outer_with_wrap = with_wrap; if (!(help_dialog)) create_help_monolog(); else raise_dialog(help_dialog); gtk_window_set_title(GTK_WINDOW(help_dialog), subject); original_help_text = (char *)helpstr; gtk_text_buffer_set_text(gtk_text_view_get_buffer(GTK_TEXT_VIEW(help_text)), "", 0); if (with_wrap == WITH_WORD_WRAP) { char *new_help = NULL; new_help = word_wrap(helpstr, (int)(widget_width(help_text) * 1.3)); add_help_text(help_text, new_help); if (new_help) free(new_help); } else add_help_text(help_text, helpstr); slist_clear(related_items); /* this can clobber "subject"! */ return(help_dialog); } GtkWidget *snd_help_with_xrefs(const char *subject, const char *helpstr, with_word_wrap_t with_wrap, const char **xrefs, const char **urls) { GtkWidget *w; help_urls = urls; w = snd_help(subject, helpstr, with_wrap); if (xrefs) { int i; for (i = 0; (xrefs[i]); i++) slist_append(related_items, xrefs[i]); } return(w); } void snd_help_append(const char *text) { if (help_text) sg_text_insert(help_text, text); } void snd_help_back_to_top(void) { if (help_text) { GtkTextIter pos; GtkTextBuffer *buf; buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(help_text)); gtk_text_buffer_get_iter_at_offset(buf, &pos, 0); gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(help_text), &pos, 0.0, true, 0.0, 0.0); } } snd-16.1/grani.rb0000644000076400007640000004214512434353162011771 0ustar bilbil#!/usr/bin/env ruby -w # grani.rb -- grani.ins CL --> Ruby # Translator: Michael Scholz # Created: 05/02/01 00:47:00 # Changed: 14/11/13 05:03:02 # Original header: # ;;; grani: a granular synthesis instrument # ;;; by Fernando Lopez-Lezcano # ;;; http://ccrma.stanford.edu/~nando/clm/grani/ # ;;; # ;;; Original grani.ins instrument written for the 220a Course by # ;;; Fernando Lopez-Lezcano & Juan Pampin, November 6 1996 # ;;; # ;;; Mar 21 1997: working with hop and grain-dur envelopes # ;;; Mar 22 1997: working with src envelope (grain wise) & src spread # ;;; Jan 26 1998: started work on new version # ;;; Nov 7 1998: input soundfile duration calculation wrong # ;;; Nov 10 1998: bug in in-samples (thanks to Kristopher D. Giesing # ;;; for this one) # ;;; Dec 20 1998: added standard locsig code # ;;; Feb 19 1999: added "nil" as default value of where to avoid warning # ;;; (by bill) # ;;; Jan 10 2000: added input-channel to select which channel of the input # ;;; file to process. # ;;; added grain-start-in-seconds to be able to specify input # ;;; file locations in seconds for the grain-start envelope # ;;; May 06 2002: fixed array passing of where-bins in clisp # ;;; (reported by Charles Nichols and jennifer l doering) # ;;; Mar 27 2003: added option for sending grains to all channels # ;;; (requested by Oded Ben-Tal) require "ws" require "env" # ;;; calculate a random spread around a center of 0 def random_spread(spread) spread.nonzero? ? (random(spread) - spread / 2.0) : 0.0 end # ;;; create a constant envelope if argument is a number def envelope_or_number(val) case val when Numeric [0, val, 1, val] when Vct vct2list(val) when Array val else error("%s: Number, Array, or Vct required", get_func_name()) end end # ;;; create a vct from an envelope def make_gr_env(env, length = 512) length_1 = (length - 1).to_f make_vct!(length) do |i| envelope_interp(i / length_1, env) end end # ;;; Grain envelopes def raised_cosine(*args) duty_cycle = get_args(args, :duty_cycle, 100) length = get_args(args, :length, 128) active = length * duty_cycle.to_f * 0.01 incr = PI / (active - 1.0) start = (length - active) / 2.0 fin = (length + active) / 2.0 s = -1 make_vct!(length) do |i| sine = if i >= start and i < fin s += 1 sin(s * incr) else 0.0 end sine * sine end end # ;;;========================================================================= # ;;; Granular synthesis instrument # ;;;========================================================================= # # ;;; input-channel: # ;;; from which channel in the input file are samples read # ;;; amp-envelope: # ;;; amplitude envelope for the note # ;;; grain-envelope: # ;;; grain-envelope-end: # ;;; envelopes for each individual grain. The envelope applied in the result # ;;; of interpolating both envelopes. The interpolation is controlled by # ;;; grain-envelope-trasition. If "grain-envelope-end" is nil interpolation # ;;; is turned off and only grain-envelope is applied to the grains. # ;;; grain-envelope-trasition: # ;;; an enveloper that controls the interpolation between the two # ;;; grain envelopes # ;;; 0 -> selects "grain-envelope" # ;;; 1 -> selects "grain-envelope-end" # ;;; grain-envelope-array-size # ;;; size of the array passed to make-table-lookup # ;;; grain-duration: # ;;; envelope that controls grain duration in seconds # ;;; srate-linear: # ;;; t -> sample rate envelope is linear # ;;; nil -> sample rate envelope is exponential # ;;; srate: # ;;; envelope that controls sample rate conversion. The envelope is an # ;;; exponential envelope, the base and error bound of the conversion # ;;; are controlled by "srate-base" and "srate-error". # ;;; srate-spread: # ;;; random spread of sample rate conversion around "srate" # ;;; srate-base: # ;;; base for the exponential conversion # ;;; for example: base = (expt 2 (/ 12)) creates a semitone envelope # ;;; srate-error: # ;;; error bound for the exponential conversion. # ;;; grain-start: # ;;; envelope that determines the starting point of the current grain in # ;;; the input file. "y"->0 starts the grain at the beginning of the input # ;;; file. "y"->1 starts the grain at the end of the input file. # ;;; grain-start-spread: # ;;; random spread around the value of "grain-start" # ;;; grain-start-in-seconds: # ;;; nil -> grain-start y envelope expressed in percent of the duration # ;;; of the input file # ;;; t -> grain-start y envelope expressed in seconds # ;;; grain-density: # ;;; envelope that controls the number of grains per second generated # ;;; in the output file # ;;; grain-density-spread: Grani_to_locsig = 0 Grani_to_grain_duration = 1 Grani_to_grain_start = 2 Grani_to_grain_sample_rate = 3 Grani_to_grain_random = 4 Grani_to_grain_allchans = 5 def grani(start, dur, amp, file, *args) input_channel = get_args(args, :input_channel, 0) grains = get_args(args, :grains, 0) amp_envelope = get_args(args, :amp_envelope, [0, 0, 0.3, 1, 0.7, 1, 1, 0]) grain_envelope = get_args(args, :grain_envelope, [0, 0, 0.3, 1, 0.7, 1, 1, 0]) grain_envelope_end = get_args(args, :grain_envelope_end, false) grain_envelope_transition = get_args(args, :grain_envelope_transition, [0, 0, 1, 1]) grain_envelope_array_size = get_args(args, :grain_envelope_array_size, 512) grain_duration = get_args(args, :grain_duration, 0.1) grain_duration_spread = get_args(args, :grain_spread, 0.0) grain_duration_limit = get_args(args, :grain_limit, 0.002) srate = get_args(args, :srate, 0.0) srate_spread = get_args(args, :srate_spread, 0.0) srate_linear = get_args(args, :srate_linear, false) srate_base = get_args(args, :srate_base, 2.0 ** (1.0 / 12)) srate_error = get_args(args, :srate_error, 0.01) grain_start = get_args(args, :grain_start, [0, 0, 1, 1]) grain_start_spread = get_args(args, :grain_start_spread, 0.0) grain_start_in_seconds = get_args(args, :grain_start_in_seconds, false) grain_density = get_args(args, :grain_density, 10.0) grain_density_spread = get_args(args, :grain_density_spread, 0.0) reverb_amount = get_args(args, :reverb_amount, 0.01) reverse = get_args(args, :reverse, false) where_to = get_args(args, :where_to, 0) where_bins = get_args(args, :where_bins, []) grain_distance = get_args(args, :grain_distance, 1.0) grain_distance_spread = get_args(args, :grain_distance_spread, 0.0) grain_degree = get_args(args, :grain_degree, 45.0) grain_degree_spread = get_args(args, :grain_degree_spread, 0.0) beg, fin = times2samples(start, dur) in_file_channels = mus_sound_chans(file) in_file_sr = mus_sound_srate(file).to_f in_file_dur = mus_sound_framples(file) / in_file_sr in_file_reader = make_readin(:file, file, :channel, [input_channel, in_file_channels - 1].min) last_in_sample = (in_file_dur * in_file_sr).round srate_ratio = in_file_sr / mus_srate() sr_env = make_env(:envelope, if srate_linear envelope_or_number(srate) else exp_envelope(envelope_or_number(srate), :base, srate_base, :error, srate_error) end, :scaler, srate_ratio, :duration, dur) sr_spread_env = make_env(:envelope, envelope_or_number(srate_spread), :duration, dur) amp_env = make_env(:envelope, amp_envelope, :scaler, amp, :duration, dur) gr_dur = make_env(:envelope, envelope_or_number(grain_duration), :duration, dur) gr_dur_spread = make_env(:envelope, envelope_or_number(grain_duration_spread), :duration, dur) gr_start_scaler = (grain_start_in_seconds ? 1.0 : in_file_dur) gr_start = make_env(:envelope, envelope_or_number(grain_start), :duration, dur) gr_start_spread = make_env(:envelope, envelope_or_number(grain_start_spread), :duration, dur) gr_dens_env = make_env(:envelope, envelope_or_number(grain_density), :duration, dur) gr_dens_spread_env = make_env(:envelope, envelope_or_number(grain_density_spread), :duration, dur) gr_env = make_table_lookup(:frequency, 1.0, "initial-phase".intern, 0.0, :wave, if vct?(grain_envelope) grain_envelope else make_gr_env(grain_envelope, grain_envelope_array_size) end) gr_env_end = make_table_lookup(:frequency, 1.0, "initial-phase".intern, 0.0, :wave, if grain_envelope_end if vct?(grain_envelope_end) grain_envelope_end else make_gr_env(grain_envelope_end, grain_envelope_array_size) end else make_vct(512) end) gr_int_env = make_env(:envelope, envelope_or_number(grain_envelope_transition), :duration, dur) interp_gr_envs = grain_envelope_end gr_dist = make_env(:envelope, envelope_or_number(grain_distance), :duration, dur) gr_dist_spread = make_env(:envelope, envelope_or_number(grain_distance_spread), :duration, dur) gr_degree = make_env(:envelope, envelope_or_number(grain_degree), :duration, dur) gr_degree_spread = make_env(:envelope, envelope_or_number(grain_degree_spread), :duration, dur) loc = make_locsig(:degree, 45.0, :distance, 1.0, :output, @ws_output, :revout, @ws_reverb, :channels, @channels) gr_start_sample = beg gr_samples = 0 gr_offset = 1 gr_dens = 0.0 gr_dens_spread = 0.0 grain_counter = 0 samples = 0 first_grain = true set_mus_increment(in_file_reader, -1) if reverse loop do if gr_offset < gr_samples gr_where = env(gr_int_env) if interp_gr_envs val = if interp_gr_envs (1 - gr_where) * table_lookup(gr_env) + gr_where * table_lookup(gr_env_end) else table_lookup(gr_env) end locsig(loc, gr_start_sample + gr_offset, val * env(amp_env) * readin(in_file_reader)) gr_offset += 1 else if first_grain first_grain = false gr_start_sample = beg else gr_start_sample += seconds2samples(1.0 / (gr_dens + gr_dens_spread)) if (gr_start_sample > fin) or (grains.nonzero? and (grain_counter >= grains)) break end end gr_offset = 0 gr_from_beg = gr_start_sample - beg set_mus_location(amp_env, gr_from_beg) set_mus_location(gr_dur, gr_from_beg) set_mus_location(gr_dur_spread, gr_from_beg) set_mus_location(sr_env, gr_from_beg) set_mus_location(sr_spread_env, gr_from_beg) set_mus_location(gr_start, gr_from_beg) set_mus_location(gr_start_spread, gr_from_beg) set_mus_location(gr_dens_env, gr_from_beg) set_mus_location(gr_dens_spread_env, gr_from_beg) in_start_value = env(gr_start) * gr_start_scaler + random_spread(env(gr_start_spread) * gr_start_scaler) in_start = (in_start_value * in_file_sr).round gr_duration = [grain_duration_limit, env(gr_dur) + random_spread(env(gr_dur_spread))].max gr_samples = seconds2samples(gr_duration) gr_srate = if srate_linear env(sr_env) + random_spread(env(sr_spread_env)) else env(sr_env) * srate_base ** random_spread(env(sr_spread_env)) end set_mus_increment(in_file_reader, gr_srate) in_samples = gr_samples / (1.0 / srate_ratio) set_mus_phase(gr_env, 0.0) set_mus_phase(gr_env_end, 0.0) set_mus_frequency(gr_env, 1.0 / gr_duration) set_mus_frequency(gr_env_end, 1.0 / gr_duration) gr_dens = env(gr_dens_env) gr_dens_spread = random_spread(env(gr_dens_spread_env)) samples += gr_samples grain_counter += 1 where = case where_to when Grani_to_grain_duration gr_duration when Grani_to_grain_start in_start_value when Grani_to_grain_sample_rate gr_srate when Grani_to_grain_random random(1.0) else Grani_to_locsig end if where.nonzero? and where_bins.length > 1 (where_bins.length - 1).times do |chn| locsig_set!(loc, chn, ((where_bins[chn] < where and where < where_bins[chn + 1]) ? 1.0 : 0.0)) end else if where_to == Grani_to_grain_allchans @channels.times do |chn| locsig_set!(loc, chn, 1.0) end else set_mus_location(gr_dist, gr_from_beg) set_mus_location(gr_dist_spread, gr_from_beg) set_mus_location(gr_degree, gr_from_beg) set_mus_location(gr_degree_spread, gr_from_beg) deg = env(gr_degree) + random_spread(env(gr_degree_spread)) dist = env(gr_dist) + random_spread(env(gr_dist_spread)) dist_scl = 1.0 / [dist, 1.0].max if @ws_reverb locsig_reverb_set!(loc, 0, reverb_amount * (1.0 / sqrt([dist, 1.0].max))) end if @channels == 1 locsig_set!(loc, 0, dist_scl) else if @channels == 2 frac = [90.0, [0.0, deg].max].min / 90.0 locsig_set!(loc, 0, dist_scl * (1.0 - frac)) locsig_set!(loc, 1, dist_scl * frac) else if @channels > 2 locsig_set!(loc, 0, if 0 <= deg and deg <= 90 dist_scl * ((90.0 - deg) / 90.0) else if 270 <= deg and deg <= 360 dist_scl * ((deg - 270.0) / 90.0) else 0.0 end end) locsig_set!(loc, 1, if 90 <= deg and deg <= 180 dist_scl * (180.0 - deg) / 90.0 else if 0 <= deg and deg <= 90 dist_scl * (deg / 90.0) else 0.0 end end) locsig_set!(loc, 2, if 180 <= deg and deg <= 270 dist_scl * (270.0 - deg) / 90.0 else if 90 <= deg and deg <= 180 dist_scl * (deg - 90.0) / 90.0 else 0.0 end end) if @channels > 3 locsig_set!(loc, 3, if 270 <= deg and deg <= 360 dist_scl * (360.0 - deg) / 90.0 else if 180 <= deg and deg <= 270 dist_scl * (deg - 180.0) / 90.0 else 0.0 end end) end end end end end end in_start = if (in_start + in_samples) > last_in_sample last_in_sample - in_samples else [in_start, 0].max end set_mus_location(in_file_reader, in_start) end end mus_close(in_file_reader) end =begin with_sound(:play, 1, :statistics, true, :channels, 1, :reverb, nil) do grani(0.0, 2.0, 5.0, "oboe.snd", :grain_envelope, raised_cosine()) end =end # grani.rb ends here snd-16.1/snd-menu.c0000644000076400007640000003363112410357664012243 0ustar bilbil#include "snd.h" #include "snd-menu.h" #if (!USE_NO_GUI) void edit_menu_update(void) { /* called when the "Edit" top level menu is clicked -- make sure all items reflect current Snd state */ snd_info *selected_sp = NULL, *any_sp = NULL; chan_info *cp = NULL; bool has_selection = false, has_region = false, file_open = false, has_undoable_edit = false, has_redoable_edit = false; selected_sp = selected_sound(); if (selected_sp) { file_open = true; cp = any_selected_channel(selected_sp); any_sp = selected_sp; } else { any_sp = any_selected_sound(); if (any_sp) { cp = any_selected_channel(any_sp); file_open = true; } } has_selection = selection_is_active(); has_region = region_ok(region_list_position_to_id(0)); if (cp) { has_undoable_edit = (cp->edit_ctr > 0); has_redoable_edit = (!(((cp->edit_ctr + 1) == cp->edit_size) || (!(cp->edits[cp->edit_ctr + 1])))); } /* is there an open sound? */ set_sensitive(edit_header_menu, file_open); #if HAVE_EXTENSION_LANGUAGE set_sensitive(edit_find_menu, file_open); #endif set_sensitive(edit_select_all_menu, file_open); /* is there an active selection? */ set_sensitive(edit_cut_menu, has_selection); #if WITH_AUDIO set_sensitive(edit_play_menu, has_selection); #endif set_sensitive(edit_mix_menu, has_selection); set_sensitive(edit_save_as_menu, has_selection); set_sensitive(edit_unselect_menu, has_selection); /* is there an undoable edit? */ set_sensitive(edit_undo_menu, has_undoable_edit); /* is there a redoable edit? */ set_sensitive(edit_redo_menu, has_redoable_edit); /* does paste make any sense? */ set_sensitive(edit_paste_menu, (file_open) && (has_selection || has_region)); /* make sure edit-header menu option label correctly reflects current selected sound header type */ if (any_sp) set_menu_label(edit_header_menu, (any_sp->hdr->type == MUS_RAW) ? "Add Header" : "Edit Header"); } void view_menu_update(void) { /* are there any viewable regions? are we even using them? */ if ((snd_regions() == 0) && (!(selection_creates_region(ss)))) { deactivate_widget(view_region_menu); } else { set_sensitive(view_region_menu, snd_regions() > 0); activate_widget(view_region_menu); } /* graph_style */ set_sensitive(view_lines_menu, graph_style(ss) != GRAPH_LINES); set_sensitive(view_dots_menu, graph_style(ss) != GRAPH_DOTS); set_sensitive(view_filled_menu, graph_style(ss) != GRAPH_FILLED); set_sensitive(view_dots_and_lines_menu, graph_style(ss) != GRAPH_DOTS_AND_LINES); set_sensitive(view_lollipops_menu, graph_style(ss) != GRAPH_LOLLIPOPS); /* x axis style */ set_sensitive(view_x_axis_seconds_menu, x_axis_style(ss) != X_AXIS_IN_SECONDS); set_sensitive(view_x_axis_beats_menu, x_axis_style(ss) != X_AXIS_IN_BEATS); set_sensitive(view_x_axis_measures_menu, x_axis_style(ss) != X_AXIS_IN_MEASURES); set_sensitive(view_x_axis_samples_menu, x_axis_style(ss) != X_AXIS_IN_SAMPLES); set_sensitive(view_x_axis_percentage_menu, x_axis_style(ss) != X_AXIS_AS_PERCENTAGE); /* show y zero label */ set_menu_label(view_zero_menu, (show_y_zero(ss)) ? "Hide Y = 0" : "Show Y = 0"); /* verbose cursor label */ set_menu_label(view_cursor_menu, (with_verbose_cursor(ss)) ? "Silent cursor" : "Verbose cursor"); #if HAVE_EXTENSION_LANGUAGE /* inset graph label */ set_menu_label(view_inset_menu, (with_inset_graph(ss)) ? "Without inset graph" : "With inset graph"); #endif /* channel style */ set_sensitive(view_combine_separate_menu, channel_style(ss) != CHANNELS_SEPARATE); set_sensitive(view_combine_combined_menu, channel_style(ss) != CHANNELS_COMBINED); set_sensitive(view_combine_superimposed_menu, channel_style(ss) != CHANNELS_SUPERIMPOSED); /* show axes */ set_sensitive(view_no_axes_menu, show_axes(ss) != SHOW_NO_AXES); set_sensitive(view_just_x_axis_menu, show_axes(ss) != SHOW_X_AXIS); set_sensitive(view_just_x_axis_unlabelled_menu, show_axes(ss) != SHOW_X_AXIS_UNLABELLED); set_sensitive(view_all_axes_menu, show_axes(ss) != SHOW_ALL_AXES); set_sensitive(view_all_axes_unlabelled_menu, show_axes(ss) != SHOW_ALL_AXES_UNLABELLED); set_sensitive(view_bare_x_axis_menu, show_axes(ss) != SHOW_BARE_X_AXIS); #if HAVE_EXTENSION_LANGUAGE && USE_MOTIF /* make sure listener menu option label correctly reflects current listener state */ set_menu_label(view_listener_menu, (listener_is_visible()) ? "Hide listener" : "Show listener"); #endif set_menu_label(view_controls_menu, (in_show_controls(ss)) ? "Hide controls" : "Show controls"); #if USE_GTK set_sensitive(view_files_menu, view_files_has_files()); #endif /* zoom focus style */ set_sensitive(view_focus_left_menu, zoom_focus_style(ss) != ZOOM_FOCUS_LEFT); set_sensitive(view_focus_right_menu, zoom_focus_style(ss) != ZOOM_FOCUS_RIGHT); set_sensitive(view_focus_middle_menu, zoom_focus_style(ss) != ZOOM_FOCUS_MIDDLE); set_sensitive(view_focus_active_menu, zoom_focus_style(ss) != ZOOM_FOCUS_ACTIVE); /* grid menu label */ set_menu_label(view_grid_menu, (show_grid(ss) == WITH_GRID) ? "Without grid" : "With grid"); } void file_menu_update(void) { snd_info *any_sp = NULL; bool file_open = false, has_edits = false; any_sp = any_selected_sound(); if (any_sp) { has_edits = has_unsaved_edits(any_sp); file_open = true; } set_sensitive(file_close_menu, file_open); set_sensitive(file_print_menu, file_open); set_sensitive(file_mix_menu, file_open); set_sensitive(file_insert_menu, file_open); set_sensitive(file_save_as_menu, file_open); set_sensitive(file_update_menu, file_open); set_sensitive(file_save_menu, has_edits); set_sensitive(file_revert_menu, has_edits); if (ss->active_sounds > 1) activate_widget(file_close_all_menu); else deactivate_widget(file_close_all_menu); } #endif void reflect_file_revert_in_label(snd_info *sp) { #if (!USE_NO_GUI) bool editing; editing = has_unsaved_edits(sp); if (!editing) set_sound_pane_file_label(sp, shortname_indexed(sp)); #endif } static void file_update(snd_info *sp) { /* here we should only update files that have changed on disk */ if ((sp) && (sp->edited_region == NULL) && ((sp->need_update) || (file_write_date(sp->filename) != sp->write_date))) { redirect_everything_to(printout_to_status_area, (void *)sp); snd_update(sp); redirect_everything_to(NULL, NULL); } } void update_file_from_menu(void) { for_each_sound(file_update); } void revert_file_from_menu(void) { snd_info *sp; sp = any_selected_sound(); if (sp) { int i; for (i = 0; i < sp->nchans; i++) revert_edits(sp->chans[i]); reflect_file_revert_in_label(sp); } } static bool has_save_state_error = false; static void save_state_from_menu_error_handler(const char *msg, void *ignore) { snd_warning_without_format(msg); has_save_state_error = true; } void save_state_from_menu(void) { if (save_state_file(ss)) { has_save_state_error = false; redirect_everything_to(save_state_from_menu_error_handler, NULL); save_state(save_state_file(ss)); redirect_everything_to(NULL, NULL); if (!has_save_state_error) { if (any_selected_sound()) status_report(any_selected_sound(), "saved state in %s", save_state_file(ss)); } } else { snd_warning_without_format("can't save state: save-state-file is null"); } } /* ---------------- extlang tie-ins ---------------- */ static Xen snd_no_such_menu_error(const char *caller, Xen id) { Xen_error(Xen_make_error_type("no-such-menu"), Xen_list_3(C_string_to_Xen_string("~A: no such menu, ~A"), C_string_to_Xen_string(caller), id)); return(Xen_false); } static Xen *menu_functions = NULL; static int *menu_functions_loc = NULL; static int callbacks_size = 0; static int callb = 0; #define CALLBACK_INCR 16 static int make_callback_slot(void) { int old_callb, i; for (i = 0; i < callb; i++) if (Xen_is_false(menu_functions[i])) return(i); if (callbacks_size == callb) { callbacks_size += CALLBACK_INCR; if (callb == 0) { menu_functions = (Xen *)calloc(callbacks_size, sizeof(Xen)); for (i = 0; i < callbacks_size; i++) menu_functions[i] = Xen_undefined; menu_functions_loc = (int *)calloc(callbacks_size, sizeof(int)); for (i = 0; i < callbacks_size; i++) menu_functions_loc[i] = NOT_A_GC_LOC; } else { menu_functions = (Xen *)realloc(menu_functions, callbacks_size * sizeof(Xen)); for (i = callbacks_size - CALLBACK_INCR; i < callbacks_size; i++) menu_functions[i] = Xen_undefined; menu_functions_loc = (int *)realloc(menu_functions_loc, callbacks_size * sizeof(int)); for (i = callbacks_size - CALLBACK_INCR; i < callbacks_size; i++) menu_functions_loc[i] = NOT_A_GC_LOC; } } old_callb = callb; callb++; return(old_callb); } static void add_callback(int slot, Xen callback) { if ((slot >= 0) && (slot < callbacks_size)) { menu_functions[slot] = callback; menu_functions_loc[slot] = snd_protect(callback); } } void unprotect_callback(int slot) { /* called only if menu is being removed */ if ((slot >= 0) && (slot < callbacks_size)) { if (Xen_is_procedure(menu_functions[slot])) { snd_unprotect_at(menu_functions_loc[slot]); menu_functions_loc[slot] = NOT_A_GC_LOC; } menu_functions[slot] = Xen_false; /* not Xen_undefined -- need a way to distinguish "no callback" from "recyclable slot" */ } } static Xen gl_add_to_main_menu(Xen label, Xen callback) { #define H_add_to_main_menu "(" S_add_to_main_menu " label :optional callback): adds label to the main (top-level) menu, returning its index" int slot = -1; Xen_check_type(Xen_is_string(label), label, 1, S_add_to_main_menu, "a string"); slot = make_callback_slot(); if (Xen_is_bound(callback)) { char *err; err = procedure_ok(callback, 0, S_add_to_main_menu, "menu callback", 2); if (err == NULL) add_callback(slot, callback); else { Xen errm; errm = C_string_to_Xen_string(err); free(err); return(snd_bad_arity_error(S_add_to_main_menu, errm, callback)); } } else menu_functions[slot] = Xen_undefined; return(C_int_to_Xen_integer(g_add_to_main_menu((char *)Xen_string_to_C_string(label), slot))); } static Xen gl_add_to_menu(Xen menu, Xen label, Xen callback, Xen gpos) { #define H_add_to_menu "(" S_add_to_menu " menu label func :optional position): adds label to menu (a main menu index), invokes \ func (a function of no args) when the new menu is activated. Returns the new menu label widget." #if (!USE_NO_GUI) widget_t result; char *errmsg = NULL; Xen_check_type(Xen_is_string(label) || Xen_is_false(label), label, 2, S_add_to_menu, "a string"); Xen_check_type(Xen_is_integer(menu), menu, 1, S_add_to_menu, "an integer"); Xen_check_type(Xen_is_procedure(callback) || Xen_is_false(callback), callback, 3, S_add_to_menu, "a procedure"); Xen_check_type(Xen_is_integer_or_unbound(gpos), gpos, 4, S_add_to_menu, "an integer"); /* fprintf(stderr, "add-to-menu %s\n", Xen_object_to_C_string(Xen_car(callback))); */ if (Xen_is_procedure(callback)) errmsg = procedure_ok(callback, 0, S_add_to_menu, "menu callback", 3); if (errmsg == NULL) { int slot = -1, m, position = -1; m = Xen_integer_to_C_int(menu); if (m < 0) return(snd_no_such_menu_error(S_add_to_menu, menu)); if (Xen_is_procedure(callback)) slot = make_callback_slot(); if (Xen_is_integer(gpos)) position = Xen_integer_to_C_int(gpos); result = g_add_to_menu(m, (Xen_is_false(label)) ? NULL : Xen_string_to_C_string(label), slot, position); if (result == NULL) return(snd_no_such_menu_error(S_add_to_menu, menu)); if (Xen_is_procedure(callback)) add_callback(slot, callback); } else { Xen errm; errm = C_string_to_Xen_string(errmsg); free(errmsg); return(snd_bad_arity_error(S_add_to_menu, errm, callback)); } return(Xen_wrap_widget(result)); #else return(Xen_false); #endif } void g_menu_callback(int callb) { if ((callb >= 0) && (Xen_is_bound(menu_functions[callb]))) Xen_call_with_no_args(menu_functions[callb], "menu callback func"); } static Xen gl_remove_from_menu(Xen menu, Xen label) { #define H_remove_from_menu "(" S_remove_from_menu " menu label): removes menu item label from menu" int m; Xen_check_type(Xen_is_string(label), label, 2, S_remove_from_menu, "a string"); Xen_check_type(Xen_is_integer(menu), menu, 1, S_remove_from_menu, "an integer"); m = Xen_integer_to_C_int(menu); if (m < 0) return(snd_no_such_menu_error(S_remove_from_menu, menu)); return(C_int_to_Xen_integer(g_remove_from_menu(m, Xen_string_to_C_string(label)))); } static Xen g_main_menu(Xen which) { #define H_main_menu "(" S_main_menu " menu): the top-level menu widget referred to by menu" int which_menu; Xen_check_type(Xen_is_integer(which), which, 1, S_main_menu, "an integer"); which_menu = Xen_integer_to_C_int(which); if ((which_menu < 0) || (which_menu >= MAX_MAIN_MENUS)) Xen_error(Xen_make_error_type("no-such-menu"), Xen_list_2(C_string_to_Xen_string(S_main_menu ": no such menu, ~A"), which)); return(Xen_wrap_widget(menu_widget(which_menu))); } Xen_wrap_2_optional_args(gl_add_to_main_menu_w, gl_add_to_main_menu) Xen_wrap_4_optional_args(gl_add_to_menu_w, gl_add_to_menu) Xen_wrap_2_args(gl_remove_from_menu_w, gl_remove_from_menu) Xen_wrap_1_arg(g_main_menu_w, g_main_menu) void g_init_menu(void) { Xen_define_procedure(S_add_to_main_menu, gl_add_to_main_menu_w, 1, 1, 0, H_add_to_main_menu); Xen_define_procedure(S_add_to_menu, gl_add_to_menu_w, 3, 1, 0, H_add_to_menu); Xen_define_procedure(S_remove_from_menu, gl_remove_from_menu_w, 2, 0, 0, H_remove_from_menu); Xen_define_procedure(S_main_menu, g_main_menu_w, 1, 0, 0, H_main_menu); } snd-16.1/snd-gdraw.c0000644000076400007640000012347012555416057012406 0ustar bilbil#include "snd.h" void draw_line(graphics_context *ax, int x0, int y0, int x1, int y1) { cairo_set_source_rgba(ss->cr, ax->gc->fg_color->red, ax->gc->fg_color->green, ax->gc->fg_color->blue, ax->gc->fg_color->alpha); if (ss->line_width != 1.0) { cairo_set_line_width(ss->cr, 1.0); ss->line_width = 1.0; } /* to get a thin line in cairo -- hooboy! you have to offset everything -- this is not pretty * if line_width < 1.0, you get a smudgy mess in gray-scale!! */ cairo_move_to(ss->cr, x0 + 0.5, y0 + 0.5); cairo_line_to(ss->cr, x1 + 0.5, y1 + 0.5); cairo_stroke(ss->cr); } void draw_lines(graphics_context *ax, point_t *points, int num) { if (num == 0) return; { int i; cairo_set_source_rgba(ss->cr, ax->gc->fg_color->red, ax->gc->fg_color->green, ax->gc->fg_color->blue, ax->gc->fg_color->alpha); if (ss->line_width != 1.0) { cairo_set_line_width(ss->cr, 1.0); ss->line_width = 1.0; } cairo_move_to(ss->cr, points[0].x + 0.5, points[0].y + 0.5); for (i = 1; i < num; i++) cairo_line_to(ss->cr, points[i].x + 0.5, points[i].y + 0.5); cairo_stroke(ss->cr); } } void draw_dot(graphics_context *ax, int x, int y, int size) { cairo_set_source_rgba(ss->cr, ax->gc->fg_color->red, ax->gc->fg_color->green, ax->gc->fg_color->blue, ax->gc->fg_color->alpha); cairo_arc(ss->cr, x, y, size, 0.0, 2 * M_PI); /* docs say size is radius. This used to be size / 2 to try to match X */ cairo_fill(ss->cr); } #if 0 void draw_arc(graphics_context *ax, int x, int y, int size, int angle0, int angle1) { cairo_set_source_rgba(ss->cr, ax->gc->fg_color->red, ax->gc->fg_color->green, ax->gc->fg_color->blue, ax->gc->fg_color->alpha); cairo_arc(ss->cr, x, y, size / 2, mus_degrees_to_radians(angle0), mus_degrees_to_radians(angle1)); cairo_stroke(ss->cr); } void draw_point(graphics_context *ax, point_t point, int size) { draw_dot(ax, point.x, point.y, size); } #endif void draw_points(graphics_context *ax, point_t *points, int num, int size) { if (num == 0) return; { int i; for (i = 0; i < num; i++) draw_dot(ax, points[i].x, points[i].y, size); } } void fill_rectangle(graphics_context *ax, int x0, int y0, int width, int height) { if (ss->bg_gradient < .01) { cairo_set_source_rgba(ss->cr, ax->gc->fg_color->red, ax->gc->fg_color->green, ax->gc->fg_color->blue, ax->gc->fg_color->alpha); cairo_rectangle(ss->cr, x0, y0, width, height); cairo_fill(ss->cr); } else { mus_float_t grad; cairo_pattern_t *pat; grad = ss->bg_gradient; /* try gradient background: looks ok, but display is slow */ /* this is shaded toward the right pat = cairo_pattern_create_linear(0, 0, width, height); */ /* this is shaded toward the bottom */ pat = cairo_pattern_create_linear(0, 0, 0, height); cairo_pattern_add_color_stop_rgba(pat, 1, mus_fclamp(0.0, ax->gc->fg_color->red - grad, 1.0), mus_fclamp(0.0, ax->gc->fg_color->green - grad, 1.0), mus_fclamp(0.0, ax->gc->fg_color->blue - grad, 1.0), ax->gc->fg_color->alpha); cairo_pattern_add_color_stop_rgba(pat, 0, mus_fclamp(0.0, ax->gc->fg_color->red + grad, 1.0), mus_fclamp(0.0, ax->gc->fg_color->green + grad, 1.0), mus_fclamp(0.0, ax->gc->fg_color->blue + grad, 1.0), ax->gc->fg_color->alpha); cairo_rectangle(ss->cr, x0, y0, width, height); cairo_set_source(ss->cr, pat); cairo_fill(ss->cr); cairo_pattern_destroy(pat); } } void erase_rectangle(chan_info *cp, graphics_context *ax, int x0, int y0, int width, int height) { /* used only to clear the overall graph window in snd-chn.c */ if (ss->bg_gradient < .01) { cairo_set_source_rgba(ss->cr, ax->gc->bg_color->red, ax->gc->bg_color->green, ax->gc->bg_color->blue, ax->gc->fg_color->alpha); cairo_rectangle(ss->cr, x0, y0, width, height); cairo_fill(ss->cr); } else { mus_float_t grad; cairo_pattern_t *pat; grad = ss->bg_gradient; /* try gradient background: looks ok, but display is slow */ /* this is shaded toward the right pat = cairo_pattern_create_linear(0, 0, width, height); */ /* this is shaded toward the bottom */ pat = cairo_pattern_create_linear(0, 0, 0, height); cairo_pattern_add_color_stop_rgba(pat, 1, mus_fclamp(0.0, ax->gc->bg_color->red - grad, 1.0), mus_fclamp(0.0, ax->gc->bg_color->green - grad, 1.0), mus_fclamp(0.0, ax->gc->bg_color->blue - grad, 1.0), ax->gc->bg_color->alpha); cairo_pattern_add_color_stop_rgba(pat, 0, mus_fclamp(0.0, ax->gc->bg_color->red + grad, 1.0), mus_fclamp(0.0, ax->gc->bg_color->green + grad, 1.0), mus_fclamp(0.0, ax->gc->bg_color->blue + grad, 1.0), ax->gc->bg_color->alpha); cairo_rectangle(ss->cr, x0, y0, width, height); cairo_set_source(ss->cr, pat); cairo_fill(ss->cr); cairo_pattern_destroy(pat); } } void draw_string(graphics_context *ax, int x0, int y0, const char *str, int len) { if (ax->current_font == NULL) return; if ((!str) || (!(*str))) return; if (!(g_utf8_validate(str, -1, NULL))) return; { PangoLayout *layout = NULL; cairo_save(ss->cr); layout = pango_cairo_create_layout(ss->cr); pango_layout_set_font_description(layout, ax->current_font); pango_layout_set_text(layout, str, -1); cairo_set_source_rgba(ss->cr, ax->gc->fg_color->red, ax->gc->fg_color->green, ax->gc->fg_color->blue, ax->gc->fg_color->alpha); cairo_move_to(ss->cr, x0, y0); pango_cairo_show_layout(ss->cr, layout); g_object_unref(G_OBJECT(layout)); cairo_restore(ss->cr); } } static void rotate_text(graphics_context *ax, PangoFontDescription *font, const char *text, int angle, gint x0, gint y0) { int width, height; PangoLayout *layout = NULL; cairo_save(ss->cr); layout = pango_cairo_create_layout(ss->cr); pango_layout_set_font_description(layout, font); pango_layout_set_text(layout, text, -1); pango_layout_get_size(layout, &width, &height); cairo_set_source_rgba(ss->cr, ax->gc->fg_color->red, ax->gc->fg_color->green, ax->gc->fg_color->blue, ax->gc->fg_color->alpha); cairo_move_to(ss->cr, x0 + (double)height / (2 * PANGO_SCALE), y0 + (double)width / PANGO_SCALE); cairo_rotate(ss->cr, mus_degrees_to_radians(-angle)); pango_cairo_update_layout(ss->cr, layout); pango_cairo_show_layout(ss->cr, layout); g_object_unref(layout); cairo_restore(ss->cr); } void draw_rotated_axis_label(chan_info *cp, graphics_context *ax, const char *text, gint x0, gint y0) { rotate_text(ax, AXIS_LABEL_FONT(ss), text, 90, x0, y0); } #if GTK_CHECK_VERSION(3, 0, 0) #define IS_DRAWABLE(Widget) GDK_IS_WINDOW(Widget) #else #define IS_DRAWABLE(Widget) GDK_IS_DRAWABLE(Widget) #endif void draw_picture(graphics_context *ax, picture_t *src, gint xsrc, gint ysrc, gint xdest, gint ydest, gint width, gint height) { if ((ax) && (IS_DRAWABLE(ax->wn))) { cairo_t *cr; cr = make_cairo(ax->wn); cairo_set_source_surface(cr, src, xsrc + xdest, ysrc + ydest); cairo_paint(cr); free_cairo(cr); } } static void draw_polygon_va(graphics_context *ax, bool filled, int points, va_list ap) { int i, x, y; x = va_arg(ap, int); y = va_arg(ap, int); cairo_set_source_rgba(ss->cr, ax->gc->fg_color->red, ax->gc->fg_color->green, ax->gc->fg_color->blue, ax->gc->fg_color->alpha); cairo_move_to(ss->cr, x, y); for (i = 1; i < points; i++) { x = va_arg(ap, int); y = va_arg(ap, int); cairo_line_to(ss->cr, x, y); } if (filled) { cairo_close_path(ss->cr); cairo_fill(ss->cr); } else cairo_stroke(ss->cr); } void fill_polygon(graphics_context *ax, int points, ...) { va_list ap; if (points == 0) return; va_start(ap, points); draw_polygon_va(ax, true, points, ap); va_end(ap); } void fill_polygon_from_array(graphics_context *ax, point_t *points, int npoints) { int i; cairo_set_source_rgba(ss->cr, ax->gc->fg_color->red, ax->gc->fg_color->green, ax->gc->fg_color->blue, ax->gc->fg_color->alpha); cairo_move_to(ss->cr, points[0].x, points[0].y); for (i = 1; i < npoints; i++) cairo_line_to(ss->cr, points[i].x, points[i].y); cairo_close_path(ss->cr); cairo_fill(ss->cr); } static point_t polypts[4]; void fill_polygons(graphics_context *ax, point_t *points, int num, int y0) { int i; for (i = 1; i < num; i++) { polypts[0].x = points[i - 1].x; polypts[0].y = points[i - 1].y; polypts[1].x = points[i].x; polypts[1].y = points[i].y; polypts[2].x = polypts[1].x; polypts[2].y = y0; polypts[3].x = points[i - 1].x; polypts[3].y = y0; fill_polygon_from_array(ax, polypts, 4); } } void fill_two_sided_polygons(graphics_context *ax, point_t *points, point_t *points1, int num) { int i; for (i = 1; i < num; i++) { polypts[0].x = points[i - 1].x; polypts[0].y = points[i - 1].y; polypts[1].x = points[i].x; polypts[1].y = points[i].y; polypts[2].x = points1[i].x; polypts[2].y = points1[i].y; polypts[3].x = points1[i - 1].x; polypts[3].y = points1[i - 1].y; fill_polygon_from_array(ax, polypts, 4); } } void setup_graphics_context(chan_info *cp, graphics_context *ax) { GtkWidget *w; w = channel_to_widget(cp); ax->gc = copy_GC(cp); ax->wn = WIDGET_TO_WINDOW(w); ax->w = w; } /* colormaps */ /* cairo colormaps */ static int sono_bins = 0; /* total_bins */ static int sono_colors = 0; /* colormap_size */ static GdkRectangle **sono_data = NULL; void check_colormap_sizes(int size) { if ((sono_data) && (sono_colors < size) && (sono_bins > 0)) { int i, old_size; old_size = sono_colors; sono_colors = size; sono_data = (GdkRectangle **)realloc(sono_data, sono_colors * sizeof(GdkRectangle *)); for (i = old_size; i < sono_colors; i++) sono_data[i] = (GdkRectangle *)calloc(sono_bins, sizeof(GdkRectangle)); } } void initialize_colormap(void) { sono_colors = color_map_size(ss); sono_data = (GdkRectangle **)calloc(sono_colors, sizeof(GdkRectangle *)); } void draw_sono_rectangles(graphics_context *ax, int color, int jmax) { int i; rgb_t r, g, b; get_current_color(color_map(ss), color, &r, &g, &b); cairo_save(ss->cr); cairo_set_source_rgb(ss->cr, r, g, b); for (i = 0; i < jmax; i++) { cairo_rectangle(ss->cr, sono_data[color][i].x, sono_data[color][i].y, sono_data[color][i].width, sono_data[color][i].height); cairo_fill(ss->cr); } cairo_restore(ss->cr); } void draw_spectro_line(graphics_context *ax, int color, int x0, int y0, int x1, int y1) { rgb_t r, g,b; get_current_color(color_map(ss), color, &r, &g, &b); cairo_set_source_rgb(ss->cr, r, g, b); if (ss->line_width != 1.0) { cairo_set_line_width(ss->cr, 1.0); ss->line_width = 1.0; } cairo_move_to(ss->cr, x0 + 0.5, y0 + 0.5); cairo_line_to(ss->cr, x1 + 0.5, y1 + 0.5); cairo_stroke(ss->cr); } void set_sono_rectangle(int j, int color, int x, int y, int width, int height) { GdkRectangle *r; r = sono_data[color]; r[j].x = x; r[j].y = y; r[j].width = width; r[j].height = height; } void allocate_sono_rects(int size) { if (size != sono_bins) { int i; for (i = 0; i < sono_colors; i++) { if ((sono_bins > 0) && (sono_data[i])) free(sono_data[i]); sono_data[i] = (GdkRectangle *)calloc(size, sizeof(GdkRectangle)); } sono_bins = size; } } void allocate_color_map(int colormap) { } void draw_colored_lines(chan_info *cp, graphics_context *ax, point_t *points, int num, int *colors, int axis_y0, color_t default_color) { /* only used for the fft-with-phases option, this is showing the phase via a colormap * colors are 0..colormap_size: colors[k] = (int)((fft_phases[k] * color_map_size(ss)) / (2.0 * M_PI)) */ int i, x0, y0, cur, prev; color_t old_color; rgb_t r, g, b; if (num <= 0) return; old_color = get_foreground_color(ax); cairo_save(ss->cr); x0 = points[0].x; y0 = points[0].y; if (abs(y0 - axis_y0) < 5) prev = -1; else prev = colors[0]; if (prev == -1) { r = default_color->red; g = default_color->green; b = default_color->blue; } else phases_rgb((mus_float_t)prev / (mus_float_t)color_map_size(ss), &r, &g, &b); cairo_set_source_rgb(ss->cr, r, g, b); for (i = 1; i < num; i++) { int x1, y1; x1 = points[i].x; y1 = points[i].y; if ((abs(y0 - axis_y0) < 5) && (abs(y1 - axis_y0) < 5)) cur = -1; else { if (y0 > y1) cur = colors[i]; else cur = colors[i - 1]; /* coords are upside down */ } if (cur != prev) { if (cur == -1) { r = default_color->red; g = default_color->green; b = default_color->blue; } else phases_rgb((mus_float_t)cur / (mus_float_t)color_map_size(ss), &r, &g, &b); cairo_set_source_rgb(ss->cr, r, g, b); prev = cur; } if (cp->transform_graph_style == GRAPH_DOTS) { cairo_arc(ss->cr, x0, y0, cp->dot_size / 2, 0.0, 2 * M_PI); cairo_fill(ss->cr); } else { if (ss->line_width != 1.0) { cairo_set_line_width(ss->cr, 1.0); ss->line_width = 1.0; } cairo_move_to(ss->cr, x0 + 0.5, y0 + 0.5); cairo_line_to(ss->cr, x1 + 0.5, y1 + 0.5); cairo_stroke(ss->cr); } x0 = x1; y0 = y1; } cairo_set_source_rgba(ss->cr, old_color->red, old_color->green, old_color->blue, old_color->alpha); cairo_restore(ss->cr); } /* -------- color browser -------- */ static Xen color_hook; static GtkWidget *ccd_dialog = NULL, *ccd_scale, *ccd_invert, *ccd_cutoff; static GtkAdjustment *ccd_scale_adj, *ccd_cutoff_adj; static slist *ccd_list; static void check_color_hook(void) { if (Xen_hook_has_list(color_hook)) run_hook(color_hook, Xen_empty_list, S_color_hook); } static void update_graph_setting_fft_changed(chan_info *cp) { cp->fft_changed = FFT_CHANGE_LOCKED; update_graph(cp); } static void invert_color_callback(GtkWidget *w, gpointer context) { in_set_color_inverted(TOGGLE_BUTTON_ACTIVE(w)); check_color_hook(); for_each_chan(update_graph_setting_fft_changed); } #if HAVE_GL static GtkWidget *gl_button = NULL; static void with_gl_callback(GtkWidget *w, gpointer context) { sgl_save_currents(); in_set_with_gl(TOGGLE_BUTTON_ACTIVE(w)); sgl_set_currents(true); for_each_chan(update_graph); } #endif void set_with_gl(bool val, bool with_dialogs) { in_set_with_gl(val); } void set_color_inverted(bool val) { in_set_color_inverted(val); if (ccd_dialog) set_toggle_button(ccd_invert, false, false, NULL); check_color_hook(); if (!(ss->graph_hook_active)) for_each_chan(update_graph_setting_fft_changed); } static void scale_color_callback(GtkAdjustment *adj, gpointer context) { gfloat scale_val, val; scale_val = ADJUSTMENT_VALUE(adj); if (scale_val <= 50) val = (mus_float_t)(scale_val + 1) / 51.0; else val = 1.0 + (mus_float_t)(scale_val - 50) * 20.0; in_set_color_scale(val); check_color_hook(); for_each_chan(update_graph_setting_fft_changed); } static void reflect_color_scale(mus_float_t val) { gfloat new_val; if (val < 0.02) new_val = 0.0; else { if (val <= 1.0) new_val = (val * 51.0 - 1); else new_val = (val - 1.0) / 20.0 + 50.0; } if (ccd_dialog) ADJUSTMENT_SET_VALUE(ccd_scale_adj, new_val); } void set_color_scale(mus_float_t val) { in_set_color_scale(val); if (ccd_dialog) reflect_color_scale(color_scale(ss)); check_color_hook(); if (!(ss->graph_hook_active)) for_each_chan(update_graph_setting_fft_changed); } static void list_color_callback(const char *name, int row, void *data) { in_set_color_map(row); for_each_chan(update_graph_setting_fft_changed); check_color_hook(); } void set_color_map(int val) { in_set_color_map(val); if ((ccd_dialog) && (val >= 0)) slist_select(ccd_list, val); check_color_hook(); if (!(ss->graph_hook_active)) for_each_chan(update_graph_setting_fft_changed); } #define CUTOFF_BASE 2.5 static void cutoff_color_callback(GtkAdjustment *adj, gpointer context) { in_set_color_cutoff(pow(ADJUSTMENT_VALUE(adj), CUTOFF_BASE)); check_color_hook(); for_each_chan(update_graph_setting_fft_changed); } static gchar* scale_pow_double_format_callback(GtkScale *w, gdouble val, gpointer data) { return(g_strdup_printf(" %.*f ", gtk_scale_get_digits(w), pow(val, CUTOFF_BASE))); /* not %g! */ } void set_color_cutoff(mus_float_t val) { in_set_color_cutoff(val); if (ccd_dialog) ADJUSTMENT_SET_VALUE(ccd_cutoff_adj, pow(val, 1.0 / CUTOFF_BASE)); check_color_hook(); if (!(ss->graph_hook_active)) for_each_chan(update_graph_setting_fft_changed); } static void dismiss_color_orientation_callback(GtkWidget *w, gpointer context) { gtk_widget_hide(ccd_dialog); } static void help_color_orientation_callback(GtkWidget *w, gpointer context) { color_orientation_dialog_help(); } static gint delete_color_orientation_dialog(GtkWidget *w, GdkEvent *event, gpointer context) { gtk_widget_hide(ccd_dialog); return(true); } void reflect_color_list(bool setup_time) { if ((ccd_dialog) && (ccd_list)) { int i, size; size = num_colormaps(); slist_clear(ccd_list); for (i = 0; i < size; i++) slist_append(ccd_list, colormap_name(i)); } } /* -------- orientation browser -------- */ static Xen orientation_hook; static void check_orientation_hook(void) { run_hook(orientation_hook, Xen_empty_list, S_orientation_hook); } static GtkWidget *oid_ax, *oid_ay, *oid_az, *oid_sx, *oid_sy, *oid_sz, *oid_hop; static GtkAdjustment *oid_ax_adj, *oid_az_adj, *oid_ay_adj, *oid_sx_adj, *oid_sz_adj, *oid_sy_adj, *oid_hop_adj; static void ax_orientation_callback(GtkAdjustment *adj, gpointer context) { in_set_spectro_x_angle((mus_float_t)(ADJUSTMENT_VALUE(adj))); chans_field(FCP_X_ANGLE, (mus_float_t)(ADJUSTMENT_VALUE(adj))); check_orientation_hook(); for_each_chan(update_graph); } void set_spectro_x_angle(mus_float_t val) { in_set_spectro_x_angle(val); if (ccd_dialog) ADJUSTMENT_SET_VALUE(oid_ax_adj, val); chans_field(FCP_X_ANGLE, val); check_orientation_hook(); if (!(ss->graph_hook_active)) for_each_chan(update_graph); } static void ay_orientation_callback(GtkAdjustment *adj, gpointer context) { in_set_spectro_y_angle((mus_float_t)(ADJUSTMENT_VALUE(adj))); chans_field(FCP_Y_ANGLE, (mus_float_t)(ADJUSTMENT_VALUE(adj))); check_orientation_hook(); for_each_chan(update_graph); } void set_spectro_y_angle(mus_float_t val) { in_set_spectro_y_angle(val); if (ccd_dialog) ADJUSTMENT_SET_VALUE(oid_ay_adj, val); chans_field(FCP_Y_ANGLE, val); check_orientation_hook(); if (!(ss->graph_hook_active)) for_each_chan(update_graph); } static void az_orientation_callback(GtkAdjustment *adj, gpointer context) { in_set_spectro_z_angle((mus_float_t)(ADJUSTMENT_VALUE(adj))); chans_field(FCP_Z_ANGLE, (mus_float_t)(ADJUSTMENT_VALUE(adj))); check_orientation_hook(); for_each_chan(update_graph); } void set_spectro_z_angle(mus_float_t val) { in_set_spectro_z_angle(val); if (ccd_dialog) ADJUSTMENT_SET_VALUE(oid_az_adj, val); chans_field(FCP_Z_ANGLE, val); check_orientation_hook(); if (!(ss->graph_hook_active)) for_each_chan(update_graph); } static void sx_orientation_callback(GtkAdjustment *adj, gpointer context) { in_set_spectro_x_scale((mus_float_t)(ADJUSTMENT_VALUE(adj))); chans_field(FCP_X_SCALE, (mus_float_t)(ADJUSTMENT_VALUE(adj))); check_orientation_hook(); for_each_chan(update_graph); } void set_spectro_x_scale(mus_float_t val) { in_set_spectro_x_scale(val); if (ccd_dialog) ADJUSTMENT_SET_VALUE(oid_sx_adj, val); chans_field(FCP_X_SCALE, val); check_orientation_hook(); if (!(ss->graph_hook_active)) for_each_chan(update_graph); } static void sy_orientation_callback(GtkAdjustment *adj, gpointer context) { in_set_spectro_y_scale((mus_float_t)(ADJUSTMENT_VALUE(adj))); chans_field(FCP_Y_SCALE, (mus_float_t)(ADJUSTMENT_VALUE(adj))); check_orientation_hook(); for_each_chan(update_graph); } void set_spectro_y_scale(mus_float_t val) { in_set_spectro_y_scale(val); if (ccd_dialog) ADJUSTMENT_SET_VALUE(oid_sy_adj, val); chans_field(FCP_Y_SCALE, val); check_orientation_hook(); if (!(ss->graph_hook_active)) for_each_chan(update_graph); } static void sz_orientation_callback(GtkAdjustment *adj, gpointer context) { in_set_spectro_z_scale((mus_float_t)(ADJUSTMENT_VALUE(adj))); chans_field(FCP_Z_SCALE, (mus_float_t)(ADJUSTMENT_VALUE(adj))); check_orientation_hook(); for_each_chan(update_graph); } void set_spectro_z_scale(mus_float_t val) { in_set_spectro_z_scale(val); if (ccd_dialog) ADJUSTMENT_SET_VALUE(oid_sz_adj, val); chans_field(FCP_Z_SCALE, val); check_orientation_hook(); if (!(ss->graph_hook_active)) for_each_chan(update_graph); } static void chans_spectro_hop(chan_info *cp, int value) { cp->spectro_hop = value; } static void hop_callback(GtkAdjustment *adj, gpointer context) { int val; val = mus_iclamp(1, (int)(ADJUSTMENT_VALUE(adj)), 20); in_set_spectro_hop(val); for_each_chan_with_int(chans_spectro_hop, val); check_orientation_hook(); for_each_chan(update_graph); } static gchar* scale_int_format_callback(GtkScale *w, gdouble val, gpointer data) { /* gtk_scale_get_digits(w) here will be 0 (set below), so we want ints * this is needed since the value-spacing style property apparently does not put space between the value and the scale */ return(g_strdup_printf(" %d ", (int)val)); } gchar* scale_double_format_callback(GtkScale *w, gdouble val, gpointer data) { return(g_strdup_printf(" %.*f ", gtk_scale_get_digits(w), val)); /* not %g! */ } void set_spectro_hop(int val) { if (val > 0) { in_set_spectro_hop(val); if (ccd_dialog) ADJUSTMENT_SET_VALUE(oid_hop_adj, val); for_each_chan_with_int(chans_spectro_hop, val); check_orientation_hook(); if (!(ss->graph_hook_active)) for_each_chan(update_graph); } } static int fixup_angle(mus_float_t ang) { int na; na = (int)ang; na = na % 360; if (na < 0) na += 360; return(na); } void reflect_spectro(void) { /* set color/orientaton widget values */ if (ccd_dialog) { set_toggle_button(ccd_invert, color_inverted(ss), false, NULL); ADJUSTMENT_SET_VALUE(ccd_cutoff_adj, color_cutoff(ss)); reflect_color_scale(color_scale(ss)); ADJUSTMENT_SET_VALUE(oid_ax_adj, fixup_angle(spectro_x_angle(ss))); ADJUSTMENT_SET_VALUE(oid_ay_adj, fixup_angle(spectro_y_angle(ss))); ADJUSTMENT_SET_VALUE(oid_az_adj, fixup_angle(spectro_z_angle(ss))); ADJUSTMENT_SET_VALUE(oid_sx_adj, spectro_x_scale(ss)); ADJUSTMENT_SET_VALUE(oid_sy_adj, spectro_y_scale(ss)); ADJUSTMENT_SET_VALUE(oid_sz_adj, spectro_z_scale(ss)); ADJUSTMENT_SET_VALUE(oid_hop_adj, (spectro_hop(ss) > 100) ? 100 : (spectro_hop(ss))); check_orientation_hook(); } } static void reset_color_orientation_callback(GtkWidget *w, gpointer context) { /* put everything back the way it was at the start */ set_color_cutoff(DEFAULT_COLOR_CUTOFF); set_color_inverted(DEFAULT_COLOR_INVERTED); set_color_scale(DEFAULT_COLOR_SCALE); set_color_map(DEFAULT_COLOR_MAP); reset_spectro(); reflect_spectro(); for_each_chan(update_graph); } void view_color_orientation_callback(GtkWidget *w, gpointer context) { make_color_orientation_dialog(true); } bool color_orientation_dialog_is_active(void) { return((ccd_dialog) && (widget_is_active(ccd_dialog))); } GtkWidget *make_color_orientation_dialog(bool managed) { if (!ccd_dialog) { GtkWidget *light_label, *dark_label, *help_button, *dismiss_button, *reset_button; GtkWidget *scale_box, *cutoff_box, *cutoff_label; GtkWidget *color_label, *mainbox, *colorbox, *map_box; GtkWidget *shbox; GtkWidget *ax_box, *ay_box, *az_box, *sx_box, *sy_box, *sz_box, *hop_box; GtkWidget *ax_label, *ay_label, *az_label, *sx_label, *sy_label, *sz_label, *hop_label; GtkWidget *orient_label, *orientbox; GtkWidget *sep1, *sep2, *sep3, *sep5; #if (!GTK_CHECK_VERSION(3, 0, 0)) GtkWidget *orient_frame, *color_frame; #endif ccd_dialog = snd_gtk_dialog_new(); #if GTK_CHECK_VERSION(3, 14, 0) gtk_window_set_transient_for(GTK_WINDOW(ccd_dialog), GTK_WINDOW(MAIN_SHELL(ss))); #endif SG_SIGNAL_CONNECT(ccd_dialog, "delete_event", delete_color_orientation_dialog, NULL); gtk_window_set_title(GTK_WINDOW(ccd_dialog), "Color"); sg_make_resizable(ccd_dialog); gtk_container_set_border_width (GTK_CONTAINER(ccd_dialog), 4); gtk_widget_realize(ccd_dialog); gtk_window_resize(GTK_WINDOW(ccd_dialog), 400, 200); help_button = gtk_dialog_add_button(GTK_DIALOG(ccd_dialog), "Help", GTK_RESPONSE_NONE); reset_button = gtk_dialog_add_button(GTK_DIALOG(ccd_dialog), "Revert", GTK_RESPONSE_NONE); dismiss_button = gtk_dialog_add_button(GTK_DIALOG(ccd_dialog), "Go away", GTK_RESPONSE_NONE); gtk_widget_set_name(help_button, "dialog_button"); gtk_widget_set_name(dismiss_button, "dialog_button"); gtk_widget_set_name(reset_button, "dialog_button"); add_highlight_button_style(dismiss_button); add_highlight_button_style(reset_button); add_highlight_button_style(help_button); SG_SIGNAL_CONNECT(dismiss_button, "clicked", dismiss_color_orientation_callback, NULL); SG_SIGNAL_CONNECT(help_button, "clicked", help_color_orientation_callback, NULL); SG_SIGNAL_CONNECT(reset_button, "clicked", reset_color_orientation_callback, NULL); gtk_widget_show(dismiss_button); gtk_widget_show(reset_button); gtk_widget_show(help_button); mainbox = gtk_vbox_new(false, 0); gtk_container_add(GTK_CONTAINER(DIALOG_CONTENT_AREA(ccd_dialog)), mainbox); gtk_widget_show(mainbox); #if (!GTK_CHECK_VERSION(3, 0, 0)) color_frame = gtk_frame_new(NULL); gtk_box_pack_start(GTK_BOX(mainbox), color_frame, false, false, 10); gtk_frame_set_shadow_type(GTK_FRAME(color_frame), GTK_SHADOW_ETCHED_IN); widget_set_vexpand(color_frame, true); gtk_widget_show(color_frame); #endif colorbox = gtk_vbox_new(false, 2); #if GTK_CHECK_VERSION(3, 0, 0) gtk_box_pack_start(GTK_BOX(mainbox), colorbox, false, false, 10); #else gtk_container_add(GTK_CONTAINER(color_frame), colorbox); #endif widget_set_vexpand(colorbox, true); gtk_widget_show(colorbox); color_label = snd_gtk_highlight_label_new("colors"); gtk_box_pack_start(GTK_BOX(colorbox), color_label, false, false, 0); gtk_widget_show(color_label); /* invert colormap * light -> dark * cutoff * if gl, use gl button */ map_box = gtk_hbox_new(false, 4); widget_set_vexpand(map_box, true); widget_set_margin_left(map_box, 8); gtk_box_pack_start(GTK_BOX(colorbox), map_box, true, true, 8); gtk_widget_show(map_box); { char **names; #if (!GTK_CHECK_VERSION(3, 0, 0)) GtkWidget *frame; #endif int i, size; #if (!GTK_CHECK_VERSION(3, 0, 0)) frame = gtk_frame_new(NULL); gtk_container_set_border_width(GTK_CONTAINER(frame), 0); gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN); widget_modify_bg(frame, GTK_STATE_NORMAL, ss->zoom_color); gtk_box_pack_start(GTK_BOX(map_box), frame, true, true, 0); widget_set_hexpand(frame, true); widget_set_vexpand(frame, true); gtk_widget_show(frame); #endif size = num_colormaps(); names = (char **)calloc(size, sizeof(char *)); for (i = 0; i < size; i++) names[i] = colormap_name(i); #if GTK_CHECK_VERSION(3, 0, 0) ccd_list = slist_new_with_title(S_colormap, map_box, (const char**)names, size, BOX_PACK); #else ccd_list = slist_new_with_title(S_colormap, frame, (const char**)names, size, CONTAINER_ADD); #endif ccd_list->select_callback = list_color_callback; widget_set_vexpand(ccd_list->box, true); free(names); #if GTK_CHECK_VERSION(3, 0, 0) gtk_scrolled_window_set_min_content_height(GTK_SCROLLED_WINDOW(ccd_list->scroller), 140); #endif } ccd_invert = gtk_check_button_new_with_label("invert"); SG_SIGNAL_CONNECT(ccd_invert, "toggled", invert_color_callback, NULL); gtk_box_pack_start(GTK_BOX(map_box), ccd_invert, false, false, 12); gtk_widget_show(ccd_invert); set_toggle_button(ccd_invert, color_inverted(ss), false, NULL); scale_box = gtk_vbox_new(false, 0); widget_set_margin_left(scale_box, 8); widget_set_margin_right(scale_box, 8); gtk_box_pack_start(GTK_BOX(colorbox), scale_box, false, false, 0); gtk_widget_show(scale_box); ccd_scale_adj = (GtkAdjustment *)gtk_adjustment_new(50.0, 0.0, 101.0, 0.1, 1.0, 1.0); ccd_scale = gtk_hscale_new(GTK_ADJUSTMENT(ccd_scale_adj)); UNSET_CAN_FOCUS(ccd_scale); gtk_range_set_update_policy(GTK_RANGE(GTK_SCALE(ccd_scale)), GTK_UPDATE_CONTINUOUS); gtk_scale_set_digits(GTK_SCALE(ccd_scale), 0); gtk_scale_set_value_pos(GTK_SCALE(ccd_scale), GTK_POS_TOP); gtk_scale_set_draw_value(GTK_SCALE(ccd_scale), true); gtk_box_pack_start(GTK_BOX(scale_box), ccd_scale, true, true, 0); SG_SIGNAL_CONNECT(ccd_scale_adj, "value_changed", scale_color_callback, NULL); SG_SIGNAL_CONNECT(ccd_scale, "format-value", scale_int_format_callback, NULL); gtk_widget_show(ccd_scale); shbox = gtk_hbox_new(false, 10); gtk_box_pack_start(GTK_BOX(scale_box), shbox, true, true, 0); gtk_widget_show(shbox); light_label = gtk_label_new("light"); #if GTK_CHECK_VERSION(3, 14, 0) gtk_widget_set_halign(GTK_WIDGET(light_label), GTK_ALIGN_START); #else gtk_misc_set_alignment(GTK_MISC(light_label), 0.05, 0.0); #endif gtk_box_pack_start(GTK_BOX(shbox), light_label, false, false, 0); gtk_widget_show(light_label); dark_label = gtk_label_new("dark"); #if GTK_CHECK_VERSION(3, 14, 0) gtk_widget_set_halign(GTK_WIDGET(dark_label), GTK_ALIGN_END); #else gtk_misc_set_alignment(GTK_MISC(dark_label), 0.95, 0.0); #endif gtk_box_pack_end(GTK_BOX(shbox), dark_label, false, false, 0); gtk_widget_show(dark_label); cutoff_box = gtk_hbox_new(false, 0); widget_set_margin_left(cutoff_box, 8); widget_set_margin_right(cutoff_box, 8); gtk_box_pack_start(GTK_BOX(colorbox), cutoff_box, false, false, 8); gtk_widget_show(cutoff_box); cutoff_label = gtk_label_new("data cutoff:"); gtk_box_pack_start(GTK_BOX(cutoff_box), cutoff_label, false, false, 4); gtk_widget_show(cutoff_label); ccd_cutoff_adj = (GtkAdjustment *)gtk_adjustment_new(color_cutoff(ss), 0.0, 1.01, 0.001, 0.01, .01); ccd_cutoff = gtk_hscale_new(GTK_ADJUSTMENT(ccd_cutoff_adj)); UNSET_CAN_FOCUS(ccd_cutoff); gtk_range_set_update_policy(GTK_RANGE(GTK_SCALE(ccd_cutoff)), GTK_UPDATE_CONTINUOUS); gtk_scale_set_digits(GTK_SCALE(ccd_cutoff), 4); gtk_scale_set_value_pos(GTK_SCALE(ccd_cutoff), GTK_POS_LEFT); gtk_scale_set_draw_value(GTK_SCALE(ccd_cutoff), true); SG_SIGNAL_CONNECT(ccd_cutoff_adj, "value_changed", cutoff_color_callback, NULL); SG_SIGNAL_CONNECT(ccd_cutoff, "format-value", scale_pow_double_format_callback, NULL); gtk_box_pack_start(GTK_BOX(cutoff_box), ccd_cutoff, true, true, 0); gtk_widget_show(ccd_cutoff); #if HAVE_GL gl_button = gtk_check_button_new_with_label("use GL"); SG_SIGNAL_CONNECT(gl_button, "toggled", with_gl_callback, NULL); gtk_box_pack_end(GTK_BOX(colorbox), gl_button, false, false, 12); gtk_widget_show(gl_button); set_toggle_button(gl_button, with_gl(ss), false, NULL); #endif set_dialog_widget(COLOR_ORIENTATION_DIALOG, ccd_dialog); if (color_map(ss) != BLACK_AND_WHITE_COLORMAP) slist_select(ccd_list, color_map(ss)); /* orientation section */ #if (!GTK_CHECK_VERSION(3, 0, 0)) orient_frame = gtk_frame_new(NULL); gtk_box_pack_start(GTK_BOX(mainbox), orient_frame, false, false, 0); gtk_frame_set_shadow_type(GTK_FRAME(orient_frame), GTK_SHADOW_ETCHED_IN); gtk_widget_show(orient_frame); #else { GtkWidget *sep; sep = gtk_hseparator_new(); gtk_box_pack_start(GTK_BOX(mainbox), sep, false, false, 2); gtk_widget_show(sep); } #endif orientbox = gtk_vbox_new(false, 2); #if GTK_CHECK_VERSION(3, 0, 0) /* gtk_widget_set_vexpand(orientbox, true); */ widget_set_margin_left(orientbox, 8); widget_set_margin_right(orientbox, 8); gtk_box_pack_start(GTK_BOX(mainbox), orientbox, false, false, 10); #else gtk_container_add(GTK_CONTAINER(orient_frame), orientbox); #endif gtk_widget_show(orientbox); orient_label = snd_gtk_highlight_label_new("orientation"); gtk_box_pack_start(GTK_BOX(orientbox), orient_label, false, false, 10); gtk_widget_show(orient_label); sep3 = gtk_vseparator_new(); gtk_box_pack_start(GTK_BOX(orientbox), sep3, false, false, 3); widget_modify_bg(sep3, GTK_STATE_NORMAL, ss->basic_color); gtk_widget_show(sep3); #if GTK_CHECK_VERSION(3, 0, 0) #define PADDING 4 #else #define PADDING 2 #endif /* AX */ ax_box = gtk_hbox_new(false, 0); gtk_box_pack_start(GTK_BOX(orientbox), ax_box, true, true, PADDING); gtk_widget_show(ax_box); ax_label = gtk_label_new("x angle:"); gtk_box_pack_start(GTK_BOX(ax_box), ax_label, false, false, 4); gtk_widget_show(ax_label); oid_ax_adj = (GtkAdjustment *)gtk_adjustment_new(spectro_x_angle(ss), 0.0, 361.0, 1.0, 10.0, 1.0); oid_ax = gtk_hscale_new(GTK_ADJUSTMENT(oid_ax_adj)); UNSET_CAN_FOCUS(oid_ax); gtk_range_set_update_policy(GTK_RANGE(GTK_SCALE(oid_ax)), GTK_UPDATE_CONTINUOUS); gtk_scale_set_digits(GTK_SCALE(oid_ax), 0); gtk_scale_set_value_pos(GTK_SCALE(oid_ax), GTK_POS_LEFT); gtk_scale_set_draw_value(GTK_SCALE(oid_ax), true); SG_SIGNAL_CONNECT(oid_ax_adj, "value_changed", ax_orientation_callback, NULL); SG_SIGNAL_CONNECT(oid_ax, "format-value", scale_int_format_callback, NULL); gtk_box_pack_start(GTK_BOX(ax_box), oid_ax, true, true, 0); gtk_widget_show(oid_ax); /* AY */ ay_box = gtk_hbox_new(false, 0); gtk_box_pack_start(GTK_BOX(orientbox), ay_box, true, true, PADDING); gtk_widget_show(ay_box); ay_label = gtk_label_new("y angle:"); gtk_box_pack_start(GTK_BOX(ay_box), ay_label, false, false, 4); gtk_widget_show(ay_label); oid_ay_adj = (GtkAdjustment *)gtk_adjustment_new(spectro_y_angle(ss), 0.0, 361.0, 1.0, 10.0, 1.0); oid_ay = gtk_hscale_new(GTK_ADJUSTMENT(oid_ay_adj)); UNSET_CAN_FOCUS(oid_ay); gtk_range_set_update_policy(GTK_RANGE(GTK_SCALE(oid_ay)), GTK_UPDATE_CONTINUOUS); gtk_scale_set_digits(GTK_SCALE(oid_ay), 0); gtk_scale_set_value_pos(GTK_SCALE(oid_ay), GTK_POS_LEFT); gtk_scale_set_draw_value(GTK_SCALE(oid_ay), true); SG_SIGNAL_CONNECT(oid_ay_adj, "value_changed", ay_orientation_callback, NULL); SG_SIGNAL_CONNECT(oid_ay, "format-value", scale_int_format_callback, NULL); gtk_box_pack_start(GTK_BOX(ay_box), oid_ay, true, true, 0); gtk_widget_show(oid_ay); /* AZ */ az_box = gtk_hbox_new(false, 0); gtk_box_pack_start(GTK_BOX(orientbox), az_box, true, true, PADDING); gtk_widget_show(az_box); az_label = gtk_label_new("z angle:"); gtk_box_pack_start(GTK_BOX(az_box), az_label, false, false, 4); gtk_widget_show(az_label); oid_az_adj = (GtkAdjustment *)gtk_adjustment_new(spectro_z_angle(ss), 0.0, 361.0, 1.0, 10.0, 1.0); oid_az = gtk_hscale_new(GTK_ADJUSTMENT(oid_az_adj)); UNSET_CAN_FOCUS(oid_az); gtk_range_set_update_policy(GTK_RANGE(GTK_SCALE(oid_az)), GTK_UPDATE_CONTINUOUS); gtk_scale_set_digits(GTK_SCALE(oid_az), 0); gtk_scale_set_value_pos(GTK_SCALE(oid_az), GTK_POS_LEFT); gtk_scale_set_draw_value(GTK_SCALE(oid_az), true); SG_SIGNAL_CONNECT(oid_az_adj, "value_changed", az_orientation_callback, NULL); SG_SIGNAL_CONNECT(oid_az, "format-value", scale_int_format_callback, NULL); gtk_box_pack_start(GTK_BOX(az_box), oid_az, true, true, 0); gtk_widget_show(oid_az); sep1 = gtk_vseparator_new(); /* not hseparator! */ gtk_box_pack_start(GTK_BOX(orientbox), sep1, false, false, 3 * PADDING); widget_modify_bg(sep1, GTK_STATE_NORMAL, ss->basic_color); gtk_widget_show(sep1); /* SX */ sx_box = gtk_hbox_new(false, 0); gtk_box_pack_start(GTK_BOX(orientbox), sx_box, true, true, PADDING); gtk_widget_show(sx_box); sx_label = gtk_label_new("x scale:"); gtk_box_pack_start(GTK_BOX(sx_box), sx_label, false, false, 4); gtk_widget_show(sx_label); oid_sx_adj = (GtkAdjustment *)gtk_adjustment_new(spectro_x_scale(ss), 0.0, 2.01, .01, .1, .01); oid_sx = gtk_hscale_new(GTK_ADJUSTMENT(oid_sx_adj)); UNSET_CAN_FOCUS(oid_sx); gtk_range_set_update_policy(GTK_RANGE(GTK_SCALE(oid_sx)), GTK_UPDATE_CONTINUOUS); gtk_scale_set_digits(GTK_SCALE(oid_sx), 2); gtk_scale_set_value_pos(GTK_SCALE(oid_sx), GTK_POS_LEFT); gtk_scale_set_draw_value(GTK_SCALE(oid_sx), true); SG_SIGNAL_CONNECT(oid_sx_adj, "value_changed", sx_orientation_callback, NULL); SG_SIGNAL_CONNECT(oid_sx, "format-value", scale_double_format_callback, NULL); gtk_box_pack_start(GTK_BOX(sx_box), oid_sx, true, true, 0); gtk_widget_show(oid_sx); /* SY */ sy_box = gtk_hbox_new(false, 0); gtk_box_pack_start(GTK_BOX(orientbox), sy_box, true, true, PADDING); gtk_widget_show(sy_box); sy_label = gtk_label_new("y scale:"); gtk_box_pack_start(GTK_BOX(sy_box), sy_label, false, false, 4); gtk_widget_show(sy_label); oid_sy_adj = (GtkAdjustment *)gtk_adjustment_new(spectro_y_scale(ss), 0.0, 2.01, .01, .1, .01); oid_sy = gtk_hscale_new(GTK_ADJUSTMENT(oid_sy_adj)); UNSET_CAN_FOCUS(oid_sy); gtk_range_set_update_policy(GTK_RANGE(GTK_SCALE(oid_sy)), GTK_UPDATE_CONTINUOUS); gtk_scale_set_digits(GTK_SCALE(oid_sy), 2); gtk_scale_set_value_pos(GTK_SCALE(oid_sy), GTK_POS_LEFT); gtk_scale_set_draw_value(GTK_SCALE(oid_sy), true); SG_SIGNAL_CONNECT(oid_sy_adj, "value_changed", sy_orientation_callback, NULL); SG_SIGNAL_CONNECT(oid_sy, "format-value", scale_double_format_callback, NULL); gtk_box_pack_start(GTK_BOX(sy_box), oid_sy, true, true, 0); gtk_widget_show(oid_sy); /* SZ */ sz_box = gtk_hbox_new(false, 0); gtk_box_pack_start(GTK_BOX(orientbox), sz_box, true, true, PADDING); gtk_widget_show(sz_box); sz_label = gtk_label_new("z scale:"); gtk_box_pack_start(GTK_BOX(sz_box), sz_label, false, false, 4); gtk_widget_show(sz_label); oid_sz_adj = (GtkAdjustment *)gtk_adjustment_new(spectro_z_scale(ss), 0.0, 2.01, .01, .1, .01); oid_sz = gtk_hscale_new(GTK_ADJUSTMENT(oid_sz_adj)); UNSET_CAN_FOCUS(oid_sz); gtk_range_set_update_policy(GTK_RANGE(GTK_SCALE(oid_sz)), GTK_UPDATE_CONTINUOUS); gtk_scale_set_digits(GTK_SCALE(oid_sz), 2); gtk_scale_set_value_pos(GTK_SCALE(oid_sz), GTK_POS_LEFT); gtk_scale_set_draw_value(GTK_SCALE(oid_sz), true); SG_SIGNAL_CONNECT(oid_sz_adj, "value_changed", sz_orientation_callback, NULL); SG_SIGNAL_CONNECT(oid_sz, "format-value", scale_double_format_callback, NULL); gtk_box_pack_start(GTK_BOX(sz_box), oid_sz, true, true, 0); gtk_widget_show(oid_sz); sep2 = gtk_vseparator_new(); gtk_box_pack_start(GTK_BOX(orientbox), sep2, false, false, 3 * PADDING); widget_modify_bg(sep2, GTK_STATE_NORMAL, ss->basic_color); gtk_widget_show(sep2); /* HOP */ hop_box = gtk_hbox_new(false, 0); gtk_box_pack_start(GTK_BOX(orientbox), hop_box, false, false, PADDING); gtk_widget_show(hop_box); hop_label = gtk_label_new("hop: "); gtk_box_pack_start(GTK_BOX(hop_box), hop_label, false, false, 4); gtk_widget_show(hop_label); oid_hop_adj = (GtkAdjustment *)gtk_adjustment_new((spectro_hop(ss) > 20) ? 20 : (spectro_hop(ss)), 0.0, 21.0, 0.1, 1.0, 1.0); oid_hop = gtk_hscale_new(GTK_ADJUSTMENT(oid_hop_adj)); UNSET_CAN_FOCUS(oid_hop); gtk_range_set_update_policy(GTK_RANGE(GTK_SCALE(oid_hop)), GTK_UPDATE_CONTINUOUS); gtk_scale_set_digits(GTK_SCALE(oid_hop), 0); gtk_scale_set_value_pos(GTK_SCALE(oid_hop), GTK_POS_LEFT); gtk_scale_set_draw_value(GTK_SCALE(oid_hop), true); SG_SIGNAL_CONNECT(oid_hop_adj, "value_changed", hop_callback, NULL); SG_SIGNAL_CONNECT(oid_hop, "format-value", scale_int_format_callback, NULL); gtk_box_pack_start(GTK_BOX(hop_box), oid_hop, true, true, 0); gtk_widget_show(oid_hop); sep5 = gtk_vseparator_new(); gtk_box_pack_start(GTK_BOX(orientbox), sep5, false, false, 2 * PADDING); widget_modify_bg(sep5, GTK_STATE_NORMAL, ss->basic_color); gtk_widget_show(sep5); } else raise_dialog(ccd_dialog); if (managed) gtk_widget_show(ccd_dialog); return(ccd_dialog); } static Xen g_background_gradient(void) {return(C_double_to_Xen_real(ss->bg_gradient));} static Xen g_set_background_gradient(Xen val) { #define H_background_gradient "(" S_background_gradient "): channel graph background color gradient" Xen_check_type(Xen_is_number(val), val, 1, S_set S_background_gradient, "a number between 0 (none) and 1"); ss->bg_gradient = Xen_real_to_C_double(val); for_each_chan(update_graph); return(val); } Xen_wrap_no_args(g_background_gradient_w, g_background_gradient) Xen_wrap_1_arg(g_set_background_gradient_w, g_set_background_gradient) void g_init_gxdraw(void) { Xen_define_dilambda(S_background_gradient, g_background_gradient_w, H_background_gradient, S_set S_background_gradient, g_set_background_gradient_w, 0, 0, 1, 0); #define H_orientation_hook S_orientation_hook " (): called whenever one of the variables associated with the \ orientation dialog changes" #define H_color_hook S_color_hook " (): called whenever one of the variables associated with the \ color dialog changes" orientation_hook = Xen_define_hook(S_orientation_hook, "(make-hook)", 0, H_orientation_hook); color_hook = Xen_define_hook(S_color_hook, "(make-hook)", 0, H_color_hook); } snd-16.1/lint.scm0000644000076400007640000054472012626046436012032 0ustar bilbil;;; lint for s7 scheme ;;; ;;; (lint "file.scm") checks file.scm for infelicities ;;; to control the kinds of checks, set the variables below. (provide 'lint.scm) (require stuff.scm) ;(require write.scm) (if (provided? 'pure-s7) (begin (define (make-polar mag ang) (complex (* mag (cos ang)) (* mag (sin ang)))) (define (memq a b) (member a b eq?)) (define (memv a b) (member a b eqv?)) (define (assq a b) (assoc a b eq?)) (define (assv a b) (assoc a b eqv?)) (define (char-ci=? . chars) (apply char=? (map char-upcase chars))) (define (char-ci<=? . chars) (apply char<=? (map char-upcase chars))) (define (char-ci>=? . chars) (apply char>=? (map char-upcase chars))) (define (char-ci? . chars) (apply char>? (map char-upcase chars))) (define (string-ci=? . strs) (apply string=? (map string-upcase strs))) (define (string-ci<=? . strs) (apply string<=? (map string-upcase strs))) (define (string-ci>=? . strs) (apply string>=? (map string-upcase strs))) (define (string-ci? . strs) (apply string>? (map string-upcase strs))) (define (let->list e) (if (let? e) (reverse! (map values e)) (error 'wrong-type-arg "let->list argument should be an environment: ~A" str))) )) (define *report-unused-parameters* #f) (define *report-unused-top-level-functions* #f) (define *report-multiply-defined-top-level-functions* #f) ; same name defined at top level in more than one file (define *report-shadowed-variables* #f) (define *report-minor-stuff* #t) ; now obsolete (#t) (define *report-doc-strings* #f) ; report old-style (CL) doc strings (define *load-file-first* #f) ; this will actually load the file, so errors will stop lint (define start-up-let (rootlet)) (define *current-file* "") (define *top-level-objects* (make-hash-table)) (define *lint-output-port* *stderr*) (format *stderr* "loading lint.scm~%") (set! reader-cond #f) (define-macro (reader-cond . clauses) `(values)) ; clobber reader-cond to avoid dumb unbound-variable errors ;;; -------------------------------------------------------------------------------- ;;; for snd-test.scm (set! *#readers* (cons (cons #\_ (lambda (str) (and (string=? str "__line__") (port-line-number)))) *#readers*)) (when (not (provided? 'snd)) (define defanimal define*) (define definstrument define*) (define defgenerator define*)) ;;; -------------------------------------------------------------------------------- (define lint (let () (define (any-real? lst) ; ignore 0.0 and 1.0 in this since they normally work (and (pair? lst) (or (and (number? (car lst)) (not (rational? (car lst))) (not (= (car lst) 0.0)) (not (= (car lst) 1.0))) (any-real? (cdr lst))))) (define (quoted-undotted-pair? x) (and (pair? x) (eq? (car x) 'quote) (pair? (cdr x)) (pair? (cadr x)) (positive? (length (cadr x))))) (define (quoted-null? x) (and (pair? x) (eq? (car x) 'quote) (pair? (cdr x)) (null? (cadr x)))) (define (code-constant? x) (and (not (symbol? x)) (or (not (pair? x)) (and (eq? (car x) 'quote) (list? (cdr x)))))) ; was pair? (let ((no-side-effect-functions ;; ideally we'd be able to add functions to this list, perhaps similar to the signatures (let ((ht (make-hash-table))) (for-each (lambda (op) (hash-table-set! ht op #t)) '(* + - / < <= = > >= abs acos acosh and angle append aritable? arity ash asin asinh assoc assq assv atan atanh begin boolean=? boolean? byte-vector byte-vector? caaaar caaadr caaar caadar caaddr caadr caar cadaar cadadr cadar caddar cadddr caddr cadr call-with-input-from-string call-with-input-from-file c-pointer c-pointer? c-object? call-with-exit car case catch cdaaar cdaadr cdaar cdadar cdaddr cdadr cdar cddaar cddadr cddar cdddar cddddr cdddr cddr cdr ceiling char->integer char-alphabetic? char-ci<=? char-ci=? char-ci>? char-downcase char-lower-case? char-numeric? char-position char-ready? char-upcase char-upper-case? char-whitespace? char<=? char=? char>? char? complex complex? cond cons constant? continuation? cos cosh curlet current-error-port current-input-port current-output-port cyclic-sequences defined? denominator dilambda? do dynamic-wind eof-object? eq? equal? eqv? even? exact->inexact exact? exp expt float? float-vector float-vector-ref float-vector? floor for-each funclet gcd gensym gensym? hash-table hash-table* hash-table-entries hash-table-ref hash-table? help hook-functions if imag-part inexact->exact inexact? infinite? inlet input-port? int-vector int-vector-ref int-vector? iterator-at-end? iterator-sequence integer->char integer-decode-float integer-length integer? iterator? keyword->symbol keyword? let->list lcm length let let* let-ref let? letrec letrec* list list->string list->vector list-ref list-tail list? log logand logbit? logior lognot logxor macro? magnitude make-byte-vector make-float-vector make-int-vector make-hash-table make-hook make-iterator make-keyword make-list make-polar make-rectangular make-shared-vector make-string make-vector map max member memq memv min modulo morally-equal? nan? negative? not null? number->string number? numerator object->string odd? openlet? or outlet output-port? owlet pair-line-number pair? peek-char port-closed? port-filename port-line-number positive? procedure-documentation procedure-setter procedure-signature procedure-source procedure? proper-list? provided? quasiquote quote quotient random-state random-state->list random-state? rational? rationalize real-part real? remainder reverse rootlet round s7-version sequence? sin sinh sqrt stacktrace string string->list string->number string->symbol string-append string-ci<=? string-ci=? string-ci>? string-downcase string-length string-position string-ref string-upcase string<=? string=? string>? string? sublet substring symbol symbol->dynamic-value symbol->keyword symbol->string symbol->value symbol=? symbol? tan tanh truncate unless unlet vector vector-append vector->list vector-dimensions vector-length vector-ref vector? when with-baffle with-let with-input-from-file with-input-from-string with-output-to-string zero?)) ;; do not include file-exists? or directory? ht)) (deprecated-ops '((global-environment . rootlet) (current-environment . curlet) (make-procedure-with-setter . dilambda) (procedure-with-setter? . dilambda?) (make-random-state . random-state) ;(make-rectangular . complex) (data-format . sample-type) (mus-sound-data-format . mus-sound-sample-type) (mus-data-format-name . mus-sample-type-name) (mus-data-format->string . mus-sample-type->string))) (numeric-ops (let ((h (make-hash-table))) (for-each (lambda (op) (set! (h op) #t)) '(+ * - / sin cos tan asin acos atan sinh cosh tanh asinh acosh atanh log exp expt sqrt make-polar complex imag-part real-part abs magnitude angle max min exact->inexact modulo remainder quotient lcm gcd rationalize inexact->exact random logior lognot logxor logand numerator denominator floor round truncate ceiling ash)) h)) (repeated-args-table (let ((h (make-hash-table))) (for-each (lambda (op) (set! (h op) #t)) '(= / max min < > <= >= - quotient remainder modulo and or string=? string<=? string>=? string? char=? char<=? char>=? char? boolean=? symbol=?)) h)) (repeated-args-table-2 (let ((h (make-hash-table))) (for-each (lambda (op) (set! (h op) #t)) '(= max min < > <= >= and or string=? string<=? string>=? string? char=? char<=? char>=? char? boolean=? symbol=?)) h)) (syntaces (let ((h (make-hash-table))) (for-each (lambda (op) (set! (h op) #t)) '(quote if begin let let* letrec letrec* cond case or and do set! unless when with-let with-baffle lambda lambda* define define* define-macro define-macro* define-bacro define-bacro* define-constant define-expansion)) h)) (format-control-char (let ((chars (make-vector 256 #f))) (for-each (lambda (c) (vector-set! chars (char->integer c) #t)) '(#\A #\S #\C #\F #\E #\G #\O #\D #\B #\X #\, #\{ #\} #\@ #\P #\* #\a #\s #\c #\f #\e #\g #\o #\d #\b #\x #\p #\N #\n #\W #\w #\v #\V #\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9)) chars)) (selector-types '(#t symbol? char? boolean? integer? rational? real? complex? number?)) (outport #t) (loaded-files #f) (globals #f) (*e* (curlet)) (other-identifiers #f) (quote-warnings 0) (last-simplify-boolean-line-number -1) (last-simplify-numeric-line-number -1) (last-checker-line-number -1) (line-number -1)) #| (define var-name (dilambda (lambda (v) (v :name)) (lambda (v x) (set! (v :name) x)))) (define var-ref (dilambda (lambda (v) (v :ref)) (lambda (v x) (set! (v :ref) x)))) (define var-set (dilambda (lambda (v) (v :set)) (lambda (v x) (set! (v :set) x)))) (define var-type (dilambda (lambda (v) (v :type)) (lambda (v x) (set! (v :type) x)))) (define var-value (dilambda (lambda (v) (v :value)) (lambda (v x) (set! (v :value) x)))) (define* (make-var name ref set fnc typ val new) (inlet :var :var :name name :ref ref :set set :fnc fnc :type typ :value val :new new)) (define (var? v) (and (let? v) (eq? (v :var) :var))) ;; but need var-member -- (assoc x y var-name)? ;; var-type is set in make-var in do and the various lets, so new needs closure-type? and set var-type to procedure? or macro? etc ;; define et al could also set the type |# (define var? pair?) (define var-member assq) (define var-name car) (define var-ref cadr) (define var-set caddr) (define (set-cadr! v val) (list-set! v 1 val)) (define (set-caddr! v val) (list-set! v 2 val)) (set! (procedure-setter cadr) set-cadr!) (set! (procedure-setter caddr) set-caddr!) (define var-type (dilambda (lambda (v) (list-ref v 3)) (lambda (v x) (list-set! v 3 x)))) (define var-value (dilambda (lambda (v) (list-ref v 4)) (lambda (v x) (list-set! v 4 x)))) ;; (define make-var (lambda* (name ref set typ val :allow-other-keys) (list name ref set typ val))) ;; this :allow-other-keys is protecting us from bizarre keyword uses in non-s7 code. (define var-new (dilambda (lambda (v) (list-ref v 5)) (lambda (v x) (list-set! v 5 x)))) (define* (make-var name ref set typ val new) ;(if new (format *stderr* "~A: ~A~%~%" name new)) (list name ref set typ val new)) (define (return-type sym) (let ((f (if (symbol? sym) (symbol->value sym *e*) sym))) (and (procedure? f) (let ((sig (procedure-signature f))) (and (pair? sig) (or (eq? (car sig) 'values) ; turn it into #t for now (car sig))))))) ; this might be undefined in the current context (eg oscil? outside clm) (define (->type c) (cond ((pair? c) (if (symbol? (car c)) (return-type (car c)) (or (pair? (car c)) 'pair?))) ((integer? c) 'integer?) ((rational? c) 'rational?) ((real? c) 'real?) ((number? c) 'number?) ((keyword? c) 'keyword?) ((symbol? c) 'symbol?) ((byte-vector? c) 'byte-vector?) ((string? c) 'string?) ((null? c) 'null?) ((char? c) 'char?) ((boolean? c) 'boolean?) ((float-vector? c) 'float-vector?) ((int-vector? c) 'int-vector?) ((vector? c) 'vector?) ((let? c) 'let?) ((hash-table? c) 'hash-table?) ((input-port? c) 'input-port?) ((output-port? c) 'output-port?) ((iterator? c) 'iterator?) ((continuation? c) 'continuation?) ((dilambda? c) 'dilambda?) ((procedure? c) 'procedure?) ((macro? c) 'macro?) ((random-state? c) 'random-state?) ((eof-object? c) 'eof-object?) ((c-pointer? c) 'c-pointer?) (#t #t))) (define bools '(symbol? integer? rational? real? number? complex? float? keyword? gensym? byte-vector? string? list? char? boolean? float-vector? int-vector? vector? let? hash-table? input-port? null? pair? output-port? iterator? continuation? dilambda? procedure? macro? random-state? eof-object? c-pointer?)) (define (compatible? type1 type2) ; we want type1, we have type2 -- is type2 ok? ;(format *stderr* "compatible ~S ~S~%" type1 type2) (or (eq? type1 type2) (not (symbol? type1)) (not (symbol? type2)) (not (memq type1 bools)) (not (memq type2 bools)) (case type1 ((number? complex?) (memq type2 '(float? real? rational? integer? number? complex?))) ((real?) (memq type2 '(float? rational? integer? complex? number?))) ((float?) (memq type2 '(real? complex? number?))) ((rational?) (memq type2 '(integer? real? complex? number?))) ((integer?) (memq type2 '(real? rational? complex? number?))) ((vector?) (memq type2 '(float-vector? int-vector?))) ((float-vector? int-vector?) (eq? type2 'vector?)) ((symbol?) (memq type2 '(gensym? keyword?))) ((keyword? gensym?) (eq? type2 'symbol?)) ((list?) (memq type2 '(null? pair?))) ((pair? null?) (eq? type2 'list?)) ((dilambda?) (memq type2 '(procedure? macro? iterator?))) ((procedure? macro?) (memq type2 '(dilambda? iterator?))) ((iterator?) (memq type2 '(dilambda? procedure?))) ((string?) (eq? type2 'byte-vector?)) ((byte-vector?) (eq? type2 'string?)) (else #f)))) (define (any-compatible? type1 type2) ;; type1 and type2 can be either a list of types or a type (if (symbol? type1) (if (symbol? type2) (compatible? type1 type2) (and (pair? type2) (or (compatible? type1 (car type2)) (any-compatible? type1 (cdr type2))))) (and (pair? type1) (or (compatible? (car type1) type2) (any-compatible? (cdr type1) type2))))) (define (subsumes? type1 type2) (or (eq? type1 type2) (case type1 ((rational?) (eq? type2 'integer?)) ((real?) (memq type2 '(integer? rational? float?))) ((complex? number?) (memq type2 '(integer? rational? float? real? complex? number?))) ((list?) (memq type2 '(pair? null? proper-list?))) ((pair?) (eq? type2 'proper-list?)) ((vector?) (memq type2 '(float-vector? int-vector?))) ((symbol?) (memq type2 '(keyword? gensym?))) (else #f)))) (define (any-checker? types arg) (if (and (symbol? types) (not (eq? types 'values))) ((symbol->value types *e*) arg) (and (pair? types) (or (any-checker? (car types) arg) (any-checker? (cdr types) arg))))) (define (never-false expr) (or (eq? expr #t) (let ((type (if (pair? expr) (and (hash-table-ref no-side-effect-functions (car expr)) (return-type (car expr))) (->type expr)))) (and (symbol? type) (not (symbol? expr)) (not (memq type '(boolean? values))))))) (define (never-true expr) (or (not expr) (and (pair? expr) (eq? (car expr) 'not) (let ((f (never-false (cadr expr)))) ;(format *stderr* "f: ~S~%" f) f)))) ;; -------------------------------------------------------------------------------- (define (truncated-list->string form) ;; return form -> string with limits on its length (let* ((str (object->string form)) (len (length str))) (if (< len 8) (format #f " ~A" str) (if (<= len 80) (format #f "~% ~A" str) (do ((i 77 (- i 1))) ((or (= i 40) (char-whitespace? (str i))) (format #f "~% ~A..." (substring str 0 (if (<= i 40) 77 i))))))))) (define (lists->string f1 f2) ;; same but 2 strings that may need to be lined up vertically (let* ((str1 (object->string f1)) (len1 (length str1)) (str2 (object->string f2)) (len2 (length str2))) (if (< (+ len1 len2) 40) (format #f "~A -> ~A" str1 str2) (if (< (+ len1 len2) 80) (format #f "~% ~A -> ~A" str1 str2) (format #f "~% ~A ->~% ~A" str1 str2))))) (define (lint-format str name . args) (if (and (positive? line-number) (< line-number 100000)) (apply format outport (string-append " ~A (line ~D): " str "~%") name line-number args) (apply format outport (string-append " ~A: " str "~%") name args))) (define (side-effect? form env) ;; could evaluation of form have any side effects (like IO etc) (if (and (proper-list? form) ; we don't want dotted lists or () here (not (null? form))) ;; can't optimize ((...)...) because the car might eval to a function (or (and (not (hash-table-ref no-side-effect-functions (car form))) ; if func is not in that list, make no assumptions about it (or (not (eq? (car form) 'format)) ; (format #f ...) (cadr form))) (case (car form) ((set! define define* define-macro define-macro* define-bacro define-bacro* define-constant define-expansion) #t) ((quote) #f) ((case) (or (not (pair? (cdr form))) (side-effect? (cadr form) env) ; the selector (letrec ((case-effect? (lambda (f e) (and (pair? f) (or (not (pair? (car f))) (any? (lambda (ff) (side-effect? ff e)) (cdar f)) (case-effect? (cdr f) e)))))) (case-effect? (cddr form) env)))) ((cond) (letrec ((cond-effect? (lambda (f e) (and (pair? f) (or (any? (lambda (ff) (side-effect? ff e)) (car f)) (cond-effect? (cdr f) e)))))) (or (not (pair? (cadr form))) (cond-effect? (cdr form) env)))) ((let let* letrec letrec*) (letrec ((let-effect? (lambda (f e) (and (pair? f) (or (not (pair? (car f))) (not (pair? (cdar f))) ; an error, reported elsewhere: (let ((x)) x) (side-effect? (cadar f) e) (let-effect? (cdr f) e)))))) (if (symbol? (cadr form)) (or (let-effect? (caddr form) env) (any? (lambda (ff) (side-effect? ff env)) (cdddr form))) (or (let-effect? (cadr form) env) (any? (lambda (ff) (side-effect? ff env)) (cddr form)))))) ((do) (letrec ((do-effect? (lambda (f e) (and (pair? f) (or (not (pair? (car f))) (not (pair? (cdar f))) (side-effect? (cadar f) e) (and (pair? (cddar f)) (side-effect? (caddar f) e)) (do-effect? (cdr f) e)))))) (or (< (length form) 3) (not (list? (cadr form))) (not (list? (caddr form))) (do-effect? (cadr form) env) (any? (lambda (ff) (side-effect? ff env)) (caddr form)) (any? (lambda (ff) (side-effect? ff env)) (cdddr form))))) ;; ((lambda lambda*) (any? (lambda (ff) (side-effect? ff env)) (cddr form))) ; this is trickier than it looks (else (or (any? (lambda (f) (side-effect? f env)) (cdr form)) ; any subform has a side-effect (let ((sig (procedure-signature (car form)))) ; sig has func arg and it is not known safe (and sig (memq 'procedure? (cdr sig)) (call-with-exit (lambda (return) (for-each (lambda (sg arg) (when (eq? sg 'procedure?) (if (or (not (symbol? arg)) (not (hash-table-ref no-side-effect-functions arg))) (return #t)))) (cdr sig) (cdr form)) #f)))))))) (and (symbol? form) (not (hash-table-ref no-side-effect-functions form)) (let ((e (or (var-member form env) (hash-table-ref globals form)))) (and (var? e) (let? (var-new e))))))) (define (just-constants? form env) ;; can we probably evaluate form given just built-in stuff? (or (and (constant? form) (not (pair? form)) (not (vector? form))) (and (pair? form) (or (and (symbol? (car form)) (hash-table-ref no-side-effect-functions (car form)) (not (hash-table-ref globals (car form))) (not (var-member (car form) env))) ; e.g. exp declared locally as a list (and (constant? (car form)) (not (pair? (car form))) (not (vector? (car form))))) (just-constants? (cdr form) env)))) (define (equal-ignoring-constants? a b) (or (morally-equal? a b) (and (symbol? a) (constant? a) (morally-equal? (symbol->value a) b)) (and (symbol? b) (constant? b) (morally-equal? (symbol->value b) a)) (and (pair? a) (pair? b) (equal-ignoring-constants? (car a) (car b)) (equal-ignoring-constants? (cdr a) (cdr b))))) (define (just-symbols? form) (or (null? form) (symbol? form) (and (pair? form) (symbol? (car form)) (just-symbols? (cdr form))))) (define (list-any? f lst) (if (pair? lst) (or (f (car lst)) (list-any? f (cdr lst))) (f lst))) (define (reversible? func) (memq func '(* + = char=? string=? eq? eqv? equal? morally-equal? logand logxor logior max min lcm gcd < > <= >= char? char<=? char>=? string? string<=? string>=? char-ci? char-ci<=? char-ci>=? string-ci? string-ci<=? string-ci>=?))) (define (reversed func) (case func ((<) '>) ((>) '<) ((<=) '>=) ((>=) '<=) ((* + = char=? string=? eq? eqv? equal? morally-equal? logand logxor logior max min lcm gcd) func) ((char?) ((char>?) 'char=?) ((char>=?) 'char<=?) ((string?) ((string>?) 'string=?) ((string>=?) 'string<=?) ((char-ci?) ((char-ci>?) 'char-ci=?) ((char-ci>=?) 'char-ci<=?) ((string-ci?) ((string-ci>?) 'string-ci=?) ((string-ci>=?) 'string-ci<=?) (else #f))) (define (repeated-member? lst env) (and (pair? lst) (or (and (or (not (pair? (car lst))) (and (not (side-effect? (car lst) env)) (not (eq? (caar lst) 'random)))) (pair? (cdr lst)) (member (car lst) (cdr lst))) (repeated-member? (cdr lst) env)))) (define (check-args name head form checkers env max-arity) ;; check for obvious argument type problems ;; name = overall caller, head = current caller, checkers = proc or list of procs for checking args (define (prettify-arg-number argn) (if (or (not (= argn 1)) (pair? (cddr form))) (format #f "~D " argn) "")) (define (check-checker checker at-end) (if (eq? checker 'integer:real?) (if at-end 'real? 'integer?) (if (eq? checker 'integer:any?) (or at-end 'integer?) checker))) (let ((arg-number 1)) (call-with-exit (lambda (done) (for-each (lambda (arg) (let ((checker (check-checker (if (list? checkers) (car checkers) checkers) (= arg-number (length (cdr form)))))) ;(format *stderr* "check-arg ~A check ~S via ~S~%" head arg checker) (when (or (pair? checker) (symbol? checker)) ; otherwise ignore type check on this argument (#t -> anything goes) (if (pair? arg) ; arg is expr -- try to guess its type (if (eq? (car arg) 'quote) ; '1 -> 1 ;; arg is quoted expression (if (not (any-compatible? checker (if (pair? (cadr arg)) 'list? (->type (cadr arg))))) (lint-format "~A's argument ~Ashould be a~A ~A: ~S: ~A" name head (prettify-arg-number arg-number) (if (char=? (string-ref (format #f "~A" checker) 0) #\i) "n" "") checker arg (truncated-list->string form))) ;; arg is an evaluated expression (let ((op (return-type (car arg)))) ;; checker is arg-type, op is expression type (can also be a pair) (unless (memq op '(#t #f values)) (if (or (not (any-compatible? checker op)) (and (just-constants? arg env) ; try to eval the arg (catch #t (lambda () (not (any-checker? checker (eval arg)))) (lambda ignore-catch-error-args #f)))) (lint-format "~A's argument ~Ashould be a~A ~A: ~S: ~A" name head (prettify-arg-number arg-number) (if (char=? (string-ref (format #f "~A" checker) 0) #\i) "n" "") checker arg (truncated-list->string form)))))) ;; arg is not a pair (if (and (not (symbol? arg)) (not (any-checker? checker arg))) (lint-format "~A's argument ~Ashould be a~A ~A: ~S: ~A" name head (prettify-arg-number arg-number) (if (char=? (string-ref (format #f "~A" checker) 0) #\i) "n" "") checker arg (truncated-list->string form))))) (if (list? checkers) (if (null? (cdr checkers)) (done) (set! checkers (cdr checkers)))) (set! arg-number (+ arg-number 1)) (if (> arg-number max-arity) (done)))) (cdr form)))))) (define (set-ref? name env) ;; if name is in env, set its "I've been referenced" flag (let ((data (or (var-member name env) (hash-table-ref globals name)))) (when (var? data) (set! (var-ref data) #t))) env) (define (set-set? name new-val env) ;; TODO: if (set! func val) need to either clear func info or fix it up (let ((data (or (var-member name env) (hash-table-ref globals name)))) (when (var? data) (set! (var-value data) new-val) (set! (var-new data) #f) ; a stopgap (set! (var-set data) #t)))) (define (proper-list lst) ;; return lst as a proper list (if (pair? lst) (cons (car lst) (if (pair? (cdr lst)) (proper-list (cdr lst)) (if (null? (cdr lst)) () (list (cdr lst))))) lst)) (define (keywords lst) (let ((count 0)) (do ((p lst (cdr p))) ((null? p) count) (if (keyword? (car p)) (set! count (+ count 1)))))) ;(count-if keyword? lst)) (define (check-star-parameters name args) (if (list-any? (lambda (k) (memq k '(:key :optional))) args) (lint-format ":optional and key are no longer accepted: ~A" name args)) (let ((r (memq :rest args))) (if (and (pair? r) (null? (cdr r))) (lint-format ":rest parameter needs a name: ~A" name args))) (let ((a (memq :allow-other-keys args))) (if (and (pair? a) (pair? (cdr a))) (lint-format ":allow-other-keys should be at the end of the parameter list: ~A" name args)))) (define (tree-member sym tree) (and (pair? tree) (or (eq? (car tree) sym) (and (pair? (car tree)) (tree-member sym (car tree))) (tree-member sym (cdr tree))))) (define (tree-car-member sym tree) (and (pair? tree) (or (eq? (car tree) sym) (and (pair? (car tree)) (tree-car-member sym (car tree))) (and (pair? (cdr tree)) (member sym (cdr tree) tree-car-member))))) (define (remove item sequence) (let ((got-it #f)) (map (lambda (x) (if (and (not got-it) (equal? x item)) (begin (set! got-it #t) (values)) x)) sequence))) (define (remove-all item sequence) (map (lambda (x) (if (equal? x item) (values) x)) sequence)) (define (remove-if p l) (cond ((null? l) ()) ((p (car l)) (remove-if p (cdr l))) (else (cons (car l) (remove-if p (cdr l)))))) (define (checked-eval form) (catch #t (lambda () (eval (copy-tree form))) (lambda args #t))) ; just ignore errors in this context (define (return-type-ok? type ret) (or (eq? type ret) (and (pair? ret) (memq type ret)))) (define (simplify-boolean in-form true false env) ;; (or)->#f, (or x) -> x, (or x ... from here on we know x is #f), (or x #t...) -> (or x #t), any constant expr can be collapsed ;; (or ... (or ...) ...) -> or of all, (or ... #f ...) toss the #f ;; similarly for and ;; (or ... (not (and ...))) -> (or ... (not x) [from here we know x is true] (not y)...) ;; (or ... (not (and x1 x2 ...))) -> (or ... (not x1) (not x2)...), but is that simpler? ;; (or x1 x2 x1) -> (or x1 x2) ;; (and x1 x2 x1) -> (and x2 x1) (define (bsimp uform) ;; find and remove any expressions that have no effect on the outcome (if (or (not (pair? uform)) (not (memq (car uform) '(and or not))) (side-effect? uform env)) uform (let ((vars ()) (associated-exprs ()) (ctr 0)) (define (tree-remove-all x lst) (cond ((null? lst) ()) ((equal? (car lst) x) (tree-remove-all x (cdr lst))) ((pair? (car lst)) (cons (tree-remove-all x (car lst)) (tree-remove-all x (cdr lst)))) (else (cons (car lst) (tree-remove-all x (cdr lst)))))) (define (canonical-tree lst) (let ((data (assoc lst associated-exprs))) (if data (cdr data) (if (pair? lst) (cons (canonical-tree (car lst)) (canonical-tree (cdr lst))) lst)))) (define (expand expr) (define (car-rassoc val lst) (and (pair? lst) (if (equal? (cdar lst) val) (car lst) (car-rassoc val (cdr lst))))) (let ((data (car-rassoc expr associated-exprs))) (if data (copy (car data)) (if (pair? expr) (cons (expand (car expr)) (expand (cdr expr))) expr)))) (define (bool-walk form func) (if (and (pair? form) (memq (car form) '(and or not))) (for-each (lambda (e) (bool-walk e func)) (cdr form)) (func form))) (bool-walk uform (lambda (val) (if (and (or (pair? val) (symbol? val)) (not (assoc val associated-exprs)) (not (memq val '(and or not)))) ; (not not) (let ((new-var (string->symbol (format #f "bool-~D" ctr)))) (set! vars (cons new-var vars)) (set! associated-exprs (cons (cons val new-var) associated-exprs)) (set! ctr (+ ctr 1)))))) (if (or (null? vars) (> (length vars) 8)) uform (let ((len (length vars))) (let ((vsize (expt 2 len))) ; 2^n possible cases (let ((v (make-vector vsize)) (vals ()) (nonf (make-vector len)) (cur 0) (ctr 0) (form (canonical-tree uform))) ;; (and (real? mag) (real? ang)) -> (and bool-0 bool-1) ;; (not off) -> (not bool-0) ;; (or din (sqrt 2.0)) -> (or bool-0 bool-1) (for-each (lambda (var) (do ((i cur (+ i 1))) ((not (tree-member i form)) ; tree-member uses eq? (should use = for this?) (set! cur (+ i 1)) (vector-set! nonf ctr i) (set! ctr (+ ctr 1))))) vars) (catch #t (lambda () (let ((new-func (apply lambda vars form ()))) (do ((ctr 0 (+ ctr 1))) ((= ctr vsize)) (vector-set! v ctr (apply new-func (let ((args ())) (do ((i 0 (+ i 1))) ((= i len) (reverse args)) (set! args (cons (and (logbit? ctr i) (vector-ref nonf i)) args)))))) (if (not (member (vector-ref v ctr) vals)) (set! vals (cons (vector-ref v ctr) vals)))))) (lambda args 'error)) (if (= (length vals) 1) (car vals) (let ((none-vars ()) (pos -1)) (for-each (lambda (var) (set! pos (+ pos 1)) (call-with-exit (lambda (return) (do ((ctr 0 (+ ctr 1))) ((= ctr vsize) (set! none-vars (cons var none-vars))) (if (and (not (logbit? ctr pos)) (not (equal? (vector-ref v ctr) (vector-ref v (logior ctr (ash 1 pos)))))) (return #f)))))) vars) (if (pair? none-vars) (begin (for-each (lambda (nv) (set! form (tree-remove-all nv form))) none-vars) (expand form)) uform)))))))))) (define (true? e) (or (member e true) (and (pair? e) (= (length e) 2) (or (member e true (lambda (a b) ;; if a follows b, and b is true, do we know already know that a? ;; (and (< x1 12) (real? x1) (= x1 1)) -> (and (< x1 12) (= x1 1)) (and (pair? b) (or (and (= (length b) 2) (equal? (cadr a) (cadr b)) (case (car a) ((complex?) (memq (car b) '(number? real? rational? integer? even? odd? positive? negative? zero? exact? inexact?))) ((number?) (memq (car b) '(complex? real? rational? integer? even? odd? positive? negative? zero? exact? inexact?))) ((real?) (memq (car b) '(rational? integer? even? odd? positive? negative? exact? inexact?))) ((rational?) (memq (car b) '(integer? even? odd?))) ((integer?) (memq (car b) '(even? odd?))) (else #f))) (and (> (length b) 2) (member (cadr a) (cdr b)) (case (car a) ((complex? number?) (eq? (car b) '=)) ((real?) (memq (car b) '(< > <= >=))) (else #f))))))) (and (pair? (cadr e)) (memq (car e) bools) (memq (return-type (caadr e)) bools) (subsumes? (car e) (return-type (caadr e)))))))) (define (false? e) (define (bad-arg-match a b) ;; these accept only the given type and can return a boolean (so their value in a boolean expression is not known in advance) (define (number-op? x) (memq x '(= < > <= >= even? odd? positive? negative? zero?))) (define (char-op? x) (memq x '(char=? char? char>=? char-ci=? char-ci? char-ci>=? char-alphabetic? char-numeric? char-whitespace? char-lower-case? char-upper-case?))) (define (list-op? x) (memq x '(caaaar caaadr caaar caadar caaddr caadr caar cadaar cadadr cadar caddar cadddr caddr cadr car cdaaar cdaadr cdaar cdadar cdaddr cdadr cdar cddaar cddadr cddar cdddar cddddr cdddr cddr cdr list-ref))) (define (string-op? x) (memq x '(string=? string? string>=? string-ci=? string-ci? string-ci>=?))) (case a ((complex? number? real? rational? integer?) (or (char-op? b) ; that is, if these are false, then a non-number was accepted (list-op? b) ; earlier as a valid argument, so it can't be a number (string-op? b))) ; (or (char=? x1 #\a) (complex? x1) x1) -> (or (char=? x1 #\a) x1) ((char?) (or (number-op? b) (list-op? b) (string-op? b))) ((string?) (or (char-op? b) (list-op? b) (number-op? b))) ((list?) (or (char-op? b) (number-op? b) (string-op? b))) ((boolean? procedure? symbol? continuation? let?) (or (char-op? b) (number-op? b) (list-op? b) (string-op? b))) (else #f))) (or (member e false) (and (pair? e) (= (length e) 2) (or (member e false (lambda (a b) (and (pair? b) (>= (length b) 2) (member (cadr a) (cdr b)) (bad-arg-match (car a) (car b))))) (member e true (lambda (a b) (and (pair? b) (>= (length b) 2) (member (cadr a) (cdr b)) (bad-arg-match (car a) (car b))))) (and (pair? (cadr e)) (memq (car e) bools) (memq (return-type (caadr e)) bools) (not (any-compatible? (car e) (return-type (caadr e))))))))) (define (contradictory? ands) (let ((vars ())) (call-with-exit (lambda (return) (do ((b ands (cdr b))) ((null? b) #f) (if (and (pair? b) (pair? (car b)) (pair? (cdar b))) (let* ((func (caar b)) (arg-type func) (args (cdar b))) (if (symbol? arg-type) (for-each (lambda (arg) (if (symbol? arg) (let ((type (assq arg vars))) (if (not type) (set! vars (cons (cons arg arg-type) vars)) (if (not (compatible? (cdr type) arg-type)) (return #t)))))) args))))))))) (define (and-redundant? type1 type2) (if (or (not (symbol? type1)) (not (symbol? type2)) (not (memq type1 bools)) (not (memq type2 bools))) #f ; return #f if not (obviously) redundant, else return which of the two to keep (if (eq? type1 type2) type1 (case type1 ((number? complex?) (or (and (memq type2 '(float? real? rational? integer?)) type2) (and (memq type2 '(number? complex?)) type1))) ((real?) (or (and (memq type2 '(float? rational? integer?)) type2) (and (memq type2 '(number? complex?)) type1))) ((float?) (and (memq type2 '(real? complex? number?)) type1)) ((rational?) (or (and (eq? type2 'integer?) type2) (and (memq type2 '(real? complex? number?)) type1))) ((integer?) (and (memq type2 '(real? rational? complex? number?)) type1)) ((vector?) (and (memq type2 '(float-vector? int-vector?)) type2)) ((float-vector? int-vector?) (and (eq? type2 'vector?) type1)) ((symbol?) (and (memq type2 '(keyword? gensym?)) type2)) ((keyword? gensym?) (and (eq? type2 'symbol?) type1)) ((list?) (and (memq type2 '(null? pair?)) type2)) ((pair? null?) (and (eq? type2 'list?) type1)) ((string?) (and (eq? type2 'byte-vector?) type2)) ((byte-vector?) (and (eq? type2 'string?) type1)) (else #f))))) (define (classify e) ;; do we already know that e is true or false? ;; some cases subsume others: if we know (integer? x) is true, (complex? x) is also true (if (true? e) #t ; the simple boolean is passed back which will either be dropped or will stop the outer expr build (if (false? e) #f ;; eval of a constant expression here is tricky -- for example, (sqrt 2) should not be turned into 1.414... (if (just-constants? e env) (catch #t (lambda () (let ((val (eval e))) (if (boolean? val) val e))) (lambda ignore e)) e)))) (define (store e value and/or) ;; we can't make any assumptions about the expression if it might have side effects ;; for example (or (= (oscil o) 0.0) (= (oscil o) 0.0)) can't be reduced (if (or (not (pair? e)) (not (side-effect? e env))) (let ((its-true (if (eq? and/or 'or) (eq? value #t) ; or, so it's false if unknown value))) (if its-true (set! true (cons e true)) (set! false (cons e false)))))) (let ((form (bsimp in-form))) ;(format *stderr* "form: ~S~%" form) (if (or (not (pair? form)) (not (memq (car form) '(or and not)))) (classify form) (let ((len (length form))) (case (car form) ((not) (if (= len 2) (let* ((arg (cadr form)) (val (if (and (pair? arg) (memq (car arg) '(and or not))) (classify (simplify-boolean arg true false env)) (classify arg)))) ;(format *stderr* "val ~S, arg: ~S~%" val arg) (if (boolean? val) (not val) (if (or (code-constant? arg) (and (pair? arg) (symbol? (car arg)) (hash-table-ref no-side-effect-functions (car arg)) (not (hash-table-ref globals (car arg))) (let ((ret (return-type (car arg)))) (and (or (symbol? ret) (pair? ret)) (not (return-type-ok? 'boolean? ret)))) (not (var-member (car arg) env)))) #f (if (and (pair? arg) ; (not (not ...)) -> ... (pair? (cdr arg)) (eq? (car arg) 'not)) (cadr arg) (if (not (equal? val arg)) `(not ,val) (if (and (pair? arg) (<= (length arg) 3)) ; avoid (<= 0 i 12) and such (case (car arg) ((<) `(>= ,@(cdr arg))) ; (not (< ...)) -> (>= ...) ((>) `(<= ,@(cdr arg))) ((<=) (if (morally-equal? (caddr arg) 0.0) `(positive? ,(cadr arg)) `(> ,@(cdr arg)))) ((>=) (if (morally-equal? (caddr arg) 0.0) `(negative? ,(cadr arg)) `(< ,@(cdr arg)))) ((char=? ,@(cdr arg))) ((char>?) `(char<=? ,@(cdr arg))) ((char<=?) `(char>? ,@(cdr arg))) ((char>=?) `(char=? ,@(cdr arg))) ((char-ci>?) `(char-ci<=? ,@(cdr arg))) ((char-ci<=?) `(char-ci>? ,@(cdr arg))) ((char-ci>=?) `(char-ci=? ,@(cdr arg))) ((string>?) `(string<=? ,@(cdr arg))) ((string<=?) `(string>? ,@(cdr arg))) ((string>=?) `(string=? ,@(cdr arg))) ((string-ci>?) `(string-ci<=? ,@(cdr arg))) ((string-ci<=?) `(string-ci>? ,@(cdr arg))) ((string-ci>=?) `(string-ci any? and so on ((zero?) ; (not (zero? (logand p (ash 1 i)))) -> (logbit? p i) (let ((zarg (cadr arg))) ; (logand...) (if (and (pair? zarg) (eq? (car zarg) 'logand) (pair? (cddr zarg)) (pair? (caddr zarg)) (eq? (caaddr zarg) 'ash) (eqv? (cadr (caddr zarg)) 1)) `(logbit? ,(cadr zarg) ,(caddr (caddr zarg))) form))) (else form)) form)))))) form)) ((or) (and (> len 1) (let ((arg1 (cadr form))) (if (= len 2) (if (code-constant? arg1) arg1 (classify arg1)) (if (true? arg1) ; no need to check anything else #t ; side-effect? here is a nightmare (let* ((arg2 (caddr form)) (t1 (and (= len 3) (pair? arg1) (pair? arg2) (pair? (cdr arg1)) (pair? (cdr arg2)) (equal? (cadr arg1) (cadr arg2)) (not (side-effect? arg1 env)) (and-redundant? (car arg1) (car arg2))))) (if t1 (if (eq? t1 (car arg1)) arg2 arg1) (let ((sf #f)) (if (and (every? (lambda (p) (and (pair? p) (pair? (cdr p)) (eq? (car p) 'not))) (cdr form)) (let () (set! sf (simplify-boolean `(not (and ,@(map cadr (cdr form)))) true false env)) (or (not (pair? sf)) (not (eq? (car sf) 'not)) (not (pair? (cadr sf))) (not (eq? (caadr sf) 'and))))) sf ;; if all clauses are (eq-func x y) where one of x/y is a symbol|simple-expr repeated throughout ;; and the y is a code-constant, or -> memq and friends. This could also handle cadr|caddr reversed. ;; (or (pair? x) (null? x)) -> (list? x) (let ((sym #f) (eqf #f)) (if (every? (lambda (p) (and (pair? p) (if (not eqf) (and (memq (car p) '(eq? eqv? equal? char=? string=? = char-ci=? string-ci=?)) (set! eqf (car p))) (eq? eqf (car p))) (if (not sym) (and (not (side-effect? (cadr p) env)) (set! sym (cadr p))) (equal? sym (cadr p))) (code-constant? (caddr p)))) (cdr form)) (let* ((vals (map caddr (cdr form))) (func (case eqf ((eq?) 'memq) ((eqv? char=?) 'memv) ((=) (if (every? rational? vals) 'memv 'member)) (else 'member))) (equals (if (and (eq? func 'member) (not (eq? eqf 'equal?))) (list eqf) ())) (elements (map (lambda (v) (if (pair? v) (cadr v) v)) vals))) (if (and (eq? eqf 'char=?) (= (length elements) 2) (char-ci=? (car elements) (cadr elements))) `(char-ci=? ,sym ,(car elements)) (if (and (eq? eqf 'string=?) (= (length elements) 2) (string-ci=? (car elements) (cadr elements))) `(string-ci=? ,sym ,(car elements)) `(,func ,sym ',(map (lambda (v) (if (pair? v) (cadr v) v)) vals) ,@equals)))) (let ((new-form ())) (do ((exprs (cdr form) (cdr exprs))) ((null? exprs) (if (null? new-form) #f (if (null? (cdr new-form)) (car new-form) `(or ,@(reverse new-form))))) (let* ((e (car exprs)) (val (classify e))) (if (and (pair? val) (memq (car val) '(and or not))) (set! val (classify (set! e (simplify-boolean e true false env))))) (if val ; #f in or is ignored (if (or (eq? val #t) ; #t or any non-#f constant in or ends the expression (code-constant? val)) (begin (if (null? new-form) ; (or x1 123) -> value of x1 first (set! new-form (list val)) ;was `(,val)) (set! new-form (cons val new-form))) ;was (append `(,val) new-form))) ; reversed when returned (set! exprs '(#t))) ;; (or x1 x2 x1) -> (or x1 x2) is ok because if we get to x2, x1 is #f, so trailing x1 would still be #f (if (and (pair? e) ; (or ...) -> splice into current (eq? (car e) 'or)) (set! exprs (append e (cdr exprs))) ; we'll skip the 'or in do step (begin ; else add it to our new expression with value #f (store e val 'or) (if (not (memq val new-form)) (set! new-form (cons val new-form))))))))))))))))))))) ((and) (or (= len 1) (let ((arg1 (cadr form))) (if (= len 2) (classify arg1) (and (not (contradictory? (cdr form))) (let* ((arg2 (caddr form)) (t1 (and (= len 3) (pair? arg1) (pair? arg2) (pair? (cdr arg1)) (pair? (cdr arg2)) (equal? (cadr arg1) (cadr arg2)) (not (side-effect? arg1 env)) (and-redundant? (car arg1) (car arg2))))) ; (and (integer? x) (number? x)) -> (integer? x) (if t1 (if (eq? t1 (car arg1)) arg1 arg2) (let ((new-form ())) (if (and (= len 3) (not (side-effect? arg1 env)) (equal? arg1 arg2)) ; (and x x) -> x arg1 ;; (and (= ...)...) for more than 2 args? ;; (and (< x y z) (< z w)) -> (< x y z w) ? ;; (and (< x y) (< y z) (< z w)) -> (< x y z w) (if (and (= len 3) (pair? arg1) (pair? arg2) (reversible? (car arg1)) (null? (cdddr arg1)) (pair? (cdr arg2)) (pair? (cddr arg2)) (null? (cdddr arg2)) (not (side-effect? arg2 env)) ; arg1 is hit in any case (or (eq? (car arg1) (car arg2)) (let ((rf (reversed (car arg2)))) (and (eq? (car arg1) rf) (set! arg2 (append (list rf) (reverse (cdr arg2))))))) (or (eq? (caddr arg1) (cadr arg2)) (eq? (cadr arg1) (caddr arg2)) (and (memq (car arg1) '(= char=? string=? char-ci=? string-ci=?)) (or (eq? (cadr arg1) (cadr arg2)) (eq? (caddr arg1) (caddr arg2)))))) (if (eq? (caddr arg1) (cadr arg2)) `(,(car arg1) ,(cadr arg1) ,(cadr arg2) ,(caddr arg2)) (if (eq? (cadr arg1) (caddr arg2)) `(,(car arg1) ,(cadr arg2) ,(cadr arg1) ,(caddr arg1)) (if (eq? (cadr arg1) (cadr arg2)) `(,(car arg1) ,(cadr arg1) ,(caddr arg1) ,(caddr arg2)) `(,(car arg1) ,(cadr arg1) ,(caddr arg1) ,(cadr arg2))))) (do ((exprs (cdr form) (cdr exprs))) ((null? exprs) (if (null? new-form) #t ; (and) -> #t (let* ((nform (reverse new-form)) (newer-form (map (lambda (x cdr-x) (if (and x (code-constant? x)) (values) x)) nform (cdr nform)))) (if (null? newer-form) (car new-form) `(and ,@newer-form ,(car new-form)))))) (let* ((e (car exprs)) (val (classify e))) (if (and (pair? val) (memq (car val) '(and or not))) (set! val (classify (set! e (simplify-boolean e () false env))))) ;; (and x1 x2 x1) is not reducible ;; the final thing has to remain at the end, but can be deleted earlier if it can't short-circuit the evaluation, ;; but if there are expressions following the first x1, we can't be sure that it is not ;; protecting them: ;; (and false-or-0 (display (list-ref lst false-or-0)) false-or-0) ;; so I'll not try to optimize that case. But (and x x) is optimizable. (if (eq? val #t) (if (null? (cdr exprs)) ; (and x y #t) should not remove the #t (if (or (and (pair? e) (eq? (return-type (car e)) 'boolean?)) (eq? e #t)) (set! new-form (cons val new-form)) (if (or (null? new-form) (not (equal? e (car new-form)))) (set! new-form (cons e new-form)))) (if (and (not (eq? e #t)) (or (null? new-form) (not (member e new-form)))) (set! new-form (cons e new-form)))) (if (not val) ; #f in 'and' ends the expression (begin (if (or (null? new-form) (just-symbols? new-form)) (set! new-form '(#f)) (set! new-form (cons #f new-form))) ;was (append '(#f) new-form))) (set! exprs '(#f))) (if (and (pair? e) ; if (and ...) splice into current (eq? (car e) 'and)) (set! exprs (append e (cdr exprs))) (if (not (and (pair? e) ; (and ... (or ... 123) ...) -> splice out or (pair? (cdr exprs)) (eq? (car e) 'or) (> (length e) 2) (let ((last (list-ref e (- (length e) 1)))) (and last ; (or ... #f) (code-constant? last))))) (begin ; else add it to our new expression with value #t (store e val 'and) (if (or (not (pair? new-form)) (not (eq? val (car new-form)))) (set! new-form (cons val new-form))))))))))))))))))))))))) (define (splice-if f lst) (cond ((null? lst) ()) ((pair? lst) (if (and (pair? (car lst)) (f (caar lst))) (append (splice-if f (cdar lst)) (splice-if f (cdr lst))) (cons (car lst) (splice-if f (cdr lst))))) (#t lst))) (define (simplify-numerics form env) ;; this returns a form, possibly the original simplified (let ((real-result? (lambda (op) (memq op '(imag-part real-part abs magnitude angle max min exact->inexact modulo remainder quotient lcm gcd)))) (rational-result? (lambda (op) (memq op '(rationalize inexact->exact)))) (integer-result? (lambda (op) (memq op '(logior lognot logxor logand numerator denominator floor round truncate ceiling ash))))) (define (inverse-op op) (case op ((sin) 'asin) ((cos) 'acos) ((tan) 'atan) ((asin) 'sin) ((acos) 'cos) ((atan) 'tan) ((sinh) 'asinh) ((cosh) 'acosh) ((tanh) 'atanh) ((asinh) 'sinh) ((acosh) 'cosh) ((atanh) 'tanh) ((log) exp) ((exp) log))) (define (remove-duplicates lst) (letrec ((rem-dup (lambda (lst nlst) (cond ((null? lst) nlst) ((and (member (car lst) nlst) (or (not (pair? (car lst))) (not (eq? (caar lst) 'random)))) ; this problem applies to anything that calls random, mus-random etc (rem-dup (cdr lst) nlst)) (else (rem-dup (cdr lst) (cons (car lst) nlst))))))) (reverse (rem-dup lst ())))) (define (just-rationals? form) (or (null? form) (rational? form) (and (pair? form) (rational? (car form)) (just-rationals? (cdr form))))) (define (just-reals? form) (or (null? form) (real? form) (and (pair? form) (real? (car form)) (just-reals? (cdr form))))) (define (just-integers? form) (or (null? form) (integer? form) (and (pair? form) (integer? (car form)) (just-integers? (cdr form))))) (define (simplify-arg x) (if (or (not (pair? x)) ; constants and the like look dumb if simplified (hash-table-ref globals (car x)) (not (hash-table-ref no-side-effect-functions (car x))) (var-member (car x) env)) x (let ((f (simplify-numerics x env))) (if (and (pair? f) (just-rationals? f)) (catch #t (lambda () (eval f)) (lambda ignore f)) f)))) (let* ((args (map simplify-arg (cdr form))) (len (length args))) (case (car form) ((+) (case len ((0) 0) ((1) (car args)) (else (let ((val (remove-all 0 (splice-if (lambda (x) (eq? x '+)) args)))) (if (every? (lambda (x) (or (not (number? x)) (rational? x))) val) (let ((rats (collect-if list rational? val))) (if (> (length rats) 1) (let ((y (apply + rats))) (if (zero? y) (set! val (collect-if list (lambda (x) (not (number? x))) val)) (set! val (cons y (collect-if list (lambda (x) (not (number? x))) val)))))))) (case (length val) ((0) 0) ((1) (car val)) ; (+ x) -> x (else `(+ ,@val))))))) ; other obvious simplifications never happen ((*) (case len ((0) 1) ((1) (car args)) (else (let ((val (remove-all 1 (splice-if (lambda (x) (eq? x '*)) args)))) (if (every? (lambda (x) (or (not (number? x)) (rational? x))) val) (let ((rats (collect-if list rational? val))) (if (> (length rats) 1) (let ((y (apply * rats))) (if (= y 1) (set! val (collect-if list (lambda (x) (not (number? x))) val)) (set! val (cons y (collect-if list (lambda (x) (not (number? x))) val)))))))) (case (length val) ((0) 1) ((1) (car val)) ; (* x) -> x (else (if (just-rationals? val) (apply * val) (if (memv 0 val) ; (* x 0 2) -> 0 0 (if (= (length val) 2) (if (memv -1 val) `(- ,@(remove -1 val)) ; (* -1 x) -> (- x) (if (and (pair? (car val)) (pair? (cadr val)) (= (length (car val)) 3) (equal? (cdar val) (cdadr val)) (or (and (eq? (caar val) 'gcd) (eq? (caadr val) 'lcm)) (and (eq? (caar val) 'lcm) (eq? (caadr val) 'gcd)))) `(abs (* ,@(cdar val))) ; (* (gcd a b) (lcm a b)) -> (abs (* a b)) but only if 2 args? `(* ,@val))) `(* ,@val)))))))))) ((-) (case len ((0) form) ((1) ; negate (if (number? (car args)) (- (car args)) (if (not (list? (car args))) `(- ,@args) (case (length (car args)) ((2) (if (eq? (caar args) '-) (cadar args) ; (- (- x)) -> x `(- ,@args))) ((3) (if (eq? (caar args) '-) `(- ,(caddar args) ,(cadar args)) ; (- (- x y)) -> (- y x) `(- ,@args))) (else `(- ,@args)))))) ((2) (if (just-rationals? args) (apply - args) (if (eqv? (car args) 0) `(- ,(cadr args)) ; (- 0 x) -> (- x) (if (eqv? (cadr args) 0) (car args) ; (- x 0) -> x (if (equal? (car args) (cadr args)) 0 ; (- x x) (if (and (pair? (car args)) (eq? (caar args) '-) (> (length (car args)) 2)) `(- ,@(cdar args) ,(cadr args)) ; (- (- x y) z) -> (- x y z) but leave (- (- x) ...) `(- ,@args))))))) (else (let ((val (remove-all 0 (splice-if (lambda (x) (eq? x '+)) (cdr args))))) (if (every? (lambda (x) (or (not (number? x)) (rational? x))) val) (let ((rats (collect-if list rational? val))) (if (> (length rats) 1) (let ((y (apply + rats))) (if (zero? y) (set! val (collect-if list (lambda (x) (not (number? x))) val)) (set! val (cons y (collect-if list (lambda (x) (not (number? x))) val)))))))) (set! val (cons (car args) val)) (let ((first-arg (car args)) (nargs (cdr val))) (if (member first-arg nargs) (begin (set! nargs (remove first-arg nargs)) ; remove once (set! first-arg 0))) (if (null? nargs) first-arg ; (- x 0 0 0)? (if (and (eqv? first-arg 0) (= (length nargs) 1)) (if (number? (car nargs)) (- (car nargs)) `(- ,(car nargs))) ; (- 0 0 0 x)? `(- ,@(cons first-arg nargs))))))))) ((/) (case len ((0) form) ((1) ; invert (if (number? (car args)) (if (zero? (car args)) `(/ ,(car args)) (/ (car args))) (if (pair? (car args)) (if (and (= (length (car args)) 2) (eq? (caar args) '/)) (cadar args) `(/ ,@args)) `(/ ,@args)))) ((2) (if (and (just-rationals? args) (not (zero? (cadr args)))) (apply / args) ; including (/ 0 12) -> 0 (let ((arg1 (car args)) (arg2 (cadr args))) (if (eqv? arg1 1) ; (/ 1 x) -> (/ x) `(/ ,arg2) (if (eqv? arg2 1) arg1 ; (/ x 1) -> x (if (and (pair? arg1) ; (/ (log x) (log y)) -> (log x y) (= (length arg1) 2) (pair? arg2) (= (length arg2) 2) (eq? (car arg1) 'log) (eq? (car arg2) 'log)) `(log ,(cadr arg1) ,(cadr arg2)) (if (and (pair? arg1) (eq? (car arg1) '/) (pair? arg2) (eq? '/ (car arg2))) (let ((a1 (if (null? (cddr arg1)) `(/ 1 ,(cadr arg1)) arg1)) (a2 (if (null? (cddr arg2)) `(/ 1 ,(cadr arg2)) arg2))) (simplify-numerics `(/ (* ,(cadr a1) ,@(cddr a2)) (* ,@(cddr a1) ,(cadr a2))) env)) `(/ ,@args)))))))) (else (if (and (just-rationals? args) (not (memv 0 (cdr args))) (not (memv 0.0 (cdr args)))) (apply / args) (let ((nargs ; (/ x a (* b 1 c) d) -> (/ x a b c d) but not short cases (remove-all 1 (splice-if (lambda (x) (eq? x '*)) (cdr args))))) (if (null? nargs) ; (/ x 1 1) -> x (car args) `(/ ,@(cons (car args) nargs)))))))) ((sin cos asin acos sinh cosh tanh asinh acosh atanh exp) (if (= len 1) (if (and (pair? (car args)) (= (length (car args)) 2) (eq? (caar args) (inverse-op (car form)))) (cadar args) (if (eqv? (car args) 0) (case (car form) ((sin asin sinh asinh tanh atanh) 0) ((exp cos cosh) 1) (else `(,(car form) ,@args))) (if (and (eq? (car form) 'cos) (pair? (car args)) (eq? (caar args) '-) (null? (cddar args))) `(cos ,(cadar args)) (if (eq? (car args) 'pi) (case (car form) ((sin) 0.0) ((cos) 1.0) (else `(,(car form) ,@args))) (if (eqv? (car args) 0.0) (apply (symbol->value (car form)) '(0.0)) (if (and (eq? (car form) 'exp) ; (exp (* a (log b))) -> (expt b a) (pair? (car args)) (eq? (caar args) '*)) (let ((targ (cdar args))) (if (= (length targ) 2) (if (and (pair? (car targ)) (eq? (caar targ) 'log) (pair? (cdar targ)) (null? (cddar targ))) `(expt ,(cadar targ) ,(cadr targ)) (if (and (pair? (cadr targ)) (eq? (caadr targ) 'log) (pair? (cdadr targ)) (null? (cddadr targ))) `(expt ,(cadadr targ) ,(car targ)) `(,(car form) ,@args))) `(,(car form) ,@args))) `(,(car form) ,@args))))))) `(,(car form) ,@args))) ((log) (if (pair? args) (if (eqv? (car args) 1) 0 (if (and (= len 1) (pair? (car args)) (= (length (car args)) 2) (eq? (caar args) 'exp)) (cadar args) (if (and (= len 2) (equal? (car args) (cadr args))) (if (integer? (car args)) 1 1.0) `(log ,@args)))) form)) ((sqrt) (if (pair? args) (if (and (rational? (car args)) (= (car args) (* (sqrt (car args)) (sqrt (car args))))) (sqrt (car args)) ; don't collapse (sqrt (* a a)), a=-1 for example `(sqrt ,@args)) form)) ((floor round ceiling truncate) (if (= len 1) (if (number? (car args)) (catch #t (lambda () (apply (symbol->value (car form)) args)) (lambda any `(,(car form) ,@args))) (if (and (pair? (car args)) (integer-result? (caar args))) (car args) `(,(car form) ,@args))) form)) ((abs magnitude) (if (= len 1) (if (and (pair? (car args)) (memq (caar args) '(abs magnitude denominator))) (car args) (if (rational? (car args)) (abs (car args)) (if (and (pair? (car args)) ; (abs (modulo x 2)) -> (modulo x 2) (eq? (caar args) 'modulo) (= (length (car args)) 3) (number? (caddar args)) (positive? (caddar args))) (car args) (if (and (pair? (car args)) ; (abs (- x)) -> (abs x) (eq? (caar args) '-) (pair? (cdar args)) (null? (cddar args))) `(,(car form) ,(cadar args)) `(,(car form) ,@args))))) form)) ((imag-part) (if (= len 1) (if (or (real? (car args)) (and (pair? (car args)) (real-result? (caar args)))) 0.0 `(imag-part ,@args)) form)) ((real-part) (if (= len 1) (if (or (real? (car args)) (and (pair? (car args)) (real-result? (caar args)))) (car args) `(real-part ,@args)) form)) ((denominator) (if (= len 1) (if (or (integer? (car args)) (and (pair? (car args)) (integer-result? (caar args)))) 1 `(denominator ,(car args))) form)) ((numerator) (if (= len 1) (if (or (integer? (car args)) (and (pair? (car args)) (integer-result? (caar args)))) (car args) (if (rational? (car args)) (numerator (car args)) `(numerator ,(car args)))) form)) ((random) (if (and (= len 1) (number? (car args))) (if (and (integer? (car args)) (= (car args) 0)) 0 (if (morally-equal? (car args) 0.0) 0.0 `(random ,@args))) `(random ,@args))) ;; what about (* 2.0 (random 1.0)) and the like? ;; this is trickier than it appears: (* 2.0 (random 3)) etc ((complex) (if (and (= len 2) (morally-equal? (cadr args) 0.0)) ; morally so that 0 matches (car args) `(complex ,@args))) ((rationalize lognot ash modulo remainder quotient) (if (just-rationals? args) (catch #t ; catch needed here for things like (ash 2 64) (lambda () (apply (symbol->value (car form)) args)) (lambda ignore `(,(car form) ,@args))) ; use this form to pick up possible arg changes `(,(car form) ,@args))) ((expt) (if (= len 2) (if (and (eqv? (car args) 0) (not (eqv? (cadr args) 0))) 0 (if (and (eqv? (cadr args) 0) (not (eqv? (car args) 0))) 1 (if (eqv? (car args) 1) 1 (if (eqv? (cadr args) 1) (car args) (if (eqv? (cadr args) -1) `(/ ,(car args)) (if (just-rationals? args) (catch #t (lambda () (let ((val (apply expt args))) (if (integer? val) val `(expt ,@args)))) (lambda args `(expt ,@args))) `(expt ,@args))))))) form)) ((angle) (if (pair? args) (if (eqv? (car args) -1) 'pi (if (or (morally-equal? (car args) 0.0) (eq? (car args) 'pi)) 0.0 `(angle ,@args))) form)) ((atan) (if (and (= len 1) (pair? (car args)) (= (length (car args)) 3) (eq? (caar args) '/)) `(atan ,@(cdar args)) `(atan ,@args))) ((inexact->exact) (if (= len 1) (if (or (rational? (car args)) (and (pair? (car args)) (or (rational-result? (caar args)) (integer-result? (caar args))))) (car args) (if (number? (car args)) (catch #t (lambda () (inexact->exact (car args))) (lambda any `(inexact->exact ,@args))) `(inexact->exact ,@args))) form)) ((logior) (set! args (remove-duplicates (remove-all 0 (splice-if (lambda (x) (eq? x 'logior)) args)))) (if (every? (lambda (x) (or (not (number? x)) (integer? x))) args) (let ((rats (collect-if list integer? args))) (if (> (length rats) 1) (let ((y (apply logior rats))) (if (zero? y) (set! args (collect-if list (lambda (x) (not (number? x))) args)) (set! args (cons y (collect-if list (lambda (x) (not (number? x))) args)))))))) (if (null? args) ; (logior) -> 0 0 (if (null? (cdr args)) ; (logior x) -> x (car args) (if (memv -1 args) -1 (if (just-integers? args) (apply logior args) `(logior ,@args)))))) ((logand) (set! args (remove-duplicates (remove-all -1 (splice-if (lambda (x) (eq? x 'logand)) args)))) (if (every? (lambda (x) (or (not (number? x)) (integer? x))) args) (let ((rats (collect-if list integer? args))) (if (> (length rats) 1) (let ((y (apply logand rats))) (if (= y -1) (set! args (collect-if list (lambda (x) (not (number? x))) args)) (set! args (cons y (collect-if list (lambda (x) (not (number? x))) args)))))))) (if (null? args) -1 (if (null? (cdr args)) ; (logand x) -> x (car args) (if (memv 0 args) 0 (if (just-integers? args) (apply logand args) `(logand ,@args)))))) ;; (logand 1 (logior 2 x)) -> (logand 1 x)? ;; (logand 1 (logior 1 x)) -> 1 ;; (logand 3 (logior 1 x))? ;; similarly for (logior...(logand...)) ((logxor) (set! args (splice-if (lambda (x) (eq? x 'logxor)) args)) ; is this correct?? (if (null? args) 0 (if (null? (cdr args)) ; (logxor x) -> x?? (car args) (if (just-integers? args) (apply logxor args) (if (and (= len 2) (equal? (car args) (cadr args))) 0 `(logxor ,@args)))))) ((gcd) (set! args (remove-duplicates (splice-if (lambda (x) (eq? x 'gcd)) args))) (if (null? args) 0 ;; here and in lcm, if just 1 arg -> (abs arg) (if (memv 1 args) 1 (if (just-integers? args) (catch #t ; maybe (gcd -9223372036854775808 -9223372036854775808) (lambda () (apply gcd args)) (lambda ignore `(gcd ,@args))) (if (null? (cdr args)) `(abs ,(car args)) (if (eqv? (car args) 0) `(abs ,(cadr args)) (if (eqv? (cadr args) 0) `(abs ,(car args)) `(gcd ,@args)))))))) ((lcm) (set! args (remove-duplicates (splice-if (lambda (x) (eq? x 'lcm)) args))) (if (null? args) 1 (if (memv 0 args) 0 (if (just-integers? args) (catch #t (lambda () (apply lcm args)) (lambda ignore `(lcm ,@args))) (if (null? (cdr args)) `(abs ,(car args)) `(lcm ,@args)))))) ((max min) (if (pair? args) (begin (set! args (remove-duplicates (splice-if (lambda (x) (eq? x (car form))) args))) (if (= len 1) (car args) (if (just-reals? args) (apply (symbol->value (car form)) args) (let ((nums (collect-if list number? args)) (other (if (eq? (car form) 'min) 'max 'min))) (if (and (pair? nums) (just-reals? nums)) ; non-real case checked elsewhere (later) (let ((relop (if (eq? (car form) 'min) >= <=))) (if (> (length nums) 1) (set! nums (list (apply (symbol->value (car form)) nums)))) (let ((new-args (append nums (collect-if list (lambda (x) (not (number? x))) args)))) (let ((c1 (car nums))) (set! new-args (collect-if list (lambda (x) (or (not (pair? x)) (<= (length x) 2) (not (eq? (car x) other)) (let ((c2 (find-if number? (cdr x)))) (or (not c2) (relop c1 c2))))) new-args))) (if (< (length new-args) (length args)) (set! args new-args))))) ;; if (max c1 (min c2 . args1) . args2) where (>= c1 c2) -> (max c1 . args2) ;; if (min c1 (max c2 . args1) . args2) where (<= c1 c2) -> (min c1 . args2) ;; there are more such cases: (max x (min x 3)) -> x and (min x (max x c)) -> x ;; (max a b) is (- (min (- a) (- b))), but that doesn't help here -- the "-" gets in our way (if (null? (cdr args)) ; (max (min x 3) (min x 3)) -> (max (min x 3)) -> (min x 3) (car args) (if (and (null? (cddr args)) ; (max|min x (min|max x ...) -> x (or (and (pair? (car args)) (eq? (caar args) other) (symbol? (cadr args)) ; actually this is probably not needed, but I want to avoid (random ...) ;; perhaps instead use not min/max (member (cadr args) (car args))) (and (pair? (cadr args)) (eq? (caadr args) other) (symbol? (car args)) (member (car args) (cadr args))))) ((if (pair? (car args)) cadr car) args) `(,(car form) ,@args))))))) form)) (else `(,(car form) ,@args)))))) (define (->eqf x) (case x ((char?) '(eqv? char=?)) ((integer? rational? real? number? complex?) '(eqv? =)) ((symbol? keyword? boolean?)'(eq? eq?)) ((string? byte-vector?) '(equal? string=?)) ((null?) '(eq? null?)) ((pair? vector? float-vector? int-vector? hash-table?) '(equal? equal)) (else '(#t #t)))) (define (eqf selector) (if (symbol? selector) '(#t #t) (if (not (pair? selector)) (->eqf (->type selector)) (if (eq? (car selector) 'quote) (if (symbol? (cadr selector)) '(eq? eq?) (if (null? (cadr selector)) '(eq? null?) (if (char? (cadr selector)) '(eqv? char=?) '(equal? equal?)))) (if (symbol? (car selector)) (->eqf (return-type (car selector))) '(#t #t)))))) (define (check-special-cases name head form env) (case head ((memq assq memv assv member assoc) (define (list-one? p) (and (pair? p) (pair? (cdr p)) (null? (cddr p)) (or (and (eq? (car p) 'list) cadr) (and (eq? (car p) 'quote) (pair? (cadr p)) (null? (cdadr p)) (if (symbol? (caadr p)) (lambda (x) (list 'quote (caadr x))) caadr))))) (if (= (length form) 4) (let ((func (list-ref form 3))) (if (symbol? func) (let ((sig (procedure-signature (symbol->value func)))) (if (and sig (not (eq? (car sig) 'boolean?))) (lint-format "~A is a questionable ~A function" name func head))) (if (and (pair? func) (= (length func) 3) (eq? (car func) 'lambda) (pair? (cadr func)) (pair? (caddr func))) (if (not (member (length (cadr func)) '(2 -1))) (lint-format "~A equality function (optional 3rd arg) should take two arguments" name head) (if (eq? head 'member) (let ((eq (caddr func)) (args (cadr func))) (if (and (memq (car eq) '(eq? eqv? equal?)) (eq? (car args) (cadr eq)) (pair? (caddr eq)) (eq? (car (caddr eq)) 'car) (pair? (cdr (caddr eq))) (pair? (cdr args)) (eq? (cadr args) (cadr (caddr eq)))) (lint-format "member might perhaps be ~A" name (if (or (eq? func 'eq?) (eq? (car (caddr func)) 'eq?)) 'assq (if (eq? (car (caddr func)) 'eqv?) 'assv 'assoc)))))))))) (when (= (length form) 3) (let ((selector (cadr form)) (items (caddr form))) (let ((current-eqf (case head ((memq assq) 'eq?) ((memv assv) 'eqv?) (else 'equal?))) (selector-eqf (eqf selector)) (one-item (and (memq head '(memq memv member)) (list-one? (caddr form))))) ;; one-item assoc doesn't simplify cleanly (if one-item (let* ((target (one-item items)) (iter-eqf (eqf target))) (lint-format "perhaps ~A" name (if (or (symbol? target) (and (pair? target) (not (eq? (car target) 'quote)))) (lists->string form `(,(cadr iter-eqf) ,selector ',target)) (lists->string form `(,(cadr iter-eqf) ,selector ,target))))) (letrec ((duplicates? (lambda (lst fnc) (and (pair? lst) (or (fnc (car lst) (cdr lst)) (duplicates? (cdr lst) fnc))))) (duplicate-constants? (lambda (lst fnc) (and (pair? lst) (or (and (constant? (car lst)) (fnc (car lst) (cdr lst))) (duplicate-constants? (cdr lst) fnc)))))) (if (and (pair? items) (or (eq? (car items) 'list) (and (eq? (car items) 'quote) (pair? (cadr items))))) (let ((baddy #f)) (catch #t (lambda () (if (eq? (car items) 'list) ; TODO: restrict to constants? (set! baddy (duplicate-constants? (cdr items) (symbol->value head))) (set! baddy (duplicates? (cadr items) (symbol->value head))))) (lambda args #f)) (if (pair? baddy) (lint-format "duplicated entry ~S in ~A" name (car baddy) items)))) (if (and (symbol? (car selector-eqf)) (not (eq? (car selector-eqf) current-eqf))) (lint-format "~A: perhaps ~A -> ~A" name form head (if (memq head '(memq memv member)) (case (car selector-eqf) ((eq?) 'memq) ((eqv?) 'memv) ((equal?) 'member)) (case (car selector-eqf) ((eq?) 'assq) ((eqv?) 'assv) ((equal?) 'assoc)))))))) (when (and (memq head '(memq memv)) (pair? items) (eq? (car items) 'quote) (pair? (cadr items))) (let ((bad (find-if (lambda (x) (not (or (symbol? x) (char? x) (number? x) (procedure? x) ; (memq abs '(1 #_abs 2)) ! (memq x '(#f #t () # # #))))) (cadr items)))) (if bad (if (pair? bad) (if (eq? (car bad) 'quote) (lint-format "stray quote? ~A" name form) (if (eq? (car bad) 'unquote) (lint-format "stray comma? ~A" name form) (lint-format "pointless list member: ~S in ~A" name bad form))) (lint-format "pointless list member: ~S in ~A" name bad form))))))))) ((if) (let ((len (length form))) (if (> len 4) (lint-format "if has too many clauses: ~A" name form) (if (< len 3) (lint-format "if has too few clauses: ~A" name form) (let ((test (cadr form)) (true (caddr form)) (false (if (= len 4) (cadddr form) 'no-false))) (if (never-false test) (lint-format "if test is never false: ~A" name form) (if (and (never-true test) true) ; complain about (if #f #f) later (lint-format "if test is never true: ~A" name form))) (let ((expr (simplify-boolean test () () env))) ;(format *stderr* "expr simplified: ~S~%" expr) (if (not (side-effect? test env)) (if (or (equal? test true) (equal? expr true)) (lint-format "perhaps ~A" name (lists->string form (if (eq? false 'no-false) (simplify-boolean `(or ,expr #) () () env) (simplify-boolean `(or ,expr ,false) () () env)))) (if (or (equal? test false) (equal? expr false)) (lint-format "perhaps ~A" name (lists->string form (simplify-boolean `(and ,expr ,true) () () env)))))) (if (pair? false) (begin (if (and (eq? (car false) 'if) (pair? (cdr false)) (pair? (cadr false)) (eq? (caadr false) 'not) (or (equal? test (cadr (cadr false))) (equal? expr (cadr (cadr false)))) (not (side-effect? test env))) (lint-format "pointless repetition of if test: ~A" name (lists->string form `(if ,expr ,true ,(caddr false))))) (if (and (eq? (car false) 'if) ; (if test0 expr (if test1 expr)) -> if (or test0 test1) expr) (equal? true (caddr false))) (let ((test1 (simplify-boolean `(or ,expr ,(cadr false)) () () env))) (lint-format "perhaps ~A" name (lists->string form `(if ,test1 ,true ,@(cdddr false)))))) (if (and (pair? true) ; (if expr (set! var #t | #f) (set! var #f | #t)) -> (set! var expr|(not expr))?? (eq? (car true) 'set!) (eq? (car false) 'set!) (eq? (cadr true) (cadr false)) (boolean? (caddr true)) (boolean? (caddr false)) (not (eq? (caddr true) (caddr false)))) (lint-format "perhaps ~A" name (lists->string form (if (caddr true) `(set! ,(cadr true) ,expr) `(set! ,(cadr true) (not ,expr))))))) (if (eq? false 'no-false) ; no false branch (begin (if (and (pair? test) ; (if (pair? lst) (for-each f lst)) -> (for-each f lst) (eq? (car test) 'pair?) (pair? true) (memq (car true) '(map for-each)) (eq? (cadr test) (caddr true))) (lint-format "perhaps ~A" name (lists->string form true))) (if (and (pair? true) ; (if test0 (if test1 expr)) -> (if (and test0 test1) expr) (else #) (eq? (car true) 'if) (null? (cdddr true))) (let ((test1 (simplify-boolean `(and ,expr ,(cadr true)) () () env))) (lint-format "perhaps ~A" name (lists->string form `(if ,test1 ,(caddr true))))))))) (if (eq? expr #t) (lint-format "perhaps ~A" name (lists->string form true)) (if (not expr) (if (eq? false 'no-false) (if true ; (if #f x) as a kludgey # (lint-format "perhaps ~A" name (lists->string form #))) (lint-format "perhaps ~A" name (lists->string form false))) (if (not (equal? true false)) (if (boolean? true) (if (boolean? false) ; ! (if expr #t #f) turned into something less verbose (lint-format "perhaps ~A" name (lists->string form (if true expr (simplify-boolean `(not ,expr) () () env)))) (lint-format "perhaps ~A" name (lists->string form (if true (if (eq? false 'no-false) expr (simplify-boolean `(or ,expr ,false) () () env)) (simplify-boolean (if (eq? false 'no-false) `(not ,expr) `(and (not ,expr) ,false)) () () env))))) (if (boolean? false) (lint-format "perhaps ~A" name (lists->string form (simplify-boolean (if false (if (and (pair? expr) (eq? (car expr) 'not)) `(or ,(cadr expr) ,true) `(or (not ,expr) ,true)) `(and ,expr ,true)) () () env))))) (if (= len 4) (if (not (side-effect? test env)) (lint-format "if is not needed here: ~A" name (lists->string form true)) (lint-format "if is not needed here: ~A" name (lists->string form `(begin ,expr ,true)))))))))))))) ((car cdr caar cadr cddr cdar caaar caadr caddr cdddr cdaar cddar cadar cdadr cadddr cddddr) (let ((cxr? (lambda (s) (and (pair? (cdr s)) (pair? (cadr s)) (memq (caadr s) '(car cdr cadr cddr cdar cdddr cddddr)))))) (if (and (not (= line-number last-simplify-boolean-line-number)) (cxr? form)) (let* ((arg1 (cadr form)) (arg2 (and arg1 (cxr? arg1) (cadr arg1))) (arg3 (and arg2 (cxr? arg2) (cadr arg2)))) (set! last-simplify-boolean-line-number line-number) (let* ((innards (lambda (c) (case c ((car) "a") ((cdr) "d") ((caar) "aa") ((cadr) "ad") ((cddr) "dd") ((cdar) "da") ((caaar) "aaa") ((caadr) "aad") ((caddr) "add") ((cdddr) "ddd") ((cdaar) "daa") ((cddar) "dda") ((cdadr) "dad") ((cadar) "ada") ((cddddr) "dddd") ((cadddr) "addd")))) (cxr (string-append (innards (car form)) (innards (car arg1)) (if arg2 (innards (car arg2)) "") (if arg3 (innards (car arg3)) "")))) (if (< (length cxr) 5) (lint-format "perhaps ~A" name (lists->string form `(,(string->symbol (string-append "c" cxr "r")) ,(cadr (or arg3 arg2 arg1))))) ;; if it's car|cdr followed by cdr's, use list-ref|tail (if (not (char-position #\a cxr)) (lint-format "perhaps ~A" name (lists->string form `(list-tail ,(cadr (or arg3 arg2 arg1)) ,(length cxr)))) (if (not (char-position #\a (substring cxr 1))) (lint-format "perhaps ~A" name (lists->string form `(list-ref ,(cadr (or arg3 arg2 arg1)) ,(- (length cxr) 1)))) (set! last-simplify-boolean-line-number -1)))))))) (if (and (memq head '(car cdr)) (pair? (cadr form)) (eq? (car (cadr form)) 'cons)) (lint-format "(~A~A) is the same as~A" name head (truncated-list->string (cadr form)) (if (eq? head 'car) (truncated-list->string (cadadr form)) (truncated-list->string (caddr (cadr form))))))) ((and or not) (if (not (= line-number last-simplify-boolean-line-number)) (let ((val (simplify-boolean form () () env))) (set! last-simplify-boolean-line-number line-number) (if (not (equal? form val)) (lint-format "perhaps ~A" name (lists->string form val)))))) ((=) (if (and (> (length form) 2) (any-real? (cdr form))) (lint-format "= can be troublesome with floats: ~A" name (truncated-list->string form))) (let ((cleared-form (cons = (remove-if (lambda (x) (not (number? x))) (cdr form))))) (if (and (> (length cleared-form) 2) (not (checked-eval cleared-form))) (lint-format "this comparison can't be true: ~A" name (truncated-list->string form)))) (when (and (= (length form) 3) (eqv? (caddr form) 0)) (let ((arg (cadr form))) (when (and (pair? arg) (eq? (car arg) '-) (= (length arg) 3)) (lint-format "perhaps ~A" name (lists->string form `(= ,(cadr arg) ,(caddr arg)))))))) ((< > <= >=) ; '= handled above (let ((cleared-form (cons (car form) ; keep operator (remove-if (lambda (x) (not (number? x))) (cdr form))))) (if (and (> (length cleared-form) 2) (not (checked-eval cleared-form))) (lint-format "this comparison can't be true: ~A" name (truncated-list->string form)))) (when (and (= (length form) 3) (eqv? (caddr form) 0)) (let ((arg (cadr form))) (if (and (pair? arg) (eq? (car arg) '-) (= (length arg) 3)) (lint-format "perhaps ~A" name (lists->string form `(,(car form) ,(cadr arg) ,(caddr arg)))))))) ;; could change (> x 0) to (positive? x) and so on, but the former is clear and ubiquitous ((char? char<=? char>=? char=? char-ci? char-ci<=? char-ci>=? char-ci=?) (let ((cleared-form (cons (car form) ; keep operator (remove-if (lambda (x) (not (char? x))) (cdr form))))) (if (and (> (length cleared-form) 2) (not (checked-eval cleared-form))) (lint-format "this comparison can't be true: ~A" name (truncated-list->string form))))) ((string? string<=? string>=? string=? string-ci? string-ci<=? string-ci>=? string-ci=?) (let ((cleared-form (cons (car form) ; keep operator (remove-if (lambda (x) (not (string? x))) (cdr form))))) (if (and (> (length cleared-form) 2) (not (checked-eval cleared-form))) (lint-format "this comparison can't be true: ~A" name (truncated-list->string form))))) ((call-with-exit) (let ((return (and (pair? (cdr form)) (pair? (cadr form)) (eq? (caadr form) 'lambda) (pair? (cdadr form)) (pair? (cadadr form)) (car (cadadr form))))) (if (symbol? return) (let ((body (cddadr form))) (if (not (tree-member return body)) (lint-format "exit-function appears to be unused: ~A" name (truncated-list->string form))))))) ((call-with-input-string call-with-input-file call-with-output-file) ;; call-with-output-string func is the first arg, not second, but these checks get no hits (let ((port (and (pair? (cdr form)) (pair? (cddr form)) (pair? (caddr form)) (eq? (caaddr form) 'lambda) (pair? (cdaddr form)) (pair? (cadr (caddr form))) (car (cadr (caddr form)))))) (if (symbol? port) (let ((body (cddr (caddr form)))) (if (not (tree-member port body)) (lint-format "port appears to be unused: ~A" name (truncated-list->string form))))))) ((/) (if (pair? (cdr form)) (if (and (null? (cddr form)) (number? (cadr form)) (zero? (cadr form))) (lint-format "attempt to invert zero: ~A" name (truncated-list->string form)) (if (and (pair? (cddr form)) (memv 0 (cddr form))) (lint-format "attempt to divide by 0: ~A" name (truncated-list->string form)))))) ((copy) (if (and (pair? (cdr form)) (or (number? (cadr form)) (boolean? (cadr form)) (char? (cadr form)) (and (pair? (cadr form)) (memq (caadr form) '(copy string-copy))))) (lint-format "~A could be ~A" name form (cadr form)) (if (and (pair? (cdr form)) (equal? (cadr form) '(owlet))) (lint-format "~A could be (owlet): owlet is copied internally" name form)))) ((string-copy) (if (and (pair? (cdr form)) (pair? (cadr form)) (memq (caadr form) '(copy string-copy))) (lint-format "~A could be ~A" name form (cadr form)))) ((string) (if (every? (lambda (x) (and (char? x) (not (member x '(#\null #\newline #\escape))))) (cdr form)) ;#\linefeed -> #\newline in reader (lint-format "~A could be ~S" name form (apply string (cdr form))))) ((string? number?) (if (and (pair? (cdr form)) (pair? (cadr form)) (eq? (caadr form) (if (eq? head 'string?) 'number->string 'string->number))) (lint-format "perhaps ~A" name (lists->string form (cadr form))))) ((vector-ref list-ref hash-table-ref let-ref int-vector-ref float-vector-ref) (unless (= line-number last-checker-line-number) (if (= (length form) 3) (let ((seq (cadr form))) (if (and (pair? seq) (eq? (car seq) head) ; perhaps instead: (memq (car seq) '(vector-ref list-ref hash-table-ref let-ref)) (= (length seq) 3)) (let ((seq1 (cadr seq))) (if (and (pair? seq1) (eq? (car seq1) head) (= (length seq1) 3)) (lint-format "perhaps ~A" name (lists->string form `(,(cadr seq1) ,(caddr seq1) ,(caddr seq) ,(caddr form)))) (lint-format "perhaps ~A" name (lists->string form `(,seq1 ,(caddr seq) ,(caddr form))))))))) (set! last-checker-line-number line-number))) ((vector-set! list-set! hash-table-set! float-vector-set! int-vector-set!) (if (= (length form) 4) (let ((target (cadr form)) (index (caddr form)) (val (cadddr form))) (if (and (pair? val) (= (length val) 3) (eq? target (cadr val)) (equal? index (caddr val)) (memq (car val) '(vector-ref list-ref hash-table-ref float-vector-ref int-vector-ref))) (lint-format "redundant?: ~A" name (truncated-list->string form)) (if (and (pair? target) (memq (car target) '(vector-ref list-ref hash-table-ref float-vector-ref int-vector-ref))) (lint-format "perhaps ~A" name (lists->string form `(set! (,@(cdr target) ,index) ,val))) (if (or (code-constant? (cadr form)) (and (pair? (cadr form)) (memq (caadr form) '(make-vector vector make-string string make-list list append cons vector-append copy)))) (lint-format "perhaps ~A" name (lists->string form val)))))))) ((object->string) (if (pair? (cdr form)) (if (and (pair? (cadr form)) (eq? (caadr form) 'object->string)) (lint-format "~A could be ~A" name form (cadr form)) (if (and (pair? (cddr form)) (not (pair? (caddr form))) (or (not (symbol? (caddr form))) (keyword? (caddr form))) (not (memq (caddr form) '(#f #t :readable)))) (lint-format "bad second argument: ~A" name (caddr form)))))) ((display) (if (and (= (length form) 2) (pair? (cadr form)) (eq? (caadr form) 'format) (not (cadadr form))) (lint-format "~A could be ~A" name form `(format #t ,@(cddadr form))))) ((make-vector) (if (and (= (length form) 4) (code-constant? (caddr form)) (not (real? (caddr form))) (eq? (cadddr form) #t)) (lint-format "~A won't create an homogenous vector" name form))) ((reverse list->vector vector->list list->string string->list symbol->string string->symbol number->string) ;; not string->number -- no point in copying a number and it's caught below (let ((inverses '((reverse . reverse) (list->vector . vector->list) (vector->list . list->vector) (symbol->string . string->symbol) (string->symbol . symbol->string) (list->string . string->list) (string->list . list->string) (number->string . string->number)))) (if (and (pair? (cdr form)) (pair? (cadr form)) (pair? (cdadr form)) (eq? (caadr form) (let ((p (assq head inverses))) (and (pair? p) (cdr p))))) (lint-format "~A could be (copy ~A)" name form (cadadr form))))) ((char->integer integer->char symbol->keyword keyword->symbol string->number) (let ((inverses '((char->integer . integer->char) (integer->char . char->integer) (symbol->keyword . keyword->symbol) (keyword->symbol . symbol->keyword) (string->number . number->string)))) (if (and (pair? (cdr form)) (pair? (cadr form)) (pair? (cdadr form)) (eq? (caadr form) (let ((p (assq head inverses))) (and (pair? p) (cdr p))))) (lint-format "~A could be ~A" name form (cadadr form))))) ((string-append) (if (not (= line-number last-checker-line-number)) (let ((args (remove-all "" (splice-if (lambda (x) (eq? x 'string-append)) (cdr form))))) (if (null? args) (lint-format "perhaps ~A" name (lists->string form "")) (if (null? (cdr args)) (lint-format "perhaps ~A, or use copy" name (lists->string form (car args))) (if (every? string? args) (lint-format "perhaps ~A" name (lists->string form (apply string-append args))) (if (not (equal? args (cdr form))) (lint-format "perhaps ~A" name (lists->string form `(string-append ,@args))))))) (set! last-checker-line-number line-number)))) ((vector-append) (if (not (= line-number last-checker-line-number)) (let ((args (remove-all #() (splice-if (lambda (x) (eq? x 'vector-append)) (cdr form))))) (if (null? args) (lint-format "perhaps ~A" name (lists->string form #())) (if (null? (cdr args)) (lint-format "perhaps ~A" name (lists->string form (car args))) (if (every? vector? args) (lint-format "perhaps ~A" name (lists->string form (apply vector-append args))) (if (not (equal? args (cdr form))) (lint-format "perhaps ~A" name (lists->string form `(vector-append ,@args))))))) (set! last-checker-line-number line-number)))) ((cons) (if (and (= (length form) 3) (pair? (caddr form)) (eq? (caaddr form) 'list)) (lint-format "perhaps ~A" name (lists->string form `(list ,(cadr form) ,@(cdaddr form)))))) ((append) (unless (= line-number last-checker-line-number) (set! last-checker-line-number line-number) (letrec ((splice-append (lambda (lst) (cond ((null? lst) ()) ((pair? lst) (if (and (pair? (car lst)) (eq? (caar lst) 'append)) (if (null? (cdar lst)) (cons () (splice-append (cdr lst))) (append (splice-append (cdar lst)) (splice-append (cdr lst)))) (cons (car lst) (splice-append (cdr lst))))) (#t lst))))) (let ((new-args (splice-append (cdr form)))) ; (append '(1) (append '(2) '(3))) -> (append '(1) '(2) '(3)) (let ((len1 (length new-args))) (define (distribute-quote x) (map (lambda (item) (if (or (symbol? item) (pair? item)) `(quote ,item) item)) x)) (define (append->list . items) (let ((lst (list 'list))) (for-each (lambda (item) (set! lst (append lst (if (eq? (car item) 'list) (cdr item) (distribute-quote (cadr item)))))) items) lst)) (case len1 ((0) ; (append) -> () (lint-format "perhaps ~A" name (lists->string form ()))) ((1) ; (append x) -> x (lint-format "perhaps ~A" name (lists->string form (car new-args)))) ((2) (if (or (null? (cadr new-args)) ; (append (list x) ()) -> (list x) (quoted-null? (cadr new-args)) (equal? (cadr new-args) '(list))) (lint-format "perhaps clearer: ~A" name (lists->string form `(copy ,(car new-args)))) (if (null? (car new-args)) ; (append () x) -> x (lint-format "perhaps ~A" name (lists->string form (cadr new-args))) (if (and (pair? (car new-args)) ; (append (list x y) '(z)) -> (list x y 'z) (or (eq? (caar new-args) 'list) (quoted-undotted-pair? (car new-args))) (pair? (cadr new-args)) (or (eq? (caadr new-args) 'list) (quoted-undotted-pair? (cadr new-args)))) (lint-format "perhaps ~A" name (lists->string form (apply append->list new-args))) (if (not (equal? (cdr form) new-args)) (lint-format "perhaps ~A" name (lists->string form `(append ,@new-args)))))))) (else (if (every? (lambda (item) (and (pair? item) (or (eq? (car item) 'list) (quoted-undotted-pair? item)))) new-args) (lint-format "perhaps ~A" name (lists->string form (apply append->list new-args))) (if (not (equal? (cdr form) new-args)) (lint-format "perhaps ~A" name (lists->string form `(append ,@new-args)))))))))))) ((apply) (let ((function? (lambda (f) (or (and (symbol? f) (let ((func (symbol->value f *e*))) (or (procedure? func) (let ((e (or (var-member f env) (hash-table-ref globals f)))) (and (var? e) (let? (var-new e)) (memq ((var-new e) 'type) '(define define* lambda lambda*))))))) (and (pair? f) (memq (car f) '(lambda lambda*))))))) (if (and (pair? (cdr form)) (not (symbol? (cadr form))) (not (applicable? (cadr form)))) (lint-format "~S is not applicable: ~A" name (cadr form) (truncated-list->string form)) (let ((len (length form))) (when (> len 2) (if (and (not (list? (form (- len 1)))) (code-constant? (form (- len 1)))) (lint-format "last argument should be a list: ~A" name (truncated-list->string form)) (if (and (= len 3) (pair? (caddr form)) (eq? (caaddr form) 'list) ;; macros are different here (function? (cadr form))) (lint-format "perhaps ~A" name (lists->string form `(,(cadr form) ,@(cdaddr form)))) (if (and (or (not (every? code-constant? (cddr form))) (catch #t (lambda () (let ((val (eval form))) (lint-format "perhaps ~A -> ~S" name form val) #t)) (lambda args #f))) (symbol? (cadr form))) (let ((func (symbol->value (cadr form) *e*))) (if (procedure? func) (let ((ary (arity func))) (if (and (pair? ary) (> (- (length (cddr form)) 1) (cdr ary))) ; last apply arg might be var=() (lint-format "too many arguments for ~A: ~A" name (cadr form) form))))))))))))) ((format snd-display) (if (< (length form) 3) (begin (if (< (length form) 2) (lint-format "~A has too few arguments: ~A" name head (truncated-list->string form)) (if (and (pair? (cadr form)) (eq? (caadr form) 'format)) (lint-format "redundant format: ~A" name (truncated-list->string form)) (if (and (code-constant? (cadr form)) (not (string? (cadr form)))) (lint-format "format with one argument takes a string: ~A" name (truncated-list->string form))))) env) (let ((control-string (if (string? (cadr form)) (cadr form) (caddr form))) (args (if (string? (cadr form)) (cddr form) (cdddr form)))) (define (count-directives str name form) (let ((curlys 0) (dirs 0) (pos (char-position #\~ str))) (if pos (let ((len (length str)) (tilde-time #t)) (do ((i (+ pos 1) (+ i 1))) ((>= i len)) (let ((c (string-ref str i))) (if tilde-time (begin (if (and (= curlys 0) (not (memq c '(#\~ #\T #\t #\& #\% #\^ #\| #\newline #\}))) ; ~* consumes an arg (not (call-with-exit (lambda (return) (do ((k i (+ k 1))) ((= k len) #f) ;; this can be confused by pad chars in ~T (if (and (not (char-numeric? (string-ref str k))) (not (char=? (string-ref str k) #\,))) (return (char-ci=? (string-ref str k) #\t)))))))) (begin ;; the possibilities are endless, so I'll stick to the simplest (if (not (vector-ref format-control-char (char->integer c))) (lint-format "unrecognized format directive: ~C in ~S, ~S" name c str form)) (set! dirs (+ dirs 1)) ;; ~n so try to figure out how many args are needed (this is not complete) (when (char-ci=? c #\n) (let ((j (+ i 1))) (if (>= j len) (lint-format "missing format directive: ~S" name str) (begin ;; if ,n -- add another, if then not T, add another (if (char=? (string-ref str j) #\,) (if (>= (+ j 1) len) (lint-format "missing format directive: ~S" name str) (if (char-ci=? (string-ref str (+ j 1)) #\n) (begin (set! dirs (+ dirs 1)) (set! j (+ j 2))) (if (char-numeric? (string-ref str (+ j 1))) (set! j (+ j 2)) (set! j (+ j 1)))))) (if (>= j len) (lint-format "missing format directive: ~S" name str) (if (not (char-ci=? (string-ref str j) #\t)) (set! dirs (+ dirs 1)))))))))) (set! tilde-time #f) (case c ((#\{) (set! curlys (+ curlys 1))) ((#\}) (set! curlys (- curlys 1))) ((#\^ #\|) (if (zero? curlys) (lint-format "~A has ~C outside ~~{~~}?" name str c))))) (begin (set! pos (char-position #\~ str i)) (if pos (begin (set! tilde-time #t) (set! i pos)) (set! i len)))))) (if tilde-time (lint-format "~A control string ends in tilde: ~A" name head (truncated-list->string form))))) (if (not (= curlys 0)) (lint-format "~A has ~D unmatched ~A~A: ~A" name head (abs curlys) (if (positive? curlys) "{" "}") (if (> curlys 1) "s" "") (truncated-list->string form))) dirs)) (if (not (string? control-string)) (if (not (proper-list? args)) (lint-format "~S looks suspicious" name form)) (let ((ndirs (count-directives control-string name form)) (nargs (if (or (null? args) (pair? args)) (length args) 0))) (if (not (= ndirs nargs)) (lint-format "~A has ~A arguments: ~A" name head (if (> ndirs nargs) "too few" "too many") (truncated-list->string form)) (if (and (not (cadr form)) (zero? ndirs) (not (char-position #\~ control-string))) (lint-format "~A could be ~S, (format is a no-op here)" name form (caddr form))))))))) ((sort!) (if (= (length form) 3) (let ((func (caddr form))) (if (memq func '(= eq? eqv? equal? string=? char=? string-ci=? char-ci=?)) (lint-format "sort! with ~A may hang: ~A" name func (truncated-list->string form)) (if (symbol? func) (let ((sig (procedure-signature (symbol->value func)))) (if (and sig (not (eq? (car sig) 'boolean?))) (lint-format "~A is a questionable sort! function" name func)))))))) ((substring) (if (every? code-constant? (cdr form)) (catch #t (lambda () (let ((val (eval form))) (lint-format "perhaps ~A -> ~S" name form val))) (lambda (type info) (lint-format "~A -> ~A~%" name form (apply format #f info)))) (let ((str (cadr form))) (if (and (pair? str) (eq? (car str) 'substring) (pair? (cddr form)) (null? (cdddr form)) (null? (cdddr str))) (if (and (integer? (caddr form)) (integer? (caddr str))) (lint-format "perhaps ~A" name (lists->string form `(substring ,(cadr str) ,(+ (caddr str) (caddr form))))) (lint-format "perhaps ~A" name (lists->string form `(substring ,(cadr str) (+ ,(caddr str) ,(caddr form))))))) ;; end indices are complicated -- since this rarely happens, not worth the trouble (if (and (integer? (caddr form)) (zero? (caddr form)) (null? (cdddr form))) (lint-format "perhaps clearer: ~A" name (lists->string form `(copy ,str))))))) ((list-tail) (if (= (length form) 3) (if (and (integer? (caddr form)) (zero? (caddr form))) (lint-format "perhaps ~A" name (lists->string form (cadr form))) (if (and (pair? (cadr form)) (eq? (caadr form) 'list-tail)) (if (and (integer? (caddr form)) (integer? (caddr (cadr form)))) (lint-format "perhaps ~A" name (lists->string form `(list-tail ,(cadadr form) ,(+ (caddr (cadr form)) (caddr form))))) (lint-format "perhaps ~A" name (lists->string form `(list-tail ,(cadadr form) (+ ,(caddr (cadr form)) ,(caddr form)))))))))) ((eq?) (if (< (length form) 3) (lint-format "eq? needs 2 arguments: ~A" name (truncated-list->string form)) (let ((arg1 (cadr form)) (arg2 (caddr form))) (let ((eq1 (eqf arg1)) (eq2 (eqf arg2))) (if (or (eq? (car eq1) 'equal?) (eq? (car eq2) 'equal?)) (lint-format "eq? should be equal? in ~S" name form) (if (or (eq? (car eq1) 'eqv?) (eq? (car eq2) 'eqv?)) (lint-format "eq? should be eqv? in ~S" name form)))) (let ((expr 'unset)) ; (eq? e #f) or (eq? #f e) -> (not e) (if (not arg1) (set! expr (simplify-boolean `(not ,arg2) () () env)) (if (not arg2) (set! expr (simplify-boolean `(not ,arg1) () () env)) (if (and (or (null? arg1) (quoted-null? arg1)) (not (code-constant? arg2))) (set! expr `(null? ,arg2)) (if (and (or (null? arg2) (quoted-null? arg2)) (not (code-constant? arg1))) (set! expr `(null? ,arg1)) (if (and (eq? arg1 #t) (pair? arg2) (eq? (return-type (car arg2)) 'boolean?)) (set! expr arg2) (if (and (eq? arg2 #t) (pair? arg1) (eq? (return-type (car arg1)) 'boolean?)) (set! expr arg1))))))) (if (not (eq? expr 'unset)) (lint-format "perhaps ~A" name (lists->string form expr))))))) ((eqv? equal? morally-equal?) (if (< (length form) 3) (lint-format "~A needs 2 arguments: ~A" name head (truncated-list->string form)) (let ((arg1 (cadr form)) (arg2 (caddr form))) (let ((eq1 (eqf arg1)) (eq2 (eqf arg2))) (if (or (eq? (car eq1) 'equal?) (eq? (car eq2) 'equal?)) (if (not (memq head '(equal? morally-equal?))) (lint-format "~A should be equal? in ~S" name head form)) (if (or (eq? (car eq1) 'eqv?) (eq? (car eq2) 'eqv?)) (if (and (not (eq? head 'eqv?)) (or (not (eq? head 'morally-equal?)) (and (or (not (number? arg1)) (rational? arg1)) ; here we have float-equal-epsilon (or (not (number? arg2)) (rational? arg2))))) (lint-format "~A ~A be eqv? in ~S" name head (if (eq? head 'eq?) "should" "could") form)) (if (or (eq? (car eq1) 'eq?) (eq? (car eq2) 'eq?)) (if (or (not arg1) (not arg2)) (lint-format "~A could be not: ~A" name head (lists->string form `(not ,(or arg1 arg2)))) (if (or (null? arg1) (null? arg2) (quoted-null? arg1) (quoted-null? arg2)) (lint-format "~A could be null?: ~A" name head (lists->string form (if (or (null? arg1) (quoted-null? arg1)) `(null? ,arg2) `(null? ,arg1)))) (if (not (eq? head 'eq?)) (lint-format "~A could be eq? in ~S" name head form))))))))))) ((map for-each) (let* ((len (length form)) (args (- len 2))) (if (< len 3) (lint-format "~A missing argument~A in: ~A" name head (if (= len 2) "" "s") (truncated-list->string form)) (let ((func (cadr form)) (ary #f)) (if (and (symbol? func) (defined? func) (procedure? (symbol->value func *e*))) (set! ary (arity (symbol->value func *e*))) (if (and (pair? func) (memq (car func) '(lambda lambda*)) (pair? (cadr func))) (let ((arglen (length (cadr func)))) (if (eq? (car func) 'lambda) (if (negative? arglen) (set! ary (cons (abs arglen) 512000)) (set! ary (cons arglen arglen))) (if (or (negative? arglen) (memq :rest (cadr func))) (set! ary (cons 0 512000)) (set! ary (cons 0 arglen))))))) (if (pair? ary) (if (< args (car ary)) (lint-format "~A has too few arguments in: ~A" name head (truncated-list->string form)) (if (> args (cdr ary)) (lint-format "~A has too many arguments in: ~A" name head (truncated-list->string form))))) (for-each (lambda (obj) (if (and (pair? obj) (memq (car obj) '(vector->list string->list let->list))) (lint-format "~A could be simplified to: ~A ; (~A accepts non-list sequences)" name (truncated-list->string obj) (truncated-list->string (cadr obj)) head))) (cddr form)))))) ((magnitude) (if (and (= (length form) 2) (memq (->type (cadr form)) '(integer? rational? real?))) (lint-format "perhaps use abs here: ~A" name form))) ((null eq eqv equal) ; (null (cdr...)) (if (not (var-member head env)) (lint-format "misspelled '~A? in ~A?" name head form))) ((open-input-file open-output-file) (if (and (pair? (cdr form)) (pair? (cddr form)) (string? (caddr form)) (not (memv (string-ref (caddr form) 0) '(#\r #\w #\a)))) ; b + then e m c x if gcc (lint-format "unexpected mode: ~A" name form))) ((catch) ;; catch tag is tricky -- it is evaluated, then eq? matches at error time, so we need ;; to catch constants that can't be eq? (if (= (length form) 4) (let ((tag (cadr form))) (if (or (and (not (pair? tag)) (or (number? tag) (char? tag) (length tag))) (and (pair? tag) (eq? (car tag) 'quote) (or (not (pair? (cdr tag))) (length (cadr tag))))) (lint-format "catch tag ~S is unreliable (catch uses eq? to match tags)" name (cadr form)))))) ((load) ; pick up the top level declarations (if (>= (length form) 2) (scan form))) ((*s7*) (if (= (length form) 2) (let ((arg (cadr form))) (if (and (pair? arg) (eq? (car arg) 'quote) (symbol? (cadr arg)) (not (memq (cadr arg) '(print-length safety cpu-time heap-size free-heap-size gc-freed max-string-length max-list-length max-vector-length max-vector-dimensions default-hash-table-length initial-string-port-length gc-protected-objects file-names rootlet-size c-types stack-top stack-size stacktrace-defaults max-stack-size catches exits float-format-precision bignum-precision default-rationalize-error default-random-state morally-equal-float-epsilon hash-table-float-epsilon undefined-identifier-warnings gc-stats symbol-table-locked?)))) (lint-format "unknown *s7* field: ~A" name (cadr form)))))) )) ; end check-special-cases (define (check-call name head form env) (let ((fdata (or (var-member head env) (hash-table-ref globals head)))) ;(format *stderr* "~A call: ~A~%" form fdata) (if (var? fdata) ;; a local var (if (let? (var-new fdata)) (let ((type ((var-new fdata) 'type)) (args ((var-new fdata) 'arglist)) (ary (and (not (eq? ((var-new fdata) 'decl) 'error)) (arity ((var-new fdata) 'decl))))) ;(format *stderr* "~A ~S~%" ary (object->string ((var-new fdata) 'decl) :readable)) (if (pair? ary) (let ((req (car ary)) (opt (cdr ary)) (pargs (if (pair? args) (proper-list args) (if (symbol? args) (list args) ())))) (let ((call-args (length (cdr form)))) (if (< call-args req) (lint-format "~A needs ~D argument~A: ~A" name head req (if (> req 1) "s" "") (truncated-list->string form)) (if (> (- call-args (keywords (cdr form))) opt) (lint-format "~A has too many arguments: ~A" name head (truncated-list->string form))))) (if (and (memq type '(define* lambda*)) (pair? args) (not (memq :allow-other-keys args))) (for-each (lambda (arg) (if (and (keyword? arg) (not (member (keyword->symbol arg) pargs (lambda (a b) (if (pair? b) (eq? a (car b)) (eq? a b)))))) (lint-format "~A keyword argument ~A (in ~S) does not match any argument in ~S" name head arg form pargs))) (cdr form))))))) ;; not local var (when (symbol? head) (let ((head-value (symbol->value head *e*))) ; head might be "arity"! (when (or (procedure? head-value) (macro? head-value)) ;; check arg number (let* ((args (length (cdr form))) (ary (arity head-value)) (min-arity (car ary)) (max-arity (cdr ary))) (if (< args min-arity) (lint-format "~A needs ~A~D argument~A: ~A" name head (if (= min-arity max-arity) "" "at least ") min-arity (if (> min-arity 1) "s" "") (truncated-list->string form)) (if (and (not (procedure-setter head-value)) (> (- args (keywords (cdr form))) max-arity)) (lint-format "~A has too many arguments: ~A" name head (truncated-list->string form)))) (if (and (procedure? head-value) (pair? (cdr form))) ; there are args (the not-enough-args case is checked above) (if (zero? max-arity) (lint-format "too many arguments: ~A" name (truncated-list->string form)) (begin (for-each (lambda (arg) (if (pair? arg) (if (negative? (length arg)) (lint-format "missing quote? ~A in ~A" name arg form) (if (eq? (car arg) 'unquote) (lint-format "stray comma? ~A in ~A" name arg form))))) (cdr form)) ;; if keywords, check that they are acceptable ;; this only applies to lambda*'s that have been previously loaded (lint doesn't create them) (let ((source (procedure-source head-value))) (if (and (pair? source) (eq? (car source) 'lambda*)) (let ((decls (cadr source))) (if (not (memq :allow-other-keys decls)) (for-each (lambda (arg) (if (and (keyword? arg) (not (eq? arg :rest)) (not (member arg decls (lambda (a b) (if (pair? b) (eq? (keyword->symbol a) (car b)) (eq? (keyword->symbol a) b)))))) (lint-format "~A keyword argument ~A (in ~S) does not match any argument in ~S" name head arg form decls))) (cdr form)))))) ;; we've already checked for head in the current env above (if (and (or (memq head '(eq? eqv?)) (and (= (length form) 3) (hash-table-ref repeated-args-table head))) (repeated-member? (cdr form) env)) (lint-format "this looks odd: ~A" name ;; sigh (= a a) could be used to check for non-finite numbers, I suppose, ;; and (/ 0 0) might be deliberate (as in gmp) ;; also (min (random x) (random x)) is not pointless (truncated-list->string form)) (if (and (hash-table-ref repeated-args-table-2 head) (repeated-member? (cdr form) env)) (lint-format "it looks odd to have repeated arguments in~A" name (truncated-list->string form)))) (when (memq head '(eq? eqv?)) (define (repeated-member-with-not? lst env) (and (pair? lst) (or (and (or (not (pair? (car lst))) (not (side-effect? (car lst) env))) (or (member (list 'not (car lst)) (cdr lst)) (and (pair? (car lst)) (eq? (caar lst) 'not) (= (length (car lst)) 2) (member (cadar lst) (cdr lst))))) (repeated-member-with-not? (cdr lst) env)))) (if (repeated-member-with-not? (cdr form) env) (lint-format "this looks odd: ~A" name (truncated-list->string form)))) ;; now try to check arg types (let ((func (symbol->value head *e*))) (let ((arg-data (let ((sig (procedure-signature func))) (and (pair? sig) (cdr sig))))) ;; (format *stderr* "arg-data: ~A~%" arg-data) (if (and arg-data (or (not (pair? arg-data)) (not (eq? (car arg-data) #t)) (not (infinite? (length arg-data))))) (check-args name head form arg-data env max-arity)))))))))))))) (define (get-generator form name head) ; defgenerator funcs (let ((name (if (pair? (cadr form)) (caadr form) (cadr form)))) ;; auto-define make-name, name? (let ((make-name (string->symbol (string-append "make-" (symbol->string name)))) (name? (string->symbol (string-append (symbol->string name) "?")))) (hash-table-set! globals make-name (make-var make-name)) (hash-table-set! globals name? (make-var name?))))) (define (load-walk form) ;; check form for top-level declarations, if load seen, and we haven't seen that file, load it (let ((head (car form))) (case head ((begin) (load-walk (cdr form))) ((define-constant define-envelope) (hash-table-set! globals (cadr form) (make-var (cadr form) :val (and (pair? (cddr form)) (caddr form))))) ((defmacro defmacro*) (hash-table-set! globals (cadr form) (make-var (cadr form) :new (inlet :type head :decl (eval (list head '_ (caddr form) #f)) :signature #f :side-effect #t :arglist (caddr form) :definition form :location #__line__)))) ((define) (let ((name (cadr form))) (if (pair? name) (let ((fname (car name))) (if (symbol? fname) (if (keyword? fname) (lint-format "keywords are constants ~A" name form) (hash-table-set! globals fname (make-var fname :new (inlet :type 'define :decl (eval (list 'define (cons '_ (cdadr form)) #f)) :signature #f :side-effect #t :arglist (cdr name) :definition form :location #__line__)))) (lint-format "what is this? ~A" name form))) (hash-table-set! globals name (make-var name :val (and (pair? (cddr form)) (caddr form))))))) ((define* define-expansion define-macro define-macro* define-bacro define-bacro* definstrument defanimal) (hash-table-set! globals (caadr form) (make-var (caadr form) :new (inlet :type head :decl (eval (list head (cons '_ (cdadr form)) #f)) :signature #f :side-effect #t :arglist (cdadr form) :definition form :location #__line__)))) ((defgenerator) (get-generator form 'defgenerator head)) ((if) (if (pair? (cddr form)) (if (pair? (cdddr form)) (begin (load-walk (cadddr form)) (load-walk (caddr form))) (load-walk (caddr form))))) ((load) (if (>= (length form) 2) (scan form)))))) (define (scan form) (define (find-file file paths) (and (pair? paths) (catch #t (lambda () (open-input-file (string-append (car paths) "/" file))) (lambda args (find-file file (cdr paths)))))) (let ((file (cadr form))) (if (and (string? file) (not (member file loaded-files))) (let ((fp (catch #t (lambda () (open-input-file file)) (lambda args (or (find-file file *load-path*) (and (format outport " can't load ~S~%" file) #f)))))) (if (input-port? fp) (begin (set! loaded-files (cons file loaded-files)) ;(format outport " (scanning ~S)~%" file) (do ((form (read fp) (read fp))) ((eof-object? form)) (if (and (pair? form) (pair? (cdr form))) (load-walk form))) (close-input-port fp))))))) (define (binding-ok? name head binding env second-pass) ;; check let-style variable binding for various syntactic problems (if second-pass (and (pair? binding) (symbol? (car binding)) ;(not (keyword? (car binding))) (not (constant? (car binding))) (pair? (cdr binding)) (or (null? (cddr binding)) (and (eq? head 'do) (pair? (cddr binding)) ; (do ((i 0 . 1))...) (null? (cdddr binding))))) (cond ((not (pair? binding)) (lint-format "~A binding is not a list? ~S" name head binding) #f) ((not (symbol? (car binding))) (lint-format "~A variable is not a symbol? ~S" name head binding) #f) ((keyword? (car binding)) (lint-format "~A variable is a keyword? ~S" name head binding) #f) ((constant? (car binding)) (lint-format "can't bind a constant: ~S" name binding) #f) ((not (pair? (cdr binding))) (if (null? (cdr binding)) (lint-format "~A variable value is missing? ~S" name head binding) (lint-format "~A binding is an improper list? ~S" name head binding)) #f) ((or (not (pair? (cdr binding))) (and (pair? (cddr binding)) (or (not (eq? head 'do)) (pair? (cdddr binding))))) (lint-format "~A binding is messed up: ~A" name head binding) #f) (else (if (and *report-shadowed-variables* (or (hash-table-ref globals (car binding)) (var-member (car binding) env))) (lint-format "~A variable ~A in ~S shadows an earlier declaration" name head (car binding) binding)) #t)))) (define (env-difference name e1 e2 lst) (if (or (null? e1) (null? e2) (eq? (car e1) (car e2))) lst (env-difference name (cdr e1) e2 (if (eq? name (var-name (car e1))) lst (cons (car e1) lst))))) (define (report-usage name type head vars) ;; report unused or set-but-unreferenced variables (if (and (not (eq? head 'begin)) ; begin can redefine = set a variable (pair? vars) (proper-list? vars)) (do ((cur vars (cdr cur)) (rst (cdr vars) (cdr rst))) ((null? rst)) (let ((repeat (var-member (var-name (car cur)) rst))) ;; not globals here because the same name might be used as a global (if repeat (lint-format "~A ~A ~A is declared twice" name head type (var-name (car cur))))))) (let ((set ()) (unused ())) (for-each (lambda (arg) (if (hash-table-ref syntaces (var-name arg)) (lint-format "~A ~A named ~A is asking for trouble" name head type (var-name arg)) (if (not (symbol? (var-name arg))) (lint-format "bad ~A ~A name: ~S" name head type (var-name arg)))) (if (and (not (var-ref arg)) (not (hash-table-ref other-identifiers (var-name arg)))) (if (var-set arg) (set! set (cons (var-name arg) set)) (if (not (memq (var-name arg) '(documentation signature iterator?))) (set! unused (cons (var-name arg) unused)))))) vars) (if (pair? set) (lint-format "~A ~A~A ~{~A~^, ~} set, but not used" name head type (if (> (length set) 1) "s" "") (reverse set))) (if (pair? unused) (lint-format "~A ~A~A ~{~A~^, ~} not used" name head type (if (> (length unused) 1) "s" "") (reverse unused))))) (define (lint-walk-body name head body env) ;; walk a body (a list of forms, the value of the last of which might be returned) (if (not (proper-list? body)) (lint-format "stray dot? ~A" name (truncated-list->string body)) (let ((prev-f #f) (prev-fs #f) (prev-len 0) (f-len 0) (block-fs #f) (dpy-f #f) (dpy-start #f) (len (length body))) (if (eq? head 'do) (set! len (+ len 1))) ; last form in do body is not returned (do ((fs body (cdr fs)) (ctr 0 (+ ctr 1))) ((not (pair? fs))) (let ((f (car fs))) (if (pair? f) (begin (set! f-len (length f)) (if (eq? (car f) 'begin) (lint-format "redundant begin: ~A" name (truncated-list->string f)))) (set! f-len 0)) (if (and (= f-len prev-len 3) (eq? (car f) 'set!) (eq? (car prev-f) 'set!) (eq? (cadr f) (cadr prev-f))) (let ((arg1 (caddr prev-f)) (arg2 (caddr f))) (if (or (not (pair? arg2)) (not (tree-member (cadr f) arg2))) (if (and (not (side-effect? arg1 env)) (not (side-effect? arg2 env))) (lint-format "this could be omitted: ~A" name prev-f)) (if (and (pair? arg1) (pair? arg2) (eq? (car arg1) 'cons) (eq? (car arg2) 'cons) (eq? (cadr f) (caddr arg2)) (not (eq? (cadr f) (cadr arg2)))) (lint-format "perhaps ~A ~A -> ~A" name prev-f f `(set! ,(cadr f) (cons ,(cadr arg2) (cons ,@(cdr arg1))))))))) (let ((repeated-if (and (= f-len prev-len 3) (eq? (car f) 'if) (eq? (car prev-f) 'if) (equal? (cadr f) (cadr prev-f)))) (combine #f)) (if (not repeated-if) (if block-fs (if (not (eq? (cdr block-fs) prev-fs)) (set! combine prev-f) (set! block-fs #f))) (if block-fs (set! combine (and (null? (cdr fs)) f)) (set! block-fs prev-fs))) (when combine (if (not (side-effect? (caadr block-fs) env)) (lint-format "perhaps combine repeated if's: ~A ... ~A -> (when ~A ~A ... ~A)" name (car block-fs) combine (cadr combine) (caddar block-fs) (caddr combine))) (set! block-fs #f))) (if (< ctr (- len 1)) ;; f is not the last form, so its value is ignored (begin (if (and (pair? f) (eq? (car f) 'map)) (lint-format "map could be for-each: ~A" name (truncated-list->string f))) (if (not (side-effect? f env)) (lint-format "this could be omitted: ~A" name (truncated-list->string f)))) ;; here f is the last form in the body (when (and (pair? prev-f) (pair? (cdr prev-f)) (pair? (cddr prev-f))) ; (set! ((L 1) 2)) an error, but lint should keep going (if (and (eq? (car prev-f) 'set!) (or (and (equal? (caddr prev-f) f) ; (begin ... (set! x (...)) (...)) (not (side-effect? f env))) (and (symbol? f) ; (begin ... (set! x ...) x) (eq? f (cadr prev-f))))) (lint-format "this could be omitted: ~A" name (truncated-list->string f))) (if (and (pair? f) (pair? (cdr f)) (pair? (cddr f)) (eq? (cadr prev-f) (cadr f)) (or (and (eq? (car prev-f) 'vector-set!) (eq? (car f) 'vector-ref)) (and (eq? (car prev-f) 'list-set!) (eq? (car f) 'list-ref))) (equal? (caddr f) (caddr prev-f)) (pair? (cdddr prev-f)) (not (pair? (cddddr prev-f))) (not (pair? (cdddr f))) (not (side-effect? (caddr f) env))) (lint-format "this could be omitted: ~A" name (truncated-list->string f))))) (let ((dpy-case (and (pair? f) (memq (car f) '(display write newline write-char write-string))))) ; flush-output-port? (define (out-port expr) ; ()=not specified (*stdout*), #f=something is wrong (not enough args) (if (eq? (car expr) 'newline) (if (pair? (cdr expr)) (cadr expr) ()) (and (pair? (cdr expr)) (if (pair? (cddr expr)) (caddr expr) ())))) (when (and dpy-case (not dpy-start)) (set! dpy-f fs) (set! dpy-start ctr)) ;(format *stderr* "~A ~A ~A ~A~%" f ctr dpy-start len) (when (and dpy-start (> (- ctr dpy-start) (if dpy-case 1 2)) (or (= ctr (- len 1)) (not dpy-case))) ;; display sequence starts at dpy-start, goes to ctr (prev-f) unless not dpy-case (let ((ctrl-string "") (args ()) (dctr 0) (dpy-last (if (not dpy-case) prev-f f)) (op (out-port (car dpy-f))) (exprs (make-list (if dpy-case (- ctr dpy-start -1) (- ctr dpy-start)) ()))) ;(format *stderr* "~A: ~A ~A ~A ~A~%" body dpy-case dpy-start ctr dpy-last) (call-with-exit (lambda (done) (for-each (lambda (d) (if (not (equal? (out-port d) op)) (begin (lint-format "unexpected port change: ~A -> ~A in ~A~%" name op (out-port d) d) ; ?? (done))) (list-set! exprs dctr d) (set! dctr (+ dctr 1)) (case (car d) ((display) (if (string? (cadr d)) (set! ctrl-string (string-append ctrl-string (cadr d))) (begin (set! ctrl-string (string-append ctrl-string "~A")) (set! args (cons (cadr d) args))))) ((write) (if (string? (cadr d)) (set! ctrl-string (string-append ctrl-string "\"" (cadr d) "\"")) (begin (set! ctrl-string (string-append ctrl-string "~S")) (set! args (cons (cadr d) args))))) ((write-char) (if (char? (cadr d)) (set! ctrl-string (string-append ctrl-string (string (cadr d)))) (begin (set! ctrl-string (string-append ctrl-string "~C")) (set! args (cons (cadr d) args))))) ((write-string) ; same as display but with possible start|end indices (let ((indices (and (pair? (cddr d)) ; port (pair? (cdddr d)) (cdddr d)))) (if (string? (cadr d)) (if indices (if (and (integer? (car indices)) (or (null? (cdr indices)) (and (pair? indices) (integer? (cadr indices))))) (set! ctrl-string (string-append ctrl-string (apply substring (cadr d) indices))) (begin (set! ctrl-string (string-append ctrl-string "~A")) (set! args (cons `(substring ,(cadr d) ,@indices) args)))) (set! ctrl-string (string-append ctrl-string (cadr d)))) (begin (set! ctrl-string (string-append ctrl-string "~A")) (if indices (set! args (cons `(substring ,(cadr d) ,@indices) args)) (set! args (cons (cadr d) args))))))) ((newline) (set! ctrl-string (string-append ctrl-string "~%")))) (when (eq? d dpy-last) ; op can be null => send to (current-output-port), return #f or # (lint-format "perhaps ~A" name (lists->string exprs `(format ,op ,ctrl-string ,@(reverse args)))) (done))) dpy-f)))) (set! dpy-start #f)) (unless dpy-case (set! dpy-start #f))) (if (and (pair? f) (memq head '(defmacro defmacro* define-macro define-macro* define-bacro define-bacro*)) (tree-member 'unquote f)) (lint-format "~A probably has too many unquotes: ~A" name head (truncated-list->string f))) (set! prev-f f) (set! prev-fs fs) (set! prev-len f-len) (set! env (lint-walk name f env)))))) env) (define (lint-walk-function-body name head args arg-data body env) ;; walk function body, with possible doc string at the start (when (and (pair? body) (pair? (cdr body)) (string? (car body))) (if *report-doc-strings* (lint-format "old-style doc string: ~S~%" name (car body))) (set! body (cdr body))) ; ignore old-style doc-string (lint-walk-body name head body env) env) (define (lint-walk-function head name args val form env) ;(format *stderr* "function: ~A ~A ~A ~A~%" head name args val) ;; check out function arguments (adding them to the current env), then walk its body, (name == function name, val == body) ;; first check for (define (hi...) (ho...)) where ho has no opt args (and try to ignore possible string constant doc string) (if (eq? head 'define) (let ((bval (if (and (pair? val) (string? (car val))) (cdr val) ; strip away the (old-style) documentation string val))) (if (and (pair? bval) ; not (define (hi a) . 1)! (pair? (car bval)) (null? (cdr bval)) (symbol? (caar bval))) ; not (define (hi) ((if #f + abs) 0)) (if (equal? args (cdar bval)) (let* ((cval (caar bval)) (p (symbol->value cval *e*)) (ary (arity p))) (if (or (and (procedure? p) (or (= (car ary) (cdr ary)) (= (length args) (cdr ary)))) (let ((e (or (var-member cval env) (hash-table-ref globals cval)))) (and e (var? e) (let? (var-new e)) (let ((def ((var-new e) 'definition)) (e-args ((var-new e) 'arglist))) (and (pair? def) (eq? ((var-new e) 'type) 'define) (or (and (null? args) (null? e-args)) (and (symbol? args) (symbol? e-args)) (and (pair? args) (pair? e-args) (= (length args) (length e-args))))))))) (lint-format "~A could be (define ~A ~A)" name name name cval))) (if (and (eq? (caar bval) 'list-ref) (pair? (cdar bval)) (pair? (cddar bval)) (eq? (car args) (cadar bval)) (null? (cdr args))) (case (caddar bval) ((0) (lint-format "~A could be (define ~A car)" name name name)) ((1) (lint-format "~A could be (define ~A cadr)" name name name)) ((2) (lint-format "~A could be (define ~A caddr)" name name name)) ((3) (lint-format "~A could be (define ~A cadddr)" name name name)))))))) (let ((ldata (and (symbol? name) (make-var (if (not (memq head '(lambda lambda*))) name '[anonymous]) :new (inlet :type head :decl (catch #t (lambda () (case head ((lambda) (eval (list head (cadr form) #f))) ((lambda*) (eval (list head (copy (cadr form)) #f))) ; eval can remove :allow-other-keys! ((define*) (eval (list head (cons '_ (copy (cdadr form))) #f))) ((defmacro defmacro*) (eval (list head '_ (caddr form) #f))) ((define-constant) (eval (list 'define (cons '_ (cdadr form)) #f))) (else (eval (list head (cons '_ (cdadr form)) #f))))) (lambda args 'error)) :signature #f :side-effect #t :arglist (if (memq head '(defmacro defmacro*)) (caddr form) (if (memq head '(lambda lambda*)) (cadr form) (cdadr form))) :definition form :location #__line__))))) (if (null? args) (begin (if (memq head '(define* lambda* defmacro* define-macro* define-bacro*)) (lint-format "~A could be ~A" name head (symbol (substring (symbol->string head) 0 (- (length (symbol->string head)) 1))))) (lint-walk-function-body name head args () val env) (if ldata (append (list ldata) env) env)) (if (or (symbol? args) (pair? args)) (let ((arg-data (if (symbol? args) ; this is getting arg names to add to the environment (list (make-var args)) (map (lambda (arg) (if (symbol? arg) (if (memq arg '(:rest :allow-other-keys)) (values) ; map omits this entry (make-var arg)) (if (or (not (pair? arg)) (not (= (length arg) 2)) (not (memq head '(define* lambda* defmacro* define-macro* define-bacro* definstrument)))) (begin (lint-format "strange parameter for ~A: ~S" name head arg) (values)) (begin (if (not (cadr arg)) (lint-format "the default argument value is #f in ~A ~A" name head arg)) (make-var (car arg)))))) (proper-list args))))) (lint-walk-function-body name head args arg-data val (append arg-data (if ldata (append (list ldata) env) env))) (if *report-unused-parameters* (report-usage name 'parameter head arg-data)) (if ldata (append (list ldata) env) env)) (begin (lint-format "strange ~A parameter list ~A" name head args) env))))) (define (lint-walk name form env) ;; walk a form ;(format *stderr* "walk ~A, env: ~A~%~%" form env) (if (symbol? form) (set-ref? form env) ; returns env (if (pair? form) (let ((head (car form))) (define (defmacro-case) ;; ---------------- defmacro ---------------- (if (or (< (length form) 4) (not (symbol? (cadr form)))) (lint-format "~A declaration is messed up: ~A" name head (truncated-list->string form)) (let ((sym (cadr form)) (args (caddr form)) (body (cdddr form))) (if (and (pair? args) (repeated-member? args env)) (lint-format "~A parameter is repeated: ~A" name head (truncated-list->string args))) (lint-walk-function head sym args body form env)))) (define (define-case) ;; ---------------- define ---------------- (if (< (length form) 2) (begin (lint-format "~S makes no sense" name form) env) (let ((sym (cadr form)) (val (cddr form))) (if (symbol? sym) (begin ;(set! env (cons (list (make-var sym :typ (->type val))) env)) (if (keyword? sym) (lint-format "keywords are constants ~A" name sym)) (if (memq head '(define define-constant define-envelope)) (let ((len (length form))) (if (not (= len 3)) (lint-format "~S has ~A value~A?" name form (if (< len 3) "no" "too many") (if (< len 3) "" "s")))) (lint-format "~A is messed up" name (truncated-list->string form))) (if (and (pair? val) (null? (cdr val)) (equal? sym (car val))) (lint-format "this ~A is either not needed, or is an error: ~A" name head (truncated-list->string form))) (if (pair? (cddr form)) (let ((e (lint-walk sym (caddr form) env))) (if (and (pair? e) (eq? (var-name (car e)) '[anonymous])) ; (define x (lambda ...)) but it misses closures (set! (var-name (car e)) sym) (append (list (make-var sym)) env))) (append (list (make-var sym)) env))) ;; not (symbol? sym) (if (and (pair? sym) (not (pair? (car sym)))) (begin (when (pair? (cdr sym)) (if (repeated-member? (proper-list (cdr sym)) env) (lint-format "~A parameter is repeated: ~A" name head (truncated-list->string sym))) (if (memq head '(define* define-macro* define-bacro*)) (check-star-parameters name (cdr sym)) (if (list-any? keyword? (cdr sym)) (lint-format "~A arglist can't handle keywords" name head)))) (if (and (eq? head 'definstrument) (string? (car val))) (set! val (cdr val))) (if (keyword? (car sym)) (begin (lint-format "keywords are constants ~A" name (car sym)) env) (lint-walk-function head (car sym) (cdr sym) val form env))) (begin (lint-format "strange form: ~S" head form) env)))))) (define (generator-case) ;; ---------------- defgenerator ---------------- (get-generator form name head) env) (define (lambda-case) ;; ---------------- lambda ---------------- ;; the lambda case includes stuff like call/cc? (let ((len (length form))) (if (< len 3) (begin (lint-format "~A is messed up in ~A" name head (truncated-list->string form)) env) (let ((args (cadr form))) (if (list? args) (let ((arglen (length args))) (if (null? args) (if (eq? head 'lambda*) ; (lambda* ()...) -> (lambda () ...) (lint-format "lambda* could be lambda: ~A" name form)) (begin ; args is a pair ; (lambda (a a) ...) (if (repeated-member? (proper-list args) env) (lint-format "~A parameter is repeated: ~A" name head (truncated-list->string args))) (if (eq? head 'lambda*) ; (lambda* (a :b) ...) (check-star-parameters name args) (if (list-any? keyword? args) ; (lambda (:key) ...) (lint-format "lambda arglist can't handle keywords (use lambda*)" name))))) (if (and (eq? head 'lambda) ; (lambda () (f)) -> f, (lambda (a b) (f a b)) -> f (= len 3) (>= arglen 0)) ; not a dotted list (let ((body (caddr form))) (when (and (pair? body) (symbol? (car body))) (if (equal? args (cdr body)) (lint-format "perhaps ~A" name (lists->string form (car body))) (if (equal? (reverse args) (cdr body)) (let ((rf (reversed (car body)))) (if rf (lint-format "perhaps ~A" name (lists->string form rf)))))))))) (if (and (symbol? args) ; (lambda args (apply f args)) -> f (eq? head 'lambda) (= len 3)) (let ((body (caddr form))) (if (and (pair? body) (= (length body) 3) (eq? (car body) 'apply) (symbol? (cadr body)) (eq? args (caddr body))) (lint-format "perhaps ~A" name (lists->string form (cadr body))))))) (lint-walk-function head name args (cddr form) form env) env)))) (define (set-case) ;; ---------------- set! ---------------- (if (not (= (length form) 3)) (begin (lint-format "set! has too ~A arguments: ~S" name (if (> (length form) 3) "many" "few") form) env) (let ((settee (cadr form)) (setval (caddr form))) (let ((result (lint-walk name setval env))) ;(format *stderr* "result: ~A, env: ~A~%" result env) (if (symbol? settee) (if (constant? settee) (lint-format "can't set! ~A (it is a constant)" name (truncated-list->string form))) (if (pair? settee) (begin (if (memq (car settee) '(vector-ref list-ref string-ref hash-table-ref)) (lint-format "~A as target of set!~A" name (car settee) (truncated-list->string form))) (lint-walk name settee env) ; this counts as a reference since it's by reference so to speak ;; try type check (dilambda signatures) (when (symbol? (car settee)) (let ((f (symbol->value (car settee) *e*))) (when (dilambda? f) (let ((sig (procedure-signature (procedure-setter f))) (settee-len (length settee))) (when (and (pair? sig) (positive? settee-len) (pair? (list-tail sig settee-len))) (let ((checker (list-ref sig settee-len)) (arg-type (->type setval))) (when (and (not (eq? 'symbol? arg-type)) (symbol? checker) (not (compatible? checker arg-type))) (lint-format "~A: new value should be a~A ~A: ~S: ~A" name (car settee) (if (char=? (string-ref (format #f "~A" checker) 0) #\i) "n" "") checker arg-type (truncated-list->string form))))))))) (set! settee (do ((sym (car settee) (car sym))) ((not (pair? sym)) sym)))) (lint-format "can't set! ~A" name (truncated-list->string form)))) (when (symbol? settee) ; see do above (set-set? settee setval env)) (if (equal? (cadr form) (caddr form)) ; not settee and setval here! (lint-format "pointless set!~A" name (truncated-list->string form))) result)))) (define (quote-case) ;; ---------------- quote ---------------- (let ((len (length form))) (if (negative? len) (lint-format "stray dot in quote's arguments? ~S" name form) (if (not (= len 2)) (lint-format "quote has too ~A arguments: ~S" name (if (> (length form) 2) "many" "few") form) (if (and (< quote-warnings 20) (or (number? (cadr form)) (boolean? (cadr form)) (string? (cadr form)) (vector? (cadr form)) (null? (cadr form)) (memq (cadr form) '(# # #)))) (begin (set! quote-warnings (+ quote-warnings 1)) (lint-format "quote is not needed here: ~A~A" name (truncated-list->string form) (if (= quote-warnings 20) "; will ignore this error henceforth." ""))))))) env) (define (cond-case) ;; ---------------- cond ---------------- (let ((ctr 0) (len (- (length form) 1))) (if (negative? len) (lint-format "cond is messed up: ~A" name (truncated-list->string form)) (let ((exprs ()) (result :unset) (has-else #f) (has-combinations #f) (falses ()) (prev-clause #f)) (for-each (lambda (clause) (set! ctr (+ ctr 1)) (if (and prev-clause (not has-combinations) (> len 2) (pair? clause) (equal? (cdr clause) (cdr prev-clause))) (if (memq (car clause) '(else #t)) ; (cond ... (x z) (else z)) -> (cond ... (else z)) (if (not (side-effect? (car prev-clause) env)) (lint-format "this clause could be omitted: ~A" name prev-clause)) (set! has-combinations #t))) ; handle these later (set! prev-clause clause) (if (not (pair? clause)) (begin (lint-format "cond clause is messed up: ~A" name (truncated-list->string clause)) (set! has-combinations #f)) (let ((expr (simplify-boolean (car clause) () falses env)) (test (car clause)) (sequel (cdr clause))) (when (memq test '(else #t)) (set! has-else #t) (if (and (pair? sequel) (pair? (car sequel)) (null? (cdr sequel)) (eq? (caar sequel) 'cond)) (lint-format "else clause cond could be folded into the outer cond: ~A" name (truncated-list->string clause)))) (if (never-false expr) (if (not (= ctr len)) (lint-format "cond test is never false: ~A" name form) (if (and (not (memq expr '(#t else))) (not (side-effect? test env))) (lint-format "cond last test could be #t: ~A" name form))) (if (never-true expr) (lint-format "cond test is never true: ~A" name form))) (if (not (side-effect? test env)) (begin (if (and (not (memq test '(else #t))) (pair? sequel) (null? (cdr sequel))) (if (equal? test (car sequel)) (lint-format "no need to repeat the test: ~A" name (lists->string clause (list test))) (if (and (pair? (car sequel)) (pair? (cdar sequel)) (null? (cddar sequel)) (equal? test (cadar sequel))) (lint-format "perhaps use => here: ~A" name (lists->string clause (list test '=> (caar sequel))))))) (if (member test exprs) (lint-format "cond test repeated: ~A" name (truncated-list->string clause)) (set! exprs (cons test exprs))))) (if (boolean? expr) (if (not expr) (lint-format "cond test is always false: ~A" name (truncated-list->string clause)) (if (not (= ctr len)) (lint-format "cond #t clause is not the last: ~A" name (truncated-list->string form)))) (if (eq? test 'else) (if (not (= ctr len)) (lint-format "cond else clause is not the last: ~A" name (truncated-list->string form))) (lint-walk name test env))) (if (eq? result :unset) (set! result sequel) (if (not (equal? result sequel)) (set! result :unequal))) (if (pair? sequel) (if (eq? (car sequel) '=>) (if (or (not (pair? (cdr sequel))) (pair? (cddr sequel))) (lint-format "cond => target is messed up: ~A" name (truncated-list->string clause)) (let ((f (cadr sequel))) (if (symbol? f) (let ((val (symbol->value f *e*))) (if (procedure? val) (if (not (aritable? val 1)) ; here values might be in test expr (lint-format "=> target (~A) may be unhappy: ~A" name f clause)))) (if (and (pair? f) (eq? (car f) 'lambda) (pair? (cdr f)) (pair? (cadr f)) (not (= (length (cadr f)) 1))) (lint-format "=> target (~A) may be unhappy: ~A" name f clause))) (lint-walk name f env))) (lint-walk-body name head sequel env)) (if (not (null? sequel)) ; (not (null?...)) here is correct -- we're looking for stray dots (lint is confused) (lint-format "cond clause is messed up: ~A" name (truncated-list->string clause)))) (if (not (side-effect? expr env)) (set! falses (cons expr falses)) (set! result :unequal))))) (cdr form)) (if (and has-else (pair? result)) ; all result clauses are the same (and not implicit) (if (null? (cdr result)) (lint-format "perhaps ~A" name (lists->string form (car result))) (lint-format "perhaps ~A" name (lists->string form `(begin ,@result))))) (if (= len 2) (let ((c1 (cadr form)) (c2 (caddr form))) (if (and (pair? c1) (= (length c1) 2) (pair? c2) (= (length c2) 2) (boolean? (cadr c1)) (boolean? (cadr c2)) (memq (car c2) '(#t else))) (if (equal? (cadr c1) (cadr c2)) (if (not (side-effect? (car c1) env)) (lint-format "perhaps ~A" name (lists->string form (cadr c1)))) (if (eq? (cadr c1) #t) (lint-format "perhaps ~A" name (lists->string form (car c1))) (lint-format "perhaps ~A" name (lists->string form `(not ,(car c1))))))))) (when has-combinations (let ((new-clauses ()) (current-clauses ())) (do ((clauses (cdr form) (cdr clauses))) ((null? clauses) (lint-format "perhaps ~A" name (lists->string form `(cond ,@(reverse new-clauses))))) (let* ((clause (car clauses)) (result (cdr clause))) ; can be null in which case the test is the result (if (and (pair? (cdr clauses)) (equal? result (cdar (cdr clauses)))) (set! current-clauses (cons clause current-clauses)) (if (pair? current-clauses) (begin (set! current-clauses (cons clause current-clauses)) (set! new-clauses (cons (cons (simplify-boolean `(or ,@(map car (reverse current-clauses))) () () env) result) new-clauses)) (set! current-clauses ())) (set! new-clauses (cons clause new-clauses)))))))))) env)) (define (case-case) ;; ---------------- case ---------------- ;; here the keys are not evaluated, so we might have a list like (letrec define ...) ;; also unlike cond, only 'else marks a default branch (not #t) (if (< (length form) 3) (lint-format "case is messed up: ~A" name (truncated-list->string form)) (let ((sel-type #t) (selector (cadr form))) (if (and (not (pair? selector)) (constant? selector)) (lint-format "case selector is a constant: ~A" name (truncated-list->string form))) (lint-walk name selector env) (if (and (pair? selector) (symbol? (car selector))) (begin (set! sel-type (return-type (car selector))) (if (and (symbol? sel-type) (not (memq sel-type selector-types))) (lint-format "case selector may not work with eqv: ~A" name (truncated-list->string selector))))) (let ((all-keys ()) (all-exprs ()) (ctr 0) (result :unset) (exprs-repeated #f) (else-foldable #f) (has-else #f) (len (length (cddr form)))) (for-each (lambda (clause) (set! ctr (+ ctr 1)) (if (not (pair? clause)) (lint-format "case clause should be a list: ~A" name (truncated-list->string clause)) (let ((keys (car clause)) (exprs (cdr clause))) (if (null? exprs) (lint-format "clause result is missing: ~A" name clause)) (if (eq? result :unset) (set! result exprs) (if (not (equal? result exprs)) (set! result :unequal))) (if (member exprs all-exprs) (set! exprs-repeated exprs) (set! all-exprs (cons exprs all-exprs))) (if (and (pair? exprs) (null? (cdr exprs)) (pair? (car exprs)) (pair? (cdar exprs)) (null? (cddar exprs)) (equal? selector (cadar exprs))) (lint-format "perhaps use => here: ~A" name (lists->string clause (list keys '=> (caar exprs))))) (if (pair? keys) (if (not (proper-list? keys)) (if (null? keys) (lint-format "null case key list: ~A" name (truncated-list->string clause)) (lint-format "stray dot in case case key list: ~A" name (truncated-list->string clause))) (for-each (lambda (key) (if (or (vector? key) (string? key) (pair? key) (hash-table? key)) (lint-format "case key ~S in ~S is unlikely to work (case uses eqv?)" name key clause)) (if (member key all-keys) (lint-format "repeated case key ~S in ~S" name key clause) (set! all-keys (cons key all-keys))) ;; unintentional quote here, as in (case x ('a b)...) never happens and ;; is hard to distinguish from (case x ((quote a) b)...) which happens a lot (if (not (compatible? sel-type (->type key))) (lint-format "case key ~S in ~S is pointless" name key clause))) keys)) (if (not (eq? keys 'else)) (lint-format "bad case key ~S in ~S" name keys clause) (begin (set! has-else clause) ;; exprs: (res) or if case, ((case ...)...) (if (not (= ctr len)) (lint-format "case else clause is not the last: ~A" name (truncated-list->string (cddr form))) (when (and (pair? exprs) (pair? (car exprs)) (null? (cdr exprs)) ; just the case statement in the else clause (eq? (caar exprs) 'case) (equal? selector (cadar exprs)) (not (side-effect? selector env))) (set! else-foldable (cddar exprs))))))) (lint-walk-body name head exprs env)))) (cddr form)) (if (and has-else (pair? result) (not else-foldable)) (begin (if (null? (cdr result)) (lint-format "perhaps ~A" name (lists->string form (car result))) (lint-format "perhaps ~A" name (lists->string form `(begin ,@result)))) (set! exprs-repeated #f))) (when (or exprs-repeated else-foldable) (let* ((new-keys-and-exprs ()) (else-clause (if else-foldable (call-with-exit (lambda (return) (for-each (lambda (c) (if (eq? (car c) 'else) (return c))) else-foldable) ())) (or has-else ()))) (else-exprs (and (pair? else-clause) (cdr else-clause)))) (define (merge-case-keys clause) ;(format *stderr* "clause: ~S~%" clause) (let ((keys (car clause)) (exprs (cdr clause))) (when (and (pair? exprs) ; ignore clauses that are messed up (not (eq? keys 'else)) (not (equal? exprs else-exprs))) (let ((prev (member exprs new-keys-and-exprs (lambda (a b) (equal? a (cdr b)))))) (if prev (let* ((cur-clause (car prev)) (cur-keys (car cur-clause))) (when (pair? cur-keys) (set-car! cur-clause (append cur-keys (map (lambda (key) (if (memv key cur-keys) (values) key)) keys))))) (set! new-keys-and-exprs (cons (cons (copy (car clause)) (cdr clause)) new-keys-and-exprs))))))) (for-each merge-case-keys (cddr form)) (if else-foldable (for-each merge-case-keys else-foldable)) ;(format *stderr* "~%~A -> new: ~A, else: ~A~%" form new-keys-and-exprs else-clause) (if (null? new-keys-and-exprs) (if (or (null? else-clause) ; can this happen? (it's caught above as an error) (null? (cdr else-clause))) (lint-format "perhaps ~A" name (lists->string form ())) (if (null? (cddr else-clause)) (lint-format "perhaps ~A" name (lists->string form (cadr else-clause))) (lint-format "perhaps ~A" name (lists->string form `(begin ,@(cdr else-clause)))))) (lint-format "perhaps ~A" name (lists->string form (if (pair? else-clause) `(case ,(cadr form) ,@(reverse new-keys-and-exprs) ,else-clause) `(case ,(cadr form) ,@(reverse new-keys-and-exprs))))))))))) env) (define (do-case) ;; ---------------- do ---------------- (let ((vars ())) (if (or (< (length form) 3) (not (proper-list? (cadr form))) (not (proper-list? (caddr form)))) (lint-format "do is messed up: ~A" name (truncated-list->string form)) (let ((step-vars (cadr form))) (if (not (side-effect? form env)) (let ((end+result (caddr form))) (if (or (not (pair? end+result)) (null? (cdr end+result))) (lint-format "this do-loop could be replaced by (): ~A" name (truncated-list->string form)) (if (and (null? (cddr end+result)) (code-constant? (cadr end+result))) (lint-format "this do-loop could be replaced by ~A: ~A" name (cadr end+result) (truncated-list->string form)))))) ;; walk the init forms before adding the step vars to env (do ((bindings step-vars (cdr bindings))) ((not (pair? bindings)) (if (pair? bindings) (lint-format "do variable list is not a proper list? ~S" name step-vars))) (if (binding-ok? name head (car bindings) env #f) (begin (lint-walk name (cadar bindings) env) (set! vars (append (list (make-var :name (caar bindings) :typ (->type (cadar bindings)) :val (and (pair? (cddar bindings)) (caddar bindings)))) vars))))) ;; walk the step exprs (do ((bindings step-vars (cdr bindings))) ((not (pair? bindings))) (let ((stepper (car bindings))) ; the entire binding: '(i 0 (+ i 1)) (when (and (binding-ok? name head stepper env #t) (pair? (cddr stepper))) (lint-walk name (caddr stepper) (append vars env)) (if (eq? (car stepper) (caddr stepper)) ; (i 0 i) -> (i 0) (lint-format "perhaps ~A" name (lists->string stepper (list (car stepper) (cadr stepper))))) (let ((data (var-member (car stepper) vars))) (set! (var-ref data) #f)) (when (and (pair? (caddr stepper)) (not (eq? (car stepper) (cadr stepper))) ; (lst lst (cdr lst)) (eq? (car (caddr stepper)) 'cdr) (eq? (cadr stepper) (cadr (caddr stepper)))) (lint-format "this looks suspicious: ~A" name stepper))))) ;; walk the body and end stuff (it's too tricky to find infinite do loops) (if (pair? (caddr form)) (let ((end+result (caddr form))) (lint-walk-body name head (cddr form) (append vars env)) (if (pair? end+result) (let ((end (car end+result))) (if (and (symbol? end) (memq end '(= > < >= <= null? not))) (lint-format "perhaps missing parens: ~A" name end+result)) (if (never-false end) (lint-format "end test is never false: ~A" name end) (if end ; it's not #f (if (never-true end) (lint-format "end test is never true: ~A" name end) (let ((v (and (pair? end) (memq (car end) '(< > <= >=)) (pair? (cdr end)) (symbol? (cadr end)) (member (cadr end) vars (lambda (a b) (eq? a (var-name b))))))) ;; if found, v is the var info (when (pair? v) (let ((step (var-value (car v)))) (when (pair? step) (let ((inc (and (memq (car step) '(+ -)) (pair? (cdr step)) (pair? (cddr step)) (or (and (real? (cadr step)) (cadr step)) (and (real? (caddr step)) (caddr step)))))) (when (real? inc) (if (or (and (eq? (car step) '+) (positive? inc) (memq (car end) '(< <=))) (and (eq? (car step) '-) (positive? inc) (memq (car end) '(> >=)))) (lint-format "do step looks like it doesn't match end test: ~A" name (lists->string step end)))))))))) (if (pair? (cdr end+result)) (lint-format "result is unreachable: ~A" name end+result))))))) (lint-walk-body name head (cdddr form) (append vars env))) ;; before report-usage, check for unused variables, and don't complain about them if ;; they are referenced in an earlier step expr?(!) (do ((v vars (cdr v))) ((null? v)) (let ((var (car v))) (unless (var-ref var) ;; var was not seen in the end+result/body or any subsequent step exprs ;; vars is reversed order, so we need only scan var-value of the rest (if (side-effect? (var-value var) env) (set! (var-ref var) #t) (for-each (lambda (nv) (if (or (eq? (var-name var) (var-value nv)) (and (pair? (var-value nv)) (tree-member (var-name var) (var-value nv)))) (set! (var-ref var) #t))) (cdr v)))))) (report-usage name 'variable head vars) ;; check for do-loop as copy/fill! stand-in (let ((end-test (and (pair? (caddr form)) (caaddr form))) (body (cdddr form)) (setv #f)) (when (and (pair? end-test) (= (length vars) 1) (= (length body) 1) (pair? (car body)) (memq (caar body) '(vector-set! float-vector-set! int-vector-set! list-set! string-set!)) (eq? (var-type (car vars)) 'integer?) (eq? (car end-test) '=) (eq? (cadr end-test) (var-name (car vars))) (eq? (caddar body) (var-name (car vars))) (let ((val (car (cdddar body)))) (set! setv val) (or (code-constant? val) (and (pair? val) (memq (car val) '(vector-ref float-vector-ref int-vector-ref list-ref string-ref)) (eq? (caddr val) (var-name (car vars))))))) (if (code-constant? setv) (lint-format "perhaps ~A" name (lists->string form `(fill! ,(cadar body) ,(car (cdddar body)) 0 ,(caddr end-test)))) (lint-format "perhaps ~A" name (lists->string form `(copy ,(cadr setv) ,(cadar body) 0 ,(caddr end-test))))))))) env)) (define (let-case) ;; ---------------- let ---------------- (if (or (< (length form) 3) (and (not (symbol? (cadr form))) (not (list? (cadr form))))) (lint-format "let is messed up: ~A" name (truncated-list->string form)) (let ((named-let (and (symbol? (cadr form)) (cadr form)))) (if (keyword? named-let) (lint-format "bad let name: ~A" name named-let)) (unless named-let ;; this could be extended to other such cases (or (any? (lambda (var) (or (not (pair? var)) (not (pair? (cdr var))) (not (code-constant? (cadr var))))) (cadr form)) (any? (lambda (expr) (side-effect? expr env)) (cddr form)) (catch #t (lambda () (let ((val (eval (copy-tree form) (rootlet)))) (lint-format "perhaps ~A" name (lists->string form val)))) (lambda args 'error)))) (let ((vars (if (and named-let (not (keyword? named-let)) (or (null? (caddr form)) (and (proper-list? (caddr form)) (every? pair? (caddr form))))) (list (make-var named-let :new (inlet :type head :decl (eval (list 'define (cons '_ (map car (caddr form))) #f)) :signature #f :side-effect #t :arglist (map car (caddr form)) :definition form :location #__line__))) ; TODO: named-let* ())) (varlist (if named-let (caddr form) (cadr form))) (body (if named-let (cdddr form) (cddr form)))) (if (not (list? varlist)) (lint-format "let is messed up: ~A" name (truncated-list->string form)) (if (and (null? varlist) (pair? body) (null? (cdr body)) (not (side-effect? (car body) env))) (lint-format "perhaps ~A" name (lists->string form (car body))))) (do ((bindings varlist (cdr bindings))) ((not (pair? bindings)) (if (pair? bindings) (lint-format "let variable list is not a proper list? ~S" name varlist))) (if (binding-ok? name head (car bindings) env #f) (let ((val (cadar bindings))) (if (and (pair? val) (eq? 'lambda (car val)) (not (hash-table-ref globals (caar bindings))) (tree-car-member (caar bindings) val) (not (var-member (caar bindings) env))) (lint-format "let variable ~A is called in its binding? Perhaps let should be letrec: ~A" name (caar bindings) (truncated-list->string bindings))) (lint-walk name val env) ;; can we tell its type and (as long as not set) check for type errors? ;; need a function that turns a constant into a type indication, ;; then append that as the 4th entry below (used only in do?) ;; then use that in arg checks if arg is a known var (set! vars (append (list (make-var (caar bindings) :val val :typ (->type val))) vars))))) ;; each var is (sym ref set opt-type-data new) (let* ((cur-env (append vars env)) (e (lint-walk-body name head body cur-env)) (nvars (if (null? cur-env) e (and (not (eq? e cur-env)) (env-difference name e cur-env ()))))) ;(format *stderr* "nvars: ~A e: ~A~%" nvars e) (if (pair? nvars) (if (eq? (var-name (car nvars)) '[anonymous]) (begin (set! env (cons (car nvars) env)) (set! nvars (cdr nvars))) (set! vars (append nvars vars))))) (report-usage name 'variable head vars)))) env) (define (let*-case) ;; ---------------- let* ---------------- (if (< (length form) 3) (lint-format "let* is messed up: ~A" name (truncated-list->string form)) (let ((named-let (and (symbol? (cadr form)) (cadr form)))) (let ((vars (if named-let (list (make-var named-let)) ())) (varlist (if named-let (caddr form) (cadr form))) (side-effects #f)) (if (not (list? varlist)) (lint-format "let* is messed up: ~A" name (truncated-list->string form))) (do ((bindings varlist (cdr bindings))) ((not (pair? bindings)) (if (pair? bindings) (lint-format "let* variable list is not a proper list? ~S" name (if named-let (caddr form) (cadr form))))) (if (binding-ok? name head (car bindings) env #f) (begin (if (not side-effects) (set! side-effects (side-effect? (cadar bindings) env))) (lint-walk name (cadar bindings) (append vars env)) (set! vars (append (list (make-var (caar bindings) :val (cadar bindings) :typ (->type (cadar bindings)))) vars))))) (if (and (not side-effects) (not (any? var-ref vars))) (lint-format "let* could be let: ~A" name (truncated-list->string form))) ;; in s7, let evaluates var values top down, so this message is correct ;; even in cases like (let ((ind (open-sound...)) (mx (maxamp))) ...) ;; in r7rs, the order is not specified (section 4.2.2 of the spec), so ;; here we would restrict this message to cases where there is only ;; one variable, or where subsequent values are known to be independent. ;; if each function could tell us what globals it depends on or affects, ;; we could make this work in all cases. (let* ((cur-env (append vars env)) (e (lint-walk-body name head (if named-let (cdddr form) (cddr form)) cur-env)) (nvars (and (not (eq? e cur-env)) (env-difference name e cur-env ())))) (if (pair? nvars) (set! vars (append nvars vars)))) (report-usage name 'variable head vars)))) env) (define (letrec-case) ;; ---------------- letrec ---------------- (if (< (length form) 3) (lint-format "~A is messed up: ~A" name head (truncated-list->string form)) (let ((vars ())) (if (null? (cadr form)) (lint-format "~A could be let: ~A" name head (truncated-list->string form)) (if (not (pair? (cadr form))) (lint-format "~A is messed up: ~A" name head (truncated-list->string form)) (if (and (null? (cdadr form)) (eq? head 'letrec*)) ; this happens all the time! (lint-format "letrec* could be letrec? ~A" name (truncated-list->string form))))) (do ((bindings (cadr form) (cdr bindings))) ((not (pair? bindings)) (if (pair? bindings) (lint-format "letrec variable list is not a proper list? ~S" name (cadr form)))) (if (binding-ok? name head (car bindings) env #f) (set! vars (append (list (make-var (caar bindings) :val (cadar bindings) :typ (->type (cadar bindings)))) vars)))) (let ((new-env (append vars env))) (do ((bindings (cadr form) (cdr bindings))) ((not (pair? bindings))) (if (binding-ok? name head (car bindings) env #t) (lint-walk name (cadar bindings) new-env))) (let* ((cur-env (append vars env)) (e (lint-walk-body name head (cddr form) cur-env)) (nvars (and (not (eq? e cur-env)) (env-difference name e cur-env ())))) (if (pair? nvars) (set! vars (append nvars vars))))) (report-usage name 'variable head vars))) env) (define (begin-case) ;; ---------------- begin ---------------- (if (not (proper-list? form)) (begin (lint-format "stray dot in begin? ~A" name (truncated-list->string form)) env) (begin (if (and (pair? (cdr form)) (null? (cddr form))) (lint-format "begin could be omitted: ~A" name (truncated-list->string form))) (lint-walk-body name head (cdr form) env))) env) (define (when-case) ;; -------- when, unless -------- (if (< (length form) 3) (lint-format "~A is messed up: ~A" name head (truncated-list->string form)) (let ((test (cadr form))) (if (and (pair? test) (eq? (car test) 'not)) (lint-format "possible optimization: ~A -> ~A" name (truncated-list->string form) (truncated-list->string `(,(if (eq? head 'when) 'unless 'when) ,(cadr test) ,@(cddr form))))) (if (never-false test) (lint-format "~A test is never false: ~A" name head form) (if (never-true test) (lint-format "~A test is never true: ~A" name head form))) (if (symbol? test) (set-ref? test env) (if (pair? test) (lint-walk name test env))) (let* ((e (lint-walk-body name head (cddr form) env)) (vars (if (not (eq? e env)) (env-difference name e env ()) ()))) (report-usage name 'variable head vars)))) env) (define (with-let-case) ;; -------- with-let -------- (if (< (length form) 3) (lint-format "~A is messed up: ~A" head name (truncated-list->string form)) (let ((e (cadr form))) (if (or (and (code-constant? e) (not (let? e))) (and (symbol? e) (defined? e) (not (let? (symbol->value e)))) (and (pair? e) (let ((op (return-type (car e)))) (and op (not (return-type-ok? 'let? op)))))) (lint-format "~A: first argument should be an environment: ~A" head name (truncated-list->string form))) (if (symbol? e) (set-ref? e env) (if (pair? e) (begin (if (and (null? (cdr e)) (eq? (car e) 'curlet)) (lint-format "~A is not needed here: ~A" head name (truncated-list->string form))) (lint-walk name e env)))) (let ((walked #f)) (if (or (and (symbol? e) (memq e '(*gtk* *motif* *gl* *libc* *libm* *libgdbm* *libgsl*))) (and (pair? e) (eq? (car e) 'sublet) (pair? (cdr e)) (memq (cadr e) '(*gtk* *motif* *gl* *libc* *libm* *libgdbm* *libgsl*)) (set! e (cadr e)))) (let ((lib (if (not (defined? e)) (let ((file (*autoload* e))) (and (string? file) (load file))) (symbol->value e)))) (when (let? lib) (let ((old-e *e*)) (set! *e* lib) (let* ((e (lint-walk-body name head (cddr form) env)) (vars (if (not (eq? e env)) (env-difference name e env ()) ()))) (report-usage name 'variable head vars)) (set! *e* old-e) (set! walked #t))))) (unless walked (let* ((e (lint-walk-body name head (cddr form) env)) (vars (if (not (eq? e env)) (env-difference name e env ()) ()))) (report-usage name 'variable head vars)))))) env) (define (else-case) ;; ---------------- everything else ---------------- (if (not (proper-list? form)) (begin ;; these appear to be primarily macro arguments (if (and (pair? form) (symbol? (car form)) (procedure? (symbol->value (car form) *e*))) (lint-format "unexpected dot: ~A" name (truncated-list->string form))) env) (begin (when (symbol? head) (check-call name head form env) (if (not (or (hash-table-ref globals head) (var-member head env))) (check-special-cases name head form env)) (if (assq head deprecated-ops) (lint-format "~A is deprecated; use ~A" name head (cdr (assq head deprecated-ops)))) (if (and (not (= line-number last-simplify-numeric-line-number)) (not (hash-table-ref globals head)) (hash-table-ref numeric-ops head) (not (var-member head env))) (let ((val (simplify-numerics form env))) (if (not (equal-ignoring-constants? form val)) (begin (set! last-simplify-numeric-line-number line-number) (lint-format "perhaps ~A" name (lists->string form val)))))) ;; if we loaded this file first, and f (head) is defined (e.g. scan above), ;; and it is used before it is defined, but not thereafter, the usage stuff ;; can get confused, so other-identifiers is trying to track those. (if (and (not (hash-table-ref other-identifiers head)) (not (defined? head start-up-let))) (hash-table-set! other-identifiers head #t))) (when (and (pair? head) (> (length head) 0) (eq? (car head) 'lambda)) (if (and (proper-list? (cadr head)) (not (= (length (cadr head)) (length (cdr form))))) (lint-format "~A has ~A arguments: ~A" head (car head) (if (> (length (cadr head)) (length (cdr form))) "too few" "too many") (truncated-list->string form)))) (let ((vars env)) (for-each (lambda (f) (set! vars (lint-walk name f vars))) form)) )) env) (set! line-number (pair-line-number form)) (case head ((define define* define-constant define-envelope define-expansion define-macro define-macro* define-bacro define-bacro* definstrument defanimal) (define-case)) ((lambda lambda*) (lambda-case)) ((set!) (set-case)) ((quote) (quote-case)) ((cond) (cond-case)) ((case) (case-case)) ((do) (do-case)) ((let) (let-case)) ((let*) (let*-case)) ((letrec letrec*) (letrec-case)) ((begin) (begin-case)) ((when unless) (when-case)) ((with-let) (with-let-case)) ((defmacro defmacro*) (defmacro-case)) ((defgenerator) (generator-case)) ((define-syntax let-syntax letrec-syntax define-module) ; all meaningless in s7 ;; actually the real problem with checking other schemes' code is that they use a large number ;; of non-standard # and \ forms. The # forms can mostly be kludged up via #*readers, but I'm ;; not going to start building in all the crazy \ stuff. ;; Some schemes use the execrable [] substitutes for () -- Gauche in particular. env) (else (else-case)))) ;; else form is not a symbol and not a pair env))) ;;; -------------------------------------------------------------------------------- (let ((documentation "(lint file port) looks for infelicities in file's scheme code")) (lambda* (file (outp *lint-output-port*) (report-input #t)) (set! outport outp) (set! globals (make-hash-table)) (set! other-identifiers (make-hash-table)) (set! loaded-files ()) (set! last-simplify-boolean-line-number -1) (set! last-simplify-numeric-line-number -1) (set! last-checker-line-number -1) (set! line-number -1) (set! quote-warnings 0) ;(format *stderr* "lint ~S~%" file) (let ((fp (if (input-port? file) file (begin (set! *current-file* file) (if *load-file-first* ; this can improve the error checks (load file)) (catch #t (lambda () (let ((p (open-input-file file))) (if report-input (format outport ";~A~%" file)) (set! loaded-files (cons file loaded-files)) p)) (lambda args (format outport " can't open ~S: ~A~%" file (apply format #f (cadr args))) #f)))))) (if (input-port? fp) (let ((vars ()) (line 0) (last-form #f) (last-line-number -1)) (do ((form (read fp) (read fp))) ((eof-object? form)) (if (pair? form) (set! line (max line (pair-line-number form)))) (if (and (not (= last-line-number -1)) (not (side-effect? last-form vars))) (format outport " top-level (line ~D): this has no effect: ~A~%" last-line-number (truncated-list->string last-form))) (set! last-form form) (set! last-line-number line) (set! vars (lint-walk (if (symbol? form) form (and (pair? form) (car form))) form vars))) (if (and (pair? vars) *report-multiply-defined-top-level-functions*) (for-each (lambda (var) (let ((var-file (hash-table-ref *top-level-objects* (car var)))) (if (not var-file) (hash-table-set! *top-level-objects* (car var) *current-file*) (if (and (string? *current-file*) (not (string=? var-file *current-file*))) (format outport ";~S is defined at the top level in ~S and ~S~%" (car var) var-file *current-file*))))) vars)) (if (and (string? file) (pair? vars) *report-unused-top-level-functions*) (report-usage file 'top-level-var "" vars)) (if (not (input-port? file)) (close-input-port fp)))))))))) ;;; -------------------------------------------------------------------------------- ;;; this reads an HTML file, finds likely-looking scheme code, and runs lint over it. ;;; called on all snd files in hg.scm (define (html-lint file) (define (remove-markups str) (let ((tpos (string-position "" str))) (if tpos (let ((epos (string-position "" str))) (remove-markups (string-append (substring str 0 tpos) (substring str (+ tpos 3) epos) (substring str (+ epos 4))))) (let ((apos (string-position " str (+ pos 1))) (epos (if (and apos (= pos apos)) (string-position "" str (+ bpos 1)) (string-position "" str (+ bpos 1))))) (string-append (substring str 0 pos) (substring str (+ bpos 1) epos) (remove-markups (substring str (+ epos (if (and apos (= apos pos)) 4 5))))))))))) (define (fixup-html str) (let ((pos (char-position #\& str))) (if (not pos) str (string-append (substring str 0 pos) (let ((epos (char-position #\; str pos))) (let ((substr (substring str (+ pos 1) epos))) (let ((replacement (cond ((string=? substr "gt") ">") ((string=? substr "lt") "<") ((string=? substr "mdash") "-") ((string=? substr "amp") "&") (else (format #t "unknown: ~A~%" substr))))) (string-append replacement (fixup-html (substring str (+ epos 1))))))))))) (call-with-input-file file (lambda (f) (do ((line-num 0 (+ line-num 1)) (line (read-line f #t) (read-line f #t))) ((eof-object? line)) ;; look for
	;;   decide if it is scheme code (first char is #\()
	;;   if so, clean out html markup stuff, call lint on that
	
	(let ((pos (string-position " line) 1))))
		(do ((cline (read-line f #t) (read-line f #t))
		     (rline 1 (+ rline 1)))
		    ((string-position "
" cline) (set! line-num (+ line-num rline))) (set! code (string-append code cline))) ;; is first non-whitespace char #\(? ignoring comments (let ((len (length code))) (do ((i 0 (+ i 1))) ((>= i len)) (let ((c (string-ref code i))) (if (not (char-whitespace? c)) (if (char=? c #\;) (set! i (char-position #\newline code i)) (begin (set! i (+ len 1)) (if (char=? c #\() (catch #t (lambda () (let ((ncode (with-input-from-string (fixup-html (remove-markups code)) read))) (call-with-output-file "t631-temp.scm" (lambda (fout) (format fout "~S~%" ncode))) (let ((outstr (call-with-output-string (lambda (p) (let ((old-shadow *report-shadowed-variables*)) (set! *report-shadowed-variables* #t) (lint "t631-temp.scm" p #f) (set! *report-shadowed-variables* old-shadow)))))) (if (> (length outstr) 0) (format #t ";~A ~D: ~A~%" file line-num outstr))))) (lambda args (format #t ";~A ~D, error in read: ~A ~A~%" file line-num args (fixup-html (remove-markups code))))))))))))))))))) snd-16.1/binary-io.scm0000644000076400007640000002125012622467371012742 0ustar bilbil;;; read/write binary (sound) files ;;; ;;; names are read|write b|l int|float n, ;;; so read-bint32 reads the next 4 bytes from the current input port, ;;; interpreting them as a big-endian 32-bit integer (provide 'snd-binary-io.scm) ;;; -------- strings (0-terminated) (define (io-read-string) (let ((chars ())) (do ((c (read-byte) (read-byte))) ((or (eof-object? c) (= c 0)) (apply string (reverse chars))) (set! chars (cons (integer->char c) chars))))) (define (io-write-string str) (for-each write-char str) ; or maybe (lambda (c) (write-byte (char->integer c))) (write-byte 0)) ;;; -------- strings (unterminated) (define (read-chars len) (let ((str (make-string len))) (do ((i 0 (+ i 1))) ((= i len) str) (set! (str i) (read-char))))) (define (write-chars str) (for-each write-char str)) ;;; -------- 16-bit ints (define (read-bint16) (let ((int (+ (ash (read-byte) 8) (read-byte)))) ; this depends on arg evaluation left->right (if (> int 32767) (- int 65536) int))) (define (read-lint16) (let ((int (+ (read-byte) (ash (read-byte) 8)))) (if (> int 32767) (- int 65536) int))) (define (write-bint16 int) (write-byte (logand (ash int -8) #xff)) (write-byte (logand int #xff))) (define (write-lint16 int) (write-byte (logand int #xff)) (write-byte (logand (ash int -8) #xff))) ;;; -------- 32-bit ints (define (read-bint32) (let ((int (+ (ash (read-byte) 24) (ash (read-byte) 16) (ash (read-byte) 8) (read-byte)))) (if (> int 2147483647) (- int 4294967296) int))) (define (read-lint32) (let ((int (+ (read-byte) (ash (read-byte) 8) (ash (read-byte) 16) (ash (read-byte) 24)))) (if (> int 2147483647) (- int 4294967296) int))) (define (write-bint32 int) (write-byte (logand (ash int -24) #xff)) (write-byte (logand (ash int -16) #xff)) (write-byte (logand (ash int -8) #xff)) (write-byte (logand int #xff))) (define (write-lint32 int) (write-byte (logand int #xff)) (write-byte (logand (ash int -8) #xff)) (write-byte (logand (ash int -16) #xff)) (write-byte (logand (ash int -24) #xff))) ;;; -------- 64-bit ints (define (read-bint64) (let ((int 0)) (do ((i 56 (- i 8))) ((< i 0) int) (set! int (logior int (ash (read-byte) i)))))) (define (read-lint64) (let ((int 0)) (do ((i 0 (+ i 8))) ((= i 64) int) (set! int (logior int (ash (read-byte) i)))))) (define (write-bint64 int) (do ((i 56 (- i 8))) ((< i 0)) (write-byte (logand (ash int (- i)) #xff)))) (define (write-lint64 int) (do ((i 0 (+ i 8))) ((= i 64)) (write-byte (logand (ash int (- i)) #xff)))) ;;; -------- 32-bit floats (IEEE 754, sign + 23(+1) bits significand + 8 bits exponent) (define (int_to_float32 int) (if (zero? int) 0.0 (* (if (zero? (ash int -31)) 1.0 -1.0) (expt 2 (- (logand (ash int -23) #xff) 127)) (logior #x800000 (logand int #x7fffff)) (expt 2 -23)))) (define (read-bfloat32) (int_to_float32 (read-bint32))) (define (read-lfloat32) (int_to_float32 (read-lint32))) (define (float64_to_int32 flt) (let* ((data (integer-decode-float flt)) (signif (car data)) (expon (cadr data)) (sign (caddr data))) (if (= expon signif 0) 0 ;; we're assuming floats are (64-bit) doubles in s7, so this is coercing to a 32-bit float in a sense ;; this causes some round-off error (logior (if (negative? sign) #x80000000 0) (ash (+ expon 52 127) 23) (logand (ash signif -29) #x7fffff))))) (define (write-bfloat32 flt) (write-bint32 (float64_to_int32 flt))) (define (write-lfloat32 flt) (write-lint32 (float64_to_int32 flt))) ;;; -------- 64-bit floats (IEEE 754, sign + 52(+1) bits significand + 11 bits exponent) (define (int_to_float64 int) (if (zero? int) 0.0 (* (if (zero? (ash int -63)) 1.0 -1.0) (expt 2 (- (logand (ash int -52) #x7ff) 1023)) (logior #x10000000000000 (logand int #xfffffffffffff)) (expt 2 -52)))) (define (read-bfloat64) (int_to_float64 (read-bint64))) (define (read-lfloat64) (int_to_float64 (read-lint64))) (define (float64_to_int64 flt) (let* ((data (integer-decode-float flt)) (signif (car data)) (expon (cadr data)) (sign (caddr data))) (if (= expon signif 0) 0 (logior (if (negative? sign) #x8000000000000000 0) (ash (+ expon 52 1023) 52) (logand signif #xfffffffffffff))))) (define (write-bfloat64 flt) (write-bint64 (float64_to_int64 flt))) (define (write-lfloat64 flt) (write-lint64 (float64_to_int64 flt))) ;;; -------- 80-bit floats (IEEE 754, sign + 63(+1) bits significand + 15 bits exponent, needed for aifc headers) (define (read-bfloat80->int) (let ((exp 0) (mant1 0) (mant0 0) (sign 0) (buf (make-vector 10))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (buf i) (read-byte))) (set! exp (logior (ash (buf 0) 8) (buf 1))) (set! sign (if (not (= (logand exp #x8000) 0)) 1 0)) (set! exp (logand exp #x7FFF)) (set! mant1 (+ (ash (buf 2) 24) (ash (buf 3) 16) (ash (buf 4) 8) (buf 5))) (set! mant0 (+ (ash (buf 6) 24) (ash (buf 7) 16) (ash (buf 8) 8) (buf 9))) (if (= mant1 mant0 exp sign 0) 0 (round (* (if (= sign 1) -1 1) (expt 2.0 (- exp 16383.0)) (+ (* (expt 2.0 -31.0) mant1) (* (expt 2.0 -63.0) mant0))))))) (define (write-int->bfloat80 val) (let ((exp 0) (sign 0) (mant1 0) (mant0 0)) (if (negative? val) (begin (set! sign 1) (set! val (- val)))) (if (not (zero? val)) (begin (set! exp (round (+ (log val 2.0) 16383.0))) (set! val (* val (expt 2 (- (+ 16383 31) exp)))) (set! mant1 (floor val)) (set! val (- val mant1)) (set! mant0 (floor (* val (expt 2 32)))))) (write-byte (logior (ash sign 7) (ash exp -8))) (write-byte (logand exp #xFF)) (do ((i 2 (+ i 1)) (j 24 (- j 8))) ((= i 6)) (write-byte (logand (ash mant1 (- j)) #xFF))) (do ((i 6 (+ i 1)) (j 24 (- j 8))) ((= i 10)) (write-byte (logand (ash mant0 (- j)) #xFF))))) ;;; -------- "au" (NeXT/Sun) header (define (read-au-header file) (with-input-from-file file (lambda () (let ((magic (read-chars 4))) (if (not (string=? magic ".snd")) (error 'bad-header "~A is not an au file: ~A" file) (let ((data-location (read-bint32)) (data-size (read-bint32)) (sample-type (read-bint32)) (srate (read-bint32)) (chns (read-bint32)) (comment (io-read-string))) (list magic data-location data-size sample-type srate chns comment))))))) (define (write-au-header file chns srate data-size sample-type comment) ; data-size in bytes ;; common sample-types: 1 mulaw, 2 linear_8, 3 linear_16, 4 linear_24, 5 linear_32, 6 float, 5 double, 27 alaw (with-output-to-file file (lambda () (let* ((comlen (length comment)) (data-location (+ 24 (* 4 (floor (+ 1 (/ comlen 4)))))) (curloc 24)) (write-chars ".snd") (write-bint32 data-location) (write-bint32 data-size) (write-bint32 sample-type) (write-bint32 srate) (write-bint32 chns) (if (> comlen 0) (begin (io-write-string comment) (set! curloc (+ curloc comlen 1)))) ; io-write-string adds a trailing 0 (do ((i curloc (+ i 1))) ((>= i data-location)) (write-byte 0)))))) (define (read-aif-header file) (let ((data-location 0) (data-size 0) (sample-type 0) (srate 0) (chns 0) (current-location 0)) (with-input-from-file file (lambda () (let ((magic (read-chars 4))) (if (not (string=? magic "FORM")) (error 'bad-header "~A is not an aif file: ~A" file magic) (let (;(size (read-bint32)) (magic (read-chars 4))) (set! current-location 12) (if (and (not (string=? magic "AIFF")) (not (string=? magic "AIFC"))) (error 'bad-header "~A is not an aif file: ~A" file magic) ;; now look for the "SSND" and "COMM" chunks (call-with-exit (lambda (return) (let loop () (let ((chunk (read-chars 4)) (chunk-size (read-bint32))) (if (odd? chunk-size) (set! chunk-size (+ chunk-size 1))) (if (string=? chunk "SSND") (begin (set! data-location (+ 16 current-location (read-bint32))) (if (> srate 0) (return (list magic data-location data-size sample-type srate chns)))) (if (string=? chunk "COMM") (let ((len 0)) (set! chns (read-bint16)) (set! len (read-bint32)) (set! sample-type (read-bint16)) (set! srate (read-bfloat80->int)) (set! data-size (* len chns sample-type 1/8)) (if (> data-location 0) (return (list magic data-location data-size sample-type srate chns)))) (do ((i 0 (+ i 1))) ; here we really need built-in file IO stuff! ((= i chunk-size)) (if (eof-object? (read-byte)) (return 'bad-header))))) (set! current-location (+ 8 chunk-size)) (loop))))))))))))) snd-16.1/bird.fsm0000644000076400007640000014462512306421672012001 0ustar bilbil\ bird.fsm -- clm/bird.clm \ Translator: Michael Scholz \ Created: Tue Dec 12 03:26:27 CET 2006 \ Changed: Wed Nov 21 22:48:47 CET 2012 \ Usage: <'> bird-test with-sound \ or ws-bird-test require clm instrument: bird <{ start dur freq freq-skew amp freqenv ampenv :optional lpfilt 1.0 degree 0.0 reverb-amount 0.0 -- }> :envelope ampenv :scaler amp :duration dur make-env { amp-env } :envelope freqenv :scaler freq-skew hz->radians :duration dur make-env { gls-env } :frequency freq make-oscil { os } :a0 lpfilt :b1 1.0 lpfilt f- make-one-pole { fil } *channels* 2 = degree f0= && if 45.0 to degree then *reverb* reverb-amount f0= && if 0.001 to reverb-amount then start dur #{ :degree degree :distance 1.0 :reverb-amount reverb-amount } run-instrument fil os gls-env env 0.0 oscil amp-env env f* one-pole end-run ;instrument instrument: bigbird <{ start dur freq freq-skew amp freqenv ampenv parts :optional lpcoeff 1.0 degree 0.0 reverb-amount 0.0 -- }> :envelope ampenv :scaler amp :duration dur make-env { amp-env } :envelope freqenv :scaler freq-skew hz->radians :duration dur make-env { gls-env } :frequency freq :coeffs parts normalize-partials undef partials->polynomial make-polyshape { os } :a0 lpcoeff :b1 1.0 lpcoeff f- make-one-pole { fil } *channels* 2 = degree f0= && if 45.0 to degree then *reverb* reverb-amount f0= && if 0.001 to reverb-amount then start dur #{ :degree degree :distance 1.0 :reverb-amount reverb-amount } run-instrument fil os 1.0 gls-env env polyshape amp-env env f* one-pole end-run ;instrument #( 0 0 0.25 1 0.6 0.7 0.75 1 1 0 ) constant main-amp #( 0 0 0.01 1 0.99 1 1 0 ) constant tap-amp #( 0 0 0.25 1 0.75 1 1 0 ) constant bird-amp #( 0 0 1 1 ) constant bird-up #( 0 1 1 0 ) constant bird-down event: orchard-oriole ( beg -- ) 0.38 f- { beg } #( 0 0 0.6 1 1 0.6 ) { oriupdwna } #( 0 0.5 0.3 1 1 0 ) { oriupdwnb } #( 0 0.9 0.15 1 0.4 0.3 0.6 0.6 0.85 0 1 0 ) { oribiga } #( 0 1 0.05 0.5 0.1 1 0.25 0 0.85 0.5 1 0 ) { orimid } #( 0 0.3 0.25 0 1 1 ) { oridwnup } #( 0 0 0.1 1 1 0 ) { oriamp } 0.38 beg f+ 0.03 3700 100 0.05 bird-down main-amp bird 0.41 beg f+ 0.05 2500 1000 0.10 bird-up main-amp bird 0.50 beg f+ 0.10 2000 800 0.20 oriupdwna main-amp #( 1 1 2 0.02 3 0.05 ) bigbird 0.65 beg f+ 0.03 3900 1200 0.10 bird-down main-amp bird 0.70 beg f+ 0.21 2000 1200 0.15 oribiga main-amp #( 1 1 2 0.05 ) bigbird 1.00 beg f+ 0.05 4200 1000 0.10 bird-down main-amp bird 1.10 beg f+ 0.10 2000 1000 0.25 orimid main-amp #( 1 1 2 0.05 ) bigbird 1.30 beg f+ 0.10 2000 1000 0.25 orimid main-amp #( 1 1 2 0.05 ) bigbird 1.48 beg f+ 0.10 2300 3200 0.10 oriupdwnb oriamp bird 1.65 beg f+ 0.03 1800 300 0.05 bird-up main-amp bird 1.70 beg f+ 0.03 2200 100 0.04 bird-down main-amp bird 1.80 beg f+ 0.07 2500 2000 0.15 oriupdwnb oriamp bird 1.92 beg f+ 0.20 2400 1200 0.25 oridwnup main-amp #( 1 1 2 0.04 ) bigbird 2.20 beg f+ 0.02 2200 3000 0.04 bird-up main-amp bird 2.28 beg f+ 0.02 2200 3000 0.04 bird-up main-amp bird 2.40 beg f+ 0.17 2000 1000 0.20 oriupdwna oriamp #( 1 1 2 0.04 ) bigbird 2.4 0.17 f+ step ;event event: cassins-kingbird ( beg -- ) 0.03 f- { beg } #( 0 0.3 0.45 1 0.9 0.1 1 0 ) { kingfirst } #( 0.00 0.00 0.02 0.50 0.04 0.00 0.06 0.55 0.08 0.05 0.10 0.60 0.12 0.05 0.14 0.65 0.16 0.10 0.18 0.70 0.20 0.10 0.22 0.75 0.24 0.15 0.26 0.80 0.28 0.20 0.30 0.85 0.32 0.25 0.34 0.90 0.36 0.30 0.38 0.95 0.40 0.40 0.42 1.00 0.44 0.50 0.46 1.00 0.48 0.45 0.50 1.00 0.52 0.50 0.54 1.00 0.56 0.40 0.58 0.95 0.60 0.40 0.62 0.90 0.64 0.40 0.66 0.85 0.68 0.35 0.70 0.80 0.72 0.30 0.74 0.75 0.76 0.25 0.78 0.70 0.80 0.20 0.82 0.65 0.84 0.10 0.86 0.60 0.88 0.00 0.90 0.55 0.92 0.00 0.94 0.50 0.96 0.00 1.00 0.40 ) { kingsecond } 0.03 beg f+ 0.04 1700 1200 0.15 kingfirst main-amp #( 1 1 2 0.5 3 0 4 0.2 ) bigbird 0.12 beg f+ 0.18 1700 900 0.25 kingsecond main-amp #( 1 1 2 0.01 3 0 4 0.1 ) bigbird 0.12 0.18 f+ step ;event event: chipping-sparrow ( beg -- ) { beg } #( 0 0.8 0.15 1 0.75 0.3 1 0 ) { chip-up } 0.00 beg f+ 0.05 4000 2400 0.2 chip-up main-amp bird 0.06 beg f+ 0.05 4000 2400 0.2 chip-up main-amp bird 0.12 beg f+ 0.05 4000 2400 0.2 chip-up main-amp bird 0.18 beg f+ 0.05 4000 2400 0.2 chip-up main-amp bird 0.24 beg f+ 0.05 4000 2400 0.2 chip-up main-amp bird 0.30 beg f+ 0.05 4000 2400 0.2 chip-up main-amp bird 0.36 beg f+ 0.05 4000 2400 0.2 chip-up main-amp bird 0.42 beg f+ 0.05 4000 2400 0.2 chip-up main-amp bird 0.48 beg f+ 0.05 4000 2400 0.2 chip-up main-amp bird 0.54 beg f+ 0.05 4000 2400 0.2 chip-up main-amp bird 0.60 beg f+ 0.05 4000 2400 0.2 chip-up main-amp bird 0.66 beg f+ 0.05 4000 2400 0.2 chip-up main-amp bird 0.72 beg f+ 0.05 4000 2400 0.2 chip-up main-amp bird 0.78 beg f+ 0.05 4000 2400 0.2 chip-up main-amp bird 0.84 beg f+ 0.05 4000 2400 0.2 chip-up main-amp bird 0.90 beg f+ 0.05 4000 2400 0.2 chip-up main-amp bird 0.96 beg f+ 0.05 4000 2400 0.2 chip-up main-amp bird 0.96 0.05 f+ step ;event event: bobwhite ( beg -- ) 0.4 f- { beg } #( 0 0 0.4 1 1 1 ) { bobup1 } #( 0 0 0.65 0.5 1 1 ) { bobup2 } 0.4 beg f+ 0.2 1800 200 0.1 bobup1 main-amp #( 1 1 2 0.02 ) bigbird 1.0 beg f+ 0.2 1800 1200 0.2 bobup2 main-amp #( 1 1 2 0.02 ) bigbird 1 0.2 f+ step ;event event: western-meadowlark ( beg -- ) 0.8 f- { beg } #( 0 0 1 0 ) { no-skw } #( 0 1 0.4 0.4 1 0 ) { down-skw } 0.80 beg f+ 0.10 2010 0 0.10 no-skw main-amp #( 1 1 2 0.04 ) bigbird 1.10 beg f+ 0.15 3000 100 0.11 down-skw main-amp #( 1 1 2 0.04 ) bigbird 1.30 beg f+ 0.25 2000 150 0.20 down-skw main-amp #( 1 1 2 0.04 ) bigbird 1.65 beg f+ 0.15 3010 250 0.11 down-skw main-amp #( 1 1 2 0.04 ) bigbird 1.85 beg f+ 0.10 2200 150 0.11 down-skw main-amp #( 1 1 2 0.04 ) bigbird 2.00 beg f+ 0.10 3200 1400 0.11 bird-down main-amp #( 1 1 2 0.04 ) bigbird 2.20 beg f+ 0.05 2000 200 0.11 bird-down main-amp #( 1 1 2 0.04 ) bigbird 2.30 beg f+ 0.10 1600 0 0.11 bird-down main-amp #( 1 1 2 0.04 ) bigbird 2.3 0.1 f+ step ;event event: scissor-tailed-flycatcher ( beg -- ) { beg } #( 0 0 0.4 1 0.6 1 1 0 ) { scissor } beg 0.05 1800 1800 0.2 scissor main-amp #( 1 0.5 2 1 3 0.5 4 0.1 5 0.01 ) bigbird 0.05 step ;event event: great-horned-owl ( beg -- ) 0.3 f- { beg } #( 0 0 0.3 1 1 1 ) { owlup } #( 1 1 3 0.02 7 0.01 ) { owl-parts } 0.30 beg f+ 0.10 300 0 0.1 main-amp main-amp owl-parts bigbird 0.60 beg f+ 0.40 293 6 0.1 bird-down main-amp owl-parts bigbird 1.75 beg f+ 0.35 293 7 0.1 owlup main-amp owl-parts bigbird 2.50 beg f+ 0.20 300 0 0.1 owlup main-amp owl-parts bigbird 2.5 0.2 f+ step ;event event: black-throated-gray-warbler ( beg -- ) { beg } #( 0.00 0.50 0.02 0.60 0.04 0.45 0.06 0.62 0.08 0.40 0.10 0.65 0.12 0.35 0.14 0.70 0.18 0.30 0.20 0.70 0.22 0.30 0.24 0.70 0.25 0.20 0.30 0.80 0.35 0.10 0.40 0.90 0.45 0.00 0.50 1.00 0.55 0.00 0.60 1.00 0.65 0.00 0.70 1.00 0.75 0.00 0.80 1.00 0.85 0.00 0.90 1.00 0.95 0.00 1.00 0.50 ) { gray-one } #( 0.00 0.00 0.01 0.40 0.02 0.00 0.03 0.40 0.04 0.00 0.05 0.40 0.06 0.00 0.07 0.40 0.08 0.00 0.09 0.40 0.10 0.00 0.25 0.80 0.40 0.30 0.55 1.00 0.70 0.00 0.85 0.80 1.00 0.40 ) { gray-two } #( 0.00 1.00 0.01 0.60 0.02 1.00 0.03 0.60 0.04 1.00 0.05 0.60 0.06 1.00 0.07 0.60 0.08 1.00 0.09 0.60 0.10 1.00 0.11 0.60 0.12 1.00 0.13 0.60 0.14 1.00 0.15 0.60 0.16 1.00 0.17 0.60 0.18 1.00 0.19 0.60 0.20 1.00 0.21 0.55 0.22 1.00 0.23 0.50 0.24 1.00 0.25 0.50 0.26 1.00 0.27 0.50 0.28 1.00 0.29 0.50 0.30 1.00 0.31 0.50 0.32 1.00 0.33 0.50 0.34 1.00 0.35 0.50 0.36 1.00 0.37 0.50 0.38 1.00 0.39 0.50 0.40 1.00 0.41 0.50 0.42 1.00 0.43 0.50 0.44 1.00 0.45 0.50 0.46 1.00 0.47 0.50 0.48 1.00 0.49 0.50 0.50 1.00 0.51 0.50 0.52 1.00 0.53 0.50 0.54 1.00 0.55 0.50 0.56 1.00 0.57 0.50 0.58 1.00 0.59 0.50 0.60 1.00 1.00 0.00 ) { gray-three } 0.00 beg f+ 0.12 3700 600 0.05 gray-one main-amp bird 0.18 beg f+ 0.08 3000 800 0.07 gray-two main-amp bird 0.28 beg f+ 0.12 3700 600 0.12 gray-one main-amp bird 0.44 beg f+ 0.08 3000 800 0.15 gray-two main-amp bird 0.54 beg f+ 0.12 3700 600 0.20 gray-one main-amp bird 0.72 beg f+ 0.08 3000 800 0.25 gray-two main-amp bird 0.82 beg f+ 0.12 3700 600 0.25 gray-one main-amp bird 0.96 beg f+ 0.20 3000 2000 0.20 gray-three main-amp bird 1.20 beg f+ 0.02 4500 500 0.05 bird-up main-amp bird 1.25 beg f+ 0.02 4200 800 0.05 bird-up main-amp bird 1.30 beg f+ 0.02 4000 900 0.05 bird-up main-amp bird 1.3 0.02 f+ step ;event event: yellow-warbler ( beg -- ) { beg } #( 0 0 0.6 1 1 0.5 ) { yellow-up } #( 0 1 0.05 1 0.6 0 0.8 0.3 1 0.1 ) { yellow-swirl } #( 0 0 0.3 0.2 0.8 0.7 1 1 ) { yellow-last } #( 0 0 0.9 1 1 0 ) { swirl-amp } 0.00 beg f+ 0.050 5600 400 0.05 yellow-up main-amp bird 0.23 beg f+ 0.120 5000 1500 0.15 yellow-swirl main-amp bird 0.45 beg f+ 0.130 5000 1700 0.17 yellow-swirl main-amp bird 0.62 beg f+ 0.160 5000 2000 0.20 yellow-swirl main-amp bird 0.85 beg f+ 0.150 5000 2000 0.20 yellow-swirl main-amp bird 1.05 beg f+ 0.075 3700 1000 0.20 bird-down main-amp bird 1.15 beg f+ 0.075 3700 800 0.15 bird-down main-amp bird 1.25 beg f+ 0.075 3700 800 0.15 bird-down main-amp bird 1.40 beg f+ 0.200 3700 2000 0.20 yellow-last main-amp bird 1.4 0.2 f+ step ;event event: black-necked-stilt ( beg -- ) { beg } #( 0 0 0.9 1 1 0 ) { upamp } #( 0 0 0.5 1 1 0.2 ) { rampup } #( 1 0.5 2 1 3 0.75 4 0.5 5 0.1 ) { bns-parts } 0.0 beg f+ 0.1 900 100 0.2 rampup upamp bns-parts bigbird 0.3 beg f+ 0.1 900 200 0.2 rampup upamp bns-parts bigbird 0.6 beg f+ 0.1 900 250 0.2 rampup upamp bns-parts bigbird 0.6 0.1 f+ step ;event event: chestnut-sided-warbler ( beg -- ) 0.1 f- { beg } #( 0 1 0.3 0.5 0.6 1 0.8 0.2 1 0 ) { ycurve } #( 0 0.2 0.5 1 1 0 ) { vcurve } #( 0 0.5 0.15 0 0.45 0.1 0.6 1 0.7 0.9 1 0.9 ) { wcurve } #( 0 0 0.95 1 1 1 ) { upcurve } #( 0 1 0.25 0.3 0.6 0.15 1 0 ) { downcurve } #( 0 0 0.9 1 1 0 ) { louder } #( 0 0 0.1 1 0.4 0.1 0.5 0.9 0.6 0.1 0.7 1 1 0 ) { wamp } 0.10 beg f+ 0.10 4050 1200 0.050 ycurve main-amp #( 1 1 2 0.1 ) bigbird 0.25 beg f+ 0.03 3900 300 0.075 vcurve main-amp #( 1 1 2 0.1 ) bigbird 0.30 beg f+ 0.10 4050 1200 0.150 ycurve louder #( 1 1 2 0.1 ) bigbird 0.42 beg f+ 0.03 3800 500 0.100 vcurve main-amp #( 1 1 2 0.1 ) bigbird 0.50 beg f+ 0.10 4000 1200 0.200 ycurve tap-amp #( 1 1 2 0.1 ) bigbird 0.65 beg f+ 0.03 3800 500 0.150 vcurve main-amp #( 1 1 2 0.1 ) bigbird 0.72 beg f+ 0.10 4000 1200 0.200 ycurve tap-amp #( 1 1 2 0.1 ) bigbird 0.85 beg f+ 0.03 3800 500 0.150 vcurve main-amp #( 1 1 2 0.1 ) bigbird 0.91 beg f+ 0.10 4000 1200 0.200 ycurve tap-amp #( 1 1 2 0.1 ) bigbird 1.05 beg f+ 0.12 3800 2200 0.150 wcurve wamp #( 1 1 2 0.1 ) bigbird 1.20 beg f+ 0.12 3800 2200 0.150 wcurve wamp #( 1 1 2 0.1 ) bigbird 1.35 beg f+ 0.12 2500 2200 0.250 upcurve louder #( 1 1 2 0.1 ) bigbird 1.50 beg f+ 0.12 2500 4000 0.150 downcurve main-amp #( 1 1 2 0.1 ) bigbird 1.5 0.12 f+ step ;event event: grasshopper-sparrow ( beg -- ) 0.49 f- { beg } #( 0.00 0.50 0.02 0.80 0.04 0.30 0.06 0.80 0.07 0.10 0.08 0.90 0.10 0.00 0.11 0.90 0.12 0.00 0.13 0.90 0.14 0.10 0.15 1.00 0.16 0.10 0.17 1.00 0.18 0.10 0.19 1.00 0.20 0.10 0.21 1.00 0.22 0.10 0.23 1.00 0.24 0.10 0.25 1.00 0.26 0.10 0.27 1.00 0.28 0.10 0.29 1.00 0.30 0.10 0.31 1.00 0.32 0.10 0.33 1.00 0.34 0.10 0.35 1.00 0.36 0.10 0.37 1.00 0.38 0.10 0.39 1.00 0.40 0.10 0.41 1.00 0.42 0.10 0.43 1.00 0.44 0.10 0.45 1.00 0.46 0.10 0.47 1.00 0.48 0.10 0.49 1.00 0.50 0.10 0.51 1.00 0.52 0.10 0.53 1.00 0.54 0.10 0.55 1.00 0.56 0.10 0.57 1.00 0.58 0.10 0.59 1.00 0.60 0.10 0.61 1.00 0.62 0.10 0.63 1.00 0.64 0.10 0.65 1.00 0.66 0.10 0.67 1.00 0.68 0.10 0.69 1.00 0.70 0.10 0.71 1.00 0.72 0.10 0.73 1.00 0.74 0.10 0.75 1.00 0.76 0.10 0.77 1.00 0.78 0.10 0.79 1.00 0.80 0.10 0.81 1.00 0.82 0.10 0.83 1.00 0.84 0.10 0.85 1.00 0.86 0.10 0.87 1.00 0.88 0.10 0.89 1.00 0.90 0.10 0.91 1.00 0.92 0.10 0.93 1.00 0.94 0.10 0.95 1.00 0.96 0.10 0.97 1.00 0.98 0.10 1.00 1.00 ) { grass-one } #( 0.00 0.00 0.10 1.00 0.20 0.00 0.30 1.00 0.40 0.00 0.50 1.00 0.60 0.00 0.70 1.00 0.80 0.00 0.90 1.00 1.00 0.00 ) { grass-two } 0.49 beg f+ 0.01 8000 100 0.1 grass-two main-amp bird 0.60 beg f+ 0.01 5700 300 0.1 grass-two main-amp bird 0.92 beg f+ 0.01 3900 100 0.1 grass-two main-amp bird 1.00 beg f+ 1.40 6000 2500 0.2 grass-one main-amp bird 1 1.4 f+ step ;event event: swamp-sparrow ( beg -- ) { beg } #( 0 0 0.6 0.7 1 1 ) { swamp-up } #( 0 1 0.5 0.5 0.6 0.6 1 0 ) { swamp-down } 0.000 beg f+ 0.020 3900 200 0.3 swamp-up main-amp bird 0.035 beg f+ 0.035 3200 3000 0.1 swamp-down main-amp bird 0.080 beg f+ 0.025 3700 0 0.1 main-amp main-amp bird 0.100 beg f+ 0.020 3900 200 0.3 swamp-up main-amp bird 0.135 beg f+ 0.035 3200 3000 0.1 swamp-down main-amp bird 0.180 beg f+ 0.025 3700 0 0.1 main-amp main-amp bird 0.200 beg f+ 0.020 3900 200 0.3 swamp-up main-amp bird 0.235 beg f+ 0.035 3200 3000 0.1 swamp-down main-amp bird 0.280 beg f+ 0.025 3700 0 0.1 main-amp main-amp bird 0.300 beg f+ 0.020 3900 200 0.3 swamp-up main-amp bird 0.335 beg f+ 0.035 3200 3000 0.1 swamp-down main-amp bird 0.380 beg f+ 0.025 3700 0 0.1 main-amp main-amp bird 0.400 beg f+ 0.020 3900 200 0.3 swamp-up main-amp bird 0.435 beg f+ 0.035 3200 3000 0.1 swamp-down main-amp bird 0.480 beg f+ 0.025 3700 0 0.1 main-amp main-amp bird 0.500 beg f+ 0.020 3900 200 0.3 swamp-up main-amp bird 0.535 beg f+ 0.035 3200 3000 0.1 swamp-down main-amp bird 0.580 beg f+ 0.025 3700 0 0.1 main-amp main-amp bird 0.600 beg f+ 0.020 3900 200 0.3 swamp-up main-amp bird 0.635 beg f+ 0.035 3200 3000 0.1 swamp-down main-amp bird 0.680 beg f+ 0.025 3700 0 0.1 main-amp main-amp bird 0.700 beg f+ 0.020 3900 200 0.3 swamp-up main-amp bird 0.735 beg f+ 0.035 3200 3000 0.1 swamp-down main-amp bird 0.780 beg f+ 0.025 3700 0 0.1 main-amp main-amp bird 0.800 beg f+ 0.020 3900 200 0.3 swamp-up main-amp bird 0.835 beg f+ 0.035 3200 3000 0.1 swamp-down main-amp bird 0.880 beg f+ 0.025 3700 0 0.1 main-amp main-amp bird 0.900 beg f+ 0.020 3900 200 0.3 swamp-up main-amp bird 0.935 beg f+ 0.035 3200 3000 0.1 swamp-down main-amp bird 0.980 beg f+ 0.025 3700 0 0.1 main-amp main-amp bird 0.98 0.025 f+ step ;event event: golden-crowned-sparrow ( beg -- ) 0.6 f- { beg } #( 0 1 0.25 0.2 1 0 ) { gold-one } #( 0 0.9 0.05 1 0.1 0.4 1 0 ) { gold-two } #( 0 0.5 0.1 0 0.2 1 0.3 0 0.4 1 0.5 0 0.6 1 0.7 0 0.8 1 0.9 0 1 0.5 ) { gold-trill } 0.60 beg f+ 0.50 4300 1000 0.15 gold-one main-amp bird 1.30 beg f+ 0.45 3300 200 0.15 gold-one main-amp bird 1.75 beg f+ 0.40 3800 100 0.15 gold-two main-amp bird 2.20 beg f+ 0.30 3800 100 0.10 gold-trill main-amp bird 2.2 0.3 f+ step ;event event: indigo-bunting ( beg -- ) 0.4 f- { beg } #( 0 0 0.5 1 1 0 ) { bunt-v } #( 0 1 0.5 0 1 0.9 ) { bunt-y } #( 0 0.8 0.3 1 0.7 0.2 1 0 ) { bunt-n } #( 0 1 0.1 0.5 0.25 0.9 1 0 ) { bunt-x } 0.40 beg f+ 0.08 3000 700 0.25 bird-down main-amp bird 0.52 beg f+ 0.02 6200 1000 0.05 bird-down main-amp bird 0.55 beg f+ 0.15 3500 2300 0.10 bunt-v main-amp bird 0.74 beg f+ 0.02 6200 1800 0.05 bunt-x main-amp bird 0.80 beg f+ 0.15 3400 2300 0.10 bunt-v main-amp bird 1.00 beg f+ 0.10 3400 800 0.20 bunt-v main-amp bird 1.13 beg f+ 0.03 4100 2000 0.05 bird-down main-amp bird 1.25 beg f+ 0.08 3400 800 0.20 bunt-v main-amp bird 1.40 beg f+ 0.03 4100 2000 0.05 bird-down main-amp bird 1.50 beg f+ 0.07 3700 300 0.10 bird-down main-amp bird 1.60 beg f+ 0.10 4100 2200 0.15 bunt-y main-amp bird 1.72 beg f+ 0.05 3700 300 0.10 bird-down main-amp bird 1.81 beg f+ 0.10 4100 2200 0.15 bunt-y main-amp bird 1.94 beg f+ 0.07 5200 1800 0.20 bunt-n main-amp bird 2.05 beg f+ 0.08 3000 1500 0.15 bird-up main-amp bird 2.20 beg f+ 0.07 5200 1800 0.20 bunt-n main-amp bird 2.33 beg f+ 0.08 3000 1500 0.15 bird-up main-amp bird 2.43 beg f+ 0.07 5200 1800 0.10 bunt-n main-amp bird 2.51 beg f+ 0.08 3000 1500 0.10 bird-up main-amp bird 2.51 0.08 f+ step ;event event: hooded-warbler ( beg -- ) 0.6 f- { beg } 0.60 beg f+ 0.03 3900 1600 0.05 bird-down main-amp bird 0.64 beg f+ 0.03 3900 1700 0.05 bird-down main-amp bird 0.80 beg f+ 0.03 3900 2000 0.10 bird-down main-amp bird 0.84 beg f+ 0.03 3900 2000 0.10 bird-down main-amp bird 0.93 beg f+ 0.03 3900 2100 0.15 bird-down main-amp bird 0.97 beg f+ 0.03 3900 2100 0.15 bird-down main-amp bird 1.05 beg f+ 0.03 3900 2100 0.05 bird-down main-amp bird 1.09 beg f+ 0.03 3900 2100 0.20 bird-down main-amp bird 1.17 beg f+ 0.03 3900 2100 0.20 bird-down main-amp bird 1.21 beg f+ 0.03 3900 2100 0.20 bird-down main-amp bird 1.39 beg f+ 0.03 3900 2100 0.20 bird-down main-amp bird 1.43 beg f+ 0.03 3900 2100 0.20 bird-down main-amp bird 1.51 beg f+ 0.03 3900 2100 0.20 bird-down main-amp bird 1.55 beg f+ 0.03 3900 2100 0.20 bird-down main-amp bird 1.63 beg f+ 0.03 3900 2100 0.20 bird-down main-amp bird 1.67 beg f+ 0.03 3900 2100 0.20 bird-down main-amp bird 1.75 beg f+ 0.03 3900 2100 0.20 bird-down main-amp bird 1.80 beg f+ 0.03 3900 2100 0.20 bird-down main-amp bird 1.90 beg f+ 0.04 3000 1000 0.15 bird-up main-amp bird 1.98 beg f+ 0.04 3000 1000 0.15 bird-up main-amp bird 2.05 beg f+ 0.04 3000 1000 0.15 bird-up main-amp bird 2.13 beg f+ 0.04 3000 1000 0.15 bird-up main-amp bird 2.21 beg f+ 0.04 3000 1000 0.15 bird-up main-amp bird 2.29 beg f+ 0.04 3000 1000 0.15 bird-up main-amp bird 2.37 beg f+ 0.04 3000 1000 0.15 bird-up main-amp bird 2.45 beg f+ 0.04 3000 1000 0.15 bird-up main-amp bird 2.45 0.04 f+ step ;event event: american-widgeon ( beg -- ) 0.3 f- { beg } #( 0 0 0.5 1 1 0 ) { widgeon } 0.30 beg f+ 0.07 1900 300 0.15 widgeon widgeon #( 1 1 2 0.02 ) bigbird 0.40 beg f+ 0.11 1700 1400 0.25 widgeon widgeon #( 1 0.7 2 1 3 0.02 ) bigbird 0.55 beg f+ 0.07 1900 300 0.15 widgeon widgeon #( 1 1 2 0.02 ) bigbird 0.55 0.07 f+ step ;event event: louisiana-waterthrush ( beg -- ) { beg } #( 0 0.8 0.35 0.4 0.45 0.9 0.5 1 0.75 1 1 1 ) { water-one } #( 0 1 0.4 0 0.6 0.1 1 0.8 ) { water-two } #( 0 1 0.95 0 1 0 ) { water-three } #( 0 0 1 1 ) { water-four } #( 0 1 1 0 ) { water-five } #( 0 0 0.35 1 0.5 0.2 0.9 1 1 0 ) { water-amp } #( 0 0 0.9 1 1 0 ) { water-damp } 0.00 beg f+ 0.170 4100 2000 0.20 water-one water-amp bird 0.32 beg f+ 0.180 4050 2050 0.30 water-one water-amp bird 0.64 beg f+ 0.200 4000 1900 0.25 water-one water-amp bird 0.90 beg f+ 0.200 3900 2000 0.30 water-two tap-amp bird 1.25 beg f+ 0.120 3000 3000 0.25 water-three water-damp bird 1.40 beg f+ 0.100 2700 1500 0.20 water-four water-damp bird 1.58 beg f+ 0.020 5200 1000 0.10 water-five main-amp bird 1.65 beg f+ 0.020 5200 1000 0.10 water-five main-amp bird 1.70 beg f+ 0.035 3200 1000 0.10 water-three water-damp bird 1.7 0.03 f+ step ;event event: robin ( beg -- ) 0.45 f- { beg } #( 0.00 0.10 0.08 0.70 0.30 0.00 0.35 1.00 0.40 0.30 1.00 0.30 ) { r-one } #( 0.00 0.00 0.10 1.00 0.20 0.70 0.35 0.70 0.65 0.30 0.70 0.50 0.80 0.00 0.90 0.20 1.00 0.00 ) { r-two } #( 0.00 0.20 0.25 1.00 0.60 0.70 0.90 0.00 1.00 0.10 ) { r-three } #( 0.00 0.50 0.10 0.00 0.20 1.00 0.30 0.00 0.40 1.00 0.50 0.00 0.60 1.00 0.70 0.50 1.00 0.20 ) { r-five } #( 0.00 0.00 0.12 0.70 0.30 0.00 0.70 1.00 1.00 0.50 ) { r-six } 0.45 beg f+ 0.06 2000 800 0.15 r-six main-amp #( 1 1 2 0.1 ) bigbird 0.56 beg f+ 0.10 2000 900 0.15 r-one main-amp #( 1 1 2 0.1 ) bigbird 1.04 beg f+ 0.24 2000 2000 0.25 r-two main-amp #( 1 1 2 0.1 ) bigbird 1.63 beg f+ 0.13 1900 1600 0.20 r-three main-amp #( 1 1 2 0.1 ) bigbird 1.80 beg f+ 0.11 2200 1200 0.25 bird-down main-amp #( 1 1 2 0.1 ) bigbird 2.31 beg f+ 0.21 1950 2000 0.15 r-five main-amp #( 1 1 2 0.1 ) bigbird 2.31 0.21 f+ step ;event event: solitary-vireo ( beg -- ) { beg } #( 0.00 0.20 0.03 0.30 0.06 0.10 0.10 0.50 0.13 0.40 0.16 0.80 0.19 0.50 0.22 0.90 0.25 0.60 0.28 1.00 0.31 0.60 0.34 1.00 0.37 0.50 0.41 0.90 0.45 0.40 0.49 0.80 0.51 0.40 0.54 0.75 0.57 0.35 0.60 0.70 0.63 0.30 0.66 0.60 0.69 0.25 0.72 0.50 0.75 0.20 0.78 0.30 0.82 0.10 0.85 0.30 0.88 0.05 0.91 0.30 0.94 0.00 0.95 0.30 0.99 0.00 1.00 0.10 ) { bigskew } beg 0.4 1800 1200 0.2 bigskew main-amp bird 0.4 step ;event event: pigeon-hawk ( beg -- ) { beg } #( 0 0 0.3 1 0.7 1 1 0 ) { hupdown } 0.00 beg f+ 0.10 1900 200 0.2 hupdown main-amp #( 1 0.7 2 1 ) bigbird 0.12 beg f+ 0.01 2050 0 0.1 main-amp main-amp #( 1 0.5 2 1 ) bigbird 0.13 beg f+ 0.10 1900 200 0.2 hupdown main-amp #( 1 0.7 2 1 ) bigbird 0.25 beg f+ 0.01 2050 0 0.1 main-amp main-amp #( 1 0.5 2 1 ) bigbird 0.26 beg f+ 0.10 1900 200 0.2 hupdown main-amp #( 1 0.7 2 1 ) bigbird 0.38 beg f+ 0.01 2050 0 0.1 main-amp main-amp #( 1 0.5 2 1 ) bigbird 0.39 beg f+ 0.10 1900 200 0.2 hupdown main-amp #( 1 0.7 2 1 ) bigbird 0.51 beg f+ 0.01 2050 0 0.1 main-amp main-amp #( 1 0.5 2 1 ) bigbird 0.52 beg f+ 0.10 1900 200 0.2 hupdown main-amp #( 1 0.7 2 1 ) bigbird 0.64 beg f+ 0.01 2050 0 0.1 main-amp main-amp #( 1 0.5 2 1 ) bigbird 0.65 beg f+ 0.10 1900 200 0.2 hupdown main-amp #( 1 0.7 2 1 ) bigbird 0.77 beg f+ 0.01 2050 0 0.1 main-amp main-amp #( 1 0.5 2 1 ) bigbird 0.78 beg f+ 0.10 1900 200 0.2 hupdown main-amp #( 1 0.7 2 1 ) bigbird 0.90 beg f+ 0.01 2050 0 0.1 main-amp main-amp #( 1 0.5 2 1 ) bigbird 0.91 beg f+ 0.10 1900 200 0.2 hupdown main-amp #( 1 0.7 2 1 ) bigbird 1.03 beg f+ 0.01 2050 0 0.1 main-amp main-amp #( 1 0.5 2 1 ) bigbird 1.04 beg f+ 0.10 1900 200 0.2 hupdown main-amp #( 1 0.7 2 1 ) bigbird 1.16 beg f+ 0.01 2050 0 0.1 main-amp main-amp #( 1 0.5 2 1 ) bigbird 1.17 beg f+ 0.10 1900 200 0.2 hupdown main-amp #( 1 0.7 2 1 ) bigbird 1.29 beg f+ 0.01 2050 0 0.1 main-amp main-amp #( 1 0.5 2 1 ) bigbird 1.30 beg f+ 0.10 1900 200 0.2 hupdown main-amp #( 1 0.7 2 1 ) bigbird 1.42 beg f+ 0.01 2050 0 0.1 main-amp main-amp #( 1 0.5 2 1 ) bigbird 1.43 beg f+ 0.10 1900 200 0.2 hupdown main-amp #( 1 0.7 2 1 ) bigbird 1.55 beg f+ 0.01 2050 0 0.1 main-amp main-amp #( 1 0.5 2 1 ) bigbird 1.56 beg f+ 0.10 1900 200 0.2 hupdown main-amp #( 1 0.7 2 1 ) bigbird 1.68 beg f+ 0.01 2050 0 0.1 main-amp main-amp #( 1 0.5 2 1 ) bigbird 1.69 beg f+ 0.10 1900 200 0.2 hupdown main-amp #( 1 0.7 2 1 ) bigbird 1.81 beg f+ 0.01 2050 0 0.1 main-amp main-amp #( 1 0.5 2 1 ) bigbird 1.82 beg f+ 0.10 1900 200 0.2 hupdown main-amp #( 1 0.7 2 1 ) bigbird 1.82 0.1 f+ step ;event event: cerulean-warbler ( beg -- ) 0.27 f- { beg } #( 0 0.8 0.1 1 0.25 0.5 0.4 1 0.55 0.5 0.7 1 1 0 ) { trill } 0.27 beg f+ 0.05 3000 1000 0.050 bird-down main-amp bird 0.33 beg f+ 0.05 3000 800 0.075 bird-up main-amp bird 0.41 beg f+ 0.01 3200 700 0.070 bird-down main-amp bird 0.42 beg f+ 0.01 3200 700 0.080 bird-down main-amp bird 0.43 beg f+ 0.06 3200 700 0.090 bird-down main-amp bird 0.51 beg f+ 0.06 3200 500 0.100 bird-up main-amp bird 0.60 beg f+ 0.10 3000 1200 0.200 trill main-amp bird 0.72 beg f+ 0.05 3000 800 0.200 bird-up main-amp bird 0.80 beg f+ 0.10 3000 1200 0.200 trill main-amp bird 0.92 beg f+ 0.05 3000 800 0.200 bird-up main-amp bird 1.00 beg f+ 0.01 3900 600 0.100 bird-up main-amp bird 1.01 beg f+ 0.01 3910 800 0.100 bird-up main-amp bird 1.02 beg f+ 0.01 3940 500 0.100 bird-up main-amp bird 1.03 beg f+ 0.01 4000 500 0.100 bird-up main-amp bird 1.04 beg f+ 0.01 3900 1000 0.100 bird-up main-amp bird 1.05 beg f+ 0.01 3900 1000 0.100 bird-up main-amp bird 1.06 beg f+ 0.01 3900 1000 0.100 bird-up main-amp bird 1.07 beg f+ 0.01 3900 1000 0.100 bird-up main-amp bird 1.08 beg f+ 0.01 3900 1000 0.100 bird-up main-amp bird 1.09 beg f+ 0.01 3900 1000 0.100 bird-up main-amp bird 1.10 beg f+ 0.01 3900 1000 0.100 bird-up main-amp bird 1.11 beg f+ 0.01 3900 1000 0.100 bird-up main-amp bird 1.12 beg f+ 0.01 3900 1000 0.100 bird-up main-amp bird 1.13 beg f+ 0.01 3900 1000 0.100 bird-up main-amp bird 1.14 beg f+ 0.01 3900 1000 0.100 bird-up main-amp bird 1.15 beg f+ 0.01 3900 1000 0.100 bird-up main-amp bird 1.16 beg f+ 0.01 3900 1000 0.100 bird-up main-amp bird 1.17 beg f+ 0.01 3900 1000 0.100 bird-up main-amp bird 1.18 beg f+ 0.01 3900 1000 0.100 bird-up main-amp bird 1.19 beg f+ 0.01 3900 1000 0.100 bird-up main-amp bird 1.20 beg f+ 0.01 3900 1000 0.100 bird-up main-amp bird 1.21 beg f+ 0.01 3900 1000 0.100 bird-up main-amp bird 1.22 beg f+ 0.01 3900 1000 0.100 bird-up main-amp bird 1.23 beg f+ 0.01 3900 1200 0.100 bird-up main-amp bird 1.24 beg f+ 0.01 3900 1200 0.100 bird-up main-amp bird 1.25 beg f+ 0.01 3900 1200 0.100 bird-up main-amp bird 1.26 beg f+ 0.01 3900 1200 0.100 bird-up main-amp bird 1.27 beg f+ 0.01 3900 1400 0.100 bird-up main-amp bird 1.28 beg f+ 0.01 3900 1400 0.100 bird-up main-amp bird 1.29 beg f+ 0.01 3900 1400 0.100 bird-up main-amp bird 1.30 beg f+ 0.01 3900 1400 0.100 bird-up main-amp bird 1.3 0.01 f+ step ;event event: nashville-warbler ( beg -- ) 0.15 f- { beg } #( 0 0.6 0.35 1 1 0 ) { nash-blip } #( 0 0.9 0.05 1 0.1 0.9 0.65 0.5 1 0 ) { nash-down } #( 0 0 0.15 0.2 0.25 0.05 0.9 0.95 1 1 ) { nash-up } #( 0 0 0.8 1 1 0 ) { nash-amp } 0.15 beg f+ 0.025 3900 300 0.300 nash-blip main-amp bird 0.24 beg f+ 0.160 4200 3800 0.150 nash-down nash-amp bird 0.42 beg f+ 0.025 3900 300 0.300 nash-blip main-amp bird 0.55 beg f+ 0.140 4300 3700 0.150 nash-down nash-amp bird 0.75 beg f+ 0.030 3950 350 0.300 nash-blip main-amp bird 0.81 beg f+ 0.170 4200 3900 0.175 nash-down main-amp bird 1.00 beg f+ 0.020 3800 400 0.250 nash-blip main-amp bird 1.11 beg f+ 0.140 4200 3800 0.165 nash-down nash-amp bird 1.30 beg f+ 0.030 3750 300 0.200 nash-blip main-amp bird 1.40 beg f+ 0.110 4200 3700 0.100 nash-down main-amp bird 1.57 beg f+ 0.100 3800 2200 0.100 nash-up main-amp bird 1.70 beg f+ 0.100 3800 2150 0.125 nash-up main-amp bird 1.85 beg f+ 0.075 3900 1800 0.100 nash-up nash-amp bird 1.85 0.075 f+ step ;event event: eastern-phoebe ( beg -- ) { beg } #( 0 0 0.3 0.3 0.35 0.5 0.55 0.4 0.7 0.8 0.75 0.7 0.8 1 0.95 0.9 1 0 ) { phoebe-one } #( 0 0 0.5 1 1 0 ) { phoebe-two } #( 0 0 0.1 0.4 0.8 1 1 0.1 ) { phoebe-three } #( 0 1 0.5 0.7 1 0 ) { phoebe-four } #( 0 0 0.1 1 1 0 ) { phoebe-amp } 0.00 beg f+ 0.225 3000 1300 0.3 phoebe-one main-amp bird 0.35 beg f+ 0.120 3000 500 0.1 phoebe-two phoebe-amp bird 0.40 beg f+ 0.100 3000 1500 0.2 phoebe-three phoebe-amp bird 0.55 beg f+ 0.050 3000 1400 0.2 phoebe-four phoebe-amp bird 0.55 0.05 f+ step ;event event: painted-bunting ( beg -- ) 0.05 f- { beg } #( 0 0 0.9 1 1 0 ) { b-two } #( 0 0 0.5 1 1 0 ) { b-four } #( 0 0.7 0.15 0 0.4 1 0.8 1 1 0.5 ) { b-five } #( 0 0 0.1 0.5 0.15 0 0.4 1 0.9 1 1 0 ) { b-six } #( 0 1 0.25 0.4 0.75 0.5 1 0 ) { b-seven } #( 0 0.3 0.4 0.4 0.5 1 0.6 0.2 1 0 ) { b-eight } #( 0 0 0.05 1 0.3 1 0.5 0.3 0.9 1 1 0 ) { b-nine } #( 0 0.4 0.25 0 0.35 1 0.5 0 0.65 1 0.75 0 0.85 1 1 0 ) { b-ten } #( 0 0 0.5 1 1 0.5 ) { b-twelve } #( 0 0 0.05 1 0.3 0.2 0.6 0.2 0.9 1 1 0 ) { b-thirteen } #( 0 0.3 0.3 1 0.6 0.3 1 0 ) { b-fourteen } #( 0 0 0.1 0.5 0.5 0.5 0.9 1 1 0 ) { b-fifteen } 0.05 beg f+ 0.10 3100 900 0.05 bird-up b-two bird 0.21 beg f+ 0.07 4100 700 0.15 bird-down main-amp bird 0.36 beg f+ 0.12 3700 1000 0.20 b-four main-amp bird 0.52 beg f+ 0.08 2300 1600 0.15 b-five b-six bird 0.68 beg f+ 0.10 4000 1000 0.25 bird-up tap-amp bird 0.80 beg f+ 0.12 2300 1700 0.20 b-seven main-amp bird 0.96 beg f+ 0.15 3800 2200 0.30 b-eight b-nine bird 1.18 beg f+ 0.10 2300 1600 0.15 b-ten main-amp bird 1.30 beg f+ 0.02 3200 1000 0.10 bird-down main-amp bird 1.33 beg f+ 0.02 3200 1000 0.10 bird-down main-amp bird 1.36 beg f+ 0.02 3200 1000 0.10 bird-down main-amp bird 1.40 beg f+ 0.03 4000 2000 0.12 b-twelve b-thirteen bird 1.47 beg f+ 0.10 2300 1700 0.20 b-fourteen b-fifteen bird 1.47 0.1 f+ step ;event event: western-flycatcher ( beg -- ) { beg } #( 0 0 0.1 1 0.2 0.4 0.95 0.1 1 0 ) { f-one } #( 0 0 0.1 0.2 0.2 0.1 0.3 1 0.9 1 1 0 ) { a-one } #( 0 0.5 0.25 1 0.5 0 0.6 0 0.95 0.3 1 0.6 ) { f-two } #( 0 0 0.1 1 0.2 1 0.5 0.1 0.6 0.1 0.9 1 1 0 ) { a-two } #( 1 1 2 0.02 3 0.1 4 0.01 ) { fc-parts } 0.0 beg f+ 0.2 2000 2200 0.2 f-one a-one fc-parts bigbird 0.3 beg f+ 0.2 2000 1100 0.2 f-two a-two fc-parts bigbird 0.3 0.2 f+ step ;event event: bachmans-sparrow ( beg -- ) { beg } #( 0 1 0.1 0.5 0.9 0.5 1 0 ) { sopening } #( 0 0.1 0.35 0 1 1 ) { sup } #( 0 1 0.4 0.5 1 0 ) { sdwn } #( 0 1 0.25 0 0.75 0.4 1 0.5 ) { slast } 0.00 beg f+ 0.510 4900 200 0.3 sopening main-amp bird 0.52 beg f+ 0.015 3800 200 0.1 sup main-amp bird 0.52 beg f+ 0.015 3750 250 0.1 sup main-amp bird 0.54 beg f+ 0.015 3600 300 0.1 sup main-amp bird 0.56 beg f+ 0.015 3500 250 0.1 sup main-amp bird 0.58 beg f+ 0.015 3400 200 0.1 sup main-amp bird 0.60 beg f+ 0.015 3200 200 0.1 sup main-amp bird 0.62 beg f+ 0.015 3800 100 0.1 sup main-amp bird 0.65 beg f+ 0.070 3000 750 0.2 sup main-amp bird 0.73 beg f+ 0.030 5000 1000 0.1 sdwn main-amp bird 0.80 beg f+ 0.070 3000 750 0.2 sup main-amp bird 0.88 beg f+ 0.030 5000 1000 0.1 sdwn main-amp bird 0.95 beg f+ 0.070 3000 750 0.2 sup main-amp bird 1.03 beg f+ 0.030 5000 1000 0.1 sdwn main-amp bird 1.10 beg f+ 0.070 3000 750 0.2 sup main-amp bird 1.18 beg f+ 0.030 5000 1000 0.1 sdwn main-amp bird 1.25 beg f+ 0.070 3000 750 0.2 sup main-amp bird 1.33 beg f+ 0.030 5000 1000 0.1 sdwn main-amp bird 1.40 beg f+ 0.070 3000 750 0.2 sup main-amp bird 1.48 beg f+ 0.030 5000 1000 0.1 sdwn main-amp bird 1.55 beg f+ 0.070 3000 750 0.2 sup main-amp bird 1.63 beg f+ 0.030 5000 1000 0.1 sdwn main-amp bird 2.80 beg f+ 0.060 4000 1700 0.1 bird-up main-amp bird 2.87 beg f+ 0.010 5200 0 0.2 bird-up main-amp bird 2.90 beg f+ 0.060 4000 1700 0.1 bird-up main-amp bird 2.97 beg f+ 0.010 5200 0 0.2 bird-up main-amp bird 3.00 beg f+ 0.060 4000 1700 0.1 bird-up main-amp bird 3.07 beg f+ 0.010 5200 0 0.2 bird-up main-amp bird 3.10 beg f+ 0.060 4000 1700 0.1 bird-up main-amp bird 3.17 beg f+ 0.010 5200 0 0.2 bird-up main-amp bird 3.20 beg f+ 0.060 4000 1700 0.1 bird-up main-amp bird 3.27 beg f+ 0.010 5200 0 0.2 bird-up main-amp bird 3.40 beg f+ 0.150 3000 1000 0.2 slast main-amp bird 3.60 beg f+ 0.150 3000 1000 0.2 slast main-amp bird 3.80 beg f+ 0.150 3000 1000 0.2 slast main-amp bird 4.00 beg f+ 0.150 3000 1000 0.2 slast main-amp bird 4.20 beg f+ 0.150 3000 1000 0.2 slast main-amp bird 4.40 beg f+ 0.150 3000 1000 0.2 slast main-amp bird 4.4 0.15 f+ step ;event event: cedar-waxwing ( beg -- ) { beg } #( 0 0 0.25 0.7 0.7 1 0.9 1 1 0.2 ) { cedar } #( 0 0 0.2 1 0.4 1 1 0 ) { cedamp } beg 0.5 6000 800 0.2 cedar cedamp bird 0.5 step ;event event: bairds-sparrow ( beg -- ) { beg } #( 0 0 0.25 1 0.5 0 0.75 1 1 0 ) { bairdend } #( 0.00 0.50 0.05 1.00 0.10 0.00 0.15 1.00 0.20 0.00 0.25 1.00 0.30 0.00 0.35 1.00 0.40 0.00 0.45 1.00 0.50 0.00 0.55 1.00 0.60 0.00 0.65 1.00 0.70 0.00 0.75 1.00 0.80 0.00 0.85 1.00 0.90 0.00 0.95 1.00 1.00 0.00 ) { bairdstart } 0.00 beg f+ 0.09 6500 1500 0.20 bairdstart main-amp bird 0.22 beg f+ 0.01 5900 100 0.20 bairdend main-amp bird 0.25 beg f+ 0.09 6000 1000 0.20 bairdstart main-amp bird 0.45 beg f+ 0.01 4200 100 0.20 bairdend main-amp bird 0.50 beg f+ 0.08 4200 600 0.20 bairdstart main-amp bird 0.59 beg f+ 0.01 4400 100 0.20 bairdend main-amp bird 0.60 beg f+ 0.01 4400 100 0.20 bairdend main-amp bird 0.68 beg f+ 0.07 5400 700 0.20 bairdstart main-amp bird 0.75 beg f+ 0.01 4200 100 0.20 bairdend main-amp bird 0.79 beg f+ 0.01 4400 100 0.20 bairdend main-amp bird 0.83 beg f+ 0.01 4200 100 0.19 bairdend main-amp bird 0.87 beg f+ 0.01 4400 100 0.19 bairdend main-amp bird 0.91 beg f+ 0.01 4200 100 0.18 bairdend main-amp bird 0.95 beg f+ 0.01 4400 100 0.18 bairdend main-amp bird 0.99 beg f+ 0.01 4200 100 0.17 bairdend main-amp bird 1.03 beg f+ 0.01 4400 100 0.17 bairdend main-amp bird 1.07 beg f+ 0.01 4200 100 0.16 bairdend main-amp bird 1.11 beg f+ 0.01 4400 100 0.16 bairdend main-amp bird 1.15 beg f+ 0.01 4200 100 0.15 bairdend main-amp bird 1.19 beg f+ 0.01 4400 100 0.15 bairdend main-amp bird 1.23 beg f+ 0.01 4200 100 0.14 bairdend main-amp bird 1.27 beg f+ 0.01 4400 100 0.14 bairdend main-amp bird 1.31 beg f+ 0.01 4200 100 0.13 bairdend main-amp bird 1.35 beg f+ 0.01 4400 100 0.13 bairdend main-amp bird 1.39 beg f+ 0.01 4200 100 0.12 bairdend main-amp bird 1.43 beg f+ 0.01 4400 100 0.12 bairdend main-amp bird 1.47 beg f+ 0.01 4200 100 0.11 bairdend main-amp bird 1.51 beg f+ 0.01 4400 100 0.11 bairdend main-amp bird 1.55 beg f+ 0.01 4200 100 0.10 bairdend main-amp bird 1.59 beg f+ 0.01 4400 100 0.10 bairdend main-amp bird 1.63 beg f+ 0.01 4200 100 0.09 bairdend main-amp bird 1.67 beg f+ 0.01 4400 100 0.09 bairdend main-amp bird 1.71 beg f+ 0.01 4200 100 0.08 bairdend main-amp bird 1.75 beg f+ 0.01 4400 100 0.08 bairdend main-amp bird 1.79 beg f+ 0.01 4200 100 0.07 bairdend main-amp bird 1.83 beg f+ 0.01 4400 100 0.07 bairdend main-amp bird 1.87 beg f+ 0.01 4200 100 0.06 bairdend main-amp bird 1.92 beg f+ 0.01 4400 100 0.06 bairdend main-amp bird 1.97 beg f+ 0.01 4200 100 0.05 bairdend main-amp bird 1.97 0.01 f+ step ;event event: kentucky-warbler ( beg -- ) 0.6 f- { beg } #( 0 0.3 0.5 1 1 0 ) { kenstart } #( 0 0.9 0.1 1 1 0 ) { kendwn } #( 0 1 0.25 0 0.5 0 0.75 1 1 0 ) { kentrill } #( 1 1 2 0.1 ) { ken-parts-1 } #( 1 1 2 0.01 ) { ken-parts-01 } #( 1 1 2 0.03 ) { ken-parts-03 } 0.60 beg f+ 0.02 3800 200 0.05 kenstart main-amp ken-parts-03 bigbird 0.65 beg f+ 0.03 4300 200 0.15 bird-up main-amp ken-parts-1 bigbird 0.73 beg f+ 0.02 3200 100 0.10 kendwn main-amp ken-parts-1 bigbird 0.75 beg f+ 0.05 3000 800 0.15 kenstart main-amp ken-parts-01 bigbird 0.82 beg f+ 0.06 3100 1200 0.10 kendwn main-amp ken-parts-01 bigbird 0.90 beg f+ 0.06 3200 1200 0.10 kendwn main-amp ken-parts-01 bigbird 0.98 beg f+ 0.05 4600 100 0.20 kentrill main-amp ken-parts-1 bigbird 1.10 beg f+ 0.05 2900 800 0.15 kenstart main-amp ken-parts-01 bigbird 1.17 beg f+ 0.06 3000 1200 0.10 kendwn main-amp ken-parts-01 bigbird 1.25 beg f+ 0.06 3100 1200 0.10 kendwn main-amp ken-parts-01 bigbird 1.33 beg f+ 0.05 4600 100 0.20 kentrill main-amp ken-parts-1 bigbird 1.43 beg f+ 0.05 2800 800 0.15 kenstart main-amp ken-parts-01 bigbird 1.50 beg f+ 0.05 2700 1200 0.10 kendwn main-amp ken-parts-01 bigbird 1.57 beg f+ 0.06 2800 1200 0.10 kendwn main-amp ken-parts-01 bigbird 1.64 beg f+ 0.05 4600 100 0.20 kentrill main-amp ken-parts-1 bigbird 1.75 beg f+ 0.05 2700 800 0.15 kenstart main-amp ken-parts-01 bigbird 1.81 beg f+ 0.05 2600 1200 0.10 kendwn main-amp ken-parts-01 bigbird 1.88 beg f+ 0.06 2600 1200 0.10 kendwn main-amp ken-parts-01 bigbird 1.97 beg f+ 0.05 4600 100 0.20 kentrill main-amp ken-parts-1 bigbird 2.05 beg f+ 0.05 2700 800 0.15 kenstart main-amp ken-parts-01 bigbird 2.12 beg f+ 0.06 2600 1200 0.10 kendwn main-amp ken-parts-01 bigbird 2.20 beg f+ 0.05 4600 100 0.20 kentrill main-amp ken-parts-1 bigbird 2.30 beg f+ 0.05 2800 800 0.15 kenstart main-amp ken-parts-01 bigbird 2.37 beg f+ 0.06 2700 1200 0.10 kendwn main-amp ken-parts-01 bigbird 2.45 beg f+ 0.05 4700 100 0.25 kentrill main-amp ken-parts-1 bigbird 2.45 0.05 f+ step ;event event: rufous-sided-towhee ( beg -- ) 0.25 f- { beg } #( 0.00 0.10 0.02 0.05 0.04 0.15 0.06 0.05 0.08 0.20 0.10 0.04 0.12 0.25 0.14 0.03 0.16 0.30 0.18 0.02 0.20 0.35 0.22 0.01 0.24 0.40 0.26 0.00 0.28 0.45 0.30 0.00 0.32 0.50 0.34 0.00 0.36 0.50 0.80 1.00 1.00 0.00 ) { towhee-one } #( 1 0.03 2 1 3 0.03 ) { towhee-parts } 0.250 beg f+ 0.13 1400 1100 0.20 towhee-one main-amp towhee-parts bigbird 0.450 beg f+ 0.13 1400 1100 0.20 towhee-one main-amp towhee-parts bigbird 0.600 beg f+ 0.13 1400 1100 0.20 towhee-one main-amp towhee-parts bigbird 0.750 beg f+ 0.10 1400 1100 0.20 towhee-one main-amp towhee-parts bigbird 0.880 beg f+ 0.01 5100 2000 0.10 bird-up main-amp bird 0.895 beg f+ 0.01 5100 1600 0.10 bird-up main-amp bird 0.910 beg f+ 0.01 5100 1000 0.10 bird-up main-amp bird 0.930 beg f+ 0.01 3000 1200 0.10 bird-down main-amp bird 0.945 beg f+ 0.01 5100 2000 0.09 bird-up main-amp bird 0.960 beg f+ 0.01 5100 1600 0.09 bird-up main-amp bird 0.975 beg f+ 0.01 5100 1000 0.09 bird-up main-amp bird 0.995 beg f+ 0.01 3000 1200 0.09 bird-down main-amp bird 1.010 beg f+ 0.01 5100 2000 0.10 bird-up main-amp bird 1.025 beg f+ 0.01 5100 1600 0.10 bird-up main-amp bird 1.040 beg f+ 0.01 5100 1000 0.10 bird-up main-amp bird 1.060 beg f+ 0.01 3000 1200 0.10 bird-down main-amp bird 1.075 beg f+ 0.01 5100 2000 0.09 bird-up main-amp bird 1.090 beg f+ 0.01 5100 1600 0.09 bird-up main-amp bird 1.105 beg f+ 0.01 5100 1000 0.09 bird-up main-amp bird 1.125 beg f+ 0.01 3000 1200 0.09 bird-down main-amp bird 1.140 beg f+ 0.01 5100 2000 0.08 bird-up main-amp bird 1.155 beg f+ 0.01 5100 1600 0.08 bird-up main-amp bird 1.170 beg f+ 0.01 5100 1000 0.08 bird-up main-amp bird 1.190 beg f+ 0.01 3000 1200 0.08 bird-down main-amp bird 1.205 beg f+ 0.01 5100 2000 0.08 bird-up main-amp bird 1.220 beg f+ 0.01 5100 1600 0.08 bird-up main-amp bird 1.235 beg f+ 0.01 5100 1000 0.08 bird-up main-amp bird 1.255 beg f+ 0.01 3000 1200 0.08 bird-down main-amp bird 1.270 beg f+ 0.01 5100 2000 0.07 bird-up main-amp bird 1.285 beg f+ 0.01 5100 1600 0.07 bird-up main-amp bird 1.300 beg f+ 0.01 5100 1000 0.07 bird-up main-amp bird 1.320 beg f+ 0.01 3000 1200 0.07 bird-down main-amp bird 1.335 beg f+ 0.01 5100 2000 0.06 bird-up main-amp bird 1.350 beg f+ 0.01 5100 1600 0.06 bird-up main-amp bird 1.365 beg f+ 0.01 5100 1000 0.06 bird-up main-amp bird 1.385 beg f+ 0.01 3000 1200 0.06 bird-down main-amp bird 1.400 beg f+ 0.01 5100 2000 0.05 bird-up main-amp bird 1.415 beg f+ 0.01 5100 1600 0.05 bird-up main-amp bird 1.430 beg f+ 0.01 5100 1000 0.05 bird-up main-amp bird 1.450 beg f+ 0.01 3000 1200 0.05 bird-down main-amp bird 1.465 beg f+ 0.01 5100 2000 0.03 bird-up main-amp bird 1.480 beg f+ 0.01 5100 1600 0.03 bird-up main-amp bird 1.495 beg f+ 0.01 5100 1000 0.03 bird-up main-amp bird 1.515 beg f+ 0.01 3000 1200 0.03 bird-down main-amp bird 1.515 0.01 f+ step ;event event: prothonotary-warbler ( beg -- ) 0.76 f- { beg } #( 0 0.1 0.2 0 1 1 ) { pro-one } #( 0 0 0.2 1 0.4 0.5 1 0 ) { pro-amp } 0.76 beg f+ 0.08 3000 3000 0.05 pro-one pro-amp bird 0.85 beg f+ 0.05 4000 2500 0.06 bird-up bird-amp bird 1.02 beg f+ 0.08 3000 3000 0.10 pro-one pro-amp bird 1.12 beg f+ 0.05 4000 2500 0.10 bird-up bird-amp bird 1.26 beg f+ 0.08 3000 3000 0.15 pro-one pro-amp bird 1.35 beg f+ 0.05 4000 2500 0.16 bird-up bird-amp bird 1.54 beg f+ 0.08 3000 3000 0.20 pro-one pro-amp bird 1.63 beg f+ 0.05 4000 2500 0.19 bird-up bird-amp bird 1.80 beg f+ 0.08 3000 3000 0.20 pro-one pro-amp bird 1.89 beg f+ 0.05 4000 2500 0.16 bird-up bird-amp bird 2.03 beg f+ 0.08 3000 3000 0.15 pro-one pro-amp bird 2.12 beg f+ 0.05 4000 2500 0.10 bird-up bird-amp bird 2.30 beg f+ 0.08 3000 3000 0.10 pro-one pro-amp bird 2.39 beg f+ 0.05 4000 2500 0.06 bird-up bird-amp bird 2.39 0.05 f+ step ;event event: audubons-warbler ( beg -- ) 0.75 f- { beg } #( 0 0 0.15 1 0.45 0.9 0.5 0 0.55 1 0.9 0.9 1 1 ) { w-end } #( 0 0.1 0.5 1 1 0 ) { w-updown } 0.75 beg f+ 0.04 2400 200 0.05 bird-down bird-amp bird 0.83 beg f+ 0.03 3200 200 0.10 bird-up bird-amp bird 0.90 beg f+ 0.04 2500 300 0.15 bird-up bird-amp bird 0.97 beg f+ 0.04 2300 600 0.15 bird-down bird-amp bird 1.02 beg f+ 0.03 3500 400 0.20 bird-up bird-amp bird 1.06 beg f+ 0.04 2300 1200 0.10 bird-up bird-amp bird 1.13 beg f+ 0.05 2300 1200 0.15 bird-down bird-amp bird 1.22 beg f+ 0.02 3200 800 0.25 bird-up bird-amp bird 1.25 beg f+ 0.08 2400 600 0.20 w-updown bird-amp bird 1.35 beg f+ 0.02 2200 400 0.10 bird-up bird-amp bird 1.38 beg f+ 0.07 2400 1400 0.15 bird-down bird-amp bird 1.47 beg f+ 0.03 3000 800 0.20 bird-up bird-amp bird 1.50 beg f+ 0.03 2500 400 0.10 w-updown bird-amp bird 1.55 beg f+ 0.01 2300 100 0.05 bird-up bird-amp bird 1.56 beg f+ 0.06 2200 1400 0.15 bird-down bird-amp bird 1.65 beg f+ 0.03 3100 800 0.10 bird-up bird-amp bird 1.70 beg f+ 0.07 2800 800 0.15 w-updown bird-amp bird 1.79 beg f+ 0.06 2400 1000 0.10 bird-down bird-amp bird 1.86 beg f+ 0.14 3100 900 0.25 w-end bird-amp bird 2.02 beg f+ 0.12 3200 800 0.20 w-end bird-amp bird 2.02 0.12 f+ step ;event event: lark-bunting ( beg -- ) 0.1 f- { beg } #( 0.00 0.00 0.06 0.80 0.12 0.00 0.18 0.85 0.24 0.05 0.36 0.90 0.42 0.10 0.48 0.95 0.54 0.20 0.60 1.00 0.66 0.20 0.72 1.00 0.78 0.20 0.84 1.00 0.90 0.20 1.00 1.00 ) { b-trill-one } #( 0.00 0.00 0.05 0.80 0.10 0.00 0.15 0.85 0.20 0.00 0.25 0.90 0.30 0.00 0.35 0.95 0.40 0.00 0.45 1.00 0.50 0.00 0.55 1.00 0.60 0.00 0.65 1.00 0.70 0.00 0.75 1.00 0.80 0.00 0.85 1.00 0.90 0.00 0.95 1.00 1.00 0.00 ) { b-trill-two } 0.10 beg f+ 0.03 1800 100 0.10 bird-up bird-amp bird 0.20 beg f+ 0.12 3700 400 0.20 bird-up bird-amp bird 0.40 beg f+ 0.03 4100 500 0.15 bird-down bird-amp bird 0.45 beg f+ 0.05 2000 400 0.20 bird-down bird-amp bird 0.51 beg f+ 0.03 1800 100 0.10 bird-up bird-amp bird 0.04 beg f+ 0.03 4100 500 0.15 bird-down bird-amp bird 0.65 beg f+ 0.05 2000 400 0.20 bird-down bird-amp bird 0.71 beg f+ 0.03 1800 100 0.10 bird-up bird-amp bird 0.80 beg f+ 0.03 4100 500 0.15 bird-down bird-amp bird 0.85 beg f+ 0.05 2000 400 0.20 bird-down bird-amp bird 0.91 beg f+ 0.03 1800 100 0.10 bird-up bird-amp bird 1.00 beg f+ 0.03 4100 500 0.15 bird-down bird-amp bird 1.05 beg f+ 0.05 2000 400 0.20 bird-down bird-amp bird 1.01 beg f+ 0.03 1800 100 0.10 bird-up bird-amp bird 1.20 beg f+ 0.03 4100 500 0.15 bird-down bird-amp bird 1.25 beg f+ 0.05 2000 400 0.20 bird-down bird-amp bird 1.31 beg f+ 0.03 1800 100 0.10 bird-up bird-amp bird 1.40 beg f+ 0.03 4100 500 0.15 bird-down bird-amp bird 1.45 beg f+ 0.05 2000 400 0.20 bird-down bird-amp bird 1.51 beg f+ 0.03 1800 100 0.10 bird-up bird-amp bird 1.60 beg f+ 0.03 4100 500 0.15 bird-down bird-amp bird 1.65 beg f+ 0.05 2000 400 0.20 bird-down bird-amp bird 1.71 beg f+ 0.03 1800 100 0.10 bird-up bird-amp bird 1.770 beg f+ 0.23 6000 600 0.15 b-trill-one bird-amp bird 2.005 beg f+ 0.28 6000 600 0.15 b-trill-two bird-amp bird 2.005 0.28 f+ step ;event event: eastern-bluebird ( beg -- ) 0.75 f- { beg } #( 0.00 0.60 0.10 1.00 0.20 0.00 0.25 1.00 0.30 0.00 0.35 1.00 0.40 0.00 0.45 1.00 0.50 0.00 0.75 1.00 1.00 0.00 ) { blue-three } #( 0 0 0.5 1 1 0 ) { blue-four } #( 0.00 0.50 0.10 1.00 0.20 0.00 0.35 1.00 0.50 0.00 0.65 1.00 0.80 0.00 0.95 1.00 1.00 0.50 ) { blue-five } 0.75 beg f+ 0.02 2000 1600 0.10 bird-up bird-amp bird 0.80 beg f+ 0.02 2000 1600 0.10 bird-up bird-amp bird 0.86 beg f+ 0.02 2000 1600 0.10 bird-up bird-amp bird 1.00 beg f+ 0.13 2000 1400 0.20 bird-down bird-amp bird 1.20 beg f+ 0.24 2000 800 0.20 blue-three bird-amp bird 1.68 beg f+ 0.03 2200 400 0.10 bird-up bird-amp bird 1.72 beg f+ 0.10 1950 100 0.15 blue-four bird-amp bird 1.96 beg f+ 0.15 2000 600 0.20 blue-five bird-amp bird 1.96 0.15 f+ step ;event event: chuck-wills-widow ( beg -- ) 0.05 f- { beg } #( 0 0 0.1 0.1 0.25 1 0.5 0.3 0.8 0.7 1 0 ) { wid-one } #( 0 0.2 0.3 1 0.5 0.3 0.6 0.7 0.9 0.1 1 0 ) { wid-two } 0.05 beg f+ 0.03 1000 800 0.1 bird-down bird-amp bird 0.32 beg f+ 0.20 1000 1000 0.2 wid-one bird-amp bird 0.56 beg f+ 0.29 900 1100 0.2 wid-two bird-amp bird 0.56 0.29 f+ step ;event event: blue-gray-gnatcatcher ( beg -- ) 0.5 f- { beg } #( 0 0 0.15 1 0.75 0.8 0.9 1 1 0.7 ) { gskw1 } #( 0 0 0.25 1 0.75 0.7 1 0 ) { gskw2 } #( 1 0.4 2 1 3 0.1 ) { gparts-1 } #( 1 0.4 2 1 3 0.2 ) { gparts-2 } #( 1 0.4 2 1 3 0.3 ) { gparts-3 } 0.5 beg f+ 0.20 4000 1000 0.2 gskw1 bird-amp gparts-1 bigbird 0.8 beg f+ 0.13 4000 800 0.2 gskw2 bird-amp gparts-2 bigbird 1.4 beg f+ 0.25 4000 800 0.2 gskw2 bird-amp gparts-3 bigbird 1.8 beg f+ 0.17 4000 900 0.2 gskw1 bird-amp gparts-3 bigbird 2.0 beg f+ 0.17 4000 700 0.2 gskw1 bird-amp gparts-3 bigbird 2.2 beg f+ 0.17 4000 800 0.2 gskw2 bird-amp gparts-3 bigbird 2.2 0.17 f+ step ;event event: black-throated-sparrow ( beg -- ) 0.8 f- { beg } #( 0 0 0.75 1 1 0 ) { black-down-amp } #( 0 0 0.5 1 1 0.2 ) { black-up-down } #( 0 0 0.5 1 1 0 ) { black-amp } #( 0.00 0.00 0.03 0.70 0.06 0.00 0.09 0.75 0.12 0.00 0.15 0.80 0.18 0.05 0.21 0.85 0.24 0.10 0.27 0.90 0.30 0.10 0.33 1.00 0.36 0.10 0.39 1.00 0.42 0.10 0.45 1.00 0.48 0.10 0.51 1.00 0.54 0.10 0.57 1.00 0.60 0.10 0.63 1.00 0.66 0.10 0.69 1.00 0.72 0.10 0.75 1.00 0.78 0.10 0.81 1.00 0.84 0.10 0.87 1.00 0.90 0.00 0.93 0.95 0.96 0.00 1.00 0.90 ) { black-trill } 0.80 beg f+ 0.02 2200 1000 0.10 bird-down bird-amp bird 0.83 beg f+ 0.01 3000 200 0.05 bird-up bird-amp bird 0.96 beg f+ 0.02 5800 500 0.05 bird-up bird-amp bird 1.00 beg f+ 0.02 4000 200 0.05 bird-up bird-amp bird 1.04 beg f+ 0.10 2100 1700 0.15 bird-down black-down-amp bird 1.15 beg f+ 0.05 5700 400 0.25 bird-up bird-amp bird 1.25 beg f+ 0.25 2000 900 0.20 black-trill bird-amp bird 1.52 beg f+ 0.05 5600 400 0.15 black-up-down bird-amp bird 1.60 beg f+ 0.04 3900 1100 0.15 bird-up bird-amp bird 1.66 beg f+ 0.01 1900 100 0.10 bird-up black-amp bird 1.69 beg f+ 0.01 3600 300 0.10 bird-up black-amp bird 1.71 beg f+ 0.03 3900 1000 0.15 bird-up black-amp bird 1.74 beg f+ 0.02 5000 100 0.20 bird-up black-amp bird 1.76 beg f+ 0.01 1900 100 0.10 bird-up black-amp bird 1.78 beg f+ 0.01 3600 300 0.10 bird-up black-amp bird 1.80 beg f+ 0.03 3900 1000 0.15 bird-up black-amp bird 1.83 beg f+ 0.02 5000 100 0.20 bird-up black-amp bird 1.85 beg f+ 0.01 1900 100 0.10 bird-up black-amp bird 1.87 beg f+ 0.01 3600 300 0.10 bird-up black-amp bird 1.89 beg f+ 0.03 3900 1000 0.15 bird-up black-amp bird 1.92 beg f+ 0.02 5000 100 0.20 bird-up black-amp bird 1.94 beg f+ 0.01 1900 100 0.10 bird-up black-amp bird 1.96 beg f+ 0.01 3600 300 0.10 bird-up black-amp bird 1.98 beg f+ 0.03 3900 1000 0.15 bird-up black-amp bird 2.01 beg f+ 0.02 5000 100 0.20 bird-up black-amp bird 2.03 beg f+ 0.01 1900 100 0.10 bird-up black-amp bird 2.05 beg f+ 0.01 3600 300 0.10 bird-up black-amp bird 2.07 beg f+ 0.03 3900 1000 0.15 bird-up black-amp bird 2.10 beg f+ 0.02 5000 100 0.20 bird-up black-amp bird 2.13 beg f+ 0.01 1900 100 0.10 bird-up black-amp bird 2.16 beg f+ 0.03 3800 300 0.10 bird-up bird-amp bird 2.16 0.03 f+ step ;event event: black-chinned-sparrow ( beg -- ) 0.6 f- { beg } #( 0 0 0.3 0.2 1 1 ) { chin-up } 0.60 beg f+ 0.20 4200 100 0.10 bird-up bird-amp bird 1.00 beg f+ 0.09 3800 2000 0.10 chin-up bird-amp bird 1.25 beg f+ 0.08 3900 1700 0.12 chin-up bird-amp bird 1.40 beg f+ 0.08 3600 2300 0.13 bird-up bird-amp bird 1.50 beg f+ 0.11 3100 2800 0.14 bird-up bird-amp bird 1.65 beg f+ 0.07 2900 2700 0.15 bird-up bird-amp bird 1.74 beg f+ 0.07 2900 2700 0.15 bird-up bird-amp bird 1.82 beg f+ 0.07 3000 2300 0.13 bird-up bird-amp bird 1.89 beg f+ 0.07 3200 2000 0.10 bird-up bird-amp bird 1.97 beg f+ 0.05 3200 1500 0.10 bird-up bird-amp bird 2.04 beg f+ 0.04 3400 1000 0.07 bird-up bird-amp bird 2.10 beg f+ 0.03 3600 700 0.05 bird-up bird-amp bird 2.15 beg f+ 0.03 3800 300 0.05 bird-up bird-amp bird 2.19 beg f+ 0.02 3900 100 0.03 bird-up bird-amp bird 2.22 beg f+ 0.01 3900 100 0.01 bird-up bird-amp bird 2.24 beg f+ 0.01 3900 100 0.01 bird-up bird-amp bird 2.24 0.01 f+ step ;event event: various-gull-cries-from-end-of-colony-5 ( beg -- ) 0.25 f- { beg } #( 0 0 10 1 20 0.5 40 0.6 60 0.5 100 0 ) { gull-start } #( 0 0 10 1 30 0.5 80 0.5 100 0 ) { gull-middle } #( 0 0 5 1 10 0.5 90 0.4 100 0 ) { gull-end } #( 1 0.1 2 1 3 0.1 4 0.01 5 0.09 6 0.01 7 0.01 ) { gull-parts } 0.25 beg f+ 0.80 1180 1180 0.08 gull-end bird-amp gull-parts bigbird 1.50 beg f+ 0.90 1180 1180 0.07 gull-end bird-amp gull-parts bigbird 2.75 beg f+ 1.00 1050 1050 0.08 gull-end bird-amp gull-parts bigbird 4.80 beg f+ 0.05 1180 1180 0.06 gull-start bird-amp gull-parts bigbird 4.95 beg f+ 0.10 1180 1180 0.08 gull-start bird-amp gull-parts bigbird 5.15 beg f+ 0.10 1180 1180 0.09 gull-start bird-amp gull-parts bigbird 5.35 beg f+ 0.10 1180 1180 0.10 gull-middle bird-amp gull-parts bigbird 5.45 beg f+ 0.40 1050 1050 0.10 gull-end bird-amp gull-parts bigbird 6.25 beg f+ 0.80 1050 1050 0.10 gull-end bird-amp gull-parts bigbird 7.45 beg f+ 1.80 1050 1050 0.10 gull-end bird-amp gull-parts bigbird 7.45 1.80 f+ step ;event \ <'> bird-test with-sound : bird-test ( -- ) 0.0 now! 1.0 { dur } now@ orchard-oriole dur step now@ cassins-kingbird dur step now@ chipping-sparrow dur step now@ bobwhite dur step now@ western-meadowlark dur step now@ scissor-tailed-flycatcher dur step now@ great-horned-owl dur step now@ black-throated-gray-warbler dur step now@ yellow-warbler dur step now@ black-necked-stilt dur step now@ chestnut-sided-warbler dur step now@ grasshopper-sparrow dur step now@ swamp-sparrow dur step now@ golden-crowned-sparrow dur step now@ indigo-bunting dur step now@ hooded-warbler dur step now@ american-widgeon dur step now@ louisiana-waterthrush dur step now@ robin dur step now@ solitary-vireo dur step now@ pigeon-hawk dur step now@ cerulean-warbler dur step now@ nashville-warbler dur step now@ eastern-phoebe dur step now@ painted-bunting dur step now@ western-flycatcher dur step now@ bachmans-sparrow dur step now@ cedar-waxwing dur step now@ bairds-sparrow dur step now@ kentucky-warbler dur step now@ rufous-sided-towhee dur step now@ prothonotary-warbler dur step now@ audubons-warbler dur step now@ lark-bunting dur step now@ eastern-bluebird dur step now@ chuck-wills-widow dur step now@ blue-gray-gnatcatcher dur step now@ black-throated-sparrow dur step now@ black-chinned-sparrow dur step now@ various-gull-cries-from-end-of-colony-5 dur step ; : ws-bird-test ( -- ) <'> bird-test :play #t :statistics #t :verbose #t :channels 2 :srate 44100 :scaled-to 0.8 :notehook #f with-sound drop ; \ bird.fsm ends here snd-16.1/music5.f0000644000076400007640000013420712306421672011721 0ustar bilbilC Music V, Max Mathews C C typed in from old XGP output C file last written 19Jun75 MUSIC5[M5,GM] (I believe GM = George McKee) C SAIL C C Bill Schottstaedt, 26-Apr-08 C C This is the new version that runs (5-May-08) in gfortran in Linux or the Mac. C On the Mac, I got gfortran from http://macresearch.org/xcode_gfortran_plugin_update. C You don't need the xcode plugin stuff, just the gfortran binary -- it gets C installed in /usr/local/bin. On linux, I think Fedora installed fortran for me. C Most of my changes are in lower case. C To use this program, first divide music5.f into 3 passes (cut at the dotted lines) C named, say pass1.f, pass2.f, pass3.f. Then run them through gfortran: C gfortran -o pass1 pass1.f C gfortran -o pass2 pass2.f C gfortran -o pass3 pass3.f C Now get some input, from music5-examples perhaps, run pass1 C and give it the input file name. C It writes pass1.data. Run pass2. It reads pass1.data and writes pass2.data. C Run pass3. It reads pass2.data and writes the raw (headerless) binary sound C file raw.snd. This is a file of little-endian 4-byte floats at 20000Hz, mono. C pass1 required much more serious surgery than the other 2 passes. I had to C embed the READ1 subroutine in the main program. Apparently new Fortrans C do not guarantee that subroutine locals will be saved across calls. The C other choice was an enormous COMMON block, but that became unwieldy and error-prone. C C In all passes, I replaced the arithmetic IFs, changed file IO, used characters C rather than ints, replaced MOVR with ichar(ch)-ichar('0'), and removed the C EQUIVALENCE stuff (not needed here because I'm using characters directly). C [page 1-1] -- these are the original XGP pages to help me find my place C C PASS1 PASS 1 MAIN PROGRAM C PASS1 *** MUSIC V *** THIS VERSION RUNS ON THE PDP10, JULY 14,1971 COMMON P(100),IP(10),D(2000) integer ipdp CHARACTER*32 FLNM CHARACTER*1 IBCD(300) CHARACTER*1 CARD(129) DATA NOPS,NBC,NC/26,3,72/ CHARACTER IDEC, ISTAR, IGAD DATA IDEC,ISTAR/'.','*'/ CHARACTER JSEMI, JBLANK CHARACTER*1 IBC(4) DATA IBC/';',' ',',','-'/ CHARACTER*1 IVT (4) CHARACTER*1 LOP (78) integer IDEF, I100 DATA IVT/'P','F','B','V'/ DATA LOP/'N','O','T','I','N','S','G','E','N','S','V','3', * 'S','E','C','T','E','R','S','V','1','S','V','2','P','L','F', * 'P','L','S','S','I','3','S','I','A','C','O','M','E','N','D', * 'O','U','T','O','S','C','A','D','2','R','A','N','E','N','V', * 'S','T','R','A','D','3','A','D','4','M','L','T','F','L','T', * 'R','A','H','S','E','T'/ EQUIVALENCE (JSEMI,IBC(1)), (JBLANK,IBC(2)) integer inputfile integer outputfile inputfile=1 outputfile=2 ipdp=0 idef=0 i100=1 99 FORMAT(' TYPE FILE NAME') 999 FORMAT(A5) PRINT 99 READ 999,FLNM open(inputfile, FILE=FLNM, STATUS='OLD') open(outputfile, FILE='pass1.data') C CALL IFILE(1,FLNM) C*****ABOVE 5 LINES FOR PDP10 ******** C INITIALIZATION C NOMINAL SAMPLING RATE. D(4) = 20000.0 C ERROR FLAG IP(2)=0 P(2)=0.0 CC NWRITE = 2 c NWRITE=20 C**** PDP DSK0=DEVICE 20 ****** CC REWIND NWRITE CC CALL READ0 c CALL READ1 GO TO 4321 C********PDP ******** C MAIN LOOP c 100 CALL READ1 100 GO TO 4321 4322 I1=P(1) IF (I1.GE.1.AND.I1.LE.12) GO TO 103 IP(2)=1 CC WRITE (6,200) PRINT 200 C********PDP ******** 200 FORMAT(' NON-EXISTENT OPCODE ON DATA STATEMENT') GO TO 100 c 103 GO TO (1,1,1,1,5,6,7,1,9,1,1,12),I1 c 1 CALL WRITE1 (NWRITE) c 1 call write1(outputfile) 103 go to (1010,1010,1010,1010,5,6,7,1010,9,1010,1010,12),I1 1010 call write1(outputfile) GO TO 100 5 PRINT 110 CC 5 WRITE (6, 110) C********PDP ******** 110 FORMAT(' END OF SECTION IN PASS 1') c GO TO 1 go to 1010 c 6 CALL WRITE1 (NWRITE) 6 call write1 (outputfile) C C WRITE (6, 111) PRINT 111 C********PDP ******** 111 FORMAT (' END OF PASS 1') IF(IP(2).EQ.1) CALL HARVEY close(inputfile) close(outputfile) CALL EXIT C SET VARIABLES IN PASS 1 7 I2=P(3) I3=I2+IP(1)-4 DO 104 I4=I2,I3 104 D(14)=P(14-I2+4) GO TO 100 9 I6=P(3) IF (I6.GE.1.AND.I6.LE.5) GO TO 107 IP(2)=1 CC WRITE (6,201) C [page 1-2] PRINT 201 C********PDP ******** 201 FORMAT(' NON-EXISTENT PLF SUBROUTINE CALLED') GO TO 100 c 12 CALL WRITE1 (NWRITE) 12 call write1(outputfile) GO TO 7 107 GO TO 100 c added^ C 107 GO TO (21,22,23,24,25),I6 C 21 CALL PLF1 C GO TO 100 C 22 CALL PLF2 C GO TO 100 C 23 CALL PLF3 C GO TO 100 C 24 CALL PLF4 C GO TO 100 C 25 CALL PLF5 C GO TO 100 c END C [page 2-1] C READ1 INTERPRETATIVE READING ROUTINE C**** MUSIC V **** c SUBROUTINE READ1 c COMMON P(100),IP(10),D(2000),IPDP,inputfile,outputfile,END,SNA8 c COMMON I,IDEF C*****PDP ***** IPDP WAS ADDED TO COMMON LIST IN PLACE OF ENTRY FEATURE c CHARACTER*1 IBCD(300) c CHARACTER*1 CARD(129) c DIMENSION CARD(129),IBCD(300),LOP(3,26) c CHARACTER*1 ICAR c was 30 c DIMENSION BCD(300) c DIMENSION IBC(4),IVT(4) c was 12 c EQUIVALENCE(CARD,ICAR) c EQUIVALENCE(BCD,IBCD) c DATA NOPS,NBC,NC/26,3,72/ c CHARACTER IDEC, ISTAR, IGAD c DATA IDEC,ISTAR/'.','*'/ CCC DATA IBC(1),IBC(2),IBC(3),IBC(4)/'=',' ',',','-'/ c DATA IBC(1),IBC(2),IBC(3),IBC(4)/';',' ',',','-'/ c CHARACTER JSEMI, JBLANK c CHARACTER*1 IBC(4) c DATA IBC/';',' ',',','-'/ C********NO!!!!! THE CHARACTER = HAS BEEN SUBSTITUTED FOR C THE SEMICOLON AS THE END OF STATEMENT DELIMITER c CHARACTER*1 IVT (4) c CHARACTER*1 LOP (78) c c integer IDEF c c DATA IVT/'P','F','B','V'/ c DATA LOP/'N','O','T','I','N','S','G','E','N','S','V','3', c * 'S','E','C','T','E','R','S','V','1','S','V','2','P','L','F', c * 'P','L','S','S','I','3','S','I','A','C','O','M','E','N','D', c * 'O','U','T','O','S','C','A','D','2','R','A','N','E','N','V', c * 'S','T','R','A','D','3','A','D','4','M','L','T','F','L','T', c * 'R','A','H','S','E','T'/ c ,0,0,0,0,0,0,0,0,0,0,0,0/ C********LAST 12 LOCATIONS NOT YET USED. **** PDP ******** c EQUIVALENCE (JSEMI,IBC(1)), (JBLANK,IBC(2)) C TO SCAN INPUT DATA TO #, ORGANIZE FIELDS AND PRINT 4321 CONTINUE IF(IPDP.EQ.0) GO TO 9999 C********PDP ******** IF ((END+SNA8-1.).gt.0.0) go to 90 10 IBK=2 END=0. ERR=0. NUMU=0 ISEMI=1 L=3 J=0 11 I=I+1 IF(I.GT.NC) GO TO 15 IF(J.EQ.299) GO TO 21 DO 13 N=1,NBC IF(CARD(I).NE.IBC(N)) GO TO 13 GO TO (20,16,18),N C ; BLA , 13 CONTINUE J=J+1 IBCD(J)=CARD(I) IBK=1 GO TO 11 14 IBK=N GO TO 11 CC 15 READ (5,1,ERR=95,END=95) (CARD(I),I=1,NC) C********PDP ******** c 15 READ (1,1,ERR=95,END=95) I, (CARD(I),I=1,NC) 15 READ (inputfile,1, ERR=95,END=95) I, (CARD(I),I=1,NC) C*****PDP ***** FIRST 'I' IS FOR PDP LINE NUMBERS! c 1 FORMAT(I,128A1) 1 FORMAT(128A1) PRINT 2121,(CARD(I),I=1,NC) 2121 FORMAT(1H 128A1) I=0 C [page 2-2] GO TO 11 16 GO TO (17,11,11),IBK 17 IBK=N J=J+1 IBCD(J)=JBLANK GO TO (11,21),ISEMI 18 GO TO (17,14,19),IBK 19 J=J+1 IBCD(J)=CHAR(0) GO TO 17 20 ISEMI=2 GO TO (17,21,19),IBK 21 J=J+1 IBCD(J)=JSEMI C TO SCAN FOR OP CODE DO 24 N=1,NOPS M=N DO 23 K=1,3 IX2=ICHAR(IBCD(K)) IF (IBCD(K).NE.LOP(K + ((N-1)*3))) GO TO 24 23 CONTINUE GO TO 26 24 CONTINUE GO TO 40 26 NP=1 27 L=L+1 IF (IBCD(L).NE.JBLANK) GO TO 27 29 GO TO (9100,9200,300,400,500,600,700,800,900,1000,1100,1200,1300, * 217,9201,202,203,204,205,206,207,208,209,210,211,212),M C OP CODE 1 TO PLAY NOTE 9100 P(1)=1. GO TO 30 C OP CODE 2 TO DEFINE INSTRUMENT 9200 P(1)=2. IDEF=1 N1=1 GO TO 70 2000 P(2)=XN N1=2 GO TO 70 2001 P(3)=XN IP(1)=3 GO TO 50 C OUT BOX 9201 P(3)=101. NPW=2 c IF (STER) 220,220,2011 if (STER.LE.0) go to 220 SNA8=1. STER=0 GO TO 220 C OSCILLATOR 202 P(3)=102. NPW=5 GO TO 220 C ADD 2 203 P(3)=103. NPW=3 GO TO 220 C RANDOM AND INTERPOLATE 204 P(3)=104. NPW=6 C [page 2-3] GO TO 220 C LINEAR ENVELOPE GENERATOR 205 P(3)=105. NPW=7 GO TO 220 C STEREO OUT BOX 206 P(3)=106. NPW=3 c IF(STER)220,2061,220 if (STER.NE.0) go to 220 c 2061 SNA8=1. SNA8=1. STER=1. GO TO 220 C THREE INPUT ADDER 207 P(3)=107. NPW=4 GO TO 220 C FOUR INPUT ADDER 208 P(3)=108. NPW=5 GO TO 220 C MULTIPLIER 209 P(3)=109. NPW=3 GO TO 220 C FILTER 210 P(3)=112. NPW=4 GO TO 220 C RANDOM AND HOLD 211 P(3)=111. NPW=5 GO TO 220 C SET NEW FUNCTION 212 P(3)=110. NPW=1 GO TO 220 C END OF INSTRUMENT 217 IP(1)=2 IDEF=0 END=1. GO TO 50 C UNNAMED UNIT - NUMERICAL NAME ASSUMED 218 N1=8 NUMU=1 L=0 GO TO 70 219 M=XN+14. IF(XN.LT.11.)GO TO 29 P(3)=XN C TO INTERPRET VARS IN UNIT DEFS 220 NP=3 221 IF(IBCD(L+1).EQ.JSEMI) GO TO 240 c 222 NP=NP+1 NP=NP+1 L=L+1 DO 223 N=1,4 IF(IBCD(L).EQ.IVT(N)) GO TO 225 223 CONTINUE 224 L=L+1 IF(IBCD(L).EQ.JBLANK)GO TO 46 GO TO 224 C [page 2-4] 225 GO TO (231,232,233,234),N C P TYPE 231 N1=3 GO TO 70 2311 P(NP)=XN GO TO 221 C F TYPE 232 N1=4 GO TO 70 2321 P(NP)=-(XN+100.) GO TO 221 C B TYPE 233 N1=5 GO TO 70 2331 P(NP)=-XN GO TO 221 C V TYPE 234 N1=6 GO TO 70 2341 P(NP)=XN+100. GO TO 221 240 IF(NUMU.EQ.1)GO TO 242 c 241 IF(NPW+3-NP)42,242,42 if (NPW+3-NP.NE.0) go to 42 242 IP(1)=NP GO TO 50 C OP CODE 3 - TO GENERATE FUNCTION 300 P(1)=3. GO TO 30 C OP CODE 4 -- TO SET PARAM 3RD PASS 400 P(1)=4. GO TO 30 C OP CODE 5 TO END SEC 500 P(1)=5. GO TO 30 C OP CODE 6 TO TERMINATE PIECE 600 P(1)=6. GO TO 30 C OP CODE 7 TO SET PARAM 1ST PASS 700 P(1)=7. GO TO 30 C OP CODE 8 TO SET PARAM 2ND PASS 800 P(1)=8. GO TO 30 C OP CODE 9 TO EXECUTE SUB 1ST PASS 900 P(1)=9. GO TO 30 C OP CODE 10 TO EXECUTE SUB 2ND PASS 1000 P(1)=10. GO TO 30 C OP CODE 11 TO SET INTEGER 3RD PASS 1100 P(1)=11. GO TO 30 C OP CODE 12 TO SET INTEGER ALL PASSES 1200 P(1)=12. GO TO 30 C OP CODE 13 FOR COMMENTS 1300 IF(IBCD(L).NE.JSEMI) GO TO 1301 L=L+1 go to 4321 c ? COM causes an infinite loop in the original code 1301 L=L+1 GO TO 1300 C TO STORE PFIELDS C [page 2-5] c 30 IF(IDEF)32,32,43 30 continue if (IDEF.gt.0) go to 43 32 IF(IBCD(L+1).EQ.JSEMI) GO TO 34 NP=NP+1 N1=7 GO TO 70 331 P(NP)=XN GO TO 32 34 IP(1)=NP c IF(NP-1)47,47,50 if (NP-1.gt.0) go to 50 go to 47 C ERRORS c 40 IF(IDEF)41,41,218 40 if (IDEF.gt.0) go to 218 41 L=L+1 IF(IBCD(L).NE.JSEMI)GO TO 41 PRINT 1030 1030 FORMAT(26H OP CODE NOT UNDERSTOOD) GO TO 49 42 PRINT 1040 1040 FORMAT(44H UNIT CONTAINS WRONG NUMBER OF PARAMETERS) GO TO 49 43 PRINT 1050 1050 FORMAT(36H INSTRUMENT DEFINITION INCOMPLETE) ERR=1. IDEF=0 GO TO 32 44 PRINT 1060 1060 FORMAT(25H ERROR IN NUMERIC DATA) ERR=1. IF(NUMU.EQ.1)GO TO 45 GO TO 30 45 PRINT 1070 1070 FORMAT(46H FOR UNIT DESIGNATION) P(3)=0. GO TO 220 46 PRINT 1080 1080 FORMAT(40H IMPROPER VARIABLE IN UNIT DEFINITION) ERR=1. GO TO 221 47 PRINT 1090 1090 FORMAT(24H STATEMENT INCOMPLETE) 49 IP(2)=1 GO TO 10 50 IF(ERR.EQ.1.) GO TO 49 goto 4322 c RETURN C CONVERSION OF NUMERIC FIELD TO FLOATING POINT 70 SGN=1. IF (IBCD(L+1).NE.IBC(4)) GO TO 79 SGN=-1. L=L+1 79 L1=L+1 LD=L1 XN=0. 71 L=L+1 C *** I DON'T UNDERSTAND THIS PART OF THE SCANNER! CC IF(IBCD(L).EQ.JBLANK) GO TO 77 IF (IBCD(L).EQ.JBLANK) GO TO 77 C THIS LOOKS FOR #S, LETTERS, BLANKS, DECI.PTS, & *S. OTHERWISE=ERROR!? C ******** PDP ******** IF(IBCD(L).LT.CHAR(10))GO TO 71 IF(IBCD(L).EQ.IDEC) GO TO 71 IF(IBCD(L).EQ.ISTAR) GO TO 71 C [page 2-6] 76 GO TO 71 C ERROR CHECK IS REMOVED! C** NEXT 2 LINES BY-PASSED*** 76 L=L+1 IF(IBCD(L).EQ.JBLANK) GO TO 44 GO TO 76 77 IF(IBCD(L1).NE.ISTAR) GO TO 80 XN=P(NP) GO TO 89 80 DO 81 LL=L1,L LD=LL IF (IBCD(LL).EQ.IDEC) GO TO 82 81 CONTINUE 82 IEX=0 LA=L1 LB=LD-1 c IF(LD-L1)86,86,83 if((LD-L1).LE.0) go to 86 IEX=LD-LA 84 continue c 84 CALL MOVR (IBCD,LA,LB) DO 85 LL=LA,LB IEX=IEX-1 IGAD=IBCD(LL) IX1=ICHAR(IGAD)-ICHAR('0') XN=XN+IX1*10.**IEX 85 continue c 86 IF(L-LB-2)88,88,87 86 if(L-LB-2.le.0) go to 88 LA=LD+1 LB=L-1 GO TO 84 88 XN=XN*SGN 89 GO TO (2000,2001,2311,2321,2331,2341,331,219),N1 C TO WRITE S1A8 FOR MONO STEREO CONTROL 90 P(1)=12. P(3)=8. P(4)=STER IP(1)=4 END=0. SNA8=0. GO TO 50 C FOR PREMATURE END OF FILE ON INPUT 95 NP=2 IP(2)=1 L=0 IBCD(1)=JSEMI GO TO 600 C TO INITIALIZE CC ENTRY READ0 CC READ (5,1,ERR=95,END=95) (CARD(I),I=1,NC) C********PDP ******** 9999 READ (inputfile,1,ERR=95,END=95) I,(CARD(I),I=1,NC) C*****PDP ***** FIRST 'I' IS FOR PDP LINE NUMBERS! CC WRITE (6,2) (CARD(I),I=1,NC) PRINT 2111,(CARD(I),I=1,NC) 2111 FORMAT(1H 128A1) C********PDP ******** IPDP=1 I=0 IDEF=0 IBK=2 STER=0. END=0. SNA8=0. if (i100.eq.0) go to 4322 i100=0 go to 100 c RETURN END C WRITE1 PASS 1 DATA-WRITING ROUTINE C *** MUSIC V *** SUBROUTINE WRITE1(N) COMMON P(100),IP(10),D(2000) c COMMON P(100),IP(10) K=IP(1) WRITE(N, *)K, (P(J),J=1,K) RETURN END c SUBROUTINE PLF c COMMON P(100),IP(10),D(2000) CC ENTRY PLF1 CC ENTRY PLF2 CC ENTRY PLF3 CC ENTRY PLF4 CC ENTRY PLF5 c END C ERRO1 GENERAL ERROR ROUTINE C ***MUSIC V *** SUBROUTINE ERROR(I) PRINT 8100,I 8100 FORMAT(13HERROR OF TYPEI5) RETURN END SUBROUTINE HARVEY CC WRITE (6,1) PRINT 1011 C********PDP ********* 1011 FORMAT(' WHERE IS HARVEY') CALL EXIT END c SUBROUTINE MOVR(IBCD,LA,LB) c DIMENSION IBCD(300) C DO 1 J=LA,LB C 1 IBCD(J)=IBCD(J)-ICHAR('0') C CC 1 IBCD(J)=I5-(IBCD(J))/16777216 C********PDP ******** C 1 IBCD(J)=IBCD(J)/536870912-48 C 2 DUMMY=0 C TO SET BREAKPOINT. c RETURN c END C ----------------------------------- cut here --------------------------------------------- C pass2 C PASS 2 MAIN PROGRAM C *** MUSIC V *** DIMENSION G(1000),I(1000),T(1000),D(10000),P(100),IP(10) COMMON IP,P,G,I,T,D,IXJQ,TLAST,BLAST integer inputfile integer outputfile C INITIALIZING PROGRAM C NOMINAL SAMPLING RATE, NOTE PARAMETER LENGTH, NUMBER OF CARDS C NO OF OP CODES, PASS 11 REPORT PRINT PARAMETER G(1)=0. G(2)=0. G(4)=10000.0 NPAR=10000 NCAR=1000 NOPC=12 IXJQ=0 IEND=0 C C***** NREAD=2 C C***** NWRITE=3 c NREAD=20 c NWRITE=21 c REWIND NREAD c REWIND NWRITE inputfile=1 outputfile=2 open(inputfile, FILE='pass1.data', STATUS='OLD') open(outputfile, FILE='pass2.data') C INITIALIZE SECTION 150 ID=1 IN=1 TLAST=0. BLAST=0. C READ SECTION OF DATA c 106 CALL READ2 (NREAD) 106 CALL READ2 (inputfile) I1=IP(1) D(ID)=I1 I(IN)=ID T(IN)=P(2) DO 100 I2=1,I1 I3=ID+I2 c 100 D(13)=P(I2) D(I3)=P(I2) 100 continue ID=ID+I1+1 c IF(ID-NPAR)102,102,101 IF((ID-NPAR).le.0) go to 102 101 CALL ERROR(20) STOP 102 IN=IN+1 c IF (IN-NCAR)103,103,101 IF ((IN-NCAR).gt.0) go to 101 c 103 IF (P(1)-5.0)104,110,104 IF ((P(1)-5.0).eq.0.0) go to 110 c 104 IF (P(1)-6.0)106,105,106 IF ((P(1)-6.0).ne.0.0) go to 106 c 105 IEND=1 IEND=1 GO TO 110 C SORT SECTION C*** NOT USED ****** 110 CALL SORTFL 110 IN=IN-1 c CALL SORT(T(1),T(2),IN,I) CALL SORT(T(1),IN,I) C EXECUTE OP CODES M SECTION c 120 DO 1 I4=1,IN DO 1 I4=1,IN I5=I(I4) I6=D(I5+1) c IF(I6)121,121,122 IF(I6.gt.0) go to 122 121 CALL ERROR(21) GO TO 1 c 122 IF (I6-NOPC)123,123,121 122 IF ((I6-NOPC).gt.0) go to 121 c 123 GO TO (2,2,2,2,2,2,7,8,7,10,2,8),I6 GO TO (2,2,2,2,2,2,7,8,7,10,2,8),I6 7 CALL ERROR(22) GO TO 1 C [page 3-2] 8 I7=D(I5) I8=I5+4 I9=I5+I7 I10=IFIX(D(15+3))-I8 DO 124 I11=I8,I9 I12=I10+I11 124 G(I12)=D(I11) c IF(I6-I2)1,2,1 IF((I6-I2).eq.0) go to 2 go to 1 10 I13=D(I5+3) IP(2)=I5 c IF(I13)125,125,126 IF(I13.gt.0) go to 126 125 CALL ERROR(23) GO TO 1 c 126 IF(I13-5)127,127,125 126 IF((I13-5).gt.0) go to 125 c 127 GO TO (21,22,23,24,25),I13 GO TO (21,22,23,24,25),I13 21 CALL PLS1 GO TO 1 22 CALL PLS2 GO TO 1 23 CALL PLS3 GO TO 1 24 CALL PLS4 GO TO 1 25 CALL PLS5 GO TO 1 C WRITE OUT SECTION 2 IP(1)=D(I5) I18=IP(1) DO 133 I19=1,I18 I20=I19+I5 133 P(I19)=D(I20) c CALL WRITE2 (NWRITE) CALL WRITE2 (outputfile) 1 CONTINUE C END OF SECTION OR PASS c 140 IF(IEND)141,141,143 IF(IEND.gt.0) go to 143 c 141 PRINT 142 PRINT 142 142 FORMAT (' END OF SECTION PASS II') GO TO 150 143 PRINT 144 144 FORMAT (' END OF PASS II') close(inputfile) close(outputfile) STOP END C READ2 PASS 2 DATA INPUT ROUTINE C *** MUSIC V *** SUBROUTINE READ2(N) DIMENSION IP(10),P(100) COMMON IP,P c READ(N) K,(P(J),J=1,K) READ(N, *) K,(P(J),J=1,K) IP(1)=K RETURN END C SORT SORTING PROGRAM C *** MUSIC V *** c SUBROUTINE SORT(A,B,N,L) SUBROUTINE SORT(A,N,L) DIMENSION A(N),L(N) C C SORT SORTS THE A ARRAY INTO ASCENDING NUMERICAL ORDER, PERFORMING C THE SAME OPERATIONS ON ARRAY L AS ON A C N1=N-1 C [page 3-3] DO 10 I=1,N1 IN=I+1 DO 20 J=IN,N IF(A(I).LE.A(J))GO TO 20 T=A(I) A(I)=A(J) A(J)=T NT=L(I) L(I)=L(J) L(J)=NT 20 CONTINUE 10 CONTINUE RETURN C C*********** ENTRY SORTFL C C*********** RETURN END C WRIT2 DATA OUTPUTING ROUTINE FOR PASS 2 C *** MUSIC V *** SUBROUTINE WRITE2(N) COMMON IP(10),P(100),G(1000),I(1000),T(1000),D(10000),IXJQ,TLAST, *BLAST IF(G(2).EQ.0.)GO TO 150 X=P(2) Y=P(4) ILOC=G(2) IF(P(1).NE.1.)GO TO 50 c P(4)=P(4)*60./CON(G,ILOC,P(2)) P(4)=P(4)*60./CON(G,P(2)) c 50 P(2)=TLAST+(P(2)-BLAST)*60./CON(G,ILOC,P(2)) 50 P(2)=TLAST+(P(2)-BLAST)*60./CON(G,P(2)) TLAST=P(2) BLAST=X 150 CALL CONVT K=IP(1) WRITE(N, *) K,(P(J),J=1,K) C *** PASS II REPORT IS OPTIONAL *** IF(G(1).NE.0.) RETURN IF(IXJQ.EQ.0) PRINT 100 IXJQ=10 100 FORMAT(15H1PASS II REPORT/11H0(WORD CNT)) PRINT 101,K,(P(J),J=1,K) IF(G(2).NE.0.) PRINT 102,X,Y 101 FORMAT(I8,10(F9.3)) 102 FORMAT(1H+,110X,2HB=,F7.4,2HD=,F7.4) RETURN END C CON2 PASS 2 FUNCTION INTERPOLATOR C *** MUSIC V *** c FUNCTION CON(G,I,T) FUNCTION CON(G,T) DIMENSION G(1) DO 10 J=1,1000,2 c IF (G(J)-T) 10,20,30 if ((G(J)-T).eq.0) go to 20 if ((G(J)-T).lt.0) go to 10 c 30 CON = G(J-1)+((T-G(J-2))/(G(J)-G(J-2)))*(G(J+1)-G(J-1)) CON = G(J-1)+((T-G(J-2))/(G(J)-G(J-2)))*(G(J+1)-G(J-1)) RETURN 10 CONTINUE 20 CON = G(J+1) RETURN END C CONVT FOR UNIT GENERATORS CHECK C C DUMMY NO OPERATION ACTUALLY PERFORMED C******WHEN DUMMY IS REMOVED ANOTHER CONVT MUST!!!! BE LOADED!!!***** C [page 3-4] C*** SUBROUTINE CONVT C*** COMMON IP(10),P(100),G(1000) C*** RETURN C*** END c added back in SUBROUTINE CONVT COMMON IP(10),P(100),G(1000) RETURN END C ERRO1 GENERAL ERROR ROUTINE C *** MUSIC V *** SUBROUTINE ERROR(I) PRINT 100,I 100 FORMAT(' ERROR OF TYPE',I5) RETURN END C C***** SUBROUTINE PLS C C***** ENTRY PLS1 C C***** ENTRY PLS2 C C***** ENTRY PLS3 C C***** ENTRY PLS4 C C***** ENTRY PLS5 SUBROUTINE PLS1 RETURN END SUBROUTINE PLS2 RETURN END SUBROUTINE PLS3 RETURN END SUBROUTINE PLS4 RETURN END SUBROUTINE PLS5 RETURN END C [page 4-1] C ----------------------------------- cut here --------------------------------------------- C pass3 C PASS3 PASS 3 MAIN PROGRAM C *** MUSIC V *** C DATA SPECIFICATION INTEGER PEAK DIMENSION T(50),TI(50),ITI(50) COMMON I(15000),P(100)/PARM/IP(21)/FINOUT/PEAK,NRSOR C C******** DATA IIIRD/Z5EECE66D/ DATA IP/12,512,20000,14500,14400,512,13000,35,40,6657,2048, * 1000000,6657,512,7777777,6*0/ DATA IIIRD/976545367/ C SET I ARRAY =0 (7/10/69) DATA I/15000*0/ c CHARACTER*1 JSTR(5) c CHARACTER*1 FLNM(32) integer inputfile integer outputfile C***************** C INITIALIZATION OF PIECE C ARBITRARY STARTING NUMBER FOR SUBROUTINE RANDU inputfile=1 outputfile=2 open(inputfile, FILE='pass2.data', STATUS='OLD') c open(outputfile, FILE='pass3.data') open(outputfile, * FILE='raw.snd', * form='unformatted', * access='direct', * status='replace', * recl=4) I(7)=IIIRD IP9=IP(9) PEAK=0 NRSOR=0 C********NREAD=3 C********NWRITE=2 c NREAD=21 C PDP DSK1=DEV.21 c NWRITE=1 C PDP DSK=DEV.1 c REWIND NREAD c REWIND NWRITE c PRINT 10001 c READ 10002,FLNM,IDSK C PRINT 'PASS2' OR FILENAME + ANY POS.NUMB. TO WRITE SMPLS ON DSK. c IF(FLNM.EQ.' '.OR.FLNM.EQ.'PASS2')FLNM='FOR21' c CALL IFILE(21,FLNM) c IF(IDSK.LE.0) GO TO 10003 c JSTR='MUSAA' c CALL PUTFILE(JSTR) C IF IDSK>=1, SAMPLES WILL BE WRITTEN ON DSK (MUSAA.DMD) c IDSK=0 IDSK=1 c GO TO 10004 c 10003 IDSK=-1 c 10001 FORMAT(' TYPE FILE NAME'/) c 10002 FORMAT(A5) C**** ABOVE FOR PDP 10 ****** c 10004 SCLFT=IP(12) SCLFT=IP(12) I(2)=IP(4) MS1=IP(7) MS3=MS1+(IP(8)*IP(9))-1 MS2=IP(8) I(4)=IP(3) MOUT=IP(10) C INITIALIZATION OF SECTION 5 T(1)=0.0 DO 220 N1=MS1,MS3,MS2 I(N1)=-1 220 CONTINUE DO 221 N1=1,IP9 TI(N1)=1000000.0 221 CONTINUE C MAIN CARD READING LOOP c 204 CALL DATA (NREAD) 204 CALL DATA (inputfile) c IF(P(2)-T(1))200,200,244 IF((P(2)-T(1)).gt.0.0) go to 244 200 IOP=P(1) c IF(IOP)201,201,202 IF(IOP.gt.0) go to 202 201 CALL ERROR(1) GO TO 204 C [page 4-2] c 202 IF(IP(1)-IOP)201,203,203 202 IF((IP(1)-IOP).lt.0) go to 201 c 203 GO TO (1,2,3,4,5,6,201,201,201,201,11,11),IOP GO TO (1,2,3,4,5,6,201,201,201,201,11,11),IOP 11 IVAR=P(3) IVARE=IVAR+I(1)-4 DO 297 N1=IVAR,IVARE IVARP=N1-IVAR+4 297 I(N1)=P(IVARP) GO TO 204 3 IGEN=P(3) GO TO (281,282,283,284,285),IGEN 281 CALL GEN1 GO TO 204 282 CALL GEN2 GO TO 204 283 CALL GEN3 GO TO 204 284 CALL GEN4 GO TO 204 285 CALL GEN5 GO TO 204 4 IVAR=P(3) IVARE=IVAR+I(1)-4 DO 296 N1=IVAR,IVARE IVARP=N1-IVAR+4 296 I(N1+100)=P(IVARP)*SCLFT GO TO 204 c 6 CALL FROUT3(IDSK) 6 continue K=IP(10) L=IP(10)+IP(14)-1 DO 1001 J=K,L I(J)=0 1001 CONTINUE CALL SAMOUT(IDSK,IP(14), outputfile) C REWIND NWRITE C WRITE(6,10) PEAK,NRSOR C PRINT 10,PEAK,NRSOR C 10 FORMAT ('0PEAK AMPLITUDE WAS',I8/'0NUMBER OF SAMPLES OUT OF RANGE WAS',I8) C CALL EXIT IF(IDSK.LT.0)CALL EXIT J=IP(10) L=J+1024 DO 2001 K=J,L I(K)=0 2001 CONTINUE C WILL WRITE 1024 0'S ON DSK. CALL FASTOUT(I(J),1024, outputfile) c CALL FINFILE close(inputfile) close(outputfile) CALL EXIT c END c STOP C ENTER NOTE TO BE PLAYED 1 DO 230 N1=MS1,MS3,MS2 c IF(I(N1)+1)230,231,230 IF((I(N1)+1).eq.0) go to 231 230 CONTINUE CALL ERROR(2) GO TO 204 231 M1=N1 M2=N1+I(1)-1 M3=M2+1 M4=N1+IP(8)-1 DO 232 N1=M1,M2 M5=N1-M1+1 232 I(N1)=P(M5)*SCLFT I(M1)=P(3) DO 233 N1=M3,M4 233 I(N1)=0 DO 235 N1=1,IP9 c IF(TI(N1)-1000000.)235,234,235 IF(TI(N1).ne.1000000.) go to 235 c 234 TI(N1)=P(2)+P(4) TI(N1)=P(2)+P(4) ITI(N1)=M1 GO TO 204 235 CONTINUE CALL ERROR(3) GO TO 204 C DEFINE INSTRUMENT 2 M1=I(2) M2=IP(5)+IFIX(P(3)) I(M2)=M1 c 218 CALL DATA (NREAD) 218 CALL DATA (inputfile) c IF(I(1)-2)210,210,211 IF(I(1).gt.2) go to 211 c 210 I(M1)=0 I(M1)=0 I(2)=M1+1 C [page 4-3] GO TO 204 211 I(M1)=P(3) M3=I(1) I(M1+1)=M1+M3-1 M1=M1+2 DO 217 N1=4,M3 M5=P(N1) c IF(M5)212,213,213 IF(M5.ge.0) go to 213 c 212 IF(M5+100)300,301,301 IF((M5+100).ge.0) go to 301 c 300 I(M1)=-IP(2)+(M5+101)*IP(6) I(M1)=-IP(2)+(M5+101)*IP(6) GO TO 216 301 I(M1)=-IP(13)+(M5+1)*IP(14) GO TO 216 c 213 IF(M5-100)214,214,215 213 IF((M5-100).gt.0) go to 215 c 214 I(M1)=M5 I(M1)=M5 GO TO 216 215 I(M1)=M5+262144 216 M1=M1+1 217 CONTINUE GO TO 218 C PLAY TO ACTION TIME 244 T(2)=P(2) 250 TMIN=1000000. IREST=1 DO 241 N1=1,IP9 c IF(TMIN-TI(N1))241,241,240 IF(TMIN.le.TI(N1)) go to 241 c 240 TMIN=TI(N1) TMIN=TI(N1) MNOTE=N1 241 CONTINUE c IF(1000000.-TMIN)251,251,243 IF(1000000.0.le.TMIN)go to 251 c 243 IF(TMIN-T(2))245,245,246 IF(TMIN.gt.T(2)) go to 246 c 245 T(3)=TMIN T(3)=TMIN GO TO 260 246 T(3)=T(2) GO TO 260 c 247 IF(T(1)-T(2))249,200,200 247 IF(T(1).ge.T(2)) go to 200 c 249 TI(MNOTE)=1000000. TI(MNOTE)=1000000. M2=ITI(MNOTE) I(M2)=-1 GO TO 250 C SETUP REST 251 T(3)=T(2) IREST=2 GO TO 260 C PLAY 260 ISAM=(T(3)-T(1))*FLOAT(I(4))+.5 T(1)=T(3) c IF(ISAM)247,247,266 IF(ISAM.le.0) go to 247 c 266 IF(ISAM-IP(14))262,262,263 266 IF(ISAM.gt.IP(14))go to 263 c 262 I(5)=ISAM I(5)=ISAM ISAM=0 GO TO 264 263 I(5)=IP(14) ISAM=ISAM-IP(14) c 264 IF(I(8))290,290,291 264 IF(I(8).gt.0) go to 291 c 290 M3=MOUT+I(5)-1 M3=MOUT+I(5)-1 MSAMP=I(5) GO TO 292 291 M3=MOUT+(2*I(5))-1 MSAMP=2*I(5) C [page 4-4] 292 DO 267 N1=MOUT,M3 267 I(N1)=0 GO TO (268,265),IREST 268 DO 270 NS1=MS1,MS3,MS2 c IF(I(NS1)+1)271,270,271 IF((I(NS1)+1).eq.0) go to 270 C GO THROUGH UNIT GENERATORS IN INSTRUMENT c 271 I(3)=NS1 I(3)=NS1 IGEN=IP(5)+I(NS1) IGEN=I(IGEN) 272 I(6)=IGEN CC***** IF((IGEN)-101)293,294,294 CC***** 293 CALL SAMGEN(I) CC***** ABOVE FOR MACHINE LANG. UNIT GENERATORS ****** CC***** GO TO 295 c 294 CALL FORSAM CALL FORSAM c 295 IGEN=I(IGEN+1) IGEN=I(IGEN+1) c IF(I(IGEN))270,270,272 IF(I(IGEN).gt.0) go to 272 270 CONTINUE 265 CALL SAMOUT(IDSK,MSAMP, outputfile) c IF(ISAM)247,247,266 IF(ISAM.le.0) go to 247 go to 266 END C [page 5-1] C FORS3 FORTRAN UNIT GENERATOR ROUTINE C *** MUSIC V *** SUBROUTINE FORSAM DIMENSION I(15000),P(100),IP(21),L(8),M(8) COMMON I,P/PARM/IP EQUIVALENCE (M1,M(1)),(M2,M(2)),(M3,M(3)),(M4,M(4)),(M5,M(5)) EQUIVALENCE (M6,M(6)),(M7,M(7)),(M8,M(8)),(L1,L(1)),(L2,L(2)) EQUIVALENCE (L3,L(3)),(L4,L(4)),(L5,L(5)),(L6,L(6)),(L7,L(7)) EQUIVALENCE (L8,L(8)),(RN1,IRN1),(RN3,IRN3),(RN,IRN) C C***** DATA IMULT/Z5EECE66D/ DATA IIIRD/976545367/ SFI=1./FLOAT(IP(12)) SFF=1./FLOAT(IP(15)) SFID=FLOAT(IP(12)) SFXX=FLOAT(IP(12))/FLOAT(IP(15)) XNFUN=IP(6)-1 C COMMON INITIALIZATION OF GENERATORS N1=I(6)+2 N2=I(N1-1)-1 DO 204 J1=N1,N2 J2=J1-N1+1 c IF(I(J1))200,201,201 IF(I(J1).ge.0) go to 201 c 200 L(J2)=-I(J1) L(J2)=-I(J1) M(J2)=1 GO TO 204 201 M(J2)=0 c IF(I(J1)-262144)202,202,203 IF((I(J1)-262144).gt.0) go to 203 C*****WHAT DOES THE BIG NUMBER DO????? c 202 L(J2)=I(J1)+I(3)-1 L(J2)=I(J1)+I(3)-1 GO TO 204 203 L(J2)=I(J1)-262144 204 CONTINUE NSAM=I(5) N3=I(N1-2) NGEN=N3-100 GO TO (101,102,103,104,105,106,107,108,109,110,111,112),NGEN 112 RETURN C UNIT GENERATORS C OUTPUT BOX c 101 IF(M1)260,260,261 101 IF(M1.gt.0) go to 261 c 260 IN1=I(L1) IN1=I(L1) 261 CONTINUE DO 270 J3=1,NSAM c IF(M1)265,265,264 IF(M1.le.0) go to 265 c 264 J4=L1+J3-1 J4=L1+J3-1 IN1=I(J4) 265 J5=L2+J3-1 I(J5)=IN1+I(J5) 270 CONTINUE RETURN C OSCILLATOR 102 SUM=FLOAT(I(L5))*SFI c IF(M1)280,280,281 IF(M1.gt.0) go to 281 c 280 AMP=FLOAT(I(L1))*SFI AMP=FLOAT(I(L1))*SFI c 281 IF(M2)282,282,283 281 IF(M2.gt.0) go to 283 c 282 FREQ=FLOAT(I(L2))*SFI FREQ=FLOAT(I(L2))*SFI 283 CONTINUE DO 293 J3=1,NSAM J4=INT(SUM)+L4 F=FLOAT(I(J4)) C [page 5-2] c IF(M2)285,285,286 IF(M2.gt.0) go to 286 c 285 SUM=SUM+FREQ SUM=SUM+FREQ GO TO 290 286 J4=L2+J3-1 SUM=SUM+FLOAT(I(J4))*SFI C C 290 IF(SUM-XNFUN)288,287,287 290 IF(SUM.GE.XNFUN)GO TO 287 C C 287 SUM=SUM-XNFUN IF(SUM.LT.0.0)GO TO 289 288 J5=L3+J3-1 c IF(M1)291,291,292 IF(M1.gt.0) go to 292 c 291 I(J5)=IFIX(AMP*F*SFXX) I(J5)=IFIX(AMP*F*SFXX) GO TO 293 C************ 287 SUM=SUM-XNFUN GO TO 288 289 SUM=SUM+XNFUN GO TO 288 C**********ABOVE FOR FM (NEG. FREQ. TO OSCIL) 292 J6=L1+J3-1 I(J5)=IFIX(FLOAT(I(J6))*F*SFF) 293 CONTINUE I(L5)=IFIX(SUM*SFID) RETURN C ADD TWO BOX c 103 IF(M1)250,250,251 103 IF(M1.gt.0) go to 251 c 250 IN1=I(L1) IN1=I(L1) c 251 IF(M2)252,252,253 251 IF(M2.gt.0) go to 253 c 252 IN2=I(L2) IN2=I(L2) 253 DO 258 J3=1,NSAM c IF(M1)255,255,254 IF(M1.le.0) go to 255 c 254 J4=L1+J3-1 J4=L1+J3-1 IN1=I(J4) c 255 IF(M2)257,257,256 255 IF(M2.le.0) go to 257 c 256 J5=L2+J3-1 J5=L2+J3-1 IN2=I(J5) 257 J6=L3+J3-1 I(J6)=IN1+IN2 258 CONTINUE RETURN C RANDOM INTERPOLATING GENERATOR 104 SUM=FLOAT(I(L4))*SFI c IF(M1)310,310,311 IF(M1.gt.0) go to 311 c 310 XIN1=FLOAT(I(L1))*SFI XIN1=FLOAT(I(L1))*SFI c 311 IF(M2)312,312,313 311 IF(M2.gt.0) go to 313 c 312 XIN2=FLOAT(I(L2))*SFI XIN2=FLOAT(I(L2))*SFI 313 IRN1=I(L5) IRN3=I(L6) DO 340 J3=1,NSAM c IF(M1)316,316,315 IF(M1.le.0) go to 316 c 315 J4=L1+J3-1 J4=L1+J3-1 XIN1=FLOAT(I(J4))*SFI c 316 IF(M2)318,318,317 316 IF(M2.le.0) go to 318 c 317 J5=L2+J3-1 J5=L2+J3-1 XIN2=FLOAT(I(J5))*SFI c 318 IF(SUM-XNFUN)320,319,319 318 IF((SUM-XNFUN).lt.0.0) go to 320 c 319 SUM=SUM-XNFUN SUM=SUM-XNFUN I(7)=IABS(I(7)*IMULT) RN4=(2.*FLOAT(I(7))*SFF-1.) RN2=RN4-RN3 C [page 5-3] RN1=RN3 RN3=RN4 GO TO 321 320 RN2=RN3-RN1 321 J7=L3+J3-1 I(J7)=XIN1*(RN1+(RN2*SUM)/XNFUN)*SFID SUM=SUM+XIN2 340 CONTINUE I(L4)=IFIX(SUM*SFID) I(L5)=IRN1 I(L6)=IRN3 RETURN C ENVELOPE GENERATOR 105 SUM=FLOAT(I(L7))*SFI c IF(M1)380,380,381 IF(M1.gt.0) go to 381 c 380 XIN1=FLOAT(I(L1))*SFI XIN1=FLOAT(I(L1))*SFI c 381 IF(M4)382,382,383 381 IF(M4.gt.0) go to 383 c 382 XIN4=FLOAT(I(L4))*SFI XIN4=FLOAT(I(L4))*SFI c 383 IF(M5)384,384,385 383 IF(M5.gt.0) go to 385 c 384 XIN5=FLOAT(I(L5))*SFI XIN5=FLOAT(I(L5))*SFI c 385 IF(M6)386,386,387 385 IF(M6.gt.0) go to 387 c 386 XIN6=FLOAT(I(L6))*SFI XIN6=FLOAT(I(L6))*SFI 387 X1=XNFUN/4. X2=2.*X1 X3=3.*X1 DO 403 J3=1,NSAM J4=INT(SUM)+L2 F=FLOAT(I(J4)) c IF(M1)405,405,404 IF(M1.le.0) go to 405 c 404 J8=L1+J3-1 J8=L1+J3-1 XIN1=FLOAT(I(J8))*SFI c 405 IF(SUM-XNFUN)389,388,388 405 IF((SUM-XNFUN).lt.0.0) go to 389 c 388 SUM=SUM-XNFUN SUM=SUM-XNFUN c 389 IF(SUM-X1)390,390,393 389 IF((SUM-X1).gt.0.0) go to 393 c 390 IF(M4)392,392,391 IF(M4.le.0) go to 392 c 391 J4=L4+J3-1 J4=L4+J3-1 XIN4=FLOAT(I(J4))*SFI 392 SUM=SUM+XIN4 GO TO 402 c 393 IF(SUM-X2)394,394,397 393 IF((SUM-X2).gt.0.0) go to 397 c 394 IF(M5)396,396,395 IF(M5.le.0) go to 396 c 395 J5=L5+J3-1 J5=L5+J3-1 XIN5=FLOAT(I(J5))*SFI 396 SUM=SUM+XIN5 GO TO 402 c 397 IF(M6)400,400,399 397 IF(M6.le.0) go to 400 c 399 J6=L6+J3-1 J6=L6+J3-1 XIN6=FLOAT(I(J6))*SFI 400 SUM=SUM+XIN6 402 J7=L3+J3-1 I(J7)=IFIX(XIN1*F*SFXX) 403 CONTINUE I(L7)=IFIX(SUM*SFID) RETURN C STEREO OUTPUT BOX c 106 IF(M1)500,500,501 106 IF(M1.gt.0) go to 501 c 500 IN1=I(L1) IN1=I(L1) c 501 IF(M2)502,502,503 501 IF(M2.gt.0) go to 503 c 502 IN2=I(L2) IN2=I(L2) 503 NSSAM=2*NSAM C [page 5-4] C 6/29/70 L.C.SMITH ICT=0 DO 510 J3=1,NSSAM,2 c IF(M1) 505,505,504 IF(M1.le.0) go to 505 C C*** 504 J4=L1+J3-1 c 504 J4=L1+ICT J4=L1+ICT IN1=I(J4) 505 J5=L3+J3-1 I(J5)=IN1+I(J5) c IF(M2)507,507,506 IF(M2.le.0) go to 507 C C*** 506 J4=L2+J3-1 c 506 J4=L2+ICT J4=L2+ICT IN2=I(J4) 507 J5=L3+J3 I(J5)=IN2+I(J5) 510 CONTINUE RETURN C ADD 3 BOX c 107 IF(M1)750,750,751 107 IF(M1.gt.0) go to 751 c 750 IN1=I(L1) IN1=I(L1) c 751 IF(M2)752,752,753 751 IF(M2.gt.0) go to 753 c 752 IN2=I(L2) IN2=I(L2) c 753 IF(M3)754,754,755 753 IF(M3.gt.0) go to 755 c 754 IN3=I(L3) IN3=I(L3) 755 DO 780 J3=1,NSAM c IF(M1)757,757,756 IF(M1.le.0) go to 757 c 756 J4=L1+J3-1 J4=L1+J3-1 IN1=I(J4) c 757 IF(M2)759,759,758 757 IF(M2.le.0) go to 759 c 758 J5=L2+J3-1 J5=L2+J3-1 IN2=I(J5) c 759 IF(M3)761,761,760 759 IF(M3.le.0) go to 761 c 760 J6=L3+J3-1 J6=L3+J3-1 IN3=I(J6) 761 J7=L4+J3-1 I(J7)=IN1+IN2+IN3 780 CONTINUE RETURN C ADD 4 BOX c 108 IF(M1)850,850,851 108 IF(M1.gt.0) go to 851 c 850 IN1=I(L1) IN1=I(L1) c 851 IF(M2)852,852,853 851 IF(M2.gt.0) go to 853 c 852 IN2=I(L2) IN2=I(L2) c 853 IF(M3)854,854,855 853 IF(M3.gt.0) go to 855 c 854 IN3=I(L3) IN3=I(L3) c 855 IF(M4)856,856,857 855 IF(M4.gt.0) go to 857 c 856 IN4=I(L4) IN4=I(L4) 857 DO 880 J3=1,NSAM c IF(M1)859,859,858 IF(M1.le.0) go to 859 c 858 J4=L1+J3-1 J4=L1+J3-1 IN1=I(J4) c 859 IF(M2)861,861,860 859 IF(M2.le.0) go to 861 c 860 J5=L2+J3-1 J5=L2+J3-1 IN2=I(J5) c 861 IF(M3)863,863,862 861 IF(M3.le.0) go to 863 c 862 J6=L3+J3-1 J6=L3+J3-1 IN3=I(J6) c 863 IF(M4)865,865,864 863 IF(M4.le.0) go to 865 c 864 J7=L4+J3-1 J7=L4+J3-1 IN4=I(J7) C [page 5-5] 865 J8=L5+J3-1 I(J8)=IN1+IN2+IN3+IN4 880 CONTINUE RETURN C MULTIPLIER c 109 IF(M1)900,900,901 109 IF(M1.gt.0) go to 901 XIN1=FLOAT(I(L1))*SFI c 901 IF(M2)902,902,903 901 IF(M2.gt.0) go to 903 XIN2=FLOAT(I(L2))*SFI 903 DO 908 J=1,NSAM c IF(M1)905,905,904 IF(M1.le.0) go to 905 J4=L1+J3-1 XIN1=FLOAT(I(J4))*SFI c 905 IF(M2)907,907,906 905 IF(M2.le.0) go to 907 J5=L2+J3-1 XIN2=FLOAT(I(J5))*SFI 907 J6=L3+J3-1 I(J6)=XIN1*XIN2*SFID 908 CONTINUE RETURN C SET NEW FUNCTION IN OSC OR ENV 110 ILOC=N1+6 IF(I(N1+1).EQ.105) ILOC=N1+4 IN1=I(3)+I(N1)-1 IIN1=I(IN1)/IP(12) IF(IIN1.EQ.0) I(ILOC)=-IP(2)-(IIN1-1)*IP(6) c 960 RETURN RETURN C RANDOM AND HOLD GENERATOR 111 SUM=FLOAT(I(L4))*SFI c IF(M1)910,910,911 IF(M1.gt.0) go to 911 c 910 XIN1=FLOAT(I(L1))*SFI XIN1=FLOAT(I(L1))*SFI c 911 IF(M2)912,912,913 911 IF(M2.gt.0) go to 913 c 912 XIN2=FLOAT(I(L2))*SFI XIN2=FLOAT(I(L2))*SFI 913 IRN=I(L5) DO 940 J3=1,NSAM c IF(M1)916,916,915 IF(M1.le.0) go to 916 c 915 J4=L1+J3-1 J4=L1+J3-1 XIN1=FLOAT(I(J4))*SFI c 916 IF(M2)918,918,917 916 IF(M2.le.0) go to 918 c 917 J5=L2+J3-1 J5=L2+J3-1 XIN2=FLOAT(I(J5))*SFI c 918 IF(SUM-XNFUN)920,919,919 918 IF((SUM-XNFUN).lt.0.0) go to 920 c 919 SUM=SUM-XNFUN SUM=SUM-XNFUN I(7)=IABS(I(7)*IMULT) RN=(2.*FLOAT(I(7))*SFF-1.) 920 J7=L3+J3-1 I(J7)=XIN1*RN*SFID SUM=SUM+XIN2 940 CONTINUE I(L4)=IFIX(SUM*SFID) I(L5)=IRN RETURN END C [page 6-1] C GEN1 FUNCTION GENERATOR 1 C *** MUSIC V *** SUBROUTINE GEN1 DIMENSION I(15000),P(100),IP(21) COMMON I,P/PARM/IP N1=IP(2)+(IFIX(P(4))-1)*IP(6) M1=7 SCLFT=IP(15) c 102 IF(P(M1+1))103,103,100 102 IF(P(M1+1).le.0.0) go to 103 c 100 V1=P(M1-2)*SCLFT V1=P(M1-2)*SCLFT V2=(P(M1)-P(M1-2))/(P(M1+1)-P(M1-1))*SCLFT MA=N1+IFIX(P(M1-1)) MB=N1+IFIX(P(M1+1))-1 DO 101 J=MA,MB XJ=J-MA 101 I(J)=V1+V2*XJ IF(IFIX(P(M1+1)).EQ.(IP(6)-1))GO TO 103 M1=M1+2 GO TO 102 103 I(MB+1)=P(M1)*SCLFT RETURN END C GEN2 FUNCTION GENERATOR 2 c *** MUSIC V *** SUBROUTINE GEN2 DIMENSION I(15000),P(100),IP(21),A(7000) COMMON I,P/PARM/IP EQUIVALENCE(I,A) SCLFT=IP(15) N1=IP(2)+(IFIX(P(4))-1)*IP(6) N2=N1+IP(6)-1 DO 101 K1=N1,N2 101 A(K1)=0.0 FAC=6.283185/(FLOAT(IP(6))-1.0) NMAX=I(1) N3=5+INT(ABS(P(NMAX)))-1 c IF(N3-5)104,100,100 IF((N3-5).lt.0) go to 104 c 100 DO 103 J=5,N3 DO 103 J=5,N3 FACK=FAC*FLOAT(J-4) DO 102 K=N1,N2 102 A(K)=A(K)+SIN(FACK*FLOAT(K-N1))*P(J) 103 CONTINUE 104 N4=N3+1 N5=I(1)-1 c IF(N5-N4)114,105,105 IF((N5-N4).le.0) go to 114 c 105 DO 107 J1=N4,N5 DO 107 J1=N4,N5 FACK=FAC*FLOAT(J1-N4) DO 106 K1=N1,N2 106 A(K1)=A(K1)+COS(FACK*FLOAT(K1-N1))*P(J1) 107 CONTINUE 114 CONTINUE c IF(P(NMAX))112,112,108 IF(P(NMAX).le.0.0) go to 112 c 108 FMAX=0.0 FMAX=0.0 DO 110 K2=N1,N2 c IF(ABS(A(K2))-FMAX)110,110,109 IF((ABS(A(K2))-FMAX).le.0.0) go to 110 c 109 FMAX=ABS(A(K2)) FMAX=ABS(A(K2)) 110 CONTINUE 113 DO 111 K3=N1,N2 111 I(K3)=(A(K3)*SCLFT*.99999)/FMAX RETURN C [page 6-2] 112 FMAX=.99999 GO TO 113 END C GEN3 FUNCTION GENERATOR 3 C *** MUSIC V *** C ASSUMPTIONS--P(4) = THE NUMBER OF THE FUNCTION TO BE GENERATED, C I(1) = WORD COUNT FOR CURRENT DATA RECORD C P(5) = THE BEGINNING THE THE LIST OF DESCRIPTION NUMBERS C IP(2) = THE BEGINNING SUBSCRIPT FOR FUNCTIONS IN THE I ARRAY, C IP(6) = THE LENGTH OF THE FUNCTIONS C IP(15) = SCALE FACTOR FOR STORED FUNCTIONS C SUBROUTINE GEN3 COMMON I(15000),P(100) /PARM/ IP(21) N=I(1)-5 NL=5 SCLFT=IP(15) LL=IP(6) RMIN=0 RMAX=0 NR=NL+N DO 10 J=NL,NR IF(P(J).GT.RMAX) RMAX=P(J) 10 IF(P(J).LT.RMIN) RMIN=P(J) DIV=AMAX1(ABS(RMIN),ABS(RMAX)) N1 = IP(2) + (IFIX(P(4))-1)*IP(6) I(N1)=(P(NL)/DIV)*SCLFT LAST=N1 DO 100 J=1,N LL = LL-LL/(N-J+1) IX = N1+IP(6)-LL-1 IX2 = NL+J I(IX)=(P(IX2)/DIV)*SCLFT DELTA=FLOAT(I(IX))-FLOAT(I(LAST)) NR = IX-LAST-1 SEG = NR+1 HNCR=DELTA/SEG DO 50 K=1,NR IX2 = LAST+K 50 I(IX2)=FLOAT(I(IX2-1))+HNCR 100 LAST=IX RETURN END C DATA3 PASS 3 DATA INPUTING ROUTINE C *** MUSIC V *** SUBROUTINE DATA(N) COMMON I(15000),P(100) READ(N, *) K,(P(J),J=1,K) I(1)=K RETURN END C PARM CONTROL DATA SPECIFICATION FOR PASS 3 C *** MUSIC V *** C C IP(1) = NUMBER OF OP CODES C IP(2) = BEGINNING SUBSCRIPT OF FIRST FUNCTION C IP(3) = STANDARD SAMPLING RATE C IP(4) = BEGINNING SUBSCRIPT OF INSTRUMENT DEFINITIONS C IP(5) = BEGINNING OF LOCATION TABLE FOR INSTRUMENT DEFINITIONS C IP(6) = LENGTH OF FUNCTIONS C [page 6-3] C IP(7) = BEGINNING OF NOTE CARD PARAMETERS C IP(8) = LENGTH OF NOTE CARD PARAMETER BLOCKS C IP(9) = NUMBER OF NOTE CARD PARAMETER BLOCKS C IP(10) = BEGINNING OF OUTPUT DATA BLOCK C IP(11) = SOUND ZERO (SILENCE VALUE) C IP(12) = SCALE FACTOR FOR NOTE CARD PARAMETERS C IP(13) = BEGINNING OF GENERATOR INPUT-OUTPUT BLOCKS C IP(14) = LENGTH OF GENERATOR INPUT-OUTPUT BLOCKS C IP(15) = SCALE FACTOR FOR FUNCTIONS C c BLOCK DATA c COMMON /PARM/IP(21) c DATA IP/12,512,20000,14500,14400,512,13000,35,40,6657,2048, c 1 1000000,6657,512,7777777,5*0/ C**** BIG NUMB. IS IBM360'S BIGGEST. 1 65536,6657,512,Z7FFFFFFF/ c END C**** SUBROUTINE DUM C**** ENTRY SAMGEN C**** ENTRY GEN4 C**** ENTRY GEN5 C**** END SUBROUTINE SAMGEN RETURN END SUBROUTINE GEN4 END SUBROUTINE GEN5 END C **** DUMMY SUBROUTINES **** c SUBROUTINE FROUT3(IDSK) C TERMINATE OUTPUT c INTEGER PEAK c COMMON I(15000),P(100)/PARM/IP(21)/FINOUT/PEAK,NRSOR c K=IP(10) c L=IP(10)+IP(14)-1 c DO 1 J=K,L c I(J)=0 c 1 CONTINUE c CALL SAMOUT(IDSK,IP(14)) C REWIND NWRITE C WRITE(6,10) PEAK,NRSOR C PRINT 10,PEAK,NRSOR C 10 FORMAT ('0PEAK AMPLITUDE WAS',I8/'0NUMBER OF SAMPLES OUT OF RANGE WAS',I8) C CALL EXIT c IF(IDSK.LT.0)CALL EXIT c J=IP(10) c L=J+1024 c DO 2 K=J,L c I(K)=0 c 2 CONTINUE cC WILL WRITE 1024 0'S ON DSK. c c CALL FASTOUT(I(J),1024) cc CALL FINFILE c c close(inputfile) c close(outputfile) c c CALL EXIT c END C DSMOUT DEBUG SAMOUT C *** MUSIC V *** C [page 6-4] C DEBUG SAMOUT SUBROUTINE SAMOUT(IDSK,N, nwrite) c DIMENSION IDBUF(2000),MS(3) DIMENSION IDBUF(2000) C*** IDSK IS FLAG TO WRITE SAMPLES ON DSK -- PDP **** C*** IDBUF WILL STORE PACKED SAMPLES. **** DIMENSION I(15000),T(10),P(100),IP(21) COMMON I,P/PARM/IP/FINOUT/PEAK,NRSOR INTEGER PEAK IF(IDSK.GE.0) GO TO 99 N1=N PRINT 100,N1 100 FORMAT(7H OUTPUTI6,8H SAMPLES) N2=IP(10)-1 N3=10 GO TO 104 106 DO 101 L=1,10 J=N2+L 101 T(L)=FLOAT(I(J))/FLOAT(IP(12)) PRINT 102, (T(K),K=1,N3) 102 FORMAT(1H 10F11.4) N2=N2+10 N1=N1-10 c IF(N1)103,103,104 IF(N1.gt.0) go to 104 c 103 RETURN RETURN c 104 IF(N1-10)105,106,106 104 IF(N1.ge.10) go to 106 c 105 N3=N1 N3=N1 GO TO 106 99 J=IDSK+1 M1=IP(10) M2=0 ISC=IP(12) IDSK=IDSK+N C COUNTS SAMPLES TO DATE DO 1 K=J,IDSK N1=I(M1+M2)/ISC IF(N1.GT.PEAK)PEAK=N1 IDBUF(K)=N1 1 M2=M2+1 IF(IDSK.LT.768)RETURN CALL FASTOUT(IDBUF(1), 768, nwrite) c KL=0 c DO 2 K=1,768,3 c KL=KL+1 c KJ=K-1 c MS(1)=IDBUF(K) c IF(MS(1).EQ.2048) MS(1)=2047 cC A 2048 IN THE 12 LEFT HAND BITS CREATES PROBLEMS c DO 3 L=2,3 c MS(L)=IDBUF(KJ+L) c 3 IF(MS(L).LT.0) MS(L)=4096+MS(L) c 2 IDBUF(KL)=MS(3)+MS(2)*4096+MS(1)*16777216 cC PACKS 3 SMPLS TO A 36-BIT WORD. 4096=2**12, 16---=2**24. cC MS(1) HAS LEFT HAND 12 BITS; MS(2), MIDDLE 12 BITS; MS(3), RIGHT 12. cC NEGATIVE NUMBERS RUN FROM 4096(I.E. -1) TO 2049(I.E. -2048). c c CALL FASTOUT(IDBUF(1),256, nwrite) c J=IDSK-768 IF(J.LT.1) GO TO 4 DO 5 K=1,J 5 IDBUF(K)=IDBUF(768+K) C [page 6-5] 4 IDSK=J RETURN END SUBROUTINE FASTOUT(IARR, N, nwrite) DIMENSION I(15000),P(100),IP(21) COMMON I,P/PARM/IP/FINOUT/PEAK,NRSOR DIMENSION IARR(N) ICTR=IP(21) c print *, 'output ', N, ICTR do 55 K=1,N SAMPLE=IARR(k)*0.000488 c 1/2048 ICTR = ICTR+1 55 WRITE(nwrite, rec=ICTR) SAMPLE IP(21)=ICTR c WRITE(nwrite) xarr c (XARR(J), J=1,N) end C ERROR1 GENERAL ERROR ROUTINE C *** MUSIC V *** SUBROUTINE ERROR(I) PRINT 100,I 100 FORMAT(' ERROR OF TYPE',I5) RETURN END snd-16.1/snd-chn.c0000644000076400007640000124060612603035272012042 0ustar bilbil#include "snd.h" #include "clm2xen.h" #include "clm-strings.h" bool is_graph_style(int grf) { switch (grf) { case GRAPH_LINES: case GRAPH_DOTS: case GRAPH_FILLED: case GRAPH_DOTS_AND_LINES: case GRAPH_LOLLIPOPS: return(true); break; } return(false); } typedef struct lisp_grf { int *len; mus_float_t **data; int graphs; axis_info *axis; int env_data; show_axes_t show_axes; } lisp_grf; chan_info *get_cp(Xen snd, Xen x_chn_n, const char *caller) { snd_info *sp; int chn_n; sp = get_sp(snd); if ((sp == NULL) || (!(sp->active)) || (sp->inuse == SOUND_IDLE)) { snd_no_such_sound_error(caller, snd); return(NULL); /* just in case our catch has been clobbered */ } if (Xen_is_integer(x_chn_n)) chn_n = Xen_integer_to_C_int(x_chn_n); else if (sp->selected_channel != NO_SELECTION) chn_n = sp->selected_channel; else chn_n = 0; if ((chn_n >= 0) && (chn_n < sp->nchans) && (sp->chans[chn_n])) return(sp->chans[chn_n]); snd_no_such_channel_error(caller, snd, x_chn_n); return(NULL); } static Xen lisp_graph_hook; static Xen mouse_press_hook; static Xen mark_click_hook; static Xen mix_click_hook; static Xen mouse_click_hook; static Xen mouse_drag_hook; static Xen key_press_hook; static Xen after_transform_hook; static Xen graph_hook; static Xen after_graph_hook; static Xen after_lisp_graph_hook; static void after_transform(chan_info *cp, mus_float_t scaler) { if (Xen_hook_has_list(after_transform_hook)) run_hook(after_transform_hook, Xen_list_3(C_int_to_Xen_sound(cp->sound->index), C_int_to_Xen_integer(cp->chan), C_double_to_Xen_real(scaler)), S_after_transform_hook); } static void run_after_graph_hook(chan_info *cp) { if ((cp->hookable == WITH_HOOK) && (Xen_hook_has_list(after_graph_hook))) run_hook(after_graph_hook, Xen_list_2(C_int_to_Xen_sound(cp->sound->index), C_int_to_Xen_integer(cp->chan)), S_after_graph_hook); /* (hook-push after-graph-hook (lambda (hook) (snd-print (format #f "~A ~A~%" (hook 'snd) (hook 'chn))))) */ } static void set_y_bounds(axis_info *ap); static void chans_time_graph_type(chan_info *cp, int value) { cp->time_graph_type = (graph_type_t)value; if (cp->time_graph_type == GRAPH_ONCE) { set_y_bounds(cp->axis); resize_sy(cp); set_x_bounds(cp->axis); resize_sx_and_zx(cp); } update_graph(cp); } static void set_time_graph_type(graph_type_t val) { in_set_time_graph_type(val); for_each_chan_with_int(chans_time_graph_type, (int)val); } static void chans_wavo_hop(chan_info *cp, int hop) { cp->wavo_hop = hop; update_graph(cp); } static void set_wavo_hop(int uval) { int val; if (uval < 1) val = 1; else val = uval; in_set_wavo_hop(val); for_each_chan_with_int(chans_wavo_hop, val); } static void chans_wavo_trace(chan_info *cp, int value) { cp->wavo_trace = value; update_graph(cp); } void set_wavo_trace(int uval) { int val; if (uval < 1) val = 1; else val = uval; in_set_wavo_trace(val); for_each_chan_with_int(chans_wavo_trace, val); } static void set_beats_per_minute(mus_float_t val) { if (val > 0.0) { if (val > 10000.0) val = 10000.0; in_set_beats_per_minute(val); chans_field(FCP_BEATS, val); if (!(ss->graph_hook_active)) for_each_chan(update_graph); } } static void chans_beats_per_measure(chan_info *cp, int value) { cp->beats_per_measure = value; update_graph(cp); } static void set_beats_per_measure(int val) { if (val > 0) { if (val > 1000) val = 1000; in_set_beats_per_measure(val); for_each_chan_with_int(chans_beats_per_measure, val); } } static void chans_max_transform_peaks(chan_info *cp, int value) { cp->max_transform_peaks = value; } void set_max_transform_peaks(int val) { in_set_max_transform_peaks(val); for_each_chan_with_int(chans_max_transform_peaks, val); } static void chans_zero_pad(chan_info *cp, int value) { cp->zero_pad = value; calculate_fft(cp); } static void set_zero_pad(int val) { in_set_zero_pad(val); for_each_chan_with_int(chans_zero_pad, val); } static void chans_show_grid(chan_info *cp, int value) { cp->show_grid = (with_grid_t)value; update_graph(cp); } void set_show_grid(with_grid_t val) { in_set_show_grid(val); for_each_chan_with_int(chans_show_grid, (int)val); } static void chans_grid_density(chan_info *cp, mus_float_t value) { cp->grid_density = value; update_graph(cp); } void set_grid_density(mus_float_t val) { in_set_grid_density(val); for_each_chan_with_float(chans_grid_density, val); } static void chans_show_sonogram_cursor(chan_info *cp, bool value) { cp->show_sonogram_cursor = value; update_graph(cp); } static void set_show_sonogram_cursor(bool val) { in_set_show_sonogram_cursor(val); for_each_chan_with_bool(chans_show_sonogram_cursor, val); } static void chans_transform_graph_type(chan_info *cp, int value) { cp->transform_graph_type = (graph_type_t)value; } void in_set_transform_graph_type(graph_type_t uval) { graph_type_t val; val = (graph_type_t)mus_iclamp((int)GRAPH_ONCE, uval, (int)GRAPH_AS_SPECTROGRAM); in_set_transform_graph_type_1(val); for_each_chan_with_int(chans_transform_graph_type, (int)val); } static void chans_show_mix_waveforms(chan_info *cp, bool value) { cp->show_mix_waveforms = value; update_graph(cp); } void set_show_mix_waveforms(bool val) { in_set_show_mix_waveforms(val); for_each_chan_with_bool(chans_show_mix_waveforms, val); } static void chans_show_axes(chan_info *cp, int value) { cp->show_axes = (show_axes_t)value; if (cp->lisp_info) cp->lisp_info->show_axes = cp->show_axes; update_graph(cp); } void set_show_axes(show_axes_t val) { in_set_show_axes(val); for_each_chan_with_int(chans_show_axes, (int)val); } static void chans_graphs_horizontal(chan_info *cp, bool value) { cp->graphs_horizontal = value; update_graph(cp); } static void set_graphs_horizontal(bool val) { in_set_graphs_horizontal(val); for_each_chan_with_bool(chans_graphs_horizontal, val); } static void chans_fft_window(chan_info *cp, int value) { cp->fft_window = (mus_fft_window_t)value; if (cp->fft) (cp->fft)->window = (mus_fft_window_t)value; } void in_set_fft_window(mus_fft_window_t val) { in_set_fft_window_1(val); for_each_chan_with_int(chans_fft_window, (int)val); } void chans_field(fcp_t field, mus_float_t val) { int i; for (i = 0; i < ss->max_sounds; i++) { int j; snd_info *sp; sp = ss->sounds[i]; if ((sp) && ((sp->inuse == SOUND_NORMAL) || (sp->inuse == SOUND_WRAPPER))) for (j = 0; j < sp->nchans; j++) switch (field) { case FCP_X_ANGLE: sp->chans[j]->spectro_x_angle = val; break; /* these are in-coming from user interface */ case FCP_X_SCALE: sp->chans[j]->spectro_x_scale = val; break; case FCP_Y_ANGLE: sp->chans[j]->spectro_y_angle = val; break; case FCP_Y_SCALE: sp->chans[j]->spectro_y_scale = val; break; case FCP_Z_ANGLE: sp->chans[j]->spectro_z_angle = val; break; case FCP_Z_SCALE: sp->chans[j]->spectro_z_scale = val; break; case FCP_SPECTRUM_START: sp->chans[j]->spectrum_start = mus_fclamp(0.0, val, 1.0); break; case FCP_SPECTRUM_END: sp->chans[j]->spectrum_end = mus_fclamp(0.0, val, 1.0); break; case FCP_ALPHA: sp->chans[j]->fft_window_alpha = mus_fclamp(0.0, val, 10.0); break; case FCP_BETA: sp->chans[j]->fft_window_beta = mus_fclamp(0.0, val, 1.0); break; case FCP_BEATS: if (val > 0.0) sp->chans[j]->beats_per_minute = val; break; } } } void combine_sound(snd_info *sp) {change_channel_style(sp, CHANNELS_COMBINED);} void superimpose_sound(snd_info *sp) {change_channel_style(sp, CHANNELS_SUPERIMPOSED);} void separate_sound(snd_info *sp) {change_channel_style(sp, CHANNELS_SEPARATE);} void set_sound_channel_style(snd_info *sp, channel_style_t val) { switch (val) { case CHANNELS_SEPARATE: separate_sound(sp); break; /* snd-xchn.c -> change_channel_style */ case CHANNELS_COMBINED: combine_sound(sp); break; case CHANNELS_SUPERIMPOSED: superimpose_sound(sp); break; default: break; } } bool chan_fft_in_progress(chan_info *cp) { /* fft_in_progress is a background process only if sonogram/spectrogram */ return((bool)(cp->fft_in_progress)); } void set_chan_fft_in_progress(chan_info *cp, idle_t fp) { cp->fft_in_progress = fp; } void stop_fft_in_progress(chan_info *cp) { if (cp) { if (cp->fft_in_progress) { BACKGROUND_REMOVE(cp->fft_in_progress); finish_progress_report(cp); cp->fft_in_progress = 0; } } } void stop_peak_env(chan_info *cp) { if (cp->peak_env_in_progress) { BACKGROUND_REMOVE(cp->peak_env_in_progress); free_peak_env_state(cp); cp->peak_env_in_progress = 0; } } void force_fft_clear(chan_info *cp) { if (cp->fft_in_progress) { BACKGROUND_REMOVE(cp->fft_in_progress); finish_progress_report(cp); cp->fft_in_progress = 0; } if (cp->fft) cp->fft = free_fft_info(cp->fft); cp_free_fft_state(cp); } void chan_info_cleanup(chan_info *cp) { if (cp) { cp->selected = false; if (cp->fft_in_progress) { BACKGROUND_REMOVE(cp->fft_in_progress); cp->fft_in_progress = 0; } stop_peak_env(cp); cleanup_cw(cp); } } static void chans_dot_size(chan_info *cp, int value) { cp->dot_size = value; update_graph(cp); } void set_dot_size(int val) { if (val > 0) /* -1 here can crash X! */ { in_set_dot_size(val); for_each_chan_with_int(chans_dot_size, val); } } static void chans_cursor_size(chan_info *cp, int value) { cp->cursor_size = value; update_graph(cp); } void set_cursor_size(int val) { if (val > 0) { in_set_cursor_size(val); for_each_chan_with_int(chans_cursor_size, val); } } static void chans_cursor_style(chan_info *cp, int value) { cursor_style_t style; style = (cursor_style_t)value; if ((cp->cursor_style == CURSOR_PROC) && (Xen_is_procedure(cp->cursor_proc))) { snd_unprotect_at(cp->cursor_proc_loc); cp->cursor_proc = Xen_undefined; cp->cursor_proc_loc = NOT_A_GC_LOC; } cp->cursor_style = style; cp->just_zero = (style == CURSOR_LINE); /* no point in displaying y value in this case */ update_graph(cp); } void set_cursor_style(cursor_style_t val) { in_set_cursor_style(val); for_each_chan_with_int(chans_cursor_style, (int)val); } static void chans_tracking_cursor_style(chan_info *cp, int value) { cp->tracking_cursor_style = (cursor_style_t)value; } static void set_tracking_cursor_style(cursor_style_t val) { in_set_tracking_cursor_style(val); for_each_chan_with_int(chans_tracking_cursor_style, (int)val); } chan_info *virtual_selected_channel(chan_info *cp) { snd_info *sp; sp = cp->sound; if ((sp->channel_style == CHANNELS_SEPARATE) || (sp->selected_channel == NO_SELECTION)) return(cp); else return(sp->chans[sp->selected_channel]); } static int calculate_fft_1(chan_info *cp, bool update_display) { if ((cp->graph_transform_on) && (!(chan_fft_in_progress(cp)))) { #if (!USE_NO_GUI) if (cp->transform_graph_type == GRAPH_ONCE) single_fft(cp, update_display, DONT_FORCE_REFFT); else set_chan_fft_in_progress(cp, BACKGROUND_ADD(sonogram_in_slices, make_sonogram_state(cp, DONT_FORCE_REFFT))); #else single_fft(cp, update_display, DONT_FORCE_REFFT); #endif } return(0); } void calculate_fft(chan_info *cp) { calculate_fft_1(cp, FORCE_REDISPLAY); } static void update_graph_1(chan_info *cp, bool warn) { /* don't put display stuff here! This is needed so that the fft display does not get caught in a loop */ snd_info *sp; axis_info *ap; if ((cp->updating) || (cp->active != CHANNEL_HAS_AXES) || (cp->sounds == NULL) || (cp->sounds[cp->sound_ctr] == NULL)) return; sp = cp->sound; if (cp->squelch_update) { #if (!USE_NO_GUI) if ((warn) && (sp)) set_status(sp, "(update squelched)", false); /* this has tripped me one too many times... */ #endif return; } cp->updating = true; /* next two are needed by fft and lisp displays, but if put off until make_graph cause * the display to happen twice in some cases */ ap = cp->axis; if (ap) { double cur_srate; cur_srate = (double)(snd_srate(sp)); ap->losamp = snd_round_mus_long_t(ap->x0 * cur_srate); if (ap->losamp < 0) ap->losamp = 0; ap->hisamp = (mus_long_t)(ap->x1 * cur_srate); } if ((cp->graph_transform_on) && (!(chan_fft_in_progress(cp)))) calculate_fft_1(cp, DONT_FORCE_REDISPLAY); display_channel_data(cp); cp->updating = false; } void update_graph(chan_info *cp) { update_graph_1(cp, false); } void update_graph_or_warn(chan_info *cp) { update_graph_1(cp, true); } #define INITIAL_EDIT_SIZE 8 static Xen initial_graph_hook; bool add_channel_data_1(chan_info *cp, int srate, mus_long_t framples, channel_graph_t graphed) { /* initialize channel, including edit/sound lists */ axis_info *ap; mus_float_t ymin = 0.0, ymax = 0.0, y0, y1; double xmax, x0, x1, dur; const char *label = NULL; char *hook_label = NULL; bool ymin_set = false, ymax_set = false; cp->edit_size = INITIAL_EDIT_SIZE; cp->edits = (ed_list **)calloc(cp->edit_size, sizeof(ed_list *)); cp->edit_ctr = 0; cp->edits[0] = initial_ed_list(0, framples - 1); cp->sound_size = INITIAL_EDIT_SIZE; cp->sound_ctr = 0; cp->sounds = (snd_data **)calloc(cp->sound_size, sizeof(snd_data *)); cp->active = CHANNEL_HAS_EDIT_LIST; x0 = initial_beg(ss); x1 = initial_beg(ss) + initial_dur(ss); y0 = -1.0; y1 = 1.0; switch (cp->x_axis_style) { case X_AXIS_IN_BEATS: label = "time (beats)"; break; case X_AXIS_IN_MEASURES: label = "time (measures)"; break; case X_AXIS_IN_SAMPLES: label = "time (samples)"; break; case X_AXIS_AS_PERCENTAGE: label = "time (percent)"; break; default: label = "time"; break; } dur = (double)framples / (double)(srate); if (show_full_duration(ss)) { x0 = 0.0; x1 = dur; } if ((cp->hookable == WITH_HOOK) && (graphed == WITH_GRAPH)) { /* can also be WITHOUT_GRAPH and WITHOUT_INITIAL_GRAPH_HOOK * the former is called in snd-nogui, and in the make_readable calls in snd-regions and snd-snd * the latter is from snd-edits where we are updating an already displayed sound (and keeping its axis settings across the update) * this hook is replacing earlier "initial-x0" settings */ /* peak-env setup. This used to be handled by extension language code (peak-env.*) using * the initial-graph-hook, close-hook, and exit-hook. */ if (peak_env_dir(ss)) { /* look for peak env file. If found, read in its contents. */ const char *error_string; error_string = read_peak_env_info_file(cp); if (error_string) snd_warning("peak-env: %s\n", error_string); } /* there is no data yet in the channel, so channel_maxamp here will get 0.0 */ /* initial-graph-hook */ if (Xen_hook_has_list(initial_graph_hook)) { Xen res; res = run_or_hook(initial_graph_hook, Xen_list_3(C_int_to_Xen_sound(cp->sound->index), C_int_to_Xen_integer(cp->chan), C_double_to_Xen_real(dur)), S_initial_graph_hook); if (Xen_is_list(res)) { int len; len = Xen_list_length(res); if (len > 0) x0 = Xen_real_to_C_double(Xen_car(res)); if (len > 1) x1 = Xen_real_to_C_double(Xen_cadr(res)); if (len > 2) y0 = Xen_real_to_C_double(Xen_caddr(res)); if (len > 3) y1 = Xen_real_to_C_double(Xen_cadddr(res)); if ((len > 4) && (Xen_is_string(Xen_list_ref(res, 4)))) hook_label = mus_strdup(Xen_string_to_C_string(Xen_list_ref(res, 4))); if (len > 5) { ymin = Xen_real_to_C_double(Xen_list_ref(res, 5)); ymin_set = true; } if (len > 6) { ymax = Xen_real_to_C_double(Xen_list_ref(res, 6)); ymax_set = true; } /* ymin/ymax for possible fit data hooks */ } } } if ((!ymax_set) && (!ymin_set) && (peak_env_maxamp_ok(cp, 0))) { ymax = peak_env_maxamp(cp, 0); if (ymax < 1.0) ymax = 1.0; ymin = -ymax; } else { if (!ymax_set) { if (y1 > 1.0) ymax = y1; else ymax = 1.0; } if (!ymin_set) {if (y0 < -1.0) ymin = y0; else ymin = -1.0; } } if (dur == 0.0) xmax = .001; else xmax = dur; if (dur <= 0.0) { /* empty sound */ label = "(no data)"; xmax = .001; } else { if (xmax > dur) xmax = dur; if (x0 >= x1) x0 = x1 - .01; } if (xmax <= 0.0) xmax = .001; if (ymin >= ymax) ymin = ymax - .01; if (y0 >= y1) y0 = y1 - .01; ap = make_axis_info(cp, 0.0, xmax, ymin, ymax, (hook_label) ? hook_label : label, x0, x1, y0, y1, NULL); if (hook_label) free(hook_label); if (dur == 0.0) { ap->zx = 1.0; ap->sx = 1.0; ap->no_data = true; } else { if (ap->x_ambit != 0.0) { ap->zx = (ap->x1 - ap->x0) / ap->x_ambit; ap->sx = (ap->x0 - ap->xmin) / ap->x_ambit; } ap->no_data = false; } if (ap->y_ambit != 0.0) { ap->zy = (ap->y1 - ap->y0) / ap->y_ambit; ap->sy = (ap->y0 - ap->ymin) / ap->y_ambit; } cp->axis = ap; if (graphed == WITH_GRAPH) initialize_scrollbars(cp); cp->active = CHANNEL_HAS_AXES; return(ymax_set); } void start_peak_env(chan_info *cp) { if (cp->peak_env_in_progress) stop_peak_env(cp); start_peak_env_state(cp); cp->peak_env_in_progress = BACKGROUND_ADD(get_peak_env, (any_pointer_t)cp); } void add_channel_data(char *filename, chan_info *cp, channel_graph_t graphed) { int chn = 0; mus_long_t framples; snd_info *sp; file_info *chdr, *hdr; #if (!USE_NO_GUI) bool ymax_set; #endif sp = cp->sound; hdr = sp->hdr; framples = hdr->samples / hdr->chans; #if (!USE_NO_GUI) ymax_set = add_channel_data_1(cp, hdr->srate, framples, graphed); #else add_channel_data_1(cp, hdr->srate, framples, graphed); #endif chdr = copy_header(filename, hdr); /* need one separate from snd_info case */ chn = cp->chan; if (chdr) { int fd; fd = snd_open_read(filename); if (fd != -1) { snd_io *io; snd_file_open_descriptors(fd, filename, chdr->sample_type, chdr->data_location, chdr->chans, chdr->type); during_open(fd, filename, SND_OPEN_CHANNEL); io = make_file_state(fd, chdr, chn, 0, FILE_BUFFER_SIZE); cp->sounds[0] = make_snd_data_file(filename, io, chdr, DONT_DELETE_ME, cp->edit_ctr, chn); /* if sound tables have the saved maxamp data, grab it */ if (mus_sound_channel_maxamp_exists(filename, cp->chan)) { mus_long_t pos; /* fprintf(stderr, "reading max for %s %d\n", filename, cp->chan); */ set_ed_maxamp(cp, 0, mus_sound_channel_maxamp(filename, cp->chan, &pos)); set_ed_maxamp_position(cp, 0, pos); } /* else fprintf(stderr, "can't read max for %s %d\n", filename, chn); */ } } #if (!USE_NO_GUI) if ((show_full_range(ss)) && (!ymax_set) && (graphed == WITH_GRAPH)) { mus_float_t ymax; if ((sp->channel_style == CHANNELS_COMBINED) && (sp->nchans > 1)) { if (cp->chan == sp->nchans - 1) { int i; ymax = 0.0; for (i = 0; i < sp->nchans; i++) { mus_float_t local_max; local_max = channel_maxamp(sp->chans[i], 0); if (local_max > ymax) ymax = local_max; } if (ymax > 1.0) { for (i = 0; i < sp->nchans; i++) { axis_info *ap; chan_info *ncp; ncp = sp->chans[i]; ap = ncp->axis; ap->ymin = -ymax; ap->ymax = ymax; ap->y_ambit = 2 * ap->ymax; ap->y0 = ap->ymin; ap->y1 = ap->ymax; ap->zy = 1.0; ap->sy = 0.0; resize_sy_and_zy(ncp); apply_y_axis_change(ncp); } } } } else { ymax = channel_maxamp(cp, 0); if (ymax > 1.0) { axis_info *ap; ap = cp->axis; ap->ymin = -ymax; ap->ymax = ymax; ap->y_ambit = 2 * ap->ymax; ap->y0 = ap->ymin; ap->y1 = ap->ymax; ap->zy = 1.0; ap->sy = 0.0; resize_sy_and_zy(cp); apply_y_axis_change(cp); } } } else { if ((current_samples(cp) > PEAK_ENV_CUTOFF) && (cp->edits[0]->peak_env == NULL) && /* perhaps created at initial graph time */ (sp->short_filename != NULL)) /* region browser jumped in too soon during autotest */ start_peak_env(cp); } #endif } static void set_y_bounds(axis_info *ap) { mus_float_t range; range = ap->zy * ap->y_ambit; ap->y0 = ap->ymin + ap->sy * ap->y_ambit; ap->y1 = (ap->y0 + range); if (ap->y1 > ap->ymax) { ap->y1 = ap->ymax; ap->y0 = ap->y1 - range; } if (ap->y0 < ap->ymin) ap->y0 = ap->ymin; } static bool is_NaN(double x) {return(x != x);} void set_x_bounds(axis_info *ap) { double range; if (ap->xmax <= ap->xmin) { ap->xmax = ap->xmin + .001; ap->x_ambit = .001; } range = ap->zx * ap->x_ambit; ap->x0 = ap->xmin + ap->sx * ap->x_ambit; if (is_NaN(ap->x0)) ap->x0 = 0.0; ap->x1 = (ap->x0 + range); if (ap->x1 > ap->xmax) { ap->x1 = ap->xmax; ap->x0 = ap->x1 - range; } if (ap->x0 < ap->xmin) ap->x0 = ap->xmin; ap->changed = true; } void apply_y_axis_change(chan_info *cp) { snd_info *sp; axis_info *ap; ap = cp->axis; sp = cp->sound; set_y_bounds(ap); update_graph_or_warn(cp); update_enved_background_waveform(cp); if (sp->channel_style != CHANNELS_SEPARATE) { int i; mus_float_t zy, sy; sy = ap->sy; zy = ap->zy; for (i = 0; i < sp->nchans; i++) { chan_info *ncp; ncp = sp->chans[i]; if (ncp != cp) { axis_info *nap; nap = ncp->axis; if (nap) { nap->y_ambit = ap->y_ambit; nap->ymin = ap->ymin; nap->ymax = ap->ymax; nap->zy = zy; nap->sy = sy; set_y_bounds(nap); update_graph_or_warn(ncp); } } } } } void set_x_axis_x0x1(chan_info *cp, double x0, double x1) { /* all callers are explicit (non-gui), so it should be safe to reset the z scroller here as well */ axis_info *ap; ap = cp->axis; if (x0 >= 0.0) ap->x0 = x0; else ap->x0 = 0.0; ap->x1 = x1; if (x1 > ap->xmax) ap->xmax = x1; if (ap->xmax <= ap->xmin) ap->xmax = ap->xmin + .001; ap->x_ambit = ap->xmax - ap->xmin; if (ap->x_ambit != 0.0) { ap->zx = (x1 - x0) / ap->x_ambit; ap->sx = (x0 - ap->xmin) / ap->x_ambit; resize_sx_and_zx(cp); } apply_x_axis_change(cp); /* this checks sync */ ap->changed = true; } static void set_x_axis_x0(chan_info *cp, mus_long_t left) { if (cp) { axis_info *ap; ap = cp->axis; if (ap) { double x1x0; x1x0 = ap->x1 - ap->x0; ap->x0 = (double)left / (double)snd_srate(cp->sound); if (is_NaN(ap->x0)) ap->x0 = 0.0; set_x_axis_x0x1(cp, ap->x0, ap->x0 + x1x0); } } } static void set_x_axis_x1(chan_info *cp, mus_long_t right) { if (cp) { axis_info *ap; ap = cp->axis; if (ap) { double x1x0; x1x0 = ap->x1 - ap->x0; ap->x1 = (double)right / (double)snd_srate(cp->sound); set_x_axis_x0x1(cp, ap->x1 - x1x0, ap->x1); } } } void reset_x_display(chan_info *cp, double sx, double zx) { axis_info *ap; bool reset_zx; ap = cp->axis; ap->sx = sx; reset_zx = (zx != ap->zx); ap->zx = zx; set_x_bounds(ap); if (reset_zx) resize_sx_and_zx(cp); else resize_sx(cp); update_graph_or_warn(cp); } static void update_xs(chan_info *ncp, axis_info *ap) { axis_info *nap; nap = ncp->axis; if ((nap) && (nap->xmax > 0.0)) { double scl; /* ncp->axis can be NULL here and elsewhere if we're in initialize_scrollbars * of the first channel of a (brand-new) multi-channel sound with sync set -- * chans after the first have not necessarily set up an axis_info struct yet. */ scl = ap->xmax / nap->xmax; reset_x_display(ncp, ap->sx * scl, ap->zx * scl); } } void apply_x_axis_change(chan_info *cp) { int i; snd_info *sp; axis_info *ap; ap = cp->axis; sp = cp->sound; sp->lacp = cp; set_x_bounds(ap); update_graph_or_warn(cp); if (sp->sync != 0) { sync_info *si; si = snd_sync(sp->sync); for (i = 0; i < si->chans; i++) if (cp != si->cps[i]) update_xs(si->cps[i], ap); si = free_sync_info(si); } else { if (sp->channel_style != CHANNELS_SEPARATE) for (i = 0; i < sp->nchans; i++) /* not 1 (25-Oct-07: 1 might be selected chan, but 0 needs to reflect changes as well */ update_xs(sp->chans[i], ap); } } #define NO_ZOOM_FOCUS_LOCATION -1 static mus_long_t zoom_focus_location(chan_info *cp) { if (cp->cursor_visible) return(cursor_sample(cp)); if (selection_is_visible_in_channel(cp)) /* this is complicated! We want the relative position of the focussed-upon thing * to stay the same, so that the zoom is smooth, but if we focus on just (for example) * the selection start, we end up jumping unexpectedly if C-x v centered the selection. * So, return something in the current window related to the current selection. */ { mus_long_t beg, end, mid, left, right; beg = selection_beg(cp); end = beg + selection_len(); mid = (mus_long_t)(0.5 * (beg + end)); left = cp->axis->losamp; right = cp->axis->hisamp; if ((mid > left) && (mid < right)) return(mid); if ((beg > left) && (beg < right)) return(beg); if ((end > left) && (end < right)) return(end); /* return((mus_long_t)(0.5 * (left + right))); */ } { mus_long_t pos; pos = zoom_focus_mix_in_channel_to_position(cp); if (pos >= 0) return(pos); } if (active_mark(cp)) return(mark_beg(cp)); return(NO_ZOOM_FOCUS_LOCATION); } void focus_x_axis_change(chan_info *cp, int focus_style) { axis_info *ap; /* prepare for set_x_bounds given desired focus point, then drop into default * we need to set ap->sx to reflect the new zx value and the focus type * if focus_left - go on (nothing to do) * focus_right - get old right, set sx to keep it as is * focus_middle - ditto mid window * focus_active - find the currently active entity, if none use focus_middle * focus_proc -- call proc */ ap = cp->axis; if (ap->xmax == 0.0) return; if (ap->xmax <= ap->xmin) { ap->xmax = ap->xmin + .001; ap->x_ambit = .001; } if (focus_style != ZOOM_FOCUS_LEFT) { chan_info *ncp; mus_long_t newf; switch (focus_style) { case ZOOM_FOCUS_PROC: ap->x0 = Xen_real_to_C_double( Xen_call_with_6_args(ss->zoom_focus_proc, C_int_to_Xen_sound(cp->sound->index), C_int_to_Xen_integer(cp->chan), C_double_to_Xen_real(ap->zx), C_double_to_Xen_real(ap->x0), C_double_to_Xen_real(ap->x1), C_double_to_Xen_real(ap->x_ambit), S_zoom_focus_style " procedure")); break; case ZOOM_FOCUS_RIGHT: ap->x0 = ap->x1 - ap->zx * ap->x_ambit; break; case ZOOM_FOCUS_MIDDLE: ap->x0 = 0.5 * ((ap->x1 + ap->x0) - ap->zx * ap->x_ambit); break; case ZOOM_FOCUS_ACTIVE: ncp = virtual_selected_channel(cp); /* axes should be the same, since all move together in this mode */ newf = zoom_focus_location(ncp); if (newf == NO_ZOOM_FOCUS_LOCATION) { snd_info *sp; int sync; sp = cp->sound; sync = sp->sync; if (sync != 0) { int i; for (i = 0; i < sp->nchans; i++) if (i != ncp->chan) { newf = zoom_focus_location(sp->chans[i]); if (newf != NO_ZOOM_FOCUS_LOCATION) break; } if (newf == NO_ZOOM_FOCUS_LOCATION) { int j; /* geez, maybe it's in a separate syncd sound */ for (j = 0; j < ss->max_sounds; j++) { sp = ss->sounds[j]; if ((sp) && (sp->inuse == SOUND_NORMAL) && (sp->sync == sync) && (sp != cp->sound)) for (i = 0; i < sp->nchans; i++) { newf = zoom_focus_location(sp->chans[i]); if (newf != NO_ZOOM_FOCUS_LOCATION) break; }}}}} if (newf != NO_ZOOM_FOCUS_LOCATION) { double loc; loc = (double)newf / (double)snd_srate(ncp->sound); if ((loc > ap->x0) && (loc < ap->x1) && (ap->x1 > ap->x0)) /* try to maintain current relative position in window */ { double pos; pos = (loc - ap->x0) / (ap->x1 - ap->x0); ap->x0 = loc - pos * ap->zx * ap->x_ambit; } else ap->x0 = loc - 0.5 * ap->zx * ap->x_ambit; } else ap->x0 = 0.5 * ((ap->x1 + ap->x0) - ap->zx * ap->x_ambit); break; } if (is_NaN(ap->x0)) ap->x0 = 0.0; if (ap->x0 < 0.0) ap->x0 = 0.0; if (ap->x_ambit != 0.0) ap->sx = (double)(ap->x0 - ap->xmin) / (double)(ap->x_ambit); } apply_x_axis_change(cp); } void sx_incremented(chan_info *cp, double amount) { axis_info *ap; ap = cp->axis; ap->sx += (ap->zx * amount); if (ap->sx < 0.0) ap->sx = 0.0; if (ap->sx > (1.0 - ap->zx)) ap->sx = 1.0 - ap->zx; apply_x_axis_change(cp); resize_sx(cp); } void zx_incremented(chan_info *cp, double amount) { /* kbd arrows etc -- needs to be able to return to original */ axis_info *ap; mus_long_t samps; samps = current_samples(cp); ap = cp->axis; if ((amount >= 1.0) || ((samps > 0) && ((ap->zx * (double)samps) > (amount / 2.0)))) { ap->zx *= amount; if (ap->zx > 1.0) ap->zx = 1.0; focus_x_axis_change(cp, zoom_focus_style(ss)); /* resize_sx(cp); */ resize_sx_and_zx(cp); /* need zx also -- this changes its position, not its size. 22-Aug-12 */ } } int move_axis(chan_info *cp, int x) { /* need to scroll axis forward or backward -- distance per call depends on x distance from end of axis */ double off; int nx; axis_info *ap; ap = cp->axis; if (x > ap->x_axis_x1) { off = x - ap->x_axis_x1; ap->sx += (off * ap->zx / 4000.0); /* increase 4000.0 to make the axis move more slowly (and below) */ if (ap->sx > (1.0 - ap->zx)) ap->sx = 1.0 - ap->zx; nx = ap->x_axis_x1; } else { off = ap->x_axis_x0 - x; ap->sx -= (off * ap->zx / 4000.0); if (ap->sx < 0.0) ap->sx = 0.0; nx = ap->x_axis_x0; } apply_x_axis_change(cp); resize_sx(cp); return(nx); } void set_axes(chan_info *cp, double x0, double x1, mus_float_t y0, mus_float_t y1) { /* use to change channel_style to channels_separate, and restore axes upon update */ axis_info *ap; ap = cp->axis; ap->x0 = x0; ap->x1 = x1; if (ap->x_ambit != 0.0) { ap->zx = (x1 - x0) / ap->x_ambit; ap->sx = (x0 - ap->xmin) / ap->x_ambit; } resize_sx(cp); ap->y0 = y0; ap->y1 = y1; if (ap->y_ambit != 0.0) { ap->zy = (y1 - y0) / ap->y_ambit; ap->sy = (y0 - ap->ymin) / ap->y_ambit; } resize_sy_and_zy(cp); } /* these are copies from snd-axis.c; didn't want to use macros here */ static int local_grf_x(double val, axis_info *ap) { if (val >= ap->x1) return(ap->x_axis_x1); if (val <= ap->x0) return(ap->x_axis_x0); return((int)(ap->x_base + val * ap->x_scale)); } static int local_grf_y(mus_float_t val, axis_info *ap) { if (val >= ap->y1) return(ap->y_axis_y1); if (val <= ap->y0) return(ap->y_axis_y0); return((int)(ap->y_base + val * ap->y_scale)); } static void display_y_zero(chan_info *cp) { axis_info *ap; ap = cp->axis; if ((ap->y0 < 0.0) && (ap->y1 > 0.0)) { int zero; zero = local_grf_y(0.0, ap); draw_line(copy_context(cp), ap->x_axis_x0, zero, ap->x_axis_x1, zero); if (cp->printing) ps_draw_line(ap, ap->x_axis_x0, 0, ap->x_axis_x1, 0); } } #if USE_MOTIF #define CHN_LABEL_OFFSET -5 #else #define CHN_LABEL_OFFSET -18 #endif static char chn_id_str[LABEL_BUFFER_SIZE]; static void display_channel_id(chan_info *cp, graphics_context *ax, int height, int chans) { if (cp->show_axes == SHOW_NO_AXES) return; if ((chans > 1) || (cp->edit_ctr > 0)) { int x0, y0; color_t old_color = 0; set_peak_numbers_font(cp, ax); if (cp->printing) ps_set_peak_numbers_font(); x0 = 5; y0 = height + CHN_LABEL_OFFSET; if (cp->edit_ctr == 0) snprintf(chn_id_str, LABEL_BUFFER_SIZE, "[%d]", cp->chan + 1); else snprintf(chn_id_str, LABEL_BUFFER_SIZE, "[%d]: %d", cp->chan + 1, cp->edit_ctr); if (cp == selected_channel()) { old_color = get_foreground_color(copy_context(cp)); set_foreground_color(copy_context(cp), ss->red); } draw_string(copy_context(cp), x0, y0, chn_id_str, strlen(chn_id_str)); if (cp->printing) ps_draw_string(cp->axis, x0, y0, chn_id_str); if (cp == selected_channel()) set_foreground_color(copy_context(cp), old_color); } } #if USE_MOTIF #define SELECTION_FFT_LABEL_OFFSET -3 #else #define SELECTION_FFT_LABEL_OFFSET -15 #endif static void display_selection_transform_size(chan_info *cp, axis_info *fap, graphics_context *ax) { int x0, y0; if (fap->height < 60) return; set_tiny_numbers_font(cp, ax); if (cp->printing) ps_set_tiny_numbers_font(); y0 = fap->height + fap->y_offset + SELECTION_FFT_LABEL_OFFSET; x0 = fap->x_axis_x0 + 20; snprintf(chn_id_str, LABEL_BUFFER_SIZE, "(len: %lld/%lld)", selection_len(), cp->selection_transform_size); draw_string(copy_context(cp), x0, y0, chn_id_str, strlen(chn_id_str)); if (cp->printing) ps_draw_string(fap, x0, y0, chn_id_str); } snd_info *make_simple_channel_display(int srate, int initial_length, fw_button_t with_arrows, graph_style_t grf_style, widget_t container, bool with_events) { snd_info *sp; chan_info *cp; file_info *hdr; int err; sp = make_basic_snd_info(1); /* 1 chan */ sp->nchans = 1; sp->inuse = SOUND_WRAPPER; sp->active = true; sp->hdr = (file_info *)calloc(1, sizeof(file_info)); hdr = sp->hdr; hdr->samples = initial_length; hdr->srate = srate; hdr->comment = NULL; hdr->chans = 1; err = add_channel_window(sp, 0, 0, 0, container, with_arrows, with_events); if (err == -1) { free(sp->chans); free(sp->hdr); free(sp); return(NULL); } cp = sp->chans[0]; cp->editable = false; cp->sound = sp; cp->hookable = WITHOUT_HOOK; add_channel_data_1(cp, srate, initial_length, WITH_GRAPH); cp->time_graph_style = grf_style; cp->dot_size = dot_size(ss); return(sp); } static graphics_context *combined_context(chan_info *cp); static int make_wavogram(chan_info *cp); typedef enum {NORMAL_GRAPH, ENVED_GRAPH, MARKS_GRAPH} graph_choice_t; static int make_graph_1(chan_info *cp, double cur_srate, graph_choice_t graph_choice, bool *two_sided) { snd_info *sp; int j = 0; mus_long_t samps; axis_info *ap; mus_float_t samples_per_pixel; double x; /* in long files with small windows we can run into floating point errors that accumulate * in the loop (incrementing by a truncated amount each time), making the x amounts smaller * than they should be (so the graph appears squeezed). * * There is a similar problem with long files (say 1 hour at 44KHz), in which * the x increment gets quantized making the graphs step-like, so the * axis_info fields x0, x1, and x_scale are doubles as well. The y axis is less problematic * since we are assuming sound files here. * * And if the data window itself is small (in the sense that we're looking at individual samples) * we need to make decisions about in-between sample mouse clicks, and the cursor placement * must match the sample placement (which means that the initial x-axis offset from the * first sample (similarly the last) must be taken into account). Currently, the selection * definition (by mouse drag) has a sloppy rounding mechanism so that * within reason only samples within the selection-rectangle are in the final selection, * and cursor placement (mouse click) rounds to the nearest sample (snd-xchn.c cursor_round). * * And lastly, the axis x_scale double can be enormous whereas the between-sample choice can * be tiny, so we're pushing the arithmetic into dangerous realms. This stuff has been tested * on some extreme cases (week-long 44KHz stereo), but there's always another special case... */ int pixels; snd_fd *sf = NULL; int x_start, x_end; graphics_context *ax = NULL; sp = cp->sound; ap = cp->axis; /* check for no graph */ if ((!ap) || (!(ap->graph_active)) || (ap->x0 == ap->x1)) return(0); /* check for wavogram */ if (cp->time_graph_type == GRAPH_AS_WAVOGRAM) return(make_wavogram(cp)); if (graph_choice != ENVED_GRAPH) { ap->losamp = snd_round_mus_long_t(ap->x0 * cur_srate); /* was ceil??? */ if (ap->losamp < 0) ap->losamp = 0; ap->hisamp = (mus_long_t)((ap->x1 * cur_srate) + 0.5); /* + 0.5 for 1-sample case */ if ((ap->losamp == 0) && (ap->hisamp == 0)) return(0); } x_start = ap->x_axis_x0; x_end = ap->x_axis_x1; samps = ap->hisamp - ap->losamp + 1; if ((x_start == x_end) && (samps > 10)) return(0); /* must be too-tiny graph */ pixels = x_end - x_start; if (pixels >= POINT_BUFFER_SIZE) pixels = POINT_BUFFER_SIZE - 1; if ((x_start == x_end) || (samps <= 1)) samples_per_pixel = 0.01; /* any non-zero value < 1.0 should be ok here */ else samples_per_pixel = (mus_float_t)((double)(samps - 1) / (double)pixels); if (cp->printing) ps_allocate_grf_points(); if (graph_choice == NORMAL_GRAPH) { if (sp->channel_style == CHANNELS_SUPERIMPOSED) ax = combined_context(cp); else ax = copy_context(cp); if (cp->printing) ps_fg(cp, ax); } if ((samples_per_pixel < 1.0) || ((samples_per_pixel < 5.0) && (samps < POINT_BUFFER_SIZE)) || ((cp->time_graph_style == GRAPH_FILLED) && (samples_per_pixel < 25.0) && (samps < POINT_BUFFER_SIZE))) { double incr; int grfpts; /* i.e. individual samples are widely spaced, so we have to be careful about placement * mouse uses grf_x so in this case we have to also (to make the cursor hit the dots etc) */ sf = init_sample_read(ap->losamp, cp, READ_FORWARD); if (sf == NULL) return(0); incr = (double)1.0 / cur_srate; grfpts = (int)(ap->hisamp - ap->losamp + 1); if (cp->printing) { for (j = 0, x = ((double)(ap->losamp) / cur_srate); j < grfpts; j++, x += incr) { mus_float_t fsamp; fsamp = read_sample(sf); set_grf_point(local_grf_x(x, ap), j, local_grf_y(fsamp, ap)); ps_set_grf_point(x, j, fsamp); } } else { for (j = 0, x = ((double)(ap->losamp) / cur_srate); j < grfpts; j++, x += incr) set_grf_point(local_grf_x(x, ap), j, local_grf_y(read_sample(sf), ap)); } if (graph_choice == NORMAL_GRAPH) { if (sp->channel_style == CHANNELS_SUPERIMPOSED) { color_t old_color; old_color = get_foreground_color(ax); set_foreground_color(ax, cp->combined_data_color); draw_grf_points(cp->dot_size, ax, j, ap, 0.0, cp->time_graph_style); set_foreground_color(ax, old_color); } else draw_grf_points(cp->dot_size, ax, j, ap, 0.0, cp->time_graph_style); if (cp->printing) ps_draw_grf_points(ap, j, 0.0, cp->time_graph_style, cp->dot_size); } else { if (graph_choice == ENVED_GRAPH) (*two_sided) = false; } } else { /* take min, max */ if (peak_env_usable(cp, samples_per_pixel, ap->hisamp, true, cp->edit_ctr, false)) /* true = start new background amp env process if needed */ j = peak_env_graph(cp, samples_per_pixel, (graph_choice != ENVED_GRAPH) ? ((int)snd_srate(sp)) : 1); else { mus_float_t ymin, ymax, xf, pinc = 0.0; mus_long_t ioff; int xi; if ((ap->hisamp - ap->losamp) > (current_samples(cp) / 4)) { /* we're trying to view a large portion of the (large) sound */ if (cp->peak_env_in_progress) { /* is peak-env background process is still working on it */ peak_env_info *ep; ep = cp->edits[cp->edit_ctr]->peak_env; if ((ep) && samples_per_pixel >= (mus_float_t)(ep->samps_per_bin)) { /* and it will be useful when it finishes */ cp->waiting_to_make_graph = true; return(0); /* so don't run two enormous data readers in parallel */ } } } sf = init_sample_read(ap->losamp, cp, READ_FORWARD); if (sf == NULL) return(0); j = 0; /* graph point counter */ x = ap->x0; xi = local_grf_x(x, ap); xf = 0.0; /* samples per pixel counter */ ymin = MIN_INIT; ymax = MAX_INIT; if (cp->printing) pinc = samples_per_pixel / cur_srate; ap->changed = false; ss->stopped_explicitly = false; for (ioff = ap->losamp; ioff <= ap->hisamp; ioff++) { mus_float_t samp; samp = read_sample(sf); if (samp > ymax) ymax = samp; if (samp < ymin) ymin = samp; xf += 1.0; if (xf > samples_per_pixel) { set_grf_points(xi, j, local_grf_y(ymin, ap), local_grf_y(ymax, ap)); if (cp->printing) { x += pinc; ps_set_grf_points(x, j, ymin, ymax); } xi++; j++; xf -= samples_per_pixel; ymin = MIN_INIT; ymax = MAX_INIT; if (samps > 10000000) { check_for_event(); if ((ap->changed) || (ss->stopped_explicitly) || (cp->active < CHANNEL_HAS_EDIT_LIST)) { ss->stopped_explicitly = false; ap->changed = false; break; } } } } } if (graph_choice == NORMAL_GRAPH) { if (sp->channel_style == CHANNELS_SUPERIMPOSED) { color_t old_color; old_color = get_foreground_color(ax); set_foreground_color(ax, cp->combined_data_color); draw_both_grf_points(cp->dot_size, ax, j, cp->time_graph_style); set_foreground_color(ax, old_color); } else draw_both_grf_points(cp->dot_size, ax, j, cp->time_graph_style); if (cp->printing) ps_draw_both_grf_points(ap, j, cp->time_graph_style, cp->dot_size); } else { if (graph_choice == ENVED_GRAPH) (*two_sided) = true; } } sf = free_snd_fd(sf); if (graph_choice == NORMAL_GRAPH) { if (sp->channel_style == CHANNELS_SUPERIMPOSED) { copy_context(cp); /* reset for axes etc */ if (cp->printing) ps_reset_color(); } if ((cp->with_verbose_cursor) && (cp->cursor_on) && (cursor_sample(cp) >= ap->losamp) && (cursor_sample(cp) <= ap->hisamp)) show_cursor_info(cp); } return(j); } static int make_graph(chan_info *cp) { return(make_graph_1(cp, (double)(snd_srate(cp->sound)), NORMAL_GRAPH, NULL)); } int make_dragged_marks_graph(chan_info *cp) { return(make_graph_1(cp, (double)(snd_srate(cp->sound)), MARKS_GRAPH, NULL)); } int make_background_graph(chan_info *cp, int srate, bool *two_sided) /* (for envelope editor) */ { return(make_graph_1(cp, (double)srate, ENVED_GRAPH, two_sided)); } void make_partial_graph(chan_info *cp, mus_long_t beg, mus_long_t end) { /* assume here that everything is already checked and set up (from snd-mix.c, dragging) */ snd_info *sp; int j = 0; mus_long_t samps; axis_info *ap; mus_float_t samples_per_pixel; double x, cur_srate, beg_in_seconds, end_in_seconds; int pixels; snd_fd *sf = NULL; int x_start, x_end; graphics_context *ax = NULL; sp = cp->sound; cur_srate = (double)snd_srate(sp); ap = cp->axis; ax = copy_context(cp); if (!(ap->ax)) ap->ax = cp->ax; if (beg > 0) beg--; /* get samps / pixel */ x_start = ap->x_axis_x0; x_end = ap->x_axis_x1; samps = ap->hisamp - ap->losamp + 1; pixels = x_end - x_start; if (pixels >= POINT_BUFFER_SIZE) pixels = POINT_BUFFER_SIZE - 1; if ((x_start == x_end) || (samps <= 1)) samples_per_pixel = 0.01; /* any non-zero value < 1.0 should be ok here */ else samples_per_pixel = (mus_float_t)((double)(samps - 1) / (double)pixels); if (beg < ap->losamp) beg = ap->losamp; if (end > ap->hisamp) end = ap->hisamp; beg_in_seconds = (double)beg / cur_srate; end_in_seconds = (double)end / cur_srate; #if USE_GTK cairo_push_group(ss->cr); #endif erase_rectangle(cp, ap->ax, local_grf_x(beg_in_seconds, ap), ap->y_axis_y1, local_grf_x(end_in_seconds, ap) - local_grf_x(beg_in_seconds, ap) + 1, ap->y_axis_y0 - ap->y_axis_y1); if ((samples_per_pixel < 1.0) || ((samples_per_pixel < 5.0) && (samps < POINT_BUFFER_SIZE)) || ((cp->time_graph_style == GRAPH_FILLED) && (samples_per_pixel < 25.0) && (samps < POINT_BUFFER_SIZE))) { double incr; int grfpts; sf = init_sample_read(beg, cp, READ_FORWARD); incr = (double)1.0 / cur_srate; grfpts = (int)(end - beg + 1); for (j = 0, x = beg_in_seconds; j < grfpts; j++, x += incr) set_grf_point(local_grf_x(x, ap), j, local_grf_y(read_sample(sf), ap)); draw_grf_points(cp->dot_size, ax, j, ap, 0.0, cp->time_graph_style); } else { if (peak_env_usable(cp, samples_per_pixel, ap->hisamp, true, cp->edit_ctr, false)) /* true = start new background amp env process if needed */ j = peak_env_partial_graph(cp, beg, end, samples_per_pixel, (int)snd_srate(sp)); else { mus_float_t ymin, ymax, xf; mus_long_t ioff; int xi; if ((end - beg) > (current_samples(cp) / 4)) { /* we're trying to view a large portion of the (large) sound */ if (cp->peak_env_in_progress) { /* is peak-env background process is still working on it */ peak_env_info *ep; ep = cp->edits[cp->edit_ctr]->peak_env; if ((ep) && samples_per_pixel >= (mus_float_t)(ep->samps_per_bin)) { /* and it will be useful when it finishes */ cp->waiting_to_make_graph = true; #if USE_GTK cairo_pop_group_to_source(ss->cr); #endif return; /* so don't run two enormous data readers in parallel */ } } } sf = init_sample_read(beg, cp, READ_FORWARD); j = 0; /* graph point counter */ x = beg_in_seconds; xi = local_grf_x(x, ap); xf = 0.0; /* samples per pixel counter */ ymin = MIN_INIT; ymax = MAX_INIT; ap->changed = false; for (ioff = beg; ioff <= end; ioff++) { mus_float_t samp; samp = read_sample(sf); if (samp > ymax) ymax = samp; if (samp < ymin) ymin = samp; xf += 1.0; if (xf > samples_per_pixel) { set_grf_points(xi, j, local_grf_y(ymin, ap), local_grf_y(ymax, ap)); xi++; j++; xf -= samples_per_pixel; ymin = MIN_INIT; ymax = MAX_INIT; } } } draw_both_grf_points(cp->dot_size, ax, j, cp->time_graph_style); } sf = free_snd_fd(sf); #if (!USE_GTK) display_selection(cp); #endif if (cp->show_y_zero) display_y_zero(cp); if ((cp->with_verbose_cursor) && (cp->cursor_on) && (cursor_sample(cp) >= beg) && (cursor_sample(cp) <= end)) show_cursor_info(cp); #if USE_GTK cairo_pop_group_to_source(ss->cr); cairo_paint(ss->cr); #endif display_channel_marks(cp); } /* these next two procedures split "make_graph" into two pieces; the first * gets the data to be graphed, using the amp envs and so on, and * the second displays it. (The first cp+pos may have no relation * to the second cp -- allow arbitrary overlapping etc). */ Xen make_graph_data(chan_info *cp, int edit_pos, mus_long_t losamp, mus_long_t hisamp) { int j = 0; mus_long_t samps, ioff; axis_info *ap; mus_float_t samples_per_pixel, xf; int pixels; snd_fd *sf = NULL; int x_start, x_end; mus_float_t *data = NULL, *data1 = NULL; int data_size = 0; ap = cp->axis; if (losamp == -1) losamp = ap->losamp; if (hisamp == -1) hisamp = ap->hisamp; x_start = ap->x_axis_x0; x_end = ap->x_axis_x1; samps = hisamp - losamp + 1; if ((samps <= 0) || ((x_start == x_end) && (samps > 10))) return(Xen_false); pixels = x_end - x_start; if (pixels >= POINT_BUFFER_SIZE) pixels = POINT_BUFFER_SIZE - 1; if ((x_start == x_end) || (samps <= 1)) samples_per_pixel = 0.01; else samples_per_pixel = (mus_float_t)((double)(samps - 1) / (double)pixels); if ((samples_per_pixel < 1.0) || ((samples_per_pixel < 5.0) && (samps < POINT_BUFFER_SIZE))) { int i; data_size = (int)samps; sf = init_sample_read_any(losamp, cp, READ_FORWARD, edit_pos); if (sf == NULL) return(Xen_false); /* should this throw an error? (CHANNEL_BEING_DEALLOCATED) */ data = (mus_float_t *)malloc(data_size * sizeof(mus_float_t)); for (i = 0; i < data_size; i++) data[i] = read_sample(sf); } else { if (peak_env_usable(cp, samples_per_pixel, hisamp, false, edit_pos, true)) { double step, xk; mus_float_t ymin, ymax; peak_env_info *ep; data_size = pixels + 1; data = (mus_float_t *)calloc(data_size, sizeof(mus_float_t)); data1 = (mus_float_t *)calloc(data_size, sizeof(mus_float_t)); ep = cp->edits[edit_pos]->peak_env; step = samples_per_pixel / (mus_float_t)(ep->samps_per_bin); xf = (double)(losamp) / (double)(ep->samps_per_bin); j = 0; ioff = losamp; xk = (double)ioff; ymin = ep->fmax; ymax = ep->fmin; while (ioff <= hisamp) { int k, kk; k = (int)xf; xf += step; kk = (int)xf; if (kk >= ep->peak_env_size) kk = ep->peak_env_size - 1; for (; k <= kk; k++) { if (ep->data_min[k] < ymin) ymin = ep->data_min[k]; if (ep->data_max[k] > ymax) ymax = ep->data_max[k]; } xk += samples_per_pixel; ioff = (mus_long_t)xk; data[j] = ymin; data1[j] = ymax; j++; ymin = ep->fmax; ymax = ep->fmin; } } else { mus_float_t ymin, ymax; data_size = pixels + 1; sf = init_sample_read_any(losamp, cp, READ_FORWARD, edit_pos); if (sf == NULL) return(Xen_false); data = (mus_float_t *)calloc(data_size, sizeof(mus_float_t)); data1 = (mus_float_t *)calloc(data_size, sizeof(mus_float_t)); j = 0; /* graph point counter */ ymin = 100.0; ymax = -100.0; ss->stopped_explicitly = false; for (ioff = losamp, xf = 0.0; ioff <= hisamp; ioff++) { mus_float_t samp; samp = read_sample(sf); if (samp > ymax) ymax = samp; if (samp < ymin) ymin = samp; xf += 1.0; if (xf > samples_per_pixel) { data[j] = ymin; data1[j] = ymax; j++; xf -= samples_per_pixel; ymin = 100.0; ymax = -100.0; if (samps > 10000000) { if ((ap->changed) || (ss->stopped_explicitly)) { ss->stopped_explicitly = false; ap->changed = false; break; } } } } } } sf = free_snd_fd(sf); if (data1) return(Xen_list_2(xen_make_vct(data_size, data), xen_make_vct(data_size, data1))); else return(xen_make_vct(data_size, data)); } void draw_graph_data(chan_info *cp, mus_long_t losamp, mus_long_t hisamp, int data_size, mus_float_t *data, mus_float_t *data1, graphics_context *ax, graph_style_t style) { mus_long_t i, samps; axis_info *ap; snd_info *sp; ap = cp->axis; sp = cp->sound; if (data1 == NULL) { double start_time = 0.0, cur_srate, x, incr; cur_srate = (double)snd_srate(sp); if (losamp == -1) losamp = snd_round_mus_long_t(ap->x0 * cur_srate); start_time = (double)(losamp) / cur_srate; if (hisamp == -1) hisamp = (mus_long_t)(ap->x1 * cur_srate); samps = hisamp - losamp + 1; if (samps <= 0) return; if (samps > data_size) samps = data_size; incr = (double)1.0 / cur_srate; for (i = 0, x = start_time; i < samps; i++, x += incr) set_grf_point(local_grf_x(x, ap), i, local_grf_y(data[i], ap)); draw_grf_points(cp->dot_size, ax, samps, ap, 0.0, style); } else { int xi; if (losamp == -1) losamp = 0; if (hisamp == -1) hisamp = data_size - 1; samps = hisamp - losamp + 1; if (samps <= 0) return; if (samps > data_size) samps = data_size; for (i = 0, xi = (ap->x_axis_x0 + losamp); i < samps; i++, xi++) set_grf_points(xi, i, local_grf_y(data[i], ap), local_grf_y(data1[i], ap)); draw_both_grf_points(cp->dot_size, ax, samps, style); } } static int compare_peak_amps(const void *pk1, const void *pk2) { if (((fft_peak *)pk1)->amp > ((fft_peak *)pk2)->amp) return(-1); else if (((fft_peak *)pk1)->amp == ((fft_peak *)pk2)->amp) return(0); return(1); } static char ampstr[LABEL_BUFFER_SIZE]; #define AMP_ROOM 45 #define AMP_ROOM_CUTOFF 3.0 static void display_peaks(chan_info *cp, axis_info *fap, mus_float_t *data, mus_long_t start, mus_long_t end, mus_long_t losamp, mus_long_t hisamp, mus_float_t samps_per_pixel, bool fft_data, mus_float_t fft_scale /* fourier scale factor or 0.0 */) { int num_peaks, row, frq_col, frq_strlen, tens, i, amp_col, amp_strlen, row_height = 15; mus_long_t samps, fsamps; bool with_amps; mus_float_t amp0; graphics_context *ax; fft_peak *peak_freqs = NULL; fft_peak *peak_amps = NULL; color_t old_color = (color_t)0; /* None in Motif, NULL in Gtk, 0 in no-gui */ /* "end" is the top displayed frequency in the FFT frequency axis (srate*spectrum_end/2) * "hisamp - losamp" is how many samples of data we have */ /* "tens" is for prettyf in snd-utils, if -1 -> print int else sets decimals */ samps = hisamp - losamp; fsamps = end - start; if (samps > (fsamps * 10)) tens = 2; else if (samps > fsamps) tens = 1; else if (samps > (fsamps / 10)) tens = 0; else tens = -1; #if (!USE_GTK) row_height = (int)(1.25 * number_height(PEAKS_FONT(ss))); #else row_height = (int)(0.75 * number_height(PEAKS_FONT(ss))); #endif if (row_height < 10) row_height = 10; num_peaks = (fap->y_axis_y0 - fap->y_axis_y1) / (row_height + 5); if (cp->sound->channel_style == CHANNELS_SUPERIMPOSED) num_peaks /= cp->sound->nchans; if (num_peaks <= 0) return; if (num_peaks > cp->max_transform_peaks) num_peaks = cp->max_transform_peaks; peak_freqs = (fft_peak *)calloc(cp->max_transform_peaks, sizeof(fft_peak)); peak_amps = (fft_peak *)calloc(cp->max_transform_peaks, sizeof(fft_peak)); if (fft_data) num_peaks = find_and_sort_transform_peaks(data, peak_freqs, num_peaks, losamp, hisamp /* "fft size" */, samps_per_pixel, fft_scale); else num_peaks = find_and_sort_peaks(data, peak_freqs, num_peaks, losamp, hisamp); if ((num_peaks == 0) || ((num_peaks == 1) && ((peak_freqs[0].freq == 1.0) || (peak_freqs[0].freq == 0.0)))) { free(peak_freqs); free(peak_amps); return; } frq_strlen = (int)ceil(log10(peak_freqs[num_peaks - 1].freq * end)) + ((tens <= 0) ? 0 : (tens + 1)) + 1; if (frq_strlen < 1) frq_strlen = 1; with_amps = (fap->width > ((30 + 5 * frq_strlen + AMP_ROOM) * AMP_ROOM_CUTOFF)); amp_strlen = 3; frq_col = fap->x_axis_x1 - frq_strlen * 5; amp_col = fap->x_axis_x1 - AMP_ROOM + 15; if (with_amps) { frq_col -= AMP_ROOM; if ((fft_data) && ((cp->transform_normalization == DONT_NORMALIZE) || (cp->min_dB < -60))) { frq_col -= 5; amp_col -= 5; amp_strlen = 4; } } if (cp->sound->channel_style == CHANNELS_SUPERIMPOSED) { ax = combined_context(cp); old_color = get_foreground_color(ax); set_foreground_color(ax, cp->combined_data_color); } else ax = copy_context(cp); if (num_peaks > 6) { for (i = 0; i < num_peaks; i++) peak_amps[i] = peak_freqs[i]; qsort((void *)peak_amps, num_peaks, sizeof(fft_peak), compare_peak_amps); if (num_peaks < 12) amp0 = peak_amps[2].amp; else amp0 = peak_amps[5].amp; set_bold_peak_numbers_font(cp, ax); /* in snd-g|xchn.c */ if (cp->printing) ps_set_bold_peak_numbers_font(); #if (!USE_GTK) row = fap->y_axis_y1 + row_height; #else row = fap->y_axis_y1; #endif if (cp->sound->channel_style == CHANNELS_SUPERIMPOSED) row += row_height * num_peaks * cp->chan; for (i = 0; i < num_peaks; i++) { if (peak_freqs[i].amp >= amp0) { char *fstr; mus_float_t px; px = peak_freqs[i].freq; fstr = prettyf(px * end, tens); draw_string(ax, frq_col, row, fstr, strlen(fstr)); if (cp->printing) ps_draw_string(fap, frq_col, row, fstr); free(fstr); fstr = NULL; if (with_amps) { if ((fft_data) && (cp->fft_log_magnitude)) snprintf(ampstr, LABEL_BUFFER_SIZE, "%.1f", in_dB(cp->min_dB, cp->lin_dB, peak_freqs[i].amp)); else snprintf(ampstr, LABEL_BUFFER_SIZE, "%.*f", amp_strlen, peak_freqs[i].amp); draw_string(ax, amp_col, row, ampstr, strlen(ampstr)); if (cp->printing) ps_draw_string(fap, amp_col, row, ampstr); } } row += row_height; } } else amp0 = 100.0; set_peak_numbers_font(cp, ax); if (cp->printing) ps_set_peak_numbers_font(); #if (!USE_GTK) row = fap->y_axis_y1 + row_height; #else row = fap->y_axis_y1; #endif if (cp->sound->channel_style == CHANNELS_SUPERIMPOSED) row += row_height * num_peaks * cp->chan; for (i = 0; i < num_peaks; i++) { if (peak_freqs[i].amp < amp0) { mus_float_t px; char *fstr; px = peak_freqs[i].freq; fstr = prettyf(px * end, tens); draw_string(ax, frq_col, row, fstr, strlen(fstr)); if (cp->printing) ps_draw_string(fap, frq_col, row, fstr); free(fstr); fstr = NULL; if (with_amps) { if ((fft_data) && (cp->fft_log_magnitude)) snprintf(ampstr, LABEL_BUFFER_SIZE, "%.1f", in_dB(cp->min_dB, cp->lin_dB, peak_freqs[i].amp)); else snprintf(ampstr, LABEL_BUFFER_SIZE, "%.*f", amp_strlen, peak_freqs[i].amp); draw_string(ax, amp_col, row, ampstr, strlen(ampstr)); if (cp->printing) ps_draw_string(fap, amp_col, row, ampstr); } } row += row_height; } /* superimposed context reset takes place in make_fft_graph */ if (cp->sound->channel_style == CHANNELS_SUPERIMPOSED) set_foreground_color(ax, old_color); if (peak_freqs) free(peak_freqs); if (peak_amps) free(peak_amps); } static void make_fft_graph(chan_info *cp, axis_info *fap, graphics_context *ax, with_hook_t with_hook) { /* axes are already set, data is in the fft_info struct -- don't reset here! */ /* since the fft size menu callback can occur while we are calculating the next fft, we have to lock the current size until the graph goes out */ fft_info *fp; snd_info *sp; mus_float_t *data; mus_float_t incr, x, scale; mus_long_t i, hisamp, losamp = 0; int lines_to_draw = 0; mus_float_t samples_per_pixel; int logx, logy; mus_float_t pslogx, pslogy, saved_data = 0.0; mus_float_t minlx = 0.0, curlx = 0.0, lscale = 1.0; mus_float_t *fft_phases = NULL; bool free_phases = false; sp = cp->sound; fp = cp->fft; if (chan_fft_in_progress(cp)) return; if (!fap->graph_active) return; data = fp->data; /* these lo..hi values are just for upcoming loops -- not axis info */ if (cp->transform_type == FOURIER) { hisamp = fp->current_size * cp->spectrum_end / 2; if ((cp->fft_log_frequency) && ((snd_srate(sp) * 0.5 * cp->spectrum_start) < log_freq_start(ss))) losamp = (mus_long_t)(ceil(fp->current_size * log_freq_start(ss) / (mus_float_t)snd_srate(sp))); else losamp = fp->current_size * cp->spectrum_start / 2; incr = (mus_float_t)snd_srate(sp) / (mus_float_t)(fp->current_size); } else { /* hisamp here is in terms of transform values, not original sampled data values */ hisamp = fp->current_size * cp->spectrum_end; losamp = fp->current_size * cp->spectrum_start; incr = 1.0; } if ((losamp < 0) || (losamp >= hisamp)) return; /* no scaling etc here!! see snd_display_fft in snd-fft.c */ scale = fp->scale; if (cp->printing) ps_allocate_grf_points(); samples_per_pixel = (mus_float_t)((double)(hisamp - losamp) / (mus_float_t)(fap->x_axis_x1 - fap->x_axis_x0)); if (cp->printing) ps_fg(cp, ax); if (cp->fft_log_frequency) { mus_float_t maxlx, max_data, log_range, fap_range; fap_range = fap->x1 - fap->x0; if (fap->x0 > 1.0) minlx = log(fap->x0); else minlx = 0.0; maxlx = log(fap->x1); log_range = (maxlx - minlx); lscale = fap_range / log_range; /* I think this block is getting the max of all the DC to losamp freqs to represent the 0th point of the graph?? */ max_data = data[0]; if ((spectrum_start(ss) == 0.0) && (losamp > 0)) { for (i = 1; i <= losamp; i++) if (data[i] > max_data) max_data = data[i]; } saved_data = data[losamp]; data[losamp] = max_data; } if ((samples_per_pixel < 4.0) && ((hisamp - losamp) < POINT_BUFFER_SIZE)) /* point buffer size in snd-draw.c: * hisamp - losamp can be anything (huge fft), and x1 - x0 can be > 2400 (very large screen) * so we have to check hisamp or make the buffer bigger */ { /* save phases if needed */ if ((cp->fft_with_phases) && (fp->phases) && (cp->transform_type == FOURIER)) { if (losamp == 0) { fft_phases = fp->phases; free_phases = false; } else { mus_long_t size; size = hisamp - losamp + 1; fft_phases = (mus_float_t *)malloc(size * sizeof(mus_float_t)); memcpy((void *)fft_phases, (void *)(&(fp->phases[losamp])), size * sizeof(mus_float_t)); free_phases = true; } } /* get fft graph points */ if ((!(cp->fft_log_magnitude)) && (!(cp->fft_log_frequency))) { if (losamp == 0) { for (i = 0, x = 0.0; i < hisamp; i++, x += incr) { mus_float_t scaled_data; scaled_data = data[i] * scale; set_grf_point(local_grf_x(x, fap), i, local_grf_y(scaled_data, fap)); if (cp->printing) ps_set_grf_point(x, i, scaled_data); } } else { for (i = losamp, x = fap->x0; i < hisamp; i++, x += incr) { mus_float_t scaled_data; scaled_data = data[i] * scale; set_grf_point(local_grf_x(x, fap), i - losamp, local_grf_y(scaled_data, fap)); if (cp->printing) ps_set_grf_point(x, i - losamp, scaled_data); } } } else { /* either log freq or log magnitude or both */ for (i = losamp, x = fap->x0; i < hisamp; i++, x += incr) { mus_float_t scaled_data; scaled_data = data[i] * scale; if (cp->fft_log_frequency) { if (x > 1.0) curlx = log(x); else curlx = 0.0; logx = local_grf_x(fap->x0 + lscale * (curlx - minlx), fap); } else logx = local_grf_x(x, fap); if (cp->fft_log_magnitude) logy = local_grf_y(in_dB(cp->min_dB, cp->lin_dB, scaled_data), fap); else logy = local_grf_y(scaled_data, fap); set_grf_point(logx, i - losamp, logy); if (cp->printing) { if (cp->fft_log_frequency) pslogx = fap->x0 + lscale * (curlx - minlx); else pslogx = x; if (cp->fft_log_magnitude) pslogy = in_dB(cp->min_dB, cp->lin_dB, scaled_data); else pslogy = scaled_data; ps_set_grf_point(pslogx, i - losamp, pslogy); } } } lines_to_draw = i - losamp; } else { mus_long_t j; mus_float_t xf, ina, ymax; if ((cp->fft_with_phases) && (fp->phases) && (cp->transform_type == FOURIER)) { fft_phases = (mus_float_t *)malloc(POINT_BUFFER_SIZE * sizeof(mus_float_t)); free_phases = true; } j = 0; /* graph point counter */ i = losamp; if (losamp == 0) x = 0.0; else x = fap->x0; xf = 0.0; /* samples per pixel counter */ ymax = MAX_INIT; if ((!(cp->fft_log_magnitude)) && (!(cp->fft_log_frequency))) { while (i < hisamp) { ina = data[i]; if (ina > ymax) { ymax = ina; if (fft_phases) fft_phases[j] = fp->phases[i]; } xf += 1.0; i++; if (xf > samples_per_pixel) { mus_float_t scaled_data; scaled_data = ymax * scale; set_grf_point(local_grf_x(x, fap), j, local_grf_y(scaled_data, fap)); x += (incr * samples_per_pixel); if (cp->printing) ps_set_grf_point(x, j, scaled_data); j++; xf -= samples_per_pixel; ymax = MAX_INIT; } } } else { while (i < hisamp) { ina = data[i]; if (ina > ymax) { ymax = ina; if (fft_phases) fft_phases[j] = fp->phases[i]; } xf += 1.0; i++; if (xf > samples_per_pixel) { mus_float_t scaled_data; scaled_data = ymax * scale; if (cp->fft_log_frequency) { if (x > 1.0) curlx = log(x); else curlx = 0.0; logx = local_grf_x(fap->x0 + lscale * (curlx - minlx), fap); } else logx = local_grf_x(x, fap); if (cp->fft_log_magnitude) logy = local_grf_y(in_dB(cp->min_dB, cp->lin_dB, scaled_data), fap); else logy = local_grf_y(scaled_data, fap); set_grf_point(logx, j, logy); if (cp->printing) { if (cp->fft_log_frequency) pslogx = fap->x0 + lscale * (curlx - minlx); else pslogx = x; if (cp->fft_log_magnitude) pslogy = in_dB(cp->min_dB, cp->lin_dB, scaled_data); else pslogy = scaled_data; ps_set_grf_point(pslogx, j, pslogy); } x += (incr * samples_per_pixel); j++; xf -= samples_per_pixel; ymax = MAX_INIT; } } } lines_to_draw = j; } if ((cp->fft_with_phases) && (fft_phases) && (cp->transform_type == FOURIER)) { int k; int *colors; color_t default_color; if (cp == selected_channel()) default_color = ss->selected_data_color; else default_color = ss->data_color; /* if value is close to 0, use [selected-]data-color, else use fft_phases[i] */ allocate_color_map(PHASES_COLORMAP); colors = (int *)malloc(lines_to_draw * sizeof(int)); for (k = 0; k < lines_to_draw; k++) { if (fft_phases[k] < 0.0) fft_phases[k] += 2.0 * M_PI; /* we want 0..2pi, not -pi..pi */ colors[k] = (int)((fft_phases[k] * color_map_size(ss)) / (2.0 * M_PI)); } draw_colored_lines(cp, ax, get_grf_points(), lines_to_draw, colors, fap->y_axis_y0, default_color); free(colors); if (free_phases) free(fft_phases); } else { if (sp->channel_style == CHANNELS_SUPERIMPOSED) { color_t old_color; old_color = get_foreground_color(ax); set_foreground_color(ax, cp->combined_data_color); draw_grf_points(cp->dot_size, ax, lines_to_draw, fap, 0.0, cp->transform_graph_style); set_foreground_color(ax, old_color); } else draw_grf_points(cp->dot_size, ax, lines_to_draw, fap, 0.0, cp->transform_graph_style); } if (cp->printing) ps_draw_grf_points(fap, lines_to_draw, 0.0, cp->transform_graph_style, cp->dot_size); if (cp->fft_log_frequency) data[losamp] = saved_data; if (cp->show_transform_peaks) { if (cp->transform_type == FOURIER) display_peaks(cp, fap, data, snd_srate(sp) * cp->spectrum_start / 2, snd_srate(sp) * cp->spectrum_end / 2, losamp, hisamp, samples_per_pixel, true, scale); else display_peaks(cp, fap, data, fp->current_size * cp->spectrum_start, fp->current_size * cp->spectrum_end, losamp, hisamp, samples_per_pixel, true, 0.0); } if (cp->selection_transform_size != 0) display_selection_transform_size(cp, fap, ax); if (sp->channel_style == CHANNELS_SUPERIMPOSED) { copy_context(cp); /* reset for axes etc */ if (cp->printing) ps_reset_color(); } if (with_hook == WITH_HOOK) after_transform(cp, scale); } static int skew_color(mus_float_t x) { mus_float_t base, val; int pos; if (x < color_cutoff(ss)) return(NO_COLOR); if (color_inverted(ss)) val = 1.0 - x; else val = x; base = color_scale(ss); if ((base > 0.0) && (base != 1.0)) val = (pow(base, val) - 1.0) / (base - 1.0); pos = (int)(val * color_map_size(ss)); if (pos > color_map_size(ss)) return(color_map_size(ss) - 1); if (pos > 0) return(pos - 1); return(0); } void make_sonogram(chan_info *cp) { #define SAVE_FFT_SIZE 4096 sono_info *si; static unsigned int *sono_js = NULL; static unsigned int sono_js_size = 0; #if CAIRO_HAS_RECORDING_SURFACE && (0) cairo_t *lcr = NULL; #endif if (chan_fft_in_progress(cp)) return; si = cp->sonogram_data; if ((si) && (si->scale > 0.0)) { int i, slice, fwidth, fheight, j, bins; int rectw, recth, cmap_size; axis_info *fap; mus_float_t xf, xfincr, yf, yfincr, frectw, frecth, xscl, scl = 1.0; mus_float_t *hfdata; int *hidata; graphics_context *ax; mus_float_t minlx = 0.0, lscale = 1.0; ax = copy_context(cp); fap = cp->fft->axis; fwidth = fap->x_axis_x1 - fap->x_axis_x0; /* these are the corners */ fheight = fap->y_axis_y0 - fap->y_axis_y1; if ((fwidth == 0) || (fheight == 0)) return; bins = (int)(si->target_bins * cp->spectrum_end); if (bins == 0) return; #if USE_MOTIF if (cp->fft_pix) /* Motif None = 0 */ { if ((cp->fft_changed == FFT_UNCHANGED) && (cp->fft_pix_ready) && (cp->fft_pix_cutoff == cp->spectrum_end) && ((int)(cp->fft_pix_width) == fwidth) && ((int)(cp->fft_pix_height) == fheight) && (cp->fft_pix_x0 == fap->x_axis_x0) && (cp->fft_pix_y0 == fap->y_axis_y1)) /* X is upside down */ { if (restore_fft_pix(cp, ax)) /* copy pix into drawing area and return */ return; } else { free_fft_pix(cp); } cp->fft_pix_ready = false; } #else #if CAIRO_HAS_RECORDING_SURFACE && (0) if (cp->fft_pix_ready) { if (cp->fft_pix) cairo_surface_destroy(cp->fft_pix); cp->fft_pix = NULL; cp->fft_pix_ready = false; } if ((enved_dialog_is_active()) && /* or we want to see the sonogram as the enved background */ (enved_target(ss) == ENVED_SPECTRUM) && (enved_with_wave(ss))) { cp->fft_pix = cairo_recording_surface_create(CAIRO_CONTENT_COLOR, NULL); lcr = cairo_create(cp->fft_pix); } #endif #endif if (sono_js_size != (unsigned int)color_map_size(ss)) { if (sono_js) free(sono_js); sono_js_size = (unsigned int)color_map_size(ss); sono_js = (unsigned int *)calloc(sono_js_size, sizeof(unsigned int)); } if (cp->printing) ps_allocate_grf_points(); allocate_sono_rects(si->total_bins); allocate_color_map(color_map(ss)); scl = si->scale; frectw = (mus_float_t)fwidth / (mus_float_t)(si->target_slices); frecth = (mus_float_t)fheight / (mus_float_t)bins; xscl = (mus_float_t)(fap->x1 - fap->x0) / (mus_float_t)(si->target_slices); rectw = (int)(ceil(frectw)); recth = (int)(ceil(frecth)); if (rectw == 0) rectw = 1; if (recth == 0) recth = 1; hfdata = (mus_float_t *)malloc((bins + 1) * sizeof(mus_float_t)); hidata = (int *)malloc((bins + 1) * sizeof(int)); if (cp->transform_type == FOURIER) { if (cp->fft_log_frequency) { mus_float_t maxlx, fap_range, log_range; fap_range = fap->y1 - fap->y0; if (fap->y0 > 1.0) minlx = log(fap->y0); else minlx = 0.0; maxlx = log(fap->y1); log_range = (maxlx - minlx); lscale = fap_range / log_range; } yfincr = cp->spectrum_end * (mus_float_t)snd_srate(cp->sound) * 0.5 / (mus_float_t)bins; } else yfincr = 1.0; if (cp->fft_log_frequency) { for (yf = 0.0, i = 0; i <= bins; i++, yf += yfincr) { mus_float_t curlx; if (yf > 1.0) curlx = log(yf); else curlx = 0.0; hfdata[i] = fap->y0 + lscale * (curlx - minlx); hidata[i] = local_grf_y(hfdata[i], fap); } } else { for (yf = 0.0, i = 0; i <= bins; i++, yf += yfincr) { hfdata[i] = yf; hidata[i] = local_grf_y(yf, fap); } } xfincr = ((mus_float_t)fwidth / (mus_float_t)(si->target_slices)); xf = 2 + fap->x_axis_x0; ss->stopped_explicitly = false; cmap_size = color_map_size(ss) - 4; for (slice = 0; slice < si->active_slices; slice++, xf += xfincr) { mus_float_t *fdata; memset((void *)sono_js, 0, color_map_size(ss) * sizeof(unsigned int)); fdata = si->data[slice]; for (i = 0; i < bins; i++) { mus_float_t binval; /* above is fdata[i-1], left is si->data[slice-1][i] */ binval = fdata[i] / scl; if (cp->fft_log_magnitude) binval = 1.0 - (in_dB(cp->min_dB, cp->lin_dB, binval)) / cp->min_dB; j = skew_color(binval); if (j != NO_COLOR) { if (cp->fft_log_frequency) set_sono_rectangle(sono_js[j], j, (int)xf, hidata[i + 1], rectw, (int)(hidata[i] - hidata[i + 1])); else set_sono_rectangle(sono_js[j], j, (int)xf, hidata[i + 1], rectw, recth); if (cp->printing) { if (cp->fft_log_frequency) ps_draw_sono_rectangle(fap, j, fap->x0 + xscl * slice, hfdata[i + 1], frectw, hidata[i] - hidata[i + 1]); else ps_draw_sono_rectangle(fap, j, fap->x0 + xscl * slice, hfdata[i + 1], frectw, -frecth); } sono_js[j]++; } } i = 0; while (i <= cmap_size) { if (sono_js[i] != 0) draw_sono_rectangles(ax, i, sono_js[i]); i++; if (sono_js[i] != 0) draw_sono_rectangles(ax, i, sono_js[i]); i++; if (sono_js[i] != 0) draw_sono_rectangles(ax, i, sono_js[i]); i++; if (sono_js[i] != 0) draw_sono_rectangles(ax, i, sono_js[i]); i++; } for (; i < color_map_size(ss); i++) if (sono_js[i] != 0) draw_sono_rectangles(ax, i, sono_js[i]); #if CAIRO_HAS_RECORDING_SURFACE && (0) if ((cp->fft_pix) && (lcr)) { cairo_t *old_cr; old_cr = ss->cr; ss->cr = lcr; for (i = 0; i < color_map_size(ss); i++) if (sono_js[i] != 0) draw_sono_rectangles(ax, i, sono_js[i]); ss->cr = old_cr; } #endif } #if USE_MOTIF /* if size was wrong, we've already released pix above */ if ((bins >= SAVE_FFT_SIZE) || /* transform size of twice that (8192) */ ((enved_dialog_is_active()) && /* or we want to see the sonogram as the enved background */ (enved_target(ss) == ENVED_SPECTRUM) && (enved_with_wave(ss)))) save_fft_pix(cp, ax, fwidth, fheight, fap->x_axis_x0, fap->y_axis_y1); #else #if CAIRO_HAS_RECORDING_SURFACE && (0) if (cp->fft_pix) { cp->fft_pix_ready = true; cairo_destroy(lcr); } #endif #endif if (cp->printing) ps_reset_color(); free(hfdata); free(hidata); if (cp->hookable == WITH_HOOK) after_transform(cp, 1.0 / scl); } } static void rotate_matrix(mus_float_t xangle, mus_float_t yangle, mus_float_t zangle, mus_float_t xscl, mus_float_t yscl, mus_float_t zscl, mus_float_t *mat) { /* return rotation matrix for rotation through angles xangle, yangle, then zangle with scaling by xscl, yscl, zscl */ mus_float_t sinx, siny, sinz, cosx, cosy, cosz, deg; mus_float_t x, y, z; deg = 2.0 * M_PI / 360.0; x = xangle * deg; y = yangle * deg; z = zangle * deg; sinx = sin(x); siny = sin(y); sinz = sin(z); cosx = cos(x); cosy = cos(y); cosz = cos(z); mat[0] = cosy * cosz * xscl; mat[1] = (sinx * siny * cosz - cosx * sinz) * yscl; mat[2] = (cosx * siny * cosz + sinx * sinz) * zscl; mat[3] = cosy * sinz * xscl; mat[4] = (sinx * siny * sinz + cosx * cosz) * yscl; mat[5] = (cosx * siny * sinz - sinx * cosz) * zscl; mat[6] = -siny * xscl; mat[7] = sinx * cosy * yscl; mat[8] = cosx * cosy * zscl; } static void rotate(mus_float_t *xyz, mus_float_t *mat) { /* use rotation/scaling matrix set up by rotate_matrix to rotate and scale the vector xyz */ mus_float_t x, y, z; x = xyz[0]; y = xyz[1]; z = xyz[2]; xyz[0] = mat[0] * x + mat[1] * y + mat[2] * z; xyz[1] = mat[3] * x + mat[4] * y + mat[5] * z; xyz[2] = mat[6] * x + mat[7] * y + mat[8] * z; } #if HAVE_GL void reset_spectro(void) { /* only used in orientation dialog button and Enter key binding */ set_spectrum_end(DEFAULT_SPECTRUM_END); set_spectrum_start(DEFAULT_SPECTRUM_START); set_spectro_hop(DEFAULT_SPECTRO_HOP); set_spectro_x_angle((with_gl(ss)) ? DEFAULT_SPECTRO_X_ANGLE : 90.0); set_spectro_y_angle((with_gl(ss)) ? DEFAULT_SPECTRO_Y_ANGLE : 0.0); set_spectro_z_angle((with_gl(ss)) ? DEFAULT_SPECTRO_Z_ANGLE : 358.0); set_spectro_x_scale((with_gl(ss)) ? DEFAULT_SPECTRO_X_SCALE : 1.0); set_spectro_y_scale((with_gl(ss)) ? DEFAULT_SPECTRO_Y_SCALE : 1.0); set_spectro_z_scale((with_gl(ss)) ? DEFAULT_SPECTRO_Z_SCALE : 0.1); } #if HAVE_GLU #include #endif static GLdouble unproject_to_x(int x, int y) { #if HAVE_GLU /* taken from GL doc p152 */ GLint viewport[4]; GLdouble mv[16], proj[16]; GLint realy; GLdouble wx = 0.0, wy, wz; glGetIntegerv(GL_VIEWPORT, viewport); glGetDoublev(GL_MODELVIEW_MATRIX, mv); glGetDoublev(GL_PROJECTION_MATRIX, proj); realy = viewport[3] - (GLint)y - 1; gluUnProject((GLdouble)x, (GLdouble)realy, 0.0, mv, proj, viewport, &wx, &wy, &wz); return(wx); #else return(0.0); #endif } static GLdouble unproject_to_y(int x, int y) { #if HAVE_GLU /* taken from GL doc p152 */ GLint viewport[4]; GLdouble mv[16], proj[16]; GLint realy; GLdouble wx, wy = 0.0, wz; glGetIntegerv(GL_VIEWPORT, viewport); glGetDoublev(GL_MODELVIEW_MATRIX, mv); glGetDoublev(GL_PROJECTION_MATRIX, proj); realy = viewport[3] - (GLint)y - 1; gluUnProject((GLdouble)x, (GLdouble)realy, 0.0, mv, proj, viewport, &wx, &wy, &wz); return(wy); #else return(0.0); #endif } #else void reset_spectro(void) { /* only used in orientation dialog button and Enter key binding */ set_spectrum_end(DEFAULT_SPECTRUM_END); set_spectrum_start(DEFAULT_SPECTRUM_START); set_spectro_hop(DEFAULT_SPECTRO_HOP); set_spectro_x_angle(DEFAULT_SPECTRO_X_ANGLE); set_spectro_y_angle(DEFAULT_SPECTRO_Y_ANGLE); set_spectro_z_angle(DEFAULT_SPECTRO_Z_ANGLE); set_spectro_x_scale(DEFAULT_SPECTRO_X_SCALE); set_spectro_y_scale(DEFAULT_SPECTRO_Y_SCALE); set_spectro_z_scale(DEFAULT_SPECTRO_Z_SCALE); } #endif static void display_channel_lisp_data(chan_info *cp); static void make_axes(chan_info *cp, axis_info *ap, x_axis_style_t x_style, bool erase_first, with_grid_t grid, log_axis_t log_axes, show_axes_t axes); #define DONT_CLEAR_GRAPH false #define CLEAR_GRAPH true #if HAVE_GL #if USE_MOTIF static void set_up_for_gl(chan_info *cp) { glXMakeCurrent(MAIN_DISPLAY(ss), XtWindow(channel_graph(cp)), ss->cx); } static void gl_display(chan_info *cp) { if (ss->gl_has_double_buffer) glXSwapBuffers(MAIN_DISPLAY(ss), XtWindow(channel_graph(cp))); else glFlush(); } #else static void set_up_for_gl(chan_info *cp) { /* probably gdk_gl_context_make_current */ } static void gl_display(chan_info *cp) { glFlush(); } #endif #define GL_COLOR_SET(R, G, B) glColor3us(R, G, B) static void gl_spectrogram(sono_info *si, int gl_fft_list, mus_float_t cutoff, bool use_dB, mus_float_t min_dB, rgb_t br, rgb_t bg, rgb_t bb) { mus_float_t lin_dB = 0.0; mus_float_t xincr, yincr, y0, x1; int bins = 0, slice, i, j; float inv_scl; int **js = NULL; inv_scl = 1.0 / si->scale; if (use_dB) lin_dB = pow(10.0, min_dB * 0.05); glNewList((GLuint)gl_fft_list, GL_COMPILE); bins = (int)(si->target_bins * cutoff); if (bins <= 0) bins = 1; js = (int **)calloc(si->active_slices, sizeof(int *)); for (i = 0; i < si->active_slices; i++) { js[i] = (int *)calloc(bins, sizeof(int)); if (use_dB) { for (j = 0; j < bins; j++) js[i][j] = skew_color(1.0 - (in_dB(min_dB, lin_dB, si->data[i][j] * inv_scl)) / min_dB); } else { for (j = 0; j < bins; j++) js[i][j] = skew_color(si->data[i][j] * inv_scl); /* can be NO_COLOR (-1) */ } } xincr = 1.0 / (float)(si->active_slices); yincr = 1.0 / (float)bins; x1 = -0.5; for (slice = 0; slice < si->active_slices - 1; slice++) { mus_float_t x0, y1; x0 = x1; x1 += xincr; y1 = -0.5; for (i = 0; i < bins - 1; i++) { rgb_t r, g, b; mus_float_t val00, val01, val11, val10; glBegin(GL_POLYGON); y0 = y1; y1 += yincr; val00 = si->data[slice][i] * inv_scl; val01 = si->data[slice][i + 1] * inv_scl; val10 = si->data[slice + 1][i] * inv_scl; val11 = si->data[slice + 1][i + 1] * inv_scl; if (use_dB) { val00 = 1.0 - (in_dB(min_dB, lin_dB, val00)) / min_dB; val01 = 1.0 - (in_dB(min_dB, lin_dB, val01)) / min_dB; val10 = 1.0 - (in_dB(min_dB, lin_dB, val10)) / min_dB; val11 = 1.0 - (in_dB(min_dB, lin_dB, val11)) / min_dB; } if (js[slice][i] != NO_COLOR) { get_current_color(color_map(ss), js[slice][i], &r, &g, &b); GL_COLOR_SET(r, g, b); } else GL_COLOR_SET(br, bg, bb); glVertex3f(x0, val00, y0); if (js[slice + 1][i] != NO_COLOR) { get_current_color(color_map(ss), js[slice + 1][i], &r, &g, &b); GL_COLOR_SET(r, g, b); } else GL_COLOR_SET(br, bg, bb); glVertex3f(x1, val10, y0); if (js[slice + 1][i + 1] != NO_COLOR) { get_current_color(color_map(ss), js[slice + 1][i + 1], &r, &g, &b); GL_COLOR_SET(r, g, b); } else GL_COLOR_SET(br, bg, bb); glVertex3f(x1, val11, y1); if (js[slice][i + 1] != NO_COLOR) { get_current_color(color_map(ss), js[slice][i + 1], &r, &g, &b); GL_COLOR_SET(r, g, b); } else GL_COLOR_SET(br, bg, bb); glVertex3f(x0, val01, y1); glEnd(); } } for (i = 0; i < si->active_slices; i++) free(js[i]); free(js); js = NULL; glEndList(); } static bool gl_warned_already = false; static bool make_gl_spectrogram(chan_info *cp) { sono_info *si; axis_info *fap; snd_info *sp; bool need_relist = false; rgb_t br = RGB_MAX, bg = RGB_MAX, bb = RGB_MAX; #if USE_MOTIF Colormap cmap; XColor tmp_color; Display *dpy; #endif si = cp->sonogram_data; sp = cp->sound; /* experiments with lighting were a bust -- does not improve things (ditto fog, translucency, grid) */ fap = cp->fft->axis; if ((cp->printing) && (!gl_warned_already)) { gl_warned_already = true; #if WITH_GL2PS snd_warning("use " S_gl_graph_to_ps " to print openGL graphs"); #else snd_warning("we need openGL and gl2ps to print openGL graphs"); #endif } set_up_for_gl(cp); if (cp->gl_fft_list == NO_LIST) { need_relist = true; cp->gl_fft_list = (int)glGenLists(1); } else { if (cp->fft_changed == FFT_CHANGED) { glDeleteLists((GLuint)(cp->gl_fft_list), 1); cp->gl_fft_list = (int)glGenLists(1); need_relist = true; } } glEnable(GL_DEPTH_TEST); glShadeModel(GL_SMOOTH); glClearDepth(1.0); #if USE_MOTIF /* get the background color */ dpy = XtDisplay(MAIN_SHELL(ss)); cmap = DefaultColormap(dpy, DefaultScreen(dpy)); tmp_color.flags = DoRed | DoGreen | DoBlue; if (cp == selected_channel()) tmp_color.pixel = ss->selected_graph_color; else tmp_color.pixel = ss->graph_color; XQueryColor(dpy, cmap, &tmp_color); br = tmp_color.red; bg = tmp_color.green; bb = tmp_color.blue; glClearColor(rgb_to_float(tmp_color.red), rgb_to_float(tmp_color.green), rgb_to_float(tmp_color.blue), 0.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); #endif if (need_relist) gl_spectrogram(si, cp->gl_fft_list, cp->spectrum_end, cp->fft_log_magnitude, cp->min_dB, br, bg, bb); glViewport(fap->graph_x0, 0, fap->width, fap->height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); /* glOrtho(-1.0, 1.0, -1.0, 1.0, 1.0, -1.0); */ /* this appears to be the default */ glRotatef(cp->spectro_x_angle, 1.0, 0.0, 0.0); glRotatef(cp->spectro_y_angle, 0.0, 1.0, 0.0); glRotatef(cp->spectro_z_angle, 0.0, 0.0, 1.0); glScalef(cp->spectro_x_scale, cp->spectro_y_scale, cp->spectro_z_scale); glCallList((GLuint)(cp->gl_fft_list)); fap->use_gl = true; { double frq0, frq1; frq0 = snd_srate(sp) * cp->spectrum_start / 2.0; frq1 = snd_srate(sp) * cp->spectrum_end / 2.0; make_axis_info(cp, cp->axis->x0, cp->axis->x1, frq0, frq1, "time", cp->axis->x0, cp->axis->x1, frq0, frq1, fap); } make_axes(cp, fap, X_AXIS_IN_SECONDS, DONT_CLEAR_GRAPH, NO_GRID, WITH_LINEAR_AXES, cp->show_axes); /* there's no support for GL log y axis labelling in snd-axis.c (line 1244), or in the axis bounds * choice here (see snd-fft.c -- need to check spectrum_start etc), or in gl_spectrogram above, * so ignore the log_freq setting -- since log freq really doesn't add much (unlike dB for example), * the extra work seems wasted. */ fap->use_gl = false; gl_display(cp); /* a kludge to get the normal graph drawn (again...) */ if (cp->graph_time_on) display_channel_time_data(cp); if (cp->graph_lisp_on) display_channel_lisp_data(cp); #if USE_MOTIF return(XtAppPending(MAIN_APP(ss)) == 0); /* return true if there are no pending events to force current buffer to be displayed */ #endif } #endif /* HAVE_GL */ static bool make_spectrogram(chan_info *cp) { sono_info *si; axis_info *fap; graphics_context *ax; mus_float_t *fdata; mus_float_t matrix[9]; mus_float_t xyz[3]; mus_float_t xoff, yoff, xincr, yincr, x0, y0, binval, scl = 1.0; mus_float_t fwidth, fheight, zscl, yval, xval; int bins = 0, slice, i, j, xx = 0, yy = 0; bool old_with_gl = false; mus_float_t minlx = 0.0, lscale = 0.0, fap_incr = 0.0; if (chan_fft_in_progress(cp)) return(false); si = cp->sonogram_data; if ((!si) || (si->scale <= 0.0)) return(false); #if HAVE_GL if (((cp->sound->nchans == 1) || (cp->sound->channel_style == CHANNELS_SEPARATE)) && (color_map(ss) != BLACK_AND_WHITE_COLORMAP) && (with_gl(ss))) return(make_gl_spectrogram(cp)); #endif old_with_gl = with_gl(ss); if (old_with_gl) set_with_gl(false, false); /* needed to fixup spectro angles/scales etc */ if (cp->printing) ps_allocate_grf_points(); scl = si->scale; /* unnormalized fft doesn't make much sense here (just washes out the graph) */ fap = cp->fft->axis; bins = (int)(si->target_bins * cp->spectrum_end); fwidth = (fap->x_axis_x1 - fap->x_axis_x0); fheight = (fap->y_axis_y1 - fap->y_axis_y0); /* negative! */ xincr = fwidth / (mus_float_t)bins; yincr = fheight / (mus_float_t)si->active_slices; x0 = (fap->x_axis_x0 + fap->x_axis_x1) * 0.5; y0 = (fap->y_axis_y0 + fap->y_axis_y1) * 0.5; if (!(cp->fft_log_magnitude)) zscl = -(cp->spectro_z_scale * fheight / scl); else zscl = -(cp->spectro_z_scale * fheight); rotate_matrix(cp->spectro_x_angle, cp->spectro_y_angle, cp->spectro_z_angle, cp->spectro_x_scale, cp->spectro_y_scale, zscl, matrix); if (cp->fft_log_frequency) { fap_incr = (fap->x1 - fap->x0) / bins; if (fap->x0 > 1.0) minlx = log(fap->x0); else minlx = 0.0; lscale = (fap->x_axis_x1 - fap->x_axis_x0) / (log(fap->x1) - minlx); } ax = copy_context(cp); if (color_map(ss) != BLACK_AND_WHITE_COLORMAP) allocate_color_map(color_map(ss)); ss->stopped_explicitly = false; for (slice = 0, xoff = fap->x_axis_x0, yoff = fap->y_axis_y0; slice < si->active_slices; slice++, yoff += yincr) { mus_float_t x, y; fdata = si->data[slice]; x = xoff; y = yoff; if (color_map(ss) != BLACK_AND_WHITE_COLORMAP) { xyz[0] = x - x0; xyz[1] = y - y0; xyz[2] = fdata[0]; rotate(xyz, matrix); xx = (int)(xyz[0] + x0); yy = (int)(xyz[1] + xyz[2] + y0); } for (i = 0; i < bins; i++, x += xincr) { mus_float_t logx; if (cp->fft_log_frequency) { mus_float_t fx, curlx; fx = fap->x0 + fap_incr * i; if (fx > 1.0) curlx = log(fx); else curlx = 0.0; logx = fap->x_axis_x0 + (curlx - minlx) * lscale; } else logx = x; xyz[0] = logx - x0; xyz[1] = y - y0; binval = fdata[i] / scl; if (!(cp->fft_log_magnitude)) xyz[2] = fdata[i]; else { xyz[2] = 1.0 - (in_dB(cp->min_dB, cp->lin_dB, binval)) / cp->min_dB; binval = xyz[2]; } rotate(xyz, matrix); yval = xyz[1] + xyz[2]; xval = xyz[0]; if (color_map(ss) == BLACK_AND_WHITE_COLORMAP) { set_grf_point((int)(xval + x0), i, (int)(yval + y0)); if (cp->printing) ps_set_grf_point(ungrf_x(fap, (int)(xval + x0)), i, ungrf_y(fap, (int)(yval + y0))); } else { j = skew_color(binval); if (j != NO_COLOR) { draw_spectro_line(ax, j, xx, yy, (int)(xval + x0), (int)(yval + y0)); if (cp->printing) ps_draw_spectro_line(fap, j, xx, yy, xval + x0, yval + y0); } xx = (int)(xval + x0); yy = (int)(yval + y0); } } if (color_map(ss) == BLACK_AND_WHITE_COLORMAP) draw_grf_points(cp->dot_size, ax, bins, fap, 0.0, cp->transform_graph_style); if ((cp->printing) && (color_map(ss) == BLACK_AND_WHITE_COLORMAP)) ps_draw_grf_points(fap, bins, 0.0, cp->transform_graph_style, cp->dot_size); } if ((cp->printing) && (color_map(ss) != BLACK_AND_WHITE_COLORMAP)) ps_reset_color(); if (cp->hookable == WITH_HOOK) after_transform(cp, 1.0 / scl); if (old_with_gl) set_with_gl(true, false); return(false); } /* ---------------------------------------- wavograms ---------------------------------------- */ /* (with-sound () (do ((j 0 (+ j 1))) ((= j 500)) (do ((i 0 (+ i 1))) ((= i 100)) (outa (+ (* j 100) i) (* i j .002 .01))))) * * xdeg=45, ydeg=0, zdeg=0 is the "flat" display */ typedef struct wavogram_state { int hop, trace, width, height, graph_x0, cmap, cmap_size, edit_ctr; bool inverted; mus_float_t scale, cutoff; mus_long_t losamp; mus_float_t x_scale, y_scale, z_scale, z_angle, x_angle, y_angle; /* only used in non-GL case */ } wavogram_state; static int make_wavogram(chan_info *cp) { snd_info *sp; mus_float_t xoff, x0, y0, xincr; mus_float_t width, height, zscl, yval, xval, binval; int i, j, points = 0, yincr, yoff; mus_float_t matrix[9]; mus_float_t xyz[3]; axis_info *ap; graphics_context *ax; snd_fd *sf = NULL; wavogram_state *lw; #if USE_MOTIF bool need_redraw = true; #endif #if HAVE_GL || USE_MOTIF bool use_gl = false; bool need_new_list = true; #endif sp = cp->sound; ap = cp->axis; if (sp) ap->losamp = (mus_long_t)(ap->x0 * snd_srate(sp)); #if HAVE_GL if (((sp->nchans == 1) || (sp->channel_style == CHANNELS_SEPARATE)) && (color_map(ss) != BLACK_AND_WHITE_COLORMAP) && (with_gl(ss))) use_gl = true; #endif lw = cp->last_wavogram; if (lw) { #if HAVE_GL || USE_MOTIF need_new_list = (!((lw->hop == wavo_hop(ss)) && (lw->trace == wavo_trace(ss)) && (lw->losamp == ap->losamp) && (lw->width == ap->width) && (lw->height == ap->height) && (lw->graph_x0 == ap->graph_x0) && (lw->cmap == color_map(ss)) && (lw->cmap_size == color_map_size(ss)) && (lw->edit_ctr == cp->edit_ctr) && (lw->inverted == color_inverted(ss)) && (lw->scale == color_scale(ss)) && (lw->cutoff == color_cutoff(ss)))); #endif #if HAVE_GL if (use_gl) { if (cp->gl_wavo_list == NO_LIST) need_new_list = true; } #endif #if USE_MOTIF need_redraw = (!((lw->x_scale == spectro_x_scale(ss)) && (lw->y_scale == spectro_y_scale(ss)) && (lw->z_scale == spectro_z_scale(ss)) && (lw->x_angle == spectro_x_angle(ss)) && (lw->y_angle == spectro_y_angle(ss)) && (lw->z_angle == spectro_z_angle(ss)))); #endif } #if USE_MOTIF if ((!use_gl) && (!need_redraw) && (!need_new_list)) return(-1); /* not 0 here because I think that would cancel fft graph */ #endif if (cp->last_wavogram) free(cp->last_wavogram); lw = (wavogram_state *)malloc(sizeof(wavogram_state)); lw->hop = wavo_hop(ss); lw->trace = wavo_trace(ss); lw->losamp = ap->losamp; lw->width = ap->width; lw->height = ap->height; lw->graph_x0 = ap->graph_x0; lw->cmap = color_map(ss); lw->cmap_size = color_map_size(ss); lw->edit_ctr = cp->edit_ctr; lw->inverted = color_inverted(ss); lw->scale = color_scale(ss); lw->cutoff = color_cutoff(ss); lw->x_scale = spectro_x_scale(ss); lw->y_scale = spectro_y_scale(ss); lw->z_scale = spectro_z_scale(ss); lw->x_angle = spectro_x_angle(ss); lw->y_angle = spectro_y_angle(ss); lw->z_angle = spectro_z_angle(ss); cp->last_wavogram = lw; #if HAVE_GL if (use_gl) { mus_float_t **samps = NULL; int **js = NULL; float x0, x1, y0, y1; /* x5inc, y5inc; */ mus_float_t xinc, yinc; int lines = 0, len = 0; rgb_t *rs = NULL; if (need_new_list) { sf = init_sample_read(ap->losamp, cp, READ_FORWARD); if (sf == NULL) return(0); lines = (int)(ap->height / cp->wavo_hop); if (lines == 0) return(0); len = cp->wavo_trace; samps = (mus_float_t **)calloc(lines, sizeof(mus_float_t *)); js = (int **)calloc(lines, sizeof(int *)); for (i = 0; i < lines; i++) { samps[i] = (mus_float_t *)calloc(len, sizeof(mus_float_t)); js[i] = (int *)calloc(len, sizeof(int)); for (j = 0; j < len; j++) { samps[i][j] = read_sample(sf); js[i][j] = skew_color(fabs(samps[i][j])); if (js[i][j] < 0) js[i][j] = 0; } } free_snd_fd(sf); } set_up_for_gl(cp); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glClearDepth(1.0); glClearColor(1.0, 1.0, 1.0, 0.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glViewport(ap->graph_x0, 0, ap->width, ap->height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glRotatef(cp->spectro_x_angle, 1.0, 0.0, 0.0); glRotatef(cp->spectro_y_angle, 0.0, 1.0, 0.0); glRotatef(cp->spectro_z_angle, 0.0, 0.0, 1.0); glScalef(cp->spectro_x_scale, cp->spectro_y_scale, cp->spectro_z_scale); if (!need_new_list) { glCallList((GLuint)(cp->gl_wavo_list)); gl_display(cp); return((int)(lw->height / lw->hop)); } if (cp->gl_wavo_list == NO_LIST) cp->gl_wavo_list = (int)glGenLists(1); else { glDeleteLists((GLuint)(cp->gl_wavo_list), 1); cp->gl_wavo_list = (int)glGenLists(1); } xinc = 2.0 / (mus_float_t)len; yinc = 2.0 / (mus_float_t)lines; /* x5inc = 1.25 * xinc; */ /* y5inc = 1.25 * yinc; */ rs = color_map_reds(color_map(ss)); glNewList((GLuint)(cp->gl_wavo_list), GL_COMPILE); if (rs) { int len1, lines1; mus_float_t xf; rgb_t *gs, *bs; /* each line is wavo_trace samps, there are (height / wave_hop) of these? */ gs = color_map_greens(color_map(ss)); bs = color_map_blues(color_map(ss)); y1 = -1.0; len1 = len - 1; lines1 = lines - 1; for (j = 0; j < lines1; j++) { mus_float_t yf; x1 = -1.0; y0 = y1; y1 += yinc; yf = y1 + yinc / 2.0; for (i = 0; i < len1; i++) { int c; x0 = x1; x1 += xinc; xf = x1 + xinc / 2.0; glBegin(GL_QUADS); c = js[j][i]; GL_COLOR_SET(rs[c], gs[c], bs[c]); glVertex3f(x0, samps[j][i], y0); c = js[j + 1][i]; GL_COLOR_SET(rs[c], gs[c], bs[c]); glVertex3f(xf, samps[j+ 1][i], y0); c = js[j + 1][i + 1]; GL_COLOR_SET(rs[c], gs[c], bs[c]); glVertex3f(xf, samps[j + 1][i + 1], yf); c = js[j][i + 1]; GL_COLOR_SET(rs[c], gs[c], bs[c]); glVertex3f(x0, samps[j][i + 1], y1 + yf); glEnd(); } } } else { int len1, lines1; y1 = -1.0; len1 = len - 1; lines1 = lines - 1; for (j = 0; j < lines1; j++) { x1 = -1.0; y0 = y1; y1 += yinc; for (i = 0; i < len1; i++) { rgb_t r, g, b; x0 = x1; x1 += xinc; glBegin(GL_QUADS); get_current_color(color_map(ss), js[j][i], &r, &g, &b); GL_COLOR_SET(r, g, b); glVertex3f(x0, samps[j][i], y0); get_current_color(color_map(ss), js[j + 1][i], &r, &g, &b); GL_COLOR_SET(r, g, b); glVertex3f(x1, samps[j+ 1][i], y0); get_current_color(color_map(ss), js[j + 1][i + 1], &r, &g, &b); GL_COLOR_SET(r, g, b); glVertex3f(x1, samps[j + 1][i + 1], y1); get_current_color(color_map(ss), js[j][i + 1], &r, &g, &b); GL_COLOR_SET(r, g, b); glVertex3f(x0, samps[j][i + 1], y1); glEnd(); } } } glEndList(); glCallList((GLuint)(cp->gl_wavo_list)); gl_display(cp); for (i = 0; i < lines; i++) { free(samps[i]); free(js[i]); } free(samps); free(js); return(j); } #endif sf = init_sample_read(ap->losamp, cp, READ_FORWARD); if (sf == NULL) return(0); /* set up the graph width and so on */ make_axes_1(ap, cp->x_axis_style, snd_srate(sp), SHOW_NO_AXES, NOT_PRINTING, NO_X_AXIS, NO_GRID, WITH_LINEAR_AXES, 1.0); erase_rectangle(cp, ap->ax, ap->graph_x0, ap->y_offset, ap->width, ap->height); if (cp->printing) ps_allocate_grf_points(); width = (ap->x_axis_x1 - ap->x_axis_x0); height = (ap->y_axis_y1 - ap->y_axis_y0); /* negative! */ xincr = width / (mus_float_t)(cp->wavo_trace); yincr = -(cp->wavo_hop); if (yincr > 0) yincr = -yincr; if (yincr == 0) yincr = -1; x0 = (ap->x_axis_x0 + ap->x_axis_x1) * 0.5; y0 = (ap->y_axis_y0 + ap->y_axis_y1) * 0.5; zscl = -(cp->spectro_z_scale * height); rotate_matrix(cp->spectro_x_angle, cp->spectro_y_angle, cp->spectro_z_angle, cp->spectro_x_scale, cp->spectro_y_scale, zscl, matrix); ax = copy_context(cp); if (color_map(ss) != BLACK_AND_WHITE_COLORMAP) allocate_color_map(color_map(ss)); for (xoff = ap->x_axis_x0, yoff = ap->y_axis_y0; yoff > ap->y_axis_y1; yoff += yincr) { mus_float_t x, y, xx, yy; xx = -1; yy = (int)y0; /* ? */ x = xoff; y = yoff; for (i = 0; i < cp->wavo_trace; i++, x += xincr) { binval = read_sample(sf); xyz[0] = x - x0; xyz[1] = y - y0; xyz[2] = binval; rotate(xyz, matrix); yval = xyz[1] + xyz[2]; xval = xyz[0]; if (color_map(ss) == BLACK_AND_WHITE_COLORMAP) { set_grf_point((int)(xval + x0), i, (int)(yval + y0)); if (cp->printing) ps_set_grf_point(ungrf_x(ap, (int)(xval + x0)), i, ungrf_y(ap, (int)(y0 + yval))); } else { /* for color decision here we need absolute value of data */ if (binval < 0.0) binval = -binval; if (xx != -1) { j = skew_color(binval); if (j != NO_COLOR) { draw_spectro_line(ax, j, xx, yy, (int)(xval + x0), (int)(yval + y0)); if (cp->printing) ps_draw_spectro_line(ap, j, xx, yy, xval + x0, yval + y0); } } xx = (int)(xval + x0); yy = (int)(yval + y0); } } points += cp->wavo_trace; if (color_map(ss) == BLACK_AND_WHITE_COLORMAP) { draw_grf_points(cp->dot_size, ax, cp->wavo_trace, ap, 0.0, cp->time_graph_style); if (cp->printing) ps_draw_grf_points(ap, cp->wavo_trace, 0.0, cp->time_graph_style, cp->dot_size); } } if ((cp->printing) && (color_map(ss) != BLACK_AND_WHITE_COLORMAP)) ps_reset_color(); free_snd_fd(sf); return(points); } axis_info *lisp_info_axis(chan_info *cp) { return(cp->lisp_info->axis); } void free_lisp_info(chan_info *cp) { if (cp) { lisp_grf *lg; lg = cp->lisp_info; if (lg) { if (lg->axis) lg->axis = free_axis_info(lg->axis); if (lg->data) { int i; for (i = 0; i < lg->graphs; i++) if (lg->data[i]) free(lg->data[i]); free(lg->data); } if (lg->len) free(lg->len); free(lg); } } } static void make_lisp_graph(chan_info *cp, Xen pixel_list) { snd_info *sp; lisp_grf *up; /* data can be evenly spaced data or an envelope (up->env_data) */ axis_info *uap = NULL; int i; graphics_context *ax; sp = cp->sound; up = cp->lisp_info; if (up) uap = up->axis; else return; if ((!uap) || (!uap->graph_active) || (up->len == NULL) || (up->len[0] <= 0)) return; if (cp->printing) ps_allocate_grf_points(); if (sp->channel_style == CHANNELS_SUPERIMPOSED) ax = combined_context(cp); else ax = copy_context(cp); if (cp->printing) ps_fg(cp, ax); if (up->env_data) { int x0, y0; int grf_len; grf_len = up->len[0]; x0 = local_grf_x(up->data[0][0], uap); y0 = local_grf_y(up->data[0][1], uap); if (cp->dot_size > 0) draw_dot(ax, x0, y0, cp->dot_size); for (i = 2; i < grf_len; i += 2) { int x1, y1; x1 = local_grf_x(up->data[0][i], uap); y1 = local_grf_y(up->data[0][i + 1], uap); draw_line(ax, x0, y0, x1, y1); if (cp->dot_size > 0) draw_dot(ax, x1, y1, cp->dot_size); x0 = x1; y0 = y1; } } else { int j, graph, pixel_len = -1; color_t old_color = 0; mus_float_t x, y; if (Xen_is_list(pixel_list)) pixel_len = Xen_list_length(pixel_list); if (up->graphs > 1) old_color = get_foreground_color(ax); for (graph = 0; graph < up->graphs; graph++) { mus_float_t samples_per_pixel; if ((pixel_len <= graph) || (!foreground_color_ok(Xen_list_ref(pixel_list, graph), ax))) { switch (graph) { case 0: break; case 1: set_foreground_color(ax, ss->red); break; case 2: set_foreground_color(ax, ss->green); break; case 3: set_foreground_color(ax, ss->light_blue); break; case 4: set_foreground_color(ax, ss->yellow); break; default: set_foreground_color(ax, ss->black); break; } } /* check for up->len[graph] > pixels available and use ymin ymax if needed */ samples_per_pixel = (mus_float_t)(up->len[graph]) / (mus_float_t)(uap->x_axis_x1 - uap->x_axis_x0); if (samples_per_pixel < 4.0) { mus_float_t start_x, xinc; int grf_len; grf_len = up->len[graph]; start_x = uap->x0; if (grf_len <= 1) xinc = 1.0; else xinc = (uap->x1 - uap->x0) / (mus_float_t)(grf_len - 1); for (i = 0, x = start_x; i < grf_len; i++, x += xinc) { y = up->data[graph][i]; set_grf_point(local_grf_x(x, uap), i, local_grf_y(y, uap)); if (cp->printing) ps_set_grf_point(x, i, y); } draw_grf_points(cp->dot_size, ax, grf_len, uap, 0.0, cp->lisp_graph_style); if (cp->printing) ps_draw_grf_points(uap, grf_len, 0.0, cp->lisp_graph_style, cp->dot_size); } else { int xi; mus_float_t ymin, ymax, pinc, xf; j = 0; i = 0; xf = 0.0; x = 0.0; pinc = samples_per_pixel / (mus_float_t)(up->len[graph]); xi = local_grf_x(0.0, uap); ymin = 32768.0; ymax = -32768.0; while (i < up->len[graph]) { y = up->data[graph][i]; if (y > ymax) ymax = y; if (y < ymin) ymin = y; xf += 1.0; i++; if (xf > samples_per_pixel) { set_grf_points(xi, j, local_grf_y(ymin, uap), local_grf_y(ymax, uap)); if (cp->printing) { x += pinc; ps_set_grf_points(x, j, ymin, ymax); } xi++; j++; xf -= samples_per_pixel; ymin = 32768.0; ymax = -32768.0; } } draw_both_grf_points(cp->dot_size, ax, j, cp->lisp_graph_style); if (cp->printing) ps_draw_both_grf_points(uap, j, cp->lisp_graph_style, cp->dot_size); } } if (up->graphs > 1) set_foreground_color(ax, old_color); if (sp->channel_style == CHANNELS_SUPERIMPOSED) { copy_context(cp); /* reset for axes etc */ if (cp->printing) ps_reset_color(); } } } static void make_axes(chan_info *cp, axis_info *ap, x_axis_style_t x_style, bool erase_first, with_grid_t grid, log_axis_t log_axes, show_axes_t axes) { snd_info *sp; color_t old_color = 0; /* make the compiler happy */ if (!(ap->ax)) ap->ax = cp->ax; sp = cp->sound; setup_graphics_context(cp, ap->ax); /* here is where the graph is cleared (see also make_partial_graph and make_wavogram) */ if (erase_first == CLEAR_GRAPH) erase_rectangle(cp, ap->ax, ap->graph_x0, ap->y_offset, ap->width, ap->height); if (ss->axis_color_set) { old_color = get_foreground_color(ap->ax); /* if axis color has been set, use it, else use data color from preceding make_graph call */ set_foreground_color(ap->ax, ss->axis_color); } make_axes_1(ap, x_style, snd_srate(sp), axes, cp->printing, (cp->show_axes != SHOW_NO_AXES) ? WITH_X_AXIS : NO_X_AXIS, /* C++ wants the with_x_axis_t result */ grid, log_axes, cp->grid_density); if (ss->axis_color_set) set_foreground_color(ap->ax, old_color); } static void draw_sonogram_cursor(chan_info *cp); static void draw_graph_cursor(chan_info *cp); static void show_smpte_label(chan_info *cp, graphics_context *ax); static void show_inset_graph(chan_info *cp, graphics_context *cur_ax); static void display_channel_data_with_size(chan_info *cp, int width, int height, int offset, bool just_fft, bool just_lisp, bool just_time, bool use_incoming_cr) { /* this procedure is unnecessarily confusing! */ snd_info *sp; bool with_fft = false, with_lisp = false, with_time = false; int displays = 0; bool grflsp = false; axis_info *ap = NULL; axis_info *fap = NULL; axis_info *uap = NULL; lisp_grf *up = NULL; sp = cp->sound; /* -------- graph-hook -------- */ if ((cp->hookable == WITH_HOOK) && (!(ss->graph_hook_active)) && (Xen_hook_has_list(graph_hook))) { Xen res; ss->graph_hook_active = true; res = run_progn_hook(graph_hook, Xen_list_4(C_int_to_Xen_sound(sp->index), C_int_to_Xen_integer(cp->chan), C_double_to_Xen_real(cp->axis->y0), C_double_to_Xen_real(cp->axis->y1)), S_graph_hook); /* (hook-push graph-hook (lambda (a b c d) (snd-print (format #f "~A ~A ~A ~A" a b c d)))) */ ss->graph_hook_active = false; if (Xen_is_true(res)) return; } ap = cp->axis; if (ap == NULL) return; /* -------- decide which graphs to draw -------- */ ap->height = height; ap->window_width = width; ap->width = width; ap->y_offset = offset; if (cp->graph_time_on) { displays++; with_time = true; } grflsp = ((cp->graph_lisp_on) || (Xen_hook_has_list(lisp_graph_hook))); if (grflsp) { displays++; up = cp->lisp_info; if (up == NULL) { /* this should only happen the first time such a graph is needed */ cp->lisp_info = (lisp_grf *)calloc(1, sizeof(lisp_grf)); up = cp->lisp_info; up->show_axes = cp->show_axes; up->axis = make_axis_info(cp, 0.0, 1.0, -1.0, 1.0, "dummy axis", 0.0, 1.0, -1.0, 1.0, NULL); } if (up) { uap = up->axis; if (uap) { with_lisp = true; uap->height = height; uap->y_offset = offset; uap->width = width; uap->window_width = width; } } } if (cp->graph_transform_on) { fft_info *fp; displays++; fp = cp->fft; if (fp) { fap = fp->axis; if (fap) { with_fft = true; fap->height = height; fap->y_offset = offset; fap->width = width; fap->window_width = width; } } } if (displays == 0) { clear_window(ap->ax); return; } /* -------- set graph positions and sizes -------- */ if (cp->graphs_horizontal) { if (with_time) ap->width = width / displays; if (with_fft) fap->width = width / displays; if (with_lisp) uap->width = width / displays; /* now the x axis offsets for fap and uap */ if (with_fft) { if (with_time) fap->graph_x0 = ap->width; else fap->graph_x0 = 0; } if (with_lisp) uap->graph_x0 = uap->width * (displays - 1); } else { height /= displays; if (with_time) ap->height = height; if (with_fft) fap->height = height; if (with_lisp) uap->height = height; /* now the y axis offsets for fap and uap */ if (with_fft) { if (with_time) fap->y_offset += height; fap->graph_x0 = 0; } if (with_lisp) { uap->y_offset += (height * (displays - 1)); uap->graph_x0 = 0; } } /* -------- time domain graph -------- */ if ((!just_fft) && (!just_lisp)) { marks_off(cp); channel_set_mix_tags_erased(cp); if (with_time) { int points; graphics_context *our_ax; #if USE_GTK our_ax = copy_context(cp); if ((!our_ax->w) || (!our_ax->wn)) { /* how can this happen? */ our_ax->w = channel_to_widget(cp); our_ax->wn = WIDGET_TO_WINDOW(our_ax->w); } if (!use_incoming_cr) ss->cr = make_cairo(our_ax->wn); cairo_push_group(ss->cr); #else our_ax = ap->ax; #endif if (cp->time_graph_type == GRAPH_AS_WAVOGRAM) { if (ap->y_axis_y0 == ap->y_axis_y1) make_axes(cp, ap, cp->x_axis_style, DONT_CLEAR_GRAPH, cp->show_grid, WITH_LINEAR_AXES, cp->show_axes); /* first time needs setup */ ap->y0 = ap->x0; ap->y1 = ap->y0 + (mus_float_t)(cp->wavo_trace * (ap->y_axis_y0 - ap->y_axis_y1)) / ((mus_float_t)(cp->wavo_hop) * snd_srate(sp)); ap->x1 = ap->x0 + (double)(cp->wavo_trace) / (double)snd_srate(sp); points = make_wavogram(cp); } else { make_axes(cp, ap, cp->x_axis_style, (((cp->chan == 0) || (sp->channel_style != CHANNELS_SUPERIMPOSED)) ? CLEAR_GRAPH : DONT_CLEAR_GRAPH), cp->show_grid, WITH_LINEAR_AXES, cp->show_axes); cp->cursor_visible = false; cp->selection_visible = false; #if (!USE_GTK) points = make_graph(cp); #endif if ((cp->chan == 0) || (sp->channel_style != CHANNELS_SUPERIMPOSED)) { display_selection(cp); copy_context(cp); } #if USE_GTK points = make_graph(cp); #endif if (cp->show_y_zero) display_y_zero(cp); if ((channel_has_active_mixes(cp))) display_channel_mixes(cp); #if USE_GTK copy_context(cp); #else our_ax = copy_context(cp); #endif if (with_inset_graph(ss)) show_inset_graph(cp, our_ax); if (with_smpte_label(ss)) show_smpte_label(cp, our_ax); } if ((sp->channel_style != CHANNELS_SUPERIMPOSED) && (height > 10)) display_channel_id(cp, our_ax, height + offset, sp->nchans); #if USE_GTK /* here in gtk3 we can get: * cairo-surface.c:385: _cairo_surface_begin_modification: Assertion `! surface->finished' failed. * followed by a segfault. * * But I've followed this thing in detail, and nothing unusual is happening. * If I check the surface status via * { * cairo_surface_t *surface; * surface = cairo_get_target(ss->cr); * fprintf(stderr, "status: %d ", cairo_surface_status(surface)); * } * if prints 0 (success), and then dies! I can't trace it in gdb because the goddamn gtk idle * mechanism gets confused. I can't ask cairo if the surface is finished. valgrind is happy. * cairo-trace shows nothing unusual. cairo 1.8.0 is happy. * I am stuck. */ cairo_pop_group_to_source(ss->cr); cairo_paint(ss->cr); if (!use_incoming_cr) { free_cairo(ss->cr); ss->cr = NULL; } #endif if (points == 0) return; /* the next two can be called outside this context, so they handle the cairo_t business themselves */ if ((cp->chan == 0) || (sp->channel_style != CHANNELS_SUPERIMPOSED)) display_channel_marks(cp); if (cp->cursor_on) draw_graph_cursor(cp); } } /* -------- fft graph -------- */ if ((with_fft) && (!just_lisp) && (!just_time)) { #if USE_GTK if (!use_incoming_cr) ss->cr = make_cairo(cp->ax->wn); cairo_push_group(ss->cr); #endif if ((!(with_gl(ss))) || (cp->transform_graph_type != GRAPH_AS_SPECTROGRAM) || (color_map(ss) == BLACK_AND_WHITE_COLORMAP) || ((sp->nchans > 1) && (sp->channel_style != CHANNELS_SEPARATE))) make_axes(cp, fap, X_AXIS_IN_SECONDS, /* x-axis-style only affects the time domain graph */ (((cp->chan == 0) || (sp->channel_style != CHANNELS_SUPERIMPOSED)) ? CLEAR_GRAPH : DONT_CLEAR_GRAPH), ((cp->show_grid) && (cp->transform_graph_type != GRAPH_AS_SPECTROGRAM)) ? WITH_GRID : NO_GRID, (!(cp->fft_log_frequency)) ? WITH_LINEAR_AXES : ((cp->transform_graph_type == GRAPH_AS_SONOGRAM) ? WITH_LOG_Y_AXIS : WITH_LOG_X_AXIS), cp->show_axes); if ((!with_time) || (just_fft)) { /* make_graph does this -- sets losamp needed by fft to find its starting point */ ap->losamp = (mus_long_t)(ap->x0 * (double)snd_srate(sp)); ap->hisamp = (mus_long_t)(ap->x1 * (double)snd_srate(sp)); } switch (cp->transform_graph_type) { case GRAPH_ONCE: make_fft_graph(cp, cp->fft->axis, (sp->channel_style == CHANNELS_SUPERIMPOSED) ? combined_context(cp) : copy_context(cp), cp->hookable); break; case GRAPH_AS_SONOGRAM: make_sonogram(cp); break; case GRAPH_AS_WAVOGRAM: break; case GRAPH_AS_SPECTROGRAM: #if HAVE_GL if (make_spectrogram(cp)) glDrawBuffer(GL_BACK); #else make_spectrogram(cp); #endif break; } #if USE_GTK cairo_pop_group_to_source(ss->cr); cairo_paint(ss->cr); if (!use_incoming_cr) { free_cairo(ss->cr); ss->cr = NULL; } #endif /* this cairo_t can't be maintained across the fft functions -- they can be * work procs that return (displaying) at any time in the future, and * call check_for_event so that they can be interrupted. */ if (cp->cursor_on) { cp->fft_cursor_visible = false; draw_sonogram_cursor(cp); } } /* -------- "lisp" (extlang) graph -------- */ if ((with_lisp) && (!just_fft) && (!just_time)) { int pixel_loc = -1; Xen pixel_list = Xen_false; if ((just_lisp) || ((!with_time) && (!(with_fft)))) { ap->losamp = (mus_long_t)(ap->x0 * (double)snd_srate(sp)); ap->hisamp = (mus_long_t)(ap->x1 * (double)snd_srate(sp)); } if ((cp->hookable == WITH_HOOK) && (!(ss->lisp_graph_hook_active)) && (Xen_hook_has_list(lisp_graph_hook))) { ss->lisp_graph_hook_active = true; /* inadvertent recursive call here can hang entire computer */ pixel_list = run_progn_hook(lisp_graph_hook, Xen_list_2(C_int_to_Xen_sound(cp->sound->index), C_int_to_Xen_integer(cp->chan)), S_lisp_graph_hook); ss->lisp_graph_hook_active = false; if (!(Xen_is_false(pixel_list))) pixel_loc = snd_protect(pixel_list); } if (up != cp->lisp_info) up = cp->lisp_info; if (uap != up->axis) uap = up->axis; /* if these were changed in the hook function, the old fields should have been saved across the change (g_graph below) */ #if USE_GTK if (!(uap->ax)) uap->ax = cp->ax; if (!use_incoming_cr) ss->cr = make_cairo(uap->ax->wn); cairo_push_group(ss->cr); #endif make_axes(cp, uap, /* defined in this file l 2293 */ X_AXIS_IN_SECONDS, (((cp->chan == 0) || (sp->channel_style != CHANNELS_SUPERIMPOSED)) ? CLEAR_GRAPH : DONT_CLEAR_GRAPH), cp->show_grid, WITH_LINEAR_AXES, up->show_axes); if (!(Xen_is_procedure(pixel_list))) make_lisp_graph(cp, pixel_list); /* this uses the cairo_t set up above, but possible pixel_list proc does not */ #if USE_GTK cairo_pop_group_to_source(ss->cr); cairo_paint(ss->cr); if (!use_incoming_cr) { free_cairo(ss->cr); ss->cr = NULL; } #endif if (Xen_is_procedure(pixel_list)) Xen_call_with_no_args(pixel_list, S_lisp_graph); if (!(Xen_is_false(pixel_list))) snd_unprotect_at(pixel_loc); if ((cp->hookable == WITH_HOOK) && (Xen_hook_has_list(after_lisp_graph_hook))) run_hook(after_lisp_graph_hook, Xen_list_2(C_int_to_Xen_sound(cp->sound->index), C_int_to_Xen_integer(cp->chan)), S_after_lisp_graph_hook); } if ((!just_lisp) && (!just_fft)) run_after_graph_hook(cp); } static void display_channel_data_1(chan_info *cp, bool just_fft, bool just_lisp, bool just_time, bool use_incoming_cr) { snd_info *sp; int width, height; sp = cp->sound; if ((sp->inuse == SOUND_IDLE) || (cp->active < CHANNEL_HAS_AXES) || (!(sp->active)) || (!(channel_graph_is_visible(cp)))) return; if ((sp->channel_style == CHANNELS_SEPARATE) || (sp->nchans == 1)) { width = widget_width(channel_graph(cp)); height = widget_height(channel_graph(cp)); if ((height > 5) && (width > 5)) display_channel_data_with_size(cp, width, height, 0, just_fft, just_lisp, just_time, use_incoming_cr); } else { /* all chans in one graph widget, sy->scroll entire set, zy->zoom entire set etc */ /* updates are asynchronous (dependent on background ffts etc), so we can't do the whole window at once */ /* complication here is that we're growing down from the top, causing endless confusion */ #if USE_GTK width = widget_width(channel_graph(sp->chans[0])); /* don't fixup for gsy width -- those sliders are in different table slots */ #else width = widget_width(channel_graph(sp->chans[0])) - (2 * ss->position_slider_width); #endif if (width <= 0) return; height = widget_height(channel_graph(sp->chans[0])); cp->height = height; if (sp->channel_style == CHANNELS_SUPERIMPOSED) display_channel_data_with_size(cp, width, height, 0, just_fft, just_lisp, just_time, use_incoming_cr); else { int offset, full_height, y0, y1, bottom, top; mus_float_t val, size, chan_height; /* CHANNELS_COMBINED case */ val = gsy_value(sp->chans[0]); size = gsy_size(sp->chans[0]); full_height = (int)((mus_float_t)height / size); chan_height = (mus_float_t)full_height / (mus_float_t)(sp->nchans); bottom = (int)(full_height * val); top = (int)(full_height * (val + size)); y1 = (int)((sp->nchans - cp->chan) * chan_height); y0 = y1 - (int)chan_height; offset = top - y1; if ((cp->chan == 0) && (offset > 0)) { /* round off trouble can lead to garbage collecting at the top of the window (similarly at the bottom I suppose) */ chan_height += offset; offset = 0; } #if USE_GTK /* this only needed because Gtk signal blocking is screwed up */ if ((cp->chan > 0) && (channel_has_active_mixes(cp)) && (cp->axis->height != height)) channel_set_mix_tags_erased(cp); #endif if ((cp->chan == (sp->nchans - 1)) && ((offset + chan_height) < height)) chan_height = height - offset; if (((y0 < top) && (y0 >= bottom)) || ((y1 > bottom) && (y1 <= top))) display_channel_data_with_size(cp, width, (int)chan_height, offset, just_fft, just_lisp, just_time, use_incoming_cr); else { axis_info *ap; ap = cp->axis; ap->y_offset = offset; /* needed for mouse click channel determination */ } } } } void display_channel_fft_data(chan_info *cp) { display_channel_data_1(cp, true, false, false, false); } static void display_channel_lisp_data(chan_info *cp) { display_channel_data_1(cp, false, true, false, false); } void display_channel_time_data(chan_info *cp) { display_channel_data_1(cp, false, false, true, false); } void display_channel_data(chan_info *cp) { display_channel_data_1(cp, false, false, false, false); } void display_channel_data_for_print(chan_info *cp) { display_channel_data_1(cp, false, false, false, true); } /* ---------------- CHANNEL CURSOR ---------------- */ static void erase_cursor(chan_info *cp) { #if USE_MOTIF draw_cursor(cp); #endif } static void draw_graph_cursor(chan_info *cp) { axis_info *ap; ap = cp->axis; if ((cursor_sample(cp) < ap->losamp) || (cursor_sample(cp) > ap->hisamp) || (!(ap->ax))) return; if ((cp->chan > 0) && (cp->sound->channel_style == CHANNELS_SUPERIMPOSED)) return; #if USE_GTK if (!(ap->ax->wn)) return; ss->cr = make_cairo(ap->ax->wn); #endif if (cp->cursor_visible) erase_cursor(cp); cp->cx = local_grf_x((double)(cursor_sample(cp)) / (double)snd_srate(cp->sound), ap); /* not float -- this matters in very long files (i.e. > 40 minutes) */ if (cp->just_zero) { cp->cy = local_grf_y(0.0, ap); /* cp->old_cy = local_grf_y(chn_sample(cursor_sample(cp), cp, cp->edit_ctr), ap); */ } else cp->cy = local_grf_y(chn_sample(cursor_sample(cp), cp, cp->edit_ctr), ap); draw_cursor(cp); cp->cursor_visible = true; #if USE_GTK free_cairo(ss->cr); ss->cr = NULL; #endif } static void draw_sonogram_cursor_1(chan_info *cp) { axis_info *fap; graphics_context *fax; fap = cp->fft->axis; fax = cursor_context(cp); if ((fap) && (fax)) #if (!USE_GTK) draw_line(fax, cp->fft_cx, fap->y_axis_y0, cp->fft_cx, fap->y_axis_y1); #else { color_t old_color; fax = cp->ax; /* fap->ax does not work here?!? */ ss->cr = make_cairo(fax->wn); /* y_axis_y0 > y_axis_y1 (upside down coordinates) */ old_color = get_foreground_color(fax); set_foreground_color(fax, ss->cursor_color); draw_line(fax, cp->fft_cx, fap->y_axis_y0 - 1, cp->fft_cx, fap->y_axis_y1); set_foreground_color(fax, old_color); cp->fft_cursor_visible = (!(cp->fft_cursor_visible)); free_cairo(ss->cr); ss->cr = NULL; } #endif } static void draw_sonogram_cursor(chan_info *cp) { if ((cp->graph_transform_on) && (cp->show_sonogram_cursor) && (cp->fft) && (cp->fft->axis) && (cp->transform_graph_type == GRAPH_AS_SONOGRAM)) { if (cp->fft_cursor_visible) draw_sonogram_cursor_1(cp); cp->fft_cx = local_grf_x((double)(cursor_sample(cp)) / (double)snd_srate(cp->sound), cp->fft->axis); draw_sonogram_cursor_1(cp); cp->fft_cursor_visible = true; } } kbd_cursor_t cursor_decision(chan_info *cp) { mus_long_t len; len = current_samples(cp); if (cursor_sample(cp) >= len) cursor_sample(cp) = len - 1; /* zero based, but in 0-length files, len = 0 */ if (cursor_sample(cp) < 0) cursor_sample(cp) = 0; /* perhaps the cursor should be forced off in empty files? */ if (cursor_sample(cp) < cp->axis->losamp) { if (cursor_sample(cp) == 0) return(CURSOR_ON_LEFT); else { if (cp->sound->playing) return(CURSOR_ON_RIGHT); return(CURSOR_IN_MIDDLE); } } if (cursor_sample(cp) > cp->axis->hisamp) { if (cursor_sample(cp) >= (len - 1)) return(CURSOR_ON_RIGHT); else { if (cp->sound->playing) return(CURSOR_ON_LEFT); return(CURSOR_IN_MIDDLE); } } return(CURSOR_IN_VIEW); } void handle_cursor(chan_info *cp, kbd_cursor_t redisplay) { /* no sync here */ if (cp == NULL) return; if (redisplay != KEYBOARD_NO_ACTION) { snd_info *sp; sp = cp->sound; if (cp->with_verbose_cursor) show_cursor_info(cp); if (redisplay != CURSOR_IN_VIEW) { double gx = 0.0; axis_info *ap; ap = cp->axis; switch (redisplay) { case CURSOR_ON_LEFT: gx = (double)(cursor_sample(cp)) / (double)snd_srate(sp); break; case CURSOR_ON_RIGHT: gx = (double)(cursor_sample(cp)) / (double)snd_srate(sp) - ap->zx * ap->x_ambit; break; case CURSOR_IN_MIDDLE: gx = (double)(cursor_sample(cp)) / (double)snd_srate(sp) - ap->zx * 0.5 * ap->x_ambit; break; default: break; } if (gx < 0.0) gx = 0.0; if (ap->x_ambit != 0.0) reset_x_display(cp, (gx - ap->xmin) / ap->x_ambit, ap->zx); } else { if (cp->cursor_on) { #if USE_MOTIF draw_graph_cursor(cp); draw_sonogram_cursor(cp); if (!(sp->playing)) update_graph(cp); #endif #if USE_GTK update_graph(cp); #endif } } } { /* not sure about this */ int i; for (i = 0; i < cp->edit_size; i++) if (cp->edits[i]) cp->edits[i]->cursor = cursor_sample(cp); } update_possible_selection_in_progress(cursor_sample(cp)); } void handle_cursor_with_sync(chan_info *cp, kbd_cursor_t redisplay) { snd_info *sp; sp = cp->sound; if ((sp) && (sp->sync != 0)) { int i; sync_info *si; si = snd_sync(sp->sync); for (i = 0; i < si->chans; i++) handle_cursor(si->cps[i], redisplay); si = free_sync_info(si); } else handle_cursor(cp, redisplay); } void cursor_moveto(chan_info *cp, mus_long_t samp) { snd_info *sp; sp = cp->sound; if ((sp) && (sp->sync != 0)) { int i; sync_info *si; si = snd_sync(sp->sync); for (i = 0; i < si->chans; i++) { chan_info *ncp; ncp = si->cps[i]; cursor_sample(ncp) = samp; handle_cursor(ncp, cursor_decision(ncp)); /* checks len */ } si = free_sync_info(si); } else { cursor_sample(cp) = samp; handle_cursor(cp, cursor_decision(cp)); } } void cursor_move(chan_info *cp, mus_long_t samps) { cursor_moveto(cp, cursor_sample(cp) + samps); } void cursor_moveto_without_verbosity(chan_info *cp, mus_long_t samp) { bool old_verbose; int old_sync; old_verbose = cp->with_verbose_cursor; old_sync = cp->sound->sync; cp->with_verbose_cursor = false; cp->sound->sync = 0; cursor_moveto(cp, samp); cp->with_verbose_cursor = old_verbose; cp->sound->sync = old_sync; } void cursor_moveto_with_window(chan_info *cp, mus_long_t samp, mus_long_t left_samp, mus_long_t window_size) { /* restore old window and cursor as much as possible */ double gx; snd_info *sp; mus_long_t current_window_size; axis_info *ap; sp = cp->sound; ap = cp->axis; if (cp->cursor_visible) { if (cp->graph_time_on) { #if USE_GTK ss->cr = make_cairo(ap->ax->wn); #endif erase_cursor(cp); #if USE_GTK free_cairo(ss->cr); ss->cr = NULL; #endif } cp->cursor_visible = false; /* don't redraw at old location */ } if (cp->fft_cursor_visible) { if ((cp->fft) && (cp->graph_transform_on)) draw_sonogram_cursor_1(cp); cp->fft_cursor_visible = false; /* don't redraw at old location */ } cursor_sample(cp) = samp; current_window_size = ap->hisamp - ap->losamp; if (snd_abs_mus_long_t(current_window_size - window_size) < (mus_long_t)(0.1 * (double)window_size)) gx = (double)(left_samp) / (double)snd_srate(sp); else gx = (double)(samp) / (double)snd_srate(sp) - ap->zx * 0.5 * ap->x_ambit; if (gx < 0.0) gx = 0.0; if (ap->x_ambit != 0.0) reset_x_display(cp, (gx - ap->xmin) / ap->x_ambit, ap->zx); } void sync_cursors(chan_info *cp, mus_long_t samp) { snd_info *sp; sp = cp->sound; if ((sp) && (sp->sync != 0)) { int i; sync_info *si; si = snd_sync(sp->sync); for (i = 0; i < si->chans; i++) cursor_sample(si->cps[i]) = samp; si = free_sync_info(si); } else cursor_sample(cp) = samp; } void show_cursor_info(chan_info *cp) { char *expr_str; snd_info *sp; mus_float_t y, absy; int digits, i, len; mus_long_t samp; char *s1, *s2; sp = cp->sound; if ((sp->sync != 0) && (cp->chan != 0)) return; samp = cursor_sample(cp); y = chn_sample(samp, cp, cp->edit_ctr); absy = fabs(y); if (absy < .0001) digits = 5; else if (absy<.01) digits = 4; else if (absy<1.0) digits = 3; else digits = 2; len = PRINT_BUFFER_SIZE; expr_str = (char *)calloc(len, sizeof(char)); if (sp->nchans == 1) snprintf(expr_str, PRINT_BUFFER_SIZE, "cursor at %s (sample %lld) = %s", s1 = x_axis_location_to_string(cp, (double)samp / (double)snd_srate(sp)), samp, s2 = prettyf(y, digits)); else { if (sp->sync == 0) snprintf(expr_str, PRINT_BUFFER_SIZE, "chan %d, cursor at %s (sample %lld) = %s", cp->chan + 1, s1 = x_axis_location_to_string(cp, (double)samp / (double)snd_srate(sp)), samp, s2 = prettyf(y, digits)); else { /* in this case, assume we show all on chan 0 and ignore the call otherwise (see above) */ /* "cursor at..." then list of values */ snprintf(expr_str, PRINT_BUFFER_SIZE, "cursor at %s (sample %lld): %s", s1 = x_axis_location_to_string(cp, (double)samp / (double)snd_srate(sp)), samp, s2 = prettyf(y, digits)); for (i = 1; i < sp->nchans; i++) { chan_info *ncp; expr_str = mus_strcat(expr_str, ", ", &len); free(s2); ncp = sp->chans[i]; y = chn_sample(samp, ncp, ncp->edit_ctr); absy = fabs(y); if (absy < .0001) digits = 5; else if (absy<.01) digits = 4; else if (absy<1.0) digits = 3; else digits = 2; s2 = prettyf(y, digits); expr_str = mus_strcat(expr_str, s2, &len); } } } set_status(sp, expr_str, false); free(expr_str); free(s1); free(s2); } void goto_graph(chan_info *cp) { if ((cp) && (!(cp->squelch_update))) { snd_info *sp; sp = cp->sound; if ((cp->chan == 0) || (sp->channel_style == CHANNELS_SEPARATE)) goto_window(channel_graph(cp)); else goto_window(channel_graph(sp->chans[0])); } } /* ---------------- graphics callbacks ---------------- */ #define HIT_SLOP 4 static bool hit_cursor_triangle(chan_info *cp, int x, int y) { axis_info *ap; mus_long_t samp; int cx; ap = cp->axis; samp = cursor_sample(cp); if ((samp < ap->losamp) || (samp > ap->hisamp)) return(false); cx = grf_x((double)samp / (double)snd_srate(cp->sound), ap); if ((cx > (x + HIT_SLOP)) || ((cx + play_arrow_size(ss) + HIT_SLOP) < x)) return(false); y = y - ap->y_axis_y0 - play_arrow_size(ss); if (y < 0) y = -y; return((cx + play_arrow_size(ss) - y + HIT_SLOP) >= x); } #define SLOPPY_MOUSE 6 #if USE_NO_GUI #define GUI_SET_CURSOR(w, cursor) #else #if USE_GTK #define GUI_SET_CURSOR(w, cursor) gdk_window_set_cursor(WIDGET_TO_WINDOW(w), cursor) #else #define GUI_SET_CURSOR(w, cursor) XUndefineCursor(XtDisplay(w), XtWindow(w)); XDefineCursor(XtDisplay(w), XtWindow(w), cursor) #endif #endif typedef enum {CLICK_NOGRAPH, CLICK_WAVE, CLICK_FFT_AXIS, CLICK_LISP, CLICK_MIX, CLICK_MARK, CLICK_FFT_MAIN, CLICK_SELECTION_LEFT, CLICK_SELECTION_RIGHT, CLICK_SELECTION_PLAY, CLICK_INSET_GRAPH, CLICK_MIX_PLAY, CLICK_CURSOR_PLAY, CLICK_MARK_PLAY, CLICK_SELECTION_LOOP_PLAY, CLICK_SELECTION_MAIN, CLICK_FFT_AUX} click_loc_t; typedef struct inset_graph_info_t { /* chan_info field is inset_graph, set to null in snd-data, but not cleared or freed */ int width, height, edpos, y_offset, data_size, x0, x1, y0, y1; point_t *data0, *data1; bool graphing; double maxamp; } inset_graph_info_t; static int mix_tag = NO_MIX_TAG, mix_play_tag = NO_MIX_TAG; static mark *play_mark = NULL; static mark *mouse_mark = NULL; static click_loc_t within_graph(chan_info *cp, int x, int y) { int x0, x1, y0, y1; axis_info *ap; #define SELECTION_DRAG_HEIGHT 50 x0 = x - SLOPPY_MOUSE; x1 = x + SLOPPY_MOUSE; y0 = y - SLOPPY_MOUSE; y1 = y + SLOPPY_MOUSE; if (cp->graph_time_on) { ap = cp->axis; /* does (x, y) fall within the current axis bounds x_axis_x0|x1, y_axis_y0|y1 */ if (((x0 <= ap->x_axis_x1) && (x1 >= ap->x_axis_x0)) && ((y0 <= ap->y_axis_y0) && (y1 >= ap->y_axis_y1))) { /* here we are inside the graph (within the axes) * we need to check for marks and whatnot before the selection, else there's no way * to drag a mark that's within the selection. */ if ((with_inset_graph(ss)) && (cp->inset_graph) && (cp->inset_graph->graphing) && (x1 > cp->inset_graph->x0) && (x0 < cp->inset_graph->x1) && (y1 > cp->inset_graph->y0) && (y0 < cp->inset_graph->y1)) return(CLICK_INSET_GRAPH); mix_tag = hit_mix(cp, x, y); if (mix_tag != NO_MIX_TAG) return(CLICK_MIX); mix_play_tag = hit_mix_triangle(cp, x, y); if (mix_play_tag != NO_MIX_TAG) return(CLICK_MIX_PLAY); mouse_mark = hit_mark(cp, x, y); if (mouse_mark != NULL) return(CLICK_MARK); if (selection_is_active_in_channel(cp)) { mus_long_t bpos, epos, xpos; double sr; sr = (double)snd_srate(cp->sound); bpos = selection_beg(cp); epos = selection_end(cp); if ((y < (ap->y_offset + SELECTION_DRAG_HEIGHT)) || (y > (ap->y_axis_y0 - SELECTION_DRAG_HEIGHT))) { /* look for click at selection boundary */ if ((bpos >= ap->losamp) && (bpos <= ap->hisamp)) { mus_long_t x0_pos, x1_pos; x0_pos = snd_round_mus_long_t(ungrf_x(cp->axis, x0) * sr); x1_pos = snd_round_mus_long_t(ungrf_x(cp->axis, x1) * sr); if ((bpos > x0_pos) && (bpos < x1_pos)) return(CLICK_SELECTION_LEFT); /* "click" is a misnomer -- we have moved to the portion where we can grab the selection and resize it */ } if ((epos >= ap->losamp) && (epos <= ap->hisamp)) { mus_long_t x0_pos, x1_pos; x0_pos = snd_round_mus_long_t(ungrf_x(cp->axis, x0) * sr); x1_pos = snd_round_mus_long_t(ungrf_x(cp->axis, x1) * sr); if ((epos > x0_pos) && (epos < x1_pos)) return(CLICK_SELECTION_RIGHT); } } xpos = snd_round_mus_long_t(ungrf_x(cp->axis, x) * sr); /* a sample number */ if ((bpos <= xpos) && (epos >= xpos)) return(CLICK_SELECTION_MAIN); } return(CLICK_WAVE); } /* possibly in time graph but outside axes */ if (selection_is_active_in_channel(cp)) { if (hit_selection_triangle(cp, x, y)) return(CLICK_SELECTION_PLAY); if (hit_selection_loop_triangle(cp, x, y)) return(CLICK_SELECTION_LOOP_PLAY); } play_mark = hit_mark_triangle(cp, x, y); if (play_mark != NULL) return(CLICK_MARK_PLAY); if (hit_cursor_triangle(cp, x, y)) return(CLICK_CURSOR_PLAY); } if (((cp->graph_lisp_on) || (Xen_hook_has_list(lisp_graph_hook))) && (cp->lisp_info)) { ap = cp->lisp_info->axis; if (((x0 <= ap->x_axis_x1) && (x1 >= ap->x_axis_x0)) && ((y0 <= ap->y_axis_y0) && (y1 >= ap->y_axis_y1))) return(CLICK_LISP); } if ((cp->graph_transform_on) && (cp->fft)) { ap = cp->fft->axis; if (!ap) return(CLICK_NOGRAPH); /* apparently can happen if fft is being redrawn when we click */ /* look first for on-axis (axis drag) mouse */ #if HAVE_GL if ((cp->transform_graph_type == GRAPH_AS_SPECTROGRAM) && (ap->used_gl)) { GLdouble xx; xx = unproject_to_x(x, y); if ((xx > -0.7) && (xx < -0.49)) return(CLICK_FFT_AXIS); } #endif if (cp->transform_graph_type != GRAPH_AS_SONOGRAM) { if (((x >= ap->x_axis_x0) && (x <= ap->x_axis_x1)) && ((y0 <= ap->y_axis_y0) && (y1 >= ap->y_axis_y0))) return(CLICK_FFT_AXIS); } else { if (((x0 <= ap->x_axis_x0) && (x1 >= ap->x_axis_x0)) && ((y <= ap->y_axis_y0) && (y >= ap->y_axis_y1))) return(CLICK_FFT_AXIS); } /* now check within fft graph */ if ((x0 <= ap->x_axis_x1) && (x1 >= ap->x_axis_x0)) { if ((y0 <= ap->y_axis_y0) && (y1 >= ap->y_axis_y1)) return(CLICK_FFT_MAIN); return(CLICK_FFT_AUX); } } return(CLICK_NOGRAPH); } void check_cursor_shape(chan_info *cp, int x, int y) { chan_info *ncp; if ((!cp) || (!cp->sound) || (cp->active == CHANNEL_INACTIVE) || (cp->squelch_update)) return; if (cp->sound->channel_style == CHANNELS_COMBINED) ncp = which_channel(cp->sound, y); else ncp = cp; switch (within_graph(ncp, x, y)) { case CLICK_SELECTION_LEFT: case CLICK_SELECTION_RIGHT: case CLICK_MIX: case CLICK_MARK: if (cp->current_cursor != ss->bounds_cursor) { cp->current_cursor = ss->bounds_cursor; GUI_SET_CURSOR(channel_graph(cp), ss->bounds_cursor); } break; case CLICK_FFT_AXIS: /* these all involve a drag if the mouse is pressed * but for fft axis, if sonogram, we want an up-and-down arrow, not left-to-right */ if (cp->transform_graph_type != GRAPH_AS_SONOGRAM) { if (cp->current_cursor != ss->bounds_cursor) { cp->current_cursor = ss->bounds_cursor; GUI_SET_CURSOR(channel_graph(cp), ss->bounds_cursor); } } else { if (cp->current_cursor != ss->yaxis_cursor) { cp->current_cursor = ss->yaxis_cursor; GUI_SET_CURSOR(channel_graph(cp), ss->yaxis_cursor); } } break; case CLICK_MIX_PLAY: case CLICK_SELECTION_PLAY: case CLICK_CURSOR_PLAY: case CLICK_MARK_PLAY: if (!(cp->sound->playing) && (cp->current_cursor != ss->play_cursor)) { snd_info *sp; sp = cp->sound; if (sp->sync != 0) { int i; sync_info *si; si = snd_sync(sp->sync); for (i = 0; i < si->chans; i++) si->cps[i]->original_cursor = cursor_sample(ncp); } else ncp->original_cursor = cursor_sample(ncp); cp->current_cursor = ss->play_cursor; GUI_SET_CURSOR(channel_graph(cp), ss->play_cursor); } break; case CLICK_SELECTION_LOOP_PLAY: if (cp->current_cursor != ss->loop_play_cursor) { cp->current_cursor = ss->loop_play_cursor; GUI_SET_CURSOR(channel_graph(cp), ss->loop_play_cursor); } break; default: if (cp->current_cursor != ss->graph_cursor) { cp->current_cursor = ss->graph_cursor; GUI_SET_CURSOR(channel_graph(cp), ss->graph_cursor); } break; } } static char *describe_fft_point(chan_info *cp, int x, int y) { mus_float_t xf, yf; axis_info *ap; fft_info *fp; sono_info *si; int ind, time, digits = 3; fp = cp->fft; ap = fp->axis; if ((ap->x_axis_x1 == ap->x_axis_x0) || (ap->y_axis_y1 == ap->y_axis_y0)) return(mus_strdup("?")); x = mus_iclamp(ap->x_axis_x0, x, ap->x_axis_x1); xf = ap->x0 + (ap->x1 - ap->x0) * (mus_float_t)(x - ap->x_axis_x0) / (mus_float_t)(ap->x_axis_x1 - ap->x_axis_x0); digits = (int)ceil(fabs(cp->min_dB) / 20); if (digits < 2) digits = 2; if (cp->transform_graph_type == GRAPH_ONCE) { if (cp->transform_type == FOURIER) { if (cp->fft_log_frequency) { mus_float_t minlx = 0.0; if (ap->x0 > 1.0) minlx = log(ap->x0); else minlx = 0.0; xf = exp(minlx + ((xf - ap->x0) * (log(ap->x1) - minlx) / (ap->x1 - ap->x0))); ind = (int)((fp->current_size * xf) / (mus_float_t)snd_srate(cp->sound)); } else ind = (int)((fp->current_size * xf) / (mus_float_t)snd_srate(cp->sound)); } else ind = (int)xf; if (ind >= fp->current_size) ind = fp->current_size - 1; if ((cp->fft_with_phases) && (fp->phases) && (cp->transform_type == FOURIER)) return(mus_format("(%.1f Hz: %.*f%s, %.*f radians (unscaled: %.*f)", xf, digits, (cp->fft_log_magnitude) ? in_dB(cp->min_dB, cp->lin_dB, (fp->data[ind] * fp->scale)) : (fp->data[ind] * fp->scale), (cp->fft_log_magnitude) ? "dB" : "", digits, fp->phases[ind], digits, fp->data[ind])); else return(mus_format("(%.1f%s: %.*f%s (unscaled: %.*f)", xf, ((cp->transform_type == AUTOCORRELATION) ? " samps" : " Hz"), digits, (cp->fft_log_magnitude) ? in_dB(cp->min_dB, cp->lin_dB, (fp->data[ind] * fp->scale)) : (fp->data[ind] * fp->scale), (cp->fft_log_magnitude) ? "dB" : "", digits, fp->data[ind])); } else { if (cp->transform_graph_type == GRAPH_AS_SONOGRAM) { y = mus_iclamp(ap->y_axis_y1, y, ap->y_axis_y0); yf = ap->y0 + (ap->y1 - ap->y0) * (mus_float_t)(y - ap->y_axis_y0) / (mus_float_t)(ap->y_axis_y1 - ap->y_axis_y0); si = cp->sonogram_data; if (cp->transform_type == FOURIER) { if (cp->fft_log_frequency) { mus_float_t minlx = 0.0; if (ap->y0 > 1.0) minlx = log(ap->y0); else minlx = 0.0; yf = exp(minlx + ((yf - ap->y0) * (log(ap->y1) - minlx) / (ap->y1 - ap->y0))); ind = (int)((fp->current_size * yf) / (mus_float_t)snd_srate(cp->sound)); } else ind = (int)((fp->current_size * yf) / (mus_float_t)snd_srate(cp->sound)); } else ind = (int)yf; if (ind >= si->total_bins) ind = si->total_bins - 1; time = (int)(si->target_slices * (mus_float_t)(x - ap->x_axis_x0) / (mus_float_t)(ap->x_axis_x1 - ap->x_axis_x0)); if (time >= si->total_slices) time = si->total_slices - 1; return(mus_format("(time: %.2f, freq: %.1f, val: %.*f%s (raw: %.*f))", xf, yf, digits, (cp->fft_log_magnitude) ? in_dB(cp->min_dB, cp->lin_dB, si->data[time][ind] / si->scale) : (si->data[time][ind] / si->scale), (cp->fft_log_magnitude) ? "dB" : "", digits, si->data[time][ind])); } } return(mus_strdup("?")); } void fftb(chan_info *cp, bool on) { cp->graph_transform_on = on; set_toggle_button(channel_f(cp), on, false, (void *)cp); calculate_fft(cp); } void waveb(chan_info *cp, bool on) { cp->graph_time_on = on; set_toggle_button(channel_w(cp), on, false, (void *)cp); update_graph_or_warn(cp); } static void propagate_wf_state(snd_info *sp) { int i; bool w, f; chan_info *cp; cp = sp->chans[0]; w = cp->graph_time_on; f = cp->graph_transform_on; for (i = 1; i < sp->nchans; i++) { cp = sp->chans[i]; cp->graph_time_on = w; cp->graph_transform_on = f; set_toggle_button(channel_f(cp), f, false, (void *)cp); set_toggle_button(channel_w(cp), w, false, (void *)cp); } for_each_sound_chan(sp, update_graph_or_warn); } void f_button_callback(chan_info *cp, bool on, bool with_control) { snd_info *sp; cp->graph_transform_on = on; sp = cp->sound; if (sp->channel_style != CHANNELS_SEPARATE) propagate_wf_state(sp); else { update_graph_or_warn(cp); if (with_control) { int i; for (i = 0; i < sp->nchans; i++) { chan_info *ncp; ncp = sp->chans[i]; if (cp != ncp) { ncp->graph_transform_on = on; #if USE_GTK set_toggle_button(channel_f(ncp), on, true, (void *)cp); #else set_toggle_button(channel_f(ncp), on, false, (void *)cp); #endif update_graph_or_warn(ncp); } } } goto_graph(cp); } } void w_button_callback(chan_info *cp, bool on, bool with_control) { snd_info *sp; cp->graph_time_on = on; sp = cp->sound; if (sp->channel_style != CHANNELS_SEPARATE) propagate_wf_state(sp); else { update_graph_or_warn(cp); if (with_control) { int i; for (i = 0; i < sp->nchans; i++) { chan_info *ncp; ncp = sp->chans[i]; if (cp != ncp) { ncp->graph_time_on = on; #if USE_GTK set_toggle_button(channel_w(ncp), on, true, (void *)cp); #else set_toggle_button(channel_w(ncp), on, false, (void *)cp); #endif update_graph_or_warn(ncp); } } } goto_graph(cp); } } void key_press_callback(chan_info *ncp, int x, int y, int key_state, int keysym) { /* called by every key-intercepting widget in the entire sound pane */ chan_info *cp; snd_info *sp; if (!ncp) return; cp = virtual_selected_channel(ncp); sp = cp->sound; select_channel(sp, cp->chan); if (((cp->graph_lisp_on) || (Xen_hook_has_list(lisp_graph_hook))) && (within_graph(cp, x, y) == CLICK_LISP) && (Xen_hook_has_list(key_press_hook))) { Xen res; res = run_or_hook(key_press_hook, Xen_list_4(C_int_to_Xen_sound(sp->index), C_int_to_Xen_integer(cp->chan), C_int_to_Xen_integer(keysym), C_int_to_Xen_integer(key_state)), /* this can have NumLock etc -- will be masked off in keyboard_command */ S_key_press_hook); if (Xen_is_true(res)) return; } keyboard_command(cp, keysym, key_state); /* if lisp graph has cursor? */ } chan_info *which_channel(snd_info *sp, int y) { int i; chan_info *ncp = NULL; if (y <= 0) /* this can happen if we drag the mouse over the top of the Snd window, then release it */ return(sp->chans[0]); for (i = 0; i < sp->nchans; i++) { axis_info *ap; chan_info *cp; cp = sp->chans[i]; ap = cp->axis; if (y < ap->y_offset) { if (ncp) return(ncp); else return(cp); } ncp = cp; } return(ncp); } static mus_float_t fft_axis_extent(chan_info *cp) { axis_info *ap; ap = cp->fft->axis; if (cp->transform_graph_type != GRAPH_AS_SONOGRAM) return((mus_float_t)(ap->x_axis_x1 - ap->x_axis_x0)); else return((mus_float_t)(ap->y_axis_y0 - ap->y_axis_y1)); } static void calculate_syncd_fft(chan_info *cp, int value) { if (cp->sound->sync == value) calculate_fft(cp); } static bool dragged = false; static oclock_t mouse_down_time; static click_loc_t click_within_graph = CLICK_NOGRAPH; static int fft_axis_start = 0; #if HAVE_GL static mus_float_t fft_faxis_start = 0.0; #endif static chan_info *dragged_cp; #ifdef __APPLE__ static int press_x, press_y; #endif void graph_button_press_callback(chan_info *cp, void *ev, int x, int y, int key_state, int button, oclock_t time) { snd_info *sp; sp = cp->sound; if ((cp->active < CHANNEL_HAS_AXES) || (sp == NULL)) return; /* autotest silliness */ /* if combining, figure out which virtual channel the mouse is in */ if (sp->channel_style == CHANNELS_COMBINED) cp = which_channel(sp, y); /* select this?? */ click_within_graph = within_graph(cp, x, y); select_channel(sp, cp->chan); if (button == POPUP_BUTTON) { switch (click_within_graph) { case CLICK_NOGRAPH: case CLICK_WAVE: case CLICK_MIX: case CLICK_MARK: case CLICK_INSET_GRAPH: case CLICK_MIX_PLAY: case CLICK_CURSOR_PLAY: case CLICK_MARK_PLAY: post_basic_popup_menu(ev); break; case CLICK_FFT_AXIS: case CLICK_FFT_MAIN: case CLICK_FFT_AUX: post_fft_popup_menu(ev); break; case CLICK_SELECTION_LEFT: case CLICK_SELECTION_RIGHT: case CLICK_SELECTION_PLAY: case CLICK_SELECTION_LOOP_PLAY: case CLICK_SELECTION_MAIN: post_selection_popup_menu(ev); break; case CLICK_LISP: post_lisp_popup_menu(ev); break; } return; } mouse_down_time = time; #ifdef __APPLE__ press_x = x; press_y = y; #endif /* select_channel(sp, cp->chan); */ dragged_cp = cp; dragged = false; finish_selection_creation(); switch (click_within_graph) { case CLICK_FFT_AXIS: if (cp->transform_graph_type != GRAPH_AS_SONOGRAM) { #if HAVE_GL if ((cp->transform_graph_type == GRAPH_AS_SPECTROGRAM) && (cp->fft->axis->used_gl)) fft_faxis_start = unproject_to_y(x, y); #endif fft_axis_start = x; } else fft_axis_start = y; break; case CLICK_LISP: if (Xen_hook_has_list(mouse_press_hook)) run_hook(mouse_press_hook, Xen_list_6(C_int_to_Xen_sound(sp->index), C_int_to_Xen_integer(cp->chan), C_int_to_Xen_integer(button), C_int_to_Xen_integer(key_state), C_double_to_Xen_real(ungrf_x(cp->lisp_info->axis, x)), C_double_to_Xen_real(ungrf_y(cp->lisp_info->axis, y))), S_mouse_press_hook); break; case CLICK_MARK: set_mark_control(cp, mouse_mark, key_state); break; case CLICK_WAVE: case CLICK_SELECTION_MAIN: case CLICK_MIX: break; case CLICK_SELECTION_LEFT: case CLICK_SELECTION_RIGHT: dragged = true; restart_selection_creation(cp, click_within_graph == CLICK_SELECTION_RIGHT); break; case CLICK_MARK_PLAY: case CLICK_MIX_PLAY: case CLICK_CURSOR_PLAY: case CLICK_SELECTION_LOOP_PLAY: case CLICK_SELECTION_PLAY: if ((sp->playing) || (ss->selection_play_stop)) { stop_playing_all_sounds(PLAY_BUTTON_UNSET); set_play_button(sp, false); reflect_play_selection_stop(); /* this sets ss->selection_play_stop = false; */ } else { switch (click_within_graph) { case CLICK_MARK_PLAY: if (mark_sync(play_mark)) play_syncd_mark(cp, play_mark); else { if (key_state & snd_ControlMask) play_sound(sp, mark_sample(play_mark), NO_END_SPECIFIED); else play_channel(cp, mark_sample(play_mark), NO_END_SPECIFIED); } break; case CLICK_MIX_PLAY: play_mix_from_id(mix_play_tag); break; case CLICK_CURSOR_PLAY: play_channel_with_sync(cp, cursor_sample(cp), NO_END_SPECIFIED); break; case CLICK_SELECTION_LOOP_PLAY: ss->selection_play_stop = true; loop_play_selection(); break; case CLICK_SELECTION_PLAY: ss->selection_play_stop = true; play_selection(IN_BACKGROUND); break; default: break; } } break; case CLICK_INSET_GRAPH: case CLICK_NOGRAPH: case CLICK_FFT_MAIN: case CLICK_FFT_AUX: break; } } #if USE_MOTIF #define BUTTON_2 Button2 #else #define BUTTON_2 2 #endif void graph_button_release_callback(chan_info *cp, int x, int y, int key_state, int button) { snd_info *sp; sp = cp->sound; if ((cp->active < CHANNEL_HAS_AXES) || (sp == NULL)) return; /* autotest silliness */ if (sp->channel_style == CHANNELS_COMBINED) { if ((dragged) && (dragged_cp)) cp = dragged_cp; else cp = which_channel(sp, y); } dragged_cp = NULL; if (!dragged) { click_loc_t actax; actax = within_graph(cp, x, y); if ((Xen_hook_has_list(mouse_click_hook)) && (Xen_is_true(run_or_hook(mouse_click_hook, Xen_list_7(C_int_to_Xen_sound(sp->index), C_int_to_Xen_integer(cp->chan), C_int_to_Xen_integer(button), C_int_to_Xen_integer(key_state), C_int_to_Xen_integer(x), C_int_to_Xen_integer(y), C_int_to_Xen_integer((int)(((actax == CLICK_FFT_AXIS) || (actax == CLICK_FFT_MAIN)) ? TRANSFORM_AXIS_INFO : ((actax == CLICK_LISP) ? LISP_AXIS_INFO : TIME_AXIS_INFO)))), S_mouse_click_hook)))) return; switch (actax) { case CLICK_INSET_GRAPH: { mus_long_t samp; samp = snd_round_mus_long_t(current_samples(cp) * ((double)(x - cp->inset_graph->x0) / (double)(cp->inset_graph->width))); cursor_moveto(cp, samp); if ((samp < cp->axis->losamp) || (samp > cp->axis->hisamp)) { mus_long_t rsamp; rsamp = samp + snd_round_mus_long_t(0.5 * (cp->axis->hisamp - cp->axis->losamp)); if (rsamp < 0) rsamp = 0; if (rsamp > current_samples(cp)) rsamp = current_samples(cp); set_x_axis_x1(cp, rsamp); update_graph(cp); } } break; case CLICK_SELECTION_LEFT: case CLICK_SELECTION_RIGHT: case CLICK_SELECTION_MAIN: case CLICK_MIX: case CLICK_MARK: case CLICK_WAVE: if (button == BUTTON_2) /* the middle button */ { cp->cursor_on = true; cursor_moveto(cp, snd_round_mus_long_t(ungrf_x(cp->axis, x) * (double)snd_srate(sp))); paste_region(region_list_position_to_id(0), cp); } else { if (key_state & (snd_ShiftMask | snd_ControlMask | snd_MetaMask)) { mus_long_t samps; axis_info *ap; /* zoom request -> each added key zooms closer, as does each successive click */ ap = cp->axis; samps = current_samples(cp); if ((samps > 0) && ((ap->zx * (double)samps) > 1.0)) { if (key_state & snd_ShiftMask) ap->zx *= .5; if (key_state & snd_ControlMask) ap->zx *= .5; if (key_state & snd_MetaMask) ap->zx *= .5; if (ap->x_ambit != 0.0) ap->sx = (((double)(cursor_sample(cp)) / (double)snd_srate(sp) - ap->zx * 0.5 * (ap->xmax - ap->xmin)) - ap->xmin) / ap->x_ambit; apply_x_axis_change(cp); resize_sx_and_zx(cp); } } else { cp->cursor_on = true; cursor_moveto(cp, snd_round_mus_long_t(ungrf_x(cp->axis, x) * (double)snd_srate(sp))); if (mouse_mark) { Xen res = Xen_false; if (Xen_hook_has_list(mark_click_hook)) res = run_progn_hook(mark_click_hook, Xen_list_1(new_xen_mark(mark_to_int(mouse_mark))), S_mark_click_hook); if (!(Xen_is_true(res))) { mus_long_t samp; int sync; samp = mark_sample(mouse_mark); sync = mark_sync(mouse_mark); if (sync == 0) status_report(sp, "mark %d at sample %lld (%3f secs): %3f", mark_to_int(mouse_mark), samp, (double)samp / (double)(snd_srate(sp)), chn_sample(samp, cp, cp->edit_ctr)); else status_report(sp, "mark %d at sample %lld (%3f secs): %3f, (sync: %d)", mark_to_int(mouse_mark), samp, (double)samp / (double)(snd_srate(sp)), chn_sample(samp, cp, cp->edit_ctr), sync); } } else { if (mix_tag != NO_MIX_TAG) { Xen res = Xen_false; /* the mix has already been selected by hit-mix above (to prepare drag) */ if (Xen_hook_has_list(mix_click_hook)) res = run_progn_hook(mix_click_hook, Xen_list_1(new_xen_mix(mix_tag)), S_mix_click_hook); if (!(Xen_is_true(res))) { make_mix_dialog(); reflect_mix_change(mix_tag); } } } } } break; case CLICK_FFT_AXIS: /* not dragged, so must have clicked close to axis */ case CLICK_FFT_MAIN: { char *str; str = describe_fft_point(cp, x, y); set_status(sp, str, false); if (str) free(str); } break; #if USE_MOTIF case CLICK_MARK_PLAY: if (sp->sync != 0) { int i; sync_info *si; si = snd_sync(sp->sync); for (i = 0; i < si->chans; i++) update_graph(si->cps[i]); } else update_graph(cp); #endif default: break; } } else /* dragged */ { if (mouse_mark) { finish_moving_mark(cp, mouse_mark); mouse_mark = NULL; dragged = false; } else { if (mix_tag != NO_MIX_TAG) { finish_moving_mix_tag(mix_tag, x); dragged = false; mix_tag = NO_MIX_TAG; } else { cancel_selection_watch(); finish_selection_creation(); dragged = false; if (show_selection_transform(ss)) { if (sp->sync) for_each_normal_chan_with_int(calculate_syncd_fft, sp->sync); else calculate_fft(cp); } } } } } void graph_button_motion_callback(chan_info *cp, int x, int y, oclock_t time) { /* this refers to mouse drag, not just any motion */ snd_info *sp; oclock_t mouse_time; /* this needs to be a little slow about deciding that we are dragging, as opposed to a slow click */ mouse_time = time; if ((mouse_time - mouse_down_time) < ss->click_time) return; #ifdef __APPLE__ /* on the Mac, we seem to get motion events even without any motion, and the times seem very short */ if ((x == press_x) && (y == press_y)) return; #endif sp = cp->sound; if ((cp->active < CHANNEL_HAS_AXES) || (sp == NULL)) return; /* autotest silliness */ if (sp->channel_style == CHANNELS_COMBINED) /* in united chans, dragging mark shouldn't change channel */ { if (dragged_cp) cp = dragged_cp; else cp = which_channel(sp, y); } if (mouse_mark) { move_mark(cp, mouse_mark, x); /* if mark_drag_hook has printed info to the status_area, we shouldn't erase it here! */ if (!ss->squelch_mark_drag_info) status_report(sp, "%.4f", ungrf_x(cp->axis, x)); dragged = true; return; } switch (click_within_graph) { case CLICK_MIX: /* printing the new position in the status area here is distracting and unnecessary * and the documentation (extsnd.html) has a mix-drag-hook function to print the position. */ move_mix_tag(mix_tag, x, y); dragged = true; break; case CLICK_MARK: if ((dragged) && (!ss->squelch_mark_drag_info)) status_report(sp, "%.4f", ungrf_x(cp->axis, x)); dragged = true; break; case CLICK_INSET_GRAPH: case CLICK_SELECTION_LEFT: case CLICK_SELECTION_RIGHT: case CLICK_SELECTION_MAIN: case CLICK_WAVE: if (dragged) status_report(sp, "%.4f", ungrf_x(cp->axis, x)); if (!dragged) { /* somehow... if there is already a selection, be reluctant to clobber it */ start_selection_creation(cp, snd_round_mus_long_t(ungrf_x(cp->axis, x) * snd_srate(sp))); } else { update_possible_selection_in_progress(snd_round_mus_long_t(ungrf_x(cp->axis, x) * snd_srate(sp))); move_selection(cp, x); } dragged = true; break; case CLICK_FFT_AXIS: { /* change spectrum_end(ss) and redisplay fft */ /* changed 25-Oct-07 -- follow sync and separate chan */ mus_float_t new_cutoff; if (cp->transform_graph_type != GRAPH_AS_SONOGRAM) { #if HAVE_GL if ((cp->transform_graph_type == GRAPH_AS_SPECTROGRAM) && (cp->fft->axis->used_gl)) { mus_float_t ny; ny = unproject_to_y(x, y); new_cutoff = cp->spectrum_end + (fft_faxis_start - ny); fft_faxis_start = ny; } else #endif new_cutoff = cp->spectrum_end + ((mus_float_t)(fft_axis_start - x) / fft_axis_extent(cp)); fft_axis_start = x; } else { new_cutoff = cp->spectrum_end + ((mus_float_t)(y - fft_axis_start) / fft_axis_extent(cp)); fft_axis_start = y; } if (new_cutoff > 1.0) new_cutoff = 1.0; if (new_cutoff < 0.001) new_cutoff = 0.001; if (sp->sync != 0) { int i; sync_info *si; si = snd_sync(sp->sync); for (i = 0; i < si->chans; i++) { si->cps[i]->spectrum_end = new_cutoff; if (cp->transform_graph_type != GRAPH_ONCE) sono_update(si->cps[i]); else update_graph(si->cps[i]); } si = free_sync_info(si); } else { cp->spectrum_end = new_cutoff; if (cp->transform_graph_type != GRAPH_ONCE) sono_update(cp); else update_graph(cp); } } break; case CLICK_LISP: if (Xen_hook_has_list(mouse_drag_hook)) run_hook(mouse_drag_hook, Xen_list_6(C_int_to_Xen_sound(cp->sound->index), C_int_to_Xen_integer(cp->chan), C_int_to_Xen_integer(-1), C_int_to_Xen_integer(-1), C_double_to_Xen_real(ungrf_x(cp->lisp_info->axis, x)), C_double_to_Xen_real(ungrf_y(cp->lisp_info->axis, y))), S_mouse_drag_hook); break; case CLICK_FFT_MAIN: if (cp->with_verbose_cursor) { char *str; str = describe_fft_point(cp, x, y); set_status(cp->sound, str, false); if (str) free(str); } break; default: break; } } void channel_resize(chan_info *cp) { snd_info *sp; if ((cp == NULL) || (cp->active < CHANNEL_HAS_AXES) || (cp->sound == NULL)) return; sp = cp->sound; if (sp->channel_style != CHANNELS_SEPARATE) { if (cp->chan == 0) for_each_sound_chan(sp, update_graph_or_warn); } else update_graph_or_warn(cp); } void edit_history_select(chan_info *cp, int row) { #if WITH_RELATIVE_PANES || USE_GTK if (cp->sound->channel_style != CHANNELS_SEPARATE) { int k; snd_info *sp; chan_info *ncp = NULL; sp = cp->sound; for (k = 1; k < sp->nchans; k++) if (sp->chans[k]->edhist_base > row) { ncp = sp->chans[k - 1]; break; } if (ncp == NULL) ncp = sp->chans[sp->nchans - 1]; undo_edit_with_sync(ncp, ncp->edit_ctr - row + ncp->edhist_base); goto_graph(ncp); } else #endif { undo_edit_with_sync(cp, cp->edit_ctr - row); goto_graph(cp); } } widget_t channel_to_widget(chan_info *cp) { if ((cp->chan > 0) && (cp->sound->channel_style != CHANNELS_SEPARATE)) return(channel_graph(cp->sound->chans[0])); return(channel_graph(cp)); } chan_info *channel_to_chan(chan_info *cp) { if ((cp->chan > 0) && (cp->sound->channel_style != CHANNELS_SEPARATE)) return(cp->sound->chans[0]); return(cp); } graphics_context *set_context(chan_info *cp, chan_gc_t gc) { graphics_context *ax; chan_info *draw_cp; draw_cp = channel_to_chan(cp); ax = draw_cp->ax; if (cp->selected) { switch (gc) { case CHAN_GC: ax->gc = ss->selected_basic_gc; break; case CHAN_IGC: ax->gc = ss->selected_erase_gc; break; case CHAN_SELGC: ax->gc = ss->selected_selection_gc; break; case CHAN_CGC: ax->gc = ss->selected_cursor_gc; break; case CHAN_MGC: ax->gc = ss->selected_mark_gc; break; case CHAN_MXGC: ax->gc = ss->mix_gc; break; case CHAN_TMPGC: ax->gc = ss->selected_basic_gc; break; } } else { switch (gc) { case CHAN_GC: ax->gc = ss->basic_gc; break; case CHAN_IGC: ax->gc = ss->erase_gc; break; case CHAN_SELGC: ax->gc = ss->selection_gc; break; case CHAN_CGC: ax->gc = ss->cursor_gc; break; case CHAN_MGC: ax->gc = ss->mark_gc; break; case CHAN_MXGC: ax->gc = ss->mix_gc; break; case CHAN_TMPGC: ax->gc = ss->combined_basic_gc; break; } } return(ax); } graphics_context *copy_context(chan_info *cp) {return(set_context(cp, CHAN_GC));} graphics_context *erase_context(chan_info *cp) {return(set_context(cp, CHAN_IGC));} graphics_context *selection_context(chan_info *cp) {return(set_context(cp, CHAN_SELGC));} graphics_context *cursor_context(chan_info *cp) {return(set_context(cp, CHAN_CGC));} graphics_context *mark_tag_context(chan_info *cp) {return(set_context(cp, CHAN_MGC));} graphics_context *mix_waveform_context(chan_info *cp) {return(set_context(cp, CHAN_MXGC));} static graphics_context *combined_context(chan_info *cp) {return(set_context(cp, CHAN_TMPGC));} /* ---------------------------------------- smpte label ---------------------------------------- */ static void show_smpte_label(chan_info *cp, graphics_context *cur_ax) { #if (!USE_NO_GUI) #define SMPTE_FRAMPLES_PER_SECOND 24.0 if (cp->graph_time_on) { int grf_x, grf_y, grf_width, grf_height; /* is there room for a label? */ grf_x = cp->axis->x_axis_x0; grf_y = cp->axis->y_axis_y1; grf_width = cp->axis->x_axis_x1 - grf_x; grf_height = cp->axis->y_axis_y0 - grf_y; if ((grf_width > 100) && (grf_height > 20)) { bool try_tiny_font; int width, height, framples, seconds, minutes, hours; double secs; char num_buf[3]; static char label[12] = "00:00:00:00"; try_tiny_font = (grf_height < 50); width = 8 + number_width(label, try_tiny_font); height = 8 + number_height((try_tiny_font) ? TINY_FONT(ss) : AXIS_NUMBERS_FONT(ss)); secs = cp->axis->x0; hours = floor(secs / 3600.0); secs -= hours * 3600; minutes = floor(secs / 60.0); secs -= minutes * 60; seconds = floor(secs); framples = (secs - seconds) * SMPTE_FRAMPLES_PER_SECOND; snprintf(num_buf, 3, "%d", hours); if (hours > 9) {label[0] = num_buf[0]; label[1] = num_buf[1];} else {label[0] = '0'; label[1] = num_buf[0];} snprintf(num_buf, 3, "%d", minutes); if (minutes > 9) {label[3] = num_buf[0]; label[4] = num_buf[1];} else {label[3] = '0'; label[4] = num_buf[0];} snprintf(num_buf, 3, "%d", seconds); if (seconds > 9) {label[6] = num_buf[0]; label[7] = num_buf[1];} else {label[6] = '0'; label[7] = num_buf[0];} snprintf(num_buf, 3, "%d", framples); if (framples > 9) {label[9] = num_buf[0]; label[10] = num_buf[1];} else {label[9] = '0'; label[10] = num_buf[0];} fill_rectangle(cur_ax, grf_x, grf_y, width, 2); fill_rectangle(cur_ax, grf_x, grf_y + height, width, 2); fill_rectangle(cur_ax, grf_x, grf_y, 2, height); fill_rectangle(cur_ax, grf_x + width - 2, grf_y, 2, height); set_numbers_font(cur_ax, NOT_PRINTING, try_tiny_font); #if USE_MOTIF grf_y += number_height((try_tiny_font) ? TINY_FONT(ss) : AXIS_NUMBERS_FONT(ss)); #else grf_y++; #endif draw_string(cur_ax, grf_x + 4, grf_y + 4, label, 11); } } #endif } /* ---------------------------------------- inset graph ---------------------------------------- */ #define INSET_WIDTH .2 #define INSET_HEIGHT .25 void clear_inset_graph(chan_info *cp) { if (cp->inset_graph) cp->inset_graph->edpos = -2; } void free_inset_graph(chan_info *cp) { if (cp->inset_graph) { if (cp->inset_graph->data0) free(cp->inset_graph->data0); if (cp->inset_graph->data1) free(cp->inset_graph->data1); free(cp->inset_graph); cp->inset_graph = NULL; } } #if (!USE_NO_GUI) static void make_point_arrays(inset_graph_info_t *info, int size, vct *v1) { if (size != info->data_size) { if (info->data0) free(info->data0); if (info->data1) free(info->data1); info->data1 = NULL; info->data0 = (point_t *)calloc(size, sizeof(point_t)); } if ((v1) && (!(info->data1))) info->data1 = (point_t *)calloc(size, sizeof(point_t)); info->data_size = size; } static void update_inset_axes(chan_info *cp, inset_graph_info_t *info, graphics_context *cur_ax) { char *str; int len, num_hgt = -1; axis_info *ap; ap = cp->axis; str = prettyf(ap->xmax, 2); if (str) { num_hgt = number_height(TINY_FONT(ss)); len = strlen(str); set_tiny_numbers_font(cp, cur_ax); #if (!USE_GTK) draw_string(cur_ax, info->x1 - 6 * len + 10, info->y1 + num_hgt, str, len); #else draw_string(cur_ax, info->x1 - 6 * len + 10, info->y1 + (num_hgt / 2) - 2, str, len); #endif free(str); } if (info->maxamp > 0.0) { str = prettyf(info->maxamp, (info->maxamp > .1) ? 2 : ((info->maxamp > .01) ? 3 : 4)); if (str) { len = strlen(str); set_tiny_numbers_font(cp, cur_ax); #if (!USE_GTK) if (num_hgt == -1) num_hgt = number_height(TINY_FONT(ss)); draw_string(cur_ax, info->x0 - 6 * len - 2, info->y0 + (num_hgt / 2), str, len); #else draw_string(cur_ax, info->x0 - 6 * len - 2, info->y0, str, len); #endif free(str); } } } #endif static void show_inset_graph(chan_info *cp, graphics_context *cur_ax) { #if (!USE_NO_GUI) if (cp->graph_time_on) { int grf_width, width, x_offset, y_offset, grf_height, height, chan_offset; bool new_peaks; inset_graph_info_t *info; mus_long_t framples; if (!(cp->inset_graph)) { cp->inset_graph = (inset_graph_info_t *)calloc(1, sizeof(inset_graph_info_t)); cp->inset_graph->edpos = -2; } info = cp->inset_graph; grf_width = cp->axis->x_axis_x1; width = snd_round(INSET_WIDTH * grf_width); x_offset = grf_width - width; grf_height = cp->axis->y_axis_y0 - cp->axis->y_axis_y1; height = snd_round(INSET_HEIGHT * grf_height); chan_offset = cp->axis->y_axis_y1 - 6; if ((cp->show_axes == SHOW_X_AXIS) || (cp->show_axes == SHOW_X_AXIS_UNLABELLED)) chan_offset += 10; y_offset = chan_offset + snd_round(height * 0.5); new_peaks = ((cp->axis->cp) && (cp->axis->cp->new_peaks)); /* new_peaks is set during update_graph if we just finished a new peak-env */ framples = current_samples(cp); if ((width > 10) && (height > 10) && (framples > 0) && ((cp->chan == 0) || (cp->sound->channel_style != CHANNELS_SUPERIMPOSED))) { /* draw axes around the inset graph */ fill_rectangle(cur_ax, x_offset, chan_offset + height, width, 2); fill_rectangle(cur_ax, x_offset, chan_offset, 2, height); info->x0 = x_offset; info->x1 = x_offset + width; info->y0 = chan_offset; info->y1 = chan_offset + height; /* show where the current window fits into the overall graph */ { int rx, lx, wx; rx = snd_round(width * (double)(cp->axis->hisamp) / (double)framples); lx = snd_round(width * (double)(cp->axis->losamp) / (double)framples); #if USE_GTK if (lx < 2) lx = 2; /* don't erase the y axis */ #endif wx = rx - lx; if (wx <= 0) wx = 1; if (cp->selected) { cur_ax->gc = ss->selected_selection_gc; fill_rectangle(cur_ax, x_offset + lx, chan_offset, wx, height); cur_ax->gc = ss->selected_basic_gc; } else { cur_ax->gc = ss->selection_gc; fill_rectangle(cur_ax, x_offset + lx, chan_offset, wx, height); cur_ax->gc = ss->basic_gc; } } if ((!new_peaks) && (width == info->width) && (height == info->height) && (y_offset == info->y_offset) && (cp->edit_ctr == info->edpos)) { /* use old env graph points if nothing has changed */ update_inset_axes(cp, info, cur_ax); } else { /* need to get new peak env graph points */ Xen data; double data_max = 0.0, data_scaler, step; vct *v0 = NULL, *v1 = NULL; mus_float_t *v0data = NULL, *v1data = NULL; int data_len; #if HAVE_SCHEME int gc_loc; #endif data = make_graph_data(cp, cp->edit_ctr, 0, framples); if (Xen_is_false(data)) return; #if HAVE_SCHEME gc_loc = s7_gc_protect(s7, data); #endif if (mus_is_vct(data)) v0 = xen_to_vct(data); else { v0 = xen_to_vct(Xen_car(data)); v1 = xen_to_vct(Xen_cadr(data)); } v0data = mus_vct_data(v0); if (v1) v1data = mus_vct_data(v1); data_max = mus_vct_peak(v0); if (v1) { double data1_max; data1_max = mus_vct_peak(v1); if (data1_max > data_max) data_max = data1_max; } if (data_max > 0.0) data_scaler = (double)height / (2 * data_max); else data_scaler = 0.0; info->maxamp = data_max; data_len = mus_vct_length(v0); step = (double)data_len / (double)width; if (data_scaler < 0.00000001) { /* load up 0's */ int i, j; make_point_arrays(info, width, v1); for (j = x_offset, i = 0; i < width; i++, j++) { info->data0[i].x = j; info->data0[i].y = y_offset; if (v1) { info->data1[i].x = j; info->data1[i].y = y_offset; } } } else { if (data_len > width) { /* normal case: more samples to display than we have room for, so subsample */ int i, j; double max_y, min_y, stepper = 0.0; max_y = -data_max; min_y = data_max; make_point_arrays(info, width, v1); for (i = 0, j = 0; (i < data_len) && (j < width); i++) { if (v1) { if (v1data[i] > max_y) max_y = v1data[i]; if (v0data[i] < min_y) min_y = v0data[i]; } else { if (v0data[i] > max_y) max_y = v0data[i]; } stepper += 1.0; if (stepper >= step) { info->data0[j].x = x_offset; info->data0[j].y = snd_round(y_offset - max_y * data_scaler); max_y = -data_max; if (v1) { info->data1[j].x = x_offset; info->data1[j].y = snd_round(y_offset - min_y * data_scaler); min_y = data_max; } x_offset++; stepper -= step; j++; } } while (j < width) { info->data0[j].x = info->data0[j - 1].x; info->data0[j].y = info->data0[j - 1].y; if (v1) { info->data1[j].x = info->data1[j - 1].x; info->data1[j].y = info->data1[j - 1].y; } j++; } } else { /* more pixels than samples */ double xstep, xj; int i; xstep = (double)width / (double)data_len; xj = (double)x_offset; make_point_arrays(info, data_len, v1); for (i = 0; i < data_len; i++, xj += xstep) { info->data0[i].x = snd_round(xj); if (!v1) info->data0[i].y = snd_round(y_offset - data_scaler * v0data[i]); else { info->data0[i].y = snd_round(y_offset - data_scaler * v1data[i]); info->data1[i].x = info->data0[i].x; info->data1[i].x = snd_round(y_offset - data_scaler * v0data[i]); } } } } info->width = width; info->height = height; info->edpos = cp->edit_ctr; info->y_offset = y_offset; update_inset_axes(cp, info, cur_ax); #if HAVE_SCHEME s7_gc_unprotect_at(s7, gc_loc); #endif } draw_lines(cur_ax, info->data0, info->data_size); if (info->data1) draw_lines(cur_ax, info->data1, info->data_size); info->graphing = true; } else info->graphing = false; } #endif } void draw_inset_line_cursor(chan_info *cp, graphics_context *ax) { /* we've checked that with_inset_graph is #t and cp has the pointer */ if ((cp->inset_graph->graphing) && (cp->cx > cp->inset_graph->x0) && (cp->cx < cp->inset_graph->x1)) draw_line(ax, cp->cx, cp->axis->y_axis_y0 - 1, cp->cx, cp->inset_graph->y1 + 4); else draw_line(ax, cp->cx, cp->axis->y_axis_y0 - 1, cp->cx, cp->axis->y_axis_y1); } /* -------------------------------------------------------------------------------- */ typedef enum {CP_GRAPH_TRANSFORM_ON, CP_GRAPH_TIME_ON, CP_FRAMPLES, CP_CURSOR, CP_GRAPH_LISP_ON, CP_LOSAMP, CP_HISAMP, CP_SQUELCH_UPDATE, CP_EDIT_CTR, CP_CURSOR_STYLE, CP_EDIT_HOOK, CP_UNDO_HOOK, CP_AFTER_EDIT_HOOK, CP_SHOW_Y_ZERO, CP_SHOW_MARKS, CP_TIME_GRAPH_TYPE, CP_WAVO_HOP, CP_WAVO_TRACE, CP_MAX_TRANSFORM_PEAKS, CP_SHOW_TRANSFORM_PEAKS, CP_ZERO_PAD, CP_WITH_VERBOSE_CURSOR, CP_FFT_LOG_FREQUENCY, CP_FFT_LOG_MAGNITUDE, CP_WAVELET_TYPE, CP_SPECTRO_HOP, CP_TRANSFORM_SIZE, CP_TRANSFORM_GRAPH_TYPE, CP_FFT_WINDOW, CP_TRANSFORM_TYPE, CP_TRANSFORM_NORMALIZATION, CP_SHOW_MIX_WAVEFORMS, CP_TIME_GRAPH_STYLE, CP_LISP_GRAPH_STYLE, CP_TRANSFORM_GRAPH_STYLE, CP_DOT_SIZE, CP_SHOW_AXES, CP_GRAPHS_HORIZONTAL, CP_CURSOR_SIZE, CP_CURSOR_POSITION, CP_EDPOS_FRAMPLES, CP_X_AXIS_STYLE, CP_UPDATE_TIME, CP_UPDATE_TRANSFORM_GRAPH, CP_UPDATE_LISP, CP_PROPERTIES, CP_MIN_DB, CP_SPECTRO_X_ANGLE, CP_SPECTRO_Y_ANGLE, CP_SPECTRO_Z_ANGLE, CP_SPECTRO_X_SCALE, CP_SPECTRO_Y_SCALE, CP_SPECTRO_Z_SCALE, CP_SPECTRUM_END, CP_SPECTRUM_START, CP_FFT_WINDOW_BETA, CP_SX, CP_SY, CP_ZX, CP_ZY, CP_MAXAMP, CP_EDPOS_MAXAMP, CP_BEATS_PER_MINUTE, CP_EDPOS_CURSOR, CP_SHOW_GRID, CP_SHOW_SONOGRAM_CURSOR, CP_GRID_DENSITY, CP_MAXAMP_POSITION, CP_EDPOS_MAXAMP_POSITION, CP_BEATS_PER_MEASURE, CP_FFT_WINDOW_ALPHA, CP_TRACKING_CURSOR_STYLE, CP_FFT_WITH_PHASES } cp_field_t; static Xen cp_edpos; static int cp_edpos_loc = NOT_A_GC_LOC; static Xen channel_get(Xen snd, Xen chn_n, cp_field_t fld, const char *caller) { chan_info *cp; snd_info *sp = NULL; int i; Xen res = Xen_empty_list; if (Xen_is_true(snd)) { for (i = ss->max_sounds - 1; i >= 0; i--) { sp = ss->sounds[i]; if ((sp) && (sp->inuse == SOUND_NORMAL)) res = Xen_cons(channel_get(C_int_to_Xen_integer(i), chn_n, fld, caller), res); /* I think not SOUND_WRAPPER here -- get/set would then be operating on sounds that * are not returned by 'sounds' and return #f from 'sound?', so it would almost * certainly cause confusion. The globals fields should be reflected however. */ } return(res); } else { if (Xen_is_true(chn_n)) { sp = get_sp(snd); if (sp == NULL) return(snd_no_such_sound_error(caller, snd)); for (i = sp->nchans - 1; i >= 0; i--) res = Xen_cons(channel_get(snd, C_int_to_Xen_integer(i), fld, caller), res); return(res); } else { Snd_assert_channel(caller, snd, chn_n, 1); cp = get_cp(snd, chn_n, caller); if (!cp) return(Xen_false); /* perhaps snd-error-hook cancelled the error? */ switch (fld) { case CP_EDIT_CTR: return(C_int_to_Xen_integer(cp->edit_ctr)); break; case CP_GRAPH_TRANSFORM_ON: return(C_bool_to_Xen_boolean(cp->graph_transform_on)); break; case CP_GRAPH_TIME_ON: return(C_bool_to_Xen_boolean(cp->graph_time_on)); break; case CP_CURSOR: return(C_llong_to_Xen_llong(cursor_sample(cp))); break; case CP_EDPOS_CURSOR: return(C_llong_to_Xen_llong(cp->edits[to_c_edit_position(cp, cp_edpos, S_cursor, 3)]->cursor)); break; case CP_FRAMPLES: return(C_llong_to_Xen_llong(current_samples(cp))); break; case CP_GRAPH_LISP_ON: return(C_bool_to_Xen_boolean(cp->graph_lisp_on)); break; case CP_LOSAMP: if (cp->axis) return(C_llong_to_Xen_llong(cp->axis->losamp)); break; case CP_HISAMP: if (cp->axis) return(C_llong_to_Xen_llong(cp->axis->hisamp)); break; case CP_SQUELCH_UPDATE: return(C_bool_to_Xen_boolean(cp->squelch_update)); break; case CP_CURSOR_SIZE: return(C_int_to_Xen_integer(cp->cursor_size)); break; case CP_CURSOR_STYLE: if (cp->cursor_style != CURSOR_PROC) return(C_int_to_Xen_integer((int)(cp->cursor_style))); if (Xen_is_procedure(cp->cursor_proc)) return(cp->cursor_proc); return(ss->cursor_proc); break; case CP_TRACKING_CURSOR_STYLE: return(C_int_to_Xen_integer((int)(cp->tracking_cursor_style))); break; case CP_EDIT_HOOK: if (!(Xen_is_hook(cp->edit_hook))) { cp->edit_hook = Xen_define_simple_hook("(make-hook)", 0); cp->edit_hook_loc = snd_protect(cp->edit_hook); } return(cp->edit_hook); break; case CP_AFTER_EDIT_HOOK: if (!(Xen_is_hook(cp->after_edit_hook))) { cp->after_edit_hook = Xen_define_simple_hook("(make-hook)", 0); cp->after_edit_hook_loc = snd_protect(cp->after_edit_hook); } return(cp->after_edit_hook); break; case CP_UNDO_HOOK: if (!(Xen_is_hook(cp->undo_hook))) { cp->undo_hook = Xen_define_simple_hook("(make-hook)", 0); cp->undo_hook_loc = snd_protect(cp->undo_hook); } return(cp->undo_hook); break; case CP_SHOW_Y_ZERO: return(C_bool_to_Xen_boolean(cp->show_y_zero)); break; case CP_SHOW_GRID: return(C_bool_to_Xen_boolean((bool)(cp->show_grid))); break; case CP_GRID_DENSITY: return(C_double_to_Xen_real(cp->grid_density)); break; case CP_SHOW_SONOGRAM_CURSOR: return(C_bool_to_Xen_boolean((bool)(cp->show_sonogram_cursor))); break; case CP_SHOW_MARKS: return(C_bool_to_Xen_boolean(cp->show_marks)); break; case CP_TIME_GRAPH_TYPE: return(C_int_to_Xen_integer((int)(cp->time_graph_type))); break; case CP_WAVO_HOP: return(C_int_to_Xen_integer(cp->wavo_hop)); break; case CP_WAVO_TRACE: return(C_int_to_Xen_integer(cp->wavo_trace)); break; case CP_MAX_TRANSFORM_PEAKS: return(C_int_to_Xen_integer(cp->max_transform_peaks)); break; case CP_ZERO_PAD: return(C_int_to_Xen_integer(cp->zero_pad)); break; case CP_WAVELET_TYPE: return(C_int_to_Xen_integer(cp->wavelet_type)); break; case CP_SHOW_TRANSFORM_PEAKS: return(C_bool_to_Xen_boolean(cp->show_transform_peaks)); break; case CP_WITH_VERBOSE_CURSOR: return(C_bool_to_Xen_boolean(cp->with_verbose_cursor)); break; case CP_FFT_LOG_FREQUENCY: return(C_bool_to_Xen_boolean(cp->fft_log_frequency)); break; case CP_FFT_LOG_MAGNITUDE: return(C_bool_to_Xen_boolean(cp->fft_log_magnitude)); break; case CP_FFT_WITH_PHASES: return(C_bool_to_Xen_boolean(cp->fft_with_phases)); break; case CP_SPECTRO_HOP: return(C_int_to_Xen_integer(cp->spectro_hop)); break; case CP_TRANSFORM_SIZE: return(C_llong_to_Xen_llong(cp->transform_size)); break; case CP_TRANSFORM_GRAPH_TYPE: return(C_int_to_Xen_integer((int)(cp->transform_graph_type))); break; case CP_FFT_WINDOW: return(C_int_to_Xen_integer((int)(cp->fft_window))); break; case CP_TRANSFORM_TYPE: return(C_int_to_Xen_transform(cp->transform_type)); break; case CP_TRANSFORM_NORMALIZATION: return(C_int_to_Xen_integer((int)(cp->transform_normalization))); break; case CP_SHOW_MIX_WAVEFORMS: return(C_bool_to_Xen_boolean(cp->show_mix_waveforms)); break; case CP_TIME_GRAPH_STYLE: return(C_int_to_Xen_integer(cp->time_graph_style)); break; case CP_LISP_GRAPH_STYLE: return(C_int_to_Xen_integer(cp->lisp_graph_style)); break; case CP_TRANSFORM_GRAPH_STYLE: return(C_int_to_Xen_integer(cp->transform_graph_style)); break; case CP_X_AXIS_STYLE: return(C_int_to_Xen_integer((int)(cp->x_axis_style))); break; case CP_DOT_SIZE: return(C_int_to_Xen_integer(cp->dot_size)); break; case CP_SHOW_AXES: return(C_int_to_Xen_integer((int)(cp->show_axes))); break; case CP_GRAPHS_HORIZONTAL: return(C_bool_to_Xen_boolean(cp->graphs_horizontal)); break; case CP_CURSOR_POSITION: return(Xen_list_2(C_int_to_Xen_integer(cp->cx), C_int_to_Xen_integer(cp->cy))); break; case CP_EDPOS_FRAMPLES: return(C_llong_to_Xen_llong(to_c_edit_samples(cp, cp_edpos, caller, 3))); break; case CP_UPDATE_TIME: /* any display-oriented background process must first be run to completion * display checks for waiting process and does not update display if one found! */ finish_peak_env(cp); cp->waiting_to_make_graph = false; display_channel_time_data(cp); break; case CP_UPDATE_LISP: display_channel_lisp_data(cp); break; case CP_UPDATE_TRANSFORM_GRAPH: if (cp->graph_transform_on) { if (chan_fft_in_progress(cp)) force_fft_clear(cp); ss->checking_explicitly = true; /* do not allow UI events to intervene here! */ if (cp->transform_graph_type == GRAPH_ONCE) single_fft(cp, FORCE_REDISPLAY, FORCE_REFFT); else { void *val; val = (void *)make_sonogram_state(cp, FORCE_REFFT); while (sonogram_in_slices(val) == BACKGROUND_CONTINUE) ; } ss->checking_explicitly = false; } break; case CP_PROPERTIES: if (!(Xen_is_vector(cp->properties))) { cp->properties = Xen_make_vector(1, Xen_empty_list); cp->properties_loc = snd_protect(cp->properties); } return(Xen_vector_ref(cp->properties, 0)); break; case CP_SX: if (cp->axis) return(C_double_to_Xen_real(cp->axis->sx)); break; case CP_SY: if (cp->axis) return(C_double_to_Xen_real(cp->axis->sy)); break; case CP_ZX: if (cp->axis) return(C_double_to_Xen_real(cp->axis->zx)); break; case CP_ZY: if (cp->axis) return(C_double_to_Xen_real(cp->axis->zy)); break; case CP_MIN_DB: return(C_double_to_Xen_real(cp->min_dB)); break; case CP_SPECTRO_X_ANGLE: return(C_double_to_Xen_real(cp->spectro_x_angle)); break; case CP_SPECTRO_Y_ANGLE: return(C_double_to_Xen_real(cp->spectro_y_angle)); break; case CP_SPECTRO_Z_ANGLE: return(C_double_to_Xen_real(cp->spectro_z_angle)); break; case CP_SPECTRO_X_SCALE: return(C_double_to_Xen_real(cp->spectro_x_scale)); break; case CP_SPECTRO_Y_SCALE: return(C_double_to_Xen_real(cp->spectro_y_scale)); break; case CP_SPECTRO_Z_SCALE: return(C_double_to_Xen_real(cp->spectro_z_scale)); break; case CP_SPECTRUM_END: return(C_double_to_Xen_real(cp->spectrum_end)); break; case CP_SPECTRUM_START: return(C_double_to_Xen_real(cp->spectrum_start)); break; case CP_FFT_WINDOW_ALPHA: return(C_double_to_Xen_real(cp->fft_window_alpha)); break; case CP_FFT_WINDOW_BETA: return(C_double_to_Xen_real(cp->fft_window_beta)); break; case CP_BEATS_PER_MINUTE: return(C_double_to_Xen_real(cp->beats_per_minute)); break; case CP_BEATS_PER_MEASURE: return(C_int_to_Xen_integer(cp->beats_per_measure)); break; case CP_MAXAMP: return(C_double_to_Xen_real(channel_maxamp(cp, AT_CURRENT_EDIT_POSITION))); break; case CP_EDPOS_MAXAMP: return(C_double_to_Xen_real(channel_maxamp(cp, to_c_edit_position(cp, cp_edpos, S_maxamp, 3)))); break; case CP_MAXAMP_POSITION: return(C_llong_to_Xen_llong(channel_maxamp_position(cp, AT_CURRENT_EDIT_POSITION))); break; case CP_EDPOS_MAXAMP_POSITION: return(C_llong_to_Xen_llong(channel_maxamp_position(cp, to_c_edit_position(cp, cp_edpos, S_maxamp_position, 3)))); break; } } } return(Xen_false); } static int g_imin(int mn, Xen val, int def) { int nval; if (Xen_is_integer(val)) nval = Xen_integer_to_C_int(val); else nval = def; if (nval >= mn) return(nval); return(mn); } static int g_omin(mus_long_t mn, Xen val, mus_long_t def) { mus_long_t nval; if (Xen_is_llong(val)) nval = Xen_llong_to_C_llong(val); else nval = def; if (nval >= mn) return(nval); return(mn); } static void reset_y_display(chan_info *cp, double sy, double zy) { axis_info *ap; ap = cp->axis; ap->sy = sy; ap->zy = zy; resize_sy(cp); apply_y_axis_change(cp); } static void chans_x_axis_style(chan_info *cp, int value); static bool call_update_graph = true; #define MAX_SPECTRO_SCALE 1000.0 #define MAX_SPECTRO_ANGLE 360.0 #define MIN_SPECTRO_ANGLE -360.0 static Xen channel_set(Xen snd, Xen chn_n, Xen on, cp_field_t fld, const char *caller) { chan_info *cp; int val = 0; bool bval = false; snd_info *sp; int i; mus_float_t curamp, curf; Xen res = Xen_empty_list; if (Xen_is_true(snd)) { for (i = ss->max_sounds - 1; i >= 0; i--) { sp = ss->sounds[i]; if ((sp) && (sp->inuse == SOUND_NORMAL)) res = Xen_cons(channel_set(C_int_to_Xen_integer(i), chn_n, on, fld, caller), res); } return(res); } if (Xen_is_true(chn_n)) { sp = get_sp(snd); if (sp == NULL) return(snd_no_such_sound_error(caller, snd)); for (i = sp->nchans - 1; i >= 0; i--) res = Xen_cons(channel_set(snd, C_int_to_Xen_integer(i), on, fld, caller), res); return(res); } Snd_assert_channel(caller, snd, chn_n, 2); cp = get_cp(snd, chn_n, caller); if (!cp) return(Xen_false); switch (fld) { case CP_EDIT_CTR: if (cp->editable) { if (Xen_is_integer(on)) val = Xen_integer_to_C_int(on); else val = 0; if (cp->edit_ctr < val) redo_edit(cp, val - cp->edit_ctr); else undo_edit(cp, cp->edit_ctr - val); } return(C_int_to_Xen_integer(cp->edit_ctr)); break; case CP_GRAPH_TRANSFORM_ON: bval = Xen_boolean_to_C_bool(on); fftb(cp, bval); update_graph(cp); return(on); break; case CP_GRAPH_TIME_ON: bval = Xen_boolean_to_C_bool(on); waveb(cp, bval); update_graph(cp); return(on); break; case CP_CURSOR: { mus_long_t samp = 0; if (Xen_is_llong(on)) samp = Xen_llong_to_C_llong(on); if (samp < 0) { cp->cursor_on = false; update_graph(cp); } else { cp->cursor_on = true; cursor_moveto(cp, samp); } cp->original_cursor = samp; /* for snd-dac, track-and-return */ return(C_llong_to_Xen_llong(samp)); } break; case CP_EDPOS_CURSOR: { int pos; mus_long_t samp = 0; pos = to_c_edit_position(cp, cp_edpos, caller, 3); if (Xen_is_llong(on)) samp = Xen_llong_to_C_llong(on); if (samp < 0) { cp->cursor_on = false; update_graph(cp); } else { if (pos == cp->edit_ctr) { cp->cursor_on = true; cursor_moveto(cp, samp); } else cp->edits[pos]->cursor = samp; } return(C_llong_to_Xen_llong(samp)); } break; case CP_GRAPH_LISP_ON: cp->graph_lisp_on = Xen_boolean_to_C_bool(on); update_graph(cp); return(on); break; case CP_LOSAMP: Xen_check_type(Xen_is_integer(on), on, 1, S_set S_left_sample, "an integer"); set_x_axis_x0(cp, beg_to_sample(on, caller)); return(on); break; case CP_HISAMP: Xen_check_type(Xen_is_integer(on), on, 1, S_set S_right_sample, "an integer"); set_x_axis_x1(cp, beg_to_sample(on, caller)); return(on); break; case CP_SQUELCH_UPDATE: cp->squelch_update = Xen_boolean_to_C_bool(on); if (!(cp->squelch_update)) { /* make sure everything that was squelched before is now correct */ reflect_edit_history_change(cp); if (cp->edit_ctr == 0) reflect_file_revert_in_label(cp->sound); else reflect_file_change_in_label(cp); clear_status_area(cp->sound); } break; case CP_CURSOR_SIZE: cp->cursor_size = Xen_integer_to_C_int(on); update_graph(cp); return(C_int_to_Xen_integer(cp->cursor_size)); break; case CP_CURSOR_STYLE: if (Xen_is_procedure(on)) { char *error = NULL; error = procedure_ok(on, 3, S_cursor_style, "", 1); if (error == NULL) { if ((cp->cursor_style == CURSOR_PROC) && (Xen_is_procedure(cp->cursor_proc))) snd_unprotect_at(cp->cursor_proc_loc); cp->cursor_proc_loc = snd_protect(on); cp->cursor_proc = on; cp->cursor_style = CURSOR_PROC; return(on); } else { Xen errstr; errstr = C_string_to_Xen_string(error); free(error); return(snd_bad_arity_error(S_set S_cursor_style, errstr, on)); } } else { if ((cp->cursor_style == CURSOR_PROC) && (Xen_is_procedure(cp->cursor_proc))) { snd_unprotect_at(cp->cursor_proc_loc); cp->cursor_proc = Xen_undefined; cp->cursor_proc_loc = NOT_A_GC_LOC; } cp->cursor_style = (cursor_style_t)Xen_integer_to_C_int(on); /* range already checked */ } cp->just_zero = (cp->cursor_style == CURSOR_LINE); /* no point in displaying y value in this case */ update_graph(cp); return(C_int_to_Xen_integer((int)(cp->cursor_style))); break; case CP_TRACKING_CURSOR_STYLE: cp->tracking_cursor_style = (cursor_style_t)Xen_integer_to_C_int(on); return(C_int_to_Xen_integer((int)(cp->tracking_cursor_style))); break; case CP_SHOW_Y_ZERO: cp->show_y_zero = Xen_boolean_to_C_bool(on); update_graph(cp); return(C_bool_to_Xen_boolean(cp->show_y_zero)); break; case CP_SHOW_GRID: cp->show_grid = (with_grid_t)(Xen_boolean_to_C_bool(on)); update_graph(cp); return(C_bool_to_Xen_boolean((bool)(cp->show_grid))); break; case CP_GRID_DENSITY: curf = Xen_real_to_C_double(on); if (curf >= 0.0) cp->grid_density = curf; else Xen_out_of_range_error(S_set S_grid_density, 1, on, "density < 0.0?"); update_graph(cp); return(C_double_to_Xen_real(cp->grid_density)); break; case CP_SHOW_SONOGRAM_CURSOR: cp->show_sonogram_cursor = Xen_boolean_to_C_bool(on); update_graph(cp); return(C_bool_to_Xen_boolean(cp->show_sonogram_cursor)); break; case CP_SHOW_MARKS: cp->show_marks = Xen_boolean_to_C_bool(on); update_graph(cp); return(C_bool_to_Xen_boolean(cp->show_marks)); break; case CP_TIME_GRAPH_TYPE: cp->time_graph_type = (graph_type_t)Xen_integer_to_C_int(on); /* checked already */ update_graph(cp); return(C_int_to_Xen_integer((int)(cp->time_graph_type))); break; case CP_WAVO_HOP: cp->wavo_hop = g_imin(1, on, DEFAULT_WAVO_HOP); update_graph(cp); return(C_int_to_Xen_integer(cp->wavo_hop)); break; case CP_WAVO_TRACE: cp->wavo_trace = mus_iclamp(1, g_imin(1, on, DEFAULT_WAVO_TRACE), POINT_BUFFER_SIZE); update_graph(cp); return(C_int_to_Xen_integer(cp->wavo_trace)); break; case CP_MAX_TRANSFORM_PEAKS: cp->max_transform_peaks = g_imin(1, on, DEFAULT_MAX_TRANSFORM_PEAKS); return(C_int_to_Xen_integer(cp->max_transform_peaks)); break; case CP_ZERO_PAD: cp->zero_pad = mus_iclamp(0, g_imin(0, on, DEFAULT_ZERO_PAD), MAX_ZERO_PAD); update_graph(cp); return(C_int_to_Xen_integer(cp->zero_pad)); break; case CP_WAVELET_TYPE: cp->wavelet_type = Xen_integer_to_C_int(on); /* range checked already */ update_graph(cp); return(C_int_to_Xen_integer(cp->wavelet_type)); break; case CP_SHOW_TRANSFORM_PEAKS: cp->show_transform_peaks = Xen_boolean_to_C_bool(on); update_graph(cp); return(C_bool_to_Xen_boolean(cp->show_transform_peaks)); break; case CP_WITH_VERBOSE_CURSOR: cp->with_verbose_cursor = Xen_boolean_to_C_bool(on); return(C_bool_to_Xen_boolean(cp->with_verbose_cursor)); break; case CP_FFT_LOG_FREQUENCY: cp->fft_log_frequency = Xen_boolean_to_C_bool(on); if (cp->graph_transform_on) calculate_fft(cp); return(C_bool_to_Xen_boolean(cp->fft_log_frequency)); break; case CP_FFT_LOG_MAGNITUDE: cp->fft_log_magnitude = Xen_boolean_to_C_bool(on); if (cp->graph_transform_on) calculate_fft(cp); return(C_bool_to_Xen_boolean(cp->fft_log_magnitude)); break; case CP_FFT_WITH_PHASES: cp->fft_with_phases = Xen_boolean_to_C_bool(on); if (cp->graph_transform_on) calculate_fft(cp); return(C_bool_to_Xen_boolean(cp->fft_with_phases)); break; case CP_SPECTRO_HOP: cp->spectro_hop = g_imin(1, on, DEFAULT_SPECTRO_HOP); if (cp->graph_transform_on) calculate_fft(cp); return(C_int_to_Xen_integer(cp->spectro_hop)); break; case CP_TRANSFORM_SIZE: cp->transform_size = g_omin(1, on, DEFAULT_TRANSFORM_SIZE); calculate_fft(cp); return(C_llong_to_Xen_llong(cp->transform_size)); break; case CP_TRANSFORM_GRAPH_TYPE: cp->transform_graph_type = (graph_type_t)Xen_integer_to_C_int(on); /* checked already */ calculate_fft(cp); return(C_int_to_Xen_integer((int)(cp->transform_graph_type))); break; case CP_FFT_WINDOW: cp->fft_window = (mus_fft_window_t)Xen_integer_to_C_int(on); /* checked */ calculate_fft(cp); return(C_int_to_Xen_integer((int)(cp->fft_window))); break; case CP_TRANSFORM_TYPE: cp->transform_type = Xen_transform_to_C_int(on); calculate_fft(cp); return(C_int_to_Xen_transform(cp->transform_type)); break; case CP_TRANSFORM_NORMALIZATION: cp->transform_normalization = (fft_normalize_t)Xen_integer_to_C_int(on); /* range already checked */ calculate_fft(cp); return(C_int_to_Xen_integer((int)(cp->transform_normalization))); break; case CP_SHOW_MIX_WAVEFORMS: cp->show_mix_waveforms = Xen_boolean_to_C_bool(on); update_graph(cp); return(C_bool_to_Xen_boolean(cp->show_mix_waveforms)); break; case CP_TIME_GRAPH_STYLE: cp->time_graph_style = (Xen_is_integer(on)) ? (graph_style_t)Xen_integer_to_C_int(on) : DEFAULT_GRAPH_STYLE; if (call_update_graph) update_graph(cp); return(C_int_to_Xen_integer((int)(cp->time_graph_style))); break; case CP_LISP_GRAPH_STYLE: cp->lisp_graph_style = (Xen_is_integer(on)) ? (graph_style_t)Xen_integer_to_C_int(on) : DEFAULT_GRAPH_STYLE; if (call_update_graph) update_graph(cp); return(C_int_to_Xen_integer((int)(cp->lisp_graph_style))); break; case CP_TRANSFORM_GRAPH_STYLE: cp->transform_graph_style = (Xen_is_integer(on)) ? (graph_style_t)Xen_integer_to_C_int(on) : DEFAULT_GRAPH_STYLE; if (call_update_graph) update_graph(cp); return(C_int_to_Xen_integer((int)(cp->transform_graph_style))); break; case CP_X_AXIS_STYLE: val = Xen_integer_to_C_int(on); /* range already checked */ chans_x_axis_style(cp, val); return(C_int_to_Xen_integer((int)(cp->x_axis_style))); break; case CP_DOT_SIZE: cp->dot_size = mus_iclamp(MIN_DOT_SIZE, (Xen_is_integer(on)) ? Xen_integer_to_C_int(on) : DEFAULT_DOT_SIZE, MAX_DOT_SIZE); /* size > 17000 -> X segfault! */ update_graph(cp); return(C_int_to_Xen_integer(cp->dot_size)); break; case CP_SHOW_AXES: cp->show_axes = (show_axes_t)Xen_integer_to_C_int(on); /* range checked already */ update_graph(cp); return(C_int_to_Xen_integer((int)(cp->show_axes))); break; case CP_GRAPHS_HORIZONTAL: cp->graphs_horizontal = Xen_boolean_to_C_bool(on); update_graph(cp); return(C_bool_to_Xen_boolean(cp->graphs_horizontal)); break; case CP_FRAMPLES: if (cp->editable) { mus_long_t curlen, newlen; bool need_update = true; /* if less than current, delete, else zero pad */ curlen = current_samples(cp); newlen = (Xen_is_llong(on)) ? Xen_llong_to_C_llong(on) : curlen; if (newlen < 0) Xen_out_of_range_error(S_set S_framples, 1, on, "framples < 0?"); if (curlen > newlen) { if (newlen > 0) need_update = delete_samples(newlen - 1, curlen - newlen, cp, cp->edit_ctr); else need_update = delete_samples(0, curlen, cp, cp->edit_ctr); } else { if (newlen > curlen) extend_with_zeros(cp, curlen, newlen - curlen, cp->edit_ctr, S_set S_framples); } if (need_update) update_graph(cp); } break; case CP_PROPERTIES: if (!(Xen_is_vector(cp->properties))) { cp->properties = Xen_make_vector(1, Xen_empty_list); cp->properties_loc = snd_protect(cp->properties); } Xen_vector_set(cp->properties, 0, on); return(Xen_vector_ref(cp->properties, 0)); break; case CP_SX: reset_x_display(cp, mus_fclamp(0.0, Xen_real_to_C_double(on), 1.0), cp->axis->zx); break; case CP_ZX: cp->axis->zx = mus_fclamp(0.0, Xen_real_to_C_double(on), 1.0); focus_x_axis_change(cp, zoom_focus_style(ss)); resize_sx_and_zx(cp); break; case CP_SY: reset_y_display(cp, mus_fclamp(0.0, Xen_real_to_C_double(on), 1.0), cp->axis->zy); break; case CP_ZY: reset_y_display(cp, cp->axis->sy, mus_fclamp(0.0, Xen_real_to_C_double(on), 1.0)); break; case CP_MIN_DB: curamp = Xen_real_to_C_double(on); if (curamp < 0.0) { cp->min_dB = curamp; cp->lin_dB = pow(10.0, cp->min_dB * 0.05); calculate_fft(cp); } else Xen_out_of_range_error(caller, 1, on, S_min_dB " should be < 0.0"); break; case CP_SPECTRO_X_ANGLE: cp->spectro_x_angle = mus_fclamp(MIN_SPECTRO_ANGLE, Xen_real_to_C_double(on), MAX_SPECTRO_ANGLE); calculate_fft(cp); break; case CP_SPECTRO_Y_ANGLE: cp->spectro_y_angle = mus_fclamp(MIN_SPECTRO_ANGLE, Xen_real_to_C_double(on), MAX_SPECTRO_ANGLE); calculate_fft(cp); break; case CP_SPECTRO_Z_ANGLE: cp->spectro_z_angle = mus_fclamp(MIN_SPECTRO_ANGLE, Xen_real_to_C_double(on), MAX_SPECTRO_ANGLE); calculate_fft(cp); break; case CP_SPECTRO_X_SCALE: cp->spectro_x_scale = mus_fclamp(0.0, Xen_real_to_C_double(on), MAX_SPECTRO_SCALE); calculate_fft(cp); break; case CP_SPECTRO_Y_SCALE: cp->spectro_y_scale = mus_fclamp(0.0, Xen_real_to_C_double(on), MAX_SPECTRO_SCALE); calculate_fft(cp); break; case CP_SPECTRO_Z_SCALE: cp->spectro_z_scale = mus_fclamp(0.0, Xen_real_to_C_double(on), MAX_SPECTRO_SCALE); calculate_fft(cp); break; case CP_SPECTRUM_END: cp->spectrum_end = Xen_real_to_C_double(on); /* range checked already */ calculate_fft(cp); return(C_double_to_Xen_real(cp->spectrum_end)); break; case CP_SPECTRUM_START: cp->spectrum_start = Xen_real_to_C_double(on); /* range checked already */ calculate_fft(cp); return(C_double_to_Xen_real(cp->spectrum_start)); break; case CP_FFT_WINDOW_ALPHA: cp->fft_window_alpha = Xen_real_to_C_double(on); calculate_fft(cp); return(C_double_to_Xen_real(cp->fft_window_alpha)); break; case CP_FFT_WINDOW_BETA: cp->fft_window_beta = Xen_real_to_C_double(on); /* range checked already */ calculate_fft(cp); return(C_double_to_Xen_real(cp->fft_window_beta)); break; case CP_MAXAMP: if (cp->editable) { mus_float_t newamp[1]; curamp = channel_maxamp(cp, AT_CURRENT_EDIT_POSITION); newamp[0] = Xen_real_to_C_double(on); if (curamp != newamp[0]) { if (scale_to(cp->sound, cp, newamp, 1, false)) update_graph(cp); } } break; case CP_BEATS_PER_MINUTE: curamp = Xen_real_to_C_double(on); if (curamp > 0.0) { cp->beats_per_minute = curamp; update_graph(cp); } break; case CP_BEATS_PER_MEASURE: cp->beats_per_measure = Xen_integer_to_C_int(on); update_graph(cp); return(on); break; default: break; } return(C_bool_to_Xen_boolean(val)); } static Xen g_update_time_graph(Xen snd, Xen chn) { #define H_update_time_graph "(" S_update_time_graph " :optional snd chn): redraw snd channel chn's graphs" return(channel_get(snd, chn, CP_UPDATE_TIME, S_update_time_graph)); } static Xen g_update_transform_graph(Xen snd, Xen chn) { #define H_update_transform_graph "(" S_update_transform_graph " :optional snd chn): redraw snd channel chn's fft display" return(channel_get(snd, chn, CP_UPDATE_TRANSFORM_GRAPH, S_update_transform_graph)); } static Xen g_update_lisp_graph(Xen snd, Xen chn) { #define H_update_lisp_graph "(" S_update_lisp_graph " :optional snd chn): redraw snd channel chn's lisp graph" return(channel_get(snd, chn, CP_UPDATE_LISP, S_update_lisp_graph)); } static Xen g_edit_position(Xen snd, Xen chn_n) { #define H_edit_position "(" S_edit_position " :optional snd chn): current edit history position in snd's channel chn" return(channel_get(snd, chn_n, CP_EDIT_CTR, S_edit_position)); } static Xen g_set_edit_position(Xen on, Xen snd, Xen chn_n) { Xen_check_type(Xen_is_integer(on), on, 1, S_set S_edit_position, "an integer"); return(channel_set(snd, chn_n, on, CP_EDIT_CTR, S_set S_edit_position)); } with_three_setter_args(g_set_edit_position_reversed, g_set_edit_position) static Xen g_transform_graph_on(Xen snd, Xen chn_n) { #define H_transform_graph_on "(" S_transform_graph_on " :optional snd chn): " PROC_TRUE " if fft display is active in snd's channel chn" return(channel_get(snd, chn_n, CP_GRAPH_TRANSFORM_ON, S_transform_graph_on)); } static Xen g_set_transform_graph_on(Xen on, Xen snd, Xen chn_n) { Xen_check_type(Xen_is_boolean(on), on, 1, S_set S_transform_graph_on, "a boolean"); return(channel_set(snd, chn_n, on, CP_GRAPH_TRANSFORM_ON, S_set S_transform_graph_on)); } with_three_setter_args(g_set_transform_graph_on_reversed, g_set_transform_graph_on) static Xen g_timer_graph_on(Xen snd, Xen chn_n) { #define H_timer_graph_on "(" S_time_graph_on " :optional snd chn): " PROC_TRUE " if time domain display is active in snd's channel chn" return(channel_get(snd, chn_n, CP_GRAPH_TIME_ON, S_time_graph_on)); } static Xen g_set_timer_graph_on(Xen on, Xen snd, Xen chn_n) { Xen_check_type(Xen_is_boolean(on), on, 1, S_set S_time_graph_on, "a boolean"); return(channel_set(snd, chn_n, on, CP_GRAPH_TIME_ON, S_set S_time_graph_on)); } with_three_setter_args(g_set_timer_graph_on_reversed, g_set_timer_graph_on) static Xen g_lisp_graph_on(Xen snd, Xen chn_n) { #define H_lisp_graph_on "(" S_lisp_graph_on " :optional snd chn): " PROC_TRUE " if lisp-generated data display is active in snd's channel chn" return(channel_get(snd, chn_n, CP_GRAPH_LISP_ON, S_lisp_graph_on)); } static Xen g_set_lisp_graph_on(Xen on, Xen snd, Xen chn_n) { Xen_check_type(Xen_is_boolean(on), on, 1, S_set S_lisp_graph_on, "a boolean"); return(channel_set(snd, chn_n, on, CP_GRAPH_LISP_ON, S_set S_lisp_graph_on)); } with_three_setter_args(g_set_lisp_graph_on_reversed, g_set_lisp_graph_on) static Xen g_cursor(Xen snd, Xen chn_n, Xen edpos) { #define H_cursor "(" S_cursor " :optional snd chn edpos): current cursor location in snd's channel chn" if (Xen_is_bound(edpos)) { Xen res; if (cp_edpos_loc != NOT_A_GC_LOC) snd_unprotect_at(cp_edpos_loc); cp_edpos = edpos; cp_edpos_loc = snd_protect(cp_edpos); res = channel_get(snd, chn_n, CP_EDPOS_CURSOR, S_cursor); snd_unprotect_at(cp_edpos_loc); cp_edpos_loc = NOT_A_GC_LOC; return(res); } return(channel_get(snd, chn_n, CP_CURSOR, S_cursor)); } static Xen g_set_cursor(Xen on, Xen snd, Xen chn_n, Xen edpos) { Xen_check_type(Xen_is_llong(on) || !Xen_is_bound(on), on, 1, S_set S_cursor, "an integer"); if (Xen_is_bound(edpos)) { Xen res; if (cp_edpos_loc != NOT_A_GC_LOC) snd_unprotect_at(cp_edpos_loc); cp_edpos = edpos; cp_edpos_loc = snd_protect(cp_edpos); res = channel_set(snd, chn_n, on, CP_EDPOS_CURSOR, S_set S_cursor); snd_unprotect_at(cp_edpos_loc); cp_edpos_loc = NOT_A_GC_LOC; return(res); } return(channel_set(snd, chn_n, on, CP_CURSOR, S_set S_cursor)); } with_four_setter_args(g_set_cursor_reversed, g_set_cursor) static Xen g_cursor_style(Xen snd, Xen chn_n) { #define H_cursor_style "(" S_cursor_style " :optional snd chn): current cursor style in snd's channel chn. \ Possible values are " S_cursor_cross " (default), " S_cursor_line " (a vertical line), or a procedure of three arguments, the \ sound index, channel number, and graph (always " S_time_graph "). The procedure \ should draw the cursor at the current cursor position using the " S_cursor_context "." if (Xen_is_bound(snd)) return(channel_get(snd, chn_n, CP_CURSOR_STYLE, S_cursor_style)); if (cursor_style(ss) == CURSOR_PROC) return(ss->cursor_proc); return(C_int_to_Xen_integer((int)(cursor_style(ss)))); } static Xen g_set_cursor_style(Xen on, Xen snd, Xen chn_n) { cursor_style_t val = CURSOR_PROC; Xen_check_type(Xen_is_integer(on) || Xen_is_procedure(on), on, 1, S_set S_cursor_style, "an integer or a function"); if (Xen_is_integer(on)) { int choice; choice = Xen_integer_to_C_int(on); if (choice < 0) Xen_out_of_range_error(S_set S_cursor_style, 1, on, S_cursor_style " should be " S_cursor_cross " or " S_cursor_line ", or a procedure"); val = (cursor_style_t)choice; if (val > CURSOR_LINE) Xen_out_of_range_error(S_set S_cursor_style, 1, on, S_cursor_style " should be " S_cursor_cross " or " S_cursor_line ", or a procedure"); } if (Xen_is_bound(snd)) return(channel_set(snd, chn_n, on, CP_CURSOR_STYLE, S_set S_cursor_style)); else { if (Xen_is_procedure(on)) { char *error; error = procedure_ok(on, 3, S_cursor_style, "", 1); if (error == NULL) { if ((cursor_style(ss) == CURSOR_PROC) && (Xen_is_procedure(ss->cursor_proc))) snd_unprotect_at(ss->cursor_proc_loc); ss->cursor_proc_loc = snd_protect(on); ss->cursor_proc = on; in_set_cursor_style(CURSOR_PROC); } else { Xen errstr; errstr = C_string_to_Xen_string(error); free(error); return(snd_bad_arity_error(S_set S_cursor_style, errstr, on)); } } set_cursor_style(val); return(on); } } with_three_setter_args(g_set_cursor_style_reversed, g_set_cursor_style) static Xen g_tracking_cursor_style(Xen snd, Xen chn_n) { #define H_tracking_cursor_style "(" S_tracking_cursor_style " :optional snd chn): current tracking cursor style in snd's channel chn. \ Possible values are " S_cursor_cross " (default), and " S_cursor_line "." if (Xen_is_bound(snd)) return(channel_get(snd, chn_n, CP_TRACKING_CURSOR_STYLE, S_tracking_cursor_style)); return(C_int_to_Xen_integer((int)(tracking_cursor_style(ss)))); } static Xen g_set_tracking_cursor_style(Xen on, Xen snd, Xen chn_n) { int in_val; cursor_style_t val = CURSOR_CROSS; Xen_check_type(Xen_is_integer(on), on, 1, S_set S_tracking_cursor_style, "an integer"); in_val = Xen_integer_to_C_int(on); if (in_val < 0) Xen_out_of_range_error(S_set S_tracking_cursor_style, 1, on, S_tracking_cursor_style " should be " S_cursor_cross " or " S_cursor_line); val = (cursor_style_t)in_val; if (val > CURSOR_LINE) Xen_out_of_range_error(S_set S_tracking_cursor_style, 1, on, S_tracking_cursor_style " should be " S_cursor_cross " or " S_cursor_line); if (Xen_is_bound(snd)) return(channel_set(snd, chn_n, on, CP_TRACKING_CURSOR_STYLE, S_set S_tracking_cursor_style)); else set_tracking_cursor_style(val); return(on); } with_three_setter_args(g_set_tracking_cursor_style_reversed, g_set_tracking_cursor_style) static Xen g_cursor_size(Xen snd, Xen chn_n) { #define H_cursor_size "(" S_cursor_size " :optional snd chn): current cursor size in snd's channel chn" if (Xen_is_bound(snd)) return(channel_get(snd, chn_n, CP_CURSOR_SIZE, S_cursor_size)); return(C_int_to_Xen_integer(cursor_size(ss))); } static Xen g_set_cursor_size(Xen on, Xen snd, Xen chn_n) { Xen_check_type(Xen_is_integer(on) && (Xen_integer_to_C_int(on) > 0), on, 1, S_set S_cursor_size, "an integer"); if (Xen_is_bound(snd)) return(channel_set(snd, chn_n, on, CP_CURSOR_SIZE, S_set S_cursor_size)); set_cursor_size(Xen_integer_to_C_int(on)); return(C_int_to_Xen_integer(cursor_size(ss))); } with_three_setter_args(g_set_cursor_size_reversed, g_set_cursor_size) static Xen g_cursor_position(Xen snd, Xen chn) { #define H_cursor_position "(" S_cursor_position " :optional snd chn): current cursor position (x y in pixels) in snd's channel chn" return(channel_get(snd, chn, CP_CURSOR_POSITION, S_cursor_position)); } Xen g_framples(Xen snd, Xen chn, Xen edpos) { #define H_framples "(" S_framples " :optional snd-or-object chn edpos): number of framples of data in the given object or channel" if (!(Xen_is_bound(chn))) { if ((xen_is_sound(snd)) || (!Xen_is_bound(snd))) return(channel_get(snd, chn, CP_FRAMPLES, S_framples)); if (Xen_is_string(snd)) return(g_mus_sound_framples(snd)); /* mus-sound-framples */ if (mus_is_xen(snd)) /* mus-length */ return(g_mus_length(snd)); if (mus_is_vct(snd)) /* vct-length */ return(C_llong_to_Xen_llong(mus_vct_length(Xen_to_vct(snd)))); if (xen_is_mix(snd)) /* mix-length */ return(g_mix_length(snd)); if (xen_is_region(snd)) /* region-framples */ return(g_region_framples(snd, Xen_integer_zero)); if (xen_is_player(snd)) { snd_info *sp; sp = get_player_sound(snd); return(C_llong_to_Xen_llong(current_samples(sp->chans[0]))); } } if (xen_is_selection(snd)) return(g_selection_framples(chn, edpos)); if (Xen_is_bound(edpos)) { Xen res; if (cp_edpos_loc != NOT_A_GC_LOC) snd_unprotect_at(cp_edpos_loc); cp_edpos = edpos; cp_edpos_loc = snd_protect(cp_edpos); res = channel_get(snd, chn, CP_EDPOS_FRAMPLES, S_framples); snd_unprotect_at(cp_edpos_loc); cp_edpos_loc = NOT_A_GC_LOC; return(res); } return(channel_get(snd, chn, CP_FRAMPLES, S_framples)); } static Xen g_set_framples(Xen on, Xen snd, Xen chn_n) { Xen_check_type(Xen_is_number(on), on, 1, S_set S_framples, "a number"); return(channel_set(snd, chn_n, on, CP_FRAMPLES, S_set S_framples)); } with_three_setter_args(g_set_framples_reversed, g_set_framples) static Xen g_vector_maxamp(Xen obj) { double mx = 0.0; int i, len; len = Xen_vector_length(obj); for (i = 0; i < len; i++) { Xen el; el = Xen_vector_ref(obj, i); if (Xen_is_number(el)) { double temp; temp = fabs(Xen_real_to_C_double(el)); if (temp > mx) mx = temp; } /* should we trigger an error here? */ } return(C_double_to_Xen_real(mx)); } static Xen g_maxamp(Xen snd, Xen chn_n, Xen edpos) { #define H_maxamp "(" S_maxamp " :optional snd chn edpos): maxamp of data in the object 'snd', or in snd's channel chn if snd is a sound" if (!(Xen_is_bound(chn_n))) { if (Xen_is_string(snd)) /* string => mus_sound_maxamp */ return(Xen_cadr(g_mus_sound_maxamp(snd))); if (mus_is_xen(snd)) /* maxamp of mus-data */ { Xen v; v = g_mus_data(snd); if (mus_is_vct(v)) return(g_vct_peak(v)); } if (mus_is_vct(snd)) /* vct-peak */ return(g_vct_peak(snd)); if (xen_is_mix(snd)) /* mix => sound maxamp of the mix data */ return(g_mix_maxamp(snd)); if (xen_is_region(snd)) /* region-maxamp */ return(g_region_maxamp(snd)); if (Xen_is_vector(snd)) return(g_vector_maxamp(snd)); } if (xen_is_selection(snd)) /* selection-maxamp where chn=snd and edpos=chn */ return(g_selection_maxamp(chn_n, edpos)); if (Xen_is_bound(edpos)) { Xen res; if (cp_edpos_loc != NOT_A_GC_LOC) snd_unprotect_at(cp_edpos_loc); cp_edpos = edpos; cp_edpos_loc = snd_protect(cp_edpos); res = channel_get(snd, chn_n, CP_EDPOS_MAXAMP, S_maxamp); snd_unprotect_at(cp_edpos_loc); cp_edpos_loc = NOT_A_GC_LOC; return(res); } if ((Xen_is_bound(chn_n)) || (Xen_is_true(snd))) return(channel_get(snd, chn_n, CP_MAXAMP, S_maxamp)); /* calls channel_maxamp */ Snd_assert_sound(S_maxamp, snd, 0); { snd_info *sp; sp = get_sp(snd); if (sp) { int i; mus_float_t mx = 0.0; mus_float_t *vals = NULL; bool save_maxamp = true; for (i = 0; i < sp->nchans; i++) if (sp->chans[i]->edit_ctr != 0) { save_maxamp = false; break; } if (save_maxamp) { mus_long_t *times = NULL; /* fprintf(stderr, "save g_maxamp for %s (%d %lld)\n", sp->filename, mus_sound_maxamp_exists(sp->filename), sp->chans[0]->edits[0]->samples); */ vals = (mus_float_t *)calloc(sp->nchans, sizeof(mus_float_t)); times = (mus_long_t *)calloc(sp->nchans, sizeof(mus_long_t)); for (i = 0; i < sp->nchans; i++) { chan_info *ncp; mus_long_t pos = 0; ncp = sp->chans[i]; vals[i] = channel_maxamp_and_position(ncp, 0, &pos); if (vals[i] > mx) mx = vals[i]; times[i] = pos; } mus_sound_set_maxamps(sp->filename, sp->nchans, vals, times); free(vals); free(times); return(C_double_to_Xen_real(mx)); } for (i = 0; i < sp->nchans; i++) { mus_float_t cur_mx; cur_mx = channel_maxamp(sp->chans[i], sp->chans[i]->edit_ctr); if (cur_mx > mx) mx = cur_mx; } return(C_double_to_Xen_real(mx)); } else snd_no_such_sound_error(S_maxamp, snd); } return(Xen_integer_zero); } static Xen g_set_maxamp(Xen on, Xen snd, Xen chn_n) { Xen_check_type(Xen_is_number(on), on, 1, S_set S_maxamp, "a number"); return(channel_set(snd, chn_n, on, CP_MAXAMP, S_set S_maxamp)); } with_three_setter_args(g_set_maxamp_reversed, g_set_maxamp) static Xen g_maxamp_position(Xen snd, Xen chn_n, Xen edpos) { #define H_maxamp_position "(" S_maxamp_position " :optional snd chn edpos): location of maxamp of data in snd's channel chn" if (Xen_is_bound(edpos)) { Xen res; if (cp_edpos_loc != NOT_A_GC_LOC) snd_unprotect_at(cp_edpos_loc); cp_edpos = edpos; cp_edpos_loc = snd_protect(cp_edpos); res = channel_get(snd, chn_n, CP_EDPOS_MAXAMP_POSITION, S_maxamp_position); snd_unprotect_at(cp_edpos_loc); cp_edpos_loc = NOT_A_GC_LOC; return(res); } return(channel_get(snd, chn_n, CP_MAXAMP_POSITION, S_maxamp_position)); } static Xen g_squelch_update(Xen snd, Xen chn_n) { #define H_squelch_update "(" S_squelch_update " :optional snd chn): " PROC_TRUE " if updates (redisplays) are turned off in snd's channel chn" return(channel_get(snd, chn_n, CP_SQUELCH_UPDATE, S_squelch_update)); } static Xen g_set_squelch_update(Xen on, Xen snd, Xen chn_n) { Xen_check_type(Xen_is_boolean(on), on, 1, S_set S_squelch_update, "a boolean"); return(channel_set(snd, chn_n, on, CP_SQUELCH_UPDATE, S_set S_squelch_update)); } with_three_setter_args(g_set_squelch_update_reversed, g_set_squelch_update) static Xen g_ap_sx(Xen snd, Xen chn_n) { #define H_x_position_slider "(" S_x_position_slider " :optional snd chn): current x axis position slider of snd channel chn" return(channel_get(snd, chn_n, CP_SX, S_x_position_slider)); } static Xen g_set_ap_sx(Xen on, Xen snd, Xen chn_n) { Xen_check_type(Xen_is_number(on), on, 1, S_set S_x_position_slider, "a number"); return(channel_set(snd, chn_n, on, CP_SX, S_set S_x_position_slider)); } with_three_setter_args(g_set_ap_sx_reversed, g_set_ap_sx) static Xen g_ap_sy(Xen snd, Xen chn_n) { #define H_y_position_slider "(" S_y_position_slider " :optional snd chn): current y axis position slider of snd channel chn" return(channel_get(snd, chn_n, CP_SY, S_y_position_slider)); } static Xen g_set_ap_sy(Xen on, Xen snd, Xen chn_n) { Xen_check_type(Xen_is_number(on), on, 1, S_set S_y_position_slider, "a number"); return(channel_set(snd, chn_n, on, CP_SY, S_set S_y_position_slider)); } with_three_setter_args(g_set_ap_sy_reversed, g_set_ap_sy) static Xen g_ap_zx(Xen snd, Xen chn_n) { #define H_x_zoom_slider "(" S_x_zoom_slider " :optional snd chn): current x axis zoom slider of snd channel chn" return(channel_get(snd, chn_n, CP_ZX, S_x_zoom_slider)); } static Xen g_set_ap_zx(Xen on, Xen snd, Xen chn_n) { Xen_check_type(Xen_is_number(on), on, 1, S_set S_x_zoom_slider, "a number"); return(channel_set(snd, chn_n, on, CP_ZX, S_set S_x_zoom_slider)); } with_three_setter_args(g_set_ap_zx_reversed, g_set_ap_zx) static Xen g_ap_zy(Xen snd, Xen chn_n) { #define H_y_zoom_slider "(" S_y_zoom_slider " :optional snd chn): current y axis zoom slider of snd channel chn" return(channel_get(snd, chn_n, CP_ZY, S_y_zoom_slider)); } static Xen g_set_ap_zy(Xen on, Xen snd, Xen chn_n) { Xen_check_type(Xen_is_number(on), on, 1, S_set S_y_zoom_slider, "a number"); return(channel_set(snd, chn_n, on, CP_ZY, S_set S_y_zoom_slider)); } with_three_setter_args(g_set_ap_zy_reversed, g_set_ap_zy) static Xen g_edit_hook(Xen snd, Xen chn_n) { #if HAVE_SCHEME #define edit_hook_example "(hook-push (" S_edit_hook " snd chn) (lambda () (" S_snd_print " \";about to edit\") #f))" #endif #if HAVE_RUBY #define edit_hook_example "edit_hook(snd, chn).add_hook!(\"hook-test\") do | | snd_print(\"about to edit\"); false end" #endif #if HAVE_FORTH #define edit_hook_example "snd chn edit-hook lambda: <{ }> \"about to edit\" snd-print drop #f ; add-hook!" #endif #define H_edit_hook "(" S_edit_hook " :optional snd chn): snd's channel chn's " S_edit_hook ". \ This is a channel-specific hook variable; " S_edit_hook " is called just before any attempt to edit the channel's data; if it returns " PROC_TRUE ", \ the edit is aborted. \n " edit_hook_example return(channel_get(snd, chn_n, CP_EDIT_HOOK, S_edit_hook)); } static Xen g_after_edit_hook(Xen snd, Xen chn_n) { #if HAVE_SCHEME #define after_edit_hook_example "(hook-push (" S_after_edit_hook " snd chn) (lambda () (" S_snd_print " \";just edited\")))" #endif #if HAVE_RUBY #define after_edit_hook_example "after_edit_hook(snd, chn).add_hook!(\"hook-test\") do | | snd_print(\"just edited\") end" #endif #if HAVE_FORTH #define after_edit_hook_example "snd chn after-edit-hook lambda: <{ }> \"just edited\" snd-print drop ; add-hook!" #endif #define H_after_edit_hook "(" S_after_edit_hook " :optional snd chn): snd's channel chn's " S_after_edit_hook ". \ This is a channel-specific hook variable; " S_after_edit_hook " is called after an edit, but before " S_after_graph_hook ". \n " after_edit_hook_example return(channel_get(snd, chn_n, CP_AFTER_EDIT_HOOK, S_after_edit_hook)); } static Xen g_undo_hook(Xen snd, Xen chn_n) { #define H_undo_hook "(" S_undo_hook " :optional snd chn): snd's channel chn's " S_undo_hook ". \ This is a channel-specific hook variable; " S_undo_hook " is called just after any undo, redo, or revert that affects the channel." return(channel_get(snd, chn_n, CP_UNDO_HOOK, S_undo_hook)); } static Xen g_show_y_zero(Xen snd, Xen chn) { #define H_show_y_zero "(" S_show_y_zero " :optional snd chn): " PROC_TRUE " if Snd should include a line at y = 0.0" if (Xen_is_bound(snd)) return(channel_get(snd, chn, CP_SHOW_Y_ZERO, S_show_y_zero)); return(C_bool_to_Xen_boolean(show_y_zero(ss))); } static void chans_zero(chan_info *cp, bool value) { cp->show_y_zero = value; update_graph(cp); } void set_show_y_zero(bool val) { in_set_show_y_zero(val); for_each_chan_with_bool(chans_zero, val); } static Xen g_set_show_y_zero(Xen on, Xen snd, Xen chn) { Xen_check_type(Xen_is_boolean(on), on, 1, S_set S_show_y_zero, "a boolean"); if (Xen_is_bound(snd)) return(channel_set(snd, chn, on, CP_SHOW_Y_ZERO, S_set S_show_y_zero)); set_show_y_zero(Xen_boolean_to_C_bool(on)); return(C_bool_to_Xen_boolean(show_y_zero(ss))); } with_three_setter_args(g_set_show_y_zero_reversed, g_set_show_y_zero) static Xen g_show_grid(Xen snd, Xen chn) { #define H_show_grid "(" S_show_grid " :optional snd chn): " PROC_TRUE " if Snd should display a background grid in the graphs" if (Xen_is_bound(snd)) return(channel_get(snd, chn, CP_SHOW_GRID, S_show_grid)); return(C_bool_to_Xen_boolean((bool)show_grid(ss))); } static Xen g_set_show_grid(Xen on, Xen snd, Xen chn) { Xen_check_type(Xen_is_boolean(on), on, 1, S_set S_show_grid, "a boolean"); if (Xen_is_bound(snd)) return(channel_set(snd, chn, on, CP_SHOW_GRID, S_set S_show_grid)); set_show_grid((with_grid_t)(Xen_boolean_to_C_bool(on))); return(C_bool_to_Xen_boolean((bool)show_grid(ss))); } with_three_setter_args(g_set_show_grid_reversed, g_set_show_grid) static Xen g_grid_density(Xen snd, Xen chn) { #define H_grid_density "(" S_grid_density " :optional snd chn): sets how closely axis ticks are spaced, default=1.0" if (Xen_is_bound(snd)) return(channel_get(snd, chn, CP_GRID_DENSITY, S_grid_density)); return(C_double_to_Xen_real(grid_density(ss))); } static Xen g_set_grid_density(Xen on, Xen snd, Xen chn) { mus_float_t curf; Xen_check_type(Xen_is_number(on), on, 1, S_set S_grid_density, "a number"); if (Xen_is_bound(snd)) return(channel_set(snd, chn, on, CP_GRID_DENSITY, S_set S_grid_density)); curf = Xen_real_to_C_double(on); if (curf >= 0.0) set_grid_density(curf); else Xen_out_of_range_error(S_set S_grid_density, 1, on, "density < 0.0?"); return(C_double_to_Xen_real(grid_density(ss))); } with_three_setter_args(g_set_grid_density_reversed, g_set_grid_density) static Xen g_show_sonogram_cursor(Xen snd, Xen chn) { #define H_show_sonogram_cursor "(" S_show_sonogram_cursor " :optional snd chn): " PROC_TRUE " if Snd should display a cursor in the sonogram" if (Xen_is_bound(snd)) return(channel_get(snd, chn, CP_SHOW_SONOGRAM_CURSOR, S_show_sonogram_cursor)); return(C_bool_to_Xen_boolean((bool)show_sonogram_cursor(ss))); } static Xen g_set_show_sonogram_cursor(Xen on, Xen snd, Xen chn) { Xen_check_type(Xen_is_boolean(on), on, 1, S_set S_show_sonogram_cursor, "a boolean"); if (Xen_is_bound(snd)) return(channel_set(snd, chn, on, CP_SHOW_SONOGRAM_CURSOR, S_set S_show_sonogram_cursor)); set_show_sonogram_cursor(Xen_boolean_to_C_bool(on)); return(C_bool_to_Xen_boolean(show_sonogram_cursor(ss))); } with_three_setter_args(g_set_show_sonogram_cursor_reversed, g_set_show_sonogram_cursor) static Xen g_min_dB(Xen snd, Xen chn) { #define H_min_dB "(" S_min_dB " :optional snd chn): min dB value displayed in fft graphs using dB scales (default: -60)" if (Xen_is_bound(snd)) return(channel_get(snd, chn, CP_MIN_DB, S_min_dB)); return(C_double_to_Xen_real(min_dB(ss))); } static void update_db_graph(chan_info *cp, mus_float_t new_db) { cp->min_dB = new_db; cp->lin_dB = pow(10.0, cp->min_dB * 0.05); if ((cp->active < CHANNEL_HAS_AXES) || (cp->sounds == NULL) || (cp->sounds[cp->sound_ctr] == NULL) || (!(cp->graph_transform_on)) || (!(cp->fft_log_magnitude)) || (chan_fft_in_progress(cp))) return; calculate_fft(cp); } void set_min_db(mus_float_t db) { set_min_dB(db); ss->lin_dB = pow(10.0, db * 0.05); for_each_chan_with_float(update_db_graph, db); } static Xen g_set_min_dB(Xen val, Xen snd, Xen chn) { Xen_check_type(Xen_is_number(val), val, 1, S_set S_min_dB, "a number"); if (Xen_is_bound(snd)) return(channel_set(snd, chn, val, CP_MIN_DB, S_set S_min_dB)); else { mus_float_t db; db = Xen_real_to_C_double(val); if (db < 0.0) { set_min_db(db); reflect_min_db_in_transform_dialog(); } else Xen_out_of_range_error(S_set S_min_dB, 1, val, S_min_dB " should be < 0.0"); return(C_double_to_Xen_real(min_dB(ss))); } } with_three_setter_args(g_set_min_dB_reversed, g_set_min_dB) static Xen g_fft_window_beta(Xen snd, Xen chn) { #define H_fft_window_beta "(" S_fft_window_beta " :optional snd chn): fft window beta parameter value" if (Xen_is_bound(snd)) return(channel_get(snd, chn, CP_FFT_WINDOW_BETA, S_fft_window_beta)); return(C_double_to_Xen_real(fft_window_beta(ss))); } static Xen g_set_fft_window_beta(Xen val, Xen snd, Xen chn) { mus_float_t beta; Xen_check_type(Xen_is_number(val), val, 1, S_set S_fft_window_beta, "a number"); beta = Xen_real_to_C_double(val); if ((beta < 0.0) || (beta > 1.0)) Xen_out_of_range_error(S_set S_fft_window_beta, 1, val, S_fft_window_beta " should be between 0.0 and 1.0"); if (Xen_is_bound(snd)) return(channel_set(snd, chn, val, CP_FFT_WINDOW_BETA, S_set S_fft_window_beta)); set_fft_window_beta(beta); return(C_double_to_Xen_real(fft_window_beta(ss))); } with_three_setter_args(g_set_fft_window_beta_reversed, g_set_fft_window_beta) static Xen g_fft_window_alpha(Xen snd, Xen chn) { #define H_fft_window_alpha "(" S_fft_window_alpha " :optional snd chn): fft window alpha parameter value" if (Xen_is_bound(snd)) return(channel_get(snd, chn, CP_FFT_WINDOW_ALPHA, S_fft_window_alpha)); return(C_double_to_Xen_real(fft_window_alpha(ss))); } static Xen g_set_fft_window_alpha(Xen val, Xen snd, Xen chn) { mus_float_t alpha; Xen_check_type(Xen_is_number(val), val, 1, S_set S_fft_window_alpha, "a number"); alpha = Xen_real_to_C_double(val); if ((alpha < 0.0) || (alpha > 10.0)) Xen_out_of_range_error(S_set S_fft_window_alpha, 1, val, S_fft_window_alpha " should be between 0.0 and 10.0"); if (Xen_is_bound(snd)) return(channel_set(snd, chn, val, CP_FFT_WINDOW_ALPHA, S_set S_fft_window_alpha)); set_fft_window_alpha(alpha); return(C_double_to_Xen_real(fft_window_alpha(ss))); } with_three_setter_args(g_set_fft_window_alpha_reversed, g_set_fft_window_alpha) static Xen g_spectrum_end(Xen snd, Xen chn) { #define H_spectrum_end "(" S_spectrum_end " :optional snd chn): max frequency shown in spectra (1.0 = srate/2)" if (Xen_is_bound(snd)) return(channel_get(snd, chn, CP_SPECTRUM_END, S_spectrum_end)); return(C_double_to_Xen_real(spectrum_end(ss))); } static Xen g_set_spectrum_end(Xen val, Xen snd, Xen chn) { mus_float_t cutoff; Xen_check_type(Xen_is_number(val), val, 1, S_set S_spectrum_end, "a number"); cutoff = Xen_real_to_C_double(val); if ((cutoff < 0.0) || (cutoff > 1.0)) Xen_out_of_range_error(S_set S_spectrum_end, 1, val, S_spectrum_end " should be between 0.0 and 1.0"); if (Xen_is_bound(snd)) return(channel_set(snd, chn, val, CP_SPECTRUM_END, S_set S_spectrum_end)); set_spectrum_end(cutoff); return(C_double_to_Xen_real(spectrum_end(ss))); } with_three_setter_args(g_set_spectrum_end_reversed, g_set_spectrum_end) static Xen g_spectrum_start(Xen snd, Xen chn) { #define H_spectrum_start "(" S_spectrum_start " :optional snd chn): lower bound of frequency in spectral displays (0.0)" if (Xen_is_bound(snd)) return(channel_get(snd, chn, CP_SPECTRUM_START, S_spectrum_start)); return(C_double_to_Xen_real(spectrum_start(ss))); } static Xen g_set_spectrum_start(Xen val, Xen snd, Xen chn) { mus_float_t start; Xen_check_type(Xen_is_number(val), val, 1, S_set S_spectrum_start, "a number"); start = Xen_real_to_C_double(val); if ((start < 0.0) || (start > 1.0)) Xen_out_of_range_error(S_set S_spectrum_start, 1, val, S_spectrum_start " should be between 0.0 and 1.0"); if (Xen_is_bound(snd)) return(channel_set(snd, chn, val, CP_SPECTRUM_START, S_set S_spectrum_start)); set_spectrum_start(start); return(C_double_to_Xen_real(spectrum_start(ss))); } with_three_setter_args(g_set_spectrum_start_reversed, g_set_spectrum_start) static Xen g_spectro_x_angle(Xen snd, Xen chn) { #define H_spectro_x_angle "(" S_spectro_x_angle " :optional snd chn): spectrogram x-axis viewing angle (90.0)" if (Xen_is_bound(snd)) return(channel_get(snd, chn, CP_SPECTRO_X_ANGLE, S_spectro_x_angle)); return(C_double_to_Xen_real(spectro_x_angle(ss))); } static Xen g_set_spectro_x_angle(Xen val, Xen snd, Xen chn) { Xen_check_type(Xen_is_number(val), val, 1, S_set S_spectro_x_angle, "a number"); if (Xen_is_bound(snd)) return(channel_set(snd, chn, val, CP_SPECTRO_X_ANGLE, S_set S_spectro_x_angle)); set_spectro_x_angle(mus_fclamp(MIN_SPECTRO_ANGLE, Xen_real_to_C_double(val), MAX_SPECTRO_ANGLE)); return(C_double_to_Xen_real(spectro_x_angle(ss))); } with_three_setter_args(g_set_spectro_x_angle_reversed, g_set_spectro_x_angle) static Xen g_spectro_x_scale(Xen snd, Xen chn) { #define H_spectro_x_scale "(" S_spectro_x_scale " :optional snd chn): scaler (stretch) along the spectrogram x axis (1.0)" if (Xen_is_bound(snd)) return(channel_get(snd, chn, CP_SPECTRO_X_SCALE, S_spectro_x_scale)); return(C_double_to_Xen_real(spectro_x_scale(ss))); } static Xen g_set_spectro_x_scale(Xen val, Xen snd, Xen chn) { Xen_check_type(Xen_is_number(val), val, 1, S_set S_spectro_x_scale, "a number"); if (Xen_is_bound(snd)) return(channel_set(snd, chn, val, CP_SPECTRO_X_SCALE, S_set S_spectro_x_scale)); set_spectro_x_scale(mus_fclamp(0.0, Xen_real_to_C_double(val), MAX_SPECTRO_SCALE)); return(C_double_to_Xen_real(spectro_x_scale(ss))); } with_three_setter_args(g_set_spectro_x_scale_reversed, g_set_spectro_x_scale) static Xen g_spectro_y_angle(Xen snd, Xen chn) { #define H_spectro_y_angle "(" S_spectro_y_angle " :optional snd chn): spectrogram y-axis viewing angle (0.0)" if (Xen_is_bound(snd)) return(channel_get(snd, chn, CP_SPECTRO_Y_ANGLE, S_spectro_y_angle)); return(C_double_to_Xen_real(spectro_y_angle(ss))); } static Xen g_set_spectro_y_angle(Xen val, Xen snd, Xen chn) { Xen_check_type(Xen_is_number(val), val, 1, S_set S_spectro_y_angle, "a number"); if (Xen_is_bound(snd)) return(channel_set(snd, chn, val, CP_SPECTRO_Y_ANGLE, S_set S_spectro_y_angle)); set_spectro_y_angle(mus_fclamp(MIN_SPECTRO_ANGLE, Xen_real_to_C_double(val), MAX_SPECTRO_ANGLE)); return(C_double_to_Xen_real(spectro_y_angle(ss))); } with_three_setter_args(g_set_spectro_y_angle_reversed, g_set_spectro_y_angle) static Xen g_spectro_y_scale(Xen snd, Xen chn) { #define H_spectro_y_scale "(" S_spectro_y_scale " :optional snd chn): scaler (stretch) along the spectrogram y axis (1.0)" if (Xen_is_bound(snd)) return(channel_get(snd, chn, CP_SPECTRO_Y_SCALE, S_spectro_y_scale)); return(C_double_to_Xen_real(spectro_y_scale(ss))); } static Xen g_set_spectro_y_scale(Xen val, Xen snd, Xen chn) { Xen_check_type(Xen_is_number(val), val, 1, S_set S_spectro_y_scale, "a number"); if (Xen_is_bound(snd)) return(channel_set(snd, chn, val, CP_SPECTRO_Y_SCALE, S_set S_spectro_y_scale)); set_spectro_y_scale(mus_fclamp(0.0, Xen_real_to_C_double(val), MAX_SPECTRO_SCALE)); return(C_double_to_Xen_real(spectro_y_scale(ss))); } with_three_setter_args(g_set_spectro_y_scale_reversed, g_set_spectro_y_scale) static Xen g_spectro_z_angle(Xen snd, Xen chn) { #define H_spectro_z_angle "(" S_spectro_z_angle " :optional snd chn): spectrogram z-axis viewing angle (-2.0)" if (Xen_is_bound(snd)) return(channel_get(snd, chn, CP_SPECTRO_Z_ANGLE, S_spectro_z_angle)); return(C_double_to_Xen_real(spectro_z_angle(ss))); } static Xen g_set_spectro_z_angle(Xen val, Xen snd, Xen chn) { Xen_check_type(Xen_is_number(val), val, 1, S_set S_spectro_z_angle, "a number"); if (Xen_is_bound(snd)) return(channel_set(snd, chn, val, CP_SPECTRO_Z_ANGLE, S_set S_spectro_z_angle)); set_spectro_z_angle(mus_fclamp(MIN_SPECTRO_ANGLE, Xen_real_to_C_double(val), MAX_SPECTRO_ANGLE)); return(C_double_to_Xen_real(spectro_z_angle(ss))); } with_three_setter_args(g_set_spectro_z_angle_reversed, g_set_spectro_z_angle) static Xen g_spectro_z_scale(Xen snd, Xen chn) { #define H_spectro_z_scale "(" S_spectro_z_scale " :optional snd chn): scaler (stretch) along the spectrogram z axis (0.1)" if (Xen_is_bound(snd)) return(channel_get(snd, chn, CP_SPECTRO_Z_SCALE, S_spectro_z_scale)); return(C_double_to_Xen_real(spectro_z_scale(ss))); } static Xen g_set_spectro_z_scale(Xen val, Xen snd, Xen chn) { Xen_check_type(Xen_is_number(val), val, 1, S_set S_spectro_z_scale, "a number"); if (Xen_is_bound(snd)) return(channel_set(snd, chn, val, CP_SPECTRO_Z_SCALE, S_set S_spectro_z_scale)); set_spectro_z_scale(mus_fclamp(0.0, Xen_real_to_C_double(val), MAX_SPECTRO_SCALE)); return(C_double_to_Xen_real(spectro_z_scale(ss))); } with_three_setter_args(g_set_spectro_z_scale_reversed, g_set_spectro_z_scale) static Xen g_spectro_hop(Xen snd, Xen chn) { #define H_spectro_hop "(" S_spectro_hop " :optional snd chn): hop amount (pixels) in spectral displays" if (Xen_is_bound(snd)) return(channel_get(snd, chn, CP_SPECTRO_HOP, S_spectro_hop)); return(C_int_to_Xen_integer(spectro_hop(ss))); } static Xen g_set_spectro_hop(Xen val, Xen snd, Xen chn) { Xen_check_type(Xen_is_number(val), val, 1, S_set S_spectro_hop, "a number"); if (Xen_is_bound(snd)) return(channel_set(snd, chn, val, CP_SPECTRO_HOP, S_set S_spectro_hop)); set_spectro_hop((Xen_is_integer(val)) ? Xen_integer_to_C_int(val) : 0); return(C_int_to_Xen_integer(spectro_hop(ss))); } with_three_setter_args(g_set_spectro_hop_reversed, g_set_spectro_hop) static Xen g_show_marks(Xen snd, Xen chn) { #define H_show_marks "(" S_show_marks " :optional snd chn): " PROC_TRUE " if Snd should show marks" if (Xen_is_bound(snd)) return(channel_get(snd, chn, CP_SHOW_MARKS, S_show_marks)); return(C_bool_to_Xen_boolean(show_marks(ss))); } static void chans_marks(chan_info *cp, bool value) { cp->show_marks = value; update_graph(cp); } void set_show_marks(bool val) { in_set_show_marks(val); for_each_chan_with_bool(chans_marks, val); } static Xen g_set_show_marks(Xen on, Xen snd, Xen chn) { Xen_check_type(Xen_is_boolean(on), on, 1, S_set S_show_marks, "a boolean"); if (Xen_is_bound(snd)) return(channel_set(snd, chn, on, CP_SHOW_MARKS, S_set S_show_marks)); set_show_marks(Xen_boolean_to_C_bool(on)); return(C_bool_to_Xen_boolean(show_marks(ss))); } with_three_setter_args(g_set_show_marks_reversed, g_set_show_marks) static Xen g_show_transform_peaks(Xen snd, Xen chn) { #define H_show_transform_peaks "(" S_show_transform_peaks " :optional snd chn): " PROC_TRUE " if fft display should include peak list" if (Xen_is_bound(snd)) return(channel_get(snd, chn, CP_SHOW_TRANSFORM_PEAKS, S_show_transform_peaks)); return(C_bool_to_Xen_boolean(show_transform_peaks(ss))); } static Xen g_set_show_transform_peaks(Xen val, Xen snd, Xen chn) { Xen_check_type(Xen_is_boolean(val), val, 1, S_set S_show_transform_peaks, "a boolean"); if (Xen_is_bound(snd)) return(channel_set(snd, chn, val, CP_SHOW_TRANSFORM_PEAKS, S_set S_show_transform_peaks)); set_show_transform_peaks(Xen_boolean_to_C_bool(val)); return(C_bool_to_Xen_boolean(show_transform_peaks(ss))); } with_three_setter_args(g_set_show_transform_peaks_reversed, g_set_show_transform_peaks) static Xen g_zero_pad(Xen snd, Xen chn) { #define H_zero_pad "(" S_zero_pad " :optional snd chn): zero padding used in fft as a multiple of fft size (0)" if (Xen_is_bound(snd)) return(channel_get(snd, chn, CP_ZERO_PAD, S_zero_pad)); return(C_int_to_Xen_integer(zero_pad(ss))); } static Xen g_set_zero_pad(Xen val, Xen snd, Xen chn) { Xen_check_type(Xen_is_integer(val), val, 1, S_set S_zero_pad, "an integer"); if (Xen_is_bound(snd)) return(channel_set(snd, chn, val, CP_ZERO_PAD, S_set S_zero_pad)); set_zero_pad(mus_iclamp(0, g_imin(0, val, DEFAULT_ZERO_PAD), MAX_ZERO_PAD)); return(C_int_to_Xen_integer(zero_pad(ss))); } with_three_setter_args(g_set_zero_pad_reversed, g_set_zero_pad) static Xen g_wavelet_type(Xen snd, Xen chn) { #define H_wavelet_type "(" S_wavelet_type " :optional snd chn): wavelet used in wavelet-transform (0)" if (Xen_is_bound(snd)) return(channel_get(snd, chn, CP_WAVELET_TYPE, S_wavelet_type)); return(C_int_to_Xen_integer(wavelet_type(ss))); } static Xen g_set_wavelet_type(Xen val, Xen snd, Xen chn) { int wave; Xen_check_type(Xen_is_integer(val), val, 1, S_set S_wavelet_type, "an integer"); wave = Xen_integer_to_C_int(val); if ((wave < 0) || (wave >= NUM_WAVELETS)) Xen_out_of_range_error(S_set S_wavelet_type, 1, val, "unknown wavelet type"); if (Xen_is_bound(snd)) return(channel_set(snd, chn, val, CP_WAVELET_TYPE, S_set S_wavelet_type)); set_wavelet_type(wave); return(C_int_to_Xen_integer(wavelet_type(ss))); } with_three_setter_args(g_set_wavelet_type_reversed, g_set_wavelet_type) static Xen g_fft_log_frequency(Xen snd, Xen chn) { #define H_fft_log_frequency "(" S_fft_log_frequency " :optional snd chn): " PROC_TRUE " if fft displays use log on the frequency axis" if (Xen_is_bound(snd)) return(channel_get(snd, chn, CP_FFT_LOG_FREQUENCY, S_fft_log_frequency)); return(C_bool_to_Xen_boolean(fft_log_frequency(ss))); } static Xen g_set_fft_log_frequency(Xen on, Xen snd, Xen chn) { Xen_check_type(Xen_is_boolean(on), on, 1, S_set S_fft_log_frequency, "a boolean"); if (Xen_is_bound(snd)) return(channel_set(snd, chn, on, CP_FFT_LOG_FREQUENCY, S_set S_fft_log_frequency)); set_fft_log_frequency(Xen_boolean_to_C_bool(on)); return(C_bool_to_Xen_boolean(fft_log_frequency(ss))); } with_three_setter_args(g_set_fft_log_frequency_reversed, g_set_fft_log_frequency) static Xen g_fft_log_magnitude(Xen snd, Xen chn) { #define H_fft_log_magnitude "(" S_fft_log_magnitude " :optional snd chn): " PROC_TRUE " if fft displays use dB" if (Xen_is_bound(snd)) return(channel_get(snd, chn, CP_FFT_LOG_MAGNITUDE, S_fft_log_magnitude)); return(C_bool_to_Xen_boolean(fft_log_magnitude(ss))); } static Xen g_set_fft_log_magnitude(Xen on, Xen snd, Xen chn) { Xen_check_type(Xen_is_boolean(on), on, 1, S_set S_fft_log_magnitude, "a boolean"); if (Xen_is_bound(snd)) return(channel_set(snd, chn, on, CP_FFT_LOG_MAGNITUDE, S_set S_fft_log_magnitude)); set_fft_log_magnitude(Xen_boolean_to_C_bool(on)); return(C_bool_to_Xen_boolean(fft_log_magnitude(ss))); } with_three_setter_args(g_set_fft_log_magnitude_reversed, g_set_fft_log_magnitude) static Xen g_fft_with_phases(Xen snd, Xen chn) { #define H_fft_with_phases "(" S_fft_with_phases " :optional snd chn): " PROC_TRUE " if fft displays include phase info" if (Xen_is_bound(snd)) return(channel_get(snd, chn, CP_FFT_WITH_PHASES, S_fft_with_phases)); return(C_bool_to_Xen_boolean(fft_with_phases(ss))); } static Xen g_set_fft_with_phases(Xen on, Xen snd, Xen chn) { Xen_check_type(Xen_is_boolean(on), on, 1, S_set S_fft_with_phases, "a boolean"); if (Xen_is_bound(snd)) return(channel_set(snd, chn, on, CP_FFT_WITH_PHASES, S_set S_fft_with_phases)); set_fft_with_phases(Xen_boolean_to_C_bool(on)); return(C_bool_to_Xen_boolean(fft_with_phases(ss))); } with_three_setter_args(g_set_fft_with_phases_reversed, g_set_fft_with_phases) static Xen g_show_mix_waveforms(Xen snd, Xen chn) { #define H_show_mix_waveforms "(" S_show_mix_waveforms " :optional snd chn): " PROC_TRUE " if Snd should display mix waveforms (above the main waveform)" if (Xen_is_bound(snd)) return(channel_get(snd, chn, CP_SHOW_MIX_WAVEFORMS, S_show_mix_waveforms)); return(C_bool_to_Xen_boolean(show_mix_waveforms(ss))); } static Xen g_set_show_mix_waveforms(Xen on, Xen snd, Xen chn) { Xen_check_type(Xen_is_boolean(on), on, 1, S_set S_show_mix_waveforms, "a boolean"); if (Xen_is_bound(snd)) return(channel_set(snd, chn, on, CP_SHOW_MIX_WAVEFORMS, S_set S_show_mix_waveforms)); set_show_mix_waveforms(Xen_boolean_to_C_bool(on)); return(C_bool_to_Xen_boolean(show_mix_waveforms(ss))); } with_three_setter_args(g_set_show_mix_waveforms_reversed, g_set_show_mix_waveforms) static Xen g_with_verbose_cursor(Xen snd, Xen chn) { #define H_with_verbose_cursor "(" S_with_verbose_cursor " :optional snd chn): " PROC_TRUE " if the cursor's position and so on is displayed in the status area" if (Xen_is_bound(snd)) return(channel_get(snd, chn, CP_WITH_VERBOSE_CURSOR, S_with_verbose_cursor)); return(C_bool_to_Xen_boolean(with_verbose_cursor(ss))); } static void chans_with_verbose_cursor(chan_info *cp, bool value) { cp->with_verbose_cursor = value; update_graph(cp); } void set_with_verbose_cursor(bool val) { in_set_with_verbose_cursor(val); if (val == 0) for_each_sound(clear_status_area); for_each_chan_with_bool(chans_with_verbose_cursor, val); } static Xen g_set_with_verbose_cursor(Xen on, Xen snd, Xen chn) { Xen_check_type(Xen_is_boolean(on), on, 1, S_set S_with_verbose_cursor, "a boolean"); if (Xen_is_bound(snd)) return(channel_set(snd, chn, on, CP_WITH_VERBOSE_CURSOR, S_set S_with_verbose_cursor)); set_with_verbose_cursor(Xen_boolean_to_C_bool(on)); return(C_bool_to_Xen_boolean(with_verbose_cursor(ss))); } with_three_setter_args(g_set_with_verbose_cursor_reversed, g_set_with_verbose_cursor) static Xen g_time_graph_type(Xen snd, Xen chn) { #define H_time_graph_type "(" S_time_graph_type " :optional snd chn): " S_graph_as_wavogram " if Snd's time domain display is a 'wavogram',\ otherwise " S_graph_once "." if (Xen_is_bound(snd)) return(channel_get(snd, chn, CP_TIME_GRAPH_TYPE, S_time_graph_type)); return(C_int_to_Xen_integer((int)time_graph_type(ss))); } static Xen g_set_time_graph_type(Xen val, Xen snd, Xen chn) { graph_type_t on; Xen_check_type(Xen_is_integer(val), val, 1, S_set S_time_graph_type, "an integer"); on = (graph_type_t)Xen_integer_to_C_int(val); if ((on != GRAPH_ONCE) && (on != GRAPH_AS_WAVOGRAM)) Xen_out_of_range_error(S_set S_time_graph_type, 1, val, S_time_graph_type " should be " S_graph_once ", or " S_graph_as_wavogram); if (Xen_is_bound(snd)) return(channel_set(snd, chn, val, CP_TIME_GRAPH_TYPE, S_set S_time_graph_type)); set_time_graph_type(on); return(C_int_to_Xen_integer((int)time_graph_type(ss))); } with_three_setter_args(g_set_time_graph_type_reversed, g_set_time_graph_type) static Xen g_wavo_hop(Xen snd, Xen chn) { #define H_wavo_hop "(" S_wavo_hop " :optional snd chn): wavogram spacing between successive traces" if (Xen_is_bound(snd)) return(channel_get(snd, chn, CP_WAVO_HOP, S_wavo_hop)); return(C_int_to_Xen_integer(wavo_hop(ss))); } static Xen g_set_wavo_hop(Xen val, Xen snd, Xen chn) { Xen_check_type(Xen_is_integer(val), val, 1, S_set S_wavo_hop, "an integer"); if (Xen_is_bound(snd)) return(channel_set(snd, chn, val, CP_WAVO_HOP, S_set S_wavo_hop)); set_wavo_hop(Xen_integer_to_C_int(val)); return(val); } with_three_setter_args(g_set_wavo_hop_reversed, g_set_wavo_hop) static Xen g_wavo_trace(Xen snd, Xen chn) { #define H_wavo_trace "(" S_wavo_trace " :optional snd chn): length (samples) of each trace in the wavogram (64)" if (Xen_is_bound(snd)) return(channel_get(snd, chn, CP_WAVO_TRACE, S_wavo_trace)); return(C_int_to_Xen_integer(wavo_trace(ss))); } static Xen g_set_wavo_trace(Xen val, Xen snd, Xen chn) { Xen_check_type(Xen_is_integer(val), val, 1, S_set S_wavo_trace, "an integer"); if (Xen_is_bound(snd)) return(channel_set(snd, chn, val, CP_WAVO_TRACE, S_set S_wavo_trace)); set_wavo_trace(mus_iclamp(1, Xen_integer_to_C_int(val), POINT_BUFFER_SIZE)); return(C_int_to_Xen_integer(wavo_trace(ss))); } with_three_setter_args(g_set_wavo_trace_reversed, g_set_wavo_trace) static Xen g_transform_size(Xen snd, Xen chn) { #define H_transform_size "(" S_transform_size " :optional snd chn): current fft size (512)" if (Xen_is_bound(snd)) return(channel_get(snd, chn, CP_TRANSFORM_SIZE, S_transform_size)); return(C_llong_to_Xen_llong(transform_size(ss))); } static Xen g_set_transform_size(Xen val, Xen snd, Xen chn) { mus_long_t len; Xen_check_type(Xen_is_llong(val), val, 1, S_set S_transform_size, "an integer"); len = Xen_llong_to_C_llong(val); if (len <= 0) Xen_out_of_range_error(S_set S_transform_size, 1, val, "size must be > 0"); if (!(is_power_of_2(len))) len = snd_mus_long_t_pow2((int)(log(len + 1) / log(2.0))); /* actually rounds down, despite appearances */ if (len <= 0) return(Xen_false); if (Xen_is_bound(snd)) return(channel_set(snd, chn, val, CP_TRANSFORM_SIZE, S_set S_transform_size)); set_transform_size(len); return(C_llong_to_Xen_llong(transform_size(ss))); } with_three_setter_args(g_set_transform_size_reversed, g_set_transform_size) static Xen g_transform_graph_type(Xen snd, Xen chn) { #define H_transform_graph_type "(" S_transform_graph_type " :optional snd chn) can \ be " S_graph_once ", " S_graph_as_sonogram ", or " S_graph_as_spectrogram "." if (Xen_is_bound(snd)) return(channel_get(snd, chn, CP_TRANSFORM_GRAPH_TYPE, S_transform_graph_type)); return(C_int_to_Xen_integer((int)transform_graph_type(ss))); } static Xen g_set_transform_graph_type(Xen val, Xen snd, Xen chn) { graph_type_t style; int gt; Xen_check_type(Xen_is_integer(val), val, 1, S_set S_transform_graph_type, "an integer"); gt = Xen_integer_to_C_int(val); style = (graph_type_t)gt; if ((gt < 0) || (style > GRAPH_AS_SPECTROGRAM)) Xen_out_of_range_error(S_set S_transform_graph_type, 1, val, S_transform_graph_type " should be " S_graph_once ", " S_graph_as_sonogram ", or " S_graph_as_spectrogram); if (Xen_is_bound(snd)) return(channel_set(snd, chn, val, CP_TRANSFORM_GRAPH_TYPE, S_set S_transform_graph_type)); set_transform_graph_type(style); return(C_int_to_Xen_integer((int)transform_graph_type(ss))); } with_three_setter_args(g_set_transform_graph_type_reversed, g_set_transform_graph_type) static Xen g_fft_window(Xen snd, Xen chn) { #define H_fft_window "(" S_fft_window " :optional snd chn): fft data window choice (e.g. " S_blackman2_window "). The \ choices are: " S_rectangular_window ", " S_hann_window ", " S_welch_window ", " S_parzen_window ", \ " S_bartlett_window ", " S_hamming_window ", " S_blackman2_window ", " S_blackman3_window ", \ " S_blackman4_window ", " S_exponential_window ", " S_riemann_window ", " S_kaiser_window ", \ " S_cauchy_window ", " S_poisson_window ", " S_gaussian_window ", " S_tukey_window ", \ " S_dolph_chebyshev_window ", " S_hann_poisson_window ", " S_connes_window ", \ " S_samaraki_window ", " S_ultraspherical_window ", " S_bartlett_hann_window ", " S_bohman_window ", " S_flat_top_window ", and " S_blackman5_window " et al." if (Xen_is_bound(snd)) return(channel_get(snd, chn, CP_FFT_WINDOW, S_fft_window)); return(C_int_to_Xen_integer(fft_window(ss))); } static Xen g_set_fft_window(Xen val, Xen snd, Xen chn) { int in_win; Xen_check_type(Xen_is_integer(val), val, 1, S_set S_fft_window, "an integer"); in_win = Xen_integer_to_C_int(val); if (!(mus_is_fft_window(in_win))) Xen_out_of_range_error(S_set S_fft_window, 1, val, "unknown fft data window"); if (Xen_is_bound(snd)) return(channel_set(snd, chn, val, CP_FFT_WINDOW, S_set S_fft_window)); set_fft_window((mus_fft_window_t)in_win); return(C_int_to_Xen_integer((int)fft_window(ss))); } with_three_setter_args(g_set_fft_window_reversed, g_set_fft_window) static Xen g_transform_type(Xen snd, Xen chn) { #define H_transform_type "(" S_transform_type " :optional snd chn): transform type; can be one of " S_fourier_transform ", \ " S_wavelet_transform ", " S_haar_transform ", " S_autocorrelation ", " S_walsh_transform ", \ " S_cepstrum ", or an added transform (see " S_add_transform ")." if (Xen_is_bound(snd)) return(channel_get(snd, chn, CP_TRANSFORM_TYPE, S_transform_type)); return(C_int_to_Xen_transform(transform_type(ss))); } static Xen g_set_transform_type(Xen val, Xen snd, Xen chn) { int type; Xen_check_type(xen_is_transform(val), val, 1, S_set S_transform_type, "a transform object"); type = Xen_transform_to_C_int(val); if (!is_transform(type)) Xen_out_of_range_error(S_set S_transform_type, 1, val, "unknown transform"); if (Xen_is_bound(snd)) return(channel_set(snd, chn, val, CP_TRANSFORM_TYPE, S_set S_transform_type)); set_transform_type(type); return(C_int_to_Xen_transform(transform_type(ss))); } with_three_setter_args(g_set_transform_type_reversed, g_set_transform_type) static Xen g_transform_normalization(Xen snd, Xen chn) { #define H_transform_normalization "(" S_transform_normalization " :optional snd chn): one of " S_dont_normalize ", " S_normalize_by_channel \ ", " S_normalize_by_sound ", or " S_normalize_globally ". \ decides whether spectral data is normalized before display (default: " S_normalize_by_channel ")" if (Xen_is_bound(snd)) return(channel_get(snd, chn, CP_TRANSFORM_NORMALIZATION, S_transform_normalization)); return(C_int_to_Xen_integer((int)transform_normalization(ss))); } static Xen g_set_transform_normalization(Xen val, Xen snd, Xen chn) { fft_normalize_t norm; Xen_check_type(Xen_is_integer(val), val, 1, S_set S_transform_normalization, "an integer"); norm = (fft_normalize_t)Xen_integer_to_C_int(val); if (norm >= NUM_TRANSFORM_NORMALIZATIONS) Xen_out_of_range_error(S_set S_transform_normalization, 1, val, S_transform_normalization " should be " S_dont_normalize ", " S_normalize_by_channel ", " S_normalize_by_sound ", or " S_normalize_globally); if (Xen_is_bound(snd)) return(channel_set(snd, chn, val, CP_TRANSFORM_NORMALIZATION, S_set S_transform_normalization)); set_transform_normalization(norm); return(C_int_to_Xen_integer((int)transform_normalization(ss))); } with_three_setter_args(g_set_transform_normalization_reversed, g_set_transform_normalization) static Xen g_max_transform_peaks(Xen snd, Xen chn) { #define H_max_transform_peaks "(" S_max_transform_peaks " :optional snd chn): max number of fft peaks reported in fft display" if (Xen_is_bound(snd)) return(channel_get(snd, chn, CP_MAX_TRANSFORM_PEAKS, S_max_transform_peaks)); return(C_int_to_Xen_integer(max_transform_peaks(ss))); } static Xen g_set_max_transform_peaks(Xen n, Xen snd, Xen chn) { Xen_check_type(Xen_is_integer(n), n, 1, S_set S_max_transform_peaks, "an integer"); if (Xen_is_bound(snd)) return(channel_set(snd, chn, n, CP_MAX_TRANSFORM_PEAKS, S_set S_max_transform_peaks)); else { int lim; lim = Xen_integer_to_C_int(n); if (lim >= 1) { set_max_transform_peaks(lim); reflect_peaks_in_transform_dialog(); } return(C_int_to_Xen_integer(max_transform_peaks(ss))); } } with_three_setter_args(g_set_max_transform_peaks_reversed, g_set_max_transform_peaks) static Xen g_graph_style(Xen snd, Xen chn) { #define H_graph_style "(" S_graph_style " :optional snd chn): graph style, one \ of '(" S_graph_lines " " S_graph_dots " " S_graph_dots_and_lines " " S_graph_lollipops " " S_graph_filled ")" if (Xen_is_bound(snd)) return(channel_get(snd, chn, CP_TIME_GRAPH_STYLE, S_time_graph_style)); return(C_int_to_Xen_integer(graph_style(ss))); } static void chans_graph_style(chan_info *cp, int value) { graph_style_t style = (graph_style_t)value; cp->time_graph_style = style; cp->lisp_graph_style = style; cp->transform_graph_style = style; update_graph(cp); } void set_graph_style(graph_style_t val) { in_set_graph_style(val); for_each_chan_with_int(chans_graph_style, (int)val); } static Xen g_set_graph_style(Xen style, Xen snd, Xen chn) { int val; Xen_check_type(Xen_is_integer(style), style, 1, S_set S_graph_style, "an integer"); val = Xen_integer_to_C_int(style); if (!(is_graph_style(val))) Xen_out_of_range_error(S_set S_graph_style, 1, style, "unknown graph-style"); if (Xen_is_bound(snd)) { Xen xval; call_update_graph = false; xval = channel_set(snd, chn, style, CP_TIME_GRAPH_STYLE, S_set S_graph_style); channel_set(snd, chn, style, CP_LISP_GRAPH_STYLE, S_set S_graph_style); call_update_graph = true; channel_set(snd, chn, style, CP_TRANSFORM_GRAPH_STYLE, S_set S_graph_style); return(xval); } set_graph_style((graph_style_t)val); return(C_int_to_Xen_integer((int)(graph_style(ss)))); } with_three_setter_args(g_set_graph_style_reversed, g_set_graph_style) static Xen g_time_graph_style(Xen snd, Xen chn) { #define H_time_graph_style "(" S_time_graph_style " snd chn): time domain graph drawing style. \ one of '(" S_graph_lines " " S_graph_dots " " S_graph_dots_and_lines " " S_graph_lollipops " " S_graph_filled ")" Snd_assert_sound(S_time_graph_style, snd, 0); return(channel_get(snd, chn, CP_TIME_GRAPH_STYLE, S_time_graph_style)); } static Xen g_set_time_graph_style(Xen style, Xen snd, Xen chn) { int val; Xen_check_type(Xen_is_integer(style), style, 1, S_set S_time_graph_style, "an integer"); Snd_assert_sound(S_time_graph_style, snd, 0); val = Xen_integer_to_C_int(style); if (!(is_graph_style(val))) Xen_out_of_range_error(S_set S_time_graph_style, 1, style, "unknown " S_time_graph_style); return(channel_set(snd, chn, style, CP_TIME_GRAPH_STYLE, S_set S_time_graph_style)); } with_three_setter_args(g_set_time_graph_style_reversed, g_set_time_graph_style) static Xen g_lisp_graph_style(Xen snd, Xen chn) { #define H_lisp_graph_style "(" S_lisp_graph_style " snd chn): lisp graph drawing style. \ one of '(" S_graph_lines " " S_graph_dots " " S_graph_dots_and_lines " " S_graph_lollipops " " S_graph_filled ")" Snd_assert_sound(S_lisp_graph_style, snd, 0); return(channel_get(snd, chn, CP_LISP_GRAPH_STYLE, S_lisp_graph_style)); } static Xen g_set_lisp_graph_style(Xen style, Xen snd, Xen chn) { int val; Xen_check_type(Xen_is_integer(style), style, 1, S_set S_lisp_graph_style, "an integer"); Snd_assert_sound(S_lisp_graph_style, snd, 0); val = Xen_integer_to_C_int(style); if (!(is_graph_style(val))) Xen_out_of_range_error(S_set S_lisp_graph_style, 1, style, "unknown " S_lisp_graph_style); return(channel_set(snd, chn, style, CP_LISP_GRAPH_STYLE, S_set S_lisp_graph_style)); } with_three_setter_args(g_set_lisp_graph_style_reversed, g_set_lisp_graph_style) static Xen g_transform_graph_style(Xen snd, Xen chn) { #define H_transform_graph_style "(" S_transform_graph_style " snd chn): fft graph drawing style, one \ of '(" S_graph_lines " " S_graph_dots " " S_graph_dots_and_lines " " S_graph_lollipops " " S_graph_filled ")" Snd_assert_sound(S_transform_graph_style, snd, 0); return(channel_get(snd, chn, CP_TRANSFORM_GRAPH_STYLE, S_transform_graph_style)); } static Xen g_set_transform_graph_style(Xen style, Xen snd, Xen chn) { int val; Xen_check_type(Xen_is_integer(style), style, 1, S_set S_transform_graph_style, "an integer"); Snd_assert_sound(S_transform_graph_style, snd, 0); val = Xen_integer_to_C_int(style); if (!(is_graph_style(val))) Xen_out_of_range_error(S_set S_transform_graph_style, 1, style, "unknown " S_transform_graph_style); return(channel_set(snd, chn, style, CP_TRANSFORM_GRAPH_STYLE, S_set S_transform_graph_style)); } with_three_setter_args(g_set_transform_graph_style_reversed, g_set_transform_graph_style) static Xen g_dot_size(Xen snd, Xen chn) { #define H_dot_size "(" S_dot_size " :optional snd chn): size in pixels of dots when graphing with dots (1)" if (Xen_is_bound(snd)) return(channel_get(snd, chn, CP_DOT_SIZE, S_dot_size)); return(C_int_to_Xen_integer(dot_size(ss))); } static Xen g_set_dot_size(Xen size, Xen snd, Xen chn) { Xen_check_type(Xen_is_integer(size), size, 1, S_set S_dot_size, "an integer"); if (Xen_is_bound(snd)) return(channel_set(snd, chn, size, CP_DOT_SIZE, S_set S_dot_size)); set_dot_size(mus_iclamp(MIN_DOT_SIZE, Xen_integer_to_C_int(size), MAX_DOT_SIZE)); return(C_int_to_Xen_integer(dot_size(ss))); } with_three_setter_args(g_set_dot_size_reversed, g_set_dot_size) static Xen g_x_axis_style(Xen snd, Xen chn) { #define H_x_axis_style "(" S_x_axis_style " :optional snd chn): \ The x axis labelling of the time domain waveform can be in seconds (" S_x_axis_in_seconds "), in samples (" S_x_axis_in_samples "), expressed as a \ percentage of the overall duration (" S_x_axis_as_percentage "), as a beat number (" S_x_axis_in_beats "), as a measure \ number (" S_x_axis_in_measures "), or clock-style (dd:hh:mm:ss) (" S_x_axis_as_clock ")." if (Xen_is_bound(snd)) return(channel_get(snd, chn, CP_X_AXIS_STYLE, S_x_axis_style)); return(C_int_to_Xen_integer((int)x_axis_style(ss))); } static void chans_x_axis_style(chan_info *cp, int value) { axis_info *ap; x_axis_style_t new_style = (x_axis_style_t)value; ap = cp->axis; cp->x_axis_style = new_style; if (ap) { if (ap->xlabel) free(ap->xlabel); /* if user set x-axis-label (snd-axis.c) ap->default_xlabel is not null, so use it rather than normal choices */ if (ap->default_xlabel) ap->xlabel = mus_strdup(ap->default_xlabel); else { switch (new_style) { case X_AXIS_IN_BEATS: ap->xlabel = mus_strdup("time (beats)"); break; case X_AXIS_IN_MEASURES: ap->xlabel = mus_strdup("time (measures)"); break; case X_AXIS_IN_SAMPLES: ap->xlabel = mus_strdup("time (samples)"); break; case X_AXIS_AS_PERCENTAGE: ap->xlabel = mus_strdup("time (percent)"); break; default: ap->xlabel = mus_strdup("time"); break; } } update_graph(cp); } } void set_x_axis_style(x_axis_style_t val) { in_set_x_axis_style(val); for_each_chan_with_int(chans_x_axis_style, (int)val); } static Xen g_set_x_axis_style(Xen style, Xen snd, Xen chn) { int val; Xen_check_type(Xen_is_integer(style), style, 1, S_set S_x_axis_style, "an integer"); val = Xen_integer_to_C_int(style); if (!(is_x_axis_style(val))) Xen_out_of_range_error(S_set S_x_axis_style, 1, style, "unknown " S_x_axis_style); if (Xen_is_bound(snd)) return(channel_set(snd, chn, style, CP_X_AXIS_STYLE, S_set S_x_axis_style)); set_x_axis_style((x_axis_style_t)val); /* snd-menu.c -- maps over chans */ return(C_int_to_Xen_integer((int)x_axis_style(ss))); } with_three_setter_args(g_set_x_axis_style_reversed, g_set_x_axis_style) static Xen g_beats_per_minute(Xen snd, Xen chn) { #define H_beats_per_minute "(" S_beats_per_minute " :optional snd chn): beats per minute if " S_x_axis_style " is " S_x_axis_in_beats if (Xen_is_bound(snd)) return(channel_get(snd, chn, CP_BEATS_PER_MINUTE, S_beats_per_minute)); return(C_double_to_Xen_real(beats_per_minute(ss))); } static Xen g_set_beats_per_minute(Xen beats, Xen snd, Xen chn) { Xen_check_type(Xen_is_number(beats), beats, 1, S_set S_beats_per_minute, "a number"); if (Xen_is_bound(snd)) return(channel_set(snd, chn, beats, CP_BEATS_PER_MINUTE, S_set S_beats_per_minute)); else { mus_float_t val; val = Xen_real_to_C_double(beats); if (val > 0.0) set_beats_per_minute(val); return(C_double_to_Xen_real(beats_per_minute(ss))); } } with_three_setter_args(g_set_beats_per_minute_reversed, g_set_beats_per_minute) static Xen g_beats_per_measure(Xen snd, Xen chn) { #define H_beats_per_measure "(" S_beats_per_measure " :optional snd chn): beats per measure if " S_x_axis_style " is " S_x_axis_in_measures if (Xen_is_bound(snd)) return(channel_get(snd, chn, CP_BEATS_PER_MEASURE, S_beats_per_measure)); return(C_int_to_Xen_integer(beats_per_measure(ss))); } static Xen g_set_beats_per_measure(Xen beats, Xen snd, Xen chn) { int val; Xen_check_type(Xen_is_integer(beats), beats, 1, S_set S_beats_per_measure, "an int"); val = Xen_integer_to_C_int(beats); if ((val <= 0) || (val > 1000)) Xen_out_of_range_error(S_set S_beats_per_measure, 1, beats, S_beats_per_measure " should be between 1 and 1000"); if (Xen_is_bound(snd)) return(channel_set(snd, chn, beats, CP_BEATS_PER_MEASURE, S_set S_beats_per_measure)); set_beats_per_measure(val); return(C_int_to_Xen_integer(beats_per_measure(ss))); } with_three_setter_args(g_set_beats_per_measure_reversed, g_set_beats_per_measure) static Xen g_show_axes(Xen snd, Xen chn) { #define H_show_axes "(" S_show_axes " :optional snd chn) \ If " S_show_all_axes ", display x and y axes; if " S_show_x_axis ", just one axis (the x axis) is displayed. \ The other choices are " S_show_no_axes ", " S_show_all_axes_unlabelled ", " S_show_x_axis_unlabelled ", and " S_show_bare_x_axis "." if (Xen_is_bound(snd)) return(channel_get(snd, chn, CP_SHOW_AXES, S_show_axes)); return(C_int_to_Xen_integer((int)show_axes(ss))); } static Xen g_set_show_axes(Xen on, Xen snd, Xen chn) { int val; Xen_check_type(Xen_is_integer(on), on, 1, S_set S_show_axes, "an integer"); val = Xen_integer_to_C_int(on); if (!(shows_axes(val))) Xen_out_of_range_error(S_set S_show_axes, 1, on, "unknown " S_show_axes " choice"); if (Xen_is_bound(snd)) return(channel_set(snd, chn, on, CP_SHOW_AXES, S_set S_show_axes)); set_show_axes((show_axes_t)val); return(C_int_to_Xen_integer((int)show_axes(ss))); } with_three_setter_args(g_set_show_axes_reversed, g_set_show_axes) static Xen g_graphs_horizontal(Xen snd, Xen chn) { #define H_graphs_horizontal "(" S_graphs_horizontal " :optional snd chn): " PROC_TRUE " if the time domain, fft, and lisp graphs are layed out horizontally" if (Xen_is_bound(snd)) return(channel_get(snd, chn, CP_GRAPHS_HORIZONTAL, S_graphs_horizontal)); return(C_bool_to_Xen_boolean(graphs_horizontal(ss))); } static Xen g_set_graphs_horizontal(Xen val, Xen snd, Xen chn) { Xen_check_type(Xen_is_boolean(val), val, 1, S_set S_graphs_horizontal, "a boolean"); if (Xen_is_bound(snd)) return(channel_set(snd, chn, val, CP_GRAPHS_HORIZONTAL, S_set S_graphs_horizontal)); set_graphs_horizontal(Xen_boolean_to_C_bool(val)); return(C_bool_to_Xen_boolean(graphs_horizontal(ss))); } with_three_setter_args(g_set_graphs_horizontal_reversed, g_set_graphs_horizontal) void write_transform_peaks(FILE *fd, chan_info *ucp) { /* put (sync'd) peak info in (possibly temporary) file. * this used to follow the displays, but I think I'd rather get all the data at high precision */ int i, chn; sync_info *si = NULL; fprintf(fd, "Snd: fft peaks (%s)\n\n", snd_local_time()); si = sync_to_chan(ucp); for (chn = 0; chn < si->chans; chn++) { chan_info *cp; fft_info *fp; cp = si->cps[chn]; fp = cp->fft; if (fp) { axis_info *fap; fap = fp->axis; if ((fap) && (fap->graph_active)) { snd_info *sp; mus_float_t srate2; axis_info *ap; fft_peak *peak_freqs = NULL; fft_peak *peak_amps = NULL; mus_float_t *data; int num_peaks, samps, srate; ap = cp->axis; sp = cp->sound; data = fp->data; srate = snd_srate(sp); srate2 = (mus_float_t)srate * .5; samps = (int)(fp->current_size * 0.5); peak_freqs = (fft_peak *)calloc(cp->max_transform_peaks, sizeof(fft_peak)); peak_amps = (fft_peak *)calloc(cp->max_transform_peaks, sizeof(fft_peak)); num_peaks = find_and_sort_transform_peaks(data, peak_freqs, cp->max_transform_peaks, 0, samps, 0.5, fp->scale); if ((num_peaks != 1) || (peak_freqs[0].freq != 0.0)) { fprintf(fd, "%s", sp->short_filename); if (sp->nchans > 1) fprintf(fd, ": chan %d", cp->chan); fprintf(fd, ", fft %lld points beginning at sample %lld (%.3f secs), %s\n\n", fp->current_size, ap->losamp, (float)((double)(ap->losamp) / (double)srate), mus_fft_window_name(cp->fft_window)); /* was Xen name */ for (i = 0; i < num_peaks; i++) fprintf(fd, " %.*f %.*f\n", 6, peak_freqs[i].freq * srate2, 6, peak_freqs[i].amp); fprintf(fd, "\n"); } if (peak_freqs) {free(peak_freqs); peak_freqs = NULL;} if (peak_amps) {free(peak_amps); peak_amps = NULL;} } } } if (si) si = free_sync_info(si); } static Xen g_peaks(Xen filename, Xen snd, Xen chn_n) { #define H_peaks "(" S_peaks " :optional filename snd chn): write current fft peaks data to filename, or \ to the info dialog if filename is omitted" char *name = NULL; chan_info *cp; bool post_to_dialog = true; FILE *fd = NULL; Xen_check_type((Xen_is_string(filename) || (Xen_is_false(filename)) || (!Xen_is_bound(filename))), filename, 1, S_peaks, "a string or " PROC_FALSE); Snd_assert_channel(S_peaks, snd, chn_n, 2); cp = get_cp(snd, chn_n, S_peaks); if (!cp) return(Xen_false); if (Xen_is_string(filename)) { name = mus_expand_filename(Xen_string_to_C_string(filename)); if ((name) && (mus_strlen(name) > 0)) { fd = FOPEN(name, "w"); post_to_dialog = false; } } else { name = snd_tempnam(); fd = FOPEN(name, "w"); } if (!fd) Xen_error(Xen_make_error_type("cant-open-file"), Xen_list_3(C_string_to_Xen_string(S_peaks ": ~S ~A"), C_string_to_Xen_string(name), C_string_to_Xen_string(snd_io_strerror()))); write_transform_peaks(fd, cp); snd_fclose(fd, name); if (post_to_dialog) { char *str; str = file_to_string(name); if (str) { post_it("fft peaks", str); free(str); } snd_remove(name, IGNORE_CACHE); } free(name); return(filename); } static Xen g_left_sample(Xen snd, Xen chn_n) { #define H_left_sample "(" S_left_sample " :optional snd chn): left sample number in time domain window" return(channel_get(snd, chn_n, CP_LOSAMP, S_left_sample)); } static Xen g_set_left_sample(Xen on, Xen snd, Xen chn_n) { Xen_check_type(Xen_is_llong(on) || !Xen_is_bound(on), on, 1, S_set S_left_sample, "an integer"); return(channel_set(snd, chn_n, on, CP_LOSAMP, S_set S_left_sample)); } with_three_setter_args(g_set_left_sample_reversed, g_set_left_sample) static Xen g_right_sample(Xen snd, Xen chn_n) { #define H_right_sample "(" S_right_sample " :optional snd chn): right sample number in time domain window" return(channel_get(snd, chn_n, CP_HISAMP, S_right_sample)); } static Xen g_set_right_sample(Xen on, Xen snd, Xen chn_n) { Xen_check_type(Xen_is_llong(on) || !Xen_is_bound(on), on, 1, S_set S_right_sample, "an integer"); return(channel_set(snd, chn_n, on, CP_HISAMP, S_set S_right_sample)); } with_three_setter_args(g_set_right_sample_reversed, g_set_right_sample) static Xen g_channel_properties(Xen snd, Xen chn_n) { #define H_channel_properties "(" S_channel_properties " :optional snd chn): \ A property list associated with the given channel. It is set to () at the time a sound is opened." return(channel_get(snd, chn_n, CP_PROPERTIES, S_channel_properties)); } static Xen g_set_channel_properties(Xen on, Xen snd, Xen chn_n) { /* Xen_check_type(Xen_is_list(on), on, 1, S_set S_channel_properties, "a property list"); */ return(channel_set(snd, chn_n, on, CP_PROPERTIES, S_set S_channel_properties)); } with_three_setter_args(g_set_channel_properties_reversed, g_set_channel_properties) static Xen g_channel_property(Xen key, Xen snd, Xen chn) { #define H_channel_property "(" S_channel_property " key snd chn) returns the value associated with 'key' in \ the given channel's property list, or " PROC_FALSE "." return(Xen_assoc_ref(key, g_channel_properties(snd, chn))); } #if HAVE_SCHEME static Xen g_set_channel_property(Xen val, Xen key, Xen snd, Xen chn) #else static Xen g_set_channel_property(Xen key, Xen val, Xen snd, Xen chn) #endif { g_set_channel_properties(Xen_assoc_set(key, val, g_channel_properties(snd, chn)), snd, chn); return(val); } with_four_setter_args(g_set_channel_property_reversed, g_set_channel_property) static Xen g_edit_properties(Xen snd, Xen chn_n, Xen pos) { #define H_edit_properties "(" S_edit_properties " :optional snd chn edpos): \ A property list associated with the given edit. It is set to () at the time an edit is performed and cleared when that edit is no longer accessible." chan_info *cp; int edpos; Snd_assert_channel(S_edit_properties, snd, chn_n, 1); cp = get_cp(snd, chn_n, S_edit_properties); if (!cp) return(Xen_false); edpos = to_c_edit_position(cp, pos, S_edit_properties, 3); if (!(Xen_is_vector(cp->edits[edpos]->properties))) { cp->edits[edpos]->properties = Xen_make_vector(1, Xen_empty_list); cp->edits[edpos]->properties_gc_loc = snd_protect(cp->edits[edpos]->properties); } return(Xen_vector_ref(cp->edits[edpos]->properties, 0)); } static Xen g_set_edit_properties(Xen on, Xen snd, Xen chn_n, Xen pos) { chan_info *cp; int edpos; Snd_assert_channel(S_set S_edit_properties, snd, chn_n, 1); cp = get_cp(snd, chn_n, S_set S_edit_properties); if (!cp) return(Xen_false); edpos = to_c_edit_position(cp, pos, S_set S_edit_properties, 3); if (!(Xen_is_vector(cp->edits[edpos]->properties))) { cp->edits[edpos]->properties = Xen_make_vector(1, Xen_empty_list); cp->edits[edpos]->properties_gc_loc = snd_protect(cp->edits[edpos]->properties); } Xen_vector_set(cp->edits[edpos]->properties, 0, on); return(Xen_vector_ref(cp->edits[edpos]->properties, 0)); } with_four_setter_args(g_set_edit_properties_reversed, g_set_edit_properties) static Xen g_edit_property(Xen key, Xen snd, Xen chn, Xen pos) { #define H_edit_property "(" S_edit_property " key snd chn pos) returns the value associated with 'key' in the \ given edit's property list, or " PROC_FALSE "." Snd_assert_channel(S_edit_property, snd, chn, 2); return(Xen_assoc_ref(key, g_edit_properties(snd, chn, pos))); } static Xen g_set_edit_property(Xen key, Xen val, Xen snd, Xen chn, Xen pos) { Snd_assert_channel(S_edit_property, snd, chn, 3); g_set_edit_properties(Xen_assoc_set(key, val, g_edit_properties(snd, chn, pos)), snd, chn, pos); return(val); } #if HAVE_SCHEME static Xen g_set_edit_property_reversed(s7_scheme *sc, s7_pointer args) { int len; len = Xen_list_length(args); if (len == 2) return(g_set_edit_property(Xen_list_ref(args, 0), Xen_list_ref(args, 1), Xen_undefined, Xen_undefined, Xen_undefined)); if (len == 3) return(g_set_edit_property(Xen_list_ref(args, 0), Xen_list_ref(args, 2), Xen_list_ref(args, 1), Xen_undefined, Xen_undefined)); if (len == 4) return(g_set_edit_property(Xen_list_ref(args, 0), Xen_list_ref(args, 3), Xen_list_ref(args, 1), Xen_list_ref(args, 2), Xen_undefined)); return(g_set_edit_property(Xen_list_ref(args, 0), Xen_list_ref(args, 4), Xen_list_ref(args, 1), Xen_list_ref(args, 2), Xen_list_ref(args, 3))); } #endif static Xen g_edits(Xen snd, Xen chn_n) { #define H_edits "(" S_edits " :optional snd chn): -> (list undoable-edits redoable-edits) in snd's channel chn" chan_info *cp; int i; Snd_assert_channel(S_edits, snd, chn_n, 1); cp = get_cp(snd, chn_n, S_edits); if (!cp) return(Xen_false); for (i = cp->edit_ctr + 1; i < cp->edit_size; i++) if (!(cp->edits[i])) break; return(Xen_list_2(C_int_to_Xen_integer(cp->edit_ctr), C_int_to_Xen_integer(i - cp->edit_ctr - 1))); } /* Xen ldata, Xen xlabel, Xen x0, Xen x1, Xen y0, Xen y1, Xen snd, Xen chn_n, Xen force_display, Xen show_axes */ static Xen g_graph(Xen args) { #define H_graph "(" S_graph " data :optional xlabel (x0 0.0) (x1 1.0) y0 y1 snd chn (force-display " PROC_TRUE ") show-axes): \ displays 'data' as a graph with x axis label 'xlabel', axis units going from x0 to x1 and y0 to y1; 'data' can be a list or a " S_vct ". \ If 'data' is a list of numbers, it is treated as an envelope." chan_info *cp; lisp_grf *lg; Xen data = Xen_undefined; char *label = NULL; int i, len = 0, graphs; bool need_update = false; mus_float_t ymin = 32768.0, ymax = -32768.0, val; double nominal_x0 = 0.0, nominal_x1 = 1.0; int old_height = 0, old_width = 0, ww = 0; int old_y_offset = 0, gx0 = 0; Xen arg, ldata, x0 = Xen_undefined, x1 = Xen_undefined; Xen snd = Xen_undefined, chn_n = Xen_undefined, force_display = Xen_undefined, show_axes = Xen_undefined; /* ldata can be a vct or a list of numbers or vcts */ arg = args; ldata = Xen_car(arg); Xen_check_type(((mus_is_vct(ldata)) || ((Xen_is_list(ldata)) && (Xen_list_length(ldata) > 0) && ((Xen_is_number(Xen_car(ldata))) || (mus_is_vct(Xen_car(ldata)))))), ldata, 1, S_graph, "a " S_vct " or a list"); if ((!(Xen_is_list(ldata))) || (Xen_is_number(Xen_car(ldata)))) graphs = 1; else graphs = Xen_list_length(ldata); if (graphs == 0) return(Xen_false); arg = Xen_cdr(arg); if (!Xen_is_null(arg)) { Xen xlabel; xlabel = Xen_car(arg); Xen_check_type(Xen_is_string(xlabel), xlabel, 2, S_graph, "a string (x axis label)"); label = mus_strdup(Xen_string_to_C_string(xlabel)); arg = Xen_cdr(arg); if (!Xen_is_null(arg)) { x0 = Xen_car(arg); Xen_check_type(Xen_is_number(x0), x0, 3, S_graph, "a number (x0)"); nominal_x0 = Xen_real_to_C_double(x0); arg = Xen_cdr(arg); if (!Xen_is_null(arg)) { x1 = Xen_car(arg); Xen_check_type(Xen_is_number(x1), x1, 4, S_graph, "a number (x1)"); nominal_x1 = Xen_real_to_C_double(x1); arg = Xen_cdr(arg); if (!Xen_is_null(arg)) { Xen y0; y0 = Xen_car(arg); Xen_check_type(Xen_is_number(y0), y0, 5, S_graph, "a number (y0)"); ymin = Xen_real_to_C_double(y0); arg = Xen_cdr(arg); if (!Xen_is_null(arg)) { Xen y1; y1 = Xen_car(arg); Xen_check_type(Xen_is_number(y1), y1, 6, S_graph, "a number (y1)"); ymax = Xen_real_to_C_double(y1); arg = Xen_cdr(arg); if (!Xen_is_null(arg)) { snd = Xen_car(arg); arg = Xen_cdr(arg); if (!Xen_is_null(arg)) { chn_n = Xen_car(arg); arg = Xen_cdr(arg); if (!Xen_is_null(arg)) { force_display = Xen_car(arg); Xen_check_type(Xen_is_boolean(force_display), force_display, 9, S_graph, "a boolean (force-display)"); arg = Xen_cdr(arg); if (!Xen_is_null(arg)) { show_axes = Xen_car(arg); Xen_check_type(Xen_is_integer(show_axes), show_axes, 10, S_graph, "an integer (show-axes choice)"); } } } } } } } } } Snd_assert_channel(S_graph, snd, chn_n, 7); cp = get_cp(snd, chn_n, S_graph); if (!cp) return(Xen_false); if ((cp->sound_ctr == NOT_A_SOUND) || (cp->sounds == NULL) || (cp->sounds[cp->sound_ctr] == NULL) || (cp->axis == NULL)) return(Xen_false); lg = cp->lisp_info; if (lg) { axis_info *uap = NULL; uap = cp->lisp_info->axis; if (uap) { old_height = uap->height; old_width = uap->width; ww = uap->window_width; gx0 = uap->graph_x0; old_y_offset = uap->y_offset; } if (graphs != lg->graphs) { free_lisp_info(cp); cp->lisp_info = NULL; } } if (!(cp->lisp_info)) { lg = (lisp_grf *)calloc(graphs, sizeof(lisp_grf)); cp->lisp_info = lg; lg->len = (int *)calloc(graphs, sizeof(int)); lg->graphs = graphs; lg->data = (mus_float_t **)calloc(graphs, sizeof(mus_float_t *)); need_update = true; } cp->lisp_info->show_axes = cp->show_axes; if (Xen_is_integer(show_axes)) { show_axes_t aval; aval = (show_axes_t)Xen_integer_to_C_int(show_axes); if (aval < NUM_SHOW_AXES) cp->lisp_info->show_axes = aval; } if ((Xen_is_list(ldata)) && (Xen_is_number(Xen_car(ldata)))) { Xen lst; len = Xen_list_length(ldata); /* just one graph to display */ lg = cp->lisp_info; lg->env_data = 1; if (lg->len[0] != len) { if (lg->data[0]) free(lg->data[0]); lg->data[0] = (mus_float_t *)calloc(len, sizeof(mus_float_t)); lg->len[0] = len; } for (i = 0, lst = Xen_copy_arg(ldata); i < len; i++, lst = Xen_cdr(lst)) lg->data[0][i] = Xen_real_to_C_double(Xen_car(lst)); if (ymin > ymax) { for (i = 1; i < len; i += 2) { val = lg->data[0][i]; if (ymin > val) ymin = val; if (ymax < val) ymax = val; } } if (!Xen_is_number(x0)) nominal_x0 = lg->data[0][0]; if (!Xen_is_number(x1)) nominal_x1 = lg->data[0][len - 2]; } else { int graph; lg = cp->lisp_info; lg->env_data = 0; for (graph = 0; graph < graphs; graph++) { vct *v = NULL; if (Xen_is_list(ldata)) data = Xen_list_ref(ldata, graph); else data = ldata; v = Xen_to_vct(data); len = mus_vct_length(v); if (lg->len[graph] != len) { if (lg->data[graph]) free(lg->data[graph]); lg->data[graph] = (mus_float_t *)calloc(len, sizeof(mus_float_t)); lg->len[graph] = len; } memcpy((void *)(lg->data[graph]), (void *)mus_vct_data(v), len * sizeof(mus_float_t)); if (ymin > ymax) { for (i = 0; i < len; i++) { val = lg->data[graph][i]; if (ymin > val) ymin = val; if (ymax < val) ymax = val; } } } } lg->axis = make_axis_info(cp, nominal_x0, nominal_x1, ymin, ymax, label, nominal_x0, nominal_x1, ymin, ymax, lg->axis); lg->axis->y_offset = old_y_offset; if (label) free(label); if (need_update) { axis_info *uap = NULL; uap = lg->axis; uap->height = old_height; uap->window_width = ww; uap->width = old_width; uap->graph_x0 = gx0; } cp->graph_lisp_on = true; if ((!Xen_is_bound(force_display)) || (!Xen_is_false(force_display))) { if (need_update) update_graph(cp); else display_channel_lisp_data(cp); } return(Xen_false); /* returning #f here because graph might be last thing in lisp-graph-hook, and we * don't want its return value mistaken for the "pixel_list" that that hook function * can return. */ } #if HAVE_GL #define S_glSpectrogram "glSpectrogram" static Xen g_gl_spectrogram(Xen data, Xen gl_list, Xen cutoff, Xen use_dB, Xen min_dB, Xen scale, Xen br, Xen bg, Xen bb) { #define H_glSpectrogram "(" S_glSpectrogram " data gl-list cutoff use-dB min-dB scale br bg bb) takes spectrogram \ data and passes it to openGL. See snd-gl.scm for an example." sono_info *si; int i; vct *v; Xen_check_type(Xen_is_vector(data), data, 1, S_glSpectrogram, "a vector of " S_vct "s"); Xen_check_type(Xen_is_integer(gl_list), gl_list, 2, S_glSpectrogram, "an integer"); Xen_check_type(Xen_is_number(cutoff), cutoff, 3, S_glSpectrogram, "a number"); Xen_check_type(Xen_is_boolean(use_dB), use_dB, 4, S_glSpectrogram, "a boolean"); Xen_check_type(Xen_is_number(min_dB), min_dB, 5, S_glSpectrogram, "a number"); Xen_check_type(Xen_is_number(scale), scale, 6, S_glSpectrogram, "a number"); Xen_check_type(Xen_is_number(br), br, 7, S_glSpectrogram, "a number (red value)"); Xen_check_type(Xen_is_number(bg), bg, 8, S_glSpectrogram, "a number (green value)"); Xen_check_type(Xen_is_number(bb), bb, 9, S_glSpectrogram, "a number (blue value)"); si = (sono_info *)calloc(1, sizeof(sono_info)); si->active_slices = Xen_vector_length(data); si->data = (mus_float_t **)calloc(si->active_slices, sizeof(mus_float_t *)); v = xen_to_vct(Xen_vector_ref(data, 0)); si->target_bins = mus_vct_length(v); si->scale = Xen_real_to_C_double(scale); for (i = 0; i < si->active_slices; i++) { v = xen_to_vct(Xen_vector_ref(data, i)); si->data[i] = mus_vct_data(v); } gl_spectrogram(si, Xen_integer_to_C_int(gl_list), Xen_real_to_C_double(cutoff), Xen_boolean_to_C_bool(use_dB), Xen_real_to_C_double(min_dB), float_to_rgb(Xen_real_to_C_double(br)), float_to_rgb(Xen_real_to_C_double(bg)), float_to_rgb(Xen_real_to_C_double(bb))); free(si->data); free(si); return(Xen_false); } #endif static Xen g_channel_data(Xen snd, Xen chn) { #define H_channel_data "(" S_channel_data " :optional snd chn) returns the in-core samples associated with the \ given channel." chan_info *cp; Snd_assert_channel(S_channel_data, snd, chn, 1); cp = get_cp(snd, chn, S_channel_data); if ((cp) && (cp->sound) && (cp->sound->inuse == SOUND_WRAPPER) && (cp->sounds) && (cp->sounds[0]) && (cp->sounds[0]->buffered_data)) return(xen_make_vct_wrapper(cp->edits[0]->samples, cp->sounds[0]->buffered_data)); return(Xen_false); } static Xen g_is_variable_graph(Xen index) { #define H_is_variable_graph "(" S_is_variable_graph " :optional snd): " PROC_TRUE " if snd is a variable graph (from " S_make_variable_graph ")." snd_info *sp; Xen_check_type(Xen_is_integer(index) || xen_is_sound(index), index, 1, S_is_variable_graph, "a sound"); sp = get_sp(index); if (sp) return(C_bool_to_Xen_boolean(sp->inuse == SOUND_WRAPPER)); return(Xen_false); } /* free-variable-graph is much too tricky because callbacks can be invoked after the * controlling snd_info struct has been freed. In Motif it appears to work to call * XtHasCallbacks/XtRemoveAllCallbacks on all children of the parent widget, but * I didn't try the gtk equivalent -- the whole thing is too messy to be trustworthy. */ static Xen g_make_variable_graph(Xen container, Xen name, Xen length, Xen srate) { #define H_make_variable_graph "(" S_make_variable_graph " container :optional name length srate) returns a sound index referring \ to a standard Snd channel graph placed in the widget 'container'." snd_info *sp; chan_info *cp; int rate, initial_length; Xen_check_type(Xen_is_widget(container), container, 1, S_make_variable_graph, "a widget"); Xen_check_type(Xen_is_string_or_unbound(name), name, 2, S_make_variable_graph, "a string"); Xen_check_type(Xen_is_integer_or_unbound(length), length, 3, S_make_variable_graph, "an integer"); Xen_check_type(Xen_is_integer_or_unbound(srate), srate, 4, S_make_variable_graph, "an integer"); rate = (Xen_is_integer(srate)) ? Xen_integer_to_C_int(srate) : (int)mus_srate(); initial_length = (Xen_is_integer(length)) ? Xen_integer_to_C_int(length) : 8192; sp = make_simple_channel_display(rate, initial_length, WITH_FW_BUTTONS, graph_style(ss), (widget_t)(Xen_unwrap_widget(container)), WITH_EVENTS); if (sp == NULL) /* can only happen if "container" is not a form widget (or perhaps no container XtWindow) */ Xen_error(Xen_make_error_type("wrong-type-arg"), Xen_list_2(C_string_to_Xen_string(S_make_variable_graph ": container, ~A, must be a Form widget with a legitimate window"), container)); sp->user_read_only = FILE_READ_ONLY; sp->index = find_free_sound_slot_for_channel_display(); ss->sounds[sp->index] = sp; cp = sp->chans[0]; if (Xen_is_string(name)) { axis_info *ap; sp->filename = mus_strdup(Xen_string_to_C_string(name)); sp->short_filename = mus_strdup(sp->filename); ap = cp->axis; if (ap->xlabel) free(ap->xlabel); ap->xlabel = mus_strdup(sp->filename); if (ap->default_xlabel) free(ap->default_xlabel); ap->default_xlabel = NULL; if (ap->ylabel) free(ap->ylabel); ap->ylabel = NULL; } else { sp->filename = mus_strdup("variable"); sp->short_filename = mus_strdup("var"); } cp->sounds[0] = make_snd_data_buffer_for_simple_channel(initial_length); cp->edits[0] = initial_ed_list(0, initial_length - 1); cp->edits[0]->origin = mus_strdup(S_make_variable_graph); return(C_int_to_Xen_sound(sp->index)); } static Xen g_zoom_focus_style(void) { if (zoom_focus_style(ss) != ZOOM_FOCUS_PROC) return(C_int_to_Xen_integer((int)zoom_focus_style(ss))); return(ss->zoom_focus_proc); } static Xen g_set_zoom_focus_style(Xen focus) { #define H_zoom_focus_style "(" S_zoom_focus_style "): one of " S_zoom_focus_left ", " S_zoom_focus_right ", " S_zoom_focus_middle \ ", or " S_zoom_focus_active ". This determines what zooming centers on (default: " S_zoom_focus_active "). It can also \ be a function of 6 args (snd chan zx x0 x1 range) that returns the new window left edge as a float." Xen_check_type((Xen_is_integer(focus)) || (Xen_is_procedure(focus)), focus, 1, S_set S_zoom_focus_style, "an integer or a function"); if ((Xen_is_procedure(focus)) && (!(procedure_arity_ok(focus, 6)))) return(snd_bad_arity_error(S_set S_zoom_focus_style, C_string_to_Xen_string("zoom focus func should take 4 args"), focus)); if (zoom_focus_style(ss) == ZOOM_FOCUS_PROC) { snd_unprotect_at(ss->zoom_focus_proc_loc); ss->zoom_focus_proc = Xen_undefined; } if (Xen_is_integer(focus)) { int in_choice; zoom_focus_t choice; in_choice = Xen_integer_to_C_int(focus); if (in_choice < 0) Xen_out_of_range_error(S_set S_zoom_focus_style, 1, focus, S_zoom_focus_style " should be " S_zoom_focus_left ", " S_zoom_focus_right ", " S_zoom_focus_middle ", or " S_zoom_focus_active); choice = (zoom_focus_t)in_choice; if (choice > ZOOM_FOCUS_MIDDLE) Xen_out_of_range_error(S_set S_zoom_focus_style, 1, focus, S_zoom_focus_style " should be " S_zoom_focus_left ", " S_zoom_focus_right ", " S_zoom_focus_middle ", or " S_zoom_focus_active); set_zoom_focus_style(choice); return(C_int_to_Xen_integer((int)zoom_focus_style(ss))); } set_zoom_focus_style(ZOOM_FOCUS_PROC); ss->zoom_focus_proc = focus; ss->zoom_focus_proc_loc = snd_protect(focus); return(focus); } static Xen g_with_gl(void) {return(C_bool_to_Xen_boolean(with_gl(ss)));} static Xen g_set_with_gl(Xen val) { #define H_with_gl "(" S_with_gl "): " PROC_TRUE " if Snd should use GL graphics" Xen_check_type(Xen_is_boolean(val), val, 1, S_set S_with_gl, "a boolean"); #if HAVE_GL set_with_gl(Xen_boolean_to_C_bool(val), true); for_each_chan(update_graph); #endif return(C_bool_to_Xen_boolean(with_gl(ss))); } static Xen g_sync_style(void) { return(C_int_to_Xen_integer((int)sync_style(ss))); } static Xen g_set_sync_style(Xen style) { int choice; #define H_sync_style "(" S_sync_style "): one of " S_sync_none ", " S_sync_all ", " \ ", or " S_sync_by_sound ". This determines how channels are grouped when a sound is opened." Xen_check_type(Xen_is_integer(style), style, 1, S_set S_sync_style, "a sync choice"); choice = Xen_integer_to_C_int(style); if ((choice < 0) || (choice >= NUM_SYNC_STYLES)) Xen_out_of_range_error(S_set S_sync_style, 0, style, "style should be one of " S_sync_none ", " S_sync_all ", or " S_sync_by_sound); set_sync_style((sync_style_t)choice); return(C_int_to_Xen_integer((int)sync_style(ss))); } Xen_wrap_1_arg(g_is_variable_graph_w, g_is_variable_graph) Xen_wrap_4_optional_args(g_make_variable_graph_w, g_make_variable_graph) Xen_wrap_2_optional_args(g_channel_data_w, g_channel_data) Xen_wrap_any_args(g_graph_w, g_graph) Xen_wrap_2_optional_args(g_edits_w, g_edits) Xen_wrap_3_optional_args(g_peaks_w, g_peaks) Xen_wrap_2_optional_args(g_edit_hook_w, g_edit_hook) Xen_wrap_2_optional_args(g_after_edit_hook_w, g_after_edit_hook) Xen_wrap_2_optional_args(g_undo_hook_w, g_undo_hook) Xen_wrap_2_optional_args(g_ap_sx_w, g_ap_sx) Xen_wrap_2_optional_args(g_ap_sy_w, g_ap_sy) Xen_wrap_2_optional_args(g_ap_zx_w, g_ap_zx) Xen_wrap_2_optional_args(g_ap_zy_w, g_ap_zy) Xen_wrap_3_optional_args(g_framples_w, g_framples) Xen_wrap_3_optional_args(g_maxamp_position_w, g_maxamp_position) Xen_wrap_3_optional_args(g_maxamp_w, g_maxamp) Xen_wrap_2_optional_args(g_cursor_position_w, g_cursor_position) Xen_wrap_2_optional_args(g_edit_position_w, g_edit_position) Xen_wrap_2_optional_args(g_transform_graph_on_w, g_transform_graph_on) Xen_wrap_2_optional_args(g_timer_graph_on_w, g_timer_graph_on) Xen_wrap_2_optional_args(g_lisp_graph_on_w, g_lisp_graph_on) Xen_wrap_2_optional_args(g_squelch_update_w, g_squelch_update) Xen_wrap_3_optional_args(g_cursor_w, g_cursor) Xen_wrap_2_optional_args(g_cursor_style_w, g_cursor_style) Xen_wrap_2_optional_args(g_tracking_cursor_style_w, g_tracking_cursor_style) Xen_wrap_2_optional_args(g_cursor_size_w, g_cursor_size) Xen_wrap_2_optional_args(g_left_sample_w, g_left_sample) Xen_wrap_2_optional_args(g_right_sample_w, g_right_sample) Xen_wrap_2_optional_args(g_channel_properties_w, g_channel_properties) Xen_wrap_3_optional_args(g_channel_property_w, g_channel_property) Xen_wrap_3_optional_args(g_edit_properties_w, g_edit_properties) Xen_wrap_4_optional_args(g_edit_property_w, g_edit_property) Xen_wrap_2_optional_args(g_max_transform_peaks_w, g_max_transform_peaks) Xen_wrap_2_optional_args(g_show_y_zero_w, g_show_y_zero) Xen_wrap_2_optional_args(g_show_grid_w, g_show_grid) Xen_wrap_2_optional_args(g_grid_density_w, g_grid_density) Xen_wrap_2_optional_args(g_show_sonogram_cursor_w, g_show_sonogram_cursor) Xen_wrap_2_optional_args(g_show_marks_w, g_show_marks) Xen_wrap_2_optional_args(g_time_graph_type_w, g_time_graph_type) Xen_wrap_2_optional_args(g_wavo_hop_w, g_wavo_hop) Xen_wrap_2_optional_args(g_wavo_trace_w, g_wavo_trace) Xen_wrap_2_optional_args(g_show_transform_peaks_w, g_show_transform_peaks) Xen_wrap_2_optional_args(g_zero_pad_w, g_zero_pad) Xen_wrap_2_optional_args(g_with_verbose_cursor_w, g_with_verbose_cursor) Xen_wrap_2_optional_args(g_fft_log_frequency_w, g_fft_log_frequency) Xen_wrap_2_optional_args(g_fft_log_magnitude_w, g_fft_log_magnitude) Xen_wrap_2_optional_args(g_fft_with_phases_w, g_fft_with_phases) Xen_wrap_2_optional_args(g_min_dB_w, g_min_dB) Xen_wrap_2_optional_args(g_wavelet_type_w, g_wavelet_type) Xen_wrap_2_optional_args(g_spectrum_end_w, g_spectrum_end) Xen_wrap_2_optional_args(g_spectrum_start_w, g_spectrum_start) Xen_wrap_2_optional_args(g_spectro_x_angle_w, g_spectro_x_angle) Xen_wrap_2_optional_args(g_spectro_x_scale_w, g_spectro_x_scale) Xen_wrap_2_optional_args(g_spectro_y_angle_w, g_spectro_y_angle) Xen_wrap_2_optional_args(g_spectro_y_scale_w, g_spectro_y_scale) Xen_wrap_2_optional_args(g_spectro_z_angle_w, g_spectro_z_angle) Xen_wrap_2_optional_args(g_spectro_z_scale_w, g_spectro_z_scale) Xen_wrap_2_optional_args(g_fft_window_alpha_w, g_fft_window_alpha) Xen_wrap_2_optional_args(g_fft_window_beta_w, g_fft_window_beta) Xen_wrap_2_optional_args(g_spectro_hop_w, g_spectro_hop) Xen_wrap_2_optional_args(g_transform_size_w, g_transform_size) Xen_wrap_2_optional_args(g_transform_graph_type_w, g_transform_graph_type) Xen_wrap_2_optional_args(g_fft_window_w, g_fft_window) Xen_wrap_2_optional_args(g_transform_type_w, g_transform_type) Xen_wrap_2_optional_args(g_transform_normalization_w, g_transform_normalization) Xen_wrap_2_optional_args(g_show_mix_waveforms_w, g_show_mix_waveforms) Xen_wrap_2_optional_args(g_graph_style_w, g_graph_style) Xen_wrap_2_optional_args(g_time_graph_style_w, g_time_graph_style) Xen_wrap_2_optional_args(g_lisp_graph_style_w, g_lisp_graph_style) Xen_wrap_2_optional_args(g_transform_graph_style_w, g_transform_graph_style) Xen_wrap_2_optional_args(g_dot_size_w, g_dot_size) Xen_wrap_2_optional_args(g_x_axis_style_w, g_x_axis_style) Xen_wrap_2_optional_args(g_beats_per_measure_w, g_beats_per_measure) Xen_wrap_2_optional_args(g_beats_per_minute_w, g_beats_per_minute) Xen_wrap_2_optional_args(g_show_axes_w, g_show_axes) Xen_wrap_2_optional_args(g_graphs_horizontal_w, g_graphs_horizontal) Xen_wrap_2_optional_args(g_update_time_graph_w, g_update_time_graph) Xen_wrap_2_optional_args(g_update_lisp_graph_w, g_update_lisp_graph) Xen_wrap_2_optional_args(g_update_transform_graph_w, g_update_transform_graph) Xen_wrap_no_args(g_zoom_focus_style_w, g_zoom_focus_style) Xen_wrap_1_arg(g_set_zoom_focus_style_w, g_set_zoom_focus_style) Xen_wrap_no_args(g_sync_style_w, g_sync_style) Xen_wrap_1_arg(g_set_sync_style_w, g_set_sync_style) Xen_wrap_no_args(g_with_gl_w, g_with_gl) Xen_wrap_1_arg(g_set_with_gl_w, g_set_with_gl) #if HAVE_SCHEME #define g_set_ap_sx_w g_set_ap_sx_reversed #define g_set_ap_sy_w g_set_ap_sy_reversed #define g_set_ap_zx_w g_set_ap_zx_reversed #define g_set_ap_zy_w g_set_ap_zy_reversed #define g_set_framples_w g_set_framples_reversed #define g_set_maxamp_w g_set_maxamp_reversed #define g_set_edit_position_w g_set_edit_position_reversed #define g_set_transform_graph_on_w g_set_transform_graph_on_reversed #define g_set_timer_graph_on_w g_set_timer_graph_on_reversed #define g_set_lisp_graph_on_w g_set_lisp_graph_on_reversed #define g_set_squelch_update_w g_set_squelch_update_reversed #define g_set_cursor_w g_set_cursor_reversed #define g_set_cursor_style_w g_set_cursor_style_reversed #define g_set_tracking_cursor_style_w g_set_tracking_cursor_style_reversed #define g_set_cursor_size_w g_set_cursor_size_reversed #define g_set_left_sample_w g_set_left_sample_reversed #define g_set_right_sample_w g_set_right_sample_reversed #define g_set_channel_properties_w g_set_channel_properties_reversed #define g_set_channel_property_w g_set_channel_property_reversed #define g_set_edit_properties_w g_set_edit_properties_reversed #define g_set_edit_property_w g_set_edit_property_reversed #define g_set_max_transform_peaks_w g_set_max_transform_peaks_reversed #define g_set_show_y_zero_w g_set_show_y_zero_reversed #define g_set_show_grid_w g_set_show_grid_reversed #define g_set_grid_density_w g_set_grid_density_reversed #define g_set_show_sonogram_cursor_w g_set_show_sonogram_cursor_reversed #define g_set_show_marks_w g_set_show_marks_reversed #define g_set_time_graph_type_w g_set_time_graph_type_reversed #define g_set_wavo_hop_w g_set_wavo_hop_reversed #define g_set_wavo_trace_w g_set_wavo_trace_reversed #define g_set_show_transform_peaks_w g_set_show_transform_peaks_reversed #define g_set_zero_pad_w g_set_zero_pad_reversed #define g_set_with_verbose_cursor_w g_set_with_verbose_cursor_reversed #define g_set_fft_log_frequency_w g_set_fft_log_frequency_reversed #define g_set_fft_log_magnitude_w g_set_fft_log_magnitude_reversed #define g_set_fft_with_phases_w g_set_fft_with_phases_reversed #define g_set_min_dB_w g_set_min_dB_reversed #define g_set_wavelet_type_w g_set_wavelet_type_reversed #define g_set_spectrum_end_w g_set_spectrum_end_reversed #define g_set_spectrum_start_w g_set_spectrum_start_reversed #define g_set_spectro_x_angle_w g_set_spectro_x_angle_reversed #define g_set_spectro_x_scale_w g_set_spectro_x_scale_reversed #define g_set_spectro_y_angle_w g_set_spectro_y_angle_reversed #define g_set_spectro_y_scale_w g_set_spectro_y_scale_reversed #define g_set_spectro_z_angle_w g_set_spectro_z_angle_reversed #define g_set_spectro_z_scale_w g_set_spectro_z_scale_reversed #define g_set_fft_window_alpha_w g_set_fft_window_alpha_reversed #define g_set_fft_window_beta_w g_set_fft_window_beta_reversed #define g_set_spectro_hop_w g_set_spectro_hop_reversed #define g_set_transform_size_w g_set_transform_size_reversed #define g_set_transform_graph_type_w g_set_transform_graph_type_reversed #define g_set_fft_window_w g_set_fft_window_reversed #define g_set_transform_type_w g_set_transform_type_reversed #define g_set_transform_normalization_w g_set_transform_normalization_reversed #define g_set_show_mix_waveforms_w g_set_show_mix_waveforms_reversed #define g_set_graph_style_w g_set_graph_style_reversed #define g_set_time_graph_style_w g_set_time_graph_style_reversed #define g_set_lisp_graph_style_w g_set_lisp_graph_style_reversed #define g_set_transform_graph_style_w g_set_transform_graph_style_reversed #define g_set_dot_size_w g_set_dot_size_reversed #define g_set_x_axis_style_w g_set_x_axis_style_reversed #define g_set_beats_per_measure_w g_set_beats_per_measure_reversed #define g_set_show_axes_w g_set_show_axes_reversed #define g_set_beats_per_minute_w g_set_beats_per_minute_reversed #define g_set_graphs_horizontal_w g_set_graphs_horizontal_reversed #else Xen_wrap_3_optional_args(g_set_ap_sx_w, g_set_ap_sx) Xen_wrap_3_optional_args(g_set_ap_sy_w, g_set_ap_sy) Xen_wrap_3_optional_args(g_set_ap_zx_w, g_set_ap_zx) Xen_wrap_3_optional_args(g_set_ap_zy_w, g_set_ap_zy) Xen_wrap_3_optional_args(g_set_framples_w, g_set_framples) Xen_wrap_3_optional_args(g_set_maxamp_w, g_set_maxamp) Xen_wrap_3_optional_args(g_set_edit_position_w, g_set_edit_position) Xen_wrap_3_optional_args(g_set_transform_graph_on_w, g_set_transform_graph_on) Xen_wrap_3_optional_args(g_set_timer_graph_on_w, g_set_timer_graph_on) Xen_wrap_3_optional_args(g_set_lisp_graph_on_w, g_set_lisp_graph_on) Xen_wrap_3_optional_args(g_set_squelch_update_w, g_set_squelch_update) Xen_wrap_4_optional_args(g_set_cursor_w, g_set_cursor) Xen_wrap_3_optional_args(g_set_cursor_style_w, g_set_cursor_style) Xen_wrap_3_optional_args(g_set_tracking_cursor_style_w, g_set_tracking_cursor_style) Xen_wrap_3_optional_args(g_set_cursor_size_w, g_set_cursor_size) Xen_wrap_3_optional_args(g_set_left_sample_w, g_set_left_sample) Xen_wrap_3_optional_args(g_set_right_sample_w, g_set_right_sample) Xen_wrap_3_optional_args(g_set_channel_properties_w, g_set_channel_properties) Xen_wrap_4_optional_args(g_set_channel_property_w, g_set_channel_property) Xen_wrap_4_optional_args(g_set_edit_properties_w, g_set_edit_properties) Xen_wrap_5_optional_args(g_set_edit_property_w, g_set_edit_property) Xen_wrap_3_optional_args(g_set_max_transform_peaks_w, g_set_max_transform_peaks) Xen_wrap_3_optional_args(g_set_show_y_zero_w, g_set_show_y_zero) Xen_wrap_3_optional_args(g_set_show_grid_w, g_set_show_grid) Xen_wrap_3_optional_args(g_set_grid_density_w, g_set_grid_density) Xen_wrap_3_optional_args(g_set_show_sonogram_cursor_w, g_set_show_sonogram_cursor) Xen_wrap_3_optional_args(g_set_show_marks_w, g_set_show_marks) Xen_wrap_3_optional_args(g_set_time_graph_type_w, g_set_time_graph_type) Xen_wrap_3_optional_args(g_set_wavo_hop_w, g_set_wavo_hop) Xen_wrap_3_optional_args(g_set_wavo_trace_w, g_set_wavo_trace) Xen_wrap_3_optional_args(g_set_show_transform_peaks_w, g_set_show_transform_peaks) Xen_wrap_3_optional_args(g_set_zero_pad_w, g_set_zero_pad) Xen_wrap_3_optional_args(g_set_with_verbose_cursor_w, g_set_with_verbose_cursor) Xen_wrap_3_optional_args(g_set_fft_log_frequency_w, g_set_fft_log_frequency) Xen_wrap_3_optional_args(g_set_fft_log_magnitude_w, g_set_fft_log_magnitude) Xen_wrap_3_optional_args(g_set_fft_with_phases_w, g_set_fft_with_phases) Xen_wrap_3_optional_args(g_set_min_dB_w, g_set_min_dB) Xen_wrap_3_optional_args(g_set_wavelet_type_w, g_set_wavelet_type) Xen_wrap_3_optional_args(g_set_spectrum_end_w, g_set_spectrum_end) Xen_wrap_3_optional_args(g_set_spectrum_start_w, g_set_spectrum_start) Xen_wrap_3_optional_args(g_set_spectro_x_angle_w, g_set_spectro_x_angle) Xen_wrap_3_optional_args(g_set_spectro_x_scale_w, g_set_spectro_x_scale) Xen_wrap_3_optional_args(g_set_spectro_y_angle_w, g_set_spectro_y_angle) Xen_wrap_3_optional_args(g_set_spectro_y_scale_w, g_set_spectro_y_scale) Xen_wrap_3_optional_args(g_set_spectro_z_angle_w, g_set_spectro_z_angle) Xen_wrap_3_optional_args(g_set_spectro_z_scale_w, g_set_spectro_z_scale) Xen_wrap_3_optional_args(g_set_fft_window_alpha_w, g_set_fft_window_alpha) Xen_wrap_3_optional_args(g_set_fft_window_beta_w, g_set_fft_window_beta) Xen_wrap_3_optional_args(g_set_spectro_hop_w, g_set_spectro_hop) Xen_wrap_3_optional_args(g_set_transform_size_w, g_set_transform_size) Xen_wrap_3_optional_args(g_set_transform_graph_type_w, g_set_transform_graph_type) Xen_wrap_3_optional_args(g_set_fft_window_w, g_set_fft_window) Xen_wrap_3_optional_args(g_set_transform_type_w, g_set_transform_type) Xen_wrap_3_optional_args(g_set_transform_normalization_w, g_set_transform_normalization) Xen_wrap_3_optional_args(g_set_show_mix_waveforms_w, g_set_show_mix_waveforms) Xen_wrap_3_optional_args(g_set_graph_style_w, g_set_graph_style) Xen_wrap_3_optional_args(g_set_time_graph_style_w, g_set_time_graph_style) Xen_wrap_3_optional_args(g_set_lisp_graph_style_w, g_set_lisp_graph_style) Xen_wrap_3_optional_args(g_set_transform_graph_style_w, g_set_transform_graph_style) Xen_wrap_3_optional_args(g_set_dot_size_w, g_set_dot_size) Xen_wrap_3_optional_args(g_set_x_axis_style_w, g_set_x_axis_style) Xen_wrap_3_optional_args(g_set_beats_per_measure_w, g_set_beats_per_measure) Xen_wrap_3_optional_args(g_set_show_axes_w, g_set_show_axes) Xen_wrap_3_optional_args(g_set_beats_per_minute_w, g_set_beats_per_minute) Xen_wrap_3_optional_args(g_set_graphs_horizontal_w, g_set_graphs_horizontal) #endif #if HAVE_GL Xen_wrap_9_args(g_gl_spectrogram_w, g_gl_spectrogram) #endif #if HAVE_SCHEME static s7_pointer acc_transform_type(s7_scheme *sc, s7_pointer args) {return(g_set_transform_type(s7_cadr(args), s7_undefined(sc), s7_undefined(sc)));} static s7_pointer acc_show_transform_peaks(s7_scheme *sc, s7_pointer args) {return(g_set_show_transform_peaks(s7_cadr(args), s7_undefined(sc), s7_undefined(sc)));} static s7_pointer acc_show_y_zero(s7_scheme *sc, s7_pointer args) {return(g_set_show_y_zero(s7_cadr(args), s7_undefined(sc), s7_undefined(sc)));} static s7_pointer acc_show_marks(s7_scheme *sc, s7_pointer args) {return(g_set_show_marks(s7_cadr(args), s7_undefined(sc), s7_undefined(sc)));} static s7_pointer acc_show_grid(s7_scheme *sc, s7_pointer args) {return(g_set_show_grid(s7_cadr(args), s7_undefined(sc), s7_undefined(sc)));} static s7_pointer acc_fft_log_frequency(s7_scheme *sc, s7_pointer args) {return(g_set_fft_log_frequency(s7_cadr(args), s7_undefined(sc), s7_undefined(sc)));} static s7_pointer acc_fft_log_magnitude(s7_scheme *sc, s7_pointer args) {return(g_set_fft_log_magnitude(s7_cadr(args), s7_undefined(sc), s7_undefined(sc)));} static s7_pointer acc_fft_with_phases(s7_scheme *sc, s7_pointer args) {return(g_set_fft_with_phases(s7_cadr(args), s7_undefined(sc), s7_undefined(sc)));} static s7_pointer acc_sync_style(s7_scheme *sc, s7_pointer args) {return(g_set_sync_style(s7_cadr(args)));} static s7_pointer acc_show_axes(s7_scheme *sc, s7_pointer args) {return(g_set_show_axes(s7_cadr(args), s7_undefined(sc), s7_undefined(sc)));} static s7_pointer acc_with_verbose_cursor(s7_scheme *sc, s7_pointer args) {return(g_set_with_verbose_cursor(s7_cadr(args), s7_undefined(sc), s7_undefined(sc)));} static s7_pointer acc_spectro_x_scale(s7_scheme *sc, s7_pointer args) {return(g_set_spectro_x_scale(s7_cadr(args), s7_undefined(sc), s7_undefined(sc)));} static s7_pointer acc_spectro_y_scale(s7_scheme *sc, s7_pointer args) {return(g_set_spectro_y_scale(s7_cadr(args), s7_undefined(sc), s7_undefined(sc)));} static s7_pointer acc_spectro_z_scale(s7_scheme *sc, s7_pointer args) {return(g_set_spectro_z_scale(s7_cadr(args), s7_undefined(sc), s7_undefined(sc)));} static s7_pointer acc_spectro_z_angle(s7_scheme *sc, s7_pointer args) {return(g_set_spectro_z_angle(s7_cadr(args), s7_undefined(sc), s7_undefined(sc)));} static s7_pointer acc_spectro_x_angle(s7_scheme *sc, s7_pointer args) {return(g_set_spectro_x_angle(s7_cadr(args), s7_undefined(sc), s7_undefined(sc)));} static s7_pointer acc_spectro_y_angle(s7_scheme *sc, s7_pointer args) {return(g_set_spectro_y_angle(s7_cadr(args), s7_undefined(sc), s7_undefined(sc)));} static s7_pointer acc_spectrum_end(s7_scheme *sc, s7_pointer args) {return(g_set_spectrum_end(s7_cadr(args), s7_undefined(sc), s7_undefined(sc)));} static s7_pointer acc_spectrum_start(s7_scheme *sc, s7_pointer args) {return(g_set_spectrum_start(s7_cadr(args), s7_undefined(sc), s7_undefined(sc)));} static s7_pointer acc_spectro_hop(s7_scheme *sc, s7_pointer args) {return(g_set_spectro_hop(s7_cadr(args), s7_undefined(sc), s7_undefined(sc)));} static s7_pointer acc_wavelet_type(s7_scheme *sc, s7_pointer args) {return(g_set_wavelet_type(s7_cadr(args), s7_undefined(sc), s7_undefined(sc)));} static s7_pointer acc_dot_size(s7_scheme *sc, s7_pointer args) {return(g_set_dot_size(s7_cadr(args), s7_undefined(sc), s7_undefined(sc)));} static s7_pointer acc_zero_pad(s7_scheme *sc, s7_pointer args) {return(g_set_zero_pad(s7_cadr(args), s7_undefined(sc), s7_undefined(sc)));} static s7_pointer acc_wavo_hop(s7_scheme *sc, s7_pointer args) {return(g_set_wavo_hop(s7_cadr(args), s7_undefined(sc), s7_undefined(sc)));} static s7_pointer acc_wavo_trace(s7_scheme *sc, s7_pointer args) {return(g_set_wavo_trace(s7_cadr(args), s7_undefined(sc), s7_undefined(sc)));} static s7_pointer acc_transform_size(s7_scheme *sc, s7_pointer args) {return(g_set_transform_size(s7_cadr(args), s7_undefined(sc), s7_undefined(sc)));} static s7_pointer acc_fft_window(s7_scheme *sc, s7_pointer args) {return(g_set_fft_window(s7_cadr(args), s7_undefined(sc), s7_undefined(sc)));} static s7_pointer acc_transform_graph_type(s7_scheme *sc, s7_pointer args) {return(g_set_transform_graph_type(s7_cadr(args), s7_undefined(sc), s7_undefined(sc)));} static s7_pointer acc_time_graph_type(s7_scheme *sc, s7_pointer args) {return(g_set_time_graph_type(s7_cadr(args), s7_undefined(sc), s7_undefined(sc)));} static s7_pointer acc_fft_window_alpha(s7_scheme *sc, s7_pointer args) {return(g_set_fft_window_alpha(s7_cadr(args), s7_undefined(sc), s7_undefined(sc)));} static s7_pointer acc_fft_window_beta(s7_scheme *sc, s7_pointer args) {return(g_set_fft_window_beta(s7_cadr(args), s7_undefined(sc), s7_undefined(sc)));} static s7_pointer acc_grid_density(s7_scheme *sc, s7_pointer args) {return(g_set_grid_density(s7_cadr(args), s7_undefined(sc), s7_undefined(sc)));} static s7_pointer acc_beats_per_minute(s7_scheme *sc, s7_pointer args) {return(g_set_beats_per_minute(s7_cadr(args), s7_undefined(sc), s7_undefined(sc)));} static s7_pointer acc_show_mix_waveforms(s7_scheme *sc, s7_pointer args) {return(g_set_show_mix_waveforms(s7_cadr(args), s7_undefined(sc), s7_undefined(sc)));} static s7_pointer acc_beats_per_measure(s7_scheme *sc, s7_pointer args) {return(g_set_beats_per_measure(s7_cadr(args), s7_undefined(sc), s7_undefined(sc)));} static s7_pointer acc_transform_normalization(s7_scheme *sc, s7_pointer args) {return(g_set_transform_normalization(s7_cadr(args), s7_undefined(sc), s7_undefined(sc)));} static s7_pointer acc_x_axis_style(s7_scheme *sc, s7_pointer args) {return(g_set_x_axis_style(s7_cadr(args), s7_undefined(sc), s7_undefined(sc)));} static s7_pointer acc_zoom_focus_style(s7_scheme *sc, s7_pointer args) {return(g_set_zoom_focus_style(s7_cadr(args)));} static s7_pointer acc_graph_style(s7_scheme *sc, s7_pointer args) {return(g_set_graph_style(s7_cadr(args), s7_undefined(sc), s7_undefined(sc)));} static s7_pointer acc_max_transform_peaks(s7_scheme *sc, s7_pointer args) {return(g_set_max_transform_peaks(s7_cadr(args), s7_undefined(sc), s7_undefined(sc)));} static s7_pointer acc_graphs_horizontal(s7_scheme *sc, s7_pointer args) {return(g_set_graphs_horizontal(s7_cadr(args), s7_undefined(sc), s7_undefined(sc)));} static s7_pointer acc_cursor_size(s7_scheme *sc, s7_pointer args) {return(g_set_cursor_size(s7_cadr(args), s7_undefined(sc), s7_undefined(sc)));} static s7_pointer acc_cursor_style(s7_scheme *sc, s7_pointer args) {return(g_set_cursor_style(s7_cadr(args), s7_undefined(sc), s7_undefined(sc)));} static s7_pointer acc_tracking_cursor_style(s7_scheme *sc, s7_pointer args) {return(g_set_tracking_cursor_style(s7_cadr(args), s7_undefined(sc), s7_undefined(sc)));} static s7_pointer acc_show_sonogram_cursor(s7_scheme *sc, s7_pointer args) {return(g_set_show_sonogram_cursor(s7_cadr(args), s7_undefined(sc), s7_undefined(sc)));} static s7_pointer acc_min_dB(s7_scheme *sc, s7_pointer args) {return(g_set_min_dB(s7_cadr(args), s7_undefined(sc), s7_undefined(sc)));} static s7_pointer acc_with_gl(s7_scheme *sc, s7_pointer args) {return(g_set_with_gl(s7_cadr(args)));} #endif void g_init_chn(void) { cp_edpos = Xen_undefined; Xen_define_safe_procedure(S_is_variable_graph, g_is_variable_graph_w, 1, 0, 0, H_is_variable_graph); Xen_define_safe_procedure(S_make_variable_graph, g_make_variable_graph_w, 1, 3, 0, H_make_variable_graph); Xen_define_safe_procedure(S_channel_data, g_channel_data_w, 0, 2, 0, H_channel_data); Xen_define_safe_procedure(S_graph, g_graph_w, 0, 0, 1, H_graph); Xen_define_safe_procedure(S_edits, g_edits_w, 0, 2, 0, H_edits); Xen_define_safe_procedure(S_peaks, g_peaks_w, 0, 3, 0, H_peaks); Xen_define_safe_procedure(S_edit_hook, g_edit_hook_w, 0, 2, 0, H_edit_hook); Xen_define_safe_procedure(S_after_edit_hook, g_after_edit_hook_w, 0, 2, 0, H_after_edit_hook); Xen_define_safe_procedure(S_undo_hook, g_undo_hook_w, 0, 2, 0, H_undo_hook); Xen_define_safe_procedure(S_update_time_graph, g_update_time_graph_w, 0, 2, 0, H_update_time_graph); Xen_define_safe_procedure(S_update_lisp_graph, g_update_lisp_graph_w, 0, 2, 0, H_update_lisp_graph); Xen_define_safe_procedure(S_update_transform_graph, g_update_transform_graph_w, 0, 2, 0, H_update_transform_graph); Xen_define_dilambda(S_x_position_slider, g_ap_sx_w, H_x_position_slider, S_set S_x_position_slider, g_set_ap_sx_w, 0, 2, 1, 2); Xen_define_dilambda(S_y_position_slider, g_ap_sy_w, H_y_position_slider, S_set S_y_position_slider, g_set_ap_sy_w, 0, 2, 1, 2); Xen_define_dilambda(S_x_zoom_slider, g_ap_zx_w, H_x_zoom_slider, S_set S_x_zoom_slider, g_set_ap_zx_w, 0, 2, 1, 2); Xen_define_dilambda(S_y_zoom_slider, g_ap_zy_w, H_y_zoom_slider, S_set S_y_zoom_slider, g_set_ap_zy_w, 0, 2, 1, 2); Xen_define_dilambda(S_framples, g_framples_w, H_framples, S_set S_framples, g_set_framples_w, 0, 3, 1, 2); Xen_define_dilambda(S_maxamp, g_maxamp_w, H_maxamp, S_set S_maxamp, g_set_maxamp_w, 0, 3, 1, 2); Xen_define_safe_procedure(S_maxamp_position, g_maxamp_position_w, 0, 3, 0, H_maxamp_position); Xen_define_safe_procedure(S_cursor_position, g_cursor_position_w, 0, 2, 0, H_cursor_position); Xen_define_dilambda(S_edit_position, g_edit_position_w, H_edit_position, S_set S_edit_position, g_set_edit_position_w, 0, 2, 1, 2); Xen_define_dilambda(S_transform_graph_on, g_transform_graph_on_w, H_transform_graph_on, S_set S_transform_graph_on, g_set_transform_graph_on_w, 0, 2, 1, 2); #define H_graph_once "The value for the various graph-type variables that displays the standard waveform" #define H_graph_as_wavogram "The value for " S_time_graph_type " to make a spectrogram-like form of the time-domain data" Xen_define_constant(S_graph_once, GRAPH_ONCE, H_graph_once); Xen_define_constant(S_graph_as_wavogram, GRAPH_AS_WAVOGRAM, H_graph_as_wavogram); #define H_graph_as_sonogram "The value for " S_transform_graph_type " that causes a sonogram to be displayed" #define H_graph_as_spectrogram "The value for " S_transform_graph_type " that causes a spectrogram to be displayed" /* #define H_graph_as_complex "The value for " S_transform_graph_type " to display FFT data in the complex plane" */ Xen_define_constant(S_graph_as_sonogram, GRAPH_AS_SONOGRAM, H_graph_as_sonogram); Xen_define_constant(S_graph_as_spectrogram, GRAPH_AS_SPECTROGRAM, H_graph_as_spectrogram); /* Xen_define_constant(S_graph_as_complex, GRAPH_AS_COMPLEX, H_graph_as_complex); */ Xen_define_dilambda(S_time_graph_on, g_timer_graph_on_w, H_timer_graph_on, S_set S_time_graph_on, g_set_timer_graph_on_w, 0, 2, 1, 2); Xen_define_dilambda(S_lisp_graph_on, g_lisp_graph_on_w, H_lisp_graph_on, S_set S_lisp_graph_on, g_set_lisp_graph_on_w, 0, 2, 1, 2); Xen_define_dilambda(S_squelch_update, g_squelch_update_w, H_squelch_update, S_set S_squelch_update, g_set_squelch_update_w, 0, 2, 1, 2); Xen_define_dilambda(S_cursor, g_cursor_w, H_cursor, S_set S_cursor, g_set_cursor_w, 0, 3, 1, 3); #define H_cursor_cross "The value for " S_cursor_style " that causes is to be a cross (the default)" #define H_cursor_line "The value for " S_cursor_style " that causes is to be a full vertical line" Xen_define_constant(S_cursor_cross, CURSOR_CROSS, H_cursor_cross); Xen_define_constant(S_cursor_line, CURSOR_LINE, H_cursor_line); Xen_define_dilambda(S_cursor_style, g_cursor_style_w, H_cursor_style, S_set S_cursor_style, g_set_cursor_style_w, 0, 2, 1, 2); Xen_define_dilambda(S_tracking_cursor_style, g_tracking_cursor_style_w, H_tracking_cursor_style, S_set S_tracking_cursor_style, g_set_tracking_cursor_style_w, 0, 2, 1, 2); Xen_define_dilambda(S_cursor_size, g_cursor_size_w, H_cursor_size, S_set S_cursor_size, g_set_cursor_size_w, 0, 2, 1, 2); Xen_define_dilambda(S_left_sample, g_left_sample_w, H_left_sample, S_set S_left_sample, g_set_left_sample_w, 0, 2, 1, 2); Xen_define_dilambda(S_right_sample, g_right_sample_w, H_right_sample, S_set S_right_sample, g_set_right_sample_w, 0, 2, 1, 2); Xen_define_dilambda(S_channel_properties, g_channel_properties_w, H_channel_properties, S_set S_channel_properties, g_set_channel_properties_w, 0, 2, 1, 2); Xen_define_dilambda(S_channel_property, g_channel_property_w, H_channel_property, S_set S_channel_property, g_set_channel_property_w, 1, 2, 2, 2); Xen_define_dilambda(S_edit_properties, g_edit_properties_w, H_edit_properties, S_set S_edit_properties, g_set_edit_properties_w, 0, 3, 1, 3); Xen_define_dilambda(S_edit_property, g_edit_property_w, H_edit_property, S_set S_edit_property, g_set_edit_property_w, 1, 3, 2, 3); Xen_define_dilambda(S_max_transform_peaks, g_max_transform_peaks_w, H_max_transform_peaks, S_set S_max_transform_peaks, g_set_max_transform_peaks_w, 0, 2, 1, 2); Xen_define_dilambda(S_show_y_zero, g_show_y_zero_w, H_show_y_zero, S_set S_show_y_zero, g_set_show_y_zero_w, 0, 2, 1, 2); Xen_define_dilambda(S_show_grid, g_show_grid_w, H_show_grid, S_set S_show_grid, g_set_show_grid_w, 0, 2, 1, 2); Xen_define_dilambda(S_grid_density, g_grid_density_w, H_grid_density, S_set S_grid_density, g_set_grid_density_w, 0, 2, 1, 2); Xen_define_dilambda(S_show_sonogram_cursor, g_show_sonogram_cursor_w, H_show_sonogram_cursor, S_set S_show_sonogram_cursor, g_set_show_sonogram_cursor_w, 0, 2, 1, 2); Xen_define_dilambda(S_show_marks, g_show_marks_w, H_show_marks, S_set S_show_marks, g_set_show_marks_w, 0, 2, 1, 2); Xen_define_dilambda(S_time_graph_type, g_time_graph_type_w, H_time_graph_type, S_set S_time_graph_type, g_set_time_graph_type_w, 0, 2, 1, 2); Xen_define_dilambda(S_wavo_hop, g_wavo_hop_w, H_wavo_hop, S_set S_wavo_hop, g_set_wavo_hop_w, 0, 2, 1, 2); Xen_define_dilambda(S_wavo_trace, g_wavo_trace_w, H_wavo_trace, S_set S_wavo_trace, g_set_wavo_trace_w, 0, 2, 1, 2); Xen_define_dilambda(S_show_transform_peaks, g_show_transform_peaks_w, H_show_transform_peaks, S_set S_show_transform_peaks, g_set_show_transform_peaks_w, 0, 2, 1, 2); Xen_define_dilambda(S_zero_pad, g_zero_pad_w, H_zero_pad, S_set S_zero_pad, g_set_zero_pad_w, 0, 2, 1, 2); Xen_define_dilambda(S_with_verbose_cursor, g_with_verbose_cursor_w, H_with_verbose_cursor, S_set S_with_verbose_cursor, g_set_with_verbose_cursor_w, 0, 2, 1, 2); Xen_define_dilambda(S_fft_log_frequency, g_fft_log_frequency_w, H_fft_log_frequency, S_set S_fft_log_frequency, g_set_fft_log_frequency_w, 0, 2, 1, 2); Xen_define_dilambda(S_fft_log_magnitude, g_fft_log_magnitude_w, H_fft_log_magnitude, S_set S_fft_log_magnitude, g_set_fft_log_magnitude_w, 0, 2, 1, 2); Xen_define_dilambda(S_fft_with_phases, g_fft_with_phases_w, H_fft_with_phases, S_set S_fft_with_phases, g_set_fft_with_phases_w, 0, 2, 1, 2); Xen_define_dilambda(S_min_dB, g_min_dB_w, H_min_dB, S_set S_min_dB, g_set_min_dB_w, 0, 2, 1, 2); Xen_define_dilambda(S_wavelet_type, g_wavelet_type_w, H_wavelet_type, S_set S_wavelet_type, g_set_wavelet_type_w, 0, 2, 1, 2); Xen_define_dilambda(S_spectrum_end, g_spectrum_end_w, H_spectrum_end, S_set S_spectrum_end, g_set_spectrum_end_w, 0, 2, 1, 2); Xen_define_dilambda(S_spectrum_start, g_spectrum_start_w, H_spectrum_start, S_set S_spectrum_start, g_set_spectrum_start_w, 0, 2, 1, 2); Xen_define_dilambda(S_spectro_x_angle, g_spectro_x_angle_w, H_spectro_x_angle, S_set S_spectro_x_angle, g_set_spectro_x_angle_w, 0, 2, 1, 2); Xen_define_dilambda(S_spectro_x_scale, g_spectro_x_scale_w, H_spectro_x_scale, S_set S_spectro_x_scale, g_set_spectro_x_scale_w, 0, 2, 1, 2); Xen_define_dilambda(S_spectro_y_angle, g_spectro_y_angle_w, H_spectro_y_angle, S_set S_spectro_y_angle, g_set_spectro_y_angle_w, 0, 2, 1, 2); Xen_define_dilambda(S_spectro_y_scale, g_spectro_y_scale_w, H_spectro_y_scale, S_set S_spectro_y_scale, g_set_spectro_y_scale_w, 0, 2, 1, 2); Xen_define_dilambda(S_spectro_z_angle, g_spectro_z_angle_w, H_spectro_z_angle, S_set S_spectro_z_angle, g_set_spectro_z_angle_w, 0, 2, 1, 2); Xen_define_dilambda(S_spectro_z_scale, g_spectro_z_scale_w, H_spectro_z_scale, S_set S_spectro_z_scale, g_set_spectro_z_scale_w, 0, 2, 1, 2); Xen_define_dilambda(S_fft_window_beta, g_fft_window_beta_w, H_fft_window_beta, S_set S_fft_window_beta, g_set_fft_window_beta_w, 0, 2, 1, 2); Xen_define_dilambda(S_fft_window_alpha, g_fft_window_alpha_w, H_fft_window_alpha, S_set S_fft_window_alpha, g_set_fft_window_alpha_w, 0, 2, 1, 2); Xen_define_dilambda(S_spectro_hop, g_spectro_hop_w, H_spectro_hop, S_set S_spectro_hop, g_set_spectro_hop_w, 0, 2, 1, 2); Xen_define_dilambda(S_transform_size, g_transform_size_w, H_transform_size, S_set S_transform_size, g_set_transform_size_w, 0, 2, 1, 2); Xen_define_dilambda(S_transform_graph_type, g_transform_graph_type_w, H_transform_graph_type, S_set S_transform_graph_type, g_set_transform_graph_type_w, 0, 2, 1, 2); Xen_define_dilambda(S_fft_window, g_fft_window_w, H_fft_window, S_set S_fft_window, g_set_fft_window_w, 0, 2, 1, 2); Xen_define_dilambda(S_transform_type, g_transform_type_w, H_transform_type, S_set S_transform_type, g_set_transform_type_w, 0, 2, 1, 2); Xen_define_dilambda(S_transform_normalization, g_transform_normalization_w, H_transform_normalization, S_set S_transform_normalization, g_set_transform_normalization_w, 0, 2, 1, 2); Xen_define_dilambda(S_show_mix_waveforms, g_show_mix_waveforms_w, H_show_mix_waveforms, S_set S_show_mix_waveforms, g_set_show_mix_waveforms_w, 0, 2, 1, 2); /* should these be named "graph-with-lines" etc? */ #define H_graph_lines "The value for " S_graph_style " that causes graphs to use line-segments" #define H_graph_dots "The value for " S_graph_style " that causes graphs to use dots" #define H_graph_filled "The value for " S_graph_style " that causes graphs to use filled polygons" #define H_graph_dots_and_lines "The value for " S_graph_style " that causes graphs to use dots connected by lines" #define H_graph_lollipops "The value for " S_graph_style " that makes DSP engineers happy" Xen_define_constant(S_graph_lines, GRAPH_LINES, H_graph_lines); Xen_define_constant(S_graph_dots, GRAPH_DOTS, H_graph_dots); Xen_define_constant(S_graph_filled, GRAPH_FILLED, H_graph_filled); Xen_define_constant(S_graph_dots_and_lines, GRAPH_DOTS_AND_LINES, H_graph_dots_and_lines); Xen_define_constant(S_graph_lollipops, GRAPH_LOLLIPOPS, H_graph_lollipops); Xen_define_dilambda(S_time_graph_style, g_time_graph_style_w, H_time_graph_style, S_set S_time_graph_style, g_set_time_graph_style_w, 1, 1, 1, 2); Xen_define_dilambda(S_lisp_graph_style, g_lisp_graph_style_w, H_lisp_graph_style, S_set S_lisp_graph_style, g_set_lisp_graph_style_w, 1, 1, 1, 2); Xen_define_dilambda(S_transform_graph_style, g_transform_graph_style_w, H_transform_graph_style, S_set S_transform_graph_style, g_set_transform_graph_style_w, 1, 1, 1, 2); Xen_define_dilambda(S_graph_style, g_graph_style_w, H_graph_style, S_set S_graph_style, g_set_graph_style_w, 0, 2, 1, 2); Xen_define_dilambda(S_dot_size, g_dot_size_w, H_dot_size, S_set S_dot_size, g_set_dot_size_w, 0, 2, 1, 2); #define H_x_axis_in_seconds "The value for " S_x_axis_style " that displays the x axis using seconds" #define H_x_axis_in_samples "The value for " S_x_axis_style " that displays the x axis using sample numbers" #define H_x_axis_in_beats "The value for " S_x_axis_style " that displays the x axis using beats (also " S_beats_per_minute ")" #define H_x_axis_in_measures "The value for " S_x_axis_style " that displays the x axis using measure numbers" #define H_x_axis_as_percentage "The value for " S_x_axis_style " that displays the x axis using percentages" #define H_x_axis_as_clock "The value for " S_x_axis_style " that displays the x axis using clock-like DD:HH:MM:SS syntax" Xen_define_constant(S_x_axis_in_seconds, X_AXIS_IN_SECONDS, H_x_axis_in_seconds); Xen_define_constant(S_x_axis_in_samples, X_AXIS_IN_SAMPLES, H_x_axis_in_samples); Xen_define_constant(S_x_axis_in_beats, X_AXIS_IN_BEATS, H_x_axis_in_beats); Xen_define_constant(S_x_axis_in_measures, X_AXIS_IN_MEASURES, H_x_axis_in_measures); Xen_define_constant(S_x_axis_as_percentage, X_AXIS_AS_PERCENTAGE, H_x_axis_as_percentage); Xen_define_constant(S_x_axis_as_clock, X_AXIS_AS_CLOCK, H_x_axis_as_clock); Xen_define_dilambda(S_x_axis_style, g_x_axis_style_w, H_x_axis_style, S_set S_x_axis_style, g_set_x_axis_style_w, 0, 2, 1, 2); Xen_define_dilambda(S_beats_per_minute, g_beats_per_minute_w, H_beats_per_minute, S_set S_beats_per_minute, g_set_beats_per_minute_w, 0, 2, 1, 2); Xen_define_dilambda(S_beats_per_measure, g_beats_per_measure_w, H_beats_per_measure, S_set S_beats_per_measure, g_set_beats_per_measure_w, 0, 2, 1, 2); #define H_show_all_axes "The value for " S_show_axes " that causes both the x and y axes to be displayed" #define H_show_all_axes_unlabelled "The value for " S_show_axes " that causes both the x and y axes to be displayed, but without any label" #define H_show_no_axes "The value for " S_show_axes " that causes neither the x or y axes to be displayed" #define H_show_x_axis "The value for " S_show_axes " that causes only the x axis to be displayed" #define H_show_x_axis_unlabelled "The value for " S_show_axes " that causes only the x axis to be displayed, but without any label" #define H_show_bare_x_axis "The value for " S_show_axes " that causes x axis to be displayed without a label or tick marks" Xen_define_constant(S_show_all_axes, SHOW_ALL_AXES, H_show_all_axes); Xen_define_constant(S_show_all_axes_unlabelled,SHOW_ALL_AXES_UNLABELLED, H_show_all_axes_unlabelled); Xen_define_constant(S_show_no_axes, SHOW_NO_AXES, H_show_no_axes); Xen_define_constant(S_show_x_axis, SHOW_X_AXIS, H_show_x_axis); Xen_define_constant(S_show_x_axis_unlabelled, SHOW_X_AXIS_UNLABELLED, H_show_x_axis_unlabelled); Xen_define_constant(S_show_bare_x_axis, SHOW_BARE_X_AXIS, H_show_bare_x_axis); Xen_define_dilambda(S_show_axes, g_show_axes_w, H_show_axes, S_set S_show_axes, g_set_show_axes_w, 0, 2, 1, 2); Xen_define_dilambda(S_graphs_horizontal, g_graphs_horizontal_w, H_graphs_horizontal, S_set S_graphs_horizontal, g_set_graphs_horizontal_w, 0, 2, 1, 2); #define H_zoom_focus_left "The value for " S_zoom_focus_style " that causes zooming to maintain the left edge steady" #define H_zoom_focus_right "The value for " S_zoom_focus_style " that causes zooming to maintain the right edge steady" #define H_zoom_focus_middle "The value for " S_zoom_focus_style " that causes zooming to focus on the middle sample" #define H_zoom_focus_active "The value for " S_zoom_focus_style " that causes zooming to focus on the currently active object" Xen_define_constant(S_zoom_focus_left, ZOOM_FOCUS_LEFT, H_zoom_focus_left); Xen_define_constant(S_zoom_focus_right, ZOOM_FOCUS_RIGHT, H_zoom_focus_right); Xen_define_constant(S_zoom_focus_active, ZOOM_FOCUS_ACTIVE, H_zoom_focus_active); Xen_define_constant(S_zoom_focus_middle, ZOOM_FOCUS_MIDDLE, H_zoom_focus_middle); Xen_define_dilambda(S_zoom_focus_style, g_zoom_focus_style_w, H_zoom_focus_style, S_set S_zoom_focus_style, g_set_zoom_focus_style_w, 0, 0, 1, 0); Xen_define_dilambda(S_with_gl, g_with_gl_w, H_with_gl, S_set S_with_gl, g_set_with_gl_w, 0, 0, 1, 0); #define H_sync_none "The " S_sync_style " choice that leaves every sound and channel unsync'd at the start" #define H_sync_all "The " S_sync_style " choice that syncs together every sound and channel at the start" #define H_sync_by_sound "The " S_sync_style " choice that syncs all channels in a sound, but each sound is separate" Xen_define_constant(S_sync_none, SYNC_NONE, H_sync_none); Xen_define_constant(S_sync_all, SYNC_ALL, H_sync_all); Xen_define_constant(S_sync_by_sound, SYNC_BY_SOUND, H_sync_by_sound); Xen_define_dilambda(S_sync_style, g_sync_style_w, H_sync_style, S_set S_sync_style, g_set_sync_style_w, 0, 0, 1, 0); #if HAVE_GL Xen_define_safe_procedure(S_glSpectrogram, g_gl_spectrogram_w, 9, 0, 0, H_glSpectrogram); #endif #define H_after_transform_hook S_after_transform_hook " (snd chn scaler): called just after a spectrum is calculated." #define H_graph_hook S_graph_hook " (snd chn y0 y1): called each time a graph is about to be updated. If it returns " PROC_TRUE ", the display is not updated." #define H_after_graph_hook S_after_graph_hook " (snd chn): called after a graph is updated." #define H_lisp_graph_hook S_lisp_graph_hook " (snd chn): called just before the lisp graph is updated. If it returns a list \ of pixels, these are used in order by the list of graphs (if any), rather than Snd's default set; \ this makes it possible to use different colors for the various graphs. \ If it returns a function (of no arguments), that function is called rather than the standard graph routine." #define H_after_lisp_graph_hook S_after_lisp_graph_hook " (snd chn): called after a lisp graph is updated." #define H_mouse_press_hook S_mouse_press_hook " (snd chn button state x y): called upon mouse button press within the lisp graph." #define H_mouse_click_hook S_mouse_click_hook " (snd chn button state x y axis): called upon button click." #define H_mouse_drag_hook S_mouse_drag_hook " (snd chn button state x y): called upon mouse drag within the lisp graph." #define H_mark_click_hook S_mark_click_hook " (id): called when a mark is clicked; return " PROC_TRUE " to squelch the default message." #define H_mix_click_hook S_mix_click_hook " (id): called when a mix is clicked; return " PROC_TRUE " to squelch the default message." #define H_key_press_hook S_key_press_hook " (snd chn key state): called upon a key press if the mouse is in the lisp graph. \ If it returns " PROC_TRUE ", the key press is not passed to the main handler. 'state' refers to the control, meta, and shift keys." #define H_initial_graph_hook S_initial_graph_hook " (snd chn duration): called when a sound is displayed for the first time" after_transform_hook = Xen_define_hook(S_after_transform_hook, "(make-hook 'snd 'chn 'scaler)", 3, H_after_transform_hook); graph_hook = Xen_define_hook(S_graph_hook, "(make-hook 'snd 'chn 'y0 'y1)", 4, H_graph_hook); after_graph_hook = Xen_define_hook(S_after_graph_hook, "(make-hook 'snd 'chn)", 2, H_after_graph_hook); after_lisp_graph_hook = Xen_define_hook(S_after_lisp_graph_hook, "(make-hook 'snd 'chn)", 2, H_after_lisp_graph_hook); initial_graph_hook = Xen_define_hook(S_initial_graph_hook, "(make-hook 'snd 'chn 'duration)", 3, H_initial_graph_hook); lisp_graph_hook = Xen_define_hook(S_lisp_graph_hook, "(make-hook 'snd 'chn)", 2, H_lisp_graph_hook); mouse_press_hook = Xen_define_hook(S_mouse_press_hook, "(make-hook 'snd 'chn 'button 'state 'x 'y)", 6, H_mouse_press_hook); mouse_click_hook = Xen_define_hook(S_mouse_click_hook, "(make-hook 'snd 'chn 'button 'state 'x 'y 'axis)", 7, H_mouse_click_hook); mouse_drag_hook = Xen_define_hook(S_mouse_drag_hook, "(make-hook 'snd 'chn 'button 'state 'x 'y)", 6, H_mouse_drag_hook); key_press_hook = Xen_define_hook(S_key_press_hook, "(make-hook 'snd 'chn 'key 'state)", 4, H_key_press_hook); mark_click_hook = Xen_define_hook(S_mark_click_hook, "(make-hook 'id)", 1, H_mark_click_hook); mix_click_hook = Xen_define_hook(S_mix_click_hook, "(make-hook 'id)", 1, H_mix_click_hook); #if HAVE_SCHEME s7_symbol_set_documentation(s7, ss->show_transform_peaks_symbol, "*" S_show_transform_peaks "* determines whether fft displays include a peak list"); s7_symbol_set_documentation(s7, ss->show_y_zero_symbol, "*show-y-zero*: #t if Snd should include a line at y = 0.0"); s7_symbol_set_documentation(s7, ss->show_marks_symbol, "*show-marks*: #t if Snd should show marks"); s7_symbol_set_documentation(s7, ss->show_grid_symbol, "*show-grid*: #t if Snd should display a background grid in the graphs"); s7_symbol_set_documentation(s7, ss->fft_log_frequency_symbol, "*fft-log-frequency*: #t if fft displays use log on the frequency axis"); s7_symbol_set_documentation(s7, ss->fft_log_magnitude_symbol, "*fft-log-magnitude*: #t if fft displays use dB"); s7_symbol_set_documentation(s7, ss->fft_with_phases_symbol, "*fft-with-phases*: #t if fft displays include phase info"); s7_symbol_set_documentation(s7, ss->sync_style_symbol, "*sync-style*: determines how channels are grouped when a sound is opened."); s7_symbol_set_documentation(s7, ss->show_axes_symbol, "*show-axes*: If show-all-axes, display x and y axes; if show-x-axis, just one axis (the x axis) is displayed. The other choices are show-no-axes, show-all-axes-unlabelled, show-x-axis-unlabelled, and show-bare-x-axis."); s7_symbol_set_documentation(s7, ss->with_verbose_cursor_symbol, "*with-verbose-cursor*: #t if the cursor's position and so on is displayed in the status area"); s7_symbol_set_documentation(s7, ss->spectro_x_scale_symbol, "*spectro-x-scale*: scaler (stretch) along the spectrogram x axis (1.0)"); s7_symbol_set_documentation(s7, ss->spectro_y_scale_symbol, "*spectro-y-scale*: scaler (stretch) along the spectrogram y axis (1.0)"); s7_symbol_set_documentation(s7, ss->spectro_z_scale_symbol, "*spectro-z-scale*: scaler (stretch) along the spectrogram z axis (0.1)"); s7_symbol_set_documentation(s7, ss->spectro_z_angle_symbol, "*spectro-z-angle*: spectrogram z-axis viewing angle (-2.0)"); s7_symbol_set_documentation(s7, ss->spectro_x_angle_symbol, "*spectro-x-angle*: spectrogram x-axis viewing angle (90.0)"); s7_symbol_set_documentation(s7, ss->spectro_y_angle_symbol, "*spectro-y-angle*: spectrogram y-axis viewing angle (0.0)"); s7_symbol_set_documentation(s7, ss->spectrum_end_symbol, "*spectrum-end*: max frequency shown in spectra (1.0 = srate/2)"); s7_symbol_set_documentation(s7, ss->spectrum_start_symbol, "*spectrum-start*: lower bound of frequency in spectral displays (0.0)"); s7_symbol_set_documentation(s7, ss->spectro_hop_symbol, "*spectro-hop*: hop amount (pixels) in spectral displays"); s7_symbol_set_documentation(s7, ss->wavelet_type_symbol, "*wavelet-type*: wavelet used in wavelet-transform (0)"); s7_symbol_set_documentation(s7, ss->dot_size_symbol, "*dot-size*: size in pixels of dots when graphing with dots (1)"); s7_symbol_set_documentation(s7, ss->zero_pad_symbol, "*zero-pad*: zero padding used in fft as a multiple of fft size (0)"); s7_symbol_set_documentation(s7, ss->wavo_hop_symbol, "*wavo-hop*: wavogram spacing between successive traces"); s7_symbol_set_documentation(s7, ss->wavo_trace_symbol, "*wavo-trace*: length (samples) of each trace in the wavogram (64)"); s7_symbol_set_documentation(s7, ss->transform_size_symbol, "*transform-size*: current fft size (512)"); s7_symbol_set_documentation(s7, ss->fft_window_symbol, "*fft-window*: fft data window choice (blackman2-window etc)"); s7_symbol_set_documentation(s7, ss->transform_graph_type_symbol, "*transform-graph-type* can be graph-once, graph-as-sonogram, or graph-as-spectrogram."); s7_symbol_set_documentation(s7, ss->time_graph_type_symbol, "*time-graph-type*: graph-once or graph-as-wavogram"); s7_symbol_set_documentation(s7, ss->fft_window_alpha_symbol, "*fft-window-alpha*: fft window alpha parameter value"); s7_symbol_set_documentation(s7, ss->fft_window_beta_symbol, "*fft-window-beta*: fft window beta parameter value"); s7_symbol_set_documentation(s7, ss->grid_density_symbol, "*grid-density*: sets how closely axis ticks are spaced, default=1.0"); s7_symbol_set_documentation(s7, ss->beats_per_minute_symbol, "*beats-per-minute*: beats per minute if x-axis-style is x-axis-in-beats"); s7_symbol_set_documentation(s7, ss->show_mix_waveforms_symbol, "*show-mix-waveforms*: #t if Snd should display mix waveforms (above the main waveform)"); s7_symbol_set_documentation(s7, ss->beats_per_measure_symbol, "*beats-per-measure*: beats per measure if x-axis-style is x-axis-in-measures"); s7_symbol_set_documentation(s7, ss->transform_normalization_symbol, "*transform-normalization*: dont-normalize, normalize-by-channel, normalize-by-sound, or normalize-globally."); s7_symbol_set_documentation(s7, ss->x_axis_style_symbol, "*x-axis-style*: The x axis labelling of the time domain waveform (x-axis-in-seconds etc)"); s7_symbol_set_documentation(s7, ss->zoom_focus_style_symbol, "*zoom-focus-style*: determines what zooming centers on (zoom-focus-active etc)."); s7_symbol_set_documentation(s7, ss->graph_style_symbol, "*graph-style*: graph style (graph-lines etc)"); s7_symbol_set_documentation(s7, ss->max_transform_peaks_symbol, "*max-transform-peaks*: max number of fft peaks reported in fft display"); s7_symbol_set_documentation(s7, ss->graphs_horizontal_symbol, "*graphs-horizontal*: #t if the time domain, fft, and lisp graphs are layed out horizontally"); s7_symbol_set_documentation(s7, ss->cursor_size_symbol, "*cursor-size*: current cursor size"); s7_symbol_set_documentation(s7, ss->cursor_style_symbol, "*cursor-style*: current cursor shape (cursor-cross etc)"); s7_symbol_set_documentation(s7, ss->tracking_cursor_style_symbol, "*tracking-cursor-style*: current tracking cursor shape (cursor-cross, cursor-line)"); s7_symbol_set_documentation(s7, ss->show_sonogram_cursor_symbol, "*show-sonogram-cursor*: #t if Snd should display a cursor in the sonogram"); s7_symbol_set_documentation(s7, ss->min_db_symbol, "*min-dB*: min dB value displayed in fft graphs using dB scales (-60)"); s7_symbol_set_documentation(s7, ss->transform_type_symbol, "*transform-type*: transform type (fourier-transform etc)"); s7_symbol_set_documentation(s7, ss->with_gl_symbol, "*with-gl*: #t if Snd should use GL graphics"); s7_symbol_set_access(s7, ss->transform_type_symbol, s7_make_function(s7, "[acc-" S_transform_type "]", acc_transform_type, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->show_transform_peaks_symbol, s7_make_function(s7, "[acc-" S_show_transform_peaks "]", acc_show_transform_peaks, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->show_y_zero_symbol, s7_make_function(s7, "[acc-" S_show_y_zero "]", acc_show_y_zero, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->show_marks_symbol, s7_make_function(s7, "[acc-" S_show_marks "]", acc_show_marks, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->show_grid_symbol, s7_make_function(s7, "[acc-" S_show_grid "]", acc_show_grid, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->fft_log_frequency_symbol, s7_make_function(s7, "[acc-" S_fft_log_frequency "]", acc_fft_log_frequency, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->fft_log_magnitude_symbol, s7_make_function(s7, "[acc-" S_fft_log_magnitude "]", acc_fft_log_magnitude, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->fft_with_phases_symbol, s7_make_function(s7, "[acc-" S_fft_with_phases "]", acc_fft_with_phases, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->sync_style_symbol, s7_make_function(s7, "[acc-" S_sync_style "]", acc_sync_style, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->show_axes_symbol, s7_make_function(s7, "[acc-" S_show_axes "]", acc_show_axes, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->with_verbose_cursor_symbol, s7_make_function(s7, "[acc-" S_with_verbose_cursor "]", acc_with_verbose_cursor, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->spectro_x_scale_symbol, s7_make_function(s7, "[acc-" S_spectro_x_scale "]", acc_spectro_x_scale, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->spectro_y_scale_symbol, s7_make_function(s7, "[acc-" S_spectro_y_scale "]", acc_spectro_y_scale, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->spectro_z_scale_symbol, s7_make_function(s7, "[acc-" S_spectro_z_scale "]", acc_spectro_z_scale, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->spectro_z_angle_symbol, s7_make_function(s7, "[acc-" S_spectro_z_angle "]", acc_spectro_z_angle, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->spectro_x_angle_symbol, s7_make_function(s7, "[acc-" S_spectro_x_angle "]", acc_spectro_x_angle, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->spectro_y_angle_symbol, s7_make_function(s7, "[acc-" S_spectro_y_angle "]", acc_spectro_y_angle, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->spectrum_end_symbol, s7_make_function(s7, "[acc-" S_spectrum_end "]", acc_spectrum_end, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->spectrum_start_symbol, s7_make_function(s7, "[acc-" S_spectrum_start "]", acc_spectrum_start, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->spectro_hop_symbol, s7_make_function(s7, "[acc-" S_spectro_hop "]", acc_spectro_hop, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->wavelet_type_symbol, s7_make_function(s7, "[acc-" S_wavelet_type "]", acc_wavelet_type, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->dot_size_symbol, s7_make_function(s7, "[acc-" S_dot_size "]", acc_dot_size, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->zero_pad_symbol, s7_make_function(s7, "[acc-" S_zero_pad "]", acc_zero_pad, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->wavo_hop_symbol, s7_make_function(s7, "[acc-" S_wavo_hop "]", acc_wavo_hop, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->wavo_trace_symbol, s7_make_function(s7, "[acc-" S_wavo_trace "]", acc_wavo_trace, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->transform_size_symbol, s7_make_function(s7, "[acc-" S_transform_size "]", acc_transform_size, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->fft_window_symbol, s7_make_function(s7, "[acc-" S_fft_window "]", acc_fft_window, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->transform_graph_type_symbol, s7_make_function(s7, "[acc-" S_transform_graph_type "]", acc_transform_graph_type, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->time_graph_type_symbol, s7_make_function(s7, "[acc-" S_time_graph_type "]", acc_time_graph_type, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->fft_window_alpha_symbol, s7_make_function(s7, "[acc-" S_fft_window_alpha "]", acc_fft_window_alpha, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->fft_window_beta_symbol, s7_make_function(s7, "[acc-" S_fft_window_beta "]", acc_fft_window_beta, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->grid_density_symbol, s7_make_function(s7, "[acc-" S_grid_density "]", acc_grid_density, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->beats_per_minute_symbol, s7_make_function(s7, "[acc-" S_beats_per_minute "]", acc_beats_per_minute, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->show_mix_waveforms_symbol, s7_make_function(s7, "[acc-" S_show_mix_waveforms "]", acc_show_mix_waveforms, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->beats_per_measure_symbol, s7_make_function(s7, "[acc-" S_beats_per_measure "]", acc_beats_per_measure, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->transform_normalization_symbol, s7_make_function(s7, "[acc-" S_transform_normalization "]", acc_transform_normalization, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->x_axis_style_symbol, s7_make_function(s7, "[acc-" S_x_axis_style "]", acc_x_axis_style, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->zoom_focus_style_symbol, s7_make_function(s7, "[acc-" S_zoom_focus_style "]", acc_zoom_focus_style, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->graph_style_symbol, s7_make_function(s7, "[acc-" S_graph_style "]", acc_graph_style, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->max_transform_peaks_symbol, s7_make_function(s7, "[acc-" S_max_transform_peaks "]", acc_max_transform_peaks, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->graphs_horizontal_symbol, s7_make_function(s7, "[acc-" S_graphs_horizontal "]", acc_graphs_horizontal, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->cursor_size_symbol, s7_make_function(s7, "[acc-" S_cursor_size "]", acc_cursor_size, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->cursor_style_symbol, s7_make_function(s7, "[acc-" S_cursor_style "]", acc_cursor_style, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->tracking_cursor_style_symbol, s7_make_function(s7, "[acc-" S_tracking_cursor_style "]", acc_tracking_cursor_style, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->show_sonogram_cursor_symbol, s7_make_function(s7, "[acc-" S_show_sonogram_cursor "]", acc_show_sonogram_cursor, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->min_db_symbol, s7_make_function(s7, "[acc-" S_min_dB "]", acc_min_dB, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->with_gl_symbol, s7_make_function(s7, "[acc-" S_with_gl "]", acc_with_gl, 2, 0, false, "accessor")); s7_eval_c_string(s7, "(set! *transform-type* fourier-transform)"); #endif } snd-16.1/singer.rb0000644000076400007640000006673712306421672012175 0ustar bilbil# singer.rb -- singer.ins -> singer.scm -> singer.rb -*- snd-ruby -*- # Translator: Michael Scholz # Created: Sat Apr 23 13:07:53 CEST 2005 # Changed: Mon Nov 22 13:36:42 CET 2010 # Commentary: # # Perry Cook's physical model of the vocal tract as described in: # # Cook, Perry R. "Synthesis of the Singing Voice Using a Physically # Parameterized Model of the Human Vocal Tract" # Published in the Proceedings of the International Computer Music Conference, Ohio 1989 # and as Stanford University Department of Music Technical Report Stan-M-57, August 1989. # # -- "Identification of Control Parameters in an Articulatory Vocal # Tract Model, with Applications to the Synthesis of Singing," # Ph.D. Thesis, Stanford University Department of Music Technical # Report # # -- "SPASM, a Real-time Vocal Tract Physical Model Controller; and # Singer, the Companion Software Synthesis System", Computer Music # Journal, vol 17 no 1 Spring 1993. # # This code is a translation of Perry Cook's singer implementation originally in C. # Apparently all Perry's data is aimed at srate=22050. # # Code: def singer(start, amp, data) # data is a list of lists very similar to the sequence of synthesize # calls in Perry's original implementation. # Each imbedded list has the form: dur shape glot pitch glotamp # noiseamps vibramt. # See below for examples. setup = data.first durs = data.map do |val| val[0] end dur = 0.0 durs.each do |val| dur += val end dur -= samples2seconds(1) beg = start begs = [start] + durs.map do |val| beg += val end beg_samps = begs.map do |val| seconds2samples(val) end change_times = (beg_samps + [beg_samps.last]).to_vct shps = data.map do |val| val[1] end glts = data.map do |val| val[2] end pfun = [0.0, 0.8 * setup[3]] data.zip(begs[1..-1]) do |dat, b| pfun.push(b - start, Float(dat[3])) end gfun = [0.0, 0.0] data.zip(begs[1..-1]) do |dat, b| gfun.push(b - start, Float(dat[4])) end nfun = [0.0, Float(setup[5])] data.zip(begs[1..-1]) do |dat, b| nfun.push(b - start, Float(dat[5])) end vfun = [0.0, Float(setup[6])] data.zip(begs[1..-1]) do |dat, b| vfun.push(b - start, Float(dat[6])) end noiseamps = Vct.new(data.length) do |i| Float(data[i][5]) end frq_env = make_env(:envelope, pfun, :duration, dur) vib_env = make_env(:envelope, vfun, :duration, dur) vib_osc = make_oscil(:frequency, 6.0) glot_env = make_env(:envelope, gfun, :duration, dur) noise_env = make_env(:envelope, nfun, :duration, dur) ran_vib = make_rand_interp(:frequency, 10, :amplitude, 0.02) # tractlength = 9 # length of vocal tract shape_data = Vct.new(shps.length * (tractlength + 8)) glot_datai = Vct.new(2 * glts.length) glot_datar = Vct.new(2 * glts.length) shps.each_with_index do |shp, i| shp[1..-1].each_with_index do |val, j| shape_data[j + i] = val end end ii = 0 glts.each do |glt| glot_datai[ii] = 0.0 glot_datai[ii + 1] = glt[0] glot_datar[ii] = glt[1] glot_datar[ii + 1] = glt[2] ii += 2 end table_size = 1000 # size of glottis wave-table noseposition = 3 noselength = 6 nose_ring_time = 1000 # naso pharynx response decay time one_over_two_pi = 1.0 / TWO_PI two_pi_over_table_size = TWO_PI / table_size table_size_over_sampling_rate = table_size / mus_srate dpole = 0.998 dgain = 1.0 - dpole tong_hump_pole = 0.998 tong_hump_gain = 1.0 - tong_hump_pole tong_tip_pole = 0.998 tong_tip_gain = 1.0 - tong_tip_pole glot_table = Vct.new(table_size + 1) glot_table2 = Vct.new(table_size + 1) gn_table = Vct.new(table_size + 1) gn_gain = 0.0 gn_out = 0.0 gn_del = Vct.new(4) gn_coeffs = Vct.new(4) sines = Vct.new(200) cosines = Vct.new(200) table_increment = 0.0 table_location = 0.0 glot_refl_gain = 0.7 pitch = 400.0 vibr_amt = 0.0 last_lip_in = 0.0 # for lip reflection/transmission filter last_lip_out = 0.0 last_lip_refl = 0.0 lip_refl_gain = -0.45 noise_gain = 0.0 # for vocal tract noise generator noise_input = 0.0 noise_output = 0.0 noise_c = Vct.new(4) # net coefficients on delayed outputs noise_pos = 0 fnoiseamp = 0.0 inz1 = 0.0 inz2 = 0.0 outz = Vct.new(4) # delayed versions of input and output # nasal tract acoustic tube structure nose_coeffs = vct(0.0, -0.29, -0.22, 0.0, 0.24, 0.3571) nose1 = Vct.new(noselength) nose2 = Vct.new(noselength) velum_pos = 0.0 alpha = Vct.new(4) nose_last_minus_refl = 0.0 nose_last_plus_refl = 0.0 nose_last_output = 0.0 nose_filt = 0.0 nose_filt1 = 0.0 time_nose_closed = 1000 # this is a hack used to determine if we # need to calculate the nasal acoustics # vocal tract acoustic tube structure radii = Vct.new(tractlength + 8) # the radii array contains the vocal tract section radii # (tractlength-1 of them), then glottal reflection gain then lip # reflection gain, then noise position, then noise gain, then noise # pole angle, then noise pole radius, then noise pole angle2, then # noise pole radius2, then velum opening radius 8.times do |i| radii[i] = 1.0 end radii[8] = 0.7 radii[9] = -0.5 coeffs = Vct.new(tractlength) dline1 = Vct.new(tractlength) dline2 = Vct.new(tractlength) # throat radiation low-pass filter lt = Vct.new(2) ltcoeff = 0.9995 ltgain = 0.05 # a low order iir filter lip_radius = 0.0 s_glot = 0.0 s_glot_mix = 0.0 s_noise = 0.0 last_tract_plus = 0.0 initial_noise_position = 0.0 formant_shift = 1.0 target_radii = Vct.new(tractlength + 8) 8.times do |i| target_radii[i] = 1.0 end target_radii[8] = 0.7 target_radii[9] = -0.5 radii_poles = Vct.new(tractlength + 8, dpole) radii_poles[2] = tong_hump_pole radii_poles[3] = tong_hump_pole radii_poles[4] = tong_hump_pole radii_poles[5] = tong_tip_pole radii_pole_gains = Vct.new(tractlength + 8, dgain) radii_pole_gains[2] = tong_hump_gain radii_pole_gains[3] = tong_hump_gain radii_pole_gains[4] = tong_hump_gain radii_pole_gains[5] = tong_tip_gain change_radii = 0 glotsamp = 0.0 delta = 0.0 temp_arr = Vct.new(tractlength + 1) new_glot = 1 first_glot = 1 new_tract = 1 first_tract = 1 offset = -1 next_offset = seconds2samples(start) last_sfd = -1 last_gfd = -1 run_instrument(start, dur) do |i| if i == next_offset # time to check for new tract shapes, glottal pulse shapes etc. offset += 1 fnoiseamp = noiseamps[offset] if last_sfd == -1 last_sfd = 0 else new_sfd = last_sfd + tractlength + 8 kk = new_sfd last_sfd.upto(new_sfd - 1) do |j| if (shape_data[j] - shape_data[kk]).abs > 0.001 then new_tract = 1 end kk += 1 end last_sfd = new_sfd end if last_gfd == -1 last_gfd = 0 else last_gfd += 2 end next_offset = change_times[offset + 1].to_i end if new_tract.nonzero? jj = last_sfd - 1 target_radii.map! do |val| shape_data[jj += 1] end if first_tract == 1 radii.map_with_index! do |val, j| target_radii[j] end end change_radii = 0 initial_noise_position = radii[tractlength + 1] target_radii.zip(radii) do |t, r| if (t - r).abs > 0.001 then change_radii = 1 end end end if first_tract == 1 or change_radii.nonzero? if new_tract.zero? radii.map_with_index! do |val, j| val * radii_poles[j] + target_radii[j] * radii_pole_gains[j] end end # set tract shape temp_arr[0] = 1.0 1.upto(temp_arr.length - 1) do |j| temp_arr[j] = radii[j - 1] * radii[j - 1] if temp_arr[j].zero? then temp_arr[j] = 1e-10 end end 1.upto(tractlength - 1) do |j| coeffs[j] = (temp_arr[j - 1] - temp_arr[j]) / (temp_arr[j - 1] + temp_arr[j]) end glot_refl_gain = radii[tractlength - 1] lip_refl_gain = radii[tractlength] noise_pos = radii[tractlength + 1].to_i noise_gain = radii[tractlength + 2] # fricative noise generator (set noise angle and radius) noise_angle = hz2radians(radii[tractlength + 3]) noise_radius = radii[tractlength + 4] noise_a = -2.0 * cos(noise_angle / formant_shift) * noise_radius noise_b = noise_radius * noise_radius noise_angle2 = hz2radians(radii[tractlength + 5]) noise_radius2 = radii[tractlength + 6] noise_a2 = -2.0 * cos(noise_angle2 / formant_shift) * noise_radius2 noise_b2 = noise_radius2 * noise_radius2 noise_c[0] = noise_a + noise_a2 noise_c[1] = noise_b + noise_b2 + noise_a * noise_a2 noise_c[2] = noise_a2 * noise_b + noise_b2 * noise_a noise_c[3] = noise_b2 * noise_b lip_radius = radii[tractlength - 2] velum_pos = radii[tractlength + 7] leftradius = radii[noseposition - 2] velumradius = velum_pos rightradius = radii[noseposition - 1] # nasal tract (set nasal shape) temp = [rightradius - velumradius, 0.0].max alpha[1] = leftradius * leftradius alpha[2] = temp * temp alpha[3] = velumradius * velumradius temp1 = 2.0 / (alpha[1] + alpha[2] + alpha[3]) alpha[1] *= temp1 alpha[2] *= temp1 alpha[3] *= temp1 end if new_tract.nonzero? new_tract = 0 first_tract = 0 if s_noise < 1.0 or fnoiseamp < 0.0001 target_radii[tractlength + 1] = initial_noise_position end end if new_glot.nonzero? if first_glot.zero? glot_table2.map_with_index! do |val, j| glot_table[j] end end harms = glot_datai[last_gfd + 1].to_i a = glot_datar[last_gfd] b = glot_datar[last_gfd + 1] a2 = TWO_PI * a b2 = TWO_PI * b sines.fill(0.0) cosines.fill(0.0) if a != b temp = one_over_two_pi / (b - a) temp1 = 1.0 - cos(a2) sines[1] = (cos(a2) + (sin(a2) - sin(b2)) * temp) * temp1 * one_over_two_pi cosines[1] = (-sin(a2) + (cos(a2) - cos(b2)) * temp) * temp1 * one_over_two_pi end sines[1] = sines[1] + (0.75 + -cos(a2) + cos(2.0 * a2) * 0.25) * one_over_two_pi cosines[1] = cosines[1] + (sin(a2) - sin(2.0 * a2) * 0.25) * one_over_two_pi - a * 0.5 ka1 = a2 ka2 = 2 * a2 ka3 = 3 * a2 2.upto(harms) do |k| if b != a temp = one_over_two_pi / ((b - a) * k) sines[k] = (cos(ka2) + (sin(ka2) - sin(k * b2)) * temp) * (temp1 / k) cosines[k] = (-sin(ka2) + (cos(ka2) - cos(k * b2)) * temp) * (temp1 / k) end sines[k] = sines[k] + ((1.0 - cos(ka2)) / k) + \ ((cos(ka1) - 1.0) * 0.5) / (k - 1) + \ ((cos(ka3) - 1.0) * 0.5) / (k + 1) sines[k] *= one_over_two_pi cosines[k] = cosines[k] + sin(ka2) / k - (sin(ka1) * 0.5) / (k - 1) - (sin(ka3) * 0.5) / (k + 1) cosines[k] *= one_over_two_pi ka1 += a2 ka2 += a2 ka3 += a2 end glot_table.fill(0.0) x = 0.0 glot_table.length.times do |j| 1.upto(harms) do |k| glot_table[j] = glot_table[j] + cosines[k] * cos(k * x) + sines[k] * sin(k * x) end x += two_pi_over_table_size end s_glot_mix = 1.0 delta = 1.0 / (next_offset - i) if first_glot.nonzero? glot_table2.map_with_index! do |val, j| glot_table[j] end first_glot = 0 end new_glot = 0 end s_glot_mix -= delta s_glot = env(glot_env) s_noise = env(noise_env) pitch = env(frq_env) vibr_amt = env(vib_env) table_increment = pitch * (1.0 + vibr_amt * oscil(vib_osc) + rand_interp(ran_vib)) * table_size_over_sampling_rate last_lip_out = last_lip_in + last_tract_plus last_lip_refl = (last_lip_in + last_tract_plus) * lip_refl_gain last_lip_in = last_tract_plus # next glot tick glotsamp = dline2[1] * glot_refl_gain if table_increment.nonzero? table_location += table_increment if table_location >= table_size then table_location -= table_size end int_loc = table_location.floor table1 = glot_table[int_loc] table2 = glot_table2[int_loc] glotsamp = glotsamp + s_glot * (table1 + s_glot_mix * (table2 - table1)) # glot noise tick if gn_table[int_loc].nonzero? and gn_gain.nonzero? gn_out = gn_gain * s_glot * (1.0 - random(2.0)) - gn_coeffs[3] * gn_del[3] - gn_coeffs[2] * gn_del[2] - gn_coeffs[1] * gn_del[1] - gn_coeffs[0] * gn_del[0] 3.downto(1) do |j| gn_del[j] = gn_del[j - 1] end gn_del[0] = gn_out end glotsamp = glotsamp + gn_out * gn_table[int_loc] end # next tract tick lt[0] = dline1[2] + dline2[2] dline2[1] = dline2[2] + coeffs[1] * (glotsamp - dline2[2]) temp = glotsamp + (dline2[1] - dline2[2]) 2.upto(noseposition - 1) do |j| dline2[j] = dline2[j + 1] + coeffs[j] * (dline1[j - 1] - dline2[j + 1]) dline1[j - 1], temp = temp, dline1[j - 1] + (dline2[j] - dline2[j + 1]) end jj = noseposition # next nasal tick plussamp = dline1[jj - 1] minussamp = dline2[jj + 1] nose_reftemp = 0.0 if velum_pos.zero? and time_nose_closed >= nose_ring_time # nasal tick nose_reftemp = alpha[1] * plussamp + alpha[2] * minussamp + alpha[3] * nose2[1] nose_last_minus_refl = nose_reftemp - plussamp nose_last_plus_refl = nose_reftemp - minussamp else if velum_pos.nonzero? time_nose_closed = 0 else time_nose_closed += 1 end nose_reftemp = alpha[1] * plussamp + alpha[2] * minussamp + alpha[3] * nose2[1] plus_in = velum_pos * (nose_reftemp - nose2[1]) nose_last_minus_refl = nose_reftemp - plussamp nose_last_plus_refl = nose_reftemp - minussamp nose_reftemp = nose_coeffs[1] * (plus_in - nose2[2]) nose2[1] = nose2[2] + nose_reftemp nose_temp = plus_in + nose_reftemp 2.upto(noselength - 2) do |j| nose_reftemp = nose_coeffs[j] * (nose1[j - 1] - nose2[j + 1]) nose2[j] = nose2[j + 1] + nose_reftemp nose1[j - 1], nose_temp = nose_temp, nose1[j - 1] + nose_reftemp end nose_reftemp = nose_coeffs[noselength - 1] * (nose1[noselength - 2] - nose_last_output * 0.25) nose2[noselength - 1] = nose_last_output * 0.25 + nose_reftemp nose1[noselength - 1] = nose1[noselength - 2] + nose_reftemp nose1[noselength - 2] = nose_temp nose_filt1, nose_filt = nose_filt, nose1[noselength - 1] nose_last_output = (nose_filt + nose_filt1) * 0.5 end dline2[jj] = nose_last_minus_refl dline1[jj - 1], temp = temp, nose_last_plus_refl (noseposition + 1).upto(tractlength - 2) do |j| dline2[j] = dline2[j + 1] + coeffs[j] * (dline1[j - 1] - dline2[j + 1]) dline1[j - 1], temp = temp, dline1[j - 1] + (dline2[j] - dline2[j + 1]) end dline2[tractlength - 1] = last_lip_refl + coeffs[tractlength - 1] * (dline1[tractlength - 2] - last_lip_refl) dline1[tractlength - 1] = dline1[tractlength - 2] + (dline2[tractlength - 1] - last_lip_refl) dline1[tractlength - 2] = temp if noise_gain.nonzero? noise_input = 1.0 - random(2.0) # a guess 3.downto(1) do |j| outz[j] = outz[j - 1] end outz[0] = noise_output noise_output = noise_input - inz2 4.times do |j| noise_output = noise_output - noise_c[j] * outz[j] end inz2, inz1 = inz1, noise_input dline1[noise_pos] = dline1[noise_pos] + noise_output * noise_gain * s_noise end last_tract_plus = dline1[tractlength - 1] * lip_radius lt[1] = ltgain * (lt[0] + ltcoeff * lt[1]) amp * (last_lip_out + nose_last_output + lt[1]) end end Test_glt = [10, 0.65, 0.65] Loud_glt = [13, 0.6, 0.6] Soft_glt = [13, 0.65, 0.73] Wide4_glt = [18, 0.534, 0.56] Wide5_glt = [10, 0.65, 0.65] Greekdefault_glt = [20, 0.65, 0.672472] Lowbass_glt = [99, 0.5, 0.17737593] Aa_shp = [8, 0.63110816, 0.94615144, 1.0756062, 0.9254686, 0.9928594, 0.98307705, 1.4507878, 0.95167005, 0.9, -0.4, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] Hh2_shp = [8, 0.928177, 0.61326, 0.39779, 0.530387, 0.679558, 0.961326, 1.44199, 1.09392, 0.7, -0.203125, 1.0, 0.0, 554.1667, 0.8, 2000.0, 0.772222, 0.0] Dhh_shp = [8, 0.828729, 1.45856, 0.9882353, 0.662983, 0.9352941, 1.2529411, 0.40588236, 1.1740758, 0.7, -0.140625, 7.0, 0.023333002, 3039.613, 0.691692, 1264.1677, 0.404788, 0.0] Aah_shp = [8, 0.8214024, 0.7839217, 1.0981537, 0.9937591, 0.817757, 1.1907763, 1.3149668, 1.0705689, 0.7, -0.4, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] Hhh_shp = [8, 0.928177, 0.61326, 0.39779, 0.530387, 0.679558, 0.961326, 1.44199, 1.09392, 0.7, -0.203125, 1.0, 0.046296295, 554.1667, 0.8, 2000.0, 0.7722222, 0.0] Ohh_shp = [8, 1.02762, 0.696133, 0.39779, 0.513812, 0.6371682, 1.4070797, 1.80663, 0.5044248, 0.7, -0.2, 1.0, 0.0, 1000.0, 0.0, 0.0, 0.0, 0.0] Ah_shp = [8, 0.7162393, 0.6389201, 0.8881412, 0.6060006, 1.293248, 1.4140776, 1.8503952, 0.8622935, 0.9, -0.4, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] Oo_shp = [8, 0.46043858, 1.0865723, 0.33916336, 0.88724023, 0.9989101, 1.224445, 0.39867023, 0.506609, 0.9, -0.4, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] Ahh_shp = [8, 0.928177, 0.779006, 0.629834, 0.629834, 1.02762, 1.65746, 1.62431, 0.944751, 0.7, -0.45, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] Eem_shp = [8, 0.928177, 1.37569, 1.37569, 0.679558, 0.629834, 0.24817872, 0.56896555, 0.662983, 0.7, -0.403125, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.09677419] Hoo_shp = [8, 1.32597, 1.29282, 0.39779, 0.530387, 1.32597, 1.34254, 1.78182, 0.46408796, 0.7, -0.4, 1.0, 0.031045755, 2215.7856, 0.82698005, 1026.6984, 0.96960765, 0.0] Ooo_shp = [8, 1.32597, 1.29282, 0.39779, 0.530387, 1.32597, 1.34254, 1.78182, 0.464088, 0.7, -0.4, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] Ee_shp = [8, 1.02, 1.637, 1.67, 1.558, 0.952, 0.501, 0.681, 0.675, 0.9, -0.4, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] Ih_shp = [8, 0.72092783, 1.2719809, 1.3881364, 0.6532612, 0.7501422, 0.65654784, 0.8194081, 0.6556785, 0.9, -0.4, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] Ee2_shp = [8, 0.9180887, 1.3481673, 1.3433423, 0.74573994, 0.593326, 0.5647744, 0.6692766, 0.7419633, 0.7, -0.405254, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] Ihh_shp = [8, 0.7906788, 1.272475, 1.4089537, 0.68072784, 0.62673146, 0.7479623, 0.7506758, 0.7054355, 0.9, -0.4, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] Open_shp = [8, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 0.7, -0.45, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0] Thh_shp = [8, 0.828729, 1.45856, 0.9882353, 0.662983, 0.9352941, 1.2529411, 0.40588236, 1.1740758, 0.7, -0.140625, 7.0, 0.101764, 3039.613, 0.691692, 1264.1677, 0.404788, 0.0] Aw_shp = [8, 1.0525645, 0.643587, 0.935229, 0.4901642, 1.0743295, 1.1822895, 1.4161918, 0.82537806, 0.9, -0.4, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] Eee_shp = [8, 0.928177, 1.37569, 1.37569, 0.679558, 0.629834, 0.646409, 0.56896555, 0.662983, 0.7, -0.403125, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] Ttp_shp = [8, 0.928177, 0.779006, 0.629834, 0.629834, 1.02762, 0.18584079, 1.62431, 0.944751, 0.7, -0.45, 6.0, 0.388889, 10514.583, 0.854335, 1315.2043, 0.280428, 0.0] Aww_shp = [8, 1.02762, 0.696133, 0.563536, 0.513812, 0.977901, 1.37569, 1.80663, 0.712707, 0.7, -0.2, 1.0, 0.0, 1000.0, 0.0, 0.0, 0.0, 0.0] Eee2_shp = [8, 0.928177, 1.37569, 1.37569, 0.679558, 0.629834, 0.646409, 0.5117647, 0.662983, 0.7, -0.203125, 7.3688526, 0.0, 5214.53, 0.975806, 0.0, 0.0, 0.0] Jjj_shp = [8, 0.928177, 0.779006, 0.629834, 0.629834, 1.02762, 0.1592921, 1.1464338, 0.944751, 0.7, -0.45, 6.0, 0.098039, 2315.7278, 0.7089554, 3066.7, 0.7983351, 0.0] Ttt_shp = [8, 0.928177, 0.779006, 0.629834, 0.629834, 1.02762, 0.0, 1.62431, 0.944751, 0.7, -0.45, 6.0, 0.388889, 10514.583, 0.854335, 1315.2043, 0.280428, 0.0] Bb2_shp = [8, 1.0, 1.0, 0.46902645, 0.5486725, 0.65486723, 1.079646, 1.3982301, 0.0, 0.7, -0.2, 8.0, 0.03, 500.0, 0.98, 0.0, 0.0, 0.0] Eh_shp = [8, 0.7866194, 1.1630946, 1.2335452, 0.93186677, 0.94121367, 0.7586716, 1.3509308, 0.8279036, 0.9, -0.4, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] Kkp_shp = [8, 0.8214024, 0.7839217, 1.0981537, 0.1592921, 1.061947, 1.1907763, 1.3149668, 1.0705689, 0.7, -0.4, 4.0, 0.4, 2000.0, 0.93, 0.0, 0.0, 0.0] Pipe1_shp = [8, 1.0, 1.0, 1.0, 0.7, 0.7, 0.7, 0.7, 0.7, 0.0, 0.0, 1.0, 0.0, 100.0, 0.0, 0.0, 0.0, 0.0] Tzz_shp = [8, 0.828729, 1.45856, 0.9882353, 0.662983, 0.9352941, 1.2529411, 0.40588236, 1.1740758, 0.7, -0.140625, 7.0, 0.101764, 3039.613, 0.691692, 1264.1677, 0.404788, 0.0] Bbb_shp = [8, 1.0, 1.0, 0.46902645, 0.5486725, 0.65486723, 1.079646, 1.3982301, 0.0, 0.7, -0.2, 8.0, 0.03, 500.0, 0.98, 0.0, 0.0, 0.0] Ehh_shp = [8, 0.682, 1.554, 1.581, 1.367, 1.315, 1.579, 0.843, 1.476, 0.7, -0.24507, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] Kk2_shp = [8, 0.82140243, 0.7839217, 1.0981537, 0.0, 1.061947, 1.1907763, 1.3149668, 1.0705689, 0.7, -0.4, 5.0, 0.01, 2000.0, 0.93, 0.0, 0.0, 0.0] PpP_shp = [8, 1.0, 1.0, 0.3362832, 0.49557513, 0.7079646, 1.2389379, 1.1327434, 0.29203534, 0.7, -0.2, 8.0, 0.040740736, 0.0, 0.89649165, 2082.2144, 0.8713607, 0.0] Uhh_shp = [8, 0.928177, 0.61326, 0.39779, 0.530387, 0.679558, 0.961326, 1.44199, 1.09392, 0.7, -0.203125, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] Big_shp = [8, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0] Euu_shp = [8, 0.9285748, 1.3756071, 1.3747121, 0.6794088, 0.60398144, 0.43471563, 0.8356653, 0.7158814, 0.7, -0.403122, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] Kkk_shp = [8, 0.8214024, 0.7839217, 1.0981537, 0.0, 1.061947, 1.1907763, 1.3149668, 1.0705689, 0.7, -0.4, 4.0, 0.09444445, 2000.0, 0.93, 0.0, 0.0, 0.0] Ppp_shp = [8, 1.0, 1.0, 0.3362832, 0.49557513, 0.7079646, 1.2389379, 1.1327434, 0.0, 0.7, -0.2, 8.0, 0.05, 500.0, 0.98, 0.0, 0.0, 0.0] Uu_shp = [8, 0.45291674, 1.0539645, 0.39576897, 0.8116293, 1.0510263, 1.1789232, 0.47529656, 0.62563825, 0.9, -0.4, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] Fff_shp = [8, 0.93787295, 0.70496833, 0.8969878, 0.60815966, 0.9375178, 0.7412625, 1.1285298, 0.2665695, 0.7, -0.202603, 8.0, 0.10341219, 8236.909, 0.945306, 79.28094, 0.498648, 0.0] Ll2_shp = [8, 0.928177, 0.779006, 0.71772796, 0.807417, 1.02762, 1.65746, 0.36206907, 0.86510503, 0.7, -0.258055, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.20806663] Uuu_shp = [8, 0.55, 0.943094, 1.035, 0.434071, 1.14681, 1.487, 0.555, 0.656, 0.9, -0.4, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] Lll_shp = [8, 0.928177, 0.779006, 0.7330638, 0.8156748, 1.02762, 1.65746, 0.3620689, 0.944751, 0.7, -0.103125, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.21774194] Rolledr_shp = [8, 0.3365169, 0.9244819, 1.0542682, 0.4485168, 1.0597233, 0.054845095, 0.66896766, 0.8336522, 0.9, -0.4, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] Vvv_shp = [8, 0.9400966, 0.6775904, 0.88759726, 0.59890866, 0.9485658, 0.737778, 1.1542239, 0.23893797, 0.7, -0.2, 8.0, 0.5, 8500.0, 0.95, 0.0, 0.5, 0.0] Rolledrc_shp = [8, 0.928177, 0.779006, 0.629834, 0.629834, 1.02762, 0.0, 1.62431, 0.944751, 0.7, -0.45, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] Mmm_shp = [8, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.7, -0.2, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.503268] Rolledro_shp = [8, 0.928177, 0.779006, 0.629834, 0.629834, 1.02762, 0.42477876, 1.62431, 0.944751, 0.7, -0.45, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] Breath_shp = [8, 0.928177, 0.779006, 0.629834, 0.629834, 1.02762, 1.65746, 1.62431, 0.944751, 0.7, -0.45, 1.0, 0.018518519, 2588.6013, 0.90612125, 812.6343, 0.9814815, 0.0] Moo_shp = [8, 1.32597, 1.29282, 0.39779, 0.530387, 1.32597, 1.34254, 1.78182, 0.0, 0.7, -0.4, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.30645162] Rr2_shp = [8, 0.3365169, 0.9244819, 1.0542682, 0.4485168, 1.0597233, 0.71856207, 0.66896766, 0.7274576, 0.9, -0.4, 1.0, 0.0, 0.0, 0.0, 0.0, 32.000004, 0.0] Chh_shp = [8, 0.928177, 0.779006, 0.629834, 0.629834, 1.02762, 0.1592921, 1.1464338, 0.944751, 0.7, -0.45, 6.0, 0.098039, 2315.7278, 0.7089554, 3066.7, 0.7983351, 0.0] Gg2_shp = [8, 0.8214024, 0.4122405, 0.40788835, 0.0, 0.8495575, 0.7129002, 0.7308959, 0.7785335, 0.7, -0.4, 4.0, 0.05, 2000.0, 0.9, 0.0, 0.0, 0.0] Nng_shp = [8, 1.0, 1.0, 1.0333333, 0.0, 1.0, 0.99999994, 0.9568965, 1.3189656, 0.7, -0.2, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0] Rrr_shp = [8, 0.3365169, 0.9244819, 1.0542682, 0.4485168, 1.0597233, 0.71856207, 0.66896766, 0.7274576, 0.9, -0.4, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] Wsp_shp = [8, 0.928177, 0.779006, 0.629834, 0.629834, 1.02762, 1.65746, 1.62431, 0.944751, 0.7, -0.45, 1.0, 0.018518519, 0.0, 0.97, 0.0, 0.0, 0.0] Ggg_shp = [8, 0.8214024, 0.7839217, 1.0981537, 0.0, 0.8495575, 0.7129002, 0.7308959, 0.7785335, 0.7, -0.4, 4.0, 0.05, 2000.0, 0.9, 0.0, 0.0, 0.0] Nnn_shp = [8, 1.0, 1.0, 1.0, 1.4579439, 1.0, 0.0, 0.9568965, 1.3189656, 0.7, -0.2, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.503268] Sh2_shp = [8, 0.828729, 1.45856, 0.9882353, 0.662983, 0.9352941, 1.2529411, 0.40588236, 0.9882353, 0.7, -0.140625, 7.0, 0.0, 2451.5984, 0.928097, 2957.0518, 0.883636, 0.0] Xx2_shp = [8, 0.928177, 1.37569, 1.37569, 0.8495575, 0.3451327, 0.646409, 0.56896555, 0.662983, 0.7, -0.403125, 5.0, 0.022222, 2102.0833, 0.805556, 1735.4166, 0.759259, 0.0] Dd2_shp = [8, 0.928177, 0.779006, 0.629834, 0.629834, 1.02762, 0.0, 0.72165513, 0.5996184, 0.7, -0.45, 6.0, 0.02, 4851.6665, 0.953704, 2500.0, 0.966296, 0.0] Ggg1_shp = [8, 0.8214024, 0.7839217, 1.0981537, 0.18584079, 1.061947, 1.1907763, 1.3149668, 1.0705689, 0.7, -0.4, 4.0, 0.4, 2000.0, 0.9, 0.0, 0.0, 0.0] Noisahh_shp = [8, 0.928177, 0.779006, 0.629834, 0.629834, 1.02762, 1.65746, 1.62431, 0.944751, 0.7, -0.45, 1.0, 0.005, 0.0, 0.787037, 3777.0835, 0.759259, 0.0] Shh_shp = [8, 0.828729, 1.45856, 0.9882353, 0.662983, 0.9352941, 1.2529411, 0.40588236, 0.9882353, 0.7, -0.140625, 7.0, 0.023333, 2451.5984, 0.9280972, 2957.0518, 0.88363576, 0.0] Xxx_shp = [8, 0.928177, 1.37569, 1.37569, 0.3451327, 0.6371682, 0.646409, 0.56896555, 0.662983, 0.7, -0.403125, 4.0, 0.022222219, 2102.0833, 0.8055556, 612.5, 0.7592593, 0.0] Ddd_shp = [8, 0.928177, 0.779006, 0.629834, 0.629834, 1.02762, 0.0, 0.72165513, 0.5996184, 0.7, -0.45, 6.0, 0.02, 4851.6665, 0.953704, 2500.0, 0.966296, 0.0] Gxx_shp = [8, 0.928177, 1.37569, 1.37569, 0.3451327, 0.6371682, 0.646409, 0.56896555, 0.662983, 0.7, -0.403125, 4.0, 0.022222, 2102.0833, 0.805556, 612.5, 0.759259, 0.0] None_shp = [8, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] Sss_shp = [8, 0.928177, 1.3588235, 1.3588235, 0.679558, 0.61764705, 0.63529414, 0.31764707, 0.65294117, 0.7, -0.103125, 7.0, 0.105292, 1500.0, 0.916452, 4943.75, 0.97222227, 0.0] Zzz_shp = [8, 0.928177, 1.3588235, 1.3588235, 0.679558, 0.61764705, 0.63529414, 0.31764707, 0.65294117, 0.7, -0.103125, 7.0, 0.016, 1500.0, 0.9257112, 4943.75, 0.925926, 0.0] =begin with_sound do singer(0, 0.1, [ [0.4, Ehh_shp, Test_glt, 523.0, 0.8, 0.0, 0.01], [0.6, Oo_shp, Test_glt, 523.0, 0.7, 0.1, 0.01]]) end =end =begin with_sound do singer(0.2, 0.1,[ [0.05, Ehh_shp, Test_glt, 523.0, 0.8, 0.0, 0.01], [0.15, Ehh_shp, Test_glt, 523.0, 0.8, 0.0, 0.01], [0.05, Kkk_shp, Test_glt, 523.0, 0.0, 0.0, 0.01], [0.05, Kkk_shp, Test_glt, 523.0, 0.0, 0.0, 0.01], [0.02, Kkp_shp, Test_glt, 523.0, 0.0, 1.0, 0.01], [0.08, Kkp_shp, Test_glt, 523.0, 0.0, 0.2, 0.01], [0.05, Ooo_shp, Test_glt, 523.0, 0.8, 0.0, 0.01], [0.15, Ooo_shp, Test_glt, 523.0, 0.8, 0.0, 0.01], [0.05, Eee_shp, Test_glt, 523.0, 0.8, 0.0, 0.01], [0.15, Eee_shp, Test_glt, 523.0, 0.8, 0.0, 0.01], [0.05, Ehh_shp, Test_glt, 523.0, 0.8, 0.0, 0.01], [0.15, Ehh_shp, Test_glt, 523.0, 0.8, 0.0, 0.01], [0.05, Mmm_shp, Test_glt, 523.0, 0.8, 0.0, 0.01], [0.15, Mmm_shp, Test_glt, 523.0, 0.8, 0.0, 0.01], [0.10, Mmm_shp, Test_glt, 523.0, 0.0, 0.0, 0.01]]) end =end # singer.rb ends here snd-16.1/funcs.scm0000644000076400007640000000513512340224110012146 0ustar bilbil(define-envelope pna '(0 0 1 1 10 .6000 25 .3000 100 0 )) (define-envelope ind2 '(0 1 25 .4000 75 .6000 100 0 )) (define-envelope high_att_ind '(0 1 25 .2000 75 .4000 100 0 )) (define-envelope no_att_ind '(0 .6000 75 .6000 100 0 )) (define-envelope no_dec_ind '(0 1 25 .4000 75 .6000 100 .6000 )) (define-envelope no_att_or_dec_ind '(0 .6000 100 .6000 )) (define-envelope ampf '(0 0 25 1 60 .7000 75 1 100 0 )) (define-envelope rampf '(0 0 100 1 )) (define-envelope fast_up '(0 0 25 1 100 1 )) (define-envelope slow_up '(0 0 25 0 100 1 )) (define-envelope tapf '(0 0 1 1 99 1 100 0 )) (define-envelope skwfrq '(0 -1 5 .2500 10 0 100 .1000 )) (define-envelope oldpizzf '(0 0 1 1 5 .6000 10 .3000 25 .1000 100 0 )) (define-envelope newpizzf '(0 0 1 1 5 .6000 10 .3000 25 .1000 99 .0200 100 0 )) (define-envelope pizzf '(0 0 1 1 5 .6000 10 .3000 25 .1000 100 0 )) (define-envelope legatof '(0 0 30 1 90 1 100 0 )) (define-envelope marcatof '(0 0 3 1 10 .8000 95 1 100 0 )) (define-envelope onef '(0 1 100 1 )) (define-envelope mod_up '(0 0 25 0 75 1 100 1 )) (define-envelope mod_down '(0 1 25 1 75 0 100 0 )) (define-envelope one_to_zero '(0 1 75 1 100 0 )) (define-envelope zero_to_one '(0 0 75 0 100 1 )) (define-envelope down_flat '(0 1 25 0 75 .0500 100 0 )) (define-envelope down_down '(0 1 25 0 75 .0500 100 -1 )) (define-envelope down_up '(0 1 25 0 75 .0500 100 1 )) (define-envelope flat_down '(0 -.1000 10 .1000 25 0 75 .0500 100 -1 )) (define-envelope flat_up '(0 -.1000 10 .1000 25 0 75 0 100 1 )) (define-envelope up_flat '(0 -1 25 .0500 75 0 100 0 )) (define-envelope up_up '(0 -1 25 .0500 75 0 100 1 )) (define-envelope up_down '(0 -1 25 .0500 75 0 100 -1 )) (define-envelope swellf '(0 0 25 .8000 50 1 75 .8000 100 0 )) (define-envelope fpf '(0 0 25 1 50 .3000 75 .3000 100 0 )) (define-envelope indswell '(1 1 25 .4000 75 1 100 0 )) (define-envelope pyr '(0 1 25 .1000 95 .1000 100 0 )) (define-envelope fbell '(0 1 2 1.1000 25 .7500 75 .5000 100 .2000 )) (define-envelope lowbell '(0 1 5 1.2500 25 .8000 75 .5000 100 .2000 )) (define-envelope abell '(0 0 .1000 1 10 .6000 25 .3000 50 .1500 90 .1000 100 0 )) (define-envelope dwnup '(0 1 10 .4000 20 1 35 .3000 45 .8000 60 .2000 80 .6000 100 0 )) (define-envelope up50down '(0 0 50 1 100 0 )) (define-envelope metalamp '(0 0 .5000 1 5 1 10 .5000 15 .2500 35 .1000 100 0 )) (define-envelope slowupfastdown '(0 0 25 1 97 1 100 0 )) (define-envelope slowup '(0 0 50 .1000 95 1 100 0 )) (define-envelope indtoone '(0 1 25 .4000 100 .6500 )) (define-envelope whoosh '(0 0 75 .1000 90 .3000 97 .6000 100 1 )) (define-envelope mamp '(0 0 50 1 100 0 )) (define-envelope n_amp '(0 0 65 1 100 0 )) snd-16.1/sndwarp.scm0000644000076400007640000002744012622705137012531 0ustar bilbil;;; SNDWARP (provide 'snd-sndwarp.scm) (if (not (provided? 'snd-env.scm)) (load "env.scm")) ; normalize-envelope ;;; ;;; CLM 3 implementation of Richard Karpen's SNDWARP Csound Ugen. ;;; By Bret Battey. http://www.BatHatMedia.com ;;; translated to Scheme by Bill S Feb-05 ;;; changes for the optimizer 24-Oct-06 ;;; ;;; Except as noted below, the parameters are modeled directly after ;;; the Csound version of sndwarp. ;;; ISSUES ;;; ;;; Output in this new CLM version is seeming quite noisy/clipped (?) ;;; Varying stereo/mono input/output has not been tested in clm2 alterations. ;;; Hasn't been tested with differing input and output file sampling rates. ;;; Uses half-sine envelope only; doesn't support alternative windowing envs. ;;; Csound-style attack doesn't strictly match Csound results ;;; SNDWARP KEY PARAMETERS ;;; ;;; amp = Amplitude ;;; [number] ;;; ;;; amp-env = Amplitude envelope ;;; [envelope] ;;; ;;; stretch = Stretch value or time pointer envelope (see 'time-ptr') ;;; [number or envelope expressed in either stretch values ;;; (for stretch mode) or in seconds (in time-ptr mode)] ;;; ;;; srate = Resampling scalar (1 = same pitch, .5 = 1 octave lower, etc.) ;;; A negative srate will read backwards into the soundfile from ;;; the start of each read window (not available in Csound version). ;;; [number or envelope] ;;; ;;; inputbeg = Source file input offset. In 'stretch' mode (see 'time-ptr'), ;;; soundfile read will begin at inputbeg. In 'time-ptr' mode, ;;; inputbeg will be added to the time pointer. ;;; [number, in seconds] ;;; ;;; wsize = Size of the sndwarp windows. ;;; [number, in seconds] ;;; ;;; randw = Range of random values to be added to wsize ;;; [number, in seconds] ;;; ;;; overlaps = number of window overlaps ;;; [number per second] ;;; ;;; time-ptr = Flag to determine whether stretching or time-pointer mode ;;; is to be used in interpreting the 'stretch' parameter. ;;; In stretch mode, the value of 'stretch' will scale the time ;;; of the sound. For example, a value of 2 will stretch the sound ;;; by 2 times. Note that stretch values of or near 0 are not ;;; viable since window advance times are determined by dividing ;;; by the stretch value. ;;; In time-ptr mode, the value(s) of stretch are readin pointers ;;; into the soundfile. For example, to read through a file ;;; backwards from 2 seconds at half speed, one would use a ;;; stretch envelope like [0 2 1 0] with a 4 second note duration. ;;; [NIL = stretch mode, T = time-ptr mode] ;;; ;;; scale-time-ptr = Flag to determine whether the time-ptr envelope will be ;;; interpreted in absolute seconds or rescaled to fit the ;;; duration of the input sound file. ;;; {not part of csound implementation} ;;; [NIL = absolute, T = rescale] ;;; ;;; zero-start-time-ptr = Flag to determine when in time-ptr mode whether ;;; the first section of windows will start at ;;; time-ptr = 0. ;;; The csound sndwarp makes this assumption, so you ;;; always get a bit of the attack of the sound even ;;; if you try to run the time pointer starting in ;;; the middle or end. ;;; [NIL = 1st section starts according to time-ptr, ;;; T = 1st section always starts at time-ptr = 0] ;;; ;;; sndwarp-window-offset = Flag to determine how the windows are offset ;;; in time. T = Csound sndwarp style, windows ;;; in different layers line up. ;;; NIL = spread evenly. ;;; ;;; loc = Stereo panning position, where 0 = left and 1 = right. ;;; Uses simple sqrt method. ;;; [number or envelope] ;;; ;;; rev = Scalar for reverb sending to a CLM reverb instrument. ;;; [number or envelope] ;;; ;;; status = Flag to control whether SNDWARP prints a window %-complete count ;;; while working. ;;; [NIL = no status printing, T = status printing] ;;; ;;; srcwidth = width of the sinc function used in the interpolation function of ;;; CLM's "src" -- which provides the resampling in sndwarp. Defaults to ;;; 5. If you hear high-frequency artifacts in the output sound, try ;;; increasing this number. ;;; ;;; SNDWARP DEFAULTS (define sndwarp-amp 1.0) (define sndwarp-amp-env '(0 1 100 1)) (define sndwarp-stretch 1.0) (define sndwarp-srate 1.0) (define sndwarp-inputbeg 0.0) (define sndwarp-wsize 0.1) ; csound manual recommended start = .1 (define sndwarp-randw 0.02) ; csound manual recommended start = .02 (define sndwarp-overlaps 15) ; csound manual recommended start = 15 (define sndwarp-time-ptr #f) (define sndwarp-scale-time-ptr #f) (define sndwarp-zero-start-time-ptr #f) ; #t to match csound (define sndwarp-window-offset #f) ; #t to match csound (define sndwarp-loc 0.5) (define sndwarp-rev 0.1) (define sndwarp-srcwidth 5) ;;; UTILITY FUNCTIONS (define clmsw-2pi (* 2 pi)) ;;; SNDWARP (define* (sndwarp begtime dur file (amp sndwarp-amp) (amp-env sndwarp-amp-env) (stretch sndwarp-stretch) (srate sndwarp-srate) (inputbeg sndwarp-inputbeg) (wsize sndwarp-wsize) (randw sndwarp-randw) (overlaps sndwarp-overlaps) (time-ptr sndwarp-time-ptr) (scale-time-ptr sndwarp-scale-time-ptr) (zero-start-time-ptr sndwarp-zero-start-time-ptr) (window-offset sndwarp-window-offset) (loc sndwarp-loc) (rev sndwarp-rev) (srcwidth sndwarp-srcwidth)) (define (clmsw-envelope-or-number in) (if (number? in) (list 0 in 1 in) in)) (let* ((beg (seconds->samples begtime)) (end (+ beg (seconds->samples dur)))) (let* ((stereo-i (= (mus-sound-chans file) 2)) (stereo-o #f) ; (= (channels *output*) 2)) (f-a (make-readin file :channel 0)) (f-b (and stereo-i (make-readin file :channel 1))) (fsr (mus-sound-srate file)) ;; (fsize (framples file)) (fdur (mus-sound-duration file)) (rev-val rev) (loc-env (clmsw-envelope-or-number loc)) (srate-env (clmsw-envelope-or-number srate)) (time-env (clmsw-envelope-or-number stretch)) (wsize-env (clmsw-envelope-or-number wsize)) (rdA (make-src :input (lambda (dir) (readin f-a)) :srate 0.0 :width srcwidth)) (rdB (and stereo-i (make-src :input (lambda (dir) (readin f-b)) :srate 0.0 :width srcwidth))) (windf (make-oscil)) (wsizef (make-env wsize-env :duration dur)) (ampf (make-env amp-env :scaler amp :duration dur)) (sratef (make-env srate-env :duration dur)) (timef (make-env (if (and time-ptr scale-time-ptr) (normalize-envelope time-env (- fdur inputbeg)) time-env) :duration dur)) (locf (make-env loc-env :duration dur)) (writestart 0) (readstart (round (* fsr inputbeg))) (eow-flag #f) (overlap-ratio 0.0) (overlap-ratio-compl 0.0) (outa-val 0.0) (outb-val 0.0)) (do ((overlap 0 (+ 1 overlap))) ((or eow-flag (= overlap overlaps))) (set! overlap-ratio (/ overlap overlaps)) (set! overlap-ratio-compl (- 1 overlap-ratio)) (set! eow-flag #f) (set! writestart beg) (set! (mus-location ampf) beg) (set! (mus-location locf) beg) (do ((section 0 (+ 1 section))) ((or eow-flag (= overlap overlaps))) (set! (mus-location timef) writestart) (set! (mus-location sratef) writestart) (set! (mus-location wsizef) writestart) (set! wsize (env wsizef)) (let* ((winlen (if (= overlap 0 section) ; first section of first overlap isn't randomized wsize (+ wsize (random randw)))) (winsamps (seconds->samples winlen)) (srate-val (env sratef)) (time-val (env timef))) ;; Even for the 1st section's truncated envelopes, the frequency of the envelope must be as if the envelope were full duration. (set! (mus-frequency windf) (* .5 (/ fsr winsamps))) ;; Set windowing oscillator to starting phase and appropriate frequency to provide half-sine envelope over window. ;; Phase must be altered for 1st envelope of each overlap stream. (set! (mus-phase windf) (if (= section 0) (if (= overlap 0) 0.0 (* .5 clmsw-2pi overlap-ratio-compl)) 0.0)) ;; Either use the absolute time pointer or a scaled increment. ;; If first section in scaled mode, must initialize section readstart to beginning plus first overlap position. ;; In both cases, need to alter readstart and length of first section's windows based on phase of overlap (if time-ptr ;; TIME-PTR mode (if (= section 0) ;; initial section (let ((overlap-start (if window-offset ;; Csound style - start each overlap series further into the soundfile (if (= overlap 0) 0 (round (* winlen overlap-ratio-compl))) ;; Alternative style - start each overlap series at 0 0)) ;; To match csound version, 1st section must start reading at 0. Using zero-start-time-ptr ;; flag = #f, however, allows 1st section to start as determined by time-ptr instead. (adj-time-val (if zero-start-time-ptr 0.0 time-val))) (set! readstart (round (* fsr (+ inputbeg overlap-start adj-time-val)))) (if (not (= overlap 0)) (set! winsamps (floor (* winsamps overlap-ratio))))) ;; remaining sections (set! readstart (round (* fsr (+ inputbeg time-val))))) ;; STRETCH mode (if (= section 0) ;; initial section (let ((init-read-start (if window-offset ;; Csound style - start each overlap series further into the soundfile (if (= overlap 0) 0 (round (* winlen overlap-ratio-compl))) ;; Alternative style - start each overlap series at 0 0))) (set! readstart (round (* fsr (+ inputbeg init-read-start)))) (if (not (= overlap 0)) (set! winsamps (floor (* winsamps overlap-ratio))))) ;; remaining sections (set! readstart (round (+ readstart (* fsr (/ winlen time-val))))))) ;; Set readin position and sampling rate (set! (mus-location f-a) readstart) (set! (mus-increment rdA) srate-val) (mus-reset rdA) (if stereo-i (begin (set! (mus-location f-b) readstart) (set! (mus-increment rdB) srate-val) (mus-reset rdB))) ;; Write window out (do ((k 0 (+ 1 k)) (i writestart (+ i 1))) ((or eow-flag (= k winsamps))) (if (> i end) (begin (set! eow-flag #t) (set! overlap (+ 1 overlaps))) (let* ((amp-val (env ampf)) (loc-val (env locf)) (win-val (oscil windf)) (sampa (* (src rdA) win-val)) (sampb (if stereo-i (* (src rdB) win-val)))) ;; channel panning (if stereo-o (let ((apan (sqrt loc-val)) (bpan (sqrt (- 1 loc-val)))) (if stereo-i (begin ;; stereo in and out (set! outa-val (* amp-val apan sampa)) (set! outb-val (* amp-val bpan sampb))) (begin ;; mono in, stereo out (set! outa-val (* amp-val apan sampa)) (set! outb-val (* amp-val bpan sampa))))) ;; stereo in, mono out (if stereo-i (set! outa-val (* amp-val (+ sampa sampb) .75)) ;; mono in, mono out (set! outa-val (* amp-val sampa)))) ;; output (outa i outa-val) (if stereo-o (begin (outb i outb-val) (if *reverb* (outa i (* rev-val outa-val) *reverb*))))))) (if (and (not eow-flag) ;; For first section, have to backup readstart (= section 0) (> overlap 0) (not time-ptr)) (set! readstart (- readstart (round (* fsr winlen overlap-ratio-compl))))) (set! writestart (+ writestart winsamps)))))))) snd-16.1/snd-test.fs0000644000076400007640000114256212476114577012457 0ustar bilbil\ snd-test.fs -- Snd Forth code and tests \ Translator/Author: Michael Scholz \ Created: 06/08/05 00:09:28 \ Changed: 15/03/05 13:28:40 \ Tags: FIXME - something is wrong \ XXX - info marker \ \ Tested with: \ Snd 15.x \ Fth 1.3.x \ \ The most Gtk tests will be skipped if not gtk3. \ \ Reads init file ./.sndtest.fs or ~/.sndtest.fs for global variables, \ hooks, etc. \ \ Example: \ \ cat ./.sndtest.fs \ "/tmp" set-save-dir to original-save-dir \ save-dir set-temp-dir to original-temp-dir \ \ #t to with-big-file \ "/usr/opt/sound/SFiles/bigger.snd" to bigger-snd \ "/usr/opt/sound/sf1/" to sf-dir \ #t to all-args \ 2 to *tests* \ #t to *snd-test-verbose* \ \ lambda: <{ output -- }> \ "sox -qV1 %s -d" #( output ) string-format file-system unless \ "exit %d\n" #( exit-status ) fth-print \ then \ ; to *snd-test-ws-player* \ \ #t to *snd-test-ws-play* \ #t to *snd-test-ws-statistics* \ #t to *snd-test-ws-verbose* \ \ Start tests: \ \ snd -noinit -load snd-test.fs \ all tests \ snd -noinit -load snd-test.fs 10 15 19 \ test 10 15 19 \ snd -noinit -load snd-test.fs -23 \ all tests except 23 \ \ test 00: constants \ test 01: defaults \ test 02: headers \ test 03: variables \ test 04: sndlib \ test 05: simple overall checks \ test 08: clm \ test 10: marks \ test 15: chan-local vars \ test 19: save and restore \ test 23: with-sound \ test 27: general ( will be replaced in the future ) \ test 28: errors 'alsa provided? constant *with-test-alsa* 'complex provided? constant *with-test-complex* 'gl provided? constant *with-test-gl* 'gl2ps provided? constant *with-test-gl2ps* 'gsl provided? constant *with-test-gsl* 'gtk3 provided? constant *with-test-gtk3* 'snd-gtk provided? constant *with-test-gtk* 'snd-ladspa provided? constant *with-test-ladspa* 'snd-motif provided? constant *with-test-motif* 'snd-nogui provided? constant *with-test-nogui* *with-test-nogui* not constant *with-test-gui* 24 set-object-print-length *with-test-complex* [unless] -1 constant 0+i [then] *with-test-nogui* [if] #f value stdout-io #f value stderr-io [else] \ Prints to Snd's listener and stdout/stderr. \ The original CLM-PRINT uses only SND-PRINT but we want output \ to stdout/stderr too. : clm-print ( fmt :optional args -- ) fth-format ( str ) snd-print ( str ) .stdout ; :port-name "sndout" :write-line lambda: <{ line -- }> line snd-print ( line ) .stdout ; make-soft-port set-*stdout* value stdout-io :port-name "snderr" :write-line lambda: <{ line -- }> line snd-print ( line ) .stderr ; make-soft-port set-*stderr* value stderr-io [then] \ Output words: We can't use clm-print here if we want xterm output \ (clm-message uses clm-print). \ SND-TEST-MESSAGE: Puts a comment sign before output \ and terminates with a carriage return. : snd-test-message ( fmt args -- ) ." \ " fth-print cr ; \ SND-DISPLAY: Wraps text like snd-test-message and prepends text with \ current line number ("\ [102] text\n"). : (snd-display) { fmt args lno -- } fmt args string-format { str } "\\ [%d] %s\n" #( lno str ) fth-print ; : snd-display ( fmt args -- ) postpone *lineno* postpone (snd-display) ; immediate \ *SND-TEST-VERBOSE*: progress information in long tests \ \ test 19-save/restore: function names \ test 28-errors: prints proc-array length and progress information #f value *snd-test-verbose* \ WITH-SOUND control \ \ options for test 23-with-sound: \ :play \ :player \ :statistics \ :verbose (event (bird) and instrument names) #f value *snd-test-ws-play* #f value *snd-test-ws-player* #f value *snd-test-ws-statistics* #f value *snd-test-ws-verbose* \ run snd-test.fs *tests* times 1 value *tests* \ You may set them in .sndtest.fs. #f value my-snd-error-hook #f value my-mus-error-hook "HOME" getenv value *home* save-dir *home* "/zap/snd" $+ || value original-save-dir temp-dir *home* "/zap/tmp" $+ || value original-temp-dir sound-file-extensions value original-sound-file-extensions listener-prompt value original-prompt mus-file-buffer-size value default-file-buffer-size 8 value *info-array-print-length* "/home/bil/sf1/" value sf-dir "/home/bil/zap/sounds/bigger.snd" value bigger-snd #f value with-big-file #f value all-args \ Global variables may be overridden in `pwd`/.sndtest.fs or ~/.sndtest.fs. ".sndtest.fs" load-init-file \ default 1, can be reset in .sndtest.fs *tests* integer? [if] *tests* 0> [if] *tests* [else] 1 [then] [else] 1 [then] to *tests* 0 value *clmtest* *with-test-nogui* [if] '( 0.0 0.1 ) value x-bounds-value : x-bounds <{ :optional snd 0 chn 0 axis 0 -- res }> x-bounds-value ; : set-x-bounds <{ bounds :optional snd 0 chn 0 axis 0 -- res }> bounds dup to x-bounds-value ; '( -1.0 1.0 ) value y-bounds-value : y-bounds <{ :optional snd 0 chn 0 axis 0 -- res }> y-bounds-value ; : set-y-bounds <{ bounds :optional snd 0 chn 0 axis 0 -- res }> bounds dup to y-bounds-value ; : position->x <{ val :optional snd 0 chn 0 ax time-graph -- res }> #f ; <'> position->x alias position->y : x->position <{ val :optional snd 0 chn 0 ax time-graph -- res }> #f ; <'> x->position alias y->position : channel-widgets <{ :optional snd 0 chn 0 -- res }> #f ; #t value enved-filter-value : enved-filter <{ -- res }> enved-filter-value ; : set-enved-filter <{ val -- res }> val dup to enved-filter-value ; 34 value graph-cursor-value : graph-cursor <{ -- res }> graph-cursor-value ; : set-graph-cursor <{ val -- res }> val dup to graph-cursor-value ; nil value enved-envelope-value : enved-envelope <{ -- res }> enved-envelope-value ; : set-enved-envelope <{ val -- res }> val dup to enved-envelope-value ; hot-colormap value colormap-value : colormap <{ -- res }> colormap-value ; : set-colormap <{ val -- res }> val positive? val 20 <= && if val to colormap-value then val ; : add-colormap <{ name func -- res }> #f ; <'> noop alias integer->colormap ( n -- cm ) <'> noop alias colormap->integer ( cm -- n ) : make-graph-data <{ :optional snd 0 chn 0 edpos 0 low -1 high -1 -- res }> #f ; : graph-data <{ data :optional snd 0 chn 0 cx 0 low -1 high -1 gs 0 cr 0 -- }> #f ; : draw-line <{ x0 y0 x1 y1 :optional snd 0 chn 0 ax time-graph cr 0 -- res }> #f ; : draw-axes <{ wid gc lab :optional x0 0 x1 0 y0 0 y1 0 st 0 axes 0 -- res }> #f ; <'> noop alias axis-color <'> noop alias foreground-color <'> noop alias highlight-color <'> noop alias snd-gcs \ These are already created in snd-nogui.c \ \ 2 #f create-hook mouse-enter-graph-hook \ 3 #f create-hook mouse-enter-label-hook \ 1 #f create-hook mouse-enter-listener-hook \ 1 #f create-hook mouse-enter-text-hook \ 2 #f create-hook mouse-leave-graph-hook \ 3 #f create-hook mouse-leave-label-hook \ 1 #f create-hook mouse-leave-listener-hook \ 1 #f create-hook mouse-leave-text-hook [then] require clm require clm-ins require examp require hooks require marks require extensions require env require mix require dsp require snd-xm require effects require bird.fsm *clm-search-list* file-pwd array-push to *clm-search-list* reset-all-hooks *with-test-motif* [if] lambda: <{ dpy e -- }> \ XGetErrorText's return code is '( id string ) dpy e Ferror_code nil 1024 FXGetErrorText { res } "Xlib error_code[%s]: %s" res fth-warning dpy e Frequest_code nil 1024 FXGetErrorText to res "Xlib request_code[%s]: %s" res fth-warning dpy e Fminor_code nil 1024 FXGetErrorText to res "Xlib minor_code[%s]: %s" res fth-warning ; FXSetErrorHandler drop lambda: <{ dpy -- }> "Xlib IO Error dpy: %S" #( dpy ) fth-error ; FXSetIOErrorHandler drop [then] : fneq-err ( r1 r2 err -- f ) -rot ( r1 r2 ) f- fabs f<= ; : fneq ( a b -- f ) 0.001 fneq-err ; : ffneq ( a b -- f ) 0.010 fneq-err ; : fffneq ( a b -- f ) 0.100 fneq-err ; : cneq-err ( c1 c2 err -- f ) { c1 c2 err } c1 real-ref c2 real-ref err fneq-err c1 image-ref c2 image-ref err fneq-err || ; : cneq ( a b -- f ) 0.001 cneq-err ; : fequal-err ( r1 r2 err -- f ) -rot ( r1 r2 ) f- fabs f> ; : fequal? ( a b -- f ) 0.001 fequal-err ; : any->vct ( obj ) { obj } obj vct? if obj else obj array? if obj vector->vct else #f then then ; : vequal-err ( v0 v1 err -- f ) { val0 val1 err } val0 any->vct { v0 } val1 any->vct { v1 } v0 v1 && v0 length v1 length = && if v0 vct-copy v1 vct-subtract! vct-peak err f<= else #f then ; : vequal? ( v0 v1 -- f ) 0.001 vequal-err ; : vvequal ( v0 v1 -- f ) 0.00002 vequal-err ; : vfequal ( v0 v1 -- f ) 0.01 vequal-err ; : vffequal ( v0 v1 -- f ) 0.1 vequal-err ; : vfffequal ( v0 v1 -- f ) 0.5 vequal-err ; <'> vequal? alias vequal : feql-err ( obj0 obj1 err -- f ) { obj0 obj1 err } obj0 object-length obj1 object-length = if #t ( flag ) obj0 each ( r0 ) obj1 i object-ref ( r1 ) err fneq-err if not ( toggle flag ) leave then end-each ( flag ) else #f then ; : feql ( obj0 obj1 -- f ) 0.001 feql-err ; : ffeql ( obj0 obj1 -- f ) 0.01 feql-err ; : fffeql ( obj0 obj1 -- f ) 0.1 feql-err ; : fveql ( v1 v2 idx -- f) { v1 v2 idx } #t ( flag ) v1 length v2 length min idx ?do v1 i object-ref v2 i object-ref fneq if not ( toggle flag ) leave then loop ; : list-equal? { obj1 obj2 -- f } obj1 list? obj2 list? && if #t ( flag ) obj1 each ( entry ) obj2 i list-ref object-equal? unless not ( toggle flag ) leave then end-each else #f then ; \ arity: #( req opt rest ) : arity-ok <{ proc args -- f }> proc proc? if proc proc-arity { args-lst } args-lst 0 array-ref { req } \ int args-lst 1 array-ref { opt } \ int args-lst 2 array-ref { rest } \ bool opt 0> if args req >= args req opt + <= && else args req = rest || then else #f then ; : set-arity-ok <{ proc args -- f }> proc set-xt args arity-ok ; : symbol-defined? ( sym -- f ) "defined? " swap symbol-name $+ string-eval ; : vector? { obj -- f } obj array? if \ car doesn't raise an error if length == 0 obj car number? else #f then ; : snd-test-vector? { obj -- f } obj vct? obj vector? || ; : snd-test-catch ( xt -- tag ) #t nil fth-catch { tag } stack-reset tag ; : snd-test-format { sndfmt res req fmt args -- str } sndfmt #( res req ) string-format { str } fmt empty? if str else fmt args string-format ": " $+ str $+ then ; : snd-format { res req op fmt args -- str } req snd-test-vector? if mus-array-print-length { old-alen } print-length { old-vlen } *info-array-print-length* set-mus-array-print-length drop *info-array-print-length* set-print-length drop "res " op $+ " req?\n\\ => res %S\n\\ => req %S" $+ res req fmt args snd-test-format ( str ) old-alen set-mus-array-print-length drop old-vlen set-print-length drop ( str ) else "res %S " op $+ " req %S?" $+ res req fmt args snd-test-format ( str ) then ; : snd-test-equal? { res req -- f } res req req float? if fequal? else req snd-test-vector? if vequal? else equal? then then ; : (snd-test-neq) { res req fmt args lno -- } res req snd-test-equal? unless res req "!=" fmt args snd-format { str } "\\ [%d] %s\n" #( lno str ) fth-print then ; : (snd-test-eq) { res req fmt args lno -- } res req snd-test-equal? if res req "==" fmt args snd-format { str } "\\ [%d] %s\n" #( lno str ) fth-print then ; : (snd-test-any-neq) { res req func fmt args lno -- } res req func execute unless res req "!=" fmt args snd-format { str } "\\ [%d] %s\n" #( lno str ) fth-print then ; : (snd-test-any-eq) { res req func fmt args lno -- } res req func execute if res req "==" fmt args snd-format { str } "\\ [%d] %s\n" #( lno str ) fth-print then ; : snd-test-neq ( res req fmt args -- ) postpone *lineno* postpone (snd-test-neq) ; immediate : snd-test-eq ( res req fmt args -- ) postpone *lineno* postpone (snd-test-eq) ; immediate \ res req <'> ffeql "more info" #() snd-test-any-neq : snd-test-any-neq ( res req func fmt args -- ) postpone *lineno* postpone (snd-test-any-neq) ; immediate \ res req <'> ffeql "more info" #() snd-test-any-eq : snd-test-any-eq ( res req func fmt args -- ) postpone *lineno* postpone (snd-test-any-eq) ; immediate : check-file-name { name -- fsnd } name file-exists? if name else sf-dir name $+ then ; 1 0 0 make-color constant safe-color : make-color-with-catch { c1 c2 c3 -- color } c1 c2 c3 <'> make-color 'no-such-color #t fth-catch if stack-reset safe-color then ; : reset-almost-all-hooks ( -- ) reset-all-hooks my-snd-error-hook proc? if snd-error-hook my-snd-error-hook add-hook! then my-mus-error-hook proc? if mus-error-hook my-mus-error-hook add-hook! then ; *with-test-nogui* [if] <'> noop alias dismiss-all-dialogs [else] : dismiss-all-dialogs ( -- ) nil nil { dialog d } dialog-widgets each to dialog dialog if dialog 0 array-ref symbol? if dialog is-managed? if dialog hide-widget drop then else \ not widget? dialog each to d d 0 array-ref symbol? if d is-managed? if d hide-widget drop then then end-each then \ widget? then \ dialog end-each ; [then] #f value overall-start-time #() value test-numbers : run-fth-test ( xt -- ) { xt } xt xt->name { name } name 0 2 string-substring { num } num string->number to num test-numbers num array-member? if name #f snd-test-message stack-reset gc-run make-timer { tm } xt execute tm stop-timer stack-reset sounds if "open sounds: %s" #( #t short-file-name ) snd-test-message sounds each ( snd ) close-sound drop end-each then #f set-ask-about-unsaved-edits drop #f set-remember-sound-state drop "%s: %s\n\\ " #( name tm ) snd-test-message then ; : start-snd-test ( -- ) *with-test-motif* if "motif" else *with-test-gtk* if "gtk" else *with-test-nogui* if #t set-with-mix-tags drop "nogui" else "unknown" then then then { kind } stack-reset "test.snd" file-exists? if "test.snd" 0o644 file-chmod then "=== Snd version: %s (snd-%s)" #( snd-version kind ) snd-test-message "=== Fth version: %s" #( fth-version ) snd-test-message "" #f snd-test-message date #f snd-test-message "" #f snd-test-message default-file-buffer-size set-mus-file-buffer-size to *clm-file-buffer-size* #f set-with-background-processes drop 600 set-window-x drop 10 set-window-y drop #t set-show-listener drop reset-almost-all-hooks 22050 set-mus-srate f>s to *clm-srate* stack-reset make-timer to overall-start-time ; : finish-snd-test ( -- ) overall-start-time stop-timer .stack stack-reset regions each ( r ) forget-region drop end-each sounds if stop-playing drop then reset-almost-all-hooks #f set-ask-about-unsaved-edits drop #f set-remember-sound-state drop "all done!" #f snd-test-message "" #f snd-test-message "summary: %s" #( overall-start-time ) snd-test-message 0 nil nil { file-count path file } #( original-save-dir original-temp-dir "/tmp" ) each to path path file-directory? if path file-dir each to file /snd_/ file regexp-match if file file-delete 1 +to file-count then end-each then end-each "" #f snd-test-message "%d files deleted" #( file-count ) snd-test-message "" #f snd-test-message "test.snd" file-exists? if "test.snd" 0o644 file-chmod then #( "aaa.eps" "envs.save" "fmv.snd" "fmv.wav" "fmv0.snd" "fmv1.snd" "fmv2.snd" "fmv3.snd" "fmv4.reverb" "fmv4.snd" "hiho.marks" "hiho.snd" "hiho.snd" "hiho.tmp" "hiho.wave" "ho" "new.snd" "oboe.marks" "obtest.snd.stereo" "remembered-oboe.snd.fs" "saved-snd.fs" "snd.eps" "test-1.snd" "test-2.snd" "test-macros.scm" "test.aiff" "test.data" "test.rev" "test.reverb" "test.snd" "test.snd.snd" "test.wav" "test.xpm" "test2.snd" "test3.snd" "tmp.snd" "with-mix.snd" "1" "gtk-errors" "accelmap" ) each ( file ) file-delete end-each #( "mus10.snd.snd" "ieee-text-16.snd.snd" "trumps22.adp.snd" "oki.wav.snd" "nasahal.avi.snd" "hcom-16.snd.snd" "ce-c3.w02.snd" "oboe.g723_24.snd" "oboe.g723_40.snd" "oboe.g721.snd" "wood.sds.snd" "o2_dvi.wave.snd" "nist-shortpack.wav.snd" "bad_data_format.snd.snd" ) each ( file ) sf-dir swap $+ file-delete end-each #t set-show-listener drop "test-forth.output" save-listener drop original-prompt set-listener-prompt drop ; SIGINT lambda: { sig -- } stack-reset backtrace "" #f snd-test-message "Interrupt received. Clean up %S." #( *filename* #f file-basename ) snd-test-message "" #f snd-test-message finish-snd-test 0 snd-exit drop ; signal drop \ snd-test.scm translations \ ---------------- test 00: constants ---------------- *with-test-motif* [if] "6x12" [else] *with-test-gtk* [if] "Sans 8" [else] "9x15" [then] [then] constant tiny-font-string *with-test-motif* [if] "9x15" [else] *with-test-gtk* [if] "Monospace 10" [else] "6x12" [then] [then] constant tiny-font-set-string \ XXX: temp-dir, save-dir, ladspa-dir, peak-env-dir \ These variables default to NULL (snd.c/snd-0.h). \ snd-test.scm checks for #f \ snd-test.fs checks for "" : 00-constants ( -- ) sounds { snds } undef undef mixes { mxs } undef undef undef marks { mks } regions { rgns } snds mxs || mks || rgns || if "start up sounds: %s, mixes: %s, marks: %s, regions: %s?" #( snds mxs mks rgns ) snd-display then \ nil nil nil nil { vals sym req res } #( #( <'> enved-amplitude 0 ) #( <'> bartlett-window 4 ) #( <'> bartlett-hann-window 21 ) #( <'> blackman2-window 6 ) #( <'> blackman3-window 7 ) #( <'> blackman4-window 8 ) #( <'> blackman5-window 24 ) #( <'> blackman6-window 25 ) #( <'> blackman7-window 26 ) #( <'> blackman8-window 27 ) #( <'> blackman9-window 28 ) #( <'> blackman10-window 29 ) #( <'> bohman-window 22 ) #( <'> cauchy-window 12 ) #( <'> mlt-sine-window 33 ) #( <'> papoulis-window 34 ) #( <'> dpss-window 35 ) #( <'> sinc-window 36 ) #( <'> channels-combined 1 ) #( <'> channels-separate 0 ) #( <'> channels-superimposed 2 ) #( <'> connes-window 18 ) #( <'> cursor-in-middle 3 ) #( <'> cursor-in-view 0 ) #( <'> cursor-on-left 1 ) #( <'> cursor-on-right 2 ) #( <'> dolph-chebyshev-window 16 ) #( <'> exponential-window 9 ) #( <'> flat-top-window 23 ) #( <'> sync-none 0 ) #( <'> sync-all 1 ) #( <'> sync-by-sound 2 ) #( <'> zoom-focus-active 2 ) #( <'> zoom-focus-left 0 ) #( <'> zoom-focus-middle 3 ) #( <'> zoom-focus-right 1 ) #( <'> gaussian-window 14 ) #( <'> graph-dots 1 ) #( <'> graph-dots-and-lines 3 ) #( <'> graph-filled 2 ) #( <'> graph-lines 0 ) #( <'> graph-lollipops 4 ) #( <'> hamming-window 5 ) #( <'> hann-window 1 ) #( <'> hann-poisson-window 17 ) #( <'> kaiser-window 11 ) #( <'> keyboard-no-action 4 ) #( <'> graph-once 0 ) #( <'> parzen-window 3 ) #( <'> poisson-window 13 ) #( <'> rectangular-window 0 ) #( <'> riemann-window 10 ) #( <'> rv2-window 30 ) #( <'> rv3-window 31 ) #( <'> rv4-window 32 ) #( <'> samaraki-window 19 ) #( <'> ultraspherical-window 20 ) #( <'> graph-as-sonogram 1 ) #( <'> graph-as-spectrogram 2 ) #( <'> graph-once 0 ) #( <'> graph-as-wavogram 3 ) #( <'> enved-spectrum 1 ) #( <'> speed-control-as-float 0 ) #( <'> speed-control-as-ratio 1 ) #( <'> speed-control-as-semitone 2 ) #( <'> enved-srate 2 ) #( <'> tukey-window 15 ) #( <'> welch-window 2 ) #( <'> cursor-cross 0 ) #( <'> cursor-line 1 ) #( <'> dont-normalize 0 ) #( <'> envelope-linear 0 ) #( <'> envelope-exponential 1 ) #( <'> normalize-by-channel 1 ) #( <'> normalize-by-sound 2 ) #( <'> normalize-globally 3 ) #( <'> x-axis-in-samples 1 ) #( <'> x-axis-in-beats 3 ) #( <'> x-axis-in-measures 4 ) #( <'> x-axis-in-seconds 0 ) #( <'> x-axis-as-clock 5 ) #( <'> x-axis-as-percentage 2 ) #( <'> enved-add-point 0 ) #( <'> enved-delete-point 1 ) #( <'> enved-move-point 2 ) #( <'> time-graph 0 ) #( <'> transform-graph 1 ) #( <'> lisp-graph 2 ) #( <'> copy-context 0 ) #( <'> cursor-context 3 ) #( <'> selection-context 2 ) #( <'> mark-context 4 ) #( <'> show-no-axes 0 ) #( <'> show-all-axes 1 ) #( <'> show-x-axis 2 ) #( <'> show-all-axes-unlabelled 3 ) #( <'> show-x-axis-unlabelled 4 ) #( <'> show-bare-x-axis 5 ) \ sndlib constants #( <'> mus-unknown-header 0 ) #( <'> mus-next 1 ) #( <'> mus-aifc 2 ) #( <'> mus-riff 3 ) #( <'> mus-nist 6 ) #( <'> mus-raw 12 ) #( <'> mus-ircam 15 ) #( <'> mus-aiff 49 ) #( <'> mus-bicsf 5 ) #( <'> mus-voc 10 ) #( <'> mus-svx 9 ) #( <'> mus-soundfont 26 ) #( <'> mus-rf64 4 ) #( <'> mus-caff 60 ) \ #( <'> mus-interp-none 0 ) #( <'> mus-interp-linear 1 ) #( <'> mus-interp-sinusoidal 2 ) #( <'> mus-interp-all-pass 3 ) #( <'> mus-interp-lagrange 4 ) #( <'> mus-interp-bezier 5 ) #( <'> mus-interp-hermite 6 ) \ #( <'> mus-chebyshev-first-kind 1 ) #( <'> mus-chebyshev-second-kind 2 ) \ #( <'> mus-unknown-sample 0 ) #( <'> mus-bshort 1 ) #( <'> mus-lshort 10 ) #( <'> mus-mulaw 2 ) #( <'> mus-alaw 6 ) #( <'> mus-byte 3 ) #( <'> mus-ubyte 7 ) #( <'> mus-bfloat 4 ) #( <'> mus-lfloat 12 ) #( <'> mus-bint 5 ) #( <'> mus-lint 11 ) #( <'> mus-bintn 17 ) #( <'> mus-lintn 18 ) #( <'> mus-b24int 8 ) #( <'> mus-l24int 16 ) #( <'> mus-bdouble 9 ) #( <'> mus-ldouble 13 ) #( <'> mus-ubshort 14 ) #( <'> mus-ulshort 15 ) #( <'> mus-bfloat-unscaled 19 ) #( <'> mus-lfloat-unscaled 20 ) #( <'> mus-bdouble-unscaled 21 ) #( <'> mus-ldouble-unscaled 22 ) ) { consts } consts each to vals vals 0 array-ref to sym vals 1 array-ref to req sym execute ( res ) req "%s" #( sym ) snd-test-neq end-each \ temp-dir { old-dir } #f set-temp-dir drop #( #( <'> region-graph-style graph-lines ) #( <'> ask-about-unsaved-edits #f ) #( <'> show-full-duration #f ) #( <'> show-full-range #f ) #( <'> initial-beg 0.0 ) #( <'> initial-dur 0.1 ) #( <'> ask-before-overwrite #f ) #( <'> auto-resize #t ) #( <'> auto-update #f ) #( <'> channel-style 1 ) #( <'> color-cutoff 0.003 ) #( <'> color-inverted #t ) #( <'> color-scale 1.0 ) #( <'> auto-update-interval 60.0 ) #( <'> cursor-update-interval 0.05 ) #( <'> cursor-location-offset 0 ) #( <'> dac-combines-channels #t ) #( <'> dac-size 256 ) #( <'> clipping #f ) #( <'> default-output-chans 1 ) #( <'> default-output-sample-type mus-lfloat ) #( <'> default-output-srate 44100 ) #( <'> default-output-header-type mus-next ) #( <'> dot-size 1 ) #( <'> cursor-size 15 ) #( <'> cursor-style cursor-cross ) #( <'> tracking-cursor-style cursor-line ) #( <'> enved-base 1.0 ) #( <'> enved-clip? #t ) #( <'> enved-filter #t ) #( <'> enved-filter-order 40 ) #( <'> enved-in-dB #f ) #( <'> enved-style envelope-linear ) #( <'> enved-power 3.0 ) #( <'> enved-target 0 ) #( <'> enved-wave? #f ) #( <'> enved-envelope nil ) #( <'> eps-file "snd.eps" ) #( <'> eps-bottom-margin 0.0 ) #( <'> eps-left-margin 0.0 ) #( <'> eps-size 1.0 ) #( <'> fft-window-alpha 0.0 ) #( <'> fft-window-beta 0.0 ) #( <'> fft-log-frequency #f ) #( <'> fft-log-magnitude #f ) #( <'> fft-with-phases #f ) #( <'> transform-size 512 ) #( <'> transform-graph-type graph-once ) #( <'> fft-window 6 ) #( <'> graph-cursor 34 ) #( <'> graph-style graph-lines ) #( <'> graphs-horizontal #t ) #( <'> html-dir "." ) #( <'> html-program "firefox" ) #( <'> just-sounds #t ) #( <'> listener-prompt ">" ) #( <'> max-transform-peaks 100 ) #( <'> max-regions 16 ) #( <'> min-dB -60.0 ) #( <'> log-freq-start 32.0 ) #( <'> selection-creates-region #t ) #( <'> transform-normalization normalize-by-channel ) #( <'> print-length 12 ) #( <'> play-arrow-size 10 ) #( <'> save-state-file "saved-snd.fs" ) #( <'> show-axes 1 ) #( <'> show-transform-peaks #f ) #( <'> show-indices #f ) #( <'> show-marks #t ) #( <'> show-mix-waveforms #t ) #( <'> show-selection-transform #f ) #( <'> show-y-zero #f ) #( <'> show-grid #f ) #( <'> grid-density 1.0 ) #( <'> show-sonogram-cursor #f ) #( <'> sinc-width 10 ) #( <'> spectrum-end 1.0 ) #( <'> spectro-hop 4 ) #( <'> spectrum-start 0.0 ) #( <'> spectro-x-angle *with-test-gl* if 300.0 else 90.0 then ) #( <'> spectro-x-scale *with-test-gl* if 1.5 else 1.0 then ) #( <'> spectro-y-angle *with-test-gl* if 320.0 else 0.0 then ) #( <'> spectro-y-scale 1.0 ) #( <'> spectro-z-angle *with-test-gl* if 0.0 else 358.0 then ) #( <'> spectro-z-scale *with-test-gl* if 1.0 else 0.1 then ) #( <'> temp-dir "" ) #( <'> ladspa-dir "" ) #( <'> peak-env-dir "" ) #( <'> tiny-font tiny-font-string ) #( <'> transform-type fourier-transform ) #( <'> with-file-monitor #t ) #( <'> clm-table-size 512 ) #( <'> clm-default-frequency 0.0 ) #( <'> with-verbose-cursor #f ) #( <'> with-inset-graph #f ) #( <'> with-interrupts #t ) #( <'> remember-sound-state #f ) #( <'> with-smpte-label #f ) #( <'> with-toolbar *with-test-gtk* if #t else #f then ) #( <'> with-tooltips #t ) #( <'> with-menu-icons #f ) #( <'> save-as-dialog-src #f ) #( <'> save-as-dialog-auto-comment #f ) #( <'> with-pointer-focus #f ) #( <'> wavelet-type 0 ) #( <'> time-graph-type graph-once ) #( <'> wavo-hop 3 ) #( <'> wavo-trace 64 ) #( <'> x-axis-style 0 ) #( <'> beats-per-minute 60.0 ) #( <'> beats-per-measure 4 ) #( <'> zero-pad 0 ) #( <'> zoom-focus-style 2 ) #( <'> sync-style sync-by-sound ) #( <'> mix-waveform-height 20 ) #( <'> mix-tag-width 6 ) #( <'> mix-tag-height 14 ) #( <'> mark-tag-width 10 ) #( <'> mark-tag-height 4 ) ) { vars } vars each to vals vals 0 array-ref to sym vals 1 array-ref to req sym execute ( val ) sym set-execute ( res ) req "set-%s" #( sym ) snd-test-neq end-each old-dir set-temp-dir drop \ -123 set-max-transform-peaks drop -123 set-zero-pad drop max-transform-peaks set-max-transform-peaks 100 "set-max-transform-peaks" #() snd-test-neq zero-pad set-zero-pad 0 "set-zero-pad" #() snd-test-neq #t #t zero-pad nil "#t #t zero-pad" #() snd-test-neq *with-test-motif* if #( <'> axis-label-font <'> axis-numbers-font <'> tiny-font <'> peaks-font <'> bold-peaks-font ) { fonts } fonts each to sym sym execute to req "8x123" sym set-execute ( res ) req "set-%s to bogus value" #( sym ) snd-test-neq end-each then #f set-ask-about-unsaved-edits drop #f set-remember-sound-state drop ; \ ---------------- test 01: defaults ---------------- hot-colormap constant *good-colormap* black-and-white-colormap constant *better-colormap* : 01-defaults ( -- ) nil { res } *with-test-gui* if *good-colormap* colormap? unless #f to *good-colormap* 21 1 do i integer->colormap to res res colormap? if res to *good-colormap* leave then loop then *better-colormap* colormap? unless #f to *better-colormap* 21 *good-colormap* colormap->integer do i integer->colormap to res res colormap? if res to *better-colormap* leave then loop then then \ temp-dir { old-dir } #f set-temp-dir drop #( #( <'> ask-about-unsaved-edits #f ) #( <'> ask-before-overwrite #f ) #( <'> auto-resize #t ) #( <'> auto-update #f ) #( <'> auto-update-interval 60.0 ) #( <'> beats-per-measure 4 ) #( <'> beats-per-minute 60.0 ) #( <'> channel-style 1 ) #( <'> clipping #f ) #( <'> clm-table-size 512 ) #( <'> clm-default-frequency 0.0 ) #( <'> color-cutoff 0.003 ) #( <'> color-inverted #t ) #( <'> color-scale 1.0 ) #( <'> colormap *good-colormap* ) #( <'> contrast-control-amp 1.0 ) #( <'> with-tracking-cursor #f ) #( <'> cursor-location-offset 0 ) #( <'> cursor-size 15 ) #( <'> cursor-style cursor-cross ) #( <'> cursor-update-interval 0.05 ) #( <'> dac-combines-channels #t ) #( <'> dac-size 256 ) #( <'> default-output-chans 1 ) #( <'> default-output-sample-type mus-lfloat ) #( <'> default-output-header-type mus-next ) #( <'> default-output-srate 44100 ) #( <'> dot-size 1 ) #( <'> enved-base 1.0 ) #( <'> enved-clip? #t ) #( <'> enved-envelope nil ) #( <'> enved-filter #t ) #( <'> enved-filter-order 40 ) #( <'> enved-in-dB #f ) #( <'> enved-power 3.0 ) #( <'> enved-style envelope-linear ) #( <'> enved-target 0 ) #( <'> enved-wave? #f ) #( <'> eps-bottom-margin 0.0 ) #( <'> eps-file "snd.eps" ) #( <'> eps-left-margin 0.0 ) #( <'> eps-size 1.0 ) #( <'> expand-control-hop 0.05 ) #( <'> expand-control-jitter 0.1 ) #( <'> expand-control-length 0.15 ) #( <'> expand-control-ramp 0.4 ) #( <'> fft-log-frequency #f ) #( <'> fft-log-magnitude #f ) #( <'> fft-with-phases #f ) #( <'> fft-window 6 ) #( <'> fft-window-alpha 0.0 ) #( <'> fft-window-beta 0.0 ) #( <'> filter-control-in-dB #f ) #( <'> filter-control-in-hz #f ) #( <'> filter-control-order 20 ) #( <'> graph-cursor 34 ) #( <'> graph-style graph-lines ) #( <'> graphs-horizontal #t ) #( <'> grid-density 1.0 ) #( <'> html-dir "." ) #( <'> html-program "firefox" ) #( <'> initial-beg 0.0 ) #( <'> initial-dur 0.1 ) #( <'> just-sounds #t ) #( <'> ladspa-dir "" ) #( <'> peak-env-dir "" ) #( <'> listener-prompt ">" ) #( <'> log-freq-start 32.0 ) #( <'> mark-tag-height 4 ) #( <'> mark-tag-width 10 ) #( <'> max-regions 16 ) #( <'> max-transform-peaks 100 ) #( <'> min-dB -60.0 ) #( <'> mix-tag-height 14 ) #( <'> mix-tag-width 6 ) #( <'> mix-waveform-height 20 ) #( <'> mus-array-print-length 8 ) #( <'> mus-clipping #f ) #( <'> mus-float-equal-fudge-factor 0.0000001 ) #( <'> play-arrow-size 10 ) #( <'> print-length 12 ) #( <'> region-graph-style graph-lines ) #( <'> remember-sound-state #f ) #( <'> reverb-control-feedback 1.09 ) #( <'> reverb-control-lowpass 0.7 ) #( <'> save-as-dialog-auto-comment #f ) #( <'> save-as-dialog-src #f ) #( <'> save-state-file "saved-snd.fs" ) #( <'> selection-creates-region #t ) #( <'> show-axes 1 ) #( <'> show-controls #f ) #( <'> show-full-duration #f ) #( <'> show-full-range #f ) #( <'> show-grid #f ) #( <'> show-indices #f ) #( <'> show-marks #t ) #( <'> show-mix-waveforms #t ) #( <'> show-selection-transform #f ) #( <'> show-sonogram-cursor #f ) #( <'> show-transform-peaks #f ) #( <'> show-y-zero #f ) #( <'> sinc-width 10 ) #( <'> spectrum-end 1.0 ) #( <'> spectro-hop 4 ) #( <'> spectrum-start 0.0 ) #( <'> spectro-x-angle *with-test-gl* if 300.0 else 90.0 then ) #( <'> spectro-x-scale *with-test-gl* if 1.5 else 1.0 then ) #( <'> spectro-y-angle *with-test-gl* if 320.0 else 0.0 then ) #( <'> spectro-y-scale 1.0 ) #( <'> spectro-z-angle *with-test-gl* if 0.0 else 358.0 then ) #( <'> spectro-z-scale *with-test-gl* if 1.0 else 0.1 then ) #( <'> sync-style sync-by-sound ) #( <'> temp-dir "" ) #( <'> time-graph-type graph-once ) #( <'> tiny-font tiny-font-string ) #( <'> tracking-cursor-style cursor-line ) #( <'> transform-graph-type graph-once ) #( <'> transform-normalization normalize-by-channel ) #( <'> transform-size 512 ) #( <'> transform-type fourier-transform ) #( <'> wavelet-type 0 ) #( <'> wavo-hop 3 ) #( <'> wavo-trace 64 ) #( <'> with-mix-tags #t ) #( <'> with-relative-panes #t ) #( <'> with-tracking-cursor #f ) #( <'> with-verbose-cursor #f ) #( <'> with-inset-graph #f ) #( <'> with-interrupts #t ) #( <'> with-smpte-label #f ) #( <'> with-toolbar *with-test-gtk* if #t else #f then ) #( <'> with-tooltips #t ) #( <'> with-menu-icons #f ) #( <'> with-pointer-focus #f ) #( <'> x-axis-style 0 ) #( <'> zero-pad 0 ) #( <'> zoom-focus-style 2 ) ) { procs } nil nil nil nil { vals sym req res } procs each to vals vals 0 array-ref to sym vals 1 array-ref to req sym execute ( res ) req "%s" #( sym ) snd-test-neq end-each old-dir set-temp-dir drop \ without-errors #( <'> amp-control <'> contrast-control <'> contrast-control? <'> expand-control <'> expand-control? <'> filter-control-coeffs <'> filter-control-envelope <'> filter-control? <'> lisp-graph? <'> read-only <'> reverb-control-length <'> reverb-control-scale <'> reverb-control? <'> speed-control <'> sync <'> time-graph? <'> transform-graph? ) to procs 'no-such-sound to req procs each to sym sym snd-test-catch car 'no-such-sound "%s" #( sym ) snd-test-neq end-each \ 1 array-ref #( #( <'> amp-control-bounds 8.0 ) #( <'> contrast-control-bounds 10.0 ) #( <'> expand-control-bounds 20.0 ) #( <'> reverb-control-length-bounds 5.0 ) #( <'> reverb-control-scale-bounds 4.0 ) #( <'> speed-control-bounds 20.0 ) ) to procs procs each to vals vals 0 array-ref to sym vals 1 array-ref to req sym execute 1 array-ref ( res ) req "%s" #( sym ) snd-test-neq end-each \ *snd-opened-sound* if "*snd-opened-sound*: %S" #( *snd-opened-sound* ) snd-display then #f set-ask-about-unsaved-edits drop #f set-remember-sound-state drop ; \ ---------------- test 02: headers ---------------- : test-header-check { res req lno name info -- } res req "%s: %s" #( name info ) lno (snd-test-neq) ; : (test-headers-with-loop) ( name chns sr dur typ frm loop-s loop-e lno -- ) { name chns sr dur typ frm loop-start loop-end lno -- } name check-file-name { file } file file-exists? if file mus-sound-chans { fchns } file mus-sound-srate { fsr } file mus-sound-duration { fdur } file mus-sound-sample-type { ffrm } file mus-sound-header-type { ftyp } file mus-sound-framples { fframples } file mus-sound-samples { fsamps } file mus-sound-length { flen } fchns chns lno name "chans" test-header-check fsr sr lno name "srate" test-header-check fdur dur lno name "duration" test-header-check file mus-sound-datum-size fdur f* fsr f* fchns f* floor f>s { fsize } ffrm mus-unknown-sample <> ftyp 27 <> && if flen 1+ fsize < if flen 1+ fsize lno name "length" test-header-check then then fframples fsr f/ fdur lno name "framples" test-header-check fframples fsamps fchns f/ f- floor fabs f>s { res } res 1 > if res 1 lno name "samples" test-header-check then ftyp mus-header-type-name typ lno name "type" test-header-check ffrm mus-sample-type-name frm lno name "format" test-header-check file mus-sound-loop-info { lst } loop-start if lst nil? if "[%d] %s loop info empty?" #( lno name ) snd-test-message else lst car loop-start lno name "loop-start" test-header-check lst cadr loop-end lno name "loop-end" test-header-check then else lst empty? unless "[%d] %s thinks it has loop info: %s?" #( lno name lst ) snd-test-message then then else \ not file-exists? *fth-debug* if "[%d] %s missing?" #( lno file ) snd-test-message then then \ file-exists? ; : test-headers-with-loop ( name chns sr dur typ frm loop-start loop-end -- ) postpone *lineno* postpone (test-headers-with-loop) ; immediate : test-headers ( name chns sr dur typ frm -- ) postpone #f postpone #f postpone *lineno* postpone (test-headers-with-loop) ; immediate : 02-headers ( -- ) "5_secs.aiff" 1 44100 5.303107 "AIFF" "big endian short (16 bits)" test-headers "8svx-8.snd" 1 22050 1.88766443729401 "SVX8" "signed byte (8 bits)" test-headers "Fnonull.aif" 1 8000 0.00112499995157123 "AIFC" "mulaw (8 bits)" test-headers "Pmiscck.aif" 1 8000 0.00112499995157123 "AIFC" "mulaw (8 bits)" test-headers "Pmiscck.wav" 1 8000 0.00112499995157123 "RIFF" "mulaw (8 bits)" test-headers "Poffset.aif" 1 8000 0.00112499995157123 "AIFC" "mulaw (8 bits)" test-headers "Porder.aif" 1 8000 0.00112499995157123 "AIFC" "mulaw (8 bits)" test-headers "Ptjunk.aif" 1 8000 0.00112499995157123 "AIFC" "mulaw (8 bits)" test-headers "Ptjunk.wav" 1 8000 0.00112499995157123 "RIFF" "mulaw (8 bits)" test-headers "SINE24-S.WAV" 2 44100 2.0 "RIFF" "little endian int (24 bits)" test-headers "a1.asf" 1 16000 3.736562 "asf" "unknown" test-headers "a2.asf" 1 8000 4.630625 "asf" "unknown" test-headers "addf8.afsp" 1 8000 2.9760000705719 "Sun/Next" "big endian short (16 bits)" test-headers "addf8.d" 1 8000 2.9760000705719 "SPPACK" "big endian short (16 bits)" test-headers "addf8.dwd" 1 8000 2.976000071 "DiamondWare" "little endian short (16 bits)" test-headers "addf8.nh" 2 44100 0.269931972 "raw (no header)" "big endian short (16 bits)" test-headers "addf8.sd" 1 8000 2.9760000705719 "ESPS" "big endian short (16 bits)" test-headers "addf8.sf_mipseb" 1 8000 2.9760000705719 "IRCAM" "big endian short (16 bits)" test-headers "addf8.sf_sun" 1 8000 2.9760000705719 "IRCAM" "big endian short (16 bits)" test-headers "addf8.sf_vax_b" 1 8000 2.9760000705719 "IRCAM" "big endian short (16 bits)" test-headers "addf8.wav" 1 8000 2.9760000705719 "RIFF" "little endian short (16 bits)" test-headers "aebass.krz" 1 44100 3.0 "Kurzweil 2000" "big endian short (16 bits)" test-headers "aiff-16.snd" 2 44100 0.746666669845581 "AIFF" "big endian short (16 bits)" test-headers "aiff-8.snd" 2 44100 0.746666669845581 "AIFF" "signed byte (8 bits)" test-headers "alaw.aifc" 1 44100 0.0367800444364548 "AIFC" "alaw (8 bits)" test-headers "alaw.wav" 1 11025 8.70666694641113 "RIFF" "alaw (8 bits)" test-headers "astor_basia.mp2" 2 44100 1.022 "raw (no header)" "big endian short (16 bits)" test-headers "c.asf" 1 8000 21.368126 "asf" "unknown" test-headers "ce-c3.w02" 1 33000 3.88848495483398 "TX-16W" "unknown" test-headers "ce-c4.w03" 1 33000 2.91618180274963 "TX-16W" "unknown" test-headers "ce-d2.w01" 1 33000 3.46439385414124 "TX-16W" "unknown" test-headers "clbonef.wav" 1 22050 2.57832193374634 "RIFF" "little endian float (32 bits)" test-headers "cranker.krz" 1 44100 3.48267579 "Kurzweil 2000" "big endian short (16 bits)" test-headers "d40130.aif" 1 10000 0.100000001490116 "AIFF" "big endian short (16 bits)" test-headers "d40130.au" 1 10000 0.100000001490116 "Sun/Next" "big endian short (16 bits)" test-headers "d40130.dsf" 1 8000 0.125 "Delusion" "little endian short (16 bits)" test-headers "d40130.fsm" 1 8000 0.12524999678 "Farandole" "little endian short (16 bits)" test-headers "d40130.iff" 1 10000 0.100000001490116 "SVX8" "signed byte (8 bits)" test-headers "d40130.pat" 1 10000 0.100000001490116 "Gravis Ultrasound patch" "little endian short (16 bits)" test-headers "d40130.sds" 1 10000 0.100000001490116 "MIDI sample dump" "unknown" test-headers "d40130.sdx" 1 10000 0.100000001490116 "Sample dump" "unsigned little endian short (16 bits)" test-headers "d40130.sf" 1 10000 0.100000001490116 "IRCAM" "little endian short (16 bits)" test-headers "d40130.smp" 1 8000 0.125 "SMP" "little endian short (16 bits)" test-headers "d40130.sou" 1 8000 0.125 "SBStudioII" "little endian short (16 bits)" test-headers "d40130.st3" 1 8000 0.125 "Digiplayer ST3" "unsigned little endian short (16 bits)" test-headers "d40130.uwf" 1 8000 0.1252499 "Ultratracker" "little endian short (16 bits)" test-headers "d40130.voc" 1 10000 0.100100003182888 "VOC" "unsigned byte (8 bits)" test-headers "d40130.w00" 1 16000 0.0625 "TX-16W" "unknown" test-headers "d40130.wav" 1 10000 0.100000001490116 "RIFF" "little endian short (16 bits)" test-headers "d43.wav" 1 10000 0.100000001490116 "RIFF" "little endian short (16 bits)" test-headers "digit0v0.aiff" 1 8000 0.560000002384186 "AIFC" "big endian short (16 bits)" test-headers "esps-16.snd" 1 8000 3.09737491607666 "ESPS" "big endian short (16 bits)" test-headers "forest.aiff" 2 44100 3.907143 "AIFF" "big endian short (16 bits)" 24981 144332 test-headers-with-loop "g721.au" 1 11025 4.35328817367554 "Sun/Next" "unknown" test-headers "g722.aifc" 1 44100 0.0184353739023209 "AIFC" "unknown" test-headers "gong.wve" 1 8000 3.96799993515015 "PSION" "alaw (8 bits)" test-headers "gsm610.wav" 1 11025 1.7687075138092 "RIFF" "unknown" test-headers "inrs-16.snd" 1 8000 2.46399998664856 "INRS" "little endian short (16 bits)" test-headers "kirk.wve" 1 8000 1.40799999237061 "PSION" "alaw (8 bits)" test-headers "loop.aiff" 1 44100 0.0367120169103146 "AIFC" "big endian short (16 bits)" 12 23 test-headers-with-loop "m.asf" 1 8000 64.964622 "asf" "unknown" test-headers "mary-sun4.sig" 1 8000 4.47612476348877 "Comdisco SPW signal" "big endian double (64 bits)" test-headers "mocksong.wav" 1 11025 7.869569301605 "RIFF" "little endian short (16 bits)" test-headers "mono24.wav" 1 22050 1.98997735977173 "RIFF" "little endian int (24 bits)" test-headers "msadpcm.wav" 1 11025 4.43501138687134 "RIFF" "unknown" test-headers "n8.snd" 1 44100 0.0367800444364548 "Sun/Next" "signed byte (8 bits)" test-headers "nasahal.aif" 1 11025 9.89841270446777 "AIFF" "signed byte (8 bits)" test-headers "nasahal.avi" 1 11025 10.432744 "AVI" "little endian short (16 bits)" test-headers "nasahal.dig" 1 11025 9.8984 "Sound Designer 1" "big endian short (16 bits)" test-headers "nasahal.ivc" 2 44100 0.449 "raw (no header)" "big endian short (16 bits)" test-headers "nasahal.pat" 1 11025 3.95410442352295 "Gravis Ultrasound patch" "unsigned byte (8 bits)" test-headers "nasahal.snd" 1 11025 9.89841270446777 "SNDT" "unsigned byte (8 bits)" test-headers "nasahal.svx" 1 11025 9.89841270446777 "SVX8" "signed byte (8 bits)" test-headers "nasahal.v8" 1 8000 13.6412496566772 "Covox V8" "unsigned byte (8 bits)" test-headers "nasahal.voc" 1 11025 9.89941024780273 "VOC" "unsigned byte (8 bits)" test-headers "nasahal.vox" 2 44100 0.22444 "raw (no header)" "big endian short (16 bits)" test-headers "nasahal8.wav" 1 11025 9.89841270446777 "RIFF" "unsigned byte (8 bits)" test-headers "nasahalad.smp" 1 11025 4.94920635223389 "Goldwave sample" "little endian short (16 bits)" test-headers "next-16.snd" 1 22050 1.00004529953003 "Sun/Next" "big endian short (16 bits)" test-headers "next-8.snd" 1 22050 0.226757362484932 "Sun/Next" "signed byte (8 bits)" test-headers "next-dbl.snd" 1 22050 0.226757362484932 "Sun/Next" "big endian double (64 bits)" test-headers "oboe.ldbl" 1 22050 2.30512475967407 "RIFF" "little endian double (64 bits)" test-headers "next-flt.snd" 1 22050 0.226757362484932 "Sun/Next" "big endian float (32 bits)" test-headers "aifc-float.snd" 1 22050 0.2267573624849 "AIFC" "big endian float (32 bits)" test-headers "next-mulaw.snd" 1 8012 2.03295063972473 "Sun/Next" "mulaw (8 bits)" test-headers "next24.snd" 1 44100 0.0367800444364548 "Sun/Next" "big endian int (24 bits)" test-headers "nist-01.wav" 1 16000 2.26912498474121 "NIST" "little endian short (16 bits)" test-headers "nist-10.wav" 1 16000 2.26912498474121 "NIST" "big endian short (16 bits)" test-headers "nist-16.snd" 1 16000 1.02400004863739 "NIST" "big endian short (16 bits)" test-headers "nist-shortpack.wav" 1 16000 4.53824996948242 "NIST" "unknown" test-headers "none.aifc" 1 44100 0.0367800444364548 "AIFC" "big endian short (16 bits)" test-headers "nylon2.wav" 2 22050 1.14376413822174 "RIFF" "unknown" test-headers "o2.adf" 1 44100 0.036780 "CSRE adf" "little endian short (16 bits)" test-headers "o2.avr" 1 44100 0.0183900222182274 "AVR" "big endian short (16 bits)" test-headers "o2.bicsf" 1 44100 0.0367800444364548 "IRCAM" "big endian short (16 bits)" test-headers "o2.mpeg1" 2 44100 0.0070975 "raw (no header)" "big endian short (16 bits)" test-headers "o2.sd2" 2 44100 0.0183900222 "raw (no header)" "big endian short (16 bits)" test-headers "o2.sf2" 1 44100 0.036780044436 "SoundFont" "little endian short (16 bits)" test-headers "o2.smp" 1 8000 0.202749997377396 "SMP" "little endian short (16 bits)" test-headers "o2.voc" 1 44100 0.0368934236466885 "VOC" "little endian short (16 bits)" test-headers "o2.wave" 1 44100 0.0367800444364548 "RIFF" "little endian short (16 bits)" test-headers "o2_12bit.aiff" 1 44100 0.036780044436 "AIFF" "big endian short (16 bits)" test-headers "o2_18bit.aiff" 1 44100 0.0367800444364548 "AIFF" "big endian int (24 bits)" test-headers "o2_711u.wave" 1 44100 0.0367800444364548 "RIFF" "mulaw (8 bits)" test-headers "o2_722.snd" 1 44100 0.0183900222182274 "Sun/Next" "unknown" test-headers "o2_726.aiff" 1 8000 0.0367499999701977 "AIFC" "unknown" test-headers "o2_726.snd" 1 44100 0.0230158735066652 "Sun/Next" "unknown" test-headers "o2_728.aiff" 1 8000 0.0367499999701977 "AIFC" "unknown" test-headers "o2_8.iff" 1 44100 0.0367800444364548 "SVX8" "signed byte (8 bits)" test-headers "o2_8.voc" 1 44100 0.0370294786989689 "VOC" "unsigned byte (8 bits)" test-headers "o2_dvi.wave" 1 44100 0.0232199542224407 "RIFF" "unknown" test-headers "o2_float.bicsf" 1 44100 0.0367800444 "IRCAM" "big endian float (32 bits)" test-headers "o2_gsm.aiff" 1 8000 0.0367499999701977 "AIFC" "unknown" test-headers "o2_u8.avr" 1 44100 0.0367800444364548 "AVR" "unsigned byte (8 bits)" test-headers "o2_u8.wave" 1 44100 0.0367800444364548 "RIFF" "unsigned byte (8 bits)" test-headers "o28.mpc" 1 44100 0.036780 "AKAI 4" "little endian short (16 bits)" test-headers "oboe.g721" 1 22050 1.15287983417511 "Sun/Next" "unknown" test-headers "oboe.g723_24" 1 22050 0.864761888980865 "Sun/Next" "unknown" test-headers "oboe.g723_40" 1 22050 1.44126987457275 "Sun/Next" "unknown" test-headers "oboe.kts" 1 22050 2.305125 "Korg" "big endian short (16 bits)" test-headers "oboe.its" 1 22050 2.305125 "Impulse Tracker" "little endian short (16 bits)" test-headers "oboe.sf2" 1 22050 2.305124759674 "SoundFont" "little endian short (16 bits)" test-headers "oboe.paf" 1 22050 2.305125 "Ensoniq Paris" "big endian short (16 bits)" test-headers "oboe.pf1" 1 22050 2.305125 "Ensoniq Paris" "little endian short (16 bits)" test-headers "oboe.smp" 1 22050 2.305125 "snack SMP" "little endian short (16 bits)" test-headers "oboe.rf64" 1 22050 2.305125 "rf64" "little endian short (16 bits)" test-headers "oboe-be32.caf" 1 22050 2.305125 "caff" "normalized big endian int (32 bits)" test-headers "oboe-bf64.caf" 1 22050 2.305125 "caff" "big endian double (64 bits)" test-headers "oboe-lf32.caf" 1 22050 2.305125 "caff" "little endian float (32 bits)" test-headers "oboe-ulaw.caf" 1 22050 2.305125 "caff" "mulaw (8 bits)" test-headers "oboe.nsp" 1 22050 2.305125 "CSL" "little endian short (16 bits)" test-headers "oboe-ulaw.voc" 1 22050 2.305669 "VOC" "mulaw (8 bits)" test-headers "oboe-lf32.sf" 1 22050 2.305669 "IRCAM" "little endian float (32 bits)" test-headers "oboe.wfp" 1 22050 2.305125 "Turtle Beach" "little endian short (16 bits)" test-headers "oboe.sox" 1 22050 2.305125 "Sox" "normalized little endian int (32 bits)" test-headers "oki.snd" 2 44100 0.004195011 "raw (no header)" "big endian short (16 bits)" test-headers "oki.wav" 1 44100 0.016780 "RIFF" "unknown" test-headers "orv-dvi-adpcm.wav" 1 44100 1.92725622653961 "RIFF" "unknown" test-headers "riff-16.snd" 1 22050 1.88766443729401 "RIFF" "little endian short (16 bits)" test-headers "riff-8-u.snd" 1 11025 0.506848096847534 "RIFF" "unsigned byte (8 bits)" test-headers "rooster.wve" 1 8000 2.04800009727478 "PSION" "alaw (8 bits)" test-headers "sd1-16.snd" 1 44100 0.40054 "Sound Designer 1" "big endian short (16 bits)" test-headers "sf-16.snd" 1 22050 1.88766443729401 "IRCAM" "big endian short (16 bits)" test-headers "si654.adc" 1 16000 6.71362495422363 "ADC/OGI" "big endian short (16 bits)" test-headers "smp-16.snd" 1 8000 5.2028751373291 "SMP" "little endian short (16 bits)" test-headers "sound.pat" 1 8000 1.95050001144409 "Gravis Ultrasound patch" "unsigned little endian short (16 bits)" test-headers "sound.sap" 1 8000 1.95050001144409 "Goldwave sample" "little endian short (16 bits)" test-headers "sound.sds" 1 8000 1.95050001144409 "MIDI sample dump" "unknown" test-headers "sound.sfr" 1 8000 1.95050001144409 "SRFS" "little endian short (16 bits)" test-headers "sound.v8" 1 8000 1.95050001144409 "Covox V8" "unsigned byte (8 bits)" test-headers "sound.vox" 2 44100 0.0442177 "raw (no header)" "big endian short (16 bits)" test-headers "step.omf" 1 11025 8.70666694641113 "OMF" "signed byte (8 bits)" test-headers "step.qt" 1 11025 8.70630359649658 "Quicktime" "unsigned byte (8 bits)" test-headers "sun-16-afsp.snd" 1 8000 2.9760000705719 "Sun/Next" "big endian short (16 bits)" test-headers "sun-mulaw.snd" 1 8000 4.61950016021729 "Sun/Next" "mulaw (8 bits)" test-headers "sw1038t_short.wav" 2 8000 6.0 "NIST" "mulaw (8 bits)" test-headers "swirl.pat" 1 22050 1.0619500875473 "Gravis Ultrasound patch" "unsigned little endian short (16 bits)" test-headers "sy85.snd" 1 8000 5.05600023269653 "Sy-85" "big endian short (16 bits)" test-headers "sy99.snd" 1 8000 4.54400014877319 "Sy-99" "big endian short (16 bits)" test-headers "telephone.wav" 1 16000 2.2788124084 "NIST" "little endian short (16 bits)" test-headers "trumps22.adp" 1 22050 3.092880 "RIFF" "unknown" test-headers "truspech.wav" 1 8000 1.1599999666214 "RIFF" "unknown" test-headers "ulaw.aifc" 1 44100 0.0367800444364548 "AIFC" "mulaw (8 bits)" test-headers "voc-8-u.snd" 1 8000 1.49937498569489 "VOC" "unsigned byte (8 bits)" test-headers "o28.voc" 1 44100 0.036893 "VOC" "little endian short (16 bits)" test-headers "voxware.wav" 1 8000 0.324000000953674 "RIFF" "unknown" test-headers "wd.w00" 1 8000 0.202749997377396 "Sy-99" "big endian short (16 bits)" test-headers "wd1.smp" 1 8000 0.202749997377396 "SMP" "little endian short (16 bits)" test-headers "wd1.wav" 1 44100 0.0367800444364548 "RIFF" "little endian short (16 bits)" test-headers "wheel.mat" 2 44100 0.14564626 "raw (no header)" "big endian short (16 bits)" test-headers "b8.pvf" 1 44100 0.036803 "Portable Voice Format" "signed byte (8 bits)" test-headers "b16.pvf" 1 44100 0.0368 "Portable Voice Format" "big endian short (16 bits)" test-headers "b32.pvf" 1 44100 0.036803 "Portable Voice Format" "big endian int (32 bits)" test-headers "water.voc" 2 32000 42.3463897705078 "VOC" "little endian short (16 bits)" test-headers "wood.dsf" 1 8000 0.202749997377 "Delusion" "little endian short (16 bits)" test-headers "wood.dvi" 1 22100 0.0278733037412167 "RIFF" "unknown" test-headers "wood.dwd" 1 22100 0.0733936652541161 "DiamondWare" "signed byte (8 bits)" test-headers "wood.fsm" 1 8000 0.2029999942 "Farandole" "little endian short (16 bits)" test-headers "wood.mad" 1 22100 0.0372398197650909 "RIFF" "unknown" test-headers "wood.maud" 1 44100 0.0183900222182274 "MAUD" "big endian short (16 bits)" test-headers "wood.pat" 1 22100 0.0733936652541161 "Gravis Ultrasound patch" "little endian short (16 bits)" test-headers "wood.riff" 1 44100 0.0367800444364548 "RIFF" "little endian short (16 bits)" test-headers "wood.rifx" 1 44100 0.0367800444364548 "RIFF" "big endian short (16 bits)" test-headers "wood.sds" 1 22100 0.0733936652541161 "MIDI sample dump" "unknown" test-headers "wood.sdx" 1 22100 0.0733936652541161 "Sample dump" "unsigned little endian short (16 bits)" test-headers "wood.sf" 1 44100 0.0367800444364548 "IRCAM" "big endian short (16 bits)" test-headers "wood.sndr" 2 44100 0.009229 "raw (no header)" "big endian short (16 bits)" test-headers "wood.sndt" 1 44100 0.0367800444364548 "SNDT" "unsigned byte (8 bits)" test-headers "wood.st3" 1 8000 0.202749997377396 "Digiplayer ST3" "unsigned little endian short (16 bits)" test-headers "wood.uwf" 1 8000 0.202999994 "Ultratracker" "little endian short (16 bits)" test-headers "wood.w00" 1 16000 0.101374998688698 "TX-16W" "unknown" test-headers "wood12.aiff" 1 44100 0.0367800444364548 "AIFF" "big endian short (16 bits)" test-headers "wood16.dwd" 2 44100 0.03678004 "DiamondWare" "little endian short (16 bits)" test-headers "wood16.wav" 2 44100 0.03678004 "RIFF" "little endian short (16 bits)" test-headers "wood16.nsp" 2 44100 0.03678004 "CSL" "little endian short (16 bits)" test-headers "wood16.smp" 2 44100 0.03678004 "snack SMP" "little endian short (16 bits)" test-headers "wood24.aiff" 1 44100 0.0367800444364548 "AIFF" "big endian int (24 bits)" test-headers "woodblock.aiff" 1 44100 0.03678 "AIFF" "big endian short (16 bits)" test-headers "woodflt.snd" 1 44100 0.0367800444364548 "Sun/Next" "big endian float (32 bits)" test-headers "RealDrums.sf2" 1 44100 6.397256 "SoundFont" "little endian short (16 bits)" test-headers "32bit.sf" 1 44100 4.6 "IRCAM" "little endian float (32 bits, unscaled)" test-headers "PCM_48_8bit_m.w64" 1 48000 0.375 "SoundForge" "unsigned byte (8 bits)" test-headers "oboe.sf6" 1 22050 2.305125 "SoundForge" "little endian short (16 bits)" test-headers "addf8.24we" 1 8000 2.976000 "RIFF" "little endian int (24 bits)" test-headers "hybrid.snd" 1 44100 4.600000 "BICSF" "big endian float (32 bits)" test-headers "litmanna.sf" 1 44100 0.533 "IRCAM" "little endian short (16 bits)" test-headers "M1F1-float64C-AFsp.aif" 2 8000 2.9366 "AIFC" "big endian double (64 bits)" test-headers "MacBoing.wav" 1 11127 0.696 "RIFF" "unsigned byte (8 bits)" test-headers "t15.aiff" 2 44100 135.00 "AIFC" "little endian short (16 bits)" test-headers "tomf8.aud" 1 8000 2.016000 "INRS" "little endian short (16 bits)" test-headers "Xhs001x.nsp" 1 10000 6.017400 "CSL" "little endian short (16 bits)" test-headers "zulu_a4.w11" 1 33000 1.21987879276276 "TX-16W" "unknown" 23342 40042 test-headers-with-loop ; \ ---------------- test 03: variables ---------------- : y>0.1-cb <{ y -- f }> y 0.1 f> ; : y<0.0-cb <{ y -- f }> y f0< ; '( 0 0.0 50 0.5 100 1.0 ) value zero-to-one '( 0 1.0 50 0.5 100 0.0 ) value mod-down : rm-ladspa <{ sym reg -- f }> reg sym symbol-name regexp= ; : 03-variables ( -- ) "oboe.snd" open-sound { ind } *home* "/test" $+ { test-dir } test-dir file-exists? if temp-dir { old-val } test-dir set-temp-dir test-dir "set-temp-dir" #() snd-test-neq old-val set-temp-dir drop then 1000 sample 0.0328 "sample 1000" #() snd-test-neq \ #( output-comment-hook help-hook mark-drag-hook mix-drag-hook mouse-drag-hook mouse-click-hook mouse-press-hook start-playing-hook start-playing-selection-hook stop-playing-hook key-press-hook snd-error-hook snd-warning-hook name-click-hook after-apply-controls-hook enved-hook mouse-enter-label-hook mouse-enter-graph-hook mouse-enter-listener-hook mouse-leave-label-hook mouse-leave-graph-hook mouse-leave-listener-hook initial-graph-hook after-graph-hook graph-hook ) each { h } h hook? not h empty? not || if "%d: %s?" #( i h ) snd-display then end-each \ *with-test-gui* if show-controls { old-ctrl } #t set-show-controls drop enved-dialog { req } dialog-widgets 1 array-ref req "enved-dialog" #() snd-test-neq '( 0.0 0.0 1.0 1.0 2.0 0.0 ) to req req set-enved-envelope drop enved-envelope req "set-enved-envelope" #() snd-test-neq enved-envelope set-enved-envelope drop enved-envelope req "set-enved-envelope to self" #() snd-test-neq old-ctrl set-show-controls drop then \ #( #( <'> color-cutoff 0.003 0.01 ) #( <'> color-inverted #t #f ) #( <'> color-scale 1.0 0.5 ) #( <'> contrast-control? #f #t ) #( <'> enved-base 1.0 1.5 ) #( <'> enved-in-dB #f #t ) #( <'> enved-target 0 1 ) #( <'> enved-wave? #f #t ) #( <'> expand-control? #f #t ) #( <'> fft-log-frequency #f #t ) #( <'> fft-log-magnitude #f #t ) #( <'> fft-with-phases #f #t ) #( <'> enved-filter-order 40 20 ) #( <'> filter-control? #f #t ) #( <'> transform-normalization normalize-by-channel dont-normalize ) #( <'> reverb-control? #f #t ) #( <'> show-transform-peaks #f #t ) #( <'> show-selection-transform #f #t ) #( <'> spectrum-end 1.0 0.7 ) #( <'> spectro-hop 4 10 ) #( <'> spectrum-start 0.0 0.1 ) #( <'> spectro-x-angle *with-test-gl* if 300.0 else 90.0 then 60.0 ) #( <'> spectro-x-scale *with-test-gl* if 1.5 else 1.0 then 2.0 ) #( <'> spectro-y-angle *with-test-gl* if 320.0 else 0.0 then 60.0 ) #( <'> spectro-y-scale 1.0 2.0 ) #( <'> spectro-z-angle *with-test-gl* if 0.0 else 358.0 then 60.0 ) #( <'> spectro-z-scale *with-test-gl* if 1.0 else 0.1 then 0.2 ) ) { gui-lst } #( #( <'> amp-control 1.0 0.5 ) #( <'> amp-control-bounds '( 0.0 8.0 ) '( 1.0 5.0 ) ) #( <'> ask-about-unsaved-edits #f #t ) #( <'> ask-before-overwrite #f #t ) #( <'> auto-resize #t #f ) #( <'> auto-update #f #t ) #( <'> channel-style 0 1 ) #( <'> colormap *good-colormap* *better-colormap* ) #( <'> contrast-control 0.0 0.5 ) #( <'> contrast-control-bounds '( 0.0 10.0 ) '( 1.0 5.0 ) ) #( <'> contrast-control-amp 1.0 0.5 ) #( <'> auto-update-interval 60.0 120.0 ) #( <'> cursor-update-interval 0.05 0.1 ) #( <'> cursor-location-offset 0 32768 ) #( <'> with-tracking-cursor #f #t ) #( <'> cursor-size 15 30 ) #( <'> cursor-style cursor-cross cursor-line ) #( <'> tracking-cursor-style cursor-line cursor-cross ) #( <'> dac-combines-channels #t #f ) #( <'> dac-size 256 512 ) #( <'> clipping #f #t ) #( <'> default-output-chans 1 2 ) #( <'> default-output-sample-type 1 1 ) #( <'> default-output-srate 22050 44100 ) #( <'> default-output-header-type mus-next mus-aifc ) #( <'> dot-size 1 4 ) #( <'> enved-clip? #f #t ) #( <'> enved-style envelope-linear envelope-exponential ) #( <'> enved-power 3.0 3.5 ) #( <'> eps-file "snd.eps" "snd-1.eps" ) #( <'> eps-left-margin 0.0 72.0 ) #( <'> eps-size 1.0 2.0 ) #( <'> eps-bottom-margin 0.0 36.0 ) #( <'> expand-control 1.0 2.0 ) #( <'> expand-control-bounds '( 0.001 20.0 ) '( 1.0 2.0 ) ) #( <'> expand-control-hop 0.05 0.1 ) #( <'> expand-control-jitter 0.1 0.2 ) #( <'> expand-control-length 0.15 0.2 ) #( <'> expand-control-ramp 0.4 0.2 ) #( <'> fft-window-alpha 0.0 1.0 ) #( <'> fft-window-beta 0.0 0.5 ) #( <'> transform-size 512 1024 ) #( <'> transform-graph-type graph-once graph-as-sonogram ) #( <'> fft-window 6 5 ) #( <'> transform-graph? #f #t ) #( <'> filter-control-in-dB #f #t ) #( <'> filter-control-envelope '( 0.0 1.0 1.0 1.0 ) '( 0.0 1.0 1.0 0.0 ) ) #( <'> enved-filter #t #f ) #( <'> filter-control-in-hz #f #t ) #( <'> filter-control-order 20 40 ) #( <'> graph-cursor 34 32 ) #( <'> graph-style 0 1 ) #( <'> initial-beg 0.0 1.0 ) #( <'> initial-dur 0.1 1.0 ) #( <'> just-sounds #f #t ) #( <'> listener-prompt ">" ":" ) #( <'> max-transform-peaks 100 10 ) #( <'> max-regions 16 6 ) #( <'> min-dB -60.0 -90.0 ) #( <'> log-freq-start 32.0 10.0 ) #( <'> mix-waveform-height 20 40 ) #( <'> mix-tag-height 14 20 ) #( <'> mix-tag-width 6 20 ) #( <'> mark-tag-height 4 20 ) #( <'> mark-tag-width 10 20 ) #( <'> mus-clipping #f #t ) #( <'> selection-creates-region #t #f ) #( <'> play-arrow-size 10 16 ) #( <'> print-length 12 16 ) #( <'> region-graph-style graph-lines graph-lollipops ) #( <'> reverb-control-decay 1.0 2.0 ) #( <'> reverb-control-feedback 1.09 1.6 ) #( <'> reverb-control-length 1.0 2.0 ) #( <'> reverb-control-length-bounds '( 0.0 0.5 ) '( 1.0 2.0 ) ) #( <'> reverb-control-lowpass 0.7 0.9 ) #( <'> reverb-control-scale 0.0 0.2 ) #( <'> reverb-control-scale-bounds '( 0.0 4.0 ) '( 0.0 0.2 ) ) #( <'> show-axes 1 0 ) #( <'> show-full-duration #f #t ) #( <'> show-full-range #f #t ) #( <'> show-indices #f #t ) #( <'> show-marks #t #f ) #( <'> show-mix-waveforms #t #f ) #( <'> show-y-zero #f #t ) #( <'> show-grid #f #t ) #( <'> grid-density 1.0 0.5 ) #( <'> show-sonogram-cursor #f #t ) #( <'> sinc-width 10 40 ) #( <'> speed-control 1.0 0.5 ) #( <'> speed-control-bounds '( 0.05 20.0 ) '( 1.0 5.0 ) ) #( <'> speed-control-style 0 1 ) #( <'> speed-control-tones 12 18 ) #( <'> sync 0 1 ) #( <'> sync-style sync-by-sound sync-all ) #( <'> tiny-font tiny-font-string tiny-font-set-string ) #( <'> transform-type fourier-transform autocorrelation ) #( <'> with-verbose-cursor #f #t ) #( <'> wavelet-type 0 1 ) #( <'> time-graph? #f #t ) #( <'> time-graph-type graph-once graph-as-wavogram ) #( <'> wavo-hop 3 6 ) #( <'> wavo-trace 64 128 ) #( <'> with-mix-tags #t #f ) #( <'> with-relative-panes #t #f ) #( <'> with-gl *with-test-gl* #f ) #( <'> x-axis-style 0 1 ) #( <'> beats-per-minute 30.0 120.0 ) #( <'> beats-per-measure 1 120 ) #( <'> zero-pad 0 1 ) #( <'> zoom-focus-style 2 1 ) ) { lst } *with-test-gui* if lst gui-lst array-append to lst then nil nil nil nil nil { vals sym initval newval nowval } lst each to vals vals 0 array-ref to sym vals 1 array-ref to initval vals 2 array-ref to newval 2 0 do newval sym set-execute drop sym execute to nowval nowval newval "set-%s[%d]" #( sym i ) snd-test-neq initval sym set-execute drop loop end-each \ #( *with-test-gui* if #( <'> amp-control 1.0 '( -1.0 123.123 ) ) then #( <'> amp-control-bounds '( 0.0 8.0 ) '( #f '( 0.0 ) '( 1.0 0.0 ) 2.0 ) ) #( <'> channel-style 0 '( 32 -1 1.0 ) ) #( <'> colormap *good-colormap* '( 321 -123 ) ) #( <'> color-cutoff 0.003 '( -1.0 123.123 ) ) #( <'> color-scale 1.0 '( -32.0 2000.0 ) ) *with-test-gui* if #( <'> contrast-control 0.0 '( -123.123 123.123 ) ) then #( <'> contrast-control-bounds '( 0.0 10.0 ) '( #f '( 0.0 ) '( 1.0 0.0 ) 2.0 ) ) #( <'> cursor-size 15 '( 1.123 -2.5 ) ) #( <'> dac-size 256 '( -1 0 -123 ) ) #( <'> dot-size 1 '( 0 -1 -123 ) ) #( <'> enved-target 0 '( 123 -321 ) ) #( <'> expand-control 1.0 '( -1.0 0.0 ) ) #( <'> expand-control-bounds '( 0.001 20.0 ) '( #f '( 0.0 ) '( 1.0 0.0 ) 2.0 ) ) #( <'> expand-control-hop 0.05 '( -1.0 ) ) #( <'> expand-control-length 0.15 '( -1.0 0.0 ) ) #( <'> expand-control-ramp 0.4 '( -1.0 1.0 123.123 ) ) #( <'> fft-window-alpha 0.0 '( -1.0 123.123 ) ) #( <'> fft-window-beta 0.0 '( -1.0 123.123 ) ) #( <'> transform-size 512 '( -1 0 ) ) #( <'> zero-pad 0 '( -1 -123 ) ) #( <'> cursor-style cursor-cross '( -1 ) ) #( <'> cursor-style cursor-line '( 2 123 ) ) #( <'> tracking-cursor-style cursor-line '( -1 ) ) #( <'> tracking-cursor-style cursor-line '( 2 123 ) ) #( <'> transform-graph-type graph-once '( -1 123 ) ) #( <'> fft-window 6 '( -1 123 ) ) #( <'> enved-filter-order 40 '( -1 0 ) ) #( <'> filter-control-order 20 '( -10 -1 0 ) ) #( <'> max-transform-peaks 100 '( -1 ) ) #( <'> max-regions 16 '( -1 -123 ) ) #( <'> reverb-control-length 1.0 '( -1.0 ) ) #( <'> show-axes 1 '( -1 123 ) ) #( <'> sinc-width 10 '( -10 ) ) #( <'> spectrum-end 1.0 '( -1.0 ) ) #( <'> spectro-hop 4 '( -10 -1 0 ) ) #( <'> spectrum-start 0.0 '( -1.0 ) ) #( <'> speed-control 1.0 '( 0.0 ) ) #( <'> speed-control-bounds '( 0.05 20.0 ) '( #f '( 0.0 ) '( 1.0 0.0 ) 2.0 ) ) #( <'> speed-control-style 0 '( -1 10 ) ) #( <'> sync-style sync-by-sound '( -1 123 ) ) #( <'> transform-type fourier-transform '( -1 integer->transform 123 integer->transform ) ) #( <'> wavelet-type 0 '( -1 123 ) ) #( <'> wavo-hop 1 '( 0 -123 ) ) #( <'> wavo-trace 1 '( 0 -123 ) ) #( <'> x-axis-style 0 '( -1 123 ) ) #( <'> zoom-focus-style 2 '( -1 123 ) ) ) to lst nil { newvals } lst each to vals vals 0 array-ref to sym vals 1 array-ref to initval vals 2 array-ref to newvals newvals each to newval newval sym <'> set-execute snd-test-catch drop sym execute to nowval nowval newval "set-%s (bad set)" #( sym ) snd-test-eq initval sym set-execute drop end-each end-each \ *with-test-gui* if sync-none set-sync-style drop 300 set-window-width drop 300 set-window-height drop window-width 300 "window-width" #() snd-test-neq window-height 300 "window-height" #() snd-test-neq color-scale { old-val } 100.0 set-color-scale drop color-scale 100.0 "color-scale" #() snd-test-neq old-val set-color-scale drop then \ search-procedure proc? if "global search procedure: %s?" #( search-procedure ) snd-display then <'> y>0.1-cb set-search-procedure drop search-procedure proc? unless "set global search procedure: %s?" #( search-procedure ) snd-display then search-procedure #( 0.2 ) run-proc unless "search 0.1 > 0.2?" #() snd-display then search-procedure #( 0.02 ) run-proc if "search 0.1 > 0.02?" #() snd-display then <'> y<0.0-cb set-search-procedure drop search-procedure #( 0.02 ) run-proc if "search 0.0 < 0.02?" #() snd-display then #f set-search-procedure drop search-procedure proc? if "global search procedure after reset: %s?" #( search-procedure ) snd-display then <'> y>0.1-cb set-search-procedure drop search-procedure proc? unless "set global search procedure: %s?" #( search-procedure ) snd-display then #f set-search-procedure drop \ *with-test-gui* if enved-filter-order { old-val } 5 set-enved-filter-order drop enved-filter-order 6 "set-enved-filter-order 5" #() snd-test-neq old-val set-enved-filter-order drop \ XXX: This works with global variables. [ms] 'zero-to-one <'> set-enved-envelope snd-test-catch drop enved-envelope zero-to-one "set-enved-envelope (symbol)" #() snd-test-neq "mod-down" <'> set-enved-envelope snd-test-catch drop enved-envelope mod-down "set-enved-envelope (string)" #() snd-test-neq then ind close-sound drop dismiss-all-dialogs #() { undefined } \ XXX: changes from original snd-test.scm list [ms]: \ \ removed (Scheme specific): \ 'add-clm-field (run.c) \ 'run (macro in run.c) \ 'file->string (snd-utils.c) \ \ removed (Forth specific): \ 'abort (forth word) \ \ added: \ 'snd-exit (xen.c; in Forth exit is already in use) #( '*snd-opened-sound* 'add-colormap 'add-mark 'add-player 'add-sound-file-extension 'add-source-file-extension 'add-to-main-menu 'add-to-menu 'add-transform 'after-apply-controls-hook 'after-edit-hook 'after-graph-hook 'after-lisp-graph-hook 'after-open-hook 'after-save-as-hook 'after-save-state-hook 'after-transform-hook 'all-pass 'all-pass? 'amp-control 'amp-control-bounds 'amplitude-modulate 'analyse-ladspa 'apply-controls 'apply-ladspa 'array->file 'array-interp 'as-one-edit 'ask-about-unsaved-edits 'ask-before-overwrite 'asymmetric-fm 'asymmetric-fm? 'auto-resize 'auto-update 'auto-update-interval 'autocorrelate 'autocorrelation 'axis-color 'axis-info 'axis-label-font 'axis-numbers-font 'bad-header-hook 'bartlett-window 'bartlett-hann-window 'basic-color 'beats-per-measure 'beats-per-minute 'before-close-hook 'before-exit-hook 'before-save-as-hook 'before-save-state-hook 'before-transform-hook 'bind-key 'blackman2-window 'blackman3-window 'blackman4-window 'blackman5-window 'blackman6-window 'blackman7-window 'blackman8-window 'blackman9-window 'blackman10-window 'bohman-window 'bold-peaks-font 'cauchy-window 'mlt-sine-window 'cepstrum 'change-samples-with-origin 'channel->vct 'channel-amp-envs 'channel-data 'channel-properties 'channel-property 'channel-style 'channel-widgets 'channels 'channels-combined 'channels-separate 'channels-superimposed 'chans 'clear-listener 'clip-hook 'clipping 'clm-channel 'clm-table-size 'clm-default-frequency 'close-hook 'close-sound 'color->list 'color-cutoff 'color-orientation-dialog 'color-hook 'color-inverted 'color-scale 'color? 'colormap 'colormap-name 'colormap-ref 'colormap-size 'colormap? 'comb 'comb? 'combined-data-color 'comment 'connes-window 'continue-frample->file 'continue-sample->file 'contrast-control 'contrast-control-amp 'contrast-control-bounds 'contrast-control? 'contrast-enhancement 'controls->channel 'convolution 'convolve 'convolve-files 'convolve-selection-with 'convolve-with 'convolve? 'copy-context 'copy-sampler 'current-edit-position 'current-font 'cursor 'cursor-color 'cursor-context 'cursor-cross 'cursor-in-middle 'cursor-in-view 'cursor-line 'cursor-location-offset 'cursor-on-left 'cursor-on-right 'cursor-position 'cursor-size 'cursor-style 'cursor-update-interval 'dac-combines-channels 'dac-size 'data-color 'sample-type 'data-location 'data-size 'db->linear 'default-output-chans 'default-output-sample-type 'default-output-header-type 'default-output-srate 'define-envelope 'degrees->radians 'delay 'delay-tick 'delay? 'delete-colormap 'delete-mark 'delete-marks 'delete-sample 'delete-samples 'delete-samples-and-smooth 'delete-selection 'delete-selection-and-smooth 'delete-transform 'dialog-widgets 'disk-kspace 'display-edits 'dolph-chebyshev-window 'dont-normalize 'dot-product 'dot-size 'draw-axes 'draw-dot 'draw-dots 'draw-line 'draw-lines 'draw-mark-hook 'draw-mix-hook 'draw-string 'drop-hook 'during-open-hook 'edit-fragment 'edit-header-dialog 'edit-hook 'edit-list->function 'edit-position 'edit-tree 'edits 'edot-product 'env 'env-channel 'env-channel-with-base 'env-interp 'env-selection 'env-sound 'env? 'enved-add-point 'enved-amplitude 'enved-base 'enved-clip? 'enved-delete-point 'enved-dialog 'enved-envelope 'enved-filter 'enved-filter-order 'enved-hook 'enved-in-dB 'enved-move-point 'enved-power 'enved-spectrum 'enved-srate 'enved-style 'enved-target 'enved-wave? 'enved-waveform-color 'envelope-exponential 'envelope-linear 'eps-bottom-margin 'eps-file 'eps-left-margin 'eps-size 'exit 'exit-hook 'expand-control 'expand-control-bounds 'expand-control-hop 'expand-control-jitter 'expand-control-length 'expand-control-ramp 'expand-control? 'exponential-window 'fft 'fft-log-frequency 'fft-log-magnitude 'fft-window 'fft-window-alpha 'fft-window-beta 'fft-with-phases 'file->array 'file->frample 'file->frample? 'file->sample 'file->sample? 'file-name 'file-write-date 'fill-polygon 'fill-rectangle 'filter 'filtered-comb 'filtered-comb? 'filter-channel 'filter-control-coeffs 'filter-control-envelope 'filter-control-in-dB 'filter-control-in-hz 'filter-control-order 'filter-control-waveform-color 'filter-control? 'filter-selection 'filter-sound 'filter? 'find-dialog 'find-mark 'find-sound 'finish-progress-report 'fir-filter 'fir-filter? 'flat-top-window 'focus-widget 'foreground-color 'forget-region 'formant 'formant-bank 'formant-bank? 'formant? 'firmant 'firmant? 'comb-bank 'comb-bank? 'all-pass-bank 'all-pass-bank? 'filtered-comb-bank 'filtered-comb-bank? 'make-comb-bank 'make-all-pass-bank 'make-filtered-comb-bank 'fourier-transform 'frample->file 'frample->file? 'frample->frample 'framples 'free-player 'free-sampler 'gaussian-window 'gc-off 'gc-on 'gl-graph->ps 'glSpectrogram 'goto-listener-end 'granulate 'granulate? 'graph 'graph->ps 'graph-as-sonogram 'graph-as-spectrogram 'graph-as-wavogram 'graph-color 'graph-cursor 'graph-data 'graph-dots 'graph-dots-and-lines 'graph-filled 'graph-hook 'graph-lines 'graph-lollipops 'graph-once 'graph-style 'graphs-horizontal 'grid-density 'haar-transform 'hamming-window 'hann-poisson-window 'hann-window 'header-type 'help-dialog 'help-hook 'hide-widget 'highlight-color 'html-dir 'html-program 'hz->radians 'iir-filter 'iir-filter? 'in 'in-any 'ina 'inb 'info-dialog 'init-ladspa 'initial-graph-hook 'insert-file-dialog 'insert-region 'insert-sample 'insert-samples 'insert-samples-with-origin 'insert-selection 'insert-silence 'insert-sound 'just-sounds 'kaiser-window 'key 'key-binding 'key-press-hook 'keyboard-no-action 'ladspa-activate 'ladspa-cleanup 'ladspa-connect-port 'ladspa-deactivate 'ladspa-descriptor 'ladspa-dir 'peak-env-dir 'ladspa-instantiate 'ladspa-run 'ladspa-run-adding 'ladspa-set-run-adding-gain 'left-sample 'linear->db 'lisp-graph 'lisp-graph-hook 'lisp-graph-style 'lisp-graph? 'list->vct 'list-ladspa 'listener-click-hook 'listener-color 'listener-font 'listener-prompt 'listener-selection 'listener-text-color 'little-endian? 'locsig 'locsig-ref 'locsig-reverb-ref 'locsig-reverb-set! 'locsig-set! 'locsig-type 'locsig? 'log-freq-start 'main-menu 'main-widgets 'make-all-pass 'make-asymmetric-fm 'make-moving-average 'make-moving-max 'make-bezier 'make-color 'make-comb 'make-filtered-comb 'make-convolve 'make-delay 'make-env 'make-fft-window 'make-file->frample 'make-file->sample 'make-filter 'make-fir-coeffs 'make-fir-filter 'make-formant 'make-firmant 'make-formant-bank 'make-frample->file 'make-granulate 'make-graph-data 'make-iir-filter 'make-locsig 'make-mix-sampler 'make-move-sound 'make-notch 'make-one-pole 'make-one-pole-all-pass 'make-one-zero 'make-oscil 'make-phase-vocoder 'make-player 'make-polyshape 'make-polywave 'make-pulse-train 'make-rand 'make-rand-interp 'make-readin 'make-region 'make-region-sampler 'make-sample->file 'make-sampler 'make-sawtooth-wave 'make-nrxysin 'make-nrxycos 'make-rxyk!cos 'make-rxyk!sin 'make-snd->sample 'make-square-wave 'make-src 'make-ssb-am 'make-ncos 'make-nsin 'make-table-lookup 'make-triangle-wave 'make-two-pole 'make-two-zero 'make-variable-graph 'make-vct 'make-wave-train 'map-chan 'map-channel 'mark-click-hook 'mark-color 'mark-context 'mark-drag-hook 'mark-home 'mark-hook 'mark-name 'mark-properties 'mark-property 'mark-sample 'mark-sync 'mark-sync-max 'mark-tag-height 'mark-tag-width 'mark? 'marks 'max-regions 'max-transform-peaks 'maxamp 'maxamp-position 'menu-widgets 'min-dB 'mix 'mix-amp 'mix-amp-env 'mix-click-hook 'mix-color 'mix-dialog-mix 'mix-drag-hook 'mix-file-dialog 'mix-length 'mix-home 'mix-name 'mix-position 'mix-properties 'mix-property 'mix-region 'mix-release-hook 'mix-sync 'mix-sync-max 'mix-sampler? 'mix-selection 'mix-speed 'mix-tag-height 'mix-tag-width 'mix-tag-y 'mix-vct 'mix-waveform-height 'mix? 'mixes 'mouse-click-hook 'mouse-drag-hook 'mouse-enter-graph-hook 'mouse-enter-label-hook 'mouse-enter-listener-hook 'mouse-enter-text-hook 'mouse-leave-graph-hook 'mouse-leave-label-hook 'mouse-leave-listener-hook 'mouse-leave-text-hook 'mouse-press-hook 'move-locsig 'move-sound 'move-sound? 'moving-average 'moving-average? 'moving-max 'moving-max? 'mus-aifc 'mus-aiff 'mus-alaw 'mus-alsa-buffer-size 'mus-alsa-buffers 'mus-alsa-capture-device 'mus-alsa-device 'mus-alsa-playback-device 'mus-alsa-squelch-warning 'mus-apply 'mus-array-print-length 'mus-float-equal-fudge-factor 'mus-b24int 'mus-bdouble 'mus-bdouble-unscaled 'mus-bfloat 'mus-bfloat-unscaled 'mus-bicsf 'mus-bint 'mus-bintn 'mus-bshort 'mus-byte 'mus-bytes-per-sample 'mus-caff 'mus-channel 'mus-channels 'mus-chebyshev-first-kind 'mus-chebyshev-second-kind 'mus-clipping 'mus-close 'mus-data 'mus-sample-type->string 'mus-sample-type-name 'mus-describe 'mus-error-hook 'mus-error-type->string 'mus-expand-filename 'mus-feedback 'mus-feedforward 'mus-fft 'mus-file-buffer-size 'mus-file-clipping 'mus-file-name 'mus-frequency 'mus-generator? 'mus-header-raw-defaults 'mus-header-type->string 'mus-header-type-name 'mus-hop 'mus-increment 'mus-input? 'mus-interp-all-pass 'mus-interp-bezier 'mus-interp-hermite 'mus-interp-lagrange 'mus-interp-linear 'mus-interp-none 'mus-interp-sinusoidal 'mus-interp-type 'mus-interpolate 'mus-ircam 'mus-l24int 'mus-ldouble 'mus-ldouble-unscaled 'mus-length 'mus-lfloat 'mus-lfloat-unscaled 'mus-lint 'mus-lintn 'mus-location 'mus-lshort 'mus-max-malloc 'mus-max-table-size 'mus-mulaw 'mus-name 'mus-next 'mus-nist 'mus-offset 'mus-order 'mus-oss-set-buffers 'mus-out-format 'mus-output? 'mus-phase 'mus-ramp 'mus-rand-seed 'mus-random 'mus-raw 'mus-reset 'mus-riff 'mus-run 'mus-scaler 'mus-set-formant-radius-and-frequency 'mus-sound-chans 'mus-sound-comment 'mus-sound-sample-type 'mus-sound-data-location 'mus-sound-datum-size 'mus-sound-duration 'mus-sound-forget 'mus-sound-framples 'mus-sound-header-type 'mus-sound-length 'mus-sound-loop-info 'mus-sound-mark-info 'mus-sound-maxamp 'mus-sound-maxamp-exists? 'mus-sound-prune 'mus-sound-report-cache 'mus-sound-samples 'mus-sound-srate 'mus-sound-type-specifier 'mus-sound-write-date 'mus-soundfont 'mus-srate 'mus-svx 'mus-ubshort 'mus-ubyte 'mus-ulshort 'mus-unknown-sample 'mus-unknown-header 'mus-voc 'mus-width 'mus-xcoeff 'mus-xcoeffs 'mus-ycoeff 'mus-ycoeffs 'name-click-hook 'new-sound 'new-sound-dialog 'new-sound-hook 'new-widget-hook 'next-sample 'normalize-by-channel 'normalize-by-sound 'normalize-channel 'normalize-globally 'notch 'notch? 'one-pole 'one-pole? 'one-pole-all-pass 'one-pole-all-pass? 'one-zero 'one-zero? 'open-file-dialog 'open-file-dialog-directory 'open-hook 'open-raw-sound 'open-raw-sound-hook 'open-sound 'orientation-hook 'oscil 'oscil? 'out-any 'outa 'outb 'outc 'outd 'output-comment-hook 'override-samples-with-origin 'pad-channel 'partials->polynomial 'partials->wave 'parzen-window 'pausing 'peaks 'peaks-font 'phase-partials->wave 'phase-vocoder 'phase-vocoder-amp-increments 'phase-vocoder-amps 'phase-vocoder-freqs 'phase-vocoder-phase-increments 'phase-vocoder-phases 'phase-vocoder? 'play 'play-arrow-size 'play-hook 'player-home 'player? 'players 'playing 'poisson-window 'polar->rectangular 'polynomial 'polyshape 'polywave 'polyshape? 'polywave? 'position->x 'position->y 'position-color 'preferences-dialog 'previous-sample 'print-dialog 'print-length 'progress-report 'pulse-train 'pulse-train? 'radians->degrees 'radians->hz 'ramp-channel 'rand 'rand-interp 'rand-interp? 'rand? 'read-mix-sample 'read-only 'read-region-sample 'read-sample 'readin 'readin? 'rectangular->magnitudes 'rectangular->polar 'rectangular-window 'redo 'redo-edit 'region->vct 'region-chans 'region-home 'region-framples 'region-graph-style 'region-maxamp 'region-maxamp-position 'region-position 'region-sample 'region-sampler? 'region-srate 'region? 'regions 'remember-sound-state 'remove-from-menu 'reset-controls 'reset-listener-cursor 'restore-controls 'restore-region 'reverb-control-decay 'reverb-control-feedback 'reverb-control-length 'reverb-control-length-bounds 'reverb-control-lowpass 'reverb-control-scale 'reverb-control-scale-bounds 'reverb-control? 'reverse-channel 'reverse-selection 'reverse-sound 'revert-sound 'riemann-window 'right-sample 'ring-modulate 'rv2-window 'rv3-window 'rv4-window 'samaraki-window 'sample 'sample->file 'sample->file? 'sampler-at-end? 'sampler-home 'sampler-position 'sampler? 'samples 'samples->seconds 'sash-color 'save-controls 'save-dir 'save-edit-history 'save-envelopes 'save-hook 'save-listener 'save-marks 'save-region 'save-region-dialog 'save-selection 'save-selection-dialog 'save-sound 'save-sound-as 'save-sound-dialog 'save-state 'save-state-file 'save-state-hook 'sawtooth-wave 'sawtooth-wave? 'scale-by 'scale-channel 'scale-selection-by 'scale-selection-to 'scale-to 'scan-channel 'script-arg 'script-args 'search-procedure 'seconds->samples 'select-all 'select-channel 'select-channel-hook 'select-sound 'select-sound-hook 'selected-channel 'selected-data-color 'selected-graph-color 'selected-sound 'selection-chans 'selection-color 'selection-context 'selection-creates-region 'selection-framples 'selection-maxamp 'selection-maxamp-position 'selection-member? 'selection-position 'selection-srate 'selection? 'short-file-name 'show-all-axes 'show-all-axes-unlabelled 'show-bare-x-axis 'show-axes 'show-controls 'show-grid 'show-indices 'show-full-duration 'show-full-range 'initial-beg 'initial-dur 'show-listener 'show-marks 'show-mix-waveforms 'show-no-axes 'show-selection 'show-selection-transform 'show-sonogram-cursor 'show-transform-peaks 'show-widget 'show-x-axis 'show-x-axis-unlabelled 'show-y-zero 'sinc-width 'nrxysin 'nrxysin? 'nrxycos 'nrxycos? 'rxyk!cos 'rxyk!cos? 'rxyk!sin 'rxyk!sin? 'smooth-channel 'smooth-selection 'smooth-sound 'snd->sample 'snd->sample? 'snd-error 'snd-error-hook 'snd-exit ( added ) 'snd-gcs 'snd-help 'snd-font 'snd-color 'snd-print 'snd-spectrum 'snd-tempnam 'snd-url 'snd-urls 'snd-version 'snd-warning 'snd-warning-hook 'sound-file-extensions 'sound-file? 'sound-files-in-directory 'sound-loop-info 'sound-properties 'sound-property 'sound-widgets 'sound? 'soundfont-info 'sounds 'spectrum-end 'spectro-hop 'spectrum-start 'spectro-x-angle 'spectro-x-scale 'spectro-y-angle 'spectro-y-scale 'spectro-z-angle 'spectro-z-scale 'spectrum 'speed-control 'speed-control-as-float 'speed-control-as-ratio 'speed-control-as-semitone 'speed-control-bounds 'speed-control-style 'speed-control-tones 'square-wave 'square-wave? 'squelch-update 'srate 'src 'src-channel 'src-selection 'src-sound 'src? 'ssb-am 'ssb-am? 'start-playing 'start-playing-hook 'start-playing-selection-hook 'start-progress-report 'status-report 'stop-player 'stop-playing 'stop-playing-hook 'stop-playing-selection-hook 'ncos 'ncos? 'nsin 'nsin? 'swap-channels 'sync 'sync-style 'sync-none 'sync-all 'sync-by-sound 'sync-max 'syncd-marks 'table-lookup 'table-lookup? 'tap 'tap? 'temp-dir 'text-focus-color 'time-graph 'time-graph-style 'time-graph-type 'time-graph? 'tiny-font 'tracking-cursor-style 'transform->vct 'transform-dialog 'transform-framples 'transform-graph 'transform-graph-style 'transform-graph-type 'transform-graph? 'transform-normalization 'transform-sample 'transform-size 'transform-type 'transform? 'triangle-wave 'triangle-wave? 'tukey-window 'two-pole 'two-pole? 'two-zero 'two-zero? 'ultraspherical-window 'unbind-key 'undo 'undo-edit 'undo-hook 'unselect-all 'update-hook 'update-lisp-graph 'update-sound 'update-time-graph 'update-transform-graph 'variable-graph? 'vct 'vct* 'vct+ 'vct->channel 'vct->list 'vct->string 'vct->vector 'vct-add! 'vct-length 'vct-max 'vct-min 'vct-move! 'vct-multiply! 'vct-offset! 'vct-peak 'vct-ref 'vct-reverse! 'vct-scale! 'vct-set! 'vct-subseq 'vct-subtract! 'vct? 'vector->vct 'walsh-transform 'wave-train 'wave-train? 'wavelet-transform 'wavelet-type 'wavo-hop 'wavo-trace 'welch-window 'widget-position 'widget-size 'widget-text 'window-height 'window-width 'window-x 'window-y 'with-background-processes 'with-file-monitor 'with-gl 'with-mix-tags 'with-relative-panes 'with-tracking-cursor 'with-verbose-cursor 'with-inset-graph 'with-interrupts 'with-pointer-focus 'with-smpte-label 'with-toolbar 'with-tooltips 'with-menu-icons 'save-as-dialog-src 'save-as-dialog-auto-comment 'x->position 'x-axis-as-clock 'x-axis-as-percentage 'x-axis-in-beats 'x-axis-in-measures 'x-axis-in-samples 'x-axis-in-seconds 'x-axis-label 'x-axis-style 'x-bounds 'x-position-slider 'x-zoom-slider 'xramp-channel 'y->position 'y-axis-label 'y-bounds 'y-position-slider 'y-zoom-slider 'zero-pad 'zoom-color 'zoom-focus-active 'zoom-focus-left 'zoom-focus-middle 'zoom-focus-right 'zoom-focus-style ) each to sym sym symbol-defined? unless undefined sym array-push to undefined then end-each *with-test-ladspa* unless undefined <'> rm-ladspa #( /ladspa/ ) array-reject! to undefined then *with-test-gl* unless undefined 'glSpectrogram array-delete-key drop then *with-test-gl2ps* unless undefined 'gl-graph->ps array-delete-key drop then undefined empty? unless "undefined[%d]: %s" #( undefined length undefined ) snd-display then ; \ ---------------- test 04: sndlib ---------------- : sndlib-check-it { snd typ fmt samp -- } snd header-type typ "save-as %s" #( typ mus-header-type-name ) snd-test-neq "test.snd" mus-sound-header-type { ntyp } ntyp typ "save-as %s -> %s" #( typ mus-header-type-name ntyp mus-header-type-name ) snd-test-neq snd sample-type fmt "save-as %s" #( fmt mus-sample-type-name ) snd-test-neq "test.snd" mus-sound-sample-type { nfmt } nfmt fmt "save-as %s -> %s" #( fmt mus-sample-type-name nfmt mus-sample-type-name ) snd-test-neq 1000 snd sample samp "%s[1000]" #( typ mus-header-type-name ) snd-test-neq ; : sndlib-check-string <{ string -- str }> string " [written by me]" $+ ; : sndlib-true-cb <{ n -- f }> #t ; : sndlib-raw-hook-cb <{ file choice -- lst }> '( 1 22050 mus-bshort ) ; : sndlib-check-bad-file <{ n -- }> n open-sound { ind } ind number? ind sound? && if ind close-sound drop then ; : sndlib-test-map-10-times-cb <{ y -- y' }> y 10.0 f* ; : sndlib-test-map-add-cb { mx -- prc; y self -- y' } 1 proc-create 1.001 mx f- , ( prc ) does> { y self -- y' } y self @ ( mx ) f+ ; 0 value big-file-framples : sndlib-test-map-x-cb { x incr -- prc; n self -- y } 1 proc-create x , incr , ( prc ) does> { n self -- y } self @ ( x ) { val } val self cell+ @ ( incr ) f+ self ( x ) ! val ; : sndlib-test-scan-x-cb { x incr -- prc; n self -- f } 1 proc-create x , incr , ( prc ) does> { n self -- f } self @ ( x ) { val } val self cell+ @ ( incr ) f+ self ( x ) ! val n fneq ; : sndlib-test-map-set-1.0 <{ n -- n' }> 1.0 ; : (04-sndlib-01) ( -- ) "oboe.snd" { oboe-snd } oboe-snd mus-sound-chans { chns } oboe-snd mus-sound-data-location { dl } oboe-snd mus-sound-framples { fr } oboe-snd mus-sound-samples { smps } oboe-snd mus-sound-length { len } oboe-snd mus-sound-datum-size { size } oboe-snd mus-sound-comment { com } oboe-snd mus-sound-srate { sr } oboe-snd mus-sound-maxamp-exists? { m1 } oboe-snd mus-sound-maxamp { mal } "z.snd" mus-sound-maxamp { mz } oboe-snd mus-sound-sample-type mus-bytes-per-sample { bytes } mz car 0 "mus-sound-maxamp z.snd" #() snd-test-neq mz cadr 0.0 "mus-sound-maxamp z.snd" #() snd-test-neq \ #( #( mus-bshort 2 ) #( mus-lshort 2 ) #( mus-mulaw 1 ) #( mus-alaw 1 ) #( mus-byte 1 ) #( mus-ubyte 1 ) #( mus-bfloat 4 ) #( mus-lfloat 4 ) #( mus-bint 4 ) #( mus-lint 4 ) #( mus-bintn 4 ) #( mus-lintn 4 ) #( mus-b24int 3 ) #( mus-l24int 3 ) #( mus-bdouble 8 ) #( mus-ldouble 8 ) #( mus-ubshort 2 ) #( mus-ulshort 2 ) #( mus-bdouble-unscaled 8 ) #( mus-ldouble-unscaled 8 ) #( mus-bfloat-unscaled 4 ) #( mus-lfloat-unscaled 4 ) ) { formats } nil nil nil { vals frm siz } formats each to vals vals 0 array-ref to frm vals 1 array-ref to siz frm mus-bytes-per-sample siz "mus-bytes-per-sample" #() snd-test-neq end-each mus-bshort mus-sample-type->string "mus-bshort" "mus-sample-type->string" #() snd-test-neq mus-aifc mus-header-type->string "mus-aifc" "mus-header-type->string" #() snd-test-neq \ "hiho.tmp" { hiho } hiho mus-sound-report-cache drop hiho readlines { res } res 0 array-ref string-chomp "sound table:" "print-cache 1" #() snd-test-neq hiho file-delete 10 { req } chns 1 "oboe: mus-sound-chans" #() snd-test-neq dl 28 "oboe: mus-sound-data-location" #() snd-test-neq fr 50828 "oboe: mus-sound-framples" #() snd-test-neq smps 50828 "oboe: mus-sound-samples" #() snd-test-neq len 50828 2* 28 + "oboe: mus-sound-length" #() snd-test-neq size 2 "oboe: mus-sound-datum-size" #() snd-test-neq bytes 2 "oboe: mus-sound-bytes" #() snd-test-neq sr 22050 "oboe: mus-sound-srate" #() snd-test-neq m1 *clmtest* 0= && if "oboe: mus-sound-maxamp-exists before maxamp: %s" #( m1 ) snd-display then oboe-snd mus-sound-maxamp-exists? to res res unless "oboe: not mus-sound-maxamp-exists after maxamp: %s" #( res ) snd-display then *clmtest* 0= if mus-header-raw-defaults to res res length 3 = if res 0 array-ref ( sr ) 44100 "mus-header-raw-defaults srate" #() snd-test-neq res 1 array-ref ( chns ) 2 "mus-header-raw-defaults chans" #() snd-test-neq res 2 array-ref ( frm ) mus-bshort "mus-header-raw-defaults format" #() snd-test-neq else res object-length 3 "mus-header-raw-defaults %s" #( res ) snd-test-neq then then '( 12345 3 mus-bdouble-unscaled ) set-mus-header-raw-defaults drop mus-header-raw-defaults to res res length 3 = if res 0 array-ref ( sr ) 12345 "set-mus-header-raw-defaults srate" #() snd-test-neq res 1 array-ref ( chns ) 3 "set-mus-header-raw-defaults chans" #() snd-test-neq res 2 array-ref ( frm ) mus-bdouble-unscaled "set-mus-header-raw-defaults format" #() snd-test-neq else res object-length 3 "set-mus-header-raw-defaults %s" #( res ) snd-test-neq then '( 44100 2 mus-bshort ) set-mus-header-raw-defaults drop \ "%d-%b %H:%M" oboe-snd mus-sound-write-date strftime "15-Oct 04:34" "mus-sound-write-date oboe.snd" #() snd-test-neq "%d-%b %H:%M" "pistol.snd" mus-sound-write-date strftime "01-Jul 22:06" "mus-sound-write-date pistol.snd" #() snd-test-neq \ oboe-snd open-sound { ind } "test" { long-file-name } 10 0 do long-file-name "-test" string-push drop loop long-file-name ".snd" string-push drop ind variable-graph? if "variable-graph thinks anything is a graph..." #() snd-display then ind player? if "player? thinks anything is a player..." #() snd-display then ind sound? unless "%s is not a sound?" #( ind ) snd-display then #f sound? if "sound? #f -> #t?" #() snd-display then #t sound? if "sound? #t -> #f?" #() snd-display then long-file-name ind save-sound-as drop ind close-sound drop long-file-name open-sound to ind ind sound? unless "can't find test...snd" #() snd-display then long-file-name string-length { lfnlen } ind file-name string-length { fnlen } ind short-file-name string-length { sfnlen } fnlen lfnlen < sfnlen lfnlen < || if "file-name lengths: long-file-name %d, file-name %d, short-file-name %d" #( lfnlen fnlen sfnlen ) snd-display then ind close-sound drop long-file-name mus-sound-forget drop long-file-name file-delete \ "forest.aiff" check-file-name { fsnd } fsnd file-exists? if fsnd "fmv.snd" file-copy "fmv.snd" open-sound to ind ind sound-loop-info fsnd mus-sound-loop-info "loop-info" #() snd-test-neq ind '( 12000 14000 1 2 3 4 ) set-sound-loop-info drop ind sound-loop-info '( 12000 14000 1 2 3 4 1 1 ) "set-loop-info" #() snd-test-neq "fmv1.snd" ind :header-type mus-aifc save-sound-as drop ind close-sound drop "fmv1.snd" mus-sound-loop-info '( 12000 14000 1 2 3 4 1 1 ) "saved-loop-info" #() snd-test-neq then \ oboe-snd open-sound to ind "fmv.snd" ind :header-type mus-aifc save-sound-as drop ind close-sound drop "fmv.snd" open-sound to ind ind sound-loop-info '() "null loop-info" #() snd-test-neq ind '( 1200 1400 4 3 2 1 ) set-sound-loop-info drop ind sound-loop-info '( 1200 1400 4 3 2 1 1 1 ) "set null loop-info" #() snd-test-neq "fmv1.snd" ind :header-type mus-aifc save-sound-as drop "fmv1.snd" mus-sound-loop-info '( 1200 1400 4 3 2 1 1 1 ) "saved null loop-info" #() snd-test-neq ind close-sound drop "fmv.snd" open-sound to ind '( 1200 1400 4 3 2 1 1 0 ) set-sound-loop-info drop ind sound-loop-info '( 1200 1400 0 0 2 1 1 0 ) "set null loop-info (no mode1)" #() snd-test-neq "fmv1.snd" ind :header-type mus-aifc save-sound-as drop ind close-sound drop "fmv1.snd" mus-sound-loop-info '( 1200 1400 0 0 2 1 1 0 ) "saved null loop-info (no mode1)" #() snd-test-neq \ com empty? unless "oboe: mus-sound-comment %S?" #( com ) snd-display then #( #( "nasahal8.wav" "ICRD: 1997-02-22\nIENG: Paul R. Roger\nISFT: Sound Forge 4.0\n" ) #( "8svx-8.snd" "File created by Sound Exchange " ) #( "sun-16-afsp.snd" "AFspdate:1981/02/11 23:03:34 UTC" ) #( "smp-16.snd" "Converted using Sox. " ) #( "d40130.au" "1994 Jesus Villena" ) #( "wood.maud" "file written by SOX MAUD-export " ) #( "addf8.sf_mipseb" "date=\"Feb 11 18:03:34 1981\" info=\"Original recorded at 20 kHz, 15-bit D/A, digitally filtered and resampled\" speaker=\"AMK female\" text=\"Add the sum to the product of these three.\" " ) #( "mary-sun4.sig" "MARY HAD A LITTLE LAMB\n" ) #( "nasahal.pat" "This patch saved with Sound Forge 3.0." ) #( "next-16.snd" ";Written on Mon 1-Jul-91 at 12:10 PDT at localhost (NeXT) using Allegro CL and clm of 25-June-91" ) #( "wood16.nsp" "Created by Snack " ) #( "wood.sdx" "1994 Jesus Villena" ) #( "clmcom.aif" "this is a comment" ) #( "anno.aif" "1994 Jesus Villena\n" ) #( "telephone.wav" "sample_byte_format -s2 01\nchannel_count -i 1\nsample_count -i 36461\nsample_rate -i 16000\nsample_n_bytes -i 2\nsample_sig_bits -i 16\n" ) ) { comms } comms each to vals vals 0 array-ref check-file-name to fsnd fsnd file-exists? if fsnd mus-sound-comment ( res ) vals 1 array-ref ( req ) "mus-sound-comment %s" #( fsnd ) snd-test-neq then end-each \ "traffic.aiff" check-file-name to fsnd fsnd file-exists? if fsnd mus-sound-comment to res res string? unless "mus-sound-comment traffic: %s?" #( res ) snd-display then then \ *clmtest* 0= if mal cadr 0.14724 "oboe: mus-sound-maxamp" #() snd-test-neq mal car 24971 "oboe: mus-sound-maxamp at" #() snd-test-neq then \ oboe-snd mus-sound-type-specifier to res \ 0x646e732e little endian reader \ 0x2e736e64 big endian reader res 0x646e732e d<> res 0x2e736e64 d<> && if "oboe: mus-sound-type-specifier: %#x?" #( res ) snd-display then "%d-%b-%Y %H:%M" oboe-snd file-write-date strftime "15-Oct-2006 04:34" "oboe: file-write-date" #() snd-test-neq \ 0 { lasth } begin lasth 1+ to lasth lasth mus-header-type-name "unknown" string= until lasth 50 < if "header-type[%d] = %s?" #( lasth dup mus-header-type-name ) snd-display then 0 to lasth begin lasth 1+ to lasth lasth mus-sample-type-name "unknown" string= until lasth 10 < if "sample-type[%d] = %s?" #( lasth dup mus-sample-type-name ) snd-display then nil { name } #( 'dont-normalize 'normalize-globally 'normalize-by-channel ) each symbol-name to name name string-eval to req req set-transform-normalization drop transform-normalization req "set-transform-normalization %s" #( name ) snd-test-neq end-each \ "fmv.snd" 1 22050 mus-bshort mus-next "set-samples test" 100 new-sound to ind 10 3 3 0.1 make-vct set-samples drop 0 20 ind 0 channel->vct vct( 0 0 0 0 0 0 0 0 0 0 0.1 0.1 0.1 0 0 0 0 0 0 0 ) "1 set samples 0 for 0.1" #() snd-test-neq 20 3 3 0.1 make-vct ind 0 set-samples drop 10 20 ind 0 channel->vct vct( 0.1 0.1 0.1 0 0 0 0 0 0 0 0.1 0.1 0.1 0 0 0 0 0 0 0 ) "2 set samples 10 for 0.1" #() snd-test-neq 30 3 3 0.1 make-vct ind 0 #f "a name" set-samples drop 20 20 ind 0 channel->vct vct( 0.1 0.1 0.1 0 0 0 0 0 0 0 0.1 0.1 0.1 0 0 0 0 0 0 0 ) "3 set samples 20 for 0.1" #() snd-test-neq 0 3 3 0.2 make-vct ind 0 #f "a name" 0 1 set-samples drop 0 20 ind 0 channel->vct vct( 0.2 0.2 0.2 0 0 0 0 0 0 0 0.1 0.1 0.1 0 0 0 0 0 0 0 ) "4 set samples 0 at 1 for 0.1" #() snd-test-neq 20 20 ind 0 channel->vct 20 0.0 make-vct "5 set samples 20 at 1 for 0.1" #() snd-test-neq "fmv1.snd" :channels 2 new-sound { nd } 10 0.5 make-vct 0 10 nd 0 vct->channel drop 10 0.3 make-vct 0 10 nd 1 vct->channel drop "fmv1.snd" nd save-sound-as drop nd close-sound drop "fmv1.snd" file-exists? unless "fmv1.snd not saved??" #() snd-display then 0 10 "fmv1.snd" ind 0 #f "another name" 1 set-samples drop 0 20 ind 0 channel->vct vct( 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.1 0.1 0.1 0 0 0 0 0 0 0 ) "6 set samples 0 at 1 for 0.1" #() snd-test-neq 5 6 "fmv1.snd" ind 0 #f "another name 7" 0 set-samples drop 0 20 ind 0 channel->vct vct( 0.3 0.3 0.3 0.3 0.3 0.5 0.5 0.5 0.5 0.5 0.5 0.1 0.1 0 0 0 0 0 0 0 ) "7 set samples 0 at 1 for 0.1" #() snd-test-neq 0 10 "fmv1.snd" ind 0 #f "another name 8" 1 0 #f set-samples drop 0 20 ind 0 channel->vct vct( 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0 0 0 0 0 0 0 0 0 0 ) "8 set samples 0 at 1 for 0.1" #() snd-test-neq 10 10 "fmv1.snd" ind 0 #f "another name 9" 0 0 set-samples drop 0 20 ind 0 channel->vct vct( 0 0 0 0 0 0 0 0 0 0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 ) "9 set samples 0 at 1 for 0.1" #() snd-test-neq 20 10 "fmv1.snd" set-samples drop 10 20 ind 0 channel->vct 20 0.5 make-vct "10 set samples 0 at 1 for 0.1" #() snd-test-neq 0 10 "fmv1.snd" ind 0 #t "another name" 1 0 #f set-samples drop ind 0 framples 10 "11 set samples truncate" #() snd-test-neq ind revert-sound drop "fmv1.snd" file-delete \ ;; now try to confuse it 0 10 "fmv1.snd" ind 0 <'> set-samples snd-test-catch to res res car 'no-such-file "set-samples, no such file" #() snd-test-neq "fmv1.snd" :channels 1 new-sound to nd "fmv1.snd" nd save-sound-as drop nd close-sound drop 0 10 "fmv1.snd" ind 0 #f "another name" 1 <'> set-samples snd-test-catch to res res car 'no-such-channel "set-samples no such channel" #() snd-test-neq 0 10 "fmv1.snd" ind 0 #f "another name" -1 <'> set-samples snd-test-catch to res res car 'no-such-channel "set-samples no such channel (-1)" #() snd-test-neq 0 -10 "fmv1.snd" <'> set-samples snd-test-catch to res res car 'wrong-type-arg "set-samples (-10)" #() snd-test-neq -10 10 "fmv1.snd" <'> set-samples snd-test-catch to res res car 'no-such-sample "set-samples (beg -10)" #() snd-test-neq ind close-sound drop \ 100 { len } #( #( mus-bshort 2 -15 f** ) #( mus-lshort 2 -15 f** ) #( mus-mulaw 0.02 ) #( mus-alaw 0.02 ) #( mus-byte 2 -7 f** ) #( mus-lfloat 2 -23 f** ) #( mus-bint 2 -23 f** ) #( mus-lint 2 -23 f** ) #( mus-b24int 2 -23 f** ) #( mus-l24int 2 -23 f** ) #( mus-ubshort 2 -15 f** ) #( mus-ulshort 2 -15 f** ) #( mus-ubyte 2 -7 f** ) #( mus-bfloat 2 -23 f** ) #( mus-bdouble 2 -23 f** ) #( mus-ldouble 2 -23 f** ) ) { types } nil nil nil nil nil nil { v v0 v1 diff maxdiff maxpos } nil nil nil { typ allowed-diff val } types each to vals vals 0 array-ref to typ vals 1 array-ref to allowed-diff "test.snd" 1 22050 mus-bfloat mus-next new-sound to ind len 0.0 make-vct to v 0.0 to maxdiff #f to maxpos v 0 0.999 vct-set! drop v 1 -1.000 vct-set! drop v 2 0.100 vct-set! drop v 3 -0.100 vct-set! drop v 4 0.010 vct-set! drop v 5 -0.010 vct-set! drop v 6 0.001 vct-set! drop v 7 -0.001 vct-set! drop v 8 0.000 vct-set! drop len 7 do 1.9999 random to val val 2.0 f> val 0.0 f< || if "random 2.0 -> %s?" #( val ) snd-display then v i 1.0 val f- vct-set! drop loop v 0 len ind 0 vct->channel drop "test1.snd" ind :header-type mus-next :sample-type typ save-sound-as drop ind close-sound drop "test1.snd" open-sound to ind 0 len ind 0 channel->vct to v1 len 0 do v i vct-ref v1 i vct-ref f- fabs to diff diff maxdiff f> if diff to maxdiff i to maxpos then loop maxdiff allowed-diff f> if "%s: %s at %d (%s %s)?" #( typ mus-sample-type-name maxdiff maxpos v maxpos vct-ref v1 maxpos vct-ref ) snd-display then ind close-sound drop end-each \ oboe-snd view-sound { ob } 1000 ob sample { samp } oboe-snd mus-sound-comment { old-comment } "written %s" #( "%a %d-%b-%Y %H:%M %Z" current-time strftime ) string-format { str } ob str set-comment drop "test.snd" ob :header-type mus-aifc :sample-type mus-bdouble <'> save-sound-as snd-test-catch to res res car 'cannot-save "save-sound-as test.snd write trouble" #() snd-test-eq #t set-filter-control-in-hz drop "test.snd" open-sound { ab } ab mus-aifc mus-bdouble samp sndlib-check-it "test.snd" mus-sound-comment str "output-comment" #() snd-test-neq ab comment str "output-comment (comment)" #() snd-test-neq ab close-sound drop oboe-snd mus-sound-comment old-comment "set-comment overwrote current" #() snd-test-neq #f set-filter-control-in-hz drop \ "test.snd" ob :header-type mus-raw save-sound-as drop "test.snd" 1 22050 mus-bshort open-raw-sound to ab ab mus-raw mus-bshort samp sndlib-check-it ab close-sound drop \ "test.snd" ob :header-type mus-nist :sample-type mus-bint save-sound-as drop "test.snd" open-sound to ab ab mus-nist mus-bint samp sndlib-check-it ab close-sound drop \ output-comment-hook reset-hook! output-comment-hook <'> sndlib-check-string add-hook! "test.snd" ob :header-type mus-riff :sample-type mus-lfloat save-sound-as drop output-comment-hook reset-hook! "test.snd" open-sound to ab ab mus-riff mus-lfloat samp sndlib-check-it ab comment str " [written by me]" $+ "output-comment-hook" #() snd-test-neq ab close-sound drop #( #( mus-aiff mus-b24int ) #( mus-ircam mus-mulaw ) #( mus-next mus-alaw ) #( mus-next mus-ldouble ) ) to types nil { fmt } types each to vals vals 0 array-ref to typ vals 1 array-ref to fmt "test.snd" ob :header-type typ :sample-type fmt save-sound-as drop "test.snd" open-sound to ab ab typ fmt samp sndlib-check-it ab close-sound drop end-each "test.snd" ob :header-type mus-next :sample-type mus-bshort save-sound-as drop "test.snd" open-sound to ab ab mus-next mus-bshort samp sndlib-check-it update-hook reset-hook! '( -3.0 3.0 ) ab 0 set-y-bounds drop ab mus-lshort set-sample-type drop \ ; these set!'s can change the index via update-sound "test.snd" find-sound to ab ab sample-type to fmt fmt mus-lshort "set-sample-type %s" #( fmt mus-sample-type-name ) snd-test-neq ab 0 y-bounds '( -3.0 3.0 ) "set data format y-bounds" #() snd-test-neq '( 2.0 ) ab 0 set-y-bounds drop ab 0 y-bounds '( -2.0 2.0 ) "set data format y-bounds 1" #() snd-test-neq '( -2.0 ) ab 0 set-y-bounds drop ab 0 y-bounds '( -2.0 2.0 ) "set data format y-bounds -2" #() snd-test-neq ab mus-aifc set-header-type drop "test.snd" find-sound to ab ab header-type mus-aifc "set-header-type" #() snd-test-neq ab 3 set-channels drop "test.snd" find-sound to ab ab channels 3 "set-channels" #() snd-test-neq ab 1234 set-data-location drop "test.snd" find-sound to ab ab data-location 1234 "set-data-location" #() snd-test-neq ab data-size { old-size } ab 1234 set-data-size drop "test.snd" find-sound to ab ab data-size 1234 "set-data-size" #() snd-test-neq ab old-size set-data-size drop ab 12345 set-srate drop "test.snd" find-sound to ab ab srate 12345 "set-srate" #() snd-test-neq ab close-sound drop \ "test.snd" ob :header-type mus-next :sample-type mus-bfloat save-sound-as drop "test.snd" open-sound to ab ab mus-next mus-bfloat samp sndlib-check-it ab close-sound drop \ "test.snd" ob :header-type mus-next :sample-type mus-bshort save-sound-as drop ob close-sound drop "test.snd" open-sound to ab mus-lshort set-sample-type drop "test.snd" find-sound to ab sample-type mus-lshort "set-sample-type" #() snd-test-neq mus-aifc set-header-type drop "test.snd" find-sound to ab header-type mus-aifc "set-header-type" #() snd-test-neq 3 set-channels drop "test.snd" find-sound to ab channels 3 "set-channels" #() snd-test-neq 1234 set-data-location drop "test.snd" find-sound to ab data-location 1234 "set-data-location" #() snd-test-neq 12345 set-srate drop "test.snd" find-sound to ab srate 12345 "set-srate" #() snd-test-neq ab close-sound drop \ "2a.snd" open-sound to ind "test.snd" :sample-type mus-l24int :header-type mus-riff :channel 0 save-sound-as drop "test.snd" open-sound { ind0 } ind0 channels 1 "save-sound-as :channel 0 chans" #() snd-test-neq ind0 sample-type mus-l24int "save-sound-as :channel 0 sample-type" #() snd-test-neq ind0 header-type mus-riff "save-sound-as :channel 0 header-type" #() snd-test-neq ind0 srate ind srate "save-sound-as :channel 0 srates" #() snd-test-neq ind0 framples ind 0 undef framples "save-sound-as :channel 0 framples" #() snd-test-neq ind0 maxamp ind 0 undef maxamp "save-sound-as :channel 0 maxamps" #() snd-test-neq ind0 close-sound drop \ "test.snd" :sample-type mus-bfloat :header-type mus-aifc :channel 1 :srate 12345 save-sound-as drop "test.snd" open-sound to ind0 ind0 channels 1 "save-sound-as :channel 1 chans" #() snd-test-neq ind0 sample-type mus-bfloat "save-sound-as :channel 1 sample-type" #() snd-test-neq ind0 header-type mus-aifc "save-sound-as :channel 1 header-type" #() snd-test-neq ind0 srate 12345 "save-sound-as :channel 1 srates" #() snd-test-neq ind0 framples ind 1 undef framples "save-sound-as :channel 1 framples" #() snd-test-neq ind0 maxamp ind 1 undef maxamp "save-sound-as :channel 1 maxamps" #() snd-test-neq ind0 close-sound drop \ "test.snd" :channel 1 :comment "this is a test" save-sound-as drop "test.snd" open-sound to ind0 ind0 channels 1 "save-sound-as :channel 1 (1) chans" #() snd-test-neq ind0 sample-type ind sample-type "save-sound-as :channel 1 (1) sample-type" #() snd-test-neq ind0 header-type ind header-type "save-sound-as :channel 1 (1) header-type" #() snd-test-neq ind0 srate ind srate "save-sound-as :channel 1 (1) srates" #() snd-test-neq ind0 framples ind 1 undef framples "save-sound-as :channel 1 (1) framples" #() snd-test-neq ind0 0 maxamp ind 1 undef maxamp "save-sound-as :channel 1 (1) maxamps" #() snd-test-neq ind0 comment "this is a test" "save-sound-as :channel 1 (1) comment" #() snd-test-neq ind0 close-sound drop ind close-sound drop \ "t15.aiff" check-file-name to fsnd fsnd file-exists? if fsnd open-sound to ind 132300 ind 0 sample 0.148 "aifc sowt trouble (0)" #() snd-test-neq 132300 ind 1 sample 0.126 "aifc sowt trouble (1)" #() snd-test-neq ind close-sound drop then "M1F1-float64C-AFsp.aif" check-file-name to fsnd fsnd file-exists? if fsnd open-sound to ind 8000 ind 0 sample -0.024 "aifc fl64 trouble (0)" #() snd-test-neq 8000 ind 1 sample 0.021 "aifc fl64 trouble (1)" #() snd-test-neq ind close-sound drop then \ #( #( "bad_chans.snd" 0 22050 0 ) #( "bad_srate.snd" 1 0 0 ) #( "bad_data_format.snd" 1 22050 4411 ) #( "bad_chans.aifc" 0 22050 0 ) #( "bad_srate.aifc" 1 0 0 ) #( "bad_length.aifc" 1 22050 -10 ) #( "bad_chans.riff" 0 22050 0 ) #( "bad_srate.riff" 1 0 0 ) #( "bad_chans.nist" 0 22050 0 ) #( "bad_srate.nist" 1 0 0 ) #( "bad_length.nist" 1 22050 -10 ) ) { files } nil nil nil { fc fs fr } files each to vals vals 0 array-ref check-file-name to fsnd vals 1 array-ref to fc vals 2 array-ref to fs vals 3 array-ref to fr fsnd file-exists? if fsnd <'> mus-sound-chans #t nil fth-catch ?dup-if car 'mus-error <> if "%s: chans %d (%s)" #( fsnd fc res ) snd-display then else fc <> if "%s: chans %d (%s)" #( fsnd fc res ) snd-display then stack-reset then \ fsnd <'> mus-sound-srate #t nil fth-catch ?dup-if car 'mus-error <> if "%s: srate %d (%s)" #( fsnd fs res ) snd-display then stack-reset else fs <> if "%s: srate %d (%s)" #( fsnd fs res ) snd-display then then \ fsnd <'> mus-sound-framples #t nil fth-catch ?dup-if car 'mus-error <> if "%s: framples %d (%s)" #( fsnd fr res ) snd-display then stack-reset else fr <> if "%s: framples %d (%s)" #( fsnd fr res ) snd-display then then then \ file-exists? end-each \ "/usr/include/sys/" file-pwd $+ "/oboe.snd" $+ <'> open-sound #t nil fth-catch ?dup-if 1 >list "open-sound with slashes: %s" swap snd-display stack-reset else \ open-sound with slashes to ind ind sound? if ind short-file-name "oboe.snd" string<> if "open-sound with slashes: %s" #( ind short-file-name ) snd-display then else "open-sound with slashes: %s" #( ind ) snd-display then bad-header-hook <'> sndlib-true-cb add-hook! #( "bad_chans.snd" "bad_srate.snd" "bad_chans.aifc" "bad_srate.aifc" "bad_length.aifc" "bad_chans.riff" "bad_srate.riff" "bad_chans.nist" "bad_location.nist" "bad_field.nist" "bad_srate.nist" "bad_length.nist" ) each check-file-name to fsnd fsnd file-exists? if fsnd <'> insert-sound snd-test-catch drop fsnd <'> convolve-with snd-test-catch drop fsnd <'> mix snd-test-catch drop fsnd <'> sndlib-check-bad-file snd-test-catch drop then end-each ind close-sound drop then \ open-sound with slashes sounds each ( snd ) close-sound end-each \ #( "trunc.snd" "trunc.aiff" "trunc.wav" "trunc.sf" "trunc.voc" "trunc.nist" "bad.wav" "trunc1.aiff" "badform.aiff" ) each check-file-name to fsnd fsnd file-exists? if fsnd <'> open-sound snd-test-catch to res res car 'mus-error "open-sound" #() snd-test-neq then end-each open-raw-sound-hook <'> sndlib-raw-hook-cb add-hook! "empty.snd" check-file-name to fsnd fsnd file-exists? if fsnd open-sound to ind ind sample-type mus-bshort "open raw sample-type" #() snd-test-neq ind chans 1 "open raw chans" #() snd-test-neq ind srate 22050 "open raw srate" #() snd-test-neq ind data-location 0 "open raw data-location" #() snd-test-neq ind framples 0 "open raw framples" #() snd-test-neq ind close-sound drop then open-raw-sound-hook reset-hook! \ #f set-clipping drop "test.snd" :sample-type mus-lshort new-sound { snd } 0 10 pad-channel drop 1 1.0000 set-sample drop 2 -1.0000 set-sample drop 3 0.9999 set-sample drop 4 2.0000 set-sample drop 5 -2.0000 set-sample drop 6 1.3000 set-sample drop 7 -1.3000 set-sample drop 8 1.8000 set-sample drop 9 -1.8000 set-sample drop snd save-sound drop snd close-sound drop "test.snd" open-sound to snd 0 10 channel->vct vct( 0.000 1.000 -1.000 1.000 0.000 0.000 -0.700 0.700 -0.200 0.200 ) "unclipped 1" #() snd-test-neq snd close-sound drop "test.snd" mus-sound-forget drop \ #t set-clipping drop "test.snd" :sample-type mus-lshort new-sound to snd 0 10 pad-channel drop 1 1.0000 set-sample drop 2 -1.0000 set-sample drop 3 0.9999 set-sample drop 4 2.0000 set-sample drop 5 -2.0000 set-sample drop 6 1.3000 set-sample drop 7 -1.3000 set-sample drop 8 1.8000 set-sample drop 9 -1.8000 set-sample drop snd save-sound drop snd close-sound drop "test.snd" open-sound to snd 0 10 channel->vct vct( 0.000 1.000 -1.000 1.000 1.000 -1.000 1.000 -1.000 1.000 -1.000 ) "clipped" #() snd-test-neq snd close-sound drop \ #( #( "next-dbl.snd" 10 10 vct( 0.475 0.491 0.499 0.499 0.492 0.476 0.453 0.423 0.387 0.344 ) ) #( "oboe.ldbl" 1000 10 vct( 0.033 0.035 0.034 0.031 0.026 0.020 0.013 0.009 0.005 0.004 ) ) #( "next-flt.snd" 10 10 vct( 0.475 0.491 0.499 0.499 0.492 0.476 0.453 0.423 0.387 0.344 ) ) #( "clbonef.wav" 1000 10 vct( 0.111 0.101 0.07 0.032 -0.014 -0.06 -0.085 -0.108 -0.129 -0.152 ) ) #( "next-8.snd" 10 10 vct( 0.898 0.945 0.977 0.992 0.992 0.977 0.945 0.906 0.844 0.773 ) ) #( "o2_u8.wave" 1000 10 vct( -0.164 -0.219 -0.258 -0.242 -0.18 -0.102 -0.047 0.0 0.039 0.055 ) ) #( "next-16.snd" 1000 10 vct( -0.026 -0.022 -0.024 -0.03 -0.041 -0.048 -0.05 -0.055 -0.048 -0.033 ) ) #( "o2.wave" 1000 10 vct( -0.160 -0.216 -0.254 -0.239 -0.175 -0.102 -0.042 0.005 0.041 0.059 ) ) #( "o2_18bit.aiff" 1000 10 vct( -0.160 -0.216 -0.254 -0.239 -0.175 -0.102 -0.042 0.005 0.041 0.059 ) ) #( "o2_12bit.aiff" 1000 10 vct( -0.160 -0.216 -0.254 -0.239 -0.175 -0.102 -0.042 0.005 0.041 0.059 ) ) #( "next24.snd" 1000 10 vct( -0.160 -0.216 -0.254 -0.239 -0.175 -0.102 -0.042 0.005 0.041 0.059 ) ) #( "mono24.wav" 1000 10 vct( 0.005 0.010 0.016 0.008 -0.007 -0.018 -0.025 -0.021 -0.005 0.001 ) ) #( "o2_711u.wave" 1000 10 vct( -0.164 -0.219 -0.254 -0.242 -0.172 -0.103 -0.042 0.005 0.042 0.060 ) ) #( "alaw.wav" 1000 10 vct( -0.024 -0.048 -0.024 0.0 0.008 0.008 0.000 -0.040 -0.064 -0.024 ) ) \ ;; it is not a bug if these don't match if MUS_SAMPLE_BITS is not 24 #( "b32.pvf" 1000 10 vct( -0.160 -0.216 -0.254 -0.239 -0.175 -0.102 -0.042 0.005 0.041 0.059 ) ) #( "b32.wave" 1000 10 vct( -0.160 -0.216 -0.254 -0.239 -0.175 -0.102 -0.042 0.005 0.041 0.059 ) ) #( "b32.snd" 1000 10 vct( -0.160 -0.216 -0.254 -0.239 -0.175 -0.102 -0.042 0.005 0.041 0.059 ) ) #( "32bit.sf" 1000 10 vct( 0.016 0.014 0.013 0.011 0.010 0.010 0.010 0.010 0.012 0.014 ) ) #( "nist-shortpack.wav" 10000 10 vct( 0.021 0.018 0.014 0.009 0.004 -0.001 -0.004 -0.006 -0.007 -0.008 ) ) #( "wood.sds" 1000 10 vct( -0.160 -0.216 -0.254 -0.239 -0.175 -0.102 -0.042 0.005 0.041 0.059 ) ) #( "mus10.snd" 10000 10 vct( 0.004 0.001 0.005 0.009 0.017 0.015 0.008 0.011 0.009 0.012 ) ) #( "ieee-text-16.snd" 1000 10 vct( -0.052 -0.056 -0.069 -0.077 -0.065 -0.049 -0.054 -0.062 -0.066 -0.074 ) ) #( "hcom-16.snd" 10000 10 vct( 0.000 0.000 0.000 0.008 0.000 -0.016 -0.016 -0.016 -0.008 0.000 ) ) #( "ce-c3.w02" 1000 10 vct( 0.581 0.598 0.596 0.577 0.552 0.530 0.508 0.479 0.449 0.425 ) ) #( "nasahal.avi" 20000 10 vct( 0.390 0.120 -0.399 -0.131 0.464 0.189 -0.458 -0.150 0.593 0.439 ) ) #( "oki.wav" 100 10 vct( 0.396 0.564 0.677 0.779 0.761 0.540 0.209 -0.100 -0.301 -0.265 ) ) #( "trumps22.adp" 5000 10 vct( 0.267 0.278 0.309 0.360 0.383 0.414 0.464 0.475 0.486 0.495 ) ) ) to files nil nil nil nil { file beg dur data } files each to vals vals 0 array-ref to file vals 1 array-ref to beg vals 2 array-ref to dur vals 3 array-ref to data file check-file-name to fsnd fsnd file-exists? if fsnd open-sound to ind beg dur ind 0 channel->vct data "%s" #( file ) snd-test-neq ind close-sound drop then end-each \ #( "no error" "no frequency method" "no phase method" "null gen arg to method" "no length method" "no describe method" "no data method" "no scaler method" "memory allocation failed" "can't open file" "no sample input" "no sample output" "no such channel" "no file name provided" "no location method" "no channel method" "no such fft window" "unknown sample type" "header read failed" "unknown header type" "file descriptors not initialized" "not a sound file" "file closed" "write error" "header write failed" "can't open temp file" "interrupted" "bad envelope" "audio channels not available" "audio srate not available" "audio sample type not available" "no audio input available" "audio configuration not available" "audio write error" "audio size not available" "audio device not available" "can't close audio" "can't open audio" "audio read error" "can't write audio" "can't read audio" "no audio read permission" "can't close file" "arg out of range" "no channels method" "no hop method" "no width method" "no file-name method" "no ramp method" "no run method" "no increment method" "no offset method" "no xcoeff method" "no ycoeff method" "no xcoeffs method" "no ycoeffs method" "no reset" "bad size" "can't convert" "read error" "no feedforward method" "no feedback method" "no interp-type method" "no position method" "no order method" "no copy method" "can't translate" ) each ( err ) i mus-error-type->string "mus-error-type->string[%d]" #( i ) snd-test-neq end-each \ "oboe.snd" mus-sound-srate { cur-srate } "oboe.snd" mus-sound-chans { cur-chans } "oboe.snd" mus-sound-sample-type { cur-format } "oboe.snd" mus-sound-header-type { cur-type } "oboe.snd" mus-sound-data-location { cur-loc } "oboe.snd" mus-sound-samples { cur-samps } "oboe.snd" cur-srate 2* set-mus-sound-srate drop "oboe.snd" mus-sound-srate cur-srate 2* "set-mus-sound-srate" #() snd-test-neq "oboe.snd" cur-samps 2* set-mus-sound-samples drop "oboe.snd" mus-sound-samples cur-samps 2* "set-mus-sound-samples" #() snd-test-neq "oboe.snd" cur-chans 2* set-mus-sound-chans drop "oboe.snd" mus-sound-chans cur-chans 2* "set-mus-sound-chans" #() snd-test-neq "oboe.snd" cur-loc 2* set-mus-sound-data-location drop "oboe.snd" mus-sound-data-location cur-loc 2* "set-mus-sound-data-location" #() snd-test-neq "oboe.snd" mus-nist set-mus-sound-header-type drop "oboe.snd" mus-sound-header-type mus-nist "set-mus-sound-header-type" #() snd-test-neq "oboe.snd" mus-lintn set-mus-sound-sample-type drop "oboe.snd" mus-sound-sample-type mus-lintn "set-mus-sound-sample-type" #() snd-test-neq "oboe.snd" cur-srate set-mus-sound-srate drop "oboe.snd" cur-samps set-mus-sound-samples drop "oboe.snd" cur-chans set-mus-sound-chans drop "oboe.snd" cur-loc set-mus-sound-data-location drop "oboe.snd" cur-type set-mus-sound-header-type drop "oboe.snd" cur-format set-mus-sound-sample-type drop \ "oboe.snd" open-sound to ind "test.wave" ind :header-type mus-riff save-sound-as drop "test.rf64" ind :header-type mus-rf64 save-sound-as drop "test.aifc" ind :header-type mus-aifc save-sound-as drop ind close-sound drop \ #( "test.wave" "test.rf64" "test.aifc" ) each to file file mus-sound-srate to cur-srate file mus-sound-chans to cur-chans file mus-sound-sample-type to cur-format file mus-sound-header-type to cur-type file mus-sound-data-location to cur-loc file mus-sound-samples to cur-samps file cur-srate 2* set-mus-sound-srate drop file mus-sound-srate cur-srate 2* "%s set-mus-sound-srate" #( file ) snd-test-neq file cur-samps 2* set-mus-sound-samples drop file mus-sound-samples cur-samps 2* "%s set-mus-sound-samples" #( file ) snd-test-neq file cur-chans 2* set-mus-sound-chans drop file mus-sound-chans cur-chans 2* "%s set-mus-sound-chans" #( file ) snd-test-neq file cur-loc 2* set-mus-sound-data-location drop file mus-sound-data-location cur-loc 2* "%s set-mus-sound-data-location" #( file ) snd-test-neq file mus-nist set-mus-sound-header-type drop file mus-sound-header-type mus-nist "%s set-mus-sound-header-type" #( file ) snd-test-neq file mus-lintn set-mus-sound-sample-type drop file mus-sound-sample-type mus-lintn "%s set-mus-sound-sample-type" #( file ) snd-test-neq file cur-srate set-mus-sound-srate drop file cur-samps set-mus-sound-samples drop file cur-chans set-mus-sound-chans drop file cur-loc set-mus-sound-data-location drop file cur-type set-mus-sound-header-type drop file cur-format set-mus-sound-sample-type drop end-each #( "test.wave" "test.rf64" "test.aifc" ) each to file file open-sound to ind ind srate to cur-srate ind chans to cur-chans ind sample-type to cur-format ind header-type to cur-type ind data-location to cur-loc ind framples to cur-samps ind cur-srate 2* set-srate drop ind srate cur-srate 2* "%s set-srate" #( ind file-name ) snd-test-neq cur-samps 2* ind set-framples drop ind framples cur-samps 2* "%s set-framples" #( ind file-name ) snd-test-neq ind cur-chans 2* set-chans drop \ ; this can change the index file find-sound to ind ind chans cur-chans 2* "%s set-chans" #( ind file-name ) snd-test-neq ind cur-loc 2* set-data-location drop ind data-location cur-loc 2* "%s set-data-location" #( ind file-name ) snd-test-neq ind mus-nist set-header-type drop ind header-type mus-nist "%s set-header-type" #( ind file-name ) snd-test-neq ind mus-lintn set-sample-type drop ind sample-type mus-lintn "%s set-sample-type" #( ind file-name ) snd-test-neq ind cur-srate set-srate drop cur-samps ind set-framples drop ind cur-chans set-chans drop ind cur-loc set-data-location drop ind cur-type set-header-type drop ind cur-format set-sample-type drop ind close-sound drop file file-delete end-each with-big-file if bigger-snd file-exists? if \ ; silence as last .9 secs, so it probably wasn't written 44100 71999.1 f* floor f>d { probable-framples } 3175160310 { our-framples } 6350320648 { our-length } bigger-snd mus-sound-samples our-framples "bigger samples" #() snd-test-neq bigger-snd mus-sound-framples our-framples "bigger framples" #() snd-test-neq bigger-snd mus-sound-framples probable-framples <'> d= "bigger framples (probable)" #() snd-test-any-neq bigger-snd mus-sound-length our-length "bigger bytes" #() snd-test-neq bigger-snd mus-sound-duration 71999.1015 "bigger dur" #() snd-test-neq bigger-snd open-sound to ind ind framples our-framples "bigger framples" #() snd-test-neq ind framples to big-file-framples big-file-framples probable-framples <'> d= "bigger framples (probable)" #() snd-test-any-neq big-file-framples ind 0 0 framples "bigger edpos-framples" #() snd-test-neq 44100 50000 d* ind add-mark to m1 m1 mark-sample 44100 50000 d* "bigger mark at" #() snd-test-neq m1 44100 66000 d* set-mark-sample drop m1 mark-sample 44100 66000 d* "bigger mark to" #() snd-test-neq "oboe.snd" 44100 60000 d* mix-sound car { mx } mx mix? if mx mix-position 44100 60000 d* "bigger mix at" #() snd-test-neq mx 44100 61000 d* set-mix-position drop mx mix-position 44100 61000 d* "bigger mix to" #() snd-test-neq else "no mix tag from mix-sound" #() snd-display then 2 undo drop <'> f0<> 1 make-proc find-channel to res res false? res 100 > || if "bigger find not 0.0: %s" #( res ) snd-display then selection-creates-region { old-select } #f set-selection-creates-region drop ind select-all drop selection-framples ind 0 undef framples "bigger select all" #() snd-test-neq 44100 50000 d* set-selection-position drop selection-position 44100 50000 d* "bigger select pos" #() snd-test-neq 0 set-selection-position drop 44100 65000 d* set-selection-framples drop selection-framples 44100 65000 d* "bigger select len" #() snd-test-neq old-select set-selection-creates-region drop 44100 50000 d* ind set-cursor drop ind cursor 44100 50000 d* "bigger cursor" #() snd-test-neq 44123 51234 d* ind add-mark to m1 m1 mark-sample 44123 51234 d* "bigger mark at" #() snd-test-neq 44123 51234 d* find-mark { mid } mid m1 "bigger mark seach" #() snd-test-neq "oboe.snd" 44123 61234 d* mix-sound car to mx 44123 61234 d* find-mix { mxd } mxd mx "bigger find-mix" #() snd-test-neq 44123 51234 d* ind set-cursor drop ind cursor 44123 51234 d* "bigger cursor 123" #() snd-test-neq ind close-sound drop else \ bigger-snd not file-exists? "no such bigger file %s" #( bigger-snd ) snd-display then \ bigger-snd file-exists? then \ with-big-file \ "tmp.snd" 1 22050 mus-l24int mus-riff :size 100000 new-sound to ind selection-creates-region { old-selection-creates-region } #t set-selection-creates-region drop undef undef undef framples to len len 1/f { incr } -0.5 ( x ) len 0.0 make-vct map! ( x ) incr f+ dup end-map ( data ) 0 len undef undef undef "" vct->channel drop ( x ) drop save-sound drop ind close-sound drop "tmp.snd" open-sound to ind select-all { reg } "tmp1.snd" 22050 mus-l24int mus-next save-selection drop "tmp1.snd" open-sound { ind1 } -0.5 undef undef undef framples 1/f sndlib-test-scan-x-cb 0 100000 ind1 scan-channel to res res #f "l24 (next) selection not saved correctly" #() snd-test-neq ind1 close-sound drop "tmp1.snd" 22050 mus-l24int mus-aifc save-selection drop "tmp1.snd" open-sound to ind1 -0.5 undef undef undef framples 1/f sndlib-test-scan-x-cb 0 100000 ind1 scan-channel to res res #f "l24 (aifc) selection not saved correctly" #() snd-test-neq ind1 close-sound drop reg "tmp1.snd" mus-l24int mus-next save-region drop "tmp1.snd" open-sound to ind1 -0.5 undef undef undef framples 1/f sndlib-test-scan-x-cb 0 100000 ind1 scan-channel to res res #f "l24 (next) region not saved correctly" #() snd-test-neq ind1 close-sound drop "tmp1.snd" file-delete ind close-sound drop "tmp.snd" file-delete old-selection-creates-region set-selection-creates-region drop \ "tmp.snd" 1 22050 mus-bfloat mus-next :size 10 :comment #f new-sound to ind <'> sndlib-test-map-set-1.0 map-channel drop '( 0 0 0.1 0.1 0.2 0.2 0.3 0.3 0.4 0.4 0.5 0.5 0.6 0.6 0.7 0.7 0.8 0.8 0.9 0.9 ) env-channel drop channel->vct vct( 0.000 0.100 0.200 0.300 0.400 0.500 0.600 0.700 0.800 0.900 ) "ramp env by 0.1" #() snd-test-neq ind close-sound drop ; : sndlib-hook-2-t#-cb <{ a b -- f }> #t ; : sndlib-hook-1-t#-cb <{ a -- f }> #t ; : make-aifc-file { frms auth-lo bits -- } "test.aif" make-file-output-port { io } io "FORM" port-write io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o146 port-putc \ len io "AIFCFVER" port-write io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o004 port-putc \ version chunk size io 0o242 port-putc io 0o200 port-putc io 0o121 port-putc io 0o100 port-putc \ version io "COMM" port-write io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o046 port-putc \ COMM chunk size io 0o000 port-putc io 0o001 port-putc \ 1 chan io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io frms port-putc \ framples io 0o000 port-putc io bits port-putc \ bits io 0o100 port-putc io 0o016 port-putc io 0o254 port-putc io 0o104 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc \ srate as 80-bit float (sheesh) io "NONE" port-write \ compression io 0o016 port-putc \ pascal string len io "not compressed" port-write io 0o000 port-putc io "AUTH" port-write io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io auth-lo port-putc \ AUTH chunk size io "bil" port-write io 0o000 port-putc io "SSND" port-write io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o014 port-putc \ SSND chunk size io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc \ SSND data loc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc \ block size? io 0o000 port-putc io 0o101 port-putc io 0o000 port-putc io 0o100 port-putc \ two samples io port-close ; : (04-sndlib-02) ( -- ) open-raw-sound-hook reset-hook! open-raw-sound-hook <'> sndlib-hook-2-t#-cb add-hook! bad-header-hook reset-hook! bad-header-hook <'> sndlib-hook-1-t#-cb add-hook! open-raw-sound-hook empty? if "add-hook open-raw-sound-hook failed??" #() snd-display then bad-header-hook empty? if "add-hook bad-header-hook failed??" #() snd-display then #( ".snd" "FORM" "AIFF" "AIFC" "COMM" "COMT" "INFO" "INST" "inst" "MARK" "SSND" "FVER" "NONE" "ULAW" "ulaw" "ima4" "raw " "sowt" "in32" "in24" "ni23" "fl32" "FL32" "fl64" "twos" "ALAW" "alaw" "APPL" "CLM " "RIFF" "RIFX" "WAVE" "fmt " "data" "fact" "clm " "NIST" "8SVX" "16SV" "Crea" "tive" "SOUN" "D SA" "MPLE" "BODY" "VHDR" "CHAN" "ANNO" "NAME" "2BIT" "HCOM" "FSSD" "%//\n" "%---" "ALaw" "Soun" "MAUD" "MHDR" "MDAT" "mdat" "MThd" "sfbk" "sdta" "shdr" "pdta" "LIST" "GF1P" "ATCH" "$SIG" "NAL_" "GOLD" " SAM" "SRFS" "Diam" "ondW" "CSRE" "SND " "SNIN" "SNDT" "DDSF" "FSMu" "UWFD" "LM89" "SY80" "SY85" "SCRS" "DSPL" "AVI " "strf" "movi" "PRAM" " paf" "fap " "DS16" "HEDR" "HDR8" "SDA_" "SDAB" "SD_B" "NOTE" "file" "=sam" "SU7M" "SU7R" "PVF1" "PVF2" "AUTH" "riff" "TWIN" "IMPS" "SMP1" "Maui" "SDIF" "NVF " ) { magic-words } magic-words length { len } nil nil nil nil { magic io res ind } magic-words each to magic open-raw-sound-hook empty? if "open-raw-sound-hook cleared??" #() snd-display then bad-header-hook empty? if "bad-header-hook cleared??" #() snd-display then "test.snd" file-delete "test.snd" mus-sound-forget drop \ ;; try random garbage "test.snd" make-file-output-port to io io magic port-write 128 0 do io "%f" #( 1.0 random ) port-write-format loop io port-close "test.snd" <'> open-sound #t nil fth-catch if stack-reset else to res res number? if res sound? if "open-sound garbage: %s %s" #( magic res ) snd-display res close-sound drop then then then "test.snd" file-delete "test.snd" mus-sound-forget drop \ ;; try plausible garbage "test.snd" make-file-output-port to io io magic port-write 128 0 do io "%d" #( 128 random f>s ) port-write-format loop io port-close "test.snd" <'> open-sound #t nil fth-catch if stack-reset else to res res number? if res sound? if "open-sound plausible garbage: %s %s" #( magic res ) snd-display res close-sound drop then then then "test.snd" file-delete "test.snd" mus-sound-forget drop \ ;; write very plausible garbage "test.snd" make-file-output-port to io io magic port-write 12 1 do io magic-words j ( ctr ) i + len < if j i + else i then array-ref port-write loop io port-close "test.snd" <'> open-sound #t nil fth-catch if stack-reset else to res res number? if res sound? if "open-sound very plausible garbage: %s %s" #( magic res ) snd-display res close-sound drop then then then end-each \ magic-words "test.snd" file-delete "test.snd" mus-sound-forget drop \ "test.snd" make-file-output-port to io io ".snd" port-write io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o034 port-putc \ location io 0o000 port-putc io 0o001 port-putc io 0o215 port-putc io 0o030 port-putc \ nominal size io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o022 port-putc \ format io 0o000 port-putc io 0o000 port-putc io 0o126 port-putc io 0o042 port-putc \ srate io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o001 port-putc \ chans io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc \ comment io 0o000 port-putc io 0o001 port-putc \ samp 1 io port-close "test.snd" mus-sound-sample-type mus-bshort "next 18" #() snd-test-neq "test.snd" file-delete "test.snd" mus-sound-forget drop \ "test.snd" make-file-output-port to io io ".snd" port-write io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o004 port-putc \ location io 0o000 port-putc io 0o001 port-putc io 0o215 port-putc io 0o030 port-putc \ nominal size io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o022 port-putc \ format io 0o000 port-putc io 0o000 port-putc io 0o126 port-putc io 0o042 port-putc \ srate io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o001 port-putc \ chans io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc \ comment io 0o000 port-putc io 0o001 port-putc \ samp 1 io port-close "test.snd" <'> open-sound #t nil fth-catch if stack-reset else to res res number? if res sound? if "open-sound next bad location %d: %s" #( res data-location res ) snd-display res close-sound drop then then then "test.snd" file-delete "test.snd" mus-sound-forget drop \ "test.snd" make-file-output-port to io io ".snd" port-write io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o034 port-putc \ location io 0o000 port-putc io 0o001 port-putc io 0o215 port-putc io 0o030 port-putc \ nominal size io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o122 port-putc \ format io 0o000 port-putc io 0o000 port-putc io 0o126 port-putc io 0o042 port-putc \ srate io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o001 port-putc \ chans io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc \ comment io 0o000 port-putc io 0o001 port-putc \ samp 1 io port-close "test.snd" <'> open-sound #t nil fth-catch if stack-reset else to res res sound? if "open-sound next bad format %s: %s" #( res sample-type res ) snd-display res close-sound drop then then "test.snd" file-delete "test.snd" mus-sound-forget drop "test.aif" file-delete "test.aif" mus-sound-forget drop \ ;;correct (make-aifc-file #o002 #o004 #o020) 0o102 0o004 0o020 make-aifc-file "test.aif" open-sound to ind ind framples 2 "bad framples in header" #() snd-test-neq ind close-sound drop "test.aif" file-delete "test.aif" mus-sound-forget drop \ 0o002 0o150 0o020 make-aifc-file "test.aif" <'> open-sound #t nil fth-catch if stack-reset else to res res sound? if "open-sound aifc no ssnd chunk %d: %s" #( res data-location res ) snd-display res close-sound drop then then "test.aif" file-delete "test.aif" mus-sound-forget drop \ 0o002 0o000 0o020 make-aifc-file "test.aif" <'> open-sound #t nil fth-catch if stack-reset else to res res sound? if "open-sound aifc 0-len auth chunk %d: %s" #( res data-location res ) snd-display res close-sound drop then then "test.aif" file-delete "test.aif" mus-sound-forget drop \ 0o002 0o150 0o120 make-aifc-file "test.aif" <'> open-sound #t nil fth-catch if stack-reset else to res res sound? if "open-sound bits 80 %s: %s" #( res sample-type res ) snd-display res close-sound drop then then "test.aif" file-delete "test.aif" mus-sound-forget drop \ "test.aif" make-file-output-port to io io "FORM" port-write io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o176 port-putc \ len io "AIFCFVER" port-write io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o004 port-putc \ version chunk size io 0o242 port-putc io 0o200 port-putc io 0o121 port-putc io 0o100 port-putc \ version io "COMM" port-write io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o046 port-putc \ COMM chunk size io 0o000 port-putc io 0o001 port-putc \ 1 chan io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o002 port-putc \ framples io 0o000 port-putc io 0o020 port-putc \ bits io 0o100 port-putc io 0o016 port-putc io 0o254 port-putc io 0o104 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc \ srate as 80-bit float (sheesh) io "NONE" port-write \ compression io 0o016 port-putc \ pascal string len io "not compressed" port-write io 0o000 port-putc io "AUTH" port-write io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o004 port-putc \ AUTH chunk size io "bil" port-write io 0o000 port-putc io "ANNO" port-write io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o004 port-putc \ AUTH chunk size io "cat" port-write io 0o000 port-putc io "NAME" port-write io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o004 port-putc \ AUTH chunk size io "dog" port-write io 0o000 port-putc io "SSND" port-write io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o014 port-putc \ SSND chunk size io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc \ SSND data loc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc \ block size? io 0o000 port-putc io 0o101 port-putc io 0o000 port-putc io 0o100 port-putc \ two samples io port-close "test.aif" mus-sound-comment length 15 "aifc 3 aux comments" #() snd-test-neq "test.aif" file-delete "test.aif" mus-sound-forget drop \ "test.aif" make-file-output-port to io io "FORM" port-write io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o142 port-putc \ len io "AIFC" port-write io "SSND" port-write io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o014 port-putc \ SSND chunk size io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc \ SSND data loc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc \ block size? io 0o000 port-putc io 0o101 port-putc io 0o000 port-putc io 0o100 port-putc \ two samples io "COMM" port-write io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o046 port-putc \ COMM chunk size io 0o000 port-putc io 0o001 port-putc \ 1 chan io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o002 port-putc \ framples io 0o000 port-putc io 0o020 port-putc \ bits io 0o100 port-putc io 0o016 port-putc io 0o254 port-putc io 0o104 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc \ srate as 80-bit float (sheesh) io "NONE" port-write \ compression io 0o016 port-putc \ pascal string len io "not compressed" port-write io 0o000 port-putc io "COMT" port-write io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o014 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io "bil" port-write io 0o000 port-putc io port-close "test.aif" mus-sound-comment 0 3 string-substring "bil" "aifc trailing comt comments" #() snd-test-neq "test.aif" mus-sound-framples 2 "aifc trailing comt framples" #() snd-test-neq "test.aif" open-sound to ind 0 sample { s0 } 1 sample { s1 } 2 sample { s2 } 3 sample { s3 } vct( s0 s1 s2 s3 ) vct( 0.00198 0.00195 0.0 0.0 ) "aifc trailing comt samps" #() snd-test-neq ind close-sound drop "test.aif" file-delete "test.aif" mus-sound-forget drop \ "test.aif" make-file-output-port to io io "FORM" port-write io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o142 port-putc \ len io "AIFC" port-write io "SSND" port-write io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o014 port-putc \ SSND chunk size io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc \ SSND data loc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc \ block size? io 0o000 port-putc io 0o101 port-putc io 0o000 port-putc io 0o100 port-putc \ two samples io "COMM" port-write io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o046 port-putc \ COMM chunk size io 0o000 port-putc io 0o001 port-putc \ 1 chan io 0o000 port-putc io 0o000 port-putc io 0o100 port-putc io 0o102 port-putc \ framples io 0o000 port-putc io 0o020 port-putc \ bits io 0o100 port-putc io 0o016 port-putc io 0o254 port-putc io 0o104 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc \ srate as 80-bit float (sheesh) io "NONE" port-write \ compression io 0o016 port-putc \ pascal string len io "not compressed" port-write io 0o000 port-putc io "COMT" port-write io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o014 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io "bil" port-write io 0o000 port-putc io port-close "test.aif" mus-sound-comment 0 3 string-substring "bil" "aifc trailing comt comments" #() snd-test-neq "test.aif" mus-sound-framples 2 "aifc trailing comt (bogus) framples" #() snd-test-neq "test.aif" open-sound to ind 0 sample to s0 1 sample to s1 2 sample to s2 3 sample to s3 vct( s0 s1 s2 s3 ) vct( 0.00198 0.00195 0.0 0.0 ) "aifc trailing comt samps (bogus frame setting)" #() snd-test-neq ind close-sound drop "test.aif" file-delete "test.aif" mus-sound-forget drop \ "test.aif" make-file-output-port to io io "FORM" port-write io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o142 port-putc \ len io "AIFC" port-write io "SSND" port-write io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o014 port-putc \ SSND chunk size io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc \ SSND data loc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc \ block size? io 0o000 port-putc io 0o101 port-putc io 0o000 port-putc io 0o100 port-putc \ two samples io "COMM" port-write io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o046 port-putc \ COMM chunk size io 0o000 port-putc io 0o001 port-putc \ 1 chan io 0o000 port-putc io 0o000 port-putc io 0o100 port-putc io 0o102 port-putc \ framples io 0o000 port-putc io 0o020 port-putc \ bits io 0o100 port-putc io 0o016 port-putc io 0o254 port-putc io 0o104 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc \ srate as 80-bit float (sheesh) io "NONE" port-write \ compression io 0o016 port-putc \ pascal string len io "not compressed" port-write io 0o000 port-putc io "SSND" port-write io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o014 port-putc \ SSND chunk size io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc \ SSND data loc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc \ block size? io 0o000 port-putc io 0o101 port-putc io 0o000 port-putc io 0o100 port-putc \ two samples io port-close "test.aif" <'> open-sound #t nil fth-catch if stack-reset else to res res sound? if "open-sound aifc 2 ssnd chunks %d: %s" #( res data-location res ) snd-display res close-sound drop then then "test.aif" file-delete "test.aif" mus-sound-forget drop \ "test.aif" make-file-output-port to io io "FORM" port-write io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o040 port-putc \ len io "AIFC" port-write io "SSND" port-write io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o014 port-putc \ SSND chunk size io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc \ SSND data loc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc \ block size? io 0o000 port-putc io 0o101 port-putc io 0o000 port-putc io 0o100 port-putc \ two samples io port-close "test.aif" <'> open-sound snd-test-catch to res res car 'mus-error "open-sound aifc no comm chunk: %s" #( res ) snd-test-neq sounds each ( snd ) close-sound drop end-each "test.aif" file-delete "test.aif" mus-sound-forget drop \ "test.aif" make-file-output-port to io \ write AIFC with trailing chunks to try to confuse file->sample io "FORM" port-write io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o176 port-putc \ len io "AIFCFVER" port-write io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o004 port-putc \ version chunk size io 0o242 port-putc io 0o200 port-putc io 0o121 port-putc io 0o100 port-putc \ version io "COMM" port-write io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o046 port-putc \ COMM chunk size io 0o000 port-putc io 0o001 port-putc \ 1 chan io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o002 port-putc \ framples io 0o000 port-putc io 0o020 port-putc \ bits io 0o100 port-putc io 0o016 port-putc io 0o254 port-putc io 0o104 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc \ srate as 80-bit float (sheesh) io "NONE" port-write \ compression io 0o016 port-putc \ pascal string len io "not compressed" port-write io 0o000 port-putc io "SSND" port-write io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o014 port-putc \ SSND chunk size io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc \ SSND data loc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc \ block size? io 0o170 port-putc io 0o101 port-putc io 0o100 port-putc io 0o100 port-putc \ two samples io "AUTH" port-write io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o004 port-putc \ AUTH chunk size io "bil" port-write io 0o000 port-putc io "ANNO" port-write io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o004 port-putc \ AUTH chunk size io "cat" port-write io 0o000 port-putc io "NAME" port-write io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o004 port-putc \ AUTH chunk size io "dog" port-write io 0o000 port-putc io port-close "test.aif" make-file->sample { gen } gen #( 0 ) object-apply 0.93948 "file->sample chunked 0" #() snd-test-neq gen #( 1 ) object-apply 0.50195 "file->sample chunked 1" #() snd-test-neq gen #( 2 ) object-apply 0.0 "file->sample chunked eof" #() snd-test-neq gen #( 3 ) object-apply 0.0 "file->sample chunked eof+1" #() snd-test-neq "test.aif" open-sound to ind ind framples 2 "chunked framples" #() snd-test-neq 0 sample 0.93948 "file chunked 0" #() snd-test-neq 1 sample 0.50195 "file chunked 1" #() snd-test-neq 2 sample 0.0 "file chunked eof" #() snd-test-neq 3 sample 0.0 "file chunked eof+1" #() snd-test-neq ind close-sound drop "test.aif" mus-sound-framples 2 "chunked mus-sound-framples" #() snd-test-neq "test.aif" file-delete "test.aif" mus-sound-forget drop \ "test.aif" make-file-output-port to io \ write AIFC with trailing chunks to try to confuse file->sample io "FORM" port-write io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o176 port-putc \ len io "AIFCFVER" port-write io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o004 port-putc \ version chunk size io 0o242 port-putc io 0o200 port-putc io 0o121 port-putc io 0o100 port-putc \ version io "SSND" port-write io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o014 port-putc \ SSND chunk size io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc \ SSND data loc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc \ block size? io 0o170 port-putc io 0o101 port-putc io 0o100 port-putc io 0o100 port-putc \ two samples io "COMM" port-write io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o046 port-putc \ COMM chunk size io 0o000 port-putc io 0o001 port-putc \ 1 chan io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o002 port-putc \ framples io 0o000 port-putc io 0o020 port-putc \ bits io 0o100 port-putc io 0o016 port-putc io 0o254 port-putc io 0o104 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc \ srate as 80-bit float (sheesh) io "NONE" port-write \ compression io 0o016 port-putc \ pascal string len io "not compressed" port-write io 0o000 port-putc io "APPL" port-write io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io h port-putc io "CLM ;Written Mon 02-Nov-98 01:44 CST by root at ockeghem (Linux/X86) using Allegro CL, clm of 20-Oct-98" port-write io 0o000 port-putc io port-close "test.aif" make-file->sample to gen gen #( 0 ) object-apply 0.93948 "file->sample chunked 0" #() snd-test-neq gen #( 1 ) object-apply 0.50195 "file->sample chunked 1" #() snd-test-neq gen #( 2 ) object-apply 0.0 "file->sample chunked eof" #() snd-test-neq gen #( 3 ) object-apply 0.0 "file->sample chunked eof+1" #() snd-test-neq "test.aif" open-sound to ind ind framples 2 "chunked framples" #() snd-test-neq 0 sample 0.93948 "file chunked 0" #() snd-test-neq 1 sample 0.50195 "file chunked 1" #() snd-test-neq 2 sample 0.0 "file chunked eof" #() snd-test-neq 3 sample 0.0 "file chunked eof+1" #() snd-test-neq comment ";Written Mon 02-Nov-98 01:44 CST by root at ockeghem (Linux/X86) using Allegro CL, clm of 20-Oct-98" "chunked appl comment" #() snd-test-neq ind close-sound drop "test.aif" file-delete "test.aif" mus-sound-forget drop \ "test.aif" make-file-output-port to io \ write AIFC with trailing chunks to try to confuse file->sample io "FORM" port-write io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o176 port-putc \ len io "AIFCFVER" port-write io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o004 port-putc \ version chunk size io 0o242 port-putc io 0o200 port-putc io 0o121 port-putc io 0o100 port-putc \ version io "SSND" port-write io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o014 port-putc \ SSND chunk size io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc \ SSND data loc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc \ block size? io 0o170 port-putc io 0o101 port-putc io 0o100 port-putc io 0o100 port-putc \ two samples io "COMM" port-write io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o046 port-putc \ COMM chunk size io 0o000 port-putc io 0o002 port-putc \ 2 chans io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o001 port-putc \ framples io 0o000 port-putc io 0o020 port-putc \ bits io 0o100 port-putc io 0o016 port-putc io 0o254 port-putc io 0o104 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc \ srate as 80-bit float (sheesh) io "NONE" port-write \ compression io 0o016 port-putc \ pascal string len io "not compressed" port-write io 0o000 port-putc io "APPL" port-write io 0o000 port-putc io 0o000 port-putc io 0o000 port-putc io h port-putc io "CLM ;Written Mon 02-Nov-98 01:44 CST by root at ockeghem (Linux/X86) using Allegro CL, clm of 20-Oct-98" port-write io 0o000 port-putc io port-close "test.aif" make-file->sample to gen gen #( 0 0 ) object-apply 0.93948 "file->sample chunked 0 0" #() snd-test-neq gen #( 0 1 ) object-apply 0.50195 "file->sample chunked 0 1" #() snd-test-neq gen #( 1 0 ) object-apply 0.0 "file->sample chunked eof (stereo)" #() snd-test-neq gen #( 1 1 ) object-apply 0.0 "file->sample chunked eof+1 (stereo)" #() snd-test-neq "test.aif" open-sound to ind ind framples 1 "chunked framples (1)" #() snd-test-neq 0 ind 0 sample 0.93948 "file chunked 0 0" #() snd-test-neq 0 ind 1 sample 0.50195 "file chunked 0 1" #() snd-test-neq 1 ind 0 sample 0.0 "file chunked eof (stereo)" #() snd-test-neq 1 ind 1 sample 0.0 "file chunked eof+1 (stereo)" #() snd-test-neq comment ";Written Mon 02-Nov-98 01:44 CST by root at ockeghem (Linux/X86) using Allegro CL, clm of 20-Oct-98" "chunked appl comment (stereo)" #() snd-test-neq ind close-sound drop "test.aif" file-delete "test.aif" mus-sound-forget drop \ file-pwd sound-files-in-directory { files } files empty? if "no sound files in %s?" #( file-pwd ) snd-display then sound-files-in-directory { files1 } files files1 "different sound files in %s and default" #( file-pwd ) snd-test-neq "." sound-files-in-directory { files2 } files1 files2 "sound-files-in-directory dot" #() snd-test-neq files files2 "sound-files-in-directory dot" #() snd-test-neq \ bad-header-hook reset-hook! open-raw-sound-hook reset-hook! sounds each ( snd ) close-sound drop end-each \ :size 0 new-sound to ind ind framples 0 "new-sound :size 0 framples" #() snd-test-neq 0 sample 0.0 "new-sound :size 0 sample 0" #() snd-test-neq ind file-name { new-file-name } ind close-sound drop new-file-name file-delete :size 1 new-sound to ind ind framples 1 "new-sound :size 1 framples" #() snd-test-neq 0 sample 0.0 "new-sound :size 1 sample 0" #() snd-test-neq ind file-name to new-file-name ind close-sound drop new-file-name file-delete :size -1 <'> new-sound snd-test-catch to res res car 'out-of-range "new-sound :size -1: %s" #( res ) snd-test-neq \ "caruso.asc" check-file-name { fsnd } fsnd file-exists? if fsnd read-ascii to ind ind sound? if ind 0 maxamp 0.723 "read-ascii maxamp" #() snd-test-neq ind 0 framples 50000 "read-ascii framples" #() snd-test-neq ind srate 44100 "read-ascii srate" #() snd-test-neq ind 8000 set-srate drop ind 0 maxamp 0.723 "set srate clobbered new sound (maxamp)" #() snd-test-neq ind 0 framples 50000 "set srate clobbered new sound (framples)" #() snd-test-neq ind close-sound drop else "read-ascii can't find %s?" #( fsnd ) snd-display then then \ "oboe.snd" open-sound to ind "test space.snd" save-sound-as drop ind close-sound drop "test space.snd" open-sound to ind ind short-file-name "test space.snd" "file name with space" #() snd-test-neq ind framples "test space.snd" mus-sound-framples "spaced filename framples" #() snd-test-neq 1234 ind 0 add-mark drop ind save-marks drop \ ; should write "test space.marks" ind close-sound drop "test space.snd" open-sound to ind file-pwd "/" $+ "test space.marks" $+ file-eval 1234 ind find-mark unless "space file name save marks?" #() snd-display then :file "test space.snd" make-readin { rd } rd mus-file-name "test space.snd" "file name with space readin" #() snd-test-neq ind close-sound drop "test space.snd" file-delete "test space.marks" file-delete \ XXX: S7 specific tests skipped ; : 04-sndlib ( -- ) *tests* 0 ?do i to *clmtest* *snd-test-verbose* *tests* 1 > && if "clmtest %d of %d" #( *clmtest* 1+ *tests* ) snd-test-message then clear-listener drop (04-sndlib-01) loop (04-sndlib-02) ; \ ---------------- test 05: simple overall checks ---------------- : ccvp-01-cb { y data forward -- r } data 0 vct-ref { angle } data 1 vct-ref { incr } angle fcos y f* { val } data 0 angle incr forward if f+ else f- then vct-set! drop val ; half-pi fnegate constant -half-pi : ccvp-02-cb { frag-beg frag-dur -- v } pi frag-dur f/ { incr } -half-pi frag-beg incr f* f+ incr 2 >vct ; 0 value a-ctr 0 value g-init-val : append-sound { fname -- } fname undef undef undef framples insert-sound drop ; : cc-01-cb { incr -- prc; y self -- r } 1 proc-create incr , -half-pi ( angle ) , ( prc ) does> { y self -- r } self @ { incr } self cell+ @ { angle } y angle f* { val } angle incr f+ self cell+ ! ( angle += incr ) val ; : cosine-channel <{ :optional beg 0 dur #f snd #f chn #f edpos #f -- }> pi dur if dur else snd chn undef framples then f/ ( incr ) cc-01-cb beg dur snd chn edpos map-channel drop ; : (05-simple-check-01) ( -- ) playing if "dac is running??" #() snd-display then "oboe.snd" open-sound { ind } #t ind 0 set-transform-graph? drop graph-as-sonogram ind 0 set-transform-graph-type drop "hiho" ind 0 1 <'> y-axis-label 'no-such-axis nil fth-catch if "no fft axis?" #() snd-display then stack-reset #t ind 0 set-fft-log-frequency drop ind 0 update-transform-graph drop ind close-sound drop ; : 05-simple-check ( -- ) *tests* 0 ?do i to *clmtest* *snd-test-verbose* *tests* 1 > && if "clmtest %d of %d" #( *clmtest* 1+ *tests* ) snd-test-message then (05-simple-check-01) loop ; \ ---------------- test 08: clm ---------------- lambda: <{ -- r }> 0.0 ; value 08-clm-lambda-0.0 lambda: <{ dir -- r }> 1.0 ; value 08-clm-lambda-dir-1.0 lambda: <{ a b c -- r }> 1.0 ; value 08-clm-lambda-a-b-c-1.0 32 make-delay constant make-delay-32 \ xen-mus-apply (using mus-run): \ S7: (gen arg) \ Ruby: gen.call(arg) \ Forth: gen '( arg ) apply \ \ mus-apply ( args -- res ) \ mus-run ( gen :optional arg1 0.0 arg2 0.0 -- res ) : random-gen-run ( ?? make-prc random-args -- ) { make-prc random-args } make-prc #t nil fth-catch if stack-reset nil then { gen } nil { arg } gen mus-generator? if random-args each to arg \ ~608.375s apply \ ~701.320s mus-run \ ~500.867s mus-apply \ gen '( arg ) <'> apply #t nil fth-catch \ gen arg undef <'> mus-run #t nil fth-catch gen arg <'> mus-apply #t nil fth-catch stack-reset end-each then ; : random-gen ( -- ) #( 2.0 21.5 ** 2.0 -18.0 ** 1.5 "/hiho" list( 0 1 ) 1234 vct( 0 0 0 ) 0.1 0.2 0.3 make-color-with-catch #( 0 1 ) 3/4 0+i make-delay-32 08-clm-lambda-0.0 08-clm-lambda-dir-1.0 08-clm-lambda-a-b-c-1.0 0 1 -1 #f #t c 0.0 1.0 -1.0 '() 32 '( 1 2 ) ) { random-args } #( <'> make-all-pass <'> make-asymmetric-fm <'> make-moving-average <'> make-moving-max <'> make-moving-norm <'> make-table-lookup <'> make-triangle-wave <'> make-comb <'> make-delay <'> make-env <'> make-fft-window <'> make-filter <'> make-filtered-comb <'> make-fir-filter <'> make-formant <'> make-iir-filter <'> make-locsig <'> make-notch <'> make-one-pole <'> make-one-pole-all-pass <'> make-one-zero <'> make-oscil <'> make-pulse-train <'> make-rand <'> make-rand-interp <'> make-sawtooth-wave <'> make-polyshape <'> make-polywave <'> make-square-wave <'> make-two-pole <'> make-two-zero <'> make-wave-train <'> make-ssb-am ) { gen-make-procs } nil { make-prc } nil nil nil nil { arg1 arg2 arg3 arg4 } gen-make-procs each to make-prc make-prc random-args random-gen-run end-each random-args each to arg1 gen-make-procs each to make-prc arg1 make-prc random-args random-gen-run end-each random-args each to arg2 gen-make-procs each to make-prc arg1 arg2 make-prc random-args random-gen-run end-each random-args each to arg3 gen-make-procs each to make-prc arg1 arg2 arg3 make-prc random-args random-gen-run end-each random-args each to arg4 gen-make-procs each to make-prc arg1 arg2 arg3 arg4 make-prc random-args random-gen-run end-each end-each end-each end-each end-each ; : 08-clm ( -- ) all-args if random-gen then ; \ ---------------- test 10: marks ---------------- : 10-marks ( -- ) "oboe.snd" open-sound { ind } 123 add-mark drop 234 ind 0 "hiho" 1 add-mark drop 345 ind 0 #f 1 add-mark drop 456 ind 0 "a mark" 2 add-mark drop 567 ind 0 #f 1 add-mark drop ind "oboe.marks" save-marks drop ind close-sound drop "oboe.snd" open-sound to ind 1 ind 0 "new mark" 1 add-mark drop "oboe.marks" file-eval 123 ind 0 find-mark { m } m mark? if m mark-name length zero? unless "saved mark 123 name: %s?" #( m mark-name ) snd-display then m mark-sync zero? unless "saved mark 123 sync: %s?" #( m mark-sync ) snd-display then else "saved marks missed 123: %s?" #( m ) snd-display then 234 ind 0 find-mark to m m mark? if m mark-name "hiho" string<> if "saved mark 234 name: %s?" #( m mark-name ) snd-display then m mark-sync { m2sync } m2sync 0= m2sync 1 = || if "saved mark 234 sync: %s?" #( m mark-sync ) snd-display then m mark-sync else "saved marks missed 234: %s?" #( m ) snd-display 0 then { m1-sync } 345 ind 0 find-mark to m m mark? if m mark-name length zero? unless "saved mark 345 name: %s?" #( m mark-name ) snd-display then m mark-sync m1-sync <> if "saved mark 345 sync: %s %s?" #( m mark-sync m1-sync ) snd-display then else "saved marks missed 345: %s?" #( m ) snd-display then 456 ind 0 find-mark to m m mark? if m mark-name "a mark" string<> if "saved mark 456 name: %s?" #( m mark-name ) snd-display then m mark-sync { m4sync } m4sync m1-sync = m4sync 0= || m4sync 1 = || if "saved mark 456 sync: %s %s?" #( m mark-sync m1-sync ) snd-display then else "saved marks missed 456: %s?" #( m ) snd-display then 567 ind 0 find-mark to m m mark? if m mark-name length zero? unless "saved mark 567 name: %s?" #( m mark-name ) snd-display then m mark-sync m1-sync <> if "saved mark 567 sync: %s %s?" #( m mark-sync m1-sync ) snd-display then else "saved marks missed 567: %s?" #( m ) snd-display then ind close-sound drop ; \ ---------------- test 15: chan-local vars ---------------- : interpolated-peak-offset ( r1 r2 r3 -- r4 ) { la ca ra } la ca fmax ra fmax 0.001 f+ { pk } la 0.0000001 fmax pk f/ flog 10 flog f/ { logla } ca 0.0000001 fmax pk f/ flog 10 flog f/ { logca } ra 0.0000001 fmax pk f/ flog 10 flog f/ { logra } logla logra f- f2/ logla logra f+ logca f2* f- f/ ; : freq-peak { beg ind size -- lst } beg size ind 0 channel->vct { data } data blackman2-window size #t 0.0 #f #t snd-spectrum { spectr } 0.0 { peak0 } 0 { pk0loc } size 2/ 0 ?do spectr i vct-ref peak0 f> if spectr i vct-ref to peak0 i to pk0loc then loop pk0loc 0> if spectr pk0loc 1- vct-ref spectr pk0loc vct-ref spectr pk0loc 1+ vct-ref interpolated-peak-offset else 0.0 then pk0loc f+ #f srate f* size f/ peak0 2 >array ; : src-test15-cb ( os -- proc; y self -- val ) 1 proc-create swap , does> { y self -- val } self @ ( os ) 0.0 0.0 oscil f2/ ; : f3neq ( a b -- f ) f- fabs 10.0 f> ; : f4neq ( a b -- f ) f- fabs 1.0 f> ; : f5neq ( a b -- f ) { a b } a b f- fabs 10.0 a b fmax 0.05 f* f> ; *with-test-complex* [if] \ dolph/dolph-1 are only defined if complex numbers available : dolph-test ( -- ) 16 1.0 dolph { val1 } dolph-chebyshev-window 16 1.0 make-fft-window { val2 } val1 val2 vequal? unless "dolph/dolph 1: %s %s" #( val1 val2 ) snd-display then 16 1.0 dolph-1 to val1 val1 val2 vequal? unless "dolph-1/dolph 1: %s %s" #( val1 val2 ) snd-display then ; [else] <'> noop alias dolph-test [then] : 15-chan-local-vars ( -- ) \ dsp.fs "test.snd" 1 22050 mus-bfloat mus-next "src-* tests" 10000 new-sound { ind } \ src-duration tests #( 0 1 1 2 ) src-duration { d1 } #( 0 2 1 1 ) src-duration { d2 } #( 0 1 0.5 2 ) src-duration { d3 } #( 0.5 1 0.75 2 ) src-duration { d4 } d1 0.693147180559945 fneq d2 d1 fneq || d3 d1 fneq || d4 d1 fneq || if "src-duration test1: %f %f %f %f" #( d1 d2 d3 d4 ) snd-display then #( 0 1 1 0.5 ) src-duration to d1 #( 0 0.5 1 1 ) src-duration to d2 #( 0 1 0.5 0.5 ) src-duration to d3 #( 0.5 1 0.75 0.5 ) src-duration to d4 d1 1.38629436111989 fneq d2 d1 fneq || d3 d1 fneq || d4 d1 fneq || if "src-duration test2: %f %f %f %f" #( d1 d2 d3 d4 ) snd-display then #( 0 1 1 1 ) src-duration to d1 #( 0 2 1 2 ) src-duration to d2 d1 1.0 fneq d2 0.5 fneq || if "src-duration test3: %f %f" #( d1 d2 ) snd-display then #( 0 0.5 0.5 3 0.6 1 0.7 0.1 0.8 1.5 1 1 ) src-duration to d1 d1 1.02474349685432 fneq if "src-duration test4: %f" #( d1 ) snd-display then #( 0 1 1 2 2 1 ) src-duration to d1 d1 0.693147180559945 fneq if "src-duration test5: %f" #( d1 ) snd-display then 500.0 0.0 make-oscil src-test15-cb map-channel drop 0 ind 8192 freq-peak { vals } 500.0 vals 0 array-ref f4neq 1.0 vals 1 array-ref fneq || if "src no-test: %s" #( vals ) snd-display then ind close-sound drop \ dolph-test \ env.fs \ envelope-interp 0.1 #( 0 0 1 1 ) 1.0 envelope-interp dup 0.1 fneq if "envelope-interp 0.1: %s?" swap snd-display else drop then 0.1 #( 0 0 1 1 ) 32.0 envelope-interp dup 0.01336172 fneq if "envelope-interp 0.013: %s?" swap snd-display else drop then 0.1 #( 0 0 1 1 ) 0.012 envelope-interp dup 0.36177473 fneq if "envelope-interp 0.361: %s?" swap snd-display else drop then 0.3 #( 0 0 0.5 1 1 0 ) 1.0 envelope-interp dup 0.6 fneq if "envelope-interp 0.3 #( 0 0 0.5 1 1 0 ): %s?" swap snd-display else drop then \ window-envelope 1.0 3.0 #( 0.0 0.0 5.0 1.0 ) window-envelope dup #( 1.0 0.2 3.0 0.6 ) feql if drop else 1 >array "window-envelope: %s?" swap snd-display then \ multiply-envelopes #( 0 0 1 1 ) #( 0 0 1 1 2 0 ) multiply-envelopes dup #( 0 0 0.5 0.5 1 0 ) feql if drop else 1 >array "multiply-envelopes: %s?" swap snd-display then \ max-envelope #( 0 0 1 1 2 3 4 0 ) max-envelope dup 3.0 fneq if "max-envelopes (0): %s?" swap snd-display else drop then #( 0 1 ) max-envelope dup 1.0 fneq if "max-envelopes (1): %s?" swap snd-display else drop then #( 0 1 1 1 2 2 ) max-envelope dup 2.0 fneq if "max-envelopes (2): %s?" swap snd-display else drop then #( 0 -1 1 -2 ) max-envelope dup -1.0 fneq if "max-envelopes (3): %s?" swap snd-display else drop then #( 0 -2 1 -1 ) max-envelope dup -1.0 fneq if "max-envelopes (4): %s?" swap snd-display else drop then \ min-envelope #( 0 0 1 1 2 3 4 0 ) min-envelope dup 0.0 fneq if "min-envelopes (0): %s?" swap snd-display else drop then #( 0 1 ) min-envelope dup 1.0 fneq if "min-envelopes (1): %s?" swap snd-display else drop then #( 0 1 1 1 2 2 ) min-envelope dup 1.0 fneq if "min-envelopes (2): %s?" swap snd-display else drop then #( 0 -1 1 -2 ) min-envelope dup -2.0 fneq if "min-envelopes (3): %s?" swap snd-display else drop then #( 0 -2 1 -1 ) min-envelope dup -2.0 fneq if "min-envelopes (4): %s?" swap snd-display else drop then \ integrate-envelope #( 0 0 1 1 ) integrate-envelope dup 0.5 fneq if "integrate-envelopes (0): %s?" swap snd-display else drop then #( 0 1 1 1 ) integrate-envelope dup 1.0 fneq if "integrate-envelopes (1): %s?" swap snd-display else drop then #( 0 0 1 1 2 0.5 ) integrate-envelope dup 1.25 fneq if "integrate-envelopes (2): %s?" swap snd-display else drop then \ stretch-envelope #( 0 0 1 1 ) 0.1 0.2 #f #f stretch-envelope dup #( 0 0 0.2 0.1 1.0 1 ) feql if drop else 1 >array "stretch-envelope att: %s?" swap snd-display then #( 0 0 1 1 2 0 ) 0.1 0.2 1.5 1.6 stretch-envelope dup #( 0 0 0.2 0.1 1.1 1 1.6 0.5 2 0 ) feql if drop else 1 >array "stretch-envelope dec: %s?" swap snd-display then \ add-envelopes #( 0 0 1 1 2 0 ) #( 0 0 1 1 ) add-envelopes dup #( 0 0 0.5 1.5 1 1 ) feql if drop else 1 >array "add-envelopes: %s?" swap snd-display then \ scale-envelope #( 0 0 1 1 ) 2 0 scale-envelope dup #( 0 0 1 2 ) feql if drop else 1 >array "scale-envelope: %s?" swap snd-display then #( 0 0 1 1 ) 2 1 scale-envelope dup #( 0 1 1 3 ) feql if drop else 1 >array "scale-envelope off: %s?" swap snd-display then \ reverse-envelope #( 0 0 1 1 ) reverse-envelope dup #( 0 1 1 0 ) feql if drop else 1 >array "reverse-envelope ramp: %s?" swap snd-display then #( 0 0 0.5 1 2 0 ) reverse-envelope dup #( 0 0 1.5 1 2 0 ) feql if drop else 1 >array "reverse-envelope ramp 2: %s?" swap snd-display then #( 0 0 0.5 1 2 1 ) reverse-envelope dup #( 0 1 1.5 1 2 0 ) feql if drop else 1 >array "reverse-envelope ramp 2: %s?" swap snd-display then \ concatenate-envelopes (from snd/env.scm) #( 0 0 1 1 ) #( 0 1 1 0 ) 2 concatenate-envelopes dup #( 0.0 0 1.0 1 2.0 0 ) feql if drop else 1 >array "concatenate-envelopes (0): %s?" swap snd-display then #( 0 0 1 1.5 ) #( 0 1 1 0 ) 2 concatenate-envelopes dup #( 0.0 0 1.0 1.5 1.01 1 2.01 0 ) feql if drop else 1 >array "concatenate-envelopes (1): %s?" swap snd-display then \ envelope-concatenate (from clm/env.lisp) #( 0 0 1 1 ) #( 0 1 1 0 ) 2 envelope-concatenate dup #( 0.0 0 1.0 1 1.01 1 2.01 0 ) feql if drop else 1 >array "envelope-concatenate (0): %s?" swap snd-display then #( 0 0 1 1.5 ) #( 0 1 1 0 ) 2 envelope-concatenate dup #( 0.0 0 1.0 1.5 1.01 1 2.01 0 ) feql if drop else 1 >array "envelope-concatenate (1): %s?" swap snd-display then \ repeat-envelope #( 0 0 1 100 ) 2 #f #f repeat-envelope dup #( 0 0 1 100 1.01 0 2.01 100 ) feql if drop else 1 >array "repeat-envelope (0): %s?" swap snd-display then #( 0 0 1.5 1 2 0 ) 2 #f #f repeat-envelope dup #( 0 0 1.5 1 2.0 0 3.5 1 4.0 0 ) feql if drop else 1 >array "repeat-envelope (1): %s?" swap snd-display then #( 0 0 1.5 1 2 0 ) 2 #f #t repeat-envelope dup #( 0.0 0 0.75 1 1.0 0 1.75 1 2.0 0 ) feql if drop else 1 >array "repeat-envelope (2): %s?" swap snd-display then #( 0 0 1.5 1 2 0 ) 2 #t #f repeat-envelope dup #( 0 0 1.5 1 2.0 0 2.5 1 4.0 0 ) feql if drop else 1 >array "repeat-envelope (3): %s?" swap snd-display then #( 0 0 1.5 1 2 0 ) 3 #f #f repeat-envelope dup #( 0 0 1.5 1 2.0 0 3.5 1 4.0 0 5.5 1 6.0 0 ) feql if drop else 1 >array "repeat-envelope (4): %s?" swap snd-display then \ normalize-envelope #( 0 0 1 1.5 2.0 1.0 ) normalize-envelope dup #( 0 0.0 1 1.0 2.0 0.667 ) feql if drop else 1 >array "normalize-envelope (0): %s?" swap snd-display then #( 0 0 1 0.5 2 -0.8 ) normalize-envelope dup #( 0 0.0 1 0.625 2 -1.0 ) feql if drop else 1 >array "normalize-envelope (1): %s?" swap snd-display then \ envelope-exp #( 0 0 1 1 ) 2.0 10 envelope-exp dup #( 0 0 0.1 0.01 0.2 0.04 0.3 0.09 0.4 0.16 0.5 0.25 0.6 0.36 0.7 0.49 0.8 0.64 0.9 0.81 1 1 ) feql if drop else 1 >array "envelope-exp (0): %s?" swap snd-display then #( 0 0 1 1 2 0 ) 1.0 10 envelope-exp dup #( 0 0 0.2 0.2 0.4 0.4 0.6 0.6 0.8 0.8 1 1 1.2 0.8 1.4 0.6 1.6 0.4 1.8 0.2 2 0 ) feql if drop else 1 >array "envelope-exp (1): %s?" swap snd-display then ; \ ---------------- test 19: save and restore ---------------- : clm-channel-test <{ :optional snd #f chn #f -- gen }> 1 -1 make-two-zero 0 #f snd chn #f #f get-func-name clm-channel ; : random-pi-func <{ x -- y }> pi random ; #( #( lambda: <{ -- val }> vct( 1.0 0.5 ) 0 2 #f #f #f insert-vct ; "lambda: <{ snd chn -- val }> vct( 1.000 0.500 ) 0 2 snd chn insert-vct drop ;" "insert-vct" ) #( lambda: <{ -- val }> #f #f clm-channel-test ; "lambda: <{ snd chn -- val }> snd chn clm-channel-test drop ;" "clm-channel-test" ) ( examp.fs ) #( lambda: <{ -- val }> 1000 3000 #f #f fft-edit ; "lambda: <{ snd chn -- val }> 1000 3000 snd chn fft-edit drop ;" "fft-edit" ) #( lambda: <{ -- val }> 0.01 #f #f fft-squelch ; "lambda: <{ snd chn -- val }> 0.01 snd chn fft-squelch drop ;" "fft-sqelch" ) #( lambda: <{ -- val }> 1000 3000 #f #f fft-cancel ; "lambda: <{ snd chn -- val }> 1000 3000 snd chn fft-cancel drop ;" "fft-cancel" ) #( lambda: <{ -- val }> #f #f squelch-vowels ; "lambda: <{ snd chn -- val }> snd chn squelch-vowels drop ;" "squelch-vowels" ) #( lambda: <{ -- val }> #( 0 0 1 1 2 0 ) #f #f fft-env-edit ; "lambda: <{ snd chn -- val }> #( 0 0 1 1 2 0 ) snd chn fft-env-edit drop ;" "fft-env-edit" ) #( lambda: <{ -- val }> #( 0 0 1 1 2 0 ) #( 0 1 1 0 2 0 ) #( 0 0 1 1 ) #f #f fft-env-interp ; "lambda: <{ snd chn -- val }> #( 0 0 1 1 2 0 ) #( 0 1 1 0 2 0 ) #( 0 0 1 1 ) snd chn fft-env-interp drop ;" "fft-env-interp" ) #( lambda: <{ -- val }> 10 0.1 #f #f hello-dentist ; "lambda: <{ snd chn -- val }> 10 0.1 snd chn hello-dentist drop ;" "hello-dentist" ) #( lambda: <{ -- val }> 1 0.3 20 #f #f fp ; "lambda: <{ snd chn -- val }> 1 0.3 20 snd chn fp drop ;" "fp" ) #( lambda: <{ -- val }> #( 0 1 1 2 ) #f #f expsnd ; "lambda: <{ snd chn -- val }> #( 0 1 1 2 ) snd chn expsnd drop ;" "expsnd" ) #( lambda: <{ -- val }> 1 256 2 2 #f #f voiced->unvoiced ; "lambda: <{ snd chn -- val }> 1 256 2 2 snd chn voiced->unvoiced drop ;" "voiced->unvoiced" ) #( lambda: <{ -- val }> #( 0 0 1 1 2 0 ) 2 #f #f env-sound-interp ; "lambda: <{ snd chn -- val }> #( 0 0 1 1 2 0 ) 2 snd chn env-sound-interp drop ;" "env-sound-interp" ) #( lambda: <{ -- val }> #( #( "1a.snd" ) #( "pistol.snd" 1 2 ) ) #f #f add-notes ; "lambda: <{ snd chn -- val }> #( #( \"1a.snd\" ) #( \"pistol.snd\" 1 2 ) ) snd chn add-notes drop ;" "add-notes" ) #( lambda: <{ -- val }> #( 0 0 1 1 2 0 ) #f #f filtered-env ; "lambda: <{ snd chn -- val }> #( 0 0 1 1 2 0 ) snd chn filtered-env drop ;" "filtered-env" ) #( lambda: <{ -- val }> 0.1 #f #f reverse-by-blocks ; "lambda: <{ snd chn -- val }> 0.1 snd chn reverse-by-blocks drop ;" "reverse-by-blocks" ) #( lambda: <{ -- val }> 0.1 #f #f reverse-within-blocks ; "lambda: <{ snd chn -- val }> 0.1 snd chn reverse-within-blocks drop ;" "reverse-within-blocks" ) ( extensions.fs ) #( lambda: <{ -- val }> "1a.snd" 1200 #f #f #f #f mix-channel ; "lambda: <{ snd chn -- val }> \"1a.snd\" 1200 #f snd chn mix-channel drop ;" "mix-channel" ) #( lambda: <{ -- val }> "1a.snd" 1200 #f #f #f #f insert-channel ; "lambda: <{ snd chn -- val }> \"1a.snd\" 1200 #f snd chn insert-channel drop ;" "insert-channel" ) #( lambda: <{ -- val }> "1a.snd" 0.5 0.9 0 #f #f #f #f sine-ramp ; "lambda: <{ snd chn -- val }> 0.5 0.9 0 #f snd chn sine-ramp drop ;" "sine-ramp" ) #( lambda: <{ -- val }> #( 0 0 1 1 2 -0.5 3 1 ) 0 #f #f #f #f sine-env-channel ; "lambda: <{ snd chn -- val }> #( 0 0 1 1 2 -0.5 3 1 ) 0 #f snd chn sine-env-channel drop ;" "sine-env-channel" ) #( lambda: <{ -- val }> 0 1 0 #f #f #f #f blackman4-ramp ; "lambda: <{ snd chn -- val }> 0 1 0 #f snd chn blackman4-ramp drop ;" "blackman4-ramp" ) #( lambda: <{ -- val }> #( 0 0 1 1 2 -0.5 3 1 ) 0 #f #f #f #f blackman4-env-channel ; "lambda: <{ snd chn -- val }> #( 0 0 1 1 2 -0.5 3 1 ) 0 #f snd chn blackman4-env-channel drop ;" "blackman4-env-channel" ) #( lambda: <{ -- val }> 0.2 0.8 #t 0 #f #f #f #f ramp-squared ; "lambda: <{ snd chn -- val }> 0.2 0.8 #t 0 #f snd chn ramp-squared drop ;" "ramp-squared" ) #( lambda: <{ -- val }> #( 0 0 1 1 ) #t 0 #f #f #f #f env-squared-channel ; "lambda: <{ snd chn -- val }> #( 0 0 1 1 ) #t 0 #f snd chn env-squared-channel drop ;" "env-squared-channel" ) #( lambda: <{ -- val }> 0.2 0.8 32 #t 0 #f #f #f #f ramp-expt ; "lambda: <{ snd chn -- val }> 0.2 0.8 32 #t 0 #f snd chn ramp-expt drop ;" "ramp-expt" ) #( lambda: <{ -- val }> #( 0 0 1 1 ) 32 #t 0 #f #f #f #f env-expt-channel ; "lambda: <{ snd chn -- val }> #( 0 0 1 1 ) 32 #t 0 #f snd chn env-expt-channel drop ;" "env-expt-channel" ) #( lambda: <{ -- val }> 0.1 0 #f #f #f #f offset-channel ; "lambda: <{ snd chn -- val }> 0.1 0 #f snd chn offset-channel drop ;" "offset-channel" ) #( lambda: <{ -- val }> 0.1 0 #f #f #f #f dither-channel ; "lambda: <{ snd chn -- val }> 0.1 0 #f snd chn dither-channel drop ;" "dither-channel" ) #( lambda: <{ -- val }> 0.1 0 #f #f #f #f contrast-channel ; "lambda: <{ snd chn -- val }> 0.1 0 #f snd chn contrast-channel drop ;" "contrast-channel" ) ( dsp.fs ) #( lambda: <{ -- val }> 550 600 10 40 50 0 #f #f #f #f ssb-bank ; "lambda: <{ snd chn -- val }> 550 600 10 40 50 0 #f snd chn ssb-bank drop ;" "ssb-bank" ) #( lambda: <{ -- val }> 550 600 #( 0 1 1 2 ) 10 40 50 0 #f #f #f #f ssb-bank-env ; "lambda: <{ snd chn -- val }> 550 600 #( 0 1 1 2 ) 10 40 50 0 #f snd chn ssb-bank-env drop ;" "ssb-bank-env" ) #( lambda: <{ -- val }> 1 #f #f down-oct ; "lambda: <{ snd chn -- val }> 1 snd chn down-oct drop ;" "donw-oct" ) #( lambda: <{ -- val }> 8 #f #f freqdiv ; "lambda: <{ snd chn -- val }> 8 snd chn freqdiv drop ;" "freqdiv" ) #( lambda: <{ -- val }> 8 0 #f #f #f adsat ; "lambda: <{ snd chn -- val }> 8 0 #f snd chn adsat drop ;" "adsat" ) #( lambda: <{ -- val }> #f #f spike ; "lambda: <{ snd chn -- val }> snd chn spike drop ;" "spike" ) #( lambda: <{ -- val }> #f #f zero-phase ; "lambda: <{ snd chn -- val }> snd chn zero-phase drop ;" "zero-phase" ) #( lambda: <{ -- val }> <'> random-pi-func #f #f rotate-phase ; "lambda: <{ snd chn -- val }> <'> random-pi-func snd chn rotate-phase drop ;" "rotate-phase" ) #( lambda: <{ -- val }> 0.5 #f #f brighten-slightly ; "lambda: <{ snd chn -- val }> 0.5 snd chn brighten-slightly drop ;" "brighten-slightly" ) #( lambda: <{ -- val }> 100 40 0 #f #f #f #f shift-channel-pitch ; "lambda: <{ snd chn -- val }> 100 40 0 #f snd chn shift-channel-pitch drop ;" "shift-channel-pitch" ) #( lambda: <{ -- val }> vct( 0.0 0.5 ) #f #f channel-polynomial ; "lambda: <{ snd chn -- val }> vct( 0.000 0.500 ) snd chn channel-polynomial drop ;" "channel-polynomial" ) #( lambda: <{ -- val }> vct( 0.0 1.0 ) #f #f spectral-polynomial ; "lambda: <{ snd chn -- val }> vct( 0.000 1.000 ) snd chn spectral-polynomial drop ;" "spectral-polynomial" ) #( lambda: <{ -- val }> #( 60.0 120.0 240.0 ) #f 0 #f #f #f #f #t 2 notch-channel ; "lambda: <{ snd chn -- val }> #( 60.0 120.0 240.0 ) #f 0 #f snd chn notch-channel drop ;" "notch-channel" ) ( effects.fs ) #( lambda: <{ -- val }> 0.1 128 effects-squelch-channel ; "lambda: <{ snd chn -- val }> 0.1 128 snd chn effects-squelch-channel drop ;" "effects-sqelch-channel" ) #( lambda: <{ -- val }> #f 0.5 0.1 0 #f #f #f effects-echo ; "lambda: <{ snd chn -- val }> #f 0.5 0.1 0 #f snd chn effects-echo drop ;" "effects-echo" ) #( lambda: <{ -- val }> 0.5 0.1 #f 0 #f #f #f effects-flecho ; "lambda: <{ snd chn -- val }> 0.5 0.1 #f 0 #f snd chn effects-flecho drop ;" "effects-flecho" ) #( lambda: <{ -- val }> 0.75 0.75 6.0 10.0 #f 0 #f #f #f effects-zecho ; "lambda: <{ snd chn -- val }> 0.75 0.75 6.0 10.0 #f 0 #f snd chn effects-zecho drop ;" "effects-zecho" ) #( lambda: <{ -- val }> 0.1 50 0 #f #f #f effects-comb-filter ; "lambda: <{ snd chn -- val }> 0.1 50 0 #f snd chn effects-comb-filter drop ;" "effects-comb-filter" ) #( lambda: <{ -- val }> 10000 0.5 0 #f #f #f effects-moog ; "lambda: <{ snd chn -- val }> 10000 0.5 0 #f snd chn effects-moog drop ;" "effects-moog" ) #( lambda: <{ -- val }> #f #f effects-remove-dc ; "lambda: <{ snd chn -- val }> snd chn effects-remove-dc drop ;" "effects-remove-dc" ) #( lambda: <{ -- val }> #f #f effects-compand ; "lambda: <{ snd chn -- val }> snd chn effects-compand drop ;" "effects-compand" ) #( lambda: <{ -- val }> 100.0 #f 0 #f #f #f effects-am ; "lambda: <{ snd chn -- val }> 100.0 #f 0 #f snd chn effects-am drop ;" "effects-am" ) #( lambda: <{ -- val }> 100.0 #f 0 #f #f #f effects-rm ; "lambda: <{ snd chn -- val }> 100.0 #f 0 #f snd chn effects-rm drop ;" "effects-rm" ) #( lambda: <{ -- val }> 1000.0 100.0 0 #f #f #f effects-bbp ; "lambda: <{ snd chn -- val }> 1000.0 100.0 0 #f snd chn effects-bbp drop ;" "effects-bbp" ) #( lambda: <{ -- val }> 1000.0 100.0 0 #f #f #f effects-bbr ; "lambda: <{ snd chn -- val }> 1000.0 100.0 0 #f snd chn effects-bbr drop ;" "effects-bbr" ) #( lambda: <{ -- val }> 1000.0 0 #f #f #f effects-bhp ; "lambda: <{ snd chn -- val }> 1000.0 0 #f snd chn effects-bhp drop ;" "effects-bhp" ) #( lambda: <{ -- val }> 1000.0 0 #f #f #f effects-blp ; "lambda: <{ snd chn -- val }> 1000.0 0 #f snd chn effects-blp drop ;" "effects-blp" ) #( lambda: <{ -- val }> 50.0 0.5 0 #f #f #f effects-hello-dentist ; "lambda: <{ snd chn -- val }> 50.0 0.5 0 #f snd chn effects-hello-dentist drop ;" "effects-hello-dentist" ) #( lambda: <{ -- val }> 1.0 0.3 20.0 0 #f #f #f effects-fp ; "lambda: <{ snd chn -- val }> 1.0 0.3 20.0 0 #f snd chn effects-fp drop ;" "effects-fp" ) #( lambda: <{ -- val }> 5.0 2.0 0.001 0 #f #f #f effects-flange ; "lambda: <{ snd chn -- val }> 5.0 2.0 0.001 0 #f snd chn effects-flange drop ;" "effects-flange" ) #( lambda: <{ -- val }> 0.1 0 #f #f #f effects-jc-reverb-1 ; "lambda: <{ snd chn -- val }> 0.1 0 #f snd chn effects-jc-reverb-1 drop ;" "effects-jc-reverb-1" ) ) value test19-*.fs : 19-save/restore ( -- ) "oboe.snd" open-sound { ind } nil nil nil nil nil nil { vals func1 descr name func str } test19-*.fs each to vals vals 0 array-ref to func1 vals 1 array-ref to descr vals 2 array-ref to name *snd-test-verbose* if name #f snd-test-message then func1 #() run-proc drop ind #f undef undef edit-list->function to func func proc-source-ref to str str descr "edit-list->function %s [%d]" #( name i ) snd-test-neq ind revert-sound drop func #( ind 0 ) run-proc drop ind revert-sound drop end-each ind close-sound drop ; \ ---------------- test 23: with-sound ---------------- : test23-notehook { ins start dur -- } "%14s: %5.2f %5.2f" #( ins start dur ) snd-test-message ; : test23-balance ( -- ) make-rmsgain { rg } 40 make-rmsgain { rg1 } 2 make-rmsgain { rg2 } #( 0 0 1 1 2 0 ) :length 10000 make-env { e } #( 0 0 1 1 ) :length 10000 make-env { e1 } #( 0 0 1 1 2 0 10 0 ) :length 10000 make-env { e2 } 440.0 make-oscil { o } nil { sig } 10000 0 do e env to sig i rg sig e2 env rmsgain-balance *output* outa drop i rg1 sig e1 env rmsgain-balance *output* outb drop i rg2 o 0.0 0.0 oscil 0.1 f* e2 env rmsgain-balance *output* outc drop loop rg rmsgain-gain-avg 0.98402 fneq if "rmsgain gain-avg: %f (0.98402)?" #( rg rmsgain-gain-avg ) snd-display then rg2 rmsgain-avgc 10000 <> if "rmsgain count: %d (10000)?" #( rg2 rmsgain-avgc ) snd-display then ; : test23-ssb-fm ( gen mg -- proc; y self -- val ) 1 proc-create { prc } ( mg ) , ( gen ) , prc does> { y self -- val } self @ { mg } self cell+ @ { gen } gen mg 0.0 0.0 oscil 0.02 f* ssb-fm ; \ examples from sndclm.html : sndclm-oscil-test ( -- ) 440.0 make-oscil { gen } 44100 0 do i gen 0 0 oscil f2/ *output* outa drop loop ; : sndclm-env-test ( -- ) 440.0 make-oscil { gen } '( 0 0 0.01 1 0.25 0.1 0.5 0.01 1 0 ) :scaler 0.5 :length 44100 make-env { ampf } 44100 0 do i gen 0 0 oscil ampf env f* *output* outa drop loop ; : sndclm-table-lookup-test ( -- ) 440.0 :wave '( 1 0.5 2 0.5 ) #f #f partials->wave make-table-lookup { gen } 44100 0 do i gen 0 table-lookup f2/ *output* outa drop loop ; : sndclm-polywave-test ( -- ) 440.0 :partials '( 1 0.5 2 0.5 ) make-polywave { gen } 44100 0 do i gen 0 polywave f2/ *output* outa drop loop ; : sndclm-triangle-wave-test ( -- ) 440.0 make-triangle-wave { gen } 44100 0 do i gen 0 triangle-wave f2/ *output* outa drop loop ; : sndclm-ncos-test ( -- ) 440.0 10 make-ncos { gen } 44100 0 do i gen 0 ncos f2/ *output* outa drop loop ; : sndclm-nrxycos-test ( -- ) 440.0 :n 10 make-nrxycos { gen } 44100 0 do i gen 0 nrxycos f2/ *output* outa drop loop ; : sndclm-ssb-am-test ( -- ) 440.0 20 make-ssb-am { shifter } 440.0 make-oscil { osc } 44100 0 do i shifter osc 0 0 oscil 0 ssb-am f2/ *output* outa drop loop ; : sndclm-wave-train-test ( -- ) 400 10 make-ncos { g } g -0.5 pi f* set-mus-phase drop 64 make-vct map! g 0 ncos end-map { v } 440.0 :wave v make-wave-train { gen } 44100 0 do i gen 0 wave-train f2/ *output* outa drop loop ; : sndclm-rand-test ( -- ) 5.0 220.0 hz->radians make-rand { ran1 } 5.0 330.0 hz->radians make-rand-interp { ran2 } 440.0 make-oscil { osc1 } 1320.0 make-oscil { osc2 } 88200 0 do i osc1 ran1 0 rand 0 oscil f2/ *output* outa drop i osc2 ran2 0 rand-interp 0 oscil f2/ *output* outb drop loop ; : sndclm-two-pole-test ( -- ) 1000.0 0.999 make-two-pole { flt } 10000.0 0.002 make-rand { ran1 } 44100 0 do i flt ran1 0 rand two-pole f2/ *output* outa drop loop ; : sndclm-firmant-test ( -- ) 1000.0 0.999 make-firmant { flt } 10000.0 5.0 make-rand { ran1 } 44100 0 do i flt ran1 0 rand #f firmant f2/ *output* outa drop loop ; : sndclm-iir-filter-test ( -- ) 3 vct( 0.0 -1.978 0.998 ) make-iir-filter { flt } 10000.0 0.002 make-rand { ran1 } 44100 0 do i flt ran1 0 rand iir-filter f2/ *output* outa drop loop ; : sndclm-delay-test ( -- ) 0.5 seconds->samples make-delay { dly } 440.0 make-oscil { osc1 } 660.0 make-oscil { osc2 } 44100 0 do i osc1 0 0 oscil dly osc2 0 0 oscil 0 delay f+ f2/ *output* outa drop loop ; : sndclm-comb-test ( -- ) 0.4 0.4 seconds->samples make-comb { cmb } 440.0 make-oscil { osc } '( 0 0 1 1 2 1 3 0 ) :length 4410 make-env { ampf } 88200 0 do i cmb ( gen ) ampf env osc 0 0 oscil f* ( val ) 0 ( pm ) comb f2/ *output* outa drop loop ; : sndclm-all-pass-test ( -- ) -0.4 0.4 0.4 seconds->samples make-all-pass { alp } 440.0 make-oscil { osc } '( 0 0 1 1 2 1 3 0 ) :length 4410 make-env { ampf } 88200 0 do i alp ( gen ) ampf env osc 0 0 oscil f* ( val ) 0 ( pm ) all-pass f2/ *output* outa drop loop ; : sndclm-moving-average-test ( -- ) 4410 make-moving-average { avg } 440.0 make-oscil { osc } 44100 4410 - { stop } 0.0 { val } stop 0 ?do osc 0 0 oscil to val i avg val fabs moving-average val f* *output* outa drop loop 44100 stop ?do i avg 0.0 moving-average osc 0 0 oscil f* *output* outa drop loop ; : sndclm-src1-test ( -- ) "oboe.snd" make-readin { rd } rd 0.5 make-src { sr } "oboe.snd" mus-sound-framples 2* ( len ) 0 ?do i sr 0 #f src *output* outa drop loop ; : make-src-proc { osc -- prc; dir self -- val } 1 proc-create osc , ( prc ) does> { dir self -- val } self @ ( osc ) 0 0 oscil ; : sndclm-src2-test ( -- ) 440.0 make-oscil { osc } osc make-src-proc { prc } :srate 2.0 make-src { sr } 44100 0 do i sr 0 prc src *output* outa drop loop ; : sndclm-convolve1-test ( -- ) "pistol.snd" make-readin ( rd ) "oboe.snd" file->vct ( v ) make-convolve { cnv } 88200 0 do i cnv #f convolve 0.25 f* *output* outa drop loop ; : sndclm-convolve2-test ( -- ) "oboe.snd" "pistol.snd" 0.5 "convolved.snd" convolve-files { tempfile } tempfile make-readin { reader } tempfile mus-sound-framples ( len ) 0 ?do i reader readin *output* outa drop loop tempfile file-delete ; : sndclm-granulate1-test ( -- ) "oboe.snd" make-readin 2.0 make-granulate { grn } 44100 0 do i grn #f #f granulate *output* outa drop loop ; : make-granulate-proc { osc sweep -- prc; dir self -- val } 1 proc-create osc , sweep , ( prc ) does> { dir self -- val } self @ ( osc ) self cell+ @ ( sweep ) env 0 oscil 0.2 f* ; : sndclm-granulate2-test ( -- ) 440.0 make-oscil { osc } '( 0 0 1 1 ) :scaler 440.0 hz->radians :length 44100 make-env { sweep } osc sweep make-granulate-proc :expansion 2.0 :length 0.5 make-granulate { grn } 88200 0 do i grn #f #f granulate *output* outa drop loop ; : sndclm-phase-vocoder1-test ( -- ) "oboe.snd" make-readin :pitch 2.0 make-phase-vocoder { pv } 44100 0 do i pv #f #f #f #f phase-vocoder *output* outa drop loop ; : sndclm-phase-vocoder2-test ( -- ) "oboe.snd" make-readin :interp 256 make-phase-vocoder { pv } "oboe.snd" mus-sound-framples 2* ( samps ) 0 ?do i pv #f #f #f #f phase-vocoder *output* outa drop loop ; : sndclm-asymmetric-fm-test ( -- ) 440.0 0.0 0.9 0.5 make-asymmetric-fm { fm } 44100 0 do i fm 1.0 0 asymmetric-fm f2/ *output* outa drop loop ; : sndclm-file->frample->file-test ( -- ) "stereo.snd" make-file->frample { input } 2 0.0 make-vct { frm } 0.0 0.0 { val0 val1 } "stereo.snd" mus-sound-framples ( len ) 0 ?do input i frm file->frample to frm frm 0 vct-ref to val0 frm 1 vct-ref to val1 frm 0 val1 vct-set! drop frm 1 val0 vct-set! drop *output* i frm frample->file drop loop ; : sndclm-readin-test ( -- ) "oboe.snd" make-readin { reader } 44100 0 do i reader readin f2/ *output* outa drop loop ; : sndclm-in-out-any-test ( -- ) "oboe.snd" make-file->sample { infile } 44100 0 do i i 0 infile in-any 0 *output* out-any drop loop ; : sndclm-locsig-test ( -- ) 60.0 make-locsig { loc } 440.0 make-oscil { osc } 44100 0 do loc i osc 0 0 oscil f2/ locsig drop loop ; : sndclm-amplitude-modulate-test ( -- ) 440.0 make-oscil { osc1 } 220.0 make-oscil { osc2 } 44100 0 do i 0.3 ( car ) osc1 0 0 oscil ( in1 ) osc2 0 0 oscil ( in2 ) amplitude-modulate f2/ *output* outa drop loop ; : check-maxamp { fname name lno -- } fname mus-sound-maxamp { amps } amps each { val } i 2 mod if val 1.1 f> if "%s (%s)[%d]: maxamp chn %d > 1.0: %.3f (at %d)" '( name fname lno i 1- 2/ val amps i object-ref ) snd-display then then end-each ; : (ws-close-sound) { ws lno -- } ws ws-output 0 find-sound dup sound? if close-sound then drop ws :statistics ws-ref unless ws ws-output ws :comment ws-ref lno check-maxamp then ; : ws-close-sound ( ws -- ) postpone *lineno* postpone (ws-close-sound) ; immediate : 23-with-sound ( -- ) 1024 1024 * to *clm-file-buffer-size* *clm-play* { old-play } *clm-statistics* { old-stats } *snd-test-ws-play* to *clm-play* *snd-test-ws-player* to *clm-player* *snd-test-ws-statistics* to *clm-statistics* mus-bfloat to *clm-sample-type* \ from bird.fsm <'> bird-test :comment over object->string :verbose *snd-test-ws-verbose* :channels 2 with-sound ws-close-sound \ from clm-ins.fs 0.0 0.3 <'> clm-ins-test :comment over object->string :notehook *snd-test-ws-verbose* if <'> test23-notehook else #f then :channels 2 with-sound ws-close-sound <'> test23-balance :comment over object->string :channels 3 with-sound ws-output 0 find-sound { ind } ind sound? if ind close-sound drop else "with-sound balance?" snd-display then "test.snd" "test23-balance" *lineno* check-maxamp "tmp.snd" 1 22050 mus-bfloat mus-next new-sound to ind 0 1000 ind 0 pad-channel drop 100.0 make-oscil { mg } 1000 make-ssb-fm { gen } gen mg test23-ssb-fm <'> map-channel snd-test-catch drop ind close-sound drop \ examples from sndclm.html <'> sndclm-oscil-test :comment over object->string with-sound ws-close-sound <'> sndclm-env-test :comment over object->string with-sound ws-close-sound <'> sndclm-table-lookup-test :comment over object->string with-sound ws-close-sound <'> sndclm-polywave-test :comment over object->string with-sound ws-close-sound <'> sndclm-triangle-wave-test :comment over object->string with-sound ws-close-sound <'> sndclm-ncos-test :comment over object->string with-sound ws-close-sound <'> sndclm-nrxycos-test :comment over object->string with-sound ws-close-sound <'> sndclm-ssb-am-test :comment over object->string with-sound ws-close-sound <'> sndclm-wave-train-test :comment over object->string with-sound ws-close-sound <'> sndclm-rand-test :comment over object->string :channels 2 with-sound ws-close-sound <'> sndclm-two-pole-test :comment over object->string with-sound ws-close-sound <'> sndclm-firmant-test :comment over object->string with-sound ws-close-sound <'> sndclm-iir-filter-test :comment over object->string with-sound ws-close-sound <'> sndclm-delay-test :comment over object->string with-sound ws-close-sound <'> sndclm-comb-test :comment over object->string with-sound ws-close-sound <'> sndclm-all-pass-test :comment over object->string with-sound ws-close-sound <'> sndclm-moving-average-test :comment over object->string with-sound ws-close-sound <'> sndclm-src1-test :comment over object->string :srate 22050 with-sound ws-close-sound <'> sndclm-src2-test :comment over object->string with-sound ws-close-sound <'> sndclm-convolve1-test :comment over object->string with-sound ws-close-sound <'> sndclm-convolve2-test :comment over object->string with-sound ws-close-sound <'> sndclm-granulate1-test :comment over object->string with-sound ws-close-sound <'> sndclm-granulate2-test :comment over object->string with-sound ws-close-sound <'> sndclm-phase-vocoder1-test :comment over object->string with-sound ws-close-sound <'> sndclm-phase-vocoder2-test :comment over object->string :srate 22050 with-sound ws-close-sound <'> sndclm-asymmetric-fm-test :comment over object->string with-sound ws-close-sound <'> sndclm-file->frample->file-test :comment over object->string :channels 2 with-sound ws-close-sound <'> sndclm-readin-test :comment over object->string with-sound ws-close-sound <'> sndclm-in-out-any-test :comment over object->string with-sound ws-close-sound <'> sndclm-locsig-test :comment over object->string :channels 2 with-sound ws-close-sound <'> sndclm-amplitude-modulate-test :comment over object->string with-sound ws-close-sound old-play to *clm-play* old-stats to *clm-statistics* ; \ ---------------- test 27: general ---------------- *with-test-complex* [if] : complex-test ( -- ) \ edot-product (test008) 0.0 vct( 1.0 ) edot-product dup 1.0 fneq if "edot 1.0: %s?" swap snd-display else drop then 0.0 vct( 0.0 ) edot-product dup 0.0 fneq if "edot 0.0: %s?" swap snd-display else drop then 0.0 #( 1.0 ) edot-product dup 1.0 fneq if "edot 1.0: %s?" swap snd-display else drop then 0.0 #( 0+1i ) edot-product dup 0+1i cneq if "edot i: %s?" swap snd-display else drop then 0.25 two-pi f* vct( 1.0 1.0 1.0 1.0 ) edot-product 0.00 two-pi f* fexp 0.25 two-pi f* fexp f+ 0.50 two-pi f* fexp f+ 0.75 two-pi f* fexp f+ over over fneq if 2 >array "edot 4: %s %s?" swap snd-display else 2drop then 0.25 two-pi f* 0-1i c* #( 1.0 2.0 3.0 4.0 ) edot-product 0.00 two-pi f* 0-1i c* cexp 1 c* 0.25 two-pi f* 0-1i c* cexp 2 c* c+ 0.50 two-pi f* 0-1i c* cexp 3 c* c+ 0.75 two-pi f* 0-1i c* cexp 4 c* c+ over over cneq if 2 >array "edot 4 -i: %s %s?" swap snd-display else 2drop then 0.25 two-pi f* 0-1i c* #( 1+1i 2+1i 3+1i 4+1i ) edot-product 0.00 two-pi f* 0-1i c* cexp 1+1i c* 0.25 two-pi f* 0-1i c* cexp 2+1i c* c+ 0.50 two-pi f* 0-1i c* cexp 3+1i c* c+ 0.75 two-pi f* 0-1i c* cexp 4+1i c* c+ over over cneq if 2 >array "edot 4 -i * i: %s %s?" swap snd-display else 2drop then ; [else] <'> noop alias complex-test [then] : print-and-check ( gen name desc -- ) { gen name desc } gen mus-name name string<> if "mus-name %s: %s?" #( name gen mus-name ) snd-display then gen mus-describe desc string<> if "mus-describe %s: %s?" #( name gen ) snd-display then gen { egen } gen egen object-equal? unless "equal? %s: %s %s?" #( name gen egen ) snd-display then ; : test-gen-equal ( g0 g1 g2 -- ) { g0 g1 g2 } \ g0 g1 = \ g0 g2 <> at start g0 { g3 } g0 g3 object-equal? unless "let %s: %s equal? %s?" #( g0 mus-name g0 g3 ) snd-display then g0 g1 object-equal? unless "%s: %s equal? %s?" #( g0 mus-name g0 g1 ) snd-display then g0 g2 object-equal? if "%s: %s equal? %s?" #( g0 mus-name g0 g2 ) snd-display then g0 0.0 0.0 mus-apply drop g3 #( 0.0 0.0 ) object-apply drop g3 0.0 0.0 mus-apply drop g0 g3 object-equal? unless "run let %s: %s equal? %s?" #( g0 mus-name g0 g3 ) snd-display then g0 g1 object-equal? if "run %s: %s equal? %s?" #( g0 mus-name g0 g1 ) snd-display then g0 g2 object-equal? if "run %s: %s equal? %s?" #( g0 mus-name g0 g2 ) snd-display then ; \ bind-key proc : C-xC-c <{ -- }> 0 snd-exit ; \ hooks : my-test1-proc <{ fname -- f }> #f ; <'> my-test1-proc alias my-test2-proc <'> my-test1-proc alias my-test3-proc <'> my-test1-proc alias my-test4-proc <'> my-test1-proc alias my-test5-proc : my-local-thunk <{ -- }> open-hook object-length 3 <> if "add-hook! local length: %d?" #( open-hook object-length ) snd-display then open-hook "my-test3-proc" hook-member? unless "local3 add-hook!: %s" #( open-hook ) snd-display then open-hook "my-test4-proc" hook-member? unless "local4 add-hook!: %s" #( open-hook ) snd-display then open-hook "my-test5-proc" hook-member? unless "local5 add-hook!: %s" #( open-hook ) snd-display then ; : 27-sel-from-snd ( -- ) \ play etc (from test 5) "oboe.snd" open-sound { ind } ind x-bounds { bnds } x-position-slider { xp } y-position-slider { yp } x-zoom-slider { xz } y-zoom-slider { yz } " open-so" snd-completion " open-sound" "completion (1)" #() snd-test-neq " zoom-focus-r" snd-completion " zoom-focus-right" "completion (2)" #() snd-test-neq "oboe.snd" :wait #t play drop "oboe.snd" :start 12000 :wait #t play drop "oboe.snd" :start 1200 :end 15000 :wait #t play drop ind :edit-position #f #f edit-position 1- :wait #t play drop ind close-sound drop \ hooks open-hook reset-hook! open-hook <'> my-test1-proc add-hook! open-hook <'> my-test2-proc add-hook! open-hook object-length 2 <> if "add-hook! global length: %d?" #( open-hook object-length ) snd-display then open-hook "my-test1-proc" hook-member? unless "global1 add-hook!: %s" #( open-hook ) snd-display then open-hook <'> my-test2-proc hook-member? unless "global2 add-hook!: %s" #( open-hook ) snd-display then open-hook #( <'> my-test3-proc <'> my-test4-proc <'> my-test5-proc ) <'> my-local-thunk with-local-hook open-hook object-length 2 <> if "add-hook! reset length: %d?" #( open-hook object-length ) snd-display then open-hook <'> my-test1-proc hook-member? unless "reset1 add-hook!: %s" #( open-hook ) snd-display then open-hook "my-test2-proc" hook-member? unless "reset2 add-hook!: %s" #( open-hook ) snd-display then \ bind-key <'> C-xC-c { prc } "c" 4 #t key-binding { old-prc } "c" 4 prc #t bind-key { prc1 } "c" 4 #t key-binding { prc2 } prc prc1 <> if "bind-key: %s %s?" #( prc prc1 ) snd-display then prc prc2 <> if "key-binding: %s %s?" #( prc prc2 ) snd-display then old-prc proc? if "c" 4 old-prc #t bind-key drop else "c" 4 #t unbind-key drop then "fmv.snd" 1 22050 mus-bshort mus-next "set-samples test" 100 new-sound to ind \ new-sound 10 3 3 0.1 make-vct set-samples drop 0 20 ind 0 channel->vct { res } res vct( 0 0 0 0 0 0 0 0 0 0 0.1 0.1 0.1 0 0 0 0 0 0 0 ) vequal? unless "1 set samples 0 for 0.1: %s?" #( res ) snd-display then ind close-sound drop \ x-axis-label (test005) *with-test-gui* if "oboe.snd" open-sound to ind #t set-transform-graph? drop #t set-time-graph? drop x-axis-label to res res "time" string<> if "get time x-axis-label: %s?" #( res ) snd-display then "hiho1" ind 0 time-graph set-x-axis-label drop x-axis-label to res res "hiho1" string<> if "set time x-axis-label: %s?" #( res ) snd-display then update-transform-graph drop ind 0 transform-graph x-axis-label to res res "frequency" string<> if "get fft x-axis-label: %s?" #( res ) snd-display then "hiho2" ind 0 transform-graph set-x-axis-label drop update-transform-graph drop ind 0 transform-graph x-axis-label to res res "hiho2" string<> if "set fft x-axis-label: %s?" #( res ) snd-display then "frequency" ind 0 transform-graph set-x-axis-label drop '( 0 0 1 1 2 0 ) "lisp" graph drop update-lisp-graph drop ind 0 lisp-graph x-axis-label to res res "lisp" string<> if "get lisp x-axis-label: %s?" #( res ) snd-display then "hiho3" ind 0 lisp-graph set-x-axis-label drop ind 0 lisp-graph x-axis-label to res res "hiho3" string<> if "set lisp x-axis-label: %s?" #( res ) snd-display then "hiho4" ind 0 time-graph set-y-axis-label drop y-axis-label to res res "hiho4" string<> if "set time y-axis-label: %s?" #( res ) snd-display then "hiho5" ind 0 lisp-graph set-y-axis-label drop ind 0 lisp-graph y-axis-label to res res "hiho5" string<> if "set lisp y-axis-label: %s?" #( res ) snd-display then #f set-y-axis-label drop "hiho6" ind 0 set-y-axis-label drop ind 0 y-axis-label to res res "hiho6" string<> if "set time y-axis-label (time): %s?" #( res ) snd-display then #f set-y-axis-label drop ind close-sound drop then \ *with-test-gui* \ edot-product (test008) complex-test \ delay (test008) 3 make-delay { gen } 3 make-delay { gen2 } 4 :initial-contents #( 1.0 0.5 0.25 0.0 ) make-delay { gen1 } 4 :initial-contents vct( 1.0 0.5 0.25 0.0 ) make-delay { gen3 } gen "delay" "delay line[3, step]: [0 0 0]" print-and-check 10 0.0 make-vct map gen i 0.0 delay end-map { v0 } 10 0.0 make-vct map gen2 delay? if gen2 i 0.0 delay else -1.0 then end-map { v1 } v0 v1 vequal? unless "map delay: %s %s?" #( v0 v1 ) snd-display then gen delay? unless "%s not a delay?" #( gen ) snd-display then gen mus-length 3 <> if "delay length: %d?" #( gen mus-length ) snd-display then v0 1 vct-ref 0.0 fneq v0 4 vct-ref 1.0 fneq || v0 8 vct-ref 5.0 fneq || if "delay output: %s?" #( v0 ) snd-display then gen1 0.0 0.0 delay 1.0 fneq gen1 0.0 0.0 delay 0.5 fneq || gen1 0.0 0.0 delay 0.25 fneq || gen1 0.0 0.0 delay 0.0 fneq || gen1 0.0 0.0 delay 0.0 fneq || if "delay with list initial-contents confused" #f snd-display then gen3 0.0 0.0 delay 1.0 fneq gen3 0.0 0.0 delay 0.5 fneq || gen3 0.0 0.0 delay 0.25 fneq || gen3 0.0 0.0 delay 0.0 fneq || gen3 0.0 0.0 delay 0.0 fneq || if "delay with vct initial-contents confused" #f snd-display then :size #f <'> make-delay snd-test-catch to res res 0 array-ref 'wrong-type-arg object-equal? unless "make-delay bad size false: %s" #( res ) snd-display then make-oscil { osc } 3 :initial-element osc <'> make-delay snd-test-catch to res res 0 array-ref 'wrong-type-arg object-equal? unless "make-delay bad initial element: %s" #( res ) snd-display then -3 <'> make-delay snd-test-catch to res res 0 array-ref 'out-of-range object-equal? unless "make-delay bad size: %s" #( res ) snd-display then 3 make-delay { d1 } 3 make-delay { d2 } 4 make-delay { d3 } d1 1.0 0.0 delay drop d2 1.0 0.0 delay drop d3 1.0 0.0 delay drop d1 d2 d3 test-gen-equal 3 :initial-element 1.0 make-delay to d1 3 :initial-element 1.0 make-delay to d2 3 :initial-element 0.5 make-delay to d3 d1 d2 d3 test-gen-equal 3 :initial-contents #( 1.0 0.0 0.0 ) make-delay to d1 3 :initial-contents #( 1.0 0.0 0.0 ) make-delay to d2 3 :initial-contents #( 1.0 1.0 1.0 ) make-delay to d3 d1 d2 d3 test-gen-equal \ mix (test009) *with-test-gtk* unless \ FIXME: set-mix-amp-env (gtk segfault) \ crashes in set-mix-amp-env with gtk "hiho.wave" 1 22050 mus-bshort mus-next new-sound { new-index } new-index select-sound drop 0 new-index 0 find-mix to res res if "found non-existent mix: %s?" #( res ) snd-display then "pistol.snd" 100 mix car { mix-id } mix-id mix? unless "%s not mix?" #( mix-id ) snd-display then view-mixes-dialog drop mix-id mix-position { pos } mix-id mix-length { len } mix-id mix-speed { spd } mix-id mix-home { home-lst } home-lst 0 array-ref { snd } home-lst 1 array-ref { chn } mix-id mix-amp { amp } mix-id make-mix-sampler { mr } mr mix-sampler? unless "%s is not mix-sampler?" #( mr ) snd-display then mr region-sampler? if "mix-sampler: region %s?" #( mr ) snd-display then mr sampler-position to res res 0<> if "mix sampler-position: %d?" #( res ) snd-display then mr sampler-at-end? if "mix sampler-at-end: %s?" #( mr ) snd-display then mr sampler-home to res mix-id res object-equal? unless "mix sampler-home: %d %s?" #( res mr ) snd-display then mr object->string 0 16 string-substring to res res "# if "mix sampler actually got: [%s]?" #( res ) snd-display then 1234 integer->mix <'> mix-amp snd-test-catch to res res 0 array-ref 'no-such-mix object-equal? unless "mix-amp bad id: %s" #( res ) snd-display then 1234 integer->mix 0.1 <'> set-mix-amp snd-test-catch to res res 0 array-ref 'no-such-mix object-equal? unless "set-mix-amp bad id: %s" #( res ) snd-display then 1234 integer->mix #( 0 0 1 1 ) <'> set-mix-amp-env snd-test-catch to res res 0 array-ref 'no-such-mix object-equal? unless "set-mix-amp-env bad id: %s" #( res ) snd-display then 0.0 0.0 { mx sx } 99 0 do \ XXX: i odd? if mr read-mix-sample else mr read-mix-sample then to mx mr read-mix-sample to mx 100 i + sample to sx mx sx fneq if "read-mix-sample: %s %s?" #( mx sx ) snd-display then loop \ Scheme: (mr) \ Ruby: mr.call \ Forth: mr #() apply mr #() object-apply to mx 199 sample to sx mx sx fneq if "read-mix-sample 100: %s %s?" #( mx sx ) snd-display then mr free-sampler drop \ 100 pos <> if "mix-position: %d?" #( pos ) snd-display then 41623 len <> if "mix-length: %d?" #( len ) snd-display then snd new-index object-equal? unless "snd mix-home: %s?" #( snd ) snd-display then chn 0<> if "chn mix-home: %d?" #( chn ) snd-display then amp 1.0 fneq if "mix-amp: %s?" #( amp ) snd-display then spd 1.0 fneq if "mix-speed: %s?" #( spd ) snd-display then .stack mix-id <'> play #t nil fth-catch if drop \ on stack: mix-id "cannot play mix" #() snd-display else drop \ on stack: play's return value then stack-reset mix-id :start 1000 <'> play #t nil fth-catch if stack-reset \ on stack: mix-id :start 1000 "cannot play mix from 1000" #() snd-display else drop \ on stack: play's return value stack-reset then .stack \ mix-id 200 set-mix-position drop mix-id 0.5 set-mix-amp drop mix-id 2.0 set-mix-speed drop mix-id #( 0 0 1 1 ) set-mix-amp-env drop mix-id mix-amp-env to res mix-id res set-mix-amp-env drop mix-id mix-amp-env { res1 } res res1 vequal? unless "set-mix-amp-env to self: %s %s?" #( res res1 ) snd-display then mix-id 20 set-mix-tag-y drop mix-id mix-position to pos mix-id mix-speed to spd mix-id mix-amp to amp mix-id mix-tag-y { my } 200 pos <> if "set-mix-position: %d?" #( pos ) snd-display then spd 2.0 fneq if "set-mix-speed: %s?" #( spd ) snd-display then my 20 <> if "set-mix-tag-y: %d?" #( my ) snd-display then amp 0.5 fneq if "set-mix-amp: %s?" #( amp ) snd-display then mix-id mix-amp-env to res res #( 0.0 0.0 1.0 1.0 ) array= unless "set-mix-amp-env: %s?" #( res ) snd-display then \ 3 0.1 make-vct 100 #f #f #t "" mix-vct drop 0 set-cursor drop 100 #f #f find-mix { nid } nid mix? false? unless nid mix-position 100 <> if new-index 0 mixes map *key* mix-position end-map { mx-pos } "100 find-mix: %s %s %s?" #( nid dup mix-position mx-pos ) snd-display then else "100 find-mix: not a mix %s?" #( nid ) snd-display then 200 #f #f find-mix to nid nid mix? false? unless nid mix-position 200 <> if new-index 0 mixes map *key* mix-position end-map { mx-pos } "200 find-mix: %s %s %s?" #( nid dup mix-position mx-pos ) snd-display then else "200 find-mix: not a mix %s?" #( nid ) snd-display then \ "oboe.snd" 100 mix car to mix-id 40 set-mix-waveform-height drop 'hiho mix-id 123 set-mix-property 'hiho mix-id mix-property to res res 123 <> if "mix-property: %s?" #( res ) snd-display then 'not-here mix-id mix-property to res res if "mix-property not-here: %s?" #( res ) snd-display then #f #f update-time-graph drop 20 set-mix-waveform-height drop new-index revert-sound drop new-index close-sound drop then \ !*with-test-gtk* \ envelopes (lists, vcts, arrays) (test015) 1.0 vct( 0.0 0.0 2.0 1.0 ) 1.0 envelope-interp dup 0.5 fneq if "envelope-interp 0.5: %s?" swap snd-display else drop then 1.0 #( 0.0 0.0 1.0 1.0 2.0 0.0 ) 1.0 envelope-interp dup 1.0 fneq if "envelope-interp 1.0: %s?" swap snd-display else drop then 2.0 #( 0.0 0.0 1.0 1.0 ) 1.0 envelope-interp dup 1.0 fneq if "envelope-interp 1.0: %s?" swap snd-display else drop then 0.0 #( 1.0 0.5 2.0 0.0 ) 1.0 envelope-interp dup 0.5 fneq if "envelope-interp 0.5: %s?" swap snd-display else drop then 0.0 #( -1.0 0.0 0.0 1.0 1.0 -1.0 ) 1.0 envelope-interp dup 1.0 fneq if "envelope-interp 1.0; %s?" swap snd-display else drop then -0.5 #( -1.0 0.0 0.0 1.0 1.0 -1.0 ) 1.0 envelope-interp dup 0.5 fneq if "envelope-interp 0.5: %s?" swap snd-display else drop then -0.5 #( -1.0 -1.0 0.0 1.0 1.0 -1.0 ) 1.0 envelope-interp dup 0.0 fneq if "envelope-interp 0.0: %s?" swap snd-display else drop then -0.5 #( -1.0 -1.0 1.0 1.0 ) 1.0 envelope-interp dup -0.5 fneq if "envelope-interp -0.5: %s?" swap snd-display else drop then -1.5 #( -1.0 -1.0 1.0 1.0 ) 1.0 envelope-interp dup -1.0 fneq if "envelope-interp -1.0: %s?" swap snd-display else drop then 1.5 #( -1.0 -1.0 1.0 1.0 ) 1.0 envelope-interp dup 1.0 fneq if "envelope-interp 1.0: %s?" swap snd-display else drop then 0.1 #( 0.0 0.0 1.0 1.0 ) 1.0 envelope-interp dup 0.1 fneq if "envelope-interp 0.1: %s?" swap snd-display else drop then 0.1 #( 0.0 0.0 1.0 1.0 ) 32.0 envelope-interp dup 0.01336172 fneq if "envelope-interp (exp 32): %s?" swap snd-display else drop then 0.1 #( 0.0 0.0 1.0 1.0 ) 0.012 envelope-interp dup 0.36177473 fneq if "envelope-interp (exp 0.012): %s?" swap snd-display else drop then 0.3 #( 0.0 0.0 0.5 1.0 1.0 0.0 ) 1.0 envelope-interp dup 0.6 fneq if "envelope-interp 0.6: %s?" swap snd-display else drop then #( 0.0 0.0 0.5 0.5 1.0 0.5 ) { v0 } #( 0.0 0.0 2.0 0.5 ) #( 0.0 0.0 1.0 2.0 2.0 1.0 ) multiply-envelopes dup v0 0 fveql unless "multiply-envelopes: %s?" swap snd-display else drop then #( 0.0 0.0 0.5 0.5 1.0 0.0 ) to v0 #( 0.0 0.0 1.0 1.0 ) #( 0.0 0.0 1.0 1.0 2.0 0.0 ) multiply-envelopes dup v0 0 fveql unless "multiply-envelopes: %s?" swap snd-display else drop then #( 0.0 0.0 1.0 1.0 2.0 3.0 4.0 0.0 ) max-envelope dup 3.0 fneq if "0 max-envelope: %s?" swap snd-display else drop then #( 0.0 1.0 ) max-envelope dup 1.0 fneq if "1 max-envelope: %s?" swap snd-display else drop then #( 0.0 1.0 1.0 1.0 2.0 2.0 ) max-envelope dup 2.0 fneq if "2 max-envelope: %s?" swap snd-display else drop then #( 0.0 -1.0 1.0 -2.0 ) max-envelope dup -1.0 fneq if "3 max-envelope: %s?" swap snd-display else drop then #( 0.0 -2.0 1.0 -1.0 ) max-envelope dup -1.0 fneq if "4 max-envelope: %s?" swap snd-display else drop then #( 0.0 0.0 1.0 1.0 2.0 3.0 4.0 0.0 ) min-envelope dup 0.0 fneq if "0 min-envelope: %s?" swap snd-display else drop then #( 0.0 1.0 ) min-envelope dup 1.0 fneq if "1 min-envelope: %s?" swap snd-display else drop then #( 0.0 1.0 1.0 1.0 2.0 2.0 ) min-envelope dup 1.0 fneq if "2 min-envelope: %s?" swap snd-display else drop then #( 0.0 -1.0 1.0 -2.0 ) min-envelope dup -2.0 fneq if "3 min-envelope: %s?" swap snd-display else drop then #( 0.0 -2.0 1.0 -1.0 ) min-envelope dup -2.0 fneq if "4 min-envelope: %s?" swap snd-display else drop then #( 0.0 0.0 0.2 0.1 1.0 1.0 ) to v0 #( 0.0 0.0 1.0 1.0 ) 0.1 0.2 #f #f stretch-envelope dup v0 0 fveql unless "stretch-envelope att: %s?" swap snd-display else drop then #( 0.0 0.0 0.2 0.1 1.1 1.0 1.6 0.5 2.0 0.0 ) to v0 #( 0.0 0.0 1.0 1.0 2.0 0.0 ) 0.1 0.2 1.5 1.6 stretch-envelope dup v0 0 fveql unless "stretch-envelope dec: %s?" swap snd-display else drop then #( 0.0 0.0 0.2 0.1 1.1 1.0 1.6 0.5 2.0 0.0 ) to v0 #( 0.0 0.0 1.0 1.0 2.0 0.0 ) 0.1 0.2 1.5 1.6 stretch-envelope dup v0 0 fveql unless "stretch-envelope: %s?" swap snd-display else drop then #( 0.0 0.0 0.5 1.5 1.0 1.0 ) to v0 #( 0.0 0.0 1.0 1.0 2.0 0.0 ) #( 0.0 0.0 1.0 1.0 ) add-envelopes dup v0 0 fveql unless "add-envelopes: %s?" swap snd-display else drop then #( 0.0 0.0 1.0 2.0 ) to v0 #( 0.0 0.0 1.0 1.0 ) 2.0 scale-envelope dup v0 0 fveql unless "scale-envelope: %s?" swap snd-display else drop then #( 0.0 1.0 1.0 0.0 ) to v0 #( 0.0 0.0 1.0 1.0 ) reverse-envelope dup v0 0 fveql unless "reverse-envelope: %s?" swap snd-display else drop then #( 0.0 0.0 1.5 1.0 2.0 0.0 ) to v0 #( 0.0 0.0 0.5 1.0 2.0 0.0 ) reverse-envelope dup v0 0 fveql unless "reverse-envelope: %s?" swap snd-display else drop then #( 0.0 1.0 1.5 1.0 2.0 0.0 ) to v0 #( 0.0 0.0 0.5 1.0 2.0 1.0 ) reverse-envelope dup v0 0 fveql unless "reverse-envelope: %s?" swap snd-display else drop then ; \ ---------------- test 28: errors ---------------- : check-error-tag { xt expected-tag -- } xt snd-test-catch { tag } tag if \ we ignore #f tag car expected-tag <> if "%s: expected %s from %s, got %s?" #( get-func-name expected-tag xt tag ) snd-display then then ; *with-test-motif* [if] : snd-motif-error-checks ( -- ) '( 'Widget 0 ) <'> widget-position 'no-such-widget check-error-tag '( 'Widget 0 ) <'> widget-size 'no-such-widget check-error-tag '( 'Widget 0 ) <'> widget-text 'no-such-widget check-error-tag '( 'Widget 0 ) #( 0 0 ) <'> set-widget-position 'no-such-widget check-error-tag '( 'Widget 0 ) #( 10 10 ) <'> set-widget-size 'no-such-widget check-error-tag '( 'Widget 0 ) "hiho" <'> set-widget-text 'no-such-widget check-error-tag nil nil { prc tag } #( <'> widget-position <'> widget-size <'> widget-text <'> hide-widget <'> show-widget <'> focus-widget ) each to prc '( 'Widget 0 ) prc snd-test-catch to tag tag if tag car 'no-such-widget <> if "%s of null widget -> %s" #( prc tag ) snd-display then then end-each ; [else] <'> noop alias snd-motif-error-checks [then] [ifundef] mus-audio-reinitialize : mus-audio-reinitialize ( -- n ) 0 ; [then] : pt-test-1 <{ a -- f }> #f ; : pt-test-2 <{ a b -- f }> #f ; : pt-test-3 <{ a b c -- f }> #f ; #( 1 2 3 ) constant color-95 440 make-oscil constant delay-32 0 make-array constant vector-0 3 0.0 make-vct constant vct-3 5 0.0 make-vct constant vct-5 #( <'> make-all-pass <'> make-asymmetric-fm <'> make-snd->sample <'> make-moving-average <'> make-comb <'> make-filtered-comb <'> make-convolve <'> make-delay <'> make-env <'> make-fft-window <'> make-file->frample <'> make-file->sample <'> make-filter <'> make-fir-filter <'> make-formant <'> make-firmant <'> make-frample->file <'> make-granulate <'> make-iir-filter <'> make-locsig <'> make-notch <'> make-one-pole <'> make-one-zero <'> make-oscil <'> make-pulse-train <'> make-rand <'> make-rand-interp <'> make-readin <'> make-sample->file <'> make-sawtooth-wave <'> make-nrxysin <'> make-nrxycos <'> make-square-wave <'> make-src <'> make-ncos <'> make-nsin <'> make-table-lookup <'> make-triangle-wave <'> make-two-pole <'> make-two-zero <'> make-wave-train <'> make-phase-vocoder <'> make-ssb-am <'> make-polyshape <'> make-polywave <'> make-player <'> make-region ) constant make-procs #( :frequency :initial-phase :wave :cosines :amplitude :ratio :size :a0 :a1 :a2 :b1 :b2 :input :srate :file :channel :start :initial-contents :initial-element :scaler :feedforward :feedback :max-size :radius :gain :partials :r :a :n :fill-time :order :xcoeffs :ycoeffs :envelope :base :duration :offset :end :direction :degree :distance :reverb :output :fft-size :expansion :length :hop :ramp :jitter :type :format :comment :channels :filter :revout :width :edit :synthesize :analyze :interp :overlap :pitch :distribution :sines :dur ) constant keyargs #( <'> add-mark <'> add-sound-file-extension <'> add-source-file-extension <'> sound-file-extensions <'> sound-file? <'> add-to-main-menu <'> add-to-menu <'> add-transform <'> amp-control <'> ask-about-unsaved-edits <'> as-one-edit <'> ask-before-overwrite <'> auto-resize <'> auto-update <'> autocorrelate <'> axis-info <'> apply-controls <'> change-samples-with-origin <'> channel-style <'> channels <'> chans <'> close-sound <'> combined-data-color <'> comment <'> contrast-control <'> contrast-control-amp <'> contrast-control? <'> convolve-selection-with <'> convolve-with <'> channel-properties <'> channel-property <'> amp-control-bounds <'> speed-control-bounds <'> expand-control-bounds <'> contrast-control-bounds <'> reverb-control-length-bounds <'> reverb-control-scale-bounds <'> cursor-update-interval <'> cursor-location-offset <'> auto-update-interval <'> cursor <'> with-tracking-cursor <'> cursor-size <'> cursor-style <'> tracking-cursor-style <'> dac-combines-channels <'> dac-size <'> clipping <'> sample-type <'> data-location <'> data-size <'> default-output-chans <'> default-output-sample-type <'> default-output-srate <'> default-output-header-type <'> define-envelope <'> delete-mark <'> delete-marks <'> forget-region <'> delete-sample <'> delete-samples <'> delete-samples-and-smooth <'> delete-selection <'> delete-selection-and-smooth <'> display-edits <'> edit-fragment <'> edit-position <'> edit-tree <'> edits <'> env-selection <'> env-sound <'> enved-envelope <'> enved-base <'> enved-clip? <'> enved-in-dB <'> enved-style <'> enved-power <'> enved-target <'> enved-wave? <'> eps-file <'> eps-left-margin <'> eps-bottom-margin <'> eps-size <'> expand-control <'> expand-control-hop <'> expand-control-jitter <'> expand-control-length <'> expand-control-ramp <'> expand-control? <'> fft <'> fft-window-alpha <'> fft-window-beta <'> fft-log-frequency <'> fft-log-magnitude <'> transform-size <'> disk-kspace <'> transform-graph-type <'> fft-window <'> transform-graph? <'> file-name <'> filter-sound <'> filter-control-in-dB <'> filter-control-envelope <'> enved-filter-order <'> enved-filter <'> filter-control-in-hz <'> filter-control-order <'> filter-selection <'> filter-channel <'> filter-control? <'> find-mark <'> find-sound <'> finish-progress-report <'> framples <'> free-sampler <'> graph <'> transform? <'> delete-transform <'> graph-cursor <'> graph->ps <'> gl-graph->ps <'> graph-style <'> lisp-graph? <'> graphs-horizontal <'> header-type <'> in <'> insert-region <'> insert-sample <'> insert-samples <'> insert-samples-with-origin <'> insert-selection <'> insert-silence <'> insert-sound <'> just-sounds <'> left-sample <'> listener-prompt <'> make-mix-sampler <'> make-player <'> make-region <'> make-region-sampler <'> make-sampler <'> map-chan <'> mark-name <'> mark-properties <'> mark-property <'> mark-sample <'> mark-sync <'> mark-sync-max <'> mark-home <'> marks <'> mark? <'> max-transform-peaks <'> max-regions <'> maxamp <'> maxamp-position <'> min-dB <'> log-freq-start <'> mix <'> mixes <'> mix-amp <'> mix-amp-env <'> mix-length <'> mix? <'> mix-position <'> mix-properties <'> mix-property <'> mix-name <'> mix-region <'> mix-sampler? <'> mix-selection <'> mix-sound <'> mix-home <'> mix-speed <'> mix-tag-height <'> mix-tag-width <'> mark-tag-height <'> mark-tag-width <'> mix-tag-y <'> mix-vct <'> mix-waveform-height <'> time-graph-style <'> lisp-graph-style <'> transform-graph-style <'> read-mix-sample <'> next-sample <'> show-full-duration <'> show-full-range <'> initial-beg <'> initial-dur <'> transform-normalization <'> open-raw-sound <'> open-sound <'> previous-sample <'> peaks <'> player? <'> players <'> print-length <'> progress-report <'> read-only <'> redo <'> region-chans <'> region-home <'> region-graph-style <'> region-framples <'> region-position <'> region-maxamp <'> region-maxamp-position <'> remember-sound-state <'> selection-maxamp <'> selection-maxamp-position <'> region-sample <'> region->vct <'> region-srate <'> regions <'> region? <'> remove-from-menu <'> reset-controls <'> restore-controls <'> restore-region <'> reverb-control-decay <'> reverb-control-feedback <'> reverb-control-length <'> reverb-control-lowpass <'> reverb-control-scale <'> reverb-control? <'> reverse-sound <'> reverse-selection <'> revert-sound <'> right-sample <'> sample <'> sampler-at-end? <'> sampler? <'> samples <'> sampler-position <'> save-controls <'> peak-env-dir <'> save-dir <'> save-edit-history <'> save-envelopes <'> save-listener <'> save-marks <'> save-region <'> save-selection <'> save-sound <'> save-sound-as <'> save-state <'> save-state-file <'> scale-by <'> scale-selection-by <'> scale-selection-to <'> scale-to <'> search-procedure <'> select-all <'> select-channel <'> select-sound <'> selected-channel <'> selected-sound <'> selection-position <'> selection-creates-region <'> selection-framples <'> selection-member? <'> selection? <'> short-file-name <'> show-axes <'> show-controls <'> show-transform-peaks <'> show-indices <'> show-listener <'> show-selection <'> unselect-all <'> show-marks <'> show-mix-waveforms <'> show-selection-transform <'> show-y-zero <'> sinc-width <'> show-grid <'> show-sonogram-cursor <'> grid-density <'> smooth-sound <'> smooth-selection <'> snd-spectrum <'> snd-tempnam <'> snd-version <'> sound-files-in-directory <'> sound-loop-info <'> sound? <'> sounds <'> spectrum-end <'> spectro-hop <'> spectrum-start <'> spectro-x-angle <'> spectro-x-scale <'> spectro-y-angle <'> spectro-y-scale <'> spectro-z-angle <'> spectro-z-scale <'> speed-control <'> speed-control-style <'> speed-control-tones <'> squelch-update <'> srate <'> src-sound <'> src-selection <'> start-progress-report <'> stop-player <'> stop-playing <'> swap-channels <'> syncd-marks <'> sync <'> sync-max <'> sound-properties <'> sound-property <'> temp-dir <'> region-sampler? <'> transform-sample <'> transform->vct <'> transform-framples <'> transform-type <'> with-file-monitor <'> undo <'> update-transform-graph <'> update-time-graph <'> update-lisp-graph <'> update-sound <'> clm-table-size <'> with-verbose-cursor <'> view-sound <'> wavelet-type <'> with-inset-graph <'> with-interrupts <'> with-pointer-focus <'> with-smpte-label <'> with-toolbar <'> with-tooltips <'> with-menu-icons <'> save-as-dialog-src <'> save-as-dialog-auto-comment <'> time-graph? <'> time-graph-type <'> wavo-hop <'> wavo-trace <'> window-height <'> window-width <'> window-x <'> window-y <'> with-mix-tags <'> with-relative-panes <'> with-gl <'> x-axis-style <'> beats-per-measure <'> beats-per-minute <'> x-bounds <'> x-position-slider <'> x-zoom-slider <'> mus-header-type->string <'> mus-sample-type->string <'> y-bounds <'> y-position-slider <'> y-zoom-slider <'> zero-pad <'> zoom-focus-style <'> sync-style <'> mus-sound-samples <'> mus-sound-framples <'> mus-sound-duration <'> mus-sound-datum-size <'> mus-sound-data-location <'> data-size <'> mus-sound-chans <'> mus-sound-srate <'> mus-sound-header-type <'> mus-sound-sample-type <'> mus-sound-length <'> mus-sound-type-specifier <'> mus-header-type-name <'> mus-sample-type-name <'> mus-sound-comment <'> mus-sound-write-date <'> mus-bytes-per-sample <'> mus-sound-loop-info <'> mus-alsa-squelch-warning <'> mus-sound-maxamp <'> mus-sound-maxamp-exists? <'> mus-clipping <'> mus-file-clipping <'> mus-header-raw-defaults <'> moving-average <'> moving-average? <'> make-moving-average <'> mus-expand-filename <'> all-pass <'> all-pass? <'> amplitude-modulate <'> array->file <'> array-interp <'> mus-interpolate <'> asymmetric-fm <'> asymmetric-fm? <'> comb <'> comb? <'> filtered-comb <'> filtered-comb? <'> contrast-enhancement <'> convolution <'> convolve <'> convolve? <'> db->linear <'> degrees->radians <'> delay <'> delay? <'> dot-product <'> env <'> env-interp <'> env? <'> file->array <'> file->frample <'> file->frample? <'> file->sample <'> file->sample? <'> filter <'> filter? <'> fir-filter <'> fir-filter? <'> formant <'> formant-bank <'> formant? <'> frample->file <'> frample->file? <'> frample->frample <'> granulate <'> granulate? <'> hz->radians <'> iir-filter <'> iir-filter? <'> in-any <'> ina <'> inb <'> linear->db <'> locsig <'> locsig-ref <'> locsig-reverb-ref <'> locsig-reverb-set! <'> locsig-set! <'> locsig? <'> make-all-pass <'> make-asymmetric-fm <'> make-comb <'> make-filtered-comb <'> make-convolve <'> make-delay <'> make-env <'> make-fft-window <'> make-file->frample <'> make-file->sample <'> make-filter <'> make-fir-filter <'> make-formant <'> make-frample->file <'> make-granulate <'> make-iir-filter <'> make-locsig <'> move-locsig <'> make-notch <'> make-one-pole <'> make-one-zero <'> make-oscil <'> make-pulse-train <'> make-rand <'> make-rand-interp <'> make-readin <'> make-sample->file <'> make-sawtooth-wave <'> make-square-wave <'> make-src <'> make-ssb-am <'> make-table-lookup <'> make-triangle-wave <'> make-two-pole <'> make-two-zero <'> make-wave-train <'> move-sound <'> make-move-sound <'> move-sound? <'> mus-float-equal-fudge-factor <'> mus-array-print-length <'> mus-channel <'> mus-channels <'> make-polyshape <'> polyshape? <'> mus-close <'> mus-data <'> mus-feedback <'> mus-feedforward <'> mus-fft <'> mus-frequency <'> mus-hop <'> mus-increment <'> mus-input? <'> mus-file-name <'> mus-length <'> mus-location <'> mus-order <'> mus-output? <'> mus-phase <'> mus-ramp <'> mus-random <'> mus-scaler <'> mus-srate <'> mus-xcoeffs <'> mus-ycoeffs <'> notch <'> notch? <'> one-pole <'> one-pole? <'> one-zero <'> one-zero? <'> oscil <'> oscil? <'> out-any <'> outa <'> outb <'> outc <'> outd <'> partials->polynomial <'> partials->wave <'> phase-partials->wave <'> polynomial <'> pulse-train <'> pulse-train? <'> radians->degrees <'> radians->hz <'> rand <'> rand-interp <'> rand-interp? <'> rand? <'> readin <'> readin? <'> rectangular->polar <'> rectangular->magnitudes <'> ring-modulate <'> sample->file <'> sample->file? <'> sawtooth-wave <'> sawtooth-wave? <'> spectrum <'> square-wave <'> square-wave? <'> src <'> src? <'> ssb-am <'> ssb-am? <'> table-lookup <'> table-lookup? <'> tap <'> triangle-wave <'> triangle-wave? <'> two-pole <'> two-pole? <'> two-zero <'> two-zero? <'> wave-train <'> wave-train? <'> make-vct <'> vct-add! <'> vct-subtract! <'> vct-length <'> vct-multiply! <'> vct-offset! <'> vct-ref <'> vct-scale! <'> vct-set! <'> vct-peak <'> vct? <'> list->vct <'> vct->list <'> vector->vct <'> vct->vector <'> vct-move! <'> vct-reverse! <'> vct-subseq <'> vct <'> little-endian? <'> vct->string <'> clm-channel <'> env-channel <'> map-channel <'> scan-channel <'> reverse-channel <'> seconds->samples <'> samples->seconds <'> smooth-channel <'> vct->channel <'> channel->vct <'> src-channel <'> scale-channel <'> ramp-channel <'> pad-channel <'> normalize-channel <'> cursor-position <'> show-listener <'> mus-sound-prune <'> mus-sound-forget <'> xramp-channel <'> snd->sample <'> snd->sample? <'> make-snd->sample <'> beats-per-minute <'> beats-per-measure <'> channel-amp-envs <'> convolve-files <'> filter-control-coeffs <'> locsig-type <'> make-phase-vocoder <'> mus-describe <'> mus-error-type->string <'> mus-file-buffer-size <'> mus-name <'> mus-offset <'> mus-out-format <'> mus-reset <'> mus-rand-seed <'> mus-width <'> phase-vocoder? <'> polar->rectangular <'> phase-vocoder-amp-increments <'> phase-vocoder-amps <'> phase-vocoder-freqs <'> phase-vocoder-phase-increments <'> phase-vocoder-phases <'> mus-generator? <'> read-sample <'> reset-listener-cursor <'> goto-listener-end <'> sampler-home <'> selection-chans <'> selection-srate <'> snd-warning <'> channel-data <'> x-axis-label <'> variable-graph? <'> y-axis-label <'> snd-url <'> snd-urls <'> free-player <'> delete-mix <'> delay-tick <'> playing <'> pausing <'> copy-sampler <'> html-dir <'> html-program <'> make-fir-coeffs <'> mus-interp-type <'> mus-run <'> phase-vocoder <'> player-home <'> redo-edit <'> undo-edit ) constant procs #( <'> amp-control <'> ask-before-overwrite <'> auto-update <'> channel-style <'> sound-file-extensions <'> show-full-duration <'> show-full-range <'> initial-beg <'> initial-dur <'> contrast-control <'> contrast-control-amp <'> combined-data-color <'> amp-control-bounds <'> speed-control-bounds <'> expand-control-bounds <'> contrast-control-bounds <'> reverb-control-length-bounds <'> reverb-control-scale-bounds <'> cursor-update-interval <'> cursor-location-offset <'> contrast-control? <'> auto-update-interval <'> cursor <'> channel-properties <'> channel-property <'> with-tracking-cursor <'> cursor-size <'> cursor-style <'> tracking-cursor-style <'> dac-combines-channels <'> dac-size <'> clipping <'> default-output-chans <'> default-output-sample-type <'> default-output-srate <'> default-output-header-type <'> dot-size <'> enved-envelope <'> enved-base <'> enved-clip? <'> enved-in-dB <'> enved-style <'> enved-power <'> enved-target <'> enved-wave? <'> eps-file <'> eps-left-margin <'> eps-bottom-margin <'> eps-size <'> expand-control <'> expand-control-hop <'> expand-control-jitter <'> expand-control-length <'> expand-control-ramp <'> expand-control? <'> fft-window-alpha <'> fft-window-beta <'> fft-log-frequency <'> fft-log-magnitude <'> transform-size <'> transform-graph-type <'> fft-window <'> transform-graph? <'> filter-control-in-dB <'> filter-control-envelope <'> enved-filter-order <'> enved-filter <'> filter-control-in-hz <'> filter-control-order <'> filter-control? <'> graph-cursor <'> graph-style <'> lisp-graph? <'> graphs-horizontal <'> just-sounds <'> left-sample <'> listener-prompt <'> mark-name <'> mark-properties <'> mark-property <'> mark-sample <'> mark-sync <'> max-transform-peaks <'> min-dB <'> log-freq-start <'> mix-amp <'> mix-amp-env <'> mix-name <'> mix-position <'> mix-properties <'> mix-property <'> mix-speed <'> mix-tag-height <'> mix-tag-width <'> mix-tag-y <'> mark-tag-width <'> mark-tag-height <'> mix-waveform-height <'> transform-normalization <'> print-length <'> play-arrow-size <'> region-graph-style <'> reverb-control-decay <'> reverb-control-feedback <'> reverb-control-length <'> reverb-control-lowpass <'> reverb-control-scale <'> time-graph-style <'> lisp-graph-style <'> transform-graph-style <'> reverb-control? <'> ladspa-dir <'> peak-env-dir <'> save-dir <'> save-state-file <'> selection-creates-region <'> show-axes <'> show-controls <'> show-transform-peaks <'> show-indices <'> show-marks <'> show-mix-waveforms <'> show-selection-transform <'> show-y-zero <'> show-grid <'> show-sonogram-cursor <'> sinc-width <'> spectrum-end <'> spectro-hop <'> spectrum-start <'> spectro-x-angle <'> grid-density <'> spectro-x-scale <'> spectro-y-angle <'> spectro-y-scale <'> spectro-z-angle <'> spectro-z-scale <'> speed-control <'> speed-control-style <'> speed-control-tones <'> squelch-update <'> sync <'> sound-properties <'> sound-property <'> temp-dir <'> y-bounds <'> transform-type <'> with-file-monitor <'> with-verbose-cursor <'> with-inset-graph <'> with-interrupts <'> with-pointer-focus <'> wavelet-type <'> x-bounds <'> with-smpte-label <'> with-toolbar <'> with-tooltips <'> with-menu-icons <'> save-as-dialog-src <'> save-as-dialog-auto-comment <'> time-graph? <'> wavo-hop <'> wavo-trace <'> with-gl <'> with-mix-tags <'> x-axis-style <'> beats-per-minute <'> zero-pad <'> zoom-focus-style <'> sync-style <'> with-relative-panes <'> window-x <'> window-y <'> window-width <'> window-height <'> beats-per-measure <'> channels <'> chans <'> comment <'> sample-type <'> data-location <'> data-size <'> edit-position <'> framples <'> header-type <'> maxamp <'> read-only <'> right-sample <'> sample <'> samples <'> selected-channel <'> selected-sound <'> selection-position <'> selection-framples <'> selection-member? <'> sound-loop-info <'> srate <'> time-graph-type <'> x-position-slider <'> x-zoom-slider <'> y-position-slider <'> y-zoom-slider <'> mus-array-print-length <'> mus-float-equal-fudge-factor <'> mus-data <'> mus-feedback <'> mus-feedforward <'> mus-frequency <'> mus-hop <'> mus-increment <'> mus-length <'> mus-location <'> mus-phase <'> mus-ramp <'> mus-scaler <'> vct-ref <'> x-axis-label <'> filter-control-coeffs <'> locsig-type <'> mus-file-buffer-size <'> mus-rand-seed <'> mus-width <'> clm-table-size <'> mus-offset <'> mus-reset <'> phase-vocoder-amp-increments <'> phase-vocoder-amps <'> phase-vocoder-freqs <'> phase-vocoder-phase-increments <'> phase-vocoder-phases <'> html-dir <'> html-program <'> mus-interp-type <'> locsig-ref <'> locsig-reverb-ref <'> mus-clipping <'> mus-file-clipping <'> mus-header-raw-defaults ) constant set-procs : arity-not-ok <{ prc args -- f }> prc args arity-ok not ; : set-arity-not-ok <{ prc args -- f }> prc args set-arity-ok not ; procs <'> arity-not-ok 0 array-reject constant procs00 procs <'> arity-not-ok 1 array-reject constant procs01 procs <'> arity-not-ok 2 array-reject constant procs02 procs <'> arity-not-ok 3 array-reject constant procs03 procs <'> arity-not-ok 4 array-reject constant procs04 procs <'> arity-not-ok 5 array-reject constant procs05 procs <'> arity-not-ok 6 array-reject constant procs06 procs <'> arity-not-ok 7 array-reject constant procs07 procs <'> arity-not-ok 8 array-reject constant procs08 procs <'> arity-not-ok 10 array-reject constant procs10 set-procs <'> set-arity-not-ok 1 array-reject constant set-procs00 set-procs <'> set-arity-not-ok 2 array-reject constant set-procs01 set-procs <'> set-arity-not-ok 3 array-reject constant set-procs02 set-procs <'> set-arity-not-ok 4 array-reject constant set-procs03 set-procs <'> set-arity-not-ok 5 array-reject constant set-procs04 : close-sound-mc-cb { -- prc; y self -- val } 1 proc-create "oboe.snd" open-sound , ( prc ) does> { y self -- val } self @ { ind } ind sound? if ind close-sound drop then 0.0 ; : close-sound-aoe-1-cb { -- prc; self -- val } 0 proc-create "oboe.snd" open-sound , "pistol.snd" open-sound , does> { self -- val } self @ ( ind1 ) close-sound drop self cell+ @ ( ind2 ) close-sound ; : close-sound-aoe-2b-cb { ind1 ind2 -- prc; self -- val } 0 proc-create ind1 , ind2 , ( prc ) does> { self -- val } self @ ( ind1 ) close-sound drop self cell+ @ ( ind2 ) close-sound ; : close-sound-aoe-2a-cb { -- prc; self -- val } 0 proc-create "oboe.snd" open-sound , "pistol.snd" open-sound , does> { self -- val } self @ { ind1 } self cell+ @ { ind2 } 100 0.1 ind1 0 set-sample drop 100 0.1 ind2 0 set-sample drop ind1 ind2 close-sound-aoe-2b-cb "inner-edit" as-one-edit ; : close-sound-fc-cb { -- prc; y self -- f } 1 proc-create "oboe.snd" open-sound , ( prc ) does> { y self -- f } self @ { ind } ind sound? if ind close-sound drop then #f ; : sc-1-cb { mx -- prc; x self -- f } 1 proc-create mx , ( prc ) does> { x self -- f } x fabs self @ @ ( mx ) fmax self @ ! #f ; : mc-2-cb { ind -- prc; y self -- val } 1 proc-create ind , ( prc ) does> { y self -- val } y 0.4 f> if 1 self @ ( ind ) 0 set-framples drop then y ; *with-test-complex* [if] : mc-3-cb <{ y -- val }> y 0.0+1.0i c* ; [else] <'> noop alias mc-3-cb [then] : edpos-1-cb { ind -- prc; self -- edpos } 0 proc-create ind , ( prc ) does> { self -- edpos } self @ ( ind ) close-sound drop current-edit-position ; : edpos-2-cb <{ snd chn -- edpos }> snd close-sound drop current-edit-position ; : check-args-progress-info { msg -- } *snd-test-verbose* if msg #f snd-test-message then ; : 28-errors ( -- ) #t set-with-background-processes drop reset-almost-all-hooks nil nil { prc tag } #( <'> amp-control <'> comment <'> contrast-control <'> amp-control-bounds <'> speed-control-bounds <'> expand-control-bounds <'> contrast-control-bounds <'> reverb-control-length-bounds <'> reverb-control-scale-bounds <'> contrast-control-amp <'> contrast-control? <'> sample-type <'> data-location <'> data-size <'> expand-control <'> expand-control-hop <'> expand-control-jitter <'> expand-control-length <'> expand-control-ramp <'> expand-control? <'> filter-control-in-dB <'> filter-control-in-hz <'> filter-control-envelope <'> filter-control-order <'> filter-control? <'> finish-progress-report <'> header-type <'> read-only <'> reset-controls <'> restore-controls <'> reverb-control-decay <'> reverb-control-feedback <'> reverb-control-length <'> reverb-control-lowpass <'> reverb-control-scale <'> reverb-control? <'> save-controls <'> select-sound <'> short-file-name <'> sound-loop-info <'> soundfont-info <'> speed-control <'> speed-control-style <'> speed-control-tones <'> srate <'> channel-style <'> start-progress-report <'> sync <'> swap-channels ) { prcs-1 } prcs-1 #( <'> apply-controls <'> close-sound <'> channels <'> chans <'> file-name <'> framples <'> progress-report <'> sound-property <'> sound-properties ) array-append each to prc 123 integer->sound prc snd-test-catch to tag tag if tag car 'no-such-sound <> if "snd no-such-sound %s: %s" #( prc tag ) snd-display then then end-each #( 1 make-array "hiho" 0+i 1.5 '( 1 0 ) #( 0 1 ) ) { args-1 } #( vct-5 1+i "hiho" delay-32 ) { args-2 } nil { arg } args-1 each to arg prcs-1 #( <'> apply-controls <'> close-sound <'> sound-properties ) array-append each to prc arg prc snd-test-catch to tag tag if tag car 'wrong-type-arg <> tag car 'mus-error <> && if "snd wrong-type-arg %s: %s (%s)" #( prc tag arg ) snd-display then then end-each end-each args-2 each to arg prcs-1 #( <'> channels <'> chans <'> framples ) array-append each to prc \ XXX: snd/chn val | val snd/chn \ snd/chn before value \ g_set_channels(snd, val) arg 0 \ snd/chn after value \ g_set_amp_control(val, snd, chn) 0 arg prc <'> channels = prc <'> chans = || prc <'> sample-type = || prc <'> data-location = || prc <'> data-size = || prc <'> header-type = || prc <'> srate = || prc <'> comment = || if arg 0 else 0 arg then prc set-xt snd-test-catch to tag tag if tag car 'wrong-type-arg <> tag car 'syntax-error <> && tag car 'error <> && if "snd set wrong-type-arg set-%s [%s]: %s" #( prc arg tag ) snd-display then then end-each end-each "obtest.snd" open-sound { ind } #( <'> amp-control <'> contrast-control <'> contrast-control-amp <'> contrast-control? <'> expand-control <'> amp-control-bounds <'> speed-control-bounds <'> expand-control-bounds <'> contrast-control-bounds <'> reverb-control-length-bounds <'> reverb-control-scale-bounds <'> expand-control-hop <'> expand-control-jitter <'> expand-control-length <'> expand-control-ramp <'> expand-control? <'> filter-control-in-dB <'> filter-control-in-hz <'> filter-control-envelope <'> filter-control-order <'> filter-control? <'> reverb-control-decay <'> reverb-control-feedback <'> reverb-control-length <'> reverb-control-lowpass <'> reverb-control-scale <'> reverb-control? <'> speed-control <'> speed-control-style <'> speed-control-tones <'> channel-style <'> sync ) { prcs-2 } args-2 each to arg prcs-2 each to prc arg ind prc set-xt snd-test-catch to tag tag if tag car 'wrong-type-arg <> if "snd safe set wrong-type-arg set-%s [%s]: %s" #( prc arg tag ) snd-display then then end-each end-each ind close-sound drop args-1 each to arg #( <'> make-vct <'> vct-length <'> vct->list <'> vct-peak ) each to prc arg prc snd-test-catch to tag tag if tag car 'wrong-type-arg <> if "vct 0 wrong-type-arg %s [%s]: %s" #( prc arg tag ) snd-display then then end-each end-each #( <'> vct-add! <'> vct-subtract! <'> vct-multiply! <'> vct-ref <'> vct-scale! ) { vct-prcs-2 } nil nil { arg1 arg2 } args-1 each to arg1 args-1 each to arg2 vct-prcs-2 each to prc arg1 arg2 prc snd-test-catch to tag tag if tag car 'wrong-type-arg <> tag car 'wrong-number-of-args <> && tag car 'mus-error <> && if "vct 1 wrong-whatever %s [%s %s]: %s" #( prc arg1 arg2 tag ) snd-display then then end-each end-each end-each args-1 each to arg vct-prcs-2 each to prc arg vct-3 prc snd-test-catch to tag tag if tag car 'wrong-type-arg <> if "vct 2 wrong-whatever %s [%s]: %s" #( prc arg tag ) snd-display then then end-each end-each -23 <'> make-vct snd-test-catch to tag tag car 'out-of-range <> if "make-vct -23: %s" #( tag ) snd-display then vct-3 { v } v 12 <'> vct-ref snd-test-catch to tag tag car 'out-of-range <> if "vct[12]: %s" #( tag ) snd-display then #( <'> all-pass? <'> asymmetric-fm? <'> comb? <'> filtered-comb? <'> convolve? <'> delay? <'> env? <'> file->frample? <'> file->sample? <'> snd->sample? <'> filter? <'> fir-filter? <'> formant? <'> firmant? <'> frample->file? <'> granulate? <'> iir-filter? <'> locsig? <'> move-sound? <'> mus-input? <'> mus-output? <'> notch? <'> one-pole? <'> one-zero? <'> oscil? <'> phase-vocoder? <'> pulse-train? <'> rand-interp? <'> rand? <'> readin? <'> sample->file? <'> sawtooth-wave? <'> nrxysin? <'> nrxycos? <'> square-wave? <'> src? <'> ncos? <'> nsin? <'> table-lookup? <'> triangle-wave? <'> two-pole? <'> two-zero? <'> wave-train? <'> color? <'> mix-sampler? <'> moving-average? <'> ssb-am? <'> sampler? <'> region-sampler? <'> vct? ) { ?prcs } args-1 each to arg ?prcs each to prc arg prc snd-test-catch to tag tag if tag car 'wrong-type-arg <> if "?proc %s [%s]: %s" #( prc arg tag ) snd-display then then end-each end-each ?prcs each to prc 440 make-oscil prc snd-test-catch to tag tag if "oscil?proc %s [440 make-oscil]: %s" #( prc tag ) snd-display then end-each #( <'> reverse-selection <'> selection-position <'> selection-framples <'> smooth-selection <'> scale-selection-to <'> insert-selection <'> delete-selection <'> delete-selection-and-smooth <'> mix-selection ) each to prc prc snd-test-catch to tag tag if tag car 'no-active-selection <> if "0 selection %s: %s" #( prc tag ) snd-display then then end-each #( <'> src-selection <'> filter-selection <'> env-selection ) each to prc 0.0 prc snd-test-catch to tag tag if tag car 'no-active-selection <> if "1 selection %s: %s" #( prc tag ) snd-display then then end-each #( <'> all-pass <'> asymmetric-fm <'> comb <'> filtered-comb <'> convolve <'> db->linear <'> moving-average <'> degrees->radians <'> delay <'> env <'> formant <'> firmant <'> granulate <'> hz->radians <'> linear->db <'> make-all-pass <'> make-asymmetric-fm <'> make-comb <'> make-filtered-comb <'> make-convolve <'> make-delay <'> make-env <'> make-file->frample <'> make-file->sample <'> make-filter <'> make-fir-filter <'> make-formant <'> make-firmant <'> make-granulate <'> make-iir-filter <'> make-locsig <'> make-notch <'> make-one-pole <'> make-one-zero <'> make-oscil <'> make-pulse-train <'> make-rand <'> make-rand-interp <'> make-readin <'> make-sawtooth-wave <'> make-nrxysin <'> make-nrxycos <'> make-square-wave <'> make-src <'> make-ncos <'> make-nsin <'> make-table-lookup <'> make-triangle-wave <'> make-two-pole <'> make-two-zero <'> make-wave-train <'> make-ssb-am <'> mus-channel <'> mus-channels <'> make-polyshape <'> make-polywave <'> mus-data <'> mus-feedback <'> mus-feedforward <'> mus-frequency <'> mus-hop <'> mus-increment <'> mus-length <'> mus-file-name <'> mus-location <'> mus-name <'> mus-order <'> mus-phase <'> mus-ramp <'> mus-random <'> mus-run <'> mus-scaler <'> mus-xcoeffs <'> mus-ycoeffs <'> notch <'> one-pole <'> one-zero <'> make-moving-average <'> seconds->samples <'> samples->seconds <'> oscil <'> partials->polynomial <'> partials->wave <'> phase-partials->wave <'> phase-vocoder <'> pulse-train <'> radians->degrees <'> radians->hz <'> rand <'> rand-interp <'> readin <'> sawtooth-wave <'> nrxysin <'> nrxycos <'> square-wave <'> src <'> ncos <'> nsin <'> table-lookup <'> tap <'> triangle-wave <'> two-pole <'> two-zero <'> wave-train <'> ssb-am ) { clm-prcs-1 } #( 1 make-array color-95 '( 1.0 ) ) each to arg clm-prcs-1 each to prc arg prc snd-test-catch to tag tag if tag car 'wrong-type-arg <> tag car 'no-data <> && tag car 'no-such-method <> && tag car 'bad-type <> && tag car 'error <> && tag car 'arg-error <> && if "clm %s [%s]: %s" #( prc arg tag ) snd-display then then end-each end-each #( <'> all-pass <'> array-interp <'> asymmetric-fm <'> comb <'> filtered-comb <'> contrast-enhancement <'> convolution <'> convolve <'> moving-average <'> convolve-files <'> delay <'> dot-product <'> env-interp <'> file->sample <'> snd->sample <'> filter <'> fir-filter <'> formant <'> firmant <'> formant-bank <'> granulate <'> iir-filter <'> ina <'> inb <'> locsig-ref <'> locsig-reverb-ref <'> make-all-pass <'> make-asymmetric-fm <'> make-comb <'> make-filtered-comb <'> make-delay <'> make-env <'> make-fft-window <'> make-filter <'> make-fir-filter <'> make-formant <'> make-firmant <'> make-granulate <'> make-iir-filter <'> make-locsig <'> make-notch <'> make-one-pole <'> make-one-zero <'> make-oscil <'> make-phase-vocoder <'> make-pulse-train <'> make-rand <'> make-rand-interp <'> make-readin <'> make-sawtooth-wave <'> make-moving-average <'> make-nrxysin <'> make-nrxycos <'> make-square-wave <'> make-src <'> make-ncos <'> make-nsin <'> make-table-lookup <'> make-triangle-wave <'> make-two-pole <'> make-two-zero <'> make-wave-train <'> notch <'> one-pole <'> one-zero <'> oscil <'> partials->polynomial <'> partials->wave <'> make-polyshape <'> make-polywave <'> phase-partials->wave <'> phase-vocoder <'> polynomial <'> pulse-train <'> rand <'> rand-interp <'> rectangular->polar <'> rectangular->magnitudes <'> ring-modulate <'> sawtooth-wave <'> nrxysin <'> nrxycos <'> square-wave <'> src <'> ncos <'> nsin <'> table-lookup <'> tap <'> triangle-wave <'> two-pole <'> two-zero <'> wave-train <'> ssb-am <'> make-ssb-am ) each to prc make-oscil vct-5 prc snd-test-catch to tag tag if tag car 'wrong-type-arg <> tag car 'bad-arity <> && tag car 'error <> && tag car 'mus-error <> && if "clm-1 %s [make-oscil]: %s" #( prc tag ) snd-display then then end-each #( <'> mus-channel <'> mus-channels <'> mus-data <'> mus-feedback <'> mus-feedforward <'> mus-frequency <'> mus-hop <'> mus-increment <'> mus-length <'> mus-location <'> mus-name <'> mus-order <'> mus-phase <'> mus-ramp <'> mus-random <'> mus-run <'> mus-scaler <'> mus-xcoeffs <'> mus-ycoeffs ) each to prc make-oscil vector-0 prc snd-test-catch to tag tag if tag car 'wrong-type-arg <> tag car 'syntax-error <> && tag car 'error <> && if "mus-gen %s [make-oscil]: %s" #( prc tag ) snd-display then then end-each #( <'> mus-sound-samples <'> mus-sound-framples <'> mus-sound-duration <'> mus-sound-datum-size <'> mus-sound-data-location <'> mus-sound-chans <'> mus-sound-srate <'> mus-sound-header-type <'> mus-sound-sample-type <'> mus-sound-length <'> mus-sound-type-specifier <'> mus-header-type-name <'> mus-sample-type-name <'> mus-sound-comment <'> mus-sound-write-date <'> mus-bytes-per-sample <'> mus-sound-loop-info <'> mus-sound-mark-info <'> mus-sound-maxamp <'> mus-sound-maxamp-exists? <'> mus-header-type->string <'> mus-sample-type->string ) { mus-snd-prcs-1 } mus-snd-prcs-1 each to prc vct-5 prc snd-test-catch to tag tag if tag car 'wrong-type-arg <> if "mus-sound %s: %s" #( prc tag ) snd-display then then end-each mus-snd-prcs-1 each to prc prc snd-test-catch to tag tag if tag car 'wrong-number-of-args <> tag car 'error <> && if "no arg mus-sound %s: %s" #( prc tag ) snd-display then then end-each #( <'> mus-sound-samples <'> mus-sound-framples <'> mus-sound-duration <'> mus-sound-datum-size <'> mus-sound-data-location <'> mus-sound-chans <'> mus-sound-srate <'> mus-sound-header-type <'> mus-sound-sample-type <'> mus-sound-length <'> mus-sound-type-specifier <'> mus-sound-comment <'> mus-sound-write-date <'> mus-sound-maxamp <'> mus-sound-maxamp-exists? ) each to prc "/bad/baddy" prc snd-test-catch to tag tag if tag car 'mus-error <> if "bad file mus-sound %s: %s" #( prc tag ) snd-display then then end-each "/bad/baddy" mus-sound-forget drop #( <'> channel-widgets <'> cursor <'> channel-properties <'> channel-property <'> cursor-position <'> cursor-size <'> cursor-style <'> tracking-cursor-style <'> delete-sample <'> display-edits <'> dot-size <'> edit-fragment <'> edit-position <'> edit-tree <'> edits <'> fft-window-alpha <'> fft-window-beta <'> fft-log-frequency <'> fft-log-magnitude <'> fft-with-phases <'> transform-size <'> transform-graph-type <'> fft-window <'> transform-graph? <'> graph <'> graph-style <'> lisp-graph? <'> insert-sound <'> time-graph-style <'> lisp-graph-style <'> transform-graph-style <'> left-sample <'> make-graph-data <'> map-chan <'> max-transform-peaks <'> maxamp-position <'> min-dB <'> mix-region <'> transform-normalization <'> peaks <'> position->x <'> position->y <'> reverse-sound <'> revert-sound <'> right-sample <'> sample <'> save-sound <'> save-sound-as <'> select-channel <'> show-axes <'> show-transform-peaks <'> show-marks <'> show-mix-waveforms <'> show-y-zero <'> show-grid <'> show-sonogram-cursor <'> spectrum-end <'> spectro-hop <'> spectrum-start <'> spectro-x-angle <'> spectro-x-scale <'> spectro-y-angle <'> grid-density <'> spectro-y-scale <'> spectro-z-angle <'> spectro-z-scale <'> squelch-update <'> transform-sample <'> transform->vct <'> transform-framples <'> transform-type <'> update-transform-graph <'> update-time-graph <'> update-lisp-graph <'> update-sound <'> wavelet-type <'> time-graph? <'> time-graph-type <'> wavo-hop <'> wavo-trace <'> x-bounds <'> x-position-slider <'> x-zoom-slider <'> x-axis-label <'> y-axis-label <'> y-bounds <'> y-position-slider <'> y-zoom-slider <'> zero-pad ) { chn-prcs } chn-prcs each to prc vct-5 prc snd-test-catch to tag tag if tag car 'wrong-type-arg <> tag car 'error <> && tag car 'no-such-sound <> && if "chn (no snd) procs %s: %s" #( prc tag ) snd-display then then end-each chn-prcs <'> combined-data-color array-push each to prc 0 vct-5 prc snd-test-catch to tag tag if tag car 'wrong-type-arg <> if "chn (no chn) procs %s: %s" #( prc tag ) snd-display then then end-each #( <'> channel-widgets <'> cursor <'> channel-properties <'> cursor-position <'> cursor-size <'> cursor-style <'> tracking-cursor-style <'> display-edits <'> dot-size <'> edit-position <'> edit-tree <'> edits <'> env-sound <'> fft-window-alpha <'> fft-window-beta <'> fft-log-frequency <'> fft-log-magnitude <'> fft-with-phases <'> transform-size <'> transform-graph-type <'> fft-window <'> transform-graph? <'> filter-sound <'> graph-data <'> graph-style <'> lisp-graph? <'> left-sample <'> time-graph-style <'> lisp-graph-style <'> transform-graph-style <'> make-graph-data <'> max-transform-peaks <'> maxamp <'> maxamp-position <'> min-dB <'> transform-normalization <'> reverse-sound <'> revert-sound <'> right-sample <'> save-sound <'> scale-by <'> scale-to <'> show-axes <'> show-transform-peaks <'> show-marks <'> show-mix-waveforms <'> show-y-zero <'> show-grid <'> show-sonogram-cursor <'> spectrum-end <'> spectro-hop <'> spectrum-start <'> spectro-x-angle <'> spectro-x-scale <'> spectro-y-angle <'> spectro-y-scale <'> spectro-z-angle <'> spectro-z-scale <'> squelch-update <'> grid-density <'> src-sound <'> transform->vct <'> transform-framples <'> transform-type <'> update-transform-graph <'> update-time-graph <'> update-lisp-graph <'> update-sound <'> wavelet-type <'> time-graph? <'> time-graph-type <'> wavo-hop <'> wavo-trace <'> x-bounds <'> x-position-slider <'> x-zoom-slider <'> y-bounds <'> y-position-slider <'> x-axis-label <'> y-axis-label <'> y-zoom-slider <'> zero-pad ) each to prc 1234 integer->sound prc snd-test-catch to tag tag if tag car 'no-such-sound <> if "chn procs %s: %s" #( prc tag ) snd-display then then end-each #( <'> delete-sample <'> edit-fragment <'> graph-data <'> graph-style <'> play <'> position->x <'> position->y <'> redo <'> time-graph-style <'> lisp-graph-style <'> transform-graph-style <'> scale-by <'> scale-to <'> undo <'> x->position <'> y->position <'> x-axis-label ) each to prc 0 1234 prc snd-test-catch to tag tag if tag car 'no-such-sound <> if "snd(1) chn procs %s: %s" #( prc tag ) snd-display then then end-each "oboe.snd" open-sound to ind #( <'> delete-sample <'> edit-fragment <'> graph-data <'> position->x <'> position->y <'> redo <'> scale-by <'> scale-to <'> undo <'> x->position <'> y->position ) each to prc prc proc-name "x-axis-label" string<> if 0 ind 1234 prc snd-test-catch to tag tag if tag car 'no-such-channel <> if "snd(1 1234) chn procs %s: %s" #( prc tag ) snd-display then then then end-each ind close-sound drop "oboe.snd" find-sound sound? if "oboe.snd is still open?" #() snd-display then "oboe.snd" open-sound to ind #( <'> channel-widgets <'> cursor <'> cursor-position <'> cursor-size <'> cursor-style <'> tracking-cursor-style <'> display-edits <'> dot-size <'> edit-position <'> edit-tree <'> edits <'> fft-window-alpha <'> fft-window-beta <'> fft-log-frequency <'> fft-log-magnitude <'> fft-with-phases <'> transform-size <'> transform-graph-type <'> fft-window <'> transform-graph? <'> graph-style <'> lisp-graph? <'> left-sample <'> time-graph-style <'> lisp-graph-style <'> transform-graph-style <'> combined-data-color <'> make-graph-data <'> max-transform-peaks <'> maxamp <'> maxamp-position <'> min-dB <'> transform-normalization <'> reverse-sound <'> right-sample <'> show-axes <'> show-transform-peaks <'> show-marks <'> show-mix-waveforms <'> show-y-zero <'> show-grid <'> show-sonogram-cursor <'> grid-density <'> spectrum-end <'> spectro-hop <'> spectrum-start <'> spectro-x-angle <'> spectro-x-scale <'> spectro-y-angle <'> spectro-y-scale <'> spectro-z-angle <'> spectro-z-scale <'> squelch-update <'> transform->vct <'> transform-framples <'> transform-type <'> update-transform-graph <'> update-time-graph <'> update-lisp-graph <'> wavelet-type <'> time-graph? <'> time-graph-type <'> wavo-hop <'> wavo-trace <'> x-bounds <'> x-position-slider <'> x-axis-label <'> x-zoom-slider <'> y-bounds <'> y-position-slider <'> y-zoom-slider <'> zero-pad <'> channel-properties <'> channel-property ) each to prc ind 1234 prc snd-test-catch to tag tag if tag car 'no-such-channel <> tag car 'no-such-sound <> && if "chn (2) procs %s: %s" #( prc tag ) snd-display then then end-each ind close-sound drop "oboe.snd" find-sound sound? if "oboe.snd is still open?" #() snd-display then "oboe.snd" open-sound to ind #( <'> channel-widgets <'> cursor <'> cursor-position <'> display-edits <'> dot-size <'> edit-tree <'> edits <'> fft-window-alpha <'> fft-window-beta <'> fft-log-frequency <'> fft-log-magnitude <'> fft-with-phases <'> transform-size <'> transform-graph-type <'> fft-window <'> transform-graph? <'> graph-style <'> lisp-graph? <'> left-sample <'> make-graph-data <'> max-transform-peaks <'> maxamp <'> maxamp-position <'> lisp-graph-style <'> transform-graph-style <'> make-graph-data <'> combined-data-color <'> min-dB <'> transform-normalization <'> reverse-sound <'> right-sample <'> show-axes <'> grid-density <'> show-transform-peaks <'> show-marks <'> show-mix-waveforms <'> show-y-zero <'> show-grid <'> show-sonogram-cursor <'> spectrum-end <'> spectro-hop <'> spectrum-start <'> spectro-x-angle <'> spectro-x-scale <'> spectro-y-angle <'> spectro-y-scale <'> spectro-z-angle <'> spectro-z-scale <'> squelch-update <'> transform->vct <'> transform-framples <'> transform-type <'> update-transform-graph <'> update-time-graph <'> update-lisp-graph <'> wavelet-type <'> time-graph? <'> time-graph-type <'> wavo-hop <'> wavo-trace <'> x-bounds <'> x-position-slider <'> x-zoom-slider <'> y-bounds <'> y-position-slider <'> y-zoom-slider <'> zero-pad <'> x-axis-label ) each to prc vct-5 ind 0 prc set-xt snd-test-catch to tag tag if tag car 'wrong-type-arg <> tag car 'syntax-error <> && tag car 'error <> && if "set chn procs %s: %s" #( prc tag ) snd-display then then end-each ind close-sound drop "oboe.snd" find-sound sound? if "oboe.snd is still open?" #() snd-display then #( <'> mix-amp <'> mix-length <'> mix-name <'> mix-position <'> mix-home <'> mix-speed <'> mix-tag-y ) { mix-prcs } mix-prcs #( <'> mix-amp-env ) array-append each to prc vct-5 prc snd-test-catch to tag tag if tag car 'wrong-type-arg <> tag car 'syntax-error <> && tag car 'error <> && if "[0] mix procs %s: %s" #( prc tag ) snd-display then then end-each mix-prcs each to prc 1234 integer->mix prc snd-test-catch to tag tag if tag car 'no-such-mix <> if "[1] mix procs %s: %s" #( prc tag ) snd-display then then end-each #( <'> mix-name <'> mix-position <'> mix-home <'> mix-speed <'> mix-tag-y ) { mix-set-prcs } mix-set-prcs each to prc 1234 integer->mix vct-5 prc set-xt snd-test-catch to tag tag if tag car 'wrong-type-arg <> tag car 'syntax-error <> && tag car 'error <> && tag car 'no-such-mix <> && if "[2] set mix procs %s: %s" #( prc tag ) snd-display then then end-each "oboe.snd" open-sound to ind "oboe.snd" 10 mix-sound { id } mix-set-prcs each to prc id vct-5 prc set-xt snd-test-catch to tag tag if tag car 'wrong-type-arg <> tag car 'syntax-error <> && tag car 'error <> && if "[3] set mix procs %s: %s" #( prc tag ) snd-display then then end-each ind close-sound drop "oboe.snd" find-sound sound? if "oboe.snd is still open?" #() snd-display then #( <'> add-mark <'> mark-name <'> mark-sample <'> mark-sync <'> mark-home <'> delete-mark <'> delete-marks <'> find-mark ) each to prc vct-5 prc snd-test-catch to tag tag if tag car 'wrong-type-arg <> if "mark procs %s: %s" #( prc tag ) snd-display then then end-each #( <'> mark-name <'> mark-sample <'> mark-sync <'> mark-home <'> delete-mark ) each to prc 1234 integer->mark prc snd-test-catch to tag tag if tag car 'no-such-mark <> if "no mark procs %s: %s" #( prc tag ) snd-display then then end-each "oboe.snd" open-sound to ind 0 ind 0 add-mark to id #( <'> mark-name <'> mark-sample <'> mark-sync ) each to prc id vct-5 prc set-xt snd-test-catch to tag tag if tag car 'wrong-type-arg <> if "set mark procs %s: %s" #( prc tag ) snd-display then then end-each ind close-sound drop "oboe.snd" find-sound sound? if "oboe.snd is still open?" #() snd-display then #( <'> region-chans <'> region-home <'> region-framples <'> region-position <'> region-maxamp <'> region-maxamp-position <'> region-srate <'> forget-region ) { reg-prcs-1 } #( vct-5 #( 0 1 ) 0+i "hiho" '( 0 1 ) ) each to arg reg-prcs-1 #( <'> region-sample <'> region->vct ) array-append each to prc arg prc snd-test-catch to tag tag if tag car 'wrong-type-arg <> tag car 'wrong-number-of-args <> && if "region procs %s [%s]: %s" #( prc arg tag ) snd-display then then end-each end-each reg-prcs-1 each to prc 1234 integer->region prc #t nil fth-catch to tag stack-reset tag if tag car 'no-such-region <> if "(no) region procs %s: %s" #( prc tag ) snd-display then then end-each #( <'> axis-color <'> enved-filter-order <'> enved-filter <'> filter-control-waveform-color <'> ask-before-overwrite <'> ask-about-unsaved-edits <'> auto-resize <'> auto-update <'> axis-label-font <'> axis-numbers-font <'> basic-color <'> bind-key <'> show-full-duration <'> show-full-range <'> initial-beg <'> initial-dur <'> channel-style <'> color-cutoff <'> color-orientation-dialog <'> color-inverted <'> color-scale <'> cursor-color <'> dac-combines-channels <'> dac-size <'> clipping <'> data-color <'> default-output-chans <'> default-output-sample-type <'> default-output-srate <'> default-output-header-type <'> enved-envelope <'> enved-base <'> enved-clip? <'> enved-in-dB <'> enved-dialog <'> enved-style <'> enved-power <'> enved-target <'> enved-waveform-color <'> enved-wave? <'> eps-file <'> eps-left-margin <'> eps-bottom-margin <'> eps-size <'> foreground-color <'> graph-color <'> graph-cursor <'> highlight-color <'> just-sounds <'> key-binding <'> listener-color <'> listener-font <'> listener-prompt <'> listener-text-color <'> max-regions <'> mix-waveform-height <'> region-graph-style <'> position-color <'> time-graph-style <'> lisp-graph-style <'> transform-graph-style <'> peaks-font <'> bold-peaks-font <'> print-length <'> play-arrow-size <'> sash-color <'> ladspa-dir <'> peak-env-dir <'> save-dir <'> save-state-file <'> selected-channel <'> selected-data-color <'> selected-graph-color <'> selected-sound <'> selection-creates-region <'> show-controls <'> show-indices <'> show-listener <'> show-selection-transform <'> sinc-width <'> temp-dir <'> text-focus-color <'> tiny-font <'> with-file-monitor <'> unbind-key <'> with-verbose-cursor <'> with-inset-graph <'> with-interrupts <'> with-pointer-focus <'> window-height <'> beats-per-measure <'> with-smpte-label <'> with-toolbar <'> with-tooltips <'> with-menu-icons <'> remember-sound-state <'> save-as-dialog-src <'> save-as-dialog-auto-comment <'> window-width <'> window-x <'> window-y <'> with-gl <'> with-mix-tags <'> x-axis-style <'> beats-per-minute <'> zoom-color <'> mix-tag-height <'> mix-tag-width <'> with-relative-panes <'> clm-table-size <'> clm-default-frequency <'> mark-tag-width <'> mark-tag-height ) each to prc vct-5 prc set-xt snd-test-catch to tag tag if tag car 'wrong-type-arg <> tag car 'syntax-error <> && tag car 'error <> && if "misc procs %s: %s" #( prc tag ) snd-display then then end-each nil { hook } snd-hooks each to hook hook <'> noop 0 make-proc <'> add-hook! snd-test-catch to tag tag if \ XXX: FTH special 'bad-arity (add-hook!) [ms] tag car 'bad-arity <> tag car 'wrong-type-arg <> && if "[0] hooks %s: %s" #( hook hook-name tag ) snd-display then then end-each reset-almost-all-hooks #( <'> exit-hook <'> stop-playing-selection-hook <'> color-hook <'> orientation-hook <'> start-playing-selection-hook ) each to hook hook <'> noop 3 make-proc <'> add-hook! #t nil fth-catch to tag stack-reset tag if \ XXX: FTH special 'bad-arity (add-hook!) [ms] tag car 'bad-arity <> tag car 'wrong-type-arg <> && if "[1] hooks %s: %s" #( hook hook-name tag ) snd-display then then end-each reset-almost-all-hooks #f set-ask-about-unsaved-edits drop #f set-remember-sound-state drop "not-an-env" <'> set-enved-envelope 'no-such-envelope check-error-tag "/bad/baddy" <'> save-envelopes 'cannot-save check-error-tag "/bad/baddy" <'> mus-sound-report-cache 'cannot-save check-error-tag <'> noop 3 make-proc <'> set-search-procedure 'bad-arity check-error-tag 0 "oboe.snd" 1 <'> make-sampler 'no-such-channel check-error-tag 0 "oboe.snd" -1 <'> make-sampler 'no-such-channel check-error-tag p 0 <'> noop 2 make-proc <'> bind-key 'bad-arity check-error-tag <'> noop 1 make-proc <'> set-zoom-focus-style 'bad-arity check-error-tag 123 #( 0 0 1 1 ) <'> set-sound-loop-info 'no-such-sound check-error-tag "fmv.snd" 2 22050 mus-bfloat mus-nist "comment" <'> new-sound 'bad-header check-error-tag 123 <'> player-home 'wrong-type-arg check-error-tag "/hiho" <'> set-temp-dir 'no-such-file check-error-tag "/hiho" <'> set-save-dir 'no-such-file check-error-tag 20 integer->transform 4 0.0 make-vct <'> snd-transform 'out-of-range check-error-tag sf-dir "bad_chans.snd" $+ <'> mus-sound-maxamp 'bad-header check-error-tag :order 32 :ycoeffs 4 0.0 make-vct <'> make-iir-filter 'mus-error check-error-tag :coeffs 4 0 make-vct :ycoeffs 4 0 make-vct <'> make-iir-filter 'mus-error check-error-tag :coeffs 4 0 make-vct :xcoeffs 4 0 make-vct <'> make-fir-filter 'mus-error check-error-tag :size 123456789 <'> make-table-lookup 'out-of-range check-error-tag :ramp -0.5 <'> make-granulate 'out-of-range check-error-tag :ramp 1.5 <'> make-granulate 'out-of-range check-error-tag :expansion 32000.0 <'> make-granulate 'mus-error check-error-tag "test.snd" :channels 0 <'> new-sound 'out-of-range check-error-tag "test.snd" :srate 0 <'> new-sound 'out-of-range check-error-tag "test.snd" :size -1 <'> new-sound 'out-of-range check-error-tag "test.snd" :size 0 <'> make-readin 'out-of-range check-error-tag "test.snd" :size -1 <'> make-readin 'out-of-range check-error-tag "oboe.snd" 0 <'> make-file->sample 'out-of-range check-error-tag "oboe.snd" -1 <'> make-file->sample 'out-of-range check-error-tag "oboe.snd" 0 <'> make-file->frample 'out-of-range check-error-tag "oboe.snd" -1 <'> make-file->frample 'out-of-range check-error-tag -1 <'> set-default-output-sample-type 'out-of-range check-error-tag mus-soundfont <'> set-default-output-header-type 'out-of-range check-error-tag sf-dir "bad_location.nist" $+ <'> mus-sound-chans 'mus-error check-error-tag sf-dir "bad_field.nist" $+ <'> mus-sound-chans 'mus-error check-error-tag snd-motif-error-checks -1 <'> main-menu 'no-such-menu check-error-tag 111 <'> main-menu 'no-such-menu check-error-tag "hiho" :header-type 123 <'> new-sound 'out-of-range check-error-tag "hiho" :header-type mus-nist :sample-type 123 <'> new-sound 'out-of-range check-error-tag "hiho" :header-type mus-nist :sample-type mus-bfloat <'> new-sound 'bad-header check-error-tag -1 <'> set-mus-array-print-length 'out-of-range check-error-tag -1 <'> set-print-length 'out-of-range check-error-tag -1 <'> set-play-arrow-size 'out-of-range check-error-tag 12 <'> set-enved-style 'out-of-range check-error-tag 1.5 0.0 0.0 <'> make-color 'out-of-range check-error-tag -0.5 0.0 0.0 <'> make-color 'out-of-range check-error-tag #f <'> make-variable-graph 'wrong-type-arg check-error-tag <'> graph->ps 'cannot-print check-error-tag "oboe.snd" open-sound to ind #t set-selection-creates-region drop select-all drop "sel0.snd" :not-a-key 3 <'> save-selection 'mus-error check-error-tag '( ind ) <'> read-only 'wrong-type-arg check-error-tag ind '( 0 ) <'> framples 'wrong-type-arg check-error-tag 0 -10 <'> smooth-sound 'wrong-type-arg check-error-tag 0 ind 123 <'> mix-selection 'no-such-channel check-error-tag 0 ind 123 <'> insert-selection 'no-such-channel check-error-tag ind 0 <'> set-channels 'out-of-range check-error-tag ind -1 <'> set-channels 'wrong-type-arg check-error-tag ind 12340 <'> set-channels 'out-of-range check-error-tag ind 12340 <'> set-sample-type 'out-of-range check-error-tag ind 12340 <'> set-header-type 'out-of-range check-error-tag ind 0 <'> set-srate 'out-of-range check-error-tag ind -1 <'> set-data-location 'wrong-type-arg check-error-tag ind -1 <'> set-data-size 'wrong-type-arg check-error-tag -1 -1 <'> set-sample 'no-such-sample check-error-tag -1 <'> sample 'no-such-sample check-error-tag -10 <'> set-framples 'out-of-range check-error-tag 0.0 <'> set-min-dB 'out-of-range check-error-tag 0.0 ind 0 <'> set-min-dB 'out-of-range check-error-tag 1 -22 <'> start-playing 'out-of-range check-error-tag 1 0 <'> start-playing 'out-of-range check-error-tag #( 0.0 1.0 0.1 -0.1 1.0 0.0 ) ind <'> set-filter-control-envelope 'out-of-range check-error-tag #( 0.0 1.0 0.1 1.1 1.0 0.0 ) ind <'> set-filter-control-envelope 'out-of-range check-error-tag #( 0 0 0.1 0.1 0.05 0.1 1 1 ) 32 <'> filter-sound 'env-error check-error-tag ind 123 <'> apply-controls 'out-of-range check-error-tag #( 0.0 2.0 ) <'> set-speed-control-bounds 'out-of-range check-error-tag #( 0.0 2.0 ) <'> set-expand-control-bounds 'out-of-range check-error-tag #( 2.0 0.0 ) <'> set-speed-control-bounds 'out-of-range check-error-tag #( 2.0 0.0 ) <'> set-expand-control-bounds 'out-of-range check-error-tag sf-dir "bad_chans.snd" $+ <'> insert-sound 'bad-header check-error-tag sf-dir "bad_chans.snd" $+ <'> convolve-with 'IO-error check-error-tag "hiho.snd" ind -12 <'> save-sound-as 'cannot-save check-error-tag "hiho.snd" ind :header-type mus-next :sample-type -12 <'> save-sound-as 'cannot-save check-error-tag "test.snd" ind :header-type mus-nist :sample-type mus-bdouble <'> save-sound-as 'cannot-save check-error-tag "test.snd" ind :header-type mus-aifc :sample-type mus-lfloat <'> save-sound-as 'cannot-save check-error-tag "test.snd" ind :header-type mus-riff :sample-type mus-bshort <'> save-sound-as 'cannot-save check-error-tag "test.snd" ind :header-type mus-voc :sample-type mus-bshort <'> save-sound-as 'cannot-save check-error-tag "test.snd" 22050 mus-bshort mus-riff <'> save-selection 'cannot-save check-error-tag "test.snd" 22050 mus-bshort mus-voc <'> save-selection 'cannot-save check-error-tag #( 0 0 1 1 ) :length 11 make-env <'> src-channel 'out-of-range check-error-tag #( 0 1 1 0 ) :length 11 make-env <'> src-channel 'out-of-range check-error-tag #( 0 1 1 -1 ) :length 11 make-env <'> src-channel 'out-of-range check-error-tag #( 0 -1 1 1 ) :length 11 make-env <'> src-channel 'out-of-range check-error-tag #( 0 0 1 1 ) :length 11 make-env <'> src-sound 'out-of-range check-error-tag #( 0 1 1 0 ) :length 11 make-env <'> src-sound 'out-of-range check-error-tag #( 0 1 1 -1 ) :length 11 make-env <'> src-sound 'out-of-range check-error-tag #( 0 -1 1 1 ) :length 11 make-env <'> src-sound 'out-of-range check-error-tag 0.0 0.0 0.0 0.0 0.0 0.0 0.0 <'> make-readin 'mus-error check-error-tag vct-3 32 <'> filter-sound 'out-of-range check-error-tag #( 0 0 1 1 ) 0 <'> filter-sound 'out-of-range check-error-tag ind 0 12345 0 <'> swap-channels 'no-such-sound check-error-tag vct( 0.1 0.2 0.3 ) -1 ind 0 #t "" <'> mix-vct 'no-such-sample check-error-tag 8 0.0 make-vct 0 -123 <'> snd-spectrum 'out-of-range check-error-tag 8 0.0 make-vct 0 0 <'> snd-spectrum 'out-of-range check-error-tag "/baddy/hiho" <'> play 'no-such-file check-error-tag sf-dir "nist-shortpack.wav" $+ <'> play 'bad-sample-type check-error-tag ind 123 <'> make-player 'no-such-channel check-error-tag "/baddy/hiho" <'> mix 'no-such-file check-error-tag "oboe.snd" 0 2 <'> mix 'no-such-channel check-error-tag "/baddy/hiho" 0 <'> mix-sound 'no-such-file check-error-tag "/baddy/hiho.snd" <'> insert-sound 'no-such-file check-error-tag 0 10 "/baddy/hiho.snd" <'> insert-samples 'no-such-file check-error-tag '() ind <'> set-filter-control-envelope 'no-data check-error-tag ind 123 <'> set-sample-type 'out-of-range check-error-tag ind 123 <'> set-header-type 'out-of-range check-error-tag ind 123 <'> set-selected-channel 'no-such-channel check-error-tag <'> noop 3 make-proc <'> set-search-procedure 'bad-arity check-error-tag <'> noop 3 make-proc <'> map-chan 'bad-arity check-error-tag <'> noop 1 make-proc ind 0 <'> set-cursor-style 'bad-arity check-error-tag 0 0 1 1 ind 0 1234 <'> draw-line 'no-such-graphics-context check-error-tag ind 0 1234 <'> foreground-color 'no-such-graphics-context check-error-tag ind 0 1234 <'> current-font 'no-such-graphics-context check-error-tag '( vct-3 vct-3 ) ind 0 1234 0 1 0 <'> graph-data 'no-such-graphics-context check-error-tag 100 ind 0 1234 <'> position->x 'no-such-axis check-error-tag 100 ind 0 1234 <'> position->y 'no-such-axis check-error-tag 100 ind 0 1234 <'> x->position 'no-such-axis check-error-tag 100 ind 0 1234 <'> y->position 'no-such-axis check-error-tag ind 0 1234 <'> axis-info 'no-such-axis check-error-tag *with-test-gui* if channel-widgets car snd-gcs car "hiho" 0.0 1.0 -1.0 1.0 x-axis-in-seconds 1234 <'> draw-axes 'out-of-range check-error-tag channel-widgets car snd-gcs car "hiho" 0.0 1.0 -1.0 1.0 1234 <'> draw-axes 'out-of-range check-error-tag ind 1234 <'> axis-info 'no-such-channel check-error-tag 1234 <'> axis-info 'no-such-sound check-error-tag then graph-once set-time-graph-type drop #( 0.1 -0.1 ) <'> set-x-bounds 'out-of-range check-error-tag 100 0 <'> make-region 'out-of-range check-error-tag -1 <'> delete-sample 'no-such-sample check-error-tag ind framples 2* <'> delete-sample 'no-such-sample check-error-tag "/bad/baddy.snd" <'> play 'no-such-file check-error-tag 1234 0 <'> play 'no-such-sound check-error-tag regions empty? if 0 100 make-region then regions car 0 1234 <'> region-sample 'no-such-channel check-error-tag regions car 1234 <'> region-framples 'no-such-channel check-error-tag regions car 1234 <'> region-position 'no-such-channel check-error-tag "/bad/baddy.snd" <'> save-sound-as 'cannot-save check-error-tag 0 1 1234 <'> transform-sample 'no-such-sound check-error-tag 0 1 ind 1234 <'> transform-sample 'no-such-channel check-error-tag vct( 0 1 ) "hi" 0 1 0 1 1234 <'> graph 'no-such-sound check-error-tag vct( 0 1 ) "hi" 0 1 0 1 ind 1234 <'> graph 'no-such-channel check-error-tag #f #t set-selection-member? drop vct( 0 0 1 1 ) 4 <'> filter-selection 'no-active-selection check-error-tag "/bad/baddy.snd" <'> save-selection 'no-active-selection check-error-tag #( 0 0 1 1 ) <'> env-selection 'no-active-selection check-error-tag 1234 integer->region "/bad/baddy.snd" <'> save-region 'no-such-region check-error-tag 0 100 ind 0 make-region drop "/bad/baddy.snd" <'> save-selection 'cannot-save check-error-tag regions car "/bad/baddy.snd" <'> save-region 'cannot-save check-error-tag 1234 integer->mix <'> make-mix-sampler 'no-such-mix check-error-tag 0 12 1234 #t <'> make-region 'no-such-sound check-error-tag #t ind set-read-only drop \ XXX: snd-nogui and set-read-only \ Snd-nogui has no widget and therefore the sound will not be \ write-protected according to snd-snd.c. ind read-only if ind '( 0 0 1 1 ) <'> set-sound-loop-info 'cannot-save check-error-tag else *with-test-nogui* unless "%s is not read-only?" #( ind ) snd-display then then 0 ind 0 123 <'> make-sampler 'no-such-direction check-error-tag 0 ind 0 0 <'> make-sampler 'no-such-direction check-error-tag 0 ind 0 -2 <'> make-sampler 'no-such-direction check-error-tag '() <'> scale-by 'no-data check-error-tag '() <'> scale-to 'no-data check-error-tag -999 ind 0 <'> set-selection-position 'no-such-sample check-error-tag -999 ind 0 <'> set-selection-framples 'wrong-type-arg check-error-tag 0 ind 0 <'> set-selection-framples 'wrong-type-arg check-error-tag -1 <'> edit-fragment 'no-such-edit check-error-tag 101 ind 0 <'> edit-fragment 'no-such-edit check-error-tag ind 0 -2 <'> edit-tree 'no-such-edit check-error-tag ind 0 101 <'> edit-tree 'no-such-edit check-error-tag -1 <'> add-mark 'no-such-sample check-error-tag framples 2* <'> add-mark 'no-such-sample check-error-tag "/bad/baddy" <'> convolve-with 'no-such-file check-error-tag "/bad/baddy" <'> mix 'no-such-file check-error-tag ind 0 123 <'> swap-channels 'no-such-sound check-error-tag 123 ind 0 <'> set-show-axes 'out-of-range check-error-tag -123 ind 0 <'> set-show-axes 'out-of-range check-error-tag 123 ind 0 <'> set-x-axis-style 'out-of-range check-error-tag -123 ind 0 <'> set-x-axis-style 'out-of-range check-error-tag 123 ind 0 <'> set-graph-style 'out-of-range check-error-tag -123 ind 0 <'> set-graph-style 'out-of-range check-error-tag '( 0 0 1 1 ) 0 #f -1.5 <'> env-sound 'out-of-range check-error-tag 0.0 1.0 -1.6 <'> xramp-channel 'out-of-range check-error-tag 0 2 -1 <'> set-samples 'wrong-type-arg check-error-tag '( 0 ) <'> left-sample 'wrong-type-arg check-error-tag '( 0 ) <'> amp-control 'wrong-type-arg check-error-tag '( 0 ) <'> sound-loop-info 'wrong-type-arg check-error-tag 123 '( 0 ) <'> add-mark 'wrong-type-arg check-error-tag '( 0 0 1 1 ) 100 #f #f 1234 0 <'> filter-channel 'no-such-sound check-error-tag '( 0 0 1 1 ) 100 #f #f ind 1 <'> filter-channel 'no-such-channel check-error-tag vct( 0 0 1 1 ) 4 #f #f ind 1 <'> filter-channel 'no-such-channel check-error-tag vct( 0 0 1 1 ) 0 <'> filter-sound 'out-of-range check-error-tag vct( 0 0 1 1 ) 10 <'> filter-sound 'out-of-range check-error-tag selected-sound 0 :stop <'> noop 0 make-proc <'> play 'bad-arity check-error-tag '( 0.1 0.01 ) ind <'> set-reverb-control-length-bounds 'out-of-range check-error-tag '( 0.1 0.01 ) ind <'> set-reverb-control-scale-bounds 'out-of-range check-error-tag #f <'> scale-by 'wrong-type-arg check-error-tag 3.0 1.0 #t <'> src-sound 'wrong-type-arg check-error-tag 3.0 1.0 ind #t <'> src-sound 'wrong-type-arg check-error-tag ind 0 123 <'> display-edits 'no-such-edit check-error-tag ind 0 123 <'> marks 'no-such-edit check-error-tag "test.snd" :edit-position 123 <'> save-sound-as 'no-such-edit check-error-tag "1a.snd" 0 0 ind 0 0 123 <'> insert-sound 'no-such-auto-delete-choice check-error-tag ind close-sound drop "hiho" "time" 0 1 <'> noop 0 make-proc <'> add-transform 'bad-arity check-error-tag "/bad/baddy" <'> save-state 'cannot-save check-error-tag 1234 "hi" <'> noop 0 make-proc <'> add-to-menu 'no-such-menu check-error-tag "hi" <'> noop 2 make-proc <'> add-to-main-menu 'bad-arity check-error-tag 1 "hi" <'> noop 2 make-proc <'> add-to-menu 'bad-arity check-error-tag -1 integer->transform <'> set-transform-type 'wrong-type-arg check-error-tag 123 integer->transform <'> set-transform-type 'out-of-range check-error-tag '( 0 1 ) "hiho" <'> help-dialog 'wrong-type-arg check-error-tag '( 0 1 ) "hiho" <'> info-dialog 'wrong-type-arg check-error-tag 1234 <'> edit-header-dialog 'no-such-sound check-error-tag "/bad/baddy.snd" <'> open-sound 'no-such-file check-error-tag "/bad/baddy.snd" 1 22050 mus-lshort <'> open-raw-sound 'no-such-file check-error-tag "/bad/baddy.snd" <'> view-sound 'no-such-file check-error-tag 0 "/bad/baddy.snd" <'> make-sampler 'no-such-file check-error-tag 1234567 integer->region 0 <'> make-region-sampler 'no-such-region check-error-tag -1 0 #f <'> bind-key 'no-such-key check-error-tag 12 17 #f <'> bind-key 'no-such-key check-error-tag 12 -1 #f <'> bind-key 'no-such-key check-error-tag 12345678 0 <'> key-binding 'no-such-key check-error-tag -1 0 <'> key-binding 'no-such-key check-error-tag 12 17 <'> key-binding 'no-such-key check-error-tag 12 -1 <'> key-binding 'no-such-key check-error-tag sf-dir "bad_chans.snd" $+ 0 0 123 123 0.0 make-vct <'> file->array 'bad-header check-error-tag sf-dir "bad_chans.snd" $+ <'> make-readin 'bad-header check-error-tag 30 3 0 make-vct <'> make-iir-filter 'mus-error check-error-tag :size 2 30 f** f>s <'> make-wave-train 'out-of-range check-error-tag 0.0 <'> set-mus-srate 'out-of-range check-error-tag -1000 <'> set-mus-srate 'out-of-range check-error-tag 3 0 make-vct 3 0 make-vct -1 <'> dot-product 'out-of-range check-error-tag 3 :initial-element 0.0 :initial-contents vct( 0.1 0.2 0.3 ) <'> make-delay 'out-of-range check-error-tag 3 :max-size 100 :initial-contents vct( 0.1 0.2 0.3 ) <'> make-delay 'out-of-range check-error-tag :size 100 :wave 3 0 make-vct <'> make-table-lookup 'out-of-range check-error-tag :size 100 :wave 3 0 make-vct <'> make-wave-train 'out-of-range check-error-tag 100 12345678 <'> make-ssb-am 'out-of-range check-error-tag :envelope '( 0 0 1 1 ) :distribution 10 0 make-vct <'> make-rand 'mus-error check-error-tag :envelope '( 0 0 1 ) <'> make-rand 'mus-error check-error-tag :envelope '( 0 0 1 1 ) :size -2 <'> make-rand 'out-of-range check-error-tag :envelope '( 0 0 1 1 ) :size 1234567890 <'> make-rand 'out-of-range check-error-tag make-granulate #f <'> noop 3 make-proc <'> granulate 'bad-arity check-error-tag make-phase-vocoder #f <'> noop 0 make-proc <'> phase-vocoder 'bad-arity check-error-tag make-phase-vocoder #f #f <'> noop 0 make-proc <'> phase-vocoder 'bad-arity check-error-tag make-phase-vocoder #f #f #f <'> noop 0 make-proc <'> phase-vocoder 'bad-arity check-error-tag 3 :xcoeffs vct-3 :ycoeffs vct-3 make-filter 4 <'> mus-xcoeff 'mus-error check-error-tag 3 :xcoeffs vct-3 :ycoeffs vct-3 make-filter 4 <'> mus-ycoeff 'mus-error check-error-tag 3 :xcoeffs vct-3 :ycoeffs vct-3 make-filter 4 1.0 <'> set-mus-xcoeff 'mus-error check-error-tag 3 :xcoeffs vct-3 :ycoeffs vct-3 make-filter 4 1.0 <'> set-mus-ycoeff 'mus-error check-error-tag :ycoeffs 4 0 make-vct :order 12 <'> make-filter 'mus-error check-error-tag \ XXX: Switch to float here okay according to clm2xen.c! \ was: make-oscil 1 ==> wrong-type-arg fixnum, wanted a float make-oscil 1.0 <'> set-mus-offset 'mus-error check-error-tag make-oscil 1 <'> set-mus-offset 'wrong-type-arg check-error-tag :channels 2 30 f** f>s <'> make-locsig 'out-of-range check-error-tag :width 3000 <'> make-src 'out-of-range check-error-tag *with-test-gui* if "baddy" <'> noop 0 make-proc <'> add-colormap 'bad-arity check-error-tag "baddy" <'> noop 3 make-proc <'> add-colormap 'bad-arity check-error-tag then :input <'> noop 1 make-proc make-src 2000000.0 <'> src 'out-of-range check-error-tag '( 1 1 ) -1 <'> partials->polynomial 'out-of-range check-error-tag '( 1 1 ) 3 <'> partials->polynomial 'out-of-range check-error-tag :partials '( 1 1 ) :kind -1 <'> make-polyshape 'out-of-range check-error-tag :partials '( 1 1 ) :kind 3 <'> make-polyshape 'out-of-range check-error-tag 32 <'> normalize-partials 'wrong-type-arg check-error-tag '() <'> normalize-partials 'wrong-type-arg check-error-tag '( 1 2 3 ) <'> normalize-partials 'bad-type check-error-tag vct( 3 ) <'> normalize-partials 'bad-type check-error-tag 440.0 :partials vct( 1 1 -2 1 ) <'> make-polyshape 'no-data check-error-tag 440.0 :partials list( 1 1 -2 1 ) <'> make-polyshape 'no-data check-error-tag 440.0 :partials '() <'> make-polyshape 'no-data check-error-tag 1234 <'> set-mus-header-raw-defaults 'wrong-type-arg check-error-tag '( 44100 2.123 "hi" ) <'> set-mus-header-raw-defaults 'wrong-type-arg check-error-tag 123 <'> set-with-toolbar 'wrong-type-arg check-error-tag 123 <'> set-with-tooltips 'wrong-type-arg check-error-tag 123 <'> set-with-menu-icons 'wrong-type-arg check-error-tag 123 <'> set-save-as-dialog-src 'wrong-type-arg check-error-tag 123 <'> set-save-as-dialog-auto-comment 'wrong-type-arg check-error-tag 123 <'> set-with-smpte-label 'wrong-type-arg check-error-tag 123 <'> set-ask-about-unsaved-edits 'wrong-type-arg check-error-tag mix-sync-max 1+ integer->mix <'> mix-properties 'no-such-mix check-error-tag mix-sync-max 1+ integer->mix 1 <'> set-mix-properties 'no-such-mix check-error-tag sounds empty? unless "sounds after error checks: %s" #( sounds ) snd-display then mus-audio-reinitialize drop 10 set-window-y drop dismiss-all-dialogs "test.snd" file-exists? if "test.snd" 0o644 file-chmod "test.snd" file-delete then "oboe.snd" "test.snd" file-copy "test.snd" open-sound to ind "test.snd" file-delete ind <'> update-sound #t nil fth-catch to tag stack-reset tag if tag car 'cant-update-file <> if "update-sound after deletion: %s" #( tag ) snd-display then then ind <'> save-sound #t nil fth-catch to tag stack-reset tag if tag car 'cannot-save <> if "save file deleted: %s" #( tag ) snd-display then then ind close-sound drop \ "oboe.snd" "test.snd" file-copy "test.snd" open-sound to ind select-all drop "test.snd" file-delete view-regions-dialog drop ind close-sound drop dismiss-all-dialogs \ "oboe.snd" "test.snd" file-copy "test.snd" open-sound to ind "test.snd" 0o400 file-chmod 10 delete-sample drop ind <'> save-sound #t nil fth-catch to tag stack-reset tag if tag car 'cannot-save <> if "save protected sound msg: %s" #( tag ) snd-display then then ind close-sound drop \ "test.snd" 0o644 file-chmod "test.snd" file-delete "oboe.snd" "test.snd" file-copy "test.snd" 0o200 file-chmod "test.snd" <'> open-sound #t nil fth-catch to tag stack-reset tag if tag car 'no-such-file = tag car 'mus-error = || unless "open read-protected sound worked!: %s" #( tag ) snd-display then then "test.snd" 0o644 file-chmod "test.snd" file-delete ind sound? if ind close-sound drop then \ "oboe.snd" "test.snd" file-copy "test.snd" 0o400 file-chmod "test.snd" open-sound to ind 10 delete-sample drop "test.snd" <'> save-sound-as #t nil fth-catch to tag stack-reset tag if tag car 'cannot-save <> if "save-as write-protected sound msg: %s" #( tag ) snd-display then then ind close-sound drop "test.snd" 0o644 file-chmod "test.snd" file-delete \ close-sound-mc-cb <'> map-channel #t nil fth-catch to tag stack-reset tag if tag car 'no-such-channel <> if "map-channel closing own chan: %s" #( tag ) snd-display then then \ close-sound-aoe-1-cb "snd-test" as-one-edit drop close-sound-aoe-2a-cb "outer-edit" as-one-edit drop close-sound-fc-cb find-channel drop \ "oboe.snd" open-sound to ind 0 make-sampler { rd } ind close-sound drop 10 0 do rd read-sample drop loop rd sampler-home { home } home array-length 0> if home 0 array-ref sound? if "reader-home of closed sound: %s %s?" #( home sounds ) snd-display then then rd sampler-position { loc } loc 0<> if "closed reader position: %s?" #( loc ) snd-display then rd sampler-at-end? { at-end } at-end false? if "closed sampler at end: %s?" #( at-end ) snd-display then \ "oboe.snd" open-sound to ind vct( 0.1 0.2 0.3 ) mix-vct { mx } mx make-mix-sampler to rd ind close-sound drop 10 0 do rd read-mix-sample drop loop \ 8 max-regions max set-max-regions drop "oboe.snd" open-sound to ind 0 100 ind 0 make-region { reg } reg 0 make-region-sampler to rd ind close-sound drop reg forget-region drop 10 0 do rd read-sample drop loop \ "oboe.snd" open-sound to ind 100 0.5 ind 0 set-sample drop 100 ind 0 sample { s100 } ind mc-2-cb map-channel drop 100 ind 0 sample to s100 s100 0.5 fneq if "map + reset framples: %s" #( s100 ) snd-display then ind 0 framples { frms } frms 50828 <> if "map + reset framples, framples: %s" #( frms ) snd-display then 1 ind 0 undo drop ind 0 framples to frms frms 1 <> if "map + reset framples, undo framples: %s" #( frms ) snd-display then ind revert-sound drop \ 100 0.5 ind 0 set-sample drop \ XXX: 'wrong-type-arg instead of 'wrong-number-of-args \ \ (set! (framples ind 0 1) 1) => too many arguments \ 1 ind 0 1 set-framples => wrong type arg 1 () \ \ With Fth this doesn't work as expected. If stack has more values than \ needed by the next word, no 'wrong-number-of-args exception can be \ raised because no one knows who will take the other values. That's \ why the first exception is 'wrong-type-arg because sound IND is not \ a number. \ \ framples ( snd chn edpos -- frms ) /* g_framples(snd, chn, edpos) */ \ set-framples ( on snd chn -- val ) /* g_set_framples(on, snd, chn) */ 1 ind 0 1 <'> set-framples #t nil fth-catch to tag stack-reset tag if tag car 'wrong-number-of-args <> tag car 'wrong-type-arg <> && if "set framples + edpos: %s" #( tag ) snd-display then then ind revert-sound drop *with-test-complex* if <'> mc-3-cb <'> map-channel #t nil fth-catch to tag then stack-reset tag if tag car 'bad-type <> if "map-channel rtn complex: %s" #( tag ) snd-display then then 0 make-sampler to rd 10 0 do rd #() apply drop loop rd copy-sampler { crd } ind close-sound drop 10 0 do crd read-sample drop loop crd sampler-home to home home array-length 0> if home 0 array-ref sound? if "copy reader-home of closed sound: %s %s?" #( home sounds ) snd-display then then crd sampler-position to loc loc 0<> if "closed copy reader position: %s?" #( loc ) snd-display then crd sampler-at-end? to at-end at-end false? if "closed copy sampler at end: %s?" #( at-end ) snd-display then \ ind <'> revert-sound #t nil fth-catch to tag stack-reset tag if tag car 'no-such-sound <> if "revert-sound of closed sound: %s" #( tag ) snd-display then then \ set-procs04 length 2 = if "(%s %s)" set-procs04 else "%s" #( set-procs04 ) then string-format { set04fncs } procs10 length 2 = if "(%s %s)" procs10 else "%s" #( procs10 ) then string-format { 10fncs } *snd-test-verbose* if "procs prcs/set-prcs" #f snd-test-message "=====================" #f snd-test-message "procs00: %3d/%3d" #( procs00 length set-procs00 length ) snd-test-message "procs01: %3d/%3d" #( procs01 length set-procs01 length ) snd-test-message "procs02: %3d/%3d" #( procs02 length set-procs02 length ) snd-test-message "procs03: %3d/%3d" #( procs03 length set-procs03 length ) snd-test-message set-procs04 length 10 <= if "procs04: %3d/%3d %s" #( procs04 length set-procs04 length set04fncs ) snd-test-message else "procs04: %3d/%3d" #( procs04 length set-procs04 length ) snd-test-message then "procs05: %3d" #( procs05 length ) snd-test-message "procs06: %3d" #( procs06 length ) snd-test-message "procs07: %3d" #( procs07 length ) snd-test-message "procs08: %3d" #( procs08 length ) snd-test-message procs10 length 10 <= if "procs10: %3d %s" #( procs10 length 10fncs ) snd-test-message else "procs10: %3d" #( procs10 length ) snd-test-message then then #( 1.5 #( 0 1 ) 1234 #t ) { random-args } #( 1.5 #( 0 1 ) 1234 vct-3 color-95 0+i delay-32 :feedback #f ) { main-args } #( 1.5 #( 0 1 ) 1234 0+i delay-32 #t ) { few-args } #( 1.5 vct-3 0+i ) { fewer-args } all-args if main-args else few-args then { less-args } nil nil nil nil nil nil nil { arg1 arg2 arg3 arg4 tm prc tag } gc-run "keyargs-2-args" check-args-progress-info keyargs each to arg1 random-args each to arg2 make-procs each to prc arg1 arg2 prc #t nil fth-catch stack-reset end-each end-each end-each dismiss-all-dialogs gc-run all-args if "keyargs-3-args" check-args-progress-info random-args each to arg1 keyargs each to arg2 random-args each to arg3 make-procs each to prc arg1 arg2 arg3 prc #t nil fth-catch stack-reset end-each end-each end-each end-each dismiss-all-dialogs gc-run "keyargs-4-args" check-args-progress-info keyargs each to arg1 random-args each to arg2 keyargs each to arg3 random-args each to arg4 make-procs each to prc arg1 arg2 arg3 arg4 prc #t nil fth-catch stack-reset end-each end-each end-each end-each end-each dismiss-all-dialogs gc-run then "no-args" check-args-progress-info procs00 each to prc prc #t nil fth-catch to tag stack-reset tag car 'wrong-number-of-args = if "procs00: %s %s" #( prc tag ) snd-display then end-each dismiss-all-dialogs gc-run "set-no-args" check-args-progress-info main-args each to arg set-procs00 each to prc arg prc set-xt #t nil fth-catch to tag stack-reset tag car 'wrong-number-of-args = if "set-procs00: (%s) %s %s" #( arg prc tag ) snd-display then end-each end-each dismiss-all-dialogs gc-run "1-arg" check-args-progress-info nil { arg } main-args each to arg procs01 each to prc arg prc #t nil fth-catch to tag stack-reset tag car 'wrong-number-of-args = if "procs01 wna: (%s) %s %s" #( arg prc tag ) snd-display then end-each end-each dismiss-all-dialogs gc-run "set-1-arg" check-args-progress-info main-args each to arg1 main-args each to arg2 set-procs01 each to prc prc proc-name "widget-size" string<> if arg1 arg2 prc set-xt #t nil fth-catch to tag stack-reset tag car 'wrong-number-of-args = if "set-procs01: (%s %s) %s %s" #( arg1 arg2 prc tag ) snd-display then then end-each end-each end-each dismiss-all-dialogs gc-run "2-args" check-args-progress-info main-args each to arg1 main-args each to arg2 procs02 each to prc arg1 arg2 prc #t nil fth-catch to tag stack-reset tag car 'wrong-number-of-args = if "procs02: (%s %s) %s %s" #( arg1 arg2 prc tag ) snd-display then end-each end-each end-each dismiss-all-dialogs gc-run "set-2-args" check-args-progress-info less-args each to arg1 less-args each to arg2 less-args each to arg3 set-procs02 each to prc arg1 arg2 arg3 prc set-xt #t nil fth-catch to tag stack-reset tag car 'wrong-number-of-args = if "set-procs02: (%s %s %s) %s %s" #( arg1 arg2 arg3 prc tag ) snd-display then end-each end-each end-each end-each dismiss-all-dialogs gc-run nil nil nil nil nil nil { arg5 arg6 arg7 arg8 arg9 arg0 } "3-args" check-args-progress-info less-args each to arg1 less-args each to arg2 less-args each to arg3 procs03 each to prc arg1 arg2 arg3 prc #t nil fth-catch to tag stack-reset tag car 'wrong-number-of-args = if "procs03: (%s %s %s) %s %s" #( arg1 arg2 arg3 prc tag ) snd-display then end-each end-each end-each end-each dismiss-all-dialogs gc-run "set-3-args" check-args-progress-info less-args each to arg1 less-args each to arg2 less-args each to arg3 less-args each to arg4 set-procs03 each to prc arg1 arg2 arg3 arg4 prc #t nil fth-catch to tag stack-reset tag car 'wrong-number-of-args = if "set-procs03: (%s %s %s %s) %s %s" #( arg1 arg2 arg3 arg4 prc tag ) snd-display then end-each end-each end-each end-each end-each dismiss-all-dialogs gc-run "4-args" check-args-progress-info few-args each to arg1 few-args each to arg2 few-args each to arg3 few-args each to arg4 procs04 each to prc arg1 arg2 arg3 arg4 prc #t nil fth-catch to tag stack-reset tag car 'wrong-number-of-args = if "procs04: (%s %s %s %s) %s %s" #( arg1 arg2 arg3 arg4 prc tag ) snd-display then end-each end-each end-each end-each end-each dismiss-all-dialogs gc-run "set-4-args" check-args-progress-info few-args each to arg1 few-args each to arg2 few-args each to arg3 few-args each to arg4 few-args each to arg5 set-procs04 each to prc arg1 arg2 arg3 arg4 arg5 prc #t nil fth-catch to tag stack-reset tag car 'wrong-number-of-args = if "set-procs04: (%s %s %s %s %s) %s %s" #( arg1 arg2 arg3 arg4 arg5 prc tag ) snd-display then end-each end-each end-each end-each end-each end-each stop-playing drop dismiss-all-dialogs gc-run "5-args" check-args-progress-info fewer-args each to arg1 fewer-args each to arg2 fewer-args each to arg3 fewer-args each to arg4 fewer-args each to arg5 procs05 each to prc arg1 arg2 arg3 arg4 arg5 prc #t nil fth-catch to tag stack-reset tag car 'wrong-number-of-args = if "procs05: (%s %s %s %s %s) %s %s" #( arg1 arg2 arg3 arg4 arg5 prc tag ) snd-display then end-each end-each end-each end-each end-each end-each dismiss-all-dialogs gc-run "6-args" check-args-progress-info fewer-args each to arg1 fewer-args each to arg2 fewer-args each to arg3 fewer-args each to arg4 fewer-args each to arg5 fewer-args each to arg6 procs06 each to prc arg1 arg2 arg3 arg4 arg5 arg6 prc #t nil fth-catch to tag stack-reset tag car 'wrong-number-of-args = if "procs06: (%s %s %s %s %s %s) %s %s" #( arg1 arg2 arg3 arg4 arg5 arg6 prc tag ) snd-display then end-each end-each end-each end-each end-each end-each end-each dismiss-all-dialogs gc-run "8-args" check-args-progress-info fewer-args each to arg1 fewer-args each to arg2 fewer-args each to arg3 fewer-args each to arg4 fewer-args each to arg5 fewer-args each to arg6 fewer-args each to arg7 fewer-args each to arg8 procs08 each to prc arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 prc #t nil fth-catch to tag stack-reset tag car 'wrong-number-of-args = if "procs08: (%s %s %s %s %s %s %s %s) %s %s" #( arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 prc tag ) snd-display then end-each end-each end-each end-each end-each end-each end-each end-each end-each dismiss-all-dialogs gc-run "10-args" check-args-progress-info fewer-args each to arg1 fewer-args each to arg2 fewer-args each to arg3 fewer-args each to arg4 fewer-args each to arg5 fewer-args each to arg6 fewer-args each to arg7 fewer-args each to arg8 fewer-args each to arg9 fewer-args each to arg0 procs10 each to prc arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg0 prc #t nil fth-catch to tag stack-reset tag car 'wrong-number-of-args = if "procs10: (%s %s %s %s %s %s %s %s %s %s) %s %s" #( arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg0 prc tag ) snd-display then end-each end-each end-each end-each end-each end-each end-each end-each end-each end-each end-each dismiss-all-dialogs gc-run #f set-ask-about-unsaved-edits drop ; : 30-test \ from clm-ins.fs <'> test23-balance :comment over object->string :channels 3 with-sound ws-output 0 find-sound { ind } ind sound? if ind close-sound drop else "with-sound balance?" snd-display then "test.snd" "test23-balance" *lineno* check-maxamp \ 0.0 0.3 <'> clm-ins-test \ :comment over object->string \ :notehook *snd-test-ws-verbose* if <'> test23-notehook else #f then \ :channels 2 with-sound ws-close-sound ; let: ( -- ) #() { numbs } script-arg 0> if script-args length script-arg 1+ ?do script-args i list-ref string->number { n } script-arg 1+ set-script-arg drop n 0< if numbs n array-push to numbs \ negative number means exclude this test else test-numbers n array-push to test-numbers then loop then test-numbers empty? if 29 -1 do test-numbers i array-push to test-numbers loop then numbs each abs { n } test-numbers test-numbers n array-index array-delete! drop end-each .stack start-snd-test <'> 00-constants run-fth-test <'> 01-defaults run-fth-test mus-ldouble set-default-output-sample-type drop <'> 02-headers run-fth-test <'> 03-variables run-fth-test <'> 04-sndlib run-fth-test <'> 05-simple-check run-fth-test <'> 08-clm run-fth-test <'> 10-marks run-fth-test <'> 15-chan-local-vars run-fth-test <'> 19-save/restore run-fth-test <'> 23-with-sound run-fth-test <'> 27-sel-from-snd run-fth-test <'> 28-errors run-fth-test <'> 30-test run-fth-test \ local fragment test finish-snd-test 0 snd-exit drop ;let \ snd-test.fs ends here snd-16.1/prc95.scm0000644000076400007640000002135112546577500012016 0ustar bilbil;;; this is a translation to Snd (from CLM's prc-toolkit95.lisp) ;;; of Perry Cook's Physical Modelling Toolkit. (provide 'snd-prc95.scm) (if (provided? 'snd) (require snd-ws.scm) (require sndlib-ws.scm)) (define* (make-reed (offset 0.6) (slope -0.8)) (float-vector offset slope)) (define (reedtable r samp) (min 1.0 (+ (r 0) (* (r 1) samp)))) (define* (make-bowtable (offset 0.0) (slope 1.0)) (float-vector offset slope)) (define (bowtable b samp) (max 0.0 (- 1.0 (abs (* (b 1) (+ samp (b 0))))))) (define (jettable samp) (max -1.0 (min 1.0 (* samp (- (* samp samp) 1.0))))) (define* (make-onezero (gain 0.5) (zerocoeff 1.0)) (make-one-zero gain (* gain zerocoeff))) (define* (make-onep (polecoeff 0.9)) (make-one-pole (- 1.0 polecoeff) (- polecoeff))) (define (set-pole p val) (set! (mus-ycoeff p 1) (- val)) (set! (mus-xcoeff p 0) (- 1.0 val))) (define (set-gain p val) (set! (mus-xcoeff p 0) (* (mus-xcoeff p 0) val))) (define (lip-set-freq b freq) (set! (mus-frequency b) freq)) (define (lip b mouthsample boresample) (let ((temp (formant b (- mouthsample boresample)))) (set! temp (min 1.0 (* temp temp))) (+ (* temp mouthsample) (* (- 1.0 temp) boresample)))) (define (make-dc-block) (float-vector 0.0 0.0)) (define (dc-block b samp) (set! (b 1) (+ samp (- (* 0.99 (b 1)) (b 0)))) (set! (b 0) samp) (b 1)) ;; we could also use a filter generator here: (make-filter 2 (float-vector 1 -1) (float-vector 0 -0.99)) ;;; this ia a 0-based versions of the clm delays (defgenerator dlya (outp 0) (input #f)) (define (make-delayl len lag) ;; Perry's original had linear interp bug, I think -- this form is more in tune (make-dlya :input (make-delay len :max-size (ceiling (+ len lag 1))) :outp (- lag len))) (define (delayl d samp) (delay-tick (d 'input) samp) (tap (d 'input) (d 'outp))) ;;; now some example instruments (definstrument (plucky beg dur freq amplitude maxa) ;; (with-sound () (plucky 0 .3 440 .2 1.0)) (let* ((lowestfreq 100.0) (len (+ 1 (floor (/ *clm-srate* lowestfreq))))) (let ((delayline (make-delayl len (- (/ *clm-srate* freq) 0.5))) (filt (make-onezero)) (start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (dout 0.0)) (do ((i 0 (+ i 1))) ((= i len)) (set! dout (delayl delayline (+ (* 0.99 dout) (mus-random maxa))))) (do ((i start (+ i 1))) ((= i end)) (set! dout (delayl delayline (one-zero filt dout))) (outa i (* amplitude dout)))))) ;;; freq is off in this one (in prc's original also) (definstrument (bowstr beg dur frq amplitude maxa) ;; (with-sound () (bowstr 0 .3 220 .2 1.0)) (let* ((lowestfreq 100.0) (len (+ 1 (floor (/ *clm-srate* lowestfreq))))) (let ((ratio 0.8317) (rate .001) (bowing #t) (temp (- (/ *clm-srate* frq) 4.0))) (let ((neckdelay (make-delayl len (* temp ratio))) (bridgedelay (make-delayl (floor (/ len 2)) (* temp (- 1.0 ratio)))) (bowtab (make-bowtable :slope 3.0)) (filt (make-onep)) (bowvelocity rate) (maxvelocity maxa) (attackrate rate) (st (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (release (seconds->samples (* .8 dur))) (ctr 0) (bridgeout 0.0) (neckout 0.0)) (set-pole filt 0.6) (set-gain filt 0.3) (do ((i st (+ i 1))) ((= i end)) (let ((bridgerefl 0.0) (nutrefl 0.0) (veldiff 0.0) (stringvel 0.0) (bowtemp 0.0)) (if bowing (if (not (= maxvelocity bowvelocity)) (if (< bowvelocity maxvelocity) (set! bowvelocity (+ bowvelocity attackrate)) (set! bowvelocity (- bowvelocity attackrate)))) (if (> bowvelocity 0.0) (set! bowvelocity (- bowvelocity attackrate)))) (set! bowtemp (* 0.3 bowvelocity)) (let ((filt-output (one-pole filt bridgeout))) (set! bridgerefl (- filt-output)) (set! nutrefl (- neckout)) (set! stringvel (+ bridgerefl nutrefl)) (set! veldiff (- bowtemp stringvel)) (set! veldiff (* veldiff (bowtable bowtab veldiff))) (set! neckout (delayl neckdelay (+ bridgerefl veldiff))) (set! bridgeout (delayl bridgedelay (+ nutrefl veldiff))) (outa i (* amplitude 10.0 filt-output)) (if (= ctr release) (begin (set! bowing #f) (set! attackrate .0005))) (set! ctr (+ ctr 1))))))))) (definstrument (brass beg dur freq amplitude maxa) ;; does this work at all? (let* ((lowestfreq 100.0) (len (+ 1 (floor (/ *clm-srate* lowestfreq))))) (let ((blowing #t) (rate .001) (breathpressure 0.0)) ; 0.1 ? (let ((delayline (make-delayl len (+ 1.0 (/ *clm-srate* freq)))) (lipfilter (make-formant freq)) (dcblocker (make-dc-block)) (maxpressure maxa) (attackrate rate) (st (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (release (seconds->samples (* .8 dur))) (ctr 0) (dout 0.0)) (do ((i st (+ i 1))) ((= i end)) (if blowing (if (not (= maxpressure breathpressure)) (if (< breathpressure maxpressure) (set! breathpressure (+ breathpressure attackrate)) (set! breathpressure (- breathpressure attackrate)))) (if (> breathpressure 0.0) (set! breathpressure (- breathpressure attackrate)))) (set! dout (delayl delayline (dc-block dcblocker (lip lipfilter (* 0.3 breathpressure) (* 0.9 dout))))) (outa i (* amplitude dout)) (if (= ctr release) (begin (set! blowing #f) (set! attackrate .0005))) (set! ctr (+ ctr 1))))))) (definstrument (clarinet beg dur freq amplitude maxa) ;; (with-sound () (clarinet 0 .3 440 .2 1.0)) (let* ((lowestfreq 100.0) (len (+ 1 (floor (/ *clm-srate* lowestfreq))))) (let ((blowing #t) (breathpressure 0.0) ; 0.1 ? (rate .001)) (let ((delayline (make-delayl len (- (* 0.5 (/ *clm-srate* freq)) 1.0))) (rtable (make-reed :offset 0.7 :slope -0.3)) (filt (make-onezero)) (maxpressure maxa) (attackrate rate) (st (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (ctr 0) (release (seconds->samples (* .8 dur))) (dlyout 0.0)) (do ((i st (+ i 1))) ((= i end)) (let ((pressurediff 0.0)) (if blowing (if (not (= maxpressure breathpressure)) (if (< breathpressure maxpressure) (set! breathpressure (+ breathpressure attackrate)) (set! breathpressure (- breathpressure attackrate)))) (if (> breathpressure 0.0) (set! breathpressure (- breathpressure attackrate)))) (set! pressurediff (- (one-zero filt (* -0.95 dlyout)) breathpressure)) (set! dlyout (delayl delayline (+ breathpressure (* pressurediff (reedtable rtable pressurediff))))) (outa i (* amplitude dlyout)) (if (= ctr release) (begin (set! blowing #f) (set! attackrate .0005))) (set! ctr (+ ctr 1)))))))) (definstrument (flute beg dur freq amplitude maxa) ;; (with-sound () (flute 0 .3 440 .2 1.0)) (let* ((lowestfreq 100.0) (len (+ 1 (floor (/ *clm-srate* lowestfreq))))) (let ((jetrefl 0.6) (endrefl 0.6) (sinphase 0.0) (blowing #t) (rate .0005) (breathpressure 0.0) ; 0.1 ? (ratio 0.8) (temp (- (/ *clm-srate* freq) 5.0))) (let ((jetdelay (make-delayl (floor (/ len 2)) (* temp (- 1.0 ratio)))) (boredelay (make-delayl len (* ratio temp))) (filt (make-onep)) (dcblocker (make-dc-block)) (maxpressure maxa) (attackrate rate) (st (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (ctr 0) (release (seconds->samples (* .8 dur))) (boreout 0.0)) (set-pole filt 0.8) (set-gain filt -1.0) (do ((i st (+ i 1))) ((= i end)) (let ((randpressure (random (* 0.1 breathpressure))) (temp 0.0) (pressurediff 0.0)) (set! sinphase (+ sinphase 0.0007)) ;5 hz vibrato? (if (> sinphase 6.28) (set! sinphase (- sinphase 6.28))) (set! randpressure (+ randpressure (* 0.05 breathpressure (sin sinphase)))) (if blowing (if (not (= maxpressure breathpressure)) (if (< breathpressure maxpressure) (set! breathpressure (+ breathpressure attackrate)) (set! breathpressure (- breathpressure attackrate)))) (if (> breathpressure 0.0) (set! breathpressure (- breathpressure attackrate)))) (set! temp (dc-block dcblocker (one-pole filt boreout))) (set! pressurediff (+ (jettable (delayl jetdelay (+ breathpressure (- randpressure (* jetrefl temp))))) (* endrefl temp))) (set! boreout (delayl boredelay pressurediff)) (outa i (* 0.3 amplitude boreout)) (if (= ctr release) (begin (set! blowing #f) (set! attackrate .0005))) (set! ctr (+ ctr 1)))))))) #| (with-sound () (plucky 0 .3 440 .2 1.0) (bowstr .5 .3 220 .2 1.0) (brass 1 .3 440 .2 1.0) (clarinet 1.5 .3 440 .2 1.0) (flute 2 .3 440 .2 1.0)) |# snd-16.1/snd-listener.c0000644000076400007640000002045512603035272013114 0ustar bilbil#include "snd.h" bool listener_is_visible(void) { return(listener_height() > 5); } static Xen read_hook; #if HAVE_SCHEME && (!USE_NO_GUI) static int skipped_calls = 0; #define SKIPPING 10 void listener_begin_hook(s7_scheme *sc, bool *val) { if (skipped_calls < SKIPPING) { skipped_calls++; return; } skipped_calls = 0; ss->C_g_typed = false; #if USE_MOTIF if (XtAppPending(MAIN_APP(ss)) & XtIMXEvent) { XEvent event; XtAppNextEvent(MAIN_APP(ss), &event); XtDispatchEvent(&event); } #endif #if USE_GTK #if 0 if (gdk_events_pending()) /* necessary -- otherwise Snd hangs in gtk_main_iteration */ gtk_main_iteration(); #else { int i = 50; /* we need to let more than 1 event through at a time, else (for example) the listener popup * menu never actually pops up. * * if no threads (as here) this is just g_main_context_pending(NULL) * then gtk_main_iteration calls g_main_context_iteration(NULL, true), * so g_main_context_iteration(NULL, false) might combine the two. * But the overhead of gtk_events_pending is insignificant. This code * is extremely slow -- it more than doubles the compute time of s7test * for example, and spends 10% of its time fiddling with useless locks. */ while ((gtk_events_pending()) && (i != 0)) { gtk_main_iteration(); i--; } } #endif #endif *val = ss->C_g_typed; } #endif bool have_read_hook(void) { return(Xen_hook_has_list(read_hook)); } Xen run_read_hook(char *str) { return(run_or_hook(read_hook, Xen_list_1(C_string_to_Xen_string(str)), S_read_hook)); } #if HAVE_FORTH || HAVE_RUBY void call_read_hook_or_eval(const char *text) { Xen form; if (Xen_hook_has_list(read_hook)) { form = run_or_hook(read_hook, Xen_list_1(C_string_to_Xen_string(text)), S_read_hook); if (Xen_is_true(form)) return; } else form = Xen_eval_C_string(text); snd_report_listener_result(form); } #endif static Xen g_save_listener(Xen filename) { #define H_save_listener "(" S_save_listener " filename): saves the current listener text in filename" FILE *fp = NULL; const char *name; int err = 0; Xen_check_type(Xen_is_string(filename), filename, 1, S_save_listener, "a string"); name = Xen_string_to_C_string(filename); fp = FOPEN(name, "w"); if (fp) { err = save_listener_text(fp); snd_fclose(fp, name); } if ((!fp) || (err == -1)) Xen_error(CANNOT_SAVE, Xen_list_3(C_string_to_Xen_string(S_save_listener ": can't save ~S, ~A"), filename, C_string_to_Xen_string(snd_io_strerror()))); return(filename); } static Xen g_clear_listener(void) { #define H_clear_listener "(" S_clear_listener "): removes listener text from the beginning to the cursor" clear_listener(); return(Xen_false); } static Xen g_show_listener(void) { #define H_show_listener "(" S_show_listener ") returns " PROC_TRUE " if the listener is open, otherwise " PROC_FALSE "." return(C_bool_to_Xen_boolean(listener_is_visible())); } static Xen g_set_show_listener(Xen val) { Xen_check_type(Xen_is_boolean(val), val, 1, S_set S_show_listener, "a boolean"); handle_listener(Xen_boolean_to_C_bool(val)); return(C_bool_to_Xen_boolean(listener_is_visible())); } void set_listener_prompt(const char *new_prompt) { in_set_listener_prompt((char *)new_prompt); ss->listener_prompt_length = mus_strlen(new_prompt); #if USE_NO_GUI { #if HAVE_FORTH char *str; Xen_eval_C_string("before-prompt-hook reset-hook!\n"); str = mus_format("before-prompt-hook lambda: <{ prompt pos }> \"%s\" ; add-hook!", listener_prompt(ss)); Xen_eval_C_string(str); free(str); #endif #if HAVE_RUBY xen_rb_repl_set_prompt(listener_prompt(ss)); #endif #if HAVE_SCHEME xen_s7_set_repl_prompt(listener_prompt(ss)); #endif } #else /* not USE_NO_GUI */ /* here if the prompt changes and the listener exists, we need to make sure * we output a new prompt; otherwise the expression finder gets confused * by the old prompt. */ #if (!USE_GTK) listener_append_and_prompt(NULL); /* this checks first that the listener exists */ #else glistener_set_prompt(ss->listener, listener_prompt(ss)); /* this also checks */ #endif #endif } static Xen g_listener_prompt(void) {return(C_string_to_Xen_string(listener_prompt(ss)));} static Xen g_set_listener_prompt(Xen val) { char *new_prompt; #define H_listener_prompt "(" S_listener_prompt "): the current lisp listener prompt character ('>') " Xen_check_type(Xen_is_string(val), val, 1, S_set S_listener_prompt, "a string"); if (listener_prompt(ss)) free(listener_prompt(ss)); new_prompt = mus_strdup(Xen_string_to_C_string(val)); if (new_prompt == NULL) /* without this fixup, (set! (listener-prompt) "") can cause a segfault, at least in Motif */ { new_prompt = (char *)malloc(sizeof(char)); new_prompt[0] = 0; } set_listener_prompt(new_prompt); return(val); } static Xen g_snd_completion(Xen text) { /* perhaps callable from emacs? */ char *str, *temp; Xen res; Xen_check_type(Xen_is_string(text), text, 1, "snd-completion", "a string"); temp = mus_strdup(Xen_string_to_C_string(text)); str = expression_completer(NULL_WIDGET, temp, NULL); res = C_string_to_Xen_string(str); free(str); free(temp); return(res); } static Xen g_listener_colorized(void) { #define H_listener_colorized "(" S_listener_colorized ") returns #t if the listener is highlighting syntax." #if USE_GTK return(C_bool_to_Xen_boolean(listener_colorized())); #else return(Xen_false); #endif } static Xen g_listener_set_colorized(Xen val) { #if USE_GTK Xen_check_type(Xen_is_boolean(val), val, 1, S_set S_listener_colorized, "a boolean"); listener_set_colorized(Xen_boolean_to_C_bool(val)); #endif return(val); } Xen_wrap_1_arg(g_save_listener_w, g_save_listener) Xen_wrap_no_args(g_clear_listener_w, g_clear_listener); Xen_wrap_no_args(g_show_listener_w, g_show_listener) Xen_wrap_1_arg(g_set_show_listener_w, g_set_show_listener) Xen_wrap_no_args(g_listener_prompt_w, g_listener_prompt) Xen_wrap_1_arg(g_set_listener_prompt_w, g_set_listener_prompt) Xen_wrap_1_arg(g_snd_completion_w, g_snd_completion) Xen_wrap_no_args(g_listener_colorized_w, g_listener_colorized) Xen_wrap_1_arg(g_listener_set_colorized_w, g_listener_set_colorized) #if HAVE_SCHEME #if USE_GTK static s7_pointer acc_listener_colorized(s7_scheme *sc, s7_pointer args) {return(g_listener_set_colorized(s7_cadr(args)));} #endif static s7_pointer acc_listener_prompt(s7_scheme *sc, s7_pointer args) {return(g_set_listener_prompt(s7_cadr(args)));} #endif void g_init_listener(void) { Xen_define_procedure(S_save_listener, g_save_listener_w, 1, 0, 0, H_save_listener); Xen_define_procedure(S_clear_listener, g_clear_listener_w, 0, 0, 0, H_clear_listener); Xen_define_dilambda(S_show_listener, g_show_listener_w, H_show_listener, S_set S_show_listener, g_set_show_listener_w, 0, 0, 1, 0); Xen_define_dilambda(S_listener_prompt, g_listener_prompt_w, H_listener_prompt, S_set S_listener_prompt, g_set_listener_prompt_w, 0, 0, 1, 0); Xen_define_dilambda(S_listener_colorized, g_listener_colorized_w, H_listener_colorized, S_set S_listener_colorized, g_listener_set_colorized_w, 0, 0, 1, 0); #define H_read_hook S_read_hook " (text): called each time a line is typed into the listener (triggered by the carriage return). \ If it returns true, Snd assumes you've dealt the text yourself, and does not try to evaluate it." read_hook = Xen_define_hook(S_read_hook, "(make-hook 'text)", 1, H_read_hook); Xen_define_procedure("snd-completion", g_snd_completion_w, 1, 0, 0, "return completion of arg"); #if HAVE_SCHEME #if USE_GTK s7_symbol_set_documentation(s7, ss->listener_colorized_symbol, "*listener-colorized*: number of vector elements to print in the listener (default: 12)"); s7_symbol_set_access(s7, ss->listener_colorized_symbol, s7_make_function(s7, "[acc-" S_listener_colorized "]", acc_listener_colorized, 2, 0, false, "accessor")); #endif s7_symbol_set_documentation(s7, ss->listener_prompt_symbol, "*listener-prompt*: the current lisp listener prompt character ('>') "); s7_symbol_set_access(s7, ss->listener_prompt_symbol, s7_make_function(s7, "[acc-" S_listener_prompt "]", acc_listener_prompt, 2, 0, false, "accessor")); #endif } snd-16.1/fm.html0000644000076400007640000030214212536016524011631 0ustar bilbil An Introduction to FM
An Introduction To FM
radio ad intro
Bill Schottstaedt

In frequency modulation we modulate the frequency — "modulation" here is just a latinate word for "change". Vibrato and glissando are frequency modulation. John Chowning tells me that he stumbled on FM when he sped up vibrato to the point that it was creating audible sidebands (perceived as a timbral change) rather than faster warbling (perceived as a frequency change). We can express this (the vibrato, not the neat story) as:

cos(wt + f)

where the c subscript stands for "carrier" and f(t) means "some arbitrary function added to the carrier". Since cos takes an angle as its argument, f(t) modulates (that is, changes) the angle passed to the cosine, hence the generic name "angle modulation". We can add that change either to the argument to cos ("phase modulation", cos(angle + change)), or add it to the current phase, then take cos of that ("frequency modulation", cos(angle += change)), so our formula can viewed either way. Since the angle is being incremented by the carrier frequency in either case, the difference is between:

PM: cos((angle += incr) + change)
FM: cos(angle += (incr + change))

To make the difference clear, textbooks put in an integral when they mean frequency modulation:

cos + integral

In PM we change the phase, in FM we change the phase increment, and to go from FM to PM, integrate the FM modulating signal. But you can't tell which is in use from the output waveform; you have to know what the modulating signal is. In sound synthesis, where we can do what we want with the modulating signal, there is no essential difference between frequency and phase modulation.

I would call this issue a dead horse, but it is still causing confusion, even 40 years down the road. So, here are two CLM instruments, one performing phase modulation, the other performing frequency modulation. I have tried to make the innards explicit at each step, and match the indices so that the instruments produce the same results given the same parameters. Also, to lay a different controversy to rest, it should be obvious from these two functions that there is no difference in run-time computational expense or accuracy.

(define (pm beg end freq amp mc-ratio index)  ; "mc-ratio" = modulator to carrier frequency ratio
  (let ((carrier-phase 0.0) ; set to pi/2 if someone tells you PM can't produce energy at 0Hz
        (carrier-phase-incr (hz->radians freq))
        (modulator-phase 0.0)
        (modulator-phase-incr (hz->radians (* mc-ratio freq))))
    (do ((i beg (+ i 1)))
	((= i end))
      (let* ((modulation (* index (sin modulator-phase)))
	     (pm-val (* amp (sin (+ carrier-phase modulation))))) 
	     ;; no integration in phase modulation
	(set! carrier-phase (+ carrier-phase carrier-phase-incr))
	(set! modulator-phase (+ modulator-phase modulator-phase-incr))
	(outa i pm-val)))))

(define (fm beg end freq amp mc-ratio index)
  (let* ((carrier-phase 0.0)
	 (carrier-phase-incr (hz->radians freq))
	 (modulator-phase-incr (hz->radians (* mc-ratio freq)))
	 (modulator-phase (* 0.5 (+ pi modulator-phase-incr)))
	 ;; (pi+incr)/2 to get (centered) sin after integration, to match pm case above
	 (fm-index (hz->radians (* mc-ratio freq index))))
	 ;; fix up fm index (it's a frequency change)
    (do ((i beg (+ i 1)))
	((= i end))
      (let ((modulation (* fm-index (sin modulator-phase)))
	    (fm-val (* amp (sin carrier-phase))))
	(set! carrier-phase (+ carrier-phase modulation carrier-phase-incr))
	(set! modulator-phase (+ modulator-phase modulator-phase-incr))
	(outb i fm-val)))))

(with-sound (:channels 2) 
  (pm 0 10000 1000 .5 0.25 4)
  (fm 0 10000 1000 .5 0.25 4))

(with-sound (:channels 2) 
  (pm 0 10000 1000 .5 0.5 10)
  (fm 0 10000 1000 .5 0.5 10))
simple FM: sin(sin)

Given our formula for FM, let's assume, for starters, that f(t) is a sinusoid:

cos(sin)

where the "m" stands for "modulator" and the "B" factor is usually called the modulation index. The corresponding CLM code is:

(oscil carrier (* B (oscil modulator)))

where oscil is (essentially):

(define* (oscil oscillator (fm-input 0.0) (pm-input 0.0))
  (let ((result (sin (+ oscillator-phase pm-input))))
    (set! oscillator-phase (+ oscillator-phase (+ oscillator-phase-increment fm-input)))
    result))

Since it is generally believed that the ear performs some sort of projection of the time domain waveform into the frequency domain (a Fourier Transform), and that timbre is at least partly a matter of the mix of frequencies present (the spectrum), our main interest in the FM formula is in the spectrum it produces. To determine that spectrum, we have to endure some tedious mathematics. By the trigonometric identity:

cos a+b

we can substitute wct for "a" and bsin for "b" and get:

cos (sin) expanded

If we can get a Fourier transform of the two inner portions: cos sin and sin sin, we can use:

coscos and sinsin

to get the final results. "A" here is wct in the earlier formulas, and "B" is either cos sin or sin sin. The Fourier transform we want is not obvious to us (not to me, certainly!), so we go to Abramowitz and Stegun, "Handbook of Mathematical Functions" and find (formulas 9.1.42 and 9.1.43):

cos B sin t sin B sin t

Here the J's refer to the Bessel functions which we will return to later. First, let's finish this expansion; we take these two sums and wct and plug them into our first expansion of the FM formula, and out pops:

cos w+sin

or in a slightly more compact form:

sum J cos

Here we are using the fact that J - J. We can change our point of view on the first part of the expansion given above, and ask for the amplitude of a given sideband:

J sin int
J cos int

We end up with a spectrum made up of a "carrier" at wc and symmetrically placed sidebands separated by wm. The amplitudes follow the Bessel functions. I put carrier in quotes because in computer music we listen to the result of the modulation (this was Chowning's idea — see "The Synthesis of Complex Audio Spectra by Means of Frequency Modulation"). The Bessel functions are nearly 0 until the index (B) equals the order (n). Then they have a bump and tail off as a sort of damped sinusoid:

page from Jacobi's works
C G J Jacobi, Gesammelte Werke, VI 101
bessel functions

As the index sweeps upward, energy is swept gradually outward into higher order side bands; this is the originally exciting, now extremely annoying "FM sweep". The important thing to get from these Bessel functions is that the higher the index, the more dispersed the spectral energy — normally a brighter sound.

carrier=1000, mod=100, index=1.0 carrier=1000, mod=100, index=2.0 carrier=1000, mod=100, index=3.0
fm 1.0 fm 2.0 fm 3.0
  J0(1.0) = 0.765 -> 1.0 (*)
  J1(1.0) = 0.440 -> 0.575
  J2(1.0) = 0.115 -> 0.150
  J3(1.0) = 0.019 -> 0.025
  J4(1.0) = 0.002 -> 0.003

(* Jn values normalized to match
the peak values given above)
  J0(2.0) = 0.224 -> 0.388 (*)
  J1(2.0) = 0.577 -> 1.0
  J2(2.0) = 0.353 -> 0.611
  J3(2.0) = 0.129 -> 0.223
  J4(2.0) = 0.034 -> 0.058
  J5(2.0) = 0.007 -> 0.012
  J6(2.0) = 0.001 -> 0.002
(A larger FFT reduces the mismatch)
  J0(3.0) = -0.260 -> -0.534 (*)
  J1(3.0) = 0.339 ->  0.697
  J2(3.0) = 0.486 ->  1.0
  J3(3.0) = 0.309 ->  0.635
  J4(3.0) = 0.132 ->  0.271
  J5(3.0) = 0.043 ->  0.088
  J6(3.0) = 0.011 ->  0.023

There is a rule of thumb, Mr Carson's rule, about the overall bandwidth of the resultant spectrum (it follows from our description of the Bessel functions): Roughly speaking, there are fm-index+1 significant sidebands on each side of the carrier, so our total bandwidth is more or less

2 * modulator-frequency * (fm-index + 1)

This is a good approximation — 99% of the signal power is within its limits. To turn that around, we can reduce the danger of aliasing by limiting the FM index to approximately (srate/2 - carrier_frequency) / modulator_frequency; use srate/4 to be safer. (Mr Carson's opinion of FM: "this method of modulation inherently distorts without any compensating advantages whatsoever").

One hidden aspect of the FM expansion is that it produces a time domain waveform that is not "spikey". If we add cosines at the amplitudes given by the Bessel functions (using additive synthesis to produce the same magnitude spectrum as FM produces), we get a very different waveform. Doesn't the FM version sound richer and, far more importantly, louder?

time domain comparisons
FM waveform (index: 3.0) vs sum of cosines with the same (relative) component amplitudes

From one point of view (looking at FM as changing the phase passed to the sin function), it's obvious that the output waveform should be this well behaved, but looking at it from its components, it strikes me as a minor miracle that there is a set of amplitudes (courtesy of the Bessel functions) that fits together so perfectly. Here is an attempt to graph the 15 main components, with their sum in black:

fm components
Then there's the perennial question "why Bessel functions?". Most explanations start with jacobi formula: obscurum per obscurius! A different tack might be to start with sin in terms of e, a definition of sine, and call the "e^(ix)" terms "t", then cos(sin) involves terms like cos(sin) in e, which is one (convoluted) way to define Bessel functions. Or perhaps most forthright, start with the formula for Jn(B) given above (the integral), and say "we want cos(sin) expanded as a sum of cosines, and we define Jn to be the nth coefficient in that sum". This was the approach of Bessel and other 19th century mathematicians, but it is not very satisfying for some reason. Perhaps history can help? These functions were studied by Daniel Bernoulli (the vibrations of a heavy chain, 1738), Euler (the vibrations of a membrane, 1764), Lagrange (planetary motion, 1770), and Fourier (the motion of heat in a cylinder, 1822); Bessel studied them in the context of Kepler's equation, and wrote a monograph about them in 1824. For an explanation of the connection between planetary motion and FM, see Benson, "Music: A Mathematical Offering". Just for completeness, here's a derivation following Gray and Mathews, "A Treatise on Bessel Functions": et again
simple FM examples

Here's a simple FM instrument:

(define* (fm beg dur freq amp mc-ratio index (index-env '(0 1 100 1)))
  (let* ((start (seconds->samples beg))
         (end (+ start (seconds->samples dur)))
         (cr (make-oscil freq))
         (md (make-oscil (* freq mc-ratio)))
         (fm-index (hz->radians (* index mc-ratio freq)))
         (ampf (make-env index-env :scaler amp :duration dur)) 
         (indf (make-env index-env :scaler fm-index :duration dur)))
    (do ((i start (+ i 1)))
        ((= i end))
      (outa i (* (env ampf)                       ; amplitude env
                 (oscil cr (* (env indf)          ; carrier + modulation env
                              (oscil md))))))))   ; modulation

I put an envelope on the fm-index ("indf" above) to try out dynamic spectra ("dynamic" means "changing" here). For now, don't worry too much about the actual side band amplitudes. They will not always match Chowning's description, but we'll get around to an explanation eventually.

(with-sound () (fm 0 1.0 100 .5 1.0 4.0))

is Chowning's first example. Sure enough, it's a complex spectrum (that is, it has lots of components; try an index of 0 to hear a sine wave, if you're suspicious). Since our modulating frequency to carrier frequency ratio (mc-ratio above) is 1.0, we get sidebands at harmonics of the carrier. If we use an mc-ratio of .25 and a carrier of 400:

(with-sound () (fm 0 1.0 400 .5 0.25 4.0))

we end up with the same perceived pitch because the sidebands are still at multiples of 100 Hz.

(with-sound () (fm 0 1.0 400 .5 1.1414 4.0))

has inharmonic sidebands. Most real sounds seem to change over the course of a note, and it was at one time thought that most of this change was spectral. To get a changing spectrum, we need only put an envelope on the fm-index:

(with-sound () (fm 0 0.5 400 .5 1.0 5.0 '(0 0 20 1 40 .6 90 .5 100 0)))

making a brass-like sound. Similarly, Chowning suggests that

(with-sound () (fm 0 1.0 900 .5 1/3 2.0 '(0 0 6 .5 10 1 90 1 100 0)))

is a woodwind-like tone,

(with-sound () (fm 0 1.0 500 .5 .2 1.5 '(0 0 6 .5 10 1 90 1 100 0)))

is bassoon-like, and finally

(with-sound () (fm 0 1.0 900 .5 2/3 2 '(0 0 25 1 75 1 100 0)))

is clarinet-like. Now start at 2000 Hz, set the mc-ratio to .1, and sweep the FM index from 0 to 10, and the spectrogram looks like this:

sweep index

There is a lot of music in simple FM. You get a full spectrum at little computational expense, and the index gives you a simple and intuitive way to change that spectrum. Since the output peak amplitude is not affected by the modulating signal (cos(x) is between -1 and 1 no matter what x is, as long as it is real), we can wrench the index around with wild abandon. And since the number of significant components in the spectrum is nearly proportional to the index (Carson's rule), we can usually predict more or less what index we want for a given spectral result.

A slightly bizarre sidelight: there's no law against a modulating signal made up of complex numbers. In this case, cos is no longer bounded, so the output can peak at anything, but we still get FM-like spectra. J=I, where "I" is the modified Bessel function, so if our index is purely imaginary, we can expand cos(wc + bi sin wm)t as

i case

If our index is a + bi, we get

a=bi case

This looks similar to normal FM, but with normalization headaches. Perhaps we can take advantage of the split betweeen the real and imaginary parts — unexplored territory!

complex index fm 6.0+3.0i 0.5 interp
here the index is 6+3i

I am getting carried away — we need to back up a bit and clear up one source of confusion. If you looked at the spectrum of our first example, and compared it to the spectrum Chowning works out, you may wonder what's gone awry. We have to return to our initial set of formulas. If we consider that:

sin split
sin split

and using our previous formulas for the expansion of the cos(sin) and sin(sin) terms, with the identity:

sin cos again

we see that we still have a spectrum symmetric around the carrier, and the amplitude and frequencies are just as they were before, but the initial phases of the side bands have changed. Our result is now

sin sin case

This is Chowning's version of the expansion. In general:

big formula

Our first reaction is, "well so what if one's a sine and the other's a cosine — they'll sound the same", but we are being hasty. What if (for example), the modulator has the same frequency as the carrier, and its index (B) is high enough that some significant energy appears at w-m=-w? Where does energy at a negative frequency go? We once again fall back on trigonometry: sin(-x)=-sin(x), but cos(-x)=cos(x), so the negative frequency component adds to the positive frequency component if it's a cosine, but subtracts if it's a sine. We get a different pattern of cancellations depending on the initial phases of the carrier and modulator. Take the CLM instrument:

(define (pm beg dur freq amp fm-index mod-phase)
  (let* ((start (seconds->samples beg))
	 (end (+ start (seconds->samples dur)))
	 (cr (make-oscil freq))
	 (md (make-oscil freq mod-phase)))
    (do ((i start (+ i 1)))
        ((= i end))
      (outa i (* amp (oscil cr 0.0 
                       (* fm-index (oscil md))))))))

(with-sound () (pm 0 1.0 100 .5 8 0))
(with-sound () (pm 0 1.0 100 .5 8 (* .5 pi)))
mod phase 0 mod phase pi/2
mod phase = 0.0 mod phase = pi/2

There is a slight difference! We're using phase-modulation for simplicity (the integration in FM changes the effective initial phase). By varying the relative phases, we can get a changing spectrum from these cancellations. Here is a CLM instrument that shows this (subtle) effect:

(define (fm beg dur freq amp mc-ratio index)
  (let* ((start (seconds->samples beg))
	 (end (+ start (seconds->samples dur)))
	 (cr (make-oscil freq))
	 (md (make-oscil (* freq mc-ratio)))
	 (skewf (make-env (list 0.0 0.0 1.0 pi) :duration dur)))
    (do ((i start (+ i 1)))
        ((= i end))
      (outa i (* amp (oscil cr 0.0 (* index (oscil md 0.0 (env skewf)))))))))

(with-sound () (fm 0 2 100 0.5 1.0 30.0))

The next question is "if we can get cancellations, can we fiddle with the phases and get asymmetric FM spectra?". There are several approaches; an obvious one uses the fact that:

coscos and sinsin

If we have a spectrum B made up entirely of sines (or entirely cosines), we can multiply it by sin A (or cos A), add the two resulting spectra, and the (A + B) parts cancel. Unfortunately, in this case there are some pesky -1's floating around, so we get asymmetric or gapped spectra, but not anything we'd claim was single side-band.

(define (pm-cancellation beg dur carfreq modfreq amp index)
  (let* ((cx 0.0)
	 (mx 0.0)
	 (car-incr (hz->radians carfreq))
	 (mod-incr (hz->radians modfreq))
	 (start (seconds->samples beg))
	 (stop (+ start (seconds->samples dur))))
    (do ((i start (+ i 1)))
	((= i stop))
      (outa i (* amp (- (* (cos cx)  ; cos * sum-of-cos
			   (sin (* index (cos mx))))
			(* (sin cx)  ; sin * sum-of-sin
			   (* (sin (* index (sin mx))))))))
      (set! cx (+ cx car-incr))
      (set! mx (+ mx mod-incr)))))

(with-sound () (pm-cancellation 0 1 1000.0 100.0 0.3 9.0))
uncancelled
cos side by itself
fm cancellation
both sides (showing cancellations)

I really like the sounds you get from this cancellation; I can't resist adding the following examples which come from a collection of "imaginary machines":

(definstrument (machine1 beg dur cfreq mfreq amp index gliss)
  (let* ((gen (make-fmssb cfreq mfreq :index 1.0)) ; defined in generators.scm
	 (start (seconds->samples beg))
	 (stop (+ start (seconds->samples dur)))
	 (ampf (make-env '(0 0 1 .75 2 1 3 .1 4 .7 5 1 6 .8 100 0) :base 32 :scaler amp :duration dur))
	 (indf (make-env '(0 0 1 1 3 0) :duration dur :base 32 :scaler index))
	 (frqf (make-env (if (> gliss 0.0) '(0 0 1 1) '(0 1 1 0)) 
                 :duration dur :scaler (hz->radians (abs gliss)))))
     (do ((i start (+ i 1)))
         ((= i stop)) 
       (set! (fmssb-index gen) (env indf))
       (outa i (* (env ampf) (fmssb gen (env frqf)))))))

(with-sound (:play #t)
  (do ((i 0.0 (+ i .2)))
      ((>= i 2.0))
    (machine1 i .3 100 540 0.5 4.0 0.0)
    (machine1 (+ i .1) .3 200 540 0.5 3.0 0.0))
  (do ((i 0.0 (+ i .6)))
      ((>= i 2.0))
    (machine1 i .3 1000 540 0.5 6.0 0.0)
    (machine1 (+ i .1) .1 2000 540 0.5 1.0 0.0)))

(with-sound (:scaled-to .5 :play #t)
  (let ((gen (make-rkoddssb 1000.0 2000.0 0.875)) ; defined in generators.scm
	(noi (make-rand 15000 .04))
	(gen1 (make-rkoddssb 100.0 10.0 0.9))
	(ampf (make-env '(0 0 1 1 11 1 12 0) :duration 11.0 :scaler .5))
	(frqf (make-env '(0 0 1 1 2 0 10 0 11 1 12 0 20 0) :duration 11.0 :scaler (hz->radians 1.0))))
     (do ((i 0 (+ i 1)))
         ((= i (* 12 44100)))
       (outa i (* (env ampf) 
	          (+ (rkoddssb gen1 (env frqf))
		     (* .2 (sin (rkoddssb gen (rand noi)))))))))
  (do ((i 0.0 (+ i 2)))
      ((>= i 10.0))
    (machine1 i 3 100 700 0.5 4.0 0.0)
    (machine1 (+ i 1) 3 200 700 0.5 3.0 0.0))
  (do ((i 0.0 (+ i 6)))
      ((>= i 10.0))
    (machine1 i 3 1000 540 0.5 6.0 0.0)
    (machine1 (+ i 1) 1 2000 540 0.5 1.0 0.0)))

A different approach, also using a form of amplitude modulation, is mentioned by Moorer in "Signal Processing Aspects of Computer Music":

jam case

This is the rxyk!cos generator in generators.scm. It produces beautiful single-sided spectra. We might grumble that the sideband amplitudes don't leave us much room for maneuver, but the factorial in the denominator overwhelms any exponential in the numerator, so we can get many interesting effects: moving formants, for example.

jam pict
a: 2, x:1000, y: 100

Palamin et al in "A Method of Generating and Controlling Musical Asymmetrical Spectra" came up with a slightly more complicated version:

e sin

But the peak amplitude of this formula is hard to predict; we'd rather have a sum of cosines:

better asy

so we can use

sum of Js

to normalize the output to -1.0 to 1.0. The spectrum produced for a given "r" is mirrored by -1/r (remembering that J - J).

(with-sound ()
  (let ((gen (make-asymmetric-fm 2000.0 :ratio .2 :r 0.5)))
    (do ((i 0 (+ i 1)))
        ((= i 20000))
      (outa i (asymmetric-fm gen 2.0)))))
asy fm
peaks

We can put an envelope on either the index or "r"; the index affects how broad the spectrum is, and "r" affects its placement relative to the carrier (giving the effect of a moving formant). Here we sweep "r" from -1.0 to -20.0, with an index of 3, m/c ratio of .2, and carrier at 1000 Hz:

asy spectra
complex FM: sin(sin+sin)

So far we have been using just a sinusoid for the modulator; what if we make it a more complicated signal? Here again trigonometry can be used to expand

multiple sins

The modulating signal is now made up of two sinusoids (don't despair; this is a terminating sequence). Since sine is not linear (it is x-x^3/3!+x^5/5!...), this is not the same thing as

bad sins

In the second case we just add together the two simple FM spectra, but in the first case we get a more complex mixture involving all the sums and differences of the modulating frequencies. These sum and difference tones ("intermodulation products") are not limited to FM. Any nonlinear synthesis technique produces them. Being non-linear, it must have something that involves a power of its input other than 0 or 1; if we feed in sin a + sin b, for example, that term will produce not just (sin a)^n and (sin b)^n, but all sorts of stuff involving sin a * sin b (in various powers), and this produces things like cos(a+b) and cos(a-b). For a less impressionistic derivation of the spectrum, see Le Brun, "A Derivation of the Spectrum of FM with a Complex Modulating Wave". The result can be expressed:

2 sums

You can chew up any amount of free time calculating the resulting side band amplitudes — see the immortal classic: Schottstaedt, "The Simulation of Natural Instrument Tones Using Frequency Modulation with a Complex Modulating Wave". (There's a function to do it for you in dsp.scm: fm-parallel-component). In simple cases, the extra modulating components flatten and spread out the spectrum somewhat (see below and ncos for discussions of very different not-so-simple cases). In general:

silly formula

A CLM instrument to produce this is:

(define (fm beg dur freq amp mc-ratios indexes carrier-phase mod-phases)
  (let* ((start (seconds->samples beg))
	 (end (+ start (seconds->samples dur)))
	 (cr (make-oscil freq carrier-phase))
         (n (length mc-ratios))
         (modulators (make-vector n))
         (fm-indices (make-vct n)))
    (do ((i 0 (+ i 1)))
	((= i n))
      (set! (modulators i) (make-oscil (* freq (mc-ratios i)) (mod-phases i)))
      (set! (fm-indices i) (hz->radians (* freq (indexes i) (mc-ratios i)))))
    (do ((i start (+ i 1)))
        ((= i end))
      (let ((sum 0.0))
        (do ((k 0 (+ k 1)))
	    ((= k n))
	  (set! sum (+ sum (* (fm-indices k) (oscil (modulators k))))))
	(outa i (* amp (oscil cr sum)))))))

(with-sound () (fm 0 2.0 440 .3 '(1 3 4) '(1.0 0.5 0.1) 0.0 '(0.0 0.0 0.0)))
multi fm picture
  200Hz is -0.106 (i = -1, k = -1)
           -0.106 (i = -1, k = 1) 
           -0.213 -> 0.306 normalized

  2000Hz:  -0.023 (i = -2, k = 0)
            0.718 (i = 0, k = 0)
            0.695 -> 1.0 normalized

  1800Hz:  -0.013 (i = -2, k = 1)
           -0.413 (i = 0, k = -1)
           -0.426 -> 0.614 normalized
i is the 2000 Hz part, k the 200 Hz,
red dots mark pure sum/difference tones
(with-sound () (fm 0 2.0 2000 .5 '(1 .1) '(0.5 1.0) 0.0 '(1.855 1.599)))

My favorite computer instrument, the FM violin, uses three sinusoidal components in the modulating wave; for more complex spectra these violins are then ganged together (see fmviolin.clm for many examples). By using a few sines in the modulator, you get away from the simple FM index sweep that has become tiresome, and the broader, flatter spectrum is somewhat closer to that of a real violin. A pared down version of the fm-violin is:

(define (violin beg dur frequency amplitude fm-index)
  (let* ((start (seconds->samples beg))
	 (end (+ start (seconds->samples dur)))
	 (frq-scl (hz->radians frequency))
         (maxdev (* frq-scl fm-index))
         (index1 (* maxdev (/ 5.0 (log frequency))))
         (index2 (* maxdev 3.0 (/ (- 8.5 (log frequency)) (+ 3.0 (/ frequency 1000)))))
         (index3 (* maxdev (/ 4.0 (sqrt frequency))))
         (carrier (make-oscil frequency))
         (fmosc1 (make-oscil frequency))
         (fmosc2 (make-oscil (* 3 frequency)))
         (fmosc3 (make-oscil (* 4 frequency)))
         (ampf  (make-env '(0 0 25 1 75 1 100 0) :scaler amplitude :duration dur))
         (indf1 (make-env '(0 1 25 .4 75 .6 100 0) :scaler index1 :duration dur))
         (indf2 (make-env '(0 1 25 .4 75 .6 100 0) :scaler index2 :duration dur))
         (indf3 (make-env '(0 1 25 .4 75 .6 100 0) :scaler index3 :duration dur))
         (pervib (make-triangle-wave 5 :amplitude (* .0025 frq-scl)))
         (ranvib (make-rand-interp 16 :amplitude (* .005 frq-scl))))
     (do ((i start (+ i 1)))
         ((= i end))
       (let ((vib (+ (triangle-wave pervib) (rand-interp ranvib))))
	 (outa i (* (env ampf)
	            (oscil carrier
		           (+ vib 
			      (* (env indf1) (oscil fmosc1 vib))
			      (* (env indf2) (oscil fmosc2 (* 3.0 vib)))
			      (* (env indf3) (oscil fmosc3 (* 4.0 vib)))))))))))

(with-sound () (violin 0 1.0 440 .1 1.0))

There is one surprising aspect of the parallel FM equation. Since we can fiddle with the initial phases of the modulating signal's components, we can get very different spectra from modulating signals with the same magnitude spectrum. In the next two graphs, both cases involve a modulating signal made up of 6 equal amplitude harmonically related sinusoids, but the first uses all cosines, and the second uses a set of initial phases that minimizes the modulating signal's peak amplitude:

comparison of 2 6-sinusoid spectra
cascade FM: sin(sin(sin))

We can, of course, use FM (or anything) to produce the modulating signal. When FM is used, it is sometimes called "cascade FM":

cascade fm

In CLM:

(* A (oscil carrier (* B (oscil modulator (* C (oscil cascade))))))

Each component of the lower pair of oscillators is surrounded by the spectrum produced by the upper pair, sort of like a set of formant regions.

cascade fm picture
osc A: 2000 Hz, osc B: 500 Hz, index 1.5, osc C: 50 Hz, index 1.0

The resemblance of cascade FM to parallel FM is not an accident:

cascade FM

Unfortunately, FM and PM can produce energy at 0Hz (when, for example, the carrier frequency equals the modulating frequency), and in FM that 0Hz component becomes a constant offset in the phase increment (the "instantaneous frequency") of the outer or lowermost carrier. Our fundamental frequency no longer has any obvious relation to wc! That is, we can expand our cascade formula (in the sin(x + cos(sin)) case) into:

more sins

but now whenever the wc, we get j0 case, and the carrier is offset by (radians->hz (bes-jn B)), that is, (Jn(B) * srate / (2 * pi)). For example, if we have (oscil gen 0.05), where we've omitted everything except the constant (DC) term (0.05 in this case), this oscil produces a sine wave at its nominal frequency + (radians->hz 0.05), an offset of about 351 Hz at a 44100 Hz sampling rate. This extra offset could be a disaster, because in most cases where we care about the perceived fundamental, we are trying to create harmonic spectra, and that is harder if our modulator/carrier ratio depends on the current FM index. If you are using low indices and the top pair's mc-ratios are below 1.0 (in vibrato, for example), you have a good chance of getting usable results. If you want cascade FM to work in other situations, make sure the top oscil has an initial phase of (pi + mod-incr)/2. The middle FM spectrum will then have only sines (not cosines), so the DC component will be thoroughly discouraged. Or use phase modulation instead; in that case, we have effectively (oscil gen 0.0 0.05), which has no effect on the pitch, but offsets the phase by a constant (0.05), usually not a big deal.

The irascible reader may be grumbling about angels and pins, so here's an example of cascade FM to show how strong this effect is:

(define (cascade beg dur freq amp modrat modind casrat casind caspha)
  (let* ((start (seconds->samples beg))
	 (end (+ start (seconds->samples dur)))
	 (cr (make-oscil freq))
	 (md (make-oscil (* freq modrat)))
	 (ca (make-oscil (* freq casrat) caspha))
	 (fm-ind0 (hz->radians (* modind modrat freq)))
	 (fm-ind1 (hz->radians (* casind casrat freq))))
     (do ((i start (+ i 1)))
         ((= i end))
       (outa i (* amp 
                  (oscil cr (* fm-ind0 
                               (oscil md (* fm-ind1 
                                            (oscil ca))))))))))

(with-sound () 
  (cascade 0 1.0 400 .25 1.0 1.0 1.0 1.0 0)
  (cascade 1.5 1.0 400 .25 1.0 1.0 1.0 1.0 (* .5 pi)))

;;; clean it up by using the no-DC initial phase:
(with-sound () 
  (cascade 0 1.0 400 .25 1 1.0 1 1.0 (* 0.5 (+ pi (hz->radians 400)))))

Why stop at three sins? Here's an experiment that calls sin(sin(sin...)) k times; it seems to be approaching a square wave as k heads into the stratosphere:

3 sins 30 sins 300 sins
k=3 k=30 k=300

If we use "cos" here instead of "sin", we get a constant, as Bill Gosper has shown:

nested cos equation

As z increases above 1.27, we get a square wave, then period doubling, and finally (ca. 1.97) chaos.

feedback FM: sin(x=sin(x))

A similar trick comes up in feedback FM used in some synthesizers. Here the output of the modulator is fed back into its input:

sin(y <= w + B sin y)

This is expanded by Tomisawa as:

feedback fm

As Tomisawa points out, this is very close to the other FM formulas, except that the argument to the Bessel function depends on the order, we have only multiples of the carrier frequency in the expansion, and the elements of the sequence are multiplied by 2/nB. The result is a much broader, flatter spectrum than you normally get from FM. If you just push the index up in normal FM, the energy is pushed outward in a lumpy sort of fashion, not evenly spread across the spectrum. In effect we've turned the axis of the Bessel functions so that the higher order functions start at nearly the same time as the lower order functions. The new function Jn(nB) decreases (very!) gradually. For example if the index (B) is 1:

Jn vals

Since the other part of the equation goes down as 1/n, we get essentially a sawtooth wave out of this equation (its harmonics go down as 1/n). Tomisawa suggests that B should be between 0 and 1.5. Since we are dividing by B in the equation, we might worry that as B heads toward 0, all hell breaks loose, but luckily

lim1 case

and for all the other components

all cases

so, just as in normal FM, if the index is 0, we get a pure sine wave.

(define (feedbk beg dur freq amp index)
  (let* ((start (seconds->samples beg))
	 (end (+ start (seconds->samples dur)))
	 (y 0.0)
	 (x-incr (hz->radians freq)))
    (do ((i start (+ i 1))
         (x 0.0 (+ x x-incr)))
        ((= i end))
      (set! y (+ x (* index (sin y))))
      (outa i (* amp (sin y))))))

(with-sound () (feedbk 0 1 100.0 1.0 1.0))
feedback fm
  2/1 J1(1) = 0.880 -> 1.000 (normalized to match fft)
  2/2 J2(2) = 0.353 -> 0.401
  2/3 J3(3) = 0.206 -> 0.234
  2/4 J4(4) = 0.141 -> 0.159
  2/5 J5(5) = 0.104 -> 0.118
  2/6 J6(6) = 0.082 -> 0.093
  2/7 J7(7) = 0.066 -> 0.076

Why does the FFT show a 0 Hz component? Increasing the sampling rate, or decreasing the carrier frequency reduces this component without affecting the others, but low-pass filtering the output does not affect it (so it's unlikely to be an artifact of aliasing which is a real problem in feedback FM). Change the sine to cosine in (* amp (sin y)) and suddenly there's a ton of DC. Fiddle with the initial phase in that line, and there's always some choice that reduces it to 0.0. Groan — it appears to be another "centering" problem, but I haven't found the magic formula yet (a reasonable stab at it is: -(phase-incr^(1-(B/3)))).

feedback noise
Tomisawa's picture of the noise

Why does an index over 1.0 create bursts of noise? Each burst happens as the modulator phase goes through an odd multiple of pi (where sine is going negative as the phase increases). Since the index (B) is high enough, the change between successive samples in (B * sin(y)) is eventually greater in magnitude than the phase increment. When that happens on the downslope of the sine curve, B * sin(y) + phase-increment (our overall phase increment) is so much more negative on the current sample than the previous one that the phase actually backs up. (This is confusing to analyze because at this point in the curve, the feedback is already holding the phase back, so we need to reach a point where the increase in the backup overwhelms the increment on that sample, thereby backing up the overall phase beyond its previous held back value). So the modulator phase backs into the less negative part of the sine curve: our next y value is less negative (it can even be positive)! But now B * sin(y) is also less negative, so the phase increment lurches us forward, and y is now even more negative. We've started to zig-zag down the sine curve. Depending on the index, this bouncing can reach any amplitude, and start anywhere after the high point of the curve. Eventually, the sine slope lessens (as it reaches its bottom), the overall phase catches up, and the bouncing stops for that cycle. The noise is not chaos (in the sense of period doubling), or an error in the computation. Our largest safe index is increment/sin(increment) which is just over 1.0. If we change the code to make sure the carrier phase doesn't back up, the bursts go away until the index reaches about 1.4, then we start to zigzag at the zero crossing. The take-home message is: "keep the index below 1.0!".

FM and noise: sin(sin(rand))

One way to make noise (deliberately) with FM is to increase the index until massive aliasing is taking place. A more controllable approach is to use a random number generator as our modulator. In this case, the power spectral density of the output has the same form as the value distribution function (amplitude distribution as opposed to frequency) of the modulating noise, centered around the carrier. The bandwidth of the result is about 4 times the peak deviation (the random number frequency times its index — is this just Mr Carson again?):

(with-sound ()
  (let ((gen (make-oscil 5000))
	(noise (make-rand 1000 :envelope '(-1 1 0 0 1 1))) ; "eared"
	(index (hz->radians 1000))) ; index=1.0 so bandwith=4 Khz (2 Khz on each side)
    (do ((i 0 (+ i 1)))
	((= i 50000))
      (outa i (oscil gen (* index (rand noise)))))))
white-noise gaussian-noise split-noise
flat gaussian (bell curve) eared

Simple FM with noise gives both whooshing sounds (high index) and hissing or whistling sounds (low index), useful for Oceanic Music, but more subtle kinds of noise can be hard to reach. Heinrich Taube had the inspired idea of feeding the noise (as a sort of cascade FM) into the parallel modulators of an fm-flute, but not into the carrier. The modulating signal becomes a sum of two or three narrow band noises (narrow because normally the amplitude of the noise is low), and these modulate the carrier. In CLM:

(oscil carrier (* fm-index (oscil fm (* noise-index (rand noise)))))

You may have noticed that this is one case where phase modulation is different from FM. Previously, we could fix up each modulating sinusoid (both in amplitude and initial phase), but here we have no such handles on the components of the incoming signal. If someone insists, we can still match outputs by integrating the modulating signal: FM(white-noise) = PM(brownian-noise). Similarly, FM(square-wave) = PM(triangle-wave), FM(nxy1sin) = PM(square-wave), and FM(e^x) = PM(e^x). FM(square-wave) is:

fm(noise).

In the realm of "anything" as the modulating signal, consider

(sin (+ sound-file (* index (sin (* 2 pi sound-file)))))

where "sound file" is any recorded sound. I call this "contrast-enhancement" in the CLM package. It makes a sound crisper; "Wait for Me!" uses it whenever a sound needs to cut through a huge mix.

FM voice

We can use more than one sinusoidal component in our carrier, or multiple banks of carriers and modulators, and depend upon vibrato and "spectral fusion" to make the result sound like one voice. In this cross between additive synthesis (the multiple carriers) and FM (the formant centered on each carrier), we get around many of the limitations of the Bessel functions. There are numerous examples in fmviolin.clm. One of the raspier versions of the fm-violin used a sawtooth wave as the carrier, and some sci-fi sound effects use triangle waves as both carrier and modulator. See generators.scm for many other FM-inspired synthesis techniques, including J0(B sin x): "Bessel FM". An elaborate multi-carrier FM instrument is the voice instrument written by Marc Le Brun, used in "Colony" and other pieces:

(define* (vox beg dur freq amp (indexes '(.005 .01 .02)) (formant-amps '(.86 .13 .01)))
  (let* ((start (seconds->samples beg))
	 (end (+ start (seconds->samples dur)))
	 (car-os (make-oscil 0))
         (evens (make-vector 3))
         (odds (make-vector 3))
         (amps (apply vct formant-amps))
         (ampf (make-env '(0 0 25 1 75 1 100 0) :scaler amp :duration dur))
         (frmfs (make-vector 3))
         (indices (apply vct indexes))
         (per-vib (make-triangle-wave 6 :amplitude (* freq .03)))
         (ran-vib (make-rand-interp 20 :amplitude (* freq .5 .02))))
    (do ((i 0 (+ i 1)))
	((= i 3))
      (set! (evens i) (make-oscil 0))
      (set! (odds i) (make-oscil 0)))

    (set! (frmfs 0) (make-env '(0 520 100 490) :duration dur)) 
    (set! (frmfs 1) (make-env '(0 1190 100 1350) :duration dur)) 
    (set! (frmfs 2) (make-env '(0 2390 100 1690) :duration dur))

    (do ((i start (+ i 1)))
        ((= i end))
      (let* ((frq (+ freq (triangle-wave per-vib) (rand-interp ran-vib)))
	     (car (oscil car-os (hz->radians frq)))
	     (sum 0.0))
        (do ((k 0 (+ k 1)))
            ((= k 3))
          (let* ((frm (env (frmfs k)))
	         (frm0 (/ frm frq))
	         (frm-int (floor frm0))
	         (even-amp 0.0) (odd-amp 0.0) 
	         (even-freq 0.0) (odd-freq 0.0))
            (if (even? frm-int)
	        (begin
	          (set! even-freq (hz->radians (* frm-int frq)))
	          (set! odd-freq (hz->radians (* (+ frm-int 1) frq)))
	          (set! odd-amp (- frm0 frm-int))
	          (set! even-amp (- 1.0 odd-amp)))
	        (begin
	          (set! odd-freq (hz->radians (* frm-int frq)))
	          (set! even-freq (hz->radians (* (+ frm-int 1) frq)))
	          (set! even-amp (- frm0 frm-int))
	          (set! odd-amp (- 1.0 even-amp))))
            (set! sum (+ sum (+ (* (amps k) 
		                   (+ (* even-amp 
				          (oscil (evens k) 
					         (+ even-freq (* (indices k) car))))
				      (* odd-amp 
				          (oscil (odds k) 
					         (+ odd-freq (* (indices k) car)))))))))))
          (outa i (* (env ampf) sum))))))

(with-sound () 
  (vox 0 1.0 220.0 0.5)
  (vox 1.5 1.0 110 .5 '(0.02 0.01 0.02) '(.9 .09 .01)))

which produces this spectrogram:

voice spectrum

References

Abramowitz and Stegun, "Handbook of Mathematical Functions", Dover 1965.

Benson, "Music: A Mathematical Offering", Cambridge University Press, Nov 2006. Also available
     on-line: http://www.maths.abdn.ac.uk/~bensondj/html/music.pdf.  If the math side of my
     article is of any interest, you might like Benson's discussion of FM.

Chowning, "The Synthesis of Complex Audio Spectra by Means of Frequency Modulation", JAES 21:526-534, 1973

Frost, "Early FM Radio", Johns Hopkins Univ Press, 2010
     I am apparently unfair to Mr Carson; Armstrong quoted him out of context, and I did not dig up
     the original paper.

Gagliardi, "Introduction to Communications Engineering", Wiley Interscience, 1978.

Gray and Mathews, "A Treatise on Bessel Functions and Their Applications to Physics", MacMillan and Co, 1895.

Klapper, "Selected Papers on Frequency Modulation", Dover 1970. (Out of print, but available
     via used book markets such as abebooks or amazon — usually about $25).
     The Bessel function graph is from Corrington, "Variation of Bandwidth with Modulation Index in FM",
     The picture below of an early radio is from Armstrong, "A Method of Reducing Disturbances in Radio
     Signaling by a System of FM".  The Carson quote is also from that paper (originally published
     in Proc. IRE, Vol 24, No 5, pp 689-740, May, 1936, with Carson's paper referred to as
     "Notes on the theory of modulation", Proc. IRE, vol 10, pp 57-82, Feb 1922).

LeBrun, "A Derivation of the Spectrum of FM with a Complex Modulating Wave", CMJ vol1, no 4 1977 p51-52

Moorer, "Signal Processing Aspects of Computer Music: A Survey" Proc IEEE  vol 65 1977.

Palamin, Palamin, Ronveaux "A Method of Generating and Controlling Asymmetrical Spectra", JAES vol 36, 
     no 9, Sept 88, p671-685.

Schottstaedt, "The Simulation of Natural Instrument Tones Using Frequency Modulation 
     with a Complex Modulating Wave", CMJ vol 1 no 4 1977 p46-50

Taub and Schilling, "Principles of Communications Systems", McGraw-Hill, 1986.

Tomisawa, "Tone Production Method for an Electronic Musical Instrument" US Patent 4,249,447, 1981.

Watson, "A Treatise on the Theory of Bessel Functions", Cambridge, 1922.
early FM radio
FM (and AM) radio ca 1934
music v source
music v source
Music 5 FM?
snd-16.1/bird.rb0000644000076400007640000015274012306421672011614 0ustar bilbil# bird songs # translated (semi-automatically) from a Sambox note list to bird.clm, then bird.scm, then bird.rb $out_file = false $out_data = false $with_editable_mixes = false def normalize_partials(lst1) lst = lst1.flatten # i.e. copy -- there doesn't seem to be a copy method for arrays? sum = 0.0 len = (lst.length) / 2 0.upto(len - 1) do |i| sum = sum + lst[(i * 2) + 1] end 0.upto(len - 1) do |i| lst[(i * 2) + 1] = lst[(i * 2) + 1] / sum end lst end def bigbird(start, dur, frequency, freqskew, amplitude, freq_envelope, amp_envelope, partials) gls_env = make_env(freq_envelope, hz2radians(freqskew), dur) os = make_oscil(frequency) coeffs = partials2polynomial(normalize_partials(partials)) amp_env = make_env(amp_envelope, amplitude, dur) beg = (srate() * start).round len = (srate() * dur).round local_data = make_vct len local_data.map! do env(amp_env) * polynomial(coeffs, oscil(os, env(gls_env))) end vct_add!($out_data, local_data, beg) end def bird(start, dur, frequency, freqskew, amplitude, freq_envelope, amp_envelope) gls_env = make_env(freq_envelope, hz2radians(freqskew), dur) os = make_oscil(frequency) amp_env = make_env(amp_envelope, amplitude, dur) beg = (srate() * start).round len = (srate() * dur).round local_data = make_vct len local_data.map! do env(amp_env) * oscil(os, env(gls_env)) end vct_add!($out_data, local_data, beg) end def one_bird(beg, maxdur, birdname, &func) $out_data = make_vct((srate() * maxdur).round) func.call() mix_vct($out_data, (beg*srate()).round, $out_file, 0, $with_editable_mixes) birdname end $main_amp = [0.00, 0.00, 0.25, 1.00, 0.60, 0.70, 0.75, 1.00, 1.00, 0.0] $bird_tap = [0.00, 0.00, 0.01, 1.00, 0.99, 1.00, 1.00, 0.0] $bird_amp = [0.00, 0.00, 0.25, 1.00, 0.75, 1.00, 1.00, 0.0] def orchard_oriole(beg) oriup = [0.00, 0.00, 1.00, 1.0] oridwn = [0.00, 1.00, 1.00, 0.0] oriupdwna = [0.00, 0.00, 0.60, 1.00, 1.00, 0.60] oriupdwnb = [0.00, 0.50, 0.30, 1.00, 1.00, 0.0] oribiga = [0.00, 0.90, 0.15, 1.00, 0.40, 0.30, 0.60, 0.60, 0.85, 0.00, 1.00, 0.0] orimid = [0.00, 1.00, 0.05, 0.50, 0.10, 1.00, 0.25, 0.00, 0.85, 0.50, 1.00, 0.0] oridwnup = [0.00, 0.30, 0.25, 0.00, 1.00, 1.0] oriamp = [0.00, 0.00, 0.10, 1.00, 1.00, 0.0] one_bird(beg, 3.0, "orchard_oriole") do bird(0.38, 0.03, 3700, 100, 0.05, oridwn, $main_amp) bird(0.41, 0.05, 2500, 1000, 0.1, oriup, $main_amp) bigbird(0.5, 0.1, 2000, 800, 0.2, oriupdwna, $main_amp, [1, 1, 2, 0.02, 3, 0.05]) bird(0.65, 0.03, 3900, 1200, 0.1, oridwn, $main_amp) bigbird(0.7, 0.21, 2000, 1200, 0.15, oribiga, $main_amp, [1, 1, 2, 0.05]) bird(1.0, 0.05, 4200, 1000, 0.1, oridwn, $main_amp) bigbird(1.1, 0.1, 2000, 1000, 0.25, orimid, $main_amp, [1, 1, 2, 0.05]) bigbird(1.3, 0.1, 2000, 1000, 0.25, orimid, $main_amp, [1, 1, 2, 0.05]) bird(1.48, 0.1, 2300, 3200, 0.1, oriupdwnb, oriamp) bird(1.65, 0.03, 1800, 300, 0.05, oriup, $main_amp) bird(1.7, 0.03, 2200, 100, 0.04, oridwn, $main_amp) bird(1.8, 0.07, 2500, 2000, 0.15, oriupdwnb, oriamp) bigbird(1.92, 0.2, 2400, 1200, 0.25, oridwnup, $main_amp, [1, 1, 2, 0.04]) bird(2.2, 0.02, 2200, 3000, 0.04, oriup, $main_amp) bird(2.28, 0.02, 2200, 3000, 0.04, oriup, $main_amp) bigbird(2.4, 0.17, 2000, 1000, 0.2, oriupdwna, oriamp, [1, 1, 2, 0.04]) end end def cassins_kingbird(beg) kingfirst = [0.00, 0.30, 0.45, 1.00, 0.90, 0.10, 1.00, 0.0] kingsecond = [0.00, 0.00, 0.02, 0.50, 0.04, 0.00, 0.06, 0.55, 0.08, 0.05, 0.10, 0.60, 0.12, 0.05, 0.14, 0.65, 0.16, 0.10, 0.18, 0.70, 0.20, 0.10, 0.22, 0.75, 0.24, 0.15, 0.26, 0.80, 0.28, 0.20, 0.30, 0.85, 0.32, 0.25, 0.34, 0.90, 0.36, 0.30, 0.38, 0.95, 0.40, 0.40, 0.42, 1.00, 0.44, 0.50, 0.46, 1.00, 0.48, 0.45, 0.50, 1.00, 0.52, 0.50, 0.54, 1.00, 0.56, 0.40, 0.58, 0.95, 0.60, 0.40, 0.62, 0.90, 0.64, 0.40, 0.66, 0.85, 0.68, 0.35, 0.70, 0.80, 0.72, 0.30, 0.74, 0.75, 0.76, 0.25, 0.78, 0.70, 0.80, 0.20, 0.82, 0.65, 0.84, 0.10, 0.86, 0.60, 0.88, 0.00, 0.90, 0.55, 0.92, 0.00, 0.94, 0.50, 0.96, 0.00, 1.00, 0.40] one_bird(beg, 3.0, "cassins_kingbird") do bigbird(0.03, 0.04, 1700, 1200, 0.15, kingfirst, $main_amp, [1, 1, 2, 0.5, 3, 0, 4, 0.2]) bigbird(0.12, 0.18, 1700, 900, 0.25, kingsecond, $main_amp, [1, 1, 2, 0.01, 3, 0, 4, 0.1]) end end def chipping_sparrow(beg) chip_up = [0.00, 0.80, 0.15, 1.00, 0.75, 0.30, 1.00, 0.0] one_bird(beg, 1.1, "chipping_sparrow") do bird(0, 0.05, 4000, 2400, 0.2, chip_up, $main_amp) bird(0.06, 0.05, 4000, 2400, 0.2, chip_up, $main_amp) bird(0.12, 0.05, 4000, 2400, 0.2, chip_up, $main_amp) bird(0.18, 0.05, 4000, 2400, 0.2, chip_up, $main_amp) bird(0.24, 0.05, 4000, 2400, 0.2, chip_up, $main_amp) bird(0.30, 0.05, 4000, 2400, 0.2, chip_up, $main_amp) bird(0.36, 0.05, 4000, 2400, 0.2, chip_up, $main_amp) bird(0.42, 0.05, 4000, 2400, 0.2, chip_up, $main_amp) bird(0.48, 0.05, 4000, 2400, 0.2, chip_up, $main_amp) bird(0.54, 0.05, 4000, 2400, 0.2, chip_up, $main_amp) bird(0.60, 0.05, 4000, 2400, 0.2, chip_up, $main_amp) bird(0.66, 0.05, 4000, 2400, 0.2, chip_up, $main_amp) bird(0.72, 0.05, 4000, 2400, 0.2, chip_up, $main_amp) bird(0.78, 0.05, 4000, 2400, 0.2, chip_up, $main_amp) bird(0.84, 0.05, 4000, 2400, 0.2, chip_up, $main_amp) bird(0.90, 0.05, 4000, 2400, 0.2, chip_up, $main_amp) bird(0.96, 0.05, 4000, 2400, 0.2, chip_up, $main_amp) end end def bobwhite(beg) bobup1 = [0.00, 0.00, 0.40, 1.00, 1.00, 1.0] bobup2 = [0.00, 0.00, 0.65, 0.50, 1.00, 1.0] one_bird(beg, 2.0, "bobwhite") do bigbird(0.4, 0.2, 1800, 200, 0.1, bobup1, $main_amp, [1, 1, 2, 0.02]) bigbird(1, 0.20, 1800, 1200, 0.2, bobup2, $main_amp, [1, 1, 2, 0.02]) end end def western_meadowlark(beg) no_skw = [0.00, 0.00, 1.00, 0.0] down_skw = [0.00, 1.00, 0.40, 0.40, 1.00, 0.0] fas_down = [0.00, 1.00, 1.00, 0.0] one_bird(beg, 3.0, "western_meadowlark") do bigbird(0.800, 0.1, 2010.000, 0.000, 0.100, no_skw, $main_amp, [1, 1, 2, 0.04]) bigbird(1.100, 0.15, 3000.000, 100.000, 0.110, down_skw, $main_amp, [1, 1, 2, 0.04]) bigbird(1.300, 0.25, 2000.000, 150.000, 0.200, down_skw, $main_amp, [1, 1, 2, 0.04]) bigbird(1.650, 0.15, 3010.000, 250.000, 0.110, down_skw, $main_amp, [1, 1, 2, 0.04]) bigbird(1.850, 0.10, 2200.000, 150.000, 0.110, down_skw, $main_amp, [1, 1, 2, 0.04]) bigbird(2.000, 0.10, 3200.000, 1400.000, 0.110, fas_down, $main_amp, [1, 1, 2, 0.04]) bigbird(2.200, 0.05, 2000.000, 200.000, 0.110, fas_down, $main_amp, [1, 1, 2, 0.04]) bigbird(2.300, 0.10, 1600.000, 0.000, 0.110, fas_down, $main_amp, [1, 1, 2, 0.04]) end end def scissor_tailed_flycatcher(beg) scissor = [0.00, 0.00, 0.40, 1.00, 0.60, 1.00, 1.00, 0.0] one_bird(beg, 1.0, "scissor_tailed_flycatcher") do bigbird(0, 0.05, 1800, 1800, 0.2, scissor, $main_amp, [1, 0.5, 2, 1, 3, 0.5, 4, 0.1, 5, 0.01]) end end def great_horned_owl(beg) owlup = [0.00, 0.00, 0.30, 1.00, 1.00, 1.0] owldown = [0.00, 1.00, 1.00, 0.0] one_bird(beg, 3.0, "great_horned_owl") do bigbird(0.3, 0.1, 300, 0, 0.1, $main_amp, $main_amp, [1, 1, 3, 0.02, 7, 0.01]) bigbird(0.6, 0.4, 293, 6, 0.1, owldown, $main_amp, [1, 1, 3, 0.02, 7, 0.01]) bigbird(1.75, 0.35, 293, 7, 0.1, owlup, $main_amp, [1, 1, 3, 0.02, 7, 0.01]) bigbird(2.5, 0.2, 300, 0, 0.1, owlup, $main_amp, [1, 1, 3, 0.02, 7, 0.01]) end end def black_throated_gray_warbler(beg) grayone = [0.00, 0.50, 0.02, 0.60, 0.04, 0.45, 0.06, 0.62, 0.08, 0.40, 0.10, 0.65, 0.12, 0.35, 0.14, 0.70, 0.18, 0.30, 0.20, 0.70, 0.22, 0.30, 0.24, 0.70, 0.25, 0.20, 0.30, 0.80, 0.35, 0.10, 0.40, 0.90, 0.45, 0.00, 0.50, 1.00, 0.55, 0.00, 0.60, 1.00, 0.65, 0.00, 0.70, 1.00, 0.75, 0.00, 0.80, 1.00, 0.85, 0.00, 0.90, 1.00, 0.95, 0.00, 1.00, 0.50] graytwo = [0.00, 0.00, 0.01, 0.40, 0.02, 0.00, 0.03, 0.40, 0.04, 0.00, 0.05, 0.40, 0.06, 0.00, 0.07, 0.40, 0.08, 0.00, 0.09, 0.40, 0.10, 0.00, 0.25, 0.80, 0.40, 0.30, 0.55, 1.00, 0.70, 0.00, 0.85, 0.80, 1.00, 0.40] graythree = [0.00, 1.00, 0.01, 0.60, 0.02, 1.00, 0.03, 0.60, 0.04, 1.00, 0.05, 0.60, 0.06, 1.00, 0.07, 0.60, 0.08, 1.00, 0.09, 0.60, 0.10, 1.00, 0.11, 0.60, 0.12, 1.00, 0.13, 0.60, 0.14, 1.00, 0.15, 0.60, 0.16, 1.00, 0.17, 0.60, 0.18, 1.00, 0.19, 0.60, 0.20, 1.00, 0.21, 0.55, 0.22, 1.00, 0.23, 0.50, 0.24, 1.00, 0.25, 0.50, 0.26, 1.00, 0.27, 0.50, 0.28, 1.00, 0.29, 0.50, 0.30, 1.00, 0.31, 0.50, 0.32, 1.00, 0.33, 0.50, 0.34, 1.00, 0.35, 0.50, 0.36, 1.00, 0.37, 0.50, 0.38, 1.00, 0.39, 0.50, 0.40, 1.00, 0.41, 0.50, 0.42, 1.00, 0.43, 0.50, 0.44, 1.00, 0.45, 0.50, 0.46, 1.00, 0.47, 0.50, 0.48, 1.00, 0.49, 0.50, 0.50, 1.00, 0.51, 0.50, 0.52, 1.00, 0.53, 0.50, 0.54, 1.00, 0.55, 0.50, 0.56, 1.00, 0.57, 0.50, 0.58, 1.00, 0.59, 0.50, 0.60, 1.00, 1.00, 0.0] grayfour = [0.00, 0.00, 1.00, 1.0] one_bird(beg, 2.0, "black_throated_gray_warbler") do bird(0, 0.12, 3700, 600, 0.05, grayone, $main_amp) bird(0.18, 0.08, 3000, 800, 0.07, graytwo, $main_amp) bird(0.28, 0.12, 3700, 600, 0.12, grayone, $main_amp) bird(0.44, 0.08, 3000, 800, 0.15, graytwo, $main_amp) bird(0.54, 0.12, 3700, 600, 0.20, grayone, $main_amp) bird(0.72, 0.08, 3000, 800, 0.25, graytwo, $main_amp) bird(0.82, 0.12, 3700, 600, 0.25, grayone, $main_amp) bird(0.96, 0.2, 3000, 2000, 0.2, graythree, $main_amp) bird(1.2, 0.02, 4500, 500, 0.05, grayfour, $main_amp) bird(1.25, 0.02, 4200, 800, 0.05, grayfour, $main_amp) bird(1.3, 0.02, 4000, 900, 0.05, grayfour, $main_amp) end end def yellow_warbler(beg) yellow_up = [0.00, 0.00, 0.60, 1.00, 1.00, 0.50] yellow_swirl = [0.00, 1.00, 0.05, 1.00, 0.60, 0.00, 0.80, 0.30, 1.00, 0.10] yellow_down = [0.00, 1.00, 1.00, 0.0] yellow_last = [0.00, 0.00, 0.30, 0.20, 0.80, 0.70, 1.00, 1.0] swirl_amp = [0.00, 0.00, 0.90, 1.00, 1.00, 0.0] one_bird(beg, 2.0, "yellow_warbler") do bird(0, 0.05, 5600, 400, 0.05, yellow_up, $main_amp) bird(0.23, 0.12, 5000, 1500, 0.15, yellow_swirl, swirl_amp) bird(0.45, 0.13, 5000, 1700, 0.17, yellow_swirl, swirl_amp) bird(0.62, 0.16, 5000, 2000, 0.20, yellow_swirl, swirl_amp) bird(0.85, 0.15, 5000, 2000, 0.20, yellow_swirl, swirl_amp) bird(1.05, 0.075, 3700, 1000, 0.20, yellow_down, $main_amp) bird(1.15, 0.075, 3700, 800, 0.15, yellow_down, $main_amp) bird(1.25, 0.075, 3700, 800, 0.15, yellow_down, $main_amp) bird(1.4, 0.2, 3700, 2000, 0.2, yellow_last, swirl_amp) end end def black_necked_stilt(beg) upamp = [0.00, 0.00, 0.90, 1.00, 1.00, 0.0] rampup = [0.00, 0.00, 0.50, 1.00, 1.00, 0.20] one_bird(beg, 1.0, "black_necked_stilt") do bigbird(0, 0.1, 900, 100, 0.2, rampup, upamp, [1, 0.5, 2, 1, 3, 0.75, 4, 0.5, 5, 0.1]) bigbird(0.30, 0.1, 900, 200, 0.2, rampup, upamp, [1, 0.5, 2, 1, 3, 0.75, 4, 0.5, 5, 0.1]) bigbird(0.60, 0.1, 900, 250, 0.2, rampup, upamp, [1, 0.5, 2, 1, 3, 0.75, 4, 0.5, 5, 0.1]) end end def chestnut_sided_warbler(beg) ycurve = [0.00, 1.00, 0.30, 0.50, 0.60, 1.00, 0.80, 0.20, 1.00, 0.0] vcurve = [0.00, 0.20, 0.50, 1.00, 1.00, 0.0] wcurve = [0.00, 0.50, 0.15, 0.00, 0.45, 0.10, 0.60, 1.00, 0.70, 0.90, 1.00, 0.90] upcurve = [0.00, 0.00, 0.95, 1.00, 1.00, 1.0] downcurve = [0.00, 1.00, 0.25, 0.30, 0.60, 0.15, 1.00, 0.0] louder = [0.00, 0.00, 0.90, 1.00, 1.00, 0.0] wamp = [0.00, 0.00, 0.10, 1.00, 0.40, 0.10, 0.50, 0.90, 0.60, 0.10, 0.70, 1.00, 1.00, 0.0] one_bird(beg, 2.0, "chestnut_sided_warbler") do bigbird(0.1, 0.1, 4050, 1200, 0.05, ycurve, $main_amp, [1, 1, 2, 0.1]) bigbird(0.25, 0.03, 3900, 300, 0.075, vcurve, $main_amp, [1, 1, 2, 0.1]) bigbird(0.3, 0.1, 4050, 1200, 0.15, ycurve, louder, [1, 1, 2, 0.1]) bigbird(0.42, 0.03, 3800, 500, 0.1, vcurve, $main_amp, [1, 1, 2, 0.1]) bigbird(0.5, 0.1, 4000, 1200, 0.2, ycurve, $bird_tap, [1, 1, 2, 0.1]) bigbird(0.65, 0.03, 3800, 500, 0.15, vcurve, $main_amp, [1, 1, 2, 0.1]) bigbird(0.72, 0.1, 4000, 1200, 0.2, ycurve, $bird_tap, [1, 1, 2, 0.1]) bigbird(0.85, 0.03, 3800, 500, 0.15, vcurve, $main_amp, [1, 1, 2, 0.1]) bigbird(0.91, 0.1, 4000, 1200, 0.2, ycurve, $bird_tap, [1, 1, 2, 0.1]) bigbird(1.05, 0.12, 3800, 2200, 0.15, wcurve, wamp, [1, 1, 2, 0.1]) bigbird(1.20, 0.12, 3800, 2200, 0.15, wcurve, wamp, [1, 1, 2, 0.1]) bigbird(1.35, 0.12, 2500, 2200, 0.25, upcurve, louder, [1, 1, 2, 0.1]) bigbird(1.50, 0.12, 2500, 4000, 0.15, downcurve, $main_amp, [1, 1, 2, 0.1]) end end def grasshopper_sparrow(beg) grassone = [0.00, 0.50, 0.02, 0.80, 0.04, 0.30, 0.06, 0.80, 0.07, 0.10, 0.08, 0.90, 0.10, 0.00, 0.11, 0.90, 0.12, 0.00, 0.13, 0.90, 0.14, 0.10, 0.15, 1.00, 0.16, 0.10, 0.17, 1.00, 0.18, 0.10, 0.19, 1.00, 0.20, 0.10, 0.21, 1.00, 0.22, 0.10, 0.23, 1.00, 0.24, 0.10, 0.25, 1.00, 0.26, 0.10, 0.27, 1.00, 0.28, 0.10, 0.29, 1.00, 0.30, 0.10, 0.31, 1.00, 0.32, 0.10, 0.33, 1.00, 0.34, 0.10, 0.35, 1.00, 0.36, 0.10, 0.37, 1.00, 0.38, 0.10, 0.39, 1.00, 0.40, 0.10, 0.41, 1.00, 0.42, 0.10, 0.43, 1.00, 0.44, 0.10, 0.45, 1.00, 0.46, 0.10, 0.47, 1.00, 0.48, 0.10, 0.49, 1.00, 0.50, 0.10, 0.51, 1.00, 0.52, 0.10, 0.53, 1.00, 0.54, 0.10, 0.55, 1.00, 0.56, 0.10, 0.57, 1.00, 0.58, 0.10, 0.59, 1.00, 0.60, 0.10, 0.61, 1.00, 0.62, 0.10, 0.63, 1.00, 0.64, 0.10, 0.65, 1.00, 0.66, 0.10, 0.67, 1.00, 0.68, 0.10, 0.69, 1.00, 0.70, 0.10, 0.71, 1.00, 0.72, 0.10, 0.73, 1.00, 0.74, 0.10, 0.75, 1.00, 0.76, 0.10, 0.77, 1.00, 0.78, 0.10, 0.79, 1.00, 0.80, 0.10, 0.81, 1.00, 0.82, 0.10, 0.83, 1.00, 0.84, 0.10, 0.85, 1.00, 0.86, 0.10, 0.87, 1.00, 0.88, 0.10, 0.89, 1.00, 0.90, 0.10, 0.91, 1.00, 0.92, 0.10, 0.93, 1.00, 0.94, 0.10, 0.95, 1.00, 0.96, 0.10, 0.97, 1.00, 0.98, 0.10, 1.00, 1.0] grasstwo = [0.00, 0.00, 0.10, 1.00, 0.20, 0.00, 0.30, 1.00, 0.40, 0.00, 0.50, 1.00, 0.60, 0.00, 0.70, 1.00, 0.80, 0.00, 0.90, 1.00, 1.00, 0.0] one_bird(beg, 3.0, "grasshopper_sparrow") do bird(0.49, 0.01, 8000, 100, 0.1, grasstwo, $main_amp) bird(0.60, 0.01, 5700, 300, 0.1, grasstwo, $main_amp) bird(0.92, 0.01, 3900, 100, 0.1, grasstwo, $main_amp) bird(1.00, 1.4, 6000, 2500, 0.2, grassone, $main_amp) end end def swamp_sparrow(beg) swamp_up = [0.00, 0.00, 0.60, 0.70, 1.00, 1.0] swamp_down = [0.00, 1.00, 0.50, 0.50, 0.60, 0.60, 1.00, 0.0] one_bird(beg, 2.0, "swamp_sparrow") do bird(0, 0.02, 3900, 200, 0.3, swamp_up, $main_amp) bird(0.035, 0.035, 3200, 3000, 0.1, swamp_down, $main_amp) bird(0.08, 0.025, 3700, 0, 0.1, $main_amp, $main_amp) bird(0.1, 0.02, 3900, 200, 0.3, swamp_up, $main_amp) bird(0.135, 0.035, 3200, 3000, 0.1, swamp_down, $main_amp) bird(0.18, 0.025, 3700, 0, 0.1, $main_amp, $main_amp) bird(0.2, 0.02, 3900, 200, 0.3, swamp_up, $main_amp) bird(0.235, 0.035, 3200, 3000, 0.1, swamp_down, $main_amp) bird(0.28, 0.025, 3700, 0, 0.1, $main_amp, $main_amp) bird(0.3, 0.02, 3900, 200, 0.3, swamp_up, $main_amp) bird(0.335, 0.035, 3200, 3000, 0.1, swamp_down, $main_amp) bird(0.38, 0.025, 3700, 0, 0.1, $main_amp, $main_amp) bird(0.4, 0.02, 3900, 200, 0.3, swamp_up, $main_amp) bird(0.435, 0.035, 3200, 3000, 0.1, swamp_down, $main_amp) bird(0.48, 0.025, 3700, 0, 0.1, $main_amp, $main_amp) bird(0.5, 0.02, 3900, 200, 0.3, swamp_up, $main_amp) bird(0.535, 0.035, 3200, 3000, 0.1, swamp_down, $main_amp) bird(0.58, 0.025, 3700, 0, 0.1, $main_amp, $main_amp) bird(0.6, 0.02, 3900, 200, 0.3, swamp_up, $main_amp) bird(0.635, 0.035, 3200, 3000, 0.1, swamp_down, $main_amp) bird(0.68, 0.025, 3700, 0, 0.1, $main_amp, $main_amp) bird(0.7, 0.02, 3900, 200, 0.3, swamp_up, $main_amp) bird(0.735, 0.035, 3200, 3000, 0.1, swamp_down, $main_amp) bird(0.78, 0.025, 3700, 0, 0.1, $main_amp, $main_amp) bird(0.8, 0.02, 3900, 200, 0.3, swamp_up, $main_amp) bird(0.835, 0.035, 3200, 3000, 0.1, swamp_down, $main_amp) bird(0.88, 0.025, 3700, 0, 0.1, $main_amp, $main_amp) bird(0.9, 0.02, 3900, 200, 0.3, swamp_up, $main_amp) bird(0.935, 0.035, 3200, 3000, 0.1, swamp_down, $main_amp) bird(0.98, 0.025, 3700, 0, 0.1, $main_amp, $main_amp) end end def golden_crowned_sparrow(beg) goldone = [0.00, 1.00, 0.25, 0.20, 1.00, 0.0] goldtwo = [0.00, 0.90, 0.05, 1.00, 0.10, 0.40, 1.00, 0.0] goldtrill = [0.00, 0.50, 0.10, 0.00, 0.20, 1.00, 0.30, 0.00, 0.40, 1.00, 0.50, 0.00, 0.60, 1.00, 0.70, 0.00, 0.80, 1.00, 0.90, 0.00, 1.00, 0.50] one_bird(beg, 3.0, "golden_crowned_sparrow") do bird(0.6, 0.5, 4300, 1000, 0.15, goldone, $main_amp) bird(1.3, 0.45, 3300, 200, 0.15, goldone, $main_amp) bird(1.75, 0.4, 3800, 100, 0.15, goldtwo, $main_amp) bird(2.2, 0.3, 3800, 100, 0.1, goldtrill, $main_amp) end end def indigo_bunting(beg) buntdwn = [0.00, 1.00, 1.00, 0.0] buntv = [0.00, 0.00, 0.50, 1.00, 1.00, 0.0] bunty = [0.00, 1.00, 0.50, 0.00, 1.00, 0.90] buntn = [0.00, 0.80, 0.30, 1.00, 0.70, 0.20, 1.00, 0.0] buntx = [0.00, 1.00, 0.10, 0.50, 0.25, 0.90, 1.00, 0.0] buntup = [0.00, 0.00, 1.00, 1.0] one_bird(beg, 3.0, "indigo_bunting") do bird(0.4, 0.08, 3000, 700, 0.25, buntdwn, $main_amp) bird(0.52, 0.02, 6200, 1000, 0.05, buntdwn, $main_amp) bird(0.55, 0.15, 3500, 2300, 0.1, buntv, $main_amp) bird(0.74, 0.02, 6200, 1800, 0.05, buntx, $main_amp) bird(0.80, 0.15, 3400, 2300, 0.1, buntv, $main_amp) bird(1.00, 0.1, 3400, 800, 0.2, buntv, $main_amp) bird(1.13, 0.03, 4100, 2000, 0.05, buntdwn, $main_amp) bird(1.25, 0.08, 3400, 800, 0.2, buntv, $main_amp) bird(1.40, 0.03, 4100, 2000, 0.05, buntdwn, $main_amp) bird(1.5, 0.07, 3700, 300, 0.1, buntdwn, $main_amp) bird(1.6, 0.1, 4100, 2200, 0.15, bunty, $main_amp) bird(1.72, 0.05, 3700, 300, 0.1, buntdwn, $main_amp) bird(1.81, 0.1, 4100, 2200, 0.15, bunty, $main_amp) bird(1.94, 0.07, 5200, 1800, 0.2, buntn, $main_amp) bird(2.05, 0.08, 3000, 1500, 0.15, buntup, $main_amp) bird(2.20, 0.07, 5200, 1800, 0.2, buntn, $main_amp) bird(2.33, 0.08, 3000, 1500, 0.15, buntup, $main_amp) bird(2.43, 0.07, 5200, 1800, 0.1, buntn, $main_amp) bird(2.51, 0.08, 3000, 1500, 0.10, buntup, $main_amp) end end def hooded_warbler(beg) hoodup = [0.00, 0.00, 1.00, 1.0] hooddown = [0.00, 1.00, 1.00, 0.0] one_bird(beg, 3.0, "hooded_warbler") do bird(0.6, 0.03, 3900, 1600, 0.05, hooddown, $main_amp) bird(0.64, 0.03, 3900, 1700, 0.05, hooddown, $main_amp) bird(0.8, 0.03, 3900, 2000, 0.10, hooddown, $main_amp) bird(0.84, 0.03, 3900, 2000, 0.10, hooddown, $main_amp) bird(0.93, 0.03, 3900, 2100, 0.15, hooddown, $main_amp) bird(0.97, 0.03, 3900, 2100, 0.15, hooddown, $main_amp) bird(1.05, 0.03, 3900, 2100, 0.05, hooddown, $main_amp) bird(1.09, 0.03, 3900, 2100, 0.2, hooddown, $main_amp) bird(1.17, 0.03, 3900, 2100, 0.2, hooddown, $main_amp) bird(1.21, 0.03, 3900, 2100, 0.2, hooddown, $main_amp) bird(1.39, 0.03, 3900, 2100, 0.2, hooddown, $main_amp) bird(1.43, 0.03, 3900, 2100, 0.2, hooddown, $main_amp) bird(1.51, 0.03, 3900, 2100, 0.2, hooddown, $main_amp) bird(1.55, 0.03, 3900, 2100, 0.2, hooddown, $main_amp) bird(1.63, 0.03, 3900, 2100, 0.2, hooddown, $main_amp) bird(1.67, 0.03, 3900, 2100, 0.2, hooddown, $main_amp) bird(1.75, 0.03, 3900, 2100, 0.2, hooddown, $main_amp) bird(1.80, 0.03, 3900, 2100, 0.2, hooddown, $main_amp) bird(1.90, 0.04, 3000, 1000, 0.15, hoodup, $main_amp) bird(1.98, 0.04, 3000, 1000, 0.15, hoodup, $main_amp) bird(2.05, 0.04, 3000, 1000, 0.15, hoodup, $main_amp) bird(2.13, 0.04, 3000, 1000, 0.15, hoodup, $main_amp) bird(2.21, 0.04, 3000, 1000, 0.15, hoodup, $main_amp) bird(2.29, 0.04, 3000, 1000, 0.15, hoodup, $main_amp) bird(2.37, 0.04, 3000, 1000, 0.15, hoodup, $main_amp) bird(2.45, 0.04, 3000, 1000, 0.15, hoodup, $main_amp) end end def american_widgeon(beg) widgeon = [0.00, 0.00, 0.50, 1.00, 1.00, 0.0] one_bird(beg, 1.0, "american_widgeon") do bigbird(0.3, 0.07, 1900, 300, 0.15, widgeon, widgeon, [1, 1, 2, 0.02]) bigbird(0.4, 0.11, 1700, 1400, 0.25, widgeon, widgeon, [1, 0.7, 2, 1, 3, 0.02]) bigbird(0.55, 0.07, 1900, 300, 0.15, widgeon, widgeon, [1, 1, 2, 0.02]) end end def louisiana_waterthrush(beg) water_one = [0.00, 0.80, 0.35, 0.40, 0.45, 0.90, 0.50, 1.00, 0.75, 1.00, 1.00, 0.10] water_two = [0.00, 1.00, 0.40, 0.00, 0.60, 0.10, 1.00, 0.80] water_three = [0.00, 1.00, 0.95, 0.00, 1.00, 0.0] water_four = [0.00, 0.00, 1.00, 1.0] water_five = [0.00, 1.00, 1.00, 0.0] water_amp = [0.00, 0.00, 0.35, 1.00, 0.50, 0.20, 0.90, 1.00, 1.00, 0.0] water_damp = [0.00, 0.00, 0.90, 1.00, 1.00, 0.0] one_bird(beg, 2.0, "louisiana_waterthrush") do bird(0, 0.17, 4100, 2000, 0.2, water_one, water_amp) bird(0.32, 0.18, 4050, 2050, 0.3, water_one, water_amp) bird(0.64, 0.20, 4000, 1900, 0.25, water_one, water_amp) bird(0.9, 0.2, 3900, 2000, 0.3, water_two, $bird_tap) bird(1.25, 0.12, 3000, 3000, 0.25, water_three, water_damp) bird(1.4, 0.1, 2700, 1500, 0.2, water_four, water_damp) bird(1.58, 0.02, 5200, 1000, 0.1, water_five, $main_amp) bird(1.65, 0.02, 5200, 1000, 0.1, water_five, $main_amp) bird(1.7, 0.035, 3200, 1000, 0.1, water_four, water_damp) end end def robin(beg) r_one = [0.00, 0.10, 0.08, 0.70, 0.30, 0.00, 0.35, 1.00, 0.40, 0.30, 1.00, 0.30] r_two = [0.00, 0.00, 0.10, 1.00, 0.20, 0.70, 0.35, 0.70, 0.65, 0.30, 0.70, 0.50, 0.80, 0.00, 0.90, 0.20, 1.00, 0.0] r_three = [0.00, 0.20, 0.25, 1.00, 0.60, 0.70, 0.90, 0.00, 1.00, 0.10] r_four = [0.00, 1.00, 1.00, 0.0] r_five = [0.00, 0.50, 0.10, 0.00, 0.20, 1.00, 0.30, 0.00, 0.40, 1.00, 0.50, 0.00, 0.60, 1.00, 0.70, 0.50, 1.00, 0.20] r_six = [0.00, 0.00, 0.12, 0.70, 0.30, 0.00, 0.70, 1.00, 1.00, 0.50] one_bird(beg, 3.0, "robin") do bigbird(0.45, 0.06, 2000, 800, 0.15, r_six, $main_amp, [1, 1, 2, 0.1]) bigbird(0.56, 0.10, 2000, 900, 0.15, r_one, $main_amp, [1, 1, 2, 0.1]) bigbird(1.04, 0.24, 2000, 2000, 0.25, r_two, $main_amp, [1, 1, 2, 0.1]) bigbird(1.63, 0.13, 1900, 1600, 0.20, r_three, $main_amp, [1, 1, 2, 0.1]) bigbird(1.80, 0.11, 2200, 1200, 0.25, r_four, $main_amp, [1, 1, 2, 0.1]) bigbird(2.31, 0.21, 1950, 2000, 0.15, r_five, $main_amp, [1, 1, 2, 0.1]) end end def solitary_vireo(beg) bigskew = [0.00, 0.20, 0.03, 0.30, 0.06, 0.10, 0.10, 0.50, 0.13, 0.40, 0.16, 0.80, 0.19, 0.50, 0.22, 0.90, 0.25, 0.60, 0.28, 1.00, 0.31, 0.60, 0.34, 1.00, 0.37, 0.50, 0.41, 0.90, 0.45, 0.40, 0.49, 0.80, 0.51, 0.40, 0.54, 0.75, 0.57, 0.35, 0.60, 0.70, 0.63, 0.30, 0.66, 0.60, 0.69, 0.25, 0.72, 0.50, 0.75, 0.20, 0.78, 0.30, 0.82, 0.10, 0.85, 0.30, 0.88, 0.05, 0.91, 0.30, 0.94, 0.00, 0.95, 0.30, 0.99, 0.00, 1.00, 0.10] one_bird(beg, 1.0, "solitary_vireo") do bird(0, 0.4, 1800, 1200, 0.2, bigskew, $main_amp) end end def pigeon_hawk(beg) hupdown = [0.00, 0.00, 0.30, 1.00, 0.70, 1.00, 1.00, 0.0] one_bird(beg, 2.0, "pigeon_hawk") do bigbird(0, 0.1, 1900, 200, 0.2, hupdown, $main_amp, [1, 0.7, 2, 1]) bigbird(0.12, 0.01, 2050, 0, 0.1, $main_amp, $main_amp, [1, 0.5, 2, 1]) bigbird(0.13, 0.1, 1900, 200, 0.2, hupdown, $main_amp, [1, 0.7, 2, 1]) bigbird(0.25, 0.01, 2050, 0, 0.1, $main_amp, $main_amp, [1, 0.5, 2, 1]) bigbird(0.26, 0.1, 1900, 200, 0.2, hupdown, $main_amp, [1, 0.7, 2, 1]) bigbird(0.38, 0.01, 2050, 0, 0.1, $main_amp, $main_amp, [1, 0.5, 2, 1]) bigbird(0.39, 0.1, 1900, 200, 0.2, hupdown, $main_amp, [1, 0.7, 2, 1]) bigbird(0.51, 0.01, 2050, 0, 0.1, $main_amp, $main_amp, [1, 0.5, 2, 1]) bigbird(0.52, 0.1, 1900, 200, 0.2, hupdown, $main_amp, [1, 0.7, 2, 1]) bigbird(0.64, 0.01, 2050, 0, 0.1, $main_amp, $main_amp, [1, 0.5, 2, 1]) bigbird(0.65, 0.1, 1900, 200, 0.2, hupdown, $main_amp, [1, 0.7, 2, 1]) bigbird(0.77, 0.01, 2050, 0, 0.1, $main_amp, $main_amp, [1, 0.5, 2, 1]) bigbird(0.78, 0.1, 1900, 200, 0.2, hupdown, $main_amp, [1, 0.7, 2, 1]) bigbird(0.90, 0.01, 2050, 0, 0.1, $main_amp, $main_amp, [1, 0.5, 2, 1]) bigbird(0.91, 0.1, 1900, 200, 0.2, hupdown, $main_amp, [1, 0.7, 2, 1]) bigbird(1.03, 0.01, 2050, 0, 0.1, $main_amp, $main_amp, [1, 0.5, 2, 1]) bigbird(1.04, 0.1, 1900, 200, 0.2, hupdown, $main_amp, [1, 0.7, 2, 1]) bigbird(1.16, 0.01, 2050, 0, 0.1, $main_amp, $main_amp, [1, 0.5, 2, 1]) bigbird(1.17, 0.1, 1900, 200, 0.2, hupdown, $main_amp, [1, 0.7, 2, 1]) bigbird(1.29, 0.01, 2050, 0, 0.1, $main_amp, $main_amp, [1, 0.5, 2, 1]) bigbird(1.30, 0.1, 1900, 200, 0.2, hupdown, $main_amp, [1, 0.7, 2, 1]) bigbird(1.42, 0.01, 2050, 0, 0.1, $main_amp, $main_amp, [1, 0.5, 2, 1]) bigbird(1.43, 0.1, 1900, 200, 0.2, hupdown, $main_amp, [1, 0.7, 2, 1]) bigbird(1.55, 0.01, 2050, 0, 0.1, $main_amp, $main_amp, [1, 0.5, 2, 1]) bigbird(1.56, 0.1, 1900, 200, 0.2, hupdown, $main_amp, [1, 0.7, 2, 1]) bigbird(1.68, 0.01, 2050, 0, 0.1, $main_amp, $main_amp, [1, 0.5, 2, 1]) bigbird(1.69, 0.1, 1900, 200, 0.2, hupdown, $main_amp, [1, 0.7, 2, 1]) bigbird(1.81, 0.01, 2050, 0, 0.1, $main_amp, $main_amp, [1, 0.5, 2, 1]) bigbird(1.82, 0.1, 1900, 200, 0.2, hupdown, $main_amp, [1, 0.7, 2, 1]) end end def cerulean_warbler(beg) w_down = [0.00, 1.00, 1.00, 0.0] trill = [0.00, 0.80, 0.10, 1.00, 0.25, 0.50, 0.40, 1.00, 0.55, 0.50, 0.70, 1.00, 1.00, 0.0] w_up = [0.00, 0.00, 1.00, 1.0] one_bird(beg, 2.0, "cerulean_warbler") do bird(0.27, 0.05, 3000, 1000, 0.05, w_down, $main_amp) bird(0.33, 0.05, 3000, 800, 0.075, w_up, $main_amp) bird(0.41, 0.01, 3200, 700, 0.07, w_down, $main_amp) bird(0.42, 0.01, 3200, 700, 0.08, w_down, $main_amp) bird(0.43, 0.06, 3200, 700, 0.09, w_down, $main_amp) bird(0.51, 0.06, 3200, 500, 0.1, w_up, $main_amp) bird(0.6, 0.10, 3000, 1200, 0.2, trill, $main_amp) bird(0.72, 0.05, 3000, 800, 0.2, w_up, $main_amp) bird(0.8, 0.10, 3000, 1200, 0.2, trill, $main_amp) bird(0.92, 0.05, 3000, 800, 0.2, w_up, $main_amp) bird(1.00, 0.01, 3900, 600, 0.1, w_up, $main_amp) bird(1.01, 0.01, 3910, 800, 0.1, w_up, $main_amp) bird(1.02, 0.01, 3940, 500, 0.1, w_up, $main_amp) bird(1.03, 0.01, 4000, 500, 0.1, w_up, $main_amp) bird(1.04, 0.01, 3900, 1000, 0.1, w_up, $main_amp) bird(1.05, 0.01, 3900, 1000, 0.1, w_up, $main_amp) bird(1.06, 0.01, 3900, 1000, 0.1, w_up, $main_amp) bird(1.07, 0.01, 3900, 1000, 0.1, w_up, $main_amp) bird(1.08, 0.01, 3900, 1000, 0.1, w_up, $main_amp) bird(1.09, 0.01, 3900, 1000, 0.1, w_up, $main_amp) bird(1.10, 0.01, 3900, 1000, 0.1, w_up, $main_amp) bird(1.11, 0.01, 3900, 1000, 0.1, w_up, $main_amp) bird(1.12, 0.01, 3900, 1000, 0.1, w_up, $main_amp) bird(1.13, 0.01, 3900, 1000, 0.1, w_up, $main_amp) bird(1.14, 0.01, 3900, 1000, 0.1, w_up, $main_amp) bird(1.15, 0.01, 3900, 1000, 0.1, w_up, $main_amp) bird(1.16, 0.01, 3900, 1000, 0.1, w_up, $main_amp) bird(1.17, 0.01, 3900, 1000, 0.1, w_up, $main_amp) bird(1.18, 0.01, 3900, 1000, 0.1, w_up, $main_amp) bird(1.19, 0.01, 3900, 1000, 0.1, w_up, $main_amp) bird(1.20, 0.01, 3900, 1000, 0.1, w_up, $main_amp) bird(1.21, 0.01, 3900, 1000, 0.1, w_up, $main_amp) bird(1.22, 0.01, 3900, 1000, 0.1, w_up, $main_amp) bird(1.23, 0.01, 3900, 1200, 0.1, w_up, $main_amp) bird(1.24, 0.01, 3900, 1200, 0.1, w_up, $main_amp) bird(1.25, 0.01, 3900, 1200, 0.1, w_up, $main_amp) bird(1.26, 0.01, 3900, 1200, 0.1, w_up, $main_amp) bird(1.27, 0.01, 3900, 1400, 0.1, w_up, $main_amp) bird(1.28, 0.01, 3900, 1400, 0.1, w_up, $main_amp) bird(1.29, 0.01, 3900, 1400, 0.1, w_up, $main_amp) bird(1.30, 0.01, 3900, 1400, 0.1, w_up, $main_amp) end end def nashville_warbler(beg) nash_blip = [0.00, 0.60, 0.35, 1.00, 1.00, 0.0] nash_down = [0.00, 0.90, 0.05, 1.00, 0.10, 0.90, 0.65, 0.50, 1.00, 0.0] nash_up = [0.00, 0.00, 0.15, 0.20, 0.25, 0.05, 0.90, 0.95, 1.00, 1.0] nash_amp = [0.00, 0.00, 0.80, 1.00, 1.00, 0.0] one_bird(beg, 2.0, "nashville_warbler") do bird(0.15, 0.025, 3900, 300, 0.3, nash_blip, $main_amp) bird(0.24, 0.16, 4200, 3800, 0.15, nash_down, nash_amp) bird(0.42, 0.025, 3900, 300, 0.3, nash_blip, $main_amp) bird(0.55, 0.14, 4300, 3700, 0.15, nash_down, nash_amp) bird(0.75, 0.03, 3950, 350, 0.3, nash_blip, $main_amp) bird(0.81, 0.17, 4200, 3900, 0.175, nash_down, $main_amp) bird(1.0, 0.02, 3800, 400, 0.25, nash_blip, $main_amp) bird(1.11, 0.14, 4200, 3800, 0.165, nash_down, nash_amp) bird(1.3, 0.03, 3750, 300, 0.2, nash_blip, $main_amp) bird(1.4, 0.11, 4200, 3700, 0.1, nash_down, $main_amp) bird(1.57, 0.1, 3800, 2200, 0.1, nash_up, $main_amp) bird(1.7, 0.1, 3800, 2150, 0.125, nash_up, $main_amp) bird(1.85, 0.075, 3900, 1800, 0.1, nash_up, nash_amp) end end def eastern_phoebe(beg) phoebe_one = [0.00, 0.00, 0.30, 0.30, 0.35, 0.50, 0.55, 0.40, 0.70, 0.80, 0.75, 0.70, 0.80, 1.00, 0.95, 0.90, 1.00, 0.0] phoebe_two = [0.00, 0.00, 0.50, 1.00, 1.00, 0.0] phoebe_three = [0.00, 0.00, 0.10, 0.40, 0.80, 1.00, 1.00, 0.10] phoebe_four = [0.00, 1.00, 0.50, 0.70, 1.00, 0.0] phoebe_amp = [0.00, 0.00, 0.10, 1.00, 1.00, 0.0] one_bird(beg, 1.0, "eastern_phoebe") do bird(0, 0.225, 3000, 1300, 0.3, phoebe_one, $main_amp) bird(0.35, 0.12, 3000, 500, 0.1, phoebe_two, phoebe_amp) bird(0.4, 0.10, 3000, 1500, 0.2, phoebe_three, phoebe_amp) bird(0.55, 0.05, 3000, 1400, 0.2, phoebe_four, phoebe_amp) end end def painted_bunting(beg) b_one = [0.00, 0.00, 1.00, 1.0] b_two = [0.00, 0.00, 0.90, 1.00, 1.00, 0.0] b_three = [0.00, 1.00, 1.00, 0.0] b_four = [0.00, 0.00, 0.50, 1.00, 1.00, 0.0] b_five = [0.00, 0.70, 0.15, 0.00, 0.40, 1.00, 0.80, 1.00, 1.00, 0.50] b_six = [0.00, 0.00, 0.10, 0.50, 0.15, 0.00, 0.40, 1.00, 0.90, 1.00, 1.00, 0.0] b_seven = [0.00, 1.00, 0.25, 0.40, 0.75, 0.50, 1.00, 0.0] b_eight = [0.00, 0.30, 0.40, 0.40, 0.50, 1.00, 0.60, 0.20, 1.00, 0.0] b_nine = [0.00, 0.00, 0.05, 1.00, 0.30, 1.00, 0.50, 0.30, 0.90, 1.00, 1.00, 0.0] b_ten = [0.00, 0.40, 0.25, 0.00, 0.35, 1.00, 0.50, 0.00, 0.65, 1.00, 0.75, 0.00, 0.85, 1.00, 1.00, 0.0] b_eleven = [0.00, 1.00, 1.00, 0.0] b_twelve = [0.00, 0.00, 0.50, 1.00, 1.00, 0.50] b_thirteen = [0.00, 0.00, 0.05, 1.00, 0.30, 0.20, 0.60, 0.20, 0.90, 1.00, 1.00, 0.0] b_fourteen = [0.00, 0.30, 0.30, 1.00, 0.60, 0.30, 1.00, 0.0] b_fifteen = [0.00, 0.00, 0.10, 0.50, 0.50, 0.50, 0.90, 1.00, 1.00, 0.0] one_bird(beg, 2.0, "painted_bunting") do bird(0.05, 0.10, 3100, 900, 0.05, b_one, b_two) bird(0.21, 0.07, 4100, 700, 0.15, b_three, $main_amp) bird(0.36, 0.12, 3700, 1000, 0.20, b_four, $main_amp) bird(0.52, 0.08, 2300, 1600, 0.15, b_five, b_six) bird(0.68, 0.1, 4000, 1000, 0.25, b_one, $bird_tap) bird(0.8, 0.12, 2300, 1700, 0.2, b_seven, $main_amp) bird(0.96, 0.15, 3800, 2200, 0.3, b_eight, b_nine) bird(1.18, 0.1, 2300, 1600, 0.15, b_ten, $main_amp) bird(1.3, 0.02, 3200, 1000, 0.1, b_eleven, $main_amp) bird(1.33, 0.02, 3200, 1000, 0.1, b_eleven, $main_amp) bird(1.36, 0.02, 3200, 1000, 0.1, b_eleven, $main_amp) bird(1.40, 0.03, 4000, 2000, 0.12, b_twelve, b_thirteen) bird(1.47, 0.1, 2300, 1700, 0.2, b_fourteen, b_fifteen) end end def western_flycatcher(beg) f_one = [0.00, 0.00, 0.10, 1.00, 0.20, 0.40, 0.95, 0.10, 1.00, 0.0] a_one = [0.00, 0.00, 0.10, 0.20, 0.20, 0.10, 0.30, 1.00, 0.90, 1.00, 1.00, 0.0] f_two = [0.00, 0.50, 0.25, 1.00, 0.50, 0.00, 0.60, 0.00, 0.95, 0.30, 1.00, 0.60] a_two = [0.00, 0.00, 0.10, 1.00, 0.20, 1.00, 0.50, 0.10, 0.60, 0.10, 0.90, 1.00, 1.00, 0.0] one_bird(beg, 1.0, "western_flycatcher") do bigbird(0, 0.2, 2000, 2200, 0.2, f_one, a_one, [1, 1, 2, 0.02, 3, 0.1, 4, 0.01]) bigbird(0.3, 0.2, 2000, 1100, 0.2, f_two, a_two, [1, 1, 2, 0.02, 3, 0.1, 4, 0.01]) end end def bachmans_sparrow(beg) sopening = [0.00, 1.00, 0.10, 0.50, 0.90, 0.50, 1.00, 0.0] sup = [0.00, 0.10, 0.35, 0.00, 1.00, 1.0] sdwn = [0.00, 1.00, 0.40, 0.50, 1.00, 0.0] supn = [0.00, 0.00, 1.00, 1.0] slast = [0.00, 1.00, 0.25, 0.00, 0.75, 0.40, 1.00, 0.50] one_bird(beg, 5.0, "bachmans_sparrow") do bird(0, 0.51, 4900, 200, 0.3, sopening, $main_amp) bird(0.52, 0.015, 3800, 200, 0.1, sup, $main_amp) bird(0.52, 0.015, 3750, 250, 0.1, sup, $main_amp) bird(0.54, 0.015, 3600, 300, 0.1, sup, $main_amp) bird(0.56, 0.015, 3500, 250, 0.1, sup, $main_amp) bird(0.58, 0.015, 3400, 200, 0.1, sup, $main_amp) bird(0.60, 0.015, 3200, 200, 0.1, sup, $main_amp) bird(0.62, 0.015, 3800, 100, 0.1, sup, $main_amp) bird(0.65, 0.07, 3000, 750, 0.2, sup, $main_amp) bird(0.73, 0.03, 5000, 1000, 0.1, sdwn, $main_amp) bird(0.80, 0.07, 3000, 750, 0.2, sup, $main_amp) bird(0.88, 0.03, 5000, 1000, 0.1, sdwn, $main_amp) bird(0.95, 0.07, 3000, 750, 0.2, sup, $main_amp) bird(1.03, 0.03, 5000, 1000, 0.1, sdwn, $main_amp) bird(1.10, 0.07, 3000, 750, 0.2, sup, $main_amp) bird(1.18, 0.03, 5000, 1000, 0.1, sdwn, $main_amp) bird(1.25, 0.07, 3000, 750, 0.2, sup, $main_amp) bird(1.33, 0.03, 5000, 1000, 0.1, sdwn, $main_amp) bird(1.40, 0.07, 3000, 750, 0.2, sup, $main_amp) bird(1.48, 0.03, 5000, 1000, 0.1, sdwn, $main_amp) bird(1.55, 0.07, 3000, 750, 0.2, sup, $main_amp) bird(1.63, 0.03, 5000, 1000, 0.1, sdwn, $main_amp) bird(2.8, 0.06, 4000, 1700, 0.1, supn, $main_amp) bird(2.87, 0.01, 5200, 0, 0.2, supn, $main_amp) bird(2.9, 0.06, 4000, 1700, 0.1, supn, $main_amp) bird(2.97, 0.01, 5200, 0, 0.2, supn, $main_amp) bird(3.0, 0.06, 4000, 1700, 0.1, supn, $main_amp) bird(3.07, 0.01, 5200, 0, 0.2, supn, $main_amp) bird(3.1, 0.06, 4000, 1700, 0.1, supn, $main_amp) bird(3.17, 0.01, 5200, 0, 0.2, supn, $main_amp) bird(3.2, 0.06, 4000, 1700, 0.1, supn, $main_amp) bird(3.27, 0.01, 5200, 0, 0.2, supn, $main_amp) bird(3.4, 0.15, 3000, 1000, 0.2, slast, $main_amp) bird(3.6, 0.15, 3000, 1000, 0.2, slast, $main_amp) bird(3.8, 0.15, 3000, 1000, 0.2, slast, $main_amp) bird(4.0, 0.15, 3000, 1000, 0.2, slast, $main_amp) bird(4.2, 0.15, 3000, 1000, 0.2, slast, $main_amp) bird(4.4, 0.15, 3000, 1000, 0.2, slast, $main_amp) end end def cedar_waxwing(beg) cedar = [0.00, 0.00, 0.25, 0.70, 0.70, 1.00, 0.90, 1.00, 1.00, 0.20] cedamp = [0.00, 0.00, 0.20, 1.00, 0.40, 1.00, 1.00, 0.0] one_bird(beg, 1.0, "cedar_waxwing") do bird(0, 0.50, 6000, 800, 0.2, cedar, cedamp) end end def bairds_sparrow(beg) bairdend = [0.00, 0.00, 0.25, 1.00, 0.50, 0.00, 0.75, 1.00, 1.00, 0.0] bairdstart = [0.00, 0.50, 0.05, 1.00, 0.10, 0.00, 0.15, 1.00, 0.20, 0.00, 0.25, 1.00, 0.30, 0.00, 0.35, 1.00, 0.40, 0.00, 0.45, 1.00, 0.50, 0.00, 0.55, 1.00, 0.60, 0.00, 0.65, 1.00, 0.70, 0.00, 0.75, 1.00, 0.80, 0.00, 0.85, 1.00, 0.90, 0.00, 0.95, 1.00, 1.00, 0.0] one_bird(beg, 2.0, "bairds_sparrow") do bird(0, 0.09, 6500, 1500, 0.2, bairdstart, $main_amp) bird(0.22, 0.01, 5900, 100, 0.2, bairdend, $main_amp) bird(0.25, 0.09, 6000, 1000, 0.2, bairdstart, $main_amp) bird(0.45, 0.01, 4200, 100, 0.2, bairdend, $main_amp) bird(0.50, 0.08, 4200, 600, 0.2, bairdstart, $main_amp) bird(0.59, 0.01, 4400, 100, 0.2, bairdend, $main_amp) bird(0.60, 0.01, 4400, 100, 0.2, bairdend, $main_amp) bird(0.68, 0.07, 5400, 700, 0.2, bairdstart, $main_amp) bird(0.75, 0.01, 4200, 100, 0.2, bairdend, $main_amp) bird(0.79, 0.01, 4400, 100, 0.2, bairdend, $main_amp) bird(0.83, 0.01, 4200, 100, 0.19, bairdend, $main_amp) bird(0.87, 0.01, 4400, 100, 0.19, bairdend, $main_amp) bird(0.91, 0.01, 4200, 100, 0.18, bairdend, $main_amp) bird(0.95, 0.01, 4400, 100, 0.18, bairdend, $main_amp) bird(0.99, 0.01, 4200, 100, 0.17, bairdend, $main_amp) bird(1.03, 0.01, 4400, 100, 0.17, bairdend, $main_amp) bird(1.07, 0.01, 4200, 100, 0.16, bairdend, $main_amp) bird(1.11, 0.01, 4400, 100, 0.16, bairdend, $main_amp) bird(1.15, 0.01, 4200, 100, 0.15, bairdend, $main_amp) bird(1.19, 0.01, 4400, 100, 0.15, bairdend, $main_amp) bird(1.23, 0.01, 4200, 100, 0.14, bairdend, $main_amp) bird(1.27, 0.01, 4400, 100, 0.14, bairdend, $main_amp) bird(1.31, 0.01, 4200, 100, 0.13, bairdend, $main_amp) bird(1.35, 0.01, 4400, 100, 0.13, bairdend, $main_amp) bird(1.39, 0.01, 4200, 100, 0.12, bairdend, $main_amp) bird(1.43, 0.01, 4400, 100, 0.12, bairdend, $main_amp) bird(1.47, 0.01, 4200, 100, 0.11, bairdend, $main_amp) bird(1.51, 0.01, 4400, 100, 0.11, bairdend, $main_amp) bird(1.55, 0.01, 4200, 100, 0.10, bairdend, $main_amp) bird(1.59, 0.01, 4400, 100, 0.10, bairdend, $main_amp) bird(1.63, 0.01, 4200, 100, 0.09, bairdend, $main_amp) bird(1.67, 0.01, 4400, 100, 0.09, bairdend, $main_amp) bird(1.71, 0.01, 4200, 100, 0.08, bairdend, $main_amp) bird(1.75, 0.01, 4400, 100, 0.08, bairdend, $main_amp) bird(1.79, 0.01, 4200, 100, 0.07, bairdend, $main_amp) bird(1.83, 0.01, 4400, 100, 0.07, bairdend, $main_amp) bird(1.87, 0.01, 4200, 100, 0.06, bairdend, $main_amp) bird(1.92, 0.01, 4400, 100, 0.06, bairdend, $main_amp) bird(1.97, 0.01, 4200, 100, 0.05, bairdend, $main_amp) end end def kentucky_warbler(beg) kenstart = [0.00, 0.30, 0.50, 1.00, 1.00, 0.0] kendwn = [0.00, 0.90, 0.10, 1.00, 1.00, 0.0] kenup = [0.00, 0.00, 1.00, 1.0] kentrill = [0.00, 1.00, 0.25, 0.00, 0.50, 0.00, 0.75, 1.00, 1.00, 0.0] one_bird(beg, 3.0, "kentucky_warbler") do bigbird(0.6, 0.02, 3800, 200, 0.05, kenstart, $main_amp, [1, 1, 2, 0.03]) bigbird(0.65, 0.03, 4300, 200, 0.15, kenup, $main_amp, [1, 1, 2, 0.1]) bigbird(0.73, 0.02, 3200, 100, 0.1, kendwn, $main_amp, [1, 1, 2, 0.1]) bigbird(0.75, 0.05, 3000, 800, 0.15, kenstart, $main_amp, [1, 1, 2, 0.01]) bigbird(0.82, 0.06, 3100, 1200, 0.1, kendwn, $main_amp, [1, 1, 2, 0.01]) bigbird(0.90, 0.06, 3200, 1200, 0.1, kendwn, $main_amp, [1, 1, 2, 0.01]) bigbird(0.98, 0.05, 4600, 100, 0.2, kentrill, $main_amp, [1, 1, 2, 0.1]) bigbird(1.10, 0.05, 2900, 800, 0.15, kenstart, $main_amp, [1, 1, 2, 0.01]) bigbird(1.17, 0.06, 3000, 1200, 0.1, kendwn, $main_amp, [1, 1, 2, 0.01]) bigbird(1.25, 0.06, 3100, 1200, 0.1, kendwn, $main_amp, [1, 1, 2, 0.01]) bigbird(1.33, 0.05, 4600, 100, 0.2, kentrill, $main_amp, [1, 1, 2, 0.1]) bigbird(1.43, 0.05, 2800, 800, 0.15, kenstart, $main_amp, [1, 1, 2, 0.01]) bigbird(1.50, 0.05, 2700, 1200, 0.1, kendwn, $main_amp, [1, 1, 2, 0.01]) bigbird(1.57, 0.06, 2800, 1200, 0.1, kendwn, $main_amp, [1, 1, 2, 0.01]) bigbird(1.64, 0.05, 4600, 100, 0.2, kentrill, $main_amp, [1, 1, 2, 0.1]) bigbird(1.75, 0.05, 2700, 800, 0.15, kenstart, $main_amp, [1, 1, 2, 0.01]) bigbird(1.81, 0.05, 2600, 1200, 0.1, kendwn, $main_amp, [1, 1, 2, 0.01]) bigbird(1.88, 0.06, 2600, 1200, 0.1, kendwn, $main_amp, [1, 1, 2, 0.01]) bigbird(1.97, 0.05, 4600, 100, 0.2, kentrill, $main_amp, [1, 1, 2, 0.1]) bigbird(2.05, 0.05, 2700, 800, 0.15, kenstart, $main_amp, [1, 1, 2, 0.01]) bigbird(2.12, 0.06, 2600, 1200, 0.1, kendwn, $main_amp, [1, 1, 2, 0.01]) bigbird(2.20, 0.05, 4600, 100, 0.2, kentrill, $main_amp, [1, 1, 2, 0.1]) bigbird(2.30, 0.05, 2800, 800, 0.15, kenstart, $main_amp, [1, 1, 2, 0.01]) bigbird(2.37, 0.06, 2700, 1200, 0.1, kendwn, $main_amp, [1, 1, 2, 0.01]) bigbird(2.45, 0.05, 4700, 100, 0.25, kentrill, $main_amp, [1, 1, 2, 0.1]) end end def rufous_sided_towhee(beg) towhee_one = [0.00, 0.10, 0.02, 0.05, 0.04, 0.15, 0.06, 0.05, 0.08, 0.20, 0.10, 0.04, 0.12, 0.25, 0.14, 0.03, 0.16, 0.30, 0.18, 0.02, 0.20, 0.35, 0.22, 0.01, 0.24, 0.40, 0.26, 0.00, 0.28, 0.45, 0.30, 0.00, 0.32, 0.50, 0.34, 0.00, 0.36, 0.50, 0.80, 1.00, 1.00, 0.0] towhee_two = [0.00, 0.00, 1.00, 1.0] towhee_three = [0.00, 1.00, 1.00, 0.0] one_bird(beg, 2.0, "rufous_sided_towhee") do bigbird(0.25, 0.13, 1400, 1100, 0.2, towhee_one, $main_amp, [1, 0.03, 2, 1, 3, 0.03]) bigbird(0.45, 0.13, 1400, 1100, 0.2, towhee_one, $main_amp, [1, 0.03, 2, 1, 3, 0.03]) bigbird(0.60, 0.13, 1400, 1100, 0.2, towhee_one, $main_amp, [1, 0.03, 2, 1, 3, 0.03]) bigbird(0.75, 0.10, 1400, 1100, 0.2, towhee_one, $main_amp, [1, 0.03, 2, 1, 3, 0.03]) bird(0.88, 0.01, 5100, 2000, 0.1, towhee_two, $main_amp) bird(0.895, 0.01, 5100, 1600, 0.1, towhee_two, $main_amp) bird(0.91, 0.01, 5100, 1000, 0.1, towhee_two, $main_amp) bird(0.93, 0.01, 3000, 1200, 0.1, towhee_three, $main_amp) bird(0.945, 0.01, 5100, 2000, 0.09, towhee_two, $main_amp) bird(0.96, 0.01, 5100, 1600, 0.09, towhee_two, $main_amp) bird(0.975, 0.01, 5100, 1000, 0.09, towhee_two, $main_amp) bird(0.995, 0.01, 3000, 1200, 0.09, towhee_three, $main_amp) bird(1.01, 0.01, 5100, 2000, 0.1, towhee_two, $main_amp) bird(1.025, 0.01, 5100, 1600, 0.1, towhee_two, $main_amp) bird(1.04, 0.01, 5100, 1000, 0.1, towhee_two, $main_amp) bird(1.06, 0.01, 3000, 1200, 0.1, towhee_three, $main_amp) bird(1.075, 0.01, 5100, 2000, 0.09, towhee_two, $main_amp) bird(1.09, 0.01, 5100, 1600, 0.09, towhee_two, $main_amp) bird(1.105, 0.01, 5100, 1000, 0.09, towhee_two, $main_amp) bird(1.125, 0.01, 3000, 1200, 0.09, towhee_three, $main_amp) bird(1.14, 0.01, 5100, 2000, 0.08, towhee_two, $main_amp) bird(1.155, 0.01, 5100, 1600, 0.08, towhee_two, $main_amp) bird(1.17, 0.01, 5100, 1000, 0.08, towhee_two, $main_amp) bird(1.19, 0.01, 3000, 1200, 0.08, towhee_three, $main_amp) bird(1.205, 0.01, 5100, 2000, 0.08, towhee_two, $main_amp) bird(1.220, 0.01, 5100, 1600, 0.08, towhee_two, $main_amp) bird(1.235, 0.01, 5100, 1000, 0.08, towhee_two, $main_amp) bird(1.255, 0.01, 3000, 1200, 0.08, towhee_three, $main_amp) bird(1.27, 0.01, 5100, 2000, 0.07, towhee_two, $main_amp) bird(1.285, 0.01, 5100, 1600, 0.07, towhee_two, $main_amp) bird(1.30, 0.01, 5100, 1000, 0.07, towhee_two, $main_amp) bird(1.32, 0.01, 3000, 1200, 0.07, towhee_three, $main_amp) bird(1.335, 0.01, 5100, 2000, 0.06, towhee_two, $main_amp) bird(1.350, 0.01, 5100, 1600, 0.06, towhee_two, $main_amp) bird(1.365, 0.01, 5100, 1000, 0.06, towhee_two, $main_amp) bird(1.385, 0.01, 3000, 1200, 0.06, towhee_three, $main_amp) bird(1.400, 0.01, 5100, 2000, 0.05, towhee_two, $main_amp) bird(1.415, 0.01, 5100, 1600, 0.05, towhee_two, $main_amp) bird(1.430, 0.01, 5100, 1000, 0.05, towhee_two, $main_amp) bird(1.45, 0.01, 3000, 1200, 0.05, towhee_three, $main_amp) bird(1.465, 0.01, 5100, 2000, 0.03, towhee_two, $main_amp) bird(1.480, 0.01, 5100, 1600, 0.03, towhee_two, $main_amp) bird(1.495, 0.01, 5100, 1000, 0.03, towhee_two, $main_amp) bird(1.515, 0.01, 3000, 1200, 0.03, towhee_three, $main_amp) end end def prothonotary_warbler(beg) pro_one = [0.00, 0.10, 0.20, 0.00, 1.00, 1.0] pro_two = [0.00, 0.00, 1.00, 1.0] pro_amp = [0.00, 0.00, 0.20, 1.00, 0.40, 0.50, 1.00, 0.0] one_bird(beg, 3.0, "prothonotary_warbler") do bird(0.76, 0.08, 3000, 3000, 0.05, pro_one, pro_amp) bird(0.85, 0.05, 4000, 2500, 0.06, pro_two, $bird_amp) bird(1.02, 0.09, 3000, 3000, 0.10, pro_one, pro_amp) bird(1.12, 0.05, 4000, 2500, 0.10, pro_two, $bird_amp) bird(1.26, 0.08, 3000, 3000, 0.15, pro_one, pro_amp) bird(1.35, 0.05, 4000, 2500, 0.16, pro_two, $bird_amp) bird(1.54, 0.08, 3000, 3000, 0.20, pro_one, pro_amp) bird(1.63, 0.05, 4000, 2500, 0.19, pro_two, $bird_amp) bird(1.80, 0.08, 3000, 3000, 0.20, pro_one, pro_amp) bird(1.89, 0.05, 4000, 2500, 0.16, pro_two, $bird_amp) bird(2.03, 0.08, 3000, 3000, 0.15, pro_one, pro_amp) bird(2.12, 0.05, 4000, 2500, 0.10, pro_two, $bird_amp) bird(2.30, 0.08, 3000, 3000, 0.10, pro_one, pro_amp) bird(2.39, 0.05, 4000, 2500, 0.06, pro_two, $bird_amp) end end def audubons_warbler(beg) w_up = [0.00, 0.00, 1.00, 1.0] w_down = [0.00, 1.00, 1.00, 0.0] w_end = [0.00, 0.00, 0.15, 1.00, 0.45, 0.90, 0.50, 0.00, 0.55, 1.00, 0.90, 0.90, 1.00, 0.10] w_updown = [0.00, 0.10, 0.50, 1.00, 1.00, 0.0] one_bird(beg, 3.0, "audubons_warbler") do bird(0.75, 0.04, 2400, 200, 0.05, w_down, $bird_amp) bird(0.83, 0.03, 3200, 200, 0.1, w_up, $bird_amp) bird(0.90, 0.04, 2500, 300, 0.15, w_up, $bird_amp) bird(0.97, 0.04, 2300, 600, 0.15, w_down, $bird_amp) bird(1.02, 0.03, 3500, 400, 0.20, w_up, $bird_amp) bird(1.06, 0.04, 2300, 1200, 0.10, w_up, $bird_amp) bird(1.13, 0.05, 2300, 1200, 0.15, w_down, $bird_amp) bird(1.22, 0.02, 3200, 800, 0.25, w_up, $bird_amp) bird(1.25, 0.08, 2400, 600, 0.20, w_updown, $bird_amp) bird(1.35, 0.02, 2200, 400, 0.10, w_up, $bird_amp) bird(1.38, 0.07, 2400, 1400, 0.15, w_down, $bird_amp) bird(1.47, 0.03, 3000, 800, 0.20, w_up, $bird_amp) bird(1.50, 0.03, 2500, 400, 0.10, w_updown, $bird_amp) bird(1.55, 0.01, 2300, 100, 0.05, w_up, $bird_amp) bird(1.56, 0.06, 2200, 1400, 0.15, w_down, $bird_amp) bird(1.65, 0.03, 3100, 800, 0.10, w_up, $bird_amp) bird(1.70, 0.07, 2800, 800, 0.15, w_updown, $bird_amp) bird(1.79, 0.06, 2400, 1000, 0.10, w_down, $bird_amp) bird(1.86, 0.14, 3100, 900, 0.25, w_end, $bird_amp) bird(2.02, 0.12, 3200, 800, 0.20, w_end, $bird_amp) end end def lark_bunting(beg) b_down = [0.00, 1.00, 1.00, 0.0] b_up = [0.00, 0.00, 1.00, 1.0] b_trill_one = [0.00, 0.00, 0.06, 0.80, 0.12, 0.00, 0.18, 0.85, 0.24, 0.05, 0.36, 0.90, 0.42, 0.10, 0.48, 0.95, 0.54, 0.20, 0.60, 1.00, 0.66, 0.20, 0.72, 1.00, 0.78, 0.20, 0.84, 1.00, 0.90, 0.20, 1.00, 1.0] b_trill_two = [0.00, 0.00, 0.05, 0.80, 0.10, 0.00, 0.15, 0.85, 0.20, 0.00, 0.25, 0.90, 0.30, 0.00, 0.35, 0.95, 0.40, 0.00, 0.45, 1.00, 0.50, 0.00, 0.55, 1.00, 0.60, 0.00, 0.65, 1.00, 0.70, 0.00, 0.75, 1.00, 0.80, 0.00, 0.85, 1.00, 0.90, 0.00, 0.95, 1.00, 1.00, 0.0] one_bird(beg, 3.0, "lark_bunting") do bird(0.1, 0.03, 1800, 100, 0.1, b_up, $bird_amp) bird(0.2, 0.12, 3700, 400, 0.2, b_up, $bird_amp) bird(0.4, 0.03, 4100, 500, 0.15, b_down, $bird_amp) bird(0.45, 0.05, 2000, 400, 0.20, b_down, $bird_amp) bird(0.51, 0.03, 1800, 100, 0.1, b_up, $bird_amp) bird(0.6, 0.03, 4100, 500, 0.15, b_down, $bird_amp) bird(0.65, 0.05, 2000, 400, 0.20, b_down, $bird_amp) bird(0.71, 0.03, 1800, 100, 0.1, b_up, $bird_amp) bird(0.8, 0.03, 4100, 500, 0.15, b_down, $bird_amp) bird(0.85, 0.05, 2000, 400, 0.20, b_down, $bird_amp) bird(0.91, 0.03, 1800, 100, 0.1, b_up, $bird_amp) bird(1.0, 0.03, 4100, 500, 0.15, b_down, $bird_amp) bird(1.05, 0.05, 2000, 400, 0.20, b_down, $bird_amp) bird(1.11, 0.03, 1800, 100, 0.1, b_up, $bird_amp) bird(1.2, 0.03, 4100, 500, 0.15, b_down, $bird_amp) bird(1.25, 0.05, 2000, 400, 0.20, b_down, $bird_amp) bird(1.31, 0.03, 1800, 100, 0.1, b_up, $bird_amp) bird(1.4, 0.03, 4100, 500, 0.15, b_down, $bird_amp) bird(1.45, 0.05, 2000, 400, 0.20, b_down, $bird_amp) bird(1.51, 0.03, 1800, 100, 0.1, b_up, $bird_amp) bird(1.6, 0.03, 4100, 500, 0.15, b_down, $bird_amp) bird(1.65, 0.05, 2000, 400, 0.20, b_down, $bird_amp) bird(1.71, 0.03, 1800, 100, 0.1, b_up, $bird_amp) bird(1.77, 0.23, 6000, 600, 0.15, b_trill_one, $bird_amp) bird(2.005, 0.28, 6000, 600, 0.15, b_trill_two, $bird_amp) end end def eastern_bluebird(beg) blue_one = [0.00, 0.00, 1.00, 1.0] blue_two = [0.00, 1.00, 1.00, 0.0] blue_three = [0.00, 0.60, 0.10, 1.00, 0.20, 0.00, 0.25, 1.00, 0.30, 0.00, 0.35, 1.00, 0.40, 0.00, 0.45, 1.00, 0.50, 0.00, 0.75, 1.00, 1.00, 0.0] blue_four = [0.00, 0.00, 0.50, 1.00, 1.00, 0.0] blue_five = [0.00, 0.50, 0.10, 1.00, 0.20, 0.00, 0.35, 1.00, 0.50, 0.00, 0.65, 1.00, 0.80, 0.00, 0.95, 1.00, 1.00, 0.50] one_bird(beg, 3.0, "eastern_bluebird") do bird(0.75, 0.02, 2000, 1600, 0.1, blue_one, $bird_amp) bird(0.80, 0.02, 2000, 1600, 0.1, blue_one, $bird_amp) bird(0.86, 0.02, 2000, 1600, 0.1, blue_one, $bird_amp) bird(1.00, 0.13, 2000, 1400, 0.2, blue_two, $bird_amp) bird(1.20, 0.24, 2000, 800, 0.2, blue_three, $bird_amp) bird(1.68, 0.03, 2200, 400, 0.1, blue_one, $bird_amp) bird(1.72, 0.10, 1950, 100, 0.15, blue_four, $bird_amp) bird(1.96, 0.15, 2000, 600, 0.20, blue_five, $bird_amp) end end def chuck_wills_widow(beg) wid_down = [0.00, 1.00, 1.00, 0.0] wid_one = [0.00, 0.00, 0.10, 0.10, 0.25, 1.00, 0.50, 0.30, 0.80, 0.70, 1.00, 0.0] wid_two = [0.00, 0.20, 0.30, 1.00, 0.50, 0.30, 0.60, 0.70, 0.90, 0.10, 1.00, 0.0] one_bird(beg, 1.0, "chuck_wills_widow") do bird(0.05, 0.03, 1000, 800, 0.1, wid_down, $bird_amp) bird(0.32, 0.20, 1000, 1000, 0.2, wid_one, $bird_amp) bird(0.56, 0.29, 900, 1100, 0.2, wid_two, $bird_amp) end end def blue_gray_gnatcatcher(beg) gskw1 = [0.00, 0.00, 0.15, 1.00, 0.75, 0.80, 0.90, 1.00, 1.00, 0.70] gskw2 = [0.00, 0.00, 0.25, 1.00, 0.75, 0.70, 1.00, 0.0] one_bird(beg, 3.0, "blue_gray_gnatcatcher") do bigbird(0.5, 0.20, 4000, 1000, 0.2, gskw1, $bird_amp, [1, 0.4, 2, 1, 3, 0.1]) bigbird(0.8, 0.13, 4000, 800, 0.2, gskw2, $bird_amp, [1, 0.4, 2, 1, 3, 0.2]) bigbird(1.4, 0.25, 4000, 800, 0.2, gskw2, $bird_amp, [1, 0.4, 2, 1, 3, 0.3]) bigbird(1.80, 0.17, 4000, 900, 0.2, gskw1, $bird_amp, [1, 0.4, 2, 1, 3, 0.3]) bigbird(2.00, 0.17, 4000, 700, 0.2, gskw1, $bird_amp, [1, 0.4, 2, 1, 3, 0.3]) bigbird(2.20, 0.17, 4000, 800, 0.2, gskw2, $bird_amp, [1, 0.4, 2, 1, 3, 0.3]) end end def black_throated_sparrow(beg) black_up = [0.00, 0.00, 1.00, 1.0] black_down = [0.00, 1.00, 1.00, 0.0] black_down_amp = [0.00, 0.00, 0.75, 1.00, 1.00, 0.0] black_trill = [0.00, 0.00, 0.03, 0.70, 0.06, 0.00, 0.09, 0.75, 0.12, 0.00, 0.15, 0.80, 0.18, 0.05, 0.21, 0.85, 0.24, 0.10, 0.27, 0.90, 0.30, 0.10, 0.33, 1.00, 0.36, 0.10, 0.39, 1.00, 0.42, 0.10, 0.45, 1.00, 0.48, 0.10, 0.51, 1.00, 0.54, 0.10, 0.57, 1.00, 0.60, 0.10, 0.63, 1.00, 0.66, 0.10, 0.69, 1.00, 0.72, 0.10, 0.75, 1.00, 0.78, 0.10, 0.81, 1.00, 0.84, 0.10, 0.87, 1.00, 0.90, 0.00, 0.93, 0.95, 0.96, 0.00, 1.00, 0.90] black_up_down = [0.00, 0.00, 0.50, 1.00, 1.00, 0.20] black_amp = [0.00, 0.00, 0.50, 1.00, 1.00, 0.0] one_bird(beg, 3.0, "black_throated_sparrow") do bird(0.8, 0.02, 2200, 1000, 0.1, black_down, $bird_amp) bird(0.83, 0.01, 3000, 200, 0.05, black_up, $bird_amp) bird(0.96, 0.02, 5800, 500, 0.05, black_up, $bird_amp) bird(1.00, 0.02, 4000, 200, 0.05, black_up, $bird_amp) bird(1.04, 0.10, 2100, 1700, 0.15, black_down, black_down_amp) bird(1.15, 0.05, 5700, 400, 0.25, black_up, $bird_amp) bird(1.25, 0.25, 2000, 900, 0.2, black_trill, $bird_amp) bird(1.52, 0.05, 5600, 400, 0.15, black_up_down, $bird_amp) bird(1.6, 0.04, 3900, 1100, 0.15, black_up, $bird_amp) bird(1.66, 0.01, 1900, 100, 0.10, black_up, black_amp) bird(1.69, 0.01, 3600, 300, 0.10, black_up, black_amp) bird(1.71, 0.03, 3900, 1000, 0.15, black_up, black_amp) bird(1.74, 0.02, 5000, 100, 0.20, black_up, black_amp) bird(1.76, 0.01, 1900, 100, 0.10, black_up, black_amp) bird(1.78, 0.01, 3600, 300, 0.10, black_up, black_amp) bird(1.80, 0.03, 3900, 1000, 0.15, black_up, black_amp) bird(1.83, 0.02, 5000, 100, 0.20, black_up, black_amp) bird(1.85, 0.01, 1900, 100, 0.10, black_up, black_amp) bird(1.87, 0.01, 3600, 300, 0.10, black_up, black_amp) bird(1.89, 0.03, 3900, 1000, 0.15, black_up, black_amp) bird(1.92, 0.02, 5000, 100, 0.20, black_up, black_amp) bird(1.94, 0.01, 1900, 100, 0.10, black_up, black_amp) bird(1.96, 0.01, 3600, 300, 0.10, black_up, black_amp) bird(1.98, 0.03, 3900, 1000, 0.15, black_up, black_amp) bird(2.01, 0.02, 5000, 100, 0.20, black_up, black_amp) bird(2.03, 0.01, 1900, 100, 0.10, black_up, black_amp) bird(2.05, 0.01, 3600, 300, 0.10, black_up, black_amp) bird(2.07, 0.03, 3900, 1000, 0.15, black_up, black_amp) bird(2.10, 0.02, 5000, 100, 0.20, black_up, black_amp) bird(2.13, 0.01, 1900, 100, 0.10, black_up, black_amp) bird(2.16, 0.03, 3800, 300, 0.1, black_up, $bird_amp) end end def black_chinned_sparrow(beg) chin_up = [0.00, 0.00, 1.00, 1.0] chin_up2 = [0.00, 0.00, 0.30, 0.20, 1.00, 1.0] one_bird(beg, 3.0, "black_chinned_sparrow") do bird(0.6, 0.2, 4200, 100, 0.1, chin_up, $bird_amp) bird(1.0, 0.09, 3800, 2000, 0.1, chin_up2, $bird_amp) bird(1.25, 0.08, 3900, 1700, 0.12, chin_up2, $bird_amp) bird(1.40, 0.08, 3600, 2300, 0.13, chin_up, $bird_amp) bird(1.50, 0.11, 3100, 2800, 0.14, chin_up, $bird_amp) bird(1.65, 0.07, 2900, 2700, 0.15, chin_up, $bird_amp) bird(1.74, 0.07, 2900, 2700, 0.15, chin_up, $bird_amp) bird(1.82, 0.07, 3000, 2300, 0.13, chin_up, $bird_amp) bird(1.89, 0.07, 3200, 2000, 0.10, chin_up, $bird_amp) bird(1.97, 0.05, 3200, 1500, 0.10, chin_up, $bird_amp) bird(2.04, 0.04, 3400, 1000, 0.07, chin_up, $bird_amp) bird(2.10, 0.03, 3600, 700, 0.05, chin_up, $bird_amp) bird(2.15, 0.03, 3800, 300, 0.05, chin_up, $bird_amp) bird(2.19, 0.02, 3900, 100, 0.03, chin_up, $bird_amp) bird(2.22, 0.01, 3900, 100, 0.01, chin_up, $bird_amp) bird(2.24, 0.01, 3900, 100, 0.01, chin_up, $bird_amp) end end def various_gull_cries_from_end_of_colony_5(beg) gullstart = [0, 0, 10, 1, 20, 0.5000, 40, 0.6000, 60, 0.5000, 100, 0] gullmiddle = [0, 0, 10, 1, 30, 0.5000, 80, 0.5000, 100, 0] gullend = [0, 0, 5, 1, 10, 0.5000, 90, 0.4000, 100, 0] unknown = [1, 0.1, 2, 1, 3, 0.1, 4, 0.01, 5, 0.09, 6, 0.01, 7, 0.01] one_bird(beg, 10.0, "gulls") do bigbird(0.250, 0.80, 1180, 1180, 0.08, gullend, $bird_amp, unknown) bigbird(1.500, 0.90, 1180, 1180, 0.07, gullend, $bird_amp, unknown) bigbird(2.750, 1.00, 1050, 1050, 0.08, gullend, $bird_amp, unknown) bigbird(4.800, 0.05, 1180, 1180, 0.06, gullstart, $bird_amp, unknown) bigbird(4.950, 0.10, 1180, 1180, 0.08, gullstart, $bird_amp, unknown) bigbird(5.150, 0.10, 1180, 1180, 0.09, gullstart, $bird_amp, unknown) bigbird(5.350, 0.10, 1180, 1180, 0.1, gullmiddle, $bird_amp, unknown) bigbird(5.450, 0.40, 1050, 1050, 0.1, gullend, $bird_amp, unknown) bigbird(6.250, 0.80, 1050, 1050, 0.1, gullend, $bird_amp, unknown) bigbird(7.450, 1.80, 1050, 1050, 0.1, gullend, $bird_amp, unknown) end end def make_birds # atime = Time.new $out_file = new_sound("test.snd") set_squelch_update(true, $out_file, 0) orchard_oriole(0) cassins_kingbird(3) chipping_sparrow(6) bobwhite(9) western_meadowlark(12) scissor_tailed_flycatcher(15) great_horned_owl(18) black_throated_gray_warbler(21) yellow_warbler(24) black_necked_stilt(27) chestnut_sided_warbler(30) grasshopper_sparrow(33) swamp_sparrow(36) golden_crowned_sparrow(39) indigo_bunting(42) hooded_warbler(45) american_widgeon(48) louisiana_waterthrush(51) robin(54) solitary_vireo(57) pigeon_hawk(61) cerulean_warbler(64) nashville_warbler(67) eastern_phoebe(70) painted_bunting(73) western_flycatcher(76) bachmans_sparrow(79) cedar_waxwing(82) bairds_sparrow(85) kentucky_warbler(88) rufous_sided_towhee(91) prothonotary_warbler(94) audubons_warbler(97) lark_bunting(100) eastern_bluebird(103) chuck_wills_widow(106) blue_gray_gnatcatcher(109) black_throated_sparrow(112) black_chinned_sparrow(115) set_squelch_update(false, $out_file, 0) various_gull_cries_from_end_of_colony_5(118) $out_data = false # btime = Time.new # $stderr.write sprintf("time: %f\n", btime - atime) end snd-16.1/clm-strings.h0000644000076400007640000004133612474702602012761 0ustar bilbil#ifndef CLM_STRINGS_H #define CLM_STRINGS_H /* there's some inconsistency about the mus- prefix: mus-interp-* but *-window etc */ #define S_all_pass "all-pass" #define S_is_all_pass "all-pass?" #define S_all_pass_bank "all-pass-bank" #define S_is_all_pass_bank "all-pass-bank?" #define S_amplitude_modulate "amplitude-modulate" #define S_array_interp "array-interp" #define S_asymmetric_fm "asymmetric-fm" #define S_is_asymmetric_fm "asymmetric-fm?" #define S_autocorrelate "autocorrelate" #define S_bartlett_window "bartlett-window" #define S_bartlett_hann_window "bartlett-hann-window" #define S_blackman2_window "blackman2-window" #define S_blackman3_window "blackman3-window" #define S_blackman4_window "blackman4-window" #define S_blackman5_window "blackman5-window" #define S_blackman6_window "blackman6-window" #define S_blackman7_window "blackman7-window" #define S_blackman8_window "blackman8-window" #define S_blackman9_window "blackman9-window" #define S_blackman10_window "blackman10-window" #define S_bohman_window "bohman-window" #define S_cauchy_window "cauchy-window" #define S_clear_sincs "clear-sincs" #define S_clm_default_frequency "clm-default-frequency" #define S_clm_table_size "clm-table-size" #define S_comb "comb" #define S_is_comb "comb?" #define S_comb_bank "comb-bank" #define S_is_comb_bank "comb-bank?" #define S_connes_window "connes-window" #define S_continue_sample_to_file "continue-sample->file" #define S_contrast_enhancement "contrast-enhancement" #define S_convolution "convolution" #define S_convolve "convolve" #define S_convolve_files "convolve-files" #define S_is_convolve "convolve?" #define S_correlate "correlate" #define S_db_to_linear "db->linear" #define S_degrees_to_radians "degrees->radians" #define S_delay "delay" #define S_delay_tick "delay-tick" #define S_is_delay "delay?" #define S_dolph_chebyshev_window "dolph-chebyshev-window" #define S_dot_product "dot-product" #define S_dpss_window "dpss-window" #define S_env "env" #define S_env_any "env-any" #define S_env_interp "env-interp" #define S_is_env "env?" #define S_even_multiple "even-multiple" #define S_even_weight "even-weight" #define S_exponential_window "exponential-window" #define S_file_to_sample "file->sample" #define S_is_file_to_sample "file->sample?" #define S_filter "filter" #define S_is_filter "filter?" #define S_filtered_comb "filtered-comb" #define S_is_filtered_comb "filtered-comb?" #define S_filtered_comb_bank "filtered-comb-bank" #define S_is_filtered_comb_bank "filtered-comb-bank?" #define S_fir_filter "fir-filter" #define S_is_fir_filter "fir-filter?" #define S_flat_top_window "flat-top-window" #define S_firmant "firmant" #define S_is_firmant "firmant?" #define S_formant "formant" #define S_formant_bank "formant-bank" #define S_is_formant_bank "formant-bank?" #define S_is_formant "formant?" #define S_gaussian_window "gaussian-window" #define S_granulate "granulate" #define S_is_granulate "granulate?" #define S_hamming_window "hamming-window" #define S_hann_window "hann-window" #define S_hann_poisson_window "hann-poisson-window" #define S_hz_to_radians "hz->radians" #define S_iir_filter "iir-filter" #define S_is_iir_filter "iir-filter?" #define S_in_any "in-any" #define S_ina "ina" #define S_inb "inb" #define S_kaiser_window "kaiser-window" #define S_linear_to_db "linear->db" #define S_locsig "locsig" #define S_is_locsig "locsig?" #define S_locsig_ref "locsig-ref" #define S_locsig_reverb_ref "locsig-reverb-ref" #define S_locsig_reverb_set "locsig-reverb-set!" #define S_locsig_set "locsig-set!" #define S_locsig_type "locsig-type" #define S_make_all_pass "make-all-pass" #define S_make_all_pass_bank "make-all-pass-bank" #define S_make_asymmetric_fm "make-asymmetric-fm" #define S_make_comb "make-comb" #define S_make_comb_bank "make-comb-bank" #define S_make_convolve "make-convolve" #define S_make_delay "make-delay" #define S_make_env "make-env" #define S_make_fft_window "make-fft-window" #define S_make_file_to_sample "make-file->sample" #define S_make_filter "make-filter" #define S_make_filtered_comb "make-filtered-comb" #define S_make_filtered_comb_bank "make-filtered-comb-bank" #define S_make_fir_coeffs "make-fir-coeffs" #define S_make_fir_filter "make-fir-filter" #define S_make_firmant "make-firmant" #define S_make_formant "make-formant" #define S_make_formant_bank "make-formant-bank" #define S_make_granulate "make-granulate" #define S_make_iir_filter "make-iir-filter" #define S_make_locsig "make-locsig" #define S_make_move_sound "make-move-sound" #define S_make_moving_average "make-moving-average" #define S_make_moving_max "make-moving-max" #define S_make_moving_norm "make-moving-norm" #define S_make_ncos "make-ncos" #define S_make_notch "make-notch" #define S_make_nrxycos "make-nrxycos" #define S_make_nrxysin "make-nrxysin" #define S_make_nsin "make-nsin" #define S_make_one_pole "make-one-pole" #define S_make_one_pole_all_pass "make-one-pole-all-pass" #define S_make_one_zero "make-one-zero" #define S_make_oscil "make-oscil" #define S_make_oscil_bank "make-oscil-bank" #define S_make_phase_vocoder "make-phase-vocoder" #define S_make_polyshape "make-polyshape" #define S_make_polywave "make-polywave" #define S_make_pulse_train "make-pulse-train" #define S_make_pulsed_env "make-pulsed-env" #define S_make_rand "make-rand" #define S_make_rand_interp "make-rand-interp" #define S_make_readin "make-readin" #define S_make_rxykcos "make-rxyk!cos" #define S_make_rxyksin "make-rxyk!sin" #define S_make_sample_to_file "make-sample->file" #define S_make_sawtooth_wave "make-sawtooth-wave" #define S_make_square_wave "make-square-wave" #define S_make_src "make-src" #define S_make_ssb_am "make-ssb-am" #define S_make_table_lookup "make-table-lookup" #define S_make_triangle_wave "make-triangle-wave" #define S_make_two_pole "make-two-pole" #define S_make_two_zero "make-two-zero" #define S_make_wave_train "make-wave-train" #define S_mlt_sine_window "mlt-sine-window" #define S_move_locsig "move-locsig" #define S_move_sound "move-sound" #define S_is_move_sound "move-sound?" #define S_moving_average "moving-average" #define S_is_moving_average "moving-average?" #define S_moving_max "moving-max" #define S_is_moving_max "moving-max?" #define S_moving_norm "moving-norm" #define S_is_moving_norm "moving-norm?" #define S_mus_apply "mus-apply" #define S_mus_array_print_length "mus-array-print-length" #define S_mus_channel "mus-channel" #define S_mus_channels "mus-channels" #define S_mus_chebyshev_first_kind "mus-chebyshev-first-kind" #define S_mus_chebyshev_second_kind "mus-chebyshev-second-kind" #define S_mus_chebyshev_both_kinds "mus-chebyshev-both-kinds" #define S_mus_chebyshev_t_sum "mus-chebyshev-t-sum" #define S_mus_chebyshev_tu_sum "mus-chebyshev-tu-sum" #define S_mus_chebyshev_u_sum "mus-chebyshev-u-sum" #define S_mus_close "mus-close" #define S_mus_copy "mus-copy" #define S_mus_data "mus-data" #define S_mus_describe "mus-describe" #define S_mus_feedback "mus-feedback" #define S_mus_feedforward "mus-feedforward" #define S_mus_fft "mus-fft" #define S_mus_file_buffer_size "mus-file-buffer-size" #define S_mus_file_name "mus-file-name" #define S_mus_float_equal_fudge_factor "mus-float-equal-fudge-factor" #define S_mus_frequency "mus-frequency" #define S_is_mus_generator "mus-generator?" #define S_mus_hop "mus-hop" #define S_mus_increment "mus-increment" #define S_is_mus_input "mus-input?" #define S_mus_interpolate "mus-interpolate" #define S_mus_interp_all_pass "mus-interp-all-pass" #define S_mus_interp_bezier "mus-interp-bezier" #define S_mus_interp_hermite "mus-interp-hermite" #define S_mus_interp_lagrange "mus-interp-lagrange" #define S_mus_interp_linear "mus-interp-linear" #define S_mus_interp_none "mus-interp-none" #define S_mus_interp_sinusoidal "mus-interp-sinusoidal" #define S_mus_interp_type "mus-interp-type" #define S_mus_length "mus-length" #define S_mus_location "mus-location" #define S_mus_name "mus-name" #define S_mus_offset "mus-offset" #define S_mus_order "mus-order" #define S_is_mus_output "mus-output?" #define S_mus_phase "mus-phase" #define S_mus_ramp "mus-ramp" #define S_mus_rand_seed "mus-rand-seed" #define S_mus_random "mus-random" #define S_mus_reset "mus-reset" #define S_mus_run "mus-run" #define S_mus_scaler "mus-scaler" #define S_mus_set_formant_frequency "mus-set-formant-frequency" #define S_mus_set_formant_radius_and_frequency "mus-set-formant-radius-and-frequency" #define S_mus_srate "mus-srate" #define S_mus_type "mus-type" #define S_mus_width "mus-width" #define S_mus_xcoeff "mus-xcoeff" #define S_mus_xcoeffs "mus-xcoeffs" #define S_mus_ycoeff "mus-ycoeff" #define S_mus_ycoeffs "mus-ycoeffs" #define S_ncos "ncos" #define S_is_ncos "ncos?" #define S_normalize_partials "normalize-partials" #define S_notch "notch" #define S_is_notch "notch?" #define S_nrxycos "nrxycos" #define S_is_nrxycos "nrxycos?" #define S_nrxysin "nrxysin" #define S_is_nrxysin "nrxysin?" #define S_nsin "nsin" #define S_is_nsin "nsin?" #define S_odd_multiple "odd-multiple" #define S_odd_weight "odd-weight" #define S_one_pole "one-pole" #define S_is_one_pole "one-pole?" #define S_one_pole_all_pass "one-pole-all-pass" #define S_is_one_pole_all_pass "one-pole-all-pass?" #define S_one_zero "one-zero" #define S_is_one_zero "one-zero?" #define S_oscil "oscil" #define S_is_oscil "oscil?" #define S_oscil_bank "oscil-bank" #define S_is_oscil_bank "oscil-bank?" #define S_out_any "out-any" #define S_outa "outa" #define S_outb "outb" #define S_outc "outc" #define S_outd "outd" #define S_papoulis_window "papoulis-window" #define S_partials_to_polynomial "partials->polynomial" #define S_partials_to_wave "partials->wave" #define S_parzen_window "parzen-window" #define S_phase_vocoder "phase-vocoder" #define S_is_phase_vocoder "phase-vocoder?" #define S_phase_partials_to_wave "phase-partials->wave" #define S_poisson_window "poisson-window" #define S_polar_to_rectangular "polar->rectangular" #define S_polynomial "polynomial" #define S_polyshape "polyshape" #define S_is_polyshape "polyshape?" #define S_polywave "polywave" #define S_is_polywave "polywave?" #define S_pulse_train "pulse-train" #define S_is_pulse_train "pulse-train?" #define S_phase_vocoder_amp_increments "phase-vocoder-amp-increments" #define S_phase_vocoder_amps "phase-vocoder-amps" #define S_phase_vocoder_freqs "phase-vocoder-freqs" #define S_phase_vocoder_phase_increments "phase-vocoder-phase-increments" #define S_phase_vocoder_phases "phase-vocoder-phases" #define S_pulsed_env "pulsed-env" #define S_is_pulsed_env "pulsed-env?" #define S_radians_to_degrees "radians->degrees" #define S_radians_to_hz "radians->hz" #define S_rand "rand" #define S_rand_interp "rand-interp" #define S_is_rand_interp "rand-interp?" #define S_is_rand "rand?" #define S_readin "readin" #define S_is_readin "readin?" #define S_rectangular_to_magnitudes "rectangular->magnitudes" #define S_rectangular_to_polar "rectangular->polar" #define S_rectangular_window "rectangular-window" #define S_riemann_window "riemann-window" #define S_ring_modulate "ring-modulate" #define S_rv2_window "rv2-window" #define S_rv3_window "rv3-window" #define S_rv4_window "rv4-window" #define S_rxykcos "rxyk!cos" #define S_is_rxykcos "rxyk!cos?" #define S_rxyksin "rxyk!sin" #define S_is_rxyksin "rxyk!sin?" #define S_samaraki_window "samaraki-window" #define S_sample_to_file "sample->file" #define S_sample_to_file_add "sample->file+" #define S_is_sample_to_file "sample->file?" #define S_samples_to_seconds "samples->seconds" #define S_sawtooth_wave "sawtooth-wave" #define S_is_sawtooth_wave "sawtooth-wave?" #define S_seconds_to_samples "seconds->samples" #define S_sinc_window "sinc-window" #define S_spectrum "spectrum" #define S_square_wave "square-wave" #define S_is_square_wave "square-wave?" #define S_src "src" #define S_is_src "src?" #define S_ssb_am "ssb-am" #define S_is_ssb_am "ssb-am?" #define S_table_lookup "table-lookup" #define S_is_table_lookup "table-lookup?" #define S_tap "tap" #define S_is_tap "tap?" #define S_triangle_wave "triangle-wave" #define S_is_triangle_wave "triangle-wave?" #define S_tukey_window "tukey-window" #define S_two_pole "two-pole" #define S_is_two_pole "two-pole?" #define S_two_zero "two-zero" #define S_is_two_zero "two-zero?" #define S_ultraspherical_window "ultraspherical-window" #define S_wave_train "wave-train" #define S_is_wave_train "wave-train?" #define S_welch_window "welch-window" #define S_continue_frample_to_file "continue-frample->file" #define S_file_to_frample "file->frample" #define S_is_file_to_frample "file->frample?" #define S_frample_to_file "frample->file" #define S_is_frample_to_file "frample->file?" #define S_frample_to_frample "frample->frample" #define S_make_file_to_frample "make-file->frample" #define S_make_frample_to_file "make-frample->file" #define S_mus_file_mix "mus-file-mix" #define S_mus_file_mix_with_envs "mus-file-mix-with-envs" #endif snd-16.1/effects.fs0000644000076400007640000041571412327441227012324 0ustar bilbil\ effects.fs -- *effects*.scm -> effects.fs \ Translator/Author: Michael Scholz \ Created: 05/10/16 23:04:30 \ Changed: 14/04/28 03:52:17 \ \ @(#)effects.fs 1.56 4/28/14 \ General (nogui/motif/gtk) \ \ effects-squelch-channel ( amount gate-size :optional snd chn -- ) \ effects-echo ( is dtime eamt :optional beg dur snd chn -- ) \ effects-flecho ( scl secs ismps :optional beg dur snd chn -- ) \ effects-zecho ( scl secs freq amp ismps :optional ... -- ) \ effects-bbp ( freq bw :optional beg dur snd chn -- res ) \ effects-bbr ( freq bw :optional beg dur snd chn -- res ) \ effects-bhp ( freq :optional beg dur snd chn -- res ) \ effects-blp ( freq :optional beg dur snd chn -- res ) \ effects-comb-filter ( scl size :optional beg dur snd chn -- res ) \ effects-comb-chord ( scl si amp :optional beg dur snd chn -- res ) \ effects-moog ( freq Q :optional beg dur snd chn -- res ) \ moog ( freq Q -- prc; inval self -- res ) \ effects-am ( freq en :optional beg dur snd chn -- res ) \ effects-rm ( freq en :optional beg dur snd chn -- res ) \ effects-jc-reverb ( samps volume -- prc; inval self -- res ) \ effects-jc-reverb-1 ( volume :optional beg dur snd chn -- res ) \ effects-cnv ( snd0 amp snd chn -- res ) \ effects-position-sound ( mono-snd pos :optional snd chn -- res ) \ effects-place-sound ( mono-snd stereo-snd pan-env -- res ) \ effects-flange ( at spd ti :optional beg dur snd chn -- res ) \ effects-cross-synthesis ( snd amp fftsize r -- prc; inval self -- res ) \ effects-cross-synthesis-1 ( csnd amp fftsize r :optional beg dur ... -- ) \ effects-fp ( sf amp frq :optional beg dur snd chn -- vct ) \ effects-hello-dentist ( freq amp :optional beg dur snd chn -- res ) \ effects-remove-clicks ( :optional snd chn -- res ) \ effects-remove-dc ( :optional snd chn -- res ) \ effects-compand ( :optional snd chn -- res ) \ \ Motif/Gtk specific \ \ Requires --with-motif|gtk \ \ Tested with Snd 14.x \ Fth 1.3.x \ Motif 2.3.3 X11R6 \ \ make-menu ( name parent -- gen ) \ menu-entry ( gen prc disp-prc -- ) \ make-main-menu ( name -- widget ) \ add-to-effects-menu ( name prc -- ) \ \ make-gain-dialog ( name -- pc1 pc2; child self -- prc; self -- ) \ make-normalize-dialog ( name -- pc1 pc2; child self -- prc; self -- ) \ make-gate-dialog ( name -- pc1 pc2; child self -- prc; self -- ) \ \ make-echo-dialog ( name -- pc1 pc2; child self -- prc; self -- ) \ make-flecho-dialog ( name -- pc1 pc2; child self -- prc; self -- ) \ make-zecho-dialog ( name -- pc1 pc2; child self -- prc; self -- ) \ \ make-band-pass-dialog ( name -- pc1 pc2; child self -- prc; self -- ) \ make-notch-dialog ( name -- pc1 pc2; child self -- prc; self -- ) \ make-high-pass-dialog ( name -- pc1 pc2; child self -- prc; self -- ) \ make-low-pass-dialog ( name -- pc1 pc2; child self -- prc; self -- ) \ make-comb-dialog ( name -- pc1 pc2; child self -- prc; self -- ) \ make-comb-chord-dialog ( name -- pc1 pc2; child self -- prc; self -- ) \ make-moog-dialog ( name -- pc1 pc2; child self -- prc; self -- ) \ \ make-adsat-dialog ( name -- pc1 pc2; child self -- prc; self -- ) \ make-src-dialog ( name -- pc1 pc2; child self -- prc; self -- ) \ make-expsrc-dialog ( name -- pc1 pc2; child self -- prc; self -- ) \ make-src-timevar-dialog ( name -- pc1 pc2; child self -- prc; self -- ) \ \ make-am-effect-dialog ( name -- pc1 pc2; child self -- prc; self -- ) \ make-rm-effect-dialog ( name -- pc1 pc2; child self -- prc; self -- ) \ \ make-reverb-dialog ( name -- pc1 pc2; child self -- prc; self -- ) \ make-jc-reverb-dialog ( name -- pc1 pc2; child self -- prc; self -- ) \ make-convolve-dialog ( name -- pc1 pc2; child self -- prc; self -- ) \ \ make-place-sound-dialog ( name -- pc1 pc2; child self -- prc; self -- ) \ make-silence-dialog ( name -- pc1 pc2; child self -- prc; self -- ) \ make-contrast-dialog ( name -- pc1 pc2; child self -- prc; self -- ) \ make-cross-synth-dialog ( name -- pc1 pc2; child self -- prc; self -- ) \ make-flange-dialog ( name -- pc1 pc2; child self -- prc; self -- ) \ make-random-phase-dialog ( name -- pc1 pc2; child self -- prc; self -- ) \ make-robotize-dialog ( name -- pc1 pc2; child self -- prc; self -- ) \ make-rubber-dialog ( name -- pc1 pc2; child self -- prc; self -- ) \ make-wobble-dialog ( name -- pc1 pc2; child self -- prc; self -- ) \ \ make-effects-menu ( -- ) \ init-effects-menu ( -- ) require clm require examp require env require dsp -1 value effects-menu \ for prefs #f value use-combo-box-for-fft-size \ effects-squelch-channel ( amount gate-size :optional snd chn -- ) hide : squelch-cb { f0 f1 amount -- prc; y self -- val } 1 proc-create amount , f1 , f0 , ( prc ) does> { y self -- val } self @ { amp } self 1 cells + @ { f1 } self 2 cells + @ { f0 } f1 f0 y y f* moving-average amp f< if 0.0 else 1.0 then moving-average y f* ; set-current : effects-squelch-channel <{ amount gate-size :optional snd #f chn #f -- val }> :size gate-size make-moving-average { f0 } :size gate-size :initial-element 1.0 make-moving-average { f1 } "%s %s %s" #( amount gate-size get-func-name ) string-format { origin } f0 f1 amount squelch-cb 0 #f snd chn #f origin map-channel ; previous \ effects-echo ( in-samps delay-time echo-amount :optional beg dur snd chn -- ) \ effects-flecho ( scl secs input-samps :optional beg dur snd chn -- ) \ effects-zecho ( scl secs freq amp input-samps :optional beg dur snd chn -- ) hide : effects-echo-cb { samps amp del -- prc; inval self -- res } 1 proc-create 0 , del , amp , samps , ( prc ) does> { inval self -- res } self @ 1+ dup self ! { samp } self cell+ @ { del } self 2 cells + @ { amp } self 3 cells + @ { samps } del dup 0.0 tap samp samps <= if inval f+ then amp f* 0.0 delay inval f+ ; : effects-flecho-cb ( amp samps flt del -- prc; inval self -- res ) { amp samps flt del } 1 proc-create 0 , samps , flt , del , amp , ( prc ) does> { inval self -- res } self @ 1+ dup self ! { samp } self cell+ @ { samps } self 2 cells + @ { flt } self 3 cells + @ { del } self 4 cells + @ { scl } del flt del 0.0 tap samp samps <= if inval f+ then scl f* fir-filter delay inval f+ ; : effects-zecho-cb ( scaler amp samps os del -- prc; inval self -- res ) { scaler amp samps os del } 1 proc-create 0 , samps , os , del , scaler , amp , ( prc ) does> { inval self -- res } self @ 1+ dup self ! { samp } self cell+ @ { samps } self 2 cells + @ { os } self 3 cells + @ { del } self 4 cells + @ { scl } self 5 cells + @ { amp } del del 0.0 tap samp samps <= if inval f+ then scl f* os 0.0 0.0 oscil amp f* delay inval f+ ; set-current : effects-echo <{ input-samps del-time amp :optional beg 0 dur #f snd #f chn #f -- res }> del-time snd srate f* fround->s make-delay { del } input-samps number? if input-samps else dur number? if dur else snd chn undef framples then then { samps } "%s %s %s %s %s %s" #( input-samps del-time amp beg dur get-func-name ) string-format { orig } samps amp del effects-echo-cb beg dur snd chn #f orig map-channel ; : effects-flecho <{ amp secs input-samps :optional beg 0 dur #f snd #f chn #f -- res }> :order 4 :xcoeffs vct( 0.125 0.25 0.25 0.125 ) make-fir-filter { flt } secs snd srate f* fround->s make-delay { del } input-samps number? if input-samps else dur number? if dur else snd chn undef framples then then { samps } "%s %s %s %s %s %s" #( amp secs input-samps beg dur get-func-name ) string-format { origin } amp samps flt del effects-flecho-cb beg dur snd chn #f origin map-channel ; : effects-zecho <{ scl secs freq amp input-samps :optional beg 0 dur #f snd #f chn #f -- r }> freq make-oscil { os } secs snd srate f* fround->s { len } :size len :max-size len amp f>s 1 + + make-delay { del } input-samps number? if input-samps else dur number? if dur else snd chn undef framples then then { samps } "%s %s %s %s %s %s %s %s" #( scl secs freq amp input-samps beg dur get-func-name ) string-format { origin } scl amp samps os del effects-zecho-cb beg dur snd chn #f origin map-channel ; previous \ effects-bbp ( freq bw :optional beg dur snd chn -- res ) \ effects-bbr ( freq bw :optional beg dur snd chn -- res ) \ effects-bhp ( freq :optional beg dur snd chn -- res ) \ effects-blp ( freq :optional beg dur snd chn -- res ) \ effects-comb-filter ( scl size :optional beg dur snd chn -- res ) \ effects-comb-chord ( scl size amp :optional beg dur snd chn -- res ) : effects-bbp <{ freq bw :optional beg 0 dur #f snd #f chn #f -- res }> "%s %s %s %s %s" #( freq bw beg dur get-func-name ) string-format { origin } freq bw make-butter-band-pass beg dur snd chn #f #f origin clm-channel ; : effects-bbr <{ freq bw :optional beg 0 dur #f snd #f chn #f -- res }> "%s %s %s %s %s" #( freq bw beg dur get-func-name ) string-format { origin } freq bw make-butter-band-reject beg dur snd chn #f #f origin clm-channel ; : effects-bhp <{ freq :optional beg 0 dur #f snd #f chn #f -- res }> "%s %s %s %s" #( freq beg dur get-func-name ) string-format { origin } freq make-butter-high-pass beg dur snd chn #f #f origin clm-channel ; : effects-blp <{ freq :optional beg 0 dur #f snd #f chn #f -- res }> "%s %s %s %s" #( freq beg dur get-func-name ) string-format { origin } freq make-butter-low-pass beg dur snd chn #f #f origin clm-channel ; : effects-comb-filter <{ scl size :optional beg 0 dur #f snd #f chn #f -- res }> "%s %s %s %s %s" #( scl size beg dur get-func-name ) string-format { origin } scl size comb-filter beg dur snd chn #f origin map-channel ; : effects-comb-chord <{ scl size amp :optional beg 0 dur #f snd #f chn #f -- res }> "%s %s %s %s %s %s" #( scl size amp beg dur get-func-name ) string-format { origin } scl size amp comb-chord beg dur snd chn #f origin map-channel ; \ effects-moog ( freq Q :optional beg dur snd chn -- res ) hide : moog-cb ( gen -- prc; inval self -- res ) 1 proc-create swap , ( prc ) does> { inval self -- res } self @ ( gen ) inval moog-filter ; set-current : effects-moog <{ freq Q :optional beg 0 dur #f snd #f chn #f -- res }> "%s %s %s %s %s" #( freq Q beg dur get-func-name ) string-format { origin } freq Q make-moog-filter moog-cb beg dur snd chn #f origin map-channel ; previous \ moog ( freq Q -- prc; inval self -- res ) : moog ( freq Q -- prc; inval self -- res ) make-moog-filter { gen } 1 proc-create gen , ( prc ) does> { inval self -- res } self @ ( gen ) inval moog-filter ; \ effects-am ( freq en :optional beg dur snd chn -- res ) \ effects-rm ( freq en :optional beg dur snd chn -- res ) hide : effects-am-env-cb { os e -- prc; x self -- res } 1 proc-create e , os , ( prc ) does> { inval self -- res } self @ { e } self cell+ @ { os } 1.0 inval e env os 0.0 0.0 oscil f* amplitude-modulate ; : effects-am-cb ( os -- prc; x self -- res ) 1 proc-create swap , ( prc ) does> { inval self -- res } self @ { os } os 0.0 0.0 oscil inval f* ; : effects-rm-env-cb { os e -- prc; x self -- res } 1 proc-create e , os , ( prc ) does> { inval self -- res } self @ { e } self cell+ @ { os } os 0.0 0.0 oscil e env f* inval f* ; : effects-rm-cb ( os -- prc; x self -- res ) 1 proc-create swap , ( prc ) does> { inval self -- res } self @ { os } 1.0 inval os 0.0 0.0 oscil amplitude-modulate ; set-current : effects-am <{ freq en :optional beg 0 dur #f snd #f chn #f -- res }> freq make-oscil { os } en array? if :envelope en :length dur 1- make-env else #f then { e } "%s %s %s %s %s" #( freq en beg dur get-func-name ) string-format { origin } e if os e effects-am-env-cb else os effects-am-cb then beg dur snd chn #f origin map-channel ; : effects-rm <{ freq en :optional beg 0 dur #f snd #f chn #f -- res }> freq make-oscil { os } en array? if :envelope en :length dur 1- make-env else #f then { e } "%s %s %s %s %s" #( freq en beg dur get-func-name ) string-format { origin } e if os e effects-rm-env-cb else os effects-rm-cb then beg dur snd chn #f origin map-channel ; previous \ effects-jc-reverb ( samps volume -- prc; inval self -- res ) \ effects-jc-reverb-1 ( volume :optional beg dur snd chn -- res ) : effects-jc-reverb ( samps volume -- prc; inval self -- res ) { samps vol } -0.7 0.7 1051 make-all-pass { all1 } -0.7 0.7 337 make-all-pass { all2 } -0.7 0.7 113 make-all-pass { all3 } 0.742 4799 make-comb { c1 } 0.733 4999 make-comb { c2 } 0.715 5399 make-comb { c3 } 0.697 5801 make-comb { c4 } #f srate 0.013 f* fround->s make-delay { outdel } 1 proc-create 0 ( samp ), samps , vol , 0.0 ( comb-sum ) , 0.0 ( comb-sum-1 ) , 0.0 ( comb-sum-2 ) , all1 , all2 , all3 , c1 , c2 , c3 , c4 , outdel , ( prc ) does> { inval self -- res } self @ ( samp++ ) 1+ self ! self @ { samp } self 1 cells + @ { samps } self 2 cells + @ { volume } self 3 cells + @ { comb-sum } self 4 cells + @ { comb-sum-1 } self 5 cells + @ { comb-sum-2 } self 6 cells + @ { allpass1 } self 7 cells + @ { allpass2 } self 8 cells + @ { allpass3 } self 9 cells + @ { comb1 } self 10 cells + @ { comb2 } self 11 cells + @ { comb3 } self 12 cells + @ { comb4 } self 13 cells + @ { outdel } allpass3 allpass2 allpass1 samp samps <= if inval else 0.0 then 0.0 all-pass 0.0 all-pass 0.0 all-pass { allpass-sum } comb-sum-1 self 5 cells + ! ( comb-sum-2 ) comb-sum self 4 cells + ! ( comb-sum-1 ) comb1 allpass-sum 0.0 comb comb2 allpass-sum 0.0 comb f+ comb3 allpass-sum 0.0 comb f+ comb4 allpass-sum 0.0 comb f+ self 3 cells + ! ( comb-sum ) outdel comb-sum 0.0 delay volume f* inval f+ ; : effects-jc-reverb-1 <{ vol :optional beg 0 dur #f snd #f chn #f -- res }> dur if dur else snd chn #f framples then { samps } "%s %s %s %s" #( vol beg dur get-func-name ) string-format { origin } samps vol effects-jc-reverb beg dur snd chn #f origin map-channel ; \ effects-cnv ( snd0 amp snd chn -- res ) hide : cnv-cb ( sf -- prc; dir self -- res ) 1 proc-create swap , ( prc ) does> { dir self -- res } self @ ( sf ) next-sample ; set-current : effects-cnv <{ snd0 amp :optional snd #f chn #f -- res }> snd0 sound? unless sounds 0 array-ref to snd0 then snd0 #f #f framples { flt-len } snd chn #f framples flt-len + { total-len } :filter 0 flt-len snd0 #f #f channel->vct make-convolve { cnv } 0 snd chn 1 #f make-sampler { sf } sf cnv-cb { cnv-func } total-len 0.0 make-vct map! cnv cnv-func convolve end-map { out-data } sf free-sampler drop out-data amp vct-scale! drop out-data vct-peak { max-samp } out-data 0 total-len snd chn #f "%s %s %s" #( snd0 amp get-func-name ) string-format vct->channel drop max-samp 1.0 f> if #( max-samp fnegate max-samp ) snd chn set-y-bounds drop then max-samp ; previous \ effects-position-sound ( mono-snd pos :optional snd chn -- res ) \ effects-place-sound ( mono-snd stereo-snd pan-env -- res ) hide : numb-cb { rd pos -- prc; y self -- res } 1 proc-create pos , rd , ( prc ) does> { y self -- res } self cell+ @ ( rd ) read-sample self @ ( pos ) f* y f+ ; : env-numb-cb { rd en -- prc; y self -- res } 1 proc-create en , rd , ( prc ) does> { y self -- res } self cell+ @ ( rd ) read-sample self @ ( en ) env f* y f+ ; : env-cb { rd en -- prc; y self -- res } 1 proc-create en , rd , ( prc ) does> { y self -- res } self cell+ @ ( rd ) read-sample 1.0 self @ ( en ) env f- f* y f+ ; set-current : effects-position-sound <{ mono pos :optional snd #f chn #f -- res }> mono #f #f framples { len } 0 mono #f 1 #f make-sampler { rd } "%s %s %s" #( mono pos get-func-name ) string-format { origin } pos number? if rd pos numb-cb 0 len snd chn #f origin map-channel else :envelope pos :length len 1- make-env { e } chn integer? chn 1 = && if rd e env-numb-cb 0 len snd chn #f origin map-channel else rd e env-cb 0 len snd chn #f origin map-channel then then ; : effects-place-sound ( mono stereo pan -- res ) doc" Mixes a mono sound into a stereo sound, \ splitting it into two copies whose amplitudes depend on the envelope PAN-ENV. \ If PAN-ENV is a number, the sound is split such that 0 is all in channel 0 \ and 90 is all in channel 1." { mono stereo pan } pan number? if pan 90.0 f/ { pos } mono pos stereo 1 effects-position-sound drop mono 1.0 pos f- stereo 0 effects-position-sound else mono pan stereo 1 effects-position-sound drop mono pan stereo 0 effects-position-sound then ; previous \ effects-flange ( amount speed time :optional beg dur snd chn -- res ) hide : flange-cb { ri del -- prc; inval self -- res } 1 proc-create del , ri , ( prc ) does> { inval self -- res } self @ ( del ) inval self cell+ @ ( ri ) 0.0 rand-interp delay inval f+ 0.75 f* ; set-current : effects-flange <{ amnt speed time :optional beg 0 dur #f snd #f chn #f -- res}> :frequency speed :amplitude amnt make-rand-interp { ri } time snd srate f* fround->s { len } :size len :max-size amnt f>s len 1 + + make-delay { del } "%s %s %s %s %s %s" #( amnt speed time beg dur number? snd chn #f framples dur <> && if dur else #f then get-func-name ) string-format { origin } ri del flange-cb beg dur snd chn #f origin map-channel ; previous \ effects-cross-synthesis ( snd amp fftsize r -- prc; inval self -- res ) \ effects-cross-synthesis-1 ( snd amp fft r :optional beg dur snd chn -- res ) : effects-cross-synthesis ( snd amp fftsize r -- prc; inval self -- res ) { snd amp fftsize r } fftsize 2/ { freq-inc } fftsize 0.0 make-vct { fdr } fftsize 0.0 make-vct { fdi } freq-inc 0.0 make-vct { spectr } 1.0 r fftsize f/ f- { radius } #f srate fftsize / { bin } freq-inc make-array map! :radius radius :frequency bin i * make-formant end-map spectr make-formant-bank { formants } 1 proc-create ( inctr ) 0 , ( ctr ) freq-inc , fdr , fdi , spectr , formants , snd , amp , ( prc ) does> { inval self -- res } self @ { inctr } self 1 cells + @ { ctr } self 2 cells + @ { fdr } self 3 cells + @ { fdi } self 4 cells + @ { spectr } self 5 cells + @ { formants } self 6 cells + @ { snd } self 7 cells + @ { amp } fdr vct-length { fftsize } spectr vct-length { freq-inc } 0.0 { outval } ctr freq-inc = if inctr fftsize snd 0 #f channel->vct self 2 cells + ! ( fdr ) inctr freq-inc + self ! ( inctr ) fdr fdi #f 2 spectrum drop fdr spectr vct-subtract! drop fdr freq-inc 1/f vct-scale! drop 0 self 1 cells + ! ( ctr=0 ) then ctr 1+ self 1 cells + ! ( ctr++ ) spectr fdr 0 vct-add! drop formants inval formant-bank amp f* ; : effects-cross-synthesis-1 <{ csnd amp fftsize r :optional beg 0 dur #f snd #f chn #f -- res }> { csnd amp fftsize r beg dur snd chn } "%s %s %s %s %s %s %s" #( csnd amp fftsize r beg dur get-func-name ) string-format { origin } csnd sound? unless sounds 0 array-ref to csnd then csnd amp fftsize r effects-cross-synthesis beg dur snd chn #f origin map-channel ; \ effects-fp ( srf amp freq :optional beg dur snd chn -- vct ) hide : src-fp-read-cb ( sf -- prc; dir self -- samp ) 1 proc-create swap , ( prc ) does> { dir self -- samp } self @ ( sf ) dir 0> if next-sample else previous-sample then ; set-current : effects-fp <{ srf amp freq :optional beg 0 dur #f snd #f chn #f -- vct }> freq make-oscil { os } :srate srf make-src { sr } beg snd chn 1 #f make-sampler { sf } dur if dur else snd chn #f framples then { len } sf src-fp-read-cb { src-cb } len 0.0 make-vct map! sr os 0.0 0.0 oscil amp f* src-cb src end-map ( out-data ) beg len snd chn #f "%s %s %s %s %s %s" #( srf amp freq beg dur get-func-name ) string-format vct->channel ; previous \ effects-hello-dentist ( freq amp :optional beg dur snd chn -- res ) hide : hello-src-cb { in-data idx -- prc; dir self -- samp } 1 proc-create idx , in-data , ( prc ) does> { dir self -- samp } self @ { idx } self cell+ @ { in-data } in-data idx range? if in-data idx vct-ref else 0.0 then ( val ) idx dir + self ! ( idx ) ; set-current : effects-hello-dentist <{ freq amp :optional beg 0 dur #f snd #f chn #f -- res }> :frequency freq :amplitude amp make-rand-interp { rn } 0 { idx } dur if dur else snd chn #f framples then { len } beg len snd chn #f channel->vct { in-data } amp f2* 1.0 f+ len f* fround->s ( out-len ) 0.0 make-vct { out-data } :srate 1.0 :input in-data idx hello-src-cb make-src { rd } out-data map! idx len = ?leave rd rn 0.0 rand-interp #f src end-map to out-data "%s %s %s %s %s" #( freq amp beg dur get-func-name ) string-format { origin } out-data beg out-data vct-length snd chn #f origin vct->channel ; previous \ effects-remove-clicks ( :optional snd chn -- res ) \ effects-remove-dc ( :optional snd chn -- res ) \ effects-compand ( :optional snd chn -- res ) hide : find-click { loc snd chn -- pos|#f } loc snd chn 1 #f make-sampler { rd } 0.0 0.0 0.0 { samp0 samp1 samp2 } 10 0.0 make-vct { samps } #f \ flag snd chn #f framples loc ?do samp1 to samp0 samp2 to samp1 rd next-sample to samp2 samps samp0 cycle-set! samps vct-peak 0.1 fmax { local-max } samp0 samp1 f- fabs local-max f> samp1 samp2 f- fabs local-max f> && samp0 samp2 f- fabs local-max f2/ f< && if drop ( flag ) i leave then loop ; : remove-click { loc snd chn -- } loc snd chn find-click { click } click if click 2 - 4 snd chn smooth-sound drop click 2 + snd chn recurse then ; : effects-remove-dc-cb ( -- prc; inval self -- res ) 1 proc-create 0.0 ( lastx ) , 0.0 ( lasty ) , ( prc ) does> { inval self -- res } self @ { lastx } self cell+ @ { lasty } 0.999 lasty f* lastx f- inval f+ self cell+ ! ( lasty ) inval self ! ( lastx ) self cell+ @ ( lasty ) ; : effects-compand-cb ( tbl -- prc; inval self -- res ) 1 proc-create swap , ( prc ) does> { inval self -- res } self @ { tbl } tbl inval 8.0 f* 8.0 f+ tbl length array-interp ; set-current : effects-remove-clicks <{ :optional snd #f chn #f -- res }> 0 snd chn remove-click #f ; : effects-remove-dc <{ :optional snd #f chn #f -- res }> effects-remove-dc-cb 0 #f snd chn #f get-func-name map-channel ; : effects-compand <{ :optional snd #f chn #f -- res }> vct( -1.000 -0.960 -0.900 -0.820 -0.720 -0.600 -0.450 -0.250 0.000 0.250 0.450 0.600 0.720 0.820 0.900 0.960 1.000 ) { tbl } tbl effects-compand-cb 0 #f snd chn #f get-func-name map-channel ; previous 'snd-nogui provided? [if] skip-file [then] 'snd-gtk provided? [if] 'gtk3 provided? not [if] .( snd-gtk: gtk3 required -- skipping effects.fs ) cr skip-file [then] [then] require xm-enved require snd-xm require rubber \ === SND MENU === hide #( "menu-children" "menu-parent" "menu-name" "menu-menu" "menu-cascade" "menu-display-cb" ) create-struct make-snd-menu-struct : menu-display ( gen -- ) menu-display-cb@ #() run-proc drop ; #( "eff_label" "eff_dialog" "eff_target" "eff_target_widget" "eff_trunc" "eff_sliders" "eff_scl" "eff_freq" "eff_amp" "eff_delay" "eff_amnt" "eff_enved" "eff_size" "eff_omit_silence" "eff_bp_bw" "eff_notch_bw" "eff_moog_reson" "eff_time_scale" "eff_hop_size" "eff_ramp_scl" "eff_pitch_scl" "eff_seg_len" "eff_rev_filter" "eff_rev_fb" "eff_rev_decay" "eff_rev_vol" "eff_conv_one" "eff_conv_two" "eff_m_snd" "eff_s_snd" "eff_pan_pos" "eff_cs_snd" "eff_cs_radius" "eff_cs_wid" "eff_fl_speed" "eff_fl_time" "eff_sr" "eff_factor" ) create-struct make-effects-menu-struct set-current : make-base-effects { label -- gen } make-effects-menu-struct { gen } gen label eff_label! gen #f eff_dialog! gen 'sound eff_target! gen #t eff_trunc! gen #f eff_sliders! gen ; <'> noop 0 make-proc constant effects-noop "Go Away" constant eff-dismiss-string "Help" constant eff-help-string "DoIt" constant eff-okay-string "Reset" constant eff-reset-string \ log scaler widget 500.0 constant log-scale-ticks : scale-log->linear ( lo val hi -- lin ) { lo val hi } 2.0 flog { log2 } lo 1.0 fmax flog log2 f/ { log-lo } hi flog log2 f/ { log-hi } val flog log2 f/ log-lo f- log-hi log-lo f- f/ log-scale-ticks f* floor->s ; : scale-linear->log ( lo val hi -- log ) { lo val hi } 2.0 flog { log2 } lo 1.0 fmax flog log2 f/ { log-lo } hi flog log2 f/ { log-hi } 2.0 log-lo val log-scale-ticks f/ log-hi log-lo f- f* f+ f** ; : scale-log-label ( lo val hi -- str ) scale-linear->log "%.2f" swap 1 >array string-format ; \ semitone scaler widget 24 value semi-range : semi-scale-label ( val -- str ) "semitones: %s" swap semi-range - 1 >array string-format ; : semitones->ratio ( val -- r ) 2.0 swap 12.0 f/ f** ; : ratio->semitones ( ratio -- n ) 12.0 swap flog 2.0 flog f/ f* fround->s ; : marks-sort ( a b -- -1|0|1 ) { a b } a b < if -1 else a b = if 0 else 1 then then ; \ returns a list of points : plausible-mark-samples ( -- pts ) selected-sound { snd } snd selected-channel { chn } #() { ms } snd chn #f marks each undef mark-sample ms swap array-push drop end-each ms length 2 < if #f else ms <'> marks-sort array-sort! drop ms length 2 = if ms array->array else snd chn left-sample { lw } snd chn right-sample { rw } snd chn undef cursor { cw } cw lw >= cw rw <= && if cw else lw rw + 2/ then { favor } #( ms first-ref ms second-ref ) { res } ms each { p1 } i ms length 2 - = if #( p1 ms last-ref ) to res leave then ms i 1+ array-ref { p2 } ms i 2 + array-ref { p3 } p1 favor - abs p3 favor - abs < if #( p1 p2 ) to res leave then end-each res then then ; : effect-frames { target -- frms } target 'sound = if #f #f #f framples 1- else target 'selection = if #f #f selection-framples else plausible-mark-samples { pts } pts if pts 0 array-ref pts 1 nil array-subarray each - end-each abs 1+ else 0 then then then ; : effect-target-ok <{ target -- f }> sounds empty? if #f else target 'sound = if #t else target 'selection = if undef selection? else target 'marks = if selected-sound dup selected-channel #f marks length 2 >= else #f then then then then ; : general-target-cb ( gen -- prc; self -- f ) 0 proc-create swap , ( prc ) does> { self -- f } self @ ( gen ) eff_target@ effect-target-ok ; : set-default-target-cb { okay-button -- prc; self -- } 0 proc-create okay-button , ( prc ) does> { self -- } self @ ( okay-button ) sounds empty? not set-sensitive ; : set-target-cb { okay-button target-prc -- prc; self -- } 0 proc-create okay-button , target-prc , ( prc ) does> { self -- } self @ ( okay ) self cell+ @ ( target ) #() run-proc set-sensitive ; : help-cb { label message -- prc; w c i self -- x } 3 proc-create label , message , ( prc ) does> { w c info self -- x } self @ ( label ) self cell+ @ ( message ) help-dialog ; : target-cb ( gen -- prc; target self -- ) 1 proc-create swap , ( prc ) does> { target self -- } self @ { gen } gen target eff_target! gen eff_target_widget@ target effect-target-ok set-sensitive ; : truncate-cb ( gen -- prc; trunc self -- ) 1 proc-create swap , ( prc ) does> { trunc self } self @ ( gen ) trunc eff_trunc! ; : map-chan-over-target-with-sync { func target origin-func decay -- } sounds empty? if "no sound" undef status-report drop else target 'selection = undef selection? not && if "no selection" undef status-report drop else #f sync { snc } target 'marks = if plausible-mark-samples else #() then { pts } target 'sound = if 0 else target 'selection = if #f #f selection-position else pts 0 array-ref then then { beg } decay number? if #f srate decay f* fround->s else 0 then { overlap } snc 0> if all-chans else #( #( selected-sound dup selected-channel ) ) then each { lst } lst 0 array-ref { snd } lst 1 array-ref { chn } snd sync snc = if target 'sound = if snd chn undef framples 1- else target 'selection = if #f #f selection-position #f #f selection-framples + else pts 1 array-ref then then { end } end beg - { dur } origin-func #( target dur ) run-proc { name-and-orig } "%s %s %s %s" #( name-and-orig 0 array-ref beg target 'sound = if #f else dur 1+ then name-and-orig 1 array-ref ) string-format { origin } func dur run-proc beg end overlap + 1+ snd chn #f origin map-channel drop then end-each then then ; 'snd-motif provided? [if] : cascade-cb <{ w c i -- }> c each #() run-proc drop end-each ; : make-menu { name parent -- gen } make-snd-menu-struct { gen } parent name #( FXmNbackground basic-color ) undef FXmCreatePulldownMenu { menu } #() { lst } name FxmCascadeButtonWidgetClass parent #( FXmNsubMenuId menu FXmNbackground basic-color ) undef FXtCreateManagedWidget { cas } cas FXmNcascadingCallback <'> cascade-cb lst FXtAddCallback drop gen parent menu-parent! gen name menu-name! gen menu menu-menu! gen cas menu-cascade! gen lst menu-children! gen ; : menu-entry { gen prc disp-prc -- } gen menu-children@ { lst } lst array? lst 1 "an array" assert-type gen menu-name@ FxmPushButtonWidgetClass gen menu-menu@ #( FXmNbackground basic-color ) undef FXtCreateManagedWidget { child } child FXmNactivateCallback prc undef FXtAddCallback drop lst disp-prc #( child ) run-proc array-push drop ; : unmanage-cb <{ w c i -- f }> c FXtUnmanageChild ; [undefined] F_XEditResCheckMessages [if] : F_XEditResCheckMessages <{ w c i f -- x }> #f ; [then] : make-effect-dialog { label ok-prc help-prc reset-prc target-prc -- d } eff-dismiss-string FXmStringCreateLocalized { xdismiss } eff-help-string FXmStringCreateLocalized { xhelp } eff-okay-string FXmStringCreateLocalized { xok } label FXmStringCreateLocalized { titlestr } main-widgets 1 array-ref label #( FXmNcancelLabelString xdismiss FXmNhelpLabelString xhelp FXmNokLabelString xok FXmNautoUnmanage #f FXmNdialogTitle titlestr FXmNresizePolicy FXmRESIZE_GROW FXmNnoResize #f FXmNbackground basic-color FXmNtransient #f ) undef FXmCreateTemplateDialog { d } xhelp FXmStringFree drop xok FXmStringFree drop xdismiss FXmStringFree drop titlestr FXmStringFree drop d 0 #t <'> F_XEditResCheckMessages #f FXtAddEventHandler drop #( #( FXmDIALOG_HELP_BUTTON highlight-color ) #( FXmDIALOG_CANCEL_BUTTON highlight-color ) #( FXmDIALOG_OK_BUTTON highlight-color ) ) each { lst } lst 0 array-ref { button } lst 1 array-ref { color } d button FXmMessageBoxGetChild #( FXmNarmColor selection-color FXmNbackground color ) FXtVaSetValues drop end-each d FXmNcancelCallback <'> unmanage-cb d FXtAddCallback drop d FXmNhelpCallback help-prc undef FXtAddCallback drop d FXmNokCallback ok-prc undef FXtAddCallback drop reset-prc if eff-reset-string FxmPushButtonWidgetClass d #( FXmNbackground highlight-color FXmNforeground black-pixel FXmNarmColor selection-color ) undef FXtCreateManagedWidget ( reset ) FXmNactivateCallback reset-prc undef FXtAddCallback drop then d FXmDIALOG_OK_BUTTON FXmMessageBoxGetChild { okay-button } effects-hook okay-button target-prc ?dup-if set-target-cb else set-default-target-cb then add-hook! d ; : scale-log-cb <{ w c info -- }> c 0 array-ref { label } c 1 array-ref { low } c 2 array-ref { high } label low info Fvalue high scale-log-label change-label ; : create-log-scale-widget { parent title low init high cb -- scale } "%.2f" #( init ) string-format FxmLabelWidgetClass parent #( FXmNbackground basic-color ) undef FXtCreateManagedWidget { label } "scale" FxmScaleWidgetClass parent #( FXmNorientation FXmHORIZONTAL FXmNshowValue #f FXmNminimum 0 FXmNmaximum log-scale-ticks f>s FXmNvalue low init high scale-log->linear FXmNdecimalPoints 0 FXmNtitleString title FXmNbackground basic-color ) undef FXtCreateManagedWidget { scale } #( label low high ) { data } scale FXmNvalueChangedCallback <'> scale-log-cb data FXtAddCallback drop scale FXmNvalueChangedCallback cb undef FXtAddCallback drop scale FXmNdragCallback <'> scale-log-cb data FXtAddCallback drop scale FXmNdragCallback cb undef FXtAddCallback drop scale ; : scale-semi-cb <{ w c info -- }> c info Fvalue semi-scale-label change-label ; : create-semi-scale-widget { parent title init cb -- scale } "semitones: %s" #( init ratio->semitones ) string-format { str } str FxmLabelWidgetClass parent #( FXmNbackground basic-color ) undef FXtCreateManagedWidget { label } "scale" FxmScaleWidgetClass parent #( FXmNorientation FXmHORIZONTAL FXmNshowValue #f FXmNminimum 0 FXmNmaximum semi-range 2* FXmNvalue semi-range init ratio->semitones + FXmNdecimalPoints 0 FXmNtitleString title FXmNbackground basic-color ) undef FXtCreateManagedWidget { scale } scale FXmNvalueChangedCallback <'> scale-semi-cb label FXtAddCallback drop scale FXmNvalueChangedCallback cb undef FXtAddCallback drop scale FXmNdragCallback <'> scale-semi-cb label FXtAddCallback drop scale FXmNdragCallback cb undef FXtAddCallback drop scale ; \ sliders: #( #( label low init high func scale [log] ) ... ) : add-sliders { dialog sliders -- sliders-array } "formd" FxmFormWidgetClass dialog #( FXmNleftAttachment FXmATTACH_FORM FXmNrightAttachment FXmATTACH_FORM FXmNtopAttachment FXmATTACH_FORM FXmNbottomAttachment FXmATTACH_WIDGET FXmNbottomWidget dialog FXmDIALOG_SEPARATOR FXmMessageBoxGetChild FXmNbackground highlight-color ) undef FXtCreateManagedWidget { mainfrm } "rcd" FxmRowColumnWidgetClass mainfrm #( FXmNleftAttachment FXmATTACH_FORM FXmNrightAttachment FXmATTACH_FORM FXmNbackground highlight-color FXmNorientation FXmVERTICAL ) undef FXtCreateManagedWidget { mainform } sliders map *key* 0 array-ref FXmStringCreateLocalized { title } *key* 1 array-ref { low } *key* 2 array-ref { init } *key* 3 array-ref { high } *key* 4 array-ref { func } *key* 5 array-ref { scale } *key* length 7 = if *key* 6 array-ref 'log = if mainform title low init high func create-log-scale-widget else mainform title init func create-semi-scale-widget then ( scale ) else *key* 0 array-ref FxmScaleWidgetClass mainform #( FXmNorientation FXmHORIZONTAL FXmNshowValue #t FXmNminimum low scale f* fround->s FXmNmaximum high scale f* fround->s FXmNvalue init scale f* fround->s FXmNdecimalPoints scale 10000 = if 4 else scale 1000 = if 3 else scale 100 = if 2 else scale 10 = if 1 else 0 then then then then FXmNtitleString title FXmNleftAttachment FXmATTACH_FORM FXmNrightAttachment FXmATTACH_FORM FXmNbackground basic-color ) undef FXtCreateManagedWidget ( sc ) then { new-slider } title FXmStringFree drop new-slider FXmNvalueChangedCallback func undef FXtAddCallback drop new-slider end-map ; : color->pixel ( color-str "name" --; self -- pixel ) { color-str } create #f , color-str , does> { self -- pixel } self @ ( color ) unless main-widgets 1 array-ref { shell } shell FXtDisplay { dpy } dpy FDefaultScreen { scr } dpy scr FDefaultColormap { cmap } undef undef undef undef undef undef FXColor { col } dpy cmap self cell+ @ ( color-str ) col col FXAllocNamedColor 0= if "can't allocate color!" snd-error drop else col Fpixel self ! then then self @ ( color ) ; "yellow" color->pixel yellow-pixel \ c == #( prc type ) : target-arm-cb <{ w c info -- f }> c 0 array-ref #( c 1 array-ref ) run-proc ; : target-truncate-cb <{ w c info -- f }> c #( info Fset ) run-proc ; : add-target-main { mainform target-prc truncate-prc -- rc-wid } "sep" FxmSeparatorWidgetClass mainform #( FXmNorientation FXmHORIZONTAL FXmNseparatorType FXmSHADOW_ETCHED_OUT FXmNbackground basic-color ) undef FXtCreateManagedWidget drop "rc" FxmRowColumnWidgetClass mainform #( FXmNorientation FXmHORIZONTAL FXmNbackground basic-color FXmNradioBehavior #t FXmNradioAlwaysOne #t FXmNbottomAttachment FXmATTACH_FORM FXmNleftAttachment FXmATTACH_FORM FXmNrightAttachment FXmATTACH_FORM FXmNentryClass FxmToggleButtonWidgetClass FXmNisHomogeneous #t ) undef FXtCreateManagedWidget { rc } #( #( "entire sound" 'sound #t ) #( "selection" 'selection #f ) #( "between marks" 'marks #f ) ) each { lst } lst 0 array-ref { name } lst 1 array-ref { typ } lst 2 array-ref { on } name FxmToggleButtonWidgetClass rc #( FXmNbackground basic-color FXmNselectColor yellow-pixel FXmNSet on FXmNindicatorType FXmONE_OF_MANY_ROUND FXmNarmCallback #( <'> target-arm-cb #( target-prc typ ) ) ) undef FXtCreateManagedWidget drop end-each truncate-prc if "trsep" FxmSeparatorWidgetClass mainform #( FXmNorientation FXmHORIZONTAL ) undef FXtCreateManagedWidget drop "truncate at end" FxmToggleButtonWidgetClass mainform #( FXmNbackground basic-color FXmNset #t FXmNselectColor yellow-pixel ) undef FXtCreateManagedWidget ( trbut ) FXmNvalueChangedCallback <'> target-truncate-cb truncate-prc FXtAddCallback drop then rc ; : add-target { gen truncate-prc -- } gen eff_dialog@ FXmDIALOG_OK_BUTTON FXmMessageBoxGetChild ( mb ) gen swap eff_target_widget! gen eff_sliders@ 0 array-ref FXtParent { mainform } truncate-prc if gen truncate-prc to truncate-prc then mainform gen target-cb truncate-prc add-target-main drop ; : get-slider-value { w info corr -- val } info Fvalue corr f/ ; : set-slider-value { w val corr -- } w #( FXmNvalue val corr f* f>s ) FXtVaSetValues drop ; [else] \ !HAVE_MOTIF : motif->gtk-cb ( prc-3-arg -- prc-2-arg; w d self -- x ) 2 proc-create swap , ( prc ) does> { w d self -- x } self @ ( prc ) #( w d #f ) run-proc ; \ We use existing motif callbacks. : wrap-motif-cb ( prc -- prc' ) dup proc-arity 0 array-ref 3 = if motif->gtk-cb then ; : cascade-cb <{ w d -- f }> d each #() run-proc drop end-each #f ; : make-menu { name parent -- gen } make-snd-menu-struct { gen } name Fgtk_menu_item_new_with_label { menu } #() { lst } Fgtk_menu_new { cas } parent FGTK_MENU_ITEM Fgtk_menu_item_get_submenu FGTK_MENU_SHELL menu Fgtk_menu_shell_append drop menu Fgtk_widget_show drop menu FGTK_MENU_ITEM cas Fgtk_menu_item_set_submenu drop menu "activate" <'> cascade-cb lst Fg_signal_connect drop gen parent menu-parent! gen name menu-name! gen menu menu-menu! gen cas menu-cascade! gen lst menu-children! gen ; : menu-entry { gen prc disp-prc -- } gen menu-children@ { lst } lst array? lst 1 "an array" assert-type gen menu-name@ Fgtk_menu_item_new_with_label { child } gen menu-cascade@ FGTK_MENU_SHELL child Fgtk_menu_shell_append drop child Fgtk_widget_show drop child "activate" prc wrap-motif-cb #f Fg_signal_connect drop lst disp-prc #( child ) run-proc array-push drop ; : unmanage-ev-cb <{ w ev d -- f }> d Fgtk_widget_hide drop #t ; : unmanage-cb <{ w d -- f }> d Fgtk_widget_hide ; : make-effect-dialog { label ok-prc help-prc reset-prc target-prc -- d } eff-dismiss-string Fgtk_button_new_with_label { dismiss-button } eff-help-string Fgtk_button_new_with_label { help-button } eff-okay-string Fgtk_button_new_with_label { okay-button } Fgtk_dialog_new { d } dismiss-button "quit_button" Fgtk_widget_set_name drop help-button "help_button" Fgtk_widget_set_name drop okay-button "doit_button" Fgtk_widget_set_name drop d FGTK_CONTAINER 10 Fgtk_container_set_border_width drop d FGTK_WINDOW { window } window label Fgtk_window_set_title drop window -1 -1 Fgtk_window_set_default_size drop window #t Fgtk_window_set_resizable drop d FGTK_DIALOG Fgtk_dialog_get_action_area FGTK_BOX { box } d "delete_event" <'> unmanage-ev-cb d Fg_signal_connect drop box dismiss-button #t #t 20 Fgtk_box_pack_start drop dismiss-button "clicked" <'> unmanage-cb d Fg_signal_connect drop dismiss-button Fgtk_widget_show drop box okay-button #t #t 20 Fgtk_box_pack_start drop okay-button "clicked" ok-prc wrap-motif-cb #f Fg_signal_connect drop okay-button Fgtk_widget_show drop reset-prc if eff-reset-string Fgtk_button_new_with_label { reset } reset "reset_button" Fgtk_widget_set_name drop box reset #t #t 20 Fgtk_box_pack_start drop reset "clicked" reset-prc wrap-motif-cb #f Fg_signal_connect drop reset Fgtk_widget_show drop then box help-button #t #t 20 Fgtk_box_pack_end drop help-button "clicked" help-prc wrap-motif-cb #f Fg_signal_connect drop help-button Fgtk_widget_show drop effects-hook okay-button target-prc ?dup-if set-target-cb else set-default-target-cb then add-hook! d FG_OBJECT "ok-button" okay-button FGPOINTER Fg_object_set_data drop d ; : scale-log-cb <{ w d -- f }> d 0 array-ref { label } d 1 array-ref { title } d 2 array-ref { low } d 3 array-ref { high } d 4 array-ref { func } func #( w d ) run-proc drop label title ": " $+ low w FGTK_ADJUSTMENT Fgtk_adjustment_get_value high scale-log-label $+ change-label #f ; 'gtk3 provided? [if] <'> noop alias effects-range-set-update-policy ( w -- f ) [else] : effects-range-set-update-policy ( w -- f ) FGTK_RANGE FGTK_UPDATE_CONTINUOUS Fgtk_range_set_update_policy ; [then] \ sliders: #( #( label low init high func scale [log] ) ... ) : add-sliders { dialog sliders -- sliders-array } FGTK_ORIENTATION_VERTICAL 2 Fgtk_box_new { mainform } sliders length 1 = if #f #f else Fgtk_grid_new dup FGTK_GRID then { table tabtab } 0 { slider } dialog FGTK_DIALOG Fgtk_dialog_get_content_area FGTK_BOX { box } box mainform #f #f 4 Fgtk_box_pack_start drop mainform Fgtk_widget_show drop table if mainform FGTK_BOX table #f #f 4 Fgtk_box_pack_start drop tabtab 4 Fgtk_grid_set_row_spacing drop tabtab 4 Fgtk_grid_set_column_spacing drop table Fgtk_widget_show drop then sliders map *key* 0 array-ref { title } *key* 1 array-ref { low } *key* 2 array-ref { init } *key* 3 array-ref { high } *key* 4 array-ref { func } *key* 5 array-ref { scaler } *key* length 7 = if *key* 6 array-ref 'log = else #f then { use-log } table if #f else FGTK_ORIENTATION_HORIZONTAL 0 Fgtk_box_new then { hbox } table if use-log if "%s (%.2f)" #( title init ) else "%s" #( title ) then else use-log if "%s: %.2f" #( title init ) else "%s:" #( title ) then then string-format Fgtk_label_new { label } use-log if low init high scale-log->linear 0 log-scale-ticks f>s 1 10 1 else init low high 0.0 0.0 0.0 then Fgtk_adjustment_new { adj } FGTK_ORIENTATION_HORIZONTAL adj FGTK_ADJUSTMENT Fgtk_scale_new { scale } table if tabtab label 0 slider 1 1 Fgtk_grid_attach drop else mainform FGTK_BOX hbox #f #f 2 Fgtk_box_pack_start drop hbox Fgtk_widget_show drop hbox FGTK_BOX label #f #f 6 Fgtk_box_pack_start drop then label Fgtk_widget_show drop scale FGTK_SCALE { sclscl } sclscl effects-range-set-update-policy drop sclscl use-log if 0 else scaler 1000 = if 3 else scaler 100 = if 2 else scaler 10 = if 1 else 0 then then then then Fgtk_scale_set_digits drop sclscl use-log not Fgtk_scale_set_draw_value drop table if scale FGTK_WIDGET #t Fgtk_widget_set_hexpand drop tabtab scale 1 slider 1 1 Fgtk_grid_attach drop slider 1+ to slider else hbox FGTK_BOX scale #t #t 0 Fgtk_box_pack_start drop then scale Fgtk_widget_show drop adj "value_changed" use-log if <'> scale-log-cb #( label title low high func wrap-motif-cb ) else func wrap-motif-cb #f then Fg_signal_connect drop adj end-map ; \ d: #( func type ) : target-arm-cb <{ w d -- f }> d 0 array-ref { func } d 1 array-ref { typ } func #( typ ) run-proc ; \ d: func : target-truncate-cb <{ w d -- f }> w FGTK_TOGGLE_BUTTON Fgtk_toggle_button_get_active { wid } d #( wid ) run-proc ; : add-target-main { mainform target-prc truncate-prc -- rc-wid } FGTK_ORIENTATION_HORIZONTAL 2 Fgtk_box_new { rc } mainform FGTK_BOX rc #f #f 4 Fgtk_box_pack_start drop rc Fgtk_widget_show drop rc FGTK_BOX { rcbox } #f { group } #( #( "entire sound" 'sound #t ) #( "selection" 'selection #f ) #( "between marks" 'marks #f ) ) each { lst } lst 0 array-ref { name } lst 1 array-ref { typ } lst 2 array-ref { on } group name Fgtk_radio_button_new_with_label { button } button FGTK_RADIO_BUTTON Fgtk_radio_button_get_group to group rcbox button #f #f 4 Fgtk_box_pack_start drop button FGTK_TOGGLE_BUTTON on Fgtk_toggle_button_set_active drop button Fgtk_widget_show drop button "clicked" <'> target-arm-cb #( target-prc typ ) Fg_signal_connect drop end-each truncate-prc if FGTK_ORIENTATION_HORIZONTAL Fgtk_separator_new { sep } rcbox sep #t #t 4 Fgtk_box_pack_start drop sep Fgtk_widget_show drop "truncate at end" Fgtk_check_button_new_with_label to button rcbox button #t #t 4 Fgtk_box_pack_start drop button FGTK_TOGGLE_BUTTON #t Fgtk_toggle_button_set_active drop button Fgtk_widget_show drop button "clicked" <'> target-truncate-cb truncate-prc Fg_signal_connect drop then rc ; : add-target { gen truncate-prc -- } gen eff_dialog@ FG_OBJECT "ok-button" Fg_object_get_data FGTK_WIDGET ( mb ) gen swap eff_target_widget! gen eff_dialog@ FGTK_DIALOG Fgtk_dialog_get_content_area { d } truncate-prc if gen truncate-prc to truncate-prc then d gen target-cb truncate-prc add-target-main drop ; : get-slider-value { w info corr -- val } w FGTK_ADJUSTMENT Fgtk_adjustment_get_value ; : set-slider-value { w val corr -- } w FGTK_ADJUSTMENT val Fgtk_adjustment_set_value drop ; [then] \ HAVE_MOTIF : make-main-menu ( name -- wid ) effects-noop add-to-main-menu dup to effects-menu main-menu ; : add-to-effects-menu ( name prc -- ) effects-menu -rot undef add-to-menu drop ; previous hide \ reusable callbacks : amplitude-slider-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } w info 100.0 get-slider-value { val } self @ ( gen ) val eff_amp! ; : frequency-slider-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } w info 100.0 get-slider-value { val } self @ ( gen ) val eff_freq! ; : log-freq-slider-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } 20.0 w info 1.0 get-slider-value 22050.0 scale-linear->log { val } self @ ( gen ) val eff_freq! ; : scaler-slider-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } w info 100.0 get-slider-value { val } self @ ( gen ) val eff_scl! ; : size-slider-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } w info 1.0 get-slider-value { val } self @ ( gen ) val eff_size! ; \ === Effects Entries === \ === AMPLITUDE EFFECTS === \ === Gain (gain set by gain-amount) === 'snd-motif provided? [if] : make-enved-widget { gen -- } gen eff_dialog@ FXmDIALOG_OK_BUTTON FXmMessageBoxGetChild ( mb ) gen swap eff_target_widget! gen eff_sliders@ 0 array-ref FXtParent FXtParent { mainform } "fr" FxmFrameWidgetClass mainform #( FXmNheight 200 FXmNleftAttachment FXmATTACH_FORM FXmNrightAttachment FXmATTACH_FORM FXmNtopAttachment FXmATTACH_WIDGET FXmNtopWidget gen eff_sliders@ last-ref FXmNshadowThickness 4 FXmNshadowType FXmSHADOW_ETCHED_OUT ) undef FXtCreateManagedWidget { fr } mainform gen target-cb #f add-target-main { target-row } gen eff_dialog@ activate-dialog gen eff_label@ string-downcase fr :envelope #( 0.0 1.0 1.0 1.0 ) :axis-bounds #( 0.0 1.0 0.0 1.0 ) :args #( FXmNheight 200 ) make-xenved { en } gen en eff_enved! fr #( FXmNbottomAttachment FXmATTACH_WIDGET FXmNbottomWidget target-row ) FXtVaSetValues drop ; [else] : make-enved-widget { gen -- } gen #f add-target gen eff_dialog@ Fgtk_widget_show drop gen eff_label@ string-downcase gen eff_dialog@ FGTK_DIALOG Fgtk_dialog_get_content_area :envelope #( 0.0 1.0 1.0 1.0 ) :axis-bounds #( 0.0 1.0 0.0 1.0 ) make-xenved { en } gen en eff_enved! gen eff_dialog@ activate-dialog ; [then] : gain-ok-cb ( gen -- prc; w c i self -- x ) 3 proc-create swap , ( prc ) does> { w c info self -- x } self @ { gen } gen eff_enved@ xe-envelope #( 0.0 1.0 1.0 1.0 ) equal? if #f else gen eff_enved@ xe-envelope gen eff_amnt@ scale-envelope then { with-env } gen eff_target@ 'sound = if with-env array? if with-env 0 undef 1.0 #f #f #f env-sound else gen eff_amnt@ #f #f scale-by then else gen eff_target@ 'selection = if undef selection? if with-env array? if with-env 1.0 env-selection else gen eff_amnt@ scale-selection-by then else "no selection" undef status-report then else plausible-mark-samples { pts } pts if with-env array? if with-env pts 0 array-ref pts 1 array-ref pts 0 array-ref - 1.0 #f #f #f env-sound else gen eff_amnt@ pts 0 array-ref pts 1 array-ref pts 0 array-ref - #f #f #f normalize-channel then else "no marks" undef status-report then then then ; : gain-reset-cb { gen -- prc; w c i self -- } 3 proc-create gen , gen eff_amnt@ , ( prc ) does> { w c info self -- } self @ { gen } self cell+ @ { init } gen init eff_amnt! gen eff_enved@ #( 0.0 1.0 1.0 1.0 ) set-xe-envelope gen eff_sliders@ 0 array-ref init 100.0 set-slider-value ; : gain-slider-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } w info 100.0 get-slider-value { val } self @ ( gen ) val eff_amnt! ; : post-gain-dialog ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } self @ { gen } gen eff_dialog@ widget? unless gen eff_label@ gen gain-ok-cb gen eff_label@ "\ Move the slider to change the gain scaling amount." help-cb gen gain-reset-cb gen general-target-cb make-effect-dialog { d } gen d eff_dialog! d #( #( "gain" 0.0 gen eff_amnt@ 5.0 gen gain-slider-cb 100 ) ) add-sliders ( sl ) gen swap eff_sliders! gen make-enved-widget else gen eff_dialog@ activate-dialog then ; set-current : make-gain-dialog ( name -- prc1 prc2; child self -- prc; self -- ) ( name ) make-base-effects { gen } gen 1.0 eff_amnt! gen #f eff_enved! gen post-gain-dialog ( prc1 ) 1 proc-create gen , ( prc2 ) does> { child self -- prc; self -- } 0 proc-create self @ ( gen ) , child , ( prc ) does> { self -- } self @ { gen } self cell+ @ ( child ) "%s (%.2f)" #( gen eff_label@ gen eff_amnt@ ) string-format change-label ; previous \ === Normalize === hide : normalize-ok-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } self @ { gen } gen eff_target@ 'sound = if gen eff_amnt@ #f #f scale-to drop else gen eff_target@ 'selection = if undef selection? if gen eff_amnt@ scale-selection-to drop else "no selection" undef status-report drop then else plausible-mark-samples { pts } pts if gen eff_amnt@ pts 0 array-ref pts 1 array-ref pts 0 array-ref - #f #f #f normalize-channel drop else "no marks" undef status-report drop then then then ; : normalize-reset-cb { gen -- prc; w c i self -- } 3 proc-create gen , gen eff_amnt@ , ( prc ) does> { w c info self -- } self @ { gen } self cell+ @ { init } gen init eff_amnt! gen eff_sliders@ 0 array-ref init 100.0 set-slider-value ; : normalize-slider-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } w info 100.0 get-slider-value { val } self @ ( gen ) val eff_amnt! ; : post-normalize-dialog ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } self @ { gen } gen eff_dialog@ widget? unless gen eff_label@ gen normalize-ok-cb gen eff_label@ "\ Normalize scales amplitude to the normalize amount. \ Move the slider to change the scaling amount." help-cb gen normalize-reset-cb gen general-target-cb make-effect-dialog { d } gen d eff_dialog! d #( #( "normalize" 0.0 gen eff_amnt@ 1.0 gen normalize-slider-cb 100 ) ) add-sliders ( sl ) gen swap eff_sliders! gen #f add-target then gen eff_dialog@ activate-dialog ; set-current : make-normalize-dialog ( name -- prc1 prc2; child self -- prc; self -- ) ( name ) make-base-effects { gen } gen 1.0 eff_amnt! gen post-normalize-dialog ( prc1 ) 1 proc-create gen , ( prc2 ) does> { child self -- prc; self -- } 0 proc-create self @ ( gen ) , child , ( prc ) does> { self -- } self @ { gen } self cell+ @ ( child ) "%s (%.2f)" #( gen eff_label@ gen eff_amnt@ ) string-format change-label ; previous \ === Gate (gate set by gate-amount) === hide : gate-ok-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } self @ { gen } selected-sound sync { snc } snc 0> if all-chans each { lst } lst 0 array-ref { snd } snd sync snc = if lst 1 array-ref { chn } gen eff_amnt@ dup f* gen eff_size@ snd chn effects-squelch-channel drop then end-each else gen eff_amnt@ dup f* gen eff_size@ #f #f effects-squelch-channel drop then ; : gate-reset-cb { gen -- prc; w c i self -- } 3 proc-create gen , gen eff_amnt@ , ( prc ) does> { w c info self -- } self @ { gen } self cell+ @ { init } gen init eff_amnt! gen eff_sliders@ 0 array-ref init 1000.0 set-slider-value ; : gate-slider-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } w info 1000.0 get-slider-value { val } self @ ( gen ) val eff_amnt! ; 'snd-motif provided? [if] : gate-omit-cb <{ w gen info -- }> gen info Fset eff_omit_silence! ; : post-gate-dialog ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } self @ { gen } gen eff_dialog@ widget? unless gen eff_label@ gen gate-ok-cb gen eff_label@ "\ Move the slider to change the gate intensity. \ Higher values gate more of the sound." help-cb gen gate-reset-cb #f make-effect-dialog { d } gen d eff_dialog! d #( #( "gate" 0.0 gen eff_amnt@ 0.1 gen gate-slider-cb 1000 ) ) add-sliders ( sl ) gen swap eff_sliders! "Omit silence" FXmStringCreateLocalized { s1 } "Omit silence" FxmToggleButtonWidgetClass gen eff_sliders@ 0 array-ref FXtParent #( FXmNbackground basic-color FXmNvalue gen eff_omit_silence@ if 1 else 0 then FXmNlabelString s1 ) undef FXtCreateManagedWidget ( toggle ) FXmNvalueChangedCallback <'> gate-omit-cb gen FXtAddCallback drop s1 FXmStringFree drop then gen eff_dialog@ activate-dialog ; [else] : gate-omit-cb <{ w gen -- }> w FGTK_TOGGLE_BUTTON Fgtk_toggle_button_get_active ( sl ) gen swap eff_omit_silence! ; : post-gate-dialog ( gen -- prc; w d self -- ) 2 proc-create swap , ( prc ) does> { w d self -- } self @ { gen } gen eff_dialog@ widget? unless gen eff_label@ gen gate-ok-cb gen eff_label@ " Move the slider to change the gate intensity. \ Higher values gate more of the sound." help-cb gen gate-reset-cb #f make-effect-dialog { d } gen d eff_dialog! d #( #( "gate" 0.0 gen eff_amnt@ 0.1 gen gate-slider-cb 1000 ) ) add-sliders ( sl ) gen swap eff_sliders! "Omit silence" Fgtk_check_button_new_with_label { tog } gen eff_dialog@ FGTK_DIALOG Fgtk_dialog_get_content_area FGTK_BOX tog #f #f 4 Fgtk_box_pack_start drop tog Fgtk_widget_show drop tog "clicked" <'> gate-omit-cb gen Fg_signal_connect drop then gen eff_dialog@ activate-dialog ; [then] set-current : make-gate-dialog ( name -- prc1 prc2; child self -- prc; self -- ) ( name ) make-base-effects { gen } gen 0.01 eff_amnt! gen 128 eff_size! gen #f eff_omit_silence! gen post-gate-dialog ( prc1 ) 1 proc-create gen , ( prc2 ) does> ( child self -- prc; self -- ) { child self } 0 proc-create self @ ( gen ) , child , ( prc ) does> { self -- } self @ { gen } self cell+ @ ( child ) "%s (%.4f)" #( gen eff_label@ gen eff_amnt@ ) string-format change-label ; previous \ === DELAY EFFECTS === \ === Echo (controlled by delay-time and echo-amount) === hide : echo-func-cb ( gen -- prc; samps self -- prc; inval self -- res ) 1 proc-create swap , ( prc ) does> { samps self -- prc } self @ { gen } gen eff_delay@ #f srate f* f>s make-delay { del } 1 proc-create 0 , samps , del , gen , ( prc ) does> { inval self -- res } self @ 1+ dup self ! { samp } self 1 cells + @ { samps } self 2 cells + @ { del } self 3 cells + @ { gen } del dup 0.0 tap samp samps <= if inval f+ then gen eff_amnt@ f* 0.0 delay inval f+ ; : echo-origin-cb ( gen -- prc; target samps self -- name origin ) 2 proc-create swap , ( prc ) does> { target samps self -- name origin } self @ { gen } "effects-echo" "%s %s %s" #( target 'sound = if #f else samps then gen eff_delay@ gen eff_amnt@ ) string-format ; : echo-ok-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } self @ { gen } gen echo-func-cb gen eff_target@ gen echo-origin-cb gen eff_trunc@ if #f else 4.0 gen eff_delay@ f* then map-chan-over-target-with-sync ; : echo-reset-cb { gen -- prc; w c i self -- } 3 proc-create gen , gen eff_amnt@ , gen eff_delay@ , ( prc ) does> { w c info self -- } self @ { gen } self 1 cells + @ { init-echo } self 2 cells + @ { init-delay } gen init-echo eff_amnt! gen init-delay eff_delay! gen eff_sliders@ 0 array-ref init-delay 100.0 set-slider-value gen eff_sliders@ 1 array-ref init-echo 100.0 set-slider-value ; : echo-delay-slider-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } w info 100.0 get-slider-value { val } self @ ( gen ) val eff_delay! ; : echo-amount-slider-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } w info 100.0 get-slider-value { val } self @ ( gen ) val eff_amnt! ; : post-echo-dialog ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } self @ { gen } gen eff_dialog@ widget? unless gen eff_label@ gen echo-ok-cb gen eff_label@ "\ The sliders change the delay time and echo amount." help-cb gen echo-reset-cb gen general-target-cb make-effect-dialog { d } gen d eff_dialog! d #( #( "delay time" 0.0 gen eff_delay@ 2.0 gen echo-delay-slider-cb 100 ) #( "echo amount" 0.0 gen eff_amnt@ 1.0 gen echo-amount-slider-cb 100 ) ) add-sliders ( sl ) gen swap eff_sliders! gen <'> truncate-cb add-target then gen eff_dialog@ activate-dialog ; set-current : make-echo-dialog ( name -- prc1 prc2; child self -- prc; self -- ) ( name ) make-base-effects { gen } gen 0.5 eff_delay! gen 0.2 eff_amnt! gen post-echo-dialog ( prc1 ) 1 proc-create gen , ( prc2 ) does> { child self -- prc; self -- } 0 proc-create self @ ( gen ) , child , ( prc ) does> { self -- } self @ { gen } self cell+ @ ( child ) "%s (%.2f %.2f)" #( gen eff_label@ gen eff_delay@ gen eff_amnt@ ) string-format change-label ; previous \ === Filtered Echo === hide : flecho-func-cb ( gen -- prc; samps self -- prc; inval self -- res ) 1 proc-create swap , ( prc ) does> { samps self -- prc } self @ { gen } :order 4 :xcoeffs vct( 0.125 0.25 0.25 0.125 ) make-fir-filter { flt } gen eff_delay@ #f srate f* fround->s make-delay { del } 1 proc-create 0 , samps , flt , del , gen eff_amnt@ , ( prc ) does> { inval self -- res } self @ 1+ dup self ! { samp } self 1 cells + @ { samps } self 2 cells + @ { flt } self 3 cells + @ { del } self 4 cells + @ { scl } del flt del 0.0 tap samp samps <= if inval f+ then scl f* fir-filter delay inval f+ ; : flecho-origin-cb ( gen -- prc; target samps self -- name origin ) 2 proc-create swap , ( prc ) does> { target samps self -- name origin } self @ { gen } "effects-flecho" "%s %s %s" #( gen eff_amnt@ gen eff_delay@ target 'sound = if #f else samps then ) string-format ; : flecho-ok-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } self @ { gen } gen flecho-func-cb gen eff_target@ gen flecho-origin-cb gen eff_trunc@ if #f else 4.0 gen eff_delay@ f* then map-chan-over-target-with-sync ; : flecho-reset-cb { gen -- prc; w c i self -- } 3 proc-create gen , gen eff_amnt@ , gen eff_delay@ , ( prc ) does> { w c info self -- } self @ { gen } self 1 cells + @ { init-scaler } self 2 cells + @ { init-delay } gen init-scaler eff_amnt! gen init-delay eff_delay! gen eff_sliders@ 0 array-ref init-scaler 100.0 set-slider-value gen eff_sliders@ 1 array-ref init-delay 100.0 set-slider-value ; : post-flecho-dialog ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } self @ { gen } gen eff_dialog@ widget? unless gen eff_label@ gen flecho-ok-cb gen eff_label@ "\ Move the sliders to set the filter scaler \ and the delay time in seconds." help-cb gen flecho-reset-cb gen general-target-cb make-effect-dialog { d } gen d eff_dialog! d #( #( "filter scaler" 0.0 gen eff_amnt@ 1.0 gen echo-amount-slider-cb 100 ) #( "delay time (secs)" 0.0 gen eff_delay@ 3.0 gen echo-delay-slider-cb 100 ) ) add-sliders ( sl ) gen swap eff_sliders! gen <'> truncate-cb add-target then gen eff_dialog@ activate-dialog ; set-current : make-flecho-dialog ( name -- prc1 prc2; child self -- prc; self -- ) ( name ) make-base-effects { gen } gen 0.9 eff_delay! gen 0.5 eff_amnt! gen post-flecho-dialog ( prc1 ) 1 proc-create gen , ( prc2 ) does> { child self -- prc; self -- } 0 proc-create self @ ( gen ) , child , ( prc ) does> { self -- } self @ { gen } self cell+ @ ( child ) "%s (%.2f %.2f)" #( gen eff_label@ gen eff_amnt@ gen eff_delay@ ) string-format change-label ; previous \ === Modulated Echo === hide : zecho-func-cb ( gen -- prc; samps self -- prc; inval self -- res ) 1 proc-create swap , ( prc ) does> { samps self -- prc } self @ { gen } gen eff_freq@ make-oscil { os } gen eff_delay@ #f srate f* fround->s { len } :size len :max-size len gen eff_amp@ f>s 1+ + make-delay { del } 1 proc-create ( prc ) 0 , samps , os , del , gen eff_scl@ , gen eff_amp@ , does> { inval self -- res } self @ { samp } 1 self +! ( samp++ ) self 1 cells + @ { samps } self 2 cells + @ { os } self 3 cells + @ { del } self 4 cells + @ { scl } self 5 cells + @ { amp } del ( del-gen ) del 0.0 tap samp samps < if inval f+ then scl f* ( input ) os 0.0 0.0 oscil amp f* ( pm ) delay inval f+ ; : zecho-origin-cb ( gen -- prc; target samps self -- name origin ) 2 proc-create swap , ( prc ) does> { target samps self -- name origin } self @ { gen } "effects-zecho" "%s %s %s %s %s" #( gen eff_scl@ gen eff_delay@ gen eff_freq@ gen eff_amp@ target 'sound = if #f else samps then ) string-format ; : zecho-ok-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } self @ { gen } gen zecho-func-cb gen eff_target@ gen zecho-origin-cb gen eff_trunc@ if #f else 4.0 gen eff_delay@ f* then map-chan-over-target-with-sync ; : zecho-reset-cb { gen -- prc; w c i self -- } 3 proc-create ( prc ) gen , gen eff_scl@ , gen eff_delay@ , gen eff_freq@ , gen eff_amp@ , does> { w c info self -- } self @ { gen } self 1 cells + @ { init-scaler } self 2 cells + @ { init-delay } self 3 cells + @ { init-freq } self 4 cells + @ { init-amp } gen init-scaler eff_scl! gen init-delay eff_delay! gen init-freq eff_freq! gen init-amp eff_amp! gen eff_sliders@ 0 array-ref init-scaler 100.0 set-slider-value gen eff_sliders@ 1 array-ref init-delay 100.0 set-slider-value gen eff_sliders@ 2 array-ref init-freq 100.0 set-slider-value gen eff_sliders@ 3 array-ref init-amp 100.0 set-slider-value ; : zecho-del-slider-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } w info 100.0 get-slider-value self { val } @ ( gen ) val eff_delay! ; : post-zecho-dialog ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } self @ { gen } gen eff_dialog@ widget? unless gen eff_label@ gen zecho-ok-cb gen eff_label@ " Move the sliders to set the echo scaler, \ the delay time in seconds, the modulation frequency, \ and the echo amplitude." help-cb gen zecho-reset-cb gen general-target-cb make-effect-dialog { d } gen d eff_dialog! d #( #( "echo scaler" 0.0 gen eff_scl@ 1.0 gen scaler-slider-cb 100 ) #( "delay time (secs)" 0.0 gen eff_delay@ 3.0 gen zecho-del-slider-cb 100 ) #( "modulatio frequency" 0.0 gen eff_freq@ 100.0 gen frequency-slider-cb 100 ) #( "modulatio amplitude" 0.0 gen eff_amp@ 100.0 gen amplitude-slider-cb 100 ) ) add-sliders ( sl ) gen swap eff_sliders! gen <'> truncate-cb add-target then gen eff_dialog@ activate-dialog ; set-current : make-zecho-dialog ( name -- prc1 prc2; child self -- prc; self -- ) ( name ) make-base-effects { gen } gen 0.50 eff_scl! gen 0.75 eff_delay! gen 6.00 eff_freq! gen 10.0 eff_amp! gen post-zecho-dialog ( prc1 ) 1 proc-create gen , ( prc2 ) does> { child self -- prc; self -- } 0 proc-create self @ ( gen ) , child , ( prc ) does> { self -- } self @ { gen } self cell+ @ ( child ) "%s (%.2f %.2f %.2f %.2f)" #( gen eff_label@ gen eff_scl@ gen eff_delay@ gen eff_freq@ gen eff_amp@ ) string-format change-label ; previous \ === FILTER EFFECTS === \ === Butterworth band-pass filter === hide : bp-ok-cb ( gen -- prc; w c i self -- x ) 3 proc-create swap , ( prc ) does> { w c info self -- x } self @ { gen } gen eff_freq@ gen eff_bp_bw@ make-butter-band-pass { flt } gen eff_target@ 'sound = if "%s %s 0 #f effects-bbp" #( gen eff_freq@ gen eff_bp_bw@ ) string-format { origin } flt #f #f #f #f origin filter-sound else gen eff_target@ 'selection = if flt #f #f filter-selection else plausible-mark-samples { pts } pts 0 array-ref { bg } pts 1 array-ref bg - 1+ { nd } "%s %s %s %s effects-bbp" #( gen eff_freq@ gen eff_bp_bw@ bg nd ) string-format { origin } flt bg nd #f #f #f #f origin clm-channel then then ; : bp-reset-cb { gen -- prc; w c i self -- } 3 proc-create gen , gen eff_freq@ , gen eff_bp_bw@ , ( prc ) does> { w c info self -- } self @ { gen } self 1 cells + @ { init-freq } self 2 cells + @ { init-bw } gen init-freq eff_freq! gen init-bw eff_bp_bw! gen eff_sliders@ 0 array-ref 20.0 init-freq 22050.0 scale-log->linear 1.0 set-slider-value gen eff_sliders@ 1 array-ref init-bw 1.0 set-slider-value ; : bp-bw-slider-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } w info 1.0 get-slider-value { val } self @ ( gen ) val eff_bp_bw! ; : post-band-pass-dialog ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> ( w c i self -- ) { w c info self } self @ { gen } gen eff_dialog@ widget? unless gen eff_label@ gen bp-ok-cb gen eff_label@ "\ Butterworth band-pass filter. \ Move the sliders to change the center frequency and bandwidth." help-cb gen bp-reset-cb gen general-target-cb make-effect-dialog { d } gen d eff_dialog! d #( #( "center frequency" 20.0 gen eff_freq@ 22050.0 gen log-freq-slider-cb 1 'log ) #( "bandwidth" 0 gen eff_bp_bw@ 1000 gen bp-bw-slider-cb 1 ) ) add-sliders ( sl ) gen swap eff_sliders! gen #f add-target then gen eff_dialog@ activate-dialog ; set-current : make-band-pass-dialog ( name -- prc1 prc2; child self -- prc; self -- ) ( name) make-base-effects { gen } gen 1000.0 eff_freq! gen 100 eff_bp_bw! gen post-band-pass-dialog ( prc1 ) 1 proc-create gen , ( prc2 ) does> { child self -- prc; self -- } 0 proc-create self @ ( gen ) , child , ( prc ) does> { self -- } self @ { gen } self cell+ @ ( child ) "%s (%.2f %d)" #( gen eff_label@ gen eff_freq@ gen eff_bp_bw@ ) string-format change-label ; previous \ === Butterworth band-reject (notch) filter === hide : br-ok-cb ( gen -- prc; w c i self -- x ) 3 proc-create swap , ( prc ) does> { w c info self -- x } self @ { gen } gen eff_freq@ gen eff_notch_bw@ make-butter-band-reject { flt } gen eff_target@ 'sound = if "%s %s 0 #f effects-bbr" #( gen eff_freq@ gen eff_notch_bw@ ) string-format { origin } flt #f #f #f #f origin filter-sound else gen eff_target@ 'selection = if flt #f #f filter-selection else plausible-mark-samples { pts } pts 0 array-ref { bg } pts 1 array-ref bg - 1+ { nd } "%s %s %s %s effects-bbp" #( gen eff_freq@ gen eff_notch_bw@ bg nd ) string-format { orig } flt bg nd #f #f #f #f orig clm-channel then then ; : br-reset-cb { gen -- prc; w c i self -- } 3 proc-create gen , gen eff_freq@ , gen eff_notch_bw@ , ( prc ) does> { w c info self -- } self @ { gen } self 1 cells + @ { init-freq } self 2 cells + @ { init-bw } gen init-freq eff_freq! gen init-bw eff_notch_bw! gen eff_sliders@ 0 array-ref 20.0 init-freq 22050.0 scale-log->linear 1.0 set-slider-value gen eff_sliders@ 1 array-ref init-bw 1.0 set-slider-value ; : br-bw-slider-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } w info 1.0 get-slider-value { val } self @ ( gen ) val eff_notch_bw! ; : post-notch-dialog ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } self @ { gen } gen eff_dialog@ widget? unless gen eff_label@ gen br-ok-cb gen eff_label@ "\ Butterworth band-reject filter. \ Move the sliders to change the center frequency and bandwidth." help-cb gen br-reset-cb gen general-target-cb make-effect-dialog { d } gen d eff_dialog! d #( #( "center frequency" 20.0 gen eff_freq@ 22050.0 gen log-freq-slider-cb 1 'log ) #( "bandwidth" 0 gen eff_notch_bw@ 1000 gen br-bw-slider-cb 1 ) ) add-sliders ( sl ) gen swap eff_sliders! gen #f add-target then gen eff_dialog@ activate-dialog ; set-current : make-notch-dialog ( name -- prc1 prc2; child self -- prc; self -- ) ( name ) make-base-effects { gen } gen 100.0 eff_freq! gen 100 eff_notch_bw! gen post-notch-dialog ( prc1 ) 1 proc-create gen , ( prc2 ) does> { child self -- prc; self -- } 0 proc-create self @ ( gen ) , child , ( prc ) does> { self -- } self @ { gen } self cell+ @ ( child ) "%s (%.2f %d)" #( gen eff_label@ gen eff_freq@ gen eff_notch_bw@ ) string-format change-label ; previous \ === Butterworth high-pass filter === hide : hp-ok-cb ( gen -- prc; w c i self -- x ) 3 proc-create swap , ( prc ) does> { w c info self -- x } self @ { gen } gen eff_freq@ make-butter-high-pass { flt } gen eff_target@ 'sound = if "%s 0 #f effects-bhp" #( gen eff_freq@ ) string-format { origin } flt #f #f #f #f origin filter-sound else gen eff_target@ 'selection = if flt #f #f filter-selection else plausible-mark-samples { pts } pts 0 array-ref { bg } pts 1 array-ref bg - 1+ { nd } "%s %s %s effects-bhp" #( gen eff_freq@ bg nd ) string-format { origin } flt bg nd #f #f #f #f origin clm-channel then then ; : hp-reset-cb { gen -- prc; w c i self -- } 3 proc-create gen , gen eff_freq@ , ( prc ) does> { w c info self -- } self @ { gen } self cell+ @ { init-freq } gen init-freq eff_freq! gen eff_sliders@ 0 array-ref 20.0 init-freq 22050.0 scale-log->linear 1.0 set-slider-value ; : post-high-pass-dialog ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } self @ { gen } gen eff_dialog@ widget? unless gen eff_label@ gen hp-ok-cb gen eff_label@ "\ Butterworth high-pass filter. \ Move the slider to change the high-pass cutoff frequency." help-cb gen hp-reset-cb gen general-target-cb make-effect-dialog { d } gen d eff_dialog! d #( #( "high-pass cutoff frequency" 20.0 gen eff_freq@ 22050.0 gen log-freq-slider-cb 1 'log ) ) add-sliders ( sl ) gen swap eff_sliders! gen #f add-target then gen eff_dialog@ activate-dialog ; set-current : make-high-pass-dialog ( name -- prc1 prc2; child self -- prc; self -- ) ( name ) make-base-effects { gen } gen 100.0 eff_freq! gen post-high-pass-dialog ( prc1 ) 1 proc-create gen , ( prc2 ) does> { child self -- prc; self -- } 0 proc-create self @ ( gen ) , child , ( prc ) does> { self -- } self @ { gen } self cell+ @ ( child ) "%s (%.2f)" #( gen eff_label@ gen eff_freq@ ) string-format change-label ; previous \ === Butterworth low-pass filter === hide : lp-ok-cb ( gen -- prc; w c i self -- x ) 3 proc-create swap , ( prc ) does> { w c info self -- x } self @ { gen } gen eff_freq@ make-butter-low-pass { flt } gen eff_target@ 'sound = if "%s 0 #f effects-blp" gen eff_freq@ string-format { origin } flt #f #f #f #f origin filter-sound else gen eff_target@ 'selection = if flt #f #f filter-selection else plausible-mark-samples { pts } pts 0 array-ref { bg } pts 1 array-ref bg - 1+ { nd } "%s %s %s effects-blp" #( gen eff_freq@ bg nd ) string-format { origin } flt bg nd #f #f #f #f origin clm-channel then then ; : lp-reset-cb { gen -- prc; w c i self -- } 3 proc-create gen , gen eff_freq@ , ( prc ) does> { w c info self -- } self @ { gen } self cell+ @ { init-freq } gen init-freq eff_freq! gen eff_sliders@ 0 array-ref 20.0 init-freq 22050.0 scale-log->linear 1.0 set-slider-value ; : post-low-pass-dialog ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } self @ { gen } gen eff_dialog@ widget? unless gen eff_label@ gen lp-ok-cb gen eff_label@ "\ Butterworth low-pass filter. \ Move the slider to change the low-pass cutoff frequency." help-cb gen lp-reset-cb gen general-target-cb make-effect-dialog { d } gen d eff_dialog! d #( #( "low-pass cutoff frequency" 20.0 gen eff_freq@ 22050.0 gen log-freq-slider-cb 1 'log ) ) add-sliders ( sl ) gen swap eff_sliders! gen #f add-target then gen eff_dialog@ activate-dialog ; set-current : make-low-pass-dialog ( name -- prc1 prc2; child self -- prc; self -- ) ( name ) make-base-effects { gen } gen 1000.0 eff_freq! gen post-low-pass-dialog ( prc1 ) 1 proc-create gen , ( prc2 ) does> { child self -- prc; self -- } 0 proc-create self @ ( gen ) , child , ( prc ) does> { self -- } self @ { gen } self cell+ @ ( child ) "%s (%.2f)" #( gen eff_label@ gen eff_freq@ ) string-format change-label ; previous \ === Comb filter === hide : comb-func-cb ( gen -- prc; samps self -- prc ) 1 proc-create swap , ( prc ) does> { samps self -- prc } self @ { gen } gen eff_scl@ gen eff_size@ comb-filter ; : comb-origin-cb ( gen -- prc; target samps self -- name origin ) 2 proc-create swap , ( prc ) does> { target samps self -- name origin } self @ { gen } "effects-comb-filter" "%s %s" #( gen eff_scl@ gen eff_size@ ) string-format ; : comb-ok-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } self @ { gen } gen comb-func-cb gen eff_target@ gen comb-origin-cb #f map-chan-over-target-with-sync ; : comb-reset-cb { gen -- prc; w c i self -- } 3 proc-create gen , gen eff_scl@ , gen eff_size@ , ( prc ) does> { w c info self -- } self @ { gen } self 1 cells + @ { init-scaler } self 2 cells + @ { init-size } gen init-scaler eff_scl! gen init-size eff_size! gen eff_sliders@ 0 array-ref init-scaler 100.0 set-slider-value gen eff_sliders@ 1 array-ref init-size 1.0 set-slider-value ; : post-comb-dialog ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } self @ { gen } gen eff_dialog@ widget? unless gen eff_label@ gen comb-ok-cb gen eff_label@ "\ Move the slider to change the comb scaler and size." help-cb gen comb-reset-cb gen general-target-cb make-effect-dialog { d } gen d eff_dialog! d #( #( "scaler" 0.0 gen eff_scl@ 1.0 gen scaler-slider-cb 100 ) #( "size" 0 gen eff_size@ 100 gen size-slider-cb 1 ) ) add-sliders ( sl ) gen swap eff_sliders! gen #f add-target then gen eff_dialog@ activate-dialog ; set-current : make-comb-dialog ( name -- prc1 prc2; child self -- prc; self -- ) ( name ) make-base-effects { gen } gen 0.1 eff_scl! gen 50 eff_size! gen post-comb-dialog ( prc1 ) 1 proc-create gen , ( prc2 ) does> { child self -- prc; self -- } 0 proc-create self @ ( gen ) , child , ( prc ) does> { self -- } self @ { gen } self cell+ @ ( child ) "%s (%.2f %d)" #( gen eff_label@ gen eff_scl@ gen eff_size@ ) string-format change-label ; previous \ === Comb-chord filter === hide : cc-func-cb ( gen -- prc; samps self -- prc ) 1 proc-create swap , ( prc ) does> { samps self -- prc } self @ { gen } gen eff_scl@ gen eff_size@ gen eff_amp@ comb-chord ; : cc-origin-cb ( gen -- prc; target samps self -- name origin ) 2 proc-create swap , ( prc ) does> { target samps self -- name origin } self @ { gen } "effects-comb-chord" "%s %s %s" #( gen eff_scl@ gen eff_size@ gen eff_amp@ ) string-format ; : cc-ok-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } self @ { gen } gen cc-func-cb gen eff_target@ gen cc-origin-cb #f map-chan-over-target-with-sync ; : cc-reset-cb { gen -- prc; w c i self -- } 3 proc-create ( prc ) gen , gen eff_scl@ , gen eff_size@ , gen eff_amp@ , does> { w c info self -- } self @ { gen } self 1 cells + @ { init-scaler } self 2 cells + @ { init-size } self 3 cells + @ { init-amp } gen init-scaler eff_scl! gen init-size eff_size! gen init-amp eff_amp! gen eff_sliders@ 0 array-ref init-scaler 100.0 set-slider-value gen eff_sliders@ 1 array-ref init-size 1.0 set-slider-value gen eff_sliders@ 2 array-ref init-amp 100.0 set-slider-value ; : post-cc-dialog ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } self @ { gen } gen eff_dialog@ widget? unless gen eff_label@ gen cc-ok-cb gen eff_label@ "\ Creates chords by using filters at harmonically related sizes. \ Move the sliders to set the comb chord parameters." help-cb gen cc-reset-cb gen general-target-cb make-effect-dialog { d } gen d eff_dialog! d #( #( "chord scaler" 0.0 gen eff_scl@ 1.0 gen scaler-slider-cb 100 ) #( "chord size" 0 gen eff_size@ 100 gen size-slider-cb 1 ) #( "amplitude" 0.0 gen eff_amp@ 1.0 gen amplitude-slider-cb 100 ) ) add-sliders ( sl ) gen swap eff_sliders! gen #f add-target then gen eff_dialog@ activate-dialog ; set-current : make-comb-chord-dialog ( name -- prc1 prc2; child self -- prc; self -- ) ( name ) make-base-effects { gen } gen 0.95 eff_scl! gen 60 eff_size! gen 0.3 eff_amp! gen post-cc-dialog ( prc1 ) 1 proc-create gen , ( prc2 ) does> { child self -- prc; self -- } 0 proc-create self @ ( gen ) , child , ( prc ) does> { self -- } self @ { gen } self cell+ @ ( child ) "%s (%.2f %d %.2f)" #( gen eff_label@ gen eff_scl@ gen eff_size@ gen eff_amp@ ) string-format change-label ; previous \ === Moog filter === hide : moog-func-cb ( gen -- prc; samps self -- prc ) 1 proc-create swap , ( prc ) does> { samps self -- prc } self @ { gen } gen eff_freq@ gen eff_moog_reson@ moog ; : moog-origin-cb ( gen -- prc; target samps self -- name origin ) 2 proc-create swap , ( prc ) does> { target samps self -- name origin } self @ { gen } "effects-moog" "%s %s" #( gen eff_freq@ gen eff_moog_reson@ ) string-format ; : moog-ok-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } self @ { gen } gen moog-func-cb gen eff_target@ gen moog-origin-cb #f map-chan-over-target-with-sync ; : moog-reset-cb { gen -- prc; w c i self -- } 3 proc-create gen , gen eff_freq@ , gen eff_moog_reson@ , ( prc ) does> { w c info self -- } self @ { gen } self 1 cells + @ { init-freq } self 2 cells + @ { init-res } gen init-freq eff_freq! gen init-res eff_moog_reson! gen eff_sliders@ 0 array-ref 20.0 init-freq 22050.0 scale-log->linear 1.0 set-slider-value gen eff_sliders@ 1 array-ref init-res 100.0 set-slider-value ; : moog-res-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } w info 100.0 get-slider-value { val } self @ ( gen ) val eff_moog_reson! ; : post-moog-dialog ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } self @ { gen } gen eff_dialog@ widget? unless gen eff_label@ gen moog-ok-cb gen eff_label@ "\ Moog-style 4-pole lowpass filter \ with 24db/oct rolloff and variable resonance. \ Move the sliders to set the filter \ cutoff frequency and resonance." help-cb gen moog-reset-cb gen general-target-cb make-effect-dialog { d } gen d eff_dialog! d #( #( "cutoff frequency" 20.0 gen eff_freq@ 22050.0 gen log-freq-slider-cb 1 'log ) #( "resonanze" 0.0 gen eff_moog_reson@ 1.0 gen moog-res-cb 100 ) ) add-sliders ( sl ) gen swap eff_sliders! gen #f add-target then gen eff_dialog@ activate-dialog ; set-current : make-moog-dialog ( name -- prc1 prc2; child self -- prc; self -- ) ( name ) make-base-effects { gen } gen 10000.0 eff_freq! gen 0.5 eff_moog_reson! gen post-moog-dialog ( prc1 ) 1 proc-create gen , ( prc2 ) does> { child self -- prc; self -- } 0 proc-create self @ ( gen ) , child , ( prc ) does> { self -- } self @ { gen } self cell+ @ ( child ) "%s (%.2f %.2f)" #( gen eff_label@ gen eff_freq@ gen eff_moog_reson@ ) string-format change-label ; previous \ === FREQUENCY EFFECTS === \ === Adaptive saturation === hide : adsat-func-cb ( gen -- prc; samps self -- prc; val self -- res ) 1 proc-create swap , ( prc ) does> { samps self -- prc } self @ { gen } 1 proc-create ( prc ) gen , gen eff_size@ 0.0 make-vct , 0.0 , 0.0 , 0 , does> { val self -- res } self @ { gen } self 1 cells + @ { vals } self 2 cells + @ { mn } self 3 cells + @ { mx } self 4 cells + @ { n } gen eff_size@ n = if vals each { x } vals i x f0>= if mx else mn then vct-set! drop 0.0 self 2 cells + ! ( mn ) 0.0 self 3 cells + ! ( mx ) 0 self 4 cells + ! ( n ) end-each vals else vals n val vct-set! drop val mx f> if val self 3 cells + ! ( mx ) then val mn f< if val self 2 cells + ! ( mn ) then n 1+ self 4 cells + ! ( n++ ) #f then ; : adsat-origin-cb ( gen -- prc; target samps self -- name origin ) 2 proc-create swap , ( prc ) does> { target samps self -- name origin } self @ { gen } "adsat" gen eff_size@ number->string ; : adsat-ok-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } self @ { gen } gen adsat-func-cb gen eff_target@ gen adsat-origin-cb #f map-chan-over-target-with-sync ; : adsat-reset-cb { gen -- prc; w c i self -- } 3 proc-create gen , gen eff_size@ , ( prc ) does> { w c info self -- } self @ { gen } self cell+ @ { init-size } gen init-size eff_size! gen eff_sliders@ 0 array-ref init-size 1.0 set-slider-value ; : post-adsat-dialog ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } self @ { gen } gen eff_dialog@ widget? unless gen eff_label@ gen adsat-ok-cb gen eff_label@ "\ Move the slider to change the saturation scaling factor." help-cb gen adsat-reset-cb gen general-target-cb make-effect-dialog { d } gen d eff_dialog! d #( #( "adaptive saturation size" 0 gen eff_size@ 10 gen size-slider-cb 1 ) ) add-sliders ( sl ) gen swap eff_sliders! gen #f add-target then gen eff_dialog@ activate-dialog ; set-current : make-adsat-dialog ( name -- prc1 prc2; child self -- prc; self -- ) ( name ) make-base-effects { gen } gen 4 eff_size! gen post-adsat-dialog ( prc1 ) 1 proc-create gen , ( prc2 ) does> { child self -- prc; self -- } 0 proc-create self @ ( gen ) , child , ( prc ) does> { self -- } self @ { gen } self cell+ @ ( child ) "%s (%d)" #( gen eff_label@ gen eff_size@ ) string-format change-label ; previous \ === Sample rate conversion (resample) === hide : src-ok-cb ( gen -- prc; w c i self -- x ) 3 proc-create swap , ( prc ) does> { w c info self -- x } self @ { gen } gen eff_target@ 'sound = if gen eff_amnt@ 1.0 undef undef undef src-sound else gen eff_target@ 'selection = if undef selection? if gen eff_amnt@ 1.0 src-selection else "no selection" undef status-report then else "can't apply src between marks yet" undef status-report then then ; : src-reset-cb { gen -- prc; w c i self -- } 3 proc-create gen , gen eff_amnt@ , ( prc ) does> { w c info self -- } self @ { gen } self cell+ @ { init-amount } gen init-amount eff_amnt! gen eff_sliders@ 0 array-ref init-amount 100.0 set-slider-value ; : src-amount-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } w info 100.0 get-slider-value { val } self @ ( gen ) val eff_amnt! ; : post-src-dialog ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } self @ { gen } gen eff_dialog@ widget? unless gen eff_label@ gen src-ok-cb gen eff_label@ "\ Move the slider to change the sample rate. \ Values greater than 1.0 speed up file play, \ negative values reverse it." help-cb gen src-reset-cb gen general-target-cb make-effect-dialog { d } gen d eff_dialog! d #( #( "sample rate" -2.0 gen eff_amnt@ 2.0 gen src-amount-cb 100 ) ) add-sliders ( sl ) gen swap eff_sliders! gen #f add-target then gen eff_dialog@ activate-dialog ; set-current : make-src-dialog ( name -- prc1 prc2; child self -- prc; self -- ) ( name ) make-base-effects { gen } gen 0.0 eff_amnt! gen post-src-dialog ( prc1 ) 1 proc-create gen , ( prc2 ) does> { child self -- prc; self -- } 0 proc-create self @ ( gen ) , child , ( prc ) does> { self -- } self @ { gen } self cell+ @ ( child ) "%s (%.2f)" #( gen eff_label@ gen eff_amnt@ ) string-format change-label ; previous \ === Time and pitch scaling by granular synthesis and sampling rate conversion hide : expsrc-ok-cb ( gen -- prc; w c i self -- x ) 3 proc-create swap , ( prc ) does> { w c info self -- x } self @ { gen } selected-sound { snd } snd save-controls drop snd reset-controls drop gen eff_pitch_scl@ snd set-speed-control drop gen eff_pitch_scl@ gen eff_time_scale@ f* { new-time } new-time 1.0 f<> if #t snd set-expand-control? drop new-time snd set-expand-control drop gen eff_hop_size@ snd set-expand-control-hop drop gen eff_seg_len@ snd set-expand-control-length drop gen eff_ramp_scl@ snd set-expand-control-ramp drop then gen eff_target@ 'marks = if plausible-mark-samples { pts } pts if snd 0 pts 0 array-ref pts 1 array-ref pts 0 array-ref - 1+ apply-controls else "no marks" undef status-report then else snd gen eff_target@ 'sound = if 0 else 2 then undef undef apply-controls then drop snd restore-controls ; : expsrc-reset-cb { gen -- prc; w c i self -- } 3 proc-create ( prc ) gen , gen eff_time_scale@ , gen eff_hop_size@ , gen eff_seg_len@ , gen eff_ramp_scl@ , gen eff_pitch_scl@ , does> { w c info self -- } self @ { gen } self 1 cells + @ { init-time-scale } self 2 cells + @ { init-size } self 3 cells + @ { init-seg-len } self 4 cells + @ { init-ramp-scale } self 5 cells + @ { init-pitch-scale } gen init-time-scale eff_time_scale! gen init-size eff_hop_size! gen init-seg-len eff_seg_len! gen init-ramp-scale eff_ramp_scl! gen init-pitch-scale eff_pitch_scl! gen eff_sliders@ 0 array-ref gen init-time-scale 100.0 set-slider-value gen eff_sliders@ 1 array-ref gen init-size 100.0 set-slider-value gen eff_sliders@ 2 array-ref gen init-seg-len 100.0 set-slider-value gen eff_sliders@ 3 array-ref gen init-ramp-scale 100.0 set-slider-value gen eff_sliders@ 4 array-ref gen init-pitch-scale 100.0 set-slider-value ; : expsrc-ts-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } w info 100.0 get-slider-value { val } self @ ( gen ) val eff_time_scale! ; : expsrc-hs-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } w info 100.0 get-slider-value { val } self @ ( gen ) val eff_hop_size! ; : expsrc-sl-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } w info 100.0 get-slider-value { val } self @ ( gen ) val eff_seg_len! ; : expsrc-rs-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } w info 100.0 get-slider-value { val } self @ ( gen ) val eff_ramp_scl! ; : expsrc-ps-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } w info 100.0 get-slider-value { val } self @ ( gen ) val eff_pitch_scl! ; : post-expsrc-dialog ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } self @ { gen } gen eff_dialog@ widget? unless gen eff_label@ gen expsrc-ok-cb gen eff_label@ "\ Move the slider to change the time/pitch scaling parameter." help-cb gen expsrc-reset-cb gen general-target-cb make-effect-dialog { d } gen d eff_dialog! d #( #( "time scale" 0.0 gen eff_time_scale@ 5.0 gen expsrc-ts-cb 100 ) #( "hop size" 0.0 gen eff_hop_size@ 1.0 gen expsrc-hs-cb 100 ) #( "segment-length" 0.0 gen eff_seg_len@ 0.5 gen expsrc-sl-cb 100 ) #( "ramp scale" 0.0 gen eff_ramp_scl@ 0.5 gen expsrc-rs-cb 100 ) #( "pitch scale" 0.0 gen eff_pitch_scl@ 5.0 gen expsrc-ps-cb 100 ) ) add-sliders ( sl ) gen swap eff_sliders! gen #f add-target then gen eff_dialog@ activate-dialog ; set-current : make-expsrc-dialog ( name -- prc1 prc2; child self -- prc; self -- ) ( name ) make-base-effects { gen } gen 1.00 eff_time_scale! gen 0.05 eff_hop_size! gen 0.15 eff_seg_len! gen 0.50 eff_ramp_scl! gen 1.00 eff_pitch_scl! gen post-expsrc-dialog ( prc1 ) 1 proc-create gen , ( prc2 ) does> { child self -- prc; self -- } 0 proc-create self @ ( gen ) , child , ( prc ) does> { self -- } self @ { gen } self cell+ @ ( child ) "%s (%.2f %.2f)" #( gen eff_label@ gen eff_time_scale@ gen eff_pitch_scl@ ) string-format change-label ; previous \ === Time-varying sample rate conversion (resample) === \ (KSM) hide : src-timevar-ok-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } self @ { gen } gen eff_enved@ xe-envelope gen eff_scl@ scale-envelope { en } gen eff_target@ 'sound = if en 1.0 #f #f #f src-sound drop else gen eff_target@ 'selection = if selected-sound #f selection-member? if en 1.0 src-selection drop else "no selection" undef status-report drop then else plausible-mark-samples { pts } pts if pts 0 array-ref { beg } pts 1 array-ref { end } end beg - { len } :envelope en :length len make-env beg len selected-sound #f #f src-channel drop else "no marks" undef status-report drop then then then ; : src-timevar-reset-cb { gen -- prc; w c i self -- } 3 proc-create gen , gen eff_scl@ , ( prc ) does> { w c info self -- } self @ { gen } self cell+ @ { init } gen init eff_scl! gen eff_enved@ #( 0.0 1.0 1.0 1.0 ) set-xe-envelope gen eff_sliders@ 0 array-ref init 100.0 set-slider-value ; : post-src-timevar-dialog ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } self @ { gen } gen eff_dialog@ widget? unless gen eff_label@ gen src-timevar-ok-cb gen eff_label@ "\ Move the slider to change the src-timevar scaling amount." help-cb gen src-timevar-reset-cb gen general-target-cb make-effect-dialog { d } gen d eff_dialog! d #( #( "Resample factor" 0.0 gen eff_scl@ 10.0 gen scaler-slider-cb 100 ) ) add-sliders ( sl ) gen swap eff_sliders! gen make-enved-widget else gen eff_dialog@ activate-dialog then ; set-current : make-src-timevar-dialog ( name -- prc1 prc2; child self -- prc; self -- ) ( name ) make-base-effects { gen } gen 1.0 eff_scl! gen #f eff_enved! gen post-src-timevar-dialog ( prc1 ) 1 proc-create gen , ( prc2 ) does> { child self -- prc; self -- } 0 proc-create self @ ( gen ) , child , ( prc ) does> { self -- } self @ { gen } self cell+ @ ( child ) "Time-varying sample rate scaling" change-label ; previous \ === MODULATION EFFECTS === \ === Amplitude modulation === hide : am-func-cb ( gen -- prc; samps self -- prc ) 1 proc-create swap , ( prc ) does> { samps self -- prc } self @ { gen } gen eff_amnt@ make-oscil { os } gen eff_enved@ xe-envelope #( 0.0 1.0 1.0 1.0 ) equal? if #f else :envelope gen eff_enved@ xe-envelope :length gen eff_target@ effect-frames 1- make-env then { e } e if os e effects-am-env-cb else os effects-am-cb then ; : am-origin-cb ( gen -- prc; target samps self -- name origin ) 2 proc-create swap , ( prc ) does> { target samps self -- name origin } self @ { gen } "effects-am" "%s %s" #( gen eff_amnt@ gen eff_enved@ xe-envelope #( 0.0 1.0 1.0 1.0 ) equal? if #f else gen eff_enved@ xe-envelope then ) string-format ; : am-ok-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } self @ { gen } gen am-func-cb gen eff_target@ gen am-origin-cb #f map-chan-over-target-with-sync ; : am-reset-cb { gen -- prc; w c i self -- } 3 proc-create gen , gen eff_amnt@ , ( prc ) does> { w c info self -- } self @ { gen } self cell+ @ { init } gen init eff_amnt! gen eff_enved@ #( 0.0 1.0 1.0 1.0 ) set-xe-envelope gen eff_sliders@ 0 array-ref init 1.0 set-slider-value ; : am-slider-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } w info 1.0 get-slider-value { val } self @ ( gen ) val eff_amnt! ; : post-am-effect-dialog ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } self @ { gen } gen eff_dialog@ widget? unless gen eff_label@ gen am-ok-cb gen eff_label@ "\ Move the slider to change the modulation amount." help-cb gen am-reset-cb gen general-target-cb make-effect-dialog { d } gen d eff_dialog! d #( #( "amplitude modulation" 0.0 gen eff_amnt@ 1000.0 gen am-slider-cb 1 ) ) add-sliders ( sl ) gen swap eff_sliders! gen make-enved-widget else gen eff_dialog@ activate-dialog then ; set-current : make-am-effect-dialog ( name -- prc1 prc2; child self -- prc; self -- ) ( name ) make-base-effects { gen } gen 100.0 eff_amnt! gen #f eff_enved! gen post-am-effect-dialog ( prc1 ) 1 proc-create gen , ( prc2 ) does> { child self -- prc; self -- } 0 proc-create self @ ( gen ) , child , ( prc ) does> { self -- } self @ { gen } self cell+ @ ( child ) "%s (%.2f)" #( gen eff_label@ gen eff_amnt@ ) string-format change-label ; previous \ === Ring modulation === hide : rm-func-cb ( gen -- prc; samps self -- prc ) 1 proc-create swap , ( prc ) does> { samps self -- prc } self @ { gen } gen eff_freq@ make-oscil { os } gen eff_enved@ xe-envelope #( 0.0 1.0 1.0 1.0 ) equal? if #f else :envelope gen eff_enved@ xe-envelope :length gen eff_target@ effect-frames 1- make-env then { e } e if os e effects-rm-env-cb else os effects-rm-cb then ; : rm-origin-cb ( gen -- prc; target samps self -- name origin ) 2 proc-create swap , ( prc ) does> { target samps self -- name origin } self @ { gen } "effects-rm" "%s %s" #( gen eff_freq@ gen eff_enved@ xe-envelope #( 0.0 1.0 1.0 1.0 ) equal? if #f else gen eff_enved@ xe-envelope then ) string-format ; : rm-ok-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } self @ { gen } gen rm-func-cb gen eff_target@ gen rm-origin-cb #f map-chan-over-target-with-sync ; : rm-reset-cb { gen -- prc; w c i self -- } 3 proc-create gen , gen eff_freq@ , gen eff_scl@ , ( prc ) does> { w c info self -- } self @ { gen } self 1 cells + @ { init-freq } self 2 cells + @ { init-radians } gen init-freq eff_freq! gen init-radians eff_scl! gen eff_enved@ #( 0.0 1.0 1.0 1.0 ) set-xe-envelope gen eff_sliders@ 0 array-ref init-freq 1.0 set-slider-value gen eff_sliders@ 1 array-ref init-radians 1.0 set-slider-value ; : rm-freq-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } w info 1.0 get-slider-value { val } self @ ( gen ) val eff_freq! ; : rm-radians-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } w info 1.0 get-slider-value { val } self @ ( gen ) val eff_scl! ; : post-rm-effect-dialog ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } self @ { gen } gen eff_dialog@ widget? unless gen eff_label@ gen rm-ok-cb gen eff_label@ "\ Move the slider to change ring modulation parameters." help-cb gen rm-reset-cb gen general-target-cb make-effect-dialog { d } gen d eff_dialog! d #( #( "modulation frequency" 0 gen eff_freq@ 1000 gen rm-freq-cb 1 ) #( "modulation radians" 0 gen eff_scl@ 360 gen rm-radians-cb 1 ) ) add-sliders ( sl ) gen swap eff_sliders! gen make-enved-widget else gen eff_dialog@ activate-dialog then ; set-current : make-rm-effect-dialog ( name -- prc1 prc2; child self -- prc; self -- ) ( name ) make-base-effects { gen } gen 100.0 eff_freq! gen 100.0 eff_scl! gen #f eff_enved! gen post-rm-effect-dialog ( prc1 ) 1 proc-create gen , ( prc2 ) does> { child self -- prc; self -- } 0 proc-create self @ ( gen ) , child , ( prc ) does> { self -- } self @ { gen } self cell+ @ ( child ) "%s (%.2f %.2f)" #( gen eff_label@ gen eff_freq@ gen eff_scl@ ) string-format change-label ; previous \ === REVERBS === \ === Reverb from Michael McNabb's Nrev === hide : nrev-ok-cb ( gen -- prc; w c i self -- x ) 3 proc-create swap , ( prc ) does> { w c info self -- x } self @ { gen } selected-sound { snd } snd save-controls drop snd reset-controls drop #t snd set-reverb-control? drop gen eff_amnt@ snd set-reverb-control-scale drop gen eff_rev_filter@ snd set-reverb-control-lowpass drop gen eff_rev_fb@ snd set-reverb-control-feedback drop gen eff_target@ 'marks = if plausible-mark-samples { pts } pts array? if snd 0 pts 0 array-ref pts 1 array-ref pts 0 array-ref - 1+ apply-controls drop else "no marks" undef status-report drop then else snd gen eff_target@ 'sound = if 0 else 2 then undef undef apply-controls drop then snd restore-controls ; : nrev-reset-cb { gen -- prc; w c i self -- } 3 proc-create ( prc ) gen , gen eff_amnt@ , gen eff_rev_filter@ , gen eff_rev_fb@ , does> { w c info self -- } self @ { gen } self 1 cells + @ { init-amount } self 2 cells + @ { init-filter } self 3 cells + @ { init-feedback } gen init-amount eff_amnt! gen init-filter eff_rev_filter! gen init-feedback eff_rev_fb! gen eff_sliders@ 0 array-ref init-amount 100.0 set-slider-value gen eff_sliders@ 1 array-ref init-filter 100.0 set-slider-value gen eff_sliders@ 2 array-ref init-feedback 100.0 set-slider-value ; : nrev-amount-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } w info 100.0 get-slider-value { val } self @ ( gen ) val eff_amnt! ; : nrev-filter-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } w info 100.0 get-slider-value { val } self @ ( gen ) val eff_rev_filter! ; : nrev-feedback-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } w info 100.0 get-slider-value { val } self @ ( gen ) val eff_rev_fb! ; : post-reverb-dialog ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } self @ { gen } gen eff_dialog@ widget? unless gen eff_label@ gen nrev-ok-cb gen eff_label@ "\ Reverberator from Michael McNabb. \ Adds reverberation scaled by reverb amount, lowpass filtering, and feedback. \ Move the sliders to change the reverb parameters." help-cb gen nrev-reset-cb gen general-target-cb make-effect-dialog { d } gen d eff_dialog! d #( #( "reverb amount" 0.0 gen eff_amnt@ 1.00 gen nrev-amount-cb 100 ) #( "reverb filter" 0.0 gen eff_rev_filter@ 1.00 gen nrev-filter-cb 100 ) #( "reverb feedback" 0.0 gen eff_rev_fb@ 1.25 gen nrev-feedback-cb 100 ) ) add-sliders ( sl ) gen swap eff_sliders! gen #f add-target then gen eff_dialog@ activate-dialog ; set-current : make-reverb-dialog ( name -- prc1 prc2; child self -- prc; self -- ) ( name ) make-base-effects { gen } gen 0.10 eff_amnt! gen 0.50 eff_rev_filter! gen 1.09 eff_rev_fb! gen post-reverb-dialog ( prc1 ) 1 proc-create gen , ( prc2 ) does> { child self -- prc; self -- } 0 proc-create self @ ( gen ) , child , ( prc ) does> { self -- } self @ { gen } self cell+ @ ( child ) "%s (%.2f %.2f %.2f)" #( gen eff_label@ gen eff_amnt@ gen eff_rev_filter@ gen eff_rev_fb@ ) string-format change-label ; previous \ === Chowning reverb === hide : jc-func-cb ( gen -- prc; samps self -- prc ) 1 proc-create swap , ( prc ) does> { samps self -- prc } self @ { gen } samps gen eff_rev_vol@ effects-jc-reverb ; : jc-origin-cb ( gen -- prc; target samps self -- name origin ) 2 proc-create swap , ( prc ) does> { target samps self -- name origin } self @ { gen } "effects-jc-reverb-1" gen eff_rev_vol@ number->string ; : jc-ok-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } self @ { gen } gen jc-func-cb gen eff_target@ gen jc-origin-cb gen eff_trunc@ if #f else gen eff_rev_decay@ then map-chan-over-target-with-sync ; : jc-reset-cb { gen -- prc; w c i self -- } 3 proc-create ( prc ) gen , gen eff_rev_decay@ , gen eff_rev_vol@ , does> { w c info self -- } self @ { gen } self 1 cells + @ { init-decay } self 2 cells + @ { init-volume } gen init-decay eff_rev_decay! gen init-volume eff_rev_vol! gen eff_sliders@ 0 array-ref init-decay 100.0 set-slider-value gen eff_sliders@ 1 array-ref init-volume 100.0 set-slider-value ; : jc-decay-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } w info 100.0 get-slider-value { val } self @ ( gen ) val eff_rev_decay! ; : jc-volume-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } w info 100.0 get-slider-value { val } self @ ( gen ) val eff_rev_vol! ; : post-jc-reverb-dialog ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } self @ { gen } gen eff_dialog@ widget? unless gen eff_label@ gen jc-ok-cb gen eff_label@ "\ Nice reverb from John Chowning. \ Move the sliders to set the reverb parameters." help-cb gen jc-reset-cb gen general-target-cb make-effect-dialog { d } gen d eff_dialog! d #( #( "decay duration" 0.0 gen eff_rev_decay@ 10.0 gen jc-decay-cb 100 ) #( "reverb volume" 0.0 gen eff_rev_vol@ 1.00 gen jc-volume-cb 100 ) ) add-sliders ( sl ) gen swap eff_sliders! gen <'> truncate-cb add-target then gen eff_dialog@ activate-dialog ; set-current : make-jc-reverb-dialog ( name -- prc1 prc2; child self -- prc; self -- ) ( name ) make-base-effects { gen } gen 2.0 eff_rev_decay! gen 0.1 eff_rev_vol! gen post-jc-reverb-dialog ( prc1 ) 1 proc-create gen , ( prc2 ) does> { child self -- prc; self -- } 0 proc-create self @ ( gen ) , child , ( prc ) does> { self -- } self @ { gen } self cell+ @ ( child ) "%s (%.2f %.2f)" #( gen eff_label@ gen eff_rev_decay@ gen eff_rev_vol@ ) string-format change-label ; previous \ === Convolution === hide : cnv-ok-cb ( gen -- prc; w c i self -- x ) 3 proc-create swap , ( prc ) does> { w c info self -- x } self @ { gen } gen eff_conv_one@ { snd1 } gen eff_conv_two@ { snd2 } snd1 sound? if snd2 sound? if snd1 gen eff_amp@ snd2 #f effects-cnv else "no such sound two: %S" #( snd2 ) string-format undef status-report then else "no such sound one: %S" #( snd1 ) string-format undef status-report then ; : cnv-reset-cb { gen -- prc; w c i self -- } 3 proc-create ( prc ) gen , gen eff_conv_one@ , gen eff_conv_two@ , gen eff_amp@ , does> { w c info self -- } self @ { gen } self 1 cells + @ { init-one } self 2 cells + @ { init-two } self 3 cells + @ { init-amp } gen init-one eff_conv_one! gen init-two eff_conv_two! gen init-amp eff_amp! gen eff_sliders@ 0 array-ref init-one 1.0 set-slider-value gen eff_sliders@ 1 array-ref init-two 1.0 set-slider-value gen eff_sliders@ 2 array-ref init-amp 100.0 set-slider-value ; : cnv-one-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } w info 1.0 get-slider-value { val } self @ ( gen ) val eff_conv_one! ; : cnv-two-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } w info 1.0 get-slider-value { val } self @ ( gen ) val eff_conv_two! ; : post-convolve-dialog ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } self @ { gen } gen eff_dialog@ widget? unless gen eff_label@ gen cnv-ok-cb gen eff_label@ "\ Very simple convolution. \ Move the sliders to set the reverb parameters the numbers of the soundfiles \ to be convolved and the amount for the amplitude scaler. \ Output will be scaled to floating-point values, \ resulting in very large (but not clipped) amplitudes. \ Use the Normalize amplitude effect to rescale the output. \ The convolution data file typically defines a natural reverberation source, \ and the output from this effect can provide very striking reverb effects. \ You can find convolution data files on sites listed at \ http://www.bright.net/~dlphilp/linux_csound.html under Impulse Response Data." help-cb gen cnv-reset-cb #f make-effect-dialog { d } gen d eff_dialog! d #( #( "impulse response file" 0 gen eff_conv_one@ 24 gen cnv-one-cb 1 ) #( "sound file" 0 gen eff_conv_two@ 24 gen cnv-two-cb 1 ) #( "amplitude" 0.0 gen eff_amp@ 0.10 gen amplitude-slider-cb 100 ) ) add-sliders ( sl ) gen swap eff_sliders! then gen eff_dialog@ activate-dialog ; set-current : make-convolve-dialog ( name -- prc1 prc2; child self -- prc; self -- ) ( name ) make-base-effects { gen } gen 0 eff_conv_one! gen 1 eff_conv_two! gen 0.01 eff_amp! gen post-convolve-dialog ( prc1 ) 1 proc-create gen , ( prc2 ) does> { child self -- prc; self -- } 0 proc-create self @ ( gen ) , child , ( prc ) does> { self -- } self @ { gen } self cell+ @ ( child ) "%s (%d %d %.2f)" #( gen eff_label@ gen eff_conv_one@ gen eff_conv_two@ gen eff_amp@ ) string-format change-label ; previous \ === VARIOUS AND MISCELLANEOUS === \ === Place sound === hide : ps-ok-cb ( gen -- prc; w c i self -- x ) 3 proc-create swap , ( prc ) does> { w c info self -- x } self @ { gen } gen eff_enved@ xe-envelope { e } e #( 0.0 1.0 1.0 1.0 ) equal? if gen eff_m_snd@ gen eff_s_snd@ gen eff_pan_pos@ else gen eff_m_snd@ gen eff_s_snd@ e then effects-place-sound ; : ps-reset-cb { gen -- prc; w c i self -- } 3 proc-create ( prc ) gen , gen eff_m_snd@ , gen eff_s_snd@ , gen eff_pan_pos@ , does> { w c info self -- } self @ { gen } self 1 cells + @ { init-mono } self 2 cells + @ { init-stereo } self 3 cells + @ { init-pos } gen init-mono eff_m_snd! gen init-stereo eff_s_snd! gen init-pos eff_pan_pos! gen eff_enved@ #( 0.0 1.0 1.0 1.0 ) set-xe-envelope gen eff_sliders@ 0 array-ref init-mono 1.0 set-slider-value gen eff_sliders@ 1 array-ref init-stereo 1.0 set-slider-value gen eff_sliders@ 2 array-ref init-pos 1.0 set-slider-value ; : ps-mono-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } w info 1.0 get-slider-value { val } self @ ( gen ) val eff_m_snd! ; : ps-stereo-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } w info 1.0 get-slider-value { val } self @ ( gen ) val eff_s_snd! ; : ps-pos-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } w info 1.0 get-slider-value { val } self @ ( gen ) val eff_pan_pos! ; : post-place-sound-dialog ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } self @ { gen } gen eff_dialog@ widget? unless gen eff_label@ gen ps-ok-cb gen eff_label@ "\ Mixes mono sound into stereo sound field." help-cb gen ps-reset-cb gen general-target-cb make-effect-dialog { d } gen d eff_dialog! d #( #( "mono sound" 0 gen eff_m_snd@ 50 gen ps-mono-cb 1 ) #( "stereo sound" 0 gen eff_s_snd@ 50 gen ps-stereo-cb 1 ) #( "pan position" 0 gen eff_pan_pos@ 90 gen ps-pos-cb 1 ) ) add-sliders ( sl ) gen swap eff_sliders! gen make-enved-widget else gen eff_dialog@ activate-dialog then ; set-current : make-place-sound-dialog ( name -- prc1 prc2; child self -- prc; self -- ) ( name ) make-base-effects { gen } gen 0 eff_m_snd! gen 1 eff_s_snd! gen 45 eff_pan_pos! gen post-place-sound-dialog ( prc1 ) 1 proc-create gen , ( prc2 ) does> { child self -- prc; self -- } 0 proc-create self @ ( gen ) , child , ( prc ) does> { self -- } self @ { gen } self cell+ @ ( child ) "%s (%d %d %d)" #( gen eff_label@ gen eff_m_snd@ gen eff_s_snd@ gen eff_pan_pos@ ) string-format change-label ; previous \ === Insert silence (at cursor, silence-amount in secs) === hide : silence-ok-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } self @ { gen } #f #f #f cursor #f srate gen eff_amnt@ f* f>s #f #f insert-silence drop ; : silence-reset-cb { gen -- prc; w c i self -- } 3 proc-create gen , gen eff_amnt@ , ( prc ) does> { w c info self -- } self @ { gen } self 1 cells + @ { init } gen init eff_amnt! gen eff_sliders@ 0 array-ref init 100.0 set-slider-value ; : silence-amount-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } w info 100.0 get-slider-value { val } self @ ( gen ) val eff_amnt! ; : post-silence-dialog ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } self @ { gen } gen eff_dialog@ widget? unless gen eff_label@ gen silence-ok-cb gen eff_label@ "\ Move the slider to change the number of seconds \ of silence added at the cursor position." help-cb gen silence-reset-cb #f make-effect-dialog { d } gen d eff_dialog! d #( #( "silence" 0.0 gen eff_amnt@ 5.0 gen silence-amount-cb 100 ) ) add-sliders ( sl ) gen swap eff_sliders! then gen eff_dialog@ activate-dialog ; set-current : make-silence-dialog ( name -- prc1 prc2; child self -- prc; self -- ) ( name ) make-base-effects { gen } gen 1.0 eff_amnt! gen post-silence-dialog ( prc1 ) 1 proc-create gen , ( prc2 ) does> { child self -- prc; self -- } 0 proc-create self @ ( gen ) , child , ( prc ) does> { self -- } self @ { gen } self cell+ @ ( child ) "%s (%.2f)" #( gen eff_label@ gen eff_amnt@ ) string-format change-label ; previous \ === Contrast (brightness control) === hide : contrast-ok-cb ( gen -- prc; w c i self -- x ) 3 proc-create swap , ( prc ) does> { w c info self -- x } self @ { gen } #f #f #f maxamp { peak } selected-sound { snd } snd save-controls drop snd reset-controls drop #t snd set-contrast-control? drop gen eff_amnt@ snd set-contrast-control drop peak 1/f snd set-contrast-control-amp drop peak snd #f set-amp-control drop gen eff_target@ 'marks = if plausible-mark-samples { pts } pts if snd 0 pts 0 array-ref pts 1 array-ref pts 0 array-ref - 1+ apply-controls drop else "no marks" undef status-report drop then else snd gen eff_target@ 'sound = if 0 else 2 then 0 undef apply-controls drop then snd restore-controls ; : contrast-reset-cb { gen -- prc; w c i self -- } 3 proc-create gen , gen eff_amnt@ , ( prc ) does> { w c info self -- } self @ { gen } self 1 cells + @ { init } gen init eff_amnt! gen eff_sliders@ 0 array-ref init 100.0 set-slider-value ; : contrast-amount-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } w info 100.0 get-slider-value { val } self @ ( gen ) val eff_amnt! ; : post-contrast-dialog ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } self @ { gen } gen eff_dialog@ widget? unless gen eff_label@ gen contrast-ok-cb gen eff_label@ "\ Move the slider to change the contrast intensity." help-cb gen contrast-reset-cb gen general-target-cb make-effect-dialog { d } gen d eff_dialog! d #( #( "contrast enhancement" 0.0 gen eff_amnt@ 10.0 gen contrast-amount-cb 100 ) ) add-sliders ( sl ) gen swap eff_sliders! gen #f add-target then gen eff_dialog@ activate-dialog ; set-current : make-contrast-dialog ( name -- prc1 prc2; child self -- prc; self -- ) ( name ) make-base-effects { gen } gen 1.0 eff_amnt! gen post-contrast-dialog ( prc1 ) 1 proc-create gen , ( prc2 ) does> { child self -- prc; self -- } 0 proc-create self @ ( gen ) , child , ( prc ) does> { self -- } self @ { gen } self cell+ @ ( child ) "%s (%.2f)" #( gen eff_label@ gen eff_amnt@ ) string-format change-label ; previous \ === Cross synthesis === hide : cs-func-cb ( gen -- prc; samps self -- prc ) 1 proc-create swap , ( prc ) does> { samps self -- prc } self @ { gen } gen eff_cs_snd@ gen eff_amp@ gen eff_size@ gen eff_cs_radius@ effects-cross-synthesis ; : cs-origin-cb ( gen -- prc; target samps self -- name origin ) 2 proc-create swap , ( prc ) does> { target samps self -- name origin } self @ { gen } "effects-cross-synthesis-1" "%s %s %s %s" #( gen eff_cs_snd@ gen eff_amp@ gen eff_size@ gen eff_cs_radius@ ) string-format ; : cs-ok-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } self @ { gen } gen cs-func-cb gen eff_target@ gen cs-origin-cb #f map-chan-over-target-with-sync ; 'snd-motif provided? [if] : cs-set-state ( wid -- ) use-combo-box-for-fft-size if #( FXmNselectedPosition 1 ) FXtVaSetValues else #t #t FXmToggleButtonSetState then drop ; [else] : cs-set-state ( wid -- ) drop ; [then] : cs-reset-cb { gen -- prc; w c i self -- } 3 proc-create ( prc ) gen , gen eff_cs_snd@ , gen eff_amp@ , gen eff_size@ , gen eff_cs_radius@ , does> { w c info self -- } self @ { gen } self 1 cells + @ { init-snd } self 2 cells + @ { init-amp } self 3 cells + @ { init-size } self 4 cells + @ { init-rad } gen init-snd eff_cs_snd! gen init-amp eff_amp! gen init-size eff_size! gen init-rad eff_cs_radius! gen eff_sliders@ 0 array-ref init-snd 1.0 set-slider-value gen eff_sliders@ 1 array-ref init-amp 100.0 set-slider-value gen eff_sliders@ 2 array-ref init-rad 100.0 set-slider-value gen eff_cs_wid@ cs-set-state ; : cs-snd-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } w info 1.0 get-slider-value { val } self @ ( gen ) val eff_cs_snd! ; : cs-rad-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } w info 100.0 get-slider-value { val } self @ ( gen ) val eff_cs_radius! ; 'snd-motif provided? [if] : cs-sel-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } info Fitem_or_text ( selected ) #f FXmCHARSET_TEXT FXmCHARSET_TEXT #f 0 FXmOUTPUT_ALL FXmStringUnparse ( size-as-str ) string->number { val } self @ ( gen ) val eff_size! ; : cs-sel-changed-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w size info self -- } info Fset if self @ ( gen ) size eff_size! then ; : cs-sel-create-sel { gen -- } #( 64 128 256 512 1024 4096 ) { sizes } "FFT size" FXmStringCreateLocalized { s1 } "frame" FxmFrameWidgetClass gen eff_sliders@ 0 array-ref FXtParent #( FXmNborderWidth 1 FXmNshadowType FXmSHADOW_ETCHED_IN FXmNpositionIndex 2 ) undef FXtCreateManagedWidget { frame } "frm" FxmFormWidgetClass frame #( FXmNleftAttachment FXmATTACH_FORM FXmNrightAttachment FXmATTACH_FORM FXmNtopAttachment FXmATTACH_FORM FXmNbottomAttachment FXmATTACH_FORM FXmNbackground basic-color ) undef FXtCreateManagedWidget { frm } use-combo-box-for-fft-size if "FFT size" FxmLabelWidgetClass frm #( FXmNleftAttachment FXmATTACH_FORM FXmNrightAttachment FXmATTACH_NONE FXmNtopAttachment FXmATTACH_FORM FXmNbottomAttachment FXmATTACH_FORM FXmNlabelString s1 FXmNbackground basic-color ) undef FXtCreateManagedWidget { lab } sizes map! *key* number->string FXmStringCreateLocalized end-map { fft-labels } "fftsize" FxmComboBoxWidgetClass frm #( FXmNleftAttachment FXmATTACH_WIDGET FXmNleftWidget lab FXmNrightAttachment FXmATTACH_FORM FXmNtopAttachment FXmATTACH_FORM FXmNbottomAttachment FXmATTACH_FORM FXmNitems fft-labels FXmNitemCount fft-labels length FXmNcomboBoxType FXmDROP_DOWN_COMBO_BOX FXmNbackground basic-color ) undef FXtCreateManagedWidget { combo } gen combo eff_cs_wid! fft-labels each ( s ) FXmStringFree drop end-each combo #( FXmNselectedPosition 1 ) FXtVaSetValues drop combo FXmNselectionCallback gen cs-sel-cb undef FXtAddCallback drop else "rc" FxmRowColumnWidgetClass frm #( FXmNorientation FXmHORIZONTAL FXmNradioBehavior #t FXmNradioAlwaysOne #t FXmNentryClass FxmToggleButtonWidgetClass FXmNisHomogeneous #t FXmNleftAttachment FXmATTACH_FORM FXmNrightAttachment FXmATTACH_FORM FXmNtopAttachment FXmATTACH_FORM FXmNbottomAttachment FXmATTACH_NONE FXmNbackground basic-color ) undef FXtCreateManagedWidget { rc } "FFT size" FxmLabelWidgetClass frm #( FXmNleftAttachment FXmATTACH_FORM FXmNrightAttachment FXmATTACH_FORM FXmNtopAttachment FXmATTACH_WIDGET FXmNtopWidget rc FXmNbottomAttachment FXmATTACH_FORM FXmNlabelString s1 FXmNalignment FXmALIGNMENT_BEGINNING FXmNbackground basic-color ) undef FXtCreateManagedWidget { lab } sizes each { size } size number->string FxmToggleButtonWidgetClass rc #( FXmNbackground basic-color FXmNvalueChangedCallback #( gen cs-sel-changed-cb size ) FXmNset size gen eff_size@ = ) undef FXtCreateManagedWidget { button } size gen eff_size@ = if gen button eff_cs_wid! then end-each then s1 FXmStringFree drop ; [else] : cs-sel-create-sel ( gen -- ) drop ; [then] : post-cross-synth-dialog ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } self @ { gen } gen eff_dialog@ widget? unless gen eff_label@ gen cs-ok-cb gen eff_label@ "\ The sliders set the number of the soundfile to be cross-synthesized, \ the synthesis amplitude, the FFT size, and the radius value." help-cb gen cs-reset-cb gen general-target-cb make-effect-dialog { d } gen d eff_dialog! d #( #( "input sound" 0 gen eff_cs_snd@ 20 gen cs-snd-cb 1 ) #( "amplitude" 0.0 gen eff_amp@ 1.0 gen amplitude-slider-cb 100 ) #( "radius" 0.0 gen eff_cs_radius@ 360.0 gen cs-rad-cb 100 ) ) add-sliders ( sl ) gen swap eff_sliders! gen cs-sel-create-sel gen #f add-target then gen eff_dialog@ activate-dialog ; set-current : make-cross-synth-dialog ( name -- prc1 prc2; child self -- prc; self -- ) ( name ) make-base-effects { gen } gen 1 eff_cs_snd! gen 0.5 eff_amp! gen 128 eff_size! gen 6.0 eff_cs_radius! gen #f eff_cs_wid! gen post-cross-synth-dialog ( prc1 ) 1 proc-create gen , ( prc2 ) does> { child self -- prc; self -- } 0 proc-create self @ ( gen ) , child , ( prc ) does> { self -- } self @ { gen } self cell+ @ ( child ) "%s (%d %.2f %d %.2f)" #( gen eff_label@ gen eff_cs_snd@ gen eff_amp@ gen eff_size@ gen eff_cs_radius@ ) string-format change-label ; previous \ === Flange and phasing === hide : flange-func-cb ( gen -- prc; samps self -- prc; self -- ) 1 proc-create swap , ( prc ) does> { samps self -- prc } self @ { gen } :frequency gen eff_fl_speed@ :amplitude gen eff_amnt@ make-rand-interp { ri } gen eff_fl_time@ #f srate f* fround->s { len } :size len :max-size gen eff_amnt@ 1.0 len f+ f+ f>s make-delay { del } 1 proc-create del , ri , ( prc ) does> { inval self -- res } self @ ( del ) inval self cell+ @ ( ri ) 0.0 rand-interp delay inval f+ 0.75 f* ; : flange-origin-cb ( gen -- prc; target samps self -- name origin ) 2 proc-create swap , ( prc ) does> { target samps self -- name origin } self @ { gen } "effects-flange" "%s %s %s" #( gen eff_amnt@ gen eff_fl_speed@ gen eff_fl_time@ ) string-format ; : flange-ok-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } self @ { gen } gen flange-func-cb gen eff_target@ gen flange-origin-cb #f map-chan-over-target-with-sync ; : flange-reset-cb { gen -- prc; w c i self -- } 3 proc-create ( prc ) gen , gen eff_fl_speed@ , gen eff_amnt@ , gen eff_fl_time@ , does> { w c info self -- } self @ { gen } self 1 cells + @ { init-speed } self 2 cells + @ { init-amount } self 3 cells + @ { init-time } gen init-speed eff_fl_speed! gen init-amount eff_amnt! gen init-time eff_fl_time! gen eff_sliders@ 0 array-ref init-speed 10.0 set-slider-value gen eff_sliders@ 1 array-ref init-amount 10.0 set-slider-value gen eff_sliders@ 2 array-ref init-time 100.0 set-slider-value ; : flange-speed-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } w info 10.0 get-slider-value { val } self @ ( gen ) val eff_fl_speed! ; : flange-amount-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } w info 10.0 get-slider-value { val } self @ ( gen ) val eff_amnt! ; : flange-time-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } w info 100.0 get-slider-value { val } self @ ( gen ) val eff_fl_time! ; : post-flange-dialog ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } self @ { gen } gen eff_dialog@ widget? unless gen eff_label@ gen flange-ok-cb gen eff_label@ "\ Move the slider to change the flange speed, amount, and time." help-cb gen flange-reset-cb gen general-target-cb make-effect-dialog { d } gen d eff_dialog! d #( #( "flange speed" 0.0 gen eff_fl_speed@ 100.0 gen flange-speed-cb 10 ) #( "flange amount" 0.0 gen eff_amnt@ 100.0 gen flange-amount-cb 10 ) #( "flange time" 0.0 gen eff_fl_time@ 1.0 gen flange-time-cb 100 ) ) add-sliders ( sl ) gen swap eff_sliders! gen #f add-target then gen eff_dialog@ activate-dialog ; set-current : make-flange-dialog ( name -- prc1 prc2; child self -- prc; self -- ) ( name ) make-base-effects { gen } gen 2.000 eff_fl_speed! gen 5.000 eff_amnt! gen 0.001 eff_fl_time! gen post-flange-dialog ( prc1 ) 1 proc-create gen , ( prc2 ) does> { child self -- prc; self -- } 0 proc-create self @ ( gen ) , child , ( prc ) does> { self -- } self @ { gen } self cell+ @ ( child ) "%s (%.2f %.2f %.2f)" #( gen eff_label@ gen eff_fl_speed@ gen eff_amnt@ gen eff_fl_time@ ) string-format change-label ; previous \ === Randomize phase === hide : random-phase-cb ( scl -- prc; x self -- res ) 1 proc-create swap , ( prc ) does> { x self -- res } self @ ( scl ) random ; : rp-ok-cb ( gen -- prc; w c i self -- res ) 3 proc-create swap , ( prc ) does> { w c info self -- res } self @ { gen } gen eff_scl@ random-phase-cb { prc } \ edit-list->function needs a usable proc-source-string prc "%s random-phase-cb" gen eff_scl@ string-format proc-source-set! prc #f #f rotate-phase ; : rp-reset-cb { gen -- prc; w c i self -- } 3 proc-create gen , gen eff_scl@ , ( prc ) does> { w c info self -- } self @ { gen } self 1 cells + @ { init } gen init eff_scl! gen eff_sliders@ 0 array-ref init 100.0 set-slider-value ; : post-random-phase-dialog ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } self @ { gen } gen eff_dialog@ widget? unless gen eff_label@ gen rp-ok-cb gen eff_label@ "\ Move the slider to change the randomization amplitude scaler." help-cb gen rp-reset-cb #f make-effect-dialog { d } gen d eff_dialog! d #( #( "amplitude scaler" 0.0 gen eff_scl@ 100.0 gen scaler-slider-cb 100 ) ) add-sliders ( sl ) gen swap eff_sliders! then gen eff_dialog@ activate-dialog ; set-current : make-random-phase-dialog ( name -- prc1 prc2; child self -- prc; self -- ) ( name ) make-base-effects { gen } gen 3.14 eff_scl! gen post-random-phase-dialog ( prc1 ) 1 proc-create gen , ( prc2 ) does> { child self -- prc; self -- } 0 proc-create self @ ( gen ) , child , ( prc ) does> { self -- } self @ { gen } self cell+ @ ( child ) "%s (%.2f)" #( gen eff_label@ gen eff_scl@ ) string-format change-label ; previous \ === Robotize === hide : robotize-ok-cb ( gen -- prc; w c i self -- res ) 3 proc-create swap , ( prc ) does> { w c info self -- res } self @ { gen } gen eff_sr@ gen eff_amp@ gen eff_freq@ \ beg dur follows gen eff_target@ 'sound = if 0 #f #f #f framples else gen eff_target@ 'selection = if #f #f selection-position #f #f selection-framples else plausible-mark-samples { pts } pts if pts 0 array-ref pts 1 array-ref pts 0 array-ref - else 'no-such-mark #( "%s: %s" get-func-name pts ) fth-throw then then then #f #f effects-fp ; : robotize-reset-cb { gen -- prc; w c i self -- } 3 proc-create ( prc ) gen , gen eff_sr@ , gen eff_amp@ , gen eff_freq@ , does> { w c info self -- } self @ { gen } self 1 cells + @ { init-sr } self 2 cells + @ { init-amp } self 3 cells + @ { init-frq } gen init-sr eff_sr! gen init-amp eff_amp! gen init-frq eff_freq! gen eff_sliders@ 0 array-ref init-sr 100.0 set-slider-value gen eff_sliders@ 1 array-ref init-amp 100.0 set-slider-value gen eff_sliders@ 2 array-ref init-frq 100.0 set-slider-value ; : robotize-sam-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } w info 100.0 get-slider-value { val } self @ ( gen ) val eff_sr! ; : post-robotize-dialog ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } self @ { gen } gen eff_dialog@ widget? unless gen eff_label@ gen robotize-ok-cb gen eff_label@ "\ Move the sliders to set the sample rate, \ oscillator amplitude, and oscillator frequency." help-cb gen robotize-reset-cb gen general-target-cb make-effect-dialog { d } gen d eff_dialog! d #( #( "sample rate" 0.0 gen eff_sr@ 2.0 gen robotize-sam-cb 100 ) #( "oscillator amplitude" 0.0 gen eff_amp@ 1.0 gen amplitude-slider-cb 100 ) #( "oscillator frequency" 0.0 gen eff_freq@ 60.0 gen frequency-slider-cb 100 ) ) add-sliders ( sl ) gen swap eff_sliders! gen #f add-target then gen eff_dialog@ activate-dialog ; set-current : make-robotize-dialog ( name -- prc1 prc2; child self -- prc; self -- ) ( name ) make-base-effects { gen } gen 1.0 eff_sr! gen 0.3 eff_amp! gen 20.0 eff_freq! gen post-robotize-dialog ( prc1 ) 1 proc-create gen , ( prc2 ) does> { child self -- prc; self -- } 0 proc-create self @ ( gen ) , child , ( prc ) does> { self -- } self @ { gen } self cell+ @ ( child ) "%s (%.2f %.2f %.2f)" #( gen eff_label@ gen eff_sr@ gen eff_amp@ gen eff_freq@ ) string-format change-label ; previous \ === Rubber sound === hide : rubber-ok-cb ( gen -- prc; w c i self -- res ) 3 proc-create swap , ( prc ) does> { w c info self -- res } self @ ( gen ) eff_factor@ #f #f rubber-sound ; : rubber-reset-cb { gen -- prc; w c i self -- } 3 proc-create gen , gen eff_factor@ , ( prc ) does> { w c info self -- } self @ { gen } self 1 cells + @ { init } gen init eff_factor! gen eff_sliders@ 0 array-ref init 100.0 set-slider-value ; : rubber-factor-cb ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } w info 100.0 get-slider-value { val } self @ ( gen ) val eff_factor! ; : post-rubber-dialog ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } self @ { gen } gen eff_dialog@ widget? unless gen eff_label@ gen rubber-ok-cb gen eff_label@ "\ Stretches or contracts the time of a sound. \ Move the slider to change the stretch factor." help-cb gen rubber-reset-cb gen general-target-cb make-effect-dialog { d } gen d eff_dialog! d #( #( "stretch factor" 0.0 gen eff_factor@ 5.0 gen rubber-factor-cb 100 ) ) add-sliders ( sl ) gen swap eff_sliders! gen #f add-target then gen eff_dialog@ activate-dialog ; set-current : make-rubber-dialog ( name -- prc1 prc2; child self -- prc; self -- ) ( name ) make-base-effects { gen } gen 1.0 eff_factor! gen post-rubber-dialog ( prc1 ) 1 proc-create gen , ( prc2 ) does> { child self -- prc; self -- } 0 proc-create self @ ( gen ) , child , ( prc ) does> { self -- } self @ { gen } self cell+ @ ( child ) "%s (%.2f)" #( gen eff_label@ gen eff_factor@ ) string-format change-label ; previous \ === Wobble === hide : wobble-ok-cb ( gen -- prc; w c i self -- res ) 3 proc-create swap , ( prc ) does> { w c info self -- res } self @ { gen } gen eff_freq@ gen eff_amp@ \ beg dur follows gen eff_target@ 'sound = if 0 #f #f #f framples else gen eff_target@ 'selection = if #f #f selection-position #f #f selection-framples else plausible-mark-samples { pts } pts if pts 0 array-ref pts 1 array-ref pts 0 array-ref - else 'no-such-mark #( "%s: %s" get-func-name pts ) fth-throw then then then #f #f effects-hello-dentist ; : wobble-reset-cb { gen -- prc; w c i self -- } 3 proc-create gen , gen eff_freq@ , gen eff_amp@ , ( prc ) does> { w c info self -- } self @ { gen } self 1 cells + @ { init-frq } self 2 cells + @ { init-amp } gen init-frq eff_freq! gen init-amp eff_amp! gen eff_sliders@ 0 array-ref init-frq 100.0 set-slider-value gen eff_sliders@ 1 array-ref init-amp 100.0 set-slider-value ; : post-wobble-dialog ( gen -- prc; w c i self -- ) 3 proc-create swap , ( prc ) does> { w c info self -- } self @ { gen } gen eff_dialog@ widget? unless gen eff_label@ gen wobble-ok-cb gen eff_label@ "\ Move the sliders to set the wobble frequency and amplitude." help-cb gen wobble-reset-cb gen general-target-cb make-effect-dialog { d } gen d eff_dialog! d #( #( "wobble frequency" 0.0 gen eff_freq@ 100.0 gen frequency-slider-cb 100 ) #( "wobble amplitude" 0.0 gen eff_amp@ 1.0 gen amplitude-slider-cb 100 ) ) add-sliders ( sl ) gen swap eff_sliders! gen #f add-target then gen eff_dialog@ activate-dialog ; set-current : make-wobble-dialog ( name -- prc1 prc2; child self -- prc; self -- ) ( name ) make-base-effects { gen } gen 50.0 eff_freq! gen 0.5 eff_amp! gen post-wobble-dialog ( prc1 ) 1 proc-create gen , ( prc2 ) does> { child self -- prc; self -- } 0 proc-create self @ ( gen ) , child , ( prc ) does> { self -- } self @ { gen } self cell+ @ ( child ) "%s (%.2f %.2f)" #( gen eff_label@ gen eff_freq@ gen eff_amp@ ) string-format change-label ; previous : init-effects-menu ( name -- ) make-main-menu { main } "Amplitude Effects" main make-menu { menu } menu "Gain" make-gain-dialog menu-entry menu "Normalize" make-normalize-dialog menu-entry menu "Gate" make-gate-dialog menu-entry "Delay Effects" main make-menu to menu menu "Echo" make-echo-dialog menu-entry menu "Filtered echo" make-flecho-dialog menu-entry menu "Modulated echo" make-zecho-dialog menu-entry "Filter Effects" main make-menu to menu menu "Band-pass filter" make-band-pass-dialog menu-entry menu "Band-reject filter" make-notch-dialog menu-entry menu "High-pass filter" make-high-pass-dialog menu-entry menu "Low-pass filter" make-low-pass-dialog menu-entry menu "Comb filter" make-comb-dialog menu-entry menu "Comb chord filter" make-comb-chord-dialog menu-entry menu "Moog filter" make-moog-dialog menu-entry "Frequency Effects" main make-menu to menu menu "Adaptive saturation" make-adsat-dialog menu-entry menu "Sample rate conversion" make-src-dialog menu-entry menu "Time/pitch scaling" make-expsrc-dialog menu-entry menu "Src-Timevar" make-src-timevar-dialog menu-entry "Modulation Effects" main make-menu to menu menu "Amplitude modulation" make-am-effect-dialog menu-entry menu "Ring modulation" make-rm-effect-dialog menu-entry "Reverbs" main make-menu to menu menu "McNabb reverb" make-reverb-dialog menu-entry menu "Chowning reverb" make-jc-reverb-dialog menu-entry menu "Convolution" make-convolve-dialog menu-entry "Various" main make-menu to menu menu "Place sound" make-place-sound-dialog menu-entry menu "Add silence" make-silence-dialog menu-entry menu "Contrast enhancement" make-contrast-dialog menu-entry menu "Cross synthesis" make-cross-synth-dialog menu-entry menu "Flange" make-flange-dialog menu-entry menu "Randomize phase" make-random-phase-dialog menu-entry menu "Robotize" make-robotize-dialog menu-entry menu "Rubber sound" make-rubber-dialog menu-entry menu "Wobble" make-wobble-dialog menu-entry ; \ === Effects Menu === "Effects" value effects-menu-label [undefined] effects-menu-exists? [if] #t value effects-menu-exists? effects-menu-label init-effects-menu #f effects-noop add-to-effects-menu \ separator "Octave-down" lambda: <{ -- }> 2 #f #f down-oct ; add-to-effects-menu "Remove clicks" lambda: <{ -- }> #f #f effects-remove-clicks ; add-to-effects-menu "Remove DC" lambda: <{ -- }> #f #f effects-remove-dc ; add-to-effects-menu "Spiker" lambda: <{ -- }> #f #f spike ; add-to-effects-menu "Compand" lambda: <{ -- }> #f #f effects-compand ; add-to-effects-menu "Invert" lambda: <{ -- }> -1 #f #f scale-by ; add-to-effects-menu "Reverse" lambda: <{ -- }> #f #f #f reverse-sound ; add-to-effects-menu "Null phase" lambda: <{ -- }> #f #f zero-phase ; add-to-effects-menu [then] \ effects.fs ends here snd-16.1/snd-io.c0000644000076400007640000005457012471670274011715 0ustar bilbil#include "snd.h" /* rather than try to track error indications through infinite levels of nested calls, * I think I'll just issue a warning, and let the redirection mechanism deal with it. */ struct snd_io { int fd, chans, bufsize; mus_long_t framples, beg, end; mus_float_t **arrays; }; mus_long_t io_beg(snd_io *io) { return(io->beg); } mus_long_t io_end(snd_io *io) { return(io->end); } void snd_remove(const char *name, cache_remove_t forget) { int err; if (forget == REMOVE_FROM_CACHE) mus_sound_forget(name); /* no error here if not in sound tables */ ss->local_errno = 0; err = remove(name); if (err != 0) snd_warning("remove %s: %s", name, snd_io_strerror()); } void snd_close(int fd, const char *name) { if (fd < 0) snd_warning("close %s, fd: %d", name, fd); else { int err; ss->local_errno = 0; err = close(fd); if (err != 0) snd_warning("close %s: %s", name, snd_io_strerror()); } } void snd_fclose(FILE *fd, const char *name) { if (!fd) snd_warning("fclose %s, fd null!", name); else { int err; ss->local_errno = 0; err = fclose(fd); if (err != 0) snd_warning("fclose %s: %s", name, snd_io_strerror()); } } /* low level IO stuff to keep track of errno */ /* OPEN and FOPEN (_sndlib.h) also come here, so any sound file in Snd is opened/closed here */ FILE *snd_fopen(const char *filename, const char *modes) { FILE *result = NULL; ss->local_errno = 0; ss->local_open_errno = 0; errno = 0; result = fopen(filename, modes); if (errno != 0) { ss->local_errno = errno; ss->local_open_errno = errno; } return(result); } int snd_open(const char *filename, int flags, mode_t mode) { int result = 0; ss->local_errno = 0; ss->local_open_errno = 0; errno = 0; #if (defined(_MSC_VER) || __CYGWIN__) result = open(filename, flags); #else result = open(filename, flags, mode); #endif if (errno != 0) { ss->local_errno = errno; ss->local_open_errno = errno; } return(result); } int snd_creat(const char *filename, mode_t mode) { int result = 0; ss->local_errno = 0; ss->local_open_errno = 0; errno = 0; result = creat(filename, mode); if (errno != 0) { ss->local_errno = errno; ss->local_open_errno = errno; } return(result); } io_error_t move_file(const char *oldfile, const char *newfile) { io_error_t err = IO_NO_ERROR; int rename_err; rename_err = rename(oldfile, newfile); if (rename_err != 0) { if (errno == EXDEV) { err = copy_file(oldfile, newfile); if (err == IO_NO_ERROR) snd_remove(oldfile, REMOVE_FROM_CACHE); } } return(err); } io_error_t copy_file(const char *oldname, const char *newname) { /* make newname a copy of oldname */ int ifd, ofd; mus_long_t bytes, wb; char *buf = NULL; ifd = OPEN(oldname, O_RDONLY, 0); if (ifd == -1) return(IO_CANT_OPEN_FILE); ofd = CREAT(newname, 0666); if (ofd == -1) { snd_close(ifd, oldname); return(IO_CANT_CREATE_FILE); } buf = (char *)malloc(8192 * sizeof(char)); while ((bytes = read(ifd, buf, 8192))) { wb = write(ofd, buf, bytes); if (wb != bytes) { snd_close(ofd, newname); snd_close(ifd, oldname); free(buf); return(IO_WRITE_ERROR); } } snd_close(ifd, oldname); wb = disk_kspace(newname); snd_close(ofd, newname); free(buf); if (wb < 0) return(IO_DISK_FULL); return(IO_NO_ERROR); } /* file buffers (i.e. a sliding window on a given file's data) */ static void c_io_bufclr(snd_io *io, int beg) { int k; size_t bytes; bytes = (io->bufsize - beg) * sizeof(mus_float_t); for (k = 0; k < io->chans; k++) { mus_float_t *j; j = io->arrays[k]; if (j) memset((void *)(j + beg), 0, bytes); } } static void reposition_file_buffers_1(mus_long_t loc, snd_io *io) { /* called when loc is outside the current in-core frample for the file pointed to by io */ mus_long_t framples; /* local framples is buffer-local, not a sample number. */ framples = io->framples - loc; /* io->framples is total samps in file */ if (framples > io->bufsize) framples = io->bufsize; if (framples <= 0) /* tried to access beyond current end of file */ { io->beg = loc; c_io_bufclr(io, 0); } else { mus_file_seek_frample(io->fd, loc); io->beg = loc; mus_file_read_chans(io->fd, loc, framples, io->chans, io->arrays, io->arrays); if (framples < (io->bufsize - 1)) c_io_bufclr(io, framples); } io->end = io->beg + io->bufsize - 1; } static void reposition_file_buffers(snd_data *sd, mus_long_t index) { int fd = 0; bool reclose = false; if (index < 0) index = 0; /* if reading in reverse, don't fall off the start of the buffer */ if (sd->open == FD_CLOSED) { file_info *hdr; /* try to open it with sndlib descriptors */ fd = mus_file_open_read(sd->filename); if (fd == -1) { /* our file has disappeared?!? */ snd_error("%s is unreadable: %s?", sd->filename, snd_io_strerror()); return; } hdr = sd->hdr; /* these need to flush active data before hidden close and fixup the io indices */ snd_file_open_descriptors(fd, sd->filename, hdr->sample_type, hdr->data_location, hdr->chans, hdr->type); during_open(fd, sd->filename, SND_REOPEN_CLOSED_FILE); /* fix up io->fd and whatever else is clobbered by mus_file_close */ sd->io->fd = fd; sd->open = FD_OPEN; reclose = true; } reposition_file_buffers_1(index, sd->io); if (reclose) { sd->open = FD_CLOSED; sd->io->fd = -1; mus_file_close(fd); } } snd_io *make_file_state(int fd, file_info *hdr, int chan, mus_long_t beg, int suggested_bufsize) { snd_io *io; int bufsize; mus_long_t chansize; #define MAX_FILE_BUFFER_SIZE 65536 bufsize = suggested_bufsize; chansize = (hdr->samples / hdr->chans); /* this can be bogus if the header is messed up */ if ((chansize >= 0) && ((bufsize > chansize) || (MAX_FILE_BUFFER_SIZE > chansize))) bufsize = chansize + 1; io = (snd_io *)calloc(1, sizeof(snd_io)); /* only creation point */ io->arrays = (mus_float_t **)calloc(hdr->chans, sizeof(mus_float_t *)); io->fd = fd; io->chans = hdr->chans; io->framples = chansize; io->beg = 0; io->end = bufsize - 1; io->bufsize = bufsize; io->arrays[chan] = (mus_float_t *)malloc(bufsize * sizeof(mus_float_t)); io->arrays[chan][bufsize - 1] = 0.0; /* there is buffer bounds confusion somewhere... */ reposition_file_buffers_1(beg, io); /* get ready to read -- we're assuming mus_file_read_chans here */ return(io); } void file_buffers_forward(mus_long_t ind0, mus_long_t ind1, mus_long_t indx, snd_fd *sf, snd_data *cur_snd) { /* need to track in-core buffer and file-relative index */ if ((indx < cur_snd->io->beg) || (indx > cur_snd->io->end)) reposition_file_buffers(cur_snd, indx); sf->loc = indx - cur_snd->io->beg; if (ind0 >= cur_snd->io->beg) sf->first = ind0 - cur_snd->io->beg; else sf->first = 0; if (ind1 <= cur_snd->io->end) sf->last = ind1 - cur_snd->io->beg; else sf->last = cur_snd->io->bufsize - 1; } void file_buffers_back(mus_long_t ind0, mus_long_t ind1, mus_long_t indx, snd_fd *sf, snd_data *cur_snd) { if ((indx > cur_snd->io->end) || (indx < cur_snd->io->beg)) reposition_file_buffers(cur_snd, indx - cur_snd->io->bufsize + 1); sf->loc = indx - cur_snd->io->beg; if (ind1 <= cur_snd->io->end) sf->last = ind1 - cur_snd->io->beg; else sf->last = cur_snd->io->bufsize - 1; if (ind0 >= cur_snd->io->beg) sf->first = ind0 - cur_snd->io->beg; else sf->first = 0; } /* wrappers for low level sndlib open/close/access functions -- we can't use * the sndlib versions directly because in some cases, Snd has more than FOPEN_MAX * files nominally open and accessible (mix temps in with-sound explode for example). * these wrappers provide checks for EMFILE as errno from open and try to close * temps to make room. * * there is a hidden limit that might come into play if FOPEN_MAX > MUS_FILE_DESCRIPTORS (see io.c) * on the SGI, FOPEN_MAX is 100, but we can open many more files than that without hitting the EMFILE error. */ static void close_temp_files(chan_info *cp, int *closed) { if ((cp) && (cp->sounds)) { int i, rtn; rtn = (*closed); for (i = 0; i < cp->sound_size; i++) { snd_data *sd; sd = cp->sounds[i]; if ((sd) && (sd->type == SND_DATA_FILE) && (sd->io) && (sd->open == FD_OPEN)) { int fd; fd = sd->io->fd; sd->open = FD_CLOSED; sd->io->fd = -1; mus_file_close(fd); rtn++; } } (*closed) = rtn; } } static int too_many_files_cleanup(void) { int *closed; int rtn; closed = (int *)malloc(sizeof(int)); (*closed) = 0; for_each_normal_chan_with_refint(close_temp_files, closed); if ((*closed) == 0) for_each_region_chan_with_refint(close_temp_files, closed); if ((*closed) == 0) rtn = -1; else rtn = (*closed); free(closed); return(rtn); } int snd_open_read(const char *arg) { int fd; fd = OPEN(arg, O_RDONLY, 0); if ((fd == -1) && (errno == EMFILE)) /* there's also ENFILE = file table overflow (/usr/include/asm/errno.h) */ { fd = too_many_files_cleanup(); if (fd != -1) fd = OPEN(arg, O_RDONLY, 0); if (fd == -1) snd_error("%s: %s", arg, snd_io_strerror()); } return(fd); } int snd_reopen_write(const char *arg) { int fd; fd = OPEN(arg, O_RDWR, 0); if ((fd == -1) && (errno == EMFILE)) { fd = too_many_files_cleanup(); if (fd != -1) fd = OPEN(arg, O_RDWR, 0); if (fd == -1) snd_error("%s: %s", arg, snd_io_strerror()); } return(fd); } static int local_mus_error = MUS_NO_ERROR; static mus_error_handler_t *old_error_handler; static void local_mus_error_to_snd(int type, char *msg) { local_mus_error = type; if (ss->io_error_info) free(ss->io_error_info); ss->io_error_info = mus_strdup(msg); } io_error_t sndlib_error_to_snd(int sndlib_err) { /* "mus_error" in sndlib is an int that includes all kinds of error conditions that * aren't relevant to file IO in Snd; I need to translate to a more restrictive * set to make it easier to generate informative error messages. */ if (sndlib_err >= 0) switch (sndlib_err) { case MUS_NO_ERROR: return(IO_NO_ERROR); case MUS_MEMORY_ALLOCATION_FAILED: return(IO_NO_MEMORY); case MUS_CANT_OPEN_FILE: return(IO_CANT_OPEN_FILE); case MUS_NO_SUCH_CHANNEL: return(IO_BAD_CHANNEL); case MUS_NO_FILE_NAME_PROVIDED: return(IO_NO_FILENAME); case MUS_UNSUPPORTED_SAMPLE_TYPE: return(IO_BAD_SAMPLE_TYPE); case MUS_HEADER_READ_FAILED: return(IO_BAD_HEADER); case MUS_UNSUPPORTED_HEADER_TYPE: return(IO_BAD_HEADER_TYPE); case MUS_FILE_DESCRIPTORS_NOT_INITIALIZED: return(IO_SNDLIB_UNINITIALIZED); case MUS_NOT_A_SOUND_FILE: return(IO_NOT_A_SOUND_FILE); case MUS_FILE_CLOSED: return(IO_FILE_CLOSED); case MUS_WRITE_ERROR: return(IO_WRITE_ERROR); case MUS_HEADER_WRITE_FAILED: return(IO_CANT_REOPEN_FILE); case MUS_CANT_OPEN_TEMP_FILE: return(IO_CANT_OPEN_FILE); case MUS_INTERRUPTED: return(IO_INTERRUPTED); case MUS_CANT_CLOSE_FILE: return(IO_CANT_CLOSE_FILE); } return(IO_UNKNOWN_SNDLIB_ERROR); } int snd_file_open_descriptors(int fd, const char *name, mus_sample_t samp_type, mus_long_t location, int chans, mus_header_t type) { int sl_err; sl_err = mus_file_open_descriptors(fd, name, samp_type, mus_bytes_per_sample(samp_type), location, chans, type); if (sl_err != MUS_NO_ERROR) snd_warning("%s: open file descriptors: %s", name, mus_error_type_to_string(sl_err)); if (mus_sound_saved_data(name)) mus_file_save_data(fd, mus_sound_framples(name), mus_sound_saved_data(name)); return(sl_err); } io_error_t snd_write_header(const char *name, mus_header_t head_type, int srate, int chans, mus_long_t samples, mus_sample_t samp_type, const char *comment, int *loops) { int err; /* sndlib-style error */ /* trap mus_error locally here so that callers of open_temp_file can cleanup samplers and whatnot */ local_mus_error = MUS_NO_ERROR; old_error_handler = mus_error_set_handler(local_mus_error_to_snd); mus_sound_forget(name); mus_header_set_aiff_loop_info(loops); err = mus_write_header(name, head_type, srate, chans, samples, samp_type, comment); /* err here is a mus error */ if (err != MUS_NO_ERROR) { if (errno == EMFILE) /* 0 => no error (err not actually returned unless it's -1) */ { err = too_many_files_cleanup(); if (err != -1) mus_write_header(name, head_type, srate, chans, samples, samp_type, comment); else { mus_error_set_handler(old_error_handler); return(IO_TOO_MANY_OPEN_FILES); } } } else mus_header_set_aiff_loop_info(NULL); mus_error_set_handler(old_error_handler); return(sndlib_error_to_snd(local_mus_error)); } /* there are a few special-case multi-channel temp files that need a kind of reference count to handle deletion */ /* this machinery affects only these special cases, not temp files in general */ typedef struct { char *name; int chans; int *ticks; } tempfile_ctr; static tempfile_ctr **tempfiles = NULL; static int tempfiles_size = 0; void remember_temp(const char *filename, int chans) { int i; tempfile_ctr *tmp = NULL; if (tempfiles_size == 0) { tempfiles_size = 8; tempfiles = (tempfile_ctr **)calloc(tempfiles_size, sizeof(tempfile_ctr *)); i = 0; } else { for (i = 0; i < tempfiles_size; i++) if ((tempfiles[i]) && (mus_strcmp(filename, tempfiles[i]->name))) return; for (i = 0; i < tempfiles_size; i++) if (tempfiles[i] == NULL) break; if (i >= tempfiles_size) { int old_size; old_size = tempfiles_size; tempfiles_size += 8; tempfiles = (tempfile_ctr **)realloc(tempfiles, tempfiles_size * sizeof(tempfile_ctr *)); for (i = old_size; i < tempfiles_size; i++) tempfiles[i] = NULL; i = old_size; } } tmp = (tempfile_ctr *)malloc(sizeof(tempfile_ctr)); tempfiles[i] = tmp; tmp->name = mus_strdup(filename); tmp->chans = chans; tmp->ticks = (int *)calloc(chans, sizeof(int)); } void forget_temp(const char *filename, int chan) { int i, j; for (i = 0; i < tempfiles_size; i++) { tempfile_ctr *tmp; tmp = tempfiles[i]; if ((tmp) && (mus_strcmp(filename, tmp->name))) { tmp->ticks[chan]--; for (j = 0; j < tmp->chans; j++) if (tmp->ticks[j] > 0) return; snd_remove(tmp->name, REMOVE_FROM_CACHE); free(tmp->name); free(tmp->ticks); free(tmp); tempfiles[i] = NULL; return; } } } static void tick_temp(const char *filename, int chan) { int i; for (i = 0; i < tempfiles_size; i++) { tempfile_ctr *tmp; tmp = tempfiles[i]; if ((tmp) && (mus_strcmp(filename, tmp->name))) { tmp->ticks[chan]++; return; } } } void forget_temps(void) { int i; for (i = 0; i < tempfiles_size; i++) if ((tempfiles[i]) && (mus_file_probe(tempfiles[i]->name))) snd_remove(tempfiles[i]->name, REMOVE_FROM_CACHE); } snd_data *make_snd_data_file(const char *name, snd_io *io, file_info *hdr, file_delete_t temp, int ctr, int temp_chan) { snd_data *sd; sd = (snd_data *)malloc(sizeof(snd_data)); sd->type = SND_DATA_FILE; sd->buffered_data = io->arrays[temp_chan]; sd->io = io; sd->filename = mus_strdup(name); sd->hdr = hdr; sd->temporary = temp; if ((temp == MULTICHANNEL_DELETION) || (temp == MULTICHANNEL_DELETION_IF_FILE)) tick_temp(name, temp_chan); sd->edit_ctr = ctr; sd->open = FD_OPEN; sd->inuse = false; sd->copy = false; sd->chan = temp_chan; sd->data_bytes = (hdr->samples) * (mus_bytes_per_sample(hdr->sample_type)) + hdr->data_location; sd->free_me = false; return(sd); } snd_data *copy_snd_data(snd_data *sd, mus_long_t beg, int bufsize) { snd_data *sf; snd_io *io; int fd; file_info *hdr; hdr = sd->hdr; fd = snd_open_read(sd->filename); if (fd == -1) return(NULL); snd_file_open_descriptors(fd, sd->filename, hdr->sample_type, hdr->data_location, hdr->chans, hdr->type); during_open(fd, sd->filename, SND_COPY_READER); io = make_file_state(fd, hdr, sd->chan, beg, bufsize); sf = (snd_data *)malloc(sizeof(snd_data)); sf->type = sd->type; sf->buffered_data = io->arrays[sd->chan]; sf->io = io; sf->filename = mus_strdup(sd->filename); sf->hdr = hdr; sf->temporary = DONT_DELETE_ME; sf->edit_ctr = sd->edit_ctr; /* 17-Nov-14: this was sf->open = FD_OPEN; but I can't think of any reason to leave it open */ sf->open = FD_CLOSED; sf->io->fd = -1; mus_file_close(fd); sf->inuse = false; sf->copy = true; sf->chan = 0; sf->data_bytes = 0; sf->free_me = false; return(sf); } snd_data *make_snd_data_buffer(mus_float_t *data, int len, int ctr) { snd_data *sf; sf = (snd_data *)calloc(1, sizeof(snd_data)); sf->type = SND_DATA_BUFFER; sf->buffered_data = (mus_float_t *)malloc((len + 1) * sizeof(mus_float_t)); /* sigh... using len + 1 rather than len to protect against access to inserted buffer at end mixups (final fragment uses end + 1) */ /* the real problem here is that I never decided whether insert starts at the cursor or just past it */ /* when the cursor is on the final sample, this causes cross-fragment ambiguity as to the length of a trailing insertion */ /* C > (make-region 1000 2000) (insert-region (cursor)) C-v hits this empty slot and gets confused about the previously final sample value */ memcpy((void *)(sf->buffered_data), (void *)data, len * sizeof(mus_float_t)); sf->buffered_data[len] = 0.0; sf->edit_ctr = ctr; sf->copy = false; sf->inuse = false; sf->data_bytes = len * sizeof(mus_float_t); return(sf); } snd_data *make_snd_data_buffer_for_simple_channel(int len) { snd_data *sf; sf = (snd_data *)calloc(1, sizeof(snd_data)); sf->type = SND_DATA_BUFFER; sf->buffered_data = (mus_float_t *)calloc(len, sizeof(mus_float_t)); sf->edit_ctr = 0; sf->copy = false; sf->inuse = false; sf->data_bytes = len * sizeof(mus_float_t); return(sf); } snd_data *free_snd_data(snd_data *sd) { if (sd) { if (!(sd->inuse)) { /* assume the inuse cases will eventually be freed the GC. * this can happen if a sampler is created, and forgotten, * and the associated sound is closed. The closing runs through * the snd_data (sounds) list freeing the descriptors, but the * forgotten sampler is still idle somewhere thinking it * might someday find a use for itself... */ if (sd->temporary == ALREADY_DELETED) return(NULL); if (sd->temporary == MULTICHANNEL_DELETION) forget_temp(sd->filename, sd->chan); if ((sd->type == SND_DATA_BUFFER) && (sd->buffered_data)) free(sd->buffered_data); sd->buffered_data = NULL; if ((!(sd->copy)) && (sd->hdr)) free_file_info(sd->hdr); sd->hdr = NULL; if (sd->io) { int i, chans; if (sd->open == FD_OPEN) mus_file_close(sd->io->fd); /* free the IO buffers as well as the descriptor buffer */ chans = sd->io->chans; for (i = 0; i < chans; i++) if (sd->io->arrays[i]) free(sd->io->arrays[i]); free(sd->io->arrays); free(sd->io); sd->io = NULL; if (sd->temporary == DELETE_ME) snd_remove(sd->filename, REMOVE_FROM_CACHE); } if (sd->filename) free(sd->filename); sd->filename = NULL; sd->temporary = ALREADY_DELETED; sd->copy = false; sd->type = SND_DATA_NO_DATA; free(sd); } else { sd->free_me = true; } } return(NULL); } int open_temp_file(const char *ofile, int chans, file_info *hdr, io_error_t *err) { /* returns io fd */ int ofd, sl_err = MUS_NO_ERROR; if (!(mus_header_writable(hdr->type, hdr->sample_type))) { hdr->type = default_output_header_type(ss); if (mus_header_writable(hdr->type, default_output_sample_type(ss))) hdr->sample_type = default_output_sample_type(ss); else { /* was default_output_* here, but that's for the user's output, not ours */ hdr->type = MUS_NEXT; hdr->sample_type = MUS_OUT_SAMPLE_TYPE; } } (*err) = snd_write_header(ofile, hdr->type, hdr->srate, chans, 0, hdr->sample_type, hdr->comment, hdr->loops); if ((*err) != IO_NO_ERROR) { /* -1 as fd */ return(-1); } ofd = snd_reopen_write(ofile); if (ofd == -1) { (*err) = IO_CANT_REOPEN_FILE; return(-1); } hdr->data_location = mus_header_data_location(); /* header might have changed size (aiff extras) */ sl_err = snd_file_open_descriptors(ofd, ofile, hdr->sample_type, hdr->data_location, chans, hdr->type); if (sl_err != MUS_NO_ERROR) (*err) = sndlib_error_to_snd(sl_err); lseek(ofd, hdr->data_location, SEEK_SET); return(ofd); } io_error_t close_temp_file(const char *filename, int ofd, mus_header_t type, mus_long_t bytes) { int err; err = mus_file_close(ofd); if (err == MUS_NO_ERROR) { local_mus_error = MUS_NO_ERROR; old_error_handler = mus_error_set_handler(local_mus_error_to_snd); mus_header_change_data_size(filename, type, bytes); mus_sound_forget(filename); mus_error_set_handler(old_error_handler); return(sndlib_error_to_snd(local_mus_error)); } return(sndlib_error_to_snd(err)); } void set_up_snd_io(chan_info *cp, int i, int fd, const char *filename, file_info *hdr, bool post_close) { snd_io *io; snd_file_open_descriptors(fd, filename, hdr->sample_type, hdr->data_location, hdr->chans, hdr->type); io = make_file_state(fd, hdr, i, 0, (post_close) ? MAX_BUFFER_SIZE : FILE_BUFFER_SIZE); cp->sounds[0] = make_snd_data_file(filename, io, copy_header(hdr->name, hdr), DONT_DELETE_ME, cp->edit_ctr, i); if (post_close) { snd_data *sd; sd = cp->sounds[0]; sd->open = FD_CLOSED; io->fd = -1; if (mus_file_close(fd) != 0) snd_error("can't close file %s: %s", filename, snd_io_strerror()); } /* this is not as crazy as it looks -- we've read in the first 64K (or whatever) samples, * and may need this file channel for other opens, so this file can be closed until reposition_file_state_buffers */ } snd-16.1/bird.scm0000644000076400007640000015222712446635675012012 0ustar bilbil;;; bird songs -- (load "bird.scm") then (make-birds) ;;; ;;; some of the bird names come from a 1966 bird guide ;;; ;;; see animals.scm for later versions of some of these songs ;;; ;;; 3-Nov-08: changed some of the function names to avoid collisions with animals.scm (prepended "b-") ;;; 13-Dec-12: minor optimizations (provide 'snd-bird.scm) ;;; translated (semi-automatically) from a Sambox note list to bird.clm, then bird.scm (if (provided? 'snd) (require snd-ws.scm) (require sndlib-ws.scm)) (definstrument (bigbird start dur frequency freqskew amplitude freq-envelope amp-envelope partials) (let ((gls-env (make-env freq-envelope (hz->radians freqskew) dur)) (os (make-polywave frequency :partials (normalize-partials partials))) (amp-env (make-env amp-envelope amplitude dur)) (beg (seconds->samples start)) (end (seconds->samples (+ start dur)))) (do ((i beg (+ i 1))) ((= i end)) (outa i (* (env amp-env) (polywave os (env gls-env))))))) (definstrument (bird start dur frequency freqskew amplitude freq-envelope amp-envelope) (let ((gls-env (make-env freq-envelope (hz->radians freqskew) dur)) (os (make-oscil frequency)) (amp-env (make-env amp-envelope amplitude dur)) (end (seconds->samples (+ start dur))) (beg (seconds->samples start))) (do ((i beg (+ i 1))) ((= i end)) (outa i (* (env amp-env) (oscil os (env gls-env))))))) (define main-amp '(.00 .00 .25 1.00 .60 .70 .75 1.00 1.00 .0)) (define bird-tap '(.00 .00 .01 1.00 .99 1.00 1.00 .0)) (define bird-amp '(.00 .00 .25 1.00 .75 1.00 1.00 .0)) (define b-orchard-oriole (let ((documentation "(orchard-oriole beg) produces an orchard oriole call at time 'beg'")) (lambda (beg) (let ((oriup '(.00 .00 1.00 1.0)) (oridwn '(.00 1.00 1.00 .0)) (oriupdwna '(.00 .00 .60 1.00 1.00 .60 )) (oriupdwnb '(.00 .50 .30 1.00 1.00 .0)) (oribiga '(.00 .90 .15 1.00 .40 .30 .60 .60 .85 .00 1.00 .0)) (orimid '(.00 1.00 .05 .50 .10 1.00 .25 .00 .85 .50 1.00 .0)) (oridwnup '(.00 .30 .25 .00 1.00 1.0)) (oriamp '(.00 .00 .10 1.00 1.00 .0))) (set! beg (- beg .38)) (bird (+ beg .38) .03 3700 100 .05 oridwn main-amp) (bird (+ beg .41) .05 2500 1000 .1 oriup main-amp) (bigbird (+ beg .5) .1 2000 800 .2 oriupdwna main-amp '(1 1 2 .02 3 .05)) (bird (+ beg .65) .03 3900 1200 .1 oridwn main-amp) (bigbird (+ beg .7) .21 2000 1200 .15 oribiga main-amp '(1 1 2 .05)) (bird (+ beg 1.0) .05 4200 1000 .1 oridwn main-amp) (bigbird (+ beg 1.1) .1 2000 1000 .25 orimid main-amp '(1 1 2 .05)) (bigbird (+ beg 1.3) .1 2000 1000 .25 orimid main-amp '(1 1 2 .05)) (bird (+ beg 1.48) .1 2300 3200 .1 oriupdwnb oriamp) (bird (+ beg 1.65) .03 1800 300 .05 oriup main-amp) (bird (+ beg 1.7) .03 2200 100 .04 oridwn main-amp) (bird (+ beg 1.8) .07 2500 2000 .15 oriupdwnb oriamp) (bigbird (+ beg 1.92) .2 2400 1200 .25 oridwnup main-amp '(1 1 2 .04)) (bird (+ beg 2.2) .02 2200 3000 .04 oriup main-amp) (bird (+ beg 2.28) .02 2200 3000 .04 oriup main-amp) (bigbird (+ beg 2.4) .17 2000 1000 .2 oriupdwna oriamp '(1 1 2 .04)))))) (define b-cassins-kingbird (let ((documentation "(cassins-kingbird beg) produces a cassins kingbird call at time 'beg'")) (lambda (beg) (let ((kingfirst '(.00 .30 .45 1.00 .90 .10 1.00 .0)) (kingsecond '(.00 .00 .02 .50 .04 .00 .06 .55 .08 .05 .10 .60 .12 .05 .14 .65 .16 .10 .18 .70 .20 .10 .22 .75 .24 .15 .26 .80 .28 .20 .30 .85 .32 .25 .34 .90 .36 .30 .38 .95 .40 .40 .42 1.00 .44 .50 .46 1.00 .48 .45 .50 1.00 .52 .50 .54 1.00 .56 .40 .58 .95 .60 .40 .62 .90 .64 .40 .66 .85 .68 .35 .70 .80 .72 .30 .74 .75 .76 .25 .78 .70 .80 .20 .82 .65 .84 .10 .86 .60 .88 .00 .90 .55 .92 .00 .94 .50 .96 .00 1.00 .40 ))) (set! beg (- beg .03)) (bigbird (+ beg .03) .04 1700 1200 .15 kingfirst main-amp '(1 1 2 .5 3 0 4 .2)) (bigbird (+ beg .12) .18 1700 900 .25 kingsecond main-amp '(1 1 2 .01 3 0 4 .1)))))) (define b-chipping-sparrow (let ((documentation "(chipping-sparrow beg) produces a chipping sparrow call at time 'beg'")) (lambda (beg) (let ((chip-up '(.00 .80 .15 1.00 .75 .30 1.00 .0))) (bird beg .05 4000 2400 .2 chip-up main-amp) (bird (+ beg .06) .05 4000 2400 .2 chip-up main-amp) (bird (+ beg .12) .05 4000 2400 .2 chip-up main-amp) (bird (+ beg .18) .05 4000 2400 .2 chip-up main-amp) (bird (+ beg .24) .05 4000 2400 .2 chip-up main-amp) (bird (+ beg .30) .05 4000 2400 .2 chip-up main-amp) (bird (+ beg .36) .05 4000 2400 .2 chip-up main-amp) (bird (+ beg .42) .05 4000 2400 .2 chip-up main-amp) (bird (+ beg .48) .05 4000 2400 .2 chip-up main-amp) (bird (+ beg .54) .05 4000 2400 .2 chip-up main-amp) (bird (+ beg .60) .05 4000 2400 .2 chip-up main-amp) (bird (+ beg .66) .05 4000 2400 .2 chip-up main-amp) (bird (+ beg .72) .05 4000 2400 .2 chip-up main-amp) (bird (+ beg .78) .05 4000 2400 .2 chip-up main-amp) (bird (+ beg .84) .05 4000 2400 .2 chip-up main-amp) (bird (+ beg .90) .05 4000 2400 .2 chip-up main-amp) (bird (+ beg .96) .05 4000 2400 .2 chip-up main-amp))))) (define b-bobwhite (let ((documentation "(bobwhite beg) produces a bobwhite call at time 'beg'")) (lambda (beg) (let ((bobup1 '(.00 .00 .40 1.00 1.00 1.0)) (bobup2 '(.00 .00 .65 .50 1.00 1.0))) (set! beg (- beg .4)) (bigbird (+ beg .4) .2 1800 200 .1 bobup1 main-amp '(1 1 2 .02)) (bigbird (+ beg 1) .20 1800 1200 .2 bobup2 main-amp '(1 1 2 .02)))))) (define b-western-meadowlark (let ((documentation "(western-meadowlark beg) produces a western meadowlark call at time 'beg'")) (lambda (beg) (let ((no-skw '(.00 .00 1.00 .0)) (down-skw '(.00 1.00 .40 .40 1.00 .0)) (fas-down '(.00 1.00 1.00 .0))) (set! beg (- beg .8)) (bigbird (+ beg .800) .1 2010.000 0.000 .100 no-skw main-amp '(1 1 2 .04)) (bigbird (+ beg 1.100) .15 3000.000 100.000 .110 down-skw main-amp '(1 1 2 .04)) (bigbird (+ beg 1.300) .25 2000.000 150.000 .200 down-skw main-amp '(1 1 2 .04)) (bigbird (+ beg 1.650) .15 3010.000 250.000 .110 down-skw main-amp '(1 1 2 .04)) (bigbird (+ beg 1.850) .10 2200.000 150.000 .110 down-skw main-amp '(1 1 2 .04)) (bigbird (+ beg 2.000) .10 3200.000 1400.000 .110 fas-down main-amp '(1 1 2 .04)) (bigbird (+ beg 2.200) .05 2000.000 200.000 .110 fas-down main-amp '(1 1 2 .04)) (bigbird (+ beg 2.300) .10 1600.000 0.000 .110 fas-down main-amp '(1 1 2 .04)))))) (define b-scissor-tailed-flycatcher (let ((documentation "(scissor-tailed-flycatcher beg) produces a scissor-tailed flycatcher call at time 'beg'")) (lambda (beg) (let ((scissor '(.00 .00 .40 1.00 .60 1.00 1.00 .0))) (bigbird beg .05 1800 1800 .2 scissor main-amp '(1 .5 2 1 3 .5 4 .1 5 .01)))))) (define b-great-horned-owl (let ((documentation "(great-horned-owl beg) produces a great horned owl call at time 'beg'")) (lambda (beg) (let ((owlup '(.00 .00 .30 1.00 1.00 1.0)) (owldown '(.00 1.00 1.00 .0))) (set! beg (- beg .3)) (bigbird (+ beg .3) .1 300 0 .1 main-amp main-amp '(1 1 3 .02 7 .01)) (bigbird (+ beg .6) .4 293 6 .1 owldown main-amp '(1 1 3 .02 7 .01)) (bigbird (+ beg 1.75) .35 293 7 .1 owlup main-amp '(1 1 3 .02 7 .01)) (bigbird (+ beg 2.5) .2 300 0 .1 owlup main-amp '(1 1 3 .02 7 .01)))))) (define b-black-throated-gray-warbler (let ((documentation "(black-throated-gray-warbler beg) produces a black throated gray warbler call at time 'beg'")) (lambda (beg) (let ((grayone '(.00 .50 .02 .60 .04 .45 .06 .62 .08 .40 .10 .65 .12 .35 .14 .70 .18 .30 .20 .70 .22 .30 .24 .70 .25 .20 .30 .80 .35 .10 .40 .90 .45 .00 .50 1.00 .55 .00 .60 1.00 .65 .00 .70 1.00 .75 .00 .80 1.00 .85 .00 .90 1.00 .95 .00 1.00 .50 )) (graytwo '(.00 .00 .01 .40 .02 .00 .03 .40 .04 .00 .05 .40 .06 .00 .07 .40 .08 .00 .09 .40 .10 .00 .25 .80 .40 .30 .55 1.00 .70 .00 .85 .80 1.00 .40 )) (graythree '(.00 1.00 .01 .60 .02 1.00 .03 .60 .04 1.00 .05 .60 .06 1.00 .07 .60 .08 1.00 .09 .60 .10 1.00 .11 .60 .12 1.00 .13 .60 .14 1.00 .15 .60 .16 1.00 .17 .60 .18 1.00 .19 .60 .20 1.00 .21 .55 .22 1.00 .23 .50 .24 1.00 .25 .50 .26 1.00 .27 .50 .28 1.00 .29 .50 .30 1.00 .31 .50 .32 1.00 .33 .50 .34 1.00 .35 .50 .36 1.00 .37 .50 .38 1.00 .39 .50 .40 1.00 .41 .50 .42 1.00 .43 .50 .44 1.00 .45 .50 .46 1.00 .47 .50 .48 1.00 .49 .50 .50 1.00 .51 .50 .52 1.00 .53 .50 .54 1.00 .55 .50 .56 1.00 .57 .50 .58 1.00 .59 .50 .60 1.00 1.00 .0)) (grayfour '(.00 .00 1.00 1.0))) (bird beg .12 3700 600 .05 grayone main-amp) (bird (+ beg .18) .08 3000 800 .07 graytwo main-amp) (bird (+ beg .28) .12 3700 600 .12 grayone main-amp) (bird (+ beg .44) .08 3000 800 .15 graytwo main-amp) (bird (+ beg .54) .12 3700 600 .20 grayone main-amp) (bird (+ beg .72) .08 3000 800 .25 graytwo main-amp) (bird (+ beg .82) .12 3700 600 .25 grayone main-amp) (bird (+ beg .96) .2 3000 2000 .2 graythree main-amp) (bird (+ beg 1.2) .02 4500 500 .05 grayfour main-amp) (bird (+ beg 1.25) .02 4200 800 .05 grayfour main-amp) (bird (+ beg 1.3) .02 4000 900 .05 grayfour main-amp))))) (define b-yellow-warbler (let ((documentation "(yellow-warbler beg) produces a yellow warbler call at time 'beg'")) (lambda (beg) (let ((yellow-up '(.00 .00 .60 1.00 1.00 .50 )) (yellow-swirl '(.00 1.00 .05 1.00 .60 .00 .80 .30 1.00 .10 )) (yellow-down '(.00 1.00 1.00 .0)) (yellow-last '(.00 .00 .30 .20 .80 .70 1.00 1.0)) (swirl-amp '(.00 .00 .90 1.00 1.00 .0))) (bird beg .05 5600 400 .05 yellow-up main-amp) (bird (+ beg .23) .12 5000 1500 .15 yellow-swirl swirl-amp) (bird (+ beg .45) .13 5000 1700 .17 yellow-swirl swirl-amp) (bird (+ beg .62) .16 5000 2000 .20 yellow-swirl swirl-amp) (bird (+ beg .85) .15 5000 2000 .20 yellow-swirl swirl-amp) (bird (+ beg 1.05) .075 3700 1000 .20 yellow-down main-amp) (bird (+ beg 1.15) .075 3700 800 .15 yellow-down main-amp) (bird (+ beg 1.25) .075 3700 800 .15 yellow-down main-amp) (bird (+ beg 1.4) .2 3700 2000 .2 yellow-last swirl-amp))))) (define b-black-necked-stilt (let ((documentation "(black-necked-stilt beg) produces a black necked stilt call at time 'beg'")) (lambda (beg) (let ( ;; have to guess about upper partials (cut off by spectrograph) ;; "birds" book has piping sound coming back down whereas "songs ;; of western birds" just shows it going up. ;; (upamp '(.00 .00 .90 1.00 1.00 .0)) (rampup '(.00 .00 .50 1.00 1.00 .20 ))) (bigbird beg .1 900 100 .2 rampup upamp '( 1 .5 2 1 3 .75 4 .5 5 .1)) (bigbird (+ beg .30) .1 900 200 .2 rampup upamp '( 1 .5 2 1 3 .75 4 .5 5 .1)) (bigbird (+ beg .60) .1 900 250 .2 rampup upamp '( 1 .5 2 1 3 .75 4 .5 5 .1)))))) (define b-chestnut-sided-warbler (let ((documentation "(chestnut-sided-warbler beg) produces a chestnut sided warbler call at time 'beg'")) (lambda (beg) (let ((ycurve '(.00 1.00 .30 .50 .60 1.00 .80 .20 1.00 .0)) (vcurve '(.00 .20 .50 1.00 1.00 .0)) (wcurve '(.00 .50 .15 .00 .45 .10 .60 1.00 .70 .90 1.00 .90 )) (upcurve '(.00 .00 .95 1.00 1.00 1.0)) (downcurve '(.00 1.00 .25 .30 .60 .15 1.00 .0)) (louder '(.00 .00 .90 1.00 1.00 .0)) (wamp '(.00 .00 .10 1.00 .40 .10 .50 .90 .60 .10 .70 1.00 1.00 .0))) (set! beg (- beg .1)) (bigbird (+ beg .1) .1 4050 1200 .05 ycurve main-amp '(1 1 2 .1)) (bigbird (+ beg .25) .03 3900 300 .075 vcurve main-amp '(1 1 2 .1)) (bigbird (+ beg .3) .1 4050 1200 .15 ycurve louder '(1 1 2 .1)) (bigbird (+ beg .42) .03 3800 500 .1 vcurve main-amp '(1 1 2 .1)) (bigbird (+ beg .5) .1 4000 1200 .2 ycurve bird-tap '(1 1 2 .1)) (bigbird (+ beg .65) .03 3800 500 .15 vcurve main-amp '(1 1 2 .1)) (bigbird (+ beg .72) .1 4000 1200 .2 ycurve bird-tap '(1 1 2 .1)) (bigbird (+ beg .85) .03 3800 500 .15 vcurve main-amp '(1 1 2 .1)) (bigbird (+ beg .91) .1 4000 1200 .2 ycurve bird-tap '(1 1 2 .1)) (bigbird (+ beg 1.05) .12 3800 2200 .15 wcurve wamp '(1 1 2 .1)) (bigbird (+ beg 1.20) .12 3800 2200 .15 wcurve wamp '(1 1 2 .1)) (bigbird (+ beg 1.35) .12 2500 2200 .25 upcurve louder '(1 1 2 .1)) (bigbird (+ beg 1.50) .12 2500 4000 .15 downcurve main-amp '(1 1 2 .1)))))) (define b-grasshopper-sparrow (let ((documentation "(grasshopper-sparrow beg) produces a grasshopper sparrow call at time 'beg'")) (lambda (beg) (let ((grassone '(.00 .50 .02 .80 .04 .30 .06 .80 .07 .10 .08 .90 .10 .00 .11 .90 .12 .00 .13 .90 .14 .10 .15 1.00 .16 .10 .17 1.00 .18 .10 .19 1.00 .20 .10 .21 1.00 .22 .10 .23 1.00 .24 .10 .25 1.00 .26 .10 .27 1.00 .28 .10 .29 1.00 .30 .10 .31 1.00 .32 .10 .33 1.00 .34 .10 .35 1.00 .36 .10 .37 1.00 .38 .10 .39 1.00 .40 .10 .41 1.00 .42 .10 .43 1.00 .44 .10 .45 1.00 .46 .10 .47 1.00 .48 .10 .49 1.00 .50 .10 .51 1.00 .52 .10 .53 1.00 .54 .10 .55 1.00 .56 .10 .57 1.00 .58 .10 .59 1.00 .60 .10 .61 1.00 .62 .10 .63 1.00 .64 .10 .65 1.00 .66 .10 .67 1.00 .68 .10 .69 1.00 .70 .10 .71 1.00 .72 .10 .73 1.00 .74 .10 .75 1.00 .76 .10 .77 1.00 .78 .10 .79 1.00 .80 .10 .81 1.00 .82 .10 .83 1.00 .84 .10 .85 1.00 .86 .10 .87 1.00 .88 .10 .89 1.00 .90 .10 .91 1.00 .92 .10 .93 1.00 .94 .10 .95 1.00 .96 .10 .97 1.00 .98 .10 1.00 1.0)) (grasstwo '(.00 .00 .10 1.00 .20 .00 .30 1.00 .40 .00 .50 1.00 .60 .00 .70 1.00 .80 .00 .90 1.00 1.00 .0))) (set! beg (- beg .49)) (bird (+ beg .49) .01 8000 100 .1 grasstwo main-amp) (bird (+ beg .60) .01 5700 300 .1 grasstwo main-amp) (bird (+ beg .92) .01 3900 100 .1 grasstwo main-amp) (bird (+ beg 1.00) 1.4 6000 2500 .2 grassone main-amp))))) (define b-swamp-sparrow (let ((documentation "(swamp-sparrow beg) produces a swamp sparrow call at time 'beg'")) (lambda (beg) (let ((swamp-up '(.00 .00 .60 .70 1.00 1.0)) (swamp-down '(.00 1.00 .50 .50 .60 .60 1.00 .0))) (bird beg .02 3900 200 .3 swamp-up main-amp) (bird (+ beg .035) .035 3200 3000 .1 swamp-down main-amp) (bird (+ beg .08) .025 3700 0 .1 main-amp main-amp) (bird (+ beg .1) .02 3900 200 .3 swamp-up main-amp) (bird (+ beg .135) .035 3200 3000 .1 swamp-down main-amp) (bird (+ beg .18) .025 3700 0 .1 main-amp main-amp) (bird (+ beg .2) .02 3900 200 .3 swamp-up main-amp) (bird (+ beg .235) .035 3200 3000 .1 swamp-down main-amp) (bird (+ beg .28) .025 3700 0 .1 main-amp main-amp) (bird (+ beg .3) .02 3900 200 .3 swamp-up main-amp) (bird (+ beg .335) .035 3200 3000 .1 swamp-down main-amp) (bird (+ beg .38) .025 3700 0 .1 main-amp main-amp) (bird (+ beg .4) .02 3900 200 .3 swamp-up main-amp) (bird (+ beg .435) .035 3200 3000 .1 swamp-down main-amp) (bird (+ beg .48) .025 3700 0 .1 main-amp main-amp) (bird (+ beg .5) .02 3900 200 .3 swamp-up main-amp) (bird (+ beg .535) .035 3200 3000 .1 swamp-down main-amp) (bird (+ beg .58) .025 3700 0 .1 main-amp main-amp) (bird (+ beg .6) .02 3900 200 .3 swamp-up main-amp) (bird (+ beg .635) .035 3200 3000 .1 swamp-down main-amp) (bird (+ beg .68) .025 3700 0 .1 main-amp main-amp) (bird (+ beg .7) .02 3900 200 .3 swamp-up main-amp) (bird (+ beg .735) .035 3200 3000 .1 swamp-down main-amp) (bird (+ beg .78) .025 3700 0 .1 main-amp main-amp) (bird (+ beg .8) .02 3900 200 .3 swamp-up main-amp) (bird (+ beg .835) .035 3200 3000 .1 swamp-down main-amp) (bird (+ beg .88) .025 3700 0 .1 main-amp main-amp) (bird (+ beg .9) .02 3900 200 .3 swamp-up main-amp) (bird (+ beg .935) .035 3200 3000 .1 swamp-down main-amp) (bird (+ beg .98) .025 3700 0 .1 main-amp main-amp))))) (define b-golden-crowned-sparrow (let ((documentation "(golden-crowned-sparrow beg) produces a golden crowned sparrow call at time 'beg'")) (lambda (beg) (let ( ;; these have as different song around here. (goldone '(.00 1.00 .25 .20 1.00 .0)) (goldtwo '(.00 .90 .05 1.00 .10 .40 1.00 .0)) (goldtrill '(.00 .50 .10 .00 .20 1.00 .30 .00 .40 1.00 .50 .00 .60 1.00 .70 .00 .80 1.00 .90 .00 1.00 .50 ))) (set! beg (- beg .6)) (bird (+ beg .6) .5 4300 1000 .15 goldone main-amp) (bird (+ beg 1.3) .45 3300 200 .15 goldone main-amp) (bird (+ beg 1.75) .4 3800 100 .15 goldtwo main-amp) (bird (+ beg 2.2) .3 3800 100 .1 goldtrill main-amp))))) (define b-indigo-bunting (let ((documentation "(indigo-bunting beg) produces a indigo bunting call at time 'beg'")) (lambda (beg) (let ((buntdwn '(.00 1.00 1.00 .0)) (buntv '(.00 .00 .50 1.00 1.00 .0)) (bunty '(.00 1.00 .50 .00 1.00 .90 )) (buntn '(.00 .80 .30 1.00 .70 .20 1.00 .0)) (buntx '(.00 1.00 .10 .50 .25 .90 1.00 .0)) (buntup '(.00 .00 1.00 1.0))) (set! beg (- beg .4)) (bird (+ beg .4) .08 3000 700 .25 buntdwn main-amp) (bird (+ beg .52) .02 6200 1000 .05 buntdwn main-amp) (bird (+ beg .55) .15 3500 2300 .1 buntv main-amp) (bird (+ beg .74) .02 6200 1800 .05 buntx main-amp) (bird (+ beg .80) .15 3400 2300 .1 buntv main-amp) (bird (+ beg 1.00) .1 3400 800 .2 buntv main-amp) (bird (+ beg 1.13) .03 4100 2000 .05 buntdwn main-amp) (bird (+ beg 1.25) .08 3400 800 .2 buntv main-amp) (bird (+ beg 1.40) .03 4100 2000 .05 buntdwn main-amp) (bird (+ beg 1.5) .07 3700 300 .1 buntdwn main-amp) (bird (+ beg 1.6) .1 4100 2200 .15 bunty main-amp) (bird (+ beg 1.72) .05 3700 300 .1 buntdwn main-amp) (bird (+ beg 1.81) .1 4100 2200 .15 bunty main-amp) (bird (+ beg 1.94) .07 5200 1800 .2 buntn main-amp) (bird (+ beg 2.05) .08 3000 1500 .15 buntup main-amp) (bird (+ beg 2.20) .07 5200 1800 .2 buntn main-amp) (bird (+ beg 2.33) .08 3000 1500 .15 buntup main-amp) (bird (+ beg 2.43) .07 5200 1800 .1 buntn main-amp) (bird (+ beg 2.51) .08 3000 1500 .10 buntup main-amp))))) (define b-hooded-warbler (let ((documentation "(hooded-warbler beg) produces a hooded warbler call at time 'beg'")) (lambda (beg) (let ((hoodup '(.00 .00 1.00 1.0)) (hooddown '(.00 1.00 1.00 .0))) (set! beg (- beg .6)) (bird (+ beg .6) .03 3900 1600 .05 hooddown main-amp) (bird (+ beg .64) .03 3900 1700 .05 hooddown main-amp) (bird (+ beg .8) .03 3900 2000 .10 hooddown main-amp) (bird (+ beg .84) .03 3900 2000 .10 hooddown main-amp) (bird (+ beg .93) .03 3900 2100 .15 hooddown main-amp) (bird (+ beg .97) .03 3900 2100 .15 hooddown main-amp) (bird (+ beg 1.05) .03 3900 2100 .05 hooddown main-amp) (bird (+ beg 1.09) .03 3900 2100 .2 hooddown main-amp) (bird (+ beg 1.17) .03 3900 2100 .2 hooddown main-amp) (bird (+ beg 1.21) .03 3900 2100 .2 hooddown main-amp) (bird (+ beg 1.39) .03 3900 2100 .2 hooddown main-amp) (bird (+ beg 1.43) .03 3900 2100 .2 hooddown main-amp) (bird (+ beg 1.51) .03 3900 2100 .2 hooddown main-amp) (bird (+ beg 1.55) .03 3900 2100 .2 hooddown main-amp) (bird (+ beg 1.63) .03 3900 2100 .2 hooddown main-amp) (bird (+ beg 1.67) .03 3900 2100 .2 hooddown main-amp) (bird (+ beg 1.75) .03 3900 2100 .2 hooddown main-amp) (bird (+ beg 1.80) .03 3900 2100 .2 hooddown main-amp) (bird (+ beg 1.90) .04 3000 1000 .15 hoodup main-amp) (bird (+ beg 1.98) .04 3000 1000 .15 hoodup main-amp) (bird (+ beg 2.05) .04 3000 1000 .15 hoodup main-amp) (bird (+ beg 2.13) .04 3000 1000 .15 hoodup main-amp) (bird (+ beg 2.21) .04 3000 1000 .15 hoodup main-amp) (bird (+ beg 2.29) .04 3000 1000 .15 hoodup main-amp) (bird (+ beg 2.37) .04 3000 1000 .15 hoodup main-amp) (bird (+ beg 2.45) .04 3000 1000 .15 hoodup main-amp))))) (define b-american-widgeon (let ((documentation "(american-widgeon beg) produces an american widgeon call at time 'beg'")) (lambda (beg) (let ((widgeon '(.00 .00 .50 1.00 1.00 .0))) (set! beg (- beg .3)) (bigbird (+ beg .3) .07 1900 300 .15 widgeon widgeon '(1 1 2 .02)) (bigbird (+ beg .4) .11 1700 1400 .25 widgeon widgeon '(1 .7 2 1 3 .02)) (bigbird (+ beg .55) .07 1900 300 .15 widgeon widgeon '(1 1 2 .02)))))) (define b-louisiana-waterthrush (let ((documentation "(louisiana-waterthrush beg) produces a louisiana waterthrush call at time 'beg'")) (lambda (beg) (let ((water-one '(.00 .80 .35 .40 .45 .90 .50 1.00 .75 1.00 1.00 .10 )) (water-two '(.00 1.00 .40 .00 .60 .10 1.00 .80 )) (water-three '(.00 1.00 .95 .00 1.00 .0)) (water-four '(.00 .00 1.00 1.0)) (water-five '(.00 1.00 1.00 .0)) (water-amp '(.00 .00 .35 1.00 .50 .20 .90 1.00 1.00 .0)) (water-damp '(.00 .00 .90 1.00 1.00 .0))) (bird beg .17 4100 2000 .2 water-one water-amp) (bird (+ beg .32) .18 4050 2050 .3 water-one water-amp) (bird (+ beg .64) .20 4000 1900 .25 water-one water-amp) (bird (+ beg .9) .2 3900 2000 .3 water-two bird-tap) (bird (+ beg 1.25) .12 3000 3000 .25 water-three water-damp) (bird (+ beg 1.4) .1 2700 1500 .2 water-four water-damp) (bird (+ beg 1.58) .02 5200 1000 .1 water-five main-amp) (bird (+ beg 1.65) .02 5200 1000 .1 water-five main-amp) (bird (+ beg 1.7) .035 3200 1000 .1 water-four water-damp))))) (define b-robin (let ((documentation "(robin beg) produces a robin call at time 'beg'")) (lambda (beg) (let ((r-one '(.00 .10 .08 .70 .30 .00 .35 1.00 .40 .30 1.00 .30 )) (r-two '(.00 .00 .10 1.00 .20 .70 .35 .70 .65 .30 .70 .50 .80 .00 .90 .20 1.00 .0)) (r-three '(.00 .20 .25 1.00 .60 .70 .90 .00 1.00 .10 )) (r-four '(.00 1.00 1.00 .0)) (r-five '(.00 .50 .10 .00 .20 1.00 .30 .00 .40 1.00 .50 .00 .60 1.00 .70 .50 1.00 .20 )) (r-six '(.00 .00 .12 .70 .30 .00 .70 1.00 1.00 .50 ))) (set! beg (- beg .45)) (bigbird (+ beg .45) .06 2000 800 .15 r-six main-amp '(1 1 2 .1)) (bigbird (+ beg .56) .10 2000 900 .15 r-one main-amp '(1 1 2 .1)) (bigbird (+ beg 1.04) .24 2000 2000 .25 r-two main-amp '(1 1 2 .1)) (bigbird (+ beg 1.63) .13 1900 1600 .20 r-three main-amp '(1 1 2 .1)) (bigbird (+ beg 1.80) .11 2200 1200 .25 r-four main-amp '(1 1 2 .1)) (bigbird (+ beg 2.31) .21 1950 2000 .15 r-five main-amp '(1 1 2 .1)))))) (define b-solitary-vireo (let ((documentation "(solitary-vireo beg) produces a solitary vireo call at time 'beg'")) (lambda (beg) (let ((bigskew '(.00 .20 .03 .30 .06 .10 .10 .50 .13 .40 .16 .80 .19 .50 .22 .90 .25 .60 .28 1.00 .31 .60 .34 1.00 .37 .50 .41 .90 .45 .40 .49 .80 .51 .40 .54 .75 .57 .35 .60 .70 .63 .30 .66 .60 .69 .25 .72 .50 .75 .20 .78 .30 .82 .10 .85 .30 .88 .05 .91 .30 .94 .00 .95 .30 .99 .00 1.00 .10 ))) (bird beg .4 1800 1200 .2 bigskew main-amp))))) (define b-pigeon-hawk (let ((documentation "(pigeon-hawk beg) produces a pigeon hawk (merlin) call at time 'beg'")) (lambda (beg) (let ((hupdown '(.00 .00 .30 1.00 .70 1.00 1.00 .0))) (bigbird beg .1 1900 200 .2 hupdown main-amp '(1 .7 2 1)) (bigbird (+ beg .12) .01 2050 0 .1 main-amp main-amp '(1 .5 2 1)) (bigbird (+ beg .13) .1 1900 200 .2 hupdown main-amp '(1 .7 2 1)) (bigbird (+ beg .25) .01 2050 0 .1 main-amp main-amp '(1 .5 2 1)) (bigbird (+ beg .26) .1 1900 200 .2 hupdown main-amp '(1 .7 2 1)) (bigbird (+ beg .38) .01 2050 0 .1 main-amp main-amp '(1 .5 2 1)) (bigbird (+ beg .39) .1 1900 200 .2 hupdown main-amp '(1 .7 2 1)) (bigbird (+ beg .51) .01 2050 0 .1 main-amp main-amp '(1 .5 2 1)) (bigbird (+ beg .52) .1 1900 200 .2 hupdown main-amp '(1 .7 2 1)) (bigbird (+ beg .64) .01 2050 0 .1 main-amp main-amp '(1 .5 2 1)) (bigbird (+ beg .65) .1 1900 200 .2 hupdown main-amp '(1 .7 2 1)) (bigbird (+ beg .77) .01 2050 0 .1 main-amp main-amp '(1 .5 2 1)) (bigbird (+ beg .78) .1 1900 200 .2 hupdown main-amp '(1 .7 2 1)) (bigbird (+ beg .90) .01 2050 0 .1 main-amp main-amp '(1 .5 2 1)) (bigbird (+ beg .91) .1 1900 200 .2 hupdown main-amp '(1 .7 2 1)) (bigbird (+ beg 1.03) .01 2050 0 .1 main-amp main-amp '(1 .5 2 1)) (bigbird (+ beg 1.04) .1 1900 200 .2 hupdown main-amp '(1 .7 2 1)) (bigbird (+ beg 1.16) .01 2050 0 .1 main-amp main-amp '(1 .5 2 1)) (bigbird (+ beg 1.17) .1 1900 200 .2 hupdown main-amp '(1 .7 2 1)) (bigbird (+ beg 1.29) .01 2050 0 .1 main-amp main-amp '(1 .5 2 1)) (bigbird (+ beg 1.30) .1 1900 200 .2 hupdown main-amp '(1 .7 2 1)) (bigbird (+ beg 1.42) .01 2050 0 .1 main-amp main-amp '(1 .5 2 1)) (bigbird (+ beg 1.43) .1 1900 200 .2 hupdown main-amp '(1 .7 2 1)) (bigbird (+ beg 1.55) .01 2050 0 .1 main-amp main-amp '(1 .5 2 1)) (bigbird (+ beg 1.56) .1 1900 200 .2 hupdown main-amp '(1 .7 2 1)) (bigbird (+ beg 1.68) .01 2050 0 .1 main-amp main-amp '(1 .5 2 1)) (bigbird (+ beg 1.69) .1 1900 200 .2 hupdown main-amp '(1 .7 2 1)) (bigbird (+ beg 1.81) .01 2050 0 .1 main-amp main-amp '(1 .5 2 1)) (bigbird (+ beg 1.82) .1 1900 200 .2 hupdown main-amp '(1 .7 2 1)))))) (define b-cerulean-warbler (let ((documentation "(cerulean-warbler beg) produces a cerulean warbler call at time 'beg'")) (lambda (beg) (let ((w-down '(.00 1.00 1.00 .0)) (trill '(.00 .80 .10 1.00 .25 .50 .40 1.00 .55 .50 .70 1.00 1.00 .0)) (w-up '(.00 .00 1.00 1.0))) (set! beg (- beg .27)) (bird (+ beg .27) .05 3000 1000 .05 w-down main-amp) (bird (+ beg .33) .05 3000 800 .075 w-up main-amp) (bird (+ beg .41) .01 3200 700 .07 w-down main-amp) (bird (+ beg .42) .01 3200 700 .08 w-down main-amp) (bird (+ beg .43) .06 3200 700 .09 w-down main-amp) (bird (+ beg .51) .06 3200 500 .1 w-up main-amp) (bird (+ beg .6) .10 3000 1200 .2 trill main-amp) (bird (+ beg .72) .05 3000 800 .2 w-up main-amp) (bird (+ beg .8) .10 3000 1200 .2 trill main-amp) (bird (+ beg .92) .05 3000 800 .2 w-up main-amp) (bird (+ beg 1.00) .01 3900 600 .1 w-up main-amp) (bird (+ beg 1.01) .01 3910 800 .1 w-up main-amp) (bird (+ beg 1.02) .01 3940 500 .1 w-up main-amp) (bird (+ beg 1.03) .01 4000 500 .1 w-up main-amp) (bird (+ beg 1.04) .01 3900 1000 .1 w-up main-amp) (bird (+ beg 1.05) .01 3900 1000 .1 w-up main-amp) (bird (+ beg 1.06) .01 3900 1000 .1 w-up main-amp) (bird (+ beg 1.07) .01 3900 1000 .1 w-up main-amp) (bird (+ beg 1.08) .01 3900 1000 .1 w-up main-amp) (bird (+ beg 1.09) .01 3900 1000 .1 w-up main-amp) (bird (+ beg 1.10) .01 3900 1000 .1 w-up main-amp) (bird (+ beg 1.11) .01 3900 1000 .1 w-up main-amp) (bird (+ beg 1.12) .01 3900 1000 .1 w-up main-amp) (bird (+ beg 1.13) .01 3900 1000 .1 w-up main-amp) (bird (+ beg 1.14) .01 3900 1000 .1 w-up main-amp) (bird (+ beg 1.15) .01 3900 1000 .1 w-up main-amp) (bird (+ beg 1.16) .01 3900 1000 .1 w-up main-amp) (bird (+ beg 1.17) .01 3900 1000 .1 w-up main-amp) (bird (+ beg 1.18) .01 3900 1000 .1 w-up main-amp) (bird (+ beg 1.19) .01 3900 1000 .1 w-up main-amp) (bird (+ beg 1.20) .01 3900 1000 .1 w-up main-amp) (bird (+ beg 1.21) .01 3900 1000 .1 w-up main-amp) (bird (+ beg 1.22) .01 3900 1000 .1 w-up main-amp) (bird (+ beg 1.23) .01 3900 1200 .1 w-up main-amp) (bird (+ beg 1.24) .01 3900 1200 .1 w-up main-amp) (bird (+ beg 1.25) .01 3900 1200 .1 w-up main-amp) (bird (+ beg 1.26) .01 3900 1200 .1 w-up main-amp) (bird (+ beg 1.27) .01 3900 1400 .1 w-up main-amp) (bird (+ beg 1.28) .01 3900 1400 .1 w-up main-amp) (bird (+ beg 1.29) .01 3900 1400 .1 w-up main-amp) (bird (+ beg 1.30) .01 3900 1400 .1 w-up main-amp))))) (define b-nashville-warbler (let ((documentation "(nashville-warbler beg) produces a nashville warbler call at time 'beg'")) (lambda (beg) (let ((nash-blip '(.00 .60 .35 1.00 1.00 .0)) (nash-down '(.00 .90 .05 1.00 .10 .90 .65 .50 1.00 .0)) (nash-up '(.00 .00 .15 .20 .25 .05 .90 .95 1.00 1.0)) (nash-amp '(.00 .00 .80 1.00 1.00 .0))) (set! beg (- beg .15)) (bird (+ beg .15) .025 3900 300 .3 nash-blip main-amp) (bird (+ beg .24) .16 4200 3800 .15 nash-down nash-amp) (bird (+ beg .42) .025 3900 300 .3 nash-blip main-amp) (bird (+ beg .55) .14 4300 3700 .15 nash-down nash-amp) (bird (+ beg .75) .03 3950 350 .3 nash-blip main-amp) (bird (+ beg .81) .17 4200 3900 .175 nash-down main-amp) (bird (+ beg 1.0) .02 3800 400 .25 nash-blip main-amp) (bird (+ beg 1.11) .14 4200 3800 .165 nash-down nash-amp) (bird (+ beg 1.3) .03 3750 300 .2 nash-blip main-amp) (bird (+ beg 1.4) .11 4200 3700 .1 nash-down main-amp) (bird (+ beg 1.57) .1 3800 2200 .1 nash-up main-amp) (bird (+ beg 1.7) .1 3800 2150 .125 nash-up main-amp) (bird (+ beg 1.85) .075 3900 1800 .1 nash-up nash-amp))))) (define b-eastern-phoebe (let ((documentation "(eastern-phoebe beg) produces an eastern-phoebe call at time 'beg'")) (lambda (beg) (let ((phoebe-one '(.00 .00 .30 .30 .35 .50 .55 .40 .70 .80 .75 .70 .80 1.00 .95 .90 1.00 .0)) (phoebe-two '(.00 .00 .50 1.00 1.00 .0)) (phoebe-three '(.00 .00 .10 .40 .80 1.00 1.00 .10 )) (phoebe-four '(.00 1.00 .50 .70 1.00 .0)) (phoebe-amp '(.00 .00 .10 1.00 1.00 .0))) (bird beg .225 3000 1300 .3 phoebe-one main-amp) (bird (+ beg .35) .12 3000 500 .1 phoebe-two phoebe-amp) (bird (+ beg .4) .10 3000 1500 .2 phoebe-three phoebe-amp) (bird (+ beg .55) .05 3000 1400 .2 phoebe-four phoebe-amp))))) (define b-painted-bunting (let ((documentation "(painted-bunting beg) produces a painted bunting call at time 'beg'")) (lambda (beg) (let ((b-one '(.00 .00 1.00 1.0)) (b-two '(.00 .00 .90 1.00 1.00 .0)) (b-three '(.00 1.00 1.00 .0)) (b-four '(.00 .00 .50 1.00 1.00 .0)) (b-five '(.00 .70 .15 .00 .40 1.00 .80 1.00 1.00 .50 )) (b-six '(.00 .00 .10 .50 .15 .00 .40 1.00 .90 1.00 1.00 .0)) (b-seven '(.00 1.00 .25 .40 .75 .50 1.00 .0)) (b-eight '(.00 .30 .40 .40 .50 1.00 .60 .20 1.00 .0)) (b-nine '(.00 .00 .05 1.00 .30 1.00 .50 .30 .90 1.00 1.00 .0)) (b-ten '(.00 .40 .25 .00 .35 1.00 .50 .00 .65 1.00 .75 .00 .85 1.00 1.00 .0)) (b-eleven '(.00 1.00 1.00 .0)) (b-twelve '(.00 .00 .50 1.00 1.00 .50 )) (b-thirteen '(.00 .00 .05 1.00 .30 .20 .60 .20 .90 1.00 1.00 .0)) (b-fourteen '(.00 .30 .30 1.00 .60 .30 1.00 .0)) (b-fifteen '(.00 .00 .10 .50 .50 .50 .90 1.00 1.00 .0))) (set! beg (- beg .05)) (bird (+ beg .05) .10 3100 900 .05 b-one b-two) (bird (+ beg .21) .07 4100 700 .15 b-three main-amp) (bird (+ beg .36) .12 3700 1000 .20 b-four main-amp) (bird (+ beg .52) .08 2300 1600 .15 b-five b-six) (bird (+ beg .68) .1 4000 1000 .25 b-one bird-tap) (bird (+ beg .8) .12 2300 1700 .2 b-seven main-amp) (bird (+ beg .96) .15 3800 2200 .3 b-eight b-nine) (bird (+ beg 1.18) .1 2300 1600 .15 b-ten main-amp) (bird (+ beg 1.3) .02 3200 1000 .1 b-eleven main-amp) (bird (+ beg 1.33) .02 3200 1000 .1 b-eleven main-amp) (bird (+ beg 1.36) .02 3200 1000 .1 b-eleven main-amp) (bird (+ beg 1.40) .03 4000 2000 .12 b-twelve b-thirteen) (bird (+ beg 1.47) .1 2300 1700 .2 b-fourteen b-fifteen))))) (define b-western-flycatcher (let ((documentation "(western-flycatcher beg) produces a western flycatcher call at time 'beg'")) (lambda (beg) (let ((f-one '(.00 .00 .10 1.00 .20 .40 .95 .10 1.00 .0)) (a-one '(.00 .00 .10 .20 .20 .10 .30 1.00 .90 1.00 1.00 .0)) (f-two '(.00 .50 .25 1.00 .50 .00 .60 .00 .95 .30 1.00 .60 )) (a-two '(.00 .00 .10 1.00 .20 1.00 .50 .10 .60 .10 .90 1.00 1.00 .0))) (bigbird beg .2 2000 2200 .2 f-one a-one '(1 1 2 .02 3 .1 4 .01)) (bigbird (+ beg .3) .2 2000 1100 .2 f-two a-two '(1 1 2 .02 3 .1 4 .01)))))) (define b-bachmans-sparrow (let ((documentation "(bachmans-sparrow beg) produces a bachmans sparrow call at time 'beg'")) (lambda (beg) (let ((sopening '(.00 1.00 .10 .50 .90 .50 1.00 .0)) (sup '(.00 .10 .35 .00 1.00 1.0)) (sdwn '(.00 1.00 .40 .50 1.00 .0)) (supn '(.00 .00 1.00 1.0)) (slast '(.00 1.00 .25 .00 .75 .40 1.00 .50 ))) (bird beg .51 4900 200 .3 sopening main-amp) (bird (+ beg .52) .015 3800 200 .1 sup main-amp) (bird (+ beg .52) .015 3750 250 .1 sup main-amp) (bird (+ beg .54) .015 3600 300 .1 sup main-amp) (bird (+ beg .56) .015 3500 250 .1 sup main-amp) (bird (+ beg .58) .015 3400 200 .1 sup main-amp) (bird (+ beg .60) .015 3200 200 .1 sup main-amp) (bird (+ beg .62) .015 3800 100 .1 sup main-amp) (bird (+ beg .65) .07 3000 750 .2 sup main-amp) (bird (+ beg .73) .03 5000 1000 .1 sdwn main-amp) (bird (+ beg .80) .07 3000 750 .2 sup main-amp) (bird (+ beg .88) .03 5000 1000 .1 sdwn main-amp) (bird (+ beg .95) .07 3000 750 .2 sup main-amp) (bird (+ beg 1.03) .03 5000 1000 .1 sdwn main-amp) (bird (+ beg 1.10) .07 3000 750 .2 sup main-amp) (bird (+ beg 1.18) .03 5000 1000 .1 sdwn main-amp) (bird (+ beg 1.25) .07 3000 750 .2 sup main-amp) (bird (+ beg 1.33) .03 5000 1000 .1 sdwn main-amp) (bird (+ beg 1.40) .07 3000 750 .2 sup main-amp) (bird (+ beg 1.48) .03 5000 1000 .1 sdwn main-amp) (bird (+ beg 1.55) .07 3000 750 .2 sup main-amp) (bird (+ beg 1.63) .03 5000 1000 .1 sdwn main-amp) (bird (+ beg 2.8) .06 4000 1700 .1 supn main-amp) (bird (+ beg 2.87) .01 5200 0 .2 supn main-amp) (bird (+ beg 2.9) .06 4000 1700 .1 supn main-amp) (bird (+ beg 2.97) .01 5200 0 .2 supn main-amp) (bird (+ beg 3.0) .06 4000 1700 .1 supn main-amp) (bird (+ beg 3.07) .01 5200 0 .2 supn main-amp) (bird (+ beg 3.1) .06 4000 1700 .1 supn main-amp) (bird (+ beg 3.17) .01 5200 0 .2 supn main-amp) (bird (+ beg 3.2) .06 4000 1700 .1 supn main-amp) (bird (+ beg 3.27) .01 5200 0 .2 supn main-amp) (bird (+ beg 3.4) .15 3000 1000 .2 slast main-amp) (bird (+ beg 3.6) .15 3000 1000 .2 slast main-amp) (bird (+ beg 3.8) .15 3000 1000 .2 slast main-amp) (bird (+ beg 4.0) .15 3000 1000 .2 slast main-amp) (bird (+ beg 4.2) .15 3000 1000 .2 slast main-amp) (bird (+ beg 4.4) .15 3000 1000 .2 slast main-amp))))) (define b-cedar-waxwing (let ((documentation "(cedar-waxwing beg) produces a cedar waxwing call at time 'beg'")) (lambda (beg) (let ((cedar '(.00 .00 .25 .70 .70 1.00 .90 1.00 1.00 .20 )) (cedamp '(.00 .00 .20 1.00 .40 1.00 1.00 .0))) (bird beg .50 6000 800 .2 cedar cedamp))))) (define b-bairds-sparrow (let ((documentation "(bairds-sparrow beg) produces a bairds sparrow call at time 'beg'")) (lambda (beg) (let ((bairdend '(.00 .00 .25 1.00 .50 .00 .75 1.00 1.00 .0)) (bairdstart '(.00 .50 .05 1.00 .10 .00 .15 1.00 .20 .00 .25 1.00 .30 .00 .35 1.00 .40 .00 .45 1.00 .50 .00 .55 1.00 .60 .00 .65 1.00 .70 .00 .75 1.00 .80 .00 .85 1.00 .90 .00 .95 1.00 1.00 .0))) (bird beg .09 6500 1500 .2 bairdstart main-amp) (bird (+ beg .22) .01 5900 100 .2 bairdend main-amp) (bird (+ beg .25) .09 6000 1000 .2 bairdstart main-amp) (bird (+ beg .45) .01 4200 100 .2 bairdend main-amp) (bird (+ beg .50) .08 4200 600 .2 bairdstart main-amp) (bird (+ beg .59) .01 4400 100 .2 bairdend main-amp) (bird (+ beg .60) .01 4400 100 .2 bairdend main-amp) (bird (+ beg .68) .07 5400 700 .2 bairdstart main-amp) (bird (+ beg .75) .01 4200 100 .2 bairdend main-amp) (bird (+ beg .79) .01 4400 100 .2 bairdend main-amp) (bird (+ beg .83) .01 4200 100 .19 bairdend main-amp) (bird (+ beg .87) .01 4400 100 .19 bairdend main-amp) (bird (+ beg .91) .01 4200 100 .18 bairdend main-amp) (bird (+ beg .95) .01 4400 100 .18 bairdend main-amp) (bird (+ beg .99) .01 4200 100 .17 bairdend main-amp) (bird (+ beg 1.03) .01 4400 100 .17 bairdend main-amp) (bird (+ beg 1.07) .01 4200 100 .16 bairdend main-amp) (bird (+ beg 1.11) .01 4400 100 .16 bairdend main-amp) (bird (+ beg 1.15) .01 4200 100 .15 bairdend main-amp) (bird (+ beg 1.19) .01 4400 100 .15 bairdend main-amp) (bird (+ beg 1.23) .01 4200 100 .14 bairdend main-amp) (bird (+ beg 1.27) .01 4400 100 .14 bairdend main-amp) (bird (+ beg 1.31) .01 4200 100 .13 bairdend main-amp) (bird (+ beg 1.35) .01 4400 100 .13 bairdend main-amp) (bird (+ beg 1.39) .01 4200 100 .12 bairdend main-amp) (bird (+ beg 1.43) .01 4400 100 .12 bairdend main-amp) (bird (+ beg 1.47) .01 4200 100 .11 bairdend main-amp) (bird (+ beg 1.51) .01 4400 100 .11 bairdend main-amp) (bird (+ beg 1.55) .01 4200 100 .10 bairdend main-amp) (bird (+ beg 1.59) .01 4400 100 .10 bairdend main-amp) (bird (+ beg 1.63) .01 4200 100 .09 bairdend main-amp) (bird (+ beg 1.67) .01 4400 100 .09 bairdend main-amp) (bird (+ beg 1.71) .01 4200 100 .08 bairdend main-amp) (bird (+ beg 1.75) .01 4400 100 .08 bairdend main-amp) (bird (+ beg 1.79) .01 4200 100 .07 bairdend main-amp) (bird (+ beg 1.83) .01 4400 100 .07 bairdend main-amp) (bird (+ beg 1.87) .01 4200 100 .06 bairdend main-amp) (bird (+ beg 1.92) .01 4400 100 .06 bairdend main-amp) (bird (+ beg 1.97) .01 4200 100 .05 bairdend main-amp))))) (define b-kentucky-warbler (let ((documentation "(kentucky-warbler beg) produces a kentucky warbler call at time 'beg'")) (lambda (beg) (let ((kenstart '(.00 .30 .50 1.00 1.00 .0)) (kendwn '(.00 .90 .10 1.00 1.00 .0)) (kenup '(.00 .00 1.00 1.0)) (kentrill '(.00 1.00 .25 .00 .50 .00 .75 1.00 1.00 .0))) (set! beg (- beg .6)) (bigbird (+ beg .6) .02 3800 200 .05 kenstart main-amp '(1 1 2 .03)) (bigbird (+ beg .65) .03 4300 200 .15 kenup main-amp '(1 1 2 .1)) (bigbird (+ beg .73) .02 3200 100 .1 kendwn main-amp '(1 1 2 .1)) (bigbird (+ beg .75) .05 3000 800 .15 kenstart main-amp '(1 1 2 .01)) (bigbird (+ beg .82) .06 3100 1200 .1 kendwn main-amp '(1 1 2 .01)) (bigbird (+ beg .90) .06 3200 1200 .1 kendwn main-amp '(1 1 2 .01)) (bigbird (+ beg .98) .05 4600 100 .2 kentrill main-amp '(1 1 2 .1)) (bigbird (+ beg 1.10) .05 2900 800 .15 kenstart main-amp '(1 1 2 .01)) (bigbird (+ beg 1.17) .06 3000 1200 .1 kendwn main-amp '(1 1 2 .01)) (bigbird (+ beg 1.25) .06 3100 1200 .1 kendwn main-amp '(1 1 2 .01)) (bigbird (+ beg 1.33) .05 4600 100 .2 kentrill main-amp '(1 1 2 .1)) (bigbird (+ beg 1.43) .05 2800 800 .15 kenstart main-amp '(1 1 2 .01)) (bigbird (+ beg 1.50) .05 2700 1200 .1 kendwn main-amp '(1 1 2 .01)) (bigbird (+ beg 1.57) .06 2800 1200 .1 kendwn main-amp '(1 1 2 .01)) (bigbird (+ beg 1.64) .05 4600 100 .2 kentrill main-amp '(1 1 2 .1)) (bigbird (+ beg 1.75) .05 2700 800 .15 kenstart main-amp '(1 1 2 .01)) (bigbird (+ beg 1.81) .05 2600 1200 .1 kendwn main-amp '(1 1 2 .01)) (bigbird (+ beg 1.88) .06 2600 1200 .1 kendwn main-amp '(1 1 2 .01)) (bigbird (+ beg 1.97) .05 4600 100 .2 kentrill main-amp '(1 1 2 .1)) (bigbird (+ beg 2.05) .05 2700 800 .15 kenstart main-amp '(1 1 2 .01)) (bigbird (+ beg 2.12) .06 2600 1200 .1 kendwn main-amp '(1 1 2 .01)) (bigbird (+ beg 2.20) .05 4600 100 .2 kentrill main-amp '(1 1 2 .1)) (bigbird (+ beg 2.30) .05 2800 800 .15 kenstart main-amp '(1 1 2 .01)) (bigbird (+ beg 2.37) .06 2700 1200 .1 kendwn main-amp '(1 1 2 .01)) (bigbird (+ beg 2.45) .05 4700 100 .25 kentrill main-amp '(1 1 2 .1)))))) (define b-rufous-sided-towhee (let ((documentation "(rufous-sided-towhee beg) produces a rufous sided towhee call at time 'beg'")) (lambda (beg) (let ((towhee-one '(.00 .10 .02 .05 .04 .15 .06 .05 .08 .20 .10 .04 .12 .25 .14 .03 .16 .30 .18 .02 .20 .35 .22 .01 .24 .40 .26 .00 .28 .45 .30 .00 .32 .50 .34 .00 .36 .50 .80 1.00 1.00 .0)) (towhee-two '(.00 .00 1.00 1.0)) (towhee-three '(.00 1.00 1.00 .0))) (set! beg (- beg .25)) (bigbird (+ beg .25) .13 1400 1100 .2 towhee-one main-amp '(1 .03 2 1 3 .03)) (bigbird (+ beg .45) .13 1400 1100 .2 towhee-one main-amp '(1 .03 2 1 3 .03)) (bigbird (+ beg .60) .13 1400 1100 .2 towhee-one main-amp '(1 .03 2 1 3 .03)) (bigbird (+ beg .75) .10 1400 1100 .2 towhee-one main-amp '(1 .03 2 1 3 .03)) (bird (+ beg .88) .01 5100 2000 .1 towhee-two main-amp) (bird (+ beg .895) .01 5100 1600 .1 towhee-two main-amp) (bird (+ beg .91) .01 5100 1000 .1 towhee-two main-amp) (bird (+ beg .93) .01 3000 1200 .1 towhee-three main-amp) (bird (+ beg .945) .01 5100 2000 .09 towhee-two main-amp) (bird (+ beg .96) .01 5100 1600 .09 towhee-two main-amp) (bird (+ beg .975) .01 5100 1000 .09 towhee-two main-amp) (bird (+ beg .995) .01 3000 1200 .09 towhee-three main-amp) (bird (+ beg 1.01) .01 5100 2000 .1 towhee-two main-amp) (bird (+ beg 1.025) .01 5100 1600 .1 towhee-two main-amp) (bird (+ beg 1.04) .01 5100 1000 .1 towhee-two main-amp) (bird (+ beg 1.06) .01 3000 1200 .1 towhee-three main-amp) (bird (+ beg 1.075) .01 5100 2000 .09 towhee-two main-amp) (bird (+ beg 1.09) .01 5100 1600 .09 towhee-two main-amp) (bird (+ beg 1.105) .01 5100 1000 .09 towhee-two main-amp) (bird (+ beg 1.125) .01 3000 1200 .09 towhee-three main-amp) (bird (+ beg 1.14) .01 5100 2000 .08 towhee-two main-amp) (bird (+ beg 1.155) .01 5100 1600 .08 towhee-two main-amp) (bird (+ beg 1.17) .01 5100 1000 .08 towhee-two main-amp) (bird (+ beg 1.19) .01 3000 1200 .08 towhee-three main-amp) (bird (+ beg 1.205) .01 5100 2000 .08 towhee-two main-amp) (bird (+ beg 1.220) .01 5100 1600 .08 towhee-two main-amp) (bird (+ beg 1.235) .01 5100 1000 .08 towhee-two main-amp) (bird (+ beg 1.255) .01 3000 1200 .08 towhee-three main-amp) (bird (+ beg 1.27) .01 5100 2000 .07 towhee-two main-amp) (bird (+ beg 1.285) .01 5100 1600 .07 towhee-two main-amp) (bird (+ beg 1.30) .01 5100 1000 .07 towhee-two main-amp) (bird (+ beg 1.32) .01 3000 1200 .07 towhee-three main-amp) (bird (+ beg 1.335) .01 5100 2000 .06 towhee-two main-amp) (bird (+ beg 1.350) .01 5100 1600 .06 towhee-two main-amp) (bird (+ beg 1.365) .01 5100 1000 .06 towhee-two main-amp) (bird (+ beg 1.385) .01 3000 1200 .06 towhee-three main-amp) (bird (+ beg 1.400) .01 5100 2000 .05 towhee-two main-amp) (bird (+ beg 1.415) .01 5100 1600 .05 towhee-two main-amp) (bird (+ beg 1.430) .01 5100 1000 .05 towhee-two main-amp) (bird (+ beg 1.45) .01 3000 1200 .05 towhee-three main-amp) (bird (+ beg 1.465) .01 5100 2000 .03 towhee-two main-amp) (bird (+ beg 1.480) .01 5100 1600 .03 towhee-two main-amp) (bird (+ beg 1.495) .01 5100 1000 .03 towhee-two main-amp) (bird (+ beg 1.515) .01 3000 1200 .03 towhee-three main-amp))))) (define b-prothonotary-warbler (let ((documentation "(prothonotary-warbler beg) produces a prothonotary warbler call at time 'beg'")) (lambda (beg) (let ((pro-one '(.00 .10 .20 .00 1.00 1.0)) (pro-two '(.00 .00 1.00 1.0)) (pro-amp '(.00 .00 .20 1.00 .40 .50 1.00 .0))) (set! beg (- beg .76)) (bird (+ beg .76) .08 3000 3000 .05 pro-one pro-amp) (bird (+ beg .85) .05 4000 2500 .06 pro-two bird-amp) (bird (+ beg 1.02) .09 3000 3000 .10 pro-one pro-amp) (bird (+ beg 1.12) .05 4000 2500 .10 pro-two bird-amp) (bird (+ beg 1.26) .08 3000 3000 .15 pro-one pro-amp) (bird (+ beg 1.35) .05 4000 2500 .16 pro-two bird-amp) (bird (+ beg 1.54) .08 3000 3000 .20 pro-one pro-amp) (bird (+ beg 1.63) .05 4000 2500 .19 pro-two bird-amp) (bird (+ beg 1.80) .08 3000 3000 .20 pro-one pro-amp) (bird (+ beg 1.89) .05 4000 2500 .16 pro-two bird-amp) (bird (+ beg 2.03) .08 3000 3000 .15 pro-one pro-amp) (bird (+ beg 2.12) .05 4000 2500 .10 pro-two bird-amp) (bird (+ beg 2.30) .08 3000 3000 .10 pro-one pro-amp) (bird (+ beg 2.39) .05 4000 2500 .06 pro-two bird-amp))))) (define b-audubons-warbler (let ((documentation "(audubons-warbler beg) produces an audubons warbler (yellow-rumped warbler) call at time 'beg'")) (lambda (beg) (let ( ;; (yellow-rumped say the revisionists)) (w-up '(.00 .00 1.00 1.0)) (w-down '(.00 1.00 1.00 .0)) (w-end '(.00 .00 .15 1.00 .45 .90 .50 .00 .55 1.00 .90 .90 1.00 .10 )) (w-updown '(.00 .10 .50 1.00 1.00 .0))) (set! beg (- beg .75)) (bird (+ beg .75) .04 2400 200 .05 w-down bird-amp) (bird (+ beg .83) .03 3200 200 .1 w-up bird-amp) (bird (+ beg .90) .04 2500 300 .15 w-up bird-amp) (bird (+ beg .97) .04 2300 600 .15 w-down bird-amp) (bird (+ beg 1.02) .03 3500 400 .20 w-up bird-amp) (bird (+ beg 1.06) .04 2300 1200 .10 w-up bird-amp) (bird (+ beg 1.13) .05 2300 1200 .15 w-down bird-amp) (bird (+ beg 1.22) .02 3200 800 .25 w-up bird-amp) (bird (+ beg 1.25) .08 2400 600 .20 w-updown bird-amp) (bird (+ beg 1.35) .02 2200 400 .10 w-up bird-amp) (bird (+ beg 1.38) .07 2400 1400 .15 w-down bird-amp) (bird (+ beg 1.47) .03 3000 800 .20 w-up bird-amp) (bird (+ beg 1.50) .03 2500 400 .10 w-updown bird-amp) (bird (+ beg 1.55) .01 2300 100 .05 w-up bird-amp) (bird (+ beg 1.56) .06 2200 1400 .15 w-down bird-amp) (bird (+ beg 1.65) .03 3100 800 .10 w-up bird-amp) (bird (+ beg 1.70) .07 2800 800 .15 w-updown bird-amp) (bird (+ beg 1.79) .06 2400 1000 .10 w-down bird-amp) (bird (+ beg 1.86) .14 3100 900 .25 w-end bird-amp) (bird (+ beg 2.02) .12 3200 800 .20 w-end bird-amp))))) (define b-lark-bunting (let ((documentation "(lark-bunting beg) produces a lark bunting call at time 'beg'")) (lambda (beg) (let ((b-down '(.00 1.00 1.00 .0)) (b-up '(.00 .00 1.00 1.0)) (b-trill-one '(.00 .00 .06 .80 .12 .00 .18 .85 .24 .05 .36 .90 .42 .10 .48 .95 .54 .20 .60 1.00 .66 .20 .72 1.00 .78 .20 .84 1.00 .90 .20 1.00 1.0)) (b-trill-two '(.00 .00 .05 .80 .10 .00 .15 .85 .20 .00 .25 .90 .30 .00 .35 .95 .40 .00 .45 1.00 .50 .00 .55 1.00 .60 .00 .65 1.00 .70 .00 .75 1.00 .80 .00 .85 1.00 .90 .00 .95 1.00 1.00 .0))) (set! beg (- beg .1)) (bird (+ beg .1) .03 1800 100 .1 b-up bird-amp) (bird (+ beg .2) .12 3700 400 .2 b-up bird-amp) (bird (+ beg .4) .03 4100 500 .15 b-down bird-amp) (bird (+ beg .45) .05 2000 400 .20 b-down bird-amp) (bird (+ beg .51) .03 1800 100 .1 b-up bird-amp) (bird (+ beg .6) .03 4100 500 .15 b-down bird-amp) (bird (+ beg .65) .05 2000 400 .20 b-down bird-amp) (bird (+ beg .71) .03 1800 100 .1 b-up bird-amp) (bird (+ beg .8) .03 4100 500 .15 b-down bird-amp) (bird (+ beg .85) .05 2000 400 .20 b-down bird-amp) (bird (+ beg .91) .03 1800 100 .1 b-up bird-amp) (bird (+ beg 1.0) .03 4100 500 .15 b-down bird-amp) (bird (+ beg 1.05) .05 2000 400 .20 b-down bird-amp) (bird (+ beg 1.11) .03 1800 100 .1 b-up bird-amp) (bird (+ beg 1.2) .03 4100 500 .15 b-down bird-amp) (bird (+ beg 1.25) .05 2000 400 .20 b-down bird-amp) (bird (+ beg 1.31) .03 1800 100 .1 b-up bird-amp) (bird (+ beg 1.4) .03 4100 500 .15 b-down bird-amp) (bird (+ beg 1.45) .05 2000 400 .20 b-down bird-amp) (bird (+ beg 1.51) .03 1800 100 .1 b-up bird-amp) (bird (+ beg 1.6) .03 4100 500 .15 b-down bird-amp) (bird (+ beg 1.65) .05 2000 400 .20 b-down bird-amp) (bird (+ beg 1.71) .03 1800 100 .1 b-up bird-amp) (bird (+ beg 1.77) .23 6000 600 .15 b-trill-one bird-amp) (bird (+ beg 2.005) .28 6000 600 .15 b-trill-two bird-amp))))) (define b-eastern-bluebird (let ((documentation "(eastern-bluebird beg) produces an eastern bluebird call at time 'beg'")) (lambda (beg) (let ((blue-one '(.00 .00 1.00 1.0)) (blue-two '(.00 1.00 1.00 .0)) (blue-three '(.00 .60 .10 1.00 .20 .00 .25 1.00 .30 .00 .35 1.00 .40 .00 .45 1.00 .50 .00 .75 1.00 1.00 .0)) (blue-four '(.00 .00 .50 1.00 1.00 .0)) (blue-five '(.00 .50 .10 1.00 .20 .00 .35 1.00 .50 .00 .65 1.00 .80 .00 .95 1.00 1.00 .50 ))) (set! beg (- beg .75)) (bird (+ beg .75) .02 2000 1600 .1 blue-one bird-amp) (bird (+ beg .80) .02 2000 1600 .1 blue-one bird-amp) (bird (+ beg .86) .02 2000 1600 .1 blue-one bird-amp) (bird (+ beg 1.00) .13 2000 1400 .2 blue-two bird-amp) (bird (+ beg 1.20) .24 2000 800 .2 blue-three bird-amp) (bird (+ beg 1.68) .03 2200 400 .1 blue-one bird-amp) (bird (+ beg 1.72) .10 1950 100 .15 blue-four bird-amp) (bird (+ beg 1.96) .15 2000 600 .20 blue-five bird-amp))))) (define b-chuck-wills-widow (let ((documentation "(chuck-wills-widow beg) produces a chuck wills widow call at time 'beg'")) (lambda (beg) (let ((wid-down '(.00 1.00 1.00 .0)) (wid-one '(.00 .00 .10 .10 .25 1.00 .50 .30 .80 .70 1.00 .0)) (wid-two '(.00 .20 .30 1.00 .50 .30 .60 .70 .90 .10 1.00 .0))) (set! beg (- beg .05)) (bird (+ beg .05) .03 1000 800 .1 wid-down bird-amp) (bird (+ beg .32) .20 1000 1000 .2 wid-one bird-amp) (bird (+ beg .56) .29 900 1100 .2 wid-two bird-amp))))) (define b-blue-gray-gnatcatcher (let ((documentation "(blue-gray-gnatcatcher beg) produces a blue gray gnatcatcher call at time 'beg'")) (lambda (beg) (let ((gskw1 '(.00 .00 .15 1.00 .75 .80 .90 1.00 1.00 .70 )) (gskw2 '(.00 .00 .25 1.00 .75 .70 1.00 .0))) (set! beg (- beg .5)) (bigbird (+ beg .5) .20 4000 1000 .2 gskw1 bird-amp '(1 .4 2 1 3 .1)) (bigbird (+ beg .8) .13 4000 800 .2 gskw2 bird-amp '(1 .4 2 1 3 .2)) (bigbird (+ beg 1.4) .25 4000 800 .2 gskw2 bird-amp '(1 .4 2 1 3 .3)) (bigbird (+ beg 1.80) .17 4000 900 .2 gskw1 bird-amp '(1 .4 2 1 3 .3)) (bigbird (+ beg 2.00) .17 4000 700 .2 gskw1 bird-amp '(1 .4 2 1 3 .3)) (bigbird (+ beg 2.20) .17 4000 800 .2 gskw2 bird-amp '(1 .4 2 1 3 .3)))))) (define b-black-throated-sparrow (let ((documentation "(black-throated-sparrow beg) produces a black throated sparrow call at time 'beg'")) (lambda (beg) (let ((black-up '(.00 .00 1.00 1.0)) (black-down '(.00 1.00 1.00 .0)) (black-down-amp '(.00 .00 .75 1.00 1.00 .0)) (black-trill '(.00 .00 .03 .70 .06 .00 .09 .75 .12 .00 .15 .80 .18 .05 .21 .85 .24 .10 .27 .90 .30 .10 .33 1.00 .36 .10 .39 1.00 .42 .10 .45 1.00 .48 .10 .51 1.00 .54 .10 .57 1.00 .60 .10 .63 1.00 .66 .10 .69 1.00 .72 .10 .75 1.00 .78 .10 .81 1.00 .84 .10 .87 1.00 .90 .00 .93 .95 .96 .00 1.00 .90 )) (black-up-down '(.00 .00 .50 1.00 1.00 .20 )) (black-amp '(.00 .00 .50 1.00 1.00 .0))) (set! beg (- beg .8)) (bird (+ beg .8) .02 2200 1000 .1 black-down bird-amp) (bird (+ beg .83) .01 3000 200 .05 black-up bird-amp) (bird (+ beg .96) .02 5800 500 .05 black-up bird-amp) (bird (+ beg 1.00) .02 4000 200 .05 black-up bird-amp) (bird (+ beg 1.04) .10 2100 1700 .15 black-down black-down-amp) (bird (+ beg 1.15) .05 5700 400 .25 black-up bird-amp) (bird (+ beg 1.25) .25 2000 900 .2 black-trill bird-amp) (bird (+ beg 1.52) .05 5600 400 .15 black-up-down bird-amp) (bird (+ beg 1.6) .04 3900 1100 .15 black-up bird-amp) (bird (+ beg 1.66) .01 1900 100 .10 black-up black-amp) (bird (+ beg 1.69) .01 3600 300 .10 black-up black-amp) (bird (+ beg 1.71) .03 3900 1000 .15 black-up black-amp) (bird (+ beg 1.74) .02 5000 100 .20 black-up black-amp) (bird (+ beg 1.76) .01 1900 100 .10 black-up black-amp) (bird (+ beg 1.78) .01 3600 300 .10 black-up black-amp) (bird (+ beg 1.80) .03 3900 1000 .15 black-up black-amp) (bird (+ beg 1.83) .02 5000 100 .20 black-up black-amp) (bird (+ beg 1.85) .01 1900 100 .10 black-up black-amp) (bird (+ beg 1.87) .01 3600 300 .10 black-up black-amp) (bird (+ beg 1.89) .03 3900 1000 .15 black-up black-amp) (bird (+ beg 1.92) .02 5000 100 .20 black-up black-amp) (bird (+ beg 1.94) .01 1900 100 .10 black-up black-amp) (bird (+ beg 1.96) .01 3600 300 .10 black-up black-amp) (bird (+ beg 1.98) .03 3900 1000 .15 black-up black-amp) (bird (+ beg 2.01) .02 5000 100 .20 black-up black-amp) (bird (+ beg 2.03) .01 1900 100 .10 black-up black-amp) (bird (+ beg 2.05) .01 3600 300 .10 black-up black-amp) (bird (+ beg 2.07) .03 3900 1000 .15 black-up black-amp) (bird (+ beg 2.10) .02 5000 100 .20 black-up black-amp) (bird (+ beg 2.13) .01 1900 100 .10 black-up black-amp) (bird (+ beg 2.16) .03 3800 300 .1 black-up bird-amp))))) (define b-black-chinned-sparrow (let ((documentation "(black-chinned-sparrow beg) produces a black chinned sparrow call at time 'beg'")) (lambda (beg) (let ((chin-up '(.00 .00 1.00 1.0)) (chin-up2 '(.00 .00 .30 .20 1.00 1.0))) (set! beg (- beg .6)) (bird (+ beg .6) .2 4200 100 .1 chin-up bird-amp) (bird (+ beg 1.0) .09 3800 2000 .1 chin-up2 bird-amp) (bird (+ beg 1.25) .08 3900 1700 .12 chin-up2 bird-amp) (bird (+ beg 1.40) .08 3600 2300 .13 chin-up bird-amp) (bird (+ beg 1.50) .11 3100 2800 .14 chin-up bird-amp) (bird (+ beg 1.65) .07 2900 2700 .15 chin-up bird-amp) (bird (+ beg 1.74) .07 2900 2700 .15 chin-up bird-amp) (bird (+ beg 1.82) .07 3000 2300 .13 chin-up bird-amp) (bird (+ beg 1.89) .07 3200 2000 .10 chin-up bird-amp) (bird (+ beg 1.97) .05 3200 1500 .10 chin-up bird-amp) (bird (+ beg 2.04) .04 3400 1000 .07 chin-up bird-amp) (bird (+ beg 2.10) .03 3600 700 .05 chin-up bird-amp) (bird (+ beg 2.15) .03 3800 300 .05 chin-up bird-amp) (bird (+ beg 2.19) .02 3900 100 .03 chin-up bird-amp) (bird (+ beg 2.22) .01 3900 100 .01 chin-up bird-amp) (bird (+ beg 2.24) .01 3900 100 .01 chin-up bird-amp))))) (define various-gull-cries-from-end-of-colony-5 (let ((documentation "(various-gull-cries-from-end-of-colony-5 beg) produces a various gull cries at time 'beg'")) (lambda (beg) (let ((gullstart '(0 0 10 1 20 .5000 40 .6000 60 .5000 100 0 )) (gullmiddle '(0 0 10 1 30 .5000 80 .5000 100 0 )) (gullend '(0 0 5 1 10 .5000 90 .4000 100 0 ))) (set! beg (- beg .25)) (bigbird (+ beg .250) .80 1180 1180 .08 gullend bird-amp '(1 .1 2 1 3 .1 4 .01 5 .09 6 .01 7 .01)) (bigbird (+ beg 1.500) .90 1180 1180 .07 gullend bird-amp '(1 .1 2 1 3 .1 4 .01 5 .09 6 .01 7 .01)) (bigbird (+ beg 2.750) 1.00 1050 1050 .08 gullend bird-amp '(1 .1 2 1 3 .1 4 .01 5 .09 6 .01 7 .01)) (bigbird (+ beg 4.800) .05 1180 1180 .06 gullstart bird-amp '(1 .1 2 1 3 .1 4 .01 5 .09 6 .01 7 .01)) (bigbird (+ beg 4.950) .10 1180 1180 .08 gullstart bird-amp '(1 .1 2 1 3 .1 4 .01 5 .09 6 .01 7 .01)) (bigbird (+ beg 5.150) .10 1180 1180 .09 gullstart bird-amp '(1 .1 2 1 3 .1 4 .01 5 .09 6 .01 7 .01)) (bigbird (+ beg 5.350) .10 1180 1180 .1 gullmiddle bird-amp '(1 .1 2 1 3 .1 4 .01 5 .09 6 .01 7 .01)) (bigbird (+ beg 5.450) .40 1050 1050 .1 gullend bird-amp '(1 .1 2 1 3 .1 4 .01 5 .09 6 .01 7 .01)) (bigbird (+ beg 6.250) .80 1050 1050 .1 gullend bird-amp '(1 .1 2 1 3 .1 4 .01 5 .09 6 .01 7 .01)) (bigbird (+ beg 7.450) 1.80 1050 1050 .1 gullend bird-amp '(1 .1 2 1 3 .1 4 .01 5 .09 6 .01 7 .01)))))) (define make-birds (let ((documentation "(make-birds) calls all the birds in bird.scm")) (lambda () (with-sound (:clipped #f) (b-orchard-oriole 0) (b-cassins-kingbird 3) (b-chipping-sparrow 6) (b-bobwhite 9) (b-western-meadowlark 12) (b-scissor-tailed-flycatcher 15) (b-great-horned-owl 18) (b-black-throated-gray-warbler 21) (b-yellow-warbler 24) (b-black-necked-stilt 27) (b-chestnut-sided-warbler 30) (b-grasshopper-sparrow 33) (b-swamp-sparrow 36) (b-golden-crowned-sparrow 39) (b-indigo-bunting 42) (b-hooded-warbler 45) (b-american-widgeon 48) (b-louisiana-waterthrush 51) (b-robin 54) (b-solitary-vireo 57) (b-pigeon-hawk 61) (b-cerulean-warbler 64) (b-nashville-warbler 67) (b-eastern-phoebe 70) (b-painted-bunting 73) (b-western-flycatcher 76) (b-bachmans-sparrow 79) (b-cedar-waxwing 82) (b-bairds-sparrow 85) (b-kentucky-warbler 88) (b-rufous-sided-towhee 91) (b-prothonotary-warbler 94) (b-audubons-warbler 97) (b-lark-bunting 100) (b-eastern-bluebird 103) (b-chuck-wills-widow 106) (b-blue-gray-gnatcatcher 109) (b-black-throated-sparrow 112) (b-black-chinned-sparrow 115) (various-gull-cries-from-end-of-colony-5 118))))) snd-16.1/sound.c0000644000076400007640000011273212524201705011633 0ustar bilbil#include "mus-config.h" #if USE_SND #include "snd.h" #endif #include #include #include #include #include #include #include #include #include #ifndef _MSC_VER #include #else #include #pragma warning(disable: 4244) #endif #include #include "_sndlib.h" #include "sndlib-strings.h" static mus_error_handler_t *mus_error_handler = NULL; mus_error_handler_t *mus_error_set_handler(mus_error_handler_t *new_error_handler) { mus_error_handler_t *old_handler; old_handler = mus_error_handler; mus_error_handler = new_error_handler; return(old_handler); } static char *mus_error_buffer = NULL; static int mus_error_buffer_size = 1024; int mus_error(int error, const char *format, ...) { int bytes_needed = 0; va_list ap; if (format == NULL) return(MUS_ERROR); /* else bus error in Mac OSX */ if (mus_error_buffer == NULL) mus_error_buffer = (char *)calloc(mus_error_buffer_size, sizeof(char)); va_start(ap, format); /* can't use vasprintf here or below because the error handler may jump anywhere, * leaving unfreed memory behind. */ bytes_needed = vsnprintf(mus_error_buffer, mus_error_buffer_size, format, ap); va_end(ap); if (bytes_needed >= mus_error_buffer_size) { mus_error_buffer_size = bytes_needed * 2; free(mus_error_buffer); mus_error_buffer = (char *)calloc(mus_error_buffer_size, sizeof(char)); va_start(ap, format); vsnprintf(mus_error_buffer, mus_error_buffer_size, format, ap); va_end(ap); } if (mus_error_handler) (*mus_error_handler)(error, mus_error_buffer); else { fprintf(stderr, "%s", mus_error_buffer); fputc('\n', stderr); } return(MUS_ERROR); } static mus_print_handler_t *mus_print_handler = NULL; mus_print_handler_t *mus_print_set_handler(mus_print_handler_t *new_print_handler) { mus_print_handler_t *old_handler; old_handler = mus_print_handler; mus_print_handler = new_print_handler; return(old_handler); } void mus_print(const char *format, ...) { va_list ap; if (mus_print_handler) { int bytes_needed = 0; if (mus_error_buffer == NULL) mus_error_buffer = (char *)calloc(mus_error_buffer_size, sizeof(char)); va_start(ap, format); bytes_needed = vsnprintf(mus_error_buffer, mus_error_buffer_size, format, ap); va_end(ap); if (bytes_needed >= mus_error_buffer_size) { mus_error_buffer_size = bytes_needed * 2; free(mus_error_buffer); mus_error_buffer = (char *)calloc(mus_error_buffer_size, sizeof(char)); va_start(ap, format); vsnprintf(mus_error_buffer, mus_error_buffer_size, format, ap); va_end(ap); } (*mus_print_handler)(mus_error_buffer); } else { va_start(ap, format); vfprintf(stdout, format, ap); va_end(ap); } } static const char *mus_error_names[MUS_NUM_ERRORS] = { "no error", "no frequency method", "no phase method", "null gen arg to method", "no length method", "no describe method", "no data method", "no scaler method", "memory allocation failed", "can't open file", "no sample input", "no sample output", "no such channel", "no file name provided", "no location method", "no channel method", "no such fft window", "unknown sample type", "header read failed", "unknown header type", "file descriptors not initialized", "not a sound file", "file closed", "write error", "header write failed", "can't open temp file", "interrupted", "bad envelope", "audio channels not available", "audio srate not available", "audio sample type not available", "no audio input available", "audio configuration not available", "audio write error", "audio size not available", "audio device not available", "can't close audio", "can't open audio", "audio read error", "can't write audio", "can't read audio", "no audio read permission", "can't close file", "arg out of range", "no channels method", "no hop method", "no width method", "no file-name method", "no ramp method", "no run method", "no increment method", "no offset method", "no xcoeff method", "no ycoeff method", "no xcoeffs method", "no ycoeffs method", "no reset", "bad size", "can't convert", "read error", "no feedforward method", "no feedback method", "no interp-type method", "no position method", "no order method", "no copy method", "can't translate" }; const char *mus_error_type_to_string(int err) { if ((err >= 0) && (err < MUS_NUM_ERRORS)) return(mus_error_names[err]); return("unknown mus error"); } static void default_mus_error(int ignore, char *msg) { /* default error handler simply prints the error message */ fprintf(stderr, "%s", msg); } static time_t local_file_write_date(const char *filename) { struct stat statbuf; int err; err = stat(filename, &statbuf); if (err < 0) return((time_t)0); return((time_t)(statbuf.st_mtime)); } /* -------- sound file table -------- */ typedef struct sound_file { char *file_name; /* full path -- everything is keyed to this name */ int table_pos, file_name_length, table_index; mus_long_t *aux_comment_start, *aux_comment_end; int *loop_modes, *loop_starts, *loop_ends; int markers, base_detune, base_note; int *marker_ids, *marker_positions; mus_long_t samples, true_file_length; mus_long_t data_location; int srate, chans, original_sound_samp_type, datum_size; mus_header_t header_type; mus_sample_t sample_type; mus_long_t comment_start, comment_end; int type_specifier, bits_per_sample, block_align, fact_samples; time_t write_date; mus_float_t *maxamps; mus_long_t *maxtimes; int maxamps_size; /* we can't depend on sf->chans here because the user could set chans to some bogus value */ mus_float_t **saved_data; struct sound_file *next; } sound_file; static int *sound_table_sizes = NULL; static sound_file ***sound_tables = NULL; #define NUM_SOUND_TABLES 64 /* it's not enough to hash on the file name length -- they're nearly all the same length! * I think I'll try taking the last few chars instead (the first 15-20 chars are * also always the same: the tmp directory, eg: /home/bil/zap/tmp/snd_16687_632.snd). */ static int sound_file_hash_index(const char *name, int len) { unsigned char *s; if (!name) return(0); if (len < 8) return(len); s = (unsigned char *)(name + len - 8); return((s[0] + s[1] + s[2] + s[3]) % NUM_SOUND_TABLES); } void scan_io_fds_for_saved_data(mus_float_t **data); static sound_file *sf_free_list = NULL; static void free_sound_file(sound_file *sf) { if (sf) { sound_tables[sf->table_index][sf->table_pos] = NULL; if (sf->aux_comment_start) free(sf->aux_comment_start); if (sf->aux_comment_end) free(sf->aux_comment_end); if (sf->file_name) free(sf->file_name); if (sf->loop_modes) free(sf->loop_modes); if (sf->loop_starts) free(sf->loop_starts); if (sf->loop_ends) free(sf->loop_ends); if (sf->marker_ids) free(sf->marker_ids); if (sf->marker_positions) free(sf->marker_positions); if (sf->maxamps) free(sf->maxamps); if (sf->maxtimes) free(sf->maxtimes); sf->maxamps_size = 0; if (sf->saved_data) { int i; scan_io_fds_for_saved_data(sf->saved_data); for (i = 0; i < sf->chans; i++) if (sf->saved_data[i]) free(sf->saved_data[i]); free(sf->saved_data); sf->saved_data = NULL; } /* free(sf); */ sf->next = sf_free_list; sf_free_list = sf; } } static sound_file *add_to_sound_table(const char *name) { int i, len, pos = -1, index, sound_table_size; sound_file **sound_table; sound_file *sf; len = strlen(name); index = sound_file_hash_index(name, len); sound_table = sound_tables[index]; sound_table_size = sound_table_sizes[index]; for (i = 0; i < sound_table_size; i++) if (sound_table[i] == NULL) { pos = i; break; } if (pos == -1) { pos = sound_table_size; sound_table_size += 16; if (sound_table == NULL) { sound_table = (sound_file **)calloc(sound_table_size, sizeof(sound_file *)); } else { sound_table = (sound_file **)realloc(sound_table, sound_table_size * sizeof(sound_file *)); for (i = pos; i < sound_table_size; i++) sound_table[i] = NULL; } sound_tables[index] = sound_table; sound_table_sizes[index] = sound_table_size; } if (sf_free_list) { sf = sf_free_list; sf_free_list = sf->next; memset((void *)sf, 0, sizeof(sound_file)); } else sf = (sound_file *)calloc(1, sizeof(sound_file)); sound_table[pos] = sf; sf->table_pos = pos; sf->table_index = index; sf->file_name = (char *)malloc((len + 1) * sizeof(char)); strcpy(sf->file_name, name); sf->file_name[len] = 0; sf->file_name_length = len; sf->saved_data = NULL; return(sf); } int mus_sound_prune(void) { int j, pruned = 0; for (j = 0; j < NUM_SOUND_TABLES; j++) { int i, sound_table_size; sound_file **sound_table; sound_table = sound_tables[j]; sound_table_size = sound_table_sizes[j]; for (i = 0; i < sound_table_size; i++) if ((sound_table[i]) && (!(mus_file_probe(sound_table[i]->file_name)))) { free_sound_file(sound_table[i]); sound_table[i] = NULL; pruned++; } } return(pruned); } int mus_sound_forget(const char *name) { /* apparently here we want to forget either name or the expanded or contracted forms of name -- as many as we find! */ int i, len, len2, short_len = 0; bool free_name = false; char *short_name = NULL; sound_file **sound_table; int sound_table_size, index; char c; if (name == NULL) return(MUS_ERROR); len = strlen(name); if (len > 6) len2 = len - 6; else len2 = len / 2; c = name[len2]; if (name[0] == '/') { for (i = 0; i < len; i++) if (name[i] == '/') short_name = (char *)(name + i + 1); } else { short_name = mus_expand_filename(name); free_name = true; } if (short_name) short_len = strlen(short_name); index = sound_file_hash_index(name, len); sound_table = sound_tables[index]; sound_table_size = sound_table_sizes[index]; for (i = 0; i < sound_table_size; i++) if ((sound_table[i]) && (sound_table[i]->file_name_length == len) && (sound_table[i]->file_name[len2] == c) && (mus_strcmp(name, sound_table[i]->file_name))) { free_sound_file(sound_table[i]); sound_table[i] = NULL; } if (short_name) { if (short_len > 6) len2 = short_len - 6; else len2 = short_len / 2; c = short_name[len2]; index = sound_file_hash_index(short_name, short_len); sound_table = sound_tables[index]; sound_table_size = sound_table_sizes[index]; for (i = 0; i < sound_table_size; i++) if ((sound_table[i]) && (sound_table[i]->file_name_length == short_len) && (sound_table[i]->file_name[len2] == c) && (mus_strcmp(short_name, sound_table[i]->file_name))) { free_sound_file(sound_table[i]); sound_table[i] = NULL; } } if (free_name) free(short_name); return(MUS_NO_ERROR); } static sound_file *check_write_date(const char *name, sound_file *sf) { if (sf) { time_t date; date = local_file_write_date(name); if (date == sf->write_date) return(sf); if ((sf->header_type == MUS_RAW) && (mus_header_no_header(name))) { int chan; mus_long_t data_size; /* sound has changed since we last read it, but it has no header, so * the only sensible thing to check is the new length (i.e. caller * has set other fields by hand) */ sf->write_date = date; chan = mus_file_open_read(name); data_size = lseek(chan, 0L, SEEK_END); sf->true_file_length = data_size; sf->samples = mus_bytes_to_samples(sf->sample_type, data_size); CLOSE(chan, name); return(sf); } /* otherwise our data base is out-of-date, so clear it out */ free_sound_file(sf); } return(NULL); } static sound_file *find_sound_file(const char *name) { /* assume name != NULL */ int i, len, len2; sound_file **sound_table; int sound_table_size, index; char c; len = strlen(name); if (len > 6) len2 = len - 6; /* the names probably all start with '/' and end with ".snd", so try to find a changing character... */ else len2 = len / 2; c = name[len2]; index = sound_file_hash_index(name, len); sound_table = sound_tables[index]; sound_table_size = sound_table_sizes[index]; for (i = 0; i < sound_table_size; i++) { sound_file *sf; sf = sound_table[i]; if ((sf) && (sf->file_name_length == len) && (c == sf->file_name[len2]) && (strcmp(name, sf->file_name) == 0)) return(check_write_date(name, sf)); } return(NULL); } static void display_sound_file_entry(FILE *fp, const char *name, sound_file *sf) { #define TIME_BUFFER_SIZE 64 time_t date; char timestr[TIME_BUFFER_SIZE]; date = sf->write_date; if (date != 0) strftime(timestr, TIME_BUFFER_SIZE, "%a %d-%b-%Y %H:%M:%S", localtime(&date)); else snprintf(timestr, TIME_BUFFER_SIZE, "(date cleared)"); fprintf(fp, " %s: %s, chans: %d, srate: %d, header: %s, data: %s, samps: %lld", name, timestr, sf->chans, sf->srate, mus_header_type_name(sf->header_type), mus_sample_type_name(sf->sample_type), sf->samples); if (sf->loop_modes) { if (sf->loop_modes[0] != 0) fprintf(fp, ", loop mode %d: %d to %d", sf->loop_modes[0], sf->loop_starts[0], sf->loop_ends[0]); if (sf->loop_modes[1] != 0) fprintf(fp, ", loop mode %d: %d to %d, ", sf->loop_modes[1], sf->loop_starts[1], sf->loop_ends[1]); fprintf(fp, ", base: %d, detune: %d", sf->base_note, sf->base_detune); } if (sf->maxamps) { int lim; lim = sf->maxamps_size; if (lim > 0) { int i; if (lim > 64) lim = 64; fprintf(fp, ", maxamp:"); for (i = 0; i < lim; i++) { if (i > 1) fprintf(fp, ", "); fprintf(fp, " %.3f at %.3f ", sf->maxamps[i], (sf->srate > 0) ? (float)((double)(sf->maxtimes[i]) / (double)(sf->srate)) : (float)(sf->maxtimes[i])); } } } if (mus_file_probe(name)) { char *comment; comment = mus_sound_comment(name); if (comment) { fprintf(fp, "\n comment: %s", comment); free(comment); } } else fprintf(fp, " [defunct]"); fprintf(fp, "\n"); } void mus_sound_report_cache(FILE *fp) { sound_file *sf; int entries = 0; int i, j; sound_file **sound_table; fprintf(fp, "sound table:"); for (j = 0; j < NUM_SOUND_TABLES; j++) { int sound_table_size; sound_table = sound_tables[j]; sound_table_size = sound_table_sizes[j]; for (i = 0; i < sound_table_size; i++) { sf = sound_table[i]; if (sf) { if (entries == 0) fprintf(fp, "\n"); display_sound_file_entry(fp, sf->file_name, sf); entries++; } } } if (entries > 0) fprintf(fp, "\nentries: %d\n", entries); else fprintf(fp, " empty"); fflush(fp); } static sound_file *fill_sf_record(const char *name, sound_file *sf) { int i; sf->data_location = mus_header_data_location(); sf->samples = mus_header_samples(); sf->sample_type = mus_header_sample_type(); sf->srate = mus_header_srate(); /* if (sf->srate < 0) sf->srate = 0; */ sf->chans = mus_header_chans(); /* if (sf->chans < 0) sf->chans = 0; */ sf->datum_size = mus_bytes_per_sample(sf->sample_type); sf->header_type = mus_header_type(); sf->original_sound_samp_type = mus_header_original_sample_type(); sf->true_file_length = mus_header_true_length(); sf->comment_start = mus_header_comment_start(); sf->comment_end = mus_header_comment_end(); if (((sf->header_type == MUS_AIFC) || (sf->header_type == MUS_AIFF) || (sf->header_type == MUS_RF64) || (sf->header_type == MUS_RIFF)) && (mus_header_aux_comment_start(0) != 0)) { sf->aux_comment_start = (mus_long_t *)calloc(4, sizeof(mus_long_t)); sf->aux_comment_end = (mus_long_t *)calloc(4, sizeof(mus_long_t)); for (i = 0; i < 4; i++) { sf->aux_comment_start[i] = mus_header_aux_comment_start(i); sf->aux_comment_end[i] = mus_header_aux_comment_end(i); } } sf->type_specifier = mus_header_type_specifier(); sf->bits_per_sample = mus_header_bits_per_sample(); sf->fact_samples = mus_header_fact_samples(); sf->block_align = mus_header_block_align(); sf->write_date = local_file_write_date(name); if ((sf->header_type == MUS_AIFF) || (sf->header_type == MUS_AIFC)) { int *marker_ids, *marker_positions; sf->markers = mus_header_mark_info(&marker_ids, &marker_positions); if (sf->markers > 0) { sf->marker_ids = (int *)malloc(sf->markers * sizeof(int)); sf->marker_positions = (int *)malloc(sf->markers * sizeof(int)); memcpy((void *)(sf->marker_ids), (void *)marker_ids, sizeof(int) * sf->markers); memcpy((void *)(sf->marker_positions), (void *)marker_positions, sizeof(int) * sf->markers); } } if (mus_header_loop_mode(0) > 0) { sf->loop_modes = (int *)calloc(2, sizeof(int)); sf->loop_starts = (int *)calloc(2, sizeof(int)); sf->loop_ends = (int *)calloc(2, sizeof(int)); for (i = 0; i < 2; i++) { sf->loop_modes[i] = mus_header_loop_mode(i); if ((sf->header_type == MUS_AIFF) || (sf->header_type == MUS_AIFC)) { sf->loop_starts[i] = mus_header_mark_position(mus_header_loop_start(i)); sf->loop_ends[i] = mus_header_mark_position(mus_header_loop_end(i)); } else { sf->loop_starts[i] = mus_header_loop_start(i); sf->loop_ends[i] = mus_header_loop_end(i); } } sf->base_detune = mus_header_base_detune(); sf->base_note = mus_header_base_note(); } return(sf); } static sound_file *read_sound_file_header(const char *name) /* 2 calls on this: mus_sound_open_input and get_sf */ { int result; mus_sound_initialize(); result = mus_header_read(name); /* this portion won't trigger mus_error */ if (result != MUS_ERROR) return(fill_sf_record(name, add_to_sound_table(name))); /* only call on fill_sf_record and add_to_sound_table */ return(NULL); } static sound_file *get_sf(const char *arg) { sound_file *sf = NULL; if (arg == NULL) return(NULL); sf = find_sound_file(arg); return((sf) ? sf : read_sound_file_header(arg)); } mus_long_t mus_sound_samples(const char *arg) { sound_file *sf; sf = get_sf(arg); return((sf) ? sf->samples : (mus_long_t)MUS_ERROR); } mus_long_t mus_sound_framples(const char *arg) { sound_file *sf; sf = get_sf(arg); return((sf) ? ((sf->chans > 0) ? (sf->samples / sf->chans) : 0) : (mus_long_t)MUS_ERROR); } int mus_sound_datum_size(const char *arg) { sound_file *sf; sf = get_sf(arg); return((sf) ? sf->datum_size : MUS_ERROR); } mus_long_t mus_sound_data_location(const char *arg) { sound_file *sf; sf = get_sf(arg); return((sf) ? sf->data_location : MUS_ERROR); } int mus_sound_chans(const char *arg) { sound_file *sf; sf = get_sf(arg); return((sf) ? sf->chans : MUS_ERROR); } int mus_sound_srate(const char *arg) { sound_file *sf; sf = get_sf(arg); return((sf) ? sf->srate : MUS_ERROR); } mus_header_t mus_sound_header_type(const char *arg) { sound_file *sf; sf = get_sf(arg); return((sf) ? sf->header_type : MUS_UNKNOWN_HEADER); } mus_sample_t mus_sound_sample_type(const char *arg) { sound_file *sf; sf = get_sf(arg); return((sf) ? sf->sample_type : MUS_UNKNOWN_SAMPLE); } int mus_sound_original_sample_type(const char *arg) { sound_file *sf; sf = get_sf(arg); return((sf) ? sf->original_sound_samp_type : MUS_ERROR); } mus_long_t mus_sound_comment_start(const char *arg) { sound_file *sf; sf = get_sf(arg); return((sf) ? sf->comment_start : (mus_long_t)MUS_ERROR); } mus_long_t mus_sound_comment_end(const char *arg) { sound_file *sf; sf = get_sf(arg); return((sf) ? sf->comment_end : (mus_long_t)MUS_ERROR); } mus_long_t mus_sound_length(const char *arg) { sound_file *sf; sf = get_sf(arg); return((sf) ? sf->true_file_length : (mus_long_t)MUS_ERROR); } int mus_sound_fact_samples(const char *arg) { sound_file *sf; sf = get_sf(arg); return((sf) ? sf->fact_samples : MUS_ERROR); } time_t mus_sound_write_date(const char *arg) { sound_file *sf; sf = get_sf(arg); return((sf) ? sf->write_date : (time_t)MUS_ERROR); } int mus_sound_type_specifier(const char *arg) { sound_file *sf; sf = get_sf(arg); return((sf) ? sf->type_specifier : MUS_ERROR); } int mus_sound_block_align(const char *arg) { sound_file *sf; sf = get_sf(arg); return((sf) ? sf->block_align : MUS_ERROR); } int mus_sound_bits_per_sample(const char *arg) { sound_file *sf; sf = get_sf(arg); return((sf) ? sf->bits_per_sample : MUS_ERROR); } float mus_sound_duration(const char *arg) { float val = -1.0; sound_file *sf; sf = get_sf(arg); if (sf) { if ((sf->chans > 0) && (sf->srate > 0)) val = (float)((double)(sf->samples) / ((float)(sf->chans) * (float)(sf->srate))); else val = 0.0; } return(val); } mus_float_t **mus_sound_saved_data(const char *arg) { /* slightly tricky -- we don't want to trigger a sound_file table entry here! */ sound_file *sf; if (arg == NULL) return(NULL); sf = find_sound_file(arg); /* not get_sf which will make an entry in the table */ return((sf) ? sf->saved_data : NULL); } void mus_sound_set_saved_data(const char *arg, mus_float_t **data) { sound_file *sf; sf = get_sf(arg); if (sf) sf->saved_data = data; } int *mus_sound_loop_info(const char *arg) { sound_file *sf; sf = get_sf(arg); if ((sf) && (sf->loop_modes)) { int *info; info = (int *)calloc(MUS_LOOP_INFO_SIZE, sizeof(int)); if (sf->loop_modes[0] != 0) { info[0] = sf->loop_starts[0]; info[1] = sf->loop_ends[0]; info[6] = sf->loop_modes[0]; } if (sf->loop_modes[1] != 0) { info[2] = sf->loop_starts[1]; info[3] = sf->loop_ends[1]; info[7] = sf->loop_modes[1]; } info[4] = sf->base_note; info[5] = sf->base_detune; return(info); } return(NULL); } void mus_sound_set_loop_info(const char *arg, int *loop) { sound_file *sf; sf = get_sf(arg); if (sf) { if (sf->loop_modes == NULL) { sf->loop_modes = (int *)calloc(2, sizeof(int)); sf->loop_starts = (int *)calloc(2, sizeof(int)); sf->loop_ends = (int *)calloc(2, sizeof(int)); } sf->loop_modes[0] = loop[6]; if (loop[6] != 0) { sf->loop_starts[0] = loop[0]; sf->loop_ends[0] = loop[1]; } else { sf->loop_starts[0] = 0; sf->loop_ends[0] = 0; } sf->loop_modes[1] = loop[7]; if (loop[7] != 0) { sf->loop_starts[1] = loop[2]; sf->loop_ends[1] = loop[3]; } else { sf->loop_starts[1] = 0; sf->loop_ends[1] = 0; } sf->base_note = loop[4]; sf->base_detune = loop[5]; } } int mus_sound_mark_info(const char *arg, int **mark_ids, int **mark_positions) { sound_file *sf; int result = 0; sf = get_sf(arg); if (sf) { (*mark_ids) = sf->marker_ids; (*mark_positions) = sf->marker_positions; result = sf->markers; } return(result); } char *mus_sound_comment(const char *name) { char *sc = NULL; sound_file *sf = NULL; sf = get_sf(name); if (sf) { mus_long_t start, end; start = sf->comment_start; end = sf->comment_end; if (end == 0) { if (sf->aux_comment_start) { if ((sf->header_type == MUS_RIFF) || (sf->header_type == MUS_RF64)) sc = mus_header_riff_aux_comment(name, sf->aux_comment_start, sf->aux_comment_end); if ((sf->header_type == MUS_AIFF) || (sf->header_type == MUS_AIFC)) sc = mus_header_aiff_aux_comment(name, sf->aux_comment_start, sf->aux_comment_end); } } else { if (end <= sf->true_file_length) { int len; len = end - start + 1; if (len > 0) { /* open and get the comment */ ssize_t bytes; int fd; fd = mus_file_open_read(name); if (fd == -1) return(NULL); lseek(fd, start, SEEK_SET); sc = (char *)calloc(len + 1, sizeof(char)); bytes = read(fd, sc, len); CLOSE(fd, name); if (((sf->header_type == MUS_AIFF) || (sf->header_type == MUS_AIFC)) && (sf->aux_comment_start) && (bytes != 0)) { char *auxcom; auxcom = mus_header_aiff_aux_comment(name, sf->aux_comment_start, sf->aux_comment_end); if (auxcom) { size_t full_len; full_len = strlen(auxcom) + strlen(sc) + 2; sc = (char *)realloc(sc, full_len * sizeof(char)); strcat(sc, "\n"); strcat(sc, auxcom); } } } } } } return(sc); } int mus_sound_open_input(const char *arg) { int fd = -1; if (!(mus_file_probe(arg))) mus_error(MUS_CANT_OPEN_FILE, "mus_sound_open_input: can't open %s: %s", arg, STRERROR(errno)); else { sound_file *sf = NULL; mus_sound_initialize(); sf = get_sf(arg); if (sf) { fd = mus_file_open_read(arg); if (fd == -1) mus_error(MUS_CANT_OPEN_FILE, "mus_sound_open_input: can't open %s: %s", arg, STRERROR(errno)); else { mus_file_open_descriptors(fd, arg, sf->sample_type, sf->datum_size, sf->data_location, sf->chans, sf->header_type); lseek(fd, sf->data_location, SEEK_SET); if (sf->saved_data) mus_file_save_data(fd, sf->samples / sf->chans, sf->saved_data); } } } return(fd); } int mus_sound_open_output(const char *arg, int srate, int chans, mus_sample_t sample_type, mus_header_t header_type, const char *comment) { int fd = MUS_ERROR, err; mus_sound_initialize(); mus_sound_forget(arg); err = mus_write_header(arg, header_type, srate, chans, 0, sample_type, comment); if (err != MUS_ERROR) { fd = mus_file_open_write(arg); if (fd != -1) mus_file_open_descriptors(fd, arg, sample_type, mus_bytes_per_sample(sample_type), mus_header_data_location(), chans, header_type); } return(fd); } int mus_sound_reopen_output(const char *arg, int chans, mus_sample_t samp_type, mus_header_t type, mus_long_t data_loc) { int fd; mus_sound_initialize(); fd = mus_file_reopen_write(arg); if (fd != -1) mus_file_open_descriptors(fd, arg, samp_type, mus_bytes_per_sample(samp_type), data_loc, chans, type); return(fd); } int mus_sound_close_input(int fd) { return(mus_file_close(fd)); /* this closes the clm file descriptors */ } int mus_sound_close_output(int fd, mus_long_t bytes_of_data) { char *name; name = mus_file_fd_name(fd); if (name) { int err; mus_header_t old_type; char *fname; fname = mus_strdup(name); old_type = mus_file_header_type(fd); err = mus_file_close(fd); /* this frees the original fd->name, so we copied above */ /* fd is NULL now */ mus_sound_forget(fname); mus_header_change_data_size(fname, old_type, bytes_of_data); free(fname); return(err); } return(MUS_ERROR); } typedef enum {SF_CHANS, SF_SRATE, SF_TYPE, SF_SAMP_TYPE, SF_LOCATION, SF_SIZE} sf_field_t; static int mus_sound_set_field(const char *arg, sf_field_t field, int val) { sound_file *sf; int result = MUS_NO_ERROR; sf = get_sf(arg); if (sf) { switch (field) { case SF_CHANS: sf->chans = val; break; case SF_SRATE: sf->srate = val; break; case SF_TYPE: sf->header_type = (mus_header_t)val; break; case SF_SAMP_TYPE: sf->sample_type = (mus_sample_t)val; sf->datum_size = mus_bytes_per_sample(sf->sample_type); break; default: result = MUS_ERROR; break; } } else result = MUS_ERROR; return(result); } static int mus_sound_set_mus_long_t_field(const char *arg, sf_field_t field, mus_long_t val) { sound_file *sf; int result = MUS_NO_ERROR; sf = get_sf(arg); if (sf) { switch (field) { case SF_SIZE: sf->samples = val; break; case SF_LOCATION: sf->data_location = val; break; default: result = MUS_ERROR; break; } } else result = MUS_ERROR; return(result); } int mus_sound_set_chans(const char *arg, int val) {return(mus_sound_set_field(arg, SF_CHANS, val));} int mus_sound_set_srate(const char *arg, int val) {return(mus_sound_set_field(arg, SF_SRATE, val));} mus_header_t mus_sound_set_header_type(const char *arg, mus_header_t val) {return((mus_header_t)mus_sound_set_field(arg, SF_TYPE, val));} mus_sample_t mus_sound_set_sample_type(const char *arg, mus_sample_t val) {return((mus_sample_t)mus_sound_set_field(arg, SF_SAMP_TYPE, val));} int mus_sound_set_data_location(const char *arg, mus_long_t val) {return(mus_sound_set_mus_long_t_field(arg, SF_LOCATION, val));} int mus_sound_set_samples(const char *arg, mus_long_t val) {return(mus_sound_set_mus_long_t_field(arg, SF_SIZE, val));} int mus_sound_override_header(const char *arg, int srate, int chans, mus_sample_t samp_type, mus_header_t type, mus_long_t location, mus_long_t size) { sound_file *sf; int result = MUS_NO_ERROR; /* perhaps once a header has been over-ridden, we should not reset the relevant fields upon re-read? */ sf = get_sf(arg); if (sf) { if (location != -1) sf->data_location = location; if (size != -1) sf->samples = size; if (samp_type != MUS_UNKNOWN_SAMPLE) { sf->sample_type = samp_type; sf->datum_size = mus_bytes_per_sample(samp_type); } if (srate != -1) sf->srate = srate; if (chans != -1) sf->chans = chans; if (type != MUS_UNKNOWN_HEADER) sf->header_type = (mus_header_t)type; } else result = MUS_ERROR; return(result); } bool mus_sound_maxamp_exists(const char *ifile) { sound_file *sf; sf = get_sf(ifile); if ((sf) && (sf->maxtimes)) { int i; for (i = 0; i < sf->maxamps_size; i++) if (sf->maxtimes[i] == -1) return(false); return(true); } return(false); } mus_long_t mus_sound_maxamps(const char *ifile, int chans, mus_float_t *vals, mus_long_t *times) { mus_long_t framples; int ichans, chn; sound_file *sf; sf = get_sf(ifile); if (sf->chans <= 0) return(MUS_ERROR); if ((sf) && (sf->maxamps)) { if (chans > sf->maxamps_size) ichans = sf->maxamps_size; else ichans = chans; for (chn = 0; chn < ichans; chn++) { times[chn] = sf->maxtimes[chn]; vals[chn] = sf->maxamps[chn]; } framples = sf->samples / sf->chans; return(framples); } { int j, bufnum, ifd; mus_long_t n, curframples; mus_float_t *buffer, *samp; mus_long_t *time; mus_float_t **ibufs; ifd = mus_sound_open_input(ifile); if (ifd == MUS_ERROR) return(MUS_ERROR); ichans = mus_sound_chans(ifile); framples = mus_sound_framples(ifile); if (framples == 0) { mus_sound_close_input(ifd); return(0); } mus_file_seek_frample(ifd, 0); ibufs = (mus_float_t **)calloc(ichans, sizeof(mus_float_t *)); bufnum = 8192; for (j = 0; j < ichans; j++) ibufs[j] = (mus_float_t *)calloc(bufnum, sizeof(mus_float_t)); time = (mus_long_t *)calloc(ichans, sizeof(mus_long_t)); samp = (mus_float_t *)calloc(ichans, sizeof(mus_float_t)); for (n = 0; n < framples; n += bufnum) { if ((n + bufnum) < framples) curframples = bufnum; else curframples = (framples - n); mus_file_read(ifd, n, curframples, ichans, ibufs); for (chn = 0; chn < ichans; chn++) { int i; buffer = (mus_float_t *)(ibufs[chn]); for (i = 0; i < curframples; i++) { mus_float_t abs_samp; abs_samp = fabs(buffer[i]); if (abs_samp > samp[chn]) { time[chn] = i + n; samp[chn] = abs_samp; } } } } mus_sound_close_input(ifd); /* fprintf(stderr, "set in mus_sound_maxamps\n"); */ mus_sound_set_maxamps(ifile, ichans, samp, time); /* save the complete set */ if (ichans > chans) ichans = chans; for (chn = 0; chn < ichans; chn++) { times[chn] = time[chn]; vals[chn] = samp[chn]; } free(time); free(samp); for (j = 0; j < ichans; j++) free(ibufs[j]); free(ibufs); return(framples); } } int mus_sound_set_maxamps(const char *ifile, int chans, mus_float_t *vals, mus_long_t *times) { sound_file *sf; int result = MUS_NO_ERROR; /* fprintf(stderr, "set %s maxamps: %d %.3f %lld\n", ifile, chans, vals[0], times[0]); */ sf = get_sf(ifile); if (sf) { int i, ichans = 0; if (sf->maxamps) { if (chans > sf->maxamps_size) ichans = sf->maxamps_size; else ichans = chans; for (i = 0; i < ichans; i++) { sf->maxtimes[i] = times[i]; sf->maxamps[i] = vals[i]; } } else { ichans = sf->chans; if (sf->maxamps == NULL) { /* here we need to use the max, since the caller may be confused */ int max_chans; max_chans = ichans; if (max_chans < chans) max_chans = chans; sf->maxamps = (mus_float_t *)calloc(max_chans, sizeof(mus_float_t)); sf->maxtimes = (mus_long_t *)calloc(max_chans, sizeof(mus_long_t)); sf->maxamps_size = max_chans; } if (ichans > sf->maxamps_size) ichans = sf->maxamps_size; if (ichans > chans) ichans = chans; for (i = 0; i < ichans; i++) { sf->maxtimes[i] = times[i]; sf->maxamps[i] = vals[i]; } } } else result = MUS_ERROR; return(result); } bool mus_sound_channel_maxamp_exists(const char *file, int chan) { sound_file *sf; sf = get_sf(file); return((sf) && (sf->maxtimes) && (sf->maxamps_size > chan) && (sf->maxtimes[chan] != -1)); } mus_float_t mus_sound_channel_maxamp(const char *file, int chan, mus_long_t *pos) { sound_file *sf; sf = get_sf(file); if ((chan < sf->maxamps_size) && (sf->maxtimes)) { (*pos) = sf->maxtimes[chan]; return(sf->maxamps[chan]); } return(-1.0); } void mus_sound_channel_set_maxamp(const char *file, int chan, mus_float_t mx, mus_long_t pos) { sound_file *sf; /* fprintf(stderr, "set %s maxamp: %.3f %lld\n", file, mx, pos); */ sf = get_sf(file); if ((sf) && (sf->chans > chan)) { if (!(sf->maxamps)) { int i; sf->maxamps = (mus_float_t *)malloc(sf->chans * sizeof(mus_float_t)); sf->maxtimes = (mus_long_t *)malloc(sf->chans * sizeof(mus_long_t)); sf->maxamps_size = sf->chans; for (i = 0; i < sf->chans; i++) { sf->maxamps[i] = -1.0; sf->maxtimes[i] = -1; } } sf->maxamps[chan] = mx; sf->maxtimes[chan] = pos; } } mus_long_t mus_file_to_array(const char *filename, int chan, mus_long_t start, mus_long_t samples, mus_float_t *array) { int ifd, chans; mus_long_t total_read; mus_float_t **bufs; ifd = mus_sound_open_input(filename); if (ifd == MUS_ERROR) return(MUS_ERROR); chans = mus_sound_chans(filename); if ((chan >= chans) || (chan < 0)) { mus_sound_close_input(ifd); return(mus_error(MUS_NO_SUCH_CHANNEL, "mus_file_to_array can't read %s channel %d (file has %d chans)", filename, chan, chans)); } bufs = (mus_float_t **)calloc(chans, sizeof(mus_float_t *)); bufs[chan] = array; mus_file_seek_frample(ifd, start); total_read = mus_file_read_any(ifd, start, chans, samples, bufs, bufs); mus_sound_close_input(ifd); free(bufs); return(total_read); } const char *mus_array_to_file_with_error(const char *filename, mus_float_t *ddata, mus_long_t len, int srate, int channels) { /* put ddata into a sound file, taking byte order into account */ /* assume ddata is interleaved already if more than one channel */ int fd, err = MUS_NO_ERROR; mus_long_t oloc; mus_sound_forget(filename); err = mus_write_header(filename, MUS_NEXT, srate, channels, len * channels, MUS_OUT_SAMPLE_TYPE, "array->file"); if (err != MUS_NO_ERROR) return("mus_array_to_file can't create output file"); oloc = mus_header_data_location(); fd = mus_file_reopen_write(filename); lseek(fd, oloc, SEEK_SET); err = mus_file_open_descriptors(fd, filename, MUS_OUT_SAMPLE_TYPE, mus_bytes_per_sample(MUS_OUT_SAMPLE_TYPE), oloc, channels, MUS_NEXT); if (err != MUS_ERROR) { mus_float_t *bufs[1]; bufs[0] = ddata; err = mus_file_write(fd, 0, len - 1, 1, bufs); /* 1 = chans?? */ } mus_file_close(fd); if (err == MUS_ERROR) return("mus_array_to_file write error"); return(NULL); } int mus_array_to_file(const char *filename, mus_float_t *ddata, mus_long_t len, int srate, int channels) { const char *errmsg; errmsg = mus_array_to_file_with_error(filename, ddata, len, srate, channels); if (errmsg) return(mus_error(MUS_CANT_OPEN_FILE, "%s", errmsg)); return(MUS_NO_ERROR); } mus_long_t mus_file_to_float_array(const char *filename, int chan, mus_long_t start, mus_long_t samples, mus_float_t *array) { return(mus_file_to_array(filename, chan, start, samples, array)); } int mus_float_array_to_file(const char *filename, mus_float_t *ddata, mus_long_t len, int srate, int channels) { const char *errmsg; errmsg = mus_array_to_file_with_error(filename, ddata, len, srate, channels); if (errmsg) return(mus_error(MUS_CANT_OPEN_FILE, "%s", errmsg)); return(MUS_NO_ERROR); } int mus_sound_initialize(void) { static bool sndlib_initialized = false; if (!sndlib_initialized) { int err = MUS_NO_ERROR; sndlib_initialized = true; mus_error_handler = default_mus_error; err = mus_header_initialize(); if (err == MUS_NO_ERROR) err = mus_audio_initialize(); sound_tables = (sound_file ***)calloc(NUM_SOUND_TABLES, sizeof(sound_file **)); sound_table_sizes = (int *)calloc(NUM_SOUND_TABLES, sizeof(int)); return(err); } return(MUS_NO_ERROR); } snd-16.1/snd-nogui0.h0000644000076400007640000000576012471670273012510 0ustar bilbil#ifndef SND_NOGUI0_H #define SND_NOGUI0_H #define BACKGROUND_QUIT true #define BACKGROUND_CONTINUE false #define BACKGROUND_REMOVE(func) #define BACKGROUND_ADD(func, data) func(data) #define TIMEOUT_ARGS void *context #define TIMEOUT_TYPE void #define TIMEOUT_RESULT #define timeout_result_t int #define TIMEOUT_REMOVE(Id) #define CALL_TIMEOUT(Func, Wait, Data) 0 #define widget_t int #define widget_is_active(Wid) 0 #define activate_widget(Wid) Wid = 0 #define deactivate_widget(Wid) Wid = 0 #define Xen_wrap_widget(Value) Xen_false #define Xen_wrap_window(Value) Xen_false #define Xen_unwrap_widget(Value) 0 #define Xen_is_widget(Value) 0 #define NULL_WIDGET 0 #define LOTSA_PIXELS 10000 #define DEFAULT_TINY_FONT "Monospace 8" #define DEFAULT_PEAKS_FONT "Serif 10" #define DEFAULT_BOLD_PEAKS_FONT "Serif Bold 10" #define DEFAULT_AXIS_NUMBERS_FONT "Monospace 10" #define DEFAULT_AXIS_LABEL_FONT "Serif 14" #define TINY_FONT(a) 0 #define AXIS_NUMBERS_FONT(a) 0 #define PEAKS_FONT(a) 0 #define DEFAULT_GRAPH_CURSOR 0 #define idle_t int #define idle_func_t int #define any_pointer_t void * #define oclock_t int #define color_t int #define point_t int #define rgb_t unsigned short #define RGB_MAX 65535 #define float_to_rgb(Val) (rgb_t)(RGB_MAX * (Val)) #define rgb_to_float(Val) (float)((float)(Val) / (float)RGB_MAX) typedef struct { int wn; int gc; } graphics_context; typedef struct { mus_header_t current_header_type; mus_sample_t current_sample_type; int sample_types, header_type_pos, sample_type_pos, scanf_widget, error_widget; } file_data; typedef enum {NOT_A_SCANF_WIDGET} scanf_widget_t; #define snd_ShiftMask 0 #define snd_ControlMask 0 #define snd_MetaMask 0 #define MAIN_SHELL(a) 0 #define MAIN_PANE(a) 0 #define SOUND_PANE(a) 0 #define KEY_TO_NAME(key) "?" /* not NULL here because that causes a segfault in solaris (key name null -> strlen of null in vsprintf) */ enum {snd_K_Shift_L, snd_K_space, snd_K_openparen, snd_K_closeparen, snd_K_plus, snd_K_minus, snd_K_period, snd_K_slash, snd_K_0, snd_K_1, snd_K_2, snd_K_3, snd_K_4, snd_K_5, snd_K_6, snd_K_7, snd_K_8, snd_K_9, snd_K_less, snd_K_greater, snd_K_A, snd_K_B, snd_K_C, snd_K_D, snd_K_E, snd_K_F, snd_K_G, snd_K_H, snd_K_I, snd_K_J, snd_K_K, snd_K_L, snd_K_M, snd_K_N, snd_K_O, snd_K_P, snd_K_Q, snd_K_R, snd_K_S, snd_K_T, snd_K_U, snd_K_V, snd_K_W, snd_K_X, snd_K_Y, snd_K_Z, snd_K_underscore, snd_K_a, snd_K_b, snd_K_c, snd_K_d, snd_K_e, snd_K_f, snd_K_g, snd_K_h, snd_K_i, snd_K_j, snd_K_k, snd_K_l, snd_K_m, snd_K_n, snd_K_o, snd_K_p, snd_K_q, snd_K_r, snd_K_s, snd_K_t, snd_K_u, snd_K_v, snd_K_w, snd_K_x, snd_K_y, snd_K_z, snd_K_Home, snd_K_Left, snd_K_Up, snd_K_Right, snd_K_Down, snd_keypad_Insert, snd_keypad_Delete, snd_keypad_Multiply, snd_keypad_Add, snd_keypad_Subtract, snd_keypad_Divide, snd_keypad_Decimal, snd_keypad_Enter, snd_keypad_0, snd_keypad_1, snd_keypad_2, snd_keypad_3, snd_keypad_4, snd_keypad_5, snd_keypad_6, snd_keypad_7, snd_keypad_8, snd_keypad_9, snd_keypad_Down, snd_keypad_Up, snd_keypad_Left, snd_keypad_Right}; #endif snd-16.1/configure.ac0000644000076400007640000005103312626144464012634 0ustar bilbil# Configuration script for Snd # # we now depend completely on pc (pkgconfig) files. # Motif apparently has none. # gmp, mpfr, and mpc deliberately have none! AC_INIT(snd, 16.1, bil@ccrma.stanford.edu, ftp://ccrma-ftp.stanford.edu/pub/Lisp/snd-16.tar.gz) AC_CONFIG_SRCDIR(snd.c) AC_CANONICAL_HOST # needed by case $host below AC_CONFIG_HEADERS(mus-config.h) AC_CONFIG_FILES(makefile) AC_PROG_CC # AC_HEADER_STDC AC_PROG_INSTALL MAKE_TARGET="snd" AUDIO_SYSTEM="None" RANDOM_FEATURES="" OPTIONAL_LIBRARIES="" LOCAL_LANGUAGE="None" GRAPHICS_TOOLKIT="None" PACKAGE=Snd VERSION=16.1 #-------------------------------------------------------------------------------- # configuration options # --with-motif use Motif # --with-gtk use Gtk+ (the default) # --with-alsa use ALSA if possible (the default) # --with-oss use OSS # --with-jack use Jack # --without-audio stub out all audio # --with-gmp include multiprecision arithmetic via gmp, mpfr, and mpc # --disable-deprecated do not include any deprecated stuff (in gtk, motif, s7, sndlib, clm, etc) # --with-ladspa include LADSPA plugin support (Linux) # --with-gui make Snd with(out) any graphics support # --with-forth use Forth as the extension language # --with-ruby use Ruby as the extension language # --with-s7 use S7 as the extension language (default = yes) # --with-extension-language use some extension language (default=yes) # --with-temp-dir directory to use for temp files # --with-save-dir directory to use for saved-state files # --with-doc-dir directory to search for documentation # --with-gl include OpenGL support (default=no, Motif only) # --with-gl2ps include gl2ps (Motif only) # --with-editres include EditRes in xm # --without-gsl omit GSL even if it exists # --without-fftw omit FFTW even if it exists # --with-pulseaudio use PulseAudio # --with-portaudio use portaudio AC_ARG_WITH(gtk, [ --with-gtk use Gtk+ to build Snd]) AC_ARG_WITH(gui, [ --with-gui make Snd with graphics support]) AC_ARG_WITH(gl, [ --with-gl include OpenGL support, Motif only]) AC_ARG_WITH(gl2ps, [ --with-gl2ps include gl2ps, Motif only]) AC_ARG_WITH(motif, [ --with-motif use libXm to build Snd]) AC_ARG_WITH(editres, [ --with-editres include editres in xm]) AC_ARG_WITH(alsa, [ --with-alsa use ALSA]) AC_ARG_WITH(oss, [ --with-oss use OSS]) AC_ARG_WITH(jack, [ --with-jack use JACK]) AC_ARG_WITH(ladspa, [ --with-ladspa include support for LADSPA plugins, Linux only]) AC_ARG_WITH(pulseaudio, [ --with-pulseaudio use PulseAudio, default=no]) AC_ARG_WITH(portaudio, [ --with-portaudio use portaudio, default=no]) AC_ARG_WITH(extension-language, [ --with-extension-language use some extension language, default=yes]) AC_ARG_WITH(s7, [ --with-s7 use S7, default=yes]) AC_ARG_WITH(forth, [ --with-forth use Forth as the extension language]) AC_ARG_WITH(ruby, [ --with-ruby use Ruby as the extension language]) AC_ARG_WITH(gsl, [ --with-gsl use GSL, default=yes]) AC_ARG_WITH(fftw, [ --with-fftw use fftw, default=yes]) AC_ARG_WITH(gmp, [ --with-gmp include multiprecision arithmetic via gmp, mpfr, and mpc, default=no]) AC_ARG_WITH(audio, [ --without-audio don't include any audio functionality]) AC_ARG_WITH(temp-dir, [ --with-temp-dir directory to use for temp files], AC_DEFINE_UNQUOTED(MUS_DEFAULT_TEMP_DIR, "${withval}")) AC_ARG_WITH(save-dir, [ --with-save-dir directory to use for saved-state files], AC_DEFINE_UNQUOTED(MUS_DEFAULT_SAVE_DIR, "${withval}")) AC_ARG_WITH(doc-dir, [ --with-doc-dir directory to search for documentation], AC_DEFINE_UNQUOTED(MUS_DEFAULT_DOC_DIR, "${withval}")) AC_ARG_ENABLE(deprecated,[ --disable-deprecated do not include any deprecated stuff from gtk, s7, motif, clm, snd, or sndlib]) AC_C_BIGENDIAN AC_CHECK_SIZEOF(void *) AC_PATH_PROG(PKG_CONFIG, pkg-config, no) #-------------------------------------------------------------------------------- # fftw #-------------------------------------------------------------------------------- FFTW_LIBS="" FFTW_CFLAGS="" if test "$with_fftw" != no; then AC_MSG_CHECKING(for fftw3) if test x$PKG_CONFIG != xno ; then if $PKG_CONFIG fftw3 --exists ; then FFTW_LIBS="`$PKG_CONFIG fftw3 --libs`" FFTW_CFLAGS="`$PKG_CONFIG fftw3 --cflags`" AC_DEFINE(HAVE_FFTW3) OPTIONAL_LIBRARIES="$OPTIONAL_LIBRARIES fftw3" AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi fi fi AC_SUBST(FFTW_LIBS) AC_SUBST(FFTW_CFLAGS) #-------------------------------------------------------------------------------- # GMP, MPFR, MPC #-------------------------------------------------------------------------------- # no pc files -- deliberately! We'll just add the libraries and let the chips fall... GMP_LIBS="" if test "$with_gmp" = yes ; then GMP_LIBS="-lgmp -lmpfr -lmpc -lm" AC_DEFINE(WITH_GMP) OPTIONAL_LIBRARIES="$OPTIONAL_LIBRARIES gmp mpfr mpc" fi AC_SUBST(GMP_LIBS) #-------------------------------------------------------------------------------- # GSL #-------------------------------------------------------------------------------- GSL_LIBS="" GSL_CFLAGS="" if test "$with_gsl" != no; then AC_MSG_CHECKING(for gsl) if test x$PKG_CONFIG != xno ; then if $PKG_CONFIG gsl --exists ; then GSL_LIBS="`$PKG_CONFIG gsl --libs`" GSL_CFLAGS="`$PKG_CONFIG gsl --cflags`" AC_DEFINE(HAVE_GSL) OPTIONAL_LIBRARIES="$OPTIONAL_LIBRARIES gsl" AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi fi fi AC_SUBST(GSL_LIBS) AC_SUBST(GSL_CFLAGS) #-------------------------------------------------------------------------------- # Ladspa #-------------------------------------------------------------------------------- if test "$with_ladspa" = yes ; then AC_DEFINE(HAVE_LADSPA) RANDOM_FEATURES="$RANDOM_FEATURES ladspa" fi #-------------------------------------------------------------------------------- # graphics #-------------------------------------------------------------------------------- # graphics: motif chosen if --with-motif # no gui chosen if --without-gui # gtk chosen if neither of above and we can find gtk-2.0.pc or gtk-3.0.pc # else no gui XLIBS="" XFLAGS="" GX_FILES="" GX_HEADERS="" GTK_FILES="" GTK_HEADERS="" GTK_CFLAGS="" GTK_LIBS="" GTK_LD_LIBS="" ac_snd_gui_choice=none if test "$with_motif" = no && test "$with_gtk" = no ; then with_gui=no fi if test "$with_gui" = no ; then AC_DEFINE(USE_NO_GUI) GX_FILES="NO_GUI_O_FILES" GX_HEADERS="NO_GUI_HEADERS" ac_snd_gui_choice=no fi #-------------------------------------------------------------------------------- # X/Motif #-------------------------------------------------------------------------------- # here as in the gmp case, we simply set up the libs/flags and hope for the best if test "$with_motif" = yes ; then AC_PATH_XTRA GTK_FLAGS="$X_CFLAGS" X_POST_LIBS="-lX11 $X_EXTRA_LIBS -lXext" case "$host" in *-apple-*) X_POST_LIBS="$X_POST_LIBS -lSM -lICE" ;; *-*-linux*) X_POST_LIBS="$X_POST_LIBS -lSM -lICE -lXft" ;; esac X_PRE_LIBS="$X_LIBS $X_PRE_LIBS -lXm -lXt" GX_FILES="MOTIF_O_FILES" GX_HEADERS="SND_X_HEADERS" if test "$with_editres" = yes ; then AC_DEFINE(WITH_EDITRES) OPTIONAL_LIBRARIES="$OPTIONAL_LIBRARIES editres" X_PRE_LIBS="$X_PRE_LIBS -lXmu" fi GTK_LIBS="$X_PRE_LIBS $X_POST_LIBS -lXpm" AC_DEFINE(USE_MOTIF) GRAPHICS_TOOLKIT="Motif" ac_snd_gui_choice=Motif fi #-------------------------------------------------------------------------------- # Gtk #-------------------------------------------------------------------------------- if test "$ac_snd_gui_choice" = none ; then if test x$PKG_CONFIG != xno ; then if $PKG_CONFIG gtk+-3.0 --exists ; then GTK_CFLAGS="`$PKG_CONFIG gtk+-3.0 --cflags`" GTK_LIBS="`$PKG_CONFIG gtk+-3.0 --libs`" GTK_LD_LIBS="`$PKG_CONFIG gtk+-3.0 --libs-only-L` `$PKG_CONFIG gtk+-3.0 --libs-only-l`" ac_snd_gui_choice=gtk else if $PKG_CONFIG gtk+-2.0 --exists ; then GTK_CFLAGS="`$PKG_CONFIG gtk+-2.0 --cflags`" GTK_LIBS="`$PKG_CONFIG gtk+-2.0 --libs`" GTK_LD_LIBS="`$PKG_CONFIG gtk+-2.0 --libs-only-L` `$PKG_CONFIG gtk+-2.0 --libs-only-l`" ac_snd_gui_choice=gtk fi fi fi if test "$ac_snd_gui_choice" = gtk ; then GX_FILES="GTK_O_FILES" GX_HEADERS="SND_G_HEADERS" AC_DEFINE(USE_GTK) GRAPHICS_TOOLKIT="Gtk" if test x$PKG_CONFIG != xno ; then CAIRO_CFLAGS="`$PKG_CONFIG cairo --cflags-only-I`" AC_SUBST(CAIRO_CFLAGS) fi fi fi if test "$ac_snd_gui_choice" = none ; then AC_DEFINE(USE_NO_GUI) GX_FILES="NO_GUI_O_FILES" GX_HEADERS="NO_GUI_HEADERS" fi # fallback on no-gui if test "$with_gui" = no ; then AC_DEFINE(USE_NO_GUI) GX_FILES="NO_GUI_O_FILES" GX_HEADERS="NO_GUI_HEADERS" ac_snd_gui_choice=no fi AC_SUBST(XLIBS) AC_SUBST(XFLAGS) AC_SUBST(GX_FILES) AC_SUBST(GX_HEADERS) AC_SUBST(GTK_LIBS) AC_SUBST(GTK_CFLAGS) AC_SUBST(GTK_LD_LIBS) #-------------------------------------------------------------------------------- # OpenGL #-------------------------------------------------------------------------------- GL_LIBS="" GL_FILES="" GL_FLAGS="" if test "$with_gl" = yes ; then if test x$PKG_CONFIG != xno ; then if $PKG_CONFIG gl --exists ; then GL_CFLAGS="`$PKG_CONFIG gl --cflags`" GL_LIBS="`$PKG_CONFIG gl --libs`" GL_FILES="gl.o" AC_DEFINE(HAVE_GL) OPTIONAL_LIBRARIES="$OPTIONAL_LIBRARIES openGL" if $PKG_CONFIG glu --exists ; then AC_DEFINE(HAVE_GLU) GL_CFLAGS="$GL_CFLAGS `$PKG_CONFIG glu --cflags`" GL_LIBS="$GL_LIBS `$PKG_CONFIG glu --libs`" fi if test "$with_gl2ps" = yes ; then AC_DEFINE(WITH_GL2PS) RANDOM_FEATURES="$RANDOM_FEATURES gl2ps" GL_FILES="$GL_FILES gl2ps.o" fi fi fi fi AC_SUBST(GL_LIBS) AC_SUBST(GL_FILES) AC_SUBST(GL_FLAGS) #-------------------------------------------------------------------------------- # language #-------------------------------------------------------------------------------- # language choice: ruby if --with-ruby and we can find a ruby pc file # forth if --with-forth # none if --without-extension-language # s7 otherwise XEN_LIBS="" XEN_CFLAGS="" ac_snd_extension_language=none if test "$with_extension_language" = no ; then ac_snd_extension_language=no LOCAL_LANGUAGE="None" fi #-------------------------------------------------------------------------------- # Ruby #-------------------------------------------------------------------------------- if test "$with_ruby" = yes ; then if test x$PKG_CONFIG != xno ; then m4_foreach([ruby_version], [[ruby-2.2], [ruby-2.1], [ruby-2.0], [ruby], [ruby-1.9.3], [ruby-1.9], [ruby-1.8]], [ if test "$ac_snd_extension_language" = none ; then if $PKG_CONFIG ruby_version --exists ; then AC_DEFINE(HAVE_RUBY) XEN_CFLAGS="`$PKG_CONFIG ruby_version --cflags`" # this depends on building ruby itself with the --enable-shared flag XEN_LIBS="`$PKG_CONFIG ruby_version --libs`" LOCAL_LANGUAGE="Ruby" ac_snd_extension_language=Ruby fi fi ]) fi fi #-------------------------------------------------------------------------------- # Forth #-------------------------------------------------------------------------------- if test "$with_forth" = yes ; then AC_PATH_PROG([FTH], [fth], [no]) AC_MSG_CHECKING([for Forth]) if test "${FTH}" != no ; then XEN_CFLAGS=`${FTH} --no-init-file --eval .cflags` XEN_LIBS=`${FTH} --no-init-file --eval .libs` AC_MSG_RESULT([yes]) AC_DEFINE(HAVE_FORTH) LOCAL_LANGUAGE="Forth" ac_snd_extension_language=Forth else AC_MSG_RESULT([no]) fi fi #-------------------------------------------------------------------------------- # s7 (the default) #-------------------------------------------------------------------------------- if test "$with_s7" != no && test "$ac_snd_extension_language" = none ; then AC_DEFINE(HAVE_SCHEME) ac_snd_extension_language=s7 LOCAL_LANGUAGE="s7" S7_LIB="s7.o" AC_SUBST(S7_LIB) fi AC_SUBST(XEN_LIBS) AC_SUBST(XEN_CFLAGS) #-------------------------------------------------------------------------------- # OGG, Flac, Speex, Mpeg, Timidity, TTA, Wavpack # -------------------------------------------------------------------------------- AC_PATH_PROG(PATH_OGGDEC, oggdec, no) # OGG read AC_PATH_PROG(PATH_OGGENC, oggenc, no) # OGG write if test "$PATH_OGGDEC" != "no" ; then if test "$PATH_OGGENC" != "no" ; then AC_DEFINE(HAVE_OGG) AC_DEFINE_UNQUOTED(PATH_OGGDEC, "${PATH_OGGDEC}") AC_DEFINE_UNQUOTED(PATH_OGGENC, "${PATH_OGGENC}") fi fi AC_PATH_PROG(PATH_MPG123, mpg123, no) # MPEG read/write? if test "$PATH_MPG123" != "no" ; then AC_DEFINE(HAVE_MPEG) AC_DEFINE_UNQUOTED(PATH_MPG123, "${PATH_MPG123}") fi AC_PATH_PROG(PATH_MPG321, mpg321, no) # MPEG read/write? if test "$PATH_MPG321" != "no" ; then AC_DEFINE(HAVE_MPEG) AC_DEFINE(HAVE_MPG321) AC_DEFINE_UNQUOTED(PATH_MPG321, "${PATH_MPG321}") fi AC_PATH_PROG(PATH_SPEEXDEC, speexdec, no) # Speex read AC_PATH_PROG(PATH_SPEEXENC, speexenc, no) # Speex write if test "$PATH_SPEEXDEC" != "no" ; then if test "$PATH_SPEEXENC" != "no" ; then AC_DEFINE(HAVE_SPEEX) AC_DEFINE_UNQUOTED(PATH_SPEEXDEC, "${PATH_SPEEXDEC}") AC_DEFINE_UNQUOTED(PATH_SPEEXENC, "${PATH_SPEEXENC}") fi fi AC_PATH_PROG(PATH_FLAC, flac, no) # Flac read/write if test "$PATH_FLAC" != "no" ; then AC_DEFINE(HAVE_FLAC) AC_DEFINE_UNQUOTED(PATH_FLAC, "${PATH_FLAC}") fi AC_PATH_PROG(PATH_TIMIDITY, timidity, no) # Timidity for .mid -> .wav if test "$PATH_TIMIDITY" != "no" ; then AC_DEFINE(HAVE_TIMIDITY) AC_DEFINE_UNQUOTED(PATH_TIMIDITY, "${PATH_TIMIDITY}") fi AC_PATH_PROG(PATH_TTA, ttaenc, no) if test "$PATH_TTA" != "no" ; then AC_DEFINE(HAVE_TTA) AC_DEFINE_UNQUOTED(PATH_TTA, "${PATH_TTA}") fi AC_PATH_PROG(PATH_WAVPACK, wavpack, no) AC_PATH_PROG(PATH_WVUNPACK, wvunpack, no) if test "$PATH_WAVPACK" != "no" ; then if test "$PATH_WVUNPACK" != "no" ; then AC_DEFINE(HAVE_WAVPACK) AC_DEFINE_UNQUOTED(PATH_WAVPACK, "${PATH_WAVPACK}") AC_DEFINE_UNQUOTED(PATH_WVUNPACK, "${PATH_WVUNPACK}") fi fi #-------------------------------------------------------------------------------- # Audio #-------------------------------------------------------------------------------- AUDIO_LIB="" JACK_LIBS="" JACK_FLAGS="" if test "$with_audio" != no ; then if test "$with_pulseaudio" = yes ; then AC_DEFINE(MUS_PULSEAUDIO) AUDIO_LIB="-lpulse-simple" AUDIO_SYSTEM=pulseaudio fi if test "$with_portaudio" = yes ; then AC_DEFINE(MUS_PORTAUDIO) AUDIO_SYSTEM=portaudio AUDIO_LIB="-lportaudio" fi if test "$with_jack" = yes ; then if test "$with_alsa" = yes ; then AUDIO_SYSTEM=ALSA+JACK else AUDIO_SYSTEM=JACK fi AC_DEFINE(MUS_JACK) if test x$PKG_CONFIG != xno ; then if $PKG_CONFIG jack --exists ; then JACK_LIBS="`$PKG_CONFIG jack --libs`" JACK_FLAGS="`$PKG_CONFIG jack --cflags`" if $PKG_CONFIG samplerate --exists ; then JACK_LIBS="$JACK_LIBS `$PKG_CONFIG samplerate --libs`" JACK_FLAGS="$JACK_FLAGS `$PKG_CONFIG samplerate --cflags`" else JACK_LIBS="$JACK_LIBS -lsamplerate" fi else JACK_LIBS="-ljack -lsamplerate" fi else JACK_LIBS="-ljack -lsamplerate" fi JACK_LIBS="$JACK_LIBS -lpthread" fi if test "$with_alsa" = yes ; then AC_DEFINE(HAVE_ALSA) AUDIO_LIB="-lasound" if test "$with_jack" = yes ; then AUDIO_SYSTEM=ALSA+JACK else AUDIO_SYSTEM=ALSA fi fi if test "$with_oss" = yes ; then AC_DEFINE(HAVE_OSS) AUDIO_SYSTEM=OSS fi if test "$AUDIO_SYSTEM" = None ; then case "$host" in *-*-linux*) AUDIO_SYSTEM=ALSA AC_DEFINE(HAVE_ALSA) AUDIO_LIB="-lasound" ;; *-*-sunos4*) AUDIO_SYSTEM=Sun ;; *-*-solaris*) AUDIO_SYSTEM=Sun ;; *-*-hpux*) AUDIO_SYSTEM=Hpux ;; *-*-bsdi*) AC_DEFINE(HAVE_OSS) AUDIO_SYSTEM=OSS ;; *-*-freebsd*) AC_DEFINE(HAVE_OSS) AUDIO_SYSTEM=OSS ;; *-*-openbsd*) AUDIO_SYSTEM=OpenBSD ;; *-*-netbsd*) AUDIO_SYSTEM=NetBSD ;; *-*-cygwin*) if test "$with_jack" != yes ; then AUDIO_SYSTEM=Windows fi ;; *-*-mingw*) audio_system=Windows ;; *-apple-*) if test "$with_jack" != yes ; then AUDIO_SYSTEM=MacOSX AUDIO_LIB="-framework CoreAudio -framework CoreFoundation -framework CoreMIDI" else AUDIO_SYSTEM=JACK JACK_LIBS="-framework CoreAudio -framework CoreServices -framework AudioUnit -L/usr/local/lib -ljack -lsamplerate" JACK_FLAGS="-I/usr/local/include" fi ;; esac fi fi AC_MSG_CHECKING([for audio system]) AC_MSG_RESULT($AUDIO_SYSTEM) if test "$AUDIO_SYSTEM" != None ; then AC_DEFINE(WITH_AUDIO) fi AC_SUBST(AUDIO_LIB) AC_SUBST(JACK_LIBS) AC_SUBST(JACK_FLAGS) #-------------------------------------------------------------------------------- # compiler/loader flags #-------------------------------------------------------------------------------- LIBS="" LDSO_FLAGS="" SO_FLAGS="" SO_LD="ld" # the SO_* stuff here is for consistency with the sndlib configure script case "$host" in *-*-linux*) LDSO_FLAGS="-shared" LIBS="$LIBS -lm -ldl" if test "$GCC" = yes ; then SO_FLAGS="-fPIC $SO_FLAGS" SO_LD="$CC" fi ;; *-*-sunos4*) LIBS="$LIBS -lm" ;; *-*-solaris*) LIBS="$LIBS -lm" LDSO_FLAGS="-G" ;; *-*-hpux*) LDSO_FLAGS="+z -Ae +DA1.1" if test "$GCC" = yes ; then SO_FLAGS="-fPIC $SO_FLAGS" fi ;; *-*-bsdi*) LIBS="$LIBS -lm" if test "$GCC" = yes ; then SO_FLAGS="-fPIC $SO_FLAGS" fi ;; *-*-freebsd*) LIBS="$LIBS -lm" if test "$GCC" = yes ; then SO_LD="$CC" SO_FLAGS="-fPIC $SO_FLAGS" CFLAGS="-fPIC $CFLAGS" LDSO_FLAGS="-shared" fi ;; *-*-openbsd*) LIBS="$LIBS -lm" if test "$GCC" = yes ; then SO_LD="$CC" SO_FLAGS="-fPIC $SO_FLAGS" CFLAGS="-ftrampolines $CFLAGS" LDSO_FLAGS="-shared" fi ;; *-*-netbsd*) LIBS="$LIBS -lm" if test "$GCC" = yes ; then SO_LD="$CC" SO_FLAGS="-fPIC $SO_FLAGS" LDSO_FLAGS="-shared" fi ;; *-*-mingw*) LIBS="$LIBS -lwinmm -lwsock32" LDFLAGS="$LDFLAGS -mwindows" SO_INSTALL=":" SO_LD=":" ;; *-apple-*) SO_LD="$CC" LDSO_FLAGS="-dynamic -bundle -undefined suppress -flat_namespace" ;; esac AC_SUBST(LDSO_FLAGS) AC_SUBST(SO_FLAGS) AC_SUBST(SO_LD) #-------------------------------------------------------------------------------- # export-dynamic #-------------------------------------------------------------------------------- CFLAGS="-O2 -I. $CFLAGS" ORIGINAL_LDFLAGS="$LDFLAGS" case "$host" in *-*-linux* | *-*-bsdi* | *-*-freebsd* | *-*-openbsd* | *-*-netbsd*) if test "$CC" = "gcc" || test "$CC" = "g++" || test "$CC" = "cc" ; then LDFLAGS="$LDFLAGS -Wl,-export-dynamic" fi esac #-------------------------------------------------------------------------------- # disable-deprecated #-------------------------------------------------------------------------------- if test "$enable_deprecated" = no ; then CFLAGS="-DGTK_DISABLE_DEPRECATED -DG_DISABLE_DEPRECATED -DGDK_DISABLE_DEPRECATED -DPANGO_DISABLE_DEPRECATED -DCAIRO_DISABLE_DEPRECATED -DGSL_DISABLE_DEPRECATED -Wall $CFLAGS" AC_DEFINE(DISABLE_DEPRECATED) fi #-------------------------------------------------------------------------------- # output #-------------------------------------------------------------------------------- AC_SUBST(INSTALL) AC_SUBST(CFLAGS) AC_SUBST(ORIGINAL_LDFLAGS) AC_SUBST(LDFLAGS) AC_SUBST(MAKE_TARGET) AC_OUTPUT AC_MSG_RESULT([ Options selected ------------------------- Snd version ...........: $VERSION CFLAGS ................: $CFLAGS LDFLAGS ...............:$LDFLAGS LIBS...................: $LIBS prefix.................: ${prefix} extension language.....: $LOCAL_LANGUAGE audio system...........: $AUDIO_SYSTEM graphics toolkit.......: $GRAPHICS_TOOLKIT optional libraries.....:$OPTIONAL_LIBRARIES random features........:$RANDOM_FEATURES environs...............: $host $CC ]) snd-16.1/marks.scm0000644000076400007640000004003612623732554012170 0ustar bilbil;;; examples of mark-related functions (provide 'snd-marks.scm) (require snd-selection.scm snd-hooks.scm) ;;; Contents: ;;; mark-name->id is a global version of find-mark ;;; move-syncd-marks moves all syncd marks together ;;; describe-mark shows mark history ;;; click marks between start-sync and stop-sync to sync them together ;;; synchronize sounds at a given mark ;;; fit selection between marks, expanding via granulate (this needs some tweaking...) ;;; pad-marks inserts silence before each in a list of marks ;;; play-syncd-marks and play-between-marks ;;; report-mark-names causes mark names to be posted in the minibuffer as a sound is played ;;; snap-marks places marks at current selection boundaries ;;; define-selection-via-marks selects the portion between two marks ;;; snap-mark-to-beat forces dragged mark to end up on a beat ;;; mark-explode splits a sound into a bunch of sounds based on mark placements ;;; save-mark-properties sets up an after-save-state-hook function to save any mark-properties ;;; mark-click-info is a mark-click-hook function that describes a mark and its properties ;;; -------- mark-name->id is a global version of find-mark (define mark-name->id (let ((documentation "(mark-name->id name) is like find-mark but searches all currently accessible channels")) (lambda (name) (call-with-exit (lambda (return) (for-each (lambda (snd) (do ((chn 0 (+ 1 chn))) ((= chn (channels snd))) (let ((mark (find-mark name snd chn))) (if (mark? mark) (return mark))))) (sounds)) 'no-such-mark))))) ;;; -------- move-syncd-marks moves all syncd marks together (define move-syncd-marks (let ((documentation "(move-syncd-marks sync diff) moves all marks sharing sync by diff samples")) (lambda (synch diff) (for-each (lambda (m) (set! (mark-sample m) (+ (mark-sample m) diff))) (syncd-marks synch))))) ;;; -------- describe-mark shows mark history (define describe-mark (let ((documentation "(describe-mark mark) returns a description of the movements of mark over the channel's edit history")) (lambda (id) (let ((mark-setting (catch 'no-such-mark (lambda () (mark-home id)) (lambda args #f)))) (if (not mark-setting) ;; not an active mark, so go scrounging for it ;; we're looking at every edit of every channel (set! mark-setting (call-with-exit (lambda (return) (for-each (lambda (snd) (do ((chn 0 (+ 1 chn))) ((= chn (channels snd))) (let ((max-edits (apply + (edits snd chn)))) (do ((ed 0 (+ 1 ed))) ((> ed max-edits)) (if (member id (marks snd chn ed)) (return (list snd chn))))))) (sounds)) #f)))) (if (pair? mark-setting) (let* ((snd (car mark-setting)) (chn (cadr mark-setting)) (max-edits (apply + (edits snd chn))) (descr ()) (header (list id sound: snd (short-file-name snd) 'channel: chn))) (do ((i max-edits (- i 1))) ((< i 0) descr) (if (member id (marks snd chn i)) (set! descr (cons (mark-sample id i) descr)) (set! descr (cons #f descr)))) (cons header descr)) (error 'no-such-mark (list "describe-mark" id))))))) ;;; -------- click marks between start-sync and stop-sync to sync them together ;;; (easier than calling mark-sync over and over by hand) (define mark-sync-number 0) (define (start-sync) (set! mark-sync-number (+ (mark-sync-max) 1))) (define (stop-sync) (set! mark-sync-number 0)) (define (click-to-sync id) (set! (sync id) mark-sync-number) #f) ;(hook-push mark-click-hook (lambda (hook) (click-to-sync (hook 'id)))) ;;; -------- syncronize sounds at a given mark (define syncup (let ((documentation "(syncup marks) pads the channels with zeros so that all the given marks occur at the same time")) (lambda ids (let* ((samps (map mark-sample ids)) (max-samp (apply max samps))) (define (pad-to-sync lst-ids lst-samps) (if (pair? lst-ids) (begin (if (< (car lst-samps) max-samp) (let ((nsamps (- max-samp (car lst-samps))) (snd-chn (mark-home (car lst-ids)))) (insert-samples 0 nsamps (make-float-vector nsamps) (car snd-chn) (cadr snd-chn)))) (pad-to-sync (cdr lst-ids) (cdr lst-samps))))) (pad-to-sync ids samps))))) ;;; -------- fit selection between marks, expanding via granulate (this needs some tweaking...) (define fit-selection-between-marks (let ((documentation "(fit-selection-between-marks m1 m2) fits (and mixes) the current selection (via granulate) between the given marks")) (lambda (m1 m2) (let ((m1-samp (mark-sample m1)) (m2-samp (mark-sample m2)) (m1-home (mark-home m1)) (m2-home (mark-home m2))) (if (not (selection?)) (error 'no-active-selection)) (if (not (equal? m1-home m2-home)) (snd-print (format #f "~A is in ~A[~A] but ~A is in ~A[~A]?" m1 (car m1-home) (cadr m1-home) m2 (car m2-home) (cadr m2-home))) (let* ((mark-samps (- m2-samp m1-samp)) (selection-samps (selection-framples)) (reg-data (let ((data (make-float-vector selection-samps)) (rd (make-sampler (selection-position)))) (do ((i 0 (+ 1 i))) ((= i selection-samps)) (set! (data i) (rd))) data)) (inctr 0)) (if (= mark-samps selection-samps) (map-channel (lambda (y) (let ((val (+ y (reg-data inctr)))) (set! inctr (+ 1 inctr)) val)) m1-samp mark-samps (car m1-home) (cadr m1-home)) (let ((gr (make-granulate :expansion (/ mark-samps selection-samps) :input (lambda (dir) (if (or (>= inctr selection-samps) (< inctr 0)) 0.0 (let ((val (reg-data inctr))) (set! inctr (+ inctr dir)) val)))))) (map-channel (lambda (y) (+ y (granulate gr))) m1-samp mark-samps (car m1-home) (cadr m1-home)))))))))) ;;; -------- pad-marks inserts silence before each in a list of marks (define pad-marks (let ((documentation "(pad-marks marks secs) inserts secs seconds of silence before each mark")) (lambda (ids secs) (let* ((silence-length (floor (* secs (srate)))) (silence-samps (make-float-vector silence-length))) (as-one-edit (lambda () (for-each (lambda (n) (let ((samp (max 0 (- (mark-sample n) 1))) (home (mark-home n))) (insert-samples samp silence-length silence-samps (car home) (cadr home)))) ids))))))) ;;; -------- play-syncd-marks (define play-syncd-marks (let ((documentation "(play-syncd-marks sync) starts playing from all marks sharing sync")) (lambda (synch) (let ((chans 1) (rate 22050)) (for-each (lambda (m) (let* ((sound (car (mark-home m))) (channel (cadr (mark-home m))) (new-player (make-player sound channel))) (add-player new-player (mark-sample m)) (set! chans (max chans (+ 1 channel))) (set! rate (max rate (srate sound))))) (syncd-marks synch)) (start-playing chans rate))))) (define play-between-marks (let ((documentation "(play-between-marks ...) plays the portion between the marks (searching for plausible default marks)")) (lambda args (let* ((snd (or (selected-sound) (car (sounds)))) (chn (or (selected-channel) 0)) (m1 (if (> (length args) 0) (car args) (let find-mark ((ms (marks snd chn))) (if (null? ms) (begin (snd-print ";no marks in current window?") #f) (if (>= (mark-sample (car ms)) (left-sample snd chn)) (car ms) (find-mark (cdr ms))))))) (m2 (and (mark? m1) (if (> (length args) 1) (cadr args) (let find-another-mark ((ms (marks snd chn))) (if (null? ms) (begin (snd-print ";no second mark?") #f) (if (> (mark-sample (car ms)) (mark-sample m1)) (car ms) (find-another-mark (cdr ms))))))))) (if (and (mark? m1) (mark? m2)) (let* ((pos1 (mark-sample m1)) (pos2 (mark-sample m2)) (beg (min pos1 pos2)) (end (max pos1 pos2))) (play (car (mark-home m1)) :channel (cadr (mark-home m1)) :start beg :end end))))))) ;;; -------- report-mark-names causes mark names to be posted in the minibuffer as a sound is played (define report-mark-names (let ((documentation "(report-mark-names) causes mark names to be printed as they are passed while playing")) (lambda () (hook-push start-playing-hook (lambda (snd) (let* ((marklist (marks snd 0)) (samplist (map mark-sample marklist)) (samp 0)) (define (report-mark-names-play-hook hook) (set! samp (+ samp (hook 'size))) (if (and (pair? samplist) (>= samp (car samplist))) (begin (status-report (mark-name (car marklist)) snd) (set! marklist (cdr marklist)) (set! samplist (cdr samplist))))) (define (report-mark-names-stop-playing-hook hook) (status-report "" (hook 'snd)) (hook-remove play-hook report-mark-names-play-hook) (hook-remove stop-playing-hook report-mark-names-stop-playing-hook)) (hook-push stop-playing-hook report-mark-names-stop-playing-hook) (hook-push play-hook report-mark-names-play-hook) #f)))))) ;;; -------- snap-marks (define snap-marks (let ((documentation "snap-marks places marks at current selection boundaries")) (lambda () (let ((ms (list))) (if (selection?) (for-each (lambda (select) (let ((pos (apply selection-position select)) (len (apply selection-framples select))) (set! ms (cons (apply add-mark (+ pos len) select) (cons (apply add-mark pos select) ms))))) (selection-members))) (reverse ms))))) ;;; -------- define-selection-via-marks (define define-selection-via-marks (let ((documentation "(define-selection-via-marks m1 m2) defines the current selection to lie between the marks given")) (lambda (m1 m2) (let ((m1sc (mark-home m1)) (m2sc (mark-home m2))) (if (not (equal? m1sc m2sc)) (snd-error "define-selection-via-marks assumes the marks are in the same channel") (let ((beg (min (mark-sample m1) (mark-sample m2))) (end (max (mark-sample m1) (mark-sample m2))) (snd (car m1sc)) (chn (cadr m1sc))) (if (selection?) (set! (selection-member? #t) #f)) ; clear entire current selection, if any (set! (selection-member? snd chn) #t) (set! (selection-position snd chn) beg) (set! (selection-framples snd chn) (+ 1 (- end beg))))))))) ;;; -------- snap-mark-to-beat (define snap-mark-to-beat (let ((documentation "(snap-mark-to-beat) ensures that when a mark is dragged, its released position is always on a beat")) (lambda () (let ((mark-release 4)) (hook-push mark-hook (lambda (hook) (let ((mrk (hook 'id)) (snd (hook 'snd)) (chn (hook 'chn)) (reason (hook 'reason))) (if (= reason mark-release) (let* ((samp (mark-sample mrk)) (bps (/ (beats-per-minute snd chn) 60.0)) (sr (srate snd)) (beat (floor (/ (* samp bps) sr))) (lower (floor (/ (* beat sr) bps))) (higher (floor (/ (* (+ 1 beat) sr) bps)))) (set! (mark-sample mrk) (if (< (- samp lower) (- higher samp)) lower higher))))))))))) ;;; -------- mark-explode ;;; ;;; write out each section of a file between marks as a separate file (define mark-explode (let ((documentation "(mark-explode header-type sample-type) splits a sound into a bunch of sounds based on mark placements")) (lambda* ((htype mus-next) (dformat mus-bfloat)) (let ((start 0) (file-ctr 0) (snd (or (selected-sound) (car (sounds))))) (for-each (lambda (mark) (let ((end (mark-sample mark))) (if (> end start) (let ((filename (format #f "mark-~D.snd" file-ctr))) (set! file-ctr (+ 1 file-ctr)) (do ((i 0 (+ 1 i))) ((= i (channels snd))) (set! (selection-member? snd i) #t) (set! (selection-position snd i) start) (set! (selection-framples snd i) (- end start))) (save-selection filename :header-type htype :sample-type dformat :srate (srate snd)) (do ((i 0 (+ 1 i))) ((= i (channels snd))) (set! (selection-member? snd i) #f)))) (set! start end))) (car (marks snd))) (update-time-graph snd))))) ;;; -------- save mark property lists (define save-mark-properties (let ((documentation "(save-mark-properties) sets up an after-save-state-hook function to save any mark-properties")) (lambda () (define (open-appending filename) (open-output-file filename "a")) (define close-appending close-output-port) (hook-push after-save-state-hook (lambda (hook) (let* ((filename (hook 'name)) (fd (open-appending filename))) (format fd "~%~%;;; from remember-mark-properties in marks.scm~%") (format fd "(if (not (defined? 'mark-property)) (load \"marks.scm\"))~%") (for-each (lambda (snd-m) (for-each (lambda (chn-m) (for-each (lambda (m) (let ((mp (mark-properties m))) (if (and mp (pair? mp)) (let ((mhome (mark-home m)) (msamp (mark-sample m))) (format fd "(let ((s (find-sound ~S)))~%" (file-name (car mhome))) (format fd " (if (sound? s)~%") (format fd " (let ((m (find-mark ~A s ~A)))~%" msamp (cadr mhome)) (format fd " (if (mark? m)~%") (format fd " (set! (mark-properties m) '~A)))))~%" mp))))) chn-m)) snd-m)) (marks)) (close-appending fd))))))) (define mark-click-info (let ((documentation "(mark-click-info n) is a mark-click-hook function that describes a mark and its properties")) (lambda (hook) (let ((n (hook 'id))) (help-dialog "Mark Help" (format #f "Mark ~A~A:~% sample: ~D = ~,3F secs~A~A" n (let ((name (mark-name n))) (if (> (length name) 0) (format #f " (~S)" name) "")) (mark-sample n) (* 1.0 (/ (mark-sample n) (srate (car (mark-home n))))) (if (not (= (sync n) 0)) (format #f "~% sync: ~A" (sync n)) "") (let ((props (mark-properties n))) (if (pair? props) (format #f "~% properties: '~A" props) "")))) (set! (hook 'result) #t))))) #| ;;; this code saves mark info in the sound file header, and reads it back in when the sound is later reopened (define (eval-header sndf) (and (string? (comment sndf)) (catch #t (lambda () (eval-string (comment sndf))) (lambda args #f)))) (define (marks->string sndf) (let ((str (format #f "(require snd-marks.scm)~%(let ((m #f))~%")) (chan 0)) (for-each (lambda (chan-marks) (for-each (lambda (m) (set! str (string-append str (format #f " (set! m (add-mark ~A #f ~D ~A ~D))~%" (mark-sample m) chan (if (and (string? (mark-name m)) (> (length (mark-name m)) 0)) (format #f "~S" (mark-name m)) #f) (sync m)))) (if (pair? (mark-properties m)) (set! str (string-append str (format #f " (set! (mark-properties m) '~A)~%" (mark-properties m)))))) chan-marks) (set! chan (+ 1 chan))) (marks sndf)) (string-append str (format #f " m)~%")))) (hook-push output-comment-hook (lambda (hook) (set! (hook 'result) (marks->string (selected-sound))))) (hook-push after-open-hook (lambda (hook) (set! (hook 'result) (eval-header (hook 'snd))))) |# #| ;; from snd11? (define (delete-between-marks) (let ((mx (marks 0 0))) (if (and (pair? mx) (pair? (cdr mx))) ; there are at least 2 marks (let ((pos (cursor 0 0)) (deb #f) (fin #f)) (for-each (lambda (m) (if (<= (mark-sample m) pos) (set! deb (mark-sample m))) (if (and (not fin) (> (mark-sample m) pos)) (set! fin (mark-sample m)))) (sort! mx (lambda (a b) (< (mark-sample a) (mark-sample b))))) (when (and deb fin) (let ((dur (- fin deb))) (apply for-each (lambda (s c) (delete-samples deb dur s c)) (all-chans)))))))) |# snd-16.1/xen.c0000644000076400007640000012605712565407224011313 0ustar bilbil/* xen support procedures */ #include "mus-config.h" #include #include #include #include #include #include #include #ifdef _MSC_VER #include #include #pragma warning(disable: 4244) #endif #include "xen.h" #define S_gc_off "gc-off" #define S_gc_on "gc-on" char *xen_strdup(const char *str) { char *newstr = NULL; if ((!str) || (!(*str))) return(NULL); newstr = (char *)malloc(strlen(str) + 1); if (newstr) strcpy(newstr, str); return(newstr); } /* ------------------------------ RUBY ------------------------------ */ #if HAVE_RUBY #define HAVE_RB_PROC_NEW 1 /* As the README says, only versions of ruby 1.8 or later will work */ #if USE_SND void snd_rb_raise(Xen type, Xen info); /* XEN_ERROR */ #endif #define S_add_help "add_help" #define S_get_help "get_help" Xen rb_documentation(Xen name) { Xen_check_type((Xen_is_string(name) || Xen_is_symbol(name)), name, 1, S_get_help, "a char* or symbol"); if (Xen_is_symbol(name)) return(rb_property(XEN_SYMBOL_TO_STRING(name), Xen_documentation_symbol)); else return(rb_property(name, Xen_documentation_symbol)); } Xen rb_set_documentation(Xen name, Xen help) { Xen_check_type((Xen_is_string(name) || Xen_is_symbol(name)), name, 1, S_add_help, "a char* or symbol"); Xen_check_type(Xen_is_string(help), help, 2, S_add_help, "a char*"); if (Xen_is_symbol(name)) rb_set_property(XEN_SYMBOL_TO_STRING(name), Xen_documentation_symbol, help); else rb_set_property(name, Xen_documentation_symbol, help); return(name); } static Xen g_add_help(Xen name, Xen help) { #define H_add_help S_add_help "(name, help) add help to topic or function name (String or Symbol)" return(rb_set_documentation(name, help)); } static Xen g_get_help(Xen name) { #define H_get_help S_get_help "([name=:" S_get_help "]) \ return help associated with name (String or Symbol) or false" if (!Xen_is_bound(name)) return(C_string_to_Xen_string(H_get_help)); else return(rb_documentation(name)); } void xen_initialize(void) { #ifdef RUBY_INIT_STACK RUBY_INIT_STACK; #endif ruby_init(); ruby_init_loadpath(); ruby_script("xen"); /* necessary in ruby 1.9 (else segfault in rb_raise -- is this the rb GC bug (see snd-xen.c)?) */ Init_Hook(); } void xen_gc_mark(Xen val) { rb_gc_mark(val); } Xen xen_rb_cdr(Xen val) { if (Xen_is_cons(val)) { Xen new_list; new_list = Xen_copy_arg(val); rb_ary_delete_at(new_list, 0); return(new_list); } return(val); } Xen xen_rb_cons(Xen arg1, Xen arg2) { if (Xen_is_null(arg2)) return(rb_ary_new3(1, arg1)); if (!(Xen_is_cons(arg2))) return(rb_ary_new3(2, arg1, arg2)); return(rb_ary_unshift(arg2, arg1)); /* arg2 assumed to be array here in Ruby */ } Xen xen_rb_cons2(Xen arg1, Xen arg2, Xen arg3) { return(rb_ary_unshift(xen_rb_cons(arg2, arg3), arg1)); } Xen xen_rb_ary_new_with_initial_element(long num, Xen element) { Xen arr; int i; arr = rb_ary_new2(num); for (i = 0; i < num; i++) rb_ary_store(arr, i, element); return(arr); } Xen xen_set_assoc(Xen key, Xen val, Xen alist) { /* assoc key val in alist so later rb_ary_assoc will find val given key in alist */ /* if array?(alist) if array?(item = alist.assoc(key)) item[1] = val else alist.push([key, val]) end else [[key, val]] end */ if (Xen_is_cons(alist)) { Xen pair; pair = rb_ary_assoc(alist, key); if (Xen_is_cons(pair)) rb_ary_store(pair, 1, val); else rb_ary_push(alist, rb_assoc_new(key, val)); return(alist); } return(rb_ary_new3(1, rb_assoc_new(key, val))); } Xen xen_assoc(Xen key, Xen alist) { if (Xen_is_cons(alist)) { Xen val; val = rb_ary_assoc(alist, key); if (val != Qnil) return(rb_ary_entry(val, 1)); } return(Qfalse); } static char *scheme_to_ruby(const char *name) { /* replace any non-alphanumeric except "?" with "_". "?" -> "_p". '->" -> "2" drop "!" */ char *new_name = NULL; int len; len = strlen(name); if (len > 0) { int i, j; new_name = (char *)calloc(len + 3, sizeof(char)); /* +1 for possible _p, +1 for possible $ */ for (i = 0, j = 0; i < len; i++) { if (isalnum(name[i])) new_name[j++] = name[i]; else { if (name[i] != '!') { if ((name[i] == '-') && (name[i + 1] == '>')) { new_name[j++] = '2'; i++; } else { new_name[j++] = '_'; if (name[i] == '?') new_name[j++] = 'p'; } } } } } return(new_name); } char *xen_scheme_constant_to_ruby(const char *name) { /* upcase first char */ char *new_name; new_name = scheme_to_ruby(name); new_name[0] = toupper(new_name[0]); return(new_name); } char *xen_scheme_procedure_to_ruby(const char *name) { char *new_name = NULL; int len; len = name ? strlen(name) : 0; if (len > 0) { int i, j; new_name = (char *)calloc(len + 1, sizeof(char)); for (i = 0, j = 0; i < len; i++) { if ((isalnum(name[i])) || (name[i] == '!') || (name[i] == '?')) new_name[j++] = name[i]; else { if ((name[i] == '-') && (name[i + 1] == '>')) { new_name[j++] = '2'; i++; } else new_name[j++] = '_'; } } } return(new_name); } char *xen_scheme_global_variable_to_ruby(const char *name) { /* prepend $ */ char *new_name; new_name = scheme_to_ruby(name); if (new_name[0] == '_') new_name[0] = '$'; else { int i, len; len = strlen(new_name); for (i = len; i > 0; i--) new_name[i] = new_name[i - 1]; new_name[0] = '$'; } return(new_name); } /* looks for global variables and constants (functions too?) */ bool xen_rb_defined_p(const char *name) { char *var_name = scheme_to_ruby(name); char buf[128]; if (var_name[0] == '$') sprintf(buf, "defined? %s", var_name); else sprintf(buf, "defined? $%s", var_name); if (Xen_eval_C_string(buf) != Qnil) { free(var_name); return(true); } else { bool val; var_name[0] = toupper(var_name[0]); val = rb_const_defined(rb_cObject, rb_intern(var_name)); free(var_name); return(val); } } Xen xen_rb_gv_get(const char *name) { char *temp; Xen val; temp = xen_scheme_global_variable_to_ruby(name); val = rb_gv_get(temp); if (temp) free(temp); return(val); } Xen xen_rb_gv_set(const char *name, Xen new_val) { char *temp; Xen val; temp = xen_scheme_global_variable_to_ruby(name); val = rb_gv_set(temp, new_val); if (temp) free(temp); return(val); } Xen xen_rb_intern(const char *name) { char *temp; Xen val; temp = xen_scheme_constant_to_ruby(name); val = rb_intern(temp); if (temp) free(temp); return(val); } Xen xen_rb_make_keyword(const char *name) { char *temp; Xen val; temp = xen_scheme_procedure_to_ruby(name); val = C_string_to_Xen_symbol(temp); if (temp) free(temp); return(val); } void xen_rb_define(const char *name, Xen value) { char *temp; temp = xen_scheme_constant_to_ruby(name); rb_define_global_const(temp, value); if (temp) free(temp); } Xen xen_rb_define_class(const char *name) { char *temp; Xen val; temp = xen_scheme_constant_to_ruby(name); val = rb_define_class(temp, rb_cObject); if (temp) free(temp); return(val); } #ifndef RARRAY_PTR #define RB_ARRAY_PTR(Ary) RARRAY(Ary)->ptr #define RB_ARRAY_LEN(Ary) RARRAY(Ary)->len #else #define RB_ARRAY_PTR(Ary) RARRAY_PTR(Ary) #define RB_ARRAY_LEN(Ary) RARRAY_LEN(Ary) #endif int xen_rb_list_length(Xen obj) { if (Xen_is_vector(obj)) return((int)RB_ARRAY_LEN(obj)); if (obj == Xen_empty_list) return(0); return(-1); } Xen xen_rb_list_ref(Xen obj, int index) { if (Xen_is_vector(obj)) return(rb_ary_entry(obj, (long)index)); return(Xen_empty_list); } Xen xen_rb_list_set(Xen obj, int index, Xen value) { if (Xen_is_vector(obj)) rb_ary_store(obj, (long)index, value); return(value); } char *xen_version(void) { /* there is no macro we can depend on for the version number (its name changes unpredictably), * and ruby/version.h tries to be funny about how unreliable their semi-functional access is. * Maybe use and ruby_version here (a const char*). * No, even that doesn't work because there's no way to tell whether version.h exists. * Humph! */ char *buf; buf = (char *)calloc(128, sizeof(char)); snprintf(buf, 128, "%s", "Ruby"); return(buf); } static Xen xen_rb_report_error(Xen nada, Xen err_info) { /* backtrace info: */ /* return rb_funcall(err_info, rb_intern("backtrace"), 0); */ /* which can be an array of strings */ fprintf(stderr,"error: %s\n", Xen_object_to_C_string(err_info)); return(Xen_false); } static char *rb_prompt = NULL; static Xen xen_rb_rep(Xen ig) { Xen val; char *str; size_t size = 512; char **buffer = NULL; buffer = (char **)calloc(1, sizeof(char *)); buffer[0] = (char *)calloc(size, sizeof(char)); fprintf(stdout, "%s", rb_prompt); fgets(buffer[0], size, stdin); val = xen_rb_eval_string_with_error(buffer[0]); str = Xen_object_to_C_string(val); fprintf(stdout, "%s\n", (str) ? str : "nil"); free(buffer[0]); free(buffer); return(ig); } void xen_rb_repl_set_prompt(const char *prompt) { if (rb_prompt) free(rb_prompt); rb_prompt = xen_strdup(prompt); } static Xen xen_rb_rescue(Xen val) { if (!rb_prompt) rb_prompt = xen_strdup(">"); return(rb_rescue(Xen_procedure_cast xen_rb_rep, Xen_false, Xen_procedure_cast xen_rb_report_error, Xen_false)); } void xen_repl(int argc, char **argv) { while (true) { int status = 0; rb_protect(XEN_VALUE_ARG_PROCEDURE_CAST xen_rb_rescue, Xen_false, &status); if (status != 0) { fprintf(stderr, "%s\n", Xen_object_to_C_string(rb_gv_get("$!"))); status = 0; } } } Xen xen_rb_eval_string_with_error(const char *str) { int status = 0; Xen res; res = rb_eval_string_protect(str, &status); if (status != 0) return(xen_rb_obj_as_string(rb_gv_get("$!"))); return(res); } Xen xen_rb_load_file_with_error(Xen file) { int status = 0; rb_load_protect(file, 0, &status); if (status != 0) return(xen_rb_obj_as_string(rb_gv_get("$!"))); return(Xen_true); } Xen xen_rb_add_to_load_path(char *path) { Xen rpath, load_path; rpath = rb_str_new2(path); load_path = rb_gv_get("$:"); if (Xen_is_false(rb_ary_includes(load_path, rpath))) rb_ary_unshift(load_path, rpath); return(Xen_false); } static char *lstbuf = NULL; static char *xen_rb_list_to_s(Xen lst) { int i, len; if (lstbuf == NULL) lstbuf = (char *)calloc(512, sizeof(char)); else lstbuf[0] = '\0'; len = Xen_list_length(lst); for (i = 0; i < len; i++) { strcat(lstbuf, Xen_object_to_C_string(Xen_list_ref(lst, i))); strcat(lstbuf, " "); } return(lstbuf); } void xen_rb_raise(Xen type, Xen info) { rb_raise(rb_eStandardError, "%s: %s\n", rb_id2name(type), xen_rb_list_to_s(info)); } int xen_rb_required_args(Xen val) { int args; args = Xen_integer_to_C_int(val); if (args == -1) return(1); if (args < 0) return(abs(args + 1)); return(args); } Xen xen_rb_obj_as_string(Xen obj) { int status = 0; Xen result; result = rb_protect(XEN_VALUE_ARG_PROCEDURE_CAST rb_obj_as_string, obj, &status); if (status != 0) return(C_string_to_Xen_string("")); return(result); } #if HAVE_RB_PROC_NEW static Xen xen_rb_apply_1(Xen args) { return(rb_apply(Xen_car(args), rb_intern("call"), Xen_cadr(args))); } #else static Xen xen_rb_apply_1(Xen args) { if (Xen_is_procedure(Xen_car(args))) return(rb_apply(Xen_car(args), rb_intern("call"), Xen_cadr(args))); return(rb_apply(rb_mKernel, Xen_car(args), Xen_cadr(args))); } #endif Xen xen_rb_apply(Xen func, Xen args) { Xen val; int status = 0; val = rb_protect(XEN_VALUE_ARG_PROCEDURE_CAST xen_rb_apply_1, Xen_list_2(func, args), &status); if (status != 0) return(xen_rb_obj_as_string(rb_gv_get("$!"))); return(val); } static Xen xen_rb_funcall_0_inner(Xen args) { return(rb_funcall(args, rb_intern("call"), 0)); } Xen xen_rb_funcall_0(Xen func) { Xen val; int status = 0; val = rb_protect(XEN_VALUE_ARG_PROCEDURE_CAST xen_rb_funcall_0_inner, func, &status); if (status != 0) return(xen_rb_obj_as_string(rb_gv_get("$!"))); return(val); } Xen xen_rb_copy_list(Xen val) { if ((val == Xen_empty_list) || (!Xen_is_cons(val))) return Xen_empty_list; return rb_ary_dup(val); } Xen xen_rb_str_new2(char *arg) { return(rb_str_new2((arg) ? arg : "")); } /* class Hook */ static Xen xen_rb_cHook; static Xen hook_alloc(Xen klass) { return(Data_Wrap_Struct(klass, 0, 0, 0)); } #define Xen_is_class_hook(Arg) rb_obj_is_kind_of(Arg, xen_rb_cHook) bool xen_rb_hook_p(Xen obj) { return(Xen_is_class_hook(obj)); } bool xen_rb_hook_empty_p(Xen obj) { if (Xen_is_class_hook(obj)) return(RB_ARRAY_LEN(rb_iv_get(obj, "@procs")) == 0); return(true); } /* * @name = "$name_of_hook" * @arity = arity of procedure(s), default 0 * @procs = [["named proc1", proc1], ...] */ static Xen xen_rb_hook_initialize(int argc, Xen *argv, Xen hook) { Xen name, arity, help; rb_scan_args(argc, argv, "12", &name, &arity, &help); Xen_check_type(Xen_is_string(name) || Xen_is_symbol(name), name, 1, __func__, "a char* or symbol"); if (Xen_is_symbol(name)) name = XEN_SYMBOL_TO_STRING(name); if (arity != Qnil) { Xen_check_type(Xen_is_integer(arity), arity, 2, __func__, "an integer"); } else arity = INT2NUM(0); if (help != Qnil) { Xen_check_type(Xen_is_string(help), help, 3, __func__, "a char*"); XEN_SET_OBJECT_HELP(name, help); } rb_iv_set(hook, "@name", name); rb_iv_set(hook, "@arity", arity); rb_iv_set(hook, "@procs", rb_ary_new()); return(hook); } /* * To create a simple hook in C, see xen.h, XEN_DEFINE_SIMPLE_HOOK. * To create a global hook variables, see xen_rb_create_hook() below. */ Xen xen_rb_hook_c_new(char *name, int arity, char *help) { Xen args[3]; args[0] = C_string_to_Xen_string(name); args[1] = C_int_to_Xen_integer(arity); args[2] = C_string_to_Xen_string(help); return(xen_rb_hook_initialize(3, args, hook_alloc(xen_rb_cHook))); } /* RUBY_RELEASE_DATE < "2004-03-18" ? old : new lambda do end.arity -1 0 !!! lambda do || end.arity 0 0 lambda do |a| end.arity -1 1 !!! lambda do |*a| end.arity -1 -1 lambda do |a, b| end.arity 2 2 lambda do |a, *b| end.arity -2 -2 etc. */ #ifdef RUBY_VERSION #define XEN_RUBY_RELEASE_DATE RUBY_RELEASE_DATE #else #define XEN_RUBY_RELEASE_DATE Xen_string_to_C_string(Xen_eval_C_string("RUBY_RELEASE_DATE")) #endif #define RUBY_NEW_ARITY_DATE "2004-03-18" #define OLD_RUBY_ARITY() (strcmp(XEN_RUBY_RELEASE_DATE, RUBY_NEW_ARITY_DATE) < 0) /* #define NEW_RUBY_ARITY() (strcmp(XEN_RUBY_RELEASE_DATE, RUBY_NEW_ARITY_DATE) >= 0) */ bool xen_rb_arity_ok(int rargs, int args) { if (OLD_RUBY_ARITY()) { if ((rargs >= 2) || (rargs == 0)) return(rargs == args); else if (rargs <= -2) return(abs(rargs) <= args); else /* rargs -1 remains (no 1 exists) */ return((args == 1) || (args == 0) || (args == -1)); } else /* NEW_RUBY_ARITY */ return((rargs >= 0) ? (rargs == args) : (abs(rargs) <= args)); } static Xen xen_rb_hook_add_hook(int argc, Xen *argv, Xen hook) { Xen name, func; int args; args = Xen_integer_to_C_int(rb_iv_get(hook, "@arity")); rb_scan_args(argc, argv, "1&", &name, &func); Xen_check_type(Xen_is_string(name), name, 1, __func__, "a char*"); Xen_check_type(Xen_is_procedure(func) && xen_rb_arity_ok(Xen_integer_to_C_int(Xen_arity(func)), args), func, 2, __func__, "a procedure"); rb_ary_push(rb_iv_get(hook, "@procs"), rb_ary_new3(2, name, func)); return(hook); } #if HAVE_RB_PROC_NEW static Xen xen_proc_call(Xen args, Xen id) { return(rb_apply(rb_mKernel, (ID)id, Xen_is_cons(args) ? args : Xen_list_1(args))); } #if 0 VALUE rb_proc_new((VALUE (*)(ANYARGS/* VALUE yieldarg[, VALUE procarg] */), VALUE)); #endif static Xen xen_rb_proc_new(const char *name, Xen (*func)(), int arity, const char* doc) { rb_define_module_function(rb_mKernel, name, Xen_procedure_cast func, arity); if (doc) C_SET_OBJECT_HELP(name, doc); return(rb_proc_new(Xen_procedure_cast xen_proc_call, rb_intern(name))); } static Xen xen_rb_hook_arity(Xen hook); Xen xen_rb_add_hook(Xen hook, VALUE (*func)(), const char *name, const char* doc) { /* called from C, not Ruby, to add a function to a Ruby-side hook */ char *temp; temp = xen_scheme_procedure_to_ruby(name); rb_ary_push(rb_iv_get(hook, "@procs"), rb_ary_new3(2, C_string_to_Xen_string(temp), xen_rb_proc_new(temp, func, Xen_integer_to_C_int(xen_rb_hook_arity(hook)), doc))); if (temp) free(temp); return(hook); } #else Xen xen_rb_add_hook(Xen hook, VALUE (*func)(), const char *name, const char* doc) { /* called from C, not Ruby, to add a function to a Ruby-side hook * this doesn't work in g++ because it thinks the funcs are invalid: * "error: invalid conversion from 'VALUE (*)(VALUE, VALUE)' to 'VALUE (*)(...)'" (snd-file.c etc) */ Xen var, avar; char *temp; temp = xen_scheme_procedure_to_ruby(name); avar = rb_iv_get(hook, "@arity"); rb_define_module_function(rb_mKernel, temp, Xen_procedure_cast func, (Xen_is_integer(avar)) ? Xen_integer_to_C_int(avar) : 0); if (doc) C_SET_OBJECT_HELP(temp, doc); var = rb_intern(temp); rb_ary_push(rb_iv_get(hook, "@procs"), rb_ary_new3(2, C_string_to_Xen_string(temp), var)); if (temp) free(temp); return(hook); } #endif static Xen xen_rb_hook_remove_hook(Xen hook, Xen name) { Xen ary; ary = rb_iv_get(hook, "@procs"); return(rb_ary_delete(ary, rb_ary_assoc(ary, name))); } Xen xen_rb_hook_reset_hook(Xen hook) { if (Xen_is_class_hook(hook)) rb_ary_clear(rb_iv_get(hook, "@procs")); return(hook); } static Xen xen_rb_hook_names(Xen hook) { Xen ary, ret = Qnil; long len; ary = rb_iv_get(hook, "@procs"); len = RB_ARRAY_LEN(ary); if (len > 0) { long i; ret = rb_ary_new2(len); for (i = 0; i < len; i++) rb_ary_store(ret, i, Xen_vector_ref(Xen_vector_ref(ary, i), 0)); } return(ret); } Xen xen_rb_hook_to_a(Xen hook) { Xen ret = Qnil; if (Xen_is_class_hook(hook)) { Xen ary; long len; ary = rb_iv_get(hook, "@procs"); len = Xen_list_length(ary); if (len > 0) { long i; ret = rb_ary_new2(len); for (i = 0; i < len; i++) rb_ary_store(ret, i, Xen_vector_ref(Xen_vector_ref(ary, i), 1)); } } return(ret); } static Xen xen_rb_hook_run_hook(Xen hook) { if (RB_ARRAY_LEN(rb_iv_get(hook, "@procs"))) rb_ary_each(xen_rb_hook_to_a(hook)); return(hook); } /* * Calls all hook-procedures but returns only the last result; use * $var_hook.run_hook { |prc| ret << prc.call(*args) } for collecting * results. */ static Xen xen_rb_hook_call(int argc, Xen *argv, Xen hook) { Xen result = Qnil, rest, procs; rb_scan_args(argc, argv, "*", &rest); procs = xen_rb_hook_to_a(hook); if (procs != Qnil) { long i; for (i = 0; i < RB_ARRAY_LEN(procs); i++) result = xen_rb_apply(rb_ary_entry(procs, i), rest); } return(result); } static Xen xen_rb_hook_is_empty_p(Xen hook) { return(C_bool_to_Xen_boolean(RB_ARRAY_LEN(rb_iv_get(hook, "@procs")) == 0)); } static Xen xen_rb_hook_length(Xen hook) { return(C_int_to_Xen_integer(RB_ARRAY_LEN(rb_iv_get(hook, "@procs")))); } static Xen xen_rb_hook_name(Xen hook) { return(rb_iv_get(hook, "@name")); } static Xen xen_rb_hook_describe(Xen hook) { return(Xen_documentation(xen_rb_hook_name(hook))); } static Xen xen_rb_hook_arity(Xen hook) { return(rb_iv_get(hook, "@arity")); } static Xen xen_rb_hook_inspect(Xen hook) { Xen str = rb_str_new2("#"); return(str); } /* bil -- added xen_rb_create_hook for Xen_define_hook in xen.h, 13-Jun-05 -- * seems to work, but I'm guessing, especially the rb_gv_set line. * I can't use rb_define_variable here, as in the old version, because it takes a pointer * to the new variable, which in this case is a local variable => segfault. */ Xen xen_rb_create_hook(char *name, int arity, char *help) { Xen var, hook_name; char *temp; var = xen_rb_hook_c_new(temp = xen_scheme_global_variable_to_ruby(name), arity, help); hook_name = xen_rb_hook_name(var); rb_gv_set(Xen_string_to_C_string(hook_name), var); if (temp) free(temp); return(var); } static int simple_hook_number = 0; Xen xen_rb_create_simple_hook(int arity) { char *name; Xen hook; name = (char *)calloc(20, sizeof(char)); snprintf(name, 20, "simple_%02d_hook", simple_hook_number++); hook = xen_rb_create_hook(name, arity, NULL); free(name); return(hook); } /* * make_hook(name, arity = 0, help = "", hook_name = nil, &func) * * make_hook("var_hook") * == $var_hook = Hook.new("var_hook") * make_hook("var_hook", 1) * == $var_hook = Hook.new("var_hook", 1) * make_hook("var_hook", 1, "help $var_hook") * == $var_hook = Hook.new("var_hook", 1, "help $var_hook") * * make_hook("var_hook", 1, "help $var_hook", "1st proc") do |a| ... end * == $var_hook = Hook.new("var_hook", 1, "help $var_hook") * $var_hook.add_hook!("1st proc") do |a| ... end */ #ifndef RSTRING_LEN #define RB_STR_LEN(str) RSTRING(str)->len #else #define RB_STR_LEN(str) RSTRING_LEN(str) #endif static Xen xen_rb_make_hook(int argc, Xen *argv, Xen klass) { Xen hook = Xen_false, name; if (argc > 0 && argc < 4) { hook = xen_rb_hook_initialize(argc, argv, hook_alloc(xen_rb_cHook)); if (rb_block_given_p()) { argv[0] = rb_str_new2(""); xen_rb_hook_add_hook(1, argv, hook); } } else if (argc == 4 && rb_block_given_p()) { hook = xen_rb_hook_initialize(3, argv, hook_alloc(xen_rb_cHook)); argv[0] = argv[3]; xen_rb_hook_add_hook(1, argv, hook); } else Xen_error(Xen_make_error_type("wrong-number-of-args"), Xen_list_1(C_string_to_Xen_string("make_hook(name, arity=0, help=\"\", hook_name=\"\", &func)"))); name = xen_rb_hook_name(hook); if (Xen_char_to_C_char(name) != '$') { char *temp; temp = xen_scheme_global_variable_to_ruby(Xen_string_to_C_string(name)); name = C_string_to_Xen_string(temp); if (temp) free(temp); } Xen_check_type(RB_STR_LEN(name) >= 2, name, 1, __func__, "a char*, len >= 2"); return(rb_gv_set(Xen_string_to_C_string(name), hook)); } static Xen xen_rb_is_hook_p(Xen klass, Xen obj) { return(C_bool_to_Xen_boolean(Xen_is_class_hook(obj))); } /* * Hook.new(name, arity = 0, help = "") * * $my_hook = Hook.new("my_hook", 2, "info of my_hook") * $my_hook.add_hook!("1st proc") do |a, b| ... end * or make_hook("my_hook", 2, "info of my_hook", "1st proc") do |a, b| ... end * * $my_hook.add_hook!("2nd proc") do |a, b| ... end * $my_hook.inspect --> # * * ret = 0 * $my_hook.run_hook do |prc| ret = prc.call(ret, 2) end * * $my_hook.help --> info of my_hook * $my_hook.remove_hook!("1st proc") * $my_hook.inspect --> # * * $my_hook.remove_hook!("2nd proc") * $my_hook.inspect --> # */ #if (!HAVE_RB_DEFINE_ALLOC_FUNC) static Xen xen_rb_new(int argc, Xen *argv, Xen klass) { Xen hook = hook_alloc(klass); rb_obj_call_init(hook, argc, argv); return(hook); } #endif static Xen rb_object_properties = Xen_false; #define S_property "property" #define S_set_property "set_property" #define S_properties "properties" Xen rb_property(Xen obj, Xen key) { #define H_property S_property "(obj, key) \ if key exists, return obj's value (maybe nil) associated with key otherwise false" Xen props = Xen_false; if (Xen_is_false(rb_object_properties)) return(Xen_false); props = rb_hash_aref(rb_object_properties, obj); if (Xen_is_false(props) || props == Qnil) return(Xen_false); else return(rb_hash_aref(props, key)); } Xen rb_set_property(Xen obj, Xen key, Xen value) { #define H_set_property S_set_property "(obj, key, value) \ set key-value pair for obj and return value" Xen props = Xen_false; if (Xen_is_false(rb_object_properties)) { rb_object_properties = rb_hash_new(); Xen_GC_protect(rb_object_properties); } else props = rb_hash_aref(rb_object_properties, obj); if (Xen_is_false(props) || props == Qnil) props = rb_hash_new(); rb_hash_aset(props, key, value); rb_hash_aset(rb_object_properties, obj, props); return(value); } Xen rb_properties(void) { #define H_properties S_properties "() return all properties of rb_object_properties (a hash)" return(rb_object_properties); } static Xen g_gc_off(void) { #define H_gc_off "(" S_gc_off ") turns off garbage collection" rb_gc_disable(); return(Xen_false); } static Xen g_gc_on(void) { #define H_gc_on "(" S_gc_on ") turns on garbage collection" rb_gc_enable(); return(Xen_false); } Xen_wrap_1_optional_arg(g_get_help_w, g_get_help); Xen_wrap_2_args(g_add_help_w, g_add_help); Xen_wrap_3_args(g_set_property_w, rb_set_property); Xen_wrap_2_args(g_property_w, rb_property); Xen_wrap_no_args(g_properties_w, rb_properties); Xen_wrap_no_args(g_gc_off_w, g_gc_off) Xen_wrap_no_args(g_gc_on_w, g_gc_on) static bool hook_inited = false; void Init_Hook(void) { if (hook_inited) return; hook_inited = true; xen_rb_cHook = rb_define_class("Hook", rb_cObject); rb_include_module(xen_rb_cHook, rb_mEnumerable); #if HAVE_RB_DEFINE_ALLOC_FUNC rb_define_alloc_func(xen_rb_cHook, hook_alloc); #else rb_define_singleton_method(xen_rb_cHook, "new", Xen_procedure_cast xen_rb_new, -1); #endif rb_define_method(xen_rb_cHook, "initialize", Xen_procedure_cast xen_rb_hook_initialize, -1); rb_define_method(xen_rb_cHook, "add_hook!", Xen_procedure_cast xen_rb_hook_add_hook, -1); rb_define_method(xen_rb_cHook, "remove_hook!", Xen_procedure_cast xen_rb_hook_remove_hook, 1); rb_define_method(xen_rb_cHook, "reset_hook!", Xen_procedure_cast xen_rb_hook_reset_hook, 0); rb_define_alias(xen_rb_cHook, "clear", "reset_hook!"); rb_define_method(xen_rb_cHook, "to_a", Xen_procedure_cast xen_rb_hook_to_a, 0); rb_define_method(xen_rb_cHook, "run_hook", Xen_procedure_cast xen_rb_hook_run_hook, 0); rb_define_alias(xen_rb_cHook, "each", "run_hook"); rb_define_method(xen_rb_cHook, "call", Xen_procedure_cast xen_rb_hook_call, -1); rb_define_method(xen_rb_cHook, "length", Xen_procedure_cast xen_rb_hook_length, 0); rb_define_alias(xen_rb_cHook, "size", "length"); rb_define_method(xen_rb_cHook, "empty?", Xen_procedure_cast xen_rb_hook_is_empty_p, 0); rb_define_method(xen_rb_cHook, "name", Xen_procedure_cast xen_rb_hook_name, 0); rb_define_method(xen_rb_cHook, "arity", Xen_procedure_cast xen_rb_hook_arity, 0); rb_define_method(xen_rb_cHook, "describe", Xen_procedure_cast xen_rb_hook_describe, 0); rb_define_alias(xen_rb_cHook, "help", "describe"); rb_define_alias(xen_rb_cHook, "documentation", "describe"); rb_define_method(xen_rb_cHook, "inspect", Xen_procedure_cast xen_rb_hook_inspect, 0); rb_define_global_function("make_hook", Xen_procedure_cast xen_rb_make_hook, -1); rb_define_global_function("hook?", Xen_procedure_cast xen_rb_is_hook_p, 1); Xen_define_procedure(S_get_help, g_get_help_w, 0, 1, 0, H_get_help); Xen_define_procedure(S_add_help, g_add_help_w, 2, 0, 0, H_add_help); Xen_define_procedure(S_set_property, g_set_property_w, 3, 0, 0, H_set_property); Xen_define_procedure(S_property, g_property_w, 2, 0, 0, H_property); Xen_define_procedure(S_properties, g_properties_w, 0, 0, 0, H_properties); Xen_define_procedure(S_gc_off, g_gc_off_w, 0, 0, 0, H_gc_off); Xen_define_procedure(S_gc_on, g_gc_on_w, 0, 0, 0, H_gc_on); } /* end of class Hook */ #endif /* ------------------------------ FORTH ------------------------------ */ #if HAVE_FORTH char *xen_version(void) { return(fth_format("Fth: %s, Xen: " XEN_VERSION, FTH_VERSION)); } void xen_gc_mark(Xen val) { fth_gc_mark(val); } /* * A simple interpreter: * * #include * * int main(int argc, char **argv) * { * xen_repl(argc, argv); * return(0); * } * * linking requires xen.o and -lfth -lm */ void xen_repl(int argc, char **argv) { fth_repl(argc, argv); } static ficlWord *snd_exit_xt; static void fth_snd_exit(int n) { if (!snd_exit_xt) snd_exit_xt = ficlSystemLookup(FTH_FICL_SYSTEM(), (char *)"snd-exit"); ficlStackPushInteger(FTH_FICL_STACK(), n); ficlVmExecuteXT(FTH_FICL_VM(), snd_exit_xt); ficlStackDrop(FTH_FICL_STACK(), 1); } static Xen g_gc_off(void) { #define H_gc_off "(" S_gc_off ") turns off garbage collection" fth_gc_on(); return(Xen_false); } static Xen g_gc_on(void) { #define H_gc_on "(" S_gc_on ") turns on garbage collection" fth_gc_on(); return(Xen_false); } void xen_initialize(void) { fth_init(); fth_exit_hook = fth_snd_exit; Xen_define_procedure(S_gc_off, g_gc_off, 0, 0, 0, H_gc_off); Xen_define_procedure(S_gc_on, g_gc_on, 0, 0, 0, H_gc_on); } #endif /* HAVE_FORTH */ /* ------------------------------ S7 ------------------------------ */ #if HAVE_SCHEME #include "s7.h" s7_scheme *s7; Xen xen_false, xen_true, xen_nil, xen_undefined, xen_zero; char *xen_version(void) { char *buf; buf = (char *)calloc(64, sizeof(char)); #if HAVE_SNPRINTF snprintf(buf, 64, "s7: %s (%s), Xen: %s", S7_VERSION, S7_DATE, XEN_VERSION); #else sprintf(buf, "s7: %s (%s), Xen: %s", S7_VERSION, S7_DATE, XEN_VERSION); #endif return(buf); } static char *xen_s7_repl_prompt = NULL; void xen_s7_set_repl_prompt(const char *new_prompt) { if (xen_s7_repl_prompt) free(xen_s7_repl_prompt); xen_s7_repl_prompt = xen_strdup(new_prompt); } #if USE_SND char *stdin_check_for_full_expression(const char *newstr); void stdin_free_str(void); #endif void xen_repl(int argc, char **argv) { int size = 512; bool expr_ok = true; char *buffer = NULL; buffer = (char *)calloc(size, sizeof(char)); while (true) { if (expr_ok) { fprintf(stdout, "\n%s", xen_s7_repl_prompt); expr_ok = false; /* don't get into an infinite loop if running in the background! */ } if (fgets(buffer, size, stdin) != NULL) { /* also, it's possible to get a string of spaces or nulls (? -- not sure what is coming in) if stdin is /dev/null */ /* then if (as in condor) stdout is being saved in a file, we get in an infinite loop storing "snd>" until the disk fills up */ int i, len; expr_ok = false; len = strlen(buffer); for (i = 0; i < len; i++) { if (buffer[i] == 0) break; if (!isspace((int)buffer[i])) { expr_ok = true; break; } } if (expr_ok) { char *str, *temp; #if USE_SND str = stdin_check_for_full_expression(buffer); /* "str" here is actually stdin_str, so we need to clear it explicitly */ if (!str) {expr_ok = false; continue;} len = strlen(str) + 16; temp = (char *)malloc(len * sizeof(char)); snprintf(temp, len, "(write %s)", str); Xen_eval_C_string(temp); free(temp); stdin_free_str(); #else temp = (char *)malloc(len + 16); snprintf(temp, len + 16, "(write %s)", buffer); /* use write, not display so that strings are in double quotes */ Xen_eval_C_string(temp); free(temp); #endif } } } free(buffer); } void xen_gc_mark(Xen val) { s7_mark_object(val); } Xen xen_set_assoc(s7_scheme *sc, s7_pointer key, s7_pointer val, s7_pointer alist) { /* fixup alist, return it (caller has to make sure it is reflected in its object) */ /* (let ((old-val (assoc key alist))) (if old-val (progn (set-cdr! old-val new-val) alist) (cons (cons key new-val) alist))) */ Xen old_val; old_val = s7_assoc(sc, key, alist); /* returns #f if nothing found */ if (old_val == s7_f(sc)) return(s7_cons(sc, s7_cons(sc, key, val), alist)); s7_set_cdr(old_val, val); return(alist); } Xen xen_assoc(s7_scheme *sc, Xen key, Xen alist) { Xen val; val = s7_assoc(sc, key, alist); if (val != s7_f(sc)) return(s7_cdr(val)); return(s7_f(sc)); } /* add various file functions that everyone else implements */ #ifndef _MSC_VER #include #include #endif #include #include static Xen g_getpid(void) { #define H_getpid "(getpid) returns the current job's process id" return(C_int_to_Xen_integer((int)getpid())); } #if (!WITH_SYSTEM_EXTRAS) static bool file_probe(const char *arg) { #ifndef _MSC_VER return(access(arg, F_OK) == 0); #else int fd; #ifdef O_NONBLOCK fd = open(arg, O_RDONLY, O_NONBLOCK); #else fd = open(arg, O_RDONLY, 0); #endif if (fd == -1) return(false); close(fd); return(true); #endif } static Xen g_file_exists_p(Xen name) { #define H_file_exists_p "(file-exists? filename): #t if the file exists" Xen_check_type(Xen_is_string(name), name, 1, "file-exists?", "a string"); return(C_bool_to_Xen_boolean(file_probe(Xen_string_to_C_string(name)))); } static bool is_directory(const char *filename) { #if (defined(_MSC_VER) || __CYGWIN__) return(false); #else #ifdef S_ISDIR struct stat statbuf; return((stat(filename, &statbuf) >= 0) && (S_ISDIR(statbuf.st_mode))); return(false); #endif #endif } static Xen g_is_directory(Xen name) { #define H_is_directory "(directory? filename): #t if filename names a directory" Xen_check_type(Xen_is_string(name), name, 1, "directory?", "a string"); return(C_bool_to_Xen_boolean(is_directory(Xen_string_to_C_string(name)))); /* snd-file.c l 84 */ } static Xen g_delete_file(Xen name) { #define H_delete_file "(delete-file filename): deletes the file" Xen_check_type(Xen_is_string(name), name, 1, "delete-file", "a string"); return(C_bool_to_Xen_boolean(unlink(Xen_string_to_C_string(name)))); } static Xen g_system(Xen command) { #define H_system "(system command): execute command" Xen_check_type(Xen_is_string(command), command, 1, "system", "a string"); return(C_int_to_Xen_integer(system(Xen_string_to_C_string(command)))); } static Xen g_s7_getenv(Xen var) /* "g_getenv" is in use in glib! */ { #define H_getenv "(getenv var): return value of environment variable var" Xen_check_type(Xen_is_string(var), var, 1, "getenv", "a string"); return(C_string_to_Xen_string(getenv(Xen_string_to_C_string(var)))); } #endif #ifdef _MSC_VER #include #endif static Xen g_getcwd(void) { #define H_getcwd "(getcwd) returns the name of the current working directory" char *buf; Xen result = Xen_false; buf = (char *)calloc(1024, sizeof(char)); #ifdef _MSC_VER if (_getcwd(buf, 1024) != NULL) #else if (getcwd(buf, 1024) != NULL) #endif result = C_string_to_Xen_string(buf); free(buf); return(result); } static Xen g_strftime(Xen format, Xen tm) { #define H_strftime "(strftime format time) returns a string describing the time: (strftime \"%d-%b %H:%M %Z\" (localtime (current-time)))" char *buf; Xen result; const struct tm *p; Xen_check_type(Xen_is_string(format), format, 1, "strftime", "a string"); Xen_check_type(Xen_is_wrapped_c_pointer(tm), tm, 2, "strftime", "a localtime struct"); p = (const struct tm *)Xen_unwrap_C_pointer(tm); Xen_check_type(p != NULL, tm, 2, "strftime", "a localtime struct"); buf = (char *)calloc(1024, sizeof(char)); strftime(buf, 1024, Xen_string_to_C_string(format), p); result = C_string_to_Xen_string(buf); free(buf); return(result); } /* (format #f ";~A~%" (strftime "%d-%b %H:%M %Z" (localtime (current-time)))) */ /* these two need to be compatible with g_file_write_date in snd-file.c */ static Xen g_localtime(Xen tm) { #define H_localtime "(localtime tm) breaks up tm into something suitable for strftime" time_t rtime; rtime = (time_t)Xen_ulong_to_C_ulong(tm); return(Xen_wrap_C_pointer(localtime((time_t *)(&rtime)))); } static Xen g_current_time(void) { time_t curtime; #define H_current_time "(current-time) returns the current time (for localtime and strftime)" curtime = time(NULL); return(C_ulong_to_Xen_ulong(curtime)); } static Xen g_tmpnam(void) { #define H_tmpnam "(tmpnam) returns a new (hopefully unused) temporary file name" #define BUFFER_SIZE 512 static int file_ctr = 0; char *str, *tmpdir = NULL; Xen result; str = (char *)calloc(BUFFER_SIZE, sizeof(char)); tmpdir = xen_strdup(getenv("TMPDIR")); #ifdef P_tmpdir if (tmpdir == NULL) tmpdir = xen_strdup(P_tmpdir); /* /usr/include/stdio.h */ if (tmpdir) { int len; len = strlen(tmpdir); if (len > 0) { if (tmpdir[len - 1] == '/') tmpdir[len - 1] = 0; } else { free(tmpdir); tmpdir = xen_strdup("."); } } #else if (tmpdir == NULL) tmpdir = xen_strdup("/tmp"); #endif snprintf(str, BUFFER_SIZE, "%s/xen_%d_%d", tmpdir, (int)getpid(), file_ctr++); if (tmpdir) free(tmpdir); result = C_string_to_Xen_string(str); free(str); return(result); } static Xen g_ftell(Xen fd) { return(C_int_to_Xen_integer(lseek(Xen_integer_to_C_int(fd), 0, SEEK_CUR))); } static Xen g_gc_off(void) { #define H_gc_off "(" S_gc_off ") turns off garbage collection" s7_gc_on(s7, false); return(Xen_false); } static Xen g_gc_on(void) { #define H_gc_on "(" S_gc_on ") turns on garbage collection" s7_gc_on(s7, true); return(Xen_false); } Xen_wrap_no_args(g_getpid_w, g_getpid) #if (!WITH_SYSTEM_EXTRAS) Xen_wrap_1_arg(g_file_exists_p_w, g_file_exists_p) Xen_wrap_1_arg(g_is_directory_w, g_is_directory) Xen_wrap_1_arg(g_delete_file_w, g_delete_file) Xen_wrap_1_arg(g_s7_getenv_w, g_s7_getenv) Xen_wrap_1_arg(g_system_w, g_system) #endif Xen_wrap_no_args(g_getcwd_w, g_getcwd) Xen_wrap_2_args(g_strftime_w, g_strftime) Xen_wrap_1_arg(g_localtime_w, g_localtime) Xen_wrap_no_args(g_current_time_w, g_current_time) Xen_wrap_no_args(g_tmpnam_w, g_tmpnam) Xen_wrap_1_arg(g_ftell_w, g_ftell) Xen_wrap_no_args(g_gc_off_w, g_gc_off) Xen_wrap_no_args(g_gc_on_w, g_gc_on) s7_scheme *s7_xen_initialize(s7_scheme *sc) { xen_s7_repl_prompt = xen_strdup("> "); if (!sc) { s7 = s7_init(); if (!s7) { fprintf(stderr, "Can't initialize s7!\n"); return(NULL); } } else s7 = sc; xen_false = s7_f(s7); xen_true = s7_t(s7); xen_nil = s7_nil(s7); xen_undefined = s7_undefined(s7); xen_zero = s7_make_integer(s7, 0); s7_gc_protect(s7, xen_zero); Xen_define_safe_procedure("getpid", g_getpid_w, 0, 0, 0, H_getpid); #if (!WITH_SYSTEM_EXTRAS) Xen_define_safe_procedure("file-exists?", g_file_exists_p_w, 1, 0, 0, H_file_exists_p); Xen_define_safe_procedure("directory?", g_is_directory_w, 1, 0, 0, H_is_directory); Xen_define_safe_procedure("delete-file", g_delete_file_w, 1, 0, 0, H_delete_file); Xen_define_safe_procedure("getenv", g_s7_getenv_w, 1, 0, 0, H_getenv); Xen_define_safe_procedure("system", g_system_w, 1, 0, 0, H_system); #endif Xen_define_safe_procedure("getcwd", g_getcwd_w, 0, 0, 0, H_getcwd); Xen_define_safe_procedure("strftime", g_strftime_w, 2, 0, 0, H_strftime); Xen_define_safe_procedure("tmpnam", g_tmpnam_w, 0, 0, 0, H_tmpnam); Xen_define_safe_procedure("localtime", g_localtime_w, 1, 0, 0, H_localtime); Xen_define_safe_procedure("current-time", g_current_time_w, 0, 0, 0, H_current_time); Xen_define_safe_procedure("ftell", g_ftell_w, 1, 0, 0, "(ftell fd): lseek"); Xen_define_safe_procedure(S_gc_off, g_gc_off_w, 0, 0, 0, H_gc_off); Xen_define_safe_procedure(S_gc_on, g_gc_on_w, 0, 0, 0, H_gc_on); Xen_eval_C_string("(define (hook-push hook func) \n\ \"(hook-push hook func) adds func to hook's function list\" \n\ (if (not (member func (hook-functions hook) eq?)) (set! (hook-functions hook) (cons func (hook-functions hook)))))"); Xen_eval_C_string("(define (hook-append hook func) \n\ \"(hook-append hook func) adds func to the end of hook's function list\" \n\ (set! (hook-functions hook) (append (hook-functions hook) (list func))))"); Xen_eval_C_string("(define (hook-clear hook) (set! (hook-functions hook) ()))"); Xen_eval_C_string("(define (hook-remove hook func) \n\ (set! (hook-functions hook)\n\ (let loop ((l (hook-functions hook))\n\ (result ()))\n\ (cond ((null? l) (reverse! result))\n\ ((eq? func (car l)) (loop (cdr l) result))\n\ (else (loop (cdr l) (cons (car l) result)))))))"); Xen_eval_C_string("(define load-from-path load)"); Xen_eval_C_string("(define (1+ x) \"add 1 to arg\" (+ x 1))"); Xen_eval_C_string("(define (1- x) \"subtract 1 from arg\" (- x 1))"); Xen_eval_C_string("(define-macro (while whether . body) `(do () ((not ,whether)) ,@body))"); Xen_eval_C_string("(define (identity x) \"return arg\" x)"); return(s7); } void xen_initialize(void) { s7_xen_initialize(NULL); } #endif /* ------------------------------ NONE OF THE ABOVE ------------------------------ */ #if (!HAVE_EXTENSION_LANGUAGE) char *xen_version(void) { char *buf; buf = (char *)calloc(64, sizeof(char)); #if HAVE_SNPRINTF snprintf(buf, 64, "no extension language"); #else sprintf(buf, "no extension language"); #endif return(buf); } void xen_repl(int argc, char **argv) { } void xen_initialize(void) { } void xen_gc_mark(Xen val) { } void xen_no_ext_lang_check_args(const char *name, int args, int req_args, int opt_args, int rst_args) { if (args > 0) /* nargify -- all are required */ { if (req_args != args) fprintf(stderr, "%s: %d required args, but req: %d (opt: %d, rst: %d)\n", name, args, req_args, opt_args, rst_args); if (opt_args != 0) fprintf(stderr, "%s: all args required, but opt: %d (rst: %d)\n", name, opt_args, rst_args); if (rst_args != 0) fprintf(stderr, "%s: all args required, but rst: %d\n", name, rst_args); } else { if (args != -100) /* vargify -- any ok */ { args = -args; if (rst_args == 0) { if (req_args + opt_args != args) fprintf(stderr, "%s: total args: %d, but req: %d and opt: %d\n", name, args, req_args, opt_args); } else { if (req_args + opt_args > args) fprintf(stderr, "%s: has :rest, but req: %d and opt: %d , whereas total: %d\n", name, req_args, opt_args, args); } } } } #endif snd-16.1/snd-xm.fs0000644000076400007640000004527412306421672012112 0ustar bilbil\ snd-xm.fs -- snd-motif|gtk.scm|snd-xm.rb --> snd-xm.fs \ Author: Michael Scholz \ Created: Mon Dec 26 22:36:46 CET 2005 \ Changed: Tue Dec 11 01:55:54 CET 2012 \ Commentary: \ \ Requires --with-motif|gtk \ \ Tested with Snd 13.x \ Fth 1.3.x \ Motif 2.3.4 X11R6 \ Gtk+ 3.0.12, Glib 2.28.8, Pango 1.28.4, Cairo 1.10.2 \ \ Motif and Gtk: \ \ widget? ( w -- f ) \ set-sensitive ( w f -- ) \ is-managed? ( w -- f ) \ change-label ( widget new-label -- ) \ for-each-child ( widget prc -- ) \ load-font ( name -- fid|#f ) \ host-name ( -- host ) \ add-main-pane ( name class args -- wid ) \ raise-dialog ( dialog -- ) \ activate-dialog ( dialog -- ) \ show-disk-space ( snd -- ) \ \ Motif only: \ \ main-dpy ( -- dpy ) \ current-screen ( -- scr ) \ white-pixel ( -- pix ) \ black-pixel ( -- pix ) \ screen-depth ( -- n ) \ \ children->array ( widget -- array ) \ find-child ( widget name -- wid ) \ widget-exists? ( widget name -- f ) \ main-widget-exists? ( name -- f ) \ display-widget-tree ( widget -- ) \ set-main-color-of-widget ( w -- ) \ \ add-channel-pane ( snd chn name type args -- wid ) \ add-sound-pane ( snd name type args -- wid ) \ add-listener-pane ( name type args -- wid ) \ \ add-mark-pane ( -- ) \ \ current-label ( widget -- label ) \ Code: 'snd-nogui provided? [if] skip-file [then] 'snd-gtk provided? [if] 'gtk3 provided? not [if] \ We use is-managed? in snd-test.fs [defined] Fgtk_widget_get_realized [if] <'> Fgtk_widget_get_realized [else] <'> noop [then] alias is-managed? ( wid -- f ) .( snd-gtk: gtk3 required -- skipping snd-xm.fs ) cr skip-file [then] [then] "X error" create-exception x-error require extensions \ ;;; -------- show-disk-space \ ;;; \ ;;; adds a label to the minibuffer area showing the current free space hide #() value labelled-snds : kmg { num -- str } num 0<= if "disk full!" else "" { str } num 1024 d> if num 1024 1024 * d> if "space: %6.3fG" #( num 1024.0 1024.0 f* f/ ) else "space: %6.3fM" #( num 1024.0 f/ ) then else "space: %10dK" #( num ) then string-format then ; set-current #f value showing-disk-space \ for prefs \ \ after-open-hook <'> show-disk-space add-hook! \ previous \ ===== Gtk and Motif ===== 'snd-gtk provided? [if] \ !HAVE_MOTIF : widget? ( w -- f ) FGTK_IS_WIDGET ; : set-sensitive ( w f -- ) Fgtk_widget_set_sensitive drop ; [defined] Fgtk_widget_get_realized [if] <'> Fgtk_widget_get_realized [else] <'> noop [then] alias is-managed? ( wid -- f ) : change-label ( wid new-label -- ) doc" Change WIDGET's label to be NEW-LABEL." { wid new-label } wid if wid FGTK_IS_LABEL if wid else wid FGTK_BIN Fgtk_bin_get_child then FGTK_LABEL new-label Fgtk_label_set_text drop then ; hide : for-each-cb ( cb -- prc; w d self -- val ) { cb } 2 proc-create ( prc ) cb , does> { w d self -- val } self @ ( cb ) #( w ) run-proc ; set-current : for-each-child { wid prc -- } doc" Apply PRC ( w -- val ) to WIDGET and each of its children." wid widget? if prc #( wid ) run-proc drop wid FGTK_CONTAINER prc for-each-cb Fgtk_container_foreach drop then ; previous : load-font ( name -- fid|#f ) Fpango_font_description_from_string ; : host-name ( -- host ) doc" Return name of current machine." main-widgets 0 array-ref "WM_CLIENT_MACHINE" #f Fgdk_atom_intern FGDK_TARGET_STRING 0 1024 0 Fgdk_property_get { val } \ we get '( #t #( GdkAtom 0x3f ) 8 21 "pumpkin.fth-devel.net" ) val car if val 4 list-ref 0 val 3 list-ref string-substring else #f then ; \ --- add our own pane to the overall Snd window (underneath the \ listener in this case) --- \ main-widgets 5 array-ref (without -notebook) and \ main-widgets 2 array-ref \ seem to be of type GTK_BOX [ms] : add-main-pane <{ name :optional class-not-needed #f args-not-needed #f -- wid }> FGTK_ORIENTATION_HORIZONTAL 0 Fgtk_box_new { pane } main-widgets 5 array-ref { parent } parent FGTK_IS_BOX unless main-widgets 2 array-ref to parent then parent FGTK_IS_BOX unless 'x-error #( "%s: no GTK_BOX widget found" get-func-name ) fth-throw then parent FGTK_BOX pane #f #f 4 Fgtk_box_pack_start drop pane Fgtk_widget_show drop pane name Fgtk_widget_set_name drop pane ; \ --- bring possibly-obscured dialog to top --- : raise-dialog ( dialog -- ) { w } w Fgtk_widget_show drop w FGTK_WINDOW Fgtk_window_present drop ; <'> raise-dialog alias activate-dialog ( dialog -- ) \ --- show-disk-space, Gtk specific --- hide : show-label <{ data -- n }> data 0 array-ref sound? if data 0 array-ref { snd } data 1 array-ref { wid } snd file-name disk-kspace kmg { space } wid FGTK_LABEL space Fgtk_label_set_text drop 10000 running-word data Fg_timeout_add drop 0 else nil then ; set-current : show-disk-space <{ snd -- }> doc" Add a label to the minibuffer area showing the current \ free space (for use with after-open-hook)." #f ( flag ) labelled-snds each { n } n 0 array-ref snd equal? if ( flag ) drop n leave then end-each { previous-label } previous-label unless snd sound? if #t to showing-disk-space snd sound-widgets 10 array-ref { name-form } snd file-name disk-kspace kmg { space } space Fgtk_label_new { new-label } name-form FGTK_BOX new-label #f #f 6 Fgtk_box_pack_start drop new-label Fgtk_widget_show drop #( snd new-label ) to previous-label labelled-snds previous-label array-push drop 10000 <'> show-label previous-label Fg_timeout_add drop else "no sound found for disk space label" snd-error drop then then ; previous [else] \ HAVE_MOTIF : widget? ( w -- f) FWidget? ; : set-sensitive ( w f -- ) FXtSetSensitive drop ; <'> FXtIsManaged alias is-managed? ( wid -- f ) : change-label ( wid new-label -- ) doc" Change WIDGET's label to be NEW-LABEL." { wid new-label } new-label FXmStringCreateLocalized { str } wid #( FXmNlabelString str ) FXtVaSetValues drop str FXmStringFree drop ; : for-each-child { wid prc -- } doc" Apply PRC to WIDGET and each of its children." prc #( wid ) run-proc drop wid FXtIsComposite if wid #( FXmNchildren 0 ) FXtVaGetValues 1 array-ref each ( w ) prc recurse end-each then ; : main-dpy ( -- dpy ) main-widgets 1 array-ref FXtDisplay ; : load-font ( name -- fid|#f ) { name } main-dpy name FXLoadQueryFont { fs } fs FXFontStruct? if fs Ffid else #f then ; : current-screen ( -- scr ) doc" Return the current X screen number of the current display." main-dpy FDefaultScreenOfDisplay ; : white-pixel ( -- pix ) current-screen FWhitePixelOfScreen ; : black-pixel ( -- pix ) current-screen FBlackPixelOfScreen ; : screen-depth ( -- n ) current-screen FDefaultDepthOfScreen ; \ --- apply func to every widget belonging to w --- hide : children->array-cb ( ary -- prc; child self -- ) { ary } 1 proc-create ( prc ) ary , does> { child self -- } self @ ( ary ) child array-push drop ; set-current : children->array ( widget -- array ) #() { ary } ( widget ) ary children->array-cb for-each-child ary ; previous : find-child ( widget name -- wid ) doc" Return a widget named NAME, if one can be found in the \ widget hierarchy beneath WIDGET." { widget name } #f widget children->array each { w } w FXtName name string= if not w swap leave then end-each unless 'no-such-widget #( "%s: %S" get-func-name name ) fth-throw then ; : widget-exists? { widget name -- f } #f ( flag ) widget children->array each ( w ) FXtName name string= if ( flag ) not leave then end-each ( flag ) ; : main-widget-exists? ( name -- f ) main-widgets 1 array-ref swap widget-exists? ; hide : display-widget <{ widget n -- }> widget FXtName empty? if "" else widget FXtName then n spaces .string cr widget FXtIsComposite if widget #( FXmNchildren 0 ) FXtVaGetValues 1 array-ref each ( w ) n 2 + recurse end-each then ; set-current : display-widget-tree { widget -- } doc" Display the hierarchy of widgets beneath WIDGET." <'> display-widget #( widget 0 ) run-proc drop ; previous hide : change-color-cb <{ w -- }> w FXtIsWidget if w FXmIsScrollBar if w position-color FXmChangeColor drop else w basic-color FXmChangeColor drop then then ; set-current : set-main-color-of-widget ( widget -- ) doc" Set the background color of WIDGET." <'> change-color-cb for-each-child ; previous : host-name ( -- host ) doc" Return name of current machine." main-widgets 1 array-ref { wid } wid FXtWindow { win } main-dpy win main-dpy "WM_CLIENT_MACHINE" #f FXInternAtom 0 32 #f FXA_STRING FXGetWindowProperty { host } host if host 5 array-ref else host then ; \ --- add our own pane to the channel section --- \ \ 0 0 "new-pane" FxmDrawingAreaWidgetClass \ #( FXmNbackground graph-color FXmNforeground data-color ) \ add-channel-pane value draw-widget : add-channel-pane { snd chn name typ args -- wid } name typ snd chn channel-widgets 7 array-ref FXtParent FXtParent args FXtCreateManagedWidget ; \ --- add our own pane to the sound section (underneath the controls \ in this case) --- : add-sound-pane { snd name typ args -- wid } name typ snd sound-widgets 0 array-ref args undef FXtCreateManagedWidget ; \ --- add our own pane to the overall Snd window (underneath the \ listener in this case) --- : add-main-pane { name class args -- wid } main-widgets 5 array-ref dup unless drop main-widgets 3 array-ref then { parent } name class parent args undef FXtCreateManagedWidget ; \ --- add a widget at the top of the listener --- : add-listener-pane { name typ args -- wid } main-widgets 1 array-ref "lisp-listener" find-child { listener } listener FXtParent { listener-scroll } listener-scroll FXtParent { listener-form } listener-scroll FXtUnmanageChild drop args #( FXmNleftAttachment FXmATTACH_FORM FXmNrightAttachment FXmATTACH_FORM FXmNtopAttachment FXmATTACH_FORM ) array-append to args name typ listener-form args undef FXtCreateManagedWidget { top-widget } listener-scroll #( FXmNtopAttachment FXmATTACH_WIDGET FXmNtopWidget top-widget ) FXtVaSetValues drop listener-scroll FXtManageChild drop top-widget ; \ --- bring possibly-obscured dialog to top --- : raise-dialog ( dialog -- ) { w } w FWidget? if w FXtIsManaged if w FXtParent { parent } parent FWidget? if parent FxmDialogShellWidgetClass FXtIsSubclass if parent FXtGrabNone FXtPopup drop then then then then ; : activate-dialog ( dialog -- ) dup FXtIsManaged if raise-dialog else FXtManageChild drop then ; \ --- add-mark-pane --- #f value including-mark-pane hide #() value mark-list-lengths #() value mark-lists : find-mark-list { snd chn dats -- lst } #f \ flag dats each { dat } snd dat 0 array-ref = chn dat 1 array-ref = && if drop \ drop flag dat 2 array-ref leave then end-each ; : mark-list-length ( snd chn -- len ) mark-list-lengths find-mark-list dup unless drop 0 then ; : set-mark-list-length { snd chn len -- } mark-list-lengths each { dat } snd dat 0 array-ref = chn dat 1 array-ref = && if mark-list-lengths i array-delete! drop leave then end-each mark-list-lengths #( snd chn len ) array-push drop ; : mark-list ( snd chn -- lst ) mark-lists find-mark-list dup if 2 array-ref else drop #() then ; : set-mark-list { snd chn lst -- } mark-lists #( snd chn lst ) array-push drop ; : deactivate-channel { snd chn -- } snd chn mark-list-length 0> snd chn mark-list FWidget? && if snd chn mark-list #( FXmNchildren 0 ) FXtVaGetValues 1 array-ref each ( w ) FXtUnmanageChild drop end-each then ; : marks-focus-cb <{ w c i -- f }> w #( FXmNbackground white-pixel ) FXtVaSetValues ; : marks-losing-focus-cb <{ w c i -- f }> w #( FXmNbackground basic-color ) FXtVaSetValues ; : marks-activate-cb <{ w c info -- }> w #( FXmNuserData 0 ) FXtVaGetValues 1 array-ref { id } w #( FXmNvalue 0 ) FXtVaGetValues 1 array-ref { txt } txt string? txt length 0> && if txt string->number else #f then { samp } samp if id samp set-mark-sample else id delete-mark then drop w #( FXmNbackground basic-color ) FXtVaSetValues drop ; : marks-enter-cb <{ w c i f -- f }> mouse-enter-text-hook #( w ) run-hook ; : marks-leave-cb <{ w c i f -- f }> mouse-leave-text-hook #( w ) run-hook ; : make-mark-list { snd chn -- } snd chn mark-list-length { cur-len } snd chn deactivate-channel snd chn mark-list FWidget? unless snd chn "mark-box" FxmFormWidgetClass #( FXmNbackground basic-color FXmNorientation FXmVERTICAL FXmNpaneMinimum 100 FXmNbottomAttachment FXmATTACH_FORM ) add-channel-pane { mark-box } "Marks" FxmLabelWidgetClass mark-box #( FXmNbackground highlight-color FXmNleftAttachment FXmATTACH_FORM FXmNrightAttachment FXmATTACH_FORM FXmNalignment FXmALIGNMENT_CENTER FXmNtopAttachment FXmATTACH_FORM ) undef FXtCreateManagedWidget { mark-label } "mark-scroller" FxmScrolledWindowWidgetClass mark-box #( FXmNbackground basic-color FXmNscrollingPolicy FXmAUTOMATIC FXmNscrollBarDisplayPolicy FXmSTATIC FXmNleftAttachment FXmATTACH_FORM FXmNrightAttachment FXmATTACH_FORM FXmNtopAttachment FXmATTACH_WIDGET FXmNtopWidget mark-label FXmNbottomAttachment FXmATTACH_FORM ) undef FXtCreateManagedWidget { mark-scroller } "mark-list" FxmRowColumnWidgetClass mark-scroller #( FXmNorientation FXmVERTICAL FXmNtopAttachment FXmATTACH_FORM FXmNbottomAttachment FXmATTACH_FORM FXmNspacing 0 ) undef FXtCreateManagedWidget { mlist } mark-scroller set-main-color-of-widget mark-box #( FXmNpaneMinimum 1 ) FXtVaSetValues drop snd chn #( snd chn mlist ) set-mark-list then snd chn #f marks { new-marks } new-marks length cur-len > if snd chn mark-list { lst } new-marks length cur-len ?do "field" FxmTextFieldWidgetClass lst #( FXmNbackground basic-color ) undef FXtCreateWidget { tf } tf FXmNfocusCallback <'> marks-focus-cb undef FXtAddCallback drop tf FXmNlosingFocusCallback <'> marks-losing-focus-cb undef FXtAddCallback drop tf FXmNactivateCallback <'> marks-activate-cb undef FXtAddCallback drop tf FEnterWindowMask #f <'> marks-enter-cb undef FXtAddEventHandler drop tf FLeaveWindowMask #f <'> marks-leave-cb undef FXtAddEventHandler drop loop then snd chn new-marks length set-mark-list-length snd chn mark-list #( FXmNchildren 0 ) FXtVaGetValues 1 array-ref each { wid } new-marks empty? ?leave wid FXmIsTextField if wid #( FXmNvalue new-marks car undef mark-sample number->string FXmNuserData new-marks car ) FXtVaSetValues drop wid FXtManageChild drop new-marks array-shift to new-marks then end-each #f ; : remark <{ id snd chn reason -- }> snd chn make-mark-list ; : unremark <{ snd -- }> snd channels 0 ?do snd i deactivate-channel loop ; : marks-edit-cb { snd chn -- prc; self -- } 0 proc-create ( prc ) chn , snd , does> { self -- } self @ { chn } self cell+ @ { snd } snd chn mark-list FWidget? if snd chn make-mark-list then ; : open-remarks <{ snd -- }> snd channels 0 ?do snd i after-edit-hook snd i marks-edit-cb add-hook! snd i undo-hook snd i marks-edit-cb add-hook! loop ; : marks-update-proc <{ snd -- }> snd channels 0 ?do snd i make-mark-list loop ; : marks-update-cb <{ snd -- proc }> snd <'> marks-update-proc ; set-current : add-mark-pane ( -- ) #t to including-mark-pane mark-hook <'> remark add-hook! close-hook <'> unremark add-hook! after-open-hook <'> open-remarks add-hook! update-hook <'> marks-update-cb add-hook! ; previous \ --- show-disk-space, Motif specific --- hide : show-label <{ data id -- }> data 0 array-ref empty? unless data 0 array-ref { snd } data 1 array-ref { wid } data 2 array-ref { app } snd sound? if wid snd file-name disk-kspace kmg change-label then app 10000 running-word data FXtAppAddTimeOut drop then ; set-current : show-disk-space <{ snd -- }> doc" Add a label to the minibuffer area showing the current \ free space (for use with after-open-hook)." #f ( flag ) labelled-snds each { n } n 0 array-ref snd equal? if ( flag ) drop n leave then end-each { previous-label } previous-label if exit then snd sound? unless "no sound found for disk space label" snd-error drop exit then #t to showing-disk-space main-widgets 0 array-ref { app } snd sound-widgets { widgets } widgets 3 array-ref { minibuffer } widgets 6 array-ref { unite-button } widgets 9 array-ref { sync-button } minibuffer FXtParent { name-form } snd file-name disk-kspace kmg FXmStringCreateLocalized { str } minibuffer FXtUnmanageChild drop minibuffer #( FXmNrightAttachment FXmATTACH_NONE ) FXtVaSetValues drop "space" FxmLabelWidgetClass name-form #( FXmNbackground basic-color FXmNleftAttachment FXmATTACH_NONE FXmNlabelString str FXmNrightAttachment FXmATTACH_WIDGET FXmNrightWidget unite-button FXtIsManaged if unite-button else sync-button then FXmNtopAttachment FXmATTACH_FORM ) undef FXtCreateManagedWidget { new-label } minibuffer #( FXmNrightWidget new-label FXmNrightAttachment FXmATTACH_WIDGET ) FXtVaSetValues drop minibuffer FXtManageChild drop str FXmStringFree drop #( snd new-label app ) to previous-label labelled-snds previous-label array-push drop app 10000 <'> show-label previous-label FXtAppAddTimeOut drop ; previous : current-label ( widget -- label ) doc" Return WIDGET's label." ( wid ) #( FXmNlabelString 0 ) FXtVaGetValues 1 array-ref ( xmstr ) #f FXmCHARSET_TEXT FXmCHARSET_TEXT #f 0 FXmOUTPUT_ALL FXmStringUnparse ; [then] \ snd-xm.fs ends here snd-16.1/snd-gfind.c0000644000076400007640000002011312512761107012347 0ustar bilbil#include "snd.h" static GtkWidget *edit_find_dialog, *edit_find_text, *find_cancel_button, *edit_find_label, *find_next_button, *find_previous_button; static GtkWidget *find_error_frame = NULL, *find_error_label = NULL; static chan_info *find_channel = NULL; static gulong find_key_press_handler_id = 0; static void clear_find_error(void) { if ((find_error_frame) && (widget_is_active(find_error_frame))) set_label(find_error_label, ""); if (find_key_press_handler_id) { g_signal_handler_disconnect(edit_find_text, find_key_press_handler_id); find_key_press_handler_id = 0; } } static gboolean find_modify_key_press(GtkWidget *w, GdkEventKey *event, gpointer data) { clear_find_error(); return(false); } void errors_to_find_text(const char *msg, void *data) { find_dialog_set_label(msg); gtk_widget_show(find_error_frame); find_key_press_handler_id = SG_SIGNAL_CONNECT(edit_find_text, "key_press_event", find_modify_key_press, NULL); } void stop_search_if_error(const char *msg, void *data) { errors_to_find_text(msg, data); ss->stopped_explicitly = true; /* should be noticed in global_search in snd-find.c */ } static void edit_find_dismiss(GtkWidget *w, gpointer context) { if (ss->checking_explicitly) ss->stopped_explicitly = true; else { gtk_widget_hide(edit_find_dialog); clear_find_error(); } } static gint edit_find_delete(GtkWidget *w, GdkEvent *event, gpointer context) { clear_find_error(); gtk_widget_hide(edit_find_dialog); return(true); } static void edit_find_help(GtkWidget *w, gpointer context) { find_dialog_help(); } static void edit_find_find(read_direction_t direction, GtkWidget *w, gpointer context) { #if HAVE_EXTENSION_LANGUAGE find_dialog_find((char *)gtk_entry_get_text(GTK_ENTRY(edit_find_text)), direction, find_channel); #endif } void find_dialog_stop_label(bool show_stop) { if (show_stop) set_stock_button_label(find_cancel_button, I_STOP); else set_stock_button_label(find_cancel_button, I_GO_AWAY); } void find_dialog_set_label(const char *str) { if (edit_find_label) set_label(edit_find_label, str); } static void edit_find_next(GtkWidget *w, gpointer context) { edit_find_find(READ_FORWARD, w, context); } static void edit_find_previous(GtkWidget *w, gpointer context) { edit_find_find(READ_BACKWARD, w, context); } static void make_edit_find_dialog(bool managed, chan_info *cp) { if (!edit_find_dialog) { GtkWidget *dl, *rc; GtkWidget *help_button; edit_find_dialog = snd_gtk_dialog_new(); #if GTK_CHECK_VERSION(3, 14, 0) gtk_window_set_transient_for(GTK_WINDOW(edit_find_dialog), GTK_WINDOW(MAIN_SHELL(ss))); #endif SG_SIGNAL_CONNECT(edit_find_dialog, "delete_event", edit_find_delete, NULL); gtk_window_set_title(GTK_WINDOW(edit_find_dialog), I_FIND); sg_make_resizable(edit_find_dialog); gtk_container_set_border_width (GTK_CONTAINER(edit_find_dialog), 10); gtk_window_resize(GTK_WINDOW(edit_find_dialog), 350, 120); gtk_widget_realize(edit_find_dialog); find_next_button = gtk_dialog_add_button(GTK_DIALOG(edit_find_dialog), "Forward", GTK_RESPONSE_NONE); find_previous_button = gtk_dialog_add_button(GTK_DIALOG(edit_find_dialog), "Back", GTK_RESPONSE_NONE); find_cancel_button = gtk_dialog_add_button(GTK_DIALOG(edit_find_dialog), "Go Away", GTK_RESPONSE_NONE); help_button = gtk_dialog_add_button(GTK_DIALOG(edit_find_dialog), "Help", GTK_RESPONSE_NONE); gtk_widget_set_name(help_button, "dialog_button"); gtk_widget_set_name(find_cancel_button, "dialog_button"); gtk_widget_set_name(find_previous_button, "dialog_button"); gtk_widget_set_name(find_next_button, "dialog_button"); #if GTK_CHECK_VERSION(3, 0, 0) add_highlight_button_style(find_cancel_button); add_highlight_button_style(help_button); add_highlight_button_style(find_previous_button); add_highlight_button_style(find_next_button); #endif SG_SIGNAL_CONNECT(find_cancel_button, "clicked", edit_find_dismiss, NULL); SG_SIGNAL_CONNECT(help_button, "clicked", edit_find_help, NULL); SG_SIGNAL_CONNECT(find_next_button, "clicked", edit_find_next, NULL); SG_SIGNAL_CONNECT(find_previous_button, "clicked", edit_find_previous, NULL); gtk_widget_show(find_cancel_button); gtk_widget_show(find_next_button); gtk_widget_show(find_previous_button); gtk_widget_show(help_button); rc = gtk_hbox_new(false, 0); gtk_box_pack_start(GTK_BOX(DIALOG_CONTENT_AREA(edit_find_dialog)), rc, true, true, 4); gtk_widget_show(rc); dl = gtk_label_new(I_find); gtk_box_pack_start(GTK_BOX(rc), dl, false, false, 4); gtk_widget_show(dl); edit_find_text = snd_entry_new(rc, NULL, WITH_WHITE_BACKGROUND); SG_SIGNAL_CONNECT(edit_find_text, "activate", edit_find_next, NULL); edit_find_label = gtk_label_new(""); gtk_box_pack_start(GTK_BOX(DIALOG_CONTENT_AREA(edit_find_dialog)), edit_find_label, false, false, 4); gtk_widget_show(edit_find_label); find_error_frame = gtk_frame_new(NULL); gtk_box_pack_end(GTK_BOX(DIALOG_CONTENT_AREA(edit_find_dialog)), find_error_frame, false, false, 4); find_error_label = gtk_label_new(""); gtk_container_add(GTK_CONTAINER(find_error_frame), find_error_label); gtk_widget_show(find_error_label); if (managed) gtk_widget_show(edit_find_dialog); set_dialog_widget(FIND_DIALOG, edit_find_dialog); } else { if (managed) raise_dialog(edit_find_dialog); } } void edit_find_callback(GtkWidget *w, gpointer context) { make_edit_find_dialog(true, NULL); } void find_dialog(chan_info *cp) { /* used in snd-kbd.c */ make_edit_find_dialog(true, cp); } bool find_dialog_is_active(void) { return((edit_find_dialog) && (widget_is_active(edit_find_dialog))); } void save_find_dialog_state(FILE *fd) { if (find_dialog_is_active()) { char *text = NULL; text = sg_get_text(edit_find_text, 0, -1); #if HAVE_SCHEME if (text) fprintf(fd, "(%s #t \"%s\")\n", S_find_dialog, text); else { if (ss->search_expr) fprintf(fd, "(%s #t \"%s\")\n", S_find_dialog, ss->search_expr); else fprintf(fd, "(%s #t)\n", S_find_dialog); } #endif #if HAVE_RUBY if (text) fprintf(fd, "%s(true, \"%s\")\n", to_proc_name(S_find_dialog), text); else { if (ss->search_expr) fprintf(fd, "%s(true, \"%s\")\n", to_proc_name(S_find_dialog), ss->search_expr); else fprintf(fd, "%s(true)\n", to_proc_name(S_find_dialog)); } #endif #if HAVE_FORTH if (text) fprintf(fd, "#t \"%s\" %s drop\n", text, S_find_dialog); else { if (ss->search_expr) fprintf(fd, "#t \"%s\" %s drop\n", ss->search_expr, S_find_dialog); else fprintf(fd, "#t %s drop\n", S_find_dialog); } #endif if (text) g_free(text); } } static Xen g_find_dialog(Xen managed, Xen text) { #define H_find_dialog "(" S_find_dialog " :optional managed text): create and activate the Edit:Find dialog, return the dialog widget" Xen_check_type(Xen_is_boolean_or_unbound(managed), managed, 1, S_find_dialog, "a boolean"); Xen_check_type(Xen_is_string_or_unbound(text), text, 2, S_find_dialog, "a string"); make_edit_find_dialog(Xen_boolean_to_C_bool(managed), NULL); if ((edit_find_text) && (Xen_is_string(text))) gtk_entry_get_text(GTK_ENTRY(edit_find_text)); return(Xen_wrap_widget(edit_find_dialog)); } static Xen g_find_dialog_widgets(void) { if (edit_find_dialog) return(Xen_cons(Xen_wrap_widget(edit_find_dialog), Xen_cons(Xen_wrap_widget(edit_find_text), Xen_cons(Xen_wrap_widget(find_next_button), Xen_cons(Xen_wrap_widget(find_previous_button), Xen_cons(Xen_wrap_widget(find_cancel_button), Xen_empty_list)))))); return(Xen_empty_list); } Xen_wrap_2_optional_args(g_find_dialog_w, g_find_dialog) Xen_wrap_no_args(g_find_dialog_widgets_w, g_find_dialog_widgets) void g_init_gxfind(void) { Xen_define_procedure(S_find_dialog, g_find_dialog_w, 0, 2, 0, H_find_dialog); Xen_define_procedure("find-dialog-widgets", g_find_dialog_widgets_w, 0, 0, 0, "internal auto-test function"); } snd-16.1/nb.scm0000644000076400007640000001071112460216426011441 0ustar bilbil;;; provide pop-up help in the Files viewer ;;; if use-gdbm is #t, any data associated with the file in the gdbm database will also be posted ;;; the database name is defined by nb-database ;;; the function (nb file note) adds note to the info currently associated with file ;;; to remove a file's info, (unb file) ;;; to clean non-existent file references out of the database, (prune-db) (provide 'snd-nb.scm) (define use-gdbm #f) (define nb-database "nb.db") (define nb (let ((documentation "(nb file note) adds 'note' to the info asociated with 'file'")) (lambda (file note) (let ((ptr (gdbm-open nb-database 'create))) (if (gdbm? ptr) (let ((current-note (and (gdbm-exists? ptr file) (gdbm-fetch ptr file)))) (gdbm-store! ptr file (if (string? current-note) (string-append note (string #\newline) current-note) note) 'replace) (gdbm-close! ptr))))))) (define unb (let ((documentation "(unb file) removes file's info from the nb (gdbm) data base")) (lambda (file) (let ((ptr (gdbm-open nb-database 'write))) (if (gdbm? ptr) (begin (gdbm-delete! ptr file) (gdbm-close! ptr))))))) (define prune-db (let ((documentation "(prune-db) cleans up the nb (gdbm) data base by removing references to non-existent files")) (lambda () (define (collect-files ptr key files) (if key (collect-files ptr (gdbm-next-key ptr key) (cons key files)) files)) (define (prune-file ptr files) (if (pair? files) (begin (if (not (file-exists? (car files))) (begin (snd-print (format #f "pruning ~A" (car files))) (gdbm-delete! ptr (car files)))) (prune-file ptr (cdr files))))) (let ((ptr (gdbm-open nb-database 'read))) (if (gdbm? ptr) (let ((files (collect-files ptr (gdbm-first-key ptr) ()))) (gdbm-close! ptr) (if (pair? files) (let ((ptr (gdbm-open nb-database 'write))) (prune-file ptr files) (gdbm-close! ptr))))))))) (define nb-mouse-response-time 0) (define files-popup-info (let ((documentation "(files-popup-info type position name) is intended as a mouse-enter-label hook function. It causes a description of the file to popup when the mouse crosses the filename")) (lambda (type position name) (define file-info (lambda (file) ;; (file-info file) -> description (as a string) of file (format #f "~A: ~% chans: ~D, srate: ~D, len: ~A~% ~A ~A~A~% written: ~A~A~A" file (channels file) (srate file) (let ((den (* (channels file) (srate file)))) (if (> den 0) (format #f "~1,3F" (* 1.0 (/ (mus-sound-samples file) den))) "unknown")) (mus-header-type-name (mus-sound-header-type file)) (mus-sample-type-name (mus-sound-sample-type file)) (if (mus-sound-maxamp-exists? file) (format #f "~% maxamp: ~A" (mus-sound-maxamp file)) "") (strftime "%d-%b %H:%M %Z" (localtime (mus-sound-write-date file))) (let ((comment (mus-sound-comment file))) (if (and (string? comment) (> (length comment) 0)) (format #f "~% comment: ~A" comment) "")) (if (and use-gdbm (file-exists? nb-database)) (let* ((ptr (gdbm-open nb-database 'read)) (note (gdbm-fetch ptr file))) (gdbm-close! ptr) (if (string? note) (format #f "~%~A" note) "")) "")))) (let ((region-viewer 2)) (set! nb-mouse-response-time (get-internal-real-time)) (if (not (= type region-viewer)) (let ((info-exists (list-ref (dialog-widgets) 15))) (info-dialog name (file-info name)) (let ((info-widget (list-ref (dialog-widgets) 15))) (if (and info-widget (not info-exists)) ; keep the help dialog from overlapping the files dialog (let* ((files-dialog (list-ref (dialog-widgets) 5)) (files-position (widget-position files-dialog)) (files-size (widget-size files-dialog))) (set! (widget-position info-widget) (list (+ (car files-position) (car files-size) 10) (+ (cadr files-position) 10)))))))))))) (define (files-popdown-info type position name) (let ((cur-time (get-internal-real-time))) (in 1000 (lambda () (if (> cur-time nb-mouse-response-time) (hide-widget (list-ref (dialog-widgets) 15))))))) (hook-push mouse-enter-label-hook (lambda (hook) (files-popup-info (hook 'type) (hook 'position) (hook 'label)))) (hook-push mouse-leave-label-hook (lambda (hook) (files-popdown-info (hook 'type) (hook 'position) (hook 'label)))) snd-16.1/moog.scm0000644000076400007640000001641512446652237012022 0ustar bilbil;;; Moog style four pole lowpass filter clm unit generator ;;; low pass, 24db/Oct, variable resonance, warm, analog sound ;-) ;;; [all this digital wizardry and we're back where we started!] ;;; ;;; original C instrument by Tim Stilson ;;; translation into clm and tuning by ;;; Fernando Lopez-Lezcano, nando@ccrma.stanford.edu ;;; http://ccrma.stanford.edu/~nando/clm/moog ;;; ;;; translated to Snd scheme function by Bill, ;;; changed 21-Sep-10 to use defgenerator (provide 'snd-moog.scm) (if (provided? 'snd) (require snd-ws.scm) (require sndlib-ws.scm)) (define moog-gaintable (float-vector 0.999969 0.990082 0.980347 0.970764 0.961304 0.951996 0.94281 0.933777 0.924866 0.916077 0.90741 0.898865 0.890442 0.882141 0.873962 0.865906 0.857941 0.850067 0.842346 0.834686 0.827148 0.819733 0.812378 0.805145 0.798004 0.790955 0.783997 0.77713 0.770355 0.763672 0.75708 0.75058 0.744141 0.737793 0.731537 0.725342 0.719238 0.713196 0.707245 0.701355 0.695557 0.689819 0.684174 0.678558 0.673035 0.667572 0.66217 0.65686 0.651581 0.646393 0.641235 0.636169 0.631134 0.62619 0.621277 0.616425 0.611633 0.606903 0.602234 0.597626 0.593048 0.588531 0.584045 0.579651 0.575287 0.570953 0.566681 0.562469 0.558289 0.554169 0.550079 0.546051 0.542053 0.538116 0.53421 0.530334 0.52652 0.522736 0.518982 0.515289 0.511627 0.507996 0.504425 0.500885 0.497375 0.493896 0.490448 0.487061 0.483704 0.480377 0.477081 0.473816 0.470581 0.467377 0.464203 0.46109 0.457977 0.454926 0.451874 0.448883 0.445892 0.442932 0.440033 0.437134 0.434265 0.431427 0.428619 0.425842 0.423096 0.42038 0.417664 0.415009 0.412354 0.409729 0.407135 0.404572 0.402008 0.399506 0.397003 0.394501 0.392059 0.389618 0.387207 0.384827 0.382477 0.380127 0.377808 0.375488 0.37323 0.370972 0.368713 0.366516 0.364319 0.362122 0.359985 0.357849 0.355713 0.353607 0.351532 0.349457 0.347412 0.345398 0.343384 0.34137 0.339417 0.337463 0.33551 0.333588 0.331665 0.329773 0.327911 0.32605 0.324188 0.322357 0.320557 0.318756 0.316986 0.315216 0.313446 0.311707 0.309998 0.308289 0.30658 0.304901 0.303223 0.301575 0.299927 0.298309 0.296692 0.295074 0.293488 0.291931 0.290375 0.288818 0.287262 0.285736 0.284241 0.282715 0.28125 0.279755 0.27829 0.276825 0.275391 0.273956 0.272552 0.271118 0.269745 0.268341 0.266968 0.265594 0.264252 0.262909 0.261566 0.260223 0.258911 0.257599 0.256317 0.255035 0.25375)) (define moog-freqtable '(0 -1 0.03311111 -0.9 0.06457143 -0.8 0.0960272 -0.7 0.127483 -0.6 0.1605941 -0.5 0.1920544 -0.4 0.22682086 -0.3 0.2615873 -0.2 0.29801363 -0.1 0.33278003 -0.0 0.37086168 0.1 0.40893877 0.2 0.4536417 0.3 0.5 0.4 0.5463583 0.5 0.5943719 0.6 0.6556281 0.7 0.72185487 0.8 0.8096009 0.9 0.87913835 0.95 0.9933787 1 1 1)) ;;; moog struct is a list (freq res arr a) ;;; freq: cutoff frequency in Hertz ;;; Q: resonance, 0->no resonance, 1->oscilates at freq ;;; ;;; Note: the relation between freq and the actual cutoff is not exactly linear but ;;; I prefered to translate Hz into the internal parameter rather than controlling ;;; the cutoff frequency in terms of a number that goes between -1 and 1. #| (defgenerator moog freq Q s y fc gain sig) (define make-moog-filter (let ((documentation "(make-moog-filter frequency Q) makes a new moog-filter generator. 'frequency' is the cutoff in Hz, 'Q' sets the resonance: 0 = no resonance, 1: oscillates at 'frequency'")) (lambda (frequency Q) (let ((frq (envelope-interp (/ frequency (* *clm-srate* 0.5)) moog-freqtable))) (make-moog :freq frequency :Q Q :s (make-float-vector 4) :y 0.0 :fc frq :gain (* Q (array-interp moog-gaintable (+ 99.0 (* frq 99.0))))))))) (define moog-frequency (dilambda (let ((documentation "(moog-frequency gen) accesses the cutoff frequency of the Moog filter 'gen'")) (lambda (gen) (gen 'freq))) (lambda (gen frq) (let ((fr (envelope-interp (/ frq (* *clm-srate* 0.5)) moog-freqtable))) (set! (gen 'freq) frq) (set! (gen 'fc) fr) (set! (gen 'gain) (* (gen 'Q) (array-interp moog-gaintable (+ 99.0 (* fr 99.0))))))))) (define moog-filter (let ((documentation "(moog-filter m sig) is the generator associated with make-moog-filter")) (lambda (m sig) (let-set! m 'sig sig) (with-let m (let ((A (* 0.25 (- sig y))) (st 0.0)) (do ((cell 0 (+ 1 cell))) ((= cell 4)) (set! st (float-vector-ref s cell)) (set! A (min 0.95 (max -0.95 (+ A (* fc (- A st)))))) (float-vector-set! s cell A) (set! A (min 0.95 (max -0.95 (+ A st))))) (set! y (* A gain)) A))))) ;;; (let ((gen (make-moog-filter 500.0 .1))) (map-channel (lambda (y) (moog-filter gen y)))) |# ;;; faster version? (defgenerator moog freq Q s0 s1 s2 s3 y fc gain sig) (define make-moog-filter (let ((documentation "(make-moog-filter frequency Q) makes a new moog-filter generator. 'frequency' is the cutoff in Hz, 'Q' sets the resonance: 0 = no resonance, 1: oscillates at 'frequency'")) (lambda (frequency Q) (let ((frq (envelope-interp (/ frequency (* *clm-srate* 0.5)) moog-freqtable))) (make-moog :freq frequency :Q Q :y 0.0 :s0 0.0 :s1 0.0 :s2 0.0 :s3 0.0 :fc frq :gain (* Q (array-interp moog-gaintable (+ 99.0 (* frq 99.0))))))))) (define moog-frequency (dilambda (let ((documentation "(moog-frequency gen) accesses the cutoff frequency of the Moog filter 'gen'")) (lambda (gen) (gen 'freq))) (lambda (gen frq) (let ((fr (envelope-interp (/ frq (* *clm-srate* 0.5)) moog-freqtable))) (set! (gen 'freq) frq) (set! (gen 'fc) fr) (set! (gen 'gain) (* (gen 'Q) (array-interp moog-gaintable (+ 99.0 (* fr 99.0))))))))) (define moog-filter (let ((documentation "(moog-filter m sig) is the generator associated with make-moog-filter")) (lambda (m sig) ; see below for the "saturate" option (let-set! m 'sig sig) (with-let m (let ((A (* 0.25 (- sig y))) (st 0.0)) (set! st s0) (set! s0 (+ A (* fc (- A st)))) (set! A (+ s0 st)) (set! st s1) (set! s1 (+ A (* fc (- A st)))) (set! A (+ s1 st)) (set! st s2) (set! s2 (+ A (* fc (- A st)))) (set! A (+ s2 st)) (set! st s3) (set! s3 (+ A (* fc (- A st)))) (set! A (+ s3 st)) (set! y (* A gain)) A))))) (define moog-filter-saturated (let ((documentation "(moog-filter-saturated m sig) is the generator associated with make-moog-filter with internal saturation")) (lambda (m sig) (let-set! m 'sig sig) (with-let m (let ((A (* 0.25 (- sig y))) (st 0.0)) (set! st s0) (set! s0 (min 0.95 (max -0.95 (+ A (* fc (- A st)))))) (set! A (min 0.95 (max -0.95 (+ s0 st)))) (set! st s1) (set! s1 (min 0.95 (max -0.95 (+ A (* fc (- A st)))))) (set! A (min 0.95 (max -0.95 (+ s1 st)))) (set! st s2) (set! s2 (min 0.95 (max -0.95 (+ A (* fc (- A st)))))) (set! A (min 0.95 (max -0.95 (+ s2 st)))) (set! st s3) (set! s3 (min 0.95 (max -0.95 (+ A (* fc (- A st)))))) (set! A (min 0.95 (max -0.95 (+ s3 st)))) (set! y (* A gain)) A))))) snd-16.1/pix/0000755000076400007640000000000012211442433011127 5ustar bilbilsnd-16.1/pix/envs.png0000644000076400007640000013430311147553266012632 0ustar bilbil‰PNG  IHDRÁ0öÖMNgAMA± üa­PLTEN6N‚N 2¢b®®¦ÂÆÎ†ÞŠþÊâþîîâòúþ’–š’Ö¢úúòrrj–Ö¦RŠ¢úþú²6&FJÒúÒ"®>vvnööÞF’Š*FNêêæÊʾ&ªJz~zþþòB–‚ÊÊÆ’ÚžÊÎÊ&ªNšš’:švFFB ¾*¦VºŠŠ‚*ªRŠÚ–Îζ*NŽš²:>šz6žj¾N:F–ŠJjV¶26žn.¦^"®F:žnº*&®F2¦^.¦V~~~’î’þþþ6¢jR*"N>ÎÎÎ ÂJŽ–‚₎ښ>š~2¢fR2²>*ªNJ’Ž:žrÆŠÞ’º"Bš~*ªV6¢f"JBV*"²>¶."JF:žvº&²6B–††âо>švº&¶.&JFF–†J’’¶6.¦Z&®JNŽž¾J’– ÂÆ’Ö¦N>‚↎ڞ"NBRŽž2¦bÂF’ŽNŽ– ÂBš‚†ÞŽR6R.ŠÞ–&FNN6ŽÚ–†â†ŠÞŽR."®B–Öª&JJÆ *FRRŽ¢¾ÕPß bKGDˆH pHYs  ÒÝ~ütIMEÑ ( ßlÊ IDATxœì½‰“Çu&^¤AzœÍ j¢¨n’èÀ%hà ZZ€dŠMýÆd‚„ ¶(ƒBˆË]´é°b7dØ:‚Å"Úý›yç{/_f]ÕÇL~=Ó]•÷ñå—/³ª««ª `¿19<<$ÿ‹‡ÀŸ«úÛ ~›ÂŸÿÕÞá¿t…¿ñð¯Cà¿®úà’dðË—"\øð¿Eø³ø7èìþRa¾Ñ¿üë¿þ¥Æ7 þ΂we¼<>þøão5âÓ?ÿùÏoݺu¾ÞBx…â|üzf^¯ —Ç}rGÊèÏ8Ü1x-Ë ®¯‰sèuý‡«“x]2øðÅŨɋ¯³“c2CÂ?óÜú7õ2Ö!Éп6Hû)Š~ƒeØ7iáèˆñwmG°$Lñ1ÉÔ[,'ñ óyËိ÷5ÞR¬txæÒ¸o^÷ï? /Ǿgæ({Ç;ZjÞyöšzçIzù²=¸sQ™c,¥mä÷ZDÒwž¼{ý¦ð¹ß¯.ýcÑì°xÝhð‹/ âeyŽŒäñÏ$óo•Ç¿üËß2Tü%æ«£æ7¿ùo*v~ãï” :IutÔ|Õ¬unf"ŠÆ´äDú1‚É °Ñœ.qëó[·Ô§¦¨åèçÚãÖyÄO'«¯8jžë¾eëýHb_Qúy_sõ>G‡gž–oòÐÓeèËòï5ù~ÙF¸Ì”£%§›7CŸ8‚J@—'ïÔPTt„T$”L•||b*z]ÓS ìßh ·o_?÷ÎuÃbƒ{ DŽïI×I F†ÄZ8h >\\šOÝëp2™_zý·Š“ÿñ· ÿñž±+3Ï;Óó›ß\)é4üÔonš—rúÍ_Êwõ§‰º3¿;F=? ªù·¢Òé}‰xê™þSïò)¯¦P85/=Uo}z+PÔLðêü-3akŠ:ØÃW^ùÅ[ZßRÚéõþý>úH¹hcTÎî÷ 9µÉizÇM÷wÜoÎèô}GóÑ2ÕŠ¥šš!1_3ô´ ý1'£†‰Š·ŽŸš£ k=o<|x]Mð†z×ßÑÊ©yxÝÐÒi©þ%ßq€¢„œ÷Þ6o+ÈypϽÞûíß)…](¶æä™ÖàÉ¥Õà×+ ©'wõúë6“»$ìßIýnÝôË_®ÔDo¦ym’Úiß)§²Fͱ⦥£:|óQóW~® È~ï¿áä§|?¹k–žÿLôŸž*âº%’⥑Ö_h®:U2ªª>-Eï;%}ËÏôÊUñRÍóçõÿ¼×M;½‡Se˜Š:rYu‡Ê5´¡ˆ~ÞP/¨r*¿®^’¯kÑ4oÊORQN?y¢|¥†¾+ ª&î뚤¡Öþ4ìTÓº¢£c¯<|¢„0óœ“V$¢êPþ½zNñÓ±Õòõm{pûöÛoÿýß¿/{ûýÛoß»}O~Ü~p[á9ÅO °‹ÇKçðƒJ{W?PFƒ/½¸Ðâ{hExþâë¿U:úË—Wrrù›+¥ òý—êÓZ¡/¯Vòxõ±úвªøùòËFE¿%$-_þXÈ÷ï­¼¬~O‘qeh©‚ëPêôå—³Ìóç¿%Wñ~ÆÿÜÍìš ·¬t~zËS÷óóÆÿ¾ú{˰VÍäçï›EÐWλ^Û£VPÕ¬®B™»O».zÅ(¨_%á’gã37ó³ U²) Q?Ù›EO4Ñß„¼ìxê-No~>|hèúD ª>~×WÎïúÿúÍO9«kK©‹ïž;çÔp10ôóZ ÉJæ{MSELãú÷ž£ŽNZIïÝ»ípïöÛ·1¾ûÝÛš²®Þ¾}U½<ÇW¿ûàÁ·±ÂžœXÉõ 6'Òa¡\MmÏ#;øõß*Í\iÁTsþJ«èje'z©–ß³~ßúxådõ[’€êCŠèJ|ú=ÉLIÝï­¾÷éJ:dÔ2uuëÓÕùOWŸž_}þùjuëÖϽ°z[ôS?á%§R=áéJ<õRé¼QeS<ûH~t_/’$9ê9ªÙ–óNHMúà)0Jï¼÷j¾—Œüâò—ï$ñŠŸž7‚ÍùP‘Ó0U¾?|hÕóáC7Ó_7 zÝžOÔHž»®QmtZZýõ¯mÄòÉ9çˆ%4Ìïèäm'£žøð}CNyø¾£¨t0Çßõ$}ðÀ;\5.<¸úHº«O IÛG®>úäÑÕ«7¯>ïW¿5xqB4Ø:\R–Ž—t»±À|i~á·v¾Wlüø¿¬‰ú-õagyÅACÎï)šV®¤$®,E¥Íùéêçç5E¥¢®¬%zK*çç+9ËKý|%uôsõ~~%ÏëÃÏo™Å½™éå,þ¾·I_9ïÖðçíz^Ññþ+ç?’r­tÿ£;PBÕžÓ+Ï1Í_Ùëÿ@L¸n¢Ÿj‚7ÆçzmÏB+è ÍPeˆ>4 U3»ËZF-Qõrèºc©"ç»’¨f‰þä‰e«™Øßµ&èu5ë¿£dÓÎýæäoÎÔ‹(œãƒ–6º ÞÞvTÕÓ¼¡«"ê½·¡‚ZbÞ¶úà¤èÕ«$K)j‚>RT”Ô|d4Aoª#ÉÓ«Ÿ|róÑ£›òÜüró{tóæÝ»Wÿ7Ò`Ç`©¶ÆÁ1Xú(Yv!4ƒ_$,ÏÿJ-޾%%ö{Ÿ:zþüÓŸ¯ô¬íTT çùŸŸW·>×AÔ´þù-%§·V’®«[ç5E•Ùi•tõù[zšëüJ9¯ÞÒÿ«_¼òÊÊØ£f¦×BzÞ¦ý”³ºæìý°VÂ[NÏîËô5?Ñ? SzÌQ+¤_8õ´“=^%IF^¾ñã†×íPL•Ðļz÷îÍ«†¢WoÞ•o/º^Tw/ÞUoÒQ¾_ü¤ÁΊl‚¡eÙ†°<h°Þþ«O?ý¹ÔLÉÛ[ZYÏK*~úùêS»m/ϤjjŽ~®õóŸ¯ÞÒ2j-PÉSIJERKQ5ÿ¥·BW¯è¥½QÑÕ+÷WrŽ×oÝ_ÉEÒGÖUkåÔQ3ì8Yšb>óF¨§§fëå×Mõ©þ•Œ^¾Áˆè/ÿX£J5õûÇîLÑÕl:=4k%3Í?±2ªWKjAÝì6²ž;wÝ.™Â‡¥å¯ÏiÏ¿9g ROSBPw¨ø©VóoË%“¡ä=³š·}?ˆ¨:°Œ|û}ÃÏï*kTZšO¿ûàªÔGêH«çmOKCREËO4)5 ]uº*ÅSâîM)ªW†ÞÔ½yS2ôî]ÅÇ«êã7òì7¿ÑT•Sï^ÔŸ%y/Þµ‡«¤Á'‹”k V†DØ‹xyA4xqéÂ_׳ü犺z–W*ºZ½elÑ_œ_I;T»œ×RTW祄JÕë£ÕýW$Qå»â§ú[©M§óJCeÇÌ•ü»¯Þõѳ;«Õ3ÇU7Ï£Í&-¡Ñ$¯wô/+Â~a¦{g‹F&©”Õßø±á¨5FÍ Þm-iŽÊ÷wåû»VGµ†j·ë×ýün×JÞµ+¤svÊ¢OÞùõ;ž˜ŽŸï@r¢]§{f=ÿ6œò!/%ÕÛ=3»¿ý¾â¦Ÿå߆"j(jEô¶šèå ¯§üG†¢rÖ×ZúH“ñ‘蕌j U„¼ªÈø©¤ô¢dèÝ›o^T*ß´¤*•c¸y÷îOÍÇÅxlÈúøñÅÇßyüøÕÇÁÛ?’­‡„/N”I¬(4xqiá7ƒ£ÿêêr¨$¨¢¦šâßRüU‚jñ’“Z4å§²DåÙ+ÆQž­^ùè™ô}v_ÿ?S'­$×Vf5¯m;Ï´Ëêµgß×úä‹Õ÷ïàùÝ/ÌÓJ@ ACPÒöØÓS¯ãoØyþ²1J E/« P)©O”’ªP½á¤ETqTïŠ>±“¾]Ûÿ'– jž?g¶DŸh5µ´4+ü{Ñ"É1ôžZΟ»çXjèiMPÉÎ÷’Z[ô¶ú0ÓýûïãýýïUTMè^Doc5¨ú¸yU±÷éñÉ'ZBoš¹ýª}“ò)izñâ'w•’ÞÔ3üE¥¢W5=ïþô§ cC[½ë˜éiúXqÔÂPT¿Ç裧Ÿª?yöT¾ÿ¼õ4˜8ü@ʯâ$÷ƒ_”VÄÿ’´4k%µŽ7ÇikT-ëõ5¥¤T~¤ÿä*Ìñp÷^ £ääïë+L¯­´†~ÿ5»nzí‹ï!'t¥œr¯ó¯}á.x‚'8Ý_w ½lvço˜½ú‡êï†1;õzé]³¶½¾àyÝ^ÕtûMò][¢zKôónØ*Õ‚ÞQóÉ;P;ïÙYßì,AŽ*v¾í¶A1EÝN“Y7Ývö¨¶FïAf[T®”Ô¼®H©\¾«„ô‘VI%¡WŠz>ò"zSSôMQGSc‘Þ¼*MÐO”ª¦{e‡*£ô7ò]ÎðW-+å¤תæ]CS¥³nž4’S}\4ÜÔL}Uâ;ß‘}U>~õé«O+’>}õñSuöÙgO?“ï?Ñ?ùì©Õ`²›;\Ò‹8õwöƒ/ù}i.^|ý¿È¥}¸—é¾›Ùájþ¸cÄMñß¿ã¯sš}•IëæÕeEÔËîßj(TQ Dóúõß0v¨ú—GFT/Z >4´}Wo“š+ój9ï–Lz¾WZùÄÚ ÆÕ²yîú¯ÝjéwÈ{X…÷{÷Ì¥&m|žó»]$i“ôm}mIë%ÒûŠ›ï+³ô}¿Vò,} 4ôÞUk%u¦6E¯êÉ^±QqT[žèYÝZ¡Š–Ÿ<òô”'Ú7ˆ¨±C5IÙi>´ŽÞýé];±†Þ}ÄÍôRC_õÚ5]CÍéSyôô;=3¿ãhªúÔ°ô3ÅÑÏž~ðôé—ŸI| þŸÊ¿/åÑ—|ðå—Ÿ}ðÁàVr~ë!vÐV2¸&÷òüº7MÝñ¿4QœzJ:º{Ôž˜¦×.¡vE/¿ö…¹zùr¸<Ã,楆JvªÕÒes™éÆåë%¼y{èdÓˆ©µJÕTÿÄîÙë Kš¨FG•*ÿ¯›þú9·œ·Núè´Ž·nÌrÞ\Zò«xut²TÏô·í…P‰÷ß׳½¤æ=·œàÔ)êU-£Wõß…G·µt~ê#)«>ÑÄÔ;OJMµÃ'7ˆÊ÷»fÕdpѼK5«yù!Y Eô.Ѱvº‹è©Dôj^¾ÄTþÇj¨æ«;RúWŸýŽÔSÍÓ§NE?sÇ?ùÉO$'Ÿ>ý@rS“ô©b¦â§¤§!ég_þû _šÿ/ß”ïo¾ùå¿K×7ßüJòóÝy& îÞ´…Ó`ý.­ˆ…7äݱ—ê_³Ò©µôŽ¡©Úe:ªÙi ôf½²El.0éÿ‡ÊæT–èu³õð݇VC5;ýá“sz¦¿þä°X:gÍÏ_[J>9÷7p¥äfú{è“ßÕ;Nà¢gQ-ŸêH‰¦¹®¤5ÔnêÝ¥0Ëk9•ºyU_[’Ëy=³«%Óm³bz¶šÌF”\ßë¹ÿ“«7ý~¨]Ì_¼zÓ,ã-Iª$S/祫áèo?+ïB}ì¦{ÉÐÿiˆx10ô±Nù÷Wå™úP”|UÛ¢RJ ??ûÌðSQñ3KPufDôƒŸ8†ª×g’œ(rj-•|üÒòóÍ/5Y%i%Msß|óMõoñOêí/Õÿ?|}u² ·¯Ÿœ4:h;xAopñõ5‹÷ƒùÝõÇæN'uQé²¡ç ½Õ¤WK†’Æ5ëyu _†¬jaô®ºÏî‰1I-KŸØ+šo_÷«%d“B s½Ý­÷ëy?Ñ¿ïäÔ^ ×äT\½ç®~~J¨šóøSÍHs Ôl†êS½lúÄh£Trñ‘\*}òè+¡7ý,¯%ô®^&]5k%5Ý_Tú©„ô¢žøKêUT¿=ÖG#5*ª%R‰¨œé“–N­œ E¿ó™›äƒœþä'O¢5ô©¡®$ç—JQ¿ô2ú™¢«q0Õ¯ÿwùöÁ›Š§ÿd(ú¦é_J‚þå?½©ÞäÿÿÕ\•nÈíeß$¾ês‡»ÑàùbqáÂë^]¿«Ï×ÿëÏ~ø³þð‡?Sø¡9þ¡>üÙïøûŸýð÷¿ÿÙï/~ø3ï'Ýô»ôÖn*ˆ:Óøáï$_¿ÿýÿQ'?²'æ à¹çì›ûWø?*ÔsîT~üÈûÊÿ=÷»çžûÑ”ÿs¿—‡¿û‘>uÎÏ}ûÛÏ)üNùÿçs¿ûÝ·¿ý;Êÿÿ§ ñ+ò9õÿíÿ”'¿RŽßþö¯ä›<±P¤Ã?Hùö«o›#u"Ïä¿>—‡òXýë·_ýoéñÚEA~þæÿ~þÍÛsæÀ;˜ÿ”/ ÷a >Õ‰ÿûǯýƒý×oÒáêMŸ™#ýùÇ?~íkÊUŸM|ͺþñ¿öÕ?þñ+yò•úüꫯ}¥|¿öÕWÒSúJýË“¯´ƒqüJ¹|íëòí«¯Ë×Wú“|—o_i'yþÕ×ÿôusüus®ßí‡ùûpùÓŸN^»qéRUP°°¼R ž_šÏ/-åûr® 6eç•Õ`Íàå|¹T‰èÏeAÁ¦qI*h7\ñ|r¢üFAÁ>áÊK^ƒÕEçùrÛ*(è„+Xƒ ƒ ö @ƒ/I .VDÁžhð%e .Ø/P;¸hpÁ~¡hpÁ~£hpÁ~£hpÁ~#«Áö²³9ôNùA} #'ã´J2JúµM¥`÷èàÒ=šÕ`6V+6&Nq™"7‚‹Sx{*ÀÒ!ÍଧÓoÈ>qZ\ÐŒŽ n§ÁÔ.HOâ(N¥O]À*9ñW.bU‘ä“äöÕ.(0y¢T€W11v¡ÏAo9Ǩÿší`”ì˜S³oEï4r &JõF—½²–ú^ãì½òýˆè‚Žä³bò žLFÚ3J>J%eEÔè >ÛÎ?].ÊÔ[\g[ r_DÝd<ôÔÚÔðü”cgkÙ²`Lgoネ>ÉÅ)&Áþ£58oåÞ´!¥ ?ƒk|½×o03pp‡>4h8ï1u³ÉåÂãÜpö LuÉ[¦øˆÉ‡Íúòm‹Ž\y¤“¤†L›8Q±ÚÄ¡¶R|¸S]Ë5-¡Bû¶ïÖKƒÎô5<¢&;„»¥švaŒê7⣮]kð  È Dç˜Ã#’‚–½Niœä0èP¦öA£Ü˜™HŸ©K«€ÇnµîÕD ÒÞÜ<,{ù©,îÍ$5¸5Ofà×0­2‰LÞ|Ül£r° ãÔ™‰‡ñT €3ðJ4\¬i'{lxl"›xz«S]+V²ÿaR}›Ê*3é×ôŒçè8fJKÏÕ?QŠ4Q‰#Ÿ_K„àÃhp·ì¡¦Œ˜M§¤f˦ xUïY¸V1'‘´$Ó£¥l™qžµôœj3vå};`ݽˆ®y÷)ëÐê §ç´†æreå’í¤¨/ùnÎè/3_‡H5拜ÎøbvEá6j]޵ a ^·}”fh2ƒDzQ†ãÉ#Q–Ø™öZMªƒ»¿~#Êæ›nì¬NRæÄ/p|B ¥¥ÙEœ*X÷žÅjið•‚‚ýÖàm—¦  #°‹‚‚}ÂLþ# Þv :£hpÁ~£hpÁ~£hpÁ~£hpÁ~ƒÑà7äÿqݯæ.CuÙŠÞ=ð«r×d©_=L%3  ëq^5tO]sl“O2z¶‘Z|8xS nÅ`1pi º"Òà¥eðÔ£ ƒWêoÕ± ÝcØH=¢ì>ºukRƒ=ŸâÄ‘‡aðJÿ¯2xcåɶòÌËG1ÑH]V-"e ÑÜ6L€ÜPáüV«N£+.4!hZà»zƒ¾ºfO³jе)8ïÕ¦}t>Ö`kϦÓ÷>T¯ç ƒçžÀêRHoB ¬¿§a¬«¹;—ï/¼0ò_1¸¿& ‚œ;Ï®]»páÂr®Þ-ƒ,ƒ·]ü3†jÛØ9´Ö`Í]ÏàÙL¿q¬a]ìWO7R­}DÔ2lK–ŒÚ‹°ü¡×àùüØ| Óäªí ìR: ˜®«¨%‹0h¯ÁË¥g°"°z\wÎ¥4mš¸% ƒy$ìà™Ôàç-´K >>ÖŸ’»Gƒ1¸tˆF5 j· bÃEÛqäìàç=ƒE`°Þ‹¸ò‚BÇ­_:Ä¡hpO$ìà™P”íUe©Árg·ƒõ^Daðà( î‡v÷E\»¶¼6ƒ™Æ/âÐÌà²Á"µ löƒ/]8ºP<Z0˜Ûa;óh«Áò †{@UE\¸Æ/=âà"j7¨´W„Ô~0£Ám Ú¸ªˆKapÐÄÚ …+’CkpWwBapŒvpaðÖQÅÇgÙg5¸|T¼ 8‹ nÚIÛÁ³¢Á;‡Š]ßj4í‚;x¯Pƒ±ƒgu±ƒwöFÕmcƒh¼¤­\Ü#ÔíÌ1¸ÅýL齈b¯‰aw¾Ð–ñ€éî0tu‹¼5Œ±mpvXÛy/¢ì„1]¹Ë›§esÕm°ƒ‹÷Fap/°ÓsŠÜù²ÉàSJ᤽©n±ƒû£a¥VÜ 9kw÷ìàÓ𵯦•Ú¨ >en"B_ >óûÁë0t”ÛÓÈà62ÖOƒ‹œ5š:2ƒO …ÛN½÷ƒÏô^DÞLhÅà¡yvªÜņìuMî¬ï7P´‰¡…ÁYt\õ¾/âtkp¾ó nÚ˜¥þÃÔx)Üc_î‹`ó^­a†²=ƒþÃnÿÜwû)é,ïÁàÀÔª›? æÚ? ¯±yšŽxvíàv†,¥"ñ ©$®ä'ü»#Þ>ß/¯¹÷ßOƒ÷ÀÎÅo¸dRå "ÚÄ`ÜÆÃ3˜)ÅþPxý+W}4x÷íà*ûå󼆎ÅMqÙ ¿%cŸ]tá5•Æ>ì'['YæFé„·ÑϘbпŠýqtä‚Oxÿžèp×áN`ÀÛ’élÝÎïh9úqà"‰9¸lÏ00Èkš‚ £Wøðl2xØ›^zið†î‹¨l]ã2V8`³²L‰({Î$¤(ãO‡uÃAÇbðîRxø{¶zhpÚžY eE8 %#F_®ó˜lƒ$ÊZÒ™9 zÆ<·‰4{íkú²¿BнX8h XÓVÒX îá‚øå¶´5¿+ï†ÙT²}ìàÙl¹äG£{±R´bËÛàßtŪ'Ç>¥‚m»Íàqo÷î£Á©ýàñÜpÿkG8¶&Cw‘Á»CáÑ¿¬Ð]ƒsvpê·Œº‹vë×¢ckR°0¸6ó]>‹ÎûÁ‹ì¯qu/UÜ%ñ¢Œ©E*³mÀÄ{lÁÛ§ðƾ)–ÈfëûÁœS¦IòmËà5ý›~f¼Ñ/:¤Á›¸&—k­ÐM7;4ü41xkÞø×t÷Fƒc4¼¿²ƒ;ØÑ=¼Oi+ ÞÊ—ÌÙ,;ï/¶Íà¦ý[Ú{m†¯k¤ôFç)k lí |®y >Ü= nL1Û¥í<²ÒÛgð6ŸðÑQƒWckðXO<É'™ÝéØOoŒÂÛ~@ÍZ¼Xœh,v^ƒús¯mf÷Ƽ WâJÐÖ>Y\Ûu;¸9Ç5¬Œ5¼>ÕÍ5v#n[|ØB´Öàc…¦_ï^¦Í3x¯Ø¯¹ÜKï {ÖÑàÓÃà<Öcp[†÷Ʀ¼CìUXKƒO®œr¯ª|‘†ÑèÞh¾_d8ì’ø:0j»±°¾öâ)gp‹…àY`ð²W+T—ýࣣ£Ýßmö26ÏàA)¼‹âkÑIƒOÿ3{z!ÏàÞ}ï0{ÖÕàÂàU›Ý¸ÆÍº52op¬vÖt€ˆ Øëþà³ÍàÆ•Þ^2xÇÅ×)c^ƒwðÞ´íc; nº¿NCî{ºhðŠ×àÂà,ò6ÆÚR9ƒ÷D|-Šކ Çà>Iï{5¢òîäw4ö õÙ!ï{â2 Þ,Ö«o‹ï§´Lg_~} >ó{kb¼·ìU(¼u¬Uáæ»÷Ø÷§Å|/‚y”´qáwƒö½=»c{ Þö*DUXƒãýPìRœ@rä·|"]ÒßS´×à^ZŽ( IDAT{ñ-Ø%jÅÓÒ®ë¢iä;Ç^ >âk1²÷CS»y×î›u§‰½¤:W¹¡':O‹gÃ18Uâë@«”×à–÷¦ùUZap? ÆàÀÙSÉÞª¢FûïÉiœ,×±"Ø9n¸ºí1bpP’SÛ®ñ–VK >ÑŒX4}O®-ƒ«€j¹–Á§¹Q£ ¶¶ƒOú«ÊM×äÀ ºªˆ ×®ÕÙÛ/Qaë«€´T[;xaÜô[F!u`ÁN) NQ85òÏvsñMÒþ{r’Â×®yô wÐg.Ÿù­R­l”*ŠÖgÏ|â*¶Þ‹89Qlö"‡¹/¢±&§8H4õ8Cà­sn`ZÅ÷Eœè÷Eað3ø,úä5^“{Q¿|oZcyOqØ=þlݧ­Iò^áþàÆòî$¶VÜ=k§QÐSƒO˹º ±øw•¥Úqo­5Ý›6·×äK©Á³Âà3—ñ¡—‹$F*ÕŽ£0x‹èeÎà‚‚¾h£Á…Á;‹v÷Eì,ò\¬ˆ‚G»½ˆÂà‚E^ƒ‹Q°ãØÊ^s÷ y¦{“Õn#Y)sœ3@ÒgÜm¦îp ßùŠ]ª}Ü÷ÌWÊÐ(ÌIŸ°÷ÛY·-hpÞ9— tÏð –¯T*Õ9ë¦ö:ý¨h]Q´Ôà`\[µÕˆØ0ƒ«ðÙƒwgžÁñœ  í^Ä¡C}xlbTã0Ø7̺Cc¤~ÏU èoŸ¡sæ¼Ê2¸½›ÏY}¬\‰‘Ì ‡±„=S©0‹÷E/ Æ×äý‘cðhvð˜ 6;n»ÃÚ}µr»%Ç`¿Á…Y7é3ƒþì­ˆÉ!b°ê’}d°3O,qŸûS¸ýò´0¸úÛÁÁŠÀ ^GƒádJ¾YŽgÞÑ •xôKx•ª”?éiE4%}Ú1n€–< 4ô›åþ:ÆX4°ƒ·øASNUJG.ƒ%}ê{&n€¶ûÁƒ2x‹È0x«å*è¼bEl…Á§ ­íàÓ¯ÁÞT-Ø+´ÔàÃÃc±Þ^ÄV¡78ŸBà½Ck >F öØvù;Ã·5÷ƒ ¶†¼—;Ü vY ®Ëî;´ÏŠì>Êó" öi å{r»ò]å‚=GÑà‚½ÆºvpAÁN ·ì¯Éì4z_“ó8*(Ø< ƒû=»²0¸`‹Ïf_ßv¿óÂlö þPá…‚‚Aá95C î·L¬~íä„N ×ÅÙ€<Ó 6?W rZÎ ƒ †ŸÛ5¸Å½iPƒU²óyapÁȼZj7ið¬›ÏTÂË%fð²0¸`h(¡TÌ:ÚV‹ÃeÑà‚±axefý¬C;ø8ñ-# Á2i³År𠵨²ë® ®Y׬ia™JŒN ÁìÈï|A³ßÑ þ žÀa 2ø¨0¸`x̵‡ – ®gí,Âï…l Y Xƒ—–ÁúùSêqîßjð¶ëRpÑÅ–äÕ$6ÏŸªÀ¿Æµ‚‚Í#»‘°ƒÍ3 ƒg³mW¥à,bÞl[ÿ0ØìWîÏk°ÙJ›Ï»Ü[4_kßÙT°§p}?_¶µƒgñJYÁ2ĵk$$¯ôg[¬CàNœ&¨î7Ÿí`¨ÁØ Ö¬¾Ö‘ÁÇ}Ñ-£‚Ó„ù|©9ŒÜd럒;”¯šc°Ô`u­º+± ƒ z`.‰¶\¶Ð`®¿É#ýsr“ÃC~?X2XZÖ]‰¥8_\ÐJøTÿ7h°úí8ÈV²‡¡ìà#³>ìR”Å¢0¸ 3sC´eû½ˆfBufðr­”qZ§`÷qrM-»š5¸Ów4 ¡ŽŽ:ZëlŽÒ8{€¹æïà<Ÿ/ô.×r¹ÔKŹ;K`¾\,iï šR.8µ$Ó´™›íˆ& îð-£Ù5™îâD%¾P™,OäËdÉBê3•hÁ©ÆBÑ÷İL,Õà‚‚m¢<7­`¿±þw• 6‚©ÚÙe4Xè…Â;…™'ðóÈÑ`a£Å+(hÂtúÞÞ{ï½?<18Òà‚‚ÝƒÔà÷4b# î}­· `\X – n"ÒàšâPÿepx¨þZC…îœäÔP–‚Ó ucdÐààÎh0XÁÕ긶n5ã¨ŽŠ¹\°!¤­ˆ”Ì’sÖ¢ ` ´µƒ vÓéóÈ™»&·dK[~ ¬c6ónÔà½`p%ÊŒqÆ ¾eÁ|×bW5¸ñ’`!pƾjpAAJƒ¥S›ü›âf‹U4¸ %\5St\ ÞoŒ‹×à*ÍÑz3 .¼ß×ÓØGÿwŒU¥»›×`Èà`NÔú¯ªŒ…Q½a¼K8Te >õÊÿxE×XY7h0å¤{·„„.‘6'WEƒO;'“±ÖÑ`ÆH7Å`6VÑàS NMÁÓÓõ»u«r±\ÀÊÆ§žì`×I.¡Ìˆ`EtdpÑà½ÆŒapxloå™Y¡ù²±*¨B x ¯Ál”¢Ág 5ËE>bÁ€Ï`n?ì¦i ­!âæì}¹0Å>í˜q­£0ø€ª1d¼‹Šb¥®ÉkÀx3¢Õ^DU‘À~\”½ˆ³vW¡ ä5˜·=°ýÁ0¸ÜQ04Òv0x«DX¥¥cQ;˜v}¹/¢` Ô‡èËl •Û}`GïEp±„Û0‘¢«Eƒ FÀ P±õÎ.+N\ZjpÍ9ŽÉà¢ÁûÔÐò÷u3±hð(VÏ‹¨Ë| vá±=ƱÝ÷äÊW: vˆÀÏV–göì fú¡'š÷u¹ò]傽ÿ½ùÒ}Ñà‚ýÂŒ0ظ .ØHè ­ˆ Ác=³­ `` 6nHƒ[sQ$ƒ¥ñag;¸çnpò‡l“Ö˯`û˜…ÎëÔ‹-»>±’+{û²Q°çð þ°hpÁbÀaY4¸`€œÖàv¿é9üí–§«u"¾\¿¬~†å—åñ¡»?·÷ï*«ÒÈ—úSGI4Vnµ^ ¶Ux™·B¬B3XÒVþÛ—vJj0½“GSñ²%õL…ÀÍ’Jãò¿½ÿ<寂Ï0­ÁðÌkGJƒ7]ò‚Œ„Û€þðÞ‡ÊT†ž{ÏÖÓà‚‚Ô`a°b¬æî\¾¿ðÂl¦þ ƒ ¶¼Ï®]»páÂr®Þ-ƒ ƒ·jòÛt!òùçìà÷€kîzÏfú­0x@D¼PݹDnc‚ÍoÓ…hÌ?µa5øC¯Áóù±ù( 1]W”Õö¡ ,“ߦ Aåß^ƒ—KÏ`E`õ^<*ªÁxwN…Á\þ ö—í”K >>ÖŸ’»Gƒ1x«Òî Š¬Äà bceÊaS…H*¸d4\x >š¿¨Vr …Áƒ¢hp+´Öà™¾AÞ^U–,—qv;xžg0»þà³6®ÃVpÑšÁk²d0ÓM÷E˜»å¯][^kÇ`fýÁº†" X¿½F3ƒý2|SÆru‹¶•'ù§ì`xgÙ¾pt$ÿó ŽÛÝ»çÑ‚Á¡¹6ÆáÖŽã#Qçv÷¦käíà,ƒù=HíN|CT¡3͵!ܧ«ÛAƒ ƒ{kpE½ò;S€Ö]ÐÙ¸mÓÚnWœ©jw îËàUäÕP´‚¤¹Fo½`pÃt³1 ^E^¦t½+v±é½œ`pS ³\ >* Þ°†ÅˆM¸u·¨\G nØ‹€ë²"É/® Zo®ñqË nS±Îvð¢õ º"Iì.ö®ÞYDª¹ÆjÆ­2¸e¥2<«»kðH¥,0H7×8 ¹E·­PƒvÜ‹­œ¹æ£)·Æà•v/bÌ’žq´¸!aøEÝ–Ü¥ƒÛÁë–µJŸe¼ÚŸíN´>hìÚ9¼ w‡Û×àF`p¿$[GkŸ~´èÜA9¼yw.~Ã~°·ƒ[îw+«™ÛÓ¡'‹FHdˆ¼û U rxÓ îSô}ÒàÂà–) fo–Á½J=ð}} ]ÜíS†Ã›dpßï˜O¾¶I¶ŽÖ7·>è’ÂÞƒ{—¶­<â^ÄäéôMät1xüZ;®™Ïi¦5x¶ã\<|ø(~kÇu2Y«”m¯É°aK_ÜÝSX`ðÚ²u;xò탣§štG¯î^ƒ#£3xýA½ýû" ƒ; g‡÷å m8²a²¯L¢m”Áƒ¹zwy¿ˆã2xþv×àÁ÷"Æ`p:ÉžÑ=Ûdp?ƒxLÃßÕ)Õàm2¸mÞ]1ÀÃr:ÇÁƒñw›vpÅÝQœÅÚ»cÝâÅàáø»Ú= Þ(‹Ȼʥ½zbÃûq£0x໘Ó¼â÷ƒGµƒ#:Tm¦Îª\"=ón[’\´ž¢ó;¤1ƒ‡¥¯ÂNiðä«Z³(sÖ!omUí>ƒ;¨àà ž¿;¶¼Y5äÝ#}¸û nÐÀ ¿«~<³šÁ”|C0¸5§*°C´tn™Dzb@´IjPÃßÖvpÌà¡~… K€õ9›fQ‡h[·g"=1( šÁ#ñwÕWƒ—ËÁ~G£ùtèÉ¢|À9ƒ Îl—HO ̃&ƒx0Çß~×äep–n­èГE}ÉwŠÜ”â0 õÉn}5xÐß2Ú[D«`´jÅœÅgØ«/ÆàB&Í!<.}{ØÁ‹á+K€Š;kæ mÐDúym9‡ÉT×gðØü]íÀ~poò*b±kmU5F!ヒ‰t×eðø»÷Eì)ƒWýò^ÓŒìØZÁ›àï*£Á«Íip ŒÀ"6‘^ygaö€ð£!N|oˆ¿;pð@ nÃçžÑrTlNì2s™4ùþ ÞW;¡Á<˜)¿=‹V-XÔâŒûhH.`_ŒN œA_o¿;¡Á«Î„EÃG; 3Ϫ'ƒGÞþ° ¼³ môÅfÈQå ›-ÆéÛ^ƒ'‹Å–5¸#§6`Þ}±)~ã.±rÌ”aãü]µÖà…EãoÛwÞÙrŽmÏ ƒGCU%7?’eØÛkðâXAŒÄàê0¸}´¾Ø$Gº2x+ü]uÐ`Ëà±43á{'ôüⳞ‰¤¢­2ÑVôìT1¸£o‹¿­Ÿ|rrÍ`$W9ºµ<ë­ñÛƒ\në`W5xkü]5ið¡×àk#3xUõb0$NÏDè7CzŽžÖy皣 ;ÉàMoŸa´Õ`ó]壣÷ƒa u#_h0-wÖ2šdϼOƒ[îEl•¾ -5xìýàŠì¤ƒ3ì— Ø­O"=ë™7¸¶NX†íh~GÃ|fè€Ú‰ž‘hIUl)IÛ¼Ó ^RïDqvCƒ ‘4K7`ûïz}G£0x[ØærãhŠbÔàžßшeºð²3í°Ø~s¹mâ­Ä¡×ó"2 ®VÑZ•uõ¾;Ó{í7׎ñw5´W฀­7×®)ðàÏ®Ì2˜«ù.µÅ`û͵s Þ WÔKŸïR[ì>¶ß\;Çàaì`_­ ƒW‘—‰9fíNv ¹vŒÀÔàUä¥Ïwª1¶ˆäqÛLiöïE´ep0fíöé=ìXš+ÂÀûÁ Ý« ¹ÄäÎ:G¾s-ÍE1øw•ƒªVva·t‰Fap$5x£ßU>ë( îöß“Ó8YÂàþh©Áн’åc}G㬣0¸7Zß|²Ð_ôá÷äÎØfïŒË¶‹¼[ m—×àpðÂ2xøß2:kàÛÒ•ºœé抛¤ýw4$…ÕíŽÁC=Ã}4ß=KºJîá´Kúìú´Õà ''J‚Í^„"ð@VÄh¾{štߌϬO‡ýàý¾( . Þ)ŸöûÁ/ê÷¡÷"FóÝÓ¤ûf|f}Új°º?øÚß“ÛRÜíEÞ^©O zjðÉb9W4–CïEl)naðÞ¢ŸÏÝÓW—Rƒg…Áû˜ñiA/ I ]œMÅ- Þ[ôÒàñ\P°&ÚhpapÁ΢hpÁž£hpÁ^£hpÁž#©ÁðΞÂà‚]E»ï*Íàø¶+îF¬=G¾’]ª{&š+ î6Sw¸ Žo}eo†Ýoä+Ù…g¢¹²ˆGðÊ7À64¸ï)—q±ËW²êPÙí7×¶µj€–\·É¼G.U—Ên¿¹¶Œ¸µ`´ÕàC‡úðØÄ¨ö“Á›ê÷\%»gžÁ«,ƒÛk°ùœÕÇšÁ•ØOol”©dE}z§tfÐKƒ1ƒý‘cð^Z曂z!kßVžÕñ—×Ê ¼ö ‹½R:3è¯ÁÞŠ˜"«ˆÌ®“ÅÙ¦;â:>;Há¦J î‚þvp°"0ƒy &[>I>;0÷Õò1€ •x ”Ó*[Ém±¹v¡Ùâhi·²"Zj0$wî«åck0xãF°^V¹JvÉh{͵€=7@Ûû"lr¨œš‘²cÈ0x«å*è–œ·" }w=…w…Á§ Y;¸ žd>*`¤ì )rV„öÙbÙ z!£Á3dE{ˆh/bŸ\Yc'~«Šï!Zï#{˜Tö‡Á+¿FÞœ-_°oÈÛÁ-ïì1 Ø œ2 toš¿ÔUUøp«•+8 ÈkpùŽFÁŽ£|O®`ÏQ4¸`¯Q4¸`ÏQ4¸`¯±î^DAÁN ·ì¯Éì4Ö×ࣂ‚Í2xM ÞvU Î"³هÐàÜļ0Kà…‚‚à™4C fïn¿a¬~í3Åà£t™ Úëál@ ži›Ÿ«•ËþW¼ ÖƒŸÑóÜÝŠPÉÚ­G( . J!5‡Öà™‘Þ”/ ƒ †RHŧ£F;¸£«Åár^¬ˆ‚‘!ù5Wd{a(ܨÁljo –I›-ŽÁóyapÁ@P‹-»îÊiðè»Ê€À5+Ì–Ÿ–ÁüîÝvë]pZ0;ò;_ÁMü7]㾸V¼—P·Ù(cG<Ã+9ýSr‡òUs –<Ÿ/–Û Eað™Ã\m¹l¡Á"\“Gúçä&‡‡ü~°d°´¬·AŠå²0øŒA‰–ê» F{Jfñ†¶ƒÍúpÓÕY, ƒÏsC´eû½ˆf¨޶ÂàåÛ1›.lÁ8¹f–[MÜéþ`CÅáMWgï%æv»`` žŸœ,‹ùc9_¸oiŒ€ùReÑ+æhe*j»@³ÊlG4ipÝEƒtn‹“åÉÒqf@D£¥-TÌá‹S0>Ë“ÅâD3ëDy@ .(Ø&ÊsÓ ö×ä vS´³Ëh°Ð … v 3Oàç‘;£Á6ÂF‹WPЄéô½?¼÷Þ{x>bp¤Á»©ÁïiÄ FÜû:mAÁ¸°,ÜD¤Á5Å¡þËãðÐÜüãP›×hÐÙõŒÚ¦>;ucdÐààÎh0XÁÕ긶n5ãX{DÚŠHÙÁìZ®,𠶃¶vpAÁŽb:}Þ9÷¾&·=›¨à,B2ØøyïdÜネ­V§à BØtà58\½Ëx“¯‚‚Á!üvNip¸z7Ãä _Û×ÌÒu,îA_{Ò³„Û5ßôš8<$dæ4˜å눂,RñMÔ ¯‚A!l¿'ëœÖà?ø] #¼sóÕ$õUõ;ú[Ÿ ÅlþC¾ÖIy¬2•ט/B2B¼k›/Á-õn,ƒ ƒg5GŠ  ¨èÙìïâ•Öà÷€kîzÛßÜ2svl÷¶!:G;ˆ"§ýÃ~ÖÊöúÁ.mèÇ„<ƒvðÌ<]Â>d‚2Ø§Ž³ES+ÇöÑ;•)êØƒšéÿ}Ã>ÖÊÛÁ–¾#3ü!ÒàåÒ3ØüNFK;x {¨oÊcÔ8¬éæƒAë´ñ×ÞÕªF&„g°'vÚöWï”ë§“éOÉÝ#ÇàHÞg˜Æ“•¨›ó‘2ë®?H¬F¿Zí ˜²¥5øùpýY1w ~†C'­Óù¯YuyÛ5>íkB4 ïƒë^µÚÄ NÊRƒÍ“ªÔvpÌà"äÆõôí Þ*`Ü×±ãi`pì¸+ ò¨ûÃkp XRƒ ƒ Á¯]óvz1Áà.¬c‡aÊ]ã·©&,Æ`ÊhWj­*næÕ£VÛz¡>׃Š¡Hß5ø‚½Y¢v£f™ÀÚÈ»DjÅó)ÐàæZíRjÐ`a58šPB€00“Á^ØÁ°N¡† µÚdÛ¾¤5¿ÖØÁœ A8áZöu…ƒU™³ºBùtˆyO—ôs².B­ Ø]@¼ÒæO<6«Á‰íFÀ"ä÷ƒ½eîMC” ÁÛV¤…Ⱦ՛Ôé Ñ)¾\ÆxÖmíd ÆfP+kþï’C”ÑÄÑQ¥¶xc·Ü~pk;8¦O‹4ƒS<9Oî¬N‘”Ù8È…k2N¬ˆ½€èT«1‘Ø~€¦t‚{RƒWíà”Œ¡U°­È]µÈê:¨‘vÂiZpa™˜œq…5g‚ñqPrzyõvAE³®A#ڃƥ±I`ÇœP“f[bôŠ4}ùš?Ð\WƒÊ0¶!VíÀ&z=CUXÚå Ç$ž¾`ÔñVµã™ÃNÛÁ câz6ÕjÄ‚%·"‡,ñ¢Isýýà¨Eš-Æ“ žYϘÁüYì …µE̳Ë5¢`ÚºFn„«ÉîÂ+¸©V#!w÷ѽ”ÃCíEà<âÂ…‚ë£Òé æaPä)ZÅdÏÀ©ˆÒq区7jÅÐëŒmDmöÝk[fj542Û¶0 ’âÎÏ‹  ÆsS^Ò‚és ÒT;¨£Ó`E€°"Ž)Ï`5ÐS¸°K5P²2 VÀo·Ì‹è±L­FšK²w?p Vtן=ìà™ÝFš—E.{|×OÄ&'ºNjƒg8už"$ëpZ’2ÉÂtPË¤Ç ÇjP+a­ˆ2„CÇðh®ÕЯÄörÉOu/;XÓ÷(w0]ÏYø™IV®ÐFÃü˜?@g䔜11rž©Ljf¯yÐØf#ˆ´[ƒµ ü{ªV¡ÅÝ"t„à 'ÐOƒÍ;¹¢•-mE0zˆN’zO+ >³9Y;jtAø^‚\&JáÚ–©•Ëe·I˜ùl¨Õ èr÷C€2öÙž‰À`0Ó†µ$kbùï–X IDATE¸žõ÷îÀpQ̃š9…ûäa 3=&µª@ìÐ^Dl7@÷h'šÁ­î~ˆ‘0¼_Fƒ3{˜Á4ǸUô]幈êbOÿÁyšÈ%ËÅÿÄ»\Mu¨‘ué¿£aа3v0ì‚›óµ¬,Uf<£ÆNÛÎkk0-LjUTc;Øk¦#`’³ÐÓ-ûyOšÓÙZÁD—qÉ£*FóËYé &®Õps 6cÁàš81Þ˜(½ìàÀ`8hHžñö—ÀB,iÏÀy¿‹€…ÕiaÒ“$2óMŒ´*TA¤§¹½b0«x-jµzÞýÐϼ–vðRb®þ9 Î8ƒùçÖÚ"Dâ+jhL0ÊŒ iª¶T q²|L]FoBã&Œ$1\ZÛ@Ên ®MµZÀÄbd)oÞ<²aÚiðÜâZÞΞ Ìàš¡Zx„cVQÓ1#ë-þ\üaB ¶^:Bƒúõ©þ±ƒCS]ߦVk¾býEïôП¦­`_Z¢¥¼P?Æ¥~Ž‹ü""5¬`K%¬ˆ:ˆeNb’MxVLLÿìL.YZÐ* ähЉ,ÅP+x²ÃVÑ“†Z­?—à‡…ðJ‚eÇ› 䢷ۋÀ >¿ééþè€ã1Ð`áÈ àXIرb‚ˆÄ¥ƒ«‡hÖ•<|Ƶ @ûD»Ìà¨:͵ê°ýÈ™à= a‡–vðb‰OîJó3{ü0 |6¿×âÔCšyÂds$ Ü Nk½!Ó[øu³úNØÁ)»!åÞëP«5€w½e‘V®Ä ’ÀVDÞ^\kñ‹ˆ |vv° òHØäMèIÆ q"zGB/jÌ}wué-7i0¤Ñ:- à»aãVgÙLiÀÖªoþÁüeæ0ZÀ¸½óVpMMöûÁÚvHýLÔ\)àJÎNéÀl°ÖiRfqL³R¤cÚz3žl£†9$® ®ðß]+BàÃÆZõžKý¥y h§E£‹q‰€ãûÁ ß¶÷eu «Ëp*ÐYÖŠZ®|ŽÐ“Í„÷o TÓÝ[É5N'¹P\­: £¿ ªÚÎ1òæ¹i Ù+RèkËI ÏCO~¬Èæ–bÇô§÷M"öôu1Û´!˜ÞÅÑ’eûûÁìt^¼+ŠfÑÁ ú›¶Ö"cG ÇÈ )­«Á".n¶~VfmÄÊ›¢Æ¿¶­ž{ ãYÇ1ëp†%Ù“~9C@OЖ¸Ñ\çÞI­‚xoÝÆUáÜÃy›Zux»B¤Uñ¼Ìq¦‘GÔê¦Á©oa‹Èܲ¾y¬kŒoÆ_ss§Vq̃¤·(p:¾eqž‚9jþ®òö­ˆ–3rC;ÛÁüÍ¿I…„3\”È0m·œe°ÀÉóÌjŠÁ¨•e8ˆÈÓîñà˜5Œ 'ótÐ:*¿[”¸ÙbA¡ðO¶ÍàäDÝfH2µj‰äÕ·š0¡]Ñ8f'¼øž\ªN±“ù^&Zø¸ 6ÎDäéO‰§€~$YÛ2"á¬íüü_:ß’ŽÀN¾V¡ [ÝeͲ‚LÄÉZµE|÷5gP¢²ñFpfX±b/‚+×pç´q¦ÀÍ‘œÞi°( ¶Àˆw21¾±Ø¢Â¹`»v0­ çã »ÈÆ‹kÕ2_Fis² ½®l3\ßvs†Gµ{ ªSÛqÝÞí’DSªm ç„ïM۾ѣêL°Övp|÷C(’ýX–SãŽKŽu5˜–ËœWhµäF+XµW, ‚$ÆL@$ ‡¼B·.ŒÍ4<.„ VÄ6 Ä':ñ-ÁÖªÜÝ+Et.Zp‰¸•ð^ÛNæ‘°ƒÙbçš\$ë¾æ;‡ÍHà·(ld5$[ÔÛÑêc‹ûÁ‰ùÛ»ÄêÆµC'î~È–‘ÑÝ”„¼ÖÖ`Sêê@¿Hõ\ h›ª™,kc䌴É69[æ™=míÖa_¸|¿ãù/‡f;8{÷CÍ ìÇeŸ4ä9i™b/‚LêVâRÄãš´ctš¬bNÃYË‹'hÜö\cÓïÿ¦çV­Îì©ã*áé­NÔªa.I\}sÉŠp1„£Ž.2 O9ßÍìsE·ô]eT¹P¦¸: ‘΀)Þ§Ò¥õ…¥±D #’¸¡áIåâñ+9¡'ž­_ÑÈBŽG™Z%Ô߬´çe—ój0J³ƒÝ¡¯s‰¦BD-‚²LûåÒlôÔ%].a¿s· ´²ÌZÂ!Ç`V׆l1èä¹ Þ71øÙŽjgæ!ÚQ«0ñ9›®“Û©“S‹Iç¾'W; îoËöÅ“ ßíü„—ªóÊÝýÀ·[{éõónb´)5hþzœ  Ó"Ê38šõQÌlµaWÁú„@¨›H`˜j*¶6Ñ -7ÖàVÄj“3y†ùÕŠ/]âÑg|¸±•.h\¾L&à8«ÁÍ¿«(€‹Š ²õv0.|Zôöc“øLº¸ù¶¡#I@7Aœp|7§jåª;PxS3ÛÐ)]+‚ìw9pÅhrëè;Ün„‘q, R…¾LmÚ¨sß“#w×åË4 7õu^˜90 æï~àèÏçÀ6Ôrn¬w”³>ZWƒÛœm•D½‰üåÑ »´¨iâœZf ã;‹ÑÁßåÙü²Ôâå go^EÀlÖX+”Kòî‡L΋Ï?‚ãqFƒëÛ‘8d^…SFáÒÄ£…º&²-@÷‰‚¶R“4×ø*0.‚†eÜÃ?&½Ilõ™«Uh0¶VäªÙ»ÀbÊ$~teJžöd?˜Œ÷Äðü2 %5’„x†áå%W×4ð8r oèGKP¨V4@Ž£Ã]üÈV“¶(¢­h²VÉ»€JàNl59'ÊçÉDÙ ÷Eˆ8‚XÉâµCf6L¥Ç2®Ýõ$¯È×Õñƒ.©Ç1x ÄàÆÀÜê^«†»0£Ù“ØCLòI‹È Ç~ðö{r®Üt'?á9Ÿ”¶­åÀC5.Ðr`pœ˜,Í6/¾ù׺װe3v°y:6kºÆ·P¤‚æ_¸åpÉ8% µ Ì|­ÔgÓÝiDd¤ åã²£"ª“ê{r°×Ú“hÑhaÃyªkà;ÐiäÍÒ³öXÄºš³ƒ³W¶ˆöTdžÆÎ%:³µS$W+wcDòî¶}ãqÅwWj|Ey$ÀPíìày÷=¹t;8—“šTíZ4I`nPq} ±‹>÷{ ƒs8"²t…Ã}Š-—ô¹ræä€(ùÄó¬ˆys6W8ì€9œ2P¼WK;Ø=|5~ê3C ± ¯¿¦ˆÛ~Ž0§d¨4{(`œ_ìf¶yÉO1×ñêìBWöO/PÂ×½ÓIϽV:ˆÃ®õ"µ®q­âqUIÄíÓ<³1íY‡žJ:C/núMÏÞ-íàùB?º²Å~0,)…¹YÂÿ‘n­’žï4tg[‘¨•Ófýë ÕÁnƒëX+_ÏP«VéVá?Ócc½€ / ƒìà“¥að’ÿEÄvãrÔîZ q_×až~wÔ/Ôö¢VüP`½$kµí’gáýáXÜv/b¹”>ò Ïö†c‚ÆmLä¦U̺þˆ&3m5x³Çqü€»ØºnÙÆ z™ÐÓú¹êEµ²\é]¢Mz·ÞžÏ͇´"“{‘Ü[g0@zY C5w–ÁÍËØŽØ,wƒÁ[ùû"Ž$wõžšgðÁÜ]™°‚ɺ+~5ÝK°®ó‹©F\•xè­ãuÊ6RŠ´»}GÕ<€QºÖilïÐ ¢Ã~0`0ÿÄ“ôj1å°Kìaº›ngtÎ{›Vsìú* ÇD­rݶU Æåmm_¸p _“ÁΡå¯U¨ñâÇÒ%ÐGŠmòÞ¢á¸ÊwBºkÄHš0\ÉlñÛþŽÆ\Ñм³ônšð#it M¶dÓd[´= ä—p"܇«TCÙ·Ãà–ëôXS­Zo ™ÐÎ" ®½<_.=…D¼›&0akN²’6Uƒ-Ygc7Ço÷ŠŠ»¤–­ù²7ÛÉcˆ‹ +ê‰ kNÂ'ólê±_pl¡•\Fƒ3¨ó²õpݺÖMÔ`iGk´«V¨±‚I0&æ.[äæšV{ô˜^£4 ƒaf4¨/iiJp8—ìúAzÈq–†a̤¬*mÕ†ðep¥ÈÛÁ‡í >àTóK%_ЦÖоî³ÍíB®[ödè M£¹0ÃÍUª‡jïþà[Fƒë6,|õã´{›Š¦8–M–l+89Áj•hsÆÄý°Õ¤Õjlðµ[|žŠÍû¤ÏúXÝÑZ/úÅïáÿá{›ÃŽcD MÉΆq즥͖u˜ò8©Áðþàv NÖ-]åµm„!`2k•k‹®‡ ¤ ìÊ †¨fÛ¶²Ó¡/u›ýà ˜¶¹Ü8‰â$ýšÙ=Ì éì8´ˆŽ’évÈ·1»ö¢I–Ï<òÌÜ|jCJSÜÒNØ&Qæ)“J›ûHüÍ©„T‚‹ŸO»ƒ]•n-Î GUô´‡ƒƒšpc¾lÝ`¨®h%P1Øj"„ûÖÜ«Bµ¾ÉW „­ïº)©Á³®VD *L¾$pà=7eE„²V°=T…$OT¨É&ê6% "èÈiK@T‡¸žÛÐaüÌSaËiK’Óàv N˜Â å‚fðñMÕ)«¡mÔIð] ‚‚C2èêhfËFæ™AëÀën4ðRºlî{Á!¼·µƒ"FA]×ÝåGø«˜¨°üP}¿Ø‹RéH"Øï†¸¯ƒKƒ…à÷1[‚ìxâDæWClrÖT«íØÁ‘0ØR lE°{ƒ[U¥¬NŒ9›g^b£6QʧË+.5©o‡6¬ktÇtÉ• Ö5_ƒ>8ä|‰[s­²fù8¯Ðb~¶,ÚÞq|ü˿Іô•¨ò†°pù¥жCÇɈ Ã׃€ë¶:PV wZ ý?ù†ÜùÇ¢å#ÈÖ¤teˆŒÂ¤¬ˆmþLim'l®ƒ¹"oC[8;‹DÓÔíéë¾@ëËçãTÍfÅùrú¥ƒeuÃ7chh¡S"FKLT ”š¸$ 5°eO½3a-mØà̹~ÈeÅ%2>ô_øâ'W«íØuXvø"@ÇÖv0b° ­óuu3íT¨ªöÉ/è÷bÖ„ B4é˜ëoóú´]ÝÜ&Ý(+®sIÇ*_W`ú_£êD´ñãzt©§9+.¬˜6(jÌ\açËŒ\‡½ÂàYÐà¢ÉeVöÆ¢gŽAg€’áÒ«1j”÷hgZÕ8}r’²‚A#zƒ±2|d!Ÿ«×\xŒ† ªÎ%7Tåtµ=mÕ®ƒ™UãZeª6Î+ÐOËÁ€póv{;˜·"Œª€V°m\Ndv c+L ~JEEÜòæI2Xªl7}Eœô2Ú©ÌöÈ)|¿½Æ x0C]S8Ãz¹¨™jbÃ>¸fhîݹZuhÑQ`ŸQû~¯Q©ÚÙÁuÚvDÕ×ItÓªŽ”#ØYЩc:´µ–}}tzƒ[· ;…6Äp2ŠÖ2ÛPz¤f58ò².þÒYª^¬à–%ß9fëÖÏÔŠ^‚}wàÓ¶­ˆ3]Fá îÖüRJ¶×êtWÇVDxoÍ`7çùŸrnW/.0kOÅjÐ!d1?ÔÐÉ|;˜eð!Ë`¿ p†±pÿã Ƨ7B é[3Ã`ÝÃMv0j äNýK÷D)& ÷8_bEèB³V„©å´Às(CE4ž`Õ€Í룰B2„uÛæ… ¢Ñ$ÚÛÁ&Âáá!Ù‹p†uÍ3¸rMÒوнwÀ1¸öFc3+Ñ)´‚[”²È, þü"ïsÚ¾™X‚Ö”4ò ÔˆFq»bo|Õrv0¸7MX±×2ØÃ¤è,jAl–eц^ÍŸ¶ªß?#oµûhL¥}®˜Ã"aiŠ8t:ß°Íë)Öt5¡ðxGa¹’Æbœ*Š!}S”ÑÀJ1ž÷Ï"+Â)b°yHnm÷sôE39o¹­L3dâ°E!ôõf[³ Îhàvˆ ›xËW!²¨H„H¯7Äaظ‚ØË1£Á-¿mïmÝp­é |¸¹ZÁ´(ĤdM£È$‚oЦËW5uG§\ß±ÝÇR'›7=Àûi%¦–Þ N‘•ƒDFAq5T|(+7÷Ê"ð:¤5xÖꛞºEÇ'gEt•DÌÐ:îÝÆ` ŸÖ(ùdacV¶Ë–ê/ÈìÀÙ\‚úR:S‚Ž2‰‘…Ã’“„A£lqc'§·”㽈 ƒÙi`³:HúàH£6U«qŽ#ÄLa¬Ѩ^ÜtLƒ‹–—c¡ÚT-­ÈDY@=7Ñ1¸$aä‚öO«Îšß“sÓßÌ<š8Õ€‡°•øáu7~kn–D86]R¼Tãʼn&e"5$8éNKg˜45â9µ‰NâÇ~P£¤÷{fOªhà1vcAÔˆÃ@*ÚW8]0´.ZBá"9NæR4n<c#“dP̸JLQ"‰–"¥óÅf [ƒí±ösÓH;ä‘ÕVN3seÒ£u!¨?wÄ8´);fvyù4Ò3T®®Ÿ@úY‚ã³AYh’âpá3Üb%WP°h¯Á³È¥ `ûèmlNQûïE8lžëÛÁÛ®JÁYD°i×Ö`õs/\Q³™=àÿàIp 'ÁxÐó6î0ÈCZ¾Dé®°õÁ\éÓbg”`ˆ—öJœ9Nøp^‰JHóÝR¹QÈSL ¯iÛßè³ÙѨ5íLà*XÁ:$ú@~i«¤…þµÏÁl6Ÿƒß`Úvq †ù¢ìOæ4¸›¬†Æl·ˆR|*¡ºUýap¿g¸;è_ ŸíQfb>_Ÿ6¨nUýyÔ¨Á­µ8\îQdU—…Á§ª[Ù^fðÏ® ~á³Å±í ÌÄRRØþíRÁ ÖÁLXšu±ƒ£gW² 6Þnõ fx›zÛÅ)3×—mì`GWúìʃ‡·W5ŠÙQað)„ßmeÏ<ƒÑOƒ_[f<Ýñ Çš‰Y#|(~S`uy¡PÌQ” WŸ<ó±å‹r ˜+ ΄­:)‡ý÷¦ GFÛÜ¢0 è=ž]éÿMöGlž£Bwnšù·‰\+(Ø< ƒ»?7Íýk ÞvU Î"æ \§¬¨[+ 6«%½Ó<æë`œ"l ®GçˆÁm5ø ÷K0À Ö|AB²E޵0ÖÌy¸0úT¾\T.V/øßÊ™×p"ž¾Ü> ƒ‚ÏlñqZ$ÌÒ— gâýØúsuñ1‘êp*:¸Ó ýòåpEvšF?o4£=#œü‡¼L#Íü[Á—Þ”ù.784_< _ŸÎßFÔø{æ-J…C€oÊ'ù‚›͈˜Q”6ú^~ªT¬I(öâ|ÁI†~¹âÓçØ °_D†å ŒÜS{;†éôy äÌ]“Ù"•Ë&í1ónÔ`ÈÀÕ+ ùÁcÕ€6ºeZ(pðUÂÎŒ§ù¸ê@Þ6 nÔàBà‚&pÜÀÊVÜµÈæÝ¨ÁHjp•"e¥Ð†½Õjm;¸hpA ¶š§p%’ Îg梢X‰½ˆ*\·  ޽"+¢í^D‘àÝGÝVƒ£ gÑfœË,D£ n}_Dg Þp²XÁé<$ì/^M½Ìak–ͬB x$íàa(œk›ò` }ÀáaøVšsû n"ÞUˆ¢Un÷A€«fb¹Äm$gŒx .È¢>޼V´\ŸƱâàÄe‹\ìà3ˆÎ·|ÓàQ[}^DapA„ÇöhÇò=¹‚ý"ðóæËå™={ƒ™úÂý‡ê÷¾÷÷u¹¢Á{ÿ…{ó¥û¢Áû…™À 6®Eƒ öÓ野ÀЊ<ÈÚ ÆÖ`ã†4¸õ£õšŸ½]Wpz±Ù~Æ ÖN“qì`ü7÷Ary⇠&8È"Î.ʼÁËôÈB„ ‰$¹´:If’:òoS ®ÔÐ¥E'0jÕqæLdc¨•œ4#>Ü„ìžæ&̳䌛q œ‰è™t‰ã‚MÁ=¨OèN„l5DëÒmC&Vre/¢`?0+{û ÏàíJN .Ø#ÌÂX޹g¸ ñÒ 8–ÿWޝèy¬Þ¯Hí®ßŽ­×ñ•ã—‚«mBû¿+ú½¯—Lê:+ú¿b—8ÄW¼dÿWPQïe}®Ø&á]nW˜ë‡:¶M–¯œoˆ—"G¶ê´¶O†éÿ+¾Ó;ÆJAqøùùáaü;]ÞøRP¤³îO{]±næ@óTTo–ÅWÜɱ§»‰|lúVyÛàW|*>½ðŠ]¸0ࢤèY*¯c_Û+¸¨!‘8Š•® u K%ª®}H ­_rqÅŸ…a¸Gί'“I Þ'ÁÍÿÙ¾Ûû8ŽGÝL·úàHõäÅ!|(8 ^›Á Lýû4á×6Ç)莚ò ð yO8§ö‘&SÃà©fð¥Ã‰þ\8¬Á°€ºÀó¸66‹Á”I(W0 n,ð‰f²² ¢tYߦ4çÓ\G6„ˆ½ªàBMíy¦S„ aª9u±§°µ™Ì;@ظØkp}(?—òsÂÚÁ/ƒÑÕãÏçî†.´€þ`”ÁV°¾„Y Â¹™œ2]ÐÐ1H3RÐ/(ê&LÆ´æá e *‹K jˆ3åQ™ahR^BA,ŸLàÞJðŸö8Œ„ê‹`'ØN8lÄùçžÁ—´ôʃÅ8vp<ÞqÎÈ€ó‡M&PEÄÁ~…ÜŠ‹Ü#ÁÌy"ÉtNÊлZ¤Åv…©÷`²G®x¨¡\6EJåbA ÖzR‰½Ãà”Â6þáô…L&ãמN[t•¾c}À¡ÙQ0/J¬N&ª9¨2è{ÒTÐ; “/¡ˆü#ýò´(’3ÄT˜“Pk㲜úìòF¸ØØÞÐ#šKí\À9€hšÄ(Ö40ø’}4ÕñqRƒUÔÃtWj„/Ί&êà˜(N…ù õ)q!Öà † ì0‡‚àœ’òBˆ † @Ú+aDLœýæØ0¸ ð ŽÐx¡åóîÓà„7TC·Àï p v±Ie IDATSFó©†Ì€ÛÇÉ#~/b¦5xjdž}¯ÜÑ4}àÚpujJAŒ)ß’`pÊø@th/›na0²È˜›âös­C؆dR™ØBƒ’“6dš€žò#4ªõF%¸¢Ò®Ž …ÚÆSW¬)H/ 0µGØÊ§£È‘¥MrÁªscvì`ð,•Ô^Äñ„V@DœÑä [ Ûítºf`.N¬&沫T ƒ0™MAp SXa÷ñ9éxS1rjR&J°†SÏGà JÉÈÌB¸\Bgº¢æ;»¸h¶ÖŵñÖ„äLøåÇ™@¶À.åI ¶|K8Wf¨…F ¹¡¢‚ƒg©ð{RƒÁ1:s|ôϦљ껂…Ž­p ×[`8:µò,žLüPò¹é˜. ¸é€Lш'PùiáôÍMò(*PwA âO°§lXÝ)J&>„fC1ñA( ‰Ï${ ?^ÁðÍez-4Š 9À2‡1'ОÏçKu=c‘°ƒg`/¢²ü¨üy¥*w\Œ!½@*ÚE yeŒ-œ¢Ñ'Næ žÐàð= Ì^„m‰ªVý‡±‰ƒÐNì‰ã±}qü³ã¡š{`S“8pÈ G÷ƒÊeæ*„iÐ!IPÂd }s°^…eb ½¢”h¡<õ¨SSÚ&2E¥„„Å c‹©ƒ?V ÀXq@²Â»¸¤ð4%˜ä|kÔÁ‡õDq·ž§4øxB.v C$Q…<Ý¡0´³Z¨]í’¬rjl‚V(½æ_x¯‰#>X„Lê!˜ØxB ¼·I¢„œ(MHm¦qñ“A¥‡æ8V\¥ß ›øø¶ÈSD/¦¨¸¼ƒsÌi| ?| .sÐN€Á‡³™þêHXÉÅ,He©A\ª d’Ó`— ²öö¼ÄòétüÎi0j[[vz êXßTÀJÜ"ãÛ‚@ÚžïBm{° U°›ªÜ.É$êÕ(˜ ¹ÆœËU ¤„£¹ƒvk\™Áu±i¶0¸‘¾¢äZn2KÚNÜS²S{Þ¯`³Užo@>EØ™­@Á'¿! µP!ЉK (±;.ÀMp8´ÜÇÄëd£QXD(>pÅÍNànw-P‘ð }K(@¸`!NеO¯Ý^%ëÄÕ“,i-!7C2Q$¦)⊲;“èh­ àN”€V„g0¿1Õ ¶dsµpzç ÔJ‹©˜@ ÞDðÙ{ÛHiåÆAhB—…¥iUÁ(" $òU¨ê ó E®0l'Df3j=Âcé%(†b~‡,¦ ) Ò&X0P@dÚ¹Ú꣄÷QÒñ•~[8 9ÕúBÙŠ¢Äl4$ ˜æla‹x4”,^ôì~©`vœ´ƒÃnšÛTNrƒúÙÉßn xåµn¨Èa{a"œ$ããƒ°ó ‚‹‹^Uþˆg³k¹)ÈxB=IW¢&Äí†iwš-¦ø0æd’“0>¦°0“·A}á]_¸¼žH;À”)òš"‚†–‰ÌRP_Œ)i=B\ÏYa¼Õ í``E$öƒq’)\#âbBKôSÜaÂgˆG©= ¦‹™ùðÏ©çb8™ =3Çá®3ðGø¶ÛAu!©ü?ÎøÆÒ…Ï‚îâ•ZLõÄÑ_TÊcé»({F×µ±ðÐM‹R0Š@y‡“i –+¹i0ÐP.PÕñNH8È EÍN›ΙCS…Ìài6Ã*&KØG ­ëš“¦þtì Ê[AâÐü]-°Aâl`|¬—“ ÝÌŽc°aÏ& †[”8ØÆ8¢ÀÊ1$êަ¾ÍP%à~p´’ã4˜”Ž?ÇC–#j{ôA;k”ˆ  3mEw¼Ssšâ`ø ^0DGa1'@åLB°@‚—¯Ž )(Cb ÍŒFe(1ÝÈÀ´aGòË×™ÔÅó4jV—”’PöS+ðn…•\Nƒ]÷н'/PAÌ!`ST*\zZ^LÏ °ë¢J!ÎÆí2q3”àRÕ¢éñFDµŠ—ïþR/Þ¬™O'¤d![XKK”ˆ ö$OÛ –Tp‚bÊ„ŠÊ ˆœÎ'›^ysLãB87ÞNÜqLKŸ):Äuå»Û×\0îÀ•Š›Ó9,ÙCd#…³ä Å Ev]„¶=ÁíetD‘ìHiHa¸ÛîàÝö²Dhæ)Èv…O6š@iQÑÝB#Ä¡ë,·2ó:÷y!‰ºY„ph}Ê#`Rn{ØÁm4ÓSŸ†›{,ªH;ÉšUAÄ]ˆ@·Æø}8’…_~“™º0mplÜyLáýpnß7?2L›„„A1ÐQ´”p.bBÌNT¿”I/CO\ÁãígÁ›É„í*2I:" ˜¾sEƒ”ìØ„1š•À·¬4ngŸº&×¼aF¿½ü¥S¬BÎ27¹OaeÀø¦d×ÇøâÝ$lhN½·¹íÂ5 ±üC‹Â!6p XB²Ñì>±¥¼ŽÆqj³w÷fAcœVž–EL@oA#¢EdL8Ÿ5¸db}h„^ós H™®ÝÐ(jE\³CLJÛ]Ë z—À´›l¨Ü} v+5¡øñí\Íu1“˜ 7PÓ…ÖOo ø$aÿ ô‡ïdu‡pÈ£>`ˆÈ;8L©¯·tMÐ…@¸‘,Zʉ(« ƒ¤’´|¸ÕÊ/@Þ `d˜ø7°kœ1+щù˜’ S8;™Ï„§ö"t$pŸ¤ÕEp5Ý])è­æ‚º=R—ÜMašÝ¥é¼unèfœ¨µY±Åé%Ý5w[ &"` øFAtSqܧŒA\ÐypWLµÁSW•Ó\•¦÷çXz§¾íD¼="Pön|i@£^Í ÈíqQëÒ‡€í`“§»Cl”X€[)Ñí‘é;'û“rë"h`w§0ÚIóûU蛓PwØ‚ÄÈL _€!ü)H6V¸ñ†=Ôêô)Î>yàÝ$p’n€²Œ¡PÚX(6>‰‡# âR°mÝ™øÊGœ'åôñÀ¶w˜œâ AÏýö{³°Lhn óü«\Ä¥ò÷p^Æñ1¡>F_¥Í?Ó„ëd°‘R9aâr¦ 6×D"*y”;ht¸/B]UžXÞ“T IßðULÀíh¼§ÌeéöË|H?B\Xø(•¯¸ˆG=âQÿ†ëÐÄ û4º:äƒùôè÷ÚHË ”îxס¡Á&£G†Nph$Æ&aÊ5ŒGWî)(ºËÙŸ¸¨ì$7!¨JkJ…@ýfíbî+ßäܱ “»ûƒ+toï$ØÁáþ2ζ»è–HŸ¢+gÐö`TTáÎcÒ¢aÛ-Nví ma[gÝò…>ñÒƒÈæ00laö„ÿ“È–(6ƒ)2!ä#j‘)-9,å8F‚Âú$@Z^0ü¸ÁYÆ)ya ­5 ¨DBƒ{d¤k Ë?1¡7CzÃdೈ€½ÿd ÐÌÐ̳íMZÄ­[鯌~ÐyÍååÏãl+x 7x€#> ¥÷~ˆÜdÒ1‹z\FóeÂåñåŽFO´óG†jhVgyˆ ‰ÁCV–#¡ž\Е©é$Ò^ƒ³Ï®¦r•0VN¼O#¢p ¶Üõ1¡½‹ƹB4 oŠƒ>i&¸a¯Ä=M‚&5™ncTÙÍûävah š‘ø`‚žjM„Pj\JëNDä;Aû'°|Shâ“ek1I¹ûcÐÅSVƒ“Ï‹peƒ©…Ò 7¿.ø ƒ’êDÉ!¹°H‘¶4¾¶)&Èà  ¸´N”³Q$A Šêœ£Á’‚àýàfà„ËŽZtÍŒö4»Ë†3CÃÛ¼YÏ-~PM !ÇÆƒ‰¶ –÷ (ÿ„œºRÃîì°Œî와•tTXH/~ÿ :ž òâ$Î4Pž1N”ˆê¯o­ zðévðÓˆöw·R`·ˆ÷0àÀܨ%_ñiÀd1 aX”¦ðÃ]ƒüýxÃi…§4¡2Æ;´¥à¶”§¨ñ›Äš*Ðu/ÖÌ ô?‰½&8’@MĤNê`CÒu5 ‹—‚ †-$¡P‡Ü@à2R #Q#>Ô”h/ð#ZDCy37nZrºE€òƒ‚â1Ò£+‡hÀ“N„稸sƒÌ;$ljLZ‡{øŽ»ÑÅŽRÄYÊ7tŸtZd8’¹5š@×Ó¢,…£?Úg2L2¼ÑU'8f&0*8ã`pnC#s‚Ýhi¢¦Í}Bª©/tŸ‚Ì£¼ãN¤•Žnìp]…;pÆ»†œa)ºíEÄã/Ô¬¨/+¡¡Àà iÚ3!q}¦ð[6k—º9Âò‘^aøUÓ‰ßôúF Óu´>¦ÙBº†zW!ºR¸jÅ`ܦ¨dÓ(<-`ëA VµW+@ÉḊº”-ç&Ab@¼#çãDÉ·iPŠÓPØöÓÎßÑ9k­ ˱”"’ ‘zŠï Ã/7<ÃU“P5‰‹ilá’€KE·Ál‡½ëcrDZZ;4x½u]\>G´ D±ä“¡KYSX^ߢ /È„Oà‹Ž+Lg/0îJבŽh·¶Q¨¬º7¥Ï5ô4ÔH;uúŽÆKa±å´Ì×TZ‡b ·¾¦¾¹püm5X*Ê_àsŽ^Å”Öv ­?ÔZ!­IØ¿v9‘†PòÞn½R‚Ðü඘ÒÈ®ˆt’ˉ¥Ÿ‹e !ÒpùÑF:V8$)ÂÂ]é-êÈtZKÍWŒ¹,D¾ùmÛwÚ‹xÉ÷€½-Âï4Ds`\|ÓE·Y:>‰è)”¨퉻 ånòM@‹!`Ê¡#«É ]@MXaqþSxèâBe¥¬Ýú)!Ý›ÙBflh§xÚÕÁ›"¨d«W¯ØâöaR{¼6ÚÖ`BÚ¡Èa´‡îBév}^„»I ܱ+àÍð^JcºZ—k|›%{s¦pß8‚åMæ…|uÙÀ”I¸ bí"úù>°C‚u¢<Ä$™¸ïüâ>@•Û©((4ô§¡I@ãø¹íÆ»ÍÙÍ1aF†ÑòŽ&…v2¨§ù vpÝú¾‚·#U ªðôoèÑ.ø‘•Ö7Äò®à¶‹Šfó wP{à…ÍïÃßäoØ@=ZÅY€ÛUÃ3WºþHÈÇÂÄ»:vcÓqX 7ð7E>‚oWºˆ%xèø7öA'.iÚïm#©¤Å'…C}X²–ÏLnÌ5Ìi—½qü®ÄÄÛ‘Œ¬¾N&Ìðõ ‹ºˆ`¢æä$œfZ*÷8å`Ïø©O¾Å\ÛSm£Ü“Øk‚p¹_0!Ïi5Ð<1q↷#¢œ«§Å”¤ #Œ!&ØŸ–…œ„e=à k!_‰RŠ`l‹ÐדT^8Ó ðœÍR†Å‹¨ Ô&ûÂ^'bwÃdBî@£ £äB|×eþ ¥GVha‚ ¤w0MÄD…´Cêœ$ÐxË1äjmÕ‰NûÁ3ýÜ4“>|úªa4Þ€.A6\ùÛ,¡Ñì]B•¿½€t%Ű,·kq7F7MSÂMüØ '1ý§@BÞ ¥ñ=d÷)…ï?’Ú¦¦ð-µÉÚ¸â‰H|<І6^ ‚‡m+‹´Ý±‹š$ QfWßüMa2Ÿ]‰hölEpkº®!ƒÂ}¢bÇ£šÆ0/"9.‹0~Aó"fä¢å,h|R‹B ô#ƒsJÃç ŒÒ5ÚÆ#† ”¸ÁaJã ÖÂUƒ­@hÁŽCr3Ò7 IL„Z‡¤pïkßÎ÷Eö$ÄDWz™¤‘ìß El0Á›HƒKî4 TuÔxôˆøO¡ï4|"@›Yàp© /²˜N´Õ:cÒÇupìö×%±M9%)0䡹0 ,Bãp á½¼g¼ÚÅ &L ã ¾V’º7Û‹0ßÑ ús¯PƤÓpñ|‰üA°ÄÓé± •ŽK#p›@âÐgŸ7ÐÅÆ„rl e=é½Ðp…©‚­–Àu¥!Üõ߇´¬´Öt×›,'aXL£ÑáD*µ=¼+lš4–@¨fzKÂ9ñ×äÒßÑå—|Ò¬ƒc qXLH}£.LÖ¿ Ÿ` N¨ ­bD‡À?"Õ.=âÇ”žºªÆ×àHo·@òÐtè ¸³ÑtävªÙÂE—Pbª…p8:œ¯a|ô%ì Ç+,Md‚ÏãêÈŒÌ 3¸fp~¿£·ç|¨¡iÛ¤+F/ú0ãz!Ò£Êr ]Ü‹[†žÂèÁƒ¤ŸÇV ñ”Ê)2¼,Ì^)!ôê XŒKG Gcã…CØs‚ÊæR ɣʀ}ÓÛÄÄÄÉ0\âVù%¾ôìãßUn÷ an‹¨@Ri`R£žÆ5¥¢äCmcÜ—þ Ïû´âËD¬GÙ1_ÉHVÔ÷ ñ¼82B ƒÆœ&5¾£âFS©Œ9`*0%@ á3\ ‚MÎt}@ \M2–#Jà[pï4ô¨ ÏpçžÙŸüg6¾¦¾„€†p@™úÕô@[¾Æ‚¨ l ç4€U2ZQ˜{»|Ôé„ã€óñÔë}Ï2 Ò5î'Ø3á8Tg ëòޒİié&pÈzkBú˜Ç°¹ ]NðJÎI'0! TR¯“¿dš^˜ø |S:åCvNCcO]Ø0„ï8Ìøµ5Kïi0Ãé^˜·h‚îDIpíÍÃ/w@ò½aækÄ!6I;ªEHÅƈà¥ëcƒq«/$gíÀR$ƒ¸ ˜%€·ðÔu÷µCÛG$gÞNÿ¦'àn…RóO+á "ÐŒr’ê;t‰)ZÿD½ ht]¤8 >ˆ‹x5 ÒbMÕØö¤$ÈI€ìëQåñØÛx€‹F3'mD¾šæ¬Ð ²á¶¡‹l¸K'&¡–ñÍâ#B¢æð-ÉŽ(óÇkpö7=à .­Ø\@‡˜Ã‚œLpEa¥@¿1$áOÒpÛR µ`Ò>w×鹯¬„3bX“R¸,Ñ%ƒ­D’…%ŒF™˜@Å„Ø"Ê0ª‚ˆ=ç /mãçû21ã X.@lÔÁ%Žž'd+BØÜçyþ0JAÓ‚öƒÔ–ˆXtR²â Vˆë¾!Â7°,À`;ºbq¢‡÷1ÅI,%™ÐSÜSÔ—4![ÐÕ¨pÌ·œE‡kÞð·±acûðSš`¡ÀšJJ„‹@xJ‹[nâ–_ƵÛóƒM2èñ~`ˆºázEÐÀÃã1”:zlVð6•Œö¢¦´E@ªxI"ÀB„å·ä¤Õ75ñY„ç.Àà°#Á^9µJu*[:®8¡#¢Q…3¦€É5‹G³„Ô&Í ºÖ'>ekŒú~Òã¾VrsS–D°ŠÂÊEP&9é0JÔ\a‘íZ‚Ì2X\ªh”8æøRù2…¦'†=ü3ÉMiÉB,¦(>:²òQßOƒkLÖàŽ¨›‰Y ¡-:¾¡þÿö®f·’›ÇÖjTàEÜÈ è¥~‡¬úýßhú–DòœC–íêÉ—d&Vßö­ÒÿD²$J¥ëºn(T†?THÿÃãJªvº‹VVJ w ÀŸ8»Ò"š¦BEA4ï_¢¡á0M&/ØÇ¦miÁ ÌQÅkØØÛŠ$"Se6øŠ”̤a£BŪÈz$VCä8…“yW£ÁüɃ®@"…ŽR%„¡!ÑQiφä)6È{ÂFãx A£VP¡ìtk_Ä«[ïXœÀûÓÈò*ìtë)¿>Ðp0„Ð"|b‡$ô$‡{]å„%-°ÎÔË ÐÖ Œ3¥I“FYz|r£‰«ØÊ(ºélKÑe•YÚlZ`‡ÈÐyÊGZ-ÞÍù mÞ—)€rÐÝH½a…0‡øød,âùƒ±E"}¯0µÿ‹DY6h¤GÐ/&2E},«/ñÔ>”tiG¡­÷éŽ(‹“ÔŒA£2öÀÔ([P&yókc¨ Ôõ°êvÑtk®ò!Y‹:ÒÃ0¦ ÞáQç¡Z–3¨r#a?|°!Ìb&Å*Щ‘Òô M4!a&KêM ocÜP`oMhÊDzaY0ÊÛ,òžžŒcÕ Ÿ†ÀÑ™høÈƒ|õ§ƒW¼$+Vá|ÊW[£vF—Ô¨»å]ËZ+sŠÎdi'Þ†ËÂEt5hðGÏì Ý‘»X’‰ƒMo™ [? ìXž$¶ì\“zgݸ”¦2†”#ÏÔï(,'IëÛ†\¥!MDS›JaÒÔJ)ç5C~M 6C¥¦­hÉîÙ˜bD3:!\@뱈égWšóó†ú.2úYˆ¿l˜fOf `¢>¢´vØ€RÌ®:´q6h§0.gy#V¢¼°h¼×‰.¡zTÃÆ #^ é+Eè¹!c¬cí ýä »2™í•¢k* S‡¶fÃClÜðÁ|^„§|¯‘Ö¼) /ÖD@ßÝw4ŒÁtÁlÖ`D'ˆ¶£ÉÄko‰Ò;ñ~°D·¯ˆ…ìèŽÕj¿§¼ ùÙiÛBóæøxRÎM´ ÿF éí4ć°ä3+âi=ê^@ýƒ–)ÐÔ+2‰ÆÖ©ùßöÉWj)Y¢fz,˜B6‘ÔN̤U†Šþû"Ðf¦!É­“¬"vѲò­;áMáWÂ7ÓN5·ýuž¾󰘨\ã’. …Pü«  !,zƒvjFL(50½ª~XͰrSB6(R"`³³ZQ‡<‹´LBHbkßõ:[·öŽnÙYQ&œ?q~ð©¹tXO=áä„EQ¶‚Ÿe¦Ÿî‹4ÆOÖãŠC!Pº‡H¶Y ÆœY{I¶gu:7ðaGC†,Q(pF ´CÝ‚—øVëâÜ¢­míðC$ŠŠM370øž\Ëß’›Úd•22#¹rôšåDÐxkt^Íïh¬3ܧëÌB‘¿J;LÎÑñ‹8Ç9ÎÊ+C›ÃÉ:òtÁÃy:\ûš2ÚSçWSñ£ƒÂ!uÁº÷ž Ÿ?WBÉú#SQl@'£“A¸p13SüL×E׌![R:aE…ÔϰÁ†Q’,ÖRW°hÌynê¬ë›ïhç˜$¡gWÒi–q,_¸B:øÌFð“çGû'e·ÐEØ'ÆÄõŒ)J‡ˆ’ÕMª3%™•ÓÈŽð3@é,u:Ù«+¬B–ô*J$ q¼:Œ JE>êRG1È&Ùè:+µ(ûøœ à<]ÆÇc/þ›žHA&DuôìJä§;O2^¾UuÁö ì  :´ÊíŒ"ÚN‹²ð«ªŒ©¡U¸œ%U‘ƒ’)U©ØšÉ8AåüT†é|أ󪨲Uùã>qj¬“(äPJUtËBA"h¦R§X”Ü=/À=`l%Yƒ„¶‡ÿ‹dhPÇÁ6è„IVAsX,1#€t@å.^ž!œ? x‚Íkº妞¡F€iK×eW¨æSetpdë Ïâ IDAT+6duó!¨SyÐíÆH´X0Ú“UÌÐÁÖø‡¨3Ôݶ8Uf+ˬâ^,"¬ûˆ)Ü åêìJoº®=Ÿ=·œHTn*Îm•'@47Ã`ú"u4v»)H _i¼¬«Ä”…TŽr°Mb§Y>Ÿi>î­¯ÕÜK-/Ä’¬kÄRHRdì1ù€7ÒÈtF"D6É%pŽ£§›¿£á]“¬=¶|ÿìÊÔ”ò³y¨'L&Cåõñ´“aÓÀ椞GJÜ•¤èÝ©¢…[Ï]x†­Ð¥a›¤²V«röȳ >×dÛ I èKÐë‡û£7JÆø”h7P¡™¬KèHKÜÿ9?˜ÚŠêL?uv%B+1[aX˜*ýYÄb¦Û&¾UðD}­Ñà°epâ,¬h4!\罯ë’SÖ¬î½T4úv^Àæ%´M²Ð?Uœ¼ªˆ[hT6²Ê€ÕÒH@±àLvY„ÕÑ0ç[ïɽÅ(' ž])ƒµÖœ B/ R6¨‹ê$¡6Ägñ%"@²³ÎU`‚ÁÍ€!(5âÇÕTâLª­åta/ÀŠ4t‚ânO×XØBµÞ&Ða޼j…[aÇ9Ck 9Z!÷'»*7+©Îá"ÜÄ"ò÷äÔ¨@uŽQÈo{ËŠæQC£Ë ÁøZ+Ðøp‚ ë\~„ù,OÃQ¥Í‚ ÔqDê¶¼áõ›Å4j†w![²qÒU.dÂ5?G¤[¡ ûƒê8™ìlC±ÁZ‘˜U¾'g>/-†;&Ù±€àˆ¡ha‚tD³ôõ—Ù‘p–AŽò°Zu³–|¸ôªQ‰p;;­cáùGûŠÁ(®,»µì©hèÔ§ž(P¢¾š!ÃYÏá±S§y%DÜôy« /Ŧ΋±ˆ‰û"Fÿì©DÌPÁ.¡€èý\eYE c=ãÂ$¦n,k#=FZô¯˜Î ÊsÔc/¡hTzž¨cÒòt„4̽ŒÓE9JsÃÞI}ëDÀ¨Z™“šHò·QÂLê Ô™|3$ÂÏ5¹ˆOúMãú0´ä…$]Ý0§cAdšj Ю¤€RP²U)Fj©è s G’1æ7Kû µŽÅ*2z„SM±jrsŽšMú¬6¤BÎ6¡í0lŒ+• «¤7³R+ð}1+¹‹ØÐŽ#øPñ“^ ÙA:ñK¢Ç×ÓPÍÌ˺ÑcÔÙÛ™ ʵ‹§ÚÏÀ® ìÒ6›}£ ÍmQÂêëÅ ²©/x¦D–b.U™Ìª{d 1”ŽkM‚m0{¶rš?g˜‡è»‚hCÉ úãßEœ{Àg$Vˆî]'ù.Âá0¥ÏVÇÀã Д€Èm%ýW è’f‚ªÍcİ=ÍEô,(`çù0Bå"Ù2É›PÀ €© °5‡´7ÈÀži͉, ãæ\cßfrrÒ < söÂþÈoÛGó£§=üN&½ ‡ÖD½àsÒžN5QÕŠ"ÖtÍËRidDÿ$gÒ}Xîò¥•j-pE3º”}h7hx§+˜³*å…qü=0p¬&¨œ»gå·ædÆmù‘%W£\égήqp}“Œ„IJE7æ^G[©%gÐivÃR,íal÷¬ÃGøu<¾ CBÅⲎ1“ËE'‹*„^pæZu—cO°ÎSÕm˜é.ö€c@K6}ÆQÁ@Á­›…hÜ…ÆÕy©Çàá|þ¹w^DPï>ÞUßV– Æ«¶ó_Щã<“bå¨qêÍ…™–Þ¹pÉ3;²tû¾†iŠÑœîÊÀ(;ÍÙö•ô8ð<ðáfæ£F£:„"³u6¡`Ò¡vÌ“,1p¨ö Äe£ñ@Lé›{¿é¹ZÅû=ëAù”Q6­ÊÞ‰†ø’À–«³ò©Š‘ Ù¦D*Àl‹õÇhSY6 v<‹-ÐÚ¾ªh,p•y2GV–#M(ó›2ÙUuGKÂÝ¢¸CX¡gbe'e|unÚ;±’“hK¼œ À5#·„ÃE¡×Cñ•®MuîWÔ_Û F žæ…¯·V‹Êp›tB Å+ÇËŽ¡0_àFbƒN· fõ¶ D±+aʨÄ!ªý‘¢¬Ì9!¤ç–—Þ‰E¼þⲃ";^*GˆuQ*óz+Jb-¹ æ¦N^ËŠ €ù6ÜÅÞÁpZ˜t¥ND•…‰7S0Òoô-r›)åRÅ#íxZFB!ìx“O‰%†²QÂ{l°Wkyª„>@w¢(ïíþ¥FHÁ•ØüŽ =º$W›… "º)AÓÒ¡Þ1±DZG¶¡CØŽŠ–Á6’iL‹=Àµ‚Ì‚øÂ©q+oRìf ^Зûˆ5¼ßÎÆDA½X{Uz†Øt<±N2e<3 (á'nÄ"èMOyLîÅ]í‹"' ÷Km–}c<.ã4Ùœ/¬¥•™2Hv ¨³11Efmä0¬S Lbj‹r,¦Î/Ñ{Ž ‰£Ó õTõ±R=HÊœETD«/ÑŠ‡BŒ€\XŸôE™Œ¥¹þÿÄïhäb™e KGD˜—^t÷&Í!Á¢¯‰êKÔ¨¼/fŽ‹¥îïú…㤠³,‘>¡JV܈¥NVE cxgVFbPòþ/:,ÔQ.WÚÒ' ÍK¸8ãRìQl;À ´•„ºHXQdꪦÜ|GCœBYœ;àºh+¢^ÚÄ.͉p$¼¸ÅàüäʺI«±WıeùÈY¢>€ÖÂYÜÒ¼ŠÕ’Dß5×Ý-Ëð…kW.$l‰å$…ªQ7`(€Ÿ#ŒQñ#s9u<­_ã;&‘½¤´¨›h Þ°«xð›±:ÉYdyDHéRÁÙ•ä2s@€‡ ª|Þ¢Ãf õÁÙÒr¡þÔœm8¯ÅǪFùBÒ55¾$•1àÔ’ì© Ï¢Y*U‹‰Ì âäZáÆ_†eC=[¡'ø…`ª‡au…¥ÒUÜDcþj%Hz¤gWî·ŒFúõeÖiÕÖlƒ‹äàF¶Ï8¬c]„bäÁÃÆ(ÒBÊ0ê5Ή¯` ßæt 0ò%Ñ7ïߣ†Ç픜ÁÀÄÿ¶»JS<€¢{ù„»É„ò=¤6e‚½a(ßD„ïàGy7…[GÍP—·o$#"ÅÕaçõÍ}.¸Ã•b»´Ö1ä\Ê  j¢>Ø‹ÀËîüj«"Ç8xÝ&›'b†Ñ™ ßk²zëc]íù‘®èrG-À‰'.Mò®cÑ¢íúìµ]bÜ ±•¬‡Ê‡FKŽ ×ä‚ô-ˆ(Ú·¢÷  £Û›×ñd…sB»NÀÏ7ÞÑ0ß]9øìÊ¥«qRåX>/£2Ö³+Q¬õʈØI+ª,EÐI3,s‚N²jËnFÛ߃NP\öây‹.HœzCu>‰Èʆcö´XքЌ悊X)ª£üjÏ‘MúŽ .y4­‹1üb±;„ŸxGƒ-üàÛ"–Rl¥2¨ŒTT“–®ß91ÿñG‚þƒaê¤Â„dêP“ƒ¼î'Û(R¬àRÅŠ2.ŽH‹ ß[ó¯F*4ášáV’2_‡X@ó4¬r• F»Êlñ>ÒÍßUFéµpfÂÆàËT&elo•(Á™2Ü[¥Üé<ù¥™OD¯›¯€ 4MØ3*&T%–ödôJï<t|¤#ÌŒMÐzr5¢&ŠËs¸lV¹à@ó¶°ÝDyÛla€åaD¯ãádºÏ™/ŠAË»ïh@Ç à ãÕEŠJ«ŸÉõþ„ؤý@y¶ˆËÿÖ«Ê_SuÞëp;"€ñ ´)šÙÓhWfïÇ(™J3·\}³³ÒCï;Z’V#/ 3dyEåw£›û"pƒzG.†„#sVrÈT= 5Ꟗfw Î_ùõn1žWå­(î.s¸µÍÑHh‹³¬TE.ðÄ× L ·Sj®ue€MñuX¤&ˆq⪵J[ƒX{{"³(­ÒÈ{ê×#ÝýMOO‡w…蕪_NÐcÍG«õ½2Å¡U8#¾p†¬ZaTN¬Q-¨)kVAÏFy z^ØîÏ3¦Tb\‹JB2¡ÝÖ>¨=NÐ!ë{+-Sƒ^p.².Û{&=ú·IqÂÊäÁÓü™ßÑ8Ûû ¶!l,¼1áÌ?”½Œ8ÕpiMY®³\츼È:'ì#qqŒdqÂfT6ç˜ÃIçRr€‹Ý;6yÀ ìI˜!ÍÓ£àAX¬]jøe‹iÎV%Ôkß×¾€Ê Œ R«ÄJ”ÊP.Øùü:Õ'hÞ6c.óÏ­XÄëpû…•ŒÃÁU{…ns›þ$‘e+4&oåÞêdÅV.jgý‡Œ|…dÄš]¹0÷Uû±à´qƒ[&{´’"’u¥0ür±È»Áõ±%sŒ —úZ¤²ì\l—à\ø‚"38ÊÖ”?ˆë( ÒI†«6?]¬sÉ7ÝDK§@”³kK®©§TA¥S@wßÑðVÇ(=”æáÐÃU±‘åQO‡÷2nu0tº°R'(dG•o2¤ò›ºØp²Þ\;Ö 7¶h–ÝO y€pQ¾Å¡;N#uLs4'ñ°ôÁrŒ¿Ðüɔ͗ҢötcØ(}aWg¸¿õކ;¼Á.!­3ê|âvZcƒÄÛÖNÌÂsÇÈ6ú£¿ˆ:Û×€+;0Çy ÎuÁ? Šãy܉áT>"Þg\{Ÿ(à šepSÎÉ‚cîÆ£(9Þú ûOŽdàðÖÒH2dû ŒÅ–Oá"L.ê@^s ßÑ'³Ži_<ÒÝ}0úδ¿ç lÈÄ7ØE«Ã .ŒÅE‡CMo Ëm‰ãŒÇ’ýùüž…Âç´—x8‹9ve÷CxÝä"àdÍ,‚v<ÜÀ{‘<í]¡®×‘& | YrξHÁ§œ¡ *ú`Õ»unÚcMn‡öRœš‰†R ç„O«q0êpˆE|â2̉‰ðáä¦Ð ²8þŽ ‘$ ›Cr‡•Vm4C÷V/¨Ýä ˜à^º>RC/>Ù Š¦ ÇFÍ/ÄâcåÒAŒÀzÂ9_¤-[x&Ú2xUùƒçE8ÍÉ!à±È0zòÜžp ã—è*޼HÓ´« °^ð(h l3ÇȵóU*_æXÂQz¤³In$NË÷öiGÛP¹8+O¨†ÝQɨB¸KQîÆõ®'FµìŒD[Bßäƒo¾£}ïC”#쑜W˜þïL,oà˜»œüËÞ+yØUì®ÿ`èãBGHž`,gšDá Ÿ¸N‡Ô‘N„`Ål& ý!zò#gl8~LºÆ€ìá/‘1’Wf\4ˆ¯,G÷,YGýÎWü‘¥œW‹ØDÅ0nî‹°ÐŽ>7 oÓ;±°ˆlKÚD•­.–ô®/HúK¢=ºã|";a+KqPN]۴Έ]ŸÙ§(Œ\â8„ êà ‡…¹ŠŒhÈ™³{w(…VÈP! Gu ¨pa#R¹r±sP€P¤rÆÎp¤–ç¦]Ç"bm0T“oFw&%IûOØ´³rÁn¾àÀÀ‚»g"V‚Œ ˜ ÜOqM6ª\™¦´õBé XÅ_{I[PVkE[ˆîX½juÅÇUaé )¸µ/âµÐ0Qs‰{xPmXáÅÊ6©»(j¯ãà¨n@HQ\Æ· ‚6;h…æ‚*ð! Q‚°…J”tI^6„Ù;͹/lí«Æeta\Äým‚M¥ÆÌ<¾îýŽFÓœX¹ºÝ/†Œ[\Ù$‹™C.M¼ SË´2(|EäþG²8»]úŸ*Uâ/S5·jX¥çØ !ѪÍß'ƒ¯Þ°ÚBÁJׯg‘Bóñ¾£é'ή¼ÔìÜñ{m§ƒ[ˆIŠ8EçùâmÃRzµºhnÓN¨qñ¢ éÉÔZóRB“€Ì¼bZ×ÊÊz*|ÂNv±K¥µ67üc„–Dé€ Ú%àè)ˆJ"”IÆßU~‰}(Ôã—ö!âgaI ÝO«¢l€ªˆÔ àñ Õ'ÇC´gå}¢Úï¢C@¥å^„¢¨ú3Œá˜z&!ÿU›#Õ ¹S kì ÑÆ_±•F7ø«3|¤÷¡é°y3PÝŠEì_¥ôgίžddŠØ‡ûØæikN‰/+Ы(*Ñæ“^±â¸“™ÕÁ0ü¥ŸCŽ™IšóAÆ0|;m°? gM2z£˜ý¬ny[¡9¹ všÔKGø0…õcÓ/Wµ‘‚q&Õ,â.zͱîîq€"B‚;Än¿£!ç_ÑÆ¢G犺Œø!ÝúÞÙ™pïZòˆ½ô{Û‰¿ÛuA,î,âÔi#¹‰ë¢$ÙéI® · ó 3,,; U3üôa­oL"ô`Þ™âÁÞ¨Fdr4ç6ù¸Ó›*š—/q§ý&ëm´zl™Ð,_6ådXÌ‹ÛÁHÈ¡Ã7ÓS…‚¿¯ü¸ œ–^µLs%g)ª­$„òTk¢Kö÷^ˆ‡í10D»Ï°I×Nc4ð™‰Ä‚=€g!ŒVp˜:‚õaH6Lõ8prn¨TQ@SÅF÷bÁ)+ÓX8K¤%†EàLzÎ0ÝåžÈ—DDˆ÷Öä‚ŠØ ¶ÁDXÞ7àE@;sˆ¢™Ás;ˆÜ Çbåbæ¹|×#)ú#Ht]óËH,2Ùe·~4ÇÓhŸ–€i>öÎĬFI™lS˜Ä† (4»ü‹ÀŽFP¬CÞC.ÐØ(Š.ÄŒý¢ÝŠEäL.ŸÄÛÆzc}á8à"HVl“§q…i.”ïGðî_GÑ˼6½¤Øÿ¤¾xÖH{2ÜÅ©3¢ïêæÀóÁ3‹oÖkŠfdQÀ* Îa1Õ.#j‹­ïã¿ Ê!¬ ¶yÖÒöôS¿£‘T‚"û½Án#Ô¼(ŠùÃÝa,¨â6~ËõþåŒsØû\¡2.Üç3ŠŒÄ<ÇvYp"CHÖôŽÍ>Îé1~¢I¼¿ã“òa°h5Fq†ÛËd$_ý@"mÝEÁ’Ñ’Dõ¤´â¥0Ôð®ÒÃuð_@ˆÎ«Ù<ÈëYf®›îw¼Ø;¶ÁÑS£<1@  Œ’åo ]fÎ8lH¾]­Éµ±ƒó"ÓvbßãPa{Yx]âÒŽd‰4 t´œ]éÛø²"};3ÉÃо1c x{6ÏŠ^*:('S$,ýå?`ˆÎlŒr^¦ÜÄ’@Ôc}ƒyÑNØXX‡k>HN<–B“Ñâb@-+AG^?~뼈Õ.Þ(½t‡ç¾ª×ChT®Ë~¦- 6ie«­C>*ä=,EÏ)]êèG#T7´ƒ>pc œ<¼´¸Jn æ²ÃXm±òÐ6#þ(ð`RSqH¨è'~Gcªñ¶F†ö8øÌhÇÁ1 ÐÁÀœð¯©gµUVîZdÄ^¼á”9’fù· üœŠ+þ)óFÔ Z̬ä½Mý•˜.ŽSu(M§ô("FF y„8‹¼òÓɗĪ'â3$8p­qèÕ‚ÍD—k–ï_:òož]¹-Ïé<‰ƒˆmô„M«™è^W.G_Ä {Ž€ÏywÒíÖÝcÃ}=õ‡I u>jaèF@…¨QKÏcb¯‘©Á§ ›X ðÓÉJÒd Q‘8÷u·ˆŠÆ°ÆZ‘o}ü!É·ŸòÁIsÓW=Ý ÒCMXqãIbt'4£Ñ{óCê„,œ’ÚѨ—ÃHd£a‡!ÉR\мÒ ]²i­Fq+•jAÖÚ<Â÷º™T†µ“bCn\¹“i –bØÔ lR¬·[ßÝðj ¾ŒK$Û´@EÓôÆeÓ¨.h1·iu“´²~Ô6;vÒ&Üx¿a¥|°æ† ÷á·m´WÒÈ3ä‡f„i4iRi È™HMÖRZ“ ƒ¥²d‹2É’`úà[ &ÜÅo½}^Díç`FKO· ì!Ži)¨v–‘·šR€‚*Ð.ÕÅ¥%´Ð0…Àà”°TÌ‘œ 5·„c/³,€@!£]…ƒ:4JÒLp|±Â“0é'YZ!…Iâj=r//GÚ»÷öE$A²˜V(,6HÝÙõt*™nVªN4êRÓ…ÏÝŸ7Ù‡‚"£„)ü‘4‘çˆwå*?Jš&Xü÷lç‹X÷Mö*ë+~böCÂOôÎ#‹»9>kBÀLITÁðÛú1•'ΘKÏžˆ›kr¶Iòpîttéƽˆ÷œ‹û#79i›ÚÃ_ôKIQ#s8»à"i±"Íœ³÷I‚ઞ.]1M¦µ£G'x4ü# Y s•Ö ªQÍj. IñµÓíšiµ¸Ú£gLB‹†Vº)%%]œ›ön#$ú0© %±>²1+ôs"è0ôv£-E1Ùl WꢕƋÕW°6e èÈ 3-š#¿Àp´ ôF:†S†5D‡ÁVö#w7¾ùŽÆn¸U‹V¶F蜟&¶µ9xÔã`Af†l<$x0)È(ˆ%þæ ¶]$Á&+5Ù¤Ì Ä¸X~ ndÇä¼Í¤È6É¢.§ÿµ‹Š¥¶LÝèð)éPSÕkKœÇ¶PCWðÀŒ*.ê‘·”¯öÙÍ}8â_m]³NCðb9Ò’ÈöC±-Ø\’c\j9V ©PIDATÿvK³¦éÉŸ^6J("…q,UW þ%àéÖÚ°PUú2Ƨalƒ¥¿‚³ âm2³9ÎûÝ—HÀ öXÖ„‡@åDà•®ÒJèvÿk‡`D»ÅL¾ó¬{Dç Z%÷¼ÍÒÞ¨¬ÒˆE p/c–ž5® )‡i`MÍœ]HÄû¡sb[} ”ŠUŸÕû eTăîÐ ]?@xm(àq©"¨x“_aÛ°ó†}dvHûjaðôH·ÓóLꃃŠÔWR§äœäãù– -ãB|reKl.zˆs†è]¹šá”WÝ5¹ƒ0™ÿ•—ß@Q$ ÁXEyñ7™Ðøo~1~P_æh¶UðÌ„!AžEb›9“ŽÑ 'YW šA8öý l~ò߈ƒ¶!š¦çRâáÑvQŒ{ØÄî.ذÎy‘¡ °%Ž“ Quå­6£FIQÕÿN¡"Hx€aìfükpZa\?qå¢[\ÓhæñÙ €e‘Z¾Ã"î'¿Í 84¢|PØô̽Q®ü(%ÝÿMÏ3åI“o]ùFb†ÞÚp§J?fuF‡ËOšK÷:HZÔéʹF(T™‰çÌ\'–ÁËRed>Ç c­!´‘4&Baí¦ ¡±É¦á[÷ ×9ÀÚ%€ˆÐ‰“Fg¹QK˜Úu’7ï½£‘=3'ä;9A‰eï›Ø ãˆWD¤Ô(æ¸+S¶Z/%Úiÿ–#‰›¶RL€Rp¦ÏN<~a”HÜùÜ1B(µSU纲H'ë‰^"û1A çˆaa„Íì㱈—õ{rD=æ\šItµ¤‘ zz)µTíó¶ŒGï¯~’+"DVë"yÞH#³4M~P@£½12Ê*C”ñ@^–&°?`$§ Ù ]œT—ÉU:€ÕÙ–È–Ù9³z™ °D‰¼8éÊ»±&·ÆÁu©G¹”R$ÓtÊœUÞ0l¤^øß–Á¢`誨ýBÆH…®8ÊÚ“*K¼‹Û2]e„ª ‚G»U3>´.þ¡ùDèää ÐY.V°@:! à„Nmñ)ÜÆh 9Qp;áPã]NQRâKÝë±ÈHÃ>õÁ£šÔ ñÕl^mí tº;%!FÀ¢Ea blí06hÑEБ-’|RJ ª ´®Ì¨Þ—çÅLà8,ª(OÈœ©Èå­# ¸"æÞo÷ 1T.š*’&ŠàDyÃK' d…Ò-Ÿ1pšÃsô)gÒM°Ì Ž3ŒfÖÂQRYt«jèûõÐXO¨"nhÎßõ‹±”¥Õaó~6 NÃKå«gºA‘®ú‰ªúؾ‹x%æBƒ"È#3Œ†@³mЬڠ1MxI‡­$Yæa!Îôär`|hJ˜Oó 'š®DŸL”f®a1q‹2 œ¡olìÐËlÍ‚ŸˆDw£¶xôÏLÅÌí¼D2àM+ËZÉc¤‹ÎºñŽFøà­bq€åpK¦”4KøÀ¹Œ¯ SrîC·]Lu¶:v[èp*’hèöÆU=iypº>:¨<@ѾPkä#áçó—IÌn€¢ÕÚ ùâU¨CT AÐ.ò‘_d(%§osåñÿV,â@@Ûɰc‘åQGf¨<ç»dj…îýmÉœq3ªšÆjeåS@hBÂPvû†1±.=)KLH¤bd„F¨·AO;J4±S1i¨ÂÛñ#G«°‚§û Æ8:á¸Úsï‘'CAîÝ<‹Ãð^û¤²oD_)¡ëŒ¯twéfv½Lg¼—™'¶xJ,Ü›ÞuêÁ¢µ¡4j++Ì 2–Á @š\ÿÒˆ-1‘=ú¨ÛɆðg«ùÐÊ‘O>ÏQÓýBUËî¾£áÅi<¤sÂ4Ó±ÿÔ}KvÑ¡Xùò©œÈÔÐ1˜„ Bt½Û£azR„’øC€”EA«€™ÔB[TuÐ0„e‡“ƒcä%¦e0K±œèà© ´ã:ݪ€z1GS$Z•xÊ ,V¶Ät ââÉüÍx0ö*îù5A¦¶›]bZ¯îºJ“h]€Z…r¾û(äÇxýECË<™"É!ú–a&Û$}L&ù8Ýýœ•øj@(äP˜êbÛOï ƒ)Ž^y \w kì¹ôŽfÔƒ7¹Ó~Î@z)ÒŸÜñÀ¯EÈ>¥²æV: .ÕëylÄá(@Ž)2WD•™#¶lLPéô„Ô;êX²}@:½uˆ)9¬v<ÁôzvQæ\ÐHŠ»ZM©ËQ {aÓTŠÄ Ù¿Hˆ{Pméûº ²kzdwö.½õŽÆë0xZI7Í$ )a•íXs Pm‚²ˆQ Á¢S8„µU$ˆêÊû(µÓûÅ€Ǫr© ÄßN…¼Y ‚øÏ¢ïh@4­*™,†}¶‘UIÔÕ!úåâ°ÙòKB‡Ú«Š (•h–°^^vP”·sYaÊOdX’ÅÃY3Ù:ô.[áÆ›Ö·§±¹¦dB«.ëßu¨Û‘•ÜKwb‘²d $°Ýýf›¾AÂëɱ6ÐA±a{ÍxGwã"¬KüÐ5Û’ ÚnY2íÊë6ƒ²±ÒrÛ"@oBS…¯WÔ PîbeCŸè*ßC¨…7õ\IJ$ÐÓC|]Àà*»µ&÷ŠlÊeXeþµ$XPªEÌl$ºNJ^mÊM Û‰vw©.ZϤâœ\z…éëCs- èM¯ ñå S©ô'ølQQÅJsÿž=ò¿þj kkç¢:è †ux¾3hMîÕÓ›çE¸Y ß0 ¦© ËK¥•#‹>ò»²«¡ bö’É)4 `ÀTLÞ7lB•2™•«©–fb„äÁòÚ}02=R²®Lè0´†«øÌ…pUG »ô˜ÞTAìX"ÅŒAcY„=¯©ÁoÇ"¿<‡fíL $1Q—Ï Ôj²Þ³øžâ‘3µ, @Äõ~¾FUŒ²µ9"bÙg¥f€ŸÂ‚ ZAfìãfáÜeÖlâHÚQ’RâÖÙ‰ñ¿¨4EWF>j Kk»&¸˜(£uûVûISƒ¿|ûòíÛ—3½ý›žHF§OoŒy gÑ@“…9È‘ @)qi7$­øŽ ÐKꪞEâ±(¨©¡ï® =p¢”2ò÷–Q rÂWš…2éÞpµÁ8Já?M³bYWŽDW: (ôɆ¸M÷E<=ÿø<=ÒåÞ4˜…X‡n.´)Úàc;l™E0šˆ¡t+lXÊH•‘^É8B‚>T mp›ÜÐÙKîi¼KÛ@mM;²<#BÒtlÌ6ÜðÜôìi£rˆqÎ, êá\NÐeŽƒWú1šxºøWV&ÄŽIB\†GˆÈŸ°ï‹Âg'WE€%ú¢&ééœxPyÃO¹È·è¨òMˆÙY©®%aéág*]вªä¼*q6#—p¾pÄ$L„UBC_°8¡túô±J4'¿j<ÏXÄ—ñcþöòòòúúûûkr(£ÐÊNÖo}˜z”pU™¢>¤— ÓåÓB®ëè5Ý^æxå.Ÿ°ŒmÒ@Wsè{©ÄAŽeÚó^{†*H䱿“®O¶‘[ðØAkÈC-‚öÌd3£6Yl«ÆÁgâqõûÕ¾ˆ_ªÒ ÇuM”¼ã;Dß w‘£dEë¡PÜöGô|PD.h4þŠŠ\`x…”HÛžG~óÛtÒ5Q Zÿª,¯efß:Aììýé7Ô2Ñ'Ä›’ÄÝ&Ì82rr€Z@:&`‘$ðÁkw^¼ñ›žãF‡ ï½\K"“ÎýEËWλȔ%£³-“Iþ®¸%ñÇ. ,fÑÈbÁó\w‘Õ5Õè³+Á>$ PôŒuïê›À_Í$&A“'h–÷]׺1C®8g·[mS¯Ò˜W ðÁ®Á¿_Ä"<,SÓb¡õ•~¡H¼ÑÒÂ`*E}OœŸ¸·rŸ“¡ìV˜^/{9[,¡)Ć”ºôG€+ÁšשÂUF ÉÊ ¾H««b äJ›ÖJéåȉÔ= V{ÏuWeT§p5Pƒšûø¾¿‚ö¬¿­ÉO¢Ü?͘ ªZ(µ¼*-†¸ªì‹Rj|Å¡<¨ÀʺA¿˜mwSz“ æ EÁGoÜ¢¢}Ç{ÅÜþ'–—¨1öì&â’ÕžHe¤97—%©&R­ÔsÞ“Ò¬áȑÔ¶|Õà—õ}õ›ž@È':Jjò ÝŒ¼%r3‘Æ%P Z±[Œ3 9^Š£«å3¡Tèýíâ ÉP÷(…6`òí*ñÀÃÑ7ˆ€ØÙ•èë`¬f®‡ŒØpƒp˜`T5†œ·êŒ¥Ð„ÆUHƒ¿< ×±ˆÿúLŸé—ªécóS?Ó?1¹Ÿ+ʧ_ù`{9ÿÎÇÅ|C5ýþGþq #qæª{‚x@X ç#ã‘Lššì›ÕtÝÍ—y¾ìO`ÙD­ÒÕl!›g™Tø+™÷ 'h°À"Ç ÑÓÙÙ´ž_¶J½ÞLêlÀYdºÎJ‹©GK äÞĹÚTKAL¯l¶e;|Ï”ˆ .».¸^Ǻ›ÌE¿“}¢;ùl/(´S.—•™_!w¢™cÒ«UåÄe‘rMîé±²Üî‹ØÕ_òï dÓÕÃew™XóE3Þ®õ‚ß//QøÂõæ‹\¿`öK׬!âºDKw^½¼‡ƒ¤*oSÖÂË—¤‡‰Â?—¢ÿ(¦K¸é ö&7|W`Ø^·îîÖí‹xÐËEþ{éV/ýùéoF¦Î þAIµþÏ…û§5‹Ç›íÇYõÁÿ’ôQ÷óŸCò™þ”ô1ü™>Ó?5ý}>x¾_åo ào§ê/Hÿ¿xTüú™>Ó?4]j0ùà¿›ÊÏô™.ÒóG}ðùÒ×ÿÇÓ—ç1žÇÓÏþïù×ççÇ×yµÿŒçøì?#ÿx;¸ Oûî)€ð¿GÈd¬ÿãéñßÑèçE[ xdï·OžNð÷¤ÿ9¸x\=ˆ)TzÜŒ3hs"9›­–›ª`à L{A1Tó$‹$Õ@X-ÎS0tòôô”,/ŸsU)a.ª%Qǹ@ÿÔ5d O ÐØe'mQ°¤Ç—«ôüœ—O—,>x©ï·X_¿>íþy¤±þ>Äò´´zýy~Z9g&›W»•ùìÙ¿žZ1–¨½æ–¢yzhËÉ»·_õÇp>/ŸBeØ)äýՈשN¸ÏÁˆ÷øøu£›NWÙe¶OÏOМeXÛ¤6ƒgg8”‡mþzr¹òžS(yïy› ÏzNñW8àxJA<;Àg‡rªE¶[xÏ(½±”BÞ¤lbÈ0nŸƒÐÕðTiGÜñS¶a9ãI²Å[çjw^}[W_¾~ûÑCÿýe½×ùtÏ?ˆ~l‡¿hõ/Lïô?ÓO¦Sç¾¥â~ mþ²ž¥ßÞÑàâƒþ÷éqùõÊs¦Ïôç¥s¯©ï7¿?ðñ øöíÛ£õÁ{½ùq9>}ðgú§õܼ¾—Ú>Fn¿?}x<¼êù*Ý_ÄÄgú§µUÒÿsü8ØÄ]èkž—¦©ñÁÈÅü<þ"&>Ó¿8ù8x»ßóï×oy*ÏâýòqüØ}yê°¿ÿ™>Ó4­=¿ß`6ç÷¿? >õ÷ËïÏöÁkñë›zÿ™>ÓŸ—ÎèÁ—/Õ?b KÃ×Ôøàe –?ôþ/_yùLÿÂDÁ´í„¿=þ>½®!Æ›{ñàÇá€ß±ˆ¿›µÏô¯HŠð`Ä‹xõs*oăÏežX4[ \{˯ü^sÖÖùÝâ‰îŸž×R²Ÿ<˜˜ÞW‹ˆ mp‘žC’¿ªv àx+Ø^¶{;ŒxCcQwÉØ¢ÙðyÔzNAjiû쟽–¿7)¬½[bS€sõ1¼R¾Êñ™>Óß“^òÅW?¶MŸïh|¦ÿÛé_ûžÜgú’ȦÏô/þú#}§ôõvú¾ÿ¿[éºÖw¨ñýªå&±ß?²°Š>ÈSÔú~Rd|oªüDºß¶Äfèû÷¦ð;~œçŸòû¿a÷núþ^’Úîƒk½w!ýcÒ×Mì×ï—d/íý(8lôøû§ÊâÏöusþ謹Rî©â£È}ð÷íǾ}ÿñùˆ)ôàÞm÷õMš¾BKÕ¡ÜÓCÔìïÄÃ×ï]wÓ׫»¿Ö¼;Al!}}«Çßui’Ý×Êó¯J_÷s=¾•GŒÖ?}ð÷ßéé7¿úí~úcÿ·Òu­? ÆWõ(÷Aê5›yøã·®Æ»é«»Ÿ‘ÎϧN[Ht¤üÁu>ˆº¯•ç_•Î~;UqõàºÈTêÿöÛß;ÿLŸéþLÇ»PmÎ IEND®B`‚snd-16.1/pix/fmcancel.png0000644000076400007640000002474711147553266013441 0ustar bilbil‰PNG  IHDR”½YnbKGDÿÿÿ ½§“ pHYs  šœtIME× $9a1§a IDATxÚíÝwXÇþøñ7 ]šˆ‚¢¢7±Fˆ…h ¢Æ‚1[ÇFˆØ;&–(jT”bŽD,Q±D£±ë °‚W¥ˆ ˆJGéðûƒŸ{%š|-Àûy=Ï9;ìÙfV>gvwf4ŠŠŠŠB!^’¦TB B!Ê'€¤¤¤˜˜ø—;_¼x‘;wîH­ !„(@ÆŒÑ#Gž»ã‰'8sæ ?þø#%~VTTô—ÿ* ¹Õ#„¥«ÊÓ#FŒ !!á¹;†‡‡ÓºukvíÚEvv6FFFÄÅÅ1wîÜgö ¢I“&ìܹ³ÜÉôôtæÌ™ÃªU«¤Å…¢,ÈÓòòòˆ‹‹£nݺhiiý嬭­ùé§ŸžIŸ0awïÞ•Bˆ7T‰KX{öìa÷îÝܾ}› pÿþ}ZµjÅÁƒ100ÀÀÀ@jN!¤ò_Ó§O§  €úõëC5ppp víÚ`hh(5'„¯)11‘Ó§OÅäÉ“¹qã*• ,,,˜1c“'OFGG‡¸¸8|}}±±±yåü¾ûî;Ž;FVVcÆŒ¡OŸ>äææÈŽ;ðññ!11wwwLLLxøð!ëׯgãÆ“ššÊÌ™3ùðÃKö@j×®Mݺu‹#K•*Ï\¾²´´ÄØØXZ]!JÁãlj%55///–.]Ê?þH\\‡¢jÕª¨Õj†Š¿¿ÿkå·ÿ~Ö­[ÇêÕ«ñóóSÒ ‰‹‹SžÂ=qâÍ›7G­VÓ¡C8À¡C‡øþûïY½z5¾¾¾€ŒBˆrS¿~}úõëW"­]»vÒ¢E Þ{ッ¯£N:Ô©S‡¦M›bff¦¤ëéé1tèPLLL”´'W£ž¼QXXHaa¡òTkiB!„OëÔ©»víB¥RqëÖ-vîÜIrr2cÆŒ!&&†E‹IBñ, ¶oßοÿýo"##±´´dêÔ©¤¥¥±råJÚ¶m È%,!„(7‰‰‰rûöm.^¼HãÆ4hÛ·ogÏž=XYYáååűcÇ;vìkÝ@ˆÅËË‹©S§¢©Yüçÿ«¯¾"77—cÇŽ‘ ¼öéÓ‡ÈÈH† ÀÂ… 7n“&MÂÔÔTz BQž?~Lnn.]»våáÇLž<rrrðóóÃÖÖ###"##qss£wïÞ¯•ŸZ­æäɓԬY“>ú€¾}ûRXXH||<ƒ ">>Lß¾}•ÏÚØØ0bĈ÷I4Êj:÷' e$ºB¼™ä–BˆWRª—°¶lÙBXXgÏžUÆ”!„x¾7ɤI“¨V­sçÎ¥¨¨ˆŽ;âììL@@W®\¡ZµjLš4éµóÛ¼y3ÕªU£{÷î%Òÿøã> À¼yóÈÊÊbéÒ¥|üñǼûÕj¢¢¢”ËY¥ÚéÚµ+nnn¸¹¹Ñ¼yó Ó@×®]“³TQáüôÓOìܹ“­[·¢R©¸~ý:7nÜÀÅÅ…7¯¯/nnnüûßÿ&::úµò3f 3gÎäèÑ£%ÒsssÙ´iÎÎÎÄÄÄJPP©©©888°uëVâãã ÀÍÍ={ö_ºÄÜÜkkk¬­­©Zµj…i$///9S…N“&MØ»w/Æ #--+V ¯¯••›6mâðáÃ9rkkk’’’ؼyókå·víZìììžIOKKÃ××KKK Y¶l^^^caaÁŠ+8|ø0¡¡¡X[[síÚ5>,÷@„¢¼8::²xñbæÎËСC+]ùå1^!„('Œ;–ÌÌL6oÞLýúõ+Uù¥"„å¤Y³fLŸ>nݺQµjUúô郆†ÎÎÎØÛÛ+—œªU«†““S©—aÁ‚ÄÅÅѵkW%­oß¾|òÉ'ÊvïÞ½±··ç_ÿúP<‡—½½½!„(/[·n%&&ooo-Z„‹‹ iiiÌž=WWWlmm8p *•Š5jо}û×Êo̘1§§'/^$77—ádzpáBîÝ»G¯^½èÛ·/7nÜ`ݺuŒ=[[[Q©T¼ûî»ØÚÚþo $ìÛ·/ÖÖÖ2P!J‘ô@„B¼¹‰.„å$##ƒ„„ ø¾‚¶¶6éééÜ»w¯DÚÍ›7¨^½:ÕªU{åü233‰ ^½zèêêÅk~DFFP³fMLLL¸{÷.=B__Ÿ:uê<·\@„¢œ¸ººbbbB\\:ubÚ´iìÙ³‡aÆѩS'022¢Q£FT«V_ý•víÚ½r~îîî$''ÓªU+æÏŸÀ?üÀ¶mÛhÖ¬ÑÑÑ,\¸áÇ3`ÀvìØ¯¯/ .ÄÜÜœ˜˜ºvíÊäÉ“%€!Dy±³³cÊ”)„‡‡ÀÎ;Ù¶m=zôÀÈȈI“&¡V«qtt¤Q£F¯•_~~>jµšüü|%˜œ;wŽ}ûö¡§§Ç¨Q£ eÆŒ 8-ZpåÊtuuY»v-¹¹¹Œ3(åKXùùù*]"!„möìÙxyy‘‘‘ÁäÉ“â)ÞW­Z…††ýû÷'33“àà`Ž=ŠŸŸZZZ¯œŸžžzzzÅü«ü÷Ï¿¦¦&ÆÆÆ(k~˜šš’€¾¾>ºººèêê*e(ÕâëëË•+W8sæÌkGK!„xÓMž<™ðûï¿Ó¿Ž=JRR]»v¥uëÖøúú0wî\/^ÌìÙ³+LÙKõ),wwwÖ¯_Ïúõëqvv–3C!þÆÍ›7yüø1mÚ´aï޽ܻwccc>úè#´µµ•×={öÄÜÜüµòËÌÌ$33“””rrr”ü xðàÙÙÙ¤¦¦*éO¿¦§§óøñc’’’ÈËË+ýˆBˆçé马ødäw·nÝpqq¡{÷îÔ®]WWWjÕªEíÚµ•{¯ÊÔÔWWWRSSéܹ33fÌ cÇŽôêÕ‹F‘ƒƒÆ #<<œßÿµZͱcÇ9r$qqq 0@ !DyÉÊÊR¾ñרQ---ÐÒÒ¢F¤¦¦’••…¹¹9:::¯•_vv6)))XXXP¥JÒÒÒ022"11 HNN&''ÌÍÍŸ[Vé!D9Ñ××G__¿Dš••Õ3½†'7´_—žžÞ3DzÆùŸÓÿ<Þäye•‘èB!^‰!„(G&LÀÑÑOOOîÝ»G÷îÝ|˜;wòÓO?1zôh¬¬¬˜nnnJ0y"%%…={öàîîÎØ±cK|ÆÇÇG<¸ÿ~å:È8!„(W dggS¿~ýr+ƒŽŽC‡åÌ™3L™2E¹¬¶jÕ*&L˜¯ÕþÛo¿Ñ®]; BQlÙ²…¾ÖZç¯ËÄÄ„1cÆàííMHH¹¹¹¤¤¤œœÌ[o½ÀÙ³gY¾|9yyy2–B”·[·n‘››Ë;ï¼£¤;vŒŒŒ ‚ƒƒ8~üx‰××Mtt4!!!Ê}ŒãÇ“••ÅÙ³gÉËË£M›6hiiqòäI”©KòòòX¾|9‡fûöí€ÜBˆrsóæMœœœ”íÙ³g£R©°²²¢eË–ôìÙ“³gÏ¢R©HNN~íÙx̤I“ÈÉÉaÒ¤IJiÙ²%sæÌáÝwßÅÃÃmmm.^¼È7ß|£|võêÕ@ñ}›ž={JBˆòäââRbÛÆÆ¦Äã³Pü¨oi9r$#GŽ,‘ö$H=zô¹éöÅ_(ïå–BˆW"=!„(GYYYhii¡££ÉÈÍÍÅÀÀ€œœòòòÐÔÔÄÀÀ€‚‚²²²€âuÊ_ææ{~~>ÙÙÙ@ñ ššÅ}ˆ¢¢"=zôßÀP¥ ºººJš®®.ÚÚÚÊ~ZZZèëë—näÀx{{+wò…Bü5ìííY°`P|?bøðá4mÚTÙÇÍÍ3fЭ[7Nœ8Á'Ÿ|B¯^½”í/jÿþý 8îÝ»+ƒ>|ˆ‘‘‘òO¥R±yófœœœpuuÅÕÕ•ÂÂBüüü022ÂÖÖ–°°°Ò 5¢mÛ¶´mÛKKK9;„âo´iÓe»AƒÊc³/^äÀ¬Y³]]]6lØ€§§'Æ ãÓO?ÅÓÓó¥òóôôdôèÑôéÓ§Ägµ´´˜:u*çÏŸ§oß¾X[[ãïï½½=cÆŒaË–-bjjÊùóçÉÊÊ"((¨t/aýë_ÿRÞ׬YS&SBˆ¿aoo±±±²mccƒ²‘‘¡ûì3åÈÔ©S±··gÓ¦Mäææ¾ôÀB~ûí7>|¨|ÖÊÊŠmÛ¶aeeEJJ #FŒ S§N=z”¬¬,œÙ±c³fÍRŽ¥V«%€!Dyqtt¤M›6T­Z===&L˜ L`¨§§ÇüùóIJJ¢cÇŽ´nÝ3337nüRù999Q§NåfýüAýúõÉÎÎfÉ’%ʾ'NÄÙÙ€™3g¢©©Yâˬ!ÞTùùùìØ±[[[©Œ ÊÎÎî™´zõê•Øþóuccc^)?SSÓg>ûd™o“ ikk?³oµjÕJlË=!ÞP………ÏLO!Di’"ÄLGG‡ÜÜ\©ˆ *//˜˜¶lÙ¢¤O:ÅàÁƒ4háááJzQQéééÊ„‰ 2•JÅСC•/"………øûû³hÑ" B¼é\]]Q«ÕRThh( ,àúõëJÚ™3g°¶¶fÈ!„……qèÐ!Ôj55kÖdÙ²eDFF2gÎ._¾üÒùyxx0mÚ4FŽÉøñã•ôG1gÎe½tfÍš…Z­¦}ûöÀùóç•U %€Tùùù$$$HEñ†qppP¦1yÂÏÏØØXìííøüóÏK¼6jÔˆ+V¼R~¶¶¶4oÞœŽ;R«V-%½jÕª¬ZµJ¹booOãÆ¹ÿ>‘‘‘8::ràÀ¢¢¢1bFFF@*‹””V®\Y)Ë~éÒ%å?‚âÿ¶fͺwïNïÞ½INN.ײüøãÊôïk×®%&&†iÓ¦áåå”òl¼ÁÁÁÊ7娨(tuuåløwãÆ 7nLDD„T†/àÃ?¤°°ÈÈHÒÓÓÑÐÐ(—rÜ»wGÑ A ø ®U«VQPPP6—°ŠŠŠ(,,¤°°¢¢"9„âoäåå‘‘‘ANNŽ2uúŠ+ˆ‰‰ÁÔÔ+++Ö¯_OZZ«W¯FWW—üü|ÒÓÓÉÍÍ%##ã¥ò»zõ*'Oždûöí>>˜˜˜°fÍfΜùÂù©Õj6lØÀ?ü€¹¹9=Rò˜7o^^^Ô®]»Ä´ò7nÄßßøï*‰EeÔU˜0awïÞeçÎåÚ@ûöí#//¸¸8:tè  š©LzöìIÓ¦MYºti¥+û–-[ÈÍÍ%""â/—Èe#77—qãÆ‘››+Ob‰2!7Ñ…B¼™ÊD!ÊÑ™3g033£I“&ìÝ»—¢¢"7nLãÆ¹téwîÜÁÐÐ.]ºÅ Miii½ô•„„‚‚‚pvv.±É!!!äååñÎ;ï(ãBììì¨W¯YYY:tˆêÕ«¯"Í'„åcÔ¨Qôïߟ͛7àííͪU«xðà}úô!>>žåË—°jÕ*²³³ñðð`À€/=//‡̯¿þJXXX‰Ÿåää0~üxT*yyyxzz²yófnܸAïÞ½ÉÊÊbÑ¢E¨T*úöíËñãÇ%€Tt·nÝâí·ß–Šâ äëëK³fÍ”í+W®P§N>üðCnܸÁáÇٶm½{÷&==///V¬X££ã+å7fÌÚ´iÃ;ï¼Ã˜1c”ô¬¬,ú÷ï©©)—.]ÂÑё˗/“ššJóæÍ¹rå !!! :””” ¹sçŽ\ªèBCCiÑ¢E‰©„o¦:uêpá®]»öæ›™™É¾}ûÐÒÒ¢sçÎøøøàééIÛ¶m gîܹ´iÓ îÝ»‡ŽŽÕªU“ˆBTóæÍ£K—.Lœ8‘nݺ=3}zY[´ho¿ý6sçÎ%00.]ºðÉ'ŸpúôiŠŠŠHII¡OŸ>xxxЫW/ BQ‘ÄÅÅ‘ŸŸÏîÝ»iРuëÖÀÐÐF½Ö±ŸžVèÉû}ûöqïÞ½gö=rä­Zµ¢ÿþ;vŒ˜˜ „››ææær K!ÊÓ¨Q£¸sçééé`iiIXXëׯGOOwÞy‡=z R©((( ÿþxxxJ•*U˜1c‹/~áü<<<ðööæÑ£GÊtð_~ù%>>>¸¹¹1g΢¢¢X·n)))xzzòŸÿü‚ƒƒ9wîçΊoøKBˆrâëëûLÚðáÃKl¯]»¶Äö«ÎÄ àââ‚‹‹K‰´ØØX xÀòŸuïÞ½ÄöÀKl—jY³f —.] ((¨Ä0xñêÌÌÌ033#**J¦eBT¥@Ƨ¼2•‰(…FªR…*Uª-•!„¨0ä&º(sVVVèéé%•!ÄS¦OŸŽ³³3ƒæÑ£G\ºt‰-Z0pà@†JLL ...¨T*Ú¶mË7¸ÿ>;vì`„ /Ÿ§§'ݺu£}ûöüüóÏJú¡C‡hÕªü1ãÆ#&&†N:¡R©prrâöíÛ@ñxWWWe[ˆ(ûo)ššhhhPXX(•!ÄSÂÃÃñóóCCCƒ„„üüü”sóóó9uê 6D­V3eÊvî܉††Æ+_‘8wî7nÄÏϽ{÷*é?ÿü3~~~lܸ‘ˆˆNŸ>‹‹ jµš^½zñÇpçζoß®,×!7Ñ…¢œìÞ½›ÌÌL’’’€âéJ®_¿ŽÆ CWWWùcݲeK°°°ÀÅÅE™§êeXZZbii Pb,åžµ Ÿ|ò ¬X±}}}e}ö±cÇ2}úôÿ~9”&BˆòFëÖ­•ñVVV¼÷Þ{DEE‘““SnåÒÑÑ¡K—.dffòðáCNžüRùÝ»wÙ³g3zôhôõõpww§^½z 8eË–qéÒ%.\¸@«V­`âÄ‰ØØØpöìY.\HçÎéׯŸô@„¢Æ{óæMRRR€â•¯Dé±²²"!!AYø^!Þ¨HTT—/_æòåËøàƒR½õçK9eu¢­­]fÇ?tèï¿ÿ¾Ò‹+mÚÚÚ˜˜˜”Yùýõ×JÛ¶;wî¤cÇŽèééUºòëèè`ll\fÇß·o|ðA™}¹)**"11±ÌÊ€““S™]ª+ëssëÖ­8;;—¸jR‘Ë_"€¸»»“@ƒ ÈËË#22’5jÅ+ÖªU CCÃ2ûvò26lXfÇ666ÆÊʪ̎_¿~}´µµËìø&&&Ô¬Y³Òv›Ë²mÞzë­2ûZÖå711ÁÒÒ²Ò¶­™™Y™^ŠªÌm ðöÛoWªö,q¤4M˜0¯¿þºÌ¾¥Šò#mûæš8q"žžžeÖåK¥R=÷–ë’©L„BT¬È­[·hРÁßÞ€•Ó­[·¨_¿>UªT‘ʶ•HXXMš4©øD!Ä›­T.aEFFâææÆÖ­[ŸùY^^ëÖ­cÊ”)ÄÇÇK !D)Ú¹s'*•Š¡C‡2wî\?~ÌòåË™;w.>äîÝ»|õÕWøøøŸŸÏ¥K—P©TÏW/##ƒ%K–°`Á‚š;­TȺuëX²d ‡~ægiiiDGG3`ÀöìÙ#­-*´eË–Éy**•~ýú¡V«iß¾=Ý»w'::š¢¢"Z·nÍ©S§`ðàÁܼy“ÌÌLÖ¬YƒZ­Æßßÿ™c]¿~SSS6lHppð?@„xøûûcoo††ÿùψˆˆÀÏÏÄÄDå›Þ¦M›HOOÇÏÏ???"""8wîP<}Ovv6§NÂÏϤ¤$Ο?ODD„ÒCONNÆÏÏ“'O’““Ã… €âÙòóó¥!ÄK»zõ*AAAeús™333îÞ½« 05j»víЧ"ÐÒÒ"99ù…æÏ¢¼lذ 6ðñÇ“””„J¥¢nݺøûû£V«ILL$??µZÍŠ+¨[·.÷ïß'00???¶oßΑ#G8yò$EEElذmÛ¶áëë‹™™k×®eåʕԭ[—˜˜ùå—_øùçŸ+ÝŒ¹¢üíܹMMM¦M›ÆþýûÑÖÖ¦  €ŒŒ 066&))‰*Uª ©©‰™™111Êcø=zôP¾éêê’››ËãÇ_h0f©Ù³góÛo¿1nÜ8ìíí©]»¶\zõêÅ;wž™ÜMˆŠdĈŒ1¢ÄvÇŽùꫯ¸}û6ÄÆÆ¢R©ˆ‰‰¡cÇŽØÚÚ*û?xð€Ó§O“””ĵk׸}û6ƒŠ—-hÛ¶-ÄÅÅѱcGZ·n¹¹9†††\¹r ‹2`*ÞLýúõãàÁƒìرƒ¯¿þš† bggGQQÝ»wÇÕÕ•ÈÈHúö틱±1 .D­V3sæL x’SsssZ¶lIƒ 066¦C‡ÿgÞò–ÿß‘#G077ÇÞÞž”9§RSS™7o™™™lذk×®áååÅÝ»wQ©Thkk„……ƒfóæÍ\¿~yóæqàÀ† ‚††~~~´mÛoooš4iÂØ±c‰ŠŠâ×_eܸqÒK•Š!^áC‡HIIáÓO?}¥Ïgff²téR<<)Deðÿø¹ûTX/³IEND®B`‚snd-16.1/pix/sceq22.png0000644000076400007640000000276111147553270012753 0ustar bilbil‰PNG  IHDR¹"õ\W.3PLTEÿÿÿ°°°ÀÀÀ```ÐÐЀ€€ðððPPPààà   @@@ppp 000÷ñQÆ pHYs  šœtIME×  4C~etQIDAThÞí[‹r´* †€¹¨ïÿ´‡›Š‚àvÿ=ÝΘ™Úê¾@nu y¨NÔ2$Bȉ?F _¤"H,^…Nx‚ŒÏ‘iÜS¼ì®FBpìy+-ÌgÄKÁ8…Äǯ’þÂzl`¨üFÓ@y ÿÝß/ÎO©™?–ëQð Ö…d¶ßæ$ªO›³½§Ï Yžo9>M"’5fv7_~ÚF@à~ÄÌrDßË.î2¶Âœ·ˆÁrÄN6[‹¾Úp:x%Þ‚·Ô»“È-ÇïXDÙ›ŒÝ0ÓoXŽ,SÞ^ÊG)ìm¨N·Hy0Z²0¾3rÐþDQªb^ž-UI¡ãžÔ‡92Úî˜h¹W½s›_ C_‹X‹TUã>Þðv(É'ËŸ…[oCŠ.ÖHo»ô<2ºO€8ã¡5W¾ô’‹ëŒ5©·ÂØI ÁDwŒ‡Pô <{þ6‰&–¦vTÄõ †ê°²­ ½€ÿ nf“Ÿp61[ɽeö‰ô¤Ût#çÔ¨O<åá«kËÙ¢r–ëžVêö˜ª‡ÞäwؽÀœ¿êšåˆSh àéå¬åZ†^ ¨,¦ÀµöIONÕvËHÍrþ):§ê/ššJB»ŒJ¹ÃÉ Ì8nà „K/:ŸCê1¿—2ßà_¦Vtc„Çög-·2ôB@m1]êÚSï²iÂe:*H}²FY'9Z²¥ñ‘QYá~»hè\k,¥XOÙª˜W‡s¥w£/KÍä@ü©BøD»,9îä\V.°ÓK>…º}ôQŽZfehP PPG@kÒü³ú™ö :l˜vUǪ€KºBk:k±Äѹ”!Ì)}~¯ÀŸG’º¸<ùSm{;Ρdà²!`Œù“bÿ"ä,+øSXÊ£U;ÔÔPÓQ˼ JJj89Ô›§TÓž.Ø‹7­šõÞ«µ†õ‰§v+ÅÙ©Tµ¥£Œ®2¶A8íÇpeÒ&JPëœoÍ1£Ïï&r–• ìV¦æ.w5â³I ËÐ  D  †Wnß0]QÓ^äñHÍæ*¤Ø¥@b»N„ÚYÇõ‰°Öó;cïÌL¤¸S×!¹å޲2=Ëiqí¹wÅÙr{””TðrÜóRýMûÝí~€¼òÈ}ÚÂÛ!hâ–aD±àA(ºÍE;– ÛŒu‚7MY•’[n•J0å%$Ÿ LGkÓÕt9¨1Ã^ÜÅð—¡a†REÀ1†P¨¿k£ò£?ÕS¥SZZÍÐP¥iÜÊbZÄà‚¸«lÑpèX.lÿ¥w¾½s B`´ f¦„OWY¾cÜ'`I hvFøÕ‰\ŽE§smkqçµÌËÐ( @ €Tpr´ó–…ú¹öŠ|’ÔzÅø§?w¾€{¢zå-·õ¬cÚa É&äÔoX›é#‰ëT¦Ùå8|ÊÛýTÜ¡©(T"P †î?'õûÚêBÖ&;&úxPGRºðbÌ¥cîý –ùòUn9s“z¡o¹wG-/48!p­>üÊë1úÞvá6ö#îÁ»Âmþ‘çͪ°²†ý~ßò«{ྒ¡ýæI¯@ÿ ±e­ò˜Y¦‰‘‡^þF×Kv ôŸ„fq$þâe¿Úw §Êø¡o1\ß&R<@}q~çö¼ùm¤†éÎË;˃Ô¥'Æ=ôÐ_>À¡yŒh?ÍÏ×z¾ž¶7ƒÒm çk=bóx=sÉrÏ×zþmojÆ/üZÏÂX+Á‘(OèIEND®B`‚snd-16.1/pix/early.png0000644000076400007640000030142011147553266012767 0ustar bilbil‰PNG  IHDR,Î ä¨sRGB®Îé pHYsÂÂnÐu>tIMEØ)!É}vÒ IDATxÚ¼¼ÛŽ%Y’¶–Ùv?'"³ª/Ó=  H _D€¢^t>D¨7éC=‚ 0ÎL«§oU•qŽûÞ¶–Ì#{ Pu£•ÈŒ8á¾·™­›Ñ6þ¿ÿ0diY‚ ›l¹ÈÈ`VUÁ"a÷o–dÐ@Û6ך$À¬5ƒ‚A02€%E„16Ù€×yª*2lØ®ó|ÿúÓŸ~÷Ûþøû¯?ýpyùþ/~ùWÿì?½½|—cËŒ¬šdŒm¸l8"ƶIb àúqÖZ ™°’`¶­*iÎ9 I˜ÀU’k KfÄØ6’– ä5Wfä¶[¶×šQU#™A^œ´ 2"@fŒÀµ$Ù²Ð0`2]“¤A‚!1¢¿Ñ<Ï5OI†#²ÿ.# 2()"™™¶]ÊmŒýF†ªÌÌÑ?l»lD„¤ªÊ ú TÑF` ¥h÷§…l©"2HF’ìG 8"¿}Z‚ T2 ;ö&ƒd}H`Aªo”$3  AFô«#ADÀB¿qþ“S}ýÇŸ·¿ÞÇ¿ùOþóÿ¿ÆùåÇÿðýïüýoj-ƒ àýííñx{>uÎÇqì[FfFxÏû¾• ’ã|¾¿18rÈžs™ª³ÊÚ·¼m·²\2 àíñÌ ¤Çq"’9@™U:ϳÊ¿ú—ÿÅ?üÝožçYÒœçØ«ŽU_ÞÞz{ŸkÏ9FŒÌŸ}~½ï{dlcìÛvÎÅ Æ €ûýöéåõ~¿‘°#U~<Ÿk-¹úw ܶq¿ßFæ§OŸ-Í5ÏãË×·ãœçyX¥TÉðy ë2c$€*m#I¾Ü_æ<_î·ˆ@ðõvƒñö<Îã8çÌ1n[Þö}ßw•2cŒ­j‘”±Ø÷}ß¶[$—tÇZ5ç™°e€°J2#«ÊÒI s|ùòõ?~ùÓO_2Rvþ¹ڥȹ尋c¼lcŒ±å8æ™/·=2óz¿G€¸m[YUõ<' -•”†a”D²T–%˜kÍUUÉ‘±ï»ªK r„ÖÊ1ÆØ@²TU%ÉÆ¶e0ƒÌ‘$·±=ŽgF”DBæÈrÛFDܶ-"Vÿ]˜‚¯/{ÆØ¶±ï·mŒ¯ïÕ*¹¤¹ŒU BU1¢ cäív;Ž“Ä6#¶mdæ¹42IZŽ`ÉAä Þ÷=r(9G2bßFäóñxŽŒ1FUeDFFpß÷1Ɉ ƾÅ_üúWÿùùoÇ¿û_ÿ·ÿùùŸþñÇ2Àš k•áU²ÊྠKA:2 Ui—§ê¶µ$–É5רRåÛ–o#eLY«Îµ,«›­]ús•ªZ#SÖÿùïÿöxÎeo%1¥.Ù.¶IVéwú¡Oe«4ÆKÀ[ÈÜ÷ñz¿EŽ-²È¹ÖZõ<'TŒ Húv»½Þ¶#/÷ûïÿôããù\¥³Jª-sUY.€%’s®‘Q,"ú‰E8Œ8ú%Dœçi˜$ÁcËÜ·rdŒ(™Ä–9"Ffäv#͹–Aز9G„ Âe•lyIAÜ`½=ޝïïoCk]ÝÕTô`H&´[îc³ÐU1²Ÿì>ƪ;39‚ñ˜"m[«ÊWg¶Ü m®¦a °Ôu•"H0Á0©ª‘AÀ¤~q0˜cD,™pF¨ç lmc rŒÈˆì*{*yŒ± n9¶mŒÌÌ8Κ«Žy®U]¾$Ûb­²I FˆfdI#"GJE&ˆ}µtެ2 }lªJUÌÀ`IŽA”÷-Wyd0xYF•î÷ñ/þ³¿þõ³ñþößÿý?þþ˜™K«ßhƒ1kV9Gç°_|AHÞ·¹¿?Þ—jª¼Ê?&‰µd`®u¿ßF„d°ÏªuÖ´T à’®Ũ*Ð’ þñ‡/=kAÂK‘ۦͤÊ#£VÙÃ%Õc1äQJ æ*U•nûXcƒ=2çQÆ<' nžIžksß3ÿðõëq®ã<-T-£Ë%—Ä®„CPvÕLBvW—`’0Á‘ùÆ@™ãõõ=#Žp™ûè›6r˜ë±ÔÇ•J: ‚€d^׬5ï{ͳŽ9ŸÇ’4ûñVŸ:ß÷ý<'ƒ©L0\¯·Ûq,AkçÄyžA£Kn‘²{ðj•ÑpE&@Rºêªìe÷@±–L¤ƒZJ^å ƒ!{Ú±ä\.b‹È`ÉŽHcäª% žçc>×¾…ÏÙ3HñAª¦1N¶=t>æ:ÖZ¥µ–e’¶Uš®}lù<Ž Ê<ì}‹@̨-󜓵22XA>×3sˆÄ’á’ªŽ Z(U”k Dd|Ù0d™†$YOF%W¯_ߎÇÛx{;ÖZKBÙ}%JJSµtÛs ¶ƒ<ç”|¿í%PSk¹\–5 ÝÒ„ 31¶Ä¾ßï·ñé~OƱôãûã8×òªr ¤`©l4^3µV?¦Ü«LKÀ5FU£0FØ`93VùðY·à”"=²3²–*4gHYGU_&xÍU²)”9«ªêˆˆÏs­µl\W*x6À°löAªD a NÍÈ”<ÈYn”I 5‹ZfÌc/û-“™cU[Á#yÏ5Kt#ttC¨bðýœq=3Òó˜Uý®—%Ë ]8çIÂ@K%¹øã—/4r$ȵ*A"ây¨B6*…Š mÙQ%F60-˃4 Cè¹úŠ.©ï±ÍJ†3³Ü…”9ÂVјlnbÀ}èÉq.ä¹xß’p4´íJ³D jÁ’Öh+"d³(׈ CƒŽ ‚o™²G0Æhæãb¨@ †z¾/,­UÃdÀKXƾm*Ë52a?Ïs³´ßö%¯Z>ü8ŸdŒ9—«ÊKå²3BU™è·w,!yyí{®S³$+‰…Pru+‡!hd0|Û÷1ÆÈüüéeÏñýçבy®šeU­µ¤£\ú;VW@F›+RÉ6º£¸Ì°Á L®}=T4Øž‚­µš½`31–@—ÂS/ ŶqœkÎåÇ,ƒ’HqžQ ,,é»—ûOÇÆðÅ< lÞª)Ȇ ²V]Ä-dóϩт”-9šXÅh¾«\¥Œ™cä#kÐÛU¼çVìµÊÀÈpLŒ5¢dÖÈÀ¬š«ÊV9€2h??^—Ö¾žð"`äÈ9«9:»a®›v+M¼Ù”™ ãLF¦ÅµV"«ËSFvaØÖEÞÂr »»Ý•}Á×*Â2‚Y…èg>aÚ ÁÈ\«Æ 9"À’KަóÈ.…cÛσª °ªN?l67ư‘’2£D­52̪1Æ*'»øÌµôAYa-•‘ #v¬z{lûf• ØUµ" éœa0("8bäèébi­ë»$ 0ÊÆ ˆ`H¶#iÒ‹¤äŒ‘c±‘cdæwŸ^^_n/÷û9KrÕz<ÏsÍ ª¶¥f D¸Ê‘tŸ,˜A—ûµePt4crá©sDôœÖõ ÓVΗbD«t»o$÷‘ß¿¼æwqÌúýŸ~8fç1Ï5¶4D’[æÔÏsÞ·pÕ ØK X°„f(_÷ñe©ébƒ¤adp I^M].i‰Ñ #l¢4dç,pÞ·ý˜qŽ €‘±å5í—ìµÑ¶¤A€žÇq<Ç<—åÒìRÙˆ€ FØJÒ­â‘ïï× h&˜]Ã-ÆÈ™9bdVi­uœ+s©jÛòÓËöùõ嘳àÇûI»zl“D2z$’#¢J ÆEY ^-úzR´QÒ¾EõT™D’}ƒmDë¥çó™1/÷mÏñݧ{Õ÷ϵf-Ï2ª…{<ñöxä–*Kê–à ‹ªj|ØìBÏT­øÝoÛã8Ñ\ ¹EÄ$T(W*v‰¬Uó¹LM.™‘Q6‰‘CÒ¶åmcls­ã˜ ïÛÖbZf¸ ¾x­5«lêã‘­—‰´.ÃÆˆ°_e³Ç>X™lžÉå k.ñÑ¤Š ‹…«Q¼Ôh³ù7ò«¥$̀ʦÁ({$]ú3´Fôæ½AÊÙø„¹T¸í3"7}–ÞþðãŸzVv£·eÒp¬*Ø‘!)@Ñ4Æ%xr­ŠŒ Æ …ªŠdŒ¡Z}z¦t±’ÍH¤•‘–J!CZSn LFÐeŠt”ŒRE„]­öÒ~<Ï÷÷¯ã9W©¶‘R»3†\p´°‹žó3•¡%Kú& [fŒÑh’ÜÆ€ãëã<×ð<ÎÛ¾m|þôú³sÊÞ#ç㘛kJ-µRqqóÙz ¼¸u²ú²š$±–# ÆÈMuSÁæœÎU>ŽcÛÆšº˜™[n¬B ŒµàˆØ2W-‘˜2L"Ö\ î[‡—.dØÉĹªꈼßÁµ´jùÏ#.ŠÂ"©¦^` ôQï⢛l/%­U9¶Ør@œsqñÎò±Å€– Õ ì‚¥Ôã`ãÙžAÁ)mAÓ=s¦ƒß~.£Eˆ’E! d=Ü2ÐÏä`œt&Œ‹&¶ºÄ’TÆýg)·Rn“-A÷·dô |t$€’½TÃ×¹œyÌuÛG ›™ ” ‚yÙK4ƶj5{ú mš¶sDãæŒn0ÄÕ!B Gä1gó[Î9¯.eG«¯‚TfÐ<—3£ ø"Y Æ9×ûןID®5oûþ¿ÞŸÏ3*­Z/ûøíýŠÒZõg#ɵú§öõÞ Û ¹Tl ׌!­BfÐmƒÙC##¢¤HÖ¬‡Ïdü18¥s®Ÿ¾¾©æ¡³" c­*xg-÷¹™Ò ŋ挒ºRl[lA2#³•̵播KG…MF`?š.5Çd|°ÊAÜöýqœšŠDŒˆÈ5+’–æ¢ox'.NMH²„³q ú„µËåjƒ—ÆÈˆ`ŒÁˆ˜U-³î9f—I°|Í!=¿€´%#e’fë Aàš!»ÄlR*",G4.eÏ*MWe\–•h\‡8×0ö-笄aT! eÕ³jH6æ\û¾ep­ÙŸoäå’LrÎSrÙ²·®jŠFàØÂKµ, ‰‚ÁÈ@zL£çV-Âsi®Y‚¤‹”‚p©@Jº”ÓºäÐB\¨XªL2bhMHçò\OªjûT— FF+h¤Ë€FîÏã\kµ;-#å뵯‹÷ûýõ¾o9–*ÛØ$=ià¶ï¾ÿôò~æ\DºNÅwùþ<%Ur^¼¿#Ñ_¯s(©§MÙƒQ¥Hd†¯†×7"ºkFµ¼>²Jo£JsiÉçvV®Ê‰5uœç¾•×éO°}W{KQð˶Ç,¡\v¹ÿA¢Œç9G’ —æZLndÕ²|®äØòëׇඳ|#`d·i¦ù3ãbSZóØ€eXöLt-#›à¥fÒkÎËÂg è½ç«Ì!,iÏž‡‰øF&£}hVY°C=ý dËÚ‚0¶1Öœ­ ¬ªoè8—Á_üâ»·/“&Ö\kc­*+3xòa±­436Àç’Áª¢5K´—T*ÀÉ”52ŸGµCh&Âs*Èeu©_µìË5U’ªˆæ#Bì+Ús¹‚]ê™ì€¤‹¼!96G/÷OcZËv¸J^ºŠ¤ö±­%Gí:¯»>’s­SæÔ@Nv2§´ #؆—ïnM™6/pœ+‡b­¾4nûv;7Òy« äç¹FT-ëÈ´>XÑÀ¯U9«d•¬[”.Y›r£‘†Ý€â2iPöÛqΪ`,ùœS¥%@Ž-`ܶñœk ê¶íÏóŒY—t1Ãr”¯·‘—&…xÎ霫J#bI|¹oÍT°ÝCâZs 2¶:ÏÇs®xiEÝ0–þ/Ïèš1«VC2¸„ù\h+Ù°êã<¹¿˜Ü§‚‚ѽôåúÅÆˆà2¶h{gHb¶BÙPEƒTƒ·6-ô…ÊCv»<lˆ%›Ïn’%ZÄ¡v׬_^Sºu®fÀ!ÀÎ ÙŸþñ‡/ ×]NÚŒ$W­Œ1"Ö\ÏàÃsÂ~z5Ú—°µ„U ˆÁàK– ©2F©ä Á6:È’ZÕ£D-áò ©‰É6B‹ÑKYeÑíʄմuÇ/Ÿ¿´k­ˆŒ ç9#8Æ^ªa㜫Éô¶˜-U4ޱ™ÑÀðjAö*-é˜ó~ßÇ}KŽéã8§–ŸÊˆcÖ>¢¹¥f¢ïû0"ɳJUK,ò–¬K•R$úå_N«îI»Mר¶hÉå¡‘bd²!30r¬YuM’yœ‡EA-&ÁÒiö¤@•f-2ªV\Õ_›´Ä6†"‚¬Z¥îÍÈp»‹ÆØ]dì#>¿¾ç9—Ÿ5Û—øúr?Ÿk.²2)7ºK]#WõøT`ÊE1ÂUÎ쟬]™íÆ#à"ãÏ7¹- „‰%$š‰u ±h òrsVn)hßs­&SØÅ´I´K¸þ–¹}i~4Ð. ²Gî@²YRQW)6/îŒÁ(8³ ‘‰U}·5F¢%²-é=.®âH 2h«n3ÖjN‘Í©tóÖê⬥E_¦+Ð,˜ƒ“ NÛŠÈë•Ú€çBÿ‚$"ì2ð‡¿ÄŸ¤qÛÇ<xŒŒLH`T9Cå rQ- µ! V!⬠SXUiPàh=ˆÒeÈ:—…9Î<·9W½?-##\¥çqž1ŸÇŒàW¡¤çœç*ûˆÛ¾d4FA^u©K4žlÛQ1jÃÐe”S³o6À5Å@nö5˜ç)[D0pjŽÔ÷U&À¤Z ´Ëö*Û¹Š›³ã’Ë› ¾ßïÏyžge†4ÉhC Rùúùeßò»—×}ã,sÖ¡Y)©µ:e°µ ^*×*|¤FpÉMîg`d”ÜÂZ+ƒh‹f#jÃíÀìŽB€`'dñ[f$ûú5åL?žsléRdγH#k-y!UØ#æÙTOàCšïÛŠÄà›£öÇ%í^mØæè[È6ö€Ð?Ò­]Cˆ Ê ¶È)ÕZü°®Z(K.•syK ö"#š UßCHVÙv²d÷³½×ãqœ«”Ê-ŸIŒèjsEMš³YÕˆ¢µsÕÅ’lÊ8m¿þ¦­¥oƒèZ »¹a-û›!¢i“@7—žÙ˜‰í´ì¨ÑH‰·[Þo÷ãyTÙÑê¢ àŒ}äëý¶mÛ§ûí»OŸþôÓ&øòþõñX³®UB˜À¹ÔÞ”Îß”8É{ž¥9×6.ã®Jƒ”¼í£¦BÕˆ’ªöï$}Á­K›µ±E¬¦EÝ£¨Ñ¢+£-ÙFܶÕ\ª/ŒPÛM#Ú \õáJ°¡¸0..}ëò?5::âb†afTvÚ dc&2ÖEzuK䪋FêãA¸t5xö}_k‚Ѳ]–çåG7Ó*ºU4Ò.àòÿ“œ­À³TjâW¼¬ýÀlXY—ÌÒZÓ]®U ÒK#ÃDù"ðÛÎ*cI—ïº ´ÃŸ‰Ø2¦\öšÇøéýëše—¯?…V I/õÎZÕ_‹DF”AÄó8#³J !Ù PkæÆÇ1ý§_î·Ì$hóëãQZϳ[v¤è˜³VExßoÛ6缦9µ× 骬3*€{vY¯LÙõŽÛrÕ ‰(+ˆåj/=Ž7 ío§>ìå&1Ë  Dƒ–ÍÌddä§{¾Ü?ýøåKIV`)+GîÛøüz?W­¹~óã×ßð‘ñé¼Ï9“PƆ¡HƒR»7*#¸!‚ÑÎ7©=ÿÉ.äT™Àl¹åqöÔ~¡ Wá]k¤ì[´?bžÀêp@Kríçóbh}±UÉ~h§f$"sU}ÜËn@¾Ê%l2/û`3‚¶—y¡ùGV/˜@áb~ôP#»#µsí¶áu±d9 Ë #žÇÑqB2¶1æ:¯¿jgµ‡®½Æº\…¨“Ë׳9x™CÁR­ò¢Õṵ̂.5ŒÁAØ‘H7×hø"/2i‘: 43?ƪÔ?Î’F'Á䱿²´eÐX*YM9¶cˆ= ÚÀRÿ´}1ʾ\lAª #MÏVs|˜S³–aʧÚ÷A[4ý8Zka£9à4d7¾Ò(Ýšu´DN²@!Э) F,· ðòüµ`Ñ^ùˆlí«ðnšÍJ|p¶}ì­¯Kê/ñAüð‡ýÉlôh›F|`E™”ÚÏ'dŒ–íÜRg»ðay æˆsVfÀZÊ ÉÞöý~ÛoûöxïÏs­5WͪÖA[ÙbÇ^ZciÒ<ˆæ[Ý@ÊŒe¤ºI \ù¢ˆ¢HÙÁógùжŒ¹#]Eyie\@+èe!¶clÃÄ<׺ʮªjlÛ±VF–VO=ääÅt8#fUÿbóEmËÃ`”¤U ª *· ϨÙf®¼uOVÑX`Ò™Ù ¹ëRsÇ%D sÌU=pÑÞšÕàêf¨µÔ&Ùª€·%ŽrYlé˜_ô9»zK·àÒuFò~¿}ÿúRòÛqžÇ9Ïj9~©Úx½¬ó9g«ðÄm%ÏcpÛÑ \U?|yXöÛ»JˆËGF¬mK³ôÍKýñØm >:Dsþ*é:ëR“‘§ê·Äj‚ØÐtšÙk®«ª­ú1;„mÄ9 Àˆ©–Š¿á?« høèˆct ¸¹Mè³MÁÉ–yÛ{HsŠÑ^}¶x¤Äö“±¿xF/.ˆdǧœ#š[~þtû‹Ÿÿì/¾ÿþy®¾|ýã_ÞÞžÏùœëòµJv2pQSl%¹™÷Ž<Úذïò3€&.ƨµ@vx/›jÓyp$ª`+2JÎ`»E2ÃF•»³LT#¶ý6îcïW¯Ð–Q²TßLïçªßq­öÚ‹¸Äß n›Šü1d«Áow| ¢Aµ߇K$·ö¢3. <‚×èÌa¥Î†2ZE#ÝÀþ¼cè:’-H\§¥ß¾6)€Ùb+ÉË=eEÖ¬dÛÃÛPž°‚`ÄË}Ù‡ìã˜ã¨µr°Jµê<Îç\Ñ—Ï´¹TAnÊçÒãù~¥øòz†2Pn!” šÜì-ÆÛqvú®ý$òj+Ž cÙüœŒ6 Er‹\%XÉÔú8 d•°¥#mW]]Ù¬"Q•¥‚½ïYK«4’QXÕuÍ«uFë¨#bYý<{^mŠ«ÀÈè?ÓA4‰fVÚ¼…&q;c]Õ”»‚·uûc º³õØüéåÓ/¾ÿîgŸ_¿ÿüò3äèLt~áWG¬µZËqµmŸp IDATÕ "/¬{™W» „ÁˆìÈü5*sÙèÑ]ö6Fï±H•rôGqÛ¶³$­Ò•ä dgu{Z)¨jmÛ>r¤Ôwïêìß‹†ªØ·-" µÆâ–Ù‰±ž¼/Ï'Íö–W0 ×ù4XïüiÐkŒmsYK[ä’Ý^Þ~.FF0«@]^á+ŽöærG\1†žø3ÛZ$‚XÕ9K$°Z×ùæ¸l®fê–œÓPûH¼g”êåvÎçq¶Hº–F¤í%¬óDc9‚ûÖúš_o›Œó˜S•½-Å6pÎj3GvH<·ª¹ï;Ïçs•Dà¶m]—ï÷Ûóy¶’#.i€V»›®ñ }K33~þéõ<ë9ÏÁ}©Z÷Ñ.ís­-/#Ù}9ÕgÀ¾bà#(`•®ª&,]®¥%!"?çHÖêfå@t ty ¨qmˆhƒ\É£ZÇ`{U{ÍžQ~F^‹-¾ÁÄN·š K0÷}ûüéõ~»Iøt¿Ÿç:ÎY«ˆã¡§I÷£mÜ—³šB¾Boc䬊dׂ~¨£½Dla"e—ª¹ÍVÂ[#ƒBTÕ¡RdôÕÖËn QHCè} 6bãv“,a•ʸÝv€–s°“Ý×B›ÁvýZ.t¸¶B8g‘ý(+Éum¼€Qãr~@fîÛFŒ„C@ßðÕÝ´g„^(R®U½@EªåkÐúØ&Õ`&Èt6‰|划cŒ$\Ë*D°–k `Â)'ÑÁNS½Ûè²6y»ÝüÕ/~1g½½½—Ê¥Œ¼o·§vÜYÂ2z¥JÓ}ç©óy¶`1»–ƒ¶“|½.p&_öütYåçqØØ÷Ívdn[Üîû¯ù³ûØoÛÞ l «ŽÅ’Û&82·Ì yÛ·ÞeR®¿þë_üå/¹mñóϯû¼oÃl«o4íµp߸Ü2›‘Æ%âÕþò²±]dvèž—u]zª.É¥8ìV™æ‡,q‰“*°]üΕ1ì3JrµC7F­Š u½ÜNœ¶ˆŸ6¶‘Fd™÷}»í{DdpÿXo1GdÿfÊKÃÎU¾Ìëý9«>ìþ×8ýMšÆµýË*Ì‘=^}x®i7wˆhP@ ?Ž(Œ–T?”ÖYUkˆp‰¡µìÌ8Ïg[O¼àœ. À!)ì M»—Œ$£}T¯%+Ž&ϘLp9#òmdUe^ TÀÌP³Ÿ€ìZí®d•Ú~e9 ÈP}Ë–îR XµfÕ–M}-Ìb Uµ¦m¸:hÛÛ{ïÚ,~¿ùõååx<Ÿs-P8=“<×IƵƒÀÇ>¥u®~æooOõ6—æ&Íx¹oß÷iõ~œ±çˆ<ÖúôzŸ%šgï˲gãÑÇãŒèÌŒ_îÛûãì½C®‚½Ê-7gðå¾gnkžŸ?݉¸mùöõñW¿úE0~øúÓ?ÿ›_ÿæw:Îã徿?ŽÑIß’F\3aÀðmËê5 íÿ´×úðp³Ýÿì¢Û½ûÍŠ—韆šZê¯Ð„ô*w€½èˆ¨¦Õ|QŽþ°"Ƈƒ^"8ÂZïTðªÊäÒøx<ÞÇsÂïsÖÛãqιeÈ1Íx1ÉÎ"64º>|36ŒàeÇmYêßLtŸÒÞÏ2›6 æn„¸VõÚ ¤Æ¶5.!éÈ-<3sιåc¨ìµ®ÝuœuMÞp5Y[y!B—|ÒTÛÛݪGpË}y{ëu©:6*0°í|¹ß‰8æI² ç1 Nkûóy¬+9íÛ ²-ž]æýæšL–,êo~ùË~úòû?üøý§—ÿä/õ§¾üôö.úíýÜ÷ d­5ë’|s$.eÌU>çqMfht˜<¢V½?Î_ü|ûõÏÿâï~ûÇ¿úÕçöë¿ÌÌçyüëõÏÿøÇ¯ÿñ·¿ý›_ÿ⇟¾~ydC #ÎS·m(ê¢1˜>ùãš™«½7"i~ùR¯À¯-Œßàr­É“á @%-hî­@ˆ2 Nö™‡¯Äð7ç7dýö8ûû?½¿c¤ŒU«¡ýµÞ‰¹Ö*Õû—§S-#£ak]ŽGt$’ -1}k­ÎŽ,#ŠŒF¨4;'¯Ì>e‚ƒ˜Kk×j ÈµÚ±Œñ<ºBø ‡›¼ 9™¹e–1Âkyѳ`tµÈ͇[¦›ãG¼Ð@ˆHzpˆ¸²® ·ñ¡£9”i¨— ]"z#_#УO´Ê!óýy<Ï€¬¸ò.™e‹Sìx?ÌímNº]6k~;Ì‘VÁmìD& xÎE¢–"˜Áþ¸­‚Jʈ‚3"FZ:¦‚˜«Zæû†ªee‘{ŽLÛùßýÛó÷¿ý­¤*ÔuM®<;;ã¬K¤‚ä\ÂÈø8µn}EªÈTU^yä°o[®®ÙßVI¯í5^ð,Iê=øéöÚ¼æÍ?þw91Ð:*hÈÂ7š°¥LºÍú½êC}62×2$ŽK¯ÿF3:ƒy¹¥~[ËÛm{Ù¶’dªêýñ¼mÃd¯î±q¬ÕÄþ6÷}”)+FÌÙœõzÎó0çªö~ªø Î^²ÉLÜ·íÚVkÌkóÍ%‚˜Khp–Q×Ú«Kêžäçñøë_ÿò‡/Ï£Žû~û¿ÿá÷ÿðÿ{Íe J?ûîÀjÕˆNÆsÍÛ}ï(7®äžâBÙÚp—³«hwö‰½ö :ú‘­g»ä:&Xv0–ôMÎì½qEû)ÁDãö@ šªŒêt›ñ±ëÁß Wöhgƒ ªFè´ZInÚ-_;põ¼þ¤—¸Ú%µÅáF+×ÿù'¸ö;Æk­eçNG+vŒè}BFÛ¾«ëì·Üð ‡âçß¿þ·ÿýZê90ÓûÈ5Ø;Àt=Ñn’çÙûðx'»j¹Ü–$ToLª¦V­³–k%[:gÉl èžò ׺ðd\7€ÉüøŽ¥fÔݘ§»/Ûj³m×` ù¾ Ä¥à7{{ñ±v•|Å0¼Úç'V~¸gºVÐŒ`lc”‰û6Î9[ë°ÿÅ ÑçÀ9Wi}zyéç|Û·‘,a*¬ªK½­èÃîp…c#ˆËç¥kŸ-ldæˆ(«J#‘d“„=fwsè;>´ùòþ°øóÏ÷Ç×õ·ÿñï~þùõùœ¿ýÃ?½=žÏçóùüý~\sî[îãr_o‘ó\÷½å%ßöqÛGèµ±}Á³››É~þ`5Â#tƒÉoNî}ãF^¤+zãcôã?vsÞ;§ÛÞKn[^䟼Võ=ãc Gó¶roX€/öSs]|¢¬µzÃØey#|¹jÝÒß·”ãuB‰‘‘ÝŽÛ(–ìül¿´d/캒ü¶ñ³Ï­Ò“mR¤°A¶¬åDµv¦+¾Ò ”cª\*ÕYª¹.*XîoÓýD¥V<Ð ß.Ѝ> ñ ÌºzRd$¬Œ°1ŽsÕ›Ó¥5;G­Þ¿ëë£w¿Û·—mû’eÚ¾lË™-îÁ@ôæ9Yç,g/>úðg\‹q?ZàyE¸ÿÉÎþ¶;÷’©E`¯@V›–¾>ž«*3 ^§%O9ûÈ@lm¼í©UV½ìãÚ爑‘i¸7d€#z¥{Ed[ô¾5â™z÷RÇ}{µ®Ïüm­ÿ%|`Ê„Wéñ˜¿ùýï>Ý_üòã>n_ß¿~úôÒ{_ærJ>Î5«$"#Hªôxžû–‚ßϹþ_ªÞ¥W’$ÉÒ“#"jæ÷F䫪«º{@6 7Üðÿÿ‰Y À ˜ö³^‘qÝÝTE„‹#꙳) +#2n¸›©Êãœïæ¿9È„ˆ©¼²¨¬†\´ÿìùÜ–/–6€çüƒPd[SUçŠ1hQVÕhc0WBFéfvå[ɉT×0)•Q+rEÌ™@ñ‹â¡Ò {Ä) ³ZÂË6ŠÞÆ›hµm]šçÇñ¬+¡[Û]ffú§Ÿ¿HÉ*VïÁùñ0å(U´ÿƒdfe”£‡CªªÐYÅf.Du0ûîöTJ‡I%`+jGQ™+³2cEÎÌÈȼÖTDÍ• Y«Z—s­¬œ×ÌÌÈ\IhˆÌ¹Ö&å+&£šŸÉnˆË}þl¿ ¹¹çËNiñVTÉ*I yŠÔLBR*Dø­SØQ=¯,ÃE0|¤Ôãqñý-É÷óÆ‹ WÃ) Ó*y¬ë8?!Gnš«¨Xi ¨E¶Í<÷l–+¤¨ä“{÷bçÜø’êõIm1M—ª‚™/ÌÇÀr­õ×_þöOÿéþöå—UùvÞnã0ÇÌð¡™¹ªfD–ذ,yFfÕ\ùñ¸Ü"×Z±Vfªé1@´­°6Y™R3cVÍȹ"§”žWSçÐZ šÃîvŒQ‚c˜™žÇP¨ZØ“›sQ¨®ª˜W@ª³U¦=ˉªXÔm×ë-[s&QWe)BˆŸHÉ jüÉÊÜŸêªâmddŠ ƒ ]!Q)±…±±"Öµ²²¢æµV†4ï£Q,‘ô½¶¢^úE [JÝMêvOoyBW¤¨IJ)–È2*®©²9bÕð…Ábeˆk%6¤Jºo#C;¢M{¨Ð¢Q¡A%«ÔjT$»µ`ûaÀù~Ü?ž32Eœ%Ñ)õ’>Û_bF «d‹•7ë¯+åšÑT¢ÊE2SUD„ìð÷·ãÓÛyøøòñ õѹ7ýzÔ^x½ÝüùLê­Æé&’+¼'DbØpÿøx”ŠAV”ººù5Çs6*éUmî-Ä1y¨JÁ¬ëxIÎlæjþ÷Æ(òŸZö­‡–o×Puüõù‡Ÿ¾|¹1#Yà]s ·ýD¬U9D)K+j2E£r…HDU¹Zn·$PJX:D7(*Õ52y2‘ELÙÌN‹»>-nciBœ—)em‘!ÝñoK3oh!à™K–Ð 6F’)¶¹jlPJ îKADÔ”"Upñ㆕̪JCÃ8Æ‹((w~2¼½²0Í*ÕªÃFlŠ˜‚}~DÜ„(*…Ä®­>7ÍeÄ´TÄÕÌ\Ç8ø±]Aïl0œúš„”f àyÍÌʈ•’±HP]™«²’Æ3®%Ê >,*³§Ž S(iNUyT÷ˆp`Õq´6'`œy–”È߈+1T*››ÂÖȺoÄ̬A¢²çÌÄLÍÅL‡D\¤Œûäž •”j½ßn™b*ëšê0S1SUW©çª¢°k˜f•!Ù\ÃîÏkÆ5üxÜŸs¢ž1Šr­ßftËp;OWÕãp‘²ÍófqF`PW©¿ªŸ«} d!ñWU Ç0»ß¯kÎù×_þö·/ßÈ#’ƒN*ÂJ¢²²VðƒÅ0¸Jf&øØ‰*ÔðÓ?C‡)Ý<µgYÂ¥â¯çokó…q&k;bced*d ‡I¡R„œÇUdTHQSµ"zTÐ!`€*s´ª¤’MYH%j› ˜E%ÃMÃŒ=<åƒ k-ŽX9¨_ÊgÐo&ùÖF#Km·n±´åD”¼7J— Ƥa[ƒ´¾¿%BM¡:#WL×á¦3² wœPflAco æ’’`MS–êŠàñÆQv׬µx[ÓÍÝê–niÁÞFÅ•u¶ˆhVšY¬Ìˆ—>˜<ˆæáQ±L>÷Fs­¢%,Ð5'x'4q½h©ûm#y•š©HÁÀ?tE´i¸ ª&Åß}Ñûu¿æŠ*M¼½se¬¼ÖäTÏÝbí#†RÑ1Æ5׎9>þô‹—ÀsG´›£H²6ÅÔ Å1ôy-ÖÏ®pGç‹V¡,ö„ò²-ݺ²÷4%…sŒ¹b¥üíë·ßÿ`+˜Qƒ+…’4µÌ<ÜsIÇH¤ ×ÌJdF™‰©DÖºÏÿïñïÆ¤¡¹¤*…Kþ–¢µ¢º ¬‚:Vv«4:rxzÍ`w—Q ·Š¹çP)òv;æÁ´Š—ÇŠ!iˆ ¯©¹§ J §šRÆÄ‘¶[žÒd?Ô0ÑRß9%®¢°N€Jô$!"ˆUªŒÞXR"YrDFŠ™S²÷¿ÿñ?þòs[ß3Ë´Ï*ªÌMÛª©€yFplÐB™{ÒC½/äFUÕ¹càª4‘Qæ c›‡FyÛ6þ³ Ed´!%K@E9ÕÚr¸ÏÝY+{ËÐ:й_4uh¿ï\ ¶ p³™9xT/ë¡m†Š ðû £©3ÒÇ¡j­KFTÁŠó<Ös^ÜR»A8~[«ªR’‘W fâÏ2Ž’ïÞN"îדdû­´bP½Y‰,Væy @ÆaÔÀ¼>Ri4EÀ¬Äª èýÕ4£¾¥ ]ü+PÏk 7H¤üùË7Wùx\nz¨Nš”3ՀѬÌDU¨Yjú~ŽÇ n½Š´4©ŒŒn&Z½Ù„!é¢T·¯Mµ©1`ÅÖÐ×K©¾–V=*°²Ui¹ž“v[É$ì¯ó›x÷TjGvR//1èÓo?š„PÍA]U‰lÒrïŠØ‰±}äÀz<+ü %ëËDÕŠæ¸kF|KD!_îªö¤À‹ËÞfψ©®¦ªîæchDDÇ_qæÊlÁD×óìã£de®ê-x×­’Åå —]"±r§CˆòzT@•€ë”4ƒ˜2Y{ܼ’n÷MŒG{oyJws˜ÙîlÀ¨ÛU!q¤ñ•&æJý1gèÄïp”j*jPS%¢ÃlôD\­÷+è?¼CìÛã‘U3ke©ë㺞Ïk&ÙÐp·¬|Î¥*cŒã´ÛqdeBÌl­x>CL¯Hõ^¥1X¢qR¦ì(æ‚ʪâmŃ+˜åUœEIk5«ʾ# :Ìf$Ç~ÏLW˜ÚŠ‚Ôýº ˜É ²jUÎg÷H‚¯HV­ÈÏïç0Ïj†ÝŒÊ y÷î¡Iõ*¯œ.·8„½Øïmh&D5#¯Œk Ï~ PîQJ4cŸ3¶6tGûr•¬*˜Rp¼:´Ô 9é D¸?!í{Ñ–©€)8>ØÝ’Hýºù Ä-ERDµwÈ[”f*ª2W0Œ*û»’‚Üïæ wݸK‘%Âï‚™?Î…£!¹¢†š•ZQ¨HÔ—D›DÛ;âj´­óÜ0Õa6 ÜTÑ{‡‰  óftÝC®hÌFFÛA7hU0Ô†ó|¥CG]•êèÁŽR<Á-"]ó,óˆÁ:ÜX–+%­kV²B 5pÛlf΂ÇTLÇÇÇãñ¸"zœ)à‘Ý8®™k ¤¹BUÿö·¯$<ž×®§ŠPSIÖÑëü¯ÊÅx?ÇáG]1g2܆#ÓLT¶ãN•ï!rkšDd˜ÄU"sèo ¢ÀÇc!KK2E•…ªÇ òðY>JAaœ(F«ãrθžóó§Û9ư>F 2Ü÷ì%'¶ñüaê%ÿ¡è˽hº]fœp¶´FÀtÇô"EìÅÀè¿%§ý¦KÈö½wÑ+:Ø[òÊžÖ©mÖÙ)ñ|2%‹Ôf^` û ÅÈò¡d¸ 0Ìxþr€§lj3Êt3U ¥J‰)c6º±¯±ÂvZTê§9¤8>ߞפù@MÀ­&·nf=ä©öb v¨¤d.˜báRäpX…¢„"˜j†Šð9F%AÌÊxeŠ %;†é%FÝ`¢Õk‰–½+Àª.nÐl^–UMd«‚4w]-j*U*X­¼*ijýéÇÏ•uŸk-nìKÝ*kU­XaO™kæP­ˆ1Œ ³1 ×\×Zï·ÃQÚãtsBA¨)Üô!Y3"¶|§G„ ÔÝŸsfK—)&*Ï—-ê-JAªi93VEecÜŸCÈV„©:'É©×ÞPâpÉz®ÈûyŒ*_«†åŒ-ë•Ü/]d°ÏäÖËD‰fµ5œã/&e‡ôÚÙ;ÍJ ˆ*“fR”-Yb|&C•"6 %…þod‰Q< )…\Z™"Iš6w¬û­àr³@ý•œâXSêJJæ ”Ì¹ ˜µÜu­—6Z¦ºòªÍ”E…ˆDÀŒ`HI¤9(.%fÝÏóU)<>žjš’˜’ŽEýñŠz.ÆT@ÚÍ…Èä¤Î2óÊ2k½áœëª×VåóCÉJëÕª(%h[oèèÚP™ J€¨J 22!š¥™å”jˆ¬’áí»'EHÔ]9#%ŒX6sÉD)JÊ«"ËÍ$—G`†9ëyu"#WéL NÃxn+Ä´ª®¨Œ„Šž©"·afvÌÌi†v+£qhðÎÅ(„ò”Ç㢚$#¸ëS—)‘u='£…Vf.JíÏ,¨ÔŒtÕRäªQǘÉzäR)Yj£Ë`ßzNˆ$PR.H”‘Š-r­bü›—FÄýQæz 9õšAç>_3n±Ù`Ⱦɀ-Bî%ʲ‹4—±qÀ-o\½@jåJ&mÔߎakÏŠì!ÐËq%/f¹J‰BijL `ÙÆÝæüMñ½ü1ÊÜÇÐç 0ðü0Wîüê4W1•4W@%¢†)ÍÆ»„–•HÙoV&Ûlåj,ü8ú*”MOÃo·³JÜ+rÐ &+¤#Êû¤eÇìàÕ"ÖqxÌÈ”BéžF šfef‰•æšûe1`1F—?e S>8!àbšSÛŽAždôº™ ¦¤vFw2±…ÞìH‘gÃ’?k[¡¢8ÔnçøáûO®ÃÝÞSr¸“¤öœWT=žOtÊ@ã`­¯ïöS³TIi­ˆ²®Ù;zn]‡ZInC=8QS”¨Ÿ?½ÝnÇûíöþö&ÐûãqÅÒL7ýüþvÍZkU‰õðZ:›FdXû:žk‘ﮬe4³æÊáÚ…A׊uÍ ·Œ0³xR¨{$éÅ÷dSO˜´Cù¯UQÈZëp“*sd±ß0¨N‡#†{OÙT½ )³ ɲª²š³‚âf’f×D•øná˜RZ›«]b§­‰°Ìx =de²ª~ë([Ñ.²·´KJžójÛd×o¿qïïkü-S™ F”lL Þ¥ißfLßmOcqwOV«©v‡Ù¡UP3Åw¼”ª‚ËèƵÀD`(1Í’áÃÙgÑãÚµ6PjŠBÌÛï•HÕ"WIÕÌN‚27ñµ":"g$óÀ[]Jª'§ÞÛ®Ò6c.¬Y‚aE‘ÅUi™2Ë‘*ñánúþvûáó§qøí8"kFþòå—_žL¹Àe5Ö*WõÑ®¹Jilv‰µûæ(iVó˜4_\ÄÜ x;Çáãt;| •÷îø]ÝõÓÛí/?p“Ò×ÂУw7Š0ªä–ü¬ í þÙ¬ãkpÍ <‚¶ô¨zÎPUÝ€P^›ª-%¡Õ@!/ŒJ‡éÒJº!즮ˆ“/¼òûí"U‡ëB•„beD¦C}±gLõt®ÅêÁ;G ˜‹¦Mu( ¢ BŽZ‘SÚ+¨’)(¯÷ƒ%wk6_d5Á²´;²öW¨!€è°>nIl‘²v”cÑ]ÎBJ4ºÿx¼üG© v“*Ù—ýJ ßrhÌèMÔÈNЛÂÌ©Kg,œ(ºù/Q”›ªZfœnÕ:íèÕ ˆf¦¹V–)õ? cp… z¸Šêávcøáך™™Iø|DõèDˆÙÊ—á¹²;åL2 bÞÇ*²uú¥\ý9%jÇ0?ô‡ÏŸÎ1š‡~V-|yTFÀÔ2T ™å‘}9!*mlÐc‚‘wÙìƒt¶óÄ–Å@ͪázÃn·óv;8m˜Y§ÛµâýýíË//_¿’™‡YŠXtŽÑ^…r ¹I¯¦|†dÛÙ»­µŠ{[jÌVVd¾>g^ûÎ१ Ò£ƒR]2À:O¢©;gA”'·’-¬-°ŠJI×ÈTÑD@›·Ù5!‘ß®yšF– ÷„îÊ0Ú6†·' |5™|g´kW]Ñl»è[¨‚œ»mê0êZ¤PÂ$¦ß›dÕ¯y !ì‰ïm#Ÿ`ÙªTôÚ¬^Ýkš‰‘´¯ ‡9Çã(âÈT‘¡Ú› ¨É z&¨CæPåv •R •± `7\©5Åcưc,æ©Tñý¤-‘@‰Q‰ 9ÝÞnçûíMÍ<+£IaíR¢‰4õ>í¹ó¢yšyÔ(æò {¢½BåÙ†0Åš‘(¹æ:Ü\ncŒ1ÜÝ´X-$Kã=ÇßHz´è¨°“ïz–PôÀ¸vÌ]uêz‡ÈÄfz˜Ž1̦Réê‡êíðûúœTúGDJn+{ôO;y3åíæóZ¢ò~÷g–¸!¢%éæ¶"˜N£TÜCV¤j©éã9›Š+HˆÝõr;Æ\«}Ç”+´Ë£GÒ–‘¬PUâ=e8EìÅ]œ0Æ=Å[™7S JÙRC+Ø9À Y¶Ì؃±°bÕE}R½:I&÷É–•a׿|È)R\:Òò×nóÌphƒ´û4 îóÇEJ¸ÊÛ»õ”× ×Á¿Yë7Ýko)ÏyæR~”h2d%™öc©ÃœÚNËXPjCƒª -g(-gaÐáJ—•h‰`¨šZ6;W!©ÆŸjh‡À(oîUBÝ©ª¸ÚÛ9ÞßNÃ0±RvîLD¨ëŽ¡¶øÁ¥(êð-q〤ã{ªš‘\& §…bµ4ùg|üZR}μ?ž¿|ÜŸs‚QŒ@¶lWÌ„\SNº¸Ã‡¥íE)r+òh³‹¡í¢ègŒ¡f&8ÕÝFõBÖLU¼¿¿ýÇŸ¾VGQ¨÷Ûw¿||i-•²´Ðù "k©YÅÎ'w­”ëZ2Rò•|!$R3ý<+˜ dæÅSæ=ˆÎî’øÖ«ìcô8žLwWZÖL@ &rœ'ƒ Ì´®kv´e4XµE6LáÜ: £%¾KÚ*Îbš±È±9»Ä&ú„ lh‘ ­Á椫ÊÖ]²âÊz1ª[„ýª¿«WD=b'ÒKÝ/íf ¤”s®O¯l–¶¸ËUKu0ÂF{ÙYn cžBwZI–)£¾Õ¡µ’c”Ã])n–ršª(†;Ë9,¦ê¦%yø!’·ó¸73÷9c­é‡]sUÉÍ5‡&et˜×+eEÒyÈHè<+’IÁ™Aâ"”ì3¶æÏkÎçynV¢ÏçU×Z„Ð-öþ™/œ)ãKQ|‘f¦›Â.Ðî ù borˆ>7w…(ÜÝÆ˜áƒrx ×ýå~]ñ<Žš¸è·¯,)ï °˜ R“CÝV”ó× .Ù”éT­\ATe,z¥¸’à®w£ªMHæpbS{¢@í;ç4H0€Û ooã0ãkr(Ju8ósœZHwWývúTÖº¤}÷"¢3 6°ï–öR2L·î€ñðÈMæ~mòy)ÄN"à]¥»Ô¶ê4ZêÑè«æ0OûÆKUež"Yf›i #%)¤¿¬³^dФ Oö®pžÆyŠâôÚWŠ™p|`U,î:+Ž¡dƒ¹‰@|¨Á³ñ¤bj;ŠŒ¥j%0Æ/C³ª¢Âpœ‡jk½H}³¯÷û¼V6QÛ(K(†Qe§_sæa‚܆‘ì„ij–«þñwßÿÝ¿ûçýË/¿¶’Å´ ¥i`¿„/óK:¸BztΜÐM9.£ˆJrAÚïžpHÛþRQÊDw>_ à¬\ ð”æm”€_™.²²œ<–Ê(U˨@æs*7ÌC N'3'GRšºêŠZQÃññ 8²ªj®È”Ȉª\ÁïeFE.3Ÿk¢ä¼éãq÷µbº* .¨€(é ]3»å—§%\K€˜~mŒ Ú"«DmE¸ ÛHÙú¯fìÃ[_ìÀ3r˜ZWG*•¦^U6À³¹È¼‰>ôÝ€$Ï*1×X™Uî¶~НhU‚9—Â3¯k†™‰àñœ¹bÎH!L¤´š—Ìã_DÆ©¸Hæj»­Å˜FúƒÚÍV–¸!7#ÒIZиt$ö©” G›jéY©‡ò‡ +XYŸßo5?Æq8†Ÿ5ŽC 7;]ð횤~¨ŠIýÝ4ªTÇÇã©PתÿÓOë\s®UÚ²æ ªž‘ªHêkÞ"Ô—ì9-ôpsèyúþ§ˆˆ?}ùÚW#Ç;¥]²œÒì£'¹Œú5wýeö%!·#J7(PM@ÖC'7Ií¬+ºt]€Mþæë!í­’îÞkóÂ΀‹˜)±…©t%¨”Ø­ô¦ˆª—„ŠšpPÚÅ"2"“´ßúx<¯kfÖÌ@Õ\+KžÏ+Çmç¶Ë¤vÒrþ~ “³ëzª…Ôµò0ÁÁp«@>½lAo‡?Ÿët½V§×ÞÆÈȹÂu©•ñ¼®Ó=²wÕ:Îñ¼?T‘úöœ)S¢f+rv Pɱ#Ä Ä×0*K0PçÍüéû>îÿ‡ÿåÿú¿¿=îV¤EÿÊ€ã„= Y;¸g¨»>7…(¶Ò3ØzÅBˆ½Ž!9 »Wg±;¸|“â[-3u·qØ9¦žÌÈÞ|T”Ço%tÒŠª±(5C‰š’ʘé¦ÅÅÊ,5É”K …”ÔØ!3±òºž™2×*ÉEÐÉs.´XP3¦±R©æZH@ÜÍíô¬TCÇ9•„,æ_ð¤$¸qUŠÌ%/~¯©”0ž»(•ÒÂÌÙ-i6©+sã N¡Ó뤔)À´*L­Dý5ïrDÄÌVÍ1àµÐÚzîŽC"«`Ü.ðíÛvÉ•uJ)t®< ÷ÇeÀZq>²jUJ«Øý¶Œ±Ö•¸àzÆ¢£ÄÙg(7‘ìˆÙÈ2Tt$˜œCçLˆje2)šfDI™©¢0L3ãýö†*â 2†½ÝNUAF¼½ß÷ççOç53ÖÇ A×Mn‡¯bYîæ@AW†˜f’úq¿L •Y™s§TÊÛ0ÕŠ˜÷§YÄ"7ˆ²G+LÕDÖÞàÇæ5¨Ú÷ÃOŸøúq¯ˆ?þá÷ÿùýOÿõÿù›ÉP"(úˆíå3IFNgÂà¹IÌËA[ꊭ‹Bv´œ*ojn89eÈ}˪Â]™øPΙ6X¨ñ–³Ì0USD„³‰2­F(GeðŠK‘ÈÅoNõ˜«ÉV4"Ûb6W¦%ÑQyÍ´ÙÆ~êÓëÇL[)09~úév¼Áo¨fnE3àn× Ò®4\”T™µ1¯šU –Ó Á´ó¥GOöS*Öº½X•µîQUx^ëºVe dî8®Œ\™ ÷eUDñ쥥¾ÂÁ*ÆV¥î|¬5ɰoë–ð²æA®jjNwˆª ™p3è§÷ãýLDzÓߎÛÛ9ÆðžJŠÞq³Ì:o‡­AU–›šéZr3#Öíú˜ùŒ9Ô¿>ï7ÓèEuž‡ÏŠm71ˆ)–YReª5‡ÉTn)%K µ¤†È¦34‚é¸ùç÷÷,™‘ψ5Wþó¿ÿùï÷wß¿úËןYyѯNô踗P%’Clñ5K^EBiåî \±R^ ˆ”q_dD÷—ÒîD&™›硦<ÚC¼ëDæŒÀ¢.âãñÈ\UR¢ÉSªzÑVU‘ˆÕ>¬N=¬¬ù²Y½ŒÐ=ln6,5÷–-"×–í5“¾=Т€¼¿™é b>kÉN7j® •ʪ3¢RRªÛØldªd®C¹„áL¶µï.ˆ ¨$ÀÚìMŠäÄŒy8 0®‚`á, à¾Õ0/J’b­2)ƒ& ªÐA5_V­Œž}'Å®âIG-L¡jˆpàÊŧq»?Ÿ;&®íWXxWÔ+ƒO l‘eÅ–ÝnpW³Av6„-|[‹l•ÃÌPuµq3¿ÝŽÛywÎY©•¦¯7KJÔ`¬²«þr>*‚o9¹2¦>"'0·cUQR¢sæéÇœ¦"«†[]ó0$F¬šÉ5pIátÍŽ4Ѫ”cø§ó”„‹3ŠÚŸ¿<~üüÝ÷Ÿ?ýùëÏ%bòZ-QFkuÛƒ™A¬¸H¡í ¬§jåQSµ¹DŠ0¼®”‹øVRI?LÙ÷9¥Ó±ø_aôø\†µ"…@ñâ!"3‚«nÇZcÑVú z¶CŠÐÐìÜÖÕCø—X½?ª# ýRÉš™S·(ä²ëõ¼ðMѵ®jtŠh%±¬P©+…‚Z¬4íAEH™éÆæÃçZU©b¥›MPAÈÖ fÀ¤R`˜‘„5kº ÌIß¡‚Ù²‰·›/í°¡"©.ˆŒ_MŸY¬TÉÀ|E`†yÅ×xPQ(^2—dÕpÄ¢{‰®6…i¢F9HõüöÕ02¼$º‰•7÷ë7ÕáUëšß}òãï~c^çí<ÎcÐÂ?×*¦ÿq–ØD»Œˆ%¸®‰æ‘3#b]™nþéýP`Ee,F¶•HÄ,°«Œ­C]€ëZǰûc­UÍ5ÑQÕÊ¥îÖ‹éDeæß~þ¦Çýÿüßÿ·?ÿ5ïÏgdÍ‘ëãùøÝOŸÿÛ¿{ÄÊmŠo?W[½v/ˆnÌnŸ÷Øy,/_ïÎk%€ƒC1¦B2œ‘æ’RÀª´/v¨RdÇ‘jUä¬ÊˆŒZªJ¨t“¹‰¯Ô+÷ö’Á˜™†ïØ"‘\®XRa´Õµ¯¼`zíV%ít;Åš™Ü´M§”,”å‚bÈ×7w7éð#d&ÔÚ‘EoæŒ+«’¹r´F½9‡¸é I“"ò`ˆ†ˆukØ™`è7gŒRÁŸ?ÒA–Eµ5òzjI¬ K%RÌAþy]‹ÚhÃ×\®ÊRý(äsθ®U -yòü ºÒè§ð¡éçÃtÎØ6RÆb5\Ÿ †t :çãµÁ %<9„¾Æg¬,9Ü”êíÆ¨àyÍ÷·zÎuŽÃÌÞnÇÛy‹ŒáÇ—/_¡°ªIÔMÉšÏ*áìýv°æ¢Ò ®ˆJwœ‡©ZEPº©nx®ˆH#“Fõ4ýxÌ:ËÜ"R çyb®2HUk³ŸºÚ§+Ê!Äøÿãçï×*î>r’‘œ×óúþíÓ§q|]«õ@ àîêJEVósçTRl“gö¯o½Q•°äk ^¿K©m‚©ŠR6¯kaƒ¨pÚù_kÅ6ݶqQ²˜ü¬ŠŠ"Ûö¦¶ª³—dI3Âàå­í:iõß6ä¡ï¨èZ Jª³£;X¦Áp)¥å-™Kt5)MÌ ÉU€“ƒ™jý·j‰;&÷¸h×üÙ<ܲ žÙz&¢É£3¥¾šo&÷Rý«lÔj)Šr°M|ëçÏŸ˜•f`ìiõ^§ ˜+†²Eë®ÚhÆlÅŒ¬ÕdE´o¥3‘Û ˆŒáš!‹?ýþÌ_'x“qªÄÑší•%Q2¬eY}PŠœNcí!*Ps³µÂ!ÃqÚ芨’Çã¾^qçYs^“ñ€‘YY•3ã9—»¸§ÂÝÄÆˆªcÿ*o·ïÖœ+"s%ä<¬ÝúnÇyÇyçaT@rÖ$Öh¦c0<2øîí~Ÿÿí_þíñxžç¸þþöV)_¿Ý×u;¹ÕñÖZIÉ«QçÍ] äÞ×¾ §éEo[%Þ IDAT‡îY ™ÙÞ Û|ÅM²®™×œÏ缞kE>®y]늘+hÁáX«3ÆHI’»†Rtñ\¹Ñ¥•€»BEÑ;äaXÕ½œ7ÒôžUØÁáÊ8îªjnWݘ»”¥Ý‰£ŒÜI“2ÅZù«Ê ¥×LÊoð 3–‘MUšª”·‹¡¤À5z3»º 0Âß(­ÎQ•ûó¹ã‡ÄÃŽ,“¸~ûv‡òOi¯}G—£8šŠ,Ü.%¿9Ö"ZE6oÑQ³c(«§>€šfF0_R+U¥29íPTŠ mk,5:œÉë-FyKûH8^à–QYibLºàêî?|ú4nž‘âz¸?J|Œëþˆªçõœ+­Ä fŽ«&Ì+DjV~ºîN‡1ÃÚ+ÓM¯5³äë·/ZhË芪²ã¤ó-cÓe³Ûû Åýq%çr‚ãôïÞÞîçŽcJóÔúv{‡¼Ü9×u­ùùÓÛ_ùÔÕžFIíê´öÅ"‰Ö^cGö™AWvK‰ÆÃðØIg›Eu !LdI)ƒ×ö¨,6œ ã‚ÚBÙha7¬%@×5W𙫬Ìl&žɾE­Æ6TdÒŽïª!Ð l4åÕ SҊ̺衬¢(wƒ?$¥¬õÞâ;¤V"fÕÞøÎÍËèXô[GKƒKšÚM*Ù)¬Ô²Pbjs†)f©Ù¼ At¢˜¨¤Võ€µ¤M¨D͸Œã¾„& ö~*§ZdÂP‰œmDdN%ŠÖÁ:a¦×ªsHDšÑ°­¼ºHeÿZ…•Å”ú¹J!®ÖÊÇŽÜÑã=Âk>⯶mÁa¶vFÇš©¦0”•qÀ ãvø§·SÍx?!¸ßŸÏÏkÎ9W¬¹i°áÈ%±²……}÷éTUEî3ò¹’?Ü3^Ž¢dIÈ*¨ÙÏÇyµá¹‰VV•ÉQy­Å˜àüãßýË¿ýÕ«ÊMÇð¿ÿÃøé‡ÃMy¬ùý§7SÿïúÓãZîÛ%H$%Ú%â*;ÈeS³¡2Í!åhEúÄÝ{ l¨ì¨fŠ—Ð€’”sÅ ÉT99´úQP&˜½<#ÞV4jÏbÅP3º6N0w®/'«k¢Êð$ŠZ,µ…<ÉèÉ~²ÚâÍ¢j TJ46«¢^ænT¨AÌF•Ø>z8«Ì€²â‹Dü‰3ßN¿®Õb÷b†„UåŒ%’ ãÔ#Í)X=RŒâiÇë• ÈW(ÒÎöRS&Ð1¢ÚÎàæ Šա$›3 „01|¥):àPUVfWêm…á›^ Yh%-,\«jE¼oLG®—ËktéÖ•-]•d^õþv²,0­1ü<‘º®ù0Ë”9¯ó8#£JSÜo>ŽákEDºaf†)9»ÙÍ ª‘WÄŒd ÷œñ¼¹ª’ú¤¦·úº©¹Ö§Û±Švy¨DÃÆp‘ŒÌ¬úãïÿð?þåß³ÊP€¼½Ÿøÿú§?üî‡ß}ÿÝ©£D~úé»oÏGÆu($DÐ[AªÿR$²ÔuÛŽº[45dÊ>œÙ6X•­i…è·ê øªNªžV¦AK˜”XÅ•_q)ôS©jÔÎÍ¥­Q@2ƒ»fÖ5Ìs3 E2"=ºÍÚ„†ö7Uk·^›¨Ÿä 6Ú)e€µØKV§u4€ OUu3J`ž 2ƒîÇŒª Z{³3ewSJÄÏ1|EAM’øYEå–9”ª:”#IQÓXiª‰´çÏLØe´4J•p£Êr:^·cä z¥ÃÏ1ÞߎãZæ†ãUòËã1g|ýv¯Š9MT}8@²Ôvb.gbPh"„Ô:.<‰ ¤ˆd¦!™i!™õN šd2™vZ&6¡¦H6° $TjȬœ_¾1"î½ç¸»î7²zI¢†¬÷"î=ÇýÿÿýRÎÅ¥‘~!ª5V.‘Áüt*†ž‰'"Õ]»Ñš$j2ÿÂX­ÞÑ#$JÛiã‰@1bg‚:ÛѲè ÞÈ@D®ªUK›“™‰„ÖWãgL$õvÔ„‹ 9' g% ¡/6!±k@M™É !ˆ%ÆÄ ¨Í irßæUß÷]׿ܶÙE¥– H§ZÇA™QŠ‘ˆüú©@Õ÷–FjZ™HÌ’÷S13‰Puf bÈbýÿ®UR¢—ZÌ™J«¦è n@UcBœÄØDKñ=U°éRB"F¦DÌœˆ‰ô]ëŸoÇ9T¯ÉMVµa˜`µì·SµY¨Úp¦ÌIͬêz’í0–*c-RµªŠ)!%B5a%SÚ¿ÇÁM2µ†ÙD€1qû•wÞþ·ÿßßkKÔõj=¤Äh°ÝN§—þ­¾Ú }“rnԤ뚩NLT R\• §C` E£U(»ÀÃ|±2›[Æ„(h<—ælÍ\}‡D†3%úR‚ÙìÝpÜÝ×8³Ó>ý•þY3¿êÇé˜^R»§©˜KZ“TBF1ö·dTd¾ IÄ9ܨ±îÌo<§yè2ÕZUDT 4!‰ r¢RªƒÁ1ÊÓ8–âyY׎y9D܇è 4W&¸úì[Ü ‹JQúÂÙT  ä Âĉ}iè¼Bl2Ñ¢íRòôŸªŒ +úÝ›Qd¶?F‹*âfÀì-Y$öm£˜7!¾u>Úó‹ErE½( €aºŠ½SàŸqÎùûè˜ȇ7>5óC:`_k8|\ô ™È I8¼©i´ª¨¤ÄfØ5«ˆˆ¶ ”Rú¾WѶIþµÏ̶èt³ ™TUµð™9º?FXE ‚á]‹ŠŒd QK ÒX¬íúL3‰H"ò Ý8Õ®M¥Ò0N/Î/½¨¥¶]nJ–m;l·E•ªVµ”hgúÆÐáÆ6"9ç&^†¾hÕ¸½ÇlΪ ANH‰PâÖeŽ3Æy¡ì™5@¡ÏpU&"þí›(¥<ÕŠ€"ŠÀWEbFP?=Ñb"^.{­âG—¢¦ªUÔÀ¦qÚNu†©”2]ê΄€HnÙT˜ÆÂ‰‰çEV¢vP<m¶@£?_Bt Aà3õÞ/1‡XTɦœ«èN—`̤â”OË « sJÄ~õõ¡×výé»h[fdJ Öv͸k•œãÒ4yØmn­a&ÎÕŒSêS#­^m.3Á8ÖÍ8Ž¥€:@ÅsòÈ„«E+ÕZjÚ¾EÇ›fJ~pJEÞÿò—ÿæÇ?IÉ|¨C÷©ÊÑrñìüâìr³ÞŒ‰©mtm¿½Øæ6¥ÄZLÑ8¢AuI Ûœjéa43Õ*þv0ŽÇ&¤jÚ$ö˼ßÌ‹{aø¨¬Ëì Ïû¡G‘ ù¬”^ê0§©ζFr1›‰RħMÜ•b ó„D³Ä¿œEÄGzø#@š'º>Mj˜'Q,øÁÉLb`IÌSiZ‘fßÈ(•TÔ[×¼ªè#ÅóI éP~šâ¬dBUHí'6óO!²/æÍL A™˜1” ;ñ‹´M6ec‘ZêÅŤªÑà?†a, RêT«ÔZ•<¯**Ñ&, ¬†„ª`UÔe†ˆ¨b1*sPän+åc9' GØ*ƒ™©úxÎÿ&›½‚±ìòºnÜIÍ,±Û¡VÍ)ebl2ÏN'Þ3µ¹I9@×µ)%©²XôëíhU+'"äœSU[u‹†Óvšm"DNLöMz¸/®Ö¥((XUèÚœ™V«þî͵Ԫš›¼ÝLÌ´ÙŽ›a †~îÈœ„'Ñ©€5XTf!Äi¬iW‹åÕÕz’ZÐeרµ]&b¦®iEÍïïW¶Ð¤¹é¿PÌUU$To68 È¡Š‚††t–1ïœàQQŒÚp­Öf«OËŒè¥HÛ–`¨h&FÙ£jªœXª£L ‰±**ZŒ Ôæ;8ëÍ‚ãèª%…/˜0ü šˆ* à ˜h`äLÌ3{>,öO«—b'¢ÆÍÌ¢JAµW ùÉÁUÆ~ê#ġ͹TÕõ8™¨Ë¥ýg§fW¸5ÀRª ³ÔŒ‘&˜¿É䯵x¡™ÅÓ¯fâc,1ð–'¢»xjE¸³ÁT3²]$~?ð&G"Í ‘Bög!VÑœX«º}µl ©TYõ}Ód&N‰r“±Ô©k—R¦ZƒéÁàjCO4v]ψU…‰öšÅT¦®mÇR‡aúøÁ£Ç'/ÖÛÁw†‰p¹\ìõo¿vg¹”ZsÊW㪺§Ã$Ä´èrQ3Sf.S)S¹wï΋g—ÄÌ`fd .õÏÃåvûƽ{Ÿ?Ð3@LýtCˆU•ƒš£&mŒ~¤ÔƒÃÐ4­Š ª‘‰Q&Ò\mR„Žr† +#2‘’šY ”ƒSBC¦”˜¸-˜æqÏHØÕ`ij4ª£øêCD‘ ŠMµNS ©¢š¦ŠU”Š?.æõŒG´L ˜ùnSÁÃâжívýÓàù¸8-¸ÈŽØT™ÙÜÅë4PRЏœÄ1ç%ŽˆD„ˆ$¤æÜ>7qªƒ“A ÀcË)•ZCºÀÜ´JmrG‰û&7më¡·I¤ÉÍT*%írÃ@U,3`nrbÖ* ¢š‚BÓdUKÈØò8MOOÏ?øäó‡OŸm6£[qìúÑê7¾òÖ½[·Õìòj{zyi8 !#RÎ`UM»¾9lûq«Ô*_9ºù‹“_ô‹®\\¦”dª@N—G©Õšß¼÷Êö£ífšˆ07i9Uk›îǹQgÞÆÀ7ÆÑÂyªŽ™Åè‹C&Jukƒƒ;MÔ•rbÅ!6ЈIÄv <¿ð‰Ÿ(%‚o>•yà ªV­z×/€#L b†ÅÔaHÑWp= ÌÇšµ\¾6TeEX_£e¾ÞqYÅÜÕ€ÔÔyn* }´™"õ#BÑ+ÂZÄ ‰q§ <0,¢FqdC0(¢Ac#¦Wnßð”°ªº¤ÔO €‰"hjD&…ûGØõÆ€mJãTf ”j6sÆÀÜ­ã2=p–Fü,p³ˆ8M½è èOŠp°Éü fHTªóQÍW¦þ6 ‰‰wÄÅUG‘˜ÂhK‡ ×ã¤N|açMa­’r®U¹HUU&ƒ¶m¥Ú0–†ru/ZÊ©”Òt©m7£‹×+`›;/ÓAÊYUK-]ÛÕiK§ééÉùÇŸÞô¸ÖäÌ_zãÎ{o¿½YoŸœß¼uãÞ«wZ¦Íf»Ç*Õ "òôôâÕW_ÿàƒkŸžõ-"XìÛv½ÝTД͹úý½öhÿ@ÎNš&];ØËÔ^™º&¯ò/ˆ4#jd*<è‹»')XQ‹&Ž3…EçÀw¤½àë“h2·Îî'p鯆lÊWy¤¢è)³ØVª%Šv^ì« •ˆlöW÷K¸÷Œ<ƒîïàœXj5f÷„Çê“CGá %àY 7SFÍrž›ñ VBòt±ßÍÄg6sQw†J¡ŒÿáÍuÖŽ»QÓ©FNÞ7¥ úàáSäxw ˜»RELµ–ˆšh™TT«ê4•"!Eð–ªnK™Ã±àYjšO¼Mw‡Ä*ØŠx3?¿PøŽ=¹‡ø˜ò â˜÷Xæ:oö+î<Åõ(Ÿƒ=ë—«Ûhrd"¦¸—»ž21rbœû;7j­U×ÃÚÌ)%ï7"s+µ^­·Õ´i3¥`95šsnºF ™ E­ÔB9K‘Oî?úàþçOŸ?WÑ©ª˜59½vûú½»÷8¥wß}ûî×jÕÇOŸ®/.^œž½8;/SƒË«+'3ܹvV3·¯¾~ó¿ûoþÛüõG9·ÀØ´yoµ`"7 çÄœ¸ˆ•i³Õ¢ïúnµZlˤ*± È/È\3Ð`ô¾tzRɆ^ì”Ù̃ȯ}ùÊÛÇ¡¥Y„jæ³Z"P(ubR »]šßPC„ê5ŸZyÖÖ?òikUEÄjVk}©¬1Ûe!âÇñ5ƒ4'Ei–Q%vÝ."1*`ÓdJÎQ‘”XÕD½ "‚;6 ¸®5 TæZ6›Ë^³, ¼"ä[ËêíæøvÏôõû{Œ™¼'ùxÀ±TwzFFcç ,"¡¨2`u$jÆGH6nã;y¨ØÙ,³I$®€€fV«*;è ¥*ÎY4Tÿ8zÍÁŠn¯PTÜÓfóÒ†j¬m,š‰½XªG‡}Rk˶_ö]Û´‰S-žê7N”ˆ¥êb±ÐZ¥ fVD¢Ôvˆ‹~Ѥf3Óf|ðøéýGOÖøÝU¼ö†7®ïÿG¿ÿ»ÛKüÉßÿÝÿæ§ë͆`—yu¸¿Ü_,Ú&#ÒÕvÐR™Æ«õ`0ÜØ»ù³ŸþÔ¶‰RÆý%]]%"Ý_ö°)Ó"17œö]››ç§§™CkɨTÁس !ˆˆÃŽÑãÑUÏ3·ùæÜY|Âçô; @¼øb89/‚¼’aªÈhƪJŽÆð§[sÊ¥V ¼"xWVÑÂÊlf‰ÁAi¸#wÁlâò'döíq@\ؽCäGk2ÕÙà`Œä¯.šU‰fþcDH\_˜(­×[ÕRS“jä *Ì\ðã;ìPÌU f¨&³4Èw;<£J @EbéãJuÀmL«ŠCx¤º6V=Õ_1›{Y~'ó¶š/• ûv‘ Vkš\¥ú¾7ðîÞì@Ÿ‘ø—]ƒ(ÿy—«ê:pNä%O$ ‚Qˆ’‚ "èÍÎ(Ñ;¦Ô'O²óÕįßÜ£Å<AÎùp™8儇ûÓTYjÎ}•Š }Ûg¤Ê©Bis³èûœrÕ…0¢6çÓÓËÏ?{qq¹&ÇIt ýöw¾vãðÆŸýÙ¿Û–Qj­"Q¤’(=?9;?;¿~tpxxH‰»Ä)ñv(£”W_½ýìñÅùú¡¿CZÌ©kE¤šP"4ÍMö§Û0P]t9w|í`_ª¢˜jmò¢m2z% J”¼Áâ3ã{rö3ì´iòÿxr¸—¶F-ÃuQN"‹yz”=ªM3íÜ·!ð“êE¹™åè7w¸‚ˆ¸4;RˆŽî5°ä³:B?p!‘ˆ&Š»¨º‡ØâñGÄ,:Í4ÔŒõ¤¨,ÏÁ~3³ä£¹ba±@fQaH(âCžoÛ5;àìøÒÍT?L$*„Hâ9*ª~rðë¸W?"É `Ž‹40Ó•ƒZãðë½øùµ!Ð4ŸM+˜©Í›¤î.{JÉ ¼þûpŠ7îbÞ.ú„„ä^'‰ÿ _C‘c£¼]èŸ ÿ¬€ÌWeox…|–ïbfªâÇd5„”¨w½ÉÚ¶msòïÞÞ¢_.úVlØnsJ¥1›D:ƒ©–©LmÛz:‚3Ûd9gQÕR§Zž<=9½¸¦RE@ìö+Gßýê{}ö䳇ϖÝêÑÉ‹2°X4oÝ»Ý4ݧ÷Ÿ\mÖ)en6J|t°β•±ÉýÉÉÙ$µD–‰ÁÜ3÷]o*DFc)¦V¥ì] WmÛ™ÖÅ¢¿XUZUÄñV¡òž·.¨7 aÄ+‚Ä©|hLè[%o@{LÂ"¾âŸMˆÅãO3 ?>1ž£§Xäþ«;’B7»=áKœ†Æ#Õ믱zžÛÆþÕÕùŒl÷ çí_W¼ó¥Þ-µÙÒï¿.!Íà ù&ï¼ø×f³œçç)_B¨î㙥pól7Á –|sfÕoÕ~¨1çµú¡CЭˆ%š==/1õëóœK€™ªMrû’íº[æ'^?™ïžl°c1;Эoºõvk`™ÓT%m´³Å~¯˜ a‰§y‡ËGja! è_ ɼ+ì…×ç¢ùÍ“LTRb÷d˜Z)5,¶€]›÷–Ëýe×·M×4›ÍÔwÓ¢_è4qÊã0ÖjV«¬7Û”¸É)xÏ9%J©Ïè|­ZΟmO/¯†aëoØ·ß¹ýÖ+÷~ü"ØÉùÅ4=F#J„›íD ßzín²æç¿R¢Re¦3½hš!1óѵ栿ùéƒÏ°Öj")11&ŠÙIJ¹”ÂŒM±Â8–ë‡ÍÛ¯Ý&1Îû{T 6mKc%5Ý<<‡Ïb¨%Œíº©BÂ`Tú[ÐgÇ6ùç:#úo4Pþö=!ú' ¶¸þŽ°í„“ˆÀLÔƒã,wú@âT‹ @“ÓTUüqî„|vjÎ C—åŒßöZ" ÐÚÞ²{í•«å^Ûð¢kÑpÕ·9ç¶mC=@H"uaÔiêû5)Ãb¹W«´©5ÒOž=|øìÁ㧗뵩½òÊáëw~ñÑ]Û\?Þÿüáîï/ŸŸ_tMs¾^#àñþÍg'——›ËEßà°·X­i²eKÕ§c­¾ªv™ ‰Æ¢,M›ÕÀT3±*6©)2­7ÛãýƒÅ²_¯‡aE‹ ¨øó+&U%#µ™†i «0˜S‘ówœéƒsÅ?ÖÞ5 ÿ6îQ4f€Í~ ^®ù"£\Ä‘ñ8㑇DXÕ<ªFUÔÉÜóØ\é @âZ›æ³xV3Ã&§a*†QR}öì<‚ "á¼JŠcˆÍA> CQíšf(5~(„¢êâUr‡Åp`™ ""S­jXO¨ cÇÉ|°DiC—j Hñ€çDÌÔ·íí›×V}··Zí-ºœóbÑ÷}ï¡ÍœsnÆ\U¦aZ.›i1XJLûÕ²i›&5H4‰¨èÓçÏ_\œ ã„h‚öÞÛo~zÿÁÑá!X•ª×o¼¸—œÄ’ÑØR¸ju>éa`.ÀØ@À{°»ÅÍWIÃY^íË ïõÆ—EgÀ´™VF(¸¿iþGWIçæ0"ÓØÇ³Á¥kŽÜ–˜I …-Þ¼Vî^GO«‹ÂN¥ªêr\ôí0ŒfJHjªÑðQ$JÌìÒQô”Æ?”B^CDZ7Œôª'Ï¢=+{£¤ 6#‚V±Àd"š7pbÇi”RNS©HÆ;óª* –›u‰øß.mNµ 3ÎBˆy„f†œHTç–/ð# Ê1Ÿ ¦©Ÿ?ÝŠ¿ ÿè7)E<$ÂD¾!¾Úl‰ÀD Kf íòÁÁî-û":Mµm³™öm³ìû¾mV)åå¢íš.å¼Ù¬Û®%LøÉM»Z­ü£TƉºÅT‹TbL˜(e“º¾¼Ü¬¯¦2˜ª-Úþb}r|xë˯¿; ÓÏùÑÉåù­‡—Wㆆ×ï\ïš´Þn¿ü¥7ÞxãÕW_}÷é£'<¸umËf‰`ÑõjsR«)%E@2(* Áiç&ÆœüG  iÊéùÕ0•̼ß÷ÿþúˆ9^$>ïÎûc@#ŒŒX{PWòʼà‰ìàL [㼫Ÿa¼4gJÖeó­f>»úöÀ?0›= Â3Œ—t¼Xb_FžÍð]—¯7,%®EÒ¼¢tï!‘2³ª ãà'<1%BP«†ìAI¾N I¥¿¦L`NšúgQ 2“ƒôl®Gy;(’[f*Ìè\Òù DÍœÖu¶M -^J"gäe¼,Jd87·€ÕãSáZ\å™LïÊž;s™[¸œ<¸äK9ÕmÞ¥‘#kC!ìÈ:¯FfÁ(±VQNtý`ïèp߀›Ä}›×›±[äªZD}>ÞµÍ0N XŠš¨=}öŒ‰»®íÛ¾”©ïûœ;i[©¥íz0ÃRf¼*à8n¦iº¼Ú|tÿáƒ''WkD˜F9=?¹sëΗÞ|õ“Gð_ÿWÿ%ðÁÿñ¿þï©‹ÕAÛ¥½UûæÍßþo÷w¾wöôìòôâ÷~ÿŸŸŸœ ÃðüÅ‹§Ož–Z./7'——Þ»Ûn¦®kšÜÔZ ¬í[Ç9äÓYª™Ti™RNô‹_?<½8÷}®³GPÐ@ç+ŸÙbp1y¨¨DñÆ9¸kÆÕhÞ RÐÆüàçžÓ¸ƒ /†ƒ˜ 3bƒbˆ­>5ä®ÞWDBÒø £ëë 4o{ùÔÕ¿aq”ê»~_ŒGùœÔŠˆÅkûfÎßð}‹"æœU‚±’s“J™,ö›ªj ‚Äs¡"¾ã # rfß~™ƒ (Çj0X ÄÕ9¥³•Ê?ègIL­‰©®ªSoü¯qµF¯)Hj†ªè>W2ûó̉.ó+\7'±áˆAœK¶$ÜOÄCBQœKž4ö×¢xŽ‘¨ÖÊž˜5`rù0@ÕÌØ´ùÆÞ^ffæ¾këd„& ¸†±VW‘¯7ãéÙEN™S†q‡†óX&fd¢£ãƒ[GG‡û«ãã£ýýCH‰·›õrµ/RÌH´Ê´5Ô³ÓËÏ}~µÙ¼þÚkŸ|þìð`5õô| úôóG/®¶ëïüÆ×ÿçý§¯ß¹y÷ÎQÓt‹Å¢ª~÷w~ó«ï}ÛjÍ{×®wGÃ4|ô‹Ÿ ã&wÝÍ›·t*¥Ž‡‡«ßzõŸ=}rZÇõ§÷?¯"µ ¢59³ófK¡ÄãTrN‰‰(Œj6©íµ8rÿé“yïö7ÿ€¶D¥*#ª™¸BãÎæ›X'cÍ{?¯ÆÛ-ˆ 2#£º3dÆIæùDã@ôÙž­øEưkæ Í\t·y\~(2¨f¦è»6™Ý›4_)ãâïD)œÏlÌ/XödŒ_V#ŒàO†XŒªk>N`RÊš5#?1˜gå•=ˆ¬bâcICD&pJ6!)‚[¹ËЧ5ž'‡jëX+ù[¾ˆ˜Û¾°?µyŽã.ö‘‰íê cdãD Þ&ØÕ4Q”w¿ ùÑ ŒîT4VÅhö9¾Ž‚9î@Šy¸æYxÿºPCDýÍíTÓLÜdÚ_.ýN¡PšÔ!^¬7¥T©ª”9Û0ƒ"œ\l†qìºvµ×çÛß¹÷ú;×ï½–s÷àÃû>­T¤”ƒƒ½÷¿ùG~}ppíèø•¿üóÿ{š®n¼rçýo}»[\û×ÿýÿ°™†„©HaFÐÊÚ´MJ)y¤¶a*bª•bÅDØ´ÝÇŸ>0U!b"hsB‚Rp3h Í _00F`F…—/½¸iPIã28—ʼv3+¸Á|Yí³U¦ÈT$$ÿõ9Óód÷6ð¦™%@™sÄ¾ÒØég}~óBm÷y&¦èÆ 2UU(U|˦±ÀD5I)™( IU'¦œ‚«éÌ'¢Ø9ÍF§¢`Æ T‘8^ø6»s.ãD/_ê“#3/Wê|N@& ôw®€×7ÀLUBù4»tþ%‹’©§µgmò¬¨AÈÀ~—%À~BÅù¶6 Dæƒ- ÛbUåçG›QU¿kÃ~òG– ÀÖ*&bÐøqËEa(e*‚„ ™U5%J”_œ^UÕZë0$°ZM­ªNª D˾»u¼¿¿·r%‰Èééųçž½8úÕ§·_¹qûÚ±>zöü½÷Þùîo}‡›ý÷ïÿ/ÿÓÿ(RÆ:™á/?üä÷~÷wïöá[G¯Þºó«üÕÿ®ËüøùérÙ&NWg7ñÓ§/ž~þ`²Ëã7Þ£ýÑõî0¥eÛvËÄͻキ¸ÿôásÜ\œÝ¾yý㇋iëâ"LˆXJmR*ErNª–˜4A’p¹Ç§§èd3å5É‹ªU&Àw@/ìúÍâ*èç¸ãÌà÷Ìß@DB¿æÁ@Ç ø|Õ‹:‹1Ú¶æ(¼9BzjÆ ßsP¡½ßŸ£šñœðZXñüh-ˆ)Å… ^é•B@ò¸L€‘3›€H¯W1³ÿWÖ2%5U…²[y`ȹVA¦AÓR!"‰ Ä@ÉT•k(Ž}+Ë óÛÔl>ˆ¢ˆ²o݃Ec@l&ÁéGZ)‚ˆª¦<&£4{÷fcÇf!¬TÃofÙoQKâÈÚŠLædp ƒ çÝ’/ñ¡ ‹‰fö[ìEçÆ§[ÚlœÊ4MS™–]_ª #!ž]®_\^”*¥ bÀ| mó»ï¼ûo}k}zþéƒOŠT­2ŽÓþÞò`¹@Ä;ׯ‰éçŸ6mzòüüÓÏŸ>99#Ô£k‹ñ¯7„tqyUJ¦ZÆ©ï8…Ÿüä'wî¾ZƳ÷ßÿsÿïþîßSÙ›Ó³«ýøGï¿ÿµ¦ÉÛ5>úü×@´]?[®n`Z¼øüÁÞõÃÄ™Rm‡²½óÖ›˜R»XÜxåö㣟üݦ)¦å¹A  ¨Ybœ†©mZ&®R^<¿(RcÔ5OMNˆ aòZ]À ¿€<¢(›Ì+}O+%Ìü€d³ÍjÖo!ƲÛéaÈ ÕÞ-_¢db‡óËÝ0½‹øz <¦cÈ´‹V‹¦è¼¯ð9È5!b{…Ø„Ù7‰ 1ûz1г^2@Dôœ•!©©hbâ¸à¢šÏi¼ÉDÖ?2 ‚UAFUS•”˜D”¿ÐÍ+óHˆu–új‰f%ùxîGq¹Šó¤LýÚ1C@‡EˆÊ,®1OÜ«™+¡\nbßæ9­Ì ¸9dÆfϧT£ÄDv;ÖÙÎ`KB¯†Dù)ðj±×AUÙŽSßt Ä/N¯^œ_lÇ©–* ŠÄM¦/½q÷Ko½~v¶ùéßþ$5ôʵ£œòÙÅúéÉÙýGÏ>‹3Ëû¦Í-O–o]?úõ'};•éâüêöÑõ2É0”ašÖÛ­‰&ÆÕ²?»¸|qö«ýUó³_üý?ýò3‘Úty½)Ÿ¾øüé‹>úôÍ7îý§ÿò_ݼ}w±ì¯žŸ~ô‹W«Å§¿ú§Wßx­ïú”»Ÿÿû¿øï~ûtx¶Y_<úôþßüèG—ÃV¶‰PsJ”ˆ‘röä–™5¹ñ!!þü$’”;@jÀ ÀŒÃYdˆà9Š­á¼äBˆa0[ý²8“ãµDÄn‹ìq¬çãw#ˆ® 0©úÙ2ºˆ"š¢ð¢óÂ>(àÞî·ÝxMÔ¼›>hüý¼« ¹Îg ™Q4žàÑL ¨ø+ÔŒ«G=Ñœ§¤†ª’R“BHåì"R`dDqŸ± ’ÏŽ9‚yÞåñçYdn|D‹è—ï¨-Ühå•Cñ†î,˜îÎru ,yî'Èìz†¤h4ã`Š\©¤æ" $0wiC•@ñ¸%ÄrsîÛŃ›—ˆ ¦Äe¬nâ™Á|÷F55¦ÒÓÔ—E×–QÔt¬:–f¹É·o_{õ•[·ogjN..–˼¿º¹ÙNN.<|⪳««Ä”õM/ ÓºlšL·o^{vyº·wçó'Ïïܼa‚Ę™râ­ €®º?]o7fúâü¤oºËó‹Ó‹µ >;;sô!‚ “‡´M\ ¤”J)Ì\¥nËQB q^5›¤f5QQDñ(?„[]¨ªsèj˜DH›<‘‡C‰c•_$Mk-þ£Ùa/“܆@Nô ÂØlÜ¥‘Q ("“pÚ]9]²AçÃ[l€9¡ï#wµSG:ò‰æ!‚Ç8Ù¿èÐ2Mê]À&Ñ$*ÅRëÅ1¡G¢Õ2QU›C>î‘2¢ •T•‘Šª:¢ a6Uìvˆ®¸ñ}½2YÌãƒ` ‰Iü²g±‘ES0d4…¸W(Ò @¡º2Õ¡²FjêKH&ôðæ<’Á]ÐgBØ]B|Æ¥j]Nc­ža¬µzE¼O6)6°Isâ*êÔDsË c¶¾ÙN][ÐÄšÄg¥ãˆR¢o}ýÝW›œú¾»Zo—ýf3žo×=ÿäÑc@[u-Oã4€5‰oߺ®#<¼x¨ç—W‡ûe[î}íÕógÞºñäÚÞ¡Ç6ÛÜl‡‘87{{+"¾ÚlŸ½8÷ÅXÛ4¹k˜)¶]úæ{_}úà1¼"wßxëOÞÿúßÿìøÙß[î­ö~øƒ??¿8¹~íÚb±¸wçÕ§ž¼øU&ºÚ^,ûÖ º&¢TI #X™„ˆJ);äTÓUß_mÖ äh›J³Á€j Abäì©å(¿ÏËîÕÊOLÁqŠXéì݉Ì3}á 9WfšèÕ`‹Ì\`ÿÈù¶êìoñ¿1‘# D‰F» MØ D-‘×£·áS`ï ûßgHPEEćDFPC1›aª9‘¡™¨£ÒT&@€”Ê8R”œ }¸ÂŽ÷sœŸÙ ”ÁÔ,!‰E,Ðk¯`HÕÀ‰£ KÑ‹õЇÃÌÔÄMÔÑ*±un ® ŽNJi*ŒŒLá%ÖË!(uŒz½ÈƒoÁlþÂ=`¬u7¼F¢”¸VÑøCÜ£`cU$L‚~™LÑ1óf&QSÀí0«Ë¼¨"ÓT–}ɾÿ¿ÕQŸ3\;¾ùÙƒc©Lt¾ÞþâƒO6eHLUôôj£ê/ÜŽõÓú¶¦Ñ.¯.V«Åbñ«_~4UýìáÓƒwV)7“¨%N£lˆmÙå” '§aÕ/6Ã(uKlmN¢vçîÍ×Þxcµwxuq±¹¸Ü[î¿ÿÕwþéƒ?þáNÎ/ÚŽ‰²‰´‰OONž<]­ºGÏÏ÷—‹ªš˜Ú6ƒ€··ïΫR‰@aÒe™¿õ™xÜRÌ©4àž8¹DþŒ<’å°hiìr¼¾¼íœãJ4‰Ý%Kaþjº &ÓD¤óEQ|q (óÑÖ‰lž’ñ²£×Ðý}²D/@ø¿ÑcÆñŃP`¼½ÉŸèÚ[—‡MÕˆñ±ÿ2D1 (ŽˆX³¢ *˜ç:¹EŒ!¸:>1ñÇ ±ÿu˜ˆ#»M†¸lÏžH¿°*BU@÷q2ï¾`ˆ`¢nÀÌi*5ȇ^$€Z%Iì5"ÄãsfgÄCkÆïì4ñä´BšsOñi,šÁTçÐÌLKò 6‚š597LÃT`­3bѤ¡'" 3-SmÞ[|÷Û_ßk׎ðÙ“gWWWÃ0<>9øè©ŠÈ²íN..™SÚÔ‰ |°´ÙlwÝ¢{óµëzÖ$ZoFi20À¤ˆ °š©Z›RÜ_]&±ÚõÝ8 ›maÜvm'f¹m)¥£[7sÊO?ûäÃðÃ?{ýÕWˆ©kÚ½åâÚñµû÷mC¥âTÇë׎ØlEçShdÿ‰hOTy¼Ö¯iûû‹?¸÷2Õ±”«Ípq¹§a˜¤€Ô*¾4„´sÛ{1ìó´´95Ôk¢øÒñ꣯sЧpf¡‹,¢}N¾…Ýa'@zsOtÞyØŽzá/¨À9Gú&>'aSÛ}Q}~³ûσ£ 4³½Q‡jÖ•ÿðå{{ÃSNœÀ¬#܈%"ô7!•*HF1Ÿ‰‹™© '‹—?D¬‚“£Lžð•ÆÃÇÿ~‚@Ô*HHîàÃùûà†ZŒ« :. ­hHEm £§¥}LÇwŠÈ«GÞU<µï•©ØÈÇÍv\ ( ºó|.u()Ú8–[w®o‡2–ºÝŒ!|B*î—ɉ|Ýwí{_y÷ Y,€ÈÄË®»lž<;=¿¼Ü_.>~r÷æá²;¸Ø®ï\»ñðÙ‹Uß–ZÝ4ÀÙmsýxïë_úRŸû§/NºÆºÜôMWU±í[A¦ÒuÝz½§IÌš$«U;Ny˜¦ƒÕj³Ý–"ÌõÇû¿úÅg>©::<˜†ÑLoÝ<"$­õr³M9œ‰êf3ŒSÝl×Çû+M‰—H¥jaCH E+ç*ÅtM¢a,ª&¦÷î\»86ÛáÚá²Mw•‘/¶ÃååæÙÉÙ£ç§UÅfV: <´e8G¦½GkHõh*˜%"{¹}Pœ7gj{(êiþ— >«"slnnÈÎ…z«Ùî(4»>…£#œo8€)bÉäiã¹fn ®Á°]¹˜ˆŒdǤ !œÏ¨B5ú”8)3irÓŸª1ª2E¸ £×Èî?tWûìÙ‰dÖ&ž<jAÅq¨ã¥Áéqó>Þqÿ©™W à® fŠBK¼ÁÕSÑëaJ°=ÞˆŽºv‚✶/¸ª©ã IAŒV•Řm>0ð#ºüÁÚ.—©xVÆŸ¾¸uíh»0pJ~UPÅÏ=»qíhÑvÄÝ{oåÑç¿.'ÛíÕ Z¯Æ †¡¨ÊÉÙ–P÷W+"HÏÎΑìë_~÷£ÏÖ2®VýªëÇR—}{÷öÍ£ƒëOž=O9¿zûÖɳ™¨mšªÊSEdµ±V)j*Z¥‘¹k³Y­–dT¥0ÑzØ.º–›öj½NÄpµOÏ®n\Û¿yãÆ¸¶ëÍ0–í8õ]^t-2sfUÄœ S᪲hÛËË C‡íÐt-'¦*D`ÕJ-oß{õ§¿üàÅùeÓ]JаhšæpÕ6Í›oÞ.ƒ>zö¬”zrv!¢HTjñãd"œ$*ê^xUÑP>ÎtÐ9éï¡Ö¬ªÑƒ~1U ±&Îå6WÞê _›]ºÀŒµZä±<àn gêÆ4<o4Ëç3ÇÁ†3£ÜAU *Âüqg!"@ß5¥˜sâÿäþðÓ‡Ÿ) 1Í{‹Í¿_‘wt9߉“3‘tgxWÏ„§g#ä¼­!FLd1+ön‹ÏvÝÙeòßmçãûê+D@"tB°3‘¢í§&Btær€L,Bñ‚¬`ÖûF¨Qà‹Â€¤Ëÿ|ѾUBëºn'‡\q²~Ó¤åbqz~Q¥\;^R‘«a›—"Û«×ï¾6M²Þlöö_œµl†i³ÝÒf*‰i³Ýæ„o¾z§Nõ÷~ûý¯¾õåÓ˳;7n>òâƒÏìïõmî½x~ïÎõ67b ÛqÇi’*b¥‘JÃ4唚¦AÄõ8v ·m»h; \-ºU¿H)ìè׎}ß¶­ˆÓ†)Á²_"qÛæ¶oA¡ÍÜ6]bʉû®A&Å ;È,0gâ±T1™¦zýƵ{·n=?[_\^] ƒV™j™*œ]^®–/.οôÖÝ÷¿ôÖWÞzí;·ú¾­ªÃXgÒÙ®<.õ XÒ<¡7ÜTÇä1Ñ9Á# Ü9ëq†²Ç) 1ÅSÀMó/}ÇÝEdB1Œj<Ó®OÌLN7öÿ“#²Â ä» Pf|é&™ûuû{ý÷ÿÅ÷ø?ÿÞ÷?zðÙ4N€æH_ˆu›0{JÎÿñެÑH‚ï‡uZT]~¶ÐD‘Ð e¶¹ò¼ë3Å× ƒ ;~=Zhè%øß%M@¨ÄçÒÇšÐD¢KÄQ’dÚIs€£«¨ð6ÏåÐÈvFÂ_¦9ÀŽVämuâx×¥w_¿··Z¾8¿ºqmÕ-û¶=>>Ú?<‡ÍÞjùâäêÿú7ÿo‘)"ð¢ÃýåÁƒÏ>½v¼wû֛׎öö¿óß|÷·ßÿÖ?WÁqº|ç½oš¦ÓóûûëËéƒO}÷Öu÷ME¯6ƒÓj1b̉]¶ÃB¥>;½˜ÊXäÞ­ëm››¦]´Í²_ô]ß4i¹ì—ý’s^ö‹&g$Ì9'&"VÕÄh"²è›eÛÓd & Q£DP…_?:¬¢G׎râaÒ4V ÙÛ[`×%â(`–*@¸lókw_ùÊÛo¼ýúÝÇGu,W㣠¹R¤¾˜z©Øòoƒ¯ v“ÝÇ%ˆƒŠ2˺U!‘ú㋳Çç}õlõÐÌQ/zS'xj€èXþ9 ŽMN¢ÕŒ ¢Cdv½Œ¹Ãó%@f¸v¼÷‡ßÿ^¢Äêÿ*D±Ê™½ƒ§"`ÀÄP+#ùiØÙŠ$EüèþÃgÛiò}‡³|];Ž.º~½Ý|ûy¸ oE§›Î›9!³›¦Ì¼¯(C™¶M‘*ê÷‡8ÙìÈ uŠ”õgh!¢™Tñ5X×*Ì`2D« ‰½‰LDlL”2ÿÉ÷ÿèÃÏ>–Z€ˆ‘@ÍW»!rJÉ ™YÌu+Þñ «g¦ÁËf0§¢ç`'’ãì@Ãå—FS#x9ªbшŠ[)°Û.îv±ñ3•!‘#…ýßÂ/Ïœô*[ü¬ât®º„(¶á.óíÄιšˆ¼—<;A"“AD¥jbX-W¥Vg‡Ü¾u­Nzzy5“’ݽy÷W}øÊÍR¦ÇOþúo~ü—ýWOŸ=øääÃ>ªuR€©ÔZ*!‚ÕýýC&Xí6‹eÛ´]·4†kwÞȹm{e¼ºÿèÑãG÷¯ã$¢R=ˆ"ZUTÅL|h™ M¥¸€Á€|£rx°·¿Ú#­ZѬ”’r&N‰ˆ˜j©š8!RÊ RÊ"UÕÆ©l¶C¿è[n†q[Õ#AèAJF$ÆœñÍ{wŽ®ãµã#Âæ“ûŠ@)ÃTDkÍmÔ»&™hÊ)5©mò¢ïÚ¶G¦Ze».7—_~çµ÷Þz£mÚí0¥xY¨¸¡MÄ(6÷*f ¨_è5„3Q*ŸO¡A‘÷3™¾,êeæ€%ù.åå'n&Öj¼‰wß®©‡“Í'ð¶ ½é®ÊŒ:¯âªc„ID‘ùÆñþ|ï{ü'ßûþ/?ýÐÄYæŒ;¾ L}â›3‰÷Eê]9jTñUœ &ƒ–¸1Å•, ’;OÌŸ`Nq˜ú½wD@HÌAnÝíüvúr0ÏCy3ô%‡ÆfyÕ|³ô‡!1 `pAæŽhl‰æˆ7í~!_Èû“ûŠ"Q×6§g——ëõz³=}q™²”*—Û>ûüêêêâê’Ѻ&“Ó¾*<qv~µ~vzöéçÏÏ^œ±û ŠEhzÑã”è.¥<Ê{Sî´ …¼{çív©0% v—cC1ÛE‡§”#˜©LíOúÊ»Óv䀛£KyaQå#R³1¦ív¨¼tï`>›b`Ÿ/ çm=ƬÇ´]ÍÚʻ๘mjïHÅBpup"VU.ÆüôógË˶m3ù×ÿÇ¿†áü¿ÿÿåï‹EÓ®<çŸ}<µMuq“f•’Aç€,D}ÞöC ²‰2@FC`ï±Üo¹ó‹‹Ãõúüj3ŸµÞsaXXJ™Ë):$eë‡ÁfóTUUÇÔuãééUu»r·BðªÓ ¶Œ¸†>ªˆˆl./÷sÊÛíæ¿ý^¿é>yñYŒRÛ_Î몒¬'ç—‡{«*„˜Æ¶5M €9nö×mUo7]3޳ºîûcÿ“ÿäü|û?ñÑÓ/Kì¾|0ŽH`ú*AÍk ŠÂvèN´\Œˆ;W!NÌ´Ýó§F6µâˆ¢LÎi¿X–Ïå;̪Š4‘ЦªãôŤœ”)ÓT‘ÙMz Ô{žŽ{ˆüoÿæ'¿}úI)嚢©ˆ9&ÌE˜= ?Á˜yZXèTa$ü \(öF¤`¼sVÙô)"_C€øúwï5u`â~ˆå¸»íÇ—'g·Ö_¼<c°1Šót½†1f‘że昲9Çó¶ñÞß¹ûþýÇ)æqì¿xq~~²ÝöÏŸ=Ù\¦¤¿ùý“¦q‹vV¤qDÌL49HDÔÔ1ß–/µw ëªöÎÕUØ_- yH#ˆm¶]?Ž]SF´«MwµÝ¨$dªšÚ±úñôìœg³&gÙô}LÉ‚¯’¤%j ÉZ[§W׫õ|9kªº®ššÏYÛ¶~ãñƒ±‹OŸ¿¼î6€‚[/çmÛŠª'©ª ^’nºÍþzMˆW×W·o2¹ÍfÛÎ*0È’ß|tô'ï{o>¿¼ÜÄ”rÙ­ÙS±©ïü?åõH»zÚÍzuêcÙ´‹Ú ~þ&k¼#.aLœ‹rP"P+»J¼q¿”ù!;†]¿çfͦ…É¿ä)‹1–%.?üëñ¿ùñ>úý'åíQNv1«™åœ€ê”˜æOvƒ ˜ââÓ2³˜'¨š9$µ]À§t–v÷±rçb³Bƒ*ª˜é¶+ ã.æ=5,P²í :7ÊòILÄÄÖ*?~%C4Õv§*­|etMXÜ©Óß“ÍÁ_ÿù·ÿðwn¦dh‚ûÞû߸³ŒÔ£ªŒ)•ÿöœÍŒ#lú¾ã¶®º®®üÞjÙT~¹˜;¦àýÃ{·ß~ó-G.¦xqqõäÓOÛY•ÇÔ´ÕƒG¾ûçñ½¿üðÿôû¿þÙ¯>ùì÷ó¦fÇå œ%+`ÅÒ÷/bm,ZÒ,Y2±sŽgM5kÛýÅüè`}x°ßmÓÙååR9_o¶ý8\÷Ã8Æ$‚Ä}ß§”¶Û®©ëªªóñÙ… äC†qǔųƒôÛQÌ=³sîÙË“ºæÕl~ëè"Ìšù0Ž’…ß»×o6QÝöãv ô`±hBcjê*ŽñõéùrÙÖ¡¾¸ÜÌæµw!¥Ìç³ Ÿ]]¬æ³ý½Õ×ß{÷»üG{óÅÕf3£ì”÷–KD“º ¨‘Šøw¤cŒUUUuup°÷êõéÕÐyæõbvkO³EV˽—/OÖ«™óþäõÙÞÞ’7×ÛvVúÓÓ3_󢧤†zxpÐÎæ¡®9øÃý½>øÖŸþñû9æ“óó˜¥Ì8 éæša»‡™vgLS5ÇdfävfyÛ]^DnàL_bRJÍŠ *sª²émLľ¬å`‡š.H†Iì]<®¬î ™Âz=ûþ‡?t€ *嵪€`òÔØ)t ˜ø¨e®éª)CÊ@ŽJ=—+!Mܬ4“þ¥ï #Q³ÝÜSY¡”\Á´>/E"+LQFÃB^µ¦j†±/|SÚfÒdí¸ËXL0|˜ËEëà™Ç4Ñf§eâ— ÜébÊÌï½}ßsc4ÕÒÅ®<Ïg3BÚvý0ŒEP•EB`€€FH8kÂþÞÂ;÷öƒ‡ç×›,²ÙöÃ8ž_osÎnÌZ÷ÎQÝ´M]‹hLãx~¹½èþþ¿ýWsÞ;¢,Òõc9è.6âŧ¬’që¨r:J:Ú_2;BU\]ÕmÛþþéó'Ï_9ÇYœË9§¬jy>suðmÅàƒWÓÍf“²œ_mšàÚYÜ:¡ÚW›n»h±v®SÊ#@@ÍL¨€ÎÕh%Ïfõùëó«m?ÄœrÊY³ÙÖ®BðàHÖëõwþè[ÿýþaŒqƺÖ{kê‡þö­½$Òm:W±s>eÝŽ›»«;}7 i¼µÚC ëîòí¯½qpëv3›_¹PÊÓÑÝ[ÿá?üŸÿûÉ¿ü§Ÿþò?þçÿúâÕËlf`¤0á¡‹þŠHÊ}ˆ§žáðœ&ýSÿmwèB@ výà ¥,"¨w­˜PŠ&­hØa7À-*ÏP`¶%÷Êû†€œ# "¢RHr)Ř%¥\˜E"$j… ¨E)"SJ]ÈtÆ,e¢â|¬Ç,…ï]HŸÓqŠ¡X½”„w‘“MŠN­x·ªuR¹NTÔ©þ Ø ÝÄùUU³ñT°,É? Bw”§)?mŠl÷¼O2­ìd "2"€½÷ÆÃœR?Œ1¥.F1mšš€¨û1Åý0&3#â¦áºò*Uk‚[/æˆè÷CTÑ~‹ŒõéóWHx÷èòÐûvvÙ.¯¿Ò 뺮ëcL)ÅŒÞ9dr–S* ÇHD6Žuˆ¸©55Ž9ÏŽÜ|ÖvýP u¿øõ§§›Ëœc¹ð¤Ð!ê¼iTMº~D³¯.>úô3ƒ¼šÏîÞ:\¥9:ª‚£Ú»aŒÎ±I=[qÍñFR˜Ï*5ÜCŒ#˜©HÒ<_¬¯®ÎûÍõb±VÕÛG·Þ~ã­OŸ=9½º®‚ŸÏ¤™Õ}×càÃÙþï>y²ÞŸ«ÊæjX-—1æÓ««ÕrÆä7ÛîÖ­ýóåÙ9ï?¾ÍèDÔUQUâ0.Ö«¿øßûÞ÷þÙ?ýãOÿ¯ÿôŸŸ<.0Q¦Ýñ4Ÿ˜•6  Hìp·[Þ­¦¦fï2¢¶˜v¤œ颿ƒ€2qqo•k$2Zá ªî@¢e~†j®šD–®à OIlŠžßè‹1 ÅW„Ps•bŠ)÷}ßT ¨Öóæúú"%Ç=½óÖã³³³Ó«³ó°iÚ6?Œãþ|Ýu›7ßßl¶WWh<š\]m$޳½£8Äœ‡ÊïÀåååÇÙbqÿá[`SÆ‘UuzÇø¾õþûßúûÿþ¿þãÿó_^ŸŽª\Ò¥“‡pÀN½Óò«šMå¸iÞj;°Þ>@K¤Ùq©€ò¾H9ÑŠ)Úν…©ÄÈ@BfŠ`!x)ŠéiÍX¾¿Ä÷ƒ¿þèÉïrJYMu7K¥¸:þ§EY±¾—+£íB-7²ñ]¡§òbO!iÚ™Š,é$-.>À›jð´E…÷ΓΦ"ö¤mC_Ni7"œ)0YXÃ…ÀSŠÍ¾ÜœîÚÐSÞ—°ðç0©•¹ÿ„c$||ÿð{÷‡8C,†D¨|SÑMß‹HÉŽ§,Y¤$•<±#ÇœD˜0%ùôóW.ÀjÞ6¡ÝŽc×Ç!Æ®›ÍVD€poeŠ›®S©šà#@ðžWM%IDÕ{®½÷•oÚº©B\ÛÖ‹ùŒ½Ÿ-f¡òG·o¯×Ì®„„^¼:&ÇhÄhCLLXüSÎ1:ä\ÝT——ÝO?úÄ9X´5Ïg#ùà¼s•«˜)‹˜ä”S]U£¨¤ìÕU0ÇlD%ؽéµ<ŸµËÅb6kBS’ ר÷AMÙûÀôâøDD¼#ç*p°¿wxq~Ñ´õ­[Gg'çÀ8kšó‹ËƒƒuU5'§gû{+ç¼÷ˆrÊCßÞ>jš™ª¦8Žã¨*’sGÕœszððîwÞÿÖ»z¦ëMs6¸iñÃN6®ojÜ;µî´s+<85+e73 ž4ÒSJ'm·L«Å‰ »ýDá$éÔûAfQ ¢XA<<˜ÿ?t9dz¨ä,žÉTÉ1ǜ˧$X a¥°Êm­D¥M”]ñf’aÊì|¥pÃcž€*%º†ÓšÄ&”äÔŸÝÁêKÙ¤ »t2á¤@Ô:´Ô câ„‹œlxˆÅbW¦«Ó¡)K‰”'qŠà(fï‹„¬°\´1I¡¡f™xPÛqdâa'-@9‹!Å,è̘ézÛ3a³0»W'bRyºs´‡jÛ~Á7M•D®¶Ãë_ÿ®ö¼hï|ðÞ9.Í:Ì9¡"±cv`ó¦‚õ|s*]DC³ÕÞ~U׌¼X-÷Ç'§F¶š·—›!åTשü†…*x‚gûì‹ã§_¼2ԽňÚÚ{$E³vÃÐ4±©+çxNݼ«“H IMDKZÃn³˜ê¬n^^\mú1ãééÅ«“ÓyÛ ²Ù¥†ºªªºªêÃÛ‡o>zã—ÿ¦®·)Ã×Þzd¢³åÌ»úÕë—ß|¢<{öEŸ»£ÛµjÜl¶Õ£÷ÙI΢jV쥣ª¹à·WÃÅÙÙ0vóÅâͯ½ñæÛoþÍåõÏõ›ÿù³_Cv4ŸÏr’2 .8ö)¥¾Ù©éØÅ¦©RLóYm*}L) MåÖëE弦¤_¼>{}zî®gMÓÔ"* Ä€ÚÊ—«wŒu=¦T…@U6Û,¦­w0iç ÀÈñrÕ>?Ífó›'O¿ùÞÛo½ñÆl¶p.¿~¥jóÅ,çÜwCú&pJr~q-ª!ø”¥©›Y3;9~}yqUUÕ|^WÙ?}òŒˆî=¸ëCÀœ}žÜêš\Ða Ç–39ï6—ýçÏ>=ºsw¾\l®®ÏÏNæ‹Åzýá÷ÿùŸÿùw?öâç¿úè}üêìL²ìXQåg;–B©[Ií–^fXé(ÅüijªŽ t qNzqQ3 ÂŽcF€ŒX¾}IDCB"‚Ú{ç‚ËÍL¤L Õy—T˜Ð•CˆM¦Áò³ ¹`uˆ Æ`WoBCdä]T]­pz§!¤ßiM åÆTL7£I#SÔi…?Åen8Q¥EŒY”v·Q+&z!½I:¨šád¥/ï¶iOŠ­ˆwÄpeN¶ƒªÙ½;{w ïP’¨2uÛa#•葨å”J–¿à·³¢–M9[wcÔ,ÞÑbÖ”ÃC…nˆ(¶U…•¿¸ÜzçBða™Èq%)9"¬C5ÄhÌcŽã¸^-sÖç¯N‡1ªÈbÞxﮯ7f7'ŠãØuãñé±hÎ9o¯û—§ç"y½š-f­wÔ÷ãñÙåÉåf£'œ5ÕázAè#&4Œq ¡EC$Œ"9çkhš*Æ,ã胳AÇ”;‡SFP•ÒP¡óËÍ;o><:<ÃÍvëpÇä]W7í|ÎÚ6‹Õòôìê§¿ý¨™ùaÛC¾÷ðnwÝ=úÚãî¢ÿ寽ޛݾ}»mg/_½{öEåýr½:Ü?˜ÍÚ®ÛôÃ8Ä"YDLoÝZóÇ<ŒéâòrÐôFõfâ¢]äh÷Üö¾:9=«œÿÆ7Þë»øâÅóª¾<:º|å#òùñËÅrÏ…Æ“æëºýì“_¼ùî[ý&_^¾ùæ×  ÜT‡~kì¼cnÚ–™þð[ï}ë[_??»øíÇŸüãÿ÷‹ß>yÚǨf¦2íoèoX7`Vò!ˆ ýV¶ðSQµlÝÊ,KÞÙ:¡0«¦ìä44Ó¢R0$TþÛþð·OžDÉXÐÞRÔ.PÜ0ÅÐq¢\NÕ”O½aNc2 7¹©‘˜Amš™‡ZQ´âŠ&VÛ•&%VãCÝñç øq´Ñ®ù¾‹öÁ$$ÝqÐËj^§ЗmNô̸W[¹ ®ÛÿÕ÷~òWuÿèîvÓ_œŸ1©B·íE%¦<¦ŒEÙ[–ŸÍçËåºngMÕÓjÖŸ÷q|üðÞ|¶ GUh_¾øâÞý{óù²»ì²&ï}Ý4ëõz{µ}u4䲈 IDATüZ$7í,°ó¡Zß:rbèüøL1.—·¾øì“7ß~nDj)'I¹ïº4ã0ó8ŒãЋ¤{÷ï~çƒ÷?øÃo¬V)åmßOXp‚©1¬†Ì»Ð¦!é(oSã™K{ ®€€pËïxÔZŒNeóYýõ玌œgJ ¥H刞ÉLnpPØR¥ª8…0Ù@ËyªM×=àRcT‘òÓ1E]JѶ´Òm"vgSÝ•·´¸8E§1~?* |)`<ƒÂTÿÒ[ Dxã  ÀÉM'0—±R9t”ÁÞ²ù³öí?xûï½äcú>JSRU“io*bcJu퉬r,@X®q[$"Ù1;攥L¬‰ §ÄÝ8Ž)e…&¸¶©—³6¥t¾íŽO/¯»¡©êʹ¾³ô¹ÂEÅ„ˆUDU˜]p¾X£êàÊi*IŽ)uÉž¿>==¿Èšª*¬ÖËÃÕrÞ6Ø_žöò *eKѶõÝÃýÛ·%éÐo*çvçAôQs<#¨ižTrPµ®ª˜S=«³©cÎYˆ0%q†É€³ÉÃûG‹Ù\R¼:¿xñÅÖ;‡šÎR¨kO„DuU½óö×ú.þ泿S}³DK®·›½ýµçªßöaÆw÷ߨ\__œ.W«Ûwn¯úåó—/·Ûíã7/÷×u=Ë)9燱ëÇ«Ço¾ûëŸýìñ»_!Ì)‰e¼Y3B}ßÂåùY;›—èËæêæ³ÙŸ|ç?øö×?}òìþëŸ~Ö îŽWŽË›‹KEv½9d)*Ȫ„Äxãp)±ª¨°!J㉰ÀDKèzÛ'¯äTr°0‰ Ët2ðNË´òxy½)¨!—6é¹›´È&±¢©h¡B°s:'Ü‚µÓ|”ÒäÄ3.‡i+hÇ,E˜ “±ôæaSV&pì’hVÑ,@míMeÈŽ¨ª|TKË|~yÕ„à˜œËMŽQD²jʨI­®*D¨+/9  fÑÇ1¦ó‹m™”Þ¾µ¼¯-Ú¶©ê§/N>}ñ*#;öŽCÅÞ¹yS=¾{ûÖþþÅuwu}S$â(VW‰B9)(Ž9 1.Á”‰‰hLÙ{ß÷£sL¥æVç¼ë{¬«ºOþâjûû§Ïê*<¸wïÑãÇUݨÀ«W_8v«õž©õã0Cßõ…ª> ñêòrµ·î·ý­ÛGiÌç—Ÿ?¸ÿÚ¦===ûìé³ÙrÖVõÝ;GÛ®õú• Á¬¸ÝõääÕÃ7Þzùìùòp|Ã!Qù† }hÈìj«cŽÀ˜R4ç˜&ÑÍæŠ‰«¦ùÆ7Þ}ûko~ñù?ûÕo>zòÙÙùLC‰›~AÝjI&NFvDÈj‹‡zÊ’–Ç$2!('d±2rÀëÍøòÅçn·‘xcö. «rÍ,’Ðü%׳pœ‹ù ¦ws ÌjY”K¿ùæ "LT°Ÿ¿`Ç1ga¦\tZÚOXJ\ƒ%3ùUU¡}cÉæ@±¸}‰i+ëÁ2º+bTU4c&ÞõSBp?þð»ïóýí¶;¿:ã0¦Ü#‚JÞ%kTS‘X`€œÞ‰Šˆ€Z2›ôs`‚@ĦšˆÉ!¥¢ 'îc&ž•wÞù¶©ªà³˜ª€Q]…eÛ\o‡«ÍõÞ¢u„cÎM]y&ï€sÇÔV¨Å™îg-!^_÷Yƶm*çØqp‰$ 2…àÎÎ7?ÿío7ÃÖ;çêÐT•÷\‡pky÷訮ïcЉ™k¶ÚyS¢³P13gUÉ‚„’ ïSJY„ ™ˆ˜ªS€wc~òù«½ÕâÍ7ÞY¯ö¬ ¿`;_dÍÁ…9ϬnÚ¦Y.W›ns½¹2±{¢"ŸíîWu[<­ëýýàýgŸ~zzzçèhµZÞ}p7øv{yÎ>l/¯«¹&ìû«»§”AÅ{ŸSQcɒű«™@!Ž£äŒÄqErU׈tq~V7­sîð`ïG?ø‹¿Æ÷ôýâWÏOÎb!‹„ÚÄ„2ðŽL5éMÊ{7à@ÐB Ž@“‡ÆJ£hgš2Ýn®\)¿ãŸ›³";²µÑÍ€¦â¿!9eÅ—y"‰TkÀ±}™"Ÿ$JÓyP¥LG¬à–aÒÀW¤œ\u‚”ª¡î*€ (¦´ÌˆyR¡¨¡Ýˆ´ íËÒTh2uOùœÛGËüéw?|jc·í¶ÝùõuÊIÕRJŒ$Á»>¦1Æ(©ªêaLjV¹bÄ2FŒ…9@„ ªÄØJ År–d™”)Ž£!d!4Mí«C`Ân Œ›*€Úáž¼x}rÝm׋ zf1É‹¦.d‡söΕßúÕr~Ë/S–8DcH¢©û˜ÎϯÏ7×ý8®æóU;‚¶@´jëÛ·öÞ¹-Y»aØn»1¥dœïSšÕÁJ]1eA5!Î&9vìsÒˆ+ç DDˆ3ƒ‰aíì­æm]÷›ŽŒ^¾|YÕuSÕc7HN—W—‹ÅBRVµ$™=ß=:¸8¿ØÛßGÀª®$‹BZ¯ŠT BðÖÔwïºgÏ^Ì—õƒ7,îH”×OŸœ½xókïýæ—?¿uï.xïÇAcqêaûœ’ã ,ÓÒqês×w§'çUà½ýƒíf{½¹º{çŽw‰Å4£îÍÇwßzt÷ÕÉÙÿøÙ¯>ýü¹B*IY‹MÊ€©¤&bäØT €¤¨iÅZž.™F¦Zh–U†®wZf#B¢€@TQ¬¥@fïÝzõê|)ƒ=@4)-éĉ{…Ó%u ˆÝÔJ޳,â‹‰Þ §5<¨š'”b®!*§;"Ø¡žðËPŸ dÕ‰`¯74ÈÂMœ¬â 75¨(tž© üwÞøñ_}Ø6óÓã×¹†QTƒwE¥X9¿é{B쇸é"d¢®ëCíS.]Ò‡¥àQTULIs!7GQ(3Œ˜E¡ä¬êœ¯=;G’µ .FÐàˆÚ@0‡øâäbÖ΂¯¼KÁ‡˜äürsz}}ûpåÙyf@#BËš6ÛÑÀ.¯ûnÛ_vý0Fk‚'¢½å¢ŽØµuh*ko}p¸?¯ÛÓ³ó«ëk5Ê&ÌÔP0“ÀÜqÕ6H®$§Em³à½DC 0oš2è#ð×}jµs]ÌåCbï)g}ñâ4%ýÚ[o<|øp½·Ädüüù“ªj—û++š¿q!3Õ¾21®üÅñùí;w—e ‘3ˆ88ç÷öÚº9>9ùÕ/ùη>˜ïÝ !ÌËßüòçóÕ̳/jCD#ä˜zD«ÛÖ‡JDJ¦XEˆh6›Ÿœ±¡iÉçï¼ý®l7×ÞûýÃCí‡aä±Ûl³ðw?þË“ãóøÙ¯÷ìY×F`bˆ&0å•»¨™4ç]euÛ”¼*!3ç,X¼zÌ„à¯ë†ÿæ_|ÿ÷Ÿ&¦¢ê3â Ê‚fL|uµU3#*M¥Id¸£2ÒMçqWþŸèMX<80 Ú&90SyO ä)§†DE™D4QåÊs SË; '}’}µ2v£™<õåQâ"¹@vDDû{íþì;üÁ·U}±OÇçgÝãc–$Ò c¡§ôcÊ)gËHL9¥ÚûÚ{bÑÊ9Ì"jJHÁ¹1çòíU1S…¬ÊHY qBÂ¥ªøÊcV`çƒ#Ä‹«^4Íšºö>I~}~ýüøôôbûÙ‹ÓYãU­R7 Ûnxq|þÅñÙó×§¯Ï.Ç Áß6U[‡:„¦òû«åÁÞúpoùðÞÝ[ûgçW/_oûmReæ”$¦ hQ,xŸ%#;Ø“¨*YT@Ì3:âò1yrÁ{QØt[›Hí98Ÿ³vc|}v1Ži¿}ç­Ç÷ïܯ› cJã°½ººp\õý•ÉÄýqìÖûMU‹jUW³ùrûåroê\«RÎy‡”bI-Õ³†Éjë[µqµ>:=~Žàˆ ™/Á,Å\âE.çJñØù*8L1åáÁã7g³ÅÉñÉÁÑÁÁÑíçÜl±¨ë&ç,9âÞÞsØn6‹EûwßúÚÃû9å‹«ëéN´33I.Ù<°’ž™2âD¥É1aǤXY¦H .þõßý+ç<ß|õ§v†˜!¸Ij*uUEÉ7 7ï(Šý”w™˜Ä*Ó¾RÔ<²‚©*û¡U'f‹ª1£HQCâÎPr+ÈY‰K»JÍ&…¬»!b‘àuã¤kÜuabk èÔ-¤rvuìýÁ{¿óÍoîïï;öÛ®;yùr¹^“cFVé}ð¬9 Ý0˜YL\.'YL4VU,D”²3‰j¼‰¢•]¯f-McÏæ½«¼))ssŒ@hª9fEИæmÍD9K TeQýôóËYÓV!YRöŽfM Ñ~ÿìUU9FîcŒI5_?«‚óÎ଩™x1o–íìîÃ:„!Æ“³«OŸ¾b¬*ßVA’Œ2fQbS¬«0ÕɳƒM71siI«ê( ’+`5C@8ÄX…P¾/¾ªÑ”˜Ì!Ý»³ºtÛÔ^¼|L¼wpP·-Ïíåe¬Ú&£äS’œ.Î.ª¦zõêE¨šÙb^ µSÜDL‰1xßw)Æè¼gbGîüôd±Z>{òñ[ï}_=ÿâúúÉjo¿|¡ˆ)Ôµ~Ä b‘ëëóýÃ[¢:ôãáíö›‚A~ãíw7W›'¿û¨ž7{‡·Ì`Øv ¶\?Þ\o·ÛËýƒÕðg¼|ï¿ýãÿ÷ìåË2DnVäc8uó±ðí²“j<‘2J^öV³ÛÞre´Z¡fÉ!‹*—?‚ÝvÈ¥”*粩©°£‹Ÿb‡ÊU¡Ý[Ñ—¼S ¢™1Ѥ‘%jZJD¦H ¨ 0ùAoâ׎@ve…ÒØU'ªêÞ߆E§X‰c“ãõªýðÏ>x÷­wÇmwzrZ×Áùª®ëã—¯fóYåùô<³GLPø¨,)9²˜MK{ÇLD*GcŒf& bÇ”KZMƬb‚ ur–¤Bªe³ê(Tž3;§¦YEÕ†qtŒëÅ¢mšaí›eIúÙË×mÓ,ëö`o‚»ÚlæµïÆDŒóªZÚ¬ú"ÁÏófn`Mà¶n‚£ÛwV³åõvxòÙ‹“«+U™ÕÕ¢mLTPò”u L¬ÐçT´Òà b YL391!{G€h’M+PŒ1EΚªÛö±v‰Áðó'cJßùàîáÁ­ºi]¨˜’6m›cÜß?À’º–œoݾßo»—¯?OqXíïKΈÀΣiÌ£¦l¦“ûÉTŒáÕó÷ÿâí¸b ÃÐÔ÷¿ñâÙ³§Ÿ|rtçNU×jF¤µoD$ÆÑy§ªÎ‡³ãç‹Õ‘bש¿wÿAõõååÞÁ¡ªŽ}tùüäds}å¼[­ÖÄn>ŸUÁ_^žw×ÛŪþwû׿ûäÙþ‡<9?/Î *ÈÚRBPÞ™¥h¢Tؤ€3#ÏÄM]ÕõÌÕU…DÆDh0‘¤&f™fN†„¢˜MCðŽyÛEûYØ5¬41q×04ç§°æ8•‹\ibˆ©¿ ÉÔ|‡"³„ cÑÀ¤P] §PÁ¤õ@U˜ôhô%2ßÌ@Þ¼ðw?úpVÏ/ÏÏêª >œœ\¶Ÿ-–>„Ͼx¾^.îß>|þúÄÍœc×õãf; 1³ZpnHÑŒ jªÊ‡~ŒŽ\3¨2ƒ*¢”+¯²ñû²®zÇ}Š"2FÐ`5‘cŽ (g9¹Ü°ã=·jå×+ÇtzqùùË—oܿ׆Ê1QLÉhËÎóÞj¡²T35öOL˦™ÏÚàÉ¥(¿zñôôâœ!:FÌ"YLM<û$¹ÆYS‰)©Ri<@Êê—V«唉pŒy1kCÚºÙ\oSNmr Ø‹˜‰˜$&zuzQÝuï½ýþ¬{çÁT¨žÍs ˲ƒB¢Dœ ãFãí£;bŠÈ¥­’M-«ÆS–41'É93¹ç¯¾øçͬ¿:~øè­³“SÀËùbµwëVáÙÓß·‹foÿÈ Ò8ºàªºÇQ%u›I‚9ëÅåÙýœ]·½óà^Ó,ÎON‘l9_u×ÝÕ³'uS!ñùÙYU×ÌÌÎ…ªF$Ñ< ý£‡Gÿæàßþâ£úèw} Lu'lr¤ h&¢ˆ"V¬‰&"DVˆTDžÿýOþÕÏ?þ(ç<ýÐLàÂ)É:]ÿˆÐŠ(GSÊ;G¹ŠÛôJ4BTfräÁ’˜Þ(év«›’]Cd&5eäÉ ±c™LØÁrH†©FXÔ_…†ÀM%¾d5 ŠüÆ.lÎñ·¿þðoøááÁ-ï+{yüÚLš¦îúØõ÷® ÕÉÙE]{ïÇyÛ cÊ–µ ˜Í| jçäØ9¢Ý TÞ•ÂW)I«YJ2ñpÁM4¨óGΚ þ¬Äð™0„ ªÐõýþjîœ÷Á9ç% 3>{qÊç³™Š°çÚ±óÜV531;ܬiöW‹ýõâ`o½¿Z,æm`?Žñüº;>¿èãX9W8ùì=3™jŒñj;ŒãP"¾cJØÊ}Ì’šˆˆ!˜ZY<æ,ì(×TUÝTuU_]mÅÔ9§ªMRÊ f}Ÿ^žžûo>\Îç‹Å¢ª*çƒs‰Óf{]ûš<ÕõÌ{ç¼+KëËËv>‹ÃØ´5*@Š£æ<öÝ0 ªº¹¾41‰)]^mÖ‡«£ƒ£õáaÝÌC]ç!¾øü3 óuµZ­¯Î.ÏÏç‹¥ŒCÄnì†óó×ë½CÉrúúõÞÁ^¨[¨Új¹Ü‹c†íbµ»áùOo…z6ö= ý€’3„ªòÎwÝ6§XUáko<^µ³×ÇgQÒÄÛßqî§•ùŽM_»ñÄ%¤‡÷þòÃÿöG?ùÕ'¿Õœv=>0wÓ¿+ R_Øòˆ¥@„dÅ䈆D%¶S‚ÿ(¦Uª¥! Šʱ×̱#¢ž!ÞÁËcMÓU·Ì[І¥@uìŽ]Þ©Œ6‡é¦K8PwO¨wôo¿õ·ÿòGíl}üú%3ÀàòêÚ9šÏf1KLÉ;frÝØ¯WK Þ]o»~ˆ)çlæÕ ‹©j\ˆØbÊ*Ê„ž9©æ”›š pL©äõ¸øäØUÁ‹¨wÜÖu¹VÁ³óågóÁŨHºš/CÐÀrVQ{uv¼k꺩*Ǽ^,s@\Êu)GÇÌHf("ýsÊ}Ù3!j?ŽfÀŽáâªëÇaŒ2¦4ˆJΛ!aAt—b+šIA»3'&&ç‰}¨æmS…jÓ9§º¦ê•%¡¨IÖ¡__ìµîÞÛ[¯V«u¨ç1±*tWWí|)¯ Œ‰ëªö¡®Ûv¹Þ뻮쿋¾'ǘEDtsu!¦Y4Ž1eÙ ÝãûoÝ»»>zXX Î{ïë×ÏŸÃv6_ΗKIúâÅç¡ ˆœSJ)^žŸ­Ö¶¹Ú¸Àu37Ñttç¾]^ž-WkÇîòüb¹^¡¢÷Î…*£s<ô yW{7kç`0¦˜Sºu´ÿÖÃ'g—Û~«€póß“KÓÉäRj‡…áÍøàÎáŸÿCr®;Q LÁB0 U04ËÅ #ÙTÑT´Lƒ TJ^-‹€QŽ‘Ì¤ðªTéK™Š2B–\îEËyƒ,_¥óÉMÄ€,I‰˜îÔÈ8u$'b”ÚEIÃØ®õ„øÝ÷ßþÁŸý"‹¤ù|yqyž5Žnq¨ªyÛæ1!âÑÑþÑá­[·ßzã DŽ1«  iÊ%¡¥^¤"9æ~cL%GgcŒ9%Y‘¸©*T³,bˆdر„•³#Ì’Éyvd àç¡:Ü[ 3ï«à‰©®üz9p×]ŸRRUï¹­Ãj6›7U¨v¯ûx¹é¯»®ë»œ“š ¡fIιYSáÇËën³ÝtÝ0ÆH ¹”Æû®‹"ý‡œbŽ¢@Ä)ŠÄì|åªÊ£¨8ôÞ§8†Òxbr"ÚTì™Dd3YÍgŽÈTU¤°ŠÒ8‚ ;ÆàYDAsR5sŽB"eÿÉÛÍfº8ôj¦bC¿íÇ>Æ1ÅAE^œÞ¹uøüÕóýûÊȱië{9 Ïž~’rxtëÞƒG¯Ÿ?ïºK@<}ù:ÔúnØtóå’®//fóEŠéìøuÓ&º<¿¬[·wp´wtTÕmÓ6Gwœ u]›ÁfsŽ1µó9‰îí-ô—úèÎ}º© À¤!‡7Jà²ì6,Ö(ÄaUÅj°”µ^Yq”¨öÃHf@,¢7žU¨‚‹YÊ܆€Ð Š£©Šš2¢Za>O*'Q˜ôƒIv}D4BÈÉ€@Dv¼^-U¯bW,Ç$´pQDÈ;SÙÍfÌ ’Ћú‡ÿüƒ?xçë’ååçχ±¯çíz¹>~y¼Ü›ï­üõußog³vµ^uÃðàÑ#ÇÕÅù)·¸î’~HY!3Ù(b¦ÑT7]v޲ˆC&çܘ!ªˆ:bÑ<Ž‘·mPN(ªUpH0Ž©®BŽÃl>ç*s휫ÃXþ8¦à]ÓT˶½½¿~~z¼ßC««Z¡¯½ŸµšÆaœ7͘3HÎèœGL"ÆðÿSõ^O–e×Þ2ÛsMÞ4嫺ѾÑHäÐŒfÈàÄ„B3z½êÕ#¥8ä€Â¦èF™ÌJÝ1{ïµ–Î-ˆª×ЬŠÌªsîÞký~ß×uƒdsÎRHÅrÎÞ9 4&g`ÅÄ1e$k}PDÉ¢2,g3"§f"R23´uí¢')Jè˜ÁR&F5ñÑçbjªEçmƒ#@b¤©gαC_Lú]—Ú9Œý()«Aê‡bi††¡$¹¼yÓ¶í|¹tÁw~¿ï†q\ïúżެû? àEUÍÌûxöèÑl¾xýò›£“eÓ.?øøÛoÏ_ßì.$ÆZr¹¿½^§~ÜïvË“£àã~³UML‹nßwÝúáã§D\UUŒÕæþ~¤þøììöòjLcŒqÆiÀ£ªóù|¿ïơס;^-þ×ÿøïþÏÿúO?ÿê+",’pR-Lƒýw%[45C?ÑÓLÕœ¹L hb‡9£‘C}ŸŸ Làå_WDeR5½CŒ«š$&U}§<0AʼnÈJ>øà&³&¾ÞPñ<`R‡ê;~XwN],;xñà³R»Ò©+@Ž<Ã÷¿óá_|ÿû³f.¢ªR·µþöv}s»~úèaJ’Ó¸:9Å;®ëxt|ÒΗièŽOVM{ùö59?XÕ`ÌÉ3M/Ñ"šK©¢gçÈ •R”œ!zæ)IZUµ˜¥h?d5ŒŽ½w¹ˆˆ0»£™«º ÞI±YÛ_ßÞ]å’-ÔKŒÕ8f$ZΚÝ~Ö ý¼i„¥‰¬a’ºrq¦b*Òõ2”ÔT7ÃHh!ÉEUÕ1‘÷Z ;ïÕ»” EF€üNèW…0”Âhˆ¬Ô&š"ÕU¨›Ùz½w“åÁ9WWa³‚ŽãXRÆÑ3!’c‡D!Tˆ”Sž<~€ØÌæ) h¨jdEѲ¡ã´/h´ßn‰}¬›ûû»PÄr*9¡ c÷äÁóËÛ›§Ÿ²Ífàœ„œFv>ÖÕÓïßÝ\w»‹Ó‡>øôÓßüâçÑ{ïýÝõÍ|9‹U³YoŠ&ú¾Ûï>}ZЬ×7'²sì!4mB¼»¹¹¿¿±çõú~úÔÍ9³w9§vÖ ÂÝým×õ>„ûçß«bøé—¿UBåÃFÐ&¥ÒdøH©Ø„x¯b$"ê‡a˜²e,mzP“¨â´+Òƒ4WDq‚O™’›Vö|د›‚”‰áDŒ*‡ }Έ Z´€xmSîüÀ~)f"ÊSº…ЦÇБdz¸št8‡è ¢éúÛóí>YßmrJ!¸f6«Û9;·:^>>;»¸¼Œ!¬×÷!ú“ãcUkšêììôÁÃçR9—GyóæsljÓ7‚HéÝ´ ŽCL\r)©d3C4DU7qGÉL5‰9©hVÉE™©mš³Õ¼©Â¬jëà£óL<ŸÏ\9åízjêÐ{¦Å¼©‚/"«åL²íº®O#2‰©#Ú© ±ªëyS×UÅDUU;Çh”“Œý€DغTFQñÞ3©2sð„èL1¸PǪ­kF ž›:2ƒ:â¶ŽMÁ397oêi‚¥¢SÑ͇‘(¥¦E¤Æ”ó¤”Éϳï»}Σxï™Ø‡0#9_´bÁ¢btLG§ÇŽ«n·É'gÐÜ~»!0Q+"wëÍ“‡g¿{õæñ£³®ëµ$˜Ê¶Ìì³s>€ ×móàñ£ºž]ž¿ººxóâ[4õüüåKöØ4ó¡ºýæôìóáêâ^3ч￿ÛîBˆë»[`:9=±ºÕ‹Eß`¥jꔊˆL½*R±#$vÃXÀ@%'†Þ3²Ÿb ±ŠDbðìšP1Y !†Ùµ1ÖÑ/šêÁéÑÑr9›ÏÚºšÍÚª® D¨¹\ÝÜÜnץ䒲X&Ç.VÄìœc†¶ªS*)•}75‘‚ˆCRÉý8–é#Zr‘â#E’A‘¼G@T­‚wDÑûBð¾ ‘AózÖÔmˆ¸mê¶ŽM]‡*„Pyï³÷TUa^E0˜Ïšº©SÊ"FLˆ Ž Ùá(”bûaPÓÚ‡à½#÷öüÍn¿Ubš|1†<ŒÞùn·5UI)õÝNM|¨C«ºIIÎÏ/rë¶u¡zsq±Ûo‡>¹Š·›±ibôqyṟ>4Y™‰‰œv¨²!k¦ûÛk@/–ÌnG\ßÝ.WÇ 4ìûº­ëj¶¾»†m]5Îùi)%K.iSNÞûÙrÕí»"¹iæf8Œƒa·Þ¼|ù:D^-Ww÷ëª %‹ZùÓ?ùâ?ÿõ_µõ ˆ½ó@„DÁ{vŽ`’C£sÈÌÄ&t/# ywØ(13 ˜'òDÌÜF;Ï„¨`ž¡65c@ïX™’L fžÐÚIŽè(c75;€ ½ófàÁ„ŒïLT§ÔÚT%šÌ©¬2;p'ŽcRµyÿö/ÿ póÝz{~yuqñæòí[t<ŽcÝ6H«Êyß÷ãýýMÝ6óåÉÝímö|úùlv”öév».ªûaxç±#E&L¥BxÚGç\R*)µwU¬“Èál³PÕU$Äb¢`UåOŽV}±Š>T¡ª[brLÃЋè¯÷²†a÷ý®ˆ©)VÁŸ,ç¤dL̜źnØl7IŒ L`³éJIj2e¢¼ hè½SSÍ¢äx6k˜˜ïª*µU]Uu]Á:Aª£këÚ;×F¿lšóÜÖÕ¼™!`ˆ±m›ª®Ç¡¤œD³gÉ•ŽTǔŬ¨öiL%µMüàųXÕm3wÞ;läœ35tLìbÆ1…8ÄIêvs½ßÜ}g }·{ïý÷<‡”z‡ØTÍÕíæÕÛ·gÇÇÛn÷þÓ§Ë££Y3âw’AGÞ¢HaÈy&¦ûøQÆín7ä¤Z²Hp„b 9“#œÌpާÅiðnß'SQfVšÌhÞ{SǼÓL€>R^´MðŽGÁqp>Æj:-$ɪô«ß¼úo?þÙƒÓ…'žŽmÌ.VmŒñ,øn?vw‰G†aL5VãÌsÊ=Hhf».9Æ}ŸLt:SGdœJ®› ˜ÐCô„™ÑˆrVÑýd&¬ÕÔTÛ¦I);ïÌ`Ñ´mÝTUð÷éÎ3cˆ9I~êS§±Sɹ˜ª­ƒ;9>Úmú›»«“㓟:€cö9å¦YL— )ÎD”\†¡ûÎûz±<Ú­×!Tªvuy=Œ!­–ÍÅÅÍóçœs¸íÀdš'“«]Ƀ©©‰ Ü\]œœI¶·ççÃÐ=zOž>ÙlÖ7p‰Fg!¹ûÛ›åêh̪XŸ;vŽ\’K)RÊôÇŪ"0¼¿½&ä—¯ÎÏΖM5ûêwßÌçÕÉê˜EJ3›ÝÝÜÀ³ÿËò?ü÷Ÿß^O~RTï™&ç\žˆùÿßþËÏ~ó«Rä`ãFš>Χƾ’™ïôKDÓ)µé§0™¦d$òÖ ÄÀd¦T¦·Â»¯Aff&šÐp˜ÚL­$:8}ÑÌhÂHÑôµ0¡¬ì`@\Îëÿô×öâÙ‹Y;G¾Û÷ý˜JZïûœ³÷®;äé¬èØúÇOŸò~¿%âãÓÓÝf_4Ÿ=xòßÿþ7Û{퓘ˆŽ"FïÑÔ±+Eûœ˜ÙÀUBÁ³¨ïMmÌÉL‰‰kçª*09Èy}¨ëÊÏäÈ@TU„ÿŸþ|½_÷Cº¼[ßl¶]?,çmª>õã˜_½½&`ï»Év H±ò":«¢¦”,åªYË$g `tÌÑ{ïÚ&8ç˜q 4À¢©¼÷!8ç˜yçæmMÞÕÞ;æ*Ɠժ©›}×Mu7‘RÅ`€ª’KQ+¥è¾O}?^Þ­w}ÿìщýÕ—¯÷ãöÓÏ>™ÏVŒcŒ>ŠL¯’!úªŠÌÁ\UÝ6³YÉ©ïÆíæþö~}{{rº¾¹C„”ÓçŸ}ööò¦Žáøäd¹\±ó‹ùœœr E”–lÓ7—ë‹óöhÎì6ëAiêÙïûuÊû“Óóùb}·Ç~¾X”TÌd¾XNÈ53ÄRdèö)Ì<Žcßu¡ŠÎS+%3û_ýú_ž¿xì0þê«ß.õÃØ…œS1§4Œ½©…VÇGW'_ÿþuQqLì<#9nB$æ÷Ÿ?üÁŸÿ{7]ò¦è›‰‰éaÅ ˆ‡… ³þ+½’!Næw}×L” q R½“jAbE„‚ŠEŸÁk 20Q¤i°IXDÁ¦Ì+(ÜjòÅD³ƒƒ{ê-–õüË,g3Ç̼s‹ùòòöž«q»ëbôUt¿}þôñ)2[̉=­Nžßß_=xòl}w9›ÏûË_¾|õ ä ä1MpMCpjZJQñÁsÁ¢EE‹èѼ5³aÈ˶)fª‚Dž(gAF1 ƒÆcíCtìɉˆwNrQP5¤¯_]¿¼z£g¦å¬Y-ÚÓ£ùr¹$ÄëÛõùå­‚:¯¢€Ì:fS™Ðë»4rR™:5¥BdFçœG Á¹¨IÓ4h¼óÎM&SŒ!0a)٤Ȭ©E” [ï5’kšXÅjS?öÞ±‰ï LyG‘2É$ïúaHiB]þä—¿{r¶|ôà4pì¶÷í|af]ßï¶›¾ïî®ïŠôšáâUV³œ³g¯`MS;7÷ë,éÅó÷¿þú«û»ííý¶÷ªú³ù—gÏ<>{ºïvûnûlö­a³©™‰ãTR˜Š|ì<‹l·0¹’Ê~w|z*YUeìíÅëùlùøÙãXÏ._ŸßÜ]|üÙ·S™©’óSçiª—4–RA‹š™°s¯^}ùâýçVð×/¿|þôAëqLÞûªnÆ4vÝ.†B ”óÃG'ñ½/~øË_š)! ±Z5qh‚窊“¯E´ä „&†ÓàÁT¤èÁê¤ÓMÙT‰E'Š¡ØÏ?ÔÐñ€øQE1å©ö{øm* ô‡C¦¢áôב™…Æ1 0¸é!gD@šVð“Èl"‰+,—Õÿüoÿ”ÐO”è"…½«›øøÁñÅõÝõ¾›:†mSovCˆ|»¸ûxÖn·ëÓg³y{||rþûoNœ^¾¹üíW¿ÝçÁr)S UJ!b0MIT³ˆ…à´ä‚&óÇb0”$ź4 ;n¢WÀ*º&Vчټnë «X±#Ab`(Ú÷ÃÿõÿÃæ£EûðtõôáÙÑrÁÈfæÐ__/çȇ–œÛ¦Î `ß'öÔ2L0vCdïpÌÉ»š Ù±5uÅŒ<õK1fO(Rê*ΚyNãÄDjb5æç‹9ÒÝýÚL¸ªbN @siH"%‰(Âz×ïºÝ˜R*åòúnÞ4÷ûýƒÓ“·o‹(¢1“s~6_„*>xt¶^ß­ÎDúåщsAJéûn†,ùÉÓÇíâèêÍ•þö7ÇÇGu³,‰x̉п¾xcÈo¯CüÕ'Ÿ}·*f:bˆ@DÞSÉ"RrYoo<~œ‡|{w}|zìœ[ß^Ÿ=>­«ùõÛ·_ýÕçßýNˆq¶œÍŽ>¾º¸œ/‡ùòˆ‰QŠŠåœ¦Ÿwß÷`RÏæHœúNE®..ÛyµZœþèG?Z,jï\3k¹Ý~˜¦ðs,j}ßw£®ŽgÏœf-SQ‰¼sDØÖñųçÎg`EÀTì™v.ãñjy¿ÛO—Ô Ê‰ŠOÆz²”Ù1æ"` x .–†%x‡"€HÄÌ BÁ̦T¾8r`l¦ÿÊ;oŠÀ¢T”´ù²þ›óGU¨‚c–ýÅÛÝn|0ƒºnšª{xrr¿ë†Ô_ÞÝ;¢G§««ûMU¹Ë·>„åê$ cÕl±ÚÜÞûÀ¯__ð$@ „¬fŽ1AT&.¥H‘PEvL¢}N9¥TÍêà\$×ç\Õ J±éÔàSb$ 3mêˆBˆjjY†7¯în÷÷MªÚ¶^´mÛÖóÙŒ†tu³½]o ¡©[WUri¢Çâý¨€Ñh7ö€d"f@ ¦è}0Ä*0‘sÊm[›©]Ì«ƒD] *7›µU ±ŠjÅsè†Î;®›õchÛEßu—W×`RÇ8%ãØ9)%¥¢ªìÜØ§’JQÍYJ4»]ïWGWÇ?üÑÏ?ûøÃÏ¿øîÙÙYUÏØ r¥”aë¦y{~-)ç4ô"*9i¸fWRî‡áæþîn³ÞlúqµXNAÿbô^Ä~þÓ_¾9ýƒ?ýËç}†ì ”éœ.Ï/æG‹‰wè"»Pç! ©{üäy)‚D_|ïûݾ»¹üÕã/šf1[]ŸŸ¿¼ýêìÑ£àcΙÙÉtÏp>J‘bÅÌînïsÞ={ñáÏÿù§§V«“’rI¹š×M={{yî#àÍõݘFY,Úª¦áï÷³õngªŽ‰½«B¨êz¾X|þï"WnL ÙTÅ„‰E$"ºûínZKLcwp¢s×W§j/ æRˆHJqLF^µ˜Ðü`&šýä{<Q EŠ¢s„–GD5Ái¸£b€S© Í£˜ªZ[…!0õŽþÝŸ}Q…VT ”@Û¶®«z6›u]×íDJE†qt>¨ˆ#ÞvÃ0æ¶ZÝÞn\¤Ùù+D !ÄX!-¶·›ßŸ¿ò¬ eºíh½ˆMØÅ”u1sYıï»=Ô±òÎ9ï%KSUëÇüTÆ£*x"Z.fUUÅBÝT§óm.ÿüëßxÆR$Dž5M=k³EˆUN¹ëû_|ùõ8–õ®'„䘢÷ã(Ä8¦4o+fî‡ä#qßgSõÁMU•:F¬¢ÏEÆ”ë*TÞ1’‘f^×íl"F¯Žª¨Rœ?\Û¦ 1vÛÝíÝíTÛžFèfÒÁˆ"Û®ï†qJÒ"ÓûÏOðù§Fúíoq|úÐ^}óf³½ÏãàœóÞ{ç÷Ý~º4¦ùbÙ´-Ñ)!¦qPÕífƒ '—$û~ÃÈUãW‹£’ój¹`"¡:>9.¥\¼z5Ÿ-ªÙÂû8i|öë5ºürì»ûÛë“èÕë—ÇN`·^/O–G«UÓ,×w7o¾þúøô¬nf«gpE_ýú׫ÕñÑñŠ™K*›†€Š0ë÷ÝÍÍŇŸ|òæ÷çõŸ¬ÎT54»ý®ä´\,ö»ýõõÕòhUåÀÌcKÎÅGÿÉãWÇgÄBð>†*¶³ùòÑãI/ˆLD̑ЀËÄ#G4ůMEæ³&e1Ði‘BÈ¥ÈD˜ñÎI)Î1“Š›z†*f ïMʓ׀²Ø¤L3-E@ DÕO{‰2A1NMuƒC²›ø³„ßÿö·ž=|_o·CŸºqS:9Z˜*;žÏgM[_\\ÙÝz+¢ûRöãp¶Z¨Ê.哸¼½¾ÒR¤”££“¢ú믾Jy('Ý €wÁ;ÇCÊ™ˆ›& ¹x‚¬‚«šzÙTUU©HcŒ1^úà™ Ù9$v¼1ÔMí8¥1!ãõýþ›·oH»±¨•à0„ "fðêÍõnÜ™Á¶‘6Ž—ì¢' å"1„"ÆÆ\˜IJrŽKQ©êÚÀªè‹*šÕÁ‡à¸©kCpÈL諼s±’œ‹È„skfmS¬š]·»xóvßí€È8Ç.ø”‹H)"f¢+© EÆRr.9¥¡U]ÕOÕ¬‰Í?ýÓ›¶Z­Ž?~òþûïÍŽC¬ÌŒÙ¿zuöðìòòí£ÇOÑl¢L³»Ý¾Û® áäôlx³›>[†¡ï†T5Ûºž‰@†`UW§§u»È©ŒýÐw;@¾zûæäÁYÉe³^/VGÈîúõ…¯½1 ã¾ß|ðì35ºxóõãçÏ4ÛÅëWÅÒ“g/æËÑ‹«·çý°{üø9O¾TöŒFe,oÏ_}øñ'Ûûn?Ü¿÷âƒ4¦œ9çœÛm6c†!Ù“§OK.»q\o6»®««CÅ„ªúÞ'-Ž# ºäÀ5m³ZÎf9ˆŠ*SuÎÙAË6…òÌL³zHY ¤0EâÉ75m#Èa`G„ELD•Àå’À&iD`,y¿0™™êÿ¶“‰ÙD '•ý4ˆÅÞ?ý£Ï>Ï%ƒjžbˆÑïû~Ó7¯^ÏÛf>ŸÕM»\¶³¶Iée?uåͨïó~HOŽ&&j×uw7WRÊ8äŸüô§9ç˜Ó(ÓäÉDÊ”ë0 3ÉÊ£(G1VŽÙy˜Ð¹©«‚ÈÕA¥Ë³znhHÈÞç«PO¯e±¾»¹ý»¿ÿ¡cD3ïªn¶}ßã8´Íl7ô!Âӳ߼=Óœó®ï«€AUBŒš³©MÎú© €EtÑ6zæéÉrcœ9Î9ç|IÙy\®Ž­(2O„K𱑻ÛÛ:Ö·o^kÉS4ŠœsˆS"\E”˜I!•2æ<Ž©†!Y„Ñát5÷ÌÑ…Wç—ßùÎGï¿ø¸žÍ‘Ð;_Õ5"±©„‰18or(†"û`šƒ÷£ó)õóż¹kÓ˜»~h«Š ú¾¯B]r‚ùŒ‘½Äd*ι’lîo¯Þž#*¡Gg!V»Ív½½Y®ŽK.—ççž=)9ß]ÝúȈÄ={º¹_¿~õòøø¤©ÛÇÏŸno7_þú—OŸ?ðè ƒ¾üÝoÏž<ÌY_~óåû¼?M)}Ã8ì6÷²Ûöåìì ïïÖëͽ€®¼÷Þ3Ûm·w÷׫gŸM–ÃýËž>>=Æá_‹… IDP ÉL$RÚº]w{0‡$"¥”’²¨ NAöd¥¨s@¨–K)eØ¡©M>nGhŠ rp£L[E¦ÉEaþ¸šUQTAt>§\7áßù¢»í~L£ˆ¨÷ìØ9ÏGGGÛí~»ë$„úáɲšóë[35°Õ¢DB ±®b@…ÛÛÛ«·w÷÷7IJ ÚʧQ‹Bp` Àd©¨s,E2Stè‚W@ÇÎĦ÷‘N)³”ªXû4õ‚©ŠU¢˜¢P)Ù•’.ßn.×·Þ3/ÚzÞÖ‹YÓÖµ ~Li³Þ}óê"0:¤$Z²öݰv¾©«6V%‡#¢Ñ^T“³Ð9î†\U!Ä@8Å—8?qç‹ ‰Æqôì!IUBˆ}ßÃ8tCÒ®ÛÍÛ¶ä☂ýØbÆ¢ª’Etº.i?”>ç±äœR?&CÀŬõ.´íìÃEõäé v^K‰Ub…‡p(°!—RTCU•\D Âb„¨>†ª®–Ggý¾¿º¾ÙtýñjÑÖõ0 ¹Î¦Ðí·uÝ–®ÜßÜÌçGuÝŽiÌ) «ÂÍÕ9]ž×m}w{ëcX?tÌ—oÞÆÆÍg«_ýìg/Þ/Ä:§ Î;1§|{sÇÎV«*z}uÙ´M]?T‘>9•ݶK9‡à~þÃ>ýà‹Øœ€ù*H îáÓ'/ž=Ny(© Y[Õ±ªÚvFÌã8l7û}¿fN¹4Mƒ}ß§,CN":ŽM…Èrd’~q)¢yjeLâ¶I  @L˜‹xǨ(fÆ €À4­íÕ1«ŠNŒ¸©×f†©dÏô?ølÕ.É¡ø@16iÌÛ®ßïÏŽÝ~?_´Z¬®«ó‹«\t»ïšÚ{vf†¥Ø0 >¸”¹ª‘~ÿú\M«àÍ´¨0º¤â!£Â!Q Ó¤Trç‡!-ÚÖ{WWÛªæq,Yêª ˜ö}·˜/سƒwæCö^U‹è?üôçÙ9j¢o›°\´NŽæóVRaòC>8:þðˆûÕï¿)¢¹È~¿ŽK‘™™-t3@fB4{´Zîº~V‘Ò÷:oª"¥ikú,À¡s„nŠ’É7ççÄ8QÓ˜¢ )%pì À§œÿP 1¤ÉP¤äaû1A1E²§N«å|1ʰ¹_ÏŸ­¼w!VS›”ß1ŽxS£—_þä£ïýÍ¡;%~Ül¹8=9Ic§¢Þ»PÅÅrÕÔMÝÎBŒC×ßÜ\]_½Ýîv^\Uù®˜hHÅ—0 ›ˆŒl£)Š–”&€ü$ GÉL§hêdàÕà –' ê!@`è¨#&›j“-au:ûÖ£'H0öy½ÛöÃXC¨«("ËE3Œåv{q²œ·mBX,Ú*ž"½^oû$c ž‘ô ÛuÝn—.n®§ÿ¢ à}°)£Ž§ L. ‡§]ˆjVGOŒf¢iÌÉ9žÏ[ôÓÉ/„¦n†~\œÎ]Œ vêêï~wquwidÑs¨ªªEÓÌš¦ ‘÷ÝînÛ½|ûúu¸- Ž|*)‰P¡aLD”cœQdSǬfYÔ3™Úz·óÞ¢'§¨ë]¿˜Õ`0£ D‰™Ùy3"+¥Œã¸ëv>xçJ1tˆÈ¦â!pŸŠ"°ãœ °ã’S)%SEÅ •‚`bxþâÉ0Šˆ2“ªL.Ÿ\²sNDÕÀ|±iv»;BS6sŽK.)ggŠŽ÷›;çƒ2Ï‹Åâh?v R.%§R$Knë"…è»ýŽGà©|ãb˜¾¯ÙbV·5Xuws³ßíŽNV㘮.޲ǡ•âØ¹ɤ”ä¼{üìév½½8?'æ'Ï–í·Þë6ÝOþù?úöÇÛ»M7¬ßÿàcS‘ÉÑŽûý>6aµ:)¹¸ÖñǪöü÷¯RIUôOŸ}ZRrì²”n·ßnw?ù‡|øÞ'óåÓÿßqÔ¹P…ZÊ !V±ªÛù¬®ÛÙb9õdåDФ\ú®›,SÓ3ŒÅØ1©ŒÙÆ4–r¨ùÀ(%çlhž\ ÃÕ£èÄ”‹cžº8Ý™ð{SB2%"xg6`Q«¼ûŸþì{uÝÆƒÏˆV…0ä|y³I¥˜Ééñ2—ñáÉ*%Ùí»}7,³4âéÉÑêhùêõe7öËY[ŠHNEë4榿úòK‘RJ&äЪu)¢X”ƒ/%!“ePF >˜Çćû€w´˜/Å$x/"ÍlVR6ïÜ郥s¤2mAGr^SN©üó/~Áž<ùº‰mªàcôMÐTæ‹ùÙ*ïúíGï=Ûu£gÿ‹¯~kb¦0Ž)zDŽ潠!3‰š¼“ Ș#’s8Ô1ôýXÅqß3«šX!PÎI•¥ôÃ8†è½wÑ…,Ù{ŸS_J1z¦”¡fN"Sù:ÉÆ±tc¯)—”3L’8kãÑÑñ˯ߤjܧÝòhÀ æCP@0¥÷ÁÀ9ͬÍãX/Z t%¥ýnGL9ªjòÁŸ=~óöÍ®ëiß›â¾ÛµMS×-n·*罪õ]ïÁl»Ý-Oš4P™øàsÑâù›kçɳ‹‘‹e½:?_Ìg1Ä““y½›®Ç"U×c¬^ݽ¹ÛnJÉc.‹†K±¢Á ¨¡ ÃfŒÌžb˜£Ù„{/YÍkÉb^Á„]ƒjªBÀ”Sޱ@G¨!´&:¦dVPBÊéGÿüëË»«à£gl뺮ªãE;«*缨úàê¦iÛ>F?›5)˧>;{}¿ß˜i.ÒõiŠC˜iõŒŽ˜:ç§›tÎyÓrV›ÙrÞŽ)UÞ7Ueˆjâ)nÖ[‘±®[M¥˜‘±K)¡ €ÅQ¤œ€Š”"Îù4½kEÇ’ö}R)Œf*6±©U—³*÷Ã~ß?:cJ˜sbÇÁGä¼w<í›`r-‚A±ëî €‰«…¨ä *ÎÓhEWÇ«¡Ïo¯®gͬ’wT²ô)÷ýÈ숹ßíÓ¬ŸNR%¥ªnÉÚz¡¥³MUUM»hgózÖöÛÝØ÷Î;ÄIài}×£ª€±«ëºzÚ””ù“ŸÅ¹ÿäéµùåju|wsË䪪Úöùþæ&笖›f&EOôù÷êÕiÚî|¿ýÇ?¸»~›syûò›XW}þ™÷q¿ÛYßw·çW—¯~ùðùÿßCØow××WwÛÍäô»¹½»¸xût½^.W*6öý¾ëÞ¾½¼ÞÜwû>•2ݧK‘”% CI©d3¶Iúí €͈Àˆk‚4ŠòÁlÈhÆìP LÔçIÊ/š D•˜tÖVõý?jšÚ¹`:ãz½YowûaÑ1ïª&8vçW×Ëy[WË99~ôð¬ õåÍuN‰.ÚJŠ˜Ázßåõîn³Ï9É` @SC[Ucv}_Ç ¢Sa”Ì€‰bpÁ\]UuCŽI³RÍì#_ÕMN)Æ ¤àn·‰Î9çÆ½²»¼¸ýûÿ(xn"³mçu}4oCŒ¦6Ÿ·ÞEU •÷蚦)Y×ëíÓ³³u¿S5dšÎÉcbˆd@Š@f:ù¨3 I`Ìç;Fß 3yf$B„¼ªÄQŒM×íµh.êc@Â~?ˆfB’R’©-e BÇR’¨ˆ¨¥iƒ4…œ÷ý‹æPU²»7Qð>ˆi “6aê~"{‡„Ì ª@l mÛ–R\ˆãЗ”JçÝXò %†XÇ *M‡qTɪ: ½ˆÌ»ŽØ3ÑÐwÍ¢6Ó‰Ðè9cˆ¡jfÓÁǨj†°[¯SÑ13OõQ!¦ƒ±ãæì¨òí¿üäG>òçßù£Û«›‹×/NŽ//®ªÆ}úÅ©ë/Î_ëó?ýÞŸ„åøÅqXYßÉÅ…YùüO~Crë›kUØm뷿ýêôñìêÃC¸¹¹}s~µîwE” Ð!üü7ß,æU+Ûuýz·Ÿ´ìE•‹JI¥ˆ•’39‘ÉÈ` ÌSöšM¥˜xŠ”‰õ¤¨`Æn2у™™¨ŠyfL:Š#¥œ™ÈÑ4l`€üÝÏÞ[4Ë+-¦S ªŽÑöìÞ^ߎc)E¼s'«¥c·Ýî@‰=8%‡œ)¿zs!%Í]º>§<Üßoú1)h<˜Ðr`“:öj<#"c$BÄC]Å6„fV!PâDîaï¦?ˆÁ{vBDHÞƒäb9‹ÊýÝÝßý·ÿ¡VbÕqª*Äå¼iÛ–€v}÷­å‡èìîn뼯êJ²¦1?xxô// L¥ˆ9WJé ¦ :%èsɘÐÐ ÙõÝhhS¶˜$ÄÊ{C(E™ëXÃRÎãhdRtHIm²E±a9Ø &ê’‚e•\J*¹ˆŠZ)*ˆ4kbðÞ‡cû¡iÛP×:©ó̬*¨SHÙ˜ÈDMÙ9BŒÎû,Fއn(¹kšøé·>zõö›³““"ÒÃr¾ðèê¶ebUKã°ßm›vŒE 2M©žÏ) C¯YPK&æÙÑj·YßÞ^Õu-9Ï "ôÞ;Ø:½ùý«½_~ý_Ï=H9-Ìì‡ÿý–Gí8R]·«ã“¿û]" ³%¹Il¿½¹lf«'ߎ %¯o‘éáógÏÃGšò8öûýv}þõñóÏá®ïnÖ›õ~/R’L¸íbvª‡ÊÔm™ JRUm"I#Ó4T$rˆbFìÔtHeŠsO¥ w(Ê#ÈAÍ‚jÅ2˜‘‚9‡NhR˜©aÓòw>úh:ÌS:ø€,iYÔ³«²^Ì@èÇqÈ¥Üï¼§Çg'uŒH°Þî%ß/–sF~xr|s»¾º½wÁÂf3&#` 5èÇĈ6fSCOHäS‹Ñ5UåO±9Ï+ïØGœ£bŒÑOÇXÏLDHNSï£Ë¹ˆš¨äœý՛˻+P‘ySÏ[¿hë*D4•ãÓ•™:ÓÇ×ûm3kdJc‰Î“wÊaBdéÇì‰@ÉyBDš¢KLTkQt§\!¤Òe窪rȈ™œwý¾ËeL%‹ˆÂ@ÇÝÍr.¥LhH9Ñ”ÓÔü  RÒ„L·‚‹Y|ïé3‚gNy\Ηã&»!Ѝˆ03"(š‚‚!;ÇĨ:"¢*ä¡IÄÔÌM?ùôÓ»ÍUUWÌž6÷óÙÜ;?›Ï¥”I9°ßïŽ%³Š€iJ…9‚‘ˆMM²ˆ2 UåÍ$ghgì‰Ñ­ooïînÚv^7MŒ• FÙ†y»úùüÉ_¤¾üö׿|öÞ{¥È£‡'/¾õaߥóóß~ûÿdõä=Àhãžfžisë›°8~€ÁÌüÑÙÉñ£ƒlPrS³[wûmîï}}n¿ÞßïºûíVD‹‰M$;ЭškR˜4k“ pr°9&S‡è¦·šÑ„›òàD (©'WÔÔl’ÔŠš(83çxâçXBJéÐdÔ)Æ ðÏÞ««¦¸")¦:o›qL§«ÅÍÝ&®êEJå~³Í·»]·ïž<}t´8ê‡q·ÞöãPÕquÔÂÍý½cN–&^ªCüƒÜf,¥­¢^@ÇMTU#Rƒ¦òHT×-€y¦PÅœ#&vRŠ‹ÁNCBeÆ”˜œjNÃè›øóß|E伈)Þ³wdÞ»”äñÙcD"r\²Ô1Ô±õXq8ëXïúØtDœ6¾†ˆŒà4ç0x_’N˜?1ñ YU2‘BÊ…(9*D{Ùïö»œJ1 LX² ct$b`–DEtÈ’Ò8=HcÎCJŠ ªæ½÷ôá¼iA¬ëz3+R˜¹”¼3Çaz¥£›*ÓL¬ Éy?õÔJ.cL-VMJi¾œ1…®ïç”ó0}?æœÕTUÙq̾ëv3r¹$@*’Ù9bò1"1ü¿¬½É“®Iv§uw‡oŽùÆ3oÞ¬Ì,U•T¥j¬ÛÔÐX†,X±ÀŒÿŒ`,EÓjPKª¹T%¥²†nÞ)Æoz'w?ç°x#5 «jøV±‰0‹øâ|þºûï÷<@¢LUU${ïÆ¤z…«îÞÉ£<¤ëË SYáÑ«‹/ÏÜýå…XµwŠtÿ§?ø‰Q~ÿÃ&“eJW¿÷ÏþåúúfqzŸŠëåWû; ‹àÀF@Wþ­sP.‹"Taq C7 \Ù·]Ÿ2‚jVr$¢î®i ¢ÀÌž‘( âÈPBF0l@66Ñ «¦”@˜Øè1F5@•ñîøŽ7,d¨ `£WTá.— >Ðoíƒà IyÔIŬ@”âPM'½cnÚ΋ëëmLñ`9%«M7©ÜåÕµG¬góÊ q¸¸^ïbŸÅBð7ëÝÐ%vd&b *D¬ˆª#àг·²(CáMÌ9bç\ð®pØ{b l@è|áx,{¨/æ¾CƒaèâЧœ¿û;Ûî$2A ¨Öu±/«Õ¢4À£ãU(kbq;]Ê2øÂ{_ètZÍëýÆ¡Óh(ˆÔ æ e(îÊ)¦ìÈ%•$XxTб æîºš³Š `S"Èæ{cUÍY°z5íª}L&bItˆ#T1'QÓŬšVÓÉdâBHªÚvýâ`€Ä¾,±o‘#šª#ŸS/)™{SûιͺëÛÖàʇâúâ‚Ót6'æåò@ó•¨hÓtªšr¯}ðœ3iê½÷Ä^EÉ}¥#2Uº‰SŠÃÐU„Î{͋Ó³nßí67gçg/_üêéûē餞ÔËÃEQÔ7W—§ïM&3¼üòW§ïþöß3dË=BW}Ŧþ{/rHŽýÝ|º¡ë É$+113©yvè;F?’Øs΢VWõv·À±ƒ^ @AØ ›–E0鳪#Ì*cÛW 1‹ ‘0  Ù72P‘¤#·Í˜è›=Y-ŽrÊ FB쇦ë˜]Y—Ý®?=9|}q3›Uò]×ûfR‡ó³{uq;mû£ÃƒP–÷N¯®nùò•JêÒd]Œ£k¾.«~L…éŽ'|0°œÄ ò“²$¢²*ÙsU•„ìÔ‡Ê…àØ«ebW”%ôM#wbÕaHïûÛŸ|ü f3v®,|Þ{W—Ôd¹: B3Ac$œÎk g€’RQN¦óøo~ð‹×¯T²ªd•À8ôCY¢&Ä}LÞ»„ÑyGHƒ*“Ë9ApYMUTeȼ÷ÌbBŒCÎ)çÂ;vÞDØ’ä,YÌ0¦ TqÜ fÉ¢š$'•,ª Y5<š?;.½c牰ðÞú±e±®ësŠuY 1ªæ, IÌTú~Ð;¸3‰¢©æ;‚6 ¡©ŒŽ¥Ñ7ˆ*j`UíN1heÉßzÿCJ1H›,’ú8 É3¦+(Éa]MËbWquc`³É„ ¢Ú¬t«å„ÉÝÞlu:²ÃÒ¹«Ýž ¡.ƒ'¢¬€*@è‘ ?z´"ð¬.År2OjÏ\O&hVבLÌeY1;sX0±%¾óõ]'šUíàìô£oüîÿü?ý¯£ð´(œw®,˺ Áyö¾žÖÌARÏBDARÎi0È¡1¦²,ß}öèÏÞýé/?‰I3±÷CÌuY¡sÞF*ŽÂX>$„ต‚#ù_&jH1eg4ºˆM5›ªö)ƒª)öà¦)‰©¦œSŒ Ø¥œ³¤œ£éwžœðf׿~ûæù³÷éüþÃWŸ½R_ÆØ÷]ßì¶1Eɉˆ\4+ 9öÓù¼,'Î;¡µªiv›Í¸Â¹ />oA/‡¾RZo6ãí(€…‚sg÷NŽÏ»¡Ë}Üí÷Ô‰&+˲(+bÇÌìT5KJfŠ€–Ç^–˜SJˆ}NÙyìÛ6ç<™Lëétµ<I¦a·Þd΃²?6µÍf}|ÿÔMî´òw#g 1Ì ü[—õUUyï§e ç;WxÎÞ#€/¼wމF%2ä40*ŒQ—­˜bÅ(DyŒ˜ØÝˆ%1SýH¢Æ¤ˆwJQ{…`ÙÁÝŽîfSí£¯=™Oˆ0^‘±™ªèïj1úHhˆ´ZÌSÌ!lB QìcÔ˜zÏ´X-NÇ©‹_¼zâÐöÝÝu33#ÁâÐ æÆ»#Īò9™'REP±\`ªÊ2°+ªÂs2ÔeÅÁ“9B`ïœšåœØ9‡œƒo·]¨üïÿÁ¿³×¯¿ ÁbŠ¢ðÎñ¬®ª²èº¡†®‹³ÙÌÔŠ"§¤«å²ç"eùO~û£M»{ýö­ˆÄ½§€N5«`†LBP"¸Ç2¸iÖ¨‘Ðû˜’w~„L‘‚ªX”EÅ!3R’”’Ši΢¦–S6ƒ~4™‰Y²ˆš€êóg÷Vóƒ_|úÅý‡_ÿèëÁ•Î_Ý^_ÂåÛËÛëëÛ››Å|¾<<:ºwZ–•s^UE$ éêúµ+BQÌ£ÏDrJ1¥Ô¶ín{»ßmÌ´¬&9ÇóGŠrÒì6±EሊŠdSì†þæú¦(ÊÅr¾<8èûþôþýz²0Écj›¤¼ÛosJì]ðÁ±&êsCÓýÐÌSRÍcß&OŽ»}ßõÛGï¾Çà¶››ž¨j³ÝëtyøÕøýõÈ!†~×+ ¿˜V±dD(‹¼c¢Â{ÃqÇf„djD8¨‰ˆ¡e՘Ƽ&ÑQ”óÝ™Üy%lÄã™ÜE… ÍÈ™ˆ"hpD „;fK‰þ€óyýѳ÷ØQR’œóDTøp»Ý–! q¨¸Ø7ûɬN9Oç³õÍúüìäv½RÌæÄÅ vƒC eyvtôË/>OYBàà|3ôÁqÒ0ä Py&v BĦ¬ (8¯"Á¹Ê{&\`ïŠPpå3{r\°bŠIÍÌTâ`†)FCøÿóÿʳ73r>øà<ïê"TÁWU‰Ä‡Ó³“ó¢,ˆxè»z:+вoº“‡b×0{¬'®o‡é¤|çÁ‰#xuuRjº^B•r®JeuÎ|#C(¬ ÐÔygŠãÉ—¥Èæ’èø_cHUpc“{üÄ4yR²”3(¤œLU³eÈY §¤Y†œG¾OκXV—M»_,¦‹ù¼Ý5¿ºxquu5[…Ó“»Íº^ÔOž>¯ªÉc@¤$2´mÛ4ûÝv¿¿Ö‹_||Q×ï²O9‚*eËÓżžÖ„4[ÆØÝ^Ü|ü?)ʇÔöÍt2qÎ!yD,ëb±\umì‡]åv»9:=4UBöUÁ.EÄ¢,AEÛ¶éû~¿ßíöÍÐõ€Z–•¨š®@URÊ¢ * ÐµÍêðȲm»Û{E½Ûîno/ÞûàC †ÜƒûûSg¿ÙJ8ÏŽV«®k‹ÂQøª&?:Ñû!5©g@rîcÌ¢9e#äd€ªI’ŒÈoQ#"³q’ˆd¤*ª ‘C1G(&¦D¤#ßLm´89"{öä^ࢬ&]ÓL”»˜Ñxì:‘ɤRË\„¢ ˆUßç¬Ryb4±SƒP”E0Øì¶e(T­®Š>ç¨Y€ˆ¼‰ËÙ¦ÓZDrÌ쉽w¾bôBQ8ïÀ‘gÇì˜=ÒW®V#DIH¤¢ŽŠhÒüÿå3›ÌeÈÓógÏôãÍèAÃàCŒÉ³[-û¶ºÞDÒíÍÖ{³N:L³gï~Ȉùõ‹/™!O'å7ßýé_}–âÐä¶*‚”ÞÀ=‹ähÆâ€ 8‡6ºÔ]NB¤h’̼sj<ô1«#ˆØh‰)ÆUMDLT hrR0Ñ>e&ì£`ÖüîƒûÁûÅ|ûÍn½×ôzy°,ÃPXÖ•£b·Ý]]\ö]çC˜L§ÎûÑ'½XÀd2›Ìî1™d5Ë)Ç!¶ûmÓ4’Sß5C×n7ÛÝ~W”}?¬·ÍÐ%ë©fÞ9Q}ðàI’i]ήèªïúØ_Žb„ñù“Çóλz2ó¾`禳y·oF\ÐúöæââMŽY5çlUUÇÔo6k@Î×7×gΙCÛ´W¯88ð>„¢ÌQ?ýìŃû÷^ð§4Æ\€ŽŽ>xÿù§Ÿ}J&ÿìÛßø?¾û£. „PBèÁ€Õ™˜:sÎŒ°ò>fu„1&ƒÑ|†DèÀú$ƒØxÑ?˜ª"‚ˆŠ)˜©dë0jb" CLf 9f…nèž<¸wo³Ù·ÍÐtððÑ×?óŸß|¡×õxyu…h?:=»w~ÿ™Õxò÷âsŽ 6t={/í Cßõ}ßîwÛͺÝí98fvÞ•U1ŸÍÔ´ÅárVU"`fJ1îw»‹·¯Š"LfÕáñ©sa´”åû¶K)6M“âZRîºÖÔÁ¶»ýb1GãӓÉdûÉùæêºív7×W÷<Üm·E˜B³Ý½þòóóG‹¢n{µ¼ÿÞß[ 4ÿ&C¨j"9'QÐ<& ̬UËY²Šª"RLQU™hÌÂ3e%&3K"ŽGu„˜9O¦ L(_µÅ ‰G_ïXZ@3u. D5„ÑEaæœ=}üHš¶íûa·Û“CÎHT 6µ!µ“PÞ®·óy5æËàà`¦fÊŽ†”³ä˜yÓöý§E±m÷Îû$Ic’PA&of!Pʹ¾pŽE2•¡ÁùàË¢AM‹ªÀnèCáRN>„œrN(.xQ‘!¶ßùçÿ|¹8¶MD$¡úçÏž=úü³—¿B„Ü(ºyðð|1_…¢ °zºÈY>ûôWoß¼Þî÷CŠ's"j›Řt±˜žœ¾½z»XÔ¿÷Û¿õÝ¿øxßµ”3) ‰ áÐÅ"Eû¡÷ÄC†ñÐE#€g5`DÉó€ šMïš(j&Š„ #ÅËLlˆ‰cŽ`ÐõýÉÑüéÃû}7lö-;"ªšîvÍÛË›º¬Ž'÷ŽcÏŸ<¬ŠšØhŠ©3jwëõÍÍèY,ÖW·ív;_¸PøP¸¢8˜L櫃ùr@*9K&fÍpõæò‡ñ£J„´Zäª*={bfÏËbQ„b·ÛH¶ý¾iÚ&øä}áØ!RQ–¾(œcv>ÅÔuÍúæÑno×·ëõ~·Éb‡‡ GÜuÝÑé±ãBRš/ç}×´MkûÝ“gÏÕàâÕËåÑ÷!‹ìv×§ï<ü‡†mDþúC‡þf³Ý¶Žì!Å4ºË$«a¹ã½ šÉxâœ/™€ÊÂÆŒˆä,âbŽ£y^R2³Qã:^)£ŠŠÈ]SžP TÔTUв”$Hðàì¸Ù5ý0Ìf““ãÇïç!ݬ׷ÛÝÅõUØl7›ÜöûƒÕôææz¹Z¨ VuÝö=€ªZ’¾¼¼!Ç1&³Ìä½wh È R†Å†˜ñ˜m5³²(ˆ°*CQeQfÍ“r*¢Lžib±*eÙ¶-³ ›Ýöëßþ³ƒ³Ü÷ à5]·~ñ…Húïÿ‡ÿîßüëÿóO¿ÿ§ˆ@žï?¸¿\¬œˆ°Ù4ßÿáß\\§))¦”åG?úÙ7¿ñéb^–µŠT“Iß˃׳&'ùËòõ¯ýÙŸÜ #`pÔw=;× ¢ÅŒÁyf&SA@ê“#2D%gRÉæf²¨eÇLHiÈFˆÔLrÕdŠÈû¾ó~ç£÷/¯¶óÉtR•›ÝÎ7.¡ßùÝï8_¶ývu|üÅ/?‹©ßïö9æíngjα/ªj:]¬ˆ]ß4ëÛËÉ|rþà±ó96@I9v­ªµÍ~¿ßõ]ëȤÅtÚôݤ*‡!1ÛHf0¨'Õ½ª:8‘»zý:LÂ|¶Dro_¿¾÷ðœÃþÔ¿S–G¤ßlw»ýõf·ïÛ”’c#¥ÔQDDƈ8Dì=ûQÔK$#Ž™Q5§DLbæÀÐpĸ­S%`"Hjhª€(YF6™d&Z®êï|ë[(´¾½éÚ~·osÎ`èŸ,çÎŽrÒ7o/¯Ö›!ÞN'å~߉äƒÃåH(ªª å^ö“ºnšNEo6Û¢ð·»ctHÞb†Ä9eP)Š0®ˆ£.GN Oªº, Çceɘçø!3Ó,¢à¹è‡‘†¾{ÿ£÷Ý–bÚ¾köûÝž<œYÖõfóþ³Ç‹Š‡4 hŒÃf³¹¹¾9"Ú´.žæ$I{‰·W‹åñöv­š··7bÖl׳ÙtROVoßžžýoøowݾI”%x ¡¸ÙìËà Ro ÌÌ;ÕÀ0tÑh<¾Æ”Ó¸§Ê"bQòha£QCʨ:5 C$Ä÷ÝïºH_áAŸ IDAT„¼k;k†a±œÖu-ªo>ûü“_þÕo}ャ£‡×ñËÏ>g¦¢,Ù…‡OžÝ<"ÙÔ¶›M(Š×/_x_8Ç0*Ò†8tÍ~<ß+ËÂ3Of‹jR7müùgŸÞM¦SG<:[G8åæöv¾˜•õ¤¬ëz:q®W¥aˆ&9±mš®Ý­¯›¡ï7»ÝrµP" ©pÞEB™/V«a¶évÛ5(Ÿ¢¹×/¾e¸wú¯Þ¼®¦“zª÷&g¤¾òëþC¸ßµû¶Ûu'Š)²šïrÊŠ "QÌ9d`0#B$6U#S&VSh9e@ä» ˜1Á˜ù&#rf’€Øì. g`:&. ÞçÁ¬žwM›%#ÚlR×uu{³q…ñúcêú8›VOÞb»n>ùìÅr1™]ß,‹PÌ\Oë$ ˪x}qÍLWë=˜IW@:.9HŒ¥s]ÎÁ1fC2PU0­K_–AÕÂÄ;çy4Ù0ŽfN1@Ñ—/^pßþ~¿mšË·/›f·\-OÏÏÀþÅχ¡™-–EY^__­Ž—»&ÿåÏ?ŽqxtïÄ{‡ˆÞyD(<Qvʉ\àûúb²½½éÚ†‰òþWwòùÓ‡OBðïíýáÿÙÅõµdÍh:¤÷ƒQdv!xR¿ ËÈ’,)'7j¦cRÑ Íh4¸²³”R’.ÆóÓÕÈ¿š…sLæ ñøpV…r·ÝnnwÂŒŽ½¤$’½óD¨Y>ýÅ'féúíU×·OŸ=Có—¯ú¶÷Þ_]¼>9;Ÿ/NBY:˜féû}N Cß§”‹¢èºv2™_Þl `Ú÷ÓªbïËœsc;!vým½Ý߆BQÝ]Ÿªfe¦Ét6™-ÒЗëuYëõ¦Òfý$%_”UUå%¦jRÆNÖÛ˧Gïç$û}{pzìœßocY.V`Ð__…Õ!ý?™1~£!äÿö_ý«ïýäÇI³š ñ´U½Ã$âèŒA3(¼7¸3uf‘”rJ)‹v]RËYï¸PwÉFB½S· ;ÅD#ΉM iÄm¡Y(øþé0­¦¢Úv]7DD±¬yRW“º8<8dBþìË7Û¦™M«£ÕbRM^_ÞÜnng“šÈ˜c'"}74]×õCŒÙPÌFÒi; cô‰‰¨Ãxœ]ø"¸º,벬'“à}Ê¢(94Bv¬9¢ª¤˜L¬ï†üñr5eŶÙÔ³ÉÑñIQV)ÉÛW_¾~õ"~uptsq{}õÊ»p}ÝüÉ÷¾«š‘è`9ó¡pŽ#0ó>3rp’’‰m·k‰1æ¬*Îûº.rŒç¦˜ã4´Ïžzðø1£WÀ·¯ß´íλppz´XîwÛÍíz½¾¼ÿèѯ~þòã_~ÂŽ¼÷j–%Õ\>$cBôÀbʺ¾½¾ÝÜÞøàx臔4Rz2;89nÛÁ,þ'¿ÿþ/øo𡽓ó£ˆ1ˆ"J–»6-ò¸ËSÌ£„Y!'!?žPMGV/#d˜‡¢Þ;><\.»œ2í›n6%È*÷NN4å«ËÛ¦Ý.W˃ã#ËœU«¢3´Âš®×Ü/?}qùúÍçïÜ»÷`¿ë¾øâ30³P£r£, b:8 ;Íâ½SSéôóϿط{-Ër}sÛ{ç÷æç÷—’â—/?ºýt²ð.üðû?ýâõ…wcÍCE·¨fäܘ‡—¨¡ðßyÇô)„TàÕ‹—¯_um×ïûÅjî}88>>8<ß6Ûü«o_™˜@&öIÕDÍÀ9ÕQ+  Š9«á¸7WÑ;ÄVp^$&ÃÑ0IÁœ¾sÿaJÉ9V€›ývß u€<¿zs™’žŸ}ëÉï\¼ºˆip8EO-,›úà™|³»2µ2c~ùù¦:_>}ÿyì:ÍyL&zÆ¢žH6Ü~·“” ‘˜Ü½û/._øŠ¢úÞ³ïbrÞ•UÝ~¿Õ>gլЯã›ëƒ„P SQ”Óù²ëv“zºÙlÌ éöo^¿R1‘`Þ@°˜/+†!=yï]Bo¯Þ}þ~N9EÙn¯={ÙýC÷òö)¼cÕQX¦ãŒåÌ£tÎ1YV%P$Í`Dd€"͈Y-[&Û$A؈DdÄçã*Ƽã1ß<’-͈="˜¨?òÎH€rÎ{_ì›ýÑr®7ëÝÉÑ|¿oÈQŒ‘#’M'S†þž#Büüó—ôÙ;O¾}ÿ[_~þòO~ô“l Á@Á‚wˆfÄDlHÐ÷Cá¢3Õ1ö5›ÓétR×Á…ñ¥,‹Q¥¨†9¥@æÍ1w]Úm›·7Wû¦’O~öññÉÑÁÑñÙýwÁ´Ýí¯¯_tûM5©ëzqqùjs½ÿó?^-§ J`i—4¦hw"YgP ºSm6·’šv_×ÕÁÑÉÁá!#vî‡Î̺®‹±Påáì¿þ/þÅÿþGöÓ_ü˜#‚9†Ø±çØ·ëí6”A²Œ Cç¸Û7–Ä Ÿ?xšSRº®»¹$ò³Å@ØqJÉL]˃ÕvwÉÌ`VW•šùàFõd:5áz~4Ÿ­úaÈ1¥»v¿mÛ®íRê‰8EÎÂÙ¹Étâœ/K?›-SN*‰9\]^eíß}þÞd²zóòóÓ÷øWŸ|rúèt2™ÆdŸþügï}ô¡+k þ†ð×}ý›otähTXQN™Àx¬÷©€ÉèPTP#&1PÍ4úÉÔ u%˜)«((¨!‘‚!IJ_1íÁ1ª("'°qGúôÉY]͉Yíî¡÷ìäh³oo¶ë²ð)åëÛõù½Ó4ÄP¹4Äù|†@Lfà ÁDï«Ú«WŸ~ú"Æ|°š]ÜÜ"‘ª2ª'ED&Æ€ŽHL³Ž?DY2!bQ̾( BVã ì1ŘÆ?Í—¯_ïÛ®‰Ãçg§«£#UûÅÇ›‰/}UNVÇ'"qº˜¼zI?ý䯘Ñ1±©±ç\Ó9EW–f Ÿ“€7GÆä̰íÚÙôз*n¯®~ö£?TL“Ébu°D"UATŠl6©ªƒÃÞ?<:œÿÑw˜4ŽÖ­˜r¶ jÞÊ8jjι±î>Ú²ÀLF7kJ4{Gï<<_Îm;Q×wYòªž CbG>zzvZÖïCÎ*ÒÇØ¯»õáò‚÷]ÇìÚa¸ºº\Tcmx6_UÊJͶ·Û¡ûøàätupœb4³Ím –U³š_1sŠÉ;ž-—îeÁ4j'3 ¹*KÎ'Ù"U¢JÄÌbÞMf³)RNiˆQrîÛv»]‹Æfßq˜ÍÄh&ZO§EY7»ÆÕ“ºžõm{zÿ|¿Ý}¿8Z0†®ï·ëÍù£Çª„ÿȺ÷káߌ®C$C$If„NÅ TD Á’¨™¢ˆ¢ äѺ:«0Ý“‘ÀÄÆl²ó&ÙÆåÎTD Ñ ˆ'@̆ˆ&I‰ȾñÁ{¦æ‚K)1RQøœ&o®®—33Ø6ݤöMÓ 1/ÎöÃnV­d$` …¢êûÞõýpz¸¼Y·Ÿ^¿¸X¯±.½L"jÖvC^²çªÂw]F$ÏP—a9ŸLªÉl:eLJ‡‡DÎÆHâU1ÙKRïýЛõöv}Óô}×ôèòêúòêªþìÞùÁÑiº·¯^Ó§Oÿò'Ÿý_ßûãIQÒØVó>ô1AŠÙœ29cDÍFÞœó—¯ÞœÝÿø'? ¥÷ÊÒדUY—GG§Û›ÝSzTÕÙbVN§ËåêììØýÛþ°é‡,ÆHã°sl£dÔ?*x¢”åî‘dlr:„˜EEŒÐ­fóyÓuÌ$IbJ!øÃæ`RŒMÛŠJå<’¥!¯×k?óYˆ]ŽCÛ4EíšÝ.æ¡,WìØ{o`EQ0S3KCüäÇ?™.f÷Ÿ<™Ï†."hß79g †1ÙXVee–ØüCM¢¤@ˆ&:j0'@f‚©‰uUgÉ>x‚¡x_í¶·ŽÂ¾Ý^__÷m»ÌËP ¡rï<û`s»QL«£')ÉÅëWï}øAê/>ûÕùãóÅâ¨ïzÕLXÁÿ/—⨯15¦(U™))˜æ<‚@òxôB`¦ˆ#Ò‚MÀD̾"ËzG €hF,’ÍïXÚ DYõ+”)(¨€)2 Âê ~òà©f{k#;Ú¬9\ÎSL·ë½AöTµm qH#©Þ‘S°Š«,戳¤ŠH²ÜÜÜ$QÇ\z—EMÅÐÀ%‘ÀÐÚ>‚A©\afhJ_”EYã §¾¸“r8ïU…Ô™æœþò“O__ßÜl÷mÛ>Ž›¦yüðA=™8Þ|ùj³»žN&'§÷.߬¿ûÃ?e4 evjE@ÅÕt×õ)F-K4bF’Ñ_Åhªø“}ïää^ÎùâòÂsj¯ÚaèÙÁb±|/Ûýn¿m}åÉTAËÕ‡¾GLÿúÏ¾ß -1"è¨FÅî ̬fH@ЍD` #kÌÈÌ{vtèOê*§LleQøÚyÇ«Åüúöª,KS‰]×!Rív»˜âjº’”È1HηëõŠçyHFä˜8øàC "D23&Rµ$©k»?ÿî÷´xÿƒoTå,ÆÁ1™æ¶œwqèM-„ÐïöÞ¹19–‰œ÷¦#ïT‘˜ÙR2¤ñNÒPG=88ö蜯Šbyø8„¢Ù靈YßÇÕô°¬êýv;_íw»vלœŸ‰Øúövy°bôH®Z,bׄbö›ÞËÿ£§£b¦ãï‘Õ9ÎjpPÌyü°dÈ@³˜3A41`â”3˜!aÎcûLu¬§¨Š©!;AfPáÃ#­Æ 2!¡"~óÃ÷yð j(¢hVTAaözóÖš…YŸrÊùè`¹ÛíBé@m¤¡’ó„Îyñ"úæíõ®ë$eD‘˜ÕeÕ‚YL¡Ë±,<:¢¬ª`uURÎÑ…ÀΉ*£W —ÔT“øœ’RJ"ÙÊÊ;æådb&ÇËår>Ý5ÝÍímìWøù|‡ô'ÿî?øÙOcJŽ‘›FlVû"UÐ>ǹ¡c"$`‹I€Fƒ•Bö|vÿžsua:›…¢|óòËùbõòóÛÛë¢ô󃃾‘þöö6õCÎi2›|ðÁ³¶ïÿè?Š’²!3¦ñÿ>eñÞ«Œï”JåÊ £úZŒÐ²šœŸ>¾wVVeì£c.C5Öu1Ù·]ዘ$æTZuuñöüÑã®i›í†ÀØyPõÎǘbLûvp4ÏYÊÒ‡Š|(‚ˆDH@ˆ’³HÊÙâÅ«×CÛ=yö|±X™RÚ6·fv}yá¸`¢8 UUËxJ€*ªfCß,rÍ2nwU2;OÄ)%BÔ1sOèœC=c€e]¹P,ªZE.ß¾>½Ïqùå§Ÿ%mNægÝ~è?|Þ1çÁ…™¯ç6´X†ÿŠƒFL’eºŒ :r_ˆÔLPÁ€Œ˜P€À‰ÐÌFi. š!™e1¸#• ‚"¢ÙX¢135B Û£u¬.܇ϟ§ÇÊRÎ%‡¢ Gž={œ„) ^Ün—³ T¯·»ó{G9%@äœ÷wiTǮ뺔¥é{"HHÞ“ & Dƒ¤â€cŒÓºBÄÂÓª$vHèC $&—Sƒê|e¦ÁWÊâ}¯@Ç O³oƮݮéTõõÛ›¶uU?|ø WùêúºžäfÛ¿zûâù“3›MJ"7ô}U×’õòæ&¸ šÚ>6mÎ#€Ž5QtÁàg¿úäþÃwÏÎSìSŒ‡G‡“ùòàx æón½A‚Åò ôÓ¶Ûnn×HöÁûOû˜þôÏ6ÄAUMa vŽxD?Â5.G#ƒ¤*YÉQΊ„«EýèÞ©š!àt6Õ,“Zªª ®hû¶KC3tó<ícpt”úÔ÷1çÔ´íd2¶9Á!ŠdBŠ)Oê2e9B`æ;ûú(MÐQ4„P˜À÷ÿøÏÜ{÷ù×ëét¬¯n·„\O§tÉi DÄDrFU#C¨ˆˆL¤ä*˜ŠcDç ©wIHDÎ…¢ ô!øº®Ù¹4ä®ß›À¾Ýæóó§ûíÎÄ&‹) UuÝîw **0–ÿfs³AOf¿Ù:çƒóŽc’$w•" SGœEÇF؃$3aÊ Yî¤×£ºóŽ)y÷öÊh•Ç‘IA€f€ †jàÀqÜ̾óød>Y¥a`æ¾L$gMÂŽV}ÖëÝl‚ó›]K²XÓ´ã'HQ!±÷@¸Ûì®Ö7»nÈ*ãò=¦Ã‰Ør…'¥$yRC°ÚùœJ@€œsŒ©ÙïœsÄì—;ûb’,LÌnDÛ‡Õáòp½¼X¯ÛáŠY—‹ÅrŠoß\J>yüÙÏßü»Ÿ|?‰$W"öCJï °í‡º 1‹÷}|~Ï»`ÄÀŽ4KN‰cL„´Û4/ð_ÿúïšV1ÆëË«x}µY_?}ö¼¾¹].¾Ü¾ÚV‡ª¨&“P”“ýìêâíGï?A‚?þ៩šò<¦£p<>5PËQd•‰ Ô¥ÿ­çï¬fóÅlÆÎçœÑYYÇŽ½»ÝîU¤*‹Ùl:M p¿ß¦,ÓYýxuT–ónsÅÄ1ÃÐWU`r":_.ê±íî;Î1ÑXrWIã´› õj÷Ý_üø‹ƒå½óÇE9íº®¬j¨ªiL]`"D„ñ‚ ƼkÎfªH4"¯DTTÔ´pAD€óqHeQbÕnóúÙ_¿½¸yñÙϽûn(Ëõͦœ¹¢˜4»Ûéꨚ̆ݮ*JpÅX̼[úTsjÊÉùoü8ZVE]Wû¾U2²0ˆ"©*Ú] ÞÆ/,õUQÉjD@ã‚–Õ#ŽÍ&5pj8F½ îæy¤þ€1š€óøío|4´í~ßlÖë~`ˆ‰™â}(Dr×uÙÒÉÁa³k÷M{v¼’”PÕaH9ºäd\t;xñzˆqˆ½'”1?2n­Ðª2ˆh 0v(¢žII=±göžC}? ‚Š„"øz⼇ñ'˜)£"Ñ^-ㆮ}ùê‚ m†¸}ùv:©GGOºÝ°Ý]?=?ÉÙDÔµ¯Ë¢ëc]çÝíf7:C‰°‹éåÛ˃ùBUû(ÃЧ¬9'b4°2#¿ûèñ³®b7¼øüˆÖíwÛÍúàhU„POëvã0¬o®}QTuuïÁƒÉ|ŽÈ’ó÷~ö±¤h…LDÔUFI¡iVC7íï>:;9Xx_6û­š:çW‹¦Ûnn÷7ëõ7>x¾ßï˪rì ÀWÕ¼‹ÕcX_Þ|ùù§»í¶ëã~¿e¼_.—Äì—UYÔv^S¾¾¾¸¾¾¸¾ºiûý|6wÎ×u9 ƒ8Ç};\¾~½»Ýœ?~TWÓÙ|Î.E¹o×Î;T•±ÉáœuâÎ…Ñc)Y˜ÈT )åÈÄÎù±𣠙š!‘äÄ4qL]Óžž0rŒýÙùƒØ©ÈRW«ªªº¶ËqàPõôÿfíÍ~«K²+¿=Äp¦;’üæœ3«Jªìî¶à– Øÿ¹6zºeuI.•*++3¿™ä%y§3DÄÞÛ‡Ù†F y_ùB^ž8±×Z¿%ý™Àý?ÇÐéX­®,÷èë?/Ô»¹¼|~¹Íã4šÂ˜¦,3%³ØŒ2QD|ô¢#4SžÓ‹Höª7CˆÎq„¢Ý/ˆè™lvÞ0Í'ß™¡hF´\Õl< çíví]ÓÈìNÇå<…ª³ï¿ƒsIcÊm[e(gzT¢ƒ“\Þ½{?¥átœLŠ0;vH #)¨g‡ŒÈŽ›ÊE™HUÚzœ›-²EÄRrãP33’”2³ÜPDR×Û ›ÕüT Z¹Ùí¾ùìÓçÏŸ¯6›ÃýùÃÇ7u3dB³xOYr'"ìɎØÊX’Ø4&…R×èB¸X/‘VÇC²|Ù®DUŠš%©ª:çɬ–Û‡»¾ÏÇþÈTJaïÈ¡0BpÄj#aå#Ã\‡PU"E„#§*ÖfZR6Ghè\ f"ŸòÈž=RUuÛ6uˆý‹«ËÍvûìŧßýóïOçC ÑdŒÎ+Ù¦Ã0õ 0åbb3¤!ôŽEÑû¦®Ý §átº™RðŽÅTІèþîÿü‡'//ÿú¿ûÓ4Õ±=SꙸnÚ¦joÞíÖq…M·uS>Üí¤¤Ë'—ÿÓ¿ý7«nñ¿üû¿¦‰¥ˆˆ9ÇCI3À6›ö_ýêËÅ’É«H)…—¢on?xÏ•„ôp8yz ×7ûï~|s¹YW>˜êœ«lºÅz³]n. ý~÷þËo~ÙŸNÃf8öoûw77»›ëÛëÛ»b¥mMS7íDJݶÏ_¾RÕÓ~_$õçñÛ?þéÇ·oc WO·/Ÿ¿”¢Î»’µÒ4Éñôpÿÿ}žäØŸœãe۲㪫]pÎûyàif €6õfª˜¨‹±L lîç#cb)¹]nˆœn±ØŠØ0œß¿yÝ­š§/>-¹Œã©éÂ4Ž*%Ôµ©¥Ó!n"„ JG€¬iàÀäÛ‰DÑ®VÏ^¼2TGÞ3S):¦d˜æJ=GdY”çTîüvYmHh:ÛÑŒ‘ÔŒüó̼wRÄ™Îþ$³Çrì/6Ñ5Uí–ËEÛ.sIi˜Îáä½'„®kÆq¼¸¸\t#þö»ïE¥mš7o?„ 7¼2µâ fûÃátš¦qª¼wžT UÁ³KjhÊÌ ¨ª•wÌä!032acÝ´¦À‘ˆÁƒgrªÅÔ< ³‰¦”Ò4>]½Ô,¦ZT‰p½XRž½xî(¤éÖ1'Qh…@’­Ž¡©Ãý‘¤È<©¢¤Ã˜6‹6—¹¥ óøÅ§¯ªX甋I)Å‘C˜íÄŠC®Cí¼o8\üØv‹"¥]týiP³”ú'ÝSÇÞÔŽÇC:Ý1;¾zrµxøøþý³ËÊ—ÿåÛ?æT˜çö94Uc&5ûâÅå'OŸyê§ûý>FÿüòB N‡óáx,Zž^­«Ð8O€Ø´Íæâââêjµ¹ê‡éÃë?ˆ& Þ›)Àbuì¾þå7 üÇ?þÓg_|BtγsuS³ ¥ˆ©äiBdïCÝà«OBŒ»Û»ë7÷·wbøÉ«çëõvµhWëu)ÂLR$çt·ÿxýqÜúêùóî…sáqÃó6øØ‡9Ÿ“å<ïœÈd¦!4u}>œ6—[ön8wת:\]=sLLAJ „¶ëúþÔ9ÛvìO2œ¸Û€«TLF®×ÿBÐÅj½¹Øïw§ã r)ç)© šÚŒÇ "ŠDªlD› ü ø&€† ŒH€À`ÀÈj:df//2òcѨ}õéËœÇ*,†þ4œU=œŽ`†@Ç=€ i$¢n¹`öÛÍÊ{6ÀO^>;çë»CÉéb»Zt*И'"$b¹rFê*²•T²y‡4{¢sÈÞbˆ07»óÜÑÍöX8{ÿ!çRH ƒ(1!°‘# ¾xööç¦îînow*RÇ “¬HTU~9•w›E=$ #¤855ïXg¶¨J)8ÿ¤ÎñÌc牡᪫ºrÄY5¹~û¾Ÿ†§/Ÿ™•åfs|8Ÿ‡àC»Xn.¶ZÖçóùa·Ëyl»åÓôæÝݧ¯žÜŸN¯ßœ§ Œ¢€ª—Ûų««kOýÝþáéÕ¨ÏÃÝÃCÓÄË‹ ‚"ôìšEýÙW_wËmNéÝëSšˆAç9SÕ¹8HäÑ‘ßv‹iË숤œ —ì–RJ)Þû¦©ÖëÏçó©kºÓþøpxØöã0ˆYž²‚ÖU}qµyþìÉ›·ï³üè]5Žƒ¨8œƒ0Ç#Uõ±æ`^Þ¡YÎÙWÁ‡ð8š*©íVП±ªL‹Õœ­š.çÜÕŽý¹îÕrÎGJ†Å*æzó/ëiÊi§óùtìûÃþ8Ã0L"ª¦¢ †³#æFA5EDœkD¤ó:3ä9Eh*梟ËCŠ)!ðÜClª„*Ð4¡â˜‹|¼½ùâËÏ=G›ÅIÆûû} >¥2 ÓC±ó¹>œû!VÁ3‡è×n±lÙŸNoßÝ ãp·?)Zô΀ÑħT‚ÇÀžŒsÉ̼ŸGD9 F§«º©bD4ËSbïЬ”Ô­VŽ‹•Mc)Å;šÒ¸¹ÜγÒÙÙ¯ WkñÛÅbu:ž‡þÌÎ!!¡±wurÎ1øXUË$bÒ†³9S3CF)"¦ŽH‡ýâå'*šR"¤¹lMÔŒAA¥0sŸ¦ºª§ÉŠ–aœ^ÿ§è«ýÝ ¶—OÒ8÷‘\·MÓ4Uwoon®¢<¹¼¼ÚÞ:¤ïÞ¾›Ãóv<}ùɳ®nLõînŸËôäbkï>\¯ÖÝ×_}1£>‘À¼ó±®_}öÕ8LÓø1ç‰DŠ”‚ˆ&Zr™Ÿçȳ›²TUbDDï!1a±Çשd£]f –SU€|ݶuÛÅ&ÆX™*÷}ß}ß÷ïß]§<}úòÅf»Ö¬ã4½û ½÷Dä¼'ÄXÕªFÌ!KÓä½£9çd¤iJuW±9iÊ£¢cï±¢À®ïOfºn<KIÎǰXé8¨ì¹^ÀŸü-BIéþúúÍÛ7ï?Þ|¼{8œC.©”òè5³¹ÃåqÒ4  0C44PBbf)‚ö˜b›¯nj`hóâ Eµªø«/¾üðþf¹jWË)"ŽÉ9O€ëõ*%ÙÄ%³oÛÊùjs±Õ¬ï>¾÷Ž pÇnµèšº|¼óxkUôã”SvœEŠÈ” £#FâÙ8^…hh¦)— ÅuÊ“·‚Àu[™¨ NsS4S)f%ÆöÕˆPˆðâj½b×.<{õ‰Í„œ“~@Šh蜫bUê¢PrV›‡]!Âl‹‡¹ÐÊàtò4Ū!¢qÐ@RDz$,‚ó®˜LÓØTÑÔÔtÑ.Žûƒuð‡ßýn{qÙŸNMÛÔumf‡ýCÜa³hŸºç×> ©¿ÀíçŸ=}²Þ>Ï·ûb5 øâÓçWÛíá4¼ùp³]w]³:Ný8¾x~U7­ˆªv\W‘X7Û58Xv›þ|ž«ì‹äR ‚Í…g*%OIE‚H$el­óÞ…HLÄA¤Ø1%°4%$ÇQMgË1;çÁ1ƒ¡s.xŸKQU$˜Ñ»¶)¢?üø¦Xyö4ÔUõêó/šº³~èO‡ãéx¸¹¹Ii2ÓnÑÅШJ¨æ‚Ä€èÈ•R¶O.Ь?f*V ³›Ç5íbš¦Ê‡ªíÆÓÝÈUKucàþ,ºáÿ÷"N§ßÿó?}ûãëûýñp<)E…›d4b4}TÚÐPјÈÌ ©Š™s `h:S´(z&7oý8ç} ìñÆ<ç*Q‹(À篞ÞÝÞ]_?ƒ‹¾ÿ“ó.gús¨âÍî>FN©4u#@ó^‹EìºW ý0Á”òÇ›13Ñ”†à\VQU#Ì¥L9Ñü6unî‰E™[ƒMǜ롧բqÌÄ®HabÇžqÖgT]ðHœmš}ÌÈÎI)¦B¨bŒÑ_,Ö»»kd˜½ ¦â\L™¨ªÂ4:dGXNC_Çxî Q&œµéœd§¢¹BƒªªE BJ ‰QU‹Zå=#µm'š¢÷ý”}p×wMÓ¾}ý§‹Ë'Ëõºi»ÍvkHýétÜ?˜–Õz³Y/^¿}¿¾Ûú×_þwÿô‡Ãù䘞=Û¼¼|:¥|<÷_¼zÊäï÷û¦©>»|Aα4¼¼ºúñÍ›ØTOÇ»ºjUDTȱÕ¬Ù9Æ&VM۟Ʀ혙E-…™À¹4M"efC—RÆi"ž?è¼³}¨ª’Ê\ÀB˜ÆqöÌŽ®Úû¯¿ü|}¹ñOÇóü‘¡iÛ¶[®·Ûç/_2sJi‡ÝÍîúã¾½©ªØtµHim]WulÔ ¨Zœoˆˆfé™|PÕ’Wwq¹öw•ó„ð3xGï?^÷úíõÝý8MPTI1ƒ¨Ø¼ÿÍíH¥ÿ$30“¹yÊh6±ÁŒ©š¨*™ÍÅ€óxÃlN3â/¿þr¿;~õùË®]¬7ë›’Ë4žÍÈ5uûñúcÛ¶»ûû)Uw÷ûÓùœ›“¸HüüÙÓEÓ¼{û‡×¯‰¹G$†sbÜû¹2pÖ‘ˆ™³Jm˜‹tM­†iJèÄ1‹–ª^ŸNÇG.ZÊ(ÞãØuÓšª©™yö¢ë–±ªÖ›m×u·×»÷oþ°Þ®‡Amw}½[®š—O¯Æ×9üÕgŸœÎãÅEût»=œúaL/Ÿ]-º¥zçK.SÊ±Ž›Í†ªzõégZÈ{o†s‘€ª)B1@’’!çCtì(Víãæw´Î7@ÍSR•œ’J©›ÆÔœ÷Îy0d7ëæct!””ÙyL¹Xv£¦k.·/Ë”+B'R¦qNçÝn—ò¨jÞ¹ªjºåâËo¾‘’oowoß¼½¹¾½xryqy¹Þ>9Ý? Â4M"ÂìÁLÕ˜aÎ †¶N'ä‰}¬»U>ƒ¯Ž`=¸á|ÞŸÎÓ”U •ìÐ (Q™+lfâÍÌX´Ý©?Íäc3óÌ¦ŠžYç:BU&›‰†àœS•y3DÑyº HÈ–ÎSÊÃaoŽ\Y,œ“œ'çÂþáà½Ë)Ç*8ç–m³h;-öä镦‚ä‡ÃîîÁ3òÝá”KŽÑ;œ¥ª"Nã ¢10Ï&úÂLR#DpH€Zy_×Á;„†€ÞÇœ2I5%ósStÉyçITÉfB‡‡lι€ˆ¡ªlþ——”šº&`Éy±lµA#&ïC]E0rÁ=Z‘ÿä“•Õ#&W¢öü“a}*“+h87âé¬9â ˜5ÉÔPUJ*LspF2Êœ+5+¥Œãh³-˹ Yœ÷Þcqý¹oºv~JÊSN³ì¬¢!ú’õ§ÝÀ€ k]·Xl./ÏÇ#æ)¥”v7»››öðâÅ‹/¿ùÅj¹]¬7×ï?¼{ý§¢º^]ª˜‰Ù™™ª ò|ZÀØvãé@Ìèœo:SÅŸeŠZ‘`$`ŠFÙÀÌhSg.„ˆç¡×Ù©€`27Ÿ!&63PPUtìL¤H™]êªFóÌXÐH 6uhêæj{õ°?µÝÍmˆ1å"Rއ3;8f`:O9¥œs.§}COžnš¦ÙŒëq^¿ù0 =ª¢w¤hÑl:\â¼Cz4ev4ó͘РCðVK)Þ3›;ªTÔ;@ ‘ìB˜îº®™­‰DŠZJÉâ ÁÏØEÔ`åÇ9ÏŒT4{&ÏnÈç+CÏ4=X¨w^DTmǵˆŠø}ð%åRr¢ª¶M›Ë«x:bôRTJa⪪sÎUˆÃ©¯ªFsvŽÁü÷ßþéÿúÇüê믾øâëªiKImµxw>ê:\¬W·»ÃÕeûÍçŸ"ÐþÐïöwÏ.ŸÔõOþØq²h‹Å²u]»èÖÁÇi*óÓ©¥FvN¥8çMi^uÌN¥";§ªMìLUµ¨êÜ(ÎÈE ;?#¨i)&JH€("Î9)æcçÁ²‘¤”’(3;"ƒÙó­*L€ ˆ!ÖFÄ%'Ddf !–’ÙqºªŠÛ‹í8œ÷ûãï~ûÛâÓgϾøÅ/óh÷~1Õ‚ÄÌH¦j$f„s¥©sU·O‡¸X óà~¦”"Ó˜r™ŠHN9¥ ûóàkÑ»Ã~*YD·›Ãñt¿?,Íñ؇á<Œý8çæWÛœL €¨"S«ªZ4¦iT3D(ŒPUµøàa`S+ ^ ÎÛ— ;^­—z§¿ý/ÿøû?|ûW¿þË”Oªõ¯ýLJþõë×ã4…Šž^<†ÄŒ›åq861¦<3/ó!†¸}zµZ^ÜÝÝPç%'çØÐÔÔ9VÉå’¨¤¬&¢JLš’(;oh¦ ˆÌ÷iJLTLKÉýÐ+˜CdǪ‚u]3Q’)šÈ,t±s¹ÌÎUŽÙ•\€ÐyÎ9u³EfξÏDfQ™ã„¦&Rªº^m6—Ož›ÉöòI¬»õ³ö/~øãï]`ç‚>N®Q¤<ŠýÎ*Åv9q³Aøy>Ž™ŒÓÜš D ImÎ(1ω”Ù†€¨JD@$fΊ 2A›ã7Œh>¸À6s~‰Ͷ*F öìÉ&ø8ò˜ò”sFÄ”'51Í#¡XEDT•õbuîû«‹uUÕ>„‹í¥s¾?÷¯?|èÇ!gY´uôžöG9#"Fæ”Rab¸ò!†óÿ“½„pšdÉ!zb¬ëØ{$öœ§Â„÷‡œ|öùçmÛ!ù¡Ф4¥ãña¹jÙQf2e^­×Á…±»®éOÃbÙyîîò”J.¨šSÉRVmm€1ú:„"¥ˆ‰È”åp:3Ͼ\@D` n>0sÅû (çÑF$$ Î÷S.%@ΓŠ8çÌ Vq»ÝÂÍîþûßÿÝ—_~‚å¼Ú~Ö´À¾{ûÝzÙ ñÓíʱÇÄôxRpÎ×m½\mV›-¨_åœPTŒhfaBÉEEˆÙ`î™dÆBÌè|`JHj³VÀT¥ Ò&R™}H6ÍÁ~CS©ªfVÜ™àcg—‚1ó|'G$D)ó•GUM™÷†Äÿõ§æÍÀ,çÌÞcJDäœCfO¬¿ÿ‡ß~ùËoÂýnj·½¸Rµœ“ó€LÍTçè˜]8íw‹‹îçY„j j¢ÊˆcÎfÖÔQÌT­®PŠ<¦½ÀÀ³33!æÙV²9& L©8DCFú)h„l€È"¢„ ZE_DÄlµì¥€XrVo@–sñÞÏë ÔMcZ®[+V$*3·í¢Ÿ&ˆë®°’¥ª";7 £š2ƒÈ|£Å)•"eÑ.ÈÌy‘¤\.`€sTÌÌÇ`¦ `Ä”sfB˜W‘Z)ITØyb'RÌ Où|>–”¦qLSbfDŒ1Ò<FtìMuö»i™“K^š¥2$"rì˜æ¿"q¨ QUÀ™ …‹8VßõfB ÄXEïC»èö»ýñððìÕËÝõíþ°o»ÅìK™·C2š#êPr~÷ã_üò×ðsí„%—TJ5U#’œý ¢Pä‘‹hÉÐR1Et³’ƒHàMÜÁ1 0ñ#3‘}ˆ’rUÅašãTˆµ 5"´è:BP))—h‧aðU‡É{? )„¦cž®Âö|ìócɹÓaH9ÅàÙQô^mŽ1¢w89Ö¢E´ŽAED >†~ѵ"êÙ™ªª±› ܼŸÆÁ¯¦äKIí¢at³6µ{x€¾ÿñøph—«ºªB¬èxÚ/§ÕÇwoKɪšSN%U!ã*?œ§BÎELïö§s_¤„ýi¿?¡̤ͥ SË¥0Sô®ú¦érÉÌ<¿é°”BìÆqD <¥Ýþ¾ ‡aLÇ0Jizd«¤ìK)ä‰|pËå"†p8öÇÞßT!Œ)ÿâË—O¶LTDq±ì¦×ïCů^>ûWÿýß\^=WÅqšÌ”˜K‘”SߟOûý4:8ŸNRòì;53fž¡Ñfê|0ÍEDÜÜ%G.T•÷ó¤÷w·c6³"%ãýÝ]±¼hÞ;@"Rfò!¤T‚(¦%'-¦Dó™9Æz>y’s9OÞU¥¢±£9aÈL`Ó|ÆžS­>D0ó! ÃùÙó§‹õÓßÿö·ˆúÉçŸ}ÿíîoë¦û1TL‰('dN¹¼ùÓ·Ï¿úÜW«Ÿmšj)™ÆRpÎ(’ùFÞD•¢ˆÊlK'¢À¬ E ÍÇô„ƳŸ À9"@ç½êb—K1•ÈdèÔ²#'¦ÒÔ™²s¹dU›Æ¡ª"VX‰¦ilÛv‡Õz™§Ò5•ª‡~³YI.ýé¼»Û9‡^yѶ tè3-íÛ몌ÓÔÖ¨9ǘ«àæ¢v @¦f8NiÑÖª ˆ¸{d ®"dçX’¤Q¾ûá‡g/»O^½Ü\\!1¨‰™ˆ‚¡Iyòü“†sNLÉ{(f(Çý)Ö±daGUU×÷ûX ÞÅè‡a0&§ ã˜ß¼û8™««Øu{3`tSœD‚¯ëvÝR’œ†}ŒÍþþn.÷;œŽÃ8JQ@hš:xOĄ༫bt®wF×»ûº Ï./‡”“~±èªªù×±ùoþú¯^½úÅÌh:>üþO¡â"%„j{‘’Òä£wÎ1{‘U³ã€L¢ÖO¥¤óá4¦1MÓþp 5›`Êc8ŽÇ)ÖÕj½†!§$m sHS9îŠ"˜Ú\—gsò†HÁæHÄ\윛E[PQƒ9¡/fJLH 0—ÁLC™÷ rÎ{)Å9bÛ.:tÎýðýï_¼úäÙË—7ß·‹»‹ígD¦¢ª)—7ßûì‹ÏêÅ%ü|'¦sÂÚgµY5vJF0"És¨"xÏŒä/"HP‘73yË©B ^MƒjûròÌ?54A"x3a$fvTÔLs¶þ|Fe0CSQ5aâãt^,– @ˆ„œséûqì§aœÖ‹¶­›)åM·<ôg3»\.®wûè«ó8yG¹Ð¢õU E¬B.YÚ¦BĶi«*¤$H˜Rñ.xïUÄqíCTЪªlN÷ùðþ¶OÃéÈÃ8®D›ª&ö1Fûób½=Ÿý0 ιÙÚ—EÎÃi·ÛUUèû1—äÝùp<µm €SÎRdH“9v*f ÄØ]l–öäê ‘ªºª›68H*Eͦa$)’BŒUçyĢ는œòÃáøPŽótާýùœ&é‡á¿ýõ×Lž[ÖÍbÕ]^=‹±úõv«b÷7×*Ò,çÃùÓÏ?1Ã'Ïž:û‡¶ëÆ~t‘U §iÑ-JV`˜‡¥æÙ©Ì½À‰{÷ã›íÅ“¦^†‡}UÕM»dÇ)çžg޲ XJAt>€!Ùæ>›[ÄÔˆpÆÀç”T´”2ûH«àÙ9S ¤+âpÞb./Ÿß¼ÿÐ,Ú˧Ï÷‡›®]ªf3ÎY~øã^}ýyô]¿ß5›—?Û"„¬†ÀE JôÎU~ÊK’‚ƒC5ô0T‹!›!(Xô¬Î¹yL:–ôˆi˜¿;f3U€’²÷,f3v¶·q*¢¥”Ãé!V1çܵÝ4¥ªªœ âØ ç¡n¢ª¨áÍíîæþ~Ñ6¦$u‹v8ÄlPúiò‘ÊX¼c°Ç!P?LΑ÷L‹*Ïb±hãyèMTZß„X…Á Ô†¾ŸÎ@x}sîòËóiøáû?6MÛu‹«RÊýÃ]Ó¶·× éáð0ç2Ì€™«ºZ­1VÞ1i«6•)?MÉl¾è#‘àÜ0å4N"b«®aws±¹ð>€!”’ǾÇaJ“ä,ªûý¡[´t8عqÌÌ3w#ŸúÞ17u\tM)Å9.Eîösm­ó´\µW—UU7mûüÕ«g/?#@¢ÙήªRßýé¸ß÷}_WÕ0ô4¦Óñ8ŒÃi¨ê¨j)M¢’SV-3JÔÒ8Í¢N!ÄsÉÌ¡®T¥ßŸÇ½JqÞoŸ^¡YIÅÔLJëÛ[${þüEÝT‹åZURÖþ|:"S.ªZêºqÎ9çMeæøà5k62b'S™Óª*’KFDU0U™I6`| $EuÞ!˜÷V7uU¿¼¿½ýðö‡Ï¾þåîãµ\än±.¥¼þî»ÏB´_ IDAT'¯žÔqõ»ÿü~ùoÿ‡Ÿu'D˪`‚Ëbž|ÊÙ1«Ø<ñ7œó€ÄDLdjŒFæˆæå\Ô @, L$jšÕ9DvMUÇA~r¡¥”f{O%sôfp:œ‘4-×ëÓéªØ÷} žÙ Ó´Ù®rÊûûÃÃéXWqÑV!Dµ¶‹bvsw—‹ãÄDžœ#JEÆ!5M45ï)g ÌÁzvE¤kfOsO0¢„ºRÑ4MÁÇ,bئ4m/6—ObU1LÓ0Žýz{Áž»Åúa·+9Í÷UC°qœœsÌ„jjÚĪª+BŠ‘ Ø#:¢b:§™@ ïÇÓY‹ÞÝß5uÝ6¯jˆ1úàw1TínWÕ(øà¼)e@%ä»Ý}ÝT)åÝý!åœr6Óàý©ïs‘Cùëo>oê¶ë¯¾øüó_þæáúö|~X®7ó"5vÜv÷'Çè\ • ®i:&î–Ãi¹^§1—2ùçtb)EDò4¥iš¦QTr*Çý¡?Ÿo?~hÚ…sþâòÂÓ8ý¹”RrB¢ÕjÝu‹Ãépý᣾nš«ª©ë¦ œd9Žûýa¿÷‘·›mÓµsbÆPµdEdçç¹Àœ¥#çæŠÛ™§¦DäBp!˜2Îfèic]ãèçbËõæúÝÛ÷o¾õé×·?¤”?¾ýpñl³è.ÿþoÿÝç¿ú2VëŸs0ãÅÅr·ë§”9çÈ fú 2¡wŽˆÔÄ;ŸR2Ô“M)ëœBGhH jfÆg–ŠîO'5 Ÿ,ûjBèÇ“”Rrç<˜S>¥¾ÉµH)9“ÖûÝÍÝz³†J.ªðþææ<ŽëU7sÉ<3M)Í-‹ž18_Tfþb®_fÞóìuB2&BÔº®˜œárÅ*VçÓy±X˜Á|V|Øß{Ûõútw»ÛårYÕ5€†ª®›º?¦|ã8HIª6cJéînZTA¤XÊ#Î}?9¹è˜óŒ¾fÂÙsªØÕÕÅfÍ.·W>†årUU5³#æœóÔb2ôÃ4Ž)'Éòpxð>œûÁ1ÄX‡ÁGÇŒÛe)*"Et8æ¢÷‡SѲ誯¾øòâêé§_|µ\®¹^˜ÞßïvýùÜ´U>Ÿ÷!0zùâ1¹¸¼ò¾>îfý]Ô¤¤”Òþî~GçYD‰~‚ƪBÄ«4Më‹‹Šªa<_>}á]†át8NÇœ“H‰±NÓx>çƒ÷Þy¾ºzÒ÷§qïvw>pSwûÃaµ^"² þòb»Y¯ ðt:¾÷¾®ë¦i˜ý0ÃñXJ~¸»#t.xÇsÛœ+¥cˉëÏ=¢!9Gˆ`¨=nCŒ)Ȭ¢9§Õf½»Û»¶[þÝüÛËÛåò›¿ÿÛÿðä“«‹'¯þ\€Åÿ_EUm–‚x_w­-³ À˜9¸Y‰~$IÍ_®ˆerÎÎóþØad7dž=<ˆˆF3¡È1Ízx äÌÖS"Çît:ƒã)彿)ßÞÝ/º*¥ÌÏ義+-‚ŒÄîüpl»ZÕ¾ûámQ©«*:·\.›º½ÛÝdï}–2æ„Þ™ ðŽs&²€è±xTÅPT g¼§X³hrÎj¶X,EÅ1RÊiÿpÈ){æÅ"į¯oîæ23¾ßïšÅòãÛ·MÛO'•ÂDÌ.V±YtuS3ó8ŽÄ0œG5UÕÃñXWAT§!("ª‰9åTnv`pu¹þxýq¹Z:ç0O©äÉÔú¾7Тš¶U­ŠæàCÉ9T¡¤RDÇSÊ%—ÒT1V1z÷m™ª¿úÍ7ñWÿº®Û¦kªõ•)ÆŠ¿øú›kó”JzJνó~wwë<ÏÌò¾?¶íâ|>‹dbÎy~ХȤƒˆ bÎYDLõ|>¥œúÓy}±Öz9Óîú#!‰jÝÔÛ«+3HãÀÌ%gê–­)¾{ÿ¶diíf»mÛ2TU= CÉr<>äœbðuÓ´Ýâi÷ŒÅØçÓ8ªj¦j‚LH†ñ”&5«ëºi;4 šãæ½dušÐx>ç21»<¥¹,M£¨lÖÛ?þÓÔôâɶŽÝ?ÿöÚMýòåÈ~Ö[=¹úâ“çËûŸ®È4‚fÔ˜©™ó®¤’rÑ>%,R@À3J±”3ãì,U@rˆ¢†Œ&™Ù•’A²¨Q ‚yeÇÊÇúSzýöGøxs»Y/gvàÙŽçÅ¢Çãf³Ä®­µ¨€€ÁqÞŸ÷¸\ÔÏ_<],–ž"œÏû÷R)ã”SJ}˜R >€‰gÎRÈ4åb3Ë9C)EAKÑqé1È'€¨ªÞùlºêº"²Òöîpš¦ôìéS8ŸÎÄÔÔ/:Pí–«™yÜïcsVï<#úº*¥tm­%—Sßßßàp<íÏç1¥«‹î¯ÿæoªz™Ë‹G_}üãïûã!ÖsžˆÓ8Š–ºm‡ó©iï}·X2û.wUÝù‡ûnµ@EçÎ1Æ#ͬyfV…iì‰Ü¢?â͇ËõÆ» ê¶iÛªHNÓáa>f°ÝÃÃ1å¡i»¶kšfqsûÁD‘Ýjµ4ƒ¦m«åz³Í)ÝßÝínïûýr¹¬»…cc UÜï-Ä€èª]Õ-V` *ã8öÇãþáÁ{çCôÎ33"y?ãØ îbãrÎf"9±;ŸÏ?|øÓf³®»æÕ'_þö?ÿ½ºñ›ßüψ„>þÌ‹ps¹ýͯ³»ý8›š ÌDDE ¡L9åœÒ”ÔOý8e™ûyÓ”w˜9oðXº;­Ž]™#Á1 ¡ÇÊ;ïÙß„ØÔ±nâvµÙ?ì»E{ÿpšò¸ŽÝ0f…"¹d;ö‡n±Øßï«LáýíÍé4nVMcš&mÃ,a×.Þ^$Éäƒw.çÒT!—²l›ašŠ”è¼" ‘¡¹Æ)”|dæ™A:MÓaz8oï¡?ç·oßT1vÝ*T{§"ãÔÇÒôýyèÏiœRšŽ‡£‰db7ô½ó¾d+ÿw{gÒ+]–åÕíætq»¯Ë®\i—Óa$`‚e$˜1@BBbÀßµ°%°,d\δËYU_}Ým#ât»] ÎMKŒQz‚¼À‘BqÖÙkïõ¾Ï+$¹ä˜3(ÌË’sEb„eZVU…ë‹]ëLɺÆõòpÑ÷CÛ P«.ói]çâãã0ÅTBX`žVfPÅqYýÙ }Ó·]Û6]ë7£Ð†ñÿæŸý΋›/>½{ÿÅ×_‡9N·¿ºzqs¸<¤JÊt ?JsšN§q<"!)Àº®9‡’êùxLq-EÃ:3KN©BÝ4η1Īª®aeb… €"Ò´­µ.†8縮€àœk^¼`që<Ùót ór<¼óW——»ÝÅùtš§i:OOÓtf6ÖH×÷—W—ÛIOµœŽçœSJqž§Ãå¥|zxÜø¥ˆØõ]; ýnÿðpÿá7ïWcl? bLUfD']¸¿}˜§ æqúðá1üä·ú泟|û—ÿëÏþä÷‡ÝîuJ¡äøÍý¿aÓï^¼ùlwyˆ)0ñº.DךB„Χ“jÍ©NÓ2¯1Ÿ¬a³onC­H)&(ªZ•˜˜˜™š¶±"uÀ w­·b¬îßw­ñÞ6/_ýõw߉%óbz}sH1ë¢ä›œŠB5â?~|\cjc]BÜiE y½o?~ú¤š™x-á9aƪÊÄ1E,EÁbcŒ÷Ö7  @-•¬s›”™€XJNOsÁº¬i·§7¯Þ¬kÌùáññQ˜cH•sc‡ÓñXsM)ÕRØpkû¶ëœoæidæq»¾Kšæ3CÎ51Eïl.ÙS«îRÚǧqÁaèÓZÞ¿ÿ¸ß¯»5ˆ¦µ²ö]oDŒ³qIk\áñáH\™M7Mλi\~ýîc©Å9Ë@1eÕzó¢ÿOÿù¿vÍþÅkvݰŒ÷LJû¦Î;#ÆZ‹È[ÂVÓvˆøë¿ûÍýÝu–„µ( I㬵ݰ±Ë<>3Ö…U±)Åœ 1<><<=ÜNÇ'k­u®ëûýÅ`K\×¹”%¥¤P½sÞzë\\㦶í}ÛÉy?ÇOOªõòòj¿?ø¶5ƈq)¬ªð›_¿áÃýáÅ«×ZtžçÓù<§a¿†ÞY;MS§ýábkˆIUÛ®O1ͧã2/wwŸrŽŸùÅÐïO§óÿøÓÿn¼}ñêõÕÍ5Túðî7×/_Ê\„hÌõË×§§»œcIYDjɵ”Z €.Ób\C<Íóy^¦e )óSþí«HRJbÁ”211K댷¶íZïmc uGÄÆ;k­µÆYkk|Ã"Mãç1ìwmÓ´ÇÓ¹k‹ÖúöãݼľsOdzwžõñ4ÝÞÞ/quÞum³„8M‹3'FÊ%µÎÝγ32!–Rc)FÈ{AØRAQȌӴ[*3aιª IÛµ)5PJiZ£U«1&–zóêúóןÿù_ýϬ9UjÚfw¸²ÆØ¦-9Å5Uˆ»ýe34F|L!Ì˺.ÂÖ(ÂH b(ç\¡ZçbHƺMNiŒ B)µ‚³ý»z%‡óx6–†v/Vú~èúÞû‘R  0Í“1².kXÖót>çZgçܼ¬,¼ßõ»]ŸRZBx:ŽÓ²¬)ý‡óo[7uOßûÖm©°†i<«nÔJÄ%—i<“0QyýÙçÆš‹Ëë°Æ˜çý²LPr&¡\R­U¬ab@´ÆÐ¦ ðÞ« %çË«+ïúñütysÍl×y™ÆÓ<Žq]+TfI)ž§\bŒiY×W¯^*êñéšÒj1t}ßõÝÅåeÊ)¬aOçñl­A¤„<ŸïndÏîÑ¡‚õn7ì¼uë²Ü?ù¶mÛvžáÝÛ_­ëêœ÷Ÿ§¥iï‡_þÝ/>Þþæ‹/¿èºÃû·¿þ«¿üùîÐÿìgß4]_²¾{ûý›/¾¤`¦0÷ð#/yΉÌ‘´äº.kÉeYæižæqz:ŸÎãy\žÆ1¦ !äR ¥˜¨ÖŒˆFx×·wCÛì÷»‹ÝÐ:ï¼!B6†·öÐ8ç¬u€è}ƒÈ§Ó£j¹¸¸Œ!Æ”™xÚ—î"km]Sµ6¾9#ÿöÝ"ô)—ROÓ< =°y¼{Ì9Ř·Û X‹V-U«°©U›Æ;k°ñ^D¬q±®kÈÎZcDØ-° ù‹"B)9¦h½ýÝŸ}ý?ÿKØDÃĵ°6§Œ )fßÛb…² ÷ÄI‰…Q…BÈ$  ÖøFÕZrÞâQ+ÔMð•Ês`¸öÞã JMm»¾Óª1PX×%Æ4ž1¦#31b˜”»¾&™a}:N gkŒ±FˆœïÜϾùüÿè?¢˜4Ïý~çû])3[h|_Jb݈ZkΙˆîÞ=||ÿn†”R\bÑdíù|:.ËŒŠªÅX·Ñ¢6`$ÏË\R‚ "¤ðôøp: ˼<ÜÞÕR+èó~x8”’)¬«3>æ  ß}xz|ZÖå‹/¿´«kš6År:×5°ðÅá`ï®zçÜ&9Ü‚ÀkÕÓÓ©ÖâŒ"cLNåáî>§ØõýþòÂ/ííÇ÷ÖÛ¯^[ë†Ãe\CÛ·W79Æ´.ÎË7¿÷û÷·÷ýó?ë;ÿÓ¯Òv}Óv š›f8ïûëgœà\„µÆJ®¹„óñt:>Ä–už¦ùtOãxšÖe]—5Ä’SεdÚò_Yünèv]³ú›ë‹7¯ß´mßõ]×ïœóF„DJΪŠD •˜µ*¢Èí¯ßMÓ¹†yš?|øøúÕu-z:Žß~ÿ˶±ÌBˆÎûVPB¬Öð¾ïŒ1Œ<ç5¦úøtºÜí a ±ÖRTS©" °IšJéÛ&å„,Ä0ÓÖµnY#†˜^ܼʹ¬ËÚõ}JIŒ˜ŸŽ··Ÿ®öûOwƒ Ëó±ÖÂÆ®á±¿ºâÂ¥*‹€Ù&ÂXk­))2¥˜@µj­b0ª sA4¥T©P7írÉÙ{³Û¿Ïã8Í˺v;ç×xPlº–™œóãù,†cÈó:昬1MëKη}ß"Ð8ÍOçqYô,)——¯_nJqlÚÇûûå|çóùŽÉä´vÃ`g¶1†”""¶MK¬û‹ÃîpØí/æqTcÛí÷µBŒ‹u 0“³©«‡œµ–’R©Š¹dç„®|×¢"¥Kʵ*’""a,Ô u2žçÇû{@¸¸Ü÷ý^¡Ã.,KÎåþöÖ9k}c¤ÍR˜rZÂÖU+•ªÌÌ,Þß,!ÎçóÕõõåõÍéø´†Ù7sVŒ9ÌÊ:NÓé<}÷Ý·»Ãð»ß|ÖÅX·Ùÿ‰YÚ®½»ûp¸¸¾zùù_„%çãÃÓÃýíÝÝÇu ã4ÎË:/ëÂñ<­1-1Ö ­jo›Æ÷­?솋ÃþÕË—7/n®®_ú¶õÖ絈Ä,Ì¨Š›u›¡éövBQEdN!þjýEÙ< !]\î%Açé÷¾þRŽç±ilLjÈ?<œCÌÖ5ÖŠ<ǘ‚9'a®bJ"¢!©ª5’K­ªqã\”JˆÎš-¤ñÞ8³ Ó°ëÚ~Ø¥œ/aY½oŒ±ˆhĆÚ¾;\\wÝðwß¿/•Nçy³ m¡ª Z…LŠÙˆªDTsQ(úC¶/ ™•™Hj­ “ Va-E·ƒh.Y¡ ¡BqÆjÛg»®÷MãœßÜIµÖZŠÃÌ›B軥ÊÌ °¥ð)`ë½µ&„t<ŸÇeúð¯kÖRu¹»avíg~-®}Ùu‡uPA‰6ù=–œBˆ!®ÎùM¬Ÿs~f&o–—K)¸á=a B‚ÍÝHD¬1 ÐE(Ò1ƘmT[j1PAÖZX ¬Jk…™Yº¶CjOOãÇ÷¬u¹ä¦iºÝNÄ\”KUØ‚½JÎÎû *½Œ‹ˆ8ç°âÃÝ]ʙڮßöZñþî¾ßõ‡‹K-zw×@Ìq]˜MáOÿøO¦õé§?ùj·»Ø,wë²#%׊ÛpÍùüÈÖÿøE¸žoßþòoÿöÛó8Nkˆ1MósÉ¥äR¶Ñ6/,Îp×úë«Ã~®¯oö»}7ìš¶õMÛt=³ 3o¶$(¥ˆµZJ®µ¨*!2‘Ô’k-ÇûÇ5œ_½ù<¥„„Öøqš–e~óú…VÏ15®)iN ¹”˜ã~èS.kH7ðLw…ó8[#ÎÚe‰T,›ZsE¤ª…™„Ÿ£a‘Ĉ–ªZ÷Ã^Œc† wYAycJ“Ìó<Ïó°CëÌo}ùÙ_üÕ·Ë2ã©mv ÊÆi…R’3§Åø6—ZuK«Ä¢â¬VUã o¤:ß4ë:«ª³A/‘évN¼m˜ÎÛRë¦Q®µâVDbÍ&7Da^7z=Ðã”DËJBRp©A>ÿâåË—_ûéô4\]§”ÑXã6˹iÚ¶–"Öoå×Ñ!Ç€("ß)2mI¾b,3³0³ˆ©¥¦g5¿÷D’ó² ¯k-¸ ¨Ø 3SÖ )%bF’Ò_2­J"HHFLͪP†]oœ!äãééôôôôôèœ÷Îo¯Y­µjM)—œ ¦Pjaqæpq‰Hë²~úð®ßwûÃõÕõÍÝí§~ß¿yó•õ¶ïw!†««ûñí»ªéæò»٣rN,’s©9+*"èî°_âH$?~ïïÿ滿ùåû÷ӼƔsÉD@H‘†Ärã¼1²ßuC×_\^îw{ß4®éÄXP¨)®`½aQ…”¢w¾–¤€u ëºlÂv$ÒRIX7!_Í÷÷ï./®c.%ç®o×5L·Ÿ®®.œkæiž–éåÍuŠi\æi^cN"bÄlÁå¥ÔýЖ¢ÓºˆpÈ™åT(U(‰È9Š[&Ö¦;0bbÎÃЃBΆýŽIŒ°÷ °XÕj¬-¥ÖŰÈîýoÞÖª€è7§˜àÖ[C1lãÓš °»Æ×Z(—’Òs%=«ØY˜™×e%á”2”ì¿®¡ä,FbIF%¦ÈD ¼ àj©Û‰˜A•i»h¦‚ n»ëeëcˆ1%~VYh-E¡ ãþ»?åRÂþõçhQ-lDÑ–œ@ÑX·Q,ÙXd&BUÊ)oªµ”ZRJiS¦å¨Æ@D¢œS-ˆ™•«*‹))ne ¬ VJÉLŠH9¥ ÆkEb(‰˜Œ5@LUµ–  Öùý~¸¸ÚrrŠŠ ¹ ¢°”R‘©Ô:Χã)ÆÅû¦ëúWŸ}¦Hß¿»~qóêõ›»»O÷Ÿ®n®ÌR×ñüöû_t‰1åœçyf^‰hC‰×š‘Ðzdž6àõ\„)¤§ãøx:#âahBÊ­s$,DDôl#êÚf×õ‡‹ËÝnOÌÞ·UQk©Ì9Õ’×ÂÖF‹l#çó8Ï#"ã6PFÄt4TµÞ®OǦiˆø|<_]]Ûñ4NËôÙg¯K)Ç1†´Æ´¦8´Ý8Ï µ´Î§’ Y˜œµ|GSké»fžC…Z«2¡ZKUG`„±Zª!¶Ü6­±Î{ÃÚúA¡vý¡ä¼u8þõ'?ýúþÓßÿÅχÖ}z¬kXJNµºZ #“©Z5gï\X×\ëóNLBC2Vž©,µjADfÉ¥X–\Ë3´FD„7ä Ósì€VM1c‰HU ˆˆ·9å9Ì1Gb®[6AI,ÌD¥f"âZ¡íÿå—¿-ÎJ7€’ñªÀΗ<‹1šâ&¤@P…ZIŒmš6Ä™·zÀgat†ZÀÙÒò˜Œa¦h©µ k­óÂBÆZ1H¢ªb¬–‚„*F¶`P0Æn»ÒxZ–Ñù&— ¥ü+» ¯Õ((䒙떳¹Îáp¸ð¦ÝßÝöC—syz|p}óÙO4—ÓÓñòêêå«×D–ðxw»õ)”o¿û¶ih7ì—yÞ.rÊ ºYºë–i©UKeŸŽhü°†«Ë=Q ©°Ð†0,ªqMÒÆÛfk6÷r­e™—®ëBXK­"†‰–:£ˆAœ”©¥–ZBËx.µ²ˆÖê½Dgᔲk|ÉE„kÄØÓéŒh§ó”5}ùÕWq]O§y^¦T«·–[o7j,5çìœ5†½5Hä‰Ñ-1X+"âL͵ ¡³BLÜX뽄ªØöMNÕ;ÇÌmÛ*¢VµÎ¦”vûAKbDÈ)31³uöõ‹ÃãÓ‰‰Žãä¼'6lX•‘ÙcDš¶«©Š‘U­„ ¨JŠ$U3(2QÛuË´xƒ¨”KñèSŽä|ÅzÄDH› V˜·öýÙ2'‚,‚ bŒs~]VÈ\L5±fF0Ö¥”…ÙˆTP`akÍÍë«îêÛ7„:g¶­ s( Ï xö‘)€°oÛªY¬!f6ÆZWUqÈdXJM,†ÅlM2 RÕšB$" ë¼m)ê¼³FˆHÑ0€`Îi À¨µ:/"ΈQ€m(jŒÔšÙˆlÍ…µ 'É9hU$U$®% “qÎ9ïÛÖ;ìö÷Ÿ>}|ÿöpyÝtíñéþúÅËaw¸º¾v¾E#Þ÷õ~ ±\ÞÜhÅZ‹S4;ï½oØBÄRLã‘h¸¸†„%ýn÷ùgŸ!•Ó²®1eUÝÆÍ¬´%.Ykk®ã8WP³¬ë:7mÇÈÖ»ϼ³‘TkN9§CØ€QµTÐ:2[ç|Ó"@Ó¶ýî@D·ïßíon¶èæýaŸB<>o®n°V aFä¶q˲¾¼¼È¹äR g¸1† µÖ3ñšb©j­)ZA« V+q¥B)ÙŠˆgÍ~¿+¥""£øÎŠåaØ[묵µªX‹ˆÎ7Ì´á0Œó¸a­{÷öý?ÿWðÝ/ÞÑæÍ³F¬q1çk;×´Ö¸Õ3§ª:‡ó4µM7—HjQß¶"â¼GÆÂ0ì—ef‘ZËÅÅÅVg]Ö(ÖgQ‰°ˆXcAØlÛ£±®ñ 3ãÆÅäyÅ­ÀÂ$⌅Œ Zýßÿ}v;ØàŠ€jš–Ù8bùY”¼aôh ÏBDÂí:±m[ßvZµ–ê›®ÕX¬sbÖJlTKR(¥÷HaeÙñãƒk¨(b÷HRK2Æ–\9‹”œ‘©m;À"Ö5]+L@”rt¾‚¶ëÎç“q6ŠGŽ!°PÙ87„Ö9kœ³^Ĉ°sŽˆUõÅëWaM§ããõõ sýj Šþ⻟‹¡¢ ,Ýn÷ôøà{kÁZç}Ón"j°Ö—šÚáâ¥Û«ëÿ_þÛÃÃíx:å\KÍšJAÀœ3ê¶O@J‰Œ‹0¢qòÅOïöíÛu=›òâAµæh¬[¦yYgf®ZµÖé<êv–g"@¼~ùÒû6¬áMÓï..µTÝ]¿<=¯^1›’JŸ–¯~çw?|øðîÃm×ç+&åœJM%âÆ‹†gºlIDAT³ML¹ÖJPç𬺲ƆHȲ„ç¬uÎ&ÖZ¬÷ÛÔ¤ßíúaoÄ0KJAD|×1 £Öª°Î‹lò×ýÕuÓ´_óz÷êÍWûË—¾õÞµóLklÛW¶Û;€-Ë^kb1aY};T¨í!®Q‘š®C$BH1#á4žSJ´]e¥ UID¬oÚf¿ß—R´hÛ·m?¸¦!$c,5í✱)­%¶RkÉ©´C¿L33çŒ19­`Hë›ùÒÚ‘Å‘&  ”ž‹Ívàív;×zçMÛU¡U´Öù¶Õ ªƒïú­D­šÂ¢ª1EBÒ~H1ôý0 »R°ßí†ýA+3âs®`L1ç¢%0`A܇¦m7ÅÓt¼P7ì@ÁZ·‘>T!ð"Â,&çdŒ !ˆ1®™.®¯ 5]?ì XˆJuZŸî>ÿꫯº¯µB³ÛWEÐb‡ÃÒ~?x۸Ʈ.›¦qr¾iû¾ö[Rz-¥í„j|ûQ„[ûùOëÿï¥ÿïÖ›íõ@ø‡?áù½*1°u  µl±?¸$Ä®Òò¡Õ“N'¦ 1“÷À!¶Uk`­shæ9€_ËNì÷Ü^ÛôxRm+w{mÛ]ûÛs¿3ÇfN Ûغ”)5bJmûU€ÕþöÑýoy~!ÁzakƒÝ÷8¶ÿß³íWAÛ3Zûæ± 1dN µb|‰ƒáL 1˜&Ðb€~a;|Ü/ßo+=îÎ}nÙÖ³ÿµc{G»ÚÑv]s7Vïq9ö¯Ïˆ‹]·ïóU‹]…B ÃI! Ä!0—bÚŸäRŠ'ýüÿî~“öÿùSŠ'X)žmÉ‘Téxj€)ÅÓþüæÄ `€‘­ÔëcN ‚%ïèU2¼Öƒà U)ž¿=²ÜE½…>é…¥_5ö©18¤L %ŸXŠg¿ôJ)B½ÏÞãr ìÛR<écb1 '„€„À@üì‚È-xZ)žÒ¾§Nüé‰A ¹ª.O)ÅSÚ÷ÜÊ!lßhs?CšµO©—+×%Ä€Pá °sbÐS׆’†“ÀP=³–9·[{bj%^Xí¸÷si¡B,µÃ‚ wÃI¤1ÏZЧ´$£å¾&öaë0*5Á]Úvç~õÞ/PMSŠ‡Ñ†`8 1! Ä€'sv‚ɉ½Ïöþ-kDK÷QŠ‚XO¹Jñ¬··îWk€ 1(W–f†R<-¥vr¦ 8œ|ÚqçVï—ÂQˆAÀ^ØÚ Ÿ´ ¸V6rB ‚õFî˜ÛŠ6„î™ïb¼a?ý¸ksnB šãÖ¡ù×¥§ÜÎ¥xzž#·.9_¦ŠÞç¸á>úb×m åJ픎¹åØ„Þg '„À®v±£\í:Ä€ò—øl¥xZÏP¦ž'wÓœ °ÒOlJ• JÛ~1ª:ó·kÇ^Z¦'öÐÖÛRWÄÞn»s¿J×û7J½N!ÜÈ-V»á$ª‡Yº¯òÔؾ–جǘš?k9öÜRˆAÀFÞ3Ü=´{Ž])hˆ5[€µô0SǾœ …ÀÖÒÉ]Pä—XûÛ¥àê-Û“+Qäì$ Ô+5ô;çÑZþöº$Õ«*ûvI²§¦ÞgFf8 1! Ä€§qv‚Éôˆ\¦§õDÍÇ Ä Xx•ô^9¨eÛÕû|õ1NB¥š\¹’7g¶]½Ï¿:5ö¡©± ÍpbBŒ¡™@ˆYGKñÜY¦gýr«U¨8{ Ö‰AÐÞl®@à‘ÞðU=å–}þÖ~fë’)Å÷޷ž÷ÌûŒá$€cÔ¡1@ˆÜÍÙI:t.ý,ï[ez®ê÷ž™ÌU§¨•]· 1^½ÛjaPÛö gŸÎëú²–ÀbÄÑÊݶ½ÔYjÛUÁ[{þ£;÷8!ÜÖã<²¶pÿ8û@È!tëãôÄ€Ÿ™S=«ýÕÁ[§'„´õÿ··å†šûÛ…Ó=ˆóþÕÞÃÜÞKb0Yf{ÛÕ¥xjÏ_  \ŒÞ/3sb´§¹í•\Y¦çW½äÔ¼×~éH.s{½n.ÅS:p%ZÆk€W–âQº‡W;†fN bB àg'! Ô‰’ÒoG)Å“;¶3Ç 'Á«T©"UÍb»m¿½´í›Öòü-‹][‚Њ}Bö2xý ƒ\ã­-0Mýœçª^XÏó—ŽmýL¤îSÚ&Ä` p{j/´¶MˆÁ€}æ î- )Ä@Ï,Ìñ¤Âª´MˆÁ€½°Ù‡–½¥­…°¡ 1$ÀJ·åþ]Ûöí}ûFy}X—¶½^»Bذj-·S*US+có¡_ëó·[Ïõ6…—õ8 =··l¿zÚú·îcmÿ '¡ 1@ˆ1€nØ7! ù¶ñ­r;QJñ´îcËÅO”âÙþ2½ô wxRxÕJñô”Û‰RЧusa§Š ¢¥Oª·3J)žÚ>–ö=×Cb 9´zb¸Íúšœ=‹]a°@¿ªGéøz¾ÌôÄ`ÀáæÌ'ÅzZˆÁ  }¶ + ‘KÛ„:ÀôÄ`’F~´ÜN”R<­¥ƒRÛKgb‚…ÕþßÛy°Þr;QJñ´ÜïhÀ 1äŠr5ÑKñœ)3d8 OˆB @ˆ`bª-+(]èõ»Oïþë‰A°ðª-5È­Åš¡Ï‘ýbÈѺz³”â9²ÿB &fÎêµã7'ØÓ]O &ë™8-¢Þû·~x¹&®~®þWìÓö3ë³wooø+!¥1FpZ>›“÷ÄîLY& lˆ]Ù¥ìùƽºÂÁÕÃ18Çð¿½;£§„ï‰mÏè´$hïý.N¦Â¨P ¸Ã{ –>ªr>äƒç}ö^‰ûÀЄ Än®.&&=1!Ðí–Ÿõ.Œµ®m‹©ö•kw½·_Ý®?w¼hw—ùþ¶§\[;óï_´kÃI¾Ö ü®v,³t„_ûFWEuž^™ãñßîk˜¥zhëm¥Û·ßß§ô<½·ôül ŸH/äL]Ü'5€\CHÍ{äæaR·÷4¼ÚüLéþz`ËÐíúç!¦ÌÏ|=¯\CØÞ– ¨3ïiîyZ?Wì}sí®÷ö_´ëÏ]üž•ÜœCÎ3¡õÜÎã•Âø©ïCn{Ïí¿h×MŠ»zâ¹oþÒ7vêß­ ²Ôs3¼¸Gé·“Dêüê£)ÀÆæì$ÂR€é‰è‰ð.ö´<ì¯bIEND®B`‚snd-16.1/pix/j0fm.png0000644000076400007640000020254311147553267012516 0ustar bilbil‰PNG  IHDR,úmzósRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ.'QþÖ IDATxÚì½y”]÷Uçû9ÓjžgU•Jó<—&;¶c'd¤óMÓÀ놆äuC½ú1,º×£y°xÀÍ" M C:& ,cÇŽmY³%k–%Y–Tó šïp¦ßù½?~çÜ{몜đ•äìµÎ:G·Jö½U÷~ôÝûìýÝš”RGqÄñzü#ˆ#Ž8b`ÅGqÄÀŠ#Ž8b`ÅGqÄÀŠ#Ž8âˆGqÄÀŠ#Ž8âˆGqÄëÛîÒ‹CCB \—»W®°8<ÿ`âˆã 3þ€—Ë‘¿{—Âì,wžž‰3gÈOOÓ´q#Âó?{+fõ{ÞÃú|„ƵkÑÍøGG1°îSÛfúòef^{á—_æî•+Ì¿ñK##¡öÔ¹óâ‹ÏC·,:vï¦a`€ÚîîVqÄëÛR¼Bß¶™|õUF^~™Ñ'¸{õ*îâ"îÒ ónX™ ï?{~ú§éØ»#‘ˆß5qÄëmVPžGvlŒÅ¡!¦/^dèȦ/]böµ×|­jṪ½êŽÖ®¥çðaš6n¤mÇ2ÍÍñ»%Ž8b`½½‘g襗;uŠñS§X!79‰(Š J«€T¦µ•ÖmÛhÙ²…¾Ç§¾¿Ÿª¶6R hz|_"Ž8b`½Má;Ó—.ñÆ?þ#ÃG2vêîÂRd˜æQ)3“!ÕØHº¹™þǧmçNÚwí¢¾¿Í0Ð 4-~gÄG ¬·7¼\ŽËO=Å™ßÿ}&Ï!îù ˜É$M6иf ]Ò¶};õýýÔõõÅ *Ž8¾ƒBûN2ð“R"l›±W^aäøqFOœ`襗ð²Y Ó$QSƒ—Ï#<#‘ iãFºéÜ»—žC‡HÔÖ’¬©A·¬ø7G1°¾­´bi|œÿð¼òä“, ‘nl¤qíZÚ÷ì¡cçN¼B¹›7©]µŠ–M›hÙ¼™Duuü[Ž#ŽX÷? 33L_¾ÌȱcTµ¶Ò´q#u½½dš›ÑMgaÍ0HÖÖ>Àõm3ŽßuqÄñ½,B Æ[ „À™›ÃžŸgòÂFÇ·mº kÿ~jº»ã~®8âø&â;®è®é:Æ ª…Û·™¹véK—=vŒ¹›7™»q?Ÿ'ÝØÈÌÅ‹Ì\¹BÿOк};ɺºøŽdq|7+¬%½®‹ð<‡‡yùeÆObäèQœ¹9¼…D¡€Niº\X™övº~˜ÞÇ£óÐ!Ö¬A3ŒøgG1°ÞÞpæçY¸s‡¹7Þ`è…˜:{–©sçÙ,&`„€Šðù€üðZK$hÞ¶žGaõûÞG˶m¤›šÐbµGß])áý/ŸgâÌ&_}•;/¾ÈüäFGñfg1DøCŒ`%ËŽ <ü²ë\—‰óçÉÎÌnm¥~õjÒMMñ;Ž8b`½õ®‹=;KanޱS§~é%ÆNždéΤë‚çaJYU)­P¢âL«¶«¶–æÍ›éÚ¿ŸŽ½{éÚ¿ŸDMM¬®âˆ#N ß:¨†aèÈÆNbæµ×È ¡ QLñŒ2@•CŠŠ´¯\II઻›ºþ~Z¶m£ûðaêûûi\»VÜãˆ#ŽXoTž‡»°À•§žâÔ§>ÅâиnRz Ê£\QI@j˜&˜&µ}}tìÛGóæÍt>LmOÉúú¸‰5Ž8b`}caÏͱ8<ÌâзŸ{މӧ™8}‚J+ƒÔJ€’׉º:ª:;©íí¥ïÝï¦mÇZ¶l¡ª½=~wÅG ¬o<Ül–ñÓ§™8aÏÏ“gqt”[Ï<ÃÏ<ÃôÅ‹È (ªòEÉ$UííÔtw«´nçN:÷¿ÿD–B¿{—ìè(3¯½ÆèÑ£øGŽ0{õ*ø¾z áërpGÓ¨ óÀz~˜¾'ž º³#öüŠ#VXïà:9vŒéK—zñEfoÜ`)ôk_ö}e‡nš4 вi݇ѱgµ==Twvb¦RÀ‹’,3uþ:÷í£}çNRõõ˜©Ô;»OPJ¼|ga¥‘†_x»GŽ0ò$ëm›–B„ïc–)(7RQ!¨"pE.”}ÝÓ¤®¿ŸÎÁAúÞýnzÂ0#™ŒßéqÄ ë~ÄÌk¯qñ³ŸåÂg>Cvl #™¤aÍêW¯¦mÇz¤aíZ@Þ“õõ´lÚôÀ˜ø9 ̽þ:³×¯3üÒKÌ]¹‚<žª…º€Í¨"TM~¬Ü2h•«üë^øw5Ó$ÓÜŒ‘J1rü8…¹9ÌL†Dm-U­­ñ;=ŽX÷# ,ÌÌвy3kÞÿ~:öì¡kÿ~ªZZH54” âRÒ´aÃ;:“'ƒø¶ÍØÉ“Œ:ÅÐ×¾FîömÄÝ»´ÌÍÑÔQ?BʧäèP®®ÜŠÃ|MCè:i’éì¤m÷nÚvï¦uÛ6–ÆÇY¡uÛ6z~˜Tccü.#N ïWB›˜P£-UUÜóŽCvb‚Üä$#G2vâ§OS¸u‹ P´„çè_‡ò¹CBÈ+—[qöß41ëëI¶¶R;0@çà í{÷Ò¼iÕqÃj1°âxó˜½qCËÃ…­Ùáarwî‚êPEe€$ËÛ*ÊÝü2Eå•Á˯øz¢±‘ïÿ~zœÆ ¨îè ÝÒòÎÖäâˆ#Ö¬ô|ŸÅ¡!.þóŒŸ:ÅØÉ“È\ËÓ@5,JÞX•jªFÑŸ…¦A*…^UE¦»›šžf®]C›ôGÙýÓ?M¢ºú­5‡:ãàÍ–:cj¨î]® =Àu1R)µ<6Ž8b`}wDazš‘ãÇ9óä“ ?÷fá” Ï&Ëí+!AŵQ]MUW5«WÓ¹?m»vQ¿z5Kããff¨îè }×.¬·”Kxý·aêoaöh©ÂZ}?zÞ–aêÂFOœÀL&éÜ¿Ÿ¦uëâ†Ó8b`}'†”‚á8Œ;ÆðK/qçÙg±ÇưGG±„ ª¨JHUzb•+ªHEš†–LÒ°i-[·Òuàm»vQÝÙ©n"¤R iø¶‘L¾Å›†¾7þ¦ž+=™è¶bÔ¸•O#ª÷²ty”§NKuõô¼ë]ô=öí»vQÝÑÏ$ÆëAá8ä&'ÉML0|äã'O2úòËØããXepŠR=­R_ÏiTɦ&R--´lÛFçà {÷Ò¼yóÛcâw÷Œ…—ÿÝò'RÞÄ•G5m倬:ä$œ‡ã~M;wÑ}ø0ï?Í›6aŨqÄÀzðbúòe¦/]büäI¦^}•ÅÛ·ÉÞ¾ªÜ«][®gîÕ2u¥id::h\¿žÖ;é>x†jW­"Y_ÿöÜÑ üã'`ä%˜¾¼ü–ceW¬|¬<°® ç—`D$˜mï¤ëÝïfÕ£Òuèu}}ü=Üb Ÿb€&Rñ'&ŽX÷#Íó––ps9f¯]cäèQFObâÔ)D>OÏ£ùþ›Ú ¯´X¢üÐS)̪*2ªÝ`÷nº ¶§+“Q©ÝÛÕvp÷&œ NýÌÝVOª²yË«V¡,5Ì©³Ÿ‡¼„ls.L£ÕÕˆ‡Iô}|ù_ï&KI$ÝHöÐÎ÷s˜qç|ïL|WßÏOO3ûúëÌݸÁíçžcæêUf®^ÅÏf—Ù ›ÜëêPn¬ð˜UUEMOu«WÓ}øpÑiôÛfó2uÎ} ¾ü«Ÿ/Uö+A=<á O`—ÔV>ù%Á‘ #1êûùƒÌ>ÖI‚;Ôã’Ä!‹I\áã<Ê£ßYŒ#Ö·*¥°=q‚Ñ“'¹óüó,ŽbOOã-.ý°,JÞXå*w••ÀÒ44Ó¤uëVZ·mcÕÃÓ¾k™ÖV2ÍÍèß.w)᳿Ÿ…;çŠORú •CªLYI¼ l<8 <ð=.ˆ Ry ¯i\øÏdò›‘{ÛieŠ.‰X)lªÉ2Ém®‘e#ç^§û8âˆS·ó·osîÿ˜Kñ,Þ¾½Ì°O«8ÊkQÑ¡é:Vu5é¶6êúú¨ëïgöõ×ÉݽKëöíôí¬P“JÖÖÒ¸~=-[¶Ð¹?­Û·SÓÕ…›ËQ˜™!Q]M}?‰ûeÕâ9ð©ÿgžƒÛWÔó”JI4[uÌ‚Jû¼ Y:ŒÒŸ½@˾G*h9@v} ?½‹ÅÙ‚ÞhÞ«X \Œ@”µÆ"U䨓 $ .MÉg0mñ§(ŽX÷²Iâårxù<³×¯3zü8ã§O3rì˜z<›Eúþ2HU¾0Í41«ªH54кu+݇Ѷ{7-›6‘¨©ÁL§‹ã.RÊûrk?ð}¼|óîÁßüÖÓOÁÈÍb*êøJ=á‚J'Í !¤AÞk졲ò¥¢„P se™ M]‚ÜùH;zWj¨T­ÊWgéc>8 m¤t¨OÎSg-òlŒ¬À,l$Óõwh‰Ø "ŽXÅôÌk¯1qîwžž™«W™¾|wiéõdßq”‰_"Au{;uýýEHµnÛFÃÀÀ;æø>‹ÃÃÌߺ…{þ,™ógèxþo1<‡@__†ó…‚STŸ <ð$¸zh;£AAWòPpŠ®=–ß04¤íC=˜í#mаª•îH[CÚAAÒ¥>9O­¹HÂs1})Àðvcný Ô¬?MqÄÀºùôÓœüä';u wqñÞž­ª*Ú¶o§iÃæïÜaqt”æé9xÎÁAjW­"ÓÜüŽm˜‘R²pëgÏrû…¨?s’þ™Iô©IZ|—@OS*ÉÑU›•a½Ê?AÂÇÑ–›÷yr9 ¢s²¥…ڜê¥=m`iÕVöžº•î¶N×ñs¦RWõ?²úäûY.~ö³Ì¼öºiRßׇ³¸Hvb‚Úînš7l kpÎýû©]µŠúþþß½òµŒsþþˆëò'´ Ql@µT”wÅ{”T•%`U*¥r¿òC&T÷õQ;0@Ó–-t¿ë]Ô®ZEª+ÃDío²èŸUµ/2l,鑲ljRK˜OPÐñ²~ÎÄ]LÓÀ ¯£ûØ(`>5Ʀç£å%–硬%ð–êÝð1Òïý!7nŒ‡©ãøîV ó7oræþ€×¿òêz{é9|˜ÎÝ»žÇ̵k¤è>tˆª–55”Oyàûx¹öÌ SgÏ2ñüóL<÷­££´ærTQêšÊT‘¿€¼7“‡ž–©2•¢ª·—ÎýûiÙº•ŽÁAjûú0S)̌Ƣü‹Î3ä R ySú¤Í)Ý&m0…(8‹IüœI×qªËÖy ÝЉî˜Â'£åÑl‰–—Ž`<Ñk' ?øÓ_`¡¦Y_Oª:‰e‚©©”3…ÍCü_´’&6Œã;X…™FOžÄ]Z¢yÓ&šÖ¯ Vo}]Hy‹ÃÃÌݸÁÔÙ³Ü=uŠüñãè““tõ!¤*Þ VnÅcå^Yf}=™žjúúè:tˆ¶;© ®¿ÙȾ‚í|œýgø¶I`ëXº‡ø$t—”nc>š+ÁQ0pˆ¼APÐñ—L4OMäu?@w _`>–ïñ̪÷ðFÍj4_ò›Oü"ÃÍ=h¦D7t=ÀÐ…ª‹i¥>®6ò|„ZþkHÆÐŠã;X‘úƒî )ƒ€…Û·=~œÛÏ>Ë•+ˆÑQ2Tµ”ºè£>/…c%õTéë®WUѼu+-;vбw/íûö‘nl$ÝÔt¯º”#H÷gðì3—ž†t5ð ¡»$4ÕK¥GMX¡íLPÐq—È‚º#èçLt/@s%š#1|îèBðóúm†{y¥kc`€¦K C!•ÐÜeòåG:œIüü8{âO^ßù5¬ NRbÏÍQ˜žföúuF^z‰Ñ—_föìY’BPÔJIŠSuåŠ,f¼¯¬ÈÄOK$°ššHµ¶Òº};݇Ó²u+­Û·—<±Vºq î‚{æÿ¸#ø'›Dt`#JQ­°/,pt¼% ÍQÅuYÓ@O2QÝÆ¶u\lßÌ/ÿÀoâ[fRº`jþ=PŠæ£s »øxt‘i«ùï!I:~£Åë[‰ÜÔ3W¯2uá#Gްpã‹×®a ¤*”Ãh‚å6ÈA¨ü€Uþ¸´,ª»ºh üzzˆºþ~j»»I¼•e³KOÃâß7VŽŽo›R(ð¸r¹/VÅ! ‘3ÀÍ ¡æüî‡~–ç·¾›¯n{@z€¡ ,Í[¤ö2HEp*WYÑ÷%qHI›*rìÒ¶qŸŠßpqÄÀz«!ß¶)ÌÎ2rìã'O2ô ØÓÓ‹‹èùþ4Æñ½ ,Øóó¼ñ•¯pô×¹7Ð…@—#„S¥Ãh1]\RXV}=‰úz2ííÌÞº…ð}ª;;iß½›žÃ‡iÛ¹SÍ)&h†ñ­ P_ú|ù'ÁtÔ€ X*)+»BEU¨)é*׆ȱᵫù÷O}7™$0tt Ä=Š©2Õ+÷Æ*¬òû‹õª2U•Ä!¨”аöL Ö¤F.Q“èAïÿ{ÈôÇŸÈ8¾÷RÂüÔw¯^eòÜ9FeüÄ ²ÃÃE¥y‘Š Êµ’ÃhͪUÔ­^Mó¶mt>LýêÕ̾ñùéiêz{iZ¿žÚžž·¯™uò"œÿœ~ò…’’ RÒ‹jV LFa`ÙjPÚÝ\`¶¾†ø·ÿœï{+ã“Àâ8O˜Ö E•¾Nå ëÍTU%°¬À#¸XÂS×¾ HÚ^Á"íг— øCØòØ $kkãMÖq|w*,áºÇÁžŸgäØ1ÆNždèùç)LMáÎÏ# …evÈåz'X!íÓ ôD‚tk+ж};Ý=D]o/VM V&ƒ¦ëx…º®¿}dïÂÿ#Ü: wo//¨û …ú6é…ªÊQ®£f¾”Fjª¼¾žMY<÷³ÿç>|ˆñµ«0¤À”þ2¥õ›B©ò±{¾ÔMácú¾:{áµïcxB]{>š-‘y ¹¤¡g˜ìV.L¼¿ë0ûöѼq#f2¯‹ã;X^.ÇâÈȲÂùäÙ³ä&&ŠÊi%§Qù&‡YUEuWU¬zäZ·o§eËîÏæê¸ü|ñWïi‹—BÇE˜aŠ©*£zAAÌ“PÐJ–3.pë±M¼þÄ6^ùwï@—RU|Né¡‚Ò°Ê•Te1}̤«ºß…§LÕ¯{†+0<¡Î¾•îE€U.Ä`˜ƒ`Fãù;ÛðÖÒÿøãtîßOuGÇßPG ¬{ëQR2yþ<“gÏ2|äÓ/’#7>¾Ì¹øÂ*ÿ~Å¡Y–ê$ß´‰ÎèÚ·Lk+Umm÷oNÑÉÃ'ÿ5Ü< “·—*”V« ôp—¡ªÒ  å•òAÈSÁÊæ;j9û_?ÂØÁuäÛëÐè"Pc:RÁ*KÚ((u¤;dŒü20­,+ðT÷{Ø5¯ÙÝU3‡†§šT#PŽê”7}¥ªLßÇp…z²ážD™m XTÐZš2xv²Ó>ú}”uÇŽrÀ=ŽX÷DàûL_¾ÌÙOš‹Ÿù R¤¯>Ñ+Y Gp*Où4à ÙÐ@²®ŽÖ°I³mÇÚ÷ìÁL¥ÐMóþÕLn]‡…iøêçàÿrÙ"¨¤P òBKdO–R<ܰïô9RyhÙ(PÙ:äRd76óÚŸü¹5Íêõ ‰(¥cI])¤¤æ(`áÒm2f~E%eº«LýŠkâyC'vÄŠÀòBÕå d¶,>VVdXQ²`LCn^X0Yhï¤npþ|€®Ã‡©ééyàgLãø^–”ägf”ÓèÙ³¼öWÅøéÓ¶½üÉW@*Q]Mº¹™¥ñq|Ç¡º»›¦õëiÞ¸‘ÞG¥¾¯†·gãò7v~ï×áÅ¿‡[Õ“Ò¾@YÊøRÙÌøBøù"„”·üN_e›Uä<êh3Ÿ{‹?´‰† 4+W`IUô¶¤GÊ[ t›Œ‘'¥Û÷+RRš- º‚U¾ª¨HKsdQy鎘ŽÔ—îE`i¶,K†+Çd ˆ<$¦Aä`ևц2Uø›7³ê±Çèû¾ï£uçη6 G ¬o›Šò<„çá,,0vú4£Çsçk_S+ºææðóy4)—y´k†aYXÕÕ4mØ@×4oØ@nzš™ë×iݶžÃ‡©éì$QSC¢ºú¾CWxÆâ"|áÂßü9Áõsh´°^Šðž®Dýðnžô°‚p· /Cëã@审!þÍZäÇ6àínEJ­X¬7„ª%Ef} é’1óJU6UfNYÎÒzSªSו/VNW®£vè>ê––î(áR¬ai®,*«"°œ ‹€'Ö稅Ԟú<ؤ:æ%L¢£ƒŽ‡¢ï½ï¥óàAêV¯þæûÚâˆõMÏóy¦¯\áæÓO3ù꫌¿ò ‹CCË”“‘L"GŒM“ts3u«VѺu+û÷Ó¾kMë×cUU!ƒ/—»nV¨³9 doߦöôiæ®_¥éü>਻ŒÐGÆÕ”˨‹RU^™ËhZ"—øUB*jDzë±i&ó›ÛR#ªÚ. C([äôR-*cåIëÒFŒ™'¥)c?Í–ˆ¼Ÿ3yC¹8䔓C¬Èš&RUåG¬âuA–j]õxà„ ^•Ê‚TVS{m_ ¹,•ŠKamÞK&iÙ¾eîûÈ IDAT®C‡øàiݾTcã}YǃïØí7—ãµ/|ÓO>Éä¹s DQA‰­Û¶Ñ¸n…¹9îÜ¡®·—®èܳ‡úÕ«•rª®^vOÓõwVîÒ“çÎ1|ä™S§h»ù:ÚÕË4˜`› T•ú!ˆ 8~É‹Ý%·ÑHå〕.ÂÔXýçëIì©ÇZ[…  \aÊ)ÔAÝÅ“¦ï“2l’ZX«Òò*ÄÆrU}*((%¥$ZN¢ç•* rz1 ”¶¦T Üà£þ?QÑ]sä=ÀÂÀ•ø®ºàà Zš­–¼¤ºaÖá£åÔJ™§²Ü±,ò33\ÿÒ—°q––xßûâºV¬°¾*Dì…ÎÿéŸrëÙg©éì$ÓÒÂä… Xé4Ýйw/í»wã ÌÞ¸AݪU¤››1,K¥ï࿨¾mcÏÏ“gâÌÆeéȼ‰ vÒB`hrÙt,‡M´DÂãÞå•¶Èчt³¶–Dk--iû·‚Äö@©*W'°uDÁPÊ*´”‰B“Jÿ¢Ô/¥ÛªÆä”êI­€% ÊÁA4nk™M €á“Ô|‰æI´ÐÇY󥪓yêŽàú+WÉÌçð£}ˆa-ÎõJ°òõyðBE•§ÔíàT(Éšþ~6ýËIûà Zn;5EÏ¡Cô<ôÉÚÚ¸W+Ö·/„ë²82BvlŒš®.2­­dGGñ‡ºÞ^õ|ÀB8s7or÷êUÆOžäîÅ‹,\ºDÕØÍAÀºPª–ò”Û˼™í±Ï½^íå¾Y$“Ô­^MÝÀ]Òº};Öú¿A|•ß3ñm?«rËÀÖÑ|å¿®{A±Ç*¥ÙÅB»)üRá<:‡À¢Ïfžàhúºøë¶àzÝ: S(WÑD€nh ‰–èf ¼v’ÔUgûüåŸÑ11‚.}ÿÝÏ£å<\?¬×•ËwÁ–¥›ŽN™šò-“¡®¿Ÿ=Ÿø>úQ’õõ8óó$kkÑ-+þôÆÀŠCçáÛ¶ÔéÓÜ~î9æ®\AÌÎb,,Ðåû45¨yDY©r£>w…ëJ×Q]Gš&$Ô¯_OÛŽt:Dç¾}¤[š1kO"’ŸÂ×.!ÇNâå,¼œ¥6Üx’Àѱ¯¸5¥Ù$4ÕK¥y²äyUv§oAÔ!ƒ_ëþOœªÙÇhª‹éL †!Ð ‰a C ›º`ê~V¦á£¥ÔuR+ ;§)ÂfÝ… ¤½<»áód®Œãg=<[(Õ%—/xõuÀ²0jkiÞ´‰ö½{騷–­[©[µ*^jG ¬rHå&'YeòÂFgêÌf¯\ÁtjB8µS²)Ÿ5\ɬϫ8W^ ”Mº­tk+M›7+§ÑÍ›U1¹>t/® ýWpÜc˜] °—RÓʇ=oªŽw!ž¦ú¦¢}ƒakÂ2 *« ­á×ý&“©6LÝÇ4|t#P¶Ç†P×!° C`˜Só1,õç„æ¢'¸"X•C+Cž4Ò¨"GÜÂú»䟞P©r2‰ëy¦Iç¡C¬ÿÈGè}ôQ0Ó±iPÑýA‰Åáa®<õ7Ÿ~šÜè(Ù¡!Èç©:P£‘’Ò(õMVº‹–«¥J;äJ߬ª®.Ú7o¦yófz{ŒºÞ^jº»I54,r ÿü£HqŽ„z ] mQb,©v½ Ú ÌÀGÚÞøh^PJû Ëaõ©M?dzOðbû»°ð¨2rºÀÔ}¥¤ô (ÃE˜ºr5MSW~Y¦î/süۣŴªÈ‘ù?ÚIÿ`’º/×`œÞDávÀôåË8Ù,õkÖPÝÕEË–-oëï7?=M¦¥%þ¤Ç ë;7üB{nŽÉW_åì“O2úÒKÏ“ •A™øU.”(ó«“ZÃ¥¥ÓèÕÕøRRXXP–4µµ¤š›é}äÚwí¢kÿ~jº»1 ˪(? sŸ‚ìÿRJD”®†›Màå-t/PEöp«RY²h9#muÖ 0œîábãV>þOã˜ISWŸ5¯¸HB7ƒå K0MK÷Ô¢ MmÃ)߈“ÔîuhÈ î@Vi¹¢ÂŠàU%s¤ƒÕ®‹>ÔÈÈß 0{Ý¢ûð#¬ýàÉ47Ëjyahˆ ú§Ì½ñí;wÒ}è-›6½cí.qÄÀú¦ çSçÏ3~ò$3/2{îÁìlT7&IÉÕ!DÇ=£þ êŠtššU«¨_·Ž¶={¨íëãîµk,ŒŒÐ¶c­[·Ò°f õ½½ÿô­ñ?†;?U²9õ¹g«ª—·l]Ýéó¥RSžDº¥ÑÍ.¿ùÞ_â«kçìª]jn0pŠŠÊÔÃ4° X´LÍW€ SÌh1,whHR:§´R «ZÏ’Ñód´ö=‡SSÇÀz ç¾pf^{M­åzææoÜÀž&˜ŸÇ’²¨HIÁÊ~X倚†é4µ«WÓ¶s'탃t RÝÑA¢¶MÓpÑtTCÃ?ýȾ—~ò—@,ªÿYeŸCxœÐŠÁ—ÈTA¤ªBX婿K»>ÌŸ>þ¼Ú¿‹´W !ñ©T•©û¥âzTX×LTÿVNA©K>!]:'¥CB„CÒRy_¥4›”TþíUzN).=O¹DZ+P¥å¨Ö³Ê+ ,¾ 9]°éóP· ̺~%… ð}ü|žéÓ§;yûkϱudˆìa ®à"0¥ë554ïÚEïãÓýÐCtìÛ§z·âvˆX滑 75EvlŒÉ ;vŒ±'˜½z]ˆeÈ•Ë$‚2Eµ’ ²Ôu¬úzÒmmÔ¯YC÷áÃÊŸ}ãFªÚÚ¾µÁéì0ý1˜~±¤ªV€TtøžòÆR™%U… —Voã‡ã¯Yª­!¸¤„MÚ/`âUS±V¥‡©ê΢xEÓ=Sú$Ei:)2áeùaz(/¬6 ¡¾¿ZÏb OÕ°Ì áR­g©2r˜ž_ê]DYÌ,©}ð¡ÿM«WTÉÙñq–ÆÆ}ùeœS§àÄ vŽbZá?:¾êýrÂÿô 0Œé:NWÍ{ö0ð¡Ñuèµ}}qÓi\t¿Ÿ”’,3uéã§O3rô(KCC,ݹƒ´m T›Ár?Q£2H•«+¡i$hÙ¸‘Ö;éÚ¿ŸÆ ¨éêRþìoGZqò×aä«0ñbi¡aÔâî­ ¬"«™Ð+ð dè0ªÙ¿ü’ó›w" šüµÜÔPEqC¥âº¡ÖwEð‘·U4 ¡ª JŠÊ ¨"`Y§€%]ÂÅôU!Þò=LáS¥å0YRUy–_甩Ÿç)C?×Ç-•·æC®•ßµ-¯Cò½8?±çûÖªl!Hj MÝ Hé¥Q¥âf ¡^k•Ìdu¬B í­Ž™ÞÓ!ÖÊJ*75¥ž>Íè‰,ܾÍ­[x¹Ü²%•**:©kת´Ý»é:xêÎNª;:ÈMN’¨©!U_¬óKð»?ç¿7‘RYËh®:ÊU•/Cç† <Ë’ª "§Q/ôȰØQÇóó1¦ûвðJ×ÒC÷8Šë¾Ju?(ª¤¨p^TO”@µLmS¾Çpš„YÑ` ’tT㪠[-dè#¢ÎûeVÉÂQõAv ŽÈ«ÜzÆ­€–ªn-‰ßÞ',ð)6Ò¦‚jnÕJ[RZi_bôš®‹;Ÿ@[”TÉnÒŒV³+&D ¬RøŽÃÄ™3ýß`äèQü|žÀó@JÞ¬CF3 ¬êj¬ššÖ¯§÷‘GhÛ±ƒŽ={°ª«1“Éû>É/…ÀÍåHL £ýýgà+ŸCÎŒ!5•jáš.ÝVÀŠ6Ü8¡»£«[ñ®,-œáJ¯h¯ ]›äÆ}³^ß–Æ@,WWR ‹`™¡ž)|4W­ ¬7Q‚O§”òQRUIékX‰@9<(…æ üd8H„ÞX²Â)¼Ü°„[˜p¨¤­Ü¢Ç|Oý=Ï™'JNÌåÎÌNY­JK$H¬6¨ùh ¿¼¡']¥²áëÌXy5˜­Ù¤ÍBqH;‚rt³ XÒñæ-‚ETÎÆpêá¡— qSL‰ïe` Çaax˜»W®0~ú4o<ý4㯼²üI…ª)ÓÜLav¯P ÓÜ\ôgï>|˜æi\·îñg€kÛL]¸€î ™ §húÊ_@à!t*_*XN鎟jWÑm4R ¡Ëhä:Nب½‚ÿb=ù÷õ±ô¿o.BªüÐ}5¢#­˜’Ei îEø¾(6Ž&„[ì«JJ§¬¨9Ôò=t_ û"t0Up‰ ý»LM…=a°D$OÝÑ”ŽJ÷G}ÍóÕµçƒ+´Â,²$Ø* %“IÒÔ­YCí^Ö_X©Îà’h®D: ]-ØHàRe唘¦¼À¸ª¦æ•-Û¶dNCf5ôÅ@Uù½~øðç ?RJ¤q—ü÷°ÏcþÖ-FNœàÖsÏ1uþ<¹‰ ìÙY¥¨4 MÓ0‰bA¼mçNÜ¥%¦.^¤iÃV=ü0kÖjl$YSóŽv)K)ñçç¹þ÷GÃ;¯Sçåðuðtõá’žrÕCƒ'_ªE.JUÙ¡-²”™ùo&tÄ?_ü½ƒ˜õzQUE韤«L÷¤­غZ©ºÕ´T@ŠZ*ÇkÂsÔÉ®{Í“ÈЫ=ˆÖÝ—A©xŽàåÝ ©À?l¿žJù„§àä»%s?ÏW¦~Nh7c—¿~MS¶3É$µ«WÓ²m›j7Ù¿Ÿd÷(Ùæ_#oºä—2ø#àAZ/(ÿ/Ý¥ÚÊ’6 ¥¥®\.ÙÊ€U<¢¢Ù4 ­føÀ/09ãPßßOûž=T·µÅ]òß­ÀŽÃõ/}‰³Ÿþ4ãgά©!YW‡™H°46Fº¹™–M›”Óèà -[¶(ëc)q³Y¬ªªbm¹_(°4:JpëòÂyjå—1</´B!p‚p¥¼Ên† NÝ2å´’Û(UU˜MMh›3$?»‘D£ÄÂ[®¨B ÓÈ{]seq—é«;r¦ïëYÅõ@¥–ôÔ(Mø˜îûȨ ÕQª»”Ö»éË€}-á=&Âþ0á)0Eùž§jpŽP.‡S¹Ã¨H&1I´µÑ´e í{öжkM6nnFÓ4„œy÷C8A7Ÿ °FúIÝA÷2fž´UP~`¸¥ÿA{Ý+ eçò‹,ÈÐîB~þz²mÃ6úœÞG¥eË’‘Pß=ÀŠlŽGG¸.­[·b$“ܽr…LK õ}}Ôõõ=N£¾m3wã£Gœ9Cí¥KèW¯Ò²¸Ý/ÀG¥wžVJË…‹G¹åo¹™Ÿ ÈTŠªþ~jhܾ çñk°QBSŽ”i/øyQ09Q0J‹\Õó´, ¢§ÈaÁ’º§¼¢&Té.WNÅãë<D‡[:ÕTè2ê PŽ,-Üq+ëQ‰U}}Ôô÷Ó²kûöQ70@uG©†´²í8Òy7û1 b·@8ÎR=Hjü(cæÃ×,oy3`9e°*”€åÙj‹>C‹pÎNp·§—ŽC‡è{÷»éyøaª:;ã4ñ»-%”A€p4Óİ,¤jV2ùÀl<‰ çöÜs×®1üì³L}íkxÃÃìÈfIØ6Épyk¥V¹“hå`¥²Ðud&™ µt8@ãÆ´ìÞBº/Áˆùiò©³hB’Ð]ÒV„æ¢ùaxY g1Ö’”—»á©:“îÅ&ÎbÁ\ú¤¤)=$7¤/Á‘üIûOñÅÖ€f8¦T˜IxÏõ/ó±|îKl:¯ •RÁ²‚¹ðÂÂy¸TÃ.KïÊ}]ÀK$R)dUM[·Ò¸e -Û·Ó²c5Ýݘ™Ì›OdŸ‡éD° Ò@ÛD/oaii£€E¨ÊÉh¯)»ì(WX9•êæ}µŠÌšÛ†)w¤ÆX:¹y3}ß÷}t?ü0ƒƒL&ë»8dŸžföÚ5¦ÎŸgê•W˜9~ãÖ-j|ŸnTGuùt¥9Ÿ_¡–*!fC™Þ^jW¯¦ë¡‡hÙº•Ú¾>jW­B·,æƒO2åþ!Â5H†¤L›”©ìí…^ÎÂÏ™¸K‰bYÚZ±¸®ûIᇘ¸Âç÷Ú?Ìj ü¿¿„.ƒ¢£¨iøè–òi7LLjÝ ZRbiÝÙa~âwžÄð}žø¿¼¯6ý„¨+áT^0Òi¬¶6’mm4nÛFû¾}4¬_OÝêÕdÚÚÞšB¹û¼þƒ`Ì{1EàêźUBwÕuå(W¹¡¡½‚ê*ÛFíy°$UóªÌAN¢„9 ³ÀŒ¦¡õôкw/«ß÷>º¦~õêØk>ÖÛZ-GJIaf†±'¸õÌ3L½ú*ÎÈÚä$õ¶M-jF-zÛIîõªôd_ÉYhZUM[¶¨ZÌà ]’jl$ÕÐPìª÷åòÞïPðNáÔš”e“0Ô ®J siü‚I×ñs¦Ražµ,B(¯+)·:øØ†?WòµÚÇÄtÓPŽ ‘õq,ÝRð"$À4Õµ–”Åž¥4j­ý®ç“?ñ$nLâ²ø¹W4D"Aõš5Ô­_OãæÍ´8@}xÓ$ñ.‘˜~Nÿ0ȑ⸓K‚¦TN«ÑÔ³V®œÜ€eWÀ+¼‹é‡»µ°yÕj/¢-TkÔŒ¿Taä4 “¡u÷nzßýnz}”¶;ïÿÒÞXß=€r³YrSSÌ߼ɨɓŒ¼ü2“'NÀâ"™Nµ(—Q­LM•wR—[G«·–-d"A²© «©‰–íÛéyøaš7m¢yëÖ7o½ð¿ŠýN>‰&$Ò×05µCPAq™©ÈØ )µŠËQ6|5 £y²8ß§‚ìx/Ÿîù8_i~±K=©©¶…ÈêØÒ½¢«¨i(xéV€¥{j#Ž¥ÒQ`X¢8wW¹d"…MãóW©ûíchç<ŒšzêÖ­£mÿ~š6m¢qãFjz{¿µ‘§¡#ðŇ!MiG€o›ê惔­NxÓ@«”wÀІÆ/,þG‡P_Óra{…„\ ÎÑÍÃèf¢Zša¶µaÖÖ"‚#™¤ÿ‰'Øøƒ?Hë¶mXUU1]b`½ÅB>ÏÌÕ«Lœ=ËȱcÌ]»Æüõëø³³¤¤$*…¤­4ï«ì¢®LïÊÍüªº»iÜ´‰æ-[Xõ®wQÛ×Gug'馦¯sët–þ?°ÿ77ƒï˜j8Y ô (ZGë⥣ëV¸ªve ÕÉ­û†ðy¡óþº÷øãŸÂ^ÑD/øµÕ•Q²<.^[*=Lè.š%1,Q¼¶ ¯8ƪ,iý¯¾º@ã{éjý ™öö·gxüÚWá¯Ä•ÅÃÀÓ$ðÀ(¨_’VPÇ2`…‡ðJ½nNؤ녠r¥JmEØžáDî7Áò ²|H¡eÇv}âÔöõ1yþþ|ßOv düa°þ‡~ˆ­?öc4®[G¦¥«ºúiÉõ Îs9òSS̽þ:#ÇŽ1üâ‹L9ƒ¿´T´?6*R=É›;Œ.ƒ“e‘jj"ÝÒBË–-ô>ömÛ·ÓºmÛ·îu÷|å08K+7oUÂÊ]^w‘®FàK¼&ëš¹¸f+ÿç/|š™šfÒB©ªŒÈSååŠÛp2ACÅúUQEU€ªR MYÒ$qŠ~QÑ€p5­ëŠ€•FRf5DÖ@/(« «“ ŽP ˜‹€S ~ÚïµlŽÃø™3\øÌg°Ož¤þõ‹ 6JD¤óÊ9› ›r%H_ãÊ}nÀïþÞ/³ÔVC"|ÞÑsUµ©"O촎ܿÿÙ;ïp»®òÌÿÖn§ÝÞ‹®z±Õ,KV±,¹a¡$BB L 3)À$!0’¡÷–Ì„„J ÄÆ$¶±ÁE¶q—e Y’¥kµ[OÛu­ùc­½Ï>W2Ø`'Ñ}žóœƒ„dÝ{Î~÷÷}ëý~¯<4OtßlֿŶÛÛ‹ÓÛKÿ† ŒnÙÂÜáÃÌ:Ä’Ë.ã¼×¼†R_ßã¿Ý ‡¾wýEkk;*ï~ÆÖã‹ Áü–>å¤AA¥O%®ëy“ʵ„¸¶9 Z¨l4uÔN4 ÔIba(¤^bÇI&XN¢ÿNOꉲhhS:ºË£v_sÁëzN´æ€Yˆ—\‘¯àÁ¹Ž#7܈=3CwµJ¯R ¢m&Òé€ë÷t¾»ÀÌx7_ûØ›™^5Js #ËJÔ,0ý\4ÖÂ66 q¥N™A•Ê\ÌHéC”*—ÿü§z{¯†/½ü©–&ï3®xVpó1Ãôí¾„‰K.ab÷n:-:[mý»,¥˜=tˆ»ÿú¯¹ÿK_böÇ?FEÑ«§3JŠT¡@Ç¢EtŒ1¾s'£[¶0¸~==Ë—c z( ±‹Å_Ìâ¾ïêÇ¿üUK¤Ò#xcಧ·)r&’†à 5”ó¹wçV¾ù;¯ÂBfÁ i%UŽâ·”4³ÈxּʉvµÏ–É!4JÚÈ¡Nb}qœ ”ëÖ2¶M-bI@I4±Ã¤]¨–jèåhQÕ­¡0ØÐ°÷ÎÀÑÈ_vKè7Z™GlYÜø‘ßäž×]Þ¶žB ]"S)T€gV’Ò–¶,­0W“‰ØI•bäS*Õa•ž‰p—ýlïû×À‡_qeçyÁJ×}êÐŒa¾ 7«2r͹ _y%KŸõ,6n¤øDÚϳ‚õÔ5Nbò–[¸ïïÿžýßþ6ÑÜ\þøL²’'*!è]¹’ÁóÎcü Ytá…TFF¨˜Êé)ùªÏÀ‡_ßÓ“™XÉDÓD O³„ß:~Ç,Ç)±@˜-´`¸àþþSÀôØp+uÙTiâr)i¶XåÒ×"…žKÙh˜_ŠS±‚–X¥Žx;Ì…QäËŽ4FÙKB¬H“ÒÿOQùÙï•ßb³§¥ß^i%Ò'j÷¥3Iª1‹áà8Ú×EË—RÀþ÷<—ýo}æé0cË'¥ &1…{>…Ñ­lQùtØ5:ÜêxQˆëG8Õ;Þ Î°ú=ë-—QÄ̸ûn¥ë oƒ¹£HGÿ{Æ‚ :­°šD†šÁ\ ›c##ôíÚÅâ+¯dÉ•WÒ±hÑY×ÓA°¢FƒÆÉ“Ì>ü0“7ßÌáïŸc·ßNsj %%Âü3ò"e‹”úûqÊešÓÓH))õ÷Ó¿z5»w3´ic[·Rìí͘ZOÙ××ÂÕŸ…뾤M<‰Æ '²•x“»js£ÝЕø¶®¨VëÄjfI?W}áw8¶v9ÊíkÚœ| TPºtE”¥9Û˜Nƒ¹!ùÙ‘©° vÆŠ%Ng‚eGIVEY¡Ì*­|"ŽêÙ™5kË“!¢©ZBu† +4ü+Õßp°¬yMq¨)˜—­®±–VÊæfT{ÅzŽþX¶ÊÒ¨S˜•´A?Û&C'ùhá-âgó¸´}-ѤӭâÅ:¹Ç‹C=o«SF^ K^KwŸñ-k5ø‡àŽO|‚Õàÿ^ ‰D9àÀŠ TmUÎ2Ç‹âväÖœùžO3®KqåJ–=ïy,¾ürF·n¥ÐÛ{V¸žjÁRR2ýÐCLÞz+“{öpâ®»˜zàš§Ni˾lÏ£kñb†6nÔ1ð›7S?y’¹C‡è]¾œ¾Õ«éY¶Œòàà¿ÍOìÞ[à»_/Èà3[B™S, ™¬†™]§µoAÝÑU€þßqûÿä¹lÇ/\…­4m¡hûÙÉ]^´Ò˜*McH‰£ià¾&7X^ݱC]YY±©²b=ÃJSt²öа´Ü$Ò‰7‘Žå²™å Š@Wlnµ®¾3– Œ£N÷âÅ ¬] Bpê( 1aäýkÖèý»§Á5Ì<ˆz`/Þ½wQyÿŸ!¼¥ÀŽLÔ ¡ÕrT«¸•n£b]qf¯¹©‚è%Ë™ýûç*O»Þã„¢åS°tõTv™`¥b•b¥o‘ÔìL°Ò‹Ùò5ÓÝŽMbŽ++’m•U[¥•傤5ë ÍŸ“VN PÊà}IÐâaÉÀ¤S‡ú׃TœÔéAþGGjüï{Ñ˾² n-%‘ETs3#mš¯˜2¿ÒùUÞ–‘º±ö’Pg"š Eèï5­(žŽAUAÍÃìA¸zN o¯™±u lWŸXœÀܼDË„ê›$¤P™ ŽB`uwS§kéR†/¸€Êè(§öîåð 7 ”bųŸÍÆW¾RyÞYµâ±š£ÁÜQ½NÏòåô­ZÅâ‹/f|ûv:ÇÆ(twÌÍû>åÁAM”|ôêI0õàƒú×åèM7±~ß>z¤X›Õ4†@÷+ÔBÕtÌŽ™qPK³X§U§{C °_<ýÑ­#Ÿ’lf]ÑÑÆLO„”U# SpU„ˆ”&ÖldÓ"©kÁ¾B6­VèL¾…ÕUöœ¾Îe Úq’ *T¤ôÁ@¨4Q4Ô­M¶RnÒ‰ÄU˜¿æ"ý"µxètt0¸~=}Ïô~ã §°@Ôp k^¶–$›V–·èD±¬×ä,æSpœX3Âì@Ÿ4Éri˜Ö9Ÿ>VX5 ýèHàRàVZÖª:úû¡ØfU"«»WpèÍ—`a›çKE8D8„tú:ÏÑøç-[¨ Qìï'ö}NÝ?]K–Ð96ÆðùçÓ¿zõY•ú…·„JÑœžF)•e>ˆ2ŠhÎÌP?vŒS÷ßÏ#×_Ï©n@8À`²UJ¥Hl]êcØì¡ÐÈTK‰lÇ!ç/È´zȳ²T±ˆ·¦È¢«7÷t’(h]Qö:šÊ ² KDаê‘4lâªæ¸+_0UíçÁújD¢ø^í ¾üZ+¿Ýp­pÉ–*…§°\‰* þáªáʈ­?¾…ŽZ +ƒ]‰ ‡=åDÉœHeA±®¤2‘2ñ\Qlˆ£ D*(ðúû) 2¼y3]ÄÐyçQ^ó 'å;(–›8vŒŒ,j³$u›°æ¡|$(_´‡ºª¨••(#Ü$Æ2V¨OH•ÉH¤aøô¦ÜKMÁF°¤ÉF”M›zÎ6LÒ²`¤iÓé…SÛµ„c¯ÚÊô+Îó#ƒäÉYSÿZ/é´,q_D¯¸Ï:/wé(R_/gÛÀ§—­á)©8¦zô('É={8yçÌÜwÑ‘#ŒãÀm»¶mä†té62í\✡rÈvÓ\—®eËèZ½˜ÊóŽÐñ¬>ä˜KèM…" ÷ôDHÅ«ÓáÕ(ØZÀT ˆª.ἇlZÄU‡›f/äÚÆe –ò]ÿ™íâäå2ä1Ͷr­UXžÄv^µçóô5¦øåþ"KÚ—¡Ž“œ8É4åÆüzh¨±‰çÊvôh…l¤?Êe:/¦w͆Î?Ÿ±íÛéY¶ŒîÅ‹qJ%’økÌÌÿQÐÑQà õ™ µé ¬iJ…è™ZšúÓ¬;–ˆX"݇·¸šçÔf‘ •ŒÈfpIØ÷%¡^¦–¦Œ¦¾×Y#X1í¢à%k™úܯà–dfZMŸ³‡ÉyLM¸V éUm·ˆºè²_ˆWþ-„³ì¬"ýg,¥õcÇ8pÍ5¸újNÜy'ቈùy:Â¥@Å<,Ú—¡]4_UÅ€´,ð4õ÷¥š¦­Mt¯‡údS6õ¯5h7ò§+Ùé"Ç+È/>kQ§ÇÒ±b?A°R+ˆÇЄ²jèÙZCQL|ŠŒ#œ+`É_‚}v]ç?`…µ§î½—;>ö1~üÍobÍÏÓôƒ´ˆùjêL°¾ø "ÕÆËo`€òè(½«W³hçN7l`pÃÊCCÄâ½ÔÔûhÆ%üj‘$°‰ê."Ö¬t;N(9Møiù8J)% ›¸æ ‚j>—«ügóYõ_ÛE*ÿð~‚`Àrd cEú‚!ŽSz™¹ƒe\ñ¾¿aìÚûè¾á@K¤¤9ñZÐî&žGahˆòÄýëÖ1~á… mÜHïêÕ?y/SVáÞ.E.ŽgAÕéNŽõ)¨£Ì¼Êd+©,¥‡ —8ÏKLÁ}Ƥ+ýV{+}ý=%þµÐ¼Òe|zFEf»*Òóé­X¿´,3±²Té3 VêksãáëH67Œ°|‰ª ¼(Äö}B9ðJúXýŸÜ1$ õãÇñ§§)ööÒ12Ò–.tV°þ|Eõ:§î»Ã×]Çñ[oe~ï^‚ýû)…!h7uê¤Î/G§B•VÏÄoÏó²$àöôп~=C›6±øÒKé_½šÊÈHÛ¾Š?D¨þˆ04«%‚yBŽŽ2hQvYÐg:üI6šËy«û^n`7§œ”+Z­ß™DËECDSD]‰pÂS8vœQB=ô’t@ÏÊÌ‚pµìyðàaV¼ìKX7O¶¥P‡@ì8T&&èß°‘­[Û¾î¥K) áuv>¾yå¾·Á#ïmQÍZõÙJæ·±Ò‘]2AER·ra»(eQeù6ÐSz` CˆLNb¶æpÙ!¨Á!/$,§¶ƒâØ=«WcýA@áòAT(t¢!E˧äjÁ*⛽F½”ZD¬HêWãëM“%YׯE]i²EhvÁ•†m¯<íÇV?q‚Gn¼‘Go¿É={(tv2¾mËŸùLúÖ¬yê6<Î ÖÏ68¯MNrâ®»8ü/ÿÂä7<ú(…8¦$”•Ê A;Å!éËWL _KÀ*•ðz{) hÒ¨™Åô®\©#©l»Ý'\š{>ÒŠô)›oáW‹™P%¾­Oÿ¬P›1£öTÑSñ÷[kyåàÿå‘ÂD&NÒµN,Ë–ØN¢]ï„x–ò9Êg9&`"…ñ©@¯ó ³ K4) :ZuJ¢I…:Téðç(ÿè0Í·ÜŽ<ÕG×’sÞ²…ÑmÛÞ´‰ŠI¼yBâ¨{Þû? "ÉB%Ò’M‚°î!"…•$)Ib…4³4iÂ"ÈUS,¨°dNÄ’Ð ˜–6’-¢hÞ•VT±ã@g'¢£ƒŽ+¾à6ž‹·õvfÆï "VX‰¤âճѲ«+V71¾µ 5ø·|³&•žLæMhù~³jŽ!çy^ü˜=ï9T''9òƒp䯙¼å¹9Hd’ ‡Ž‰ –\z)‹vïfÉ%—Ð91ýÔpúïJ°dkºçŽÝvÇo¿SwßMóèQÜ8κ "íð¾|5ŸA°s‚e•ËÔgfHáºô¬XAÏÊ•™Hõ,_N÷âÅ Ãô'¡ùyTr Z$M"=<–¡¥«…Df©Ìmyy!|zäµ\Óy%ßè{¶•œ¬²’®…òÂQB¦  »Ê` "Ð'Ö´0á·°Éi´Ôƒà’hâI³(lëEáN»J‡¨ÑÍ]jžÊ}ç²xð}”~¾ÖãŸÿ;ÜýáÖŽ\0 u•¥E"µPE±^uQ ÛÀ :¡ró*i‚\#Cªöd¯…‘…‘ãP£4>NçÊ•ŒîÜIß9çеd •ÑQÂÂg˜ ?È|µ KJl©=`Ū¶¡8M\!B•‡¤kQ"h­HQ°òC²ºž«a–ÅåŒà@ÏVn¿ïÇ=¡OÝÓ[+wN§¯þuëXvÅ,½â Î=W¯¬¬§n`.ÃØ÷™?r„£7ÝÄák¯åÄÝwãŸ8A<;‹ÃlÖœ7çE*Å€«íœ\Q*ѹx1Ã\@ç’%Ì:ÄÔþý oÚÄø¶mŒmÛF±·—Bw÷O6î%MHæáþgCx§þšöFú–^Ëi:X‰4ÆO‰ˆÚ$qäð‰Õ¯çO׿ß)‚­«§¨ä" Ò³PŽÐ4Påk–jfH â+ˆ C§¼vË‘:PÕ°­²4h©OÛJ¢‰Çšeëap—;O§[¥Ëž§“*‰O|5%÷õ`qæÕôŸ4TôáËo‡ÛÞ¯­á"÷¦ä†ƒ*ÒV‘Pê9“Š´ødT˜«LÂ\¥eN2SòÂŒÄT'r@W(•¿ì2†·mcØd%zzp;:ÌûE¦½ŸjͦY-Q°}c°:½*®ˆA+#RÖ-í T¶xžndÿîÇ,i¶¨éͤò«Ã˜32'Z–ù€r]:/fb÷n&vïfÉe—Ñ51ñ ]ó´,%%þì,Õ#G˜Ú·O‡JÜr 'î¾›h~Lj’cvîMËó°g@[^WåÑQºW¬`ü ݶÞÕ«é'¨V©=JÏÒ¥O ªvä[pâaò3ú’‹€–¶Â‹X¡BH¤Ž’2W‘0‚õÃE;¹~âÞ½û($Ê(G \ATv‘®…cÅš2*T’:%i0Åi›' JrƒeÄQÛIpdœUUv¬+Ý,¢) P²š8Q¬1,žF÷x³ô8³šö\½_ƒ¾_}ÃÅ>øf¸þãP†ÄÑoŠ´‡*Öá¾0Þ6©-'ýié;™GÅÆM~†Êia¦jþÀÄéìdõ _ȶßÿ}Î=÷ŒU£š{ÍÚûc°é5]Jn“’£½iâ¶jŠvÁ DK¤ Ÿß d{Êt^°-Û… LrOar‚Ž)í›3c²à–á¿j#Ê\…Žƒ«–³äœ­œ»üWè]±â?Ì"õÓJz÷ç;Üû…/pê¾û¨9B8;‹¥­´{A9,90š¦»ô­YÃðhgñ¦MtŒQl[,-öôPìéybÿàny0Ójmrd‘žùÇ.ÍÔZ4ZmÍ-KvðÚšc]#”ÑÃ÷¤`#] Y°°8.' Jª™Í™Ò¹SAz–,׊ôÌÊ´‡6IvšåHVPA¶KXPV¨wíŠhlLÚºQ„ç…xC6¨G~V‹ŸhÉ¿|;òÇ)h&Tä•òÁ Š'z'Ó&íÆTW˜60wêÊ+’íØ©ðL­ÞoœU*ѳz5£[·2~á…,¹ôRz—/?ó?úøH¦ÿÚ™kÞ‹B*nGÅísÇ&Ùâ¹h¨lßR%~NQÏTa5ÚO8£¨–á-3¾2Ÿ}Ï|ñH…èýWè}Ë—œƒk8a$>ÓáøñkÕÙ ëÉœû³³TåÇÿôOÜö‘бk#›7Ó¿n^GGk@üó~M=_¼XßþdpºçÁ\)i;##sÁ™+Ì©ÃdÏ¿ù'˾Åk°0­¢A©$å½?häå¤A)iR±ê”“EégTMO…›=¯4'ã¸Ë8óY‘líÚ…º²"7Ö¸dÑT™+Ûºœy:¬š&¤ñÇsEh ÃË¿C+ó½<Áü<Íéibî£x·|×M(HˆˆmðšP¨C$àTO‰×®¦YpyçÇ>¤!|9Sú=>Ê¿ýi%±o~¤6ÑÌC¹.Nw7Å¡!Ö¯gÑÎŒmßÎÀš5z©þ±> 2„‡ÞÇÞC,Qàb)™Í®¬XžFŒU¾h[‘ÊR‚–P‰@eN{åë*Jùfî´¨Q¾l-‰×<š@Ð[@~ðbxÁ2œN+[wTœ}fÒ¤î.2.,FÅçbÙYÁúYçÕÉINÞsÇãwÜÁ©{ï¥zø02 ÏH](Pù‡p*££ô­YÃàÆŒmÛFÿÚµô,]ÚÅô¤|ùópý_Á¾¯ÀÔÞ¶ãø¼`IãW‘9ÕŠtª ¾~>Ù1Ìï¾÷#ܼe®Œ¨u„¥²>WíèÎNô„OEÖuKh5(ËÆií`:Ã* ÍÉr-ÓÚv— Vz¼î&š}•¡bšdÔÕ:5:ÑÌ«ŠU§˜ø­«&XÍ…𺿥Ù9ÆÔ¾}œºÿ~Ž|ÿûTx€¡ïg¬cu‚gÈHJ –Jàº\Ê-Ͼï¾ì…g6]æpÇY†l2ö®ïaQûÀ^™0Û*蘘 wÕ*íª¿àÖ®¥{É’ÇÜÇŸÃoÕ‡±EÚXhÁy—l®´S¾h¯ ²rO›ZS[E~½) ZëM24f\c³ÈbùîÑœW.Å~ö8îK—gBeI‰•´p;Ng´Õ‚ è±fcŠŸ÷œ³‚õÓ¾âf“ù£G9zÓMºöZŽßqõG%˜›CAe”¯…mcyng'½«V1?9IýÔ):FF½àíÚÅØÖ­Y€„S.?ù(ŽÚ4ÜðY¸ýïàøf.Ó>¯"1B•èª*6“Pe>àvbéòÉß}7^~ V.×B¢4r8=1p”Þ“ó3ÏTÑ2‚%õP¼"ëY+˜¸g-¡ˆ(XÆ´hEúz²Ã$ù¥³Û\%¢i°1M¡i¡D4hKnA8«´fo_{´é£Çˆgfé¨VÆ”<°ÌŠ€@X(0ßßžô.¦–Ñì¯<¶KüL‚…OY5(‰&ñwŽ2õÇSŒ¿‹‰Ý—3rþùT†‡)öôà ßn‘DpÓ`Ï;46T’•„”­›N~›}¡`ª5[K?ùGÔzNŒH%ak3Ìhžæ³ÿeœ¿ZÕíd"J"Òíg^°RËŠ›D”iÐkÍPéÿ¢ãeOüÀä?‹`É8fîàAn|×»Ø÷ÍoÌΞÖÞå+¨ôËr]:alÛ6íÜIÿÚµ4§¦˜yøaz–.exÓ&Ê¿øŸÐ½×û®µN¶Øß“$ðKÌÝ4Öpa†ë2qùô»ßÄ·^ó¬|OgK¶J²ÄtO® =£" dëa{I5µçG5Z³+ZÕ•'ÂÌÉž-ÝŠ¨%V†È U ûKŸišcõ¦hƒñY®Œ:—,e¢¼’S°· û#=o,¡Wž\ÊÑ'‚°«ƒo|òw¸ç×.jTi} E+uççSpŠÊD©&–¯÷òƽ—S»Ö¥?ÛûüàuðÑË T¾UÂˤ…¸¶ò\œ\[¨ÌÁ@”®,™­€T¨²×Qëu›í8—J+àÒ‚Ýí識ɡ´–þÅ2s8%P¡ iØš,é#[YGÆ”TSoRÈ&ÝÖnÁòïÀð/¬¶Š*˜Þ·£ãÈ‹ IDAT7Ýľ¯C×_OâûmQ\yÁJÛ»Þ+\¿žáóÎcñ¥—Ò96FÇø8^G‡¾ ®¸žŠcÚ¹)øÈïÂ߇©GÚÛ¿Ô•mbÎC ¨O,®yX¾ŽO¿ãù;¹íÅ»¹ùE»[óƒüMKù”ïä¡Í¤K Víó©¨zf;(¡]êY+HkvU %dne(™™ÜÖk˜×ªÙš­äa|ÜÏ Q`Õ4Ý@åÉ<ÌIxXÁaôVAzP"ÍoI¸á‹o`ÿolof˜Ã/K¾ñÛ²ÓÊ*_a”vç{qˆ¬[”’&½Þ …°»üDéÊ'þ~¿ë¹¨ýßÑ™2|+Kcdd¬+dÛç´‘ÐܨÃ¾Š“–ÿ+[O+¬ÜïéŸ[¸EØ==ôžsýëÖ1rùÞ¥ßÄ P’Ø&j¸$ ›¤akîYd¸g²Ua¥‰GV()$U×Ù‘ÍaØñYXöܳ‚5<ô­oqǧ>ʼn;ï$n4HÂ%%–ãPèêÂëè ¨ÕqL¡»›®‰ _|1£[¶0¶m¥l×ý·CÃÞs|ýSpíWQþ $º¸J++k¡ò-#V¢u¢K2×5æƒ~ïKwðÍϼ–¤ädb•±Écí€N«W™VNm?; ,9út°(|*¶>%LE*û™};;h÷R§µðXå—ã-aJi©C¼íµ!¤§Y2Ðé7ʤâXóú¹![âqóŸÈV l‹ãÿsGßrqo)Køqsy‚éëÔ›_N«¬">%Õj …¯ˆçÜPïFŠªB4ˈx)â¼oAeÉO·Òœ<†x÷ë÷|YPXƸÚÚfa7õÍÉ©›×¡¾9…¦Í@}ùÊ*ÉUR9ñ U‹‰–í&–JX]]¸ýýŒ™=ÌáÍ›X·«pˆéø×À­S(„¡Gc¶L\wH|mPuȶ㤖¶‡V I±^êÎ,P/Ë¿›_yãf“¨^× ê¥ÒÓ–pú¤ Vszšû¿ô%nûèGB £ˆêä$…®.ú׬ahÃƶmÓœ÷ýû隘 ÍúV®¤22òoÿ“¸ë6ø×ïÀÇÞ‰iéá°ê;«Š[ã*ßÖÔÄÜUÓÁzbNSFÖ‘nàÆ¿}ªd·„Jiäošh“œ8ÎæUPttö_Qè=µŠ¨S²tKXÚäÈ8ã›§îêŒénNS¡¡:ã±z&X>ÄAŽlåpÇ‘+ƒ>531âÇmUZ„Q 4ÿÛ¦?ö\½?iù©`å§S^} ãÓ¡Qf·HO.˖Τ©“¦EC¯¿¨ª@Ôb^Aa;\þÿ ï±ô›?Œ÷Ö7`í¹Š¨¤ V‰ßÓí¼ÛЕrš†ãM×< Ó¾%-£kúÈ‹X·¢\¦²l•‰ Fwì`dëVº/¦gùòìp@E7ãW_‹Å+êè¶úl…Úl"PÚãí ºf1܉ã Ò¨IV`vSÁšÂ.¸ä÷89r.Î×8µw/I°è¢‹¹àz–-{ZŠÖ“"XÍ©)þÞ÷˜Þ¿Ÿ¾•+)÷÷sâ¾û° FÎ?Ÿ®E‹ô´T"ª×‘IB¡«ëßÔ̦¤D" àM¯CÜsròabG •2;;NS‹•okÊhÊëŽ Ã=NÌ5w÷lŒw²ÿ+/¦¹ªd ¨¤éI“ñïØI [\:0¡hùú¡tUU¶mŸ²Ó bkšCÙià$' ú8=}ÒI6YpÄO¬lï.háÓcv´¨¢Òo»Ëf‹j }ÝÖ4X‹ÒA1¯[‹|÷Åzô:’+¢ì€ {¨(ã]e‹Â&NÌM"Íe7Œž ©XuJªÙ~ŒÖÌ)å¼¹(s`ìðŠ¿BÙ.2ŠH·ßΑk®aì{ÿLÿ?Âõ *‚² t —Ý·^] W*8 ó9Rþ—l Tœd–»Ö,ʲHU*Ñ·nƒ72xþùŒïÜIi`€Bw7N©´àÙÀü{‰¦ßI"m;F…‚æ\‰æ| ›÷8/T†X+²>SµÚü¦æ} ³§(æp€FÒÇçcªÍ&tt0²};]IJg>“þsÏÕ㘧‘p=)‚¥”"ñýÓðO³/EÔ}”¹ƒ)Ü?á׿Æðµ× lHlƒ¹µôíP{BZU5–PEÊàe;Ëâ }T¿ñ<ÔòŽ,ñÅRù›:¢ Ð>¨XàŠ–¯‡¤V“’­ÛÀ²ÓÐÕ”Ýä¦G.¤vâˆ8[gQ±@Eú«#®ñ¬èê3 V6TO7.æ—…Óc÷$Ê!ÃÖÒp÷µÔÏA.`â4/”mãôôà½z€Ê»6##‹Îb5;pE€ë\¤oe;wV¨[e/iѲU¢8¢léùÕ“¦¹Ì9àÈ‹~“½CÛ9|Ã8þƒP>|˜%t»Pq¡k/M³¨}b"„ƒÛÏ¥>ЇH¤HVB÷M°™Ñ9&XèÊópñ††è_¿ž‰K.¡oÍÖ®}|a©“‡#o@YúýU‘²ÕaÃkka'R³öÃËà¹Ù¤0tÕ8{œis4a6‚‡Ñ‘3¶=>ÎØÅ3qñÅ,¾ôRº—,yÚ0åÿãG•bþÈùþ÷™üá ï½—¥0pì•8&± 2b%¥ž[HÃf×hs‚cµÂ#âTÍ샺ª“ÊWwaoìÑB…ÄV I ¤émW*k}<jø› uUå4(YM¾rÿ‹Ùsl+Žó/‡žÁ‰pᨠuœ²®„§è(Öøe÷‘¶Åúú½¼yßZÕU@&b™`åÁ2l VœÃ"G‘!È,A‘¶P¤ ÃÃt­\Iÿ† Ø»¦‰ž?Eœ8Ø*¡«<¯Ã5Œ`‰XéYŒYV¦¿J+¬¶|Ä0ÉL¯NS¶m¨–L°j-áR ý3ú¼û<2§ÿÝ% bAÙ…N é”éF ®}ûËhŒörh÷¹Ô–ôè6ÝÌÏÆ¿Ý')|m⛲!y$¶Meb‚¾õëé_¿žE_L÷’%”‡‡u¸Êãý:ø×pÿꂊ24û¨ =»J·D,3ö~~Ï2Ý­ÌÏ(EC ˜oZzgZ¯ü4c¨ÅzOñ0m TÙ×Gßúõ,¹ür–>ã mÜø“ùfgëg§¨Ñ 95ÅüáÃùþ÷™¼öZ÷ÞKïü<+}WJŠ,@ -Tg"‰æ×;¢3ü~ˆ~‡±¯£ãŠ>ì^§UUÅæCÖÔäÐôDÇŠdôY>EÇG&G‹x÷­ÄCÕUÔ’Bá!\…p–'3Þ•åJ„«4öØI+à [eI§Såßz=ÝÃø‘£¹"Ö@Åq«Zòs^ …”ƒ=U.CGÝkÖÐo.Ò èYµœzéËŠÿ–$Ñ©7žÒÛ9CÉib'‰¦¨Ö]Â9Ä·M Úª«,z,Ö >©3ß õÌËjÊÓ[ÂYè_âë*È2lãF§0Á£è,ÁŠ€²„`Ù _¹îOQAØWÂvT[âvÞ^Q¡N¥6KG}õ¯‡©}fŠ%›_Êð¦Í mÚD×’%úÐÈóžØ HI¸ûãpëè£ec²U¡®°Rœ¶žÔ'fGæígÂî-g}l2!eSïë7¤Î‹¬'­Žºš;@Žm›Ž¥,}í/1ºù|&6og°ãYÁúy¿‚ùy¦x€“÷Ü£ó{öPà:ªUú!]ŒdKÒ ÙWùGÀ™7m"4]4R*ûóNGÝ«'}kÈЋ{³P(ÍÀ j…,Ù&n:z@ËL¨\©³¯›º”Níæ¯ü,[byËÖ¢”>2‘rÁqbÍÂò¤m(X:`‘ÄŽ¯2l>|ÏÞsÿýÿ|(SŸL¤BSAqz^^^¤š¹YLqɼ‘z7l`ø‚ èY½:C°¤ÈX~ŠãÍÿÍÌt/ŽˆRQñêôvÎàãÏ æ Z´æÝ¬EƧ}†¶Ò}R7~Úæº‰^Z¸<œî®¨†¡†*×E:L¢A-3s‹»Šœ|ãÅ<òòT׎`»‰ƒ±˜~|zRY  B²Õ "êôˆY:U•Åò­TìWþœ^ þwIcGRƒ!Yd‚•(=7[Cè›ÊÝUÒ_W9ôNJTm Ÿ›R3ë›ê±s"ÝK†(]9LÏÛÖQ¢Ì*.§Ÿçã2xV°ï°\Æ1áü<'î¾›C×^ËäÍ7S=p€èäIе}JÑiJÿÔ!9=Xb¡´íµe‘Ø6V¹ÌÀùçSæäC1sø0}kÖ0~ávzvÂ]ýc¼¥>Oïí‘@X÷«ú‘º ¥oáb%z¯d5©Æ¼úÀç8ÔXÂTÒm'Z¨ŒøäËvpt…åØq&b®‡f^Ù1qÅÁvDA‘t؈‚ââ[¿Ï¯|ê+ìøÚõ¨ZÐjõhG/®tpœAï† lyó›ß½›b_^gçëIÁ§‰ã·15] >_¡àì€JA$M›Æt9û¹DU7k‘Ó!²¦ÞäòÓ¸2á«¶¨®…Ëé`I_¾Ò-Pªe5©3k¶À/¹úܯ1óâó°Lûn)‰“z™¤n×=©©°%šÚ=®šúŸngŽ.wžn)©ø+qŠîæŸA¬"øûß…›>Žr4×°M°b—ÆÉE­7Må¨äEÊ´úqÒòˆåmuùC-K3ùK%:—-£ë² ¬ßmR\äé51; ÃªSV :‚MŒþ! g뱌¨õcǘ;|˜wÞÉáë¯çØ-·Ð˜œÄ3-^ÐaÌŠyäLB;°o¡@嫭Ķ) R ÃíÞMÿºuô®^MýäI¦÷ïg`ÍzW¬ ²?F-~Qàb[ åbbhÌ– æ $ › ZÐ’HŸÒ¥V„¦*qSr!ï™þ_<-Ñ^]±5» O3ØS¼±pT†;N…Ér¤†ô‰H#-Í¿’eKƒûÜ„¤bã81´étàø1~ã¹FùŽ#ä»Ä…îôçcU*”FGé_·Žó_÷:V>ç9ý&Ôÿe f§z›•R’«Û@|Hš6ÍÙqÝÑ °š“¹´ ÈÚ¿|¥¥OŸzé‹Qe\öÄ<+ߨ0ŒS?LZ‚Õ\P„5Ù?½¹w\Œ…D J£˜­XéœÃÔV¡´­Â•QÕUHÊV7‰è°jt{s:W2ˆq›VÏç s+”—<¾wm>òFøÁß"=m©pB#ZF¨RßVÞ>#LY”:ðÓydbü€ oF G˜¾eAW¢»›Âè(ý60´e =(¬’( T“¢íSšY_±8a„œ·(F[éü8Â8+X™Ùüða†½ùfNÜuó?Œì–÷£:¥ÿ$ÂèBÊ3ÚK££ôž{.}çžËâË/§wÅ *##”ƒ®ûŸ¢Q{!2±(86 QÕ¥>[!®;º‚¨¹Úk7{A¸*âµ|š¯¿Ú")ˆX‹”iñh‰TÚ³ÝÇÒ‚åZÚ"`¹2#5¨’З¡JÏ 3f{™C{féK¿„¼ëÄiÁ¦ *zW¯fpãFF·netË:ÆÆè{ì ƒƒŸ‚É7Bj™X”½VÒºz¤oáÏ5Ñ „¤nëŸI™¶bSI…f˜Œ”¦°µ(œ%M›Ö6*!#VäÒ§s¯zÓ¹Èì ÊT1 ˜¼Ã$ÎZÁÔ–¾ö"woG et¹ó8aŒ$8AŒ5'Á¾.ÿ¸?yù¾qò$Ö÷êÿ‹p4v®¯O©C š¶öûÊ´~Æ'Ì®º¢äôýÃ…‡#iŬ*FvíbÑW0°q#]K—RÀí±9šüóá]ľCÁ(¹Mͬwš”¬&ª&ˆç¬9IAìÀ:çÁîøÏ+XJJ¢zG÷ìáÖ~G®»Ž¤^ÇJ’ÓâöR6V*Rgâµç¥vg'¥¡!íÞÍÀ† ŒlÙBßš5Øž‡](<¶?,¸ 5õbâ Jk3Ÿ¥L^(ˆÙrvâ•4mí“IbŠÏv½†”Þ̬êÑIζ®Œl;AyË–Yd—pL;hÚÃT°'ÎþLÁ2q;ʜᶛèy‹°Š2Û¿K«BÊÔ4îaö·ï@Eܾ>}²ePÐCë×ãuvb{ÞO_ƒ fà–—ÁôUÙD6BªÓP,*s}r)TSdn%¨Xi‚Aœ q5¢”²AfÎ Z;yI`ÖbÌ®žO»Ý""OÐõ{+è|û¹Pt@AØÈ¦ÀJ¤6‰ª(£°ºhãªcD¬ ‚,-»¨43ÌK´'ÌjJ,_§L‹šÙ¹ìÜ —†V@±BìûœòØž=»î:–Úf!µÍßò¥>HÃ÷ÝW‡¼ð컘c·ÝƱ={˜½çŠSS,³¥NhµuÆ ôþbº ¯Õ¦û©2ieAæw°óÐÂü‘´mÊ££ ¬ZEet”ùÉI¥PB蛳 !ª¾fo£8¸¶Þ@(É&NCS=ò>>ÑT-ÌÐô÷ᑗËþÙ1Lýĉlï?L…¥”B% Q­Æq38?zãÌ8€ò$I­†­Ta4ߘ-L¿iC" –ŽCÿÚµŒnÝÊÈ–-,Úµ‹bo/ÅÞÞ\˜çãq›†pûn¨Ýš•q*æ‚#,‰¬ ±¶.X±äîîõ¼dû—9îS‰ê8BÏòs+á(’‚ª‚È^§³+ÇŠ³ÕO™Eá?cØXE¡)EáSÚÏU²šÙ +­°¼(Ä Bºí9†œ¥åóq oÊÕ«ã+‰á ¯ÿ¦ð¨ô–XA»X¥W—lZ+b©E*R¹$é¤Ý –VZQŠk Û§ƒA®¡9,‰‡Òè(72¶cåí?¦pÑÍP)-êó’†­[ö$ÉVœ "À•¡ª0,;Ñ"•R.ò†\+Љ«¢A p˜&ßTAM îœéã‡f錺^ Ç»Ž«oƒõ=Ý FR頻°5tT«…ÏWSme‹Ê££ŒïÜÉð–-,Þ½›Ž±1‚j•`f†òУ£ZTT^LT¿ú|[%xnØ I  Áòûôûœ¸¼•ë“àzLìÜÉØ¶mTFFžôm–§L°’  ~âÕ#G8~çútïÖ[©=òHFÍ3Úóð¾…-Ÿ²,°mâ(BØ6ž>ÊÃÃô®ZÅ’Ë/×K¤›6ýìf·¸ “WÃ[Ú˸|šh®ÂÒÁ"Q¨XrûÈf^ð«ÿ„‚bâSŽºJºJ’ž¥…ÉUÔ wåé„a+l+Ɇ¾éi•'`ÉVö's8åS²ÌÒ´Ð'ZNM§àØ5*ÔqÂ×è5Š¡UðJ¿‡=úNóö…?†ï¼[÷çé{¬´§Í1dƒïly1NæÊ^×Ý LÍ"íÓ€Ö8G3ÈÚ¿\¥&íXä¶ËÂîíÅí룲lc;v0ºe C›6Ñ9>N¨ndªù2Še)-jsÔ¦;²TétqŠÊÑE TZA‘{–€U.Ó·f Ì:DýÄ Ö®epýz_r ½Ë—g¼öŸûë–·Ã=Ù^Êå?19ÁJÛ?qÂŒÛÁŸ¼è½Ü2q!^9¤”4u+˜4µÙ ¶ =KWTž@,”+°,s¼ÇÙò¯«ôp›`%QëâJr”ƒDI¤Þ¡²£ÛÁ¢ãSñêTD]‡MÄM¼(„¨yÕ?ƒZ7¬þýŸÞ î»çºï ¦ZEYdëêê}¿ñ&{'°¥â Ïz9IÁÖÁ­4Ùµç:V|‡+>ñwôþxR_œq«¢JŸól©`AwžqÕ÷®]ˢݻé]½š®‰ Jƒƒm™|ÑÉOhR+ ¦GóT‰bÕÇŠ%²iµˆ*̰z‡Ïgñîgꬂի5¦PxbY‘Õãð­ÁÌ2JôÉäi%lØ>ÅO."5隊RU¡n¾ÇÙŽÅ‚£^÷üóݽ›eÏ|&C›7Sèîþ¹„ëI¬`nŽé‡bú¡‡8zóÍÿÑ8uÿýøSS§aÏD¶Myd„®¥KÙ´I‡¬[GߪUO>Ÿ}áב»`ß÷à;oѓ͜q¯íÖž{eb Í,e²„·ÿ¯÷s׆­TB]ÉtóÚ=-ôüIy"‹•W®¥ïnv”´h‘©ÈTUm¨Ó¦€¶ôuºêãF‘Žêеè•n E¬ËljâL´,_¶sÚçô<‚]ï€þ©ª0dvÿ~¹æN}òc xÁnÝ vÕaß¹«yÓG?ÆÞµë2ä³#bl‘´­·d Ò‰?et1O5V½ó;8ÿò0ñ dzû€èê¢4>Ni|œE—\ÂÐyçÑ»jÝK–üô%ûxö½5÷ l,!³lÈêt§Þ6f&(BD’´pÖÆ2 mÈŒ˜F¼dÐÊHL‰IJ´´ˆ²å¶÷øQ‹h1µm‚Ùg,ãÑ÷üqÛúÏB±J‘:%štP£û ÈÑWxÏÏþ9Ÿz¾ð*8vm6VR –•¿œ+LOp•,åëJ’šž3ΛҜÔÂ5œ°,ÔУ»v±äÊ+™¸øb}Øõ3òîžZƒ”œÚ»—;>ùI\}5Í“' ææPR¶‹” ¶çÑ¿z5þÜÕÉIŠ}}ŒlÞÌøŽ,Úµ‹žeË(âV*¿x&”ð™ÿ n†cdý¨2ëVpºXɨ5 DR‹·|îóÜ¿é|:‚åXGvu†U½ncI+FyzV%”BÄšiÅ2ªô9mõò³+'‰ÛK¶r úφºÚJ°d5qü˜¢Òð?Ë—º%Lšm‰ÃÙöÞ·ó£‹.àÇç¬ÊX_Ž0˜gæ+¨ M°<f1eeÕ bÕéóô<ÂÜËo£’,¦ïœµŒlßÎèÖ­™î ”T„ï­É.HYCâÛµ‚v!¤D&ª-UäÝ•ÍÖ¯§ÕU*X24ó¶4À59h‘=§.ó5}œúö¯#Wvµáu~"Ç^éüɲj ê 'Hè[p+¯A”^Àâ³ËÞº Nܬ‡A–>™”F°ì&­ÓÝ4(nñ¾¥+EiÇqkfÈvä-wl˜PÿÆ,¾ôR]mwÞÏ4_þ¹+¬Õxøšk¸ñÝïæø~Rb{2ŽQRêªi`€òÐC6°ä’KÚ¸‘È÷™zàʃƒŒïR‘,. IDATØAÇØØS »éÛðÝOíÿ˜aq¥lµy–o+h‘FµK¸u:Õp]¾ôÖßáêWÿºþàÉ€JP§(}bÊqC·€¶~èÁ Ùú‰ë*'Ò‘›Àuz…Õ&X±,'Ñ Âž 5n$ÐbgGI–žb5µH•h*ý÷†QûðÔVhѲNÂÇàTv¬+*G€íB8ÔÉ—ßÿ‡ÜükWf¬¯”SŸ¥ýä.Â4vª@€Gú9mU+v.kž^k†Ñx)‹œ¿Äã?Û{zâ^øÇgA8™1øU,ôs¨ÉBjÏ—4>/‘[š´rNÓ|…%Óç°uZ™Z*šª}¼³pi<âóúàÚçãöZí,°‚å¡~i¼YÊïw‚Yµ ¥°‰Õ0ôIèØ =ë_añû¿ ?ú¸¬cLjU¬©ºnÓT—fŽbò"U H˜ÄúKw¥YªÎ¯ýä$À²p;;) 0²e KŸñ Ö¼ð…O8—áçº'aÈ©½{9|ã„Õ*½«V1¸v-²˜~è!:FG\¿ž¥—^J÷Ò¥tMLPèî6w½ˆ‰]»þmb´o¿¾÷eøæÇùEŸp%h×°•3è ã¢--TMø™Î[®yÛ¯s뫯dˆ™'ªbÕq… 3µ‚Ì<–׌X‰PeÜõT\²ùíƒö´ªJ[C'ÖÞ ;IZ‚&8¡>ñ²B-‚N#*áÑ@W燧¹yDéM~gV+(Úp"ÅpËÂwþòõ<øk[èc:ÛÁËD6½àDÐ:ŤY–¶¯ž q£(ÛË+Ó \h`[7Òl¾žJéÿ!Ä ¶}ô>øû—Ã̤ÉçÚúØüü“XCÓ^ÒjýòÎ;Ê®«<ßÏ>íÖ¹Ó«F½[–du¹a0˜¦…0 ¡&„@€Ð’!!Ÿ' &€íЦcc÷*7l˶dÉêe4í¶Ó÷ï½Ï¹çŽÆØ=™µîš«i-Ís¿óíï{ßçMTãÍLÐm£ÕaEA œe!zËÏÌpjˆò&ÿ²šÜ#»§U'¬O³C+ ±C2tb?}iÇE¸Yê÷W×íÌÎ7«ái—@ߪ_:Sn¼Šðþ»±'ÁŽU±jæTú¶ÔgÙP¯‹' njÆ›È,@4 ¿Š3*ì°ýOަ)‹H¶ØR:ªËô527›‚“Ýö4T¡rcðµŽwcE6˜Ð¦a¯³À¶Ï¾†ü”Ô¬iDq#æÈâÙêè—•]$Ç×¼t•¾É‹”// ÈÅݹ :Œ*ŽïS’°z>¹¹`>ÁLÁ«¾„üÚ›T1Ãòk{¬óÿÐ…Jê®Êhè•)ÝI%G!o–‚4³HyY›“˜ý ¿¼œü™ÃÄ)Ä0ù=›q¤$1®2~ž’$Ë+ UØFì+DÐlGø ‚7^ •A(wz~µJýàAŽÜx#ãWü„eÛ¯Cã”|°#%XõlÈ×”ÅôÔ ØÐÐèDj„-ý[¬àîŒ×$™Ï# œþ~7nd@“U»/†Â­L[ï$¶›Ä:k³+x)¢ðw Š¿#áïëGLïÝËøŽ”ïÜWý˜ÞÛ®Ã4¬-Îgª_ŒÐWZÒ'(d_ ¸fkÍ~ô¹+8úŒìþ‹ÓÒ»e2@µQYSDŠgä â¦AX³¸î§§C?úîóð#‡6Æw´xh'ÏZr9}Î/êþ^Z¨’Ë Õ¬Ëƒy2•‚¼©?Ó쨤Wo]ð2B‘Ùøx¡FDàFú=¡ÅÛµ’ÃŽ/½ŒC¯Ú”nKD ì7ɶÒ>³Ùê°„› 0sÒSà9 ã3ýÃU®áªn°+7I.PßËû.öt•wÀ–Ï>þ/üêïüÅȼ"ú*ZRïO\ `ÄSÇšlWe4Á¬k˜aÐ’R¸³tL³Y`Rû‹XÝÝ”GG©¬ègàMGè8Ù&ô,Ó§«0ÈÎ]‹9÷?Þ…æ[…ÊÊ#³…*)` †"I#Õ“›ø°û1N?r5¹¦›²Øêd¬Wí±Ûb!%_u‘ŠÝÙ@6[éÃÉÆ§©óõ²3¿ÇA|þd¢—/E"ˆcƒ ®("TGÚ‚¥ºª‚Ù¤`)•}òH V²H8W¢)[IÓup¥òèi_ží-ëÇ8°ñÏi>óo¨O1¹k^y%7Þˆyçnÿìg¹ÿâ‹1dTJæj¯–A»1Ú³„6ËÇÇ!‡€±´HÇÛ¿|v‰Å«™vWF¬¢¶üªÃ%W¾ŠÛ·odÛÃëÕÕbÑú¬3ñ1ÙNK„•qÑPE« á}~œßð!Uôñ5)NRoo|n(7[:¡H'ßDšvàK­ÊJd©“Ö½Œ\s*&ad4lº¥ µŽ(+Z µÑ²UpF^èôŸLÁJ2Â˺&ÇR]°ÒÁ²›,ë0 9 ‡Ïâò;ŽPß½›ÊÔ#À\=B½1kÝpõKžÅÃ6`ÉØ ‘¦^BHµÌX÷ù+éº{oJ—Í,o–›TËѵl]K—2ç”STÔ¼ytÌ‹•›±óî Ö{ö v!"IÎð°dHÙ©QpšÊw@а©ëà‚kßÈ×oz-¾tHÝÛºX¦".˜f”Bø 'Né¢ ³=.ÄyY„E‹°dV,â¢A>ï²ÈßÁ¿ýAžqÝ÷Ó¤éÈo‰cíî’¬D¯•|“„{&©/-ÂA&!óy•·¸“E•±"›FµHذ³™F“•òZ´”,õ<‡—v iˆkvZ¼áf$ø$oF‘I—Súb>{Á/\0ÒžnìJ¯¯‹üäß©÷ut掬&G¾©Ô'¸àfÊ߸÷ÑZ[[¢P@ ¬[ÇІ nØÀðÆä*ìR©ÍúÓîÍÛ> ¦Q+b‘³<…ÒñÕâ%jšxS¹–ÿTgHaÜŠfóî‚›¼62 •H^·zkcç†ê8ŸÄV±E=ªs(±ÿ?_Š•hãp1ßzìžb‚Ãä T/fÎÉ'Ó¿z5#[·RÂ*”îÉHŽö] 7¼ı6Ìoä™Äž‘hˆìµ0/OÂxÍæ',¥{ãfæy&sŸò%}ú}.X‘ç1õè£LìØÁá;îàÐ7rlÛ6Ì£Gé’.}b2i£›´úŽëªh…GøIa»R¡8:J×òåÌ9õT×®¥´Ââ`ßç¨{ ›–*[*Ä´œ¯‘·4öw¢ÈU;ÏäÚGžÂWï}] /¡¦¡m*ÂO‹•iF˜VÔV°”ŒÌ‹4X"*™„E‹ Ã¦ÙY ì°È[.r’ó>ðÖ_}] ¸K£ºf„KøaKGãËö#D¶Ó×Gaî\:—.eô´Óè\éÀê¯@Ï~ÂÈbj¢¿î¨¹œE»%CJV’S§hªH2› ¥÷È ”² 5ŽuÂtìëTi0mL¨çñ4¸ ØÂN©Ž÷ÿø™ìxáiÜûÒ§´©ÆgSh¦AE&&i¾ôJ¦¯§4:JyÞ<úW¯fô´ÓèY¶Œ¾•+Ÿ¸Ãâè­°íàíVb{O…‘±”¨Ø5ÑCß%„/Ó‚%õ¢$ƺCN˜ì‘ßÒ@%³ÇP/JܰR˜X=ÀÄSæ³ë¼ç# RQoBøHÞ¢JELÃWsçŸÍв—Ð1gίö¦Ýñ3¸ôÅê&Úߌ2 •£å=B‡c$iâÔÕgcâ*ë<Œg¬tq2:;±zz¨,YÂЦM nÜHߪUTæÍSâÝLËÖ.cêÐëÈ],+dúX…ñ#=ŠH|u ´ÔÅŸ¦J{S¨fvXÍöªPª j¡Ýbí[kJhDД‚»>ø<îú英´g1ÕÁeü‹3 V"ÂLø`%ê”dÓ‹(¸Ëé+ Ú÷ä.â=÷ÂNWJ[ÑGî,Û]¸¤q(•T Ëó[DÕHcvBÝ9 ]5ƒÛñ5]Õ—œ5ŒûæU/YL„‰ˆÔ׌tP¬ÌóùX]“v¤5ŠF'ò©XÓtå&É×àýˆ¿ñ$DÝQˆ¼äïáÇÿ¨H†òiáiä«Tm£Ñš©Ê†º9¹˜Sêõ¨Ê–¬f8*Äï®`Ú¶G¯¹†ƒ·ÝƱûïgê‘Gˆjµã¶ýYˆßL òLòÌ?cšT, kéR†7ofxãFº-¢2þìDÄ©ÿ ä ÷û„žEcªˆ „š[¦s›Ø5x¸º”×þ:·»R,Bò‘2­&ˆÓŒT§e)5Ô0UgeØ1¶¨!¼æ´Ë¼HqÂ’¥h£NL³³€ÈËT6‹<Š¢A§1żm¿ ÷Õ? xpJ-Ó$7Öù[ˆ„Iª ŽZþÔäµH¶µI(m.VÒÓ(u:í),/T°ÜÛ¡ól˜{Ö›1õSÈ/¿™+jÍgB½™÷4Œ0¹›Úu0-¬uài¬:i/ÃBL$6õßöÐ=Cüj•=×^ËÿôOŒÝs±ëbJÙ¶õOÞÿÉ#»íKB £P 8vU UõfÎhÄ-ZÅ0ÿÏà9ÿ®äá³\ÓòÛaüízëãåUÁŠ#åÍsªª`(«‹Ÿ1Í'›Ú,§>ÖLµ CVmÓ‚ å2ù¡!J Ò·v-¥S!wöıE³^ òÌôä uì³d˜F”YQ˜ªèÉ„¨ÖÕ‰”·ó8’¨×g|wt“žÁÄθùfÝz+ÁÝw3:=Í)¶’Ý4º@H(×Tá®–ôbK[zRË›iÏÞ{\Êx"¯éêbùýÑo®`MìØÁþ›nâÀ­·rà–[¨Å8¦ùäà`wÂmÁÎtèy&„Ú vUø0Ngm¾‚mëÓbeÇe¿F‡W¥7)F a³}neg –> ¦Ëj,ËPEÊ´£4ÂK8ÇðÉQÁ$g¨£#}L7JF3¦Ë™d „nw.=¥K0Ì'÷KûT,iª>^I"ßT(bµåѯ‡UWGÁÇ+Xa†Ùî%r =¿ñâǦdõ`¥·, ëSk1ò†’ ˜žêZeHÔ4‰]C¥¹è|C#hùò²6—ä8ÔaW) ˜`©·²ÞÒ}1lz¼ê“©ª~zÏvÿô§˜×_Ãȵ?"L‘ ÌAµ¢x¦&|XÍVDÃje‘²&E*ÑÂÅÇS‰xaç²eôœpƒ›61´y3•yó;.£Zü4‘éá6ò4&‹ˆP¦qi9ÓKaŠUŸñŸQ*5I4q‰®­`e„»ny—ÜgP=x91A3 Œ€p Ù¡\F¨Ü$µ‚úYSTM”y8b:33Y”u.^ÌŠ—¿œµoxï·`5ãÎ/}‰—]Æ¡mÛˆšMͯm(df(2Ú)aš8• ù¾>º/fîg0¼q#ƒkת®Iˆ_µZÝSÁ•ÏÑg’ÖzQúB !üL¬’;;ó¢|‡;—âçP›TÜi*Þ4~UØ¥51Ì8Ý &!m–•)X"L —#|,K}v„ié7šá!IA¨M—M•"mû².è0«ôæŽaûn/¹‘ïCaÙè2÷×_{Ž´Á3rÜÔw ÿ¸üÜ4x²Z 8Rm/ÉòÉí|ü¿ßËÆmÛ¨ŒÕf5 GaF㕵6F­?g·˜î,Nÿز°*œ‘"}êeðìJ‹‚a)O^’°qC‰0Óˆû0N­L¦¯ºQ;0½ˆ’UÇ }¥¸w¥*X ÌIwrÜ ±úeÜ#ðÈO~Šûàƒ, |:­˜BQÒåC¹ µ Ô‹J]ïÔ•sÂ5•X¹a©ùM¶8ö‘–™3ŠS”ËaT*Ø}}ô®]Ëà† ®[GÏŠ†0~ý3T›ÿDlAXxµÍÉ‚º9j8aÞtSÌ-%@eé1ûœln™ŠóRÂÝêl‡ÝZA_:õgu3i‘¶/ô}›Þ!ÎÍ ¶íînýÞŸwæ™ žtÃ6ïìT ɯ£`Í&Gñ îýêW¹ïâ‹qÇÇS…m¶‹ÏjOŽ}…înúV­¢Íæœr }+VP™7O…™þ:9Ycð߯€ƒ?k_»&+h¡ĞúüH×"^Îr÷ÐZ"ËÄÏ9Â&Ý *Þ´ê°ü*¶Rî”aÅ긢cå“ðÓdn•tZÉÑÏ4#…êÕE. Fu„Ÿ&áØf®æ­ T+òi¡jRŠ+%§éSW"V:Wü’â=Aü¯@ì¸áÀV<—Ÿ,~6®ø¥³Z[Lò(ÙEA•L^uùE<óòŸòÜK~¬$9â&šHy|ÑòZAθ³8 bà ?0@ÏÊ•ô¯]Ëðæ D«¾Ž74N1ß ï¸ê¨ì üšƒ7•#¨Ûr$Ur$L|—†¯˜`VbxÊtmùaJ¯H;‹Z»©Ø¯Á={áHUýÿ (YÐÕ+7¯ˆ–§îÏžFR}N%‚É7>*†¬8>åyóè;é$†6o¦{Ù2:æÌ™=ÈwúKx“A(,‚@«Ã†…[Í«cr¦a¨®Êâö;BƒYá]‘ÖÀ%–­äõ °&UáòêPóàÁÑæ‹.-Ø&±¿Õ¤!³ÆÓ¹¼eJI$%K–°îÍofÞgÐ5>…YXYÿょ!c÷ßÏCßÿ>ûn¸£¿øͱ1B×=‡,f>Y(лlƒk×R;|˜©½{é\¸¹'ŸÌ°öc9• v±øk"páÇÿÛ¿ãµôº`Å‘†÷i»‹pUÁšÌwóìOý„‡F–aE!¡maŠˆ.w’žú8¥ N)¬S êªÐh”аdz ¶JÀ1ìX…Ph)ƒaÆiÆ`2ó²cUôR®j“Su¥*7ê Ï„*¼Óˆ«Á”M!n*0_×ÇnˆÉùðæGŽëmãÂDLr IDAT0$t]¢?ñÎË©v÷òÂw_Æ‘r?µ|‡ cг¶$ŠLä$¶@â¢m NfþþݼûÅ ¸ûˆâ…Ñêœoº:(ÀfHMf%ËWkàÜ–¬DÖÕ¼1ÀœT_oFJW‹à°>9'¶ØÄî“o‡†AÇ-lj`Ûˆ|^y1O9…B_‡ï»\¥ÂšsÎaþg¤6œ_›ùÙ¯ÕØ}ÕU\ÿ±1þÐC!ð¦¦0‡âÀ~­†_­’ïî¦cÎz—-cîSžÂÀš5ô¯R ±‰G¡Ø×GeîÜß<ÄoÛOà¾ËàêóŽëªâX³ÙuÁ2êÊk4áÑáżããÿÊËVZVº ÌG.þÝõ Q“BÔ¤ÖÓÐ[´ŽI® aê0T+N9Y¦Ì„N„Þ•NÄÉÅ z—0Ðsx”ÍšbHEùÈU«f¨øpO ŽeM`5CE;¨/¾ V=ET`j÷nÞvÁí·0ÿÞ±oÑ(ñ¾ÿäÑ‘EéÚÛ¾*®z¶–؈ác:äPDšh2òÈnNùçïPþþ}È£õöPS™±FVw7¥9sè\¶Œ‘-[Z¿žþN 80кQE„ão#Œ¾Çôd…82èîœÀ’!‰"õñ’ê²ªŽ¢Ä1•) Ñ £»cq‹ ¦[;ÃW.ï¬Íz“¹ëùÀpák‘Ƕ©F@4d(ˆcI¨9ûɆÖlhܳ–šˆLÁ’¯bëN*™ÉËã—ˆ3å%Ù@‰žU«8éMobÅK_šn0ÐKJI予zÿŽÛÈäp`'‘W%6Ô/ÖôTWÕ´À3[ŠãXÇxÅz3èšy¾uÍû[>‚@¥R˜‘:Z؈ªdÏe£\öÁ3ñBœrä$˜,SE˺`YBc¶‚•ëð<À[Oø<Jw¨™‹>Â$E*é´L?Ro_¶M%t b•Üœxò4¤OÖÕÎÁHŠ—ÞôÄU—°¯³Ìgn>Ÿñ%#äbS*á«#}°•iÛ1F¤¸EV¬þ_É Ñ~ mu1kTìiÊfM,¦©0MWüt,ãå'ö ]8÷ˆw!“L¨6Xd¢Ÿƒº‚ß‘b÷FRª”ߊ·o3'±\A&õ&TÏý$\"Ъò¼‚ÅÔ?ŸÊÄÛ6`#"™Ê F³õ·Íö’“^:ÜÏãBJ¢ey±] §ço0ß© +79 ïÚ µG `j¼±ŒUÊv¢ß0¡UÏtYúÜ$”Ž[Z¿•ÛÆBófj¢ l Êóæ1²e ËÎ>›ùO{v±ø[}ÏÿA¬úáÃLíÞÍÄöíäþsÊW\AïÁ}DŽë‹Ìñ/’ª«ª;úî ýXq"fܲÃýŸ{þñF$B+-xsP¦ÑC÷ñ_úJ¦Žu@чR¶TÝ•£ –,C,‡VÁÊ‘¬„(šË{œ;ü.¶D·¤GB3l%ߘA”2Ð WͼrÒC衱å…iÁŠ’Á©NöC©žGSàjˆ|ñ>À®ç¯O½v¦ˆZzPs¶ŒR< vÍÅ:Š*Ò3CÍÕÊf»JÙ¨ÑS§ÛšPÝÚ”D/Ä<ìþÇÿÅÞz)|ùEê5­ýˆáéÏ$Ò5¡$D$¬ñ¸E;H»ª°¥ªoÃî„-EùL¢…_4±ÿm#Ñ–†Vj~O‚W‹f#å}¥+IéŽÕæÑ #ì@iãòÒ¥7 V3ÄòBÄÜš=¶CÊ÷ î¼ûƒ†9u?A " O]Û®ÝÒ8…‘‘¨©¢•Ì`c›ñ’L2Ò’™>íPùòýýGFèÒË‘á è?ñDòÝÝ¿³÷¾õ‡R¤šãã¼åÞ~;û¯»ŽÊîÝôîÝËëbéÅŽ§M¤è_‚Bbhúêka‰œˆÇÎ=ƒê/¢‡q¤T,eé*fyÞt9º£ŸïþÍ‹™r;¡;†’P‚œ„ê ;,l]° ¡¾ž$³K3ÛÛæã|rßÏÖêÍ­í–ßJÁIB 7NE‘ ô­ „—™Ï$Û0Ðs xÒ}æJÂõ8’Z[L¡¥ ¡DzBÉ¥¸vùg³Éœ&o¸ØAf :ÒÇiøäóêh$§rüRäþ±åÒ_þ ¾öRøÜŸiÄ«zƒ&„ÈÈ ea§Z¯(T+ 3x 5§J A+D$ ,lcµ Áð?/¡ð†>ÂhJ2]ÅAKæV%êiÀFz$ÔË £Ô¤6'ô1›².0šj“É®OÀýÁ†7ÃÒ3S%ýØöíºãƯý9'Þ|c@QÝpD¬AŒÔój”!¼;ŒšzîijI'uÑ’-ObÖ<ÕÀEBPfpÕ*†6ofÎÉ'«¥ÙÐЯ1ÿ¿ºÃ ]—æ±c4ÇÆØsíµìýùÏ9róÍXÇŽQ C–„!%­!£É¢f|=¯ 2:˜™"¶ ËÆøìfäk—FËKèµÆ÷ð‘·ý ·¨1ŠäCÕM9±£êÏIÁ² œÐ_ÏeŠ–î°,;ÄÈÅX…¯Þù:NÛ}ÚU%›Ä$ú) gÙ[£> Æ:6=Ý œÊ–‰ÔÆŸ»„ßy%"o`§³)"=Ñ"ªì–Í‘~z$L†Ëv¤›1Ó(J'f‡ÝÎ]¹ÉV¸@ Py><ë(?x޾÷ Œ½áxSŠißj…$Xš|H¥OÕÒR©¸U¤â ½“òµXsFò:¡eA¹Œ¨T(ÍËà©k(ý æ– ša¯‘#rM¤/¿ßPˆ²]KñÏy\ÕyéŸL§…vkˆ@4öYÖ…ò+&²‰  ‘gâEçqç-sèÖ[9zû타M2¤·S4Ô´!È©‹<0”G¯a©ŽÓÔ…\ø-ÿaŠ{ª`ù2£¦ÏlnC!å2V¥Bqî\FO9…á͛ټ™òð0†e=þräÿrÁ =ñ‡bì8xë­¹óN&|àÀ*š.:@;9ƒÜióe×é!í‰Yßð××’Í|® "×į:˜‘ò¢íܱ˜ýü_pàÈH†y#UVR.V]•«"eêîÊúx˜,ÑêÂ2áÂQ"L3MF‚üûOÞÎS·_ÓâzëóŠ ¤—­rØ"O&è?š}Ó“Ì%&ï{=ö EÌLZ3!ø5'¸ _bK5G³â°=ÄUwVÉ`Ù‘>†§ë|Óè´§(µv!f8 ¿Þ|1äKDžÇá;ïDÞr3…O}˜;¶®ãº§=È‘N„AH. yé׿ÁÜ{ %ÔmíËÓƒaÔ:úɤHeÐÏþŒ"èÍViÑ":—,ahëVú׬¡4<Œù4â¥4ƒSÇ: ]KyóBIÑVüþ¼áR¶kJQ®ç‹)Ìldž×hi¾êZn0©”ôÓcð³‡a¬©”ãý@GJ¶²¼äu»9åÏ#T7bÃkájOŸE@[ÝÝt,\H×’%Œžz*}«Vѳt)å‘‘ßM¨ñZÁ’R2ùÈ#Üõå/óà·¿?6F85E!Š(k¯Rð›,1“2š-P©ÒVJB)•VÄ0Àq0Ê6óÿa7«»}›xõœâ•×TÀÂÃ#üÍç>Á‘éV¢ X afn%uÁJŽ„è¸¡=õ1P:¢­`Žâ`Ùv@\0(ScØ;Èç¾ø66Þ}“¢Pf:…$4"½Q‹Ùžl{’SâLHBèäßµ’ÜûVSìò1ˆ0uü”WÍáWuÄôÓ‘~:¿Ê¬4ýÆoͶŒf¬´YB#w˜Ur¡§þ#5Z…kJ-·ïéÜ3çv_u5ÎáCt‡M>vÁÙ¹rG††05/ÙF®Üq?µÃ<ó‹ß`ÅOo@Nוy8ÒK† •™—eDùBZ¡mã ÐwÒIô®YCÿš5 nÚ„S.c—Ë˜ŽƒŒ«LV—#rM굓Gº DQ â˜rNQUó¦òp _¶¯ÑfCLd…‰Ê2ô”ìD4ÔrÄœ9 “p¤»bUŒŠ” (Ä •7¯™SÇ@©7Û±l?-ÌÜä@lšHÇÁ(—\¿žþµk=í4úV­"ßÙI®Ry|äÐïðcll €ýû÷óÆ7¾ñw[°GŽ0µgÇî»{.¸€#·Ü‚Ùd+lŽÇ gµq¦H¥?à 78Hn`§§‡‰={ðêu:æÎ¥wåJ机–Âé× –<Œe…D±I}ª„WUÁaÍb×øBÞûíOr¤9ÐÉ•¬\¤ “Ð_j1hƦÒ. G3Ú˜8§B%¢‚I\4ˆ‹ÂѶb]u“8¶™ 9ï¯ÏaåÍw(V’œ%T JIG•ø÷’-;cxJ.Ç‚¿ï§ðöÕDt–§1E„ßthNðkAÍN‘#IŽ©í`2£±âš$±é¸.;R†bšP” ey™ø9 a¢qØ· ¾{úS¹ëùÏâ²?“öÆÇBÔq¥ôŸsp§ýíW©\þ0b_°µI,¢£g`€â¼y ¬_ÏðÖ­t-YB×âÅØ³@¥·ƒæ¡?AÛÔ¬tºÀôxE å[,ÚÊe0+EÕev¯^#S°-›K¢ý < )VÈçšã¡ÊCõ…Z*;J¨nƆvep|²SöFM.G~hˆÂà Ã[¶0²y3«W+²îï8ý‰||÷»ß¥V«Ç1çœsÎï¶ÃjNLpðÖ[9tûíì»î:ª»wÓØ³Ñl¦ó褓š­PE3ŠUvf• {Å zN8yO:]‹3±{7“»vÑ»b=K–P$.˜ ÿ; Á4#¼ZŽêx‡ Wðá¡CËxßõÿÌ®ÚBÕe V2@wbMŠÛn„Š(j(³³e„Ž –0ì™Äyƒ8g”mü²C\0”7ÏVÌn‚‚Ñ$.ŒÝÍßõQæ]wOºÑ ý–v&È0Ûg‹*“¶MçâÅô­YÃàºuTÞñu&¦»É;.]“ÁÄán¼šê*£š‰-Uì’EJªYJ9é¥+Ñ‚JjžL—¢©ô`¦¥3œ´Ãj@\߇°Wþ >òéOp¬¿Oo~´X%bÌäyú5éS¤AEL3zå”ÎúvzÔ‹E*‹ÑwÒIô¯[Çð–-”FF(ôöâü2>{xŒèúÛ¦@†*;¯>Y"o¹l8bFÑc«™Lœ™K-!©&tU/T9 ¯ì.õHyô’:Ð V‰fÜ Ú »!У¯ý¡=åÊ##tŒŒüR_ÞïÍÌ: yýë_À¥—^J]‹Ñg~¼÷½ïýͬÐuiŽÓŽ‘ÏcW*äzz˜sÚi œtRŠá°K% ÛFq*´eSÄî»ÃKð|bÍ4lªãˆP²»¶€—ÞòêQ‰ØQæ¸be¦Ä4ãT—”ÇUž²¤`i‚¨p$–ª‚•SÇÅ´`ÙªÓ’EAA4é'(QÇrBÊ¢FOcŒg½ü_(_³34²•|“©Ø²0;:0»ºèZº”yO}*ƒk×2´~=N‡Çtønªþ4jEÊ¥¥BÆT‘‰CÝ©i6®+N¼ª¹UÂOj‹˜×Z13Po^éÉ4@"yS¦h’lT—î²B-Ò¼úOçŸ?ÿ…"™ÿf+XY¡jN* TA4ÉE…«¦øï>s7“Ø0ˆ|SA }ƒ a“·]l|„N­3iªîcHÀíGÃÄPFj[„­Ðˆ Ћmªg,/)bÇ00K%d.Gczš0°;;q*º–,aîé§3xÒIŒlÙ¢lN¶ý{=‹zà˜žžàu¯{cccH)™˜˜ P(°f‚OnÞ¼™¿ÿû¿Oÿí'?ùÉ_Á ]—·ÝÆÃ?ü!‡n¿É;¨îÝ‹¡™XYÊh?37Ï(XÒ4é\´ˆÊ‚ }¼u+ еhѸ‹Hä‘×!½‹†$ô[ ¡gQŸ,qŸ»Š¿ÜÿYv 1Œ˜0gåÍöbe*Q¥#}бò&Âã:,’j[Ò*XÂ%› dª`ÅU,:ÌªŠŸ2tPU&Ú{v0wÝÓ Pš¡hšäèZ¾œî•+™«c©º.¤ÐÛ«WoÇðþ)Õàz¤T~¼R¡Žˆ$Í©‡ºNG‹tr†—nsÂKÜF!Â(µrd§esœ«È×ö íÑ3jêï>Üõ¬­üÛ… Y*‚T7Gø¿´`%ªz'öÓÄé˜ÓŒ ˜gm¢«pΓ¿P½®{-p„86ˆ<Ü °Ð`µ˜h^ëócúò<ÚV²IlY"XõfUí=}îëÙ«ÝÓCqκV¬ oõjBÏãÐÝwãtu±ðÏ {ñbz–.¥ØßÏÂǹçžKµZå+_ù »wï>îûË—/畯|%ýýý¼ýíoÿ ë°¤$ Câ àž /dۿȱûïMÕ|þ¶.*阒…i"… Ž"õgËBØ6•ùóÞ¼™¡õë™{Æ”Èuv>1…­Œ œ†ý‚‰‹ÊbáÆˆºÄlª4âƒõaþÜý7äF0:TØ©ÈI5HËtV¡ÂÉDuE›* / ™0 E 5ì8 ˜Ž@ÚSD–M l¤jWJ|i©`„²¨Ñ!TÁêZà¾s9µÏ=Bh؆‡Y°y3C7ª‚=¾ ÷,—c†Iw/Á+±„…e†d£+ìs5Ä9êcJõóAœ©$m†@™i¹@¶Pe“¦“"5Ó——¼QE‚P°ý9ëøÁ¿½|É£ • o¸m³ª¬?¯-Uº*…H*O¥ô%Qǰ¯e½+®Q.¾å‰§¼D!Ü÷}ØsD…×FšÔÇ«8ªH3È“–'[”ft[²©·”Ùd½±LsŸÇ·ñÊýLǼè…/då«^E߉'RèëÃ*hŒ±Ö4±Ëeò¿wrƒTÔ]¯ãû>ïyÏ{¸ï¾ûضm[úuÛ¶)—ËÌŸ?ŸÏþóôôô°lÙãÃ&µKJêGrèŽ;ØužóNÜr a³™vOÙÇÌãž™ËQ¤cÞ<º—,¡qìS>Jix˜ùgžÉàš5 ®_OiàhÝ}><ð–V+§³âb×PöÝw¯ïÚÆ¾xaJ‚¢|ä0þái"ÇRƒuÃÀDÒ³¡ƒNÛ¥ ›”benM;á§Ý•miæ mi)TlWh[ª` bÓÀŽÊfMJuºót˜UºÄ$qùM›…½­ÃÃ/à;zS·½šÿ®žªü€¹!$ÏôJÙ¯ÔmjãeerÖöG(Ž’ŒâV§c¶,¿U¤’¯'y©åÅm¸ÆìÁ \ó­7H u|–AKß4KÁÊv[y©LÅ Þ8ª™ä#…s1ê±"¿v¾{ècOìºøÖ‡áÊHõ©™ÅnÂWÈ!«ª4`iÐFâÉËè½Ò€Úøø£«×a¶Q×L°Y*QeÁYg±ñío§wÅŠ?(÷ÉW\ÁØØ_øÂ¸öÚkû~WWÏyÎsfãÆœ}öÙŸ¤µçWê°Æx€m_øÛ¿õ-j‡© H;Y4[ „eÑ1:šÆ€ÏÑG;€ê¾}8å2åáaJCC¿š²öá¯Âí­Î“´+J…'•ê8”|«ï˜ìè"¹H[Ð8ï*¢?:‘9¼:DØÔO¥tJ‰žç™”âºHA[Á2MÕa%dÇô­ÓR+²L"aª‚% d °¢RTÇŽ”i¶SNQ±§éË)LÉÙ1 g=áýkD|gß'¹Ô;[/ Ôã¹PÉOóö#ÿΊ‰íöbÊ)c%“H¼xZç“©Ø›ñ‡ïº‹›>ñ ¹ür‚F#ýžiÛ꘢W¨îô4N¥BeÞÌ`é0Å AÁ{&Fù‹`ö=æþà4œþ¨j¨+ ¶’Xȼ .täªljÞÆþøuôOL­Bõ¢‡u¡º±ÒêuÓh,é@P„¨HeÀáù{€ë¥éÎI±² *aš‘*X¶Ä0”&ÎÈHy†bÇ ö eoMdC™e+Î4vÐ_:ÊpçAJq])Å£³aéWÁ:~U˼öØ1 †T*vÕõ% áHÂ’Z&„gî¿’g?ø^ýƒ/Fª(%鶺)é·Ï®‚°IåÎ2ÚI½ç.Çü«hú*‚*hØ”œ:å\ GèôhSͪ©äf æj‰Ü U'•ðÁ²Jò¸n k£®f’L¡,/§}ÿiïd|ÇŽÜs‡î¸ƒž{¶1òÀˆ>ÈYÐÑ+׺Nw PG@»ÞŠ0‹"hš:LZhíI ²¢U]¨¹ù<¥ÑQ*‹Ó»j£§œBÏÒ¥t-Z4{ïïÙÇ5×\à 7ÜÀ7¿ùMî¹çžãþλÞõ. …ù|ž}èC¿¿J÷ÐuÛ¾ý7ÝÀÈÆŠ ÙÓƒ],4›D®‹S©üæï ‡wÂy/€ñ]móª™Þœ(‚ïl}1ïyÃgp¯Ÿbü¯~AxÔÓí!JÁîHm±É,­ ‹ªhye:{-þä¼±pùÞ´`¥EËl,ÓŠ0„šŶêª@š‚¸i¤ ²!TfžUE6}…1ÊGF&‰ž:c;T–·n1¼æ>¸s vÕÀr‘ò½9øXF˜³NLT4•ˆµdâvæ±óùµòНœQ×™ƒºâd»ªÔ—·§Ôbš†å2=«WÓ¹b!åswâælªÓJ6¹&•Â4ù*9Sûò,3ˆˆ›qÓPæ`”–’ùUÛä:‘R$hã)`d-Ïr57Ý;NptŒÎj••fL±¬ätM©k¢\KCð)<¥&O k@Üq œ „ ²,d¡@eñb†6l`pÃælÙBihH:ŠÅßÛa¹çyø¾ÏW\Á¹çž›ÝöîÝ›þ²^î|æ3Ÿaùòåéöï¹Ï}.çœsæo¡CüÃøí‡sÏ{¯¤TA–m]UØJ-™(ùÇ¿ü(ß,>#ϽONùò±¦,èbeºÛ`Xt—U€ZE3Çû¾ü¯¬X»½5tÏÈr†§ŠJã„ÈtzR7 „/±ü¸n(–Rì× ºsô䯕s:bÎ…ýæ®àm{á ‡$"’8¡OÅ&+™…#|~á´Òz¢¢©¬B×™#.ä…Ë˾ôE^úwŸ‡f¬:+_÷ÙÈI‘¢TÂìëÃêí¥Ã7n¤gåJºWvÐèý(Sò^&&º©O—p„t–¦¨§)Z*‚ªMXS©ÅIÁJC#ÂXÍ«´%(ÕdHqbÑÑTÆ8øS°ý¸SªÑ6L°0óPò ï)ËËTY³üÝ–í%39P?·È É3FúÈ4±»»)Ì™C÷Šjܱ~=½+WRèîþ½-NÙcÞí·ßÀÅ_Ì÷¾÷½ãþÎ3žñ º5NæÂ /äÿ·wÞaRÕçÿœ2}fû.»°Ë"½I[ª;æjÔ !Qãµ ¯5&â»&–˜hÔ Ñ\K„Å£#béˆÒ—º,[¦ž~ÿø93 XcÌšÌû<û,0‡™Ý™ï¾ïûû–ÈA(DO?ý4MMM 6Œ±cÇëë‘Û`É+ðÁk8Šxb¸';.`Ù&’0ðÓøõ5ÿÃsSNeËäfâ/g„A\À„¨+hº–1Šœ ³–¬  ÒC  Q‰ºÖíã§·ÿ‚ACV +aY÷:­€¤y®>Û@rÏ Â1\ÀrC,í¤Ýòr£R¢Ã›‘}€2füË*ûñ£&‰S!-MTKP¤µãsŒ`¹]ÙH1+¬ÊEÀ&SD ЬÃ'^ó#ny®C¨g¾ýJpB!¢={ëÕ‹ò¡C©7Ž˜»(”” ) ºùGÒÎ4RZ˜=;ª02>B¾4ŠmQk¡(ÔŽb[XIA\5ã‚mŸ½CIs5[h]Ç ¿-„Öû‹‹´Ø©9n§ej î©Ú5ØÏ®-‰aÀÊI^2ª*{¿ì™ò,·ïSê…^`õêÕŒ?žñãÇ˱,2mmèñ8ÖªàOOP¶hŽ­c)¹45#Â,mËõRÄGKI˜93g°ðäØöK?[~!ã¦p^ˆêâÃïÀò僲² XŠVPtXŠ’Å(Av"•I¸wƒ{¯Â'ÞG@ÒD>¡-,eÓÎY*hvR†kI')yê~;%´2^l×þI¼Ïôú!Ón~ŒvÝ"’JŠ3M‘&´‚>Y€V6­'  vXFQ,TŸ‰V@õ™^Öa$“ ï ¨¸ù ´Œ‰©ª8‘RQÅýúQÕÐ@é€tih V_/M\Uw —ZFºé$”P3©d˜¦•H–C$˜$¨f(µ °J+qNFÂJ(b‘®» Ä.`)¦»ÏÒÜ@‰´s`e“^œ´þè–0+´“´¡Í„„[‚›ˆÆÇvr\ÀýÏd¼M‚$!‡B(±¡®]=ÂrÍÈ‘Äêê¼e¹ÔI;©x<ÎÆX°`÷Üsš¦±ÏÍ èÑ£ÅÅÅ\~ùå{ì±TWWáç•N§¹óÎ;Ù¼y37Þx#555ÿ~€ef2ì|ÿ}v-]JrÑ"Ê6®§Ï–Õ,GKSSʽÊ|iqÒ“V!뚢ÉðÔýóÞiÙpKëþ§DläciˆeDw1«=踪k%Z’*K•Á‚U…T$KP$áÆPS¿“ß\5ƒq½ €rï²’aGâä‡W¹ŸMkq;'.CJBÎX¹Ø©¼$Þe݇3uÖC¬é> –¡ªuÅé6‚V†¨.‚$TWßè–Ë#>ÅÀ¯èQ~E÷"IJܦâÛÞ"ò,õíK×ñã)ëߟX÷îD»uûÌÄmÅá`¿ƒ¤:è)?-M¥ødƒX8NPÉB¬”"Æ@M–’‘ 7…Y ¥èV¼\S<°’â³éšöYš8Í8âp8c fy{Ã|^~4¥‘^J$B¬GÊ  ëرT B¹›òÓ™Ý Z[[ùío ÀÇÌC=tÐë¦NJee%§Ÿ~:ƒà7¿ù ‰D‚I“&ÑÿïàíØ±ƒx€¢¢".»ì²Àr, #™d売âÞ{é»u+õé¥>Á8°%0eaëX®?ÛÚëÀJ©Âz$ôñû¶YsoK¯ê…—!¨Ce»è¬".`)®ŒAgÈŽ„²+(Te°´T21¤T Evp|B~ó“ÿ¼ŸNüŠf¹yx¦ëoe#»9íN`eµxŽ X¶Û=È®’œš<9›€“”øí?æ–ŸÌDSeÚ©jÙCTO°5¢FBä *nž b£ø,oT•üŽpДuœDPÎÀr4–F˜1+A÷­£éS<•@qéç‹¥rlœMc®ÿ)’Ú.¢¨t…D[” /CÈ—ážYÊDZÆL7>+©à¤¥€%kBT?"îoÙb»Œòl4•gAåjóÒt´¥Ê«-œ5kãÆ`äÈ‘ì£t]gñâÅüéO⦛nú¤ÎüÚºu+~ø!ï¾û.3gÎü×,3¦}Û6Ú6mbç_ÿJûÂ…XK–0È4 º»qGC]•ãúåGwyff² \=ËXûäØÓµ/̘Àƺ”&‘*ÛpB–«°™ó^Ïú²{c¡ X>)Goð) E‘3aTÙÂñKâ4ÎgsÃá³øq—û½OIwíuq çTVÖ‘—“gé¹e²¥»`•žíj;¼2ùdn½í4Y€H±ÞFUë‚–ëh`¦D„ÛeɪX¸û%]¨¦çG.ûEtY˜”°?6…À8B9iÓÝwU±KÜãÓϨ]‹qþ4' á 2¦%aj*>UÓT<À²’ŠØå¥%±p7rã šƒcRW–ïefýÁ\~XÖ»>Û¸î¿ïpŠ™TŽª,/'RS#<¢Æ£ë¨Q”÷ë×éÝ ÇáÙgŸ`çÎ̘1ã ×7ŽššÎ<óLN>ùdþUêŸ.ëvl›¦•+Ù½lÛ^øºu°~=ÑÖVᾘwZcã—Ùb_e甾ÿ½K„ÖGþƒàP?/ýà(6¾Q‡‚:N‰ % %aItU—ƒ•?fSp|à©¡2h ’’"8NYþÕM[þ‡¨‘àLë÷"ÈÓ¥=;zÇ)ËoJ¹2°²2—츓ð2 Ab|òÒS(’Û±PP“˜§BÙ‹_Ö…óªŠ*E|¨ªý²gPýè9Àr×)d§ñ:vB&mÞƒ½Iú>J¯ßÔì ©¶-ãØ’7µ-lÇ¥*¤:nðå”h‡¥´è¼$ÃÆ6À4Áõ2sìyËÌY´˜îßµ¼ä—ýCµý;*Y&ZWGY¿~ÔŒM·Ñ£)éÙ“âúúo'j×®]Ìš5 ÇqøÝï~wÐkN=õTŽ9æÞxã N;í4N:é$þÕêkí°ËBkoGÇÙ³|9;/fÇâÅ´¬Z…’NI¥(v¢¸uîÿÛßb&/¼ù vÈ–,ãt áŸw,ÒÐ2¼ì<ÏkLTE‡¨U¦AE\Ы¦°w””\ „¬æN eEüÝ' à’TtFÕTQeüÁ®¤‘* s´ÿ/ÌÞ}¥é74BÒmO4œ/ Î&º8™œ»¨­‰7j6F\7á¯ÿs »è?1dŠ%œ9£v‚Šø^‘Î,Yø$TTÇ‹ëR,+Ee‹î*„°j‰©q¢Š'ƒV†€¥áÄ%Œ}>ºFItjýCàÿW€½ÛàºAXJYL ÇKr<ª€šv]<Ž—$FcÃñØâ†íÊ_\ö¼—p“5.Ì»= XûK_,YFŽD#Júõ£zäHj¨9’pe%¾pX¤wÒeù‡~ˆaX–åÉYLÓd—+¡Ç+//çä“Oæ‚ DÖaII Ñh”D"ÁM7ÝD*•bÖ¬YŸÊ6/ÖAª}ëVZ6m¢iåJ-bßÚµ´¬]+âÖ^ÖnŒçì9›™Ž¢û“^’„ê „‡T ^*ÃÀb6Ôƒ;g^Îö 5(І/Š٘e†,E–ÇAG@¤ßµ;–ò+? 5 ^A ¬ ª%ãWEž_ÄL”2dŠƒ1Sö=Å]½*ãZ;09YÒrãN–Enè9ÊJ_Z{•óÎïÈŽ‘ý‘è—DŠKiºIvh©¶$5$]ìƒTC„HdÓ]²VŒX!)M‘ÚŽßÖ±Ú´½|ƒ°ž‚Ð 0ò÷:P„î|´éç?Âiú#Š ².a*EäBÚ¦`û9]žíºtêt\ ÊgõÙ-/c/ߨ‚ÕÕD»w§´_?ê?œò¾})8ð7à kš&¿úÕ¯¸ùæ›imm=àš††Ž:ê(&Mšô™ô>úˆ9sæP]]Í´iÓ €õ¹Æ½Õ«Yü‹_°mÑ"´½{qR)ü䯲 µ?{%ÿ$'ß·Ýë´$ [’ÂaJû÷âÑãjèôš lŒÜÅöÆn\qÍlßÜ Ù´ðù3¨¡zLÂ*3¡<-©²¥ARóbºÜ‘P–Å‚]vÃP÷ï!?ª ~EV±ÑFØN¡Äò> ïÜÑ@Ys³ØÕdKËzz¢a#—|“í2Ù€¿Â†wO§åÐZRé0EC±-ŠFXJÓãHŠÐ f½œ´ävuŽÌê3h6-~G§Hm'$‰‰b_GÃIJØm2RÒAŽÛ‚A^üpú|UÛÆ±mâ«V¾ôGøö¬Á(= ~7é&$K5%ˆ¼þ¸ XZŽ=žv3óò-ž 3°\ hÝfË—¾²Œ)Iø«ª<¿úcŽ¡¤GBåå&–ê“ÀÉvcÜÏ8ã öîÝ‹mÛ¼ñÆÞ5Š¢à8cƌᦛn ®®Ž>}ú|¡ûúè£X½z5³gÏfæÌ™|ë[ß*ì°ö§!$wí"ÞØÈæ×^cý³ÏÒ¼b²ãxÆJ^'•%æå÷í2aå-Ký¥¥„««©8nãÆÑuÌ* ‹1ßããø,ÊÓ6¯¯9Ší‰nH%A3ƒ2QC&f‘«LŸñ‚®G;YÀr;ªüÅ{~l—O-¡$!a{§r>Ý‚Q› ”A 8ü×åsÏ5pÈæ9ñ°Þq?£9ý’ö÷‡c\)‘CAÖ› $4Š"íø0Ê"}9èϸß{#áÃJ)‚-®ÙHF®ÃR-as@ÃgºñêJÆKw–UÁž”’JÊÊñ¾âÀŠ—Hm˜Ì¶aSÙöúë´ÿíoŒ\»’°¢c c‚­æ˜i¿øÁ: 1š)È)>—#‡+$¶r™º•ge/Ù±_**"PYI´ºšú£¦jØ0ªGŒðÜ>:{½üòËhšÆÌ™3=Ÿ¨üª©©aÔ¨Q^µiÓ&ZZZèÙ³'=¾äsìÓ§}úôaÒ¤IÜrË-ìÝ»—C=”Þ½{ÿûvXŽeѼ~=MkÖиh»—-£mãF’Û·#;ŽgÒ"å}ÞìË,%C‹ÇÅ¿Ë2á.](ë×.®°º¼_?Šjk³:ï·¨a,¤©åJ´L>Å`ümckSw†FÈNc‡mÔPŠTq½Ôâ 6ªUI–ꎃRÞÒ]•r€¼0T±Ö2½ev™¶ˆ•ÄÉĬ8²ß&Yá¬{â¼›ï󺆌ÝQ‹·?Xåëóü]ºPùloœ‘ÅÄÛcdAÊŠöá—u‚¾ A_Ù´½0 3¡b¥Äé[¶Ãò™®'»áЉÙ‚>Ë "'Q !}‰)qqB— ŽH»`•Z¡}o„W×){Ú©— «bî·EsÓ‰u¿ í’û]ƒò¬¤%%ç²½Î* RNG29¡tÐ Júö¥ÛøñT B´[7bݺ}#b©î¸ã6lbüG}”Tž³ @·nÝ<Ñp=øÿø·oÞ¼™ßýîwø|>®½öÚ¿ûñ<øàƒ4662mÚ4ºuëöïXŽã ··³zî\Þ¿ï>Ú7oÆL¥À4=‡Q)oÜÛßÄOôx*j4Š?£zÔ(Ê ¾s'Í}DIÏžÔO×Ñ£‰ÕÖŠei pðV_{ôÞÑÖj“±‚ܲt&¿_v6èÕød+ì †2ÄKbh¥@TÇ–|b”]XÍî«$I–dPe Iu<Ç;$cEdJøTŸj²Ó”gš‰™qŸE±Ñ†O5HU„)ÒÚ8ÿ¿n¥~þû¹åƒ“ b‡BD9„ÒAƒ(?ôPä†]d†ÿCõÓÖ\ŒcH”—4ò¥XÙ6Z{€Ô¾0VJ0­´’Ë64lo$T Õ´Eâ⬭Ï2ˆHÉyɵ9&.<É­¨{!¾V6‰ŸiTûGŸ Ž é°j‘ܹM2\1‚~¢“=pÊ ÷´}>¤H¥¨ˆª#èÒÐ@—#¨5 5D …:5HmÙ²…tZXvÚi´µµ±sçN4MˆëƒÁ ×)M˜0«¯¾¿ßO×®]?õë677óñdz|ùò¯dÕÒÒB$Áï÷ÿ{ÖÞµkùàÁYõøã¤ššp=˜Ë¨¸W‰X·nÕ׋ÝÑGRÚ»7¥}ú`m›7®¬ôh?³â¯ÁŽïc¤$ãþÜz,ßÿàI$Ý!¢%‰q$ÕÁŠHÈaöÒ"2¥2NÈ€åõ×`¥8à³M|ŽJŽ1Ž$Ÿ,;"ã„Äh(E‚r†2mÅF!Ò”è­d ­4@@Õ(Û·‡ËÒ° UÅWQ¯ªŠhïÞT54§ƒž=‰ÕÕ¡DL¶·\C›³ËVhÛ[Œ_Ö©,o"L‚™x­-@z_;#»~âr°L‘pã¥9»!¨Š&Ø÷A'ƒ”qĈ¥X q±`)­°Õ†è–ÃÈŽÐqfün´¼!h'ùÚŒP*MÔHÓãXA#*Cؤ½´˜L‰‚;Ë`—Td¦ßÔ š‚ˆ©b¢J¦'q‘TGDv…eœ€»ËŠ€ÏgP$·“âÄÌ8¥Z !)“‰HIbF]g½ ¿xŸ`}=±Þ½)êÝ›ªQ£¨:”HM þ¢"ÔpØë õÌZ·œˆ!ùÀDk”h0A—ªÝøeDs­]¡fZƒÞœéd„)`¶Ãò™†XÙLAYDVŸi e„¯»ª™m[2B“—eŽK­B\Üî@³ '÷KIhï`åÇQ@;‘$L V_O·qãè2bu‡N¤ºš`i©·‹ìŒå¸&“_|1ëׯgåÊ•ìܹӻFvv}úôáî»ïFUUŽ>úhV­ZÅ|€aœyæ™Þu…ú–cYìxçÖüñ„**¨:ôPâlúóŸÙµl¾Pˆ²¾}©?âjÇGRö®]‹? Òúú¯æ‘·l„—'ƒ³Â[~9–Äbÿ8ÆËßÑ)ooÆïèÄô8Z$€S±"Ð^ZLªÔ‡íSpܸV¿aN§ë)‚f†€éúIa¢bz®²â£†Ý°8 ôÉQ5AXMóÅ)uZ„äŧ!IŒ8å¦è¹d$]ú§¸W/ååŸ*0Ý÷î¡hv3š@ULLM¥8ÒFq´ 3­ßCOø±R z»t‘Üìd„í²j±µjš^j–}/k‚&erÇ‘Y-#×ýÀM»II.‹ÜŸã@2O‡œ’kíG7qd_q1.](:äºqÕ#FéË—õêÿëÃ?äã?DÌÔÁüÊ'Nœˆßï'2wîÜOýzüãyâ‰'˜5k#FŒ( Ð?°l›Ä®]H’D´ºÛ²HîÞÍ®e˰M“âúzŠ»w'XV†$IئùÕïÚwÀÓ߇¶·:lîÿR|gÕ=Âv»Åñ6*Ú÷¢(1=N2A‹ù0b m¥%¤ŠƒXªŠlKÓ‘T’H*IÈL0‰Ò‡;’Ë’Œ–Å"'(@KÅ|&9MTMPj%æ‹“EN”1;NefýC· |{ÜÙ>‡ÔÚKÈš à×P$‹h0â˜XI•øÞfRøHéq?Š) ]ù)¦…b‰1P1-$ÃÆÑC€”çÝžÉW¬ûûg-O£—䜟ø’ϓ˞èúKK©<ôPá´9~<ýû«­%\UÕiÝ òëá‡fÙ²e¼ýöÛžgT~E£Qn½õVÎ;ï<ŸGoéÜqÇìØ±ƒ›nºÉsK(Ôg×FI–‰å- eU%Öµ+áÊJdU=`!þÕƒÕ˜}"ì[&þîò2’Ÿ¿TÅŽò®ÓJ‘8㓌bvX1©¤"ŸíiKµDLßt2"NÊqƒ%²€…ä8(Ž%7-Ér¼ì2Õ2‰ª ‚R† ”¡Øl#êKPÙK±ÚFŒ8]Ãh{SÙŠè÷)¯èÒÆgñ7·`¦Ã`B(˜& jÈ- ¥”½–èt‚Ñ®Zn2³i"[b‡e™¦%8`Y-^Ö—Ý2òöº›Ll¹×Ùµyù'™zþÊïGF –—Óeøp¡Í=š²Þ½ñE"¨¡P§åDµµµ±gÏ@Ô=ùä“€Â$ @ðŸ‚Á 7Üpo¿ý6'tÇsÌ—ºOŸÏÇE]Ä®]»¸á†øñLmm-¡o@”ü7°ŽbÊ×qâ°{Ì>6/ó:+Ûâç e‡ð›‘ÿM ÅN¥"RÛ/‹0ƒ «HF+ö#—Ø|‘–$1-îUØNrÜpT:vXŠc!á–-K¶l$I4¨ŠiåR`"£]t[z‚òX3%¾Vœ¤„™TÙ×v%5ýÿôÉÏsÃK8KžD H(I ű„2HØÂ¾X)m#·Qµ¬Û¨iag£XB ãX¶ÐÝYyZ¼,X¹òÓý7[ÏoV«I IDATÓì¹äÝéH³ÐòöQr8L´¶–âÞ½©nh ëèÑTôïOqߺÁ›o¾É²eËxë­·>qŒûñŒÏçãÊ+¯¤¶¶Öû÷X,ÆóÏ?mÛLœ8ñKÝ4¥wïÞ\~ùåüüç?§¾¾žË/¿¼€HÿÈS¯µîù)|ôgØ´4VŽ8.—u¸pÆÌòŸ¨¦Iqªšæl 3¨â“ ÚK‹H‡i/Ž‘ö…‘ ‡Ø¾8ÑÖ#I4 ¤¥ !FÂ:,Ùµ¶ÉÔ HH¦!~– ›ˆ’Äoëølƒ’`+4J-Tï¢Äߊœ´1÷©(ñ(E=nÁW{êAº« Îm‡aÇ—OÂLû‘% ¦Z»ùxR2­!dÓF6ß ÇÂÀŽ¡n&ÞÁËt…ÄÙàOÓp‰šf^DÊ_)éÓ‡®cÇÒuìXº F´¦†PE…ÐæuòZ°`÷Þ{/ "Ó7mÚtÀ5¿ùÍo8äCøö·¿ý‰>庮sï½÷2|øpŽ<òÈ¿û±½ûî»i´Pß`ÀrþöÒ‚Çp^|ØÓªÚˆ)]<ž[.¾‰§Oø²nSœn#d¤©Ù·Y¶1B>ŸD[Y1‰X”Œ§hºEQk;Ѷa'E4• hd„]° X>Ù¡ŸˆDgYc*8> Ù´‘üâÛ'ë6a9%ܦIQ ŸeP¤¶S]¼‹°”¯éÈi¹ÕFmµ¿½ªÆåžë¶Ø?›„”Z‰^â†÷¦ºêàOïqIŸ­„ŠdÙØŽíÉ]ò3òÌlú° R–‘{ñ\Y1q0é€à+-%P]-,XƧfäHÊú÷Ç vz¿ò­[·²víZ–.]ÊÕW_ûç½ÜƒÁ Gq×\s ‡v˜;,|þç•ýZ߄ܿÌHx饗2yòd?üðN„RñíÛ‘ç?Kè¶«°¤¤x°X²Ð©eý¯6õîúƒR„í%J+~I§(ØŽ£JháfPÅÓ Ë)‚™ NJœ¢éíD!ÒDíA[H]Ž?ï‚Uö¤Pvl1ÚŽ)‰ÎÉ"㔞ì†EL‹£˜"¾Ëoˆ+9cã3 ”„-`/šnHÏAs,ŠÄ^Âz Y²‰j Œ T$LF ¢µDZ«4ö;:Eñv©a%EDsKq \áìK•LdIœ¾I²èªdÃÖćßAŸ’æ–R8i ¿©Sâo…( U3Eèg\€Ö–ÍX ÝtÁ@…T™°7‚.P!4yÁ¸ø{Â/ôxDȧnã¥7›îéžaåô{ž¹¡,ãïÒ…p×®”B͘1T  b©**:}ÇÐÒÒâ-ÈW®\Éý÷ßÀ5&LàÐCà /ôº©Ïª™3gRWWÇ)§œòOù¥]¨/¸Ãzâ‰'8ýôÓ3f ßþö·¹þúëÿ!w˜imåã Xÿì³ì[·ŽÌÎÈÍÍÔU@®•$¸lGŒCºìÊ=œ\BΪ[N佫þMQ’T&›šY"`iè!?)%Œžô£µ@§yRÆÁNQ²p:EHM1\Jƒ"î~I|¨’ +’8­S-IrrËnǬŒÓ!èÓoë¤4‹ˆœyyi%cyaN’HoÚr­û!-JÆOOnP"³eÑȦ“©|  ÔÔP>hU.«¼¤W/ËUT„Ô‰ãѳ]Д)SH$ó®»î:FŒÁàÁƒ½¥ù©ææfÞzë-žyæFŒÁE]T@‡Î XŽã`š&×^{-/¿ü2ãÆã?øÁW’1æXé}ûˆoÛÆ;wÝÅÆçŸÇik#ì8”eä²¼ÿCŽAmH.)1OŸÖ|ùhvÞþmRV- $ÜJ¥Ö„Ï6pT IvH9aÒí!¬¤‚ÞæG2…fNÖl’F,'¢‹ø©°å&Ǩ.Ëu`ðI¹‘PuL§n ‚¦lØ^p¼Ï¤AÎØ8) )%BR”$ü¥2¶p?H€f÷-Z³ hdŸ¯ Š.ܲ r [–K7ŽÒ¹¸¥¤„pm-µ&ÐeèPjÆŒ¡¨®IQ:unžeYž'ÔæÍ›='M#OòÕ½{wÏjúôéž#çu×]GKK S¦Laܸq_:@Á4M^yå¶lÙÂèÑ£ihh( Dg¬l=üðüøâ‹<õÔSñðÃ{¿á¾èâ<µw/M«W³}ñbv.YBÛºu$>þŸe urF~ùÃHÖeô%Õ!¤¹G“:¢'éd3­RÛG…½ű°| †í#Ù!Ó&Nõv¿«Ø°²©°!:¬“&(e(nÌ»œë°²{,Ù …áJY4Ç‹ír2®¬%-(ŽK—\z¸”R¤¸•Hí2¤5HiB!ã…VË®.o?O¨|‡Íìg%£¸o_Š{õ¢îÈ#)8â=ˆvíú Üpà ´··cš&¿þõ¯¸}РAœ}öÙ€pÝü$Á¦M›xæ™g°m›Ÿüä'×cš?>«V­bôèÑ_š Z¨`¥Ói§©©‰k®¹†Ý»w3uêT ÀîÝ»™6mÁ`W^yå3m0lÓd÷òå¬zâ ¶¾þ:É;0[[AÓð¹åsA*ß~ÆÙ¯«òd² †ã`hŽ$8¢ŒÊWD³¤ÚÂ`@EÉ^Ê•fdÉFs$[#Ä›bèí~dÓÆˆûð9~GGÖmBŠF‡­AŸÈã H¢ÃÊî¯|’â˜BÊb8¹¤M0½0 —]iåZÙ™¼œÁ´H¾qR"‡Pn»¦$nú<wS_ö [ûýÙVU‘‚AªG¦jèPºGÕ°aø£QüÑh§ÎÎÛ¾};¶m“N§ùîw¿ ½žiš„B!σü{ßûS§N%‹}¡…ø–-[¾’=l*•"™LRYYY@ŠÎX+W®tî¹çn¸áºtérÀ .ä‰'žàÍ7ßäâ‹/æûßÿ>¥¥¥ß7$“|ôüó,¹ë.v/]ŠdÈäF³Ÿå¼Ž*ß¼Ïs•$|%%„ª«)éÛ—ŠC¥uÓ&ö®_Oh@šê;¢h‘ºî'¢Ø]*vS܇e+ìk*#Ó$ÑÅL¨(–…•P¡ã3 X– 4}.AÑð+:Šc"Y"’Ëvå*¶‘Ó×Ù†ðˆrô\T—­å"º=—‚“µA–ÂÙÉðÊäùä¹..dçy±T²L¸kW"]»R9|8u&P>`•¢~äúӟؽ{7W\qñx¼Ãíååå^_RRB¯^½8ýôÓÈÍ+T¡>7qô¦›nâšk®á˜cŽaÊ”)Þ~Á[¦·´°ù/aÕ£²õõ×1Üe°¤ý€*O•}’ßOYÿþT LíGÐeøp¢Ýºa[™}ûý~´êûiñ¿Nk¢KS03*E£¦j'E¡vÚ[Šhj¬ÄLª¤ö…±Ó2ªmb'e±P—tü–.ËI›aŸ+ɱÀ´=Q°åÆrÙ7áF@å—–'vÃ$÷Ú¬€Ø4ÜkÒ‚}nk¢%K•ŸŸ×!ùaÁR5dUC†PôÑÄjk‰TWy;ž¯¹Î<óLâñ8 .ìž­Ã;Œ+®¸‚ââbŽ>úh@¤/Y²„÷Þ{›o¾¹ð-Ô—,Û¶Ñ4sÎ9‡'Ÿ|’n¸N8aÆ‰Û ƒö­[Ù¶hÛÿö7ß~›–>ÂÒ4ÏqT  ——(-ÅÔ4’MMËÊ(ëÛ—n‡æ†H %èZï¿ ¶¬ù$ÒgÑ–‰Ò´«Rð¢0 RT•ïA6möyG9’în ‹`ÇÀÉH„”´w –S„å>Y•eŠt—lz­åEqi¹óþìS¶Û²³É7Zޤié¹äÓtwT–ëæâ”†ðˆRŠ‹ñ—–«¯§û‘GR5d5#G­®ß‹N|š·fÍO@|É%—°~ýzñK,“ÁqTUe„ ôîÝ›»ï¾A Ÿäz¹~ýz.¾øb~øÃrÆgÞ©…úb€•­x<Î}÷ÝÇc=F<ç‘Gé°M55Ñ´jÛþúW6¿ö{V­"\ZJyÿþÔŒMía‡áØ6{V¯&T^Ny¿~”õéãÙÑ|ò_‡}§a:óÙÛ\AóžrüŠNÈ—¦(ÜNØŸÂHúØ·³ŒÖ=%ȆM¦5ˆj Z‚lØ•Œ-)ƒ_ÒÓrÅÀ®sA6Õ&?ÝÆvc¹<3r€åucùÉÄn Žá†|f?gò@Ê|åå÷ëGIïÞt?òH!®¯'ú9v…¡î¹ç¶oßÎsÏ=ÇÚµk¸½®®ŽéÓ§¸ä’K¾Ô}Ì™3‡åË—3yòdÆŒSxÇëËi 7oÞÌQG…Ï磶¶–gžy†’’Ñ é:-6°cÉÛ¦ÛØ±„++ñÇb¨Á –®cé:¾v @ ªŠê1c¨2„ê‘#©èßß[–wÖ.ª½½Ý³Z¹õÖ[Y´h‘×e=Ì«««‘e™X,ÆÿýßÿÐØØÈÖ­[™›3Î8ßW}JÕ²–~œõ A¼%F*&Žò§ #áhVZ¡­©=îGµM¬”"ì^d Ÿ¤#I&†ãxi–ëX`™9 ²2þe÷RPes­œ$&?TC°Êåâb‚]»éÞê1c¨nh ¼_?JzõêÔ|¨lýå/aóæÍ<ýôÓ,X°à€ÛƒÁ ?üá½në`ܧçž{Ž^xüà·«Á•W^I à‚ .ø\'Ö…*ÖA+“ÉpÙe—qÿý÷sÕUWqË-·|µrÙ­ðÁLÁ‡p@K05•`0dÚHiXŽ&Ѿ·;#ã³ $ÝÁ/éȲ…í±Â-°ìLnôNÿ2y{«üÎJï(΂Tþ‡Ž n–HŰaTE—áà UV®¨@ù®”ÿ¬züñÇyî¹çx뭷ؾ}û×<ú裃A‚Á 'tÒg~MÃ0XºtéW2Ò­_¿žââ⃞hªXŸ» Ã@Ó4Ž;î8V®\ÉìÙ³½ß¾W-óÏUGŒ8¦„åHX’šÙ,IsH·…ÀÕ1l S±Eb‹ 4–™á¼}T~•·§Êºnæw8É2„Ëᯮ¦jøpjÆŽ¥òÐC©péY¾iÓ&¶oß΂ ¸çž{áó¤ëºwÍa‡†,Ë\xá…8E"‘‚SA¡¾Ù€•­mÛ¶ñè£òÈ#pÊ)§pê©§zbÔ/µÃ¸¤ô]H Â’\IŠ8()ÉkqÌ”*€J@•V\÷S|ÎT‡®*;þ9»¬«ž×=i’±‘îÝ)îת†*‡ £øC(ª«Ã÷ à -Y²„ùóçðç?ÿ™%K–pÍE]äu0W^y%>Ÿ|-[¶pÚi§}nAq¡ Õé+[‹/fÒ¤I”——ó /PUUõň€Zç¯Ç~ñNl¿j 1tVíXÂF%ؾ¤ X†ƒiI¤TǪ¬GTv tôÜ>*;ê™®³AvÔË•©(˜>N4JÙÀTŽA—Q£¨6ŒpU•ð+ïÄfvétšx<Îûï¿ï¥ 755±mÛ6ïš²²2TUeÖ¬YŒ'¼¹ p€¿¸a¬\¹’¹sç2cÆ ÊËË ÄÎBýëV¶î»ï>.½ôRN<ñD¯ãú¤²M“øöí$¶l¦rþã( ~‡Q,lV"IA2M†„ZrQ%Ü þ„ÝÒªè¨>áj`šbnå-Ø-·h7öõtÀôûñWV¬®¦lð`jF¦rØ0Êû÷'XZÚé6ùË_þÀ«¯¾Êã?~À5G}´çQ~ë­·~áöùçŸO·nÝèß¿?§œrJá]T¨Àxúé§yâ‰'xá…¸óÎ;™>}úA¯ûè¹çX1{6Ý׬bXÓVìbH–‰ÕU(-bÐã!VJÔ „ÚÀq=¢âA:)%·¯Ò­!ÔÊúF‘ãCi3»H÷î÷íKeCÝÆ£¤gOÂUUJK‘;¹ËŽ;¼ƒ;v4;à§?ý)¿øÅ/˜?¾çrðekÅŠ,[¶ŒT*u€ê¡P…úFˆ“ÄóÏ?Ÿ÷Þ{;v°`ÁF Fº¹™¶M›Ø¼`ëíí pŠ$0C/Ÿ)öW¦Ÿ V)>a‰>âHªî’÷߇û)T¡¾ñ€õúë¯óÆo I²,óØc1ùÛßæÄaÃXuÅÚÚ¨j€ÂË‘…‰£¸šCKŒƒ²&<¢ DjN¶«ÒÈuPV^'eJi)‘=(îÝ›Ú ¨4ˆÒÞ½‰ÔÔ|=eG™¦É7Þèí æ´ pÆgлwoŽ?þøÏL`¹ñƱ,‹éÓ§%nøÃ8ýôÓ ï¨BýkÖöíÛÙ¾};åååôêÕ‹9sæ0cÆ úöîÍÃ×_Oq$º³ÎBÙ¹_:í ¦- ± ×~&Ïú7+sÑÝ“C °[U‘"*† £rèPê?œòAƒ•–â/.î´>QŽãÐÒÒÚÁ…^ˆmÛÒ‡ƒÁ áp˜D"ÁÏ~ö3¾óïЯ_¿/”"¼uëV*++ ž…*Öç­™3grë­·òãÿ˜»îº‹–—^âƒiÓ0šš`!<ݱsÆ~ùSÖ‚ÅVU‚ÕÕ„ª«éÒÐ@W÷4¯¼ÿoÝ`ß¾}¼øâ‹hšÆÔ©SzÍèÑ£éÓ§'œp§œr W^y% Lš4©pbW¨`}¥ë:üã™={6ÕÕÕœzꩌõùøó¤I9,\ š`_Qñ½{1mK’ˆvïNÅ ATMíøñÕÖ«­Åï&£tæJ§ÓL›6ͬƒÉ_N<ñDïdu̘1ž=0ˆÁ7Þxƒ?þ˜ë®»®ðj.T°¾®J$Lž<™-[¶põÌ™ÔìÝËæ_þÓ4 wé"d.C‡Ò²y3û6n¤rð`*‡ ÂêŠ ¿_D¤wÒe¹iš,[¶ €ÓN;öövÇ¡¹¹Ù»¦¦¦†ÚÚZ&L˜ÀÌ™3áÀùYÝÓêÕ«¹âŠ+8óÌ3ihhèj…*T°þµpáBÎ8ã Š‹‹]VÆŒiÓ¨6Œ¢úzÁÓjl$\QAäKªÿ¿îºýöÛÉd2¤Óin½õÖn4hªªrÌ1ÇpüñÇsì±Ç~éûzôÑGÙ°a'žxb!ö¼PÀúºjÕªU¼ð ̚5‹É“'3{öl"‘ªªvêof¶kºøâ‹ùè£xçw<¿rŸÏG8¦OŸ>^ØBEE²,sÕUW1qâD¦NŠòwð¾ZZZ¸ë®»hllä¾ûî# ^å…*Ö×Q¿ýío™7o/¿ü27Þx£'/éLõÊ+¯x§zgŸ}¶ç•­òòr¯k?~ü§æÝÍ›7={öx{­¿§víÚÅK/½ÄYgUx•ªX_WíÛ·óÏ?Ÿyóæñ£ýˆ³Ï>›Ã?üŸú˜î½÷^fðÜsÏàW‹Å<àÊÊJvðyêÕW_eâĉ…W欗^z‰†††/Å)3M“×^{þýû4m§©©‰+Vð­o}ë-?OmÞ¼™gžy†ºº:¦L™‚ü ðDël¥vöXVVÆÿþïÿ²wï^&OžÌYgÅìÙ³4hÐ×bâ¶qãFÚÚÚ}¾iÓ&ÚÚÚÈd2Þ˜7|øpïú‰'rá…~阩X}ñjlldÁ‚yä‘466rÚi§QZZŠßïçøãç?øÁ§\(ŠÂàÁƒ?‘ÇY°`½zõ¢G½æã?æì³Ï¦¤¤„@ àîf9n–e1wî\ŠŠŠ5jÔW®¤H¥R\ýõ¬_¿žc=–óÏ?¿Ã eÅŠ¼ð \uÕUŸëë=÷ÜsÌ;—d2ÉØ±c™>}:EEE,_¾œ{L&ÃyçÇ·¾õ­¯xÕo 2‰‰DXºt©g•;|øp}ôѯ$nÿzíµ×xçwah·fÍš®¹âŠ+ðù|Äb±/‚W_}•Ç{Œ¡C‡~.s»B‰€“Í›7³fÍ‚Á £F"‹±qãFÖ®]K4¥¡¡¢¢"šššxÿý÷Ñ4=z0tèPæÏŸÏ¸qãƒhšF—.]xúé§Ù³g?ûÙÏ8ôÐC;˜¶´´°lÙ2ÚÛÛ©­­eÈ!ìÝ»¿ßÏÎ;iii¡¹¹™êêjL$aäÈ‘<ÿüó̘1ã Ï!NS__Ïã?ÎŽ;øÙÏ~ƈ#2d ²ß|óMŽ<òH‰o½õ±XŒ]»v1vìX’É$Ë—/`ذatéÒ…?üd2É®]»¨««# òá‡Ò¯_?úôéÓôî»ï>ºvíÊÕW_ͬY³xå•W8ᄼÛ/^ÌÂ… éß¿?G}4ÍÍͬY³†p8LCCÃ`]VVÆ]wÝEII wÝu<ðW\qwÜqguµµµÜyçÔÖÖÒ«W¯`}RMž<™®]»ò‡?üÉ“'3qâDn¾ùæ/½×uÝ‹B¿þúëyûí·Ù´i3»ÊºvØa]ŽOœ8‘ŠŠ /^ÌË/¿Ìá‡^`’Fmݺ•»ï¾›úúzŠ‹‹0`ÍÍÍÜ}÷ÝôìÙ“íÛ·³nÝ:Î;ï<zè!R©õõõH’ÄàÁƒYµjÕ'’mý~‡Ÿ“mÛ<û쳬ZµŠAƒaY}úôá±Ç㤓Nâƒ>`Ñ¢EL˜0§žzŠ«¯¾šž={2hРƒ¦RRùýþ‡ad2âñ8ûöíãöÛogĈ 8D"áYLK’Ä’%K˜1cóæÍcÅŠŒ5йsçÒ»woTUåÅ_äW¿ú•7žêºÎÛo¿Í/ùKŠŠŠ˜8q"K–,éXétMÓhiiaË–-<üðÃtïÞÝ»w³zõjf̘ѳ)GݺucëÖ­$“Iššš3f ²,SYYÉŽ; €õY5fÌÆŒÃu×]Ç+¯¼ÂôéÓ™2e ÇwÜçúÿ6làƒ>à÷¿ÿ=/¼ðÂAÇ€ã?É-_ħ~øðá >œ_ÿú×<óÌ3wÜquÔQ”••Ðé õÁPTTÄ\€ªªÈ²Ì¼yó(++ã‚ .`ãÆ\}õÕœwÞy477SWWÇGAyy9º®ÓÞÞî d»‰I“&ÑÞÞÎÀ9äC¼ÛÇ¡­­p8Ìá‡NYYÙ{©±cÇrÎ9ç0kÖ,öìÙCÏž=)))aïÞ½Ÿú<.\ȤI“hkkcøðáž…@÷îÝ0`'žx"}ûöàÔSOeÀ€lݺ• 6ðÀ i×]w;vìÀq&L˜Àé§ŸÎÊ•+?~üðCÎ9ç,X@(â‚ .`Û¶m\uÕUÞ÷>¿,ËbÙ²e¼òÊ+\ýõÄãqdY&‰`ªªz«‘¯«¾Ñ[¿ë®»Ž9sæðá‡rê©§rî¹çt|ËÖœ9s8÷Üs9ãŒ3øÞ÷¾Ç÷¾÷½ÀjöìÙüîw¿ãöÛo§¤¤„«¯¾úK‡j\|ñÅÜxã´¶¶rçwé*‘HP\\Œßï÷+‘HPTT„Ï磤¤„L&ƒªª\zé¥ÜvÛmÜyçøý~ŠŠŠhêÁÁƒIDATmmõ¾Þ¸qã˜7osçÎŲ,6mÚÔa_õ£ýˆ^½zqçwòóŸÿœd2éÝ.Iøý~|>¶mÐÚÚJEEŧ>#Ž8‚yóæñ‡?üx<Þ¡Kß¿$I¢k×®H’D:ÆçóF ‡Ã(Š‚aH’Dee%~¿ŸP(Dee%@˲:|­@ @$ñZZZ>1=ûý.**"P\\ÜÁ{ž={6—\r ={ö$‹aÛ6ÉdÓ41Mók§Í¨ßô{}}=óæÍcíÚµL™2…矞W_}Õ»}Þ¼yÌž=€¶¶6/®ªGÄb1|ðAï·aöEdY»víâÞ{ï塇âÚk¯ýR'PUUUL:•Í›7süñÇsÚi§qúé§wzNÙ×Y=zôà7Þ`Ïž=õõõ,Z´ˆ¦¦&Þ}÷]ºvíŠa¤R)Î=÷\Ö­[Ç•W^‰¢( 4ˆõë×3bĈ¾v&“éð·,‹d2Éw¿û]&L˜Àe—]F*•úÌǸfÍïpeÛ¶m<ûì³ü÷ÿ÷'^¿ÿý~ZUTTÉdX³f ŽãL&¿ˆÝï÷3fÌæÍ›ÇYgÅ«¯¾zÀ´ I§ÓèºN]]/½ô»víbùòåTTTpðþûïóÀ0}út/,9‰PYYÉ;ï¼C·nÝhjjúÚÓ‹þ%Þ5%%%,_¾œ††‚Á ·èùä“lß¾Ÿÿüç(ŠÂÉ'ŸÌ¹çžËW\ÁÝwߦiœwÞyÆí¯£:=ëóÖâÅ‹Éd2 :”x ƒøÚk¯eìØ±Þ~¢°ÿ׫_|‘‘#G~%Þ^û×þ<¬wß}—êêjêêê ßø¯¹þeëÓê†n`È! 2„ž={~ê…*T°:wÍž=›ÆÆF.ºè"ªªª ?ùBªX»öíÛÇ¥—^Jß¾}™ŸOÑ>Ÿâ¿YhOð@ðªih¿ßïï÷ûip =Áå–œ7ÝÕhJ>ÓÏÑE/íi šÐmðº³_=J…™ƒ¢öÄ,ܰÀ\ÁËEd¸Žö¯µAå6¬uNßœ9hOp‡ì6J^?Ú3ÓžÈàlÏù~ “»í­ý ØJ÷?µÍ5/€3óýÿ¯?—eï¡mOíëÑ÷ÕîÿQÙ/€Ž²õ}†“ÚöÄ~å|gíþ§¶ ^ e]¦ˆó^./€îȺ/€®².«Ìâ´À4™@7Ö»ö¶wïÅ~ﻕ>´­•`\»ÿ©m2/€ÆÛþ÷TÛÛöV€ Ýî^³ÿGeûüÏKcäí}%¥,¦X®oOŽ)-3mxÁˆ£÷¿÷²ŒR@𺽣ÔY^]ê9€m§„”¼àfî6¬åﳯÞ/l+ǘõ•~ÏYK¢”|÷Ñ{s—UYß#ó„Ôþ·CÎyëÊeCžÚßÒïÞß’eUV‚×…£}åP8[wCYIËK¢äf]±AÔÑÀjû·[‚@cÙרe+-_j–HðBö e]k'?Ú4oí´æz<ö'x!C#™É×®ž \%e;º¦ömíäíÿµV±fè(uúÐFg?{ÙR×Ô–Ö ¥åŠ@ìN;‹iÃÉ29´Ý>CƒöV—D©Ù¯’>(õù‚ÃbÓ ç:%žksÛcºNT²íÉýÍùîØ(Û¿}Vìó=aã¦N_vÔ„Üן Vgö«vÿSÛd^È$î^:J> x€à%kQ€7ldpÆX ç’Þú›ØR)ûmûíw/—’ûù©ý}NlÐlIY‹ì  Z¡v[*e¿íéåRr??µÿ©à´ýlO•Ç€B ¦áºyt«|hû›Ë¥”Þ˺Bêh±JÁKgÙe9Lÿ1S2úþ×<ËVðÀ”:Ñ{½=ºŽÛ¬ ^2±×ö¿f¹ÁËh_9¥·ºÄuç³çÀ•³ÿ©kb‚—S9& `û;µ\#¸FÚÁ LFBãêµ7—KÉùîÒýßÿN-ô–žN ‘#0C - ëà+ô#àÔ¶+~¹ŸŸ ž5˹t¼Fy:ÂHOypNàÚzXòzÎö»ëtío»®ØÓ†2>þLBoº ^®³´ˆuú€àe¤Ï‹Ù°s‚—N€Ût¹$Š”CYÕQý;zJ{‹K¢¤ÊV²\ÊæuýK9`´ uÔ†b«å%QRe; Ä©íßNVêß 0åp8z ÊvéX¶Óò’(5˽¤¶/oŸ¬Ò´4Ô¸LñpWÇ­nÑJV6b]ÌC>ÛÐh_9`–6òŒTì "Û²·¥Ž_9”ƒ‘ƒÖZï¸vÕr&¶Ÿ*mæš:þÞe#g®¯‡#ÖÉšåR¯“€çûÙa‚×HS×.÷’zÏwÄ `ªÊ9ÆfÚYñÀY*^:Jå »ú# 1ªïÈ ×ï¥d^2åP¸IꮽÚeOZY¥ô}±Yƒá0Bà =©vÙ“V–D©yßQð›"x™>Tè¥mÄ:ïÚeOZZ%õ¾Ør/)2/¿r@#kÖ¬3g³)ƒ×ì¥ëLÐW{±Ì¡å^RÇBæ%+ÈÄ^ Ô©ëaÓN¼<­h±=×nïyI”’}Ü¿Ï5/š Ĺ¯DúÞzV£ÓfÕÔ´¡ŽxÎ ¼ ĦAî2¯ýÝ%wud#e,³d_Û˜ç†^ÌÍ4hÿƒ çÁKG ²\¼Æ `¦AÙø‘2 œAà5Y£ïmÚ$t·^¯Ó?î<¼î8 hŒê«›¦2˜/bÁK§À¿\ó °ž§¨F+‡éB@æ•Ùi*‡^:|åP@ðæãº4‚ðz r£‚‚^ x x€àpš»ÝÉ(x€à‚@€iFÁ  « å¹˜‚WÕ¨äóùÉÀEíC{z&Ø9ÆýXrOlí¨Çε;ÚÓÕÓiÛ}ªé/z~?çÕÔé%÷ƒï8¡æ£µa½ßú¬šï´ ЊƒWèÄÝÝhs>_…í ¢Á«ÕÑe/Ó=LšÂå­¶þVÝó½ã~ï÷ìÉÁu€ö…™WÎTCntÝ^#3Ò‡síC{‚Êàk0©†¤‘AY›Òž ßç×I«p½´#Xy‚^°ÓÍ5/y xÀS–·¾¸ôG—û÷=‹Ñ:Çs¶ÎÔÖ¥Yã´™Ò~²ôõ7êÖòÖ½bIˆØßù-˘ðŠ:úÛXù81Žœ~òÌ¿U·ºž6\Ÿ·íl4Àxç;ûsóJãÖƒ™ÚB¨ŸÁÒ뎇FË¡i ÑŸc à#e\Ü“™ŽÖæG*ó2ú ›i$½Ï@·Ç"4÷¼}mœF¤ê†é³9sëùNµ‘Ôë©6”P—~oêógÔÔ´aIjk”nŒÛ롎9ô7ûF´þÿú¯åc}ÅtÈ uÉr+ÿ®ŽËÈrÚÁþõÜl/ÔžJ¾·ÕºýVÝz%óºbIˆýI=zúJßÂ1Tgž;N#îbÙJl wU½ˆ}Nî9º¢>„¾;tîK_«n-oV¤’“Tò~ëžóÓâ>©3÷'Λдâ™À·ÍÂRA¸´ ¥í¡¥ºµ¨žãŽ0·•§dAQÙ+ägê±vúïœö”“-i“žmp®}0˜\ÿóx(ARæ2/Øùµ[pR¦tIEND®B`‚snd-16.1/pix/gaussian-noise.png0000644000076400007640000001232111147553267014600 0ustar bilbil‰PNG  IHDRú˜ÍÐôlbKGDÿÿÿ ½§“ pHYs  šœtIME× #Œ^IDATxÚíÝiTSgð'$µ‰È¢"‹u`@@O±öPjmPÆ—86S{N‹"Vk°T»c;S:ÖéÌh+ØjZ!¶ãrE­k+PÛš‚€QÜ";È „-óÁãm3U×çwŽnrs“ûóxß7Üû^‰Åb±€ˆDÍŽ% bЉˆA'"ˆt"ºKAojjÂôéÓQ^^Þå ÛÚÚ°sçNx{{cãÆhmme5‰ú(Ùÿ?ð§?ý ÇG{{{—/üñÇ‘ššŠ¢¢",[¶ ûöíƒZ­¶Z§¢¢¥¥¥¿ø!0`À¶F)((€¿¿? Á ÿäÏþ3Ž9Ò-?zô(>ÿüóNŸÿî»ï`0P\\ 777¶FQ«Õ8þ< Á ÷Œ9sæ`Μ9>Ï>ûŒ­@ÔÛcôÎŽÌË–-éS§X1"1}Íš5(((À‚ „Çrss±nÝ: y{{#44jµ b5‰ú(ÉÿŸë^RR‚ºº:H$øùùjjjPVV(•Ja]£Ñˆ+W®ÀÕÕŽŽŽ·ýæ7ºî£÷,///ŽÑ9F·æææÖ!tŽŽŽ7 ²R©ä¯¹Db£ƒN}Œ^¯G^^ AwÝ©ÿ;tèjkk1nÜ8ƒxD'bЉˆA§¾­­­í¯W ú¹×__~ù¥°l6›Q\\ÌÂ0è$fz½K–,a!t"bЉˆA§¾éÕW_E}}= Á “Ìš5 pâÄ âÙgŸpýä³ÙÌ1è$ùùù®_QØØØˆádz(Ä ß‹jkkqùòe‚A'1;zô(Ö®]ËB0èDÄ ƒND}S¯^îãミOQWQQÁè»wïîps bÐ{Œ^¯·ZŽˆˆèòtë,K§­xzzÂ`0°Hìº÷‰DÒáuÖÖV„††²Ä1:ýdÿþý¸zõ* Á “˜­[·Ž×§sŒNýQYYvïÞ @.—#55•7n ÑÅÆh4¢°°AAA „Á`@uuµð¼J¥‚››´Z-‹Å “ùûû###ööö(++cAtåM&ƒƒƒ Á S§P(0qâD‚t19r$YêØ£c ÄA*•âÍ7ß¼¥u·oߎ+W®°h :õ»®™"""niÝ£G²`캓˜¤§§ßôÞöÄ “ˆxyyA&û©ã¶téR,]ºô¦ë^»v &“‰EcЩßÕd2Èd2øùùA¯×£­­MxnýúõHMMe‘t‹¤¤$¬Zµ ,ƒNbg2™ðÉ'Ÿ° :‰YCC’““Y±ÙXñJLL„‡‡G‡Ç—-[†¡C‡²@ :õ'mmmVsñÝàïïàú¯é?çííÍ¢±ëNýMhh(Ït#:wã,¹²²²“wƒN"1þ|!ð›6mbA8F·]||¼Õò÷ßÏèr¹±±±·õš÷Þ{Ë—/‡ úm ¶ZÎÎÎf ôRÐo¹oÕÇŒØØXA¿}áááVË;wîd ÜeC‡ÅŠ+°|ùrƒct+xzzâÂ… ,ƒN}ÕÅ‹áîî¹\~Û¯ €N§–]]]a2™P__ϲëN}IBB–,Y''§Û~mzzºÕrdd$Μ9ƒ¬¬,–Gtê‹Ö¯_Ï"ƒNÄ Ó=oòäÉX°` Á “˜1>>>,ƒNb%—ËáââÒáqÞm•A' ´ú1O§Óá@HH‹#üóu½^iÓ¦±<¢ƒND :1èDÄ ƒND :uî7¿ù FÅB0èÔWìÝ»¾¾¾ðòòê¶mÎ;~~~,.ƒN}EVV<==áîîÎbP—xfuœœ 777‚A§»­±±±Ã­–ºËèÑ£Y`vÝ©/ضmÞÿ}‚úÞ}ëÖ­VËœy”H„A/((°Z®««c ‰-è«W¯¶Z¾xñ"òòòØ D£ÓÝôã?âÝwße!têm‹‹R©‰¤ÇÞgÛ¶m ë0ä"vÝ©;v ‡Fkkk¾««+ÊËËYpщˆA'"ˆtº‰ªª*$$$°Ä ‹Ycc#>ÌBƒ.v>úh¯Ý=U&“A&“¡©©‰…gЩ·èõzà¾ûîëñ÷0`"##1yòdž4àSoŠŽŽÆÆ{å½FŒ?þ˜EgЉˆA'"ˆtú™¨¨(Œ3™™™,1èbuåÊìÚµ ¿þõ¯Y bÐÅL&ãņĠ‹Ö7ß|ƒqãÆA©T²Ä ‹Õ–-[0cÆ Œ1‚Å zÆc=‰D‚cÇŽ± :‰Õ{»?žÅè§zõׯÆF«åžž I Z[[agg;;þŸLý$èAAA°X,Ârqq1[à¬Y³>ø ¦NzW?ǰaÃÐÐЀüü|@@@‡]÷›ËËËÃéÓ§…¿ýíoÙýÄ’%K““ƒ±cÇ⥗^¡C‡XÄ*<<[·nÅ¢E‹X vÝIŒžyæŒ;C‡e1xD§îpöìYh4˜L&„……õ‰ÏwwwH¥R¼õÖ[HLLdC1èd‹ššìÚµ ---}î~å‰'NÄ7ß|ÆbÐéNUUUaùòåHOO‡B¡è“ŸQ*•bðàÁ0l0ŽÑéNäææÂÇÇO?ýtŸýŒ¿úÕ¯°téR,_¾ÉÉÉl4nׂ x±ëND z¿”––Nׯ>s@@î¿ÿ~ü÷¿ÿe2èt+²²²pùòå~õ™ÝÝÝáââÒïþƒâ bðàÁØ·o‹A<¢‹M]] ¥R‰’’¸¹¹õ›Ï¾hÑ"H¥RlÚ´ f³™É Sg6oÞŒQ£FáܹsˆŒŒìwsýòÊ+ÈÌÌdžA§[•’’‚ö»Ï=uêT|ýõ׿ ŽÑID¢££Œ .ÀËË /½ô‹Â#:À¥K—ðôÓO£²²3fÌè÷ûóÎ;ïà±ÇƒB¡À{ï½ÇfÐ ¸þ#\yy9/^ Ÿ~¿??þ8æÎ‹GyÇg3è÷žææfáWék×®¡´´¯¼ò 222àéé)ª}õ÷÷GDD^{í5455¡¥¥…_ŽÑÅëôéÓhiiR©ÄþýûQXXˆÄÄD<ñÄJ¥ÈÊÊå~K¥R >­­­HHH€ŸŸ|ðAÈd2Œ7NXïÊ•+¨ªª‚¿¿?ìííù…aÐû®ÌÌL<ñĨ®®ÆÑ£G­žÛ±cL&FŽ OOO |úé§?~<Ö®]+êºLž<×®]ƒÅbA^^V¯^ {{{Ì™3GX'''gÏžÅìÙ³¡T*áââ‚~©z€ÄòóiY{YDD>ûì3÷«“D²³³…1hee%† †ææfTWW[­÷æ›oÂÁÁgΜA^^ÂÃÑššŠ)S¦ˆ®»~+ ,‡‡‡câĉHJJBee%är9œ­^!C†0©=ô÷߃|ðA—/>uê6n܈¹sçbòäɽô·ß~ñññËå8yò$6oÞŒgžy“&MBbb" ‘H:¼îõ×_Gmm­MEsqqn4oÞøàÌœ9GŽAxx8‚‚‚î(è¡¡¡·}’ȼyó ÕjÑÚÚ ___L›6 _}õNŸ>?þñHMMÅÍ:+QQQ¸ï¾ûl*š··7|}}™Ì^pøðá;> §¢¢Z­&L@KK rssE[§äää.{‰Æè:K–,Á„ ßé ëëëQRR‚3f`Ïž=¨¨¨è°Î† ºì”––ÀÍ^XXˆK—.¡½½_ý5öîÝ‹²²2ÔÕÕáÌ™3NÜ ×ëyûá{DSS.]º„ììl´··ÛÜ“ëË®]»Öåó=úŽŽFTTT§ÏÏŸ?_èVÝ®––¡»o2™PRR(•J477ÃÃÃ㦯3›Í^|ÑÞÞŽÊÊÊn¹kiee%œœœ •JmÚŽÑh„ͽ––ÔÕÕÁÅÅÅæ}+++ƒ«««ÍÛ©©©Á Aƒl>å·±±f³ù¦ÓPÿü{ðKóïY,”——w˾UUUÁÁÁ °9À‹åo™ýKïsKA/))AQQüýýoë‹"•J»ü¢K¥RìØ±“&M²©iiiÈËËÃ;ï¼cÓvêëë‚S§NÙÜÐ*• iiiþ‡s«Þ}÷]899Ù|ÄÜÜ\¼ñÆصk—ÍûæååÕ-S]=÷ÜsÐh4˜6mšMÛùÏþƒÌÌLüãÿ°i;íííðõõŹsçlÞ·™3gbíÚµðóó³i;ëÖ­ƒÙlF\\œMÛ±»ÙôäÉ“HKKÓO> àúŸ‰BBBpäÈa='''xyyaË–-2dˆÍ_h"ê9‚…B’’üå/<üðÃHLL´º±Þý÷ߨ¨(\¼x¬&Q_e¹‹þð‡?XŽ?nóv.\¸`ùþûïmÞNss³%##£[ömïÞ½–††›·“››kÑëõ6oçêÕ«–¯¾úª[ömûöíݲ¬¬,Kqq±ÍÛ1 –œœ›·ÓÞÞÞmû6cÆ KAAÍÛ),,´œ>}ÚæíÜõf/^ló¨¯é®1zu݉è£÷&777 <˜­@¢ãéé ¹\Þg>Ï]íº»îDÔŸ‚¾aÆ[úƒaa!âââîè”X¢î¶gÏüðÃVåçç#..Î꜓Ʉ¸¸8lÙ²Åjݤ¤$¬ZµÊê1­V‹¸¸8\½zµË÷.//G\\¶oßÞ?‚¾~ýzX,¨T*ÄÄÄtº^qq1Ö­[•J…ƒâĉü¦Ñ]³ÿ~¼üòË(,,3 øè£ R©™™‰ììlÀóÏ?•J…ÚÚZ!ì«W¯†««+|||°råJÀ_|ƒÁ•JÕåä™ÍÍÍX±bT*ôz}·œÍØãA?uê|}}¡Ñh°ÿþN×38þ<4 Ìf3Š‹‹ùmë&S¦LÁïÿ{â6<ôÐC.k­¯¯NkjjBII €ëWØi4¸»»#//pâÄ cÊ”)8vìàÌ™3prr‚F£érN½¶¶6äää@£Ñ@¡PtË)¹¼ŒKäBCC±eËTWWcÑ¢EøûßÿàúE.ÍÍÍpvv†D"Ùl†Ñh 2r¹íííV]L…B³Ù ¥R ;;;477£¹¹ …F£f³‰ÎÎÎÂs‰:t(d2Z[[…«È ˆšš8::¸~ÑQ[[Û]ÿkŒ““S·\ÜtOÑÿ_ee%rrr:ÌÈBÝëܹs¨¨¨À¹sç0a¤¤¤ %%o¼ñbcc¡V«‘••…††lÞ¼jµjµéééhjjÂÁƒ…ÇÆ­V‹Ù³g ½­#GŽ ..ƒñññP«ÕøÝï~‡ÜÜ\ìÛ· .ÄêÕ«¡V«‘‘‘³ÙŒ;w ÛüðÃQWW‡GyD˜\bÛ¶mHJJºgÚ¨¾¾999Bï ß=((Ðjµ˜5k ##ÁÁÁV·Û2d||| Õj1pàÀ{rª¥î¶{÷n”••á“O>±züСCxî¹ç´´4äççã_ÿúbcc‹“'O¢¦¦111ÈÎÎFvv6¢££;}Ÿ?ür¹±±±ˆ‰‰Ajj*à‡~@HH²³³‘˜˜ˆ’’$%% ÛtppÀÅ‹ûdíΟ?üü|œ8qB8 988ÀÛÛZ­ƒ .ä ƒV«ÅåË—1~üx@HHŽ?ŽÌÌLL:ÀõÛLWUUA«Õ"44ðí·ß"88›7oÞ[*•bÒ¤IÐjµ0Ýrv]}Ñ¢E4ht:pa`` V®\i5#¨››–.] N‡°°03©6zñÅáííÝáòÍÈÈH<ôÐC úè#áÏKß}÷^xá8;;cïÞ½H$Éd0™LX¸p!þýïãêÕ«°··Ç?ÿùOdddàÀÂûâÀøüóÏ‘ŸŸàú‘‘‘ðððÀ†  ×ë1{ölL™2… ×ÍøcœÈ­_¿ÂòSO=ÕaaÆaþüùÂ/Æ7ŽæQQQ¯Ã7få™5kagg‡1cÆ ¢¢~~~4hÊËË…‰F&Nœˆ1cÆï‘’’GGGDEEáÛo¿øùùÁÝÝpðàA¬X±BèiP÷ânɪU«0zôhDFFvû¶üq¤¤¤ÀËË‹…î!ÿ–$ë PEÝ™IEND®B`‚snd-16.1/pix/mixcmn.png0000644000076400007640000013257611147553267013165 0ustar bilbil‰PNG  IHDR„$ø¯h« pHYsˆˆÈ¥†tIME×'2Kà×þ IDATxÚìyXSG×À' I€a_‘MT@Á_—"îVT\›¸Ö¥¸µo­µZë'j­Z+ÕŠÖºAµjµKbë† "‹bŽ‚,²£ìK²Þï±÷M–Hd9¿‡G'sçÞ¹3sîÜsgΜ¡8::6 €©W$ÞM46lØÎ_vVUP#€ÞH­JMŸ—n€*“•Ê +í˜Õ̆é!Cþ—J¡@YY¨´ ùùåЊ+’¡âºŸ+ iFÍ•IÅÙVb‚I÷(1 ÒèÍ%Õפxöz)·—°ZÈ«U¾t1)“•!„ B2…L¢ˆ¥QMcVVá!ï”––Òét+++*Šz8!)Lب±D¢@St=hƆLc™TÔ´–ÙÐØÐXg@732¶’ËA¨§QD}]Xn© Ë„- ›¼”\¡¨VI ™BöJ•*¤²FSÖ󲜺ºº/^XZZ …Âüü|D¥"*Q(rBÞ(k„¦ 3be`eN3Ïç*BýhzEƒ@. Ñê¥,i–ƒ*y•Œiw3ÆTcºC‰´¤^QM@GAÁ”IšÓ %õR¹„K¤¸w÷aè÷¿¨§9yh£\*ËÄr…B.ýîûŸJʪ×|ȱ²4CUU×î?zÖœmòÉò÷äri£¬Q*—¢ÿŒÊ%uõõææìÒÒ:Îd2“““{÷îMý'©T*‘ÃÈ(C—Aƃ>þ´Ï;}ÔŽ2u/û^®<—eÅjõRýûÔ\,¸hÔËH»›±§ÙaùîÊw†ƒ ¡iè A( …¼™£ ™\F(¤ˆ „¢¹4RHä¹1a´ßWßžÜw„¿uý" •òýѳ™Ï ¿\¿PA(ä ¹D.ù×ȨX&KÄ ÃÐI§ÓBt:ÝÙÙ¹  ÀÞØ˜*W—5”‰ÅÐTtz3{4)oË,½.½ŠVÅuàæˆrŒåÆ CƵ’k••o±ÞÀP",1¦#„RÒS&ŸìeäÅ/âËÌeDA˜SÿãøŸ>µ}®æ_µr±b2Ä@d€ Q¬ ¶X^<†=Æ•îZ+¬¥2©OkžºYºQØ”ùNóÓªÒ‰Dc3c„…Åh³Ñ¦RS‘XTN”ߪ¹µÚ}u±´XÚ(µ6²N¨IH¥ô3í7Üd¸@ h¤6"„JòJ*zV °M @G@A(„\¡5£hÊ% ‰\B ‚P¬X<Ù¨·r‚#?E*r…B.–7ÊT‚»:Û}¹þýïÃϹëF-¯lù|»«ƒB!—)¤b™XªPUHÔ•\+++:^œ“ÃÎÎ6ruµfYKjad€ŽB/F/º”~ñÞÅg5Ï*Ë*ÝßrG(åqÊ­¬[_ÏÿڨȈ°$|l|®'\¿–zmõôÕŽ=B© ©w"ï$I’úOèoÊ4Eݯ½?ÈxЃô?ßû¹¸®øˆçBH<È}0¸ïà¾â¾Õýíûýœð³‰ÊjÊìfرåìƒWæ‹ò.ŠÁ¾ƒBfT³^Œ^‘"ïÞÖ «ª‘;ª-©=xùàŠ R‡Ø¢ØEC••ì=¿wâ;û î‡R ØâÐqÔQD(Es£ž„L!%R„‚PàaT•!G„B"—È &"B¡pq²ûxiÐöÝ¿(bÓÚ¹î.„BA…B.Q(ŒÊ¥ÒFsKsK‹¤¤gùùùÊ—¦Òhµ·o£~ýD¢F)ØŒÐQ¸+¸[Q[áãâ3ÇeΩ¬SBèÎó;©V© ªÂ@fP\PlÔÇèiéÓÂÞ…¥ÌR/ä…ÊåÕxÕÈ Är1]JG5J Dê%v%¶Ãmí í*ê+XTVjVjyMyjQê¯f¿öõþ`Ô¦–¦ë¬od42ÌBZ!ó¦9Ó\!WH ivCö¹šs½,{m¸ánÍÝß^ü†Jzž”f’&4šˆM s ÙÃÙw_ÞͳÍ+´*ÄE+äЯÐa BÍLÁSE&—)ä2„(ˆ A4‘’@QÅ2±‚`!BQ]S÷ëñl6‹J¡üúGüÇKƒ¬,L)È@A(¥*6£ ¢ ccc‡Û·oÿëºr9êß––jÁbK¨ð@GÁ‘áXª«„U©-K-,B SS …‚HÒŠ)C¦8‰™Âgù™ú¹Ø»Ü(»ÑHm$G%Å q¿ÞýMëÙõyyFr£äÊd#C# RîéÍêý¼ú¹±È¸7£73›ÙèÒèfî6¡ß‘•¨¯I_…ScflfÄ4J©Hq´w´ÙR_Pñ8¡©!ÀR(¹¢Üÿxþ‡ÃâØ¼… `d€ŽEø©k©êLý˜¾®ÎörB¡PÈ(T (j+…B¥JäAP…@”C?]ÎÌ~òÙ\º}Ï/?»´yí< •BPпFF% ‰X&.­ö0wñòra³-„BD"¦Ñh4M"yÕQ)JÄ ° £P&.ëÙÐÓbx2êäåG—F:$d&”×”£èQÉ£ô¼ôB£ÂCé‡þƒþêaý^ô»‡‡B¡+Äyòž>³fÕD„ÐéüÓ½ëz{Ê=/Ç]+ÜKæåiãY×PŸong.löB½ªJ«¾IüæiéSz)½Ž^çLwÎxšQhWH+£¥–¤zòrhtp¢;Ýzÿ½ …6…‰E‰™™Èå6äÖ¦×6HŽfBbWow5îj±kq¹ \A(Ä2èWèP¨Q%=5ªöK¼\Üœ{H2ŠBЍT„PN~ ƒn œ¦²JH D¥Påb"…rø§Ëe5!ŸÍíãÖ!´yݼ~¼øÃ—V­˜¥ ±L¢d3*—Iä3Sìg©ùy¡@ˆâäähmmE§Ód2FW E®¼@‚à €ŽBjmjTIT°Ž ªµ†Us ÿ@•m•…¡Å±¢c…´BC ÃÔÇ^«­®ELD­¡RûSoUÝ*”I­¥FR#ò«þqãã«/®ÖV× ÂZb]¡¨(+*“Š¥Tkª±¥qdeäË‚—b‘˜B¥˜½mVK«=U~ªº¬Z.“2 åµr…µ"¿.ÿYͳ²â2…\Au¥šÙ™.8\Ì,6fGWDçÖå*ìÕ¨ú¼à|Å‹ U•%ë-³PX€—:Œ2JAˆ²la \®:ÿîÒÛQ©rBŽ2D¡8÷²‹¥*iÆ|Ë€FCTªT.QBhÂè·ÇÔǵ'NàæÜããà©(ˆJ ô¯Õô2…¬QÖH¡Ê òóËË+Bnn.l¶™““#BÈÎÉår™\æ,sL®Jƒ– ã`ÝËÚYÿï·=bÛ³qÐÙÛ¬zXYõ°R>˱Ÿ#üÏw2Ù8ÚØ8ÚizyôR>¥§{OåŸlk6ÛúUFÈîÕÿÆÆÎÎÊÉð=È ¹“§Ža±Y,ö¿¼Gÿf:2©D$U ôroò¨T*–È…´±AhllÍk¯j-*zA–¢¨è¥æ'þòËÙ/¾øä€ŽCXØÁ&ÃÊýûÔ©“,àâd.\>s†²··ýþûoKJJãâæÎ}!T\\róæ_sæÌzÝOŠ=züñÇ„о}ßôèáðé§®_{ô艩©Éþý¡v¹¹ù_|ñ¥‹KïÐЯHí|Æ­8üÃ{lm­ÃÂZ[[_ºt!tèÐwÖÖVYYÙ!!ÛqšÃ‡÷ZYYÂ3€Nyü8i×®0>}:ª+?4šÁíÛ‰¡_=F£5m J¥P©J#£-ÙŒÊår¬íúûûä“!:Ý Uxᚌ’lß¾;<ü„‰ ëøñƒ¡#GŽûûÛ²å ¡°vôè)ß}÷5BhëÖ F”—W Ô!4qâ8_ߎŒVUU#„’’RBBÖ!„¦N 8Ðóðá㤠˜˜øßjvvîÆÛ>ø`ÁÓ§iAAuyy #%%ýuÛŒÇ;·nÝ*|M\ûöíRuqé­RŸ6lU©½Ó§y[·nP¾NHÈv2MXØÁ5kþ OíÈ“'OIýD,#„ví kUÁûþûðŸ>‚•Æ”@ÒfÔ½²¥4w4­UUR±XLÞý“'O[M¿yóçMNÓ›™™/l— šxêÔoeeAAÍ¥¹párNNB¨®®žÍ-..ýõ×?-š«E¦½z9Κ5­í7ïææ¢rÛS¦L$køðá½ðÀоøúPV=B'‘ê‡D"mò¬Áƒùûkõâ4DQ²¥PÛ}5=“ÉÔB…mJ©•üýwž—o¬¬l skk«Òxx¸gf>·°`+[»ª0mÚä]»¶’?Ÿ?ÏA¥¤¤Ðjj„ZÜ¿@ LKËhîþ 6X»šéÓÇíµÆžÚÈ[où´ªr¼|Y\PPäääØr²Œ"mlFp¹‹¿øâÓ·ßö•H$ ,Ç16¬yë-Ÿ>ZJ*Κ،âizÞ²eýøñ£ÃÂ9rœÉdâø­[w]¼x…Í6{ÿý9|°!dnÎvp°ãr÷éã¶fÍG­ÞùûïϹwï¡»»+þyñâÕ£GÊÎέ¯oøá‡Ývv6, ß6¶µ··322lllœ3罈ˆ“8Óàp¦“¥ærgà÷'ö0{öL3gάÐÐ}µµuØÛŒâÚ;pà[;;ÛiÓ&“×!íYÕõor]›v£¶¯Å¨Qþ¤Š‚mF=zº«1gÎüH§ „¾ÿþHAABè“OV6w)*…J£PB‡3÷Û)|ß †½éÛ³”V®\#t-·cÿë‘° oȘH›Q*"šH÷×_w÷ï?¢¹~ýj?¿Aíu+õõ K–¨Î°?zÙ²EíXàíYYÙÊ166ÖîiÇ,Ξ=ÏãW‰ Û Ò@§ãðáãqq·T"þù(“ÉlùD ç„_éŸxš>xÏL>ï¡ðiz@׬\¹Fæ.°cìó?ñè(†`oz@OÐÊÞô T  'e”¢ägk¦L&óÊ•h¨@§XYYÖRiJ;0Qhˆjnn¦µvÐòòò'•%ˆ‚ð4½…f®}a@¡ÒH›Q*¢P(£€ž  *•BAxš¾ ]Õ€)“‰Ê+ªlm­ B¡uNTª£Ý _QQŽÃ£G¶¶¶ÖE5EGߨ©©ÆáñãÇ›››wöKJJÎÌÌÀa_>­žR^^‡Ã666£F‚Ç UnݺUZZŠÃ#íìlu‘Klllee%3ÖÊÊR¹DE] 8üî»ïš™™é"—ªªª˜˜¶´´;v HQ«Ü¾ýWqñKö÷÷wppÐE.ññ7ËËËpxÔ¨Q666¤øiié©©)8ìééåååÙê)55‚èèë8lnn>~üx¢VILL,**ÂáaÆ;:öÔE. %%%8>¾ãÛ¶mä}ùå—šœòäÉò___!Mxï½÷ÈJ;{ö¬Žr™8q¢Òp”ŽryçwÈ\îܹ££\ž={FæÒ¿¡vA"©'õÃ'}¾wÑÞ¤/ìÇØ7=2š'Ë+`¾D±Þ5¿R‘ G[¾‘‘U]]Óä)ê-ææì=ìá;hƒfâ‰Tqê¿fRî¥|ûÒ¥k¯æûô雕õj¦ØÃ£o] G6ÛÜÎÎ!33B¡2êÐBm ™›³BvvöÆÆF½úéêêš™™fccmggG§Ó˜L¦¹9»G„ä*W J\\\üüüšÌE"‘\¸pÉdN:Z  £Í"z*•jccSWWkaaÑÐ RRU)¦¦¦ ÅÔÔ¤ÉcccI[ŸØØØäää&“………!„„Bá?þ-Êè¿°°°,--FY[[Òét2ÞÅÅU"i¤P(††L‘HÔä¹gúôéÍ]üèÑ£ƒæp8 ,J¥qqq]¬ÆÉuÓ]’®]ºŽVd¡P(‘Hº| ‹Å⺺º"`oðêëëµ;Ú¾ÔÖÖ644ÔÔÔÀTC©¨®®V(ºŒõõõͽÖ;û+£¾¶: ZœcllÔØ("ÃR©!dffN¯&åíìlKKËÕO3敟—°°°1cÆ 8ðµòݺukZZ§§§7™&%%¥¶¶¶-52pà@‹¥a⢢¢ÂÂÂוû×òCñÖ[o1™ÌVß )))-§Áͤ5ÙÙÙeeeí^:}bccãîîÞ.—JKKm)²···©©i«JØãÇ[VF Œf]§ùøø·œKCCCRRR[jÃÄÄdÀ€íR±¹¹¹¤_’ÆÆF™LfbbÒ¬²²ÒÒÒ’B¡4—@Ù7BIOOWVøêëëi4š¡¡a“‰ëêê TŽzzz²Ùl ³+..ÎËËÓP¥Ñh‰äu½ÝiÒ»ŠD"åÅòM¢PÛä;??ÿåË—í+-‹eUU•¹¹yo[™¡C‡¶ „¯EFFFUU•&Ê(•J522R?Ô¿ÿV%A&“=xð -¯ //¯VÒµÚg¶Ú|†††Ê^tÚBAAÁ‹/:µ‚øŸÿü‡F£½IeÔ±j¯V#DT”WÛØZ„™ÚóEÓŽN§“ʨ™™Yvv?z”TRRŒÃÊ#¦**QXXØ»ï¾ëããóº÷ºuëV2³ººzÀ€ê}¦\./..f0mÌ¥±±111ÑÀÀÀÞÞ^ýØTcÔ …B¡P¨9hРæ¾;÷ïß—ËÿµòÇÐÐPÝ­»¥¥¥æCx¯§ŒÚØþ7p ¡ n==ö¹üÕT …Bµ±±Åsôÿ|¡R,,Ìñè½²4÷цÇDµÐD›„ËåöìÙ³G¸m—Î×–––’ óçÏ·µµ-..600Àà FFFz{e¾õÖ[ä›w©µµµøåàáááìì¬ìB²I\\\¼¼¼°öÌáplllÈW&“ÉTwíêꊢº T*U½ÉêëëÕ‡ÒÓÓÉþ{Ìœ9³wïÞNNNx¨©]:Üdeeed¯:gÎìð|À€íâù?h%%%¤&ºpáB+++üÒj»ª,¢Êz€½½ýܹs---I1ꪺXv11CMŒ644¨Ï>{öŒ3¬N›6ÍÕÕÕÕÕ5µ‹˜á§¾¼¼œÌ‹Ãá8:: ‚ÜÜ\<šE§ÓõÖ›‘=?ùa/‰ðäÒСC}}}}}}[¾ˆ““¾ŽÍ‚ ÌÍÍI1£Óévvª^Ö{÷î­S û0tèP•‘HTQQ¡™™™Iέc!œ2eJŸ>}ðQß¾}›ü"z]ð'“²˜Í˜1ÃÙÙ¹wïÞ¸ÏìÙ³§.úÌÙ³g÷èÑ+mÿt'•­aÆÉd²ââbRÓZ´h‘©©))fXUU9±W¯^:ÚIäÍŽŒª+ë*c:¡çÏŸãLŒ……E¿~ýÚGmÊʪû÷©)p¾†††ÉE¢WÃi·oß?žJ²cÇŽ …ÂÜÜÜÜÜ\¬KáŽ#<<|Æ X-X±bEhhhee¥X,¦Óé£Gnò6° ÷~ø¯¦ÒQKìÙ³§cŠ×ªU«V­Z…S ŸÀ!C†¼|ù²³›.é“}ûöÙÚÚŠÅb@ ;1 '¿|ðš.f¢¯^½J~ÍëNª===ïܹãáá‘™™ ò£!ß~û­L&«®®ÖÑfr¡_ýµ}ç¦Û‹%K–,Y²û >\C1+((())‘Éd ?òõ×_[YYQUU¥;[—;wâ0æöÍËÊÊêåË—|>ŸTuW'''èÍôÆë)£¡(.~áâÒ[%ÞÈÈH,nÝ´y̘1>T‰Ü±cÇùóç?ûì32fÍš5.\033[°`AËäñx¾¾¾ï½÷žX,NIIi÷iú*P‘_óIIIXŸvttìÕ«—N[H}šÞÔÔÔÍÍ Åf^ ¥ÕÁÑÌÌLsss???•©ö&§ésrrT¦é]]]Õ‡:xš^%²Éiúæ¥ðwZZž¦×ܯI”§é @Ú}âïþ§OŸJ$&“IŽ‹k‡ò4½òp>+mhhHLL466nãLE]]ÝÓ§Oñا‰‰ N•o¤&çOsssU¦éB~~~Íùt ***²²²”cšœ¦ïׯ_“ƒR"‘Ï÷ë×O]>_‹ÔÔT¡Pˆ§éUF@Éiú”””üü|„½½½‹‹‹N+G}š^E, ¥Ri˃£eeevvvƒ 200hUÌòóóU¦é{÷î‡Ó:/NÓ{xx47MßÐБ‘§éÕåóµÀÆÍxš¾ÿþä8¨rŸI£ÑÔ‡Ù´è3i4šƒƒƒòt<î3Åb16zûí·Û’KccãßÿÇ>IáTéÍšœ¦/,,T™¦ïÕ«—££c§3 §éÝÝÝu5M¯#\\\T:»œœ>ŸŸœœœ‘‘ˆÅˆÁ`p8Í/‹§ÿ°RˆåU.—×ÖÖª˜T×ÖÖÖÖÖöèÑ[+ãe2Y]]\.'ãLìÉ”T@‹ŠŠÔMÄÚwE˶Mxb·¶¶611Q,K$\ü=z…B©TJÎ6÷Žg2™êú´zLvvvNNŽús+—Ëqu½n©[M_YY‰ßÖdgŠO!¿ì( ùFWnVõ«59MÿZà‘Q\3iiiäZ:õqL6l! IDATYYNWQ&jkk “Élî«IY˜Ÿ>}JJÔæV `åÒÎÎŽÁ`(ßOs ˜È9&WWW¬’’ïòÆÆFåqSåõ£“Vë–Á`h"f¹¹¹êß«¤°‘˘”yñâ›Í‹Å¸Ô*+EÔ¥B$) *•Jþ‹Ç«?û"‘ˆ ˆV×)Ü´EÒpGk&==]yCž…BQSS£®R´ðÕdbb‚+“l…ââbõÞL™–…PZ^Àdooooo/‰UJ*ŒÉÌ××·IU^C1ËÏÏo¹¤šôQb±X*•’Y]]Íd2 ŽiN\›‹'©ªªÂ¸¯k®º´› U–R+++\3ÿuR=%¢ººÚ¢ººZ]Ìú÷ïߤq³JŸ©Rç¸zår¹P(´°°PYGÆ“é›[ÀD¾ãœ±JÚrÙi4š‰‰ ¹ü£¾¾žÅbãþOÓ·|:®É TAA&b¦ê=©˜™™)‹¥™™™P(433S‡Òä•mnnÞF³õªŒªƒ½ÖÕÕEDD´ñ›ýcVÒœ2ZWWçàà ¢ŒÖ××Ëd2íÔGGGGõOý/ø5556l˜Š2Z[[+‘HÔ õ´ÃÍÍŽ}³Ê(x-e´}Q^½Ô‚2Ê`0T„°®®ŽN§khܬ¼D jsŠ6q¶··§Óé¯[Ê–£R©T$)÷øÊ1‰D,ëÔüNý{µ¹w¿²2jnnÞØØˆK]]]Íf³[PF±ÐÒh4¹\®¢Œ6©t¾®2ÚŽ¨¿ZPFA‡QI“åæh²_mwðp”º2Êb±TÆAµ¦wïÞØœñ(£dŸÙe´Q_½„UOe¥³eeôuûLåê%EW¥oTWF5AËQÜ—âûQVFqÿÙŽëää„WèM•J¥XïTK6›-”{Å7¥¨t\e´¦¦fùòåW®\A=z4&&fìØ±m¿2FSï1MMMñ{7þ—\“ÔŽ¼©f2™L&“ÔtýÎ@)Og¿n©[MßäÊP倊~ Ü¬ú¤¹ûlò3@ëõ:- ª²E[j€N§«tÇÊ1 £7Rúoõx<'H¾³UÞ^êRÑÜ æVr´Ë ]÷-T*µš¨Öýª~JÚî½tÛû(T©ÿæÄ¬Õui–––mœ4o; EåȘv¼7\½¤èªô4MG"­Ü—’a]›ÛéH8•E ¤J5â:l²&;šFƒ7~kÖ¬ÁñãÇw½¥µ@ Pß`Þ\.wÙ²eãLJfè8ìÛ·¯³¯½”QmˆŽŽ~úô)4 (£úÀÜÜ<<<‡%‰»x Œ¶õõõ¤bÚI9{ö¬²·T Ut¾€)//7--¶ÉCEEE|>‡·oߎºyó¦úöŒ*466^ºt ‡ÓÓÓMLLÈ‹¼,kÒ¤Iš¤ŒŽŽ®©©ÑD½s玊_ 6›=aÂÕmRR’žw†ðóóÓµ[ìÈ­[·šÛr½U ƒ‚‚4I«¾i¤†˜˜˜j’2**J}e ±°°7nœ&)«ªªbbb´®ðAƒáí »·oß&7•y] Æ´iÓ4I¯¾›_“}‹H$RéZ'Ož¬£â§¥¥¥¦¦ê³Â}||<<<º›˜%&&iw.F›9s¦&)šÛؽU˜LæÔ©S;NŸY[[{íÚ5­+ÜÛÛ[o®:Am+7nÜxúôé¸qã”+6‡¹¹9ÇÃကhBPF›ÅÙÙÅË˯ÉC|>ŸÃá\½z5<<ïºôZ/aÜÝݵ8ëµÐp½ZZZJJŠ®oFå˾9š Ÿož1cÆè!—wß}W¹XZZêóAèøûûk’,777))iúôéÚå2jÔ(M’½xñ"::ZŸèéé©îhw4ܬ  àÁƒ³fÍÒ.—#Ftœ>3###;;[ÉPuLMM¡7ÓoØf4&&fÉ’%!‹µ|ùrh€ˆ]´hÔ SæÏŸß5ÊrñâÅÿþ÷¿Ð¦ Œ6‹T*åóùدû†‘7f3“˜˜ˆ5ÑqãÆ?~ »ñfFF•ÇD±µ¨òæÚíÎÞ½{œœ ±rèÐ!б>Ù´iÓ Aƒ M= ó‘Ñøø¸“'yêÊèùóçÉŸ7nܸqㆆd³ÙäÏ«W¯r¹Ü–OÉÌ̬¬¬TIfccsðàAMr\¿~}^^^«ÉÒÒÒŠŠŠTrqrrÚ³gŽêöÔ©S‘‘‘ú—•+WêgM‡bÇŽÉÉÉ­&ËÎÎ* ¼³CË„„„deeiw‡û÷ï×$åÚµk [M–’’R\\¬R—ÐÐPMrÉÊÊ ÑºÂƒƒƒõ³ÐªCúèÑ£V“åææŠD"•¦a±X?ýô“&¹lݺ5--M“¬ªªRÉÅÚÚúСC:*þÙ³gI7)úaáÂ…S¦Lénb¶wïÞ»wï¶š¬  @*•ªƒÁ8}ú´&¹|ýõ×IIIÚÝ¡Ê+¾6oÞœ‘‘Ñj²ŒŒŒòòr•²ØÙÙ8p@“\^¼x±fÍ­+|îܹ3fÌ]³U(g}Ø"ïe9dêÔIÿtm6õõå„‚H¸õpôØwär Žÿî»R©Lý*C‡¯©©:t°HTcnß¾;þ<*UÎ`˜°XV*éŒ3°¤ºººž;wnàÀÚÝ}@@€¯¯ï÷ßßêã·oß¾‚‚VåW_}Åãñôì*è8:t諯¾ÒÚ#i‡bÓ¦M—/_þûï¿¡Y;ÇŽûì³ÏNsÙ·oßž={´vH tvΜ9ÜØØØʲ{÷îC‡åææB³v¤Ò†ººW®Ž/^¼’ZuÏa¬ý·kN¾iú˜˜ò›iìØ±Zk¢@gGßʨP(\¶lOœ8±³o t&e4,,Œ ÃNîݽºvÊÍÍ=wîBˆN§8pïlÄår_Ën]yoúŠŠ hB€Î‹^GFccc±µhHHÈŠ+päòå˹\.—Ë…){€7Huu5—ËÕd…2@;¢?×N¤;'—ÔÔT.—‹c Æ€=zÄçó±†:räH[[Ûæ.¨ì÷áÀàÚIŸâ®Z\;‘€k'-x³®âââ***ŒŒŒ¦L™âïïÃàÚ©ë®0àÚ©£¡?×NB¡Ífß¼yÓÏÏ!ôå—_nÛ¶ÍÂÂb×®]ä@)BhòäÉêXàÚ è8€k'@èµÓÕ«W.\XQQ±{÷îuëÖýñÇï½÷^Ïž=ÁµS·\;:âÍ»vÂ_c#FŒÀšè?þøÍ7ßp8œiÓ¦-_¾|Û¶mˆ^¾|ùÃ?ì,5+ ù|¾®Ýþè‚sçÎMš4iÀ€Ç_·n]W*Zrr²æÛ©ðy½iz …:lØ;êñææ55U-Ÿ‹×Ñãá†£GnÚ´iË–-øèæÍ›±ŠçM¢££SRR¼½½;rÝáÑ{¡PõÁÀŽ£t:pϼmÛ6„Е+WV®\9iÒ¤N4" Î™3g.\¸œœ\VVvâĉ©S§BC@GæõFF) Nþ|8ŸÏïÑ£AT*uëÖ­ Ot:V­Z…5Ñ?ÿüsòäÉ#GŽ$Ç:#\°`Á7BCCþ\ùÜ&IJJ‰D*ÉX,Ö¤I“4)BtttMMrÌ矞ŸŸ¿gÏ''§ëׯ#„Ö®]‹þ±UNÉf³'L˜ £ºMJJÊÌÌlßkFDD”””`« uüüü\\\ºÛCrëÖ-M–%=~üX,«€Š¸¶@lll“¯ &&&š¤ŒŠŠ …­&KOO¯©©Q)‹……Ÿqã4É¥ªª*&&Fë 4h»»{w³Û·o·šìáÇ2™L¥i ††*W|||yy¹JäÏ?ÿŒãoÛ¶­_¿~qqqMžklláñxú×D5'==Ëå6ç| o@лwo‡<}ú4::žŽ ~¿B=tÄb±îœÌwRòóó¹\nsö ...<oÇŽxK?÷Í7ß@¥µŒ\.×pËŒv'::ƒ´•••§NÒs)x<^ó‰ÖÅ•Q„Pppðš5kÆŽ‹-ðÈO4WWW<,*‘H–/_nddtøðá¶dtöìYÊ?êoû2kÖ¬«W¯±víZ//¯ŽßÒ‰‰‰MÆ—••eggO:•Ãá0ŒG >Ü‚N§ÃãÑ2‘‘‘¤˜uöw^xx8Y–“'OBãvÌg–N§>|¼7×›a8žžžÍápX,R˨oÈD¥R¿ÿþûÎèñ^]0X,ÖÏ?ÿ¬ ÷B¡ÃáP(”mÛ¶=}útΜ9µµµ NZc çüBBBΟ?¿cÇoooå]—0Û·oÏËËkyÃ1@°lÙ2NOO÷õõUI€ýä‘?7mÚÔ§OhéåË—Nœ8±É£ØÊ*%%…ËåâÑ0}­oú¯¾úªS|“4Éï¿ÿ®üeÿé§Ÿ:880™Lhå7‹ú‡ôÆ•;·n˧Ÿ~jjjªáb eöîÝ«óùçŸwÒéõGfçÎ ,ÐE^Ÿ}öÙÙ³g{õêÅãñzöìüâÅ‹~ýúDue”N§s8‡Cîëêêº|ùò 6lÞ¼yûöí-_Íf“K…Ôù^¾|©²Þ³¡¡!))©#O£ë‡òòòÀÀÀóçÏ«¬ºµµµŠŠºsçÎ?ü””4räHXºÔ*•••*NÄbñãÇ;ã: üM¯SSSSSS£þ™×ŽÊårÏ;fy€žQ÷Bt&eT(Ž;‡Y,ÖÇüöÛoC3è“Aƒ …Âììl¨ @ŸøúúŽ3æÉ“'‘‘‘›7o^·nŽì€îƒ···L&{öìT€2ª%õõõGÕp­1Ð2'Ož¼|ùr“‡ðjúeË–zzznݺª«ƒ³qãÆæ–()¯¦Ÿ>}ú¼yó:E‰<<¿ÉCx5ýêÕ«MMM¿ýö[¨®Žº7åÕô&LXºt)T(£ADVVÖýûªþGüü‹ÅÒ×Í›N§ãaÑœœ©Tª£¼€:666nnnP€Þ°²²²²²‚ghwÌÍÍÁÓ8t7eTQ\üÂÅ¥·J¼‘‘‘X,Òä x‡züNÚ´iÞ„éÆãƃÆh ‹-Z´hQ“‡âââ"""ðž«!OOO0íÈìܹ³¹CصS7÷VtmðÆ(MJNN¾~ýúþýû=<&Lh®5?üðÃŠŠ þïÿ uÕ1€*è,Z´høðá8|âĉ+W®(ë©aaaáááæææ666 v|vîÜYUU…Ãÿ÷ÿGîP`gg7nܸ7n8p!m€. ‡ÃñòòÂawöìY•Þlß¾}=zô077ï2» ua6mÚ´lÙ2Þ¾}ûÓ§OqØÔÔtΜ9¿ýöÛ±cÇBàm”Q +àëëëëë‹úî»ï”5Q„PXXBhêÔ©¤k' ƒƒw)«¯¯_¹r¥ò^Y¥¥¥gΜqsskÎñ t¼¼¼°2úã?*k¢doHºv:8xjN"‘¬ZµŠÔDBµµµÖÖÖЛlF»°an—¡¼¼üôéÓPôf@g§¾¾v[@í. À××÷ûï¿oõñÛ·o_AA´7 ;:ôÕW_•––v²lÚ´éòåËÿý74kGãØ±cŸ}ö™@ €ªtÇ™3g‚ƒƒÕ7—îŒìÞ½ûСC¹¹¹Ð¬©´¡®îÕ°/^I­ºç0ÖþÛ5'õ´šþøñãË—/WÑDB®®®ñññ¡+W®Œ?¾¬¬ Çggg“a@ˆD">Ÿ_QQU€>Ñ·k§¯¿þšËå*à³X¬åË—#„nܸñôéS„Pmm-—Ë †æÐÕÕÕÜÀ¦S]PMHHøðÃ7mÚÄçó}}}I÷à ƒÜ,11!úøñcMìZ€6òüùóáÇóù|ƒA„³³s[Œä:®2ºsçÎ#GŽ?cbbÔ…„……!„¶lÙÂãñŽ;ÍÓ.¤§§s¹Üšš¨Š.À… V­Zõ´555\.÷Ù³gGE}öÙgönóóó¹\îË—/¡áºÑÑÑ0 `t¾š>//7--öáÇ*ñ¹¹¹|>/…#×J$>ŸÃb±˜ +chh¤üMßd2e’’’°-”r$‹Åš4i’†L š^j÷ÝwßõêÕKý(›Íž0a‚Žê6)))33Se”Ïç?ÞÜܼ9úùù¹¸¸t·‡äÖ­[š,KzüøÀÌü IDAT±ºÐªˆk ÄÆÆVVVj¢ŒÞ¸qCÅI`` &¹DEE …BMd¦¦¦F¥,ãÆÓ$—ªªª˜˜­+|РAîîîÝMÌnß¾]\\Üj²‡Êd2•¦a0Ó¦MÓ$—øøøòòrå˜/¿ü2==}Û¶mýúõ‹‹‹CmÞ¼ÙÍÍM½_566žyò¤r§ÆãñØ©ënݺu\.wÏž=<oß¾}zöKòºàQgûõë‡þ±-//_¼xqçíÍrrr°ñ«‰‰ÉÒ¥K¹\.,‡€ŽÎGF]¼¼^-¢_¸paCCéS§” äq÷‡ÃçÏŸ;v¬D"ùøã7nÜØêõÝÝÝ9NËi ãââZMÖãÇWÿTZ¶lYAA§§çÕ«Wœœ¼½½ÿýw­³ÐM>Rñàǵk×—.]êÛ·¯ž‹ïéééééÙj²äääÏ?ÿ3//ïöíÛZçbjj ½™Ð÷jzccãV—jnÛ¶-""¢#ä}þùç¿ÿþ;urrBíÝ»·ã7öñãÇÕ·TU!""bûöíð`@÷oÂårçÍ›Çãñô¯‰jÁo¿ý¶~ýz•ÈÜÜ\.—Ëb±x<Þ®]»BÙÙÙ.\€&PF[\5ïêêjkk‹úâ‹/8NsV#x“Lzzú¹çÄÄÄþýûs8///¡P8{öl§Égýÿ  mrß©²²² &P(”£GÆÄĬX±B"‘ÀãoœèèhÊ?´ú1©/^$bóæÍ¾¾¾¿NpoväÈ‘;w*ÇWWWã•X‡Åb%''>œÉdƒ µLBB)f6lèÔeùý÷ßɲ´º'ÐA0xãw€G@MLLx<Þ€B¦¦¦-Ø_²Ùlò¨†ó§º`Ö¬YxLtݺu</""¢Õ]Iß,áááéééË–-;vìØ‚ Øl¶òÑàààèèhooogbb2þüúúzƒO¼Aâãã.\Hþܹs§&–9]ž}ûöåçç¯^½ú×_]²d‰ƒƒƒòQì— [Žâ· æšã¯¿þš;w.ùs÷î݃î¤e‰ŒŒüè£ÈŸ7ntssƒ&îø¼á‘Ñœœ¼Nùܹs¤·ÑNAzzú¾}û(J~~þï¿ÿ¾téÒ~Ã666çÂ… ÿý·òÂÛ²²²wß}÷þýûçÎ;®®®ðT@G ¾¾~ôèÑÊ«’¥R©ºg’nˆ¹¹9‡Ã¹råJJJвS ‹sçÎeffNŸ>ÝÏÏoàÀwîÜéVo™LæïïÿâÅ 2F¡PÜ»w¯3–¥°°0((¨ªªJù!Rw"Ù¾¤¦¦^¿~©è|d4>>îäI^ Ê(”íÛ·‡‡‡krA6›AþÄÖN-Ÿ’™™YYY©’ÌÆÆ¦É kuÖ¯_Ÿ——§“ŸŸŸœœüÇàŸgÏž={öl“ç:99íÙ³GGu{êÔ©ÈÈÈV“áÍý–-[fhhˆ½º¤¥¥‘µQVVvóæMþøãæ.µpáÂ)S¦t71Û»w¯Ê†2A4™R*•ªT,ƒÁ8}ú´&¹|ýõ×Êû,¶Ðgâ [xÅ·ÀæÍ›±wH’†††&S–——«äbgg‡×·µ öÞØ²2úâÅ‹æ|8Î;wÆŒ k¶‡ÃyPùùÞE'NªªÊÃbq}UU^eEîù?ùÁK2>$díúõ«Õÿþüó÷ãǧ¥=|ôè&þÛ¿?´¢¢°ª*¯®®‚h†«W¯"„ m1bĪU«T"333•?…­¬¬.\Ø«W/¢ý8pà¦M›ˆN­[·B%%%dŒ­­íÁƒq866?«A”––Ž?ÞÖÖ6::šZäùóçÞÞÞ¤˜™™™ÛÚÚê:ß]»v¹¹¹µï5SRRzöìI–¥wïÞ3gÎôõõ…V~³¨;Bž0aB»çÒd/ÚaÁ*NFFÓ§OŸ;w‚´hºª4räHýd}øðakkëv¼àСCUÊ2gÎÝ<Ö˜Ùl6ŸÏÏÏÏ÷ôôLOOqj‰¤žT)Oœ8ôùÞE{“¾°cÿÆlFcbb/^%%…Œ …ÇŽ댦i\.Wy’.?????¿S,déV¨xk]àïïÿË/¿t²i8ÿùºðùüµk×â‘æ÷Þ{!4kÖ,ž¶ðf”Ñk×®}ôÑGׯ_ow¿÷Ož>ê¤U$ÉãÇU"ÝÜÜFÝéÊ"TæmBÞÞÞêîuÛ…'Oždee8q"''çâÅ‹}úôqjŽË—/ÇÇÇ:thôèÑ~ø!T  þüóÏ¿þúkÿþýþþþŸ|òI§.Kbbbddä©S§‚‚‚Þÿ}å‚íܼ¼¼ÈñìqÞ¼y NFmhhX¼xñÇu´“º¿O+++KP•ñôôT±É;vìT‹æ¨;Á533ãñxo½õV(KïÞ½y<ž.¶°ËÈÈàr¹YYY‹/:t(—ËŶ}@“Œ5JÝM= Œ³³3Øäµ‘wÞyçwÞée™2eŠ~LICR·nݺٳg+;W•J¥çÏŸÿöÛoƒƒƒu·s¦Ši¶‡‡Ç¥K—ºáÄ-cccÞ.Úøý­üÓÍÍíÂ… ^^^±,*Œ··wTT”&¿.Ož<;vlUUÕÚµkñª¾ŠŠŠÆÆF' -˜››ã½L@oàÔÔÔ¨¨¨µk×.[¶LÃ…ª@sèɵS\\Þì8$$¤Õ˜ÚÂöíÛqF“'Oæñx<4Q ÝÙ²e˲eËB&LÀbÖI5Q„PXX¶vÂ{7ðx<]h¢™™™\.×ÆÆ†Çãá-¾ž={†—0t"y<ÞÞ½{¹\î¾}ûx<žî|ætôêÚ‰Ïç#„Úh­‰k'¼“,ή9ÚèÚé?þPq*Ñ$͵ŽILLÔÎE?¸vz]1뮨T*‡ÃQ(|>¿…â´ÅµSeeeVVÖ”)SpØrÔ××wõêÕ꧃k§×¥{ºvjco®^—ŽïÚIsÚŵƒh¹Û×NBáp8ëÃñx|/Ë!S§Nú§k³©¯/'D­‡£Ç¾#—¿Úò»ïH¥M¸¾:txMMÕСƒE¢zsûöÝùóçQ©rÄŲÒÑÝøúúê¿/Ÿ©S§v–=ÜJJJìììÈîï§tF•%""âùóç붇^TTÔ³gÏŒŒŒ    ˜:oªÕŽäädŸŒŒ rÊ z³ÎË‘#G6oÞŒ½_Ý©´¡®îU‹_¼x%µêžÃXûoל¤vº’466òÿù¯ÅÇ £€ž±²²ŠŒŒüûï¿'Ožìïïïëë{çÎÐD6bmm õ¨‚.ÉŠ+ª««BK–,111Q>¬²1=Б)++#w‘ÙµkW'-…‡‡‡‡‡Gddäâŋ׭[×}`oŠ5kÖ`?¸³gÏVù€™;w®ÊÆô@G¦®®îƒ>Àá-[¶@…X544Ķz! m>º‹-ºrå þÉçóUì] µÔYÈÈȘ}úÓ§OñÏk׮͙3ªÀP¡ º+W®$5QŒº#I S€÷S&5Q„Piié™3g f€nÂgŸ}Fj¢Ð›ujêëë¹\.©‰"„jkk5\¨tt>2š——›–ÛŽ444 ">þ¼ååÌÍÁb±Ô·~n’èèèšš•ïõôôtMòe³Ù&LÐQÝ&%%effªDÆÅÅ5™øâÅ‹æææmÌÑÏÏÏÅÅ¥»=$·nÝ*--mqmØØØÊÊJe´ÉUüuuu*²gbb¨I.QQQB¡P»²XXXh8.[UU£u…4ÈÝݽ»‰ÙíÛ·‹‹‹µ;—Á`L›6M“”ñññ*ëE***4ìE'Ož¬£â§¥¥¥¦¦ªD^¿~½ÉÄW¯^Õd±vËøøøtClj‰‰EEEÚK£ÑfΜ©IÊ„„„’’e´Igb±XEö˜LæÔ©Sµë35Gó>³¶¶öÚµkZW¸···.6eèМ8q¢ªªJ%2<<¼íj( Ô4wG§®6íÛ·O~pý÷f¦¦¦°ó ?eÔÙÙÅËËOw×www'MHu„ú&Ý;vìèß¿¿®óÕäË^e›Ó;wî(ÏÑ[[[Ÿ:uJÃï? 9ô‹ºWµ}ûö½r劫«k[rÑÿNKKË7þtt:üýýõ‹ú梤¥<=====•cRSS•çèÙlö±cÇð €ÖèÇ Öˆ#TbTfä]]]/\¸ÐF“_ý8½655…Þ¬+(£€>Y´h‘••ÕæÍ›ûõë·mÛ6kkkX¶ÜyÙ¹sç‰'NŸ>=uêÔ ôíÛ·š(t"8Ž™™ÙÚµkñÖ!:5yþŸ½ókby÷øÒ •"é „ˆ¢*PÔ¬¢bCìÔs<úÓc÷(öÞjrE5ô""½£R”Þ[îs{÷&Ò)Îçññ ›ÝÍf2ûÎwÞ"h¶oß®««{éÒ%77·åË—ëééÁà34F,ÖÖÖÖÖÖÛ·o‡·bàêêêêêzëÖ-x+ ¿!ffffff7n„·bàììììì|ñâEx+ Ð准~K@ Ðíàj@ _€yF!@ Ð…@ @c@ Æh·ÔÔÔ ÿ%==ÅžoÞ¼ÁªtH¤Í›7ƒ×Ó¦Mc(lƒ¢(WõòåË´´´¯_¿îÚµ+--m÷îÝ_¾|Ù³gFÃÎê6-à†kغuknnî_ý•——×/¾ ü}“““ »qãFXXØÍ›7Ÿ>}zóæÍ'Ož`ñà]~ꘘ*•Z\\üðáÃ{÷î•””#2gÎ:öÁß4vïÞ=*•*""r÷îÝàààGݹsçñãÇ¿¹¹¹øZØm9}útTTx}êÔ©>ôýïtÇŽÖÖÖàõþóŸììlA&Nœ˜‘‘6&$$ˆˆˆ§‹VTT`ÕPÇ—››ûæÍ›PRR’——OaèççJLá;'è9 ‹â·ÈÈÈܼyA… 677#Š\}ôèQpppHHˆˆˆH{{{tt4èÌÝX Ô××/]º´®®Î××A«W¯¾xñ|À+W®(++3`yyyååå<¶ûíÛ·€€€’’ð‘Ÿ>}º}ûöÊÊʬ¬¬°°0†±4??Ë–-Ì#ÐF³€€€Q£F8qAÿïß¿oذa̘1IIIÍÍÍëׯ•Øh4ÚÚµkËËË׬YC¥RÏ;‡ ÈêÕ«þü™˜˜ØÚÚŠ Èëׯ/^¼îÖEýüüjjj@okk‹ooo_ºt)•J½~ý:Ã%-Z´¨©©I8]®­­mþüù‚`£(øâ°¦ÁŽ HccãâÅ‹ÛÛÛãââ¸këÝ»wT*•÷.Ê‚£GÆÆÆfffbU`233«ªª˜?ø‚ðuJ xÐcci~~>‚ qqq"""Øn111‹-jllĶX[[8pt‰?ž›+W®÷¤¬¬¬×­ŽþgŒ***Rþ ë*[Û·o¿qãF—O8†t9ååå<–üÞ´iVÓ _j{}ÿþ}öàÁ°ûÿîÝ»4íÑ£G Ï’^1ª8âüùóàù >ˈ#¾~ýÚÒÒ¼ç™3gPŠŠbøìàÝ“'OÒh´?b¿@EÁSŸá62ØQQQñññQQQ`l/^¼À*¾xñ‚õ©?’ŸŸ"üvÓÒÒ€á^GDD`o]¾|™F£½zõ ßCRRRº,CÊÐgΞ={èÐ!ìÏ„„„÷ïßãwˆ‹‹cž9œ|øÀl_v×tKK °Â9åÕ«W s áCŽºvíÚǯ]»–ás•––oÙ²åîÝ»Âÿ ?~ü_ÅwÁ‚د \|ee%VïôÆû÷ﯨ¨æ5þîedd„‡‡ƒ×ééé,Š—~ùò?Š"rìØ1A–,YÂKçßÔå;kÖ¬é²8§€A +q¶sçÎ’’’½{÷¦¦¦Î;·®®.--H$¦§§§¤¤XXX„„„¤¦¦–””0˜/UUU™™™}ü¾ÅÇÇûøø\¿~ýܹsºººáááøG8~ê9gΜÂÂÂÐÐÐõëׇ„„ܹsçÁƒEEEß¾}+**b( ]RRB$£££ñ.`îܹ]Ž EEE£G.,,|øð¡@ÕÐÐÐPæí999D"1)) ?mnn®¯¯Ïï¾LMM¨¨èÈ‘#ÓÓÓ“““8€ Hjjª……~·ƒþõ×_¹¤5kÖÁiĈÌï&$$´µµ3??ˆ…Ë–-‚&;Õ××#2eÊ”wïÞ544ÄÅŵ··c'ùþý»ššZll,~Kaa!³¤‡¢(¦–””€ù§”¿ëׯ?þüÚµkT*•F£)((äççñãÒ¥KË—/»yyye®Ë"àœÂŽ'###%%žŽ¥¥¥ƒNHHÈÈÈ ‰˜Ô”““³mÛ¶¾Üí‡ vüøñ_¿~ÉÈȸººÊÉÉeee-X°@NNNZZLqA%Þ¤¤$`&‚ Ü%•óçÏWTT())ÙÛÛ_¼xô 8­[·®²²2,,,999,, “ ¯]»†¿ggçñãÇ¿~ý:..nëÖ­±±±‹-RSS+,,ô}(***((ÒLKK‹OKKËØ±cïܹdÚE‹ñÒèœÎÎÎd2yóæÍ«V­Ä7ü_QQQ[[ TXðe544¤¦¦‚ÿ§NúåË999qqñêêjÁÝÛÔÔT`&&&***‚ëÉÈÈ066Æ„[2™Œ·C²²²°wÁL_pÿó2dH}}=І***6lذnÝ:AÞ½{gff¦¢¢v[½zõîÝ»±µ¦×¯_ÛØØKÿx-++b-4FyÌh{}nÍüA{÷î‘H¤‡jkkS(uuõ~w{SRRPÅÏæmll(Š””ÔêÕ«£££ÓÒÒ<ˆMÝÞ¿O¡P$$$±³³3f ¸'±±±`"ngg'*ÊØ£££Àh4FërÝÙÙ‰-U™ˆˆ°l ðõõ½zõjMMÍ·oß>ÌðŒ©ªª*++Ã,}“ÂÂB ‰5kÖàíø»wïz{{÷âU;v ˜˜Ø<Ù/]ºÔÐЀ ÈçÏŸQ=wî¨ÈZvbfíÚµgΜaØ8räÈÄÄÄŽŽ}£ÑÑÑB^¯ÇóúõkÌéõë×$éÒ¥K|?Ÿ={6uêT †R(°(gÁ‚·nÝRQQQPP3LãyüøñŒ3ú×°vãÆ GGG•Aƒ!2ícµ”–.]Šÿ]ƒ®Æ%ssó‰'~ùòE[[[^^A ‹üü|Ð9---sssW¬X±zõê7oÞ€3X[[3TÈKLL455ŠãñãÇ׬YsöìY`¤2ˆ÷|çÔ©SëׯÇþŒŠŠ%=%$$Ö®]+))‰—ß½{—””ôöí[lÖÍ& ùùù`r+//¯­­ TÒÝ»w_¹rEŸëÀ ,Ào)++»sç^¼WWW'6lÜí½{÷.æÄÒ%¡¡¡žžžÜ|øðá?~üà—1 ñx÷hŒrIVVÖ¯_¿Nœ8±mÛ6™_¿~;v +ãÁ0Ûàôôô;w*(( R[[ J†Ðétooo:>|øð´´4oooà I&“ååå¿|ù2zôhÌǬ©µµµ|˜0aÂÕ«W#""äåå7nÜhbb"""¢  @$kkkÈdrbb"vrUUÕêêjüª+Ö±_¿~ fVïÞ½ÓÕÕ}þüù˜1c¶mÛöóçω'ž={VLL A}ûö-\¸áÛqvvîÒŠÚÛÛEDD¶nÝêàà€WIµµµ%ÿ—ÂÂB°À¥¢¢âîî¾sçNæñ5 ؇¤¤¤­­í»wï<8{öìaÆùøø\LLŒwçöù믿))iýúõ sqÀ§OŸ( ˆ!ÀC£ÑH$Ò§OŸH$R\\FÛ°aC@@€““Ó»wïÁdÝÞÞÔû÷ïûÔm¬ªªBQ´O¹aÜ¿ÿÛ·o2}út!¸5¿xñ+0ann^XX¨££“ŸŸÿèÑ# …íææd'}}} …"##Óe§?~|dd$Ø’””dff6qâDE»sœøðáCRRƒ&Š1jÔ¨OŸ>ÞŽuÔcÇŽ â¹|ùòU«V]¸pyMÓÕÕ•D"­X±‚ÁHõóóC$""‚—‡ë AƒTTTÀø‰ççÏŸUUUOž<ñððè¿‹[·náç„FFF@ ffÉ’%JJJ‚|ýúUCCCQQ¼ÖÒÒ"‘HÅÅÅuuuË–-cÖö,,,òòò€>  rqqIII122"«V­:þ<˜ï¥§§C311ÑÌ̌ٸ âV899ÙÛÛ=šÁU:** ?ß½{÷îÝ;_ & IDAT__®=Žð^%‚L˜0!""bâĉà'yåÊ•‰'‰D{tçÎÌÑ],]TQQ±¦¦ÆÀÀÛ>þ|à€9kª©©/////¯­[· ÍstÆŒ`üÄ.‰¹súøø°VCËËË«ªª®_¿¾xñblûóçÏÝÝݱñsÒ¤I“&MÂ<ïû2Ímnn7n³)####-- |›dee±×­­­`ò„üG`öÙ³gÏßÿ …BaŒvìØß¢¤¤„i¢&&&âââD"l±°°ŽV¶¶¶¿~ýãøðºÞ(µW¯^¥ÓéZZZNNNd2ÙÜÜœÁþƒ‹ó•ôŸþ™7oÞŒ3˜—€†¢(•J%‰D"QSS¯˜ÄÅÅ?|ø¢ï­­­ááá555/^¼OJGGGA:::ðN"))‰õ$µ“žžnjjŠý>|¸fÍqqq999æ¡PhöôªU«bbbˆDbuuµ¢¢buuµ’’’žžžªªjDD°ð?=__ß””CCÃüü| Þ˜››ƒßÑõë×ÝÝÝUUUõõõ1'<0îkkkÞ¾}{þüù ‹â…¢éÓ§ÏŸ?¿  `ذaÅÅÅ`¡cÓ¦Md2ø’jjjþûï¿üýì@ï_²d‰»»;ˆ¹¾råÊ•+W€¹ ðóósss»téÒ–-[lll/]ºtá°@ÁQsÉÉÉd2¤PàHÁmmmqýõõõ­­­D"QBBêâ{‹Ð áËÒÒÒ‹/Þ´iÓÑ£G­¬¬ˆD¢¡¡!ûg èxà}}}—¤¤$ «©©UUUÙÚÚÚÚÚÞ¸qcÙ²e@¼þµvvvñññØ9ÁyNž<©ªª ôѧOŸººº¿UL¥R© –Ž_ 6 h“?~ü¸}û6XqUSS6l¶@ZŽŽŽ——×âÅ‹§L™ÂcÓ=´R))©#F8::æææVTT€§OŸÞ¿¿¡¡!›ÙHŽ=ºiÓ¦.ǘ ™‘‘akk¶oß>qqñáÇ ¨›Mœ8øßËË˳8ÜcùIùüù³¥¥%óá–––˜7ÀÚÚ:999 àÖ­[ ÌnH999˜ý““£¯¯^———+**º»»§¤¤€9ØÅ‹W¬X¡§§7a¢ÃÖÖß-¡1*}úï[1nܸ.§7...øU¢¨¨¨©©ùõëW.ŽínuBEEK®¢ªª:þ|555!øÞbyH¼¼¼ðisÀ5€×wîÜapl,\¸äž ²ý¢E‹ºÌ4,®$--mذaÌ£¨››>á°PW®\yáÂ0;åh…ÆèÿáïïüøñaÆ‚GESSSSSSwÍçÏŸ-,,dee%%%‹‹‹±ù=;ÔÕÕQ©TÿÝ»w#bffqâ„¿¿¿¿¿XX§â“àôsçÎ577]±££D 3ÀY ˆ®®îáÇy¿’ŠŠŠmÛ¶Mš4)))) -- ¨#@ÈÄÿ4ðš³þ¡®®®«« ŒZÌ8°··RÓýû÷:0Ø®¡¡QVVÖÑÑáàà€ œ£FÂvÖÔÔBCn*•ŠÅÔãá…%K–DFFzyyaëÞzzzD"ó"îwøcýúÅu¨rSSScc#3Áí=zôè·o߀øôéS+++2™ê£ Lš4 8)**jhhüñÇ`BÎ4eÊæðäÞ¢¨¨HLLLSSóþýûsæÌÏ›ÖÖÖ?~àwóööœœžžŽ9äáþd‚øùùágqÝ}×VVV ¦“²ðè:`¼1ÂXªöaݺuÌó+Ðf›úûû‹ˆˆÓ{~ŸæØØX`´ñªŒ_aÿ ´á½EÝÜܱ&Lxøð!›AÊxIIYYÄüM:<ŒÓ 2h¢x‡Š ˆ¯¯/è–X‡ôóóÃ<[–/_Žé£xë¢XLýªU«Àtë¢À¢Å^@Gy¦xtSîììDQtþüù˜b .R\\ØßcÆŒa›ëòwÇæe¼zõÊÍÍͱ”ÐEñâ=ÆôéÓõôôÀÿ3fÌÐÕÕõòò]tèСRRR(ŠÞ»wG5EÑïß¿3¿u÷î]0~‚kÀltyyy,‚ ÞØ o˜ª¨¨Õ K… Þºví¦‚1¯/a|ùòEQ†Å½+V0gäxóæMff&›9IxD|@£šššàçadd±±i“±±ñ AƒŒ_¾|Y[[‹A*©……›Ã÷—/_þþûo,×=())7ì)²fÍðS·´´Ä¦MŸ?=z4¾³2“œœœmmmmhh˜œœ|üøñ¦¦¦%K–°Ž’ˆˆTVVR©Ô‰'‚ "‚ô˜º¥Ë¥ 0Çûä±8˜¡/""Âð°5j^ͬ «H 0Pe@,¿:&i°I°æ²³³b·{düøñ***nnn`ÄÉÈÈŽÅ$‰F£ÉÉÉ”––by="""ª««gÍš,KöaìÁMÆ{ //¯eË–ikkK¡PòóóëêêºôvâE±Û¸fÍšqãÆué„Í0ÑÇî*‹¬F˜/?6Ä¢U°VFމùŠ0ÄA“H$,Šö`-(÷Ÿ>}ÑÒÒ*..–=á,XÀuHDAAÃ|ø2l𓾾þÛ·o‘’’òòòºwï^vv¶§§§ªªj’fd|dpäôlyyy˜Új``Diii,…@ 0¤á`MCCÃçÏŸA¶æå- ÃtY}tÖ¬YûöíëÒÅ?ƒÇ2:5ü·Ï¬…Lž<vjii™ššjii9vìØ¸¸¸‚‚Žîä† þú믡C‡VTTdggƒ8ÐÖÖV2™,%%ÕCE—RßunX{*c#µ³³üâ@Ðý·oßX,pq1ìºÇàÁƒÙ©ÙʆQ©TæTkì·ÅðŸ™K5*///&&V]]Íb½D®`Y011 eˆeGݾ}{KK‹ššZxxxTT'éÿúÅ Æ`2räÈèÑ£ÛÚÚºsßg––Vw)ÌØAVVöÚµkõõõ ˜imm­ªªêÑÖ–fÈP+---''ÇðÐÇxóæ pÝÖÒÒÂÒãpЉ‰‰Í;wXwÑt:EQ/OpægXhb.'ÛÇü!CÈd2PIUTTÀ(Š5wö^ ÌMƒüÊË–-«©©QPP DäŸþ‘““³··gvu…Ê(?å4ìëQSScŽeØPg{\fçðãÇà‚¹âñsyaŽ*?~œ7ožŠ¢½U$¬/Œ«|G[[»­­­K‡<Öܾ}›w ¿¯Ýg{{{0ÂS(”ùóç£(ÊQÊ' ßðå+‹ŒŒd][¤¡¡!//Åܘ&OžÜ]îE°ê…wnæ///NgÔ€¢¢"E»ËÖ,è6ŠbB2Ã(ºlÙ2¼ŠÄÎõtù¸_µj;“ÛßÅ•––Æ B€¥þ"''Çœ!yyy2™Ìb%‘ïDDD477wW¡+++‹ÅÂ(\ËfÝŽ„„¬ÞÍÍ-!!!11‘÷Š}„… 7A°¢*&&¦¢¢RZZÊþòòò8MÜÈÂTJNNf½ÏŸþ ¦¤Ü±}ûö½{÷²Øáëׯt:=&&¦;Š#IŒ#’““KJJäää’““ׯ_l``À©_k°˜zá#**zïÞ½èèhGGG *•ÊQ¾§†††wïÞñžÄ‘B¡`iÕ»£¹¹¹¾¾Þ‚N§³Î̯G&¨}ÕÝ×––Öë ‚ ŠŠŠì;)ÆÇÇVUUaiqGŽ ¢$À‰ÙÑÑÑÉɉ£º} ‹òËžuÓ ¼¯iv—‡„@ Éd¾èÜ&&&ýõC‚pÖ?Ѻº:ü111yyy|¯~„ºº:™LÁººº...×®]¥à 1ÚUUUååå|)õ9cÆ |>°.™5k>ó‚ 100¨©©é.¦KBÖK–,a½†‚qùòåúúz†: 'Ìj(Jxx8Š¢=Ú…Ø”ñNwéâ0ž|øpæÌ™Ý¹5S©T†„n̽šÍxç;wî”——ß¹sÇÑÑ144T__¿_—ŒbM@@@ñ=xø˜Œ¥/^ìnÚóúõë¼¼<¾ÚØØyìØ1ÖÅý8bÈ!fffÌiYÖ­[^__ÏNm¾#///** ¢Öµµµ‚°Ó!MLLºL"QUUE¥RëëëSSS/^¼øçŸ’H¤C‡ýš(žÂÂB …Â"ÓpggçãÇù2È`}”y´Y¾|9‹LÀ\˜¼ÖÖÖø‡`SSCw¾°}ûv,©H—€îzäÈ‘9sæ9ߢw Œ ¡C‡’Éd·aèСååå¼dc”1úåKzTÔ'𯲲J˜7ˆ¹È ¨««Ï›7Ÿ0ÿÇ(Š:tˆB¡pôw|||¸+ lbbòýûwüÐÇ××EÑþèjÍ;`ž·mÛ6###ÖãšœœCá EÂð[ÊoðȬY³DEE€ ÃÃã˴YYY(ŠÒh4 …2eÊ”/ºwɘ1cÀ’ Ù¹ »{ñ‹˜5kÖƒ°?¿}ûF§ÓÙÉÙÜe‘0AòóóQŽŽ–••Y„~Ïn5j”aÆ’Sbàó±ð‹)S¦<{ö ûóׯ_¬ý﹆µÏ}qq±ˆˆˆ¦¦&Xeú ;Ûˆ#RSSAÄs2FËËKÅÅE† ÓÿFŒ°ÚÑ |¬>|¸„„°RWWgdd4wî\aÆÑ3³iÓ&Ìs”F£î\ŸMEEÅ‚H$&$$àá¿!$É××7>>~Ë–-eee ï®X±äþå;VVV˜ÜØØøùóg>ˆŸëëׯøyHZZšˆˆsò)ÁA£Ñ-ZD&“AB\CCCþ~Æ~„„ÄíÛ·œœÈd²ººzll,Ã………“&Mê.>ƒV¯^M"‘ÁŸeee“'O?½øE˜˜˜ˆŠŠöèÖÌŒ’’RGG>x‘‘²uëV|»ßÿèèhæ*VÅÅÅ›7oæ.÷mà=GÛÚÚÑÁNœ8Y~)))AAA‚h¥KïäÝ»w,.)**R©T0–þ†cÚ7üüüPõ÷÷çÑt ,ÓWUU••• "ÔÛÛ«æwïÞ½¹sçö…©¡¡!³ç(;°ÈKü;ë üç?ÿY¹r%^4 .¼yó&xýóçϪª*Þ½EñhjjŠŠŠâËáƒ.;'pêºpáB¯¸võAÞ¿ÏðñîÝ;†Bä|Ä××÷êÕ«ØŸ åmzñ>üûï¿Às”B¡°Ž£Ç3wî\æ˜úG͘1ãÔ©SXáoØÍ6nÜÈ0š}úôÉÉÉÉßß_-®\¹›´766fggóË[”…=ÄNÔ0»5—””Ðéô7R©Tà߬¥¥ÅŽ—óæöíÛ ÅÕÕõýû÷ýÉmkk£R©¬'µ¶¶R©ÔÐÐPvN¾k×.¥•–““¯®®NOOïèèèEoQ< p-pÍ9~ü8ûv$CLýøñã'Mš”žž¾jÕªßpJÇ]]ÝÁƒc†è‚Ë· b®£££³²².]ºtäȾ7ñ÷ßoÞ¼y×®]µµµ»víòóóÛ¹s§€:'CB\WW×iÓ¦Ç!¿r¯ DEE7oÞüæÍ›?þøøvtt”——sZ[ˆ}¤¤¤@z¸uëÖÑétP^²w‘——ß¹sçæÍ›‘ž2Œ2€W­¶mÛvúôi*• rªÃÑ ‘HÔÒÒ¢R©@¥Óéß¾}ãe15 $éÅ‹ùùù¸|ù²€ÌDmmíOŸ>eggó7Žž¡sš™™á]€?iÒ$*•*LÁ¢ïãááQSSË>*lcø-566^¼x‘õ>µµµW®\éñ„“'Ofq*QWW'!!!X…î¾ÀÂ… A 6×Õ&®^½êëë»lÙ2yyyøCêRQxóæ HíÑÐÐpéÒ%A‹Ç¿~ýºyó¦àôKMMM0°r— ŒM0·æììlEI$Ò!CúKÑE!óçŸZZZ‚Ê@­­­©©© ®€¬---Pl³¯¢(×nÍA]]+<Ýf؃•N§ÇÆÆ h£©©éÂ… BXt=Þ­ùßÿ=zô(™L&‰ Ep}?eíÚµ...(жµµqq¸PkÓ_½zÕÊÊ T©ºråJ—e/^¼hooêP?>22Rø5ýðlÝºÕÆÆfÊ”)| Õç $ééÓ§œjkÖ¬Y¶lYKKKKKË•+Wúc¡yá !! eff&$$`¹®ÄÆ]]]-ZÄuUevl‘;wòòÔg+++°†•••%´À©þ‹Ïœ9sþøã[[[†úã|gõêÒÈš IDATÕîîîgϞݵkW_Í8#mÛ¶mÞ¼yÒÒÒ}J,èƒÉäÙ³goÚ´ÉÁÁ_)?»Ã×××ÃÃcêÔ©ìW¢ç777A á{öì‰GfϞ͎@ö;ãééééé9zôèàà`N«‰÷£Ï¹k×.†i}zzºlÄÀÀÀ>XAÁÐÐë'ý•+W¤¤¤à/‡EáÑ£G‘[öíÛ'„åEá|sçα®B Á””\»vmBBB—©éùËÎ;ûà*6Iæô(//¯É“'ƒtÜÖˆˆˆøûûÇÄÄÈ[”až „n¶wï^!´:'û$€€€S§N(ðüúõëׯ_‚s—òòòªªªjqTÁ÷‚(›?Òh4PyOÐ?~¼£µµµÅÅÅœ>ïÕÀ«'8¨Tª¨¨(¼ñòåËÔÔT"‘Ø»Ytúß¿Ÿ>}:G–(2*0 ˆ‰„ÅÔ÷€CÞ¯_¿8:êÅ‹“&M~ŽÃ~ÊñãÇÝÜÜ^½z%膞>}ÅÔ ŽM›6Q©TA·òäÉ“iÓ¦ÁnÆ&ÇŽsvvæc-?‰„©ï#|ûö EÑââbî~¤° ±y£FÅN¥Pyóæ «!²`ÇŽÊ0Šçþýû(ŠÂnÆ&§OŸ¶¶¶3f § ÕõõõMII¡R©ÁÁÁ˜Ãè¥K—0W¹+VÄÅÅQ©ÔÛ·oKHHô®Ã(‚  T=s5¦^€¹ººöX œœœ2™ìééyðàÁ––øË鎶¶¶ÀÀ@www[[Û‹/®X±B Íeee‰ÄK!óÈîÝ»¸HëÈ $˜••Š¢û÷ïç´‹þVttt9rdÛ¶m#GŽ9r$sæQþ’››«¯¯Ÿ›› bêû;wîœ3gNw%9ºãÀÁÁÁ>>>{÷î­¯¯‡Ý‰µ%J"‘»,ÉÆÇ‘3>>þòåËü-Ẩ'V¬XÁº†3ïìÛ·oÇŽ¦¦¦~~~»víâ´‹þVÄÆÆžõ¥ 333%?ÏÌÌdŽ£·²²ºqãÆ«W¯¾}û»YTTTrrò½{÷˜³Šjkk¨ÝÄÄD,£¾ššš±±1åûøׂè—/_Jâ}4&&ꣀ'Nti‰Î™3çþýûj4>>ŒŸºººùùù’c0Okkk=—™û‚ ¦¦¦¾¾¾PÄÆÆz{{[ZZòžÚ*£ÝòèÑ#†DÊ3gÎ|øðaï^æÇ/ÌÌÌ( Ì噜œ,dMA°°°iÓ¦ ùÃΞ=[@âè“'O<<<º|kÑ¢EB}íûœ>}zݺu]¾5vìXÅÔ¿|ùTÁpwwþüyŸº3|©È0oÞ¼àààß¼ÅÄÄ (:räH!§ñŠŒŒk+V¬D}ÄgÏžM™2ûsáÂ…Xîß¿?gÎæíD"‘L&C}A³gÏ^»v/I6‚1jcc#ˆºôôôáÇã·ôºçheeeff&~| `ó'QQQ!///--Ý>¢¨ ë õYÚÛÛãââÆŒì‰bØÚÚ&$$ð½é¬¬,|¹ö#GŽ€:ÝüeÏž=ÿý· oãçÏŸY˜òÖÖÖ³fÍ:pà@ddäïÙÍÚÚÚ´µµÿøãû "-NNN޾¾>~K¯{ŽÖÕÕíÙ³çÈ‘#ø‰1›‚}uuµ˜˜X—¥Œ-,,æÏŸ¿wïÞ†††ßÖD Ñhþþþ£Fên‡{÷îah|$??_GGû“D"ååå•••ñ±‰¦¦¦††¼#@‘‘á4Ë!;€‰‰ géÒ¥(Šþûï¿¿³%ºtéR~%HÆèâÅ‹ñÁø|ÄÑëêê2lŸ;w®à8Øy¢pç- ~ZÝ¥í577§P(—/_þ=TÀO”uèòåËù~˜+ 2DYY9''‡­|ûö­³³SKK Û¢¥¥E§ÓùSëÖ-Pf½;Œ§L™’‘‘ñìٳ߰›:uŠB¡ØÛÛ ¹ÝîRÊ/]º”ï#'û|ÿþ½­­ oQA %%%»+Œ§§§7cÆŒßV¸:qâÄÈ‘#YX¢¢©©)33?ŠÊÈÈò7c]UUUyy¹±±1¶eðàÁƒæ{LýƒfÍšÅb--- …ÒÙÙù{Ú£gÏž577;v,¿N8ŒÑ¡C‡êëëó7¦¾¡¡ÄÑ3l722’’’t>Èî8r俼E»äï¿ÿ>tèPkkëïó‹joo?|øð„ Xh¢ %%¥òòrþ߃Æß–––ü­­­¥Óéøyˆ‚‚‚©©)Ó ÆÆÆª©©ikk³ÞÍÚÚÚÅÅ%((è·²G;;;=êìììààÀzO™ñãÇó7&#::Z___EE…a»ššš¡¡aTTT¯Ü“;vìÝ»W@'·°°˜7oÞ¾}û~7}ôäÉ“lZ¢üõánooÿù󧺺:~£®®n^^ž ?5û+„lRWW×ÙÙÉNÉ%‰”––ö»ùž;wŽ¿–(}F»#88¸»UŒY³f :/F—té-jddÔ5¾4annîææö[) Ç7n;YñääätuuSSSùØúÍ›7AL('Ožð± …‚¢(ÃF¾øçq‡±±1…BÙºukxxøïÓÍF-|MpåÊ•îr6Ož<¹W¾…‡2ËNššš"""ÜÕabFOOÏÓÓó·ÍNžÆÔgeeá×Îz$%%¥´´tÀÛ£t:ýèÑ£cÆŒéQÅào¤¨ºÔÝ»½å9úõëWf‡<AØ™XûóaXZZz{{£(ú›X¢NNNlîÏ÷d…qqq=®/ñeÌìR;°²²âcLý—/_º3»ÄÌÌìÊ•+)))¿‰%ÊK>ÑcŒ***Rþ ;ãÏŸ?wwwggO ‹¯¾}ûÖÏÏB¡`UØÁÍÍ1^aaaS§Níò­ ܺu‹/­°(o3{öl>z;…††vGßK–,Ù²e˶G?~ü8wîÜÑ£G3gq/_¾œ8q"ëoAÈž£À[”Ù©;>|8sæL6' åöíÛÐ(‘‘‘ÝÕîæcL}xx8>ŽÏÂ… o޼ɯÜŶGæÌ™Ó[kMÀEÒ2ý‰'üýýy?O}}}jj*ëŒÆÆÆRRRü]±e€‚¬»c`ë£ vþ?þàbÙKéÌ;ÙÙÙÌ)9222üªÆÔ¥…Íëèt:_¼>þÌ]éÔÏŸ?T}”N§ÇÄÄlÚ´‰}MãúõëK–,áýZZZjjjTUUY죮®nhh(¸:vÌDGG›˜˜°ãÇ/þù矬ž:uŠ;K_Õ…G ˜ã}±§ ¿òdggw·¾'##C øâ±Æ¦î΀™™ÙâÅ‹÷ìÙSWW7 »Ùùóçg‰"Ðg”™²²²ÆÆÆî~WÂô½}û6‹ åE‹ñqFˆ1€õQà'Ê‘&Êw@måîŒQEEEÞcêY—·ÑÒÒêììäKë.Êá+sBàÓ§OsçÎ5jT/j¢‚ÔÕÕõ¸à(LÏч¶¶¶v';‘ÉdAÄ&}t÷îÝüõÆî#–èˆ#zQE¤¹¹9==½;Ï{YYY}}}ÞýŽªªªÊÊÊò-b ß-ÑîÜ0 1*(‚ƒƒçÍ›ÇΞ(Š Ás477WAAoQ„©*=ûXZZ$}h¢ì<žÍ7˜ãèñð=¦¾»>Ì»Ÿï]ÔÄÄ„B¡ô‘jé|éf£Fâbužï°ˆ£g@Ùš™ùñãGkk+/Þ¢‚Ü¿ŸS> Ÿã?zêÔ©[·nqm‰ò×XaŽ£Çטú   Ö¾+Ó¦M{úôi¯wQmmm …Âßà°o‰4cÔÐÐ/*=› >\BBBО£‡f]²…’““¹^•¶µµuww ì×úhGGÇ‘#G\\\xO¯³bÅŠ .ðr†ÚÊ]bllœ™™Éã¥r]ø›#2339Š£ïŽÝ»wÿóÏ?ÍÍÍý·›Ñh´cÇŽ999q­‰â­Ã   ¡]¹ ²53³}ûö}ûöõâdii9gΜýû÷766öë‡ÝéÓ§yÑD1´´´ŠŠŠx9CAA¾êR—èééñž‡$))©Ç|¼ÇÔs­»3?¸÷ìÙÓß‹^¸pA8–è@3F§L™ÂãÂÖãÇYÇÑ3Ð[9G…?‚»¸¸ô_}ôýû÷ ,pvvî š(Â2ŽÏ‚ „ âÌž=›Ç>êééÉû•˜˜˜¸»»÷k¾ïh¢‚DDD°Ž£g@О£!!!ܹâñƒiÓ¦õënvúôikkk¾h¢NNN<ú¶±ˆ£Ç³|ùòK—. úÎ,\¸Ç<$\ÄÑw‰¶¶öÌ™3 x÷‚èEKÔÈÈH8–(2ð–éOœ8Àõái<¦¦¦"""‚óݲeK```»œ8qB 7ÖÎÎnÒ¤I½U¯…k:::bcc7oÞÌÇP’—¥ø5àÅëß¾};vì`Çä%Û(×qô]bcc3}úôþù§¥¥¥ß >ÇŽãÅO”™ëׯsç]ÈÍÍÕÓÓcCCCYYYyŽ‚,%ìÜœ]»víÚµK ß”••Š¢ýT–è˜1cøuBö=ÓxǘúÓ§O¯_¿¾ÇÝ/yH¸‹£ïsss??¿øøxa.Øò…øøøùó繸¸­Qè3ú”••544p4|#‚¬d“››+//Ï£·(ø :”÷D*VVV...ÉÉɼ‡ï“ãÇ;;;ÛÚÚö‘ëqôìÌyTTTrssz=Æ ëèèà:¦þÎ;\ÇÑw7Áëwú(FCQtÔ¨Q|´Dy¤®®®°°ÓGÁùüøñ£¥¥¥ÇõÜ),,”è®*=G–wÔGùn‰òˆ£gÇLVVVOOOÐ^mC† QVVæÚø ñòòâï%y{{÷;ÿÑ‹/ž?^˜–è4F544´µµ?}úÄű ­­­ÊÊÊ%¸‚L[·nݾ};/AÊ€Ÿ?ÊÉÉIKKó~IvvvÎÎÎñññýBmnnÖÑÑ?~<ßÓëHJJr]§¾¹¹™Í8zYYY)))îfù™™™---ìä…PTT411á®N}UU•¤¤¤ŒŒ o¯§§'Š¢/^¼èñó,:À˜1c¸[:omm­®®fa´Ëñ“/9I˜á—+^MM¨¨¨¼¼<ï§êwú¨žžž ,QqqqîV“;::˜ëÑw7f*++sS_ZZš-èP­úúúööv®ãè»ÃÜÜÜÇÇgïÞ½ýÅôâÅ‹ÞÞÞ 4F{‡àààùóçsq +ÙîܹÃþÅUTTð%G:;#8ÐG###ûò·µdÉ …"MT^^^[[›»HPPë8z<žžžBÈÔÍuE1 Þsjñ°ƒ©©)…B¹zõjß7CQuttì;š(àÊ•+~~~}äbBBBš››Ù̯N$)))Â…}tõêÕaaa}¼§9s&((¨ïh¢€sçαï°äææöêÕ+A_×yHø%Þ3£££3cÆŒ‚‚‚Gõ}KÔÀÀ@ÈšèÿNŠžMéïï–ÌÞ¼y3xð`bþuÀsrrðŽn¯^½RUUýüùóöíÛ¹{pŠˆˆP©ÔI“&<‰D£Ñ133+**ª2¸»»¦§§ƒ?-,,ÔÕÕ#""&Ož,''òú644²?‘ê©Tê Aƒ°ÖÖÖÊÊÊ‘‘‘·nÝâ¯Acgg'..þòåËŸ?‚-öööRRR>|ðòòJJJ1bDBBpÂþC$&&¦½½]\\¼££cÔ¨Q<èìì$‘Ht:]KK <„@éF&“A+4H$Šˆˆ‰DlŸØØX{{û¸¸8ð?8ÛÇAñÁÕJ^¹råŒ3”””ZZZÀw­ªª 2½}ûVQQ±¹¹YEEEII©ººZII©ªª D÷GÄÔgffâGåäätuuñ ^&LÀ&ôÕÕÕW®\áHV455MOO×ÐÐøþý{aa¡¶¶vuuµ¼¼¼ŽŽŽœœ\uu5ÖEÁþÏž=Ó××ÏÌÌì.5_عsçÁƒ¤¤¤h4–Ÿ¼~üø±……ð«[=zdee…¯XA£ÑÄÅÅmll’’’lllÄÅÅCBBÚÛÛgΜ‰uËïß¿üøl±³³‹‹‹+**rppÃJà[ÿ÷ßJJJ@ÿ `]°–,Y2sæÌúúzðç˜1cššš‚ººz[[[JJŠ]^^ž¬¬¬šš¸ÈÖÖÖÇWWWs®·aÃ… º¸¸ý>++ B ¢•»œ >¼¬¬¬ªª AŒŒ 6/@AAÁÌÌ üðkjj^¾|‰÷Úµkü²²²² Ú¸qcqq±««+ø‘fff655áw2dˆ’’¨C¡¢¢2nÜ8&%%2õš™™III…††_g[[[99¹wïÞ‘AMMMVV„“Ϙ1CBBAøøø¦¦¦1cÆ”––‚5¬›N;bÄ0f"¢¯¯ýúugggu3ooo2™ÜÞÞ.**:kÖ¬?Š‹‹wvvjhhHHH´µµIHHhhhttt$$$ttt€‹:thEEûùIôôô”••©Tê»wïÊËËÇŽK"‘˜{éÛ·o+**ð[Ο?Ͼo˜‘‘@ R©XçTQQÑ××ÏÍÍÅ?ô±[­¬¬¬®®®¤¤Ä/ñ¾K,,,ääänß¾%¥±°°>|øçÏŸõõõÁúççÏŸÁÕÈÈÈTVV¾~ý\äÔ©SÁTrrò!CšššÀÃ}Ú´iáçÏŸ‘‘‘Àç5==½¦¦KPjff¦¯¯ Hyyy]]¼¼|}}½žž^BBè–Ó§OOMM¥Ñh&&&®®®½b¹‰Éä?/¢P¨fƒ<=ÿ·ê«¬¬JCC½“õ>~¼«SGÇÿÖ„x×ÒÒ2zôè›ÄÄDK a‚888ˆ‹‹···‹‰‰}úôiÖ¬Y¢¢¢4MDD¤¸¸è""""111t:D"aØ÷ÀTvØgäÈ‘˜%jooÎæääD"‘]üæÝ»wà¾ëòòòÚÚÚŠŠŠqãÆÕÔÔHKKWTTK´ººZYY<äXämf&444..?ŒÖ××çççã—àŠ7LåååÝÝÝÙo%55uÞ¼yŽŽŽÀÑ¥°°PII©®®®   ¾¾^II ë¢`ÿ)S¦äææÚÙÙMŸ>] 7911ñøñã˜ÅõP0˜‚-3fÌHIIÁº%ØÞÞÞ,Ѥ¤¤ööv///qqñ‡bÝRCCÃÉÉ l‰···6lXLLLGG‡˜˜H|ƒo}öìÙ111`FD"‘g‰bii)öš@ 455•––JHHXYYÅÇÇëéé544”••‹”””œ>}úرc¹V¬###þüùæÍP\ÑÈȈyJ‘™™©¢¢‚Ÿ222ÔÔÔ€×ÓðáÃÙñÁ3jÔ("‘¨¨¨È€y _HIIÉÊÊJNN?Rccc€ßáçÏŸÕÕÕ eEEÅÛ·oI$RKK °DÓÒÒZZZ<==¥¤¤IHH¨¯¯;v,ðÑ=æˆ@ˆŠŠRWW—––.((Àºè´‰‰‰`ÌDdíÚµ‚³DŸ>}úöí[gg烜œœ€aúýûw`‰¶µµ}ÿþ]LL ÌßÀEþøñ# €#ÿ]0SŒŸ‰‰‰ ûŒ7Ž!RBZZÚÃÃýVÔ :gEEEnn.C(ìVWUU•––VWWÄÆÆ ô&§¦¦fddà_[ZZæææ644 bii ®6''§±±qРA®®®à"À3‰µµõÏŸ? x¸?}ú´©© <âŸEwÆ(ô…@ ôÐ…@ @c@ Q@ £@ hŒB @ Ð…@ @c@ Æ(@ £@ 4F!@ ýñ~wÅ555~~~àuzzºµµ5ü!@ 1*$) xíìì ¿B@ þ \¦‡@ @c@ Q@ £@ hŒB @ Ð…@  <8Mí$B$j1o%ðVB @kŒŠŠŠššš•”ã7VUU766Á[ @ ¬1ÚÙÙC“——kii[ètzEÅOmmm))é!CTñf«p>@NN•J…_$@ H_`Ö¬YÙW`jkkokkÇoijjBDQQICC£­íÔŒŒ¬áD<÷¿áIDATÃ…ðÃÃÃÃÃÃá@ Òhii‘””dŽõËÆÆEEeìÏÜÜ|AÊËK++66Ö76Ö——— GUWW§sBaaá¦M›èB&“9=dçÎ_¿~t+7n,**âè·oßž9s†£Cüüüªªª8:äéÓ§7nÜô}¾{÷îÇ9:¤¡¡aÑ¢E‚¾°ÒÒÒµk× ¡›8p 11QЭlݺ5;;›£C¢££9ÂÑ!ëÖ­+--å興ˆ‹/ ú>?|ø088˜£C:::æÎ+è «®®^¶l™ºÙ±cÇ>}ú$èVvïÞššÊÑ!IIIû÷ïçèÍ›7ptHTTÔ©S§}ŸŸ={víÚ5!|›œÒÔÔäãã#„ ;{öldd¤ [9tèP||þ¼¾ÍùóçsjÎqc3æädijj!RUU-%%…m¯««Ç,âÖÖV83€@ ðßíììÌÏÏ“””lkk“–Æ£µ‚Brò—ìì\ŽäY¡!##cee%„†LMMåååÝŠ••¥Š­­­„„„n‰Dtbbbööö‚nEZZÚÆÆFwÌÄÄDIIIЭXXXÈÉÉ ºkkkü̶_w3AÝ„„„„>‹‘‘ÑàÁƒ…0f*** ºKKK!Œ™BëfÂ3GŽ)„Ïb`` ¢¢"èVŒ•••ÝŠ™™™ÆÌÔÍ.|Fmmí99ùtzþ‡ÝÙÙ™‘‘¦¬¬ˆ ŠHŸdÈ!>>>BhEQ!´²páB!´²bÅ á|;‚nBJJjÍš5‚nEQQqéÒ¥B¸c3fÌB+ÞÞÞBhE8wL8ÝLTTÔßß_Skáü6§N*„VfÏž-„V„3þ §› § ‰µk× á³Lœ8Q­LŸ>]­Ì;v3Á£ÆÆFöö]L’:;;ed¤lmmÿÿf:@ t˜™™™“»uZÚWUÑØØl•””mkkDèHQáw]½atzØndd 'G`þ'//£©©.*JÇÿ¡#"&&)))¨e"‘¨¥¥%è{4Z‘••%‰ƒ h+òòòZZZ‚^AVTT$‰ °ôµVddd´´´½¶+++«¥¥%èE7"‘(„dØÍ8EZZšH$ zmtæ1fÂnÆRRRZZZªªªm…@ hii 2d‚hjjjii‰ˆˆ0¿ÕÙÙÖÚÚ^gffW4}“דûø"E„L&ÿy|…B5äàé9å¿W¬ÒÐPAï¤G½ïêÔÑÁ}4’¤¤œ¬,žI¹¹¹‰‰‰,¼ñ²³³“““ ­­­á<@ þËÛ·o+**ÁýMMMOŸ>%Ó¦Mëî¨ÆÆÆ°°0áx˜@8¢­­±¾¾¼ }–V3ÔU=0àFÿ¨M_[[{åÊAž?þõë×.÷©ªª BäÙ³g™™™ð+‡@ ¤Ÿ‚Ü?þ<ãڻ󠨮|à¿Þ¸Í*v7‹`0Ø ¢‚Aái'¬ q‹šg¿²,Gp™`¬1îÆšÑ—1Ž)RÂ@Ü­j¬¼2Ÿ!®  È ’ȨA‘%Ú Ø¬ÝMßî÷ÇÍk±!€ˆÈòýTÿqúÜsî½}Î-ùyî9÷Þ¼ID‰‰‰DTWWÇý¹ïWF£Ñ9rÍ8XÅYÆÅÅ©T*.­T*-éöÖ¬YÓm"##ýüüt:_~òÉ'aaa!!!DôñÇÿðï¾úªU•>ú(**Š{œÅþýûóóóûçiðŒøh€èÃ?LNNF;´ãççGD‰‰‰111&L@› }L °éôƒ¦è!“É”ŸŸvè‚N§KHHX°`Aÿ<¹S0*‰;fÞ¸ñÄ<ÎË—óV®ŒÏÈè0]ãüyR*éŸÿüíkb"Qs3)•ô{Olh ôtô %ûöíKJJâÒ[·níŸG9 .ܘ(7> F­ÿCϲ«Ouu•¥@KKë±cÇH±µŸ={ñ‰ÊååKk×RK )•”–FDdoO*55ur°¬,Z¶ŒŠŠÒÓÓ·oßž™™™°k×.Ëö°°°õë×sé´´´÷ß?33sÏž=|𺦜œœ¤¤¤œœœ¥K—fgg{zz._¾Ü`0LŸ>ÝÞÞþîݻӦM‹ŒŒ¬¬¬Œ·µµ½zõ*•——+•ʱcÇ ahKNNnkk»}ûvfffff¦F£Y¿~}vvvffæáÇ-F½¼¼¸ôÆÏž=›™™yèÐ!777L²ÁhÏ…„(üý'u¾ÍÎŽT* °Îoj¢Ï?ü5:š22ˆÈÉÉ)..Žˆbbb&NœhÙ¾{÷î•+Wré‘#G®X±‚ˆfÏž=~üxt- L¡¡¡AAA¡¡¡_}õUXX÷º›øøx½^ÿé§Ÿnذáâŋ˖-‹ˆˆðóóKMMmmmU*•sæÌQ©T©©©J¥²¸¸- CX§c¢ÜÛ€$ ÷çž3gΜÔÔT«2ýöÂEè}¼š¾¢¢2/ïêýû•§N}7wî}¸g¹\.—Ë­2###ÛõõõõõõE§À Å0̾}û𛛉hóæÍ³gÏ>pàÆ‚‚[[[îa7ýóVz€ÈÇÇÇÇÇÇ*ÓÖÖvñâÅV™ãÆ7nœå«]Ç20¼‚Ñgåà@«V¡W:Ú±cGLL ÚŒvÅËk´L&½téJ/‡E *)!ëwÜ 5÷îÝ«¬¬¬®®îÑ¿ÔBaPPТE‹²³³[[[sssßxã)S¦ Áhoµ´ÐŠ”›KJ%íÜùxò(7gÔŒfeQJ •–R\ÖÔÀñÞ{ïEDD,]ºtÞ¼y………"‘(777%%E¯×§¤¤Ô××Qbb¢]QQ‘X,.++S©T‹-R*•D¤R©‰Àð F«««‹‹‹¬2%mgg›’²¿›½p ˜:’H?ø‰ˆ¢£):CLxx¸ÙlæÒ›6mâ?þø£¥ÀÎ;¹DMM%³¨¨MFI&sš93¼÷üûß©¼œÖ®}œÓÜL+WRI :ÁèóK±±Ö™ÜsFÁhŸ3uÍÍj44Àpf2±/&5™Œƒ/ µ0'N|‹V<~¡‚“ÓOÀ²Æ—^òbY½0ÕÖÖ655Êå>7o–êõ½^gÙ<ƒÈôâƒÑöø|—×€ŒÆ¶K—rfÌP44Ôët-èH€ÁèÊ•<ÿÆF­L&5 f3¿ªê~O*öw0ʆÚÙÙ¶µé˜J 0´°¬Q àÑäÉþ÷ôzC×åùýyr#FŒôðð‰ømmztÀÖØøH&“ÖÖÖ `T«­?þ|]]½N§C aMmyù]“ÉÔu±§»Mo2™/\Èî˜/""Bz²Qjµ†a˜¶¶6__9ú `è)..±±aììlœû2%2·˜œüf,hž²íúó’·Âz¾ ±XLD666¹¹ùãÇû¶¶êˆèÁƒ‡Õ£ç£ææ"ª­­U«jµZggçV|ÖL‡S÷ݾy}ÂûzRxĈ‘&L²|0a’N§ ‹pw÷¨«« t$À`$“¹{xŒjjj‘HdV›x<^_£¿VÝÛ;/X,¶ýïOŽIýðø‘Ô»>–¹"ö!;v\*•DG¿NDGfºººDEEpM&ÓÉ“§Ï»`ÙŸÏ÷ô­V?ÄRlllÜÜ܇çoomm5›M<_£yâUðQQ¯/^<¿Ï‚QNQ~ÎŽw”%×rWÄo_¼|Qkû­—/çu:?ÀÑÑÁËk4—vuu‰„,kº— ggç)SÕê‡Ãð·ß¸QªPÌÐhÔ #þùçŸÌf3—ÒÕÊ¢§FÝ=ÇdüÏ«Þ)¹–KDþSËÜ¿_)“I;­Îçó%‰‡‡gMM•ÁÀVVV GG\»04477©Õ†á¯¨¨P(f45564h½½½õz½N§¯­Õt]«7v E Ÿªü‚§‡ùùO³Új0nÞ¼uùr^ÇŠ®®n£Fy899ÕÔTáJª ý¸qã»-ùÔÁ¨H`!6Ž—{?ýö¢…ò1®#ÄF!ÿ·aØ%Kþ³¢¢j÷îí;v¼×Úª³Lµ0™Øª*D¢Cß±cǺ-ót·éy<^P€·›XMD$¦w×þ‘šˆÈDìÿ—yçX"b&6v™Uõ‡0ŒÐ`0¨Õ¹Ü=0$iµ ÍÍ-..²¾Fe2 Ëz}f<a†a~ù宣£CCC£XŒ':ÀÐÑÔÔôàÁp\ÀÄ­Xª««W«5#F8‰DB‘¨ûPSØŸ§èêê¦P¼ÖþŒ=Ò:88ôäD>‘HDÄëç7®S¦L•É\üü&ÙµÏïãçŒöš­­x×®-¸F†0Ÿ§*!IxVB½^`´Ê”éí{Œ67«‰ˆÇç…E?Ë Q |öŒþœ‰L–œÒïJ÷ÌÚ&à º®ÈGÛÀ‹b=2ZZrK£®C»@ϹŽ¢‘Ö™Ù®òŸ\½$s‘Lò÷í*õŸâÇã РÐsj¡–ôÖ™‘Q!V·éÍfÖd2vŒšLF"#zÎ,0uÌdY=™»åì|“Xì$ ¸gћͦ––Zt6ÀTšUʲ–—rRÆžÔê< ‘Ènà£lK :`À‘좷÷¢"VÓÀ ÓM0ZQQQUUõ´;½{÷nMMMž¥R©DWÀÐ#`G«OSSËšžëqQ§‡®¯oê¶î©SgNœø¶ýùçŒ^¹r%??ÿiwzñâÅ¢¢"\^]3›Mz}£Õ§´´¸µµõyÚhÔw<ôµk…=©›ž~¸­­­ON£«×îß¿ÿøñãàØ±c›7oÎÉÉIJJⶆ……­[·.;;;99™Ë ß»wï×_Í0ÌÁƒ·oߨqÏçÎKKKãÒQQQ«W¯^°`B¡(,,$¢Y³f­Zµ*+++==ˆär¹Z­ÆÅ ÃÖ?ݹSND‰$4TQ[[¯ÕjÇŽ}™ˆ®^½<µ¶¶N«mø÷¿oëõz©T2ƒˆ®_¿Q^~ˆd2Ùk¯MïÅq‹Š®»ºº\#¢ÀÀ)^^£‰hîܘӧ¿o_ìäÉ3&KDÓ¦½2z´gaá¿ø|~Mͯ,k=Ú£—Áè¦M›<==ÅbñÂ… ¹œ¤¤$•JÅ¥•Jåºuë’““-9¹¹¹D´mÛ6wwwWW×Ù³gÿÞžÓÒÒ¬jqQéÖ­[¹=¯Zµ*==+sçμ¼<\…0<ݾýKVÖy¹Ü›ˆnݺ£Óé‹‹KÖ¬YID©©ÁÁSËÊnïØ±ûwâƦ¬ì–Á`ððp?>ÛÛ{ ýüs™Á`ˆŒ }ÚCñņ‡†Î ¢ŒŒ#;vld›.ÊöÙÁ¿üekZÚÁ””ðùük׊u:ýèÑó{Œvd4-Ó7E"}ùå—–œððp…BÑ“ý>¾c-.½gωD²víZzrdT©T®^½º‹Cgee•––ââ€áÉÇgltôëÜmzËÈèÀ9½Ï??$•J‚^>£©›`tÉ’%û÷ïW*•›7o&¢£GZF4·lÙoÉÙ¶m—X±bEBB7g´ÓÝ®Y³ÆRkçÎDÔ~H•Kgddpe¢££ãââp!ÀðÔþ6=G*ÙÜÜrâķׯÿ¤Õvþly™LRPÐxâÄ·D¤V×ÊåÞ½¸MODýë^î6½L&DtêÔ™û÷+Ož<3cFðK/yZJÖÔ<¸¿šˆ‚‚^9uê;>Ÿ—–v 6ö]xñâ-‰ËUªÌI’éóçÿ6ËÓÁÁe`>ôþÑ£J\‘0dèõtùò%«Ìººú7ßœåà`oɱZÀDD%%?ýòK¹¿ÿ¤¿ýí_|‘Â-`â–4i4µMÞÞcºXÀ$ˆÊÊîÜ»Wnuh–e££_·|}÷ÝÍ6Ä—””R»L§Náî×Oú Œr ˜ÜÝÝ„B!·té›oþ×l6ñùƒÁðöÛÖsF¿ùætiÝ£fºïÛpHˆ‹àEaš93¼Ûb“'Oœ ìŠN½)é^Dtw€8õ¡5W¾Ræ‹é‰GT»²ØI ÁD{‡Ð Ü'€*ˆ: æ*{T¤ ‚K‹›½­é) ü ´xøNÒf©[HÖ]yGú ÒÙÝHÁ…6êkP¹qbu®;ûÔJËÕ¬•ê[s„§Š5ÖÛuO°D?NyÕîÄq4GéñÇŽÏÔ˜ž’xA–ê˜4ìøŒrªÖÓcÞýUt¡Õ45•„Îv•’„'Ž€gˉzŽ¥yï}kñÆîùÊ£}žjYŽžf>’íø\Ó"È2¸Â?õ‘›†%\Fw¡@.wy’£%kQ•î—]„ ½£)pç"¡êŒ‡5ºh=ñÂØ8á#íJæÅ˜KbÁÖ”y—òÖÕOð¨7|éB¢-‚RykZóPôWøgð£Ãa´ º7.½‹!ÔLÑé‹E„ˆˆ.° á¡Ò—û œO’8ßå1ªjÛò;¿†’KQÃq)¥ãîÏ‚à@öÄ2Á€““Õ—ò6l,0¨’ϲ1 $zDPÈ`Ýš£D½‚*üóÁ•kÞC­ê àÕÖÃú*T»Íâé0ˆÕ*¨µ4eÑCKRœ2°†+CŸðÈŠ´Ô›™ˆÿ›ÈžX&Øn-ÌAÐ\ÙÈWrÈ7°mL‰D–6[ãÊ™Ó5þE™—ÔÜ–öö¥jH¬Ç‰PûÐq,!ùð[~dRZû±ße¬D’î¶Ä2Á¦î´8ß› l§»Ü˜="(d·æ)¹ëþsðýxî‘û †·G4ÁhQ,DŠÎ¼hCwÁÐ4tGc刔ºKÄBK¦|Oº èeŒ™xø¸^6¤]JtÞ™º½Å!rcÑ!RÈ oÍ'3†PáGåWlÔ6Jǵ´š¡¡JÓ`ÍbšÅà’¹ësÑphè.xÀܪ3…qŒVÁƒ)áKÅDÌ·d̉šD‚¢>,á'n9ïr¼‰©Ûó|–éB¢-RÈ oÍQÒ.fVùW䣠Òÿh–©æZô,f®ûIkêºó/J#‘ý"ÍÙG2šªÁâæ6?›ˆ ¨¢ÛCsÀQ—ÈAÌÄüwÿy"ó]½½©$¥3ZóŒ—6ÝzKË|?+S]GG£®Ì3S··åó”D·^æÿccï>ƒáv™Pt®ÁkóâúXzšð•½UHè÷ç™_=÷} íx¤Ï_¿ lNm3ó41rÃõ·íÑA³ü~Š[à·&®G׎ÀðÜ,ßðªëPŠ·¤¾8ïúr‚ÝP~¨aêúÊg¾Eõ³pçºnøqCe\>ôÈ}ÿ$è ø„(œ.ëÜ? ú X†ÊÉï¢îîŸýŸmZȯüIÐY+ÉRìIEND®B`‚snd-16.1/pix/fm30.png0000644000076400007640000000550011147553266012420 0ustar bilbil‰PNG  IHDR0òʬ™øbKGDÿÿÿ ½§“ pHYs  šœtIME× 9 u~¾ ÍIDATxÚíÝ벪¸Ðv—ïÿÊö/»)v®Ü2Ǩ:uv‹bXÂgaòú|>Ÿ&ôÇŸ` @€¿`¯×«k%¯×«û5—Ø‘ðú|>ÿ|>!<ê½à® êY§3;¸b³ý`€Ý¥egÒƒN !– 0õ@øû†TkX}çÌÌ9OKNâ炪bÀyûŽÃ÷ØÊ=^[6ª½½ÏÛ.ïÙ6s`Ô>¼¾§+¥FJ©eO…Wí½kÏÛ.ïÝ6z_߃ußÓØþwϲ§B¶g”–zÞ÷±Þm`,Ä~ñDz£Û,À ð°ñ×¶yÿc`j¨)À ðük!¶:o·{l©a¤ƒÀaöëÛ›`Àt½4ÒÜ[š ªÍ=Ùæ–e¥S-Rë($ÿŠtSÜ8®úÆž%ÀJ'zî—G=‘uû9‘µ%Kü+nu†€` XÝÛŸâÉUhøš¹œN©í½Û÷ýmᕺf°´lD;Sï½}^ê9µSFJ9,ÀR`¡†ðzËÍlƒ eÙ“Çqé½·×yÖÎwËK–b ‚‡×ìÎnS©Äƒ`!¶rM°ÒvÕzŸÊé@ð{DièÈ=²Z‰!Fó7$ÏØ+%‹e7 ŸU£Â…× ö~{JæD/§S*ŸÓÒ3+=ω¬dø¸Ÿ¼ßŸzлld›¯œž(U©QN‡%?åt~ƒ!$ À€VçWH vôìåtR¯9sÃ=0f{×T@¥.3y Ò‘÷.• J­£v ‚„×þ@Ï]Z”º{õˆÞWï{·©·ýûë!?9cìgR«s–{^éó4“ì+}±”ª¶în{¶¿90`Hp•æÊ¾ËR×S–^§&>è}Ý®§ôti¸&ÀÔÄÎ2„„ z_3—Ó©ý»ÖþRY“ ¿R“Ù¥e#ÛuUûs·–û/Ü”ÓaµÏÀ~d À€VáR"âhÉœ‘åt¶ïßr1÷ÕÛ§«år›”Ò²;ÛÜ{ÞÙÑmÈ-`0YÏlûXíž‹wê Í£ÛPÛ>ÁÊ<ä*°"ÀÜ=tQÛ^€0`¯÷FQæÎZ«TœÙ>'²BÚŸWÕss‹ÃÍ\ý¯R€݆Ü2åtXî3°B0€»¸+ Àz¹+0m€±ŽUïe8zT2C9–÷.ݲgªQ@ððJ‰tÙÈ6§Âjû¿ÖuÔJö0"u;±³ËF¶9÷ø¾7UÛ¶Ò6 0`Z ‚ #ŸŽØÆ+{‰  GÜa[ Ꙭb#jÛÏÚû`ð#ºp{på«4?6r]¹P>Ó~'²B ar®þU®ÔNKž;‡¼gß»¶ŽT¸©f8B0µÏ¨´|äçÛÚ®£í¯m›!$0-0ÐÈ$>“úá%j©žõçž{¦ýz`(¸RçAE-µsfýûçm¿cšƒ{u¥Ëˆ¢–Úi]ÿ·W™ÚÆ3íWxô˜/…Rïy‹jâó¹Ë¥rW"lŸ›ÊCHà±Kiâþpû×”J 0`øèkßKÛ[î5 Ï]‰`ò8õï3ËFµk?¯U[Gib߉¬8¤¶sC½åtî.µÓ»þܯ¹u´”Ö`Ä%gî.µsg9–¶B¢çãôi 0b @€42‰‡²¥Kí®*µsÇлåÎC©ç·¬ÇM= xpõ.«AmÙ®Zi=¹uBBµR:==›}=­Þ0<º¥õç. :ÓN<Ð-å‚ÒµœÚQà‰ár/ÆÔ;0ëôÈŽ|© 0 ü^î‚o¦ÇÓî‹ á¸ØPl_ýôÈÐíì{§zN¹×Õ¶aÿË¥óÀ øÁö¤ÍÒ²–/’»¿dZ×_{Þ‘vº+íIµöšf(§sE;CÝVÍ]‰€³Ì @€4ò+$ÒRNg¿|d9Z›sí¿j ®ÖåûKlF”Ó9²¾£íÌ-3„„j%sŽ”¢¹»œN©Í-ïÛÒÎÚ60Â÷L~½B† !y `À3=R½2Âk~…„IÂKpéÁ´=¯oyšm™š‘åtZÚ}¶µmЃ@!ut¸8¢œÎ‘6mgn™ƒf,§ÓÛ®£íTX’€h¤&>“:çëŽR4wÇ-믕 ª]Ô¢¶½º¾çªvX9¸JÕ¶ÇɾZCï²+ëgý­õÎZ—BB¥/òÜ}Ï,»ªÍ­ëß–ºŠƒ ‚­u˜5Ó°øÌÐñˉ¬0QÜÕ“z²ýûm8sÃwæ'¿éWbÎöXË\™3ñᇆ”³…Xn®ìèÐÑÙßWíf&z`¼W³?½"W¢wÙÕáÓúÞû¹°ý©TÛÿÏ-ÓƒÀ=‘ý¼Ñ>Ķô‘eW†~mýw¶C€A ^à“Ëžlsk;z·Å˜–€hd‚é½np†r:½—µž±¯‚«µÍþ¿#—ÓÙ_Ù ¥TY­–õ 0âh©™ÊéäND­UÚ¨­_€Á"CËÈÁ|ÅëRÛo & ¯Õ·#Ð¥2Bz`°xOföí(•rS–=ØW© ö ÛѲ©Ïô=rj‚c_ø³ý½ïj¯!$LðQ*+½œNéÔŠR¸ÕÊ íõ0hVE.§s4@[Ö/À POëÈó¢—Ói á£í7„¦%Ààäp À À€››_¿@€10€]3‰˜? À+W ü(_  @€ŒÅ†8NYðw]™›z¬—›z†€`Lω¯0–ç×8€€ãj&ÖA€MÍ/„ À À À¤ø50 ÀêÜÔ`½ÜÔƒe4„`¿Úø²` .3û¥Gz_Ì`z Àz’ ÀwøÕËv\®$Àü`+0ßäœ À– °/ 0;áõαõ>ß¾$Àxèà„0öz½º¿)VÜÙl“ÿÚ¿´y¼'Û¤ÇV÷.}@-Vïógû z‡=¯û>ÿhèõ¾¦öü+îSíùµ×l·9Êçpd_ZáËóHv¼>»WÝ`z%ÀÕöŽÔ8!„ °;S8ÒüÅÝïalƒmøßŸž†è!¡{`Û‰À–äì}>À­CÈT•ÂIp#üõ+äÐÆ¸~ï7v:Ÿ³Ïú"ÎĦ%Àðøõc2Ð`M¿”¨÷¤W'ɽÇbêøÊw½ß}\¿Ÿþƒ.Õü}<厵3ÿ~â¸6„ä’ƒÁu²sY¥3 À¸ä›\%ÚuzcŒŸþVÿYªgö}¬ôøöõûç”ÖÓû¾¥õ ¯9¼£üWêÖþÒΟ;Ró¹y—Ôã=]m>¦ô|=¯ÏÔÇõ£¦TÏz=®ÜA°¯5Ÿ §3Ÿin=­û•ðzeÿ޹ã®÷ñ'Žë÷ˆ¾g‡²³­9Ì<XW„ßvޮĿú9ä–÷<þÄqývH1¢žûÆ/}S§þÝz0–zl†”÷$] IÄáÍS»¥ðš›_!”è<í_JYÇ`*ÇIEND®B`‚snd-16.1/pix/hairy1.png0000644000076400007640000021361611147553267013062 0ustar bilbil‰PNG  IHDR /½¹¥”sRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ*g¥r­ IDATxÚìwxTUþÿ_wzÉLzO @Bè!B/¢àŠbïbùŠëª?Ûª‹«²â*®Ë®k[u-XuUE@éÅÐ{M)@Ò“™L½÷÷Ç$—„$4EÏëyæyfîœ6ç–9ïsÎçó‘¦OŸ® @ çè@ @ ˆ@ @ D @ „@ ¿xt'úÒçóñÝwß%zJ ‚6ðûý=ZÆå—_!:C ~ª‘e™Ñ£Góà@i$z½ ©Ý<Š"#Üj à·‚ÃQÇ=“&‰Ž‚³!@šp¹p¹ÜlÚ¼…aÆa0PIj-DÜ NdY=+‚ó‚_–±ÙBN˜¦¦ºN‡F«Ãl¶¶›N*ŽÁl¶`4[ÑiÛÿ›lhpàq7àõzÄI‚³-@dÙO]]~¿ŸÊÊJ<’$-zQð³RT\Lƒ³®]»ülmؾ}ÑÑÑDEEþìý‘Ÿ…Î:qå唕•Ñ¥K z½þ'·©¾¾žüüƒ$''c2)--CQd"##)/¯@’$¢¢"Ñh„Yšà Pôzn—«}±à¬ÇfA§ÓãjpRQ^Òfº¨èxÜ®Lf ½‘²ÒC˜ÍÖ¢Åé¬Ããv¡Ñj‘ý>Ñÿ@pšœÖ¿½ß裡¨ƒÁ@LL ‡ƒÚÚZÑ‹‚Ÿ•Ç—w ÝïkkkY°`!ÿûüKf}5›Ü¼<rsóørÖl>þï'ÔÔÔ´Èãñxøèã™`Õª5ü°di»u˜Ìftú–zþd[‹ŠŠùì³Ïq¹\8Ïg~JiiÌújeeegÔ…Eý¤>­¬ªbßþ\¼^ïÙyÐhµ˜Ìf4‰í;v°fíZ*+«Ø´y 9ëÖSU]"‹Í›‚Ÿ¢AdÅßöKö£(Š*V\ NJ޵ùòËþÀÝ«((Š‚ÇãbÿÞm8µÈŠŸúúöï݆ÇëE¬ö Á™ ;Ä’$Õ˜ Ч°°“É„N§£´´” «­VÌb ÎŒ²²2Öþ˜ƒ¢@dDýûg²|Å*|>/~¿ƒÁÀˆáÃQ™•«Vãr¹Ôí€99ëhhp1bÄ0µL·ÇƒËí¦k×.:t˜úz:$b6›Y¾båÉ7rÂëõ±nýzÊËËQd…ÔÔ®të–ÆŽ;IïÖ ÇêUk¶c2™¨¨¨¤V&!!Á,Zü=ƒ²³ÕU’ÐÐP$†òò Ž-ÇjµRZV†ÅbA«ÕbµZÙ¿?—Ý»÷à—ýtìБ޽{QYYÁ¦Í[p:„‡•Õ­V˲å+‘$¯Ç‡Íf£¬¬Œ+WBMm-={ö$%¹3»ví&77I#Ñ£Gw:vìHþ|vîÚ,ûIKKSW"jjjY±r‰‰‰DFD°qã&\n‰‰ ôíÓ‡ï.F§Õ¢Õjéß?»ÝN}½ƒ¥Ë–ãóù0 dföCvìØ‰Ålf÷î½øe™ÜÜ<\.Pª*«Ðˆç†àÌåG@€øý'(MÈŠL§ä4Ìæ iÊA‘åfiÂ#bP…¼ý;‰‰KäÈ¡bâ:‰£¾¦Ý‰†9sæ™™)N@ øÍpøP!^ŸÂàÁƒÏ®Ñh4ètDzF:vìÈÑ£G1›Í„„„€âG³B‚3 Gq»=ôîÝ »Í†V«Åçõ¢ÑjèÝ»K–,£ªªŠºº:ªªª1|8[¶nÅë ÌÔGFF¶šµ·Z,X¬ÊJËðù|„‡‡`0Z\Ïm±~ÃF¶nÝF½£žˆˆ4   £¤¤”­Û¶“ššŠÇã Ì²Ê n·›Î:Ç–­Û8ŸOLt4Fƒ‘à`{³ûÇ@°ÝÎÑ£G);ZFj×.”—WPS]ƒÝfC–e¶nÛN÷î鄇…²hñÄÅŲ}ÇL&úg±zÍìÙ³³Å„Ãáàâ1£Y¹ru`%+x<:uêDeU[·n#:*’­Û¶“œÜ™gÛ·ïÀj±²yËVÒÒºÒ¹S'EáÐá#¸ÝnÖ­[OÇ¤Ž¤$wfÕê5h´:uêÄŽ;‰‹Çëõb1›éß? ³ÙÔØ¯zÒR»âõyÙ»w?û÷å’Ò%ǃÑh$!>§ÓÉ AÙ¬_¿…ŒŒ>mÚ” §$?”€YöŸ8•IEQÐHm]rŠ¢¨Ë—Š¢ È~¢p9*Ê'4,’ÙßTq›Õedd0å™'Å-@pÞ›=¿Ú£é¿VQN¾ë@ÒH-ž‰í'$±.g5ÿ~û£Sjë© Ijt5xƒÁвŸÏ‡ÛíÆ`Њ+@pÆtꔄ¤ÑpøðaöÕ×3jäì6;v› EQðûýx½^´ZÖ +&£I áøs‚PYUEmM-#F cÛ¶í,$1!á”ÚÓ½{:11Ñlذ E‘©¯¯gãÆMØl6¼>/‡ãïL½^Ohh(&“‰.)É|ÿÃRqñqÆ÷MhX(E‡!ûeÈ?xúzééÝPŸÏGÕŠÝܸăÛí&8ØNPPƒ·ÇV§Å`ÐcµZ1 Í& $¬V .·ǃ×ëE–eœN'F£‰èèhü²¿ß‡ÝfÇb±¨N$dYÆãõ ÕhÔºý~Wƒ‹¤¤Žê*IhhƒŠŠ BBB((,bË–­ÄÅÅá÷ûûèØƒO¯×¡Õj ²¢×éQ0™Lââœ1’Ô¸ëDPš© E‘‘‘Z¥WPhÒ±#û¥žúúZ‚‚ìÔÕVŽÉd Üùíþ9Ë~?~¿¿ñÞi[)€^§;+¶Và·No<±“ Eáð¡|‚‚ìØƒÃ¤öwÔÔTâ÷x0LØì¡í …Ò#EX­A§µqÊÄd2Ó»_&.ŸŒÛß¶¡ŸI½ÞŒ˜Çœ)‡¡¼¼·ÛÓÒ&ซ*::Š]»w³vmµµ5 ýÎ]»ip60jÔ5mÕŠÉddÓÆÍ8œNÒÓÓ(((`Ïž}øý~Ö­ßÀ€þYØíöõXÌfì6z½NH+ƒóyÇië„……LEE%ú÷o5 ÅÞ½ûèÔ)‰  +Z­¯×KdDf³™„ø8¶mߎ^¯'<<ŒÈÈH’“;³oß~–×­Äél [·4 û÷ç²jõjjj‰Àï—Ù±suuu$uì@pp011ѸÝn$I ¬\‡ÀÖmÛ9XP@lL f“‰=º³s×.ô=É;ÇëÁçóa±XÔ“SWWDzå+9b8-. :N¸åœ ŠBQa^›Û°BÃ"Ô{R ü /Ž,r`ECu5¯€£¾–#‡  $,,ŠòòŠ Ÿ„F#’ºE³=ö(¤¬Ê©¦’ŽD…Zèž–"V/P*+«ð7®ti4Z‚ƒí,_±ŠÞ½zÒÐÐ@AA!YYýZL@+Ž-gç®]döË  °¯ÇKŸ>½¨«¯gË–­x<úeô¡t:=v»MPª­­Ãj l\xh4]#í Yöã÷ùÔ1H~î.\ÎV邃Ã0 h´Z$IÂårr0o‰SÐë ×—¢Â¯×ƒV«Sg2S»vm5ÓÂðaC©««Ç`ÐØ‚F÷îÝèN·F‘}l^§Ó1jäpÂòÝÓ»!Ë2v»Çâr¹0›-Ô××!IC‡ Æf·¡×é2xAAÑëõ†^¯Ãfk}sÆÅÅ2jäpl¶À@ÿ¬L\.7ááaèõzú÷Ï¢²² YöŠÙl"µkW¢"#q¹ÜX­–ÀÖG`ÔÈøe?éÝ6^o nOJr2:½Žˆðp´Z-C¢²ª EV Âd2Ñ?+“ÊÊ*|>!!ÁØm6""" ÅçóAtt.·³É„Õjaà€þX,fL&3ƒ Än·Ú(¦t¤¥v$l¶ @Ùlté’‚Ï8GiÝÒ@HÁY@AÁïó¶ZðË~4M3}’„¤ÑPUYN]]u‹t»qUCR'jk« $4Y‘ BQ”ÆãáínÁjŽ=ÈJll’$5{i$ E‘©8Z"NàÌÊU«‘ý~lv;f“‰ìì$&Äc6›¨¬¬¤¼¢¿_VWŸeYÆb± Óé6Š .uBH¯×áp„V«¥E=^¯—† `±XÐh48ŽÀ„˜N‡ÅbÁãqsôh9>ŸŸð°0|ÿ‡¹ûs)))!½[7ê¶oßFÒPïpн{:i©]Q…M›7Ó?+³Ù“àB{o´-@E>¶UQp¹œøÚp#îr5Ve•ÀôŠF£EÒhÈËÝIçätàà½hµ §²ëŒ§0LP÷‰‰IÁb6›1›Í-Ž5wm›¯¾ m•¿­cv»½Õê†ÝnÃn·µ3‹ !¡Ù6­&Ñ.¡ÍÄM°*$š‹Š&äçSVVFff¿6g” C»õ4}ݪmM¨9áÇÍ„l³ìv»ÚNØn5­r4¡×뉎Žjq¬ÉÙD“ÍL Žˆiš·->.®Ùñ˜6ÅÖñ¿ñø6 gŠßï'1)¥ÝïëjªÕ@³ÅŠ¡½Ù覕IÂï÷ß*Ixdàºw»\™ã“ü9êõZ‚mVU|h4ñ!i4(²Lm•NœÀ œøøxzôHG’$|>?æ¬S·7 vïÞðØ(þGÊfÅŠ•ÔÕÕa2šHOïFRRG6n܈¢ÀðáCÕÜn·‡œœuTVU¢×ëéÛ§f³™5k×6ŠgY™™-ìšróòp¹Ü$ÄÇ‘°¯×ËÁ‚BÄd1jät:+V¬¢¤¤„´Ô®TW×`4Å–Ø Ù/#··ªqwB“ã“ÙJÇÎi­’•) ØÀ5^»’$ŸÐ‰âÂ<òrw"I:ž„ÄÎH’†3Ч.@t’B¤A:ásVbõC hFZj*i©©?KÝ‘‘‘Œ¿ìRq¿z4 åGp"% Õ¶48ëq»N2˜ý­®<Š_>±¹Ñ„Ûí?I ¥ãV?_Íà‚&ÿàAŽ””`±˜>lh«ï ìÏÍÃb1c6™),,"½[‡»ÝNbB‚:±”ÚÆFii)¥eeŒ9œ°°°F'#n:vè@ƒËÅÁƒ),,¢cÇÄ6Û—šÚ…¼¼|.=£Ñˆ¢(QSSÀY)9BtT”ˆÇt!£&YÚ[‘$ŽmAmrÞÑÆ¶UEiæ P l;W…ØøŽìÙµ€®i½Ô´œËI‘1ˆS+‚_’$a³ŸRZƒÁˆÁpj{ñ-§¹§¹ýöÑBx4µY’$aûñ+ k—úöíÐÂñÆ1 ¸,+11Ñ„‡‡a4š9bÕ55lÛ¶ÒÒ2† Òvü%)à¨ù¬ôî={ÉË;@ŸÞ½Ðjµ1lNŽßïgç®ÝÈÏg`öbJ—””2pÀq2/è‡a“xhïZж¡Œá¯©¶ˆRãôˆ(2~¿—ƒû±ZmH’DáÁýtHêð&zϰS õŽZ4ZN¬q@PWWAg=iì+¯×GCCC û$Iƒ,ËízÈüz0›-¤wëÆ¶í;(--Ål2‘’’ÌÂEËðxq®º¤$—wEQHH8¶ý/.6†‰ ,]¶­FCÿYD„‡³oß>öçæ³q:ÊÊŽ²uë6ôz=kÖüHddý2ú¢Õj1ÅTó…NuU9‡Š Úœé–Þ·ÑÉF£û>Ei;psgHø|^ ò÷£ÕiIHì Àáâƒäï§CÇä3ѧgu^¼8@ðK§¸øu5n,ó ÓÙ‚,ÔÖVµñM``·‰U ˜KÇ]ÒbÛ’Á`àúë®E¯×¡( IIIèõ:RR’IJêˆCÓWmìØKÞØ$ }c\ªÁƒ³[Öt:ú÷Ï"£Ñƒ•N§C’$®Š™ÐbUM£ÑpÅå—¡×ë8 ¿º&-5•®]º Óìý®»öµlF¢¬ì(‰‰ ÂûÕ„No 8¤m{X嘓 4Z-ee‡Z¥3Mê²D` –Ùb!<2F½¦bâ©(/CVäºó=+D ÁéLpp°èˆ_)mÅpi¾’Ð|P|Z}ÁpÛ «ÑhZÅa;þsócÍËÑjµj;$IÓj¥#&&Zˆà_n—FChXd›ß74s¹ëpÔb ²Ÿ ¬t:=>Ÿ¿ßGpH8¾ã¶ÚƒCñ7Æ;D @pʈ•_²ì?©{pH£«~Ï Ï»Å„^oh´‘O˜Örþˆ¢(üøãõsXX©©]p8œìÛ·Ÿ¾}{«ß­_¿‰ºté|Fu¢¨è°ú¹gÏt‚‚ŽE|,,,¦C‡€KÓM›¶’–Öõ¤KãíѼ¬¦÷.—›;v‘™Ù÷¬^06lÆëõl'=ýÔ=&ù|~6lØÄÀY⮂ãhhpQ__OddD«çzËg©õë7“KbbÂYmƒ$IhÄàN œ!©ÓÆÓH{jè †“jù4WA~²ñz½¼òÊ›ÜtÓ5*Z£>Ð+*Zîy=z´œ™3?ç_ÿzñŒêzï½éÞ½ƒ^­»9o¾ùÓ¦M ¼¼Ÿï˜ûÄòò Ö­ÛÄ¥—Ž9¥ºš—ÕôÞï÷S^^qV/–¹s¿Åårc6Ùºu;^¯—Þ½{´™ö£>ã¶ÛnhvÂeÊÊŽŠ;N Ú °°˜5kr¸ãŽ›[=×›#Ë ¥¥¥ÌŸÿÏ?ÿôÙhµèdYš ‚_'ûöåÑ11éü €¸¸23ûb6› ,Ã|õÕ¼€Ïé‹F¨é.½ôbV®\«~Þ¿?÷ßÿ/fqÅ'Y‘Ñ“ÉHTT$:Ž={öñᇟb2©¯¯`íÚõ|ûí"ÒÓÓ°Ûm”””ñÜs/‘›{€•+×ð Ϝt¯£Ýn£¶¶Ž}ûrÉÌìÓ(¾aóæíŒ{‡ƒ—_~‡ÃA\\,wß=‘¯¿þ–ë®»€o¾YÈÈ‘COQ4/ï·Þz‘‘|ÿý2Ž-çÓO¿Äçó³kײ²2¸òÊËxñÅ—ùúëìÞ½—;®]Søæ›…,^¼ŒË/ô[CCÿþ÷»”—WÊ}÷Ýͼy Ðëõ¬_¿‰îÝÓ¸á†kغu;_~9€1cF2jÔ0q÷‚_%ÕÕ5>|ÌÒ9 ¼þú¨ªª&22‚{ï½ ³ÙÄøñãX¿~³šïã?£ªª†#GJ7n Æ :ã6Ȳ¿ß+N†@ øURQQ~Úä¬D›Ù½{³fÍcãÆ-ê±;î¸ù¤F)ï¾ûO=õO=õkÖ䜒Ëܹß0kÖ<êêbãÃ?eÚ´)<ñÄÃìÛ—@vvYYTW×ï]úÓÃ\qÅ¥L›6å” ­l¶ êêê8x°¤¤ŽÜtÓµ-ÜϘ1“믿’§žzŒÔÔ–,YÁæÍÛhhp±xñRvìØÇsú:+V¬¡_¿ÞL›6…;wÓÐÐÀäÉ0bĦM›B×®h¿&\Ö"’÷œ9ß0fÌ(¦M›Â¥—^̬Y_³~ý&ã™6m .—›‚‚BfÏž§ö»N'Ì€Á¯—73kÖcÆŒd×®=­ê\¼x©*âdYw@ øÍУG7JKËÐjµDGG’žžŠËåâµ×þCNÎ~øa9£GgÏž}¼øâËèt:U¬àì MŸ>]iïKǃßïçž»ï ÞQC\|D›j§³¡•·©ÚÚ:¼^/’$ˆRYY…¢(èõzìv~¿_Ý&e±˜1›Oì±Êél ¡¡Aýl$jjj$ “ɈÅbÁåráp8Õ4M‚Åápàr¹ ;¥Îq»Ýèt:ÕõX]]=@-£ªªºQ$è¶#Ë2“ɈÓé<¡ýGÇ÷ËäÉÏòç?ÿ·ÛÙlVûÖãñPWWÝnC¯×«¿ ,,I’¨®®Áï÷£Õj nÑ—Ë^¯G–ýÔÖÖdÁ%Á¯¿ßÏçSŸqMÏæç¤N§%88EQ¨¬ 8M1™LX­&O~–?ýéa|>AAAmFˆnˆðdøÈ‹Õï ™òôd$ ´zY؀ΠNgẔ\ðËaݺÍdôÉdÃú5¼ùŸÿ2|øð“æùÉ+ [·ngïÞÜÇ¢¢"1bH«´MB¤ ­V{Êb@–eæÏÿ®ÕñaÃÕâ˜Édjs›–ÕjÅjµž´®;w³sgË•ƒÐÐÆŒÙ*m“Ñ}“ÉØ(ªN.>¾ürn«UˆÐЂ‚¬-\ C ¸Póþjë÷„„´ vÕ¼ MíÒj5§Üï@p¡’“³ââÃ-ŽuêÔ±Õ¶TI’Z={öLoœä~~$IƒF£Çç ­Ö(øýÑ9‚ ’Ÿ,@""Â[  ƒ‚‚ÎÁÍ'µ?äLã|œˆ°°°Vu™Í–srRR:©a훸øâQâÊ‚ŸHLL4f³©ÕóýT¸é¦kÏK­V«ê¾^ hBQÕÙ€F£Çï“°Y“Œ>®]»éÞ3YM£×ë[]ïÁÙ¢¡ÁÕ*üÅÏ*@âããˆ;ê_jÔð\Mllôy©«OŸ^⪂s@çÎI¿ø6jµ…ZЦ9Ù/·ˆ'SW_×jœ$®%Á¹‡ŸMNK€ÔÖÖ¡×»ÄYÁožúzçЗ‹ú¿ûöÛï£Õê˜4i"AAAȲÌo¼Ã½÷þ_ ×ðÍùøãÿqë­×°téJºtéLBB|›iŸ}öE|ðÞV[xO—æu6:,Z´„Þ½{uFmøâ‹9Œ?¶ÍmØg‹o¿]„^¯o±-{ݺ̞=ŸÑ£‡«ñϾøb›6mUcw Î=>ŸO>ù‚Ý»÷ñàƒ¿'&&š;v““³»îº‡ÃÉsϽDïÞ=¸ñÆkD§ýLœò“Ól2qäHÉ)Åêà·@dD,~Ÿïœ•ÿÞ{3qâMx½>fÌø„?üáÿ˜5k.?ü°œßÿþN mÒÜbQÑ!bb¢ðxù(p\c2OêtGpf”••S]]ۢߣ£#¹òÊËÔ4V«…çžû3Ï=÷wõ˜Ë妪ªØÒšÍ&êêꨯ84ŠŠŠ«K?—Ñëõ$&Æ‹ ¿Oƒ£þÜ ±cGóê«o0qâ¸\.RSSèիljÛå÷«qOvìØEVV_Ž-gÖ¬¯¨¯wòä“°gÏ>^zé¦OŽ©¨¨àõ×ßÁn·a4IOOeÛ¶Ü~ûÍDD„ñ ÿ`Ú´)íÖ»}ûNl¶@l¬ŠŠJÞ|ó=5VV||IIXºt%ƒÇˈC(,,R,\¸„1cFrûí ;;ƒÁ€Ëåæá‡ïãŸÿ|]uüBvv³f}ÅbF–5˜Ïç#'g |Ï=÷ÜÎÂ…?¨ž++«˜2åO¼õÖû8NÂÂB0 b®5 ,¦ºº·ÛØ1#IMíÂgŸÍ¢²²Šçžûsãà5°7Þårñä“¢(Šº_Þãñªâàž{b„˸é¦ÓŸyß±s'G@€I’DEE¨Š^/ IDAT¥¸›!ËÇúÝë=Öï ,fÙ²Õ¼ÿþëíæ}ûí4í0òz}üáwñòËÿVWccc¸öÚ ¢“"àü²páx`^¯¹s¿á¾ûî¦wïžÌš5ï„ù´Z­*>úè3u`U^´®Y“ÓO>Bff_FŽªæ‹A–ežxâ!</99N«½yyUÊÚÚ:¢¢"™4év ÒårsÉ%£éÙ3;v³uëvvìØ­¶µie k×dþøÇÿ§æóû},]º’aÃ7 ]$$Ä‘‘Ñ»…ã–•+×ðÒK¯Ð¿?þò—?°bÅuûÙ’%+˜2åOØí6®½ö ’’:²dÉòvOUU •9RB§NéÓ§'÷ß?‰©Sÿ¦¦™1c&ëÖmä£>cÒ¤Ûq»=ü㯱nÝF¾ÿ~)—^zÌ=óçŸpfB×ï¦Wï.9\Š$™ˆ‰ 7ÇqTVVòöÛï³sçú÷Ï`èÐ@åÛn»‘Ý»÷0ï²e+éÙ³;X¹ºï¾ÿC–õ~™8ñFÑÁ¿¢Ñh Oµ5Nª«B “É&Ά@ Î[·n¦ªª²Ýg{[Ž/¹dz½þ¼´Q–e4 ¿ÿ§ŽýÏ>àÙg'SSSǺuOšÞ`Ð3th¶*BöíË¥´´ì„yŽ)QgéÏ„•+×0zôp,¤¨èP‹Æ æé§ Œ$|zvîÜݘn?þ¸P˜0á2¢¢"Õ|O?ýX+cÚQ£ŽÅ,Xºt%&“‰ìì,>øà.¾x$))yå•7Ûmó½÷ÞEaa±*´L&#O?ý8NgC ñ0gÎ7tíšBzzª¸Ï2á<ôÐøò˹ªø8UºvMQ¯e?cÇŽ¦_¿>üå//òüóO‹Nþ¹ˆ,Kç¥Áï¦ÂïÀ  {Y}z$NßJ^’ÀlgC çÜ܃ Á}RRg¶mÛJP•ˆˆ(~üñôz-ƒ¤¤NlÛ¶ “ÉHJJׯI¸óÃ}÷ýo¼ñ.:Žßÿþjkë˜6íŸ8Nž~úy²²2¸úêË[åËÌ쫾ïÒ¥3!!ÁÜtÓ5<óÌ Øí6Õ@|Ù²UìÝ›K~~!<òbb¢[ämjÃßÿþ*‰‰ 'Œ!ué¥cHLL ®®žôô4:tHÀf R·‚=öØÿÃjµðúëïðÉ'_Æý÷Obܸ1jš ~‡Íf#..†yóPTtˆqãÆ`4ÉÌìË3ϼÀ£ÞÏСټ÷ÞÇLžü,&“‰Çÿ”––1räPFŽÊ–-Û)((âî»'ªù.¹d4#F !-­k›!JKËÔøZ7Üp5¯¾úUUÕdgg‡Ãáä¯ý;‡“yó0~ü¸VýÝÖ9h¢¸øÑÑ‘âæ;GX,fºwOkqlúô×p8œ¼ñÆ;ÜwßݪºÓÙ žÃk¯ ^#7Üp5½zuçðáæÎ »ÿþI¢sÏ2§ ]£‘Ñè³/Ÿ•šMTúÍÙs„Û;\ÍۯϠ¾>à»:88„šš€QÍf'44˜  +!!¡Ô××£(2C†dMHHq6@pÞ˜9s‹›ÍNDD(ùù(ŠBTT ³fÍÁ`ЉV+qèÐat:©©Ý¸âŠ‹Ñh±;6 Ž3Ž„n·Û~ñÆ­+W®áС#èt:JK˸ᄏÏy“'?{B[“_;Š¢P]]Óêø‰¶` ¬V‹¸±ç‡Ã‰ÇÓvàË3‰„~ÆÑ<Ї¥A}Õ¹êe§³³ÙLxx8ññqH’„Ùl&%¥ :ŽÄÄÒÒºJ‡ˆŽŽ9å:8Ð*èáñäçç³xñb\.á.X 'ùÔh¶#Ë2QQ‘¸Ýnõ;½Þ€ÉdD–eBB‚Ûýóýµ3tè ºuK¥S§ŽÜqÇÍç¥N1ã,üº9gFè‘Ô××µÚ'k·£(2&“ ßi¸.ÌÏÏgâĉ,^¼¸]ÿÞ………,^¼˜””>ùän¼ñFáêN íb±X0ôøý>Ìf&“I g³ÙÔÀo&“I]õ8›lßž‡Çã½zJôìØ‘ÞjŸ—¤¤dŽû£5³o_éé餧wkñ]hhØYmÄ cD„eA+Ú3B?‰‰1$&ƈÎ\œõ-X²,“——OmmË'33 «5Iò«ËÝÛ¶m#>~ÜIˬ¯¯gúôé,[¶ ¯×Kff&&"RŽ?ž»îº‹ë®»Ž©S§2uêTE¡wïÞtïÞ]œa@ ´IÀÈ\ÓYßâø–-{±Z­8õª'Ç&òó 0 —è<@ ø% ›ÍÆ€Zx ¨y©]7„'Ãjµ2yòd&Ož Ðb¶hþüùêgI’xê©§ðù|g´|)Á/‘œœ =ZÎe—=ïuoܸ…O?ý’éÓÿª›1c&F}à wò¯½HLLŸ>›Í›·Á#Üâ1TTTÒ¯_®¹æŠ6ëzê©¿ò׿>Õêý™ðÎ;ràÀAâãã¸í¶¸òÊ›éß¿½zuçÆ¯i3ï‹/¾LMM-d2aÂïÔãsæ|ÃÁƒ…<ôнlÙ²/¾˜‹^¯cÒ¤;ˆ‹»0W|>?/¼0E)Sž7Ûo”矟ΟÿüÇ W€€ÄáÇZ­€x<2ÉÉgf¼"IR»{d÷²Õ´K ‚ •mÛv²aÃf œO–*+«xÿýÿ¢Ói¹í¶ÀÀÿ“O¾ÀårÃØ±±aÃf\.ûöåѧOO22z“›{€+ÆÉ_<Š„„¸SnǦM[8x°°Åÿêœ9ó·<{ñûe^~ùuºuëJÓöêÕ«s0›ÍL›6…ââüþú;øý>n¹å:bb¢™3g>990 ³U}Í£Ïûý~jjj™5ëkõX÷îimæk‹°°Pî¾{"UUÕ¼ó·\tÑ¢£"iüø¶ÅÜK/½Â=÷ÜAhhÿûßWlÙ²>}z²páx½^µ_|1—çžû3^¯^øÏ>;¹Íò>ÿ|6õõ¢¢"¹ì²Kp:|öÙWôèÑþýûqð`!K–¬`Ô¨atì˜xN®«‚‚"êëlÞ¼ »ÝÆå—C§ÓòÌ3O0uêßÔt¥¥e,^¼ €3INîÄÖ­;èÓ§'ùù„††,nÔ_o½õ>eeGèׯÙÙý™1c&‡¸âŠqx<^víÚÑ#¥h4n¾ù:rr6°bÅjü~?ƒ ࢋFœó¶ <@ üÂøßÿ¾bèÐl†Ífåʵ¬X±†¡C³ÉÈèÍo¼Ó88ÌbèÐlêêêY³fo¿=ƒššZ†Ífþü…44¸øøãÏÔ²Ö­Ûxâc+yy¹êªñª âÙ³çÀUFâŽ;n!$$DÍçõz1“ƒ‹§Ó‰ÃáÄb xÝÐëõx½mïˆX·n#“'?ËäÉÏ’——ÙlfèÐl À–-ÛéÐáÔæW_}9åå|ñÅî½÷.t:2dH /^ý6ó95 ŸN§Ãëõ²páFFŽª¦“eFƒÑhh7F̧Ÿ~I||,C‡fÌîÝ{yíµÿ¨çcéÒ•TUUóÁŸ¨Çš„ç¹`óæmÌ™3Ÿìì,ÂÂB˜7oA›éìv;ÙÙYdggñù糑e…ùó°aÃfŽ)7é/ššZúöíEß¾½HKëJQÑ!’“;ñÌ3Oðç??Êüù ÉÊÊ`ÇŽÝ<òÈ}L˜ð;ÊË+¸êªñ ……E|ðÁ'x½^,ä®»n%""œßýî$ E&3³/ï¿ÿ_†Í>å6ääl °°˜M›¶²lÙ****ÉÉÙ€$ITVVQ]]ÃwÜBxøÙ3Ìïß¿Ÿ}òäg1ôtì˜ÈŒ3ùÓŸ&66ú”Ë*/¯`Μo¸þú«°Ù‚xûíµ¬*?þ¸—ËÅìÙóÙµk>zÿ)å»è¢¼õÖû8 Û¹ë®Û(,,VÏGII·ÛÝâ|7Å¢9\vÙX’“;¡( ……Åm¦Y»v«V­U…¨àÂ`Ĉ!ª Âüù 1bH›él¶ ]»¦´ú®¨¨˜ØØtºs+„à†V«eýúM"&¦µ}ÁÊ•?2räP‚‚¬Ì˜1³Ý²jkë¸êªñ,^¼”K/½€wßýI’¸ë®[ÛÌwï½w©ï'O~–ðð0^|ñ/ìÛ—ËêÕ?¢( 6l¦°°˜-[¶“’â wïÌš5—õë7±cÇ.®¿þ*EaÖ¬¯éÑ£‡—0xðÀSê—ËÅóÏÿƒ¾}{qèÐaü~‰‰¯e÷ßÿwÜq3ýúõi3ïôé¯qÑE#Ø·/£Ñ@×®]øò˹¤¦]‘‘jÚ)S^`ðà\|ñ(&N¼‰™3¿ GnTVV1fÌH²²2TQóᇟžžÊÊ•k¨ªªa̘‘m¶áÀƒ 6‹ÅL~~»wï%%¥3C†~LL4ÁÁv,‹z¾ssó¹á†«ÎÙµ5gÎ|dYæèÑrÂÂÂP…-[¶SZZFAA;&²uëÆ‡ÓédÓ¦­HR`µkóæm,Xð==zt7é/²ØÊ—œœÄš59Lú7$IâÖ[¯ .®uËë®»’©SÿFbb‚šN³Hyy9UUUí. @ðsrë­7°sç.Fßï'))°ýÈh4ríµHKëÊüù ©ªªâÁï%44˜˜˜c+×^;£ÑØb[Os±1p`&3g~qJí¹ùæëZ|Ž‹‹aäÈa(ŠBQQ1ƒ÷Çétrôh))¹æš ,Y²œ#†ªö ÇfË–m\ý•Øíö“ÖsóÍ×áõúèÛ·'¨Çh4ª$55…ŠŠö£¥_tÑjkk©­­Ål6Ó«WúöíÉÞ½û¸çž;Ô´cÇ^¤Ê:wNÂï÷³}ûNn¼ñ‚‚¬j:›-`7Ñt޾ýv‘‘ádg÷o³ dòÝwßSQQATT$Æ "++ƒ `2ILŒçÎ;o&'gÆ :§×ÖàÁ).>LP•‘#‡"Ë2ÅŇ;v UUÕtì˜È­·ÞÀÚµë°XÌL›ö4 £G§¸øp»³ê‚ŸŸ¶œ*4ŸHhâÿþï¶VÇÒÒºòÌ3çÏ ÁoN€°uëVufE ‚_©©)êLýñhµZÒÒºpÙe—´ø®y º¦4:$¶i;Q\|˜«¯¾ü”ÚsüŒwPPAAmMW]ÕºŒàVÇ;wN¢sç¤S®§é}[å7µ¡{÷n' ÇÓ½{·6ó/ ºtIV·D5Çh4´8Þ´št"ÆŽ½¨Åg³ÙÔê7ÅÇǵ8v®¶`FbccèÞ=M=¦ÑhZäGD„µ8¦( ë×o¢²²Š   bcE¼ §E¿~ýè×/`<÷׿þU\‚sŠì÷3ûß1áÞ¿¡ÕéE‡‚_ ÇŒ/4î¸ãfqO“qãÎìœK’Äý÷O(D ¸ ˆìgÉç/3~ÒóB€àg£¼¼¢]£sÁo“  «jˆî÷ûY½úÇ6ÓY,23û "@ 8RI^^>‰‰ñ¢3H’–:«Ÿ}>‘‡Õ„Ñh¢´ôz½žøøg½~!@@ ø™™?!¥¥eª‘øòå«yå•7‰ãÉ'áС#¼üò¿éÐ!`€=fÌH¢£#ùôÓYøý~,3wÝuÛGãž={>©©]HOO=£ü7ni×U?þ¸ž‚‚"®¿þªŸ\Öñ¸Ýn^yå-ªªª?~ƒõçÖ['‘l‡„óĵʷtéJ>úèSbb¢éܹ#wß}ûŸÃÊÊ*Þzë}êêê¸æš+èׯï¿ÿ_öïÏS#À; ¼öÚÛTW×på•—Ñ¿?5J<ÀÁƒ…|òÉ»çä: eàÀ,ôz=’$‰ï7ŒF£t¸\µÍDIÀ&(44F¢¤DA£Ñœ“ßB€@ð3‹ÐÐ`ÒÒºðÞ{s×]·2|ø`öìÙÇ%—Œ&66†ƒ‹¸þú+¹üòKÕ|ÿüçë<øàŒÀétžV[¶lãÀƇË墸ø0{öìÃn·qÑE#ðùü|ýõ·$%u #£7;wî&..–¥KWÒ¯_ã™3çþûßϹå–ë3f¤sãxŽ-§sçNêç;wÓÐࢰ°˜îÝÓHMíÂüù yÿýÿrË-×1thv W¹'â•WÞâî»'¿þõ&;'‘ÏØ±QQQ©ºÑm-\còägY³&§Õw‹E4~2Ž)aÉ’•$&Æ“˜Ï¢EKX¾|‰‰ñ8N,XÌ›o¾«¦Y±bM£@ÙÏK/½Bbb<|0I’HLŒÇn"11½¾ýAm\\,Ÿ}ö¥úyúô×)(("11ž™3?G–eââbÔ²ŒFã)÷aUU5¡¡hì:ŸÏ‡Ç㥡¡ÄÄxf̘‰ÏçgÉ’åêkÇŽÝ-Ê ¦ººšÿü碣#ILŒgÛ¶ìÚµ—ÿüçµ/V¯ôÿ²e«Ô²6mÚJRR‡fâc;·Ür=555„„ýöõõª«ÓjµøýÇ ,fܸ1ìµ\PPÄ’%ËihhßËèÒ¥+Õ~«­­;­ò÷îÝOAAa‹c•,Y²œòò ü~™%K–Ÿ¶'±€È ´ëС#¿§%K–ãr¹Ïz_54¸Z\{÷æ 7nùÙÎahh²¬¨÷ĹЉ)ˆ@ ?#ùùLžü,“'?Ë?®o7Ým·ÝÀ´iS4hÀOª/$$ƒAÏW_Í㫯摖Ö€ë¯¿Š¬¬ ’“;S^^ÉáÃ%dee••AP·ÛÝnSóÝ|óuH’DVV±±1dee`2™Ú­·_¿>j”f€˜˜(®¾úr²²2ðûeE!#£·Z–ÝnûI¿óÿø+cÇ^DVV €‚ß/«/E‘ÛÌwèÐafÏžÏW_Ík< UUÕj_Ü~ûM@ Z}SY²(kÇŽ&ñqÝi·wÓ¦­têÔQRç›êꊋsèБ¯‰â–ýv„ ã÷Ë|úé—8 m¦{çÕ~{ï½N«Š¢´ï½÷1~¿Ì»ï6•8ϧ˻ï~¤¶«©,EQ˜;÷[ÊÊÊÎz—””2oÞw­®GYVx÷ÝÏJû÷`ÅŠÕ§œÞ`0b6›€@ëõzìv>Ÿï¬ÿþßÜú[EE…D(‚_ :udÚ´)@ â8fôËÊŽRPPØnÌ… ‹©©©åðá#ÄÅÅ’’Ò™ÚÚ:&MzÏ>{¿Í|.—‹¤¤ªÞY³¾nÓ0944D|º\.ôú–žüRRްjµZrs°{÷^Æ×f½¤ªªš#GJNGÂh4›{€íÛwqå•—ðÁ3±Z­\{í„6ó\yåeÌž=Ÿž=ÓQ…ððP¾úêkzõêÑ8°2 ÓéZE,?t¨Dd¯]»ŽK/½˜o¾YÄ%—ŒB§Ód%&&š  «Ú6l憮fÔ¨a-Ê*((âË/çrË-ב›{€ÐÐ.¾xË—¯bРìÚµ‡qã.&""Œ¯¿þ–ôô4ôz6[@h-_¾ªUÀÇó‰Çã!::ªÕ*ÖºuO)UU5ÁÁv:uêHnî<‹¹Uº¦499²?ùä ¶oß…$I<úèètZ^}õmœN'11QÜ}÷D</3fÌdàÀ,’’:¶¨w̘‘ÄÆ‚p~ûí"æÏ_ÈÈ‘ÃÐé´Ô×;xûí”—W`·Û¸ï¾»Û· têÔ‘˜˜(µ¬¤¤Žj<¦û`ÆŒ™£ÓéxøáûXµj-n·›M›¶Ë]wÝJaa1|ð }ûöâÚk'´is¦ŠÎðð0²³³Ô­3g~ÁÍ7_Ûâý?®gîÜ@š‘#‡rñÅ£øþûeüðÃr&N¼ ½^Ç /üƒêêj–/_ÍÓO?NUU5/¿ü^¯®]S¹á†–×[dd4k×¶\au»=„…EgõzûÍ üü|ˆPpÞØ¶j.½†\!:â7†ÃáÀjµŠÎœ”æèšÞ"..–ÜÜ|zöìNrrññ-íwÞy 3g~ËåRÅG`°­§¾ÞÑn}¡¡!„††²|y`fô¡‡þ@QQ±:óƒÑh )©~ø)}úô¤C‡´Zm›©o¼šåËWsÍ5í6\µêG²²2ؾ}±±1Çýîñh4uð´dÉ .½ôØV¤ääÎ,Y²¼Ý²û÷ïǺuY¾|5¿ÿýèõ:233X¼x)X=j‹=º±pá,_¾šaÑ’Ò™ü=3fÌD–e’’:Í=÷Ü¡øú÷ï×fY6[`ëXS¿öêÕƒ¬¬€ëÒ¥KWò»ß]BLL4qq1¬]»žåËWsÿý“Ôß=dÈ $/D!ýí·‹p:°Ùl-"È7§¸øÚG÷Üs;—]6–1cFâóùù×¿Þ ::Š;ï¼…øøXJJʨ¨¨"11ž'Ÿ|”7ß|O-륗^aÙ²U¼ùæ{jÄïñãDZ~ýæÆ- þÀðáƒÉÌìKmm%%¥¬\¹–U«Öªå<üð¸ûî‰|óÍ"JJÊÈÎÎj³í›6m%!!Ž{ï½ ‡ÃÁË/¿‰Éd¤GnL›6…Å‹—²víz¾ûî{{ìÿ0}úkŒ?®qe¡%û÷ç±|ùjz÷î¡ ãÙ±cW«÷sç~«NZ¬_¿¹Q¸ô§wï€àþûß_套¦òÀ“ÈËËW…û¿ÿý.?þAAÖ6m@*$11¡ÉŽà³~½üæHff&™™™<ÿüóâŸOpN)Ú·‰ÄÔ Ñ¿1š‚œN›6Mt†à¤4 R›¿ïÕ«;½zu?iÞ¦™Ñæøý2ƒŸx›ÖàÁZ¤INîtœ@ ˆ‘&¯\MÄÇǶY^{Æ›s¼hþ»›{½êÔ©c«zkkk¹øâQ',¿ÿ~-ÄA‡ ­Ê9ž„„¸6Óä0""ü¤e………¶™¦­ðÙÙY­¹ÍûãBäo{™§Ÿ~½^ÏgŸÍbÇŽÝôéÓ³ Ñ—Þ¢ŸŠ‹óᇟ`6›Ûܙٮ=Çã?HUUµ*>N†Í¤Æ¾øÝïZF±ÿæ›Ej»&O~¶Õ ׉èÛ·÷q×kü¿ÆöGµk5xðÀ“^WÇîk›ý‘Ñ ŸÏÇôé¯b³Ùe™ššÚ6Ÿ ¿$„ @ 8fΜIŸ>}èÞ½;Š¢°téRFÅ+¯¼‚Ñhdÿþý”••QZZJÏž=E‡ ÎV«…É“ùUý¦ßýîqbáLúgž}öoH’D·n]Ûm¡ÑhðùüÔ×;T[ƒ¬¬ŒFû EQ¸é¦kˆŠŠä¥—^aݺdee0zôð6Ëûî»X±b Ï??Çnݺòå—sùöÛÅ€Âe—%#£w«|GŽ”0uêK@`›D|ûíbrsðøã‘˜ÏâÅËØ¼y;ÇfýúMüã¯dEQn½õzFŽª•>è´<޽õÖû¬^ý#o½õ>¿ÿý 2©S_BQdÕ¸?)©ƒÚV‹ÅÌCÝ @}½E9f“ͼyß1uêß=z8C‡fóϾ@JJ W^9á×%@JJÊ(/?f°£(+ߨ؇ IDAT‚_ß}÷UUU$''óöÛoóÕW_±aÃJKKéÖ­?üð¯¾ú*², "h—ºº:@Äcü:øóŸÅëõžÐÁÔ©O¶øÃäÉã÷ûÑëõ(Š‚^¯§wï(J …ÑhDQžzêÁk³ýñå=ŒáÃ`2™HOOã‰':!Ë2’$µÛ¶;ï¼·;àíªÉÞiÀ€L>ÿ|F£Fßþô0²ì$Ìfë×oâÑGïÃn·¡Ñh1 têÔQÝæ¯ÓéÛ¬/)©wÞyK«ã·ß~3'Þˆ$¶æ…„óØcðÿÙ;󸨪ög†aß÷EvAEpWDQÔÒÔ2wMS«×Ê·Þê÷¢Yi&íYöº”iÙfY©-Š»¸aî"" "ȾoÃ2Ãï‘ÑP4wÎ÷óáÃ̽çžå¹çÞ9Ï9ÏyÞxcÓ§O¡¶¶±®ºèèȘ3çêëëÉth´’tph”­JcÚõ&ó{»qÛKÏÍÍF*•6¸x2ÁCANN!!!èêêòùçŸãììÌ_ýEyy9¶¶¶$$$°yóf-÷šm‰E‹1gÎÑQZÚ¢¢ABpÏÑ××çäÉSšÙó+}´õýSGG熳ý×:3´¼£]]Ÿ«‘H$Ü0?¹\ÞäXk\:K¥Ò&ù7×==íºúûûbdd¨umKu½¶=ÍÉJ__»®>>í5«ÿþ÷¿ÉšÖU.×iÖÔëZÙ6*"-Åy`¥R…ŽŽŽfSÕ•+O·@ x(˜9s&³fÍ"22’üü|llÔ,ÆÆêlAAAx{{·9¹QPP@^^ß}÷'N$55—fàþÁÔÔ„ÎB7I£7¹;…µµ•fÃùĈ"7All,'N¤{÷îåCóæÍã믿ÆÕÕ•œœÒÒÒøè£îX$]@ <˜ˆMè@pÄÅÅñÜsÏaff&„q‡fÀ€œ={–1cÆPXXÈäÉ“ñññ!&&†üü|úöí‹···&î@m†!‘ •ªþ²µ„ØÓР¼éHÞP@îcŠŠŠ4ïDdGàZŒL,¨*/BWO8bxP)..ÆÜÜœØØX:uê$”«øá‡?~<{÷îeÒ¤IŒ5 [[[V¬XÁæÍ›ÉÌÌÄÈȈ·ß~›¡C‡D·nÝ„ð©TŽT*»¼©µírþ|:..Èå†Ô××´iYTWWSTTˆ½½í,CT*½¶ŒD¢ƒD" ÈÝ{Éçĉš‡\ ¸Ó„=þWDñØ3"&ăʒ%KxõÕW9þ<}úôiÕ5ºººTTT<ô{N:EMM eeeZæh:::øùù±yóf† ‚³³3üñû÷ïçܹsŒ?^t.@©¬C¥jÛbùù¹¸¸8 R)Q*kÛ¸RIYYÙU@”J%J¥xöÚ22™{¨´é@„‹-=PÐ*6mÚÄСC… Ú õõõlÛ¶ÿüç?¤¤¤0mÚ´V]7pà@fÍšõP÷›;w¢¯¯ÏW_}ÅÈ‘#o˜~Ĉ>|˜ââb233Ù³g}ûöì¢R©X¼x¸¸8_vïÙ6f¾·mÛÅÀáM>_Ë7ßüHyy9Ï??SsìàÁÃäå0|øÊ÷Z§;ÆÆF7›Bð0¾î­,± ] h{÷îBh£lÛ¶þýû3|øpºvízS×¾óÎ;µl:„žž©©©ØÙÙµZ&K—.å©§žâÈ‘#¢ƒÝaV®\ÃøñOðÆÿGûöžìØÛfÚw¨ÙÏ×2eÊ8ŠŠŠµŽuïzCå`áÂD'n¡þ ­ä7Þ`Á‚BmŒØØXÞ~ûmúöíË€„@šÁÃÃ{{ûfϽøâ‹¸ººòÄOAÝ'Ì™³KK ªªª022â…fòÝw?“™™uù~ºѹsâêÚ€¾}{ѯ_ïºÝååÌšõ ^^î%cРþ-(ÊR]­`áÂ×ظñ/NžLÀÌ̌ٳŸ%:úcöï?È‚ï1mÚDÚµ{°÷ùUUUSQQÑä¸T*ÅÚÚªUy¼ûî'”––Ñ»w÷£×¿ÿþ§—йs íÛ{’žžÁȑޑv¥¦žgÍšµÔÕÕ¡£#cܸ'X»ö·& V¯þžàà ‚‚üo[ùÑÑóÒKÿj×$==ƒ;÷h‚¾ñÆ¢fëÔüx¤õi›SÌ/^Ìâ‰'F D ¸ßIKKÃÜÜ\¢ "‘HËålÙ²SSÓ›¾ÞÇLJääd|||JùLž<ùº«r¹œÑ£Gãææ&:Ó}‚\®Ã¿þ5CC/^ŠBQÃþý5&J»víeÀ€0:vìÀË/Ï`Á‚÷xÀË˃7ÞxMÓ¦–¹s_aÁ‚÷4ß‹ŠŠñööÒäõ2uuu¼ñÆÿ=ý¢¢¢ã&¦Y'Nœj•²eËNºu !<¼K–¬àÒ¥›NL—hâZ¬[·•JEqq kÖüˆD"eÒ¤1üòËFªªª°³³%2rÇŽ$ Àü?‚ƒƒ8vì$YYÙÞgç¦JàÉ“ >„Îäææ‘œœB]]ññ§9q"OOwzõêNnn2™3³+^úŽ;Irr*uuµ 6„úúzrsó8vì$:::Œ?€Ÿ~úššì80œ²²r6lø©TF]]Í94khhÐr†TWWÀï¿o¦¤¤sss†±c'  %åvš´ul<-Û·ïæÒ¥lôôô3fÔåñL..÷^Y&XA+8xð Bm˜[Q>"""ؾ}ûC+CCCd2Ù Ó{óû‡ÚÚ: µŽYXXDppQQ/`bbüеýVÛÜI#Ÿ-[v49ŸœœòPÈGGG®‰$Þø×ZwÀ‘‘ýÙ»÷QQói×ΩYå 44˜¨¨ùüôÓoDDô`÷î}„†Ó¹s Ÿ}¶€  BCƒ©¨¨dÏžÈdRž~úyBCƒ‰‰ÙNYY9¯¿¾++ BCƒY½ú;Š6nܤù;q"žAƒÂÙ½{ ~È©S‰ôíÛ ¥RÉéÓg &>þ4çÎ¥abbŒ‰‰ Ñ(Ï?ÿ ~~>„†³|ù*RRαxñrBCƒñõõaùòU¬^ý=î†SXXÄÁƒGXºt%¡¡ÁtêÀ¶m»[”Ùúõ5Ÿ¨¨ùÔÔ¨½¿ùûûŒžž.üúuHLLf÷î}äå°ÿß|ðÁgäææ·˜¿··¡¡Á¸»»²jÕwtéĆ Ýû¾&^Å@Ð<ÅÅÅXXXA´€zÆTÄô¸Ÿyì±Gøúëï©©©ÁÒÒ‚I“Ʋk×^vîŒ%##OOwŒŒ ‰ˆcíÚ_;öqLLŒqp¸2€tuuyàÚÞ»wÍ*F×®]Éd´kçØ¤Mß|ó#™™—øøãÿiV|ÞyçC23/±nÝFAmm-7ªm¾¾WV3CB:_w%¥-±|ù*¦L‡«« «WÇÙ³©šU£«éÔ)€Q£†qâÄ)V®\Cÿþ}6l0¾¾>Ô××óÓO¿’••Í÷߯£¦¦†‹³?~4nnÎôèÑ__ÌÌL144$(ÈŸž=Õ.½Õ®…¥ØÙÙhM)5<óÌT¤R ;wîå?bÉÔ¦X‡§¶¶CCC<<\9sæ¬æú°°Þs¬5kÖ^~¦†àëëCee%ýµ}}=~øa”––áííEii™¦Ÿ دE™ù(3g>@TÔ|rsóùñÇ_©¨¨ ?¿€ðð+^¿ýv-nœ={Ž]»öòä“#š•1@II)?ÿ¼žÂÂ"ª««5&‚>>í‘Ëå÷¼¿DÐ*øæ›oxê©§Údû-,,000¡QWWw_¼¨ïW”Jå W?÷;;þïÿþ­uLOO—§žš ulðàŽÐ:öè£Wlø§L÷Àµ½ÿ¾ôï¯íemôèMÚ4eʸ&í›;÷­ï¡¡Á„†7)cèÐA :Ht4`À€0vïÞO`` uuõØÛ7oš¹zõ÷Œ5Lói޽{ã ë…¹¹ß|óC“óŽŽ€Ú¼j×®½˜››addˆ®®œîÝCµÒîØKYY9nn.èêÊ©®V´0¡RIRR éébeeÙªvÛÚÚЭ[ÆÆF˜ššàééÎŽ±?J¥b۶ݼúêìVåuìØ ‚‚:âääÈúõ^~†mY³F­|— §§‹··'‘‘ýùã¼½½6l0 ^QIK»ÀË/Ï"%åööv ÆÞ½qÔÖªÝ[ÇÇ'››Çùóé899 änQ\\LI‰zóÓƒˆðÈ‘#˜ššâíí}WËU©T”––’’’B[eðàÁ7}¢² }CÓTnQQ‡&22ò–¯·´´D ¸ßÉd¨T*!ˆ{Àã?&„ ¸í´oï‰R©$>þ4&ŒÆÈȨÙt“&áĉSÌœù‰[[Í{áÉ'GàÇl&?¿€gž™†¹¹)ff¦ ¨½ÒäO]]))ç˜:ub‹ŠÑ¶m»HI9‡±±#F<¢YIèÛ·'––TWW#‘Hððp£´´ kk+Í* À¸qOàèh¯Èëéé1jÔ£øùu`Æ¿ÈÎÎÁÎÎOOwž}v›7oC*•²|ù'èêÊ›Q\¬0 L+ÿÀÀŽlÙ²ƒ””sŒ÷††899pöì9üü|ˆ?““£&m£ Y#;vÀÉÉA£4WUU“’rŽÃ5'SSÏ3xpYYÙB¹›¤¦¦rüøqàÁ DøùçŸóÌ3ÏÜõrKJJøâ‹/ÚìKµ¦¦===”J%õõõ­¶e¯«U ×ÕûGe’’’‚B¡`ذašùæüÎWWWS]]žž[·n%22’>ø€yóæj;üFªªª´¾ ZP"Š&žKZ‹\.hƒ644°qãÆV¯ 6#ÄÊÊŠÂÂBÑÉhàÌ™³”••ÜÕR>v_I!?¿ðòÿRR’Út¨­­Ó2#º[H$Nœˆo²çãZÅ×£Co:t¸þ$©··W³! sMü6¬©äFf´ÊüíÚ05ŸÝÜÍ MxòÉ‘-¦»ú34[íÀˆh311n’×µáééÞ$ÿÈȦÞýü|´Ò´T¯kåÖ«I^£F î}6§€„††ª^ž{÷Ýw˜z=z´Å¥Ê»ÁæÍ›éÝûþö€r§B­^½š©S§’˜˜ÈîZà´††Þ~ûm:uêÄ»ï¾ËСCY³f áááxyyif¥R)*•Š÷ß]]]²³³122â‡~ ¡¡  ‘HxçwJ¥lÞ¼™={öh¾ ZfÙ²eDGßZûnÝÔvÉ™™™\JKKIJJâ7ÞhUú›ŸÒ–P*ëðññ‚¸Œ¹¹a³¦N‚;566ÖT=š <ÄèãáôéÓtìØñž•¿gÏžû^FsçÎ}¨îybb"~~~ÔÖÖ¢¯¯ÏðáÃ9wî|ð¦½sçÎe×®]š¶¿ôÒKcffFaa!!!!¬[·€¨¨(vïÞÍž={HHH`æÌ™ìÚµ‹Ÿ~ú‰pôèQñ  @  ˆà îî¥Ý›Ž"•bddDyyù}+Ÿââb’’®¥{'''.]ºDDD………áââBdd$ºººèêê­Qd2&LÀÛÛ›… 2`À:vìˆR©äÓO?åÍ7ßÄÌÌŒ®]»’››ËÖ­[9vìß}÷6làÃ?$..N}šáÇӽ{w͹Áƒ£P((((àÂ… h9 hÜìêêŠR©äÒ¥Køøø`bbÂÀõ¸FEÄÔÔ”)S¦0wî\LLL¨­­e„ |öÙgdddPQQÁÉ“'éׯÓ§OoœÄoT3üù矷¼7F MvvuuõB-¤R©VÌ’ÛB¡Bnëê‡L¹\ÿž•ßæ¬¬,þõ¯±iÓ&¢¢¢ðõõ%55•Ï>ûŒï¿ÿžñãÇ“˜˜H@@À= H–™™‰³³³xbZ   €.]ºGZZîîîw¤œ²²2Ž9¢Yu¸“ìÞ½›èèhΞUE²µµÕœ366ÆØØkkk:tè€J¥âé§Ÿn6GGG&L˜€¶Oö^½zaaa¡µÝÍÍ ###† †‰‰ .äÂ… lذ?þ˜ß~û7Þxƒ‰'ÞuwÐ*¶¶¶äåå Aš%.î0™œ[xÁÃÚÚ¹\‡ Fß±2 D Ÿ6NCƒ”{ùÚió ÈñãÇ‰ŽŽ¦sçΜ9szõêŦM›X¹r%ÆÆÆ’——G÷îÝqttÄÆÆFôÞÛL}}=EEEZíkÉÎÎÆÁÁ¼¼<öîÝ‹ƒƒ*•Š 6°råJ:ĶmÛ022Âßߟõë×cccCïÞ½Ùµk•••<÷ÜsšØ˜™™µ:ØÜ¦M›èÕ«¥¥¥ 0 Åt…9é^º²_§àÒyÒNÄÚÑ=ctõ[ïwæÌ™7L#•J[TPõõõ›u%kaaA¯^Ú.úf̘Ñ$««+³g«ƒ(M:•¹sç2g΢££iß¾ýïEEE”••áææFUUuuu˜™™µêÚììlòòòppp ;;oooT*©©©888 •J±¶¶nÒ¿n'ºººŒ9’Å‹3{ölÍÊÊÙ³g‘H$ÈårLMM›ÄkIJJÂÅʼnDBzz:íÛ·oò|$''Ó®]»ýí_øøx,,,¨¬¬D.—ãàà@JJ :::ÅÔÞÞ^£xËd²[*çzLœ8‘ï¾ûNcâÙV)**¡GâG@@AAr¹.JeÍ-G&“µÚ¥¼àáD¥’P_/ÜðÞqòó󩬬l2àm´©oÄ××___ðññ!22’Ù³gãççÇ™3gصk#FŒ¸ëƒsP»ö|öÙg©¯¯gàÀWŸ‰‰‰¸¸¸••…®®.æææäçç7™¥Ž‰‰iTO©T²råJž~úitttHOOgË–-šóGŒÁ{ï½wSv£555(•JM̉’’JJJ˜;w.ÆÆÆÄÄÄÂÊ•+ gùòåLž<‰DB^^®®®“““ùsç %11[[[†Nvv6©©©ó°FoP $$$E~~>ûöícìØ±ÔÔÔ0sæLär9nnnX[[“••…T*ÅÅÅ…ÐÐP~üñGŒŒŒ(.Vû>/,,dذatêÔ‰ôôôX¾|9Û·oÔ{svìØ¹¹9fffH#s[¤2ôÔå§çÿÄÚžÃÖÙ›üÌ<ûaªC½R¥¹‡¬Y³FÓÞû ===>üðCV­ZŪU«prr¢sçÎüðÃÌš5‹wÞy‡wÞyG뺿ÿþ[ÓN…BÁÁƒQ($&&ÞpPkii‰©©)ééé"—Ë)--mU}°µµeçÎ888°aÃd2^^^ìܹ•JEAAVúììlM['Ož|[äæïïORRsæÌÑR†¨««£¬¬Œ¢¢"­k:tèÀºuëhhhÀÍÍï¿ÿKKKòóó5i|||ÈÌÌlònk cddD]]—.]ÂÛÛ›úúzŠ‹‹Q©Täää`jjŠR©Ô”s»V}}}Ù¾};QQQ€zîVƒn¶„µµõ=3_m-øøx"—KÚ¬kìššZ$uûutÚæÌ|}½’ôt9ÙÙ÷&>ŽR©lÑÝkMœ7nü‹ƒ0}úd<=Ý©©©áë¯ //ŸÙ³ŸÃԴ龺´´ |òÉRŒŒ éÑ#”áÇÞñ¶þøã¯Œ§6»ß³çžžîš~­E¡¨aóæmŒùè-Õ!/¯€S§Nk#¼ÝdeeóÃëxõÕ5ÇÊÊÊùì³å8993vì“B¹Óœ:uªI$ïêêêëÎàâääÀ /¼@QQ]»vå·ß~Ó ß—³z6äüùóxxx ££CII‰¦åå夥¥if4êêꨩ©iâ5K"‘4©{ãÆòíÛ·#‘H¨ªªÒ:ß(£ . T*‘HZ¿iÉÔÔ™L¦ÉÓÍÍ sssæÍ›ÇàÁƒ‘H$ÄÅÅáááÁ… 2dˆ&ʨ™™iii”––RSSC÷îÝñôôD¡P P(pww§}ûö(•Ê&³Çžžž899¡««‹‘‘‘SRR‚»»;žžž\¸pÍŒoRRÓ§OgܸqTVVâáá¡éúúú˜šš"‘H4Êlpp0ÇŽ#==ÐÐP233177°oß [gotõÔ{1êjªi߹ʱsé@EiŠÒ: šÜ]]]\\\())¹¯Ÿ©öíÛ“’’Baa! ²wï^úöíÛ¤MÅÅÅMÚ#‘Hpqq¹a0ºvíÚáááAzzz“¾y#¼½½éÖ­±±±„……¡¯¯OX˜úe«iG\\¸»»³qãF@¬1''GÓþélcdd$‘‘‘œ¡®®ŽÑ£G£Q@Ο?[úT*ÅËËK£èäååÝöwk¿~ýðññy ~§ÚµsÂÒÒ‚¶ÈáÃÇJ¥XX˜ãêÚ6ͳ².‘pæž•_XXDCCR©¶˜‘q‘.]:Ýðú-[vbjjJtô›,Y²‚ÇŒ?þØLdälmmøè£%Ì›×4nGQQ1}úô`ôèÄÅâ÷ß71|øPJKËP©Tèèè`bbLuµ}Íà_OO…¢†ºº:”J%ÆÆFÈd2êêêÐÓÓÓ¤inÌŸ Q@ÒÓ3°±±ÂÎΆòò Íï¾:ÕÕŠËãd2•ÔÕÕ¡R©8}:‰!CjÆ”r¹ÆÆÆ(•*ÊÊʵ‚>µµµTVªÃŒ©¬¬äܹ4ÒØ¾²²r”J%2™ SSÍñââôôt[ "¬]WSd2)ff&ÌœùÔ5“œkyê© 8::‰@„wƒþýûÓ¿¿v´Ì÷Þ{ Ód@.‘H8wî©©©¼ûî»|õÕW„††RYYIbb"¯¿þú]­ã a~~þ]ßüÙXöñãÇ™3g¦¦¦ÿ8Ï[èËk¯½ÆßÿÍÒ¥K‘Ëå8991oÞ<-Zĺuë°µµeÏž=èëëSRR‚ŽŽú…P^^ŽJ¥bÒ¤IjïYC† !''‡4»Ñ~ùòåTTTpèÐ! ¹xñ"C‡E.—3ztSÝÊZøqÝâþÂÐØœþc^æóÿDÒ±ûPz Ÿ‘©Ú±§5XÞXî÷uuuìÞ½›ØØXzöìyWúb||<çÏŸ¿¥²bccùòË/ Óúß8ÐuËèèhâããIKKÓ”söìYöïßOÏž=ÿqÊËË?~<áááÍ7ß|£Yy»ºm±±±ššJtt4¹¹¹lܸ‘W_}•%K–ꕾFÓ®‘#GMllìMÉè£>ÂÏÏ;v`jjʘ1c4²idÞ¼yÈår¾úê+FŽ©™¹]}³¦¦†Ã‡‹ íw‘Æß·k?«T H¥’‡ª“k‰‰DÜûÖ`ii‰\®=4LKKoÕµ‘‘ýY°à=¶nÝI×®]pt´'==Ci¼ªªú†y„†3þ»X[[±gϤR)uuõ<þøp¾ù梣ߤ¡¡O?]Æ3ÏLeüøéôéÓ™L†>?þ¿ü²‘_|†¥K¿dÒ¤±× ®¸yóvÍçU«¾£¤D½º®TªˆŠz‰wß]Œ¡¡z"ÑÞÞŽ°°^|ûíZtuu)--ÃÀÀ€Ï?ÿ‚¼¼|¬­­¨««c̘Ç9tè™™—4ŠÉœ9¯ðé§Ë5}ÒÄÄ„Áƒ\.KÉë¯/$<¼66ÖÄÄlG&“¡T*<8‚üüBvîŒÅÒÒ…¢†çŸŸÑìDÅÑ£'Ø¿ÿïË“ŽŒ?šM›¶ñ㿲~ýwZÏECý÷€& ¯¡ººš>ø@á·¸¸˜Ã‡kfÒ–-[vוÁݺuÓ2]:xð ¿ÿþ;ǧ_¿PÉ IDAT~­ŽÐ¬Ž¸ëååÕªô“'OæÕW_mb6u-A}Fàáß“Ã[Õ½G@/MüïMµÕßߟ„„òóó ¿e™•””žžN§NÚ3X©©©äççccc£iÿîÝ»ÑÓÓ£sçÎZûFvíÚEhh(Ÿ}ö•••ÌŸ?ÿ®ÙjÆ[é/W÷™«ÿßÎrnDtt4›7oÖ:6eÊ”ëöñ€€ììì4û€^{M{öpýúõM®k-ÿùÏš»6ÿFZrpðOyë­·„òq—™3gÑÑo6ùüÑGK˜4i öövE;OžL`Ñ¢00ÐgΜÿàãsû÷«íÚµ—ðð>¢S]f÷î}tíÂàÁX¼x¹¹·î|ãØ±“Lš4''öì9Àùój%¨´´Œe˾Ò(ÎAAþDE½|ybdþM—³gÏ~|}}.+Z4ÏCTÔ|¨©©á­·þ«9æååNP?Æ ¡²²’O>YvùÝùo¬­-Ù¶m‰Ý¯YÉÛ»7îò×bMþåmÚ´•ŒŒLÍñï¿_GNN.vv¶äææ“˜˜ÄðáC9r䯽6›Ã‡µØ•ªAc®¿{÷>ÆÍ“OŽäøñø«&¸öñçŸ1œ=›Êœ9¯ann){…““YYYš™½Ã‡³mÛ6þû_u‡{î¹çرcNNNXZZÞ³hÛ>>>$''ß“²;wîÌñãÇïû{™œœŒ··÷m·!¿š+VqWÚÓ©S'Ž?ÎéÓ§ '..Nk£jnn.'OžäÂ… ±cÇŽ&3Óùùù?~œääd4Î@½É9!!ŠŠ M¬mÛ¶¡««KUU«W¯¦GÔÖÖâççǧŸ~Ê‹/¾(bcÜ$W¿_‚{Mvv+V¬ÆÛÛ‹ØØ}$$œÑ쯵IL~~!>>ꉉ¸¸Ãôèú@µ³S§&O‹……>>í©¨¨àìÙsÄÅ©'§OŸ„žž?ÿ¼žüüB,,Ì?þ êëëY±âk|}½éß¿/qq‡ñòrççŸ7Þ‡Ú³lÙ*~ÿ}‰‰ÉŒ÷––æm¾o•••cm­^á—Ëu¨««ÃÝÝ•´´ ØÙÙhV®Çߥ[·ÒÓ3ZTLjkkÑÓÓ»a^qq‡™4il‹ç9Ž®®î-í¡kÌ¿‘ƒñè£Wöך››ñ ꉣ^˜©1»úZ{{[zôèJII)ÿûßJfÌPOJ7šŽÕJ‘¾¾> Ň¡¡ÁWòر#–ñãG£PÔ°sg,/¿<‹3gÎòÕWß6[ç~ýúĈ`gg#L°î%vì&&&üñǤ¦¦Ò¿¾üòK¦OŸŽ§§'3gÎl²©ön#•JïYРˆˆV®\y_ßÇàà`>þøã;4ÏÐÐð®{©¬¬dÉ’%\ºtI£€¬[·Ž´´4jjjˆ‰‰ÑÄöµ}þ‘#G4‡×¯_½½=~ø!QQQ𙣔”N:…\.gíÚµœ8q‚AƒáååŦM›xôÑGñððÀÍÍ [[Û;ªØ=Ì\mæ"Ükì‘Ëåìß°°Þ¸¹¹°{÷>²²²±²²ÄÄÄ„M›¶Q__Ï–-;˜:uÂßÞ|3š¥K?à£>' Àkk«ËƒÀŽ;É–-;˜8q þƒ»»+EEÅ|ðÁ¼ðÂ3|ñÅj,xáÇ\ž‚‰‰±èXÀðáCøãÍDEÍgæÌ§h×Ή§žÏ×_ÿ@nn/½ô¯f¯³´´`Íšµ;v’^½ºñ裃©¨¨dñâeTVVâèhÏŒSèØ±IIg™=û9¶n݉©© :h)vv6ØØX5_£@7Ç«¯¾È®]{yå•牉ٗ—'cƌԬ¢„‡÷A"‘н{¨æØ”)ãqwwå믿'*j>ݺ…àKJÊy***‰Šš³³O?= WWg-ú€ˆˆèÇÀáš¼F†±±¡¡Áôïß—‹³Ø±c7#G>ÂÒ¥+Ù¸ñ/ììlù÷¿ŸC©TÒ±£o“6TTTrâÄ)Æžž.Y´èc:tð¦o_µéðªUßQZZÆÛo¿¯ÙãããÕ*eP( w‰C‡¡T*yþùçQ*•„„„hìû.\x_¸Ýݵk×?2Åù§ƒ¨êêêûÖ›Œ®®.íÚµã±Ç{(°eeeœ;wŽøøx ÈÎÎÖÄõ˜9s& \¸pššöìÙCNNIII˜™™‘œœŒ¥¥%;wæäÉ“¬ZµŠððp‰ŒŒ¤_¿~Z›Úlll3fL›'4zž4å駟櫯¾ºc¦Y‚;Ë£FrôèIöìÙ€±±VVWlÊår{l(}ô9ƒ…cañpÌî2ggõjdyy}ûöbÅŠÕlÛ¶ ¦M›@aaK—ª'ÜŠ‹Kx챡èëë1hPœxþù™H$àìì„©©‰&¿‡…¬¬KMöUT´~…`ذ! 6Dë·ùÚMÐ×âîîʧŸ¾«uÌØØˆ×_E똫«³Æ¬iôhµ'Ò1cFiÎ3в²rÊË+èÕ«ññ§[ôÞeiiÁã×Ê«S§@:uÒ6Ã}챡<ö˜¶W®gž™ªõýÃ—ÎØ±W‚Y{zºk™[ôïß—þýû69êþÔØ—^yåE­4úúúMêÐXÆûï/ÔN]FƨQôÒL›6‘iÓ´Ýœ¨Gªîñ6¡€\fÇŽZ¶È?ýô“&ðà Aƒî‹:–••Ý3ó—eË–1a„ûÚEäìÙ³/{¡º½Œ1‚Ÿ~ú‰ªª*fÍšu×ÚãîîÎòå˱··'&&†€€>ÿüsâããY³fMËóçÏ×ìOÒÓÓC©TRSS£‰±Ð¸ñ¿wïÞÄÄÄ«««xø¯£Ô6zdhcmm­åXð`akkÃ!$;;‡¤¤jjjquuF.×á§Ÿ~cúôÉlݺ;;[<=ݨ6æååsút&&Æøú64õÂ… :v쀩©)ùù$$œÁÓÓ?ììlqttàÌ™³škììlµÞ{÷Æ‘Ÿ_Ðdà÷ Ò¨hªT ZÇýý}˜6˜ššÑìì\Æ33Ó;^æ¸qw§œ‡6¯€˜˜˜P^^ÞäøýjÀ€L:õ¦7šÞ. vÿ¿\ïÔ`ÚÞÞ^+ÂÝÂÐÐ’’||| ÃÝݬ¬,ÆßlòñãÇãééIJJ 111Lš4‰˜˜˜&Ç\]]oÙ ™@ x°yê©ñM>×ÕÕÑ­[€Ëî?¥ 2''¦M›HrrÊ×κºzÔŠD}½kydVÛ}|ÚSVV~yï‚%}ûöB©T²eËÍ ²S§÷¢«™:u‰‰I Ôÿ¡èr¹[Û?Ȳ‡‡nw­¼›"h£ HII‰&ˆY}}=={ödÑ¢EM‚óÝo899ÝòF©ÛñRúôÓO™7o^›}P8pÓ‰¥RÙ?Þ·3vìXÒÒÒxòÉ' `íÚµ-Æ¥hŒ×âã㣉{ð Ä?w‡«½A5~vqqÆÅE;öÆÕæ¶wƒÔÝ^;0¼:¾Hc›z÷Öžl”Éd ªmõ`eÕ¼§ 77‹Y@ ë’œœ¬ñèT]­öI]YY‰••Õ}_÷ï¿ÿƒ{³qH"‘0|øð6û \¸pᆻ¯ÅÈ̊ʲѶsçÎ\ºtIãvܸqâ­%<¤Ô××·Y³?¥R©q¶ÒVePWW×ʺ:NŠ mr¯o›S@®Žñþûï°råÊ{¶ºp3¸¹¹Ý³²%É c_<Ìamm}×ËuttdÆŒâMù’žžŽB¡¸o7ÜMbbbîûUæû„„3(Š6Û~{{;²²²9s&¹ÍÊ@OO—òò;ßnfc¹àáD&ÓE.× ȽÄÑÑQAp]üüüèׯŸD㥗^â“O>ᥗ^ºék333)))iòaÀÜÜ\cÊÚbcc…r£Á€Žw/ÿ6/  -GÍ9súew¼œsçÒ„ÒÖŸ5 +¼½ï™¶P@‚Vн{wC ¸æ™˜?>o¾ùæM_{ðàAºwï.„xõ±Ž.–vîBmyÊÝYý)--k²ÿåVÙºuç騠­ãîîqO©¸Áyã‹ÿô™¸Us¡7RXXø@ì½»W””sþ\*çÏ¥R[[#"¸­H$ôôtoËßÕîùssó9~<^kBQCQQq‹u©ªª¦¤D½¢ÚÐÐ@vvN‹i/^Ì"77ï·ÿÒ¥lÍ碢b­hã­E¥R‘“sëu©­­¥  ðŽÞ窪j“šOH8ùsi÷´ D wÆMÇ‚¦ƒš¤3§),(ÀÂÒ KK’“’(qWw˜¢¢b23³ÈÊÊÖúkížœüü23³°··ãر“(5TW+عsçϧ_·ÜŒŒLròäéÓš™™Ü´C˜æ8q"Aó9-íee7oöV__ÏéÓ‰·\‡ŠŠJRSï¬ —ë`cc}MÛOahhpÏŒ ,@ h Š‹‹… ZÀØØ˜ŠŠ ±Ñþ6r6ù Î.nX~¾­18¶÷!oîTVT`tY¯þrSgˆ8?‚›§¾¾;;;ärí¡aVÖ¥Ö (utP*•( ¤R)R©„¤¤üü|n8ÓŸ——OZÚ-Ï\;wîA¡¨ÁÐÐàrœ {öÄáèhOppÇŽDWWNFF®8;·ãܹ4;râÄ)||Úc`ÐòFëââÍçsçÒHNNÔnœƒ‚ü9rä8yytìØ{{[:Jyy%VVš½z5£##CºuëBAA!ññjåÄÆÆŠÎ$$œáâÅ,¼¼Ü±¶¶ÒR‚Šœ8tè E-zzºtëÂÅ‹Yèëë‘”tss3BCƒÑÑi:|OI9GJÊyýh×ΉãÇO‘•u‰‘#Õ¤«¬¬ÂÝÝKK ¡€Áýˆ\.§®®@ŒÒÞÞ^æ22™Œ¼¼<ª««111A___å PT£T*±Xÿ úo¾~åÄþ}XÕÕ’¹è}-dᛯ£T)i×Ιñ“§òËÚøá»¯ÉÈHgÐà¡ôèÕ§™2üðí×\̸ÀsÏÏæÄñcw ÅÚÆ†¾ý†ñ“¦³éOœXÿËÏøtðeôØ ìݽ‹ØÝê }ýúGЫOëÖ~ÏÙdµ‰Ç¤)Ó¨­«£ /Ó ñ”——óô3Ïaaa)nn@GG‡úúz ‰‰DJ` ?yy7^½«­­C¡PhEa÷÷÷C¥R’™y‰ .Ò¡ƒ7a8pH“F*•R_¯dèÐì݇££eeêàÒeee¨TÊë–w;;uðÅääT†À¦MÛ ò'?¿@ëXCCVV–ôéÓ“ÌÌK$'Ÿ¥´´ W×vtíÚ…³gÏ‘™y‰3g’ ¾\Æ!:u àâÅ,M^2)**fóæm¸¹¹àãÓž“'Oakkƒµµ…œ=›JÇŽX¿þOÆŽ}œøøÓTVV5yÝÁÁõûáðác´kçD×®ÁlÚtEùKM=Obbyyùxzz änRZZªYj«¯¯o Áçäžõõ)ñ€³páB 5î»j~þùg† BPPÈ?@Y¯DG¦ƒ4¹©Í¶nj*J¥ö`jêŒghh€m[6‘”xšISŸæü¹TÞ|;ºÅ2RÎ&cffδ·ŸàTü .f\À×Oí+årÙA:³hÁ›,Y¾’¯W~AyYöïåé™ÿàRV&ÅEEiÊ›ÿzo.ŒfÖ'2oþ;Ô×׳}K £ÇŽ7· pôèqºu ÁÀÀ€cÇNRTT„m«®m×Î__T*/fqöl*%%¥Èår²².]7fcôö>}zh”€êjÅ þ$n9`pã`_ýÙDë\}½’ìì\ÜÜ\‘Éd×\kBuu5åå嘚šàà`D" ?¿P¦1Ðe£U``Ç+ï ¥’ÊÊ*LMMP*•ÄÅÂÚÚŠÚÚZjjš¥ãååAnn>þþ¾Zõ È] ))‰£GPUU%Þ‚;NÖùSøv.HTd2ýõ«V­bܸq¨T*±wá6mÚDDDD‹ç÷ïßO~~>666üöÛoH$ÍÊ’à*$h>:X py€³éO23. ‘H8ü÷A:u¾¦FžÞW¤¼}:pè`\³ç‚Ô.¤Ÿš>€Q£Ÿd˦?.ç_ƒ»‡g B;ìÔQÈ…òÑvèׯ»ví¥ºZ‡‡+vv¶üý÷23/QQQAaa‘‘š\'•J´Þ©::2LMM8>ýòŠˆú|uµ‚íÛw‘““‡““>>í‘ÉÔ¦^èëëSSSæMÛ(((h±®~~>8ð7þ$'§`bbŒƒƒ›6mÀÔÔX“_ã1—vXYY’’rŽôô‹èêÊ5¦PGž ¾^‰\®C×®]èС=ii´oïT*ÅÜÜT“— nxx¸Ì‡077ÅÙ¹yy'ÈÎÎÅÄÄKK jjj›5¹ÊÎÎá×_göìçH$Èd2²³sÑÕ•£«+àСcdd\dûöÝDDôÓÈWrÕ»D( w‰«~øá‡â!®Ë¼y󈈈`Þ¼y˜ššröìY:tèÐêëãââj—³%%%øûûó믿Òlš3gÎPZZŠ K—.%""‚o¿ý]]]ÑÁ®ÂÈȈʊJêF¢÷Á»ZçÊzõÁÐÐPóÝÔÔ”K—² êê¯(s»„°`Þ y5êõ&eØÛ;ðdž_Y0oH Ä Bºvãë¯VРj@O_Ÿ³Ég01ijâ±g×Nr²ÕÞƒœœ026¢´´TЭGOqÛ8áá}®s…p£ÆŽŽ8::\VF¤šòàÁvMÒ6D[I設¨7¨ðòrÇÕÕ…={ö·X¦››‹fuÁÉI]vçÎtî|ýö ®õ=6v?½zuÇÈèÊóiffН¯¶‹Ûž=› ¢ÑL«gÏ®šc×*izzº„…õjrm»vNÌžýœFnýû÷m’¦k×`ºv nrOîÄ@ ¸zzzDDDðïÿ[cnt3;vŒÑ£G?”²ùïÿKTTK—.%**ªÙ4‡¢k×®¢#µ’Î]BÈÌËÅü·ß1? @å[ZQ;y*VfW¼ÖôìÝW³ÇãêÙÌá#g؈Q-ÎpÚØÚ5o¾æ{cºÀ ÎMòšùÜóZ×Îü× šMÂ颿½Õ䨛 £Å|144ääÉSML’š›}¿Ÿßו•UlÚ´ ww×Ûâ1ëF8;;!—ËE ˆ@ Ü^BBB¨áû‰½{÷Ò§O!ˆV"•J±µµ£²wiÔ3—–VVëê5IÛ’’q#óŠæÎ·Ö$ãŸ\+¸¿166"$¤óß?¿øùu¸kåyx¸‰Î#@ ¸ý<òÈ#7}Í¥K—ÚÄ>³×^{­Õisrr„±V*!&¦¦˜˜š a¡€A[ÆÉɉ¬¬¬Ví9~üx›‰……Ú—¼¥¥%EEEXZ¶ìr5!!µ·¥åË—óÉ'ŸˆNu•JIUE‘DG©¼;ÎjjjHK»p[òª¨¨7N ྜÙ:sñìq!ˆ‡„ˆˆ¢¢¢ðòòÂÕÕUä*üýýY»v-AAAôêÕë†é'MšÄÈ‘Â=µfàY_Kq~†D§¾VqWÊñööB¡¨¹-yvÔr+x004nx‚‡–žNgv=Fÿû3!Œ‡„²²2>þøc>ýôÓÓ>|˜ÄÄDüüüÚ”l¶oßNEEE³ HYYÕÕÕ´oßž   ôôôDgº ¹®Nî„ Ú8YY9@Î/ÇÚÚJìÝiãH¥÷vã|› DX^®T# ‚[ÁÓÓ“S§NÐìù¼¼<ŠŠÚ–9¾¾>ƒ âôéÓìÛ·ÐÐP6oÞ¬9¿uëV6nÜÈ|€———èD7@¥T¢¼ÅYGG.‹‚ÛŠ‘‘¡p¬ÑÖß1* 55Ê{§µ5Ÿ9s†7²qãFˆP Ü4ÿûßÿ äÒ¥KBWγÏ>ËsÏ=GZZõõõ=z”7Ò³gOª««‰ŠŠ¢wïÞBX7 ´´”ü‚|JKJ)-)%7'›êêê{VŸÚÚZ«]àF}¥¼¼BãÊW©TR^^AyyµµÍïoQ*UZÂ55µÔÕÕ5ÛçŠjkkÿq=¯Ž^WWKÑÐZU—–Ò¨T*­€¬-E/¿™¶\è†ÊG ::2ììì±¶±ÁÚÆ{G²2/RZRrÃëwnÛzÛë´bégŠ›óSQQIVVv“¿ììÜVçý K–¬à—_6°fÍZ–,YÁ’%+xÿýæÍVOœˆgýú?µeÊÂ…ï³bÅj.]jjж{÷^Ž9¡ulëÖ7ÝÖ·Þº«æÇ!99å¦ó¨ªªâý÷ol^ýP]ÝtoÏ… Y½úûfët«myëo@p“8;;³sçN!ˆf°¶¶¦  €wÞy‡¹sçj…‡‡ áÜ¥R‰B¡Àή©«b{G².f`f~%áç‹?B©RâÕÞ‡G†=Æú_~fÕ—Ë8uê} îÚl9›ÿúƒ³Ég áÅ—_%þä jkjØ¿/G'ž;ŠŠ ¾úb©¸)mˆªª*lm­›Õ;tè(v7¼~Ë–ôíÛ“ðð>,Y²‚K—r°··eêÔ TVVòÉ'7ןNŸ>Ã÷ßÿŒ³³ãÆ=AYY9ññ§éÛ÷ʳ+V³víoœ8qŠQ£†áååÁޱ=ªVRž~&††­*ïâÅ,~üñ êO§NKK ~þy=ééèó ϰxñ2jkkqw÷àÑG¹gýM( @p“xzz²råJ,XÀo¼ÁñãÇ©¬¬¤wïÞ"Þjó„¹sç²oß>ôõõE§i¥ÒÒ€ÅØØ˜ŠŠ ­c§L`ûÖâOgàà!:Ç”©300h~Еx:Ò’¦LA ¼¿èm¬¬­Q*•L™:ƒDz}k GäÙY³˜2a4“.—%xعõ½F‘‘ýY°à=¶nÝI×®]pt´ÇÑÑž’’R¾þú^yåÅë^¿`Á{Ì™óÍ÷sçÒ˜1c ‡cÛ¶] Ƙ1£øñÇ_èÞ=€±c')é,3fLÁØØˆœœ\NJdÆŒ)|ðÁ§Lž3fL¡¸¸„Ï?ÿ‚ššZÆŒ…‘‘!2™Ø„.ÅÅÅdddPZZÊ´iÓðòò"++‹Þ½{“ššÚ¦7Z?ûì³$$$```ÀÀEg¹$ž>Å/?ýHCC)g“ùÏks066A__ó˱YZRr~_ÿ+ÉI‰øQRRÌG†cna!EE…Ô(j4ùD ,.¸!~¸„Y³f`eeÉ·ßþDbbvv¶¬[·éÓ'£¯}Ïwך) > s ô©¨¨D*•bnn¦•ÆÌÌ}}},,Ô+ƒ*Uýµ…Üܼ˓EîØÚÚ0hPÍ5ÖÖVÈd2¢£ßÔfbÉÉ©3±Æº|ñÅ7dg«MÁ²³s©¯¯GOO sFŒÊ'Ÿ,C¡PðÙgË100 ºZÁôé“©­­ÕÔiàÀ~­nwMM-FFFXX˜cddDmm- …B“—ŽŽ*•zÏŒ……9æté¢öž†5 ÞwRWWÏ?¬#.î*•Š>}zpòdææfÝóMèB‚[`âĉ¬^½3336mÚ„»»;íÚµ#'çŠÝrjj*ÉÉÉDGG·)Ù¸ººŠ8)·€\.§¾®ùºÅEEX\ä1þÄ º÷è…TãJüÇvíØ¾5†Œ éL›ñl“|LLLèÞ¯öÞåâ«/–5IçìâÂö­1lßÄIO‰$¸.&<ÉÏ?¯ÇÝÝ•úú:ÜÝ]™?ÿ=:wdß¾8¤R©–"pµ‘–vÀÀެZõíÛ{RVVÞì@}ûöÝ$'§’œœªY™°´4'&f;yy<úh$„Ñ©“ÚCaÿþ}ÑÕÕÅÝýÆï£®]»Ð±£:ÈlãÿüüÂÂz‘——Ovv.æææœ8‘@LÌv“pwwÅÓÓ}¬¬,ñ÷’!ŠA IDAT÷ÅÉÉ‘˜˜í¨T*¶mÛÝì ˆ……EvdÙ²¯ððpÃÑÑž“'ÈʺDaaŽŽöTUU³€ÒÒ2 °´´ &f;UUÕs³íÛc F*•âä䀕•%ýû÷ÅÅ¥r¹œ¨¨¨d×®=Èår¬¬lð÷ ˆ@ð0"‘Hp÷ïT"ÂxÈèÝ»7¿ÿþ;¶¶¶Ì™3‡¤¤$ºté—_~©I#•J…«KÁM½/ÌÌÍ9—z{{GŒŒ/+…äççãêê¦I;vÂ$ìÛCCCo.ŒÖ¬VLš2£G9ôÑfËps÷ |À@ òó4Çö˜F¹ñëèO]}ÆÆÆþû ÿûb&¦fâ ®‹ƒƒ>:˜óçÓ7î ôõõ7î JJJ5ïÃæðòò`ô踻»’–vwwW²²²±¶¶Ôû”J%‰kk+žzj=qwwE¥RQXXÄO,-­pusCOO{/MÏÞ}›\¯o`@¯>a×-çƒ/>|¯ „5ŸM®òy£|Ùï•LƉñMÜß–—W´:gg'œ4߃‚ü[u]ã Eã''Í93³+}2,¬iSKK ­ã^^xyy´ª<;;[ ›æïâÒ—vZÇüý}›ä׳g·kžcƒfëÚR=®.#$¤s“ûrm^æZÇjjj±±±¦OŸZéš‹Pß»·ú7I˜`ÝeÊÊÊ4•J¥xã‚[ÆÐÐPcj4{¶z‰½}ûöüõ×_øúúâëë+„$¸iÌÍÍ1¿ÊÛ•@p7°²²ÄÊÊRâDOO—ýkúUç6§€œ>}š£GPYY)z­@ ¸­„„„0x°Ø´+¸9h@¥“bðQÐ6hs H=èÑC½DõñÇ‹ n+>>>B‚›¦VQEÚ™ýBmœêÊR!P@@ Üyôôpöì$ÑÆ),Þäßy…·¶–úz±âÖ¶‘÷ÎAŽP@@ ¸H„ w…ššZ!„¶®~Èt‘Ëï]X¡€@pQ]]Íÿ³wÞáQ_~·$»›Þ{! B„Þ¤ƒ(EiJ,  PŒ-¨*‚¢ˆ"*Š"Mz‡@ zBzïe“ìnv¿? K¤IȼÏÃCvvÚ=wîìœ;sÎ)**4ÆQ(•ØØØ —΂ÿ KK 1žê9z½­¶ælŽÄè )¥¥%ØÙÙcff@ii)ñqWðôòB©Tݲ|Ì¥‹\ 2X—/]$>î ½ûö¿«þ}µü3úöˆŸÀ•Û·g7…ù<úøq“kR©´Ú¸‚ú‚nx@ ¨× òórMâr(•JIINÆ? ¡1ýø±# ìíhÈ…óçXúÑû<ûÂT¼||qss¯RÁÉHO#âhE`³ö1¢NF¢Ñ”aeeM“¦ÍÐh4D<€§·ÎÎ.ЦmŽNÎhµZ²²2IN¬ˆÄÞ*¸-ÅEE””–œ˜€¹BIËVv-*•ßë±’())!?/_?\\]IKM!)1{G ^Þ>bP<@´Z-¶ò2URárüvX³fÑÑç=úIZµjΊ«‰ 55o¿]^©ÌÅ‹—Y¼øÓ«QÄ›2fÌÂÃ?¦¼¼œ… _½íkÈÎÎaÏž<ñÄã·Ì÷Å«ˆO`ìØ‘4kv{.ÓÏœ9GAA!;·¿í>­^ý#£G?Y)ð_jj:ÇGòØc^W¬XÍsÏM¸ãûv·åjš:£€ >ÿüsžþyÌÍ«ÞøóÏ?ɤI“hÔ¨‘˜Q@Pg€ò«»7coï@ìåËpÃÆCFz:zƒˆ£GH¥ä忢.."==GG§jÛÙºùollíëÖ~£“399ÙXZZ}ú4jµš¨S‘8»¸ó¿ºÒÒRvlߊZ­¦û#½ÈËÍeêä <7u:k¿ÿ''göìÚA^}(.*$+3ƒž½û’žžÎ¿ýÊÛïÀ¢óèÝ·?¶vöìØ¾y Þ`ÕŠ/hÜ–cGãÐP( ˜ÜÜ”––’’’fü|MQ»r%žÒÒ2 süý ×ë¹páòÕyÀ77WŠ‹‹IHHF¡0'66ƒÁ@vvÙÙ9èõ`nnNbbEEjd2“Ç… —ÑëõXXXáââ&[¡×ëùå—_رcÏ>ûì-•F1räH>ûì3T*^^^bVÁCEQa!ÇŽ ×ë¹tñ:u¡C§ÎlÙô'ƒþå˜ÓãC†1èñ! Þzc>^Þ>œ>ƒ Y™øø6 3#ƒV¼E>6sssÜ=;vŒ„„ž|òÉ;.»víZZ´hA‹-¨¬ùóÏ?yñÅëÌøÐjµèõú:7¦W¬XAïÞ½ñ÷÷ íž;wŽ£G2aÂ+nܸggg:uêtÇe—,Y„ þu>®ŠÜÜ\V¬XÁܹsï¸ìÑ£GINN®s‹8[;;  9y¸ÐhÊhÔ“¼sæÍ¯TÞÞÞWC«#.®®¸¸ºÒ¡“éœú´—*ýΩTW…Å0иIP¥ºCÚw0þÝý‘^•®¥Up£Ât#7æ½ö·Á`@¥²4.`u‹ž=»±k×>BCØ3g:NNŽ”––:=úhuJ± ?ÿ¼'NÑ¿oy¤â…Ã5#ô¯¾ú–矟È+¯Ì0ÖõÚk³P(Œ9̘6f̬¬,éС-]»vB«Õ²cÇž*w]:wno,7oÞËØÙÙ2yò8BCð³³åå—§"‘HèÛ·§1ßôéÏ£Õj±³³%(¨ jµš;÷2{ö4Þ}w1ju ú3yò8^~ùEBCÃÉd¼öÚ,ärY¥>4hàC£F Ї]»öñúësQ*,[ök×®ÇÅÅ™™3§PVVfìCHH0~~¾L˜ð¡¡a8992}úsÏQ÷.„…½NWÎË/OÅÅÅ™•+¿'44Ìx´-4t6aa Ñh lÌèÑ#…r+ŠŠŠx÷ÝwQ«Õ¼ù曄„„0|øpãÂÉ÷ªgAƒ±iÓ&BCC™1cnn÷çl›T*¥mÛ¶wUÖÎÎãÛµkW¯Êz{{ßÕ@‹-P©T¼Ï÷Âݾ¿×~[ZZÞÕn`MŽ{ykrL7nÜëŽÒ<(îeîñõõÅêê[í»y•Ê» v¥P(hÙ²å]•uvv6º±­kxy{ãæîŽN§3ÊAò€ƒyb8¹9ƶ*• ËûÞæÌ9sQ•Áƒçòå˜Jc-//ÿŽ”ž=»™,²¯íZT;Þ½<øàƒ°Jé¡¡³M>;::Tª+8¸%ÁÁ¦sD×®/JÌÌ̪=òõøãyüñ&i úWª¿W¯îôêÕ½šßM ãw7Û­¸º:ÿëuK$}´â¨YïÞ=Œé/¿lú"P¥RUª«I“@“´ÒÒRd2)‹™¾”xöÙñ•~7ÃÂBĬÛÁÊÊŠððð*¿{ùå—M>4ˆAƒÝ×þH¥R†zWeÝÝÝqww¿ë¶Ÿxâ‰zU¶U«Vw]önªÜkŸï…:ÜSù»í·ƒƒ={ö¬SãC&“1dÈ:7¦»wï^#cë^æž{yûõëw×e-,,0`À]•õóó«Ó A¹\^£â¤R)Žw±ku/¨Tª»~i$¸wP©”nŠMçéé!„SËQ(̘ñBÝšãêó nz÷[[Û»¶áÄœU?ÑjJHŠ9!QÏ)+)¬±¶e2YìÎ î‰D‚ƒƒ}ês½P@Ôj5gΜÁ×××da8iÒ$“|±±±dggרñÁÃA`` B‚;&99Ùh·Ð²eK”J%ÅÅÅDGGãççWiκ‘˜˜òòòîéXš æÉÍqtó¯×2H‰‹ÂͧR©¬ÞÊàÆÁÃLíT@æÎ…&Màé§!"4èÕ vì€õëáý÷á6χ–””°nÝ:ììì8vì£GÆÑѱR¾³gÏràÀˆeäÈ‘üÌ­@ ¨¿h4¾þúk£ÍÃñãÇ™0aëÖ­ÃÞÞžˆˆFƒƒC¥²§OŸæÈ‘#ØÙÙˈ#„@ëR© •e}·{ ´°E&«¿‡3¤èÚõz=ååzñàÕc †š]ãÖΧ\&ƒI“ + öï‡k»½{ÃéÓPZzÛU?~ DAAŸ}öóçWöòý÷ßíL-Z„F£A¡Pˆ*¨ódffröìYzô¨0r;tèM›6ÅÖÖV§VM{6-­[·f÷îÝXXXpøða¼¼¼èׯÙÙÙ¬ZµŠW^y¥RÙµk×ç¯ùóç3|øpñ¥£×—STXDqqPáÙJ¡TŠ{*øÏ¸æ.WPŸsÌ13SÖXûµû5ƒ“ Š‘"Ü%¿üò 7nD"‘н{w6mÚDPPÑÑÑìÞ½___ ÀüADDaaa˜›› ÁÕ€rMù(++£ÿþìܹS¦*™™XY[c{äææššB?ÿUBtZ-òèýkëæMìß³‹7Þ¯³^Çê# …™L*Q¿uÐ×à&˜\Üàá¦ÿþÈår£÷%wwwŠŠŠ¸rå ………œ9s†3gΰoß>BBBxã7xÿý÷…àj€]»v¡Ñhèß¿¿F=%=-ͨx\ÃÞÞVKbb>>¾·,ÿnØ,z'üÁÍ/qòÄqÊu:¡€Ô!ÌÍÍjÔËš ænxï3]ºtaÍš5|üñÇhµZæÍ›gü®I“&üôÓO´nÝš™3gòÞ{ï¡T*éÒ¥‹8~%x踤óVŠÊ”)S8(vk„ÒÒR>øàúõëGtt45bРA|÷Ýw|üqE@®Ù³¯ûÅ÷÷÷篿þ¢iÓ¦LŸ>ððpÌÍÍéÝ»·8ªSGÑh4˜U³ûèäìBäñc& È;‹R®/ÇÜ\Áäç§²õï¿Ø¿o7a¯‡ÒoÀ£têÒ­R=Y™™|ýå甕•ˆŽ»òÉâÈÏÏC.7cÌø‰üß§Ÿ`ee…J¥Â`€—f½Â”g'Ð(°1:o_&=7¥RýWb.³vÍwètZ¤ROŒI³æ-ÅÍ­'DDD²wïA&O‡­íõÀ™ÅÅj.^¼Dppe—Þéé™äç€^¯çðáctî|w.é‹‹‹¹x1¦RlÿŠ””4~úé×Ö˜èÐ!„åËWâííÉc]w¾mÛNœœiÓ¦j7æùùÄÇ'Ò²e³ûv?222ùë¯-Lš4Î$}ÅŠÕ8::3pà€+µ[IL„•+A«…à.¢aK$žzê)rss±²²B&»î]ãÀÆsðnnn̘1ƒÒÒRœÅ,"xhðõõÅÒҒ ÷Ž ìÛ·fÍšáïïR©$--„„-ZÄ‚ „Ðj…BÁ÷ßoülnnŽT*eìØ±äææbmmm2;vÌ8yzz2mÚ44Í]EÔ~$I¥ø ~ ÑëË9yœä¤DÆ=3™Ø˜Ë,z»ú²²R”*ž^Þ€„­‚ðiЀâ¢"®ÄÄpîl4––Ì™·€åŸ.E©R¢Vãáéż‹Ëå„- ­²þ³ÑgÐëËñhHvVÇŽ H!++›’’R¤RÓ£YÙÙ9·µH>~ü$ IŒ7Šï¿ÿ‰§žŽ££ùùù|øá2\\œ«T@’’’ùùç |ðAz½žÍ›·ß‘òÎ;±pá«Wõ…ìÛwè¾) qqñ¸¸8Ñ¿o "!ÀˆCùðÃÿ™( :µ¯2ú5rrr9|øØ}U@ì2ä1“´•+¿§S§vxzz×èx« HRìÛݺÁ‡Þ0³…¨(=úÎ.R.¯R©¸Ù–µµµð-xèÉd<ýôÓÆÏ|ðA¥<þþþtîÜ™Ñwøl þÛfUóÔíÎ_666Bˆu©TоšCÙeee(”×wæ—ö?z÷í\&ãDı*¦ÍšWJ·²¶¡û#½°³µÃ¬Zñnîîøø4ÀÙÙ™„ø¸jû—•IQQ!vv·Ž7вU0-ZV,4\\Ä­#èõzÜÜ\133]&'ßžkà |8pà0{÷ÄÚÚ++KrrrY¿þw&LxŠÍ›ÿ©¶¬ ß|³†qã*~ƒbb®°zõhµZ¬¬¬˜J¥¢uë8;W¼ðqrr4yA”••Í{ï-¡E‹f<óÌV¯þ‘óç/Ю]£’d0øí·?Q(ÌiÙ²9ß~û%%¥¨TJ&NCTT4eeeDDDâääÈ”)“ŒŠÏüóÏnvìØ@¿~½èÙ³ß}÷{öìgõê/ŒùJJJ±³³ÃÖÖFÁªÄܹPÕ(;;xñE¨Â®@ ÿ%dg瘤YZÞ?EO.—#•H)*,Äꦗaéi¸¸º?}b_ñ9zƒž¦Íšc}U}rÔhÂ^¥y‹VU* ææfœˆ8FrR"ÏM™Ž¹¹9«V|AI‰ß899ãß°!*•б'søà~äfæXXXòíÊäçåÒµÇ#@…zÜ•Âßy“W_[H×î°zÕ NFÇÎÞž™³çŠTOÈÍÍÃÆÆ__oNœ8…F£eñâOiÓ¦'OžæòåØjËЪUsV­ZÀæÍÛyá…gðôtgïÞƒœ8EHHk¾új5áá‹X·î7ÊÊ4Ì;“ÜÜ<ÂÃG¤\\œŸCCà ÆÑÑžNÚ‘œœÊŽ{?~4/¾8‡/¿ü„;ö››OQQ1¡¡³±µµ1*0Uáâℯ¯7ÖÖVÕæqrräµ×fñÃëiçÏ_4ö+99FKTT4 ¼ÅO &8¸%?ýôîînøùùϾ}<øQ^{mŸ}¶˜Í›·SPPX¥âïßÀø÷† ѳg7&MË¥K1Æô]»ö±qãßœ?‘ æbgWsëéÚ©€´hQuº‡GÅ?@ î#99Ùh4e”ÞäöÝǧÁ}m×ÑÑ‘‹/ “J±³¯ˆù’š’Œ£“..×éº{xðú[ïV*ß¼E+š·hUmý*•Ͼðb¥ô¹ó_7ùÜ®CGÜÜÜúDE\;;{^žcªPô8ˆþ™¤½4ûU1€ê!Û¶íâ±ÇúãããÅéÓgIIIcøð!äææ‘““Ë¿™¦6D¯7ðÃëªÍãééÀ¨QOTú.))©TЧgåu¢D"A"‘àååAPPãŠgÈÝ ©TJß¾=°¶¶2±[©Ž† ý ¾'Y];NyÍ^ÏpÃùÊk}õók@³fM®^·‰„GígÌW\\Lll<-Z4E£Ñðý÷?ѵk'²²²6^7Ó³g7¢£Ï3tè \]]Ĉ@ µ‰²²2ÌÍ嘙™¾å¼ßJ$R)›QŸOnnÅîKã ¦µÂ5öȧLj!¨–_œÌÿýß×$&&óè£ýhܸ¡ñ»ÌÌ,JJJª,§T*Œ» ùãèèÈÀ}ùê«oÐh´X[[1iÒ8ôz=vv•ãWµk׆ÐÐ0Ú´iE]°·¿žÇÉÉ‘ŽÛñÍ7køçŸÝ8::лw´ZŽŽ¦A]œ«üÛ´¯J,--+¥¿ýöGœ9sŽ•+¿gòäqdeeóþûKILL¦E‹¦ôéóAAÆ•öíÛÒ®]0]»vdäÈalØðéétïÞ™o¾ù˜˜+¸ººÐ»wŠ‹Õ88T>öxùòæÍ[Ä–-¿"“ÉqppàŸvãä䈻{ÅnéªUk8sæo¿ý!¯¿>÷ê‹ÛZáM²xñbCu_j4Êï…= IDATËËyá¹gJõHågSårs¤R9ùù9Ä]É ¨©±LXØ(•'Ê&Mšba¡¢I“ÊËuœ9sžÇˆTjÀÎÎG<½@ x`üñÇ/4nìZ]d’~ñâŽ9†¹yåéÆƒ2¤ŸÑP·\'¥¸¨˜3fÒ£çõ·“ ,z=‰dfzÊ˵Uöá·ßþäÂ…ÆOwÃàz}?b¢÷Ñ I§z ýèþ-\¾x‰òò2ÆŒQéûÔ”t$%nîwHöüùK$'§Ð»w¬­­*-B322Q©T• §##OÓ¹s{1aJÔ%ØÚÙâîቻ‡'* ñqW*Å$©Š+1÷Ï}ÅŸ‹ôPkB*þÕó5I9‚uͶãfÞÿ}“jìØ±bfAÃ`0—›‹›»i 5¥R…ƒƒ#)ÉIø\­p2ò8ƒ;;{üü¸|é"øÏMާ§7.®®•Ú()QsþÜY<<¼HII"¸MÑg¢Ðh4XZZظ )Éɸ¹»sêä \\Ýðôô"%)ÉXOJr2žžâ¦ÕQ,,TbG­žsÍ oM!·@ ‚šG«Õ"¯ÆË£½ƒ¹99&i‰ ñ$ÆÇ³yÓŸ\‰!#=‚üãã),,¨²žË—.±þÇøúËÿ#!>Žõ?ý`T(ãã9°w7‘'"¸ÃÜÙ/‘Ï߯¦¨°€¤¤D¾ü¿O9|pŸ¸a‚JäææqéR,ZmE¼·ää.]ŠåÒ¥Xbb®T[.--K—b¹|9Ö˜VXXHJJšñ³N§ãÒ¥Xrsóª¬#;;ç¶ž±‚‚Â*¿KJJ6ö566Îäzt:1ŸF£áÊ•ø[¶s;}¹W’“S(**6IËËËçÒ¥X4­‰l¯]OmB( @ Ô1ÔÅÅœfffÌ™ù¢1]*“¢Ñhؽóú x´ú¶nˆvýÓÚï6|ž^Þ|øÞÛ•ò6mÖÂø¿o¾ÿv%ƒ‡=Ió­ÄM{ˆ(--ÅÅÅ33Ó¥áÑ£Çñññú×ò'Ož¦iÓÆôíÛ“åËW’““‡““r¹œóç/2p`ß*ËeeeãççˈCMÒׯÿW×ë±Ü¬¬,7nË—¯4¦8qŠõëÇÛÛ½^Á`à?þ6*¡¡³°²²âóÏ¿&%%•¶m[WÛWWgÆ…D"1Æ›kÕªy¥(ð7þm¢”•——óÞ{KP«KðcÒ¤±&ßíØ±‡ž=»yŠ þ`üøÑ¸ººpþü%rrr9pà0¯¿þ*•úUV¦áÍ7+ÌÚ¶mÍ“OæòåXöì9€——é1È’’R&OgTö²³sðóóåñÇpæLírñ,@ j‰¢P(ÈHOÃÅÕÍä»´ÔTÛy ñÁ»o¡×—óô؉Æï¦ÏœÃ’Þ¥wßþU¶áâêŠL&ãÉ‘;=zöæ‘^}ø|ÙR òóèÝ·?NÎÎXY[Ó6¤IÙ½*òìÞù¸aºtéÈ[o}ÀÑ£'hÑ¢)..NÒ¡C[&LxŠÐÐ0ºwï\myµº„Å‹—Ñ­[gzöìFhèlBCÃnÙæúõ¿¾ˆÄÄd^zi.©©é$$$¾èªFHH0:µ#$$˜åËWbnn^e] I¼ûîììl™5ëÅjÛ?þ)“~-]úLú,NNÄÄ\!>>᪢²™'NÑ£GÌÌälØð—I¿ÂÃñóÏ¿1bÄPÂÃÓnF¡07¦¯X±š+WâiÔ(€aÃ#&&–-š¢Óéxï½%ìߘÿfðàG‰‹‹gÅŠoÉÉÉ# À`¡€Ô$䨱cˆC µ;;{’8uòff ¥²ÒR6Âæ&Wòó¼Q©¼½ƒ¡¯W¿hsuuÃõåæšB1í¥Y•ò¶m×Áäóµ¼7ÿ-,ZÎüùsP(Ìùé§_9uê '޹íò*•’Y³¦ñᇟгg·;jÛÛÛ“&MøóÏͤ¦VØŽ´nÝÂ$_Ÿ>=Ù»÷@•u4hàCXXè=É À¨ØÕ9yò4ƒõ£]»6?~Ò¨¸8;;]½f]ºtà­·TYçÎ{Ù¾½âXÚÉ“§éÝ»Gåż\Ϋ¯Î¤°°ˆ*vš||¼?þ)bcãhÙ²y­/õNiÑ¢þþþ|üñÇbÆÜWôz=ß}÷cÇŽGÁmáå탛»‡1ˆB¡D*&›‚ÚÍ+¯ÌàÓO¿ÄÉɹ\FÓ¦MøþûuÆc…*•²ÊrŽŽìܹ—Õ«Ä`0\q´ïçŸ7pút4›7ÿÃÀ}(..fíÚõ?~’ãÇOÒ¶mkìøöÛµ”””röì,,T<òHW<=+v‡ Ä™3g9tègΜ#:úœQQ¹NŸŽæðác¨Õ%Lš4{{;vìØÃéÓѬYó3cÇŽ¤yó 6lø333Ôj5ýû÷ÆÉÉ‘™3§°uëöì9À¬Y/Ò«WwÜÜ*<ÓõíÛ³R[7}:ôi¦M{޾}{’žžAãÆ®öç,))©lÚ´¼¼|š7oJÆþ¨TJär9ææÇǤR) …sssäòÚ÷®Þ­ˆ¬­­±¶¶D BÁýG§ÓñÌ3Ï0jÔ(¡€‚Ûÿq–ËÅœ!¨cë++&MKffþþ 03“3|ø¯*UÛ$5hàØ1#(,,$4n\ájºmÛÖ´jÕ•J€¹¹‚^½ºÓ«Wwìxá…I¤¦¦¡R)>|0vv¶<÷Ü£§,339!!Á8;;QZZÊàÁ«]ûÍž=­Rš‡‡óçÏ*\4iÒˆ%KÞ5¾0 —/ÇR^^Ž……Þޞ̞= [[FŽFvvR©”©S'“––€mµm,[ö¡ñGz‚K—*âû <kk+4-cÆŒ®ï¦TU_Ó¦MhÔ( vÎqâ‘ fÑëË))ΫçR0PªÎG*­¿/õåºkÛÌÌŒ“'Oc0èMÒKKËn»{ãÂ*v=®½½¿î•Ò®gºÞ?y¥ºll¬±±±6IsqqÆÅÅÙ$Í××û_ûpãBþŽŽö8:Ú›¤]Û]¹‘† ý«­ËÑÑ[[lmmþµMÀÄè_*•Vºn33³*åzs}J¥¥RQ+ǺP@@ ¨AÊËËùsã_H$! vÔë«/--Ãß?€¢¢²Þ¶½½íÚ‹!( ˆ@ ;AAçAy î‚Bà!§M›V”•i„ ¦‹3¹°QD Á} A!Á§¬¬ ­V+QïUY¶.@ ¨'h4Bù¨ïÈdÌÌ„òÀ8tèD(x`>|˜Ž; AÔ3>‘¸¸ Ó˜–ØÙÙ’››GI‰ºVôµE‹VUz’Òë ÄÆÆ¢Ñ”Öx¥R)Í›·">>†ÂÂBôzSÌ~~>x\YY%%¥U.ToŽ_Q_|±ŠøøD êO×®ÉÍÍcÅŠÕäææñØcèÒ¥C¥2ÑÑçùðÃOððpG"‘0nÜh‚‚‰ŒŒâôéhÆ €¼¼|Þyg17ä¹ç&ÜѵeffÕÇݸ™?þ¼Ê ‘‘QäååÓ³g7Ôê¾ûîG¦L™tDz®®þU¾V(ÙbZ‚;gÉ’% 8 &°oß>Þxã Æ™™-[¶dݺulÛ¶­^Ê&661Hj))i899`n^½›ßÔÔtbb®ÜKK‹jó©TJ”JåÕ¿-°··¿z†ÜÀ©S§ðõ­õ* r*¥ëtZRS“ñööªñ>Êd2T*ÞÞ^”—ëÉËË£¨¨ˆòòrlllxŸòó P(•Žf={žvíÚükù­[wÒ¸q#¦L™Ä§Ÿ~‰¿Ö¬YÇsÏMÀÞÞ®Úr¥¥¥<öØFŒŠN§#,ì}Þ~{!¥¥¥·2æ³³³åõ×_eùò•Æ´ŒŒLΞ½@óæA899réR,ÉÉ)téÒ¼¼|¾ûî'ºvíH‡! öì9€«« AAäååsòäi”J…Qa¹™’’ŠŠŠ0ôdeUŒ³£Õê°··£U«æ¨Õ%=z¨p4Ñ iiéœ? ;;[23³(--%##‹ØØ8ºuë„L&ãØ±«±´´ ]»6”——³oß!ÜÝÝhܸ¡Iÿbcãð÷o@\\qq ´oß–²²2 ©©éäååÑ¥Kí:.Ó³@ ÜQQQ<ùä“$%%±víZþùçV¯^M×®]™5k­ZµÂÒÒ²ÞÊgÅŠbÔ222™9s99¹·È“Å–-ÿ ÑhذáOŠ‹o½‹¡T*ñððÄÍÍ33) ‚'Þ ;5zíñôôÄÖÖ®Fm3,,,°´4ýg0ÜÞ=îß¿ûö$44 //O<<ÜHJJá‡~&44Œõ믶ìÚµë ã7Þc„ŠcFÃW_}{Ë6¿þú;ÊÊÊ(++cåÊï2½ž¶½^V«E«ÕïW­Zc̳eË?$$$±rå÷”••‘žžÉ‘#·lwÕª5Æ¿ùå23³)++ãÈ‘Nž<ͪUßë_½z-ÆØ× .qñâeRSÓ™6íc¾U«Ö°k×^.^Œ¡¬¬ŒK—bعs¯I_:b|ž/]Šå³Ï¾âèÑãh4V¯^{C]ßc0xë­‰Œ‰DÂñã'Ùµk¯¼2ㆅm9¿ýö'½zuÿ—vfÒ¤qØØX³}û.¢¢ÎЩSû*ózzzckkEy¹½¾\Ü´ÿT)G"GG{ uT§ûé§_2d­Z5çË/¿!..ÒÒR† {OOwBCÃ1bh•eŸ~zD¥ïzôèÊ–-;nÙæþý‡),¬Ø‘HKK§¼¼œˆˆ“DGŸ3Î×S¦vËv/]Š1þ—Àĉcprr`ûö]äää’œœÊôéÏpäHååzЋկúOž< Àã0¦…††aaaÁ®]{qvv"?¿€þý{WéÈÙÅ‹1¬[÷#G%0°!¥¥¥üóÏJKËŒãÉÁÁ•JÉØ±£Ðh4\¹/@ ¨«lß¾¡C‡Ò¡CÅYæ–-[ ¡\%,, KKK Ë–-cÀ€,[¶Œ©S§âää$t €V«£°°o¾YƒD"aÖ¬iüïËéܹÇŸäØ±H¦M{–1cFþ1öÁÌÌ ''GZµjnRŸL&cÊ”IÿúùN•ïìì <==„¥û€^¯'33¤¤\]Ýê\ÿüˆÃËË­V‹µµîî®(• ²³sJïÌè¹Â®¨„‚‚Bll¬Ñëõäää¢V«Q«K°°PѦM+fÍz¨°ñÍÌÌ&++‹W^™ADD$›6mÀÌÌŒÂÂBbb®››‡••Ó¦= €B¡ÀÊÊ333²³s(((¬vD.—“œœŠƒƒ=;vì½z,QA~~> ”””boo‹BaNvvÅñ,ƒ$ɤdg瘘ÌÅ‹—ؼy;O>9¨8â¨P˜3yòxËeØÚÚrêÔc]QQÑ´jÕœÀÀ‚ƒ[ðóÏèÑ£+íÚµ¡OŸF¥ÇÎÎ֤߿ææ4nÜÈøyÞ¼E̘1GG¡€A] !!Á¨|®sþüy7nÌ¡C‡x饗hÓ¦ óæÍãìÙ³´mÛ–¶mÛâìì,¼ïTA||"¿üòæææ”””`nnVe>[[üýTJ÷ññÂÛÛóŽº×îƒD"Å`Ð_](€êïM^^J¥’ .cii¯¯·¸—ÿäåå‘““k|s]i×® ƒo¾YÃsÏMÄÖÖ†)S&ñÍ7Ç•žxbp•å¼¼<°²²ª”¾nÝoxyyð÷ßÛ=úIŠŠŠùõ×?°±±&""’îÝ;3vìHcýC‡>FÆþ´lÙœo¾YCHH†¯ØUéÑ£ ë×ÿή]ûxöÙñ´iÓŠ?þ €fÍ‚8°/Ï=7o¾Yƒ o¾Ze_Û·oKiiÝ»wfïރ̙3€Ï?_AII ¾¾>tëÖ™æÍ›²råwôéóJ¥’Ñ£‡óÍ7kðööbæÌ©ôìÙÍØÿ×^›…¹¹9ß~»–áääÈĉcxíµY,[öÅÕ^Íqp°gàÀ¾tïÞ™Aƒú³wïA”J}ûö4Ö5iÒ8c¾ªðóó½¥]˜P@ °oß>:uêÄÙ³gqvvÆÝÝ]å*;wî¤W¯^ìÙ³‡þýû3qâD5j„\.ÇÅÅ…¨¨(6mÚDqq1½{÷¦]»v4iÒDï*‰½¾FCii©‰Ò­[g£arvv6}´ ™L†T*E*­8ÖöçŸ[øæ›5lØðƒ‰’±téÿqìØ RRÒhݺC‡àùçgÒ¥KGžyf 3gNaéÒÿC¯×ãííI¿~½þµ¿VVöM§OGcgg‹·¸‰wIVV6yyùH$äryï,>]I©¼fh};´oß–öíÛ?»»»ñÊ+/ݲŒ«« ®®•ßÄßì]ÊÆÆºR]MšÒ¤I IZ¯^Ý«är9={v3* ;vìfæÌ©èt:ÌÍÍÉ*üÈ<úh¿JŠƒT*eÊ”IÆEœ\~ÝçóÏ›Øä̘ñJ¥rrò°¶¶ÇÆÆž›wž,,,xŸœpp¨lƒÒ¢ESñÞ|}}xæ™±õöúëÒ¬Y3||*\~ôÑGâ Üw @hh¨P@ê(z½ƒÁ@TT—/_f̘1·U®OŸ>¼öÚkôéÓç¡•Í™3g033ã‡~`È!ÿšÿÕW_eΜ9äää0yòdV®\)ØU”JEµß]SZ¶lŽBaŽBaztB.—™(רΥîͱH¥R‚‚š‹Z]\)zƒ÷Wù¸v¬OP1jv7S( Ám’ „P‘J¥x{{óõ×_xÇ圜ÈÊÊzhÝÐ4ˆ† Vû½‡‡-[¶ÄÃÃC ¦ --7·;wµ©Õê(((ÀÑÑ¡Ú<:Žsç.âêêlT0 ‰OÄÏÏÇèÙH©T`cc}ƒâa52™”£G#pv~°Ï†½½-ùùÙ&ijµš¼¼¼*¡ï2™ ;;ÌÍÐjuäää V«Ñë+<’9:Þ_™¨Õ%âá¨çÈd昙)…"Ôf8€———D=æn”€Q£F±nÝ:¦M›öPÊÅÛÛ•JuË<^^^5bT+€¯¾ú†7Þ˜w‡Ê‡–U«Ö •J+@»QAÙ°áOär9føð!¨TJ~ýu#¶¶6œ8q’#†"‘HЇµµ VV–ÈåRôz½fètZ$pqqF«Õ‘——Oqqñ}oW©TŠcèõ)5¹&à6HHH¨ÒO¹àᦰ°kkk!ˆj())ŠÅ²Õ±vízââ077çå—_äàÁÔ—ë9tè(¾¾>Œ3‚ÔÔt£ŸÿŽÛѯ_/:Êöí»>|MšòÛoröìyÚ·okâÑèÿû‚þý{Ur[z37n¦Y³ λp‹91­VËÈ‘Ãxë­hÔ(€®];Ò¨Q§OG³uëN 胣£3H¥±F®½å\§¼\‡TZ¡ˆääÜÿ¥™™™\œ×sôzIÅ“Š[ ¸ [¶l‚Ô»ö¿½Ý¯Ïh4šfõ0pìØ ÜÜ\Y¸ðU^~y*gΜåôé³èt:Þxcžžî9rœU«Ö°pá«,\ø*‘hµZ¶mÛiL[¿þââ(--å7æáà`NwÝÖÁÃÃí¶Æó“O&  Á¨`i‰7é‹ jÒÓÓê¬Ý˜Á``þü· cíÚõÿ:æ33³þ“v—-û‚+WâïË5½öÚ›„††FJJÚÕ{”IxøÇÿZö×_ÿ`ÿþÕdt7lÛ¶“Í›·ßô ‰ÐÐ0"""iûö"44ŒŒŒ¬Z?^„"¸í‰eß¾}õöú›5kf4ž}! @ðÓ©S{rrryï½%,Yò™q‡àæ bÙÙÙ¼÷ÞÞ{o z½©TÆ©SgŒi^^¦v6íÛ·ÅÌìú[î#†âëûàƒæçç!‘H8wîññ‰”––‰›~ÄÆÆ‘••“SÍÄSÉÈÈ$11™ääT“ÇŸ¼­ò ¾Ã;ï,$<|2™œÈȨ*ó=zœ¤¤~üñWã¢þ^xé¥)øùùÞ—uD"!<|áá‹øôÓ/puu&4töm(òCèÚµ£IÚüùoÝU_úõëU)ªùòå+ _į¿n4¦ýý÷6Âñtéçµ~Ì×»ý·Ã‡×Ù@„ÿý7NNN´oßþ¶[VVÆ™3gêõCË–-ï¸Lffæ=çççsøðaBBBî¨Ü¡C‡èÔ©“ñà¿æÐ¡C÷T^¥RQR" a¡â8Svvnn®èõzŠ‹Õ|öÙ \]).VóøãèÔ©½ñ»¶m[#“IéÞ½‹12ùÀ}077'==“¯¿þŽÂÂ18ŽÚ IDAT"´Z­±¡CÇðòËSyä‘®·ì϶m;9}ú,ÑÑçH$Lš4©T¦M[Y»ö~øa~~¾œ>mlgΜ˜››³zõZöì9€L&cܸQhµ×w=¬­­1 ÄÅ%`a¡¼¥{}!77ÜÜ<ôzr¹ ¥RY£ýqss5QZ’“ïÜKÙáÃG ¨ò»ßßÄ»ï¾Nyy9aað䓃y÷ÝÅ´mÛšüü†„……Šuë6P^^ŽBaÎ3ÏŒåØ±¤¦¦“’’еµsæÌàüù‹|øá'Lú,]»v¤¸XÍ'ŸüEEv4½{÷ OŸGøüó$%¥ —Ëyúéá¬]û * ±°°`úôç°·¯ òĉS|þù 5ª¸žï¾û‘_~ÙÈÆ?°lÙ—äääPV¦A©T0yòx”Jï¼ó£¤¿÷ÞvïÞOhhÏ<3¶ZùüïËIKËÀÌLÎØ±£ðõõáÍ7Ã133ã­·æWÊÿ曡·•&&((ÈhLüÁÔ©¾¿ýöÛ|üñǼÝââb¶oß^o .^¼H£FÈÏÏ'##ã¶wB®½=¹Þÿ}š4iÂG}ÄìÙ³¹rå nnnUÚ£DEEÅ¥K—Ðh4(•J6nÜhüA 6挌4ù,¨šsçÎtWeÛµk‡Á` ++ë¡“‹F£aóæÍ¼öÚk·•¿ª|ÖÖÖ‰Aøøx3zô“”••!‘Hqww%*ê Ï<30 P(pttÀÇÇ‹ŒŒL£üž~yyù8:: P(˜gΜaòäÉòÉ'ŸàááR©$((ˆO>ù„ôôtãgAõlÙ²…ððð»*{s´é‡ µZ………q.½yWpknÞ ðók€­­I4s¹\އ‡»I> ‹JŽììl±³«,óÛ=Úãà`_eºJ¥D¥RÞ ˜H+õG©Tš¤)• ú÷ï‰JUµ³‚V­šÕˆ¼ýýë‚WCCö¶6¼÷Þ¬X±[[›*ó¹¸8Ü€ˆˆÕÖ׬Y®®y}|¼ÉÍÍ5ÖùØcn«O))i=z­VGpp ¶nÝqU”]Cß kk«JG«"55õŽì¦Î»HPPàÕ¿/ ‘HhÒ$M›¶"“ÉnARRrµågÌx””4fÏžnœ®))uAù¨— H]%//;;»k?==™LFyyy­uÝ—žžþPÝó„„BBBˆŽŽfذa„‡‡3hÐ N:…k×®À××—øøx”J%M›6%==òòrìììhР~ø!Æ ãí·ß&>>ž.]ºpöìYÞ|óMzöìIZZîîî888бcG¼½½Å'Ô0ƒ|(®C"‘`a¡ªs‹iÁÝ1þ[ Fކ¿Õ ò¶m[Ó¬YÅ˯  ÆX[[áììÄ”)“H$øúú0hP¾úê[JKKñóó¥Y³ Ôj5îîn&u:uæÿÙ;ï°¨Žµÿ¶±ÀÒ› Š)*ˆ ±Ä^ˆ‰=11EM¢&ÆôÜ”K¼‰ÑXâMrsïM¹–˜¢ñM¼˜X¢ù’Ø{E°é}Yv¿?VŽ®€éÌïyxØ=;3gÎ;sΙwæ÷eãÆ-(r\]]èØÑKKµ´Z0eÊ£ôèÊW_­âÀCx{{áîîfæ¡M×¼ùɪÝ[²jÕZ“™;w1óæ™LΜ‰eË–ßpuufúô©deeó÷¿ÿ‹ÌÌl~ÿ}'Ç`àÀ~DFÎcèÐ’Ri²@ïÞ=Y±b»wï£C‡ö¸¹¹¢Ó•ñþû‹ILL&*j&ŒÀÛÛ«Jݪ;&Á=Ó§O¢££Ŧ_.—ciiIqq1vvvMN6qqqh4þøã† ÖbÚÜ‚òòrzõêE^^Ï>û,YYYìß¿Æd÷ýý÷&·œÃ‡›ì¿G…Z­fÈ!”——sÿý÷£Ñhؽ{7Ë—/çÂ… øùùqàÀΞ=‹F£¡OŸ>¬^½š .жm[ÂÂÂpuuÅÖÖVx‚VBnn^•IÆ»‰_¹r+ž{îé*Ÿ®31c*sçšÇ¯iÓÆñã4;ÌÒ¥Ÿš{öÙ§ªœóí·k¶ŽˆˆVƒò\}YS§>ÆÔ©™{øáñ¸¸˜¯b~üñ‚*yGQe3ù¬YÏHŸ]]]xçªÜ«3ÛºQŽ·:&&Jii)‰‰‰¸ºškÀIIIxzz6©Ùþ6mÚ‘‘Ñàçݼy3kÖ¬!>>¾É¶c^^J¥’”””×G­­­™9s&999Ä©S§ˆ‹‹cܸqh4222ËMŽí†zíe’ˤI“ˆŽŽæ•W^áàÂ… xzzâééÉo¿ýF`` ¡¡¡èõz6mÚÄùóçÙ´i÷ÝwIII<òÈ#tîÜ™¼¼<›¤Z¤¥¥áîî.F$ÕðË/¿0vìX! aggGjjZW±íÚy á܂ѣ#îho•@( fìÚµ‹ŒŒ <==™>}:VVVFÂÂÂ8räH“1GIOOo´ÁPll,‹/fÑ¢EMº- E‹ puðàA @LL o¿}}6ÈÝÝwwwz÷îÍÕ«WñööæÓO?­R†££#ÞÞÞœ;wŽðp“KOT*^^^¸ºš6ÖõêÕ‹¨¨(ììì˜1c£FâàÁƒ¬Zµ £Ñ´a´}ûö¼ùæ›î©¥!(,,¬eK&“µ¸Àk±±±L:U¼A‚„¥¥ºF³)AÍÜ.°§ zZ}øøx^}õU|||X¶l‹/fĈ$%%ñå—_ræÌ"##=0Pnn.ŽŽŽ¢ÇÖ@LL ãÇçüùófF£4›sãçÚ’˜˜Xí@ÿvÔæ¼.\Àßߟûï¯y³ƒƒ¨Õê=y{{óÜsÏÑ­[7³ãLž<™   ³cƒfÈ!„‡‡óÅ_ð裲|ùrúöíËðáÃùùçŸE§»C<==IMM‚à­~$)) ///¼¼®oÜyÿý÷¥ÏkÖ¬aÆŒìØ±ƒO>ù„:0tèPi6YPwhµZN:uKÙîܹ“ÁƒÍo¿ýFHHVVV\¼x‘éÓ§Ó³gO¬¬¬˜7o¡P(°²²¢¤¤£ÑȤI“ àÈ‘#UëÖ¶:âââxâ‰'X½z5S¦L©1Ýÿþ÷?Ž;†““É&T­V³hÑ"† ‚——žžw¾¤]ŸÞÏ*]RW2pàÀ[ÖaРAÌ›7KKK6oÞÌèÑ£ë½_œ}úЫW/>ûì3¬¬¬pttÄÁÁ¼¼<À´ G<òÈ#Œ1‚‘#G"“É8~ü8‘‘&ï¶¶¶|þùçŒ?ž€€¶oßÎüùóéÓ§ä*wÞ¼yüøãdffòùçŸsêÔ):w•U•À’$==ŒŒŒZ»€­/T*•´Éß¾}DFFbiiIYYk×®å7Þ¨6_~~¾äе´´”ƒÒ­[7ŠŠŠnkžН¯/‘‘‘xxx`ggÇ·ß~{Gõ¢k×®Rýžþy¢¢¢ˆŒŒ4«ûðÖ[oqæÌ"""(((`ݺuDFF’››ËéÓ§ÑétRy3gÎ$**Š+WLn!oµ*w7XXX.ÇÊÊꞃwÞÌСCÍVùš ݺõ OD´µ°ÿ^:tèÐ`ç« Ô'h½(*”ÊÆ3§n5 H÷îݫ̚~øá‡ÄÆÆÒ§OŸýÉÉÉtéÒ…:pîÜ9z÷î-Í‚7$—/_L3ð¯¾ú*¶¶¶’-?À™3gèСãÇ ''‡ÌÌÌ*×w[¿Ëlß¾½™)NåìdAAï½÷^lÌ9s¦Ùù*ê·»®ÊÍø™™™ìÝ»\\\ø÷¿ÿÍË/¿ÌòåËqssÃÎÎŽ–,Y‚««+ `ݺu³lÙ2ÉÈÈ@&“áàà€V«E©TVë <--ŠŠ NŸ>Mrr2¹¹¹|úé§Èår³>uã WWW._¾ÌÖ­[ âå—_æ“O>¡k×®· Pw£\Ž;Öäî£ÊYq+++žyæf̘qGùªëíÛ·gÒ¤I·Í›››Kaaaµ ÛíHOO'33“#Fžž.ý¯dĈFÜÜÜÈÉÉ¡¨¨H:ÏùóçÙ½{w( gΜ!;;›Áƒãää„§§'/^D&“¡ÑhÌL¤§§£V«IIIa„ ’6uêTΞ= ÀäÉ“‘Ëåüõ¯•bÄÜ©£ ƒÁ@VVÒÞ$ÜÝÝ¥Õ ÊýB•ç©ôœVyÜÍJË­8{ö,®®®õ@´å „ Z 'ÅÊʲYcÔ=ƒ ®B( M…²²2>üðCV¬X@HHˆ4c‚Á`h”ý•{Z;•,WWWipV© ýùçŸF"""ðöö–Ú¬’?fÍïtUgÕªUÌ™3GòU^^^XZZräÈú÷ïOXXØ]]ëÈ‘#ùí·ßˆ¿åêBå 2%%¥ÚAzjj*GŽ©â6uÿþýÄÇÇK¦†Ë—/ÇÚÚšqãÆ‘··7………¬[·vìØÁĉéׯ_ƒÍž9::ÖÚC¥·°Ê>sãÿ›qrrª—ÙrNÇÆ«ìsèØ±ã-ûø×\¹’ysþðëä»r¹777³þ_IMûšn\m­KÖ¬YÓäÌ [2—/'5«@e-‰ÜÜ<äryÑÁ[ {÷FF\\\ ªþ¹±oßAŒFÎÎÎR0¾¸¸óäåЧO¯:ïÓYY9ÄÅÀÒÒ’^½º×ú^(((¤¼¼'§ºq T^^Ntôî»ÏÜçÔ©ÊËËéÑ#ÔL¶îîntìèÛ"úJ«W@BBB8}ú´ôb_»v-Z­–´´4\\\xüñÇyçw9r$–––¶ùÜÛÛ›ÄÄÄF9·«««d’ÑT±¶¶&66???Iù¨-ZTãFíºÆÍÍãÇ“@FF[·nå©§žL{~Ο?/™ÌTšãTîi*((@©T"“ɸzõ*/^dÆ <ôÐCRù999ÄÆÆ²cÇ|||غu+ÉÉÉF®\¹Â¾}ûðõõÅÍÍG}”„„,X FwIfffµƒ} ¡øïä¿ÿý‘¸¸ 2€>ú{!˜ ''——_~›óç/¢T*xûí×7î&Y×¼¼|ŠŠŠ‘Ý´ìVZZŠŸŸÏmó¯Zµ'''d2GžÄÂBU­[ßÏ>[Ê”)™ââbzõêNI‰–Ï>[v× È²eßT¤ïFvíÚKròüýýHJJ!''—;öÜ6_uœ9s–ììÆŒU'27˜«tB¡V[PPPÀàÁXµêœœ8pàS¦LÆÝ½ù¿SZ½âììLvv6©©©|øá‡ÆçŸÎk¯½†››)))UÌ·­VÛ(Q©Ÿzê)¾úê+ŒFc“µíÚµ+|ðAOB-’’V¬Xa¶w᫯¾"''‡¬¬, Å£ÑÈž={8sæ VVV’ùÌž={ËåI³üþù§ëbݺuèõzÜÝÝéß¿?/^d̘1xxxH3ñuaŠ$j‡NWÆÿû#O?]uÿá޽ќLJú’“S°··ãñÇ'qôèI<==Y¼x «VýÀÅ‹ñ¬_%•9‘#‡²{÷~æÎ5^¸ðcÆÜÜ</žKqq1Ÿ~ú,-ÕLúNNŽìر‡ýû2thUK‰.’ùÔ‚Öƒ FsèÐQ)͉§ù¨ÕÌ™óAAüòËVvîÜÜ9ðÞ{ocmmÕ"ú‹P@$ÍýœdÞbÒ@3¤Ïuíû¾92oÞ<Þyç&]ǹsçÖK¹Ï<óŒ´é¶!íÕ;uêÄ¢E‹èÑ£›6mbôèÑìÚµ‹ŒŒ fÏž»»»™ò°}ûv–-[Fff&†¾}ûRPPÀ„ ˆˆˆ oß¾ôíÛ×,† fÈÏÏ‚¨†îÝ»³téR¡€4 mÚ¸áãsçnZ|p$>hjŸU«Öš¹]utt¨•ù‰àîYºôk¶oÿ£U\kxx/ÂÃM&TëÖEÕ˜.44˜çŸŸ. ô«ë‹˜”¹\NBB"ãÆ=xÓ3ÈdípáB<–––LŸ>å–{:~x½zu—¾+rz÷îq äIþóŸ•RþêÌľþú{4““ŽÇ«~"ôßÿþåå¦MßII)Õ¦éÖ-„iÓÃÞÞNа>vì|Œ%Kþ‰^¯göl“'Å·}˜¿ÿý_¼õÖ+ “ÉÉd’«öîÝ»Jå—–êxë­WèÜ9 þÆòåßRQQ!)6µzKåÛÛÛ!“É4è>iOÌàÁ¸xñß¿ž³gÏa4éׯ7*•’½{£‘Édx{{Ñ¡ƒÉëcFF&^^Á”–šVÒ+¯©¼¼œòòòkïê?ˆŽ>Ì’%ÿäµ×fcaaÑjîV§€€É“B¡Pàïï'­Vš9EF¾†Vk*×ÖÖ'§^¬Zµ­¶™L&y5 Æ`0šíŸquuáêÕ Ò÷W^yž’’”J%J¥âÚä@?iE¥ò~9rXGï¾ûf‹Zýh• H`` 4{¼hÑ"À´w 94ì_|Ñh›Àår9o¾ùf«}‰”••QQqwþ²mmm),,¼§ó:99€¥¥)Zé}÷Ý'ÞèA+D¡P˜y®ºñ³J¥º¥+q ö(• ¬¬,…0˜[ Æ›jµš“'OKÊR%w óN&ȪsElmmÍÍa¸ª“ÛÍÞÛ*ß7¾‘êîÓZXTþ.¯R¾Z­®»K©TT9V]|´”ïñ²²ªâ\èf'·º6¡€4#¤HוAx.\(-‡5eÃÖͲk­Œ5ê–ë '''agßL9~ü8………øúú¶zYœ;wî®WAÃboog¶OB ¨OäB&Í».¢{ Z¶â*¢5·>yäÖ¯__«¼ÅÅÅUü»·lll(**ºãØDß~û­èLDZZ:ûödß¾ƒ ¡€Í…iÓ¦Õk€CAÓÄÓÓ“+W®AÜ„R©äÉ'ŸdéÒ¥µÊõêÕwkžrK„ IDATÝZ)-Õ‘››Knnn³X釛›;þþf¾¾Q«ëÞL¸á  ! Žî‰þóŸ¼öÚkRPLAýáãÓArß»hÑ'B ‚kŠi)2™˜ƒnÍÈdJd2s5ÀÚZCYY‰Ù±¬¬lŠ‹K°·¯[sb¡€@ ´"Lñ(*„ Z1 Åõ½ÐP@ 4 EEÂn¾&,--)--m‘Z‚–Œ¦QŸ‚ÆÇ`¡Ó5ž*zŸ@ ÜB)))‚¨µZ- …‘‘‰NWVÅÝÿÕ«ôè*$ ȽpèÐ!³@„A}sôèQzöì)ÑÌ™?>ï½÷žÆ |óÍ7Èd2†Np°p'4gÜÝÛT‰CqåJêޝŽµÆšY³žÁÅŹJºüãs23³èÕ«;=4¶žáKxï½·ï8½Ñhäƒ>â½÷Þºëüw{®‰‹»ÀÎ{™5ëéd{Œ¨¨MØÚÚðâ‹ÏbggËO?ýÌÑ£'hß¾³gOov}­Õ) þþþ¸¹¹¦øA}³eË–Vı¹SQQÁ™3gøòË/yðÁ…@nB§ÓqêÔ)† RcšK—.QTT„ 'OžBk@Ο¿È±c&™geåêŸÞÊÂ…ï"—ËY·.Šää+Õ* ™™Ù,^<€ÜÜ<öí;Hrr r¹œG™ •§ÕjquuaذAœ[&åKK»JFFfµõÛµk/‘‘󈌜GZÚUÚµó¤S§@¼¼Ú±bÅwlÞ¼ÂÂ"λÈéÓ1ÄÄÄpúôY¾øb'NœF&“U[¾‡G©Ÿ¾\Rˆ~þy‹”æìÙ8âãضí쇛›+ûö$>þ2{öì7»®º 55ÔÔ4é¯rµª®#p@ ¸^^^¨ÕjÖ¯_ÏúõëÑétw•óæÍ,^¼¸EÊæ‰'žàßÿþ7Ÿ|ò Ë—/¯áe–JÛ¶m¥ï%%%( rrr°°°¬žqqq–f¡5¡€êiÓg÷îý€‘Q£FÜq¾’-ööö„†S^^NTÔ&ŒF#ôÃÓÓƒüü Špp°—̵¶mûŠŠ iµ&2r……EüüóV®^Í@¯×ãàà€¥¥i…åÛo×0tè@Àäº6*j3£F ',¬Gµeët:6oÞNbb²ô 0ÐF#¥³°°@©T¡ÑXIŠŒ••%J¥²Î÷ßåææ\“…Q:fee…³sÝ»L ˆ@ ܹ\NXXX•™hß¾=J¥ŸÓ¬]»–Ç{LK häççW1ÒéÊîBá5 TÏž=¯¯wµi gÏÆpîÜE;RPPÈÙ³qTTpssÅÉÉ‘„„Ëäçç“™™‰››+yyùlܸ™€€ŽTTT —Ë ïɤIã¯=ÚU9We œ›¹p!ž)S`×®}¤¥]­±¾7rñbËÁƒG¸t)¬¬l.]JÀÏχŽ}ñòjÇ€ý¤¶éÑ#/¯v5*7µE£±¡S§@³cEEÅ×Ü6 D ”çŸþ®ó”––RVVÖâeóÈ#ÜqZN'Ùc ‚¦…-W®¤a0ÌŽ{zzÜqÇŽÄh„'Ÿ|MµižxbGŽœàFàììDVVGžD.—ñÒKϰaÃ/$$$Ѧ+ôcëÖÿÃÃãGO2jÔpììl™6íqöì9€­­-¶¶6Ò’[1”5k~ k×àj•™LfVÖ#L {÷®äååsôèIúöíÑh$$¤3ÇŸ¢{÷®Ò ºu ¡[·NŠÁ`0 P(ðôô`ðàûh×®-áá½8zô$!!0íQ‰=ÇÀý9{ö~~¦ÉI“ÆW™»“ë¼[RS“ êHYÙõ=,‰‰— ©{/hB‚;}`*•”——ßQÚ?þø£UȤ{÷î€iV³¢¢¢Ú–•ìÙ³‡¦}!K–,J h"XZZJÞÚòä“Þ6M垇8°_•t7{Dz°° <¼'áá×½Jz{{áííuÓ3©ëmë —Ë¥[?ߺVù·oïIûöžÒ÷>}zѧùøÑ£ï¯R~·n!·¬[]’——Fc‰Ñh¤  °ŠB*@ h`žxâ "##[잎{¡ÿþìÛ·ÞQz777ºuë&'4:]z}y³ªó_ÿúš™w)Á½!“)€ªF™™88øSVVJVV6*•J( Ascîܹh4ᆷ…ñÎ;ï°hÑ¢'%%…víÚµ*¹8p€üü|ÆŒScwww:tèÀ°aÃDGjöï?ȦM&eII)B €Va*¸5 …*Uõ+ÖÙÙ9€¡Fï]B©‡ †\.¯·åKAã°uëVzöìyK#66–Ë—/·:ä×_%99™   |||8uê”ôÛ/¿üBtt4Ï=÷Ü-c†ê–~ýÂé×/0¹´n<=½°²r‚`4š¯‚ÙÚÚáîÞ¹\NvvžÈd2ÔjË:?w«S@:v숋‹ ,½O Ü[¶láÌ™3ÄÄÄ´:ãVxxx°páBŒF#ÑÑÑ´mÛ–­[·ráÂ|ðAÎ;G@@ýúõÂ??o”J¥¥yB‚*XXXpÿýÃ$eÃßÿú~ ÓBˆQ( ÷‚££#ŽŽŽ¦‹Á]Ò®];.^¼x×ñ@Z:•û9Ξ=+küòË/IOOç“O>¡¸¸˜§Ÿ~ZJ h$*mùF±*/¨ŠL&»ÓÄØ ç#p@ ÔÞÞÞlذիW3|øp)P–P>@ @ ¨%ÁÁÁ|÷ÝwDDD‘‘›››Ùï%%%XYµÎ¨ÓÖÖÖ”””˜˜È;ï¼ÃþýûoéšW 4 ññ—9s&Ölc±L&ÃÊÊ ½^_oÞŽ“òòr±á“y•ÑhD¯×›wwoCXXw¡€AsÀÅÅ…¬¬,>ýôS"##Ùµk¹¹¹L:•cǎѳgÏV+£ÑH»ví "((Ht˜F¤¸¸„üüÊÊôB ­˜üü|,,TXZZ^3·±ÄÉÉ™ÜÜ<\\\®4¶¨k>yò4¶¶6­¾íýüÐëµ”””’››KE…ióyÇŽV'¡€A-ÈÈÈàèÑ£hµZ† Æ„ HMMeÊ”)RƒÁÐ*½ }øá‡¢ƒ4.^Œg÷î}dgç ´rd2ÖÖ°´TS^®'99 JJ 1[–’––†——pb4‘É@£±ÄƦEEÅääd7j„"µ`áÂ…,^¼œœœ(++ÃÏÏ””ë±Ξ=ˉ'øè£„ÀBhh0¡¡Á¬]û“H+ÇËËFMEEååbE¬u*#h4–€ó5g*šF©‡\4…@PXXX ×ë[í~€–Œ»»;XZZòöÛo£×ë 7›ýwqq¡sçÎBX I{–øøË—a´b®\I%>þjµºÑêÐêV@Ž9‰'ˆPÐ@7™p÷Üb™5kz½µZM~~>ýúõcïÞ½\ºt‰O?ý”mÛ¶ ! ‚&ƒµµF£‘ÔÔ4,,TRXAë -í*YYÙØØh°³³kܱQk¾¯¯¯tÉYi@p/( ÉÃÓ„ ðôô$77kkk&Nœ(„$š ŽŽÎh4&“£ÑˆÁPJ¥ÆÚZéS§ZÜžµ¶m=qqqkõí®RY––еµ ¾¾7o<Ïg­NqrrÂÉÉÉtñbfZ Ô1£FЇ ^8qânnn´mënvüêÕLRR®Ð³g7!$A`a¡®â»k×.Œ1X©ãîîTÃ/ãx@ŒÀ ©œàê’³gã8xð(Y¼ûî›f¿­\¹ w÷6Èd2zô ))…´´t³tEEÅÄÅ]ÀÑÑA´èÜ9[[ÛF;¿µµU£8¡€@ÐŒÈÏ/Äã —/'Uù­°°ˆÞ½{’“sÝÍnAAAD©T²lÙ×,[öõ=×'33WWç:¹¶º,+;;GGGärÙ=—•—W€µµ÷n¦RTTš5Ë8°¿èÌA}( ŽŽŽVñ%mooOQQ!:NŠÄXQQ!Z@ ‚Û`a¡¢¤D‹R© ¬¬ŒgŸ}••+?C¡P R))..ÁÉéúÊFppg‚ƒÍ=°HiiiiŒF# , 22’Í›7‹Ö@ šõ² ½¸¸''S¬ŒŒLÉÓh4’——‡F£!55íŽM°´Z-_|ñ]ºt¹eº… òÚk¯¡Ñhøî»ïˆ‹‹#((H´²@ Z=ûÛ›Bİaƒ„9—@Pß @VV …½^of“™ŸŸO~~ƒ±Æ›qÛ¶m`kkËðáÙ1cÿú׿n£øKv”J%åååÒoëÖ­“" W’››Ë¸qã5½@ ê~ûí·V{ý±±çÐéÊèÖ-Æ€’’~ÿ}'cÇ> :I=rîÜ|}½Q©TXXXHǵÚR¶oÿñãG ! „RWtëÖ•ŽýÐëõR”EKKK23¯Ò©Óu¯r¹œêüQ·k×N€Zm šãàpo~Ë}ôQ}ôQ³c999<ûì³w]Vyy9+V¬àùçŸ¿ë¼ œ={–|°V×ñùçŸóâ‹/¶š¼{öìÁÎÎŽÐÐлλfÍFU«¸ ÷Rç³gÏ’žžÎСCï:ï¶mÛèØ±#;vlPY§§§³gÏ&MšÔlú‡^¯gåʕ̚5«Yõ騨(z÷î§§gƒž7!!˜˜F¾ûAÏîÝ»qpp k×®w÷ûï¿gôèѵz†Å´iÓî:oLL ­öå^^^Î?ü žžmÍÜÜ.]ú5aa=ùî»ÿ2mÚãb$TOÌšõQQkpp0·öXºt%ááa¬\¹ŠéÓ§ A „RŒ7ªÆßüüÚUsÔ˜¯„Whœ8q‚+W®päÈ<==ñññàí·ßfÔ¨Q <˜gžy†o¿ý–.]ºPRR"¥© '''zöìY«ûæÍ›k•×ÚÚš’’’ZåpwwoUyÓÒÒptt¬Uþ]»vŠ››[ƒÖÙ`0`mm]«üçΣsç΄„„4¨¬“““ILLlVýC¯×³uëÖf×§;Fpp0¾¾¾ z^kkkŠ‹‹k•ÿÊ•+¸ººÖ*ïÎ; ÅÅÅå®óææærøðáZ·¢¢‚+W®´Ú—»ÑhÄh4¢V«Í¼R‚)îFHHgöï?(FAõHDİjgddÌŸîj”z­^ýS¦L6{–nØð “'?$MÐ|úÀ`0œœÌý÷ßOFFVVV’r1vìX¼½½ð÷÷Ç`0ÓO>‰••U½ÔG¡PðØcµóŽÑ®];ÉL¬6<ùä“­*o¯^½¤U´»eìØ±ØÛÛ7xï…ÔºÎ÷Roî¿ÿþfÕ? “'Onv}zĈ¸ºº6xߺ—gOXXX­MUÇŽ‹]­òÚØØ0~üøZåõ÷÷§]»v­øõ.C&ãš´‚W^y›Ù³gØ{{;âã/K{5õCVV6YYÙ88Øóúës˜1c ;áà`Ï¥K õ&ÿÒÒRRRRpuuÁÞÞŽ¼¼|²²²±±±!!!€ôô«ckkKbb²”?))77W,-…yº •+ jµš‰'Vû[ÿþæQE ¬ßǺLFçÎk•×ÖÖ[[ÛZŸûvñ[Z^ww÷Zç­­Ó½Öù^hß¾ý=å¯m½­¬¬j5#ߘýC.—×ú>lÌ>]9aÒÐÜ˳ÇÃãÖçõ÷÷¯u^•JE@@@­ò:::âèØzØ*•’‰ÇPZªÃÍÍ•Áƒàèh2ƒ{ñÅgùùç­Ìœ9 AýÑ¥K'23³èØÑ—AƒúKæÀ/½ô6üÂìÙ3êå¼……E:t€ÔÔ4Þxãe–.ý/¯v“–v•ÄÄ$~ùeÎÎŽ¤§g˜åî¹WY²ä}ºv (hÝ H}Qàvxyyµê@<³MƒÐÐ릜&\ï;66žxb’P=óôÓOHŸÇ»¾áßÚÚŠ)S­·ósñb<‡ã7^¦¬¬ŒÇ7µùüùKÈÊÊÁǧ£GG Óéøç?ÿ#åÿõןDã ê:"—+P©¬«ý»y¯GC‘‘‘Áûï¿ÏáÇ͎߼z²qãF,X z…àžhÓ¦Í=­¾Z/;wîäý÷ßçý÷ß';Û')--÷ߟ£GVyfÝȆ X¼x±¢@ÐÊY½úÞ{ïm^{íär…Ùoqq竬xìÚµÏìûŠß‘šš.)h^ ˆL¦ ¢B^¯5û;zô0z}™”îÇ72þV¬ø®JãÆã믿&==áÇ3hÐ Ž;ÆüÁý÷ßÏÕ«Wï¸>W®\á§Ÿ~"22’””:Tmº¨¨(<<>>¼û‡‡‹ÖjÁÖ­[ùå—_èСäË/¿ä£>âØ±clÚ´ ooo"""غu+<þøãµv,¨=2™ FòeˈˆˆÀÛÛ›øøx!˜zÄcʃÁ|Ÿ‘‘…Zm‰R©bRU’–Vÿ¦)ÎÎ.„†ö Ôʰµµ£¼¼éM 8::^3£š¹Ò¦¶¶6´isûø ÑÑÑôêÕ«Ö›/HL4¹œ»|ù²™š}ûöѵkWlmmñðð --6mÚ “É®Iš?(•J@Ÿ>}(//§¸¸777JJJˆŠŠbÇŽôèуèèh¡€4ƒ•+WJʘfÛÏ;˜V²¼¼¼¤ô{÷î¥{÷îh4Ú´iCzz:...båö.(-ÕRXXˆZ}ýU˜ž~{rsspqqB«-¹A1É$(¨S½×ËÏÏ™L¼ƒZz}FcÓ3}êØÑ½¾D4 ù+ AA´iãF§N·v¯Ç–-[6lÿûßÿjtÅ{+‚ƒƒÉËË#22’.]º˜ùïÿè£X²d LŸ>•+WrõêU¦OŸ^ëØASC­VS\\Ì·ß~ËSO=EJJ )))€É5«B¡ ¤¤„‘#G2hÐ ²²²„Ðòòr~ÿýwiÕ£òyUPP@dd$]»v5‹?´xñb>ûì3|}}™1c+W®$++‹éÓ§#“É„@ïììl¼¼ÚQ^nÚ÷‘““‹ãµß²prrD«Õb0ÐjKig*&“eƒhAT*dˆIP@ª{t{Ž‚‚|³£ùùtî|ýÁ=iÒíƒK¹¹¹Ñ­[7²³³éÚµk­ktß}÷qß}÷U9¾qãFé³F£áå—_=BÐâðôôdàÀØØØ¦…BAÏž=éÛ·/J¥’‚‚²³³¹téR­}Á½caaÁºuëª8p ´zu#[¶l‘>ÛØØðÊ+¯!Ö½¾Œâb-jµ’ÔÔt¬­¯›šáìlŠàž••µµ•˜ QqqqB¤:**ôúÝ6]§N5 Œç믿æ™gžá¡‡®o’úã?øóÏ?yüñÇEË wA=¤ÏãÆ«ò»½½=íÛ·§[·nBX‚VGffíÛ·'//ÆÜÖ=##{ÊÊÊj ^ õ¬€Ôžëž­Ö­û¡Ê1€aÆ2lØÐjàn°´´ÂÇÇ€‚‚‚ƒM+íÖÖÖ8::JQÜ‹‹‹ 7yj(/X@ úV=ŒFrs“Dk Á:ôF·¤îf¿½ôÒ ! @ hÉ Èddd‘pY´Œ@ šíÛ{Ò¶­‡„@ ´4äÊ•+×|°›lm•Jöö¨Tj ŽŽ¢Õ@P/\¸p‘€€ÒÓSÉÏÏ£¬ÌäK¡PàììV»2Ï'‘››'„+Z$…w¿FÙ/D¥R¢Ñh°³³ÅÎÎ0räÈqºwïAYYÉ]EBàN¹|9Î;áèh££=ÅÅ%P^^~Í=ûÝ»Ç ô¦¢BD4-“C¶ ÄÕµ NNöÈå2 † Ѳ@ hP*ãph4VX[[‘••{Oe5Ås@P'ÏËZ8†j’¡V333ÉÎÎF§+­*‚F£¼¼œ¼¼<®\¹"„!uD¯€dffqîb2r¹ÒL7*ÊÏfذ(wÁÓ@NNyyùØÙÙâà`/ZJ  ªx’““‡ÁP³³£Š@ 4U¤¤D‹µG/ìœÛ™T£‘_£¾Ç—@DÄÐ;Ú¿¡Tª°²²@«ÕQRr•üüär§OŸÁ`0ˆ–A£R©ÈËË'55ƒÁ(E?¿³É3@ 4Š“ÿ[ÇcÓ_e[Ô>xk:—Ò‹t~ûm#G©ò¹RIHHF­¶”ŽÉd2T*KvïÞ'ZL š)2™éyÞÄkItôa€*f66¶І‚¦¨€lÙðÖ~Gô®íœ8´‡ÿü°Ãì÷èèCtéDii)ÑчÌÒR©©WP«-pwwÇÚZCjj¥¥%¢Å ™Ò¦;”––6Ù:æçPV¦ÃÖÖ–ÌÌ ÒÒÒÓʈ§çý¢ ©* Ïýe>Nm¼YñÏyØÚ;Ò-ì>À|CyJÊòòòk,ÃÍ­ ¶¶¶æ“IRRnn.¢Å “žžFnnN“­_rr >>¾**Ê騱#………äääˆÆ‚¦¬€Èårž~i2¹K+ë*¿»ººpþüE”J%öövU~ íF^^6"p“@ £ÑH~~*•º^Ï#“É‘ËU-MxTΓei©½^ߢD¨V«±°h¸~¡P¨[Ü=\QúnR®IDATQ4L츖x †ú¹¯ê\±¶¶ÂÁ² {‡bÌymI1¶vy(äF*®]ÃÔ©!—ËQ(䔖ꪔqþ|Z­{{;lmmÅ[P Baa™™—qrª?/X2™µ¹¢åÙ>p„ N~ v>­VKÛ¶î-F~:]/ÆãëëÝ`ç´²Ô Tµœ>xúT,nmœ$“þúF.W¡ÑX#—·²ÿa:wîØ<W×kfRù(e`«‘AE>7Ä`Òh®¯ŠXXXTó )E­VSXXL^^Yz@ 4ï}NNn“­_q±öÚÿbRRRQ(äØÚÚÔûye2#2YËüiµÚ?§¥¥e‹‘ŸÑhrÝ ÈhQ}P§+•Š6˜[˜ µÚúÛ{Ýä"¡ÛÚÚ0xð 4šëüÒÒRäryµÊŠ@ šjµÅÅZ¼¼¼št=]\\())!4´›tL.—¡TÊE# AKT@z÷î)ZE B¹¬êŒ©Â(CFã».+Óóý÷ë¸p᯿þÂu«ƒ;àÈ‘ãèõåôí&ú>üðSòó è×/œ1cîÍÛYNNn½šì5ÿýï<þø¤*Ÿïµ¬ÜÈ„ £Q*•|òÉç<úèÚµó°²_±â;._NbáÂw›åuÖj:§¢¢‚òò2,,Tx´u½E -‚X‹dv(KÛ´{9Ÿ‘Ð$êvéRfé;¨byy9={vãС£ìر…B^¯gôèBBºTI¿aÃ/,^<€ÈÈytêÀ²eßðæ›/#—ËùàƒX¼x.¿þú¤¤¤b0èß?œmÛ~gîÜ¿¢T*¥4-¤¤þú×÷18::ðñÇÿÆÊÊ ''GFŽÊ·ßþKK“§¨ÐÐ`¬­­Ø·ï r¹œ²2='ŽæâÅNŠá›oÖÞ“ú5K™øùù{ÊXœF£‘%Kþ…77W|};Ÿ_À¨Q#(**æóÏ—óÎ;©RÖäÉñÃx䑉’9ý™3gùè£ÏxñÅ™„…õ ;;‡/¿üJ’¹¿¿…ôèJ§NÄÄÄ‹¥¥%—.%H Ñ‹/>ËO?ýLbb2öFÞ|óåfÝãâÎ9€ãÇO¡Óéøè£¡Ñ˜dïééÁc=\%ßßÿþ/ vv¶èt:¦L™Œ—W»–£€\8ŸLII)@ ´4*zª ^ÅZ{Á옃£-ÞÞRG½^ÏüùG§ÓèÏĉcñ÷÷åÈ‘ãœ?©Zäüù‹,Xð11±fƒ–矟.}/+ÓSZZJAA!ÇŸjmîåÕŽ×_Õ«àõ×_àÏ?÷0lØ@víÚÇý÷Ã`¨¸¶'UÁˆCøì³ådgç`kkÃåËI$$$2ztûöEóÆ/5{¹Lž<‘õë£8vì$ƒ;÷0|ø`I&¾¾˜3ç"#_¯±ggg²²rسg¿¤wfܸ¤4yyù;v’ž=Mû®vïÞG·n]¥ò+Ü»wïÇÙÙdÞväÈqòó hßÞ“€€Ž ÔŸß~ÛÑìå`6YPV¦gïÞh ê/ɾ:Ä$«¿ V«‰ŠÚLzúÕ–¥€vo(@ ´HÊc ÂüX‡t ¬&uã¬þ«T*>ø`Ž4Kz'øúzóÚk/ðþû‹oP8Ê8zôÛ·ÿ‰§§=4–Ÿ~ú™ÂÂB)]LLÜ-M¼š;®®.L›ö8üo¼ñ={†JòR(äòÐCcñöî@y¹ž>ø{fΜ†‡‡ÉýoåêH%Gž 8¸sƒ¹­&MÏ¡CÇÓÝë2QpäÈ1²³s°°°03ª*[g²²²Ù±cÏ-WІÌSO=q­+Y·.Š„„D,,,HL4™ªÕRÀú!.î¼ô}äÈ!-²öï.]·R©¨1Ýþý‡2d@³¸¦ZlB7"“ÉQ©¬Ä›ªQQ¡¿°G Z/%y%¤'§KßK‹JÁÖØhÊÆøûûqèÐ1Iñxë­WP«-øì³åäååãææÊ¬YÏT›7,¬‡äÒ>,¬vv¶øùù0räP<ÂóÏOÇÍÍ•+¾ã÷ßwÞ OO¦N}Œ¹sÑ©S`‹u‰ß½»i¦ÝÙÙIš1:t ´bô 3iÓÆ•M›¶ñý÷ë‘Ëåüõ¯¯"—ËùôÓ/)..ÁǧÏ>û¯½6›ÈÈyôìÙM*»¹ÊD&“Ñ»w ýû÷‘dòê«ÏÓ»wOÒÓ3xó͗ضí^zé¹Ë{ñÅg9u*Fú~äÈqvïÞB¡ÀÁÁŸØÛÛIåÏ›ÉCeëÖߤòÇaÃIiÂÃ{2~ühÚ¶õhQ^Roì3Ý»wÅÆFCHHéºß|óeÔj5+V|GAA! ~œ9&Ó·¼¼|"#çáçç̓F4éë”}üñÇ5>UËÊʨ¨¨à¹™O#—+ ×´/ lm=´JKóÑjEäy@к)ÔSX\hvÌÑÆ+‹êcLT”Ë).*楗^aБÒñ¤¤$澉L •ŠŠš£ Ëå*lmlšd Âß~ÛV[‚L7½Fçfþüc/Ý{7X=ssó4h_}£Õ–rêÔ:6Ø9mlœP© -F†‡ ]{÷‹£P¨±±±F.oœûøý÷?$2ò5Ô꺋hÿûï»éÙóöJô¡CÇéÑ­Gïç?Ë¿gРA·ÍsÏnx/]ºDJJ  @~-üc^^ƒ'§ê=dåää P(°··G§Ó‘••…§gõnØbbbpvvÆÝýÞ"œÆÇÇãëë @rr2(•Ê»| hÉËËÃãvÊWAAz½ggçzë€999$&&Ò½{w³ã»wïÆÝÝ€€ÓK¶°cÇŽxϲõ?¸*-­êÝÅÒR-mšmhd22Yuޝ;*©ç —Wÿ 7¿vƒ[µ[µFtºkŒ9„èè#FFŽ&"4Qf̘‚J¥j6õ½§¨J.\`ÇŽhµZV¯^^¯'??Ÿ÷Þ{C‡Õ˜/::šS§L›Û233‰ŠŠª1må*̽²bÅ éóÚµk%—ywCjj*[¶l©ubbbØ·o_½6hEEeeæ¦T«V­¢¨¨ˆ_~ù…´4“w—•+W¢ÕjÍä"š&1±ñ$9›ý-_ý+))Wk]æÂ…S\|ÝM¨V«½+¥R}Í”ùßùó—æå%—£P¨ªœÿêÕ o›åÊÕÌŸÿwѹî€>}zÑ·oX•= éЮ§´Ð¸§ÌÌLÜÜÜþ¿½{Šêº8þÝe—} ª6"*‚c£FEƒ)Æ<,0šÄg, MˆÚDâctÆg š¡¦Æg’ª$±Íh‚FMã£mŒ3˨øXÅÁÇ*>XQv1‹ìûöä– ø(>†˜ßç/ؽ{﹇˞û»çœß!>>ž£Gâ÷ûÙ°aÃ-u½\¸pòòr*+ÿ7ÖvöìÙƒAºuëFVVv»Ï?ÿœ#F¨=$ëÖ­#22«Õʸqãh×®•••$%%±fÍ^|ñÅë3 †ÅÅÅlݺ€gŸ}–¤¤$Ö®]KYYo¼ñ‹…ÂÂBªªªÔÞƒ¢¢" û÷ï'..ŽÌÌLÊÊÊX¿~=C‡%--¯¾úJ Ä233C‚„“'ORQQÁ€X²d n·›Î;“ÍöíÛéÞ½;«V­¢ÿþŒ5ªÙt7ndïÞúœåS¦L¡cÇŽQ[[ËàÁƒCÅñãÇ“@Û¶m°ÛíL›6N:É­­ýIQ˜mx$:½ž6m#Ù¶y-{KJ˜‘ó Ÿô;5<ð@dÈÏNg ·ÛC‡"""p:kÈÌ«Mp»ÝX­»8þ))O© ƒUTœ%T0›MÍ.x×ܰ"‡ã2š¬äìÙsAŒF#ÑѪeS…šš+j9¯^­ÃçóñÐCb2©®v¨ùì~¸iãª(&ep¹® Ñ´ ù¾­­­ÅᨹÖHw",,Œìì—˜;÷¯!Ÿ=}º€ˆ3:D©åôûÔÕÕѶm›»ôV(-=ŒÓé¸o®Y×µ5î•`0Èž=¶û¦þ€š’ö^©8s–Ó§Ëï›:¬®vðp—{8]@QØo;Hm­ë¾©CŸ××:¸¸8víÚEee%;wÆ`0ÕjÅí¾qª^›Í†ÓéÄáp¨¹g̨ŸD³iÓ&ÊÊÊèß¿?&L ¤¤„aÆõ½F£‘yóæ1wî\ÒÓÓ©¨¨ ))‰C‡Ý0q¹\,[¶LzµuëVæÍ«Ï’››K=¸téRÈk‰‰‰$''“˜˜Èš5k¨­­¥´´”Q£F1räHV¯^ͱcÇ(**âí·ßàwÞ!--}ûö©ûjDN:E~~>ݺuãÕW_eÑ¢EŒ?ž¨¨(Š‹‹Ùµkñññ,X°€ÂÂB,X€Ûínö‹høðá ZŸ&pþüù¼ûî»L:•ÜÜ\u›Í›7óÝwßáõzÉÏÏÇl6óá‡bµZY¸p¡ZçBˆÖ늳š?ÏxƒÉÌ&Ìà/oM`ÎâÕD´mu»÷ß_A^Þ¬Ÿ§L™ÅãÆh4àtÖ0uêëœ:u†¥K—óÞ{ïСC‡“ï¿?@uµƒˆ3ãÆdÛ¶ï8wîø“ÉD0l2ìªq=Ûl6òóóÕÀ+''‡sçÎIð!ÄÏD»,¼6-ŸY“FòÖŸF1:+‡'Ržnž8¢GX&Mz@}â߯ß#$&öW·éØñWŒ‘Ê™3ddÔߨ:t˜šš+èõ:ÊËO“””Ø¢$22’óç+Q” ±±]¯»¾}Ãk¯½¬–Óåra±XÈÊÛõ7|ø“ê~~ÚëѸýhè9rä))2ßA!Ze2{ölæÎ‹N§£_¿~tìØ‘ÂÂBl6~¿Ÿ'N0yòä[ÚWÃ*®OýdËóçϳbŠΜ9CïÞ½Õ›òÆ¢££Ù²e 7œ_1`À–-[Fbb"%%%˜L&¢££)(( S§N׆&8Õ× D||<_~ù%Û¶mÃn·Ó§O‚Á sæÌA¯×HIIaذaØíõ㱟~º¾á2꾺téB==z4O>ù$ùùù¤¦¦2xð`¬V+^¯—ØØXbbb8vìX³ç°eË-Z„ÕjU¯×‹ßïWƒ«O>ù„’’>úè#&Nœ(W¸÷‰a)ϳøÿbÚŸe`ÒÝËu_WWÇáÃGÈÍŽÙ|{©W3gæ`2™°Zw²cG‰úÞλoy?;vì&99©EeعswÈb{Í)(X öM™2«É±…BÜ9·†×ãñàóùÔ'øW¯^U{"4:¼ª1¿ßF£!,, EQðûýèõz\®úqsáááèt:E¡®®ƒÁ€^¯Ççó¡ÓéÔ9UUUØívºvíJAA:äé§Çãñ`0ðûýêP1£ÑˆN§SÏ ""F£žSxx8†¼¼<æÌ™ƒ×ëE§Óa4 MÊêõzÕž ³Ù¬ö`4ôDx½^ÂÃé­­EQÂÂÂÔ@ Ð$›ßïÇçó©Ã±ÊÚ°Á`P˪ÕjÕ‡†ã4ÖP $ ¯­×^Û!zöO­¿þv3 MAo0etôýo^Û?ºX¼øo$''ñè£}Ù½{iiÃøúëoIKŽÕº“íÛ­èt:Þ|sK{‚Á ëÖ}EEÅ9¦M{E… ?ÀçóѳgãÆ½R&½ÞLiéMÊZYy‘§žªþîóùX²d9uuuÄÄ«V­âøñã 2„ôôô»~ÌuëÖ1f̘ûêâ‘DˆÖËëõ]'·»rÛCK[üôJ£Áåj:ÑX«ÕÜtòì¦MÿÆãñ ‰ˆˆ ==µEeðxê{€Êd2ªÖ«ª.±aæ›ö€4ç‹/þ‰F£Áíöókžxâ·€!Ä@Z4+ âóÕµšùåñ’»_®çŸOoUç'Hã(Dë®GQZ×aŠ¢´xeì´´ßqòd9†øø¸—Á`Ç`¸ñ ÈíÛ·gìØZ´ÿŒŒ4NŸ®@¯×Ó½{¬\ˆBq‡´0ñãr]”ÚBÑ¢€*!¡ç½iätaX,í[ôY“ÉtÏÊ)„¿$Z©!„B!Ľ¢“*B!î8rä8NGµT†â¾äv{î^¢(‚~é0B!·7ðû‰é1ݤ²„âVú + Šró/Z!„â—…4}©úòEŽ=L°•%Bˆ»åJÍ­gS½i²aýŽþAjU!„¸Ž3çB~¿\]ÃÛyó¤b„¿( ·´Ý ×Ô…ú„BqÆT£¹ÎZ-B!~ê¦= F£QjI!„BqGȬr!„B!„ B!„B @„B!„B!„B!„ B!„B!ˆB!„âÞû/ºí®tç-%IEND®B`‚snd-16.1/pix/fm20.png0000644000076400007640000000536011147553266012423 0ustar bilbil‰PNG  IHDR2óš`bKGDÿÿÿ ½§“ pHYs  šœtIME× ;ÐùÅ´ }IDATxÚíÝ뎛:ÐÉѼÿ+çüB¥ÔWÀ° kI•¦$& _l6Ÿï÷ûý˜Ø^@2A²¼ÏçÓõ`ŸÏ§û>ÂlOˆ}¿ßŸï÷+Ì€KýæŒ ¤žÇtdÈ\–/3d£´|Ðõè€S†– 2úÀ4A¶„Ukh-sjæI€«'û{n¯-úF>©}+w{mÙ]íݳ^ª3´¾_ê>æÈ ¸mˆ-‡9¥FN©eW…Xí¹kë妭Ö÷Ë=¶ ƒ€½±egßö>ÖÿïYvUØöŒÚRí¯sËÓ·ž¾­~TkeA ')™ 2b¬½‡&È`òaÕ›zcæÈ€G†˜ ƒ ;mnÞ.+ÝïÎ6·,kmcéŒÅ¯ Ä ³íá Û_3×ói¹eW [ž»¶^*äJüþõzE¼ŠRj#˜¿ûýñ™—¡% È€ Þί–X­òÃËø¤¶{}{ê>¿QÞ( -ÄÖÿ_vìÒ²;ÚYª)Ö»^KNÜd¹ÂjðöË‹µþ;wLÖÕ—el}îÚzµívÒ8Lb¶;p ìä?ÅQÉ›Bmïvë‘AÀùŽ’Õ3o· ƒ`î,Y=ëv 2`z‚ ‚³Rë'—ñ9Ò~Õ/8õ}]ýâ Ÿ‹½½F= vý¹8kÛþY.ÈdZ2A2€¹9E ©lý¤2>¹ª¹û—–ë‘A0Ëi:ëÓuÖ;rê4ž;Omj}îRmµZݵÚrAÁBl»çNÝÙ®{ç©M­Ï½¾|]ϲÚrAÜÒ½ÃàRSAPO.YT¼Øná(þ\UYA„ï¡-á•›#S³ôÆÂl[Ëv§Jd«ÙLb9†–0ÙΞûÂ^ƧtHFiY˺ˆ…I,CªÔ¡¥ew¶«z­Ë¶ÏñÏš2>\Ñ“ð¹`$CK@2A¼_-!˜§]|¤å~¹í¨UòX–ë‘AÀ+޳-ïÓºl´žçÎJQ:6ÎÐØS[ßÖr@éíj ëåöT¶mP*ã‡ÖÓzœ¹abi™»MA ¹Š°O ´íÙGB^¡Á-ÝS»ÖCdtèuuíý†Ÿ9¿B…ØžÎõÈ`¢áXî¶ÞÉó«Úµ„OK¯rý li-õ|zd,¬j%qö”Á¹rHxtûö<¾2>Lóžù\ch 2€»¹Š ÈŽr%`ú Ê_ä3”ñY?íyGlŸ92b3•ñÙsÎäÞmPýÖS[ßvgŸÞ:d{¶¡¶}‚ ˜ž cšÞˆad0õ¼˜_ïLfëÞ§ž¨ ƒi‡ÒBLÁô!–v¦n»³ŒOËö´Ôê?²}ˆ…ÉzbÑÊøä.á6brËRëEõ^i(b›÷nCi™¡%0=A2A9¨ôLöCà®]x$J‰ŸÖÇ?£©_EõÈ `€Õ®¾½-ñ³wÙ™!Ösõð½mÌÚ!È ˜Z=®\eï²³ÚÜòøGÚ¸ôPC^×Ò¼' kCçžav¨ S³Þ7t®[­¢¡%bèœ ¦Ôy™-óg‚ ¸-жa–›«ÍŸ 2 Üг÷ A“íä©¿,»ª]ÛÃJRëåB¬Ö~AFÓ‡“k_÷ÔÎ_šGÚ»ì¬!bËã·Îƒíy|GöC0#ÊÜŒ.ñ³÷رÖöÕ–ë‘Ód€ d™ì‡€J¿â•NñY»²ŒO­Íg´³´LÑôaãþ×½å=)«8¢„ÏÞÇÛÛN§(Áj%|Z ®o«€=²Ígµ³¶ ‚ ˜ž € d€ ƒ‡zÓ!$¥ªµB…W¼-Õ-ŽlƒãÈ pø® ´¬%¼G{K»zÚ²g™«(AðžUk/ê®2>½íQŠÈU”€é™#€ 8ȯ–TêŠB¥«mßYÆgÏãç.@Ò»mzd4ÀJÕR;~éjÜ-Wê>#Äz¿v¥ÖmdT­”O®ÇSºZQË•ŒŽ¶¹õñ—žf®®4¸'—kÛ–fº®%÷ˆm3´A‚ @¤f?U+ãóóÓ^ª'JŸQeˆnï‘-§¬ÿÁÛ¬VƧ§TO”2>#ËZB0-e|R½’ÊøŒ*C$È`¢€« =gjÿ™Ûæ€XnB™J86”›}ÎÚ6=2˜tè9ûe½¥z<4Ðf ³½¥zðèéA…ÀÞR=Êø)Õ£ŒLXÛ¿×sG½¥z¢”ñ)ÑÑö 2fo9žèe|F–!2´¦'ÈA È2ÙAÕŽ¹Ú.Ÿ­ŒOËz¹jáÊø0ßÄø×¿v¬Wî8«YÊøì)÷£ŒLdo]¾™ÊøäÖ[¾D•ñ=æ×m—92˜lgËöõ„šL8ô|j€íÇsñ0¤ нe|~#5^¸Aß¿_˜ -aºËöjc¹cÅ"–ñ9ÒFe|`â^Wk ûÊøŒ,C$È `ÏkÏzÑËøi£2>LÓû€½ È:A ÈA È€ ƒ5¿¤ 2AFÌ 2A ÈðL.>«Ï¢C6Ù..>‚0ÃÐd^ž¬÷úˆ2&6 ƒCÕ\‚ @‚ @2A2A Èü͹™‚ @2 ³d‚ ô¹‹‚ìŒoXáZb¨ˆ d‚Œ§ ã d áŠE2A È ô°A†€ ½cAo0‡µ2AööžÀ¬Cšˆ=½+A È`$ç 2AF=†òkó”ù«Ïçã½¾:Èz_toÒ±µåµ[ïÔ-÷9†eÌà·ehÙz××K9o›{ïS[ÿŒë(Œ\o¸ö~)hϲ®/‡¾Ï_õýúfî5*ȼÀÙAö±‘Âd#S¹gØ0zòxôsØÛ`þøoOƒô˜€)zdë Ì–$í]à’¡e*J!%À€;dµ¼µQNà}LJÏûì½>‰#ûé 2@Ü>týš¤ôÈÀ!·¢Ô{ð¬ƒma쾘ڿrû]ïí£÷ëß»^¸»KÿîO¹}íÈßWì׆–œºS8w.Oé2NýfWQö9½3A†oùŸ?ó©žÚr[éöõý·ë”§÷yK/ÄæðíÅ|Rw÷M;AngH̓äæeR·÷ì|µùšÒúzbß©÷ë[‚L‰ çõÀr;Ãú¶\HyOsÓú¹bŸìë˜Ûïzo¿b¿þ½óÃßóÁò¡{æðóHp‚ëy½R ¿õ}È-ï¹ýŠýú×.Å=ò\ ôÍú»u§,õà 5'îY:×’ÈÞ«>žBln~µD` 1=2=2€ƒþ\Äj¨É IEND®B`‚snd-16.1/pix/ncosfm.png0000644000076400007640000031023011147553270013132 0ustar bilbil‰PNG  IHDRX(„¬€sRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ21ã-aé IDATxÚì½w˜]Õ™æû[kí}B嬪R%EB ‘¦1Æ6ƸíîžöØ÷Ú×·Ç×=óØm»é7íNÆ0ƒlÀ`‚±‰B$a%P@±”³Té„î{ŸX%U«„‘¿ßóœçœ:»JgiŸPo}ß»ÞOù¾ï#‚ ‚ ZN ‚ ‚,AøHsÍ'à†Ï=¡C}r2ANR,9‚pbÙ8Áâ'Ö“J{\uÅ>ÿùrRAN2¤‚%'£Áh~l-ÿ÷ןfÖ™w²lÙ.ŽMʹA%ÂX¶KÓÕëð‡•{8㬻øÔ§âg?[!çGá$@Z„‚pÂÿ¬ *X(ÊOëñÌÂÍ,za öñwwŽœ'A„òG½œA8qlÜrˆCÝ)°LáŶÀ6¤Qü·¿_ˆ27ñðoÖ°iÓ!9i‚ "°A8=µž5æ„•1YOVöb—ë>ý0Ÿûü£|÷»/ȉAøˆ!-BA8øZÂJžü‰¶ñx™k´âõ¥;YúÖNìˆáÛßš''PA– ýÐ*¨Z)1å†>,Š*OëƒÎs<Ÿ®ž´œ;A„ÒǽœA8ÁËδ‹|X–Î]›ü¯ ?¿5Ë—ï‘ó'‚ðA*X‚p"QE-B5@kP)ðà –çç³ç@ÝRÅAøèü=-§@Nä;NÛCC{?“{~+¬vÝô?—ÈùAøˆ ,A8¡+SÁòsž+Ïî÷¼Àå©þÇðYºl¯œ?AX‚ ã+†Œˆ'Wb+ctWy­Âücž3Aá£ñ÷´œA8‘ï¸Ì˜œ°h›Àôž5¹ç]ìð¶ ö¸|õk¯È9Aø ,A8¡+ÓàƒGÐT„_«cÓ»o‡ŠÑ]A– …(oéPX© RÁ„ú'MÑüA+oæà€ÇŠ.#Ý"ÔŠÛ~ü7~á1Λ{7;v¥¯O²·AD` Ÿ*J剥c¨A.6%ظ±wD–·cg7«V˰÷`¯¾±ƒ–¶ÿä«_{ŠtÚ“çOA– üiâ$¹ -£ƒû{Ló‡¥ûXñÖ¾YÛúõ‡xþ¥Î~kùéÏVrÕÕ¿âÑG×ây¾<‰‚ C@óü&žyn#£›Êø?·]Á¹ç¶R[["Ï© Â1 – œÐ?it¯UæbéÂÖa¦Š”çÇR#èÁúŸ7/ËóyÁµìØÝÃÕŸx€¿üâãüä'ËäùA8ÖǽœA8AdfùÁ}¤Zq&lZáÌÁbS»:Žá]Z„‚ "°áC#Ëà›œY\ÇH®ò„Œì"TZ`LC¿ š©]å™ðE` ‚ ˆÀ„_`§5èRá |p¤ŒBT‹0¿‚Õ/aÞËó]Q/¡”x°AD` ‡%°Â QAEfò|“WɲFåŒTKç‰â÷Ïèr9vEKIKA– |Hø–Á·­ ‚õ¾b2-BšÜGHüeLîÅ4d+Z:~ùÇ´˜ÜAŠÿn•S 'ˆLÈhþ˜3À¼¿ŽenkÅ/îØE*å óÚTᘜüµ˜âq>ùÇôÈ…Ÿ ‚ ˆÀap“'Tì†=‡×vÑì?;¡âõá:þð‹?ûk±šIhrÁ¤–æ»?^ŦíÝò ‚ „H‹PNÙˆ_‡Q äB;½¼ì©â7ÈÁRá.B£œ*σEð˜*o·`~LC&F"ó=(º{Áuý;wwß³‚ò²×]7E^H‚ |$ – œ(ò[}ù­ÀÌe bÑqe ¦ö¡ –uŒV`ñ:¬¼ufîÓ†‘1‡Ü÷‹U|é+¿ãô™w°~úº’òzáO©`  {·Yø–L^2úóþŠ)/¬0»Ké$({„ÀòÀWÄ4䇋dÂW#©¯Àhu¥8ôÎ^N™ü¿ùÄ5“¸ö“ùìõÓåu%‚,AøsÆÏˆ˜~9Xäò¥ bòâ2£r´ÂR}êe–¼°‰¥‹·BY<Z×¶ ¯Ý¢9„ùÇðÃÖâ*¬Ì¹ ÏÙ#¯ã™g6ÒÝâ¯ÿêtŒ‘b¼ Zȧ’ œ6$»éSäµÝŠ ãfàV\ö~+l!*´ EÍ0±ww7{÷÷gÇjšÂŸÑ VÿÇíIy|é+OR^y3=¾–íÛÊ M„?¤‚%'€Gìb?^ üÌ,°¨Šæýà Zp¨¬À>|æse¼UPh¸WþÀÉóÙõù¹Ê׈ ,¬-³–ì9ƒ¾´Ç5×>Èç·sù‚ñ|óÿ;W^p‚ |èHKNÈ;Mƒ±0ÊÇø*3÷ïx¡üÊQø½JŒÀ"bVÔò×b£Še›ÂŸQ#Ý"(2"Wé{qq'ßþjü7ž|jƒ¼æA%KEÄIqRØn£üœpÈ æ¹SaÖ° ,­Ã Ö;3A¢ùk1ºÿý™!Ñ#)P‹CP ÖK{°÷`7þåcüÃw^`óæÃòÚáCAZ„‚pB–Bk(Iõ’HÅpŒ‹k ޱqµÁ3ºÿ,B¥òf*0Á.Âáh0±s»!ÏhŸ—•?{0œ~ð³#IÖä^´ƒÑõr-üc¦øŸÿ¼˜SOŘ1UòúA– œœK£”K4•ÄOƒñlÏ`<G\cáhƒ¯uÿh„ŒÀ²¡¡ÆÏ¶MQLCž˜:–+³‹p„Z„ï®ÙÁžý]Ác,//ÚÂ+ƒ?ëÆ/þ–ªª—Ì+¯AANìǾœA81+榈¤“Øéà:’Jb§“Ám'IÄMc|eôÀm:còv³À*ðYéCNûµæ Z„×™S÷ÚëØÒy Ût f~ûÒ’ŽÇ=?[)¯?AN8RÁ„€¯5%©R) ? ޱ1Æ`y.ޱp=c\,má ÇmCߨ J“V冬a^œ1øQ»0h´ Õ eŽúÉæ`þâ?×°ößÏ‘sç[` +g:?”µ(¬ÕÓ¹qC’‘%‚,A89Ñʧ$Ý©žÚóОÁñ<´çáx.ÚsqŒ‹ö]´gáXVÖŸeð°4Ê(Ô0ë_ëÂ>9!ㆭ¿Áb, þÈ|œø*? µ8¦áÑa„>A^A– œ|DÝe©.œT¾ Žçb< 㹸ž…q-\T±ãbŒƒñìÀ¯,¬´C$• LîÃ\ r°ìBV¾ÿËóû›Ëó©XZ#†|þU«L5« ÒFð}HKX‚pò ,'IY²‡ÞT<s»›/¨ÜPt—¬Þ³0ÊÅJ9Øé$Ê» Ý¿šËÿvæð,ÎäÅ4?%n^¥È+2gy¹¡1#(°BÏ—¯CAG᨞‚QCyëÌxÕ´’  "°áäX â©>¢éð|´çb´…ãgUÐ"tÃk¶çâ`°R'WÁzùÁ5Ã&°‚ ÑŒ¡=%ÍÌ\g…b&Ó0B­¸‚ V?±7pLC6N"‚ "°ádXn’h2A$•ÏÏU®<G,c9¸®…16Ž1ãߣ V*MÄM¡ðPFap‡OÀ×" =XêXU+¿ÿ±Ì¨3BYXa >èþ"ª_LC¾À [„âÁA– œ¤Ë ãÒ© ‚処vÏE×wѾ…c<´ï&wß ªZÊ`¥ÓDÝŽî$d3Œ;&my¡É=/ûJ ªòe*XÖ ¨`iàêU¦m˜mf¢,¯½º™×^ÚÈœóÇÉ QX‚p2s V2ò=Œëb'ˆh0A4ƒ1Væ¶¶°¼à¶« v*XIß Æå w+b­Àί°B¤Šåá}~^‹ÐŒ”À çf[„äÖæz…íKíV·”Ǿ}GØ»û¨¼A%'7¤S(‚ –ëYhßÃõ,ŒçOöIÅ¥½lÖ•ö<\× îÌÜΉ¬lK'±ðQZgϰ¬-ÑàçÿðüK?´3•UÑ®¼Œ¨êgx'+°¥9”𨎠³ÐÒ:/‹Â‘=® Uèåò²P(KKK„Žì_„‘þ+Æsˆ§úˆ$“DSI¢© ®!š¹¤ƒK$ÈÞÎÞ—÷}175¹§‡emžç³o÷a´¥ò†;ë¢ÛEÔ îË ~ÞØåñýׇßLž í·®®‹/ÁšÕ—°~ù«wxõÕNy± ‚ûì—S #‹ñ]b©>ìTŠH:…£2-ÂàÚ o‡íC×EYÙÝ MîÄò# ƒÙ†ÃöW–¥1ÊÃ3Œ—âì…&w­ŽÓ üÀeeZxÃÿ7[6¦!;àÙË%É{Äò‘3¹dë'?]É×ÿîêkã<üð'9mÆ(Œ„› ‚,9‚0ÂËs(IöM%ˆ¦¡ÝÂÕ9#»1.–åâ¸Ƙà>ÏÅ1C$"n'±}6Åð,_²Q?‰c—àÛ¡HʶÙÂ]‚Y!3À±¬ÉÝoø?R|­Á²rC¨uÞZ²1 EÁ£ž "” ªX#8.gݦƒô¤\zvt1ëì»9ïœÑüÝÿ;›+¯œˆm‹ÐX‚ ŒÀÊU°ìt*W­2nPÉò=´Ÿ ÕžV²|´ ,7EÄKbù6Jùh†«‚x”¢~’„Šá·¨B”Xù¦òPðdctà“ú BÊóèÝ·’úzT^úz®‚E¸&BC{ÆÔî…¯(V‚0§Ë葵`eDœøÓ/ÙÁâëæ†ë§ñ¹¦±`Áxy‚,A†ýMæ¹Ä“}DR)¢©D¶b•¹Î„ŒÌ"4ž‹ë9áàg MÔIó’D\­üáËÁR lMÔKb“Ƶbø¾Êvyf=ÉÅ%d+X&ˆRø KÑš’º:¶,\H²«‹Æ™3IDl{äA°æ„bNåÅ4dڕLjiP~( ÍÈ|6¡ÿKçmð|~ñÀjûí:~v÷Ç9sV3íí•òfX‚ [Ã÷ˆ¤RÙ Q×sàÑÌ`çþÞ]× ­ÀåùÀŠúIl7‚¶!(´T°¢~Çr·vùx¾ûyò†X‚ Ëï_ÏÄU¸cÐñLè¯r³†vmå„V0ڠÑ:š¨›"æ%ˆ¸<åá&’$Žö«ˆÿ±ú*Û"ŒzIÒi Gã{\£ñ• GÒ 4ìÙ/Lr/ª¥ºº8¼e (mj¢¤®nÈË*kldÂÕW£V,Ãß´¸PÀËÔ^p¬8É}+X™‰ü؈ÌÂq>o.ÛÍ[ËvñÈ#ïòw7›—cÔ¨2ysÂÉüÙ/§@FåyD’ÉàF1DŠâ¢©$‘ПbÑT8 :•$æ$ˆºIl7‰ÆgëkïòÆÝ ‡çCÀÖÄüàßÏÄFdS|”QÇŽ@(ŽG09!)/§¬±‘m/½Ä³_ý*oßw} }]–EEk¾e'šá·Ãuä'V¹ÇµÃËkõ´fÕ»ûùÂ_=ÁysÆòå»åÍ!"°AøÀo2ßËF4—œpÊÞN'‰8ùÇsßM'‰8I"^’ˆ› ’àñPÃâà Lî/0ÑGòÄUÄIq’XŽƒV^ÿ ,“'dŒFÙ ¬ÂÖeI}=3¿òÎþÆ7رd ¿½ñF6?÷¾;´Q?¾"0¸›¼ .“w)}kÊ|­P#ds÷C[Zîñ‹e …^Ñ:ßÛr„…‹6Ë›CNb¤E(#L~+–J„¦v'Œb°²×–´çŒ ï3–±ð¬ÐäóÄÜi'X[`Â7Ù58ž…FKx™Ðù1 ¶AÇAÛ±¼à!´¦éŒ3h:ã ö,_΢o~“·ï½—S¿øEÚæÍC[Öqè[v˜ä®ÞGLƒŒú(”¹ Ö+¯îç?þ÷F(µÂ~aN˜`:sLþ¾X‚ |p0 '[• b2Q ^öÚñ‚`Ñ „4¸v|ßUD$Q/EÄMb”‡Æ–„¾Rx¥”øÉ Šå&Ѿ®Ë*XŸö<ãájƒ«Mì˜S¶ þ_æø•¢Q§ŸÎ5=Ķ—^âÍÿøÖ>ü0ónºéØþ,¥‚DZtN`¹y^0•?2Ç/Œp€pØóHú¯|ˆ¨Üˆ!Ï+ŒŠpý‰ùÇ´ÌïX‚ |pÒ »"ÉÀe ¢l\×É…æG8xnPÁrUhBOu“¥þè –Ó×Çž+èu|¬¨"ê%‰y R©L+·.×Xh˸a5+¼¸ÆÂÕl…Ž{hí¡Íà»cUUL¼újÚÏ?ŸõO<Áï¾øEÚæÎeÒ'?IÕØ±…0¿‚åù¹ðÐÌÄüPÑŒ€ÉßmHОS#%f #X™µd¢2,/-¡óE¢,A8™‘µ Œ0ÉE÷¡{œ ªa€9ƒ¾§t²ß%ê$à ¬à2¬TOËn¿G®¹†XÑõŠÖá„—t’h*•g~Ïám76~ °b¯ñÙÒ;´5D«ª˜~ã\zë­$Žáé¯|…?ù É£yó 3¬¼¹‚ýÍõy~«b¼Ñ#;*ÇQÕ-ÎFÔ9ŸØHgs ‚ ,A8éÖsb\;da¹V˜¥ ŽçaÂØãy¹‡LÚ»ëâûЍT°"^ƒ…Æû£Z„%uu\vÛmLZ¶’%Oo!êãx"©d¶‚ådƒPÝìÌDS”Ûe<—´öðãƒÇŠ#ðÞöƒtL¬òZª::˜ûïphãF–Þr k~õ+.þ÷§f„°EhåµàŽÓ0@„*;'±ë`¾ï\ƒñ囼ü­L ª_˜É• nÕ€ësèHštÚ“q:‚ K„‚s ˜Øb'SDÓ \Ï ZpÆ¢Ê5ãb,ãZ8ÆÍ~íj ßSÄM‚¨›&êÆ°] ­ [„n*ÅÊ;ï yÎgÎt]‘Š FÏ>›ØSk‰ù&Œ°²"Ïx¹=ÛÒ ×¦3ë3.®qQŸt<‚V>Ñ£>¯|óïiúäùŒ¹ôRJ†¦S¢Qê¦Láò;î`ûk¯±ô‡?$ZYIÅE+3§XDð)å(£¹÷;?ãª+g/‹ï“«TËà‘g´@T©¼\¬P„ýó¿¼Ãç¯Â¤I’ð."°Ax߸‡ìD:LrϘÚM`7×LíÉ=“èÌ+ÄWA„‚çñRXN­ý‚aª«‹wÞÉÕ«©?žÉ7ÜÀ_ûÑÊÊA½>A{Ðd[˜Ú³ýçå¡ff'fæ'æÖé»àÙOTÁ¬ÿúe6Þ÷טּóNÎÿçfôìÙÁN¾!Ò2guS¦°åùçyéîŸâŸÿ×y»½Ð8N¡y<ãÇ*0˜‡‚ÇÒhåÈsë¸Ü3kqóÖ6P>a8« '-ò„‘XûÁݦ7¨`EÃ@ÑX*Þ>ÃûbáñhJM%ˆ{ ¢^‚¨›ÂFŸãµµÜ°x1—üŸÿƒ²m^ÿÇä''²âŽ;èÙ³çØ|Jü¾@d¥’ác&ˆe×™,Xs°ÆDv½Á:“ØV÷ˆ)ŸæÓfòñ_ü‚ ~ð^ÿ_ÿ‹§þËaÓSO½¯s«ªbÒµ×råÏ~†oÚa€¨=@øiæþÌÏØÁÏ㈠ëšOoÍ{œ¢u¯©ßqKŒî‚ K„Š×cáÿˆT‰œ TÔÎ µó äv&ä3ÏlõƒÑˆ›ÂrÓ¨¢ @´¢‚Ó¾ô%®¸ÿ~f}ó›¤ûúXøå/óô¾ÀºG=N+œs˜5¸§°Sù†÷üõä¯5…†‘í c¶Î}¨Œž=›ÿêWtÌŸÏÿöo,üþŽlÙò>ÏžÂ7V¡i<è©‹LîÅÇr&÷ó“Ç(4®ç¯e@ã».4ë ‚pÒ"-BAiÆNÄôô %zèN:…q]Œ±‚ÙƒÆÂ¸רYÿ•cœÀƒåZ(ß'æ%°=—¨—Äv’hå£8 }Ôi§Q?u*Óÿê¯xõÿ‘mÏ=ÇöÏ}޳g3ïæ›©›:»¤€_~îo+Åöl¢é$©”ÉEFdã$O–k ƵB|Ƈå H¹Iܨƶý‚¿Ú¢••L¾þz:.½”w~þs~÷…/0ñê«™ü©OQÖܫÕ?ÿ9¯~ë[ì=÷3LžUŽrü0øÔ´ÿc¹XžkÜ‚ãÙ¸žÁw‘t×K *° ˜M)+Òùܾå°êÏ’¦P¤¸ùíB¿ÿ1T(°@ëpfâpósíË⵨ãÄI„ëoþv-VÏÉþs5§œBɨQ¬{ôQJjk©<9ÈA– ü9à».ž´ï”eñÂ7¾ÁäÏ|†õ¿ý-vù÷Î IDAT[‹nj­©Awv¢·lAïÝ‹›L…-8+Û"´´OÔK¢ò[žù-î½—³n¾™ÚÓNÔÓ¯­å¬o|ƒ1—]ÆÛwßÍžµ‡‰ùI|‡ÐÌnÐÙ6eñL %èäÍ&t] ÏÑDœ$ž—ÄØ>?Û ÿV?<çyÝ»â[_.öœ­ZåW…Š+Za+Ñe‚áˆtãâa«¯ †!lQæ· ‹Ûš™˜†â+bUUÌøâ9°v-Û_}•o¼Á”O:¨f‰gKD` ÂɈ›J±wåJ–ÿèGl¸ÿ~Jªª8åÆÿ‰Oн{7óo¹…HY¾ï­¨è÷ófüxtS^k+fûvÜ–ÜmÛЭ­è­[1Û¶aöìÁM§Ð®ƒk,lã5¾ïõ’DÝ | ¥8•¥¬öY:_~™sn¾™±×^KiKË -Eé§rñÈšÿþ¯Ä{ÞÂMC4• RcaG;yós×–qÔ÷à>?­H§“ØtcE}¶ö†Õ£aÀ³lö1Nýæ7‡ô߉&JÇÑAfÌñÓË- ]]./Gø²ZZ‚JVss`†ß´ wÇbpËé^±Ûõ‚ –«Ñ84Ÿu®½†Óþöoyõÿ‘틳ýµ×Xþƒ0ïŽ;¨›5‹òööc.#ê'‰{}¤ÒŠh*‰“V8Ù(† ‚å˜Ðo~]áT°RN‚ˆ*¤¹žeçr°ŽÓ Ãñ4~QLƒŸ«`}ÀÔt+%ZUÅúÇcý#ìêbþ-·ÐtÆ‹SоԹDwU#‘Wq =XCÝÞ)+£cþ|Ò½½l_¼˜•÷ÜCÛ¼yT´µal{àsçù,yc7g9 Kr·á„b¾÷½ï}ONƒðg[ò<¶¾ð/ÿÿÁâo›­O?M¼¾žšSN9¦È‚À¨mÅb4œví—\‚©¨`ßúõZ»–]/¾Hb÷nš/ºhðh*-EUW£«ª‚Û¥¥èŠ TI ª¬ŒÈ™“9¼}]ÛwáøÐ“0$“ Ói&}í+Äê)kjbÜ•WR=y2‡¶mcÿúõlzðAö-YÂÑ;=wî€;öÞ}î9*R[ð}Cï‘^Z£}åûhßC…·‹¿Î~çã—(Ü:›Øh@µQu4Ê•£‡Ge½µq!¯ª™t©ê š¥Tá&›†Û*3U-Þç+*»2¾sW|vVÄ~ P ;gô9çP?m½ûöñÞOеc¯žÁs¬°HÞct ›SÎ×þzÔÐ?°m›êqã¨hiaû+¯°í…¨4 +ë÷½wÞµ†O|ò÷Ü}Ï;tw§‰Ç ííò¦X‚0ò¨°:P7m•mmì_¹’Í?ÎÞåË}î¹Xñ8j*C´²’æsÎaì•WâÛ_{‹±õÁ‰TTohÀdל²,Ty9º®.W••Ъ¬ÄoÅÞ×Þ¢{Ï\ß'•V$ ]‡q_úktôϬ«¡³­*èè|qw¼µå ÃD½½‹ÉÛIãÄvbUUC>/vi)µ“&Q:j~û[’‡«®.ø¿ü÷o½ÁæmGÁÀ’7vñôÓ[xö™-ÌÛB,f¤¢%"°áƒÑùÊ+DJK³©åǬP”–RÑÚJ˼yŒ¿æ|¥ØúÜs¼s×]x©gž9h‘6†x]—^JÓ¹ç’H&ÙñÆlúõ¯Ùþ»ß¡|ŸÊI“0Tò×¢"‘ uXW‡ªªÂjiâȶíìyq ½òÁw}R)ОKOº— ŸgÍ/É{¿ÿ=ëœ-/¼@Ëyç1ó«_¥~Ö,Î:‹¦3Ϥ´¾°ó~ ozöwT%6ᥠ=‡#xi ö½ÉêûîãÀêÕÔM™B¬¦fððS‚¤üÇÿàóvâ˜b‘Ç-Á¢¦¯ aÑ8—]1¿üïç±îÑGY~ûí”55QÙÑ1¤×k†²ÆFj&NÄs¢hc¸÷À2™ [no.ÝÃÂç¶1mZ-íí#ñ‚ K¡²½æ³ÏæèÎìxùeVßsÛ^z‰Ê1c(ih8¦)8ûËÓ²(=šñW_MëE±ûà­›ofÝPÑÚJyk+zÊǩ›:•éó7Djk9²w/‹±â¦›°l+§tô肟qS)’‡Ó»w/׬aýC±úÞûØ´p!]]Ý$}H;à*›’†*Æ%^? _kt<Ž)+ÃD"$¢ñôÓ©3&hq#1ýå{¤ó©‡[Õ…ÓgÑ{8ŠŸ&¯JååZƒß—ûÚ/ÕØ .åmšD|25‡ãÌkž_ØK¶¼Æû§‚CÞã{˜ðºŸÐÒªÀç¤PTÙÇøÎUXû*˜sýŒàù‰F©3†iŸÿ<•cÇòÞï~Ç+ßý.žã¯­¥tÔྨGÞJñvâh®E¨‹DV¾¨ÑTÚQ8çœéU\û¹&\y%3g²ä_ÿ• ¿û&¥fâÄ! ¾L5VU•õÞûð&6oï.Xy­Õž^‡_ür-=´ž¦ÆRZZʉF|€‚,A86±êj:æÏ§fʺvíbçâÅl~òIv-[Fë¹ç©šÙ·¬¹™öK.¡ê”Sصd «n¿ž;¨6XuõþÆY³hŸ??0¯[Ç–'ž`Ï¢EX¶ŒÑóç£-‹=Ë—³ãõ×ÙôôÓ¼ûë_óÎ}÷±ù¹çØ÷öÛ$zzp€4àG£”ŽCígP=cugžIÓœ94ž}6-çŸÏØË/gÜå—SÑÖ†‹·=ºcùJzW¼È˜ªnR}6=G"øiz«òªUy•#íû(/¬ …÷ûe»Ñ£¼Í¢¯d*•‡K8¯ixü=on{•Ç⇹¡Ú/|ì¬ùž<¡sU#å+ªìeü¶•4èFfæ´~¢¤~êTÚ.¼ÒQ£xëG?bËÓOÓ»om\p|µ<ÉÛ½]¡¸Ê¯RåµåÃ"SÁ*aö”2\´ŽKÕUD++Ùºh}{÷RÖÔô²¯îýÍf6oï£ú‰«|Á·ÿ@>´žwß=€çúLŸ^' ‚ Køsàè¶m,üú×yá›ßdãÒ0cÑòrL$rü·mS7i“?õ)êfÌ`ײeì~ã VÞu}‡SÑÚJ¼nð_&V–ïºl{é%¶<û,ë|¯¼Â¦º>6nX(*x*la0Ï£Æ`i×§úè>Æw®d|4ÅŒk/8îó­¨`Ü‚4y&‡6nä­[náÀêÕD+*¨;¶ÀõÈšowõå*Dú®ŽQÅò“;GâÀ:?Úo=Ú²°âñ$®î}l ›wtU°ò*Y­à¶ãùüþÉÍìÙÝËuŸ”ˆ‚ðÇ A£Â Ç÷<úÄé룴¡þBŘø‰OÐ2o{Œe·ÝÆÃûÓ¾ð¦ÜpmmƒþeÌüÊWh¿è"Vþä'¼û«_ñâ7¾Áòÿ˜‹øCgÍÒ®Ú)S˜ýío3ù†XòOÿĪ»îbç+¯pÚ׿ÎèóΣ´±ñøBË:.¹„ÑçžKß¾}8½½Äjj°JKÑ–…‰DPZS3aí\@âÐ!”1ÛÆD"Ã6“ÎÂ!î'°S)ìT’H:‰ç€c\´qqÃkc\œ0X43„Úd¾v nÚ¦Äí£Ôë#ªlÖXžÒšúSO¥k×.6-ZDjÿ~Ó®#’Jâ‡0×5ËÃqƒµiËÃ5ÁüDW óÁ:]|WAšlÐh)¤{{­ìŒ>çê&OfÇë¯óÊw¿Ë3_ú5“&qùOJé¨Qè‰A6¶>3¢'æ öÃñ8—ìpj/H¥7&µFÈ`n4Øá€Ìãë¼yžVÝÂùŽ™q>*L™A*XÂG §·—×o¾™—¿ýmzv¾~PQ’Á.)¡qæL&^s ©înVß?+XUmmƒþòTJQR_ÏØË.cô¹ç’8z”Ýo¾ÉÊ;ïäè¶mØååT7è:´eQR_ϸ«®¢ùœsس|9+n½•MO=…¶m¢UUƒz´Lø}ñúzìР®-« ¥”Â.)ɶ‰T&ls8ð‡7ñ—?E½Náõhzä*Xùq Ù–\~Ë0[IòðËÕ-]”µÅ9\3“HO-u1ÍøRð‡¾Ý»I>L´²rÐj£]RBé§rÚßþ-móçónt[;ëñ=²Fû‚l®‚Û…¨Æu±Ò.eÉ£Œë\EÅÛK8ðö âõõT´¶IÔWO˜ÀäOšhU»Þ|“×nº‰tw7íí-sçr`ö<û,Ûž{Žƒï½GÓYgaÇヶ۴1TvtÐ>>M³g“:z”ÞÝ»ñ}mÛ”Ô×ÿÉ>‡–-eOQæ¹Pô-j払¬±/LÈ3šW@mÛJÛË8Ts&V_=µQ͸Ø»l«n¿U·Þʦ_ÿšt*EÝô郷S¡¬¹™¥ûW±å½ðTžÀ"/U¾°m˜'a\“v)Mu3vûÛÔoYM碅l{þyzöï§~úô@ò[Ñ(M³fÑvá…D++Yy×]lzòI^Œ´²­ª%'P8VLÃ@zƒ˜†Ù“£,˜öç÷Þ';Ù¼«gÀ˜†BAH¿õMTÃu1N>¬A–ðaâ¦RÙ´‰}«WS:jÔ ¡œ¦ŸŸuÓn¼‘}kײæ¿`Ùm·¯­R%*#nJ™põÕŒ½ürö®ZÅ’ïŸ]o¼Aic#å­­ƒ -+£jìX¦ÿå_R;e {ßy‡ÍO>ɪ;ïÄu*Z[‡´[Ð.-¥zâDÆ}üã´^x!5§œByKËŸôóÖ½üU’‹Ÿ!šð±“>©. å"*—Ü^|ñ³1 *FZåÓØ~€’Ö UŸI7Pg:J‚]˜ 3g’ìéaë¢E¼wÿýì|þy"ååTžrÊ ÏÏ3¯n`ÿž ÕV~ê¡ñ0E‘ù7ã¸Xi‡Òt7»×0½&Æä?ǵkyïá‡ùÃ~DE{;ñº:¢CØU¯©¡uÞ<¦\=ß{—btÖuz›tQ°¨.®…¢ÆWÐ…®õ1Ãü³¢”– o«ðÞ§:Ù¼§w€˜†® nkª+l.9¿™ÊŠ÷_Yóç}ex ‚,A8¾ë²kéR^½é&¶¿öéÞ^¦OÒÏÚ¥¥Œ½ì2gÍ¢{Ï–Ü|3V¯ÆŠÇ©lz–-¦ç…g±`%}Ü^Ae(ß0ž1¼ÏÉ„‘šJŸæŽ}D[«Ù_sÊi¢ÖÚJrÏqÓÙgÓxÎ9¸¾Ï¦ßýŽM<@ßÞ½Ä[Z(;N{øÅ%osð€áˆ­¤…q™5‘»ÖÆñ‚ –ÛCûžuLŽ{\ð/ÿBËyçaWT°ïí·YÿàƒìýÃPÑè_³‘òr:.¾˜…þ(V÷è¼ ÇŸA˜_ÑÊ´»¢lZé°`v„޶áÍ º÷é¡À ¦¡¸j¥ oïÞy˜YÓ«™6µá}?®“Hðî°ë­·¨wA ‚,Aøhc¨;–¶ .`×’%¬üéOÙðøã”44P>zô‚=«ÆŽeÂUWÑvÁl{ùeVÜy'[. Òµ«« öÌ›ºiÓÏLe%›ž~š¥ÿþï$¢¢­ø`;xm-£Ï9‡iŸÿ<ñ†¢••X¶M׎ÔMž|Òüeîöõ±ó‘‡èY²«TØ)åö÷^e[p^~4‚ŸL°ª=ÚÆì$ÒRËþÚóðýfFy†æ¼è&e å--´_r ÍsçÒ}ð [ŸzŠõwßMßÁƒTtt­ª*8¿‡v~Ÿ7WìáÈáRðÈ‹hÈU¸ÎlËq(ñúhÙÿ“Tc¯ú8¥£FÑ~ÁLþÌg8ºk»–.eýƒ²eÑ"Ê[Z(mlô5ûÚ[†ÿ|º*½Â]yZ <6'Ó óVoz¢Ø‡ú¸ñŠ8íö°=¿Üõw>¶•d,ò>*X¹ï1ÊçšËÛ™6åý·¸eQÑÚÊž+X|ÓMtïÚEEKËûšµ("°„“7¦wÏžlÄÁPPZ¯©aüUWQ7y2Ö¬áû7ŽnÛ´ëŠRËZ¶MÕØ±L¼æ¢••ìxí5VüøÇÙ²…†ÓNÜ$M` 7‘MgžÉ˜Ë.C[oßsï=ñÚj&L´º”Ù®ßz¼ª'N¤áÔS?U©ÁHwwsäÝwÙúÈìûþ?M€íÙX:FÌŠ Ó)”çæ<ó«Yycs²ÙX¾UíÒ:a?Öèzö×ÌÅÕ-48£ÊŽ!¦ÇcÌå—SÚÒÂÑ]»Øü›ß°sáBzwì eþüì÷öu-dÙÊG—kÀ/ò[yyÁ§9±•¹mãxÄHÐrh§Ð͘«®Î ¾Xu5ã>ö1êO=•î={غhëy„®;©7î¸þ¹ Û}èLÓ[å÷Oph¸sñÈôF¡×&º¯‹¯(¡½cø^_ËÞØÎoW!ô¯`é«V9‘¥1x\sYÓ&×ã&“$R%8S¥³âqšÏ<“¦Y³Øú ¬¾ÿ~Ò‰µ“& *^A–pÒ¢”ÂK§ùí·²îÑG)©­%^S3¤*@õرŒ¹ôRF͘Áê_ü‚5¿ü%]Û·S?mvIÉ U ‰Ð4kã?þq|¥x÷׿æÝ_ýоƒ©™8‘HyùÖ«ª¢eÎÆ,X@ïÞ½¬ºçÞ}à:æÏÇ#†R‹ !ÔôO™ä‘#ì{ûmv¼öë|5?û›~õkèN))§rÒJZÛ‰77£A÷õ…B«x°³W•:‘‡Æ–DZ8P7‡”ÝF«¨/õP ü\[ñ8õ3f0öŠ+ˆÔ׳ó7è|æ6?ðVi)eíí¤¼¥¬\ÖÃÑÃ¥(ÏüVEƒ¦3íËì.Çl ª•v1ŽKL¥h:²I~W^]øZ³mj&Ndì‚4ÏžMª»ßuIwu¡´>ænÃ÷vû<¼Ë¥¯Â/ôX1°i¼`a8Ƈž(*aÛuˆÏ]QFÛ˜á ö\±|7¿û(é’Lëâªxa¸n£<>qi+SÆW³kéRÖ>ô«î¹'Ö­ªÂŠm­%õõ´_pÍgÅÛ÷Þ˪»ïfÔé§)-ýH¿§A–ð–]RÂèsÎßgÅw°cÉ’ å×Ô4ø.¿ð/ØÚÉ“™|Ýu˜h”µ>ȲÿmYTvt š7•©"µ_x!㯺ŠÞƒyçç?çŸÿœ’º:Êš›‡æ­2†Ò†Æ.X@ëܹT¶·spÝ:ì²2Jêë‡ÊùQ¦«³“ÎW_eÅw²á·¿åàºu¸‰D"Ä;:¨=›ŠéÓ‰¶´ ++Qñ8Êu1É*™~r&¥tÂÔ1*†J)âuu´Ì›GÃÌ™¤R)¶=ó ‘Ñ»9Ä)tŠgT ¬B#>9ó}NlåÖfãºD,—†žLrÓzùÕ(­Žû:‰”•­¨8nÅvýxxG²¤¨‚5 Ù}€¤w4ôDPIClÇA>û±ÊaXËWíåÉ5]81{€˜ŽÓV°p¹æâÑL;%%UR[Kû…É—^bÕOÊÞ•+©™8‘’ºº¡½µ¦zÜ8ÚÎ?7‘àõü€ƒë×S?eJðןÁ;‚,á$Ã÷<:/fÙm·±óÍ7ƒùjÍÍCþ@³KKuúéLýìgÙýÖ[,¾é&´e y{;@ICí]Ä)×^Ë£ö*‰ IDAT¡õëyã_þ…ÍÏ=GI}=ÕãÆ ž7eYTut0å3Ÿ¡fÒ$ö®^Íkßÿ>}{÷ÆäQ£†|>¬XlØÒÐÿ”H<Èî_äÕë¯gÅW¿Êæ[oe÷êÕ¬yüq6¿ð‡·n¥¢µ•ÖyóèX°€¶ h¹øbjÎ8ƒø)§`77£kkQUU¨ÊJte%º¬ £}èdí8ý¢*;<ìú8ºº†tÓºK'KÆØ÷äoØÿäìúÍoØy÷ÝÔ_r Ñãå>×ëÃCû|Òq=VüA~K¬”¦dû>» ’Ö1¥ÃöZXþÎ~~¿¦'n¿Ï˜–òøÄ…£™:±®àù©hmeú7ÒxÆl~æï{ôíÛGiSe£F -î´”Q§Æ”Ï|†½«VñÒ·¿ ;‡úy""°„? ´eQ=~h™3‡¦³Îbëóϳêž{°b1êÞGœB¬ºšŽùóuÚil_¼˜?Üz+={÷RÕÑAÉ/+­©›<™1—\’m“êꢬ© +1óçJº§‡¾عj¶lÁíëÃ]·÷nj;:˜ø7Ãø«®bÜå—ÓrÞyÔM›F娱Äjj0±XP¹ª®Ú„aKÅãÁu,ŒœI&V^„CÕ¹ øž‹©«Ãk@WÙ"É8}ëV±÷õWq}ŸtW‡_y…îU«u啃þ_ª'NäÐÎ$+·’ìµ³3 ½`„,/ì€VµŒã¡=—¨q¨Mî£mÛzjfžOÃY“þès½ö<¼œ(ý[‚ Tµ*ªn…³UJQ²m?×_öþ–ç8X»6;¯°˜e«÷óûw»qcÖŠi08|âüÑL0ð óª±c{é¥TŽÃ;÷ÝǺps@ÇÅý—mÓzÞy´œ{.[^x·ï»ßui8õTùÐD` žãpè½÷8²ukàc)ÚTÝŒé{ҵײù…XüÝ﫬$^[;dã¸ÒšÒ†ZçÍ£aÆ ÞùùÏy÷Á‰”•Q5fÌޱmª'L`Òu×1ê´ÓXó‹_°ô–[Huwg·sVÑŠ”•Q7y2 3fP7yrºnÌIû|å¼Ú%%”··Ózé¥ÄÛÚØ¿u+ÝG¢’IÔ®]¤^z‰±×_Oyk+%Í͘h´ð<+…²,Ty9º¾S[‹®¨*ZAE«´­TPÑJ§ÑžKÅß_CrÅ&¬¦FÔ¸Iô”NÂvJ8å‚94ž:#rdϺwîäð²elýÑPžGÍœ9Çýí_»ŒÝïl ÑcÄB¨ã„‹f½ažå8×#jªƒ´w®§fæÔùÇ ¬w»T¸vÆÃÄÀ£g—£Ãa"‚r%[÷ñÙK«Þ—ÀRZûÿÙ{ïè(Ï;íÿó”é}Fz¢K¢#z1“MöÍ»›ly÷·}ßýåäìÙÍɾù%^;Nâž8±cÇànÀ€ ›":H Šzïš>ó<¿?fTÀ€Fq²¯ƒõ=GG#$Ýšû)×}}¯ûºìvFÚÛÙ÷/ÿ‚Þb!<22Ö®;QÕÇ»Gˆê51€õæJ¼ºMƒ3•…(w¯Jevëº× §´”YßøaŸ‹;wrü¿@6°ff&¼x3¹Ýd¯]‹§¤„S[¶pæ¹ç0¸\±ÌÇ`çîtM¬éú#*A û|´;Æé§žÂÛÙIòìÙ íòDY¯iš,àâŽTmߎª(SZ9Š’„)%…‚ÛoG’eNþú×ôTVbLJJ8WPÒjq͘ÁŒ»ïÆàtrqÇÚŽ3ýLô½Dñ†«‡}>Fš›é:vŒKo¼AÓ›o ‡±^ÿý4f3žÅ‹IYºŒFú[Zðõ÷ …hߺïéÓDzz°/[v­ƒ h41Påp Úí1FËbAe¶ôz„p1D³f.¡3õÈÙ™HÅÅxM…È#z£—¬¹edm܈.-îúzFz{‰øýtíßÞíÆµxñ5ÿ–ÞÊ :ÎÕĬÑÖßÔ«eNÜ](…£ˆŠ‚NŽ`WÈj©ÆQ¶×™Ÿ{~*ý*¯õFˆÊâ8X¹æN«Dè B@Fˆ˜ºøæF™9Sk ’„ÞnÇ’’BË|ø½ï1ÜÒ‚5;›ª‰w/zã ‰í œ¶d¢Ü½âúkì|3™È^»–ÌU«ðvvrìá‡é:u Ùkÿ'°8% £ÛMþ-· 18½e 'N`IOŸRûº¦k`M×ç.ÍFòœ9Øóóizÿ}N=ý4:› ³Ç“ЪOŘñãÚµ˜RS9ýôÓÔíÚ…ÉíN8îfô8®™3ÉÛ´ _?L]Îââ«” ó’º`·ßŽ«¸8&4¶Xuº–•šô#Š„.¼ú*ç_x–}ûh}ç:>úCZ¦¸¥Âu™ÔTÒV¬ }íZ¼ÃÃôwtôûñÖ×ÓÿÑG aÊÍEs-HA@ÐëcË錵Íf³9Æl™LhJ Q ZBg/¡ÉËA[\ˆßœ¬˜´ýE:‹•” ÈÚ¸L&:ª« †Bt~𠯼‚kÁd“é3ŽßýçÒuö"A¯sŒ¿ŠEÃev £¯ã LŠD‘”ƒeeˆÌ¶Ze«p.˜õ¹çç¢7Â;=~QE‘dTQüìNAá» G5X! bŒ Ü>ÓK¤æS‚ƒƒ (H:]B×  X²²p—”à(( fçN*Ÿ{ŽÃç»8íšKT+%fÓpEV¡L”›gˆyôhL‰?SJ 9ëÖ‘µv-õ»wS¹mu»w“µb£1¡¿GÒjIž=›Üõ뱤§ãëêB”å„⪦kº¦Öt}¦"~?-‡3ÜÒ‚Éã™ôÁ9ܘRRÈÝ´ KZ'ýkš@c2Åvè%ÀêH:Ž‚Š¿þuB##T<òHŒ‰r¹0¥¦&Ì iŒFRæÏ'sÕ*οôç_xow7I³f%ä™3ºeßš•…£ ­Ùü¥W£ï‡Îj%{ýzro» Ka!’ÅB÷Ñ£\xôQ¢¡ú¤$Œ“°…’Fƒ9=ì›o&yÑ"úÛÛêí%àóÑwà-¿þ5«­ÃÖåºÚC0NĤ¤³Xº;V௨"x¶mQ>ú™ù„ìùHª D¯êˆ ª 55!ètè’“ékm%‰`JIa ²’¡ÎN´ ÆQ¶Bé`ðävºÏöôÉHjAçrá*)!eÙ2ÒV­"yÎdƒCRRìwûÎ0ôÉ#ôT ú4cf¢âDqûÄœD>ËdI‘ØÒÉŒšu8JV`/ó¹ç³nÄÏÞ®AÔˆËp„8€¯ãìθÈ=,ÇVm;_]édÑ]åd­\‰%5•ª_¤vçN†pÍ™ƒ6ÁÝu²Á@JYõš4ö4GQ´b6 Ÿ5Õ¾u×ýÉOhxï=Ì))Sb´d½G~>36o&80ÀÁü€¡æf,iièÈáÆ"bòo¹…ú={8òÀ(á0¶ìì„Zc$·ÜBéßü £1Ö¤„[ 7b¶9ü}}Ô¼ý65/¿Ì©Ÿþ”á–ì¹¹0=•´Z¬99dl܈Æé¤õØ1Zvì ~ûv$­K~þ¤l¡ÎjŽ`ùwßœ”Ä`o/ƒÝÝø::üôSî½cNÖ’’k.ÑfCµÙè>|œú÷? ,kpÎB;«ÁŽ(éÑ ºæª^{‹ˆ¢Äl²³)ÿÁbNýwÜAæÚµ¸ËÊ0geaHN{èª}—zïZŒ„|2’¢\‘E¨\;31þZ G‘Ô(z)Œ^"£»Çürl%s?÷|Öøø°«7F¶¤¸Ó|ÌLÔÈ’b‚ñ«æ"BTBPÌÕìÛÖÃ?üCìó,\Hñ7¾*\|åŽÝ{/ŽÂB4f3ºòüQäD[˜]õ>­t…È«Ø4ð™1ÊDøö=e|íûÿˆ1%…æƒùèßþh0³y¹†ÃýgÎ7›ô¥KYôOÿ„53½ÝNÄïGc4N اk`M×ïV ûö¡5™Þá7ZŽü|òo¾A9òàƒ4}ø!EwÞ9%6K”eRJKI[´ˆžÊJ*et嘠¶Jk±»q#Ž¢"jßz‹s[·¢³Zq%¼ò q6y<_jp5ñÁgËÍ%{Ý:Œ™™ôÖ×Óºw/íâml$sãÆÄ.ZÙlFãtÒSWÇ`]m»v1xæ ¦´4ÌÙٓΑÆl&eáBRW¬ ¬(ô66ôùP€þ?Ä[U…eÖ,´WXg¨Ñ(ÞövºOž¤nûvj_žÞ^$§“ä²rsÑ$'ƒl@BB–eì3f‘»q#«WãY¼ƒÓ‰=7cRRL§w•±FÚZè{Þ=AŸŒˆg±Ô1Ëñ ƒÑ‰6¢ª"E£ˆŠŠNޠׇI﹄c~9ÖùŸßàÒˆ—]ݨª@8 !D'XFÄÍNc×g]!|W…ÀŠ(˜«Û0öGøûȹœ ^¼˜ô+d™ƒÿñt>ÌH{;«VM:¾c^vÕûQµâø.Gñz1>—· e"l^œÄÜ‚uŠºßþ–Þ3gb[Üg̸nÛpô†ädR–.ÅS^:íLÕ3ÏÀ“ƒÁåšt~Íééd¬[‡1+‹P$ÂPg'þ¾>Μ¡ýôi¢À…ßþ–Þ‹ aIO'}Õ*<+V¾z5k×b.(@›”Œ¨3 B\“$ün6Ÿþ+ÁãÍŒ j äËÚ¨È}L{¥Œi°& à¥H,ÞG¯ cІðŒ4㜷ÃÜESŠ¿§‡ ¯¾JÍΜٲ…¶Š\L^FƒÚŠ¢ˆ„†5±Ö ±ŒêØ×ãâû‹²X"BDÁRÕ‚¹ÛÏÿóW·à% sj*ù·ßŽ%'‡¾êjNÿâ 74àš=ûªíÿ£-~v]  j„+l®±sð ›ÆjåÛw.E§ÕŒoƒ‚Ûn#gãF\3f 5›Ñ˜LÓkº¦k`ýnÕWSCÝ®] 57£1™¦ç ëõ¸Š‹±¤§S¿kí­±ÖÈnHæÔT²V­"iÖ,ª^y…“O>IRq1z‡#¡=£7GG~>Ésçáƒï}ÆF\ÅÅè,–„Á’1) ½ÃqÃ+UUQB!">aŸA’&Õ¾i-RJJȽåоö5tv;_z‰ªgŸÅšÎnŸPîÍZ½šô•+éë£õÀšÞ~›îcÇpÌž{¿'‹ ˜RSI-/ǽt)a¯—†×^£ñå—‰D"ØFÁý$Bx__} ´µaHOÇ^T„99½ÓIÎM7áY¸ÜM›È½ùfr7m"¥¬ [Nz— íh~ßïC¼¼÷ ÂÚñéù¤xüMlÇà8pQ.sv¿¬e¨ÄZ„ z9ŒAÆlÃ9w ú9‹§ ¦M-‡ѸgGŽS»êo˜›P¢"ÁAíe­É‰Øc¢{”1 … ‚$"¨ …¢X.´`iäoþiÖ¤ãHš=›Ü[oÅ”–FÍk¯qaëVzÏŸ').„²GÚìj €†Ë¨¯iÓpy«PC˜d¥ïܾ­ö³÷½Ã-}#‚+UUQ£Ñ/õ"rº¦ÖK\.lÙÙ\|õU*5Á”šš°¾j”Eò”• …h9x_OF·;a&JÔh°dd0ãî»Ñ;yðA:Nœ@o·cMPpŠ `LJÂ=w.j4J_u5§NaËÎFïp$,¦¿K ‡ikãÄãsúÉ'é={?Ö¬¬ë¶vGô-éédÄ™œ°×ˉŸÿœº7Þ@ ‡q—–Nz£–´Zl99̸çÌ99x{{ix÷]Îýò—‚€ÿ 'ÙÙdnØ€}Ö,†[Z¨~öYšß}—χ{áÂk‚5A°çå‘RZŠ!5WI i«V‘¶z5îÒR¤ÌŸ?–- H͵w~žùxéçD[{ð i ûE$åj9„W‚šqp%ª R4ösz9ŒQÂéÂ1g1ºY ôõámog ¡I§».H% ÍFΆ $—–Eh˜»Š¨¾HH"0 1V£ãB½,'q\3¦\æÕ%‡"hü!ŒµíØ:ùÆ×&Ïö5öô,\HÁw¢Š"5;vpô¾û0Øí=tv;GÚCìn €F¸ŽMÃU"tâßÓ¨aÜj;ß¾uÉUÖèýäFݬF"úûé:{Åò¶éš®i€u½Õ‰¢Liu"ëõd®Xs?GB˜SS±åäL ˜˜RRp ò¥—Ð;œÎ)ÅUTDöúõ(á0‡~ücqÏŸ¬×'æ}¥ÑQ^NÖš5¤/Y‚ÞáHØôF­Ñ‡¨Öje ®Ž³[¶péÝwi:xÏ‚è]®„Þ£ÛMZy9kÖÐuâç·l¡÷Ì,ÙÙ˜<žI!ˆ"îyóÈ^¿SV½55\zë-ÚöíÃÛÝMZyyB¶’V‹-?ÛÌ™h““i>xÚ;h?rÙbÁQPpͱè¬V< 4köü|Œ©©h­ÖX^áÇ9Ò ÿ³O£ö{ z5„ýÒ˜À}TÐ>Î`¿Žµåˆya)j ”¡b#4aj/ö™ hï¦æµ×¨|î9*Ÿx‚®×_§sûvYÆRT„p á¶ Š8 H]µš×½C”zB>-ÝxÛR%Þ"œ ¼XÛ†Š‚Š ûÃè.uc=ß@òžÿ@Ÿ”„-77!ñ¸Öj%½¼œ´eË@’8þè£4¿÷QÉÄóo·PåI·h˜ªMÜJß¾e ÚYò©IBÖëQ"úª«iØ»OYÙ´µÄtM¬Éj¤­ŽãÇ ¢* ºDsøâñ0…wܧ¬ŒŠÇãâÎÈClw]¢s&¦aY¶Œ†½{éçë) ¾Ï…-[hعcz:挌InA0§§“wë­¤¯ZE}='ý,GL hž9d®‘Ex}›­Æ­¶ñçÿÁÖLJ†ÈÊÒý·ÝÂ>_ƒQ@­w8°åä`òxPÂaü==èl¶iä0]ÓëZ¥³Z±çæ2ÜÒBÇñã 56âœ@0{<Üz+²ÑÈéßü†¶#Gp`HÐojôN™?“ÛMwe%Íâš1cJ» eƒ¬U«H))a¨©‰‘Ž4&Ó”Æq#V4¢á½÷8ýä“\xùe÷íCïtbÍÎNèÿ[33ɹé&’æÍ£¯¦†ú·Þ¢åÃñ÷÷“RV–X‘$Ål6lÀ’“ÃÅ—^¢æ·¿¥çÌòn¿=aœ^^Nêò娒DÃ{ïÑôî» ÔÔ ±X°Lz ƒËEÞÍ7“ºliË—“ºlî²2DYFÒj¿pmžàá ¿³5  „ ”â€%®e"n.ª2&h¿jlN4ö³Mƒ&„Y;‚æb;†U·bŸ5‹ü;î kÝ:ÒV¯Æïó1ØÞŽ¿»›þ>uŠÔ;ï¼ú¹¥ª¼ß\9܈oP×`M ã"|UEPãÇ71Î`iÕBË Îºvþõ7ÿ‹P(DËÇS¿cCuuÓÓ±dd$|Îf­[‡)·ˆw.†h)ž’z…Mõr/oj“måÏ7,úƒ¬?ùÓj¦°PÛý‡eÉTU¥÷ÂN?õýuuxJK§üÌ ýýtœ<‰955a‹ŠéšXÔåïëCL@”|eYÒÒp͘rþÅQeJ9|’VKRq1…·ßŽ¿§‡Cÿõ_ Ö×cÉȈ “|pé¬V\3fà*.æìÖ­xÛÛÑZ, 3k§.Z4&~ÿ²‹3EI‘Ÿ-/öãÇé9s†óÏ>Kß… Xsr0&`ì) $ÍœIñ׿Ž-?Ÿ¶#Gh|çοð‹sz:Úv…j­VÜ¥¥Þs—ví¢â¾û@’p O® ’„%=ì H_³†Îª*Z vÇÎmÝŠl2Å@õuv ’„19SJJ¬%l2!ét_8p¥´70²óU†?>êW‘"*j$E½ÂhTÓ8‚/iTì®ÄŒ¤DUƒ ‡1|hÎ_¸ùÏœNAˆîÜ\²6mÂQR‚Ï륻²’îÇixä„H­Ãn먨*‡šÏb 7ãëÓǬèeº0‰økE¿žÈ¾Åü¹ä` ÚêÅUÝÆ¿<ñçäßy'É 0ÔÞNËPûüó 55aÏϵ©8ge{2/í¯£¥¸ð* Wi rÅ÷D4„HQZù³u8€õÈìÿ`­[»ùäÐ0Y™:ÒÒ´ˆâïÿœDcRöÜ\êwí¢â‘GbŒuFFBQ^£l¡ÞáÀ’–Fï… tTT D" ÇÿL×4Àú£¬‘¶6újjè:}zÊL”(I˜Ün’fÍ¢íða:OŸFc0`¼Â`ñ:W’N73ÓúÉ'œ}þy†[ZH))™’Âèq}}tœ8AoU΢¢Ä³ !Öò¹Á•âëêb¤µ5§’À¼ˆ²Œ95•›7Sð•¯`ËÊ¢õàANý⌴¶âY¸pò›«  x, kíZd‹…ö#G¸¸m}••z=I³f%4¿“‰´òrÒÊË Œpæ—¿¤çÌL©© 1k¢,£w:]¶. IDATq PE÷œ9¨‘#8òóÇEç“üM_Ô 76ÑõÂ+ U_B «¢ ™®>“£ªcº'q¢ <.v7hb-B“Þ‡¾ÏТ]»îòkX¯ÇQ\Ljy9Ƭ,¼CCôÖÔн?]o¿M¨£[I ²ÉDTU8Ütc¤o·‘À`¼E8AsÓ`]nŒ*LÐ`2Xm`{×…þìÿ]‰(Ë¸Š‹É½ùfŒééôÖÖÒ¼gý§OÆ]Z:éÐ;äç¥/ÑZT²úY›†Ë2¹ªMƒv`­Y„Vó‡ajžx¶‹î¾¡ÔÔxæ7Ý8ìË–N¾°TÂaüýýˆ²<¥ìV½ÝNΆ ˜=ª_{Ú7ßDk±`ÏÍMx±!Ê2fSJ -ŒÎf›nN×ÕϹÅh484DoUÍ’wóÍ8 ‘§è¬* ÞÎNZ"ì÷SpË-è§(@†B ·¶räç?§¿¦†eÿöoxÊʦ|††‡ñõö2ÒÚJúòå_ê¿Øä¨tž<ÉÙ瞣óØ1,™™¬þÉO°¤§'dì9 Òü}}TnÝʹgžAÔh˜ýÁ¬o~31ÐFÌtµïÂŽ<ðg’´`›~õ+Ìéé ¯†Ã^/ÝgÎpôÞ{¨®ÆšŸÏºÇGg·Oê[àïí%4y[f&žÅ‹±\W¯ÙÕÜËí?ØÏ±›6€!f4:ÑXT½†ñè臂)2Ä\ÿ§ìý÷¿Áløýï ë³ü¶Jjj¨‘&ªbЊädêxüÑ\æÎ1‘”ôYpñû©ß³‡®“'é¡( UÃxÔfþç²²?ÀúðÓ>>åQDâ@kšš‚ìÞ3ÀÁC¸œ —Ýì99äÝ|396àY¼˜Ú7ÞàÂöíx;:bÆ« úJZ-)ee¤/[Æ@}=ŸüøÇ¨Ñ(I3gNiסÞnGïpâüK/aŽë§ëKÌ |‘[„¿Ÿ³[·bNM%¥¤$qCÍ 5xé5o¾IÒìÙ¤””$Ô~¹Z]Ú¿ŸúzRJJH]¸ðwÒ±´ÆÃZ³V­úÇq£T$àÜóÏÓ¸?õ#ÑãaÅHî¦M‰ë߀ު*>ùñiÜ»ÑÈM¿ú©K—¢·Û§öZâÔ/~Aã¾}Þssÿò/I]”x¤Jpp³Ï>ËùgŸ¥çÔ)4N'·<ó iK—&Äh–¯§­Ù|CFƒA{zè={–ž'Þ¶ ]k+FÀ èê¤$ä… 1,[†£ G^§žy†Ö£G‘‚åË™¹r%¦H¥¹™h}=Ѧ&¢—.mo'êÄñ’ü~\ŠBÆüÖœòo½•ì5kÈZ¿Wi)ö²2$»=Æ`éõf3¢Ñˆ ‹™|Š~b8·pˆ»¹_Æ`…1BÈDiñ”ÒÕÕG8½l,Q ´gÑЭ[‡xÅù#Ê2¶¢"šg/ïûCƒ ¶Y k.°ŒŽ3jŒg(BÌ+îƒe²ûèë1k!§8ƒÕwî·Þ;ä…Šv:òr¯/r¿Žñ¨Žžh3ßZTòa°>86ÈÇg}pk%Œ~Ž¿â › ¼ùféiZV”[¯yOI)-%kíZŒII|òŸÿI˲Œ{þü„Ǧ³ÙÈݸKz:UÛ·SÿRR¦¼À7§¥&P÷Î;$Ï;8¦Öï·dQ–9ûü󇆴Ú)·=L))1(­–#>ˆ19Õ:¥>{n.žÒR¸¸cZ³Óu̯úð3™°ffâÈË㫯¢D"h-–iQc¼Ú+*¬¯Ç×Ý(Ë“çðÅ[=eeÜqE›7Óuò$§œ†ýû±egcÉȘ´*j48‹Š(ºûnì´:ÄÑŸüo{;†¤¤„C­eƒä¹s™õ­o!jµœî9Ž?ú(Ö¬,ŒnwBÀØèv“µz5óÿú¯1¥§cr»ÑšÍ„†‡1&'ß0Þ9J8LÈëE·3¯‚Ze{~~¬Mn0yÓM¸-" 144D "8êð0ÔÔþå/c.ç.æ9s°ffÆ6˜Íˆ.¢Û`·#Úl6âè‡N‡Æ€V$<æ–.¡ÄmBè­"’ÅHƃ/c*[Ì@o/ƒ½½øÃaÂñqD€POハë»ß½*?K÷kƒÃ 4[ËŸ1;•.³“ˆÆ5XÊe,m$„É飧KÂp¾ì¢ Vß9ësÏ͈7ÈÖS]tæeÇ4Xb¢6 ñ´IUšùÖ©¬ÐÈ#mmtUTÐrà¯UU/[~p|ˆCç}c¿WW\%L›0A#–Ÿg`ÝjpÍÅ’!)‰´eË(ܼ™úzÎ<õµo¼9- sZZB›bF³[óo» ÍÆ§÷ÝGó±ÜÍ)ÄŠiÍf´ ޼¼ëšúN×4ÀúJ$­OYþÞ^:Oœ ¿®{^Þ”|«DI˜”DFy9ÝgÏÒSUEhddJîç¢Fƒ#?{n.]gÏÒyò$Z³yÊ}rÑHÚ’%èl6}}±vÔô…Ãps3—öîåƒï~—ŽcÇИ͸fÌHlndcr2¹›6á*.¦íÐ!Ž?òÑ@sFÆä¢Óøy–^à÷¸p»åI¯AƒËEÞ­·b/( ¯ªŠŠ‡bðÒ%‰±Ûñû’#?Ÿ¼›o&<<ÌѤóäI2–/O¸?zO™WÓëZ–´4ìyyT<ö¦ääXÆÙŒì$ga!¦”iÜ¿?¶Ëo YzZ‹…¤âb´f3u»w3ÔØˆ1))vŒ)\²^g7è…£D"(ÑhÂ,x.$}ùr÷ï§ê…h¯¨ˆEM¤¦&œ“è,,$÷–[pΘÁé_ÿšsÏ?¤ÕbÍÎŽ±H“Gk6“¾t)…›7ñû9÷ì³\|å$½~ü Ü II¸æÌÁ×ÛKûñãÔ¾õ½••¤””  -$­ö†a­A`¤£ƒŠG¥êå—i}ï=úŽ¥ÿãé?tˆá£Gq®\‰d0 \åš% Q£Á˜žŽ{Ésç‚ÑH_k+þ@€¢Œ·ì îÚEdÏ´ååŽ)H‚шàr!:6‚É„hµÆÀ–É„ Iˆ?b(€F"‡AÊLCÈÍ‚ãçÖÝÞé$eñbRW®$ªÑ0ØÓƒÏë%P"¡ž;ïD¼BèÜ2Ôµó5"½AǬ+ž•ñjËwŠJŒÁÒ !ŒNÝ:´»ÉÍKcås>?Àò…Øz¶‡®œÌø.BÆÙ«‰; …+˜­ -CAR•&tý§))X0v?=&»þ¬YYd¬Z…*Iô^¸Àpu5-o¿ÞnÇ–Æ¡:ø¤Ê7ú&î$D˜ x¿âßQ2ë·1yvB×  8ŠŠÈÝ´ gq1µo¼AåsÏÑ[]Mòܹhã <‘îEJi)¾žz*+9õä“hM&¬ÓAÐÓõÅX£SJ ™åå4ç·m£¿¶Kzzâú¦¸+oÚ¢E„†‡iúøc">ß´-Â(ÕÚJó´tô(‘}ûÐΙƒ”™³SFƒZ‚É„h6£h4tÕÖÒÛÔD$E6[0ä#æç X,´}xŒS»ö4kÖ˜A«9+ Ùf#Ò×Ö†/d°¥…ÞêjäQ·oQ¤g°kÇN‚ ýÍÂ^y̱}Ô¦APââv®´‘ ®ÁR1jè]~ÚûLˆ5}äfy(ÿÊüÏ=¯#þÀHIFÑK¨’x•¶ x p_| Uib¦ÁÇ’ÂåÔ¾õGòß~›¶={èÞ»{I ·ûº÷ƒ±ëoÍ’JJèkn¦¿²’#.Üeq05 ¬&°Vq‹¸EÏØkUÄ(¨¬5ï¡i×;4¿ÿ>‚,ã,.N¨¢1™ð,X@Æêբȱ aÏlyy1Óâîm&·›ô¥Kq—”à**ŠENM1¦mº¦ÖKé¬VœEE¤””pô¡‡ðvvbp:§Äˆ’„Éã‰EÓèt4ìÙƒkæL˜P㌇ Š7,¸Š†B ëÞd½kf&sÿüÏ™ùÍoâíè öõ×¼t sZZŒ‰š f½¥/_ΜooWg·láü / ëõ8 ò™SJ y·ÜBÎM7ÑöÉ'|òÃ2x馔L))“Ι¤Óáœ1ƒ¹ßùZ§“®3g¨Ü¶š7ÞÀšÎbIH”/ß@7SQ–ÑX,ÔïÞMýž=4¿óýŸ~JÏ›oÒòöÛ±÷ì:¡¸¢$ap¹ÈÙ°‚¯~ŸßOoK ^¯—àÈà 4=ð¡K—pmØ€x ‡lAÑÚí$—•‘ºv-¦¼<ú;:" ‡€¨×‹ÿÅ í܉~ä‰lè¨>Ëé$,ËtÕ×Swà(‚€”œŒ­xvLÓ•AW]=z‚C÷ÞËÅ;h?v ?®™3ÉÞ°ˆ¢\VFúªU¤/[†Þn' aLNfpà޶W ´« ´˜‰ŒHãöÑÄ1cÑ«ä'ª1 –IçÃàòÒÚg†úAòÒÝ,ÿJéçž×˜—Îu2â´£jE¢3½–¹èe-ÂQ€ÕÌ,ƒŸòyb×ðw¾ƒ«¤Éb¡¿¶–s÷ß·¶A¯Ç6É.YI§ÃU\̼¿üKLÙÙ²sQÎß1(2Ƭ])x¿ìß‘ðú줬ý&w}+“öO?åâÖ­T½ò –ôt,™™“ßS£Û%3{Q-̹§Ÿf ¡kVVB›ŸQDÖë§ÁÕt}±ÖÄ›}Ú’%cñýµµ¸f̘2ØÑÛí$Ï‹ª(ñ^¾8=Ë€¯«‹ú]»¸´g½/âž??ñ0j›ìuëÈÞ°žsç8ûÌ3ôœ?Oö† ÿ~­ÅBöºu¤”•1ÔØÈ‰Ç£ëäIìùù‰oT ¶£4{ãFR-¢zÇÎ?û,¤/_žp4’§¬Œ¼›o&£¼OI z‡½Ó™Ppó ; &Ä‹’DúÒ¥d¯_OÊâŘóòlkc°ªŠÎwßÅ[]1- cFÆõ¯;‡ƒÜ›nÂ9o¾‘º.^$ÒÂЙ3ø++‘Tõª¢ñ‰>ÃcÎ’,@Õjîéa¤¿ÿ2+…pw7šœŒË—ÇéVoWƒ ´?NÃûïS·ogÏÆÞ}F¶Ù³Ñæå!¤¥âÌÊÃfu2Ð˳ ûýŒ´¶ …0{≮ûnÒËËIš3‡äyó°ÇuŸ#g±·¼‚·Mf ÅBØ+]nÍÀDË†Ë GG?¤¨‚QïGŸä§¥ÇŒÒ0D¾ÇÁ²»}yùl'^‡U#ÆÖA Ѝ£zÊkÙ4Œ,?iÑ&Š >–ä/c“fÏ&sýzRW­"è÷Ó¸{7 /¿³¿™=;¡V›{þ|N«é|R翜º&ƒ5¡m¨JÒ°b¹›¿úÏu¤.]Šl2Ѽoõ¯¿NÿÅ‹˜ÒÓ²T0¸\8‹ŠpÍœ‰köìX\–ªÆ@šF3Ýò›®Ï]_H£Ñh0Hç©S4¶ÂB¬99“’б–ÏuÞ£HßäoÒ0Ðj&â“ÆmTeL‹%¨ŒY6\iá F,º$?MÝÂM> ’¬,¾gåï4÷#UU\zæºÞz‹öÃÇx;©˜¨VFÕ1FMÀªÅß_Dñ³â÷øk>R£ÍÌÔyYœ³üêç›Fƒ%;›ÔU«°äåáíí¥ò‘Gè?uŠèÈI×HBhëõ±õp7qRë³"w5¤eñ\#·¬mÈ$ s+g‡ IDATZy·ÞŠsæLƒƒtŸwŽÃ÷ßOÇñã˜32¸cëVÌÏ”ŒSƒƒƒ´<ÈÙgžAçp°ìßÿë=Ÿ/]¢jûvÎ<ý4‚ª²è{ߣ讻0&Ô ‡ñvtÐ{á’Fƒ9-mJÁÚ_XÖQUQÂa”Pˆh8Œbp8Ò|„½^ÚŽåÓýˆžcÇFF°z.nÝJÍ‹/hlNJ'ž yñâËî)'ëú¸ý‘Jd'DA|–Ác±®`·F¬¿ûª‹G~h»ê5ìïÇßÛKϹsÝn\³f¡³Ù¦å"Ó5Í`]JÒ”LIoxT,IØsrµZöîå“ýˆ–ƒÑY,X³²¢¢Fƒ%=»î‘ŸOÿÅ‹|ôïÿޝ« KzzÂ.÷²^³¨ˆÂ»ïf¸¥…£<€¿·crr€Oo·“±bYk×âëë£âá‡iØ»ÉÛ€ŽHg³áÈÏÇ–“û½7À*TFé:uг[·ræ™g8³e ÞövT˜ÔNDÒj±çæR´y3æÜ\úÛÛé­«£ÿìYêwîDLÙÙ×ßL"±ù1ƒÜÛnCŸ‘Á`G]ÿ?{ïÇ}gû~:LŽ˜`s$æ$æLQ–LY–“ì w×{½ûjïzŸ^Ýë·µ»^{-KN²eË–W²-Q¢LK¢dJb³ÄœI€@ rLžé~ô#Fo“Má[55ÀL±Ùƒîé>¿ó=ßs.\ yófz÷î%àš=û¶`M$ N'y«V‘½baE¡ûòeBá0¡¾>zwí¢cófœóçcÎË»ÃA‰„C!z›šB°Û‘m6d½[f&ÞY³(¾ï>Šï¿_‹ÚY¹’ŒùóqWT`òz5®$§WoWÁhÝÅß¡?A‘N3± xÍój4ô9ð,*ʘ}ƒ8.>GVc¤x†Ñ¹B4uÚvÄ(r;˜ûð2máR_Oç¯~EëƒÂÀÔ×#:ˆ7Øœˆz=§OÓ}é—.‰Ç‰yʨ^°ARQeq‹Oøs)ã|ºÍ^J¼žÑ2«~2”ò{jIÝYƒ­¤ä&Ù ÅBÆÂ…ä¬]‹`4ÒW]MÝsÏáïèÀìõbI´ ;ƒl>ÝGHoºæÔ>êà>æÏÅ­Ù­ƒ5wª‰õK·dêe“ “Û»¢{nîÇö7œ¬ÉúD¬OB©Š‚š0ö¬‰ÊâõR°f Y÷ÜÕ;¨yùeZÐ\æ‘-YÖ&§V®Äž›Ë…—^¢~˽½¤MŸ®ù"%Óö“$ÒçÌ!géRºNŸæäOŠ‹‘:ujÒ– ¯—ÜåËÉY¶ŒþË—i;|˜ˆÏ‡ÉížØÉýnÒ¢ˆÎdBo³ÑväGŽÐöÁtîÚ…¿±ïÂ…ÚÓ€–Á@Úôéä­Z…9'‡¦Ã‡ ÷öÒ¹w/Ý{ö`HMÅQXxûV]¢tf3i3f¹d ’ÝN÷åË ]¾Lçöíô8 ùŸMzÛ}kf&¹Ë—ãž>þ¶6†::ˆ* A¿Ÿ®={H]´czú-Ï[A08c™pú”ÒçÍ£ð¾û(\¿ž¢ûï'oÅ ¼³fá*)Áš™‰ÞfûX&ÆI1¿1?êé÷PNžAŒªø»ÍÄ‚Òpºåó¨7–rÍÊA⤤ùSÂ4uÙñw*tœeöÐËÄrÐôìohxê)¢‘ÁãÇ ïØAlï^¨­E¿lÙPD‘´iÓÈ^º”¬+Ð{½ t‡©©š‰ Z‹p¼«<ãÅö×;Î !<¢€Iõ“©4“~ñÁGBÿþýÄý~\sçNx]1¤¤à7´ ˆF£4þîw´mÛF¤³÷ܹô^9ÛGXgº–=8ÞÁ]¸=ÐB!¢gî3ë&o“5 °&k⨯§áý÷9ü½ïÑ}þ<’,ã¸ÓŠ~ÿyæ<ú(ÎÒR†;;ixë-Î<ö&— ÉhÄ|ÆQH˜êfÝsUÿãú››é¿x‘«¯½F÷Þ½È -ÛŽ‘ Š˜RSÉY¹’üûï' vuÑwîmo¾‰1%ÙdÂx‡}ׯú‹¿À”›Ë@Oýø¨Ù¸ÿÐÐYHÙLJI kÖhÞf3fà,*Âäñ ³X´H’ÿL¶;ØAìàº„Q õë‰Å²5›á†|Â1öHUÐÅ“5ˆìÓÔic¸G ÷ü0iCu¤{šÖšË´6÷ŒCˆ¡ž"ÇŽ|üqtYYèF w½ÕJJq1ùëÖqiçQª3r$Pe!Á¢IJb_Ï’ra“¯Rå J yCMXu1PWG×öíñ¸¦}œ`JOÔé°fg“w、-XÀpg'—_Óßü&±¢)¼MÕ¬[X1ÜÄh·lP%Ôh`-œX“5 °&+‰2¹Ý¸Š‹‘M&j6oæÜóÏãïîÆ]V–”è[”eÒgÎ$oåJLç7n¤á½÷ˆø|¤Ïš•´~M”er–,!{ñb">Gžx‚žsç0¤¤hº¦$ËètR°n&‡³Ï?Oë‡bËÊúX‹²Á Ý8Íæ»ƒâWUFÚÛ9ó›ßpæÙgix÷]zÎ#uêTôVkR,ajU9+V`Ê̤¯¡úÍ›é:p€¸(â;ñˆ¿Þj%oåJÒfÍ" ÒÛРùUmÝJ°­ SnnRŽý&‡ì%KðΟ¯·—–ÚÞ}—¾:s†¬OzÂmxgÌ oõjì%%tÖÔ ˜Íûû û|cÀò­ÄÞZB»¶­¾Šø°%$޳i¸fË &ï‚r½…ƒ¨ªèÅžìA{„¦.C½úöAfÙ(Ôõ‘éðasAT†Îk£ÈþýPSƒ®¬ ñ­â¹·vs153“#À辡^oz ׋ßGßSÌú ^¥én‘ÕËÿœ‘ÁAz/_¦çàAzwïfðäIÒ×­»)Fè&P.IØ pVT€Á@4æÜ8µ`Ãm¬;Y6 HZ‹°ÜÄú“k²&Ö'®b¡¡ÁA‚½½D¤MS%½OESyKz:Õ›6qä‡?DgµbMOׯì'Æ”r-bæ_ÿ5 \|í5Î>÷§[vvr9|‰©œ‚uë(¾ÿ~ÚâÔ/~ÁÕ}ûp•–br¹’± ¢HJq1å? À•mÛã,,Ô&v>aºˆÑ6WæÜ¹„††hÙ½›æwßåÒ¿ýæôtŒN'†$‚Çõ6ésæPòðÃHí'NpuËZ·oÇàvã,)™‰räçSòéO“¹t)uuø;;é9|˜¦—^"00€=/}JÊ·#éõØóó)¼ÿ~Ò@«§¦†Î#Gè=u {y9f¯÷ŽÇÙàp>kÓ¿úU¼3g’¿z5™ à,,üƒÔÎÄÚšÙúÑÚ6„ ˆ!PÂ72X‰öãX+®g¸tboÞX#4uÚéУod†q€u¢à´@N”UBsâŒilV$!tî_D=|9')+ D‘³ïìá²Ã­1X"×g Þ‚Åƽ'%LRM† ©b'•¦0k–ü)…<€³²’ÁÞ^ú/_¦ïäIþs¤.[6¡‚ÉíÆY\Ì@{;ý&G ÖoÃZÝ`.:ús`5pæ$,ž¢#?ç_› ëÔ)Îüô§œ}î9íÚªª“h™¬I€õ‰ª¨ß¯¥…SÏ<ÃÙßü†¡¦&ì¹¹ff%îÂH:ÞéÓ)X·½ÍÆÑï}æˆG£dÌ™“°‘  Ö¬!}Î|mmùþ÷é¿t Q–ñL™’Üj=´ÊzkVÇsâ©§ll$}æÌ¤|•DOEk×j Q¼;ÒåU•@_í­ô]¼Hdd“Ëugp3j—±p!ùkÖ ˆ"Ý—.qyófz&ÐÚJæŠIc½ÝNÖÂ…d,^L hÙ³‡º‰û|È ¶ ZÌ£v¥>ˆ½¤„î†[[é?tˆÎ={µ¶’¹jÕ„ ^2H)-%gÕ*Ä”:kki;vŒúwÞAÐéH›1㎀|4›0¥¨ga¡æ{÷ßÉZž:ñØoÐý)Q¢ugyg7ñ+]ˆab*jT¸Æ )73B{‚rÍÂÁ EI+@µÄhìtÐ7`ÄÐ2@¹aLüˆQb *  ´¬)p©‰a»‹F‰ÖÕzá„¡!D“‰ šh´8´gé –z[5^/–ˆøU£)Œ[î%Ë×D^$“”Œ,<Ó¦‘½r%²ÓÉ`G¾övz%ÜÑ ØËÊH°ÚjÙTÞ舑×Õx+†1ëFv+Á`EuˆÝA¾¼RG~áвl2ap: ôõѼggö3®nÛÆ`S¹+WÞ5añ“k²þc¾0F#–ÔT¼3fá̳ÏRýòˈ ]•œÌÍcT7³`ëÖ1ØÐ@õ¦MÔoÝŠ£ ³Ç3aÛO”$ùù+0>W¶oçÒk¯Ñ¸cÙ‹iiôÉ0Q’DêÔ©Ýw:‹…Ú-[¨yõUI‘dPêxöånÐS#AhضSÏ<Ãé_þ’‹¯¾ªiß23‘&p–7¹Ýä._Nîš5Œ Ð~ì­»wSÿÊ+ÈV+ö‚‚ 5Z‚$aËÊ"{Ù22–,Á?4Äå·Þ¢yËZwî$sÅ í|»èÓ™ÍxgÌ ð¾û0edÐ}å ƒ tô-|€ÎíÆœž>á¾èm6¼³gSüàƒŒô÷Ç âkmÅSQ‘|û^þñQÿŸ¯Âï_BØö[h¾`s‚ îë%|ä½ïîE¯·"ФˆÑb<>Ö"Ç|°®M 7„>ëåé%}(æMvzúMèÚ†(0øp ”8ˆQí!$Ò¯f8Ó%1‚²ƒkÁØ@øèQ¢Û¶qÑ’NGj‚œ`°Æi¿nÒ…²Wª’Ðjiƒ5‚ÓØOÚ@Ya™9Eãètâ=›ŒÅ‹‰Äbô562P]M¸¥_w7)N}÷!óJÃñ:!;ã&¯¸ ãØ,EBû‚|yµ‰¼"ÓÜy¤D£Dý~Âýý„º»‘ŒÆ >Ù` mÚ4ŠxƒÇCË¡CtìßÏå·ßF6›±çå},ûœÉšX4¥D£øZZioׄ´IL&Gg/ZDñ‡9úä“4îØ šky’àÆš‘AɆ ¤VUÑ{ᇟx‚Á¦&Ì 1X‘FÜeeLýÓ?EgµÒyêGœ@W—f°x'Gíq+PÅBöÂ…”nØ ¥É÷ö2ØÐ€'´úIô™u:¼3g’uÏ=ÄC!zçÜ3Ï0ÒÒ‚h6“R\5sUCOÂ(Њ@i毥'Ç×ß?Æd-¿Ÿæ¯%j2_Xêø¶à(K¥«ñ j<à2ÙB8-Cd+MT¤ä‘î.½îœ·ffTÑéÄ3{6öŒ ¯^E2›Ç˜ê[U§?Ì+W¯1X·b­ÄkÀjLà.\¹Ëý!¾¼ÊL^ÑhtwsiÓ&Ž~ó›œüÇ$ÔÝæ5ŽÝ3/¦dã‘öǩ۴‰Þóç18Ø>¦ÇàdM¬?¥(´:Äáï~—@w7iÓ§'m?`r¹È]¶ŒŒ¹sé:{–ó7Ò²?ÞéÓµ–R’}vga!kÖ1{6Õ›6qéw¿c ±‘¬ùó‘’`…F­òW¯FÔ鸰iMÛ¶ H:uBÆe´ Ù ’9w.iS§"ˆ²|W°RÃôÕÔÐW[«y©jRl&—‹ìÅ‹É\¼˜¨ßOã»ïÒüþû´;FþÚµPQ–ñ$ì2œååtÕÕÑuø0í»wÓwò$9kÖŒ9MOø* G»ÍG¦ØÄ””lÒ,7Ë Üååsºp!)••xfÍÂ3m§óŽ×ƒíûÅJD6\c­n`°njŽ>Ç%Ô˜¹'È—W˜ÉýOXJ,Æp[ýõõ¨Š‚¤×'nd“ sf&AŸ–'è:|˜Î]»èؾ¬µkµkõ×£ËEÎÒ¥¤Ï›G8¦iûvš·o§óÈ2-BoµN§N¬»£QDg6“ZUEö¢EœñENÿò—ÈF#¶ìì ['£L”³°Ê/÷”)´:ÄGßùýµµcÞ>É€5ÙdÂUVÆÔ?ù 6µo¼ÁG=†95³Ç3áÄ¡ NòV¬`Îßý’ÙLÓpþ¥—päçcHÜ “ ´ ­Í¨ÓÝ5‚õÁ+W¨ßº•#?ü!ûþÏÿ¡÷̬ÙÙX33'Z£O%Ÿý,‹3på m»wsî駉øýØ 0N b×[­¤ÏšÅŒ¿ú+â²Lgu5­{÷rú»ßEE„Ä97Ñùjp:É^²„¢‡B´Ùh=p€š_þ’¦·ßÆ’Ÿ¯­;€$I§Ã–Mþš5Ì}ôQR¦LŽ®sçu:ìYYwM²‚ÿw¸üì³ø|CDF™ %pc öõcèmÅ¡ Ë΂9‹±Ïš…!7ÑéDp8l6D³1Ö­hä;Ä8!¹ª`sG°e…‰Géè7ÑÞmFìòãdƒ"–W1•±Ÿ…(èB ž=Œõ«_§äÏþ’¼õëéikc »›`(Dè+£6AH¢=9fÕ¿Þ2bœè]³mÐ^·9†±9¤«­”™òH3ßZ·) ˜=Ì^/:«Q¯ŸðzðÜÉ“´=Dt†ÛÛ2Œ«q?‹ *j\®'À#Ë-äþç¬ÐÀM|@Ý[oñá?þ#~õ+RÒÒðUWc+)¹­wÜhÜT|ö³„"º.^¤·ºšš'Ÿd¤®ŽÌÕ«‘&¸ÎŽJ<Ê~˜Ô™3ñµ·su×.Nüð‡(Ñ(ÆÔÔ¤&~'k`ý—•ª(ø»º¼|™ÎÓ§µü¶$&·ÆØ»Âuëpæçsᥗ¸ôúë¸JK±ee%½ wYEëÖ‘RRBõË/séw¿#Ø×GZUUÒz&I¯×Œ=—,Aoµrè;ß¡åÑM&R§NMj¢$‘>s&eŸù ž)Snm%2<ŒÞjýÄæ>ZÓÓɘ={V#ÍÍ´îÙCËÎô?NQ¢5šLÙóòÈ[³Gi)½ÕÕ4¼ñÝÇŽ¡žªª¤ÀZöÂ…d-^Lè8{–¶={hß³Éh$uæÌ¤V°‡ƒì%KðÌœ‰"Š4ïÞMËÎèL&D“)iÇ~OE…÷ÞKúÌ™8iôKU:ž¦wßåêÞ½D£1 ÐŒË?VyÃjhÙ£A¼á.ÌbÓÜ{§ÍA°ZM&³ÁbA0™õ:ÄP1ÒÄí7X8X õ+¬ŒôÒ3b ­Û‚Ð ÕeFòWÔ›X,5rd‹á+ÿœ.¬éé}êS¤Í™CÇ¥K vt*™Ž`0, 2ÞŠAg'1.;Q½žÉQ°§ø1»Ã¤ªí”Nª±â?l¢íõÚK´=DeÃ5§váFÖj£%p-'Q‘Pb:t]YjýOX:³™´iÓð”•aII!ÖÙÉùýˆ¶7Þ@ŒÇ¯ËäŒÅà韫,˜=°4¹Ý¬]KJEÁ‘úè?žÁ  Å5cFRûâ*)!õj¥¥ô×ÕѰe íÆ;gÎdÛp`ý°Q‚€Îl&pü©§8ôØcÔ¼öÚX».™äuI¯ÇYTDñ`r¹8öä“4ïÝ‹-3SóyJ‚ÍÑ[­¤Í˜Á”/~D‘ê—_æð÷¾‡%==)&j´Ìiid/^Ì”/}‰Þóç9óÜs48@je%&·;i7w{v6ž)S°'Dëw #5ÒÙIÃûïìé!ìóa°Û'<Æ’Á@je%<‚kÊ:Ož¤ãðaNÿøÇûû±de%•“¨³XH­ª¢ä³ŸÅš›KÛáÃ4¼ò ç_~™Œ¹sÇÿwb=­¬]Ká0ÜßOßÅ‹4½ó»wã(*œ–6áçµeÈ_¿žò¯|…p8LçÉ“cV†d¦[G™1‡½Õú®”`‘£G‰55¡\½ª ÑEƒª¦yß>Úáâï?› &¢Ñ8‘hü:°5Ê"©qÂ*†Žf¤ý[ÎïGœ}bqbj¢Ãh·#¤¤ X,ˆ²„ F"ˆñØX„Ž5WDM10Ò×ÏPD¢­Ë½!rWÏ!wÁËð‰D:;q-Y2á÷8uölÒ/F‘$[Zhظ‘þƒùßXÆÕa7á(¼ò œ<¡ÒÑK–×¾²Œ§²’‚õë1¦§ÓS_¯­†ª®&68ˆgÞ¼¤‚ŒyóÈ^²Ñl¦åàAê6ofèòeÐëqWTL"›I€õWQ¿Ÿž 诫CUtfsR7 I¯'µ²’âO} ga!—^ó7ìïÇUR¢ “:‹…Ìyó(¼÷^š÷ïçØ ‚€=''9KÀž“CîòåÝ{/ÇSóÊ+4ïÝ‹5á~žÌçewi)k×’·r%}—. 1§¦Þ5aÙj<ŽðCóQ IDAT'Ý®ôz<ååä.[†#;›+ï½Gͯ~E¸¿[nnRÆžF§“ÌùóÉ[»–˜ªÒsîMï¾KãÛoãš:“Û£cñzÉZ¼˜œU«éê¢e÷n®¼ù&C8ŠŠî8y5 ¤=••®_­ €þ–ú/^$ÚßOï… d,X0’'üL g~½Õú=Ý÷q* 1ÒÔÄ¥gžáâ/IÈï‡êë ïÝKäå—ÑÏš…iÊlYYس³É˜;Ï´id.]Šköl¬%%èSS‰†£|ÃD‚bª:Æf­xhÅ@¸p!A\v/bf–¦Ë²Ùìv lY­Zë0C ‡0ÿͧ>rááa†Î3ñá:»ÂŠo|×´éØ+*0¤yQD‰@ïš’KÂ\RŒ%¿!Õé¹Z~ฺ°u—°DMƒuÝ$ãMSƒ×¬QÃQAUp¸FHñaÒÈV! oº‘…$Áùï:N¯µÔÑntÕ®ÓW±V£ÓƒÂ Q9‚Æ`ÅU†öa–ͶâÊ2aІe™h?±înäÛ,nÍîòrr/&28È`S!¿ŸÀÕ« 8€âóa.,D‡ÜSQ–1{½¤/Z„wáBâ’Ä›§òx?øqQŸ`â ¹„¡A(,¿I½ÍFæ¼y|êSÈ]µµô]¸@çž=ZfgNú$è–ôt²/&oíZFz{iÙ³‡Æ­[iÚ³‡ì%KƆ&k`ýû>„^5#ƒÖ>âØ“OÒ_[‹Ñ¥é’)Å‚wÆ Ê>óÂ##\ܼ™s/¾@ZUUR7OA1Øíڔ߼y\þýï©ùío‰ŒŒ>š–#fËΦüsŸÃYTÄÀåËúîw br»±dd$埥³X0¹Ý¤UUaËʺkÀ@dx˜Æ]»è_³†‚uëõ÷sî…ôô1gNb²Fødž°z=J4ÊPC‡¿ó®lßNÆüùÚj- Û ÅBú¼yä­YCxd„Ó?ûm»v‹DH>=©ߨykú‚ô\º¤ Çwì ·¦†ô¹s5 ÛÇYÒëI).&wÕ*œ¥¥ôUWsùw¿£}ÿ~‹Wié„û"x*+qbÎÈÀèv,põÇAYª(Ñ(ñp˜Þ]»Ô×cÌÌÔnÀ7| ŽÂB¼sç⬬d «‹¡¢ñ8Q®ÙÄ‚;vÙ·±£ýܹ:ÝuçŽl±h@«²cf&¢ÙBÈ Ð?HLUÇZ…JÂU]Q@ƒtò„öý\´ ÁdBp:GõXV+‚ÙŒ<½”ˆoß¡³ ƒu*~=‘Ⱥ8 ÿæ!Ê:Býý ]½Ê`k+çÏÓrò$¢ÃsêTÌ¥¥Š ‰úC4:Lhhˆ”¢"jßÛÍÕ=c1TT¬”1Öê&±;Ê“åp“šÕdQÈ5á "ÆU%NP=H#„ÅFÌÂ">Þîµ®z:Lnb²îιƒcF£×4Yª¢,cËb©ž.¯•¢“½=| Wð^8†ïƒðíØç¡‡4ÉÃ-¾‹¢N‡£ €œ•+q”—ÓßÑÁPg'±xœÞ;èß»—@u5îåËîpÿèÒñw?wjz·Q-™0hiQìØ{÷ªT_€µkÆN]AÀ–•Eβe¤Í™C_SMM´nÛF×¾}[Zð.[6±=‹,ãž2…üÕ«ÉZ¼O’,#Ê2’N‡ÑᘌݙXZ{zhÚ½›êÍ› öö"éõI¡pA0ØídΟOÑúõ´~ø!ÇŸ|’h €«¬lB£ÅÑÕâõRþðì^Mû±cýþ÷éòªªèéÁ˜’r×ÜH㑱`0iÑ´ cá«WiÞ¹“#ßú-ûö!&G2~`&‡üuë(¸ï>úêë©ùÍoh|÷]l¹¹Øòò&<>²ÑHJI <‚5?ŸÞK—hùà.þæ7ÄÃaìI‰Çõ6i3fPñå/£w: ö÷ãoh ûÂ\¥¥‰ äD€ünôĉƒôUWsö±Ç8òµ¯Ñô«_ѽy3í?N¸±É`ÀtƒöL”e¬dÌ›Çô¯}¬+èï³“`8L4ÁfEpg'¡ýû <þ8º¼<$“ ÑsMÓ$È2:‡{e%Žª*Lyy`4ôù ‰)ÄTˆª‰vatAY’`åj°Ú4ï2«)- 1- Áá@./ ïýýô:M gX†áD$ê` ‹ Û·iÉ ï¾Ë•]»è®©Açráž?ûôéX+*Ñç`-)#}î\KZÚ$¸šXãn^‰—á–v?ú(-û÷#È2é3g&½ ½ÍFþêÕ8‹ŠhܾÚ7Þ@oµNè¬=¾lYYÞ{/îòrwíâÜóÏÓyâ%6$Íf ¢HêÔ©ä¯ZÅpk+'ñ úkkÉ]ºôc÷Çí99Ø23ï*–¢åàAê¶l¡éƒ´Y’¢|ƒÝNÎâŤ͙Cp`€«»vÑôÞ{Œ´·kÓuIºÓ[ÒÓÉ[½š”òrz.\àü/IÏ©Sd-]š”U…¤×“>kY‹£w»i=tˆÖ]»è>~œx4Š7‰ìHÐ&3.$kéRÜÓ§ã5 ÙdB2î¿©[J4J¨¿Ÿö³gi?žP  ±E@àÜ9Þ}S^–ªªÛgrsÉ[»[q1Ý uwkú©Q6+ñ~çb‡cúô§oh ¢ˆÞåÂRP€µ¸½ÇC4&è&ÐLA•¸fª*"V£f΄ÂqךÐN†/_¡áµ7é»z•Xü2„â ˆñ8jýƒ‘Ðð0ÖôtR«ªÈ_½š‚uëÈ[½÷Œ˜³³,V£ñºÈ«ž#'<}Is½fÓp +a|áè{‰¼D§g˜ôÜtö8¾R}½ † ÍR!ªÔ`7¡Pˆ$Ü~!¬;†úßàõy%tØ3Ƭ[Eå·ŠÊTU&ŽŒ©iC]u©QTQT¹0 53—Q[>—ªïà;q‚¡íÛ =‹mî\¤ÛL ÊÞY³ÈZ¶Œ˜(ÒÛÔDÐïGöï'PSƒµ¤à ¾SC~xê-4K`ƒuÐ÷^u ü~+ÔTCq‘ÀøMŽê,óV­ÂšŸOÛéÓ4ïßOóž= 65öùH›>=i¶ÒŒô¿·UUÕÿ*–B6™>ÖÍB‰Çlhàð÷¿Oã®]X½^–?ñ™óçO¨™¹îÿFé<~œcO>‰¨Ó±àßÀ]^žüHkb¬û¦Mœ{á†ÛÚ˜ó·Ë”/} çmVF·ÜŒ¢äÃÇc¸­y>JjEúdB“ïâ›èPS‡¿÷=Ú>üga!s¿þu²—-KúøÄ‚Aš÷ïçø~Dב#ˆÀô¯©ög8‹Š’Z½©ªJ<¦úÅ©~þy|õõ=ø ³}w’¾bJ,ÆH{;}ûÛ\ݶho/:·›Ïüþ÷šˆÝåJú|mÜu¥ª;:vt÷û±bº“qªªjÓ~>ï½ÇÀ™34¿õJg'¦h«^%%…©¯¿Ž¹¼Ýmt3ª¢èî¦ú¥—¨}é%‚uuÚ¿,€0V«•”‡ÂöW…~ñâ[îOld„'è;tˆî;©¾€n؇-Ça0R°x!Æ¿ý[x`Š¢ ˆƒ 75Ѿw/½GÒsäáÎNt@ăÀЈ!Ç]œÃŠþîª*tN'F—kÌ:EÅ;ž~òK®l|U/6ê Êzâ’LTÖ—%b’LL’‰Ë21Y§ý.ëˆK×Þ‹É2™Ó{(]Ö„˜+à8?ȼãèÌQbz™¸A"®“ˆdâzIû]/á¶¼‚Qºõ$žÿäIú—-Á òÇ^åtÎ\‚‚)rUÔÄ31Pc‰)‚˜Ššx¸F;ÆzÂa#);±œ ûm&qE"׋ËÄâ2ñ¸D,.£óXûêÓ|nãw±Å¢X­V2>ýi ~þsä; ·(Ñ(ý—.qæé§iÙº¥»³¢`1›I_º”âøRî¹A§ãjäÿIbßG7æÅnxoÜÏÛßX·F¸í9ìë£þwðwvbJIÁ–›‹=7—”ââO¬Wá$ƒu#À …è©®æÒoÐwé©••I1@‚(br»)ݰwy9¾æfŽüàûú°åä`I‹h´%dÏÉÑ’Üc1Nýâ´|øá˜QT²Á M~¬Yƒrö7¿¡qçNQÄUZšœ^M& ×­#kÁb~?²Éô±ÀâzÅÃáeõ H&·›â µªŠêjNüð‡ 55aÏÏOÊ©XÔéH).¦èSŸÂèñ0ØÜLÛoÒºo¡¼sæLÜfKŒQ§Ï™CîêÕ Ë4¼ý6õ¯¿Ž¤Óá,.žðúDÞ{/©3g ‡K‹¶2—eLãZPw:ßî6p¥Äb 66Òsú45Ï<Ãéo›ËO?ÍðéÓª«!Ár+«‰ÄqÑY,¤Î˜AúÂ…¤TU‰Åêì$8<¬MoÜHèâEŸÛ-XÃQK”¬E‹ÈX¼,º._&0nÒ0Ä"ÂgÏ|ùeô……è§M»y Ì99ØÊË1åä ;ˆ£†Dû”JŒÄôÑÖÔDãöíÔlÚÄ¥W^¡íða¢žY³ˆô÷ô‰*Dâ btØÑY¬Ž¢"¼3gj1C£mà ΋þŽ0|ò4² ¢jC„ãLNGãznˆÆ¹ÉlT!%moN/FwÉ/ÙuEŠ+cNð×ü³´çxLæû®ÛŸh ÀH{; õU"W©]7C®¦Û‘A\ÒÝB{uƒÀý†©BÁÒa¾Ò¡=‚ü#‚ Ž1X¢ "$qƒžÚYKYðêÏÃAb‘#çÏih€PËm˜ A’0{½ä®Z…kÆ üÃÃô65 …\¾LûÆÄûû‘ŒF"Þžz_½žÁÿ¸ŽÍn`¹à+_(.n{MÒY,C~Ï=¸ÊÊðTVjAòŸPV{`݆ª4{¼•+‰sð[ß"24„-'gb_¤DSRÈ]¶ŒŠÏžðÐ5¯½Fxh‹×‹9™›çh‹ËáÀ–•uW+€ÁÆFªû[:ŽÓì2t:tI0Q‚ àÈÏ'oíZ¼³fqùí·©Ù¸‘¶C‡4á¸Í6!Ý=:]Wòàƒ ÓÑqìWwìàÒk¯…Z'ÊSRÈZ´ˆÜÕ«‰øý\øõ¯¹øâ‹d.Z„l2Mè}%Ê2)……ä¯YCñg>ƒ£¤wy9f¯÷“{ad£‘þúzνò ¾Þ^"¡ÃMMô:DïŽØJKѧ¤ ßaŠRJ¬U«°áÆ××G8Æ__oï^z7mÂ6s&†ÜÜ[ncÌ.cÍ{zèê"”Ðg‘ ŠBðƒSS1͘q°DÙjÅœ—‡¥¸˜HÔ ’ùŽ kðà!ü'N"¡¢ñ ·¶b=¾U(©šMƒË«,KZb2© ͈¡¸¦ÁºX>"}õ˜6^"ž–GoS+WÞ{º×_§îç?Çwò$ÑXŒê¯.¥vþlz-iÄ$ݵŒÁñyƒ7æŽk*$VC¶úä?µhÀ*®DAEDAÑ€–¨ÒQXÁ”ïŽF‰Ã55 íÞMß‹/b_¸Ñ`@¼Åuatá–»z5öòrz[[éï'‹1tü8½Û¶!TÎ幺ü[j®n»3NS6ú¨èz†÷OPG)H²É4Ùò»ë–ª …ˆ…Ãëf!Ê2‡ƒ¢õ뱦§sòç?§yß>mò'??i€ä©¨ tÃbÁ ¿õ-Z?úˆ¨ß%=C`Eô6›z¼j-rú™g@Uqäå%•Ã'JF§“ü•+™ñ—I4 ØÛK,Ô—Oè„h®ÇiS§Ò¼w/{ÿ÷ÿ¦ýÐ!X³³'v§O0…)¥¥?ø F·›«Û¶qò©§4;…ÜÜ ðh"}þêÕäß{/ñXŒîS§¨yázÏŸGo³‘RR2±^–±¤§“¿v-©3gìëãà7¾¡™ùî)S’z› [VÖ˜ ÀÝXövúN"ÜVû&$Œ[]¥¥T~å+xfÌ@´Ûñ 028H4¤ýµ×Ø»ÕïÇ1{öm[»‚(j™œS§’±|9æü|:;"éëcpëV$IÂ}K—nQ§Ãš™IÑàž5‹®. h%nÂ1 3´u+Öª*Œ·9ÞJ,†¯£ƒ†}ûh«©Á˜—‡gî\LeeØ++q•—ã™5‹’ `ýzr—/'cþ|\eeX22È\°€©_ù ™óæ‘·b¹Ë—“9o)%%˜=žëo¨Çÿ†kaè8XË@º üàÑH(Y×[1(×e޽—]‚¢ ¢àòâÍéÞ"ªwà:Ý‚8ÕZyŠfý ãã*B Ÿ?þaë¿Çé®­£éÌEúΞ%zîJÓÜYô™RQ$õV÷' GA ÀŠ :,—ûH=Ù€ø×nDQEBA•›¥Œ1Y¢¤ÏÎaIQ6ÖÁ>úÛÚ´!‡H„P_]Ï=GøÂRÖ­C2›où=eO xÁá`¨·_Oa¿ŸËÛö±mÚßß`ÝöqMŸ•–ãdõ,ßÇ–ÏLÖÝ °Íøè“OR»e‹–Ÿg2%=¥ J)ÅÅä,]Šrü'?¡§¦wy¹vóLÆØÓl&sþ|òW­"ÐÓáÇ':2¢Þæç'Ýž28d/^Œ«´”Ú7ÞàÂË/ã,(Àš‘‘ôJAE\%%ca͆O°žjüÍË]^Ž=/‹›7syËš÷ìIÂUV–Ô…D6™ðΚEΊèívNÿìg4¾÷–ôtùùI ˜SSÉ]¹’Œ Ò´cÍ;wÒéž©S18ž+‚(â(( {ùrÒçÏÇwõ*ÁînÔx\›êI&ûn,Ue¨¹™Ö}û¸ðÌ3T?ý4­o¾Iû›o¢OMÅ’“sÛc4 ´ò׬!gõjBá0/Ç vtгs'ƒ ët˜‹‹o$§×Ô©x.DJI¡¿µ¿ÏGtd„Á;Þ·hG¶9s´íÜp¼%½Wi)9+Wb+)¡£®Ž‘¡!¢Š¢e mmóò0äçßôïEkF®òrR*+‘=œÓ¦a**BŸƒ­Tk뤔”`ËÌDo³ÝÔ®esj*&— Ù|ëkƒÚ7¡ægнµq?RÂ@J«‘ý =†¤ªZ®²s;'÷k¯ ªŠ+]c°Y!Fô985"úÂ×₈“Å'X¯8Ä|‘­aTŒ§É4ÈÏ0‘ûO?Æœ_@wc#}Ë h™3ŸêDQED„ˆJx^ÝÊ k”ÁR5€e­ëÅsò âߥ]×Eu di  ™-ÌXx_¼w%:·›ÎÚZm`BUQ}=ÃûöÁð0¶yón{í×Ûl¤Ï›GÎÚµC!º›šèWŒìñu¡º‘±ºIø~3›Ußãä»ßL›W“ëz”½p!j,ÆþþgÚŽÁäñ`¿“XõÆ“Õj%mút*¾øEz/\àÀ?ÿ3R"™="æÔTòV¬ âsŸ£åàAÎþú×(Ñ(J<Žý6í[}{N¥>ˆ5#ƒšÍ›é»t‰¬{îùXŒ¢Nw÷‚+U%ìóêï×L0'% ½KÚôéLyäD£‘Îãǹ¸iõ¿ÿ=öü|¬ééIµ‡Mn7ÙK–PüàƒŒ´·sê'?¡aëVd“ wEÅÄ~S:΂Ê?÷9ÜUUøÚÚ¸¼e §úS$½CJJR:/Ùd"¥´”„Ѩ-/½Ý~×Å }œ…–ÑéÄœ–FWM Ÿw7ƒµµ4¿ø"½ûö!›ÍØËËo{ŒF-QŠî¿ŸìU«¦¿µ•P8ŒÿêU:¶l¡ó…ð¬\‰!#ãŽl£9=¬+H»çT«•®.F††ttàÛ¿ŸÖ'žÀ>w.æÛD ìv¼³fQöÈ#‚A†‡‡ È©©¤L›†Úׇœ–†|›|O£Ë…§²’¬E‹°¡s¹@¯GÔé´i®瘼Zý;Ô¾¥›(à«…ú'4+yÙ¦b½½ ½´‰x]=’ª1XŒc«F³¯µUD5~-‡P¹Æp¹3ðæôâÎ 0(–aù i „šè£ª1 h©1mzRŒª¨Ã"#ç Þ§háÔƒèûÛp{œ•ËÉü¿ÿ•«P—êÂ0'@š‚ €*k@k”ݹ޲áZlŽ"êˆ 2ÖÚܧ®¢ÿ{·6E8úH´µ¶¡ö×KìV%ÉHcöÊå”~îs û|ôwtà! øÛÛéݹâq<+WÞñ\3¹Ý˜32°—”°s ƒÓÙk¯'é†ç[½&]ûY§Wù§ÿ9Ùö›X·XÙ»ËÊÈ]¶ WGŸ|_s3žŠŠäܵǰ٠’»l;vpᥗ$‰ÔÊʤ·aLI!Õ*œœß´‰ /¾HtdkF&WònÃ΂2çÍCg±Ð[]­9w.’ÑHËž=\~ûmºÏŸÇYT„533¹cìr‘½t)éóæÑ}ú4'~ücFš›µ(¡$¶!ˆ"îŠ òV®Äœ•Em- [¶Ðuü8Á²o51v°%w-¸ öô0xù2º$Be“‰¼•+É¿÷^2—.EŸ–ÆPG}gÏÒöæ›H’DÚòå{Ny«Va+*b ³“Á¶6mpld„ðŸ:…wÆ ÷Ý’•EÚ¼y8§L!à÷3ÐÖF4A?øÛ”)·Y£Œ–§ª Él¦åÄ l¥¥¸æÌ!eÆ UexhÍö_Î8(mÕÄ¿¡yT$²‰½¡w7øŽêȤç_C§*Èh BUeŒº‘¹º«EâwwÆÞÜ>Ù ÒŒï×" 4öJU¹ÆdíOP$Õ>!á­-¸ðÖ¸úÒ² ŽQã\Ó†%fÈâu†×çŠÄ™¸ a½ÔçÄUôº®µE5Á€2X8‹ëdIà/MREÍ+*oÕ*¼ 0ØÙIwCØ]GÏG¡s:ñ,XpÇãaÍÌÄY\Ì7‡ï£'"_L¹‘­º…MÃø×dÊ?ýå$ÀšX·)ƒÃAæüù”}æ3´~ôÿå_% sjjÒ-?³ÇCÞŠxgÎäÌsÏQóÊ+è¬VlÙÙIù>‰²Œ«¤„ŠÏg~>gŸžÁ†lÙÙ˜Üî¤}«t öÜ\M•h} Ÿˆ²‰ IDAT`MÕøã“µhm‡qáùç9óë_ã((Hš‰²çäP°v-ë×3ÜÖFë¾}œ{î9._Æž—‡9--)÷sG~>%=DÖ¢EÔ½ñ§ö3]]Øóò&Ìò¥ù3çÍ£â‘G0ge¡·Û1Úl:;18ŸXËŒÈÈýµµ\üío9öØcœyâ .>ù$;wbLMÅVTtÇ¿­ÞjÅž—GæÿÇÞ{GÇußgÞŸÛ¦¦`P½ƒ {;H‰’¨ê#+¶³Îæl²ywOr²ïfßd×Nvµ£ÄU–%«D‘EY¢Õ,J II)‰b/bØ Dï3˜rËûÇ J"F‰ãXçÜ3ƒ)3ó»å¹Ï÷ù>ÏêÕäÖÔ  Ã==´îØÁ•ýWQŠÓ‰åíñ²ÝNFU³¾ñ ¬Á ý ÷ôîîfðôiš~ücPU,^/ÖÄ`Év;žòrò6mÂ7o#ƒƒŒ êí¥çÍ7é{ûm2o» ù4›ã Ù 2óë_ÇQR‚·ª ׌8ËËqä䘆ſÅc‚ Óÿ•cj’9"Á q 2uÈñW±:#hç $uÙL5j(úñçÃÔ`‚dåõâ * Xç ¿v±7dþÿ„ÕÀ8ƒeÄÈ!ðU‘‘º8ºššYèªQ_ǹEÔ+ ZAc*£–Ü#a-I˜•#‚&*¨(¸/t8Þ€ã¿y’L•˜Ô_éH‰Ç t‹ˆaÀXd$¶aÉbÁ[\Lù}÷‘±p!]ŒŽŽŽDhÿàNþüçd,\˜Ôt~Ò9@±Ûy²N¢{Œ©ú*IøtýÕuÌ–¬|û›¿›KFi?z”†wße´½ý&áðï°ÆKBŠÃAц ä,^ÌÅW_åÂ+¯`hZʦhhÍ̤ìŽ;PjŸ}–æ}ûð––¦fÉhéNŸ9“Š{îA¶Û‰ŽŒ 8æNò:0DIJ9bçs7 ƒpo/†¦¥ÜÅ)ˆ"’ÕJÁºu—,!ÔÞÎÑ¿ÿ{°¥§§d*HRÒ¼ÕWQaæðíÚEÃ΄{{ .^œZ“,ã-)¡øöÛ±\yõU.½ô#­­ÖÔ¤´½Z\.r—-#gÅ |3g’QU…ÕçûÒ‚iÉbÁêñ F£Œ Ósù2áþ~B׮ѼmÚà ²Ó‰sšyDGf&¹kÖ¹l£ýý 45Ñô ô:ÄXs3Y7(Á‚€¨(—,¡`ãF‡ƒžÆFBÃèÑ(½ï¿OßÎÄÛÛI›?éS:ˆA@v8ðΘ5+ MhnFp8ð––2ÖÑ’›û©Þd‚$aIKÃ_Q+/ÅãAP””¬~ógº8ÃÏ~16Á%o5 ’ Å±•ê(~ µÍTaMÎ4ÙªDiîz‹†ñçÐ ä •ß‡-Ëɰs&„ă IÖ*ÉdÕt±i–è½ ‚:Á`%™,.m¨¢1³ÌXúDgãD—£Ž ›ŸQÀÇ£rL:JeTA&í\'Gqý?nDɳOî$Æ-DÐe 4ø†-€8õB[J4;ä¬\I÷¥KŒôôà)/'sî\ˆŽŒ`q»?µyãñ:L€u½KœÄh}«•ø[¶|ûë¿›K”eÜyy`4¼ý6µÏ>‹‰HÑféæø7°ipåäP´ažâbN?õ—_´¼<À§ŠU?6±ŠBúÌ™×Ô€®sâá‡é»|y9—+¥“ âp^Y‰/ž+Éò—º»o*¾28ûÜsÔmÝJݳÏâpd¦&´׬nØ@βe4¾ý6uÏ2ÂHs3Ãh¡熚(oI kÖ0ãÁÉZ±‚¾¦&Btro¹…‚šâ‚@oC‘h”èÐý‡1xø0Ù[¶ ßÀ¦E3⪨ˆŽlyyxçÍÃ?kñ±1b±XJ®ÿÿž£ù‡ÿ £î B<ÁiÀƘdG/¨&ÐR lÕ®U*ÑZA5 6Ù^A».ìyâ¹ñ.ÂŒœYƒØ²=„½¨žÆ/Ž™ú+)Lš‘`Ò”1u \k6ˆë´TXiDìN®Ü6ŸO.áQ+‚–ÈFLZ>LînLt52‰Í4QAWÜç»È<|Ï:Ì0²DI4é‘ÀˆüžÕOº$âñÈ™•Eᆠä¯[GZi)ùëÖQ¸q#Ù‹áÈÈøÔcããç¡; ,„Ú7(ŠÁ·¾ú»["wN«Vá//çÊopö—¿Ä‘‘+++åsúM€õ›\©ÕŠ·¨ˆŠ{îAFùè±Çè8qgfæ”Ô÷T@RFU%›7Ó~ð ^yÅÌ‘KOOÙûJÅ”B€¿LC2««‘ívÚåàßþ-£­­¦;Å(!ÙjÅWZÊÌÄârÑòþûøa¢CCd%Ö ‹”½`å÷Þ;!„î9:OžDq:ñ¥”Ãgóû)X¿ž¢M›pdg£E£¨‘iùù_jߘÑövvìàà·¿Í©¿û;Îýô§H‚€ÅãÁq#Ѹ¢`ózM|Ï=Øóòèkn¦¿±‘†gŸeàøq´ÑQK–L¿8øgÍ"¯¦{n.£ƒƒôÔÖÒñÆ(6²Ãý:Q–qƒ”Ü~;éóæQUº.^$®ë„š›:y-ÿ`Á ¿3¤üÞ{ ÌŸOZEžÙ³I+/Ç™ý;lèú壗M+„q€uÐÑiÖBp‰"Hnïm*Ö€†,ë¨M ÆJŸ¤ÁÒ'Y8$<°à #¯ŸwkÐO,£”Ø  í‰CI@—¼ÿ¿1PÂàEZ‡Dz‡õdö8«¿u5gþËíÄ»ã„CЦ²V¢ž°‰Ð¡Óãa$ºòD U@ i8ë{ÉežAÀWVFFu5öœ££Œtuª¢öôÐ}þ¢Ó´ñ$S“UébhS.£ÝB!«ù9'›N1=M|®IÏ¡ˆÂöæ~²ö_!ðUKÂèt¤%¾—hL0ZèQXzð"¶þAÔxWNÎo¤Ìõìù!Óá^ÀN†$ÞØÑ}2ƒeÑùÖÝ¿ÝrÛX_×öî¥ýÈ\Á ²Õú™º\Ó++)Ú¸-1ý,÷í£¨¦ñ :ÿ; °&ès–.¥ü®»hؽ›Cßý.’͆333e'óq¦Â™#¸ ®®;qt}ôçž{Ž}ßúÑÁAl>_Jº5‹ËEÖ¼yÌÿÏÿhùðCþíß…ð––bózSúÿV‡ü5k¨¼ÿ~FZZ8õØc\úõ¯ñ¦ä`>~…Tù•¯»r%ƒ×®Ñ_[Ë¥—_FTS‘‚S¾ HËN?§«*ÑÁAFš›é9y’–Ý»mkÑ•uC¶pœ ,»çæüñã.+c ©‰¶wߥéõבïœ9Óžl™™¬_OÉ–-DâqÚÚè­«ãÚ¶m´oßNpìÓÌ(ËØü~ò7m¢`óf4I¢çüy:ââ÷¾‡(Id®Y3-ˆÌ™ƒªëàrá,-%ë–[Οâv …pfeýÎÏýØËÿˆñÒ/`ûcPÿX,EïœîÞ³›þW^Ç2­°LÁ¸Éé“JtS–q†i²^õšˆ~I›b,:Yì.麬ŒànK)?-¯˜Ñá,âOFÅ1âÆÄÿŠq“Á’GÁ2 eß}û¦- ôöÒßÙITÓˆZ¹›èºBFzì„C“­Ò&•ucâV›ü÷Äc˜ŽÖ±t޹¯×,»WELŸŠÚø{uD dQC5´TdΧfÝ:|ee)]ø¥2ž??Ê`8†×Ìß1áÇ…4 h}̦aB¯Xt¾uÇo`ËgºÏœáý¿ú+ºNžÄ‘žþ™ü‡ƒŒ9s(»óNB]]ìÿë¿&ÔÑ·¤ä¦þ· °’L”ÝNáºudTUqùõ×i|÷],N'¾ÒÒ›3ñ¯žâb²,À ròÑG¹òúëŒ »bEjLÔ¸]ÆÚµhªÊé§ž¢õѬV2fÏNydzz<¬[Gβe 54pôûß§ãøqrW¬H ¬x )Ù¼™œ•+MÛ§QQpçæ~i¯ ]g°±‘Cßý.uO>ÉÕ—_¦qûv†.^Ä–—gþ6)¸Ó§ÏžMÎêÕÈéét;Fà /0|îîü|ùùÓ~GFùk×’µd ­­ ´´0ÖÕEïáÄ®\!¸iSJßǽbéóæ ‡li¡ëý÷¾xG0ˆóŸE¶ÙÈYº”‚õë TW›e¿ÊJ<¥¥¸óò>ÛÈÀ7ïBŽš TK=Âþím—ҳѽ٠^¾Lë;ïÐöÊkÄ/\EJ%c’`ÜÐI2JIk’}Âä× A| £Ç‰0FPUƒ±W¦^'5„ST‹óÑ i…( cÄ ÔÁFT›jÓ35XÖ1ˆuv“ó­ïQtûX²³é¸pÑáaÄR7¬*d°ßIxÌb2XãòSØ´‰’ß1¾n@Ä@ŒêH½a2öÕµX›0Lá“\§¤£FNµØøƒÒ¢ß(k¹íƒáBÜ0¿‰fÁ0M¹¥I¬•ðqFK”tüN%…¿}ÑxÖ¼yoÜH¸§‡ã?Lwm-¥›7æszÎÒ¥dVWÓ~ü8gž|IQ¤àQx`ý Q–ñRºy3¥›7£Åbh±²Ý~³3!1¢CCô]¸ÀXo/ºª¦|E 8dÌ™ÃÌD¶X¨{æNüô§x‹‹±ùýÓëÖv EÌ<´Ž“'9óôÓœyúi‚‹aIKK9J(­ €Ò;î {áBÚäÐw¾ÃHg'î¼¼”˜5ÅnÇ[RBæ¼yªªð~a·CÓLptƒ¿ Š8 Ö¯Gñù@‹Çé9~œ¦^@v8°z½Ø¦l ¢ˆÕç#¸|9…[¶ ddpõÍ7¹ôôÓ´íÜIZi)¶iÄ«’Å‚·¤„Ê kéR:/_¦çºàÒ~„%- ‹ÛušÏ"Y­¸òó±"ºÝ uvéî&ÜÐÀ¥;I+.Æ~}\ÌuÛˆ#3ÓŒ!²Z>',Wÿû!¿{12©¼ÓájìÝFý…fjŸû%§þñ/\@Õ â€&ÊX'zDGé ’:Áj3WãÏ%Ù¬8à ƒw9¢Õ‹¨Æ‘ÆÆÕx’½4¢ ‘ž>Œ¹¤±8Ÿ°¿{yV-€hµcD4´á1Œˆ†1 JÈ\Œ«­(úX3³ÈY¶Œ²ûïGw8Ò:‘«¼ ö; Y´Ob­®{l2{¥ˆc:rLCè#ãÀU‰¬ê±äk%Íü.R¢d(é:&ƒ¥w;ùFqáot._¹ÐÇP8‚K€BôÄ’¸ŸèhL©^g6*Ê:i6ûçþË+2Z4JÛ‘#\~ýuFÛÚ,–”ý­9K–P¼q#]§Osà;ßA ‡IËËûL9¹®`ÂõëÉ[¹’º­[9ñÈ#f:Kbß¼ °~ËC”$$‹ÅÌôxn‚«ÉkpÁÆF>üö·M&ª¿ŸôÊÊ”‚ŠIXf—.%7á¶è»ß¥ãÄ ,þ˜,N9™gfR~çø+*jnæÐw¿ËÀ•+¤åç§Ü¨ Ê2ÞÒRJ×KÃδ8€ ЏrrRêAý¢i©ôxœPg'½µµ´¾÷Mo½…¡(fäÒ§N­€b·\´ˆ™>Höò娺Nï¥K4ÿó?ÓùÞ{„ ®];­¦BEl>Á•+ÉX¸]hûðC.>þ8F8LÚœ9Ó{QQðUT˜vYYô551ÜÞNÛ®]t¿÷™+Wb¿_Õø6âÎËÞ#?Ñí&cáBòW­BÅpƒ_(9À`ÝiÚô0bk¨ Ưc b*ém§°÷7¡Q®DÁåÂ3c b"Úp=K4]½Ž½Jˆá“:)³“°ü>oÑåBÄ@ˆÇÂá$‹„":¾ Žâr!æç"”r”`·eaw#º\H^/ ¡‡U´¡1¤¨aj°bV{òŸý9$Ìxm^/ë×c/vÒ;tžw‚Áš¤µš¤Å¦0Y,Q7"&ÀÒ¢Ž4âôBöܱ),!‘•8ÙÁ^ƒÖãä÷JK~£óùëKÝ ‡"1óÿšÀjb1I«DÙp\?I/):³ƒ:÷”™:Úþ‹é­«c´« gFFJ]z¢,ã)(ÀP¿s'u[·&0kVJûθģxÞââ”Ò2n¬›ã·2,.Þâbr—/g´½Úgž¡ö™gȘ=›Ï—ÐJ\Uä­ZEѦM´<ȹ­[i;z4¹ÁO[RJP½%·ÞН¼œ†·Þâì³Ï2ÜÜŒ·¤›ßŸð‘ív².¤üî»É»å´HÄdÃìöߘâs7DÙj¥î¹ç¸°m×vì ù׿æÜ¶mä¯Yƒ’(‹ÞhnÒ Ì¬Å•+îí¥»®ŽŽ}û¾pôyóÌ(Ÿé€– VP@îÚµø««‰„B4íÚŵ_þ[z:ö¬,”i’¬iifxúæÍÄÁÎN†i~ã Nœ =‘øi:`‰èH‚ž, ãe›%)³³ îŸe¡óÄ N=ú(µ?Nï~ŵ={ìv¼¥¥)uÂÛý~òW­"ÿ–[¸üúëùÁÈš7ÅéL-3UðSTSƒ§¨ˆ3ÿôOÔ=û,™UUؼÞÔm–dÿŒoØ€®ªìû_ÿ‹‘ÖV<_:¯Á›ë·0b££tŸ>Íеk8³²R‚ `(Þ´‰àâÅŒõõqàoþ†îÚZ»ô3RÛØFz÷Þ‹¯´”æ÷Þãè?üƒ™û˜™™•¬8dUWSqß}hñ8—·oçô“O"Š"Þ’’”¢‘QÄâráÈÌÄW^ŽÍçû‚+]U“sx£ùe™‚µk)Ú¼™´²2d—‹P}=µ?ù c8 §-§JV+Þ’f|õ«Ø‚A££\{ûmÎÿìg ª¦‘ât&°‰Æ_e%·ÞŠ«¤„þúz.<õ]»w£ŽŽX¼ø†`M$l~?¹+WâŸ5‹†ýû "]û÷£Š×‹íNî‚ Ûíf¹o¼£ðsr0ýøÇ¨wßÐßo†WT «*£íí4îÞÍáï}K¯¼BïñãÄx'‰«Œ‰N¼Éé‚vJl#ø Ü_ýc5‘æ“'é8]QH+.EV¨£QŒˆ:`{V%V"½—pÿ‡ÿƒèõ"ºÝI %:ºá*i›—ëìÇZV‚PRŒêÍAŠƒEò#gQrsQÙŒ’Ïv;¡ÕñJ.¹GAzQ1bBw©£q´ïYĆœŒ…• Õ$@5…­J ñÝ„šÖ±ª*ñŠ÷d kœÜŠÐ@6Ád™AÔ:qâƒn¾R>ó76çîïâx[Vâ’KJ” …qeLÜ—eCdÉ¢3+ÓàþJ ÞÒRòV­I¢§®ŽþS§üè#B--W¯NÙ§ÐæóQºy3é3fpâ‘GhÜ»×¼h/I½KºÜßuº¦qä? çìYœYY¸n`ïò1¶Ýá0eÕÕÔ>û,ýìgÈ6¾’’”I‚›ëæ˜~æuåõ×9þ£aõzMMQŠ#­ €ÂõëÉ^¼˜kï¼Ãù矧ïâEü••ØSˆ‡ßñüÕÔà++ãè÷¿Oýo k™UUÓ¶ë­¼+(Ú¸‘Øè(ç^xá¦&|åå_êH!=g°¡Ö½{¹úÚk4¾óýW¯š‘K6Û çÈêñ5>6}Ë-ŒõôpíÍ7iݵ‹Øè(¾Y³Ì+Ði4Z™óæQ¸q#–@€¾†šví¢ãÝwéܳ‡ÂûîKiŽe»ôÙ³É߸[0HÛ¡C4¼ò ]g (øfÎüT %‚iÚ˜MpéR‡߬Yä®]KZ~>—+%Vís±Kë:†¦¡E"t<òÝÿû£Æãè'N îÙƒ°kÒw`ËÌ$­¨ˆŒêjE:Ο'nDuÓ'J¶ôВ⓺‹8Ôré(ò` Yåôµw’¾p!¹55XÒDÃ"½1#)jÿ˜!i $[:®oþOÄ@!- Áí6Ë….$ìP”l?re>‘«íXËK 0Ò³0"*! d7¢Å‚œžŽ’èr1VÞEô;ˆnr0¸LÄ×SBûÙKœÙ± ÉjÅ™•IWÇ„kôºˆŒY’ÂõëÜ“ÞX“Åêã kÌÀ®©DÇ4ÒjÛñ‰QòÊF§Ú4Lb¾$Ý4q âCnî­¨švnUþ¡UãWÝ«½ʧÈ#_ a  ‹®NXI¡û$KH– 'ž3d¬³2 î/5Ù!‹ÛMîŠäÜr š(Òrð ݇ѵo‚aà­¬DLh ‚€§ €‚5k€ã?ý)=çΑ^Yù©Ñ?ŠbÚ,­YÃH[ÿïÿ%ÔÙIVuµy”Ê:¬VœYYä._Ž==þK—ÅfÚbÓÓçy†a7ÐooôÔÖräïÿŠ{ï¥ò+_ùÌö /¾ÈGÉù_dÎ7¾Aùwâ)*úLÛþpK GücZ÷ï§ê÷ŸœeËÈYºô_tqòeé0¼É`ý FëÁƒ´9B×éÓ823?(qfeQ²y3²Í¼“÷÷ IDATÆé'Ÿ¤õàA|¥¥)Çu‚@`Î 7lÀ rôþ¦÷Þ# ‘»bEÊŸCq8È_³†œ¥KëéáÄO~BOm-ÞÒR\7pÖžÂvX­¤$¾ÌnùI-Óòåd&4D£ÝÝ ]¾Lï‘# ·´\±"%j\T<%%ä®]‹«¨ˆÁ+W8÷ÔS ž9ƒè÷ã//ŸvÖ´4òV­2…ð@ã;ïвs'#/šÁÌ)¬ƒ„ë{ ºšŽÚZ†::0Âaâýý„LVfºUŒ')|ÎÆàw¿Kì‰'²³ ’k±á®.>ô­û÷£ à.*ÂeBCCLJ®ÁŒº:Ä;óóæÎE²ZÉ^°€²»î"¯¦k0H_K Ãýýh†1åýºâ¸Õ¤ü?tÛ¯ößBt¹¸ðÖ[4?Ž`µX¸OyhÚH},6á¼}(„f·ãZs›9?Š‚èñ úýiiˆN'b†Þ7ÞE ÅpÌŸƒµ¤™h’ùÌeŽŸ¦uÿ~ZBv88ûÒK”ÜÀ<5¥DIëŵÈOÖ²¥UÝM¸y;Z[?ýC."å:æj"²G˜d„*LzNÐL‘»ÃˆREœºÈík#§R»±Mƒ¨b}îP®A`Þ§ÎûCaƒŸö„pFCȆ†(è|8dp6,RfȲLãN·tÓ4І¢ièaÑ´«ïÄ@0˜Ä\]÷ HªK¦øÌ{l|ø/ZZ×­›²ÿy )ܰOE½ 66ÒöÎ;ôŸ8Aɤ¼=‹ŠBî²e®YCëœyæ´xœ¬yóR^‡Õã¡hü¥¥\zí5N?ý4=gÏâý ç¯ñcå—eÜXÿ‚áÊÉ!:<ÌÉGåÀÿù? \¹‚§¤{zzJÈ\RÒ++)¿÷^"ýýþ»¿£ïÒ%ÒòóSŽ ‚€Íç#géRfþÞï1ÒÒÂù^ ö™g°¸ssS¾ºqçæR|ë­”Þq½gÏÒº?CÍÍdÌžh±|iË~ºªÒwö,õ+Nÿìg\ض gv¶|Š]²Zñ••‘¿j•<€«¨ˆ®º:Úߟ+[·"Z­¸ ¦ŽXÒÒȘ?ŸÒûïÇê÷ÓqèWžzжƒñ–•a nXfÏ,¾í6 6nddpæ½{¹ò 4nÛ†oöl¬^/Ò ¶Q’°¦¥Qºe yëÖá*-%kÉ’d¤’d±|!J~Z$Bld„±înš¿óº¾ÿ}⵵ķmò`¢Í†h9wfeQyÿýä,[FöêÕÞuÎÒRâ¢ÈèÈáp˜˜aZ+Ä Œ;yqÉ»ÑãÁžžNö’%Þy'J0HG}=¡p8iÌâ taüD¦¢ŽDÑGãQsŽêe86Þ6i’E»)#<ºÞßOó¾ýX3²q–W`-,BÈ ¢ËiˆVƒýö?i;~œ‘ކ¯]£ôöøKŸÂ¦„±È1,BÍÑC(í,Ž]Ø;ÆPÛB vÛ‰ŽÉF§×/3Mh«4yLÃ¥Ç6$ìWzÉíë$¿$6!pŸô^)±.YTC Ô¯R}ú'¸ë¾‡½d(æ~}{'‘µ‹xdÖ\^œjIÐÐ óaçº Þü«/¾Hϱcd,^Œcñ¹ ŠfÌÌ’%ä¬\‰ävÓq⯾JÿÙ³H’„¿ª*…ÍÄ‹f/]JpÅ 4]§ýƒ¸ú 76’>ožÉNsPL+,¤xófœŒôöÒ}æ —~ñ B­­„ Ìšuc°–°È¨®6MIƒA§ós®¢CCtŸ9Cë‡Rÿæ›\~ôQ:_|ÑìTU%²mÚG!tu¡Ür‹¹ï* î¼<|åå8 q••á./Gñù ‡ Œ‹Å&tVš†#lÝŠpþ<Âà Â’%¾dË–X¸Íb¡¯¥…p(4E£¥‘ÐbÅMwvÕ0ˆÄư._È$-?Ÿœ+p––¢ƒH>rBÈ.XlŒõ¢ŽF C±­Z…œ(7šÆXw7½µµ4ïÙÕ×ß`x`{I þ™UXŠ‹3ƒ 9‘D§/‹œ•+)ܸ‘ ðû±EŸ23  ER‘  Aˆ*„xÀB\’ Ÿ—&ÄíÆu:«qcQcª>KÔ äˆ†“ÆŒ¥±¼®N Šcæë5cR†¡¹H†Ž$j„‘Ža¡.‰EáZ¸´Ïk¨¥ó™÷þÛ¿¾AÞ¹÷N†3ý8âcH‚†(É[ÝÐiw¦³»tMg.Ò2:‚ǯ!«zHLh°ô¤5ƒh$ôV ‘»4ù9 â>…¬ÞzøšaÅPß}±¯©°1ZA@T², hÓ&ŸŽ3gh~ë-ZþùŸ‰ttàŸ3%ïªq;…²ÛoÇêñpöùçixûmœÁà mb>éÂ+gÉü¿óé7Ö¿ÓuuÑqì_~™ÈÐr"€6•²†dµ’5o¥w܆Á¥W_åìÖ­HV+iyy)ù<Ø|>òW¯&oÅ ®íÝËG=†+;{zzÊL”·¸˜¢M›ÈY²„ú;8÷Ë_Òqü8Ù bq¹R®yÛ^§ó ®´X 5&62’<`ÝAr¹HŸ5‹â[oEp8è¹x‘ h~ã "½½¸‹‹oØ—d<ƒAro¹…âÛog´¿Ÿ¶ƒ¹öæ›\úõ¯É[½9…\MAqdg“»f 9«Wêé¡iÇ^z‰Ðð°ÙÍ9o•l³‘9w.%[¶à**" aÄã±]uuø**¦Õ‚ |.A•ÚÑèt~¬Œ-Ê2V‡+;wRÿÆ ]½J\U‰éú„•oj"¶?êóÏ#ƒˆ>¤“™d·cÏËÃ[]£°9=p(d­D&_¢Ò‡~å Âûï#Jbn.$UÜä­Yƒoî\Æ¢Q»»‹D¦tꆹ]…Ѿ›ïÆRP2åbIt¹P‚A”œd¿Ñë%¦ëŒôö!z¼8lóç38…›7X°€ÁÆF·mãÊë¯cMKÃ9 °gÖ²-¢ü¾ûðΚEpÙ2‚‹!Y­ˆËÂôW ‡ uu1ÜÔDÏóÏÓõW…Ñßd·#OÒ ¢ˆl³Q¸n³¾ñ 2.DÉÈ`¨¯á¾¾q{ª$ ¥öõ{åô½{QÖ¬Aœtå.ˆ"’ë¬ Ïœ98 \.BÃÄFG“@+hªŠ±w/ /˜áìyy^¯Yb®¬$¿¦We%== twUÕäg÷ÏŠk yÒðn¼ýYi)- 9#ƒ¨®ÓßÒBs3¶‚Òªª0z{¹øÁ\ؾ®3guvâÊÉ!{É‚«W“·~=Y+Và,/G d"ÈvAABd3ë3a£¡íÛ‚1Úk†Kk€: h¡c‘bÈ‚j.¨È’†»*NÚj•è%µƒ©¾WÚ§X6¨JTÙXbû0…­m”ßjÓ ê:²'„È@D&»¥—yC ?¤i¥à_ àÈm5„¼¬z, ¦$ACBK–ûÆ3D‘‹Î™´[rPE…ì¡®¤{ûTGwcŠþjd hé£4ŠŽí!pùì”í-62‚zæ Fc#B,†<‰ñ% W0HÙ]wá›9“p(DûñãÔÿâDº»ÍŽÃ­|d»À¬YÌzàQ$ÜÝ;'ç Qú¿ °~ÃÃ0 M3½ˆt=¥D¶ÙÈY²„‚µk‰ŽŒP·u+ »vaq»ñ–”¤ì$m÷û)Þ¸‘¢š:ŽáÌÓOÓüÁä­Z•2‹$Hžâb³½V9õøã´;FæÜ¹æ:R1ö´ÙÈš?Ÿü5k(X½ÚdÂŽ/¯©ç8µÛlnæü‹/Òuì-ï¼Cóž=ª«±gdL ,<®[Gpùrú›šnj¢åwh{çJî»Ï<éL³Žq CáÆøfϦãÔ)Z÷ì¡}ÏPUü³g§Ôm(Y,xËË Ì›‡5#ƒž“'©ùeZöìÁSQ+…¤dµšå¾¬,¬^¯inú9?¨ÆFGi;r„†wÞáâ‹/råñÇé|î9"Œ¾÷á÷Þ#~ô(®M›`$Œï7‰ ”ÜU«È\¾œá¾>::ˆ&J}Ú¤rÚÙ‰úÞ{pá–U«%y$ˆ"ŠÇƒ«´÷Ì™X23Q ƒÑÁA¢‘ññò# ‡Ã»wáCHßø†¹@v8HŸ5‹Ü5k°feÑÛÔÄèð0ª®'ý³4 †Ïבógÿoò"ÎÐu ]'ÒßOÿåË´>LÓþý\ûðCTQÄ[Ue²leeøËʰgg“±`%›7S|Ûm%|÷¼¥¥8²³QÜîG©QôžÄí5A•&Lú‘ÐLð”,Š&“%¡![t\sU¢E´.¦°WB’ÅšpwTK\Ã!Ä0dè !]ÀïÖñ[Ʀú_é –¬¨Œ"1WȼÖÏÜk“™ø¬‚žphÞF,n,zl{eÞŽk©$A3Rl…¬NÚ|yè‚Hî@’‘(Ÿ °’îî2h2a¿“EÝ×pŸ>N4ŸRVعsÄ÷ìAÉÊB©®þØ\ø+*(¬©Á7{6=W®Ð²w/í»wÓöÎ;äÝzkÒW.•c¤§°OAÁMpu`}òˆ Ð[[ËéüG®¼ù¦Yp»§ÍáDgf&e·ßNÙ–-´?Ω'žà¯~…§°W0˜Ò‰o<”¸òþû ÌžMçñã¼ÿ?þÑ¡!ì)µ gÿþï3på ~ûÛ’„âpàHQL(ÛlX=”/(¸ŠŒîê"ÔÑÞ€Ž3Qy+V°ðÏþÌì®SUzNœà죚&°ÙÙ¸òònbe«y9Uðx*+é½z•®3g8ýÐC„šš,¼ÓÅ —‹Œ¹s™ùõ¯cÍ̤«¶–‹[·rö§?ÅS^ŽÅë¶äfø²=+ Õ0ˆ†Ã¸óòwv …pfgi ý&OOa!†¦qu×.ºOŸ&‹™‚ñÄña¬®Žþ‡BE\k×~ò>œŸOñ–-/¦¿£ƒÁ¾>Æ¢ÑäzT ÖÛKüøqb=„äv#Úlˆ“öoQQ°fdà]°Ïœ9Ø‹ŠG"ŒŽŽ2666e]ñ¶6´úzì“l[QÄæ÷\±‚¼M›|>z[[&’Ñkô:€¥¢’ÈÈÑÁAÔH„¡¦&¢CC4îÞMó(>é‹X¾œ´ª*³fᨬ$cñbrW®$0gî¼<¬‰¼QQkGÐ@¾q Üx÷¯ÑO¿™p nv= q!á¤*$UE]GAÅ"ưˆ¦Þꈓ¾vŒðI µCH‚ª)Y„†Ž¤q[,ŽSˆ1 Ëèlú(ðŽ‘e %DíFBènÞ—Ñ•#†H_\!£~€ª®Ó„5ñYqć#³—v8±q$QGÔ¤X]Ô«¥!‰úÄ}tdQ£Û—…'%›7˜?ŸÖ3gîíBZè@øÀÔ‹±dg£L²b¸ž%Ì]»GA vv& šÉKüÝwÑ÷íÃøè#,÷Üó±c-+ WE®âbd¯—±PˆÐÐqUM– c##Ø/ÆrýgIthe-YBÆ¢E¡áaF‡†°`óxé>uŠžžÎ3g̋Ō $«Õ àÓ’eåJóæá*,DöùívD«õ“™õ¾ÝPÿ µgí§OLÝ^ô‹1ôs¥ ÉEÐLA>úø%Lá ‹G4dQC² ¼g™°d0&¹¼'J…‚j`SUbœCAŽã¾ÜM©7D¶úD› Ù¢2ŒDOÌJ aYím“¼0H:Þ£ÃGóv;âüIå>AŸ`±Æ»= ¤ÆŸ/êºF`¨7aÓ0™½ºÎ|Ô0@P2áL'5'·TVP°nž™3骯g°«+ùÓa±à,/Ç™™i²XÓU/Ö­#kùrü³g㫬4už_âÐå›ë7Y J¢šÊ+o¼ÁG>Ф(æÁgšÚñò‰¯¬Œ_ù Þ’®íÝËá‡b¤¥…´DY%•rÅí&¸x1óþäOëíåÒË/óÑcaq»qåæb™†Y›Ì¾dVU‘½`®`ðKcÔv£á+-Å•—GëáÃt?N×ô;†®ëdΟ?ío$Y,øv¾Ù³hh aûvj~gn.ŸÛ܆Çí2–-cÖ׿N\Óèol¤}ÿ~êŸ[F®ÜÜiÙSgv6…55”nÙBûéÓt:EÓk¯ÑuâžÒRìéé7d!AÀ‘iv“Ù32P\®/¸lh eÿ~Î<ý4µÏ<ÃÙïŸÖŸýŒ‘S§=z”ÞþÙíFr»‘¯ÖŠÝNúÌ™ÌøÚ×32ènldx` Yb‹é:á³gܶÈÎXËÊ33“eºñaõzÉ\¸’{îAòûèéa¸¯h·*Éhõõ;sãèQ,55¦;ú¤mE²Ûq–”à[¸WER @(bdhˆ°ª264„ âKÈ®¡®.é8s†¡®.$¯ÿ¢Ed­ZEæüùdTUáÊËÚžŽÝï'½²OQ®ìlÜ99823“—7yNZ™ÕÕo܈dµrᥗ¸øÊ+ƇÉ^° ¥ WH´u¬]KÞªUć‡9ö£ÑwîœM’K1~Nf´}Gd`€¡ÆF†›šR2;$ wNå÷܃#'‡¡¶6ºNœ iÇôX [fæôŒc¢›0£ªŠ‚±¦§Ówå ¶n¥ëØ1tà kÁ‚iç׿õRºy3™óç×4ºêêhüõ¯ºxux˜ŒE‹RÚ^méé8sr@QÐLLt`‹Çƒ5•ÀUAøBQü6Ÿ»ÏG,&ÒÛËX_£}}ÄuÍ0Ðb1†Þz‹ð{ï¡66â^»öcNõŠÝNÞŠ—/ǰÙh?~Š®*®ªD[[Þº½£ëuû¤ (.ÙK—’½|9U¥¯¥…±pxŠ•‚ ÄëëQÏÃuÿýû,‚ ˜Bø’ÒfÍ–“CLUèìd,¡{ÿ~¯—ÀòåŸxÒtdd F£h†¿ªÊd),À7oéóæ‘‘Zë¼|§“¬êjŠjj¨|ðAÜÉ.¿qQp¼·—Ðáà ¿ø"„Ã8–,ùؾ;7—‚µk)Ù²…®®$¨™LdŒ>ÍØ;ï`--MúHM9–HΜòÖ­#û–[a ³“H4:!>ÂõõD¯^Å÷)QX‚(¢x½ØóóÁã!3ÐÖ†0ÖÙIý»ïâ­¬Dv:§È ‡ÃÌ­\»–¼Õ« TWãÊÏÇâõ"%Ê@ÿê °çÿ´œaÊ‹ÂàaèÛѳàœÛ~Œq C¦ªd+œ0)l1ñšxBŸx˜C»ÄÐGV´’XÓb©:Ö,¤£ª‹7;ûæ¼BÌ¿A3Èïl%}èÿgï½£ä¸ï+ßO¥ÎizBO΃™AΙˆL€A"©,ïóÊ~ïœõ[Û+{ßúhí·²‚mÊ¢– $µOI1S¤D¢€ À€Èi`rêžéžŽÞÕqbF–×AüΩSÕS3ÕÕU5]·î÷~ï5ÍJ EL!Ëf×á€j%éïè(bH5ß?™ Ù¾2£†‘µåxÅHÚdT¿jÓÌ•˜W™ŸÉi!|MÏŠƒ£ƒ×²iÐAµT&Qeå§ŸvÉv öϘA˧?«±׌xfÍÂÚØˆìó™§7Åè7Ö–/\Hë=÷ J<ðçùK§ÓìœB%J6¯—wÞIÕŠ„.^äÐ}÷1ðÁ(.Þúúi‰É%EÁQZJõêÕ”/X€·¾þ_òs”–RÜÞN*G´Z wuÑûúëœñEEŠgͺîùD1g—±m‰XŒá³g¹ø‹_ÐÿöÛ¤"Ê—/Ÿ+fóû©]¿žêuëHÆã\Þµ‹S=D*ÁV\l²k×|V+¾ÆFZï½{E¡Þ^†OœàÂ3Ï0ÖÙ‰¦i8+*>”§C“íÅŸ««±¸ÝS—u>&#3|ò$þøÇ{ðAºŸ~šžG!12ÂȳÏݳÏÚµ(×hä¬V,e‹Q³i©݈ IDAT’ßÏho/ã¡j:<95:Jøõ×!™DR,“òÖDEÁUQÁŒ»ïÆÛÞNp`€Ñ¾>’š–Ãñ8¡çž#¾gB$‚}ñâ«nd’ÕŠ§¾žúíÛñΚÅx(D°¯x*•upOF£xW®Äv½dblŒ‘Ž.ã½½tþâtïÜÉàÙ³Ô®];åyVìv*—.¥nÊçÎÅEÓ_Æ0 ¹3]3ÚÁ Ç0 0Ì6t-6¯íÉÀÀfÃU^ޝ±‘‰ÁAú&™×šïïg|ÏRgÎàY½Ú,‰^ã[½^Ê-"°b†ÕJÿ¹sfÙ/m0±?‘×_gbçN¼wÞyÕ¾ˆ’DI[µ7âinæâÁƒ$ Ri]• $úû‰ìÚEâ7$ ÛܹWí‹d±PÔÖFÕڵتª¹r…p0HB׉ƒôïÙC`óf,^ï5oˆ— ÿŒT,_NùÊ•8kk)]¶ŒÒÅ‹)]¸wuµ ®ÿ­ÀÞx^|ñ‚òÙUË*PF˜ Æ{`Œ ÌÛ…›†Œ¼ Ã ½.SÒ‹‘½2ÆE#gÕ :ºW—sè+QìzŽa"S¦3ÁPÒfåÍ¥ëxkázJªXvö6!JPWÐmÄâ"¶î!¤DŽ¹Ì¸äç–ÝêÇ!ÆÓÍz Ê„ù –‘¹‡‹<´œº€¢¦&¬œ¸=³ŒÔ2™DµÆó¼DqÒ5b¨ G@=ÉWAžÂÿžàtÍ€­ï$y¤[`}‰€Mùf…ñ&Àú—2ZîêjZÀüùœûùÏ9xß}Øü~´x|Z]z²ÝNI{;óÿð)=gEc—.aõù¦¥ïº‘Gr|œ+ûöqôÁyó/þ‚c>ˆãooŸRô-) ޲2*–/§åÞ{1D‘Þ·ßæÄ~ÀÀ‘#8Ê˧,׉Ђ»²’Ö{î¡lÉ"££tïÛǹÇ£ïÐ!<õõÓòŠ’m6ümmÌþÿkY#çÏsyÇNþä'fÄPuõ”Q5¶¢" 0ãž{,[F`ñbŠÛÚ>öàJWÕ¬UF°£ƒî·ßføÝw‰9ÂÉ•+уAD«Õ žÄ:JKiܶ†;ï$ 1ÜÝM,G¢ÃÄß}—þoÅãA²ÙP®ao"* ®êjê¶l!°r%ÑTŠ`_i]Tr|œXG#ßþ6úè(’Å‚%_«×KùâÅÌùÊWÐFúúɶÈ'ø•+ŒþâH••¸¯¡¥2ÛY¾œúíÛíí%44D,•B°ÙèÙ½›èÄ„©¬®¾&3n/)ÁרHñ¬Y8**].Óøõ_ \}øô¾Z3ƒïZ#6|ãƒw0ŒtþaêS>£eq+@ Œ «†´Þ*SÌ? j¾uƒ2˜bûè4 ³3ŽìšÎD…—‹_˜‡Ãˆ¡`:Ä›ö éy:;PFcÔ_Ì¡9˸ï3_ev÷)Ê;Ï0 Z‰ÄElºLlt´`—@tQÜæÁ.&Lçù«Dì-nÏj¶DƒÇÎcQSyf£yb÷¬»»Ž`­Ìd°Þ¬®â³R)v 1úK8¾aüÇ’ƒ\ b îÕÿgøóãã\‰é|·NG6– Øoe7Öo3¼uu¦ƒz}=ÿá8ýÔSDúû)›;wZ`‚(RÔÜLÅ’%57›¡ÏŸpq¡l³áom¥dÖ,$‡ƒ®]»èyã †F°Z)™={zl£×KõêÕ”-^L2åÊÎ\Ú±ƒžwߥqûö)˺‚(šv6ମfàôi†æÊ®]LtuQ¹ví´-3 b/+#24ÄDO={ö¾|QQ(ji™VH·b·ß0Žú†a '“\xåþÃ?Ðñ ô¼ðÏ?DÞ}—‰_ÿšøáøÒyŒ“‡³¬Ìd+[Zéí%ØÝ]@’„vîdbß>‡St×]y\=õõ¦VmÆ Æ‡†íí5…ðiÂdâ½÷˜xí5ì3gb»†O™âpP»v-åË–‘úÏœ)`ÖT`dï^”êj¼×i“·¸Ýx›š=¢cc”-]Jå-·`÷ùˆá(+C²X~{_ºƒÿýàŸ7­_W¿³Ž>‰0xÌ<º×ø»ÞÔ?û#¢Š†*˜e<éZžÚÕŒ–q90ƉIÂö ƒ¥å1Zy– ¢aBòbÊÈ35²Ö ‰2'ý÷ÌÀª'²e91]ºËzMåk£Ò¦ o´¯ãtÝ<ÊNGFYýŸþ{I ƒ—.‘Hƒz0–z°Þæ6;³6 zžMƒž+^æAÀ@ š?ì@QSæÏò&“ÁÒ À" –)$j¬Ä]E|‘2l“–0váÒ3yÇ<É@ÄQWü«¬:BYVîLÄàÃqˆë" ¼¿ùýÌдìÿçM€õ ™¸€Y_þ2v¿Ÿ³Ï?Ï?ø¥³fa÷û§}S”n­Ìäilx˜ÑsçèÚ½›Ð¹sÄC!‡ãú±,‚€30EýŸû±ñqzÞy‡ O?Í™§ž¢|ñbSœ;•öM–ñÖÕÑt×]T¬^M¨£ƒ¾}ûøðûß'‹áªªÂž®ýÈŸËEÅâÅÌÿ“?AE†ÏžåÊë¯óáw¿‹ÍçÃâóM¹ A(ji¡aËTਭ [V·ÛÔÊLÃþã†bÓ13esæÐtûíÈN'ö²2¢É$ãã$4ÔÄÑ'é%œ³g›þK“þ—$‹…’Y³˜ù…/`«®&88H°¿ŸTÚL3>kƒeˆškÄaÅùZ )–ʳhHwj:jÀÎÐ=Xõ„éo•e°ÔÂù¤uI«•‹µ­[°–%Ï>IË-+Xõÿ|š­[ …BŒô÷VU´-•”ßj`!5ƒ•Ñ]iY=–œž‹¢NãáNµ° ±p2² –PHÖXI8Šù lLº®GÏÀégòZT3Ç¿ Ô= $@òXùÛÏcðpç@^£ÎŨÎkƒ:÷uÀÒ"«(àžæ³ÁD?ç_z‰³/¾ˆ–Hà(-ýÄŵÝX…wP³#mÁšï¸ƒŠ¥KÑS)¬^ï”e z‘Þ^úߟw¾þuN>ògŸ|-‘À^^>¥‚ ŠÙ’PQk+## 9BdzÏ2vaª¤*ˆé¡úÛnÃÛÔÄèéÓ\xúiz÷ïG7 Šf̸®÷SÖ.cͪ׮EOž¤óÅé}ë-‚çÏS¾téuÝÏQÄârQ·~=K—Rú(©‹!‘À1wîÕçÆb¡bÉê7m·›ÁÎN¢ããY†!zþ<Ã>Š1:Šìp`$`ÏlG¶Û)7Ê5kŠŠîê" ™€¦‘!üÎ;øÖ¯G¹È$ Wy9[·¢Ë2ñd’ñ¡!tQ$51A÷[oºr…H?%³g_3^(“ùè®®ÆZT„h±äô–¿íurü8ô3³¤—ˆAç£0~´ ”,-d®Î%úÔýè£Cš©52T#C8ú(ÂÐI˜}ê‰SôýÓwMŒ’ÈhÒu3\ZK»]Š)sºƒ•oÜ)΄‰—@œH¦- õY˜áÈš Â˜‚ª…¢ó•H‘B"n®Ë˜ŽêZ¹áÏ5”¥< …,0Ècµ²ëбF'XôÄŒØÍâ?ú+\4lÛ†»­!]çâ§j˜ÓtÅPÓ®íùú+#ï= MGó-êß¿d¬ki°ò&Ã* dR56’Ž`{ÿ+–þs9[ƒ¨Câ-P_¡ä9¿UÙÐ~ÒÙ“‹JƒAÕÐyì  'E–OóÛâvS6gZ"Á‰ŸýŒ‹¿þ5¯÷Õ1`]‡ñð56æü²nD!º®O‹m{q1Å­­4Ýy'åK– ‡éyã º^z‰š‘¬Ö)=ÁDYÆßÖFã¶møgΤ÷ðaúöïç³ÏbhŽŠŠi¹í+¥sçR¿u+®ÚZz÷ï§ë¥—8óÜsøÛÚ°—”\w_òí2ê6m"3tì£'N0ðþû Ÿ9Cq{;ò^ŠÃÅí6¸ðúÐS)úÞ~›Þƒ‘D-G™"SSTœT®[Gé’%LD£„úû‰§èÑ“' ïÞMð‘GðnÙ‚| ÖÐæóQ³z5wÜA,™d¸«Ë´SH3Záwß%¸c‘W_Žb¢Ãq•9¨ ŠØKJ¨X¶ŒÊõë1ìv/^4ítH_ý¯¾Jå½÷¢¸ÝÉjW.]гªŠñÁA\ T¬YCýÆÏœ‰½¤Q–Íkßbù·9)‰ÆËßE8õN^Ž ¼o‚(€³ ¬EÞ²”øàŸʂ¬t©n艧‰¼µ‹¾c§Hp5ÀÒtÐÓÀH̰YùZ¬üåÄ«`üPºC/QØa˜´DÕ ‚6Ó%þÛ‘^Sü‰ ¦RiM–ŽQieô‹õi”X² ¦A”–Õ`e"l²~h8Â!æ=ú46QeáŸ|ÕlÈe¥¥(e ŠhoèÁ"$Q²9“­ô‚èÉ"xA4HyÊÎfT."§pÂb¬dµƒ”³Œ;©Â: `%žü=¬ ›´IÇ]@⤞º@j05Zÿ€õø¥K]’Y™þ¬—¢:{G@5Dªl~Ë”7Šš›iØ´ Gi)‡¿ÿ}.îÙCÙœ9f„Û Þ y`M£ r£¢íÑ3gè{ï=´DgYÙ”¿/* öâbJçÎeƽ÷R2>‘¾>öõ«„/^D×4ŠgΜ¬)esç2ãž{Pü~úåü³Ïrî™gÈøåËXŠ‹ñÖÕ]ÿâ·XðÔÔÐz÷Ý–,¡lÑ"ŠgΤtæLtÃ@q8>qY~W]#§OÓñüóø«¿¢3ã+ÖÖvýã"¦Ac#Õ·ÞŠ§­p(Äøð° ´’IÓNáÕW’Iìí툓¶'HŽ’·n¥lɪJÿ¹s$5ͬ4E£Ä.]bèû߇Hßm·}$¨wVTP»iEsç’ÐuFzzˆÆbLŒŽÒ³gry9¾––«€c†ñ,nmeö—¿Œ¿½ÀÒ¥”-^LɼyøÛÚL—ì+ppò üóŸ!h׸á¦TèÙ—žI$þæa_xÞSèéß7ÔÈÒ5`"ˆM饸5EJƒ±Äãi`•XªzÐR“ʆ“ŠÃ è;”Ö6¥­¤Ôd+ÓŸ#hƒ° P½üÏPŠH™í˜L!D£Ébµ…à—kQHåJtY¶*ÃXi“Ö©9 †J…Ö‹°‡ò™·0|ê}ï½G°³“Kö¡7öÐT1ˆÝ/,æY1ˆy݃ %æY8¢’T©<Ö›ªLq{Ʀ!¸«Y"LUÛI9ÊØ&Ô,]‡g¿ŽÊ§«Ì\ Žý¤Aò‡ Ì¹í7XOw/`s¾_Fö3ë†ÎރǻAÊmESøKV+¾†š¶m#:0À{ßûçNQ:k·û†ýþ¼ °>ÉàQ’H†Ãºï>οü2uëÖeKS‚-YÆ×ÔDõºuøçÌ¡ó•W8÷ÄŒž:E`ɓ阘ZÜnªV®¤rõjtA`ðèQ.½ò }{÷b ¦í+æ(+£jÕ*jÖ¯g¬«‹K¯¾Ê•_ÿš`Ge  Ûí×ýL‚(âkh °`¾¦&|Í͸«ªnHpeèz2Bxx˜”®“ ßµ‹Èž=ØgÍBœÄ< ’„¯±‘Ú[oÅ?o„3Nîé{Løý÷TßêÕÉ8 ¢ˆ·±Ge%ª %#9„:;é;rÑbÁûú.W&n&££ú÷`ÿìK¨WÐQ%猞?OÆ gôïAôèÄ.€‘0×g,]#“ç›?“$(i€¢J¸xÆ ’Ö4déFz®ç–I­ì~äíC0 —Žâ.A)iþ>ª€ š Ø‚6ˆH0®¸¨¾å³ˆ¢Û”6 ŒÆ?å15Väi¢²nëÚuJ„†MÆ·ÖAëê]çßçÔß>JߡРt)…ÜÔCµ7ˆÝÇ"§ €T¦$(Mrpϰ=¢ c&¤²ÅTé/ðÀÊäŠFNìnXÔr½ÒJÊQÎ&¡®`éññç¾mž§ülGõ:%Z•´ûþnPw€mËG– ]G‹FÑ“ID‹…¸ªñ‹î3¹¬Å‚fBãT ¤a°{ÈàÍaø|µ„HÂÔ@«|ñb*—-#ÔÑÁ;ßú¢$QÔÜüoû r`Ýÿ»‡b·ã©­¥åŽ;ˆŽ²ïoÿ–pw7žêêic+%³fÑòÙÏ"Z­\Þ¹“cßû¢¢àmnžV”ƒ»²’æ;î ê–[LVáÀÎ=ú(£§Na+)Á;©Íÿ£Ø(G €½²gu5—÷í#Þ×GϾ}Hv»Y˜FG¨dµš´õÖ¨ iDz{é~óMÞŸñÎNÀ” 2Ë8.X@ÓÝwc {ÎoÀ5aîùã…¢vô«º±‚Z® VH$UTˆ5T’£‚z¿þiè¼€¡‚j¤ÙÆüó=©,[8E!Õê~pÿaÁu¤%“Dûúèß³‡_ü"g¿ùMœ••|ûP7±Òh–ýË–HE-Û9™Õ¹‰9Gû¡¤Î·:z“"›J…)½³2’“š[n¡aãFξø"üàؼ^ÜUU7к °nDY¦|Á*—-cøÔ)Þwz*EÙœ9Ó~R—­VÊ—.¥úÖ[ÑR)>üÁèûm’–,™Ö6<µµÔoÜHÉüù Ÿ?Ï•7ÞàÊÎ ?NÕ-·L ÖD‘¢ÆFŠZZL¯©9s¨^µÊû|Ó3‘½G2áÊÞ½üÆ78ûÄ ¾÷V¿Ÿ¢––éi§“²E‹¨\³ÑfãòK/Ñùâ‹D{zðΜ9-`b+.6ËlK–Ïè³¢Q³{_U{á¢ï¾KÉ—¾tUŽ_fT,^LÍúõˆn7ÝÇOÇÝ ½÷ÑPˆ¢9s®Ùá—¢«V¬ |ÉŠçÌÁ?kÞ¦&\UUÓ~°ø÷á¯ý ÃçÞ')äX%]Ï1âdtFg¥£,5=úD\éט2,—þ2ÔAp‚£é÷K¿§fzÊìG†eA…¸ú“0Ð{ueKÅüÓ"K7`Ì! žš¶ü>¢ÃœXN'Jyçk:©+ïÍr6 ùÂì,@¸*CP§V¼B«|6ËjE*F™ðGpíXÔ]x \éèÈ¢Ž,i9VGÈmKÈfšS_¸’gŽ}Ž“³8«´2'q·ÎfšÌ•¹ÁÃf2XR¹HÌYDZ‚[È=ð„v<Ñq]71“žwž-7eÏ·>iY¤j(þë¶Á <ð]û÷“‡é}á:ë›1f{rì\~Îbæó //­¡áð8¬øõÿGÓ²ÅÓ¾¦­^/õë×ã 8ñøã\ر_Ú£ð&Àº9~'K@©‰ ¢CChÉä´Í,AÀQZJÍêÕÔÝz+ç_z‰Cßùβ2\ååÓ µNHÖlØ@Ãí·êìäÄÃsðïþŽªÕ«±¤ó³® ÔÒv3¿ô%ŠfÎdàØ1z÷íãøC‘ÇYY‰£´ôúÿ´%íí”/\HñÌ™¸kkoØ:¿®ªÓ*é ‚ÍZ¬ß²…Èð0Ýo½Å™Ç£{ÿ~\••x®S˱Ž@€êuë¨Ú°d$ÂÅ_äØ?ÿ3‚¢`+/Ç~μÉl£«¦†š­[)]¶Œx^رjĺ»ݽÿ–-(×èÞÍ<W._NÅòåÄâqÎC.)ÁH¥èÞ»—+P±x1’Åò‘Œ–âp`õxr™n¿«¬¥a0þä“t=ø?‰$b¦ÓA†MÒrsT“E¯a*J` €s.ŒT( ¤Ryó ‹•ÊÍeª`x†‡ó4YZN›•a¶ÔÌk&(ÿÊ_c½ž®.ÆÃa’†A"½K &›SJ‡„£0ŠêiÙþ˜Áö²Œäñ WT Y,ô9vRUÒ—í"”³¢v5«ÅÊX4dØ-EÈ­SPMK:ƒŒjnÇFéCU—Ð6, \‰1“!Ô Õì`T$E*´nÓ“$˜ú®ÞH{—“­tZ›xÑs7J~m”jµ; ø„4Pà Z…Œ- s5`‘êY™X=?˜Ÿ>€3Pu“ùË”lõ<2«…+°pÈ[ŽõlïªÜµ$a+*¢vÓ&uu uu™Ùœ+–"ÏvveNŽ*Цiy¿c [EþÓg¹üäã8\UUÓºoˆ’„¿¹™–»îB¶ÛÙûµ¯1päîš%%ë¹›ë™v÷±‹ vv2p侯Æi3Q‚(b÷ûiÚ¶Í|ªxâ .ïÝ‹½¨Omí´·á(+£vüÍÍ$ÃaÞÿÖ·>M͆ ÓÒ6I esçR¿iÖ²2ƺºïè`¢¯{i)v¿ßŒQ™b?nÔ("€à… tíÚE÷Þ½`×t ¿Ö1q4mßNQ[±PˆË¿þ5gŸz 5ÃLi»‘Ó®ª*ª×­Ã;c‰Pˆ3¢¥RS¦mÜX7Ç¿ýX–)›3GI ¡K—¸°c¥iêéÞˆ‡ƒªåË©X²„áãÇ9ü£aè:þ–¤)JuùO&%sæ0>0@,">Ánùj,F÷ÛosqçNFNÊvÓL×2£¸µ•ºñ·¶òþý÷ÓùË_218HÅÒ¥&à˜Ê2Ãå¢zÕ*ê6oFÓuº^+;wÒèΪ*\S„kg·ãñPºp!+W"¹\œê)®¼ú*gÏR»nÝuÁO&ZÉ×ÜLÅŠ¸›š,]JíÆ4lÞŒ­¸‹Óùñ׆®ª„OŸæøŸþ)½<@üäITMCÛµ }Ϥ3g°nÙ‚£¢We%j*Eé’%TnØ@ýw⨫CM¨DGI%R9p•Öéd–óçù@KÓA¯€Ó§rå§|Û…l‡¡fþ¾¡AD©m9þõŸÁ×ÞNÉÒ¥(/‰‰8‘ÁÔ¤Š–_ëéaÜ€Èå.ÿÃÿm–:£Q‚çΑ‡Q“IÆûúëë3Á•aÚxÅuH…c$Â1—›%þçÄ‚Ad›æuVIC44PM𢲤eˆb5™Ý’ѨïïÂÅ%tSg%æ|³DCÇÞÂ>Ê+C+,« èÈ’)„ïŽV³w`mVž™2,V¦¤Öm©æ}ïÊ˨wwÑèaijInÀàÇzu,Œ¦¬dLå«ìk½p}¦løß¿ðu^Yt'W-#XäÅõès¤~õ*;vàÚ°ÑfË6“œíþ€¸Ò-ØSä‹úÉ·®Èø|AÜnÇjO2Ûs µÆÏø¦y$½ìÏÑ÷ë]ôì܉³ºwMÍ´#£$‹weåÇ\ÝXŸ°aq»ñ·´P¾p!‡øCƯ\ùc€¥¥ÔoØ@ÅâÅœøÙÏ8úãã(.ÆYV6¥€]”eì~?Í·ßNÛç?oÆ jo½•ÒY³p”–^×5ýÁ6 |ø!|ÿûìýë¿ÆPUÓ{©d®Ìi{`Áf~ù˨‰gŸy†c?l–jÛÛ§Î|”$œee4Ý~;·ßN<áÊîÝœxðA‚.નÀYQ1åy% ge%µ›7ã™1ƒ`W_z‰#>ˆŽé[v½/KÙfÃ[_OÅÒ¥”Ì‹§¾{i©Yšþ˜ƒ«‘S§8÷裼ÿµ¯Ñ½o©T*«KNÉáaÔ÷ßÇøö·±56RüùÏÓtÛmÔÝz+ ð¶µá_¸ïìÙ(þb bÃ!’±TNt®M²UÐò­4€Jx%Fªo3Ëu‰Döý5Ýd®2¶ R¼a‡%Hz|x—lDñø°•”P¶|9¥Ë—c)-#COM‘Lj$ S¸žòÑöû&À’GYÝû÷Ó}à‘¡!’šN4%‰€fs ¸‹q”Wãok§¸­ A–™÷•¯0¼ª…êä!l¤Ð0Ðt£À÷I´TÈ0Z™a¾•ƒŒŠEHQ}©ÇX´P®š±=Š¡b‘R(b ÉБ/…Qz#ÙT¡pYK£Svunål²Í,Š:¢”Ö)‰Fž^Éœ¥¯Fn£ÁÞEÊÛŒU¶ã>u #¬’PUT› %@öùÑSšH § P©és:©L˜Á§ç¿øüçЬ2ÑÊ".l\Êî¿þ}Ç/ >Kü¿ÿRgÎàÚ´ Ñn§£ç IåòG‹ÜÉ{M¡È] a±a³&˜ï;š³Š YÑB÷_} ½/Hôr¿÷ —÷ìÁH72LGóùq7Ö'ñf.IT.Y‚Ó{è£.PÒÖö•U%%4lÚ„«¢‚~ô#Î<÷‹M ¤1o}}ÖŸê“ ®²ÿŒŠBù¢EÔ®Yƒ#àÀ·¾eæÞut˜ù|ÓŠÃAÍ-·˜v##~àÞ}oCîššimÃP¿q#¾3÷÷sùÕWéÞ½›`GÕkÖL[Ëg/-ÅÓÜLço`ã]]ÄC! UÅרø±îú—2•##œß½›p(tÍ”¬ÃÂ޽ǎ!µµ!YR´X°WUáioÇÙЀ®$'bÄFB躑c¯ô<+…|VKƒ¸ÍÆ‚ŸîÇ7{6}gÏ(°RȘÊ)ó¦±ÀHþ•[±W›¾t‚$a(š5 wË ‚‰…'̲ŸÑDŠá3XKf^'P¾p!›7Ó°y3 [¶PÔÞÎÄè(¥‹Q»aõ›7Ó¸e MÛ·S¿aþ–¡_ãü‹¡¢Jš‘Î44H‹ÐÝ4þ”%Õ¢£ú9¥AVù¹c1Í(°70Ù,Ó4ã§Oº/#ĵœµEúo²Ëš€š’øú[ÿ/BiÎÊàZSpe^#¼6¸3C,ŸÂÖõcûÎ᪮¦rÍê3Ê[oÅâõ¡Æ“ăh)-gÙÇXØm¤uxîÚ€f•s¬œ sìî \X>Ögw£ùäÑ£\:q’+EA_0k&š¹çŒˆÞóÖ!B\±c³Å™_t4 l³Æ¯¨Œo_Hhõ,Æç4`{|ƒGŽéë#Ò×gVT¦Y ù8 Á0 ã&äøä]Uʱ‡&xü8‚¢pË·¿MÃöíø¦Þ„®“ŠF>y’èÐî´Õ†sšeÇßiRJ×I†BÄúû‰õ÷#ê:²("ŠÏ‡sáÂkþ‹Ñsàï}÷»Œ:##¸;àœ€+³l³á^»Ë_ýÒš5wÌ M#ÚÝÍÈÁƒô¼ô#ÞAèA!…E›…ìܪ€MÅHŸú=šÿüQâÁ §ž~š“?Ìĉ84 Oúý=€M€°Fý°ü§»(]¹1 úÞ}—®Ý»¹ø«_1z䲦™ŽÞ $%0R•63ÿOÿ”Æ­[s×z zgcXu49I,ü{ÈÎ/`-ZU0ö™×ÿ3®÷ŸFqkDŠR.Á* 8[znìØÌeÝ*‘,ı‘0¬$ *2É ‹_|Ã. ;ÄÜÜ!`Ø §vÐlá˜^êBŽ'm 9@´ ˆí ÙD;è™ß?új½ŒªÉhš„ªÉWM™Ÿ§4%·¬+$ "Oܦ2+¦¾rGiiÖ—-zù2Á÷ÞcøÍ7Þ»—xO¢:l‹ «9Yl §ç~þï ùüı™ÇkvYÂìÇw±ä±WñÆ ÆþË|Ü3ä …¤n!e(¤0÷-¥+$ «yüt I,¤P²ûlôZ+±ø’|®ùâØˆa'Ž(Žìëv↕º³*w•”Ta/.Î…¢ß`ÚÚ› Ö'|¢ˆ«¢‚òE‹è?r„ÞC‡­Ößè&.Ê2þ–6nÄêõ"Šâ'>ÃOE¼uuX½^Žå¯ÞC‡kë”]˜‚(b+*¢yûvJfÍ"ÜÛË<ÀÐñãØý~|MMÓŽ»qUVÒpÛm··Ó½o‡¿÷=âÃÃøš›ÍNÎën@0h-¢~Ëd·›¡“'9÷Üst<ˆ®iæÏ¿¾€=mÉà®®Æ?c®Š ¬^ï Á^…/_æÔOÊÑú'N|ç;\~äú{Œ¡Çc|ÇÔînœ  åYMdއ¯±‘Ö{ïÅ7kÑ(gÏf¬T«¥ª*ZGúc!y½Hy‚(bñùp57ãioÇ(GM¨ÄFB$#ñ ‡L§™¦›ì’ÑÔFéºÏ ÛíT,YBÕ-·`8ôž=K<-`´RiV"‘¤öö{ þ÷=55X<,EE„úúõ÷› œÅ†µ¸ gM¢Õ†šH ¸\fÄ’¢@*—ïCÐTDÁÀê:Šâ܃ õ!ˆó "^B'^Åzá:1)×M'è9]T>eh ‚é%©ÙR–ŒŠEJRúæ°)ϰXª¹-1]îCÑБ4ä‘FDK3WBž…iá`h k¿Ž}±Èdx +Á@(`¶Ä<} ‚Ç%ò¹V™JK:yÂáÈZÍXŠŠp64àjiÁZZŠ`µ#Ž¢«zޱÌD!¥5u¾´ìbž…–í˜4‘ÞÅmùìfÆ‹}”VD(qg3E1ÏŠ¡À…>/:'³^4ˆ‹6ì–‹KÞÏ5 å‚¸Óï+ £% êì6ׯÃUYiV1n@6û&Àº9Ì/Ê´Ù›·¶àùó8C]”(I¦qã ®R$#äiŠÏÁ,¥Ö®]KÓ¶m 9ÂñGáÂŽT¯Zev½Mƒ/jj¢ñ¶Û¨X²„s¿ü%gžzŠÞwÞ¡lþ|¨LãÉ6Åíí4lÛ†»¶–ÓO=ÅÉŸüA’pWWOËˆÕæóQµr%Û¶‘ŒÇ‰ îéab`Wyù5mnô!Ûí8++‰ƒŒ šfšÉ$)à >xгϢõô`­«CžTBe™â´•IÑܹ ]¹ÂØð0IM›œ|cÎßz ý§?EnoGp¹ÒL±(ËØÊÊ(š;×Z%¥h:Dú†H%54ÍÔî¶PHè0ÞÝ…»n&Ž&³£ÌQVFõ-·P·y3£}}ŒôõO¥LsPb œ=M°g”À‚XœNÓ4wUµl-Ÿú3¿øE4 |éRê7o¡å®»h¾ã6nÄ×еÿˆù,ÊhgÎSô0ç@¸âjÀÂØáXÏC'& YáþdÇzòb€LÕ?ˆ†Y6´Š)!……¾c&¨Ê³—5# º„”i0*ÑÓI´CrñBiÛ†Lg¡®‰ì‘ïDðå2 '—3]…’hÚˆùxÑÀë•Øð‹ð‡Æ‘ÜnÄIUQQ°––ânkÃÝÚŠ¥¸Áb#6"I˜@+ϲ!êô0ôåvD›-×)äYR¤KwXEúæ4r¶²•^GíÑÓXD˜Ê·i¸jŽù¹X±+1–—Êvcš&°Ú5^k 2ÆvaÉ ýýp`Ýl…âp˜™P••7uQ“ÆØÅ‹ô8@çk¯švµ(Ë8ËËi¾ývü3f0|ê{ÿÛ#Ò߯¾GYÙ”çE¶Ùð·¶Òö™Ï`ñùè|í5|㺎3˜6ãhq»)_´ˆÆmÛÐu?ù çžÞd¢,˜8f„ð3æ;ï¤lî\Ê.ÄæõšŽèó§PC׉ :}š‘“' ^¼ˆÕçCùˆ‡Q–±S·q#­Ÿû¥Ë–‘ÔuÓ™>Í%ÇÆ8ÀèÃãœ?{kë5Zéœ94ßy'†ÍÆPw7áP誈9UUIŽ’züq„C‡PÖ¯GÈ´½ ‚Ù,Q]/ ´$—›d,Il$„KeV ˆ¨Iü¶ãkWðy’‘²ÓÉðÅ‹ûû‰§Ø“ÄUƒñ ô;FÕŠ…-÷‚€%mÒrÇT¯ZEùâŔ͟·¾[Q‘y¤A¸~ø‘CC9p•çÕeº aˆðÐy†víÇs¥]0ˆJiIÄ`]‚l:±£ X«”Äb¤pü•+VP·a=‡qì‘G8|_CÎ@`z†€N'îêjì~¶œñ±g)#N>þ8'þ×ÿâÔCÑó‹_0ôË_2ÖÙ‰oÖ,d—ë#K³ŠÃAQK ÕëÖQ4g¡‚}}¤tݼïkáÝ»ùe|[¶ Z,Wå-Z\.ªV®¤nóf’@ï©S$5 Õ0®Â!ÚåËh¯¿ŽÔݼf d®AA0Ϋ«ñΞ³¡ÙáÄâp“Ž›ˆ‘Àd±‚'OQ}û½ÈGösÙ‹‹)jn¦béR,ÅÅ ž;G\ÓÐm6•µ¸±¸Ýéëè£Ê̲Պlµ~t)ûÐCCéöE®,Ôí0°gí¤I ¢BƒU004P‘WêËÌCË(‡PžO!&óʃi‘»˜¶£Ò¦¢2DUFßM˜lUZDžoÕ€. k‡ª¶"ºòT "¯\8iˆàöXؼÖGâ•ÄŽ"ºk‰×_Gôx°¶·_õ-;تªp··c¯®Fv¹Q£ âÁ0zB%¹¶ ÇjÅôùºfÉn’~úõ­”sîVÜz8 ²r¥Á¬“{¾È]0dB³â”¢¬,'W¼F‰0÷^*I]g¶8ç&Àº9nŽi¤¢Q¢ƒƒè©Ô´óÁôd)jj¢íÞ{±¸\ìý›¿aôüyì~?®éDB`†&æÏgîü‰±1N=ñïÝ?®Š \UUÉ–äGI uë×Ó´};ÁŽ>üñ9÷óŸ#ˆ"eSh¢ ˜µ@€Y_úeóçìèàò[oeMJ§ Ön¨/D«•ÊåËQŠŠè=z”ÑŽ"ÝÝ÷ï§çÑG‘=œ55È×iâüíí4~úÓ8 264DRÓHF£Ä._fðŸÿ™ä… HŠ‚m²écÆ.cÛ6n¿H<ÎPWÑt¨uþ”D?|E×QV­Ê,ÒQQ ¢×‹¦(Œ\¾LïÉ“$*q âÀøàg^~Òù p”•eYÉjÅ]UEýÆ,ûêW)3‡ÀâÅ4nÝJë=÷Òrûí”/Z„«¼ü_¬cýGöþqlÜX*¹Rá¤,EY2°éX?Bh)ƒx·˜-Ñå¦4¸Rú X“u ›¡"ª]FyÇdô„” f¦4àJ¨¥Gìã° ƒØÐ£gÎ0xô(Fš¡™Îñ¨¹õVlo½EJÓHE£ îØÁø£xÙ²ënC¶Ù(7ò•+\.;;‰†ÃYÉPôÄ Æ_yku5Îyó®Þ€ à,/§aãF<­­„íîF5Œl%,(ÅÅØS)l÷Þ{U Š®i$ÃaÝ?ûö ‡IjZ‡•Ð!1>ìv›ºÀè,-nk£lþ|ü­­56b/)ù­XËàÛÿËÁ_!gÀ”6‰½Ê/÷å Ø-Õ:žù©ˆuŠ  9–j²à=ßÂ!Í`ÙQ‘ )hCÚϺ²gMGÓ'GÐ@4L@A\£gZän¤ÁU–1ËX%ˆ_°Ñ‘6ÞÌX1p}›†¬]ƒ‚Œ@?×Ρn –ó½X‚¨ÀÄŽ$Þ~›K·‰Tø_}©¤›œ 8›š°ø‹ÑÚ'P‹£ÙÏ!‹¦À\Ì2YF–ÑÊg™r,—ΪÐ;xÕq“i#ǺIâwQ2ˆ'l8Å n©x;ç®?‰›šo½õŠ­+¢ý曩X¾œt*Åd?Z.ÇøÓO3þðÃdÏŸ'´z5rIÃ¥_wU ›7S³~=‰éi¦GFÈf³èv.VL®” IDATì®»H=Jå»ßp!ñËÇe¬^MtÝ:â±Éxœt:MdåJ¼ÝÝZ[;q‚ÉÂ=7üuu,zßûhÙ¶Ú«®¢zåJÚo½•Ž[n¡áÚk ÏyáW}ÎèYø‡.xõ.ÈM‚â‚`Û%/šÝ·Çžg‘²ÌOWÕ.¡h]BÙ²3:É ¤úE½è*U¼J£¦ŽÅ!cN‘2U¢\™öªC¡DÁ²‚K æFDÆö1…Bȧi+h/WÞJfcÑq‰(†Ö¥b@˜4G ª(C¢-ÊñÞˆ–V ÉSïn—Á°y”Aá8qaŠ¡ L“؉¼z|zâ稡!dwÊ2ð¦ý™ÅÐUQ+ö ÎócÙJ7Xß‹_È`Þ%åMû¶ª%I:Ù¤‡še™ûVö¨’/ÔF+T•ìýZÕòÖßøûBff†?ý)}>ÈÐsÏáol,dŽ• Ve¼Áp…ÃÔ¯[GíÚµô=ô‡¾û]~?¾ÚÚ+VÍû@oh yËøú×é{äª/FY`Í‹ ŠT.YBÇ-·à¯¯çôÃsâ¾û0 Ã*;^`‚ziHãÛ s =ÿ<#/¾ˆ¨(VÑókùÖwEÑÞ^Úwì ýöÛÑL“±#Gß³‡Ó?ø’ÃaUñ\nD,„ÛÚh½é&jÖ¯gèèQ’ss¤b1&_xáÿ˜ÜОæfœ—i3ÍÍ4mßNdåJf''™·ªQ€t_Ó?ý)ÎpϲK›=••4nÚD6›ÅôxðõôY³Ï¢Exq„ÃÈn÷¥Õ9ûþ¨\¼˜ª¥K‰tvâ­©±âU.gH_Ìñ³ü“E‚†_‚³ù þj= Y_Xfûö3øÿ/Ùù ViÅ¥V^ð³ ™é½â<f–fb•4‡¡áBÅáva¦"Hÿ1Ž˜4æ­ÌÇ5 aUå˜:’3³>Æ犪U‰ ¦{Èn"*%Q BIƒp±kÞ*B„ I{ðtäÌ‹4¸f ÇnßB…'KËâÔräŒæi&Å*„Á…+"ÒÝÍxß ¡~dY³â'ò)õšiç}…z!Y,U®JŒèšÎUÉ}Œøü꜒U…yUK–t² ŽLŽ.é•bT†":QµÔ,A+Y]¨á9q’Ð=w@ýZÝ ,ÜkhÙ™fÏcò•WÐU-“Á\q_Ùá ØÚÊt_‡þùŸyùÎ;1u`k+Êe²” Veüª‚–$á‹FéܹoM Gþõ_øå/qx½Vbù_t’¢hl¤}ÇŒ\Ž}_þ2cno_ÿGd·›šU«Xú‘lnÆ]Y‰–N/8 þíŒÄð°5J½ãžÿÜç˜>uŠ;*ârž ÙíÆW[KËM7Q½f 9Uexß>Îýìg >ð56à­¯¿,É’]."]]ô¼÷½8£QbCCÌŽ‘™eêùç9ûïY¹ÿ%¢æÝÛßtà 8jjHÄãÌØ+]¡¾æf½½yªò$ÜáóѼe ‹>ð¼zzp54 WTàŠDT;"*еúõ ú0Ñ¿ôÄ3E"”IÃìy8ò ÈNXÒP¸‡Ìù³Ì|÷›xàH[‡,í2«ä¼Ìy©}âÅ~­’Í´U*‡©ã2Uœ>/ô¶=>‡q8…”³J­-¢e‰–a‘A’Z[˜› ’Oc¤µùyX:Ìuu¡n ÊFÉêÀRuÁ*Q±É2º„W²¨_àUÒdÝãä„§›a¹Žæä9ÜZÑ0Hcã T!‡¨8©ô·hu1{î爺YØ„¢%䉖aXa¬¢ÕÝ(•*LšÆšÔK̹b´=*,æcÙ£CY';çBN©´Ç ñ¥DKtù¾H4$UÇy>Žû…A„C߃‰ÃÐ~#8¼ z¾åâq&_}•£wßͯ}Ãßøgÿã?¨X¶ Å뽬ECE·›úõëi»ùfô\Ž—î¸ƒ³=@åâÅoHuO™`•QÆ%no§uûv\Á {¿üeÎ=õ×]‡¤( 6öJN'Õ+VPõÕ$FGyé«_%‹QÑÓ³`UL”eÂ[Zð×Ö¾=U)Ó|]ÿ—§ªŠê•+‰öö’Åص‹¡§Ÿ&ØÖ†¿¾þŠJ¡(I„ÚÚhܼ™ŠåË™èëc¦¯¡Çcòùç©ß¶ A–/û8+uëÖÑ´u+Κ†%“N£i»v1þàƒD_#Š¡¿ŸŠ%KÀå">=M"'ÐÓc¥ë:9I²F¯qÿ‚€§ºÚúÖý[ŒÉ0Õ,Üâ@ÿ¥ãFÀÐ.ˆt¢Î˜Lßu7¢ rÆÚ•Kïw©Ó’Mq›¤ú²cº;#kž‚eXË£k8Caôæ¦vÏ‘<$ÍDV/P²0M¼\k[‘º¶cAOfQ§˜ªQ0¹'Wt m  ÕE1 >çÐAMLŸH»yÉ4DYÐ fóR•’½ :H >š“ˆ†Š:aœaX8Æ€p„š™Jâ'GÔ D{4XØ ãÂâù#¼¤#rKg0ã–9^0æ‘+Q0­´{Ñ&XÓ.Ä„FC¶ïÒ›‚Ý©ˆJFCÖöåÀ!v¡7dcP½ -‘aêþäwâÞ´É›—<Çe— }½ÕŒ!Ë >ý4™óçÙµ ]ÁŽŽÙ<Ü4nÜHíÚµŒ¼ô¯Þ}7ý?n-|úOÖ÷” Ve\FñwtÐuÛm$FGyú3Ÿa¶¿Ÿ`Sî+UÌ”ÀSõÕ´ïØÁ¹'žàÕ{ï%ÜÞŽìv—G~@:ctÿ~Rããø/§ ]@<MMô¼ÿýÔ®_Ïè‹/²ÿÿ‘Ø©Søêêð. >@q»©\²„%ûr8ÌäÉ“ >õG¾ðÐ4d§_SÓ‚Þœ;Þõ.˧mšdÓiæ8ùÅ/’êëCPD1\HÄkV®$ØÕ…R]»­ðêÕ:;qú| Iˆ¿F#|“ä¿}Q1b>n¡TJ§àø½Gï&‚ô$i0ì}¤<Ñ*U´ yp©h{Q€Ù£¸„ÂU¢ 8L ¯ªá V`´¶3¼k‚éÃã…«3ur&’ ¢j’ ¹™© ãÕdènóåñ­¸wc#2êtm6‰™3É®oA]@’ŒÂv¹˜†BTƒ­n ˜^‘Žôi$Û.aù¤d¡Ô€n‘UràÉ¥é™:a,Ë3e)’Æ'ÂÇÐ ÁÓ3ˆ9Ý"Qù¡÷%èFáwk|hJEЬëU5Z‡OâRS)’t$[]KÔ+YБì”aF£fî\ÁGg–<¦¦Z<Ï™S†4rÏš…Ñ®97Špv7ìù¯þå—˜zìIâ{ÿÒ—ÉéD²KÃóJ”+¦áÚké~ßûPñ#G8y÷ÝôßsîŠ ¼ Wle™p{;Ë~ÿ÷ ut0²?Ï}îsÄNœÀ‰¼®Ùe‚UF¯çEâtR¿nÑU«=xßþ6Z&Cõ²e¯ëÛâñмe µ½½hé4N;ý¼ ËWuäûßçÌcioÇ}Ó…¶¶ZU3ÝÝœüñ9ù“Ÿ0sú4m;v,˜¬E׬¡aófDŸñãÇ|ì1FvïFp8¨\½úŠd͉Ðzã4nÙB£«œšbøÉ'™~öY‚ÝÝø.·àA46Ò´iÁöv‚¸¢Qä`ðMO®r/í%µë˜&…P1Ÿ”~Á¦8¡¢œµ É03lµÚXÇ&g¥²¿Æ¦Aì¤)Œ £f1ÂA0L¦Ž/kବÂìl§÷(“‡G/[D $Õd²»†¾¼“ñŽ::ç$İ ×Êx;;qÖÔ CªAnj–Üú(¹Ã,Ĉ’YŒk¸ ›P¼0¢A4ѽ3§¼ÊdÚF{KÑÊwæé‘ô4}ˆ¦¥`‰¦‰`Zc?Á4IWyHG<ˆ9ÏxÚ:¦n«W¥?_âTÄDÖ4jÏ d²–2ˆu[dÙöbåM$ëd&\0m™œ× i^Ô)XµCi0L²ÏYËWü˜†µˆ!º|M E`ì ¤Ÿ|õÉ'Ñ÷ìÁóž÷\ò‹l˶mT,]J&føÅé¿ï>¦ÄÈf©¼Dñú¥P¹x1­7ÞHEw7G÷ÝGj|œª¥Kq\&ÿ®L°Ê(ã?_4JëÖ­4_=¯üð‡ìûÊWˆtv¾n¢ä ñF£er•RB--´Þx#Z"Áž/|Ñýûñ××㮨XÐèKñz©^¾œž|Áá ïg?ãéO} ÅëÅ]UuÅRkA­ÞÈ믧ýöÛQM“Ñ#Gè¿ÿ~†y„`[îhô²¾ ÁŽv´´ ™&McvbOs3²i’#ÐÞ~Eo‡3xKÕeΟåØGnÃÌèV‘´M² ;Ò@ÌÙ>« âœ!ðõ@x3Œ‡dÂJZ@)kí#\)ÂA…p Œt¡'ô’ÈÁRE  &NC#PjjaQÑ›zØÿÝý¤2ZáðùEš ?{ä÷˜k1Ô^ųK« •¦ÐõHÞövüK—âmkC GHuj¤¢¢fXÄȰGi²­f ÆÅ]„%? "ŠHçØ)‹,•x§$ݰ ÷‚í_,%«"£cä´¥v†uYðǂVÌD.äd¶-Œs&‹”ÑQæ4Ã@ÐLļ’¥™…ÆB£fâÔrTôŸCJç0Ô¼çÌÊ¢Ž"ê¶Á]³¬1'æ„wdlžbÅê•© ª€™m2ÏQzy½x]N›­Œ°Dfú§É=Jêïÿanç¦MóZ4Q´¦ïz•«W3;1ÁО= <ð‡Q±hîšš+>§>5+V°ôÃÆŽþèGìùÛ¿%ÐЀ+Á – Ve¼ÑÈKÒí7Ý„¯®Ž“?û±“' ~€2~Õ;ÖŠ!¨Z¶Œæ-[˜9s†Cßù±“'‰®^½°q»K³þê«©½új~ýëœâ LÓ¤zÅŠ+’AqWVÒzÓM„zzÈårœ{òINÝy'éÁAA t™q_ÆFj¯ºŠ`O®.==T,^Œär!½ÊÐ MãøWÿž™§žFÐ,^£›vS}jÖˆ.o$/•‹Ãóy»`ò<¤æl»ŽiïcÐ/ò`•ø«âŽkÐÓ&ÆL3g\T£#&.M'‘Qêë0W-Bð9õl’ñ3ØqV…„U€Á?[…é”L0D3AH Yܸ ˆAd¿wSžÖV¦]'˜ãÕ© ™&‚hØŠÖU9X vLƒ©ŠtŒž.ø¤Dð•W³Œ‚çItãs´Ÿ±"+ìëÍ«Y‚a‘-Á°ÂNã‚'f þ+ŒR5‹¢7KQüýC)µ ,åOó1 ²h KÖˆ03êFçàdQMÌç‘•¨+e¬=%ÇÖKÔ¬‚ Z¨^ ÓÓ›]UÉ<÷Œ!9È¥±$‚€ ITtwÓzãøZZ˜èëcø™g~ì1’ýýD7l@º’=CP¼^š6m¢víZEö|þó ïÝ‹iD ˆ• Veü e™Š®.š6m¢jéRIÂá÷#– ²-˜&Éñq0M²³³Èn÷‚—>;êׯ§eÛ6F_z‰=Ÿÿ<îpwUÕ‚k|µµ4]=-7ÞÈøáܸçÎ>òþ¦&|õõW|œA ÒÕEË7Y¶ŒÙ±1Î?ù$>ÈÙŸü„Æ;¬ˆˆË¨Q’ÓI¤³“È¢EZ[qUW#¿ŽZ¦ß:yFðxæ‹Áúp›9s†sO<Á釦ï›ßÀœMaè¶5Ê&Všº½ö‡« æÃ<™ç•’ÃÑŠ*’aÚ$+kïsa„ƒ a^õ~¤úvDÅ>—ÂLf1száC]ÔM<“@ÎÜÔ«¡‡ëh»õS„–,gôÌfcÓduM€Œ©-Apˆ“` CNÒ/œ#J}2AìøK Ž?GÆe“!Ý(¬Ø+¬Þ˧ KFq¡­b ‚4Ó"8²9ªæ& TAŲª‚ß ƒà°E°$Ã(œo©WÅýDÃ(lÞÁc³…ܯâêB ­ÂmÖL¼b ×ÈætÎR˜l”åy’ffG\è# œž™_c”¯È.Õ"XFh# ÚºBy¶^¢då•3æpö\ñ¡Ï8@ú‘GÈýô§¸®½Ñíž·òÖáóQ³jí;w⮫cà¹ç|òIÎüèG¨±¾†œ XÙhl¤yófÚwì`xï^^ýÑèüq¼Ñ(¾ºº×´Š” Veü' 98|>Ü‘H™\]ðíÏáó1;0ÀÐ /0ñÊ+ N·Ï+IÎ@€¦M›¨^¾œ÷ÝÇñÿI–‰tu-¬kQQðÕÕÑþŽwP±x1£ûö±ï _@K$…`këÿÙå¢jÙ2ÚwîÄÓØHbrÙífîäI A ÔÑqÅÛ"J¢,¿aÙ:¿r50Àì?ˆ18ˆ¸obw7Ø(I¤c1†^xc÷ÜC¼ï ¦a*ÓžÒ¶‚Urª ç O©×ÊÞ$àÀ!ÈØ“>M°ÉÖ~RÖ7ªóU0Ü5äþ%AD}6‰‘Ìj 辬ˆßF¬‹"¬èÆ WãòÖPÝ»…Ö[oESÆHÌÎ’AúP‚"ÙjRQÒÍ,1aŠ}ÂK ½²ŸØ¡gQ„9².±¸JO/*OÅ|F‘XÉE¢%جĜªé jfÇ,’c•,!O–ò$K7‘“:Ñ™1ÜÙt\ Æ|b•W²$ÓÀ%dðŸŠ#ÆbEñº´’Jw-dÄ14æù¤ŒòcèÖc¬:0FM´‰‹+Jˆ’•f,tȵ¿äïzqq‚Qâá2U•85*Ì+?WÓirCC¤¾ñ ÌÑQD]G^´hÞ—%g0Hý5×иy3¦ÃÁðþý ü✾óN|--øš›¯¨hIŠ‚¿¾žîw¿C™éi’ÃÃT¯XñšAÐe‚UFeüÚந ÜÑ¡ë¼zÏ=è¹þË|ã»Ñò××Ó´i®Pˆ#wÞÉÙÇ#ÒÕ…+^Ñ’…HWÍ[·êìäÈw¿Kßý÷3ÛßOý5×XyPW ?ŠÇCͪU4mÛFí5×èè ØÜŒ«²ò-EœŠÄSO1òío“}ôQô]»`÷n¤¹9Äuë@qWT0{îé©)33¨’„épØÞ+]7¬1a©Š•'\ö&h¶>?òSAtÀÉ¡K~>[Ó"ÛN ½sƒ£c êö˜.O¶0™m˜YÄ5“„¬Š¨é…Q›XJ¶LÓŠK0°Æ†˜ˆr1É]MRj¦Æ¨ž·‰’="Ô‹$«”téºLåì$‘øtÁä.š%D+ÿ»}ꉦñ‹#ŒöH°$¾¡`r·U,Ã$ìžÁ'Í2ûRvÞˆÐ(çå7¦e„³ Ìé¤fæeVy•Ê"XzÌÄ_†\ññ4KÌîfɈÑT!°êf”íïçÜþä4 Í4ç=O2‡‘Ûµ Gk+rS¤ÉW[Kãu×Q»a³ããL=ËàÏÎÐ#ÐþÞ÷‚(^ñ‹²(ËT-]Jëöí´Ý|óe[6Ê«Œ2Êøµ"_ÓÒ´q#sçÎÑ¿{7†®ã¯«[09‘œN"ÝÝ,þÀÈÎβ糟%>4„ÓNÛ_5«W³ø#AËå8ûÐCøÚ×0T•HWŠ×{eU-Ä[[K ¥åmK®’'Np쓟dâìYTÓ$äFF01—³êtš›©^¶ŒªeËP‚Aj¯»Žæw¾“†nDòHŒO‘‰§Ñ5½TÝ*Q²t{å ³•©¬¥b ˜ÄÒ:9]¿dJƒn“1!¢* TVÀ²„ö^äÚfœÍÍ8›šPªªPª«‘<>BK#|ÌœÄßѼ¸ ê¦PšJ›Åé÷3³8Þ™y†ñâøÍ(ŒÔ$ÃÀpˆÄºªHÖ‘²®é”mv/^Ž‚2dÇq¦íòWfÝÔLŒQ3=6oÌ'éó•«üíqç24Œ™.Þ¾üfšÅÛkȆNÐ3‡oïæyᢡ˜7¸ëV7£OIÐVw)§2ò¼Y4¡kEõÊÈo:ˆqðŒ›˜IÙýšehÏ÷6–*Xª5"DÐ`d`ìÌÚ$ÌV(Í’qa!°4ÒñS´þ?AûýŸd ƒÉÁA’‰ÄüDtšä¿ÿ;Ù{îÁ³y3Ò¦vÉNq_ü¡Q¹r%“ýýŒ<È¡Ï}SU½½ è…‘– Ve”ñC¨µ•`K É‘NÜwÁ–œ èY,EÍÊ•´lÛFìÄ ^ú§böìYš7o^ðþ²ÛMÃ5×P¿q#z.ÇÀ“Ob¨*®pøuÅC¼Ý™™!vü8ý?ý)gví"ϳÏè€úÜs°{7 / ïØ§¶–†k®¡jùr*–,¡båJBË–á‡ÑrÉñIÔLÎR=òŠ–í­Êoºmf–²à1¡éC€xÍÍŒ;F2‘¼tRƒµHQT£Q„î:UCu‚,#‡B8¢Q”êjä`W}Ó'N‘Ÿ"°t)ζ6h¨CÈš7:ô2‡¾óâCCÄ™™~w ˆ¦QÚ1¥#C1ï2 T“xc„lÀƒ˜ÓqM§l9£}~£ägSÀ€ìy75ãTÏLÌ»lilCÞ8/&n#MýØá™é‹Mî%Ñ ùÍçLày>‰9(ÔªüBƒüíÁöc)¢JÀCϘ ¿`“$³hp7K*Ã9kâÑ1SûÌb¤Vrù|Lƒ&€& Ù ÖÈ9ˆMÚ»˜FÈó°üqœ;ÿºkiºþz*V¬`.cr`U×ç=OÒ33L>ó ‘›oF~žÁHg'-7Ü€·¥CQXþ§Šó ì$,¬2Ê(ã7 Åã!ØÜLåâż|×]d¦§eùu•­:ƒA꯾š–mÛ8ÿôÓìýÒ—04PKË‚V ’„7¥eÛ6ä#8C!Ü‘ˆeÆ‹Ä#¼ÑœNfûû9ûì³ =J"•*(G¹’M›C=zóŽ;‘6oFöû‘ND‡WU‘Þ^"½½¸¢µ¤ç’¤fâdÓÙ¸PÓ‹£CÍööHiSàì\NÃ_|†ö|Ýébül?ñ¼Ja•Ь‚Ã…»® iIÔµ@e ˆVýèv£TU!TT034Ä™Ÿ?Ž!;ñ-ZŒ¿g1BE¦#À±ïÞÍ‘»ÿö[n!—LlnÆÛ$a¦Šær}~üìixJvÈgÞó¤-¢åŒ¥qO&æy°„yµ5Öfj=éÆœ­alb^LCñz-Ò”"õ§vx„ðôŒ}ý¥FwI×­SCG2t\R×3)8_ôY‰vÀ¨ ™Ö*OÝúY1U\žÔ í)Æ(% –©Úþ+H8º&’<ïC›51³†¥`•,H05¬%š¨s&Ff]mŒN›¤3™¢RiCgM{_uĺ÷û~¹£ Éá ÜÙI÷ûßOdÕ*&‡†˜ž˜ «Y±Z @LQ¨ß¹÷k©Ü‚€Ãï'ºz5]ïy®7ø V™`•QF¿yØ}‹ 6 çrŒ8Àø‘#T/_þ:a™W[·o·Š±zˆ“÷ßâõno_ÐøN°=o†º™_'~øCÎÝy'“?ÿ9f:¯Ä\zæ;4Ã==xÛÛ™a.»(óS4MCé%„óç‘L±ä˜¢,ãŽF ôôèéAòxION“ž‰£kzÁ“UˆrЭ•‚ί¼Œøžáêè¢yÛ6"Ë—£"0|ôUTð ðöínü](]íà ¦CP0M“©cǘ8x3>Ê™ÝO0zò$Î.|í—,EFÀ"ÜÞ…§¶wu5m;vP½lñóûÐfN^ V•Ęş‹« KⓜßMäå‘¢e«@…šûÔÔÁ˜âÕ±qª¦'‹1 Æ|Ó|žÄ‰†I@ŽS14zΪ×1¢r•x°ýW2Aeé— •ú¯.4 ’ "{æPÓ0¼—y¬¼2•?Ï0€´¥. N¹¶=W‡>—ÆHå.öb邹YèøÄ§©¸áÝLFµ ì:Ö±EÍ"[“¨?ø{8ºº ï#‚$éî¦õæ›qÕ×3Ö×Ç\,ÆU_ûíŸø¾ææ+ÿíã¼á_ZÊ«Œ2ÊømÂ[]M¤³ou5‡¿÷=ÀJe–˜`.¡övZ·m#ÔÖÆÀ/É䫯R³r%¢(¾m+†®5™düàANüð‡þêW9ÿðÃ̼ðS¿øcwÝEõm·!—¼?+º»i¼î:Ún½Ãífb`€ÄÜÜ¥ÚjPAôQ¸óNä-[¬eòvˆ®ìñàkn&ÒÛ‹·¹)$99M6žBÓt+3+¯`e@IÃíGÜùNhh²Û¶6š¶m#²r%ÓcãÌLM¡‹"¢â@r{ð/^Œ»­¡¹ãø9ÎàÔÏ~Æø‘#ˆŠÂÉûïGEB‹á[´ˆHï\-È‘jÙƒä hk'ØÜŒìvcê9f>":`j IDATŽ;U4ŒÏ#S¥þ¦"¡É¡¼ïÉ‘È|y´ TaEõʰLïè†5"œã5“ãTÅJbŒù£¥×V¦qŸŸF™JY« íÀÑ|þU~5¡dÈ¦Ž—9„' „a+`ô’Ðvø¨hjàNX Ö \2¦!¿éºå¥2bÖc©´lÀÕµÉãÅ4%´É8d +ôU/*X¹9гÙöšÞ÷QÚo» Ok+CÇŽ‘L& <Í´®sÈ„$¼î:‚kÖ\ô¼uø|D{{i¾ùfÄPˆEüÇ„::®H®~­ªp™`•QF¿mˆ²Œ3 ÚÛËØáÃŒ¿ü2™éi /×v8 y5¾ÚZ0M$§ówwäçp H³ƒƒLœ>ÍÌø89MCÍfÉLN2³{7F*ýÂØ†|`˜€8% & zrbÁ²V#óbòÊY…;†t.Ëãf`‘)C/It·ndèÈ™,Ò3°5Ä^É™'cùÕƒ¢:ª+…–‚Á}%jU^qÓŠ+ü Ýê”Ô§­q¯oÝNnC ‡‘ÃDʼn‘50⌴f?a2q‹˜…¶íÄ»¼Åë%ºf ïzb(Äh_ñÙÙ‘|ìcèÕÕÿú×Yþ™Ï¼¦"í®¨ iË–7ESF™`•QFo¢%ITôôந >8ȱŸü„Ú5kEñu%g0ˆâñ¼íÈ•i¹¹ÙYô\L󲫙òþ’æ­[i{Ç;Pª«?}šL*Ezt”©]»˜Þ½Qðtt ¾F¿¡–íÛiغ•‘“'™™˜@մ‡߼X…£G1wíBªªBZ±¢T*HŽPˆ@WáåËQ"¨•ää4zF³œëŠ‚¯­G]†¤ ¶·cz6ËÜùóŒìÛG ©‰@G£'O"UVèéÁ×Ù\Enh ¾wR0DíUWѲe ®pC¾ÚÚÕZå†N“zñA‹`é%#BݼäÈðBò•ÏR’Y¼G&tËá?ϸ®›Öyº †€4Rª&'¨ŒM]”½Uz=y5­Ê;‰v6…>‘+¬|ú¹hÈvDƒdG7ÔÎV õÂG1Í]³œæiW- Ã/ v¨èYU%¤ËÈ@nÆR°WÝDdË{PjjÃa¤@)FŒ´†1—A¬¨##‡Ð&f‰Ü¼ïÊÕó^» ×\CôškÈc§O£Š"›¾÷=Ú>üaêwîäÈ~@ÓÆoþ/9e‚UFe¼Ùà ˆtvRÛÛKßÃ[3Nç‚džoWdgf~î9~ùËìþÃ?düÀžhù2A‰Î`@s3Í[·Òrë­d ƒ©óçI%¤àFþå_pE£8ª«‘/±²Sr: 45±èƒ$°hCCÄÆÆÈFÁ_¨ ÌfÉ>ø bUΫ®šO¢\55T¬YChÙ2Ü È¦¢ÉdðôôàíìBzef`€ØÉ“8|>Yftÿ~FdñÇ?Nhùr¼ÝݸÛÚ‘«£Þ ®ºzÂx*+åu«˜êà)rÏßSTçG”Þâùóúÿò#9MÇÏâ:4YÅifÀöè1ÏJ“ $ ª&'¨ššœ—â~‘ÙÝ&XÑÀÉÓY2c:†fêì ‹h™È†ŽlHš6²¼A®BDDLf3‚Z æOMCgΑÃ0\d„Ud'çÐRv¢»~±é]KCÆ&XÁÕ› ¯Ù‚ âhh@©«C‰F‘#äpÉåÁ³öjjþìÏ9÷Ìó„¯ÛDð‚ÚAñ74ÐqÛmT­[GÃ;ßIýu×áðùð77¿%ÈU™`•QFoî7(‡ƒª%K¬Õ}öï¿ËÝn‚­­ÚÚ0³=Dÿý÷3üüóÔoÚtåZAÀ]YIãõ×^²„d"ÁÄéÓ覉–L2qÿý$¡þ#ym•QQ¨Zº”ÆM›pD£ô¿ô™Lf^U`~U}êé§‘êêp¯\yñM‘e\Ñ(J8ŒjšLž:….Iøºº,^Œ£2Âøá#œÞ·Q– wtàôû­Ç›oÆáóéî&ÐÖ† ¬`¥vþç¡ÖV"ySû[íý«L°Ê(£Œ7ý•¢¼-É•©ë¤ÆÇI£¦RV&Ø‚ Šx£Qšo¸–;HNL0²g‡ï¸ƒøø8Þº:¼„+^ЏFººèzï{ ôô07;ËÌø8Ù\Žä™3œû»¿ÃL¥P‚A\uu—<†;¡~ÖýÑ‘Êå˜cnf¦ç²ªŠèpÚ¾ñ‚Ñœ–Éп{7'~˜>Jldow7k×âîîÁÙÞNxÙr꯹–PO_m-®pÅãÁ !»\ W§ô4Ì×k/Å7U•‘ßߎWLáT+ÁÞ. ½@ÉÊÿM2 MCIfQM—„‹óüWyU MÀÓq$uª&'©˜œ*Ä1šYˆ€È)ó±¡À'LfGlõÊÞ4[U*U´ „1#uÇÆ?`ü~¿ÁáBHgS9„¬Ž¤h†É¨¬#»ÃtýÅרٸ‘`w²7@êü8¹x#g‚GsYHÌZ VõúÍT¯Û4Ô B0HllŒþýûÉI ;v^º”Öw¿›P[ÛÛÒ+Y&Xe”QF¿E‚•åÌ/~ÁÞ/~‘Ñýû wvâŽD®¸ožh5mÛFÕªUÌ pæ¾û8÷‹_`¡ÎÎËw?ÚKÓ+—-£iëVœÑ(“ýýħ¦ÐU•Ø3Ï0õðÃäΟ'¸r%’Ïw‰C(^/-[·R³n©TЉþ~r¹`HB:˺`¬#Ê2á¶6d·ÙéÄÛØHôÚk‰¬^¯§¹º!F …pƒÖˆP’~åô|㙿AØÿyHž‚Æ_ãB:™¯ÿ-%ƒSÔæù­J}V‚IôäWí f‰ÿJÕ“*â¡[²É•­r ¶· {”ç™Öq¦t“ÓbÓ(yÂfÎhȇšJ†ì-¤ —ªVùnÀBi,yT@ÔÀñ¡¿¯\.KÉr»\nQFHe‘Ò*š®3$›Hî ùHN'þÎN*V­ÂÓЈžVÉŒÇPãi ]˫ژ$zífj7lº˜ßær¤¦§q75^¶Œ@K‹•ˆ.ËoÛ…(e‚UFe”ñ[‚ I¸++©\¼˜@c#§î¿ŸƒßúÉñq‚­­ _•œN´Üt¡E‹}é%Î=ð'øCxªª®hìvÔôöÒtãHŒž8A:“!;;ËìÞ½ŒÝ{/¹óç _wâ%”DA’45Ѳ};-;v03>ÎøéÓ8ª«©èíÅ0¼gc§Ojm-ÜA 65Q¿n×]GÍÊ•øššPü~PË ÿÅl÷ÿ7~F^€ÓwYÇöTƒ³x †Žú•Ï";sH‚¬›ÚKâŠÊ’½â/_M£j(Éœ³Jž/\A˜ON·}OÞi WJGšžEš™C0LÍ@šç½*æb‰¦ŽêN2zfGK«üfã/tÃ’ÝçAÐEœŸú2„B>Ø›àóYŠ–Ëät“Ig9—Í":Õ+WÒºc’×Ëô‰¹ãfOŸÆe*/.z)²×°iÑ Ðd™‰þ~2©¹¹9b/¼@.£öÖ[_ó²Ë…¿¾AQ¼^Äp˜ŠÞ^B+VPÝÛ‹3"›É\4Â$ Éé´Š· Ùeêñ_"»›Ì}w’q™èXj“bÈóHÎ…XnŠª"'sææ{°ŒùãÂ|‚«ZÅ•ÒÐgâ¨sI4;ÁAÒ-’'ò¸¬ëÍÉY2RŽ©!3CZÁlž Î#ZºE°¼ý‚&âü_ÿ× †BVQ¶Ïg)Z~?¢Ï‡ár1Úž S&71…™KQµý–y÷§¦ëÈ‘†,“™KÒñþQsõ–~üQ¼>¢kÖ\¶ùwæu]&Xe”QFoú@ν$Ý]/íÿ³ VNEJäÈíOÚ„G…Z ÙÒ¬õÐLOZc:ž&Ï¢VŸnZ§š ¦i_6tƤ Bê ‹>ý}ü]KHÇæHMÌKæŠ ëöi°nF\&;›"ôéO—;Kÿ¾}Ôÿ—ÿBÍöpv÷0|ô³##ÔÚéé‚ X=€íí4mÚ„ç *Ê«Œ2Ê(£Œ7ŠÇC ¡Ôø8çžzйóç¯8¦»îH„–­[©Z¶Œñýû9ð­o1ÛßOíUW]ÞÀ^¢&ykkiܲ…`g'sôÝ{/cÏ=G*•¢nýúË’5A].¼µµÚÛ1e™ê5k¨¿î:¢½½†·¦é2\¿m¨'3óYH.Uë´P°X²yšÁßžF?šZìL4¬¼P0LdÓ@1òÏXñ &E+?"LïOc ]„¥#Cë÷ÐloZe<™e,©’yŸ·Ù|ÐÆ´mjoûÄßQÑ»–Š•+A”ÉÎÆINX©ëöí^üûŸDÆÏœ¡á¯þjÞý£¥ÓÌ ;{–ó2øÊ+´½ûÝÈn7¡în*V¬@K§‰tw—_Ô¯‚išfùn(£Œ2ÊøõÁÐ4Æ_y…WÿíßèÚ¹“ºuë.©ú\öªJß°ÿë_gêøqVþ韲äC"Üѱ°˜&¹xœ£ßÿ>Ç~ðbGŽà¬­eë·¾EͪUx£Ñ+ìnbjj2i].‹œ½É»cw}“©Ïþ9.8ks9@q€è<€×Þ<ÅÓDÎ<é1PLk?·NÜ%ÇB‘Ð2š½é. QЉ÷ ÌìUÑÑ0†SÂpŠ˜NÃ)¡+8$¦Ò„²‡‡Fb8õn ¼…S .œ!ëÙ›v£„«À4Q“Ib‡qúG?bä‰]d†ú‘•߃1cÿÿù?¬½óNÂ+VÌ»âÃür÷ÝH½Ÿø’¢üÎvx–¬2Ê(£Œ·Ò7YQÄííeúÔ)F^z Q–¯8¦›w I¢bñbZo¼w8ÌËßû}=„išT-]zeÂfvªV¬ÀÛØÈ¹gŸ%=1ÁÐÓO“žœÄ„Ë’5ÁŽu].ËŒþ W¯¾ïfÔtÚZUg”Dè jÖVP´ò‘Ô,%d=7ní§ÛÞ¨ü±DÃ*Z–mÿ•d8TEÓ0]µèRf2 éla\ÈÆ÷ŠÙ ¾tŽà>Œó–Û?ÕGbzfžz¥ƒß‰e!c§ª·ÿÑ'‘ÜÞÂãëkj"²r%Á®nÔDšÔè$ÿ#|Ë—ãîìä‰O|‚ÙÉIj׬)xèœ~?×\Cýúõˆ¿…1n™`•QFe”ñŸ‚âvéêÂ[SÃðÞ½Œ:„»¢Åë]pÃï§víZ:n» -•âÐ?ÿ3G¾ÿ}êÖ­Cñx.É ˆŠB ¹™¶;pÕÔPÓÛK¤« w$b(·Ûú} ÃÈåÈŒŒpì’Éç÷ é¦ETŒù›aZ•/‚jóÅŠ%‹¾„Û`|3¶ùÝÞ_+!mRžd¦ªcætÄú%°x+¢Çƒ(Ê0—DÈæ4;;Ëöe>¤xï­·Qÿ?>IëŽ[Àíaìd©TÍ0Qó~, ç«!5ÄСûÏ?‰ì™¿ÊÔÒ‰³±™DŠö÷¾o]Á®.šo¹…šÕ«q‡Ã¿³Eèe‚UFe”ñ6…Ãç£jéRd·›³>ÊØÁƒT-Y²à±¡ ЏB!š6m¢~Ã2SS<õ©O1uü8Ž@€ðkÔŽä‘Wϯ»Žº«¯¦rñb«Š&|K“+5•"qþ@Úãeè•£D?ú8K¢IBM&—ŠÞ«h¾á&ü xjké¸ý–bYöM½éP^EXFe”ñ&Br|œ¹sçˆ:Eó–-ø®°ºïÒý¶þÿÐÍ%$™ëïgô¹ç˜Ø»cdù•Wð~ ´v-án ò¹ÏV‰trl Éá@ñzQÜn´D‚éƒ|ðA&ŸyšøË‡QD—.¥du¡½ÂБÿY‡d0%ëøçyâÓ…U…®’•…Š‚3Ip:¡écNû_½ø°hÆÌ ¹Ó§É?NöÔ)²†Aãßü £?Ρ¿ù íÿó!…BDW¯ÆS]m='ÆÆˆ8¡ë4oÞ\~‘¼EPV°Ê(£Œ2ÞDpx½øëë©\´ÙΗzÝ~™·È ¿+~@) ’ËEÿ“OÒ÷È# ïÛGbhˆVN¨ d†‡I=÷ñ/~G4Š â±ÓÄe§Óªáq»ñµ´P¹~=¡eË‘¼~Ò³ Ò3qÔ¬v±*e«[jþü ˜i…®Ÿï¥qÛv’Óqf†FÉ&Òhz1u]3¬Õ}Ó ëçÀŠ«¨Þ²£ø°ˆ"‚ËÁ YA`´¯™XŒú;ñvt Õ×Óÿä“ ¿ø"UË–ȵÃç#ØÜ\÷½ÅPV°Ê(£Œ2ÊøCËdHMLX«(ššåì®]ô?ú(}÷Þ‹KU ÑU~¬ø*Z±‚Ú{îÁÑÓsé™&‰³g™Ü»—ÁŸþ”ØÞÐÆ‡qHFAÅÊgeå—tuu}Y²33œ}ä^ý—ï1òË' j–âˆÅ­ý—üÙŸ³æKE+—H0º?Ó}}L>Ìä¡C\ûéOÓ°m[ù Q&Xe”QFe”ñ«#—H0vècû÷3üüó¤''qƒ\õÉOR½rå=c¹D‚‘_dï¿ÈÔóÏ#Æãÿ{÷U?pü=ÀÀˆ(ÊMå&¨!à%Jígje´–º%+í¶Y^v³lÕ\­-/™«†y%[W´«ÛÅ_Eê=é–(–$Þ@ä¢\D„€`f¸Ì0s~øó!:–»Û¶Ÿ×óð<2g¾_ÏùžáÌg¾Ÿï|z¾­ª¼é1v,¾ ^ ´¾¿–MQpØl˜Š‹ùæ‹/¸øÉ'¾ÌBi4âájWS†—”6pŘŠÖo»°Ûiª©¡h×.ò¶§a.:›ÃJ@ÜPF¿ö¿˜7ï°P>1÷®]鈋«+V‹…Â?$<>‡Í†wHˆ¼(~¦$E(„â_÷¦ãîŽOHm6ÕÇŽQñ`:~œªC‡ ­ÀÿùŸk¶ïÎÀ‡Æ#(sc#µçÏcSµ„•Õl¦åÔ)L©©¸* ®:nÁÁß™Z¸T4Uçç‡Ot4>11h}{`mn¥ÉPµ©Uý– µ jM`׸ö§ç¿íÂÅw½ž€[n!`Øp¬Ö6«kqóñe蟦ÿC¿Å+¢YY˜**ðÆ]¯ÇÍÀÁƒq÷òÂÃÇG^` !„7ŽOh(awßMŸQ£¨ÎÏÇXP@Í¡CTìÝKÏ›oÆÝÛ­¶Óöÿ!CÇ#(ˆ‹gÎÐd6cSl|[ƪùÀZ>ûŒÖÐOœˆæ{}ºhµèéƒwT­Ç¥@«Öˆ½ÍA›â‚ÙÝk«Mk+=ïÛ~?]÷î|“wš†Ê*Ƭ]×ÿs]zô pèPü rîÞ‘âgER„B!nÅáÀÖÔt©2ýu,²·šL¼ÿ>ÇSR0?Ž»ÝNh|£GãÞ³'ŽÃpú4Õ_|V+×HÂ¥ûé…Ýu·ÝFKk+•§N©÷î»üÓzî–ôt¬¹¹¸úûãÖ¡7½ž®¡¡ØÝÜhiiÅ\g fþ|‚îº ]Hˆ:;%ÄµÈ –BˆBQ»C/¾È™wÞ¡Å``Ä3Ï0 1ÑéÅ܊é²’/“’(Û»kE:­–±;wÒcèP¼œ(Uàhk£ìóÏùzþùüs´ÍÍxòíBx-àÿôÓD%%uš†´Ûl~ð½‡Ç;4TN®¸n2ƒ%„âÆ|b×hи¸2j½o¿»ÕJvr2¿ú ÿÁƒ¯}ëooÂÆŽ%`Ø0kk1œ;ÇÙ;©ËΦ¹¢‚ ;î¸z..tïÛ—¾ãÆáÑ«µee4ÔÔàìnn |ùeê ŠÇµ“o-º¸ºâG·nrbÅû{,!„ÿ ¶æfªŽ%+)‰Ú'ð #~Ó&|ûõC«×;ÕGk}=ç339¸d æâbܬVÂ'NdÐüùÝ~û5Û+v;Mµµä¾þ:'SSÑ{zòP^6³·ë\+&„XB!~2‡ƒÓo¿MÞ[oQyø0òÄ9¹€ Åh$÷78½cÆãÇѹ¹1|Å Bǧ{l¬S}ÏžÅ]¯§ëwîõ'„XB!þ£Yª«)LOçȺuh€þ ÄÍžWŸ>NjÆ¢"r_{ü×^£­ª ß¾}‰xà†­]+,$ÀBñß«é›oø:%…Óo½…¹ªŠûÒÒ=¯Þ½îÃXTÄá_ÄÞÐÀ¸7Þp:å(„XB!~¶mmTåäpêÕW9¹};½n½•Û-¢ï½÷:݇ÍbAq8p÷ò’` !„—Òè¸=ˆIDAT)v;µ§O“µj¥Ÿ~JïáÉ{ê)Bïº 77 ñËE†@!Ä¿íS¾«+~±±Ü—–Æ]ë×c©©¡:'ÅáÁÿÙ¯m™ÁBñS 84 è||®zB!$ÀB!„ø/$)B!„B °„B!$ÀB!„K!„BH€%„B!–B!ÄÏ•”ÉBÜÅÅÅÔÖÖÒÜÜLÿþýé}÷•khh ´´ƒÁ€F£¡OŸ>„††¢ýµŠŠŠ¨¬¬$::šž={:Õ¦µµ•’’*++ð÷÷'22NçTûÂÂBêêêhii!**ŠÀÀÀÏ1 c2™ðôô¤ÿþôèÑãš}›L& illDQºuëFTT]ºtÁjµRVVFuu5­­­ê6OOO§ÇËf³QRRÂ… èÕ«‘‘‘¸ººv8¿DGGãçççTß&“‰òòrjjjpwwç–[nÁÝݽݘ”””ÐÐЀ››!!!«ÿ·Íf£¬¬ŒŠŠ ìv;¾¾¾ 0ຎOˆ©ƒ%„¸!FMSSeee¬^½š3f8ÝvÓ¦M|ðÁÐÖÖFUUO=õ h4§û©¬¬äøYYYìØ±ƒûî»ïšmÚÚÚøÛßþFjj*aaah4JKKyä‘G˜1cWmo·Û1beee¤¤¤ðë_ÿºÃ~-Y²„úúz¼¼¼hiiaúôéŒ7îšûwøðaÖ®]‹^¯§­­ÒÒR&L˜Àܹs9wîO=õ=zô@§ÓQZZÊ=÷Üüyóðööv*°Ü¹s'|ðݺu 00Å‹ããã£>¯ªªŠÙ³gsàÀ¶mÛÆ/ùK§ÎÇž={xþùçiiiÁÍÍýû÷· Ζ.]ÊáÇñ÷÷Çb±ÐØØÈÒ¥K¹ãŽ;øè£X»v-xxxPRRÂý÷ßÏìÙ³éÚµ«üщŸ6EñOW\\¬*çÏŸWŽ9¢äææ*MMMížÓØØ¨äææ*‡V¾þúk¥ªªJQEq8JMM’““£|ùå—JAAÒÖÖ¦¶3 ÊñãÇ•¬¬,%;;[©¨¨Pìv»SûuâÄ åüùóJQQ‘Ú·³m¿¯°°P©««S ¤¤¥¥]WÛ3gÎ(/^T,‹ÒØØ¨$''+ÑÑÑŠÕjuº«Õª¬X±Byæ™g”ÀÀ@eïÞ½Nµ«¯¯WF¥lذA±X,ŠÅbQÞzë-%..N)++»f{‡Ã¡(uuuJdd¤òöÛo·ÛÞÐРüîw¿S’““£Ñ¨cKK‹Sû×ÚÚªÔ×׫û–­DFF*_}õ•b0”¼¼<¥±±Q±X,J^^ž®|üñÇNõ½oß>eüøñÊÉ“'“ɤX,Åd2µ{ Øl6%))IY°`¤¤§§;}N ƒR^^®ìÚµK‰‰‰Q¾ùæ›vÛ?®ÔÕÕ)‹E1ÊÂ… •;ï¼SÝ>nÜ8eáÂ…êñïß¿_‰ŠŠRNœ8!ñ“')B!þÖ¬YC~~>Äh4RTTĬY³xì±Ç¨®®fåÊ•œ>}šž={b·Û‰‰‰aÙ²e”––²páBŒF#]»v¥ººš9s昘ˆÁ``Ù²eäççãïïÃá 22’Å‹;õ Ú´i„„„àççÇ… ¨©©aóæÍ 6LMÑX­ÖNÛët:5Ó¯_?\\®iç€ÚýICC×3Á~ìØ1²²²HNNæÍ7ßtºV«%""BMßi4 sj 5 ýû÷ïôØ ÈÍÍeüøñ¬]»‡ÃÁwÜ¡ÎÒ\‹»»;Z­–ææfššš8sæ ~~~øúúÒ½{wºwï®>7<<wwwÌf³S}¿÷Þ{DFFrðàAvìØAïÞ½™2e z½^}ÎÉ“'ùâ‹/HNNæwÞ¹®ózyÿòòò®¸}ðàÁê¿===éÛ·/{÷îU‹ŠŠâüùó ¼¼¼8sæ ½zõjwÌBüTI€%Ä¿ˆÙlfîܹ±}ûvRRRÔ+%%…sçΑ’’BŸ>}hkkÃn·ðòË/ãp8زe ¾¾¾ìß¿ŸåË—3`Àü1¯¾ú*C† Án·c·ÛéÒ¥‹Sûd³ÙÐëõ<ÿüótéÒ… ð׿þU °ÒÓÓÙ²eK§í7lØÐîMòF0™L¤§§3f̘ë€:SSSúuë˜>}ºè9«K—.Ì;—%K–¨)I­VKRR’š6û1ª««9{ö,›7o&11‹ÅÂâÅ‹yüñÇÕó-UUU,X°€òòrêëëYµj¡¡¡R•{öìÁÛÛ››nºÉ©~=ŠÁ`ÀÍÍ¡C‡’‘‘Aff&©©©ôêÕ‹ÚÚZV¯^Í´iÓ:Á7ÚÅ‹ÉÈÈà¿ø…úØÌ™3Yºt)=ôZ­–ÖÖVV­ZEPP\P„XBˆKbcc8p 7Ýtµµµê¶ŒŒ f̘¡nÿ®ÌÌLžxâ úöí ÀĉY´h………Üzë­°uëVÆŒCtt4Æ szÉÝÝáÇ@tt4ûöíS·ÇÇÇsóÍ7wÚ¾W¯^7tŒZZZغu+lÞ¼Ù©«µµ•mÛ¶áëëˤI“®{­©©‰7âççÇ‹/¾ˆF£áÕW_eݺu¼òÊ+N/èîŒÝnÇh4²páBÆŽ‹ÝnÇÅÅ…­[·:`õìÙ“—^z‰úúz222XµjêëÅáp°ÿ~V¯^ÍsÏ=wÅ×Ñ•X,âââX²d ݺuc„ Œ9’ÌÌL&MšÄŽ;ðòòbòäÉ?hfòzÎÁúõëijjböìÙêã©©©(ŠBrr2z½žôôtV¯^Mß¾} —‹ŠøI“2 Bü‹|÷›O...íÒ_V«µÓY'›ÍÖîÛlÚÚÚ å7Þ`ôèÑ9r„çž{Žùóçc0œ»¸¸´ëÛÍÍM9»ðÆNl6Û ‹ÅÂæÍ›IOO'%%…èèh§Ú•——óî»ïróÍ7óÕW_qèÐ!¬V+§OŸ¦¼¼üšíÍf3™™™L:•!C†0xð`f̘Á©S§¸xñâ>®®]»âã㣫«+!!!íìkÑjµ„„„0hÐ fÍšECCƒšvs8öîÝ«®ß±X,ìÚµ‹   ~øá«¶×h4h4ÕÇL&Š¢8¢¼šÐÐP"""8yò$ØívJJJ®XÊáJ¬Vk»ÒØl6<==q8dffòì³Ï2sæL~øaÜÜœ¿¬;–œœèÞ½;uuuÔ××ãïﯖMøä“Oøä“OÔqyÿý÷ dêÔ©?zl¬V+Ë—/'77—ÔÔT"##;œÛËkñ4 ‹›Ív]Ç(„XBü{òÉ'yúé§ùÓŸþĈ#0™LX­VæÍ›Çã?΢E‹Ðétóá‡r÷ÝwGAAkÖ¬aذaèõz¾üòK"##ÕT[¶l¡ªªŠ?ÿùÏ?h¿âãã5jÔUgg.ûË_þ‚Íf£¶¶–ýû÷ÓÔÔÄ€ˆ`ãÆ˜Íf/^Ü¡Ÿ;w²iÓ&&MšÄÙ³g)--PSSÅÅÅ,Y²„5kÖ¨éÌË‚ƒƒÙ¾}{‡€uÞ¼yj9ºº:fΜɊ+:„ÞÞÞL˜0—^z‰ªª*4 ï¼ócÆŒQÇñ™gž!&&æŠA…¢(lÞ¼YÉÈÈ ¦¦†ØØXÆŒCXXS¦LaÕªUÒÜÜÌ»ï¾Ë“O>©¶ÿÍo~ìY³®¸ð=--ÊÊJú÷ïÙl&##ƒ¸¸8âââ(,,dΜ9£ÕjIOO`Ĉ„„„ ( 3fÌ`òäÉŒ?¾Cß“'Oæ³Ï>ã…^`èС|öÙgDEE1zôhzöìÙa\ Äܹs™4ip©~Ù´iÓX¾|9±±±úÏÏÏgß¾}äççSWWGZZz½žÄÄDHIIá½÷Þã‘GáèÑ£äää ÓéÔóöÛßþ–W^y“É„··7»wïfÈ!DEEÉECH€%„¸T#ê»i›}ôQõ÷‘#Gòæ›o’žžNvv6ÞÞÞj §{î¹???öìÙC~~> L™2N‡ÝngäÈ‘ÒÒÒBXX‹-¢wïÞ477süøq""":ݯ_ýêWíÞ¬ÜnÖÆÃÃãšu ¾ûfÚÚÚÊ„ ÈËËS°¦¦&Ž;Öéz®.]ºpß}÷ÑÚÚÊÔÇÔ«¾¾¾ÝLÎe®®® vN›6˜˜5-[ZZJuuõÓ°:Ž•+Wòé§ŸrðàAEaúôéLœ8êëë9zô(wÞyç÷]Q5]— ûå"§Z­–9sæNff&®®®¬_¿žÛn» ¸´€½¸¸¸ÓºUÇçÓO?%;;˜'Nœ`øðá<úè£êó¿?®S§N%66Vײ²2ªªª:-üY__¯ŽÍý÷߯¦/{z½ž &`4ùüóÏÕ€÷r€õì³Ïrë­·ràÀÊÊʸ÷Þ{ILLÄ××W.*â'O ñ3UQQÁÊ•+™?¾ZFàߥ´´”¤¤$-ZDXXØu·_»v-=zô`Ú´i?h±õÖ­[±X,Ì;÷ºÓ~999lܸ‘­[·:l^Ý»wsèÐ!V¬Xñƒ*×_;}ûÔbW N¬´´4ŒF#üãoH:U °„B!D§ä[„B!„` !„BH€%„B!–B!„K!„B,!„BˆŸ«ÿKuÂzr#U IEND®B`‚snd-16.1/pix/fmeq6.png0000644000076400007640000000201611147553267012671 0ustar bilbil‰PNG  IHDRã_F3PLTEÿÿÿààà°°°   pppðððPPP€€€@@@000ÐÐÐÀÀÀ``` CY¼ pHYs  šœtIME× 6oÊÎ]nIDAThÞÝ™‹’« †¹* (ïÿ´ËM¥jjYvÎa¦e×6?&$H ©5©IÏÖm´&óÒÿ¨Tª—Ï`X''§y} Ûƒ¶¨•ŸÆ]Çv. Å„6+»¤ƒ<ÌsX-BL¿·ø}PSYÆkabN!3Äð[]q‰¡`¢¨V-|¼Ê»ló-,Ž!vB=Yt)|‹æâŸ“µSÜñOý’Eç ù…ïݼÃ6£½Am J£©Ó±3šYÈ-n¨±£‘5Ï1ÔrV‰2Tñ\þ2² Ä]T¼ Oˆñª÷šìóÂÃ~J‹+Q!‹¶ \ø%ÜúNíí¹!&FO®ônÝífWõ± …ƒZ?Ï2ÌW*&¾!Ÿ_D]=«€ŒW½’6IóÂÁ>£EЍ ESP9ø?F;bMˆ_h•*ãb†kˆ:•cc ÏáeLؘPQ& ¢&o%¨Ú[NP0#¤·óUL”BÃ"iÏ -¶£‚MAy0 ’/QÄšÕ:š‡á¡Yé̽†DL…ŽÂ‡Í2‰fÚh®‚¥¨©naF@ï¨q“íÖ!`‘´|È´ÅŠ¨ ESP•XSçß}töq¸âS…Ü÷tJê:N…ƒ¬éj’9ûø"XŠÖ} 3z_Åd»uX$­6[ËÅ)VÜJÈ¢)(î–|MÏS-ˆÕ&¼lÈè{‚žXùT§.åØç–Ôe™ÍU°ÝJ>ru fô¾ŠI®¢X$í%ç Å TÈ¢-èœVľ>Ó˜q²Ì(‰ZdŽ ãRŠççç¸9],ešCrå˜`,ì%6QUßsŒ`Á›äÕ‡}H{+vA-Ú‚ú!)“±óëF9-¿=K`ájXüš—“—šººFM˜Ûf¤ýîG, ÓL‹Eíª$éÙ\¯ášÌ«mPÚÕÇý"Šþ+´­@<Ò;ªÈ­\IEND®B`‚snd-16.1/pix/tanhsininteg.png0000644000076400007640000005773511147553271014363 0ustar bilbil‰PNG  IHDR°®¯sRGB®Îé pHYs  šœtIMEÙ ’‡ IDATxÚì½w|TUú?~ïÔôI§¥Ð$ôH/!@(¸Ø•µíâbVVÖ]ìb×Õ] 6¾"¢R)!’FzŸô:“I™ÞÛýýñìÞÏýM¹sË€ ÷ýâÉpçÜsÎ=ç}Ÿç9OA1 Cþ ÃP ‹Å.ßwuuI¥Ò¬¬,øáÀ‡k ž +•——>|X£Ñ/BQ´···¹¹Y(æææ¢(J¤9"¼}Ïì! ²R?Š¢*•Êb±¸\wêÔ©›o¾9..î™gžÉÌÌDQÔh4ž8qB(Âo£££SSS£¢¢¸9åÀÃU—°‰DsçÎŽŽA‰(.uwwÇÅÅ9N\UäóùãÇOHH?~¼X,>sæLUU7¡8p¸†a111ð! ä&©TjµZÓÒÒf̘Q__Ÿššj4á±X¼páBømOOOnn®R©$¿nüâ¬`8p`%a¡(ÚÝÝ}øðá¾¾¾¨T*AäryOOÃáX·n]ÿ_|±e˸˜ØŠÝnGQ”Çãùd«“'OÂÏ9k˜KX‚DGG§§§Ï;×n·!2{öl‡ÃÁãñ$Éüùó'Mš4iÒ$fòœ?Ÿp±‡8p¸> Ën·I!²gÏž·ß~Ûf³q…8p¸¾Ë]Œâ<Ý9pàp­ ‹"é€Åãñ8yŠ¿a¡(êt:ív»Õju:$|ôÕW_­_¿>!!þ„ãBöB–KöAîqràðÛ†€åï÷îÝ«×ëÛÚÚ222¼ÞF p:8§¬Zµê/ù‹ÓédÉV(Šêõz»ÝÆãñ¸X8 ‹Œ2F½gÏž¿ýíoS§N¥èZ…aXZZZii©Ãá`)ß!òøã/^¼¸¥¥a6ć߾J@%$¿¯àWø‰!TUUY­Ö›o¾ùóÏ?wIëÌްbxx844ò)ãrûf/_¾<}úô &èõz– &8Âú/öíÛ—™™‰'_F$44T `kA+,,œ0aÂÖ­[<¨ÕjÙó ËÏ9C>¿G  ®Efggwww3føaMMÍøñ㉉‰1 k3Š¢6›­¸¸X.—s&|~§„åŽyóæíÛ·±T‡ƒ@………îÅ~˜©™÷Þ{ï;ï¼"~G„…àq¦l6[`` ›–‹ŠŠ¦L™…ÅÒÒÒZZZXÆTC?üðÿýíoyyyƒƒƒœVÈÃï‹°@ &–’ö ÚÚÚF‚ ˆÑh d¯"Òßß¿fÍ‘H$—ËÎU‚‡ß›JXXX˜œœ ypc¡™A,[,pæZ°`AMM û[………)))kÖ¬)//×ëõþ’1Ý?sàÀáz$¬®®®¨¨(by AâââúûûÙ4Ûßߟšš e2/^|öìY³Ù̲«}}}aaab±8>>^.—³g@°Ü\¸pÁh4rò×;aA\Ž‹}}ýúõgÏže#q\¼xqúôéaaaЈX,fOr¹<55544táÂ…:Ž}¢A8vüúë¯ï¿ÿþÞÞ^NÈâÀáz',rGtttoo/›Ý+—ËÕj5ò?3“ÙlfŸ°  `Ò¤Iiiieee~Q +**Ç—ŸŸÏ Y8°’~®™„Eä<á =Ëeçoܸ±¯¯/""‚Y³ÐæÀÀ”¼MÖ/©œ¿ýöÛ™3g¦¤¤´µµét:¨PË^ÍtÿÌ'aùØ9ð! €Ä‚ÞÙÙénÃb©gÆÈÈH8",[¶,//1Å (j2™"##ñÚ±ÉÉÉaaalD6øauuuddä½÷Þ[QQ¡T*ý2|•J•››«Ñh¸Tˆ8¢±s”JåW_}õí·ßvuuy µÉÏÏOJJŠŽŽöc¿ 'Nœ8jÔ(ü»Ý>00Àf÷%$$Œ3þ\»ví©S§Ìf3cEQƒÁ ‘HZZZL&â3ÖéÓ§ß|óÍÏ>ûL­Vsް¨"000==}úôéáááÞÜÖ•J%ˆW.Õét …Bf»W¥R}»l6co300osÔ¨Q , KKKLJ HZZZoo¯ÝngC10]'Ož3fLMMM__·ˆ9p„Eu󦦦NŸ>]"‘x#,ÿå²Q~øáýû÷3Û½Ð&‘ì¦OŸÊf8"‘Èápà£p8ìó ƒP(‰D‚¬Zµª²²R§Ó±×'Mšô׿þµ§§ÜñÙƒsãð»P quŒAT`rrrkk+³[»òׯ_ÿå—_Z­VÆÃ‘J¥ÑÑÑð§Éd `©pµµµ…‡‡C›‰Ä`0°OƒSSSãp8FŽø#GŠ¢—/_ÎËË3 œŽÉá7«²Ýng,Â444Œ5 ¶+¾c{zzØÐAqqq\\nkÛ¶mÛ·ß~ËR *--3fLll,‚ F£Ñ/Îb555"‘(,,,##ãôéÓCCCìc’”JåñãÇ_xá…ææfnWpøðˆ‹(äM˜0!22’(뱌õ1bBµÅbñÐÐË<Î&“ 'åÇüøñãÃÃÃ,Ç^^^" U*{w|AjkkSSScbb ã§rø=Š¢ …bÔ¨QSÁ0›Í@~ÜZ¸œ‚;y±)M†w „>P»´Z-ß.h?¸œ9sfOOKpðàA‹Å²yóæ_~ù¥··—½ÈÅ8Ü*aIIIBBÑÿ^°ž%¹à_Z­VfÎî¸$è"O98yd°åP”H$à'ýd¯» …„„Œ7«¹¹™¥o ->>~Ô¨Q|>ßl6³*ñ®–––ÞsÏ=/^äœÅ8Ü0„e·Ûy<žG‡ƒ¥K—^¾|™Y³ÕÌgŸ}¶¼¼œ¼B¢·Ýuîܹ©S§Î™3‡øý’%K***;"TUUEFFâÕ±Ùl,Úš‰DyVRYrŠ¢ùùùjµ:..nãÆW®\ijjò‹xõÝwßuuuåçç·´´p†|7a‘ ##ãüùóÌ6ÃÌ™3Ý=QCBBòòò˜ÙÝ- ŸÏw‘ø233‹‹‹‰‡KÑîÝ»÷ï߯Õjo`62 ‘FñI³Ûíì%,HP!vìØÑ××Qßìqý«™œ"ü›%,\ c°Nž<Éãñ@-ò¸ŸÙ¯6ŸÏgÓ ;+ …B»ÝÎf);ŽiÓ¦áîø»víúñÇY:Ž””ðnÅåS–û J‚Ï;wdd„e!üé (ºsçÎ?þñ“tò èì_|ñENN§ÿ¦‹Í‚»Q*zÕÖÖ†‡‡»+ËvøðaF ›ê]³ÜÇŽ;ãöíÛóòòØÛÝ;œ””d±XüÅÅÅÅ2™¬®®®  À_‹ð‡~HII9tè¿”Öòòò>øàóÏ?/**âá’°Ü3+\‡$è1î£Ï˜°""""""ð üâÇÁ²|Ão¯Ò‚6·lÙR]] ¥¹YâØ±c3gÎ\±b…T*õK‡††ššš¥R©¿bÚÛÛÇŒ3sæÌºº:?*"Ì|³9¢ “É4{ölòÈgíá+V0~¨û÷ïŸ:uêÔ©SñÎ`¶mÛ¶÷ßßh4úeëböÈ#4551k©ˆä²dÉ’úúzÆ~ ©¤¤¤ &À7~qtøS¦LñãBp8ãÇ¿ãŽ;z{{kjjüB.F£ñ®»î²X,ìÞ´i‚ ÅÁþHAÓ§O¯\¹òܹsa]uÂÚ¿?ŸÏÇó‚º@ 0;ƒãóù.'†Í›7ïõ×_gæèÄçóqqƒ¸V˜9^YÏeñ1Kå ?ONNNLLÄŸ\ÙÚǃ°g5“ñ"ÎÉÉéïï" j…lÌäÀ%:½¢¢R¹2´o”±cÇ* ö —Õjµ}æÌ™jµº§§Ç/ 5Ä6´··ƒTÈrÛl6ˆ™ONN–J¥………ì×’L&S©T+V¬`o÷À[p:f³ܸq~9»€w›Édêêêb¦i];•> ]T $žGëÖ­c`‰Dprìþ_óæÍ«­­e°”ÁƒÁý‡6›qš­ÜÜ\¹\îr‚%i4ˆ2¸xÏ[­V\oe°$l6[ddäôéÓñ/F£@ `c^,++S©TëÖ­ƒ?!K{e{{;ŸÏŸ?>‚ ³fÍÒét, Zî¼óNø3***00¥ØÖÖ–———’’2&ôå†R*•]]]÷ÜsOhhhUUûýKèÔ©S[·neœáŽ¢ÈvO á6aaaî†g–m†††zksΜ9555~¤Hx3øáÀÀ€H$Âàœq*g¡P¿%îÆ5´¡‘àà`—¢Ü‰Äh42*!‘(ÆÇÇcÆ&·¢H$âñx ›#§Óé;sÀòä_†……… …BÁ†„B¡@ ÀuóÌÌÌÀÀÀÎÎN6ËbEÁX- Á:Ʀ͡¡¡®®®õë׋D"¿ø^ Ò××eF/^¼è—}‡¢¨ÃáÐh4.•ñ®"a¡(ªÑh&Ožì1†7hÑdh™0aB||¼·A¼§+ y{lx°]äääDDDL˜0Á¥Ù¨¨(µZMWdÃq—dSRRº»»!]´¶¶†……¹œ ¬X±¢¾¾/wF§' Ö,Y"—Ëï1«Õ ÁCà¿ÒÑÑÁ8× Š¢V«Õ`0Ày+¬PâØDjµZ£Ñàm6›­££cdd„Í&’Ëå=== .DdÁ‚<ýÉãÐÐPww7_„„„ø¥V&¤Ÿ2eÊñãÇýeÆÙ·o_nn.±Á«ë‡•““c±XH’aÍž=»²²’®Zd4]„–Ðh4À£Ñ=66vxx˜Á5Ó}deeÒå(Àƒ¢(lZ"‘eddœ={V£Ñ0^»DÄ0,""B&“1¶âËd2›Í†ç¨€á777³ÉÛU]]­Ñh¦M›F<´)›ÙÞJ¥}}}ÙÙÙø7éééÃÃÃlŠz´¶¶¶··Ïž=ÏØÆx¡­V;<< Å „B¡D"!^aÖ¦Á`ËåB¡pÚ´i—.]b¯ôÈåò¢¢¢-[¶„‡‡³ô„6_|ñÅÓ§O7ÑÕ%,ÈìMšÀ0ìøÃÑ£G鶉x'dvìX^^Ž¿]Œb¹¹¹ œ=ï0 ‹‰‰éèè` p•••ñx<—“xŒ3/ƒ4J´ãp8ÓAuuµÉdJJJ"þ666v³TeP„¸pSSS …Édb6p‘H$ˆGqqqF£‘ïC'Åb1þŠÂ½:ÃáV|ȯ ÈÔ©SCBBØÚPµX,}}}F ,•,9 ÍÞÞÞ9sæÄÄÄ$$$°× A®¯¯OHHàóù¥¥¥×B%¤øHü‹qãÆõ÷÷ÓÝýýý È¸üŽAÛÛÛtôVh$::šXç•8df&'`G±V«•™£“J¥Šˆˆp9ví£©©‰Ù‰{Ì‚ Ë—/ïééaÀ/(Š‚¹ŠhÅGdõêÕíííŒ× (•ÊÔÔTü›ððp«ÕÊl÷Beßþþ~<Ÿ ³«« 4kfbàÐÐP[[Û²eË …€€€¾¾¾êêj6:×àà`}}}VV‚ “&M ¥«âxÔݪ««³³³ÃÂÂÂÃÃýé©R©*++~øá¸¸¸²²²ë‚°ƒääqýúõgÏžõËÃÿˆÅH^BÙê%ï§NêñȽEwÙ%y-—-[¦R©d.ljjBQ4!!Á¥'ëׯ/++£+n@#QQQ¸ÿŽI“&•””0‹øioo;HÀÏì<AÎÎN¹\>yòd|àééé  3V„ÛÛÛ322ˆ_Ž=² 1{7›L&µZMôh‰‰µÊøeoµZõz=œA8ö.þ6›M§ÓI$’   Ñ£Gççç³7céõz©TºvíÚ±cÇBšÏÿÆÒÞplÅçóÇŒã±ð=D===~v¤àó‘_~Aè´ÙÐÐ022â-ä;++K.—Óå0ߺ;"²víZf!Šjµ¢ü\zb6›…B!ihxxX§ÓÍ;×å¿Ìfs@@3ÑR(òù|üˆ0vìX­VËÀ ÖŸÏ'ꘆ ½^Ï8&I(ŠÅb;ÝܹsÕj5ãƒB£Ñèt:oºé&ü›´´4›ÍÆF„³Ñå˗ßÉÉÉr¹œO¯F£©©©Y¹r%‚ !!!aaaº’Ëh4–””¤¦¦ÆÆÆj4<âøÆ#¬âââÈÈH¨eee7n)5!!× ¯.a­Ô/áõÄ}k±Xü¨³3qâDðÍóˆÛo½õø]w9iî^biw~éëë£ëÙ V«½E5Úl6ºvw°•FFF¦§§»ÿï† ŠŠŠˆ`Ìvw¹Z±bESS³3þ®®.¥RI”Ú0 ãñx†YÀ€\.ïêêrÉß$ê'éNÇG|:£G6›Í ù8¹€t†÷'&&Æáp0›FEõz}EE´ÎãñØø^hµÚêêê5kÖÀŸñññ‰„¥G¾Édjll„'>jԨѣGãQSW—°ÎŸ?gðˆÉ“'Óz§‘ºÈQ[[‹a˜7Ç.A¥§_Y¼£³ˆù|~||<‰?ƒ£L\Þqø”)Sºººè†Fµ··+•Êääd÷ Œoiia`1›Íî¾à@G×™× 'Äì ‚Œ?¼[è>q«Õ:22âÞ™ØØØ®®.º†6<ŠÐÝ :kÖ,f*!ø0VVVBj-Ó¦Mc£êõú¶¶¶™3gwŸH$bÃ/‡Ãh4J$œ°XJX`äÕjµëׯÒ5jØÅ®:aµ´´„‡‡,©µk×9rÄ'†S¦LÁ蟢F£!¹Þj³ iziY,w.À_ ´‚ið¾ysÏÊÊb`Ã2`ª÷¨Y3ð¿Ôh4iiiî Z,pI¡þhàx[§ÓyÌ-µ|ùòÒÒÒ‘‘ºýÔh4ÆýlÔh4ŠD"º c* b9B(" Š0]VÕëõ½½½Ä™Ä¹’†Áãñbccñw3´`·ÛAÇd¦²(•Êüüü;î¸!{1>ÅÇXPP¦¥¥áòµòay³§ ΓDDGGû%™,Ž›o¾ùÀÔ1Š¢¾5Þ±—G"“ÉÀráñ™=üðÃíííÔ5eEÛÛÛÍf3n+u—_Ôj5]Õ¤€€¢ZÈÌÌÔjµ]]] ^'CCCçÎÃ2¡…Å‹£(Ê ž¾Y*•FEEág—sæÌ ohh`–ÄápH¥Rb5O¼'‚ ¬ÂGáTè›o¾Q«ÕmmmD+&u8NŠú̈Ýn'·.GFF2?FéìD ­Á) Eí ²w/â2û†„…!ü£7•ÐÛ †a£GÎÍÍ¥¥Á 98áö(10÷÷÷ÇÆÆºœÄãØ²eˉ'¶nÝêñ@ÖÛÓ™ÈãÀ'MšTUUe6›qõ¢v`µZÁéÔ] ï9®câýÄ0,00„/º Úív«Õêq¢nºé¦ŠŠŠ¾¾>rÈGV-((xá…\¾;vlyyùÈȈÇs'ò§ÑB.‡³lf,0ŠýüóÏ[·n%>q‰D"'­5™L«V­Â¿IJJòa!vûí·www+ ÿ×=NÐÈÈȬY³Üͥ̕ÙíöÿÒÇèÑȪUˆÝþôÄãÍ*+«]´q‘D0 a”-ž+¹êQ˜'Ïb2™:Á:::zzzÄb±ÇŸŒ?^*•RgU ºù曽ѼMëéÚîÿøÇ•+WÞrË-$Áª÷íèÑ£A['Ž>Ûl6ÜÅŸº€ Óéúûûï¾ûn÷ÿ Î¥»NÌfóðð0˜Sˆ=1›Í3Ùú|:6›­½½ö±A8(`VŠÍn·º„ˆ¤§§ÿôÓO999*¯¨¨Ø¹s'þÈBBBBBB`ت„"‘(..nܸqAAA× ×j}}½F£¡õŠö ©Tš––ö_¥#0;IH@âãÿûoܸõ7ßüŸãÇø7ð/!;ñ|È·:Ý} lEòJعsçþýû!é-Å6m6InBQß}}}---Å@AfΜÙÑÑAWƒ«¯¯onn‰Ë<óù|­VKËr‡¢¨\.?þ¼·½ôÇ?þ±¼¼\&“Ñu‘kmmu×1™0aB\\W‘HäQV]·nÝÈÈ1Z…ºQ¬ªª*33Ó½‡N§“™gƒÅbimm%ZññR) ²Ñâ¸Øf³]¾|Èw©±àŸ|XW#é•gû·ÕÊ,- ¡©·ɈP8(—cÉÂm!¢(ZSSãp8ðƒ^o¯ºõi&L˜@¬zï‚Q£F St•pÉ„åm-ÒuÅr8f³ÙÛˆÒÓÓëêêè*\zÜ}¢`í9Nº1‹E£Ñ@¦*v1£ÑH}áùµ½YÖÓÒÒŠ‹‹iYiQU*•?ýôÓ¶mÛ<Þ"˜™_ÜK·G9ÒÝŃ¡¼¼œ„Ï%!!A àŽ8Ôn·Û«««=væjâŽ$>·Åb¡¥ÁùœØiÔ´Ùl$ùvÿkŠ¢³oá‡ÜôóÏþ³²²’º³{AAøR_‹äs¨Óét:·à!AvìØqðàA¥RI}àPÊÈ£h‰o ê[W“œÛÌ;·££ƒ–\Éçó=zŠá:Ç£5“‹¥½½‚Ò]ºC0™Ltß²‡C¯×»G8áeÙ r-~:räÈã?îÞà† ôz}]]Ý“k@ÔéÒ“¤¤$>ŸÏÀ”l³ÙJKKA ôØ™«EX(Šö÷÷/Z´ÈcÞa"ž{î9ÜŠÞN IDATÉÂ/xá…^yå?2 3Á“|1EDDäååQ÷µX,@Þš¢>–žžµZ={öl’åh0hy·–——·µµÝzë­Þ沕QÜi`“ÉdP'Â#–.]ÚÜÜLËÁµ¥¥¥°°póæÍÿwÖ¬Yýýý´,Ðjµº©©iéÒ¥ÞFgX¤åÏ!¼Ñ\zzzIIIss3ÅÇß×#¹ vLZ†6x:_|ñÅîÝ»Ý7ÑäÉ“y<5Ójµ–––º \ ÂB¤¡¡A¡P§ï£ZIÉ+³CP³2YZ `œ&Ô[?i‰ˆ¯À£%K–”——S·‘ƒï-¸AìLo> €§Ÿ~úСC*•Šb˃ƒƒ½½½}pS ää¤%¼PÿÔ©S»»»i%Ã0Œ<©ÑŸÿüçÊÊÊÎÎNêó)—Ë=ú—¿üÅÛ¨ñ©¦¸r¬VkMM †Ü»‘œœl±Xè~CÚ̘1cø|>3Â*..&{âW°œN§Ï÷3ž}‰z›)))cÇŽõ‹¸D^à‹ˆ_z©ðŠƒ$­cåÚçû9==½¸¸˜îiy›x+]Ó†·§ ‰ {­—É«bΜ9àÄÀrçÑãù_VbZƒÅõV …Tl#îï3o3ŸššªR©hëÁÑ›7É%..Îl6Ó­¢Õj?ýôÓ;vxÛV0dZO7)xûÕ ü|ôèQ¥Ré[ËXw“ÉdS¦L!:}x^sË—_¸pb³§OŸ¶Ûí.n„î‡"·‚ Ö`0¸$„ò¸D¨½¯¯ÏÝ%ÝÏ<óL}}=•¬X“óøQ¿ö†´´´PÌŠ~C###O<ñɽæÎ 1Uç³··÷ĉ=ô³·‚Ç‹CBB,Xàmø‰‰‰*•ŠnrToKÎ=õ÷œG·‹~G}[,–wß}÷å—_&yî7d>,¿ˆ€ŽŽŽöövßVÿŒ Ì»ð¿ÿýïÅÅÅߺÝÝ݃˜mŽ|WSxoo¯F£Á£¼‰………T¤6E[[[«ªª¶lÙBrÙ‚ ‚ƒƒ©oàÆÆÆ’’’Ûo¿Ö." ®\¹BžEkÉ’%ß}÷]__Eš&¿5†a·Ýv[yy9ŃBˆkùøã![ {Mú¦R©¾øâ‹Ç{̽«ÐÔ=÷Ü#“Éjjj¨´ Çy%%%àuLrZEW6÷yvôÛ$, êÔNå±û]j¸téE¢øìÁ–®¤C~1ݦHF„aXZZÚ'Ÿ|244D—}Hº!¨ð©cÒ~_Y¹]܈¨ëGä}¸ÿþûjîé.þäÍRç›ÍVVVæMÇÄ0léÒ¥f³JUûl.°X,ï¼óΓO>IrýuDX~ôäz饗T'd¿ˆ)Ú›pÅQ¿ûî»>OÐqcÏc±XLݼ\@’¢!¢²u]*M`×®]GŽ¡B‚ h´´´,Z´ˆ|Ôv»â»dxxøûï¿úé§É/ãŇn4«ªªHNÊ`kkk)†¿Øl¶’’w—Q"f̘¡ÑhhÙÝIJ^¹{I—Îìv;ûjHD„„„PI½DL_éÇ»Ûl6¨ìó2*)à‚¨¨(wÅ–-[ª««)º’Ëåòþþ~Ùµ\ÔLŠ[W£Ñ(•Jo'eÄQSO}¡ÑhÚÛÛÇïm9avûí·Ÿ?žbNð?ðy8ûØctuuQy—ƺº:—*. | ÂjµVUU‘„úb6jÔ(0ò¹×pç²÷ßÿÑG%¹8--Íh4R,ïf·Ûßyç÷ØÉkGXZ­vêÔ©.©‘_Þ¸·yÉh ò²²êêꨚw:$žÌxR*Ê5Ä„èt:HFFrñôéÓF£Oš&nF¥öü@X.Ò£Ëâ±cÇÔjµD"ñùÔÍfsII‰Ï›vuu‰D"oI¦˜áìÙ³|>¯%Ç^wëëë³X,.©‘¼Ñt^^•6ñµNÞ“ÀÀ@’È—ç…›~|n!Ÿ[×1©L×üùó!g,•[‹ÅbŸ\°bÅŠêêjŸ¡*°Í ª«Ï[GDDP´‹étºªª*o/ˆ šL&*Ç‹¥´´tõêÕ>y-00bþ‹ÅråÊ•|üʻᄏ­­­¾¾žŠÈÿÁüóŸÿ$¿,55•:a9Ž>øà/ù y'ô÷÷Ëd2…B100à^ÁI$Q÷?¤¢Cutt…B’Ô  ì¦>ó—Òp7.°Z­eee´¼TÈ‘••uñâEŠ4„Pó3fÌàà ù|ârÏ×#Œšb©¸Ó}’i‰‹‹kmmuIIꃃƒ‡"Ötð†Gy¤³³“• ƦÎ0ù[š ¹P|ê>iÚ  WZáÊI“&AܵÏûêõz“É„Wè$ÁÎ;¿üòKŸf,¥RÙÑÑA%!Z||<ÅLD===?ýô“K–t\)‘HHÒNß%ì…ŠQ[[Kž!îe2™ÂÃÃÉo¿¶©„%af±X¼Åf»XˆrrrÈIV¬L&sO¯êŽyóæ öôôP‘†ÎŸ?O¬›ímÔ111ÑáS ÈÍÍÅSÊ\•044ô©§žÚ¶mÛã?¾uëÖ¤¤$ÕŒ¯²³³ùåÿ¶)‘H¨dËDQ4((ˆÊ‚³Ûí> Ò‰D"ò`!¯1EVkkëÂ… }+¤Ù¢b W($…<ðe³qãÆÃ‡S^ jáwõêÕW®\ñ™Þb±( *yï¬V«O Ôd2•––’§åÀ‘˜˜8<<ì³þ•Ùl.**"W q •`‹Åòõ×_{ó•%Îyxx¸R©„pwz×ÓÓ3qâDŸëgýúõr¹œJÎø .ø|+³R ]fùjgï£E¦Ó¦Mƒ¢XT”,Š=_·nÝéÓ§}^¦P(‚ƒƒÉ=È)))T‚­ËËË)Zîð“fò•Yñ¨pÍf£rÎËãñø|¾Oánç³â!®cR‘ @Öèèèðy÷ÁÁÁóçϯZµÊç6ËÈȨ««óS y¨ìóÊÚÚZ‰D’à/Ÿxp³¤[ÎïÃ`0@ÅSв†O““\.—ËåT¬$ÐŽT*õI—ƒbý©PðôéÓOœ8AnÈçñxáááPÁçb[´hQ^^ù1 $¾í¶Û(Nûüù󛚚È¿õz}nnîâÅ‹©¸k¥§§K¥Rò`‡ÃÑÓÓã’"Ë—/—J¥ÞüÝá=WZZ qøTÍÂ… {{{e2¹úvòäɬ¬,ŠÛ0==}``€¼Fw^^yìäÕ%,E$ EÁjµR9a‚a3¨èÇ>3£ºäÇ Ø=Ÿ%»»»‡††|z¨ò Cww7õ‡ÃA’¾„ *4™LÁÁÁäê0‘‡§Yòˆ’}úøÅÕ044Dâ#‚¢h__XQ(nÃ9sæ ’ÖéÓ§³²²~5ÂSŽJ¥¢ò†¤ü؈âËçòåË~Œ×ËÊÊ"wƒ8{FCQG@dåÊ•yyyäÔjµ&“I(R!ßñãÇ÷ôô_ÉçóiñËš5kd2™7»dž”J¥äétˆHLLìïï'ï€Z­...†Z)Û”Ëå$NI6›mdd„ŠÞàà`’‡6›­¨¨ˆâ!`„ wß['­Vë¥K—,X@qÔ ,hkk#‘Ú0 ¢˜Ž zµtéÒ®®.½^ï­“gΜñVÉ›„%“ɼ%ÃÁ‹R9g¸Š„~ţ쬬3gÎøì$â½’¨Ë´.]ºÔ§«DWWIÞaw¬]»ÖgLõRAÖ¯_îÜ9r *]S/µvíÚóçÏ“*áq8F B½· Nž<é1m?I'—-[ÖÚÚªT*=RRqq1„%þš*!]Ëbøt3(HI.ÙíöˆˆˆkS£Œ)¬{>CÕ(ZRpl3Š£ÆkÖ“–H$¢˜ÔO$žAû Óé®\¹B”ã‚I“&õööz4ÌÁ-$ xR<™%=vÒn·wvvÒŠl?~¼\.÷öúq8¹¹¹ÔU\j+**Òjµ3>·¶¶R·,Y²D*•ztï‚y(//Ÿ9s&­-ÞÕÕå­ÂÛÑ£GÝëN^ï„§ì$ž†‘d§gf£µÕ}Ï&å@B€Ñh$¿“ÉdT|^pL:•Ü© g¦8êÍ›7·µµ‘/W®\¡hÙ<ðÀGޱÛíÞj¸*•JZR³³³½©„àp÷óÏ?Óٹ뮻@ôØI‹ÅRPP@Ñ¿ 7YVWW{Û·†ŒŒûXº#**ª­­Í›ËØÙ³gimØ€111!!!ˆ§4Š---wÞy'Ý-“ÝÒÒâžÉÚ‡B„T &\lÅãñV­Zõã?’̵R·¼˜L&ÿ&¥r÷Ü1<É@xyä‘G\œòQ­¬¬—@ºÅ:KJJ@—t)S£f°©SRRd2qKB#===äÙÄü¬FFFnÙ²eÓ¦MñññÄõg±X@.ð×Ö¥ž ‹¢£×ëív;$3ò¨§Ù¦h3™LðR¢þDwíÚU^^N2$5нaܸq999û™Tb°\k4=2 N§ûþûïén]A ƒ{<žŽ–WþCNç‘Q £îpG-¥R©» a˜B¡3f 3᥸¸ØÝãܹs d@˜¢)S¦´´´IEÑ>úhÛ¶mÌ6õìÙ³›››‰¹kPmllœ3gõt›~P ATTÄß»˜ÓhÊç>ïììt:Ôì(>Zï áÚ‰‹‹£›ÁyçÎÿþ÷¿IRŒÓÙ O‰3j{{{AAÁ<@—ˆ½™u!/­Th0<Ëå€øÑ®]»\¼œ 5nuu5-' ¼“éééaaaî4›ÍÿùÏÈëÐxÄüùó+**“999=ûÝñÈ#;v í€FΞ=K«p· ÒÓÓÃÃáŸÐÈ™3gV®\yƒ;FѰBý9##ãüùó$jNbb"Å|Áû™1`œîîîŸ~ú‰J•,[¶¬  À[ýzZ"þÃÜÜ\o¾]Ä%H«YŠŒÉdª¨¨``BdùòåÅÅÅ.®žV«µ¼¼œ®9þr)z:æ[o½Eþ~%ÁÊ•+¯\¹BtÓ ]+qY.X° 44ÔE« ^ÛãÇkЩ¬¬ ÒH0¶JÏš5ëàÁƒ¢hUUÕM7ÝD%sçµ ,êÂ‹ß 7’Íyùò劊 ?ŘÁétz34€ ŸbÕªUîÄ ­Âðð0ØMén ÷™t9?¢û—.]êÍU‚±.Ÿ™™YXXèÒU›ÍV\\Ì@iEäÉ'ŸÜ»w¯‹=Ã0*i|¨ ¿(оüòË{öìa¼ŠV­Zµwï^¼æŠ¢{öìñY””ü‰/Y²¤®®79åææR #!A¢ÂqHt—÷Õ"¬äädqÁÕsŒ`Ð2‰©RdÐr«Ã0ìÅ_|þùç¯ÍдZmYYÝwš·6Q5›Íµµµ „Ⱥ÷Ê+¯x²»†ðx<÷³\?8ý¹ŸYƒË—////wÑ'HÞ[—¥ M³lätbé pìbÓCAþñüðÃànƬÁ«BXùùù]]]S¦Lñ—r„/Ç_]…¼ˆkUUUnn.•R"´=“‡z&êÕW_}饗\¾4õõõ ”Vo×ëõŸ|ò c_¹reaa!‘ÇåË—çápWÖœNgQQÑSO=Å€ 1 KKK«¨¨Â"VBaS%oùòå•••ÄCÆÜÜ\Š9v4ªR©ªªªúžÊ .|ýõ×ÝÿK­V7773ˆ/Å´N'ŪŸñ /\¸pÁåKÆæ!èžX,v9Ás2Þf—/_&®=»ÝNžo‡ŠÉ©¨¨È=]2³Wü*88°ÛíðP¿;ñÉ„çççÓu˜òÖfhh(Š¢ï¼óÎöíÛ©"¼N ‹ÏçÏš5Ëã6c<; .ôæ6544¤R©¨ç2¦hÜaöB[³fÉdòÆÔþÒ¶À†ÕÞÞž˜˜È ŸaaaîqÿÃÃÇÚ¼y3³Ûíö¢¢"â7‹¥¤¤„—•••——G4<ét:pþd‘HD1 ËÍÍ¥˜€Ü/^\YY‰;FhµZ6=ÄU¶}ûöÁùÀË/¿ÌØ‹ˆÌÌL(gUTT4þ|¿˜þþ÷¿Ërµ›Íf±XŒ ù…\V¬Xæ6FÞRÁÁÁN§ó½÷Þ{ì±Ç¸‰ÝH)’ýx\H«Ø±±±îß·´´ÔÔÔÜÿý̈ÕE6†e§×ëWñˆ‰‰!æ3Â)•<_ ©èÄ`2™˜5ÈÎÎÆCqdi‰D`¿ó ¥b–œœ\YYIô5³Z­,߬kÖ¬),,ÄÉ:((ÈgÑV*+sddúyúôifžýî„UVVÆãñÞxã;vPOþE2ŸwÝu×÷ߟ‘‘ÁìAû'½Œ»sݘrX­V§ÓÉ@ãõot†aÛ¶mûÏþãQ¥¥›†h röôô<üðÃ̺úÔSO½óÎ;Äoôz}MM WšðÆÆ_饥¥´ÊƸLæ´iÓª««‰kf``€b!nŸ$ Êd2Zá\™:""Â`0àmæää0*&|âĉ555¸] /œÅ¦Í»ï¾{ÿþý@|óæÍcO.‰‰‰}}}µµµñññðð‹ëž{îÙ³g³°D¶±„‹¥£££³³Ó`0à»Îh4S¬ýIE€jmm5›Í3fÌ``yñXU ¯îKw¼lJ½A"‘¸'`Ñ€‚ìãb 7™L bhp¬]»–XˆÈjµJ¥Rf.éø# çÌfóþýûwìØÁf%''×ÖÖ³8Ž}ûö±i8DªU[[›œœÌ˜`àQQQxvÀ}ûöýéOb‹ ȨQ£ Ãàà`bb"yamêmnܸñÖ[o}â‰'üe®Á0ìÕW_]¼x13yíÞÓëõ§OŸ¾|ùòÐо“ëêêbcc§NJ«CÞŽ‡är¹Íf£^¥—z233=Öæ2›ÍB¡ÐUï!Ï­¤8²²²Ü;ÉXiØl6—É„ b6UùdÁ‚£®=ü“^Æl6Õ+GKoI{Ò¤I_ýµdža˜Ífó˜>A­VC²c±¦ÖÇå‡ÍÍÍ ЛÙððpss3õ¼æî¦Íï¾ûŽø¥V«­ªªbã10wîÜŠŠ ¢pýË/¿dff²YÇøÑªÅb9räHvv6Ë‘œœÜÖÖoA©TJ+¡¥Çɼå–[ðÄmmmtSžyˆ‚´´´@ý1öX½zu^^^aaaVV–_$,Ь׮] luõÂ~¯JèG)÷vó(ÔøÑ„üðÎ;ïüæ›oÜ%DƧQ(ŠB1qâ¾cDhh(ã€Gw-¸¿¿ŸVMM—}{ë­·þøã!'›8\%,..†Ïb±˜Vý1oHOO‡œ«¥¥¥žŒMƒðÛææfxó•——§§§³_ëÖ­;wW®\a˜íþ€À³hÑ¢iÓ¦ù‹\\š9ÂòýàuÄL9²X,ÞR0ËeŒx²g³lAììlžÉdr/=00ÐÒÒÂloðx¼›o¾ùèÑ£Ä/•Je}}=ãÝ‹¢èäÉ“‰„e±X”J%K K¯×ã¾y(ŠЭ$êŽ1cÆ@Ú\‡ÃÑßߟ˜˜È~Ádddäææ ‚Ó§OûåA•+WŠD¢çž{.::š½¬aؼyó9ÂÞ« o3--íµ×^cPèô÷ ÿ–T*5 NRÄbñ²eËHªŸ2ƒ» J]139AL5d!²˜P(dcÃÊÊÊ:tèKƒŒ½FÉÉÉx1m›ÍÖ××ÇÀë“&M‚8«ÕšŸŸÏÆá›8öcÇŽõõõÓuµóƱ±±ÿüç?7nÜèm 7mݺ•™+ŒÇ61 Û±cǨQ£~«ÒÐAXz½^©T28Ôãñx111+ÇåÑ2®÷Bâ×8D÷P2°y,íMqíŽ5êÊ•+Ä>Ëd2–ü’«ÃƒM Ñ”süøqA„BaOOH$ò‹ùyáÂ…·Þz+Tdñ ¿`6cÆ ?žÄCΩ 6ø±Mާ® Â',fÉ=FÕ¡(:vìXf^é"‘è¾ûîëíí%.6q[›V«µZ­·Ür ã]èlXlÒΔ—~²ÛíÃÃÃ,m±@.111mmmGŽÙ²e â'óóG}”••uï½÷úךãGF¸ÞN÷9º~QWW×ÞÞÎ,ŽÏçOš4É%_KKKkkë† 3ò´iÓzzzðµ;44TWWÉ&¾ ¬~ЂÝn{›Nç´iÓàT"‘@¹0–I†­^½úìÙ³2™lâĉþ^&Ož¼{÷nº¥ä9p„õ+Ãn·»;¦«T*ð f&µY­V—Ðb­V«Óé˜mHŽJ´µÙív(†Ê˜x<ÞÊ•+:„gzijG²á—Õ«WŸ>}Úáp|ûí·~±7!²|ùò£G~úé§[·nõ£ðï8ù…ï@X‡ƒ K LŸ>üof6>„%»›œØÐAhh(1F—}.ˆûíîî>=yò¤_N»E"‘Ífs8r¹œeV_YYYIII/½ôc§yΦÃá:",E'NœÈàŒ_$-Y²äìÙ³þíÑÅ OêÆæDA›Ívwh0&&†e 0‚ &“)88W*•ì=’x<ÞO<ñöÛo#ÒÙÙùøãûåáJ$’×^{móæÍÅp¸Á ÁŠÅb<¡B~~~gg'Ý.h* €˜zO¿ç’H—:Äbñ£>úÆoàûÍd2Éårnb8ø|þœ9s EÑÁÁÁcÇŽ±t"çóù;vìxíµ×äÁÝßß/‰Îž=˸j¹ûcŠŠŠb>ȃ Ë-¡P(>úè#N×ÒÒåXL&ž£–ú£sñÖÕh4AAAwÞy'³Ý…¢hXX˜À …¢§§gÁ‚lÈeùòå¸Çn·ëõz6 ôS"‘@?FcSS³!»kÙ=ôPLLÌ®]»?y p‡•°@Ú½{w{{û§Ÿ~êŽã—-—Ëëëë™ÅÄz$AˆRö˜s†:¹…B\ècØO˜@½^_]]í—Š>B¡ðwÞ‰‰‰ñK nx•Çã‰Å ö ê`]"–{aioBüšÙç>¼W*•jdd䡇bÙ²X,~òÉ'?þøã   b–‚[DDÄ+¯¼‚øÕu–‡’°ü®H$’-[¶|òÉ'~lY$Í›7¯®®ŽèûÇòP/((hûöí|ð‚ Z­¶´´”=#€éjxxø«¯¾ˆ½O&.r8Âò?@½òo®>±X|ÓM7]¼xþljj*..¾óÎ;Yò ÞO<áFÀ0L,ïܹóùçŸohh`ããîñ±‡ßüYuÏçkµÚØØXHóèô÷÷Ïš5ëj#{ÂÂ0¬¡¡Yñw÷΄‡‡Ÿ>}º¥¥%--“‰8p¸ºŸÏïëëkjjòW Ad2ÙÈÈH\\ˆ(µ¹û‘2†·mÛöÒK/9Žææf–u€ñf…BavvööíÛ9¶âÀáZ¨„¸9ãŸãQ). 2nV,ÏŸ??77þ a™“zât:¡`¯Ýn÷KÉ6Îc€‡kMX,EŒ‡zü'‰…lÚ³gφ„Ü===GŽaã„…C"‘<öØc[·nÍÉɹ÷Þ{¹38nHÂÂÐÌD <êþ´Z­¡¡¡,ÅPâ@i …Ìʺ nsæÌéîî†2œLÄÃ5€À¿Í¡(*‰XªH8ßI¥ÒÚÚÚû￟e¯oºé¦ÒÒÒqãÆ 6ÅD‰‚ÛòåË•JåæÍ›9“7ž„‘4‘‘‘l"ATT8ŽC.c–™‚Aš2eJ]]]ÿ¥K—Ö®]ËÞg ðàà`Ž­8p¸Q K(–——×ÔÔDEE1f„ÈÈÈ[o½õã?õÐjµBVb¤@ÝÝÝíp8 ¾¡£ê8¶âÀáFU ÙWv:f³9((A¹\ÞÛÛËÒF¢ÐwÜ‘––á/ŸL8Ü`.F fyÜÝÁçóÔJ%‚ fxx˜e¢8 ÎÀÀÀµk×–––nܸ‘{ê8ü EQ£ÑXQQQ]]­R© º:Ë3¸yóæ?A“Éíµ+""âÙgŸ}ì±ÇæÏŸÏ¹ pàð;U -Kssóðð°Á`0 IIIlD6>Ÿ×ØØˆ H[[ÛÒ¥KÙœÈÓÒÒšYº8pàðÛ!, Ã"""î»ï>™L600ÐÖÖÀ†bpõmÚ´iEEEF£‘ ý¹4ëþ™¿/•>˜Íf§Ó©Óéz{{Ù§¯ŠÍÎÎ~å•WúúúæÍ›Ç=$8ø°\Ûâñü’Æ/44tÖ¬YõõõQQQIIIœÉ‰~P ]Àçóy<Ëê Åtîܹï¾ûîܹs9%Žþ',>ŸßÚÚÀ298‘K$’Ûo¿álä8p¸*!ÇÐjµlÜÜqÎòø™aù¯-v%š9pàÀá–@ àóùì•9pàÀáêŸÏojjjkkûÃþÀÍ)®kÂBQT§Ó †1cÆpsʇë]%„BÄtì8pàpu Ë[&uŸÖm6ÛŒ3Ö¯_ÏÍ)®aÓSCCƒN§#žôÁ÷ÅÅÅo¼ñøI¹7äp8 |ç˜Î‡«NXÀJßÿýt:ñ"EKKK ÃO<ñöÛo»sŠ¢3fÌ€äëœOüà‘tjkk׬Y322âžÓ*''çÿøÇ3ÈÿÒ·¿ùæ›<odd¤¤¤d`` ··Ò±ûxýdL³ê½7áÑ· {=ƒ^1õo`b¯Û_‡s{®(rØl¶Ù³gßrË-‚.^¼xîÜ9>Ÿ?eÊ”ìì숈\D"†ÅØív@àt:ñoÂÂÂ^~ùeJ¥úå—_´ZíÕ`+>ŸßÑÑa·Û“““)fƒÀ0¬°°pùòåçZ TWWÇÆÆŽ=šâOL&SmmíâÅ‹)æ,EEE©©©šÊB”Ëå³gϦx —ŸŸ¿hÑ"ŠÕ­ù|~[[‚ “'O¦8±N§³¨¨hÙ²eÔ'¶²²rìØ±±±±b0-ZD=¤@ (((˜;w.ÅŠM<¯¿¿_­V§¥¥Q¼ Š¢ùùùÔ³' ‚ÆÆÆ   ÄÄDŠsk³ÙÊÊÊ–-[Fñz@PVV6iÒ¤ððp*¢¨Z­noo¿é¦›(ŽšÏ礧§ …BŠÛÛÛ«×ë§OŸî—zz‚X­Öÿƒœ@IÁ>ú¨§§>?Þét^¸páÂ… N§óÅ_Ä0 ¿à¼ÊÀ0,77÷Ô©SÔïe·Ûñ®R¼Åjjj(þðááá·ß~›Ö-þõ¯) ê·¨¯¯ß¿?­[¼øâ‹6›úõgÏž=wîõ[X­Ö—^z‰V—¾ú꫆†ê£x÷Ýwi­+ Ã^ýuFCýú²²²ï¿ÿžÖ@^xáZ×;v¬°°úO Ã+¯¼Bë}ôQgg'õ¹íììüè£hÝâÕW_ÕëõÔ¯¿|ùò?þèwZªMNR©ôôéÓjµzïÞ½;wîŒÅ ê+V¬¸téÒž={à™¹ª®Ýjâĉ@ØïÅãñV¬XA«o3g΄!Sü Š¢tC‘-ZE€(þ$66vÖ¬Y´n‘‘‘ÇHQÁäÉ“i=Då‚fÏžCý'!!! .¤»®–.]*‹©ÿdܸq´ž~%õë§NJëB¡ФP¿Ezzzxx8õŸDDD¤§§Ó5¾Ô© !!J^Z JIØÿÄoðÏî—]0¾;õë©ÜÂåš‘‘˜ýüjŒúÜÂf³íÙ³çê=;fÏúÚÜåå—_¾®ºt5ná¾ë_ýuƒÁ@üÆ‹œ.ø/¾ø¢·¦Ç¬ ¿Ê! ã»Ó}y’üäJ»ÝnµZq}> `ܸqð_ðHŒGtGÁ`Ô×à ÄÇÇ_W]ú}Üï·€•lµZÁK .qqq›¶ŸÏ÷ûV¥:dÎmŠÖiÅ… *++wî܉wq¶êèèP«ÕtÐ_Â/~àâ¯ÇϸM—ëÉNü_Ÿwôxù—$Ÿ] É5ÌfŒâÀiM×õ†ýû÷‹Åb8‚s‘Õj=sæÌ† ~­¾ñ8¢ŽsçÎ………ýãÿسgË+¥¥¥eß¾}þ•+m6›Á`pß.¨ì:b›z½ž¬jµZÕjµË¶ôv±ÙlÖëõ‡ƒ¸Üu:äþ×h4jµZ£Ñà?Ñh4Ä6áMîÒOè< žÍCËÄ6‰Ì¢V«- ¶Òétxk$‡kl6›ÉdBQÔáp@€-ñlýúǾ}û–/_žžž^PP@t ‡¡üç?ÿA~=ÿpްh ¸¸xÁ‚V«U,¿W«ÕN§ó‘GñcvXR©ôÛo¿õHd8P!/ØÀ½º­­í›o¾ñykbƒðùĉï¿ÿ>¾iÍf3É>¼xñâÇ,“ÉðhµÚO?ýT§ÓíÛ·ïÕW_ýì³ÏvïÞ­P(Píîî~ë­·´Z-±Ížžž/¿üÒ¥ÙŸ~ú©©©ÉEéøì³Ïð6p~Q(ï¿ÿ~EEݙǻ=44´k×.’…ÿúsŸàô£G~÷Ýwðì¾üòËýû÷÷÷÷#7NˆH$2›Í“'OnkkÓëõÄÿ:zô¨Ùl^°`ãGX׉Äh4òù|p“aÁh4†‡‡§¤¤˜L&?'Á‚°X,AAA`à7™LF£Ã0•JuêÔ)©TŠ ˆJ¥êïï‡ý©P( …N§S(&“I¡PÀB¤··÷СCZ­ÖjµBã}}}F£Ñáp Ûl6ø_\<±X,r¹ÄœžžžwÞy'##ÞØØxüøq‹Åb0ìv»Åb†N"ØßßßÕÕe·Ûaº¶nÝ:vìX‰D"‰ø|þ®]»Þ|óMAî»ï>«Õúú믗——ƒh2™Ìf38¬áÍÚl¶øøøáááC‡ÁèˆÛŒÇãíÚµkppðÍ7ß‹¯J¥zúé§,Xàp8T*•Á`鬯¯±‘‘£Ñh4M&“Ýn‡©pÙŠ{öìùôÓOëv÷ïß?44„¢¨^¯—ËåøŒ!R]]ýä“O"rüøñÉ“'Ûíö‹/Þ@*!n‡ [Õàà 8Ð:uª£££¼¼¼®®î×êÞÿÝ9øDhhhcc£@ P«Õ³fÍ2›Í.\ÐétqqqJ¥²µµU.—O:ÕEþb ƒÁpéÒ%½^üùçŸ+•ÊÒÒR‰Drüøñ÷Þ{oìØ±ááá§NºpáBPPÐÐÐP^^Þ¡C‡ÆŽûÿþßÿ“Éd'OžLNN~ï½÷êëëSRRrss|ðÁ¹sç*•Ê… ž9sæèÑ£F£Q,ñÅ:.//O¯×?žÏçÛl¶'N”••566¦¤¤lÞ¼9,,lÍš5cÆŒ1™L›6mêëë›8qâÑ£G[ZZƒ‚‚öîÝ«T*+**ŸÏ¯©©±Ûí•••ÑÑÑ¡¡¡999wÞygTTTYYYJJJmmí„ ,X Õj/_¾œ‘‘xæÌ›ÍÖÔÔ422Òßß?nܸ?üP¥R•——[­Ö„„„¤¤¤òòòÐÐÐÄÄD|®®\¹Òßß?uêÔÚÚÚñãÇ/\¸EÑòòò¿þõ¯kÖ¬‰ˆˆxíµ×Äb±J¥’Éd”H$ÇŽ«­­íîª2™L?ÿüsTTTTTQtZ·nÝ[o½õÔSO RQQ±iÓ¦”””‰'~ûí·uuuIII`“Ž‹‹“H$½½½‰‰‰!!!¹¹¹ ¸“ÐuŽ¡PØÞÞ—˜˜(^{íµ…  …ÂM›6ÍŸ?_©TnÚ´é×¢`N¢¡)̘1#:::''çÁ„ê>£GŽŒŒ4›ÍW®\imm…Mâ¯ÛýðÃááá_ýõáÇgÏž½zõê7>ÿüóJ¥réÒ¥ÿþ÷¿çÌ™óàƒ677/X° $$äûï¿OKK;wî\ppðààà×_½téÒñãÇßvÛm"‘èØ±c¹¹¹q °°pxxxÿþý­­­ìîîý÷Ë/¿|ôÑGÏŸÿÿÚ»šØ¤–6|(´PþÄP¤µ•Š èqa[ª¥!M´&­‰&*¤6Ý4 ]ëÂ…M\˜ø“èÂÄ4Ö˜šˆ‰M£±%Æ l¡ˆDÃ?Ô˜Êåô.æ^Ò¯ßýüêÕ½¹ådÎÌ™ÃÌ3ïó¾óðNŒŽŽ¶´´ìÞ½†a‚ðx¼Z­Þ¿¿P(‰Dƒƒƒl6;‰Ʊ±±¡¡!*•Ç._¾l³Ùôz=“É—’ÊÊÊÞ¿ÿäɃÁ&«R©º»»µZ-†a§OŸŽÇãD"‘Çã 3 EM&Ó£GîÞ½ A“É´ÙlsssÿqðâñÁ`ðéÓ§ƒ˜8N¡Pàñø“'O …Âááá²²²X,vîÜ9N÷éÓ§›7o’Éä[·n¹Ýî¡¡!ƒÁpýúu£ÑøßvîJ§!Ptwwëõú/^ôööÞ¾}Ûl6—g³Y‚P´ìþJXíW[äííí(Šær9†FK$<_‚§ÖÖVèçI† ëH´v޶¼¼ Ã0 Ã`‰ÄRžWµZ½Êùú£%‘H†ñù|FÈ YÁï÷WVVÖÖÖ¶··;Îùùy¹\îøµ´´h4Aîܹ …¶oßÜ^/Èd2`C7n$@ØpøðáÍ›7?~ü0‚™™†q8œR©t: e%ÕÍçó ïwWW×ÔÔƒÁX^^ær¹³³³.— ðšššS§N½~ý$¬4 |Ÿ]»võõõ8q‚Á` H¥R©T AR©~ü …‰F£¹\.‹UTT„ÃáÉÉI©TZ,)J}}½N§;sæ ‘Hôx<@(GFFfffäry ¨¨¨À0Ìápx½ÞL&C§Ó9Îôô4†aÕÕÕ‰D"§ÓiE —ˉ„Åbq»Ý0 øð!”ÞÉdNMMMNN^¸pA,ÔCEÑ|>ŸN§ƒÁ ÏçK&“¹\.’H$ …&‡1›Í‡C¡P¬:áE"ÑÂÂÂÇ3™ È%î÷ûÁ™ŸL&A3‹Å`0L&S8}¢(Š Èôô´Ýnß·oØZ(Š‚P]4‘>‹ÕÐÐ`4C¡ÐŽ;"‘H"‘ðz½>ŸÏëõ¦R©x<&èõz­Vk±X´X,¹\nll¬ì£R©UUUn·Ûjµ¦Ói™Lý¡Ô3›Í.— °W›Íæp86mÚô[ä«ÖùÊ éOôÇ­û°~Ý’ËåB¡ƒÁ¨ªª2]‡S^^¾wïÞ`0˜L&ûûûgggçææöìÙc4q8\*•zþü¹P(d±XJ¥rÆ &“I¥RaÖÔÔ”Íf©¬¬äñxäñxz½^©T8p VWW ‚l6+—ËÙlv]]]0\\\, ýýý.—‹N§—„#4Íh4ÖÖÖŠÅbEÕj5‰DJ§Ób±X àp8‹µ¸¸ÔÈL&S¡PŸöì™B¡hkkK$@9œJ¥J{†á\.g·ÛU*ÕÙ³gkjj¶mÛAЛ7oˆD"ùòåÅ‹Y,AïÞ½Ëçó2™ Ä äry}}½P(©««Ójµáp˜Ëå²X¬ÏŸ? "‘(¶nÝZ^^n³Ù|>ŸT*½ÿ>ŸÏÏd2­­­Àþ"‚9r$`Æår»ºº€Ññöí[«ÕÊápD"ŸÏ÷ûý_¾|ijjâóùë6 ž®_ýe½ ß´¾;::zzzärùµk×®\¹òÌ´§_cýZŠN§Û²eKOOFûËS^ZZºqãF¡P8zôèèèh[[›X,þáXðï¸þiýW^c­Ö)á¿…~®±Ðh´óçÏ_½zµ³³³äuþžÑÿôñoÁ®*ƒƒƒããã‘Hä{¦FNgccãÒÒ’D"IO~8ü¯¿^ÿw{ Ö A¿ÅÚÜ©ó IEND®B`‚snd-16.1/pix/fmeq36.png0000644000076400007640000000270611147553267012762 0ustar bilbil‰PNG  IHDR:)’©ïsRGB®Îé3PLTEÿÿÿààà°°°ÀÀÀÐÐР  €€€```ppp@@@PPPððð000 * ô¼ pHYs  šœtIME×  9}Ç\KIDAThÞíZ‹r´* &„« úþO{ÂEDA]wÚ3ÓùÍLuË’|æJËØïÑÂ^úŽ`|1xLb°H—A¼P<ŽT?’Ç™¹Ç$GÀØü"ñ˜œŠ©Î1|±xH:Bƒ|#ö!qýbð% u’ÓZ-:1:¡y¨~±ZÛ]ß"Gýö{'ä÷X9­)'øzÛ¯RÝ®°úIÏþØ1ÿuï¸Çå«q@ªjmŽè~¬”ø 3~Þin{®¾:. –ç…Ñ¿>JDI’³ò;½úÇêæã¶æª@ÚÜíÿM·U`ÖÙMN•“>CL&ºñ×Òî¾ÿšòƵ±#–^oÞ¤$]iÛÎ B7~”îΓ‚«vˬ|*õF\{~êt›,¸66A—V–ËR7÷à kZÍm':¹Ö§&ÎU=vPà Z†ï/ÝÊ}Z¬ŸÇu¼36B—WLð+à(” ¯Pz”PšŒZiŸ4ý…FFwÚhg­Ìö¸ŸwpÆ€eÃ*˜sH7±*]qÔ*ÞA’Ufž2’àÊX@‚®¬È9ô¨tGÊaêå¦ N)ùìL+t³½„nîažÒ]ß{Rlf‰®‚Ì9l!é-“¹’rŒT«Ò™ã â tž+e)‘ß1’àÍØÛ`Ám‰'¸eW´Æìvܽ‘¹—ê:Ðõg15J›êTIuˆ(³»aR# ïT¼1ƒYéÄѪx d*l©ï£àll’‘Yͧ׋ÚXÈÆË ]_Œà•ìý±c±ëâúÅÅNâ6խЭ©7èd¸‚—±ñQ&+8“µÈúŠz6Òøœ0Ͼ¯ÆFñ™b~Ў”Ì:….|"«ýj¢.³¯Ýa[Äâmª+Ðe8SiIÐ%eò®Ié ÝQÅÈfÔi™.¤LŸÑKsn5VèŠùLIæ º 2„š]Ô^™¸€®[%ˆKvҜۧº5­e8yºåt6'»tòº¬tâhTìµ-êÐ"Ìè¡ÇvMÄOÙØäía½˜OЩð\ºä¤Ô6+jƒŽ0 ±./ ëV‰TÊ›ÆbH_€T’Ûâ`kW7«Úgýk ÊÍ•N›Š´“åç¡ÀœCúU±Ð4Øe„µg ‚‹±A®Ÿp[ñ˜²Â[nR,\@MN欕ìX¤š’æG’BÈ é/ ëV Û-©ëæ€È¶ÄÑl^(- &çðüÇ!zoÀ}¼QŒ%¥3Ǧb܉ ð :ǃ1”äúŒ«óÁÅXá$W³Ã²*ª? S-Ÿ~˜´9L5³DÇ¿äI[ ˜š++gÇ ¥úl·¢tä(*†„K<çÐÅ'=œ1JY Þ"¹¡“\W¬»ìÔ÷b’h憶½ã‘Í6#ÁÀ1ºV »¼lù´“µôZ¯»™:6FLˆ{Áîòk4‡3 j¶îOœa9ú’Çré¤ÂõæFàž#ì$·”Ë•{2¶Fš·µ¾ì§ëc‡ñùi®[Ú¶D‰ôù¾ê ‘½=Q¿str#XÙ›ÃóXâÒ°Œ+’Ê]£4õ.¿sZ-Ø»;~)ŸJÔ²ü’ì¯Óàüb‹Ø!ÿבó¿`]Ò‘ÿóèüïdLž@Ü‹ÅÓ*ÒRøÒ‚Øí„áO©ÏIø<«¾Ð=îK›á…îRR‰ÒI¿ÿ ûeÃ(`xQø2íý>÷‡–(ºfMIEND®B`‚snd-16.1/pix/zramp.png0000644000076400007640000002441611147553271013007 0ustar bilbil‰PNG  IHDR'êU;ÜgAMA± üažPLTEN6FFBvvnB–‚>šv†ÞŠ–Ö¦Bš~îîâR*ÒúÒ®®¦V*JjVN‚N²6úþú6žjRŠ¢ÊÊÆ ¾šš’Êâþ"®Búúòz~zŠŠ‚*¦VÎÎÎNŽ–º’î’êêæþþòÎÎÂ:švº"&ªNŠÚ–º&JŽ–&FN2¢b¶*.¦V&ªJ"JBF’в6Æ2¢fº&*ªNB–†*ªV&®F"JF’Öž†ÞŽ:žr6¢f¶.rrjÊÎÊ .¦Z~~~¶6þþþŽÚš²:.¦^F–†"®FN:>š~²>2¦b Â2¦^J’’"®>R2‚â‚:žn¾:žv†âŠ&FJŠÞ޾¶.*FN6žnŠÞ–*ªR&JF&®JJ’Ž6¢jNŽš¾J’–N>"²>>šz¶2 ’֢Ǝڞ‚→֦º*NŽžF–Š"N>RŽžF’ŽÂBš‚R6R.†â† ÂN6ŽÚ–’ÚžR.¾*FR–ÖªŠÞ’&JJÆ RŽ¢"NB¥úu bKGDˆH pHYs  ÒÝ~ütIMEÑ[. IDATxœíSW¶ÇGTP³"¶Y! 3º Éã ë ,Ú%!à*ÑPV%ŠAa·¶VÝ%Äd«Þ¦Êzù¯ßùqïíÛ?§»§‡ùu>3ÓÓ}»çÎç{¿çÜn T¡6ÃaœGEóÁ£‚÷–áó$>øCgñ?énEð·"øGÁüÎÍÃ2èäÂrˆžGÿÅŸRó£ß.}O|…áR~¾ûøŽ¸âš!~Oäî„C-&&&>MÉv_"‡‡‡¸`3‚ï6ä¿mÚ78pHÝ‘¡0kµ˜©ÍõÊ…1ºqGspýÄqzlqçò£ÈèSLd€ÿÉÙ/ýhîª%Yß*’`\ЉÛ+^˜§1aì i?×ì(í0ØÞNŠöD-2qÿÙgzíÐ~Al0÷0ü=†¼þ6ø ©Û.9à9äyo)¨ù¡cãT–µÜò퟉”Á´ÍÊty*HP&SSïÜå;~œÚ ÎeöÇʹ.ÀvH'¡Ý§Œ˜@þ…÷þùÏ¿D†9„w@ߚпråÝ®\ºÆ¦ ÁügÃ_kàÚ5Ý>aG~@‘Q3Àûˆîã°b]7Ýïâ³VÁ]j àYæ}lÙЂØðëÁ¬@ì=DùvÓÌZÌÆÌ 7Ì`€ûc=$‚ë±D} «Ø5xXYÑB¢`VWVWW)þq1½b÷¹º²2…78têwôŽ/¥MÓÀ~²|Ùï'Ë=DiàÏÌ/?ú#?¨ˆê~øAÅ?„û¥(陋´uå’ãÿc{Ç> ûQ)Í„Žz OC¿m Ö>øjŒ¸C8æc4p×sûÚhä¿{ø%á4ÈCû=í:CÚÐÐæ¦e ”æ˜4ih`"HçC”m mn(5T1ƒa>dG¾fÍ»y«Ôo¨¿GîñØå¶ÝÝ¿U,0è^Àc€£ صV!ÌWËþ(ƒp+ð ˆ~_Ó2—©ÁÁ©9ô_êu'Eû $Z>?Ý|N鯿üòË_¥—u@Ëïü©ÿµkº…eàªæïp¸¿‚‘Ï®Nˆüɼ‚g×”"Æþ€!Ž@l›#¶?ÝŽuÿÀHqï©áKضEp—5€M÷(“¹ÇÒðÒm››ÐJ¡ØßÔ¦@ýÆ«W¯° ó"¸¡@Ôc + (ÖTìi'P Ñìg¬Á>,5ÔsÊbà €Vv¯ï†% WzXÀÇ‚ÁnXþ» x™ƒÂÕF%?Seôä:G‚ÝÞ¦VÝý*˜ 4LÍ ÂCë$àyN-øë;?¡[8¨‰äØb?YøÉ2ꢓÐÄp4—Uq <à?F"ß]úïdªF¸âºj`%@ຬ‡ «,¸ûxóåE¼óõû†þجÈÊ~HܤS¡mK ¦H¸GC¿NŽxÛ³Þ¢±Ÿ3N€67L‘`2 2/ö68þqSûƸ@R¢À‡ vc ~IІÊ{ Ô½´‡ü1ªw}cù:d:åÝ2®Ð‚cœ%¡SŸû Æ ü§UNSæÝ’€.¦Ø p¡’%üUt ä+3˜ã˜÷+[m—˜#jäXì}ñÅÞÜÞàÎÜvæàOŠ£ ,³pîpƒŽ~Ýp§D»Kw°ÁQu¼ÏO`ûòç$×½v Ûu¯€\÷?î5,„!þ©ÿ‚ëNL\ ðŸ¸æšœ¶uØ_p!ä/LàqŸºîkx(%ð©‰ú×°oBy@@X÷bÓá—VZ„c¼‰ú»Ûwuõ‹þ€‘$ UÅÿÞï)]`@svDù§B:BQ àÊ0è)Rؤà7SA›ª(0ï…~°˜™ÒÙ‘]øôpò Vij™g^ˆ“‚&°»Ëñ®}ÀËø½ãoåÝé”ÁÂÊÂtyweÁÊê§A ‚U“ú¬`ô{¡^öG}HZ¦ãåD¼‚NO°õ…%€²Ø21¿ƒÇíXÛÈãÇñiîÕêÎ.ª‹‹[pƒ§—~·Uöat £MhÁbTûÉ…€Ÿ@Yùs;Aw¨âÖ>½ÀÑaÿú«Áp!Ö]­ Ž|’âno_øôµën¿†5÷õ6¬%[gz¼·¦…¶ïš‚`ÛkWm÷H8þó‹šïmbé«9¯@ÞÑŽiІr,…‡(ö7µ°)l¨¸7ƒ??­Ye€¿èõ%C¦ ÐÞ@á?cB´Ð_fe¨´Aå; üÊ`]­-”WŒLãÚtyEÙNþÕ*H€JLVLØß0ÆC+Y„— Y*ؼ ˆ}kà7«<êûì`nn¢v€Àº§³ºhÉ``=À£ € ·ª[;pG5,V ØÚ:ØêÛâx:øÚï'ÎhÀOTÃ2 —éˆ(?^vz>gOx ^ b€§m¥ØÚ£À w_¿vac{[)€ã_ËÁUËm÷ž¾G8dKPÙÈà'‰>£’¸ƒf€xRˆK`L}È” ¼_aØàü¬¯…Æ}³f¢_ @çEA3Ì™µëV@Å…ù3”ÄZœ¬LˆK/Ö© ¡ßr\Á˜Ÿö¥BP —9ZU2(«Jx…âzZåUžþYÁ„¿¬ä¡ÁUøœõë¢`θëzmЖÀ o cžŸ!ÿQ+vàû×?^$ `C4+àx§h‡gµ†+[(€¸W«}}}ÐÔwppP¥,û`¹~À¬CÃ?}~¢uÎÁ Z'°Ç¡9­Q'ÖO Žÿ M ¹ ‡×.G;hÁ?¯¹Û‡4m60ñ€­ $„C—&… øuÝ»w]ˆ}hUxÒ°¼@%B\ sN´¡×6îyBÊ xZT¯ÑìM¡)¨LHOm°¬ «|ÖA?d›_j…€xæÕª¸ŒLƒvoíêð§;Ë€íâs\Y™}L¯¬èr˜c¾\6åÀJÙ8Á*šÃe8TÐx¯$ÁIÍ“®rþã•«º ö$ísZSôzô·„À±ÿÅÞž×ÂÃ>> b)0ÔÀãE[ °¬òö>F<ÇMŠ}å õEÔJ@ — †>K¡Ê+ëp‡Eoo/IÖÖ‘ÞõÞ^Xí=€°Ú{Óç':ï?á/ï"‹QGDúÉg¹ç/Z_º0èÃ,• Î|Aàcð»ì .¬Ãã£þ.”Â0ü»óXÜû̽w¶îÑÓ<©™".`°ç b¬0ê_½ÂÜ'†(é£^™à çWúÙÚšýy:ÈTªàùOž šÀüªEÏYF`ʯÀµ[:Â1ëc”Å‚1ùÕ´Õ(VèAyºÎ‰‚ VyNTåE\ÐdÐÔŠ üÕj´/ß_½Q¾²úà¾) B9‘] ëutA’€Ò†<ëaÐþ÷t]ŒwÈ‚`ôßSõÀ¦F±ëì‡s"2Œû‹TvtÔòlÕ>j¯Òƒ·0-ê£Ãɪժ²êú:š„ú…>DþºZY§ûÁqïúq/‚öòšZ®¯Ïó7ÿfûɨç'd'˜z9±~â@}ò<=æÒ}€LUáèò€c_ÿ€k¦G!´P¹pß¼çnàÓ†»±áº8úóÜè{I†¨&€§µ5}šÌ;5à"ò²Ÿ!í33Á<ÈÔ ñýŸH®nñ¨¯TÀõ™ÀŠ€žQÓ¸ƒÆû2ºð P—9ê-P2P'0ó§¢U5òÃÓýû÷)åGx Bß~¢sSÁ9Q­«˜Ô[S>/4Ó¤{\ ò4ÐàM˜B°?¶2 o<ÆA v(p{1JÔrÀÑ¿ˆ’8 t‰R!ƒ1^p¯¢ À‚ ü–ä ÇÇÇë½èëÇ*ÈÕSUǼRÊzï|¯fÐ+ð蟅UõÜLoÅø‰3Š¥ %ÎO. //÷üŠ—40 ôàÂӦ˳Dð„€Fë|ä Jd,›] ~"…ñÊÅ!Ü€U}FÀ+ x%0cRŸK¾THm>³Ò¡gkäú|A”vËl¦Ø¥AÿºN…8âÉPÎ}V0=¢©ÐÈp$ÀÅՠвW  °P ¤NSÔc=6À‰*Šõ‚õôÏT w¯öâÞ®ö¼MH‚æ0ð±àRxÏ›µuðç†t)@¡Ï¦>8EÄ•/¯,î úªäèø µ@%AÚ à¹6@'À˜¯bü÷ö­k/8è%ðÐ_=¦ø_ÿð˜´Á $0¬Â6ç-°¾âŸí%ÀMËà«Yµòvvï´ nGóóG³GÀì÷þé-ÏO wÀJÐTî$Ô'Îå¿¡'`Q¼©KäM´uÅÄ+Z¼¢ÐquÓ%U ˜r€ûcU WuÒCÑ~ðᇞzõ±Vu¡ŠîÞYŽûYk¡Dðöí[j:Â庴PÌÓ“ZÎ"PwZ<’˜œ<:Úߨ˜ÄöýÉýIàáä>옜|ÏY•®ãÍôV¸ª'¡>:þkfBÈ?5:c¹€º~bmÆg tf#þž{¦ ã[·|ñ®ûwu2´K¥ž(¦•ýÐ̨΅`°ß] `ç s 2k@Í‘®BòCgÊh Çtˆ‚›æ?WÔ%d ÷i†” ›hPå²^ÌÙùš¥¥á§<ðò¢A3M4¨=dA§‡irhngg'òäNŠR9L“¢Ê© P3A\Pi@çÎ â·0ñÙbØ:èõ>ÚZ×6 +bž¥é TU·œA.T#X?>Ö9ï‡ëv&ÄN0ß«óÿ^¶‚y£ö½±_ÿ_}5«×U&d¹Á[t%…‡o‚n dð4 ¨xì¡â車‡ûûŸLö_L¾xñbÿ“}T ÙºÀÃI½Dà“óõû¤„O>i¼ u PšÉ7°¸8yñâ‹7oàË7ožº£Nà—°FGk6(?±;?yvÝ_ ïZOer}¥<×qH(ÆÄÿººNh—®…ØÅ+$¨(ã„j€Ë¼áµBìh0øÓ”Ð_2¤æE1#šº§…¨¸‘ÕÔvi9#D€m$* ö¼ØÇij =*tØ“ìÌ©ód|EÄc¿@¸ëS[;|z€UR¥Å*¢) F»WP] 0j®'CTY€çØÖõi^¯@ ¢àÃ^¶‡Þ¡DÈÈ`^Ä|¯_:+â°§LˆÊaþ©<Ð?«oA ÏAŸûœ€–Ï©mÿH©ááóÉ}T†‰ý}ZLªäè“}Ë @ÐöÖ>y¡5àãÍäEÄþ‹‹oHðô¯ÿï ­NÂÖÅ‹p¿Híÿ¢UäFžßÓ2~ÒÓsYÝ/Óýw}ôљΜùHq†6?âí3gpǻμ`ëÝ<7Þáq°ûð wp,Ïà1ïÞñ!Ä7ßü/,Ô:lQu [ÿ÷Ý©Sðµ€%,pí/ß}sêtA«ôtŠßxk°ú¬|C÷wï`ý§Ÿp×Ná!Øîçk| -àX½À†¯¿¶¡å¿aùòkæÔ×/aƒø7o `ñžè˜—¸ Ë—7ñ0XÜTG±§èØ|°ý¬Ýü'nÿF}BãËšÅM³xé[£ÕßLûozçm¸Ý¤¯Ã  Åm½ÎOnÞ~ò„šy [Ohyóöû'·ß«Ö÷·oÿý÷·ß¿W;ñèOøØ°‚;ž¼ÿþm߀Í7nóÅMðD«7žÜxò—Oq /‚½7OŸ>½ñëSµ~ã×~žþ àÚ‹»ùˆ_Ÿâó¯7x DïÄ­ÑËY5~R!å'¤H¶è t$•̯(?].U¨‡ŠSQwAèH2ÇöÇÚO\ÒIe\„ ¬ý'JŽÓì$-ÈÇâ'‚PñA¨É°ø‰ ÔFüDj"~")?„šˆŸB ýD]ØÂ«¦)¹Cë5´i¿8ö5é ¼Qì¾´½ÝŠt¦)6n’ý$òU©b>f3æµ¹&Q¯u©‰ ºØJö“øþk¼}̦èDh2é$­Ÿ3©ø´Ç÷šmêK±©RI¿°T t+!³£4®µ’ÄP/Ö.IÊ„q;²¬˜Ð¡(©]Ÿøº÷GnTüšˆä-ßq±õ„·/Ð} XïÞ8&s ‰)¤Ã] DS–ú$µN’ŽË¥“RÂûø¿ÌxøW!z(Ž îÔõI0þã’¨\:/±Å^¤N$ïV²áEœNêô“Ø·yËô:±z)T'ÉCè"sŒt~RÉà'Éo¯W"ê“ÈW&è¤dí ½]{ØÝ'ç]¢!Q'Q7Ó|W`¾(v¾Ë¸˜=ßUó4eÉzµe<&®ÃsY¦ûP/’w A"b"*¤í}—D½P0áê€ë»D'BÁD„T°>]Om?ñé¤dÈð-üA0d  `}Ò~~" 'ÑOA`Ú¿>„†#~")úDj"~")Õ' ‚Æï'Íþ4‚Кøê“~AŒý>?iö'„ÅWŸ4ûÃB‹"~"µ‘úDj#~"µ‰¨OÆá12\ë…Í>õ#'‚ÑIÐOH'5Öì/'BÈOt}rÖM'.ݳ’ù%.Ý!/Ù¢'ÖOŒLÎ÷÷Ÿ¶Y2øtâÆ{â?k<ñ_^‹>D¦ïŠÐ¹Ô @¤èÖ¸údììÙ«W¯>ºúóù€N[&ý¾ÎjÅêxÔ'Èð¢t¯HêLÔÒÝäœ$?yta .H!,ÏÃé¤îà=iD,]H¾,Ä"®>a?aŒ>ÝÓÓSqxI:ÁVHä¶3ãþ{¨aÜ ¬EØ•päxtSÄñö#âåá:ÊûpÞsð‹OØó- |ÝQG%uÒ’üäªå' ‡tâT––>î±°ŸèŽJÁž±7Aè’ë(P´Ÿ8Î _!T*K¢¡{¨á'ÃÚOz4ì'¬–H”<‰DœS±Ö¥’Ú‡¸úÄλÆ<,EêÄžÌ*y“\¡7íIv?©Dç]©mJr}’ÒOÒ":Ú“¼õI~"…¼Ð>$×'Ã1~âà'¢¡14 ² ›ïÊü©QœàÑ8O}Òßj~"Ö$h—D‡ø‰E`0NÄORÕ'-VÇ7dÚŠƒÖñ“ÖË»D(‚Ž©“¯OÚÆO¤F¬KA ïºSêW„Òõ˜hù.wµžŸÈìpwc…“øIb¿b(]L£eã¤ü$üûñÅŸ?¡t+þ`:y?o'?¡´3õüì¯mg? } 9_—"µ¦Pß°Æë¤³ü¤ˆPNœR'ÀÄO2ö[ˆND)'K©îi}ñ“Œý“w‰RNó½nmˆŸDv%B9¬ hmˆŸDw%–rÎÔÓQÒf!„ü$ùï­t‰Ÿ¸b) '­­“´~R©8š®ðW,¥±„¾»­­“´× k‘œî?qE)#â;ÛÚ:I{}ý¹züƒõÝã'á-¡"ô­­“´ó]Nŧ“îðW,¥y¾91ßÒÖÖIÚú$ “nñ“¨A‘óŒlÌ‹Z['â'q]Å6dé«s5VÊ}­I[êDü$®«Ø†,}uªRêùEô¶Ô‰øI\W± Ùúê@©x_Q÷è$ýùñ“¼}u”R|ºï¤÷ßÿ?ÉÔW§(%hŽÝ£“Ôõ‰ÿÿ3ŠŸdì«Ò¯ˆ/¡{t’ízá¥.º¾+¶!o_m­”hwNNìzá“ø;­­“öUJ¬vNä÷O⺊m¨£¯vL¿’>r÷èD~ÿ$®«Ø†:úâÆvRJò§íˆŸÄuÛPG_º¹‰JÉæh5ŽíˆŸÄuÛPG_ùû,滕ùbщFü$¦«Ø†:úÊßgp$χQ¯ä@ü$®«Ø†:úÊß'½"·T|"äAü$¦«Ø†:úÊß§~E©Ôs]t¢?‰ë*¶¡Ž¾ò÷øÎ¥}}T¶&:ÉC'øIÉ-L'¥Pù?fç‚/H%•¸ƒ2¼{-äù†Ç餎^P'Åÿ+œ¦ùI‘ÿQÑʽ‹ë*¾%_¹ûŒxA²T :;XëÐ<ßœ¸×hÜ 0”d? ýÆÂüDtRW1b¨55&:ÉNÓþŸ–褮B’H‘‘‰NrЬúDtRLW¶2Ržcd§y~R P,ÔÛeêÄURI=1’E'ÅuUó5-­“æÕ' ÑI݆Y0×WŽ>Sž‰Ï0}Xà‘9¾7 )dæ¾â^)~R³ÛâºJhÊÝWÆ>ô[Rw+:14­>ÔzuC¯+NÕ½èDÓ¼ó'¢“„½'sé}Í·ÄOâºJhÊÝWí]'¥‘To':Ñ4í÷ãE'Q­Mù®ø·òùÉÒ’øIž¾bw5I"5Þ_t¢Éç'K¢“|}Eîj¶F4áÏ!:1äñ“s„è${_¡]­¢ÿãˆN4¹üDt’·/{W«IDc}.щAü$®«„¦Ü}y»ZS#õùD'ñ“Ø®šRtÓâBHAš/¡kt"~ÛUBSrí/‘ÔäøbÛS'¹®ïĽ¸‹$â‘í«nOäº^XtqPWJÄþëoOˆŸÄv•ÐØßÝñ¨ïÚÊ–Ö‰Ô'±]%4y»D"j~KÚS'â'±]%4¹"‘D’¾7í©©Ob»Šm‰¤!î»Ôž:?‰í*ªI$’ˆoW{êDü$¶«@“H$/¡_¨ˆ;,ÿÖUâ'±]yM"‘ºñ¾ƒí©™ïòõýK"‘bHpZZ'r}—êA,ãdHÒIÞ€øIön³¿VÒ2äüYˆŸdï6ÓËD!­HæŸKóý¤¸ù®à¸ÝTˆ‰´5£°ú$¯ND!B ‘‹M¨O$ÅZ”„ <‰ú¤ä§_¡ ÔO|˜t>Þš.•‚-öçhà)£˜ó'ÖYEï—Rüâ™ ´M»¾KÚ‰Bê“´ˆN„öDüDRPP}’щОˆŸB ¤>„šˆŸB»YÂÚIDAT RÖ'èDèBÒú‰ÃàŠèDè>ÒÖ'Ž322BÏuéDÚ_䦮OlŒ)D'Bç’ÅO¬ó'• ÊÄè—ÙuÒ’{åceÙÛ‰«6éç»ÀP´NΡLrå]-¹W>V–½ø±Rþü‰ÃKÑÉ í••eoËø êd©Þó'-¹W>V–½ø±Rº>éé9]ÿyÆz?mc•…®üX©ÏŸTÇÑçóÏw5拨ùXYèΕ®>q,ŒLD'E>VZÁOâÉön]ù-Î|¬,4ÕO Ö‰ ´''ë'‚Ц$ûI-™ˆN„®@üDRì'¢ApÅO!É~RK&©tºF¹ÿß[FÅÕ øI)ôñÃ-‚P“ý¤”¬e\‹qf‹Róýdè1<,:i!D'¥FU²Ÿ=Œó TÂ¥’è¤ÉÈwÐO#Óù´~2<<¦ÖFH'¥~ÑI“'ñS2‹FÒO¼dKëDò®æÂë€fÕÂ5Ú ÿ„. òÏ?Ez?ñé?O'ú§ŽÑIƒÐÿ.™Z5Z-](¤Ùó]„ü¤dþÑuè“ZIÿ“NȈO'¶«X;ºûßH7è-2Ìw%é¤dX(©þ'¿ŸX‹è?@ÕÁœ€NR×'5ubžºççÓ\tÒÔÏÕ‘ã'á´Jh8¢““¤ú¤õ$4–¤¼‹ö4ñ³uéýdÄКïòûˆü€NšàŠÒ B¡¤­OF|:1p'þñK~B'ƒ™ ,ºôüIC)æzao$Ó[‚ÐQ¤¬O’uâšÙHWd"t ýþIøt» tÉ~RK&öu+¡5AèjøÉ¸èD\ùû]‚ù{+‚‚d?©©Aè"rû‰ t¹ëAè"rÏw–¡S±uR§Ÿ4ûK„F1f¢¼?9§ÿ½é¹1Ahw0­Ø[œŸ¨>Ç–D'BÛÃQ¡“"ü„Þß¡"íÌ’íÓùIêyá1ÕqÅ¡GÚ5Ú“RRøIúó'ô_å+NÅ?Ú5ÚWÐX–¢ý¤’ÛOpj@t"t*Š éL~2ó{¿–Ÿ@&ÇÓh¢¡­ÑY3UÝ~=ßeÉ$ÒcÆÔ|—ÒIS¦¹¡8Îa§ï²ü¤ò{¦?zÌœ?Qï m DqŽó'##J&¿–ÉÕñ‚ЉÔô# O'ôïðÏwé‡ò“f-‚Ð(¢ü¤ë'O'ô÷ õƒüä´ t*¹ý$¤“þf)‚Ð(œ,ó]~ @J–LÀO¸üqœæ–_B×SÔ)yÊ=Ž“ÕOFq¾KéÄW Ÿ,õô@—ÎéAhEéä4õƒ=:•lõ‰ÏOüYú ©Ä9-:š‹ãŒÔıãT*¨”l~2ŒôGëüÄ©àd_„¦Q”N*ÐO%¤“äë…GúµH†£ÏǃN â¡þ¡™ç'Î)üÄÒÄÝa1ÖvȳÍþ6 ]Nq:ápŽö“œ× ³>D'BÓáø®›žŠ æJ&?©w¹´$õ‰Ðd*…Èäô’sº‡b9K}’ÂOp¶«¢‚Ð ¿Šºë'E}:AÈMctÅZFùIÎú$µ ¡m‘¿/,µ‘¿W/g ¾æ?„îÅÈ伯9¢>„nelììÙŸ¯^½úóÕó!ˆŸ‚æìÙ«ÈÏaøê“Nü Bû:y„B9ÞkëûÉ0ÝÆñºÇqxRkú(’oæ*bAèú‡•Ÿ€N¼Ö±Ôõ‰ÿ—êû‹pÆOà=äÑN~ußèâEìPÅØð0ÖñžN¨i¸…æ»Æä!”F¨Oø/©OÁ¾Ä+PÇË|— xÈ|— ¤ÀÒÉ#ªãûå|¼ °.ö.‡??>™Èõ]‚ÁØØYôµ¡[}~"B4Ö|ײ†ÖUƒÕl¶F}`C½QyÈ#åŸF—G a9‚Q³0ñI!ªýÄ~y1Ÿ"ýÇ•‡¼§º‰ïg9¸†OÚOÌ.úH´äuÿž€G›ÿ­“GW=–G—# •Ñp^¤XŽ\U~2zÙpç-î˜uÿÜe òÇÉ=îà­>._V¡æNä*o5·B„6áÿ§Ó$x;fIEND®B`‚snd-16.1/pix/noid3.png0000644000076400007640000011023711147553270012666 0ustar bilbil‰PNG  IHDRèê1ƒorsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØnL=F IDATxÚìÝy@Méÿðwû¾hS)ÚHJH"kCa,ÄÁX*!²5ÄLö-B¨È¾ŽA2L¶ìSHJ– m”íë½·ßóÕoÌнս÷Üåóúk&çžÏs>Ï9çžÏ=çDjj*ÆŽ+‰»zõ*ý9{{{tî1,ÎÿMSPQ ’IçÎÛ7oõMMMxzzRòòøñc̘1¡¡¡_,Π¸¸jjj——‡¼¼<äääPVVƵ@¿zõ*Øl6 D‰cµ@i•è´‡ÎõD’x{{ÃÈÈè«Å9$''×ß]wpp@hh(×õcÿþý˜6mÔÔÔ(Ñ„é,ÐõôôŽK—.¡U«V°²²â[ ›7oâìÙ³bY gff"''UUUˆˆˆ¸ººâÛo¿môºž>}Š€ž“œO¼‚´t m`s]ºh–’’¼|ùðÛo¿!//0|øðF÷kIII}.''ooo@ëÖ­é­´nÝáááÇÆ¡ À¿ƒèÔ©S¨®®þbžœœŒÈÈH,\¸ð«? |2kÖ,XYYaîܹ .—””„qãÆáñãÇ\·#//[·nŪU« ¤¤ÔಫW¯Æ„ `iiÙàr¹¹¹puuÅ•+W`llÌ5?+W®Ä/¿üÂu¹ììl”••q}­ ®®>„ ÔÕÕ¹®÷Í›7077çº\NÎ$¦}€±…×e³Râ¡chU\—-xÿºFÜãW”T5þþaÛLçëçúgÏžA__|Ûþòòr”——ó´NBkÑ¢EøðáöìÙƒéÓ§óm½ùùù˜?>Ú·o===€­­-TUU)é–’’‚¢¢¿Ï[fffÐ××§¤Ø»wïê_Àó÷ iž´´4ŠÜuûgº††ìì쪪*©ï´;wîàèÑ£066†¾¾>”””Þ¬uÚÙÙ¡sÿQ^ÜÚVm J‹> ¤à=ÆŒ›½=éh°K—.áÆõÅÊüùó›}áÚ³çßýÆb±¸páÚ´i///JºéééAOOUUU欑¡¡¡ ‚ŸŸTTT\6==Ü ¹Š $%%ñ´ÀúõëáååŵðÎÎÎÆ/¿ü‚ƒ6¸\mm-’’’P[[Ë5þáÇ¡¬¬Œ´´4®ñ÷íÛ‡û÷ïãÏ?ÿlp9‡'''Ü»wÎÎÎ .{áÂ$%%ÁÍÍ  .û$æ,…ï‚ÿAîO=í\à†± BйÏ÷ _À>‰Á僘½-šë:Sb{å0¼~=ÃuÙñãÇÃÛÛ¾¾¾ oÓ“'˜6mbcc¹®óÙ³gX¸p!®]»yyù†·çN´nÝÆ ãúãÀƱk×.®?P}üøwïÞÅСCyÚ¯`âĉ\—½xñ"\\\ТE ®ûÕñãÇ1~üx®ë¼pá2220kÖ,:¹òÈÖÖêêê¸}û¶@ÖÿôéShiiáÆ055ÅæÍ›)éôóÏ?C__ZZZ€óçÏ£mÛ¶˜4i%G@Š‹‹1räH :úúú¸sç***0cÆŒ&Ý $¼yþü9FÙ³g#++ 7oÞÄäÉ“E⺽~¸ððp´iÓ¦þ"ñÓ#ìàææ†o¾ùþþþPQQÁ°aðgÏhhh ´´£F’˜ÎJJJBBB’““aii‰   úGbùÍyÈÔÿ]<°Áa³pãâa\¸x 666èܹ3lmméèᓸ¸8ܾ}Ïž=ÃàÁƒ±víZ¾Þi­? äåëï °X,ÄÅÅÁÓÓfffpvv†««+uŸ$$$àÆõ¿ì·hÑâ³BÁÒÒëÖ­ƒ‡‡ìí푘˜ˆC‡Íf£]»v°°°hVü7nð´Ü¹sçõ‹lpp0fÏž½{÷ò%þ_ý6›ÍµˆúÄßßkÖ¬Á¾}û\îæÍ›8tèz÷îÝ`žžžŽgÏžAGG‡§øVVVHMMåZ ÇÆÆbÆ hÛ¶mƒ:‡ÃAl\,ß÷¿w¯“ Ó²5bÎîBŸï.¦ß<{€Woò5þëׯѱcG,_¾ ÿ˜’‚÷ï߃Ãáp]oTTºvíʵ@ÏÉÉA||<|ø€… R¢ø,##ÁÁÁ˜7oÆŒx{{#33Æ Ãúõ빞ãHã”——còäɰ³³C||<QWW‡šš >ÙÙÙ`´²Àßï‘3†††044„‡‡LLLêZ·n~üñÇúÿ8p ºví CCCx{{ó|á'Ê233±víZüùçŸ044ĬY³0uêT()) ¤8ÿ¬då ¯ O//øúúÂÐЗ/_Æúõë‘™™IGRq8œ:u žžžxøð!ˆððpŒ5J Åù—Šuggg„‡‡câĉÈË˃§§'víÚ…wïÞQ5S§N0`À€ú󖯯ïgw:„>}úddd0a´iÓmÛ¶Å?ü¡í‡¿ýöÔÔÔ••Õà²/^Dzz:*++ùÿþýPTTäúdTDDF…êêjžÖÍb±xZî·ß~«„¬!5jT}‘Æø, öài}¥EèÐÝ o“ð´ü½¨ý¨ã°¹.w÷B(Oë+--E×®]‘‘‘ÁSìß¿l6÷ø»wïFEE÷í¯¨€¦¦&dddxÊmqq1×r>kÅÅÅ\—«®®†’’”””xÚþ¾}ûâäÉ“\—Û·o ¹þ@Áb± ##MMMžòåììŒÓ§Os].,, ÑÑш‹‹“¨sð´iÓêÏ¿:tÀÈ‘#?ûAbçÎõÿ¯§§‡‰'ÂÐÐ3gÎäú$Ç—ÈÉÉÁÊÊ §OŸÆîÝ»éIO>*++ÃܹsѶmÛÿ¼¶%//'N &&»víâéœCxSXXˆ‰'bÈ!;vlýu‰œœÌÌÌpöìY¬^½‘‘‘”,>zñâÔÔÔ°dÉ’ú™ddd ¤¤„C‡!>>Û¶mãùG 5ħÿ°´´üê]/ÐÞ­[7‰è¤œœ„„„@VVãÇçë{÷Madd### 0)))Ø¿?8|}}éýÁFHMMÅ‘#GУGf¿–Àfff033«¿844®®®pqq¡Îj†Þ±ù·/åöSÁ.lµµµ¸yó&<<<\.;;ŠŠŠ<Ýél¬îݻ㯿þj0oÞ¼Add$ךÚWIII°³ûú{àK—.ÅÌ™3±téR¾Ç7·uÆ›¤û0·ûúùè£àò7~ßÍÌ]¢ÀÏÏ¡¡¡|ÝJJJ>{·ñk¢¢¢0eÊ8~ü8 ±nݺ¯^›>|#FŒ€¬¬,ÀϧúcĈ˜={6úöíûÅe¬¬¬°lÙ2L™2ùùù”4>xúô)¼½½ôÅñ{ päÈŒ1uuu˜?>#픕ÖJLLÄîÝ»±cÇxyyaåÊ•ŒçÿÖ¶m[¬X±^^^ضmBBB””DGW>|ˆ-[¶àôéÓðòò‚›››ÈµÑÁÁË–-Ë/°råJžïÑ»8åõqÕòòr\»vërOž<Á‘#G¸.—››‹‚‚‚Fµ——Gß½{‡­[·r]®¨¨è³× xÁõüUWW‡£Grý ²²²Ñ³-ÄÇü†7ϸßO¸}9é su6jªÊ¡¬ªÉsüN½Gàò¡5\—;yò$×±€¿Ðú4p/Ö®]‹eË–q]nöìÙHKKãº\vv6ZµjÅs| žŠô… "99™ër¯_¿nök*_²iÓ&ž^yþüyƒ£–Á ÃóçÏy:_î×ÃÁÁÁøé§Ÿ\®E‹˜|øÀu¹ÔÔT8Àý•€;v@YY™çøªªª<õmaa!¶láÞ‡nÔ¬0½{÷æéG²ââblܸ‘ërÛ·ooô]D^÷UÂÛþäëë‹ÔÏÂBÃá`Æ øæ›oxúÁiÊ”)puuåéX" ×"§NÂ… ¸2«¢¢DDDðôã)ùºýû÷£]»vøæ›o¸.ûi e^¾·¨@o¦ÒÒRâîÝ»˜7oO»ˆ’nݺaÞ¼yˆ‰‰Áš5kxºˆ“ÇÇêÕ«±oß>Ìœ9S¬×kÕª~úé'„‡‡ãÌ™3ؽ{·PG"'MóêÕ+|üøÀ߃°1AEEöööŒÅÿ믿ø>­Rc1ÿCf LÚvFêÓÛ`³„_xeee5j,‹¸¸8¾>6ŸŸŸß¨‹Å¤¤$¾ÞýIOOÇÚµky^þÖ­[8vìßâ×ÔÔÀÏϯQŸaòX‘Dýû÷‡ªª*.^¼HÉh¢Û·oãĉzUà‡~À¦M›(yͰwï^XXX ]»v<-¯££ƒµk×Ò9¤9ßÙ> ""“&MâyàÞ‘#GâãÇŒ<é*5úéÓ§±bÅ øøøˆýô)~~~ðööƲeËðÛo¿IíÁööí[8púúú˜;w®ØV8}úttïÞ[·nåé}I">˜¹9++ &&&Œ=%”™™‰–-[ e`ƯÅïÜwŒÌùÿÃÓÀñˆ¿q¬š¯VU\ð–ö.hÛ™ÿã¬\¹ÈÈÈøê2yyy••…®®.ß㛘˜ ¨¨¨Á»¨¨ÕÕÕŒÍ-[^^Ž’’øûû3?##X¹r%ù¬E‹˜:u*öïß_ÿƒ)iœ_~ù¥Ñûf‡àêêJÓÝ5QUUÂÃÃáííݨÏMœ8¥¥¥øý÷ß)‰Mpçμyó†§)üê2—/_Æëׯ1sæL¾ÇwwwGnn.?~üÕe>|ˆÈÈH®Ó»5…‹‹ Z·nÍõb<''G ñ àããƒÌÌL\ºt‰’ÑHÑÑÑ(..nÒ¹aåÊ•8zô(OƒO’Ï;v ={ölô-[¶„‡‡ ׌kÿFß,X½z5Ξ=‹„„*Ðù%%%sæÌ†††Hƃ†ªª*æÎ‹ÔÔT‰?ÀJKKqæÌܼy .ä:ʯ8²±±Á¼yóPPPÀÓ€YD´]½zµQË÷ïßgΜALL #í]¼x1Þ¼yƒS§N1ßÜÜ\ w{‰äéÑ£ ñêÕ+FâwìØ………4’8ÃvïÞ ___JD#ÅÆÆ¢oß¾MìðS‘sùòeJd#äææâøñãM~úÀÕÕ~~~4Õ]#íÚµ ***ðôôlôgåää°cÇ¡Ÿc$²@¯®®ÆÛ·oñÛo¿!00Pb‹óé¿üò NŸ>ôôtžç07 …šš|||øz—QÔÈÊÊbìØ±022ÂÁƒQRRBgX)R[[ËØ°’’8cZ¹ººBYY™±×wÚØ8ÁĪîF†2_AAªªª< Ö'ZZZŒîûLÇ×ÐÐhÔÓ&G"§P'Ý»wG=è{² qöìYÌž=»IŸÿ4áîÝ»)™pûöm$%%5j€Í²±±Aß¾}DÉäQ]]òóó1oÞ¼&¿j7bĘ˜˜u}‰,Ðwî܉ÇcÉ’%ÐÐЊPSSK—.EDD„Dž096oތѣGÃÝݱ÷Y…­ÿþøù矱uëVšÖ„HòòòFO£Æ/΃§@MK9éÏ…·¦¦ÑÑÑXºt)¦L™‚yóæ }Û£¢¢°oß>ôéÓQQQŒÄߺu+† ÂHßGEEañâÅŒ½ŽAšFWWzzzX¼x1%ƒGgÏž…»»{³^½pttD]]=zD åѼyóš5*¸¶¶6¦M›FS.7Bqq1.]º„þýû7y¦¦¦ÈÏÏGHHèMQYY‰mÛ¶aøðáX±b…Tîˆ2d¶oßÞà{‰â$22Ó¦MÃôéÓ¹¾ï'‰”””0oÞ<aß¾}|‰™‡¢¢"ÌÍÍ\æÀPVVƸqãiãÅ‹‘––†9sæ0?66.\@`` #ñ Þ¿Å {ѹÏ÷ŒÄ¯®®ÆÅ‹¹Î‰+è‹vMMM|ûí·8{ö,#ñàûï¿ÇÒ¥K‹¿~ýzÆ›'M³~ýz¼ÿ¥¥¥” .òòòpèÐ!˜™™5k=={ö„••Ž9B×%|8ddd¨ÓxЭ[7tíÚaaa`±X”>˜={výyëKïéUVV"44~~~ðññAll,ž©©©"7 GTTjkkéó&é¶¶¶ôC²²²——ÇHìùóçãÝ»w8qâ#ñíìì ªªJӽ…¡¡!ôõõ‘˜˜HÉ ===tíÚ•ñÅÅÅHKKC—.]ø¾n<~ü˜’,Äk333,X°W®\¡$ÿËÇ‹àà`¾¯ÛÊÊJ(#¹‹Už””„Ë—/S×L&LÀ½{÷Dfà¸ÈÈH*ΛÉÙÙ:uBhh(Øl6%„…““ÔÕÕqýúuFâ÷êÕ ½zõºu뉯¨¬ MCä¿{M;ù*SSS(((P"„ÀÐн{÷ÆŠ+(ÿòúõk,]ºjjj|_·»»;éè/X¾|9¶þ“'OR’ÿ%//O`×%¶¶¶011Á–-[¨@ÿdÅŠ?~<=ZÙLrrrpwwGbb"ãS°ÑhíüÓ­[7ØÙÙ58×6!’D]]êêêÈÉÉa$¾I[8ô÷ÀåCk‰¯¡¡!çÎI“&1ûСCøé§Ÿ?sæL¾ GxóîÝ;J¿ÂÐв²ü¿ô×ÒÒByy9BCC)Ñ_زîáÇ#++ =¢DÿËÈ‘#¡¡¡!u³Ùl_wˆEÎáp°aÃlÚ´‰„ã“N:á»ï¾Ã;wPWWÇhq>|øpê>qvvFçÎià8"RE´½½=#±srr] ½YY^Œ÷o“ñã¢}Y¿ŠŠ œœœ0mÚ´/þ{qq1.\ˆ}ûö lCCCqÿþý¯þ»··7úôéÃØþƒ¾}û2ŸצM›pãÆ \ºt‰’ñ?/_¾D]]Ú·o/°={ö¤DÿˬY³0zôhôë×O ëïÖ­ ðú5=ÅõOÓ¦Mƒ““TTT²þ}ûöaëÖ­xñâ…ôè•••ÆÈ‘#ižs>³²²ÂÈ‘#,ôQ ËÊÊ#FЀp8aÓ<颡°°...pvvf$þÉ“'¡®®Ž!C†0ÿêÕ«ÈÈÈ`lÊÄäädÜ»w² &ZœÿÏî_xü¯½ÖRWW6¢yÁI IDAT›-ÐÁTåääÖè¶ñË¢E‹°qãFÆŽq===€ÃáÐ ODÈÉÉAWW—úä_çb‡ƒ ,†——:ÄØM¢ˆÍfCFFF ×¹‹-B~~>%ûJKKQSSmmmÅPTT„¶¶¶@opŠ|¾gÏôïߟïÓ¿Y[[£o߾ػw¯PãnÛ¶ óçϧ`‘ž——‡7oÞP2%%%èêê2?33òòò{¼Ž›ÜÜ\a–Tûöízƒ› 6`Íš5B4ˆ4®_Î;G‰²·oß26Sƒ¨ÉÎÎF\\œÀ_Cjß¾=/^L ÿŸÓ§O£  Ó§OX mmm,]ºT ç‘.зmÛWWWz¬]Àìííáî  ŸX‹‹‹±víZLŸ>fff”|òõõŹsçMÉ3[¶lÁ‚ ‹ogg‡¤¤$êBˆØŠŒŒ¤$¨ªªÂòåË>¨•‘‘,XÀèw—¨è=Âwß}'Ð8zzzÐÓÓcô‡JQckk+öç‘-ÐsrrPQQ ÚÓ„ ]»v(..è£IµµµØ·oÆŒ}}}Jº€ihh`êÔ©Ø»w/ý¢-fZ´hÁèçùóçcëÖ­ŒÅ÷ññAMM cãcÈ+(ÒNHˆsrrB—.]PSS#õ¹¨««CQQ‘À*”““ƒ¦¦&=5õ?555ðòò‚¼¼¼@ã8::ÂÑÑ!!!”t{÷îʺC‡…¡¡!X,–ôè)))ˆˆˆ€¿¿¿@¦ƒ _€cÇŽ!55•ïë®®®Æúõë1aÂXZZR²…DOO¿üò ~ýõW¼ÿžBÄæâÚßß………ŒÄ» Y)OP^R@!E´´´àèèH‰&&&PPP@@@€ÔçâÚµkèØ±£PnŒ899¡¸¸/_¾”ú¼Ï˜1]»vȨùäëbcc…çÓëUŽ=++ çÏŸ‡¯¯/íe øôX4¿ç²LMM…ªª*ŒŒŒ(É ˜7o£wD ‹MÏrrßíxõøŠó…÷£Vff&ƇvíÚaÉ’%ˆ‰‰Áƒ„úÝÛ¿ôìÙ†††PRRjî8Æfõ¸xñ"ÒÓÓ1hÐ :$„©©)%ÀÑ£GÑ»wo¡äÃÍÍ ùùùxøð¡Ôç]UUzzzB‰€¼¼†¾£gCUS‡‘ø«V­‚¾¾>TTT`bb‚¢¢"”–– -þ¦M› ¨¨MMMxzz¢ªªJhw"€¿”——‡®®.zôè!ô×Û QVVF¢Yµj¢££ñáÃJª7n@GG£GZ¡xüøq¼zõJªó¾zõjèêêB]]](ñpâÄ Ì!Rú™3g0dÈÍ[Gx£  GGÇç¶mŒíÛ·ÃÏÏ˰1cÆ //×®]£dˆ˜ÚÚZÚ´iCß""ÌÌÌ “&MÂêÕ«yZÞÛÛkÖ¬%O„Í;þù'ž?NÉø‡?ÿü³þ¼ÅÔ Y„ÿTÔµahfƒc½‰¯¦©‹Ó7 åIŒDä“ɧ£bbbЧOF㇆†ÒA%¹¹¹õçß“'O6{}vvvHLL”Êñ=zgggŒ3Fè±CCC‘œœŒ¼¼<©Ë»··7lll„ú:a޳³3Ž9‚[·n‰Ondd{{{ØÛÛÿgþë„„<|øžžžÔ»bÀÀÀ-[¶Dbb"× z¬]|LŸ>aaa¨­­¥düO›6mêÏ[:::”¤¨¨ÈÈ/åP]YŽªÊRhê4핬¿þ8Ô¼øÕÕ(,,„¿¿£?ëïï5kÖ4+~qq1‚ƒƒ1iÒ¤FÖØØ˜/}pðàÁ&Åç—ƒÒA( jjjõç_kkkJH3\¸p¡Ñ¯'òÓ­[·ðæÍ©Ë»¬¬,c¯ìúûû#''GêžÉÏÏGûöí…>Þ‚@÷#A®¼uëÖèÑ£zôèñŸ»ä;vìÀŒ3 ¨¨HgQ1¹ ž9s&bbbðøñã/.sãÆ dff2záDG]]nnn8sæ %㬭­ëÏ[ôÈ—™™™16¨çÇQSSFâ¿Iº‡W®ÃmÒrF⧤¤ààÁƒMš'ÜÒÒ²Ù¯µ°X,ddd4é³8uêcû­‡‡¼bðôéüÛ¹sgêwÚv±òüùs¤§§cÑ¢EŒÄ·´´D`` Ô¢†ÂÂBèëëKÌqÆÈ q»v킯¯/Éb¨wïÞ_|Œ#??ÑÑÑ7n%IÌ|ûí·Ð××DZcÇ(<ˆ‡……455‰¿lÙ2 0 `$þöíÛQ]] ;;;Fâ'''#++‹vD1uùòeÆb4BŸøŸhžbæúÝÏÏOª¶933›6m‚››#ñ±yófÄÇÇKUÞÓÒÒh T)äææÆ÷sŒÐ ô²²2¼|ùÔ£bÈÞÞ... ùìï˜8q" œ#¦\]]ñ×_Q"x°sçN :æææþž¶®¬¬LhñËËË¡  F¶¿²²l6›v"–***ø>˜¯fÍš… . ==:BˆÀb±¤j›9*++mƒššvîÜ)uû›ºº:c±---1xð`¡^“ˆÂ¾^QQÙ³g3Ö%%%¾?µ ÔýÝ»wظq#‚‚‚èCŒ988 ''ïß¿¼zõ , 666”1Fs£7Mçν;ÃÔBH㥥¥¡´´”!DÝ»wÇøñã}zƒ ...ÐÐР@ˆ._¾Ìèµ”––ÌÍͥꉑüü|üúë¯|{%¦)ÆŒ[[Û/ˆ.z‹-0þ|ÈÒT3bMNNóæÍÃæÍ›ñöí[\¼x³f͢Ā~ø¡I†ñK`` 222h ABˆH;}ú´Ôl«¿¿?---ÆÚ0vìXXZZÖßÌ¡}ŒJ«V­ ¢¢Âh píÚ5ñ,ÐUTThÚ ¡­­ GGG9r³fÍbô‘B¤“@FFF at´`B!¢ñðÏëÄ÷ïßãĉÔ!Bôã?JÕÜŸ^±555•¨í¢[Ù¤ÉÆ‰Ÿ˜°°0#!!‘øf6N(ÊËFQ^6uƘ››ómzµÆzúô)TUUaiiÉHüÔÔThiiañâÅ´#0,44)))øðáƒTl¯ºº::uêD/DË–-C·nÝ0räHFÛѳgOœ9sÑÑÑR‘÷Û·o‹ÌµH||<߯~ 4‹ŒŒ %Âè9ˆ©A¿ ÛÀñÈ~ˆw¯¿øïjZº‘Üà™ãLJžžÞßkÎË˃‡‡Gý€†‚ ¡¡eeå/þ[PP:wî [[[Fú&22:::pqqa$þ­[·’’Bß“"@VV·o߯«W¯$~[£££‘‘‘áÇ3Þ–E‹!??_*æå®««ƒŒŒŒHïL~' ›œœtttDâZä·ß~CQQè„BHC¾ÿþ{Æb?‰9‹ã—@U]p¯v™šš"99ù‹ï>.Y²­Zµ‚šššÀâ9mÛ¶ÅÍ›7ÿóo©©©RqaNˆ(ùðáƒÈ¼rdmmµk×¢¤¤„:FJ¾÷„éÙ³gÈËËÃÂ… %nÛ¨@'„ T[[‹/^ cÇŽŒµ!11Û¶mc,þüùó1tèPÆâ'Ý‹’Š}íãǸ{÷.#±{÷îï¾ûÉÉÉtГmݺ‰‰‰R±­Lž÷¥Qyy9^¿~­[·ŠD{†ŠùóçK|Þ_¾|‰ÔÔT‘h‹™™æÌ™Ã·s è„"™™™ˆŠŠÂŒ3‰_RR‚ððpÌ;—±lÛ¶ÑQ„ùõ¨]JJJ••ÅîÝ»‰ojjŠ¡C‡"$$„:CÄiiiIÅ4¿!!!˜7ožH´åÓñQUU%Ñ9ÏÎÎÆ©S§ý¾“Ö￯½b%lrrrPWWçÛM *Ð !DŠ‹‹ñêÕ+8::R2‘ࢯmÛ¶xøð!%ƒˆ„¸¸8‘;>|}}©c„¨]»vhݺµÄoçÕ«W±k×.‰Ü6*Ð !DÄèèè@SS“A!|2bÄØØØ ''Gâ¿?444¨Ã…(==~~~"1X888@[[[âŸì9~ü¸HµgÖ¬YPRRâËT Bˆˆqww‡……þøãFâ·k×ݺu£Ž „HTáZPP€ˆˆ‰ÝÆ'N`àÀtþ²_~ùFFF——™6ÕÖÖJüQ¢ÆÐб±±¸zõ*è„"‰JKK{TÑÄÄæææðóóc$¾¦¦&Ú·oØØXÚ!„G111`³Ù"Õ¦ 6 ´´ïÞ½£¢îÝ»Kü6š˜˜ U«V¹mT Bùºº:ÔÖÖ2»U«V:t(öîÝËH|%uôÒBÚ„¨E‹ŒÅ.,,”ŠQikAI2ÄÅÅáñãǹ}ååå`³Ù"÷ZšŽ9‚ÜÜ\‰ÌûÞ½{Ñ¡CtéÒE¤Úůר@'„BþùÅ('–¦Ö8»‹¹¹U‡ &1?]à^¿~›7of,ß?ÿü3lmmiç—p›7oÆõë×Q^^.±ÛÈÔq,­Nž<‰‚‚Ìœ9SäÚöúõk‰AÿåË—`±X"y޹páB³×#З%N:…+W®ø{>\Qz7ƒB¾$88Ož<ܽ{W*#€¢’*tZ¶a$vAAÊËËPÿ·#F`Ñ¢EˆxüçÏŸ#""õÛ¸q£Ð^±(//Gtt4í„iiiX»v-€¿§Š„èèh”——CMMM¢r—€£Gbûöí"×¶7âÅ‹:t(íäB¢¤¤sss‰ÞF‘l×ùó盽ÞA÷ðð@xx8ÂÃÃáááAG !DäÍž=»þ¼Õ»wo©Ùn999ÈÈÈ0öe¦££ƒ^½z1?åI jªÊáè:Ž‘øqqq¸}ûöËÏÏJüšššÿCºººØ´icû£··7Øl6êêêè¤$E,--ëÏ¿ëׯ§„4Buu5JKKE²mLŸOMo@êëëcòäÉ •¸|geeáòåËøùçŸ%vŸ¢GÜ !DØÛÛ36EË;wðý÷ßÃÕÕ•‘øIIIPUU………#ñó³ÓPZ”G;¡éÑ£–/_޼|˜,RÏÖÖ666غu+è„"ÎÞ¼yCI DÄäææ¢¢¢‚Aç\±°råJ˜™™1öªRC\]]ѱcGÑÎ'DdìÉZzFbŸG7771³‡Æ€еkWFâ8p%%%ÐÔÔ¤JŒM™2…’@øBÔ ECCC¬[·Nbò]TT„ºº:´hÑBdÛ¨¬¬ŒqãÆQN!„ˆ:c‹ŽÈyûw#Úµ'''(**6úsãLJ““ž|ø@ÑökB𢢢'NœùvjjjbôèÑX¿~=u𩍍HÌ?uuuøðá£× m/è„"%FÅHܲ²2\¹rk×®elÛ—.]жmÛ2?/ëôMÛ1_œß%ÔÖÖ†¶¶6‰o`` ²w»–-[F'6"$é}hqàììŒÁƒãܹsb¿-µµµ`ôDX¨@'„F——‡­­-#±Ÿ={†°°0 <˜‘ø¸yó&íD,éêê¢{÷î˜7o#ñDz:&iòí·ßbàÀxþü¹Dl¹¹¹DNc&ÊæÍ›‡mÛ¶‰E[Ùl6®\¹B&D^^^055Ezz:è„"HñññˆÇ´iÓ‰Ïb±PQQAAH34gê›æPSSƒ··7vïÞMÀ0%%%°X,„††Šý¶ìÞ½#FŒé)Ö>9r$ PSS#ç,’|ªª*Þ¾}‹‹/RN!‚”››‹ìììÏþfmm-F„ÑðèÑ#J‘ÊýÉÚÚIII8räuœ 8Pb¶ÅÞÞ†††ßgT BH3téÒZZZŒÝÓÐЀžžu!„"ïß¿‡¼¼¼Ø|÷Ž;§NBRR’Xç}åÊ•èÙ³'Z·nM:!„†ÕÖÖ26 ³ƒƒÜÝÝqôèQFâHÔ¯ó„é0a‰،=š:Tˆ< 6LlÚ\XX(ö¯Èeee‰U{'NœH:!„H+‡ƒ˜˜FbkkkÃÁÁ>>>Ô„üK÷îÝ) "ª_¿~رcž={&¶ÛðÇà?þ@Ïž=é˜ DÏ1sçÎEeee£?+/Ȇ:uª~ÔÀÄÄDÈËËSoBDZpp0ž|¸Ø´UQQkÖ¬Á… àää$–ù¾wïΟ?S§NIÅ1B¸B!ÍôôÎùÿ^©¨AÇPð#üoÚ´é?¼ùùù())a´@‹‹£ƒˆ,MMM¬X±Bì‹Å:Pg QAA6lØ VïŸrþüyê@!²³³Ã¤I“štŽ¡Bˆ@ÈÉÉAV–™¯‹…:ÀÅÅ…‘ø¯ß»¶ý~x,lٲ峿=xðwîÜʶN›6 ,K¬&ÒGVV-Z´øÏ±#NöíÛ‡ ˆU›­­­Ñ§OÔÖÖŠeÎÙl6ŠŠŠèb€‚‚‚XµWQQêêêØ¼y3è„B˜ôíÛ—‘øk×®Euu5ÌÌ̉Ÿ—в¢|©èëîÝ»cÕªUÈÉÉa$~¿~ýè€#R鯿þ»6ëëëÃÒÒÓ§O§$<»qã†TéA:!„ˆ‘‘ää䉕•…‰'ÂÜÜœ‘ø'Nœ`là8"]&NœˆÓ§OãÅ‹ŒÄ766FYY™P5#„0+++ “&M»¹¸GKKKäç‹çLJ–ªýŒ tB€ãÇcáÂ…ÐÐÐ`$~@@Z¶l eeeê "ñ>|øÀØ¿?ÿü3bccqëÖ-ê1Ó§OR"H£¾[ŒŒÄî»U__ïß¿—ºB—i£FjÒ£ùT Bˆ\½z•’@!"ÌÁÁéééØ¿¿Øµ=)) }ûöÅwß}'vmïÚµ+í|D*ôë×çÏŸÇ7¨@'„B!„6›šš±k÷Ñ£GQQQ!vgÀÌ™3ñçŸÒT„B¦©©)–í.++ƒØŽ7R[[ÛèWþ¨@'„4dÈJ!„‰”••…ÂÂB±k·ªª*cƒŸ6×¶mÛpõêUTWW‹U»·nÝŠÊÊJKÍñA:!„ˆ Q£Faûö파½nÝ:¼ÿ¥¥¥Ô„‰µnÝ:¤¦¦‚Ãáˆ]ÛÛ¶mK(Dþù'âââ0hÐ ±Ý†K—.¡²²’:SÈç˜W¯^QN!’ °°±‘Ð[¶l‰óçÏãùóçŒÄ3f ÔÔÔ˜K¾ íÒDF†¹?wîFŒAÀlÙ²E¬fÈÉÉATT–,YBÇœ•••¡¼¼œÚ_}=µ~ýz*Ð !„ˆ7GGG\¹rçÏŸg$~y0¶°£Ž{{{hii1ûÎ;˜0aúôéÃHüøøxtéÒ…v³’’$&&Šõ6„……áöíÛÔ™¤Aåååxüø1ÂÃÃ¥j»©@'„B¾ çm2nŸc$¶««+œœœ„oîܹPUUed[×­[‡Áƒ£eË–ŒÄ?tèX>ÞLˆ¸‹ˆˆ»6‹ó´|3f c¯Î5ÅÇû¡ž tB!DÄTW–¡¤P82£GþìÿõôôÑÑÑ}úôi˜››CNNî³ 9aM…”ššJ;aŒ©©)zôèA‰ \9skÖ¬Ûö«ªªÂØØþþþÔ™BÔ©S§FA:!„‘øcJVj~ð b,þœ9sàîîþŸ¿—––âÎ;ÿÇ|±h±±±Áüùóɉºº:¬¬¬èÀ gdd„Î;cΜ9bÓæ„„,_¾¼þ‡>ž‘¸êêêX·nu!”––†   ±i¯••,,,Ä:ç}ûö…’’’Ø´÷Ê•+X´hLMM¥êØhž‘‘ØØXÄÆÆ"##ƒÎD„‘÷êÕ«úóÖ‡/&& ¨¼X IDATW¯^¥Ä"‚V¬XAI¢²²²úóoBB‚Ðâš™™‰Õ:eeeÓ#DèС:tè ÖÛ1lØ0ܽ{111bÑÞ“'OJÄþÓØväÙ˜wïÞÕŸ`ß½{GG7!Dä½yóoß¾|ê§ÒÒR”””Pâ AÙÙÙ”!*//¯j"//Ohq/^ ;;;¼|ùÖÖÖ"£{÷¦?ýôí0BÄØ+?üVRR"V¯tH‚åË—cĈðó󃮮.³z=êGÆ,--ÅÙ³g©‡!"mРAõÿýèÑ#TWWSR!DZ¶l ?þ,Ì'RRR-òú‹/Äjš¬†ìÛ·O*§Ð"ÒéÑ£G(++ã©@§wÐ !DH:vìwwwäççS2!„H5999„……¡¨¨H,Ú+Σæ‹ãv”——CCC“'O–ºcƒ tB---añâÅŒÄ×ÑÑAŸ>}¨#!„ˆ„´´4ÔÔÔˆE[3M–¨oǹsçD¾‘‘‘ˆ…¹¹9è„B$S‹-ЫW/,X°€™/YYØØØPG±fkkKI ~¥¶J‘—/_"44T¢¶)22’:VˆŒŒŒ°`Á$%%QN!ä¿>~üÈH\%%%øúúbÏž=Œm»¼‚"íbŠÃá€Åb16EPAANŸ>ÍØ\D°,XÀ蹉W{÷îÅüùó%"ç²²²PPPùvÖÖÖJÌq„rrrÐÔÔÄÖ­[©@'„"zbcc‹=vA^>ºNÐDÊÊÊpqqa$ödžFâWVVò|÷ƒÐ¹IšÛÈ++++,X°×¯Ó9™|Ù€¤r»©@'„"Uâ¢2{ð”dff¢®®®É²¾¾>#m‰‰A\\FŒA;!„oŽ=*òmlÕªäää$"ßýû÷‡³³3Þ¿/Òí\½z5ÆO:!„B¾®eëöhÝΡɟ×1l_ý§ÑŸ½{÷.0a„&ÇÿñÇ›üÙ¢¢"ÓN@‘*ÇŽÂ  ¡¡!Û£­­ 6›;vˆt;ÓÓÓ%j?rssƒŽŽè„B$‹™™cw/ZY9˜¶c$~bb"rss›µWWW¬Y³ÙÙÙŒlC·nÝh'þ‚¸¸8JÃÆŒƒnݺ!99Y¤÷“‰'ÂÙÙ™:Lˆ®]»FI Íæä䄸øxœIüŽUWWÇàÁƒE²mÉÉÉ8vì,--©@'„"žÜÜÜpèÐ!<|ø‘ø666PTT¤Ž „ˆ5X[[‹lûºtéB$D 4hÄm›ªª*¾ùæøùùQG ‘žžLLL¸.'/ÈFœ:u W®\$&&B^^žz†"Ò‚ƒƒñäÉÀÝ»wѽ{w±hwuu5cØÿôÓOؼy3îß¿ggg¡ÇWVV¦ïòÅb‹©ù¢ËÊÊ0`ÀtèÐ:¢ÒÒÒ°víZ@II‰Ðã`̘1(++¹Ü”——cÖ¬Y´“‹Åž={0eÊ‰ÝÆòòrêh!²··‡‹‹ öìÙƒéÓ§u9ÞA÷ðð@xx8ÂÃÃéLBˆX˜={výyKZçßlŠÜÜ\ÆÞ!œ6môõõÏHü–­­¡klN;Á¿¸ºº2öÃÉåË—1þ|˜™™1Μ9hÓ¦ ttthGhKKËúó/“SZŠâ]EºÓIˆdøôdFCèwB!b/++ ÷îÝc$v+K{¨ièàÆéí"•“ÀÀ@Æb/_¾#FŒ€‚‚#ñO:E!b¢oß¾èׯÒÓÓ)iiiX¾|9”””¤6T B!ÍÄf³PV”÷Ùߺ»OJl+++¸¸¸|ö·ƒÂÈȈ±|{ÀÄ~ýúáÆŒmo—.]{‚ƒq§®®lß¾]äÚÖ§O˜›KæRîîîhÙ²¥ÈµkÍš5044„¬¬ô–©T B‘H¡¡¡ŒÄåpØ8¾y:ÚvÎ+†††°¶¶†··wýßnݺ%´íÕÐÐ@@@~þùgFò-''gggܾ}›±}í›o¾Á;wè #c``+++J„yyyÁÆÆúúú¹}:uBRR"""¨³…¨gÏžT B®êêj”””`ñâÅŒÄÏËËà ê8~à0²­`±X(,,d$¾¢¢"Œñöí[F/t? .IÄÛ”)S ®®.RÅ;v ***4.Š”œS…ú]UW'Û)J¼¼¼PRR‚êêj*Ð !Dš¨¨¨ÀÍÍ‘Ø 8vìcÓUWW3Z¬BÄ—™™âââpñâE‘iSFF*++%:ï#GޤŒÅf¦:vìXƒÅQN! ®®ÎØÒW®\ÁíÛ·1`ÀêB!"oèСطo^¼xAÉ";;;‘jOzz:ÔÔÔàèè(ÕýB:!„ðYtt4X,cwªªªPUUEA!Dl”——ƒÅb‰D[Øl6€¿G–dóæÍÞ={D¦=çÏŸÇëׯ¥þX Bø,--±÷q !„HWWWJ‚ÅÄÄàôéÓèÚµ«Äok\\u¸0‹oYYôë× tB!âGKK ÅÅÅŒÅWTVCmu%êêꘉ¯¨ÔÔÔ0_NN¶¶¶xúô)c}п\»v±øcÆŒÁÉ“'é`”2«V­™9¹Y,ÖÿµwßQQ\ïÿÀß´-ôÞAA”bCl±×€ÅŠ]Q, ‰ÆXÐÄEQQc÷c7ö(cÅŠØ:‚ÔÝßþ˜¯Ê»; <¯srN„ËÜÙgîÞ™gæÎ½HII··7Beee >¯_¿¦Bêwwwœ:uгú¿úê+N—Žš1cÂÃùûüžSðÏ©(-)æ¤þ‰'âÌ™3HMMå¤þQ£FáøñãÈËËã¤þo¾ùW®\áì&M÷îÝ‹´´4êŒKKK,Y²D.ö%##ƒÓ~PV„B!¼¼¼¨ñŒ=ºQ|ΪúJÐ !DN/qäÈNêçñxðööÆÎ;9‹••9«ßÔª%RqV‡póæMÎêïÙ³'¢££9«¿S§NøçŸ8«¿mÛ¶UβK‘>Ÿ¯¾ú þþþŒFª¤¤1114Á-%è„"Ÿ€³áÕÀ§÷¤h}TÒèèèpRoii)rrr0gÎ:„œ½Òó¥ÌÌL5øx·jÕ ýû÷Gff&çûòñãGN P‚N!„±äädÄÄÄàçŸæ¬þ°°0¹[êˆÈ—.]º@OO!CAAAhÙ²eƒÿœÚÚÚ033Cpp0trvv†©©)%è„Bù/uuu˜››sR÷û÷ï!‹ÂIýIII¸sç5RÎW_}www<{öŒó} A×®])A'¤qqqA^^¢¢¢(A'„BÈÿ‰DhÖ¬g“3]½z·nÝ’ésEEEN_QPPà´~R=¡Peeelذó}IOOo4q0`ÌÌÌèÕªFª´´ýúõƒ¥¥e£ø¼ÅÅÅÈÉÉ¡B÷Z·nG5ÚÏß­[7üùçŸÌ¿-,,`mm-³úÛ·oÛ·o"""#ÓÏïàà€¸¸8Îâïáá“'OrV¿‹‹ Óÿ>þœB8ñþý{´mÛýû÷oŸ÷ûï¿Gff&òóóéà˵µ5¼½½+ü²4+~úô)s—þéÓ§t$!rïîÝ»ˆði§-ZHtûK—.…‚‚<<<8ù|055…‹‹ 'õ{{{ÃÙÙãÇg~Ö§O™½_i×¾¢ÿ·JJ*€ß·/„º¶øª2©ßܦ-~Û¾ š*¥L“å“TSSS”––rvÓ\EE¶¶¶øã?8ûŽ÷ìÙ>>>œÕohhˆwïÞQg[ììlææMcÚ]uuu¸¹¹Q d("">|€¾¾~£I=Š˜˜|õÕWÔdDUUÆÆÆ²Oлuë†nݺøôžÝ1&„È;OOOæÿŸV­ZQ0(A'„Bˆ$¤¦¦âìÙ³¬Êššš"%%¥Úroß¾e½ÔUjj*ë'Øßÿ½D?»žž±víÚj˶iÓ#GޤCH%Ž=ÊY‚^XXˆ×¯_ãÇlT1ÿñÇñâÅ j|2Ô¼ysL˜0tB!¤¡ú믿¤2óõ¯¿þʪ\`` rssY•1b8Pm¹>àǬ¶™™™‰ß~ûÕLÄl'É[´hzõê…_~ù¥ÊrÝ»w‡§§'Þ¿_í6͹@X«ìžHÇû÷ï“Fõ¹±|ùrj2Äçó+]RŽtB‘€²IŸ¸Ò¢E <{öŒ³ú§M›†Í›7sVÿèÑ£qôèQ|üø‘“ú[uvÇ›WqHKIà¤]uéÒ]ºtÁÛ·oYmwäȑؿ?«²W¯^­¶Œ““ŒŒŒX?AŸ÷® f}ñÏæfBFF«v5iÒ$¼}û§OŸfUÿÊ•+Y•344dUÎËË ˆŽŽf• ÛÙÙ±ÚîöíÛáää„7VY®¦“r5)b™   \¾|™Óï a×NvìØÁYýb±¸ÑÅ\ @KK oß¾EII ^¼xQî¿Æ°² Wttt™™‰cÇŽaĈðññ<<<ðï¿ÿJ½~¶ç›Æ@™B@!uÃçó¡  €‚‚Î."544““CCÂÚtõă¿ŽÁ©çp‰n7997oÞ¬¶ÜëׯaccÃj›ÆÆÆ¬ž ÷éÓëׯ¯¶œ’’Î;‡I“&±z‚l``€´´´jË™˜˜°ž©YWWÚÚÚHHH€«««Äâïåå…Í›7sötÒÆÆïß¿GVV}Éꉇ–[îLQQË–-£ÀHºÏmÓÞÞÞ˜7oœœœpæÌôêÕ pýúuèééaòäÉèܹ3K‚Ú·o;wîÀËË }ûöEhh(lmmgÏžETT„B!æÎ+•ú>LCì?COÐ !„È-;;;qwwÇ7XÝPø\óæÍ! é‹ÙH4iÒ ;v,Î;‡ÀÀ@æ?UUU,[¶Œn²HÉõëׇ£GbÞ¼y˜7oöíÛL:ÿüóTê}ðàæÌ™ssóFwc$>>ãÆÃwß}Ç$ç0`À„„„ )) S§N•ÊÈS§NQ£§BW””” ‰X ß5j¢¢¢XmW °6®ÂâþÕcÈz_õ=sX9t„˜Å°uð…ê(ȯ~’´3f@QQ‘Uœ&Nœˆ´´4VCÇUTTêÍšÉþþþøõ×_YMèV¦  ~~~PVæfðßæÍ›áíí]é0LÎFÒÉ8p 455¡®®ŽY³fÁØØ˜ùoþüù=z4–,Y‚ƒJ|8zAA\]]áììÜèâîç燽{÷bÛ¶mPWWg~®ªª ìÚµ S¦L‘J’uuu())5º¸/[¶ 'N¬ðü$°bÅ äååaÑ¢Eõæ\C :!„ÇÉÉ 111ݦ±±1Ž=ÊjvÖÛ]³f «áwC¦¯EJ£jË©j袳Çd¼OzŽÌwIU–ÕÔ5† _ˆôÔD‰ÆÊÞÞ?–øqíÛ·/.\¸P«¿“„öíÛãÁƒ5Z < íÚµcusCnß¾]åï °hÑ¢µY"ÿ®\¹‚ˆˆˆ o YYYá»ï¾ÃªU«‘‘!ÑzçÏŸuuõF7›8´k×®ÊWZÚ¶m‹ß~û S§Nŵkר‘JHûöí«>'ªªb×®]Ø»w/¦NJ£Bˆ¤hii!;;›UÙK—.áÊ•+¬ÊZXX ))©Úr***øóÏ?«-׳gOôéÓ***Õ>•´··GBB‚ÄŸ^:õ†ä÷ð.I²Ë—5mÚ/_¾¬ñß-Y²D"õ{{{—{Ÿ–E‹Éõúݶ¶¶5jT­âJHmaܸq ¢áî2äèèˆíÛ·cðàÁœÎ´ß?oÞ¼‘è;ãZZZ•.9F :!„¹Ò¾}ûjŸÜÕæD¸iÓ¦jËuíÚ•õ0¿Ö­[£OŸ>X·n]µe.\Èj›ššš˜9s&._¾ŒÄĪŸL …BB$Iõx¸ö#‘í,\¸K—.e]¾¤¤û÷ïçô½Èäää*ïàà€víÚq¶úúú5Š+!’mmmøúúR0d¨e˖̨•†6O†<³··Ç´iÓ°wï^¼~ýºÎÛ;yò$Z¶l‰>}úPp)A'„êíÙ³G*k ³¹˜hݺ56oÞŒ/^°ÚæìÙ³Y%Èßÿ=âããY]ü|óÍ7ˆ‰‰©v(r“&MðêÕ+‰Ç©S§NåÞ3ìØ±c·©ÂÀÜÆ/³¿ Ë|û gwý„N½8i‡¥¥¥¬G2pÅÒÒFFF¦Žƒ4:k×®…££#L+jȈªª*¦M›†V­ZaçÎÙ¦¹¹9~øá n5úöí @€ßÿ]"×CyyyTJÐ !„}bÄö©¬šš«“LPP«µ­‡Êz¶m777œ?¥¥¥Õ'¨**¬?¿ŸŸvïÞüü|(**BKK«î ²Š 444jôÎf\\NŸ> ??¿:×/PÓ„sŸøëûuëÅb1D¥%rÝV mmmìß¿ŸÓýhh“͘1¥¥¥4ù©ú‚ZQÓ¦MÃåË—%¶f´®®.–åwtÏž=už ::111œMDYŸðxÛ¶mCnn.„tB‘?Ý»w‡®®.Ž;VmYÖÛõôôÄñãÇ«-gff&±‹ÂÊèëëã»ï¾«óv0qâÄ­§š••%õÏ' f6mñï‹ûœÔmjj Gï`K˜­­-~ÿýw©Œ¤! ‹ŽŽ¾ÿþ{œ8q¢NÛy÷î®_¿ŽÕ«WSPYèØ±# TçóÓÛ·o‘žžNeiüøñPTTÄ/¿üBÁ BdÇÄÄ©©©¬ôË—/K¼þ²=99˜8q¢Dn&ôïßÏž=cý7gÏžÅÅ‹å>‘âriœîC¦#þÁU$?¿G_ Z½z5¶oߎ§OŸR0ˆÜóóóõk×êtCñÝ»wR[ç»!÷ûöí“øª#¤ú¸/^¼¸ÎCÔkòà‚ô:*))Aaa! i½!!+W®ÄÌ™3)˜²Jн¼¼àååX³f ~ûí7¸¸¸²³³áããàÓ„A …°±±¡£"'ž?Ž‚‚lܸ%%Ÿ&G3fL•OðBCC™õ•‡SSSØÛÛÓ„r$..yyyÌÍ2àÓ<¡PHÁ0uêÔrq‰‹‹«7ûnff†ÔÔTX[[sRÿ˜1c0cÆ Œ5ªAµ msd½çîý÷±cÇ¢wïÞõ&^éééÐ××ç¬þ˜˜ !!¡Ò2JJJ066æt^ƒ±cÇÒMÑ/XYYaóæÍ>ÝhÙ³gO½ü­[·Æ Aƒ°téR,^¼˜¬Œ 4Û¶mî]»0vìØÿýÒ¥KF¬¡   tîÜ×®]CçÎ) òž I]]íÛ·gþ]vÁQTT„Í›7£¨¨©©©XµjUf&’UXXˆï¾û&&&àñxØ´iëûóã{ðàAÄÅÅaçÎàñxøé§Ÿ(¸ GBBÌÍÍ¡ªªŠ¨¨( J ´lÙ’‚!A}BñëRJ¤ØÚ³g¢¢¢äú•mmmÕh¢BBjr½P§ žžžt㼆 0f̼}û¶VŸ˜˜HA¬KKK¸¹¹!22’ôú˜ W†ÇãaÖ¬Y(--Ň0cÆ ())¡W¯^øú믡ªªJGJÊòòòÊMµ|ùr¨««×ihÖðáÃ|¦–ŸŸtíÚݺuãì _c“žžŽË—/ãôéÓ˜1cÆMMMz?RJ6mÚ„‹/¢E‹ ÑÕÕEhh(îܹSoö9éY ,Z8qVÿ’%K°víZ¹Ž‘½½=0}út‰Ì«PŸ/l½½½é‹ÞõéÓß|ó &OžŒ.]ºÔèo§OŸOOOðù| d õíÛNNN˜4i-S'ã¸Ó0uÉ‘«YÜ•”” ¥¥…-[¶à矆@ À·ß~‹sçÎÕëw‘äYNNΜ9ƒyóæA `ݺuؼy3´´´$öÞ”¦¦&ŒkkkìÝ»>>>¸qã)INN†V®\ @€¨¨(8::BKK‹’s) …5šx­>PVV†ªª*g}°‚‚„B!3야¼<¨««s³«Ç¶ ë ©œÕ_PPPí…}»víЭ[7ÎÖ¯URRÇãü)»ú÷ïÏYýïk·8 IDAT ”„5`þþþµZ›[Þ'ä”gpssc^·$²ñÕW_ÁÚÚ»víªq2vìXº™òåµ—¼î˜@ €»»;ÜÝÝqðàAüüóϰ°°ÀäÉ“é¨IȶmÛœœŒV­ZaÆ 2©³[·nèÖ­`ÇŽˆŽŽF@@@£~‚"iëÖ­CQQ a'K`¦L™‚Ù³gÃÐа^ìóªU«hèr5ôõõ¡££ƒyóæ¡mÛ¶œí‡­­-ôôô8«_GGG"?~éôéÓôdœ mÛ¶˜={6<<<(2¢®®kkkÌž=ÇŽ£€Èˆ‰‰ 444j¼æìٳѷo_ºQù…z±úðáÃ1gÎ888`Ë–-õjÒ&yôøñcDDD uëÖ˜3g† ÆÉ~Œ;C† Á?ü€ß~û ñññtpê ::>>>èÛ·/¦OŸNi ºté‚>}ú`É’%õfŸ÷ïßOÉI5 ccãr“5ruQÅåhƒ–-[ÂÎÎNâÛ]·nfÏž-óÏcaa¡PˆÃ‡cÈ!ÔÐé{.ßóÆæÛo¿Å;w˜×6Ùˆ‡››[_G ÿgùò刈ˆÀëׯ)!A---tîÜNNN8uêîß¿OG¯îÞ½‹Ó§O£}ûöèØ±#´´´8Û4oÞaaahÒ¤ 8€—/_ÒAª¡’’øøø 99QQQhÕªÔÔÔ(0&‹9©WUUjjjxÿþ=뿹wïÚµkÇY¬²³³9í[X%†ÝQ—ƒøûW9©_SSÊÊʵþ*I^^^°µµm0ßÓ²WxÒÓÓ9y2?zôhXXXP‡Iêô=733ãt¹ÊúN__?~ćXÿͺuë ¢¢Bó^Õ‘‘222P\\LÁh, zWWWãÊ•+X´h½cÂRVV.\ˆ¿ÿþÁÁÁÌrwò¢{÷î˜?>>\§õ+›ÔÔT,^¼QQQµZR„Toܸq077g½ H$BFF 8Ûçׯ_KeØ®$uìØÉÉÉœ-seÖ¬5Š‹ ð.ù9§qX¶lLMM%¾ÝW¯^¡iÓ¦œ}®M›6! @æõ†……Iå•)kkk˜™™Q‡Hj,** ,@jj*«ò[¶lÁóçÏi5 Ľl9g"&&&X¶lŽ1&èeáëë‹íÛ·S’^ììlDEEaÊ”)r?ôyêÔ©8sæ =z„¼¼<:x•())Á³gϰ{÷nš5SMRR¬¬¬äz?çÍ›‡¬¬,rR¿··7=z„‡r‡þcæIe»ÅEPáq·DRLL œœœ8iWÒ ££Ãé;Š:t€ƒƒC½‰‘<ºººxóæ C†ÔÕÕ! k4úŒÔžžJJJXO,kff†qãÆQàJ‚æææ1b„Ü/'Ã%‘H„µk×ÂÛÛ»^ÜýWSSCPP.\¸ÐàfÖ¤]»váèÑ£ðóóãôI-©¿lllðÛo¿áÉ“'œîÇСC%¾ÍììlˆD"hkkW[ÖÀÜF ýn)Râ¼¹cƒˆgMÛ•4L˜0Í›7opñ’Æg"òÅÂÂþþþ˜?>C†z÷î ggg¬ZµŠ‚!CS§NÅ›7oXMЃ””z-¨¡%èeIzpp0BCCMGô3—.]²eË,•!”Ò4{ölx{{cÕªUÈÏϧƒù™mÛ¶ÁÞÞß~û­Ü¿çK*†eË–!--ÓýÆ ÞYYYÐÔÔ„¢bõ§˜¯¿þZâõçææB,sòý0·iËéñ”F<`Ñ¢EÐÑÑ©íOâEÈçlmm‘““Ãz˜;á¦áº?jlqôè’’’(` 1A Œ?ÉÉÉ8räg“9É ‘H„C‡!%%&L¨·K˜YXXÀÓÓ‘‘‘(**jô_ÖÒÒRìØ±­[·FÇŽ©÷’c………àñxÕö[yyyð÷÷—xýÅÅÅPQQaU600Pâõ?{ö VVVPV–ýJžÒšà‡'`·ÝÃ¥R¿4Þç.[cž uuuV7\jJíy3vìX$&&⯿þâ´klqüøq$''WY.!!gΜ¡W%÷7R {‚Mš4ÁرcÁçóqôèÑF}P9555Œ3Fî'ŠªŽ­­-<<<°jÕ*\¸p¡Q×;wÂÖÖ–’ózà—_~ÁĉY••Æ{§OŸn´O¥uQ0|V8§ŸKíD(bõêÕô…eÁÒÒ¯^½¢@Zc3+{ii).^¼ˆððp ˜„ú8äææVY.++ 0 177GAA‚ôÿãîî@€C‡5ÊzðàA¨««7¨‹ófÍša„ HKKÃüÑèŽi\\|||ààà@ës¹¦¡¡¹sçJeÛ¡¡¡ .^ðóó£†S eeeðx<s¶¶¶¶3f  Rk#GŽÄÂ… «MÐëõ«4¨ªªÂÃãڸÉ_·;99añâÅ JÐÿ››ÔÔÔ]'wðàAhiiaÀ€ î³™››ÃÛÛiiiêIzll,Μ9ƒ¨¨(zrNªellŒ¾}ûrV¿’’LLL¤²miLri`Ö Ö­;s/W/&y466FNNg+k¨««ÃÈÈÞÞޜƖY#uÅÕ²’wŠ»¬‰Åb¤¤¤T[Ž–nD :ðiâ—Æ”¤—%çýû÷oПsĈHOOoOÒïß¿èèhÌš5‹zªz” s¹¼šŽŽŽÔ&¹‰ŒŒ”ø6---9ÀRSÏF–võ¢]½}û–ÓvõñãGlذ¾ä, Y³f¬Ê¾zõ JJJ”ü7ýúõC¿~ýDÁ¡Ù³g#++ ;v쨲œ‹‹ ”””(`¼fˆŠŠÂ7*-ãçç‡=zP°S‚^–¤«ªªâðáà vâ8±XŒC‡ASS³Á'çÀ§IFމ÷ïß7è$=%%'Nœ€¯¯¯T&f"Òáàà€Î%ÿD–ÏçKe2-MMÍj'³+# —:Ô‹YsyB5”B¨®ÍY»zöìç7ëêËÅ«ªª*ëÉï?~ [[[‰ö³¶¶¶èÞ½;ësxÙ¹4ð nEE"33“&¾•q¿¥§§‡wïÞUZ&-- ãÇg}>$ÕSVV†H$‚H$ª´LII ª²øIsãçÏŸÇßÿ ¸ví'ÐÍÍ §N‘#G0dÈw> 55µ9¬½*ÞÞÞðöö†H$b5ñJ}sîÜ9ôèÑ|>Ÿz)Û·o³6ø;wЪU+èêê¢[·nœ^`´hÑW®\‘èv'L˜üóÏ?tà«Ð¶ë ì^პC¹›q\QQ¶¶¶ .¶qqq°··—è6ÝÝÝY—ÍÎΆ¦¦&%Èr")) Û·odff6¸Ï·råJhjjbæÌ™•Þœtqq¹¹95 Zµj:wsçVx£1$$¾¾¾( RPPÀ7ß|ƒãÇ£S§Nšžó¥¹ñ:À××¾¾¾èСgÒÝÝB¡°Á woˆÂÕDxx8îÞ½‹/^4¨ÏU¶Îy×®]©‡â@ß¾}™~ËÎîÓðg©ï¾ûúúúôj4iÒzzz5jCÂvî܉ñãÇKt›“&M‚ƒƒë½ì{ÖØ˜˜˜àÍ›7Ô?cddÄô¿#FŒhtŸ?88ÎÎΜ¾úCˆDLEE 8'Nœ `È[‚®¥¥sss˜››C[[›Óêææ¡Pˆ#GŽ4ˆW\\Œ‹/6º'çŸÓ×ׇ§§'Nž<Ù †ÉˆD"DEEÑ:çrЮÊú-555©Ö¥¥¥U/^aàñx‰Dœ q6lNœ8!õã!)JÊì‡I8pÇ—hýÞÞÞÐÔÔdUöÇPWW—hýêêêõb¨¨²²2§çŽ^½záâÅ‹Ôé~Ñ×”õ¿\ÎÚ/-B¡ãÇÇÖ­[+ü}FF5)hÞ¼9zõêUi܉ôú8UUUüþûï•öÁô' º¼éÔ©>|ˆ>ÔëÏ‘››‹ü+W®lô ØÎ΃ ÂÊ•+ëý<¿üò ìíí)9od`mmÍYý>DëÖ­«,³bÅ üóÏ?R­sýúuNGX=¹[§^’Mƒ#jÿ6mÚH´þ6mÚ@ З«³fÍBXX‚ÈŒ²²2œœœªœ8‹Hž¾¾>š5kFq—±fÍšÇã1¯ ~.::ÞÞÞ4Z”t@WW¾¾¾Ø²e ²²²êågÈÌÌÄÖ­[1eÊÎG%È +++Œ3k×®­·7_víÚ…fÍšIe‚1Rw†††R›Eûþýûptt¬²LHH%þ®.üù矜¾_ÿûï¿ÃÃÃC¢Û¬Éš··ÎïK¿ÑÔÈ90gά[·ŽA•‘#GÂÂÂiii 277GVVV…׉öööÉD>±°°@JJ JKKËý|ß¾}UN G z#cjjŠáÇcýúõõrÿÃÂÂ0bÄ©­5\_5iÒ¸sçN½Û÷¼¼<¼xñBâOшäLž<©©©ÐÒÒâ¤~KKK@UUµ^Ä‹ëõª›4iB–…¡C‡r:7‹¹¹9’““é@FÅÐÐ/_¾Ä(2´páBœ:uê?׉W®\Aff& (HR°xñb¬[·®Þ>¥]Æ»³gÏÆ’%KêÕ,¡³fÍBPP,,,¨åV’ܽ{qqqõfŸSRR°nÝ:ÌŸ?ºººtåX§NêÍ;ÐíÛ·ç´þ>}úPƒaÁÎÎŽÓþªG¸|ù2–bccѲeK ©3— ÎãñhT‰ŒÝ¿ïß¿§@JÐ妦&,--ñèÑ£z±¿÷îÝCóæÍ%>™OC¢¢¢???üþûïxõêU½ØçððpøùùÑrj ˆ‚‚gOÚËøûûÓ`ÁÞ¥/ânžç¬~//¯3q©,äççs:ŠäàÁƒ¬†Á …BäççÓ#UöÑ›7oFaaa¹D1::šæ¢Ù³gÓ ³°°À!Ch¾JÐÙ›8q"bccqëÖ-¹ÞÏ›7oâÆ Ù«¡ªªŠ¹sç"44Tî÷õâÅ‹hÕª éÀ5 <+V¬ @°`mmøøxÎê×60GÖ{b]_ìÚµ ãÆ“ûv5räHìß¿Ÿ©ÒãÇ˽ƒ›žžŽ”” ŒµnݺÞ<˜k(ÔÕÕaee…‡þçw¤Q‚^±I“&áÀÈËË“Ëý+))Á¥K—Я_?j­50zôhìÙ³Gn÷ïòåËxóæ FŽI‹pBMM –––œ±nÑ¢ž={Fƒ‘H„¼¼<Ö˧IÃÅ‹«}}AII B¡Ó ;©]yײeKŒ3OŸ>¥`È‘‘ø|>^¿~]îç¶¶¶)²¶¶†²²2óï»wïâÀðòò¢àP‚^1‡áÇc÷îÝr¹L×¶mÛлwoXYYQk­^½zÁÄÄD.“t±XŒÝ»wcôèÑœ­+M¸gllŒüü|äääpÓù+*BEE¥ÜKRå  ÀMõÅÅÅxñâìììª,§ðÿwPç³¼¼¼jçaPUU…©©)^¼xAm†Jðù|hiiÑr¹2Ö¿`×®]€‚‚ìÙ³ß~û-GŠüýý»wï2qçêÚ‡ôzÄÕÕººº8wîœ\í×îÝ»ñöíÛJ'!Õ'éééé¸ÿ¾\%çË—/Çüùóé5rššš(..FAA«ò?†ƒƒgû›˜˜ˆ¦M›rVÿÛ·oa``À$ ²–ñö”” m`.×íªyóæÈÎΦI‘s;w.÷T§K^6FÅÅŸyó&B’’’þ3rP‚Î*™{øð¡D.jRSSë¼÷ïßãêÕ« ¤ƒSÆ Ã… ê<[ÿû÷ï%²ÐO?ý„#FÀÚÚšN= ???ÎꎎFÏž=9«ÿîÝ»h×®gõ'$$ iÓ¦r?‡EóvHz~¾0¦«« ÇYý}úô««+"1£F•+W˜155&L ÀHÙüùóIëÐswIäG” 72zzz̬šééé5þû§OŸ"$$!!!ؾ};óÿÏŸ?¯Õþ¬]»K—.¥¥·êÈÄĽzõÂÞ½{kõ÷·nÝBHH6oÞŒ;w"$$'Ož¬u‚Íš5£S½~ý–––Õ–Ÿ_£aLX²d nß¾Í˹sç"$$%%% ÂË—/k´kÖ¬App0®_¿~¸págõ÷èÑW®\á¬þöíÛãöíÛœÕÏõÚâ ÕâÅ‹¡££C`iýúõR­ 6àÞ=q#KjjjœÞì#Ÿ–Ž^»v-ÍÃD :{Æ CVVΟ¯~mÜÂÂBüøã8yò$üüü ¯¯}}}ðù|æÿýüüpâÄ ,_¾œÕdL/^DFF†JKªIˆ²²2&OžŒ;v°ºcúñãGlß¾'N„¿¿?ôõõ! Áãñ ¯¯ÁƒcÁ‚øí·ß˜;ßU‰Døßÿþ‡AƒÑzç„Z™1cçµõéœÄ6^ÕMzW[êêêõâ¸n©««cÆ 266ưaÔ(Ê€««+ìíí±sçN„‡‡³î#}‚~õêU¬Y³kÖ¬ÁåË—«ýÃ]»vaÍš5(**jpA9r$8Pm¹5kÖÀÛÛsçÎ…@ ¨°ŒP(DHH† †µk×V»Ík×®¡S§NÔ2¥`êԩزeK•eòóó±jÕ*Lœ8±ÊáÌ:::X¸p!ªôâíÛ·¸ÿ>-•'Çgú-6Ú7lØPm¨ˆ¶¶6:vìÈÙçTVVFïÞ½9uÿþýuýö®8­ŸË÷ÿkcÀ€ú/®“£úv\?÷æÍ¦ÿݶm[µå¯_¿Ž5kÖ 66–N^„swïÞŹsçàçç‡V­ZQ@¤ÌÄÄzzz´}Mô—/_âêÕ«pssƒ››nÞ¼Yé»Ó"‘;v쀹¹9ÜÜ܆¬¬¬˜%K–`õêÕ•®åš±XÌz²/”––"11±Ò2 ,€-©&%ŽŽŽHKK«r²·¥K—Âß߬¶9kÖ,üïÿ«r›ëׯ§Éþ¤àÊ•+ÈÈÈ`ú­_ýµÒùùùX»v-ºwïggg„‡‡³ž=ø4G— ²ŠŠ Ìi¼‡Þ¨ëwî5¼^}?¸žˆ’íñZºti£îÇx<ÌÍÍë徯Y³†é[´hˆˆˆJËÆÄÄàÁƒpssÃùóç™9Y;777´oßÉÉÉèØ±#HA‘ÀÀ@ðx¼*Û,‘Îy)55?~¤`°IÐuttàææXYYáÇÐÓӫ𠃞={2å¯_¿Þàcnnmmm<|ø°Âä|ÿþý5žÐcÞ¼yØ»wo…ï.¿O~fÆj055¥V)E!!!ˆŠŠªp"À»wïÂÌÌ †††¬·§¥¥???lß¾½Â™âaiiY£mv¬¬¬Ð£G888@UUúúú•Á}þü9”••Ѷm[¸¸¸ ''ÿþû¯Ôö­[·nt£pŠÍùIEEÞÞÞœîgC<çÙØØ K—.¬Êš˜˜`Ò¤IõòszxxÀÁÁxôè:tèPiÙM›6ÁÏÏ ÄŠ+èKŠOËmæååÁÓÓÐÒÒ¢ È€¡¡!nݺ…K—.Q0d|^Ú³gºwïNÁ¨†rY’áèèˆäädDEEañâŵ~×L$Á××÷??øðáÖ{”w>>>X¿~=455ѲeKæç?ýô"##k¼¯’’æÍ›‡Máa(m7ÆMÿoMãó{Vàû‘Ô"¥LMM ?üð¦L™RnHÞíÛ·qûömÔx›hÓ¦ þþûïrw¿oݺ;;;øûûSॠì„ÇãìÙ³˜7o^­û­ÔÔÔ gýûï¿™‹NGGG…Âj·¥¨¨ˆ‰'²…!WZ,,,`aaÁÙ±Ñ××çt555´mÛ–³ú•”á¼…UßѺukî.”•Y'’ò€íweèС¬·Ù±cÇ*ËϱÆ |zÇÕØØ¸Á÷ÁeÙk×®EÿþýË]'ÕTxxø&KËÉÉi4糘˜Z%@ÆÌÌÌУG „ŒµlÙvvvhÞ¼9£ºø4kõž={0mÚ´:M£¨¨ˆ¨¨¨ÿü|Íš5œ.=TÛÏâááÇÃÞÞŠŠŠ8pà†^ë)**¢uçøçâqYÚAAQ·/ì…sï‘P Iádv\ÝÝÝqòäIxxx 11üñ‚ƒƒk|Ó¥Œ——Ž9‚S§NÁÝÝEEE8pà–,YRëm’ê½~ý§OŸ†¿¿ú-“ û-???frG¶ýÊÊʬײõõõe=¼uРAÐÔÔdU¶_¿~prrbÕnŸ={&ñãbmm^½zU[®GRY[ZWW^^^Õ–3mÖ-;~-•¶É¦?744Ä7ß|ÃéwHSS“õúâlWñòòbltíÚ•õwwòäÉìb_ƒ>WAAuyš¸µ¼ÂÂBlß¾½ÎÉ9Pñdyñññ8tèPƒcHH§+4V3fÌ€X,Æ«W¯(2¢¤¤„"66ß}÷¤ªó ¤§§#<<Ó§O¯ð©Ï/¿ü‚èèhæâÓÀÀ)))> mÈwAlll––†ÌÌLäçç#..ŽÕ…o•e-‘Š‚ü~ÌÃÛ¤g°háD­Q† „cÇŽ.\¸€ž={Öy„GY’;vìÀˆ#¤6C0ž>}Š}ûö!88¸Â8¯^½šyEÅØØ(**Bnn.Š‹‹¡««Ëùg°¶¶f™™™ACCƒUÙ•+W²*gnnŽ7²*ëàà[[[‰~~ƒJ_§’¡š4õLÜw£oß¾¬ûž±cDzž ©&íŠí ½\·R{Û·oG§N*LÎoܸM›61ÿîÓ§þøãÀ±cÇàééIüÿììì€óyFCCC̘1 .¤`Ȉ¶¶6ôõõOÁ¨†2 66¶ÜDV¡¡¡033c.„Ë."UTTŒåË—#55?þøcƒÊõÃ?0'š9sæ°~ŠU·‰‹ðç‘MPPP@ïs PÓ¤Ö(cË—/ÇèѣѼysøùùId›Ë–-ÃØ±cacc ²eggãþýûðñña~¶uëVæF˃˜§³FFF˜={6fΜ >ŸÐÐP‰|ãE$?ÿü³ÄËjkkכɴL­ØÏÂ*™VQQÁòåËYm“ÍèBêêéÓ§ˆ‰‰aþíééÉŒy÷î]¹ÙÚ‡ŽƒÂÇÇ^^^pww§þ&&&†‡‡C†zöìI“òq iÓ¦¬_+jÌÄb±X• q¿víZ½ TÙ„Re7-êâñ ¯ÈzŸ Ehéš$ÇJЧ®2#‰pèÐ!ôéÓGbOSKKKqøðaôíÛ:::äz®lˆûÎ;)õÈ­[·ÊÝ {÷x•QqÙWq·Ðľú›iEyHO} «–uÞ¿¦º€-KH•âããaccƒ””˜˜˜4èÏ‹¦M›Ò¨;ŽÏ„È e ;’HÌ¿¤m`N墢¢Ä—nRRRâ|9(B»š\p±I΀'P“HrN!_ªë;üDúç Bdš£P!„B!„JÐ !„B!„B :!„B!„B :!„B!„B(A'„B!„B(A'„B!„B%è„B!„B%è„B!„B¡B!„B¡B!„B!” B!„B!” B!„B!„tB!„B!„tB!„B!„P‚N!„B!„P‚N!„B!„JÐ !„B!„JÐ !„B!„‚²,+ËÌÌÄ™3g}Ð_gÅÿýy¼ %¤FI¸áêê === Äþý÷_ê·ê¹¬À»\ùÙêëÉ—ôõõáââB¨À¥K— ««K „48vvv°²²â6AOJJˆ#ä&(ÅÅÅPRR‚¢¢| $(((€@  }ª†X,FQQø|¾\í—<¶«ââb(**BII©Ò2'OžD÷îÝ©·üŒ@ ÀÍ›7Yõ[EEEPQQ‚‚B­ë‰D(--…ŠŠJ­·QXXW§ý(--…X,†²²2§}FIIɧ•쇂‚B•ßYì‡$úIìGQQ”••åb?êú+--…H$ªÓwNzõê…cÇŽQ§ûEEEhhhÀßß_bíG$ÎèýïIDAT¡¤¤<O¦ý@]úåº|Wjû·u½¾âbŸëÚ.j{îes}UU»¨O1‹Å(..®Õ÷‡ËvQÛ8×åüÀö|½|ùrTl™X½zµøñãÇby²qãFñ;wÄòfÒ¤I´O,¤¥¥‰ƒƒƒån¿ä±]EEE‰¯^½*&Ò³dÉñË—/ë´7nˆ#""ê´àà`qZZZ¶qñâEñîݻ봩S§Š ë´cÇŽ‰;Æyßµ{÷nñÅ‹9߈ˆñ78ßIœÏ%± .'%%Õi×®]GFFRVÏÔ¶ý<}úT¼|ùòZýíÁƒÅgΜ©Õß~ÿý÷â””™Wjû·u½¾âbŸKJJľ¾¾µúÛ;wîˆ7nÜ(óë«ÀÀ@qNNN½‰ñË—/ÅK–,©Wí"33S<{öìZýíåË—Å;wî¬Õß®_¿^|ïÞ½Z^zB!„B‘ÊB©;777¹xOrðàÁPSS«Ó6Z´hssó:mcäÈ‘umÚ´©s¶:uªu?4lذZÛæ"ƺººpss«WíB(bÈ!2oS=zô€©©)%è„Â¥öíÛËÅ~tîܹÎÛ¨kr@"óT4qJMõêÕ«ÎÛhÑ¢…\ìGË–-åb?$AûáêêZçmÃØØ˜:°z¦¶íG[[NNNµúÛfÍšÕz;tèÀÉw¥¶+êt.ábŸëÂÀÀ Ö7?ííík]ïW_}U¯b¬¡¡Q§k.ö™Ïç£K—.2oSu}À ³!îœOÂò%uuu¹Û'ÐÑÑ¡}bÓxëüô¤±´+555¹›LT|"QWW§@¹&çsB‘ÇkUR¿¯Éê:z®¶Äb±˜!„B!„Â-‰qÏÊÊÂÆ‘˜˜ˆÁƒcàÀ•–ýøñ#"""‹îÝ»cܸqt4©ƒ> ""Ož<††ÂÂÂ*-[RR‚­[·"&&...ðóó“»å²ÔÔT,Z´‘‘‘Õ–=tèΜ9ƒ-Z`Ú´iÐÐР™xôèvïÞ+VTYîÏ?ÿÄÎ;?]T(+#((H"¯B!Ò xxxTY.%%ëׯGZZ¦N œ={ÿûßÿ˜2iii8~ü¸|&è7nĨQ£`mm#GŽàÔ©Spww¯°lDDúõë‡9sæàòåËØµkÆŽK­EŠJJJPZZ PRR*·¶pIIIÖþRii)(é“¡ˆˆxxx`îܹՖݺu+:uê„€€Ü¼y‘‘‘˜:u*QFßÃM›6!55µÚ²ÇŽÇCTTâââ°uëVS%¬´´”Ys]QQ±ÜðmI÷b±"‘¨ÎèI[ll,NŸ>ŒŒŒjËîܹQQQ€ÜÜ\,X°ëׯ§†E‘ª²õÚË|þ*ŸH$bútIž¿%y> ܵ›#GŽ ..šššU–‰Dظq#‚‚‚`hhˆððp(++cÀ€0`àêÕ«xñâ…D÷Q¢ÙSbb"¬­­|š4!..®Ê“«V­ÎÎθ}û6µ)ÊÌÌDhh(fÍš…Y³f!44™™™Ìï§L™"Ñúvî܉k×®QàeèÉ“'ÈÈÈÀ–-[˜§Y•‰‰‰a&ÊquuÅ­[·(€2²oß>,[¶ †††Õ–4hbcc±eË>|ǧJÁÊ•+™¾qÁ‚HLLd~7cÆŒr€uuýúuìØ±Cîcƒ   ÿÝåË—©ABdâĉLß={öl\¹r…ùÝÉ“'qòäI‰Ö'ékeÂŒŒ …BV3Ò+**ÂÍÍ »ví–-[ Ю]»reþþûï:MøWº Ôˆtkkk„††¢´´«W¯Fff&3¡†™™Y¹òéééÌ>---XXXTºíÿý%%%ÈÍÍ…ªª*s“¦¨¨=XZZBSS?~D||<@EE¶¶¶€¤¤$dggLLL §§‡’’†Êt._4h ¡PˆÂÂBf)„;vÀÙÙ——‡  ;;›ùB””” mÛ¶hÒ¤ :ÄÌ”˜••…ùóçc÷îÝÈÉÉaêyüø1=A¬‚¹¹9&OžÌœ\ØtÆÄÄ W¯^x÷îx<æÍ›‡uëÖÁÖÖ/_¾¤÷Ï¥èôéÓ(,,ÄàÁƒ«,———‡¶mÛø´¤bUkqëëëãÛo¿ŸÏGzz:V¬X///xxx 00°`Áäåå•ëOC7¿þúk`~nff333„……¡]»vPSSìß¿_â ú¹sç››‹ÄÄD9r­[·fž|y>ÏËËùsç€Îç„™zòä Ξ=[íù1==–––̈¨=zTY> €õTv [Ñõ®««+Œ™·e‰\nn.|mÕ­[7\½zéééÌv/^¼ˆ¢¢"JÐe,??gÏžÅýû÷‘›› ‡^½z1&‡ GGG,X°JJJðòòBTTttt’’¼êpëÖ-899IeN‰¾ƒîèèˆîÝ»ƒÏçÃ××·\ƒsww/wg«I“&ðôôŸÏÇäÉ“™¡#D:JJJð믿V›œ—u$ÞÞÞàóùàóù¸}û6>|XiùÒÒRæ.áç*:¦6l`¶[PPÀtx;vd~¾gÏ@AAù™P(ÄôéÓé@VaúôéL¼ 0fÌæwÝ»wÇš5k˜ëééaôèÑàóù˜0aÍ .CÊÊÊàóù˜3gø|~¹ ɬ­­±gÏfØ@ `úÒ~ýú•"M$›œüø^^^决WdüøñÌ÷,55•IL+"‹+&^Q߸~ýzf»EEE‹ÅÐÑÑÁ Aƒ˜Ÿ_¹r…2Yö3>ŸY³fI<&<B¡³fÍŸÏ/wòåùüó¾šÎç„YIJJ‰'àççWeÙ1cÆ@ 0}ÕöíÛ«½nþ’ŠŠJ¹s6\¸pÏŸ?gržââbÀ¸q㘺rrrpôèQfe?÷÷÷§þ’eç,WWWôîÝ|>¿Ü¹?$$Æ cþ=`ÀØÙÙÏçÃÏÏi666¬Þc¯Õµ¢¤7ضm[æéÂç>b]ÆÖÖ¶ÒaÓD²ž?Žƒ¢[·nøóÏ?¾¾¾¾ûRTT„C‡1Fqq1ÔÕÕ+Ýö‹/°zõj(++£´´ýû÷ǃ*,«««Ë$û)))Ð××Ç«W¯ðÇ0 žÇãAQQýúõcÊ***Vº"ùDCC£ÒYXXüg+++æ=[";•õ‘ ­­ýŸc¨¯¯Om_Ê-Z„!C†0O~½¼¼*]&ìÈ‘#Ì…[iii•ïedd`õêÕàóù‹ÅÌë?155eú»?B,#77ÇŽƒ@ `úfUUUôîÝ<`.(üüü$“/‡‡Vu>WUU¥6J‘¹àà`´k×6lðéAaÙÌÚ_ºpáž={ÆüÛÄĤÊmoÛ¶™óÃÑѱÒr:::¸yó&ÒÒÒPRR¼¾tüøqäååø4 ´C‡°´´„ºº:Ó×÷éÓ‡f…ç€P(¬òœUÑȸŠ^/ÔÑÑaæò’øM±X,¦CÕð1•iÚ´i¥w³²²˜‰‰444ªìÈ|||м¼<…BXXX ''***L’ÿöí[¡  ¯_¿£¸¸zzzHMMEnn.ÀÐÐÚÚÚ())ABB§†ª  ñ !@¹‹¶²d¹²›’ùùùHNNPþ•ÊúÆ•+W"##JJJhÖ¬ PXXȼWž––mmm(**2Ë´¢°°FFFHOOGzz:s§löÿøøxæé|U}9!„4Tet•ÑÒÒ‚‘‘Q¥åŸ?޲´ÇÚÚºÒä844Æ cFYZZB 0ײÀ§©ÅÅÅÐÔÔDRR>~ü555(++ÿçzWEE…y RÑõ.!” ‰óññaÖÀ%„B}#!„ÔW¡¡¡?~|•7` ‘¦ÿ7òX@µ®auIEND®B`‚snd-16.1/pix/fmradio.png0000644000076400007640000130631211147553267013303 0ustar bilbil‰PNG  IHDR"ÌÇæ pHYsÂÂnÐu>tIME×¹Á~X IDATxÚ,ÚÙ²mYb˜åÑÎ1û¹Ö\ýîÎÞ§?'³²2«W•„ÂB²HÆ—!P¯Á-ààˆ Æ Ë’\–T*W“UªÌÊæäiw¿W¿æš}3Z.Ìü—ßÍ?ûì§I²Úç%ÆÎì`2ßn’ýꃯ?(ZSd ›Â£éw—ë_ûa %N7p_ ó&/ýþäý÷Ww·È7?± ùìü‹§Ÿx®Iv{©Ú{‡ó¤-ÄÖóƒÝ]6š‘ÝV Èšýƒ{ÇûM“5ûét¤w×ÞÅ‘ØûúƅÞ0K‹ :®´Im{ض^¦®wH\¼/¶ë!äq• E©e«®qCovëÀë¹®]Ö9F–ÅÒ ®"[¨« "JJÆ.ÎÓ Q ®f–ã„C¡”Œœ!²(7ƒðD@žçKßëAlµuF(µY˜íʸZ–—å³=Ùt Çõ÷Ùž9ȲÑq $³}(d­×S@›®D;žS5; ù˜ZUY!Ëf–«D…€¶}¿©+%„íÙÙ]] lˆx[»^‘©E¡dÔ_§<²¹Eé¾ÜѸ©÷ÚÏ‹”ÐhÊÑ€sM%u‡DPqÑB"(tš®‚D[°g7ÚLŒ’Ð(lYÚ©„LiÅi 4Ðb!¤†€lŒ‘JSŒ Ú©2F*i‚€âB"H,Œ„‘œB 12Z"!‚ c F#%¤4°4 ad!ʹ@QD”‘jD¨”I0„Æ2ƨ‘VÀ@ˆÑ ‰01m A`0(ÑF!ˆ @Hkm´!HkE2 !µ”ec4DHI •"ÔÒP !)±´ÖÆhb1­”R ÖJB¥ €ýÿ1ƒˆäc,•BPC@´Tˆ€°VJ ”4Àư1USZ–ÑZ`ÚÉ)Æ®”†`ª”ÔFSli$hµP V@Æ­ FK„ @ ˆÄ£!ÁÎ%„c*%'H­…„¡1AˆÔÚh¥!&Ú(BDó 2c€£•Ö†ZnS7B°4À@€ÔÚ 0!­PÈ˲”Ìò•äÐB‰AˆëÀXhc€B€(Ô@ª¡q D@ k£•V@(0”š ¶¹’" 10Ji­†Ð )!@B €Áh) @Øêi© DÁ+ˆ „–R Cƒ†)­Zk@$º†96AXÈá¼&µIÈ;ÍÂ4¢ÕFÀŒ–È’Ú@c$†B€€ÀÑK(Â`¥„V*ƒmŒ‚Ê@€4@4!€ ZAˆ(ÁZi!B°• !Œ4e– aD,¨€€€¥!±¤)¶ b’s‚‚FéÖF0Ñ¢¤$€H¡ )¦†Hje€$€jƒ•2 Ò ƒ‘²0P+Ð`!ŒðÏþòÿx÷úÒ¢£Ðw-*’¤Ž|§Ñu^K Åh{vo»¹e” `o¶·ÿäÿ§á w{·xvtö~÷ûÃÙG-£ñjsÓ¶å£ûï½¹x=è,pF“>¯A^´y½~öà;]SÜ®_ÏÆgI=x}׎¶ùúÞìèåg_yQÿèl¼^¤ë}úàÞ°Ý^ú]ÓȃùåöêzñÞ7Ÿdyrs»öÞI—qÉrkb9àÀ÷’͆Ü‹šd›ÆQ_H)ÄFm1¬3׋Û6õ㢕¿þäãzSÝ$éǯ¿üƒßú­ßû¿×š².ZbÂp÷YæÐIÙ\`Lâ÷Þ-?빡‹CêJ›…¼is^„AˆM‹$òû㆗¼kãÁ¬)ÛÅyVtRû¾ mª aåQS€Â²L{Á´ë-dF€A¤82vÙVM·=>¼¿ßïªF ‡Ã¶. Þ^}qsµË‘çýè_}üŸþãÏë‹Ï?}8£g<º>ãXýÁìÀbárßÌ-„“¦+à >¿}1œPŒŠ&uÜ`¸Z½õGñÑryë…¾í„mÕÔ0'¼›ß8ÌŽ¯o®ãá4rÂN4‚—˜ÚFct[æÃáH(ιš[kc Ñabi)\Ç2˜¦»ÌB(ô³&e˜QËÞ¬®¢^Ÿ§.ËÀ em׃þ„8Nž,¦·H¸RwŽç%dà®nµQägû$˜0„¶!Ù$óã3цg(HÎÛÐ ÒdWW»Ÿí¶©P­E@ãÅòfØëcjµ¼°í~UÕÛ¶ZΓõòÞÉI£q[VÂnÐS¦1‚×mç»>cÞb}ëÚhÛf¾%¶Q’dG‡'JÊWo¿œÞcÄÊÖÛòÜ^¿Ì÷^às¡n¯®Þ ^ÞÝÙ{Ãõõ6ô4•6YFQ‹©‡,š§I•çƒA¤Œþòí~Ï÷ü¢¬·ÛÕƒÇO ¤Uºõ=o¾ÝNŽ›¦Ü,—ŠÊ÷Ÿg~õFr19œ•UÉ0Y¶Ïyë2oŸîœÀȉ®ªÛŠ9Œ£%ÖÊ ÃÁdw}AœR" èêÊu˜èf¹aoxsuéúÑ`vp·ºÞÍ—ï?}¯¨Š¦*ÏAM ¥xÓ¶<}üüÝË.³©ã£šïé¾ÌºEľ)n|7ôm%Q³Zl¾~úõBµ7‹•ªG§ßœìö˶+˕ڵ ÉW'Ãhµ^l<߯4 ÒGÏ>ÿø:K»ï}ðÍ««/ýaõOšÝmM¼Ã“Ùü‹O£éÁéû¿ù³þs›yOÞ¯ö·ó}zïÞóíò‹(|°éhÛ,xΩc¯¯ß<>{ò­ï¿G=¹›¯J>üÞf›v¢qƒiÊ•À]²ü 0u^Òëíælâ2;Àÿðßý£~Ü÷]O4œXtv0EÓ0 ÃaÆûM⹑‚Ú‚ä¯úÓžúÔEŠö'æ»~ïÞñã4M;ilǾwvøæË«8˜!,?üÆþNqUMÆ÷&ñƒ²J”ÑNÞ¯kޱ9ìõS ÓùÍí“Ç_zýwo_…ÑàðäBÜÔu?ê7- gJÂùÍU<>І³|›Pè§³*Ém'BZv-êù±¨y¾Í¯GŒßV($ ¼x·Ù14ðœ>&´Ú@Ûµ…¨ûöD(‘¤"¬t»‚ÿÃÿà?2FØØgÔ—:ö[ovw6MÆg›ÍÕ½á}7êsÎMçu@*azî‘ kÊ¡7ã­€èŠv­r˜k­²Ò±#†UÑ@©¤~ØïêΦ^™fÓÙ)/µíìà¬+¸¨ …€S-å¸rñúºkÅ œí6¥ÄwÜnmÝ^_wüòÏ?ñ˜yïýoó<Íß{úÕu.éG}Qp¬†×„3Ï ó"oöõ(žî×{ (ç6 agª]”ŇY–Ë–×i.+Ó Ü–“žãy•YÀ—¼­Û¼-Z.Q•WFã,Ù›ŽËŽl;J°hÑfÏ•âPÐ|ŸßݯÊÍò¶ß`Àò}Uç‚t·ÚE¾/¼šo|¿_¤íÕë—~èjIW·Œyûù^ÖHKžîÒ²l(‚Ŧ™/ŽÅê¬Þ§‰ÜÂ./`º¦,;RZ/¶YÙ8Œ©F”i#¤BÍ&÷în ­"Íê"çTh Ú-nç®í¨NEQ§™ãŒÚ®®òu¤¥V0Ýä¼-?-ß]Ga›T]Ç!$7× .丰¼YýúÓ¿ûƇ߮Võf¾£Ì’ty $HÖûÅÍÝó÷?¸»¼ËÒÌö#QZ7o¯¢þ¨L*q[·7¯^q¯m»ýj]—õ`0ã¥D¥ÛíÌ}F0M"ƒA<Ñ´¾øõµM]¡DÜ?Ý-Ó¦Ú3 ƒáv»È7í`<Úl×{w‹b;] ›¦Þl·@ÑŽ«2/(‹ú›ëEU¶FZ æ×s œ,ËBÏ«÷mÕuAØ“ þìÓOÎ>‚Ⱦ½zaÔ·'«õ]šíB‹»ÛÁè`³Ü­(³h¶Ïo¡"iZòºÝ,מísÞäi±ïúqœmŠ,Ûwª«Ò.²Ãªl겋ûÈŸÿåŽkÎ}ä›(é8îÀ^_Ìÿêoÿ: ê‹¿Z^f¡ç1‹ÔySìº7¿z;íßS%ZÌïŒ6m)¨$ëu±/š’aÿæüânq׋¦UUÝÞ.}ÒCš®—7ƒhúÙÇ/ê²8œ<\/wïÞ~ùèÉÕ¦ûìï>LŽV·7ˆ²í&Û]¶É®98~pñÕ|·ÜÇ£i’Z$¤2ü_þ×ÿ1ÐÑßüù_ó»Ï)í¿:/Ó¼ãª,š²jª¢^Î/ŽNŸ~õÅAÁ ªšõí¨„¥2#!|óöõ±}´»Í®_/^ýz®S{³ªnî²×Ÿ½q@ä°ƒËë¹…œí]vùöâoÿæ/t#ëT[Öå«W¿ü»_=}tb·æÍW7]–õ úêíçƒ~ÿúó·EµŽX°ýêüÅ«¯úQ\^uÿóÿô?`«„…LÖù¾<—­u÷ú«ƒÁÁîÝâ‹ÿ6¹}õ¯þâ¯þÅ_üÙù›·÷''žåÞݬ’›vzpTÛí¶jÚBÝ6j›dUQ#Äl:øÕO^B…ûá´XÕ›Íÿwÿí“§eSçQ¿o¹LµÝmÃÈ7X”¬—×ãÉHK! ®»®ç8m«‹¢¸™/b÷è÷þþ~òËŸlch<×{÷ÕuÕåvÏãÓª,+±?œ.‹ ãÙvÛ iø`2–œ ŠyLJSÞvmÕ…=×¢VUHjŠq[ /ÖZCÇu amYj[A#Db]#%¥Ä÷=‹:¼k/ÒRbŒ\7”]‹pÝÐ(щºß?îºVI±…á²qp º"³m¶CÅÑC§ió¸?-öMÐw1aé:™Qeeû 3Ú‡¼«mß—­±Ï¤9æ]á†6Áp¹J‚€ù6ã­¦smÛhô£ýz!u|W SæWUઃ˜Â¢¬'Ãe:^wZ€°ÚØÉö{bû¢„ZUQ9Ìa¶×µ-¯*j@—9ØXÉvùàÑc%Ñn¿Rß;}ºÛ/1¥ÐcÚ8šÜÝÍÖåôÂÁfw„¡ÇBƒ8ÐÒpÒô0DÙ¾jÚâù“v‹šÙ4 zѦiš¦í †Žå¼øüW~Üg–m$Ø-—§+iü¾¯ZžlîŽOB]Ñ"f ¦Ç²®€m#†Ã-uUVbFl‹±2Ë)c„`×ñvËÔ%Ìóú”°†Š×õkYYˆí“e<ž†n¿(“ºªÎΞ6mY¤É ?‘2Æo•‚ª“£ÇÛ›9ñ­8žI)µÚ¦rh †äÛêô郦®ëªöüÞ(žµMK˜e{ŒP2œÝž¿Á؉£²í~õw¿è‡l:;óý¾ oš( lVËÝzõ›ßû­þå_Ìï¶¿ùƒïß?}äû~Ã;Ñh!äñƒ{wç·ãé±eÛ6öë²ÕÅáØv‚².ß™ ïueE,«ÎKß lßR]__œ>< ¼áÝÍ;?Œ"od1RWå0ž -ƒÙz¹¢¡=Ž „Éj‰‘އþ|qDÑ~»>}ôÀ4üêÅ]|0øö7¾ýjî,ò]½ÑñáÝ»+L]‡¹Óá½W_¼Ïg³g»å’R1ô½Iecg¿Þêù«Oßö^¯çI¶Û¦ï?{&Uƒ F¬«£§ªz×4i[‹iл»{Í ÜˆzÖÍ&»¹|i¹N¯?‰ÞŸþôþýoQWCXëF)ª Š4Ê“5âúé{ß½»¾‚¹Ñl6XÍçy+·»µâšwüùóû¿ñýßvm›Úó}€ Æ´Ž®¯ÏYh‡'»u¢ ðG”\ãFn’Þž>Âðû¿ßÉ#Ú‰–×e/ìWUÛ ia 12¬nׄ¢ AàþŸÿ쟎â~™‰Å<õ<òÿ÷7¶í"Ä lž?¹ÿɯ궺ÿ`:8ùê˯zý*ƒ=[H™®sj¡þ¤—¥ùõÅ›ÇOžgû¢äEÕXÚ€(dã®âm×A¼X¬¥–®7«­C­<Í ±,âž¿üÊfРiEÙ4CưìjÇ€Jt­PMWtÊ@Ì´ïøUÉ5h4ZƒínÇÓùùün1gžs~}ó­ïüæÙÙýl_TM~x|Ò5¢,ŠÁhj Ñ Ri’®Ue¥tî:¡¬;.[׎D€ É>I¢þÀ\¦±Œãº€b#-#ñ`<,óÌ¢ñíÀöª4ÓÔx–5µ]+ÏŒ,L"$KÒ8ŽŒ‚D DÀqâÝz»¹ÛHކ£‰bµ¾¹wü°éäzuÇ3j9u“:Žëz¥HT—•Å#PÛµ—7çÇGgÝËŠ}FŽãS‚!0œ«²Î¢¨ß–•6Êõý®©5V)L©ŠRV6%ó}‚@×¶\I˱FÑ@Ë®kµŒlºN:®k(–{â2¥”Èñà¾ÚtHÄyÛ” *‰”)E§œx“î´T hÛfuS溮ƒ1–­HiÅæ§É†‹"ŽÇªíÆÇ ´î „ù~Å}—Åy¶‚TÀ°åçy ìšÖwCÉÅv¿MÇ–ãnV90Œâ,-Â0Èëœ"äc^5užƒažo56µ˜m‰¶S‚SBûA´^Ý QEÑiƒ ¼óƒ˜+Â,+Ù,Ã#ËFé>¡3y~/ÝåÚpÉÕpt´ß.!"¨°ßkó¢iØ‹™Å:Ý®—ó£ã'U•í’0j0:Èò­ÅXQÕ–ëÂéçŸüÜv]ßñ]í× 'ˆ²]ÄoºÅåeØlÛ«Û¦i³Ùì,K¶˜YR¶Ú𠊵êÊ,³{<Ý^½u˜ FVy dެ)Ú«ë«Ã“I—¢BgsÛBø¡Ÿf)µ¬¨7y©UGñž¥"Ñ´ƒþ¸ÕÂtm¯?’FóºBР†6CûÝ]<bH›ºÚ%ÛÓ{šº,ëJhˆ©Çã¯>ÿ¼ïÆ££“ûŸ¿ü<ðœÀ´Bù z³\|ðìîúúôá½,k®®îö»»§ÏŸˆ äm“[ÔîO†ëù5!ÔrYàG]×vm„ô]¯ãùëw¿þè£Ô]ÝòVJá0£:g0§Ù‚’0ˆGi¶æB‹Æ¡uw³D ÕŒâ㪪º¦<˜Mg³M‘y!;<{ööü×·¯¦Ñ‘ÍÑ씼š_>ú!Ť.Ö£é1O//Ïm`FŽï¿}ó•ïxA04¢9”Y¼ ^ž¿|üèq“•—×ËЃ³ƒ™OC¨@QULJ¿øÅ۬ĔÁàêí¥ßs}·‡©kÅýÛ·çOÚ¶µÞì’íöù“ÇX!¡D²ÝA`¦G'i^h €ÇǾ٭Ã(„îøè¨é`³OšŽgišfyȼð;Hˆ¤ÌjË4ð½Àé!¤’íz<;D”ܼy1š0ÏáuÞ…¶ oê³ÓoÏß" Èn·TZ@¢(ªò¼.Ê8Ž!ƲUëÕ¦7˜aÈš¢}ýåçßüè{ —%C†eõ°tªªÀL§~þ“_y¡w8=Dˆ\Þ]A`;ãùº1—ï.ŽÎ1&›Å\¨òÑ“æó[bS­N€ÓgëM~»¸³=»ïÞ½~Éñ¨ß5]úud½ñ¨IÔâjþüvàOóFÓÀ†cÀ™]-„Bþ8Ê“=ï8q°oGMÞ ƒÐî[È­yõ|×0&Phßñã¸7‹ž££†wG³#‚Ôbù%`6=bo´ôýˆËÒw}ÝBiˆeÝÚs)#¾µE¤¨ÛŽçim*ÝÅñ¤njçFÔr)cBòªÌf‘/n/G³žØ]QqÑeaA¥ÀèÍbÓ›` U'ÕÓéLqh€b«×ïåEލ3ºæNÛtãö<-e䌳:£XN?`®Í\‹`‡ØXa)‘ÉÓ´M\Û“¤2L÷Âv@Q&¡,ˆMšF¶¦ v¿Ôb”£ª®0!eÞµRA¢y ò2õ{^W\Ö¶çêîß~ ÚT`à‡q±Ý²`.ã¼µ,„¯jÛ¶&³éj¾±”§I ´m× ¡±± é †BTJ{ª iNµ%Q@É O,‡w5ÔFi¶éD)¸ðdz™ÐRI÷;.–»·nu­t<·)j íùŒ¸UQQJÎî=o«éYŽï‡s×õ·ÉƱYè¯//#Qȶkº’Y¶È‹£,O¥’Ó£)¡n’•^õÇmÝPÛ:õ%±@[²*Šývr|#¸^/âáPIN]š!9Ø‚l¿E¶q $ò6oöýhܪn·_ûbvt¿ã…ì4%e!L­4Í‹r;˜xAüë/y|òÔ¢bÕÔ´°’r„eÙ&ÛÍÓg*©;ÝCz~$E!ªó”24íŸÝ^^ ©?É IDAT(Í{ñXizsû:Ž´AäJ ³}…1êòü¢Ho¿öÞãj_ F£¼ÎDCÂpX5»åüA2=8¼¹¼¦Z2'Øo®è”NèU¾_¥ƒq¬@Ý”\ð:ì…$mS¦›ëÉè iò4YQâ Ç¥xs!e°a8úôÓO$TAúAÿêæ< #`^fJËóù‹'?˜¹‘IöótWž=z\W¥h϶£a4LÞ½y›no‹dm9ÑzuÇŽFrÞ4»j¿óGÔe·×·‹Åâ[ßýΫ—/ÚF¶²ŒýÝvm[ÁpÜ{ùùQ4ö#ß"°j:?,ÂÂ0V’g«Åw¿ñýÀ!´5ñ¨7žõÊõþxzê¡è½ÞNíþ›?ï…ñÁý“¼É”êÂ~œîwÓÙéÛ7_QñI¾/__¼ì&á`¨@×…ï.Σ±å¸áµ®Ÿó[6ËåÝ ?†Ìz%¯š¶…ÄÃÁ/þs€ådxRh©‰ôÂa e²]¼øåÏÞ{ïÙòîf¹LÒbç+ãþÛÕ»¢Ë‹FùÁèÓOþŽ9›®g5YæãJ‘æõöòÕ§?ûq4<Ê’¹l[€±Âz¾_ êfö•±«r… ‚R5ÌùÙñ +[aÞ5ÐÖ1ëGÁðúüÒ·<ü_ÿWÿùùÛ‹h<ö\——#s8;Ü%i§ó¦ÞOO”DMÉF»w¼]ÜB‚Ï‹ü°ÌŠ’§Ä†ºÌf×ç_úî¨ßë#ؼ{ùîù{O[ÞÈNC`:^ôƒa£»VuÛí³2ŠR‹`ÙíV„Ð ›d>žð®Åj¥…hƒÀ¤Ì·žïf÷w«9²0ÔéUWs–›åìÞÁ(ÿâ?{ôü¥®V‘,øWíÛá`ºš/öIúèñó¦ÎЬ2XNƇëdƒ@úq_t¢©2Ì`8Îò²‘ÚÞÖ€Zu:AØo‹››Õ“÷?ÔFÖEíBto8JVYz·«ùɃ'W_¼\\ÏÃpú[¿ùƒº.ó<ü¨®rϵ—×÷>ÅSc¡ÆfDhÄ,ZwâÅÁìqZ”ªí(qfGó»«Ùäj@„ˆ]^^Ç'§g@«urýàÁS  çM[ØŠ‚(\t¥JËÝ“'O–«¥&«’£ƒ‡ûb+•`³ûV²I>ûìíÉìá ömâ4²v"_T*šºoß~ö&ÓGgï¾üÂó.†Q/Û• i“õÕÉñ{i™¬V7ÃxZ×üòÍ‹§ï?jDE”{{w{p0dÈ7@§I²^­ú³°ÌrYó»ÍùG}çòõµÝlp4êMon.'SiT"ÖÇO.ß¼±ûØs¬Qo¸Û.ž¿÷¸«E‚ûòÕ»³£ƒFñýjÇlòðéÓ?ýÿ…²å¼¬Z¥á׎ãA‘•ÛÝüÁ£34@´PµãÚºÚ‚Y¶­ðC?Ë % ´AÐùŹ ò}.…°½ ìO$.¿¼øêŸüoÿ×­“¶JwËÞ´ßÚ¦ÞÅ·ÞûHw* «Ëìùóçз_]L§³Ùíù9BThq0>¬óÊhÍ;qïÞ‰à¹Rªß÷±%t×Õ< ‡¾ïû”Àõöòäø cÔð @Ò4™’-D¤\ƒöôþóªJ”é¢xÒumV¦fMW9.ŒÜ~Ó‰ƒãÃa8išB™zÜ›yn;V`û\p? e« PÇNl঻m³®ê(µœËÁ8üú·¾¶O²´Ù?xÿÌ‚TH(°œÐ"t{qya{ýpoowŽùA9FÀÒTuµp<·á5¯;B‚rÐ6ãº@%:!«¸?æ]Ç»–R›yŽÔ¦-$oZ%sßÔm-4™ÚžÛð"ˆ£ ­Ïz‹›…xõ«¼¢ 0Ç^Ï7ƒ(ˆ,Dž<{B Ù.÷þ0ð}ÿÍ‹OG#ßõý¶m “y–Ty7 4y‘„ã Lò®Ñ€’²5zµÈæóÄtt8­re41ìbM”iDWcËUç鯦>ÆPw(c{¶c¹”Ð}²tˆÅ˜³Y-e-4DÝèÝ6Ïóõlzº+š²XEƒ1¶£$Y(%Ã~O*†“ª,릌œ0®Úd0ãûDÎf™C‚Œ@±èn·‚6æu§9´ Ä —å>éM& Q”ßcµÔ­ìöi’+«4zýê3)‚Á ©Þ¥ÂhßI’Ýz<~ îÊjÙnUdXÑ¢ØR‹Q¿áEÛ6ƒÁ˜ÙÖf½"®•Ô«ÀwEÇkžA섽ñùõ»4ÛÍNžîÒÜ±í»› zÛy‹Å‚Ùìþýç×7o¥mÝG£l»ÓJ'G›ë¹ÔÀs|”TÒH©°,Ïý_þôç÷>‹ûÞÍb±K“Ùáh1_i Ýž]2::Í«4Ë2áÁl”ïs£xЋ€¦µÓ|ïCLÃ}Yûb49h»j"ÚÎ(1‰’ÍZ4 P–ã÷òŵöò<í÷zA]ž¿ ÷ôñ³Í&}õö˯}ûÉ®°l[,å9y¶E}íkßy÷æ­ÐqÆúIºs˜”E¨“¬×UUO§Ƭ¢¨Û¶GuÞZ¶w;?‡u=ÜÔÅf_öÇnY&¯¾úuÊb„ñvuƒ¡QœS¤¯_¼É#„(«ZjUd›Ðë[¶ x÷âíáÉõï„í‡i‡YRµ]­éŽv»9œXNÐóY–ab

vŽï âa^idÃÓ¯//‘š6o÷9²ímµÌöÛát09<¸¸¸;‘[Ô2Lâÿì?ùã2¯$„Û%“O¾øô‡?û Ý/~üù_ÿõOÿÑ¿ÿ÷š¬q\Ö4iÙÍü•ø¿üå'÷žŸ|çßùÖ'?ý8œÐ‹ÛÌÌ7W£(\]Þ=þÆûë»;dÜátF-{¿M-Ë ãQž–Žã%edz¶Ì»¦Ë³|4#öyxAÛTÄvŒ‚Z‡Y~5y´ BÇ‚a@õcBl­¹­ß×Õúßú„)Çu¥ p,Ûó¢ÕzÑﻺ¥lÇĸv¯Ì˦-=|þöÍëÕöÖó­åM6šÞïG¬Hr¿ßÇ&Û„Yôä舶]ÜŒ'3ÕJˆ¢&Ïr×¶˜m¯WLDè¹MÕ"b0â~k`d×*®ŒtÇ›ºÃ6“¢a®]7%¡ˆÐ!Rå;JCLq×ÕªCu"Œ”@ÀVY²‰û³Z¶’·ÙJ×õ é•ùV´5 c ád6ì:‰€"YÌU²õ\×hœåûÃã#ÀµÑìF£m²¬÷u+ùGßÞ]S‚Æ£I'U]¦½Àk[ 1VªmóÎv]Û"œC.š çV)GÈÒºÓAZ^äEÅìÐ&(Ùí‡Ã±ãfõeÝ$¢h÷ã¼XwUÞÊrçØ~‡¥Ñ6¤•ínsí;e÷ªr[©Œq<·H;Ì‚•oÇB ŒãÅYVjÕZ¶Ãké:Ì@|sûfvz?OŠ"KÐÑpR×)%Ì(±&·‹µzÐ6}ýê×~øMœ‚KQ¾ÞØÞÈõXU6«ùüþ“{ó›­’ùÆ62¶•–ˆÙ Út¿Û†A„¢˜mÖ‹¨ß£ˆêî7Ûª­Ç''erɅ̪êìÑ}) "f\ ÇØöwËf9ˆRÌô>¯"7ø~¿®+âà¾Qì$ùÖ±ì^o¶OÖ6õ÷Éî`v@4*ó¶*²¾þõ|›î“íѽ£º‘;ȪD‘ŠâþÅ«W¶‡'‡÷’4#HäEëGD4„x~u9;>–\J.Vsv ¾g„Äœ~t{}ÝëÅ0%¼h!Æš8U¶¼;öþ7EWwMYdåÁl¬„ȳ¦å™Ò*&«+%bYã£ñüö5Ãñ\Œ€6ºj‹^Øo¥Éê’B5LÓjç¸vºN‡‡è*¯¤ÓÃã2×åf;>˜îWÉht˜î¶mÛ:}òôý—Ÿ~nxöìÃ$YW»@==ÿð¯þuz¡=¾uuõ6oë0šÄ½èúî*ôêªëGe¾µq<øög¿ü¢n›éÉQ׎íß,Þ=~ôd»]BŠuþøÃ÷³do6@Cˆ¹ãö¯/νÈÑöãÉzñLlÊ(š¯)’aÿ +›u±õv|òp›¬|Û}ýê«oãûÑaõ£?ý¸ÕÝoþÖwE_|þ‹ç_vy~óôÑGU¶ø}â÷OÎî.n³}ù­ï§Í¸â`49:ã] ¡úâÓO<ˆz³Ëwop`ÆÇ±ßÛå‹~¯W—Íôøôå믲"‹ggà]Ó¶ÇH—µ@ðÅËyþÌq˜’ÍùEò;¿ñ»Á›×æÁÓNj͹<ÈÛ‚X¦çÌN'ç×ç0êX¢‹»‹çßüðüå›åv#tyÑh<=¹7BÄ£žZIXÔE„Q4º½~wtxhÛ¬éj»žÛ_ÌçÃá¤ËÅr1Çÿåñ'«íš1l1ײí¤ZvUñîÝe×Ôèo=~ŸÙ=×uò$?8² ª×MÓAC….Òd}ÿÑ×:Ui†} dö›R`ëÿ#¾zmÛÃ02ç³·5W/»Ÿ~î¹…"/Ã"Z”`9j–íA`;p”ØJò?'ÿ‡ @ /AdŽŒH±%™¤(’—äí÷ž²Ïî{¯½ê\³÷:ò}"L ”F–!„Õ8@ÀÆvÀ ”ãY…5Ö››ÙxŸÖmšù2ÇpœW™@HYJ«Ž5\¯íªÎInk´à m‹uƒg’ÇO0¨, ¢•¬heŽ ÎêºÉã¬3Ð:wÝP•e³Ó-Â\ÔõÀ³ïïæ³É±ë¯êº!’³\”ä¢HÚªh­ª*S †mÝd1²"§IÚ6„ÒD`P±u“4-í÷&··’(K’ÆD‹ª­A^åÃJºöúÕ—‡³‰ uâ`G›œTJa‘•½Ü›”E>„ ×»ö†åA*Ôð‚âì6’¤0,† B·ÓѪò¼§6'²¤f©k„°Øhöí=ÏË·}sÔæÕʹ¡E£ë^Àg_¿žîÕMÆaG>ÃA –cÓ"õÂÀìvŠ$-+J™ZUÈKJTÕe6ûŸD¾¢‚¤Zûž×ÌÊ*×4õòâMgÔU¡øAYe,å càn7XPÕ|ïè$³,qDšl4°*ó„eÙU¢ÒÉ=—‘8Y)‹õª×볈ͫJØ,‰$Efp1¶W›ƒ‡ÇËù²Ê["ò „çòª’EÒ™ î_Ÿ›V—<†h³˜‹Š*°BEÏg±guÇqäe @= 7‹UÛ´--5}ປä¦2̲TÔ$ ­AšûºÚ]-æDfE­*&¯ó^§Ûµ†7·—ФÞÎ/¾û›ßÙ.®ÿêo>óK÷ŸüÑï…aP£ªêj»žÎ&;{Ã@¤ë†ðæíi¯?Ô”Nú˜Á Ëgã8`ÛÌç×ûO%±çMw4`AøµÌ-à D²úƒÓÓ¯'ýŽãÂÅADÓíu·[G¤(t»½ñb5ϲêþn1î_^œ+šQTUÕŸ¼ü¤ÊÙoû‡‹Ûk euL/í»Iï0tÊf³Ùƒåf±ZßÉ’yôüÙ›WŸër¿¨›^ß X¾¹9kõG<äß^¾œ=XÛëŽ5JŸ'*¯²¡-ç÷¶í0Ç0´Í溉iIÓ4k®ÎÏ?|‡CðW}úüécÝPæp]\úbV¶‡Ožlï.T‘}ò-ž`–§“ý#³£³9úÓÿî_ Ìn]–¶?÷ýíÖ2¶í°,<Ø{$Äö½q¼?=º<ûHygëjª™¥i”„„cûÃQè¹i›ö§‡I‘Jßäd Q ÚåüVëZV¯»Z¯â¬–©l`š‡UF·ëÝh–e¹ãx ϵ€)J†6”cEE–6wK]0 É¢(‹È0 i)FuWyÊpÄNçMQaD_l}ŸSÔ¨ò²¶±Æ‹6’eEd'ö´LÜ`I)¬ê2ÈlAQÝ8tà ‘E1Ü`E!ÊÓ‚AKâljQ\—e.Êb†5´¬‚$f G ³˜ß ûC˰g;ê¦!µ€¶ªÛË1lÁ "aYôîó_¾þ²ÓÓ»½®:4ÏáçåŽfJ¶Ww¿>zò”2¨äê$ ö&~´ë˜Ã¯>ýUËwÞÿövíì{óìàd8œ¿½¬ÚèÁÑã›k;þþñÌ—·'úäî¦îf•?ú³¿R8qo°÷Õ—_8¡ç;Û À÷Xïîo¿xšgéÛóKÄp˜á¼ (˼£ŽL͈=}ùæàðAY§´ e0Ã45¬ZÔ"TTÉþÞ7.//½ÀA/Iòn{‹g£éÖ‹Q¬A—pð£OñÙ¯^ H1´ñÿè!Êꃇözýîo¾û—ñg›m”ÕeX”~û{˜-S£ZÓÑhúòË_ŒG,U\Ýo1Gbdq±ç¬GýyW¥_Ð l‹!ko¶fÈplèÚ„cTÝ*ª< œºYVLÇ3gçYlYC^Ò}C›V5§Y‘†eÉó2CA–4ÛÍæøáQ•ÕNk¦Q§(-ŠÊ´æ9ctsuÑí[ e뺭ëL$å,õ¶Ëõõí aùÙhODSFnª²Ó€´)°lXëõ‚¢ ò´­“0åe¡È2@1æQ]f«IèTå‰,HJ& |Çæ‰$ËzYg<ÏI² }WôÅêVÖº1û~8˜b†»½¸PU}°?üÇÉIS 9Ž©(óHT$ERl×áãí<£3d†c„ÈϺ“¡³±1ÇË–Ò45ƒe*Š…I‹²6M+«ÒÐˈ „íB¢ZV¦eDt½—”!.±ŒX–)ha*‹ˆaUȶeac `ÂTeØ•¨)U›!ÀH%™…ˆuݵ¬ñ ä˜1Œ@›FÓ8Ä!L/ÞœÞÚ‹Ðݪq¿X/¯/={áÛî$Cms2_½99|ø7þ“éÉpoöèí_tÆ£'ïP¸³—áÐuŸ=vmG%x8›õ:ÇÛöúÝßxýê4oR/IdÞÿG2ÏßÍ×gYT¹¤ZÕ’®geRω²€ç×gÝN_íŠeœ&aBIö{(¨9žÜ¯6E™]Þt;ýwž?ûÓö »}ÿ»ïÁ¶Éý"É…—þöoÿ*qMUÓ<ùþ³>þñOËOö ÇÖëWðá÷ ®„ê'xgT IDAT*­Šº×2˜­Û<òý]ׯsZ`u§‘“Ѷ„u;duéî¶ãþaHQ™äI暆u°7»¾|#ñüxïéj·«Š’2ù¦H@Ó,—×½^G„4Eê˜ý$‰“¬‰çAg8ˆcŸ#¼ipn–ŸÐE~(l ¤)Zí»½Ñoÿ½qY“MÝ‘4Þ ó-¡ÀI†¥n7 "ˆ„€"-›’r¤&Œ(ËËÁÀ­yE ü% uÊŽ°a+¾ 5Ì)€Mn9b¤M^VM–€‡uѪd‡Qâ³ÉS?òмèY{Aþr•ƵÙ’ «œî6°( EÇAP5 eۃ㣺¦œ%M.Ú"MCM3"%™Ïó\‡‚¦c‚ë²€1º²((…ãñìå§Ÿ¬CÀ×UVv»}A–®/¯8NЭ ¨© €-O:mƒYX¦A$kç"CiZÓºæ +Š.‹=‰tš¦æYX¥UZFb„ø8ö1¬N=‰â–cÙš-òØG-')`!/ŒüÐÑeE!:…L•F¨fÃ(ayžÅ¤¡tЛúAäx;QQ0"A™V¯H£ß§0eq’Þ1›féh6ªËŠÄF¨¡ƒþt¼]ÎKeËŠÂ £¬ôæÊw6Ë4È»½±·Ù&n–dÑÉþI–×£"Ú§–¾ï³œ"*x' «<«È jùËë‡Ã}Ô‚I¯{úæ\7¦Hfš¦Z¾¹'°ùòËÓ«ç½÷Ío¾¼úBUùЛ۫×7/½ ùËÿï/y–ÜmÒÿçÿ†#œ[e—Λ/Þüt\Ô¤ÐzÆÏþË»ÍYoop~yáØË­cstøÅg?x.Í žã³¸ ·‰Ù7'Óý³A¨Òåîf¾šîïÝß_gYѵdX5—׃ÙH—•‹×g‚È•U&‹þÏ~ø4 qš¹XWËuš$u ¿ûÁ‡¼Øž<~>¿»jªéÝ4óšþèo~NˆE4êMþúÇõ?üOʵb‘å×ׯ?~Q•­m«†.×ëßxÿþö*/ È Ãéd¾Z*Ëžåô²Šïï/G£ã¦Îò¼¶7‹~Ï Â€B’¦+c½7‹ò•ë„F€…Ô»qúÓQ]ñÀ€m—6n˜N·;w¹Ô'ƒ²ñ8Ȥq ¤‚CäG^ FIàpHIJÄÚ– ˜ÒV†w‹ M7ª¬.ЏéýüþÑìE§gäQ}yzýàÁÔ²¡2„Ó5«MR¢ àê:³ú½<Íë¶byžc¤åýuw0%­®KÌó‘·Ä„… hËz&²*¥qD_Ö ‡XU¶ŠÆ¥€#<¯È¬mû,‹!ÓpX­Û¦n2HyAS¯ Ý´JÐÒ¬Mâ€( ­@œ{·÷_=ø¾$Š‹ÍaD†ú––ùiÓ†P…Ó=Ûæ*r"¥. \"ˆ Mûý½««·£é¤ÛéfYQSªÈiKš¦i(š‡~]·œ$ã~ˆdV"h^Ò’8à8CÌa³Z+Õ1Ë0u[ëÚ,ËÝ2+A‹9µˆì€ˆZ’»/?ÿ¹ÌR¥€ ⪌cVT‡šŠfeJÄa9.hÓ–uY²²•&+IÔ¢8“%R¥uÕ¶U™ö;ÏÝÆñfÿè‰ã®F„á((ÃæðÕ«Oƒ‘iZ÷ËEÕ¶º¡b^ Ý­ +‰k÷Ó$Šò"S$]ÖoçŽdÑ÷#]ÓïV Uí°‚€0Ú.—FG!‰"Ú Øw‡³½ÝÖ¨ŒÂxº´¾·3ÌbŸ¡$ˆ6jW%Œ€@}»¸||ø¼l“¶©‹8a¨hF‘æ jÃ<Nž^ž~ÞëyVk†œ§q–¶ K:V§¬›År>í§i–7Ð^Þ= ‚]o4L}×^/ž½ûÞÅ•“§ÉxÒïôö7Ë[SDahõͦ›å¢Ó1EAÚ:™çnögÇÛ­Ã b[×´n†¶¨Þ-w²"Fåbƒ¬‹ØL7ŽÂíb¾züìi–eöü¾{8Iʼ®ë¼UIå'wäóW§œ‚L«“zIUÖ°š*ï쥮v£È鎲ÀE£ë¦(ªó›+Ëì3c„–Ãòòòjt<ÐT£,³»}þÎ{™%iÈc¶,cATç×÷yA?÷_|ú…j‰¢iF~N™ºÓ·¯® ~çÝgîÎ?|ò°Í /¡I¸><<ô‹–ãq¥¨Eúxt}[Ø‚rØœ½>Oföv>™ûqõåÑÁžç³4¸¼ºzïý6›¹ÙÍ—ºÙ7k—®@ÝˆŠ èâzq!ë¸öd0Žó<‹†%jg|þúW¬¢¿xôA–y£ýÑÿóç?þÿ÷ˆ@$Á:ûúëü_~÷“—o·‹ÕÑlÀ1üþä „MÛ Íæú?ÿý?<{uîöh4Ã"Ü&QÜé âÄM'ýôÇãé€$ç~}wõö;¿õÃ,¬Ú&c9v³Y:—ç§z¯/ÈâÑlðéÇ¿Ô:šQUÖQZÝ\lMÙwF¼"ÿݧŸÿÿò_½üª)Zϳ,™ŠûK{}¿º–øIOëÿê«7 Ãõêëîdê,ן¼z™EA YÇ ŸþóúÇ~ÕàY$Ë"¨ÙË·¯»CU»WçoZP™š”¦Å.óFÃÃÅù|ò`os¿Æ{ý“Õvk˜Bì ¡swãTe#RoϬ꺩£Û-ê’EÜË·_N'ÓÝfç%ÎÅÅ•eŸ<Û¯Òš…ûì—¼¤ÁÎÙ躵¼¹LYH‘6_õëOžÛóän}¦)šÈK£ÙQSF ¨ã8{øàáË/¾”ez°ïIíXá¶Ãq¨;Ö_~ýöÿê´ŽâJ6…§ïì X V̼hÿpæ8ÎEk¨øío^~v«O´®,iF:_^¾ 'özí‚ìÞÄz°÷Ü´º¡ïLö@ ½`‡ £*ƒŠæŽíŒÇ‡y™k¦8å|yU¦MÏ~úÙG,"øþ౓²«¦,`Q"âþWÿðËO~áx C{½0(ª*sûÁÇNèõù)l!G‚Hë‰Gß~”yññþ뛯ûV¯¦óœ;_7 5z½"¬Ó²¨[¿¯:îªiŠ*o¥ãù[Žˆe™#9¬\]_ ‡CžVó¥zýÑ4 ÓNOmê2 RÁRÚ†Mü0k³§Þ»¹žcY¢yQaÊ\ùaZQÄŸ¿½ÜÛ›ee¦HzZQ¶iB¼Ì,o¹º¼l#p"±hCÂ’ùÝýÃçûax_ÕeUÒ²²òü•bXNŽG£ÓÓ·YVÏFC–7ó­ sšbDqÎp¬çz£éÔvwUUû¡wpp4?¿oÛ 2´Ê3­«ß^ û]ÊrыׯOž¼Ÿ&»‹}?Éž<¾½~+pbœdVGËŠÊÝí º¡#‹»ÁdùâØ¦¨ƒ<¯›zص‚0x{öò½¾u·¸¯ëŒ6µ®J¡UZ^ÞìïOYÿâ“O4ÕP;:(¡íl{ý½ÝfkvuÏYïÖqÜgì¹q ó÷Þ}ç«/>G Ìã¤kõ7ë{^`ã¢è™Ý4/îšzMKZ“ YŠš’$ul¾üò«î°ÏðÌf~W7¬Ð•ÌUyyñæúìÁÑ{ÛÍÙë—oZÄü7òÏü`Óæ „ëÛ×=úꋯÇã¾&+ @«ííÁáqæ¥-jZ׫ÛÙÑqäGeYG±ûøwÎOÏ(Q(ò„µw;QÐuÃTíÓ/>~òâ „¶Ib+¼0Ç 0‰Ò‹ùõñãwé5mªüé³o¼úú¥¦ªyVXÃþ˳Ÿ[ïñãòÔéôF··×|øÁ/~ùË'ÏÞßn®kØ?8±Ë( ‚e•øN„ríåñƒ§y˜ùé5á^#Îýýl6»¸<}úôÅ›×/Gƒž¦Z¯œ½žÎ낽¸85ëӯ?üÆwYÊòıçÿ÷þáÛ7ŸHÓ=¤žwøà`uqÝ hXÚ¾ÿÃÿðÿaú`ßèNýØ¥’8‘9šGÃþíåÍñÁƒÛùÜO Œ•%eSýƒßû]ÚPU± @íõýÑñãä¢l…nˆXЂVÕM{³öœpøN˜»I0iÓ~p𮓆+Û»º_ªˆùä럙’ø‹ŸŸþ£òûeQ­—[¢H–©7þô£_ò¦æûÞdzðÉ'¿þÞ~÷ÁѱèË?=yt,*ÂíÍ¡»p}|òر]H@Eƒ^× œº¬Ã*–œ†…ﺽN“5 úîb¶ÿ$̓O§´ÆMÕbH“$.òl8e뺛ýÙ(ôS톲¬ˆä6òr‰ð¼ÀIƒ×Ò„ä,­š& T”.€ ŽQR"”E…FWE*˦·syYä!—eC¦aÛ°„CõÜõd<ôã:Ž7DeyI)óЍÚT‘$¨aAJ‰ ß¼þbz|„¿^Ü1õ½”ð¤ªò*E™ö¬ávíI’LXÈ"‰Â*+3°Dx"]œ=Ús'Aãe±Ê mÛ4 Ž#Ÿæ`°7]ÛWMͰ56Ü¥y툤“$Q^z’Ô…3 °W[ÅÔÚ–Dò4€-L‹¬ÈS‰7wšÙOCw2™íìMQÄŠ¬¨Šy}yžÆÉ¨··Ý-T]u6QÔ8–.çKIfOžÞß]Q %"bŽY-¯eÕÜm¶{'ÓÝzW”5bY h‘ÔÖ4ÓÛyœð 3¿»<~ü(+ËGï|ó7©—©f·ßïÞ¼g™÷­w¿u{êNN¦×秃þ¬miXF/ßœÎ4-Ý­m!ÀMךnV+$¶¼À›ÝŽë»Ãáˆ' m<ƒWW󷆩1D‡ž~þ[ßÿA綳ˆE¾-[ pSDY¼xôóׯ0E}cª™={c·uÕÀVäÙ(ò=gõÞß ƒï:e}çï®N_¿‚ èÃ/?ý¡Ê^ÛiæÿüW·wrÄ”¬,wR oï–Õé-w뺮÷›¿û;›µW&i;¦Ø‘ˆZT5B¿{Ø5»ÛµË%K‚½ÉáÙåVªdIïö&+o îv†Y^täÁÝöN4I’Xnnß|ï7{¸wȲøhvBtíààµ2oPÛœ?üùOÿŽÓ£i~^TM–‚B1‘hQ–¢{{Jºi‹´Øy¶ Ë ¼jÃ8j[¨HÚõͬI1Ó¤\n¼ñžäíÖÑ&„˜I €ÿõÿü¯5“a[éñã'O¿5…&IÜö½Gˆî †aº‡¯>ÿâøÅcF«þ÷ÿíÏnï¯?y´s<,Ô¿ù¬æ·Ç¬×·I˜’2ý«Y®=>|¾XÞaŽ aÉÈóP•ôëË+kÐoêÆµ=Àa@ôº)œÐí÷ºI«š²¾[aÂð’QÕp³¾×;½£:Éô·Ûý‡-ƒ"?I‹vÔï¦iÁb”yUÎÀqlÝÐàXo×LÒ4 Õ 8cY‘6pw„CJwv{vÎ`ÛqEU•>zö½7'ÇÇonn/={’¤Q•V„UŠ*QUÅÙì²2íY(Lò¼„L£È½(ô4SMãX’DEU–·[‘WE]h2d/ñyT‹²^ix¥£Yœz©ÙírL›%9”ôp÷VU† ë*t_Ó»e“¸;O’Õ¼J$^Ïâ8Šì:F{Ç ŸwŒÁrs/‰<Ç‹U›÷,­®hšm1Óöû{Qâ”MKx 2lÕf<''YY€¢£¯æWã½CI±¢¬– ¬â,m½£PJW«Å`Òü¸(k–ÇšÞ‹B—ð¤­ZNy‚–̲¼ìû+E5 <õ¨Ì›J¤¼*íí†á ÝTâ0à9¥¦ƒY×ié¸-‡”f¾ëi†P. ÆÎ^#дˢæº;€©®™E•·mùÍ IDATK&,hÚ¢(ÀýÝõÁÑ#Ï ãÈ1ÍhÛ¢ˆe·)e êOfŸÿüo'{ãnw‡ÉùíÛujž ÛváYž š&Ñ“§ß\nežÍ’J”Ô0Ø2 'ð¬ i/?ýjvr[jvíÜÈšL>É}Qwô†ÑÎk«:-âþÐÚ„- ií†Óã´Ê¼õm§»‡08˜åu © I².ϾâD¤ª×݆_—u¯;ÚílI–Ë»GžgI|¿zkSUWÓ~zd/ì¶(XкUu8º¦q gºÿògNßÔÌ0Œ‹:/šD‘õ$)¬æ‹£ƒG^ä¶Mƒ f(¢Ò ¢’aYÍ2çóKM‘$U„G®'KZÓdmƒÊ4«@ÒííÞ®¦€A@Óôõf¥z‘gÃñ4‹¢ÕfÝ1 ^T"Fîp0ñì­$ëiœÔUihzUÃÛ›·˜c=|vþö벪‰(H·sWnè\ž]ý×ÿâŸVYqss 1 ¶Éáþm/¦³½4ÊûãáÍõ9áDYÓ"]ÞÝ‹Šhu†ör‹Xè{›ý£Çnâdñ. ’½“ƒ:-Oß¾šÌƸm-mæŽÕ4eÆÞw}˜!öÎÆô:{×—w‚ÀWI¶·¿÷õ«/ ÃòœÐèõ\ïæ/þâ—ßý·C«'râG¿þèßúf•«Õu:yxx,*ê|~æÚ»ï|ÿ;WççUẽÞrí0,nïºýn×ÿìç?}úü„2 -ª( O=ˆ“|8œØö¶©hfy+_!Z…³ñp/tÝ´Hæ×÷¿õÛ¿“‰½]Žf£áþŒ ruõZÑ:e]=œŸ¿é$Ëš±,븉ÕGÓn’UƒîÄv.<~ÿÕWg÷·‹8Ï_Üo~çw›ÅT&2ϧg¯&á Ë”¡Yà÷}?æ1f¿Ü,PáýÀíüƒo½Àÿò¿ÿç§W_œ~ä×θÓ{ôìðãþ¶§Œ¾Þ*¼³Ü^ܼžÏçýþ€!Òÿú¿ü‡{ãži%e½XÞÿÉñß:Þ¢7ÍÒ£iúÇC<MêªÔ4úöúÅby2_.ýùç‡ã~yöôtº8Ö¶3hªÚóýä}ûÝç„Ùç“wñÓuÍôd¹Y= 㪌î§Ã™èU”ƒÐ3™ÅÃb½®;­ê¸­;Áåp>Úï#Yv£ñ²nÇ’5±€g.˜aÜ®^&nSUMU!¤7Mí8^^T5¯Ó$yúîÓëëWÍаŽ÷w›¬ÍÇáÔµ5(ÿúoýŸýðwƒ±A4+=ƒpl{Z*¢Çû¯ÿåÿ/~ö³_‰†3úxòl»zkºîî&#ÎÁõ‹¯ÆË“²ïûJ¥I2\ŒÊCä ¦77מçŽÇóªMxÇ{Ñù^ð°yP/Šôé³K Ðvý A4Z,Û*)„`¶‹%ŸLξþú«Ùx4Ï *sž»áµ%—êÍâ°¹úì' âRÖ‚Ñh%YžŸÍ^ݿaçîüÉý›o‹ªÛo·¡é–S„úV”ƒq0›/^\ÑC@ óB÷ÍëëÑxÜòb0œÄû´áÉâì‰h»²ÉzÕÓ(Û[á`ûò¥n£´Q¯û£d¶˜•ußóÆqÜýúðäÉI]ðÝ6 ­ÙòôË_ü’·àêòª*r/È®£º® ú£ûÕý|¾ðýÙv·Ö îê”–P][p Ãu»•®cªëMÛRfRŠ2nDùâûߎ'““³¥¡iUÕ™ŽYå3t¢º®Ü`üðx븾m¸Цj˜c5Uzä²á¥ ZÚ– ýéemc}&¨®éº®Ò B¿LË$ÝŽ¦ÓtÚ¶¡Ì³N‰.œ o^¾!zòÎÉÛ7T×™A±f"À©Nò²â¢ þç¿þöß}úÙïXÞr¼Ã˜Ö`4 Ë4Ê9žNúfû’Ú)MC¦"­lKCwúžË®åô<»M*Á;@ÜXIë: ºa2]ÊVg„jCšWŽëS]¯ë,ËŠÀ›–ÙÞ¶=Áå!¹›,ÎòŒP6•Òh«ÔõCŠ5Ù6HƒûíQƒp8˜t¸»sñôÝ2êÊ´s=· /”å8E^JÙ‡£õnçY®c› "¯lƒ‰JX–[Õè©éQ¬i¼yù#'=&”™y™zÖôäp|-ð‡A'úãfo¹V‘¼`Y–9@÷ÈrìÃö+lØ.çœU+Û¶ºZUmuد/–ïåU' B"šN‰h»¢ãéÓ³_ýâç£ñ0 &¼Ó &-B±2 ×¼}ýêÕóŸWi¹Mê¬ÜðîGE– ÜKÞH!FÓåÍ›ë¦åAÓÉüõ›×Ëå™RS N£"MÜÁˆi„bãnû0] ºªEX/‹}L$—e½ïÚ(å…“ûë³ébµYÕ—¶®Yá`”weQMÆ‹¦©‘FnnÞžŸudYœÄÛóó³,/š,×)my5-÷»G¨¥ÄbyvXß%MǪ›²­¹í[Äupß&‹¯¿ýj0Ážn÷QÇÛÙìÄrü²ÉeÅEÙ,N¯nß¾¨'99=ß=ì @ßs«" ˦=@@Ö£qPåenÙF£ÁœYÆñpg˜ÎtqhûúÅËËç?¸~qýd9ÛíÈ€†t{8ÍãÝ׿ýü‡ïÿ£ÿôÓçùC¢ÓË'mÝÕMûÅo~ñ;¿û{&sÖ÷¡?hy3ö‡ûãV‚ž·Ýù“÷îî^£ÝÉùÓ´Ž›¦Ë“d¼˜×eí:îõ›ïÇ£¹gÙUÍ‹¢\ÎOlÓ=€‰jûÙòb»ÝöP)ÙÆã2+Šþè'_¼øCìQýÍõî‹oó{?þòË!cža­7oufù£E'Òèp|þüã´Ø x\é:ï ›v(Ï£ùt1]¬+ kY^GáÍëÛíÃÊòm7?>|—–ÙÉèd½&ûâïþÊô¼AèØüÕ¿\Lg—ïžþûÿûßbD #ûûüŋ߸¶qXÇŸüä³õúmǃ‘ÕþŒòcº Ãénµm‹ün{\œ~òã@ [ÞÍOæDׄX§Ñá°<{§iKÅ{8Ø1’ÃÞШ!ÂL‡ W›·ø÷þÁïGûèÙ“EèMÛ¬Á:ƒÈÐtüñ§ÏwwÏ?üX°“@´åýÉ¿ùþzÿ¸nSQðv²ëÓó'žg‡aðÕç_ž./4fé„ɺ%:6¨1ÊÓ(mª'Oß/òc]6MSŽæã:Í5FE“-ç—U¥6¯ðÞg®ã!MA‚l¦ËËÍÝóéÅÅeš¥exÎ`2]ÆùÖuª(£¡=ÌÓ¼Ve„uÝu]æù.o¹ïûUÑbˆ FbÇí.˜L`eYÆ\]V\CŒj|·;¾º_ýÎgïüõÏ¿dºq6ÑuZ¦e¯ ¨@Û¶nìV+72‹ö²/ªÎ´õ¾×0¢²ïx×øÁ,‰·Z=€·Š÷Ui†²-¿U]œD†á@„â]Ýh ^»þx·?™M§gMWUMì;3†ÙÃãÛåüI#[L€i:»õÆÐ ‡mÕ=<^3Ã]Ýß½ÿñSÛ`i–[ GYC¬Ùvæ©Á¨é:½÷][Õy3=[´eÛµµzöPPb#J)ÓLÓw÷Û½¡Y†K)FYT (³Ú¢†Þ8Öˆ«º©KÕõH#RrB5Õ+)¸c»ãÚ÷|ûHz…{‚ŒŽË¢IG£+Å›š7²ë©ð¦Å„  ž“#%Äô\´íún2]!°NFežC':eÚd:9n ¡J6®?«‹œ1Z´åØ]›ßßßN– ÛgÙžgÅv¹œ&Çz¾\¬V·D£þ(ÈŽÇèš6O'é1“ŠC$|oè{ØCÓu€ëý.…–å8¦{ww†¤k£ì˜x£A&ºñ°~sº¼â¢ËÛ#ýéù"Jv@•nPУýÚ–o†æFÛ·ƒñ º:itÔ!Å„h„´Uw<$ïüáæa­³áåb9é;•§iÛvãñDõðîîõd¶ìdçya–)AP¢V‰ñpÜ å–×i\h¬°®zˆÔ1NæW]ÓpÞY†C(A˜&Qj;vÛvÃñòÍ«W¶çá¬nšº¨0F–c¦iá¸þ×_~rrIt}»yLñøü*ï„R¥MÝ$ÚUufn8=Þß1à ½AÛ5P‘²HÌpR•u¯D]—“Å29l¡BYÏg šQ¶Ó ¢S‚)»»~5].;ÙvJ¢^îöÛ±Ý~‡ÏOººJ’nyîc}÷Í—_K”ÿÑñgbëûk]gÇûèù'Þ½¾q½kp19}¸»áP-Çç°ïë*åZ.žFÇ­k†÷·7óù9ÑhmjÞÎÆãª,ï“ÜsüvãÁt¿ÝsÄMÓ \ïÛヌ¡ÁÌ®©"ëÝýh4h¸¬ë29ì>ùñOÊ$©!†AÑÚus¶˜2Çzþñ§¿þå/ƒÑŒ„Bûo¿ø«3÷êé»'­è4Ü¿|ùÕÕÅ3 ³íf{ïŽAÉ3›ZÞ0øþÕ7c×ǵ,ûñfÅ,«Çýtx²?²ò0 BHÉÛýÆn[E.son>xúΈ…Ÿýy+ù‡Ïœ¦Í‹W_Í&Oê¦8;¿H’¤îê0Þ¤¬÷ègÕ©x‡ûãpº<äùýãú»ï_Žf!ìÉðéd2T²G*ër 1žœž=ÞÞˆŽû·kÛ4‰™«ëˆÔ]Å<=ŠvËÅþGúž½x¸{;šN$“é‰çÙºa¶ÛÿƒÞ>D ÷‚°ˆâ– çóù“g§ÿêüW_ÿíßþùŸ?9mªîg¿ú›?~ޤY·5èùú!zþñ³ªÊÊLUuqùÎå›7+„FȱY™kbb­_Ý><{ÿ¹çnà¯î]ÏÔ®­ÍÓ®ÁЋ¶÷&³×»Óh×6Iz]cØ£$=6en‡c¹ÅLÞÀ²M‰†°pãã!D‘Y”&$˜Mò(iTÏóx6?÷»<©nwŠ|ù³_Õ þøÓŽiX~œ•†n¦Ñq~{ÿpvq"zX•5 °o[Æì¦ME+iìüã.§”™–Æ›VÄw…¡;TÇ=TûýÁ²¬V¶€4Í0„†îÕmÞöÁ˜çÛq¾cDoEÍ XU}`/K×ôPûÝ}茹j/UÃ;ÞEÇĤ†‚Bg:3G×ׯLËB½&ogXoÛÜòì®åiœº^0ô§«‡Ã`Ž7<6–á&iTuùÉò™êºõýãd±4‰^™Æl;Ó ›6†ª¾wƒ€×¢n*fš¤§XgÈ©¦K)-×Ù¯÷È0U!;® Ö£žµmU‹ôÀƒ¬8Rbfuªb²ðñøÈLìøÿŸÞ‡PS–¥Uia;%¤S}Q梭&ãùíý щN˜a²,MÔª* †A§qOÆS%DšU@õÃѸ­*ËðÓlK4ê:®Pr¿?„AÀLs³Ûˆ{%‚Á¬S W}×òñhœDY[ Û¶ ŵîß¾ Ý@!€Ê£Ã ÷ ’7U'x†³4)¸lꦺ¸x÷¸Û5ªc„Û¦Ýí"ÝЙn›¦wÿúìì)Õ²ˆÓ´¢Œ4°\«¬‹<+çgëÕ#Ö4!åÙųc´#XÙ®#Z±_¯f§”êÑnwrzÊ;ÁˆµÞ¬Úº}zõÞ1M•T:ÕgËÍúN Y—Åd>M³¦íZpND'ó"²}WÊÖu‚ëW¯‡ƒÐvl Ðê~=އ“ñq³³,/-¢A0îoÚ²©øÕÅ{ªÍýƒï8hÇáÉas½°ÜÀ³G÷/!ãÉ¢Vµ(9„€ÙŽ”­à".âùü¤­#Êp×òÉò¼kª".@O½¡Ëtûå«Wg—°Ge/æó“.ïu]oЦˆãwßûlí¾ûöëÅÙ;?øÁ‡÷¯_›–£aŠuÂ0úüWߤñæéÇ‹Þýñúæz8žDû}Þ¦Ì"X'6³°Þ×uѶbzzÚÖ @ôµçeÔ0’œÏ'g}ß®ï]'´}Ó6ÝÛ›·–ÙAOçWoÞ¼`¡za]ÆU“M7L£ër éÛõÝòò¼Ìêm¼#„Z–{Ø­qÝpŒ0ý¯ÿúg$Dï=GVòõ›ï–çs(ànsƒuùý/^½÷'²×ŠCÕˆê‡?ùï>ÿN  4( †óÃa T«Ô¶½_ÿâWËåù0 ó¬¸~u³œO]Û1=Û6øNO¦ww×@a@ÐÉtt<EžhüäùßÃX»~ùÛáà=fCwððvžœúé%,ê–øGÿ°në®+dÞpœç+¤¹¯^½šœÍ,3øîÛ¯ ¬]Û?nw†~ðƒO:¥¨Áî_¿ G£q8ovëétH•]Ö­¸ À¤(tŒÛÃÝæpº8GüÏþù«Ziš&@ùGÏ?Q]Õõ©gXÌ2Vž5žÌNûªöMº}Xöéßùè4ô½ß|þóÿê_üejÜŽÂ!54ÏšÖM%EÑTÅ{|öÍ·_YœNÏ”iy’Ð4 Õ£Ãz½<™D‡:‘œ.'\µ 4¸w Ã-ët½áؾï·Ee»¶äÀ0†–Ų< ü‰i™µmÓ†ãASdº¦÷XPÂ04ì¶á1KïD徦cz^4†G©FLÃÛî]ß5ˆ±9ìÀm×=l_¿wõÎ(\äÉñôòœ7uUC™ºi5MÞ”mÝVãÁ0:V–éZ¦•¦û T¯›œ™f•×cÌÀMÚ Tµ’ˆC$uEtׇX`h”aMÕ  Ìm«O×)ÀÒ¶Ó6ˆ®ÖÇ`8b†A!P ëjÙ‰N×µùäÒ¸Ññ@¨E‰æ¸A[\5Óéc­ÈK§À¶kLÓVª3 !¤H£h4ž*Ѷ¶ë®© $‡šV×í|y™D[ÞI× «²@X*¥@O¤ä”Ñìp0lÃЈ«ÎqQ)z]7šª :H!˜ehXµeG¥:@ŠPf$ÙÃx42¨ÙÕU]4ÁhØŠTCˆ ^óœ™C¡dDSCßꦆ€bŒ,fD‡¤íZÓô @I²W ÏOž¤éÁdVÓ ê–N¤”‡ÝfyrÚ=l}ÇGuq]@×ú®›ÏNÖ«ªLÇÓ)† -Š(N&Ó…äR*u<î|ŒѶuVY¾£S3¯3Þ Õ©ùÉùfsgZž®3 :ÁEࣆFô››‹gŒ™MW–e‚¶©›¦J¦Åvzö^W–U“B‰FË“Ãam9¶ì¥i1ûÍúÞõ†šÆÚ2¯ëb4>Ë«RCò¸Ë-Û&„eq^ÕÝd¶ §×/¿]œrÞ¶^æ5ØÖáhrÜ¥ežÌæ§]×Rf4ÕÑuÞ Ó4×÷7§gK×»¬a3GûÊ8M§§KÑÖÛí* \Çs«¢ŽâoâwI?›,6ÑGwmÏ}SDGÛ1˜nˆª vM=ÍkÞ6]YçÕl~Þ÷]]å¦áB¤º¢JöÛñt‚ª«ªíšÑâ<·@eÑhL™†Å«¶%5ô¡»øîÕ×¶£éÌ7'“t» Æe+¡§qøË_ÿÝx9|ûÝ¥hš\ž\Õ•ªUµº½ &Ãù,‹Ž²“ˆõ£á"öºA$¯mß-ÚzŸ=?Ð BºYÝÍcð=¸¾M°ÛQ¥±ï(뫃†"Ü2Ü4©‰Þ7M­³`¿¿««dŽdÏ“´¾}ûzq:o•Ê·åõÍ×£åâúë뮂‹›Ï†FÈ9ÛW‡Ãà2 ½¿øþƒ3ð#›UôóŸýÕlv٠؈¤M“ËÏ~ôQQ&¢Q†Á†ãéw¿ý¢R%#Ô¢¦D¢«+ß#‡ò¾¾|˜>9!:±Gƒ¶Þè”ÇsŠÄq¿“Ôúà½gëÕ›¦V¨Wgç—ûݑˠÆ0\ÄÇíÀñ’ìøÕËïÛ‚{ž??;=Ÿ¬Vç§?ŒóHg:LÊ®×d/µ89†¡×DE–FÁ`<œìöá0ÀÿòŸþ½ê˜É\ÇÏËãñ°Ñ4Ô¶%Z¥WçX¢éhДէŸý@Tä9ÁÚéùi'ÄêveR=‰wóÉÓõãå˜QÛÞ\;žžé+ŠDAZå™ïŠ«´HʺzöäùÛë—¦mÝ2lR5€béÙÃýîq¸`û^!¤AÔW™ÂLÃX½~ñöýÞ­«:³òQèv%·\Kt­ê¡åÚÑþÀ˜ÕÃJ#,/bæ!%”ªkKÛôº¶R}ÍkÞDM-OeUg»èq:\¾þîåÉüj:†ã°Ì“¶¨ ‡vmË$;–Éz]ÓpQ–(Ñ«^1fȪ²ý€w]Ç[!„熪—œ ¦Sj0 A–$ bCg¦Å6ëÍx:˪ @©©úÒÖ +°ë.-ójv6;ìVJ …:bê@A;‚´Ž ¬››»·y‘º¶÷äòYY¥Y´'GÓn|k  H£­}Ãí{}w¼ÚÝËžëÄQte©Qæ8vEÔò³ôà8¡i:Y|”R Ç ŒA× ª³¦ªlÃ)ŠcªQ‚”B†C¨†!jšº(×µÛ¶i¹h*a{¬‡JZ7©uè»®ix§AjøÎns`…TPb!{f¨3ó˜íÚ¦›ÌfIºÓ0FÄ5M=ošÒµš¦v»GÇš˜†ÁeÍ[iÚŽ2pÝýêÐ6Å,\h=HëÌ e¸®*Éfu¿xï“’ä°•½.e¤,b× %„?Ž«J6®;pðÕ÷ßÛŽîúÓ,Kl“Ó#3½ñx¨z°}¸ýà³OA‹ãxgÙ¦±å9Yž(.‚WOŸ=Þß#<Ç¥×M­g†Áëš1}³¿_,® àò²ª†Ó!BZÏUÓÌ´&³Éêñ: gš®A*Ë$µ=+/âa¸(‹R(1¦@vUÑOæ‹N4 “$=Ž—Siž)Å]Ï€D‡­7ª¬žÎB4Yy¾ïxAº¢ã~:_ö=·l/K2ÓÄ Y¶ÄiÜk}à¹ÛÛ6ÂAà0»*„0/ÔðdÖÔI‘ÁÈsl_T¢j“é|‘[ªÙå?S@B¬Š´NgFéñ¨!J) ý¸Öt¤SiV–=ŽgÅÔK‡8¢/Â` A»ûè÷¾ûîË“Å!«n{Œ[MÓ‹ºL®êîïÿn6EÚRÚOgË,+MÓèÊÆ2Cß|÷íwI™ŽçXþÃên>=i;éûASïïLfX®ñê›ïù½ð IDATo^‡ÓùúöQqùv}{6?)‹z“îŠä0ŸŸïv›ßüæ7o¬¤|ïÝoïW„jÞhº<ÿðËÏ?ÏËòïò»ŠH³èfïŽÜÀ±š´}ñæú“O~œGÅ›Ûۺ젺k!¡²4‹‹èt6ÿþËo,ßýQ§itضiQ¥Lƒÿç¿ù˳§ÀŸþòWÛýúìüü›ï¯k•¤ÉVtü³ßûÝ»ß~SeÍt,f˯~ý[gâ9¦§Fl=‰6J*õ¹jÖ77þ0Ü=Þ¯·‡8%+ |øü}Ç2Fþ`Ù%£vßk¡ȶê8w˱¼ÝãC׿ž7½j›ˆé&ÄÿÓòùu»ùþÛ¯OÎ΢­œŒ†Iž?ÿDôQÙ¶åÕ;’Ë××/Î.Ψ¡¥^¾ýf2èˆù³áíÛW'''Ø-oª´ÆšŒæ‡í¦“BÉf2_n×[fjHi³ù²Ê uË1©®Ae¼zóíÙéS‘ª¨{Ð1C?v7lªêqýpqöŽMÕT–i-—ãÇÍ^Ó4òc„:HF Ò‰0ŽÓÑ`½®§„#J²è ç”éEQb)Å1ª²’¢å޼‡‡×ëõñ½Ÿ ‡ƒ®%,6©´Ï²]u³ßíj ê”ð®iƒÉ²®³N´Ôu¤µu 1–Šݨ¹ÊÒh6™@Œ5„šV–•Ô‘ÁUÓÔùbz–÷yWWÙÎØ‰6[j†uWÐOF§IyÔ ²Ã:ÙÝm¤¦—EáÙ¾íÙÖ æÛõ—ÔÐf:&][úÞ¸ã²åy¯àp0oxÕ”j2šâ­‰©ÕþíÅâ#jàãîqœi6iëj<˜rc¬*{¥ÂpÞãº.sËö(ë!–MÑq,5„Ó;f[Ûtt¦ ØèD×"C¨ei^¶År¶|¼_upí×­k8X±Ãqçöp4Û¯-ÇsÝA¯¯ËÑxÈËŠ@ ­v›Àõš¶NãjpN£8¦:#Í¢&‹’­ÍlƨjU è•Ô³ƒeÙJBÓ3ò4ˆ»óA–ÆÑÚ®ô§u­¶-ÎNßKÓ(‰¶~8U„X†bª)“y«‡{?pêyÎU麡n:‚7”釸øäêª)Š»‡{®Ôxy²y{§$'„•eq~öÎËo? Ÿ,Ï€«õt2$ÄÇ!Õ·œ9N[ç’4§Ë*.Ò$ÖÊti¬msSÓ Ã&L»½þ~:?g&â%M‡u 5€ nË8OËÅéyÛ¥B©ÑtP%ç®÷L·ó¢(ªÈ&B ˳£ÍV7L¨ÏeÚv±|š¦9 Öíhù¤íò^À»›ÇùÉÜuf7÷[ÝÉ« ’g‡ét”ÇÜ·¼}º¯[áþ`±Xß¿ÑM–ÛûÓ´4 ÂuUÙ–™%éd6â]sXï˜ÃÜ0ÌÓ¢È7aH˜a×Ul™¾ašM׬n‚ÉëúÝëû¦©{ –ÓE§m×(¥f‹ËC´ùêë,Ï)%ï¿óþa»™ž„”؇cYTÇóåÕujh¸IÆ3Ø£õê¡nÛÞýa|\QÄo¹(ꬰñ§ž£‡/_½œžOYï60™—uÇ=ßíê6JºÓË«2»F(©>ùàÇw{ÃötÀfËÓ*?ÖY> Ïž^hP;ÄÑÕÕ9ÆÓ>Íóíd6ÍÏO¢íʆmß$ÉqìO‡ƒñï~"ZÐ ôÁóOeßNNšNžTM:ŸÕu“•GK§”Mʦ0ˢܵ=ÀãíÚòœÉ|œîó®­üÁ sÏs“ý¡«J?p‡Áh¿Úš¶9™Îã(Ö€ Û¦óúæ…jP¾þð¿ù#ß 6›½n ®”ËÅ»q¶q\AÝöü8ÙPÍr—2Ú”\·BMabÒc-.ÂyÙB…—'§MÙ–e.%§:ž÷p·fÌÔˆ®3–nV¦ëB€-Û*³ò­æ——½Y²W°ýðã]¿x6M“ÙCY×_ÿúÕ1Ê~ò»¿ƒ(ûê—?ŸŸ„è±T‡M øÑïz{½êÚúÉ»çÛÍ®*+ŒååÉó4J#÷¶M<Ûy\­ŽmËÎE‘‹É ŒÂô°Ïó”Z8-7uÞÔmú¾†Ì¶I÷«»?ú}DånÿÆÐƒO?û¨—'çwï¾÷q‘æRU§'狳‹›W¯ß{úÉ»ïØ 9 ª"ö½©nËãö°>쟜=¹Ø?þñùåÂ÷†uSQª!ØëT3¨ÆaÄ$ J€jëüÍÛ;;„´ýî8;›â?ù£?5LúôéSéd8‰ã³Í|sœºÉìÐ$ÍúÉûÏ-—ÜÞ]æK„LÝÕÖ«ûžÈQ8ü‹¿ø¡¡¿QÖ®7˜„“’ç¡<É–óV€ª¬uŠ—'Ë<Ž•jtÀ=ög³{ЈnZ¶Tâ°ßZŽC5½× Fàx8:~AŸdy’%㓸kµ4 €DIú*H-#Ë º¡Ù+†BšYžj&!šÛÖ9B´½á˜Š+Ùõq±¦ÌâêËo¾|òÁé|pÑÆAj0£é Çî÷v£É¼íʶM×Bã¢43:D–m¢ÇQ‚iïÙnžR5†n€zÒ‹¦…a ,Ó/’Â<ÛqŽûb汆Mé]ÓòŽLNfY’tuï†L¶-Æì[Ç45D™Å’h[±þdºÄ KUè­0¤: Ä(«Br®abج%Ƥm+Â4Ì^ Ó1•UWaŒ°o3ó¬Q}ëx¾€‹ ¡žôœb\§ÂqmÞHˆ¡á:²U -ÇnÊŽ2S)Õ”­íYˆhÉ1¢&bºJëG°7˜)úTWµãû@vQTª h€Õ]†i/<'-)zÃ6”}ò*±}(ЊipàM⬠¥`¨ ÁQòª1,Ó¶œãvK2Ã^c´:¿<­ŠVˆVJÐV¹3±-ÝKÓƒèåÙéå~·˜c@0µ%–ª.¦mÚÎ`u·M“y¼ÃRÆÌ´›Bš¶¼ FÃ*meÍ¡Çã“‚=ÑhšÄ†áXŽ/:ÅÏÒh:;m›²'HÉÞafSw=v¾?‚@¥õq6;rÕ‰VjŒôPÙ†Ÿ$)uÍÐÞÞ=Ü?^Ÿ^\jÌ}||ø^Óôž?¨’ò‹Ÿ^ƒÿóößÕµhê|47eÑâ*‹öŽã3]§”í·[Bg ª² 3Ëé¯êúäƒÉd1>F{Ç–m-:¥a ``7/³J6uW«u’íó¨%„l¶¯ñüã¿/{þòö·Ûu‘ˆäÅí—›ÛïïÖ«ícTëù‹ŸWëâõáá_ÿ_ÿºáƒ_þöoÅößþùýÝóÑåÛ›»/~ù•á¸gøÕW_fÖ]ºìf0#©eZ¡¼G-OzÞkÐé‘lŠÜsý¢ˆ“$fˆÉ¾«Û.ôÆu“Ø»Á´,· D(%A«éTCfœ™Q¸hJ‘š·ŒPÙ)®rÛòò¨­šÜq,$hÙd:³Ê”kTW€§»’¢ÛVmSûƒA“·˜¢rÑ€ QYd]ßÃq|8b¦¾£Ô†â@q…L[/ª}«4Å +eÙ&®oɸhŠ* Ý‘Ò`Õ$UV9þWqWH!a¯ätr²ß&½’:30$Yqè!’  Ñ©¾{Ø8cWоH ¥ŠÑp¥Ñ°®kèôJ%m‹)9Ÿ>Ùìí$Ç@eŒ]Ýy#—"íöúûùùvzßõm/4j÷RÆL)¯äÉÕe²Ûu\hxŽ—ç•aèJpËö$çi¶á»NÝäÇ"v,‹Qbm³¾ÌOtfuMË“¢ý~ˈÕuå`¾eSµcl¾¼|ÜÞ÷R„ƒ À@Á^)‰ P"LoÞ\ŸžÏ…ÇíÑ4 “šDC”é!®y~õî;ùaßÕY„–Ix×éƒ@I –óåf÷ÀtÃñܦ–w7·“ÅH“¤nD[Ñ)Ó–E¬تn²˜Ë\*%Eß0ÍꩲضLª³²(ÚŽ;~Pæ9Ñh‘§Ó©át²;ÃñˆZÆ÷/¾tÆ‹®çžg·µR@´y2šœæéñfsŒWW—RHˆÁÙÅe´5J_¼üZ'lqzÙUM[7¦ë†ŽE1aôÊ &y| „9ŽÑ<Ï«pàéh†¹9¬=/ivmɳnYeô@uáhQU©€­hÔhäâc¯ i1 Ð’xûà†Ãv¹ª»Õ“‹ç×ß}#ñ™íøc®àÿ ÷Ñkiš†ùÍ_N'ßsSÕ­®ÔÕqFÃ03"`J$-:6$‚2hP€ ÐÆðÒ †å_á¥a{cÀ¦ Jâ‚)3ÍIÝ3ÝÓÕU]uëæ{òùrx¿7y¡ò<¦ksjà‹çßùɯº¿ß|ÿ7~O£ªèÀUY…ÁÀòèju›DvqSnïÞ]øƒJ´¾½»öÜ`~pÁÉ^„aÔ4¥h¤ÑâìÑÃÅ&å]?LF;m[þ$„züìù»«WQ>züt±¼_¯6£ñUª—µEIYdOž>í;ÞÈR qpp ¨É²½½¦ëÓtÛvÍÉéÉ‹GÏñSì÷‡Ç§}ßô\jaÖŽËêž ÛM¢Ûëóép:Î0s";TcÛ™¼zý¶\ò·onîV7÷ëo_ïŠ|ÙTÅ¿ùó¿ÐUq»¹9_}ýùÏÛLß|ûv±¹ùÙg_µûÝì(BµxòàøäÁ÷ž}²Úd“£cÅ î¶»}yï{IûY¶PB[žÇ5¤ÍîäáCÕƒºJµê€°‚¨GÕ}~xp”íSÞwq’£ÛÛKǶ†£yQgIœðJâOfC)ñê~süh8ã2˨§m`!Ñ {UWÅ¡_d„2ð}H𮣑ê[L‰R²ç½e3eÄv¹Lw›Ááá¯~þÕ‹÷O£$q¬A݉‚B „m]—µ†@BkØSf!ÀªºPRG~Ôõ Ì(1Àˆt\u¢Æã²2¼k/©ŠÞ ˜¨TQWÄ5‰ŸÜ^,¤ÇGgm«ú¾°‰¯¥¤öÛ]0¢¶ïwµ4ðæüjSÞN†ñ(uYÞ_]ÇCÏ÷ö“ˆÏñ0¦é¾×ûs W}+½QÔY× bQ¨0FfFIÉìq<ŠV‹[‹r!”´•9%¤kuÓåÌbŽv²€Ú(‘†Z.JÛ†W]j3Â(“D† u¹QWUeŒ&u' …l( V®Cò}Em–„^(%¥ ÃHÊ.J¼Ôƒ„Š*­}Çö,úîÕkDåd”(”„A¨!DP ^×Ùì`¢(ÓŒ9N‡}«¤–o)’qxyÅh=)UºN=ßv‹@¯íÚ¶IOOžôBÖyáY¾E}€Q@ eQæÑ.Í1ƒñÐAÎju9žÎ´–„A¦€àܨçùi¶»¾¼xòü£Ín- ÖJF)µ0ÐuQ;ž5?yôîÛoÂ$p]_q²[/}?Ô’¸QP]ÕèÁ(‚Â4e©…ó¶hâmÙ †3ˆa¾Y¹¾ïz‘r·ßºžÛUõp:YmU‘ƒ±a2Ýf4pÀ­‹º×yô~׿«ÕåÉÁƒ86mµº¿8<~ÔÔ\´ªÎsPŒoî—F©0ØÄVBÆQ"´ˆÂd¿Ùßߟ=T=yùò~U<5È®òŠDØ¢ ÁøvqñâƒßHbïó/~ê»×qÃa(Œâ¢ÏÒúèôÁzµoû~4Nú^B•h,Ë}s·º¼[ÜM&“¾óá±c/ò °°n=+ “IÙ,Aí P¸/ÖùуSËÆ¡…ø¬‹étŠÿã¿ÿÚz¾­:“eí{$ATít/ÊïN~Ðt*y. ¡ß;$s½\GG“ùß~ñÅ?ü£gÃ÷]ßßW[ìŠa’yZ¥ÛýÁÁ˜ «md%³Ùì¨J{€8o*Ïv]וaB™SgA!Í[-–V`GÁHJ-Uƒ4ôBŸ‹†ZIVlœ˜…N°ÎVmWžÌË2+˳C!:ÇóË¢k»2ˆBœºÈÇ1ÕM#M‹´m 0H¶¹lúêää8]—E#*ÊœïÒT©ÖæÓg= “èþúPm»¶ìz%k‚PS)EŒ¼«[Û÷¥áD „©1ÑJÀ"b îU¥q\×Ù•Âòl¥MªÉ‰’dX7m^¦ µ¡eµö¨ßpéÆ60xŸ—Fµƒ`R·mžïb?é…Y,ï.Þ¼ùæjIúî'ßÙ-W–˦€Ö}#±eŒÐuÛø *ó¦å•׊¶»µç;¾WU9<ˆïßÝn¶«““ d±XÌ&‰Å|)s(¯¹m¹˜!Þé^È(u/””ŒYÀ`fYBvPiŒ)¥L÷3Š ÚÔ5ÇXaˆ1uòýFõýðà¸oKÄ(o:¬%µ^#+? €BY±r|K„]¦Mƒ è´€]¾z÷7?ú«g öwÛmU5Wo.y×GÓ¶n˜P‚묦 %ÃÁöÂO`± IDAT>kŒNÆ¢jEe“Be3®ËË…í8ÏÖË%Èv(ư*JDu]u£Ù¼Ý~½ƒ»£$,û½ÅÃG}–¯“ñÃó ˆ1B¹–Ï[^¦åáñ“Íæ>]§Œ³ƒ£õrãEqUn1DóÙáíÍkñx2©ÛâêüíñÉ1 (Ê<…»Ý®­Ë‡ï=ÖªWBfdi¥EÏëZ¸aÐ+^dY ”2¾í6·1J"‰t¶^XÌŸœ>ªvHßóÉh‚$n»ZŠ~˜ U¯ò2³m—„I³Œb‘çnYmµÐQqY‹N Œ 0Amx¶ßÌgÇĦ¼ï<>˜eÓ×Ü ,±ïÆ‹Å!m'ðºΌA?°°†RWe=™ ARuº—“ùQÖí!Bæ:ŒàÕâŽ:þx|PæY¾_=8=å¢üo;+°<;Ä_½{8ÁÃGïî®"š0tþâ¯ÿ¿Û»õƒùÓƒãƒ"m»Ý.ˆ‘.oõÅÏŸ=óCYvšæ„@ßó罄"f#Õk ôzw›LfZýnA=zxV•û¦”Žgw}í[îêîcêCeÌfw7HæÀ!Ú®ç›ûÕx6ÅŒíV; ÕÁìd»½Õ¢cÔv]Ëp{³‚sÞ~üñ§çï~bŒ¦PC pBr½º©²óýßýöYª¤áH¤{AzÈ5ÀB»žc]Ü^3lÇaÀg»Ú Fê:¡ï7붯'\.oW»ýz³1ÄhÞ+ØÝå—ŽæZÁË«óÀ¦ã‰4|³ØÄɸjZºy¹/Aç˦N–î‰åzAïVa<Ü­Ö–mEÉh·ÙÝß^ÄAüæúf8O~ð;¿1ІÑÍjC°ǘXËÅåp"j×mÕ· †ÀH€yúäé³b¿ÂÿÝ?ûo¾÷Þ£“÷çG£?þ§ÿd¼÷ìÁ÷~ë7ßøñÇ¿ûüé³'g|÷w?ýÓÿöŸ§wÕƒ÷ŸL†¾¬ëëÕýÉðd~|4Ÿ4U›¥ÛÉáub¹Øj¬?þè{oß¼±=#l,».JDt«ú 4ew·:<`ª²ÏëÕ0å”Í®©cÇ·ú¶TŠ4¼Œ§È»²)vË[ßö…ÖY¶qmßü¶.xg,×éEc¡`Wä˜J HÓ6qJ!;¥yÛõ’ðaäi/±f±X«h8½Ymî²twy¹*yþ›¿û"ñ§·÷—ï=~L;’çµ3QÙ–í:‘Ûå ‹«½ÅûØ­ª\ÛB,y¶·}jSRå}S7“ÙP¶Q(xN±í„NQ¥0Û÷ J¢0Š â¶q%8ïühdQ a­$ò½DŽ©•í÷RtQ4Ì‚Ð÷ƒH+±/6Q4¯ªBˆí¹¡DÁpqwg{ö(¶eÇlBƒ’[aNp}þöøéäøà¸k¸Â$ ±¤–]å¹=çUYÇ£ÐqÞ*€ 4`„-Ó–9a>ï(,)°í„-¡ŒIbY‰R¼©LÜh—ë­Ã¬–×¾câÙŠaÛsƒ¾oÓ<‡]×@!”eScDqYGŒÓm«hÛõb÷äÅû€˜ñhXµY–î£d¤ Ù¦õ0 0µ»® “õjD ±¼*¯¥ãáA{»Ü%AD±mvS·EÖ¥§Ç£¦k¶ëõì`º¾F¤¨Ö¶X­»ªiÊ0JŒæJk)ÕppØue™íæfûë׮أ°ï[#TÙg@šÄ@¢/ß¼œ¦ºª„šØ¾oQ*¹]#úæÑãgeµ#”8~” <Þ•e–RlÛ¨êN2Œ¡Íj&>¥”ûúú›àéììzqé†þ0õØtÕ.‰¼´('ó¾n®¯.CÏw]»*Û®n¦Ó¡’ÆaNQl]SÊ0Ѽ­|ߥÌëÚ[ˆ‹&NÆMW÷]A™wu×të{HLÜÍê2áø.!p»Û&ã ¦}Þ/5·„ƒá¨çc-E?=\¯oÚ®1 º~’çyß5È¢¾ïA¥Òm6™:Œöm©y7˜Ž»Nx–¿ÊVPé£Ã³Åâfµ\1Ëÿè“ïVe:Í뢦 ;ó7ŸyÄùÏþóÀˆýÅçŸ=}ñŠ©£¸XÝnOOÝ€¥ë=Á4‰¢6¯!¶hãp,š¾á­Ðj~xÔ¦›åÝb6! ×m—æ;Ë"ù¾‰ãÑýâ&ކŽOšªÀøÁ0]§j)ÕÁø,¯w}SL†GAä7m­ 7C„±¶oï/={OµàÕ·ïzÃ?{¬”Ä,7·½R}ôÉòn÷³ÿòÁéô7ðÛ_|ù9*/ E­ããÇo¿ýÚrÉ`˜4eþöõ¯½÷ÐÂvÓVûtG5žž2Õyn¤œÏV·›²,ã?qØ CUòùdÖ÷}½M=~Ú4¥:·iU÷ïV8Î÷÷¾N&M™úN"%˜Œ‚ ^sÙ·CêúvU­x%¸¯Þ¾œÍŸ>}è9ñj¹™M˯ÓÊ@é±Ö2D0!”Oš¼N³‚zîÁìt·]»^ŒÿäOþ˜Pèúöà`"EaL3šÎ<[6[­îã¡ãCÑó‹ó¯NONn/nùæWi–bÌ´BIèÞp::›<8{%Tù¡Nïï¿ñ]Gp„ jöér¹"µˆ®R©ÛÓãÓëw·˜ê¶íñÜÈβ]™ïÃAøÃÕÝ‹C£”¸íÚªâŠØ“aÒqSõx>ç]ßd³HàGuG †]UÚŽïxÖ~—!DÝÀJµ%§¶+DG-ÓÊCËõT@J,ŒŒ‘m‘uûÅÆöœíj?J“ñà`ò°lRÎ;ÏOvÅÚóBÙ‹}¾ ÂЦÎvs B%a«³±ì©Úöì*ë²4ŒcÍ‘VÚõ]Ï ê23Ðô­ÂØŠ¢Áön‹¶-*݋ޱà3*UÕìÓh6S¦“¼‘ªõl‹PÆU›ç[É¥(Í·¡; Òé¶@0Ërd—­Û®Læ\¶UV ª:«ÂÁ¬j2ËTUU‘V“ÑIYlï®ï]Ü/ˆQ4ˆÆ‡Ùæ>ö¢^#/Šfñðæê’YæøèD4¦ùt2m«ÞŽ<ŒU‘÷³Ã™o£íbcÛÖìèpw·4úž©¥‘v)®Òʉ}Ïó÷E3™N7à\õ¦‚†èa‹FGG›®èf˜"‡†èª*²=ÏOn.n÷iúé'Îç‰Q’@ ‘bˆøþh³¿bŽzÙô-w‚ Ó#.¦$/7Éh^·Í~¿ðl0nóÔóD1D°’2‹PêxÑòþ>L¼ž ΥƘB0TR* '§‡¼¨ÚšCL\;Ä8,ë=зjËÍj‹ #o2>hZQ{ ,;²Ót›ï9õˆM ±¦F40#ú.Œg]_gûM 3}_cì#¦€³ñ1W…RÒrâ^·¢ë0²05Hm9BYŽ/D¥{e»!Øcnží!0LDß»®£¤¤ÔF˜»õìàHHT¤[jc×÷yÛiŒ»:3F ¦ÇMSµ]C±e;Þr·,Ëöå·__/¿|ýîåW·º¸ûóêË·?ùì3¨Íg¿øÙë‹/¿øñ·Ï~È,K(n¸ &\ð¦*(fB4Zé¾ï Ø ×õn®ÞhMf=ÏE׿X6¼…˜íó}ìGmÕw}Ã,æ0G‚¾-+! ¡d”l7kDµ#FX™mýÐÇØæ¼J.’á!¥^ß–u^>8^Ü®¶«½ãYÆÀÈÞ/.‚ŽçQpy~aÙŽxZhAYæ6±!0U]µm7œN´RuU+dƒ!èFª®J?™¤Û»dõF2 Ó}f¹Ô(ú£4Ûˆ¾9˜·BÔm£„™Ìf]]@¤–å¸n˜W©ì„zˆR^Tʰãxûý¦ië8#7»]àZ^4TZ9õMëÇÆFŠõr3=>p˜õ×?þËj‘͇‡ó,;y³Ú¶¿÷ŸüáæöäEaß ­eQ×ñmËÝgËùÉ !oÄp6êºR!6dùÒõBJ)&¦HËÀ ˆeŒ67w Jåüà4+ŠF”uÕY§mÆ?HægOŽ‘!¯Ï¿žÌ\?¦ØÿÑg5›Œ'‡žK÷»½À#ßówû|:=Êö;FçÒ € EĬ7ëÉÁÜ÷Ãó‹óh±gÙƒ4](£µ€ÉpÜwu“•ƒÙ @Ô–¥6ýxrÀ;Q6õn»<˜Îª¢ÌöklÙ?¤ØY/Vê‹«óçïïÝ˯Ã(vÈü»ÅúøøÌ·ø7¯¾hÊn8€g§ÏW­,²,?œfEÆ[C˜%`ïÐð~µiºìh~ºãÏ_þôÁñœ"Ëöü^ô«õ6J"ŒÐõÍ¢åüÅ‹ÓÕÊr˜BÐIBDZ•VtÎ}øì£_þô'³éd”ˆË6u™Ã;>pÐTù~³9<>pÝí6„Z¶Ëx×QbC`€AÚ); ±,Ù÷JK£%È`˜¥u±-ƒ´à-µ"CŒÖB[(!”€Ð2˜k “áQ¶_"D|w ú½o³®e¹Âm‡ëÕÅp4ñ=¯ëjDèêîÕ_ÿÝ¿yù‹Õõëô`6¸>o±=9üø;/¾÷êÝ·›ÛôújYoÏ‚xDWðFrÎ,P¦•í]_XÌ æy½ÏÓÝp<O]Q1ìh#-âõu§@+•”îÓ]éyå£PS5nàx–ǘ]»éÁ¤ã\ô-¦é*7H4—mSsÉç‡G·‹í„Ý+Ë ÜÀo0˜œ_|;™Œ&“ƒ¾ª›® Æ@.Z M™íÓIË»¾å˜p8Ú/—ÐJ©ë:â¶)´1aI©¯®Ï'³¤o;eP§k ëŒƒ›Í!zx:ÛovRHLà„B‘v¦×~8TÆÙ>p„…¤)r'p)Á@£¬H]ŸÅñ¨«[J‘ÑÆ±e„¢Ìö“éqUWY¶³lâzø~½I›jÅŸüæ‹Ë»»Ví>y4;:Úg×Ê]-vo,ì𺋣ØõœºmE/ÆÓñÝÝD6„DI£Lv]Çtsu;==ɶ÷J·QrÜóR›ÆH%£º.Û-ó*L.õÏ¿}éXt29È«–×ù(‰–ËÛñhÒw„`290RÝÜž»‘›Dãl»æ¼\XÌjyÝÔeQ÷§O«]–íóñ8à\t][ó”!¯îd^ïýõ«gÏ?ÍFÛå’ 3C™©)¹¼øæê÷ÿ࿸¹½»|óƶÃpvU™¶;ꡞע•׫›ÑxŒv-²Û”±‚ ðƒ¤R‚îp~º¾»ÞíWÈ¡£ùYÙÝkÀ·›tr6ÅÑ·_Ÿ‡#xÖåÅÝ«óŸ=|x {‘»ªªãd0m®µªž­n×IDL× ïú«7ç–‹o¯oïÓì;Ÿ¾øßþAÛȆï†ÉH(€ 2BkC†P›,ï,—f]_\[Ž …Šâ©]ÛtøþËܵ‚PŠ1b¶Œî”Ì à&-ãqL)Ón7ëÉxèxþ:_}ýòõátbàFÝ!¤h<œgÛTÙU}<˜¦ëK-ËsÂAؤR}”D2©äòþúäàR[tê»Ð ÒRhÞsê $šWÕ®ãY2˜DƒdqîPOÑs¡%ËêÈ÷‡E³nêæ`vT÷’ˆ·"ŠB¹iyM0ÖÆªg6ÕF{>Ýí6 0°¢y±u]‹a«,÷½lÒÕ¢ƒðjñöáñ´êŠÉxf^®nFãˆeQxް¨ë.LÆMµ•ZRlAï t\Û2F6›•kyè¦áMÃ-×–B…Z© ¦ûµÑ3¦´ªëÞqCÑw¶ë{Ô^mn0='lê jè'qÇ+%€ÖªµÖb±‹Ã0]ÛÍó}è…ÊÈt†!ˆ ãzwW—d0Ìv©íX]ÛI¡¼$î÷+¨QöëcDhÂ…Ä¡³x×TEi¹.a¸)Z¤™f« aÒ·u¦”aÐZª^jl¤ÄMöÅJ N &6.vk-%¢ÀdYÑýí[D}f ¤î„nwÜw54 íD'òa0y÷îú—Ÿmg:šfÀüÁ?üGßÿî'Ož?vcx=><œ­¶wÛí~ßî~çï_ ijó D-Ï ÂÅò* âx0ýöͯà dŒ5]ÓmÙN™¶oK#¯®®†³„YvºØJ€ü$ä5‡”¦ÙÚ¦b¨k˾Q¶ï`뢱-” Ãé:ÍzÑ8ŽïyÞÕå¹$Ì&¼/m+ºº:w£eÙUµÊöÛã£3JPÝ”b•ëļi›¾„LƇ«ÕBöMʶkyÛ÷¡Ôbžç¯_ÇÙ.ïEb£Á¸ÈRÍûã³§÷7—u“OGã0Ù†ZvWw^èSêù>øŽÍš¦¼KÑš÷BÊ’Ù.ÁT(ÑòÎËÁMYa싾ð£Dõ¨(7Z£ápÖñ:ÏóÓã³}ssßÿìÿú?þü—_½kù7w—é¿þì_ºÓ³ëw/ùÅ/¯.oÿý_þt—?ÿÅ_üõ_}qxüàƒŸ–yZU…ã…À€¦)¨e9Ì£6 ˜î–«Ñ|¬{X}ÝÕ³q' Ò†@6<ž]}ûŠw*H¼££Ãt±³Ë÷ØvµHË‚AÄÌfÑv—D/«¦ Ží:ÁãÛ†¹(Nvû DFHéEQÕ4MÛ8ž8cÔ6½˜MΚš®Vžë-‹Mµ\/m—ÄÑ8Ûç–à  †8J@›ºªFóiWw—Wï¢ÉØu»»k{ Æ‹åÒNoÞ-y_DáØï³Ïüüƒƒqðàßýø¯â$ÈóJ¶¹zùùO¿X,Ÿ<ýøöz±¸¿xòü¹ì”–|ÝÅQ›ڂû‹›d4†‹Û…j|xj¸€YFFã»Å»»Ë»]–!¤V‹Û¾e·ÖJ®ç‹õ»Ï>åYWò}ºÍ°oï.Ò}~þòüæv9?˜\½»nDg9(LF÷w—I8 Ž_«Ü(Àó.œøRt?úÑÏ7ù6ôbÞŠ£Ó©E)aÊaLô2N–Þ^߃±HËEº_&þ4ß–ó³ißt—ïnŽâ?þã?Ñ@¹Ä† ïºÖr"ËAšb·÷1ÔK½Ù.Ÿ<}ϵíWo_Þ¿Ûb@Z‘icžŸ> É‹g~{õñYN˜ëÜÝ~ëþ`c ¶\îv›dà3ËIó´ëøãç÷›52}4ˆ¨ã3jõ²ì¹°¼À ½‹o_¹Žë96@˜wFbê;I/y[µ³Ã š¢n²ß2@B™SjEaRd[D]H¼—ˆ:Œ·•OÝýví:–ŽººŠ3â@…4 8Ùj¡¡np°xûí{/ÞûÎG¿]—%68NÆe“»öCU–ÅNÄÛÕeO]×ç¼³ˆÅûÛ#¬®ÛºíÆ“AžÕ­Ä®KlÛEØú™6¤Œ¸v™e”ÙÌ¦Ò a¬p`ÅmW”Eq|z*D)¥p]Géj¬zÝô;dqœÏ¿ùU•|üAÛ¼¨; ˜GmàÜÝÝÐñDˆºïª("„ÒýÎ÷ÃÝ~ã¾k9×WoµÔ€®î É``´IFC@Û¾ccJ³tç¹¶m×"cxÓÙÌI-›¦ă¾m][ŽÝVƒ–†¢.!ŽíÐÝâ.ðÆ–ƒ»²&Ôkº"òÀüžWå~=™ŸH¥”ÚÆa.¥¶è«¶éƒÃ»ÝÅ®l«´&@xÎð7~ë·NŸ>H|g³¾“ÏŽgñ0ÀÆ¿<ÿöñáY<ØŽ—¯w³ÓÇXÃÍn¨±l·o@™‡‡ÇMÞxn,DßlöŽïÇãáíÍ¥üù‹O6ë[±‚Ȧ¢LK¹Ë w8¤Pf»½ãxĶ0t²b„þh|X¤KËõ‡Ã¨­ò4Í¡-Â0lÒ3•g‹>’¢[ܽ¥–c‚tµ+5‚(ÇŽW÷· Ç ×/ʽÙ´ïó,/x¿{øôa]t×›—»lsð`rSÞºnXó&³q8}ûò•?:Þü~s<ÅM#[!eSr×õ¢(Þ¯v‹Åòñ³gÛûM¶I=‡j ÙË^lVqÛµË4GS¹ÔÍÒ=¦”óÆö½¦lº¦òFC­eçe™žgùv›×ÿëÿô¿UÛïö_þäîn¿Ò½ûâׯoîOÃ3&£Ùéá—ûåÅËÒ6Tt‹´Gƒ0˜J]{žÝV¥Tð®ªú¼,§§³*ﺶFYž_VM±ÍdÇÝÐõÃéù—_L&Ó÷¿¾Ü.–ï=&•nM¹½]ð|øÉó<­Î¿:‡>øèãçûM±.Ö¢¯lì†q¤…yŽg3t›;¾K1–œJÕk1dRÓ©²ÉGGGyžw}×òz†î³<'f“Áp°^ÜާŠIÛq.Ïwm;\¬n{ ŽŽŸY^µ{#ú0œ ¥m/¼¹xóøÙ©NV”˜[Å?þ쳃¡ÿÞäTBøðÑ{]Ñ#/øô“ÿçßþÙñÑéw¾ÿ{—Ë»çˆFØ,L‚@uðâêêÉóÇ@€ó7ßFñ¼˜YÎj{>Ì-l¦ñ~»ÑJS×Ùܬۺ§ƒÕ»%¬äõ»×û~øíå/.ß]tÌ´›Õ¦¬*¶ëüâËŸLãÅÝ%Ôê—_ÿ²ÞCÛGEÙÜÞ¤7·¿>~ð4-›uy÷êÍ»¢R´§ãÁÙüÙ`6-—b!× ›Jµ"÷ã¤l[ׇ²æeÝù‰„I¾O)çgï¿þõ×øŸþWÿµì%·ÒO" °mJæøˆ4]K©âd\íÓûÕ­Äøó_ü]àG‹íÎèþÅûŸ~øâ“/¾þ»ƒƒiœŒÓtÓW@$É>M‹šï6Ë?ø8/ʺ*(Á~<Ô¦2¢K÷$ IDAT 2æ Ç_.Þ9ÔJ’!µÈn»t<j§éÓ²ì|Ï/»¢Ìk×s‡Éþn‹)•ªÁRù^XV©è{Ç¢ŒÑåbƃàJ -uë‡$ú ‘„¹°É2‚}€8¡Œ»nv`ʆ¯^%Š…Q*¶'£É8K3ì d l¹¹ÁF“²N»¢c,ÀLkÑSÍò6ŽFuÚ´MíºŽÅXo$¢®èCÆsƒ}º |Ï÷܆7}ß8Q L-$Û2 C ´lZ„ ? òUN)CXñ®ýçi‘VQ84¸¿=¿æÔ„=œ»jšT€‚ÚÔs[‹KiFq[·ÂôƘ8š ¤ªý>ˆçôŠ+‚íZgÏI6ë£4Fm]`H€4BJbÙP¢¶m¼ $÷}‡ ÆÈ®«ZJ`4nû: eY)†=ÏçUÛT¥ë0%MÏE†ëÕÊ¢e³¦¨1F^b7Y©ÆTð®±Üažm1ДºˆšåÍb8ÞùÛwW7‹Èï÷~Ÿ¸¬oöu-‚Á¬Ê×0+ ›,½_¾ÍNÇã‰Ï<¥š}v9õ=÷#¿Ðu$Ŷ©¨§ϳ|ÛT©c‡®ïÒ[ X•—Q!M×»;ǧ®ô}ß6«ÈÈNº Ù,WR'°´·×7ÞÀóýx»^:ž-9O¢)@¦kEY¥ÇO›²^,ï&ój´ jwÚHfÅNàíV÷6s“Qˆ)‹>«—Ä#EVçe~}óíx~üùË/n^Ÿ¿»_.–b¹zûÓ/~Ñf]¯îÊ\Þ,ïHµ2]“im,Ø‚ˆ¬6›“£e–×uÅ\wœÌwû%¥Ô 9c‹7=¶¬áxf”ÚåËù|&”é…`êÞ ËõB¯ØçMÃÇó¼*òÒñd:M³\uñæþ›¯^>œÆW Û§£x`³ÐŠ’ñ?ÿ/ß}ÿ7>ú{ðüÃVõïð~±nînoŸô¡ì°n›Ð‹ÚŠsÅ-âøÁ`—ÞC }Øi0ìëz8>p=GI½]­Ng –Ë{¥µd4ê>=ÿú Qï?üáÍÅõÛË‹a2ûàÙGR×-o ´Ëzÿìù³åýF38Ï ±ï7GR%[DZšœ'Ó¨:#©A"‡—ç÷½jÏ÷­Àƒ<»³iÄUï†á?ý»ÙÑQ¼á `´ãFJõMWõ\Mæ‡éúF4Bj5ˆ¢TÌc@õóñIQí[•ž=~¡Bœ_¾úá8šÌKÞ\ûxx”×Ùrÿ’‚àÿÓÌ‹Ûá`Xî÷“ÃЋïW×ñÈDÃÝ:]íö¹}[Œg“»»›ª“ÇàûÅuœDQ0Z¬ï"?PœÇ‡g"+vÛ‚cø½ï}OJÒh~0Mª]­ mv}½Ñ„Õ\þèG¿8;}á:Öò~¹Ù”Yµˆ]Þ´|}y5;9Þ•«Õý®Þvˆý¦¢ŸÏ?ùô£^ë]¹L˜ciØ…°Å¤î „û]ê¸n`ëýFmaJ,Öty„øþÉ€h„¶YõU3ŽBççç2æˆê´ãƒ,øòÕËØ 'ÙÅ,‡ÑÁ8`.*îL r><Ü®¶ÀF> NŽÏÒlG s½Ð¨žB´XîÆói`ùJšÕæršÌ€B¼Í!@‚ñpf´Èò1úèèÁÝâšbæØ‘1]Ì\ PU–ãñcûâÝùì`†0âE#¤Ž’‰áC£¥{®Ë¹Ä8®òýdqoH$$@Öen{1±ÔåÛWUV%G㯾üÕÓ÷œÐq™7Œ&ÊLß’²Ïsß²iL}/.ÓÒ³l׊j4 ¡ 2¦ë:/rCÛV ï²ýl2c˜ØSJÚºq)­E ±Š“A‘î—ù¶k  ˜@@…Ô„aŒh•¦qFÑØhÔ6U×uo^ŸNGg''’‹( V‹%†6 Ò¶XÓjÇ‹es…ëÕí,˲畴ÒÒ´ã4eäÍ$Tu]Dáˆ8¦¯[ËM ½V¦£(žKÝ--ÛmEïº^Ï{ì¹¾ëBC…þÀGÐ}mÛ”°aì†X*>?=QÜPfâAPµcÛÌñˬ .a޽¼¾e„:~Ôs®Lg‚Ör±\.Îß^ýàÿÞÃG3ž–Ñùééíõ¥çø¶Ï´!Ûææ—?ÿòñóžœ=ë9_.ãÉ‘è:˲¥ÌÑi–7íP2HFÛí³%!Œs!eãx–㌫ºT¦f@suS F ÁØÂî›oΣ¡?&»Ý>ˆm(±E½ºÛ»ŽÛÕd6.×ûñƒÓƒƒÉ~ÑhÓŸÖûb0æYÑÕüèô‘`w·HFq&ûý–0¨5îºê/ÿò_òº»¾¼ø×ÿêo¿ùÕë§gOÜÇånµ½kTå½{óÍj¿ÿõg¿|ñøE<£»œ»¾ç£¾â"©ø£G/noïQ–ç+ƒë:ÓÆX„¸œ§Û}41†ZÉ´ÝÆÑ`¹¸·,(…ax®·_¥BòÁ( ƒázuúÑ…E ÉÚ®îãþæ›/_¿¾|rvØ42+²ëÓñ?þoEShZHÑteñûð;®²n¿¹üìƒÇϰï@ct'ý0á}#%÷£2P—ä`z0Ò(­»j¹.BX€¦oûÑdŽ©Ú.î]Û]-î?~ÚuíÕõ¹Tä»ÿðöþ]Vîf‡Âð 0Fa8ð·Ì›í~;=8àe§§ è`FÛ² ˜£&ÃÃåý­ë@ÛñF Â, !¦`¯¿þÒ‡¶íåë"çÅÉщÁ=¦ï©AJ¾Ym0Â'ǧˋ[€ŒøÔ<Û1°ã`¤,›îÓO¾³[ßj Ú*wtO'gLK Ýñ|~ñÕ¯gã1ïúó‹o¤’óÑ0°Ñt>ox›f»'›&½\+Ï!¢ñƒøíÕÍÉÉÜ"† áø†0IY¹/¶ùÝbóðáé»—UW=ýàÙl~X‰uÑnhk/W7O?|ñóŸþâìáÉÑÑ£z[^/Þ|ðéweÖ¼zóõ(\ߟn¶«*ïÒrýèè(ͳûÅmÛÕòâò¼í¡Ï˜; ò´©Ôƒ³÷švÇ0ÀD±k¤©ëåÐ ÄEºË·EÍËxSM;^[ãö§*§YÔâ­ Ž¾heÝÕóM½÷l7JâVèûg=§ƒèüæÊ= g'ïÈ6«­ãÙ@¡éÑÑùÅ뺪ãñжYYÔ}×Äèo†°ÈwÑô!„²­riP›ºç5ï-FÃp¾Þn†ÉpŽˆ¥;?B 0.!7÷7á ½°È‹–ׇóGyºAdwR`l«¾KÓ-þÿI²¯_ÛîÃ@Ì¿ºzÛ{í~z½ý²K%’’(Ƕ¤häÇŽ=1ä%ƒÌ`‡<æ}€“8ÆhÆöزÆ2e‘²(ФX./o¿÷ô²ÏÙ}ïÕ{ù­<äû7>Žõ†b–çÁ¼H)(¯ˆŽ•EVèÃ_|øüÏW:WÚ[r§eÞºõÕ—^¹‚JíÁ‹¥¶iÖEzKu+b4£pŽ)­`6äÑѦBs¹ÅŠ2öCÕä5Q­ ’Øs|Mn•U\ä%+!/¬Èí¹KÒT•§Âl>•£BV„EK‚ä‡1åQUä{Ï6¶vó4M'?üé?4šfìG„£I6:ë;¯¬%ž[T' M½³üD«k«­•ÁÙâdpÿæîó¦Ùä(„QØé¶]ÇBF8Ü0Z¡ëð —¥YÍ4)¥ŽcÉ’¤Hj™ýñ Ûi»óEQ IíÉ¥¦´6vVíù… È‚&ÌFÓ,My…¶›mXV k<>;ïvW¡ƒ¡ªiˆgÖÇÓ±Z(F•ýÒŽã” —”Âñ`Ή€%ÕxtveçV•k:’ åTYçaWYwzËã~ߨ©:§ñHðGUŲ¢,aU¤nØîÖÃÐsÜ0ÇÅÕ›ý£~U•€TR(ƒ?øÇÝÚRPix°ßÞZ‚r¢´øhW½ÝÜXe0wg>,ot¢0% GežbÄË9'É?[ZÚ©1 s2QòDÍ3txô´µ´$ ²ëEÂ<<ÜXÛ‰<;ŠÓÁürgój•–ç³£µUS×Ïd™t;™k}ë›ßœ©¨ÞØÝL0gY¨f£Ål~ÙÈ¢š%Eû;›W¯\¹:<¤©«ÕëPË’0ŽpTèùñ©Qk…a˜'qù—ç5µ!ˆ†IZ9Û\^®0ˆ‹¢*!DáÈxp"‹¢ÑìôÏŽ½ ßXR ‡qš¸ãtsw7p<{>'¢ ×äÃGOŠ2_ßÜÌ‚˜£BɲյÍ$+ªªt»»²‰AäÏÏI á¨Z‚DâPMЙ(áyY(§”§R©È‚¡×+ÌœÄÛ¹r“Á8ƒ©(êZ­ž”¡"«ƒF½f·Ì=NšQÇ8‹‚9%ãRÒåªàâ8’5ͶBkañ•³,+QSŠsTΜ «n][ã²æ+-Z€ª¨x‰«RÌR¤ê†¿ä:½Fž0VÂ! Ä8ÎãÀÙ¦v„+‘° Q§X€yž ¢Â¸räù0‹²Œa, §•Œ‹ ¯·ºä;‘Ù<Õ²ÌE°JÓ¼$®ÄÓ³g§YâwêH3ç4ÍŠ¼À)L*gAQ3Uƒ( F†Þ˜Û.¯ó‚,–˜r `e‹ªÞ2ò°~ôˆ3´ºiŒ/û¼ÀCPTY¦ŽLæ‹i­Q³#Û²”Tœ“(qùÒr‡U“ª?8åØÏ*Ûóbˆa™•eU¸öâÊö­ÑtD.®ÈîÆ./JP–æ,¨|ô‹%Y‰J1²’±$i–r·¼þ\÷ɳó¸Ha–¨h4;“aŸ8sTà‘fEä8¶Ùjæ9;8Üë.·Ê¼``UÖjv1¦CË™…e±råz^–e†TM1rt®jºï¹Ëí¥²d“ÙD’¤Í $öbÑYîy"ÌÝ ‘"P”Iæ•EÁÉ8pì,Î|ßZZß*ã<Î}JñÚÚ­0ã4Sk-;ö–Ý`²@0iuUP­Éy»³”§ Ò ó$p½ZÃ@ÆnT¦é•Û×…“&Â"Ž€eM( "º®^½qkp6¿öB[©7_ÌF§uÓ€Ðh™Kæòþãùµ·¶ƒ…»˜E%!îÊ|jg¤*A¥Ë5* £þE–¬b-]úðY£»‚1‘%5Œ}^uµ•¾çN%Yª7jƒãcRH¡—^ß}2~:_`ŠzíÍ,†óQÛl{¡½²Õ[œ)f5C^Ö—ž<ît[ëë;ck°sójO59B;Í.ËÙd1^íuC?"(¿²´^§’½˜óå…F¤^¯û [–%MáA â4\^]F€P‘^î¶¶v – ñïÿΑÅÁT¤æYVz®+j¼Èéƒñ€ãh³Õ).–z=7rR.Ÿ~ªÈJS[±í1!øÍ·¾ýôÙ#"AŽã)&aâaL=ÛÙÜ]™ÍæåmC’ùÀOÒ2h™MÏ E±ç“ ÓlÅ¡?_LŒf‹#0“ªb;3jT¬Ì`ív/ò]ˆhÆ,Á|~)©(ŽÏcÇ¿” ’ðY?ƒÜG$tœó´fð"1æÎTQxŽðQœV¸*ÌÊL6¤Ùhzvy¶ûÜÍžJZscmµ*Q‚®Nœå™ÙÖ˼ÌÒ@ÕÄ"'{¬Ê|hÇœˆ ª†ý•¡¢ðZ‰­Êbž”˜¢ŠeE^²*Á´,2È œ,‹@Ž£œX2¦Ê<Ř9/pYQ ²ŽÆy ª¡ªÈX’'§g§º\·­¹¦K­V’åaû~"‹*‰.7¢0 <å WU•›º à½ÿññÑñeC¤½úrS¯kf= }A¡‚ 2(L'ÛׯdN>Ÿ ‰‚ªªŒQGq¥•µáé ©›q^ì <•±ÀXWÑ袽¾,ó”hnÙå:„jšE²†9*ÕuÓ ¦eQ <ÇKàôð²ÙjbHÅ ‚äø ^PxQNªd:Ôí”%‰ë1ˆdYÐÔZú)K£0êµz?üÛ¿MA„eM—ê °ue'Ï|óõïýÕ¿ÿ¡my;ËWSVz#Ísۚ䤸víÆ¿ú_ÿ·?úã߯ª*Ï^R'£ åE*bžI¿úè+×7I):Î|4;]n´yIRuYD$˳foy1ž†±ŸÅYݬ[¶Åó\^ÑõÍõ å“éüæÍç«iMDùW^yY¬Ì•î¦(WvomooJ ÑR6»+ÚúVïéã#Õ40ò¯o¼PI‰ï¤Ëõ­U}ûÙÙ^U¼( ^|ív‘eªjÄI’Ei³ÛLB? r" iqbk/Nö%nÖè­ .N!£I–ãòíïC€E‰‚ŠxAP±œÇ"¬à|q^¯µJVAÂ\Ë­›Í¢Ê Æïüøý¤-],fÍeùk_úÖòÊêÑÑC‰—}×]ÚèÆŽë¹V§Ý5Tc:ű·µtuæÍÊ*ˆ“£² L'³FÛàˆ2ôNU©‘—8N-C×|;Ôõ$ÍÝi`öjæ#»"zbÈúd¾pQñó¾(ãÔqO/.çg®ÿêÑ…u¾÷ô|¿¿9;žŽæãé!Ñ‹‹Ñe·Ñ\I0Ÿå„á\ä BºaàR$]ŽÏìÅtsy}ûÊ•¢(²¨L³H–DEÔ\gA Aûbɘ¨ð±—MÇ“îR§ÊpF²&ÑJRWWµ(ˆ+’šÖtbçefh’=FƒSYÕʼ¨`‚a™Æ’¨fˆ¾,ìY§[+Ó‰”±ÄñT+X…óPÒ$¢þñù+_y…0%úål¨z¯±$j|De•'$A‰ §9æ(^³¾ŽÎòX¡r ³Ùâ\Ⴒ@dµ6™ÌJEÑx‰C‚ —æå4‰©ˆ1ˬÌQÚl.…ÃÊB>I=µV#$y(‹,èÑÉI»ÛÆ„Ð5#/ʸ¨…†qFI­mf~´p=ÆE£8æ$1 ÃTª)={ø8«* ÙÅôøü¢Ì¥ùÈ—Ôj0½@LŠR÷óŸNûÊÅÈϳҿºs-eNÓlÆ9Ḩ  * DeÂY‹ò@ëãÑKXUÉ{GÏ Ó0¤Æ|6—i1×Ì:¨ª²ãáy§ÛË‚(lÆB¢(pI³‚%IX3§ûOÃ>ô“‚•’ªeÎ {Ð?웽žëZï?<|" éٓϰ<ÿðƒƒÕf/MCÂsU\¾üÜí™ÛÏqÜn6N/Oú” Ê Æ ½úƒÓ׿ùb]oä9LÓ¤f6B?Æä¬l÷6ÜùÄqåB\²œç%Óìž|ÞÐêu³W²ìøéÞε„pš^wÝÙÂ]Y¿áz^à9¶¹ÜÛ´ç3@QQìõÖw¼…'Ê¢ªj"o8®e˜õ$Ê%C¯@Z¤U­Ñ€ÎyQõ–×F#Ũe¹ÍóJ…ÄÈŸ>{xåú-]3NNTU•)O+Ï™Õ;"©TC"7 KÁ”!ÀYÌüØí4V‹,OR?ðÃõ­ÍùbŽ+XVˆr°mÖÇCk8|éK¯oïn<¹÷E­×d%óýþî¶ùf}E‰Rrz´·½ó|ÁÒÙl ªªFÎ ¯dE «´ÛÜNλË+¬Íf+ƒ(uDލRs<¹h4µv{½Ñª¥e ªê›o½yøä‰¡Öýd¡ÕôÞ•ÁüY”úDÔ8¾ ]¿Ñ©-òáRs9Œ£{ž¬´{7v¶£8M‚êÚÍ[<ÏI¢2³y‘»A ŠjÇXÛÚÚòbo6[¨²¡ÊA„%¨¨ÊšÑõü N%Qgyº¼Ô ÃB$XÖêøø—ÿa!‚¸"ãêLÓ¬SŽ&^”åi·Ý–e¾,RÏìá¢mÔF–C ZÛÞýÖ·¾öäþžfªÇ‹Bm>™~¼»y#Kó4‰Š¢¬·ÖÂÐUD)p“Îrc4(-­nèg–=T$#O±¤©UJ¢ÊHašíÐ(zåápÈ —dþG?ýÉgÿúè©õgÿúß¼eÑ{½ï°ôâ`f'va'Og‹ÅbØ_,†å³ÑÉø·?å䬌ã0r[õVÅr®ei`LŒ¶þì‹»x©×k-7›¢J Yˆ(¨\äZ†b–8eeáx¶¬J<ⳤ,LôÑ]Î$ˆzY… Êä3– 3ár|Ôn5)¢,æyžG2․ eâ4\ZÚ˜_Îó)œ&7ã Où<‰À!&£IUV¥åñ|ö‹_~puuW›Z½îFväg½N]ׄÄO©ªa„“ E"JyJ9žç°çEµºŽ *ÒBø¤pSåÊ“¯Â|:9‰*¤`ižˆƒHà« ! ƒx¦H(ñª$^F< /²‚r£ê|:5uraêr °’*H€äôø´·Üˆ$A¤5d]ÕçÓjÖ@""'žžp„StUðÁ½ÍN{:>Ÿú’,]­¿VßP¯nodz|¹±ýú·Þ=žµºÛ×¶_x~ój®W×vn*ªº²²%Q슢!˜£¼šNdžYK³€az9:ì­ô8NqIšFÍà(É£ !N¬å•íÀ¶Ó"„J‚gQYd ,OZíåg†B .S0›ž·zÝ8Ì,{j˜µÅÂ6v°d  IDATëÍ4É<Ûó}ccçèñ³¼ÌDELüŒ£Jš‡îÂ#˜4[­gŸJª" R&‚LÎïœÐI²ÜÐÕébö¥om¢Š#€‹ ¿³´<9Wà 5øZ˜OÿÓßÞZZ“ºjj'>½ÛZ]?ßߝɿÇ÷Ÿ„C[lÆwŸÎOljŸ1Èï=y„*îñÃG‚$Ž/ý“}ÛË’~|òìðÑúòùà(ôãƒ'‡ ,j’–EÕ;¿ø‰)·V·®=8þ¼â“ÅId®´ë„'ú_ýà]‘… X ”gyq±>99¡¹V€ùÎíµ_¼ÿs{n_ék}üÑüÃ$è6¶ÃÔïmv#7ªÕz3!DŠ‹\®sÎtR²R–(Ï+r‹ÅPäUByˆÉ|:ªµëiH¢tq:¬ÊòÚíçCÏÏñÒº© Dˆ!«FÓÈ“Ü,J¥|^–§‡W¯ÞUÎQj[s©¦q(Ÿd¡çÅkk[çƒsVNÚ|4++æÌçËÝ(Jg£Q³ÑC³²²l«Þh@Ežw<—#’"É%ˆbÇ Bomg{tq)‰‚5nníN¦#Ëš²ŠHŠ´°G°fËY¹¶¶}÷ádž®ÇÌ‘ÍúhÐ_ÝØ2ǵ}®’ú£÷¾òW®î¹£þÙøÅ—¿}kê冂Jn6½ÌXâLSÓTŽÛ­N‚¢TKR‡•Y§µ<Ÿ8'‡û”S¶6¯ gg"­éXÐ8Ä@^q<ëyÂÐùðtkû&&b*Sä '2PmnõÎfþøìò÷~ç»EIDDYV”2Iïßý¸Äùp4Á7»Ýïþæ·½háû¡›”ˆ†Ywç7­*};B¤„%Ĉ«5n`õºkYVéÿÎoŸpä…ˆ0I”ª¤JYÑéµb; "_Ö5‘ª¼Hmo*cqe¥ö“wßk›uMR ÍåVeTq ×6¶Ï‡{Y”ë†ÚìÖ­©O8P¡BU[i™{ÞL‘ AY^˜õ¡DQjQ`)†Â#% ý$‹$Iê´§§÷H>~ÿþOõn0ž>¾wqx°×éÔxŒÀiµ;™ŸBÄ f¦YçEÂ2vz|Þè4êŠ<ž§IYµ•ÚÅåâó½ã9EniµyAšä’ `TNN( ±æÞÆÆŽ¡ÊªÞDEqº©&~1¡2ŸF¾$Õ¢$°ÌÃJ5Ô$ (8 –i™† ¾Ìó!/ð°‚,&QŒ ßlב„~"+’¤‰ötN$Š@EW –¤V–jͨŠ*Ž<ÄLa™äžcÕŒ:„¡Œe O$<ò, %ЦBÈ¡ƒl¶×¦ÓKŽ£šbD‘« TpaÍtE&X>?;\ßÙæ±œÆB¥"׎Ožë­u÷O~«åõ­ÎÕ×^}ùˇçO¯ÞÞÕd¥Öwžë˜š¡ªZo¹æ;žµ˜onoÎ#Œ…Ä/1VU¸²g–¡ÕE².F’@™"©UœIšD‘Q«gEèÏ]³Ù „ŒåY¤HÂl4.zvùx©½!*Š„´¤(‚ÖÄf §™½ÜÞ¾èŸaœiªF¸°NÍ–I¨xÓn§ûŽOÔ¦T“Ô¹5?<}²±¹š§p2?¢’|ï‡þ™5ŸÛIœWåz{ù³ŸÔ:ÒöÆNwïÞ±¦3­ièªL%éÿø·ÿçÖúN<ÏO¦—ã#"ÃÀu/ÎN|?¾ýÒ ÿð·?©jÔZ[›Û§g}€™¢Ê5£3ϲFWz¯X±•TŽ}”éÍnÀÜÔÉOÇJ'íµ6?¹óùÈ:QHSn+~þv Ð/~öÁµçëïòáÃÈu_znR0&ó\”D/ž¯pЦˆ“ûÎïžžçôç?ø³ƒ³Gž# r¢Xú¬ÓmmmîZÖW ó¨JY‡—ƒz«ÍŒ um§Þè XÁ bæiˆÓ~ÿ}Âñf£© ZR攂HÁ*N@—§«Û7’À 2˜×š +„EZxCEÕûƒ‚iUUZ^ >{ÿÎÞ¯>Þs½EégÃù„0¹ªH3èf« hÑ2×ëš 0™7†Ã‹ qk’ÆJ<­ïl ’<ò=Ÿ¦*ƒeÅ o´×LMhÄaFþáÞþÉ…NfTTßüµ×ª2vv}¥!RlÍÜK@‰"/n-÷¦£1CTÖ8‚ù Œž*j=rÊqI‚†cEYf•ÖÒpÁ%TžÊaÞO\‚(Ì£À÷+À„’¬ÆahYƒzc!’ÆÏK”ŠAàÊrÍ^ÌfÖ@ÀjâÆ«;K²¢‰¼Ðïö:ˈœ@X™[Ψ¦4¦ÓaYÄu£1êŸ!‚tÝ80g]^R…e,ß|·ÖiªºÂ œÄŽVk; O7kYÛcKÒ%T!ߊ ’†¾;œÀ—YŠJŽ“h^ÆIœRŒAJ³(Ïb±"I–='\%rB Y–¹Ò çEîWP´­‘YÓkB3)œ”E+ëÛŽ=­ª‚b)ÉÜÕµõÅdz~va¹»uóè|¿ÞÓ ª´°ÏóLˆÑ‰X׿3k<¹{óêsÇÇç?i¶Zkk‡'º¡ÏÆsI^¹ûÅ]ÉD+f‹ar~~²¹¾äÍ|³Ñq}‹ÃDRÄñöÔJRkçv¸‘0 ÌzÇžÏOÎûÛPdMÑf³©j(¬ÈL£{~|¤é†®5Š2;?;ÓT3+Bk2uÝàðä~M\ZX‹ƒ£‡>û´³´r°`M§ÓE•¸~šƒ2?98Þx~ûÝwÞõÜa¨H’ãDf[YX®Ïü•¥­ãg‡×o?EÏ'÷ž ¦§G燗Π%ÕR§µÜ[;yò´ÝmiŠzõËýý_¶ä«æ2o¨Ò㓇Ÿ>¹³Ñ\êÏÎ.ÞùÙOv7¯ßÛÛ;}Ú÷ƒw a–•þý;ï.ư¢“Éôóîú®wrv†óòÓ¿è_œøóúüg÷öŸ==^5—Žý4GE–ߺ¹åÏ2H‹¼È7–w8÷ꪑ„¡ èžã#&>lÈ5?N«$IÝZYºzýÚ|:­µ:EY ˆ¿8?ëõV+óúƒßý£ýÇ”‚Nk™”Ò_üÍŸ¯®^»þÜõ4ñÚK+¿¸Ûl)šZƒFîš·³ VTŠ«Ñ\:íŸjç³YŸ\L!qñ<ˆ˜f¾fÔ4Ná%üÅýOž¿ùj–F‹…xI)B’å<å§ñBéúÚÕÏî½oÖ<Òë-:žM0(qapN0¢Š&–UYʼn(ŽX™äX„ÎÂév7£ØÃ%« 4q e0,;IIp´{õº¡kL,BÛ¯ RUdy•¶7¡T Ý(I=I– C¶5Óts:›É†ˆ¡8žNYUê²q||Ú?=•8eaÍ–Vºq§IDæ8+Vt:+~àfqR€ U¥&ëIIŠÊqta8°‚!ÄÁœ†XLfœ¨òBÉJ&IR†’¨§Q(Hü|;8<=<8zãåoÿ»¿ùk{<íïbýÉéäÜ_x³Õîölè?|z¸j,ä¾Ôë çšÐª}~ûk“`,Pí?ûÍw67³\¿² xýµ×¡²0*«Ìqfp€ƒ5Á°\{©Ýðâ¨ÕhÉ2ç¸ùÆúr£&Æ^ @µ±½Uäi¯Þb$_^Ý™Mfˆ+ó"©7z¬ X^À*‡ÆN ×$N@ŽöŸþµ²LrPõˆ“Íú§IË‹ÁñÞÞW_ÿÚg~jjš,«²fäIE&S Šú_ÿån½ðe‘—(G§³A³µT¥%â ¡ÂEÿ´µ²šùnž•ã%‘»<¹E‰•‰Ù\ϲ¼yȳH3 {ì\¹’d® hi»¹#bÂ*<žMÓÌkôÚãɹ$«GOžÕÛºçm¹¡µÚ»öøèžkY+«ÛVœÀæÇË\Ç”÷ŸÞû7¿ó&ɤ¹@ñÁýÚÕzSæªþì½_Ü~~ÝŸÚ;À.ƒÂšZCSoGãë7®þìWŸh wóúM^¢®¨V4}2«ªÚ?|¼³y=Or€e϶6®¸¶ŸW‰X—(“%­æ%RÊ¢$¶;Í{wv»]Ê#P Ç ÎÏ;õ­¢(³4ö¿×êDٯ07ŽÓ$#„¼ñÆ×!„£Ñ¸Ûî±¼ <­,ó*+âf£e Ç%.–W7ÏNΦÎL–„Ì/ H0ÅøþàŸ°Æa"*"Ë‹z(©BM7#?ì÷Ï·76‚°-–³xvÿps}w8ŸŽuN½º¾ûÑÊ@®n\ÍËH^Õ¯¯]ÉÔW©.‹‡OŸ¹ÖD¥<åæU×E )%¨Ê³<Æš&'¶Ê‰ Tu¥Á*()ˆPteû¹³þÙx³o4ºìtÚ'§‡“Á(«:—Çó¹·'¦ÞýÙÏ~ª&('°÷Ÿ>µÑÌžÛN:œ/$N_X±Ìb.u¶ï=ø…—ãEZÉ®=±å´7Ìë×_‘%m6·^~áuÈrNé–A|íÖd5³Þ¨p¸²²ruw÷øüY­ndyÙ^Õç³EŃÙÅÊR+tc?š·­¢Ì…ÃË¢™w¾øàöÎÍÏ?ÿèÚsÛíÞúÃûŠÂ«™WxÝ;xVUðtïÁîëgG—#ë(£§7V_2üÉû¿Ü]~ããÇï(ö«|Ð÷NNG¢…üéÙ÷¾ØË#ñ³g?Ûöø³OöT¹^ŒÅ×^{}88ËÒ˜P1tÊýÏ|'ËÂ"óƒã½Áï}ï{£ùÄ·ƒápT«V"2 §BÂÁåñ[_ú^˜”N«-lüÆ[¿æ¸Þ+/~½Ñ2ÞúÎ÷_¸q äì7~û{;­k7^¸äÕó½ÙºÊ}ãßêš­®}åÿÙ­ÈÝÝë¯|éËø»ÿ´Vo¼õÍon÷Ö~ÿ»¿õÝïG&Ú«7_¹u}çÉþ£áô²„$N‹Z³¿µ¼a¶›ŠÄ F“$^yùå£A祪É’$‰tSAeöÒk¯aè{–ÙjfUTei”.8]£(× Ý²CCÓ1/8¾7¸˜zW–Å2ò9A¿ÿÅ£o~çÐ)Bo>_ýêëý‹Ó$‹z5"¼\sgv­)"HªÊ2¯‹Kz[!9¶§™ZèÚ¶ë;Ñb{óúÙáa­®W(C/ó Ôº.KÆ_ÿà/½üf²kØ(¶v6³9Ö ;›;ó鯵ÝÉåy”–?^Yé|ñùƒ0 |׃~5 k>.1ûÃó/îÜ5ê­~ÿp¹¹öÁ'Ÿ‚ªê™ÝáÙÙ`Úf®$·½ÙeÃhXñ­âógŸ~õúaäÕkýãƒ4«ëWâØkÈÍÁÅycµ%Reyuç‹;ï7{MCQÓ8lšFžù¼ ™wܼÿów_üÚ+LJg£ñY·+Qd,m/©,N0yîÆsŸ}ôq­%Ö»+™Žg·Ÿ¿æz¹Ç¢&ûóÙúÎîÁéCX0V«››‘ã¤"O+zÐ?õãH(€j4v6–=Ïë®ßÊä€#ÝÚYÇyRþÙþ¼mvQ^-‚ Î)¯¿ùªQÓ†§¢¬ºÁdµ}óàÙ>‘ˆ!6V;[ý‹cLxM1ÂУͦ³ºÙE˜„®7On>÷%×^T`À "Qdá“ï%®›¤þ«¯~ýÁ½Ï‚4úÏ¿ñkÝV©ú×n^ÓÕF£ÑzéÅÛ•‡n?w«Ùjà’ßÛ»ßk.A»AZ,ÊrES’0UeMV¤•Îæ³£³N£-pbU9+5½Ì ¢ÂªD—ƒ H³ÙÌÊòLÓ…;W4EMÊ´LY·»ÂXäÌN ÒPÛHdUÈ’L”UÛšåYa¶–ÒØ­Ê °a¬ <99è­m}k¡ÖL@ ÅT$Ï¢"ÉM³Ey^V .g–S7uÃÎl¢·a芆DâøöñѾØë]îízWiÕÆçS¸(uR¯r¦aÎÒñh¡ˆ²,$I)ir69kõ6ãt4Z\A‘ ‰®5,o|tv¿¨F—}ç´¿wíæJTÀú^½Õ™.N“0uâèìè$X\°Šœ==9¸ T:|và;óÏ}œÊxvp¼ßw]×õ]wæ†Ó¡ëÌËk«ŸŒì©]0Öio=¸ó9$"•Ú‹éÉ­Ý//ì”Òtcíærgãƒþë¿þÛ¬=wÚk¬Q¨n¯o£Š™2püßxá­¹_®o-õºç_|åxðð¹+·ÛÛœRl›‡§ßýö÷ íòèð•·¶};âTq²8æ+XkÔîÞÃEÖÐÛI½û··sí¹GžH2Ù{zúöÛ? 2ûd|â fU…vv®ØžMrôX4µ¦Ö¼wçÀ‰ÝÖš&×ÿæGÿ¡ÛjÓ "¡øßÿ¯õöß=üùGÿ@ûßþ»·?½SãÐ{ïœÜ?ûäç?zLóîÙç©EÿÍ¿ù5IFŽöá/§ÉÂÛkÎüÅ̵ÐtyÿÜþÆ›_fñåÂ’lHÒt|¶sëjÛ0QÞ“£'/ì¼0vm™“ ƾ÷íïf™o{i¯× þÿçÿ^—º7n¬¿ôæsÿË÷?¹àá÷ßú½W_yuëÚÕÖ]Û]_½yc}­ÝŽÿøOÿ$y·Wkvµ¯¾üZïŠd¨*ǃ֊~íÖæä⨽Z“¡ÓÑüØ®ÒQd¶DªÃ“Ãç¿|+‰­óùà‡ïü?Ëz·@¤®rGç§««æÕ;ïÿã'ž­­vy"?ÚŒ9zI K*J—'ç—‹á+¿ñºÆÑƒýGKWWOõœŽTÒ>î„ødïli­MEn0ØÎbs}ÙЃáYsyÙž. ­>º8æ%I’N·†U²¦pK†{£öR+/Ê"‹‹,§’tðô™¡*ª¦f¹§×µþå¨ AQ½ƒ{Í^#ñʘˆ±ãg{«W¶!a?zðÉ«¯sr>·Ã‰(©¡3 óœeàb0 ¢èÚõ›_|òy£Ýf *Y–+#‰U”CT7̧OO^zñAÐXI¼`öæëßêõ5•ó_¢µë7o<~‚¡ðú—ßhµVßùé_ýéû/\çr{g3ÍÎüjø•7_­·j¯œŸž}嵯Þ\•µýá¹Z“« æiµî ·nø«wwׯ—Œ™uÃvù<Ì#Ïó_ûò[+Ûmמ·ÚËQV¤¨†(÷ÃDUµ…ušÆ…Q¯Ç‰W”ÀR©)EZ` JÉr3)Ò¢,Ê(²HLüsˆ9‚=ŸÊ‹¼(éšeÍ0æ¨ Š¸ày:µ[Ý”A`LyN¥|J.+ó³Ë}æGO.¿ó[ßNÑO甆®ê5Q‘ó<ÍYÑZâ$Yz|üloïs™“î|tg1îî?yvŒauy2{öà P–‡ýáŸýÙ{ŠA&swré8Y9ÁèrÀÉÚø|üôé}­YŸ-kŽ»V7.ÎmI•²0S…]ª`{4—ù®*PU6ã7j|¯³Ñ^^NZ s}ã Ï—ŠªhrmiÙ$u[­³Ë½íÝ­F³S”nì¥k[;•àò²0ñÎoÞzþ²^ÁüÚ»7¶X>Û½v«ÖÒMMPÔÿ øŠ•,1 ÄzsηnåWõr~ÃtO&)‰AZi)Akî†` Øþ6à/ìŸ ¶?, –WÞ•–")‰”Ä0à ==Ó¹ßë—Cå\uëæœ|Ž w÷ÞŽ ‚`/íøþw›­#Ë&£©«ûÚ|ܸŸï³„ƒƒ¹ÿô·÷ν·ÕÙè4.ÚÍdL]LÏührrt~õæüÁÞíÃ.-d‘ýöÛuÕÎ8 ã ˆËÅz£qä‡$ ÅjáèÉça µÚͽ½Å³ãÎëç'2ÇR h»`A76V_Íx\öûx}»Š©ÅùMvÿý?ø}A*ø'ßÿQ¨ý»ÿþßVV »;w¶øGßSDéõU¯,¡gAp­p÷Úý{†~Yɯ«kƒ IDATãïüÁï ©æÆr~}e‚RÞ°œhêô­v«Ÿ/÷n¯%åªÑ\X.U*«3{X^â´éL©*vŒp¢vnÜÝÕ8¶X‚a¡’ɸWÈWR,ebÜk"àD1Fy³á ‰(ªû@–éÀ±z¸±¶Òí†H8˜µ'ÌÍ5 '‚y ýêÅóµúj%ƒñ LB0EË&H4 !×26WÖÃW;þEïbÛøó¿ø?à ê]\àXÝÇýú“gÏ^ç»ß?¿x1TO6×7[W]žÇ ³?nŸ ¹‚¢”žüú^$‹õòh0ËË@敪•îY§ºR7çó|©–dѨ?¡H!Å>ýøãúú ƒy¥|zv†>à K{æÄ6¼J½bŽG¾åO&íº\×}‚@Ö–n¦ ÁAÉQÖª•þY—_óy¥\Ýüò‹_/UJ Èe‚S¨5œ¯ïíÀ gP»ï¾ûþÙÉÅÒz™"Ñ|®dñÖÚÅÊË«kë›}þþ»w’ò|odÌ<ÏAqFÌC^Î:Þ[o¿õâéN¢È»sí–®z(x–%çÊåbîäÍqN–„£¬{~•+– ,–«–a€`&ÉÅɬ5ì÷* ËÅB¹Ók Œ|u|Q®HB\ÍŒaµxãÅWŸ÷'ã¼Po7×ïÝ8ýâÈ]%W̉ÒáÑ!IgeyinŽ9‘'”@¡¤äÏöÓ÷ß{ðäé‹8MJ5òÝ{œ¹^à‰1¬4Ž!&bI.MÝœV+ ®Ž!åØËýSNÎpèh>ü£?ýÓ8 æÓqNÊã4ÇÉl>EÁwÜ$ƒ€ŒâÄñ`Ps¬œCsÑ'¿|²°TˆÂ„,.Ð8„ãh©´˜ÆÞ|¦zž{ýÎn»ÑFÐKÍ¥êr»?J (ð£J¡C^wÐ*«8‹3ÛŸ^²¼L`L‚ÎÿöÇŸVäBm)ßîu´±~ty´Z½ÍÑ2̓ÑäÚÞ®[­NgeqÍ¡ºmš¦&•m>(—Öz½N¡¼(rAA«³oDdײÔa{þÑoº¾¼øÙóž¿z:s üæâ'±î]œÎ[£«åRþ?þÝ—åZR¡qûìø·ï¬><~3üªõœfѤÏï ^šŒ¼0ñnܼóϞÞù½o¼[ɯá8ªÙÚ\5»ý^­ºrvxP[©´[çŠ$O‡]ã‡ýfa˜§ãúrõøÅ%ÍÑhLýûÿúÏ´‰óÃÿæëÛ«?øÆSƒ üñ;ÕEº.®/Ö¿ñá^Ä7övÀ8åìþ‡ò F ` ]x²ÿ1Ó¹ýî7Ù¤D*ÆE¹Ú›^\î_ßysx"U£gŸï#" B“ͽ›ÿßßþíw¾ó~µ¢ž¼ÓQUZg Ík0¸òå‹gwîîÆæ`p.dá[­³²‘,?µZï¿úø’ ±3­ä£G?Ç1IÓÔ/Ÿ>Õ ûôu'Á¦_|ù+­çï¿ø´T’ž¿<8|²¯ÃO~~Ì1tw0‘E„ <+·&Óåj9Ë„À³r=§Rª˜–“I EVÊppke±^-–k¥É¼©àJ¹«Û êdôætÿæíZ¨B >ùò_rå¿øÏP.xñÙA))é]޼(¬mpÓ¾Þî6¼{ÇÐ-!—›Mz™ yáhß ‡ãîÒò¢3Ñ×f}!GccusqФ˜¥“£SŠåa0á(E5æ®íj{mg·Õj 0šS 8…)¨©C!/Ga …Öåa¹¶Œã ŠêX# š p–ŸL[›×†ýÊb äÄb£qR[¬¦‰Ë‡¯ö«ËCVØë]<|ç¦%‚À ÇÀ'Çû‘F y⛿ó{~ûèÉÉ œ ÷Öoax<›)+ CâËçO7vw€ ¸Ù¼\¨/›QÂP4C1‘ V—º—íáÐ¥‰l{kûâÍÙêÖÒd<ÝYÜehùÉ«—õúÍÆá¼jta^h7z8‰ÿÃG?Œ‡0†ugú¸ß€««³\¾6v*K5S3ÂØ•eQäòó÷ÿ¦)EÁ²(¿ûÁC}ê’#ŠAñÃþ`yµÍ1͘a†NQ@æú†oYîÖúZ¿ÛKÑHxð§?þ›ØOÛ&I‚á8h–ƒ!bªõjÕUW7$9×ê¶dA´­¹X(ÿÏÿËÿD lAQ®z÷ï½÷íï~GØããƒr~±7nݺþ°{ÑP}õÍîe;HãúÊjë²Q­Tzã¶,É@ s{~|´qm-Ž¡7G¯ŽžÂg÷­G_ýÒT“álòþïü.{™ç yÎ ƒÌN¡Og4jðõÂÓÏ\¿MóÃÂ`(#æ¥ËF‹ÊðãÖ+2ã®^ñ,5ëÏ×w×Qœ ðœª6M?LœäÖÎr¹¶mi¶¶¢ LÿjpehÖBeéÏþýŸP°â[–jŽ ÕÃ'ƒn>Wš«*Í‚IY3“QXš¼Ðñ—AèÀ )šŠ‚ F!7ñ9Šë5š9…'ØÂ´ßæ³0Žâ8†l>VתÃN¦ ’ÂÁ(‰0ƒ@E#;d8ª3l’8ÃË\§ÓþÅO!åÃó®]»&ÉÈÇŸ=Ý[Éëtdwwž…€éX¹”B)‹G¾”AIq­¨vºH%i=WÔ’,‰§šËÈ5Ô,¥Ü4IAmwíúóû;w7˜s< 3ÐÈ4s”_, O‡ÓiÿÛ¿ÿáé~/HüÓæS8¨HŽ ½ØâcÌ‘ò„Þ!RŒÊ//ž/ÕrŽ¢yND¢ó“I~e‰J=ˆb/ÏÛå…¼«§,G´:Ëó"íù˜å»D®l\»<e8¶™I ÚõkueKÒ\ïD±P`K8 Ú®ýæð¤¶@³ruW¾c‡Óõ·¶í^ ‘@ è¾Ïø”yc}ïñ¯Ÿäo”DO-T‡çRR-@gÛç§•µ:гžîŽÔa½’Ÿm7ôx‰ötƒ)Ö~ý׿èÍâj>/ˆÿÏÿûŸ—ê‹…‚°º¹™Ï• A˜´Àb yðìÙÎû±ïMú“Mk‹‹Óî<#£,ôRâdÁž÷‚ ¤¶Rù«ÿëÿòQÛOL^`<(Ik)fûIH¦|¯s¼tç]½ß`òIóx»°‘ÀPoÒ&|C)KìFÛ?º¾±qöx¸õ£üà#Mó‚…m‰¹‹asQVD–ÛPŽç35W“Ù•’ËÿæÓß¹!ܳ—'«»eG CˆÀ™Žáéhúàkï|ôã_2µ´·J%Ù`ܵ¢d§^{r|@¡ôGŸ>AAŠfàC/eyX`Øv¯ƒ2tC +¡ßOX‘a9z6˜Ñ"r,ÃQŠ«ý‘”[©3T ìq,“ü<Š‚¨M­(%K±Ýê8 ƒÑï~ýkñ—ÿñôƒ?ûãk'ê«Ç¯¾þÍß³,½P)©ÓqãâøÖí÷‚8Œ£ œ”BoNPøtª9¡MRÁÓÏŽ·nïù¼¡š¯ž¯n®A‚ÁL :QA™¯)Íó«È n¿{טš~hÛ®S+.û¾‘Bà¤;XX(F1ŽÊ å4]ËI¢TYPæÃJ`®iÆq,–Ë1$š>ÓõJ©žÆ@EÓñ¨\ÜÒ­1†[XJPr5 -’bIXôC›DÐ?ÿ?ÿWMä‹…ïÿɶN«‹W-ãñ«Ÿÿ»?þï "Ý´Pö*µåÃ'‡,©©êÚæÆááÁúʶ\äd¶Ò_2}|x…E±ƒúšj1 a&j†º:_½s¯{vìföR½fkFA)ÌNN0‰ærJãèl¡¾dkãÚÒÆéÉ©,¢r¾€“2Œ;ãþH–s¹b¡{Ùùä³G3Ýr|cs}ã›_ûÚ­kÓ˜yji…ÀÏîáh.NÁ(ÑXZ1 -ÊL a1œ¾8z“/æÛóSþÑ¿ùSL!õ}ƒæd”ÆYŠl´šR± )GQª¦!$PÎ× }ÖR¯¼Y˜—¤Wg ‰™ûÎÛ;—#š#“Ô«V–ã‰ëie¾ƒi'ž-¯®úLàä³ã7Ëk+D†›¶ÆnN(g@¸ßüùåÅàêdøàþúç¾j´´4IÞ¿õ~ìOh™Îç f8Ì Hí6R¦q´y¢ýôÇŸåóÜ­½;§g¢’‡ba0–AÂ0˜éê×?øPWu,\?ƒh2÷6wWy‚3g¶å¨qàÞ½~#à,òLÍ*•×Ç$̉W­æoì¼5œw0”P„’‡„ž¡q¼Œ ŒÀž&hœ“ Q Ç@¤k# ‘’(¤):2à 1KýÔÏlIÊ¥Q27'¥Bų.Ç$ž­OmQ¢«Õb¯9„‰l±Ví´g|lA‰òI”'8RszÙÁDælս蜤ÒOþöŸú“Îùy«×œÁL›FÚÜN PŠÊQ<â»n­¼=1{a$YXȵ»“³Ëcu>8… Ñ¬á{"iàýò£ÊùÊáéÁ›ƒSÛð&ƒG²šê«C՘ϫ¹Í£Ó3€g×5¡µëZ+Ž=›e¹Ja¯srV­/“‘‚à€«â¶˜/]۹ǥŒíDßøÞ–™2Ï•óeá_½ý#—ßýöͺ´psý½oÿá·R»s÷í;<¸¿~…Ñ»ïܱ ÊHJa„¾¹¾õío Í`†+¼ýîhì/m­,º@ QL\ßÝaålïÞœyoËbž&¨JµØ8=YXÝสTÏ..WÖVH˜L"4lÏrx~ÁU'<Ïõ—»×vmÛõBaETRÌSŒÀqŒˆ·6÷®Ž/öÞ¹½½²$åò¯_}^+-·{ãŽÞ–ýÿ¹ýá7k£©Öºh7ÆÍ¯ø­««&FbS‰"„ãk‘(¶²ºúŧ¿d)ðFI _λ½WæHŸb…Y¿?JT¿aXº{Ñ8Y®¬]hsKŸh9EÎøøòb¹ºHe8“½Q§(æ§3õö½›‡ŸŽÇ~ÿÚÎMmè˜a_)nn¯ït‡Íj}iÐÕ¶oÝP·úoß¾þ@³¡Ù»¹}à ÌÜ*êÎB !Sx¾»wûãßü œƒùúGŸ¿Lp«yÜfùÊ£Îoæ ëÕÉYN`œÕm;³ÅRÅÜ¡a‚1‡‡S›iº$²ŠtÚ=‚€Á×UÝŽìýƒnIÚp:±Õñl©²|zÙ÷<Ç uäh2›ªŽŠ¤Ù³ƒçßýÞ×ÿÍýQ¯1ì\öA N¢¤\]Ötu4í•åÓµa õ½Hs)†n`‡NHJ\œœk®¾¾ºK`ÌxÒ‡2²£—$ii骹¿¶ZõlË6‚•õF·•éæÒúêÒÂÆ£O~ûÎ;(Œ¡0"$Âéd† Ä@“ápÒé‹|õüð°×=?¿z&@£?Â18‘¿ñزýÄãXaØ(ðAJBC‘\>×éœåX‰äØA¿ÍVæâ1™düÇ?üW ·F£êBÁ=× ì¹V(*©—y‰“†ïEÕJýðèKF1Ñ,èùþþJ­¤^meicqm6orUÅlÛNúõõ­‹“#Ngªº¸´hOÝð,sV­ì¾;uòR1´}ö÷õ¬ÕïŒ1šÿäÑã(ƒjùEERr%—i g›Ó7—Gã¿ÿåÓÊbÑîÏ^¾ÎIt].õôÙaãÅV}çéã/—® g'—æH+ÖJ9R¼lŒ‹µ<ˆÍ\(Þš/I1jE0ÓÕ…ºâÙ6J 0ÅVÒì4#Ô“œeÛ•e…#”âB C]×ýÐXØ5í M0¶¦cI©éÆ8ô‚$Î8N38KyVr/F<Éà šn`ûœXðÜ™ lËô«_4lu¦ö•\•¢™f缜_µ¦B±¤Ùt¬Ga ‹âĈ›Wg‚ u#I&ƒ.#½ã†¾ª…0‚Ailè°øi¥ ÎæÆ›ýÚÖÆd2ë^\’ Ÿy€;[x·þž‚”{üñgñ ÜÔf# ¸íáõ½Û/÷/ì>¨ð¥ÍÝÝr>_®,‰rñ­_C9¸\XªÕkËKÛwÞz£„k·®o¬­/Õê\¿~G…µíu‰ËnuoC`( ‹‹Òí»w5µÃçQQ.²<…‰ç¹NèæëyV¤N/Ön.g‘kÛ¾ K…Y–Sè餧ÙÓ­ÃH–‚°@ªîQe1g™†ÏÙ¶fþÊÖBa)gO¹1¯¯•fêgA[³”J=ˆœ ˆÏ¯N—WÖ1évO šr,½¼²Ö8?'9tª ËåÚHŸŽÇS†Éˆczú¼å°EúªÛ ù'ÿô“Å­‚¨ã$µµ~MTê®åôÏôÓ“Öænñ?ü‡¿ä‹N@õÂÖ‹§ŸÖ« ŒØ©S­Ö/.ΕŠÀŠÏ`h¬šAžž½æØü«£×žé~öékÍžf‘}~ÞxôäG’˜ÿë¿ÿY©À?~yChœÙ'¯iV$Ê´âž=Ý[®G^ ÃÙYwHÃ8#ÐQšÌ ›å ÅmϵWf9ã82À¶¢Z±2UÇ)ˆà0(ˆÌhf¢ J Tो[ŽÉà²Y ŠúV¼½Z¿³ó`8D~zçÖ½­k{~'§ˆ0Ôkô‹åJ”¦…%±£:'ÆA@Òï76·®ôéÇË›[ûqgP¦Aâ‰2¹P^Ùù’f0’bh‚¶L¹Ðó e(AÏŽOî¼{ØêÙ†— ÈçúíNqayØê;†½±{ÍÕ\}6Æ be}§×9•¼g¸‚(¢(ê'ÅÒE<=8…xm¥®kIò¦1„"ŠÁ~l^^óŒàúnêB»{7;ÃÁÝ·UÃÁˆ˜ÑØñã¨{5˜šv˜Ä©—5»ËS'ʹÃ7O6öîöZ E% ¢ „LF]+[[/}*ò,˜Äy›Î:nXÓ./ 4)½|þHTŠŒxŽiyöýûFæ¨R«´¯N1úö7¿;ë÷%YÎ犩 ÀR´iy]¼èô€(M²tw}·ZȾW\(Y†MRŒëé"‘d.J|Uób!ƒâN·_ª,FagM0 –ß¾v{6B >Îçf“¦IK‹8‰:??DÀ$ųՅ¥ýW‡•µAˆ Lüæé/ ’äQʲ2ºþï=4 ݵ˳¯_[ßÿô…XÍAP"H¥$ CÃ0F šã./NV7vÝÐ…ààŸ¿ühvìZ¾kûÚh<^‘DJ6·¶´@|÷jxz~80LëíoÃ~–"b™CÑ\ùá[æ”F÷Š¥ØÆÙ‚‚b¡ì˜)gåêFêG¨/ÖVNXmž6"”¸÷à:”‚ÏßœŠ•à %2œœÆñd:̤0 ÍÄú½ï˞ؾ1Š˜:vèÀ‘Fvè:îÒÎö´5ÎÀP.å?C „¢ð,Ò,pı-Ц£4†âÈÔ=1§$‘¤h”i¢sLÞœ,‹p„À3-ç!"fh6HÂæ¨_+UÓ8ihꄈÁ¬!pÿ¼fæÍ½ÆyO³4(K!”v­Éîúê\3P8u½( Ð…jñßùþ`¤+…oÜý€AsKË•r^^ªmÝx¸½±º®Nçï}øn5·„døî¾ÿ°T-‘|w÷6Í"w¿~¢h×++Š Ò3Íæs@N–ýÈUyKWQ‚‚I?…R×Ox‘ (c9q2Ò‰a(ÍŽ1ƒ1Ìö‰D1ßë5Ëežbä {ý£ÚÂÚd:LˆÆÙÎè¬Tå;nN5m´¶¶óñG¿¹¶»è8Nó¨C!9ß7…ûæÅE»s²}gk>²ÃÀh [ _}sø2ÃýOÏÍü”çÏ~}lú.ÍÆa >zþ+8ööOÎcz1Ü·5‹#п8l.¯.>þèq D?ÿõ?P àûÆE»{zðŠ 9Óµ›§‡ P*Hbè%7oÜÛ¼Q»¿úÞ'¿|î G͆žŸŸŽ6×· §GÆø—¯ïÞZ¶}ë¢{uÐ|~­zÂAó’‘øýÓË·ßÛ;;ëA, tµTLÔR¹gåB>‡ãø`4¼{ïŽ,в[nÝ©:NáÍg³r¹z|~Ôí Ô-HÜ_üåO×ÉÅùl0¿}í°S³?kŸ¾9Uª…~oæ¨~»)KÒ|¤gÓþ`D"¬í9Þ€ÂdC÷!Š™uFÆÃ¹"(Aœ^œÝÚ¹‡ÉDõ ’¹±µn©R”æº)ÓDNm/p<¢H…½ ¨ˆŠ‡™†žd0ˆ¡ÕJÁvQ¢Ä\®ÛŠ<ëG ¥(À¤™ÏÐ@Š„qCÃ~âD©ñþ@’Ä••«Ëó“£ÃòBMÉ+Ï>}º¶½•Ë ÕbXÊrl’” =ϱL†ã³|}p°R« <«(¥Aç Çð8C6t›—s áåÙ±Ì R#(Ó…6¼½½}Þ:ÌËuÁX“D% Û¶%Iâ¤B§Ñ¨Õë^šQ”¦3²¨ÏôÈ÷— }Ú†Ÿ¦"£¤¡ˆ¡éÅR1ɀ˳Wª?›Œ'“¶51Ô¥åŋ㣛ïÜ>z¶uÖ­®Õ U5ÇN%ª8Ö¦8 Œæ­÷Þ{‡ÆeËS/ÎŽWWWJÕÂÑÁi©P°L’ ¦mø¡7’D?=|ÔœWx’åIù¼y*³EçfžšÚîí[o%H¬PŒ¢Q‘(eê=U×#'ÞÙÚ~õz¿\¬ © 2>êyŽ-*BÅ“Q—Bhݳ–W˜µ;ޤ¡ŸÂ€íE¥˜%‰fÌI†ÂÄš[aäò"7î ùœ<Ïlg\®U3 ÷6ׂR'êd4ðx<èQŒðùã/ŒÓ´wfüãã¿¿ÿà~ &^fqxôâ8ŒB˵§7­Lþ‡ÿöüüן 8‘‰2†3‘ò\Šð8 Q}¼ÿze³–¦Yà…ª9ÝÝÛë4›SðôÅ‹×w´pƒ©®ù,Ž”rŠ>MoݺI5w[ÝÎéI‹E‰œ"ÛöœB‰·< YF(ž$¿÷íïKMÓ´o›‘‰²Üj]dŽ2KûÞÜ0$ˆ´ªRý壧å䚦ϛý&æp„”òtN®Ì ão¾Û|Ó>½:3}s7w[Î)´ˆ=›Îê« ¦fên˜Sg£¾¨pÆêªJ DhúY‚зH”„‘,ÇæÓ~žIRN“Ðq- &p îL5F‚(ÆpÒsì ý8SHº§Û ’$ž$1áƒÉôïþë[·wż´ÿâùÖîîÒÂòÁÉKÍž³˜\ª-Úcä|2‘JÅÈKR/Æy'™$€œØ2¦–"‹Kå—OžP8Kól”¾£L†‚D”fd{ž½²¶&AœÆYÉ5Þ6\€a"‹¢ˆçòW“†Ì),Ga ruÑXX\KbÆI0A‚HËIùÉdê;¦é¸+̦]HMÃ*Öj–a¹¾žY©PÕ 5‰"Ž•úØpRcbAzmçÖîîÍN«s÷Îö[oß|þò‘(;ë[»[··¯/ÞZ½ÑMœt<+޳JAÅÜá³SÕèݼö¥ïµ/q‚”eIk³‘F0X–Ò®¯gDÒëtÞ~û½‰6H,ÅÊöú°ÕE)ÁÄw6ö®ýê£ß@q”%FÐsSe!ާÓèöŠRèõ:QìµÛ Bûª.PD¾ó5Š$§³aQ))r±×i4/æ%u28Éò¬4MyJÀ1âèä€áhš@/{ç^`Á¼÷^”€0 !¥Š‘­O‘8 ×>ož®×üÀî® ™Œ¦ŠXxýæ‚æhg–¹‡!¤*8(e(€  a¹ŒÀD;›j“Iïæ­;—§–zöEݶ/»-Ç÷ô\¡Ôhu:C H0'Œ>|øu(FCÐh¦H¼ûÞ‡–®]]…¡FñëËãÕ%OÓÀXجdY6N"0Û¬¯6Û}^”8FÂYi>ï'©ø0ŒB F*Tä¹$F¾a8“qêÄi\-­µzWžkÑ81LS.]]ZË‚ˆf(‚`Û—grI¹’kÛnh 4ÐÌè±t~ªNù²„™fÍ †a44 ¤@º‹Yº¢B Y‚8nL‹lè…®çfPœÆ) ºj4·œJ%wÕèN5“£Çr}?ä04ÌbËPò峃;wßU‰çÙšé hP§0”„QDÓôúfÌ ‚–W æPM0 ¦RŽe]×ÖœžÀå ÖÁ‘íX ½r|ötkïÆÕÉÀˆÆ»ívÇKTNT0½ÒAÑÚFJš¡Nzj›"ËÏçZ³ÄÓâxЭ['§«+ $Áï¬ï8ž! åœÄk5ŽäUµ{íöm¡lŠ Àw¾õ½«þÂD¦X|mk×õÚ¯¬Ôön<ü»Ÿý§jµ ` I3³A±éZµÅbF¢ç¯¿Ú½u³×l;–1šviŠ™;mˆ OŽÚ@˜-lÉo^\^Î^ž5f±²2š„°LÚªçôÓ”qFW¯ò|i8`H2wyAÊP¨s9¼j]Q0ŒèÅU—€éP®tzCH,3¨+êlb‡q>Ÿ õ,óØI•!8ÒMõìÞ­»A”Luµ¯  —¸ÕÚ"K`cSý“þIóüÊÉ¢…j¥“/¯†Ï € ( !GêøæÞušbxQœ«jm±Æ³B!§t„cÜÆæ¶ïê‘I¼¼¸²zÞèÐ<™%BPµª¥Ïᦊy×uûg­­ÝÄ÷(†&q…À‚TBÐ4°=!'’¤hØ–,Êžk-U‹ýî@àË2–…*‹BÇÒ8¥†…aÀ`dn›E…~ëÞCKa Tòå,5MŸÌWoÞ|û¿g«ªÙ<ÇÁ¡k*ŽâË„¡ƒ@È\ÕR$ìtO«kŽkò<„È\Ÿ#:' K74Ý÷#NÈŸƒ“8A°HššöÇpAXV:¿:-×–aÌ’8ˆB aPˆ|Ír9‰‹'pJòJqÖ×)ž€ Hà”ád [fµT·Ü9M‹ÃÁˆ7°\Ó¶mûÚÝë¢ ¡ A (¬¢œ]œvü¿}xÿ…Q 1AÁ_|ô GEQ lg¡¼zÕ¸sù\®A™eh¹¼€¡˜®Ï£Äul—/VgêØÒg*ÕËÃ#Q›&a˜6»íj±\,W(‰ùâãOê+ÛŠ€Šq"Õb¥Óiaâø&I²IP8éÛŠca˜†ÅÔŠËÕ…"'¢˜‹ÒÅß †EÑá¨Ï<+°A‰š÷õF«ýüùkøƒ¿že!0©ú|8š’$‰¤¦ëE%'ÉB5W´š²Rh¶»Šœ^]ÛÜˉ¹™:šƒ¿õN„žgà4Õé¶®­¾Ù?ÔæF¨[›·_ï?`Ø÷:½!F Çoö1CpH±×‡/¶W6ßL( )ZÉñùjI›M/®Æ¦o|ï[ß»8=5#Ga¹Ô+›h¸S*Ûã0—Ïm_ß~ýå~n)¥©ãàìíl dYT„Ëžçy¦»V˜%ÑjuÑœ‹¥…Ø÷x˜ŸÌfÚtGE“š1¥ ¦V]~¶ÿ•nûy²°·½cœZ¶¡–Š«YšZó CŠR$ú‰˜Jœ¬Î¦)–f™¦M1ŒÈ@ØóAÇñT=/2æ:xO§s…}'´l§²œvz†¦ŠyÚs’篇I<£^G)›žÄò4ÍhºÙhœ]»~½\É?ßÿÜOìÀh‹ÒL‘ÐQšÎ-NÂׯ¯:ºÅdH8ˆ@ nh¹0Öz£ÉäÕã/úó ß=™©£gOž'YóG_=ræ–mÏúÃñ'Ÿýb8œœ^brÕ<{úDää“ãæ|<º8iôç–:ž†¡ÿìé ³(B). …Äû“1Åð'ÏÎïÜƒÐæikqm±V_œ5åRimiuÜìïnßV'&˜Òëëë%)ßkó ‹ë‹[­AgiµÆ¤T® L†"`ÕåB¿ÙQ®Xa2f† Ê"Š3´.߬¬o¶†-u4¶m¦ðYoz55»çfÛ*U‹Ož=Â1<²Ù´ùêäu‰]l–o·ºí³ãƒ¼RèuZ–9?8|R„—Ÿ?Ocg2ÕaøÙþq¿;e9 ½_üê·8Ä^½iÅAÜéLcŠ@™Hs _ͦÕb>M25ðMC'qlj8$É çMråå§OŸA@‚AÔB9ßÎY©¢êó•ji8'0± æ‹Å…‘©åsÊÛ·F8\¯Ô(Ì/­Ê<Í2| s9‰‘Ê5mÒ¥îÝi!h!¤…Šòôù—y¹Ä‹¢çZŽn“ÅWDD ÖÃ™ÄæL×Aq 3k K¶çæ œ,öè‘R–!G3˜]ÅÕñ4ÎÀÅÚrN›ÏV·6¦3+ ˱³(ñ<;¯”i<3ÍùÊÂjGiæ EœD:ÝI©D…^ÈRŒ&– 4ÏÐH–Fà)c;Š`žï”‚f “&€’,Í^¿}#N\†çãÍP¬XŒúŽ=ÊK²À‰†1C Â÷#IÉ»®™Æ‘ïÚ8'›í kË« #ÜkOŽG ¤¾¸Ñi^"8* EŠ`TÓÅ0€%hšp¹8=¿~ësÕ0lS)p± ™$©m[œŽûag$犇ûÏ9Qa1KßKâ0`¦ÉÈŽ»½« :Ãc8Æ®†R¡ÃÈe¯;€ŽÍ;ÃêÒR94F_6‚^uOq‚ ,Å¥%Ç61Œ:<Ü/æê)DP7Ÿè…–&Þœ¼¨Ö*išPí¹¾ã»¶cÊ…úëgR(`¡×e@ƒ’K‹; 8eqiçZ½ n°X_ÙÛ¨kª™Ë3•ì¬Ý#è(É2sn¯.לÈô†•šÈq`Ps«M’G …b§wÈP”TâæÚÄœÙ0†¤1!)"~ç eU›1ª«F©.„ ™Ë“8 §> Íg»÷o°„€“éåéiM)â8%³¹º´x‚#Z(”Æó)’ÀA@ZUª¦m’<&ËËÚ\ÏÉRe›«›–?Í’4Ê ÁÇžÛê­›wÏ®Ú Aì%©ª[œB¡ÖV’ Ò¦ AY–âe¡o&¼L‰\íõÑgc¿mhêÁ‹Öë£/g£Fûb. 2DZû/ßlmí(‚aè|ª.­,±¼Â Ï nܾ}ÃÝöâÐ]]Ý´š¬H‰ÅPy¹2êµ”'Y̶}a‘ðìˆÀɉ>–r¬’ËÙ¥™j”†0Œ«³FàýNS, ¶i¾zÃÙâÚª5Ÿ©ÖpyyÏ7TFb{^”˜Ÿƒ@øøø)„“8N¿yóÊw"S5sÕüåIk0œôûåíçoº­œ¡†¿ysh©Zë²; stùo~ö“¢TSøãO_æZuùüø óAš ÇýÝõ¾éÓ†×oßí6/A••2fH]€¯/¯Ôq [,•ûÚøþƒ—k ¼œghòÚö NäA:ož‡aÀðTæ%a˜!º½ºaèV‚ÄXŠa(næÌtó¥!ÃÑ#uzkw …I³v2•Bùäè e$¢öÇ ÏfÚÞî͉9;;<^]ÛJ80œñ|„OçE%÷êùW,–£)n¦ª¦®î.cÔvy‰ëFåb-…SC›úAtïÞÝI§eZ*ˆMz8ÔÆ å¢jÙqÚn¸½±]©Ò¸l\q ¾´rC©YQ4ÿðλ@h Œ Á(Š#U4ì™ç{$@“4Õu¿ñÁïø©—¸ç'\/ÊJö† 'Y¾ØO34Eତä“O±ÙÿO\5[“%bÍ;w2çaºç2|\Ô]UÝjXê±F²5öøÍOþAŽ˜7¿Œ' áqŒÂI´ZÐXô1\¾çÜÃŒ;3wz-ªdY¹È1¨²z£Ë"BäúŽ,‰ Eyoõ󞦫¸¬¶ë…aÖÓ4ËòøÃ›×O?Ûl¶4Lj² HrE²8Š8aœQ4ó¿ø*Þ¾,ó‹Õ}àD%•9æ+È#D1YJU4^,ï»õ“œJ‹2Å` %Ëâj¹•U…T•®ÓÅ{NæSL"2I²H*¬…*Ý(3Œ™¸ÙÞ ¯¬2DóŠj¤UD**+«F·æm·ÿé?þ£(Pî6¿ú°|prÐmµÞ¼¿ó HB§‡‡{š¢oË‚ø»;g÷ó¿™®îæ£ÅñàhŸE ©èÝýýÄ×oÞöýÏAI‘²Hý€e™›Øë Ñn†&öÝè¶ÌŠF³æ.Çð¤,;ûEQy¤ªærëñ‚g¹ºe™6ëÃ×»Ãv¿Ó,!—‰Âñ¢,W,I½lµXìî÷Ó8ùps Âbúë—ç€"ªx•úÁ?󤪪NÇ¢)EÁ`ÐÁY!Ê<ÏP㻕¬ðPbìõvmŽŽo.Ç~éš ¿ÿÅÇA?ZMg÷O?ù<÷“4J”¶<ì¼ý𢩠8ÊjEÛ­aÙêÉ¢éj»ØÝÛ·mŸ¥ù´ ëía… Á/?Ü?Ør¢x±æLÁbgç4‰L2Ž÷>½¹y‡Xùðô¨ÂËk„Jއj‹ f³¼o4ö5ÓŠÝÍ›ÛÍ0ºJ— Ì³(uÖîr9Êpˆ3Úñ÷Ó›Ýþ>RÀ£³Çšª:Þ´Ómsã­#ßöšg! )Näò<”E•eÙÐõ8Qmuš“û±a ËS ;_Î+6šõ<Ã$%½Ýúz¹a å¶(iˆæ9žÉб< Qèy"¯&@€¦€òüM³Ù»x÷2,³‡gßoZõµïrPè÷wJRv;{Wç¿k4÷ÛÖ7/¾‰S\QfAäS Ê\Å(OEaŒkVÛ ¯¾y}qýru}5Û:ëåØÝß}Ôí¶í( rúßüé¿“%0\mg`ûËáÁñÊž/ì»~¯TáÅó_K†l;®È²6vâ0Àãay——ï†GCPâÅ|ɰ’$×O¥†<¾z¯©êN¯÷úëßE8¢)šÂ`±Z-¼5ÈéÁpïfôüòÅÌhZ´XÎöýù‡†Z{ýêëÑüâÕ‡WØ<.ÎßÎÆ ^A™œyš¹žm­n§9w{MNœkC·DV9ÚS…høùO~üéG'{æ§DÈþÇÿ?éüîÁƒúõ“Ÿ5Ÿ>ùÁiÝH}x|øçögß~û›ÝNÎv†¥LYbíñÓzKÛmwª€|ù³ï±ˆå9‚éÇÏ>¦A(C—htæó·/x–P0ñ’¼à²¦d•E9·—Aàk’r8ȼ²õÝ'';€Å.VëN÷xïxëÌÓ,,ÚŒÇMÐs?ôc;ˆ“†ÕlÔêörNQdw¸3ÿàðàùÛo-¥ñøÙç&«ñü'?ùÉ”n7ï­H§²eúqEç$H‚Fÿòýe˜§m«§©Ú‡Û+Œ“§Ï>¹Y/$ž½Þß?Êó¤À@âÕ‚vúõSÄ“Ùâ. ‹?~v¿¸„z¿ß`eyyZº¾³ÍÓJ¨×^¾ü§¾ºÃª* ro=ûÁgw篫 šF•ÁéÁƒÕvéÇëåÔ1 cµœÈ‚šæ)CS$§gËU§¦©²’fqä8ÇST)Kâ$ôªÔ%ÊbÄ‚šÚ´Ý‚oöŸ==Cl7E!“ÑèÿøÒ8¿½¸Tt §1â8MM#Ò4ûü»ß.—ÛÏ¿ÿ²DËrêtrÿþ͇N·ç¸^«]/Š2ÜúA³®o7ëÚµv¨ÉršÝv#ͨŠ"¡3wV àþÿáîæ<-ª¯Þþúþýdxܧ@VÓ[ËÙ ÎÄ© ¢Ê*/sLeBøïoÞÿÁO~_ô“Ó'G/ßþÊØµN÷vƒ¥W±ÉÏ…›|Nn#èè¼õ¿ÿê)xöÖSÊÙ“®hM³ÓmcœþÃ_ýý“‡e~š¢<^Ù€UU…e*ȳ†e)V[Ç~Ìòh>YrÆ›ùz]D2ŒÙh²Y¬Ú{ƒ»Éu⸊,£V¤Àj7Æïz§g­º9¿¿NRPUD”P’æI˜1# µÉø6ŒÃÀYŽÅ¤Ì"âx¶5±Ù­áî0öÃ(ŠkzÍK|ı8‰Ë*ÚÝ9ˆÜÐÙ¬„øBOn†Ã~{¨j|öèEc™0a ÉšB!6²Ç»ƒ]†If¸ñBœ–4Ë ,‚ʲAÀóŒØóõ¼ŠAf,C¥qnI– ƒ¢Œ ˤ`äÎx~{7z¡Ùj~õÕßó’(@Í];^´†…²qÖ4ÃeAquûrçàa™“åvœÆDàÙåfûôx2^­×UÁ¾{ñ6É]X0ËÅúÅëç,âonï0Jãü7¿~)r¬$qß}ó6\U>óââf6úí7_YòPS­Ô© 4÷w<8}â»Ñ`¸³³Óßß;E€éuú2#>ýÞSK®ËŠtòà Äó¢lÐýA"²È ’p´²—QRHfX`™­”v)RJ¼Zï6þåçÿP«79NE òý8Ib…cÓÔE¢zöÞá!Yš¥¾Wîï¦Üx6¡V·4£¶Üp,‡‹‚eÙõ|]âˆ5€WÆö8Œü¨gµéŠIp:Û8uÅXÆÍ‚Ûû;CæŠÆIŒóL– ‰Ûµ¿·w"´)ËaX¸ÙVâxYP]•ƹÞä¥_¤ØÞ®;ƒœ…n0Ue`êÜrËB6%á݇›©º¢õ­ý×oßÐ —6ÜÙrõz‹K‘§‹eo§“¤Yâz4Æ»ÝüÌâ$êš;‚H4Õ˜Ýßa’hª¶ÓÙ¿8U¯ÕèŠò×2-×[V4eÕêTYÜܽ;~xúqŒc«­‹2ÇZf…œÀ4 N.ïn¢À$IVÚóÙDÖQâiŠ8ñf<4ÛeE ’óî›uRq˜”€byÀU$­hUä UTŒ hÿGžZ“)REŽIu×öÕÕM¡H IDATÐøèÓñhä8޳ÝdDŠÊõt‚²¤þ׿þÏS,®Š¿üë_¼|ñ»l ¼8mÕ:Ëõêzýõ~ÿÇ-“<Á9™}XÎÂÛV§¿¯%C‘ õüÍ+ÄÒ{‡GTAM×·­ZÃqó ØÞÀJlµ:0¯n¯o+{݃o_>'Eæl—¼Ùê÷êMÓ>ý¬^׿ûê;Q³h¨Bð T•¡&R @¨·:<ä ß]¾b ÃÑtoPÿ£?üYŽ9¤j–FJ®¤‰%C¬ßM>è¦%Èšã®ó–€uC›e TðOÿø¿öâ¨(]3EI3Ûúj¾íuìÜߎ¶n wëTŒqSbè´Þ¼yÿª¥ °iæÿŸÿïªÕ;HüÄŸÝ/$Qb-ƒÆ`ÞR4?lîÜ^ ¤¡[kª Gn6ë­<Æ×7—'‡G ÇhŠ2ŸŽK”%«fÜ]½Ï³b8ÜÇeVð"K:÷"A7ã$Ûîa NFÓ£ÃE–AVZ5]ä‹W²$"ÈU8QëV»Ñp]W³d¡édª(j–ÇŠV+H®(|©înçþfœTkhöÆOqÑîÕQ§i‘‚%É+I6ÂÔ£CAŽaÃH4 ‹<©J¨7›ž³‚…xA”P%€eiºBPÀ%¤Ðu#MØ,HhˆªVòúúŠC…„»«s0®¶ÎJ‘F­³;ò’¶¸Ÿ4[m–“îÆcÝPd¡ýÝ›× dЇ >Ý?¢©j¹t’4c6JË *LÎŒã$+h©¦.c\Š “VUY*Ï¿þ:sšîƾýp!³õ(r¯ÏGtʽ;iùé|yw}³|h~zu÷ƶm.­‹šfнJEC9œhLÓ-’ÃÎ1(aoØS×l NŸ¨²jjÍF¯ûÿöOÊXfýÙ“‡Ç§gƒÃÚàA/™q{ÃÞïÿÑfãùÉÙÑoU…”kî%XY Á‹¢,ÍvŽ:iY^ñ¸=Ø c°UV†­zßvW^²­™uÕÐ6Û)b»oåyÜ0÷¦Ë ³|~þþ we&°È [ÿ®Ó9ÀA8’b¼;8Ú&Û,ÉÒM®L¼ÕĦ!¡JÖ;ÓÉSU+ XžTDn,(Èñ²_ýË[E™Š-ت(ÉéÎÞ|c µöC4eI¸›¯{¦ è É ÓZo7ªÊR}÷õ›ÎN°l& •™fëíÛ×­^¥iñU™W¤äUÊôîF’Aæ$ž›Î¦µFMbÈÆYöºýÁv~‡‹TX3­"Ìü$ñ}÷éÑÉbí/íUMV4YÏÊïR‚üÍ·Ïi®ìoGkQgõº¯|^Uœåj8FǬY¿ý‡ñ’¨eÕ®F÷qˆ,¢i1.Ã4Œnîf_<ý8BBUºiH’¶Üúœ$AÉÊ< ƒª,Èq,¢!³^»¦Œº½£³“ã4 hH«¢¦îx2qÿä$IãšÕUeY–×IÖË…¤)Ož‰œœâ¨7”y΋’ïúASÚ1zn¸¥X×[~èI&ÅT\I1e–Œ¼^ÚóUµF·×JKÉSì:‰O¹tÀ?þ¾>èÌ/çÞÚytvP,£ÕÒÍÎß~ýãoþ–Já@R$Qøú훟ÿâ—²È~û›€¢¦“ÍíèBÑùéÍÄžAšEe¾˜M¢$cY•gi{6Wýxx;.ârX!*ã/ôÚª¢®·îW/ÿq±Yó"×М"_½ÿí 7”´:MSŠ$m •Uo»ž[Ñ@ïÞ\|ЪÞkµÍš¨ 4d$}²_“›/¿þÀq8.î§wo?¼%Ùm­®¬7Ëíz¶v%þÚu •íviZHëv Ç^øÛM«fíwŒšç¹¢1Š(š©ªŒçø¢¢9†þºQoà"ˆ#¿f´ãrͲ¼!ëe•°4 ~|j/WˆGœ@§QVPåðp/Ü8›íŠ"4])ÓÙLQY@ŽÁÿý_þK·Ñð×Ñzµ¾¸»6M^“ÌËÑhrµPEñ‹/~:›ž³¬%BuooÇß"OZnJ=A¬–«e³Þ—e¶Ì0(òþp€ÓBáb53Í–¤«‹ù4Ç9+!@`ä,/T©7[~”—iPk´M­µ^œûIÜiôͨÕj¥YY—¤<ÃeQú»"Ïg8i4­Ì‹‹¯íY™ÈÐ ÉînÇ¢(²b §Y”%‹Åe”Øœ$G·Çè5`‚óR–@UÒyž#¶,Ó¢1è»î:O `hNd¢mÊ Hâ8°˜”q²¬”â„CBx¢.”8Ã4JMQEIµEÆ/d¤(âRVØñäF—­0˦ËQ·Ù3-m<¾¡Žìz9i4{Žíª"/(Õýlâø1¸†®Eiˆ M(R×,–Šªb*9Æ “’T²EZ¤©2Æaš—šÔ(CôúòÃOøÇ(•b&Ûëõ¶«´û û`pÚS†;Oûÿþ/þCnêuåÙé³OhHûýN§?ììwž|ü q¿3ÜÝïK§)£§ºí†USqÛlï”$aù²DÑ4/rÂ<+(¿fq¡—ÜÜ¿©ÊœÊq­QÍ.©²JH\ѹ¿˜:îõö“‡Þ–åXÀж;m¶k³ÉRRÔ4ñ}7ä8N3Õå½›¸Ù©G^@¥näº"e¹Ç)ÚìúF×5Óh¾ý"LÆh:J<[RÔ´H¬nw9ÛÞFäÄFÝZ¬æaàëšJU¤ÂyºHóŒºð¶ C«©OWiQP]ÕMõÍ»·“éRæ¹U;¾@tÁ©JI"‘"~§EÁV%˜¥—œíÖ]?ó"Ç ÇO>ª+¢¿ ÖŽýågŸGQ€‚‡°m˜kon5µ0ˆÓ2å­]Ù44EšNÜ·ïß~òù§ CÛízkÏEáX˜Â’¸±¤òÃÃöâü¦ÓðHd‰aÛŽ¤ê4'Õëå|’æU»Û BOùùfΉŒ&É8‹<Ï9>zzr|Z˜ÆXDÐê6qšC–ËqØéL&ÓëÛ—ýF“èîü½&"€Ä›ËÑngß[nÛ;-ÕªÏg‹ÛÑ{UVdÞJ°§É¦)«ÍN#.2g³!U~:xà{¾ÑPvw²‚DEb{ë""H†¸Àë…ßé¶ý(^­íq¤(÷OšÃ!B-J™ïR€¢h¼·³»^;ªhÒ4¯ÈA£Ùï´Z,C6k»ÞjQthã´(S$¯ŸÛhÖ Ã¢¥6‡DÇó4ň“2ÜzͬÕÛ‹íʵ7íîÞ|>AòÖ¦Šóñ¯no¯Tµößý÷8›L]7xüð/‰ãùíù‡*„E}ï÷Ú«ˆá¸Õv¼¾·)Š) ±ÔÞýø1hºÙ¸îºÕï…N|ssmXJž‚ùtãm–öoþ<ƒÕbÆI,¹0H}ôh¸·GQ•$É×ÎAêuw CÝ®¶2/à8"„‘dYÖ¥3£û«²«P¼vqùÆ”´0 qžâ4½–ÕïG7ËÀY?yð‘»õ'ÚëmVÒ$M¨‚ÌçÓÀݘjíüý»¢JDØ+"— ]¯1hoÝðåë×*B^Ë õÉãH¤4ÅÍV«"”¤[³0©ªŒœd%Ʋ*nlŸcPÅYœ ²&˶[€²(iÄÔ”:b)ă<ˆ-Óä9¾×믶›£ÇŸ±)œÏ|œÁ¦fÄQ² l„»ñöŸ½zù|5÷šVýɳGï^¾®µ{yoæÞd~éE!'j]Ìòl¾˜ Žëù¬ÊÒ´ ºµìƻϼX–U­^s'Ó§y‘×µšø%.Íb8p;>g*¾Þn¯–cU5§“eÓªëf«(‹,µÛa„ã7¯~˱²®éJ]ÌB*dž¥ô§“q^Qšnù¡qq™%Õj»X¶¦×<ßí4û¯¿{F¸(²ŽUïï ógiÂóÎsí²,EyÑÝ.IM¢$ÍÄðqä*:Ï à¹ÞzëÊšž„qQViîY! ÚÖu` QÌé$qmQÜhËPL4Ÿ$[;p²0 Ü…}0|ä—‹Ùb•g“r¦LÍݼßïõ›¯¼#!‘¥‚4¦K”ó˜ ä%“geÍR™ -¶+S78ŠOéô÷~ÿÇÿíþ7[>x ìw²"ÿ³÷'b&Favöý“V½?¹Öš|Ëh'%®Jé:ŠH&˜ 9g»j7keU-·KŽeDU£**/R28KeMÎï‹$®:ÂQàx¤$‘8›Î7ËùÔPéh[ÒÌrv» CÄË©‡žkj†È×·Ó©,†¶Î\d¥»ë…¤+öÖž¯î[íN‘âûû[Y†ªÚX­ïy:´çKAm@šIÁpPG¥üüí«½£!ˆA‚‹< a6ËMï°÷áÍ{9ô½½u¼Ýl—›{b ¬Ó…ÑìØqÄ1.pÃTЏÚ8«2i ñ¢öþêµã…§U¸¹鲑x³™“œ:¿éuCä¤ 1)tIö\‡fù$ΚÞßy4šLq‘(¦Yo þù7ÿlvLMÓ©äN°,4qžbìu:ûe+Pà4«ÕQdCÀz¡yRfÅ7_¿Oׇ{G¡üë/;ì ¸¯(êo¿~•Æù£³}Ž–ßÑ-‘`øæÕëã L@™f{<š%a|°·ÿöõÅr=’ !˜N³¹]F«ÍºÄ¤¡ÕÿŸ¿úÿ&«»a»ww·™m&<§œ >5êÏwE^öb_Dš(s4Ëû‘‡dÍ2MÃÒ¶›¥Ø‚$Á :alÉZMÒtÃÌŠÒžm&s0Á.E ­Nßu7Ýþ r–‡ÃÎÃ,ñTSìí¶õ‹ÑK™©ç8âeŽ¢™ÅöJ³ä†Ñ\Ú“ûÑ;ñÓ•­)æqï`ggW–ô,¡Ò$mõ:y–­66'se–ñ¼D#Xæð~²U= cÏõ꽚cyˆá³O>Užç%b*NVA?¿xµ¿³_¯7œp“Féîn_©qq#%ïÔúÿòõ¯…6úÇOüoÿñÿ€”@@%+¦¨óT4¬ÂÌ·—›/?ÿÉb½,‹$-J †Fa€Šnöú Í8öV±ê%&ºj¸Qˆ A´ › w3Kü¤»”åË"§yZ´Is]Ógó›F­½3ؽ¸þ†çLMQJ*zþâ-Ex‡-¹iÈJ%Os (ÛfQ—9Åçç7qš5UÕ$ñ’2jhÝÛ󻔤‰]†áöìÙÊUV”0 |«×HÂ!YÚñ}ÄIfÍT•ã¸?l%qÇ)ÇŠ,¯ä–e±È †A–ÞXLç’¢F=Ï’4QŸäx–cdšQ¤³¸~Lóp÷ð¡ï/«2…4gšÇÒ,Å"–BiFñçžk ¼\•8'Å1…°‚q’v4-üÀµ )K)™C†Œ6v硤‰%†¸ÀwýnË%CJX)1 ÿío^ úá¿°mwãLZµZ‘U”@Y¦¹¼›wÚ.R7yªÝn¤•T‘iX Í3"CHY¤8¡ERfÓ‰`ˆ ÈËœb–¹aõ|Ãh» ŽöÊ¢°cB64•—ÚSt­FÃìvv£82“ *I©“æL% z]løITQ¿;X:vÙª¢qœ4žÝÇ~µ˜¹R¢Ñí•^¯s¬²Ý.ƒ"ê6»qè2ª¼Ï5MîXN¸h5Û»Ç_?ÿŠ)*@XQ«¡Š$av}¿<>= ÂèÛoŸ÷wšUVP¥˜æKCÒR¯ª µž.9©åäv¼Y¯Z]Kååñ|+È(Œ«V½“–ió2§È{^DÓ@34Ž”-«~½ºow²¬Vtî8kñŠ.åIBå”yõún‘”QèÉHÚß9»]24dT‚j±Ùp,:yðxäׯn>ýø‹ÔË9bÂȈ“êŠÒèz+‡”î~ø{Ëù2n«SÓÄÖ›W_‘,ÊÒœã8N®oG¦Z?8xÔé‹*½{4¸R .N¼È+Ë"¢iìn“"õKRE«¼Ûmg8’(Ù´Ú˜¸$õNž=Ê‹äëú•aÖƒÀ·T£(YIäx(¹Ÿ^3R]7,7܈œ.0ðôѨ,Žò·Úý4È(XºIUÜÒ^‹Èq† ÚqýÃÃÁã£=²Lº­:ÉA™»«õ¦¬èV¯•ã" }AL³áÀs’$E*Šaˆ€h:× ƒª*Ž…¤”e¾$t޳ƒ“Õb-rÇ3Ь@+º8^Óu\¥÷Wá d*jäÅ ¡l7¤èªb˜‹w÷š,,#^Vde>ÝN§#×w†zÁÆ[4ZæÎ°w;º £0 ‹Él³¿¿Ój5Â8EVR0&ÉïÿøKª“õÄìô'Ëe»&?üô•TQƒÝád2~ýöëg?+SšQ†¥­:#ÒšÉÞ­ßííD^¶uפ(4ê¦UdÅ<ÄÇÇ3§5x½¥Â”B*(¨¸¡¶û¯_|U×Zë`u;ºxwñÞ‰ìéz>Ûn¦ëÙów¯xA¹¸»®R\&´û·£Û<-‹õºrÔ?-VTA\Š}qˆ‡ºÚȳhl4½. ZžçV­¦ª¦úuËÌ _|ü‰†¤!¯¨¢ØépÚnV’`X5S–äÍÊñ¡›„±b´ÿòoþ²¬Hͪ/6›×oÞBˆ4SàœJSçÙ³ïß_^a§ðÉÙ—DYQq\k×ÂmìU·ßÒU5püÕvf˜µåj+ K/+zÝ6E¨ñíåéñ§îz¦˜R‘Hp£ÓößÝ,Ã]³Öß¾ëí0æea;«Ä8†ßÙÝ­ Cײ”$òâó,#…cL: –áÜ(âE†!&ÉÒ‡GÏŽúΪg4ÎÇ3«#ïôöмH²@ÕtßqȰ “å™Õn%QŒKÌñHŒùjÆ"V€b (šC9ÎExžG@\L'FÓ  §1âÔŠâE•‰í2ͲýÓÎå‡ëñzÞì©>4M³0T¸;ÝÞè~ºÚn`^°¢þöÃWÝZ3 ‹Õvž;eìW<ÏT%X­·—Ó›“Á±kûª®~ÿ“§œÄQ¤ä9v½ZCH~ñ: ‚4,c\! °»Ë’¬Z}6ðæý›—¯_|ôøã•ã7ê݆*Ù› Ómæ$»¼ºÉI±¸­6šªŠ’ÔkuãÔN²ˆC²lšÎrËš5‹geA ’äeÎT”YŠÓ¦Ñô€Sà¿ø²ª!¹ÈŠËÕl2~úÙ—××# n6ò‚`1 K Pä¥m{ª.!¥!NÒȬ×Ö Ûq憩åi4š¾gÇQ ‚nÖ._¿Q•aÙSF½¶uV,˵z…¯ýJÐjWïÜ4÷Ì–FI†3C5,YÞ?Ù©@þöÝ]Âî ßî6'£¹½ðï.îQôI!#‰ÂtµX.&w[€GbÙébºë¢ ì ªŠBb…îAÇÙ,‡{}$Ó2/ÙˤÛjœŸ ’ì¸Ë÷/_xŽ[QùîþIèV“•ñÿúÏõóßþ•=Næ‹Í«óç“»û7ï."úêîjºYÏ šrg9[˼’…1‡Ð|rѨu «±^¬no¯?ýþ—‹ùèç¿øU‚ãéÔFXâ0XGöÊUµ™Ÿ´ÖÉÁÇO®o§a!–jÖÃþ® r8UY%U&° bÄ"Çiæ+²^Ò¥½Y¨JP±ï,4¥Á+¼³µµ.üÞGŸ­¶vE•1ºe´ª¨œm-Žç-K_.¯o¦Ëñôv±±¿}þ-ASj,×ë„QoÔ }³^“"C Úiv.Ïo1Îêz£×ÛSo>Yj†Ü0L†@B•G‡‡Y˜m7›¬Ì,Åâ8A’Å,ÊX¶xüðéôn•ònÕFóãµ,ñ—Ž(k¯VZ8³åíÁÑ·rœ`[ñäÝ·×¢‚v÷îÂãf°Ó»z~£5ª¦ˆaXxx|°Z.’, Ø&ІBeRlÜíÁi»Ù«Q»>¿ÈÒŒæÓš¢ è†U1NKQ’$Ws±Þ–E" J™i¨œVVeN°‚aèŠ]$E‚ \EšÚˆ²2Ddù¬ôe]®qâ-§KºXÿöë_rªŒ½|t{Ë )Is±ÝÎrº}ñò»Ý» &ó;Ræ¦Z¿º½¬wêª&‹©b¢8.B?ÑL•‡ÂÙ“‡O?êùŽD©"ñ"AÓJç8ç±n)¤¨$MK0ÞëíÓŒ¸ð&-JF]¨1ÞÚF<[ÁŒg\䈩QVTÝvÖ4©šÍ~Í9ž‹£„ßöÖö½®Ôqm63Dq,Ë1Èüœ ˆ VëÜŒ®h¶Úé ÈòP Åê %IþðþÝgÏžŠr·T¶Õ6 PSì¤Q¸žxgŸ>‰Ó(ñ"AçTU]ÜÍMá…c*©˜"K{Ao0(I¥á÷~øÅ:ðEQ5DHêÝÞÃçY¿{b˜ÚÝ͵®ï‡¾kɦëªÂYšÙîºÁ2ÍœnoÇ‹ý* ÒëŠÌ3ÏÊï// «&ˆÆW¯^6[+HU™%Éz³Šn®ÏYºL“2ÄÄ’a7Ž£(ŒÚh”Ö‚mý€2B˜ÅŠ%åaµ\Nu]‰³TáÀ÷3E«¦®.H¦‰RU±Õèâ8Û®¼»Ñ¬ÓlшØ7ŒÒa œŸm2 Õkuß½iª"KI˜”áBÕôvèWIâŸ{ðôÁñC½¡j†‘Äq’µfKSë“ÉÝéñ™f2ÃAWâÎpß^yqüìÏÿíl4½]»q¨)5Œ3›Ð*׿ýõ/ßnv:’ ]Ÿ¿¯ë–&z£Y’b|ugu÷*ŽÛ†QËÔ-M^¬|IWÛ…À°4ÍDIì4z³Õ–¡©Ïž}ïðà¡ÀqBJ7)ÙîÖÔ›¬È’2-K`%pBpÿð‘‚_¿úÍÕèܶ3Q1Îjj³Æí*ŸeƒJÄT¸BjS|ù²Ì˜*ÏqFŸŸì졊ç!WÒEo°Ÿ—Y…²h0ˆ%eAâø¤XëJƒáÉzu/ šbÉîvÿà§?¢Ð SY’`é‚Pêz-BQ^\oaº¾|½È¼LÖxŽpk'´jf»¦»ß¾ü¶Â8ÃqBè––©P8öŠ“áñÞÓ*ÁäI˜í÷oãn= ²APPAÑ,#ñ§hïÞ~-É ÇÊ ¤ˆ|j ^ IDATãh† $lçîxrs°÷¸ÙŒ)uÍ R'I'Qæ휖8rܬ÷r\]\~è4qBœ`A¦j&Tñl1½½[ô»ý†¨Üß/‚%¦®~µz ¨œ&"Ë I¿xy¥ ÄÃÁ™· ²s<—e%d˜ÐÝ’”¨†Zæ˜d`+Ò%)‹,UäÆi NPYL (BÆ<žG”¢ÄO±ßnõвÂiASìz½D+)úÝûsªÈÍFëêú"='ÂÓÕêé“GËùŠE Eã0ÌogSENôã ‚y8ïoÞaŒ\¤ehÉhnÇ‘ÑUhŽTENEaÏNONxÿî­È«"ÏÙŽ³™Lº-«€ƒˆäÉvµµjMN¨BSP~1Y#‘»Ê/êadqŽPšF¸H9$;ŽÃòŒÈ+ÛŽ2¡y†¢qæ#–i¾3ìèz”eQdû»gþv«ªÕ;¬H.Kr–¶»ÚÝîí=8?«ë°f6óSU ¡, rŽƒ,¡rHüÙCoíÌ&3Y¡íÁíõ ¨R0Îê­úû÷ïAÎÖ:Öj½øù?þm¯»¿Ü¬)”%©]Äq«Û÷“ÕýýmuU]Ìg!A©¿Ô=Š I`9N„Œ(pÌf½P‰8Ã…f¢·Jäl–¢ $-·Yx–åy´c¦ \g;赊$ß3U±dAˆS7ÍŠÝV'!¸=Æ œíÎÉÏ ¡³’,Qä•Íj#)\™%’¬yfÛÛ<§ÏâÐ]o¶²¨^i6;É)DѧéÚÅûónwŸá¹‹÷·4A’IôýíÖY/WóçÇkoâm|QᣠhªÖ§Ÿ~ÜôU¸áJuš«ò$§Yša)å¸Lç³·ÃÞ!$ÇC±¥Æã«4*ß^ÝÅ!}:†|¸wPòÝï~-³ŠÄk’Âfi©ÊÖ ½#ËF\$ INžß|0tÑP‘ã«Ò-ò(ŒBN6Kwå»e…uY®Â8áXvxtøìéÑv3GHbÚqÝÙd"Él»µ“ã !–®(e ŒÓ$A„Hžªª€âx8›ßûN<]ë¢Î‹¢¨h„JK\Ð,HK×2:¸$¿½Ù¬Í§·ˆi–~3ùvm¿]Ìüñdœø è‹‹Éã³Ç­þ»—ßY’¤Ááp¯»S¿¿¿$1üÁ§_^Þ»±Ç+R«ÖXm¦›í’A,'j‹ÕŠP&UŽsPF£ªˆa IYǶ‹¦Þxuýû´³ EœɆšFN½QñÝ›ó‹›/ô…hð }?خȻ—,s’ÄIaèM]Ò EŒ˜¤)N0鄹Ý=ko&áÿ&g3)FÛõĽþp¦^ê–÷Ï¿¸¼ºŠ¶1Å0q4 í³ï}úäã–¢ÞNî"+'HÓÐе–Ú½½¹ùüÙ'¨Òi”ïíïBºdYȰt%.$M¡HA#—¥¿YJ²ÁKüv³JqQkÔ;ÌqÆñ4üéO~|35µZYR†n’€Ô5ÁÛÍû°ò&WÎÕ‡ûŽÙ!9N²$Ìr‹ôŸì=ØýüG£ÝN³HK‡Á?ü£ŸöëͼV¯G±×´ó09EK\°ë,ÝÉvY¯«HRâ¤Â±]«õX†c9°^.!Í"¤aYå$¡HñYAœÐC€9{üp´ž€2å5E–d…AP¤jXŽ“ÕrÝéu%YÍ«,\]k±<`8ÙÛºì ÷¾ûîõ|>âù`°ƒÔn¶!ÚƒfUÒ³ûuUU Ë4,ÓqâVÝÐÄZØ"Å1,/£ŠÐÎvËðL­Vwm——XR dhTeŽüÔ¨iQ”¸°šfUÄTKŠ AIc’çY 2`Éq‘Wy•i’úIгÅbÔë%Qàv«wÀ1Lœg <_BÕEëêæën{·ÙÌ—×®»ÔÅzàGYW¤¾“ø«yáBä™4΂(-C—”È!IBò<÷ý'ÏxZ Cûä£#/D°¡J+q¼ªŽÎoXŽ;yôx»ÜÄYi†g?òÒ,ç +z³ö$‰¦äy*sÎKÄr®½Eœ¥ëržE0× *MKƒ)‚L‡N·¹ïù[ÇÞ²€fk¯“ jt:f«ã¹>Ër–Ù€F¡Ý¨7%Q½¿[fm½YOã8r7+ÕT›­îåÛo‰ãyÝ^oIEâ(R9I1k8§ÿåŸ~üð¡¨jo^Wæx0Øu½¤ËWa>ýþ—ãñíÕÍ­®Áéë—ï…g4³ÀŒ¦À(- E§DšeY†õá^„‘çâ<7D¹Ý;ž®æ³Ù\døá°1šÌUY)˜œÊ¡í&[Û®0ƒœ»öf5oõ,ÍH’„4k .'Ò˜Ðív»¢ã(ö<;™û³ÕjYdÔ&™ vv—soíoÃNÆ%vr’2PUMžW¹o¿ù/ñÍ\ž_-çAf¼­kû¾"‰4*̆¾u<ÇvEE:ÜÙ»»½DÆPÇ R’´ÑáüÁÏ:‡5R4Ž9‰…D,ƒ«ˆäزêq!Àð ‹ ‡‘¦êA¼©Ê¥©s—i§¶ÇòÔ‹o¾ùñ—?©õÌñÍåò~­ëív¿·Ù,9N=:Ùó‡4ˈf§ã©¦ Eéš¹õ6÷÷³$Ë“2»¼GEÖ®™Y\ªšî¥nÃjE1ìûIUIUf)…tÐ<(J ¢ÈQ–g˜FB–ª`šŠbP„ ‚Pà”­3÷‚ 7è#Áëtº$§æé9U$›oGÿ@—•¤ÕKÎ…4µôóüÒžÝ^z¿øûK“5îæ£ª(À×J½ÑêXm" ß¾z;ˆ.£¥(jŸ}yxs1s"_F(ñÒëùˆcœäqReYQ Œ30+׫(æ°ÝƸðÓWBj²\6ÆÊöLEãxñ—¿úªÓWž>züúí»ýåoŽ»;a5…z1?_¹Õr7kϵ†ª¤Ò¤¬(Rd Ùu$IÇkÇO¾{ýææöòêbúÝ×·8Kò”:“¡ÐÜ3Wö%Ò®e$‹ã¼Ì U’ïgŽTgcæöúbŽó‚P$hÐïíîÖFW÷ò£|­‹Þ^³ÛëþÿÁW³dIbæÌ“y¼«:å«®7}ÛLwÏÌb³»Xp‹…! ƒ #dRèAzÐÑ#ô¢7)HQ A”@ذvvvl÷ôtßî{ûÚºåÍ©ãMæÉL}ŸŠ (WUY¨º)4¬«v²®4[YVUeq·€©šm Ý2Ðûï>Ž’ˆÂ2kµ=¬ÓÙ­ªÁó«Û§wñ*n6Z/U™/ƒd¿uòý?ûÈ­Ÿ|þ›íƒ-;§—''­§OdIŠ×+d×gÓ彃½åd™¦åуÃJ€ÅbÄä¬áu³<Ò5uxu=ظn-õƒ¢LšgPHHvMI‚õ¦—‘ $©„á ßº^ ®¥)DÊlq­êF«=/î–ó¸Ù4+I“HQ%W5$‰Dh^õ¶î¾~¶ZnÊŒqZÙ†ýÁ·¿]k5÷wá:¤Uvrø`½ˆ¦ËÛœçÇ{÷e¹ZÍC’Á½GY2æÓ‰j zÝÁ’f Œ´4ŠtKãLŠ£T3t [q+ªä8õÕrŽŒ—7t­È’4Oëu r˜‘+°¢\VÐ&^!†,Û®:™Œ–ëñöþ6FBFØ®×*’ (gU>.l§î8¶Á:ŒÆó™"Û³0dP®©Ê:Ì—4 +ΪB0%-E„it°½Ë„HÊõîÁ`{°÷öâµ×è Fƒh½¿ïâÍéåõÕñÁ#¬è7·oM/ω„UC×f“™jhnÍݬ’`³nõ»Iœfe®j M °(ÒJV±biëÙ°TÂJ‰*Œ“’§:´ƒÝÛéÝìf:8ÚeÕëjÛµ,Û¡¬#¿Ùí·ú(XR&ì†5\Ä 8íxûA2¯ª²ÝìaEø«‰ \RÀ¹iØ%Ëöº{QMÒ[Ëû‡‹`¦HÄ’„çxa”²ÞhÔ°jýã?þÍfSW½,Ž]O£È2Ð •d¼L££uI™¤ðÁ^ž’›é0Öè´¼v- Ö¹”læ~•³ëÙXÒÉ8  „ éÉýcJIÅ8ç¼ßi•„AŒ Qì ŽLŽ&“v£ßi7 Œ«˜2Ï®Îʨ¦›$¥dyr3;?9ºpüŽ¿ò)¢ØW¥Úý÷\Ÿž>zœ¤«hµÙlÍ×#YÈE©š´,£RäóÓSAà ;(i±Ù,°‚ÐgëEÍõâ$þþŸý^oË-“‚êîy@”¬*0בª¬æs bIæ(‹ÄEÂQ‰¹‡Ág_ÿz¯ûWÑfˆ\êïÖó".Ãr4¿ò×Åv÷$¢ë$^Z¦7ØÛ_Þ^ ûe$3ni¦mT±¬&·*‚¶Ù-Fé"¨*Þh¹r.°Š¦á¢éØ )“¼8iß;9z„t2Bi.„è÷¶¾üøKy£ÑO¢@bUª¸Œ( ×í­.gŒ–‰dà4M®Fç$Zw;ÃÕõbyýù7/^_Ü o®“õo~õë¯O_~3¼zsûñÏþæHž.†ÙégÓƒ‡÷ÿõ¿úI¼üúÅiŠ4O0Fß¼}ÖìØOž|›ÄñËÓ×A°AA¡®>zrDq•yšåeµ¿uTQ)K i¶æ©²Ê$ŽP3m&a!Òßûx¦‚èÆ_V T9¶íûQÆ7ïܯ[MIŽ_~þKP™ƒîölýêã7A¾½ ¾øäUd‚ YQƒû'¿zþUÆ…¥²b Š,-•Êyï“Ó³ \XçŸ}öõ‹ç_oÖË¢€¯®¯uSS±,W˜rº “8X¾:=ŸŽ"Áea»ÙlõûÓ»‹½ÃGÛGÛ¦§uÚíÃûýŒ®5 ‡Q¬©Ü@Êt¸’”U µL–ºnT„K·LC0HòÔuÌå2AßÿîF³é:$ Ë–2_Í$ˆ¯/‡ÓÉ*õ ÇÐ(äÂ"ÍLÃùçÿú_]_ŸU´Ü><ÀºôÙç_vë[vwïp'ž¦ªšýž#ë³É@ðñãw£"G7NÓ±jZeQ¼üï¾ï/Òñ|Øk9f½ÅAœ,¸¤DÅlïÖW_}%£Þ >›¬ƒà,ÞäþºŒòK­åýâo¿€¸â"ÿåo>/ªrÿè0Iâ$$Ò8©Õœ2 ’’lÃÉYEI±‰$Ô$[ƒš³cwë}ËTÜzïðð$+Û´ Iœmwv˧OÞÑ5c¹w»;Q)’eÕC„‘eÖƒõº e§1ã ¥®Y‚¬HMÃÌ¢ÜÐUÅ´ÂM€dhèfì§’ŠVhÁMÛ¾»f Ù>êûËõÅå¹.æ³`½Œ®n..×£%ÕðvºZE¶…ñbî÷·z///'ãP×qžæ¦ªw[2Ï›n›–eQæ%% ËÐ’âŽ[“„Ó0«˜¬š„F–Ñ“”± ‘i¶ÿáçÓ¨w»ýœ$ V€Œ–¦Ýòƒ0)Ö'GO²8¦,S4Gw-ÆË2+Ö›¸ÑiºÅYÇšªI@ Ó•ëÔhUX][T\@¸¸S2z7™y ýáý‡Q´·¯^|YÄtçh;È6ËyÐj74®ÖÓ5à–m'±0“*0IR?Ü„žç¥IRqFDY3Zá"O$Žú‡;7·W¼’tÓÈ¢D¦úÍüÌ_¬ÞûPwÔú7}ø=hHwÃQ•3Ý4Ó$o8Þ&öÏÎ_}ëé÷$Hg×—6ï=z0¾ÞÌI’f»3Š<I;?½juºE”( q€€Ü²ZËuLIIÔxq¤y’±‚eEQþª×j´Ú ˆXèG²b´^Ãê2¨UÐO¢p: 7é!­WosHó˜$òýßýýýþîr>΢ùÉÑCÝrüù5â²*If+¦åd¡k™LÚµîÁÑI$«áÂÖ<¯¦IBãôzyÑm ’¸\Fs[5·[Áeݨ²®’¦9©i—0%±©»B B3JèèvÚn6£g——EQß?Ø„±†5&x«³õßùþÅÍ›«77ûÇǃí³oNwö¨Ì3S3T]µ¼–DËj=Ø;ùí¹KbþäýÙH†Šìe|ýøñ‡IVøéÚÑ›÷¶¿u3ú‰Ä­v£Y«kjáfí¶[ªb+Juu{Óª ,×êõÕt£»j¯Õ¿½¾8¿ºbˆ5Úîd¶´=·(ÒíN³_߹͠TÈ’‰1b€ÜÛ¿§©òõÝm–¶£¹^Í3£ÉXEdoÿé×ß|¹ 6AËT,Û2e6_kŠ*ÔW\áZf™ç~¶šõ¼$²ÝX/¦¦S¯^1’ §æ¶£u@Ô¥ní” $8C©ÛnuÂtú´Vó°L³ˆ¬V‹zKk5Ie–i†SñŠƒJP8pêF¸I¾9{•æñîþƒáõYÎJ-$¸ÈÑf¹îƒí­ÿç¯ÿ½¥›»[÷.§£Éäú½‡OuÇÒÏRšWÕáÑv’†Bðp5i·E…+ÅY&éNBªç_~#ôøÑ½p³zuõ¶Ùi,|CIBU¬ºw-Çi÷ºd¬¢¦^82êžç¹UEÇã;ZˆÑå—׳(Î7ÁC%œ…%Ì—ÑíÛ×—ÿùÇ¿œÝä4'Ó« ¤,/«NÃìµÝf‹¡ìGúû›MTŠôñ‡Gƒþ¾^£^]Ö5Å4‘îè?þO?ûõ§¯JV`³´ôL¤aãf8›\½^¬bϱ$‰Çq¼µÓô?ÿéóª*††­™LâAŒÌòôüêù×½}wé¯HH„ Mñã2È“o^¾åw 'Œ&ÃÃÝÃÇß9Ò0|ôøq£Û5ud>_S½:»˜Ž®1€Îv–Çm·Ni¹ÝîÚ¼nhÈô´p“h¦ÙvšÃ› Ó”yI¦KÚ¬9ÝZ7Ü–Û<ìwƳ¹SÓ&ÓÉÊ]KÊ+JúïþÍ_:äm5ÍšÙü'ßýóBºûèø”÷Þ€%•QÞ®Õm£9œ¾•þâãÓËËÓ‹‹Ó÷~%Éè6x;¼š® Å©[𡨼¨|F©êyHe–hª]o¨h»ÓO“TÆJZ–BâšbEYˆÊT5 D³×œ. 6Žö·Ú»§/^ì7’8ÝøÑt9OÂÌkv¨œ‡wI²®o¹Ÿ<ÿu.ƒM*xyuv=ßœÏ*–Þ-¦×§C(ÀxLÆÃË«¡ Út6#9}õêNVk4îFó"Ë¡q’CRUTâ\4êöjEÑëxºª¬ƒM‘!Çr2R*§«Åjœ†q˜g¯Î_š’6š­/oÎ]à ¢MAÓÕt­ •)x};¯9Ž©(!¦m"¡¬Ö[–¡ØÁ*ow·TYf’¤iÖÎAšªÊ´,Š¢Ðtw1_ ¨ÊH¢LE )F#-Ò4+œZ½,JÈ1 ”¸QNŠ(\º¦Mª*7yJ*‰–œ²ŒK&“^­Ïªl,w:Ûm¯1™Ì·ö÷S Öy§Ñ,˸Yë½óÎóѫ¯ž_œŸ`U95L'J|BKÏmȘ¯Ã¡é2FrÓ–±¤$iEHªcWâØ³Û2ºÛ[óÑe™Ó”ÌúãY’-'ׯvgç`4|#!ƒU &Am8 PJLIH1]·Ý-Jc^1N™¤P(°DU‹¢ –á-V#HäZÍ“¼GLªÊ2kè]IyYtí®áj2VÖçÉàhWÆ®¬Yª)dZ]Œ†Ãé9g€Rðòü'¯>µ—NŽ “–þJ7tJØÝÕÛZÝŲpëçϿܴUMßÌW‹õ¸s°ŸÉ*^–‰X‚8ÉÊB"ON½½>KIÙëvu„×\Ý0[€©’Н®/¼Zâ*IŠébeÖlSµƒ òBpÐvû£Õ$ZGóMl¹êzík’’æY×¢M<™ßukM@JÓ4ÏV-+ò¢b«MªI¨åy›(á€÷[¯¯žEA臅®ª%%q”$W43вÉ||pr´Ø”š,o‚Ue:u¯.kÊõÛ·÷ïqy~ÃaÅ1©™-†å¤ÒV¿}=~3Ÿ-¼zÇrÕé|NÊBQä’1UÕf³‰­Ze•n–k`¯;¨x9g*Há˜î|9 ‚%àHHÒ|þvµŠKQy®……öâÕ©Ûp{m³^ûòóŸ´;´¬Š­ÉxïäP¢(ðƒN¿³µ³ûúåW›8 ©$UB6Õµ¿ÎãxçÞþõÍÝëÓWÇ;{P’7‰_VQÛÙöçk¬IyTJHr-c¼òG[ô{?`ŒÄ™¯òrµV U²ž®Ü¦µ3Ø“*­HmÝ´ªRÂ^.×YAæóÅønuõf|°ûáÿåŸÉ*cŒó4áeµX-G‹ùrµ04ûçŸÿ"ί-ÓJ¬â´*IUI@ÄåÈßì¸É¬¼y;‰E⬠Sˆ†…fhQœ‡y.Ë àì|82$ˆ$ÉkxŽ¡læËGß¾w°ÿøùg“ó»ÓwŽïÓ”RJj–Ù0 ­ÞhiŠÕ®;Šj_ßF޶v†Ãéhq7²7—#Y-€.¯Æïœæó8äEÉi VÁ,LÓ8É8¤ÛÝû‡ ˜·zÝŠTªÞ}xϲµö'¾˜Ç<>9n×{–¥üÖo}øÁƒ÷„š"ÞN'ºl:º¶IY’“š©O—Éož}íµjѦDJÞ艫áÍÖ­éÆb5ñÃI­Ù¹^gÚZËõÚŽíGó4b§ç7O>œÞŒ¿zñr8{ûâóçgožýæÅËçßœ_Ü-ï¿:}c9Š®*2Ò£ D½ÿQÁhŹ!g\•5?HÇ‚‰ Š&‹åNÃsT÷`o§(b˶c­×Ë›«[ÁËïþðÿû¯þŽ–¥Û1D¥þìgŸÄ1̪©òrãOçkU«QÄÌ6º$yY±,Nšv ËRÅsÆ% i=¯6^.$)WP/Š\•‘ Y‘Ò(wív½nQ¤b-)KCQYMò|„û[½¢ ‚+ФHœ‡I±\úI”müÕÁÞƒW§/§ÑêôWÑæë—§û{;zCÁ8NJ‹ÝÃã,XU!EÙ:ØQ±nÚžãhšj5[ÅêI2—¯íEËÐtlÝ0uÕb‚Ò²Òe‹K@&kvë±#I‘aè¶¥4D%i–ÎYI ®©rZ&ŽÞÊi XáYmo«ã º‡w¤€â^¯µ³×Á™nyöÛ›oÞ9~ÇéwA• ÂKJ(OE!fLPÙIüéŸþñt´û E’+êuS”UTdeI• JPR ¼Ýٯٮì"‰H ]“ÛõÛé[×¶»ÝjJE‘öÛB‘ë5Ï1¬áøj÷þ=™±(Éã"vt3KKE–$„D! À²4«*X÷,k³ë™Q³‚õV¤éd†8B¶®6"…½û[³ÉPÃÞ,„T™c( IDATzmíÏ“$Ú?zà9öëo^D„ëõÞÞÃé:|ùéÕøns|°W±B7tS±ƒr&k 'Rg¿Ç(eTÌW£Ã£ƒ8"Aº–ÑÛÚŒa]¶jžiŠ'ï>ùúùsOG÷î ß]_5úýºÝ„”¨ºGþ½{u[+r2–ÇOÖëM¸&+UIwöŽfÓ;„ãµ±ª¬f+k°µXNYE‚8+¢ÌQLE‘1PÒ(ÚÚÙŠ¢˜–Ä0p³á–]©„…¬((I „lÕ9yp4ߤIJi$•$+r]Ö€L@‰Ã­N¯Ñßv÷üíÛN¿!KÊÙ›S΋'ÞÝøË0÷·§³ÙɃCU¶¯Gw;#ååë»nß>Ú;®*1ŸÒp£Â9©â»ñêähpúz’µ¤"ÛrÊb£èrF€¢Ë³ÅÍbêkŠÉ8‰ý, |ÓrÝQ±²XŒ¼æ áºBaÃu$qIÐ*OªZ½%¶¿½“ä¹`Ôv<Ͳ_~ý)/á²éÔ#דñöÎ6IéË×ç±ÃÝp½Ôuy½,,ÍP4‘f<ØÄ®Ž·{··×õºž&ÁWg/~üìßÍn• ®ö÷»Ë›ÙÕۻÓÝdœ~ýÜõäÇïëæâ²;¨+ŠÞlõïJ@.Sâzõín߯ôøà`ËÞ_D³pµ†Š%UEòáx>Ÿ-¯>~öM!f¤h¸†f›™àº¿Õl'ÍHBäŒ LrΫ¶$d qRѪÂX%e¹ô!° „c)-Áíp|xÿø³?©(‚ñê›ñ()C…á^ŽGËå’°$É$Rf†aFq¦™ª€Üµ‘gaDZ>ýúþîQ¥–q¹Ú9î¾:{üø{ãÉ¥bb ³ö®¾ªÆÿæ‹ë‹›JÒ<Û¾¡¢Ùºæ'I‡H°áj1O‚`½üâëg~]ߎ®n†«ù*ΣáÝ$[Å—W·Srsûúí«—wá&1±6÷£,ÉLUõD’Äjµ¾=›ŽïNgw—ÿË¿ý_± ß~ú»AI@ŽÑÓ'‚(E("„ü(ð\GERY”ŒËžcSJTMÉ :]nt×þé϶œ/jV“pôòñA¿§É¸Œè|6 Û4±)eEQîoõ—«¥¿I*÷¶:“…Ϲ`•0L‡”d½Nd¨ÄY©Èê*ˆ£¤bHÂ0qÝq“,S¡ÚëvJ‰òB`Öid@P’B’ôVÛ,ÒIn½Q÷ýc¹\Ph†fT ÂuÞ [zwwçgÅÀkfY¬[-*Ó´ *²%+ŠaaÀPJ|Í–bëºnÖûƒc¨ ,‰*#y™·»]ZÒ0Û , ÅJË@×T ac 2RHK²9áaä{žÃ)ãŒC™#!“ª¬·ê—o®²4kõ<®h@ƒ¼H5p¶uM-y9›CÆPÈÚ¬¦ŽçÌÆó<%NxœæXÁ$&XVôOxvq>ŸÏ8¨j–¥UYd:20Ô’"uÅ|ÿ Û¯ïÍf#YÝ莦ÓéôÎr»¢Êò´Ì*ÔÚ©«P)²˜#ÒöË[AJ«i骲 “å*tŽàh½œ÷vv(¤,9§L`Ǭ×ë^F• Û;a’ªR,Ýîögš‰ý pÜúã÷ŸÜ\œÉ²å¸vÓkNGÝP2.ÜÚ ÞøElöÒ2j{ÅTú;ý<òà +X6èí”% Ÿ…i6“*´ —ñTw[ëùʮɃNwz3;=}öΓ¬RÂtCY¦YÝsXž"¤<Ú;Üúͳ—y¾´MÈTgµ˜0Vã„Ud0è|ñü¹®¨¦k›ÍíÝ×v%Q)*…ï¦?JÒh“äX‚ý^g¶ÚT%«Yn\ XZVºjÔ ]ÆZ^dV Je™ZuM“Ì¢$›(áum§¤…¬ªªƒNÀ\Wjó`9èÖdÉ 7ãV»‰¸9—eM— ÑíÝáÕ‚ˆðþáÉËoçþêáý].”ùfá:öüfR³]úãn³ýúÅëåf *â¼ ‰ààv4ï-&“oN_ÄãÙ²d²fØûÝžá6vööòpÚi·½†{vþ:Ï2ÅöŠÞÌ~ùÙç;ûÖ =à žílï$qi5*K©={qÇq‘&œT”AÉ•$âœÀõ0¼¾þù¿ùøÓ—²“‡Ë$Sqt¿CK°î òäQg¿§`6šÎ$.$+gaa]ÁNݮۺ¦Y/Nß&aFªòübB‰ !EÌ!D¦s;]o–;{ýl“GQÐjÙ¶í­üÅу]š‚z»yïøðïÿî$ <<ôÇñ¯õ¿ýíª¢‚@®q”eû‡»•(ò'ÿ4 iž’^Ö\/в’‘2‡ºnü \!¬BIÉâx¹\õw{e¨ÄÁ¤Ýꫲ“l–þz±x? ü…?u¼ær~¹»súi–‡õv»(á7_¿l·šH¬àÛó‹F­e»^Íh\œ¿îõÚ«—·2’@ʼÐUíõËá­?yx4øêÅEHÇÕ«Ì’Ø¡.›ªjbÌ—þº×ìÖlUS,?ˆîÝÛ¹­vÍP ˆ›¯}xݲÇËu³išºGbÒí¶Nv¶eÉ4LH<õý{ÇG‹YÅÉhº°ê^çë( ’È”ÐþÁýW/>u-WÕm$R!&zäÏ;»yF„ˆ÷öÎý ÀTÖäéxÖ°õÉ<-âŒE±©ˆˆ›®®ÉW_~Ú¨Õ J­…hú Täßýão_ÝÎÏ^¾xòøÑx¾±m}û°7°·½f­·Ó¾xuåz^­Ù\Ìæëx&`¡ Æhq§cH‹¬»Ûó×ã·çWýîöN§};º²Œ(ÇF½Óñ櫉c·ˆ ed”Kf%•``Iî¸ÍMPJ‘*Vãè§¿üræ¯Þ~sóòÕm°¸ýæ7ãg__Ïfwg¯æ?ýå§j¹~ùìêÞþ¡×lª†lÚ"ðE7?úð;ëQZs•<yFTIè¦Î+ $–eU¼L[Mg9óÿÿð¿=›~õÏþø/ÂUzÿÃÁñÑÞ£“ßþ^·ÛìþòW¿Žâr€E“eÛP1Ö †$ 9¯a”ëX]úaže›dM(•©´WÃÙW€ñb¶ˆš–) =½:›¬&—“õlغúâôlt5‰ :ŸûËõÕååt>]%IJX/£VÓ¨*fÙâjš&Cତý­þxè³’uZ P !ÁškŠ‘•”ª*«ºç•eƱ„ðƒ½Á:Œ@º!Üít%È3J«Š „òŠC Ñ‘L EÑa”¦*4±ªJC›„K# (ƒ¢$„UœXÐRSp‘•Iš@þÿò/‹"¬Õ»óé=zx"€FP¥eYЊRV%¯TYÍgV­Öj¸i^ÜŽ<Ûâh††>cäŸ|ûóÙ°b$ʪãý½Ë뛚SSTs­$3š™º I²^ÆÍf£ÜÐô0 uEFm’¸¬¨-ËŽkç ,é…¨()Ë ÏHNii)ö×çÃ8MO‡³©O‹EÉA”S¬‹n³wu75-Œ„q=&Y(q5ˬbU’+AM]Å2Ö)ð}̤8"mÏkØ]BA‘´Âï~ôÆhŒs¯áeIBŠªâ,O ,+–e‘ l׌ãaM3TXaê•D%lŠ$Ù¦ÓÚÎò€B)Ae$ÎBUȣхÕí­¯©°Ì“Ä'²ÛÎòvµ §ï¿ÿ=šUeÔÛ Í–!ÝVÇ÷£­Ãž†¬üû‹2yz|¯Ê‹M¼Tee2›Ù5%ÊÓO~zZÐÜÒô4&% Á Ê(b¤¢0]Çi–€ð{?Ìò|>Ÿ7z* MQUV$ÁÙµÚèò­*)H–!'QVÓ-=LBe…ª×0Œ¤`@° ^“¬œÎ&• ëfãæú¢ÖpLÛÌÙDS˰Ǔ Ýi Ê_Ÿ½~p¸¯"뫯^¥›ëãƒ'—7š GãÅË/_õO$¦i~ð­''G†£Ûû÷·eãE ͉ãÔëMwx}—¦ëÁîÞh¾Qœf»Û'k©(0ÍX­æšª¸¹¾+KÑíÖ)áÛۃ£½õtÞkÝ[¬'²v¯G¼¾|Ûªy;ýõlU2>zóv¯¹UišŸ,MÓh¶w w£ ”*É^-M ×ֆ˱©[§gWmÇÖ º½›Ö’$Ä™ajY^Y°µUÏS~;é&>ÚÞMŠ‚QniÂðþþÞÅÍm–d¶ãzŽw=]Õ @Q’ªßnq^u{=U·—£Éòä¨óúåUçPIV0KšTœsÈ;M÷Ù‹¯M×mÖ”À`“Õ,KpE“œ ^E¹5èÖk*€D)fld2”7›U»ÞØäær¨ë–*jëÅl6_cìù›U¥ÛÙ, ƒå;O?¬hõüë!Iw›÷üͼm{wç(¤‡ï¼{{ws{ûv¿Ã˜òò僋«Qeä°Äà÷þêWŸoÖÉ{ïüöìf¶&T5«az´áÝÛóf¯{3Mg¾`”\)#)—aœW’¢$Æ*ÂË´óBfÃ\T‰ÐdLJ’'\â¬åh‹iâ:Úw>úž¬ê†n/PU«Õ%¨ ž¾ÿÑ{}o§Ñ²F]ÅMÍR„(-” U[„ë8‹$ÉXoÄÞ`77_~ú‹¿ýô¯Fãëû?ÿÕ7—ÃJÌDP³Õ<£Bâ”kŽÍªª¢`½ƒ‚hP/ Ñt…QŠ¡dhj‘.X׫#ˆÒ¬ì7[q𛆋€\Ò"E‚ -)gaa=ÎËh³ôzÁ:²mEÖUKµLSR¬ë2”BWó äH“ ‡2‚QA{^@PR†Œ²¼$””±¨ -I³®ßL|Æ@Í1ƒ(¢`§µX'E•ÛŽ<œ.7y¨hr©(K ­8¬â"NREU…y‘¹v-',ÉÓ‚›$„0Îâ,PJÒÜP ˆÎ(„BÆ*¥´£÷ÞûÖS·î.fsÓ0ÐÞѾ °Q.rBª," ÏÖdHR§–‚"B*J—«(-ªºc1‰Ñ´lºÎN§ó‹ŸIªdY,¤ñzR ÅÕu„YgÓé¬×h„g”&E^sêAÎaZ¤¶©˜²;Z, C©Yu×uü Ør÷F«ÞéšÈn*[5£×tº5§Y¯×ôíßKàm³±U¬Áû4ï„Jy¯óh¿qTk;‡Û»e;F§I^º5ÕpÌõr£Ê|«wx1AD)ãõšwô¸çéý³Ëë­Acº•Ey°?Pº^û@âœ"ØÖþîÕÛëz§^oµò(ÒɘV€1n™FÉ+Y7%AÓ¤}¿æ:‹•Oʪ ,9BrÏÇLR+MgKÀ$Ê©,!Ày%*‰ FD'YÔ[ƒ YèHËJvðr1 >žŽw{nÝ{ñæ,OcÁå节£(¢HG2­XÇ÷·h½f˜g™nê3?ÖuÙ2ôù&„²xp´¿Œ‚<[?x°7ZÆT*Kg³µ®PÏóNßL¶·ƒ­Îb4Ó] ¥¤¨Ê|çp;öZ%†]³Õºï/KÂ4I)’¬ÕîNGC§éÙuw½šÑJ@À8«TÙ®Êb½^윤ATÑŠcËД, 6~¡èªbʦåúË•UÓjޝ-K¢ärtn0oú%iúêím¿]«5›Ÿ}üÉ`oWP*l5êiLXœÜËRñêÕ—'Ž•â(,Yb¹íaÖkn'A–ëý÷n.¯‡×#‘ºíNç‘­Éq¹ö–ݨgCal‚¢$e¶±]§ÈÈîN/N"ëÝ^w±¸Ïf«š*M–«v­¤‰‚QÓ4çiGñn¿;*’¤MσÏÃiœ2ÇÕíZój8ª9ª¦zDŒTšªukuÛ0šµ:@âÁƒûë0Ó¼1h´GWggHWYhY¾³ÿöÍå Ûov])#«ùäp?˜­eÛ;Ûa°ãĬé)—³éñáÞd2]ç…fjža'YÆš-«êx±<ÙÝÏH.q%K¨\îjZ”U¾Õêt·¶nf×Yoæ‰Ô5ÙpâÍüw𣃣㳳϶÷w±fŸ¾|¾Šæ†êùþ°ßøó´$âèþcÄáÝä&)ÅÉÎA\úíA/‰ˆäºm˜u;.Ö;[[“Ñ4­ÈþNkzçiÝkmC"$X)*¤*ây£ÙÜ´½žóÑ~T“,ª~¹¸±IÛ5×Aê¨j·?Ð%0YM–ÓÅâ.z{1l·kÁ2_'‰ TÇÐæA ¹$Eáï|ðþíð:-JJ+*$Π®HIAT¬Êœ‡kªLˆ,giÙš¬Z¶a  ôËJtn°1Ç[½ɘÛrW¾/ PÐ,3Æ C4ÍHû Z¤ 뤔U‰4-H–g‚CCAAˆIEYEÒ¬’t·Ã,³cMò$ª~½# ð£È5¼’³peHº¬à4•AÛ0 %¥¦¦¥„&ñ v{µ}sÕªÍzCÆúÅp8ðz42–è¯ï´G6ª &Ûêo£ÂP ƒ°[où›%V‘¬aäÏW«­þnž‡YYȲ `u0hä´j5›¤âN½1›ß¨†ŒCÅ)jD\&Ý~ íÇÿü½§dS¾ºxc¸Ö µu3aaˆâ2ø­'ËùÒ÷'ýÃ.–œ›·gíA¿ô ‰°þÑÖp6ut§Ûïæ9½¼¾ûî÷¾µ^ŒS"4Inuw‡“³²(¶z»ýAçÍÍóŠƒ8ÜZ›‘Z˜M»½í–·ç6åÙ|Üëì-âÛ4Š9áLÍÕ­E¼i4ûO}p^™ΣbçhOœq3¼¶,Ó_YÚž;¹ÞœÝ^bIÔl{±y–{1šŒlíl¢h•D ’²’åEÖlxiÁ¦ãÈ’¤¸Õiú«VSLU/I¡hj–I@«c~÷ûOa)«šRïxóQ ÊŠãàŠàJ°Š…Q”Ÿ<>Þ„‹~}ïðéî£öo5OtPU³µ/Ë*BxŒþüG´‰ü»ù¸¸¢*‹U"@*N)kÔAIˆ†¡ÁÅíå ÌjšƒŒ0TPVœp!Ë\‘” ÎtMÏÒB×5hiñ"˜¯6*–%ˆÎo¦žÓ%8߬)…VÝ.¦€s©¸£¬ªò¢ª×d”TB¤d«×óÃ0-8p¦jî* mSÎS*É‚± B¹f(•`–¬q Bo'S JIy×4Ó1œñ205ÕP­¢¤ .eLPQÔ’$º¡Y–2_®¢(7Ä„D*ž‘R‚j–§­–Ç9–1ÀÑJè*RU%IòÑ„ÿÿÓÿ« …súÛû ’ý$– âZ–¢éY+Цê `Æi;½îî õòÍí¨ Ú$¼‚ÅñöÞ{Þ­Ôpÿà¤î6ÿûÿæ¿Ê³èdïàÝ÷Ž?x÷w ›ýà‡<¸÷ÔnË»ZZ‡Ž´lhå<ûoÿÍ )·;®×CÖû½²ò“4vÚÁnïÿT©ÁVÝ¢U5Y4G@SØÞÞ¹¸>~üž[w7Á&£q{çpzwÁIR¿ bÅÔ†·w!@šáL6ñ^¿ÍiEs¶‰ã€KYT"uÍúöàH·¤ÊüfÄk„ÔpÌV£Þ‰ï'¯Î>K’E’î «@S¦jX•õ`å6Ò]d%2Ä "œ²Ë(]†Þ¶#!åôÅYNBËv7Ó%…DêÝÝÄõ:IH„Í­&IËhãï<ØF¹Ôô:N¿¾üÿI¸¯fË®Ã@Ì+ìÏ>9ß|o÷í€î R¢Ä¡HQ*M°­ñÃhª\5~ð£ŸüCüd{ʲKS5VfJ")’ ht£Óí¾9žöÞgç¸öòƒ¿ò]OTC/Š`9žÆ‹½þHàp2EèE…\®¬ìq–f1Iõjm>3[FYæeŒŠ”P(Ç14‡ ¤‚PZ%M"–•r‚JºZS+‚\ñ£¨»¹Æ)åÏóóJµ\io:Ö4cbU©Yóq³Ûqœôôäíí;÷£ ½:»*0R8ae[ˆå\sÁ¨~üí8=ßÒK©Ç- IDATª(/Hq’É’™e™Ž½l×{ssîÆÓõÖ®í:aèiFP‘橬 g7­Ûݵzãùë׺ÆW+•óË©¡˜Â'¿ûêñû÷œ•ÿúðÅìZi¿ßߘš—Iš1œøÎý[Aì ˜aYÅ™gªVÒÊŽ2LJƒY³…m…†(HšÀ@FàE/ dIêÔ«žkA†§“æþ|:ê·öŠ 'ÆqÅ£œÈé籟´Z·.¯1e°Ì#ò4­wê£éìz<¸óðQâ¥,‹\XKŸ—˜v»?¸ò c´ZW§Aæ‰Õz¿V.’¼ÝÞ¸>:»õhçÛ÷ž~úëRµñèÑ'¡eϬá÷>ùñi•õÚd4°–fÙ¨ªýüôœ’d÷V§I˜³XƒHÅÐ^­íöƳ«Ü‰’Â3dNa%;³ã,¯*ÞŽ._î®Ý]ZË \a,T*:_V¦óét<_އkë××Nä¤R³k¨Wƒ³0HÀåNíàðM¿¿¦iЍÈÖÊZëoÏ7¢ŠRx¡«•´• ’«²©øöò\RuãJY„b Ý8)ñ‹‹éÂÜZ«fY‚‹a¦iJšADA#Uo7ÛËùËÜÒœl¯ß].byßu´Jm¾ ˜ôúw3'Aš$D0”‚€f­;6ÏYÈnoìÜXç×§×FÕPÔÒôj&Ëòéð¢QoÏ—öÌe‰WÖkƒK•gE‘ò°bT¼•¯ªÈsÍVýf~Úmvê5Û™Z+st5!EªJeL X¿ÿï _¹p¦ šµ üR@Ó˜×)^™—«þí{Ý^½¤•ìÕTTéjéÅ®‹™ìäì²¢ª¾a¦iR«Ýp«œ¦³ÅÈà5' Gó™&š$z® Wªè3{VDRA…ÏdQ^¥YÇÍ’&JÜxni¢\P C"êEaž§Š$FI†.)ZMl>úèÎt´ 0x,p’9_h†!‹ÒÍäúÿú/ÿÇú»olÛ2Ck£¿³Z oííƒ<_Ììüä{ñMþ»£ß}ïÛï?}~8ŸÙ Ç»QÈ ¢& EA €xÌ"APL²8Ž % Ècå²”Tkò|¾ŠÓLDEÐÒ(›¾Èr ¤sÛ2W~»¬[QD A,ó€Ãiœ@Ñfµ1´€,x–²r" <@ˆä™ 9¡E–z~ªˆ¼¤²0sËâ8Êq²ïy˜A°À ‚ƒ¢(Æ€@-{¦ Ãp$ó•“e¤((„8%i”Ä+p˜â,c(f Ô%&ÊHÈR "£²Ì@‹‚Š/sRJ²œæ byFÈ’Œ‚“‚€øˆ¤ ð‰P!Ì+•.×zM]å99NrFÀ˜A‘ ='e,°ТñEE¯œß¼ûpßw’^¿:{™†ñÎÝwK*œ^•_{°wúú8Ç(ðÆÆÚíñÕe®(B{ûï.®¡ïȲ®è‚åzæÒTuÅ÷}YÔ$I”Ä¥0ŠüíõÍ †"•J•§Ï¿ÞÛ¿·œÎb×S NÔ«óÁrDR«"9U=|úVÄF§ùÉg¿ûµ"IyZZ4kå(ó#Çï¶Z¶=§€è²È±ü‡ßýHW–1Ž_ÊŠ õn§ÏKE°ò*åîÂŒ®‡iêí®mÿú³Ÿ×‡„v}M­”?}ñÅèÆžþÅŸÿ·ÞjŽšÜÛƒ—‡Ïç{õp;õ]CÓ›µšëy˜aàÛ‹¥í­ö÷ö‡WJYçNä9Û["鲂 ý ˆâ»{{ãÉÄÂzÝpü$ CÈ`1†d@M1m›Àp˜Àrƒ’ª¤i®¨" ™’*F9@´ E1§p«À?ùéï¿9x=›x½õvÄ0š®BŠL?ü»¿þȲ«Ë‹gÏŽßLÒ‹Ñ“zYÝÞ¾—dÎðÎ~ùá³—Ÿ»Á x:Z>ÚxD Ø …AV„<¦„ìÕKN諊Êò ˜Äñ}a €¦«Q7[Ugå@HUMKâ4D•å(Œ)BuMÓÐKˆ"*’,œ¥9”e@œç”åu4ó#$±lœ§iJÒ,Ö™Ghᯠ*Ȉ.ò")rŽãü0É MÒˆäP丒RNR"IÐ žåªf¥a4†åxY³<“E‘f2ÏÆIÈ |–æ„$<#0ˆ ³$‹3E–*šHd©À E² RH—J ¨ | ¦ÀsÒŸüøÏ8áyy8ºÂýþºÄ ¼0ƒ’¢H‚P˜¢€2U¹¸™ô:u‹QžÏ&7ýjg²˜íààˆäÙOÿôO~ùõדÜÛÛm­o|þ³¿_ß왓©ZnE‰µÍ+J¹·¹æ9þÜœoß»ëØ ŠswÖî÷˜BתuÖˆ“4ç 3±¢ª±O£hl¹~§»w}ýFQŒno£`cI”Ù<Ëay/k¯_?ÝÝÞ#1¾¼>¼ž†+RPBÀPD!)Úø*ÜÜ]—$Œ€ðêôâáî=’e4KÖwvž~qî‘‘P޼%å4XéT‡ç׳“Ñ °Có|n®îl}ôÁ÷¿Ó©wÎÞ¾¨Ôjår åL–$,ÇAÊòIß±ãr¥ìx®ä²Ê™vž%ábµÐe±pp3¨ðmQÑ(€¹#IªÔ66…@v÷!£‚Áìb5 Ù~\¯´c?ò;¹´Ç¶|6Ï3T°,#F$Ö$ åÈ Œ‘é¯x†Jý(’xž¥"&¥²J(È’ü‡ð‡qž¸±»½ÕZÌmÓvµ’’/’˜Æ÷ß¹uþú(H¡Q’E‘«e^5dz¸3rHÓeŠIš·6Ú™•2²HG…bÅ¡yÓÒ›qäF¦Ïó¬mÏwwö}{a-ÌZ³Fqœº<–×¶¶—ætoïÑÜÈ"Û«îÏíeO£VÖôÉðR5*ÖlTéwаXy³R¥¥òõèLÒõ^­ @¾=/Õ®µâ8ÙY­ößy¸ZL'³y¹*Œ£iç~µ,'^²±ÝþÛÿøW¿Þ[kQDÍ©ƒU®¦“¥Uª×G×g­n;ñI’Æ4ÍJ'òM°4',8Ÿ>>¨´öÒM)<==Õ)Î2WX‰™…þf«V-©—‹™n•jåfpƒ Ã1‚yN©&ÉsÞl7î?xïÙÓ¯{ëk(/¦ãa©¤ÄY¢UJ4J£0zïƒǃÁ|2)Kz³Ò8¼¼ÜìwgÃÑîÎæzoóË/~…®Úk™ÓÅÙx°ÖßɨÕëîÍ‚U»WMÌéÉ«ñÜܬµã(R”öõø’Ç‚iÇåa’têk’ðÿò_ýÛÄ—ÎõКK3¾˜tô]/ò#³Hܾ³}3yóô›CŽaw¶ns úòígï<Øù‡¿þÍh<øðñ{€¤‡[;ÛqCLjµ[‡oŸ‚<%kRà$Ф´z]’ç«å2£YU«¥y6]̶;kWƒ+€†Ðñ‚^¿9Í@Q4%cÇÖ’$H2]U ó Èsb A¥)…$Í‹‚Š"WQU/HVlí<>棫í­[zIGP<û g1ÏÌ¢¬U¯^žÜÌgg‡Ç¿}õúáýG½ºrrv´{o{{m¯Ûëo¿÷àãGõzmks£­lLç;û·†Ã±¬2š ¢°B!F`Y/‰5YÍH*qBA0f¹ZS¢9¸Z.4‘W$A%Ï÷1ƒ9SBJªf9~JT˵’&+¼ïø3)Ì•×kµ/4‰Ó¼¢7E!xAÂKLEVMkÉq@œ¤QF›:Åà ¤”f(!¤À@º"@ž§„z/(Z[6föŒä….*1IÍ•×.•ý(å1“‘³, ‘çãP¥9pÃ´×¬Ž– ‰ L|?ÂP¹"Š*{QFò ³€$”a°ªY}üݽ¿ÿÀ7cÌaB"Üno ¦ˆÒ8ÎcBŠÈO%…¡9 Âhî,ïnï,-G®¨š¤±°¨u´ñ•5œʆ¾Õ[û_ÿòÿoþù7;]…åloÙ¨ôIìÞ{g6yËá{ßÿŽ¿ôOO.IáolvÏߨšè:έÛ\ßô3J‹f«)‹ÒÛ—›»]ˆÂ”Æ‹3”‡¤Àœ ÇgqWÖ´ÃÏAvB[å¥0H,Ó\.ÇÕJµ Ùž†Qx>¼®HÕ4ÌÃ"-ÂÜÕ™;ÝîuEYsWÖd>k´ÚL©ÐØJ–§Œoí¬ýî×/Gç ]áJUyµr ¾fÎÍÍݽ÷¿ÿá“/Ÿío­oßéD‰“I·Õ ½¢À (`ÈAIà<'›ÎÆÝ^ëÍ‹#‚‹(ô™Q”[Ë9Ȩ( ®Ds»w{+Ï‹’Ѳ}+…´¬hÊæãi£Üؾûøì-‡„ãá.Ô}Û¥0™š#Ç™^LǾ“ŠÎ`Ø*7ƒ4Ê‘9Ì1lJÈz«ãF!*rˆ€Ì°(c¼ a´¹µ6›˜ŠÌF‰k¨òùÍu§ÕŘys|\kÔÍÕŠfþÝ÷ßã¥Ò¿ùùíûX¡ØsÍÐmËB @»K7 ÙúÖ^è8„É,gÕ)—#˜]Çz)J|YV†W×¥fÐ\Õ±e¡'«MŽ_¼øœüðG¯_|fÈ ÄÆ«%äÜò® ¥ËbîÙé¯UZÑ áâøõY©­#’ó¼1[™«él­Ò_…Q&½V !q8¼PKÊ`8|ðàÑr1;º¸VkÕŠVZŒÆšV2½Õåñɽ:}SAÉhºNøïÿò/¿ûýÞÚ¿óÛOÉòu…Ë$gXfQtsy}ÿñ·¯ÏÝ”ê†Q.NR¬–ËJ³‰ –²htyÒîlIq–ÖÉÑqšˆaŠºQ‚`Ð+7V¾„Œ^n®/+Z'MbAá^¸ž9Ž…«"wqu²Õß Ò„e¡9óÄS$íâ|€09¡\‘OÏ$©øQ9ecm2ó»µ¶÷üæêüøåÇ~giMœ¥S.©ªª yº¾µþÙ7O%Œº½ÎçŸþÜ_ǯ"†-ÆÓ Öåél´Ñj÷¶îè‚’Øv#  ðÿÿù‹ÍNý“|ë×wb¯œF•iT·ðg?|xÿƒßþæŸJÕÊýwn¿|ò%"Zyah ¬è­’—O3"Mç‹Ã££šq5ó©·; ½e|ö»¿)K(u®Æ×(ž¿Òšzæ³å‹¹"OŸ=ÃÅÉà™v˜f,%ÍlaMvZ5†g¯g‹¢ˆ9޵¼PäðÂZ©œ\©ðà1,S$ñÒvšÍÚÊ eK9hZË’ÂuºeËO¾úÝÃ÷ÓÄ/WÕ(Iât•$ññ«ó/¾z-‹ªLù©mÆY’! ‚;·ÿáç“æ£ï~|u~>X\”jŽl¹bèºÒëVäJ5‡É?}þe×Ð(`l'ÔuaåF~˜bj‚1˜Nªc'ÄB‰ìd±²´’ šf‰,i¶í¤EJ!¢y‘¥QU¯*`ž¡&)aŽè2ÈÖꕱeë,Â,rãã¢Q– A`çK§¤+9¡¡ŸÅEŠY>O$0$Gi#FQ$sXÑTÒ0 9ކ¡«¨:Â8ôøö'OŽ+5£·ÑÉcÿíÕKËô¯O‡¥R%#ùÙÅUž§Ã$$žíi’J1Ö5}lMãÄו’Â1qœWË%¥ªžž)šFOUËYŠÃ D´Û-/òps¦ps·Ê*ˆav×oC3\õ;›² ZæY­¼Î1¼ ä«ºA°4Ç[{ƒ›Óœ](1Rašvú ašk’|pôºÚê¨K2æúj|{w{îû©›ð;]¯oîÍ­Áb:C4:ío¾zÒ®Õ%A\,WZ©tqq ¾Ô5Â(œ\|û÷ÿðôô´YiÆY\/ÕÃ$^,4 ËíuÏ69I’Êj«Qš^§¢,HšáZKBÓJm=pg¼¨Z汀甒Z>=õÑ»ï ÿù³_É,9FÖY{|ÃÊÚÒ¿÷î;ŸõL•—ùJ}prÄŒ5ʯ_?«×ôÓ“ÍmIaF£Éàìt{Ÿfh2=[:Þb6n×»9!`™œ¶kõÓñ‚$‚P`eË4JA†.bL§Ë;w·c’à ÇIZ©ë¾xVU*Ž5gU®WßO–+g½ÕâEöWŸý¦Ýݬˆ×;Ëñ¼y'no8¼Ù¹µ¬<˜"UE2oœ\ž„qG©À* CGæ°^idi–¦Ð Ó^£É@,KÊñÙùÃ;ïTŠçW7ÇŠVm¶êiîÞ{Di”O~{s2öíyµ³öÅ—¿$)«+F–%sÏž-F T¥â$ɳñ߬WöŽNlîüoß²ÍA4ɾzóâjð4‹É“§¯½ØvÔ±FIœ}óÛ·G×YìÍOƒ¿ýÅÏûòËggÃeÏO^ÝLÓV¯vrq}y~½ÕÝt|'%P &‚£é(#ŒŒqT$q T•§žœžV 5Î3)aÆqÑlÔ¢¶ëB:AÈfÆYÙ¿›Rj®iBEŒâ»æXuvu¼¹õþt~(1º^6.'—­j¥Ü«çç0$q–‰ºQUËQ½:xÙi­y¾MÓL¯´?Ô”òؼVMÒ¡ÑàúöÞ®ë%¡F‘Gxe½ÑV«†ã¾øê—?üÓÝLGájº²µN‡ÐÌMa⯲¤x÷ýGG‡çfR;õæ2@‚ô²ªÊª¿š‹ ¯«š»ZF~!#àëË¡& ãÙ‘¢h5µºò†®åìܺg™ããçoß½ÿ­ÑdøÁÝO|F.C¥^§ÿÕ‹¯ªõr¿·îÙsFDšu;­™ëD¶;ž\ÜÛ¦èòêHº$*Ð0Šx^>¿xݬv_¼<4êjU/O—¦À†eiQ ÌÖeýzr½Þj:AF@êzÞý­Ï_>ßn¼‚ýÝÝ„µ{[{~èøIÎA©Âɹ[/×0bDVä ¤ªB Ø®TÝØf O) „dPJ ML(²ÜK"—‹"¡ŒŠb5·1“œ¼½º¼5+Ж¯ÎÎ%Qy{x“¾³rïß¾Ó¿³½±YºÝÛ‹lò£ývU.V¹V”yÊ-’%QµQ9?> CnèNè— ÝqV,‡ã„° R$™Á8 #„ÀZ³q=ŸÅqA.J Ù$ ´@¤y—Ç$¥˜ä$g0.Øš¡œM†’ ÃòŒ EAäÙ,Î Ó4—E `èØÄP”ä8És’‚$ E‘eDà9J1‰i”¹ §PBžÍ GI«ªeÍHšy¿¾‘'À4³æ´àÂ(A ÇVñÒ÷ ø~.‰ÀLžå‰ýˆpX 3ý„A¨€Ë(5MŸ»¼ À0€iXèš‚2ÐB,„Ý{¼sëv¥Ö „dy„·ÖzQ’3˜aÔe= a%„AŒiÛ·vö3¦Yæ®ÒjCã„…, ËåäÞöþ“¥ª ±Âw>þîÏõOÚ:#d˜ãÎO.§‹ÑÖæÞÊôãÈœ.¬w<›ˆ‹áõpëön…±çS„Ú­,Øg/žv[‚h¬R IDAT)<·˜/&œ$ÞÌ–ï{nŽç§ß ‡ǚ΢U0^F$Í—ö"KóÐÉ&Τm´“07+Mc–UæóYœÆyžØY´ÕÞUUia.%V~tÿðæ\dùˆdâdY5£ä‘¡¨¼"ÆŽ#K<#*õ’ä…9Ï2º.ÆyI£kÊÌç3Yå“,-é¥ñÔä0J²àþ½Ç~E¶Wª–ïDnZÐÔufˆ¢ûÛÏžÿ’g¹Ííñð"‹Ò”%²ÈÚ#Ó³üÁdÜÚÜö|7„•“Y¬æ!Í}/4;ý­—/>å”= æsˬUêKs¬U@ß[~ôøñðæÆ —4ñû¿yþ Šlé!@½1Ÿ/ ËÜÞ[_ïí‡É|sû¶,(E–ëe– †$Ÿ+2ßZßýâ·Ÿê-“‚@?óKJŵÌf£aT+Wgçí~³¢ªf.¦ƒÇ÷Þ:¾¬jŠ£v{}s5L&›ÍÝ;·Î^>¯Ö«gÇÇ;›ûóéÀœ8­Zc{ãÎÊthw[AŽg“Šf8žåç´¤iÎÊ¿YNòÓ?úúëWÐn»µ^ïž_p‚ ñgÀû÷ßž ÓÔo·z ½6™ÜTËJ­ÜYš‹^¯>:>¹½¿syy…Ò"Œƒ[{{7o¯¥Š¢‰2"†Ï.Ï}Ï—4-Š££×?þ£ŸŽGÇËLå‚xòõ×û›[Õ¶6¯&³ÑÖö¥¢5½‘Ëòá³7>þÁ2¼)üØ ì¾õÁõÙ9!9(e©¬/“íþæÊwõzit}Últ²¬Uf8ñà×:^šós†¾óá×_ürsçA/.ãÅsVÌv×n$þÙ§ÿe£µ5µM˜eq”g°¨hŠ®¨a³ ·µµ$îʵXŽZVO××ö÷ñ³_t;Æd6ñ]—`<O`fqDÅZ·÷ìí›w<ä)+•´ÞÇï~ì/“Woe^¤o4«ÖÅÊ´RðÛÛ{+sU×ZëÛ=qE!RÀœ&ó+siTtš­(N0Â9ňCm¥Æ ²ãÚ K5V»_q,â8Àhi»òaóÃca4ÍNú H=?ÕIŒÄ Þ*˜ZóþÖÙÍ%yJ—ÅIèWíÚ\jK H •pAIDaQ OòäøU¿ZˆçÞ½w/ðÓ³½nå”7ošõºãx)äyͦnæ>|„áld%5 “4Í¢ÀÔåU©ß¿ÿúå—Û{û•RU` ¤°ÕjQX.š¢ž¾ÚnïXKûôæ²\©ô·öþþgëö­Œ¤%­¤(¼ï$Ïïß»?N¾þòËßûÁÇGc 7_uký‰i"•»:>õS»U_¿xû*Ïãf«_Ò¤ó˳vµ6Oõz/#ôððí½;Êe5Œ2ÇwÖw›Q ÛÍF”OÊŠ®òÆdy1Ž1fF7£™Â±$ó*åVä†ÒDÙu–c9ÀRf à P"„TU= Äf³åÂvbQÄ<Æaõ7{³Ù0Í’•kBõÆl6u,+ͰƋ¯ÎÍiXªðöʳ­¡X¾½´8xõRxÏq)$ãÙ|nš^…é:¢ cˆÆË‘,*+z¡_dP$ÀBŽ"Di–²À ð‚˜ahš‘4#€æIK‚ Ћ¢‚䢂 0 u}º°¦,ÇZ¶KY†¡ˆÂP6ŽSˆQšä²Èc† ¢œç8M–$,ÄyÆó’íE Èy^ð"–$! #׺•Ê8F¥q´ÚYÛ”Š†qhow“¤¹¢²·;»<ößmÕÕ®¤0j™þô÷þ¹^ïí7om¼W¯êbÝ¿·½Ùè–»k”:íoG@àÓþûâÝ÷ؾegÓ¡¹ŒÐµ«½yùüìñÃû,€â81ñíýŒq^`7 8ª’举&ñº¦¾ç8V·ÓŠ#¿ßí<=x»Ýß4Jªµœ¿>¿ÒxÅ í¹mßÞ¹³\Œ?|dš6¡ÑÕåñÿäÏNÞ~#KB¹T%4YŒf¤ Z¹J S«6ñ«ÿúᇟ,gc?Ìo.Ëå2ÀšÚî‚c´ªa¾VCqÜürRm•ÊXL=8>ê[½õîd:8~yª êõ|Î!AC(.²ª^³W‹0‰›zWRµëáÑí;·Fãk²Žå¥J¡X Jž¼yS×kûûwMk¾¹~ëðäÍ|2=:¹Š³È fÿò_üw¿úÕg/Ž&#iñà»·´Ÿ<0„ùŸÿ—?—H‡c”¾sGÇ DÞZ'°ø8Ÿ%1 pÿÎXd°qв²ÞÝr‚9,€¨[*»Þ²¤–ð¼8Ùöf×Oi’¤"‹1[ý=EÁË0ð¬UYW7*¢(N³ ’"¦I£L–a³‰ªèq””0€Éƒœ—eŽgý…fY«QK¢1¬ç†uU‡­6:öd¶Ño ÕÚñËç¼$ÕJ]MTB’vÚÛ¯_~³ýÎ]ƒ3^~óbïÎíJ­~su$(J¯ÞÏ+å2¦9MhQÄÂå*¬KåF³õâõ € €¬UÃЄ„`Ìí쮼yQ“Íí®=™vêýW—ß„9Rjâ|tÕ_ßæ%ηV»§—5ˆš3inõ¾zI8Z¯v F“a·Ñ(†ÌÇó·GÏw6Úó1AIš2õrçÍéi¹ÜõÝ€—±Ì˳ɨHww·±Pž¾­UŒ(¦¥r% @xQU*Õ¦m† qÿÅŸÿëË£ã,O”V¹¤i˜À:ËY¯ß×¥ÒÙ鱪TŠŒÊ¢øÛ§ÏU]ÆyѨV¦ÉŒ&‹Ÿz¡¯Ššahck&cîäꪽÖ6d9Í#Œ¥wï= ‚pé-?ü–,škãëaœ&^7ðâálP1*W8ioìø ³{{Óš™I^MnÝ{/óÝÙòc&òãÓÙ™ë›ÕÒ¶öï=øòé7Œ7Û5ÖŽ®N“„é¯m'0/r®ÜV£„±$,ƒóØ«˜ÉhºÂÓIP6¤,¡a–ɒ̲üùéI§Þa(BºrQäôf»¬IU «òѽ»·Òy‘ÿý÷߈—d¡È£²®ÞÝ]ŒG¢Ä ¬°»Ów\¿ 4È¬Š®qH- ê«ã·Q¸V8]™c{!Pnj™ª :SÿéË£ ‰î¬­¿:>è<Ôþ§÷?rF,ŠÁp¸ˆƒœeYD †¥¢Rüˆa!%HæXI0é%¶ðQš%Œ€½$ª¯ñ¡xVH’‚aé›Óë†Ñêí¶C7R•²Ú”ì‘Ùï7Ü\\~øà½ƒãfíjKÒÕÄr.“€ÉdÎ vú•k|õÇŸü5ô½­mIPoæKI­nÓr\Q–c–Ëó äi¯¬ „󔊧U×Α©0*Ì¡Q—RY…Uäó€O`ÅnM.CyA-Éd!ë&¹^Ry–iQ/«Š.Àr§òº"ë{{›u¡Þé¬íÝÝiÕê–éìßÞÚìö¨Ä~ëû9˜«¬ÖêõšÛ¼ë:wöoI”Eq¹ZãDZ-7ã‰RfÒ$‹R0¿4ÝxåL‡³‹…K£ë‘9‚óÉUzËœ]c—Lþ³7Oß¾>ýíÏ^¼9>µÝlp¼|ýÍù}ò“í;)!CfSïloT@ÀÉ€‹³|åxuØ”…ú*°T•ÃHT$eaŽ{½¶ÂªWoËjÓË™çM7íJ-?ZüøŸýÙ/þñ¿2è”·òŒ=xù² ²z;²R{ùâùÃïÙ®•çéÕàü“ï}ïäÍQ˜'‚fxS³Ùh fîÏKzÃÐj¿úͯ޽÷¡ãºaè÷Ú8ö9–“ ¹,(ÿé¿üÃ'«úd~iÚ7K7ð‚„çØ$NXHR5Ï‚¬€¢ aÈraL¬ x4^ˆ®7k¿þÕ—3Ó ü”Cœ¡‹ s1OHQŽTIQår¿¶3·‡7s£ÕšYNàÅoÞŒ.Þÿx³[ÿÏ?ÿ€’¯w›/ž7º-]©öûÛÕžVâZÓëÿôË%à f­V‹)0ŪÊ3ñÓ¸V×Þ^”ûQáçcGDEá$‘AÏ/®Z­º K¯OŽ•_äᢠEáxQå9 2Rp%MUJœc<‹eYÎbBAÁ±,HT’¶U–$£¬_ʲèD‘¦UTQ^ßo3 â0ëGþàôx·{'¡¤\/–—²0 ]ò ñÂåtcç‹ócš' ,e™ayáæì¼^¯ÅqñâÕ³J£ÇII”rŽgË$ñ{½­Á`¨ò¬Ñê¦nXä„3dwáÿí?ü]££L§žQR ¹öìàÀü‡öÒŒiñÁGß‚”¨µŠk/¢3ª&v’åY½×(Ò4°cFåʲù®iÛ'GÇ·vŸµšeDÓu9 „׺ÍrMg¹ò¯öÿ~ðñVæ2'þ™ôëu,1¶íÇNȲd÷ÖýƒÃß³yBßyüèõÑóV·QZ$Fýúf ‹JIWs·xñêùã?&YNS®çz)›A¹8Š6ÛM7

~ø…iÑÁ`´L–áÑõøÙ«—nýg¿úx0ŽlË>::_Äé`¥ió&ön]MðÛ÷ï½÷á‡k;«·om}ë½ß»·ýz½ÕÚÙÛÔ ß4ÒÞŒ¯l¸®‘¥9A8ãBlix‡k €_×¶7÷v¶6uZ¶›},P)¢ý½=®˜eû»[»;[Yl®u›¾ïyÞÝÛ;çM¿æx¾AuªÝ‹B×¥ Û6[íº”¬LÃB[6›Î‹ŸÇe¢:žÃ2äEöå£OãlDÅ/?û]ÎÓüäì*Ÿ/—Çgƒ8œ~ùê2$sþÅÑétáR²Ê‰FÕ´édé™^œ±çYÝZ7M•_³Ö6o5ý­[+õ|óG»;Û›·¶oÝÞïÝovVê+þ Õ¼Ep¶Ö݃_ï÷]O¹n³ŠEPÆuË,†‡{»aÅ îY fâõl×`¸÷ì쬳±Ò÷š6ÕLïïß †AR-Ö6v¯^]¸íš”•,åÅr溔 (=¿|VÓÚ®oÛTØ~òüñáÝ­—§£ÍþúõðÚ@õæàê*ÎÂÖn·cw§§YsM»^4¬•i6$T¶µvIèxqâŠ:¦mšß;??ÛX©kÈ\„eÎnZÕy)=BÈ&•my±¼a‚ª;·ö>=±-M7h¼( _“œ;Ô%.U‚?~zúæ;÷.O‡ƒé¸ÝðLé¤,¤º…\VÙ½Íí8ZÎ’Ø7mKk ƒA»QŸ m³2Ýè­š_îîÝþî׿³¿z»µ×}5„Ãçé²úéùçyù´®ûàèätce%MKÆRHˆÌ ¥­º7¼ VÖ{žÛÐ~÷o¾þàm×ïÏ’Ë—Çן}ò–øñW –¬mun^†vv“!»œ ï¼µsý|ˆ±¾ÙiFÃyšy V4RÕ¾ý!YÔwÞi¿ùàÍÉ(‡¦ê¯­ Gñ¬»îÈBPS0É‚‚jšÛ®ÿúçŸ]Lç7Áå³G†—G,E×5¹’ –¶ã6]g3DåÖN'ŸW¬ªŠ2'ºÓð'WO§†u‰¹&Ð(Èu 4º†Í“Å骵*q:‹sV:¶#£2—!WDb‚Û¨V˜à…+kGÁhµnë»Îg·¶»Ã³LÀ¢Ós“E2Y”½M×´´yhÞ{csxv¾ÒØR¾F9D…èn‰ñüìlpç­Ãó³—Ö뽘Oº~ëöáÝ“ÓGwîműJÓw-©3—»–C°yIWš|žå’x´V” ¯‰3ÆqÝóçÃsøãÿîÇy’Rˆªdœõ»Žt¬ëYŸ ïlº¾˜þêâ¬Ñoà9×kÖÅÕ ãù»o¾ÌB ‰_¯}û;ßý‡¿ÿûýýõ ™×[½0Ž0€.Ñz›ýÓã3™ÉÎf×4Ìj)Žgolï½xi×X•šY¬ÊùŒW ²ýù<¹ä„½÷µ?øå¯þѰôµÎÝ—ç/ -h&e±LG˜›¯^»ÍËaQ„®cA` ˆÐïýß‹’áÅÍÍÕÕAtYÉ«p~{u}f@ç¦N¤ 5_Ã6!£É÷ùø·wæóyž—†ípÁëµÆfg%¹‘Ó{¼w}ýª®9NmumË2¬´ZŠ„*ªqx18˧©aëÞúêåé«ôý;ýì&À†á4 UðøËóµ;­i B4)8‡ãÓñ›÷ïÖ{>¡fºP dÉ8ƘhJÓùhnù:¯Ê²,$TUÆ t9GóÑä×ÏM‘{ôøã¯Ž—-×̤ҩ°œzžòš“(àÌÅ„•2/JbQĤ´-Ÿ©t6c5ËJ³Œ8¤®Ùiaû†#P…‘aÚZ8«šµZk­s3;‚‰ùá;¿ÿ/ÿ[ßë{­›ÑÕöamÝ?zöqo÷½÷ßÚyr>Üîx¾c!êdÑUËÐæ^Kzu9Ùz½ŽS«,­1™aT:mçdüä²w×U¡¹Œ&TÇN½•‹Z¿Å’ªY…¨°BY”¹MCÃfÉ*s ÙqÆãcÏi#‚«|Ž ¯Èüö·¿m9f‘p‰¹ä:WÕjÏ¥@c^ v_»¼¹ñZf¸,M¨9}'½^Nó¸]7vÖ·þé¿zãÞÓ²;­UR‘4ÍïÝ9øôá—Ë(þÞ÷¿WDÑ‹£cù»ïýÁgŸþfe«7žÒö¬2Y&…IŒÕn%Ôå³gë¯?˜ ®:Fýdx ¡°¡ÙY[—X³a{uýñÃGÝÕíñè„êh|1‹`ºˆwê]`haV²ª7|©D˜Äjš¡ímì_a(ËRq&¥¦VÚMQ*ˆ)PÕÑÅùÝ׳ù|8nìnY ¨ZD‹àfÈ‘ØÛßøè¸VóœviÌëƒlyoç`0]bh.rŒúÉÅMÝòÁ„êì_î IDAT_ÿ›/¢2]Ç ¸4j8™Ï*ÓΧãÉhæ·jÃð”õ›Åõb–¸È†‹*fc(ˆ¢Â Ä®û¦TAÛ–[dµ ª ÀÒ÷IœæI^a€®Ú­N°Ìl ËR.‚ Ò5T’J\rM!ݱ*„<,S& R‡{‡ó`¶ûàp¥¾zvôtûö-•%Óá¹NÝé¼xùä»?üýx°xy|Þ]é œ/òÈ4L‚dIÌÕžW&‰šåÚÕÒYº,ǦÞJ¦ËÆj+KcèFÓ2°vq|nuÜàfjénG÷Ÿ·¹Ùêo4§1m·ŒJ–žß#úðƒoÚ¦°ÄÐ" )K¥Ëˆ`d6ãeÌšõÎñ‹WOΟ­w×'óéúâ³ËÉõëwß-bN<=ÉnŠLãE¾{ïöÓOŸö÷|¯Ñÿâ¿}tyy¶{ï^ [©–k†ùê«g|ç&ˉZJl#«ñ|!¤ÚîÔÂAL1‰õÍëÉIþâñ«8Ê=ÏÂ@b6:=†ºÉ”‚¸(8ÚÝÚ[ÌÎt½ÅªêîöfUi—“AÃÕÖÖ÷ Ë(®Î¼õÁ,ZäJºN×vx(ˆ±R™avÏ_=r^Y"Û†Ô•Õr.ì5cvž]žìÝÙnÐæh~=šŒö;·Oƒ³VÇ;—7ëÛÝ$Œ§“…n‘ý­ý_ÿî Ša«æ„1÷,{Ž5Ckù>Õéå azW[€Ë°XØÔ'D›‡±§{-¿þüü*¹Ún•<ŸÝ¼~kçlÜÞ]òùbŠïÞÝñ\0¹Éë5¿»Û+–Àk™Ë›Ë­Ã{†_…[L§6"Æ`hYä5ë*-2ðõ·ßñÛR‹ó¡Ù«ùÒf"÷º–be%F†p>[Ý>™ùòÜ-¥’´Œ³3 Átج·‰VfEÒnm*!¡‚„ò$ML«ƒh5¸8šÅªJMÓ-ƒh„i^wex6¹ÕͧÇñ“Ÿ‡ç·ïÜžÅÉÍé©@¤ÙhΆ7~­-ZFÁýƒ·Í‚PPõïÝ~õè“•µ× ‰Zš©ºí&¬(¶¶„JÏŽOn½•\Ï·ÖûÀCmAÀ˜«`AH%škõ*IšQ³l5[á2p½¶@P7Í`>Ð ÇÒ\.XÊŒê,1  êE0gR"Ï­å,çKVp˜G£BsˆåSªüYtcÙš­7“4¶<¤J¤Ö4B¡ÉòÒvt©`ºŒ4Ï`B(AáÿðOÒ*1¡Å˜çááÎv4 ’I™šÅ!¬›f „ç ãËÇŸní®§q‹ür<îyÅíÃ}Âu³¦÷zk£‡uŸìÜ?yübe}e6 }ÃPШsysµ¾¿LÃ2YÜ>|-™ÅÈ"GÏž´ì~L`»UŸ\TJï¯{´£ñYEÛo_ÝlînN]9‚ÏOÏJ†<ÏÔ(M˜’¹u©;†D`Ô\KÓ5œ'U”GQ–+t[ö:5ÁIÅ+"p†¤ƒ\G&ÀõŽ=™Íu )¡GÆoJ‚<Ût¬¡zG?üá_¾ÿÖëš0jÛÖÅÅ0ÏÁÑgüÅ#¢Uøûß«28‡k[ã‹›L…†›ÎØãgßûÖ/¾œÎ¦Róåx}½b/˜ ŒºYw'§7Žå*j2H’léNY•¦ ³ è¯u*P•£l\e¦MLà " VÁ–ãò"C çŒgUJ ™©†I¿Õ,X)x¦”h4µz­p義’f«÷ìøl­å6ݵã³ë„ûwò,‹³…ãuÓ X;XOò0èï¬ÕjëÁäÆr"©˜bk««ÏŸ"m˃’,—£ÞÚ&ËKˆDÃ׃¨*À\„aôêüb£·÷ÕㇺÛµºFí$‹• ³Ùðê÷¿yKdwo¿Ê˜aZQ˜ºF4“1‚X`B¯¯Î>þ"Éøz»wyqáõVx2Û;¼}r¦³×î¼=™“›ón§gŒWyweõÉçŸ9ub{4JK˜ì¼Á‹äññ³®·’f•ašùlk˜•|weó&]&Eü­ïÝLçËÉHB¾Ö?€,•–~~tuïþnR&³›YVä¸nM_Ž–ñ\÷èééåû‡_ÿäÉC&s^‰V×¾¹ž¹:唨JÜ:¸{~vÒ«kíÖöÊf÷øæúÖÆŽãÅ´`×;¨W«…ƒBx‰,y‘ÓxaC±SÎõi8a¬ë+ç³q^mwo¿<9¥5åp ï4ÏÎoÚ½Öv»ûÛ/|Ë®ºi¹×“”8/*“JL%€îÜ8 )Ps¦Ñ|¿ÕËc \‰eÌS=âÛo¿^™z4 Þ~ãÝÁrÄ”ØZ¿•'ƒõ­ƒ;[«/^œ+€^k?»RÐD+yäd(t4Ê%=Ã2U”ŒCË®ÑM¶ Îή®×·÷'×'·o¿¥»¼,BŠe•c [†O4Χ~£ ˆâqX\÷LÁ$Æ:¢B”À’¥¥nû•ÓÉ`mm+Ë„%¯!šfh\pÎa‘N¯8f’ %uET*©$¢˜RU !¢:’Æ`t^¯ùºáGÉ¥Fj†n1‘å¬À:¤È®¢xrÿµ·!„EbEÄPÓAñòì… —°è”¿uk³ÛØÉ‹’%•a€$"O¿<®ö¼D[,ÂÆ†Q–<•°íb$ɃUM &óžÑC¶Ð…5/–Ø h 2µºZ0àíÕšá‘Â\e®å,&¦ºëáxɈEÊ4%p|Ë6Íñ8tj¦F‰dPÁ%‡j¥Ê¬Àº¦kTr(„ÉŠC“œ—Qiø.%B $€Ð” RbJ³eHHË‹D×´<Í!!T×0Ð’ta»†L.ÖI ¥c9‚D@ ¬ÒþÙŸþEU•¦†ŠR1‰4‚ã(kÔ,H¸Z\±N]SRPl ç³^sµ”¥”ål²ÐmÛ&ŽÕul„?øþ¿zñì‹JaQà•Õ•ç7w;+…ª®ëLN’i§Óµto:<;~öÃïÿá‹ÇÏ"–OŠ\ù¶Ë)^z†_ëÿú£Ÿ¼öú½ñ,s‚:B³<íïôe„þß¿ûëN¯ž3Gƒâý{ï\†Ø€¬d®ãh_kŽÑÚX‰‹Ëélc³;M4È#–8¦Q1è9µ¬ÌQ6 †éaœ›„ŒG!ãE’½ÎFžL ¢ÒP.W¬õÛo}ãO¾ijª½º2Ÿ^¸N]UÏÁßüýbBp™±¸†ÝR ‰¤ ñ J×2 ŒK®¤ç¡Ñ‚­®õe"‚r"Te¢†¡£(mÃ6 8™¤&q[]ygïp}óA]ó<¬uÞŠã G#¹¨IÔ\_pš–3¥x¯µ3XœäY±Ó¿ò€gªfÕy…p­Úl6Ú9ØŒÓr,<ÛÔ€†-d*(²¬Ñ¨Ÿ\/Ò¸ÕtV;ÿüÓŸ|ýïF¶ˆ¦N]ûè£ÏïÜÚØ^ 'a^Ìßÿ£ï× Ã¶jº T,«-´ŒÈi™gG/OŽKaéÍ‚ÙjÍb†›‡•Ä‘ŽeÖùPƒ¾Ì’­»ë£ó©fºqùt¯·ëÔQŒ¯‡ž×C:¯5§Ï‡ŠW+û>*jy9o5ÛX¹…˜iNûá'Ÿììu\§9¼—ìîí?}ü,ˆg+ÝÞ"žF'_<<â:ûæ¯?:>ÙÙ½=\>{~ÁõÜÀ ‡rg¥}t:º³¿S•)¯´·ß?l´Ó«iÊfª”£yÒܶFg®¥˜ÛË ´k$–D2ѧjHíº9/—žjT BDÄAé¸ ˆϪÕ͵é`TÈâÖÁÞt:›Œg«kƒ¡‹¬þúf4ÊÝò¨Ì"¿ïn¼s¿ðôÖY·×Áµ•† Ëë #°²±óëŸ|9-޾ñÁÖ S[a§G¡Ý2#XyvKVE °!£š¢È¬TÌæž[P%Iª„2mË­ûa˜XYeY„¥¶ÌURÎÐ]Ǧ–(’BÓô´ }{­TBñÄÒuBMÁ‚5‰Íl9±M«(8 ¥f˜™Y21Ì:â@bQU¤,bË·0eA¢4êÀ+™+nKBűrK^ ¹ÄY.ç¦C•‚JÅJ‰¢*•kƒ«KÃiØ-‰…–&±ß4ÂeUà¬×µÇÇbP]᪴ŒµAouÛãÑ'†¦ë§O¿üäÉGH«{wwÞ|ÿ}SÙ„R(±×ò4JžbˆL£I+ † ƒKI%Âåi†°l´ÚÃÁÜruDµ$ˆ%ä*@\…sÇs€Ò¤È4]ƒ0)0„ 1ô³™nCƒ¸¼PÄR*Î¥ R€K.‘Ì]¿•$buÀR¥0‚PÊR𦠔âB"‚ç@ ¢é‚• Á$ª8±PT)(xA1áå,"bÝêDFCÀ IN‘©P2UÈ;>¶mZFÒ«9q‘jØ ƒy»î¿œŸìïÞ‡¹€ |syܱ:%FµFÇ*ðéàÕÎÁ>Õôá|ô»Ï±êo=~ñÒô(ÊÅ8WùN§—2+‹F³=¾¶°Öò¼ºß9½ºØ\_iöºÓÉô‹/{Ž­ieš@Œ ÏWQjbø ÊØf{m™/Ë…‹ÙÔ òl­ÛZÌ"ˆ”ü/þôÇ_{çMÓU–CÍA8S…Ž ,æ¿ýø—¿=ùͽ½ûbQúÝUV&Ñ(@X·}1Š#]*¿éi†çßûãï?}|<9?%uqñ$ðš¸f·¿|ü8ªâoÜ}ðÑW_  v×WO§×º4[Žž–"ª’ý͵›ÁiÀÐ)–z’†µÚJ£ÓyytB!ä¨DB"w›ž,Àl¶Ø»µ;MÖÚëíRĺòW÷z“ÑM‰Ý×n ®/Û -Xšy´ovÜl99pšîÍàÔ7ÚÔÄÈÕX"!e:Åu{•e\ 4^Öê~VXã®ïO‡óÁÕéë_{÷äì2Ë&[Ûå2Ù{ãµ*ÍGÓ³Ç~ðí§ÏOS–ìô· a2¾s÷–4׳ÛíÞl0‚±JáMEV,¤* ­î¹öMpÁKC”ÅöþÚðj Ll[´_߉ÒI´¤ÓêÕF×Ãe:[Û¾=>=kö·.¯Ÿµì¦]¯cN®¯I½nSzþêËz{SQ`"ýæbà4µ4Œu£½ˆGárp÷ÖŠ€ 7a³SÂðõ¯½÷›Ÿý­Vuм¸¿ñÍý?ÿó?=yzó«ÿúH¯ýô7ÿi¥·:ÏÂtŠuÚ0½œgÓyòõ÷^Ï’Y¢²<.qy,‡¾8¾´°UÛô¯OGžnb¤Á¢ dŠ1©Î Zì¬n&“ ÔôN /®ôÄêêV£qûèèwoîÈ™ÿ2œÄâ3˜£ãš®õµu¦[_{oS•²ÚJ§¾¶²·\Äõ5?ZL’ĵG7§:¦Š#‚p0ŸÆaÙ¨o¾uP±Ø°©c×KƲ²0©NªXa[^–$ØÒ5 Ãy¤[Ä®×&Ë ƒ¼U«Î‡n£Î!+âÒ° ÕÌt¹´\C×í,M(E™œ—ä"Á25*TQ¢kT‡‚I%*„ @&Rc9¥LÈŠ1L0F)Î!&’Kˆ1—€AY¥i† c$…€ˆC…‚E¤ûFTP©Sƒç‰¢ âDR31&Z™æÄ”Zóù壳úþZoÏä5ÉôE2vÚG¿ûôg¿z´ww eàåÑ«ªÀÀÍ£xs¿=›&i$¿ÿï}ñ/'ãŬÞ7Ú†»`éFmkwß³toUÛhxŽíXQ:DÊnÔ«¤‚b¢”D·™ÈYYR¥A"xÅ% 0Ú<- !¡‚àL”&2)&q@ÅÜ6 ¢óѸ֨+³41M SC”9"¨*•d‰Ûh…”U¤[.¯µ+(tÎ $”¨,…fPë@©JUŽfUJEI0’RÓàe^URLeQ1àz€J("D ä$%&Ù|éÔj Á<Í1%JŒ ©P׌ŠåðGö§@ažK€9ˆ7<çj8î÷Ú¦F“©ixÛ«A 'ÝÖÆ|17Mt=jÀh¯zwvïüâáË{Û[·ööO®Ï5™±Œµ:-® èèf²so'Ž&i Œº¾ÚÛX\ÏfÙÔÖMÎ@é¿xñ°·¶âmVA:Ó]ÛÆ1ìÙrÞðu·µwüì3ÓÄšfŸ/£Œs^)¬+Ôr¼iBž¶YU¼, Ûvâ¬h5ýíýÉäšÐ7ê_|ñd}k#Ë4Iüº3Y,M\ɘ뚪ûNÅÅd9ïxÝBp¥¤Ê¢í5- fKÝtÿçÿýÏ·û¯ñœ›®€–Å©íyEž×Z­_ÿâgÿçÿõÿìîoÜÚÙ†À®¹uƒÓô¤F>ýíß­oÜÒ‰my"«•N­åÂrqq)AÅ‹$a*LÅ$!êñé‹&m ¬ •cˆ6-(mÓ-ƒ¼ ­=J¦ª’Ô -å©äÄ3ÍJUª‰(ë†-E)4B…š–ùîJ§©;ÜÀÞzM– äкÓcyQkxYBª|¿6‡Ô¶-¢|Ú¹ ®£cAuÃP°ç<ökán”F†­¢e… 1œ<ê·_Óíú`ô<Ùöîβ ŒÊLØòæúü;ïþÉŒ/N_5^kÕüųÍ׌³eÔêo'ѬըwzÝõÍ•óW¯V×÷$VQ‡Y6Ÿ\ù–_a#KÀóf{e>ž)$Ñ hÌÂ)†f·=›§7ÃÕõÍ$_¶êµ££+»FÚÍæñõ£ÝíÇì^œS“ÖL'§Ëå$ј±È&÷î.‚üÉËOïlíS€N/¯£ ù†žVÓnkýââ ðRÓ­8ÉFáp§µõáû\òbecöÊf«³X„ñ4ã2çýë¿ùç{Ò•ÝEZ‘M9§x­©ûNíf>mùºHüy&4¯lÒ&„DÕ8LMǯ­nôF/ÎdËíÕk]«s±8^ëu¶ú¯çbQ¯Õ.NGë·º·v.O±Œ›5KSœ-$cÑ\€ ·UUõ¼fÝ«ŸÝ˜=îûMaNR „, Éù,ÊšÍ6KCÝ –éAH5J-Ï‘¼@DQMBBó¬0,KQ¶‘F Xb‰J M¡P¥CšW™my¥/]Ï-r&İD€() Õd%‰¦±ªJZ!lY‰ išõ*ÍQ@ÊŠD‘‰‰bèÈ"‹3 C÷Ð* &…äÆf”F0/*J Æ„W•Â*^L(©IäybÛðÁ U0DI% Jë¢I„èl<{òÂäųg:E÷|{,`¦á¤9»8yñ`<BT\Ns"‹Ò‚ ¦ïɬÈ!EUpVpfêP)4GíUc­³Ro×vöÖì6íj½V·ßØÌ8¯{µx¶¤Ô šVŒóÊ÷<ÀUR¦T§Y–ajJç\q‚+…ÄT'H€¨%«9Ö|ÁÕ¹’BqݰdYU@QHH ‰€Š`HJYè˜bbT¢eAt AŠ`@¦iL)щ!‡B@äP#eÆ(ˆjy^(™KhdhšÃ+®9\J´˜­Ž'+w¾¸=¦0N*§ƒ ÞLKNôHCKjI’u^]¼‚ÿã¿ý·É<@EYÙ´ ¨Ùó00Méûéx!DÞ[iQUkù¯.¯š#°p­ú“W§›õºÝ9»:Eþà›¿GSÃÔŸ??û£üÙo~f«ªÑju;«Ÿ~ñÛÍ»Û61æ“ÙÚîæéñ‹–Ý)A"›LÓ½­¦¨P)íE2i6¼ª0Ò|ê9F’‰{÷n¿8úÂ$^RÄót‘LS2¯ )h•¦9϶VÖ¡’Ë<Ó€nkÒ4Ýé4ˆÄr{{Wø|z±»º3›EJƒk~Ã[ùÕ§?oÕ¬ªHc¡Þ¾õºEß~õ…çƒiXzM3N ÄP@jÒ2,ŒñÍM\ÄÁø¿ÿ½ -ˆT‹"ãÛ¶–‹ðg¿üÉg_>©òâí7Þê÷;®ÛÓ(f2ûâáÓvËÛYß`¥¦ÛÀv]ž’éòBIa!ÏôýÏ>ýÍîîöñà<ž-¢Ï/{† ©»H†:Ç­µµh1™Íb`³î$Ë¢"(Ë—Dѵ^cºXJ µ[f”dãIbXD#¸ÛXËaN˜¬[þélT–åfÓÿáþh6-“ŠÀŠ3Þël3>;®õ·Ý:ùÍo>Û¿ýšëBÀ ^ ¬K&4ÛÔ žá6º4‹‰´³|âu›eÀFÁgÊ5¬ZÝs«Š±¨æufË)4KøæöíR E©mnÝ £ _oP˜ϯZ^¿ÄúùÙ{;÷2UååÜÓ}×u ›d!RRÅ ;kÓ³Hs 7l Fçeih° 6±ž“‹Ý×v®?‹3|±³ÿ5Oún~W³kÃW“R²†o?LÔ|k«Ö´¶þ˧?ßîá&>´·œÁñéô*1êXz^䃋Ù[^>åP]1AÂ(µmæx½ÙÐI&2O¥eûw6ßüÞÞ[Ùì²R@ª,ÅHÓmS±* RÓ=¿öüéç&ñŽŽ'¡šëòydí¦ælûÎÝ•n‡Wr÷n=d Y^™zc<‹›­ªf¯Ï‡©FS€tňîÈb<[¿µ]Ä,\ ,ß„œ2u=-I¦v«žÌ"â[ŽA 'A¾4‘\gXL¯#ìXu—ÆË,/‹v¿L7•ïé‚AˆIÉ2È!6°+˜i:ˆR0ÄR¥ö<]VÔü¶ B”ê ò"— ÀØTTG¸Àœ*€«" P]Dã (@–§CË0¥ÂšŽˆFXÁ!€B*c2»ÝdiÎÒ5Ý4áÄPT£<¯¸ª£Q¤±D%!:Dœ‰)CHf—¥Ðu…)&دù\¥8B–X‘HÓ‘|t9öò+–„¬$óåyçðÛw+6 çÑ'OŸ–1Ó-}4¹*Y>_”e¢s&9K{½msDrØ$Œ-ÍÊâ¢éÖV—'üÕMzçg¢îÝ7½(¸R¶Ûùú‡wWŒý«é°Óò dGaéÖ Á|8ñ[ Q‘f~Ó`\– Ó- Qƒç©në’A K¤™¬ 1Œ$!¦P¥ŠU ëTT9ÕL%”*Ï3Ó©;¶Æ™ª ¡äRbBt·L cC÷³x©‚%Uˆ‚qTáDwýI8´ áV”$e9¥e#¢AN;OOv{ÇOR`”šß4}¾Öj=y¦Yõt«cüíÿ÷i&£–kèí½»k¯¿}ÿò¯þ×p6ÃP(ŠÇ¥H[µf^f…PùR¬tÝ”-ta-Š´Þô´_SDðZ{%)gy–µí¶Òå[o¿ñìÑK)Jªi;›w_;-·Wë-æSAn *icoMß}çpx2úüè©k™k­õ ̩݉—ñÚnÿêüÂÔ=»A%Ä‹«E¿ç"€^^h/KÓ_©™p0˜ÌÙý·çƒ ãR Ò3-J¬¬*³8•@$XÉmÛj[~­±òøüÉ{^Ä~üô«ÑÍ¥eZ~«.K^³ëÇ7Wš(4{½V0_4ší¸ÈÆÃùÊJC"9Î4b¬ôºø½oøáw_½|x\·{¾«õt`i¦ùÉG¿ù§_üt_»ÿöw~ÿ› ª, “EÈ!î67ªl^_mÉJ–= <»K‰(Ê”å@‚<¯Š2d…ˆ~ýé'+þf\ÌË…ÎLÊQ93” ʸèè(•:¢Œ8Ó¦]Ã&‹i¶$-â Ȩæ·+I.nζ{[—ó ëšoÞwüN‚ ëñ4Z”³U¿#86}]‚!@-à-¯$C¬ÛY»8»Ô Í«»PÃÔÝ»¼t6»@‰áõÀtMSiy%m_C„¤ÛÞ響z‰î®u•ÓñÄò•F;eÉj 3N¯Ž X„Ù"NëM=  ¨W31”Žß\D±B¹A ¡ÌÙâŒF`°HK˜“’[wL=™'Ó2„iæÛö«ÉÔ5¶ØÛÌä kgã¬ßƒŽÖþôóWÛ=@{0*”¶tQ'‰R«ÃË˜È ôwÁ¨˜-§[[+¦æ\^]onl¤"C é&eÎÃÝ‹Ë ´o}x¿¸A·ÞÞß¿»Ó®Õ¹Ä¡UZ!ôvM–HÃÂ0±b”—™f[YT *ɳY•#â7 ‹Áb¼ÚoaL!FÁüÂ6]¤yR¤„à¼BšVªJS˜;¦[ÆUZ-u]óÜNœÎ5¬A¤sÉ(V¢”q:«uZ”x£«›f¯¡®DEtÄ*‰„ a•ʲȯ7“RTš¡#H“,Öt›Å$§ˆ0ÆŠªt,S*”Ʊãè`%¦Hˆª*820DæÌp Yq 2äJ ÌÓÄ0l]ÓoƃZÝ×(L A¤0†J€’•¦ãr&«"Òt£**ÓÕ "e.(•†a±qÊLl))˜Ì±Â⸊-êyãE\Á IDAT!eæ˜NYr•ïÛIWUeÕk,-¨N¹â,cÄĈ"‘ äaΕfkpÆD B˜géØ6ì,L%VQýâŸ*°,²êé«'ÿî/ÿu¼“¼p놃µÑh>Â~£ÿôåã«««N{0Ëâ,.D^æ¼ÛlÛÔ*Ó0ª¢¤ª¢@p¬#ŒiæŽW›/&¦¡µú~ÑfßZízBǺ[¼yxñúzß¶QbJ9æ°D5ü•8œBÅ!¡!Š5U±¼`í†[äi\rÛ©+ „R:.0q²ª fÅs¸ —ͺ›-E&gÝîj¼(¾è7úeÌráʸÏJ‘n´{7á’—Üð{×GOm+Ox;™\„QK—¦M°åŽ.¦TR¤U¾Ý¨Œ—©¨C­$ËtÝÒ¥…,Ößk¡¥KPÛl•–ÁÁ×v¬Ì^ÆË• ‹ %üþê_ Y¬,mÖ$Š b&B¹„ÍH¢a´Ì¼ñö|>¹M ÝÇ(_מּ\6Mliµ½[÷~ùñOn<8<¸ûâä«0f[ýµRfy\4ÚÍã³wvLg7J ˜½Ýþù«ãp¶0u Ð΃Y·î©ŠùÕéàÒ°ˆÕhA°sÃ1þàÃ>ýìËGÏŸ³"ÛÞÚ)(9þ–…ï5™Bè2Œ>å@ÃpP"l'q*PÕpjïÞ}_WØê·ZÏϾ’©,9L–SªcÏó.¯Ra)ÅÎꪦ[‹d0OøA¯_°d¶¬²eŠlìºæák[ï¿ûnßXûÕg¥Iô½ßû‘  Ñµö_ÿé?ÿãït¿yÿmC‡;ã‹Ål¼ñæƒ(+}Kï­¶.‹¼Ì{-¯(I-O¯ fš€2ž‡£ÅÕÝïýägÿ2Zë˜F3A5KR6¹™X6ñj~8IbȆ<‘J € $Ès jeRlî­TœŸ5¨\×™ÌR ¹aRbÏ÷„ï¾ÿßl‡ÓA,=·kù~œJ¨©fÍ–Kª!ÃÁ[y•PÍÆÊ°\Ž ÇÂkš¦9(¦ÍZ+˘nX‚8)}WCÖùéU}Å04<¾\46í®½ÂS9Ç=óΫG'o|ëÞâfúôÉS}M_uûç×§‹4éÑ­›ðUg£òñìÊi™e$R‘ëºí—ø|4[”ón˜ÝfÌqÅN§³~£5F Ó,âj^2[3E• B;º7¢Ž‡Ç‹E¹º¾wëõC>®JU¤|Öµ»ÝÎNÌç5×c€÷ÚëA²\ÝhÛÊWM1ŸL»¾®éñxy|vòÖý÷f—3» ½„èŽV…*®¿éÒÊš&a§Û2 HóJ‰Ü68*LÏ‚Ý\.VÖ[tY‹¤UiEI/Ówª¢‚Q +F¤dTS@`Hu΄B)¥T©išPH׆@S©LJ†©5¦Jiê~Î% j ,K °„ @…RV™€0! æE‰‘IˆTiªy&ç€e Ñu‚¬ª\"“ÊL` f}t1ÂDº5[Vd˜”B"…°*² dé4)J˳d^rɼT71ae˜s¨üþj0ë¥:ai)€„5Ãà¬RPCšÆ“TÓ5ˆ!’Td• Ð<‚„9¯°iZR–eVRÝ–€™š[ñª(––îpKY €ÀLBÄX0¦Q½HKV^ÃRñ*7]¯,ª“éãþëÏÆ×IʃýÝ} lŒèj¿vu1Yiwúk= ·kýæg?ñÿ“h_O·fùa×Z¿ß´óþâ Ý'tž>ݺgF…Q°–P¦A¶ÝAAáŽ+ßR\BQ\ಠ\ePY2²]–,<3š™îéé<}NŸô¥ýíôÆ•<ÇóýÍ7ùžOä'?ýÙåîJ…xáÞíÜÓG_>^í6Ý@7fïW—Û£Y¹3¾ÞêƒÙ¨³CY(LWGμMržb_ºuÿ_ÿ¿ẕ̌ÃÁÖT’â®ÞN§‡Ñu}2uÓ šÑå¹ÚnÝã§ß>}óâò‚ð+ óvzxÚÕ³Íöéaõÿô³OæË¶MDÏ>ÎÜ¢ÝZ:Õ¤/þé?ÿ­·_ž‘O7ï½õÚ}Evbÿí_/|žæèÆâÅÕÙs¾(&l$P‘FÁ»Þ¬–ÇÜòœ—ê R‘îöû¬BJ*g¬I”¤ˆú¦Ë§™®9­NN;ªr!þ÷~ïoÕ¦åÛÕ.«L–ëÝP898ñ¡}vquPP2)¾|z9žË¶Õ ÄÕæcô¥Ûß8ß?¿º:ÿõ¯ÿk÷>ýàgËÉɺ{–QÕ;<m}uïÕû?ýÉ”ÂÉñÝËõÕ|Py%ÆùH¥‹óë¦eE«ñáöjŤ.ˇl7\^^îÆ“åÙóG#9®w _رXv{·ñÏnŸNVgèó/>¾}{ì†1dzç?]=æ=ë^½;ß\”µ½8Y«g¶Æ;Ò;_W(<ÚGÏÚÑ,ËÿüISáÞÉéEcœ©—òpgâôÍíÉ&7G…ÌcöW?ãþ‹ÅÉѳ'åüöý8ÆXd™í“/ÿƯÿ;›Ëúùêêå·Ncƒ]R 볫¼”³åèìÓÝòt‘pL(u:2bÆó XæQ¿«×Uqà“Ö¤˜²r6X­¥ (‡„c»ïÆóÆHo[D“U»[OŽ&¶µÑ¹rQÄÀún<š4í>/%öÄ:OH"„oŽ£bz¾Þ¹`ºw”G@dœ:=¸Ô(sý ÛIRdetžrê%˜DÍ~C˜–ÑûvhЬB ƒR¶¯U¦\Â(j£{Œr ˆÕ:0oILŽ$_”ËÞî}ðÈó.¹RHœ¤´½É¥ÀÌ !£Àñ‰ 2 v·Y/—Î$Í8FÒ;£I˜Å`c@ 3ŒQ`½u\2‚‰1§µaBŠ8±7ÚcâŨ• ´Æ‘˜j<6­M¡£ bÀTÒò‰J „}ÿÏò?üOÿãé¡Ä‘>^¯ÿà?úÛ/¿ñ­?ýÿH7-$zó¥[÷^xE"ñ“~ÂDxÞîήŸVÅní=ýbuýü—¾ýk9•. ?úé{BœkÂE·éöˆa6YVjô³ÇG… uÕì)!ƒî#¦Já²`'ÓÛ^Çר:šcÞ´ö]¼Z°›šç+·y| ™—×¢%‰ôÆ+ÅH LNçt®u“üöä–¢ò"­nŽî8ÓÐ# :7çÃèeµ¤ËõùîàåÉøp±;«·Ç8Æý™…QdŽ5»vr³ä7:æ2óíÞAÌ3æu (&£Õ³JQ…q Ø{Ó`Vy±ëC sFi †ÀèÞq!D¦ Ài 5÷9þßý·µm8–£*ÏÏ.ë¬R‹JíênÝl^¾}ß–)b­ÙwH2l\÷äüZps4:ۢʧWèpë._ºuûêjÿÕ¯}åáŸömëî©í»àRÓï_{í¥ŸüôçÀK7èrTì6]®d××Q(êͰmFË%¡Aa~¹^!NJAyš^5.¯÷à Ç —8°]ÓNçt0p¹Yå2` Vzo‡04M É ‡¯¿ðÂÙj¥FìÆéé'?ý¼Æ¶?¹7ÿÁŸ|.¦QM«Í'æôe²éÝîb„žç‹³§u$Ì k SîòºI1yìc*¹kÇãâÙù^IÖG«·~9Í[g†M,JND±Û´” gW_ 6Ž€nÝ9hX­šwßùΰï³@„¢3‘ã»_yåãÞ{íöË'·oü—ãÊÏOOyôP:»¿z´}õë¯êvýùÇON'³ùäìñ&«d–©õÕz²Öh­1—ªäj³ZMO€Øåå™sŠx¡F:ˆ.F/²B×mç,²”¹µ¡éúLI‚I"q°].'˜CŒ6µž*†<óÉ…Æ…Ú7uL„s}´Î$ i@e&#¦WçÕDe²Ö„Ø5CÇh ")9B‚ˆ1 1ÈNï¥ä®&¦<Fé`ŒÊrâÓf×1iÂÉÍ"å·IŒ1 ]Ÿ”¶: ã€ó¡¤d>£]–”„’Ç€N> .Pã‰ä!x¸ Ìø`P”ž8Â( Üû&†ÀY¡½Œ•u?0 Œ²èC¢ !¢›:•˜qb=ìJ)„è©×„ŒÁ#b)¥)R‹¦„9óië5B„K9 sQJŠ (Øh"À±½Æ)fÓ²½ÞQà6Ä€°Å‘s%2ÁDÊx vè:*$P„Óõ~þÁþßøðñSÎU?ø·ßzýoþÿÖåõêùßÿç;wŽæ“ãÅÑòßù•¡ ?zï¸ÌM×ãz+‹ùŸ}ï/Uö_y'5"ºZïê«/»ÐO?þè!Ï¢iÚñ|Ä+دëë«NJV”|s5hoA"p¤Þ;¶[u7_ÊnNîø„æIeDdgJBv½;U#QfœÓŒ•¡¢ãYå{›*ŠL·š±àcðLæ‹vw­D’Zß$ð€¶CpHCb( ¢X³]˼¤B’èbô]ßyŽ !&¬%§b$5ÞG.åP·Bq*ù~Ó2Ns‘EÓ;d²‘„¶__ÈŠ (ððïþþjÿ<—9x¾jÖ“ƒŠÜÔ{žóÓåâbu혺?;T>zøØÍ '§Û¦9_Ÿ}ãµ;[–’~õlªnÜ~ë¨(Пþáû¢äo½yðø£þZ¯¹4Bé>)Êêü•»/8ðç_¬ï.Ç#¶¾ ûõåa5‘y¡JÕÖ;í0fòÅ;7¯]?<ûÈØÐuÞxw4ýÒ·~óºÞýèýÑhºœÊês´éÎßz{~ým­¦Â°aºµõ¨È8á­ïgÛYœLHãÚkµ=.u‰L 6µ‘Þ­ÂîisúÂÉ;o~÷ýÏþåéô–Õd™RÍõµn6»=­nn7gU^U¾í„L.J†q«uÛíç³ÃÙn{1=>ØmvˆD.¨iZ`Rf««‹»ƒù‰Õ!A ˆº0 U%׫梔YÓ â|ZÕo¢­*¾½ìfÓÓÐmV1•gîËa°Œ1$Œ[뺾O* Ò#ïƒc8†À0$@)&VäÜô ¥w  .jLΧŒâms­ø¨ ȇM°ˆ)J€ãzÎ@ªb´µ–Ê6e,!Øo֋ù ¾»^W!ÄÑ~½.¦"y0¦'Œ1̵ÛcDŠ|¹Z=Bfyé¬I` ÈQ*©÷¦ºÉx„1 Ö‡¨1œ².XÇ™Œ)6u+QÕ$†©(F‰Ê­s€0çÅ0ô $ Î0^¹¡¦Š±(zÛ¸Ïøñ¨E„0vsJ•’œúè1NÑC×ꬔ(Ek•gý®3¦“ãÌš/ª±÷1ú®šn®V@€ Hôz•Q7 g £äq`”OÛ¶M”é F€±q:ò¼ Ä`DS€ýøÇÿçßû{ˆDƒM»ëïÝ}åïü'ÿéÓ§_üƒÿë4voêþ7~ã7~ó»¿FPþýõ=œ¨"dðÛ¦$¤Û¯Ü~ñôåÑdºÙ®ž~öÙÕõ*™ù½ïJ€D>{âp/ #(dçj¾Úoë¡™°2&4:>|륯†ùkß:}뛯¬.WÙAI<ÿò!a2:º¾ÞÞIȯ®öªÝ™P9ÅÉæºÍ—Å,:y0' cz×!L±ä¢*r Ø½ .„"ªFã´©=• ¥(X9¸ÞtM9ZbŠƒi¢½Þ F©¨\tŒâè¹wšR bH”ÆXŒ&à”rÞæKm×g³Ã)‘¡Ý£Rò¼íö88üû¿ÿwž<{ÄG0Š[ßsD3 Å¸²ÃÐö{ëQ¡˜dl]ë“›G»m‹êÍ˲®·e&®®‡\ E9Úu®îVeq|s1ýäéç‹lA ÆI–Ÿ_F^ñN0袾úÊ‹7Ÿ5–øjÌ œ£”XAëÍîäøh1;¾Þ›Æí‰?ÿè¼iÛ¢’ÛvxåÅão½û'Ÿ >þ€6&öd}©qÚLÇ8"×# )¡ØWÒv}gÓÛo¾ùê˯ÈD~øáO8qÇË;”Ê«ëÇugnÝß]¯?{üY.ø¦ßs„šÁì]{cVö& :c$¨EŽ©ˆj¼mzËLYíµo9ÆÄ¬‚‚¨®¾û«ï¼ýÖ¡Gý|4 ³±2]? þ`^ômßÔÝâx´­ë£ãªÞu¦ªÂÎÇz0œS×Ùf“Ét÷äb~½[¹Á\îvqèÏVgF7³ÙÁ®ÞsÀ‚Q„R‚J,­Ç«Í.!K9g©‚tÞQC©¢ÑÅA÷6ÄŒO¯›s¾ˆóõp9ÊsÛB x4ºo»@Æe1ÉÔ¦^½÷Ú¾Þ8O»mw÷öƒÌn[’½þÆ×¼³Ûz½X,—G5*ñ¾Aù׿rç‹OŸsîÇ“ á“Ëìwã,/Ñ£GgóÜ¢®|rãYE<ë‡Qä=Ê•ÄAïK%®FÙ°‹’ó¡ºkøB„PW»-ÁAªÂ]äåÐu²PÑ[ŽØ`:‘çÞ!m·²XF\Ä¡Ž)¡€%ÆÎö‰¦QV¹l0qp€Zïx¦RtZ”ˆÈ”Þ˜ÈPЈqáý½Ê…T¡oe™#"M7Pú¶È¦Éj‚¼O“ÓF›\eŘPW·˜¢”°È³ˆ\p„Ó$8 BÒ!’¥>yktÁ‘ØÁ÷ I*b¯Í(Ÿì‡ %Œ2¹½¾.ËBHˆ‘¢àQ"„P È;Ø)‘ñ‘5CFf#?Ô@B$M z½/«)‰8‹@PŒ—( ¡ß¹x®Cvoe!Q Æ$ĬàU°ƒ'X`™L§! œQB ž \@(iãNBÊ =& „tÞr ¡w [©FÁÂ6% RÜ œ9Lêr>Öý@°ã²ŒY_S¢0¡Î!x7ôT0ŘÖ^]^dÖš¥2%Šˆå”Ù!&Ô3¦šº’äeüÙ¿ú“ÿ÷ÿÙîj Ù>*^ý×ÿÝΨúïÿîßÕ®QŒ–øþà?[ŽŽ?ýðËëkŠtgéɳs‘È׿ýÍÅbY£ëÕóÕó+B(áz³ZïŒé.ž?Yï†ÝîÊb$9Ø¡ë%!µN{ï>x÷ßÿ½ßGY‹±tCWdŠËl»_)!‹Éx·¾$‘&à@`‚0I)2ž¹ÁzSg£pæ“1&g‹¼ï¬Æ S?ç€Qdœé¡ï;Æ@“3CL¬,Êaè0!ˆs.„`‘“¬ ¡‚ö›6ˤ(skÃ3Ú€Bè#.„„"¨Ã4wCE c$‰ bt˜Ð^¨ q¸yç¶ítc4ÐÆipD¨6i½ß¦˜œmÍj×åB¥äûV[|åÍzw‰"DÇE&0¹Øw’ñe9ÉËÑÙåÙ|4î]œ5vÎÎa·k4q³ñâá—ϲLšB2À²ç϶u³¹urÜ5n³_?øúëϯûZGcÀÆ›Jò§Ošª˜þÍÿðoœ?¾þè³D‰§Cï&ëÍ^©ê…Ëv_Ö‹\5׃ŽF—·nìwg׫ZˆâètÑî:ÒñÉÉý^(26™Nîܼ€ø.v»JæÛºÛ·nœU9š$Biv¬òIYœ×Û˜¤ 9Íe!îßxù¤\LËoÿâ/Uªà9p¡RÝPOÊ 2III1?xN€,§ËË‹ëaØ.}q)NÈþà‡ï߸¹`œ<üø 3ìîÞ½{y±™/‹oߘæ‹åa5a“§OV,#Am&•UÊ[RÑí½Òºd…ª(¿¼XKœGMm@²b³nNo©¥äå¬:¼wû«b|´8žüƒ_ž-n}÷—~ñðÆKßüõïüöoþÚ·_ûÎKo¿þ¿ú+ï¼ýÍ·¿ùÕoû›Ç‹“ßúëßyëÍW_~ù¥»¯¿ý•wó2Ÿîߺw¸œÏÆ…"X|º/ÓÕÅóã›ó¼µ} "=ø³å8ÛÔÝÍ{wuÝGëò¹b "&L `Bi2+LÛ¡”r \Š>ø2Ï)C¢1=c¬*F:¶f0JrAëT–•ó Á”iõ–™c¶Ù·Y9†˜aÃÐa0mC×טá<¯ê݆`|@ž`Jt?hÓç³®ítß3.L$(lÍŽ`\ï·yžI> !Œ¥ÊCð;QwMÇyÉi;b,råûSd{í1%Î[‚â4@tvE„A‚”p²Zcß{™åˆ8L)áXÐà]Š>b«¬âŒí÷«LŒ ˜`ÂRGÄyâ).\(M!*dŒy‚(g º¦%’•C« BœKg;*aÐýîüšŠ‚0®ÛVª@Þ Œµ„“C >Fä"„ÕmS#J (çS$BCÞZL8c ÅŒÅRô¾ç4ŠiÝ£˜Œqò2Œ1,G”z§³lŒÀ;݇©â0!4"l]ÇX“Oq@˜ ™1ç}ÂQ©¢Ýì`.s„‰‘1é§œ§€Ÿü|õá§ï¡Œ5*+^¸¹¨Äly8vÓçŸ3P½vuk^½ÿÆó‹g®ß?¹}Pª‘i‡ÿÕï¼õ.&>1†q‘ÎöFwÙ<[ÞÐuwãÖMi9::98N$/^<<8Þ »,.NËÙÑüÁ7^׃•¥àœ2œb`lÄ9„ÐSLŽÎ¹c"š 6ÙØ†èŠ6aÔÔ •À¸tÖ›ØKÈq )Æ’é.¹d¼ÞoNãérèkL°, á] ÇQŠ@X½ß„N; eá €qL‹É† 4DcH6É9®Í€}L1aŽH"!¸Œ $"Rׂs¡Fø7~ûw£mÀº6û”H2®«Á‡‚b.åzÝÙØžÜ<»Øbl'Y>)ç­i|ЄðF[Ééîze“å²èz}¾n_<ö6é!8W#à§ÓÑE»·½³ÁfÓÒl´ÈÆe@ÖYÓ·R9aô; ŒR R°˜Ð¾ë¹Ìƒ÷Þwy>u¾Ãˆ2&R²!xæœK8R&´na)”±¨Ó벬‚A˜`ÌBßZÎ)P¯wj<"¢Žr”™n-!çª|kfj†B£›ž Å8r:P ŒÓ¶Õ”ð€µL%‹1qNäЙ¦ßVeIq9Øš ÀcÀ1oC@uYM¾üòËÿò¿ùo‹¬ˆÑ´Ö.o–ÿÅü_M¦‹?ü§ÿðÏÿøÏ{ƒNO~û;¿õÆ;oòÙ{ÿëÿö÷{Ó¼ñµ#ÖU!±ówÇ Ýº«—óçÅæzsrpÈ@­÷ë¬Ì»Æ]›eäó7ܺ÷Òær“`?=¸i·Ùã³÷—7ŽÞ|íµ,EbußOË)¦ÑF$±ÈBnìàm`KZç»Ñ´Àž!lC ÖI#G¼2Èz Q»ÙììêѬšHUvº Ö•¥ÆE†ßlÖEQ 18B"Æ"øDŽÖ%K78g[™8âÁ¶ C€]ç0#Œ†¾×*«HDÎ:̱·-c”CEˆOy6¼ûîWëm}àÀ¥Þ%cï]¦xòñìºæ”–ßït¢ »^õ*»Þ˜Ö™¨3©¶Û«ƒƒÒGzq½¶Î”¢`”×½Á(hoNŽOÎ/.;m†¢w‰¦((í´cöûŽáLPâ"Œ›Ï'WW›Ýj×™V1z<:|¾½º¸^MGÓINŒzåÕ×íàŸ<}ªZíšIU Á'Lt‘×›1b¬gÞ.Ó|Üšúàd1uµúÚÛoŽÆd ¸T¥ÓîðæÉÕåeUN^{ó5Nél©¾úàÕï~ã·–‡§¯>x½ô¢8Ä÷^Â]y•6ï¼õMšxr|ãPˆìëï~sTpžOoܘ-Fu×å2—2à˜qž¡0ðéa–眄®ëFãƒ3Žª¢ô)%ärQ•£ñã/?9˜,—óÏâr6oí0tÝbvè¢ a89º5t}¦2%•kâòxivMd~6šìu/9;ZL^yëÎÍ“å[_}{¡F¯¿ùÒk/½vßúöoÿµo=x ¢;¾1»yûn°iq»4Gg§c”×Ýl.Gãr0PLJ‚0 äµnle)HÒÁ§¬ Çè#I©"ÇÌ'˲œs2f¢èº.D'¹šç›æ‚1œç“ൠBHD g‡¢Ì˜Õª&3„%ÄØà½Ï¦õfƒ*Ê1',!+UuÌ«2FçŒË %xÖ7m3ÔG‡§¦ïι¶Ž"Qä¹u^(ÅÝ\¬•e)Ä&€¦sÁ‡¢T#’H@IÈùäÓG_|üytèùóóÝ^C̶îñx2+Ë™î»èaŠ8>9Z]n©H…ªœóÀpYU'G·Æ“|:[§'‡“åìÑÃGC¸|åõ7â)˜²(1Be{Ý;.d®kµÌ9ã,Aœä¨¶!E1‘dµm]4’Z££ï9L(c×E¹ ŒihÊ€aB‚"Yp!Hå“`ºèsÞ˜&ˊ豋 F%Ù 5Æ€'FSò‚e˜‘„˜wIc#yîl´¦ÍóEŒ‚•RÔÆ„”º}«Åÿÿʇ{·ï zð S 1y<ã0žŒt r‹ùaÔ¡Ñ= ("B=[U/TQk¿ë¶Š@Œ¢î`JRz<_\¯bˆR†b4þâùÕbTæJù@œ >ÅJd¢,‰Ã(°ƒåtßt(†DA¬ïµ³Ñ."r0ï:ÝtvT)Éi&Ô7~ák“©|ôìcÝe³›—s¼Ia<šbl¶f©2c„(Âb ÓÉìäðv×îžÝ:zq4.‹éI”B˜ÎOÆyuyõüå×Þ¸sçŶÛEntç<Ž¡k›gWÛ‹¯~óÌñßþí—~áÕ_ ºè¹Øù²`ƒÞ¡ÄUŽÓz€;J@w>AÇp`´Š$zm82“”’`=† ¸ ˜9d'ÊIòŽA)8Rm†²,‘1™MÏn¤¹à«™ÈºÝÆÚ=e’Ѷ'LP½×@€ ¬uÚ{[æÊhƒ0‘J)`®˜7NIˆß­¶ŒFÓE&ˆ$(%䢵œ‹˜%8Ë8Ú¥”‚뜋ÀsÍyŽQŠÁ"D t_ƒäŠª`‡ŒR%Ž¡D‰LÁ ‘O( ”³, ’F§SÀ@¨ñ‘3,•껚sFÓÆRNÁ‚„!F„r:´y›•j\.H‰Xœ0JÄùN·;YN0xH$8\oš¿zï'1Ec7t7öÖ½L¦·Þ}”zÿ§UÃ?þçôƒŸ~¿3k»ÙÌ‹Y×t]Ò½®Ûõú£/?iû‹õeoawãdÁÕ¦^œCj³Y_wˣâ,”Êʉ::9ˆCÜéuž‰ŒÍ^zå&–$J¦ä(¸‹Tfc¯[BQ&UB.bHÉVÓ'Ñh/8¥€PBŠIJqÑ÷Ûª(%CÁZß95*aÎ B├TY–Kç,B…pzèÑ»¼¬¢3€­’ Š±Ï¥ @(,Æ@Á3LÂB1Ô{ïL¡¸’À$!ÂPY–”0Ãh6ö#ËRÙ.$Œáö­{µ®¨:g&ØG{²8T‚_÷­Âà ÁHŠ>íÝãCmÝÕ~—KIuFŽf‹QVÍNŸ=&ÄsF‚‹ºåJ (ÅÙdšP¨²<ùÁŸÞG)BB ä]Û·(ñq©fåh³é§·ŽiP ¨îö‹¯O—ËøóïýÕŽöÛ#¢F™wš3L˜a°ÁJmï&Åt2/å»UWù8ŸSëIžq>Ú»UŠ~>?ì×JEgº²J÷û}QØÓgŸŽ²b>þòÉÃÎO=å”VãùÁüQ”•Õ¨œ»0dªp™dGE"¢‚î÷[õÑá±,Ì;­y\œ=¾ñ K|»ÙñŒ`¬m1ŽRfë‹ýü`ÒÖ]½jŽ&ãQ³î‰teQ ÀfGUˆ&Wåâh D¼ë”ˆ2F€&äB"œÁ.zœ"¦Ì³TjëHä&¨HØF¢§¢„Ã¬× @©ˆÞ ïbŒq°ƒÕ¤mj™ F…så „ ÁFçp¢¦o¸)â¾o&¤s=!„20¦}»gK1ÅÚÚ2/ƒóÎZ®¨6è¼}þþO~LH‹Ùøéã«Ñ‚ ˜þá?ú?zïO®Îû¦ ï6»G?;»yóæ¶kvûc\ ³½höÛëÚš³ç«<Ÿ”£—}·ßæYec'y.˜ Ð*U0B×ëg&z P—ãI‘,¢‚ň$ƒ¡,P2¶¶O>E1K8â¡K.Y&uÛ@BUQ» 1†—^Åd”"2v 2Y¦H2€pŠ(/‹„ID„ñÀ0 QI8Öø,—1z(¶Æ#‹˜¢ÞYBpÂETø`©8ŠA·BHà”£” ’ à0 MJ8¯f)XÆ(J)zÍ…B Áƒ¯¼ÝôûˆS0‰qN0 „€¤W_º¿Ù¬¼qÛ}-ó,‚LTBPL®ê!ÇÄô0©u#%æc>û$§9a©5–!QUâh¼hë]BÉY‡0ôƒI!"‚#µ™}oa“阸ÞìO–£¼ÒCÝ;+„r]ãlŒ‰ ®Ÿ,?þÙ'íO/..sI&eQkmëó¾Ì$Ž©×ö•ûw÷uSTY>c%‘Õ³ù\p:^Tã"ïM•Y–ˬ(ÛfG VÙx4žêaßn¶Ç7oÄÐûd•º\?yøéÑš/>}x89<<:äœÌ' BQBEŸW2]Ì—ûæ:+³"/ ‰C7D²¬H)`—çÏOoŽç³€"i2šo®®SÂyV u{ÿ¥¯¯uß¼ðÂË“rÜïv‹ƒ“ã7%g£ñAž b:eál7›LF“ Bh<ɳ’¯ÚçC×9ëu“åt–Ogó%HÜl·2+²‚Ç„8.쇮M–„‘à]B("Ä%Lö1XÊ2„ú€3Á% Á%À ¥2¸„ÈÀPŒ!ô¡@"‘6›«Ñd„výŽq€qB)ËFu_‹BEc¯VWBä“jº^]E^Xc8/†¡éÚ>Ë ¼Ùìe©p×ëH£,#Ôx ˜sʰˆ^É3Æ¡,'Æv™\Mœ#.xmšéô“¤»>Z¤2Ž16xç¸È0õî<Ëóà¬0Â!x’¤T¾· û<Sέbð\åzè9S EÎ0ÜÖ­éõd>£Dc…Ì‚!íDŽ)A„ºÎG“9lŒÃœ0Êi[列 ïlð‰Ic¸ „PB 7×!p*DÂë#b$aO’Àv'h xßG<Á5Áá,9Ó`Âæ(ZÅUœ"½³[°vA( Xb„j¥.86Xp ”âˆ0Ž@iY.ûvÍÍTÖö5¦‰$âLJ"̻Δó1JÈÌ9ŒCDÅ"Æó,†èƒG0A!TŠ EÁZ"¢ÑÙ!!’c™”ÖYL(€D§¥P˜3ëz.dˆcD Ä„CôU9²z@`•(qï{ï-!“膡kÛb¤¢KF·<Åò,¡‰bî“S…|ôÞù{ï}É@ ÛÔ=ìƒ|üÇÿä[íö«Î»Tæ@†N>üâñÐ*S(œ’Ãáƒó~töþ'ÿüìêìù³?øB£ŠòH°I) !¨=4É‘ëõŠ1Âqv~y6tý½;¯ ¥ºvͨ ”{kƒ!D|–ƒsޤŒW8$£ Ncâ¬æ„[ç1J/LFw„’¡Ó19•U»ë¶ç #ï0ʼngåPF·BÈä,S©M¥@›Í&‘ ¹š6¦¤”HP$ÉU™7£%Aq.€d\q„©w=ÂQ²Â'1pºœFL ‰J›Eo¿ýÚ ¶vQŒ[ãb Œ )åÕêÚBÀbÆÆƒù4çßën1šYcçóƒËívVf¯¿üê®nê}­¸R‰¯·«¢Ì9ïÃj½Á8yFw>¸ª"ËrUo›óÕEF ÙÚ¡ùÿH¨³ŸmÓÃ0è×¾ÜÛ³¾Ï»~û7ûxfì±=N;!uœ6[!miK¥¦‘8@ @8 qŒ('¥ BD‰hbš­qêz›Øñس|3ß¾¼ë³Þû}íüþˆ_ßîí n0¦%¦™D¥`“é4ûäéÓ£kºÒqò´z~öb“&˜ Þ«p¹YÝ<º¡¬Óº;ˆ‰·oÞŒéh]_?¾>Û›.——m¥^{㵦ì2Q´rãb‘©ªÚ{Ÿ$ÉÕj­CxôøgåÕnRÜIh:J¦_ûú¯ÝØ,7ÇׯsÉŠtI‰ƒBQ‘õÝ.!2åG HŒ~4E!ö#Îr* P±g…êC6Î&Ó½Dä+s‘Ìæ €\žçùhÌ0Îǹ¼k›bœ ƒ·Î¤M’‚ ‚vÆ!CŸüì£m¹MRWí¶*íW~MR¢gLeÆcºmŠy–Yk|€Ñ Bxˆ1¦˜ôªuÞRJ@¤Æ(* ÷1½·ÊŽÕÁ!ecYdÌàBÌåXÛÚ{(Hfí.I §² ‚Q²<_!ÇÅq×·œÊ8æ<„ï»6I²DŽÕÐAGùTëDÞeyÖU5a,D`D1FqïÛèÌ÷¬ë!ˆØ|œYƒÕB¦Ò„28È8ÂíVål6‡ØzGœvX %¼nKÂ̦Ö)ƒ±ž €‘ºèãÀZïB$ç f^©€DÐ!ÈŒˆ¡,Ù6’a&‹w!zÈ’C¬ÚÞZ¤Â[E(C#†0ÅÞˆˆ ßõ 3йµã‚ JÁ„€”ê“BÝ[ % „¥ $0xD"¶WˆA4t ¢˜GŒ,pY aúHD87g B¼‰ÎÔT0zmzNSo•ž’ÄKd®».F‹a!bZ[ÂÀ»„0ªx×r’ÃÑy"Ë Ø[C$4ÁaJ¼!½3:@1Xg(0:yô gàygƒƒT"g· âb°: ƒ©Hº¶ ž`B;UIž"œYcÂD–­wgËáÑGßÛ¬KïÌh]ŒÒ<ßÛUe1ʬMßE€®íÍVõŽc\¤©Z ᬠˆ@ »vœp†w»õf}ùäÑéÙóG÷ýôìôg'o¼þÊÃOïMÇã,“1PŒXcÊro<ß¾{GÕU^Œªë0—z„çÒモ"Ñ ™L™ ÀAï½÷†pI Øbž2‚#ˆ^{„a!‘SÓW[BÓ¡¯0òKJ$€F¢Ô€)Â;k!òRJB$†³`Œ(Ç §•,:b(„ ˆ"«Ï„Ó΂‰ÆC̤œÈËgzB9ã /¯[ë$!xJ˜\–öUÛÌdzAi ‡.ÍR­T:–Ï/‹„©¼Ü–Öš½I&™üɽ{”D„adlWnCÄ.D)Ä®ê‹×NêA)냵±¦m„@FyHtÚXäO3^j’’ǘ ËjU$Ó¢˜ÆØ_–w¦w_{ãnµÓÔ?»÷Q‘Ï9Bu×#Ä" nqŒ0PÊ9¡\[{mÿ`o¼h†áòÅãƒÙq^“b™-ö÷÷ç ëôh2&»õr:[ `E–WMyõü’É,"Ê ~ïç¾²|è­Ë |pxÈ(£’ÁàSÁ÷÷#ˆ'ã|¾wØ ½”œ2:šŽ1ÂÑ›<†$£ˆb.2Ý«¶­©¤ÖwTp€€`œR `ÈÓyDÀ‡@Œ¥ìû’`N8Ø"ÈÊzͨ‘<ÙêæÇ~G»®.{«Íj½ Î}åë??ɦÖk„‘EÓnó K©$ù¦êú¡/²”böâüád>uºÀ™Þk¤³œ©Æö ÍF|½Üt}ƒYaTˆ12š:àƒ³À( «šÑl†1D zð È$†2x¦sÊ1‘Ó$„^fEˆÀ¸JFIP¯µ¥2ÔÄÛÊR0Àœm ÄyE)ˆÝЗeã|?Ÿ/6[Œ¡Âv&bL0ƒÇ ˆ ¶eI¤+ã¶“ñØ™`¬EÀZåÇÅž½Q–’æ¢Ú6ç[Fʳv¨0¦˜ñbW•ùx!ƒs6 ‚B§-D KÒaØÀèaðÎ:ç¬SÖGO8‹ƒL͘Äû`1”±ŒL9¡(z"Â\0J„1 Sä”Á1ÆT­1&"MªuÍ Âä¨[W"‘Ó[aDw=„Qaô࣑"ñ.:¯“>@*˜×A†(`Ä{Ëö.`(Põc€ŒÖCŽq Ã|4ÖENÓÁöcBBÐ "ì½Ñ1–«=³@Œ=&Ò  6ÚDä)ʨˆ@’å]³#”ˆÑi*(€ìËVŽò@ð‘ò õ@@Ð"°3Ú =”0B«žp ‘æI£óqÀa\°Áˆ¢5©±]Ô£‡‡v(½úÓ?ÿôÑ)"IÀÍ›×ë­ŠQÒt>ž ¡ ÁC(]Wf<÷}b 0Î Ö Ni%¤ >²&…Ð:äRîO7ËÖ ýårûñŸ=zñ¥ÖéD£Ñb¿]ïæÇùd:uJð‚NÆãƒsŽs> =¥Á µ…ˆŠëÕ’‰„êѱŒcúà#Kx„º aœE CðAiDdPMšæÞy]@È[ƒaL¥¢s”fÞYL!",ƒöÛ®ct_Š”@€”2‚YÓ•i–ÆÛ¾NSžÊìbu6›Íœ‹Æo»ºV6HIœªÒ\`D­jàoÿößëÛ&ábÛl@clïÌt”?»XiZ7;Ê`Â&—›%僌`PuåÃíÐê AHòï‡.xpY-o%({vu:huûèz–ȳ庘ŒO—Ë×n<_¯¬6û³4 òôùr’ãl4¶V+ndc#Àp·Z§—ùÔ)H©Eܽq÷—¾ùK—ËG÷,WçÁæ i™u¥®¶«ýé(¦\;˜¾M_¾}÷ø`q¾nL_~ñ­¯ö¶Ã0ܼq'-Š«ÕóÙtÌyA¬« á B1e…ñüüák¯¾óÙÇŸ-wOï¾þjFm·]4ÍŽ(PÖõƒ N.QÖ»Fæ‰jc<’04:ŸO²h|€‘0®›–JªUOq 1PCg•›ê¡zÅ2jÚ2ÍuTÕz).öæëíŽEiâÖuå6¡,xk}lê !Ò]µ¾\7ËË‹ºÜÖLMšÐÕíÅÞäàýçõ×~y¬:§Ìy*‹}Zt/Ï×úð– u`ò|û½B~MwgŸÆa~úxíi\oôÕÙÃÙh\Œ¦ßùηÞxãåùÞµßøÕ¿“&™U-– G0Ô›!IY06`lã-§’#hmo"‚ˆÛYÆ8X) Á¶e;Û;°^·å6IÇÂh¢À¨Ý@in»Ž2J‰4N9H0Bc;8jF hÝ^ŽGãxo›¢(T5 ÎpôF¹¶ï®_ª¡,7ɈbÀB0”Ó0 H,f¤i,.á§µ F…·2(0v à”Ãa$ñÿÉB„@ЋĆ1„™Æð” uïÁ /x[5DC6‘V™à`¯:ŒT–ÍŒ6X$’¹ëÖ˜f!bL)Þ#ªª´šOŽ”ê[Óf<À)kódÒõ[Êqž%ËU¼Ù;X ƒRªOG3Û;*`tnhˉ IDAT5ãÙ”;ÊPZ̬Rˆ(¯‚ÌcJ ö¡Gdl겪vùx‚‘&4³>r%3çj­\š¥š¾÷‰¤„±¾ö„#†h0ĈÔEƒ!-4¸í*‘p„X€-p!ðÈÇœDJlû¶Ì&‚ŠE[=E,¾Iî ííf2ǯ.^,ŽucÏûóQ:W›mœ?xh^†Ýeß»b¼}ïæÐˆ3xˆb¯¯þ§ú|ðñO¯ÝºÆ¼wÿá([Ѐ!:븣£ÁÊ0 ~¨H3„ñÐl1g>"¡1eR °Ú*b8ø¨ê–d<_$'+¨”:Ìɶӽ·Ž’M…ï¼yëw~÷7ý >ºüdN÷?ÿ¹¯zdM€ÃˆØˆ¸îZÊ1KÓà°U;CŒ$I$ð¸/k9O‚GVkO¬@ÔùˆÚ’û]ˆH–ªAêˆRfZë,‰`mÔJçãqUÕ\€,BTò´é«`Q>Ê;µ¢PÉëºEï£ëÁ7“kÏŸ?•3?·ž>9}²ùèK¯}W^ }·lúÿùŸþ/¿óOþΛ×~ayñìððZ1Ÿ˜zËÓÂýoÿ†S.á‰q&BýÚÏow;m«]Ùtš<ÉwÛ]Ó67^R¦]·»háÑbT }‚åºÜž¿öú[OOŸì6åñát\@œœŸ={öÙ‹×_ûüÍ×®…èt£-’DbÈ›z•ge#¡Æ[ 5¹å8ï{嘛fãí¦Lsá”XtN†=ÝGÀAd¹i!wÎø¶2YNÚª_m7/¿úÊùÓóUµºuã`¨ÛǧkYä‡ã½²¬xš¯ÊËË&ãÃàÕÕn}²¸éÂðøÁ%…C¹UØñB¢~ñé“–ÕãeY¾üêÉñÝ/\­êÖXd{¥oÓÝTÞ¾þò_þè³é1·›¡vüdÔçíº²èާ{O—“¢˜L‹åUeÍ@Jeö+¿ýÍßüúoµm3O¼zè¸d8&}¿#:£<©¦FRŠg»Ýåt2&$éÜ@1 >ú¤HUé&d¶NYÇ Ls DÙ”Y %6»Qæ´è»‚оmû4M<ÁÑBìhÛ5ÙÀƒ‡ºÜ_wWõ‹,fÅøbùb”Ì ƒ[ebl”q¡ã4G.WÏÇÓ} ©GäPÀ€à C¹<ºq²Z—b4nå xB$P—g—£ÅCâó^À@€,ÁXãƒHãZ„Q\š¦Êƒ -fÀŠñ±´Œ£ö“’ƒh¬ €b,Ñ9àC=¤|ì}T¦ÍRBHâ#uNaB¼u]·blÂ1#ÂĜєQ ­7Œ¡ÄÈäƒ'Xºœ`ĬŽDq) `zuvyxýØè®\W³ã9Tïj20&¶mp¼ "Bcô,M‰Öª¢„pŒµ‹‚‰Œ1°[]¥É  -¢œ 0Œ#çi_¯=7 %È‘Ê'bÜU‘LüÐ¥Ï>úižh™^>¹Ç@xåÍ/ÿÙÿ^–Ìî_^>{ôðç~ḻò?þøÔ«9:êÿ¿ÿÍ\N§óùtZbB ýä£þÑŸüÞãOWœÈ&«²?ÎØàÌn«Þ¸±xtUsÂòÅrÝlÝÁáÔ+§1ÑúG)q8bÖm% ³Ög ßÕ]ŠI‹|4*çcÀM4!I²Æ9[^îõ«ÕŤXÌOžŸž¾ýÅk}8Lþ›ÿê¿ ÁuM;vÕj’N Ѓª¦Å1ºíwéhA£µM¦MWu+Å&Ñ[_mK9‘œ0г~( ¦1’3bPßTb2E ©FIWÀEY·(k¦dÑhdé©ïÀrãN®EWOñŵ¡jj‹(ÃÕÅ“XÜ0Í&êÂG?ýÉ¿J8 x¿ZÝGÔx{ô³ÿë7Þ½uûä¡üOÿðní¿ûÕßü…7¯ß§SzȤµ ñ~ñç~™¡pãp×t6¸£ã#`YíÚ~³Wœ¬LÙuíÐ[o¾úìüŠ!è€L@çËagÝ›ݸùòwþê_¿rðR’M†Ð_^Ì®í O’é“Ó‡•³{47Á0†QLöŽgOŽØ>Ÿð"£?úðSG¼në)Ï{HE‰(jµyùÎÍJËw_ÿâ{?ýÞµ[Gã¾|qÙÜ<¾ó{¿ÿû£Gû#±<]?[_Mǹں­Ú FU"q¯Üºñî«¿ØØ*'«G«÷¾ñy„ÂÙÙåÞt|tr­ï:‘cí¶ÙÞ¾õÊruiœÞϽµ>võëößüš‘]·"‘¦,mPß^]ÍN¶Ãy¼)›v4š]_m«Y6òÄpœSl%]oþæ/ÿo|ãë‹Å­MuŠ“2A$FQDU·eLPÄÏÏO¯Ý¾#Ô «®+ ÞöM±JcBFóEµ»¤,µ5íj4žD­E’#Ì]æÙ$hƒwv@(b" ŒånGLsa´EØK–·}Gì•&™…¶ÚîFÅ«zƒI¢6jÍ»f !Mø,ÄÎè!D‚‘yíÒ|Þì:Š{̦(‚A- ŸPBŒiS9kê2¥”0k]×,ÇÓùÐ{ç|^0ÕºH(õEÚWDŽJ<ŒLB¯˜€ËnW&y‚Hêlo¼<×}‡ À„†aÂÝÐ ·B°à0ˆ"7´Nr)Ä€9oµí½IšjÝqʘ„8®c€`Þ÷u>ž8 `c#¦6RÚïº$CœÍU³Ã‡À­xBkUF r2­Ë+†$Ûs‚è8!Z{") `³k’œË„ ­µnÙ8hg\,˜@PbVèÁÑÔw ìUIdú”‘v­\T0¢5ó£OßK?_•M Ù¯žÛÏ?žN÷@Ë_~tëùåid]Pa©@Ò÷5%"¯kúÖ[wŸ\<}ýø½t<©vç“âè·þ½¿;´Ë£Å<™æºoólj|ïT7ô–ÀÑö_ÿ§]?`F(D)aélòèÉãL 5ømµÙÍke ôóQº¬ìîÍkCW?|~™q‚— 3çXƒÑ£‰ìzKPh‹1†¡l[Š)!š ¹m7‰,rÆšaÃhæ¨ûÝÁäèþûÿää6=Ü{K©Ú ‡9N¡nû).t]§հe2BOaDC(iä!ÆpÕ ''âü´î¼Aü|o>~Q‹bS•ÅòâÅääîåÅÓÕùããésÓ]<ÿÉŽßûÞ¾’f~ðæ§?ú€Ñ6Ïæ§ëåÙ飷î¼òðüÂEs8>z~|ã(¡øéÙÆôÃ[Ÿ{õýéÉш vúb7Êéld<ÉŦ-¿ðÒ;¯¾õÒ£O>ë±üÏÿ“ÿh:_¸Î¢„9§­üÿñï¾8½ œ¶¦ç#Š–lËêÚbZV:²¸©ë£|¿÷VȳA³Ñhýär>½{÷hUö}ôðË_ze}¹›ÎŽ/.Ì‹"-¼°Ÿ|Êq~ûæ~öa‘$y’1*Î«Ë IÉÓk×n›NQt¦5™,ŸtU¯­Êó ¢§Uu#dÆ(nÚžq½öï1§np2ãMÝrŠ1"Q â04y±£s1ÕK))OœÝ*­F14¦ÖEm6iz0(c•fS„±1-†ÒZˆ¢z!B8:ƒ±>I(†T‹ø1ˆNGHƒÈÒrW' ƒ€ØÁކ°€´×0M“Ä)«¥\ŸIncưÃ(8$S)¼‚E¡´íK¨6}.g!„DBÙ²ªª4™e)òž0Â{½‘áÈÛ…’4Ó±&ùĘژ¨Œz•?¼ñÊn÷¸Wþèèö¶|Ôt~6?^ïî¥?Ü¿ûtõñzï+»üñ?”ôó'‹ìÿè_Þ¾ýJÝ=#]¹Ú­êruxxö®ÇÛz3˜zaX@ÙÑãíc§bÓ¨ë׿»ÕrªÚ.¦ãrhMï aü<~åÝ/*œL‹ùÛ/½±¸>éªN¯œÏöÚ®s–k³ ûßþùïÿÅþ¢ï!¸î«»×NÎWÉ Š¬CšÈ)ŸžV+‡”Œ=†½µPÊù\È„QŒu~œ–»Ö{3eÛÛc!•ôMí)GLJUo»íÐH(˶ÀµƒqªãžžÜ<ü/ÿ‹ÿ8 rWo2J]D;¨A›|^|òé:×fé­®Ú®ÊUcÇ×røbUE.¬îººqÞoV¶+çL©îâÙÆ ”I‡{úéêüîÁt0ò±Æ˜[“Q@FQïÀÙ¦zûî­¦Ùôyès!ªjQEBÚRy‚¦8ĬvY1²Jï”GøT °ÒêÖõýÛ7oV¾þòõGîý£ønœèfˆ0"ÉlÕ¬7ÛÑtÿÁ?øûºn;åƒ@P9BÉàÕ­ƒƒ««ŠæHД£¤3MëéùôhB!ÿö~ðsï|Þ¸Ü\&óô«ï½÷½?ù·éx4/ÖËç‡ûûú©<ßc‡ÓãÿèƒÅÍýœñ‰œ­O¯ê«Ÿçk{‡‹ÇŸ<¸ÿüEžó庋eñäxsÕ©¨s*ß~ímÈÜŸûß¼yûÍýë¹ ø;ßùίþÚ7V篾òöGŸýõ³ç›ÛÇG›ò|½­´ ƒîòŒ³8º÷ìÑñÉþ¯¼–04JTä×öö•:𦾺qp}SÕbä)NagÏïC.þú»ß“ãÙ—~þ‹¡ŽX‚@Ùò“‹&nî¾öry14äÙäöâåAœG•åE½;8:Y]œÌXÂt? DÎÜ€”éDʶëíõã[8וּš`¬G11I#€FWä.Š•sž`D)G0ÕªCd x p¡Ó­+òqo›àår3šG,Yo¯êfÙձȋ‹å“qzôé'ŸÝ¾XŸ6bÚs5²¼ºý²´†^n®F# 4È2Öë¹Ü®æ{Sè®ÞÝ9š‡-›zTÀ¶²Ž‹yÒw½õàx>ãî;çwþ^Qð UÓ`‚‘4‰È»ªåã Y ¢e õF*êzëœËò%ÄZCwÖ !$MS¥{³¶¸7@Ó W™ÈTB€ I6À8–{ž~¼8ØØ)…Ð;ˆChWÖèýƒëWë- .ËSèQ7ìDšïÖÍ8É‚µM…£“Å$ÔÖ«b2­ÊV‘ˆáŒ$ cä;?h5Îe×xÌIð*€±V5"`lOy†¡©¶O“ä&ˆá™Ü,/1ÂÙdTÖ»4c⺮çlÌ3Q^>ŸÎïh7 íVŠœÊT« N87ºa43Þ«8“Ðíåy:š"º²ÊF€ «[Î9$ «‡b<6~«+ïHOÁXå5F !B„!о)ÓL’µÍv: ƒÀ­u×5I6¡@i0å°fýbïø¨ªà7’æ5Î1¼H²kOÎNsB²üÚÕ½{³5írÇëHÿôãÇ‹ÅþÒl›³ÕñIHakóìñCKù½Ož“®m1ºËZ?¢\¦À¸;K%Xuà¸@Ñ]6»åW¾ðÅ'_4¦:žî¯Ë¦³Õ¨È´r]×<뜾{ý†éÍùzÕF€uøÜK¯ÿíßúÆ[_üÊö´¥s:’Hµc˜Ž2Ýk%ÆŒQðáýüäýÿúƒ6½Þí Ä w<Ÿí®"DcÊ;h&¦³úëf“©ñˆXËD† fDèµÚ ŒÖhH£GG롵vÕn”fVE‘"ɹéƒ6"ß5]åÌálŸ¿i†£½Éo}åo}áß+fE>*†ºÛ›%J«ZùBfÁú§ÿÙÿõ?–;ùøÙ=ÉÇ›RS &Ë«6K@–¥WËaœSÇ=ªÄh"Zov—5 `4ÎÚMCSF1‡`Ê´kf ÌrµvˆS.¼jF“bïl}1Jxï±W5g #I­¶9׉©Ÿ@ÔîÚÚ€ &ƒµ#Á²„Ïô/íëwï|ùѽ¿ôÖÁ/¼÷K»MU{G¥TÂR£4üíßþ»]SŽ'‹³ÍvÄðb:SÁ.7ë§\‚ZÙëÓŃË'óÅœtÐ2zuööKo—U¹j··nÚÐ Qäz´7Ÿåõ?ÿþ¿½¶¿¢@Œ€úë?ÿ«‡íV:pë•›LŽ€&ëíù;×ÚÚ ¾sº~ò¢ÐOI:98Tß9>Y]µ‘¢ë×Nc›í:ÉFÈÁrho^?Y_.A’kP.IxU˜¡àIIi0±^eEÚî¦@¤ÜƒCjmŠbdœZ_ìöN0F^¥{!8$CæµS¶Ï‹T7.âà|\öCƒC 0ÁQØ9Í·åJkkZœRüø'ïG)^|üL.2C#ÝÆï~öÇR óm9œwZÚň¦BVm°ÑpÁ†º¹ýò ñé“'OG#!döül)8ší·}ÿ•_¼ó÷~ãwO!õ(pm{LAÔÐÁ@9 h„¼*'ùÂùÈØìjDe˜Ö4j<¢0p‚5î|6Ûë†î|"æ1(¬ï*L&”‰Õúñ¬X@ PºvéÞ$¸!Xáp®¡(‰9Õ@O²IöèÓ‡“ÅQ>ù¡ÂAûºÎš²¿º|týæmB@S·"M…¤ÛËã#祛ùÞ±ŽÖöŒ¨˜Í†ªò#!Àу x-’I×l„d0Šà´”#€…J0,‚04ZÊbp;F ÈEÇ‘¸¨D=ôŒ$ÀûÈ!4§Ô ²Qt Fè<Ñ‚½±G =EEßõ;BD€Ž@ív=I1ÁìêìtÿäP÷N#7I2g U5Ë ¡ÕƒKo¢GšFZ«ê`º×5­E(†`w°O.¦Å´\Ú‡ç?xãÎ/=~ü™G ðûßÿvžg“ÉÞO?ø> éd>ÿ“?û£ÃCùôù ™ïõ/žkD:·óÙ|û|xõõ»‹£b¨Â®îÆ“øèÁi]ƒhÚmÛ-&SUÄ)؃"éíPÌ‹‹e“H˜É"x¯|‡öÞ™Æt¤AKÓƒµuÏ1é9žìgL~zyuäo¾rû—é7çײƒ£kgÎç7&Áï=bÑËcêe,-×›î}ðâþgÞ{~±yFQ:èÞø@4À1žRm# i"Gœ”YõÛ€ñ¨¨;Ýy½—ŒŒíZ« £¤U>Zì©r$.m|]×È%@k1!a-ˆ16ª¡˜Ξ\U,€D’MÙþ»¿ñÍøþ‘²jZLBvh²<Ñ– ]-¹Ú¬ÿ»ÿá¿?[¯¬‚ΫQškA°QŽ™‡>‚w ä¬X—%Oxt Â(¤ŒÁ sÁûÁ B´mÃ}(E6BšË²÷Øí[i.G9g ÖH’h#LØ %…Ljc„!@"å9&Ú›¿ùÕ¿õö{o%væüË_z{2^(5#`®/³ÉÌ{‚oÞ|3DÏ$µÚí¦:Õeß-ÚÆ¦Iºl7Gû‹ÍZ—}gµ›‹¦·m?d”¯nßùàÑÓl’È@©}üàƒ;7nÈ•íúÚFE¦[×µC$úõ;¯<{¼šìÑËËMÓ견FÑùýy!Òâý~ôµ÷¾pµ^®Ëv:ͲB>xötÿXÿ­oÿèË_|{»zzú¢º}ç%)äûßÿþh>XTVÝ\$n""{‹ÅhѸæ•WnUõCT5àôéùEÀPPš£¦ïêfúìat0£éÁñ±µýl¶¸8=5.ܼóª·¦{òÑäÉý{ùtC躚 að.ୠƶÉ(iëÁ»:‘#Ñô%¦@¢†F$EµÙ²<ÕÊ®·õñÑá`…³=A(:Ìd|ì«3<'›eŸ“èW‘0|ñây–M…¢¾îÓ” ‘¦éˆR”b^LƵÅk7ï¼üò jÈ[ï|áÎçF{¯¾s÷ùÙÓû÷ïMFÓ²kû^¿v÷¥]³mª –HÙ·†v¹9»¸X¾ûÅwŸ\º”OÕ(I“±J™Þ"!ŒZkl1žwí†Pêp~`a@–˳ébF_•iž`½qÊHpN$ƨo-K%¨Ý¶P"žäöãXÒöÊ€ `GÊ *ze³Î‚A=(I)eTÛ°˜$u«Ô )#£Œó£ýË«UŒÀh§ŒÉ®:c•SVGHú®?˜•µíWR†AÔGoEè@ ‘a Kd¢µ1Æþúo|P|xýøð蘓0(å=ëÚ5D„âÔ €Ã¿ð‹ïôµiºæä`±Ým•Qƒéf×6}Säbh†Á9½Ì|¾`ÌK&Ï—ËÛ7÷{‡>{øá|1?>¹vúâ´SæääÚP7뮓bl†êæÍ“‡OÏ’” "²$?_žõs?·¼¼hUm<ï»'8:1hûðÅÃ;ׯ6kÎà4º¾Ô4uev ˜'_z÷­?ú“?ŸÎø+/¿3Ýø~×od6í!Ô‡‡çËý½b<EÎH2|îÆ[õÑ_]VeWY1áøÙÓ+à¡»Oï?øþûå\õ“Ÿ|24øäxñö›ïÓ©vÝé“Ód:;¹~¹¨ûå$ßú ëªÉF{V÷uÕ$ã¹îv‚€®©#"Éxþèãööö¥çÏ åÊÛhƒà™Fàéã‡y1A,íê–%)²Ýj)’”Qd{XV·•S*›ç:úó§³ý)$Ü ­E¬nÎS™Içb¹ÛŒ'“h@×LD! $ ÏæN{{tÊgÇIžåjDŠ IDAT6v€‹óGZéÆšº¶2“U]ÝÚ»Õ;_ªC`pÎ¥‡„ËçÆbî«Ë­ƒT¤ªóÛ7^?¸~bMw²³okk-ÆIDЪ!VV›½½Ãè € ÌB 1M嬂 1ÝÖK!g)¥r»"Yh;¸¨„,Î7§<Í1 Û²)ëöðäh½´r“ÙÁr¹ÊÇ3=ôý`9ÇõÕš&jz)1"ˆ 42ktv0sM£•ŽqìvM…1äR"¥›ò˜ˆA¹;w÷ß|÷KOî2[9ç1&"eð`<Û?]-ÿïÿçÿLP¾T‹ˆBÌÐÞY‹ŒõyÊ­FÆ{B)†Øƒ9ÞtF]?>¬ëN{_$éл"܆H$¢ê‡Lˆ"M1&Úûy’©¨­qŒëR3„fc‰±¬A J FÁFŒ&ÐÚ1 ÍgGwŽŽç‹ñ¨zÆ$‚„¥2AÀ‡G7¤d áõn·7oKÅeš'ɃYÂ"‚qe[¾u÷nU·YZ<~rÎF2¨b8;_]›ä‡‹ä_çýDðãã=êüÇï/ަMÓæžÜß?<ñÑ#”‹"å‹ñÞ“Õ DñÅÙêõ×Þ8]ŸIÂ¥”‚ `Ðõ;¯ΗÏ_|õ«¿þɃ¿šík“ðø‡ü§wn¿´mÎÎWW_~ï«úo¾Å¢L&ÙÇŸ~´¹~óîéÕ™R»èüåÕå‹ÕEÓê²ìn~þËï={òàÖõWŽ/×›gÏÎO^¡=à4?9>¼~ó˜&tµ¹ô.(ÕïíÏ8¦‘A·û‹gJm! bˆK½ÃŒ¸%›¡ô$|l´•´W­!lÔ-p„¡¬k–FûÉä‘”FÄ%GÐÓˆ›m?™IpÝ·&*É ék³M– ïH¤1º.ã#ˆ3ˆ8@Ä:•ä9"$@¼Y_MÆ#L)B$BhJ)ŠØ;¼ ׎O?ºøÙƒYºÒ¯™`«u9‹¬˲F.Š‚Zà!Z͘g‚J&‘2b6Mùdtxãå×óiâ­×Æ)ka(RBt°a¨×õÀSiܰÿDûjÖí< ÃüöÕ×úêî{Ÿ}*ÊI’¢lÉ#Å)cGgœ8ñŒ{Bn’‹\ÅÍdFã(Å¢HJ‘(+ Aý œ¶OÙgׯ®oÕw½=úÏ“5¢6Nxtd­Y-ÏIä W7+ Ù²ª0Àf5çe9¥Cg¨1…Ä!g9t(D=®ŸÇ1c41R*ÛÐ PÜ aš7l¸>;?Ã8£˜øP6çûcÞtiUí ƒ(Ë2mÄôlÒë€5²•[B‘À`§¬jç•×K;Þø,à¢B`ìuª#2/äšó¶H“M„ Ð*£‡ÆEÉ€75$pmmS¨N)}‚AÝV”R4i/ÕÒ”Õ$H°°03ˆ€ì`)óñÆÞÑáq4HKYžœ,+›jÕÏfõê·?8;_ž~öö{÷nþé¼*þê¯úÅ­OïÝ?ùÑk¯Þyí§|~ó“¿ýÕ›ïÝ~óç¯V«Ùâ(ÿøã_ݹóå,/Êùjqÿþäìät6õD§D]Uˆ¢$ ¦Å"À¨BͪÅÐI¤*ËAM£ž¡qÚŸ—‹B¨qwÆAë¢È§ÌŸç3 LÅu˷ǃåª^ߊwàx2ÙÜØ©Û†bÌ¥iªºÓš‘Àh9ÜÕ]£¬”J#’,˜Ï› ôʆïolw‚—­ÚZËʺ®:$¦®ä`”Ìr#D«¦óAHI†ÛáSÏ=g´ŒÃ¤mj©xÇ;Œ|p6¡8Åa×Jå[oý¼·1~pt…ª„ÁR@ ÑÄi¤k ìRÇ$@hÓÐÇDë#d,Ax„ž®ý^'éª,â(ôÓ|µêRÕ‚0¢Pp蔃ŽT¼ÙZëÕ²6ÆPJœ”ýA»Ÿ Ü¥dìííïˆFçç(&¦–ªãùíOnNæ QY`•ÔRÃÈcÂtó0„ØcB­¥Ð È«ÊGžvV´ƒÊX!eÝT~èåÅr}<ÒX§ÓÌ×Ê*Å!Â7Ö:Š)r@Zãy^×ȶÈ`ä€C nº$fN»¶«#?0Z®e£9Ÿ?õâ•ÍlGuÍhcÃZS••ùÇÇÇ^?rÊ)Þâ—_þjY5&.€‹eµ¿³xøàèÁ׿þõÉäb¢œ¾rñÂÁá¡"h±Zƽp{¼ÍEÑÔïãeÞ¾óÞ§_½ö¬…ðäø|r>yöús³ãcHýÓÉ’xñ¥íõÙ|Îë:ŠéåkÏüô½¿í´0L’¸¨*Ÿ4ôfËÙ¥ÝýÇùìÆ…ÑKÏ„ÝÝ ‚àÅ—~³§P£µñöÉ“ƒþÍþè“›ÿÜþ+µhÏO34"W¬jÏKk^"©úiv4ŸíôÆãt è|ù„áÔûL©üîgS JgéËÏ®o.\Ü„/&‹^’åEµwa/À~§5a4‹zóÉ9†b4Ú;}ò$ d9s‘0#X&I/_M|?AÈ2â+­¨O´V½µ dáb’o]Xc„”Ë ‡ª”sÔvU9̆Ès²k¤tاŒ0Õ )'åÚúFžŸG,0Ú"ÏC)£Ó$–¼q(è8"z>¢ãuÈR-ÂЬMí{)¯jB£¨rõÉäöíÏî¨ñ¥j=Ïë±@jq4î¯m´ ­ ã ²’‹®×K'Å¢7H²(†d.ïo?ûò7;¾€"‰+”ÔÙ€a GŒë¢¸g¥ÅŒµªJ`âÇáªY€Ž 7GÔi% ¤Yon\1¶«»E ‚ €Ní¨G´n=µE‘ŸÆbeÏëǾßðÒ9L( ,B;€qÜ?:y8nQ/¨Ûe⇲i½ ðXx>™ìnï4 WÆP‚†£QµjÅc!:?ËDÝAHýtØTU„ØAÝY/Œ»¦ÃÌ8c1âØ\PJVÕ¹³MMŽ 0Ð#189}Ћ64\P ᵨ&lÆ[|pïîbÕ„qøëwßÔÜóýŸ´ËæÞäø¯½õÓ7ߘÎ>ùÛ¿÷£WÿöÖ?ùùkŸôÁ'¯¾÷ƒ^ÿìµ×QóÿÕëï|üA9_<ølrçñ¢úî?¼Øï¿ûÙmÍzÒ76ÐÌg”äùœbÔ*=ö2`´Ô–8‚Ó`>Íq–h ;Ù(#£ AJÛ¢Ãø,_umÓ*E:_•QÌæ«\ 4Ï—Òl T#8‡ ó˜ŸøÑ¼Y&Ø÷úŠtãñN?I¦Ë)¯šU-ÑPÃ(Óë™TjYçBÝ¢ÀÇÍ#ÿèôlÔïõëÞúrgs#@¾RÁÖ‡AY4²Ècˆ‡,=ÊH`|vï™$ê_¹z‰Ë²)Ë N”°gOfAŒ³Á )JGAj?¸u°,øõ§ŸŸŸM´¶”²NqLÀÙ¬^ôûqÌ¥õ†ÉhØWµUëEL)†Œ @tí¼\ÒÌ8Ñ¥m'ˆî®¦“q’€IJG&UŹ(k¾¹‘ÌÏ›£Åì¿þ¿uãú7—Ë©úÆ@L@%Å¢$ Ça$ ñ£WF±äZx>kj>NSŸ!eugL'¹1Ê:RG0Á–8 0BJê$ˆóšSLÔAiÕÅIHôGÖÑuY§©±%W˜Qšˆ[ÞõÓ`¼X­üˆ!‡ÔŒ"à0Á@ rÎp© ƒ¹’Ïî^[^мsa7_ÎA8æÍÊ`3{m+5¦øâÕ§ûÑ _.0ô-Ú:ç^Īåpä(ðl¹lʦ ˜?Jâe™órõÔµýÙr2ˆÃÇG“ë—/GI/NÒÃ'._¾RJ{rv‚, Ã(KÃÃÃGk;³röÝo~ë½O>U­ pÉyH‰%º˜V£^òx:Ùß¿´¿·£þâ˃g¯nÍj뀻¸;¾spOßo„Á|ýå—n?z8+kÃÙ²âØ@ÆW‚«“Y¾·¾¬±´ÜžŸ,Å£Û“Ó‡+-\¾äu±üη¾SÔ‹N´M‡ë[ À‚b¹4Zìï]•¶±@3̈‡¹Y4š.Ž"ϼ$/W º ò€C¼. õ¬1i¶M)¸ "g´-ËÜA³½½Q”+à,DAlŒpN¶«2Î"l×ÖÎT]«õëz ÄÁÐÃéü8 Ó `cèü¢š‡>%ØsPwJÅéZàÑ6FA‚;<Õ)‹![fLè§¥é”@xQpëÝNN+!U5 £²©ãáVÝrÎÅ8‰ †5P†ã¼^ISú½8öO¦Œz¼í’,½ñ §G§a¾×Ö{8ðæ(ˆ(Ù1ìùaйƒ{^èÇy1Ã^FÄG8€êª6Œóü\Ôr¼¹½XL0ô ó)³H°àUâÕMS)ƒ 5q”6¼Æ>á]E£³éI/Ž ¡¨;íü8!Øê¢Éò$‹e¹ÐV®mn®ª)cØ®W% ¦’Wga4†ÄYl°(PeõQQL¶wvó¹‚Cj‰2Öô²4¯ ˆ€ñîܾÝÛñœòZÍŸTŸ–GÍû·Þ)ñ¸*Û¿ü‹?K÷ƒ¿yõG?û«·Þýå½»G?ûù÷ßÿüóO>üüãO¾,òãŸÿäùébyzÜp9;>œ^L¹ã²(ò¢EXë¾ç-šv=¥ƒ4+j‘†ƒ0q¦…È[ñYyAºáæ˜×B‰Î ƒ †`Ï[. ç4aàº<$„w*ŽÃAäÍÊšè! ¤æM·½9\–µçÑíñZ¹â”"¡ÑA­x/ͺÊDiÊ ÆQŠÊÖçh@!ÚáA“7-€y‹Ú&çЂJvg“"¶nË$Ie×)+«ŠËN÷ât£7:™ž#J4æ '#â15¢¼¶u±“ÄôÅg^)f ålP¡PíZ/i¸–†Iè´|ñkW_y勳s š^oT–¥û €,¡XÐÔfÈcÁdrtçÁ—º´òÏ‹ cD›…¬jeáµ [ùã\”rÖt~äçK²¬—qÑQ %g\øY`!0 SÂt[Tð"JF¢k¬uõü˜d1ÓT`„]ÙÛ|x>í÷¢‹£ =š­mGІyI8:>=­õ µ±Ò¶7?<˜Ì¦ÚH!Ð.Ë"%U-ÀUÌ9Ã(n¹ÐF „vAÄAÀ ®$&ÈÍ<ßÊŽ † 9k RÎ2hd§¬“Ú1Š@§L´¶U#˜„ƒ¸­¶Ri«´Á„ZeFpIè¨oôW®\ôF,×÷¯˜ª³ªñBX‰ea -6¦Â¯¼ðrÍ›8ôW«*J#ë ²`YÔ˜ Aº±3².ªâ+Ï¿²ZÍõ«™¾þÔ¶2P|>;üö·¾ƒzÿÓ› ƒµÁ(Y öýž†jsп÷øh<'ÉöÎúÖÑùq½šonïyé¬=^ÌÇ£žµ¼hš«—.ï=¾÷­»•êÑ“#FÙúÚö,_¾øõß|ó?í¸~êÚ~æ÷ï?¼{ÿô̇îd±ð°\ÌFkPº¢ÊUƒ×{ÃÀóç«b8È K¶w·äÄûú+_ÛÚ[ßõwHo¼ô´5Ú‹‚[½ÏPïÚ³ßzã€bÙþÕýªÌÖÆ¶aè ]§#6"©ŠÙp¼Àa‹¥j(Å„x«å„Rº¶¹_äGA@(aÔ“ÐùÀ‚0KêUkœˆâ4 @8`a(;^Û9ŸFQÚï»n%«.Ž˜4ħeµˆ²P6¹Ã(èÇ>%Z68€ZpÜ[_äâ>sÖƒ.&sR +A«eS¯Lãî~qrrZ•†;ƒLW{aŒƒÈ)úýQ£¹–<Žçºmm§,õ(Q?yòh¸Ö#åÅÜpXÁÖèh™Oeo79;;jd}²üÄZ|ûÉ{w·n~÷þã³ÅG¯ýäƒG‡ñ`öùÇ_þ/ü¿e^ôWõÚ÷¾÷«³Õÿó_=xðYQüä{û£¿û˰§þü‡ï=ypaãìasïÞ½$‰DáMæ§»ÛãÓGy×q/J ±]#b/*Ê"K{ÆŸ"©2Àó|.dæ¡ºÓ 3;–¤¢RySAèu¥Œ£€·‚9ðd6Å€ kÇIÀ¥YrÜ‹EyÛD!•ÂZi’Øo:³(ótu…1JnmnÖ•je3+ ` óM/I¥èŒÓQµM[wYÜi)„$tBSê;mJ.º®ÙÅËU'5ÇÈ%^§d¸Ø2 rçñ£^/K¬¥*jÉ¥ìE)#ÐX/Ÿ««×vúaê·Éh‡žŸõðöŵÑÅÉñýí­(¢³¶îê2‰¢¦ã¡ïCŒŒ¨i¸oõÇýÀ ‘ó´mÒÁF±lÃx4š=YÖ2‡¶CB/³týí·o}û[ߪåéÙ¤°Ô<µ·ßuM’x—6¶î?™fK"ʤÐÖmY¶mL¡äÖ:õ= ­3Êa` FŒºÎg‚ćÊõÓþx”r­,ÀVi­uù‹Å’"à©Ö¼lkƒ„¨3â·çÅ8‚£8!ÄÖz'k œs(ŸÌßúø­rY8µ®d°060„B!V·]"kt®—Z@¡š,Iuëò:ù•@+%P~Dˆ³ÒèˆÑZY=JFkŒ!"Ðh SP ‡0F]'­†A@eS²4ü˜açKn¾ùÊ‹ašnn]ЪPŽ×µÆ` €ÆYê¬Ã_yùq¨U< ™OYgDèyMSGarí¹KWw.|pëîWo<3›æŽxNþ«?ü§‘O>ýÀ ÐÛÜn«ü­_ÿêÆÚ¦±œLãˆèZ÷FÙQ~²ÙßÚ¿xmµxØ‹’;÷×kG'gÀª­7Ö‡³E-% 3Œq­šùùò+Ï\»sô2ð“/ïA _yù«Ùüå±°˲­†ýµéÙb<uula•$ñËO¿¸ZÍv÷žYëã »—·/ìKS_¾°kˆ¹rñJçŽ_úö$#5žƒ¸Þ_ÛüäîæÅxq2÷üä·¿ý­?ûOzëã[/¾|ÃÇ`J²P´Õ`pUY½8;Ȳ‹Rt„‚ªlz½Œ¤Z¥´ØRš*U Ñœ"ÏtMÎh_»2 {šÛùê(K‡ ûE}μ$ ˜rÂÖWÓÇŸFËz6™=ÚZ¿ ¯ÎâxcÎQìDç–«I^,{ÃÁñÉÙÝ÷½|öñ§†àû÷>9~¼šäG«.û—ïZtçðæÑÝ#Ÿ²N4WBò¦-«%ߺ°_Ì›ÿøï8—qÈŒÅCK\YòË»;s`\–&ÀÁ1ðÒÁˆ&ɺŸÈÎ«È *­[É÷wv¿òü‹Ú”>€C˜9« –šH\ ÙŽ7/æó#ŒRX˜6‰ü04Å4 Bi].‰OB^à9#ƒuÛ°È'W«åh}lÿ!Û2‰G¢ái/ó¦Í†Ã®,¤q?ŠXT”D}¡âVpàô "¬ë F ”€bÙÌ7¶6›ÕÄ"|þøI]Ûvs3;ºW/?{ÿàÝož~pëïeãÿð'ïç‡~|çç?þüɽÏn¾yëÝ÷ÏŽ}qûË/Þ~ã£Ý;¾üøóåò¯+ãÌY‹ yëÍ7Š|‰)Ãi%,bj ‚²¦Z8褴JI!~Ùr€(RDhÃ1ÆXg!´i>>:†@ˆ—«VpÑu²ã’2GIÓ”ˆ™¦MÛÁqÞuN¶•Bya¤…ñ„TÉŒhîgI×vW®¿pýÆ• UHcD¡V´8„Q‡]ÒIƒ°rÒá^o ;(¥ƒ„-‹p–ç{Û[󼚗‡‚ˆÇG!W°­µ0¡ÿÆ«/?û&­hõ—_ܾ~ýú“ÓùöæÖ¢®yS_ߺ¼¨*‹ &ôÒöú­[wF½lÉW é°îVF˜ÈY, »5”]p²*ƒašé¬Î?¿}g­?ÞÝØ(xáùr†”›æU2ÚnþÛ/;LÀÞÆîÚÖ@Êš„Z JáÖÆÚG_ÜBd½»îž=:?®>úìö½ÓO¦÷ø'Ÿa÷éû_œLçE=ùçÿÅ¿:9{Tæ'Ëe÷Îío¼ðB@ßGƒáPtròèðÂÕ+|Õ€¡‡<Š=êÕ¶3Ü8P@–³sB@¡µFËÎ}‡%4 vMÁO.n_>¯žØ ² ä•ÎjѾ÷äc/“¼$ø‘ôÝ?( ñ³7_ýèÝÏ_{ç5N'ßÿ¿_ÿÙÏ~QçÍï|úwÿƒn¾ýÑ÷òöO˃ïý_o|öåÕäñ›?ÿäo¼ÙVó÷~ýñ/ßúÕïý£ß ýq0 …Ž ×ã­ùt–¬áÇw=:<3N®¤ûq«yäÅwô©ƒôt:Â`äùTtõª¬v××gE¾hÛ,öw·¯“û0Œb YÝq«:¤îŒ5FD¨u€! 1ÄÕeဆ€zA\ÌfašˆNx>…7M&>±¤©JBe «|Žc(Œ¡ ÓHr—³tìõãÙäÉxw€L×OÂao’]ÚÛ»:·ÎîímœLæóæßxïý³yþ³_¾£y÷ðèøæÍ~ø×ß{0_ñ|ñþäÿ8š}ùéÁ¯ß{ýÖÏO?ÍNî3˜½ûÞ¯Ýÿx~zr÷îCÚùbqõò3O>±Îä¹ Z›Z{„v 0ìµ5§¡—¯ò [Û÷<1œollž* âC`J¾×m8ZÊRɳ"¤­@,ô¥è:!5Æ„¸ ðOgÃ,È«2ŽbÚª‚»­AYuí*ߨ Φ Ð*ËÂŪÀÄšBl×½¢j´ƒ¡G=GKÞZ$¥„„Š·êë˲Ýèm ¨æ ÷ œÖ¹0óÃNq#5£IÛ5ˆPé„Ú‰Œ#jè¬ ¹4N–E™DG3FÜå§.­êêhòdckìx²X.YP·B`Ê()…D@‚Oâ€Ôï¤~êÚN×¶~–n\ØùìÖ-?ñ¶·6‘—RB¯_¿z6Yö‡Y?M™Ïˆïk¡!‚£0®…Ø=÷ôS›ã®iÖÖ7)c­C¢áƒáˆùX+ kÚÚ0¬µNco2_ÜøÅF åNmv·ÖFÚua@«ÓµÁ¦Q®­’0˦«™Y͵Oe˜t'!tÛ[>Äó² £žìšFumÕa„-rñ€5ÒH-T 8D ¦=®Äz½¢­u IDAT/rüþûRä÷òI¾¾±Fv2TL1 Â4ªËÕk¯¾®`'ŒÅRXvmMc($:)´¤ˆA{ãÀ:€$÷óùÔC8 bãlÑÖ˜`Þi„ ub“,¨ªù`0®òR·Õ`ˆ´Ó!f>õ¤ívF#Ù¹²ιЋÃ,$××^~é†iM£—¦}¡¬,¥CÄc^»jýÌHÀÿüÿ ¯Ú4M¤r]׎ãׂCM1…Z@dŽÎžœüæ×ž³ñjUœ/Ï/oì|öÅA-ÊvÎ9•²Ë2_ë¯ìlýä­›/<{¥êøæÖàÓö×w 镽Aòøá¡Vî¤^Þ(€&ÈÂÙIÞ{›{÷î^ÚÝ6[ESìí\jº°(_Vµhöw/^½¾óé­Ï‹²¾´½ùøl³Þª9O{}Ë5HS´ÀmLÓ’~# Þt„ÅuZÈÑ>ƒàyÞüæ?ù?üÆËþŸ~8Íg¡^xá_ÿË;=¬û£~Lƒe™'ƒµ¦à Ô£µµãƒ‡0!£ñ ËáyõÅõ§çà³Ï«‰îc­Ã~xçÎmY®î-®¾x)<=_5!mM%§“âÞÙ, qncïúÏÞþÑþZ¯(™¬ñ”o·pP%ƒäèAN¸vuïðñy˜E­JµˆXl4JSÛj"Új4HëJ`ϫۮÇüoýîwÿèþûÕò¼×‹ Êzð½tq¾ú_ÿÃÿœ1ÿÖÝCo˜\¦÷SƾraÿÛgÖâµ®ÙZZ•õÙtua·¿·³þáû†[iÙˆ¶©þàŸ~ãŸýî¿tÀ‘À3ZMíÆ(2J#±G}„´Š‘Ê=)„ÄD`µl²AÖ‰•3.𲮫ûãAQ¬”0bL¡mzy)z½Ø˜êÁýåÕîlÉ—×/>ÿî{ƼY}qp9ä!ð僇w×ÛVßüüà»ßÞsM¼˜–9yÞãc Ÿ±ãSþ¯\k›çKòØŽŒEI€ò•Øy>Z-9àé—®MŸÌOÏvÆyÞDaÙé£yÀZqÞÎ~y<.Ú† E½µ·Y/¹4•° ç¥[ãa^.xg¨‹0ª“Ðkkž¦þ¬œw4ŽCß_Í ?ñVÒÚ€xm[EQX ­x <Äñˆ[v&KÇ¢"C ^@’€¥W]F!@[Ë(Zµg$K†‹eAˆ.$R²’È*Û"ê{ºó ,¦U^z^ÝÙÍlm’Ï…mÛ0?ò)Y•EÖKQ΢NÀ­è¼¨d뢷D†ÐÀ4ʶ` …ìFº¦ ÔV 6“¬3æâƒwÎÊrUrdt’†Rkx?ËžL.níÍΊlH©O^xþ›‚×ϾðòÁ'_2l~ÿ¿ü½ºvÇ6.îMç¿zçïŒî>¼{(¹Ûß/‹¦(Ú »ýÓZ|ý·žùoþà_ˆÜ®ïl5í !¨xë°iŸES`¹±8Le]Ïšv±xðæëïF^ÿþÑCÝš$ ¶.$^ã8ÊëÕb™Áƒ©K°ÌÌsBXÊœ2šsäª4 %>õ˜ZÉl˜ÌW•o,'6ADà0_Ž£4¤tVÕ²Ó½A¢•ËBÚ˜WÕhd¬÷Ü3ßüï~moÿâéé£áh䓤¨Îti4T‚sÝüéŸüÙÍ[±G ²ÐH€Êe¤½ª®­“>ñ­SQ’”R8­˜¥C T–"Ý)xÔR%¹µÚx¾ã­N’4N‚ŬѺ“H¥ÀÓ¡ï´ÅF ­¾¢È@B‹‚ˆâ°éx@Ñh0¨'ˆÑÀKâgŸ¹ôoü.oyo8ŠâìôèpÐFɰÌçaF<štmůo_$½ZÔÎàQ¯o!0JkèT@¼SË¢ÜÊÖ¤¡ÆT«jI™W”­ø«i®Ö-õZ¤õ>8øâÅk×=èA¤f«E?îoídmÕÕ«0ôï»}ü±¦ëº(޵–‰d§ÓÐ'ßyøh{P”óeþªåq„¦ç5@öÚÎÅói;ÏaȘõîÜyüò³Ï!M•”úØb D4B~ÓêoþÆ7;e’0+óeœÆøø wÏ_Þïê’+{Ù§.\½vé­·Þ[°ø© ûêýgƱŸU¼P¨hªj¶º½‚slÙ÷ÿß¿\¹VÏοÿ½œÌ~ü—¯½óö»gg³¿ûÿ^}íÕ1þÉÿŸ¿xã—§ó{÷?œþì—¯O|vøåÝ/'‹óGOâ×mÝ-ÓÍtÝ(&5 ®+0ØßÞ}pp¬´Ý[_{|²)†1ԢЎ“@çjë![ k:G>î7㛃AšÄ!!¾µïùŒøˆ¨ð{_Þ›ÏÎÆýQµª‹z™16ð¬. ‚ÃÞ0›ùÌ* ÞÈF´ÓùtsmØ´¦­Êa?£uüß~‰ùTT–zt8”EÇŠÃ馅 ÎháEÌ£ììü¤·ÕƒÈ(Û†¡tÜoÍʺyàeN¬½šë³å1ªØÃ⃕awÜ}ô~^f?üÁ÷JõøÁáôŸßüìãŸÞûâÖÍ÷?>8øèþÝOß;)ǧ§g«ÉÄð‚YðèðèÒÅ]Ü¡z¹ bÔLõxëÊúx`ZW)xagcµj´D þèöÝÞ0"Žåuá iPñÚ:÷âö+—.ìô×Ò²¨˜ÇzqàŒ‘@A!aŒ-°Ôó0rgGg³ùl}¼qøà öÈÖö°œå;W÷jÕØ¿|í™^Èîß\µ…[ÙÙEÛ(Ó¥Èoo„"ˆú¾g´UJT ‡¦!SFq)Œ¦Q„KÞhMŒ’ eÁ€D m»ª–* ’Õª {æ·_ùƵ§¯wmáÐ:Eöq¨€aRÂV¼üé/~*¹®[N°Vw•òƒ`¤ê÷B.¥Qˆ2¨4<†€k¸Ö¦I@RÒ$¨ZÎ2Æ9k:aÂ(ÎÕM·9ë¸P!…ÕÎ9 3Yà,$P!;ePFj¾µF[±o\çÇÔpcx©ßO†ý¥US;»œ±V·QØ×Nt\ÅqZW+rõÒN»â­`[[k³ùB#ÔÊnm<ÄÎÕË\²¥ @¥8¯0йèàäà©ë—[‹#üу/ž¾ð,6xVœ²Üçù<ŽÈªÖBºo~ç«¿|ë×…,ð¾ûoß¾÷! ¶0ë§V‹ùêÂúF];YwBÉ‹ëë¼*¹@á¦i××Ö"žÎi 3?¸ð˜ehkcçl’çå’1"¸þÒÎêÝÅÁ“öÒ¶2Ë”Öìom6Åâúå °SU¾BCb/l]Ïb2{XT<ö­•ËÅù_|йB?ÀþÛ7ß¾R|ôéády°*à|Qýëö³ùÙ_üõ›œWÖ²Wßü…•ÕÎx|ÿõ_Œ¼ñôäɃ€^äáŸÿ‡£°çÓprìÖ2ø–.„Geà2Õ‚ýñtV ÒÔã-ZvåÆxl›|w<<šWwîß‹¼R|÷äQÊ|Ràˆç5 ¬l ‹ƒzÚö2¼âc‹)Â(Àx<[οxÛb5ÏtÎJeL—y™0’ ?¯J¡ÍFà4!HÒäiÞ¬ôr÷âÕUÞA ‡Y u¬ENôÒþjU\~Ê8C;WlmouSÕ³,‰¢mW%ý´Y–Ñ0™4LJŸi«ÁúÚ½O¾88öG'ËYì7'ÛÓÙÁùéÑ×n|í¿s›»â•ßyçæÛQêõrxÖÂwâÁÁý¿´w”<9i!“CŸF^_š˜5P¨ªnÄ0é)#ëçK>JSâ ±d<Ü}r~ê|±p dI6_ò(€)AZF°´’Æ%Á¢œ¤Éˆp“öãyYHšvÕÁ%WO.ooNçÖ ƒUQ¬õÓFªQ’Œ9=›ã ŽB^[ùÆ`´8ŸÒh‡}¢($ÎËËfË”z”¢I1#ù^×T—ÈaÇ0uHwjQW\ÊѸß.øÙlæ ŒIˆ=|¹·;YI¥ê¯êv£ßÏÛ®ÒÇ€VÕ¢Ÿ°†7S kh­¸ïÀ¢Ð±OGkáj)·—Ÿ¿êAor6ÛÞÙ«êÖƒlc-,:í<†¡E‹Årœö ³â¼Yì±uÔaKÔÒ‰&æáÁí§žVèóî²Ûv–u{8}8`=†%WÀ(êãÄ×/dI¿gl'aFmS0FóyMRäùž”­EÈóY[6vö¶»¦-Êóõôl¾¨‹ÉÓ×÷>ïË+»Ï}åé://_Çýßëõ·¦‹sl0°( ¾Ô6ô£0öЉæßÿOÿöôð„xät¶Ø Ú8jBÑ“³|s¯W·åôäxQN„dQ>|øîŸ­Ûã €Gû»»Ó£Ó·ló³ê_ý“ÿnï©­ƒ'ç_Þ>0î:-ŠqZÔ" {Ö(a BžSͲhBS¡=J¹adµA ð™øEÓ¤†T…Æ( YŒqôøx:Ö¢®ërƒh,EW)áyÁ²,‡½lµjËVâ \„%žT†,‰’"¯BŸ>÷ÂS[ë;gÇÖ6Æùr1ŸMx·TYv«Ç÷”y {úÙgxÝ9¨Æ¶œæ¼k!²Vv¼k)´uÖŠlìGEYcì|Je–E9èYÈn|f:í$¦H%›ªëxÝ®w•øþßüèwöÚß¼ó7¿xý£›ož?>¼ùɯ&‡~õÖGŽîí÷æ4gËyÛTônÝþ2‹YQº²éüÄ·(«vo r6]lî¬)n´ÖZÙ, ¸h»ÖI®†ÐØVJD©ì´±°jÚ^Ì&‹kæ,˜ä9¥ÀQ¼\6Ûã4 c+€„jUu õ•RªŽwIè+n1rmWQ@c‹¦3Î ¤ù|J°§`Ø @‚­æqBò¶òµÀHm•Å ºZtHéV ¨³ÂÃV)X·  h9…f}4Z,¡;²¼à~fý´)k“é"£a¯Ÿ¶mç”îÒˆáùb! ó0D-'ÀòVŸ ¡9€þîúØǹ$c×ÔÒšÎbŒƒXÆ€Ã( t^J|šJÕÊ“0M’Îè„6!æ¬î%1×eÄAäŒ%¡VwÈŒµý^¯j:æ#? ¡‚EÓ„Œù,ùÊÓ×Ó‘¯K˜d°]^,UîSÜ*Ø áSà³`±,ÓF°ßswînnlùYEY[«läG^0[×!ƒ Є ³ùQYsé,Bä FÃÁÎÞîx8f†žÀhÅ“dÄyC ÃCh•ñ¼X[®´Žüèó»ŸKˆÆëÛÇǧ¼/}õ%£›Ð žzö…ÅbÁ«:xrzÔiÙ ©u{u«¸±Z;뎂Tu"ðÃF c†škH N:0d1cÎç,õ€3Ðun”ØÝÞþÚ 7Ú¶í Ö!jeÛ…Aè0G`Öët›×ÅÑÉt±ši©dc:±$¢žï—Eg­8‹ÐÖYà€6: ­M”ÄùJwYƒNK­åZÖ«$·FÔ×RDž‡1[µœ2 ¡¦ŒRˆ•ÕÆÚÑ F”µöÂNtYlŽ„ã¤HA™ÿÒמ©ËåÞÞ~ìQŸyYê3 u'ÅmUŸÙF(#ðÞÖEåL–EŪö#üÜå Óiy>Ÿ?uuGqܪ.Hà(íß»w/Žýù¼º~yR{¸¨8/Ÿÿʵ‘}~ÿàù7œïo­ß=>Yï¤qÛ{GÇ3?1eóEû¶5‘ߟ¯*Jt]‹ëûóz!h˜ô¢^5m]qIŽÂà|UŽÇ BôÉÑiÙÔ;éh±ªfÅ*!Aët¼¡…;Ÿù þûóïŠz†B³8oæUÙ {>‘ÜtØxí~úðóëûû]-ÏæShdÏßìíù¿óÿŒäÁþ3ûßùÆo‰¯~õòõkûµG_þ‹ßÿçßú­?ú7ÿî˜Ì>üã?ý³ü‘Ä¥Éx¸^õhØï„äQí¤ÒÀy ¡V) YˆXQWq±ŸA-·©ïa‚(ˆ”$¤ ¥‹ª>žNö†[Ž’¼.Ò |ÖÒÐ#^שg¯\)ë¡2‡0q;`‚ZªK—ö–ËÖ êQ‘þª¬š¶Q+³XòÁpm9Q·>ÿ’AÄœÿðäxs˜vž<Þê¥ËyUv`s´ÜD¶2Æk«;ÝA¡´2Иåe³*'‹ã·o¾÷äþѧ_¶”äQ KÒ$ƒ¶U ;ðËwo¨ÓªUP;åÀrV¬7 $³éyô87#io‡AÓ4û[Û¼Zwi”FÌ/ym:™†ÑyQ†Ø¯[ž¦±–|Õh«ñõ Ц©šncÜ/J>ˆúAL‚4£€FÙ(⢱k/(eÝ6aâû˜œŸO/_½ÜVeQ4ÀÚ0`£ñØB1-yH`Ã+J®Z`MÛ˜(ð©G´ÌÜó†ë½ª–ƒAJ *›Ž†þ(ôŒ•R¦µý(1Z¤<ÆšJz!ÆžTÂ÷(…TJeÚUua€…Î{ÔʸÖ*ô“QŸåóÐ'>Åœ[Á»¼,êV¤‘?+WFqU¹\5ˆÝ8ëIд•ÈËÆ#¸®u'àú0[äç]6n„–’`4Þ^«ó hT‹ ô<¿“‚ØA¬´€x„)Óé *Ù€™qQŽÿ’Þc×Öô0°ûrøógŸ|Ï=çæ[E‹b)7EJj©GžØ€ßÀ{dÀðÌxì'è‰e¶-6!ŠÍ‹•‹uëæ“wúó—?ôk²°²)ãé¶]æ²g÷§ûÊZ€ãb:׺{uqþÑOÿŒPr³ººÜ¾Õ£ßtÃbgÇ«´eIb§0äIÒ6ì,¦óYpì6M»â¬ª&S;ZL8Ÿ°ó·—ç×WŸ}ý‰D¹F+…–¥D!84~ô“'y–R”ŠÆ~-X)s¶sÎ}ƒõD ŽD‡ñêê|wq²éVªÞܹûØ»Q”Çäî½³4AÓâÈy5‚ó«—›ÎX¯´àdtë¬+02.Öco½IŒ5Ñ#1pg'GÝ ½s\È,ÍÅ‚ „±¶*O08984}ðчfh0Å“‘"0›È4Æäÿùÿq½³6ɸF&í¬VÆ ‚z‚‡XHn!(Óìp÷í͆@0‘„§I"Õ`cpvýÀ(ë´"„ wvÕL#&Īè£EáˆrÖø¼œaŠ%'µ:=P«TÜ\_Ý™ßÏÊ‚‹„ 6Žàˆ1Ô6ëèC1ëd2‰¡Ãï?}ÏC¸ÝlEÆrœ-W+íL)ª—"Çû‡÷bзÛ䤱ý“û§ß½x»n7OÏQ÷Ïn^¼ÿàôû·¯îW_~óòhg¦¡Aîœî«¡ÿüxôèáÍòŠb°éz­{­ÍñÎa7¨vlKžyWC_w›œ›ºÇÈ·½Ú›L0 ß_ܺÞTÒ¶Ö‹½ÙÍÆL3±DZ&™øá£Îö÷Úv‰hZ³›íVéîÏþÍÏ VÞøÎÁÉá;ï_½šU ÓYyòÞOîΦ‡îÝ{òôäá£Ç]½ú¯ÿ«ÿââü‚@ôòâw™¼ÿñã÷>¼óì³çÿÓÿò¿žîï\_kGgzïA×oö&ÙåªõÁíΪ¦Õ )¥à™÷J¹lŒ&xä­=Þßï; — RÎ+e«¬ ÚÁ5v||zÇëqˆ ãC“'YÀa1Ë26OYu—Š£y¥¬æ8°­æ;àœéõ`óT*qï=þÑÙé)¦¸ŒdÉÁþAYî¾yó*ÑÏ¿øòõÅeÇ,áµrÉ•ñçËÛã“y™MÞž_ I¬!]oNÎön¯¶’ªJ×·óVJÆ1½]mRž¤(}üÁッ3(Ì¥äÄû0Žº(è‹o_|öÅï8ƒÃäºNc™æºÑÍP $hÊ—íõXÁÉzìÆQyVÛÖŒ–°„2ÜwÈhŸK!" È4sÖ†hzãc„覂㣽ÁÅíí Ïy½¼jT€6ôý&e™sÎ0(½S$ÏÞž0€pADþ¶Þ¸è¸Ûívg§$‚÷½­Š0fI*#°ÎRÁcã0rÆ b£7ˆÀi1ñÖŽc¬áH<¾{'Kóëz+8eÏòE3vJ7•Ú;A9lÝÖa¯cUÈ¢<"È©ÇqÔvuÊE딲Ûm7>yðCp³Üi%^×]c‰#.¤¸­7Ôáýjn\ Áî”S`oFJ颬º~ô%ó„c0Ä·«užrA€…ØX‡ƒ¿Ù6kmVL¬u’ïtqVNSÁ”ñ'ûû"ê¹L©0à}ë ‘P»“»OþþÇ2›'ÇÅï?ýjTztžÇ ¨ †^ò„3F©¹ªëу¹ÀtÝ·2Ã3¹ûææâÁ“û»Õ `¨‡öúòæóÏ¿ 4¿¾\YÓîÎ!Dí¨(&óé|’ÏööwWuÏÍdÒ÷ È9ƒ„c ôÞ:ÊRãf»5ýP¦Ùõrã•ÙߎC·xäm?vêîé}„áòæf>«ú·ö÷ß~ÏÆA•ñZuÖA ù0ö6BŠ0Bž"ÂZc1Œ//Ï‹¢À˜:o¹dÚÎY€ã¶WÑcíåÍz´v>¿øÙßSÚsYIRÜÞ®gižL.WŸÿó¯ûæí ʸ€fŒLƒ ëq$ŒJ3šã"ŽÁc@‘HF¨I)v$m×b@së®-‹y™óa1À³ª°1ÀH|ðEQp6}ç|¨²)dŒ28Í*§‘Ê…LR™¦ùØ·œÃ¦³ÚèôN5Ý¿{ôàþAô`‡½ý“õím·]åY·v$œ» !Áøƒž0ƒÓÖBž¥Æš„1’òyöæâÚ:½3›ªèůn/?xu~˜<¿]ìÎTÀco߬–Gó#ŠéóËýÇÞ×ýº^½½z»;™­»aoÞwª3úp1!¿:¿A)šÏæoß\Þ¬¯vˉEpT:—üÎÉé¦nnš-ƒ”⃕¢”&wö¯n× …wOšÞÜðàðl·L'ëíŠ3–’äÿôc–û©Lîò,4ÍëóW×i.>x¼rÀ˜.µïš^/w›æífkd"/Þ¾>8<ºzs9Û›+»þî«o^Þ,ÓD6µ†ÈBÆúFC%OúAõ¶/’Â;y¤£=3\€~'Ë;5*c‹\"ƒÓºÖ˜RÈà0˜´ œÇ¶l¥êN%Ø]¯‡<YÁÖu×v}äQ«øö|©ƒÆA!ØlÖâ¬È°1˺ÎS^$åÙÉ™uMžN)(¹Ùt7Bü›O~½¼½5¦OEê<°°G‘r*7íªà…Rš3P%%FŽOØnµ ”ûêÅ"¯ÖjðÑG§#@ÁƒÙôpv"Rœ•ÅØLÂDÐÔu~}õâÛ×ãB ¥¬ƒ±(Ñr]K™­Ë4Ç”®·[%ÄØ€1-v½i!"ŒàýÅbS7J+!RÁè¤à׈rê¼ÞÔ7»ÕDàœŒêhÚv;+§MÛër&›nˆÎf›®¦„pDcƒwY–jo0¤óéc0çÍhÚnDŽÖ:9>0­Ýt<Œb@ IDATšwö^‚õÎ:Š£À¬7€!Zç TNGg]Àœñ,çœ%¯.Ï1vÞs #a(¥mï°ÈG§Bú@)@€ EÃàŤQmÁòíØ0Fp$Ö‡ˆì,—°«åUÝÔóCJXVȶí¡OÞ“’ÝÔkÉŽ¨ÑŠ^æ©G:CÈ+Þ q$ B(ä1`ˆ`’¯ìhmÆÃDY8¯2 Ã0¨i•[×)åô‰@m;–)NÒ·oo…FgÀqЖQX–9‚x0_:8Û=LŠêòåùÑ{wî ÛºšíÑ”êvPBß´Ëóëu•sˆ­êd²H˜73,%ÇpÎFë`†€PBd»6õ6¡Œ`JiŒP"ƒY^aËùþ}ü.p„ x÷Àpžz38ÍR|þå¿4›uˆHp^ðtU×£Õ „‰·@@0J 0VÆå)5ÞZÞ{úðŸ|ùÍ÷ÊâLðÅþn×öW·× ÆŒ¦«º“ü_9ÞíìÆ òT Ê9ãgÇÇUZM³…ÝÎbÇG$š$IU”uÝu½ÎÓŒ ptx€0Ý™íäùdZîx¯£y1ÓÆyç0–ÁB¦ ß?}B@Á #>Äm;&²ÄÞô—¯ßÜîeû‘ØËåîܞܿ\mH$–£ªD±ï/ÞL’2•H³g¯^¾ÿðÉ u îÅÛ· c’R­Âõò 3LËÜ[o´7ÐmP€Û~äÀϲŒ`$eÙnŒ²€BÌ(´AÑ3Ö÷õÑhr¦‘,[}ÿto³ªŸ¿>/«ÜGä<mTÄÚƒºkRÆ!lZi‚ùó‹ë¿þ·ûÎÃÇ‹ÅÑ|2 òIÉXzS¿ýꫯߜ¯NV] (¶}g5ÁaêR.#€·›kY;ôÆ mÓRNw&£rJÛ^íÝlÖ€’?ý“?>¼s¬ú&‘E7ôœDðåíêíÕ³ç¯Þº Ûˆ´rˆz±5Cˆ ¤­&VfÎq)BÄóIæ@„$¿^ל¥.ãìÍí¦ÈD;ØqèbÁ5J‡BE½×¦ó&²èL_oûi!sËÕ&MK NJÖ+½[d %Ák„{”$”ƒ¡ïŒœF`°„âÀ8á(¹]o™dÁŠ•êóœÇµ×Û±K°ÐÎcJA•³Už#`Ÿ_œs„8GÆZ±”qÛÔcˆcA0îOSˆ÷8Æ8I‹ËÕ:Æ@¼n60o|š F GÁ©÷ŽRåi?v«íB„ZÖËhd¤ ð(Ídžña\pW›ngV$’¯›1ã<8«µ1ÎgBj­ Ê[ÁqÁY_æ4ä½5F9cMor™(5"ŠaĽ·X 1“¢Þ6.Fà!§xÆ$ozµ°÷ñÏ~½æ,›Ìfjè>ûìw׫[­Åt>É‚‹Êj€"„!DX¢nû½Éqµ›¯C`M}5¨íÑâÏÞ|óì«Owvï/ûõ7ß|Þ/ÇÑŒ9DÁ‡¸˜ÏDZqNGCöΓ¤taLæN˦† !íšmž«e+S~t¸W¯凣ƒCoqmWwïÞj›æ¹Èè囿Ó/?M8_mÛIÎgEµj{ãL*€óÁË(µ'CB e©Ö#‚ÉÁî¼kû*+Š\‚(£¢¾ï]toý£‡ùéñÝÅαw!F1fLDï a@54ÿðþ›õ¦¬vªÙTén0‘B)ŠB%Döžè‚˜ ªiõäGý¸ýîÍ[@Œ±éT)™ä¢ëgto>CJŽ÷½CÇÇ‹ûwGæÉŸ¾? £œ ãІ؛ÛzQì]¼¹m;=É$$(Mx½­…HïžÜÛÛß·C8M‰(éPG8ƒPzoÇaÀï¼ûhÔ΃HˆP£N3~»ZKš—UÙ´íåõêþÓåMÝ+UJ‘±d]×óIâ1•šR|±º>œf«Òüó¯Ÿ}øÁ;ŒÄ›ÛÛº¿õæ¢ì†^¤Ò!8d«›-b”%<§iÝ×A˜1:F‚£œ9€~üñ_ÚÖT%'Øè)‡ˆ´1ÆûQà¼àhU·ÞyB1„0V2ùîÃû÷÷`î=8£”w]›f‰må¯~óÏ‚3Âèl&ˆd´6Ì#z½mž Ê·u ±7ÝàTzx{~]÷ã£{g/þðýj[¿¹¼¸^®1ˆ‚òv!„•«õ2Mó®nWµ~ïíÎENû ‚ž‰JÛ.:ˆ1ÈGï%O"°óE-¼]^Nç ÉÓ®¹Ló"¥“¼‡' ÀÍõ`æúÕ›årUä v}{³w0:!P,›a¼XvMãƒNy¢F qôÞùµQ$ÄÞ‡$y‚( ‘ië’„3B co8"ãŒZ¹fè¨àiÆ2.ì”5Å‘Q°!ÜÔ½Ñ@ˆ´í•±&tÿþ³½3âQ¾—¿÷ÃwÕÙÝý̳ìTîî/(eYž<ÙnÛùl*h~~}Û´M…“ͦv~ÈI¶|»”“ªšo–}¾WÜyøûO>;¸{,Yj¶v1)ƒZùi™‚6M)µ½ÿO!€¬ÎXšF &! µ1Îh¯0•ÚªÑ5“©C=€&Í‹t"vvJ™ÖtÖ+Fóßòy[·‰ &€›M!yñæ"„`0Ö,Šl’gƒ«*"uÀìM&Ö˜I&­u?™¬·æÙ›ËqÔÁGâ^9Ý)J™‚ÇNÛs´º½Ý;8ÒÚ¨f€È{ë"”“fÕÂ?¸?/Ë„¯»Õ8º^iˆ夔œ`î•QÖ+m|p:êwèúå8<9~=c„MÊrpVr!m·›¢(«;ŽîÿÙ_þù»?»n:ÝKäÞ,ŸMËY Q›ey= /Woæû“nlGë(”Ûí&)X¹;í:cM€€ýú÷Ÿ°™ ÎGœF!™'C?4Ëng¾À(hÓá“Ó“¢RN©nw¾—EÓÖ{³„nP½SÖ[;˜ž@Y/ÿèÇôí«×Ëåí4­ö¿ùö;kL" =ªÝÙÎß}ɳJ²<„pq{Qf•Ó¾ïûŒÉ*“:£ý$É:=™ÜÔCo¬nº0;æ2Óz|yñ‡W/¯AÀŸ}óìù·Ÿüá«W:˜³'ó{O¬¯n–E:]®^žÜ{L1ZWWÏ7‚/Þ|a}˜”{ô§xö|F;Ú÷?xg6çc?ôzu|çtÔ˜Ú»Ñi8êQwÞ(ö?ùóÝj5jïÒTH.®Ö‚1A ,)ßv}žeE¶p1vcoÿxÝ,ënœÕ^mDþ_DZF²!On6[DÀ =ACg•‚뛺´ÞŽ=§lo–ýì%àÁñÉÅÍ-AÈoM´Î"”¥Kž¸)$ ¡Ú;o©³®Ö›?þ£ùŒ²Rnœ5Ú0žyçë¶{{uóé—Ÿ¥œ £A7ºË8¦ †ØØ R!s9“¤é«ë‹Išöz|y~^–iW+Ni’Hâ³>ý`~XmW[Â%¡Ð+GhZëþË/¾üôó/m@}×aHŒÚŽ.RJ|Žäõv§Y¾i×˦Ëd¡…€Rº`ÓbÒ(¬Ã4±X;Lʪ*夨ìè%æ™ÞcB"8lT£ 1xHv°8¹X^[0bì>ûüy–³ýYy»n…8Œ±Ö6ÐèF 1è´I’„'˜0¬{ 0Ú4 £˜d{[å ¥¼ëFí4t›$ÔÈôÆÞn·Úx`ƒ1øH eXÔm !4&¦Œµ]"°>b B6jã‘r4Œf1Ï•v¶syÂ|€`Bp7Z£•1:H÷y|3™Egñ“jvq}˱“$ys³ ífóNkŒ¡ÄÄúä,jµv»Ó¢n†‘Hy¯ˆQÄÁ”BDZ‘™°h3Xï0”!ª„%Þ8ˆœƒ2çùÁ´ì”ã{`¸Ì«dúàô¤šVwœ `$y•hP$7¯¯>ûæ]o‚ —4@â}ØŸW^û"-Óår^M‡ë¶=8ØýèÇ<)vÊì½þ0C‹a|ñæRrìlìÌ€1*yÖŽv:-ß}t–Éüîã3 0” B(Ûnê<§ŒåÞ〔÷fYî]¿uÚ‰¬´nŽcìÇpHÓlSQA¶]ÓæîþB ª5¤ Ö&RVRŠûÁ̧!Ìh”Bz [ÝC@ª,wØÌ³*—Éè<`¯š¦y€¯ÛžMò_üÍ_TÅá¨Ç,K)ZœÊqÐ!àÙbWmì¿ÿßÿ\Ûm „” @õØIÊ…°Þ2‚¼µcF±Qò“Ÿž=xøúå9ÂFX«Æ<ɉ &?xúãÔ/ŽÏvïé0THÆI1™eEjšO8¢,Á~Ô]7nêÛ` —üðÎ!é·ß} ßŸ•¦•§‡ ¦wœ–«a`òŽ®o—iJ9éÚeš&À@üðþãV>œ3PT; lÛ DgÌÞlTÚj!ÜÛßYß® ‡e‘"bS9¹¸¼¨2î=]n®Ž÷çÑÑ1l¬õÔ£Ó³3m] ƒ(Ø^¹¸Ú¬&B¦!º± ÞG‘§Ç³}£væp±£¹^-o®¯KŒqEJ_¾]ƒ]äÓîÕäÃ?ÜÝ›¦Bþöw¿ýó?ÿ‹Q«~èÎ/nêåz¾»—ä¹²–S¸¿;ûýwÏ®®—$ÑýG÷S)ëms÷Þ=­Œ6vº˜¶uAÒ=¤Ø ³Ú¼ýöûï YˆDö}7µSe6z"&ðf½Ý›Î 1êiV´£¦$Æ1ºÅ4]­»TðT¤AÆD Æ)1:PÌ©’ñ½6nQ”×˳ÐyÏ8Ã÷íöv3p*3A.o–‡ó*"B1úàgÓ9縶ãàç¹PÚ!™Ìº±ç˜Þ?»ÿàñSÂñv{I)¼WÌçÿøë_n¯—ÎCãFÁp¯­¸à(RujÈg%r8£Œ¦(‘Qv ùó$kÕPøø§?øÁûïwí „ „…`…”ݶ¡©PÃÅï>ùzPºÊpیɔä4Æ=pÐÚ°˜Zkc}.R­µ h‚%œ¹h0£Î(mÌh,ÂŽ¦½™TY™N Qö¶/D–p6XÕ´&I"y–H¥l×lû¡q66µÙßb!..—e– È´Ò&x £Èc,Õ€ sÚèšV3ÄÂDìfÛB„–›#èò>)z'(.³¬íl?ŽEžù!è³$Ó]Œ 8‡Œ³2ÍŸÜ_oÖ£·;e¡]èµEÀ(oe“uÛLÐ}o%B„‘ÁDå­šH)#T¤Œiï$DAD€C?*ýöúæƒwŸŒƒ¯›^J0ÓjÜ™ç1øae&To6(²Œ±FµQLC@>z­€Þ.`8›v4Æ3W[M`È%?¿é‚c8oz³:a°6ËE€TòùG>=ºsŒ(ʬÈS=*¬Uúö¢ñÝ7›M=ºàœ3NõÊs†EBR‘0F©Lfeå:>~t|x\r:[P¸”§¦ÓWç—E1ùþ|©NSi¬+¤HeZ· Í;ï>.ÎS!r« ºÀ©ÀRô0¤I®G[o×\ò²˜®–7ªïO!ˆwNO¾ûê;­Çã³c§cßë£;w(FÃØi­–—«¥aè,ǰ,  1QÊQã0X\àcJ—Û:K‹A9‡‚`T ½`aN"Ø™M8O›q`ÿôý<¸?`FcLË8gB"¨¹È!¢Ú6Z÷ϾûþÛ—Ï!ADÊ껇3Hßk‰Q§ì¶ï9C‚Q„Q£! gù8¦ï>}§äõÛ›ýÃÝ{ûÇ„$÷ÏNŸž=þöû—ÇÌŸÞÔ4#+fÞZt´˜fû¶9»ÿÂ!šîL•iÏ_]¿¹¼‰>ìï&Uò‡oŸÑˆü8rŠ÷Oú¾wÀœÜ?IJ -&7«7¢<+Ó˜¨æ‡u?ö}G Ë‹üf³Le¶ZÖœ‹i1u.®›õÁlïx÷àÙÅ·ÿåó'Oî¾{³ºù÷ÿ×ÿvDß}÷‡Od)¾øò«—/¾~ÿOþ²«oV·×J›w?þúß|þÅ×(ಘ̦“Ãêh¶·—üòjÉD!3Ð5Ã$ß[nÏ#Š»»ªUÿ÷üODÊÝs&u•Œ¥˜¬WÛèQšäãÐ{€¥›z#i¢l _LUš]ÞœI&)ëÆ@ ûÁnaä® 2‚Hˆ "§ÈÐ.œ4PÞJ_\o'U^åÉj³•yR7]ÛôY•¤Pv혦ÌY p„4Äïøðp÷¬¯ë¢H €Þj c‰RÍË×_ýáÛׯúÙýWø2œYmLŒÓr'úaÌ’bÛ7À‰Ì³,³À ÷T°Ÿÿí_Hg{3™$2I„@‚±ñ”qì¯>ùG Å|T¶¨Ê„ k‚Èd„1eÉý³»”§ g‡'Ó”ê‡Ã£Fˆ`E’TËÛçœäžÊçožÙ^‡hú±åDXçÁs3Äw~ôÃ>4†Ðƈt xçâÍ’¤]Uy|vwg²`•ýèç?’Z®›•#xl;’ðyVuõ ±¸;Ÿ_¾zchˆÄÿæ—¿ùîõ‹7«U[kçÜ$KÁE)¬qÖò|B•HŒµ Éç³ãÝݽ±½•8G˜qŒ¼q29†8â³Ó³^éÑù!ÃbVLoê¥Ö}•e1Ânöç‰àv]ïïÏÿ»ÿö¿ÏÓâíÍ«ÛM; îÃwž ]wu»ºwz†1¸º½z~~¥¡ƒ.æ2{~sU% ±SÚêPHè…h‚c,BˆqS7Ç'‡Ëõrfa2™{˜hÛ%¯7=$l7wަéé½.Îo¿ýìÅ_þ»_”ÓêwŸþjhW…¢8ކaw!rŠ !¢˜c|Ê2ŽSà}ct•M{­sœQb2ã܃1ç”ú`fùd:™`œÇDH„a‚I¨·ÝDð¼(#vU*ËÙ´ÞÖTç¢õ&O©S€a¼Zòé㳄 ‘$”Ò¾í™D˜ £Ãkµ1·›|’äI::;-óÉlâ,yçÝG÷$}øÞéîbn­¢)Ó`ÑîÁ‚2I8º»nû¡70˜›í*á‰v!K²Ùd¾ºÝ,öwÿíßÿçQkçƒsFQ$G£c q<ˆ bí¼£$Sfà’J!‡`LóùFmÌþ;F×™P£‡×ç¯)I_¼y=+³£½Ý‹å5£¼Ì³²šEF¤\ð”'ÞÇãd§‚8«ñ,a­./—yšÌ'ÛViÏNvëõîOÿô¯ß‡äå1 ÁŒ#œJjFsqqµn®Êjáa÷Ë_ý²k&”`­3Á(f½ñ©óIAô!RHöf;#†(ÅâÃ÷>8=;Þ¿yqïþ{IΕYÞ98áŒIJ¦åa4Kø,Ÿ­¶µ>²Ýlº~)DЏ@Ø¥œ_ÜÞX€U§ Œ‹íœ†$˃ Ĭ̛¾/Ë꣟>Id.Ó|2ËR™gÆ Y1a\xgœõøÁÃ{ÐSñÁ| 9¿¾diÌ_ÞlFÞùv»L”œ¼¹>sqñÙ·¿½\Þ>¬-Fbè꺎¦Y4(-“”æœ e³YA²¬«„Aƒè¼ïF3É‹fP˜,¨÷F〃¨r^õ}‹‘Ö]ƒ‘H%µÎˆ5n͉pÖfx|¼¿n;HÀôþáщ¶-ŬÙ*L¡ùíå–di½Yn·›N û{;—››FÕƒ›åzRÐR¦·u§ƒ=\ìMŸ%l´újÙîÎÌí¦µ»óÉáÞñîÑQ ÞBot¤ k«•rIY¼zùêÓÏ?QÆ&²(ej¢Y7@T¹´áF$'M«:e0Ee•m×}墆 èg8F)ɨ ÁÑÑ)Œ±$ür¹å˜`ˆFg|DçWWxµ À误ßÞ¿{ïÅåÕv}[Àbg£¬Ö7wÏö®—ÃíÍM9+µñæ—‚Aàá |–'’¡A¼5–S‚)BåÃÐèèvDE9¿éJ¨ÃCô ¡©²ŽÚj½YnËD¶ƒÆ("„ {à†Ä£€¡¦‚©1pm°"B9AK†¡Í²„°ijˆqˆ0Â0«ò^9.dA©±A:KÒ„QýÉéþ³ËkÉeYŠÕªSÁ¼¥ º,O‡Vgi^L ñ4-8 6“<›OJ°ÖFi‹)&g$KJ)í&²˜WÅ0vB‚ ƒð¯q`)+ÊÐvè‹B~ôä'‹Ùt:7ÖzØÝÛµF[c1aˆ@ã†Õí¥ $Ë’Lf!Æˆí½£SëA§‡‡OŸ*£VMM@è•Aˆíì/5È2 œ¿¹Dœ"êåúû·/Ò”%1;„ðÏ~òÞygÙ¾¥”ÇÇÖêh8$Z èU£ÊÉ x¤°šLÆѽ¼Í’ˆ"O œ yšg9½òÀ  šØÃÅ!£4›š ÇcèF)ÕšÅl*l¥I°Åñ½åbéH§-šLçJÖ˜0Æ™T vþz¿:¿¼É¼„˜c;‰'½!GÙp†~’ižÔû2ŽÒ£Ã»Z? ¢0’ ·Pz^º+ ÂIßu¿úÕïó3ŠºÖÍÇœ\®V>=ãn‹Õ ›c€¥¬0tAiÓc Œ‘[³Ê`‚9Ô¢BGY PJW}£ªmÀˆŸ%eÝ`øÿƒ£›ÍùÕõµõv¿•ªnké1¿ƒz½¾ñ •Æ­Ö[L µº­KŒQÕÔÖ*€PÙõ]Ó9kU¯ÃÈ¿Úï '‹“ƒÅR#ôôËO†Y/JÄ‚(ð™µ`w»ÀæùC\[ÄÑ_ýçÿ¶«êÌ÷¥VÓÉØ9òàÞ³“{‹dÈ»JH#‹r§Œ¢0Ï¢éxvðàN’ãäôôÎÝÍæ6â’p(ûÈÂI^–›$Îóñ`·»î•óœ¦#èã¾+Ç£ƒë«ëÍî{Þf¿Û­‹íí­*”¤£*,Mk­Ä„P »ªñh˜£</†‡½©†Y4´À”»Û0Ì)¥æG8›$Y꺺— `WVh ‰‚P é(„†nU²w—ç›uoµúÈRû½j³()n»ÛjÅÓ°í+¡ô8N%,^½}¿œÏ"7—×··‹¤û¦‹X(„9=\tuß*:˜N>^ÜRìãüújKèU§èö'~zþî2ú›ÍÅë·ïŠý:ðxÛt]_u©÷òÏÿôß\¼úîÅÛÉ`úôñãùx‚}&€3C 㼂È=ÌÓÀG<¿iåwx¥Zí·ûN9Aëmå3 ³ÆH)‹º fŒ ㄜzû²÷c$•ÔÊ„QÐvªj:ÈØXI … |ûÜ3Ôfyn¥mdø‘U(MgTLB²ˆñZtÌ#a@‹Ú ’ˆ@[´}+z¡Ñ(DÎö»ºã ¥qÐv®— $;qïôèÞýSŸ¦ÖØNµN©0*e”ÒÛ‹‹·çA2ÛÜ®vå–/¤ÑûÍG„v„! ‰çþxõq–eu«.7+%‚!³þäë/—G×7—XmMo°Tðáüý›·/ë¶ÛVÝÁ"£´U[ôMšçHƒ4NÚ^Rˆ—ˉ¦­ÒΞ€"ô#4¤(hÛöq”§(mo(ŒXœpc¶8Š)õÈt0–Æ´½°Ò†ÌCȃζ}‹=^ÎÞ¼{“°h:]¡Çý®oë¶O¦Ð‚B4Ruß2ßÓaQWÃÅhì¬Nâ(­9˜/—‹d½¹Å>éÚ6‰S?`UÓbD“,¶}{4m7í¾oGãÐG<ñ’8 žG!€‡ãL#Ø)•å¡Ïˆ Š F¡}ßì£ 4R"äc"ŸI4 çéXöA!Š ¢^šÅt:…Öbaõô(2µªãÀ0µ®ýäî“V´é‡Ç§û}m :;=eT²ŸÓ<ŸLX0NÒh8§ÓÛÍm>Ë'Ãï%ãåäd1f^6œg÷Á&úËòÇ'ùËßm8×¢*…‚Æ€›²XfóŸ<þ4Í8Â$Μîîã®ëZÍ¥íc‘4?^N A<žæÙrºˆó ìxt§‰Ózzx$lƒ´õ_t7 i6~óî›ëó«Á`^”›VHJiÕí9gû¢½Yß i¦÷0£„è pÄ:,TÆxÔÎöÚq*]šNXã²Åm‰0–}o“üêÝ»$šù/Ë’"Tåøwÿg߃ªjÞ¼>‡yßìªÝv‡^QVµPÆX œP¶—Š’a±Ú"%€ª·¾G}Ÿ×MC0d”nêæúþEœ‡°ïólØëš˜e”ÀÚ8Ÿ(P E”ÛÍÍëoßZ¨‡Ù`_+â©a<¸sïñt˜­Ë ygª¾%I/)¤N ‡Àb>M¨«ÅóçÿP”·i:ÚÞ|¤¾Ëӱն釭hê]'Qa‚ÃÀ¯‹¢hgàòãõ¾i•ª.×7RJ)Åt6ó¡• ÐA¨¢ó$3¦ $MF^è€s[ä(¥„ûŒ"n€kåÿòŸSëïËÚaØöº—’ab¤i'•ÖGwï®Ök!5Áx’dE-±Ìó9Mý81Œ¢ÜÃd_V«Uq¸[`Ò™‡gGœøÛªªÛòh2ÎóѦÚ† Y횆f‘Îóx[”€J±s²Wë ‰¬ ¿ýÛ×¾xtïÞë·«Õ¹Qô‡ç/>öìõ‡‹Õújvxòã§_½üá÷›Ë*õvªüôÙã(õ÷Ĭ…‡g77+ãH’S«-€DÀÖóâ÷sÒŠ„@3ö©F*  ”ÊHs—$Y×uy­Ó(œd#¡€‚"Šc#ŒT]š'ÛÛ e$$F+†qž vu%]Ï“\)¤œÄ#A œOŸ~ù'TD C_jfÂÀ¬.k̇ów£0 Ãh/…Q6 <¨ê”‚ºìûãåQ6œµuǨÿÕ¾¾ÞoºÎZk¥ê}?®T4;<;;ëú6N&9GXÝŠ8ötßüê׿ºpvz»ßÏô=ˆ|®òªdã}t¶¸®oû¶K}Ï8¤ DP„ºÕm1ž%Ë¥ní¶.(ñ EZ±TºÕ]€  H¹•ÀXG8µeqÖ;a¡Á„Càª}‘ƒÊ}·ŸæÛr+ƒ×]§Œ>˜NwåZ´Š:VhaZT´µqº-ûˆz{Wc-)¡›ýæêâ&0’„¼Í£OïÖ•ªê3å“ÀYõàÑIùMs{p8:¿¼ŠR/L#ÙëZ4d¥T2 <%º0ZÑAhÒÐA2äy'G³,ˆª¾»ÿìŒXüþÃÇÅdH:8BH>|òðáñ]ÇwsMÏžýøgi¦^úÓ?úªWrU¯îÜ™¿ûî*Nã( «ºwØ[Ìc…ôý§§ãQß÷J™ÕÕÇ8ΉǬÆ‘|”1Œhï’,N'ñäx–eÃa6™N·ëõ [@ö»}ž x̺¶¦ceÕ÷'³{¸mšÒ§ÑnsûÃ/˾EØôBÅ^챚^æƒñƒ‡Ó¹ÐmàgÆaEå»wªúþÝÕÇM×ÍÆ£¢Ø¥¥”Ú€—ë›NØAQŒßœ_Rî!ñ02qÅ4êT×ÉÞiò¦-l #“ª®k:aZŒL̳»g‡Ó1åh[½ÿøñ¶x‡ ÿ»ßýp:Z<}úãl2*ú‹€†ú“ùùýуƒ{Þ¼8|¸&yßt€8BÛËK%ó¦m‚8¼:¿4ÎFù@Ôêßþûç…P[W!k ±R†!ÓÂ"g³¢mDQ ¡®7k„°6šb–.…2ÈYcs¥$ÁÈ÷¸ìÅp<$Én¿‘Æ9‘‡Ju{q b&N˜ÚH§Hê.¤¼bßt#8åô$}?ÜWE mMSw„@qgË'–‹GGaä9g©G„ªi°­(Ö7›(Ì8A›u)”} OGØC‡Ó‘êú‘?¹óàcPkØà¯-Ú¦-Œ“!JÐp,–G‡G'Jì ”àt¤m·;¿x÷âí[ŠáÕõ•ÙmQ“(*ûZˆ®Ë[kŒ3ÐY r¦13R m4°ö¶»ÑU=€`4Ôuå aÔkÚèaÜ+Ýôºk$@ÎJÍ©'´¢ùÌ–Eã$ˆCœVF>Þm«I:´ÈÖM“„¡ùWWWNkʸÖÎ'%RBœ¡!L$¬Õºo{ká¾®Ú¶–ÆF<|óær”²oJߌíå~¥M0|ñöã NÛ®?¿Øx”wFK‘v˜H ¢}QŒÙ¶j0@}­ †ÆB é$žÎòét9LçãcGýjKÄ9Df˜f£tÑé>湇øtIÔ/fCèñÁ$_&b›ÑR’oš,ª,zɳG~ÆéÁòt<·í~±<ÎÆØ¨Åt ™&~Sâ§Éð`qd(Ъ‹’ µÚ… •®ñ(|sñÖhF¤]SuŸÝýäèhù±G‰PýbyÏå €‡•nûº%”ú•ºO“Çö±îÅì蠭ǸÖÊ|4išf_Õ<ŠÃ8¸¾þ™¿/VMÝî¿?ïÏ9øq½ŠXøäácGÝz}ûõW_ß{|GKM)æ>¨ö•ùVvJ)ÈCÓ)ãÕ…a/Mßí=YèU&<…’ýv%Á¸nôÕÕ ¨à(ÏUr¶Î.g˜°M%îÝ9ˆã ã ‹½ÓÙ §#žgãA ÷)òè“Ç‹õz×Ë  r¬þôÙ#h˜qn²Xv­êº6䜆»¢ð}@¨• ƒ¤ªKD´åf½Þ†;}x?ãÞâx9¨“x]]ôq@£|2Cê˜Ç°F~€g“'aÕ6Ø,+ÕÝ¿ÿtß|'#ÙÀ7ï_Mçy”xõÝñÑL+§­E¸º^•e™§³øå‡ª³]ß{Ëø.e-dHYU«åÁtvpTl£éè` :UC„»ÚÅ“ÁO~ôÔ§¾ÊjWîÖA@auÝ´jGeK8 }w~Añ°Û–ëƒi@±~}¾?˜Î¾øô Bîàþ}©´sp2辫ª"Êbéb–?¹÷éh’‰¶—}’À´ ¸o›×ß¿‚õ½RAÌrë²:]‡„wÚOœB†À06i”k+”t 4`”'½œy€º+4G˦ó=o6Œ‹²5À­CÅQÒ! ¬› 2ÎéùÅÚóºë)BœzÛ¢TÖ˜·MW·ûù0gíÊB* ,áQ>t1È(EÎöÂ"L;£¬­Ò„QêèfWzÄãÄó0‚†¥Ä‡Ó“Ó%î²ápøõÏ”‰|±|øÇÿú ßËéxypœ³ŒÆ2å³ïž¿õ~’ªjãþt1ö¸ƒ€ŽFC%öY4ôC¿k‹ÙáÉhÄD×bʧÓ#ò¡ âa6ó¹÷öùª“1[½‡=†{ ƒ£“Ùl$•%Ó …ƈ=#¼—=¢6ò8D¤inOÎŽv»M!¯Ò(ÆŒG _ÔÍåÕ*ˆîùË—ùda¾Ý·»r@ÿúãvt»Þýõ_ÿGÂ;*«ºNBæ3VuͮބÄÿñO~vú`¡¥kûSäq}u©ÈJ£; q§èÛ6OC!{ÑwAìqd ¢Ôáûqß ”ÏÈï~ûÅ® =¾« LÃ4ÍÆœ‚ÙüpŽ‘£År’åãa6˜Œ»¢zøÙ“étI{ôåýƒ{GÿåWÛ5…GÙ¶RCC6»sïñòî|8œ4Õ6H°GFû}Ác 5ØQŒ»ºz×uÝÍî¶iwBtƒá¸ìjL€®¶MceóÁá|>¾{÷Îõõùx¸˜óõzu}}á€ê¤(÷eìdñàᣧu[ˆý0Vm-0Œ{×ëË_ÿîWûªj­•ã§óá®Üõ½’ªifƒmÛõ>¡A\Üì±B 1Çž‚®—½Ö Ó+†!DÀjã0ò(…@C[­„žO²0 ‚¸nw@Ê8&&¼ãé¼íëñ0}ôèîv[[Õ#ˆ0ÁB¨Å& # BP@C‹v6Ìçã1t8‘¥ˆbˆ¥©ÀãÜ|%ÜñÑ1õI׊8Jó<«Ë¦W: ©£žÑB ‡ñ££¾“ûª  •U8OFhb¼ižù>ñÁ¨èÖÎAˆÈÉÑÁ³'Déxrx4U=øáÅ7ÏŸžž|rr|6Jü“éãá0{ôôA@ât”~ùõ—Î.&‹ FòìÞ¬×öôìè?û¥Fǧ‡_>ùy¨Ç…)²8sÒûxõÍ»·ï"<ë³,¢8°HÌ:ÑY«Ò$sÛÇq$D—¢4åë͆2Ä}}u¬òß7 ç$ˆ£tO³8I«â"‘µ¯ïK€q ØíÛ¶s®6—Zô7—ëÝj‹€û÷/®ß`œ)U··É`¦z¤‹y`…A°LæFbÏÇO?yþüû7ë0öªJ@Žg?¼xÝócšýc¥­MYo‡q‚¨'‘ÅÚH­ 'Œà²ê´mg“¼Ø G" Pê¶(˶îg‹1B¨(D”²¦Ú¾ý°âi¤„´I 2ãñÁr’p’hb€NÙOgCѵY¼Àº¹¾‹ÿìÏÿ¤*º®+Gƒ)°â„²‡ 1¢ ¢¸éÚõêÆ£áíÕ!>F~¯ôt>;98TB„qúÑúâFÉâüüªḩ9Œ÷Ú¤š^lË. ”s‘ ÎùõÍMãi`;ãǾí-†ÔÙþâýy’&e»S][ïËwÏ÷EÓ‹!;ȧëÛRØC#q‡±w0™!AÖ“™FùuFª&¤!†LŠ]šŽ=xÜç@ †º¬CP `ël?NÆû¢ÄÆAH ~}þN)Ë=Þwµê­UàŒÚ­¯&ÙL˜ª¬j'QE¢Ú¡@Œîr_„ã´3w›y>Ô½õãЋÂõv7žO´p}#ˆ†“Ñn· &mÛdI2œŽß¼~}[_ÿÑ—¿ú¿ÿƒæÞɃÑr±WR¶p¯®wW_^ÇIøgÿäÏ¿ûÃ7ß¿øÞ§|8ÉªÍÆú·ÿíoâÜ¿>?ãq…JÔºwmWEŸ¥#²ÿëÿO„ˆ¢¶n…F‡“1AŽÃ(fÛýv>˜ŸUåÎAð7d£Õ~¿ÂÐ) Aâ^¶EÛä<#‡Q B…Y‚nº>ϲ‡'g—WWi6ÈÇvÔ£>Ò(¸<¾úèòÃÇÑì àxšæ²Uµ£"èöu-Z9æ"Ù˺í1bJi cÍÑòøîÝe]PâiÛª°Æiêœüæõ7EÓM’ñºÜ]¬·‘O06u]3êWu‹ÊæñÉñAµ)Fñ—$Õn“M¦ÛrSUÛ AþÇÏx„Gã9@¸S"ä¡Ò+%üøáæ¯~õ×q7ÐÆBcâ4°Ö°€ii¬UÀÙb[vÄîÖEY‰$JÚ-˜Ž1qÈÆ£ÃJìÇÙàäì¡]êg¾Ç¤+ò wسÐ0†“ÑìùßÿîÍo0BÒ™ûÌg·m™«À¾yýoþåÿˆi\•pF `˜¦ìt×M¦KÑvô~à­{ÕÑ@ S÷û Œ.?|Ìñb1ijiT•O'ëËUÛnß¼û¶ßµÇ''×û«n?}üh±˜Ý|¸¦NY[×β£åa˜øÓÉBжSý_þœRH½€ãAð~uúþ¾Ùc䆃l9:JÒépœPÊ!J )›áh©…tV ̬T;‡±Qv¿ÞXáí¤J²p1š Šý$YNsX?}ó»ßgƒ‘€1<=X„É ­ö,ƒŒE}/Å«7—”ã0Šdko®WÙlâQºÛm åZKƒ˜%Ê*]ìv“Ùø‡—ß³<þæ÷?ìki‘«ë@§4•DìúŽBWvÝtžß?~˜ Ç©ÒÇO|[{,rbÏ@ -Öµ„Å8<›ù;‡œƒ:†©½ï{çY®‹q(O“¶—¢·œÓˆ%ŒòÃ;'ëÛÕt<ªúþf»ÅìñãÇçWmÝùÁ`>Ì{¥öm;HÃ0 F›}9å½°žç•Å> Š¼Ð në-ròËÏ>}÷þ5¶äð` ˜»Yo‰î=£ø‹7?<}òäëO>ý¿úO¢Ä2eõ_|*ÚªkvÏ/þë¯ÿú»ë—eñûwÎÎ÷ß¼~q>Lg“ñâõÛ·oß¼~õþ…Ä}9K=~¢…ò ­»‚{ÙryB<ðîý‹Õj}½Zé^Þ9y@=JI¦¨êJu4]~X_Õ• 'je(BQè é0†Ú9YúZk§lplê%”Ñ4 ç‹ã«Ë÷“É8g³IlX?ò—I€NÆs@S¯Ü{4Žél'“¡£iŸ3äÅ\ZÓi);GBL›.N}òdÒ úìóG×ëíŸÿù}ùóG­¨“™~ðà1÷bðÝ6WãO8T©íÙóåxf‘œ¤¯ß¼úx±çþA²øü‹Ÿ ‡+º®iÒ$}óò‡ƒÓ{ÃQD6Î`nµéùpv8»üø†‡ç9Ž1°  p-G»j=›ŸAÛHÝóÀSÄ#¶ Zœ.ž~ñŒöøÑ§'G®^”/ÞœW×ýùÍ‹l8m´’a’P’TUŘ‹¼l·ÝkøîÃøþê_ÿ´júó›Ëá$&$å4¼÷èH+áû!á˜@Ë}î1Þ¶m6È)öAaÀ“`œäiœEB›ñrº8ÈM¯‡ƒÑÑáRµÇTômžŽ÷å&eqì'ˆë«MQ¨¶»•Zìª>˶Ò§wÎŒ¶éÉ8¤AåB–(- 0‘Ÿú~h]çq_öºi*yS•+øí^öíþôàx¿Ýw]¹3šjQÅQ~uyõòÛçÏž|±¾½–°?ž=/¢ŸŽæ–ð“ÓÃåጲô³Ÿ~±ì*§Á»§Øá, „ûEñö훪³F[){ È¿þ7ÿJÈJ+&#M½ì u£ Wª—¢|÷þhÞÿäKèÜë×Ï¥A˜}µ9ZÜ‹û¿ýsådHy¹i>œ¯Œ JQ´uÇY\íu×OOžÞ9à”aÌ®7WãéÐç‘CØ—èzuûüõXÌíŸüò/Þ½zI¸÷øÓ/Ö«Bj§Q]÷Ö!ÝõfyÇ‘5¨,›Å|¨•ëEGä”Jö¢ó) Htv¼Ün×÷Îß9=áœ'á4èÉÁÙx¾ðcOÉ~4>µPÓS>')ˤqBòa„(]ïWìHyQÀ4°Î˜a7Å& Ò]ÛA†1-î D¡hº8çÄÑ›› Ͻ÷o.Ëjw²8zóö ÃYøÝÇ«QžÌÒüf»wØþѧ±x: weIÔKýâ›WëíMÛ¢ÅÖÍ~úó?vNú £(õŒ–!ÎÛˋ?<ÿ­ÖÖâch[W̓³cÆÒ†#è1_kƒ¡-ËÀ>J=Ý¡Ú,ˆ€c­è ÁÎ0f†³ín&(´­ BÁ,KÎ÷Ñzù;©£8þòÞ‘uèôéáp0øðñæøñáíͺémà<dñhg½€~”>8½#›ö¶ªŸÏ“QUË““-D#ä0Ì!qšNÆ…u§NÇÓl<›.Œ«—G÷>NÓ,²<˜Œ00‹Ãƒ¾³R¬Â¡×JñþÃëÏfÛËößÿúL“¾Ù½<ÿý®^¿øíåûŒb÷ëoß¾2­|þíË?¼úMYÞžœ~úÍ?|#;°.n==þñç_‹^X«†ÃI×뢹yðࡇH’…FYÄâI6€kf %L’Fm]wˆÒ( ÒëëëÓ»‡Î(ã`:òè€tèæ°)šl0‰˜7Ÿ,†“¡‡i¿U篯.®}ž´]A<GC„Š`Þ‰V[7Í~ûâ¿bLFAv³» (ýÉ_0†£0!˜WM3çFmÂØƒ|uóq4 …£AhÓ¦[,¢·—§£!'¡Ôm1©¥ÆÞ~°FŸžno7A¥€jõû0°c.¤>¤Æ ãÑd2:Ý+›u˜ùOŸ¼[—ûZØVº€HA’>¼}é ”7å­•¦—Â[e݈uqC(m«f»ßC‚ Ivu‰}\—ˆÁùùêóOî}þÙïß]J­~þÇŸåX„8GÖ8?ɰsZ* ÷8~øè$e, xÙµÜó;gËj ‘ÚE¾W÷Úó<£ÛãÅâv×øLGõß\¼—ZNòq[5Ã4¿X_²@ZéÝíꯞ=‹‚àz³NyÌ2Ìö­ð ¦„œÞ¿ÿ»ç¯bŸLœÂFË®“¡ŸG‘_”û›õîéãÇJE]IkãíÌž}íGîýóWÇ˃ÿþ‡ß”ûÛjUb¾Yýº^õFµ‰qÉ€þÏÿê9>=¼X}þ暆ðîÉÙýÇϾùö»ŸýÙO¯¯?:ã’,̳I]W”!ß‹µî–£_ýÇ_¿¿þp0É¿|øg’tŸö8›Ý)Êõ=A–øx}o9l•ÚWÕ×_}f[a!œÑ»¶ï5ˆAòÕ®zúðÞÑ|ÎyÌ8z|ÿÙ ›5¢NB¾Z]ÒÀ÷9*«J8}||ØKx$Xœ§JˆÍÍ9Ï#mM>nwÛ¢¨°a@¬sªÑ0+JÙ÷½2R(W¶mø²SòŸýü«ºntƒñ¨)T/‹ñb ÞÜ®€Oµ,|Ž>^l´³ŸÞ=¸¹.Šº™NR/ˆpÔü‹¿ügDs‘, /.®Âˆ þþ÷¯n·ëÔö…˜.wï,’(â!£Ètõ?z~ߊÛòúwÿýÛ(N(‚Yäï… }o½[µ¥œ2ÜHL€Ñ@R®÷%u”ø”È)eœ.Æ™–¦ aq¾ß¶ÊhÏ |ìoË]˜¤ÂÛÃÙ\ÖѳÇGߟ(¾úê³ç¿ù~u}yÿlIÇJ»®—Ëåä`tôêåw‡g‹{w‡Q ’a:ÜìÊébq¼œ+A}ùd¶œ°‡£_üò –Ñ×ò0}úäxW]ßTï‹vµZ_¿þøþýù‡÷ï_0„oV«ÿò7[4m¹_ÿç¿yþüå»z¿ÿþ¼nU·®¶> "î]mv‹ΰ³}Ù76Òlª«ªÚç1[N§Ï>}öŒû©ç›¦iöu¹\LRž­//&‹Yd¢+²AL!v¥al7ÛŸœÔ¥.‹­ŸBhüï^îëjõþæÝÛçJÛ÷»¾K²Ôitu¾â£À“}§ÔJ Ç£ƒÓÉ(ŸFãÑää‡~¨«º®¯©ñ'£‘0åÓl˜\}ü˜øÐ]Ýi4ò &Ç'é ˜MOêîA¡@;C„¬0ᦅM·÷ÃÀ§AUß2Ï  h™v FK-…lÜ¿ƒH®t?޶ë}’Æ0¸øÛ_}ð‚àÁñÉ»w;??ÿúgES?ûôÎ|~Koyø¬k{c]š†U#…h²,"(²Ê`ꚺöÃÄ8ÕW2d‘]ßZEвx0™×Åiî€}ùüûmÛîûýÇ›=DÎÃt>.ÇKë$£3Z̶›ÛˆGÜóÛ¶›déNÚ4ôã„mŠBŠýâäø7¿ù­(Äx÷YøõO~¾¾(Òa<^,Ö7ׄ ‚ˆq>´ˆê-÷üÀVW7ãé´jšW¢ïD߿۔iúކ~Êcº¾Zïw¥°Û€7·ÍËV²©“8g1’Fï‹‚§º©ë£åk ¨d’.kÙ–×ëd0©ë =›Ïo67ãÉHkt»½HN&‡]]ì÷…¶ÖQ˜FIbˆ êAïTÙŠŸÞÿäúf&øìø“ÃÅ!¢&IÆ]ÛŠv7Ìõæ{†P®…àÅË£À‹zQh#´¥ƒ”w}'µÕV“t»ÝJçÄ®®•tãQnŒ€Ö­»j:ÊL§- –4a­×•’c:IÃÙ"X—û¦í0p°›ííÝ{K ±êÛ×—×1´ #ß¡M[œ.çZÚ¢ëÚ¶?^Î.®nšºó¯…e†`pçÙÍÊíöêþþì!­iÕvoo^Üœ·e¾Z …iç£ÙÀÑêw¿ý]Ý´W7GG]ßh'ÊnwóîüôøƤ—ˆxžsßã›õ-¤öòâUÛéä0þùOþŒyáþæÝÙñ]¡d>Ìf>¬ NñÓ»÷oêÚ8•FÙÅÕÖ÷)„&áAc”v·«—ó‰ƒb·÷"…¡GxïnC¢‘O¿x‚,ÑZŒÆC én½£$M†³üÿ#é¾lÉþŸTçT®º±oßÛ¹_3ofÞ„ÝÙ ]‘2iKb’IØ– °þýd4 ذ ($EYÁ’–K®v9aÓ¼™7óB÷ëÜ·o•«Nàø‡|¿Ÿ_|³½½Ë ˜¯óEžPò Eq’Wñ2Tƒùz¡5“µ$ ®-‹9Ž•ì ?<ô­†iQûù/.^œåeü“ŸžÎFÃùpþüe­çñº¨RäYþ*)çqÙßlęޢb£Ý,K¡µ¶å¥Ê³”+Î-EUJDÐ"I0BB(fYÉ:;¿¾`† ´Hó¨¿Ó}ûÉ[†à²J!Öñ< ›¶µë´5ÒY¾¢Ä[¥Œ`™ÁÑüúf8rÌÍëáe’Vc§äU§Ù%uœµ ‡yRmílbL³2 Z¶exÌ1δ4´­Í.R(Ïs§éºŽE)zðð®«iªÿÿî/1vn„ã7•æ—¯ÎWY =^.;ÞÎæ®¸PËwy^©‘Éx^„åed@JƒçiÒííÍÇuUT($QI‘GÃf»%]Ä hŒ(ç*Ë“0ldå* [£›Å_ÿègÚ﮾zýÚĘYÌ4Qèв¨··VÀ°B²ª˜ç¡ÚÈòµíÚHQ‚ ¡kYqÓ"„⛫I¥êV+(®52L#^e(·IWã´Õ …X½>>=ÉòæjäX&/3Ï vw÷꺪„Dõ§(9¤Ñi!„ Õ¾×·-ƒ¾eç³××Wë8J•,=Ï&âé£b€H u3Ø(âœPL˜›Ä‘i@`­¹Ú²‚åj:]•y±\¯; O2³\/vö°5]›ž³˜/¦×KÎùl£:|kO¤UG~Çc^çRÖ&@Ñf»×%¶È`¿~ü’×Bb*jžå*ðè|>AVÈËÕë_^ 8?ó·:gÊ3)”¼ÚÑ´Z×Jx–ßßëvîsH³áyA d &Ø.ó„Ù´æ²(sF-^Uø'׫¼’%cTk uÑðÂJJt™s¡ÓíÎ&¯EÁÓÐ ?~ïãgG_3jÎãe¯ÙYܬ3Q{6k‡^ž§IÂA€01øæÕq³ÕU•!DÝmØãU¼\oµÌ)ÄÄ&XAŽëû÷nGKƒò^4‹WJèͰiú¬Å‚8®þèÿ·ÿàÁü·_ýä—ÿ~³éiÎ$¾ÉêÒpM«,ó¨©ÈÝÙöõ•ñ‹—G'Çk¥kš•@Ì¢wv.N»í®k;ŽfUdÀ€¾ã;Y¾ÄÔR(ùÿÍ_íðÃ÷Þ{÷Éã|•nïîXlÚ«ÒhsÿŽKÉxvÑìv··ÏÎ^»U‘µ[ŽiØËJ:¦½´!TŒaÏñ£åª³Õì¶6-›2‡z,ŒÊÙÞþVos;‰V«ÝíBdšC†¾yöÍ{O?l·Ûß|óª× Ú½M*( %!Ð6ð:Í!!žm3BÊŠSŒ=Ûª*ºÌÄá“§o;– 4ˆ ¯Ì*fÔ¦@ßo]OsZ››W׋$òmw‘!X!ÔƒÇ{o=|€ˆ¤lìK]!€4FÃ3…©‰X&“vËùø»ß®ÒÔñZÚW2t4~öWÏlªw{»7ã™ÔEÓÛA‡Ð #Æªß w7úiœ{~¸³}KE)ê[ÛÛ«yøeHÕh£³úA‘%J âšUQ‡¶µJÓA«óàÎíÅz¶L“n«‰|òÖãýýƆa;v%2┊ lâáb~ÿñm»;á&êt~^Щi×Óù›£ä??:š/¦ÃëË$)_¿|1ZÍ“q1¾X½|yÊhJ²Šj™¼¨(35ÆRðƒþæ2‘¥¬-ƒ0ÈÞ\l °Â©ÐÄÀ¼Ê€¾É ˆ¹ŒB„@Æ”1p•×Ì&iQˆBx¿X§ª¨5†·;w¼}hÛžé„~h0d ¯/‰k /†uºö‚N¼Ž™É&Ñܲìx™($£¸ja¥jžkF‘ÚÖ(¹yçνî¶xUA ºæ/5ò˜$–auU˜Vfµ:.Æ:Ém+@d­ Òu‰¥ªú[»³›•Vœâ[íU¾DÖ9Ç ofyUô{u%VQ¢!t{Ëd†íñb½³Ù[§Õr1E”„Ž%yZÓ4²Šnc­ ¡MLÏWˬÑ|‘¤ Œ±l4ý×ço¾ýÁ޳úǼœœfX/òšÊ8®”¬üf+K…BÒ²ÌÐ1o&מ廸·ŠR¢+飻w÷v÷[ÍM©+­Ñç?ÿü;?øaž†¨†P à¯ùŸýņPÅe:ØÞ ú¶ãŒ¤âJVŠÃ°œ\ý*Y—­ ©Ä)ižÅœn³M±¥:ôXÛ÷ƒ0HÒxk§Ï0m…áÉÍew³Óko&Iæ6iÃkRjnŽ0r†7Wa;Ð _¼àu¹µµ?_—ÓvØ;zý•h]ˆY<ìmúVc6žA@ŒE%1Ñë8Õ)$T ’Cv©=»™SÐŒ‹X#Yðòü|ôâä!G)&fÛïîvl“aŠmÇ%ç<Îó•íZY´‚˜C)€ò2¶¨1™N“<-x:þd¹ò=?l„v€Á«j<¥ibùÁ›«³*žFÈ ­ zww'K­ËÁæV’Qµ.£õúf=otš³›åd:AÌŒVñbX6«‹ºâÂÀF^äMߦÔ`ÔÛ?Üö;¶ªá`g`¬¤ÈF:× j@.xQ¹fQ®ñ½{ԛϡ?['JKײ™ÁNGÃn+ÔR~Cèb2›ìïíS\ÜÌ’$yçáËá Ðnu,ÓK’[t<ž9&ÁÍ Äºwg5×iJM  Ì^ÆK×£¶íóª\|ï;ß÷{‡o^]ïmïŸÙŽG.ª"/ø†»Ù ?ùô§;í˵]l/SÎ\‡ bÛôz±øèñ·Ã¦Sf O2Iï¿ßi£ÙäÃ>žÍ¢f«ùýï~—×òó_üÍ~ïΣ'ï` j®&;·v\Ï“œçÙ´e¶¿xþu-äAïöÖV¯ÝëÏ&W@7ðC¿ùêÕ‹ÝÃÐiíníÛ¾åópïpc{·Ú«åúƒo}ë*+* ªÖF[AªÈcØÛn®Ïb‹Å2wº(UÕR™Ý*]¤ñz°uj…PBú^Ãàu¶G“™á8º„Óõd–çu^sPòZú–·ˆV¦k7ËYÛ Lƒ­Kñ­ï¼o±bH)-óŠ0Ç´¨t8·7šeU|ýò™æòb8›­NYªÉbñöã'G¯ÏÃù;¿ÿ÷A LfiÄ14UˆŸüèó§o?i„,©¥QÝ{tÇu%u/ bù~ƒ× ¯TQäR𺔦Iv`5½Î2žìßrœÎp5ÔíîÜÍÖËÍ­~™Ä–«zW“qØ¥¦ƒ[Ên7ÍVÈ6Úݾ–U­Ë Õ»¸:?Ÿ\CŠŠ$ý@–âøúòÅÍe’ÿûŸüo^~}z²ø×úï_¼9ƒ¹šŒË¼Laކ×%µ…äõlYP˹-C/p}7]¦ÈqVt¦ÄJ )„Ð…Lf(¤¹ä.3s)|F6%Ï Æ uÅK‹Ú%/• ·Q–éñÕuÇQeYZS XÅÖ —@ì:vÍUQr•í8RÕBI¬1A°Ð ãßùî÷ d,ÖLˆGÇ/·wv¥Ö / ãx穸ŒÒ<‚n/Ö3ö9O0`–ã" ×«E·ßCZ•e ŒAb2»½ÙcSÃtš§1ÆT€\i‚Lƒ:®3]Ì]ϲlSk!F XPhÜ9¼UÁ ˜¨e‡‹t–U|gcû|tÚÛÖo?øx­ºÝ…†22J)Ä$NfZ©¿Ýð8¾}u©•P¬§³ÉðrÿöYW`Œè`s³†ÈD°.$2Ñáþ­ë“Wžë-³òrrzúüô룡FªÊ+Çr·¶·™FÚ<(’2lxžcŠJÚVÀAŽ”aPH˜à© €cEkQ&qÔúqåY.’¼NÒÕýÛouÆ Ùlnœ¼¼þÿþÍOßòA”F/^¿øð÷1Q“á(tC„a^Tû»÷fËU¾Šn¯æ+Š 5,YSjâJTY”uzíéêòújžg¹p»°VýÃïýƒÕ<¹ûèŽRJˆšQ(QƉi»ŽÓ.ËÊ´Ì,["À¬O^¿Y.ÖýÝmÓÅÌÏlô77 ^•}úîoŸ¯[ƒægŸ}åyôÛッsYé À˜åw‚ñèu”ƒÝmϰÖ+ð[ðQ´°Xßó齇{ç'oVѼÈâf°g:Ì`ˆKmXWi´T”Úß<u~sÅ+tкe:ÆÞþ‚Œ(]a˜åy…a´˜/f£u4Ù=xtúây%Kh˜H ©y–ñ²,âžÓ\Œ“íAËë4Z]Qåiæ¶Ã†|dÞÇ€HwúÍV0š-7‰ç†Ûëlø¿úâçy!š=Ÿ(0¾ºîô;³éÔ¡~–N”B9×@É’Ë^{¶N ¤éÛ·{ûw˜…ª”‡a/ÎbØYÙ–›¬â<[R·mYîO>ýÑþ`§×ëMg¢Òñ:z÷[óxüàÞ»µŒ}¯I0ž¯ÇQ Œ³ócË6=Ï=;; Cª¥ÚØìYŽK \™ë9HS¥…”âêèÍÞ½»5´–e¼õÞÓõb\Â\ýÙ?ÏãùÉÅùhx¶Z·w>ùô³Z©Y´ QsÄã«õåx4Ë*I#‹8g˜ ¡(\Ô5W!ÃfHÀe–¸Ä7ˆ^­–µÀ¾eun( ¡r\C×x‘EQ” ‚†&h'Ži§…PJ¶sޤDHK£"Þí´£4‡r-=â, 1EV0›uÛ­áh!¥¤#‚LÓX¯Rd Ôº¨k ¡ÉÔ<źΠłƒÀ£Q”9–¿;ØZ_æíЖ j¡’ªÆŒ!Â@KM(åpôF»{Û}›¡ ,Óéüf0¸e¹TÔYgskME]ÛÌ‹ãëÀïƒ-—7ˆ’n»½Š&¶Õ2)‹£1DFQ¦¶ã`G×í°!*s©ò‚f™f)ƒZº®˜a)%³4²rœfºZy¶;Ÿ/Z­.Âðæjä‡å³áÕÍçŸýr¹ˆË´6 ´LcÒ·Ÿ¼„ €6Ü8®4L˨¥ÄÄúâ‹OÎNnܶ}qqQD+aãË ÍU‘ÔUQ¬E™å‹Åu£f‹´”™T°ÛìB¨U -˯qÊ<ë³O~:ÇqMl,ÖëV˵]jõôñ“WÇoLÇêvûuÅâ¦íˆœ2ˆ%jE0!Ø(ŠRÑélž¼1-†1*ЏÛßNò¼J“Ãۖí¾>>}ÿwþÓ_|ru36)*ªúöáÛí¶/Iªz0ØZ%3ÀBÏѦEçÓµ1D€^- L"Œšz5Y*Aˆ _?ÇÐ*Ê‚bxØÔçqvûþ}ið:•®Ûœ¬.ƒ #³š8C‚Ҩ̳Œs8¾A.Ç‘¥à•K<ÏomßÚeuuuá­o¾zézf‘®¾|q“'÷?Ï·÷0EQgU> ¿m[¦z7Wc?4C×HⲆ€h‡ÙLáêôÍùÝ{·£WUÂʲ,ÐJ²LiE ­KN "&¥’—YÕÛØ´,ÖkïÀÛ¡ëÚ„ Y•ºØ¢U»&’jÍ9Æ;»‡ÝAër2›¯’fô0[%3M„Á2‹,Ëm…­v»õÉW¿F˜ÈTJs!gë…e{H¡$Ї£ÑÇï~¯×Ýhî5‚ãëYgpˆ2y~u¦†q=»éž a³H“ŽL T¢~}t¼³ÝxþâÍåÉœyYÖË×G‡;ð‡à…ü?ÿÅ^½>¶)œÎÒg/>i4»•À{Û;ë$êwû“á¸ÓkÜ>|Ôh5ºC Rƒbg¿É.ê¤.ñõ›ÑöÁ£×¯^Ø®ÓÜh Uò‚8L·»]:Ð@«d>™Ì_½y^e²Õk?ýè-àÉûéÛßùnåq2õšMÕ7_Ón5ÇÓÉd9ðèîõd¬E 1ÚDZ½f]Ô›ív§ëìô-3ð}_'kfSQW~КŒ_i‘²Î§Ç'¯^ Dï>¸7»:óƒMÃÄÛ[»Óñ¨ÙáÝ»½AVDe‘{~ ¸ººÞÜÚ–ggg/?úð7'äufZ” „*£2M×ß}’¯ÒÞapûö]¯Õ†èÕ‹ŸýÍyþÍñe?è?ûåE¯Óðšá|2ÿO_ýX¦ÈÀPh ¤U “µ<;ÏëŠW 0’r,+¤D§ºæ…¸5جk¥8¶\s‘d®ÁÒqRìt;îÆÆ|4 Â5ˆu)•ãÛ²ª½À,Ë?p´0v¶6ÖY$%æu¶Ñîìll §×µÄTáLðñ2j7ü(Ë dpU€\F}ß¼Yäƒ6³jP –u-nï./®ç··&Ëd±œA¦;¨ª\Ô•ïºRІíÆEQŠÚÂLêºTJM±ùêø—’Ë~kóö£ÛŸýãþc&Ke¹ŽV<«l´€™z9›Päjžgi·¿·\mæhHxU-~]Õ•¬y…4H1¤q¬VÌbHÛµLMÛ©snX&Öd5‰¸¨¿9Ÿ.ݾÿðòü¢ªsÉø/?=áyâ9t²šÕŠvÃÐ6Û{‡LŒf¸ÅEe9´®R^å‚—7W£ëë›ñtòì×ÏO._i`ñªÛ¸µ.'`G¥LcðøÑÝ8K³·1èåe¶3ØY×"90é*þ“?ùã,Æ ®jŠ]Ó0*•GUíQ£1¸ÏLa펊 Á ')S¥+ÏoE«ˆ¹–VP#ªë$lt³"ÅDyŽ?·a^e]euÿΣ_ýò_þ‡æÛÍ$Š~ë¿þ;I¶¬«ÚïXË´Ì׋[nóB˜À6[Û›wm[Ö%!˜†PWµYÂË´^;º:=ÁÄ4‰§Ñ2Zÿöoý^— Ït±©x^Ý^”ªªôæÒÑ$Í#ÃD@£‹ÓËùòÚt°Ve•Päß¹¿ëµhµ® DWã+Û¯¯Nkž»Ì#À–’‹œÛV£å@O^½loc„Š,–Úhn/F3dÎáèz¼s°µž­Š25\£ÓÞ<~õ ¶ÝnwKÕæÝx1‹ã 0ô­ñ$úá·ß?½ºVJc„6‚¶mÛAËs=§×Ýô^šd&µ±‰m;¨óB@Å«JA¤´Àî=çÂÐn!µ\ŠnÙ.׉Ã[ƒ8ÍÓ¨Ú0á:O9‚je÷¶+QdY¦ ùûɢ³×ë­;éS#þøÝÇ›­[£Ùp3Ÿm6«(§¦µLËŽoúÎx6ªº4{WãKÊBªaè‹ „Ø/`~ûþÃlýóõÏÜ{òêÍËñ:!Àhúî¬Hƒ°³^Þ”¥úÖûß}þì‹R–óñ Bò/þìÏ~ëû¿õ쫯ÖÉz2gÕª·yçÉ»n®Ï˜é½ÿÁ»Ó›+B2`3èäq<ïl d ÿü_ÿøÁý½Þ|÷ƒw³|QëJaû~œÞL®'ƒíÝ lÊZ9> ü Ê¡FšÅÍÎ>‚Bëš1Û ¼³ëÕªP¨NóUèö£dÞÞð 4™I‹bm30D0àZ—ë݃]ÎeQ'"Ï>xg=Ȥй1œÏ<„ ‰_½z§QÃt~uü’Rª †nÃo;î"ÊܰñÁßùXj±°h»œY¬*2 Û”Ø××W\ÔQ<‰Õùäòþá^]²ÁáùüôøìòÉÓ§îßBÔZú®'¥*k©u­¦ßÀ€ %ñlïð.ƒ„0K©œY ÅU3“8Ø _<û¤50“øÅ‹¿ÎâOÿ·}ùâfk§‰¨Ò§>}qqþæêœp¨JÌ áš@t³X=zxw<[Ì’)Ë,—€ 5‚q\x§ÀaN‘Ô\Té2/š~ç)À6X¥ë×'7Œ`!R.tYÄ6³RQ"‹*Jj]Þ,bßrfñÒ±]ñ8Ya„””š£é 55¨g9BCj1QePÓšs›bhU&ã4a5Ú~Z–‚gÈ6󔯢ià ʌ"'@îmç †‰IPkN(J⊈ZŒB‚ˆ@Y¡Šhåßê¨2ýæç¯>üè[eZ0æT¢¤ŠÖ²r\{9™1Û&æ¯E ´ÒÚ,xŽ0®¯Íe•D Æe‘VR È „Èbnœ'”ú†ib$D¥ ƒ¢.LäeŽ-¹ÝÝËëPJ,Y,§. вúì—?Jk1¾ž&<) ÊrúÛ?üÀ®Á ‚$Ï3êår¬Àº¿¹³\-Úe^º„/‡Ç‹Ù|r5ªÔ*ɪãç_>þènVŽ“HÔD¨j!¥Ú½½utòeRŒ‰Wü_ò¯~üãŸîwúµóźÑt³,%¬Êd§;Þ,û÷­ãoNzÍ Ë·´ª(ò’"UJbÃȳ5.*tÅyROÛ\Ì—s!µç6>ûôË¢@»Iû½ðÿùÓÿûå‹«¶~ôäc@t§Ý¶Hôøh8gЬø8lw…PY:þè{ß_N†ç0,E½ÈÏZ~;Z¯¼;?;ûúç§“õ<×uW&£¿ýwÿA³Ý£r\Ô˜1›03›Ï˪êoíqJ U‰±=_›•ªŽW‘iPƒ:;ƒ-Y"eACÂå"?½<.“‚ZNQg¶øÐ4Ios(=¼9=Ü{’G+…m5§7 `’"ÓYÛM{§ÝŸ §V B·;º)˜zf@°ëfÃÿòË_c‹$QžV©"`Óí 'ó pŒ’ºá› –Óܾ½I±‘¦y§—ÅD ‰GM¥…^ÇÜ l¼·w`Q³–•粢̳²ÞÝÜ@/ãxÐë4Ùte3–—…IÙÕ4ï5¼¢*>~ï£ùl\Ö‹­þ6Ó0C|­¦¿ý[¿«j¾w§ù/þùø»¿ñí kœœ~ñìÙGï¿“FÑ$Ê{›AÅKÇ´Æë©m˜EU›¦¯Sϳ‰á-•‚RéZMïßþÍ£×'»wWÉâøü¬»µÛ €Å¼­~Â8KóÁA^¯ß{òô­w;Fç¿ü ¥öۼüº¾:=>¸½¿XæY=\&#[ø¦môûýÙlqûþ®a¹³é"J`´Êž_}Úq‚Ñôjÿ[ƒ­ÎVçívÆäzÌL{°±3žŒ™Í jË@ IDAT,“‹U4ÂÑÍÕÎá6ÀÑW/Ý–ÍLÖö7„°Šdv;<å{û‡ŠY3Ân¢QÛ Åišj î?J‚°Ù@óivîØ$]•NúÛÝËãáõúÜ5y«Õûù›ÿp¬ ||}1¿øúW7§Ÿ¼x6úÑ'?s˜¹Xg˨RPlî~èÞݼ­€Ö·ŽOf„€f§ãššg¦Ëd „®çM¯nMWWËñ²¨ËÁA[¦úÁ[O÷ïì¦ë”8vVOnÆË8,3‰ÊZÔQºþÞ·¾—$ËVÓ·±W+½\\-&‹F¯]Ôy¶F‹)‚Y·; ŒåYD±O-–$Ënk{:›9>5hprüòf|^rõâÕ±VBI¹ˆk jf’¤È‘VŽãNÖñÃÝF³•ðÜfN+h1Ëb¶ $H×ë~cx9©ë’š†I½²Lq°¥¥ÌÊ‚PášÁ:‰$†°ÆÝލp’ÆaÓ}}|ºÖF«ÇñéåØ0êfؚ΢­ÍöÏ~õ‹'wßo¹®õŸþùŸýÎ?üW_]\ Ïj]žM.ÆÃ\•Ûæ*^6Âîh4mX&$Îó¬¬ǧ`bÉ ®v¶\§m¯ßj…ÌNNÞL®Èi2¯Pòúæ#,d ­ðòôx÷à`6=­æ"‡×“á`ÿžÖéb1X®â£7'ÓåÅ—Ï_L†|wã ÕoºŽ‹‘{³\Xµ[ƒl½‚aâÌŽÓû×ÿÎ# •³­ýþáöþÑë#dosK*¸Š—aØ(ò"ÃÅ$IVk¯í†Í*J’jµß8™Ž*,U» §á÷™¡³$¹u÷^³\ ‡ ÏÍó¨ÙÄñ:M#ŒŒÁáàøÅ „¬²ÉºØÜØ~uòy%HYrÂÄÙ›ó~¯Ÿ£r±œƒ ó:Á–×r‚ЧŒ1ßqÒ$º;¸Ýïö ­w¶¶w ƒ®”EVðÈõZI2ƒ€§qé†Y­ÜÕxTùÝïý7uY4ûûwövn¯ÉâÇõÉ‹¯_ûà FëåÊñ=lÐåd5Ÿïìï&ËÒo§§¯ý^Ã3E‘PF µÓ82M¦«›lÏGÃ+Pa;\.–‹En½ZGeljȺ4 ±»Õ¹œ=bïíîß̦®i–"ßì./¯ “FIºÖx¹•€„˜Ô@H!™Á2üÀËë²m Vª,S۰㜷ۖÏB“ÁvÓ¤ÐÊTæ{¦’ø|8Üh6Â×RÕ¼¬ÝÀtºP£ñrº¿Ñ_,ÖTaÏ´¦"¥¨Tr°e®§E­5&Ü5‚”—9(t!…RK ¤éz¥"«~k»%+‰­c±cu]J©Ll¡g…¬a]sÏmdEá…––@ QÈ „¤…Àp0ÅÚÙllìDÙ4ôz²RµÌ=·Åe ˜€ –E¦¡hº›7ã±:¶å]‡¦C‘$¢ª˜Mƒ®Æ³f¯M™“ÇI^®[­n]J I]UÔ3yU)g– œÜÌMÛL“¥–Ð Z“ùUè¶üÐ6¨uôâ%2èdqCå¢nøN–é·Ÿ3-§®86Ü"/lÓI’¢Ýh¥éz82Ǽ]/V«ùz,]ÌR“áUVRʨm$qµ^­Â¦Í°y>¼jm7FÓ Ô¨Æu²Ž«²fŒðª† )­ BkÉMƒr® ’p!¬‹J !K¥¢†Ð9äX8Y_W´ G2Åg5ñ<è°Õæ¥RÝÙ¿»šÇnÈ0 (”eQ(a©ò­Í³óKj!Ó÷¯ã,B€IÔµP•à„Ð*+•T¶‰LD/KLŒÀ4£IQ`\­³Ú"æ ëEGr!kŒÿŸ$ûj¶õ< Ãüö¯—ÕËîût eŠEI¶D…G%“I”Ìø$3ù¹ËUfrå‹äŠœ‰Ù–)«$,8NÝ}ïµöjßúzy¿·ä"Ïßx˜rK4ʱm „l[Ã@B›F)“š¶µÔ«({÷ÑÁh4LÇûã=­ õi]âZä”x«Û¥¦•oùu£ò67ƒÕ< ‚ÞÙùÚ -ßòóu”Ý>º÷8MrMZYYV—(…4æ”°í&§ Ô®Ë†ËÂ0\© …ëþ`òìÉWátä`•n ê) ÉÕ‹õls麞ÁhÙò8in@&ðòë bÒ{wï¨JaŠ”’²#)y¼mÓüö'}ÜïÞÙß ÆÃNgtìþ¤?îíuM~½ü½üîw>üð¿õ_¼½øÄõM­À2[üãÿîprœ×[’b%Zõ;w=?§”}óÝß° —a+¯K¤ítÞt†a™6uÍ ‡ðRåEË,òî[ßÖ@Ýi¶ª×ß=Ú¿ÎÁѽ?ùã?™]^CoÔ³DMN__åe…‘›$¥RòüfÃ3ÙpÞpÑ2»XچפŠY|›õí¶2±ÁAC€Qó–”7h5Ë¢ïý³ßxçÑ{i2g¦ÝŒãõ5¥.BæbsÓ FB#¡¸’œ@i%Õv=[S>¸÷æòf‘ÌL˨×úo?þ1¥dv‘–%D¬ 1ÞAÁŸ½> G}Ïq…»÷ï¼~ùŒBkçh?J³ë×çRæé\>¿Ø=îb'qÉ,Ö*Qeµ˜âëM¾¿P·E´¼mZÞrÅ©Â(/«~€M'Ûæ¦m?€ 2€îŒ¿3î7¼tü¡ëØB¶ ¯]¯C ,ªÌ AYG[xoÿ°-¥˜Ü MØ–šز°ç™¼ÔQ¶nê–Qc4é>}q9;ë|ýøÞy¥i­àÑÞáë‹_<úïÿÕÿp5;Ý€ïŒݽoºÁø?þçz~”Õ‹ÕÖvLDˆ–*ªŸÏë,7+7 \ßgP^ÏæwçÛßù¡’þtô×ÿáÿ ƒŽíö7Yt_ýñþÕf¶Â–0‘}:_=8ž~ùËÄy”°£É½g/^í}šN¸ªÞý‡=cg÷îñ݃ýGÓGÁ¨û½ßûÍ›Ùi™ÖHŠÑ°Á¦¢…~(¡øøgOÒd“¤QØë¡C-%å LËí0<.ª4K"%(±a•—¾ÛË«ØrÜ,“Ï_ü "ÜíŒ(Ô›ÕŠ;&FÇGw^¼<ñ\s::´l'.n"“Á¨¨RƒØH@Ëu³4§†NÓÍÝ73B—ëówƒÀLB0^¯—7ëÕp0>?»Jˬ(ó¦lQAŒÞ9z/nB–é²Þ}ë@ðºç†×¢¢Å#5PÌ0Ù|yÚuG¥¨NNŸnWõßú iÊ~Ðs,¥³ÝÇ··'÷îÝ+ã:ÚÞЂ4ªE&º¼Ü¦ÕÊë{ÛMÄ‹ÀéLÇÇB´¶ãÛR)åzPx]}ò¤Ø”g7g’´1šRäÕïÓ¼©êl„M«ë¶–6ª•Zí &‚—Û´ l«•cŠ¡¶lH¤LKáXV+ERðÐq 6«„ Ëbжl¡åÈÙ¥ŽzÖ:I'ƒ½w™áôì¢í°Ó)jþàÁèúzÙ›za¶ÓV7­„«eÒù¦Y^œÝ^tìbSÔ²VœË¢¡ce¥ÈÚÊ5ÌÕ:C„L»NYû›4~xoRÄ`<ôî~ùÕ3‹ÒI§ã™æËÙìx¼[6#hZ6M e`ÐÐ ¯6ëéЯ¹H²‚1mVÑ*¡„Фë9ïÞ=uváå4é‚·¨ªªI±î"¦“l 4¸mRÁAÓª¼·mµMçë"B¶õ n±TR Æ³×—×~Ï5qeÉsƒ9iÖð*ÀXG› £8i«RB¹7}-ç)ß.gsê’óÓ«š— ­åÍíöð(xüèí¬Hònvwö»>aÄ’c*¡¦¢ÕËÑ`r~93ˆýï‡*Ò}û¡ÎßµÃQh„,k8è^ÏžíßÛQ¦”Mìw‡«íeUÇ—³s(¨=47›(oÞpaØ úÀ5¼±·ßŸŽvDÛ&ÓpÞè–Ô«ËÂrLÛäñAšTi¶=={¶Yl^ž¿¾ûÎýqt~õ¬»ãjýß?þ˯N^lüêâòý?ÿüu^6Ö•@¢ž‹¬Qm;Ù ^¾¾ÌÐu©n)5°éüzUYÐ 7ÛÂ"ÖÕm.¹„R›ä•0°=ê÷ÆýAà’T]wÈHÈo¸<<ÚOómU63o‘nÊëÅmŽÁà뫯-ˆ×›uš—·«!JhœG1B ö7=þÔîXáÅvÝäÍw¿óÝ<Ž*Û”žž?ïF“ÑtyÈûýÉüñGISÔU^l³ÑΤ­ÊM+Uîïî½x-`½Ž£í"B ÁA%çIš¦EíLËI€:ܙږïuC(D§3” h«ÊLB°±]EÀ”¢†2SáûÇHÊ‚¨•ZAn• :¿ã½:»PFüÀ¿ºž;]biËôÌùvµ¹Ý¼õàÁz³F@7-ÿŸþÇÿùæì„9æó§_¼áY>—¼*S©°j˳Ùí´Û+e -óš(ª Pì™»n€ÀR4ý½‰g…Ôªž|õ‹ï~øƒ¯¾|z¾8ýàð;ß¼û}ç1üð½ߨýfŽ›ÿîOþ\Åú_üùõgü;G½o¼{üÏ¿õ{GwÞ=6ÜT—üñ·öû^·ÓqBëGïFù¦†XCËïõ~Qä–Ô¶e5_mïß9øä“Ÿµ Þ?8Ø™Á ª–šsÓ4—|ýå Ë -SÁ8NV¶­E+…J¶''/ûþ°y‘•UQ3abïïsÏï[f/Ê/]Ó©Em{ pÈlK1 ö‹²ÈÛÒÁ†BÓ‚+ØâÍöºÛëEË…? úF~sµ-¶YT2ÃR;¦¹É’Éh:'mÛt»½ÝÉÝ8ZxN(… %ÅÖ4V6žßYÏçÁ°Y,Öëh½º:sÒ”ɦ9|¸ûì׿¸½Y=z÷½É~Ù–²­ a¸\5}ô·=¿Ã†ºÝ^oº£ï{¢Še[w»Ã¢H˜e¤qòÅ‹gÙf£8›_y†Ã¹\æÉÀu1qYJ(nAÏrÙð~Ç¢ÂX%¥–màv6Û›˜«m°×uš„9†ytº¾l%ãÇ»ûª®ã=xp„jà ݉¿\•ßþà÷ÛºIŠ|ï`ÐÖèt~®Éöf¾m8O›µàâffyævM̳ºhD“·¡å"¢<§Qüÿï5A:ŒŒG­5†afƒ E¡É ìÆ{Þ'–ØÝíö§ËdóêúÙÐíp¡ Õ¨Žr%zŽl@ rßwWÛÜDš0œ Pæ±04ƒZBB¨…cY•†Éádt¼¿Ÿfj<ÒV ·=3Ïŵ¤Tzv>ïzuÃEÓ6]ÏæÙr±ÑTI™—ÌtóªBŠ(QS‚eƒ©i”UÞµ»fhæÅ­hº’%BÌ4oËaÿ(Ï2Ç¢ãé.ÅT" 84©É 8ì}üñÏ·uÜ¡îl¹šÇÉÀéÅU¦Y{ÿÁ›U¼íô*Þ2¡½®AU6•&¸”ž+G½Éôà‘F9 Ïâ{÷÷lÓ,Ëàæxgÿv1O‹øúööÎýûî­ngCÓÑÿôÓ/†ãÞh?üÙÏ>ÃÀ Ltmwîí覎7ÑÝão}÷ý–·D"hÀVp$-„Ð2læZ¢®)5¡I†ëëD´8Ùd_~ñdmÖ›âçO¾zqñ5(Ù~ë¿Ý¿gþîoýΓçóåm•ñ¼Ê0e ¡k†²ë<· _4b–%“Á¨)yVäNØ5ú%¯ºa7^eˆÑÇÇw†A÷l6ß™v³ª!¾ý/þðwÓ$Mw•nŠ(‡X»>º<ŸŒì ”U«52£ØJ«†s~{‘· ¨ër³)´ÖeYÈZ'‰M ÆLºmæé:.¸ÐeifQóþݾßû엿ܬVû;ržh(MÇ‹6«é¤oØÞíì©v²w4»ºèN†„XÙ&.Êh¶Þ,ʲ̓úùŲik!•j¥m:Rl`­•rQ¹){ýáÃÇo(.DËípÐu躂çU[) ‰cëV]àÃã»&B­Ô(“ÒåvÛñ­Á`ØëvŸ¿~i[^S6-¨ò\@ÙŒÇ:ii(£óåù‰e ²n¾õo¼÷­w²$ÉËÂ2¡cöë<ëï GO^|qyuÒí «†{k¸$È‚PÖ5mú6†f™çey\1ÇßÛ¨åC®OOóMõ§ü§ÓÃ;ïÖ눚`ºÛ{pÿ@eíýo> Q¶N{ã fµÓs„Ã$¯‚Óéþmt4 Û æy‘®ST °æE¯7®ÊŒóœƒ2ÿôö‹_ùåË‹Ëã7vÿè÷þè«_}²³»Ûë ÓM,5ß=Ø_o"? ”¬£(\#J’¼N“íñÃ&nMÛDÚÎ#ɰ综,e+:Ãn¼ŒîÜ¿ ‘-,šRe"#pý¢Ü*ÑŽwöV›†xvqÑë:NgG '‹½Ý»&³.nNóŒWeêu¬<ãS¡ÚQ§ÛHöÑ»>¬+ö¼®×w<2Å Z¬ÖƒaPµ’WцVçe£[ ôå«soÚ¼º^=xãÞ¨·wu¶îNóm4ïNús.Oo½;êÎ^\¡LŠ´h5+D®ý`lyÌ´L-‘Ùó«¼0ˆ ÇëÿÍ_ÏV›º­e$W©¨ ÓÞl£F4®í¶¼Â½ýÆ;îÀˆ·†¬¤ÜÚ†º÷Þ~§IÇôz¦IÙÁpW¡æþÑäþƒû‹{]r09.ÔººMSHìOžŸÎno÷öz¿|òúéó¯…lV‹áV Ñf".ßñ¢$µ E±%…Îê)Õ÷}LLÈ"ɇcÏwÖI®¥†Gbk:ìXÄ<«Q Ñ¤Û ¼N ¹ÂH^¡J+žËرñz[Þniž–ŸlVa¿)ù,^ÙžÕ4´¥ãxX£›ÕPË 0+ !€ jÈôü¸. !µÖ`?!ƒ¾ñæÛˆ$K{ÎäÕÓ—†k1F«¼I’͸7yz²4 F8(ó¶;¦Ñr5nÈ÷w⤱,F‰2H€Lf¹VQ&Aßi ò«/ÿØé‹—WÛEºÜ,næ7¶É‚~G$éõòL¡"R6„A;u›'e³ÒÍ««çPÇd–êªv»¦É($q–]\œ¼ùø-LíRÆÔ ×‹HÐ<ÃË“W»{;Yµ™oNs¹ÜÜ=¿øb]Ä@XÉfE<•§òæì:+ã¡i~üìï¾™/¶ÿÛ¿þߥ‘¯N‹ÿã/þÂÀ(Íë$ÉlÛ|þÕÂ2»‡Óï~û„™yÄ$—Ð$m]hdƒ„¾·Þ¬(㪪jU¿üâË¢*³vK¡Ñéöï½yw¯w ‘u}sýý·û{?úͨ\[¾<¹8M·…&¨å­I’ m‚µ¤V¥”žIÝÐÏ«êhg ! Xv{ýõ*Öº½so¯š·ÙÛÞИ­fEYCeíOËdÛ4ßíÆÛµÚsB 1À¶½øÞx2°»VÝ2fzA¯* ,•Ý5°ÖÑzÕ›öš:¦Ä(ë´ÊV”zÌ&M3‚M‡ÕE#Ze«ýÑþêvÕ‚&t‚Qwª ¢!lÃN÷útóË/¾â8° n÷°´¢|ë^¼©š’./«ÅêvoÿÞêfkšÌu,‡u,KQ.–¹À|o0^Î#¿Ó5E;‹nÞùÆ;€c¦¨Éeo4ªmr!èwƒåMܶu]Ç vMÏØækÈqÙ6iµ¾:¿B[-oŠ„s]5m‹´%ecU¤`<œô˲‚F»»R Ç¥mÛvzYUiJ°S×eè9Û­(êÒ1Ž;üÉÏþáñ»oÿÆ·¿Ÿ'1dM·7©ëêüõç;“C­@Ø övŸ=ÿbÏwïÕ¥ ¶Ií~±-íÀB„º~`2‚ɳÂ4ƸL²ûïþ¢`ÛÔ æ²ãšIR»Ô&)òÆ1¬uY/WJp¯Ó[̾m`Æ:®ë„>М Z)@³­WÛWׯãz½Ò¼ÜÌV‹ªj+^{¡s;[ݬ¯) °¤. jvl7JëßMJ™6å°k˧9ŸvÜ0ìnŠÒd”áÀ Œ„$SPíMÆ3‘IöP?èXÀ€FX{–³ÎsJ0#d•n×q8¦R0+r‚U] ÌHÇYÖnÒè¶m‘œšP7Ê7­uQ C×YFIÓ4¡ €›¦ê‡aUðÀs "¨Ë:£ŠB 8ÐLßqÜ®îN&»{»¦é`h®V³bñ IDAT=¡µªŽ¡ÆÔwF;“tœì-gA¿Ûï-`&EæøAg¦í5u /—/_¿øòé:µ7·Àõ;ãî$p{U–þÓÇÿDÍvo÷ YlˆI!TÛæÌfÄ÷x_½º¨tª@ÛÔääæÔ±©ç–g”m7›¸ÉOÏŸGéüÓÏN¤\~ùÕg?ÿìâäæÕþηúüêéGýäåË‹h9;=9ûù—_`§XGñÏ~ñ“Àe¶¨K_=/0næýâ߯.³'¿¼ì EÅ1aÃNw“Dî½ûÍ6ÑêÞ[û&2Ú–;A€ ‘lcÛqÊR‚j6t„,´ ·³+BØåÙE]—¥¼*dÓ$noo(5½ ;}ýb±~ýÅçOŠ Ü,×ã*KKÐÔõ°ÓHEQl{ŽÂØÀÚ‚¶áUQ :} tU7“ÁØõ¼,jï>~ûøð‚òèÑñ«—/òª~óÁdì .÷§÷ Áu]Y,B`Ã!Ôe­”4™!Ž£u‘WO¾z2ŸŸ,£H+¸^o‘a û=»mUV–„È¢jºŽo¤ì{=ŒÑ««ë{:£þ`•.dÂgñ«º¨pkõGçÏ_HmÙ6¬2.8 vÉf¶­ .¡øú˧£Ýårqöêš+i#(YQÔŽé EÃ’–Ik.GÃþd8èx]†ñîþ”±nQo¥ÌwH£ª ÓtWÑ2ðCÛøþ7¥ ‚ ×·©e¹¶¥q dÚá:M XQ× š6ßÛßÍËÆ±q«UU6ï¿ùsU(pµ¹úÓ?úÑO?ûÕZ<{òäÕï|ÿm1d—ËÕ2>£­ùäüt¯… 8OE…ÔžaJ®¹”ã½^V•iRY®±¿³›fñƒ‡ÇŪXm–?ü—?jÓ¬…rz0ÉÓbE»Ç{HCb2)‚ ¡€8uQ5 ïz¢u-UŽí®Ö‰ë;é:b¦#AÛr#Ó0LbT¢:¶'•Ún—žãž¼úZVµ?pß{÷}…µILÓrj¹;EV*q k8:\®.»¾oº¾„•cËåÚpY¿Ó‡X·|ëÃõrk{&#ØÀödwŒnê›`ÐÞÞ.Ï0-×0ì†sæ8Ñf‹ „~öÕ—ƒI×2ì›u^Õë²Jæ· Óxœœ ú}^K­U#êІÞh²7 Ú–¯,CëºN¨añ¶i%2L ÐqziYR›nw­f‹sÇñ:ÝÂpØŸH‘Ù®ãyÝ“çÏv÷÷÷Žã8ÁT,‹ñîÀbtÇê‡áÓÓ¯>z0îY ²¨Ä&ʳö×O¿”­ÈÖ)o•å¸Tc€`¿Ûq©i2fÚv”¦‡Ó¾A`V”‹ÍÀõ…eÓ„–üõ‹§·«¤móÛeZUÜsÙ*ÊlíÔ\UÓT*©[SS `’ÔI\BbdI•v=KQ×í°;ÀVwÍQVä½®=èõ‚ã¦vBÇ0ßzãíÝaQ:è÷[Q.†ª6½áEàÙ·›ˆs5 »—7‹›õʵ˜hE𿶉E‹ƒÀ.y›ä¢z2™ê¼Í«Ü3ݺl5õú~˜ÚµM¡uàw…ä›8„z@Âò²v](µàšš:­8" Z"µVP€·E¼×ßyë½w|Ë3-¢s;LÔÊ0©aB×èÄñÒfÒ1\FIQo<¯OLŠ °˜Sò"솖n¢UÇ7™þñ“ŸEWñâlûàÑÛï~ã;wïw:Þx¿¿¿TfÉdºëƒëë™é™ýÞHÉÖö„ðí|6Ù=ÒP-7Ï›ÝÎþî>P)dTic[FƵÀÔ€Âïw¾~ú,*V···§/_½:}Ñ,PV¶¯Ož,W›ñh|q=ûäÓ¯¨6µàEÑr®—‹›«ËMßñ“"Õ­FLDñFJpñúäåå ¶Ö›‡‡OO^ŽçfÒ4e+ ˲d¶7Mêííì.’t«´ànZÆePÈÚüOÇ%ÏfÛ @xÒ ²”÷¼@I©í0KBqЛìL¦–E7ííc*ߦƒ©‰¨ÕŽ¡^¿>¹M³Ý¦î°; »}—áP¡†£Ó™¬’+L˜çô‹jK •ÊÏožþý§Ÿ¼¾Ò@(("Ô4óº’’›Œ@ Ó<¯4ÔŽí6­º%Ô*·øÃ¿E¤üËû^ÇÜ.f@‰½‡÷Ó,žŒ§ÝNpzrÞ8Ò*—‚ÑýÃ_~yõ*Ê¢õ|…Ü–qUÖV.pèYUÑƄ çzžc…~à LÝ”.ëäõ c[D¨Ð 1æÔEBÁï¾ñn&&*°°TZ‚"QdÕ°ÛyyzU‹v2†us»$…Zm£J´eS·ÓÞt±ÞdUUåõÁÑÝ_=!¤~}û"À¬ô½A7Žù³×Ï_žžïƼ©MÓNs¸¤@VÒ2‰m™  ëåa.la¿oa$V·ùëׯ-Š\:©yþæ{ïZ†y»YPˆ'V‹¥e²Åf±XF½pÔYZEU–˜VçzyÝ ú’× ¨º*ë¼ÑJø®u}ÕRtû¶,3ljK‰jÂ0¯sϧyùoþ¯ÿ@±šx½ûÞ@Ô²RR†½Ñ|qÓ´µo‡Ì@ñz1«R+pvõ|Ð6uóòô©Öġݓù¯Ú!qTìO&7W—†ãD번²¨ßäIU5Ðz½Ùh¨;A§,K¥«{ß]ݬ¶ùºÓÝ©šŽÇL³³…ßwÆÝîÓ×W»;AØ­T¶WyŽ! ˜F`²3Æ4W¤ò-·Ìjæ˜Zk)•aã,‰«Fj&£UÌ;¼·_5Ù ³Ÿfùêör]v¦ÔÀ¡¦Ô-AÐ2úç7¯}Ï ¤ešGMÞš¶‰ ¦Ìæ¸bØÌÒB`únÏ|úé?ìîL j¦:Ùf1ÃH±Z‚ZÕõÎØŸmòš× ßtª¢J ©NnÃѰN›†‹Ñ”—d›d„â¡ÝE+µÒ=¿ïÛF] fÙƒÁ¨LêA¯ß Ãqo8Ÿ¹vWÂöwÛíßß=~°O©WÞé 7힯àæìäU#Åùü’#N¢¼*™A/®f„bÆp™Õ­,5‚‚+F†@I%´2 º·˜h—øP¨4Ï Ö–¹qkÉ{¡]–åÅrÓÑuYѶ«h;u‹´!†ý€`Úԅк­dR”Ì4xÅ1ƚж匘­ß7[`펇ÃQIˆÁE0bÔ5-Rò‚bnãDˆDK)eÐ •’( A]e?ûO?ÖÈ9í?zãÍÑ^¶8³<æzf]oó43 ³ÅÍd<íôŸýê£R–~·nŠx³ B/JÉvÓˆú‹çOÖ7‹õ:KÓ5ôýùzµ¿3MÆXÊ“×/ϯN@‹=§ÏVåÀ ð:Z¯VùŽs||¼ó7÷·3‘&Pãa/h[%ö,Æ H‘QÈ2Z6£{7óeÑuûR´Ûma¸Î&Ž«< ?-rFÂÞo½÷íl™r÷âæÅ¨7þ쳯®f§Ó½ÃÓ«‹ºˆ]¿÷úù¯9äã;þÑÇ~èö{Ó|{3»=‹–9E¬(5èv½¢IЦ(š00µÒZ Ê IhÜs¤”ÝîøÞƒÃŽO F†kåeî;#DEUÄagÈEU—¥ëu©ñ£Ç÷!ÐU#m†Ú¦)+‰0\\­°M 6®ç+B0­CŒ´))BMUÿ³÷¿?_¬â*sÃ%ǯβ§_Ÿb€7×õj“Ô\!J§{Î{߀xÎ`gÿ É­ÐÒ÷})€ª®+Ë 0Å›Íb¾>=»|YK¦[U7¢áØómÌ@šòÉh\ñ†×B±ˆ“UµÐ€R4ù°ç¿ýÖ»ZY÷¯¬[Q¤éáÞñluc˜hÜUJ$‹ëƒÉ2pYijò¢è §Dâ¸LR^‹º)nY j t+46)EPÔ@ˆT¼ØŽ]ËÌèŽÃÀtµÆ†EV·+¨ôtwg9_Bl¡Û4jÞ³jꀢ–‹ j¦Y©ØÛ;ÐRl£¨ëØI^L~ç’ÀÁ®í~}òâòÑáîbõ¦#»ÿÖ[Çq[˺~ñâÅýçH•Zm·Ûì,º(çó9„ÀqœF4¡AO/çžåw b ùÞ·ß›¸kù¬k^]^ßÛ;^Æ‹ËÅ­ïz?ú£Ue&¥ÒP(†ƒi^DHA‡ùžÍÎNN|€i­¢ØDìM5³Ûsã£ý;ËíÜ ¸.xo¶EN´åV4,²Š7yv¼ÊMƒ2øüé'PÃ")Þÿæ{“ñÞryËyy÷Þ#^ð"KGÓþj¹ÄÐÈÒ|­…®åÆ·éål>ìMiKš¼U:}ƒZÓñèüä²ÛݹÓÜ ]Ë&¾B$™"wïß­Û,¯”e3×a¢6²j=ðœÐîS˜˜ÄB¶=K!*ê\h¾ÝlÖšŒøqRN¦Cò(”ŒênőƶMÅÑùÍâøèÈ`F•• µ]oÒ6…–âäÕù"¹>º»K ‹tëyAÇ÷/Ï_'Iº½N—0fèVHX;7¿Y?ûü‹7¿I‰­%Z$³áèxÐía$ÂBU¦E` [..Ï“d³X­lßm«† u­¤PžaVu nm¸ ¹†y½X¼1ùæ÷û»5Þä΃ðøðh:8L‚nßõº^àZ¡~:Nnno„jkU‰¶®òd3+êf«¡šE«ÏŸëìlkÙŠMRªiʶ×ò`:9¿]—5ïu=Ï g·[‚éÁáhdžçQšÛÔZq!@RI^)EZpi§ë7e‹p-› 3«jd‚¼*€&C Â%:-×@:ÇÓ$` ¨p8À YGѺN 3CÏzyu&…!@4¼HŒˆ ‹¼Rx# ìS+9»¾Ê–Ú²Øîî!Ƹ(RßéB)eŽTM…°&·«%bжƒŠ  sÏóKÁ¡'ŸýúäóO¿zü­#ÓDQ•/—¶aæIE‹ÅíâÅÓçÀ«7‹ëËKM•”ÕütqvúúÕ³ϱ]ž_\–I’—YÃùg ,š K;JãW’ÙV˜ P"®Á:M´Ô”J‰É wz=;;=c„žÌg:O“8¹^¬Ëmüæñ@Àv3ÛVÍ|±~p¸ÿòììj¾¨y›'mYå–mŽûƒÅv$LÒJÈÖ³œ,Ëh)¡ý0<{=ì ÷‚À¡Ø¨‹º©+ÃÀ¤°éØmÛRdk¤¡–Zʶñò†PËrÌ »áκœ}öô§>öövnÒ'CvxòêÕ‹W_IÁ¢d³Ú,e&9uÓmeiDµ™ë;Tks»5l!¦’ÃU èZ׈% ¤Û¬ð Z7•È´ØËÓë»o?8::°)s<Q´]Æ–éi%³¤DD~ž´½^ï?ýtvsS ¾-Ë£ÝÃ$I2‰D7äIšWÔ·!J Æ”F«2£ÈœìMïì´¼zvú’Pa@›˜äòæ JeiUV°ÖÁt‰4*…a-™Ôº­yfQ»Ö¼)‹¶–H¤%ÁfM„C0%F£ZifàV(Ó æ{otT•høœ¦ÈmÇS­ªêÌ1½4Þào~ð]ƒ ´¢¨jÛd¶Á¼Ð¼œGŒQ§Û»]Ì0aà'I+UÍE×µWñ†æj¾ü_ÿõÿ²ÝÜ|ôOŸAðÆôÞÓ—/ÆãÑnïÎú†›È–:V'§³·ݳ»œ-»}燿ýà Õ7Ñ"^¯æË«Ñ8Ün²mï÷ðöj£6Lm0CkÔ޳mú}Û³ Aóõb0šØn[@-é¶×é#CHÖ0¨Š h¢w,O4­m7RRk¡˜e* Ä\ÇqZPþÕ_ýx›¬'“o|ðÀ•i…R“ŠHÛÖ¼)ƒÝíz•gùþeÓΠg0Ë÷¼éxÚr5žŒ£] ¯ëôFÏñlÇÓIÛ6Ý^‡ å©ë»Žg'QB ìZŽÖØölÐH× fêF®· ?ô(2x+‹2Íã[­Ù:Ù$i´`Söm|0àšˆ5T»½n_‰FA0šì¶e*ÚÖq„”ªííÍ5±4—ü³>}øè0 äRS;ðÖËëÃ'«¼ì„CAS”°EuÅ^Ÿó2Êã;‡Ç !%£!Æë " †”þò—Ÿ49ï÷ºu•UKˆZÇiáÚF”$J@äPkÑêûG»(ñ`ÿ¸Ô·uÚP¿»ŽÎ³ªõúƒ«³—g7MS__®IžIQ–óUÜ4²’Z>†Ù Õñ]ô†þ VEöØnòuÏZ†W©¶©¹c2„T´h¹IáÁîÎ|=oeÝBB`VÕÀÂ&FUÍã<íø¡M¼Ma„!@&cÃN`’7uh8i^ÈV‚0¯K-$ÂÍm–„aC×sm¸Š7YŽi5B…J]ɄԠ5 Š4T²B L°¬%ŸlUh»ù–×¹þÍï|ïøx‡š-B nkx·3Ù¦ ©ëŽß“ \,/»a¿¥ÔAèÉë¯ãüVèßüŸýâó“·ßyo6[lVk­Ðüb3èUÝ,fkˆ‘hñ³_½h*.Ðdù,JT-Ë­ynÛA±ÈFƒ ”8MÛö‰D²fB¢¦mD©]ßÉËÚÄ̵mßpâ<òÂÀȦx¾¹ÊJá»;J“›1ÖÅRsJ!é :Û¤L²T)íPϲX”ä¨!â½Ñ¨m›(›a‹’¬ã°ÓñƒywºK\¥¥B¢ç†u[=~óÍ0ìUeM²L‹2Œ RÄ€v:¶âiÓ±D%6ëeQm··I{•æùÏ~ú÷Ys½^DQ”^ϯx\¼zùêôæ’ºøëÓ«ªÌ¥*ë®6y-¤jbZ„"XåIÀ}úË&MëÓçÏm‡$qzöâ•ã8P¸ˆ²Vƒ°Ÿ—YÇè D™ B“É(Î"›z&3—ɪåÜ€(Ïx¿VuÞ±BDZ!jÆÝ%t-ò†s„b"KJ‚Y0";ýý²¬R£ÎP!ÙNÞŽ b1LM»#)T\%¡çA¥”„èÐ2ÊZxÌâ²=èOÆ£áÅ|1N&£^+A‘åÈVb×±”ëmÚu,ºáµÁX+ÁLk¬DÛ* $ BoÔë‹–îvÿåŸýðá£{¨Ešl‹-n9êlv¦DÑ´èë'_¤Y'YÝ”­ÖóËÅùÙS¬Œ§_žþäï>.¢xo8Ý™ìi@ŒF“ÙìŒÐ@Ž–Ú ­ŽæU£\ÍçQS¼÷÷\æ\^^R›t}ÑJË¢\TiœôF;É&Y­·¥,y[Ün“À4Ëæ Co±žQÃ\ªº‘®iæR¿uÿþ›wï?Þ÷àøèÎþƒŽÙ Z”K(i†BǰEÄ„=²3=\mç-¯×_EQÓ´–évá`di•[?py!^?º÷¦MÂã‡÷PyV"mÓ¬ËZ3¡”DˆJÔ†a0&t!yùÅë×W_æiò럞Í6¾Ëþæß?[.·“ÁfÕ…3¥‹BfIÑí…ɺˆó̰mˆ©cZj„‘k›USué»ÿÉu²ci–†ùÌçŸÿ;ßcFä\suW³ÙT7)Š(ʶ6 †~†_Äïü2 Q6­IQd7«º«º†¬*+3cŽwþç3/ô ßê‹8h«•Ò2ÜiÖjçûyB"¬+:ÓKaåÍîü®¨‘릓!cýN5À¨¼7nÊÛ‡!g Ãán]þp}6_/l „i‡-”a) XÈÂNÔi¶–²SVŒ1DÞæŸ|ðéÑ÷¯^ûìùƒÓõªZ¬om¤?¾;Ï"~3_®î–Ùi,w¢îª0 ±G——U«ÕV´žÆT*t4JÚmSk«ÄÖðq”ïO“œ(:>:æ Zµ<­ñÆÔ,¤”R”øôÞþf[–TÖĽ´AD±ª±û³évÛZ'%„Ä¢m:!yÜtFy—g™uÀy9 ß»[l3»¶¸pÚõßÝÞ=ÿöÇãý½ë»[oÁhØGÐa„îVKr‹`ÊÉw¯ÞLÇ}A'±©µÚ9~|pðßüWÿ¦mÛél¦¬¸º8£l|4¸¾x'„ðH.ë7‹[ï¦Ø¾Ó IDAT!°[¬Ò~?à½N €áh2­Då=6¾ÅA¸¸½Í²4Š"‚ FÐy='Œ´rWîÊãý“úâw«MA ùƒŸþAÄ{AÆÞ½„€dƒ¬©·‡?ÏGGeUì‡ãñË×oŠruwµ«šŽ`6ˆré´îôO?ùùh˜ì(जâˆ8C< è°—9m´—MÓ´ºGÝzÞ¶»& ÎKµ[5{£É qŸ1†5ÒÒÝë·oßLfªµNº|<¼:¿Ð¥I€•›íï%qŒvxŒƒ0Ñ­±Zzo„„Bòl:9¸¾>÷ÊÌNXÀ3’Ýn7'§‡£l,­Ëöz¿øèŸi#’¬Ö•hÚӱꌶz4ê‡$Ú–vYÔx!EÈ(Aøv^ ¯Š¢ý‡ß|ß–ï~ÿù×ß={á¦4ª»Îed×´¥ðÊ µ+Kk@CåU‚°´` ”(šÂHÙÔ²*»,$7ó-Oâ~ÎÇñQ<ÃÔZi(a,¤MÙR&YòLµ­õÊ[@_oï^¿½² %(&M×ñ”#äBßÍo†³!ÆqYli ”1Ω%AXÃbF,QAi…Ä këEÃA¿¨»ùr9È!´‘fÐOWÛ¶% Ø ß*1™Î^Î{ÿô“ŸX)µQa Ã0 Õõ.¦øåïÏ׫5²sóÀH­ö„ö“H qްß5'>ŠB†˜µ&Œ)ÅDyóäÑÃýé½åyqqõNi])i½zúÉrµ*ºÝñÞcdY¬¦ÓÑên³Y/¡ÇoßÎk³£—ÖŸ9Ñ¥Y%pÐk‹9pÊ$QZlWÿøŸ>ï§)çi[• BÙjF™wÊYŸ¤3ïJQ-lž‚mÝÆ<¡Lg)¦© À1j]QI)Ó<fƒ]Ñô‡12°ªáYºÙxOº¶æ˜ FÙêí¦£ØH5šîm‹…-ea°Nª¶sè H1Šýìã, ·»b;žZ«kYbˆÃ°W¶5ÅÜZ1ˆÂáf³@!€¶w›V7ƒáØ9å‘­èD<ðÛ]ÚO¢0Ö­ öºcaä mUm׌N©»›Åp:m©•£yÚ–ø òù³Ï¯ßÝp†[ÕZ‹xˆÎÂ4 ¶1 ÅaÎã dJTFjH1!(d‰05ÃAH‚B-¾¹þG·¶aÎöC+ÓÌÆ§Vâ×ÏŸïÜ?ý@¨‚`ä÷¨M{éön±«»j½Ù\^½;:Ø÷gB)³Ú¯Ê•RÍr^t¢PCG!j‹ZZBNªNSyg‘ñ»¶‚ï÷z½^º-«íªê÷rŒ¨õ{'f³q'Ü Ïå<êõ<ˆ4ÉG㉔Rv*âÔ"×ï ´i/úθ¢Úåa%¬lË$äm…„.Ò(’Æk/Ž÷s†˜¡Ê9ÇãÿúúË-·õx2gÃþäч'žFÇý‡'O9 ‡ÓÞd:JòtÿQßgy÷ñ¯>xóæì÷¿ÿ¿?üìt6:ö®¦Ycýþí?näm½k«è{ˆÝ)‚AYtF7Riì0¡äððñŸüâŸÿÙ¯þüÏ~õçO?y¤ý,î™ìº* 4ŒB--°¨Õ.g½ûƒ§¿ü³?ùËùWONŽÂÐn6«]SRŽ8fÂØ4Œ’ ­ª–"„ÎïOg‡ª3ǧû»Vb 9¦Z:D1rHI÷o½Õ–´.ÑW_ƒ±Þ– ¢l˜dwó g½ápG|q7Ÿ ’¢©9OÞúàúvÎq&¨í”‡t0HÚJ Y†’,(‹ÚA„FÐoÊ: ( X#ð"d­×V{à’YcDЦ¨e嬣Ý|øàô‘uu¯?ÔÎî¶Ë$É’$ñP!ÂŒ†/¾~1_/×w­Ðà`0PF,×ÛY:äQ,Ug•ÄA ó4c$$Þ;]oJçÀ,ÍN?úéG«óÕên£±òÎiƒlŠZV.à€…T «´t‡yÜ‹k‘¶.M¢]Y[àZÛ¶“ ‚ÊF pÔy™l6>V}úôÓñì°j6A6PBl¡Ã]Wc@¼äÛr?üàú’{°•ÞzãFžGIÓtÆxö9`œ (BBŒÑŽSÓ™J´Z›¿ú/ÿ ]ézg¯V—³YßHxy{‰0÷†$A··§³G«r‡¤ØÊëÝšcä¹Ý,NFG÷„ƒä½ž {ƒÙþb¸\.µëƳÅíÕv³Ù?80B–ÛᔢZðø½÷o®¯F£|:›Í/ïvU™ †C„Ýüò*ÉíªÍÖ '´˜ß±ˆgþ7Àh‹ ž B P]ÕEIR¶‹/¿ù¶RÃæ—ŸýiR6Ò(o‹ àu8Ir¤ê*Ʊ×ag@]]$|,9ó¦i×-äœwY Ùa(Éd»YóaH½±+‰ó.ñ¦”Û]%ŒºÀA.¼ˆH(¥ £øîòvW¬nί^ýðL™fµ.¯®–mL)`H´j69>˜¨NtM›÷2N#ˆóCŽ×VµUE)pZ+!ªöö|{v>ï%Ã8'œÑÃãǪ»®¬ªr’e öÄA@Íçó0NÂ0×Þ_^¾kwÍx4 FN#cÚ(íY…µ­YjIÿí_ÿuÝÔ]ç[£“Ý®7º~œµ©µ°7Ž8ÒÞpì‹Vò8BЕ»@;ꪢK{ìÑñýãñ±‰=t¬„§(ˣͲ BÎRíJçÜpÐkZI)ëm¿?ò.–kç!Ø*Q7]]Â4N—»µ0dl[o½%A¢Gƒ¾jm”cÌBhÒ»Þþ´kë7o¿6ÂHYeSص-ÐÄ:ôâÕ¦„À¦y*•ØìÖŽ{ùQÊ0ä£Ív‘ÅY1¢iÃŒâ^ÚÄ«ž<ùhš>{þ²¿—ýó?þU¿?ÜŸ#„ÇÇÙìÞh».“Qx°·§T+Éj8Ý‚dÚvö‡·/¹Ý\_ÿðæÅ³W_U øòÙùeùÍâÝÙßý‡—/n?ÿáÛùWŸ_u¨ë‡Ùåj•¦ü`<Ümº¶kº®ÑÚˆdI:øôç÷û9ÚíLþñg<\ï.¯.®Ó00!Ò P÷g=Šñÿåÿëùg£„†¿þâï—õ"à‘Ö ï)Åaµµi“¾V²1»Ÿ~öqÒË vÞcí‡1Î’¤_ÕEpJˆÐ A7¿ûü«Õj7íE²17wÅtÒ³RO&û[³ æÛE/Ãù’-æÛM±»w:™ÅïψQÄ­u¥¬½AÊ©ÓÞèuP+ãÕq˜wÊv¢ö{µ«]C1g1¥bçïíßüôCDh]/  I’9ßP‚­qÖJ†é³ß|ÿâëû{§Ö{Œ½zˆ&mšÖ)GvÐY@0æŒJ+*!¡ƒq OïÏç)>ÿýïîn7YÈ6w«0 ÷›ri¸5Ò;m“$E߬—Œ¢0`e+7U³cÆñ$·Æx b–@jœË²Þ§?ûÃ(‹BÎ’¤¯mñ®‘gQ’ º®&<ˆâŸÞ?UÊA`1F0àƒ^Î<-j‘¦Ô;#•§{€Œñ]' ôëJŒGã»ÕÖZ(LyœGQa Y×y<4]]] 91êv~;åcËr½JÕqÌŸô?ûùŸÿòÞÞðàÞïÑ㣃õjµj6yœwe#LWo«ñxŸf”c¶¸»ã', ·â.MsвÛÅœ € Ëú=)ºU!u½¬·]u tyšJa‚¢éâ8MÒX+×5MÞ!DÖxÄ|ÞÁ¦ÙÝ^\^^Þ¤Qz8Åaœ÷2àõ¶¨Ó$FÏYDnç—ƒ|LjE!».í¥eWh¥w«;Äq/éÏo¯×ÛºÄè…T£MSŠ“(ß,µ.ǃ½õ|I9ôÚ9h!q¶ÓgW—<'½ »ºSÌon7ŶÛm·s-eÈ´Ú{{‡“|´œ/X„'Ã#„I>ê­aA:¼±q?U­iÛ Q_—ôìüu[uI”>zr*e#•ŽìíË·á“ý!†ŒÐb¯” ÂÂÆzÐë ¤ÅvÛŽó^Ç å‰Ô5!¬ëÕÛo„®Ùpä‹õBi RR÷ú)#l½]Al­0R›|8PÊU¢ÒÐt¤lÚéþ¸‘xc€Xm7B‹^ÞTMóòÄ£ùòÚ:³Àm‘³Êì!%ëef}#Œ"PN¸³.ÍúB+ÙŠaâ ÜEÀIÝ Š<#´(oEgkiuÕv•zvöâùwßc1ÂÀ»ïŸ½Y×Erp%›,Êâ0Ô@S„‹Æ)×)S‹òðÞP*rWWqQ„!ô*ÐåªÐZ±0’µhÚ:`¬UzU4κ€Sí­R)ï¤Þ+ë¥Tƒ4Á8OzøàÅ‹«]q…A·w8;}pÒE«M}ïô4ŠC%@’e½Q~0y0˜ô“´¦mëŠG€ª-žìB:cÎ0ÄÈ< ›Öò€8`¡ÃÀ£û÷ÚR§yÌ< EU‡’Æ‘uöÛ—oÞ{z Û¢àâöúhÒßUµ4Ju5 zi’/«í®ƒ,ÚÛß¿¹Z”>>yüoþê/ƒ©ädYåf½\ïMòm×6MÓÂ8 0¸_§ƒÄ™àêö Q`”‰ÒÌÉGDôúc£A+w“ÁxØé*Í2ì°’mšæ7—óÁþ¬?´eG9ͦ害NcÌTg Þù¢DÏο3móúí›?ü“?¸üp5¿#1ŒQÊB¬BŽ×‹ÕìÞéÔvQ=¿]nJSï¶«v[Y 7‹è¨ñ!}u£!`R×Mg £ÔІãpØTuEé®( aI–/×ïÁl_©dK½YÞÖRcç€×0$Q ŠQ÷!°“Qz¾Úm†ÓÁ`8TJæYJݬ<å„Ò¶ØQÎx˜ ÑY|öÝ»ÛËw÷žŸ"óa/OÇmÝ b½ö³½Fˆ—Úy%‰5ºkŠ(ްGÞÁÛÕå 7†<¤Ö(ë1D#¢”,våùÙùr±Ì=Lq@5ðÓ€ÞI D”Œâ,ÒËÕ¦—ò²¤˜N&9ö(Üψl«= @×6KʶªÅÈ2’þô㟵­ÿÝW_tUþNXÌ(…qÞ‹²Zt]Ó…•²œŽf“Ñh½ÞAã„•»A§¬¦Am' Ѓ¶“V[Loõ JBïïÏf÷Ž u½ “!ÁÔ„ ô‹ƒ´­+ü³Ïþ@‰È ÐZ«u¹9šLÛ]»ÜUœÒˆg‹ëˆ‚ˆñº!ÅàlÐõz³ÚVþËOÏ~¼Zî¶ß¿ÿËÏ~þÍ‹o)¾£I¯×§/__e1÷Ò¶2¿ÿáõ0‰K!’}ô䓽 Û“^–gͦpÎÛB(©¬ÖRL€ïL££iÖK.Ï.Ã>ô.¦q±ÞbN!ĘºÙôÒq¢ÙNIžbÝJIÑ®³0ÂÜ z#BXQ¬Â(pX+9Žêz‡ŠSþ›¿ý§gÏ¿ÛëM|’ä<ÍsÕÚ !õ®)‹Ýp0»¹¸ôÈ ‡“õÝv¹ÞYÙÔ¥B†AðíïŸG„ìünµk×iš/Kí%率t˜8«ëm©¡IS>¿]tZ[§z“áb{•DíÕ廪®£4ÛVkÍân¹-,W»Ýz±ÑʇI¿ª«^–F!õÈÖe©MzùÁôÈhKF=Ó5B²ÞåÅe6Í7»Õåùíã?|¥1ã!€ðúÅë¤ÆQO¶m4H(‹bK„EÅ|Sl~û»/NOîçq^e–÷ @R´x£¬Ýç_ÿc[+a•cx»Ùji<ôBKlÅÂÛf³¬jÌC ¬÷(aÑtÜÿè'³üÍ«gBÈÃéÉÅå™ìLàPœ…aÛmÕ”iÔh²)—{÷<™/.€‡ï(¢”iCȌӓÉðnµ^”»‡ë¢Y®Êþ¤ßË’ÕfÑÐXUÖEDƒåÝb[n?ùɧôÏ~™ôøð0øàñO¾øò×I?ug„><߬úY–õ˜¨­÷&LQ„Óa>æly¹¾7»?ƦÁœ3ïDµëBs<€]ÝE q0.•ÀAÐ 3‹Òž|x[l¤ó$Œª®¬•uH'³¸_âÁ“_ü‹?è:õ_ü¿eÓ9K¾üÝw?¼|÷å—Ï_¿ýûÊîæw«µ|é þòþa³ZYI¾þâë—çßœ½¾üöïß(Þ6¢9{wvpp3Z¬6yS¶UcLƒAdu+ˆ…ìzYÚ”  ˆqzïäøj~ý€“¦ëBÒðäD€,Ï¥;Nsä-~˜Ìâ¨ÚÒ8 „f c“€ÖeóÑGï½÷ô‘4z»Û6E#D÷sÕ6uÛŠo—g)‹f{©Úª¡¬·Ù]:¥£xÜøRImrÐY¬±ë¢Œ³Äg­c4‚Q|8ÛSR>úðàþý·ë[‚ˆ5^›#H0J2J½'»¦Œ2ü‡Ÿ}*¤tµÖë‚´n:„½45F #´iÄF{åÄþpÏ:ZWkÐñdÑÖIÖM€6Zž]Þì÷*á¾}ñã}òV¶u”²,ÎESîÙx¸÷àÉÞíåJ[÷†i–]¼Í‡C‚¸µ¦?ˆ—Ëñ¾7ΤV—ççÞ{¬;Õ5'¸k%!¬jʲ¬µµY6X,ÖÛªŽI0¾ÛÕÞk£=Øiåê§ý0 œ5bB lT›.MSàÉÙùÙÅ墖µ~ò`2™)¹ ÃHkm ã,êZÑ´u’fG›rNè\—ž¢|0M·.ïöç×w›rI(ß­“a€¬E€¤ýxš§WWs F¡PØÊ#$â!õμxö|z”¾þþ‡ª-Ôž¿¾½º~}yywsv•¥é‹g/Êm›‡QFE#œƒ,;Ø;ªëª(ʽÁÞp4dòÎ!·Î2XˆÔ£]¹-¶Eš˪ú‡¿ÿ»ãÓ$ ö÷(I–»ušð¦Q7—«“ûY4ÔJ`ŠºÖx¯ 2FR4Ú»Å#¶´óØyë±ÃX+¥é»gW¿þûßìÍr#ÝâfÝ™PFv.f@*Ý ›ôШ©ÕdœÎwÛŠS0Îyxp9»¾Ým¹ÛVMí¼mÚ®’ãÑlºoDÛ÷„B€Ün[O†“(¦Åvç½=~p ª¶njÕÍzE<F¢ñ~ž­–kNèd/·Rv][!PîjB‰p¦ëdÀ˜¶¦«‹wo^%qúþã´Òß}÷Õõͼ(ªõf«µ"˜;¯×E»?9þìã5Ï¿ÿªišzUýõ¿ûë—×?Žó r>Î`L€]‰u†Qz49Xo B轃“Ñx$ö!O1‚DÉ8ƒ€H##š =õL =vÞç󲨒$]SòÔ!a8^_ÿ°-ë áVw×sïŒÔ²é uÎ;‡Óº+»Ò;föM{£ª©ò$îEi'íôl£;à}‡jBŒÃFmîÝïɇE±6Ú&Ù¨SUåA©;ÎYÝu_þþ·^–«uã;ܛޭVÊa>DÖ—¢ £hSÔÂ)Î1#4K#kqƪ‰…J‰?ùÓ?žd³/þÓw×»3ŒÂt6 ÙÞlv Þvˆ²a¯¿Û•»J#à¤wÀãAÊ—ÀœB€ ”.M"åŒ5Ö#hŒÃ!â) îŽG$O†ýþž6‚sDp¢lE<ŽûåfFa/ß^½Â÷Ü3Z é´Îo!!Àä,<<9j»ºk*ŒsÈ9O9ïZÉ nd%T œõÇ­•l’Œ°$Œ^¼}{´?­Ýɶl»éxß:¨”„­ûq¾Ül¼ç|ø0¤ù¿û›ÿégŸ29F‹zí¥7i¤…xõú‡ã§ ^œ] äŸ|tqyÞˆBÒÔÝloïêæ².ëÓû÷µ××ó¬—CʧNB‰{Œ)9yzB ò€3 i1&Åf¦‰…¾)ë^Ö÷âêõ»ó(æŸýäçaBtuÇi”æ»r‰±§<ˆzU¢jŶ˜ÇíšFúΈ¶¨Úyq§ºÆCxsw×ïõ~xyá½zúþãõ²¼8¿ÎÇÃbUg Á¯ß\NfCBhUÔ¥©GãÉÍÙÝùÕU$Õ®®EWhB¢AoòÿÓ?¥qL)G8èeÜ8“át?™L&¢CýÑ Ÿ$qއ½±ÓT9 !Â8´ï¶[£ )0þûg_Þ­î8 >yò$€uSìî9¨ê²œN­p)«4Ä›¶„ÄCHT'‹ítväB¥•u#êªÛ•Gz¹X¿~÷–g¿Šh<8[¬ Áû㙆z”„±óÂ)E‘Ö ÀÙxÜ{ùê-c!¤ž…$e[?õòû~xñ|õO¿þÿBÆ­òÎjcˆÑ&éÑV"lÁx”=:~R6-¦¶—ç»¶íd;O¶›¥Bx[«V)Et[–Ô€¸>ïmT·®Ö³<òÀVHbfœsÒP «®åˆ¤0Å®  ßÍfQ¾|~è´ ãd6#ªªÕz6œg!µdÍXH0tØ»ÏÞ\\¬’t²+ïvź*4PUÉ &0ÂUÑD”I§™ëZÏöÒÑ+Ïf1@´«ê0F÷Žî/—k€uöe+Iò,oÊFd2<ÿþ3æéãû›â®éÚÑÞÞb»¾Ý®k)µ‘œ‡Þ€j[7­$ŒrL#o¶¤,ÌøÏ?ý…µÝë‹×oß]GÆ1!Â%øôþèôáÑ×_ýú‡×ÒU·„Þea$ŒhÀW¶:Ú?º¼[u÷³^¿×ŠÎyšÅƒ““ãéÞ½åzÃÏQ ¥ÅZœ(­ýz½™W/>ÿõ³(Šû½„ äÇ«3F‘S@[ÿɇ¶›&Îó§Oç×Û¶ìúyÒUfÕÔQDgY¿¬ åÀ+Z‡‘QV)­” Xd”ö`„0p»U±ä}‘‘žQêpR2trG¡?=xœçÃé0 ó(eÔÁóNÞ`„QªU¥»+V¿ÿö+ cìöfžòÔAê}E –Ê,wK‚óp±Ý2ˆ”Ó^/Jy%­$!üèÞAÄ;åõøŸ®T=_­Ò< ¢hµ,öƉGþöv=ì§³a¾Þ6¥Ån³=<˜.·»ºi¤QaÖ © A˜`ª­VZ÷Ò8䤭jJã÷>}Œ%ŒÛi­³d$E鬦,%VMaŠŸ<~SWQï %$À\ZFaÆ¢Ívi´†"L”VÞZ a?ÉveÕ)yïp_H¸«$åääð¾hÔt2,êv6šíê¶UxŸÇ‰4®­EÀ¨‘"$ÁÅò.ï§?ÿè³Ï~þÉÏ¿E“XA=Iªíòèè¸kõz»ÔJžœ<¾›ßÑÿŸ$ûض,= Ãüçýï¼÷É禪[·ªºª«:¢n€¤@B”@Ik ^²^~?ç~O=ÒHKÈH 4i‚»+WÝ|OÞ9üѯñazKŒ2vq½èÛ†P6žŸ>KfCÎýU¶´Æz,èe¬mû²­f³bW+)]sÇïÚÒ÷]`±Å —]Y–ˆaær H_WA쬶»Ó«7Ùf½Ünï¿ý ‡«óm$~ânWk5½ƒüº©–Û«®êZ-_½y­*‰0ìú<ßÔ_óM»B˜¢éª&óƒ!€Òí@k†D 3£€ž¥wŸùùv½æ4^^]JÙØÎ©ÊF 8ˆŽ.——‡Gû‡{GÄAMU;„¶²«eƒÝdkÆÂHõj:?íï¿yór¾7‚˜Œ‡SBHY•"„hUWm]A¨Õ]uöâÒZ–  uœÄÓù¼È!Áv{µÞÜìÍÛ^Je¹ $‹Íš9>DÆru³}uñí|ºÄ©’QÎ_iAF„@f¿xú—çÛm¾¶JH ·E¦µt/ê¶îZ‡aJ`ÄU[#n ¤ÈX©Åp4šLö¶Ë ýÕ¦¸5;ô‚`½[k¥Ó8ÝlVY¹‹ýHv¨éʦëû´BFª¼ã˜`#…F`µètù—×—ðÉhvssùÃá(íU–oÚ8I(Ó¾ZƲÝD Ç8в½s{X€kLË yzµ½v™3'„a×c¡ï÷ª 㨯ڛl©{åqTv™[S·ýn[(£6ZX `ÛÖ€°’Ðj©µŒ\&”mº6%`#:ijV´u§cÎ!Ö£$ÀØANÙn6e#dÇ0βõu¶»s÷¾2m‘•¼ÿ]o<}ñê<Ƽíd%ÑÈ®6™S@•–0Œb²$ÝKBo˜Æ†M- ¬8ñB7ÎêËi²¯Œ‚´ã()˼mÛØMoÊz—oö’Ãež5ý&Û4yÛuPÔ­eßKK4­E׋Æ*9&ZY‡N+ !"8oôOþíò…ø¿ÿü/ª¶ñ\·lZάiz|{/+Z/™îÒO÷m^Õh‚ °l•µ}&~àŸÝœH×ïû&MGÄ%£89<>žì'@‡GVwÀZ€(v”ã0£I¯+JHäNž~ñ*ßíÜ &À„-ëzW—¡ËÓdp±{• £É¯ýËq:ãôÕæòà`æ"ÿr¹Þ§¡ëK¨V›<â!¢T˜VH5Lý p­Ò#!%BpW¶ã8©šº“*ôܪiÖ¡ª—IàÌÇ‹Åîýï¾=ÇZä^5bî‡Ñz»u£”2þÕŸûõ3Ç%²hFù5`¹Î¬‚c±Ç»VPÄé! ZÛõnmªkkA¹Ž;ºµZ\]]¿ÊÊʪ‚›õ3°M¯«-4–Xº®êЇãÁ`™EQßžN_ß,D×@•Ò1g«,€a`µ2ÙAfuO¡§)"áp4›ŽGQwAàn7@„R[ÆP ßzëžcëR*…ÅjÚNc¨,1Eч>ï”UÒÞÙdÖËj8tOöON/ͺ­Ë}2¸Ø¬=º'…¸Ùl‡Ã4q=%M^n÷¦M'1‹,÷Üàí»w?º÷B”±È}ñÙ—{“ý€À8oÖWF£µ2½ê%!Ü#5:½zrxtÇq’]¶ªËÜõ} ±#¾kwOµÔM_ÌÂp¸^]®ÅIÓ4”pi4£Ôu¼ëëkìh2+Š«¥Æˆ@Œv>ûíçe½ŽÝi2˜ÎÓ$íµéi¡-óÌ÷’¼Èž~ý)€(ËV›õnq³æ¯O/ÛΪ¶eØ) yy½ ôFEž{}yÝômè{>IvŶWª¯AUoÖ7k !太ÊùôdSnFƒÁlz˺ÆZøøá;ŒÓr—YÏ.ÞÜ=zhZkiå$Në®nÛÆ§ƒÑ0ÍëÂôr:IÓ$â,èEëÇiUJŒ°¨lº¦é»ý[óÿóÿOq~ÿã?ÐÀvm)­ÆÐ  ¶Ë, “ ¨Œ²Mµóƒ oÀXCµ^W—§“ÑáÐ s|H7eýÅ7_`H$‘Õ&…œRjoÖ²ÖPìRg:ß,.=ŠÛ®§ãél_jÕÔµ% ©ìº¾ë1¦›¦ªŸ?;Ͳ+' Ö¸›âºµYE tˆ§l×w•çŽ×0f|àªð©s4=ÜK—B¡´–QÒk¡1ÚT}G‰¾=«ô] RJAUYöZ¦A\V vðÉ£l[¶mûñw>€Æ;8L=?ÚlòÙ|n-\®¶Üq ÞmwÈ£/Ÿ}ýúÍyÀ}@Ý7‘çܹܬnïÍ#?¨[ D÷B9œJ­Ë¬œLLJñ¢n§AÈ 0ç//”e«€aÝŸæ\mR£úÃùþ:¯ovë0%nXæ%Ã` ²Æ´}ë»CH¯ ²Àó ÀwùtoøÉŸ¾?‹ï-ý0ÅÐ]¯¶ÃYèiÓ´€(—'²ÓAˆðã»Bk ŒŠ1ä.q¯¨Š(à¢NvŽãì'×ÛÅd<„‡'{ïßœš–|üöþ§ÿùüè»oÿú«ß*c0ãÏΞ^o®?¸÷°¬J—²«åâäαç»EÓçe›Ž£^›¾mî?ºßvZPn×Ìå·nŸÌ'ã®Ìñ’4B…?p‡ÐÞ\®ï=¸ †ˆ¡Äh-=×U ’0Ê󜻘á²j!žë`êjHšfwptWˆ¾®ŠÐ F³Yžï?Ö²sCŸwµ¹ |§hv_}ùíb³üè½ïÎ§Ó ‰8ñéL7Øí6«åµüO÷MUYDTÌÃ:k!MÞŒãA+ê«ë«0ô¡†Ü6È:“ÁþÑÞ!pއã@6]œÌ÷æÃãã{é`>œ 0''o¥Óx·Y9€ñé¦` V×7>w/oβÝVkÓë.ß4aºùäh:tu±?y‹8ˆ9ÐGÌãMQ8ÌE 2‡º˜—u!ˆÃ¡ý/~ÿ«0ìÀ;÷ì-²«“ÃÛ®ïùÙ“ÅÍÍ'Ÿ|¿Ì7~À æ„ Y]5ëõv ´ô÷¿ÿÝÛïÜß;˜;Ì-›V8^ÐÕõ“oŸæù¶ïúõ¦l”¤˜bMFãäb}ã!B¨…ЙìÇ.&åfWYcº=;` GÃMži%<Ä•µŒ’./"Û¶ð=‡yÑÕæ*ð±NÚ¶ŽB ‰#ds×s™KX-›¡Ve#p1EÚœ§³Ùàôrqyyúý÷ß[®²¼«ƒA@,ÔFz>Úå¢jÖ.B×ç`z÷È‚Z(XÔ9Äs/&¡û®qyàQGô “ý8Š›Îx:Ž6@4€N)˜øB¦j %TÃÕfÝ©>ŽR¬è…O8viY bmÑ7Âk%¡¤(*Θ¶Èíº\Øw­ÅFIís¦•ì;øÞ[ïNý²,•74>¿xM\°, Hp:ŒÝ—Ó²•óU™)À˜€Ùx´ÙåÄes´ÒìâÀ…®–˜QÒÁæÝßi™ÕwîÞ__­Õi’`‹µVÃÝ:ûöõiÝïÖ79%Äb¤5ØÛaåU-eWt2ï…ï9a½±ÈêQ]n·ÀÀù$UJ­vËÄã²µÓñþ›ë%R \M0BZi4Úëµbžùn[uuS0Æ9ÅyYyÜíú–b–F(B½CÑÊVõªE_ûäø­Ááüq[”U›Og3a'ëÀõ…QЇÍn‡ŽŽÚ®³" 1&Ri¡:NYì'«l ,ðB U T]þßÿ?~ðÎãŸþåOø/ÿè'ÿæÏþãý_õ›Ï+Ñ?{~R–gÕA2ƒ^Òöâjy•úÞª¨®o.BM§|¥6÷ï×ý.£§Ï¿U²x÷­Ó(±Ð Ù¡+E'¤éÚòäÞI•—ù®Dĸ>­Ë²nZ/ÂMÓ fãÅæMßpc«ó³«pf•ÐÊ(aÏ ˜C è«í º®¡ÄGÔp?ÄVKÕ˾ƒˆ2Nš¢àÞXÂþ׿û§ÅŪk›Á^üÞã÷‹rƒ5ž§‹õ9á)e®…¤kó|‚Ñáál>=Êóroï–¦ƒÕÍ qçl>ÞÄT=|ôŽï®ÏŽï{<|gÿÖ-£úÙÁ˜2ºÚ];¾C"Ú^¥”MšŽóºÍË5„¸oëëËKJ¨0v±ÞîÍçm×øˆ2N!À Gß½Ù¼†ùI’ü€º®¥pƵÖe± ýHÛ¾é³<«NÏÞüîË/€êv}wvúôñ;'×Wåns-¥júzØÛî6”Ø©?*Ë&Ï–õ‹º¦Ea°ÍVÃñ¸oÅÙù©Ç]bØ‹Wg£4xZ7Íñ|´¹(Ë~u0™íï??u0k`ÖÛŒ1Š5Þ–¥š!·ê„Ëݾ·ÿÝOþ›[Žâá¤ÏÛ?øîQ}õÍYÕh ¥P@kðJöàã?˜ìMâp¶Z-®’0ôi£ ”E®“ƾƒaÈÜ$ò«R¶JÍgûÒÂÃÃix„Ê0dq}!HÓqYo½€ !«¶®à›×/®ž=¿ñ]l5¸Zå{ƒH)uu¹²@Aâ´EÎËëµÔš2³ªŠóÅêðÖ´Wúæú&Mù¶ÁÀ%úi#âRìä½"Sâkd'¶Ù¶€`Jh×uRœGFI‡³ÈB/ Â8nV—€ H:  €”3©¥ø«ëÕ/þîWG³IglÕwV–²È¢$rÛV-·ùp®W1 Uª¶t<Ž *ê #¶Y•nL=|kµØ^.œâÿ¿.¤y]c€¬ÑeÛ•MË\l–Rh£¥ºízk”Ж@èp¦@Àj£„Êê^Xb`LS·!f! ÆÉx˜ RF©¾'JJˆš0˜g˵Á£1~÷Ñ{ÀZˆ4ÆH©”Æq¹Ó¶=ƒÌjÁ+t¿kwPC×õ]ÇÝì.F³Ñ/þñ¯þêó¿|ùõyw¦^¾ö¶-w÷ï…aøõÓÏ9ó²Ü'W‹z:BhÒ ]¬®‡£èñýG¯Îß<ûú•ƒÙr»¾}ûþÑáÞõúòÖí[ëõªéÊ(DQ´\ž¥é`0”ív>ݯ¶dÖqCЫ7OÒx¾?¾³\ÞCæÓ©ç¹;”:/ç{]-1¦Ôç˜0ä†tZv^8èDŸ­®'óƒVtRkÙ+/ XÑŠ×O??¿9 ùd§£t<Þã :sá†ã¼¾B…ÉÔ€z˜$ÃáØã."h ú.3”-Ö7ܱÐ&×ÍnÆ<¾Z<9˜¦I0œù„8š^—“Ùäær¹X®§‡ù.s6L“Õfƒ túì³/AãÉt³ÞqŽˆëmš¦€˜ž^žNº³E_ÆAzïö½ÕÕe×5û“#y“Ùt»½£!ç¼oÑëÁdÖV•1ÚÑ4Õ`oôùgÿ´XWmÝ>øÛ?ÿ§4žsl7åºÙv'wï¸Aàùc {Ñäéød¹>]\½É7Í“_‰¦ã[ÖÏõ0âM¹àG0ÕÆœ]<ù›Ÿýn•oÆiD¡sv³ˆ}*˜ÕEìG‡³mV{ˆ–R“äEk´Ý›DžŸl×ÛÉ`ðêõÅãOn¥aüâÉË0I£Ä' ¬WÙ Š°Æ]׆ ú©ÑD»]eÓéASm³¼A˜ÒÈLoi܉JŸ<|òúÙôî0 ª²Á˜мܰSµ¹Ö2¹¸\Sà6vûæÙ+QjkÅÑÁÑb—AÓO¢4Ïûí¶|çä~Ñ6ƈÐ÷wU͈ÞM7Ywq}~<ßëÈEéSFQâ²ÄçeU bÿ_ÿÙÿöWÿ¨»d%A • Qž×B£-0Ji`$tC^6 )¦&áa[÷è "YµË•ÆÚ¬·ëº¯_Ÿ»@ìùI´.—ÔsFñ°¨VãƒqYdÊæº‚¶Ï‡ÉŒ*(mƒ¾“Ð()¤Œ’¨®7‘i‘éîÞ”µ†ûn貦ìü˜L÷'ÏŸ^ ñh»éšv7îµYo¨Hý¤Þö³ùàho“ÕŒà8 ­î?~øÎ»þÕüþÃÇ÷¦oÏORiÁþ‹ŸyÜó˜oô\Ïcœ ë:¶ô|ïûAnNÏÎúºOFÛº‰ÙU]àú”Y€Ì$¨!‘q0جÓÉAìy·8÷ cN¹ïÇÆöÜû^PL©%_ýöÅõj†I]åH)×÷¯oŠÅÆa ÍòúÁ[ÇÜ⬨ö÷RN½ºíl׋擾“ëBó€‡ÊVv¢$Ì©‹îèhÔ)á1ÏÝ5 „#È4ÈÀù| ¼fWŸÜ9ºûð¤È×Ü ¹ã`b)ƪÌ¥Z™m~óÅWO¹1Û*—d›ºöýPIÝÉZI=ŒŠ¶¹7Ýç¾ FæVB,@22~³X_Ÿ1.¡qvUësg—5m+ˆƒ‹²q7<`¨‘½çã*WÆ@mYÕÔq("Т²éì(c:¡\‡r‡¸„[£ D£ªm£ô‡?úm{ΔR=£¡ã¸e¶Š:¡¿^]àã“£5†¸Õƒ¦ãån—DƒÐgYÓ4M…n]õ}+#¶_|ö-£^yÓ‡á°1lÄüpòÎã{%¾}úäÁý»e½‹¼d±YR—"É•ÑM_Èîܺuµ:ëŠÎñ¼Ád¶z“çã0¶Q8.ŠmÛµ£tfQg,î¤r°9ƒç/_Žg#ÊÒ›õƒfo|Ì|.D„)†v¦]%6ùÊ!d0<(Š&Ô6Åd2ZßÜ>ª‹ìæj‹¹s縩º¢íƒÐ%Ø¥AØÈ/Ï—§‹u;¿=üàí0@ʨ$ˆ´–Œ1‚ízs~xtx<ÏJâ }IyèWÝõ H)s®ÎÏ£( FqèSäß }÷àà8/+iZ/k€Ö]§‚ m«íh¼ÿúÕS£Åþìäòâ¬(³ã{÷ŒPuƒ]þò›/ƒˆÝ¬7¯ß¼æXEÎ )úÆãTkx´wËh‹‚(އûRª½½‘2VõŠûÆTuRcij*éyüoþ¯ß¿x}š„,ß7Ë›0(ç|v{öêéóï¼÷1@)4v=ÞõªÌòíÍeQ6ª£¯Î_¿u÷­½éapÕ÷ºÚ*Ì\„ØÅëó²É\È—ë´v¨ƒ`˜¸JAmÛFª]Ù­œ R½ÎëÌSm)†R {½)­µ÷Žî~ñìùgŸ~öÁ£÷–›mQo¢ ìœì¥¡OÊ]æ†<â^Qìòf§ÃE¶-‹,ò½‹›©4Cp×WÇû“ýϾúfœD÷¯‹õÞ|¦j! ’\·lû4L€YUE¡‡œ Ø”B*Çó€5³½=)r#¬k•E¾ë)[f›º¹X-÷¦IתFÈ8vŒEy¾ó"¬­t<¿,¤PR#ì`ôû/çQÞ*UuýÀñ2Y+`Œ»^Ye#Ï‘‡Ì…Viƒ\Ça¬+…m)*Ë!0 @ë]–øþr›÷}ÛgÄcÃ>üáÅécð`>ì«Êqh'[Ç8”:Ûe,âu]»Ý:žSU%óc£U^®ë¹ŽŸ—&´l/÷öïo6kŽ£Q/Û7ç¯?z»Þ]¬/Þyÿý®nU *i,ÖG{³õf·í¶¡ãö}Óè ‰°yyþ²joz˜Î:"ß>yþzõ¦¾|svSQ¤U-Ý#êÚ¸8;[÷V¾9}s±-×Z™Fȇ'wcÛb9™N7ëÌuy¯F¹V@©–`tïäÎá­[Uµsx µÐZ„BŒ˜Ö]'øéåÅ›ÓW @À¨l¤sÂ)v¹Þ®féàÎñoŸ¾ÙæÙÝ£ýÓók‹”}¶iïÜ›̦ZuŸ½ûî‡ÛÅ Ü,+´ç ‘U±â˜ жžÄc€”†`B0E'\îJhõƒ““í1«¤ŒÜ¤o't¨ÜuƒmÙ ¥²ÝÍåùͶ,1µuU£T CD!ØB F™ª-£   ¹-C„Ê}‡QŒ³²J;S@1&€Y«4€¨“Ýݽ»”±8áI0nûÚ÷ÝI4€K%¹Ã³²J‚3Ø*I¶ÖºÜ÷³ÖtB%QH®á8ð?øã0ƒØG4uDa@V’Pż¨Ùæjüî;o ve¥ )u=‡RZµ¥ÃiÓËõv ‡ÓåzûÁt2„³/Ÿ}£Œå˜÷²~zyyr4­r˜« ¸3;Üívc"—³ÑðåÅUiHó¦BŽmËzº”WÛwï~pïícLuS7š0ñ«¼ÔÐß–ç‘rï¶›v—†3¥Äv³ަPµƒáÈ@Ü4;BÀtv´X¼¦ŒEQŠ¡¶F®‹Ú‹8‚YR7ÛÉxR¬+@AšŒÓtÖvÆZŒ¡ý0[︋’áøé³ë¯¿~>EÜŸß=¹ãGaŸ‰tœlwëº,Wû·ö._\j£XÀd/!€Z‹<Û9œ§‘÷íןÎö÷Î7ÒH*üáád:nû] ä(/¯ß$q¬•!Œc¿«ëZãé¡Põ“—ß„nLý`™=;{}Õ4Ý—Ï>uÀ䳯¾|öòå8št]SÕ}èD ƒª“á|o:™$µ¥¾O(Ó·Öm-•än"Uãr½Ø!dÃ0a–=yöõ­G_õÅÍ:O#w±Ëm§Þ?xsvýó³÷?xëÁ‡YÞ&±g `«]¹\îöæÛU¡EõÑ÷ÞÝß;¬Ë­p„Xß)‡±:ß2Çùü7Ÿ.–k>äÌ‚]kb/(EEµR7Rw½ }Ç¥Ôj1Ieߥƒ”9ðêr³?Ÿ…®k‘‚XϦû¯Î.âÈa(¬[µ?M6E™eÙýÛ'»M–eëÑ8ZUu­ð¸»ÚìeU#⎇øôb™mwwoOE#¿9}µ¿Ÿ~úûo0“ñ`½ÝAŒ¦û{7›e+»Ä ×»š0/$¼è{iê“·Ž³ª®ë|yM£Ã žÎ«ÍFˆvSTM‹ö’t×7ÂÙ¦ØÈN3lª¶GcD^^ÝÏ÷G ˶F‘:â8FCˆ,¡²¸éKîúZZ Õ0J²yU‹­E…”‰ëeMߥƒ±U2$||x0;ùäïvy»-WqàqÇ)ò|’¦§W‹ ŽçÃô~õ»þð_ (ja¬“i°Í…ï:¾£-`ØØ²«U­CßOãÅÍ3J A âáÕåsî±Ñìðåù«®*öç‡ÏŸ3Žwe}µÛØÞF{³ºB˜îïí]®×ù®îÒJ)L¿ýæKͲÏÿé«ÿü‡'O¿ø‡¿þ¬Óm¦ëÍšPûažŒ‘ÄO³¬xuyöì«oúç?«Šr6,²1"˜×ù&ÛíÓí¶ñ9¦…u†R 9wïŸÜÕR†ql ]‡-p˜KÑ`ˆŽË×ùîÕóW(Jñõ.÷\¸mÞÔƒ$ÑFWªæŠ'£]™%á UÝõMu8_­/t_b/Î_a€¡Cd/Š;¥‡1“}ˑۊš(„œLÂÕ®¶ÖìÏG»<ßäÙÑÞ|µ­–Yö'?~gèÍCbt'1Æþ ‘­Ú.Ï]ÏþõoÞœÓÑf»s1Äá$ y]ËFi k‚Ý*ÏíÖy›†[MGÓ[Õ­Æ Â6—Q’ Û¹„[ˆÚN‰¾Ã¹œ ãP]tÙ4NÏ;¥:aDàÅ­hÒ(B5]1%[cŒ’Ò`€1ÚÛÔÔâñ÷½ï<ü“NUŠØÍqJ¡¥ÌÕØ¶m·]×øøÞÝ^"QÒ¤¡1PsÇ[­—†€JKˆy¤u3 Ìï¾~¾7öúÖ*e¥Ñðá¯^ža!Ú›{‹Ÿ¼~á`”Îg°OŸ|ûá[»®SJ4“áÍb3Ny‘™®ÿ“ÿ`·Z9ÔP%Ñj%uض(GQÄÿõ‹az!7RÔu1œ¤eQÎg·º~Û–2NR@ÔöjCÇ©­†$WëÄ©VPAâ(Õ¶ê>'JÑ3ÎÄF™²ØNf‡èÍfUl®.Ï®•Ñ·ÇÃ{wÚMæû§×g@µœÆ‘¶Ëãx¿UÆwgÁ«/ 4Q(©×«óÁ`þfñÚu4ÆÎº\ÄC\¯ÚËÕKCš³óå7_ÿÓþh³M½[ô_úÛÓëÅ‹Öo?ÿõ“/¿ü »æ›/Ÿ®³›WOŠWòéé·7×›ç¯DÓy~˜mrLÓ+m b°‚üîû…é›|1%‘…Fˆ¬%N¾ÝN<¿®²L^¡`d„úåßÿœ#¯lëIjH¿~õ¦‘ùƒ{oýêŸü‹?ýcÌ£ªn‡‘ß4­EÝuæb¹ØŸ¤²ë’Ñx>!H´F€HŸ'}UFÃpq½¬Z||ëÄ.ÇŠ€÷í»Ž×µ’iu“íF£ùA»|1L˜ƒ=ÎvOn¶7)î"ÇÁUQæ!$1¤ƒÑþbu14€\¬Ö‡nàßlÖXÙÙ®* 9Û"ÛÛ,ó…ÒPä ×4 ÂÓËËÇ·†éèÛW/fé°Ìn ­C7¤Ø½sëö¿ûá÷Á?ÿdÌãfÑ-_;HXÉ‹"‰ü(‰–å:« U*î„Çû“›uî{¡ëЧoÎ/ m…Ä#Áõ¦8œ ‰•E[C š®±ˆÉÎ`†¬…¡Nt> Æb(¡EZLÔFåÀ@v`„<"â–yã‡^^t}ß…±/jxþ»wøÔ«ÊüàöASªNª»wO®¯W]ߎ÷öºN YœÜýì‹/nQà‚å*ôÃ.kyì}_\]ézNÙ«ÝnË}Š€»Ú®\Fc”á®m!¤¢kÆ©ßTdïðX«r¹ªF³Ð4ˆäx»ëM2Ÿ8Üë:i¤! öÂ:==»|òì”ÚešFÛ¶Òc@õ8ðki­UÜaVÒ¾ëÒ4ÇI–WƒÁ°.:‡S‡zœÒÊv"kTÕöÃdz³¾¦ ©Þ2Bæ·§ûÙ@c{†™¨d:žeº®ç”PJ¶«¬»'_Þ7=@ª¶4z¢ïÛ²I’°éºèûÆH"ÕºØ)k€AwïlÖ‹ LŠVäym¢ÄR5m‹ P@98ìd…©k#lë;¾”¦–5CXV«Ë .º2dþQ2׆~÷¶•¼º¼¾}ëØb”7ŊƈòÛ¿þ¦–A¤ë´ë¹­¨¤æ•)CÏÓt˜kØí:?ðÑ ßT„°ã·çEY ]Û6xËÅzÄ}SWª;tú'´i·ë¢ò¾Ë·Sk¥±–"—;6‰œ²é%U[L°Æ—AcµÕ°½1Æ¡Dõþ÷?ù˜@‚Œ½@Ý1Â…Y¾šN÷ÚºÆ'÷ŽšN „JIŒ0F°“’AD0ö¸Ó÷Ê1ˆ½¦@u»í(Tßi‰Ñ1—.ÖkàtÇŽ{ѯ>ûù½ý#cÑ¢¬.^¿§#¥ä|‘ì ?|ç­o_¼Ö]?%£Ñ±Céñúhç‡{Ðêõbã…üpRïÄõâìÑã‡›ÍÆu(a€PÞ6e”zë‹5ÀààèÎÙé0b2Ú„uÍnŽV‹M²7‹ý°Îßó­6RöÒš ˆM«ÃDÉ:ŠRÔ@É~0)QVmËqtþr]”×77[ˆð÷>ù`0¿zö5÷=©™lräÂzWs§«»mv¶{þâËÓdE^ö5{}õÙ«7¯ß\Ô»õiò¿ý¿^,_×}ÿË¿{úì«ÏT§þóg«Í•Í_ýôwÇVÓßüò @Ýd8}úÙKÎ@Ý7¯>]ñ¤+w½¨ëнñx¹ªÓ»ÜÉ*=ŽÜRõ:{Ã$+×½6·”¡;¤Ä$餄l«* Sǧg—oš]uquúëßþöoÿþ§ð!ДQÑ™¦«&ã±håéË7ïÜ{øÉ÷ÿHé:‰Ùféz>A¬iKæâ}ä8ìÓ/þñÖѽÐwßo[ÝKÁ˜ånÜ5ãÁï~ø±d»ƒG ‹ +Î5î-ëëÍ­ýéÕ®©ºìxÞæ="¤êèªùxšUåf“ù®ë`Ú¶ Î¯-t0t‡³¤(–J(ˆéérb'JùóË…ø"ßøŒ÷­*UG ¡ˆj«ªªšGu¡’€·½*«f4LÒAQí–ÛÅþþáÍ6@^ÒWb§éí·>úè?$žÃ} Ñg¿yâx¨ÈTHÓÑ8Œ'Ož‡A{Tk#dM¼‹Å¶ÉнqP•uÓÙ8öϯWeÕÞ;žu¿Øä<¤›bp×sý®ë¥–¡ãˆíM¦R)b „afŒå.*ëÞ¡ŽCt'Ì Ž&Ab¨7tÂ0¢Ì Gþh»©Þ¿srû.wÙéÝb#»e‘2ðêòUÎê®j” Ü¿s³¹FÊ2JË¢|ûþ£—§§B‰A’´¹º¸¼¢˺ŽbíûÔsH‘h%„úþ½ãÓ——q:ìDO1˜M:`NŸ?KþÃû~ñwÿðÞh¨m/ÄqJv›Ê1œ—ð븮CšVPäEAÔ¶ S¬ ž}cˆè稒èh:²¦‚R ©+âã4YÖù4 ÝZ€”.îìï«ÆTV f‘·iúNt.v¦óyœÆFP­ ¦:ŒG‹Å:I}‡¹FcÝëÓåÍÍuìúë¬züöb±RiÃëPVn·µãðÙt\¬®yÆ>g”¥˜Mƒªí¬ÅwŽæëM{³tìE[fÕd´½Ùf9 YqR•:AÕuÚBŸû~èWmGËÇP9ögÞ½ƒ\F=:¾Ÿoo\êBH€ÌM 5××g\­×›7ËÅ Ž«¶ÂÐÆa ú’94¥]׺ \BH0 Bo½-‘Óï'oÎ/¦“½iç]® ¦ÁéÅDxÿÖ¶zÏ/¶«ùÞ4‰Ò¢Êu kQ+«ƒÐß–¹Ç#HÁ.˵€!)¥´–b­QÊ`Dû^b BÖšŸüÙ¿ÙÛŸ8ÌéUø1F¤(V¸q2¨‹ØC¼wpÏã¸J*úLk­¤YÈ•¨9Aë¢ßF¡®ë¶ï~ðÁ«—g$pçÓƒÍz©‘ÚìV­ŠYô‹/~w2¿£„°6Uu4Méàìâ²·ý$I>øè÷Ë¿œ Ò B˜ôÃ&… gEž¿~þäᣪ¢Y/.“A|0;¸<{9Œw;ÑžÜ}«.Åzu==DñávyñàÑ]îÄ”€;hü"oöîÞÊ–õn»œÜ´­ò124¤Ã°©ë0‰ÆMÕø!u\Z—"Ä Rì¦yþ_ösâ8ï<~ô½ß¾xu>Ÿí;.4­âž{½=ç®gL÷æõ«7¯ž»Ž÷ËúåéëÓ7ë7Ï_žvUõé×Oʺ£ÐéÚæÅéå,™Hm.7[¬] õþxdµ]n–~ôñöì¼jó·ï=°µqzxÿÁ››àáìà¯~ûj:MçÃ8‰†—ë%Ý»=pï2Û8sÂAW–ÂÔt¯þ·ÿò¿¼~úòßÿ‡?½b)¿}ó¼êd™o0°œ:Û<»3Kš¶j$Š=”ñéuÁB¸ŸÌn–U˜ú×»u]#î¡]Ýl—«hdëòz±â¾Sÿõé%âÖµëºÃÀ»\¬ scŸHò²¾wko±-‘¦eŸIƒ†ÑàfsÑ÷=PĽ¼îOî@(Û²N½¡C½þ§?þÃ?ûA×f²­F“Qš$“é|yv=ÚçÇž¿Z¼9=N†UÓ·MÃlÊмi º$(õæáäV#»ŠÔÁÜ‹VÙ6t™Ò–`øDBU=cFa0¥Õ—«¢—*NÜ®ë»^¦qh5*ªÊuœÔ‹Þç£?úÑw‹6×ZÞ½wœ]¯Þ{çñÉÓ‹Wo¾÷É»÷ݽ>ßT²—¸S›]<–ÕÚëp £$ʼ9½ ¸>s‚ª_»~¨4Xm¯}žÞ^oW½1 ÓRûÃÛ ¦ºb`âh©)`¯//Ó7J'Ï_¼ÖXNâÁ¶ÕÏ^?ýø½[¨º¦„­š~˜ø·oë¬o²ÇÇ'Û¬Õ@XÑ Æ  £dµ^kêp ËÎ …í‡*e%e]sîkÊJ6˜ÓQà»br4¬ÛÚÅ!°(Jß 8¶PÛÆ@cµjNîíûy|ÿCÆ{Y¡ÑÁÞ¶¸ÄÆÅ<Ôº4½å~òôågø£Þí)t9~+:B ƒ#Ôçfôf[|pç8oºmÝìRîð/žœE±;‹üóëõÑlúâbq{< ÀöB®7Ëïçán×®ÚvúZÖÅ«ªv½ «‹Ûûû½2JNqo¡úÇÿìÓ$»ŽS–‹ƒƒû×—Ù0H1󫺌ܸi%÷ý4ž}ûÍW³½t:œU­-Š›ý½[ÛÍ’×I IDATÙ«®(‹4 âd\´kÑ·wöï/×ÔE˜p€ 'FY¥¬˜ÌW7+­ôh2êE‡0@[H¤j†Ÿýü¢j7¾c·õj<œÜ~ ̲F×ç瞯..~ñ÷¿i„¢D>}~¾¾YpÇ[ß”éͦ ¢lµCXÓuq#e¯EßÛ˜’8 ]ÇaÔŽ÷Ö[ï\/ÎFA©[5Í»>TZeõnïÖuÓWO¿þÃO>B¬×7º»Fz.t¬:Õ©f>ŽÛFÕq…~tïÎüÙ‹Ó÷|àÎ{žížÿÑ' $p8Ç„dyªò²¬¤ìW׫o¿zþöÛ÷fÓ9ÒÈü®©ÆU”ñlWþô?ÿl³Ù üp»Ý´]åñÀ KF„ú¡ßŠÿ…ûè²ôL Ãü¦/ç›Cå®êÜh40† '’RGâȲ­Cíìãc/¼ó¿ññÒö´iѤ$ŠA¦8NÆÐ±ººÒ­›¿œßä…üCž§ÆæuIˆÂ±ÍY ^o*[†iK‰ šØ–Å™’f‘¦êIZ ÈÒʺîùª”K0ÙëºòüùY¯ã*ØŒ’mÃWwªª&Ô1nš¶×é<{uçð¸ Ó$˹ ¼P@+jáYFœ–ÿâ~ü½~¤**«JÏDUö&Ñ&šmg«t¾Xo±Ô:»ÉkËë­’Ä30É“2wT£bST¦B×~» -]ÍÊŠ Ðuœ¨Û8@Õ‹ÍLS1” XQ‘†§M×ëɆgMêémÚ–SUQ Ʀ–e–•æ¯ãUv>Û^ÝÜ|çÃwÃí¶ÉÁÁ­/¿þ,­£¬È]bU TuâùÞ2YBDÅÄ1£åÜs»ÝNU&ë¤Â†RåY¸IÄ®ÝMêm•p<¿&±Ô²Šê¦Õt+)7\à¡×‹êøÙ×_ÞÙ½ey%¾Õ­ëÊtTñfµèúž×y{ö6a9‘ÀÒ¢h]×Q’•¥bºiZXºa;vIKÛ “¼eÇ·g‹K]Õu6 k(³ ;/ó,-&ã^‡¢¸ÌËZ¤yIO˶,jC7ó¶®+ÖðvŒ%"‚Õc÷öýÛÄ´* ÛÂjk©f] Õ€@"ÓôÒ|ç›Eˆ[lbÈ9$BÓsÍpuCZWQQbbml¢ŽõéÕå73®6@p[wViquu)¡a«:!XSTÆ ¢!F‚ÑJQÔÀ19âYRCUJ)+YJÞÚ¦4…ëƒý=¨¢‡'ï"‰Âhé»®fi5M RLՌҭa£ÏŸÿt›Š*§užö¯iYàÛIz¦#M¥H …•,ãîàÕõe{Ý)Ô¸ °Û1y}/XÄW}#(êZ±„í’“½;ÖX½9½,[Ò´©ëªEÁ®eêš]ÓZS°†ˆxÞr$¦Œ†ÖsÛîpPK„tl!"lÛšvž<~5¤Æ Çö%ã 7è7u&!¬Чã]S‘Àqš™†& ¢(Í+ÊZE#×Z…é°t]7Ic ãå6;žŽç«_ž½úèñ›ëå"ßÛíõ5©žÝœûÉ7g‹Y70Ïæ+ ª –iäiñÑûeƒóœcUŒåÑïýøço_9®“ÑΤ“¤5g¢×÷UEPÉê P jÏ_|urçAÓ”›m¤ÇLˆ!¥,BÞðƒ[÷£h%‰„x¾S×…F4^—DDZ—_[‘‡õåÕ©køÝþ(Þ,TÛ̳ ¦v•äŒÕ@a¿üå§óË£ƒ“ýÎClmA]×{û«Ùö׿ü‡÷~磛ÓËí|ãŽ;°†uR˜ŽÚ– Øóí¶’P¾^V”uÛØR iXÎ)ä²å’B `F]¿3›­Üþ0Œok¬$Noæ§oƒ^?ÍóëM'PF]¤«Æ0ýîØãµ–‘¡¸-k\WßßÎXåzŠ¢( •š©ìí?Ȫ•¢•˜E•VU©6ØëÞÙwM'ŒòÃé­0®v&×ðR‘wö÷ÃdC©˜ŒF¬mÍÐÐ ì(Ë\CÇ* -:>Þ³5]·ôÇï=øCAëN&qàw¥hªI˜¬!×Fñ*~úô+×…›‹®½—¶LQY“·;û{׳«n÷öp`7ÉÍAÿaÑdŠ%uèsµºœX#âZÛx3éì2^¢´ýaàèY“@ ÙfuS—Ì3p#Àf]6¼2 µ.+!)¯P[Ñ¥–Pò¬‰¿ñðÉÞxš•Ñáñ]ŒAž¥¶æ@A=«{sþäï>=¹}pyy­ éX(kä& uMo(“Œ¥uÎPKN’MQ7ìp8®ëÖ1í¤*Ê”uüѺºik9í ¥äiÉ—›ðå›Ï¾õá'*cÑ:ë¸;iZ_¯7¹£oè¨çöª¶†å©êv ‰% ¢A€‰­)ic T›†YªZÒ!ôÃ~£×”Eå9 áBQ0ÂÚf9ŸMë‚ýöé¯ñÉã²jR0æšNP F @wÓ:a†ƒ®³Ý^)ªu…ƒžƒ‹” t<Ý™-ó4‹'{£Í* FÛÅõþh7‡ c|9¿ñý±¡³ÅM[¢ß}ÿ[ó¯_}Ýíõ—çÿíÿô£tÓ:ƒ€q¶Zdº®†ã< uÓ*²DÁŠªaÚÔëÙfç`ºY¯×cm®é£%gL׃Ñdpss¡GÑJm…múMF9`ñzËøÇ_ü|~½ØæÉ£'Û’*ŠÊxÆÄN²­gwUÍ “øÙ«§M !‘ßúÎï45­Úd<ثʦn3Yµ&1ÏnÎÇý*¯±†}gˆIÊd::ŒŸ]_ÜšPʱ"kʧƒÁ`w0xuy©kŠÕ¼lvöŽâpm"›A…åõËçÃ#Z7§¯_rAm³§êÊùÛåýƒŠ´Ù;:²køþw¿ÿí;£ãJ²é`šæiUäCË×Ñl6w} 1mzt iÍRAX˜Š›'…ØœÖëõêÿüÅÿLrþ¿üoÿ×ÙõËËÕj±J0À¼U¹,¾uüÍa_wuUÑUH ‘E]^¯.0•Ͼ~—é£ýñ>c™mmË!b¢áUU»òïþ⯫¦e„®6e#TTç4ptE#³›„@Þ²Æ v^¦»;Ã8J S€K‰¢Ú6­ä’ö7ë¨.@T.1Ašb-· KS޾zõ%A¶i)q™cb´šìeëÁXH!³åâf9_,ïœÜŽÓ”¶ôÖ£¶ÉwŠPk+rîÊéÍ…¡!pR¥–b•YËjµǶ_¥¥Ò¼¬0% +Û¹XEÏÙéO’²â’¹†Y1*¤P¸Ê¡€ ü®€P`ñÁ£oÞ®öwNnX¶›$œ‚!-äPX¶“¬ÒŸüúïÆ^¿(*‰¤„DÐëhÅâ´0b-ŒÊƒéh>[ä'Pu\dõ­ÛwÛºn+¹»?€Aâ~àIãéîË›s)Áýûï(DD7…ªjhÆ­äQ”a ¡JÞ ;n×晴Õ@ªJEI©ÒÖ ã\ ÔP ÖUòÌû÷Ž}¯·XŸ«š¥¨JY¥D‘Ãá4Ù¬ün0¿Üàéø°\)9·]@!éu½Mº–ïyÛíZ3`UËA0¨›LðüäÞ·1-gëu]ƒ£ƒ‹›ÅÔ*Òr|t:/ß|Ýжëu $¯/ÏFÃñÑÞôÿù·ÿñßwý¬É÷‚#]ÓövGý›Åµeë²AA7àHÖE³Y,îÜ™¦imÓ ãëHWL½•"´x“Þ;¼z{¶\ÍîÝ{D0zóòÅxwGÓÍl³!¦Êªb $ŠÖV,èö®¯VϾ~&1óƒa`{ª¡ª#¥€yåw{B@EËŠÕ&ÂXêÈõ}ǵ̣½»W¯}ßa”#•4U‰.$8>9n+†7wß³ŒNËh.Þ{ômkß±fË•$Â5Œ´Lâ<ï;väb½ lû'¿úâGû¬Ò¢›üÉ÷üóïý€TNËÿú÷ÿòñÝ'û·F£ï¼ÿÇ?}ÿÛ?Ô‘¹óÎÉü¸åÝCëÎýÃqwjÙõ—ÏNÆ?úÎï‰<ß,¢ñþ„11Þ=†J¦#c½¬ZW~0d2¿¾~ó⫯޾¼\¯«ÙåRWqÖC¯×*X…¦¢¡¨§oŸÿ«?þ—C„…ªê«ål4D›äËçÏ’åªã÷—ñòäáí¾ßË«­e¹m[ ÁUE!Øx~úEòu¸vMJ¾Xm¡„ž¥§UµÚ†®­åMF°¦TTÕuž[ØçU±?ì\l¶®f»'ðæf×%’˜ ¹È[©+*B<Ï(‘èúz3õû×ë™ÊUGW›¶âUuUH&9ÐUÈXs÷øîÍüª¨èÀŸ%ilÃpíÅâjL(Êßž¯>üΡ™MQº—¶›Ó‹ûÓ?ŸÍÖEÆT„”aEû¶³IB‚•¶¦£‡€¶ 72 ¥ƒe\Nw‹;¾ÿH#$Œ#ϱê´ÈЍå QÕË‹Ó;î[ŠúÕ³s.ÅáÁÁüfî;ÆÎ`ΆGú£ã»÷h8¢Žç4ñÚÖÝÕf5஫ñÒ²Œ¢iÛJ—s¹熪¥EʍY!ik!#Ðlš‰ öŸ³&Æ lñxÚÕ3ËÛ&cMÕ% HjA¢)+g§Ï¢0ÍæçX³s}stý4!†}Ï£­”H±°,˜$Hu=õz3;žAM†ël2Þ™ ‡ëõj†{ƒAÛ HpÍÛ<¯5 žY4 +¨jªªe ±¦ªIUè¶ÚwÝ秘߹sçäa”5M];¶‹U"%†˜Cˆ8k~óõ?1ó•qÊÙq·Óc¢•²îú^ÓЊ®w}½Pˆqûðdq3gŒöü I¶”ÿþ{¿ùõçM•"³‚v<çhg¯(«§§o'ÃàW/žßz4úý¿_ÜpÙ8Y!tM]fm§£SNWË¥nA¿Û§EV*9@A@„(Š®ñ†¢–}ÿû?DH`‰¸@”VŽå©@ (ãÈß|öøÉãÛµ@€3¢y”X¦(òª3°l]5°× 5¦®éEµ¯ÊÃã߾z¥ lxæ(P¯×kKÑ ÿÃóßß:üéŸýÛÃé]Àè:ÉWI:vmËìŒFŸ¾ü¹ahì½zóâÎñÁãw>Ö]¹]-ÇK’ðäø(Jã0ŽÛîô—7s+ªîsYõz»o^¼a´îtûAÐ{úÙ{GGnWs¢"E5˜€e±ñ½Áf³õ;2}G¶E4źX¼ ×QQVR"*h`ããN3 .]‚ÊkDÚ4É-½—†©jˆïþàû¦¯Ÿ¿¸MûS YuUm¤9½Þ``»¸ièÉ£Ûy±Œ´m<ùš¯³í*ßjÀŒ³¢, K´mÑ ö$­OöîkZïÇø£®Þ·5ÿ¿ûlž¦{ÓÃÝÉxhøÆÝÇûU]L÷ÍŸÏ_0m•C1Ùu~ýÙß½8ûò§?ûÕ›ó§_œþõÏþ~†äºÆv–ަÝBÔÝãƒ:' …<Ë“¶n®ÃÚµnÚ×/ÏÆ£[¯ÏßDç ·m#ÍSÈ€ë«Y–´œýòƒP&ˆŠ¶óy¿?‘‚åY’F5²a[¡åzþÞ{ïu»ÝN¯¿˜]˜–ƒ ¢$¼º9PŸöFYÏÖ7–î á¨Uú]ózšakªÄÊÉþqQn%G½^_9[n§£žL2$ ¼Þn¦AO@àn–—¡¶i-ÇšoBÛ6ÿs—]Íát”eU’dXS0$ަMiJZpbëçË›®ê½÷ÞƒëÕ…Œm” ÄšZ´%«@Ñ1†›ÅÙ«·oÛ ˜†q—ñ½ãI”µrÍQZ&–³ÀD2¢H\Vµb¨–¦IE|ëÑû§Wˆ$l[)»ÝaUÒÝIWyqö†(JÝ6¨¶—ù*°@²]c¢"¢x±7Ý“äm#ZêØV+™”$Ywú#+gg/'M+±”„@ånç äµà•ÇõòdÍZÅëø††lÕyýæìέ»MÕ&Eþó§¿9µM&DspüèÓßüz8 ¸TYUbìOo½yùUÕ–o´ÚDqzŽ $T4Õv첬¯?o²e_&Y¯ã½Én^¹ãÁà˯¿šŒöwŽVËÕâj1>r› Xš£Ù0LRSq]0Ú2†»}жLÕ¢œÂ¸-!’¿ÿ{? \§)kÇEbZ:1 V "Z™X×o’_½3Þ‘µÑëYŠ-Ulmn6£q¿Å"¼¹srTU-Ádwänâ"J¢Ýî`³ÞÎὓù&^®–ÃIÏR:m[øƒq0[%On”Uq³^tºF´¥eU–-GBˆPJ5Mõ,#‰CEÕkx;x×ß  Ú¦‘å1çLÂVRÆÛ«å’åÅåln˜@…ºŠì’e„q hª ‹¤@\‹tàv11¯Ög÷o4L]Å!9T¬/_¼¦y qÏô3½Y-¢vÕwºÞ÷íŬàù«yR-÷w¾5=8øáï~/0ÔË·q£;;of³mœ8š¶Ó¼®Ó2/› ÔUIh™‚>yøîñí;½a°™/4Ëõ_Ð*‰©hˆõr{yvަ{]Ï«jÖ:𻬕­l}Mo…$–*°ŒÂ'ï>>½ZrÁUDo=Ùn7^ Ñ¶îö»“W¯_8ª;˜Œþõÿ«?ù¿ÿ×'ï}ðô˯ŽoѦPyüð^S— ஜ½½VÿŸýÞ¦“éåùYÐóY+<§—TqÆ“á^Y'’«uS¶JK|öúó»Çǽ™Ï@†ï!@1”ÁhWa§?©«@‰±f˜öj³D»n7 ·Nüÿÿuœ½-kžIÃ’?ø'?Þ®æ¦åQ! §(ÒÜ4,Ë2^<ûú£¿ûèáaT&mR,^oJ€dVÎõóg'·3š\¿M²MD£Ïþá·†¡¯ã¨ÔýÉ×oç¦îŸììîLÏâËãO>8~x¼wèZÝý p4zx|ßôàÑý#Hi(É2ï]Ã6..^Æì…#÷¾:}útûtÔã?ÿó¿Ëå‹Ë—ë¿ý«_–iýòÍËëóp³5-“–åAZÞy´OPl‘ä7÷o=Ö =I"%âÒv 9mi–SˆÀgŸþ ™Fd%)›(W0 · ÿçÿòcU% Æ@¨¶¥K**ª|yþöÆs;«ÍiåŸÜ'¬¨EÑur¡šækÈÝ›hÕä)+¸˜7«eÇös–×yÄnhj›ÁN¿ß€"Œ7¼•Žo=yûË,t²T£á¼¬rMÓ«ªéøFßïey®¨¡MÃÙto§LËm;ý¢ªl…„¶¢r ~P¥ô eK À:P…ë(2-Ì×R੯ÏòÚVÕa׸^†R€*ÏV›ðÝïÝóôÕO~úó¯¿úÒ Z]%“!kyUÖœSÃr¸„‰ª®TMÝnWÝþ°(›¶­:~7Ê êÀ鵜_Í/u£‹°hXS7P€žU­Š…í$­öv¿ûÃïÿèþž<¹½Z‡«(¹ýènO7hÉníìMÇóÕŠJzïðär¶$ºª)d»Ýöƒ~‹!Q"…ç9›õ¶?î"› š=rªBÛv Í$‹‹õÃ÷ßÏ’eÕ´Ó£} Ê„¿Ó©7Š@¿ÓoªŠ3 1˜Œ9Â’Øô×,X΄xïpGrhèv•mÞ}ðNQ5œÕ½`7Ï˲‰c ¡VÔ‘o»ë0Ô4MW¶¥Eú“¶¨5OE‚Ìnb×ÐGB‚Ψ¯)ƫׯ¿÷ƒïw½þéù‹Áijýh³q½ãõίÞ>¸w´Mêùz©«8ð¼¼iª²1U­h8ÑHÛÔ “[£îÃ{‹$ßÝÝki%8B*ÃDªŠ-@+$€B" –éMºÍŽNŽv&½¶¢›rÇ™­™º®dY<vã<äŒ Ve’–Yß Ê² üÖ{Ÿ¼¸xC °L;/+¤¶´®Ïç×»ûãýõvÑëx”²b¢…‚ÆEÇP¤ŠJt•Di•Å…c+y!°þè_ÿ€U kK×7Ó4”u:cA›–6†å´9ß$ó·§M#mÝ2‘-¸¤¼ê;Lp]7q’ž§«&o›‚7A·_äaU·ºjt;vK¥IE›½£“Ã;¿øê×k袡ùì¥oõG“¡øïßùøë—¿R³g¨À‘Ó[»ûêí›ôI€/7tµ®)$#³ª[… À´³²n—`Än?TŸ<øf¼¬Àñüàââ­ë8¶íUUfj&¯õ¿ýëÀï½g‰”@ÑT !k@ÓÔMÖ5€ß½wÿó¯žö<Û³- $¥M’^ñBÆa<[ÎþËýQÙÀÿá¿8}óÙ'ßÿƒó'êõý"¯„®i~õòåûO>ÌØM“ð›ëõûïÝÓ½þ7>xTÖ©oúšÕ©YQMZd{{ûiëš-Xé¹^ÍdI£¦lö÷ng2{ûâÕí;–Ñ<0œ¦i°.hÕ¿X\ª*ñ‚aš„œ×3³8qÑHdñ6*&Ÿ|ó(°®iŠ‚ dªj-6—–íx®çùv#?Í—Q˜/Ö‹‹‹«£ñý0Þ̯o^?ß~ÿ~xñæÂ3œAo¬¨ÞáÑ®«töFÇ{ÇûOž<æ%þäŸ|ðè½[û÷ÇwÌ÷îÞz÷ý'd\fÛÙð𤻣öÓϼãæ7_|¥é’kñÓO_¼zûµ·Ë8ú«¿ùß± >ÿO¯g¿úòåWñSïìüY’fׯ.¿|~:z‹õU– C×t…Àø½`±]ÜÚÝY¥üëŸæëÍrV¿÷;Ǭ¡¾ïiÜœÍWn`yzp}yöüå ĉ¡ÂLHWè›|fš–²º‰ÛS‘þúåêƒoÜNZÞšÝñj1SެN´Îæ§N§·Y„“Á­éþBR5lÉ[‰Àñ««ë‹ùÌ0”ŽÓIš¶Èò8Ëuí¯gkÓ¶³2]oBL, dÏu6e™Då*ºìwÆM›w»CZsÓä:¶£m›X†]|•®»NàØ^’GmM§Ýá<Ýî ë¤$7‘&OYi˜6V`Gû“Ñ2O•ô¼Á6É“"3M%Œ›ùvëw= Q’ÇØ@ !£À?ÿÓŸ¾¾yÑ7GѶ¢¼Õ’äM !-k‰ m9¢Vue'k= IDATµ¸5kâ´vM§¬¨&ËtÑZìTÄê2Š~´s´ÉsCQv;{;ƒi?ðÓéу½‡î{ÃæÙë×…XÛŠ0G@eÞ¶hk»hõm•öF½pÅe´7ž¾|u $·l½Nm³NÏ9?]* tUøù¯/‚¡Óï;Ñ6Ç€îÝ:š/ç âƒþ() 3+§oÞØ¶::8š]Ή"B{£{\m€®HÞ6¦að¦Ú _]½ô‰‚ÙÍü²ãzã7¬"ÈâÜ ‹hczKyn†ýÞ¦`-/÷ÊKÇ0U¢_^\ô:FÜ´ ­9Ï&ƒIQ&º‡†£É³/ã÷lCé]/®™RœìÞùågÏ!Jß9|Ж8ªC@QR!¤Ì«ŽoXD¢$pµ'?‚H-×…–ÌíØ¼•Œ UW°y^K ?ÿÅçi±IXúù«g6ð!ˆÀÍ&™N§a¸… 3Iã<ì9½¢Ì8g¦ët»½urÞï “¼ˆòx§7jš:ÎâNà¯ÖIR\M†“ºbq]b† hªª0Ziª±Í*‚ùî`fPÐÐ @ƒ‹<þO>BÒ?ûjÿhÇÐ{a’ø¦C°Þ¶ítwôËÿðÅo¾þÂ1¤®ø v@LŘm6š+›E«AÎ…Ô4Mµµ¼`œ1ÓPÛŠÚ–Íx]W”JÀ›ðÍ«ÓÃƒÃ¢ÙæYÞï¸ o¸”iZÞ?ºóðÞd¯û÷û—/ŸŸÇ|©˜°¿cݽ½»ï?ºš©ªÛlãnž—M+]S¡æu‹€ Hš˜` çsù½ï}/èûŒiyw;“<¥º­Ó†¯–›ÞØ|}þÞÚS±–V™Šˆ$`H!f-sGq¢:Jã‚J9캀 øåÍù7?øøìíÍ:YûNçöñô³¯¿pÍQà›ßxÿqK¢_üìK ‚uÄõâê½ï—õb³ ‹TŽÇ}Z·~ò!ÂCeº»wuõÚ2ݼÊzÝAUäU• ½nn¢ª({ýÀ6íh³Ô-,Z úÛh®Íu¼¼HhÍ Ý·3Üæš¡dɲÓ²–åEè9¾„¸ ¯´þÈÖT1“ÑíÎxOr­jSVK]7¹l£˜hŠ¡°’Ô¥`”.?xòí«ëÓƒ½½n0GÃ!9:8ØõüÀ2lß½mÙšß·…àvÇ0½ìz½^Ä×ñÏ8—?ûùÏ_\ýâòâ|¶N>ýꯖכß~vmnÖéüOÿì'&óëõéçáOŸÿµ™îÏ/7ë6~ûrÕÄÜ›èÛÅ*ÉZTÔêaš2Σ¸ò§¡ m UÑ1VÒdûöꊳf‡ãnw´;éù]Eq8l(eƒá´em«ªE³Ù[ÝíloVÈ^ÇëZ«p-@)¤5Ô¶:ï>yÇö.Í›ÅE4-x}u6»¼FL欭Ëü`ºoXz¯ßÍ“Bp®c¼mÊ8]&I"ªÜ ¼¯ž¿¸]Ú0Îò4 zy^I!oM‡›ŠsÊ«2,94‘ôuä€qI!§¬Y®×"GUë– Ee-0?ð, $­˜¢Pdz£$îŽQW«íh8j9Ç gœªoó”`£ÈЍJ;AÀX( :íDu®«¤¬˜cÛ®c±†!ý޵‰ÛÓW/-]ÂÄyVÑ u›Æ]ןÏâ²¥€2oU¢(V e\ÞŒÖË’"üþÃqJ}ÏúöGŸ8È.›ìÝ'«¼ºµ{°7]Í–P!wïÔ•Jë÷,ÀøfsvzùŠ–ôâÕ-cÜ4¬ª®L¢Õ­Hë¤ktJãdnkÖt4y{}qïÎ]IÐõòbox¸Íó(]ôýQQV«d}çøÑj½YÇ7Œ#)•mrã:^‘Ñ’Å6qʰ*iéjV’óÕ²×ís&CoirçÖ¢$jÒ:´ £(YÐó6᲎*×êœ/i”ƒÞpôúìÔ ,OW †¥Ê6iŽã•yžFÕþÁAÓæ¬%šª¸®Éji^žG¦ÄiÈakh¶kØ1VÔŠn­Ãy€;‹M!8›tû–å¼xóêÎäÐu‚›èÊ5í"Ï)e‚rJ!ÐÔ´¦•Y™©ú·Ó ,ë8ŒýþN¸I¦ÝI£˜C!œ_Ì™¨Ãzúù—''eV®£ÌŒ¦•YÙpÑ ‰ò¢tÝ8Ì€@ž­RÊ•–­¯7[Π®ãªŽ0×tUfyCˆ QÓT M(š¦¡5$RJÞ4LH„T-54-«êmYtýÛï~¤»†|w÷h5¿6 "Âi  $¿y{¶ŽO…‹ÕúÉ£ÇXUad›†‚Ô<+ö¦Ãmœ`ˆ{¯*¸,Û¶¥ Æ”ÏQçët4žÄ‹J6¼ùî·>¾¹^$õÖñÉj[†×F¹ÐLašÕ›«‹¶m×i˜„çg/§‡;÷îÜÖt@ Ôw»’óªn"\rH0@J†D)ˆòíoãÉ;œQ!q]VB0¿;*›B@>Œ¶›í_þÕ_âý£c]ÕjÀ1”±’R΄ªCÅ’#UU×ÑæþÃež3VpÞ»wvñVÕ@X)“Ž6©Aêõï|ûw{£Î¿þ¢7&aF4ßÄ\‚“ýõfÇÙÞîAŒ³Ëù?þ!¼?†á m¹ni¶°¢¸Y\ݺ/ÏÊCÅëxYœöÃËË7D'·öNâ8¯ëx0Z¦{}ýÆõ¼*Ï$ØÄ°* :ƒ¶âËùìàÖ>mh[ñ_ñÓ´"ïvº¬’X—‚¢()‘B-lbi5e1¡„\P.€‰ YÇ ¯.¾~xr÷êÕUCËñx¨W¡kªgˤª>|ðøé³SÇÕ]SLiY:ì÷£Š¹žÑqÍlÃ!†³ËHCêä`²Xlǃþ`<¹£ÁÞØvlë~×É“˜Qf9 F *š®çKl0ó4êvãéÛ‹`¤ „ Fôüjî8®m™‰À– EJ°Tt?úèJdºÊd<ÍãR€ÒÔM³ *²çªJêÿür±ºÚÙ9¸8»Bv]÷âb¶7ô1º©é–1êONßœ;¾AST³ëu/æó(J)à®nj«š•…ŠU¿3ŒeôÍt«ºª*Æ©¦›:„RȲáǬh[PY•©FtÓò£íf²?>>¹k˜jn{ЊF×ô¶AX•R@8³Ë‹—g;ãq˜nó$QU˜…‚5 ”U¸ìûj’3‚QZÖ¾¨ª"Vò*è;›E2[/£a¦W¯‰¦#¨m£do²3ßUq÷áQ¾n~ûÙ«u²­ j¸ÏQãMÒ”øæúôÕ›×ÄÔnÝÛ÷÷ÖùbL›¦5¡†’BpÎtEå aLƣν“{šaÕefé.ÔqU‡¬j4Ï­’už¥ù~Žß{çAœ— ¥k‚KL ¢è®¡RZŒÎû7¯óÍ:ìxݼn±´²*Ã[RÝéŽ>ûâó;‡»ÁÎd< ã¨×ï¤77?ûô3&[€aà(%YÎ'Ó§Ï?ÿàýOnßÙuÝ Iò²Þøö€s‘—a[Õ½Þ~’†šjp*4˲T …[Ç6}38»:íì¶5M]S( ÆŠª7Ú«ëªaM¯;*òB0FˆfÛ~–G*Y×mµ³³¯@u0>~ø¨ª*Œ¸am%\' ¼º~ iF¸\_ 8‰"‚ë›Ëy¥Ç—WŸs(?ýÕgŠÙ¬Ãôoþþ/(Mó´üíÓÿ÷ÕëO_|µ|ýâóÍjý‹Ÿ…e±jšŒ¥q.%õº~•W\‚y˜ÛºI³ ómÆB ×mC«Çnž^kow|³L_¾~~8ÝkÒ2­Èk{¬GQµÝFÏ´êºÅ:Ž’Ä6- œ6p0í|ôÞ¢fÄ×eVHQk†Q¦ÔsW/žGQÚ÷‹"ÊŠÂè‚ãéÝͪP¶õm»Õ;'ïÚ¶ë˜N'èśк’7y”Çɦl˪©F“ý®g©š‘P‚Ô´´m# é/öÐñèøìík˵#7Ë-¬mè|»& wûW˵`×õ‹¼âBp¹]ÇÆ@݆ëýI?è[ZII5þ¹¹°• ´\—bv³NvF ckyŸLŒûƒm—Ãþ lbDŒ¦jÜ®!Ð4X‹†–­¼ûD7õÓ×/Î._m’fs|4/ŠNתªJQ¬«Ë3US?ùøGžm£éîAݦm#˜hÃqÕ´EUª†!‘ QkØvËA”ùrcÙA^†š¦3*k‘Œüe;yW¬6,; ¯ Ó¬+¦ê "b1ß@Ììž )Êíñ½ý†Ê0ztŽ3P¸–¿Ùl Úž·YÆU›¹Žýòå«¿ùÅ¿ÉÒò?þÅo3yuýzù³û²…­¡«¿üÇ/_¾yf0÷js˜ŸŸ.‹¥B´zèfgKË2UªC(*` †q‚ˆ³ #¬I A ,X‰€‘V…¦bE ÀÙüjäõ§‹h+9t ¢jªšDÁ`›fešvŸ"šÊ4Õå:Vˆ4 -MêñÐCÂŒ³üöñþƒ»ï§E%o¨ëÖUÎàlv½ ¾ßþê…?p¥TA*€.,Çð\k45f‹°jªïqßë3†kš𑮢ö‹Ï~Ë!Ð åüíõÑá­ƒý)Q ÎZDPU5–Іί.)Õ±¡„Ñ\UíÎdÇ1ñÑ­ý‹7—«(1t ˆº–¥ ,MÅÛ2#€0.8†’+†MÒº¨þºÈl¥55c¥c™‚rÊØ ×R¯¶ï¿÷(ÉùhÔ“¨ µ¡´\&ë»'G׳ժu s Ï®¯!‚a_­6˜Á(-Óºø=*A”÷oͶÑÞd¿g;ì;¦æéîîÁÉÁá­¨ëø¾oCiÛÚvT¸†IÅ’2ŠïÝ~×1§‚@´­ išælÓUÏëvG“/^}éjj¿3¢ªE븎o˜®Û/,¢5Ö-•˜i¸!º¹;:Z¯/{ý1¥Òëx^ǹYG®¥>¾÷èfq“W•ïš—W³^gÒëu€FD˺ýþzµâÜ÷a“çRý½Q™@^5ž­ŸŸ/TìLÆPª"«c›ŠX Ž!ïqÞšf9Ž¡Ù m‘apFP‰ªÍ·7N0”ªÉEÅ«J×M f¬bTÂ8¹ØßIÒ¼Ìòƒ½ƒá¤÷Åןwƒÿ¥ûlº$; Ã|RŸÎùæ7OžÙ€° H(Q-Ú*ÛU.úwÚ&¥¢]MªHSXìbw'ì¤7ß|;wŸìöyžŒú1b:1  1ij&6ëå|z„x ‘åZÎíòÚuî,Ã,vƒøîòîÅ‹ÇB¬¡ÔiØÖÝd>M¹;l==«‹îînɉr€Ó·¶S¼*‹X¾ï·CûÅÏ_„A²¾ÞÓ,©«¢/Äh¾@–AX–Õɶk;IÔ‡¯¨t[=D¡C”Nò¤“UìDЂ/ß¼™Ÿ<òº?¬Ë“À ‘EÂz¨¤ì7ï™è†Á&¶TCœÐò«¦ÍF€ãåv?_ÌçÉ´(÷ÄABHˆ±ç1!!†Ú”8e×Z+%ièþÑÏÆKb MbÞ°åò.Íc9pœ¦ÞÿÃßþz¿ßÆiQ¶UÓå£Xôm¹0öÜÞ¾ŽRB4ÔÖ@`DÓ(­y呸k»(&–öÓ,ª†reÐFŠI4Ût]Ã…\ï—¶ƒ´E»‹½a\ ­é²SB´ò·_¿]¶¯'ÇÎxq4=Kþͯþüð±Èϲz£ÐI&úùôáŸý»_QêmVKêbÏ ’h ©-IÏêú§Wx~|* ÄÈâŠ;¶c!§˜QÒ§qYql6,´l?Œn~øå?}ýæíwï_&#'Ó7ï_3 >}ø#?Œ'çß}ûÛÓ‹Sš™¢(^}ù¯ÿôÃ÷ï.ó4ÖÌçOsÖeõ£òñÃR²>'D‡»Æò±l­ ‚b³Y„µê´«år<›"€¹TÊpÖv4È«fg´\D£ña·€J µ•Ôërå:¶åÐßõ›¯_™8Éßýúïïn/_~óîñ‹Q×Z&ugA×Èò°öü„ XW‡ßýî××ï÷—nòIðòí¾«7_üâ¿þúêP­§£Œ No„ã;¯¾~þä8ò¢d€Â,í÷ýív›M’UU¹ÄîÐ×<‰‚$MË­ ",”>=:ê›" !4J c²l!9/;ç90Cd‡BrDÂnFërÙ4Ü·0S}/ƒV=Ž2²êúÈ ê()ÿþ_ýO K‚)õ,ךNkBE}½Ýüðæ·ãÙl踔u–Nëmá…Ñ/ù/^}ÿêþp—¥FÎÙÃGS);΄›"-ùnµDi‹¾ûúëãŸ|ò£x¼0šC7®o}c°—OÓn¨ë¶éYE ¥1ŽC÷°ÛŸ=B6¼¾]9˜àð|šÆq׋ùtbc¢V»öÎ.žշ<’ÛõÕùÃGqwíÚñäìáõýÇívþþò=¥øãíêÝÝýf³å½üæ»w ñ© ›²LÇ™KBן>}úÜ·ü4ŽçÓg±®Ï²À(¥„~ñÙ§V·n˜fy<>:½¿ù8>š&^lFn—û8žZ€7EÕ4ý“gOŠv`T«Á- <(ÇOOøøú4;Á@2.ŠÖl@±›úâÃÝÍi~ÌD”ÀÐõ&¡l œ][<:@·_Ï&ùôÄpÞ´¥e{‡ýv2;ÞÖ‡C{sñälhYU6Âô²W«6¥CÙJ* ãlo—÷ÛÃt>7JWu5šLÚ¦å}Ótžëƒ0´0~ùæU–T>^ZÔ®ÙJ2 C€lþñr;=š„¹ü°2J÷ƒ1%×mU’N·ÅµCèñƒGw›«Ýz﹦Çó´Â›ým>h%Þƒ$™ %,ä²®&ÞnSÖ‡ï¡$I­Ñ=>±:¬üÀiÊæÕÛKU…?\~Œ‚Àw‚ßüú»ÙÉd>Zt{ÙwUà’ãAÒA©¡B+pqbÅØ£wïÞ¤“qd–çDq<°¡o:hIÛr¯®.¸üööz=Ÿ* ¶Ë vlä@Ãq7èÉ(Ūo5ଋ‚Üñzµ;¶D6¤ìuÍkj¨qÑuŒµŸ>úäãÝ­íÄë¾0Ä8–+ô Œê8«ùŽ6Æ(hA-BÚ|òðGŽK'“À`èš8Ë='ìy%YÛ¶–—Zµ/ïÊ¡ËÒ¤¸U=Æi«¬Øm‡Öp”¼ø ¦«-ì{RRgd{ Ó•‹©ïy‰¾æg§§mßzÀßqsw…:ÛËãÝn äùÀZV‰N±Û––g½vÏñ-(ñn·yøìqSu}׬4±];†gˆõr1¼¼Â”äã,ÂX!…1!žï®î—¡;XíËÕ—ÿí7û¢{ûîªmän{ ÄÝ©ŸÚ®íb)-Ó^6mA0½|õÝ¡ã‰oö«<õü`òõËߤa )ëÒ§¾êÅò°9=¾hwâfyyvþÚ~Yl€g‡ú@‘S×Úqñt”ú¶e,qhYûzEôPBJ Au'j²¤ÚtÄ®o×Ûz>ƒvE='~à¯W[JPèÄœózè²0–Ò( •25g¾ëm ´|ÏÂ>|±HÓ hލK°®ÊuÎŒfM[ì‹R)$…PØú!õ­ÇŸý1ï‡õú‡xº8:Êß½{ýì'\ۺ߿÷ÂðË/¿A·ˆ³—ß~¸^]{¶µ\>|r1Šó¾í!†œs®¦Ðq’Ë·¯û¶\Š cûÕ͇ÛùÉ\bò»W_'BB ĹZçñx’G»²ô‚x”Å›MacjÄVU•œØEµ…jزíoWJ²aP×w«¡«˜ ‡}—¦ÀsÜ4Í òã(ûñ‹ÍòhÇ“ñ˜@üé§/ÆÓ¼-Š(–ãé16òhŸžœÕ))ƒ ³¨tßw“×ï¿ÿôÙóÉhjà¶ïú¶çFYFŒn™zôô)ººë\ÇQ ¼»¹t„–ƒ:;™oÖ7¦ç§cÝ3-I”Æ»Õ>ÏÇÈ…ÛûÝb6Og™æ<ËóÉÉéþþ‹:vèûÅÀb¨C˱±ÙÞÛ$FÖà{á~[h›ÙÈá’K8XÐBÄþpõv:Z ì Ô†n ‹ùðø¬d’™" \ÛÇiQ¬/—%!d~¼èËmQ§ÇgzP›ý2Œ‚¾éçg‹ÙqµY+¾xöó¶­T'ÓiS ×µ³ÔQNùaš‡ÁXrr4Ónö5Å^´}³¹Úæ9ï íl# †N8‰ãy4õBnøzsïX!@Xl®çA,d©ëleã÷›÷A<[Ì'××—ÓìL Áð89º/VCßc‹²^£0¶0$éØ%$sv¶páBR›a 0:–+Ð@Ö¥þÇ¿ÿÍlš¡{wswzzR÷la4ÍŒ¶ë5Æ ,Ú»õý|1YoöeÑûsz< ïúžqçQ)ŒÐh”9Z(É¢ÊE4 óšíˆÁÄP¥e?pÛ±æRq£5YD!¥~þüøç¿øÕîp Â1† ×Üpj9íZüõßü§ÐuûŽu]sz|îû¸ik€aß3‚0÷=wÜ gÃÑlÖ¶¼¥û Š57?\}œsLpYµ]3XuLŸœbbî–·Ož<®ûj½ÚG±g¤nwE14J€8ˆ‡ª¸ðB‹+ôÃ(«j³_n¶[àTZùtš…î'ϾØïî 9üÉÿ qâ43 IDAT@p!Ø`Ñ ÌÇÛÕ5qÝõ¶øíW_á‡Κ¶£ØBB-Ë"WCÇž¸cutUU‰bú¦­Jø“OžU¬Ú»_oŸ^Ì’t4™N¤bþò¿ü·Ë¢ƒ46ÙÀ2 (‰×Ûê¿ûïÿüÙãÓºëËfã:a>š+USâ,×·=®Ê¡ØmmÅñèæúBEYUTãt|·\ êœÌrJwÞsEí¾†ÔtmO±‡ Ô^/7y2ÞoJ!6o¿ûx¿« S⸖ct~òÅO’Ð`©4DH!U’;ž»ª7×Úvh™ÄPß¾¹ò‚i‡DÎýæÚõý8­öK#Ðl4Û•âõ¡|{:šJ!!äk{I¶¯Li6¨Àý2FáŽȲšªÀøv0ôC«„çºÊ^²È 7Û²ÅÓÓ“Ëw·|h擈q¸Ün&Ó¼ë„1ŒK_k=ŠB$$°é¹Ù'éɃ]‡C×4m𦬫1ÐM[ýþ˽yqX—ÅšM§oîßôEɈ€ÏüIWïÛº6œ¬×Å_þåÿ>ÔÍúÝúòõ-çb[Sé"{>;Ž?§‚AX‘LËZÞ^¶»4¬;œ>FV¢µ›èûwïdž¬swµÙ¿ùøîâô8±§óë/¿xü¢>€7ïîËõåõf¹Ý\튢8°ÓÅI §Aâ&a|2›Ï&ã/°PON?úü“¾®éx2V‘—ø>Òj˜eGW߈Ñ$gõr](JêCË1ìç³ùÐò0t'Y4™< š¸½¼?¬ç£Éõíýõê#AHA$YK)¾ßnŽÎFQˆ⇀ÁAÔÅͮϲLñvhvQšyž_o:fÉ㣙èz¥d×ìã8KRAðñ‡¶eµŒsB ÙÔ/Yw£hê¹Q5t6v!T©¡ÐÅPÅ!wòN–o¯>&‹C§ë›:ƒ4DÀ^6§G£tºÛnlÛ#–ca¤V #Šý06RU…¬®\š²®šÊ#nQžã­ÖÛ{ˆÆ i‡<Í“l̸ ý@)f[NUîʦ›æGqv|ˆ¼˜`B‰VJ6C‘Ey– Ö»õ6JsDÓJϵ)!c]× ¥2¢žõZ)׊ϧQj£(²ß)˽¤C‹Úûjw·úˆ°ÔÆs,H]eÙİZBœÉ8ë†.Ëg ”zmÕªr¼s6 Lq8J#ιV°ë¸m‘Ó“cÑ ‚³ãÅl<™¼yõ- plmac°e;ãq²*·~œœ/ŽïÖ+D k;uß0Î1ÁÅ߯îÞ½¿~}ù¾ê>œŸ=9>qÿðêÍ¢Ož?‹’¨köJ +H5VMY§Iì»ðÕ›o®o/ñÉùŘqˆ‚( Æ(H)FT£ÕzýãgŸº–½/;ƒ`æ›} lKÔfšç~L–ë›Ï>ÿéd’Yó‡¯&~ù‡Wãt!zGΡiÜÞ]úãŸþë_ý´m[bG–…Oë¢ÇPH٧᤬ etÅhÍQšR«©Ê$Ìßx;ã0\ß]I%ƒ0#{±}·ßž/ØÀ¶û­Ei$BôŽï9¾ÿ‡W¿ëkµÛ7¾ç5‚[ö¼ý‹ÿå/D"lA#¶åÁ•ãyé({ùõ÷ëÕàР­õt‘ÇÁÄs„@ßI’X6М¢±'{>™õ²?;9+ÊýÀ„ȲÑ0 £ÈȤNÜð¦Ê·Àuš‹Ål$å¡bBÕmëû1Åx÷üÉ)ëø»ËÏÎ}?(»¶Jh°J’ø°¯ …¾ï&€%:ÆdõŒy¶»Ýþç¿ø÷£t\”Ðp”g]ÃŒQébÓøIðáÝ÷ûC=ÍÇAˆŽyžc¸6À.·KÏ›h•»eóìé'YŠ;ÓÉ€0-›ms(.Î]\´ÍŽÚ¡†©ë5µÍê°m6]·òhÄ`g¹|¿=`~þlôäø“Àó'£(‹§«ÕΠܘÌF#ÿÏþÇ÷þÝÿúÉÃg_üêóþP4 ÿ£ÿüÔ›M§NüêÉ/'çG£YäAk>C£3ÊF“4F ¿üøýùbb,%‹|KôCúégŸ®¯W¡“/Žæw·÷†iⓣϼÈ%ž=Чã4³,‡©åØ£<ŸLOy7¤ÓŒXp4=ïŠUÅŽ•6¶ƒÐöifcRÔ»ùèÔ£>ö­ÈKŽN:¦’Äõ\¿áÝbrR÷õíê(É™¸º|C-G Üvuy(ê¢m›Æ³m-ÍõÝÕ“'@ ‹b×Eñì ñO5 ²)×â°/Gƒ]Í+®¡}͘TH«·oo¦óc¤ºÞ|H“,½û¥k;H÷¦aì Vaiq­Ú¶ë;†,Œzã.ß„7gZ %XÏ,J1a´ME-Ü·“l4™ Ö¬înìVCåAˆ¡[4…ïy4¿¾ú¨!˜çl[Ey°!FôM´iÚ!Fª¾i”±’$¿¿º³l ´ˆ=JÝ««›Ä?œ(ÅeÏ5쯮¯}Ï£±óíËߟågÐUëÝ.p²ó‡³º…¶k+ ¶m+øà…D2A!Ž¢°/X:>€ %|?¢õüAÕÖ{Ë"ÙËûýfy`‚ÏuiÚ±`u4_c®nïB×w=wÛ6ùxÇV]î×­šCè„õzÕÖm5HÁ$Ï:!^ýp=™f®ôCoa¸Ü¬š¶™d©1cÒ=THJÀ…dx!Û)ëî³Ï?{úä“S`$‡OŽŽêº„ 8.\m7øÝ÷©¥ST*Œ\@ P†õB£ÁÁ¼(;×!¶Q“tQõûØÉ|7ìMM !ÔÙï–aœŸ¾}ÿj:YÐ(Zíïjn,h3Ö'Óc&6²=LPÕÕœ›Å8­êÔ¨éû0&QRwCáù⤩™c….v¿ùæãÛ˯ÿñw_ß\ÕOŸ~úôES7q¸Õa‚%ïê€Xåüý?þ?~ø´eµ¨F"æ`Úr–x¾m¹ËõV9O²ë»%p´9¨ív¿é*âØÉij,ðÿü櫟ýò_EGM×ì7›G>ÿÛÿö÷]£¶Ûb’…Ùüøå÷o=Œò$ùñ?ÓLRC8ÊF·÷7L i¬‹²QB¦ã„uÖ éŽØÔ@®6ÛñôÄO¢ûëA4å’eQèÍ „ŒÂÑíÍ{€ÀlzÖTÕ jÛ¶6ØbïÞ¼ÿî͇|š´m5·)žÌöýþâìDkˆŽ¢¸­;haÇ÷BûÝå¡olð]›7m˜{ƒÕrÅT;?;VM§¤DÛRÛ:Ô…Epè¹××WÙøˆP¤ ’Ìç±àRI­a·ÝU£h€Âh l‡D~Ô3É8‡‡ž{¾O-²k}«mìj4Œ“¼ê†Aµ™;Á×C‹5ñ߯8uÛâÚ–ÐÒ©‹¼,™Lcß´R”,­•í¸ ¿ú«ÿmPÍ£Oo—¥ú8tê¢ÈMòñË?¼þÉϾ À>ìãE6§‚ Æ’Ñ%4¯%èÙÀÙƒ£‡I6J’€K*Œb Øßoîïïîxà æc׎ۮ¢È²ÃqYnÓ±ç¹^UmÎ>}ôl¾ˆÇÇ¡oçs? <äö«b}{sÿ‹Ÿþœø0 à !GGãxâ),•”“ÅQQí¯ïoŸ¾x$¶Àÿ§ éxtõñŽº~6Ÿ•›ƒ¶½øh‘ÇÞõvýüÓÏ—fÓÅü|¤†ž)üôñƒª¨0²Ç‹º`ž?r]g³0ñ1f.v06^h÷¥db  TÜ÷C§ÝÊÅñ À@ I«ìÚÐs¢8à}7JS Ò·o¾=žbHDЮcWƒ”ìvëivacÊx{É“O(âú¨e˜,Êu$zÐ è¶iÆyj{žçyÛíVpuvt¤ ØîÊ ò(¿½½¶,è"ÚvLn‡Ôhljº»Ýj2ž@LŒÔõ4䊉ñ|ZÖ:ùtf”ã,ð|ÅMÝ1 ¥2fO)USùÁÈ÷‰MQ[Ad -UâO[PTU;I'ûÃýòn3 Pv‡Fjx¿¼{túZf½]Z˜ºIÞÖÃ{DˆÁÆ£øf¹ÊS•UUìòh9dª–tE£ µ-÷æúe“‡Ï?^¿· Šâ¸( Ù×§‹iÕ€–\0Þ ©¹-)@šŒ>ÿôÇvœ0´Õjdr|އH€ŸBƒzÞ.7ckŒlôñþ P¨—z¿[j²4…Èò’´iÛª«D%—ûýAp;ŒÂгyƒê®‡@äÖ¬ZžŸ=¯ê}54ºŒq'ò.m`E^l9î¦ØÏ'’º«0\›À³FÔ FÇÁŸý«?Ç„´u›§ [mWaB,d1Þ»>úÃï^r‰ÃÐ)‹jà<É£}[ªÁ¥Y«&ÛÕ½0ÖÐqßÁÙRe›¡­C›zcié; €œñáèèLˆCúA£¦¸Ñ @ê ¼À2÷ÅÚÁ¶ÔÄ÷h»¯ºº.òhTv¢ïªØÉ‹C§-I‘O²© t¿j»–‡ë_üê‹Åâøîfk;Æ¢n]׋£Q_ »ÝöìIþËŸ}/œc„…RRHHÏex-clŽæGQìîUÇY–¶m-VÊáÓŸ`mʪxûñí|òÝ«—OŸ?9:ZPj‘÷»o_ßüpû'ÿæŸgIü×ÿù??úYÀõƒÅÃéÓ³GFƒö»å²ëÕÙƒ“åýmW€ši>cõàx.c}šç\몺7ÆQä:ÎíÝít>BHÙ˜j8HÕ[ÄE„³®!Æq’°ïz¤7Ìq¼¶ê¯W÷ï_~0\j †®÷i±ðY‹óggZ+-͡ގF©’PKŽ1 }ûåo›ºYmv÷‡åÏ>û|»Ýíªõóólvùþí( v’$„Zû6É‚À¦|зw·GG‹®na“YŠ CâÇ1Û3JM}à E¶%-'êù°ÚÝíûžM©€Á´"¬n¹‚”¸†è›õ=`<sÁ†‰y>fU§WHfi*;18šÏʪB–xúäÓÙt!°¨S•‡|šƒ¤_³NˆŽ•å~:;½½¹ö\Ïö‚õîÆsèÏ¿øçWß p˜ON˜è„–›½E]D íþ྆UÕtF#'4m-¹l9Ó|°óY:™íFNà~ÿÍWA>‡¡hµO‚ù“ãÔI‡žk‹g^ Q´ÞÞ4û]SÕÒ°¦Ú3 òéȧ>ãÝzs‹ ¡Ôƒº-v¥ç‡HuóÉYQ×Yb/OõOüIJ̡ß=¼ø”º^³ÛKÑ×U7›Ïëö,Û‡Ÿ|Ž-ÔÖ0pý$¬ÎÇsÍ(ç‹EÛ¶à8K<;H¸žÇ}úè1g¥’{M<DzÔ‚^qÖÖŽátU\Ýîö¿øâŠ„³Ù¸î¶v0u\pØßífyÚ³…cß§Ä£F …¥ëÃvÉ‘<ìîl/`²ïEÍ…² šdcnôÛ÷oã0´mÿÍ»ïÎG6qý"’%™1j¾˜e:.dÛŽmYW= NÓu¾ïÅü8Zvk£¥„žo·Å.|ˆ€ë¸«í~O­ 㢩¥†¶ƒu1Â60LSË‵ÌCþ8Nš]D¹Ø™JÆÄ|מŒ§%oÚ¢qˆG©íÄQàØÓ’©ÐuÚúàdG«}‰ cƒ‘ФYzqY—«È;yûáמ;¿Ý»Ã:ð’®oÔy’Ô¬ó}?Iã}[·mçY¾Ðq)2öÑädq2r<ëîú¦lÛ$Q@jÛ6†ÆôLhÃW×7›¢0^Þ\…A ¤âv†EçÚ›uIÐ÷‹=„@d{ÔrìÖu-ÏÏf‡¦¸©šþ~þóã£Gƒl‡¶K²9½–Êq¼ýf÷ñöûÕŽoëÍñè$ɧËû³ãù˧IÉ{×q$VJ@/¯nß„n¢µRƒ”R}ßmv‡‹‡§O?+š#@°¥”fÚ‡¡Ú ¸;lÓ@®Ww»Ã&Mîß½íö5du}}º8»ÚÞV÷éâÄ®^űë8RH Ò¶­<ËŒ'Fó®lu“ØñÙ°µ¡K°+A/]Ò÷»Ãªˆò cc$~{{3´•G ¬¶Ûa` e„j WȲCÄN84lSnŽ&ç]_ïöw®§Yr8Ë–õ%ÏŸ=1ÐP±í°Z„°§!°Bß5Âô]†în]|ÿê5µå8_ÞÞ,N§³dv¸ßŽfY+ù«÷o?ûôq>Z\]^?yr‚idc2]Œ47MY%ih;˜i>Š!EÝ·M³#˜ ÁÎOŽBM35”M‘gQi@ÕôZ ˆÌ 0ôB(çݳÇÙŸþêß#µê !u[:­$ê‡^õ«×¯Z^cŽš¶§I=JÉx’P'xwsÇVÅ¡|œœÈumÑoMÍ›££ˆ5Š!4Î=0Š7ÐRÕ?´ìñEòöm ‘õðÉTiKHuþdZÖ=4ƨ褗øÆ4Ð8QE®+¸`jP²CÈ—Œ—u†#e”c“ºgqè ÎžŸíSJìõêÆq¼,Í_~÷û/ÿ›¿ý?>{ `Â8˜"¹á Ï&õ¡1X¶¼›ŸEÜ^ß¼xñ£ûׇu¸åp½)Eþ‡û‹ÉíÍMç¨ëì×kÏu}ÏÍÒéвý~;!ëúpØNNnËmà†¼ïÝGAºÞn”bI2Jã£Ë?Äiî9Ø ØP–íLgY[µ«Íúñ“gWßÜüÓ—¿ë5×À‚ØžÍzF½ÔFÎ"¹p"Ï Vdà e¤!¶³ÞÞ\^½½[ß+©«Jœ.£ëdùÑöpeá¨Â`E´“GŰ÷ÀØvìrè.fkVS‹:ı]{hJ-/t°æ‡}©ˆƒ€j_WJ) ´ÑÂö¬¦\ Oœ!ZÖyn`;øãö&s"L%€(ò}‚Ô$[(£Ã>y‘éz^Wçâ¶©ç@.ô矼˜ŒFJs/I%ïyרĮõ·ÿõï–77ãü¨lï¾{ù„ éº«·ïC'¸9Ü•–ºSUj<Î{)ú}›OŽ=×ÅJ7uQ÷MSëÏŸ~ø¶Å„`` Æ:O«jxõ‡o€aéôtsw(7b@õ-Dy­@ŽçFG¿ÿêËd2Oó1ªz·M²h¿_Cc!êÜÞÝœ=xÙ»÷—6Á‹Ùɶ^fYº“(ŸŸÌÑ~:w£ <Áà|>Ó’AèX±…lkN’Iºº¿FMgÇo¾ÿmÅyRjQêB^j ÒdÎyk„β³£“ܳíºnmxžß´|׬‹`ãul Âù¾<°vðH¸/ÖçëׇežO秇ýQx~»Û/¦Gß¼º©‹eåJÓº®ÒÑÿ¿Qeùx¨;â€t<)v%çÃÅùérµ>¬7¡ë ý ˆ¿9,)¶ˆ¢-o›¶‹âˆ EÛtF##7¾—઻¢)¢0¾ßßwûa4šç‹¤*ì`¥ljƳ³f¥$­w‡¶l1²VQl¯×['y:~óñænÿr©4løÒu¢úÐ#KV]¿.Ê0$æ'E‰®WÓ“ê¾–°w{½&.tmçêÍåì,Mç÷¿‡F™Ô¥ôÛ¥öõíÍÉù ´Éòþf4™Ú½¿»©Û2‹’íjïXtÍ0èÙì8ãzWŠ¡ën 6®ã¦Þ„éù4rÂ'ÏwMQ5\1•Úꪪ”ãÓÅñl>9+V;˱}?qíàätGQÇ™Æ* “²×åP¶E³[V«Ã½4°Úh £ÓûíšXæbtt»Þo÷·ç£Åû›ûZ¬?Ù¬÷£Ìw]»¬zúÌŽvËž©¡nzßžF½Þ}'’ÔmŠárWçîëNj$îP±¦Waâ°a À Tµm?(bÙgG°AØVZ™(ÊÁmÝØ^ Üoªõ͸Fr.AØö]HQÏ)WuÙ~[êYoÙþæ°ùäÑîa÷ëõé|€½Ü—®çv\ÔÛ‡O·ÛbsX¿øä‘ð›×ß¾x1ã}ÿæòM+ËåêP¶œ5EÕÊâäd¼¼¾ß톓³S¦XÛ¶6¥œ1°ï:mgœžÔuNÂdþô)ʶ]h µm¥5†øý‡W_~óUì†M]ZÄu]«h„ïøauõ0šÕC9ÍÑéyœFˆ‹Õ~ˆ%a)Þl6Æ €AU[Ÿ\<<;=¥–]WÓ\Ii¹‘äU], ð¤f»Ã-ÌóÏJîªËlœâÔn¿9Lfç4¢ƒ46¶7»»ÈÏ#?6F%ON/öû­Míñì$Ëò8 µ¡F›“ãILJý~q2é‹BÜ ¼(Ëßw ®[ÇvŽOÏ»¦ˆÂÀõD’MxÐµÝ¶î †©! …îb::™~öã3Jƒª–¡‡ý0–Œy¾Ûw÷¿}ßëBKÓÔ*É}— í®Ì'¡QˆZ€²¯[ŒPX“®ä“i dƒÐ€ùÄLjb¢´P£dÒ4ǵ§Ù鮼ÚNâ93&$“Íþž@ aA­¥¶±uqv̆Ž+Ö÷åÿKÒ}ôÚ–ˆa^yç|ò97¼{_¬Div³›¢º!É‚‡aØ#<0`ÀÍ#Á¡åŽ ÅîÊõò'îœ×^{-ô+¾á·ŒÖ†®ß§{IÆ0o«ºî‚ËzØo£ÉôÙÕu[p‚éÅzýÇú^(·æ§ïßwcŸ¯¿¾1 oÖOP 0"¤íaÓÐÛ¡aÄ@kŒb©¢é{~¹º:%§^S×vmçñáñõ‡s¼”—Ÿ¿øôÃû·ç—›¶Ï¿{óáÿ§?ÿÙ/Û¾êEûoÿú߯7‘? ãä8Œ½ëzÓÙòãûßרÕ(¥hꎚ†x=ç§ãq½9SRÉQi”š†&…ÆŽ-x¹¹*ËLô£áj¶íN "B× Õ4‰mÝü—þ°ß&};Ú–n1‡£èâÍf©1¸YžÛ–©>ʶo:€ˆ­cº¼ïnÇ;B¬ŸÞ}hŽcÛm•²ÑP›>E©Òôôùõ«¼,ó:±-«­¤Ó"ŽÀÄsM·e… Õl{‘•ɨצî3ÍÈ‹¬-›ùf%x;´Ü`a%^Ïf(‚*K3ª››åBˆ¦¬[Bßq †F«.Ñ Ó134rJS;´FÐTyÝöÜ0µ'çW“IÄ4hè~ÛÖrhtfƒB˜õÏ:Jˆ€k8eßOçî°ï5Õ!QÎåÅSAZǚÅ·˜] ^‘»˜®«ªE£Fún{ÿå/_H1A“iFÌ»Z×0!Îûo›.‚ÖÄóܦåÇ4™¯'}'oÞ|\•C/¹d:+’ÄÖÐåÓ'Û›®ÆÜ †‘!D 渡N Í$T¾7CHU}‘Ýr¾Tpä57uCw q^g“Y¤ë^ÓŠ‘×IVF3Ÿ*v¿xr=o“²H÷›©iDÛýídaÙÔå`¾àªÈòhæ»îôþ°µƒ"–æÕ(Û°û®ó#³®š¢éƒÀêzFƵíþ@ðPç#1ü0$¼ìZ…¦k«/ZÙÁ—Ÿ¿8>ìLêÙuåh0·äy|8H"5d‡Ä …FH×v¼m©í!CKö÷]ßÌfTaH“c\v©AÁ.«ß?üôüÙE/ºíéGWs h=$÷vàW¥Ü>î¿øâË7÷=¯}ÛR’Ý|ü`P†ÖñŒûû£jß6@OGž\Î0@RpÝÖãº~þôj¶ŽÊ¤’ãÍ¢üT{v`šŒAf:¶%ÚÄÚ¶a†‹u¥3›+6Ÿ&³1$˜ ]Q\¬žñ¾…#r½XxåNß«ûÜ4éñ0¶~8%Tëû! e Ÿ-ÏûªC¢3ÍHG¬—ÕÙ“ Šèaw¿>[ÕÑñl‡êmÛ¦Uòå³/tqÑœe#¥$Î6 ê°À3y7˜Ž5_Ì¥ì %Ó`M6üÃú'Ò]ÛÜÞYEl i!Öl³Þß¾e¦EdDŽ%$«±¯ªº­G00¢sYQÆÛ¢œ²@¢ÛŒ1D9ÆGLÙb±,ò¤hš³ÕYVe„ŒŽëYÑ´EY7UWÏž˜ö›_çÇRgÚ$œ&‡ØòSÒ5ÕßýíßDy3Ô#"²¥¦ó°n‡4/¼Àj.p|+Œ‚^4€ —”Z³‰9ÔÜtýÏ^^ Å`ÙÁ§Ÿ>?b¨H1Pç›+Ûwoï#g²\xiÚªWUiiVÝ5TÃÕ(2†ˆn (ÜÉ2®¶é#H8¯/®Ÿ B;7ŠLÓ¬«x}ùY‘¤£ÏŸÿÅë?~Õåå$Xæ?{~%ÀAŒG€45J Ôm×¢³™7 $ ™;ñÚ¡o+Æ(ÎC¼ýô׿ê’”Cà›Ÿ½ü<®ã?þéëyþ¬oÛ2¯„&“Yßvb¢c/˜ßßßi–†3ÁeYÄŽëI€Á8Š›ªrüP·ìº.äÈÃEŸNÿü»¯û®s,KJ8Jnšú2šIPE¿üå¯,[Ƕk„®9" iݘŒð?~—$[ô³õ$Ir¥¨°«/Ò¸(ó Ü3<.¸„ƒãDev8Ÿ­ë¬$Ìæ³lH’ÇùdÙ¥ffšŸ]_¦ÝâaìÎÏæ‡ÃÂr$àÈu<$çßÜg ï“ç«Ýö±L à陂‡ý>ðͦÛVQCE¾YÔMZ„P 0eäju±Þœ‡‘°Jâ$Ã^ôЦ¬þðû¯M Sª¦ôtfÓ¸ŒýÀç}ûäåY)‡¢-mÏ„ È|ßéÚaà\´Ã Œ¶«¨$‹àÙÕË'QÕM0P@ ØÄÆÛù— –^‘Ö§Ó)˜¹–aowq•&5{,2¡ãí£Ô­Õt6vÍÍÍý< ÖáºlùìbÖ×­f4µèFƒ‰Anúa•@IÚ¶‰¡é®jªËJg“Š—eQb¦ë!Ö(ÅÌeÓ4µá¬w÷o0„At¥TJYŽ×ÖUàÛm“ù¾£c¯i+!׌ú¦d䃆Vgèðá´“`˜†ë›·ï0eÑ”U½¹Üe'Úfóô‚w<Þ}xúéÓòoø8JêºÆ=œ¶mߟ]%y}ŒK «z¨·Éz91 ³HÒ"O.¯ŸIcºƒ;ujêäöm'U_UÍdaTŻҶLÌhà]-JŒcÕŸeq_Õ¢Üßî£I”¤8L˜à¹£M9ÛÊNYÙå‹õÅñp¬ëœé@ÔÜò´ÉlFfZ¦>´ÀvMT׈¢Í†¾Ëó¬oKDz€Rçëµç£k3Èåí»Û‹Ë5Uúßߘ¶Þu]Ý  S·ÆNÎ7˦©òmªÆ^ É1ŽÂ1l]cB„”AôƒS|*ŠÎpLÞ·jÄ£jxÛNƒMÖæjyÕêR¿\mž>ÿ”êP×cFϹ¦‘¬8ýÓW¯zеB×-ËÔ¸”«õ‚pZäá$ڜLJÃÙbÁ £QǸ{Ü>†ng)oÚ³óÍñ°;ì¶*ŠYší Ë,³ÂwÜ/þåÝÇÛüŸ­Ït¤’‡(ŽÇxÎ C˲Ji»6’zÞ$ƒìár1[}Ù—@!8$Æ4š¥Ù©Äz½Ð\b#« Œ†…» ¢0=ÞF“K É)ÞùþŸ]^#E¤…’SÓ0Õ¤’ L`–URŒ‹é„`T·5„Ð÷-ÙXg7·_>»JÒÛííþüÅõ_üÕ_‰®ùæ«oû1/N{Oþæ?ÿÍßþöÏÖ›åÝÍëÈŸX6ëy#:Ùð|µ8¯³nàeÙìr? i4ÐuªˆJãÆ°,fc Ì×ï¾¹zzíjN™åŽ =hªn²òòSUäÙËO?)Žy–¥–c0bÔU~Ê?¼ùæ­ÂyÈ2.%Å"Í‹º+¯/?·4Gc¢Ac!Æ Îùˆ‘¦›Æ»ooîn\×´ý(‹:Hiã¬;•UoŽÂÊ´&uÙjáB2ð±Ä"ÅNu†Fe!  oªûÔ3ž?zwóu|õô C½mkÈ:s©ÕîP"ªµ|4úêIxs—½~w dwÜ׳,CËŠNùäâb—”¡È÷ŠB¨L‚0Š’–Nâ´úüË«ùÜ+³v€Mzµ€’P ÅÇûÇßüóÀ›ªê1ŽEÞÞì,K}ã:Kδzw³^?Ó0Â¯Ò ézß}ÏÚ¶"¬Õîx¸ÛßýÕ¿ùËë§W}Sš5ôÑ3¬2EÇ'ß¾y«DÿìêsII9¼j'Óµ¶ gn‘Ç×//ž¬Îê ½`½8å­n610bUYR€yî‰V@m]’ÓÝÍç|²ÜtcåzÆruy:n1Aša9äÙq9930²,³íñ‡þÜ#n?×u<;jÛ^×̪¨mßyùìâæö±“õÕÕÕiŸýéÛoüYX¶ R£bƒT$˳Õz=JtLöÏ®žäE ”ZÎ'h4ê¶å¢NóúóŸ}2€¦­:;0`Y•1„!ó4[N6†IMÇìê‚R¬vÊ«Ýñ.Ž?â‹Ëà €JB„4‰i QrJg“Àuƒ7ÝÐdz@#lHŠüáÿâ‹WH ß}ÿÃÙêìtx¤îž2#Ûկ߼qûön§1ëW¿üâbò¤îŠÅÙÚsü»Û;@5‚qèûiZbD Ó0Ái|%0 ‚Q%KÒÓt>3uC mÝÆ¡·–@¶¼5m¡é…,.2Ë´gÑzŸ'–cØl¹d œÙ¾ú¾L·CO’¬²ŸÆÇìPd—›YW4ýˆl“†žWTe]'TPÓ³—nÀ Æïe7ަ‰ 1•”§øÑÐMÓ6/ºbh»f:F»A ~öò ÕÉ^4†g´U×W5€ˆ £##çCÝUéJ€¤,fãZzš&Ñ´\Úk[];Žª{ñäÊÕ&ÓÅÜõ¤(Ĉ`€„¢¡VûþãtÆ(.ó:¯ÝÖ±P”0„ÔîÃÃÏ¿ø\Bž:ƒi̶ÚB¦u‰Áb“í²û¾jÚ²ûäéSŠ1‚ÈAÚôU×}{Êùpsÿš·ÒsQdB‹¨^Œœ!H°Rˆ@ Ä"œv}ß6=:bª:ñ1{d–­›^ß&«)ˆE[ç¢ã\äm÷‡t‹Í“ó²H³¦bŽ3›MÙ­0LXšÝh›®åf²Ã.x·y²:Ñt5ÑF%FÓ´fgÑÝí^µãÄwŽTwÓD/ Ͳó´=“À ½÷ï¶âI`UuQ7ÜŽ(&¸¨Op$¶Œ Ò $5¯Ð0ÃÃX]Ìž >$µO&3¥¡¾ì g^U§‰;cI,?Š¢ÉÃÃÝù³+€±ìúùr'ÇÉÔu}û¸¥Hzn´½ýе mZ¢i”вÎ{Ä=ߎ³ƒíz³yp8Úº^…“ÇmáXÆÛ‡ýó矓ÃÝû÷”2´¶(4Ñ)Žeñöæ§2‰!Ö˜åÙÞ‚,Ï붖ز,ìs aY$ÝÔÚ¾ì{þúÇoG5Bæ ÞI9¬Ö×÷÷ùXÍçs¦aÞõ:³ÀÐ¥ÇÃ2Ú”oñ¸Ë¤€Ÿ}ò©`£é:ûãþٓˈýa¯ä8Ÿ¬  Ⱥl%mC?žb°éR1Œ ë«ó±çIVš&áͰ8Ÿ=}ö²ÉJ ôh³,G(¡eë»Cö/_ÿKY¤­èó,Iò|»{4ˆHtUW§9Â< Ïê¶®úbäʱlƒùöÌÓ B±CL­nÚË«W¾«ûÝ÷ËÙeÖ&··ÛÀõìÐÙï÷«É옓C±YŸåMÝ—=fø|5»Ø"‚CÏfšEm#ËŽRàÕæÒq¬ºŒ™©„uC+Êv½XzQ˜e¹t¶˜ Þ[ÎLPp:>NW/ê*M’Ǻhž>…Ÿ¿zéhº‚A:B¢(ðukà#e@ú´nw&ÓkA^|úllÆw·óåĤæ›ûÛox~ùrwЇ¡ÿÓßÝ_Ì>9ò»2îïï¶Ÿ}ñ2;UYÎÿõó¯|×6 /No@:“iP¦1¦F¸t‡AÔÒMx‘à Ò¡¬»Íú‚][e#G¶ïDoÚSˆ‘4ŒÉ86ƒì˜fÛ–^„F1´˜"ŒhYe“ÐÛ><>n($”ÚMßSFx \SÓ©˜Ñ‹ç×ÁÔ‡ÀŒ“£Ò4Î4ZšyûøàŽøÇ×o?ÿù«¶j_|ëMíY´|øpÎýÀžNfSºã®tÍÉdj‹VÄ§Ô t1pPÃ&}7@5Š÷¹ÅŒóë‹›7oÆn´Mgîϸò"ºöùÕÓ4?( Ëéx#k<ˆQŒ)#+ ª ]oûÁÒ5ŒpÇÛ,OuÃÇÒ5)"¦"MèZ]1ÞïþòϾ^_B<ê†qØl›8ºYå"–»äñøæãA˜‚@¢A()ØUÙ/_¾¼¿¿D·XDmÛ·:äm&uùÓ7ïM“`!»†OÏ¢ŸÿìçJÀ^¶#mÖë{~Ü&i³n¶Ïòc>rEtF3†”Twõj5;íâ,?x‘;³Öß½þ»`¹º_ö…¡3üüú‰‚PH%Ä ¥º<°}‘aRˆh?¶º¦mΧÃîxóë_ýåOnAÛªq˜Íæc ºZœÚjµ ˆýíß|EÁèzV–¥qQÿoÿÃÿL,ݶË&zžïÚÞññ–0¸Ú\mo Ue¦mB9 ªªš,'mÓ¤Iêù&e¬­F‰{…•è¡nÒ,?Ž'ŘRŒÕ´¡˜Ãú¶4õ Ëî¾ùê›c\`GoûJ)BØ:&`Ñ›'óOŸ1†¥â–9E§”„2iD++ùwÿøŸ›&?[=ÿêë¯t¤Ù8*ËNöAÌ8fÝT·»‡W¯žKIÒ"!:‘ÕuÐ(EõlklyZd^ d>îö†Fy?x~ä¹ö)Í)%Ÿ¾ºîzœÎ'iRGî¼éªA ¼é;‹QŠIÑžeö¼U¨AàˆLËéE[§5!hDíØ¤Ðæìl³Þ¨êª˜D+9ð–×DcMÙmÿéX IDATþôæë¬,ê~TRyŽQ–-D(¨ Ú•c™ÑW3ÚeÃÂ7Ö‹³ºæM_/.ö'‚q÷ן_½¸ìû¾m;•ŽÍ2o ÇÌâŒËÞ5yšPˆË6¾¾¾†:Á¸Z,Ï.ÖE]¯WjЖËë뫺( Ò •–eiõa‚ Í48ð醂‚PT7Üq)#VÑ×XaßVm1Œ]4Yv¼:Vз93ŒäX2¢Â(bX¿¹mš6!VYäRŽmÇ!•¢Ã0e¶Y,Ú‘ŸŽGË0t]Ëâ´ÍÒaC# ÃyÜî%¤QŒbCGlJ) 8þâøñv-!$Ò=û¾¾>’$ÞϦSÝ74Óíª²Úébùìü"Ë Ã0 FÃs¬éÝíÇð+jÚL§Î,œÒ-Á˜jÚtfÙDo»!« ]³NO§Ø°Ü¶ R„ÒÀ›Ç»óÕ*Þ¥ûd÷É/~VÆU×µALŒ¥iA4)â’hÌõìªl "„j„Z\a˜ŽÕs!ú®—£aaáÝýƒehŽ¥INæ}Wwôm׳õLJãz}>=Ÿ¦§òjs=‹&]-ë2]D‘c…ý€~úá' Óp>÷‡iÖ0T\ †nvM¹=¤ºc·M z°˜ŸÙ¶1¶£blûÈ[F‹ËQ¶B*g:cT½{ÿñ·ÿájûD ûp|«i3ŒÈ);!Â>yõåëwï¤"T‡ãc’”o!G.Óy|Û<}þrÄÊqì®)‡ÝÐÉ»‡Û‡S<4íb3•ò£U’l«¢0 §æÙÃÍöÕÓOÈ¿ûî‡g/?Û7ñ!‘ð±'¸a˜6q›5Ë“—}gé®aêJ S„ÈL/Àp ,t\Üu—&e$ ˆë¬’êäºS‹zXï 3çžo„4=ýáF‚IVžÞÞü°¿Ý+˜FMÃðl´žÍ¾ùþ6¯sK7-o*x; ½AŒÔrñ~hÛR#¤.ŠÇ_þêW÷Þ§ùããáïRC3ivJö Éë}÷Ã[B¡a›U–»Íj¤D êTüøî6p# û¶n€€l‹´†\u¢ <ûþv[U…FYß/І^Õl ·ÛOÏÂét> x{óÞD‘Fì²Ø3¡}¼Ýáõf=ŽªéT¡AJ䨆¡ëL³e‘{º'€lëªæ`1÷Þ¿ÓuŽ#<´ƒ7”¢UÉënþê·¿>žr€q×ôŸ­võlmvžg“`uJŽD“&1M#Ì’ô)šÙ|Ñ4ÝîñÑó=Ûðª¼Ç~6_fI®ëV×Ty™L—K¢Àãý‡YØv´ÝÞQŠ˜Nu¦‹q` \˜¶­”üß~¿ß?B…{/´LbȦ÷½n[ÏŽ„è6“kâk6Å´m=ÂQ§&%4¯r> ‡ø±®‹‡›»YÚ–…¾˜Ìò6±4Ï öÝî&ÓE´Ø¦[‹ê–â67°ÖuRVOÎ.x%ß?|œ†Q×ESU]#zQ–Iàùƒn_?½|B‚ÇEf{nºÃÈ¿úæ{äÙ"xûáa6ñ—óÉ(Å pÌã)ÕuC•5©¦ëÛmždÅÅb%:¡jÄÔB5_-ÚªwœAT 3è(ÅÉúû¿9wšn!¨ê¶„È„rZš“ä[7ˆ¦©niÉŸ~zk0­k+ÞñÅbš¥ÙÛïßPÓ £éãÝÍt1¡:…@ ‹*µuϲtÞ}ßyÓ!8ôjèf2%%;„k°iòˆ "é,t]¯aUeHÊåâ"É·Uf´cOÒ5¶Ýô'îÐeQ† cmY•UiÛÓ´‡Çìšåù…i…7ïή6P’¶«}ß­‹"€Ï‹JÓŒ—Ÿöp——E0.S1º&R¦E2?~ÿý0¨I…Êô`ú K³*«N¶§}¼^?íÇâxÌÅ(ÜЊUÛu׆Çû8ÏJ5¢²Íø •ÄÔÄbƒp^öeݵçë«®«ŽÙ!˜®çQôðpãûÉéd6­[žK›§ˆàï¿ £©nëU]iš9]D–a‡Ñ<=ÄíÐ!]z!-³4òÂ4¯Ÿ\­÷û[ÊŒÙj.G !>»8ëAØ>2׺n±Šâ$Õ™áØóÙY?tÓI¤ëfË3À;]×Ö“ýjh2YöyÚ(Uo˜A]¥•ìt#Âhx<~ŒÂ o“¶éðˆ¢€i«Vt¼Lãt³¼.Ä6yl€ÄÄThŒ¨ë”™Že¤e1¦›ŒQÐqËÖMSý{wS¦±mû{ÃÔvǽgEÁÄå#¿»}wy¹¶µàí÷oË{èê<Ïg“UR“IW©ÇãÃùæ ’êawc{N䆜÷HˆA´³ós›…jè‰a1÷]5*ìÛÔôÚÀ[¢ ]óÎWë$~”ÝÍ£¬Ú‚ŽY†m vx:È/Î/ãì D'úîâçDNàXtä-¼ß}×4±Í 0òšDmt¶ž;š=ñ対t¸C¨ajLu°èÛ¾:}øioXîõõÓ÷oÞÛ¡}õüj¬ÅÃ>þü“§ERé¶n›Ö»÷'†€çcãäñù?ò¾(Jj2/êª]Ds¦ãº-«¸t]‹²±,AÖ¤bÔ˜a5M³ž/˜Nk^ˆ†[ž³8Ÿ@%uS¯xÍÁg—ÏLJˆ®)†¡×#Ì<Œü˜òËóÍØ $Ét1cdûdêö `Íßßï/f—u/‡bø7¿ùuY=¤EŸ–aô¿ú퟇kˆ)5uc¿» 'ÞÕ¾ƧA ™Ìu¦Yš*ÙϦgUUIÅÀ¶©ËQºfôxwçö,8»ùð:›­ÓGÙûžß5Ârì²(š¶ JVœ ;ž¡×·o{ÒE™Ò$UJ‚8mÎ.Ï·w è¯þÕ—¾ã÷=QÛ5bTê¬JÛ ²ìøÍ¿ÏvÑ•gF®ÉíÃqLM µÍP·ÃÓ«KÎñãî R!8˃ãO4f—u¡¤´·o{×Ò¤„`8;{*Ñw’ÄÒ‚¶kufÕEk‘!õÇôã‹—/4 ßß¾ìÕ!>Ò¥Öîxr-§lkD ;IQÔmê¶§YY_[.m«Ö0ͪo|möüÕK×ñмdm:všU„â4ÿþ~'$%Å`èL*ÙÔ Óè6NKÇ”€Š2¢Uíþ×’B¬õªÇß½þÁóŒ®Ûí^GÆ«ç/˜†„è4GÀ£¼ç777ÛÃÝl¾úúOßZ–N1mª®éú²lxYO¦Ë¦Åû·ÿïfsv¶~깚£ã8ƒ,ß! ŸÒÃæü¬ƪ*_3L79&–¡ªšSBîÇB4ÐW<ÍN¦ 몫ڦj(Ĭi–“éDóQ“µ.K(Œ]–äºmUiÙÖ£ãÙm]¶\ôC¯3kªî›<Ù{^4JÙˆTcF;Tº©wuÃ()ª4ô—Y¿ýð1t—ÞLûç¯O At<œN«Ëg¯øG4Û Rå.÷‚Ù$p»º+E§ð8 ¢ªî”÷÷g—¦ãí·TÓ ¶†ahE/Fj;®AÌh½:OgÓ—ºaÓÝÏ^}é:Þa÷þ“Ï?;úòtóãfqn–¡¼¦NŠú9kË!7ûצá¬×Ó4«¬œEnÕpŠ 7@˳MßôŒÉ1'èÊši:ÑÉ2<ËË®(öžeŒ@äuÇ1Œœ¼ÙŽww÷¨a¸ž­{)û@¡në®ÐM÷ãû7³©§yÑv»Ű\lª<•R- ^læCÝC)9ï]3(²Ì´Ô0ˆÀó u Å0Ž£àãËWŸ<ì?êÔ¶uëÈ€†‚cÅs¨é‡Ôë/&k×s€, j>úùr½ÔåMøîjuÝ”]QÆLc#äbPJ/‹Ø ”Nõcú¨è*º{8ލþó_þë·w¶f¥l:5?³ ËøñýÄÍåæ29&ŽÅ&“©AhÝePÂÃ.^¬BÆŸ~xM-Œaš$†G±ÔŽÇÇ‚l—8Vdù¥FbXбƒíþ ÛšcN|Ýr€ý˜TþÄùøöu'€iÙ]Ó×ÉJJƒ¤ëeÛŽ¤˜/Бºaضžd%£îÐÅüBéÏË ,SããØã0òÉzxËŸÞ}»¹8Ïãä!Ù2Ì —Ú¾U¦Ý!=<¿:ÏŠ1ãÆ}ßëI|£ÙÊÐÂm‘Y(âiæúr~ØgM%ß=ÀL×l¶·<›™ª®ô,?¦åÞòæ’wºe2dÚŽ?‚r¬’·M*ЦÀ@£Ä$!Íîo|Ëm ßß9¶MMJ`Ñq»nË"Nõ¾óZ‰ª)z¡FÓaÛ÷†cN'³,.Ëò´¸¸ìó^gr€† ÃÄ–éL¡o~òôÕûŸ¾Á8™mß MéZÖ!N..Ÿø†ñõw?®V‹©çgy§Çyž²bT#BL$”˜Ìô,Ûý»×lËIª\õPÓ²-Ž À!”X§xïèaûô®ÎrÑ’‡ÝûÍü F^=ŒC³;ÆáÌ%îÛá˜ÞÍü)fÚBƒ´ /«’slÙ%è›ÞèŽmJ úìevL5Ì&³¶ ƒŽõ „ÂNÜðwÿ»ùbaAZ¶Á*âUÚ êìâÜ2^ógŸ_§qróñƒa™–i1bæ]&„ÈÒb2_öJx–ízžxEž„ŽyßUµ[†—U^[†fŽPâAU‘Ÿ¯ÎŸ¬÷û¯’ôN—Twóôš!Óµº¯±RUÑRŠ,Ó}<•Iº½zòüT´MW2I0v^Œ½hNí«_|âjöýÝãųõùúI7=ŠÛž´Yý‹_ÿBt}5Vѹ·Œæe=¸¾w±Øì¶©îiU\|øx .kâAãÉ««®kËOV6”Ð5'ë«ùé×å¨;h·{LÍ ˜@ pCaà#ÔZ F)^\>ç}_ä¹!í®çAhº†}ûp‹¡X¹«÷·¯7×+F½,I%6:%–ºæäåÎ2YàG¦«Ù›ú›}¾s}3‹k1½¸Xmo¶‘OŸK¥FÑ?yú´Éà³gŸ"(nN¯^}qy~ýýŸ^ßfïðÙæ "8*€°@ ×uÍu\DŸ'&q[ÔšiRçÛ×?œ_^l÷é>=†¾y}~þ»¯þaWÄaÞÞ¿ÓB{Úr>ÌDÕñÿú¿ÿw"´ãîÔñ&œÌ ¢M[(Å8—›óõñxä|´,ÓqÜì”RCÓt-ðçBÛÇÇ0œÑ½¨šFwô¦)ub 8BmtͰåuU$;áÚ÷;Óõà¦a)¥ÿÃþC§9IœÄ â)9¾Uùt‚/ý§XS~ÊæEª4ð|¡dßUMÃ~÷ÿýñÕ'çû8Ϫt}=+Óêá_\Ì=gZ5)6ðë//×óUˆœ™71AÇʺ04 CäÙvUÕºn0b||óÖ2©é¸Jª‰³ò¨z7ÞùÃñ˜/WË¡…j†eFþÔ AQáÀ]ßC”Ž{¥$ˆ † ù/ !¤îš´<ÙºË4: Ê4Hä9„EO^<ãƒçûio¤‹å @ðÏÿ˜§YÙ5B@8ª€À÷ûN8Îä³O®ÞÝÜõœ[®cR›alZÆý‡Ç0ˆfÁ䔦 â¼>ý‡ÿ寡¢ˆiŒi]_ BˆùP×U']™$³Ùr6]c4tåðù¿åÍDz&sYr`­Ã‰$¥àÆ_üú7?|ïéÞlA)I‘pP€Aq‘Ÿ|÷LaÌ(ÊãLó<ÞVjÄ¢¯ “i4Ì’GÏõ{N¨÷ƒyš—ëU’¦»ÝÇgWŸ ?œ~:[=½»ÿv¹XuEbxšc»YžÄM¼™­)a¶Ç¥,ùØí“¼Ë˼˜Ï¿ {xqµ©ò’ Ö ¹k:&Õ”òûÓl¶Ò\kl8é ã{]'>|Ǻ.pž(ˆ¸ì]{¶˜Lê>£ÈDº.$[k@åz±Þ„—Ä5ÕPÿìÙ/²®Lwž¹Ëpùèȳ?ÿì… qS¦_~ú%uÓ¥S/x|ØimÎϲ˜Çûí¿ûoÿû¾ýØ)~ýâz¨¡P½áÛeÞ®uv69|̘"ßë»ñþñþÅóOFÎZ°•@ÁtâyV–åÍÐ<}q¾½9ÛíšÖ6œitŒ¦;˜œö{ÐîîÞ4<9@8ŠÉ$T@ ²±LºZ¥éIc浉Íl€ØÛ÷of‹ ³±o7g¢‘ãñ1tm”ÁëgÏëBD‹ šÏ›²ëp÷Å/~=ÖDáÁYD‡7ïqh¬ß½»í ÿ³?ûåÛo^dÔ¡F §ÙFïöÛ=bììììõÍM°ž¼xâ3b–uÕŽÁš€=Á8{¨'óMÞV¼À7MÒ< «©ïþâÏþŽ · ˆ¦è8õ§§í¹Hãßýã?¬/×^àžÒd4áÄ4yÑO/WÙ>)Š"œºIRe§±ÑB®€Ä2ôä¸32F¥ —ÞÐ4E\ÍW³ËùËó'WÛýÍ)N Íõ¢iq<-××Ó…Uç'Û˜¹!óü©Ž,%„.ÝQ ‚ªYž`ˆøÛ¶gL§-Lóû/ý—„ƒ4}¬û¡ÏŠ´lž~òüöõÇúú«?û‹ß|üð..îW— ™øg_|®€T *)Å8N‚©Á¨R‚bZ×ÍÙ“Mšf‡,M‹Ót~±Ûí!ádÅ«bû¸«©aCöݧWWY‘=?¿:ÄIËKÀäÿñ?ÿŸ–mµm…îDNfI|T’ë†nXÞÝÃ;'° £;^) mÓú*Ê:“Ë«U|H‰˜nŠ ʼƚåFîû·?j3MÇÔô´7lD‰Ž†Hûp÷þíÝb¬ËfG1[uÑJ NÅi³\Þ=Þ @ÿü/~½˜G]W1¢C 0ÒÓx/$DŒìOïß¿ÿ­.˜>¾ûá#µ|ƒ -¯}?B üý?ý~3_'Åñpxðée$8D†¥1Ë4™î$‡t¶žPƤû-`êÍʺÆT ¡¦Ë³$>ÆÛúx¨|Ïr½ÿŸ„ûh¶ì: żÖÎ9žï=7v£@H>Šz|²Ÿ,OgçVð@?ã›|C^b›:ŠzýÞóî¿éYÄðU06 ÇN•µ¼©ó"¶0  m)n@*QPˆÝ~€m™óɉ¬Èi#/ÖLG! L¥ß~÷CÖ hÒªÐÅr5?É눠Êç~PàZ[±Ÿ]]–Ö4ŒÎÀÞ>ìX®miYÙ¢«³…,)m“²·5’xÑé¨ûÝþöÍ›ŸökLë²ÉËh—))Q!ÇŸŸž-nÉ´l[ùãúÀ ¬.+QZ¨ªìW‘x^DmH;èOÀ ¦Æ„0"Ï6 Š"žƒr jª¶X½Åˆ@æxðØr@‹Ò¨*2=ìïXÓÒe˜øžZIô®ÄÕöÉèuÚ`ÚbP45Œ‚½"+ÉÖoq9 X$VIfi¦®Ç•Óïâ–+Q&ÙRtˆûÃÕ{gEÚ†±wqvZåm‹j–Csã…mwº½QžÄ” Îé\“$„[ÑÓ+ÎÞ{~AÚ¶7™wl£ljAE†€3 Ë«b‰ŠóË+MRJ”–i *–Ñ5(lÛµMÝëyA®›ÆÒøþpñÍw_tG&¸åãÍd1I ZáxÒŽéï¿üÝ'Ÿ~–eÕäDD*S#P'YÙBr½8óvVdTEæ0$kiÕšw4ì¼úúûÉôLWàÃêÀAæƒÿð‡Uïwz*mèÉåKVhý}PT©&óé1f•YÃ0Ò âeް¬îv][¸'uUeÞX䨪w åÞÝ}ßs&ŽÕÝwm-•q!(ZÜî/æó²ÂŠ.ö,“%>a(äY’ååÙlT´h¹‰0*luþ_ýÍø „²"ÿéËß/ç”2“¿á%ž£2Ó2ŽãùÙuš{EY–ö¦ý(8¤YÓ’ÌsâÓöRA”EÅà×Ãn`$óf\¦„Ep!Ç2¬ÇÁ`4úýï¿@[ºJX@á8BÒ6-Æü´?î ]]µ(ƒkTˆ¢ÉIlà{Ž3â9°¼‡Y”Æ ÊÚŠÕe-/âÁü­ÛÍú)Û«&Ù¡.dQå3/ÒX³jÛqx–B±_ï\«'ë4:ã°À¿üè“§Õª%USaEæ©G3…ÑìÄ;ß}÷Õd>ajdù.Ütgµy`8ZèGeÛ +çeŽ)8½§ýºïºªÂ×”A5¦¥i¬k Ç1þ!¼~y=) m]s¬€Z$«2†¨®ñÃý»woï%œ,ò l ÀB¾E&‰‚,=mÖ=×0 ÅTT+‚kšˆœ{óðÄ*¼Œ›ûû¤?¹üÙd2mhZ¦j*ÓTxFNó„à²×;YެB«¬½¿gŒÔOÂZ®™E™çf³~Õq’uN,µA uK¤Xƒhº£`ZÊ&#°r[c(Ô/¤i.[ft8Ø®+É…4IÜ+rb H’Æš®Ë²}ðî e ÉŽz¾¨¢N™Zå,.š¶p‘*9q&©ïÚ£ª.UEŠÃØ‹BU‹¯W+k¨;îäöÍwгÔÃ2œÆÒ,L:Þ6{¼y7žÏ^;îŠnÌûç^Lç£( r·wr1&9n§‹îùâzy3˜Ù<#RÌ5$ã)Gk<<›”aµ{\J#ƒÔEŒÐ™¶¢*}åæÕ+M±D™Í‚=#IGD^¨P™Q‘FýáÕáðÐàÆ/jM I£ :_Æij>æP«*¸Ló(XŒŸ’CÇ1yÈV?9»C˜Uѳë‹2¯ƒð`u´Ìÿ÷•Y<܃ÂÓe) óåòæÓÏ>ö¶»]°~öìJ书ª„qEÖÛûá¬ÿýïü¢æ!æÅùf›I Ø#QQ+Tf^ÐÍ%C0TÕó5[6[À³i’)‚ÍŠòò¸Þ­W§“Sï¸/Ê|8šâ=$ Ê&? œÈ1R–ob €aâA—MÃ")‰e9·«e­£+j’û¸m('åUeI*ÇÊYš£ýj†‰")Þ&ZîmÛàÃv<^¨›ŠÓ仲€•(ªmN!Ï}üÓ϶O÷FÏ :y`^.N÷›5P•gó®ÒnWmXYÑT³«oWñød¨ªrSÀ  »Ip IDATÙ;®Àð-GëäP›=³ÌÖSwQS%>ƒèx2â!;ê/Œ—·?ùÉÏ‹*K"Ïó·2+«"S%…Gäl­î¼-A ¥íÓö´˜…D1TØ¢½·LÒTâ?ü°O‚¡3½¹¹e$p\-›ší e ù§Íýõ#KWwKÇÕ;£n•æP*¯…ǸÛï{^ÌPtvu .ã”Z´©[…“y‰?£ÑÄe8¦©¢Nß=»¾¶mÇ?†y™ÉªÑ?™?<¼é»C2ºÆm6k… M ƒ"ÊêÛ»/ÙÓ˳¶i[L$IdS¶ Ƕ²¨Q†æuR•ã¨yQÈ¢qô¶†f³çöŒûûÕ|~Q•©wµí:ëûµÞ—%I»»eàJ]’ “±$=-r]U!Ã:=ÕÖ ï ‚ °|’e^ ^Ý0×/Î@1fdY¦”ÖuMôÅßý+¢9%°©1ÏóЦFQ¦)"+°¾hšÎò•%˜"àGGÂpE]H² ÊŠ°AhL>úÅOzºÓ"Ô’”Jç˜C”ò«ínµ¹‡ßR¦irM’ÖOOª":á~,ªhqö<Ùg’ e©{÷úîÃÏÞ/X §@WuWûmÍÔª %y y¾©*€ó’¨-ïŸÆ§ã&)—Ñê:ŽÑ±×é±¢h¦Iw¸  tú=Nh!„ÛÍvq½Pw½|’5¶Êr‘먶’'q‘ ¥klï8q'ãÒy…kHÕëHCÝQ/ܼQu‰«Ù0Ùw]ç«?½q:zƒêØ?æ4å©¢†¯pC»šÝòx·ó,ÍdYѵܛDVáE9K IQ2TYÉʇ:ËÏÿ®njÐaçmw!u [”E)ˆ¬©v%ž“!Û¢-uQî˜n^72ÇuÌQQ–u ¼c¦šêÑ;¶Eµ<lËÉÓè°Û»½¾©Ö7oå:ÎèõÍW¢"'ˆÔ£“Eåw÷÷¼ÀŽ'ã‡å[IT«0Úî@Wí…IvýÁ‡Þa»=†‹£@ûwb倬©òŸÿð[G7ýx¿Ûûò^vÀ@)0l%áîûW“É‚OÇeƒd P ‹š@„'Ý~ISW#Ïw,‹ãa•£ÕnÿòêÃÈOÇ•Àòš¢ßûÞñ¸‘9‰çùq§û‡o¿vìù`†’”¿þͯxA?zKBBTïNŠ<À„4OfóÍê cl˜* 4OQ[Å–Ùˆ%.ŒÂÅôœÒ4etÌdUDA|Q¥¡³³¼ãRÅ‚Õé6Å¡­$–eY––1þ¿ÿöŸS‚‘Õ-©¥ÖËñØ\=‡“®©Z«•§vÌßüÅçURíãᘠ…Oj(D¥§iÜz™l7÷¿øÕ/?÷üý'ŸdŠÖÓáµÛ5аî ô“ËÅÍ›†§Œ‘–~½‹|™”pª"m½USA4K9úGcÛƒ°ßø‰§ ¥¨Âõq·»8¿Ø‡Û¦ªQžŽ/–›Çþ°oÊ Dp— Yˆ¶â%y‰h«(B”&ïîû}ƒ…rPCë2­ƒ4}~=šôŠ!*šöxÿèöËéëã&YÁ8ßB a¨Ÿä Ó²6ÇEiÉbFXžgu “&¨–#Þ¡¸|v1èY‡»;ÙÑ’¼$%µºÖ‹ïqDdEXd5n^²4-ÓúþþÝdÜo l©ÒÑ{šê3ÍÑÖ‡{Cê45džVDÚ Í¯gWûØ“ dËzUµqå Œ¨ëf’…,áâ0Õ‘¥Ânwh™BW0 ©€æó<–,+:FmCTYC%Úï·³Ó©8,( «,OK®;4VÞlü‹.Ò$΢KéØFqËóĶA›}+õ#곫SHq5ãÅ©£›®ÛWu5Í|vAp) Š­;šm*'Ê:+°šª@À&Y(ðÜh4V$aï=vûÃ,ÏdÙ"lÃbܱú“²Ì®¯_,—„ƒœ";Ž¡™RÛ‚pµ\.˜QÄ+ ‚Z®ÓŸ&¡Ÿåe×Ý^gï²ÖµIU”¦Â²^ïX}ÛÒöûÍlð^šyq ¢–ÈÛ®Ž"§zé~<Yªõúö-¥˜*YÈói˜oƒÝüì4Ì!Œz®¥9ƒ$Ú„W71B§ß¿}û£¢ðîhV„Eàï]»·_ï7OãË«õáxrvª2Ðó6²aýüÃÏß½úž=™0”'”b@eF2u…7 jAàÅöШóv¿ßô&γÓ÷¶Þv—¼;ëõV›À0„‡ÕŠeÕó«YG·¿üêûg§²(|÷úíË÷gÿýþ Ê%Ë ?»¾\=­ªº1MÝTŒÇ»G˱:Î$‰}™¦Â¦ëRRÑ–î½íÙÅ" Ó$ !$€r†)6-YŽišÎ¸¿¼¿—D™d8V–¤Ȧý„°í>x¬"{8TªJÒYiV´8D¡ªhyZ„Y>pµ‰9Ô B¤©vY&†­TqQÂÆ1ûUÂÿ/ÿûÿ*Ë­eô¿}óîýësŽå¿ý*)÷…Ïß=<8}~·Šÿéwÿ2žËúûXRy]TY>ö7’"u»væ2£ÔUÊançy¶£’·¨!”ECôúÇãÞó‹aO*ÊÚœn¿…¬(óF”„÷ûhÞr<ËœfSÂðÀ°­?ª Í,›¤Åb XÒÑ좥£Qïêâ7ð~uw2;¥„+êL—t ßÅïŠãn¹–yqÖ¹ßFUÝv:º?N;ºäïý8OGãþãºf>F%ûôðíb:õ·9†âz»>›½˜,Ææe„žSmeù¸3ms³} ý²lHpXÒªå%á…Ý:¶½2‹F£#«áh“Ȫ¦G‰³{ýîa³’D³iJI 0ª¶(ʬ¯O \¤e¤qfÙ "ÒÄ —#í·Ë»3Nã" 6Ï^¼·]@,Ç“ÁÃÍÝÉåµ&9¨N8]<]½úòÏ×[3¦V¡DË ºfÈ|ßþ¸Þ>v2Ÿ†G_ÕÄÅé¹­[¦+*2×Ô¤7PT œÖŸ y–yitM@QS†'UêÙŽ ìísÍ0Q+Œ *ªÀÕ<•(& ` „Ãáøà-yÖdøZ5E]2v»µnˆóÁ"mÊ·‹Îùýã#dyž‚ @B ‰ÓIDaÓÜß½;™ ]wî<^{ï}Ðp»¼}ï—¿Ô8ý°Ûuçc×p’,pFƒÂ‹uK“$\&ÍÖÛÚV·cÛoÞ¼Ò,UeÓp E±ZŒú{µÜ€DŽÂ¢˜u/WÁRŠ©êD÷oîlÅ®Å:Ø®«ê}S„tĬ̧þñtñ^^VÉj/ʪf /6…Ï‹<ååæ³Ó+®At”y7m”½N¯ÎsÄc•±ß®ã¿`Ù–çiÏ—Þöñ¿ü«¿þ—/þìï_½H=ï°d4‰½¸z)mZ¨ˆ à9–#„ˆ%Âi;ÃÀ¤ŠÓ¸ ÝC°Ë} ë²Á)UÝV­2?]ïAz0Ùî|úñçÿÅû‡ý‘gg&Ãó_ÿ08÷$ L*YT4YÛåGUæ»}ïdì¶´©y…±Ýnäg”Á¶íÔymºþ~+«¶Ós!ß¿ý~qµ5 S§«7Mckn™¥,ÇgUEþwÿ¯YŽ8‘Ó ÓOBÀCÝ0’¼ìÛöÛÕ“möÂxïÚæÙl.i2Ř2|]§²¢êò(ŒvˆÍw˧û§•ç…½ü¤@ejƒ5"½þ¸çŽ£<‹âôútvHr…X„Ïi"ß&+‹~_Ó•Îf¿¿¾º(Ô0 Ï3b[ŠOÎ'Þ.zÜ-Ÿ]2€áÀ0ÈdŒ¦my7¦å¼xùáÃý-£Y§Wˆ4ë0Vše`±˜¥M–Ç%Ër¦¡£ºª›‚Dб(ðyÓ¨’ìt•ëg ‰¶=´†3 KqþõWoûÍl:…¬Â]ßè WÑÂÕœ–¨Ì²ÃnBïù騮j ª*IxNhÒT“’vµ[òé{ dEtûƒ:o)úî¨ÉëUŽ¡=¼»1»ŽÄ‹M ÏôÜÎa“PžÊºLJrõâ%…$?¢ÞÈœ/N–oÝQ¯(=S艖f> ŒÝq[dqÙÍÅéY–Æ®®f‰·?&´n4SÍ›º©ªA¯_Ò¶­ js¶ÚÉ‚qíñéÑ2†‡ÄW 0ì %IáK6ÏbYÑ ænß~øá'@p]•("D ¤65·‰Q–ó÷>U\äTÓÌ(>°Œ”qÔ$†d–y&)².J»4È#ÿd|„Ùp2éfsX̆¢$Üþx/ip0œæi©ë:/‰š¬×¤üî·¿sF•ÕÿþÿŸ‹ëg„ÂCçI ŠfÒæ¦¡GÇÃnvú®üïÇË.ÎÎã8ãx˜ a®."ª²i”2"­‹¢®`ñn»TÍñzóˆˆp>xæp/µ‚ PN`duûú¨²«Á¶%u'ŽÜ´yCü'™§,g®¼;CS»²=ž-vË[Mï‚zƒ²"¿é úvçTZ?‰Í9zÂ"lCâE R×ùxxÒqfQ±Ÿ¸ÃcœpºÒ‘Í Í€PŸŒ' ß¼}uu}. ¬n9ç§yÑÔe~ýüê»?ß–?yù,ÚÆm]šÝŽ­@F²»ÛÇùåLQÕãáPÕ¥i8¼$…a4èöòºdy‚*m%K‡ÃîýÓ~q~ÚÔG $Q€^°ã[3H=WpËv'ãß|£ËbY5 mV *‚¬(†(ÉþÃÓË?)∈Ë6+ÉyÃå‰ÓÃ|q}\=e¬É ìÝêMÙÂ, ÌŽC æÛWVÍŽE‚a[„“鬨K¹Ã}|qÍ+öÉdjú›Õ¾g+¿øü?¾ýã»Ù¼—5,vEQ„jJeD(©jtöþ5Ž*”áŠd]«wØŠ&qÀHÚùûïñRiBS¹u·#÷|öëLJ»4<z_Àe Ä­ï1 rl“`¹H׎¦–7 þø´­Qe÷¬Íz›$YZ'“Ñy]ÅÛø ª†Û±Þ>þAbø­Äa0°;ß}ù1­`¥ÿúDzãnõ&¿hPO}LäÃqMýË_üú«¯¾byöìä¼ÎsD±c)ûmPV©¢ ûÛxr=‹ƒ€Ã M#ÇÖÛ ¢zÿî{‘—!”1a¨¤‚:%ùiuxöììöñ‡ÅÉ'qȱ‹«K¦…„Åd‹¢µtM‚\]V¨­ìno³= –iÃ1M”G–l1Sf»Þýú?ü2I¶»}únµººœovþË.Ç£ñÀìØÝÁãÓTMS·óí?ʆUÖ¥cw÷G3•­v›º=v†fvì‘îLS¿½y7:9iõ½}”ÆÃÙy™5ç+r?ñR·7®³œlÝf“éb»^a F—¿£"ùö‹¿{xòr º†¹ßì§Ó(ÉÖ›2;›ÌV+Ÿà\—%Y²~ý—¿ ’°Å¬(±”W›ÅÙ¸ZmwñÝÝ›w‚bBqv³:~òÓïîo£(ä¨ BåAê PhÛ¦?è6%1£e Boçó çZYQ½è€ þàúÙfµ¶5‚ À¶*FãEï/Î/YÍýöÕ&ÃÓÞpè7I^›r§nüÅôôææp^†@Öå"‰u‘ßG±eªiÖ¨’¤ZF“Vˆ URXÈaŒ?¸|~:¹ä¡E…ªu*”›Ž³|xà8A™Û~4t5G™³O¼Œ(2£Hx—Ê6m#0Cyaf©ÊÎ?\ ¨m1»ÿò½N/&<[Lê&—x=L}‡M‚S^®n e$ël†2[4ûÕ—Pä®N¯“¢¸»½ùÙ/~'Ï1ºkSI:¹šë’œ¦i^§ó«0>ª²$iŽm»¨* àxðo¢Œ;ý'+…Ÿ÷Çײ²4ÌûU᫺©ºj'‚¢ê¶ÆBTWÈèt .eEmq-*b–²!ØxÇp2¶¤¢5,ÛRE…—hÚ¶‘d•S)F5ÂLÑÄ<ÇS‚mE’hù‰Ï±”å4)Ëq’Æó’8œ¼}÷½e˜¦1l*a«©š¿ó8I¢ŒºÝ¬ç§/γ(M‘ãø¸.qÎaµ®Âper”Q 6$õ¢‹ë˦hÊ*îöÆ*Ú6UD6J[·ß{ÿýùf¹Rd¥3pD^C”Íݸ¨p !‹–«Ïq§‹EÅÛÃãåÅ,Üx€1¶i»®“f!ƒAƒˆîØšdAm6ËNwЖYY¦“Åy· @YSÏ:æŠUî~¼]~gÙ“².—ï:Ñp<üãWÿ<ŸžBT+Uf¹C°9““óÕò)нŽc‡I.‹Râ­l§ï{ëŒäuTH¦*°•ˆ—€f›ÁÚK²Xâ…$ˆ³‹,Þ+ŒqþÑ‹®¥û{ïôtöŠ HŠšÊ5l ‰aIÛCx6=NG/ÓLS5E 5@3Ç1$ªv‡Ý2OtÁ,ªÄS5M’AÜëö*\6lñâå/þFtޤ2BÞ”m›f5éìÅËà°”$¦¤FaT4g‚š`4îïöA–®ž_Äz›}‰ë?øÔÛ¬ûƒA–•‚ÕUD-)Šº*ºf§©kÚ&¶.‡¥.¸i“¬) äZz§u ž¶Ý5kÜâM“–’ p2®ý³ÉY €a·;(iiËêz»Ê› –èbþÜ÷w ò†®dQ”A‘—"£ºQ&ÞåÙû * A§'ŠmspCŽÔ/Î?؆ÉóŒá…þñ°"@Ûz¢Ål8ϳääìJ Ï+ûw±¸z\®!GÏsÝþ çîv{¹Ó“ØÛ·7?ûùé·¯¾—E½dèv»Ñ$S5´Û×ßq5b;ý¡¦Jª®I.J¢k‚&KiÍR¦å„ ϲÐTͯßܧ#Ð2ëà°÷ƒÿö?ÿÍvrz[ÔS1š©xûåGçŸNû}³÷oÿôgÏ.yÀi²:<¸ýqœÆDª¤M‡¡ç7)U q<ì}{ØmÚÐÒGY–áÆ2{M[7„[ÏîöuÝÙýÓ#/ñŽ=¨›:ô׸"½Ù"ðW¶Õ w»ÿëÿý׺Γ¬^m–/‹8ÍöAÜ5ºl9¨¢T´èêŽb™bØ$H’Ž{£µeÈBï_ÿþßæ‹ávFQøŸþê?ÍFã¿ûÇß¾÷ù»›­¿=ž¾ÿÞý›ûŽjsP%ùÝÍÃô¼¯(êÓãcZ×a@ø²òeC‰ÓèÃ?ß.ï{ý‘ QŒIU1–s òZRîÞ¼{sqz`UĹ©A³k|ì'y–ÆXŽ}<ø¸¬)®k£¼æ W¢Ò”džáŽñÁ–5(d Æ„g¹FlÒ©Bý IDATú‹—uX›®¡„ Õ1ê‚~óú[K2ã"tƒìãÂTÔùtú¸Zcžt{yVg bÓ#†R&+Q¯op,Úÿ4Í}ïè=»~N °uGSÅÝ~g}C7_ûº3œ]¿|±}Ø[¦LFVì¦.-·ûðã[V“öèÍëoª 2‡Šêw& "c8»{û¶lê‘1”E¡¥,¦¡[EMi[þøæG³3Ç-«ØBœeÏž=¿o‚]dèjÕzÓÑ‹7ï^ee¢Êªáº~™w, \Iž€¤&ÖÈ1 ˜šåѼwdÇ‘¶%}Ûà8À@XµÕå‹sØòw¯?úé§åX#B'—‡Íáêü* “è¸ÿþÇÿiww—¤ÁÕûÏ)ªØápÆpc(ñ<#PS1TY€€hšv½ÞÀ‘y}¹ÞnüÕõt±ñâ85™X=/SÛwž—Ééùü_~ýñËOö³S…ë|ýãŸ~ñþÒ?Fe]È¢P4Ít8/ò,ÏÙó³«ßÿá÷Ãᨭ±.k%ÊtCÙÔ庬oÞþøâãŸáªR%½®RÃÁdøÖ WB«Ì/OžîߨªDÎéÚuЉåXúþŸ¾ü6ÉUt,MJª¬Î¹~ÏBmÝwaÌOzIXÕ˜L'öÇ?ùMï^æ)Í‚Aøøô¨ªš¢ŠÞÎûç?üöj6Õ$㋯½é F;žò†ný^~ð’‡ànóÄ)òt0ÈŠÔ|Ð’(­S¹_g£“´ñó²¤lë‡qQ"¨Hww®Õm„r¿=¤9¿š­n—´‚ <:½À'Y¦ÚÝ^o²ØÚ½~‹[MêPШªF hyTÄ1y†e4-X eXõ³—žEq‡A·ŸFM^“›õ²®Š‹ÙéŸ^ߎ]ûƒÏ~öpwŸæaY€¬ Ž^Ö5Ë2MÕ̉<<=íùivô·'§“Íê˜Ôùb:6SÓ$^ÿƒ®ëŠª•Eªv·Z³œ\g9'êOËëëgC‘—NÇ]žb7dEt».­›Ïù—›‡ûŽ31l›’Ö4F€º¢QÊ+¦XdYwx*ˆXSUBQmÕp¬Ô´•¦Šˆe‘Z†Y™Ò´tqú^™&<ϳ¼ú~¿;FÞŽ¥|2 ö[YQ$Qæ8®*R–“«¦fEŽJUUx¡ijLP¦MÝ ²€Œ5,=8zEX†oVe˜§‘ë XÅǽ"*’*µU™DX2TÖ¦ÙM«-Á-/)œ€ëËHn_v*y©‚!òFÖdEUjš³|\Ú–#+b‰òžì®WO ªª†õõïzÎ1|ì¯)ä Õq g|y"@îíßþã¯ÿjµÞ˜–1ìϪ*iZ4쌳4l1óñé^TÕnÇ¡ xõýw†9@˜Ôuáº..ZÅ›¤¥•D[¢kZä'®e+†Âþd>kHÉÔÐtò2MW¯ª«ÛQwX¶uMÔ–)‹$ñ}S³"D²X\K"e¡) \•šÔª0·¦2ÚkžW³0)Y$¬£u^ßÿ`uú*d¼<…Ð6„aåÿ/ÿöÏ£î´Â8 ×T‘»“9n#Í´gŒêâôìô»W¯UNÒ3 Rï°ŸŽON$S ,_»£ƒán½Í³ÄÚQœDÐBEIŠÚŠ5V°ì‘ýÍwßÅv: Ó$‰ÞÄ ¥*Ë5Å!˜/ž=,ï8Žx­P–ÄUÝf8›NçLK6þ£e ª¸nëxywcëÎÑ{Ò-{·ßäµçÚ£‡Û»åñáýë²$:†Og‹³Íj ÌŠÊßlX‰Sdmó.—÷ŠbSD"6 °GäÓé|ûåWúdt5>{|ØJ¦ÂJmji¦£W‡ùùT”ö˜È]½iËpwˆÂcÇš„ŸÓ„$Þ·-ÓÔÈ´¤ÂOõN×íèþjg¹=Cw(p´h‚ÊÃjÏ¬Ú 54-bIªd§qhtt… £hÛ3†‡ý‘åàawälc~Úãú°_«ªðìúg_þñžUùM†bžaÙÅüФ%ÊBªkn0èÉþ}«q)RA„\AÛ¬D€ ×£ÎiT¤ói¯J*DÀW¯_}|öÑ{ç)’![`¨¡Ú‘Ÿˆ [7ùÇÏ>ýúÏÎÆ ådA8GÝÐA’BÑÛÜÏ.Ϊ<Ïã<¯Ó—~êv’­´u™v~rqwóCUbÇêuúý¾ûòòÙY§,Ë©²„Û–¡Ð0ÍÉÿö·kØnk]6*\ò‚ìýþ¸_f±"j²¡½¹yèõ†f§÷ìübvÝ&ÃÑÉjuÓ븪ê½ýj¿ ±æU“ë²Ò6ewè”À´ª@9q&~„ÏÖœÕ~9›££‡!îwF®ÙyZßÍf…0Ú;ý(ŒW§ Çoׇ†Ÿ|ø“àxhH:èeI.óÂÒ¥¢B^^?Ÿ¿}|Ð÷'/žS–¯ÂØqõ,NÃPMn½<ÎO¦»ãB’£º# qC†‘%a (@´ †¿ùõ/‹´Lã¼?œ!œk²VuÓdEÃxÞºÈ}×™ "}ýæë“Áe^•†ÎÌ&WuUÅe΋bU#–Y’ À#i^Pv;O”ª¨>þèýë/³8¦ ú#^T[œsœpØEÓ³ùÁ 9¢M#ÍVY"MÎíÅì¹ÊK/?øÄóž®ÎžûŽÓk*4šõONN#ßïtG F²©™¶‰¬‹¢?Ò¦à9–—Tׂ ¶mnèCkœ£–¸Ž™±,Û¸myž9…ETg2ÃñIäo8^0LCÒ™,®%Ia8 Ê: aœxºj#„–á!Rd“ÒZÑ´<(!¤ŠdR1jeYVd£­sYÑ(¡’np,¨+D!g»,LŠ$¦‡ýNY‚°®9<#E.´Œew?áÿOÒ}ôÌ–&B~ýñ.Nøøüõ™yÓTVVU—éžîA°bÅ!„f`1k~+az`计¦\Ú›yíçâ ÇÛ×±˜?ò<¶¹$¼“Ìb]UÇñÄ ,/J'Ø&é> ¼Àä­ îÖwO>ùªíxS¥ ™¶i#ÔZxê9.dÕãóBõ}W‡ÞŒØÍ›ë6í¢“Ù»÷omŽ”ÑrÀmf*ŒöûÍ“g/³¢5¡†’ôµ\L¦È¢)ÇÃbzLvã³ÆÐÄ8k¥Ôp4qã(ݧ?½únryq}ý.I+jbUw‡]võôiRíïn—=ÿ|ØöBPÌvÛt<õ¸àûÔ¡MVzN¬l4ˆâ››wçÏP×FèE®K¨à P$éó'Ÿ„Ód㻣ãñáéGÃÓj½ÂɋϿ*Ó|4ŠD‡— dU9]Åh<ÛËÅ`>ŠOª¶°L†5"&´bPK)üøÅÅnµRÏOæˆÓ$M½8–„@¸qøöýk˲¼É°H÷yºþøÓ¯Ð¾`¦õñ§Ÿß½yëØžãǻպëÅìôì›o¾.šþâ|ÞÖm²Ù1&…m^ŸœŸ¬îos Ã$’–iA³«+µá`¡¦þj·Œ¬@4(OªCšW]ݦӈ·ôX&ÏžœeE‘0Ý`6=1O&Ù&¿¸<½xtuXm¹®]kÌVvÿäü¼ÊÔ7mh¾~ó=ñô£ÓI+êJ¥Ÿ¾ø8ÝæB¤`SzÓÓ‰ëzßþxDêÑéÕêáHC³*kÛ÷‡ûÐôÚZX¾–½n·ÉùÓG#¸^ï° MŒë¢µ]w³¹?™ŸçmN-²‹"Ô›Øó †Ì¿|ýûx:=œ.N–Û›a4åPû‘g´äÛ·¯ñŸT×Üql€aUÕ†¶%G®u]{8îã8nûIº.w±”Žë¦ûÃo~ý7Iv|ónYUÕ|q®KÄUûÛø»²º_ÌŸÜ~¸ŽbS*î¸Þ‡›W§gO¸æmÆ[]Í¢AÕt½¨ —Ÿüøú¯~ä)ÉüØPi®taº–ƒüW¯¾{öÉG@@ÎaÉ‹‹Ë³b£¢‰ÇˆõæÛ¯žž ®»ÝëâŸ7·iÓ·„±Ã.4)ZMG¾e¸?½¹þòçWi@õ«_ÿÌs]«Üi9ŽM›ì×û0ˆß¼þ!=ìv›¤§µìäl~²zØdemSUEÝ7?z”«x¾þðf‘&e_CE,›6º‡]mXFRžœœÿùÇ÷iž]ÎæBê›Û¦ÁŽI¥•ÄQž¤¾Gb'§ç¯ßÿ8 R›­â¢®’}Ý)ݦUöÑG¿»}/¥ò‚/[PRÕu+¤êBu­<ߥ’|ñò·\Öa¢![UÕQÈhv:þúOÿ$srvv¢p{ÿÃæìÑeQ¿ûè×ãiüÏÿüž”rÕÊžZiU4AP6œ·9$PH èýòoí$´†+?Œ“M@†ˆi»“ûwß<}z1ŸŸ%åýÇ/>µ°Boà 1’lÿ›¿ý‡Ñ"Þo·“ñÄ@#ÒòÊ2Ý®­‚ٸʲìwnè̼Y½%ž­{0ÙUÞì³Í¯õy¾jê¾ô=@ÞMl{´|¸yüâQµãIS>zñÈäæë»¿xùd28ÙïWAëDHª]ƒšÐKI4š¢G" OsÕÍÃë³ùïÛËóÓ¼Žë ¢":e¦eG¶Á-H-ÃM%ÎNÎÓlcQË€\Ó&´Lð¶ÉÒÒØòãíæHPÔåâêÌ$Èô‚›ÛŸ ]£kž]=?¬’Jîë²0”³IΦgûõ:ž…Žì7·Ñ"|qñø°©?¬ßžŽ®²Cyz6KV¥X<Άgo~Zùâ¾ïƒ³ˆW ¶.ªÓÙôx,£ù¨ìÒ>Ń( :8.yâØF/Åøl¾»½?Ÿ\!ôyGmÓ» oº¬æJüñÛ?½|þüâ¹ëXZC!…m˜!ß3 ìp!Оn¶ÃÄB(Ñ5‘ë¦y~Ìòÿî¿ýÏŽõÿûß_ÍçѲ>ü«õßt]7›Ÿ­—7ž‡“4+6ëd>ŸÙ^¸º»u¼ŸÍOnnÞÚv E·8]ÜßÝ3#]ËÄÔ~wýÓÅâ\J Mvñ¸,@œ¼YýiÛ¦Ùv}ûäòåzs µ„ ø?þç?l6·A©õ  a8¾¾y8™«®ëë~Ÿ§‹ù©ÖAåÒèËß~©„¬«šwå3¤"ËFóïø.Ý7ë‡Íq`Ǿ㾻YMãÉW_~òÃwoÆñ´í+¥M‹˜„è2¯\×¢ Ù焚¶g Íéz·µM„íØ~’mMæ{aØ×†V‚X† Çq–ËëG?ª²LÊkaZŽL d¦PÝÓégy™"«¦ÀaÔZnÞÖ™2“÷m`jÑÇ®_×¼í%eLôòòIôôÙóÐí lëT"l»Bx¹¼ÖºÛíÒ¢8}IMäöôb‘æ›?üù/ÿòþóûûuÛIÑ—]Ûõ:pͶ“'¢Äâ\x–6]ÂçO¯0f–íåÑr™ëøJµbÇvGã‰àr0XÒíd1ŠýÑö° ¢p0Œ kÛ¢ñÂP!î­@'›ÑxŒ‘X‰i 1ÂmSÇ# ò¾¼¢ažå@ Ó² u’w½&–ɋݼGÈä˜8¾‹!ÒŠPÃp\»«´ÇRÔ¼“#Û1Ž»#Âȱ!R¦eØi˜†Á,¥e´m Ëv¤êê*±Í ÔõÁ°ãº]Sb¤Û¦ñcF jujb|ØÝÇá¢ï8„šQ\ŠH0Ÿî6˶kF£Åv}‰²ˆ­µ.xɨUg)¤P)På%ñhàÇÇd“5Iè“ã^i$Û¶) bÚ¶cýõO<9¿róúýk¨aÛî|7¶|˜×ËÏ~ö—Ýæaç…x¾K‡á뇥5 (¥àÖE¹oÒ ˶¬b["Äê®$Þ,w¨ÃȲDŠ®:V&avh†ÎàÕŸþ4;ªrÓtí˜Q^4BÕžެ。~ÿ°;9 /¦Êc‰ [pXï†óIuäM+‘©%0wëû~ñÒ@6e$é¶1’òhºh{{Û×ýìt´yXi©5h1 »Ub < 6 ˆdU :¢WóÇ Î+¨QÛ -ä0˜p$šœÏﯷûc2™ |7¾Û®1lêVÖ]9;ñ¿þÿþ<Σ¡w¸K4PþÈ.njH!r4%¨ãÝC²l*Ž©ùë¿ùùÍ›÷B£Aäv}ù#΋õf'¥òoŸÕádºZ¿&€y66#0šŸçÛ,MB¢Ñpú°¹‚–%‡ˆ’b5*gZ£áfýáÙé`pw{úqäM<ßzöäqš¦žoÏf}ÝXc&±˜ ÿ§ï^…¡Å˜•¬6–C£“,ÉY2ÍŠ²žMòdÛ÷ýâdNzxXþâg?SJïV{DZ(S«ý6Í“Ãn÷ÙgŸþñOÀgçgo¡Æo;ÝSLëF˜”RÇtL¢…ê»®ªóA<È‹ò~·»šOÃÈ*¹Jo-f®×G/´¶‡Ý¿þ/ÿÍì*–Þ/oO/Ï7øéÇW£Il;æt|ù÷ÿqž4O?~tóî½h:›­»0›ÎÓmáþòööòâiz\•E)±}ƒ"Ò5mÇ{)êóÅ£íqIHÇ Çó¬¼8–cذê²ÿõÿ»?¤“(B˜‹¼©JËr‹ªd&Rñ®Â!ç 6èåé<çM“œ^µeoš HJbÙÌ ;¿ÿwÎÛtŒ~º»±,4ÄÀ@i™ ÃÁÝòa<Ž1Tn—¶ãŒG±z¹}ˆ#!å|6¾¿¿åj¥%B½§g‹"M‚ ‚H#$®W7€¸WÏ×÷÷M!OŸ=ÚäÛG§Ÿ¾?¾NycÓ™Äo¯ßÚÔhžyUá¬Jž^=­Š À®éÊßüú6‡]š”†ep®,º¾ÿ«ß|e"{»¾OÇ€£ªj-A6ëÄæòýíl1ûí¯ÿv·º7MÆ:9Ö7ùt';îÃ''ôDiÏÇ‘V¨oûŸ>ê¸V@—Åñ£‹_|ôŒY´L2LÈp`æû`¬q1_l@ÜlÚ¶a0pÜ/Ö¤–½Ò½€&„¦[ð½ÒuŸ•ùQI`† K!º6 ©Ҹï2 ! @¥4°C&ÌÈ;Ãvd²i~œ?eÓ4m<×UåŽ#t~L”hƒh¾_=¸¡Å˜É›žP䆑bâú^ºY1Ëa¶ÍÛšËÞ²\&@µ½_[fH  ”BYžÙW „PDÓJ™¦‹0¶\£J:Û ˆû¦Óu²µ‰Ugu#jÙIÏ ²êR¿o å3áa—ÝŒ‡£ÕrS·Åd0Ùî ×'}Z‹žei2ô'Ëëõà|6LÞ½zíFÞÙìRk™Ô{Óê_<>51¹ùá½çŃxÜ÷(òÆÛíÑñÌÕr#•jëBt}S Ãí`ËÛ=…Yß[ˆJÍQv¬ƒaX$…èuŠ‹+~>4ÎÁÛ»åÇO?ƒPgS™y‘œ_ØÎDSU5ûa|°‚Eö”YTÈŽô˜"42ÆïoÞÍ&S׉Ӿ'¨1¡µÚn¬¡™%˜]튪äÎ0|töòûo¿›Ï0¥$Ô3òäÐÕm4ë¤|ÿîíùÓ³Û×ï „Qhaˆ©iÅþávÛIdø6â¨ÒÌ1u·«½çØH#€¨ç£,KúK¢÷«:×8À}VÔ—²mSKóÕ«?ñ®u‚Hžì·m§_¿þÑ3œã¾„W}m›Þòá½ïy£ÉYYïÜ(hòÔv‘mEšß¼ÿîñå' Sëýc{eÅV¾i™„ÕgŸ¼¼{þìÓg®énóíìä44‚¦oMËþî믃ñ€l}·¿¾6;˜&uL·H’h<üpó”pqvÆEqØd‚A3]E`[§=ç@ÁÃÛ›«³g¾ËªÝNJ5›óBqQ§å]ÕµÓñøPlñ¤â9s´g†«í:ÍöãÑâ%\Ê'çÏ«^š„tEóü駦ƒ0®ËÊ=Û –7·„ÀËÅE’4½ªÏO®~üñÕ݇Ýv·¼zñ©-Ù5Ÿâ“Ó+€PÛq-1¢€"j“ÿ¨uMÝ%E‚½^s%„cYÇ4™NO7i¢O³F+¸Þ®þ泯>úìËíæîl~ °=+= Ç,Ët4:yóÓ_ÀƒÑ)Dj·»ÄÃA0]>Ü;®Û5ýÅÙÅú°‚Tmí¼®é‹¦ö¢·Ü£ýþ@Ó¶ýÑ(¼¹½‹ã1£4Írf}ŸØVÔ p{HþÇÿáòm¯mË´é¥D¶grD¨F öJ©ÀìË£oÛY™3Û~öèÅh2ç¼ ÐHö;Ã3}+Øìﺦ’ðøöõÝÃvùôñ‹Õjí{ ­ÂY|5{üþæõzüÕÏ~–wy×µuÝ´‚»c†ywG,17Ûíâtœ•G‡9MŸ{ Èt2MŠ]rHNfSÛdUÙõ¢µMÙüdþöÍ·!qg'‹&ß‹\/§¼L—·Çxq]χgir8d‡ÐLOcÅûüP·Bh¤€@¨à‹'ÏEÓM&B6̲ FR•¡7Cšî·“¹7 '»õòñÓÇ}Ž)2/žGX:ë/¾übîž}ؼû‡ßý-!rA4š\Íg„ù|‡ðÍíêw¿ý­cb%¸ã@‚$Ý[žË«Þ bZ²J0&Ì¢ ¡4͇󹨤’Ò°°iX®j­šºäRÅQTe&B–cCèJ e›¡ÆuS7 ÄD¨ªj/t´D=ïÛöè¹ ™P ˆ1‰€IÑøaœ=ì{ÝþHI(TéØN]µJFÈ>K¡3$ïQ›ž‰ ëTI1‚aˆ0EP­e4™ˆVCKA­µBH¨¨ÌBx¿^yQ$è{‘Ïs!6¹¨l×Ј2ÓRJ.%Ô1ª´–DÙňϥjûÔ¢6$!ÞV±½¬É/îº[Ì"~Ésì È n7·'ÃSl`æbÝ T‘WÃ0βz·^Ÿœž™áÚží¦E™‰µçÇ»‡Íðdnšî‡ïßÇã(4‚í¦<»?«òÎ ¬ ˆ”7pB?,~~zr¶òVÃYVl/ή¾üùç®ß<,—Wç^4­ŸÄR4 Ÿ!Ê1„¶ïa)LÚXT¨ž@ g‹Ì3‡g\v¦‰8†‹1ªm×4²ª?ýÇ7Y–ŒG̬š×–­p懡åꇇm‡Pê2ãCÓrµ¢ÑÐÛnÒ$-£Ñ K‹®©ã“ îA]•O_>‡²bZZ¶«„0M›QsÌ…–^*¨0s äaÔ¤TØŽ…£,ÍÚª0 ì{QÓöñxèÁ³/ï® Ûüíßý&Één‹t¿Vøtq¡@`„Lf"”ÄRvuÕ:nXµ¥V¨jºÀ'iYEѰéë“Iœ›]¶úÞ8ü`à»þËÏ–WGÇŽÞÿøÊ° ‡ €›õ½ç»“ÑéýÃ×1{©C°Ûn0ÅðGWOoÞ¿íu9Ì ÆL×8÷ZÐtºøþû¿Ng3ÇñöÛ¤íêÙb"ž¦ûÑhtÿáz>;¢«ªâ/¯þ©Xßo¶y'Ez=—ˆ$Í À0ÕPáÝ!cÕµmÞMÆ£ßýí¯D¯º¾ïE­•NF›Íû?¢”~¸[ýôÝO̦¼-ãÓ†ƒ¼ÝŸŒfٱ͛}sg.{]Ó ÁV†´’<#X3êS¢Û*³¨[Öùùéì”÷×ËGµ‚×w7Ž'ÃénwçQ“§˜°aèÇqxsýìå'cwøÓ߯ã(ËšªJ[QÆÄÙç‡Ó³Ñq—“ô“Ï>³ãMϵˆ"@f[ö~èú®ëûÀwùÅWƒñˆ2–2Çg@ ‹yiU°&ñhôþúÎ÷ga4ÀZG‹¶®?þø¹H‘€Ç‹gNèÌgƒ;ñböìÉ£*o‘ÖeQgYe ÑÏ^~ÖÕRN,ÑTZF‘ê@)ªÉt”g]ßs€É<È Ò%¯u-ÇñË5”ãzš=¯ Û•­BTH{ÞB ÛT•,êm<šÈ¶çZ(%,Ûç¼…HA@c·Š+„5@A£,2æ†L¨@Õ„R× š¶1(…)¨\Ãõ¢§оO¢¼– ÷J*-±áŠX~Ì‘…LÃA„´ §{ݛ̔!ƒb Ê¢é¹ˆbÿ¸ª1E¶mËŽ&íEY”¦˜1V¬÷¦ï›„ñ–×MN$s*꫽é ÒUÚjDýЭ ™Ôµm;Šâ"»·\›ˆÚ€×ç…Œ!ŠÈú~Åu5žm×k!kHÌ0ˆ‹òè¹ã¶Ï­‰2o»ZÖÉ~:>´Ï’íttµÞDÏ• ­€³éÄs¢û›}YVèlv{Ï’&³CÏ)Òeß¡Ýr9=2f¾ój0Ónªº†-sØ~½ŽÛý®ªê0ÖIŽ!ò]Ç÷Â$¯}—B¯®ž—È®JL±”]¶ß±m™R Ã0(PeY|÷í«Ñð´'ï¦ðOï Dƒw¯¾…Z{n´}X1„¡FUwTi›Ùl6½zXÞúQ`b‡óÖu¬I<®úÆ"Z·(˳Ù|œÓ¢.]Û Vp¿Zq¨%Ä–mÇ.Ï›¼8Læ®ìäÛWßÿìËŸµi~Üì !JôÀéÅùá°6\ð³/¿Ê’Âò-Š5ïEÝU¼­ò¤„ ʆWµvF# dz]™a£ãZ†™—´OÎ/™…×wÇéÉIY‹cþøùíýõÕå3ƒÛ|øN<퓽¬[Bí¶î ŒvûÚ`¦eÙpÃfZÃ}¶†ûýw?øŽWpÝ[Û’/?ùòþf¥µަm• §§mÓ&É1ŒFÑ0Z¯ïŸ?û< ÍívßäÍâlQ¦¯{¤Å?ýþ¯ÓÑTiž¤•išóqœ¦Éx8L“uhza<~w{mÛ ¼ÃîøîÃ2EŠØÛtÇ~XÞÕvº8ùþ¯ß÷Ý+Dz(£ˆ@‹²ô˜M@`Lfž·9$Bô6U”XŸ~ö¥%F†iYá ¸{ûz8+ÅwÛ}Y×E¶‘…`žñ~ý¾Ë›^>óöGш¾ïONç-u4 ‹:׊u¢²ƒÌvC[¤ Ħ?´¹xwsgZìÙâÑÛÛk®…o³$mêÄÛõÃl>X Ï|ý£;°2›Ý2»Ž]dÞÄí²¶úôlêñj[C¾|úìzyí»„·B£À‹Ì‡ë`öäÅ),tÙ¶'§'ÿë.êÝ04]íún~80b¹_õ¼p0Ï'§£á4àmyõì±D\+ÅÃhæaňAÃAhyaì²|÷øêi8v¼=¦wŸ_~1^Œ Çìj­A7ˆ¦"“½ªµC”—{Œ0c޽AQº?JŒ<߯ҶíŠñb"R"ÍË¢Ô DUyÇUg¬ëí¾«†¾9QR`ÂêRh lÇÌÖ™éQæ¼ÓMÛ8+[N-«i Ûô Åœ×RAjZ”*Þ ­°P9‚CZ·)D˜R£lÓÃfíE1A+Z×%¦k¨ É“£í»P!+Œa[ö!1âXÈÖ²Â>/8hl'0S¨süÊUéØÞúþÁôÍa4¬ëSF¾è•BBJUféÉbA ÜŒÑx6=.÷jJPš›55¤DÕ=üæf9]Ì›ªnŠ H¡°°±>î÷«ëe<nÒû6ë‘Iܦ®©7¥ å]=±"ß‹°–LJ6ð+Ä‚6+Óá³/«lëºðâêYÝfÇd‘ £$oó²³â(L“´hêâdr®LËŸ„g£¹F2?#?º½Ý(%?ÿô›¯¿sÃ0„MÙôº•÷‡ÇÏ/Ú¾½yûj2›uÎ7û¾+mÃQЬ©Òš’ª¯yÇ·i3Í„Ëåµa¨º,“„¨‹|3]FÓy•“ùY+ʦhp/ó.qÝÀ° DAzÜÏf3@A•¦†aض­”†ÌhŠH1ž\>Üß`aB•è8FeYµÕÎ…UYgévvqÃ1ywýp:ys}‡€žÌ¦ùlѶÅq¿› Ç€ÂåòÞœm’¤‡ *ùîýÃÁl6L’´oäÕ‹ó☠!,S;†…S;0«}z¶¸œŒ§ëû?cˆCch¹´íâü±IÅjó0.x×”E [Ì=ôšw·¼ÆæÈs¼4YUUc›Ži¢üP 8Ï&Ö<ÏÊ´(-j:¶ýêõOžå¹¾'d7ÖÉÎ òù³'y×®·ÏŸ<½~û.)2@©¡õp8^%Én¶ûñ‹ÏoonM‡alHç'£óÉ`øèù³À~zõêwÿ·½(³$¸žU¤™3ð«4±ýÁ(°noßZN¸Ù>`€î—{°èùÉéS.»ëå?~òD*¡’Jk¥0ñ `V WH @šµ“Åìêô¤îŠoxu> rÞÌÅï^þ‹áãˬ8”ù!‡‹“ó?þé÷QÛ¶C½]?DƒPsÀL«l2!Äd2Ëòc™UR©ÅéÙqu4<+ÍWƒhÖv}Yg‹ÙÂ0ÍN×»ÍÆ6=×·£hðæ»ïQ<âœTMJ0ö½“oÞýáë¯ÿ°^—3- 4¦JÉù0¬êî˜eCß•\Z®Ñö¼ÌÀôx|ê0kq21(iê®UÉÀòV¦]¸áë¯_WÝ¡*›²ê)U‹ùù?½c†¶M«Ëùð$¾¹þ`²„…Ýd“feˆKÈAg`Ž€ÓÆ1ÚÖòêÉ9C²hz@µicÑÀ²­$ÐçÏ6›|ýðþÓ?ß“C’QB)C ªùør»^¸:y‘eõd:ýÉÅb^w9å†ï‡“óé(¼8îöϾº|zu®{ Q5ÚvéÏý‰*´i1àÀ×um†,-’0v€AšžÒœ·M÷ø“«ì %QšÔ¡?¢L‡ýx2œLfªm/è„´™WwCÕ– j(toÖh:iÛ$+ “˜Œ1˵=Ó[n®-Ë“]—äG©|½\ªËÆ€ŸÎOoW÷„©‹Ùű.Šüp~:W˜”Œƒñòáaxð¾¿Y®ZQ_ž_}ÿÓw•<Ä£1 !ò×?ÿéìò‚"ÖuMQ¥¾Qœï…QfÀô¸ß¬Óï¿y#•¬úÚ¦Åh—g]Ù¾/t©±Ú¥JëÀñ€;þð_ÿÿU[÷÷â¶Öf` .A‰¡‰Uþ¯ÿË?a ›6mz«*SɦaB‹‘çÿ»¿üx~vB ¬Ž#ðýã>E l“f‡iš©R–E×÷ûºI&ƒêIÞ¼«}⺃`Ùôl¾˜öe °ë;u  ÃF´²¯.»nðÃû?ž„ç†Í‘-EgÎ0ßîu6ŸÌZÙôͶ<¶Rêw´1'Áüü*–Ь–ƒY(„Þ®w=àyY]={rXoË*¹zñÔÀîñ°u=/°FÇ´t}JÔóÒb®*K³'Ï÷JÞx?z‡4¿]®?yy1‰Ï´‚½[ïlÛ7\…áRµ<3MWI‚°–J¹VlY¦à-Ì0F¨o…’Ußõq°h»Ĉ«—\›¦¥‘4˜Í;Yµ©ï…â?fx]k™‘´Âb‚Ë4ˆZn 4*އ(I¤â“ª¬!…†m¥‡Dă<)Ë:±LJ‰)7,[r©t¨ÌÅkÃñ brÞÙžß5 £Pñºi„i2):Î2°B½î ¸íRË U“i ÓF§ÇÔ4-E[õJq);-?´}G3L³j‚M³±Eí¦jªüðÙ¿äm·ÝÞµµ`ŽÕ)M8"&íšn:ší޻ދÙɰn‹Ã.}þÉËA4b>ÿäéñ¡´(O¦ZË££Ùðîía'ò R7i¾Ç »A`»Þýõë²o벜¶‹GƒA^o»ýÓ'Ïv»wUÑN|w:ñ›–)´j]Ù6:${“ùÄ€‘gjn[ž A‹9õÃÔÜ%£ªíÊ,C3×åmé{âÈF'±7^ìvkf»Ôˆšl ±=Ê6÷–í!€,Û8›?>Yœ½}÷ÃÉùÅŸþê͇×Ã8 }3ÍJß ‡ý‡¯?ûâ ÀáñpôýP´²ÌòV—m-‹²-ÂíréZÖx:¡ö]k¶I@ÝË®ç¼Ì u”é~]7<ÄwZB ¥VÀuãüpË…@Šiؾþñ‡ 9ž›'¹àP#àÛf]¶–qè;F°­Ö¦E‘0\?¤¤;l›²)OÎfMËïn¦³iÒ*t±¢êʺŽâWÿáõl~òùW¿Ú_¯à ½X+Öôåh•e úäü‚sÐãb[Z³íaÇAÒHÃ5uWÕµ´Ûwì¶ÆÐЃxÂSºrMÓ^nV÷m‘ÄŠQ•URJfÑÝrÛ6 àG Ò0à×ßý%ÆÄ@ûÝÎñ£uúàû‘…qÓ·½Tó“ù·oþº¼ßK¥j»F–u³¾»¥È”|óëéh2žUÓµiûù—_=ÜÞy¾ëŃlwÿü‹_2¤6nˆãýöïþþÿíÿŽÏΞB¤1* „’™Œ ! ƒp{,˲"˜ú®Ÿ•Å81‚{- â6uo0=-žŸýò‡WÿüÙ%Ûã±,ª:›.ž˜CZåy«Uvñèþ Dõ0ùVx³~=‹cÍ«m³"+üñ€1ܕݱÌ//O³CÖK)×"°çï€ë{Ôsîß\»ÛµM•µJu¢¯o®ïß/†BÚ¶%¤Hó¼ëzß²•¢¶o±AU4Q–ašÈÿüϘ2)EKÏn×+Ë"¶a×eÿíŸ_•MK‰Áû.ðESLî žkÉ‹úøälÞu*-³á 8f©âaÔ4À¦±ÿúý­ãÙ Ñ^À^µ¢Ñ­$qè ô5¾¼¼Ä@gI5?‰þæ¿ÉvY§+.9à‹_|Õ¤¥ýélA ]ÝÜ>{þÉh8$ŒÙ®›$»Áh&d´Šâ¡ã²ºJöéþöý{“Ó¹Ž=ð£A0¨<¬·Žì‹U•—«Uá…~ø 7ÞÙ¶¹˜Ÿ¯V÷†0B½h@eTÕ1˜Z6]g8&†’¢mS×B(«ßüôf6¿üôÓO»^äEê¹&Ô†Êñ¼ºê\Ç7 Z7m/ZÓÀ^´m Ü×@ Q­•¶]Ë ƒ®n0C~È^ L‹jÕCŒû¾©Ë:Œ‡Jñ¾)L,.;!¥Á”Ëž›0B :aÙ.Z)(ẋ!x‘æ¶B“ÃŽš†î¤aXÉ¥–i9X³¤:ø‘Ç{U)…´BrÞ3Æ”¼N—E†0c¦ ÐB÷¼-óÆqˆ`~ÌMÏGd›=3mjãºh¥fÔ ²Õa D–¤Ô¶¼ÀÍ7EÙ4 v 9}#«&‘•‡óc¹kêV1G¨*r=‚­h)„Y›žÌÎ¥ÐU±U’òZYa–¯µjx3]<ËÒC§{Ûòš¶D˜Š,WÛÄ»½½‹ÃayÒÕ•a9¦g÷}m{&V×4Xêx<¯šªÈ[bS˳ÒBZ&óJ‰E Üoï„cÄ…äX3Xî÷Z°‡Ã.…ãoò¢½TPhïYá1Y* ª¤KÛ`àüÙÝÍ-7¸íFYyðB»Ü«õÃéÅ)ºÝ쟼8q-//*ŠÒ0{¿½§Ðî; ì$o[!f§†l¿ßf“(Õu;œ{Å!=[û|³;ôª`”ùF(xMc³??;ÿðþÖ Ø0…«Ãæêò´­zD Šùîá0±fù曬(Æ®Û Õt=Àb–Jj¡*9‡ `‰&ó2p–5fON¯Î¦ˆàô¸‹¼˜VUí™år¤Ù.Ùg a øÅéâa™”}5ô¶ãfå)0ÌË<õíAݵB•ãá”÷]º_/ç‚‹¦+/äeõøò©¤­šùÓÙG/^Þ-ïq䨡R^lv£xþèñ£Ålñí¯Ÿ?»šÎNWéÑdðòâ1ÜÉIl»fY6Ï^¶¤´4˜!¡"Äæ¼ö£°L«dð£c„1A¸×R5QÓ,¶ zÛuº¶-óÌñ„qU$ê®oÏïš29dÑ0Þn7J Ë6—Ô²Ú¾@*„ ‚}×2â×P*Å ‚!¬1QÓsû®DÈ4,Sã:ß7˜®J‹„Ô0¸8ȦÔä¢Q Œ9àÛ‚w¦‰58—œ÷BiFý®I Ûœ"„PmÙq]¿ë:©¸ U×i„˜mõMfÌêºFÛÔ$V·Ì°1¡]ßô¼5 su·v<‡R{³;PÓ¶,§ÈÚC¶›ÎNªº·Öµ™LM‹é^qf»¢*U×´&Æóái/;!s`„«BwÜpÜÝa㛡aºƒ‚C)»—?ÿUYTM—)ŒeÛžžÌ-èóÆ ìóÅIºÛÚž6 Zïv¼ïÑ\(lPZïòó§Óx/ï7vçwÒ»l‹<-NN&w7ïʽÇ.1IõVH $BiDKšÔð!é¡B·«]úUV )òbïºÑÃÍífgy#Ó³WÛ»ô˜ACn6·ãዪ+v›Œf³ï¿ýæÑü“ùÓËW?ý* :&Û¦( ËZ­?(ˆGó‡Õ;­Ùô4ÍöEÚqÜ´å Ú./ÒöìâI<ŽYƒlÓñ¬:­V-/=æ¦ÅdÄŒ™^xýÇKµÈ«²-W][Ùqóæ§¾—„‘®®ór³Yýÿ$Ö×®­[‚ä‘ÇŸÃÌkΕöÚñìëTU·-ƒ-›Ù’%„A‚€ ‹ ßr„Àí¦U¶qãÓUuªNÚ{í´ÂÌáÏaD.øžâ;Œ¢Ålz¥ls÷‚¸ïŽ­…û}¦µD–ùnЋܥ~âÇÇòAöØs}7§Ua¬=æû$sŸ¾¿û0=éAw*vó‰‡wÅNW¨W¢í²ØžÔ‘¨Î tX'Z€eE:ˆóVîvK—sù߃ d—‡ž·zx ®õ‚t¿; Ÿ={¶ÝìŽMõüæüþÓG¥+f°¨U×ç—?|‡1œM»ÍFš–aÒv:öý››§wç“™f³ÙÇiE~žUVk  f|8^üí¿ÿ×B»QœPL#ÊH×e/_~€Ñ&ÿÕ¯¿Åóós€@ÛH%%„VtŠ"ÂîÌºÓØãbE€í0Wm˲\Ÿæ£‘UõÃ*ûìúÕó_þWÉÝa{uq… “d·ºDÔêÃýììšù°)jÙØ×gƒáéÐhÐQDg/o‰@ )ãx½^úAxÎéÔ¾}óãõÕ°mz«,PhEéŠöT”/^|s8mþö÷¿ËO‡¾2y]öFYe=¹¾W×B RJ{Ükêºo¬á?û§ÿÜ Iו}«¢0ÖÚ<®V~m«"ûåÍŸ8O†ñòþƒ±Þõ͵ãƣХE#"×ÇØ:Ì’ /޲ÒçÓyìEmÑ F#HÐõôÆbÀ÷«—/yÀ!§Ì É`8½yûæÙËWI:üñ‡ï•m¾øêWËåZ1›]2„¦ó¤,ŠÃnM8Y,wï‚̯æy±ë5~¸{¨› aße|»Ý.ÆÓº-˼FV3[‹1ÄÊòh8»¼Xì¶Ü$£XŠÆH¢¾ï!â^î‡A0‰£h¿Ú+Fg34Ã]' ­.0U³*²šÑ`º¸t<åÖ÷ÖòÎñ|Ç [Sb‹ñ8Ï1"´A IDATm’=ežé­ílqƱS·µãVR‹”1¦k„0ÓÓqÇý 'PÃFT¡ëcL•’®ç×Õ™Ów´ ½Nb£A' +µë'*”º v]Q2JTÓ)­)áœ1Nü¦©«®H’¡T °±÷Â""Œ9ò”m!ÁÚ‹ÖZC‰¡ÄFa®]7Ö€B‘µ»¢Î9#FC¡d%å©äœ‡¡ßŸzeêd˜te°Z¨Þ¸>šŒÇ¸Y¿¤©nUÓe‹È ѹ o7KâPÇq6w+ʧÜjÞÊRÆ÷fá4ºT†º¾CSžòUä¥Ê@£eäGƒazÊ‘ÁpÂý~Õô *5žiÝ0LÒñ\Éö¸Ûé`¹¾¯ÊŽ27¯O7çOÇãiQì; ~õߎ+£á¤o+/½]YŽFÒÑdôã÷š ž\v%ZÙU"žú>“q*)ê›îübÆ–ï²ÞÈñtLi,ŒpÏRm-b1@kiƒ¨‘˜-^3Þ•]3™?ëëMvÈ“'5Þí{¢Â¬Ü!1p«.“µˆœ´Ay[už—"®Fá´ëŒã! ¥øp| ÇÉyÞ,ûº¨;¸¶®…hDÓ]ê2HÖºÐ×__å•™t}νÑúç—¯®†£‰6È€¾Ê7ŒFq̹ǜðf~á²ØÉ]ä°´¬»Ï¿xU¶²©ú'— D(Ã8¦UÛueD®îl¦.#÷ãÓé”`¼Z=¾üâ5ÅTK±¥”§ ƒN(4êëúýÇ;Ó£Ó)'œk£½Àq8×Ê,7Qè/&“V´”Ò(÷‡=À–;þ›·ïœÐÀ¹}{›S'ˆ>}|÷ôåÍõüúÍ\\]5Öö³o¾q™ÓÈêó_qsý²n2mqyhÂ$˜N&Úc¹þí?ø¦-~þôYUUÓâRô|~6˜¤«Õn1¼zýåWR©"[a†ˆõû¦×°•MùüÙ«»õõù×YÓ«µ±µ©çx.¯»–P ™WÀ8Ïk—ñé8®Û®" cmÀr{øúÅëÔÆC¯3%&Ž5Ä ¼?}ÿ÷WW£át³|Ô@¹aj-YÝ=„Aˆµ,&ëåFi¥× öË­…:bB„Ùfÿf4˜Y‹ò$z»8n ®²ZKC8ð½¨iªFÔ &Ó‹w~’J¯W«ûG`8"V› "¨íÛQuBcHŽ8¤½ìÃU%Ã$üõoŸhi¼ ‚°©ºV©(òòckXn>ýÝü¡ gúýÇG èÕõùÝãcE»:W¥NÒñ¡(Uæ/_hUç§6H§ÊôHÛjìP-”êº^\]‹f]5¢è$Bˆb =–O_|ÙôM/ÚÁ`¡Aß´%$žã£t³ÓaŹç…3èÐ6ÏšN dòjß”ÝÏ~qêâàTdŽç]=ù¼* Usê“d2YLOÛÃp0»|v‘9f³ ¶©N®ïJ%ˆã!ÆŽ»¥Ýüæ²Ìû®GAèpê–më8¼È ‚½ád´~üÄ }XÝý›¿þ×Z€_ñë0„Û¾²pîI!Õ]×ø@‹Õ0Ê\æµ¢D–8ž—·û2o!u,î\æeÛ«Öa¬¸¨ëÀe˜hU×vÜó(Á}cZQ¹%–º “j€†Bƒ}7T](p·-Z ëSÙkÏ÷1mm‚$µXŠVqÏMo³>*- G¢1ÆXˆ5PP›ŽRÒµm´Æ•u㳺>i«ß“¢QBX+€Äõ‡¥ìT…ª›u’Œjuèº. Ƶ>äÇ|8[²¥ìät6}§•å^€-öæ^ÛÔVª‹ëgÚt¢¯ w0r›Ã.J}+]‡QIÝQ†]ow»}¶O¢ ©:€1êÉÍ×hcëÉôÂ@ûøx+ªº’QíøÃÃé¹8¤)Ò@‘„î⶯e£”égªEéºl’`*P¥Uã& kÕ5]«ËúºjOÞüüûQ⎆—ˆk Ìh°ð‡DQì €tŽºNï«å~³ˆK}²}ßõÆ•ýî?|79`‰Þ¿y'e‡Ãªê&ãa[WEß“˜CzÌvØkÛþô‡ß‡¾?ÏÛº:RìLJëË Ïu~ón0P E'£aàx}×ÇÃP+a \¯nëåvK,ÅÓÓ!‡P+='´ÀTeÁáÜ9w×÷7Û‡éìb¿=Q½úê7§ýÁôÙëo~•yy²„wy9žŽZËãÆõÙÕÍ‹ãv“ŒœÁp²ßoÐ¥£®ïNF£éííŸg“4Œß~üøÎóë—ï¹›Ng.søã÷_þåkė_n‘ƒ‡£«Oo¿ÇžI¢i}ȸC¡Çõ}%‹—w÷ƒéB·p»= ¬°Ü!uQB„ 4 €®­Æáq’ö­*› “^5­PO¯^ö¢i›r>{AÐ7å|~µ?l'éð«o~û§ŸþhðÓ¤îz‡×õ•_ûJhܵu< „›õR[5™œ‹®Æõ¼ºYL§^–>>ÜÎo®¡2ûì>òx“•†3Ïól¨ïÆ£áßüõï„éñËW/µ±X©4ØÁV™ÿ¿_Jt¶“¶W"õ}-µ5j>³“±Ê=Nà}ý¿µR¥ƒ€ó´ÌŽE[¾|ý5ü—7?ŒÏÆm+£09ä{F/‰âixûç·ˆOŸ¿*Ž'!;ÊI:%•ëû»ÅÕ €`q:"× OveÛ—˜Jüh086FÑÀM QoÞÂ̸þã÷FÆ‘º¦)²X˜¾×‚B&¤„„Rˆ#ß&ƒVt•èáÀèñàúW_þÊÚÖ@£…8Œ@à¶¢ªº=£q[6½U‹ÉùõÙÕ¶ØO³íñnFÓ«‡å§¯¿ø"’~q<¸aÛ7Q )8g“Ë'>¥uvôýðâìb½Þ!?À|ß‹ã"öì³ç§r»[oÏŸ?©ËƒéÑ©ÊD_ø$T@/>@Ìǽ¨€›Ó:Œå>Û¯wy‘; è[a¡ ¼¡ëhDÓ›Øñx²˜^ôªýÍoþrz¶h›Œs4›Îšºv¢{X”Õ|>+‹¼m²À w«‡(áJ @1 ‰QPk=™Í0a‡Ýöüê çýWÿꇟþ¬{öõ¯g—)¨14Ä¢4R©[b\ƒ´EÆ¡!d¸jËêT…IJ(C–deA¸E2‚Šühe®Óv @ÌD¬Â†Ô"?ž–a4[­îëæàòDX!µV¸®k•v¸WÔ9°Ø  ˆì»áâpØo?©›ªËzÈÉagNÒÉÛ?ÖeÏÝ@ªVKËü Ð7‚{AQçŒ iA߉ºÎ¸ï@€Û£²V ˹ש‚bŒdÆ‘Vuí)pcÍòî—Ùô‰ÝñâÀâ6ö²>ÔëØ;'Ü=ÜBèŒÆãS±Е¦“¢B&Òº³\9|ÒÕ™ÅÂaÎþ´¢˜æÛ2ˆb?ôË\–UÄž¬@­+«M¯, e][ édx÷î6m&î~yóã8UUk€žÌÎ~üþg‹Âüþvåy8§Ù¡È«ƒZv* ƒ®*•D„á(Hß½ÿ`¡E ´ÒÜ©²½° #Ìz·ŸNκ¶—Ò` F}§Ú¾3_ÝÞ_?ý|÷°jºÒ‡‘7ì»Ö÷‚,?R ƒt½\ëÓÙÙÅÝírõøñâl°#‰ô¸ŸÁðë_»/Š»»·ÿèŸüUÕ4RÕWOžu')»ãh~þæO?—õ!NÞ|ÿc§qüÀMÛqÇE€:Üõ§®ê¦©­®e uâ(ÊN=„N'[£èdrö¸½mNÇÉ쬑µ*¦Zê³Ùũ횢`„ â·Û²)†ÙáÐumUä髼9>]^Ýä»c-Ëáè ÙÉ.ðÇ]YÏÇ‹›WÿÇÿö¿[b^=ûb ExÉ©h(ÓñÙ§wÑ ‰ãÙû»Í&ßdzÉÝÇwq3ßëj†NÕ6°'ÑØW>¼Yv­¨Ê.ð]äòÍþ$£FªSv½úâóNÕlõ0!ĪüT6õüâ DðÓêΠ ÎE/[åøÐõùlzq*ö„ëÐwÛ#A_#Mv¼[­¶‡åW/ŸWú›ßýÎöb’Ì]ê®$îvËÅùÅî!ó"÷Õ7_Þ¯?ýðÇ×ù-3?yÓ4Xd¡á¹Üu(`ó¦£bŠ %„Óá¤è‹¾“M-9Ôåå—óËë'Ï…Ëõût¬‚(%“S±§Ô6u7]\²Çª¨ÅóùyqªŠ2MæU-¬Ò­¨Žyep]öéÝíìì2I‡ÝÎõü8ŠB«õ‡7ov»Œ2f­6Ú`@|••PRb´±Ä凲ÔR*[!±VÿÝý?0Ÿr‚ÚNAc?ÎO¥Öõ¾?üôg¼ê&°-«€£ ëúÓA(Õ<{úâp:eÝa8H¡áƒñ|²ù¸ ÷X$új§»}Û ‘øCÑÑÝññóÏ^3€¨ \õå|¿9HÙ †ãÓº ‚û>R\J•UÅñpZ\^E£ôí/Žãa¦ùñè…þd·MÅ£NÖ»²¼ÎQ§J—7= \ßaY§ëšªÉC–$Q$ŒÐ –`‡H:0…ÃÁðPd·ø‹oÿ!2øTí(u׫=Â2ð¢&¯hàÎ/ž=~ºïTm °Àl«lw “ЋXšLŽÛÆ6ñ“SYU9äcÀ“›' ϧe×ÿÅo¿ªëª6Øq…؃®Rñ-ƒ?~€.f”ð÷oßxa,’Më>Ð* †®çïWU_Ofã옵Bi#“qÒ(²^>jæ[ÝƇÉd8ˆ‘ã~¸ý䜂(âƒSµN&½Tëí{æ0eïÁãö#¾¸zª¶ÆhAÆ\et+¤Øô½Dòêå«ývwÈ3„ãøV£íúð/ÿù¿œÎ]Wn–»'×ϳ¶Ö½Ø­7Ï^<õ­ë¾jò³Ù4 ›å„ŒÑ6 ⶯˜ÙádþöÍOˆŠù٥걂rêy‘ÖÚ÷‚ÝnçáÕìzó¸V@ùÍW}#7Çmû§}áÇIU¯üùñçŸoI´>µëA%îXÙŠÚ¡¾Ê*QT5€¨ïÛÈ)£$Y\3ÇŒ ¥©›úúC@ŒÕ°«õÃæ¶íÀlxÞ¶­Ì—_|s{ÿ3'i$×7— ì‡usŒü0IB×ÀÑln”(Êb~s“w¡SÇkëãx4ŒfûÝû&Ï£8Ý÷bˆ9æÆ  p,Ag‹‹4ÞÞ~ˆ¢d¶˜V–|¼½MFžh1RÊêÃ]C± Ã0Že±&Q¬j)tÑ0M'jØÕå<zI·m¥ˆr¸‰·;|ðÝ(ð¢VŸtmÇ“q§2f\×IWïgfeûÐ×ÝÙÙy§jY÷Ü 1¦«åæ´”ÒÚÌY7Ëßüê«É`âú¸}‘—ñ(!KÑY+â`Úµ-"Ä($M'‰–íz½O§;¨./¯Ê¢4Šš3ÏwÊSY×M2JŒ‚yÙB(É%© ÄAYÊMäöG QWׄÒÐOu³,_Ìf-¤¢m¡nOe•çs$ÄH ©±||ÿ8_\'ITk×8ŒG^øüó—­êe[ Óé.ÛÌÆ±–¸ï[ ­ïûq’¤ƒa[£²Ø ¦“À€‹æ]œ_AÐÌfg¦§|ssõ¼Í«Ãi3H§~è)fÎÏÏêžMçI”°C“$|zsc-kDñåç¯E Tašö¥”ª £0ß—eWa‚N›M4 £R Aóád 13ð¸ç ,®ªš2  ©š$NGÃ^eËÝÁó k#4b0t¦„³ýn%:Íü ìNÈ¢¾oë¾ƾíÁd8X̦Рä/_~Õm/+„èõüåõälÚ”"6ÃÍr9¹ƒxòðö.ú>áå±_Üh€ÿÏßý_gC@œJaÀž\¿,„v)Nüa]•7×çuk׫u:I2þéûwÜ£½è|îÇáÃíûÉôb´Vû#Ä0¾Ÿ·Øa»êDŒC6LQŠ&VéízYO¥üÙ«×M×j­¶Jl^ö?D¦Ó㣳xjM_4;©yÛ–J™¢”õŸý£WŸ}Ö—M×ÖŸ}~Ý”mÝ4m»ŸÌ®"/Þì>!è`‡ù¡—mŽQš ‚c²^=ƒx:œtmýp÷0$a˜®—+×eEž1⟇¶,¯®Ÿ6uµßí£8Á.UÝÔ‹LµýÙl¾Ï>U§Œrø°YÝß=Ɖï‡nUëóËiÝæ±cŠû^(”®ÃÚ¶"›•ÍÙäúÕ«Ï”Z5Æ(d-DÐ ü¾íòlÉéhØw‡ÑäŠòøpü0Ï©SŸ¤ãÙÇÕ'­ËóÅó¾ïO§õ8™c)!‚ZPB¤¡ˆ!!9‰¼¨Ç2?Pë$gãÓv‹O§ñ0L˼¥âÄÙí3!r‚€u\/B!§ëOŸ¢!‹Âhùiù°z﻾lEUçƒx¼ßn<Ïõø,êÀw/ç×m]qŽž\>øo¬Òʆal-Üv£Ñ€a·­3‚1!ŽçQ×åRê^Šë§ÏË,;fÛ }ßï;aB@üÐ_î›N䇓ƒX˜¦ ãÅ|º8_ô}U79eñi·®ŠáNß·”;Z*€Ëý®8iÒÑEyÌ´l’Áô°[y±g4ÎGî`D½b¿×Ê ³<ÛqÎáFÏs\/]O¢Œ=Ü}t\W SW­ëCÆ‚ªžçX¥U×;+D_7¹xÖB)Zê8ˆm×–c‹ˆë9V¨<«Ü8°VŠNhÐ3†v1§]×¹Ì#±Zim®çii2Žã0ê ©)¾ë[M4”QQk‹#¬>˜ïaLóÓ"3Ld_C,eÛz£XöÒhàú®çƻՒRz!„qÖËR ¶lŽûùôŒpwu:9Dkm»Jy„UM!9_ÌŽ‡ha”ø¢—ï>>öêd¡q¨‡‰Úì?v¢¡í³²­søÝ‡wå©-ëðTh |Ĩ´ PqssÑœŠÓqK8Šíw'ø¹M[WeÕ4- h‰ÇƒºÉãQÄ(½¸w°õ‚x¿ÞC¨8 ˺b§,ı؆×ô¨¯sÊ ƒXw­…í± f¨>¢ïÇã…’]U“4澟NgÚæmS"‚¢Èûðæ}4z.l2£5 Sºn`(ól6›23²7º!åØ6´TqÌ<:,²]è{œ‡›ªÍ³]WÕ{o˜¬—»Ýúý7¿ú¢«ÛF£(IYl­b ­W»¼)\ψ×MÅ1Fþ»÷o&£a×w¼óóQÛ —ÂáÀݬ²^å/>{Öµ¨j[äà6ï‡^àÔÇ|8Ä‘WgE#j+:ÐÚ¼{!”JYk{¥ŒÆhßs””ÇuD§1á›ã&uBkuê‡m%ƒÔùôs‚z¾X¸Ü{÷鯻^µeƹ«­r(]¯‚4JýD }8î=Ï›ÌæE¶²*©'Ó‰¨¬ìú^Ôó³ Éé´d4#O™¶ÈÊ :ÕDnPÕ'J'LÛËYâFÃ7oÿôñÍcèó«'מELÖÍnàŽAІ=Çu¡ÑeU{.´½*eþ?ÿ/ÿ5ØíP åŒ1Ç©ŠÆc|vvþ×óoR“ñ¤êd]ç‰¬Š£Ö­ç¸?ýøÃp&ãåý¶b4ï·YGÀ ª¬ýЗZcD ¥¾ëwmWuµìú$5}od?Ÿ_¥ƒ¡5ªm{޽ªh|/$h 1ĪU··?;Œ¦qò÷ß}G¡#{Í8©²šjJ8‹cÛª¶É“xÌœ„a¤áÅùÑý“›g}Ó0Ÿ…Ñpó°=fû³óùáqo¬âAPgM”&FÛlŸ!Æ“áø§Ÿ~t}0LÛ²'ÔU©µ Ë»;u]Vw?šNÇÓ«ñ ˜÷¶1Tæ»]/åvs2d®G9ÑÊ–e‰°åÔ6ªñy lEÇ |Þw-†¬]Û´ƒxR·R‚AŽ®úÊuîî'”Ò¦¬Ü€`«º­êb8ž‰¦«Ë&I {€zʼ²*¨ÏÏÏóqgNStRÕó‹¬qã:Á“AÚœ @`šŽê¢rƒA‚1q€­ÛŽ2Çqœª:1Ê0Ú¶o0²žëXÚ¶6«Qp!k×s)Š[Ó÷}ë³ØRÐÕ Au¨ÕŠX*DÛv5gÁf»Áxn`”Q¨Ä†H ‡áëÕÖ i¾/ëVFǃüphT&[ݶ]…uÖ×e>ZŒK>üò“?œ³ö~¹ŠCÏ®èû‹ ßÖºi›³ùð´-›]a4ÙçE9X»˜é((óQwt¶MÓå¹?Što|6}UfÙÕüA-H’”x˜qä'I×5É8еBy¡C™§¤PRâ3Ÿ1äsÑCmD¨çÇÇlopÌòc;eV§A"Ê!%¯_=ß<ì?~ü´¸ÅÉâ°Ýú¾ãrW€vrq–=î«ú8¹¸Ø=óýþùëWÙòx÷ñž†¾(Äp6¤ã<ïË®¿œ êZ-G£€ZÞIT!,ê2Iƒ®VÉ4 {4ReÜ:‚u¶îËöbq“µÛ.o¤B†’A2N~¹}ç¹—Žêj“¤1ÆÁé¸>ŠA2 |îz`Qßî“á™vwxˆa ±æ§M!4ôý/·^ä‡ét½>ôm=LÇÞ*„ týq:ŒÏ϶ûÜåèúÙå~½RŸæEÓwEÕ7?þ݆“ 2èþýû`6¨Ec–À@F’A<ó¬@{¡GMÛV"«Ë—¯>?V}UÊtQ<›ÄCäB/H‚ÐÍNmÙt6òÝx<¼xûñ'FÙ0¹êMǨŽãX#Sf›F´Ç*¤±‹ÝüX Ñ}þù—»ã¡…œÖWÝêP>ñ²­Ûãön6íî—J¨®W»íƒ„^äÿéûVËÕ_ý³ÿü§ÞâùâX cA(Æ¡G…e] -êFR†‰£^šåyolÝH'¢OžG¡ð?{ñTiøÇïþíëoþ´´hz Â}pày›ÍþüêÙÇ÷ïʲŒ&Ž›V’0”ŠG©ìe]WŒ£ùÅy‘—§Ózº˜u»Ûí!±t­¤ŒG/ˆ’8ÎŽù~W@óËåÃÝý§E#‚(ª²XÜs# px£Á@tv½GãF€ IDAT]sÆ „œiá45ÙñéÕSÇó4“®ƒÊét !ú»¿û($ÛÆ¼4 «:ç‡Q¼ËVϟݨ^lËñ`<Îê®»º¸jlûæéËç·Ÿî-„éd ­óc0L˜ãNL¨­Ë|>%ÃQyÌ„7¯ž·'Ä(æVƒ1nEu<G—¿»}w<Ç@d ½àâü)D´ªr àp8A@§ñˆb8σÀ$ÆÃ‘hdÑì“xàpcD‰ÒÀ .I¢ÇO÷^ìŒ'ó"ÏŠâxuóBwª*³`897ð"/Båí>ŒªCööÝÏ‹Å$1= ¹ì›®éƒóͶˆ£ðòòYà¹.¡ÐñÓÀçZË®«‚(0Ú4mƒcÖ6†sDH¯;&ñ!ÛûÄIà¦ÍJH÷‰ËBit-ŠQ0>‡^JÆ\Ì\«5ÖÈõ\ê!«É)o¡ŸŠZ×Ù>ôZI€ ²jAtÃô´[ºŒƒ³ýníÆ¨-`S;-hèb‹vÛ3æQ/ ­C©n-uܺ©šª ãÜ”5ãÈqÝ®î)ç*F¥ÚÝæBì'©‘ÚBC0ÂÈ {%8Z‚8Vu:$>#ž'L)å¡R¢mË žZÕ:^à:Ck²²*Ú²*]N(ðó²Œcñ`uÚC“Ígç›ýžr³¸|R´ÕoóŒ"þá—Ç ¡q4ºýù>EFhàhá#MEWF³$‰ã²<Ì®FŠ÷ïÞÕeÁkÚhc ÚµÝ( …š„Qß[ç•ï¶Mq½ð|Ÿû^@h¬óãùnÅyuDÚ2F[)š¦äÜK“„»“‡ÍÊ ¼éø|¿ÛÖ²LÎêòàzát|‘·Û8Ž¡aê0æèNç}ûIÀ­ì“ÉâìêXfóù|vq•6_ÿöseQÛ—/_žù̯™±=«Š:Ƨuy~yD¡i•áÀ£å˜0XžN˜0×ÁuÝBÈŽK©¨ÏlÐ {³Gй˜¿ XfY1 }× …¥6†U I gE_ž6G†ËÕ'«¬Ž&Ú¡p·ßf‡í8¬–»*?ýöÛH(3V\^œ»ÌX»^Pä{ ºóó§}ß,FÃs zæPÏ ›ºqü°/Ä1ÛPî^^½(Ûœ¼¸˜×]“$qä0Diµ§S 'qšì6y/2ðbñ\Ѧª²6«“YªÚÎcI4Šú2ãÇ"Ù§îHE`»»MŸD“h½þd Dœ”‡#ĬÌËÃêá«/¾ýðá]+…Æî0ö!AuÝ@ª\ÏoòNÈÓW¿ú‚Ø4ù©¨gƒY¯Ôht – ñâó·oß¶ õâéõå«?~÷o¿~öóåWÆh¬º—Zkc!RSZ %qàÄžS6­QÆÄä{©ÿÅ¿øƒÁ¸iNëõÝóç_f‡}Û /Œ”ì“á lÄfy—âÉôêïÿþßÇ£t:YXcŽÙ&Šã¶Á0ÐÚ÷ûóÅ%„|ó¸B.®ž}üðb„©±õ˜k5^¯6q:.¾ÿû¿›_sžX­Šf·^nî?-EY6ýh»,ì:é8d¾˜E…)iº2òc‰µ’s$5FvõòæåseÁÎá°O“$NR!E•猻5„Æ b¡kíî+ ƒÓÉâöûŸµ•º# ì~hëÊ¥§¼üÛ÷?yz!iú>‰}J}:VyÞÕÕͳçë]Y–ƒ4ð‚äç[H44VIéúî»Û_zÙϯÏVŸ–?ÿðãÅùÍnuPJa ·ûìêâiKäêáCzõÙkÝu£A2O†ƒ±ç‡­Î¥Ò¾ç# ó¼t¼PA5ÐJa†]êqè,W+×=/=žÖ¾Ä­-4}‘Í&# @QÇû}¶ËÇã# ð£àþÃ=¦4 “6ï ÒAôUkP—D‰Ò8¦œ€âi«¸ïV…0—“:ïÙáˆd.#N°¼»÷ýÀÃ2Ë¥¬­R1C´±R´}¦ZÛ¦ë)õ¬î$¢ë|—æh¨µé]'ÆJÑa™ïXd¬‚5ˆh†C©­Õ2Šʼ¢jü ”`œqª"§žÃ]GWµ±]ÅRjâ" 0=¢jVµÂ0ꦃúž¯4Bº¾¯µaGȇ6LB?ì«Þq¡¤-?RØ"?´VuU¹ ¦uYb 15zhÑ—JZ? ”Õ©À'ió<ƒ9„Õu'»úìɳ¾,ahMà±¾7M]Z —¯ßÿt,Ì;«DŸmwI2®úÂhË©ûöÃíl1Ò½~ûþ€:IÒüad”0Ò@âð¾íµé$5þáÿý£³)#Z3½œuÇBžú8™ªNï6›Ï¿ýZKØ7=§ Ž8µ¨ua¸ÛÍZiË \_'~úš¸Ã¨9nr¨Gµè¶á0„ìöÚAèAç,‰&5.g}¶ÁŒÉ®—]-¬á^mï!÷ö›¥5ºÕ€¸cl,ìEs~õXT™çz”BæxÐÊZH!”ËX™ZÚ$N«^m×+Jî0h~3ªš*ü гì„ã(ße²V·ÙþøäÉ‹ûÍ}U–ÌõÚ®jE§´bE“EÕ´}µ'€yÜPõåÅu¯+Î7  (q¯ºª«cÇeݬoÏç—Ôó ªÕµ†–ôQ”lNy^^¿|Õ42‚sØt´9ɋ˳Èßüòg€ì(L¶ËU©Kê2 ºt:*Úâ°¾[\]%~²ØÎ†³ÑìÓãÅd½~мxö¼“ýïÿÝõÕ4Ч›íòúzhZ¡Em¤°œÍÏ×÷+æ†ñÔù‘BžËG;œ8E}lÝùÍõæð kX4>"­we¦<:Zœ'£Áø|?Ñ€byZ~X7!~ñâ™’Ú¥-hjéRnB`ˆ¬%—óIšÄ}%jÕJ@Ju­èþûÿöä>Vº1Êž-Îóªè»Ž1ìq„ÑûÛ?MÆÉ 0F–ŸÞ_\<%Sº²Ã. ÂÀH{w÷SòìÉgËå¢Sznž(q™é$õ¨÷óÏ?8¾;ŸCËšjýâõ—y.\2›‡ýp”nû·?¼¼š|þúW÷ï–^@1¤¢±FðñX¸±A/M0HS £Ä«ÏžŽf1÷œº,Ã`H©ÊJö3N ¿ü¤u›v’Swa6À¨Í÷kFÆÃÉ™1Vöf]åƒáÀãA)ZQd‹é™ã ëfg‹¶<†®³~<ì÷‡8ð‡éèþÓ§h4ÒhÙ·»œg4ˆë²Y>||õüª-ôÇû[b°k‹h’ j%Z£ÿéúŸÜßÝžªìÛo¿¸˜ß@ ÇãÔjÅÉp˜lVK¨ºªRÂÈx«Þh­®3Î-®UkÓy4‰ïï1#)NÑöÒ ¥£á¸h÷Fˆd0*Ëý1;Þ}¼wCBÞ7ÈàÀŸ((G9¡Øñ”ÌÇQf»Ìš& Óº,;Q¹.RQ‡ƒtùqi˜6Uߊj<œ)åÐùž³YQ:±@—‡–3œ¤qµË¥’Qè‚ÞbB…(ŒÀnÄ Ð¢í¢$AJ©!†, F"¥:„!f!!°ë:kåâz½:%‰/d -ƒJÓâ³^vMS uÊüH0:”ºÜ-ËZ)E¹G¨K© y€¤ÕX`K´RYÕìêãx^V™‚£\a¨0ð¸·ßo±GBìלVÔj(w tYv#BižWM½e$Ès >w††á0¤ÐÎ#Zl¨ç¹¢ª§ƒëC¹¯N¹Ô‰œnóQ7ЉbNM©3‡¢²îµ± ã‹'¯6Û{æ ºïuÝéã~ 05†OËáÙ<Ž(•‘a2Ž¡ŽUµùñçï/—Ô ò¦ö(}þòÕ);P ÓAL)~õÍ›û»|› &£$çÇëùVB—yÔ'…”¾ãrŸrÏkE븼k{kGVë{eÔ*¥#)Šãñx~ý̨j»:zññ\—åpx¾­vÈêéù9 ¶ØØ$—eí“¶/‚ræõ!¤Ø BÄáá»aWÖž—TPq -˲c2 :Œóª*..΢$­ªrŸ­ÎfçÇCq:.GI¸c „duÚ7U¸Ñ¿û#rÈõÅüýí}Õgé8’  c‚ëÃÃf6U]לJš¸Y¬ïãQÚ¶â°Ù}\vû§?C·œ]]Ç.~óóÏŽ¦iÜÇ?ÿ‡w¹¸jE^IDAÜØƒëŽš.Ã×O®šV‰^QFµŒ`°@›Q×uˆÚV)-L/Å ö˺øÍo¾¸Z¼ÜŸVi¹>ÎŽYVí&“!Ž·ïÿ4œ»ž¯¬>¬£ÉØ ƒ®¬,$Ìq#'ÈŠ‚A<NWÛŒSh»Jš®*§q’ô]{Èÿ?îkç–ô0ë—+‡];ÿ9œÜ݇M²É–( fƾÀ¾ñû Û/0؆‹ "Ùéäðçªvåú²/æ=Öîdv"†3$MSß 4²óÂ`qøä¿ûíõÍ»éhl,¸¸ž$ã¶f³Q„·÷ë³³eª¾‘¶ùúÅÏÖÛ ܶ, &“™¼<ùŠ >N$ûýÆ ÆfàVÙ¶/KѨ³ËÇû]îBrrrB…Q\C$çˆyÖØ¢Ø%‹ExB‹¦ã©ã¦q [¹œNâÈ5n·Åòàè`z4šdB ×q5ÖÈDÈC~zzÄ[U{'Ä’^½#PV…PV¾xù<ßæùîöà8›„Ù»7ßOf£Q82HP”›Üu܃ã)aÓ¶G3¨¡¸ë’û‚”«%¡(Š^t˜ÈQ–iiï>¿MSÕIB°C­ä’z`UßUC¯GÓ¤,ʺå»Ý}_ÊI’IÞº® lºbàR”$¥m:Šâhd4hºÚ¡žC¨2š"F Eù$4šnŠ»““‹¾ú¡E)>¦–X&Œ'GEž3L²©C¨£®„ÆjÇeMß@Êâ êë`EaWr$ÁHˆùÔ é’À‹ŒI¹ÝÇɈa e1‚@p‰0f+ÝGé¸ßozΩï9„i‹©C(ƒ.Â][xA‚‚[…(3)£°‚1âР×BiÅ€wmãPW(íã §k`Ô$[ôM+y5]ó¡¥BD¹ì<×Å„4uÅ•HG“ºé4´J% aÔõ]9ˆQ6!)1E.C]Û»±£†49\~ºyG<<Žò|k$8œN‰tU"êU&¼o›ª˜-G÷««zoÓyäbˆt8ؽlz5hEP×V“Ñ´¬«ýÃ}L1¡‹lT¯«›»ÏC·?<8ïšRŽ a.VfÈËÖÈ`C‰{wóþàüL§)‡ÝêH%Ñ(A„Û¾¸89RR +Ó 98ã ¯8uÁ(”Ž’éᨫë}±»|þ´Ül)¢£iRo6 —³ƒ¶¬ B““ƒÏo_»žÓ+Ψ/ä`dóéÐæm+‘„óñX*PÜïâ 0ÚdÓ…ÑRYâ1ЬfÐ…”X  JÎëÙ|±¯sÉÍ(™A®Ö·«¡Qï'˃–÷ÀZ ЦÌW‹ÃK)eS¯'ã…äÐó‰Cœ¾®Û® ÂÑÕûwA6Áâ(a›¢Œ}/õ㺮ï®ï¾øêÇ%ëíCàFÌ ¹‚Y6ÕZñœž^ÖåVôêìì<òƒrÕ!+‹­h¨ë“wôI0>È„PÅfˉÞÞí ·ùžaDèv×Mß÷AQ_k €/O²k|ÏŸ¦g×ï~DƦãåwù]v\§£¥µÄˆ*‰¦ ±ºÞBÏ_,fûr€´mstv±Í·»Máy±–œaêQÖ´½‹©ÇÐù·Ç†lºaƒ8Žšž¸ d(óüW¿úk-ÄÃÃ~þü™—–5™ <öˆK™°z9žÞow¾ÃbuÕÍ3œç‡ÇéñéI[vQ­×«ƒéR[ÍýüñõÅ£ãI|øþÃk€Õ(Ë(Ên!ÅA–ò|¥„‰C?IÓû›HavVýÐÇéÌs=-ÅÐ÷‡‡rÿíæcx^Xæ»$¦ QÇqÖ÷¯¶›[Éñ ;.¸ïú q !òjóèôÙf³V`P½v ±\®Ö¡‹\æûÍ÷·‹la„F˜GlÄ&ﺇ‡µE"MÃ×?^eÓøÙù/ßüôa~:¡Ìƒ6p]­¥ªj¹c¥±ÑãùĶš!R¸˜M¥ØuÛªM’ññ£cakt¬BöÒ£°Ø¯‹ã²Èû® ãQ×?\]ݵhºŠĈûã§—Ëe£¾/ú¶Ãê8}×Qô‚?úEäzƒî˜çGãžoæB´U˜€®ƒ’Ùtl(vÛåå²Üµ‚µçe~˜Ñ­ÑVž5yËûÎõÝ˜Ž‹2|¨ò:/º4T5 i"ì`¥n­£(³»Ž3Í-P#€±[Õˆ¨çÁÐK -î ü8íEÓ”|<›ó~x±E@ÃÖg‘…¨m÷ Ó0Ž­!RB Ð áÀB¯i¥U]ä§ÐZ#±U ÇéÐõ„AÇqÛª°ÈdÑH+ ‰¸ÐÚŒ²±h„µÆ÷IࢷŒ!ÊÔ0ð\c0& |`DYñxj­ªÖó1šWkÎEGCÝ`¶h4AÚZ‚¡6jppèÚ]Ï€í¥lvÒI&e…-…ØH=¤QÆ5צqaG¨Þ!Î0 ibÀšºöBB!Ô2&Bs)”š²×ÖLÒ8ðÜ÷Ÿ>_œ&¾óñÕ»åb‚ ¥ˆ„£hè;`àåÏvëœ*töå¥ë÷7WØwâpL€ZÌóMö]KÂðÑé)PJ9”`:™HUŠNûþâÖÅq‡n`쎳龺=™žÄq:èa}{ŸÄ£û{ÇâÉlÜÃ~–ŽƒQÐô9Vvz°,¶k‹]ìúPöãh !DGiTä•1òüâTJ>ðºß×JÈ M/nnß-O–Ë,ýÝŸþ™+;Êaºü¡\,ªºš$seÏëÉâ”8äó§+ªél²PX»Ž ¼É(a \Ïa®õ1èö}2Nz–2—–MN„™Öõpqùä„ (âÇQn¶$”íWŸŽ–çMSé>‡nH¬ “ÐJ‘ZŒ.P~º»ž3ˆnšÌ’,ôÜp<žÖÝþàðÑ$K[>ìú^°ÍWqæÅn·Û?{òäóíg+ÕÙñ‘¥·7'çGqP¥=‡–Ué0¼XžC[î7OžYܯ\Ï)׺ԡ“ÉÔMã*_Çé„!æ¨,N?ÉÆ~ô„ˆYx )®Ëû§—V;·w¯)Šç‹¥²ÍP™$ñŸ\kò¾8^öC×µ{Ñ´ñhÜì›$oVQõ»^·¾{òôKm EÆ‹ÀÅW¿øÅÍús½ïg³ùÁÁå?ü—ÿzr¶ üÇøøìLKÀHÉ­EÚ`•EÄJàz6 ¢¶j…¨Ÿ^L@`¾ùæ«'_ÕCŽÞ¾zsúä týñýèñs^97÷?NgÓ¦’$Û<<ønH˜GÑû×߇™·˜­W-ïÓ8ô°×‰ŽP”³ƒºXyË<&NW …¥ãá¾Uq’vM†À»ºßbæ›}Ûhn¹ãF®­6R¶öøü ç{£7¤„bÙƒןXàÅ~º/š¼*þæ¯=YŒÝÐíÀẪº{¸"„Àý—úí º££S ð«»NóâÎ} Áv»>>¿§MU÷]vv‘¯ò4N "“Qv|(vùÑéÌñØõÇÆ•Z¶¼Þ[x'ãÙ¤¸ß­ïîÝit[e#û„à8™Ä£ôêÝÛ/ŽãjWBMŸž<-ëÖgŒ9átz"â{Ä*Ñc cQ­à¾^eÁ˜0·íJ$qFU¿IüŒKU ›i6Þï+Ääxxÿúu'‡^”u+ªüÃäh^—]]7¾—6e-Ž“C3™ÎÒi¼ß˜JÅJÙ6=„6Ž˜Öbà—øƒÌ۲˜©Û–m’f][ðZÄã´o¶Àà Šæ¼j]ß8n …Þ‘ÀX eË„ÆZ †Ê×%!0vÊ$r¡„Q.u üoØ\Ãø$N²ÕÝ]6Iü ©óE–8Äp…(Bó¶öChÌûÒ! m¬<`Ž e¥Xpé¸A¸©'À vÖš:‰0€a@ôãÈ`4V: ©,P@I¥vaßBI1±@[c€%XˆY‚ AÆé¸5ÀÀÔs.Níû~¾\h®Û®Â¹xD Þ¬îˆú‡ýx:WªûcÇõ‹ý6Äw’OŸÞY‹/Οë[‡¼kYœ‹Y?~úe‘×¾¯‹”Òó¶ÂÀƒ tÇ¿ýÿþñë_~…'?½Fêç¿øÈ¢8ÞáÃÅÖq2hà ˆŒ¥„* 'Ä–mƒ­eYѨ/Ÿ|õ7¿ùkd€ìšº-=þŠ2üéúûǾ&”VM³Ùl&ÓIÝQ<_ÝÞ%cw<>Ú¬ïoîß4©ª‚8wíÉùe¹+ÀÉ(‰“ÑÍ»÷ƒƒ£S!Zìд"í4žÜÝÝLK×õ>¾}oL ØmÚ?ÿô{«ôê*?:žÝ\mT«¾}í;þ|q¤­ªÊ­Üc£8‰Ã$®6Åh±,»^5*‰ÒÓ‹‹*ßê/—‡›ÕŠ`ŸP„(qœ êúú&Í©†MgFã &ªk•ÆB ‚äPl+uš¦ªÕƒáˆÄilÖåý£³Ç„˜¾ï? âq_V“t’¯wFÚ‹Ëó¦î]f(s¥U±ˆ)U¹®…6Úå7Ô5ži1¬7÷‡³ƒ<ßùAÄ ÷°[-ç‡.tî7Ô!‘l7sý¶+’ha5¨ûf÷/–ÀþòCâyƒŠó(r&éASUIÛ‚ xþìY³®1 þ$RŠN—Vû<‰—Ѷ.1ó TB}%„ë3æLÚv§ÏM¬jòrxøã]ß ®?‘üa‘Δ†E³bÊwX¶*n=7pˆC|œŽ¢ªQ̇ç§GÈÒ·o¿›Ž“¡—9iú] IDATH M•·3i‡Íͪ‘ÍÓ¯¾¼zÿ^éa§7Ÿ¯ïW1@å]yþä2ðÿç¿ü×ã'Þ›Â[G„ZÃÆÇÓº¬«²ˆ'!à hÊUsúèÙÛï_f´š βmþ 8{ú¨í +/pÊ}žDÙÕæzq²½­Ë«£É)òqÙl¹´²ÝŒ»\úˆýíÏÛŽKkLJÈ*«0ÁA,š¾SZg¡ß÷Xk,ýÅ‹¿M’¢Î'ÓC׉òbóúÕŸ¾|ù‹r%¹®Êz~0ƒhû>_ÌgAäüð#N8I)妠AˆGaúáÓgß'ãlY7M]m]Ïó½´ªsÏv·«ÃÓccØÐò^tóÅ\÷ýzurv.„§Ó®i>\ß ž=zúþãÇÙÙÙl:ÎÛž!¥Íà3 y^ï?¿¿}tvl´ä¤.‰}†´/öEÉëÁu7oþäÒàðì<_?lÖÛñd~{}{Q¹)‹ÍõÙùó‡ÕÍÇwo}Îîïn¤Àaä4jË+mj—%–È]q{xtÎûZ4t äˆJúÛw‘ë3ÊþòÝ÷}_u]“RÁ÷ûÝ~·./NŽD/ò¼<=;…[¡§ãìÉ¿B =<=½û|«yý›ßü;­t‘¯NN7ÔÆFqXu8 µ–»Mi1Í’²è…®CbF+dz†<ìxAìw{”YTN|×Õ ÀUJlµ4Ùl|û¹Ü5Rc<¥…¶ÚëÅ pSìžùË8 }ÏkZîyVÒ¡2A8ˆgm{O KâêB‘ë†e½ Ï£ÁÕç7ËÃyš&M[IQz¾«¹…«•,ô "CßkƳö©!¦„`ÊB×õç ôÛ¶€cfº:g6ÄH— •å6pêíöÎâùe5òÆ»*Œa ï»À˜‹…0ˆ4†‘¸ë;J(F¾’Æó ó£µ’Bô½Á„,z¡¬À{^rwõi:]h«ZQ,æ}ß¶U’άQÛÍíñùcU±ÏƒÄ7e¢Id´Ú—E:=šZ åñl¶h«0R@!f+Þ¹Žï¸ëZ=Èlå×uO~ç2›=éÍR0M½ÄÚ^:ާ°]$“V‰ˆ„9“ùÌšúþáæ‹¯¾Qàªv›Ø£ÞhŽíæüì1Ð@éÖaÎ0ðélб#E¦ô`þ(ßÝCG½øâeÙå~b¶R $ÎŽŸ¼}÷Ž9d:9¼[ß+#³EZ× oÛÅÙñîþ.ô½Žë~Ï…ÙtÚ½¤RHá/ÇJ?ˆ‡1Böëýéå‹õÍ{`L¾ß£Ü Ú÷¢ “Óé4~õê‡åÑ…ÀA7-\W#H8ï¯gÉ9×=Ôƒmi˜zNäºÐWV©s29Þ{ì¨,[ôEm BtGãr×4]ñò«g¡;Úæëix؉æÙÏíWÚ ádòÖ¶]3;XC~ÿ‡ß.Ž–Ô‰„Ò4 û‡ý0¨G/ÎE3ä›ýôp&«lj=£­ç„’ˆÛO\?Üë"ßQ'ô|Ǫ¡ÜôÚý6?<}ºÙ­:>,KÇ1—ZiH\Ó5µï§w›«ål*únWÝ•» ã ¬ $A×Ïw77û¼ZEAì øûw<˜Ïöy¿êïªb{µšÓ§_|õá͇õîúßÿ‡ÿ\o{­‡²+óËŠöžïÜ}¼CS²œN_ýé5õ‰ïÙžË]S§Y²-Kâ (Š?½½:}ràúìÃû•4ýéÙüæ]úq‘ßf£3Ôöa+˜,æà÷¯>R×êA|ýøïþéÏ¿ßoW#÷_>zªfb …=ç0b\X†o8 TSC¥;[&¿üæéf?zò¤©·mÕiYLWWkŠ1*ôÇ~8ººz ^,5?|ÿúùÓ\pJƒ¦m¢ 1ÏÏ‹ëE“Ŭ*¶ÆB£Õ$Keu/—gmß÷Ý6Ž2¨2ç2Jeº Ì>¾y»«<â)>Ü>¼g ‚ᮼ:>>zÿþí$ »®yX¯ö&󶯴G)c²¾ë`©çCd‘mßñüçÚº®†¡AÛ¼u.Êb»Ú~ó«oÿð§Å yöÅs‡º×á, €ýzðæãçI¸Dã ·.ó( w›ÜX)Ææõí^kHG3×Á·×7^4åmã°p_U»Íu¦°^UM¿˜žô¼È¢é.‰¾<|±jÚ*‹Æ‡ËÕv‡Yè3ê»À‚aèû¾IÆÙ0´uÓQܶŠÕÚˆ1Å«û‡éx.´ªêëÇ”Vt]”B “ö|_塨‡íÕûWmo´Ûíz¾<ª«•—Nöê %GóÃ0¡¹B—AÆ¢¾ï,RÆbæ½l­ÂB7 Т}³'È ƒãé”ËNŠWî¡€°@›0æxã®Z[‹ Ì¡JH`@ÖqC£5jßõu»w]Ô4MÇÚj 1uÙnµåŒ³h¨;ŒY%Zù€¤Œ5;HÑuC&¢ëŒ5Ê€ ÔXÑóÎõB€­TamMh`Œ5F 1uöûÇBÑKÈ 0iCD!v°»^ߌG#©­5š0'ÌM¹¥ˆ9,àªòœHKÉyå:uœ¾/eÚ@¥¦lh;!@€ ÛwÍx<®ËÆ kt­$ \F¿­‡xO¦“ë×oÇ ÇƒC©0%ˆXÑŠÑx¹Y=´û|q°ªkëVöÅ@id•íÛ¢QŒ%ʶã1KE_Šp5²LJ¦Éç—ˆ:÷«;bX&wÛÏ.òüéÇùéñ$ñwy ÷¢1êº]Ϧ'jƒH8@âÉ£éE^ø`’Ômëa0<ŽÙ(šv ŸC'Ú®vcÇöPŽc‚˜âèàr–¯öRH7Aƨ·¯_½|ù‚÷Ýúá!›‡ÛûC±¤²,÷]#Ï(®×kæú.v%âXQsìa ŒP‚@ {<v©ss·+öžçmšÊ õÝV©A‹¬{óñÝÁñ˜QÿÓ§Ù,±†­w½)/ŽK@Mûpzyî ¯ò(ð'ÙÑz·q}‡§çaØw]^ì.›m‡!I'~ß óÙÔñá,:qB÷ètQmk£ÕÉÅ1¦ÒM™½ºÌ€íוç:£ÛO·’ƒ(Œ<'¨xkŠÂ$àí›;Ì¥ADC6nê}šy}cVw[.Û§¾nšêf}e´cÚí®Fq:u»ùôóç¿øðáÓ¾Þ/ãe±©_ýøý¯~ñwm'º®á-︞-FF™¾5›Õõ—?ÿöíO¯4Tm38Ȼڬ „¢æ'/Îõ þð¯ÿòè«Çžçz6ººýÅ œg_<ÿøù­Ž^¼øª®6ø«g/º®µ)i𡣨‘BRŒF~2HÃ(ò¶ï.UŠ’08|ôøðùË_¾ýé/?Š€Õ¾7.óPhyxH±ûûßýËÏ~ñ"tèTÙ5Ož|¹»m¨o‡¶Å€eYV»¡Ó£,[ýôç¢4ÑJŒÓyÇ»²¬üÀcoW”Bˆ,›]¦yó%#L#`xUl-ޤm^ÿ½VÌñÕd2Ûí[cùzu?Ë®îîê¶{tö$ŠÂ¾Њ0IšjϹV=yútà´0 âã§Ï¡1Žãû½Ö0ŽãÏŸ¯¨k²ÅŒáð»¿üþ¯ÿúo„™8ËÞ¾û‘²<>@Z­6åٓ˦*¡Î1B8P‚ó4‰ƒ€½~ÿ&òB×ÃVŸ^¿@ZF#Òµ«7Ï¿Zm®º='iæô Œ’i.‹,ŸL?Þ¼õI…iv8iê}@=¯Å.oF‘ï9Ñýíêìì"Žæ€97¢³ÐugÑ›·ŸÒ¹:›»ÊCa®ò9h å@{ÆMÒéÃúsgAœ™gÍÃbƒ~ñôg?ýø—Ivpxô¨Èo p..žqͧ‹3‚jØ|ýó¿ÿáÿâ@àÓ ³¼Ýëvmv¹¨÷j·-ž?{4£B–Íñò7ë‡5£8Cvx4©«òÍë·ÏŸ,=yô¿ÿoÿËÏý?}ü´ã}§{Å­C€j €˜¶¼RfiÖ >Ê’ÿéüïãQÒ6%B#Ä\G)öýOÿöìË/?(›f³zøæÛowÛ{-•Ô*ŽF½ºÍ¹àãñ(Iß¾ú)&Èâ(ŒÚ.B#BÃ4¹»CxqÜtû¾ß=>:êHB²ÞÝM³Ó0Šß¾ù£ãLý(´šÿá_LÞ¾ÞzôøãçmqïÒ,²®»<~vñ°º“BKjã0[­÷R¨Àuç'O«ÝÃã³GÒ ª¸›ŽÓõnç»BÐúæúõϾþÅ~[ m1Žâdè+â5Ÿ¯ß=ú’Poß5Æ`Ç#n>ºÀQv\¤ñäîþ&ŽÇ£ñ´ëúû«›4öwy!Q¼+÷e„J Vüp~r÷á~:žeÉ8vâ(I0–.`çggÓyüú»ï¾ý»ÿ4ŠÏ÷=ßdŸø)sXÇhQ„V+lÐÐöq6Z­dg´ðƒIQ=cƒ …H+.%–!ÕvI<¿]} ýd”Î7k´ë…À˜º©!ÀßÿéÏi2Ñ ¬×„q2™<Ü­ßIÇsÎùÅáÌ"æPäzu܇»{Çó¼$rð\"H™Çu«”" ©Ç¥ˆA«¸´žö¢BÈ ÒÌ@[­Öa2ÑØ+­BBÐL$¶ªÙôXÉA…-FÈZ«0 Bˆ0t-è)‰ d؃VŒ=i„ëzCß[+æ ¡a˜º^T+ÏwÕ v¨çtU â°\í‡að_s ‚I®0Aõu‡¤Ž¯„ÕZù¾ !jð}Wö*%JKmDÌ"Ðä…Ðõ<«%¼Ï™0Æ06]]! ¡]íE˜h †”8Hp>Ÿ/z]h%¥eÐrq]5ƒØ;«*]ì–'ûui„4ÕèUi-ie~~ñâöæ~uFãõn›i³çÌq.Ÿ\®¯vþØKb·ÚvœËËŇï>Z,…âj`~D¬†P"èãl”®®î-ƒ[ŠÀ ›0 ÷•±l”¼yõãd6FP×ÛN5Š| cƒU£\?£/x ¸éœÐ ©mú]LÓVòj_$EžÓV{F<Ç÷VG‹ƒ‡ÕcÌ ´Õ¢º¸x±Ù¬Œjæã³Íj7š$²w-4£Iòâñ7·w÷^‚²äHiÈ<û#Å…*K'›Õz¾\`ºFjË)aƒ°Æ6„1«pœ˜²n1 ,¶õx+ƒÐÊZIÒ‘_–µ‹'öº¦Øïšxš}~ûÖq7t©F¡s´¯îš¦Ž¼LÈ~¿[ÅÉQÏwi2Âh„È@Œ¬ÓË=Æ(ò¦ZÐȦ4q3§Éd—?¦Vº?¼þþäbáú™2CÓl¨qË“åõ»]±»‹³ ƒ¨zK¡ž@ýÁÙÙÇ×o*Žç§ÕfÓÊîd6ƒmäpqv¶¯v'§§ÐNÈÙÙñ—//nï mÕ³'gy^PŒ˜KEïBÆ©ë||{õèÉ“(›”EÙ¶y’¦¡¶íÖA(ßG—‡·Ÿo,“嘊•)ùv¾<Š"ÿ~uÕÔÛ/Ÿþ‚«Æ ØÝÝõrt*•€NxóñS}À/^¼¨›Þ‚Z­û^9Œ@ ÑJm(öÚº÷÷òìòñåÁäns5›,ŒÒŠû«Ïß|û›Õý}]V®ëMŽNöûï…Õ&…QþåÏ¿;9;¥„†£äþöf< ’t”—[Bàáòt_×UÙXkŽO6«Û(ÎÚý>›ø”ù7WW™ÙbÑ5Íç¾úúWM]5»Î¢þ·ÿòLJÛmœfoÞ¿xÿâô«7Ÿ>9ˆ ÇŒ—ùz#â½X¤sDàz½òÝðüôŽ(›gÏŸYXÚr5™Ji0 v¼"Õ6 Âr(ÎçÏúnÏM5 'é(¾¹ù|¼<ÒD÷ƒ±x³Ïƒ`œF‰;šÜÝ]?{ö…š`ëø Ìc–9‘””åãçÏ_ýøÊu×zus›Lc@P<òç'G÷·7Û|5™B&óɾi?ÄZ£(£²Ø§‡:Jj0× ÚV{>æ\DÑ1Êy“ÄsD±TÐq]ÎÛÀ ‹jO|†¨ÐmgúÄI …å®ð£‰{‡1 ƒ¢ÜJÎÎ_Þ]æºY]ômq0;ZÉv¸\¤£éÃýçÅrêù£vàBì:¡;ð"òâ¡®â$¬ªÚx!”¤ªw˜AÑ+ce6›Þ~¾ ÒÀó\£€Õ<ͦZ#«ehFXL<ÙBãGaWu”X˜$†¬ç½V–Á™¤s4ÀC=ª…iÛ`â¸^dM ˜Rfº²ÒB¢!r…ÒR´žŸ@ˆû®¡Ä‹£I×çÔqd/ Ôqšµ¥j†Ü÷#¤Y?ìý 2ELAh‰ÅJVQ–ñ¶/ÚÍ|¶hв×:ðh ÖKh¹j±~òRH3£H¯é+Ê꩹Ò*„Öª ò€uS1Ô²0Dþ¤k¡kÕÙùÁ¡€œ hŒ&?œîv{)úƒñó’Ýêš` A¨ë;Iw>þh~xt{ýæìñe‘·m1JêuºˆØ¸ØVÑÄ[Œæ?}ÿS6h¥Ë&w±ƒ0"U]Wï›Ùåädv2ôhõðéäø¢, ñ£È ·ëöÅËÛÝ=4d>Ÿº—¯öqêw-÷`€},XB)B KK“ÉÔs™ï§Ê Qô­¤*ó‡Ñø,NLÈrzÊq×¶U€BL çõ|túùa“NX–-”Ñ”DNèöb7 çùví, 'M×+ÓFñ¤ëa0XjžÎ2#,À= ×¯¾òâÔ ·ªù|áI $Ù8aØ»»ÛüúWçÆ²¢,—çÁ,ZtµO3 ƒb[}ý«/o>ÝyQê…içæâÅÉÐÈ|ŸÆ!/‡$‰1Öù&‡œH!½(Œ>=±(°¶¢Ì++ÁP}³F‡œoôÛ¢p\8›œ;]ß][ã-ÎÖÛ›4ZìË HÇ·W|èB/âC¥cŒ˜î­…¦íú~¨ž½üêó›7„Š_ûW÷Ÿßó¡šÎ²Åvm!ø§øÇ/_þÒXùáõu¯äìø¨ÛïkÐMfÉÕ»ë¿üÖ˜ 9îñéñÃÇÛºë~ñë—w××{M¿½8?×úýãoÿpñôÒÊvs÷ñèàÐÁÕí»å"£ ð\Vï÷—O~Ñ«úg/~ýaSòüÛ_~cvŸ>:Æ–”m)A[«¢È/p]”BcÁašžŸŸ­îïž?ýjßî׫»jW^>iw»¢¬\Ïe0ê½yõÃd=3 ½P¸ÃšK¼Ðíª†º¸(6JY+4!¸*[?ò€¬¡R´e±ŠÃ1dææêóf³MÆÞÿH \c4܉R¥|<:è†Niîz‘PÊR«4Æ¡“ç%%ÄÃ@”y X$„t}Yÿþæãô`f…Óö¥yVØ*/˜O¬DE¹MÓ‘æ]Ç0”´—}8V =~œe”ÁnÀ¬Ôu3ijq_õBäÝJ©! K¤ô@˜ÛµŸøÊ* IQí€èö‚3ÇmçÚ@%u`%"®ÔçÆÈ:ýGAÊlh´ZQF»v‡£N4Ê 7Ö+e(q8-v+?ñV ‚ lë¶®óx6†Öõ&™¤ZjÉ…²¢ªZæìU«V¾ÑpÂXƒÏq–ÚP×kÚh긞Ѻ†¶†˜V.¦³«»×Ô‰‚06D»2™f®ãXLçGÆ ÆEϹmöÅîðäb·¿Ñ½I’”ëš"¿í$°í$™ñüÍÛ¿LO1cÈ|äI˜kÃ0Ìo:–±gÏ?ýð™ƒAKíÛ=FŽÖ-àÁhùöúãárbZ?䯲Ѩ­•ï«Ð§×«ùiŠ!¹ú¼›,ýÉtÂ+9^á¡ïZYAƒ‡n`^´éšöèâ°­óõí!¤¸Àu1‹C÷Í«ïó«æ_ ¢î·”€À™7rká&L+…ŠÍ&™¦¼ãám¾O§ÔÒÕj%1[œßß=ŽÇã~š-O›º-Ê- ðàèòêú“B[¶þt{t|’¦#dA:³ñøÃÇWGg„‚}¹Ï'“ER–ÃtGN¼~¸{úò)úíjã¥Ááäl·Ï'Ë„w}^ì ê­ê=ÇAT«^]ºyòôÌwC9ÀA—|Ó/íäG]›¢éÒCGTÚbĸK“²*å1kidM#;­3ÓlüæõGìÂÅä¤Þס‡ãd¤“Û»²t±Ë·Ÿ_ŒÂyU5ëÿÿù¾¾z}øó¯ÿ¶.÷¿üõ…‡Cˆ{‚½³‹/ÿøÏÿ×ò`6žrµ·š×eûüåÓíús½Ę4Q ïîv]¾º8yy}³Î‹‡p4&ÐÏÒø÷?þÛó'!Œ8¢ØÐtôæý», UýæÕwÿñßý§W?½©xOθÐó¤R˜Qˆ Ð| MÛòÀ!uÇÓ0XŽç‡O¼MMß×Õ>ò#%aš¤ÛÝ}6ùn”ÍÆùÃï?~>?<Ê×÷CÓf)²TȆ¸[›çŸï_§ÙŒP6=}úéc˜¦ØCØBŒpUå‡Ës u'Ê:oO½Ì7×Q˜ƒ©ÇQXä]Ûmf³ú¿þŸÿǣ奈ÅFJ(‚ˆYŒÇ °ûâîÛŸ½ädøûÿð÷ó䨮wç——7‡G\™›ëõ|9³ÉþѪœŒfÛÍnz´x¸y¬;Œ¦ãñ§ë«ãƒ“ËËóûíf9?ò]ˆ?š¤VƒÏ×7Ïö²*ó¦(²ÉÔØ °ßoª|£ªA(usû6'VÙr_MG™ƒÇ3#ä¾­²3Ïó04±çGév»9X{~@0<88+‹íÁÑ,ŽR†üWA"ƒ%T¡®âÄ!È“Jª–guµ&Ôp!±%˜#ußvÙ|5¼¿Yž©^5 ŽÉ²l´’ ÷îf?;˺}óãO?ŒSïðàèý›ë8ó<ì:t:96Eã3ÿðt‰ ²Ò†ÓYêyQ×W©Ï0 ”’®Ë, @Kó›vÃ\j·“„`>=D#„Œ½ÿŸ øà•m; üúÚ½MŸÓϹõÝWIQeÅ¢£ØŽØ@ $È–­È¶(Qäë·ßÓ§ÏìÞWÉ÷Móú‘#=×w•¬ÓÔ.[a`1£Ü]‘Y—…esÑÁ®+Ѧ5m!¥ÀHØqnû‚šØVRéú¶–¤ë¤ÁEsPÜ÷”–r ¥át] H߉NôGÇGuÕv]¯U›öŠ̱Ðb¹ ƒ@Â6Ýï!ì4„Q8Ýo¡ùƒÓÁjµ$È– ø~p}ýV)HK³LA ¦¢®)“éEß5˜bÂͦ-ÇŸ½úêöú6©ï ½¬+(³4ˆ< ÐòáÞ "BèawÀ>{öìãûצesƒe_\@¨û^C†-Û¼ùpsùù‹¶)û¢¦äÜnkèx|¿ÝÜ^_Ÿ>›sbVE_Ãâôä\ö¨U­TRij™È ¸©@ÝÙÙñÍÍÚ …~tûp3»<¢úôþž‡ì³«ùù«¿ßwñËWO>]¯5U²Øw¥eÚ~Û5÷·ÁЃ„/¯—ŒQ%k®-hBÓ$ÛÛøôâˆ;BfHñ0.’³‹c ¡ruûá‹W¯]×Re),D±J”ÄdÓÉiQî!Ä}'UR´„:EÝ QÙ8¨Dé9®a¸Yz€Z\]¼Zo0!Q4ÝÇ›pìäû:cÌÔh>úáiEØ yߪ,ÇóÈÁÁjy{ôä BÔw­†}è†PSlÁô°7,Ïù~‰HåØnUe=ƒU™9vPÖeÕäž?T°‘]«5f\ Õsvœçï‘Ãᩆ…”Ê5šÔu•+m¤ù*δ¢ßBL'ìPŠ4€€bÚQB«ª3L…€¹ß/£Á¨¯û¦-mϧŒŠ®E4eßÔÍôèèþý­æÒ´Ý¶j”î¹i)4j ”›e1O)†PÓN4Žoµe§ä¬óc@Ñ•ZiœÃÃÞ \ :-´Ò¨ê+×µ g’2[‡A(»F '¥í[0„@/ B ÓâM›Pdsé» j¢êUí‡ã²¨ê®£ªÊË*gÄ ÄJ{ÏîÞß0׊¢aß–»låøÃ®m?<ÜžžœU’W`2Œ–ËGŠÜÙÑÉ_ÿÕæ&ÿ§¿þÓ·¯ß1ϳ,X2ˆàt>[/v†K ílÚÊq ©øýâÝt|”­Û'_<}[l:3²N.G7?-â>™Ì'ÕAw½€¸=_pf†ht4Žl&«®èbÇÁŽ=\.8QªÃ~ô]*Z 8°-Èð0)ÜBX‡d‹u?¯–ÆG3¦9@ºé›lw(²üÉÕSÛ ÷Éz6•y…‘RHbHï¶Å{¥–÷/O/«ªR¢BÏA^–œ·¼YZåŽU'y¯„msÆ=Ý·–Ñw=ˆaÞÆXB× €@D Á`SÖ“ÑÙÇÝ5òèø,-ã8ήÎ/*ÙÄÉa2žÅejb"ª.‘U仾7º¹{;ER‰ºlûª#œkÈ@;QønûNkØÖíéñiÓT½TmS"™Fô¿ÿíÑÙ)áFZJÓƒé ÛwÑxTÙûŸn_|ö9%j·Í…ȧºăZ«<ÉFG—Åa—ílòÙìtu»|úÍ“}–pÌœQt³øp:9L¦m™u¥œ?¹Ìö[ÁïþÝÙéy­1 ï )40Û÷¯ÃpŽ‘à”oV{JÉn›–÷¸~̲ôâêy/KÊí<¾›ÍMµRÞm¯ýO³~üP¶U“lŽŸ¼Hâ}|ñÙ†ü‡‡;j"ENä/—7H¹Mß¼xñüñãJÀ6 Ǻ‡yYP¬)€ ãp^¿~ GÁ0HÓüfsW+ßÒ² ‡v’e“Ñ4¯ šØ0Ÿ\Ƈ¢VصHèϲ¶^ï?™ÆPIØÂJöhtL^¸~°¼½Oæß~ÿ–»öÓ‹§î>e]îÛaßÒZ&¶cX˜™‘íÊÐ÷ÌÀGËv$³ù¼m3¼ýö~~õ•?ð«dßuÝ«o¾F˜Ç‡Øt¦/loЉN¨#dzVž& „-4/+×7»Ži «.E³¤J´j2§­ÊûF!Ѝ=gôöíOÁØë$Œ‹dñx;ñÝûÛñ` 4þîÛïN†H;˜XŠT“ál·?p +©ª¢&RÌÊ:7æZƒÝf1œFªJ+ººí»¾w}»-úªi\ß-’BKÖƒ‚’¨×@¢õ jŒ†‡‡•‚’ÛvwñaCMRäµëzQµMΙ BŠTefqKk .«Ø ÆM Ù¨¦%ûª—€`Rw)Á¦–J¨žPƒ`Rõ¥€m“›–(ÖŠ¦Ó—¢ÌŠéÉi™§RUˆJˆ-Ä\v]Ó®õy+ag;.ÃüñîÎ}Û Ñ™ŽÓ)s|„;݉¦j‘'ÊVHÌMJ±1“ªMOÇV[íÓ¶o ››Ä‘B LDU·®ªÒöGM¹²l'Oó „À‡8Ö¸9>ºÌ³ ãÂáÓ]’¦v²*z ˆÞôº>9<]'»,?¼8ÉjsÛ¯wKÏá¶3*ãebÊ´D  F³åâ~>?.Ë6KwáÑà8Þ­k´ö,;¾»þ¸œŒ&‡Í†`‹¡VR–U ™m»Y›QÈœÐ\Ü/,núnP ‰éQkbƒs[ççÇ‹íB´RöÀôxSÖ£hTu…ÁŒÀÖÛÕt:·ì ïê¦/Ÿœ=}|¼sÕz[¬FÃ3TdöåÑy××&·€ÄÈЧe‡eoÊ‹›ó³ó2oОpÄ{FãÉw¿ýGwŒfó,Ù[ŽU‚Ò¢¸®;êÑÃz;ú’Cqóéýäè<x‹‡mÓ¶®Ç¯ïgØ”E/Mß 0mÒµÐPÚVEe;Þ>ߎ¢¹‚°íë¶î¼q˜™Á,Ãö0QP¢4/ ǰ¦•»Õâüê‰T Ha’í-@¸ál׋ªË_~ù§u±%bl(€¢ÈÐl« Qí‡óô°5ݳh½~h'éÚxºG»xsuù´,‹Nv²ÃáøpØSBïnn±OÏÎîn~¶x8¹åß¾ÿéÙçOû¶œé!y,;p2¬VU]¾üúåÃãÚæ¬èŠq0@€%iÙÔåWß|þþíOÅv;žÍ»ýÑùÙ»7?‚‘"ØÅѾýÿ~õͯ æFmA8ðû4|õü²ïúFô¬±T i[–T€`@ ùò¹çû˜³Nä£ÑLJºÚ^sæ0vUÑ•ÕÓËWY_œ?ûñƒ:0ÊÌïü݋篴Æo¯¿ã€Øö€Ùx³\Z–_¶å“«g?|û-¤(ð‡‘¬Î¸i@M‹*õƒpqsMæ¢k¥âw÷·“q(¤µ9¬µÖMÞìV›í..‹&.㯿øüÝ›'^Ÿv’˜”IÐÏ_n2Þ>ì5kÁ^ª ]Kf}!r%:Ÿ†Ú$ëÕíd8 Âp½Ûì6ç¯Ò.™Ì®dÛ%ÙêÉ‹?)š¢Lâ®8\œ}V7)V¤­*ä©>”R„ed´‰v?a‰y+`ÇÙ$µ‚Õ0Œ–ñÓ§—Ç'§wïï'C‚Xqn_¿øïþÔñ­›·^|þüh6¯Êº•ÁÙj± Ž‚d“$I#ƒÐ››;°áËûGÓqêªEÈÈËu_µm›&ƒ|CE9±ºi±eˆÕdû釟¢ñ¹áÀ"Ée‹×éÒ"Q^×y×Eúõ/óþûßϩḓ²m ôý`0 ŽVËÇÙÅ1%¬©[Ñ–a0jêÒt-!Ôz±œÎ޶ËUrØøxƒ"KˆÍD×j-üÁôÓ§÷]WEÃ…ôþæãäü ØwŠˆs^•mú˜Ðýz5;;ÎUYIw`ÚF(J ‰¤Ø*e*Ë®ï5æÈäÎf·5mE´geV'Q4é»¶íSÙ‚´Ë”lEÏZ‰”®4’ºÇHcL¸í×Õ¾S¼­µibFí››¥8˜ò¼éšú &UQ× @·0l¢hšÌqÇ¢k;Q2Æ«¢Dtªo&@ ·«•ømY5dUÛ# Ú®«ªÄt™’@·z/ßn*¥Z ƒN”M“QjK-ÒÝfŸ”Ãïãht±^¾Ù®Vó‹gËåÝòáÎó<¥ÁííM†@5¨º•P6U¼Q–¬“¢<=:ïD±^&­‚«$«j’*fFÈì$ªòNC‚b¯7ë—ÿä›OoÞÇ»ýôtæ›<+ 3pt­ï> gG×Þ¥ñÖ\‚Nn–Y„äYŠ-cï8ç–cuu3y÷wé.áŒbb5M+U.Ü @#ãí?¿zù•áQË®—ÊPqdReù!Ÿ¼¼»}cRdXAÚä¢ï ljw1å¶–HAeX>F¨m²,/ÆãiU—–é =×ÄÐ(ꪬ²8­£Ñ!Ùy~°=lËÑmÖJ¸yë‡ÇýýÎô¼ÇÅÒ \fõÃ^uùäy¼Ë(EgOÎ?,{­£±niٔıËíÑɤS lJÛ÷˜²üжÚ0¥5¢F]Wáh®@-E µLDƒ2oËõý$¸¨ó,N»†‡Òbç&IJ‘ýÀî“¥íX@ÒVÕ‹Ç›Óóóºk´Æ]Qʽë¹×7ëå®)ê³§OW‹çúi¥15@Õ·US_žºÿñû?üæ_üyµ/±Ìcwâ„FÈ6³$ïd9<û<Ý?… Bžœ^lã’0Ûn£Ñ@¾/6ÓÙ™î»Çx¯5}zzWýtöt½x{4{…=ìnn>,Ÿ>»2)»¹Ù¦áÇëÿí¿þ_^¿ýa½ÝŠºÆóù%‚Ò+d3$¤VZC{ LÆ1Á&qÂз–i¹žÓªþúÓ›étžÄ»¾nì¢3}¿$Ü~<ü8žFt¿ûÐÝlr„¬îÃû×O¯^fU6žž\üh‡†lm:w›“ÑÀ±¢8Û3çY>)“ÛËåíóËñáÐÊ, "‹[„“Vª±¤òèôô¯þß¿æTGvX·PÔñg¿þg#ÛêE9Ì–ûÅÙűçì°Þ×ë/ž|ï6È¢±¶Èë®v -ºÑtúð|ùÍg˜Àl_Ý/oõÇ¿’½BŽa’ÞîŸ~ñÙz÷Þê¨¹Š…7?½ž^œ4]iºîzŸìV‹«/Ê&¯›l¿Ú0€;ÑM†gËÕ}Øãp¾[o0†Ž9…Æ›ÇOG'çI¼òƒép\µiŒ^¼üüpX>^/ž]>¯êœ˜c&…Z‡áhýðhX|>9_=ÞP‹sÆÊ¼JÒz2šçY1œO(B»`(>½þhGahiœ[žWÄ™o†–ç ©®ïdzYèy×oßRûn(J°ëjNØêúñë?þBÅÝÑt@í Y6éÓ'Ï ¦ ­”ëE½L7¬ŠZaé:Qrˆ;Ý1L™9Øï–6÷‘6±…u§wûarF̲QE²~ñìUÓ– "‚HKŒI[we™†a´^ÇZiÆMË ªxOˆ©0g¨S@ÕmÓ« ®Ìòʱ= 7Ì"MµF”¢¦Sm§‡‘×6m×µ”[M“4hZÝÊRx¤.úTh×2¥j‹¢ÖC…L“ÄÙÁ°¢®.º¾QHE[mv]S5ùpø$É·þ壟UÓRJ]/5ËÔ°l„"É»®Š&'M^C(·ªOʆò†Â`0ÜÜ}MOƒ³ªÈ””N8J÷La…¯?¼yòôevˆ{%çG']ÓÞ^*‹Ô±ºNY6y\nÇÃi*[¨õzµ0œA_çZË (¥¬(Û¦ £)ŠüÛë›a4}×klšNW§þ`Òwe–$ŽÄñF Uwa€övÒ–õ)ߌÒt«QëØÚ¦j[Î4Ï=Ïøx·zXÎN/¥EVƒc×¶ÛxtzµÙ.‰³ùÓªH4TÃáHcu{ûqÊ:¶)…*ëŒfÚVV¤E‘Â`³Z!NEShh¥ILˆ:ì’éñqU´ †I‹2õ¼IRÆZw] ÓÜîPPkìS„ºêiFAÒ4"ëîö]àz-ëâ€5CÜä'm¥uxƒß;žkPŸ£U £¦’mÙ„ò»ë×ãÉIS¶yÔe~uzö‡Ÿþ›ÍÖ7iŸæ7Þí³x6ÏŽÖËÇÏže‡ŠÚu¥áÄ1“hhÝß¿ÿ£_ÿró°U“4Ž+ٯכ—Ï_`ÿëßþõôê Âêèô‹‡ÍÆtD[6/¾þÕüOÙ•úë_ü ŸŸŸwm('1Æ¢¦k9Du $è2Ç|ñÅgÄæù.YìVŸþÕOøÎ Bn¢Éè¸L*Ãfù! |ÿòÙ‹¿úþï_}í8.à퇟¾øÅ×å:±Qš>0ȇ³i^Äiœˆ^~þêÛß}Fy³9Ÿ=?lw t ˆâCÒª& 'E¶ŽæËÅCÚœ»ŽeÿÃû›¸l96Ò:wÝ@ÅÜmÓJnßÿù_ü›ÍÝõÛO§Ó•|µÚCŸJ¸[oÇ[/×óã3¡„le!Û³§ç»Ç[Ì™aÚ®aäeÊ(Êâí¡¬ÎNžýîïþ‹çFÇ'Ç7‹€ÉÕóËx±µ,s4Ÿ¼þýF§§§'Ãífûîý»W¯>k*¼ÚÜÎONE °åN'ó‘ãj¿ùã?+öuÙ ò†ÎÉrwq{}|;;žŽÃ£ïø=ãÈ5ƒºk›:‹œQÝ—žïÕ™°¾¤×}ß6óñUš.r{{§¡$éâxM‡ Ѫ¯1êþ|ÛCš”I‘|öâÅÍõ-%d6½ŒˆO˜l{9ž‰®&„-×›É ä!E«ü(°ת‡µ}=Í«2e&ň ­ú[¦'±¶ƒÀ4=lpB ¢c”N¦ó¼(Ći´u5M ÊŠ*6`6%‡é†²Üq´lQ+{-!ãJè*©a×e…¹´bv(Eƒ)­ËÂr\HðúqéEj¦Ì)5€–u^çuß­éåéi²_¦›µ?Šf}Qܨ«’R£GiYU‰åùZÊ"/\Ï–ªÇØê%PºS±ƒqœ,)BÔµÚ¾eÀ*»’rÕÕ]Õ5œ0ß.ªŠ¸ïIU§814ì¥èÇããÝaÍ)² @¤´vl»­[Æ&t½\MÆC†]¨´Ò½ 6ËGè»´(FÓQ_7X±p<ŽÜàÝëo_~ùOººÖ}=˜ŒUÛ€¶˜œwªOw‹‹/¾y\Ý7m aY‚ ì¥è¥Ìu̪®,ÓŸjXè§Ó‰É™i ãzW¹ï†€ ÕC0µX/õl8¸YÞ¸†9NxýƒrL…Çõ²xFêmÚ"7ÝA8ïî®ÏƒÑ!Þ˜¦ :%•>»z 9ÄÛÏùGer°†CÝ5ÔE‘c¦É(mòÔòŽ j‘AQ­éÑùt·Ø †¥EzH1eáȼ}?>ž•} †“²ÚQJg˜X]Ñ™¶Y×™c{Ô0û® £a[÷yz Èþìë_I‘QÌ N•>xÖ°Uù!¾w¨/5ZïïÎý“RUµ¬Là"¨-´6Û½ÐÍÕùe–ç”Õ‚°’R+¸Û¦'CÐÃÅí"á<Ï„h|7ÌóâìòøëÅ2œ9ŽÑ—mšV³óy_6i\ &CN “‡w½„˜[³£ðæý-¤üètʧjZއsÕö6‡mBÜ‘¢s)@ËûæPm’¾nrˆŒgW_ß¼ý~4œh QTyΙAäŽßUÝ®\¼|ù‹Õò˜º©zË4뾄=Ûnwãù([»ýj8~¸ÛoÚ:{þüå>Éž?ùÝþ1Í®.Ÿ ØÿýÏד€¾úêÏþÓþOÏ¿àóÓ+„©ã™ƒN¶iÙ@€1†¦AM“TU;zÿüø—‡ýC\ÆáÏž<½¾¾;?;§¶mëû£÷?ÿ8Mæ'G²A¿ýÝßüÿî^¼ÿÄUÑ—“`R'j»\*!?ñõïþñï(%Aä͇óÿúwóâ˯± œÛ½j1†ÎønwÿôÙeºK 5öÙ}èÍ!6ÖÛ÷ûUŒÖ¬6MÓ›6ýͯÿõÛ7/umkj@U÷u„C…vS”Ñl™ D\|ö«¯ê‘0¼97MfY}¥vË?ôOΞüîwÿu81äyƒ±§f”ÕÐþfqëy¬ÖÃrµxûöâ›_zósGüÃÝÂó¬uÛŠ "-7höñññX4MËåÝ69<9=KÓ²=ÇÜ ‹ÕÖñÃ|»TˆžÍe'âtwzr‘‹âíÛ7Ÿ=ý…”=ÒЀ`…h  öå¡o닳ã4Ùa‚«ª±}Kw½nå¡<œ^=ÕEæ1ã†éøU› !yžÌOžÜÜ|¨“üôÙUY–¿ýíë„n³mלÙQ™oe„` u’$—Ÿ^I’æ–mKˆÏne …fs¼ð»?ü~4Ž Öé! ÃP%P°-е¬KÛtÕ3«¥Œ¢­š¶/¬tO"×Ë’M^ÔŒ2€E‘äNh÷ªnÀª ØëˆlêL¶Ò÷]Q·Jc¥zÇ¥uÝ&ÉÖò Êx×5)?:êÛ’@M‰S—n›n0Ù<~J]\=½ûðzìE³ùQV”·¥Y‘Lg³¾¯ÉaÜ0úª¢Æ][¾ÓöeÝÇe’àøh F]ÝŽ'ºÎ³ƒVTMÛ[¶C9««LÊQ‰6˜U”±ï217`Yf¦ámÚ5¢kEÝ”Q„LÊXrØNÎÓÃÞ $Q–î•FH‹áhŒzzûñÍÑüBØô1À`zzšÇÆñøx±¾þô™VòöáJ4??úö‡?<9?«Š¤iÑx0Oóu×Ëõ¤†uÙ&lE ·r¹c¬èò¦ª¥Ò–kí! ó€-ˆ€{¬«S×ñë¾yûîÍÕ‹Wßvײxf¸X¾MçŒù][ÈJC/Ýœ²RfCÇÊ̪…i†éo–·±LÇ˶[ßÄiaE¾Ã±îájuͦ¢QÈÒŽá->}baÍuß1 Þàîîr€cDZC©ÐÀö˶„˜ún¸~ܺǰØnu ¦Íïb‚! XuÜØE¶Ñ L†·i:Ó²ê<ÖÂ0}gµ¾5 NºNêž_k$Ú¢WL ]gZuyUåXÚ¶gVùžhKjå]#MaàFŠvù’ :žæÅÁ´œ*-œÀň3æ<Üß ÃÙ›ïÂÀ©:ÙJ¸|¸^4Uõ'ÿô^ÿxݵÙÉ“Ë6×uS!ØchhЇÃàáîÁ°p4 »²Nãýüø¤+r)¥7Þݾòì—ñ~›µ¹T€2'±Á±:UÕ VçU1;™8Ì:>;¹¾½>9>±{·ÜKd›1§©šV÷½Ú¿<ÿbqû‘1©Ï-àX¼o¥&,šŒ6«èò_þ«÷á§Ÿ:ÝP¥†Ã±5p†Ñøp·NÜÏ_½úá?2ž£N˜>ýáÕó«oÿá_>}Þ”5ç4Î*Âé`4€ ue·KŸ>yÇ)¦l·ÞŒ£‘–¨î3 ¡ÁãÞýýëÙÑ1PÈ‚Oß~[ |v<;›]¼iÚ2 ø:ÍFÓcT6³u”P@=¹|ª¥Ü&U]p‡lïë†Ì QhM›`HΧ'ŠÊ»Å»ñ츬ë¶ë†QÔw74N¶+Á“_í®5Æ– 8Î · 4u5œ=ÞßLO/ :Õ"EB‹sŸ3€úNn6«¯¿ùåãý§Z¨Àu ›dy2šÛ¾5x8<=~ûãï£g†C˼Ìófr4«ËÎåÌ›‡ûÅ¢¶Pšš²£4>#XSˆÆY³#RÊ4”ñns<¿Ô¨…ÖÛ dP!NݤØ` ,ÇøîÇ¿ik‚L£ƒ]ŸIÁ­$^ùòˬÊDW»¦…16, cÄ4 æyÞn³ô6FvUE‘ûÁ(Ý´yó„Þ¤¬rÛ3뤕­8>ž ‚Ñö (‡ÞqR%É—§]ÙV¶ûFlÖëã—g}ªâä`º˜C‚PǙߨæù—_”Is·|<:Ÿ5iñúÍÏãÈ7(OËÃÑÙéÿøÝÙåqÛo>¾[\/®Ÿž Ú üðúÛáhˆ¦™îÚº—½ fîæúh:žŽd§ó´Ô´øc(±5 ¶«ÛÏ_}yH“"=ˆNœ?‘}qØ'œÀ£Ó¡ãM~ûÛxõÙe™t¢~ã¾nFSÿâ˯:ÑdUÛKí1F1-B î{-:¥ ˜Dƒ“ùxtr‰c8Öz¹¸ºüJî°_%yþüùÓ,ÎZ…úAt’®×jrÏõû»¿}õå—lÇûÍÎh¬qï1ÃgW/ï?~€¤×ϦëÕB)TUõÙåy‘•ëÅÝìrƘQf2/ö“Ùx·L&'óû›ßÿünrquXÜÞ=¬OÎN¼ÿöÓýéÅqYlüùð©+ÕåW/ÒÝ![®G'çyœlï4 ÏŸ^iÑ G“õâz~rdÖˆêñî!xu+Ò²öm¾?,ÇóÏ–Ÿ6»Í|r ƒ¸¨€”Þ‰4÷ƒi’½zz©ÀDªºô1$*ÉwŒ0©u0°{Ñ—y3==;9¿xýýwŸñ¹èUžì E‹›[Ã2§óI[eÛÕÝ‹_¼|¸¹´²ÑÆHYŽYæyQìOΟv;5&4&e^PGž»Y>ŒÆc!Ш¨RoèˆN`†š¦œ)á(K6snr­Õnµq¼°lêgãó^(%õìââêÉ«ýâ¡(ÓÁôçáp–&kÛ"1¨‹ÂµŠTU†áv] †UQa …¶5ˆ·ơ㠫¶–R Õ¨^PÃà_ÜÜûad0£. ÈÑhLC¦’Ø‹C*”¦Äð­4hbÜ –×gGçJj5‚0Næ2ßso¯ï)ÏÏ>{üxCMf~_¶Ü²!¤iİ­¼,NLßp,W”çeèYñþ0šN”R÷«Ù|Ê(í[ÝBä[,©@8u¾ÁîTCÕçÛ¾/ Ûö,žöQ8"L‹¦Ë2‘×±î¡gz‡d#¥-ö ŠM-±&РD P6yº]…5,dß!iJZgûÂæbCX•T„µ¡Êv¤|«+1¡cÚ÷·ËÉI¨Úvý÷¬Dƒø!%Vﺣx_c›)Ñl;iˆñ`þþãã3‹™ñ¾4lÓ¼ªhM @ÈîΞ_te™‚õt8I²„b `”QX”¥a±N7Œ±ý>acµ­ÒZs1Â-׫ê¼k[Ë4u0©ŠÜ°¹kùÉ>C ú†Ÿd­çeYpS»;–šTÐÇ›…Ðóó³··1W¼C¢Õ=l•€ßþÃß¿üêùrÿýüîòÕ™ç âÛ”aèiñÙ¯Ÿ½ÿö­àäræ(c±ÞØzzúêíÛkÓÂqZH"Y …‹r÷ìÙÑ›ß5u;{œ™™Ëŧ u­`.ýÇßþÝ“«/3±!Y-Ò£Éä°_ïËŸ]´BÙÜ` az š®¯d lëþ‹W¯ŽçÓ ˆÇ’ Ý.oùÇ_&‡ÍããmlǨwiGÌ´¬›ÙÉ“w?Í Æ;нùñÍg/_ Wû-” b¹Ç»Í;Ó²º^?}rqóá§Œ2‚)mË®¨£ÉÐä^ï÷ùæó—¿¸[\k…0duDkŒ²Íˆi®~÷·ÿñüâœÎ†²j ŽÛråY.¥N|¸?šŸN†³Ç‡÷Ät./.ûÇ ˜–uã †}YÝ/Ÿ\^Tu-:q|r¤Z‰dÐÊS¨ËÔè8üù‡ï ʦçÓÍâ±näP(ÕˆJ‘t¿Ž¢I‘՛ͼ+[Û1ò<‡P £!lñøi<s;R°Þ®·&³=Âh¼Û-~õ‹¿p]g¯§Ññp<¸_=L£Œ!BâòìÉö°åÌpÝÈ4­õv%TUÖŒ²¶, ®ë@ïïÎϪ´ì4¦ Ñ3Ó‚HåqŠ)éÚ.NöÁx\WE™Y]`ÌšVŽggHK©IÉMÑõãÁèäê"Þõ®ï5"öœ9·ì¶Ü*Ís¨u¯,ÓoºÊ¶Âª®1‚¾3”RwmŸª6¨Õ· a„h®¤lºf88¡L+Õ"b&ùÖ6؃CÎmË_­nìÀˆVU H‡5‚€Ö}®IãÜ ,ÛrÚBAÒ[–_™BÄ2L¨Û wÛ £ŒD/$à6×¢'ÔD·]͸M8]K¨Å|œn¶Ìp n(¦¢•‚ )r’Å{ƒ;„a„IÝHB¨ÁL%Q–gŒbˆxQ' AÙhΦ ¯:µ†Mݶª´MÇ0}€ ¬±½‰Ð}üù£$* UÓ‰®Œ#ÕফœÐkËÞõÂp_–MWûèª)Ëek9NÙ¦@1Bay«åÒ FQ4Ø.÷[£q+Í!É~ÿäéçtB”QÆ %ÇÖx6‘ºó¸ i' Ñ-4=c±;¸Ìc.B«v}>šª,#DÛ¶ù³¬IÇó¡ ìÖÄ ù¾2šœ@É“*µ-hÞöe[ Z؄̠E:Ø>}~yûþchRj([ Fö-ì ¶ ßs¶«7ó´êâEÜôe8°)0º¾Qºo‹&M¤U\u1Oû[°•¥E8æ ,Çb¢›¦šû¡§”6ˆñéúÝ|6q¼áÝí‡4Ûi¡ÃaðæÍY]ãNz®C¥Ù¨Zh4?»[o‹4ÿÍŸýÅíví]ÒŠÞ4LÎíhðú§ïŽŽ‚0š¼}í;¤éš¦Ôqq°¸{ÈâWß¼\~|\^ß¿8ÎÊjñéž9~Èݢʌ0úøóÓs%Të»Åv·úùËd³ûôþÆ4`ÛŠÙ“_îß$yqH ~õù¢¶o¢j€DjÕC€Aè8¿þ³?’nw‹(ŒNOO¯?|,²üòò*MãÙðøý‡wƒÑØ¥£ÆÏ¯¸|ñ)ýxÿÑ1]Óæ&w?QÆ«]ùÙW¯>ýüÞf!6Y8ËÛÓq'£¨*û¾M“>mò²mš²hÃAP×%ìqžåœÓÙøäÝ›)¢Ãá1ñþòßOŽO«"®« PtS´n«b“|õå=>Þ˾jDcÛRB}XmŸœOÒ¬èå‹WTB&7±CT)º4"ólk8žÿþ‡;Ö$寀–kÚuW1dI©Ë*=>½Xo¤q†y¯ûªé¦]WCÍãä@ ÈKã"+“‹«§ñvo8f~H«¢1 ;Nvo^¿›_Í¥?÷ãÙÉY’î “K RMÛ9®gf¾ÛÏ/ÎÚ¦(óF€–RzÌ=¦µ-ô#^傆æŠQ&jÕ“ì˜AÓä²×”r©’ªÈ³^KJ1ÇÞa³°}Ó²f½ªÚªDŠjÒ•y 5­ºÄw­¼yqÐZúÖZi0€INl‡q@%²ç–%š^)E(él›Š8Ï ­¥aéþ eG8k›¦¹c9ªÕ)Ìx‘fÔ´çRvR˱¥’@„@[5 æÒ¾é¤€Ä4÷›¦ŒÙ.TŠ3SÈŽƒ3£}/JBl­ Öý~—š†M-Üw}SWá8òìp¿Ý0, ½m—3Ã,ÒØ[@¡,‹ƒ‘Ç4ÏÚ¢êFY–Ad—©húvvTU·x¼LlܰÍvF.è)Â’r_¶uûõŸ|µú”Òådæu•”JkÞ65èú¹¾Ýb‹RÎÊC (†JCvEì…˜0Vwy‘Æ–aƒèæú“VÊ4Lϵ}ÇÙlcË6úZ4º««8ˆFõÿOÒ}3Û–ˆaý¼Ûöø{®{þµºY¤Ä¢H–MªDþª”(²F )²f03h íó׿ýþ¼‚ù+X§Ö8íM •SïN½¶—WÏwÇí|U»®Ïç©ãétH‹48z:m_|vÝ7¾im>á!ŠS]SRŽ”#ÓúÍñ0_-QÔÝi¾žÙÖTmÅ„ëwuˆ´\ª»_î篦ûû½¾îœ‚RF;âÈi–+=„@"cY75W$:ÀyÚµéu¦ÊºÙë~ðÚF¸ ’°]ý‘S+€8š>çÓÓprÞr)1™Jw»Nbš$’íöF¨„!©CŸ–Y}lÆXQ=hõ“'Oo·U_Åiœ¥³ÖÛÀšee»«0CóÕY°¨zkCF)òÝ?þåúÅõзïߨz½¸°FÿüæÇ—¯¿öÖÍÖwG Úó§ç’òûý‹æ«Ï¾~ÿé“ÕQÀ$‘E?öÎØO·_|ñy×µ?ÿøó—ŸN2²Ã^Èì°kþÃø›ÿûÿú?‹,ÿÕ×ß^•Oðç_~á øà½ÖE£`ÜGÿÇýíßüÍÿzA:É…é"~{Ø-WŒ Fȧ7o/ž\§‰ìŽ5ahÐeº„$\£ûñÅgŸiÓF²¢)GÆïOUž k¬‰Æ‡j6Y]/è*€(T9uCØnïižðXl¶7/^¿˜²åÝí¡ào¾üã¾Ù¼|v‰‰øðÃ_Ÿ¾¾†6v­ÒM²ÅÐwY™""p2Æ„-Œòxû.ŸN .øãØ´Öúél2Ô³!ÉSŒ!Å3“¨Ì@$T:‘’3lÇ.OǶ§QŽ¢Oó¼ª:ã†D$ •°±ëC„¡Ðáx˜¬J2FkZ* pHšàHHjœN5ƒ¶ÞJ)ûS>SŒ&M“„ û&”% @nnw‹ó‚3Zæ¬óPs,£*U†Îö’ó¦rB0N Œ:òáñ&Må<]½{󦜡&?üõm" !¹"é´[?)ú“;ìùZ!9D,ó~ìXŽvŸö1¢õùÚöÞhƒ˜%ó4I²7ïo®®^c¢ñnŒó³²o[ŒXšŠg(ÐÛ»7)M9Ù¤€Á‹”b§QÕWEÊ)–ußY3\_½úôñÍr>)‹Õ0vB‰ñ¡œM†ÖïOIž¦r–äˆÇpêJIêyÛÖ“²<íºÃiÿùŸ ž?Ü?¦™ªŽ³i™6§e*ŸgÁº¦í&ËÔ;#$xí‚(ac5`Ff«ì¸?a,dJ(ä0ÒÑ4õa›¤7T··÷E6Ð9ã< YJ$ŠeC³%–Ýš~„'™´cP<1¶<=îNÚ·)Kg‡{Ÿu¡uÃúâüöÃGÆÉêleu8µU’ñýfß4;¥’±×ç©b‡»‡Ãã˧¯7ïwû]žOhð#ˆMU÷M½›NW?þðÝÅÙ™b† ‚΂Ïή &NÛÅÙÂŒºi C™‘ý¶$úÑ*1YLgw7ïÓÕt=Ù=ž~øó³³óèŒ²ÓøÙÙE§ÛêpÜÕÝb~¾}|˜-ÎMýõoÿpÿpb7™] ží?@WË =îòó‹?ÿÿÀ NÎΡÿå¿ý§ÿùßþ/E>ÿÛÿüÏ_Oñ·¿û­·ƒsxèƒ[F/ž]½zyE\€ž¨,5cÏ îº¡œ–ÞšSU…–çO»¡:n//®t‚&»»Çdž!@ÍÿñïþîòéÅ´¸Üï·! “r‘¤Åñ¸É’¬nNÏž¿Ø<Üiç•&Jµ} çT¸hò,ßl'óTPC|ÜÜ¿üüYŒpÇɼÇ8©Õãhó‡ßÿö㇈ð«‹%€Èy°\d 2N33v±¼ Pƒû¡]^åýv‡Ò‰h˜œu¶Ú"¤gÝæ Eºi>aHî?~ÒxxýÙïL°÷‡ŸAD{õôå‹/~þáGœÀ§—Oïooçy‚h1ÏçÕnÿåï~Þm³b2+¦ØC€BY$Cݯ/? ´u«Ê4+ÓýîàƒËó¬©û,Qûz«„bTa£…(Ña:M8DmÛ!Ž9Äy>;4÷ÓY" @)’$ÎÏ.»f<Ö÷Ož>om9KÒ$!”ñ”PB݉DEžl6§4' ¸Y:sÆa8‘CÕç«,Eshh*&Éü°{ '%fmÓ (¤›í¶˜’'SD"£Â[”— arØw«‹%Á(Œ1Q‚RâœCycò,×ý€€—ICÔÖ‚‘G˜xŒqßui.($Ѫ¯æ“"º8˜JÊ8À™ UµDúl}9žz¬$:ŒIÄG³÷³ržÊ<ç¢ùs•­&«Ãöv6`DÌÐrA²tb†®Ìr`ƒ·~6›×ûº×M’3%Ëæ´Ë2éѧ¹ìë‘3ž•â´ëOÇáWßüºÝ÷!B"Œ\* BÁövϸ:¿X»Þ#ˆ˜B™,ꪒ2‚0¢]ß#H11 íh™ ¤ÁÙ·ï¾»:•æi×nž2I 6s.`jW³ÕÇ÷ïLYE§m’”*K¹d “»ý!Ï’DfÑ…íáa}qeFŒHÎϯڱé­Í§å|µÜÞÝ_?¿¶ZcŠÉüç˜éb}m{x¸ýæ_ý‹Þ¶·wo /’<˜RÅëöX·ýÓËg7Ÿ¼ñzÐ0›ß¼ùäÍ(Òd2_ý@ùð›/¾Ö¾ÃÀ¦‹•-ìûï¿ÿâÅ——Ï^ÿüáM]ÎÖ×@Ú¿üù¿?¹|ýó¿àWO_;¯{B$‚` @êÛ¯¾øüåçe9g —<6I DËÅÊ·ßÜN—aÜæñÓõ“sß„±›Í/ëË Ø¡y§Ûñüâæpû°-ŠYo‹b}ûé^•‰”"ËŠ·÷o§iªDê\‹0ÔƒK³„3l³Ùxý«WÕ¦¬U’fÉ„pÚ M0BÿÙ_þíúϵ¯VWó|þpÿ~yv &Œd“Å»¿þòôÅ“ùÙzóðéX÷í7»ý¦5Zq x®›ª·#x’–˜¦÷7Y6¡‡Ñc?=?Ûïö1ÄB×T/^|¾­ ÃIò²Ès× 0@ï̓Յ5hzXŸ¯áZ†g«_‰”¯—}u¢[.c3œšj>Ï3BûÝ %ßÝ>ÈYÊ)šžrœ(Ù<¡‘ 51^{3$c0ÚýÝŽ¦Ôë±Ý7Ú˜õêÚ¾ê¦mÛê|}µ½Ï(Å„b` ¢½ÖIÊ †Þû¦«‹4ƒ(Æ1P"„ 8Xü©i_™ÑÊé xÐé]QdCe¸ÄJ%oúDTÌò‰oQ>]?OJ½&"Œ¦·š‹Õj÷¸!4d™òy4JE¬Bbcè`±, f°„DÊ(еÛT•ÆöÑkBe’g!tÁ!™e[Æ37hD,d"Q‰ê L¸Õ eT÷=Q„#êcðÀR Cˆ"ŒØ`Œ`A`l„À¦i~|ØBbÓ¬ÎkÛ¥i¡‡‘ ˜&¢m›ür&Òƒv^/¦eÛ4c˜Ás ¼ñÚGhÉw›=§8U¹×c„A0 Á·'³\—£î¼…9*‰ hÂ0/VuØÖgW˜"€­5pNëÎ÷¡Ò­µÍd2÷œN{¥è,ϼsUMÃ$XÕ»£H“<+ u„R«^H[4e(“³‡ÝJÓ'OGÝÏVSJÈöáa1[qJ¾ûó?=ÿü©âôæÓÝd–§ëbp¨X•QÛ®êÕT¦RBM‹2QÖĤÌÖJ(&ÉзœòÉbvÜl1”…àC‘NOÍ‘"˜ªFÝÖz1=K' ¢`´õ@g*ËÒL¦4x;Ÿõ}Í!„0ŠO@@hΙÓÃæÏ„^ IDAT&É2É©:&"q„èÂÕ±ïšÃb~éý¨‡Ó$›+•Uõý|µÒÆš¡ÏÄäöýÀt¹ŠøŠéÄ ƒ`¬kÞÙ2gùq "ͦ³YpsœI“YÔø1Ãrr†0ÜÜÝq–9ß È˜ÊÝ‘ódyqùË/ßçY©ŠÉ`úI9—2KJU–¥y3v×—/‡¶A§Ùœ2@06”Ip˜Í—ÛÍ­A1j;ŒýÇOï’2ï»>Ÿ(γïnþ§óo¸(Þ½ù„¾¾¼:îŽÐÛ¦n=pŸ½|ý¸=ôz\Îò«ëÏþô_ÿÛ¯¿ù*“%0U$j°>_ç+ÑW-Bøåç¯ïß¼Èkè.çë$+GoGÛ¿þò7§jssÿîù«¯3N§“ù¿|—¥`5»üõ¯¿Á¯¿x¾?µ³QG%ø‹'O_œ¿f?ÿü¹`„1šN’S}’Ï“®:ŽÇ¯žUÛ­÷P¿\®l‰mÛåżœ^üéïþër¶˜L—„’û›ë3kÇ$ɪæˆp˜,$èýaKš—“úøè ÈŸ//µv}ßzoÏVOÛ¦B$ªŒËéûD“Å"eT~ÿ—7“¡‚$  @4I (yþøxÿûß}SúíþáìlZ¤‹ïßa £0Âó‹åáá˜$Ål¹@šh®ž^»Ôí œÐÉl7Ç6ìö»?|ûÕ§·7Þ£³³ ª¯N„à±dRqÄH#hKDj7.'vÁA#NŠÌ @˹ $i}!–<Á øÁHÝO&¥óñXï/Ö×p­;N)Dëª=eYb{àü˜¥²Ú(g2K‰'ãXKÅ¢„"B]7#)Ø8xmu9™;m´JDŒbìÝ8¤2[À†EGatLñ`¡È˜&ºÀ~ëHºÞ{`M‹€p8ÝA@cŒcl Ô]p HÚ¡f”ÇŒëid k EÌZÿx¿:¾ßmw»M"rk¼ó#nE •œî7zL4ŽuVf§}«R)8¸ÝDèŠYùñÝ'ÈåXwŽ+êŒñ2.†^?¼ÛˆDP ‚Ž£!Fã`r™%eé\\®&Ú­#…1M¥3Sœª£‘h‡1Ï®!†¤Ž#Aˆvó𱜳é¬iNL¸ >„ô°ù$ ªø¼>'’å¦ïÆqœO¯Úöp¾<;šn¾œÁwÛ;FDšÎ{Ý*.ºaL³„@×õ& Rq<ì†qÌŠ† ï†4•ÖØújùñæ}’d<ãÝ©fX¥E pDxàuЋù¹û^q„*ˬsN[–°"ÃIßU™¬é{©R¡ipÄØ.““¾szl3™'ÉÄ{‹)n¡X¥Z®í E@u¶X”O’e6C˜©”áïn§óÒ³ÛnpgËõaß”“Œa!”’UÛÓÐŒ“‹9‡É_þéÏ¿û—À;·÷o&Ó9ðr6ô}ðñÙ«×÷7wÁ‚l’ÍËÉa[I¦„È’4?íïbŒ˜¨,Mšjßvý|6×f$v§*Ë %”ú¡ïg³úöÛ4¸Ñž¿¸ªî·ÞëÚ„¥Zûà‡IQFiJSšyO1C©Ìï7û/ýÊôúxòYòüé³›Û»|мf§Ãa~^lÞnO‡SRð\Î>¾½Y_Ÿ!ƒnî·"‡~pƒÏ^<:ýæãÇßÿëßvÇÃþp˜ŸëÙÌ ¶·[H‚R_Ÿú¬8K ”*¹ÛõYI)DÞ{íûèÝ|¾,Žã€°šÎS3ŽÙdrj÷L²l6Ùì7y^2–ÖZ­N\0‰bý¾ü0ŸæŠ&U½C¬ϵ®0a$DbL" ¼i«Ÿ_ì6ÕíÝýùõX2ô]ˆ.xN9Y¬‹_þú£ öêõÝûS}š, •}ßÍW3Q"¡è°­@“I:œœ5Cš'@B¹NÐÃH±5mߎDr‚56ø€ ¢XàHŒ«{=æÙÂÙ~Ô–`‚‰e"‡xßQƤL÷ûG•çˆ ï,1z0"DÅFÓÏf+Lø8´SÁó^7˜`©·Bj{ï©´:"²"íëV(jí ­’"tÜAe9Ûïö FŒÊj+Tj ˆb ›C‹(ÅŒúÑa‚1¥Pcİóõ’Pb†#Ψà`„o;* ¨>B´œ_¨q$B¦ÞÕ©qyÊäÑ=œ’¬\ÝHYÞTÇ4U0Šã~±Q¼ÔÚP†´ŽÖE DÏã8{¸û¸XÌ1TûݸXm-å2KŠn4W¯®·ÞCÁ£²ïº$O†Ö˜ÑÌæsë4‚>+sãLÝTù¬àœ#H1Ý=úÜ4_bA»¶ÎT®Ç>BBÑ®Fçé¹¶Ãöñ.-æT@‚éA’æ‰dاÖZ€íj¶8· Ž‚*B¥ÇFâ­,òîÙÙ\×G%8‚"BÄ”Htï‡íõõ%áÉ~³™/gÖ0¦À÷AªUí£›_Žº ƒ¨ÃhÁ`‡´˜Úæ˜&E"ÊíöÀ`6[WíóÌ[Ëò‰Ç~ùü‹ßdTnî–‹dôžzLS©[8fgœ*m•D©¬kúAÛt˜Iš¨¡BˆÙ¬„ÖY3@¢ÅL ã{`H \&b<Ù€­( ñ@dé Q$`u¨x’`êmça> IšC¬îÀJ>€XŒ µuÎ Q ÅŠ£€aÁ\0‹¦­h"R9{x¸ÃŒe>aÐ]^Lm(§L±~ì)ÃLH ƒ]šL|ˆ`ÊBtÞ Fx’i=rN=bLP$9'“²@.%£Ä¹àQ@ÄõITìÈiʤԺë‡QB)ò*¼KY:ícÓ´´tv/xb  DN§†p¢×£Ö®_.®6ÛC„F¥y?Ž®Š`{Âár¾ú§?ý÷<—××ÏêvìÚSß¶MÛp”½nVË̹ÐٞБu¨[¡ – dÚØ fq6e„?ÜíÕ’;k%M…äïß½¿¾~®’ôøPAGWW 0Ž‚ªˆc4Ÿ®¬«‚‹€ÉÙrV1H."Dx¼^žwÃ)8c€>p&1}(&‹1Œ}ߨ,ÍgSÝuÞ:ÎeÛvE1ë†sD9ƒ]+¹£¥Jª]%‰ÀéÖ$2/§ H0Ò®ëêAeÙ`ÖÆY9—º©…’A ¥Ä…Cš¤“ѵ‡]µzòlß¼µ$ÅÌú£ÄxΊéúÃÇŸRT *¤‚¦‰‚b^Pœõƒ•JNäY])B¥(„bÁö˜ˆq&iš§Ó›Û7Y"ó3çFÓ5‹å¼©÷—×g‡Óæñþv¹Zs©§„±äùnsktøùí›År‘Ó`×6×— ªÍãOKïQžÎüèŽj’.Åææ&MÊ€àv»áòbûéÍÅÅsÈÔОî7¯¿üb<Œý -JpÎs3€¨h]µ¿þü7úóßAïÒbb ]ÛG8Éej¨ëãóó'ï?Ý£hÎf×çÏî7ïó›ÇÍÓϸÊùå—³«ÙÕÕ«z»?Új6ÉO§Ýr=Çßþö÷ù4ŸM WŒ+)¡G1b (³"?ÜlΟž×ÇC½mòY’¥,¡éêÖû¸X/»ºòòœRL½C.Ö² Þ¹"âüh5è;Í1CO«»ó¼µÛLäùä̆®;ŽÓéåããûrvÖ÷®>íÊlbÔ¡ã(‘*3Qs¢ú¶% ƈFíÑJI¤Œ¨Œ÷!ÔÖGÆX:™üüÓ_’‹"¼Ã )ˆM]ÓgÎV‘,åÞƒhÀ­õ$›š{Añt²ê][mådií›:+ËC½“,2kºÁ;;;[T»£|Ä  FÐ:a‰àtmsjUšÄ¥ CÓ• ·ÞÛŸ¾ºÚ>ÞÆH¶>tR*ÌÃf»O“Ùòjqóég!3œèmQD1PFd‡~$<%l´£umOcݵ.ô…ZzBh‘˜ªûí/ 2Æx7n 5mšŠ`›ð9¢¬>Ýq>…„x„µ}O ˆ!G3Žítz¡­­ªý$_àFÛ"ÌÕ)€PäËÝã‚39Œ#%ÐëÏŠÌ;PwÓÙÔêÐÆd¹\ï·±¢Ìš®Ë“äÔ£g«5ã¢;5i’J•€¥J@pYRºèw¢´Þz‚Ì|±àTµÝ ’å3íFÝ"öã‘`n¢Mƒ šÎοûë?ë®/¾Ül7©LõàÃ’¾²Mß®/ÏRUnªû²P±!Žc[M²¹n6[ì¶›ˆü|½v.Œf\®&Jë±êÍ·¿ûÆsrÚ<ó¼<+6ï·íÐ1‰°‡ë'OÿüÓßÅà&ó™”êÇÍ 8PÉ‚ëåÀESíÏ_¼Ø?nÇÞkØæSi»x¿ù@Èx¹º½ýé/¯ž5êќꨣA0 l+WÕ=þWÿâ[ ¥b–åy:)&³,SH*8ÆÁô–%"ËHµm£Öuy6wšqû«ß|ÓwÕþ°[]œE€›ÓûÙb- ØÞoÿšKæÂÐÕílvV•n{Ž(OÄrºüåí[„QQŒòÍîn¾X{ëÒ©µ®OUZæb;Æíq÷ú󯆶sšr!uÔ&š›OïzÓ~ý›oïnßñ—³ó~t–!È3¨ýîÔ³<=ú„Ñr¾êë&I•õC’!«v:]œª¦~lÎ^<#0¬’Ë}¬†Ø]ÍÎç—ËÇýÍÓË'åtMœ]‰æe2 0M«—L9B‘¯D‚1F’¦‡TðÙôìÓ§·iQ¤é¼ëk˜”*@¤jñ¾‘¼D¹8–“eÓµã0LçSÆÈv÷0-”äº?q•XÝ1gz0ÖØÉÙ¬ÚŸ¢Ú÷Y61Úzm­ ‚ªÈæáfZLã}ßa“Rަþì«®­Žû‡gϾèu£%ˆ"…аÁVIÊ1 ´Išçå$B㌆ T2Õíβ¥µ±jëåù¨Ç~>_K0ñœ&MC´ë'/Ú6é†.ϦÖUfÖŒº×€#Ìy}¹’JPÝh­ÇÅ|â´6Ä$QDI-t$Ëg˜yݶRåè´sî5å\ÞÞþÌD)òüxz„QÁí½CÁï‡Ùôºîzoû¢˜aBœÓãhGeÛ8ÆI¾òøñ¸š?ºqìOœ§cß3©¼ûÆq¸˜Ÿ?ÜÞbŽ „Á \Ò`"P©’ró°)ËRf™¶–P&i‹Ì;ë‡vXœ¯‡Þµm„S‚ššRË*]·=~JÕ”R4tUðšq »SQέo(uËÙÊ:·Ù=LóÕr½¼¿¹)¦ËS÷˜ܹmšMgË3kǦ«–óµu£éöáXùl>ƒžN»dV ‘ô¦Vœç:7öLJæÔ…à¾þêW?}÷ãÏo^]]¸ÞfBÛoï6€DŠ¿ýÿÏúê\qÿî=áÙóW³Å%ÏÑÕú Öìó?ü^7cý°ç)úôÙŸÿô÷É|~¾^èQkõãjq=™ÌëãÃ_¿ûþøã06›c=TGDÇÕô¢«wÎ[Šþ÷ÿã¿¿~ò$g…L“ÅzC0Þ2NAÌŠH+•l«6L}pw··i™æùxs0ãpýäi³¯)"ƵišaH] w7÷«åá~{‡p Å‘µí.Ÿä ‘$U³ƒ€è#§ª—)ç ;÷õa0ãåÙ˺: ¶a§åDwˆ1 iœf³ùëÆy¾à’ÿðÃ_¦óUÕëúx\tÃ(fÓÕf{ß Í“—Ÿ¶ëb¡r‡áÅÅEª²$S};tÇÝü| !èëŽ +’Q7eQnvCÛ^_>©ªãqXÍW¢»ë‹u?l)å ’q8&‹)€zlŽÅ¼@Èá€ÐTÁ”Ga·¿Ï³l¦ïJ¸£*”xèO„’‹«¿üüg!x‘O¬p][€0ÅòÃé˜dœ#uªct"€#¢ÀŽîp8•“Òëx¬NŒa•LïoßË„÷})BŠÜ~ü0›]äÓ\7ýÐëÅÙÌ.ÒÄ›1-&TÆêTùŸ¼xþx¿gü3 €@dš{d›SÃS‰€G‡`aÐ3¬±c"ʉ³}D lÆÆŽqât-ä4ÓëV0‰ÒcÃD›Ùu&£¬é[7ôÀ@™d‚)„˜q¼A€xʆ¦–DªTE¦Îw”+Œ ÑCsª'ëB1:B9%˜r\†~ïŒiV7è%¥)#ÐY²¾C‘B"ûæ”ð‚)¡‡FA0B @ê¡aŒ`(Œ`ŒÁbëGï­w@ÛŠ3Ú·Ö…N$BY÷nŒÅlÕô Ï@ýxˆ(êf—'‰àùi·I„‚Ž3&9톱J”lÚÖÅQ*<°Ö$RI)‡Î$Yrܬµy™ßìÖóÙÔ¦:¶4-‡¡[ÍŸª}ß¶ óQ7ÔŒH.rA@Ðö§I1UyŽ(кÏò9&#ìB0®U|ª­ p,òi*óÃiWÎæbLƒêt;,–Ö‚÷÷ß_]<‡H úD iªÝ(XŠ!ê†f69w~ж˳¥GÄØZ$É8zÊYD°í:¡P ïVzÜÕ€ ‡€p„0ÖU5-gRÈûû‡¼L °qÊ‚6M°Œ&ÜøÁ,D2ôµ×Á &Hh£õ8 ÀEª´é½Tp*e{"†B©f}?D¯9QÎF3Rë|pZ1q¿½]^LMßhÊb!ö¡¡@F‹\™Á ¶išˆô~GpÌdÚÔ-@Èõc 0[Lú^?Ünfg‹jW×u#3Î0 aÁÌ¡ù¼|¼½3Ög©L“üÃû÷gg ) (M’íîa1ŸæE6v²(Ê®j­‹£5yR¦Iz¨o! œ'€23ÎŒÝp”Jt§Bó<)î?|P*_..‡¡+‹éq¿ ÏóÅØ¹Îú_ýú‹<›Yãϯ¯£y6iÇf¬‡¡Õgçç›Û{Æ/^´mw¿¹›” iïäÍÇÛWß¼ûñæÍMHÀï¾ýýÏÿðÓà[‡"¥ª˜Þ½%˜LVåËg¯ñÿþ¿ý\’Ùr•—ÓGPN*®Tj­Q¹À€Õ§ŽI𤓦kct¯^|nÆ–+Ú§²Ä…cþðpy}ÅPrûñ#OùòlaûP·»ÅbÚn2Y=noË$Wi ¸ùøq¾ZaΚêa ΧSçÂ0ïüÅÕõæá.—¤ÜùÑ›hBÇS  ¾ùø#Çt° ÖõîîQÉÂÐõŒºªN¼œù¾ƒ O)g˜lê UÖ™RÝǾEÀîîŽ÷ÇݤçóÕã…VC,rEÝ0Þº-²tZÌ>þø†%’RZíªÈ H…·fuq]š±­Ÿ½~uØ­õœC%3ÁE€ÐiPÎ&!Ø¡ÑÚ9=Œ(vƒžÎãXé¶SªHiŽ{&8OÑi_cÀºq—dYšLF³ È$ÝÉÈDfÝH™r1jßÃóbU×UðÖb€Ä2=´§ã¡HgU{ˆÐŽƒžä %Êt}ßv,QÓrrw—å™ÊƬm{.‰w"„2£•‚‡vÐCCk*ƒvÖ€H™(œë¡§IžXgúÆa™´ížA©û±× Òù“nm–OOÍ&Ž!ïýÑLvcƒœ ‰Øm>aË1I*Q”­®#„$w”Šãu Q‰™Àº4M›—y@·•”¼˜œ™¡Æ”[ãÛú ŠlèŽ ŒKkµ½T9€È{‹ Ýè" „GÖ*¡!;J°àå!Œ!P"¡mu$`† F³ah­¶"=Û7G«Ç¬˜ŸŽ;ݵn «5™‰#¾Ëv< Òriƒ6£NX>ÆAª9Ö Ç"+ÎG3PŽ ¦£0æ âl:ñAHS/× „Õãîn¾\BÌ ƒ‚ªiy1y¼¹ ÑgY1ÔæØö ðˆ<åéqµZcëÓ¢RaF°Ø‚H˜ÌµÙCBÓL ìŽû*)2£·!‚8t‡‹åóÉb5ŒM0¶Ì'zÜZã(“ÞVR];`”(UœÌVNH¢a¬w!„8bH†^w¦Jeºß°€Á~쑤™Hªc;YMbMÛOæEªï±s:O˦U™JFê}•ç4psË%œå‹úxb‚G!À4U1xo;£ÐI YIDATÌSýhjˆ`Æ3ÈèÇT‰P’‰Ñtr%¥s΄e*0¡ ·Öž-žµ]³Ýos5 !Œº³†c (äÛÍÄŽ24ݨB¡zhÇ*-­Ú3z~öìæý‡|š§ª°Î‹2­'mÝb¹à8}óËÛõÕ*eÓ¾wÙ³Ùu°œpˆ¨šÓ“—ëþd«Ó(2œÐÔ;D%ò& HfËòîö-R(0ý áL §]–óÉÌãM°6”‹üøø€0ªíÃr>qû:Oçë‹síN›»ûÙ|Uí'åüöáñÿ/>z丿+tu˜öŽH »‚mø°·|ñðÁÿ°±¶µÞ%% IMêéTéÕ«ý}„çU³J½¼ü*…ºØ\öq¤„}ýòùî‡ë¶k»SàÇþù¿ÿúó©mkÞdAžO_?ý].–7÷ïoï>üç_þrs½Þ¬þ¿/0Mø§ÿIj%E%… ÂØì-Æx²SLaµÞN£Öe¹n®ºîPUõÐOZUч·ã0p÷þ»··Ãùütwÿƒ¢|:´–)ë—߯o·„¨¶kc4›Í;àɶ$e’a½®žž]Àœ«Õ¢xyzÍT˵g„ˆµƒV§4:Ðuíæê¢; Ï»–ÓŒ!$¸œsWjFH¹¹»ùòËÿ*VÝ~÷žBÙŸG“\p Ò &eœçjs±{yêÌ\-7›ª&±ý‘11v|ydPg&'3Œ£Ùln]ž¬À¢fŠ)ó¹Ûoß_·¦Ï§ä|$ Bˆ@LøâÝzv.¸\TzrI°zö–1.d¥´<ŸöŒZ g=#Ú'£‰ÎIòBÎý¸ÚÜAh¿}­ê›¬m§èsBFrY-×§v7ÛT¨eÊe!" 3Êbegk¦^-¯g×OaÌëÍB›çç7]ˆÍú.„Ø™Óí»{;8Ê¥âòññI)Qêfh™ø¦¹šÆÎù‰`sŽ B,¬9q%(“§Ó›àS 1f‚…’Îô0‘z½4Áù™$c9Q#—u‚tM 1#L„œ­SªšSDs޳í´^"J­é„Д`ˆÎ$¹ ¹ÐSJ‹bü9§8`lo|v„dÛ½6MC è‡žqJ¸~✇‡á¸Þl§ÁÚa‚SÄC´„"2@3]Œ ‚@FÖöœ#s&0ƒ)eœ!yê­%^¼ÛœßŽ)!®5‚lF|ð6ûPT%Wbl˜pÂhpÎŽ¡ 3 Îú4+U9?¹`) Ï>Ìrz©D{ìÏà ç8NcH1Ÿƒ%^^#‡Œ—$“·Ãk]V%Ôo战pÖѦ¾»¾õf˜}jš‹ßŸ›ëª²SÇàÌ(…Á~ùU/µ’²ÛŸŽÝyÙ40aQUÕ1ú²YlÊZIEçu­ü ªz=™Ì8 vç.„„!z3c|vqÆ9WEmÝ\håcö)…Ùy;SFê²jO]?œ‹ªšÆ A@ƒ Dàg}× Wõ»óa 9•å‚‘¢@ í;Ç÷»‘\Túðü‰—JØÖ1Î20¢%Î3Ä©*ËóùlæAh5ÓÀpjÛs³^zcŽû¶Ù,‚ç)èµä•”\!kD| a#¨*—ΦDPñj4ƒ(çšR¢åB¦äËZ!D¾<<¼{÷®Òõ8ç¹[¯¶}ßS0‚ÎOË‹å¹=ïO»Œ²’ÕÓþRJЦìÁœ1ŽeS—Ÿ6Ûj4¢ •Ž™ †‡ÓÈ(¿½½Û¿!¢U-¯¶÷æ¡$Tm’‚œÏg<¥$ú9f׬ œXÛuUiYÇ„\jS Œj& (†\Ô*¥l­£ê¢ >MÁ˜ÉjaÝ8›Ž3N8Ëa†ä !D!s÷ZT£z²&8[Ê&zëœBaœP‚Î¥Ñö#­Wí°G—E †(!Ìb\2HÛU!Ãàð E ÆB¦@b‚ÍÓÌ8. -©6Ýq¹ZâDb õº<<в\^®G3–«Eöp¶Ž0”\´a¢1BYWn2)%!(€Ø 3áDXËäçah¥¬1„0ƒ"¢,‡Ä(Á×ZÅ@Ì8r˜ ]˜foU€#Ý,Cˆ1uõbƒ’ؽ~«–-–Cߪ²O¡$•ö§”V«::–SÐB€Y2)¨@8 úf©Ï»6å~Ù”û·Ö˜‘ O@iâ$K¾y%„-ocÈQ/h4”RFp²CbJEh!Иò²$Î)EsœIF˜2TÊ5eÌú~8ZUê˜'‚„wS\U—)Æè­:dØv{B(D3D²v@ØKQÄf¾ÚÜ{ï&?HV{›PÜnnÍ`GZ/»“÷FéE ¤?=ÕUíªÊåÜ]ŠZ*s\r÷ß}?tƒ,‘’˜iã¼ÛôB ¯§z}•!H.A”|t”+¡D×1æD"B’ ¤€Qì¦ä’ƶ©×ânìbºÑŒ0Ò„\ŒnSm?ýò󦪨C; H@ˆ¥lÓþøz±¼ .sO1^”Ë~<{?SB‰„›‹Ë—çç¶}ÛÞÜqª>_ÞlÇÁÈJ!~ûŸ¿)]TÛõÃß^ÿúÇ?ýÓîÛ.øØÎc=gzœNýyÀŒüþûÏý/Ÿƒ. ]ÔýyÀ êb5Ov²ùòâ2kŒ‡$\nDœ…À/¯¿ÝÞüˆ\zùö%Û¤¹= e'^›ðÊ ƒr'yìkO„wб õ3 .Q–5 Ä“¹ ö‰ù?lÑñ:]¢± =T<:—¹a_iô"Cð©®´¯$ƒ¡ællÀ—VqïhD‰ Þ™s"ޤvˆù#≻áêv‚ªLŠDófÊÙäýàðÌL èea›µãi?ó}õ ø) Œ\$¶;¬ Z;£x›åˆPìÚÆÁÅ/ЧÒ!¬Ö½Î%9›¢ÕQ3½÷Cy \tÂ…Æ‚m^~i?ˆAG¦¯Æš›¸½ÉÃl?%O®+ÝíŒgF»¹7ê9ø1¡ç—ôŸ;_¨ŸÊÿ5{ßPW&—Ôõ{äZ×Nãµ3µxa,½…Ptâ%‰DÒÙI1ÝΈŠf¢Ð Fí^‡?„Qó–äÒUËíûJjŸ¢,^ ±„…PCºJÕ:'(³m>£6v/ÀïçÀÕ¿þˆµœ˜iºj3£}1p 7‡LÆPÚ †Ëƒ÷Dm.—d2äƒLtœºFI^Ö1 :ïôÀ¯Ñ”Ì÷{e|Xp¾Y‚Ѝ™B$ÄÌ`z¢â§KÂóXj‚¢#êåÃ;wM,„@âgA ¯5 ¬ ånRqwèªJè†7jê(5j*WXvÐ81t%¿Í[é‚~Þâ÷…îúØj‚,›Óf﹆Úh;¦{¥>ÎÆxBš<z…ÌLesGõÁ€Djv¤nyçwY*ü¤²I›¨1u{olX&’å£L›­öüàUü H©‚\í$‰vSS´4Úñ$f7¿óõýP.»¨ËzZ^i{^¤5ÿzð<[ªI1¡Ò“¦^¶÷4•Š~PæÏñl©5HÒ,"3óž&Led’}öWé£xš4Edý2ÿ¼^¬5QM™u„×b±è!H&M"IÖÓÞ÷Ótïÿ…eþ$¾È`yú(ëikvý$Õ”QyÎåÏO¦”4šAÒjQMvŠi(½Ž]Qæ÷Ç5©Ç× QT³äà¡IØ"ò–$szÞå×ú=üA~Q–¸îû†mùñ¥óî¿ÎoïñäÂö)óÞÖ®Á삵9.èEÛÖ®ÂìMÑ´v˜½,6Z»þfIMkWcö¦hZ»³ú¹‹Ô]ÓÚ­1˶=¶îŽŒ¬Aá"ö#4¥¨êæã#4IC$éù¨<‰RU…èðö:¾ê•W¥©›€IEND®B`‚snd-16.1/pix/bgd.png0000644000076400007640000002247211147553266012416 0ustar bilbil‰PNG  IHDRhÍR@=PLTEÒúÒ’î’š²Ê®®¦šš’N‚NrrjFFB:::...ÊÊÆ***’®ÊvަÊâþŠŠ‚Zf‚v†žzzšþþþ¦¾ÊêêæjjŠúúòžºÚ‚š®vvnºÆÚš®Êîîâ¶ÂÖ†¢¶¦²Æþþò¢²ÆÎΚ¦¾²¾Òš²Ú–¢º¢®Îž®Ê~Šª>>>𮯢¶Ê’¢Â®¾Ò¢ºÒ¦ºÖž²ÊŽ¦Îš®Âš®Î’¦Ê–¢Æ®ºÎzЦ¢ºÞ‚’¦666Ž¢²ž²ÎªºÊª¾Ò–¦¾zŠ¢Š¦Â–¦Êr‚ššªÎŽš²Ž¦Â¢²ÊJJJ‚’¶Š¦¾222ž¾ÞºÊÞ¦¶Êž¶ÞBBBŠŠª‚–ª¢ºâ†ž²²ÂÖŽªÎ¶ÆÚž®Ö’¢¶šªÆ¢¶Ò’ªÂަºŽšº–ªÂŠ–®~Ž¢Šš®¢®Æ–¦º¢²Öž®Îž®Â¦²Ò†–ºz’ª’ªÊž¶Î†¦¾ª¶Î’ªÎŽªÂv‚¢‚–®ž²Ö¦ºÚ’¦º†’²šª¾–ªÆŠš¶¾Î➪¾Žž¶ª¾Þ’®Ò¢²Î¢¶ÖŽž²¦ºÎ’¢ºz†¦Š¢ºŠªÂžºâž²Ò–ªÊžªÎ’¦ÎFFFŽžº¢®Â¾Ê↖®Šž²ž®Æ~’¦Ž¢¶’ªÒ†¢¾‚’®ªºÒ’ªÆ~Žª’¢¾Š–¶®¾Ö’ž¾šªÂz†žšªÊ’¦¾š²Îš®Ò®ºÒž®ÒªºÎ²¾Ö†–²¶ÂÚ¦²Ê‚’ªŠšºŠž¶–¦Âަ¾Žž¾Ž¢ººÆÞžªÂŠš²¢®Ò’¢ÆžºÞ–ªÎŽªÆ¦ºÒßCQbKGDˆH pHYs  ÒÝ~ütIMEÒ E  IDATxœí]Å™Þ\bEqkŸõSÍ¥-híÃi «”úRRÜ ÑA=¥µÍŽX §4q!§íÕn½(WRýRiIíÐ5=ÒÞå8Ô¿íff¿fwgvw´ßÚ÷‘´«}÷ÝÙ™Gϼ3û!é±ÇËd2Oó6þ^7bÏÛ”ç·Ï„axØÙ"¸¿€êx;bÆ@f²05U˜<òåGOýÏéñýã×®Ýûèn´ …™æÆ‘OýkÇ·°ñUl,®ùšîùæ×V IÄð°³E qaOf D3¦7ßl.½uêÆøÖ¹sÇÇ÷¾üÖõd»9yïoO]ßwü=lü·Ȉ¬Ó”ç¾ðÛÉÃÍÃqÆ0žâ7žÏ ß”¿++g°EYIϸ‰ÅŽ·éèߤ¦¬åÃË>m¿yO1£žY_?ˆÞ“—ž?wàÀÞûê¹ñG×Ö­¯¯_iÞyþøoüþ÷ï¿÷ÕÇïÔÖb+åùàõ×Ö ­ÇÃÃä3L>è½0¬Xô• ÚÊujÆO,v¼ý)~¼åu‡eŸ¶Íñ”0s¤Ù|ûÅýÇQ}Ÿ¼çÀƒ\»³„4c²YØ|ñøWÿx߉“'œûcíÒR[§4ÏûÎÝW»sƒôrfš1ú‘£¶‘´ä'Of…‚ºr;^c\)ϸ‰…×Éß¼>¢íÏLO7›·ff눇ñ·ío¿±ï=D‚÷Oœxðýñ__š›ž<|sõí7jXÞ¿çă÷x©‚(„šç}Ïÿú’+1‹ˆƒJƒ?ƒ˜¨ahÎÜ$+q="¯Ä+Ь=<¬4'ìÄ7ÅŽwÆ¥ØÏp—;,û´}DtÄ“(fÈÔ¥ûg›(â˜)¼þâ¾'>{òä}§ßøë2ÍlüåýåId|ÿú—QlÒœYR=Ož¼çžÓ¼qÄäˆIt¸øw>¼!ÿÞÑì4lâXk×ó ®mm©]Øà'ËA³G?ÑeïÛG•Ž„}É`ÍXX^@ïù×ÿÓÏ¿ÿó'Ÿüì¹Ë?üèÊÂÚòòá¯ß{üä÷¿ÿ$1¾ùÑáåõµåÃÏ/-#,,Ç g‡‡¯ ðÍÖ¯ÙY* x¯¼"[Ñ{X^yF^ÂÆeÙbLŒã ±ã]p,ŸjÊZ^vXöiû ˜x²¼@˜Q8Š óöç^>ð'¢÷~xgi3gð [(lLæçæÞyá_}õËßûú7^øóÇí«ó…©£í+Ï"ã«ßû{d¬¬ߨ˜šS<‘õ/ü壹ùù©ùØbjª€ojŠ|ÚSƒW‘i½Ñr¯›ŸÂ}«x Íç±ÛÔÔüÔ*ž"¿ Kb²Þ=ðʇ¬G~œeu;¼eŸ¶JMÐÎ^/ fÜŸ™¨m­ÕÖ®¼÷íK¯¼réõw¾tuâÌ2²M,_½ÚœûÎ+¯üî_ÞùèêÄÿžA~kMÅóÏ>úΗænY[ÃÖØ¢611Q[›ÀóµÚÖÄþ¾…ÞµµÚ™µ‰Ú:&<%Æz׈÷ÚN‹&[ÆÄȯ٭æX>5Ù¯Æ[^sXögûk¨ i¢vÕ=aF»=×^mßX}æ™—½yç¿^ûëå¥#7–ÚíöêÒÒ¿ÞÞ|æÍo½†ŒÈ¶„üÚKÄ“qäÈÒ l‹/ææWQþVÑ¢2ŸÃ_ñ·Uei¯$ëÚsØ€çs(þjHLLs‚ìän^/Zž>mŸµ\$¨ 3*åN¹R~ävwå§Ç¾ûÝ_Û\©vª‹•J£RyäØOW9öÝ_!c·Z­ c¹òòìþ9~îX¥ZÙ\©ÄÕB¥ÜêT­.š£cj °p·\.·*rE­r«[nµ*-äÑju‘S¹ƒËY‰Ë.I,·Îf?ÑeïÛoáâÀeÐ(w„+ÝN·Ó9аÜ@Wã—çËåËÝÊJ·rþ<6þùŸØˆ<+Äó|ãGÄócTXñªÔÍÊJ§ÚX©T[ÝNµÓíVЬ±ˆ¸³XíV;jý𬋯ÜmUºhŽ]prCâòlj€¶äàÑX‘ýxËêvxË~m¿\E…ÒÀt ÝYÌŒÏf ÍÈÌf­(•²¥,~S&lÔ²òb)o””L³òYÊו²W~⾃\PZYÖ¤„A˜PR¾–"è™'ê²Râ%Ý%®È*™¦ò™Õ¿Èǘ5¬d5N⾃~ܸ¦wf2ÒýH3Æ;w*šuF1ƒÌŒÙ,0`ÄΤoR‚Ö`´&6ˆfd ˜š`C‰3@3&ÍÈ€fÌ`j†$Cþª™ì7D¥!‹tbn÷®¦q×¹ÝJA·fâ—S3˜Þ®j™³ÈIËȪ#Xi€®À,nf°4ƒ¿]‡Ýrq€(3}ÝÛÜ>ðÅÜF"‹ª£Äm$5¡$™6Ï%¶BS]©¦Ï²jU꛽L©ÒP–òádžÍëŠUcZÈK?n\ ¯3mÞ3¨½Yך|zQ§¾ƒ Z«R2•㘣f0Ãί'fH6û1ŸÆ/)ógÇ­VÇÔ\㼦¡'fŒI&šÖ~2Z“1ƒ”êÅaÌ٠Ó în9»rÏ j+¾2Ã>éSAí5C¸5áîVýˆ3˜)m˜!Q+-û¡czóö­ 0cŒÇ Ó/lŒs}õ´Äöܾ‰¦PtßÄq L¢R¿˜sjÎNó2 ­ Fi° Sz}FòFÇÓ^Ͼ‚Q˜ršÄkº€>‚É Ð W3Lq†¤A`Ó1N ,:ùš®$j XÀµã6@3l(£ã ä¾É,hÀˆ3lhã;#d͈:€øôMŠ…|>_,âçg3Vë3¢Î †È@k`‚ŒgD @ ­ € J3ÆÐghÔ)èwÈMia†#•¢Î6 pX4c›`FªaÑ w‹4vif¤fÍÈoÛöww!fÔ)”4bäiC3tf ìE(áI6»k׎ù<úóÀŒ@׌ŒU33JY4ÝU’™AØš‘8kF6; hÆÎbј‘hš‘!qFÞg `J !‚Èš‘f¤ºf0"P¬¥fÑ ,(ÍÛÄ9a ˜Z¤ˆ2ˆf ÉBÔØ•E}“¼Ü5qÖ 33€* „Òšdô‘®»tf hÌØ‹™±cçŽn"P € „¦êYøQ¤C¸cZÄšÂO„ú@]b†м$æ8ÃpÞd` ¤ €Ö‰f¸bƒÀŒÂ<ža8×Z'#]{õ‘.w­ Äý¶f(̨ëÌp­0£/ g0ÎÂëš± 4#m°× ÖD®}™ÀŒ>;ÎP#P­5QΛ82CböD€ „i¤Ë•fŸkf$ºfض&Κa`FÁÖ K*Ök5˜‘@ØŽgнÖ™c I…¦‡ñ ÐŒ”Á^3 5I/zé›3ÒßFºìÌH ”Ö$Ã>£ÆŽ3`<# °íµ¢l–ˆXýpŽI6Äòì}Ëûc3c,¸¾ G?8V3ÇÊÞ´È&üȳG²³Ö7ak B3|¨¿˜0ClËÞ³\Ù0#cbFp(ïðDÌV‰Ðþ¼;ûÂŒ€òl?žáÿhŽ-¼ 9Ç –Y(s¡sÎ{†¯ž„»‰à8ç™þÐÈóïDœ¼ë3’ÏŒœ…6“lØiFH×gDP ³P•Wü-ûg‡Ìå V†7»oâñÚqK†´ýR™È±óƱzwæmÂhvØ_ÎÁÊÉœ‹<3yGÒc6œ)ØÆa1#§­‚9®ÕÖìÒ¹f8oÙ1s‚è*=ä™Öj4BŽ3z,OΘ7á–Bõ×»3Ë,t$.=þ( Û8ƒsÞ¤wfêÏ©<Ý8»g†Ðþ¸[î͹wŽ{q¶Ë³kf„¥v9vy ¾U‰]6r’@6¼U‰¸³ÛÌùÂŒ°Î›ˆT‰íᩎ^+Ûjrö\~äÙ·lÐ`G þi†q T¤J¨µ>;SfÌÞŸ×ôã6û3@iMØ×gø>ža›7“ÙdµšÙV–9PÎÙdÃ푸w¶¯l¯y6À¶×êwk’Ó Ì¼Ìl+mv½ ޳ij:oÙÏlp3ç‡3‹]Ã&Ën­6ÎÁU«ÛM—9¿²áº@hšÁÏð±o"’eÕ?jg¦Õ—#‰u6dô¢=g𠃕7_.TÚ_@Îb›ò¶LÀÖŒ ®Mफ़¡ç9äK=yeDRßÄ&oÞ$ìËÃ}Éspûóž vß$€8C0oñ¸¥„£µ~äÙû&¼A #¬¾ 7Ǽ±ÙK³PÁù’°™V™Šfˆ%ñÁY|¯!j Q°@áiLé…Òš„t} 9`kFôq j@œ`#è¾ <4©`·&c ©G\Ç3QÃç8ƒÝx3M3üÏfôzÑ §ñ € [3<ÅV3vßÄËxü[VÀSß„7XqF€gxÏfôD4#¯À-3r:‚?€Ïé›ZìâôM˜·øÖûÔ¬ò”©êmhð­}¥5qu}F>_â3Ã9@Àb†»ë3€ý 3‚Ô #M`E"VˆõM€éYÁnMØã*3„¯ (ï°"È‚šQÍHË ‡8#«Ã¡×"í ÷ûÎ5Í`g¨´ð/Îðý^9‘îÜA3J¥!Œ`FêvÎÖ 5Î@„ ̨×iÛ9»o¢Ç,ÍðÖ7$¶}“z]mMêþõMÉ;ÎÐþ«À¤1뛄ýxÆ€Y3€©}ߤï¾ @¸Œ@A3R¥5á]ŸÁÔŒ¸ôMÔ3ÇŒSÈ}ú€ƒ:r¶f¨qFݬqê›ä ó4Qƒ>ÖÀ~öq†Y3âÔ71ýhÂdFÄ e FÀšÁû¯‚8Ç9›¥ wfäÂnM´ÿxŽqß$G·¶¡UU-ýÈsRÐÌàŽgdK `ÄQ3lncx§C;rªü‡Cœ‘P¿¾ ʼn‰¬9ù¿rJQ÷S„” uʼ²×/hšÁnM¸¦Ë/èÌñwL=A=§ˆºR7QBÈ5L3Ü߉"LíHø½… ´rØ=tß÷ÝKú4„8ÃfĈÚW šÊܵވPrF.X7†Ü7ÉÇ™†‘æ+8ôM€F¤Žb÷¨Å£o ìZ²&¼ù ¶f$¡o Hg„Å yM#‘}“(¡õSM“0Ç3Â'uß”Ö$Øçg¶f@ß}¶}+3ÒÞ7IÄ"P蛤lÍP㌠ž¹HØq†ý3w€i€¦.žHÌHlû&uvk}“4€­Üñ 蛤¶}8o’bØg@ß$½°3 M1ì5Ù–Ï}v.:½`k†rÎÂS}ë_³J}uaSŠa:=CØr¿múîKï[(­I¦§¾‰õf3¸Àp*6°mM\ôM\i0#ðÚ7fô+|î›3ú¶¨¥o²k—ù¼ 0£_ÁÖ Nœ±KfS3r:)cn³Ìð ú&›ðŸ~, }W„f·ïµ:üÇ3ÝñP÷ÃÊ 0#Dè<´{ºuÇ¥| •bÐíöq†Ãÿ»Ï,ËÈôÛ0À‚œa&ñŠÔô¸…œjÐí"}“0˜ÔðZ2dÛM_%‹‹åÉšfôÒš¸Ï-/o®<Pﺥ?¦›¾Îøxµ Dú&Á3#¸§[¦ †ÈÏ™-´P‘LEú&ÀŒ„€ªa^yZâ *]ïq†ðu ÀŒpÑ#3r†•A÷M¸gÔ8lfxDN«j;bha…¹¯jîµFÐ7a’˜áƾ ¿8Õ-Õ—òa¤Ë}n6`F¼¡´&ìçgÙ7fÄ,Íȇ1 ̈98qFZ“´ƒÕ7ɇ1ž̈9z‰@}Ïf…œuÆ8ÐÆµì뻦 4#0õZ¹9ÖÇ C.Ç3 o’DX5ƒ=´aÞYxÞ¹ÖàâŒs˜á­‰Ä*mWÌ ”Ç  †g°˜ÁVm}æR3ÂÏf¿5ÃÅ“Uü<£Ì lfôg„|(ûD 0ÃøÊŒð¯ÏfFß„ÑkÕ)aÛk‰f°éÒx[g?‡‘®Hú&ÀŒXƒ‚f”Ö„óü `FzÁjMòК ÎpÀꛄ4 Ìôÿ^k‹’µ\©´Ó²ì¾ ë?žÃÏfx†:$A¾k‹Ö*0ÜG@ݽh?žÆ5]ÀŒ`@aŽ^´0Ã0ѹäm ˜o˜G?%­ÊM>æ‘óœdaFp×gØœQãŒä5<Âp¼vQ—3¨'ÆšÌð :äÌi²aË }žfÈ{f„C_DoIl˜‘£¬ ÍùîE`F@0ê€Â k‹ž3úhV†f„;žÁæ0Ã3Ô`A«à<{G¿žzD‹kÇ‹¶šáÃx0# ¨ò —–&Cw”hA»ß4#½ˆ¨ö=ì#Ð`5ƒ/3b¥5a??#`ÍfÄ 68qFÐÏÏfÄìñŒbR5ƒu— 'Ø·&ÞÇ38gÔbÜ1í¢Ï`3ƒQ¹®«ÛzæÐ+¢ÏpË ÷M0Ã?hšÁ¼ã9šá¾fø‡h†@u3ü[3bg¸¯n]÷½ôM(f0蘆ìÄ33\V70ÃG°û&nã k¥1«1bfÀ G/è%ÎÐÆ3¬õË’° ‹ÄðËI,+Wx& âð4žá•FG1f°:,À á©o 3˜Râ&,e·F|ôvê2Îè•9Æ73Ø—12ƒvÅ >XÍ“A¼¿Iîo(­ ïúŒ¬OÌ0½ÆÎÈÜ{«.Œú%f£ÕÆqí?0™Á½>Ca¦ˆ83¢>T€8ÌàÄ¥ÒÐК;öZ)ÕgôZ ‹¼ñ ÌÄŒz0#¯€9Òezƒ‘ ~zÁ.=o̾5A}$x¦2ƒL…GÇC÷‚]zÞ˜íxþ‹¬ÎŒ˜=7 Ý véycŽš±·D¦ÀŒ~ߥ;ÍPâŒ:ÏÈ’Q oçZÅÜþ¢·âwê› x? ßSÖ>Á 3x×gGº}“ ³ð 5ƒÅŒz)‹_ 3òÀŒd£f°â )|Î; ~°3øˆ:Û€ÀÁÖ `4À†Æ ÖõÀŒCiMØ×g3RŒ5ÃzÖ•uà7¨‹•¿Ø@c†A3Æ|`†õJ 浟A?Ì/çðÅJkâêöJÀX#"—3”sÎö‹-Ø­ 0ƒÀú ÷ØÃTñž™ÁÕŒ! )dFÔè ~k{tÜB %…Xþx–˜#yM ßš‘aF CCŸV0JtD*¦‡òU³9õÑÝê5´ºÙød9ý‘Ý’ê¢û„™oãÔ_Íå3#E­ ëÆ }¢=϶ðn‚ :ÛÆ©¿šÁ`FqT!„KfÐ]#»;b Mèï4¨'ûë2¢¯¢U$Ìl볜Ã;hšÁé¢5#/¤´ŽŠ °ÄÔŸHQ·ÌHfäÔ†^¥& ùˆ©[G|é2÷Mlâ ÷ÌH<ŒÌ l Ͱ¬R,Éú-ÐpŽ3JTkÌbFÒDÒ¶f˜âŒh†A¡Í­ Yӟ̰Ïè=ÎH< j¡Fú'§ñ$gäŠ2¡'ì”ÒŒQÅQѾIâ¡Gä¨E%Æ“LÔÈQSƒoT™÷¥5á]Ÿ1D8A>£ÚåÁ)a®+<ùÌàŸQËã«Æ‹Ê˜!Ã=3ÍF°pˆ3xˆ:ÛÑÂ3¬¤H”Ö$€+wú.«<ÙÄîú @ÂÁÖ `@Ó `ÀM3 5УfRÎ"Rá¾ %pñü 6ò»ý­‚{3¢>@ÐO…gèšñ™êƒÝvDùi@Qí½ "u’Lø¼ ¥ʶòŸáï2èŠrï}ífdFohž0C~ìtt¤?’àšøRÌ~~­xsQÖ 0Ã'à‚$Ü°Ñ ×ÄŸPOÿ1NTføµ"wÙÄBšƒÙ(ë˜áPA–peZw<³JªDîêDx@À ?Ï+ÕhÓšPw"Ù£¨õM¢eF”{ï#äwi=M®fpïxfkF„̈T±úyµÝÄÌÀš‘ôhÍàÝñ\’oQû´|‹š$iE3¢>@àj†åŽçu÷¢ú!¨ún4Ãz/¼xsõ¨Pˆrïýˆ,­ÎOcÊ+Ô(b?á#ÿ™TÚ+Œ¬Ä7…ZÊ%6㦔Ž2ˆf¿Ž/•²u»]ò2â~–€ õ˜-¹3ðó3ä°ÄЖ(éŠk®'f ¹E½‡ÍD!ÿ–6šQ”ïƒU{­ff¿Ž'.ž‘’kfô²y€(²¨BJ˜†8ƒ££:Œ÷ü¾‰û+wJô†E2bSß¼|[,@ ¡”(ù©Ñš÷¨èù5@Ÿ£÷8Ð'ئÁ`¦ÎµÒ wÌ”fÒ‰mÛþŽà®» cš )G>¯3ðB훸­ôtfè¶¢Þ7!gÎÆŠäS+j'ÓŠê£Ç‰ ¯Ä‹ÅÑâ( ?@µ&”ÑMœÁ9¡F„ˆ¿Ž—%q—ÈÆÓõ6NÀåÈ3 M3ìâ `Fª‘߆8!Ã`§GÇÃm6a 6lä‹Ûîb2ƒ¾>#Ìp:o#Ñ|ûú¬Äi#$ÐçMäðËdRVz„WÍ„Ü7™•¿’j—è¿®eÂi½mZÏ­ hFX0h†òÏq2ÃQ3B8ädc”zÊøü E3´Z·¯û`™šajðRàWÄM%ñ‹“Ö #3ÌÍ ùƒ²VùbüËJÉ…³ÌH;¨›ýHÅg5š³e†¶J©hÚbÑ޳äCk’rÍЋO„üT¶š‘ak†¥!à‚Ç f*Ð O¥Ф~£žzC¦ŠM²K¥:JJzË í6š!À ÉҜ證ÑÆ3þzmGºD ï¾ûî'ôn>™iäZœyw¦€‹{||»œj»ž¨03£¦¡^­ó­ÅÁÁîÈJ¥Qn•år£+Ç[µñà±oßÄóäËôÞ¯¼Ðâ~´´ü^sVYEÞħ¯Õ¶jgÖÖ´\îнúü½C./R:×®¡ù¾¾>J wIDAT}j!Ô°ä¯m­ÕΠ²Ù"%„?hq ÕÖ¾ñÓ×pBœêJµy£T[5ÙOñ jµ‰‰‘n§[éT+‹NEÏ@Ú8VÛ赺„°hÀËK‹/ŸZº¸xq‘¬ “‹Øº¸¤`uµÝÆ"§$G¾2.öû{Q.2=µd.T(smÜÃį¶üA_±½M {õ#s¼r®­ø’)yaÌÏLL`Î`î `CϨ´:­ÀБªQA¨v+›j—¼:+•ÅEDÔ•••Å•ÅêfÍV7«+ÕÅ•Êf·ZÝܬ”q¢²~£2Ø\¬.¢ƒív:Ýj«Qí¶*ÝNµZ¡Ñ)WZHþ;euŠ-¤ÀЊn½­J£U-Wªå2zãU-œFMÑ‘S!4FææUV!†ÍËçMº•nPh zw:›¼Øê DDüê¢þú éÚ¬VÐÁwѤÒm -ClA³V£±ÒÁ9#Ë+ ¼µ"îX5ð¬ŸßTLè +˜ ­j§…ReTf†¢í²i,’Âß°¥+“©‚›œªŠÊ\Þ¦¼®«zk/„ju¤Ü¨JUZˆMÊxÆììã?¾{÷ž°aÞcø9HDËGÈd±‚™…x²R^A_13îÏd05‚$Çî=hÛ»•¯ô‡L ÔÅݪu`zJâ£-îÞCßM«鯔Ûnyº[3š ÖP–²Q)O­dwË[0”ìníEUI‚˜0ûøl3Sqc÷㻃Âm¢«ºd]¹Çd2¦ÔŠIõ¥Òí¡{vÜêoüszM2i“̤W ¡WéD*E)*ˆÈ"`ÇU×ö®_˪ë®eu­k_»‚ ¢¢"Hï½§g2½>ÏûÇ“;æŠ,‚ŠžŸÃc”ÉäÉLœ{Ý÷uݪ Á """¢ß6õY¹—%÷-áCIDDDtŽ2Ò’û–h•·VúWþü»;+wBDDDô;ó33ÒŠGVàlUÚˆˆˆˆèœbh#"""bh#"""¢³A{ò‡”uÓ3pÆ_HDDDô;v©ß5ýNøˆJùÑ|ÜŠGVÜqý||‰ˆˆˆ~-'d3ü`¥í䛞N~¼ãú;Ø=JDDD¿cgxÎøKNþ8÷´ÚˆˆˆˆÎZ>Dô+šŸ4ÿ¡º‡x…DôÑÇÜçÇ>õ“K¨ mDDDD¿œ g+Yqr»èÿÚ~N$$":}¬iÑù¨yR:§Ñè´*mg ‰è™½”7”¦D1åƒM™¬é6'|Õ)rÛ©ï§ù÷úÉxfWHDtê¤t®£—G‰è,'¶“cÓ oœp›¦üô“•¶SßÏiVéÎø ‰ˆ~]§ÚxÔ¦æ%«¦Üsšqê'ov±ìì^!ѯ˜”~:´­ô¯ä2(ýO¹ ¿í j¿ý+$¢óÈ/–”8§ˆÎ¦–;ÏìkÏÝUýÌ+$"úqOMÍ“ÐÕ±~0-ýd#Âé|¯¦íh'oJkúÈ_!ÑYqÆk© mDtösÛ½{Š=d?Ùˆpú÷sòO¸ç3»B"¢Ÿï笥ry”ˆ~£iXg"¢_ CÑy@ `É}KNþÄ,¸r2ýîý2éä/Qmn8ùvÑ-.>%DDDD¿ m™í„,¹oIc#BóƒªV<²bÉ… :thˇŒˆˆˆèöÄÏv)ësB6÷´ÚˆˆˆˆÚˆˆˆˆˆ¡ˆˆˆˆ¡ˆˆˆˆÚˆˆˆˆˆ¡ˆˆˆè÷äÌŒW©l'P–]'Ü ùGNøÂ“?õóýäUpãÓ¹à³rU'Üí/ö­ÿ§‡ë¬\À¯õ³ë×ëŸ|==§/ÚŸóŧ¾²û¬òñLWgÅ?^§øÂÓ|Î~ùkþU~5O}KÆ5""ú£9×ÙFÁåQ"""¢ó€öÝï™Õ ÏÅjÝÝÿÉE¦SüçT>eÙÕ¼4õƒk£8åRò 7ø9E²Ó| ”kþÁo}ŠË>ãŸåÇžšsý+ADDtîRÊ©_ã~ÑÐvŠ‹8ƒ:áÙ "§xùÿÉ4pò7}üÜÅ…ûÖç:™ýOOGÓ»§~@Îìgù±ïõë>DDÄdöó_”ì5î—m¿Í—ÏÓ¼ª’ïùû»uŽž…_òÉ=ýïÅÄFDD¿äKÒÏ gñ•Kû›z¤~)êÔñ„uÒ?òrfÁš¡ˆˆþ°)å·Úø’Ìä'ÿ""úc¾(ÿq»GÏ8/ÿvª_'ooüUŸs÷€üÁ DDôGÎ';çÝ£'Zý±O­µ°k&8¹}£ù»§¸ànüsæÀý`¡è æwõ¿.¹þØ#pÂvên—{@Îî“ËåQ""ú8õKÒ)RÄo¢{ôÌ&ëžñ§ÎÅUð˜þœ{þ9—÷ó«s1OøÌ>{?ËÉ?+?ÑÏY<Í—¤Ÿózzú8\—ˆˆˆè<ÀÐFDDDt8ÃåÑSïªûµ–´xUçûUýZÎÅ+ãÙ}==ÃÐv^ÕåU1–w¯Œ\%""":0´1´CÑÄ6"<ñij|tˆˆˆˆ~Ó¡-??7??—Ñ/ï~ ••Ë£DDDDç†6""""†6""""bh#"""bh#"""¢ßŠÓ={411§¾þ òöSO=7oÞŸüþÚszeC”Oýî…B§•ÇXi#""":œn¥mch#Ìoš7bö6½ ÛoãCIDDDôë‡6+ý+ðã+Yñì5pÉ%ÓOç~ÊÊZâ³·Þº˜Ï Ñ™‡¶ÓÑ®]yówÇ›ðÚkÿ9á#/½ô|Ϟݕw{ôè à‹/>mön„Ï Ñ Îáž¶qã&¬\ùÉúõ›Nq›Ã‡÷>¼‡OѯÚV®üÀ Aý~ìJ™ À矯æ3ADDDô+„¶qã&4½ýcŶ¦Û¥—^Âg‚ˆˆˆèWmJ™MñƒÅ¶¦2›‚Å6"""¢_:´5/³)N.¶°•Å6"""¢_:´5/³)N(¶PfS°ØFDDDôcþ‡‘+Yq:7SšFOþøúõ›šyá…WøèåÐÖÆÐF™ ‹Ÿ:{ô€AƒúUW×(oñŧM£Úˆˆˆˆè¬…¶Óôce6Åúõ›”ín?¸wDÄÐFDO'´4XLO h5ý’.·/4&'ž|³UW]ï=tÌlO1g¦oꥰÇÀ_]k“å’Y“íÚ6Ýò››ïKi_V0æÂºMÛßêq1b1ÐX-–L‡ÙoLI2ÚSŒi©gš9ÝnkQPsô“Ï—Oœ£3“Û–v¹ÿVµ^÷íŸÿÏ”d3§¥š³3âó²Íé%ºCo¼ù®¿™â¬¦ì Sn¦%ËiÎt˜œiÖ¬ }BŸM"bh#¢ß§g,…* ÐàIë٥͵3r†ö;ù6;ÿõŸ/¯¹EH€,þS´ž;½ÃMóšÒÒ·?^6yîþ9gHß·Ú òìÚ§$ ļ>ïŽ=@Ÿd 6xÌ驿t{÷¿Þ’Pó~¯Q ë6kkq~ù¢Ùûß^úíŸÿÏh1›3ÒÍ9™ÖŒt“=ŧÓj6Ýp·n·ª-f“’Ør³¬9™ÙCú&æò9%"†6"ú]ÙñÏç¿Yp;€øâüÖ ®lqÙûþû‘Å‘–Ö¥r›º-;>ºpJ´¦N „SzjæÀ^ßû$Xß9 gù¼™ý{(·ô<ònÏQáÚúwßXÿÝæ—æß¦4Ôê˜$©ú”¤V³&]±:øÍwr4Ö~ñœ£ï,ý´ßxe‰Ô”›ŸéX:d²0QŸßµkŸk×>5 ’`€973}Ä`ïñÊ#¯½W_SW½akb›’^“F)‰mï+o»÷4šŒfgº1=ÕœaÉtªuüÇ™ˆÚˆè|㯨z»ÃˆË­6›ÊçÏl³xŽZ§ ¹ÜË/_àìÑ9ÿâ!ÊÍ>Ÿ}Ãç^WþQ ÅSÇ•\yÙg3“»Ý¿¤hÂHG?ýÒ˜’ôí5·Ô}»Qk2jµšooºG h HïÛ]Ÿ’´ûµ÷d oôзÌÿö–ûª¿ùN­Qg¶oýÝ%WR¾Å#Žè˜’ð€ Ô@1@Èž4*{ÊØ=?]óá  ©Û–];S“j×n|·÷@g‹7äZŠòÌÙæìŒ‚ÑøxJD mDt>ùjÞ­»ž~YäM¼¸äšË“Û”ð8òÙ¼[ŠÆ_ÔâÒ1j6l}û‚‘V@„´=˯»2ê¾Ó{LáÄ‹{=~÷þC«æÜ¤÷ÖnÔêu¹£‡©ããv=ûŠ`H··¼ê²äÎm?9]Ò»wt”—|Ð~°hkL }¸ÂÈ:­‰ª= @L€ˆ* ‚@c.t½ôVõKoÅ5 üoøhÅŽûólÚ¤Àx]î†u›bë69ôìså¥''6ßÑ Sê‰DÄÐFDô›°á®‡w?ý2€Ö‹ç´»mòÁ«Áµgÿà—ÿ®³˜|0tríªo¬@°µo]:fb›Ò/®]rlå꜡};ݾ@Õš ôH@RëVE×Î0d9?<©©,×jÚø„6¥ï » €¯^»{õZ# F@­Üy—vzgú¡·>T¢¡Ð6@ ¨2 €à"€ p¿ñ>•ØW§T@àhEÚÑŠ8 $ dõêZ>wz¸¾AgU~:[{¶zÝ&Sr¢Ù‘fÎH7g:Ìéö„‚þz1´ýÊdIR©Õ»ž|qóÝH@ÁecZ/šÝôYƒ-!¥M‰Öd\=Éî'_2:À˜åÌ™4ªôO³êwî}wÐÄ@eµ½CyÇÛšìɾc•«úŽM¢€”dËœ2ÖS[¿bæB"@bÛÒß®Þ|ï£6À ¨€¸®íõŽ#o¼¯ä6U¢-gˆ”¾|;k¡ˆÀD€(È€ð@â?àb@ЉÜZzÀ+þó)M€ˆKNŒ¹=;ŸyÅœŸ—“aNKÕ KGÍP–neÖœ•aÎÉÈ5ÔqA'þ’1´ýÊÕµZ“ñ£¾ãê·íŠÎ=Û,ž£5›šn°ú†»[^6vËCOí~ò% ŽaýJ¯¿:¹cEÕ—×. VV[œiE—Žvï9P½ü‹]7ÞcÂ@Ðéõ|"t¬R DmZJr«âã+W'YJ%,Ýž1yT\·ŽëçÝ¢$ 䎔såeŸ·XøV‹‚m}bM²•­pAÀ ˜D Q  Ð~À-nTJâb@¨¶ÞW[Þ°Õ˜h3'%„÷TZ"@B«"SanÕÆmÎÞÝJ.Ÿpòƒªo¨^·ÉlO1;ÓŒ)Iü-"bh#":‡Þè>¢ß3î{þõ­>)1 ¡UQùÂÙñùK;ž}õë%ðï‡}²jÛCOZW^’Ú¯‡ûXe²,1÷fï¡£²Z%Ǥý;¶g¿R9 ¶^]wà½O”õ$½®hÊXGÿžŸMœSh àr.à¼|ÂG¥}u"±%õê¬s¡íÀN€ˆoÝù9Ñ8‹ü› xàÒx h-&êm¹€ˆˆwbœ0 ‰Rœã4õ.k½+ DuœµüšË“{vùêæ{s‡ôE(¼ë¹×-ÙNGÏ.jmã?à_̽¹zÝfsZŠ%;Ã’é(™5Ù˜À_'"†6"¢³ïIKaRQ^Áø‹Þé0$oì…Ií[W}·Yk‹o³h¶£ggu[v¼Óÿ9ëzǵ þܵÏ„”Ê£Ç~òyïÇïÙñì«)íË+¾Z§ÕhZ{>Xa¢€©8¿pÜE–6%ŸNœ£cØZÏž?rðòÞcJDœò–ö­=µ®Kû*u¸ Ò¥]¿/¿‰Åkiš²––  ?çÈ‹´€ð.À\ ¸zÑ‚`‚€ H nÔ€˜ø/ (%Då« € ÅSÆ&÷ê²rÖ"ßác®ï6›²3RÚ•õzô®Àñª]Ï¿«ªÙþä‹Êík€Œ~=ÚÝ0—‰ˆ¡ˆèœø—¥Pxvï¯þú»Aï=·ýÉ+¾Û  Ã-ךíÉ®{¿˜sSÕ×ëT€^«Ù´è/Z@%Ö£@«QC;ݾÐ`‹ÏÒ罜=:·˜6~ãØ+,@mñÎKFdMýzË^J7@pö» òÓÕõ<‘? Ù“Zø*k|o~ D¨”>݆¬ûÊ¿q}@†GI]VKrÇr]λ‡Oàe³‘z„"ðÈÀ x€`Äöµ`;Û"h¼q B€°±¨ª„H[§¶uÛwo~ìYeö[ˆÏÏîrçâ/çÝzü­•³4@°äf•Í»<£W׆{# n³#Mo‹oþ W~±¦úÛ¦´£=Åœé°ç«Ôjþî1´–o®¿kû£ÏÐÙâ˯»ªìÚ™utÙ*VgúÞß2ÅY¯úZ˜• gÑXÖ°~î£U·E€ÔnÊæNÏ»x€o¯¿kë£Ï´œ5¹öÉ·¾÷‰ðAÀœš²ëÕw¿¾ó! (™1±þð±cK?«]ñe{ xpB¼ã¢ ½»î~ä™Ð®}J[ÀL;ä5_¹%x¢ðKhu|œ'¬>%"ZDG’à‹!(‚ hB@K® $‰EÒ˜ E1OX³xWù*¥‰!\S©ªÑ‰/L*oeu¦¿[Þß$‰0 ´^pEéœiënÿ¿ýÿyÇlO1g;-YNK†Ãš“i´ÅI¾À²Q3|•ÕÆÔdsn–9ËÑã¡;˜ØˆÚˆˆN×ÊK¯ÙÿÖ‡;rp›ë®ª\³þ™ø:@«0êu¡@Ðh€`ÉË*¼|‚¬Óí¾áî(?æÂÎ÷ÜhJK­Z½ö£T@ à~òE½¨T)‹§&£¡áÀak«¢×ϩ۾§òé—{Ñf;̲'ŒÈ{ùLJ…ÁpE&ädaød4Èp €UÄ^y'"zÆkŽ C[àÜ@ 1\×x#PAÀ€`,€° ›­™ê­–‚©ãÌŽ´­·Ü§M©u›¶›6m·‹PÞ›;v¸-?çµÂîj@ªM¼Õœé0™Íú`È¿eGLçå­®u í×þƹ?xTë¡w–“lÆ”dsfºÖjáï'CVL˜}øÝe1 ¾EAÙÕÓ2öz·ÿxéX¥YLD“€VWLN(.غð%ÓäŒ^xùÄH0¸|Ô pvi/»=›o»ÿËÿUñ€rfhP2J-æ’«.‹©TÁ·?î~ïM_\vM·÷@©“ù?`*oå …ßnÝ/ \™ ø €P´1¹DñLéñt`¼"ÑÆÏºñ}™-H‚b› ”±Hê ¼YÄl6¿øHSE-¹mié×Ô¬\½ý–û”¼¥2İ·H³›Úb>öÎÇÕ¯¿g¢@BˤNm>ÿz¶Ýʼ_5@rç¶m_-ù|_ßìL³fgXr3-ÎtU«×®š<×lЛr³ÌùÙ–‚\K^¶ÙžbÎH3;Ó4c‰Úˆèç)K¡’®TCÙU—•Ìžòõü%kçݪŒùW‰Úlêú×[£•Õ›Þ,EyÅ—O,œ1aÙES½ß¬WFÝÖó²³Í èEYK$ñnR‡òÖ·\lð|½èޏêºèÈéå€W4„Dh«Ù´=ºi{ ˜•¨Z"aøÅZg½øÏ¨õzw8.3"&ÃiLiJߨP € ðŠÐàÀ'ºübô®27"&ôú/F“J[˜ÓR¿½äª˜ˆqʘ·¨8†€0 wØs÷©zöUåƒa•ªÍM×8‡\Ûí¢B±Òß±èò ïºþâÑ`ÈìL7åfYs3Í ñ®¿=m¼âl®$þvƒ%'Óg1%%šÓR,YNs–Ó’—mÍͲd9›?•;_x£aß!‹Ãnq¤åÀßm"†6"úýÄ5%(墶‹®2˜Ío¶ìeT«ã3Þ#Çe1ü¢å%#6_}S @œ5oô°‚)cvíÃ^nÌ¢N¦R*R@´ÙD4Ê™™Û†vïßz˜íoO»Þû$ d‰ýs=Lð…ózåÛê7nSjTÔ)5€-9±Ë_®7 ž{ÌY‹é„'}×KoYi&{²ÉžbJMæ_Cý¦íóƒO/›§Ãc•q²¡ã• §/º|ÂúîTÕH€0‹“×ó¦_ÒrÑœwKzÇ©»÷x•$6«E»Øµf*-öí?¬õJE¥MÙ¬¦Ü•¨‰mŒºqw—[Fƒ : U ¯ ¾(\*èBðA ð ¾07çŠÉ³t¼¼RcÎ#ú@5€Þ™Öp¬RÉýE擜i mJµjûãÞh×L@W@‡_ù”Û+aHÄ5¥ÝÁ$ˆ*]ÐÕ>c ¬JAÎ8•VƒfƒHl@¢Ø3—:¤oöËí,÷‰0êÂ@W3ü¯ïoO+SèB@ÿTÀDŠ"xdå= YÍOUmýö;°de˜ŠòÌùÙæüs–Ó”šl´'ïzáÍM?mVâšÃnq¤YœiæŒtKº=¹¼ÿ(ˆÚˆè7çëÞúÏÔ€ÆbŠø@-*jŽA½ítþ¸×蘨T)…š(Ø®ìøkï~æGq~Ú ÞžãU o¼¯,€ XÛ–fôí G²¶>ÛX1yHä~ NÜ>RŒ˜ ^na@rT¨¼22‚AèDÛf=P„­^g‰³¦ÍZ$iP-#"!,5f5Ÿhñ¹ã†ZñEìXe? *òœ¡¼$mø]IѶg_ì= ‹UÑ0ÐM¬KúDb 1@)•ù[ûÖU»ö©¼¾rQMTÂh ° &jlÊ•‹ÛøÅ¸V€N´¯Úü>5.ñM}@ß8£pGá‹Â”·‚ì…Êx‹¢ÊHWèÜ€[dîxÑ,:^å;^Z³Þ\œoÎtm£~÷‹o)õÔú#Çj`²§X²œÅ/ÎÔ›D mDôÛòFëþî}c@|NfÞÈÁ{^xCã @Œ´PµK?«Xú™RÂÑ&qnº¬ß cX?ÇEƒ"¡ÐŽGŸQfaÄÍRöÊ›;}ÃÈéI€Kúd ˆ{Ñ4- /ܳ',Á'# dx寭ly@à•á‚rãÊi‚Ÿ¦¤+{8¢^¿%¤‚OF@ mb±U“‘Pœܹ7­´Eû®Þúè³ek6´±É„â“úvO7|å䫽FDñÌôb¢è[ëÔ€r$—&!¾ÕÕÓ¼oúw›ÍB˜i€rDT¬Æ¶4bœ²µÎÄZ ¨€x •RbqíA$Ÿo ùm!ys>¨ýðKhPÁ„$Dåï[°6¥S¤Ùê­R{‹îÚÚµOy9iÚŠ'‹ç4TUÓ~Ñìü1ò¡ˆ~Cž±HíÒÎ;{wk·hög—\%Õ¹ 𬢠0z«%àõi# œ×¶4mÔÐu³A$­èB°¶- ,[utÙ*3P+NíT"]ºX 4vl“Öºeþ¿_©bÂ@H¯ ÈSšF— ¯ !Å? IDATj—h¢«â€(|2|@H†ZÔœ£‡Ú‡ô­Ú½ßäþqŸ±Ý›MÄUò¢¥ §Áïß=ùjGÿûÞú(èóp…â¬RO³F Vzúv/ºâR×'ŸŸ~Ù/²šì¤ZÑŠóÿ»ºœ@|âú»‰ sJͬ§r1 ºAHn@r¤zH>H^ÈÁïg—ødhåÆ/QI¢nçOPL\žZL7{¦Tbš‰r€lΠ^ »÷ïzî5³ÃnJI2¦&›v³#,D mDôëø—¥PŠò:Ü:ßs¬ÒVœ¯3ßn;°é(te8™,’–ˆ·'gî:p$ôÁr¥Õ ¨â¬¡½7ÎZ¤‹€v±ú©t¶j€:e? R0`Ótã{uMx±vÎ Õ*D%¨”-ù2Ì€M,*£:†›Š¢!Ò¸¿Þ4a±LÙ´˜è—¡õ­ì)csfM>¶fö¿>n6¬^Û^ŒÕh:®*Ô·¹°uËž/<úõM÷Ô9®úˆPèÛΔ›YY–ÕëÚ.žS|åe;³:*™ÌÓlåÔ$·¦N…îb¢œ_¤:/XÄ¡XQ `hÖëzi¡ B5ZPÛ8Xö!æC ‚•h˜•¡–!Éb眥EAP–}ûi£Q€2sPr¶²2«4›EPSvûY[š4šƒKWitZsj²1ѦÄ5s–ÃìH3;Ó’ÊK,N¦7"†6"ú}~åbçÀ^¶]î¾*u¨ÞõÑ…S6oW‰ÂŒM¼–+¯úÀ9¸Oá̉_®=þÁr‹Xn“«Ç«;%²8EYNÒ€¨X°S5ëHЋ3=e-W}]õu½ A& KŒI3.À/¦àÑÃE8†Ü¸cLÉIVÀÔ6ËL@é“°Þç^ßúÜë Hgº‡ÄÎ3åKÛ–¶¹îʸ‚Ü¥ç¸wîMÚ6[ múO öòÕÖëZÿiVõÒU»³:Jø¾ËÁ¨#`6Ìù9µKþ@¿fᯩçràÂ@' p5âçò]) Í0±4ë<ˆøáÁi ì¼2ô@žh}ã¬I=:™Ú”Vï;(íÚglöŒË"é6µýjÅSW|ékqþê?ýYh#ÑÀ±ÊÀ±Êº­;eÀäL³d8.xø&6"†6"úEU»1gä­ÙäìÓ ÀÚ;Ü|ßcJÇh0Zƒ> Kb$‡HhSR0gêžÞ8þÚ{ (^ûmâPe [X4h»˜d}c›#’«OÙ[vªZ ^†ÈÄ72P¢”…4¨•’‰5¦å°©€¨Ó:” –-ŽŠˆŒbt¢Sé~hZ5Ê ^­@Ø …Â2ÐáÆkLé*µºx긵–B‹vn±GM h€äò’ü #Ž³Ô—d½ü_¥º±Å«2õ[vúDÅŒa@¨j¶‰MZ)c{ûˆî Â~„pLjÁ£œú Ãt#•Âaƨ¡ICûºkëÞû¨¯”Ä)‰§F™xbÓ@“·FÝᆹŽþ=>>Õ IcDd1öEk4vX2?¹MÉÉ¿K»^þ¯Îj6%'¥v(×ôüã"bh#¢³)µSå ÏÁ£oõ%ÕÔéÄËsZq~jﮞc•¾Šj_EU°¦^ …t‰6M¢í“‘Ó€² @™+‰ùFÀ«lr’ÑA) Ê¡€È§K¹¾*¨äÆP•!âWX”R€À­ŒÆá!"5.kJ@\€·Ù¹UmE%/ÒÔaÄ5«D/ ¨ôºn³§î~àŸ•üS f ALnläÔ[eKØýÆû=ùKÁ¸áj­V­×m³êÅ·öàû* oÂÈ’y3Ô:¹ÓЈR2T©,Ý:$´+«­© WT[kêt€.7«æÀá€h†[äÝ|ÀävêüQDá‹ ^†?Öx`Wp8§KÙßïëÀž~ºzîÍvQP ˆ¶%V*ç@øs–Ósø˜RU-¾|ÂÁÿ~´îÆ{”Ú›:ÞjŽó9®d@Ÿdëøçë2úõ8á·¨nÛ®3ªSJR¯Çîfb#bh#¢s¥fý–wNP‚:@ ¨¼)ã²'ŒŒøüñÕ5þÊš`uÝÖ¿?›Ò® ²\¹rµ^¬–ª€4”¨rÄŽ{ ¬K*û¨²D‹b0XÈðËÃÆšôTØB,äÕ qwšGjœ¾ÑR$hÕTj]:‰¤jÖ`üƒbƬU\8©{ø©@'6عš[3ä”_>1¡}Ùò×_:¦aÛ®m÷<¢yà •¸T¯˜Ä¦DÌøìŒ¶ ¯*š1ÀAKaD”¾¬tJ™x±œ‘¾aîÍêš: (^peí¡#ãöÕbgž[ìðË|@·RÀ)·„@± ¸dÔËðÈp?P/ÚB½@ÀµâËÊ_†› C€µ(¿~Ï~•,3¼@îÈÁj‹¹ò¥·”£·>ù’Z”岆ôIïÖñ»ÛîWNŒ°•·j³xNÞ¨¡'üò¬¼bQÝŽ½æÔdCB|ç¿,¶þ¿GfC5žƒGV\¾@j ){eOoÎH7§§F<ÞYºîŽË®_»zÞ-f@¨8ñê×dQ`‹Ùb¤Y/±-"ŽõŒŠÚO52BrãÂbLÔä.Ð!EPFPìÇzÀ«TƒšÒðŠ³°”}ii@&à¡Í/ú73šuM€$ÀÒl W\€Alÿ4Ë&[|îÔñШ—½T û÷«Eh쉫U.À~A'×ác™Ûu¸~Ž­¤øˆ¥0"®Ê D’lÉ=:Y‡ôy³ ;“=¥|ñìâ…w€ºÆ¾¸}ë–ñéöš=’öòƒ‹‚Q¸%xd„ÂðGÑé&Q‘s5ž±ò#ìE´Á@c#mßjƒ-¾ý¢Ù[wywïSõA Ýâ9ý{|8x’0*‹×%Eæ‚Üã›¶·š8²Õ´KÞhÙK¨­–òù3ËÎVë´žƒG}GŽY2[ÂÞWßY{ûƒín¾¦hÂÅŸ?÷¢ük"bh#¢sE–¤/®]¢×ë•‘ýaÀRœV«w¾ø¦9=ÕâL?ôî2µZ5èígÔýƒ')›ý•QAqUSb“•N§Dœ€ЈcוJ˜’Ì $¨”ÅH[¹±XÕS¿ ž(ÂrcR¾Êèb/¸Ù^~eÓU`€ €=ÅÒ¦¤vã¶ÚªšT±>lvÄ{ŽhD‹$§´"†ÅÑ¢z.÷%Õ¹€Њ„×t —ˆ//i?kRõ¦í0s÷vï=èî4,"î¹±I"/»úàѯ ºË@îð­æ^ž2I%r¶¹eaÛ«¦äöjVG%ªÔå%×\žÜ©Íg×ÜZµzmýêµQÀ˜žÚöÚ™¥ófØýï×>¿v‰‰˜ÓS+½>[Q~§Û(Cw7=ðDÄ09Óœ=:ÛŠóù7EÄÐFDç„øòÊÅ*qTÓN5D£Å“FµY4Û`‹÷«ø¨ÿx= ,€Zl>“š-†ªTªö‹ç$¦¥Zp»²0ªL&s‹Wubb ®2ú_Úª’¼2¼2b1„EòÈ Åä°zÑóØ´ë¿“ˆb²XLhßÚ>müþy·*K½ ÍÎ’ŠmÄrr¢«¶^)¼eŠcDœ| œX¯j¶­Mi†hjÌŒ‰ÃXíùÙ–¯ÿ`¹hh] M]@¶%dŒjëÑyÇs¯7TTëMÆÞßé¸bQýí›­]úCûÖ’ÃþÙ˜Y9£†uÚ‰ë>÷¾ü1xb¨“Q/!ÁøËÅ,¯Âu\.‘Ø”™mF娆{6}µVtÊØ¼ve“F­›¿dÝü%f[|L«õÔÔµž7£õü™zjÙ´ùÊyea pÂȲ9SS;”‡<ïö¸Ø½ï  h5c¢.!^o-¿vFÃν•_¯[1e¾¿ºÆèLëùàLlD mDtNÄBáå—Î=þÁ e‚®.Éf¶Z|•Õr(ììÝ­Ó‹R;”Xï£GÞ]–5¸wÅëïÇj1’-&˜ Ðë´]ï½yûu·×€ ³Ø@¦M£5@àVvë «ÅÙ2B1¨Å0³tÀ ÆsxÅHÛÐäF N”ú”eÎtà»Í¿Û¬¾XÄŒ²DiB÷Žº¼,ׯmÚ-;‹šÅµ°øW5A|UH”ß2ÅׯÄY«À ˜ö ˆQs’Hu~ÑÖZpɈ‹g¯¿ÿGW®¶˜ŒíÁ„+Õ‹ûlšÁk.-®Ùs ¬Ó¶èŽì©s5&4ÈðÉðÅà‹¡ABpéx‘Ø|ˆù CòCÂ׸« .±7Î(údý.Ð¥$y^}7Y¤äÀú-ë×o {%´)ÝùÚ»mfNJïÞñÅ=5‘¨^“Û·n3VRi‹ƒ­Ø÷Ÿ··ÿýß23|@ñŒ‰‰e-£>ÿ¡–/Ÿ|Îbò«ÌÞß{´¢Ý‚+ã²Ñ@Pk2ò/‹ˆ¡ˆÎ¦}o~øÉe×h5 ùc/Lj[¬uù+ªìÛ•\1€¿¢ê¿=.Î9¸ã‹V˜–@”Ö"bÊ—2Ìš’´ùºÛ@"W<í"H韨Åv´T ˆSº䯸âgnBœUªn6žC©o©'àâlx¥@§ÜþÈñ 8Ê3 .2HL¢"{Úøä=«7¾øVœ83*(FuhD±×-(v¶åŠn¥µVè€x±ªÌÔûá<â„(çà>®õ›Wt7k ¨,à6Íñ*gzîè¡Iò­\]²xNúØYa#B$x%øb÷©F ª÷åÃDB B ¢¶qn@'BÕ%'LgïÝmÅÈéÝÅì:7L- ŠÇ Ïxñªy·ÆäT¯Y¿áÞGµâÉ-œxq·ÿï–UWßôÙÌ…ªpX,™ŽöKþ”3rð¾×ß6xVL›/úø¸·ÎÏÜÛ{¤Âš‘¾ñþ˜ìÉæt{霩üã"bh#¢³¦j͆ã_®i1ñâ`mïxUéì)c‡‡\ Ášz‹3͘š `õ¢¿lýû³m¯»*ΞüÕˆi–f¶æ«¨Ê`6[‹×ñ*å@t °‹Â•¿Ùæ«å(À ØIï5'ejšhbˆ‰“”ð”-vѹŎ:åJrn6BVá¦R©B²ÜÄ€Ôþ=’F ýfät›8Zªi›p*Q ŠSÞmâPΰ¸6`iR©Ò™¯èÖT&‰è|¼2°(o7KM=­¶ve-çÏTÛVNû“=?;e̬ þB1„bëŸ!ÀRÖb°o'jãžD#@,иF:`4Þ|ÀL-AÔƒ°·>ü辞è&òœPe¤çœ5æÂ˜$½ÒaHRIq¸¶>êñj27´Ÿ^¯{>«£ ¬uÉ@ÏÜ»íŸÏsã=:IòÕ7H@ÑäQn™_ý톈˽ãÏíg)€²¹Ó™ØˆÚˆèl ¹Ü†Ä„¢KF†ê]¾c•}ºÇåeÐZÌ– €­O¾øùüÛÔ€£s»Ýÿ÷“ˆ,²ØÇÖô¿Àš“ÙñæyæÜ¤{¿²Il5óŠ#âÄ”‡8²Ó#îAÙ‰¥UZÄEêµÒ¡œy¥ovê”_ìrËg0øÅjfPtEdÀP”'[Ì®½BŸ);Cjðl9Ý$ ~ö~Ù¼ÃS]«'4U锣¢â¸‚èQµ?—²„jÅ6­8ìA+&ÀùÅÉ­&=¢š’”9iÔ†%÷g<2 P¯sùTðÊJǾŸW’9ö®Þ‡®±£Æˆ`Á0B!”ŽÅÚ¡ãäÆߨˆú 5 Ѐpá ‚áïGïzuNfëÛ¤ ìµtâCbB¯Gï ÕÔyÙþøszÑù[÷Ý&weÊlêqïM¡ú†]/½•;|À«¥}Õ’¤S.;?§Ó]×ë­–GL3§¥ÿb¤´+k³ð*[«"Ï¡£¦”$­Ùt¯Üw—†\³=9©uK‹3ƒÄÐFDtZ ¶xƒ-þÇ>{hég5ë·æ_4ðÈ»Ë\kÖ+hlñA—[j–ÛZN¿¤fïAczj»Es–wªªòČوRQ‘W4@¢8Å<*Ž1U쬢!TéKP¶Ì+#ø-@‚8„ÊÚ¶´bã6¿,+s7RÄ9ô ©sÛH«aÏ#)‚Ø{vIÜûÈ—ký¶êÕ¡£þCG•mj†œÌ’)c=þ€oÅ—¢ QÉä6›è•Å,±–ªÜ‰HãÍ4"¢…ÅEÝQß,Å*§,hsMÝY$NP^> !©ñ›Æ¬–¢9S[>÷÷  Æz ˆZêT ¡Ã0À…Žcç­Åˆù Br#æE8ŒP°qˆ[ƒ˜RrɈ#_­]ó×ÇÛ\weÑÄ‹¥htÛãÏíxü¹8娱xkƨ¡1ƒ>¡ª¶ÛÝ7T¬^ûͼ[5ÀÖ{•-ñÙ-.½nᮣj@ŠFeµºÓm ZÏŸùùµK~ø©91¡dökN&€PKŠF£àÒ s" n³=¥ûV›k÷~ÏÁ#Yzò‘ÚˆˆÎ÷𱸜L}¼eÏ¿_…ˆ mæN÷«TÖø+kÜÇ*ÌYÎ6 ®P™M)ý{膥†ª”^ KD©YߥR¦RÖR%ã”tÀ ÎÂjªf%äú÷P@9)Ë hì)Y—Œp¹ü›whc1X”¨ª 6xb@î¸á֒⃷?&Ε̦Œ‹‡d^µ~Ë¡WX’8l {ôÐ̃-…¹[z\ì“Þ¢g¢TD®”=oÜæª®•+Ôl;Z¸Ùà’¦uO¥ø—.6·)ƒB”!)ÊŽ=€DqPDLlÔS:-Ò÷ͪù—ŒÈûÇßݘÜP¹á—Q£†;†N倨Ôe¨¢ˆ„ó#@8€¨‘‚‘Æcå]b¯Ê ßõÄ‹-¯ºl䧯é⬾³lû w'*YR\~ë|KQ¾¯¢*³o÷£+W>ÿ¶¸ Gvÿûž{­©ê>ttý†GÏ.ÙÃúmyü¹v7_«ÒjŸLh©ìí[—Ü¿DIlîy$PU G¶?ûª °fg´½þê”öe¾\ü—P«×ßîäŸ1´9k–sËãÏ|¹61!Tß 1{>øgsº=®²&XW﫪IõË®™—— àÕün±Êj­è¦4‹£$q°A¨Yc¦F ’PöÀ©ÅY¥‘f¡'µowGŸîn»_(»¬”gÎÏΟ{¹©´xý¨ÚXL¯×·šwy¨¾¡âé—c@«¹Ó[]=íãV½Ó2K¶[‡¬±¦°éÁ'÷ÿãyƒÈO!@ïLër˵™#‡¼™ÑÞ&^b»²Ê]ûB>œ˜ë¡Ïtd¹0¨Vûwîy¢6 :â‡Øço–DâÀ(ev²ZͳK¨êÆ£D¡BD•1 ÃÄ%Ï¿\§ƒ.µÁ(\@M´T@ †¤¢ˆiñ"êG8€Pá¼¢·i0Š0ÆY;Ý{“s`/%±_¶jëe×(Á1l2O›9b€ÄV…®]û¾¸îŽÂqÃËfMþ û›¨›&·ni*ʯ=p¸ì¢¥³§~8z†ÆdÜùÌ|GŽë€Ä¢¼— VT]úÙŠIW«MÆPKT€Ê ÏÖ¯fÃÿ‘ãŸ/øsÛE³»Þ¹˜‡“CÑÏrxégr4Z0vx ª6P]ÓiÉŸ’ÊZˆúüÁ:—ÿh…½k{[ÿùüº·Äj©ò/QR¯®¾ª׎=’Ø[fÈtdöè\訿²:\ïVI1ŸË­ÁEjv˜Uh5oF˹ӗ]4U©ÛÉ¢Ï@²Ç\¨Ír|:x’X sË\©Òë¾™¹P2/ìoŒ³.oÕÛ$ö™åMŸ7e¬dпԢ—QŒ“ &j³xÎדçn›s“YäZ^yi ®X¿Å!ºÒõ¶_4ÐÖ½ãg³oH>|,Iì™ó‹KóEØj:ÀJ™â'Fõ*.P*|QѸªœsÚô#«ÅéÖ X>@`çÞ: ZX¼G×U»ä!‚&µ²Yu¢.D¼ˆúÂ'¡x&P‡÷Þü¾O€Z«MlݲbõZϱJCrbÍÕ7)ûó”ë/9©lîtå êl}â….·/ <òU÷ÊxdCFzþ˜ Ó÷i8|¬¸8/­Kû•W,6&&¨$¹éìùàÑŠüK¥ÓZ sË\¬©õW×î{óC@(¼íÏ[R“}»ù潤’b[Îì°›Óí¦´cJ’>ÎÊ¿¾S°![£‹iµÑÊ@% †6""pöé–TÖ"P]¬©Ëìßãûk,f«ÅlÍrªjÞ0!²÷@S‰HÙ^–5y´9Ó±ÿ¾Ç$±Ö™1¤OÛkgyŽWÆWÕkêUÁ`°º6êõÕ~ºÚäDš…•sɈVógn¸ó¡¤’bïνF{ŠÚbö¯ŒC¶’â½ÿx~û_—€˜^WxÕ”$­Yx‡d6©ü÷ûË#ï/—Å,7[çvi£‡~÷Ø3ÞüÐj1G¢Ñp(¬âZu»u~¬²zyÛMç8%wíP4}¼1ÝþÕÈé‰J©-¡`Æ稡àÒê\R³~Oe›]6 ‹å΀F£µ'ûŽWå†fgjI@&`s=üb8Ol*‰©i ••b Z%NÅ À## 4S !]Ð7@VC“  >$߀z  ¨ÃðrÈ zQIJ¢Qï§«>]-‰Å>±†›=zhÙµ3 R­ÀWQÕý¾›Ÿo‘ hUb‚s@/ÇŃ3. P¿mWË©ãüUË¿ÜÿïW•#°¢þ€Öbj9gZæEƒ5uÞYºõŸ/@4«€SÆMcv¤íü÷kß.ù«9#Ýì°í©9Ãúå‰K=S’tV ÿ›KF†YíרbU¨³9¸ÆÏIx mDD€F¯·8Ó¬¿O G–Ž»2²÷€$Z)•}i¹³§ä^6öã+óÛt9™çÏ,½âRÉáp°º.\ï U×Eýmw>¨n–Ø”-nÙ£†¶[ò'ÿ±Êœƒ>›µ(µ{Ç̽U5¾ªšCo|àÛ¶«©•Ò¡|û o$—µ,¹ò²÷=¦µ1eéS޳F€FNWùCûZós¶<ö¬ äÖó÷þ×^®,ÈyMZJÉ”q…SÇó§Ûê—­Òˆ®…¼©ã²&Œ\9åÚÈ›¤6ëK* °Šó@rÎy½ºî}þõB *ލ78ÓÂÇ*‹½˜é6W¬®*ûØ â@0ˆ¥Le“\­ø¦V@’ẪáS# Ä|ˆ¸ /‡Z —3èaX(®²AlåÜ0¸a‘¸Dó‡[,˜*¥¾ÄNmÛßxÅ‘Öôï~úåàCOe!ÀTÖ2wæDû°~¦ Gó_ƒÄ’bË/¼Ìµò+“Òla4´˜6¾Å—&´(pèÃ{_yÇìH‹Ô»ä`€½[ÏþCÛŸxñÀ»Ëì];$–µðWÕÿê»N·-PÛÑOWïzéÍö×ÏU›¿¢*XSŸTÖâ¼þkŠ_–«ÖImL6ªê:9³;IÕ8ŒšШcø¬G]CÑ)-eýڲظ¦L,Ësaö¤Qïudƒ¾ôOW”Í›¡Oˆû>f¤[2Ò¼™Õ1Zç2%'zkë•£,EùÌ*š2€57ëÃQ3œÃúu¹íº`m]Åçk¶>þœNŒ[Sr^Í–½»ÁÐê+©Ä>³˜ø¬Êã­^³^ t¾û{×ïœ ön¬É‰ÿµ—kD-wüE…—‘¢±·ÊúEskëy3 .Ÿpø“U/X‹”lvƒZÌiê-š1ÂFL‹ IDAT±hÆÄ¯»Hµ4MZj«©ãª×lÈ=V¿F­J³ûUÄ‹ÁuAñíôâ Ö ˆ[&À Ô>@”Z“(êeø Hð#…6k DƒÐHP…“ ™ vÕ¹ççF=ˆø "(5v!(‰­Aôê*92¾0·ë]×Çe9•gêÀ?ªšûð™üÿ(mÌ(Ͳ_£ŽÅÃ7‹ڈˆNåË«o:´lĨe[}B§6¡ÚúzŽR&î¶™?«ý­óOþÚýo~ðÅeóT@Ñø‹ÂÑhí›Ê@Ë™“ÚÜ8ל® >Ãú¿>ÞrÚø¼‘ƒÔlÜúõu·kE1¯é@úÖWOÛýÂæ8kÆà>ÁºzEµçxe4kZƒÐþÖù¡:׳o°•ÕmÞáújÿ«uÂ@R—vgMÎ7üÖýƒ‡Ž¦µ- …#Þšºnw.JïÕõ£áSM{ØÅP/`hQ`£‡ŽZD=Lé0HëÛ=±´xS÷Z1´Ö> gÉÕÓ<ùbüÊÕÊ1íñt²wïX»ÿîõ÷Íb…Tã°{ŽW5F¯D¨0`좦”U@¯´ȰøB8sòÁ Šh †‘â.|m¢ÁüQ„ˆ†H•C&Ü"ƒ*[îŒÉ‰é]ÚxwYÅïTªÿŸ½÷³¢°»ÇÏÔ;3·mï »Ëî²K•^± `T¤ HUØ‚=Ø’˜˜˜ÄMLLј»‚Š  ‚Ø)ÒaËí3wzûý1;ë Ä·|ïû&zϳϺwîܹSçóùœãüæÏ¡”ýeç^Úsù“åßKû‡³2 (WÛ­ç¬)õs§ _iuU猱TMúòÐkÃÎc}”Ž„{/›ßgÙ|&´4}íÅ µDêÀskù¼HÛ¶ùÒâ¾WÏ“öÖâÉW­j^8cø}«6^y“)«ã~w¿·Ú=O< ³§þ+_#E¯Vha.;j?€’wÊZ¡›bl›¦\†ÈתSÜ·U 4ÎÕ8Wã¡F‘‰"³\xóAe\#m9äC§Æöùüñ¿{¿w!@êýí)€ä9CÕê¦]pÚõWžBŸ»ìª£¯ot)jà÷¯.Üí”$P;yBÑðâÁ£Žeò"ÑoùBŠedv¹iÉM„O×lŸ&‚¡·ÿⱡ·¯Œv¯22¢Ò˶´i©Œ¸÷@òãO=ÆF…OîýEÓ’Ë›—ÎݲüvÊOJµ€†Ë/t× Ýõó ¯§†ÙS#½{n½ù‡#~z{û¶7/¹©ÐŸZСwcÿišªöùÅúÁ yýš­ö„ÑÚn¾¹åè›[:Sჽ{6\qÙçS~£X嬩eS'Åv|Ž¼â ¨ÒUåÝ.8§ýÐQ»eC-àøôÈ@ÈŸHðÌÞ:#¼b^™Ð< °Š Âå€sÀœ' Šðe´ ‚P Yè~6p3Ài`,Þ²;4ÂàÍÒŽK¤Ä'žõ‚Å_T:·ÿ¢s›W,¤¸@×ã¸óþ‡ßùÓß³˜7ä´·¯,?sÔÉG|Û¢Zž[Kû“Ý/:·÷²ù¥#y¯¾ÿƒ‚å¥-omµâIÙ³;‰'w=úWUF±ìø§~]1vÄ;+ïÌ82ìî•¶¸tðÈ› ¯o¾â²«–ðAíläE=}î_«<ÚU—mÞv%–1<Òf±4èÿò»Š/àLM žTyB Cò”¶ÄÜ)GÚrÈ!‡NýÏ®ÙÿÜ«áÚj¥=aÈ áGŽzÔ­ÿÊE©ƒG„вA7.=Ù ÇO u¯¬»ôüúË/6³òš) (€ °±/ö©ª&”7ΚR1zhçòÒ¡£æ­Ðb ²KÛ\Õ™£CuÝä¶ØÀ›®.ЀžL)­1KÕ¶ÿä7‰?%ý·Û–5ôþÛ úõzeâ,Â÷™s€ÒQC"ýšÿR3Ì£q}o¾¶yéœÆ\®*ï{? <¿Øªyƒú ¼ûƶ÷>ÞùÃ_1¾GÓ¼i\yiæ¾_V„_aT‹çìÏvšu ã÷Š…‡Ì›8nÓô+‹LË›cˆ XuéDiÑ¡‡ÿÔàÇ'dýs@ûdÑKë*l æ5É { 9 º`C`¤ÁÇïfËY.Dw—ùò[øÎH`ÿJ¤~þ‚çúKIpUñ«¬¡ÞÍKçvö5Æ?ÚI:Îú±G}·a +Ë–Ì>™±µ®ß¼éÂy¬¯V†ë-ÛÔ¥Æ*om˜vÁÚ© Y€ TYV8l€t¼­ö¢sû]»ÀG?zèèÆ­yu»ÿüŒKìñõæ3ºŸw–tøX¸[¥·ñÀáw¾÷ƒ>WÎ)ܿ㣷|P:| A’ÿ‡WJ€Õ)Î&x7ÜVÛ_’ŒC16EÛ&À†Ë=øà—ŠüŸYU] 1EÎÖRáU ”™R´ýVøå"eYîÖ”#m9äC_Cìö¦×_v¡ÒWÚâz*­ÅSZ<¡Å’¡êò?¼… °¶]1føÉï5¥l÷ Ç[²ÈÏ[wÙ•™»žG«nh_ìËoûн]Û–îúì×$O’[cJ,!·´ºåÚªsÆ(­±Ê3F|õt,Èä¿{Ó=ñwÐ4íX–×f×8ý¢Ck6{kkÃŒÉj[\i+íq¹µ=±gË wywÌÆE³´Xâ/Uƒ  jÜHÆqq¬ÅöçX‘‰ èýú¥‹Í¬’_×=Ø­òÐ[[FýìÎÂÆºÍçÍ)ð£WuŸcå©ZįX,ƒDúƒÙË"¾QJ‹Š.:7zƈWM¨ó{Ú²¾QHMÕÍ›0­( ¤` I šWmƒ˜Z˜"/¸>cpœë“JÍaH¢n1ìÇ¡8ÐÈNG°•×Ngù%V £á¾Ë” àãÕ?k{ãmçÃò­ °Uå}V,j˜1ù„ÃýtI?NV¼©¦šÍêuååÑúÚ®Ë0¡àšóæÐíq  BÁ†…3+/<'{äxaÿ^y uö<ùÜá×6:–}è¥už£oñ ~J[,ùÙžÎO<üÚ[¯^²øŒG~T}îXûžzaÏ_ŸýóÕÿ·Œ­lGI!› x›àÜœ Cr’¢mбiÆ"4X§ Ù·•è7¯ª‰eÖÄYo«¥„ªà(‘ èUH£È|ÃÛ× 7MT~”»wåH[9äðCñ ~…ýšÕXRŵxJ'õDJ‹'˺ú†o~/Eáw–ß¾çwOÒ¾²âú=[W,´¤ì‘µø²’ÌÞë¯X RÛmðªkHžÓ)¥-Þ8kJ¤¶€ü¦úVþÅcOËKØpH9ÖÚý¼³Ä£-Z"u|ãÖÓnºº¨o³ÒÓ’i5žÌ9®Äž~™öÂ=¿}Âòzö°êš}¿þ£y¬ÅöçXM€H‹_<ö”ëº Ó.è~ÞYïÞþ“7]½}å4ÀùåZpxNWµ< àÓ5 (?ût¸®¸~s¸‹ïnqÏŸ¬þYáªû*üÅd_½«óùŸì¨Öb h I#cÃ6@šè] B‡cÀÌ€úY i`4À?Ü”ìb.—@Ô`„ãh RzÇd+åºç½`™~WL7Ù0ð\{÷—ŽÿíºÿöY¾°ï5W+JH‡qùyL8øÙO~³ïŽŸ|"[5ebÏ3*Æ<ù”x¹ßÙv, ê‚ñõ ¦Wœ3@é°Þ«-[> Y¶dp¿ÏzœõG@Ôã­}Ïîdl‰íŸ¿½â޾×ÌÓÚûþúüÇ÷?\<¨ßÐÕ7Dj«ÿo¯”)Xäð+RØ• †õ(Æ&h×¥‰²!d§ ÇžRzý³õôe ±q¶ÆÙZЕ=ÒÆ™ZˆÎFbbÈÌ~c ¼',,D"ßNèoånb9Ò–C9|‡@2L°¢Ô{N»Ž£%RZ,áù>|3ö?óÊ›s–]èšã7¨Ñ,óÅþÆåE…Ò¢ÄÎ/ä¶ DëNÿÅ]‘ݹ¢BKQyß$H4Ìžºþòe¤ÀO\óg¹¥]‹'Õ¶Xß‹¸Â|…€cZÙÃÇvýá)±ÁOY°ÒÓ‡zpõ¦© ̬¢ùâ€peYíÔIrK{ÕÙ£kÎ;ûÅñÓÍCGüò÷¤Ï‚\ Ø€¼!§µ|°~÷# È1¨å‹}Ù¬Ü÷Ú…}›?™·"Ô%cž’›¶y9¯JA~ŒiçÐ'4¼ï' É'LiY„|@QÀɰIج¿7U8}`(àÊ î0²¿j¯I- $€E Íq|q3`p:ÜR Ža¦~þ[ø›*úŠ Dz5ŒÿÕ½%ÃØ÷·¼¾‘ ¼iùÓ?Hà päàÁ‹fÕN»àäãÕ¶~ó¦ ç¹@°¶[Óµókg_|r1½|äàwoºg÷C{q®t€í¹pæ€UËùg‚O¾}ýj¥¥}ÏŸŸò"|yɈŸÜVuæèÿë#z¬{¦òGÚØ€ÑQ…¤dš²HÆ!X—bm‚viÂòH[§¦\½š³´ˆ¥r–0uÎÖxG ¹YžPy¨Œf†¨l˜’¤$èÊ»™ÅÃó=y%ÁU‚ŽLè.i;ZÛP®â½ÜM,GÚrÈ!‡ï"’ä‹ ùâÂÿpÉîypßS/ðÅ…Z,aûÝi®?ãé¦rä¸zäxjgÇÙüh´G÷½}ž/+J‹øÂ|¾¤8\S¬,#(êäõ¿{ó û÷ÿ÷GÀu•Öv¡‹ß’¡¾²~ÇÏ~** Fiió6  OS¤ºüy+j¦OÎkÍ=.·'Œdºvò¹ýV.–[Úò›êßYvë–+¿).èµäò¶Íïe>Û홫5-_X7÷ÒwWÜ!¿ûÃ2õK.7(*¯¸pÈì©f[|ǼžÚÔ)(j@Äç‚={Ð!Aúl«éÙP²¯xõò§4ÀðMÝoë`oþ–ÊZû&>á‹ øò’Pu…PRÄ•…ºW«ÊøâÂ@A> ˆòYã¬)Åûú\’8±øòé—·®º·ñ’ó z5|¸úgÞgõïe¤2‚ü3Ÿ}L>Ö"m)ÌÊZ[<ÚP[sáxûŸ~ùå±3@ÉÎÜûijñÏv3€ TLWxƈçžK¥CÔν´pÔùÈñ¾·.¦¨OÐgJ„Ÿï ~:€IÓÕ—]?ä´Ïþø´«éQ€ð[õ5 Âaµ}ªW迦׮æ"4 Ðà@ Áh€ÅAÔ3‹#`»pi„o:,Àâ¾Î™R€„³N‡ÞŽC»!@³=©ÏXÿ0±{ôxâ—¿Ïø™ºŸj¯Ë6,šÙcÞ´hñuû/ã¢.?ºsñ†”íË­9¥ßuKN>aÖN]í-O¤,Ô¯Çì‹›ŸhgëF÷ñc_2‰ÊÇ s(jÿó¯z³ 'Ci‹}øÃ‡zLXqú°ÿ¹ó¼ñ8'ŠÍSEŒP¢Î¬Îj¢@)4eŒë2ÍXm³0:I[Ä瘧~Ï”²›¯¿«úìÓçÏ15ÞV9[ã,µ ÎÒ(i Ø:¥Ù!*¢²´f P‚š¼÷­‹Îx¦ëö„m‰7UÁUÜ A¦š´(Òf>oÔFîÉÝ”r¤-‡røÿ‡Ö¬V–õïõmúRu—œ¯Å“Z,¡Æ^(––LuD#$Rz2£%’Z3s>(¨²â©q¶?6à¬?ñàYÝÒ@=4 `¨"`h°ÐMÈJËá¦@a»pIt—ñaþTªí‹~2RˆD€eÈ£ú!8LŽ Ëê°YñJü‚ªW_³}µÌô‰iãÜi}o¼*TSíÚκKñlàØK¯{íq´¦[]Æl¯¸¬÷Òyù½ºîùö­¬¹ðЍ¢ò€Ã0uÓ/ª™1¹lì)ÆÛÞÞöú„YßÃ¥pè€^WÍ©?Uçܱõ›×ͼZÏʣþÒ Nyrfµ|úðŸBe‚¼†é¼À·—Š ‹Në]uöé§\IÛ{Ÿ{óè¼K,šVY>LJR4Y&ÀêaW C(…¢l0°ŠblÆ4Ô¦$Of‹º™¨“‰"3Þí}3+Uœ3æõ3/…Ÿ¦Eû¶ÀﺡÏ÷–Øû—g÷ÝùÓ ·j…ýšÃÍ þñrØv¼ÀVÏ„ó«¢ðu¸ÇØ×… T»ÈU  –‹²bŸ–‘°5¸^WZA@ÆçMŸjI€(ÀJ¿>}Èí°×B³ @ÊHYŸ±Ñ~œîdt›tf^}Mû[[·üöé“Ï(À"þ<«æÏBÚûš+ºû‘ðÄ=û_¬« ol„ä$³Á€¨‡!…]I ж]†°šbl7E´"PJˆÎF‰LÔÉDL”Èu91`êS篔¶ÒFÊaWâI•6,ÒtBD6 ëdÚa“e ÞQÅHÄãíÜÙ!Ml%`ë®H8ÒM4eAﮪ730ŸÜ×ù]’ŸîÊŠ¹¢‚o¸xåc­o-]E±ì¿ùaî¾#m9äð]Äo‚õEºÿ¶>Kf¿>˜®©àX–žLoàÑCk6¾ÙlgÉ'¯±NËHJ[Ì+ †kª‹ú4íæ¾¸/.Øõ‡¿{s 4/šÙ•±‰û¿6ù éËC$P?sÊ{¾ÿ E®m·ý¸uóûÓ>ÝÀyùx»Ú÷ªºFFl˜5ÕÛHJK›™Už3ÕŽ%:[ÐæO/›pÆÚ±»@  OK¦;YfÝÌ)½®]àÍKÛ_|Ý+zzÆîS&6Ì›öÁ²[9Ÿ±É€S\ í‡=o”€OXã>éÒ€B t£ Øp]ôà€ \àa6š¼Nþj¸ ØhofµÈOoàfAÌTß DJÀŸsòDð"D îÏ- p~¶G×/­aÍyÍ/¹AèR<5|ÿº0¿ß•sz_=—FôTfß_ž Xš¦>\v«—»ªá^ÝgM©™9…+ùZž¦™•™PpÛ²[üþ)Г ê/¿¤iጢAýN>Žßó‹ïý€ò1Ãû^»àŸqôý/¼¶åÚÛh |ôA§Ò¶|ÿžÃ/¿A#ï[ª(Í:ê^å½tüímÛñ{>?2ÿñ‡/þ.„lQ<!E‘Ž8¦¤)¦Øü@F åQв†4†mBvZh…#´0/E‘‰Ú™!^Oü$b‰¬iL]pÞUyKeMÃëi RrÈÍ ¤B6eØ!'Ëé): a2¬ÉÙZÀÖÅÙõí ¼«Œ–-Æ49SsDÒI'MÒ° ©Ž bFDvx}àÝ}6Ì[È ¥E¡ªr¾¤¨jüØ“÷Æ{«îÛþ‹ÇÊFmž55µãs¡¼Œ¯(a#áÜ=Aù µŸyeðÝ7u2¶Ý~擟=j‹Ù––¶Èï~DÑvr”ÌŒ"Ð aºR QYŽÕE óRO©mÛ EâD›’mQJá¡þ©pM€"@ &eЧ´ nic,ÓSÚBn¶ƒ´™6i:!;K‰6‘qiÇb¦£ƒ4Ü …’ýQ7­’˘&$ ' êŽHÒ–åY+# ¤¼„xiýá,tà0°ô7€ÖY  ñ_n‰ÖŽE¿+4m  jûîúÕ„ªr¾º"X]Ñ÷š+þooÁàW–²¼/GÚrÈ!‡ÿ¤÷ìoœ1Å’•ÊS™ŽzØù«?ìæ^eMó.íLúVâè†w(.ÐpÙ…z*ãI\J[\n¾uy÷Ig*­1-–P)-‘нÿÉî?ýƒ´d:R×-TUÞgÙüÞ]ž‡^Y¿nÚÚ7cs€/׬gò£|iq°¤H(.äËK*Æï>é¬ã·ò¢ž[ûÑýSAa÷ÏËŠû\9§ðœ1ÛúH¤®{í”ÉÁñïŽãÕÕ IDAT¾1ójo€ ßµ äxR‹%ôdZiOÜ÷êy|YI‰¬èÉ´x¬¥ÊuO[¹xç/û`Õ}^¶•ç…F£†ÀKMcHŸÉ…êÆ>øƒôî/·¯¼³Ø·Û0<µ  €@ûj\Èÿc…„ Úé ÀC×P°¡T:‚ ¬$46¶H{8¸5 ºÉ.ÉW©Ž¤yBF÷ Øt’ÑDÚíxÑ3ø`ÑŸŸÈ÷§<·aÁ0u<ÏñÑÐß>±óÚÛ¼ÞÈ7E ”ŒÛ{0TVÜ|õ¼š.ýd-›¶1AáÀókw>ðh`ý9 ¡¡¶×œK¯˜ÈÏ;ùüyaè¤ôg{<×tõ¼ž‹f«ÊO^fÏ_ŸoÛòAÛšõÙÖ˜t¿pü€›®.ìÛtÂb_>óÊÇ?xÀû\[7ú,_Ô)é{k«ë8E½=÷* „‰rì°)åiV‚´L«V˜”¬`uo !ìJ mR”m2 •¶IÑa4Ócxkš'å»)а(¦ÊŠ¢²^[²à*œ¥HÚ…4ÒpBÈ:"IŠcš4k! §´NÓ\•pe‚1LÄ8è”uBv‘òÝ•E¸ ƒ°¢qñj€‡Û"ëŸ 2A^õ¤$–|D¢K$å'§Ê©ÖöÖwÔ\rþ ÛWžòBÖÓ™ovUÌѵiË!‡3ä5Ö}ëñퟯ›yu¨ªÜ’äÖ½BÝ*Ç,šÕ•±}ö›?q…ù|I‘P^Ê—}ƒP÷o„ª3G9†©§Òj,©¶Ç•¶˜K4̘ìùÀ±ÑzöðþÝ?ßõ§@éð½ÍRZc5Ž×uë\ÏÚ) Ž¿¾‘îÒçñ$#•±Ré‹}D pÆ£?ÎkìñÒ™Ó¸HèèºM^Ïœ#+¬À ¼q©cšOÖì{í“[zÏþ­7¬¦CA¡¾fØ]7rÅjkÌc™Ží4/œÁ„‚Þ’Žee¶Djª<ÿê«îó|.\ÿfM±­²Ñ°åËQàÕ“ÏݺòÎÀî/#Û½Šo¬kÛ³_>tÔ¢ç«q^Ž{ÀQq¶ ¬š«ÂRA °5ð&l.‰T…Ò@ÈÂ-„›‘òÇ2?Žr:ˆví ÛÐþ:di ¨ÒQX|_*ë4 ö’R9€÷KÛ¦ªáÐ1¯EÏñH¹ªòúùÓ5M?ºï`¿ë–9­s?7ô¼€ãÈ»ör@¾/4@Ó¢™=.¿ä”õÐn¿ÿÓŸ>Bµ“'4]=¯däàSž`/MšÜø®gŒœß¿WóUsz^~ÉÉ‹µ½óþæ9Ë=Ó‹$û^eÕ„3:_­Ú—wZXªÖºù½Ú)-Múƒë;?Ô1M¥5ª®øÚw¡éHMõ®ß>¹uÅíðS:ÓÊ÷¯=T‹'³-m‡×o¶ZÓ÷Üÿ°X@ÉØá5³.>²õqÝ&/$žî,>Ò´aYÅ@ €¸ Õ… ÀEA’ JÅ y.,"$‡ ‚†[BX¸q£8`ø ¨*øÙ¾9› WCA3„¢*$dm$ŒÏÛjýò¨@õ÷yØ7¶ý'“íÏÉZ@^S}ßÛVÑÈæ)ó+Æ:öÆÛ™Ï÷ ó?õbê½½I[°è.t pØ€~Ëv»èÜ“O˜Ö7·¼qþ(Ü¿þŠËêçMûg§Ö«ãgHï¼OlYqßE³z]y9{*5èå±S3ìðö¶CÓý¯[Ò´`F×¶?ðè½,à™EÆ2h×!HÛÉ£ÒQ2Ãf £³”áÅ«2zؼéQ—&hÊ"D—mJ´9WÛ2jd¾› Bæ\ €«´bÙ B6HÈKBС´1¦É;¤³5ʰIÓ¡e‹"ã2YÓuáf@ÿˆuocyŒÍ£nznŽÅ€fB7`Øh¾ ÐàŠpÅŽÇckªÕ² cštÖrSD‡ï‹× Ç„¼uî³ëÒ“ÎúèG¿ê>ñÌŠ1Ã…Özè_ñ~¤!ü¼¾1Ä <ºÏ³ÇÞ|‡/Ì×T·n~oã‚놪+‚uÁÊr¡¼¤aúE^<ÝwD`Ë‘¶røö`ÝœåÅzýÕ=ô´¨´¶wÍÙ<¾ñÝ7\g©WRØöñ§ƒ'Œ+1xÍEWÀu…òÒ7\õoÍØNÀÉŒ-ùùž`Eiå燻W è㑼® dkš5uÍ”ngRàkÎ?Gŕ֘ÚW©`QÁ¶wtÞ1=í§aöÅn¾öÈú·ÿ\3Œ úôŒô©ÒãK‹‚•eÁªr¾¤8¯±6­2AKf¢_w#æÆ@Üø¥s¦ë­í},:­w RÛ™c­M3&÷[:WO¤bºó/ÏxÄÑ˃·²³Oo¸áªÖ·¶ýÃß"~—˜ ðÕUãǶmÿœù`{Ô*PÕC ä"e°‘ï€5`˜‘0×EŠ€œE¿Ð;Ò¡ÁÕ;Ò\D¡Ëà§).Aa!mAÓaèÐìjç•@ Y Ú·ÿPý¼„ßRÎöIª˜€8@(?Z=í‚/ÿñÊçÖ@ëë½à,Öß T ¿oS¤_¯ÖÝû*û4 »wÕ m…;~üë@4òÑõ«mÇá‹ Ï®Ÿ’£2€Ô®½„ã¼6ô<Ëôœ?½aáÌü憓—Üù“ß|rÇOþäDõÄ3û®XXþõ †/Ÿ~ùÇ«FD\Q ªa²®MPŽ¥3Q"¬hDBb˜”8V Ä}ÒæJE“p\‘ðH›@*‚¬ä‡R‚« p ™µÊQÈ0-I™3µ ! P–ÎZcu!m–F®£‚È€]Bt©´í âøª1 $|Ƈ&AÉ‘`+ÈÚP èlÐàf;H‘EÛelÖ E‡2mÊ´‘‘v‰”ÛÁØ’ÁµDÁ3L!ÿÆßã¸ïû,úŸÛù»á¬zá8òZ°vÜX÷õÞÉ#›–´ÿpfÿá¼}ÎüýÿIÆöm¢k9Ò–CßÛ¸uàõWú…@^¤k§|z÷—›®^U4¨_㬩Ùc-5Œßÿì+/œy)WTà:ÎÀï_­¯ùvÿ(á4Ÿ·~Áu”ÀÑ‘°!J=.žÔïšùJ{LmiÉôÑ7ßQ7mÓâI†eBÕj[\Ëʑƺþ×_Ù0kêá×ÞzgÙ­žmêÓÝ)ìv¶0?XUΗ•ŒüáÍ^›N ?ï” U'àóß=ùé/O:ŽG¹ßrma¯Fµ-.¶´ Чö¢s>päÝ<à¡1þx@´OSd@Ÿ7ÏIù¨ wÏÔ¡£%§íwý•;~ü°òÁöO’t tZoÖqÛv|ždH€zZú½O8@²¡)Z6 ÂA–D8j8 ¸&®„ÀßäCíÐ] £Ð†F#² N DDj $ a!cw˜z€—îà½Õsð…ÏØ¼ÉÓ`¤2;Wÿ̳"ñ¢ H_ µý™Óº“çOßù»'Ùü¼h]÷£¯½%”s%E\A~ü£o\¼ˆõ•Ôî“'4-[2jÈɇÀÌÊo^±ÒÝw0µg¿T^pNãâYå§J&UÛb¯ÁûÑaBšA×ÌëuR¸Ö³¯yæéé!;K¸n–y¨šÉÁ†-QÑâL‘6h6 êá€!E†2¢NNØBÈ4k$hNÔ:H£„ )ßM ®Â¦)3´bÙ2!=¦%ÎòI›©3¦É˜¦à*!d̤ëúš›69ÑA äŸý)_ñ+¹«ƒ´Åa¤¡IP%XYè$²ÛÁ¸Å@;\ ®ˆøú2J·šH2mBs‘Ò@vdD5V&…üÏñkµu[êXÞ#ޤ" ÆÆcàº1thv@\î£î¿í›EN¦k߯–#m9äðoʱ#þÙK†(m¹á®^‹fõ[¾Ð%=™~þŒKgOºú†ìÑ–Æ™S޼þ–!J¡Êò‚“ºª¿;Øÿâku«Å“j,Q<°o³_زdeóu«oÚFÕΨ7Jm‹gŽçK û­X$T”&vìÚ¼øFÚ÷„s}N %RÅCN¶úúÿÌ£¥^|ݵíÆ“³-íÒñÖ7,-z\Wi‹1AÁSCcíl{ïãÆ“m)»ÿ¯ÏS~g[æÓ/¤O¿ðŒy-`Ø×eÛâæ'Ÿö¹eùÛs®BAÂï³€î—]Ô÷³ï©d àå>MGU•[~’µAz“‚zÉàŠ ‹Ð(˜¸rPIÀm:\Äy@Æï˜Ë•:Êaš…È,@T¸i¸)¸) ÐL@x?~Ô 8µýéÏSסpýÿü±Êàú¿{&põÓ/êyÕœïûÕ¡µH ³ý3¡¤ˆ/Èç ó=·¶£r •e}V.jºêD¶C/¿AñÜžß>qü¥užr™×¿WâYõW\vʃµ~Ú’Ø+ë=‹¦›Ïê³tnøëÚÏ®ÇþzàÚÛÞp~5DË¡I× ÑYʱÄ %-DK2Q2#SÁ@Fä‰aR‰@FzØZ¡)+ÓÜ5¨_Ÿ§>¥D{ÿ’ºHFÌwSÚµRñ|F3…$u'¬KWäl-Y ”€¥3–ÉX¦à* ͸l¾?æ‘6K†“›¶™G»ø²tÖ(“_‘6]ï m†„¬ Éœw9@„¸¥  ë´fQ†íˆ¤“")Ó†„NÒ¦+ “ ’°²pe„¶Èí¾¢–ò"e8 G‚“‘DÈT§C½•;þ-·0ð­+JG ú l9Ò–CßBdçŠ h¾Ã²¿mÛÇ£\íÕÒ»¿|qüŒÑ®nšs©­ŸÜÿðKg_Æ—u?ïìnÆ}—wZô ÔXR%¨Ûµ¬¼ã¡ÇÓ{Dëkz-šÕ{ñlµ-&·´•©ZÅØ”–öM‹oÐãÉ®1@.ßÜ0àæe=¦Nú¯nFí…ãõdZnm—µVŸ3¦ã¯Ñ5ÎR‚«„#%ÂèŽBÒºÒ³aBⵃ´™¤ LÐe \&߈sEŸ´¥ü™ïØ"ù¤Í+P&:ZÐ †= ]BÆìÐA]ø3¤2”BŒeRºMk);ž¯¥ÙHq G„¡))D^²_¯ÃzÎËi G…%HÃÌvüb¨,¨²n»3£á²3G÷Z:§läï,]Ë‘¶røö öñ§ŸÿöI® ª®–—ôîéѽóÙŸÚµwÝœåW-kšséÑu›^›<ß{˜u›8®ÿ©²·¿S &XQ¬øZoÓÑ7߉ÔT×_<±âŒ‘^5X]ô[ÐËÚ|Í-É_tjl½—Ì–ŽµÖ{Àªeÿí- ä ò¾¡žÈ‹°áà«çÏeƒã:D@Ô9hžÒ¦$*aóÕ•‰€©‡u)B‰¼£zåQʰl ¦¦ºÈe „Œé¦GDÅ-€ ÄýBÉ'RµÑ€¡Á0 «õ'> ˜;H$w²ºA+–÷Cˆ®+ŽH¢Û!Ô¥`faêpÒ(}Hø$ù1™¯H›­ÁÊ‚HÃP`( ÒÈZ-(2€SU^9vDÑÙ§×L»à?O×¾­Œ-GÚrÈá_Ÿ?öW.?/XYZ:là7/¹aÑ {Ÿ|Žy¡¼däOntéyÿâOo\ºª÷’Ë{/œùüð ’;wy­u—^0ä®sûù”¨7ʱl’¦Nùê»7Ý£´ÇC5Õr[,Z_3ì®I–aá¢}ÿ§7lÿÓ/×N>WO¤ÕxRim—Û}—/¨9ÿl¹µ=X^*<ªÆ=gO –—r¥E/Ÿno£ €ö5ëãkÖ ìÛ0zbÇ®¶ƒGÔΞZ9ç’MѦ¨Ÿ j=)HL26¡ZŠAk L²0]dXä¥a&& *7 7 ¦ è~‡šâ a„$ÊSÐض‚ϼº'ëO‰hðKg PP]LO<ŠæôzäÉ/…_˜¶Ò1å㭩}- þ² {\rþ–ïn^<;î꾸P>Ö²ñªU @ù}Þ’ìwí‚ÞËœ¬°ïÉçýã•Ìkoy¦¾ à†C½Ïj¼bz¸¶ºë’‡ÖlØéâÛÝ#°7μØúë¬eP–Chn˜•ƒ´L.†6¤¼@:&‡M)lJS4D6 êñ«Št*P·* HzˆËFxQ9NÒ"1b‰AJ6â,—Ñx^…ÞQCl6ˆ¼« Ù”¡ga‹p²Ý£Èe ,•°UÞŠËݾïÓ5Å/ŒJp$x•S;2"K„b@6 [USX4HàÈÖjV3ظAé6‘u Å%di—JÛ_UWS°X:ÊŸ’þ qÖŸ'Íøª^¶Gƒ¥ÀÍÀP¡«0H2‚#•÷j é_>é,Ö°ûÎ l9Ò–CÿºØñÐã;ü_XÐ}Ò¸º©¿aÉÏùó;ßû0žQA¸îª’A Ç´ž3%±cWýÔ‰|^ä•ñ3 ú4%wî²n“ÎõÀ…ÔN¡ÀýÆvx͆âAýÂÝ«•ö˜k;CﺡÓÝãu—œ¯%’Z{Bi‹ééLÍä Þ§ËK„kªÂ5U®ãl¼ò¦}O<çm–g´ëe„š¾·„à]s t›2±yÙüW£Mù¾Ï-T˜®—YÑBßEy޵ Âv ËØ"—ÕHÓ±,z[ã0Ô!|L æËQ˜âÞ¡ ƒ³Hb8ÑÙŒ.vÔõË"Üq-Df£È@'iaBŠ"O©©D>/©¼¥’Š$äp@ ›cé† S†%Ö@Ða—-rÙ;)[*×m¹ÜÁØ|ÒfË0dxeSW„¦‚Af!ÙmHv‡"&K†àË·{ЪÅÄMRs(Ý&T—\Bq;¢Ì¼&6tT nÁ5Ê@ÂoIËøÿMù)I G†£ÁRaK0TjÇ@‚YZ\9yBáùgkªst-GÚrÈá_Z`ÛzãÝÐ}â¸Á·­ü†%×Ï[qøé—9_~pºrä ¶[Å/„»W‰Žxéu×´(àгk#+þÕ=¯]8Ï*G©7ªeë5çÛáÿUt›t¦mj{\i•|½AêMy¦tùÿ|vdýÜåF2S< K(m1Ç´¼©R‡eÊ.:÷‹¿½Àp\å„3BÕ•}¯ÿjͰ(€ ÙíhTóž¶€h€C" Â"@*Ù-A¡xª‘ž€0€—½å36W†›RPTˆæWn oNÖ/i~ ÔËfuNÔ8Q sRØ €NXœ¤q–F+VˆÉ†ô,MèF–S†)ÖÀy¤-?È<¼_clrG-ÒôI›-AÑ, )¢ Ñíhx;CoÚ«ØL¤U‹RlRqHÝ!—ÜÅÎ2Ó-Ø)PIž’¾˜'ûõP©c†ÔËKð~ŽGƒ¡¨­Fa~ìýíi ôô¡Ñ ãrŒ-GÚrÈá__Z·yùíÐ}ÒYCnÿÞ7,ùβ[=ý2íçQ’Lëè+ëm€/-2$¹×Ò¹Mó.{ïÆ»«ÏÓïú+³‡¿rÖ4Ï36±ç÷ÑΞs.Éíðÿ(– UU„ª*þ·­íݧOÖÓµ-.9~dÃfißA¯ Œ°í/ÿûˆ{¿Ï,«µÇÖö=KdßO!è7œyæ t’Ô Ç%@Øè(:Š. Ò—òž@P`@ lcSàfáˆ@ 2qaèýTQ  HûwÏ‘Ä&ð(£äûu[à|ºæ 3ê^U<ä´7§.t}+ø–H_~öÔ8 ÈЧ`p¿}{É¥ü¾Í£~þƒcë6yþU>Ú±ê¾äG;á[Š8–MxÄ1T³²Wií»l~á€>¿üF@àø²’7‡LŠ lHtÀ…„#@±A‘®”M…c(‚£ÀÆÒ²_/ÀcH²0t%2ž®a±ŽFæÒˆv†ru"¨Ë0tè´8I Hz$O ’šàé¸ÅK*oªŒa†9)¬KŠ + S†©t6² ì2…Ìþ;¸Z¶ƒ´Ù*t ¦ CåÍüf`ÈuØY¨&R.2$`„Ñ›V-*iQŠM+¥Ú”lSŠMê!»A(n‡ËZ–ÓBä1@ñ³/:Ä.‰g)tõo3-(d&:{˜[[N¦•Ö˜IÓµWLÿf7¢èZ0Xßù—\y4‡røß@죛WÜ×í6áŒ!w¬äþyÇS{}£÷|"ü˸Ó–ṑ®–¶~ö«ßüùêš©_tyæÓ/(¿¨TܧçÀ—v&ÉäðmBéðL)+:ºõ¦{3ûº@õ„qùuzZ~ߪ@^Ä1̵ã§gwíu}]ÌcóŠ_‚T}VT3n¤œÊXÇZ¥x.\`ɆëB·`Iˆ0]pH[¨È\ ›¥ƒVá*€ÒÑñ¦¨P\È€ä€zš?š " %¾ý¯¾é® D ý8/ïLöÚÔCG>õé—J-ÿº¨ºp¼*f[ßÚBMËæ×ΘüÖ¬k,Q*éÛ\5zÈú³¦y‹Ym± @ûWåï„ÒÑC…n•»ÿöâ;¿×ÿ{K¼wã݇ÿö"0ñ$Îw* ›C› m P8hŽKpá"@èÞ_t#ð<79ŠL>RV*•Ÿ/¤‚y¨©d>ãšÑh†rm6cPºþUÉ IDATÒ³´eYÍfHÏÚ:ô "‡MÉ-:nQ ›5ÎÔ¶"²jº[ê m†[BÍÌ/°ï‹Ææ“6Cƒ®A×`ea(°³€W„ªBÑad‘r‘v!ã¤&"iuåj´jQ²MÊ¥Û¤ät6¿âI?‰BÅ'àÙ¯H›#Áሰ|?6Cé8+L’‹@sCàìÓÚjmÛ'!š}ÃU]ç¸ÿ3êZW¢öí–ßr¤-‡þ% ¶Åß^ºŠø±¿ùá)à =ìûëó›^ߪÊ+i~S60y‘’ýÞš¾<7ìG·È-íOvÒ)ÈÙ@A¿^ÃWßð_²ËáßL8ôÁÝjÉT ¬dØ×Už1Biûª˜»ó§”dô¨Ñ’é–×7–Œ,}º[%Ç÷æõN°Æq#¹QCœ¶¸YÑÚ¶f½ f‘u@º0m&T@!u²0 ÈÌŽ—i ’àÊp³PÍŽ E €|?<Þ3òÐ2¿Hê©}Eh@a€òlß „ò{÷,;|ïc…O¹(üìw˜UåÕöï]O?Ó+ ÃCª¨ ì l Á¢b‰½%F£±¤ÙƱbWTTUš´)§íÞž½Ÿï}ö8¶Ä÷ýŒÉ›œûš‹k®™} gNùí{­u/”ômè3ûT6YsÞrhZ8;Ú­ú…1ÇÂzøtÃöO7DÎÎyê'O’vím]ó /˜ÙkʯÌX8`Ö)ή}ïpöžç_õƒHü[§Á}x‡Ü›TdÞ%aÞŒBaƒ‚ÕÕpqBŠBgá ¶Ã…Ý(ôçpäÜÃÂS3ñ¢J)!(<ˆ’IÄ"Z1r–e›sݨ¡3&% ÏX”•è 'SØHØŠ•F(Møa/BŒcp°T Ç€§äý3[ÇÀù@GÞøô¡j° ˜LŽ‘‡6ª`íúSbž–à””2¨å ŒC…"í²ºÇë„Ó]NsyðaUÕ<Öô…2e4Šp ¹¯8PžOQáÉ 2l4ä [ &`Bó QÈjôõ†5›ÅÉê²Ò!£‡ýpƒí;ùN€+„ëTPA?šv¿òöÊ“ç6ŸwÖ%sÿŽöÖ¹oúE€Dtz @sòö'žsd¯îï_s«Óžæ»ÌÖE»×޹ùR›Ów*ý鯲ÿâ ÝÿœgÔËoõ½áÌ“Þ=ûBÛ²ý×E(Üà%ç~å-¹ [üÓ•­·ÝKƒLÎÁ…®£ ‰Þ=›fNƒ l¼ð|þ¬duÅóŸZï~€x ê''‹¶¬€Þ¶‚çD¡û.C)jfùâD.ƒ:Ì’3“Ã0cÐ^ÄáÇIOG =n©¥BÆÈE„¬‡·UÈ%;"4å…=ÛU8Ž—ö8ƒ l'jh²>Eø4á,7BÌDHQ,® *ÃÑ`xn@ljÞ·$:,#€6 DQñî³âT[jœQ‹¹\j–g±^Ž…F¡¬æù}l¾ÓÆé.«z¬â±¦Œßõv€kA·UàÉpU¸Jž#}h³ x¨™À2@Mä($ ¦±Þéß':fDôï>¥ÿwþYÁi+¨ ‚~d½tʹð¼)o?Uüýî}(VW*/³s2TL-Kùl„È»AY§¨_ïpM¥žÎ†#®8éää|å4$6LžÔþþ:eÇ®Hyi÷¯gêî|áµMüõ€[~^ø‹ü¨î,I%¿ý«pyi¸¼4·ýËï~`ÜŸ~å©ú†'ŸG¥á·õ›7½×Œ“Šš›<ÓZsäáDLP4¶´XËäÀÀ£ð°  BçÁÖ!ZpÂð,8@A)ØL;Ÿîáw7UP„ëšþ"‡3Ô`Gª”©[SI0—PwÂQUcF¼2æXßñ* N`È;ÞŸ6Ï Š¤np>Ãg/$ø×g¸Òþ}†\|žP”|ñ¸³”TWìúõïy 8¨ÃÒ`¦Õß»ÅÌW :l…q©à:b$x…£®ßЖ’1[MŠŠc A à ÁŠÀH@²NÜTã¦ZÏ’ ÏgH,¢±W”ìdŪ­ƒR¬XHË)!ÞvÃ:ál×ÌÀs€ʧIˆZab˜5( šŸ'pt :hË'û e™°MXL¦ ÓQñɇÓcºgÕ(Õ“¼\’P¨Í˜íaF¡þ—jœárjmŠÇ(”1($°÷yлlÚWîš'çûê\5m® KÏpeÝ„åA¢À 8æ°Ìù¸†ÿšƒ´Tпäí_¾2cQó‚³z{8ÿþÁ½O¾óš?¼î7þøÈð‹Î0ë;V¼©*¯ÙRøý+ѳnÔ•‹å­;ÌŽtýäIDÓ6ÿùq½µ½éÌ“œ}zÙþa¹O7ö˜|ø³w;îðª£Y5giçÀP Ãñ :€_²'`\® 3ŸÆ…$P¬o ºÓh“ë—J­ÀxógH+Ã¥$ØsåCX(ˆm£@éÚ¾v´§@ì`RA·œ$èÀÏÇáðçrì=­ûö´ÆËJˆ$³Ä”•ÔLž”ljüléÕêŸä‚ «Ô€ a+žÍ²Ô“¥X”  ^{¶$bhCKˆJ2,û¸æs[ wÏa݆mýHÈ:|†ÄL-n¨¬å‰šÕuJ=^s8Q%ŽK©äq.ˆMYb±`xísv8bvp¨ž‹r¿öìÂÉBÈ] A'øÕËc†VϽ÷ÖI ("ŠÁh”U½«ÅE5æiI^N™¤y¶ÝcÚ)o¨`3\ Õ<ã¶HØ1y“ðYÂ4ÿwÒ¾Â5ªÀíÒÇfëùÚ¨£åÑÍ2`ëP¸uµåÃWuHíq‡ñ±ï(Ší©Hey× ÐVPA?!“)ª¿ä»«Öÿþa±(ÙxÂQ„xÌ–äß'úDª+cµU‘n55ãF5ŸûÍUÖ~üÊ´yê¾vŸØ†\pö—Ϭ,ª®ì1å½=%ïÞ×pÒ1½O™¬·¥†°Lç»ÞG7Ü>êÚe}O;Àú»Xwãoô8úP­#½åѧ#e¥ý¦Ÿ¸rÆÂpYÉñ¯ÿ5Ö­ZÙ±û˦Qt!¼í?\¾Ÿšì]Ÿì]ï¨ÚËgœOþûÓëëIÎÅÍM¯œ¹¨xÿáÃyÅK“Nµƒ"#‚:c  Î0|´á¹°ƒÌ޲ÎÐ €ÄvxïeuÉqƒ6ø•£Ñžu–¤ð9É_rª«©:úˆ¢öëß#p—„à¶H0F ׊Üd‚y =O;žø½úKQïžÃ·îŒýþahúê°¦Ï~%— îXÜV=›åY¢gÅh\+‚ÄQ—¡4•MD =bè­šZŒœÛç6ѵEÛ=;ì™ Sáuâ—JyÙ¡„ 6‰Yš­QÎ Cb®••üBxBxBL1 ¯ ÅЩ[}^л&Ãåà8ï†ÛãPo8î"¸î¥Kx“Ä M´ì’x6%U7¢ŒLYÝc5/*èqªÆ¨–)nš2”i§|šp¦Ë¨”U=ÎpÛ®© +d[aÉäl—1éWĦwqׂ/WÍ×F=_µ5¸*,¶'D†5'šû£O¯šcöèöígæÆûOºá°;þÜõ‡~¢Gà ÐVPAÿ¥Ö}¾å‘§#%E‘ÊòX÷ÚDÏ:1O}ºñ­…—š{†ohÉ;v½vÖÏRï¯`ìm³4cØÔ£¾Ml¯œ4wç³/S bø`u_»ÖÚöÙ>è×Wõêafrêî}CF)>@¼g]× f7~qÐ7„JŠìxfå¾·WWŽat¤w¿õžgÙÕ£‡MüÓ­;ž}¹ÿŒýý¤éO7¾½øÊþgÜ÷”É…¿à•Þ»ì¦ÒAMÿ|›˜üæ9ÆÇ·ÜÝãðñ}N™üΜ¥E½äõ[< ѽÖhO»–, Ç€qÁzð·úÍ÷ø ‰RK<Á%¬áZr˜³<\—J§Ž×raqèq`­f8´ÙÅ6l—Üò«"WJpÊíOŸw®ŽÀXn\+ÚvÄ3Š<)ÉÊËpcˆ·’µr”ÑcÐÎùà®8£&XETMSeÅvm÷¸´Ë™î–e}B¶"VX2Ebó6ámÂÚkx>´yúWÅЮN›mþ««æó{mƒ jŠ57ÅÇŽH0:ÔeÉ^§¤/¶¿2sñño>ñ= N[Aô£iå©ów>ý" Dk«cÝk£Uå¡’"y÷>ϣfÌën¹ëƒËnö[jô;wFËÒy[[±õ/ÏDk«¢Õ•ÑêŠíyæ—z@YËÀA gk{ÛÔ}mz[Çþ×]œ_mN)æûîFm°fGÙ¾+R^ÚpÂÑf*«µµ›m©pyéˆËèRŽ´²s÷Ñûþ‚ÿUj{]Óô+¾kš˜fÓ™'…J‹;Þ]S?õ¨Õ^®ïÞ÷”ÉFk»Ù‘ö4ƒ³mWVŽ´ÚÚÞu X‡ X HÎêj­f^ÀRC˜Éï<c‘¾çÕ툃׌?!îï³دòðñŸŸs! .Âá`ŒÚ7ØüIØÊàzHjnp»%ݪGnÞV³è ŽƒX„æ ÒòDÜ£}Äö#¿°Z;&•Á°i÷€mFÄ3<›u4.¤˜QC‹èF,¤¥³EÚØr1gƒcؤ'ÀáADÇf5U=Áp|h‹&t´Q!ãÔ¡)ʹëºD•=Îö8†BiÎã4§x‘Õþk}ÎÚóiÚÓæ>¡FÄ3’¼|åYÙ6b†–•"NºWúöÞïKf-Ùñ‹«%ù2þêQžYÌåüPß#NBž÷ÙVŽñʶ{l»·þü!Ç I–hÛ"±Ebóá-Â;„5=Öð“º*ˆ¿JAþ¦Íæªpe8F>ã×ÑÁ5ÔÜ?<¬9qàh滶ý·üÆÑ×.;cÍ'güwä ­ ‚þõÚpσ«]ÁçúêÞV}o+’õC/^Ð8í8ÿ°/{fõe7G(2 åšeÊÞÖG¯«‰ÖVEª+£eÛ~²ç1‡ÕypÙC/]è9DÛÛj´§+G~µ4iË£+éß§%zu÷×ZÛ’bt¤<›” èóc"e…’觪F}oó" û«i+öþÊŒE‘Æún¹ÂØ×n´uUcüIIQöìcwíÍîÞç)jHà‰C¬¬Ä¸Æ0çvÉ!€PZ¢e²4hSs-(hÆN"@`ƹÓ[o¼Cºñ¡³Rùù¦Üç›ÜÅHpsDèïrˆøe¿í”îi-l*…Eš_s¯ ¶Ñë@¸±¾üô©DFüé!š€é"rÌöpTÓãœêVÊÅ£†5´ˆa‹¹l6.3„l” {Ñá\*8ÍeT*hNØ3#ŒÕõÌÔ2Q³C7›†ÃE/²•Òk˜nËd(€é:TkBÒ¨<%20§-0éÊQOPCà;ß>zILÑ’¬|mhy$?|$íÁúÓ8¸Ôaâ–"VŒÑJBÙÕ¢Ð#Œ‘„¼bÐÑVëøx=yíš±#ÇÞ~-‰ð‘pÕ˜XOô¬KÐ+^^}Å/¸õÊHl]%%Ä¢DáUÐÿTï_þ‹ò–C.˜ VßRJ$ÅÉI®¦ë­âî}áŽt™¢ ®Uµ³²#+N6gg%³=mËŠ?wé»+þK£tÈÀPEiëËo1f9 çgyèsæçnd~y—ðšÁEü«â‹’¦$3]ª¢~5³oÀ[þØi$°ÍJ€ž€ð€oÚ)€N!RD ÈJ`õù–›—ˆûb‡pýÍœ—´_da·‹Qè‰B]Fˆ¢†5ôˆnŒ³»CD5ÚY\%ð<ˆ§³Te8ÍeÊ©nØ3£‚ÕuAtB¶%ÎvB‚4ÐØùí€x(ò}5pàPR> eѯoæô¢°¡F„‚ëüþ‰E1Yc úËŠÅ>±E`ð q¨Ž#äí=ÇLðJ ÍF¡G= 3 9uíÑcƒ Y‡Ó]ÁrDÇî´ÙDÇÎC›åRƒú æý˜7&ÈðdxÁ,Qó}l¨©µô››Ä}CƒD†5çS‹èF¬¶jÆÇë ¸V€¶‚ ú‰ôÆÙ~ñà¡pxðsô¶”ÞžÒZ;´Öö¢¾ Ã/YÐmÂØ¯ŽœwÑÞû¯<¿hóÖÔÎÝÐýðñ§NY÷Ëß9™\Q¿Þƒ—ͯ›8îûnnÛS/¾:ó‚Cþ|[íû|[Vö¾¹ºfìˆï¹-èG8!ÙÛÖ0eR×4f†a„â¤Pœïß§X’Eótƒ¤³v6GÍÎJN6g¶§ÌT†HŠ“íLNÞÓêBÒæ¦ú³Oûì]RÐP_BÀÞVdNPèôù¯×q‡ÏSžYé3™_ÙìŒ/ø'N,À5A•ÖªHŠPÇÂò ¾®)t6p¸¢:"tJŽËWˆŠb­ÕBÛ³ÅQC«Œe#†ájˆˆ†-‹aÕ-;•u=[=•õ¡U¼°gF£zÔÒEÅ›q)rAÛØ}<¬œŸ %4?zù}W ¶“°”"^ŠP#̘‚ç0eLÊ^’ÈQAÀˆÀàà†aò”ª#Úvzȱ’Œ\Lsþú¬05Œ"¦ Ã(Ô_~ 8_ƒ6Áqx›ðñ jë°5@†«‚¨`³`º8m~À**CÃÑ»'Û·!ÔÜÔÄ}ÿ:¾¢Šæ® ­ ‚~"m{|Å«3±@¯c8ÿL.2:ÒZk‡ÞÚΊbËâsÈ[w†ËK·<üäêÅWÕUÁ|ÅÄq±AM©m;‡z`¿³N~éä¹éO6p‘ðЋtÛÆ??)/‰u«)oèÿdߪÞ˜{áþ×_\Ì¡…ÇÝ-wo_±òà{n.Û?O±Úª|åw‰aÙPIqçãO]×ÉÉv:kµ§¬tÖ‘'+ÛÙœÖÖÚמٹÑÈà+—´­^ûå‡óW!ðÉüji‚,4à—ÿMÍ„1é»Í¶Ï´†^8¯|XóÊ“æÆ‚Ñ‡Z@è2ˆJ±8iådVe0ë@€z ;ŽEÃN ¹ù&6.èÉóuL¦x`^‡   c^…˜µ#‚¥º-ó\Ö‰nÄ0ÆÙÜÒ7’1ôl4¬ZIAÁ¢„±ŒQyVó…²²öÌ(tѶ×a눔Dt:"†áY,ŸqªYšÈ0„‚€Ó]GXÍcTÊÈ4äYQ^‡ç×ï×=)¨ßܧ€:0>˜0xÀÀ/_‡ê:\TÓy›)B,3 S‹5¼ß5Ï-2$È@„̓0&eT QªÇ95D¬"1majF¨áɬ—fٌǙ.g¸¼FD×Îç’N›mÀ2@4Ø L.¿¨ŠÍõ¡Íø¦ÞlŸ^lŸ¾~`_~@ߎk±Xc¬0P€¶‚ úÑõÅcÏDÊËv<öÌú??F†É“F]µ$Ù»¾ë1©?æÂ¡í<½îwޏö¢xUù‡ÚkL êèCºv|¼¡G¼¡€o¹kýí ÕŽnï#}Oë‡×Üæ…ö:ú–eó_8ynzÍ'v*ã:¤ßSŽÛµòÍžGüí»·òÔù|$©,¾üüŸ­õÝ5|8ôw¶þpmyäéWç,”•5ô<à¶+ë÷/’Û¼mûÓ/ ˜}êèÆ¹¦Õ9f»î†Û³ŸmŠ”•Äü!’Úªpey´¶:\ñ“¢d,ö€¦þoõbaE1\U®ªHDÓ˲R¬®¦ýÃOÍè{âÑf&§·§ÌŽ´#+NNÖÛRf*ã9_ÍǸAó¦§wì*Å!‹æ”ôo´eÅhO—dË곇N£»÷E\³ƒÞ8@2ÞsÚäÒq#ß_|U `\Ðîv<‘ãBg¡PÄÍ—AóЬÉê†0)hBð4°S©„-3êêa×4³<—u"aC}r4’3ˆÆ Y'¬šIF† Wç ÃVEßiƒ‚°kÆÂš(Û–F/<ÔÕÁ¨°çœáûpÒÆ/ž>É· mÝÑþáÇžnˆ€ ô>e²X”¼;ÖȃoÑšÊ÷ÿõÀ;®ïJl;Ÿ{Õµ,mOë§¿ù#¥^²¾ûðå ÿÎÊùŸR®e¯úÙÏcݪ‡_ò?€ÈÌúÍ¡¢d¤²œ¾öî´ý™•¯ÎYÊ‹Âàgµ,žûC®ê­—fÖo>èŽëDb[}Éõ‘’âP"îæ¤µWßÊt¶d‹{a IDATE#Ñn5‘žuѵC–Îû)qÍ7¹þ­?fbQ§rÄàò–V6g´u©Œ#«¾gervV²²’ÞÖ!ïÚk¤2‘ÒâQ—.ŠÔÕij9? €ˆÇºÕxeÚ\²{¯¿Õ ëÖ]¨7ªþÔ)µ“'½8~*ß‘öÃDÀ&ù(æÁ …Âqóã¨À ZÙ"A̯_!=´š—ðxÎü˜¨ØœãF©\Öá²N´X#cx6íElÃÌ„… iœøUq]`tÊ©.«ÐFÌpéå<Ë Y0&%ÔÕ@MX® /š…ÁÁÀ¦'*ç¹¶&²šgUz”u½\:N!Û."’èÙ1ªEq%NTóåј %D%D¬$‘“DN ç©#.¤7ÍyV oÞ ¢g‹®-:¶èÚª¢Á6`ë *ž F•ÁäÀۡИ!\S#×Ô›ëÓÀõéÅõüÿ­‡~'Àè­môCeg¥§O¤™4Ä0@(Ó6l±RÙÞÁÇÉ_Ë•f5` …½+Vš@¨ ±u?æÐ!‹æTàÉ>c£{Û*ü™ý†•<6½ú£Ô««<Àå¹hMÕæGÿæyž_0ª;²Ç‘µ}mMgž\Ò?ÿFfËÊK'Ï3Ú;´/÷6Í>uйÓfðÂY¾½*N†+Êæ_öYþù]÷¯Z|Õ¨Ÿ/nY2÷‡_êµ9K9QˆVWö›qb¢K`ú¾U¼uÁõGM¶l~Å0í¶<øÄëg_˜ìÝóÀß^Wܯ÷?6ä¶lOÖwÿ&~û:ß8ûB}W‰ ùÝÝÈlÙV×·×€¹ÓãßõþO#6ÿ9‚Xì!M;õßÿÅò\¤¢,R‘ß’`¦³VV²³9+“Ó÷µ+ûÚ윬·u ^8ûûþÐ]}k͈–ÏÞxOæbݪUIÑT­iÎiMó¦ï}kõcµC#¾O$‰L,&ŸÜk …xleAJœô´áwsಠ"ÀpmÄ-›š ãRÞ"žNr¸,©œ23a†¥ÎP²q!ëD8ÃQ„DT±ô£SÇT0 »¦èØšË+Yx\ŒªÁ&°Ï‚›dÃð@€·ßžš Šg±þÐDHIÚr”Ñ ),dŒ‡'žšÔäµü8Îuu)ʨ”Q)TÄ"ZjÈ±ŠˆTäJI^–;b´Ãã3”ÉP/Ë Ä,‡7‰èپ٦90l¸jÚü±P× A,ª O. îÏ75rýzs}zeÿpíï\Ah+¨ ¬§bb°Ç„`ÆÍUµÆ¹gôœ2É#äÙ¢¦j O1À†CÝ&Œ õ®ßµòM!%€$š›FœwVßÓ§x2ÖX ”Ÿ%}Î9£ûÌ“_ßïh° Óý„£Š†VvíÕÚ:¶>þ¬ _¾°yá,m_{¼®¦ó޽ÙMßr7t?|üAwÜP>|°™JG«+©ç½6{I¨8­ª8oº˜üd|Ã|ê ©eCœ¾åíhMÕ?<>õÉyÛNyÓÖ®úʇ ÷Í]‰Mݽoý½ºâgMgœðCîÀ‹Sfízé 1~Éù5ÿhƶíýµëï}xÄ¥ ÿ±é{Û^:î¬ÜúÍÑ`7¹÷õlX(:¨qÖ)ýÎ:ù§}°™¯¾˜ÿ“/±pYI8˜.´%ÙÊÉÚÞ¶êý‡ßñfGºñ¤cž?î,¤~Ô0ªxÈ@vËöæ)“ªö±bÜd(*lhŠüþ ^°\K, ‚môBÍî^›Ùµ÷xÀ‰@uà0ÈÀåÑïPÀt`g,PP<>ë`ËyŒà "d3ŽD Áu8Ý…F£¾ÍV>,V–ËAå,@+#,DDr€XðDK@Û]•'Ä–EAu8ÕM0JÂVb‚f§ø°b¼pÒE¶Ä7Ìš1O‹p‘xWâ8Íe4Êh45ΨQO/r¥""AõÐᡃr9—ÉPHð¡M°ѵEÏÖ4Ó„§À6àh_e³1¢}úDö=ŒoêÃõod¾kè¶'Ÿo˜rDW\+pXÚ *蟢—«[¨¢"ÀµÎì6蛩>h´¾s÷ªþ…¦.»®5ïsþ¬òCüô¦;ÌM[ÿSáÀÑþ8\Qúb¬@ P(€ Ô™»îßu×ýÏ—ŒÙóô©=N>VýrOfýæO<§ç†^xn娡:‰mûS/¼rÚyb5•C—ÍïÌ@D«+ÛV¯}á„9V&W=fÄàóg}“Ø(íøèÓPiq¸¼TüÖRÔKÝpûŽgVŽ¾á’ºƒÇ~ß1í~,Ä¢±nÕb2±òŒ¹õ›Õ[ À†Äa7`Îi©O6ä¶l%#•eŒ¶Ô·]õô³—î~éGÜ|þ¬Hlßzïç¿èà{~‘ø~oìý‹®Ûñ—g¨aFxP#]f Ðgæ´–Ë…+Ëò§*óU„-óþu'%Å¢dâï–ØÂe¯Ï»¡[ZLdµáÔɃÌ”wînœæÆ?<òöÜ‹ø`ìÔÿxó =-Ø‹åæœº[þU¼àÇÖ²ÌÐKÎïøbÇÈGžÖÍÁÀD jƒ†ISÁsü…\žª ÿ¨½È‚¡”å=—ƒuDÙâdW$6 °Ô‹éZ¼Ÿê/ ET%òÑ}6`Y@$@X?ÈÁAˆ* !NTj3¬âyë;m [ 9&›.Z;}dØ3y—ð. ÃŒQM´mCŠxË›„U=F£1NKpJŒÕ’D†™iå҄˺l†eê‡èŠŽ-z¶ jØÐب ÛȳùÙl¥ãÇD÷k‰ "Ä~×YYjÝç¯Í]vâ{+ jh+¨ ®ž‹52]¦Ø$t]¿ÃÆïù‘ëÍ€è€È@Ť Å“Æo9ø$ˆ )/¥™ÜƃO4‚×Û˜üªe(ùÔLTz`rìȚɇo}üY÷ñgÛßûè“»îyå’¡_/,m¯ÎXÄ…C=Ž<ØìÈŒ½íª².áºÒÖo̿Ēäýo¸¤yÁÌoü¿ÖÞtGÛêµÑªòúcïÑ«Çn­ñ‘ð¶'ž{yúÂý®¾ðøUOß‘F{êõs–…KŠbµÕÔ²?½ãOP5f„Û£[Õ¸‘Ö·ýo/½túyÑêÊnî×4ã$ÿRÛ¿ï 7Þó`¸²}ÐT£=åc‚¿àj¦Û¹Ÿžb€—ÏÖÈ¿® 9¨iØ% ¶.¿±fû—¾g˜€ë! šaz4œ0AUÄj€ H†g\Ê „ŒÓëð¦]Û÷c™b ?qMdX2l5³ƒ÷ Ð)ˆ†s Ô©xk— OÅ"œâB¯‘DLIØŠ«²\šDMÝ…Îeõ˜§¹ çI¬'±¢msšË^\P㼚ä""YiДGS›rÙœËd2ÚS5cFvÛ·ee%![û?ùåï"=뢵ՑòÒpqrýjþÙ9ǽýt=~óÝûæêHUE²¡Gÿ³NVwíµ%YÝÛ¶jéÕc®¿¤sk§ö¼¶*T”\}ÑuBQbò»ÛòГ­/¿U è@r@ßž'›Ú¶“k¬o{w–ɹ@jÓV#+…ã±HUy¼{·h]u¼{·ž?ÅZ°ÎõžÃL,þ˜¦žøŸý:m˜2É–UGRøX4ZSéŸ lþócµÆ8’lg$"+v&g¥2ŒçùóÚb®Ûùºò» ¾b$¼`fóâsޮ߯8(­úýp6G`³8*Ž,X”€2`txÄ"À)°žç‰Ô#²Ž• ¢³K„‰ È€O‚%Ã’-(Öj½¹Aç¬ Ëiƒ7 Wá !YÞ¯uж·Õ„¥(é—&QKw®(,qÄñZØ1-)äC[Ø59Íå µ„¨1§Y¦ ®ƒvqÚÎpýUu%e@sà© ržØbC%F+>`¿øþùï2•·<ú·Wf-^L)þøhWƒ­à· ­ ‚~dý-ÖèÕ.&²M‹ Š,þl @8±p@<€NaQ„€@=€/÷ø=é\y:pÐ倄¶Û _ô 0‚ eû—[§Í³€`§³èsÆÔËúÖÚªy‡Jоxäi¡´d¿.ùòñ™ [ö¿õÊoþÖþò®3Oi˜2éÿ¯Ož ÏÛÿÆK•]{O:&Ù«‡ÞÚn¥sÄ4_›³´aò¤—_Ðypê“õ™Ï7÷=eò|ÐÖÿîþw_®©r uùýgNëüÕÞ·ßw«î píï¯{cÖb.@a¨;rô­W÷k03¹HEÙÞ7WWj‰×ÕÔ4º|ðÿþøßtÕªy‰¢¸ùÞ‡ü¥–•˜uŸs@¯©Gýú_¿,òö¢+Öß󠌾úÂþg¼êgWFk*{Ÿxô›g^0îç‹#ÉxÇ{k"ÕUñú:ÒÖoœsa823¹¦yg”5÷mƢĦ­Å€”<¶ïÜé|yi¤¹é£knS39šÌ½mdo›ä?IŠ“û]»ìÛÄ–Û¼-Z])&ܪt—†6øNûïùúŠÅvkZÝrU\(©uÎ1PJMïuü‘Ž¢Z™‘£µÝLgœd¥³™{¨¬Àu©C Uó2.€(¨¿û–íɺÚaÎK½üÖ»õûñ€Ò%Ô×3LôŽ‚W!˜  ¨ªÃ Á±€BY0 e(5Ã` „ʉ+qbØþªóÑ¿= Áj°³è6PP 0ßÏl¦Ëtx*â®êæ8>GüOØHØŠ&K‘õ³†D-Ý3Ù$/ó.‰Qtð!Ér%ÎÏá "ZvLÔb¢–d; ×ÛAi‡Ç¦\.ërYð&ˆÃð\H ŽÝU@eðñ²ÒCG'ÇŒ ‚¾¿éyß÷XÓô[fþìÛ|Vµ´TЩ¿Äý’ŠX”l8á¨Ì¶­¯½“hì•Þ±Ë%ÄÏt€™€ ×êAwA 7ßéì`‡ ®jc®d Ȩ:hÚ`ÊÈX0 ˜nþÜ[Úø…´F^Þ¹;µî³ò–AÚÞÖhu••“†-;—¿–ìúÙí\û‹ßíwíE}O›b+ª_\}ѵê—{©ëYéÀß^×ÙîmËÊ{—Þ¤ík›p×MßpéÊõûö0ºsÏó“ÏÊnÞæu‡0òò bÁ1Ûž~qãŸþ2üâ󺛺sϪs/v296°-CÝk›—Í÷W×ûÀµîG]áX[yzûß^ÿ»løÃ#¡H8Ö£Û—}vÓ]ˆ]Pýý↞C–Ío<ýxß„ uɈZsõ­›îyPF]}¡•Jÿ!ÖØÿœ3†,šópql¼õžHc¯ŠQ-î\à…£gä^[Ås\¯Åçô=Ö;s—í™wq<ˆ×÷éÕýÔ)liq¨¤èõéç«»÷ñ€ °]ÞC)0té¼~g~m!óù¦µ¿¼kÀìS‹û6ügãÎç^‰”—Fª*¢Õ\(ôýÔY œ6†Cÿm?hb±vÿ„EÓÊ~Lne˜d¯þ“º®¾¯ÝJgíœdgeyϾ Use•1L³#mgrV&›ùdbQKÓCÕ- fé¦Y4nTË’y7•(êÓË´ôÎÝþô¨°@Ї͡Är "X@Xx\°ŒgG!Ê@)8Ée4ÚIl”P‡™ @ëwÕÁüªØ€eö èðnž¢åbþ*wÁrx›$,¥ÝEQš„uS Ž§³É¨,xNŒj¹Žb^#žÄúû²Ó 9V\Tc¢ϱˆ¾Ã£)Ê¥\6Gø ÇáC¼‹J‰ƒ­ÃÑa™ 2ʆ ->ptÑ££‡±_÷°»jø¼‹1ï⥠­ ‚þYz6ÖhÅ TŽj|ÁÙ{ß~÷kï [6_Íä"éŒÙ‘Ö;ÒÖÆ­3‹àê°( ŃEàºùV¤ø/'ÿû —çq RþdšêðX19@ vZsçùEò‡Gö ào‘'@O@p]CV5 ³m§‹Œvl¬[Í[ó/‰T•G*Ê¢Ýj¢ÕU£†æ ³uŸ¿tœºÃÇO]½"ZUàËgV2 óæì%ïV=dÙü¦Y_íTøìÎûÞ¹øºò–ã{}ç…M÷=¶áxÇuß&¶Õ—ÜðÉm÷z@ÕþÃ[Í®?:¿PKÞþåª%WÛŠ:òÒ…wõ¼U‹.ÏlØ2`æ4­-µãÙ—ã =†/_øíýª›øk¸´hÍwĻ׎X¾pÓŸÿòÉm÷†6*ðúÎÝ øS ÇéY©í£OY ÿÙ§·\4?RUà½KnèyÄ„NrÕ¼‹·ß÷X `€Ï.»Éš;¨ã®ûÿv×ýþ:p='wkмdî» .ÕÿðˆTa×µoºã£›îðÉÛÿrX–qȆß?ÌËjêóMPÜáŽeí~áu¾K}èEç5/šÓõôúÙî|ñõ~}u͘ß~f>Ûä9N§;her/ÏXȉb´º"R]©¬tÎßÉËe¿6…ÚØXì M;þßËf‹·cÿ\/á¸X]M,Ù±%ÅJgœ¬du¤í¬$oݹöúß4N=’×uÝþçÎ(<@omßóÊÛ7E¨ÙR9q\ÇÖÉÚªÝï®èð@F@ÈBX†ëò°\Q¸D. ê2 ¡b€ÏÝÀqîW=tnþµO ¨¤ \DT@‡g‚õ-7”íÁt@,D06òº• …eÓß vMM‚ °i7¬™ÄåYÛ+"’@¤Áu¸¼E<‰åT7ìš‚åD¨µ¸¨ê*lWÛÚAÙ á²®õÆóZi™œ¤eŽGÑÐí¨C«9´hܨÐ÷O‡æC ÐVPA?±Y€ °¢Ø|Þ™Mçœþåó¯í~ã½ ß‘ìÓËÊJ>±}ºðò!¸t2 P¨ˆ›/€z]¸-Œ¤³Èƒ2¨ Ý«ÃÓáê€^@Ï|·q>b 3^®„~{¼ ˜ÁVÄ~GR7õ¨Ïo¼cûÊ7)*+‰ö¬0sZ¯c[ïC®aî|ø©öÏ6¾iyŸÓ§ ñØêe×îxüY^à¥]{= ïéS‡^4?x`ÊÎÝ+Ï8¿}Í'Eõcn¸¤t`ßu·Ü-&bŸßy±¬ƒî¼±ôë»hö¼ºêù)3âR áø#ÇÝrEg•êëoýüî†_ºpÐ9g|ã¡~}ÎR=™øÐo[W}°ýÙ—[–ξü|Vº³ý™•«–\)/0tɼHYñ3ObUMXÀ ²µ"=ëúŸ~|¨ºò­—2@ß³NÞÿW?°sÅ˯Î^|À¯¯ñ‰mÏKo¾:efHL>,d^zƒ ºÎë&Oª?ýøö/o¯n)BÙÉ–‡_§²€$PìyØ±ËØ±K*öÚçìÓ-ÝxgÁ¥là´9ÀÀùg½lQçÿhý÷½³ä*wËÏŽ;ÜÊJÚÞÖHYi¤º€•“^?ûš±£ü\=ko¾sÃïq½#e¤²-œýw‰ ]p­s!øúwËÂã@¹6´}CbQB,ÊOï~éÕ³—ŒX~~ň}Ͼާï??¸üfù³Meû){ÛÊG rñË0ù¾ ;–ß"@7€R,XÅ: . ›‡&ÂæàŒK‡ PƆ†§ ^KËRÁÉ¿Gø6u`³°.”DUPŽƒP6ßåfûÐFÐï|xI–ÕrNX1EÛm;Æ«.ˆƒ ³GÝÔÂ!X1C‹²ºÒ‘à3D°*1‚â„=S´í£ÅEU娣Á"€ÒÚáqYÍAv½±ƒ¼´>“T(Ž.”¬;ë¨úS§$¿gLçÛÄVÀµ´TЯçbv€kÐíðñƒ̬™0fÛã+ŒŽôä·Ÿb>·ñ‹X·êÌ꾸ó¾“bCe¡°(d†e>²‡ƒå†ÓÎ2ù‚¡[0LD ¬ÆÍomÑN`çhAô@)PA4¨ôÉ…€}+^Þ¾âe3/ÐÓÙóf”ôîù‡Ò!Ëò µõGM”×oùpö’mϬô€²C E÷ë=lÙüÆ“ýÊs½7Î[Þ±æ“XUÅ¿¸\Ù±{ÅQ3"ÅIÛýø»oª=p¿mO½À BýQ=B^<éœ=/¾Á¨9hô¨Ÿ/ŽT”}vÇŸ…xl͵·u›8îÄŸ÷½¯Àåžß»ä†áËÏ÷M+§«~¹ç¸W«Üoh×cŒ¶Ô“ã&«{[CE‰ÞsNm^0󹣦gß] Þ›¼à/Õ4ë”ú“Ž¡,»âÐiz{ØÈ«—طꃶÕkOxÿ9?¶ã™¦8}ZˆÁ PØOëU” \4»×ìÓ¶U Nmß^p[VÙ¥ýPƒHÉ!šæŸ¹ëå·¶Ü÷8 $ƒ»×ûÔ)ƒŸ`óOˆñè» /×RyÙ¢çœþöWè{Û¢e%ÑÊòPi±ÞÖ±õÉ_0gÀœÓ¤?ÛøâÉó¦L¾ü|£=­·§ºMÓsÒ„¿ûIùpðð|£<Êý»UHcñ4x” ‰Å\Mã~Êû mݱáNzúu‡Ðõç_>ûJ͘•ûªûڻǢýÏ!ÄcVN^}ü,º¯­(«­re5­j`rÀØÈ¡DÂT4ñ\ Ñ_ ÅFTGD¥vž¹ PÀQP¢ ¸ðP Â@à»$È©ù†6Û…gc€(À#Ä£šCe0@#2€ !ëP…ñ¡Mc¡q :"ºn–‹…´¨®‡aꩨ˜±Ûar*®r¬˜ ñ‚)ÛpX|¤LÊ㲄˹^s“×€]Ó]¿” V³¼ÒÁƒ¦ŸPsÌa¡ªò® ­ ‚þez*Ö讫ºà¬Açåÿªî°ƒN8Àë³3ÀîÇVô;û´ñ{ZUä«¢² ™B¥ùJ(ô3@,©:rbÛ¦­So@°@5x ˆŠ,`X° „U„ŒüpƒätzufûU„ƒMÂA¨\Ð÷ùúLž´ëš[Û¢`ޤg_‘ ˆÖV÷:cªPYöáÕ·îã¥á²’Ìç›Ã¥E~Åóõ9KZ_]M&F_µ$T^úÂä™  ·šuÍ…ÅM½Ÿ<øÄî‡8ââën½çýå7vÆ_õ>é˜Q?_²å¡'?¾íÞhU¹˜LŒ¾á’†)GØüàÑêʺ‰ãlIyþøÙEõ'¯[¹í‰çîMö ——ðÛë¾Al+O<{×s¯R ïÉÇZ0sçß^úSé@±3ÁHôëݾik´¡ÇØ«–VŽùÜá§æ6oãx¾ùgg¸"ßò\ܧWÍØ‘6ÞûК…—Gƒñ@é¤ï™9Áƒ¯(K&ãdù»–ßH‚"/x+$Í·¨§<í?g8IycúBèÐ6ª&ŽkšæÎç^ýèúß„cÑÜæm.P;aÌÈËÖöÎ÷‹È€EÝxþ¬ã^ÜòýòÅ××þâwÿô«ª‘-žãèí©x·šb^–U×ò(†þÛ9m,–ÇÜOP!ý¶¨ëª»öúðßþU£&º–e¶§¶ŽòCü¾½ð2iõÚÐ÷œÓ©ª«ûÚ²~Be¥2˜è6j¨µýK»-eiªàAvÀQ0 ˆ ÛB¢ª †ƒàÂuÁàLxp ÇÁ¹ˆÇ,àŸý¨€ ›À&H ÞoV4£àÑ÷~mðaeOtlÏô4þçq{e“±¨• E“zL× ëp…¬#Ú6+y¬ê…=3D¬xH•茛)¸aÊì?ÂëÛÛëߤ…BZ(©‰ÉÚ£ì?÷Œ’QC [Ú *è_¦¿Ä}#ʯŽõqâ ófúð¾ÄdbëãϾ6c!T <ö÷¿äÏ\¤o¤ªçwžäwÑ`¾ŒÊûöî7ï òS¯@wÀ†gƒh  Y†Oƒ£å}5=(wú}ôN0§vØ€d ÀÉB€®/k IDATOCÉ ´]nPÔvž¨?õB4(§Ú@ ( l¼ŠaÍý–ÌE"þâIçDÊJÖß}ÿØ彿œ1hÞt«/ºn磋DÂÍÌéuü‘6ìÏ­ý-ÿ½óŒ“ª>ßþõ;múö^X¶²Ë.½7± ("M¥Št¥ˆ€¨(b‹5šjŸhÔhìFcWPA, ‚ ÒÙeÛìô9½=/Μa±Å$æ/&sxÃ|fggΜóë¾ïëºjaë;xòÅžËçfv«z¸ë Õ`Èh¨í}õåîüœFMê2vtÑiƒrûöè¹|ãr6mxoËÊ›úÛ“j›—]ï)Èz×õ¬¹­í£„¦Þzu×N;•_ÜÿðG«n±p£ßú•åÏ}¶÷Ù0 Ú¦RxÜ=×\8Ú”qư~7\¹åòë6ÌX  ì¼3ë—Ìé¼<ëÊËÑxá±òA.^tಈ"àJ’b›?ÀùBvr‘õnúlz®(ûòœŒ6’ìÑCóHc™Íj´y{ÖÕ_µ°mÇž-KÖ2Ö=Ó}Cn]S4|à߇OPy¶Ù €ª(Cs[·Kn&þOvk¢tÁ›O$ð†e#ûk¼èÊÍv|{äöIÛI–öX›ïe>6îÔÙ¢`hPÖÊ&Ó 1M^iÿéç@hºxäÐoû_Úáð”yJ‹¬¾¿ú–#ϼÌÝW/ÎîßK ýSˆÆ¬¸¹0Pr楢 åqÑyÊ{[¥\ 8¬Yª@ë# BÃÔ@ œQ "PEÙ» Ä¡kPøˆÛ/“…¬‚±ŽNÀŠ*áME„$Â6Eàœ¼dÆ V= ïäEµƒ£ý:R8E¡#:#jN]r’ªiQ¢ :Eå‡îÃSÔоdP£¼Ô¨«Ú;´¬üž7^U9s2íà¾'®yçô}7ýâÓ›~¡Ú h~ù­ºËgWL=ÿÙW}ã] 4 ÿõË{­^üöe+¥PxÌs’ÃQW^vã«>ùbZeÙç<~ÆŸîÉí×ÀG×þLli?íþÛ[6T0¤ÓËß¼ŠñzÚ?ޕ׿Wìpã Ç‚hñYÅäóÚ?üÄ¿mg·9‰­~¡Ýض+½GÝ€Û¯u䥵ù£_켨¯ d÷¨ë~Å¥Õ3'}åÍý`Ím{óµÕÆék'û€®¶‘‚^.À´‰-9Jhu9ó§MÕI\³€Ø äûýRlÕ3s`Ÿ†• Å`øƒ%kYÛÛaȺ«Ÿ~郥× ­¼4~ô8 ÃúÂÐ{å¢$±ÈíÛ#·oÂ7¸iÃ{;ïþ½µY2ô®¾Säxêä„N‹–ÞFŸ2#ðL² J…F ¿ŸÉò*%Ö*«&TÄ ’I$qd®ó¶DO~‚p,ëièväå m×ÞnÃïÁ£ü9Óü@) ÊJÛoRgEYøÐQÉ~nbk»ÜÚÎØkÝæO¯ºhüKg_þb¿77»pÄ ¡#mjf|¾~k—• `ó´+_xÝÂúó•ÃõT)ÉÞ¥ÇÝtço¹Ùžî5í»>ã*ÊØÌô^[w¶gJÌ~=e `m>æ;m†:]NA”ÔN£„ºÝõ.·w’{£qÀ”ÙÁ–¢ééVÙcée²ªßÜT3{Ê+Ã.°òãa[é9#+gOსښJÿ»<]Ü×tB†ÜwSí¼i_9êvÝû—æÝùóß•žuÚE»7n¿ã·Mo¿?úO÷|gV:çY›Ø(ûÄI>m´þñ×<™Æ×Ú£ ,'€5hV§ã”ÍKÍíÛ#§w½ØÚþÊù—v¹h|¿µË=•e¶,½þÀƒOdQû XnY‰£¾ÆÿÊFOf:ëvk )È:  $9ÑRÏ¢  œ Sƒ®.˜:(¦ІAAÓ€(œQDs EAÇ@ kÈ2$ ¢Œžã ¡¹A˜¸ÂJª‚!Ãhí×iIgÕе……¸†˜QEižËô¨£ò²¿?®¥8,m©JÕÿIâÈHwd|ëXwã››Z·lë1}¢ØÞ¡ÅyˆR¬©E‘•ž«¹k*rº–2ÍáÈ¡g^Öbñ‚Ó‡ üÙ5»×ÝØðžЀ N h$õ¤dš¸ÝhK #†­™9€yƒ€ Ct:^A ëPeÐ ØNV »Ç§Ø™ZçMü‰ŸÁð&ØQÈš™ÑÀÄt–S­‘g5ÍA”d$ ¢pM}ÊöÄŠ†5ÃG€i0bªþùMMÐŒ%Jå"µÛ…ŽÌtâõ ÍgDc†ùem6¸ß­kö>þÜ£¥ý”?»~Á )‰·´+ÑXŸ«/o|î• gijÆÔ% -+£éÞ¦bx1QQ^á£MZYqíªÅŽ«Ö'íZ’†jÖüY¥}£bw­Ú¬š WIQ`ã{´-—Z0€ðS˶ïÙkÈJà{FP*/_³p¦*IÇÎtn¹ÏgG!i€§¦¢ÇeWΜDh&~´éåAã¬$=¯¾wççîýóSŸÜùw^Ž3;sÀú•®Âü'úž#‡£gËèŽd€ò3žThÐe”™**zÓGú¦bö"HÎT Í6=‘mP“Ã匋Rñê.™°û÷ö»`)‚^‹º8NQ”¼Ó—Mwì“ÝÔöO¶Qˆµ„ë()ì¿ô²Úų¢¾ÒgŠÛÖ;UÛë¾fþôšÓŸíÛ~ÇoÃ[¶…>ÙMÛ˼µó§õ_» ¼åý«osee|ùÈ3†¦™@VÚ!w®Ýsÿ£»ï_`äï~öõÜúo‚6Êcʶ[6’HM*muJ@›ƒ@¥@Ùóv`Âr"Ë©:G'Ú£4ñÔæð{;NÁ“CË–mý×­H¯ê ¸{ï‘^ï6õ|Ñhݶӈ ÄíÒM³bå")Ý÷å–mý–ÍeËKM×!ÒÞqäÁ'’‰VW˜×¡` † Š0:4 ¡p  0ˆÑD”‡' ! šIƒ®AÖ¡ÈP€ÚÐâÐu"Z†3¨K:dØ0Œ6pAE&ºßˆŽ¨‰À+T¨2;|`ñŤp-m©JÕO²Üyî‚<ÔTÐâ‚Ôà›Z2ë»q™éhç-)ܼôúО}Àq`Ï` fi€ˆ8$ÐT"K4É4·öÎAñéƒãmÒÞÅœVQ€C‚©B4ºQOôU“V½’MB `Ú,Â3G‰Ÿ$j„01Hd†Š¸š *fP”aÊ„&L3JB #!ÆaFaF:–dHd Š M„d&¦»ºÛW ë·SÓÓò.<7gò¸Pcóþ[îµ’[3:õƒ‡ù³FÇòzuWÙ½ú·×#¾þ °6Ywp, Ë¡@—aÈP´„$™fçý¨ö6FÒn׺‘D{ÄÝòaq×T”>¸íËÃ>¯»ï-WþÇ¿´nÿ”±¹ÙrqS ©œsQàp#íu÷Y¿rßCOýóSŒ-7Z:Yõ¬Éuó¦åöë©Dc/õ9ÛŠˆm_e¨¹ìâªy—¼½pMè“Ýœ¾ ÅãF7,›[8| €ãooykæ2-!65æì=`ÝŠýO¼`h𝴍~޴¡ÔX<¹fñM×Ñçíö¢i«kInë¼:jµG)ДÇû>ú£*m¦ý¬À E,«±œ4£Ó¬ÐNQ±Í2ÿ ñ‚iÝfM–¡o½¢™úåóäŽ`ñ˜‘¥çõÒ¸™…Ó.ì²`º©éZ$¦øïMžoi†Ï“SWã€é¡(¡(Y²Ûjë;\^=çBCc¡©0)8yˆ&â&â"2=à%(Vb©œ8ÞŠº‚Ä ª:…ƒ3- Û¡·Côv'ü:â:b:¢&Šè2vtŸk—~O\ƒí葸´¥*U§ä'ÁëözÝÞ®¥oÜ´ðê–7Þ%@v÷š¼½Å`؈Åp”ß±§èô!º?Àþ¥Pú‰`k ”ÊÉB0 ÃЀ¾«;r²ö¯¹­ ¾nD (ªHPu(ò qÎRQ¢6^Ö,]jÞà±™"â&bB@ˆ†/‚˜•H ŠLÐQ˜¦!PD0‰hš‚áMġȠb  nT ’E*'ú¼5vâ§hèU=þÀcxÌòql'ãTðu›Üõ¹%Êe¿JÖþ&kSé .Ä Ð %^ Õžç“lý 6-iöƒPvö±•È¢óÎ,¿xBû—ù­»†®[qàé¿‹mžâñxkZ×R9’cq®¬¸ßµËbÇ[£n¯{ñ«çÍ.Ü·xÔÐHcs´©U•¤ì¾=F¬¹¢ì¼3|z÷ïwÜx7ŠÏ>=t¤1Þê—£1ä î+FbÏ :¶O£ Ñ«{ÃòyvòDxßÁ-+Ö[Äf=óÒsGõ¿a…¯k—ê‹/xgÞª¬êŠÈ¾ƒñcÇÓ«Ë¿‡Ì–„6º“ðÖi 4ˆ ÚEþ±aˆ#Щ„­.¡Ah–“YNeYÕdI¢=Ê‘SÚNœ<îì^ÝMÃ|ã¢Eé5•ç<õ±Íï«(sæfo»ùÝfMî6s2ìÂG“ð€ ”ŒÝuÌ(C–ºÁ(ª)»ñGËå§úÂ1¡=ûøXœ2˺M-Ѝê *À›(â'DI€y®Ä¡kPe $˜"2 * £B QÀ¯#¨ ®#®AС\væ€VtŸ?íŸØR –‚¶T¥ê'SÛÖÞÑòÎ`˜n3&v›=U‰ÆÔPXnëØ~ÃÏë&ÍîÙý“ïvÚ2ÍÞ=ôöíQ?ö ¹#oi;¶aóˆ{oâ?ýâÈšÛ| TpˆÑÐd° `À”¡è'ˆM²µ"Øba;8˜W 3ÐTÄ ÄMD „ ÄN…¦&à¦ÐDÑ£0cº)‹Ø(Á@ Ä +48BàBÐ5ð0"b ©P ˆ@¨°'“=G`Y [ñ"öyIJ´elôLÎû6}êñysÎÞþåaå³}î4Ÿ9€n€ƒ F`ˆ ¤Ä¸ØÉM´S¿h[NËÒ?¶w¿Š›_8@²õízÙÅþϾüòɇݳΙ“U0l@û‡;TQêwãUJ$*…"š$7,›ؽwÛ¿a}ž=7â÷w(ÁP¼©ÅÛÊhó§W—÷¹úrBQí[w¼9i¾ ;²2ú_»TÓ4o0,ÃRGPhóÇ[Úý»>'ôņåóz¬˜ï´óXÕXü½%kã‡Y¨å«êÚ󪵳§8ôÜ«g/‡axK‹*&+þÇ3F¤¥™'·Gm¤K&"ÐÖŸ†<ù>Å¡RÐ(˜6´±*Ë© §éC³:eA›ú9¬¿»lìµs.`}µýžËævž—Ýyó½ŽÜìüÑûœ{FÝÜK¬‰ #Õã—úk\V çÜK¸.ÅMϿƾÂ<ªG——#kŽ5·Z.ŒéÏ@Q@› X4A÷À‡&@wB•¡rÐD(!(‰ÃÐ!FÂ@Ð@XA\GF¯z¥¹µrìè7\é.Èû§p-U)hKUª~JuðÉ9YeÆä ì]1)á/¯„"oÏ\Z6qlͲ¹.Zd ïÓöS˜ß}Þ´òY“”/´úßœ¹´væäç¯öZÍ! 5 ÄT'›j å„[ €2 ˜æƒÈ:b$maš ÞHHS…@0eB D0)Ñ€`ZÐF‚¦$BÐ!+ A0¨2b²( & ØÄ–lDª6SJ¶Ÿ™¥ÿeû¼µ±xÒÄ$Ï%ÛãüÖZnzß…Α iþµâ9Ù­Ï¿ZÐxI%%¶ ’Û ²½"ªÙ£´ÇÝëÚ%‘Ž`nI¡§Ý/‘={€ 8J‹HºïÍéKêÏšúÉë`š›—]3ÿz¿§(_‰ÇÅVZMņÙW¦••TL<×SZÔÿÆ«EIA5—‚aÆå²r2âÇŽïôÙÜ!ý@H¯ósz×ËÁˆ%ˆíx«ÐÒ®ò‚Á RGÐÔô+æŸm¹ç·çöï•^Ù•omÏj¨íµr¡#3Ý4Œ—ÆÎlÝüz­\ØkÕb.Íû=ŽGê› J¼´äkm4õ#ÏøsMÁ ¡Ó 4Ç)–ÌÆpºÆé4£S¬F<ƒ»ð;•ÏBK{÷yÓ½]Š:ßèÊ=iûRhn-=ÿ,¾¥-³{¯k)ŠcÙ4/Šò¾²qÇ/ f˜â9½=oU `€þ×-ã;‚®@H/*P‹oáTæ8M–åh¦Ášà/ ˜HãALèªªÑ ÃL|ö SDˆa ¬ÃÓ³ûð%sb-íyýzò}p-El)hKUª~ÂUvþYB›ß™Õùšºýæ{KÇŽî~ùì÷WÜ(Ê î"1k.¾ô¼3kÍÊ5iïØ0w¥Óé8|ÿ#iÙ™f\`eÙÒä´ÌL>2 @`èÖZg¢B|vOÐÛhÀp\àt˜!ˆ@ŒEÜ@\OÈlQY¶‹l F]3D4‰hB05TV{”7Àë0y0!„E†@#Î@Wá5!ÚCuR'O±‰ê„k?l@Í–mˆÅ£@‰TÖdb„åKœnÙØÖ×”,š™>¨ïßû©™{Iɹ£¶L^eÉo"&T-!ª [”hnSl{È­.çÒÓâÇ[ûß¹6«O½¯Õ/CJ0òáâk8»},56gé7îµÇrû÷°ë¾ÿ÷áÚ;²º5,šÉ7·êªê-.èØ³oóÊ›û]sEzUWSÕ †´ÞYgN–3'ËWÞÅú§¡jj,^6aŒÐÚ^3}¢u£»Èé.Ê + ßÔb¨šIØê¯é”s”Ùª§_(ÃB›Ÿõz †ö ´úß]|!JecG÷¿qEVCí÷>É·/"œ”auÚhâñ~ÊÇ{þ8ŸÀ0t°œÀrËi «3œN1XÀh?©»0ïß§¨À]TÝç«n|Á={[6TsñxW^NÃÒË>ÿã_Ú›u`ÐÚe\ÿ^Œ(±-íhn!]K²%™3 “Ìh\ôÚßÿX8ÛQZ$í=@›Ð˜ "t¢Sï8]a9*F<î+æ÷Z½¦I±ìw©¡)-m©JÕÏÃíJ³/áV…¾ØßýòÙéÕå»ý +'«ú¢ñj8*…±Öö²ñçÔ-žÅ¸] •îù×j'ÛºöΪq£=Y™Ç}ÆÊ? s³èuÑ[`&xH°•$ Ȱ‘Öž£5°o}>G M‚©#N#n"¦#n$ /Ü §6äÙ­I#Ð0 0’iŠÐ<Ì‚,@ÐÁë`¢€‘˜ ãu@®0ÀÛ?€ Ÿ„`†€"qoMHƒuÐ[¶Y+§1{ÀbÇ‘¦ IDATê`ª¶S]! HO˯·´(©Æè²úüËši*ÑXÝÜK¾ÿ¡èñ¼r2¥™öß“·P',?(#Ñ¥)0? q†‚BƒÐ„",«&Û£4kЬn°”¥´Aû¯=(ÑëóVM9O‰Å‹N²÷¡'5A,¿pLñȡ՗LHðm(âîj±¸Á fŒ×£1ÙØÿ³_[›×%3'zôkú“Oj­:Ô(D¢ޏ³ÏÙþñ®¶ý‡ËgM®¿r~F·ÊtD¥p-m©JÕ{eÖU[—Þʩ竡ˆŠ¨Ñ˜ÐÈîÓÙpÒÕÝWZøÚÔE}–^Vzúà“XK…C÷^}ùñMEm{0ÝÖÕàM$YuÕDSÕöôdt’tÄô)¶–8-¿1àü ÐÐYP*t†M„Â5ˆxí$“³A{ãuüåvo2) „a†aÆA¤1ÈÕK²*â@Ôö¢³ü2’ Í<[A”#Qñ• ‘½‹FmÙö·s\@ÀÖðD@óº»/˜ÁÔT¼ÿÍ6mX6wÀM«ž4ŽÍÍþòñç]…yÎìLÙ8þÚ;–·¬NHås믘cÉ`¯Oœ×øú;É€')N¯*ï½zqÁðñÆãµ³¦üXÇíàŠÏf¡þ ?¡ÍÿUc6b&¶2Wpú›Ú£4öÇ1þðä— 0†€¦@Q ´ÕM´GYætšÕÁ8,™”ü·ž4¸4—æ³<“5Q*54«¡Öץؕâk—™n­«ÐyAí~|Ë}ÑhŒúݶ†ojð‚ÃþRDÙ£¢ÞÊòÐúÎÔ\·PÐ ZQN¿íšÒqÿ8#El)hKUªþ‡Švpîü\äç~Û"ìûËsg>òËâÓ‡¼8|‚é󊱸 ^»\-ÌÛóÒ›l§HÓž³Œû3»×Ô-˜®ÇâF\øìÎߺ®€@ ê 5+r"¤Vf8¸-Îo€€É@ç@$&€DaF Š‰Ͷ:-P;ôI.ºÑõfš - D` 0 ‘àp lv´:¹š½"굓דsiâÞƒN ¼á=ÍÞ´ˆM±§ß²‡öï:y\ÙıOמFì•Õn³§ÐûçÌ:(6@ìú_ÙH³Œ®jÖƒ”ŒÕóªÃØuÏ>^wm¯”0A7­êe§Í¦WvýÑŸŠØö>üô–Õ·wÙ¢ ˜  ˜Œ¯ov‡”¢Aé?²ÒÆ!!³1(„á8>mœÊp‰ö¨Á™C#P‰ç‚Jþ…ƒÿå×Z—Ó×µÔwò~úWO/÷~ªeǶ¸ Û¥SÓGcÂ\Ë׆¶ÅUt¶˜†ÑuòyY“Ïc[ÚªV/úîf(¾6Á†TBh ÚR•ªTñÍm£üítìºëþò c”pT „JÇŒ¬š1é•q3šÖuÝ´  zÚ…ñæ¶Ü½{¬˜OLý÷ç¬ðY‘X–È £%<Æ4ÛÎ2³Ú±Q{}2ÀΤ!ëM˜!ö¼3;Õ›Û¯ç©s©q>­¢ËˆûnòxÞüj{”2› ¥¶¬™¶NíQ“ò¤5òÑÒÿs¥Íh£)P”%°qL¢=J³ºõ‡p œ @# ÐþŸ¯ò c¤Ž ›æ¥9îÈ‹o”ަ b¬¹5+æ[ýr ä++éuãUŸÇ7¸«0ÿû<æ÷²Î·§ä·´¥*Uÿsõ•ÀS)ª™>Q8Þ·ú³"1©#oiM \¿’KOKÞM¥-W®3UÕ™•ÑëÖ5‡þú7Þöú7p"T8›ÞhÀx!¢ÆÍzŒ@Ds@bØÔ8¢öØ™l¯v;hÁêÌN5F‘aH@$# Ùo"l¯6fÁåD‰2J +fNÒ)úÐm¿´V+rö®Y4‹+ÌmÒ¼tÀaÍß…A"=ËZµZÃÕ£Gì[} ±µ:We×úK§VÍžòæ”…|{‡#;³`hÿ7§/aœŽa÷®o|õíØñÖ±¸äŒaÖ+vìõwÞ_tõSL;€|k{äàÑÞ«±íùÝßþêOî‚ÜÂáݺæ”:~X¯'ÝëñxÞìdZœÔÕ ÐÔÉ« ß4ÓFQ` ˜ClKú}0(š£EŽSY&Ñ%V{”5(Τ8 ‘ÄRì¿TB›¿iÃ{®œ,wa¾§0Ï™“õ“>u$Ÿ×ñg«q^ GåpTð䎀.«53&~ÿ‡ú×ô³«¥ -U©ú_/gv¦3;ÓWY@ê mb›¿Ø&d½·âÆXc‹§¼K¯u+bÑØÍÙ)E Z*=‚o÷óm|{ìž™ h 2(}ºv°%Ö1UDT(qH@ˆØ„—LV0í Î)Uèa¨œa¨ Q D,ç'{lŽr9«gMé8|Lyã]_E—Úë–¹»¿qö%±u_8£Û¢Y´Çýâð =1ÃîÆRlr•Nn °a3,妻]>»fî%­n¬Ëë"®BŸú;ešNŸ÷ãîjX>wäŸî9A]÷=°cíN;VÁ‹Jóôrûµžâ‚o|;Z6o}gÞÊxS Ų5Ó'ö¹zñ©zàP'Ël–ÒF@uré¼…ð•E°?ØX›çÂJ0àŸþ“gI¿†¢iÓb5–Iì"€ÕhΠâLš0I‚¸ÿYVkmç2Ò¶ÞxÏá¿¿éÎÍòxŠòëÌHBØpåeÿ¤Ï¬×Ãz=ž’Â,ÀÔtÂÐÿ®¥8,m©JUªþ­oÒΜ,Ô×|åöÏÿßã™5•ÞÜœêK§è’òμUtQ‹³º. ¢ \¿’MO“ÁøñV±= uÔp4ÝíríØÒjÊõ¢â–ŸX PYJHqq ðg“ŸËþ‹Lχ¡@àA«PHl$1»"&Â@|Urz×÷½niãË:ÞxW'¤xúÄðáÆwç­Ò¬> u fTÏšÜì©â€ÓmmOĉ€/ë'ÒöÒ#ew35€ø¼ƒq£«¸à¥sgH-mÖZhvC·.ç¹çŽßð–¾{]VÏ:뵊n|qø6a: ±1ö†‡¯ªkŸk®øÊJo²ÞœºðèËTN9¿×ŠùÙ½ºŸšÇ‰Çû6 ˜_WÚȉ&U·D{T?mÔª´9ÀsY%ÿàwq›¯9\&‰™6Öa±šÂ2*Ëi,«™œNs:Íè„3) $¡»~ïŠnüô—8³2wýòÿé’Lþh“Rë»æ Ëíbׯþ=xÔ•›åÊËñäuöÁyã_#¶®¥ -U©JÕ¤j¦O”Ú;¼e%†¢îÿëó“Æj‚^ˆ=.†#ýÖ­ÈÜW Eøã­B›_lïP#1VQ­½Ó„(žyº^PØ™ö¦µj·³§${ÎÚi¸ÄBÈBpAÑ¡R€ :Š˜™ØW°d6gß… µ†ƒíÞÛûÆ•_¹N×4ÕÁÑ.çÎ[îàÈÏ­]<«föT½|´ø"¶c°ÔilN·{—4˸ ó£ÇŽÃ¾½÷ò¹yüvÁe±™@ïÕ‹kçM{¡Û¤×w˨­j|kSàÓ/\y9_>ð—æW6²"䉭ê@õ¼iÝ.»øÛPìý«Ö{yúß´ªû¢Y¬×} _¥-b9Éヂ m@ƒ¶Å¶äöhÚh€%OŒç}ÿ.Aά„0žå•ü/¿•Û¬,rŽD{”¦8Nd9…cO´G ÖdX«= Š3“)¾õå±õ‡ÿá3ùüÇ·Ýô 5iš¶dëÌÊè>oZdÿáø±ã›–ß ¶àÌÎ,:mÐÈ?Þõ¿sIáZ ÚR•ªTý_}]NoY Šc+§œ¯ ¢Å›ZÒZÛ«mS~Gv¦#;3 u†¢v¼¿íƒ‹³@(=ÂsÖÈ/îy hgjv^§iÏÃÀg'»ŸK¦AË`dðdq'QèF¶¬ÕÂ)çåOŸ(kú¶…W»Š >¹úÖŠY“[¶î \³ˆ-p)hKUª~´úì92Ò<¹ž¢Gv¦#3ý¿ücév1n—3'+ý[ÌÍùcÇ=órÞ€^-o¿ïëRì=k¤QÖeÿû˶y›e‡¦Úú À àzQ'd  É ˆ4:ÀÚÑ¢žêrbïO¸Lè4_îð]§O<ð—ç_xJìôÉ?}׌l;»Åmb³Èé=¯˜mjõ´µ{íTNŸØcÉœOîøŒ|èÞèñÖêâüª©ã7/¾Ö¿á=ËÝ-hÿý£ÄÆMX´`šf (‚D ­®ºÏµKƒ{÷~ÊÔËîß³~͹ýzÊÁ°#+ãk×iåÙ^g ÇŽ[áîÇ^{ÛÐuWN–+'ËSVâíZâ-.tde$MêO!¥ÍV';ù´а]?LÐXÒÉò£S{”1ÁRÿ~‡Ô³¨2á› 8(Ùà(ƒ¡|·”Çnøª0öÖ¬eîÁ„Oˆm,§²œÂÒ‰íQÂQV{4±ˆ@ >9]ù‡Ï¤ëygñM-ñã-oM_R0l@ÙØÑB›_ôþõo¬ƒ%‰µÛîÞÚªA7_í-)üÊ#l¿ñî]wÿÞ‘Y=}bí?“Kñ“ØR –‚¶T¥ê‡¬ðî/Ü¥Å\FÚwßíÀÓ/m^q£Ëëqggº³3¹Ùî¢|Ou…·´¨xÔÐÿÍ—N%%L¯­ÚúГ4qÎHª¸àãk~æܯý÷»c¨ÚèfÅÕë@P$¦žèœ€¬ÂP¡Ù€ho*DönÛX ÏÕuúÄìA}Ÿ­f„µÍpÚÖÚÖ‚m±Ëã„‘[È9tÄÝ7h‚˜ÖÒ¾aÖ2È>°~éœ/~Ú‘Ÿsþ/Ÿb½%sä~xùµÂ#O—&! š›8‘¯™|R_yéÀ»®~qàð__`2Ò¤p”ËÎl¸jan¿ž¬¾ÅŸë)Êï2vtòÐÚuû¯wÝúKÚ¶M©_0CÅC>+5µðM-m;?c=î†%—6\qé©õ6'¡Í$ ”-¶™öf‚mc€%Ð-±Í¶üHø´™`~ˆ]gB¡å …£ƒ£ E1Fö½Åš“‰,> à‹??ùáµw¤•—:2äÄö¨Như ³”6Nc9 ,Ms:Íg0h¸$ÑÁÈiwN;ò]Ú#Ëp™é[.ZØmÖäëW‰í‡Ÿõ³_ý©û‚é•e;×ܶP¤#0©À1-§wsX¹šßØôÖ…—YÇRÑ™#ú®[`»{N?á¡oþ^t¼Õ™›EsÜO×R•‚¶T¥ê‡¬—j†»ÊJÜe%îʲ´Š2wq¡« ×Û¥ˆ:ùüÙ{àÕq³ÔÖöt€„"Zcs¶¨ añ¬n³&ÿϾ€´Ëkl^s è4uì­Í¬ÏS0ù¼Í«n¦Æî‡&Çó @& q¢¢ÃèD` מ?“ìþ¦§¾[õÅt1ñýù«7ÍXJÛoÃlÛCD蔋`[Ú >½.»¤ÛŒ‰ÄŽàƹ+UYñ–• ¼y••œuZ—sF&Î>.çVO¤1@{ Ïzòus/‘ƒ!¾¥on‹µ´éªF¹œ}oX¡Eㆮgö¬;ôÂëÃôYs…ŠüÉSŸœC ûímºª~|Ë}îÌôíkn£ívjz}·!w\×üêÛ‡}–é4cW}É„ª©ããM-_f~¼‹ñG`“€fo$Â(h€DT·Ú£æIíÑBió­*O@S—8J1”ÁQ¥¨,«±LîŸ u7md¯6]óîÎkïÉ´C×9@¥\¬È™JBl£UŽU9N59“a­ö((δt`·,pŒÂqß ¶é’L;'ļiW ìÃ1Ìþÿ÷ø¾‡žà[ý£º7ºýÓO×Ü67L4¥³N•óWA°¾ ÂÝ\õÎ…‰o2Ùƒûõ¹f ãrnÇb~÷èL„tÐ ÏùÈ¢?°íÆ»]y9®¼gV†·´ÈS\à-)úþ«ßV†¦Sÿöƒ|×RÄ–‚¶T¥ê?R¯{ªLp¼Uÿc.7Ë]RäéRì).tçf¹ r]ù¹îü\gAÞæÙËïm͵ó[{BËáàú]9¯h̨j¾s|öަ\¹î.%®üBÓ'ÿïËj\¨=å”} ¥`ø•ñ—wìI´ëª{­^œ7tÀë/Ö:‚ÉTSKޱ,ge  mo^Ñ„lGt[÷©±D['£»—ŸVé¤q‡zòÕòÁ€Tic3owBM+)Áéè»~eí’9 €&JoM_Ú˜Mó¸w}þ ¾‘ž*`¸m—=¸¯ƒ¢”CGµŽ`þà~oZ¥ñ‚ÐÚη´Ç›ÛÔ8oikX<»l솪~rûo޼þÎÀŸ]Ómæ¤çêG!wÙ½ëû®]ºýÖ_øË³{SÕÊWpæå4,˜þöù³-P3ìökîÀÞB{G`×çU?qqUTÇþ˜2›¥´Ú,hK*m&(*1ôFë`ÙRÚÐ Úh†Ky²)>ð/Ú×rœ"qN° 0šÌÒªÁQG¹ˆÈ2ªÆ0:Eë„6¥StŸU‹‰”ÃÐ&åbEäÄ©ÝÕYbe&Ú£ øL¶%{« þ©ƒ‚»¿Øÿøß\9™î‚¼ªéc‡½1eaü‹ýáw?`FÓ4Úë)Ò¯áü˜„!눂¡Rˆ‚âŒÄwkGTÌ{Êž¸T·ãõ³[z2­]=ïsÆ ƒ2Â#hZ¼ï‘Ö¸ö±½ƒóùœ™éÞ¢|Oq»´ÈS\X¿pÆVfžK3™P&òˆüS¯ä¶[YzÖˆ‚“?)-U)hKÕ)WÛ=U`d¤šÒtòÑ ùƒ¼?ß±ÇàrzòsÝù9ÎìÌÆW6ÖÙv_ÌÊk²z[Ž4ßñç_‹ì;à©ìêíZê..tæ9ós(æ›äè¡c ðu)&4}àÉ·ßü ‡({êªÜe®’BOq¡;/Û[RäÌÍR"± óV 8øk>«þ­;ÝEyîÂü¯€£/½Ótåf§U–9sÿã¦PûþòìGëîVCa+9 Ç‚½W/vå¿1íŠÈöO-@A'ÓUëŸ.;Áú㮩`Y¶í³} (±ÓH%[6£‹ jV.,™8öõÒþ ȱgãtÛÂ#<štÑ€šË.&×ôêÛ%cÏZý›—®m~o« \¿2©®Ðñ³Ü°±/ˆ×mî%½ë£MÍޞݹ̴~×_iÝY†¥`X—¤Xcsɨa–è²ïÑg=õ÷1Ïüñ“+Öî¿î‹M=å]h–}錩V¨—%«$D;BIþxù:ج¦Û£ëÎÁ·_Û™ØvÝó•ÜÅYÝk †ôûñ JHž´=štú0ŠšµˆœØe€%`¸½CÊ848NCrP2Ck–Òæ6e4–Ñ Æ ”A(•f3u©w|F;t•# ¥XíQ…¥Û£GÓœN³Fb8í>›øã™W ¿z¤Šæ¸¾7\Y5}â¦9+Ÿú»uÄꀮi àŽógý|B¢šàAD“ДӰÖ&_AdûK‰5wibaŸ‹=nÞAËz˜6Ä’ FÖj‹¯i;iߟþê G´p¤ãð±4íî6_ý»è™lˆâˆÂ±Šƒ‘YÔ©ôßýêÅ›Z`šG^~ëÃë~úoÖ™Ø>ýaèŠ ÏMáZªRЖªS¢=UÖp’¯¢Ì¬,S33ÔÃÇÌm;““Õ.€‹DI;ÒØëHcÔŽWr>»±eMY¹€¸?öŽ𱫤Ð]ç*Èu×T¸K Îüúxõ-r0|æ‹/´jhR Y@hnóë[wºòsÝÙž’"gn6aè¦[ú®¹¢ºÓÅ€ÐܶiÁjWa¾»0¿aÉ¥®¼œŽŸ¹r³¹4oxß¡·¦_Áºœ¾²’a¿¾õ‡%6Ï®J¾×W·óš6¼'´ù»]|Ðæ·¶×Ï›fñ·\ycÓ ¯[Þf” mà­ìJslè‹ýVÔUÔ²ç=gdñèáÛ®¾5ðn f«qÉÞhùèa»–¯kZ¾®Ä~(Þn¹Zùô[ccíU‹„¾|â…~?»¶dìŸÜùÛo¾—¹ýz6,šY3íÂH䩲€É¾wî¨>Ó'–]x®e¶wˆmE#‡$ïïÈʰ ²j­[ŽüíµÏþ;WcóÎóf£2J‡…s§ù”h̰o´\!|i…ÃÈ¡ˆØÞÚX·•6è±dÅ0G^xÝ•›­ â[3–H1ÞU”?üž;Ûñ·ß§œ;/Û]Çzÿó{¦„èÄê(mv‚6ëÃs2´±I×NJ›m –úw vêÖê¨C—”L3º¥´¹uAeXat¶ M¡9‰uÒvèàhÈ”‹9ÊnR‰ìQ•ÓÛ\—â€ßâ$hãltã°l‰ _Ö=ðˆ§Ê xm‰”fõ"öW Ì ˜"A”d‡yâÀ D:–øÂ¿ËËø5Ä{$ž 3BÌ0a4Ñ5&®3ò¯ç Å“s!µÆpÈ<{û{•l˜2”ƒ•ŒÌ1 e.¡š(¦µ}#Œø*Bmºü:ÓÐ[>Øž7 ÷¤-/(ÁpôÀwažÐêã’Ëk¦_Øsù<ëž»÷pÁྐྵ}{¤ˆ-U)hKÕPaO•Õw“®OƒçÜQ¨(Û?o•e߯•b"³Ûc¢Ã²r2€|$ò.‹Æntd bM-Ѧ–& çÊ…_'¶Ï~ýà€?üìLºÍD–è${‰’D_Q>ßæoûøS}®¾|Ò–—3q…Þ¸Elï8üç'[6oÕ‚ÑÃ{­Zü|ÿ§W\ÇEãInûx—5)ïÐkàí×y»ÿ€¯^Æ.À³·’¯=‰Û †öϨ.Úü|k{ÉÃYÀ'?û•ä*u厠Šh’ §³ç•óXû£~NÇ]4zxûÃågÖÿºeÏå÷*°y+f‹gŠ­ÆÑ@àÑg­; SÚ©¤Ùð¢€Ç~ ëRêrö½þJ6Íû—êábs«¯ ¯áÊy —ÏNÊ“qñìæF»»Ó¯ÖÞüé;~îÂÞ}võ¶ ½uç}Ï|ý;û~ÿúFlÛl°a¼!t´Ïøü¥¦”é'ò]Y”ç^.<÷²#;”¦U ,`M:|  èæpyZ»4QƒÇ xÚ˜™Zð€r²8?¡Ëž7+#¿ó>{öt{z¡”‡a¶gÎNÍ3Äb¥1UN0éà}ÚöÝÝ)–ž½öFìôÅKº÷ÜŶ»; Ä»É^›Äq²§ß¶ãü½¬¾äc>Oq¤€Ú”Þ>·²yÎô?NµÚšÍ¶V»«ýÏ<€TåÄ¢@2ë§9“Fq›j™ÙIÆÄÒ+¯÷쵬mÁœ`¸èŠ~¡ì æY/¼ôœòÚõœx¾t/[¼ãåç•Öoš¹êÌMwÜ{GçÂŒdÔø¡09hrò ’Is@cÀ‘…,I° „4͘úâõß­l €ÝÞºËõWH?îq”õìKàȸ]Öë?í¸)§|Òìj7 ÚøÐcÞàð6C¿jÍA'%GúL'ì¿Gáíõ<_Tmk—/]ÚÔßç ×· 6æƒR%ªÔ:—-ž}ƉÖþêž'¿ø…—œÓ±ã¼ÿ;邬üØÀ‹%§Xr%_È€ž]—lyüéòëk–¦ú¦-«¿ÿS÷Û}ÁÊÓrQtþ'˜¶´ P(W@„dÚ”4Y71"$L› ’iTU¤9mìO€¶L¶ J@) J2ÍS2änëk3†“é è4$š:á:µ„ÇTe,Ó†(óÏ9€•NUCK§œóøOøþšç¤]X±ãúÃEohØÈO>ü€'ŸÝôð3?yx®¯wÁÅgê9ã¹—ïÝýHCÖ€Ž $›jÙ¾Þ¨\å¥J  Kc侚tÊBªèh²ŠKè!ò/¼"ä&ÙNW\0‚Øþ˜é'@Q¢Chßg×§ŸÐºÛN/ÞðƒÞöìÙkiú(\/v½‡Ï¸´±¿o×ë¯ûHïÊô7Iv-ñ¨6í8×ËÎ-oØÜ8\ôó…E—Ÿ7‚¨¼¡á°Zó‡KVGkÃÔÉ<Š\¾ró]îó×®9÷³y™c§Â…2÷„¹YýZ6S}gCþ™…±ëqÀhlXú•Ëg¯8þoöG”ɼ-2„€*‡JRÙA*@)…*åÑ$nwÔ=*A[â}ÿÔL®…@§ IÍ<%à4Ó §Sõ“©FlˆÀ¤¾Î$h3¨É}®ÑXSyL9¡Œ(\¡†Ppjpè$m$ÔHÓBFškz¤hLÕÑMh¶„Qm†IÇ€¶ätÆ"éX™ u*Àl³%\kÝDcA *óìHê¬ BxQ„¸\ Z-R˱ÝàŠ*!¡ 'ž ‚ùô! Ô±þû“,ÏãÕÕж•€ñ2UƒØÔ}] ã‘Z-ËÊ6(u4rñÁUüÌ4Œ7ßyåÜ+Z§Om<æP¥½uí×oJ6M‹¯¼.^y=Qð—ýëçú=ü##¶mÎ§ßÆAÛøŒÏ‡˜™~ä€FIÀhÀd)S”$xZ 8@h³P#ȆPPV4€‹(†Ïáp”iÒÕØbAd€2P,†¢-„ÊQzõy¯¾Qv&p+ˆb°8µ‹Ud/ŸÐmL›rϱgë5'Ù^/¿òFí•7’uÈÇÍ ŒÆ#T"PÊòCµvXufþéç¿ò* 4Ìœ6üòš¹gôg"6 ¼Zv›ˆ)(x³WÚÞ?ãŒÍØI¡Bä¸V[óŒã ”vì¼oËÐÿw®¢*=íã òo½S/”’·qL;æÐL_ïêë¿›ð]u€È}/Ȇ,zÆù³´æ&w0ÏëN´i€Jvʬ ]{ì2ðìKS>$ dù]¦_—ám‘LiÙiáœËÎÝpß#¯úâ>7_Ÿ ¶M?¾þ¾G¬ö–?~áS:xñçWŽ<´‡;E}ø‰Fé~pÖÔ0û´æ_|†ÑÔØ:\ð‡[e'i2IXCc€×o»ãá³.Ë“€õç~V\ &uPàxî`¾>óXtÅͳú½|Á/”¼¡aw0ï æ[çÍZúåϼg˜ó;¿¾ßhmÉMêÉþÅé·”fS@P)h#)Á¦Ðô‹œ¹âF)( (IN… ïŠÒ^š@C2 ÚH¦Yo¹ÅWX1˜Áƒ:OA4XÌ*‰U•S ÚTjhB˜b0¨4m ´d§$ñ±ªÇªÆˆ&ºõ ´)òÙfJ gÈp8mÆ‘/±ŠÀLdvœÇ2éÇ‹`²ˆ Pʺl·u!|x¾÷Ñ8œî[0 Õ‹µJD»ýéÃ$„;·:ÚˆòÞ,ZŽ×âH ,ƒ@„ToFo >Ô/BËØý} dIæ÷^©5åvûÆÕÞÐpyÝFÒ×›Ìû…RX,Ï?ÿS÷Ýí®¥‡k’JLl"¦$Û 3m²3T¨×êSŽ>dâAûøÅRíÕ7×ýèv*¹·˜z‘3N;þé¯ÜбtGæy¶ÏOÖÆË@ˆdN½Ùө勲¼{ï]—œ½œ—Ê…çW?qÅWóϼH(êNײŋ?¿2I›ï{ø¹cδex›º6å„£¦ò‰Î¥© Ïîl·;ßW~û®ÿpÖesäªz"ΪÝ‹.>33y¢?\tóΖ¡úæE—×±ó"A©ì œ-Cî`Þhnœtà^ÉM…•jP,Û=Šalxàw¼òëö„®æYýK¯ý¬;˜zú³µÉlk±ÚZÿu)b££F©ó`ìN• MãÐ’ª+Œ2mb„i#ÉìÒà£c-Žx™LÝcÄ.˜%yi¨.<^KA[Âóàù)—¬:òUˆ /?oÑeç¾»b ãlã3ÚÆço0ÏdúCÀ”lJbWl\ »  C] ¤¢K…¢ÈQ#ha „PA#@ <Ž F `¨ó3´«`.¨1C-‚¡.ÐKPà€ä„O#õmÙ’>¢c$‘#Fˑ஻ "ˆ<€Áep”ågiGJ´ª¼îôÇ-ûö—"ÇÓ²ÛÂ…;ïkœ1µEÊ—ÉøØ·n"£yrnÒÎ]uV[‚ÏŠew`ÈÙ40ñ€=G®e47ÍMM[·‡=ÿµïTßzÇêîÌNš°æÖÛóϾ$€¶Åó—|áÓ]rÍÀ“ÏZm-v{«ÕÑfv´fº;·ñ ÿY M$FUZ  ð­˜6B“<URІ‘6 Jdµºœ¤N>1™ê! % Dˆ´>kó™Ú´[¼Lèz`Ð@)hS•Ød>Uy¬ª‚ʈrׇ/Ð_¤œSƒCIAQ…ªÇšj$jS5¦jLèc@[òáI“L[ò…%­ c@½ëN˜ój6u©Ê3—;ÎE„¨gDè.ß‹ˆÀø ¾€/°à0 $ÿøBõb^¥Ôá$ˆ¹+à ˜EÄyh?-pM‰,Ë K:âZ%RãU˜Š/´˜9` Ó–0ðux jD‚7Êñ×R+(ÐwØ;|æ¼¶÷±üÔ2™þûÇÕØqÐ6>ÿ”ód¦ß¦TÒ*&ÐÔÛÓžßL2àÉ"£‚ë(…ð8º@VÀ#`*(‡Å!5D6‚€!`6EÌá x .A·†Ø…bPp'B³‚fŠº@QÀ, IG…¡&J¸fKÕÏR/Y³Kf¾T É! Á ¨ ÀåÉbqJ³y’…JÞ_еïn ®8Ÿ(Ê6ˆí•ïÝöê~¶ë7¾ ¶Â3/–ž_=ðÀ£oþöA4Í9ýÚϾßKvG0´&;.(ãTåDMNYÚ4?ʼ}çým;Ìö‰Ã’o¦Nn˜:cªª,‡Ÿyqê1‡xùò†Í…sÜêSÏ9ïlhÝiaeýæI‡í?óœåå·ÖuyPDzÅîÜùÐú›o'ˆ6ææ{ÊœsNyþ[7?|Æ¥0Ðåæ™¡-–Üñ¤¹!±A”×ml;hŸc¾÷µ»÷<Ú[¿©aòÄîm~àwÅÕk^¹ì_2Ò5FoÏüÓO˜~Úñ/ÜøÃ¡—_3²VW‡ÕÕ>a¯eï÷À=gïÖu¹¤€vµïpáió.:# þ… iÞXu¿}PxþïN»„q]S-3¬ÔÝÒÇöÞõº«¿äšÚúM¢ôÊ뛇 Z.»è’³ÿ\Ä–¼,e´0^aPTPP2Úˆ0m‰¾©DcÂu“çtÒa¥Pú MEJ³é‰©N:ÚyJT3ÖƒêܤþhÓihÅž¢²”iã”jè¡ ˜b0SóÐÆ5ªèq**q*êŒéJJ§é2YÚ,É´m Ú´8Ê'#‹zŠÂ„J2?uJûfj"D< Àf Ì ásø öPF!8DêRð@#^Sàr¸jq´¤(¦é‘Ä4¯Ò<'u¡Åê0u¿¬€V jàx¢?BÀAjà„>‚u ”«{B¢ww.¹zÕûU¹ü}ýïv§~(÷ßøŒƒ¶ñù;Ìï3ýè—™@3иdaÇs/ÜíMÅ­jŒ2ƒÇàr´$‡éCk Ÿ‚0„,Ei:šc„<ÕÅÚ5åÍ %†N‘S€0u›fMt¨ sTê"u;r)¼´INDˆ”;|æ|5c¿ßñ4…ß ÍÊ8Õ9ÑDHÿ¬êþ#?öžç'YÄŠ¡wîºDpî Ú ¥ØóVëæz©²ìÆ/×6léëŸÒwâQæÌ°ú?~üÔ¥_Yb›rÄó/<­eÁì»;¥þô ]€ ‚uù¶Ke‘¨/)ؤ>æžv¿mî>¼V×sYkÒ„)‡íß¿56ª­ß”ØM(}õÛ· îÚféL[ßñŸsÎ);-ÜÎãöÒ·o^sËÏâM¡`ƧŽå\¸ƒCî@ÞÈÛ=»^wUeíú¾ä¼¡‚—v‡ }GØwø¿«4¤MÊ£TIÁ™JAˆH»GiDHè4¦çÓ“)Òk%àoT `m‰Pèbt§-9ŠÁlê 4Б‚6 žÉ|F±¢rJ¹ ×W.m×ò†žî´%ˆÍÒ¼HרÁ4-mQ²Ð¦êLè”Zœt[ÐfÊ/¬­A› B…]w3ܱ…kQOUb¡BE½†º £V‡& X î"ŒÐ9Ò² ¥  1«TA8 \ÃÎÃúwÔ‡,êpÍŠX4ÏižS«q¬±§Šº£ZjàEÔ}x1ªÌªàuÔEê%­uUí=þãJÖf~°Ó.±:Z·Gý¸r}(ܶ JK®>ŽÛÆAÛøüãν™þ6`ö˜¨ý2à=ª’ÝciãÃ;&D„\/¨1j1ª1ê M@>bu†& G,èP…ˆt¸!| …`€£D1%†c€GÈ1 AUØ °Ô#Tx1J@I`2àK^­Y7@ˆåÛÄIÒ“/BÄ „‘„e¦ªhh@ÿ'Î<ㄇ÷;ŽJ[ËN×\–¬@xé†[þøÙkUJÏ]—5‚לuv)€PAâÔ¡9íSÇN=ó¤–Es“«Du祛~4ù}[e`lŠ¥®Œæ8œhBUãP×?†Í÷ûÅNLB©ÝÕnwµ?÷µïTóÞýc«­¥=fÙ¾ÞQúð»?Ùôÿ~߱˵-Cã.ûÜʹç,pïa§ºO¿³G’ŒTäËJ(#yƒ1ˆI‡Ê†Û~¡¾‡8ÑÊ6  i鎃kÞ↾ôÊ‹'qàÝ;¡öꛉY•«JßQ-¸`ÅÈ}{õ–Ÿ >õœÝÚ¬+ʆû^VVA¸RT]|ÒQÓŽûøváç^þí~ÇêA˜¤™L0%äh³*^†;ád¸cR_S#¡…°Ýž{õæfÓ<†&ˆ=0¹i€‘ö$k•‚€QÐjjQPTsp9Üq€x¨€º\ó#-Œât˜Ó»n?Áö·D?ã`k´ÏÿÿçžLÿ|@—!‘|šXûî–}àѺ —£¯L òypc¸xÈ u4 Ô˜€]€-@š¡Åà>š4„Šn‡ ˆÑÊÁ(Àa$2 à…pCÔCtñTZ©:4 ´KÁTú$2+&!d!jrSÍ•y­ š»;º÷Z¶îæŸþîæŸz@@È×\:ùÐýT×®¿÷°Sœu/œtp@EÈÆ n\ÚÙwÚ™'5/š;üÜËfkó[wÜûü¿}o¯ï|uÄv¾öûœo?Ù½”RN 7á›ð³´žêƒßéÚ;îcQtă?÷åŸy±aÚäi‡Ö†ê[†æ½¼qÚd,_­ÛØ<±›UjA-½“ JÊK§‚9iBmý¦XæºQ ù'B×}û—÷¨2F¤)‰¾ëjŸqæÉŽçm~kÝîßü↻|ê‚Ï«2Idúòcæ÷©Ö³!Äë?ù¥Ñ}ìÓ_ôòÉo* ˜2–Å̙Ӟttÿ©Ÿ4ÛZ¶ó <î“›5{ú¢ÇN?óääÉÓ0mò?šúð£Çg´Ï_}nËôOféJY³€ táV_`n;ŽÀGìÂáÆðXúŠ–ä~%-('y`"Íε²ˆ=PÁáÅ(y —¥’e†Ã •ÂÓaÄ ÅhaÈ T¤ši €”€©re>+›€€‚\î4 4 ˜Mìk‰Šéoøù¯“þ-cï|åE™öÖêš·ž¿î?ÖÝó«ÕOÍȾ-„09ªÜaˆ˜pø}ž¦4æ<ö³­yÝýL>üÀ£½clL«ý‹~ØÈsÃze’¥x:B,m ¨ššŸâš¿Úð(êZºÃÔ£zÏÿm_¼@ä¸î@¾Q¾ý¼öýÛ:—,h›1••+Þà°74ìË$ƒµë˜Üi‹a[³Ï9ex݆`ý¦„Tk]8gÖ¹§FAð‡‹®N¼s9yä³sf,úòåQ>¹|eûÜ™x~àmËÏ=EßQxþë7½vËÏŒ¬]}í-°¥ù7’á,›™z‘}'Õ.ÙÐ?9oþü×~I²õÈMsúIGõ{xçî;oõZi™Û ¶mæõÿú¥f/|ã?ó/¾š<r}“ö¹ùúØÆ‚¶9‘„i#é‰*)ön¦ [ƒ¶$ƒW¥ÐÓDÌ'º_lU@U‚¶„iStù1 )!–ê…ºnR´Y̳bÏ"^LTAÉåö×íÐ5´ÀЮQjpƒ¦æëF(t"FA[¬êLÕY‚ðÒµ6   ” ƒ“Œ"6SÚt@‡=äÚ¾k+nB¶é$dŠ"¢“ú•wú†¶/T‡°!ž¸ÈUPÃôÁ)P5zˆ†Á ¢Ú‡Á áDØïlð­s±OAë E®#5Žkª¨Ç¨+h¨y¸ ‚ÌG¥f—:0ã´ãûW×úþ ãþÐñmãó·˜ÿÎôÏ,ÀKÞ\¤Ô•¼?uÈÊع~ˆ †¦©e ×ê2VwP"™àj%É *ü”!" ´ƒ²D@4D*#8”Aåà14 SA# \ž†tL*@´J(’ mU êÀ$9› #ÈdýKÖMªŽ»æ¦Ùm-!ÐqÀž mûVª¹vÀ‚P@üTl¯‚q¨mS&e:Ú9ð„* €Þƒö9ð¿ÿ³cÉ‚÷8¸´Eív¡…@2pr¨5¢²éÞ‡2Szí‰Ýz.û×øÍRM³»;?ø2ZÆnCL;þãa±ýÁ¼Ÿ/ŲÂ×¾óÃä· ìþ)sÏ9Åœ2ñ±oþgÂÛ,\uÖŒ³O~ãgw>Í7³€@òµhnì9ü€5·Ýñö/ïV~­” IDATú «ΘØ=wÅqsÎ9EojðÂ7þó™k¾Iej¶½5¬TEEÒâ0á°ý§ttïnÿÃÿùì½ÄúM ÁÖ}Ð>ýŸ:vÒ‡\M{ûŽ{¿èj;cW×obÀäí6ÙZúÕÏf{{>ä/ƒŽ‚¶Ñ6–’m‚Žî´QJ5ÆUÉÃ¥L›JAyT@#)hcœÚ8(ÆS¦M!£;m£LЦhÌ ®„DÐ`ƾÉ|Kx ŠPˆE=E°Äˆºb0‹2mB'ú(Ó–à¶ØÐƒÀ4R‹(E6®3(Œ*LSbKÖ¨·”hÂô|ÛwíÀµ”lÓiÈU*•sjÃýFð_ê|A9›BœaêÍÐc0Ô‡ª-¢Š1jNˆýCè>”XЄGZ¼µ{” >êÜAP© ¨£"öйtçü³/Õ\Ïš=}׋Θ¶ü˜–#ÇáÚøŒƒ¶ñùëÎO2ýÐ ÄryŸH¬–ì05JlKá¹ü^”öGUH2N§#Õj´%Ń€C0à"eM0Ô#YWš\®uƒ)ÅÈ(¸áÁ Q: 8ÐÔå~ $øK„Ú"иr%‹mRÂKbA,  :P¨e¶~`Ç'yüä —½¾¶©È" A  ¨&” „€Ø*H„™…;(Ëm'E’@!Ðè@“4½&vÅVÀr2v@—ÁŸžŒ©møÒ7s_úæ 9£A€ØE†¤¼œžƒžE®f ™<š# ÃÀг/Ù}“§žtÔØÃk^×  Ps1t½˜”0mDG؈J#* ¨¾ñ‹…˾©ýã ¶±CÅhkyî_o,½½^›ÐUß2¤å2»\ýéÙg/gAð·ožrȾªe.¾êâ—oúÑ/ÿ²)d$UÑ)Ÿçyý?÷ó¹Ó¢Áá)Ç Kë6•×o¤Q¬v[Ëì+/*þïc‘L@Å@#æˆxšh ÈIåÑ•´V(Ý…Ð 1`“€ªÄsŽ\žKX·ŒDlƒ€¨€¼1)à1D >CI`&%€ ò*IÖ:$j e€!;¯&YçÀ€&º¬Ù!"m¸Ê*Gc+*à!ŒÑÞÝ€R·‰˜BOØ< Èí°-ìîcí¯_zíÒÕÙÛcÏ›•Ù}ç¿û“ONx&T`h@’™Ój´À37hkDeÍ 7[“&ÚS'e&M°{{ì‰=™ °ˆ6ôئF£¹ÑœÐõ×~¶L9ê  Xö %w`¨g 7¦Ú–j[™ Ýù§_xòÒ¡RÀ9§Ÿ0oÕ™¹¾IÞ¹ó¾MþŽZfäù Ó§.¸ü¼Æ­I¯æ¹3›çÎ Šå°ZSmëá3.µÚZ^~ž7˜_tÅùzcÃvÞÕÿûê Ï|å†$b‚©êN×\2wåé„Òõxï?üSù‡KüÈzOç¼sN™uÚñª½*¨T{è)A¾ØØ×»ÇM×nu]ES$)œDé*P(B4(` fùA4Nu>šÓ¦ReLa¼€J ¤@:@!ÒÄ@ Š”iÓ N(ÉnœØ ·Yª§ë!Õ8ÑÑ„É|“ù6qyL/h¼Ñ]AHbD 7}ß&®¥y:¹Nc]ÕÔH#±F#¢3%ÑFM®˜ÌR¼,¯giݦ.4†Ê„Çj‚ÛAã‘Êc3ôíÀµ×ŽÝ ulîRÊ)å a~Ý$¾hbåŒp2ÔiàUoËÁdÆcQ­Fât? ŸÁê@S‹Â±¡(u‘Fàø!”*à¢@Qå¨2”8|Aæ×Ä€ÝÓµã•5ÏœàýÛ³kÿDîÑí骟qÐ6>Ï™tÄÿ÷¥s6îuÛÌóë›õ̓í®+›ÿߣ³®¼¸¼zͺ»äRj\8çé·Ie deç#—©ª¾ îJ”©P\@&e ¶yOÞx¢Ï  ”ºj;PºÄˆc€ \‘þ¯ ´y€Ír%N•Ûl\ž„LƒJ²Ë§H/E7à-€¯‚ hš€Æ ih0:C9@zæNÍ9á®®…hÔ€È@³Ä›¦î€I[8{æÙ_mTž}iÚŠã¢;ž!YÀz±9èɪu¥ÌšÛK$9iˆ¸–x 7.ظï/¹¢Ø“'Ú}½=ûìº`ÕY#¿/ûcýðà C¼òæÛ·Ýñò¯7³¦M±û&Ù;ÌËõOÉôtZ]Fkó_ãÙB1[›ÍÖæ¦ï!/ÅòÛwÞÛ{à^A±äæ‹ÎÐ0‡ØùÊ‹§Ÿpdr7~ò ªiÓŽ=¼¾e((U_½ªm‡yïùƒŒ–¦ÂK¯þáŠk®:£ïãsò¹É·ÿ~¾ô[ë¶L=ü€ XÖ²‹¯ZÕºp·z¤¯ÝüÓ'/º:Yy Yg<çüO5ôOùP7òø%׬þîO`ÆŠã–\½ÊêhÛê¿:ÚaE1ùA5¡&Ü ”ê\Ѹ\w#Ðbº5h…Fp]P¨ŠmÁ¼$í-¥”h #îQ"]BzO×C¢ ªqEe Íf—‡4£8†J =еP1˜éK¦M„B'D#;mÐR‚b2jòŒp2Š“Q›ºœQ%æ*‹•(Ö¢HƒŸÊ£F$ -Ü w2Ä!TPÊU“šÐÂ(Õrj-§W-Ó‹w[Ja±JA¹,((‘ÍèLlIÜ êˆbx&hŒš¥½‚@ ¦¡ÊQᨈb 3«¿eJ¯³ep—k.°÷®ÛÉ`½'¸{æ8e5>ã m|þ¬yõ‡ÿ¹Þ¿º¹±Š?\l.FåjX®>¹ê ÓÎ<é勯fÒ‰³W Pª Òb’Q dTâa¹•*^¾à ×òÅw6$&$h”$ŸG@ Á4-ö¢ ‚ 8:ôh‡ FPe¨s0ÀšØ=ïŒÛvÙÑÙ2øÁMeBÇjã3ÚÆç£ÏæGŸl˜Ò»Ãeç&ßšm-f[‹74ü›ÝŒ7 ¬ÿá”H )©rH“A µN.Ë‹FTÈHF/%††¤4qk–åº[²÷Æ€Yf”З¥¡!aÎ&(Yy˾ô7Ôä…Û2@È ¨ Ð%dTð€ P:ºÐ9  ± ª€Fð#T#ôÀŸ;K,š‰Û~]¥¨]:xCuåù##Ð=t,€¨‚×”~#LQ‡³>S¶š¶tt7j¢ÆP_ÀÂTu„ædà´4Ÿ(0ﬓͮŽu÷üïäCö³÷ï‡ @T€*âÜwÀNRNÊÕZ¹ZÚumö+þöˆ-V ºŠ=ßËÆÔ¥‡'cg3vv;X˼™-óf~´»á ³ ÌN™Ø¶x¾¶ÝöÒôºùÂÃËWòjMÙ¾I³Ï=eÖÙ'¬'nçܱçÑ¥g^Ôîý÷Xö­kúÞé™ïAÕdI³ÖÒÆ*Ju®A·Þi££;mM/L®‰¡èH±— „‰XHÒt·¤3^£Ð(….`H¸–”"ˆ‘—]tÝwþë|¢ ʹZLË7™oÃå”fG  =PõXBîÓ”i£iäÇhã:>QþÕTm-%œZ<Ö3Š“aŽAÊ 0®Ä±š2mždÚX0"ÚÂm´ÆyjA” jj%§Ôr¼F=ÞxƼ§¯ e»X2óE}Ë 1Ðï tÆmU©=ýB ø2ê¹y×Åþ¦çÍw‚uaÍG¸n”òýÓOýä¬sOmž?ëƒÅãþÐñmãów˜±kIÉ<ºbÕÚÛï2 }î+*·8ùÊÆÍ ”Òõ›’, !×ö"-‰çˆ%ÓæË,®¤ýÓ•¹ù60âcˆd·wRmÙ¨c2Z¹9—\~‚gºxû5Ík‡ËИA‰£‚DPyÏ­ôB4@ jˆ\DH/L ¼qV·f;êËqû”<€´1(8*bñ#ÊÞÇþ¼A©6uàÕ_üvÇÏœ?ùýì]úA!^‡¨9ˆ,]ΫˊOtïµlÖÙËEyƒyk ŵý´+ÙÜ3Oüs_k,ó݈ío1B<ºò*w0ou¶Ï<ñ¨p~·bUeÍ[fžvüÜ OkœñáL¦/}çÖ§¤ #;gúÂ+.xOÄ:Aœ 6%[”§ê§B¨&Ê)ÉNU@·fÚ %R÷hÒU* 'Í®„hIC¡Pä&œh<]zÓŽÒld4ò„@@×CêsÅa¢Îµ–ÐÒ=›»\¡8$„‹zŠÁLÇ'‘H˜6C ¶mL£ºêzHUžN–Ô3ÔÉ(ŽN´1%ŽÔ(ÒâP~jD0âÀ <;NåQ[u ¡G­ºàujq/ÖÍJŽ×ôjȪбöIç  ËÕl¡ÔT®øÃE8wÜ ÿsW,+O2@ë²%qߺß=4ÛTª—E”F %yË΋f_°bÊvØ\ÆÛøŒƒ¶ñùûŒ`lõM?¶ºÚ­Îv»½õëN÷î;Ͻ`…’±ò…ú–Áž|qí·¾/O²nÉë ‘6ÊXÖ’F±5Kw‚)Sì™Ì árƒM=H#?ByÅ@Þxìz‰Ó¶B×ëê2:Ä›@4E"6Te—ªh$‘e²–ž(ªIH˜¨€ 0ÀÖ@c˜Ôr ˆàozÃáÇpZL 2ôøà6äH.l1D¼ ^¯!  t ¢± ”A/o±HÕ 2¢„f{ r¨é5DYÔŸèÜõ¨ÕwìwSÏ«·vö{xµV·g÷§THá€×ÓãàHi8’®ÞÚ[מּá«·'3¡Ëêî°»:íî«»ÃjoÝ&ÒìÍÿùmP®Ø v[‹–Ë__û‡«¯Ÿs手¯¸àŸôÉüÊ-?{tåUr“&ìrì]Ëosµ¿ºGoÌe'tg&v'ªë6óø…Wnzø‰¶…s\rNß1‡|8Òú‘'î>ô5ÕÕѱÇ.‹>}Ö»ïÃV -‘GB TÝiS‚ … ŠÎ‰J„šV&˜Ôh”â«* è{é‚(‚+PØhË‚FÓFÀài é» ¤€áŠÃ‡±*DZsh©ÞÆÍÙ°.BB)·‰«Ì,ø ˜ ×R=!×éXÐ]ÕõP×CY¿ž¡N–Ô³J]£QêåJ«q¬F¾6´¥4[ìf„cQP”,«óÍiµ\Xkd•^õ†,Õ‰•˜)!kÚ¼“»ç›Ùi“ð Œ*µ×¾÷_›ž_0ý ·µ´žtÔàãOi'9¸v]õ¹—¢X¾>,ùâ%³Ï;õOÆþõñmãó·˜ü3/& Ecgõüø¹kÿÝìjïÙséâÏ­¼ï“9c ?sþ¬óNM:Y®¿ãÞ?|þk#ÅAI5—¯ñ‰CБ} ÉYN²„èŠcBW­P ü ©÷N N;@€Ê˜› äZrN S—SÙ¸E{ø‰ä±+?'É\†«%6ˆ¨TH£—u–¡Ü„s妋'«3C`*…0•€gAm ðCT:C*0ÈQáèŒA9˜míób‡E¨ËØ~¸à%ð"bjòz-ˆ „¸¤V¬¬Ro U¡ñaªˆQI@› 7+ê¢@šÒÒÜfõÖçÔAiÂ.¢ ­(ËåB!ÃM’ÚúÆ-µ[@ Ýîé´»;­î««Óîé°»;íîŽÌ„nÁùÝGn°(1 µ§N*¾³¡ãýúÅ÷ü-ƒ…ç^ÎLì6Û[ÿ‰žÞÃ/¼òè…W=ó"€E«ÎÚñ²sGÔá \1šŸÿúMoüìN³­%3¡+3¡ÛîlÓsY{bwnÒ„$k À‹ÿöýWðóù+O[xÉ9Ûßa:øôófSãÿ.¿°¾v}òÆîë]xÙy:D#P·6"$å©< Eaª`!ÕA)Ñ…¢sªs6†imÀ×b4Í0ÔDÊ™i÷ÂÄ:š,l’ѬC$;m„Aeí©d…Yñ©Ã‡ÅU¨øìKkï$7{z}`È/UrÀô¢;Îæ‚ÏO=öuÉBb- ¹Úæú@¾eÞ¬¥ÿúÙ–s¶®=gºÏ8hŸ¿äüöà“vþ—Ë;–,{féµ7ZñéÒ‹¯`ÎùŸš½â¸‡NºÀloÛé+Wôì·ûÈÅ'††GÚ ÎI\5öötí¹´¸nƒ?T¨½¾Ö„” U¹ÊÖ¶hnËóè†ÍÕ[ª›âZ=›rR)§JšÍGÒÞóú„ìtõ*¢ëÅŸüÒ9½®$öš0æ½IÞBbMèž21~gãb‹¥Þš˜’Ý»îP@ªÀ4  X Pd"R ËôѨ0äa† ¶€(ˆ€*MtVZ`ˆ4”Bôäy = Pæù-µÈË9ÍFIEÌAvÍ@ #Të,ÌŠúëKg,xîE{"Jo@ ÐÀ Bˆ(ÝáËË6Õ‰Ò¢Ë%[™€æÔ-„õ·7ÔÞÞÀE×íÕnÈF=>ØQ«Ð0uòÂo\-å‰s®°'vÛ½=K®^õτ؞_ýÄg¯wâ~»ïòÅKÚe¤74üü7¿g·µ¼øoß ËU”__ @ÕT»§ËîíYøé³ÄÕêr€ƒsë„1Ïÿž·~y÷ë?½Ójm.<÷ò”C÷{é†Ä@ÏÞËvÿ÷¯lWÜ®Ne#M?%F:Ê´)œP(”j :WRÐFˆ“úø±›:C~OO…Nbˆô# …H2DT c˜¶#Mù¶t+ŒjÊ´…¢D‘‚H¸Ètÿì}i˜TÕ¹õÚ{Ÿ¡êTUÏ#=A74ó( *â, €Ñ8 8!qN4×D¯šÁDMr£F3™“¨qºšˆSgEE”zªùÌgïýý8ušF½F¯Iî÷£ß§Ÿ¶û]uªºÏêµÞµ–i0‹{Œ^bÚG‚”@Û'vÚ¸,É£B¥IQL’b’“¬H‰ØÚæjà*ÒÞ‹iKpÓà–!,¸Â‡’Óâ_HJ)¤ÜBܲîíJÐ@PO„œ³±l¸uÇ…Íۜ޾ѧov÷½s÷}1 aî¡ _=þ¡y§ÕwÔð+WØÙ|}}Mª»ÏìéÕ++Æ-_ò_«Ï Ø¡Ûà ‚¶Áùç̯;ö›rõªyýúcŸ_sÕwÞúá h;æð}®^ùþ]÷Ý7lFÝ~ûLºbErhiC|Íy—oûåájNDôì!ÛBItè‚#&\pfnûÎò®ÞW.¿^‹vÔôò2­ªÜìêu,»åÐ&_v~ag—¶«+±«»²/½ë×"@ÅÔ‰ùL.³i³EAT“Å (Ù1æ‚3+ÇZ=û#Šçð"oAe´â&"95”Mç6düè·n¸5=H7jOêùõ#XÀ²0‘è‹¢F$Aœ d‹.<¦€ÍK}öMò€Ê` ù`½lS¢õhé{È}Cb°m¨4 Îáe`íJîÖÔ¬m§>Ô÷0²Y® Ÿ N,™T‹IQTì€K˜0IÀб IDAT¶,Ö> ¨šÁ¼$½³½¸»ÇÍÈ€—›ð<¾eû![¶ÑèF¢jí~ûuÏuJ(7Ǜƺ^Uñ…Þiî¹?^[¯­®™<ö‹îìÉq³ùâŽ]#Ï~0öœ¯H$èË?È®½ê»TJn;‰èa?ÈmÝ1å6¼?€—¿qÓG>>媕 ³ö}ÿ·ÎoÝaÔ×¶ý#¯èk7ÝñÁïöÒ™‘§-šö ?ñ<×uˆµL¾råç-HÐÈÞ‘(!6ÆJ;m W$s=B#Ó˜•ªŠ¯3·&j£* P”˜6!AAˆ”ŒîÚTJ¡ h¤ÔˆÞJL[é'0–s˜É©)HŽ07`ðA‘h6ãÄæSbAœØTºãR"B#‚Ê|©¡Ñh“þ1ÖC³4ÍSx¥…¶7 •ýò(÷™¨œ3áR•ï%&3!Mzù¬®æÜxÑEšJ’^‘v Ò-i¯`œ3Ή#KÑA9H mI¶ qÒÙÇŽ=Óïê­Ó©èê£ÓçVí;©ó¼SÎv¨âãÝlÞ/SC[þ×pí3>98ƒ3Úç‹Í «®YøêzÅÇ“H_¿å§ïüðN˜tùòÖ£æ<4}ž­MP•÷ûg=•Ð{ïGw…Ì 9‡Ôºû¼ zã@Û‚#&^º,ÙÖ¤¤’.¹ˆE\Wóœ™Îpú2N_&5´eüEg+F<™+ØÝ=›~ûàæ_ÿ‰ÃÏ/?zçÏC#Ú,ìËR"ÉrÌ9_·ê¬÷~ùÀk+®Ö#Å3ÄŽIÀˆ d2ÐêøÎ•zMÕÇ,‰G3ô@#¸DÚ®@X„¨z£‹:t# >¸߇Ía ˜@(úB#ª Î!|„Q¼"<¥9"ÑèÀ8…ªƒ8Ð& †á[u©nCZÔãE/Åb¼BÉêpÒ!ÔñÀN*Å­‡µ¶=³E™àW<ƒL>\öq1Øš„˜as—¦ÆöÛg‚d~øóÔ°Vµ²¼÷µu(±-˜iÖ¡ÿ£à@ÏšWƒ5¯†h¦qÖ´–ƒg¦ß\ïôöõÉÖ&ÂØ§“[¯¿­¥’‰¦†Þ·Þ}âäóÚêò޶Y?¸îߌØèeCçê›VèM$þ..š;v<éX7u2Y/ ë°„ï‡"þè3¿’󿄠Ÿÿví7ÔMŸräŸîzóGw=}þ•F}mÇñG>ãÄÏþ¦[_m4Ôv~嘺}'9`úŸ²B‰æÆiß¼¤qÖ´ø˜¹ëþ®q \÷qÐF ™6"¥¢&û™6IÔÈ‹ Uõ7>6´T`¥DÚ¨*ÁB¦-¤‘%#§Œ—ʯ4ÊkÀÈžµ¶~L« G¬~⹑Т@Ž(–Ïd 9Š©{nà)ZÜ‹S[¾p¨‚ dÚ¨"¤F8±8‚@rž€)bTW]æó”($Y1¼IBh¥Ä´ù*—LºD {¥ÈQ’GUêg2Ššóâ¦- 4YYŒ;&)‚tKÖÇ0ÎCGR`‚¸ˆ8œtáïKV½üíÊpcýûÛÖ¿¯©±ôäúYû–óbýÛŽÇŸ®j@é—G0¾g§ ’©\’Bˆª¡”¯«Uñ@c¥ì\EìaÚ”ÒN@Ág„ÛLƒ‚¶¨Q>”GYè¥!Ô+Ý$À q/–sP2K ø7ž{eÊ-¨®xŠF<ƒXÌáp Ï€S¢J©w§&——O$L©ã©b!ìBHP3AMA© {Âuƒ@á A[É=J-ƒ[ a2"›PónܶE‘¦Ü‚“žíJ6`œ3Á¹n‚A² &o­ûáϹi½sÓO<Ï {6s>pzÓý²Q¸Ñ¯F`È ; *ÊÇ\z^íÓÝtvÇê5ýåI-·e7l²{úv­^Ã7¼ËðÅóÇ.;­nßÉ>v¥÷®ûÞùñÝÓ®¹ÈMg«&ŽÉnüèÞ–©uÓ''ÛÛÜtÆÍæ%0ò”ZŽ8ÈËG.YÜûæú7oùiÓøQ›?Ü’;²wÓf×qÕ¨zÜŠ2GÚÍËíîÎnÝaíØ=ꌯŒ;ï´î—ßýÕã¼tîÝŸÜ«D6R(?*¿ñ#æ¸å¡†@ Ž©)OÕL›{öE(*HùÈS”‚‚í( ¸H`8à´J ˆdàB q¥|H Ì„j•w-@ñáduâí#²Â »Óµj*ÈÕ—Çúð1S¸T¸Tqƒ¸°ãªmVïI5ÉK{{´(aðÝ HBãhÝgÃÛoïíôÍ?ѦŒŸq˵u'ýÈ¡'¶.8r̹§¼qè‰S£¼ºB"#Òòxdb8ÏnÞžÞ¼½‘Ò‰Ÿó±×Ñ/ÿ4cþ°ÍÛ*È`åFW±åÁ'â屯:£¥±z˜ÿ£· ±P@Ôï·€Àvœž>»»×îz¾ŒÓÓç¥3VW¯ÕÕk÷ô¾ÿ«?J)']töÔk.bšöy™F6ö#¾OÕÏ‚k…ÍÛV/½$ÿæzb;Z;°yî!XMJzè#Û³ÓF¤¢r&Æúˆ¯,ø”kÕ–ír∓=nÍÃL׊Ûv>õ•e©öÖ9÷þÐíËš»ºÞøÏÛŒ_¹tÒ…g)É„š0Ì»…ïWúÆwo{î©Bañq#óïnÌ¿õnù¸‘ù]v:+©_¿01´9ÙÓ—Ú±»nÚÄá çh9b¶_0_¼ìÛ¡%¢$:Û§œur÷{›2ë6T†m Q:†57ÔŒ6êÌ“6ýü×J˜À‘'ð%dPÊu#‘IÂR@ÕÝ@¨mÉÊ\¯ŒÕ  (B:¯‰\`[fŽC_UÒ÷MâíŽS)„O¥J Ë2l+“; ˜Ããmh²¨IõšUhߎ"jX²$´å@Ô³12‡-;Ö¿ÿÚùWšç_9rÅM'Ì}ñà…í€åçå|´2¨ 0ájÑò_hŽ5ÖO¹rÅè¥'}ì¥|rî©cV¯™ ¸‘™Ã‹ø¹ì[ïæßzWMFÇЊq#gÝv=÷üM<ÒrȬOuŸœÿ]žÜ§]k‹|)4Zí%K¶6%[›pǵ»{Þ´ÝÝkw÷Ù=}vw¯ÕÓ7aåÒšIcÿ×ßz bKÕa>¶iàW_ºö–7o¾C ——<÷”ŽÓRUÅßiÉÚ))a äž6J™d*W$gREÒi‹äQ0(¤¤*Zd!:• ’I®È@QyÀ0mŒ@#%„Ê£™6Š˜ãĈ3­éå7׎“9ªˆ€ nØ–QaOž£ŽA¬pçÀ V¸ÓæX:í$„LÛu³oJn.R)4á%E1)KîQƒX‚Ðþp].˜¨á_,Ìå!Óf8–A¬D`&„if"ÃÕB Ú®áÙ(ø¾Þ Ö#3àÍ!0H2G6ú{¬¸žW•Ö£ç "¶ÁmƒóÿË<|ð¢ôK¯3 ý·”вÄЖd[sáÃ-¹ubÑú—ÊG ßï†+ò?Z{ùõ+Êá¾·> MÈRŽZ6êm_²¸ó¼Ól{üé¿_xmˆØX*9ý{×vœ¸ÀÚÝýÆÍwlûÛ û|ã¢ñ+–|jäճ˯*lÙqÔŸï sí×^}㎧ž›|åŠÚ©c5•ï}àÍÿ¼]Ãä é·ß ]{‰¦†·oûÅŽ§ž;ðÎ[j§OöòÅ7oº£¸uÇÔë/7{úR}Y««gÜŠ3š™Å×êé3êj˜¾‡yãû?Ûqïý¡•¡má¼QgŸ¼ã¯Ïo¿ó·åým6 5Á†9³:—,*¼»±°iKÀ["¢fÕD© ¾ÄA梓Ù-QìgÚˆ„Ø*TÌ…ãà J À%&o7Ü4\M)Ó¤¼‹… W*5„•°Ì8léâJæò˜ç(V€ +¢@°ªtH¤#l?l`;ô_ÂkCÙ&¸[´ºšî |tðÂ&ÀŽvÈ8j@9à tIÓ€xäÆ éø‹Î™rõJ%ø:®¿å§C®¹ir¤ç#ü @‚ú<À3­ú¡Í3¾{ÕË×}÷Ú׸åÚˆØ^»áG…ÍÛM ‰¦†X]ͰÏlµú|4ÛÚI$V›æì½Žˆé{¸ž>»»÷“Q8ÿKÔxdGX»‘8±ÃüÝ&»×¼úäIç;=}áb`óüÃÆ­\Z»ÿT‰c Ôz%%4Ô7ÈRÃ…B(‘ŠÆ™äLp©–ȶÒNÛ%aR*Œ”(´pe €^]¨ÒWu?`ÚÐúLCÐF£‚ùÒÝwãÂŽ3ÛS4-çÊe¾¿ú{G+7¥GO‰;NmééƒX±táz=*í$HÈ€W¸Y&9B^ŠJÖQ1mt/¦M¸T:dhs-C³ nÜ™˜Èªé©¶›ò; N º¡v êˆtž%n‚ä {*RÌœž>¹ñ¸£Æœ{êg+×LôœAÐ68ÿžyö«+výùqHD»_J2!9ßöàáo)/Ú¾ŸrÙùS._ž8h,-`Z¤ êA—ˆaϪ{HA5Î?läùKôšª¾7×?}êJ%"êÆ,Y\ìêýàþ‡×ÝzgŨá þúûêO+{‘œ?ºàŒdkÓ?ú–Q_»éyæ¼+&í¼c_øóó^ÛûúÛ[ýkfýÆP•Ûöð“³ïú^ˆØv<³æog\Üù•cŽ~ìWáŽðÚ«¿ëd²Þõ½òö67WpÒ™–Ãê¿§Z† ü¾ënºãýo@ùøÑc–/~ê ïþøî÷ÿóv%℉¿ ã±)W^жhÞ7üˆå !×Ö›úÑÊ×0 .Â^T†*ƒ‰E<Ô— @8.Àçp ¤"°ïxä2pTô–£:™-ôUPU:- %¨ÌWòxЍ+˜Ë5ÛCèÒ¨lÇGO£H2 R€$c#iSB²»@vC²Ý½±§ž«Šº(B@°û«°£j×0reÈQO¸ä¼ú½“`3o¼#f.¨ÂABÂÏŠ˜¹pŸ*än´v`²¹ñW­ÓÊFvìó5zE™_4?ÍoúÕ½}~ãïæÑ*dã3ºý†/G³=±hë?âÅôdËäÞo¡/5a hHœÝÑsÝß?üã£Ísfúù¢—δ/š?fÙi{V …ÂTÍ%Š„ÁX©NT¡”–vÚÁ… aT £tÁÂ^ÑÒN› ›¬H”…Ã8W…¯ižÍ⥶ø¶Ñ ”€—äQÆyÌsâÒŽQÇWT=ç"G‰ãg?¬0’––ó¨'¡ÄòsÂp¸tˆaX,Ò%i· =‚æ¹”\¼ÂÉJA˜àªç‡y µÅ* i¶0_W8T¸”Ù{äQ#nåä¤Èr‘åªåª¶— Åî DÞ Ò--*s(BË@Ø(…¨§Níh}òqCO]ojø2ìÚ ÷68ƒ mpþ9³þ–Ÿ¼yÍÍ1@"3ÔªŠá'W>zċ˯Ò8%ëöÛgæÍ×´.\ÅîꥺªW”ší©He{@‘$‘Xcšûý;~&ÈW¬•@Û;1oØôÉߺõβ¶f|D 00Jc‚è2dÚ4âùL ¤T•L㊊ä“DÑ@5Q‚á!hãW˜¯(PM–:ã ¢HPÉ®2_Õ|Mó5ÞO³ímýò¨$$Ƹ°c‰QG¨ÔP,-ç®}àš¥8æy’8±wç¬èÇÄŠùŽÌ!dÚˆH)ž]y²a[BPaÒ8³K.ZLP3Fhó#¦ÍW¤K„C©#tîjg¸–Á-ËŽ ‘ájÎSmOq<[Àv¡æ ºÑ gÁqÁ30ýÒúZ¨Øjç‰Ç´,ž¯–¥¾$\ûl78ƒ3ÚçÏ݉á4*Ñ%3ܾqòqÛþòÔë—\‹, Ä+Ëg¿újòýW-éB¸° @A¢(ö˜…:[e*‰M[VÏY䆩³÷Ÿ~ãU•£G¤ßyÿñÎn:hƤKÎí{mÝë×߯,7ÚšãõuÓö*ZØôÀ#ñÚª'-h;jNíäqRmÍʇíX4Ïܾó­[ï2wv͸ñêŽݵûŒ×*Ê7刚‰cN|õñOöjÄöú·ízæÅб§.Á™º^z㩯.qÜQCŽ9ü•kovøAJÂ`FlÌÊ¥©ö¶Ôö]íÛÿö<€ùÜ»éGߺèÚ|ª=`úŽwÞ«Ngë€ÈG©¿|Íâ6(|Œi#²OÀ•ˆ3Âà‹"i"ðàpzdT¶Áïf B™ì‰4Õ nŒ:ŒqMx ÑÊXotëúàUËCË"pAGÁØ0#?…,¶Âûˆ@E¶õÀê=¦S'&†õÄj „ø¾Rƒ4H”{`¨Dï¦-[6m!mÍÉÎöäȽ¢ì½Ûï©Ngë£Z‹|T–Å"‰<äÛ4 Ù2D¦’}ï(‚p[øÝ—±û2óPzZ6öÃ!º -« ཷi×{›ÃZ§/œW=iܳ˯bñ˜ÑP7ê´…ŸÇÄÀîî×"ÐF ÿ¡BúÏœxÔc¦G·Oó¡JÎ;O:ö‰Eçbd©`ŠÆª (`Œëp‹4ƈ ª‚ª2Üi# Â6¦‰Ò*bÚü€+,`ŠÜ³Ó&¡.R°€kÔÓ4OÕ|¢Äe‰i“D‹¼„€ÒiÓŠŽÎÓÆ(ˆ«vë+}ï¿Û3x̦¾ˆyŽ$„¹ž´uVð5‡°ÐR ™6N„RVЬçjDH'KÄÍ”(„òh’5âí‘G#¦M:Dº„8R\=pc®cVW¶‘ Ô¼«ÚnNJiÁvÁz‘qa |8¶ (~eyûÉǵtlåäqÿt¸68ƒ3Úç ωá$º4òHåQÙGwÝÐàNËR£Ï:©ö{?c ÒµaK˜‰¼„­EFBŠf¡nņwáYUãF½üÍ[ÞºéŽ +—vžtìƒûͧѵDg{õ>öÿÞµ{„'Ìu³ùO&úREI¶ yãæŸheÇýý!BH¬¦jõ9—f7~´ÏU+‡/œ `ÇÓO mþ$tûŒÙýÂËUc;õM‡R`Ó>}îeÞú­xMÕcÇ-zùò†™ÓÜÞô° ïRÑÙ yÎ,Û~ríi+ ?zì…gízwcò¹µFd8 QaW?Ífn<Ö<÷P§§8Ö* 2’ ±“û·íúŒò°¶– ßL¸,À´Ñ—@¥D,-(EvkµZåóSd ª¾ÂƒÒÆYfbó³05¸¸‰˜‰²1H›ˆ…yq‡Gûh6àC[„Ìàj5êþSãÓ&&ÚZ>ºø› P T$u()@‡jC àiP}(`nÙ¾uËv<ý‚ðj 9CÃJ±²($¨,/k˜XjÂèw~þ­GlîzÌî¾ÀÀNŒªÃò]׿sv¿G†'N«­žòõU;Ÿ{ñ±Î@ýŒ)ÝþOElvw¯VQ΢rsg×+7ÜÚqüÑ{i£ý­PD@þ{A›²\bÓ¼­½¸üÃGÆ^¸äº¦Cf¡;Üi£,ƹΠ@¥¾.Üp¯€ª’j’jR‘\BE@5PM~ôõ±$.eœ@T(4Ea¯*{–ÕT@Ñ ÅT꫺¯é^œØ–+5Yi€&#ÐV ûÐ]'Æí˜tBÐFi(–¡XöޏaYóXÀãÒE1G˜å³¢§;Ä é‘2ÚÃi§*i¦à¥˜ä2G’¤˜ä‘õ\+p`ÄM–¢FF ?ríÑI¥€,qr”*Fü饗„ÚkyGÛŒë.­ŒÜγ«®‰%±Ê²xmu¼®ö£Gÿºý™5S¯^5r~°·6ÚÚJ é¿´‘=L›¢Lã‰û;ÌE{DÒϬ¿ò̺©q BÁ(Õ‰K(PèÜ¥L F) ¨*KL›äq×&*ˆ h ÊÐÆW”€3&ÊÃ6 Ð%Ñ]‚JæqxšæiŠ'@­P! åQî‘G%ažÐ]g <Ên(V\±­mF\³?P¥ÓBd&§3˧E?æŠXàÈnB²’¦I 4Ë]¦*¾›Ó“z1©Dò(1åa¸®%²-pé锘6{±Àé)"¯€e¡d¸šsÓ€ëBZz(,'@ùøÑÙw?@EÙø Ïj?u¡þ™õƒpmpAÛàü›&÷þ‡ÍGÎv³y/›sû2^&çô¦íž¾ÜŽÝNO2Yp: Ö©ldGÇé‹»Ž[Z ¸Hø¢ÔbäKH`htyv"É/ÜÖJL;bÁácÏ?=ûÞ¦ÞI‡Í )Ó “ôIMÕˆco]<¿ñ€éýÏÚÝc4|JÎÖîç_*lÞ6┘;v7î?õ¹•ßÈnø@ØNËч÷üƒaEã–Çž~íÆÛö¹rEóœ™_æ,å?ÚöÌò«Æ-;mÄâùæŽ]sîúÞÿtä–GþúÔâs P1²cò¥Ë†tìÆŸÿÖïËÏPÐ%¯D§È†=g•+ÊG E.¬êÇ ´ñ=¨l?€ë–Âl=€TÕä²½nCûàBhp-A^Q¹/Lª^©¨+¼e‹(øÈ¸ðlL¯@1Ty´½fx„vÖð•Ë4ÎÇšßw«]=eB¿õƒò¦÷Ýý;ˆ´EKBE ¥€8‡˜ÑSÖ¢eµdôôCæˆFÕ® MëÍ˾½æ²o·,š·ï\’lo¾ï¤sN_ÚîI¯>yùL . ò }AmuÍüð mKñ·Û1GámÙ@j*9ãú+>Äì|níÃG¢IIXu¥Ñ2$³ñ£‘çºðï©ÉÎ|noB¿KwíX`‡ò¨Î\Uõ㊤Řé0Î@'®¦y*ñýœJM½˜ Ä•2 š4 "Qæäm7ÎÁ,ÓH:Å”Q’G0e„L[É‹à2áÐò¨Íe¾ P2P3 ?£Ã÷!M=–÷[`Ì9§8ž_×1tÌÊ3k÷üùáÚÀÏ B·ÁmƒóÏŸòÎöòÎvn_ÆÍæÜ¾¬Ó›.îêªéîõraZ~&ëô¤ ;ww÷€RùÞ¦-§¯ C„„”dP;r¶UGMêþ€ë¾4sø¤ÿøZYgû®ÄðÐ$hcY¡L\vÚ„+Vô?°õÿõëž×Ö%š‡TŒlãmpÏgšúׯ,SË’ûÝríö¿>¿åñ§u·ÿ‚„±Y?úvçé‹Âƒ»^~#°íãVÿáKž"ðMztößm˜1À§‚ÈX½fÓ}68½bäð «ÎJ k)nÙ^9aôÖ?>U>°HÕ›ì»Sc;Ç­:+Dl[xôµÓV¢Z€•6‡JèÈP9„„ˆ ¬ cÉâ?j}¡×ËÃãžÐóàµf î3!iØL_z=Be IIŠ¡R€çP HàZÐ÷ú2´ McòDüùµu#F²xþëÇŸ%6@hà@ÌÐ øPv¢¦Swè‘k!ÜÞKF¹´ `z´Ð »}un6ÿÞ]÷ímUc:›æÌôrù§ž=0¢Ôb/Ú ¯›½ŸH&"PÅÞª| Úk›Øôo]žá“ÙðÁ“ÇžiHþYâôe’#†Í}â7Õ{ö–Ȧ­ÿ¿ $ùïø5Jt·*}®3¡S¢K¦qMóH\"ŽÄÆsÄÞ¦€PUó8‰I¢H•ûõt͵Y2¤Ù¨&8\—ž«ª4dÚâñ´ñÒN›&‰ì®î»ºQ]¹ßW7Í™ù×¥—ì¸ïÁ¶¨K#L)Fé¾[ïÿ‹yÿ_€¹QZó¹ÊVk~Hg%šöýöeŸ¶Ôûò›Î>!\a Yd½©aìÅçVïµiÎ>…i Ñ !2Qþ™þ/m„IED—\gD—Šhº§j¾o¨PP–š¯Ø\ Ë;И‡ šîQDL[èÄÕU´Œ„ M• „"y\Úž¦¾rÓLè qÑÚh (,ÐWW\WU¡è„è@L‚JÅ 4ᩚ¯.\5c€t´jÇ#"4ÜóïÏÂs`*È(Z%>UP¨@ž¡¬PK¯+ÉCzp¤_Bff”o’Œð½!¶$ F²©=c¨joô ‹–óÓÄðP=ù‰¨+,K0ûͶ%ŒUq¸ª" cÎ:eÆ W|jqçcsõ®}=Q]Ù<÷ô†M;_zkꌫV{È€«òÚ½U¡ !”G-´…fì~öÅx]M¬®æcµ¼ÿ4ÐÂb”S]P]„;mªækºçÇUà «æM}lè4‚€©šM©(1m¾¯ÃÕ5”†.ªJF¸x1é•$4"û™6¢Jê F¹Âz1Õq5 !: ƒè D0«Ü×tOJƒ'¶£ÇBŸt B˜Çu×Ö]Gs˜°ãÄŽIG¥~hD`à<%À„®¹Tóý€ø69+ú¢êJYÉBfH ’e;–žcÄ‘I§˜ Ôâ"Q,6Q„åƒeÀ²p,PÌ„ãE ÍGÁí£ãÈÃEyJ8nÇÁ3G_yAaçîŽóOÿ¢pmœ Î hœÿ¿†;î+×}ߨ«Öâ1ÅódÑ2wu‘ÈX*€J@ŠQÁ()åºÅ,Ç “Æe‘¤åFô[H³%Æœqõ*ê¸N8DìcÏ=eßë¾àíŸþrý57UGìâ–íé-ÛYEÙŒk/®™8Öî鳺zj&«2þÿŸ“–ÿpËÃॳFMU±7m´6_¾$VQ殮ÎÓVŒÙõüKOqr J# E‹ú` ª1Úßà5‡Ôtê ë¯ÿ—Í ^ƒi£Q…WÛ‚” .„€B± ÚØpÁ0Ä,X€oÀ•HUÀ±¢Î) ý5Y džãÀw \¤¢ck% @ÃШ4> ÞÍAÏ  áزÔIÕØU¢¢*„1^L–ÔMˆ€?uÁ7‚¢©G'#ˆh6}ܯ“®Ä [G(j• ‡ýä"ó¦#¶ÍxäÙÓW uÞa£Î?}ÃÝ÷íxéõKïsÅŠOOä}ôË£²äEÊ#³Ž5†Ô—wvL¾îkÿô7Râ΀„áY\cD—D—:s=P´@Ó<Ë0Bü«Q¯CKt(› µA£TÕ}Æ8 0(4Ð¥«k®®¹ýò¨B¹îºqiǤº+E~PE0ƒ‚3¦Ã)NQIr„ˆÄÀWô@㞪ù ]'vv ®±l£Ðl[wÝut׎Q'Æœ¸´P& ÅŠÁQá+é€:B×Üb¾Ë}‹'M½ µˆÀ†gÁÈi Ãq¨+’¢hå Íñ’N‘æ}™ƒÌC˜à&HžK€eA³(z ¨…b€G‘£À жàÈ–³NÞõîSŽ=ªåÈÙ*Ë>c:h8œAÐ68ÿŽyçŽ{µò”ÑP×ôWòw>ûbûñG¦%òÅ }ëû?K¶ 1šw®yUReIž/¢k&”Êò¡'ÌízÿCÙÝlø`@Ã…qìé8ÂèóNvÍÅ÷™ò."rSúÀÐæîû_ðê×¾µõŽ{*"~%\¦qê©߸0ñ™2ùÍÛ¬]ÝFC]²¹‘ª{½9w=ÿR÷kë&®\ú/:Õ«O_µé`ܲÓÓ$ª:~ÅííX;»Ê:Úú|òØ3»Ÿ|V‰âÊBÂ)”Ô%¥˜ÊEœž¸À¾çÁ¸ ”MÛ~ÎWóë7¾ÿÇÇb@PЪj¬²’Û]ªp0\…æBÚð8@µPT3Á,X€Íàpf¢aÔÒ‰–Ò)9È<– Û†ã—ÚE PØÃR`ND®y œDÈËÈ*h€ÄCO ÉOd¥†$\–€»µu)HªâùˆTÔ=.aŒ9}nï—X)¥\U¨E°WJsqËö?ïs$·òŽ¡cV,é<ç”ÇŽ<™{Á¼'ïkØê§½’t/¦ ˜6D.Ér¯¿]>jøÈsO!”þKh¶8 7mW×C¦Í€%b”©\ÓUJL›Bï ÚTÉ×™Æp„.„Ó¦‚2A=AˆäŒiÒ‹+vLuLÍ™6Ä €Å¸øªæSW"ã°cÄ æ»jP¦‚I­`k¶­¹vH¶éšv\ØŒrÊD\µC¦íç??kÙü;›.|Oø–`¦Ï 0á¸>¼ ” =õøY¨3=ï*"H:EÞ š…ÌCXàHŽ [‚f! 0=HÂE‘£ÀQ +«F-Y.Ñцە~bLQ\EáŸmoÞxÛë×}À¨³¿:vå™Üýû{ÓCGwŠ“Éy¹‚V^ʸO$_4‹3"Ðö?ì´Y*qh_4¯îàý3ë6$þç¦Ñ÷~ýÇXue¢¡®fÒØO~u¤¡W!ýÄ;iîyF}Í^… Fé ®Øò´E³¾ÿ͇8¶é™c—/Y{Å vddÀèó—t,Y\1¶“ÛÎC³ª<Ÿ—%­|1äh×ÂñÜê5v_¦?æ^K›ù‚$tŠ3>¸û¾wÜ[åA„#6´eâ×Îëïtÿðyá¢o uµûL˜õ£}ÿW<»üj¼ã;íÇ9ð„¬½öææ93GŸqâ¿âl‹ èzþ¥¶G¶=éòå!ïR3y\b^Gˆš8©£çûÝ^¾ðÄqKÓ¯¿]=|X¢£5½y»ÙÕãgósÚ¢aÇåt÷á®= P‚6_U fâ˜|¬ï¹µ@Udºx¾6zþödÀ à(.‡€Yð ¨]’1  ÐÉ‘†—ƒä¢2)Ž êÀPò }˜Ž4Ðô$\Žê\„d8àÁ%>´qÖ¾>,oÙ;ž][ù0ôÚ²ó ),^€ ÂmCŽ:xØWOÔT‰\~õ‰Ë”¨E>üªV_;ùŠåÍ‹æ¯YùõÞ?>¼½ ‰ªª jÌLÔ³—~ð«^½îûè\²¸iö~?$|×ÙÅâ‡yêàŸÝÔØ€ÒDêú ¦m€{´?òC²­O=§k|íÅŸú®è[·áÉS/ˆUWÆëkgG½õ…ÍÛœtVO&ôÊr½¶º ù̳ÇWœõ›Dc}¬ºrÌ9_åžgnÛ£q¨Ž¯ê¾ªû!h3`º¢h¦{šæ¡LæËI.‰bvIšT¥ªûÐQ2"ˆ@÷]]suÕuTª šdœëÔgõc³K.„PÕ@!˜Ç)DÀ=pU‰+¶®ºB'$ƒ"¦sÕóUÍ'L2Âã°ãÄê;A`û‡‚6Û ™¶˜^jD TP&Ê×à‰"M(¦UKÂòAm¿<#M6ƒë—â£Ã=N‘wÁ}èWË{I£èd!,°>ˆ„aAà ¸€Ÿ‡k£èÁ³`yHŒ½ï’Å'¯¦_±aÐ:8ƒ mpþ³æòë7Þ{¿ [4oì%b‰J @*ª‰Dˆw¶ÃZcM Æz£¾ÖhjØüп}Û/$¯¯M ©ïyýí¡ó3jªî©Û2÷Qçö×3.Î~´5¤#ªÇvN¹|yÛ sì|fÍê£Omlo­_pDnû®`ÇîîõïÓˆ Õ±1KOâAàô¦»_yËêê©›>eÜEgkµÕn&¯©zdöÂJ@‰B"J†AU!6sçî'Ž[š}û= ÔM8åê•TUs›¶<·âêÝϾ^Ú']¾\z~aó¶ÔÐÓæôe&_ržV–üä¹*lÞžÚü%O8U”¶Gø3^_ Ü—B¼~ý­ÐTzÚ:Öÿ×o^ÿî0üÄc†ðÿØ{ï09ª3küÜ[·R÷ô$…MPå,@$ DÎ9™,‚DADcìµÁƬ׋½ëÈÚëõâl“ÁdLB ¡€4šØ±âMßU5dìϼßï·Ï¼O?z¦[=ÓÝUÕuOó¾çQÝÖÝÐÓ”âÁÎC–N;ãù'Ãýh3˜„ nš‹æ~ôìK9 °@ûaŒúÌñ¯n³D…"Ž r1"B f!HŒ¨D§ ¹tj &xºÁaA¡LHŽXCU?%G·f =3î ÈLj9±d4r®Dƒ‡pÛ&ÿG›²TÐ*à£3¶Œ-fjàÁ$‡à:¥ÐfžwjÓAû¹S&äÆµÜ¿äXÁ˜"AL Ó6å¬ûž[^yK'Ð’"@’ð_&û¸_»É6=Ï¿ Ó€¦úÓ†¶DÕ©å4›óUÓ/øÌ'O\xíúýgtóž·¬N(´ÇÏ»*ÚºÝ&$g2».ñï¿Þ¯€jÞýßÛûøkÞ™uág^½í[¥õ¦ä„o:Ü´9q4³„£CÁ˜áÈdÁÑaTH¹N×îýÚɆ)¥EL‹[2KO´QÛŠh:=j(‘mD°A ‰³sjEcehÉ aűd†c†. |;—È£†’†-­(¶¬Ø`’A8$tð€²‹ÐŒ$R¦- ­„i“£BWÄД*ªFóŽ÷ü›¶Î}Ìãð9h“JB@¥-°8ôFÈ"dÁÁjÊ.G9êŒ2T?T2€òÁ=Dzðbx1"ÙyÅYÓ—Ÿ6t*øoÑCGÔÒ‘m#õßS\}ëûÿþ;Q,›ÀìUËg]rN¾cœÊwÕ!Õ­l ™÷÷üêkkÕkk©iæZFçÛZz_z=Ù£ {úüž>[~ÿèf yîÌà÷XvòóѾï{|å†Â” JÈGN]ÙÿàãŸZ<õÜS…”¬°û;?&ÃR#ë'_pÃeÓ§„ƒoþÃ*=}‹®½xÞÕ+X>àg­ÚþËê²Á@™ a-K÷™»ê¼ÎC–xþš/¾s÷= Ý1jÑœE7®ªël«mÝþØé—”×®33emËCOîý›‡Ÿ¦Oò4ÿàÞßo{êù}¾z#€M¿{ÄnlÈ›kk1ó¹ÿÌw 粜[z£ÝØðÆWï~÷Û÷8ÍMøÔ?¤¸ÂA\ªL?íØqK÷™zÆñÂþÁp°ôôÕOŸï—Qv€3 ´š ¸m–¶lËõ€Ê‚¦fOk>íØgNº°A¢ðeÑŠ³f^˜®‹¯ßñí±)`ì޻ͻâ‚1»Ï×Z?yÎÕµëÌ óØ­cæ_wñØ=ýéVÚð«yÍsG5Z õ/Ýz'€ý¾õ¥ûð›ßü~®±ÁmkÍo›täA»dÕÿ•%‚ðÉ•×;ùÜ?º@ÓŒ.sÌ(8R°1íôcë§NbûœÑÍÎèæ$±€Šù笀ýDêSÌÔPÔPÔQÊ¡nëÌ0ñðekÎZUT’°y KÒ–¹³Ê¯¯U58²†Â„ôb܉)À€ C¹±õð%H˜â-d»o(ˆ,™ó­#(ÀL€v%í= uê|[ËìÞrYç"€< ]§d-m1eÆÅgÇåêø£ŠK•­>¾á÷';·Øh%P6C" x@L&MS˜Ã{ÚLZ}oCfòŸ‚»äãT6lîß°ÙÓ¼àê•ú$ Pš€ü“˜¶ä„ Í–îZë~ü‹íO=ßyÀ¾þ޾Ø÷÷ùÊ ­{íæŽé2b+Ò/nÖÏÖ¡æ , šÜ\âÎî}œkÇ-¸î’Ëß £œ n50mn:,;2$LûNŽX:GýBX­7+õ´Ò€r)û,˜¦iqSrá0âjÂ4‹E¢ÚfD}EMMLÍ iÒ¦¬aS.`Ã’ÆŠ)! Ã2cbê´I;¶Íä †#Í[Vl±ÈEàò ‰L edòhØq˜ú´éÀ¡!5¡5¨*Õ©3ky⵼߲ftOP΃Ä)ÆòÀ}ˆêÁ ú‘¼Šg`½h‹ãÔ°šM©Ï^µ|±møåýîèQmŸÞë¿×þ2€©‘m#õÉUÍw•€"0”€ sRHV0lzôéó€…Ôi#o%ùÜ2ƒ_:à Xy X¢Ó›.aÿç/Æ(2TòØùת›¶–6mU¶ÝE+Š8ê¼×ñö…Ï=ü™w¿û¯CÁóIŠÑÂÏ_‘ ¶×ïú®3ªé„g3ôYÞþæ÷ß½ë{  Y÷’¤tîUÎZyV®ulÊŠýÛo^¾åë` ®½xîåéøçã§]<ð«Æ0ƒÖÅ7\6ñ˜C†o«ÚGÝ~wÏã\#j^nT“Ó2fëž-L¿àÒs8äô¸o@pÚ[÷;ù ŸˆØ×¾—ooµ›þÜîØþô‹÷{®Å° ùiçfÔâ•-Ûðv¶KlŒ&RïRá`é‰ó®ò{ú0•¤iEÓfÒp¤rhT©µï»‡ï½ï(k^~ìèuw|Û*PßÖ²ðÜSßýÒßàÈ•6¾wQÙìí¸„:ÍÚÇ(Q0 AÄé(—2õ›J0㙵²×`”Fêàk˜5˜>b@§GW%»6PÙC Z ˜‚R\¤æ/^æ ×´dqã¼™}kÞÈOhwF7oùÅ}ëú§§U¯ XŒ«ƒ6 C(…h§6J( b3Ùp¦šÙ÷"¹éÌJ7áí¬:ÂËÙˆ±šLUPX…¦Ÿ$jè$ÖÈá^ßNc‘ÊÆÍÍ3§æÆŒò{úüÞE׬ÌîÒ¸B(Ó¯T ¨TMð<¼!Ж‡ç"°ìxÏÛ>›{¥Ë¦=È 9–2mÚ&6‰L ‹IÛ¨—•‚ªÖ“J=IA›` V)¸)yäØé B¸Se"Í%Z:·È°%±5q5WÃåʈ%“BF"€ºfà"ˆ…ÛÄ&L ¦L›ÃÂĤÍý8$"<äœ1m¡V&òh´AúJÖ #”yËËS/O<™ÉQæàè Àþ£pEÄ Tà0**d²²a”¸Í  àÌèšsî)³Vœ wÍëO^xÝü«.øËˆmDñ©Ð6R“²šº| I3Š 02¿xdM`8à¡‚•­RQ†Û$`gFk4³ÛpñÑ™é6´Ê(+”%*U‘ÆD&Á(àÇü2‚‘†T&çÎ}ýÝó |÷QÐDJÜteÛþûðJ„N<|Ù½T|÷ýGŽ=¯}é>­íö ô¿þ6:Üúä…×°(N€ãÜËÏ_xÃeéß¹2mê¿2±ræOܧ=/¼:áˆe"ñ&†\é+|j(j+¸XùùЏ­òÑöÆÝçGýˆbâ‡^wOñ½ ½pÎn7^þÖÕ_Hzݱµ9mriýÆfÀ6„ë+Q˜а8b€ê˜Fgm…|X"Yr\µ€Ö „9(@Dp<ø±Þ™ue(vFIucPH©ÀÜŸ‘"IàÖög_*mÙ–ŸØá67}ôГ3Wœ1vÞÌþ§žÏs€6Ð > S—æ´–J´Qf Ê ²Í$C¶pVF³!C±cv›×·v]Ý” õ“ÆÈçßÚL“"6>n±›È£*cÚv=ïÕOžœ2Š ÛJ[M ¨j ƒ@ íãêQaCòhU7Ì›ïÕN™,Û×mC® \¤ Í!ŽZ,ŒE–íª  «^­§•]®'•*+À" hK,BÓ̦Åm+rÎ SQK%mÝ…+,3–®A]¥\š0m”*j+&…¦Ä¶"eP‡…®bi…ÚQ61¤4lÉlaY±mD. „.âòP°€EtgO›…ŽøÓ™ÃcU£fÌë¬ZÞðòðŽy ?Y˜ åI²YÐôE~Ü@¬  !úQá5dÙ‡R´óZ´äÎäO;nóÃO¼ùÍï÷¯y½ÖÓ·×m7ü娃Ä6R# m¤þ&å4u K¦ÝÈ™I` ¶?8.©CC,‰PѤїÒìW œ p Ø²U ¢ˆ0BM¤ñS`!Í•NVwxÊYÓ\ (ÂÄÙñÛMðæÙÓ^yË_¿1ßÖ’Ÿ=Ýi ¥Ý±Í/Ýx{ÿo/þò Ô¶‚Þþ5Ÿ½­aÒøù׬žF üþFjšSN>ÊÌç:Úo'?÷­núõƒ,çÆ~ €¹—Ÿ¿àšvSÚW¾ù?ê¶²/p‚ÂÝ,â³ýÐ¥;Þý ²ù#•åiyšU‰ˆ€ @éŠ Y÷%í‰nÖgeÁȓ̀É-s쩇/k?þ°‰ÇöÆÿôö·~8°©€ÒðtJ«ì­¥L¦L™6–0mÓ6g E`)@ƾ·Ý0ýœ“‡-„€R€€iXýØ)¡)ÍFùdЦ•v𦂠ŒHD ¥äëÓÔ0ý’sǯ8£€?2ÆEVÌr=*nXQl‡“‚TuK¾GPfQŽù9æ[FlÚ\:†ÃCG†“‚1¢uAVëd­ ªõnåï~û¹IøÐ2ãäÉ$uu£Â´¸isËŠ]Î !“ìQÛˆl+2]‡¸Ù©Z~\ZÚVD‰rXÃâÒ ¥šN‚ؘ-lD¶94t¸ÜBÊCSÂÆPO[hG¡#CG†®J™¶¸ ×Tæˆ_gÕòÌKΗܧ6øî×¾] $09¬"ˆB”ƒŒäA* hÚC$dMl‰1PÇQmúÝ#}×™NëØ=ï¼eâŸÏ}±ó©Ð6R«"õ]\C(L±RÙ¢¨†ÍLÉ Æ%hÃÄ/ˆ‘’"c8pF0(°²Îö*a\'¬6ö ÈeÙ£ÉPá©föÌô ÔÔh?ÈÊ‚ …PÙÞÝt÷šxCNSƒŽ¢wîúné­uåí=Ó—ŸÖ¶lIÐ?@˜a7Ö§Žó¾:]öƒ¾þ §oüá;##+7?væ*¯§¯Ð5qÏ›W×o“a4nÉbaÿà£'\Hkþ@“•7ny÷?ÛãÖÕI7ú¦ß?úè©+-Àl×1\', ½•”ÑTjÑçÛ{7hýüê[ãRùˆ?ü{\ó§Ôåk›¶~ø‹ûr£›sm­u;`OIaJeSo­ëí­ég}ŒMì~æÅGŽ=‡®¼3 Tß…isÁ…2½ü•5Ö¾_¿éá£Î.¾ó¾¦yâÜUËñP†ØlÀÄòëºîËo/ EÍ“ÕZÔ7À+5D‘ßÓ¿ã_~¡†i ¨j€ÝܸðÆË+ÅQãZè†ÍýO¿@²6£|cCX*SÀ×2Na‘A"‘¥;$䜗A+S¾ô°Ä³$*¹~@sãÜk.îZu€÷~tïšÏß1ÀÄì"AiDYŠ}99ä)1LnXʰ”ÉDB¶Q(š0mg/îþåKã¬lß©LóÝý–ÕÓ/`€RÐÄ΃‚i˜&E´ ÓF²A„¡GøÇ”îçÖä=€B @¥Y ¢¾®~÷ù¡ÖÛ|²p~d*΄¨C­ ªõfÅ#3äv™w‚°Åèé7F;4tYà²À Ò´¹´ ‡„Ž MÆ…ÉH ëU¥ ª^-ÈjžyB‹Å. ,+¦D%ò¨IyÊ´Y‘B0ʵ´©¸mD–çàݦáƒT+j+F…¡¤eÆ Â5“KÓ•+Ö̆#Ú,²Yä’ Çƒ04X â€;Ffæº-G†Ž#T!¬ qX¨ª´ÎªÕY5Ê3T[Á›_û¶;”{Ah,”ð^†/HðBC{¨›:¥wÝ?ë› ôüêdâ$&dÏ]þW"¶]PÚt©Ð6Rÿ¥ò ]> 4ò@“›#Ô@CÆO  ŒËB ;€¨¬‰@ADà1"±3Ä=IàÎ8µÒ‡qPš³%1ƯeÝ æئPÒ;%-Ç–Ü÷€Ä3izµý%…’Jõ2#ë. íQ,{Årù­upÆí[ûž_*»cFÏ»ìÜ¿Ðï¿ó€Ë¹uãݺñmg8T÷sk&¸·£wñÍW™uùáÿõÄ—y6¥­€ŒÍXyVu[÷¨¹3\{1€þWßzêÂk+゚Pcí‡,mž?ëõÛﮊ%¹ãS{ö½òVmÓÖÿþ»Ù—Ÿ¿÷·xõ­‡Ž<›—+|g[]g›3v4&<”ŠI™"¶~êâxµ¶ô;·Û}€Â” o¯OÎ$:À¡šÚ°¥aKÎv‚¶Þ—ߘsñÙþú¡ŸNÙ@ë§Ͻôܦ™Ó~7o¾®‡3m°Ð4o&«±>ÝBˆªKÏ_ÿ•êöF6+Ð~äõŽãw÷!f­Z>zù½ïÝóóž§_020?ã¢3v<ö +•“a”úiSˆAËï¾ofäÏ®%d6÷´?Ù8‚ÌB=eÖuž&Ò2Öºdq°£çƒ;¾ýÖÝ÷ؽýc˜œô_ …t<°ˆn& K–d–4 a2a2AM M’éQPȾF&ør`Ñ«r“Ç÷¿þö°ˆ‚áDZ´˜A4\!%Éã €Aìê¢üÞïàÓF˜à@p𔃼RÛðèÓöú=›N©³Dl™S~ªå…gG‘ÅV۵ȉÜë;4´(Güó•IS¦ ¡£B‡…‚15@ëJAV ¤Z/*uFÍFd™±KÓ┪De¦Íw‚6ΨPÔ„-¢„iËiŸ¸Ùô¨8 JÑX1*LÁ-+¶Tì°Ã‚… …Ãê…J֦掦 i컡!BA}fCÓ ²ÃÔ§Í¡#W6¢iÕb‹E¤†º\-oyÚÉ@Ûegâ±â,æ–RÞ+oÊb99 @xˆ#x ’cüazRUû+ÅdOÔ˨åÀ_¼¦ë”£ÿszè\©Ð6RÿÉú0ßUø!ЬÑäBFˆ4j™¯U2ÅI€ ™óÖx šÂxè*„!"(‘^ñó Ûåí ¨QøH”dÝãqÖ»b‡ƒØF9H±×b;yÐx@[ú+ä}Ð d?x ƒƒ µaí4ûAexÉw÷V»{ú'.ýÞÃÍÕ^½ýîÑ fÏRþï|$¥SN8¢¶mGãÔI»ü׳–9v¼&uМ+/PB²|.Y¶Kë7¾y×÷'tÔÞ}ßi3{Õò ÇúÐg)vJ×ûDËÛñ̋왧žú!ü¤qúìstíw’gÊbi X|ým àk?MAaÚpdcפùW]8ô®Þ¹ûžµßúáÜ+/¨nÞ¶õÏ^q§F-3i3êG%LuW;AÛ¨939måö§^PÀ¾_»©ëÔcž<ïªÞGžZqWŠØÒ›™uàßJŒ™M ¯Ü~wiÃ&ê:<ë§N^ò…«Ý|ÎïåÉŸ9ÎnnðÂõ_|}­;ºÙï,LìÜýóWô<ôD°a³ @®³­ù˜ƒ·<öÌð(÷!ÐF³I—ÑS&tvMxøÉ(1ÜÊޑ̶ ÁñB üî‘2À73èjÍåH§ah~v؃ÑäÓ%4›a)F$33%e:•GA(sØP…ÞûÍÃÓ›'},0#m4CÙLÂ"0) eìOIfùA ¡Œxÿ{?-_~Ót àM@ õ" I 4X@T󄆔–Œ .TÕá¡åÅ¹Ð·ÂØ ƒ“–ü|üÚ-¶å…çZ˂ضL›ÃD¢3æ _0¦Ò`•ëd­^W ¼Ú@ÊIO[Ú #“Guê©f›Q>W&åÊÐÒ6"›F¶Y$N„ÑTu`Iň°id›Q  ’¹2ÈE¾[ öÎäÜ6"Ûˆº+âÀm­?û–pÃæžÇž¡Ù9ÉéB VäÁÍ'^|éõÒƒ›Ãevµ0åÄ#£Árß+oO·ÃH ÕHÔhû›Öûù.è<`‰… Š©ÔL!(ÐtP\¤³{‡¶@jxv2‚à‚Jf UÎÓ>@ŸÂä›P)1œ™ØiؘøÕ‹7-TEº)j«ËØüàãO^pÍî×_Újâ§ö\sÙç¬ É9ÃÄS™mX;›bÖŒË3ºüž>£X@5£ñ’k•£Þ´E.cÚ Sš$µü0€t”ØÙïòÌ®yö±‡Ì^yÖÇ#[‡1m&ÍÒ!‹]2LÝe@Ÿ÷}úóå7¦cl`"@ a ¡ÎØDÛÚíúKßÒ[,[2¦BYq\§kf³Š¨CÍŒ¸õ¤âŠÀ¶¢:QËåüóµCL›–tTè¨0O<¡˜HÎôS…TTëIÅ2b‹Å9â›6§J%‡©†É£Šre;Q2ˆ`RÎA]•²¼Nfùa!¶¬Ø¡c††F(œ8°\c¥aK'#´ÈEàÆ–,0 @Ùa˜õ´ŽZ4®M+V‹\[4 8¬ŒbæØQ0á¦["¬3å=!¹…eM9ãøÎSŽزíÍüQ>“«Å°#J›zbŸ»ný ˆm®ÔH€¶ÿÎÚ˜ï µ¨Ë* JÀž1µÚ?8Ð7àÓš­aQ6 Ç5!3D1„†I€»Æar8M@DH8vt8vtðλ¾FK 1Ð8è˦°ü Ü•À#´FéyÓÏVÜÓ&ÀžHI¿Ä SÀ®ƒÑƒ]”Ô²‹àá§ÔdÅkYº9¦yýÏïàŒj Š{ –ÂoÛœQ)¬³í€Û>ëŽ=ðÚÚ\[‹Û2濲=G/œóÈ™—¦O>ðóWŽZ8g×c×uü}oÜõ½}þþ‹3Î? À“ç]ÕûÜ+ë^ǰ‘C8m•}ë~ø³í¿~¨>Œ²•|ha7-3mˆ¥ ÓÌq `Oœ|Q÷ý;e¢ÇO~ú„öeK{è;+®s¾¼*,8C -mhËt.NÍe/u?<§Ž06ýì“‚Þþ¦™S½í=Ϭ¸nÔÔImË>Uþh;òÙăvþKKºëÔê¤cyäôK̦ú_¼¿yÎô›¢.­{ðé…‰'¿öˆæ¼òáÖ‡Ž?¿ó¥&¢ IDATO¿°âú…׬•jmGŸ¹mÇÔsN®›7ó‰=Ú>ãöÛ«ý€}ßûåÉÝÆ)f^|ΤãûÍüuFàæo|gY¯Û‘®Nîü²Db 0ªiÒY'†Årø£{eÖ´¤†%¡Á" HLÅ,e˜Ê°Ó‚1a&ƒ$cÚ´!26!öæ^vÞ‚ë.ùørþÑN¦-¹Q FaX”ZJEÃäQ¢AT¶« h#ßÑòÙ–«TÇs®ú€^`+Ü\ ¢%B@׿_¾¼÷ê5uQÞ•)8ÊŒyAUu•Ð’2Á뢚† hshX¯*9÷¬8aÚ¨PŽ:*Ìi_†BØ$jpÊ]-ˆj-Sï”GµJTu¦„isf}´ eÓèûýËm3²ŒØ²cå䶤±¢±2 -Ûfä tY @¥4\pßtâÐi™-l#²Y”XïºÜr¹a–b†¨ Ê‚G[†Ž lÒª¤ƒÂ–ÜbQñ¸Îa&WxÙåb àSH… HçÜ“]ß4Ö´sOí<éÈç?û•îùyÒÚ‘›ØQýh‡BeÀnòñ‡-ºá²dXçÿƒpm¤an¤F@Ûÿ¶Z—ïJtÌD:¨(Ćé.ž£gLõ×® û’e6ȺÎ|uT="… @DP"˜Ú Õ”€ T *S 2eBÓûåþéÇÝ=}}KÎC©Œ–@OÚ—–8ßë:DÑ@ÙB5B¿Nýx9pr3bkÿ̼+1ÚªEÄ~­5À„Ï!†Ùñ'ÍLö¨¦é+γïâ)qØDÈ*b¯è%@$úQ‚vô¾óÉuMε·:­còãr­cݖѹֱÃÃ"w©Òúùq-š ýêíwO>úwª¾—ߨlÜrÜ ÷%½t¯üÝß÷¿ü†sµ Gl‰ø2þèƒË[¶õ<ýBH‚ø0Ä–Ïü5 cž2Hˆ©aÀ0eÑiz ßÂoÛ ›8ÐÔþðlùÏ€Ùb8Ó–€6BuÒQÎMo~㻋n\E þGÝÂó³èà Ç>÷òå^oÿüÙÓñJ Úˆ­‰¥µE¨©(Ýu¼ñ×}©ó ýfž{Ê.¿të›î{l÷WM>öPÞ¶Ï_ÿåü¸±awï’ÜÙ0i|8X¬ëí_¸tö^ýüíGô+Ûw´í·×‚+.xþó·÷¿õ.¦{ʼÕmüÕŸº¢óÐ¥Qÿ`­»7^÷A˜…º ZS€•©Z!2tÏpb‡ú]ã¬ÉçâŒýΗ¹Ãf†ü“EÚ, ÔÔ†©²Í”2AlÔÔ Œ€QHg[LùÌñsW_´‹ßÎ~KªA  )…¦0‰aj´ªKw5@ F­)­Të€ýoÎp@Øê +ˆ B wâ„1Köp;Ƒʻy匪)8ášÅ¢ ªqÕB â|'Gó~—¶d5O¼ÔÃV„fÈÝBà˜a^yÊ£:$Žë­J½¨ÔóJ)‡ÌÙ)’T5%OåQ+’0åŠ e‘mFÔP¦æ¦Íc×JRj)ÖIŒ•­"ËŠ„ 5ˆ’4”Ž [ Œfé°0‘G]¸ÜÌņaHePPAœô´Ù‰³® ð"%EaéÈf1!"æP!Ô@ Úx_ ŠàGðDz½d>ÐzIJÙW\áÚ%>ÉXpõаT)ôz;úJ[>"Jíyóêég8¢‡ŽÔH€¶ÿ‰Z›ïÃR\à` D@ÃÒ½…s|ÛÚqϽS³ôɤëL‹(l ŠCÇ(Y˜9 ž«Â.‚Ç;ÍA&äÀ¶nÿéÇ}ÀnGŠe´,v ¥¤ÙCćäÈWÐÏÑk $ÒŽ¥“òðê/N©µtÄ ˜‚6«a*Õ©o~”‹À0Í™—œ“ß>å’3À ªP5ð(‰6’ 7ÁEíÝØÖn¥u®½5×:ÖÝ4ñȃš‡]@¯M¿{äƒ{·ø ×&ˆMqQzÿCwÌ(wLs8XZxÍÊ¿':f÷ùcvOS>üÕƒNc½]_ð6l&Àس‰iÖº{ªÛ{ưï¬g}ð›‡_»…7$ˆ-×ÖlßÑ”É|8pοù© ¿bjbh0¨­Ï"(TÆ9ñl'QEC *%ÛlE•<Ý@毾赿»«ÿùWŠÏ¼HÙyì¡ã:0ªz¥·×?tØxXgÚˆ¥)S•Ã?ou˶=o½zÈ—¤û¹5µº;Ø÷Á.èî¶KÆ{™ëd§¯Ä;Wƒ(P’‚6˜”ZŠ˜2mYfõ hb+ËŽ»)㛫@¬êÁ§PPܸy{¹2·y´¢#¬w+¦àDh)7 hUÉ¢an‚ëA´D=\˜6êe¥^V,;6mž+úVç™çäœðU@ÀA˜sý­~nÇßµ“mʤ]˜6§TQG™&gL˜O|Ú4È<ʪܶ"Sr“pËŽcׂ¸ ¦¢±2bÉ´°DlY±«ÇHa¸"¾áªÀ­vCdQ2ˆ Àr±rƒ)uÄv6=šø´92”ƒ”–Y,Š98‡ò¡ á ø!GÁÒdpªqñÂ+Î,oÙöÄòÕù¦«¾@mk÷›®¬Ÿ21*–¼í=•­Ûë¶uïví%ùöÖ?‡Øþ_±\ù|×ðWŽ#5Úþ—Ôšaˆ-™c?(% hBöX`,Ùcó—ÿaZ⠚ɘ˜ ¡Æ€„§@bL- µµ‚[B§±0“À)d€0F˜¼?PAh¢i°c˜ÓQ-[{ö+ƒ•0½‚®2xEà†šÀ˜ó @ ˺ߪ@ ¤å¡$ÏÉÂP‡sìÝnÿ†Ñ PèÚC¡ÈPßP2ãØ=¶í¿oÐÛïu÷ýƒkß[tÃ¥:¶þ?#ÅoùzÇáËö¾ãóù‰^úÂ7Šï¬Ï·ŽuÇ4;£GåÚZ ãÛGÏŸõ×ì… GøôÊz^[K€™çžÒ²ç¢ §¯º½§¾k¬‹Î|ñ–¯oøÉ/sYûšÍ{ÜaoÜtGCÖ&8d–3|m’Ðu`0M˜NÚÚ ´ÑŒ. 3ËâOfÚ’éQGæ¥×HKÏŽÚ+Ì"ب¦Ò›ÞùÇ?ñù‰ û?\M"ÆSmÔ,PCQª–n|²­yðwú_y37¡CKY?i¼Âg¯ºEá?üÆû?¿oÿújÓ̩÷Ɣ“Ž ûœ1£þtC5Íž@kM²ãù—Û?½÷è¹3§Ÿ}Ò“\ìè;èß¿8ç½}÷=ïÜs/€ñË–Ì<û¤Wîø2\+,sÌâ…G¬1¥Ýà`·{o{âƒSZöÝã½oýpú'DÕZðÛ‡ÔÅšübùÌÆ2,™È£”iÃTÌRÌŒfJj‚2 JÀ §qF…~tßc½/¼êv¶å'O¨›Ô¹ðêòù¾a6l „€fL¥°55±d É£É,f"Ô6¤”ç¬Îš ÊÙס Z…ü´É»]wI|ø÷Ìþ–|Îk°ÊŒ "4åÊ 8©j^2-RÞrù-£ûúk¢Î1BKÅU5mî†Y㎠sÌÏ~ÞötH‰CÇ ùÌïÃŒ]h›ÀeŠÚª^TrÄO˜6ÊÑÚ‡!$ŠÚ²â÷Á²«–ÛqD•dÚ<²ÍÈa>N˜6'ÝZàVƒ„f³HjÃåÌåQR€Ú4à)Ó…BG†„Ǥh%n±Ès©‚G U¨A%BO ŽÅð³04°&O˜yÉÙš™/_=íÄ#Ç,šã}Ô=ïêC-q¹êmß1üÐýËzèÿ¤Zú§Àq¤Fj´ýo¨'ó]Iw2a°O’ ™ÅD6Í›)çÍ|ï÷·?ûR2Ö™ä.3 >PQsD&"Eé¸è´”T#BÃt€~À‚³g†•j@ˆPÃ)ô>E˜ ‚8 a~?Æ ” L°@ÅL ­ Ð\„^2†j¶YsÔ*õhâЀò ‚Ûõgªl²¾î~Ó•³.üLÐ;à÷ô}¯Ýö3Ï?mÎÅgßbïÿèßÕ%7Ö€A ­³ÍQjãwþE×å^úÊ·t¦iº-£síãfŸú¤£ú+wÄwþs0Pl^8göŸ™~öIq©ôô“ÕOžðêíw¯½óŸ )ííc³S¾XšRE©Šˆ}ÿ’ck=ýî” “=´cÙ’µwßóÜ5_ì8`ɲÞ B¦ž|Ô'nODlCE2;½Ö½w°þ_õñóö¸ùªy—ŸŸ<¾ñ÷õ½úVëûŽž?{þåË_øÜWûÞz×LÈ㮉 W_TÙÖƒMé F´ªÛÛÿ©Ó.™wå…£Î~ñ¬Ë¸í­fµm5¬†Â_Ɇ?8ôä¿zúãC ß./÷‰w‡ÞÉ'ò‚#ã#5Úþß×ýù®d,1qÏ(da’J@ÚZ*¦¹îÔ•ûf Ü0 È„rÈI ¾Än&|ŠP‚Ç%dœ¶œ-ÌcPÀÓ˜0 ÄÁ€†v‡ô@j ‰•nˆÐ„Óµ/‚2ˆV …¸†¸†¦cèƒØìa” åAz %Ä1ª š#—Ù‹ %þìø@›(ˆXÁ×ÐAêeÜÕÜËÎuZÆô¼ôÆøC>]?iüC'œ?jÞÌ«/J1DGW Ñ”³V§ÒÖíý[·‹‡žÙ˜jÂxù=ý V¯øs­lZ½/¿1záœ|Ǹöý÷Í·µ°¬Æïýø—/ßz'Fí¹p·ë/-Ô=o÷y£æÍz耓x¹J3òLs—Í1_1šR_ ‰»O[~Ziݽ?™RÐ6Ä´1e˜Š™Â„Ü)êdü“€Ò$PŒgGŸOï=ùèCÊïmˆúìQM uÐTbÒFR¦$òhÒÓ¦ K2KH1䬫¡‰ n‚›)%ßÄro `äÕa0ƒ¤Ìœ&ǽÿê—ßMÊoYå8ïx…¨J#EîÔú ¢ª”VÔk·,t½Àb1 ¸<ËsÏ4yAUÍ3=^gÔòÔË3ÏŽ#*„0«ÜqCbÈ|ƒ—˜´9<§¦vH½¨X"vU`Û³…Æ&8‡ *d\böØ(/=ßÎYv ²”S>‰u]\£ŽbRXVl›éœ-I()扄i#Z$ ) •Ë —*ÄòÓ£$td‘+ «y®T ¤ j"ˆ#„r§QÒxP?¾cÍW¾5õ´cOëq–sì‚Øþ‹€æoŠ{†PÚЫ Çm»ÜþÃ."ŒËç»v^Gj¤F@ÛÿD=4{ÿÈ2YÌm ,•™Kd´½gðWì—I— h(é” ó€<0— ª+„8G(Ó®¸¥ŠU  ôìN Dds/ö|ö hð1è€{‹”Æ0=äf¤gP»¶úSNN`ýÙ‚U­AÔÀ}2üÌìÜlþ``Œ¢Ø €Ã퓈Üy•NöiÆ>¼ÿñEsfŒ?äÓžºø­ÔÔÓ«mÙÖ~èáŠ@FÐáÎÙ‹JÖó7D>Ùuù¨æ%øiáUͽ䜿rGlúEwtsÔ Cé¥CÕ÷ò›=/¾:é˜C¦NÚíÆU†e%–¾Ï]òÙî_#Y€X}¡yÞÌþ ›ÕÀ k‘e[vÌ]3Á^I‹ÛüÍo(€fºQÖèÌÌÒ1:$4¤$ušÚ°¤‹ Ç|BõôõïDÀ°ÇɼGC —³T[G¦dJX*Ö6Y^À£'œÜóØ3¾x—¦,Y¼èK×5ÎþXàŽçÖ|ô‡gúºÂ¤ñŽ9DK©•¢æÿÀ}… Kÿùc¦ÁùöqùöqÉÏÕ-Û&±LÔ¼ Pá´3NHx¸'ξ35l¤ýÕ—¦üðÈÍwËœ³jùøÜòë?¸ãÛfœÀÌdP¦ #5×eZ0S‚2à-°TåäÃF*o¿·öŽo; …\}ÝŽÇŸƒù4MÒ'vÊ£ÉM¦G53%3e44= BM&áÚ&†’†”‰*J^Ý  ”€e³¨@ZçÜY+Õå/xt@Áuú@û•S U…º<3rÒ<¦V]\³í¨^VH¤…ǸgæM/O¼<ó,[aŒ´ªl7R1òSRyÔñBB4#¦à–ˆxÕ´x.ô9LRQ´ÂìŽ(Ï=n›¦ÍU)§üœò!PÕXA¶´ÍȲb7 Bå$ Í ”Q•N-4˱’ Ü6"Ê¥Ë 76ÀuÈá:‰O›… *>tVÔv-ê#ðCÈX U Çhœ7§´ö=ó!s ä:Æ-ùÇ/µì¹è¯W!ÿÿˆc†àWòAv¹û‰Ä[ìFpÛH€¶ÿÑz÷ËßdÍdÓÖļÊ3Êh3¸a³ðƒ!ûÙ½;#@ “µ¾ U`:`eX׈%b…*pOQ(j”5ön€®¥fÎ$¯~Dæô¢ˆØ÷Àú`öÃ# èê‚WB#Œ0º+{É-º© ª#°@?À¡}¨Pƒ®Á(AEˆ)¸B (uÙþ%ðšæF:vjÈE©-Fbå1ç‚ÓÛ–,æ5ÿµ;îî~ö¥ü¸–w¾}ϱ/>¡”¤rê`Üs™tôÁÎØÑÞŽÞê¶íì»ø ×ì²Á_ÿò7¦F·±>×2&?©ÓÐI(YwÏÏ×ÿô×NSCn\K]{k®uŒÝÔ8áˆ4KøáØ]' -‹7ðæ7¾ÛûúÛæ¸±¢TáA íÓ{Ï8çäÒ–m ‹Šo}óû9æûVβb‘c bKÚÚüBÎÌ9‡nzê} Óæ¦ÁÚ$2¸ŒQ[QK償c~~ÀÓy"€q-ÕŒ8ÅÿaïKã,+ë3Ÿw=Û½·ª»«÷½©fm–F@5:¨¨ˆDETdÑà2.£ÆhLÆhuFãÄ%1E“¸`\#*¢ˆ¢("4K³4t×vï=û»Î‡sNÑ’¸ÉL¶úÿêCWõ­ê®sÏ=ç¹ÏÿYÀ ¼F­”»W¦u0hº*re_¦Ï}ð#ï^ñ¼åOžh ý^uf0›bü®÷虹ÞýÁá»e=úß°ùôSoxãF+WìøÅL»_6ÑÊѯ\¤ö7­ïoZÀ[KËî{à O9tçî+ñ‹‰kDxz0âï¼úóksÜQW]oÙð·Ç<%TºéÑzÁ† ÂB¶RÆІ±ÿ䣞'JxË´M¸QìŠÄåV³^õ‚LH-¥’B…¢Šê *òÂÌGiÉBí¬1!«¸¢‘b‘f¾ò!Eàá”ih¶ .ð•#ðyã‡L7Dä…Áº'=ެZÁý{ʽ3`ýää·¾úþöo¾…ü÷»1|ØûWüK"¹¥Ymÿ:£æô(Mï}`øƒ›esÿ8`óæóÏÚwÛéÍ·6%?!p$`QÛM€`±Ô¨Á¶¢õ¨JåQ§s¤¹ÃÐc 8˜Èrˆ_¾Î-|‰Öð¥€5p30ó˜ïcz-Üj‡BÃTÀ(9î ‰2 Ù Ì cŽx>Éà3í <Lt`oÐïa·Ù¹îÆ@e‘H 2Û:L `ÃãO\øñÏʽ3?ÿèÕÕÜ€SîÝ3I‹Ø| ÚºTÚ‹ÃÕ«²{÷œðŽ×­}̱Ń3ž٩£kº '½ëžÏïxÂTó-Ë&’ƒ§£-ã·}ÿ÷ߣªºy "šZ¾íY§ðö×>tfÇÑþIfÍìþüWäDÿU?üû¿¸òMz8.fç§vî8ìÅÏ£œÇ·ÜöÙ§=÷ïnùj¼¯dÈZ²Éien¸|²ua¿ÄWlÞyßÄšõ"Ó¦­@&m\1/–çóXI‘„Óìò‹~CÄöˆ†0öí+Þ0wÓ-$kN9ÃÎ6!€$ôà Äï|ý;^~Éßùþ›žqÁIJ‰RÚŽ]Aºõ(i ¶-ÓÆ-·–sc8¥¢£Ê8®‰ ]›+éBr €3É-  ð ¡o7¤M4§à-ÓÆ„åÂ2a‰ÕŽRK˜ðªmZ îìø „Ý×z)8À(Aóßi8 ›.¼gæVÊ‘‚ ­gÄ ÷a×›§Ã¢L¤f°Úˆ’E=%6©¦¹¹öIlž OxNRO3Ç*kRFU] Ç2AtcDàÄ(ÈØҨ棧²žÉm~ )§&áù(˜t¸<ö…1<©ó^‰XI¡Y‡¼ŠTÙ®D¶¥ö‰²’s¥­%ÄPb"m#ÍbÍ|勆bWvq=Z×vT ¿6FF±P‚ZmEa±áôS7_|Þì÷¬Ú°.¼ÿxÏÞpåŠãßúªø×¥3þ'x-ñjK³Úþ˜ðý_ǽïm¾ô˜gn¿ôùƺ›ßôN8`XÕH§»PÐÆÜ¹¨L1PãNÅUµÇi2DfÞ£×À& rÈ!îÐCÈï} X‡°„5(%H=‡!°á¸9Ô •Cipð`ÃDA.tB-ÌJ çs@ –ÃÊÇá€AÛˆÐxR)pÒA@Ù…«f°9T…R#wm8p p`tÛ\w£­k8XÃA"x !ê¢í]Õ€¡të¹§OîÜñÃw¼÷Qo¼ò‹Ï &kN>Žòö„Œ·L› …‚²x0ßü+ £ñwn´ß¹Ñvª¸6;Wëu§Ü›^ùŸ5§ô­ýT¼fe´rÅêãvn>í‰ÇÇEˆêâw^uͮ׬œM%Q©CRqk´š!tl‹Ø‰ÌÑÃ~ÙÓOøÓØÀ2P‹’ÂT(úqß§1)b_PÝf…ø‚4L[d}™¶ê·F74PçÈ JƒÂÀw|þ+Ùç¿’[žýôU;wÜ÷ůÇkW'›Öÿ&m°¿ÉÜöÑ«¿}ùëzÕK—q¨N³#/¿OháHè‚OàOzà7}ænüÝwm{âÉÁÔòÛ>þ·m„h,-ÓF©çÌ1é8³Â!Œã’rÚ2m"Р´y³`:gLÚ¡ЦÁQž8P€ûV'žKÇ¥åÒByËcV8Ý$tðÀ:gAY ›*‹†i“h ›Ð‡¤Ì›B.ZË`H䓦r¡ô*7I@ëžÎz.ó)…Ö¹ ¥ëÙ,A.¢™#™§¥«ÓÔ]ó†3S8ÉUm˜B IDAT„’CÆ~Œ›ÞiT_§}•6 M@;Cݬ…Ñ ÏwjHªÄç±+”‘±+zu&M„µ*ä•‚$ðÄøJ…¶d6eQV2hb<ˆ1A]ÅŠUŠ™Â‡@¯µk™¶ª T|9¤ˆ…JJ¸ò’mœ¯_#: xpfâÁ}Þº_ëú7ç±4K³ÚþS¼UúÇâSùygØòܳöðµÉ´êR¦Ö5 ÄnØhtÅ.ï|ˆgR±Aa¡|«dýrÈÁêM(ÖÁgP^¡*!FX¶ ;W¢6¨ÞÌ£b˜÷ˆSôÆ DÀ¯‡^€La5æ¨áñBÀT+,÷ÐÚƒø6 UOÜ€¬F/l±§+P•¨JèªÍ¶I¼ö˜#“G¡Êêæ÷}xåQ‡%½$üÖ÷& Dl#ÈàjdH xl|ìñë/ꚤždžfŽŒ½«‘ðü„ÿvùº'?®}µnM¼nÍÔ#ßûŸ º=Lͤi[š%Ðöÿ›âþ§\÷€Çæ»|2™>;ßàºdZupÍuýÙ‹,Ây€¡¨,J‹Ü·®Òƒ€ˆÞ>üàÇlE®P ‚«‘;6Â/À°*‡õÀ-€hÌõ0& cجhŒ+ð|s!æ9XŠ©!E-QÕˆ8ï¡}›W•OÄŒÁ h ‡Ñ° ¶„©Ò z¢¿õ9g­>÷÷}ï¦ï¿òÍǾîruÓOóÏ}eXG8¸ª†„÷ @zßžk_peÿÄc}ÑsWuè'õäá­»(!ñª©hÙÄy »ð`\‰™©Æ¼i³°Ð9L50yЛO{b13—?¸¯œ™;îÍ¿³ò-'c˜„Ù‹ï¿ä’ÛÿèýØzèöƒ¯¸h¸oîCÉôZÆGñ\ÚC&¡Î;°þýw,Ù¼ák—\%z ï÷ý–ß¹…çŠÉ@Ö=–i*@!ˆžÄpÃelaíÄ¿âÅÛÎxr53§F¨êï\úš´õXƘm@›pZ[a,÷‰e‹"‘y‘Ç+ø2xš 05”Ef}ŸÆ¾mE•#Ôêu!šõh"ó^”õEê@ èªBaYŒmK‹6ŒjÇ™gùž½û~ü3Þû^´|2\·:Y¿&^5­šŠWMÅë×ô·nìmX·˜Ðû«ç{ozçŸüÜ o}Õ–ÓOm¾Ò ¶ä™ ì* zD Ââ…ÕOþÔú[6~ñ¬‹ȸŸì¸ô‚“þꚎfë@µ\ZN-׆·£D# yh&?¤ž_P÷?èºKëih2Ï@(BMÛ¶f=*Ñä´µFi™² oÚìF “à`Ì· MxP€HßjÚ$iÑ€Y@o1ŒZËYÃ2†eÅ™/—Zc"Söt¦ˆÊ’¥–—Æåôø[¯¿ý í‰Ï¥Q-b˼¬”#aùˆC]E¤äÄÈJ ÌX˜ºmaV™Y.¡4„3Ôä4uâó„å"ÔÑL9ã²ÐTµ W÷dæ+Ë ƒ‰ZJÕ¸GèB˜’Û‚EYi+Í bŠ aê"UÔÓV[T¥²väe«°Ë—mÎûn¿sâàé¯|É#epQœÇ¿5¤õ °ßíïo/]BlK³Úþ5ösíÿ€³»Çœ˜ïpu2í»ueã[¬ ó]y2]9T5°lš¦mö«ß¤@U¡6°€v@ œ8 ŒáJÔ– ™€Ê€0ÏQ*lŸƒìc=ä¢!J9‚9†þ’ âXp Ò@P8ï@;›„ƒYƒ5JÔ•jتŔÀW®¨•úìcÏô+–úñ÷þäÜK0LËm׫4‡ÈQ›–PÔ@ÿÀm[^}Ùú3žríE¯üÖ‹_ÕÔwïõÞ™^4ƒ10VÀ–Xy´G(€IGOî¸ìG¼ìÂj~¸çÚïÞÿï¼ð¼ûñ±Óáà´…a01|×û§šì­[nÿÁ%WeÀÿÔ# £P*@ý³|ŠÅÑÎW¼¨Zí¸äüxÍÊÞÏÿ¶â¡ TŸ¤ŠJGi‚¼m“nÃǼ¹5ZªáèoŽyª˜´"Ô¯³©] «åÚ =æñš¢‰jë‰l¥›ÑºÝsjÝŠû$í#I¸zq=ª Ù®G£¬¯Ò¾HÿúGç>mãÇëµBî;,tq°+€i` îWYey‘åã{îo¢€Ã©å½ë’뢵«¸ò’Þ†µ¿±ý÷ÿà·òµ‡}ýÇïùÄ[Ú ÐÔ(é ñR©7Ÿóí]o?àY§Õ ãC^xî½_ú$öiƒ%žQǤÄÑD~€rßtXÅ"T³À>û…·¼ï €pjùÄö­~çFÒÈ é¢Ú¤i ¤‹š6ᛜ6.[M›`ºeÚˆЂ軾¸  è@›G+hk˜6BÅßš|Õûƒ ;Ørj´„{BüÚÝéoև˞‚5‘±=YÏXjiæxa|NHä§÷î‚„–‚¦Ž¤™w~üÕ‰Î#”¬m‚h_µy-ÓFRQh?Kxa8ŒÓTY ëÄæ2P2PQ^zã ­S ­{A¦RÂæRK©|ûÞ¶d¦à¦äQZV0Ì€ÀÔu 7BPê°ðµs¥sÍÉÙ¼f×ÿ—S޼ò]«õÏzÚªcŽø ¯»¯ùz¼vÕ–“Nÿ·Î~C¤õÏûôa?m ±-Íhû7JÂýã7—gå»|4™&]8È…?<ß•?O¦ÇÀºîZY²©‚9è€ìÎ{ÊZWNÁ§ô +‹Ü"÷@ Ç(€¡Ç|kàè Ä`Ì *¸ ©ÇœCê°³B ŒRƒu ¡„1Ð5ÐP3:˜µEéa„n²`[Ðp×Ý÷ìºÛH±znáÇç^ʺVÊí›;…ÐÈ¡Jœ¢pXqÒ±½G=ÿó;¾¶òptuŸØœöÚÎPZ)ˆÂh9È>Ä]\gÓ>~àùgM}øü­wÜ{Í×nû‹O_zE FCçxýïúoòŠßqz¹`®«ìÚàŸ`ôiœY¹°G³±¨§ŸýôC_t¾gQ—y–ðÜJȺOÒš†òEÄ6‰á¤v7Aüð­¼êÄcþä/[žÍK©z&£Ü…¤ P ´ ­HÃpPƲHdÏý$]ó¨áSnt]FÛ«óë{$ëû4F!­Zmu„¶Š\ÙK²~öDÖ£Ù¨jƒL3ß&ù=k\W"sÛ‡R‚]WôÞâ&€fv~4;/—M}ñy¿ bÛ{ÃMÛÏyÆÃмsלuñ`ëFˆ.I˜0ß®Gâ%Q‘(·ŸwF±gïh×]Ÿ:ö)ǽå*‹ ­]2âµLZ˹áÜRî)÷‚D¢\óÐPé °âQGò¼³ô‡ïó@Ñ$€4L¡p’"$  Ôwš6ߺG…eÒ ®%S¦í¾!?<Ò¢Ñ&ÐæTvíV´Y•6yhrCО¡à`O´ ɵT¸¨.½$DzH°y+¬ÖÆDÆh%<%&å<3¼0ÛG·³Èº€BBHþ.RTˆ?ƒ˜”¹µ!<Ò¥¦¢.îL_¥ Í&ê!c ÖÍS–Y eýàû.“µJt.غ¯ÓO7¦6¯M¯ÎŠŒ³Js¡‚5m‹@áJÚà¶(+µñÜÞÖu=‚¡6f1k­iûp€\5uük.;ä’óÑÅpáçw|ã%¯yæ×þúßµáàWtX=¢OÿþúK³ږܯyÔ}ñ'Ét#x¯€•;w˜ k‡wß›kÔÖãI!*ëPzŽ@J‡œ´ í$Ь†-Qã ÎÀPÌ{ÌW´)$™El $2bá:¡· `ØÂPWHŽ;¢øÉÙBÛ¶Š€À¼Òó]*³ Hà ƒV¨ r ­`4°çÛ7äß¾A(°êø£ãUSæï¾tÚiqcØ:Ĭ@Í`M‹B(@û½o¸itçî½×}ŸrÙÕû€}ÀÈÀGxÅ-ïaâµê}οµtyûºô Œ¯Æ™%uÎ#³Ú>}ÅÄáV."¶×°Ï¯ãy!b)• ZReÈ/€¶v{üvïº{ËOÉîÝ“D9×f@Ç Ë)s©A›±Ü¥Æu¼¦Hd>Y GÅÄ >wЮkÁt„²Yrk÷(xe]G®ìÕYOeý:MH¾ë;§LìøFÖÙDNÀç 5Pù‡ª˜}ÛF ìj“Q²ò„c6>é±ã]w[­{Ö…Ë'Ù |ÿW¾¬X–¬]ýpŽíOÿüˆ—½pÃãOÄ…@ØÆê ¢}HÜFà…×à(÷Î~ý’ßéoÞðÛ?»¶·a-¾Ð¬ÉCF´L÷F#„¡ÂSÞd¹Ñ˜‚jZšuOyü o{í¯ÇðÞ=Íip™± ¥Í:@èCFé )ë˜6ÁuôíÚ ÀÍ娠 õ`%à€pÓæÛ¼mZxh±”:"| êEÐ&g”"ŽhéÒiJ„ÏÇ rðÒðÈ€?d³åÆ`ñ5SK¡Ñ<Ô•&c„¼êUYäËv=êR=/ü™¦ÀĶM«/<÷þd¶V%@’Þ㋬4°AéQyÄJ(‚Šaä1ô8Ba©öÖ^W°…ÇuÝ=bå Ô£ ]k¶!óÀFŽB!9òµv}½¯³»:ÎS@¯s¿ÖÝî²iP8:@)Õp ´†×JèªM6!@Ä wèe.?ì Ÿ<ç¥gl*`Üïj…‚ °(€’ÀzøFÉ”fæçYHà%ç1t—–fð²¾×€0ŽQÄ(úHûH™¹÷ÞÏõN[†áýXßÓ™Zp-¡äƒ`ŒÆwìþÙû><þýÇO³]\šX^P­!ZA&1ìÅÙu׿øÄãÿg=O²}õ‰Çlœýì8ôi£h@›„ÐÖ2m…)H8®ÂA•È<‘ùÝߨrà¡·ýð@`@ȪžÏ#·†YK´‡…(µ¬Uè«^Õ®G{$“TÍtEÏ–ð¬ƒòmdLsðVk:¾­I'iÜ0˜ýé­EQÄÖ%kWEË'£e᪩hr­[­ž W¯pÓÛþäžk¾oZ?uôŽ£vîøšÍº#_öÂö“ð!Ð&½R¡$¡'‘'ðÒ).ÌÆÛO¾éŠ‹·vJ8Íæq?#£– Ë}ƒ« å ÂCPÆ]$JÎ  íº“ŽýâSÎ_yüÑbÍ*õà>Î…@÷û™!f ‚¶¾‚Pᘰ\Z!ôm÷ÀAx€ &°Ô±ŽfëâàdÇ´µ6Rt[T°Ð2b ó”»0­¼ p}â_ùìÝ'EµáD%¦â:´p¼0lµõ ¦ ‚Äæá…UU…¢Ö,™ªhªÊîF´—d½*뱬aÚxnü†Só]v¿óýöànü¯¯“[6LŸöÄ»ßó¡©|×ÝÉtAQ8Ôaw?.=J ë±È”l›ÇAâ0µ_dD¬–Ì{8Ûå`ù®þ| H ‚æéñÇÔŒ›[®¡hµek€úÉMجݵ>DfÔ €/àíCåT ’X9½%>ö¨í?ç†'œ½»9ÿ¶CÀ9¦ÐRÔ#7m›a0twêæ•ÝGŒñÆ/¿i#e¥d*B™ `ÜGÚCöÝõ'Mb£œWËæ\Áµ€žÀh€1Ôt9Á”Áñ¯Š¸0\š>IA ¨6à%¢EÜF"¿vâ/óâÞ†uÁ²A´fÕÔSërE¤ IE™“DI(áµµÌXn ¤U0®’Õy"óI6ì“ô”?è]ûVŠáø­î/{.ë#í‘,ñ9³–YK”÷žðʈRG¾eÚz"ëù,fÅ-€žxC €Ê£(0 „QÚìFëÎfÛ45Îæ~tËÂni̘Q £•Sñ†µñ¦õÑÆµÑº5×_õ»°ÖGþÖcŽºòE;Ÿ k|òÊmÒv -ô„xi>âåCˆ €lðP‹±¨pžǤãÎpa[#÷4E$J/ -̉ǽ}×q;¯õïÕî°ìÈÃðSЦ˜ªÙ`JŠ€À6ëÑÎ=*I£ikÖ£¤m²£‹k FZ¦­Ù6V·š¶´²˜Wþe4¸xL©£Â…¤r’B„|Ô›(ov7ÄÛ¥®¤I9/Íä–aL #9B@B•œp n vè¨Ð¨µ¡®lÀôX$4OÊ|Ž…ÖH!Ä‚öó„Ìy–Û/]ý¤pOEk—¬È%Wa^yCf<áGÎPij¶ 3ÂjÍ¥Öv„pä"”¬´¦ä¦àÔjfÀ5œ³uºF•#ï%ض)t>¿ûÞÏ?ûØ7^)’ø7¿ÖîØýÕç½ìÌoÿíR¢ÇÒ,Íhû°$ýµûOÊà6_y €åO~üa/½`ÍN:ú¯°%ßõÞ´ò ÍÑfsÔ€ô›¶…›wøäÊ€ X `Þ£œ‡6t*º6G +WDÇCO8fïy—Ó®Sû  ß1=§,ÖièËå(rÐÜ‚ ö-btÀê'?>{÷ŸvÝ}ý_ýM#E{ÖÓym`Í`2ø1X­ÛM®¢nCÊÊØ…´È;º¯€¢ïSCxmIUDÊ>Ò´Å(‚a½lù0BéÒ’D9 Õ€¶Ï_{Æ6}¦4(„çÌÙ@Ö2v”â <‡Y\ÊH­›ØsXøSÜŽülM¼zŠŸqÌÀŒ%eNPÝ0mÎRU U°`\ýЇ& òU½}Ø‹É6>ñi{?õ9飶糾Oc[´ Íyg(/ /LBò–iãiÏe}‘žò‰u8gO}âÛVÕ=w|ýš…û¬Ñ¢yß5ávû½–KŠ ØZU÷íÉïÛc®¿‘/ŸtóÃ0À/»0Þ´þo~7Ù°6Z¹Bô’ýOÔo]úLü5 ©U›ÓyB¼PZp‰ò¡sûÜ€0ïw£ÂQ8N“VX+„ܶëQA"QÆ¢Pä¡a¡eý‡ó_‘Ý»GN }Ñù§ïÁ®qK¶1@zHCPRPßö_IAM-h#m°íÒ×iµqྭ±¢é0íí -¥NZÒÊJF¤¯ƒ ï%Uê@¬3…4Êe”¦Y§Ú€5ú¿Äæ1)œ ¡¬ö=°‚jM…öÂJªB]9AëqÐ ³^•‰J/²Î|Þ¸yŠYP©=2HkêxuÁ`£¼FôxÂŒá®]MyU)%…fRióð#O‹:)kSrUø†i« jÃØ¶MË8tõ!ÓzjùèÞŽù­“ÖŸrÂ#ºÐ]ÿšß;þm¯}îM?}î/߇.Õ¥/ÍÒ,¶ÿ°ïŸpW`ÿŸ’íú\2ŽÁjV“¦ñOuØÌ»Çi&ºN˲»¯çÀ €óM“‡îºš`4]?À²££Çí¼í¼ËI÷A¡i.m¢³V%Ú<ŽpH‚Q @¬ÁO¡=œÇʦBØ Õ]wŒÿøÛÅ­%À™§ó€8Ëá Ô5¬†ÚÒ³¦vî˜Ú¹ã”Ç€1þüo.`lÁj¾IÕ ¶Æ7;‚Q=±l8kWFUIµë#%ð!ªæ½0#«±°s@Âsâ¼ 'ÆRæAšPÓ!&À“&QŽJõtøàËT³¾Ožñ²ïRAtÚšP oI]ªä!­‚AÅ™¶5[ÝÛ‹{€1Š>w+ ©Ð=’õ|Û¢©Â$ÞÛŠµ · -ayÏe=›I¦îCÔïºÕgóüN=ᤚñý.2$‹mªk À:׬P—l~hºÈÀ[?ñÙÞ– ñº5ÑòÉpŲxõÊxíªdÝêùþä;¯|ó£ßùßqO[6ÚH%UR*‘´ÉR…¬ŠD9¸kËxëÝõü°¡Ù˜°FòFÓF…gðŒX&7_¶L[@X`yhd ²{÷xàˆ—_­X†«2DMØG³h·aÓ^p³hD`]äÇ?܈жd›l§ÞYJÁ:ûB“Ó&h+nk@%-ÇËZYa>ž/BRɉô> "Ð~dc¤,BU‘S|“âaN"¸:&EBr+X%Âê^I¥vÜZêC]Eº´c¦U2Èìj#”›ŽÞ9ˆyíf©ß¶Ní‘!ªÀÕ‰ÍQ!ÊK¢ýÀŒ'ÝPY›ÀÖ µ 2âFŽ ­ TüÜåqÈv'…úÞM+ß±b ÒŠ »O°i¿æ†ÅšxÛæìË׿|mS¢š‡Ø¨n£.ƒc X-0k k0 Tµö?/{º_<'ÕCVSºÀ¶4[ÄKÅe%ÂJ„t¬5ñÖ{­êª¤ô½*ói›zÓ‚¶yøyT™Ûý’qpÏ *]L‹¤Èmɼê‰l`ÆqY¦®u ”,SdÄ,&uáP)`:ÃXAð©ÃØ!:ú0wÔaƒSOùg\”¾ÿæ?:æ /?çÚë—ü¡K³4K miðñÙ?yMüeipÇwÔ±o¼À_'ÓXqôá‡<ÿì^ý{¤S¦7H+ÞÏÚÜ¡—u5AiWÛPvó`Ã~mªu·kš†ã[ÓÈÌ<ïa¤ +HÚ‡£ð¬†2 ·i°b‚‘FP"ìmAKÇ pâ&¨¤)ø³eÀ³^ ÌËáÆ qd÷ý7ÓGjÁ 7–ÏfCºW­F5†àZ³ÄFY—…œT è´%6¯óÀ cŒ–[Îú$D+È&¼£ ©ÊUÖÎRîLî¤Ø›!Ž‹*c[ôXÖ€6fí"hCáTÁBÔA¿â…….Çц“îÄW}PG(«Dì ‹ÀÖÔ:ªœ.¯ )|´L›TµOás ðø³ñ™O¢6çÆ®è«#Ì<ùM…³Ás[þ,ЇÀꎜóY¤ãVU‡Øš¦,bµ®¦]víµ‡Ü?úð…{îæÓ¾ Õ¶Ò)é•´1"H£d "[F¢LxÞž—a ÚHàKA¶?Ó†–i£Tø±E¢nÜ£\×±€hžô€€–yHIÀ‚’v Pá ã;?i;bAí@›¥ÌqÒ®GZ6M©Ž<¤¦l6¤ÂDª I¥… Ò×a ¥ºÕz¹‘ê$„ "МÊ }4S&&E³ZmºGy`87Ÿ¾åÚ³}ìåïòx[ˆ@zPM@›½'memuÇ´IʤgÂsi¿võã mÛRÅ Ò¸G™wÜK§Lsám‚¶Öц–Û´qÜö—nÛxgVT:"¼ô@{"3óeû’˜üèPRŸ%ÌÓÐÅU‘ôó„ä!¯jD¢¬DH‰³ó¾&`%T‰`\s”ð5P€ä0ÍG•¡*a÷² ­ÁĹúXWQ^Â1Ÿ7m5ïØ‚ ²*H©í¡-”_@j @j‘:øü³¸ü¢Gv!Ú³÷ë/|ÅÓ®ù‹çÿ×Ë–¶¥Yš%ж4ÿRØî—1p>˜L‹.¶×u›Ë ä€"Y·:Û}_@ÞuÛs`â¹™†°iz’ή˜›„`Æ!%ˆ4Ö¤€.Aj8@PÄF5FRCxŒæ4¶N ðˆç€þX8–µ ªÆkpÜ*¤ŒG4=ž8˜ÇšC Q)-a %¼æÄ ‚37"! òD窔}N`DášL¹ÎÍ.ŠÕ½½ÒªÝÃÍ2¬i࣢ì‰,äUˆJZÅ­µ¦s3D¤t<¶õ‘ˆ£"Ü[õ{iÚlÆü˜$È4uΨ &«:W\^>6,E¾_þæ35[Ú\IyiºVSíT)E©}AM[=1¿X–±)]G¶ mU§€&ð§_'>r¢ë±Ñ·ñ{ {B+`Û9ψ7o¸ïïå@ ?dßíwªª^¬§j̧ëÎyÆò“޽þ´ç%@à1”7%ñ •’^ ®#^ªHJ¢×£}šF¤l‹µBjh-9•ŽÂQ,F~˜´QŽ˜/c^ˆ@7¸- µüŠ?ö i(¡mZ/!aÄÿ"ÓÆ¥#‹Émàhw© Óf%ÌQF¹«x°è`€À~ ­ ×¥íq Lý÷é©çDŸ Â¹Ê@…uÕé«~ü‘,{84ñÒ Â…!ÜK§b[$4I±RqYñ°G2F¬]ðŠBä¨KôÇ51Þ5¹ƒ ׂ6[ÀØð¿ð“Ý"´•' 7ï \\ƒÁ{&py˜‡X°AV)Ñ5”…¶¨Ò´•+sÜ /¿dã©{D——ÞôÎcßxåþûÐ_»Xš¥Yš%ж4ÿnñïïì A­[}ÐsμûoÿžurjÝÝû%òrªŽg1-€J``Æcä ,Ö™Gnà œah:d ›<,ÃHakŒÔ£N!çÁŽF5­@K (!7aEŽ:@ša]ŒzáÀ8(pçúm–ßgÁJ1gÕÒ«ÚAY7  ±ã9?ÍÒ^U„Z‹´%Èc¤ö ÓFK÷ÓU‡­®÷ÆAáf}4¨+GªŒd9Ѩ…ÑÂêÐVþpFdÍ<#+¬º˜GRå=“õxæJj2îS©2DE¬7­KÆ3#æu ÚRãÇ C4ý§¨.ñy]¼4A^‡¶¢ÚÕUÀ+ã Ú@ä³à³p)h _7~ù˜~•ºŽLÉ C2/´¡&Ú“±Á‡éGžïlç6X$ÌL÷4™^rЋŸ;}Þ×}*äÆu›žýŒ,Ëè›ó[wå·îjÌ Ú~âïªOüÝ  ^æÒ4Z.`ÒJ¢¤WT¸H”:Âi!udËW2ŽÐ‚6ÆmÚx`š5Ö1mÜÚÆ.@(÷‰ËcQ„²j@›t@jÓ¾3M»#`¾«X`@@„ЪӴQ©©ðì¡ÝhW*0æ3†Sæ(#ÔÁ g-Í&\k•Ýk¦mÒªÐW\˜OèsÎ%7O|.´„ã«Ô£âˆxiN¤G4WÆ®h4m’«†ió ÖÎ{E sÐfÁó^ƒ”sè6‡Ía h…½w®& >àµu,. 3ë¡üÀŒé¬CÖ6ñ¸lrh‚¬ÔÚ@[d ©%lûÖ£/:ïð—^ðˆ.&|ó»_:÷Òçßã¯Ø‡.A·¥Yš%ж4ÿ¯Ü/#á>sâ3ŽÓ+ïþÌ5£Ûîôt ºYç1l2Àú€êöª®ë9ØÒ­JGÀØa»o;´zH»!À%ŬÃö0«Á2¬8Õ•,ÁkÐ d=0jd™® “!`0yÀPfÊqʬ•Pœ"< ¸œÚ1³CFFˆUá4-ËÈi•e\¢<*°È†yEK·|ͼXÐáòŠ,XAêQŒ"Š~”†¤¶m¡®p ÔûDoágHâó^•Ų07)GY©95NT cÇ…áJóÚˆ±¶c”=dúHû>•¥â•᥹NlN*ÏKÃKc ÖK²2sÚ@îƒO ÎV ÎõM˜:T2Ô‹JË@‘ʓԓyÁëñ¿ß҆ȚîÙDSþ}Öi\ðìzfî GŸJÁ·^ui´m“ZÝúþ¿ݺ+a'Á/;Ħuh&@DKé•ôJñrZM›)#Qâc_4ÞÎ £– Óà°&§Â1±䇧ÂÇu+hk›¬Ôß¼údÄÀkÂ¥ùÆç̬³’BÒ&‚D­¸lú²¨ðTºOüÉ‹Ámk¾•©q ÎqfeŽ2mËyâÄÖXM›_s¿+áthªˆ–†s|ü‡çþö©50céÔÀdü®úª ø;vütßT:[XÁ¢²Œm‘°,€ õø_‡où泿ãÙGžü„¯ë Åoÿ݇¿ø¹ßöŽßÇ;~ gk­µ†¶µþ¿ÖƒéÔúŠÜ/O¶š£úE·‡6.~î3vÿö®ô¾@qã ÀÙ€öÇïô‡¬€L ”@p G›P%ìX\°ÌZXføQ`8¸ˆ:áÜò<`8`HHäJðƧ@’H‰'"‘2BxRÉÄ’ú’_xóÝØRÞj³§DrCï}L²¾¹… ¦–æ®/­Ù8Öºí"+ºbÒfmÇRè0,mà$°òÔ´ò0Y¤ k²¦“IJ:ÄŠ¢†jŒt6«;Û2ÓrW1<7Ž[ïj„%îýüå¢uo‹Ô*gü‚‹ÚñΣAÞhÕ¡Ðε"¶®®ïÁï€ÕˆÔAû<ÓêÌÄ4™éº:#U"‹DYDÒ$¬€ ±BÌñÜ>YaظîêÉc®þøíoø‹ÛßÀFßôêWþoW¼ú»ÿúåƒoø)ŒqÅá pÀüwOB»É—ÃÞ=ä5 ár¢%³2Úþt@ Ó3YÞ NÛÏýæë{§ÑÀè)h£,Q$†Äe®?D”CjËx(D+¢Êýɽ (€˜œ¶Ð¦†j)Áœî{3 #B8ôw ãNÛ©…¶ƒ:94в¹ó‘2«¢ñ‚Á!F(ˆx Ú(@ASÌl—¡ËÐe¬KC)~ã£ßùê‡ÿR»y,ç(ç(Ë„œi©lRäž=pÚ Ò&NŒPï("ZÌUù;ï}ë³óOe ´%\ÀŠÃ8x3„Zßô`‚êL$”‰à ,ÂÆÐ€•´Y²BZ!V¨ÆÀtñ…ÚÚ»~ûÙñ &Ç/x0_(‚±ï|á÷=û÷Þ¶¾]k­5´­õðؾnî´GÿódkãòKýC·ïöoïû/ oHÀÆ ¹v ’84†½„ÀõvçP´ž`/áj‹rU‹Ø"¶8ìaÏi!-¨‡˜à0…:>†ù>؃'@ÆÙOHjø³SA($¥bÒW¶Øš¾wEׯå“À5°ìc÷î³ØFàý(¼‰ *V.§zÒ5Œ=·¾O̰ ì{Hû$kºé¤f‹ ˜ãµO5I5•“ÎbEÛ˜–u¥âçÆ·VËyã Mo ´¬ X€.ãD7±¥ª6ت ï¼meU¡aà;ð» „`Ùœ“·švQ¶VË!¯5©S\R¤6…¡B,‘-ÑÂy‰{?~Ç?~Gƒ>é pü¥Ï?|åÖÛ&[~ #‹ãö?˜}ÇïUÖ¨¶Í\—ñîÿxßþÔ+‘CçIKX™lNuÎõTV*›‰.Z&ÛÛl„&Æ£Ap'”ÒÉh‡&+1Øl‚{*’Z9³9×îß½ïU˜ëº"C1òVo¶Q€‚±€~<ªRï´QŽÈiŸ¬ûg?þ<ŒYiD1‚ltÚˆ”±T4A°Ú%VHÈ4üY  Èên°ÙR—S6ä8æ®Ì¡{hÛÀêÛÛ{ŽV;‚¸¤HÊH®umm'¤ œY.=å¤Ih1'å&_~êã·=ê¼ÿˆ)@¥sCÎÎSÏ…ê`OJμò&$–]¹L Idlhà,4@¤ÍPíT_¼{~Ý#/ý¾—=HbÀ”üÎ÷¾À¶ÖZkh[ëÞ}å;†ÿ€‹€GÿÔüÖd+éTýÕ¡T(ljÍ1I„uÊ„G$hŠ……6H-6"Ü!¤Ä":d >@mõËqÀeÀ. %fçÀø¤v‘8RÊ€M†·’ŽaWÝBÛ…X9¨1²Ì+`8„³øîjwƒ;O^¦ W¶hÛ|ª‹®¥6òè©‹=¨a ì;ÀDå²®›tX:A1 5REXh± º›&m›Êĉëh2N÷àWܼ-h– KÐýHWQ6»À.°¶d«ï¯á<Ü.ì¾÷º ´¡:ŠÆ‰Öat7æµ¶ I\r]"T %üY‰dÁ(Šˆ³€=`Ø6Ÿø˜í_ûí/ýÚo÷ï­>¤­¯‘Þ6ÒKiÓ(k”5¢s™è¸ôCO¼@îužt‘Z)mNt.ôÔÔ¢Ñr¡ ×"(qÐÆ•Ï¡s¯Ù$Q …ñRÛbÖ¢ýþOüBÉÆx(R;@›Àà´õ%Œ…aZš¥ÞiË©nï“u‡ÇSãQ ¡°{h#1e¡ ‚yÁS =·9) <ÍÚ.s]», ãÑbÇÿ¥_÷ÏÕÍÓm}ƒä6)‚ˆÚâ°Óf¹4\EG{£w.˸ڌËFeŒì ó+Æ}0ˆ¢Æ.‚qœ0ë bÙ6B‡•‚³ œG‰á÷i€ ¾ý[=õIúä”Ú¸ôøƒñãü¿ôÖZk­5´­õP¸¿oÂ}{sÀÛ&[ýÉ¡(àéˆký¥ÂÁÒ[ßpJ€,႞¬<¡Ã`•…p 9^ ý£ñlÐ]ÀÀPìl¨û ‚D’ )R$’ÒÀýv¶Ž&È$ î†L|;¶@(`M;a.‘È ÅÊ¡En4«CàÑŸZjm`þÁ!‹]¡[ÚEμRMh± lƒlC,]VÏb-á4¼Fö'ç m$·o¹÷d™†£¿U°UR;´a«€º‚«àwQ8RmòÒ‹Ú íxã|ÜÙKª4]má4ø¡‚X–Co„OC|îYÀ8 4øX=Þ“Òñoc–›ÄÑóP¥–ôÐÆµÏxsŠC2pžt[IlžtÎõÔÔyÒ½Ù6¥õ”ÖÈ@PÇxàÔsæ…r}^IŸúÁù)§q(m&hr¡‘9ºvâ›NdmQŒÃM2P0N Lhãt÷µ—ôÔ%˜s‚ƒ÷N9å´ùØ7Ìò”Æ£ýõM"„…M„˜2×)o2tYê²Ôe¬£}©¼@„ЏWóX~þ½‚顲˜$KWè¶ÐmÁh£<®H›Ð³Iµ–d•ï>n%>Üj4ÀÙL|³%­[B}t>yÀ…äÜ.–K€VHcgi4€îzÏ_ìÜ}_öðK6~Éäüc‡yÅY×<âAÖg¡k­µ†¶µþÜé_ÜϰøòŽÉV OåÒËG2èW•ú)jè ˜M˺vÓ„iDšÃDÐvx…Ø@Ö tŸà/„X-B†Ô;Ĥ¡¢Ë>Úè,òÜ– Æü’88TG’ÒÊoe¸ì‰÷•»sîý¤khŒ<ùáMì·ß*` Üæîèè$oØ2pâsÌ,%âr;² ² ÖÚJ 5°¸T6±£9×’X4`‹€%Ò>!e4B‰|dMƒA š\»M›6*±*°:ÐefµÛÀLÚ£µH5Ä>b²„ˆEH§È,Œž(ƒcÙØau`Pz€fê²íG¥¶-SÖHcyç3ÚU›³ž„r¯{hË£–l¨@˜¶unµ_W° ÄXc%’ìlöõû9L‡åMVó¼}emã^š  „…Àd ‚öN›”6§üA Aœãb0Û9å´ùÐC›ôN‘a<Ú;´š!1e¾Ë\—Ñ.Ç0¥|„6N(oÜøY"Óu†.#]ÎtR„¶‘ÔipÚŠa§ –KV†¾elîʸڈ«IlîàÆC œÕa9Á슇GÎVw|VÆ4©­¶µDòð{؉h ´A4§ºËÚ±Pجª½|"}ä³ã<ù—~ú«Û™××ÖËmk­µ†¶µþAê«ýËû+®Á}ÇŸö“­ƒ¸×¾II±ýÌ”1Æ{ÿÂß¹/ÜMv)@Z€‚0D ²­Z u1Z‡|ðdþÛ…0îÏ7ãïnápºqƒg¥Ç+‰h@»ÈX Γ¥ç+/W–ˆ$jGx"~L.YûÆ—›p;BR«ˆa‹À©g4 O[Â/Aà; ÛˆK´µÌ­GÆ:Øa]œ-BÚ'¦‚©`JÄr‰UN`AâU¶•Â9R%ZEV…Á#Z‡*@[Ðül…&~ÈûèCÚÜiI{=®eÈoˆÜccÏÕ£õÕeè˜kÅmÚg¤‹Ç(u9t†.Oº­ ®pm?-B+X¡Üœ–ßù‘ßè™IP×C£AdŽk_øVÀ1Õ·Å!gžò¤´)ТÀÓ¦:SÄVó|˜kóq<*Ahb!Hiµd= ár¦‡îÑ|€6žqYY4Ãxt¢š‚´ÚDN뺘´-ˆN=´m†e»ÇßyÑÏâY£cU@•U)A8]õˆ“öAã ¢³)ÙTÏ!+, l„‰0iè¾êO}-!]J}(€+o{ñuo~ÝWËûøšLöíö5½­µÖÚÖú‡‡k_íËúß_ŽyÖWzÝL¶úï+¸àEÏ óéÉ÷¾H p-"²ï‡ÖCÆ>DZm€ J58$O c —s `AR¢m$EÎ&»±³©ZPYˆ dü~+'æŽUahûêgN帶 ìBV–ˆT¨‚9!à4,–ˆ Ä%°–ãrÝPÚ0†9qˆºÙO¦†©àKÄË„}`/Á$¾ê²fwñô?Ù ­‡©-ã€ãaDXBu„¶Kø%¨ðb;øÙös××úÀä~M«æ(ILÎßqѹÚò¨3ѵY‘GG¥.]AZÅÍ©ñh§‹¦•Êrâû‚z‘œ NPÇd`4å2t…oyðT&Ž0ä}ÐÄSÚ¾eõS,¡`(•ÌãÙ*• IDATÄ5šåP@-‡y(£/¥Õ²@6BՌŠÉ´±„t^äi|]”¨<ùH™¤ö òƒ’˜ó#´Å¤¼é¶ŒtYÒí„pýAF„òÈ©ïëÎúóR%\ÚTR§a<:o'¡)H븠 ?q-¸ó3Wm†å Uæ;µaŽ}ëËübE:{ßoýÁ è"Ž\ýˆtÁE_ºëw9AÑ¡KðºAÍ—X6Â¥S=%8zããMŒöoï ÷o½öê'þË·{âc¾1\;ógúZk­µ†¶µ¢Äöà¿X?ø8_mNx÷dëÂç>có…ÏúÔÿùÿx€GËådë€Ø’D H:A{$¾‹Ì>K©åhÿÓðÛ?¼7›4ÌE»‘ºˆœ…h€nXöB‹¤ µ‘N¤õÇyÒ-•–Š”@ÌØT;±™'CTŽ©À‰O„P‡°a ¿„_".°JØ  +«~ž±UF’ý™_Ÿ‰º@(at=´«„8ç›o,vÑ—þó%MâĆßò´ƒ‚}à$t‡¨l¹D뇵ðÀé´ ]¼øL‡Ö éÇØVÀVºH ‚ë„7¼ÏãÏ|—ñ.rzm9ÑÚ‚·Yê Ñ:#dmóZËsí4ÔÈÀbè¡MRË¥çÌ"兀ò;sÜ—é¬jxèo'[Ú 8oíÞ á¼-ž¡ýÈ_wCáA‹åù0Kt+º†Kp%„Y)Pƒ\ܲ Ã^…I”@"ôJƒÛñ^¡F¨a+ D¾l„H@[PŒ ädX Û<)ƒÍ±¹ÄùºŸbxê-Àú-x°£g¶–»˜¶Ø X5pÎóžyîKŸ¿wâ Ÿû­w¾êíÀ°@ ¬FÃoØE`(ŒEç¡Ú8\‰öN›:vö‘']ÏŸPïì÷6Ûm—ÁWð5bdÑžf;âê4%Τ†`ÙZe i‡Z­³»í=yD—sÅ.:O:gZ2;5u´45$¯u^ëkªO"žG/‰•ÔJi™9Ñ9tá[áHNˆá"Imßø”ŸÍDÇ…OŠ$E5ʌЦ@xR0F*ÈtÊi“¶?ÂIa í pm”Á ”óœ{EûCšs' Ñõ‘½Ó6@[¡Ía8D8ˆü ]Æ»ƒëQ“„寋ÎõÐÆ[ß;m¬¹Öy7:mB¯S¾rY¦³ÎÍy9w%/-VãÍg‰‡ïÞþ©›n°ËU¨êÍ[¾e¯2w~èN #XÂ~à޳ÿé7Z ¸ä¢öÞ“±3ýï|äkoËÎ>@L 1)Ö¸¶ÖZkh[k­ÿ%÷àîa͉÷Ï·¦#Ʊ{¿Â3Û?>Q\¹ lÀ¢Clp¨á¨fÐLWà˜0CZ"4h7a"dBà2ø¬7 0D¾ù®Æä0ªbà D„Œà$x )ÁWh vÇ2ÖgƒõÐFG㫎R}° „ Kà—·À;o¹ÕöWŸË1v®m¶`ºFm t‚uƒy×—Ã&`¾uñ£ÿÙî|Çïïïì3À¯¼¡kàtnX³;ýÖ¶dg“&qEÓ’Ðe”¥MD•R‰,vëIŠ˜œÜ–tÁZIí´©£¡¾æy£óZ#‰‰ÏBàÄ ê„tLLmot6Zx'¼;×e)=ï¼ßɹfY "òÌKjç±TÒ(e~í_½”‰È$¬SÊ8) Àøà´Ii}&ûñhžôp› · PåiJµšökm,Eæ#!P/ƒUÎÁR Œ„‚¯à´…SãÑÚ8I‚íXXœ6V…TTàÚçÝ®šŒwtá³Zg¾+¼žñJ5:tÀb„¶z0P¯ÿÜ¿X½w½á—.¼åi|óÏÌ€+_yëѧ<ñwo¹uþÈËŸþ“?:¹ð\³¿ìö=ó¦óévfÃ{nk­µ†¶µÖúÚÛ™úšw g–n±dXd¸t2bQ90‡I à A]£bpXÂY耘 @Ãy°2`a±"ÈjèˆD <&N´/´,’‡¥0‡Ã€póÕ û8¨@6$Û2¶‰ä!? qþ¹‡/{Ø¡K.2³Iýs¿|08u;põ'ÛÐ5t@ëÑ4¨{ø×ºÑfÓ'üô›.¿íÅw¿û}×áŸ^ûvဠ¡öm û#±9€.#õ½ÍF û)n£‡¶Lt P0=´¬ÍH—S]¶à-³!ʚך,¼¸Ôqá{nc‚¸Þ ËCçÐÒ[œXõf[ 1Ii3ÈÀD *NH³‘VýN[o³Q9õJšNf^1 ‰ …m•”ÂJis§‡8·P <²û«Uî½dÖJŽŒÐ¨ <ô9m6³],‚‡ "¸>§mØió²ID‰¯9kOsÚœ¡uìc–…v™îúÙh[ÞX²ðY¥3¯'±™ç¥ÛÝÓ±BûÀÈ>ä›ß÷êªÆÀ.ðù_þõå—î¿î'tëEÏ>¾/}Pÿ::ó'Î×ÖZk mk­õ¿„í¾®58“òÄG¶º%Žžwè‚s÷So,Î={ÿÓw^þþÛ†!l ¬ÀöÐ~hwÀW_¹·½»wr§gÂïù0#«D\B²HýyDØAÜE\â¶÷kë8ñV3MõµŠ&ã]ž´X9a\45òFÓ³?<‰$–g£ÓFœàN1Ó[­¼Þ‰…Ìsá/úÒÝSY+j @óHTšùjžÊLtJZD"QI$7Xkª M!]¿Ó&„Ë£îF3 c¥ ˆãÊ1Äœh+çP`12Yðœ0鬦ï°b$ô©1!±!\בqìe:§šˆ”q !kËÚÀÚ íÇ£¤ Í„9 ÚB뜶  ´Å¤iúÆ÷ÚšqgqØ+<AH˜¿àê×|Ïůùž¯ËÌ^ÃÙZk­¡m­µ ÷ nÑᦽáåuƒFÁy±P«qºåŽÑzTU…Üb_Á7°aˆ¿‚ ˆ A±ŠP5‡ ˜X°ËÀé¸ù‚EÃ}ª¶|º($‡H @)%vè*…VMí󫯼òͯõ¿öºMãÒY߸°ÀÊcé±ò —mõ¢çd»vÿþí+oºáø³oîÿg/øÍos÷‡H,a,*Š:Aœ}öE¿–¿ ýÕ§W'w bÕq¥[ Ëvqqq Ͼû‹äâDHE6Oå<•tEî¸ó¼ôY×ECcK‹º†$‰•Ä å#AÁºí‰­@«‚áÞ“Ẻ³¼”¶O!"A‚ ßC[‘Z¥ ÉU‘¨Ä£ï½7#‹ÃN›”¶¿•ÂþÂÿø~( œ6F‹'”Á¤]© (Bc >rï#eÒZ%L ´E„8B›KÊ™ÌwyÐãѾÉ*qÒ-3¦Cï´Ic•5Ê™ž‹SM¤±™î&±é¡­ª%Y8U“,è mÜ.\Y{´ ßôÖT 5 ìœ³öï=éßöŽéå—NÎ={öµÚß×k­µ†¶µÖzÈÜ×,Ôºé´ïX¯N¼oº•'œÝœë hæ[†¡N(#.ÓXd°Þã˜A- hÐRÔ@‘< -X‡†zuU@È–"ú3æÙÚ€|®€S`ÔCÔ}:ø®«Áö·wcëèýG`oH69m{ »H;»¸?;6 •`.‡ž Ù «y,ÏÚØ ÷2_ùƒ iÞè I¬"F'ˆ›úz–ª©© ÝÝm™ïhý’ 抣í”ÔD$Émß5‹Õ Õå$5™èü•œßçw<óL)m¢„©!\W ËEèǣȊáz4KÅ à¸tYg<Ñ9ÑVÍ)"ó‘¹(È0o ‚Â1їćÈR ÑSâ’òF9“Å.C×/´åTsáÍI¥–&'š·þÚDçH•REH“¤µRÛÞf«K°…£û^Ÿùζ°Ñ#í"íB[T Ú#¶H5Ú€*ÕgMþuû¤×¾ü¼ÿ`pmMlk­µ†¶µÖz(šmgxჼcxôHrœn™„€6!&Øâ2# Ãiù˜Ë¶fÀ2¤ˆ ˆc¡P_û¨ú@Ý>Ê—a3!Y0É6ÔD h´qè\èsnù[ûÄ»lÑ‚ôï°H¢…³ÐÐG.¾àòÛo­ï½ÿ]/}Í“þÕ[6.=^¼` ³‘.x‹†Â´U@ö„ë6oyÚæ3žò®Þ¾øô=±]òœo~÷pëPжìƒîîÀ¶˜…ÊÞ‡þÏPm`µÕ<”åþ\Q#–N¬œh]4TUÝŒTVQ#ˆ“ÄÎS9÷å&[ŠÎMt3¬µyMªäJqã7ÿùF·š¢&,1¤°2Ù¹/{§m†*Oh9óÂ:"’’†!påh“vê~܇§[Þ[abôÅz§Í wŸ'ðcc·ëÛ„ÆÜ`@Iá6 `@AX"’CðhÒp8XöKk„<î³'Òað<ŒîÉy@“†f÷ó®yÄäØÙï~Úw°‹ÎÒ¿ý‰³ûèá­ï§¶¨Á`%Œ™n\pó“ÕÍ7Οûô?{Ùkï÷û"°yéñk~ðöÇüÝaoLþX+„j€¶¸@ T³XEJe²é6ÒjË9)7âªYL¤°|á&¤/ù7oŸÅJÓG³ØÍR5 Õ!²ˆšº-RÛGµ¥’<óÖÿ¾Ñ­ Þ±e4€ƒ ?÷å´ÍSù¿üÿFR$Ï3ÏXÒJo©ˆLɬ”vêê!§-3m*§- Å ¢Êe¼A?!¥*2©ü`+N€°ÄXI)$–I„Ÿ¤·Yñ‰NCMIì¡mË ¬6ÈjŽ2L™Ü±¢t½Ù¦Œ)H+‰í“A$±El籜ùj†Êk^è¶0m[Z°vB› k&¤á̃B$7å<–s^ÎPÍS‰ƒÓ–<·^R«¤é-4–…¾kaæ«>§M* ‚SÐæ‹Ç•SÜPs¢ ÒR©ÌGl_ZJD"49&@@C ‘ÅDqIºSÐv0MK"6¯tN´0Nh'­UÖðÚ÷ÌE›(•ÖN²¦®`°Ѕ˲nŸB¬ÀJÐ »ÚÁu0&ô)ÎC„ž.ùw^÷æ×MÎ?ö ÛW3ž×ô¶ÖZkh[ë!DlŸÒNïøŠ¿þ†zoÉ×U9ÿ¸ç<ð þ£ÉV'¤}&mŸÅqhÇo±ŸQÑg«%œça'„3Ƥ™ÑÆ›Ðp@G8Dàˆp6>`jæ³³·}Ççn|ÅËŠ<3MÆÁ«4°, 5š:arÅÖá—¿˜m]ü™_}ÇùO}âõ?þC<ÏÔK¶°1ž5´5¦Z´MÀÃ.ÿ[Ó(ž¼L6OzËžÛæ¤ÌéúóSYZ±tbéDíf¤RÄHØÚf±š¥j–ªy(ÐVø6TlB›‚¶½Ó&©ƒòf#®æ¡œapÚP S)’ðŽg^Á(i¤³ç7'[–€æ@7ú"ÇÙáGãmÐzš @êÓÝÒà…¹a½ }+:V€@¨€àâÐe¥=Žbåç>æM¯¡ßü¢x ²o$›‘À3l\uÕÆÓnØxá³ßùí¯˜^ö°Çþäò<ÀšáÊ!Y„¾†mÐ4¢APGt÷ߨ\õÐF›8“Õ¦XnUnôdÒ´û…ª _z¹²låg8m6šºYªæ©œ¥jæ«ÄëBѵÚ·O{ý{'h&¬™¤fBI-¡Ii3OåFXÍQöËs(°i—]žqç…u2Y©l¡[G²$£•Ârç ß á”2×DIm.‘ƒ‘ÀbÌ i3Þ%‚´×d]×OH%vÚ8÷”Å~<Êbè#?ÀA8—¥®?DèÇ£å‚ #–V1§ZZ+;ÛC­†ýDVe4VóTWH øTÝ-)Z‡°„Ø8g÷äÉ’Âwˆ}ºg×üÈ«Ž\ÿ¨÷|Ï>î'~øËˆíC?ö³ÿço|â›oþ™5‡­µÖÚÖúÇ 3Ølk=¸ü2îï›p/xàûów&[}%•+ããø3°ì;¬B@#f HCûhO]n¼ÚŒãó%Ð8ŠYO0"ÂØ‰ÐŽVp“bBÈg^ñ#×Í!ZøÃ ¬ñ¼„cEÀ}ŸüëŸüëÕ[þå±ç>ãâç=£ü̉“øØ%?ñj̰¾ƒmÑ´+ëÑDhàÂéNLT&ÆÏ|WÈ6ºï­ÏÚN–V”Ž®üÒ`Fª~6ªˆQÎlÆå,VóTÎBÅhðš]›;uÝ A:pÚ2ÖÑ•7s”óXÎS9ãÕ<–3^ËÖŠwžg^£¤)h+“ ŒIn3ÖQ'±‘ªÌLR9Šúœ3–w.cTqCC̉žÚZKFêcoÔIi#”FÇ–Fh‹ >qï3ò€ñh½¯ä2©¥µË‰VÎã”1ÊR§~§­On“Öî1Ôäø.R–ÎCdGº‹/ÜßÞ­º@:À×ÿøÎ/»ô¿ë®~íËùêï>ø»ëßóžïúÛv?µÞQ[k­µÖÐöÿ"Yëk2î™ñ_iŠú¼Óžö“­Þ3Kc ›Ñíðc¯1ûK÷7w鱃>›pf ¦¡ÞçuÂ,ô9n`ãeC74×OKÀásŽ^rããØÛÞA-˜DŒ-0¦§¼:´tø³úe»Ý?ÿPû¥ûuÓì~æÄë·çà°ð¡ƒÕhÂìÚb<"T`ɶm!­Í\—¹ÕЩuôØŽ¿‹“ʯ ~î/Þ:'å0µ–5a#[ N[ªužLºfbU› ¬(n&¡™&§š{ßC[ï´Íi9Oå²W´íòÐ&‡çÖKo•0mLc*Ì\E]œ¸FH§”y¤üÔ_ñGEFk9¥1°uIñNDß;mÂ:I,SAÄ!òŒFI‰ÅÐG@\âÎg¬Ë£îÇ£± ´öräÒ’&åT+o¤±Êil_‡€¢uÔ¹*¡.aÈ.fç^²,«U¹ËiqÁën»ç³'ê/ü]{ßvpì)O¸ûO?@ß÷¡gýÁ¯žó¸kû¨úžûÞ÷ª7Ýò{o{î^·^J[k­µÖж&¶µ¾^¼ûj÷¬ñ9¿1Ù"c>ˆÎ{üu³Ç_{Ï/ü‡ˆãjRRŒ~ÛE³CW]^ýåGí¸»FŒ†\3.ÌM/¹è²ÜrþÓ¾éS·ÜzÑñ pÏ=MC@¿Ö"vp.¯¼ñþ²Ú_Zà6 # bh8‡Î¡ŒýÙè+ ¬d IDATЫàÙÿö›*šbl(ÑI:›‘N‹í±º~¤òM ]aæ«ÌuŠi¬t-ŠÔnÐÛ3<ù\ë´´ôs”‰ß;m4¸ÌwÓXÏS9C5÷圖GÈÓæQDÇ3¯œ)h[Ð6K]HŒe#´™æ¿Üõ"51³PMx9…ËKAPÏBȸ‘Τ؆ù·šN£ VJ+¤c)8& $¤SãQâw>#]º,v9Õõ‚ÒÊ‹…“ ˭ωÎB×ÏF¥±CMX…Ö§*¡JhlÂô¬‹ò›Ÿ|ßG?±üÈîµozyzÔ•_zÏ_¬îÛ~Äm/®îßnîß^Üù…ëÞøš«^ñÒƒªþÔÏ_ÿ–øŽ÷¾œ×¯ã<ÖZk mk­‰m­ÿ9wú~e²uî“®äOüð¾ÿŸØÑc#‡…ñ²¡_hsÀñË/½ô¥Ï?ñó¿LÇÔ`|š Ÿstë•·nÞðØÜøü‡?ã©úÃÿCE:Aˆ 4" ãÍ0Q]×x°{›¬Fè ê€*}ôKÀ ˜û—>?}‰¦Ø6ï¼´6K,°3BÛXBÝ¢i1óUæ;´VX—4ÉB7/Ê´šÅŠ'Ç©':¡ö¯ü×ÿ¾‡6Ü”ÖÖLQ+o”7ÓPoÐÕ<–3RÍYy„ïÙV’"ñà…uŠ˜DIAÛ<êFTšv5õqÒ5J™¨hîõ„6‘S’SCµIq“=± 5±Ð-=¥wÚ¼g48&Á“‰…ÀàÇñ(ï†RÖ-[y¶ïåÒª`rªó¨¥±°¾´ˆÐ!8ôÄVG4lóüÃ/}žžNcY]ÿÝ/ºøÖ¼ÿGÿY³¿xλßîiîßiïÛÞúÎo›ŽW¢Ûýä»^üª[Oüåæ¡kt[k­5´­µ&¶µ¾A€ûªZï~;€g~ì¿xûd‹})ù0²ŒãàòÜ{Ùí·®>úÉj)N î 㺛¨#‡îýôç?ú¦Ÿ¾ôæÏ»åiw¾ëO&t^AuP¨Gæ` ‚@æ0æà2@¢ë PGÔ‹±K^‡4À¹‡ï›§Ò·Ü7œvQZ›ÅûÀ6³mØÃl'-¦®ÎV0Â9ѹԑÜê,v›Ù’®"v ¦-Ú%æ(AÞMi=£Uuîµòfêê~›mNK¾ò‡ÎZ4n"…åÊóÌKXŠXжmH,0–¹ŽºX˜V*+„+h;A9¥!JîX>ã]AÚ‚¶× E¡ÛÜêžØúD_Ï8£"œ680r¡{hC㽎té¾W “SCk›Z‹ÆÂ$QET MD—ððçë‘—Ñv9âÿо^rð‡]flOdð€{ò«&íÎOþí,7)C*^0OjúgÓªìÜáî{èú·5¥Bò¥­™ŠLFò]¹©ì|î¬T]Éë0WîÝ–I;¤¼¿.µÞ?T®Ûÿ§#Û¶:³]SoûÚ¦ãòÀ:7ËæÆßÚ*‡Í4©dV¡¯È——j8ëÕÓ(jMÇoX&´ëQT/"MI¥)9SŠºúßÞ¶E][¦bR×d  Û½(¨×òx‹º41^%N5©S¬7ÌìÔTÓdKÚ­ÔÒZWÓ¤œÍ 'íUªaâ¦Y%Jkõx¤ðÊž3®]1i%KkVäÖ²šÕÝxÈV¦•4¬4 vœºcIµšÔ(u*ŽÛ…ùõôèüH[ÕMäG&óLäv+³[Ù—u«fFòÓ¹a¶òßQ®ñÛþEÑlŒž²í·Þø¼¯ärÎ57ñ¢ ØL·èÿ½9®~®©œwpÊ;8Õ­ºn89½­^ž-·“ÏM§†ýa¶°?J—KÃRØß¸®¹ÂzRWrÏ?wìùçl?ç̃ÿS?xÌ–*[cM÷WCdš;/fkn³¼¥ÈSä+ö÷4’{N/w¼á#®W„– íJÊï7)gRšÑu3¹®2×d“åa# lßÔ’¸Yõ›‰?ìö4)Ô)ÖLTÊhI¼†ÔªñPδŽšÛÉiàDy­ç½!'læ¾qíj‘¸YVÏBg(¯»qÍËÓ!d‰›Õ¡0¬z±Ud¶•UÆ’º9Nž9®mL9ëjrÛÊ ¥*GÚjyÔ™UÖ5¶Ÿ;­Ì™Éz©™‘Ú…‚~®ù‰œ§_rç»NÍUþ3_ú©+ù>,Þ9 Ú€ pZbõóÍñbÁª…s^ÿší»žó³Ï~aTêõO[•In>·E\Öµ¨š¬rMCYl¾4,™þµ=ÉÚõœSß|ýèo_óÓÿúù™ùƒ·;­/½ìÒ¼s×`ó¡ÿÏv¾üÅÌx Ú€Mì(ÿòpƒI³àÀÁ¯ŸÿÊ›ý‰o4Ç3Éî·Úü†p¦¿›îV)v«õƒ‰å*øå„¤Æo—ç®7‘#ÊøJÌÜÞoÉþŽÙßѹo}¼ñïÏW¯¿×HG¦+ã)ë¨hÉO5S¨•kçdZL†‚P¿ýz㹦Ti§ ?°º…)d:ÊZ²¦e—Ç´¶IíÑdvKÚI¼Ô«T‚´’¥ ;È<×ø¶éÚ5'®ºI9Ò–&•¦ëÛ‰É G™êiX$V5IjÛ¢š‡=%*«Ê‹ªoÛJãLI¡¼¥¬­Ä—Ó•ÛU*‰ebù¹º‘üDã¿ýÚüô¹çï~ÑE/ü×·7Ï<ãˆÐ/¿üÕŸîK¿óÿA± Ú>–šE}ÝoÞìÁþ¢Ôrï±ícg\yyó+ßpöODýÛÿw¢qÖxž*²”ÇÊCROòúÛÈxÖœ»oBR¥“*úõ½¦+ÓSæ)éÎÕôªÿ)ÿñ¤z0idAïébh6·¼B“Ò´*í´ð,*ï(kËšÑÿp^ã‰À¶šùcÚünÓíf•,Ú–#mEϪ)¶ìl¤ðF\/œjŽøN”ç…S¤V= sÏ©IUiÍËa6¥j„AÙß¶‹4I©#·­$”Õ•ÛU/S+KçNHµóÚ«Îþà»üì]wÕs_{õòŸÅO>ó¹êÈðO>ó¹7ÿà¿óƒâ 4D€CzÜ2‡Á½¦áþæøÎË/}þÿò'úw¯é-n‹`ÿ„OŒâtn@®Ûÿ÷/³¾ß.¶•7ûÄDãÖñrÛ·¢§¤§¬«¼«v®–Ô’ô„ª“Iu2iXÁ??­æ¬ÑLÿ¦3ªÎ&IG¦£¼#kZÕɤÄ&´ëy´5ꌤÞPÏVK•,­äiµ—˜žmzv-¿ü©·œí?1²Õ+ÚVsÔw‹,7ŽÉì¡4L¼ªÛM«Jê["7ÉŠÄR¢Z/ªúv5p¬<‹Å…LWvGI ¢+…ê¥òŹº….ºóö Þ[óŒÓÇ_|‘eÛ˼ùOïýöƒ7¿whtËÍÿïÛ—½ï#oûÍ™kÎ €h°\ p7ù­ïÿhì%—œþÖ7ö‘íÖD§9î÷gQË}vCéçû‹6ºpþvS*<™@A¢^¬$V”—kT»è|=ñ³ÊLZ9˜>ÞSï Æ^ù‹Æ/–ª¥ÈWГfdZšMTLœnžÎ«›>c¶¤Ýj’äžcZv%K‹Ô$]5ü ð­Zoéu·TºM§—´«ÍsýJ‘æ…cR»žEŽ—[mSURURKâ"µ”Èé&ß®ޤ±«¤PÚ“:Jå]e¡¼T½TÛ¯xé~ÿs®™;Õ2Åf’ôk×½eú{?|—?¡¥° ¢ €´Âó˜ñ| ‹ìô'¾×¤ Rù†ô‹Ž^;ýë»ßœp/ÏõrÍæJ#yRW²N;µ¡BOH3ªN&­®.™™¤–tp.ÚÂL^<7»:#=w*qº¹º³ÁÓ:ã=÷î>-ï:i«RÍ“,RÈž5C½ÐôÌ¿»¥ÒM‚¢ÞŠœäÃÿ¦—Nž9U/‘Wm«Œ¶,(†“žRßT»âÛv”&–b£8ñ‡Êz CY;O»ô=·^ú{ïämÿþþ‡ýÉŸ9Ò»œr÷°o&¹€hp´…wÄÍD$Íô‡Ùé éG¡^}ÈmÒYE‰|#ÏÈ7z±«$Søìä® &Ëh«OG—´çî|d¢qã¸*ŸUd©[H"©-3™8ÝÜ ³N;ÉŸQsü’zwî9j©’§iUQ"»­F'K;š‹¶^QoGõvT+â¼p²Ôu½Lž²¶SU’çEª$Íĺv%°«¾]8y\()FÊ|Ŭú–ç½çMã·ÝÈúPD€u±pAÊÎÇp¨i)”Nq_ls¾:á?¾k«ž+9±šÃ*vwý¯L=£üœsNù/*I÷©îEY×Íý"-wn+‹äe÷»íY™É¹h‹§\;6 &^Už,OÕ" \¶4«¼§n¦0Q”hç¿[m Õ_ðî·ïÞ5ø[NÍìÞó¦E¥Ë7Ñà¸Zª?V±Žá…ƒ¥Ìi?[°šA’dKÛ¤m o4#»m†¼0KUž_5o«—ÉË”4iÛ*æ™b¨¦SM+6Nœ y¹<É+ì$Km¥¶‚¶üPÝ\A"û´ÓŠK/<íº«Î½ð+}‹¶ï~Ù¡¥Kº Úlô°[Å ÜJŸžh\5^™M£@©”Y B…ÕzõEç¥Ï>–´-ç@‘(ª­Øš²b“&2bÈ å)õ”ØJle³ Cusõm¿ôBû%—Œ¬°Ø–Ü€h°iîØ\*²& r…FÃ×î9å¢ó.ôÿ¼ý¬•´‹ÚÂ0ÇÚ1m¬Ø¤©¢žŠN1ä…~¤ÔQj+íª›«“+½à¯;mÏåkXlZâÜbÔ¢ ÀÉpù÷&tÎxËU7Õ)¿óêÑ7¾®ùÊ—w?ôçI«HÚEå@ñO¾&Œ®›2VlÒLA\žµðÅF©ÔÎUì:cÛ Ï{þí·ìzÝ5k˜kË¿@´ظ¡a¥ÛùVåŸ&ÎØ6>,u¾þwû¿þw¾tÞË”´”¶‹gg‹K{Hñ›.¶b“¹ÔQ«UhÚhÆèì÷¾}øŠ—ìºñúcšk@´جŦ%¦W‘D•öDÚ¥HêI݃JZÊŸó¼K÷£¼AíoË/O#uµ¤™B£×½rÛï¾ú´þi©(6D!qŽrÃéþįšãž5†ºÏ†ç~ýËÿõ¢…7H§•¥F±¯V¡V!ûùÏ;ãæ/6r ÑË5Ü€çIžtF^Ö=̵Ɍʑ¶¶4+u«•Ën}óî[Þ°Ò\›ÿ Ý€h€ÕܵËVÔt¦©%yRGÚý–7žÿþw®´Ø}&¤¢ – ¸…!5à:†ƒÒŒÔ‘Ѧþ2Ò…‹F)ÛÈ5€õŒ¶ûïÿÒ£>¶T±`Ý¢mÑi¬–:«û´¬[´Ýwß_r³}ì÷¥”·`p6oÑ¢ €hÑ¢ €hр߰ÆgD¸çž/ñ6wÜñvÞw€õŒ6IWßü±¥®ºü,+м ˜9ôª±±Ýå…VëI>€cmËÛRWížoµ…—P:NÇ´•ÅöÝýï8ÀF‰¶ËϲŽ«-3Æv(†ÙŽG´Í'Zyaþ ³l h[gG,¶±±Ýå„ù 8Ѧ• ªµZO–ó¡ópœ¢ML†lŠh[ØmÀÆ6r `­¬ýæºïì-ücyRoù»p4Àq¶;îxûaÏR€£aóm ÚNî†}fqìòñ”i Ú°6Íäýѧø´À ãcûý3Ú$íÙsÅRW]yå5’yäáòÀz™’GyxÙtIOØh[ê5?õÔÄSOMÜ{ï}eÕ=õÔ_°.ÉYgíÚµk|™t[‘M|LÛ•W^sÖY»H4°a•é¶&3›2ÚÈ5p²¥Û&‹6r œœé¶™¢­<|lêtûÖ·¾s‚GÛ#<|ï½÷ña€Ík~¥Â‰m’öì¹bÿþ§H7°smÿþ§VWlZó-?SŽx› ˜Y“tûÖ·¾së­7ó ?×öì¹bÕ¹VZû‘¶ ˜YæŸOú?­Õ/bÔ lü\;šÑµ…6ýæºó£n ß¾"`ÝsíèG×6k´-³DváUþðGù¢€õµæA²ÎÑ66¶»ÕzrùŸ”~ò“Ÿ½õ­·ò '†ûîûËÍm+rÙeöç7Ýt‹¤ûïÿ?›Hù7ø éþû¿´|Ÿ¬âµo”h[j€íˆö¾}íÛ÷Ðì]*éÀ†µoßC'Þ‹šÏ’}ûÚ±cûÕW_»&CK›õ„ñ7ÝtËŽÛOÈOœ`aºcÇö£êí´GIDATVÜ|ÑF®€“0Ý6D´•s£cc»É5€me«•G³-¼ pâùÈG>²êû®ýB„{îùâJ»í°—UÄ÷è£]wÝ«øÔÀIe£-fî¸ãíÇô_vÙÅSSÓ¤ØDÊ%¥G³ÙÅf]=Z¦ÛìåK6x®MMMýÞd›ûÜ£ó£n|!ؤAsb¿º£]۬ѶÔ*Ùx?eNlwß}7¯îD‹¶•žŸ àDból|.oÀZùUcv™kÏ Fy´µÛûç/ßqÇÛƒ`†OàPû‚}‡ýùÞÏìýü>½ê‡ez` Ú6#L®ôœT'³ëî¼aÕeµüi¥ŽmwÞùAÞ}€ý\¿\uY-¿fàÑÆ‚€h«²â˜6€M€hØݧmÛ¶³x³káv{?³w=£ Gtf0z4;è.ƒéQ€M€hØV9=jYVy¡(Š“ð]³,ëä|ဓP£qÊo³÷Û¤O{£ma²/œð–›{îùâò[ùŸHO{llwy¡Õzò8¿œO.ª´¢(æGÝNl­Ö“Ç?×JÇdõh™qŽÀ•¸°üÞqQ.3Â7à˜ßò8ÈÓ`d¬O´ÝõÉ»Ö÷I,ê­ù?®ºÌüEZvªw©§ÁÈ"šŸL,ÍQí^8^µðåå…w\tËÃ>àÚ>çežÀÚ¾ØeºÙ›+éãðñÅ7 ŽêÕ®´«Ö¶ÃVý«|f„¼~–ÿÉ wœÿãªð(Ÿù€¿emŸÛ¢<»ë“wÍMî ö-,»c´)ܺ;´·˜ëà¸0boctxÙzµ¶Ð¢6ÓIxF„µoˤÏq˜ÍÜ8½Ø5·âh+«–ßòcE ŽÆüêÃþ®CŸÆš$s£ Þm‹²æDí¶ÃNÝ®í¯XÍÊN*Ó2[ø‹ýº…­¶L· þ€ƒß‹‘9ì˜5¼Ùšß÷˜>ìRp4¼ÊéÑåÃeEYsè\pÄ› þÕ> º €#ZfztáU‡ÞlxLŸùa—¯–ûŠ–yƒ¿Ø5‹6pò¸çž/®º~VzÕ¡?_ø“UÚªŸöŠžÞRW­úim`5‚`fÍÏRun;O{}_,ÑŽ·Õí^{’¿X¢ ¬OÊœ4Qx§¯ÁÜqߣ\W$†”®¿µ·Ÿ©Ñ©2ñˆ³&AzÁ™%u`ú@2Ñ$NÊTT¼-âÑÄ …²ž¨ÜÛ3ޠΔOÅ8÷>G<îï|ÌÓÖsä ʽýˆOòüñÌ÷ÕÑÇ~f[í]òx¶~׫öÇÖ>*]î®=ž³¿Ór{j[­}´¶íªckÙ‹[î ’°¤é©;-`wÉÖZ1Gæb¨ý1ÚþøÉyðf0@ÕÒüã‘úæÞ kÉ– ËVl„¨ºd$@ ÖŸWj˜!‚d­¨þÖ‘ÜQzÑ%o”z×ÃÞ;ýÏlïm\MµŸ„§?ÚZ°”­ã>÷Ï=Ž+K6ŠN0Þßxí‰zt‚DÑ ò1»×/Ý .X~|×Ú§0îmŸÿû­åÌòçäÞoK_ˆ ê¿5ñyH.\÷yVO-5R×'–·ÛÚž³´Ù»Ž²uû–i=Ž«ªAòÑ&ï™­ ¨ù¶µØ”<—k?çèñÔÚ>\{,©ã>w{ãjzâ‰È9P„è]˺Òk,¥1›/‘¶Âúô>Yû»œí=Ž«ÉPá©ÙÀÚµ“å<õç#ƒêÈ,Ä ¯±ËÞËF3cÅ@ˆQ›ü/‡€Ь>¨íoåZÁIEND®B`‚snd-16.1/pix/energy.png0000644000076400007640000002443611147553266013155 0ustar bilbil‰PNG  IHDR!)„"-·sBIT|dˆtEXtCREATORgnome-panel-screenshot—7w IDATxœíÝ{x]UÿñÏ99i’^h“Þ¸4M)ZÁ2,ʯՂ r !P¥òŒ3tøia|äÁ ¿ÇÑß ãÌøÓAìbdAÂ¥ôÁ6Ò¢– TÁr)PÚ&½¦i“œýû#œä\ö>gŸsö}¿_ÏMöY{íµWöe}ÏZkï„$Cà‘”$=nló»"nõ-ßЖϵ!’ôo»ö³<bb4I .üæ_ÎÔÍ7߬«¯¾Z'tRÅ™/ÿË÷«+Q?ZîH>Ÿº?ùe BŒáôèÂ7ß|S?ÿùϵ|ùòª‚ì<d1 =ëØª²xêwdÌN‡#¿,cAÈPñ€axxXo¾ù¦zzz4sæLÍ›7¯äFKå ÄVräŸý{÷T´úáÁƒ2 c¬Íôü²Œ Ç*ÒkñÆoè™gžQSS“fÍš¥Í›7këÖ­ºð USSc¹^±< Ž®œúQ]xÄ)’¤ ^û®kÛyðØë$Iì}Z·îú•kÛñ›Wõ n0ÞmäF…mfcä™6wv~çœw^YY­}øa[ù­}¸ø<òœtyùeËê .øP’¶nݪÎÎN}éK_ÒäÉ“%IsçÎÕ•W^©÷¿ÿýjii±,„UžWFzìBüÊÿþ…æ~ÿã®no÷†mÚùÒ³šzÑû\ÝŽ_¼®OpTjäM†Qù3Fz†«Î/³N©üÎ9ï<=òÐC¦yœ{þùÅóËb:'$ãÙgŸÕöíÛsŒóÎ;Ok×®Õg?ûY%“Ió¡'råÝÞ^ÿ?:ò#ó]Ýäž^Õ¾ü¶&7ÓÕíøÂ‡ú§¥+í ‘!FA›»’üFÖ±Îï¡»tþ­’F‚‡ìÊI“ùL’z°«h~RÎÓ± ?<úè£õÉO~R©Tªà³}ìcºþúëõꫯÌéëëÓÖ­[•n".sêgè³Gž¥ù ³Ô§ýémØ¡öw~­ç¼.IZ{Ò ’¤{ŸÖ1¬³¦,”$=°ë¿uÇ;Ý9ù]:ýt]<õCJ%jôhß%Ò‰‚m¦‡Ò£yÞ¿ëIýÇÛ-ã‚ñ³ô©éKµ`ü,Õ'Çiçà^mÚû¢ÚßùµÒƒ9ik’I}ù¢+õ‰¥ç*4tïÎß©cÇeç7.‘Ò'g,Õ²É'jzídíî×{_ÒOþü+õ§®> ªë 1Þýo캗›ßƒ]ØÊç‚Ö Gz,läwAë…’F‚ŽLþ™e™4£½ ù)Ú2cÆ ÓD’ôùÏ^›7oÖ®]»´xñb¥Óiõööª££C§œr =!BçkÍ«¹nšÒ†¡mo¼ªÚšZxÌ,M{æ &w¨~îÔÑ´çq²vìÓà¡Ãj„>5c©6uoÔ+'Œ4Ü?Ú¸P;ó£’¤wzwhIrž&MšT°ÍìkåÞM¯©÷…ÔxþÓò½oB‹¾sìJ%’Ú{p¿^}ç-½gö±ºdÚ‡tü¡©ºîíŸË¨ë¾øìVí8 þƒýšqÄT}fæ™êyn›ž˜ùvYùýŸ¹—êÔIÇipxH¯þéuÍžyŒ.h:E-ý“ô¥·Ú•¨3Ÿèw}@ebì¡¥åeðîp§Ì޼üÊÉ×H§Kæ'I]¿¼_­ytovð‘ù,g›yùe+9'¤˜ùóçkΜ9úÙÏ~¦W^yEóæÍÓÎ;µråJM™2EÆÓ”'øé¨q’¤G7­×?|çëJN§Éã'i¢Q¯=G+ÑX7š¶wïn{Õ¥š6cº½©C’tâÐ =ýÛšü-Ÿ¶X’´ý­}üêË•¬¯Õ/ÿí5yLÎ6¡aýi`§wЮݽ:øönÕ¾öŽ&4OU¾+f.S*‘Ôξ]:ÿs+´÷Ð]þñ6}ý3×já1Çë„û ½°xh¬Œ{vëü¿ÿ¤ã’ú忎lû¢9KôàƒÿWS>2ÏV~©³šuê¤ãd†V\ûwúŸ×^Öüè¾ïüDï›u¼N¸'­?4¬dª0ñ«> Lª™"“9Ùó1Ê.C‘ü2¸ÿ>]¸ü¢‚e¦Û+5'¤Ò'YÕ××kÕªURMM‰„‰DUy€_žÜýGÞ8_ç.ý¨N]¸H¯î[OÿùºûÙG¥½{5|`lèÑÏlÖÁáCÚuâ¸Ñe“<ÿS;UütÍ©™ƒñ»çžÒáZCuKÒ“}/4šÓÃiýÍóß×[ßß( J5O’‘6¿†ž0adÝOÿNûªá¬cµ.ù’¾þîçï>W×?,´×õÛgŸÔ! ªîÃsF·}üœy:ðÌ[ªïL°¨t~o§¤ùR"‘н?øiA™Þ{äqz¢û5.;^‰¼ÑQ~Õ'„I¥ODzjsgò+'_ÃH—̯ÔúvË'•ñžb‰„jkk ø\!óÍ—îÔ^ž¬SY c›çèïY ÓŽ9Q§M_ xáÇJ6Œ]ëöØ¯äŒ R}v@BÖОƒ9ùÖL¯TC­ê'l3s­œð‰ùJïP"™P¢&Yòšœ1^‰†”&dÎòÁ¿ìÏM7}‚jêr·mì=¤wöÚÊoxÿá‘Ói½ðÇ ʱ{ï ýy¿wPí¤†œÏü¬O C•õ„$”‰‚ë^&¿rò5d”Ì/cùE—¬ÿñ‹.Öý÷Ýc«|’Åœºº:uÔQºùæ›ÕÙÙi»ðãÆÓ•W^ɸ\¡3â1zlâ³úå¯7*ýN¿þùo®×¹ F{ÓÇJtd®{ù•“oÚ(Ÿ¤å·þ|ÿ½9Ë–_tÉè2³òåýݼ³ÆjöÁé‘G•Qa…$’ ͘>]é'— \¾¿ð*í_pPoŸµK)#©9“’$½¼ý ½³_zv®Tø€&FZ÷õ<¡ë\¦9ÇÌÖÃ߸MÉúZM©›X6=4¬æ†é’¤ú—ökß–×5á´fÓòýäÕGõ¯'_©iSµö›?Õ;ƒ{t\ãÈp¤-/nU÷æJ2ö(Þ©SõÈ?þD‰ºMo™Ÿqçƒ÷*qD]Yùm~ã÷:möIºýÛ?Òë»ÞÔ`2­æ#fª!U§Ë~òeí;ô¶fOšY°~Õ'„ÃÈÏ0 ]tÉ¥e­yß=w+ñnc×½±ü²ÿµÃ0Œ’ùe—ñ¾{î]~ß=w~¶üâ6ÝwÏÝ£kçæ7Æ´'äƒÃz+1Q²~zIýýÃ| txó·:þð4Í>j–êëêÕ·w6?÷”þå¶›”œ4NC®dv©KK¼ù¤&¼3¬•‹ÎÓĆ êzüQ)‘Њ³—ç$;V¦†tèí=JílÔ¸ÆñÙ>»k›þî¾oéo[>¦E NÒ±G¥·vüYkÿ•nºó?eL§Ä‘c ó{×ui(=¬OüõÚ½o¯n¿ïNÝÿ«‡4nÑLÕŒKÙÎïº-·êSÏŸ¦sßÿ5Ï8RƒÃCzíOÛµé©ÍzmíÕž3Ûtü®OƒJ†c¬óîp§ü9Ç*–ß'.¹lô÷_ÜÓQ÷/îéMsÑ%—ê÷tXæ'YÌ éÖžÁ‚ÄåŸ*=ž‚æ{[ïVßÚ—”þË¥ûKCR¢.©ä´ûÀQJÖ¦ôáµ×jÇ+IJÍ"†é2c(­;û£û¿4ô‡^é‘IçÿôÀÍzmÏè6¡tÁúÆÐ°å5ôõ½úâÿOC?Ú¡áÞihX‰†ZÕÌš¨ºã›TSŸWÆc§è{¿ú©†ßØ#)¡ÚùSUÓ|„R“êd ¥mågÔÕèÇ{ºuÓ÷~®¡?í“qpHJ&”œ8NÉ£Ç+ÕHKº¾ ]ÿñß9ûàW}@($r{Ê‘Y'‘=ç"/¿ìÀÁ‰ü$éÞλ,Ë{oç]º¸m…u~Yª~:–•]ó„¡Ôðáf ï=4rÑLkäAéÉ„jêj5nòx¥‡Ójøô‰Òž‘oñ´a¹¬¦¦F ‹›58šthX JÔ¥T{Ê‘Òá‘kdæZi¶¾™„ì4ž9QéƒÒPZJ$”HH©ñuJMn((O¢¡VÆûgH‡ )!ÕNªWMý8¥‡Ó¶ó«ŸØ äÿš­¡ý‡¤ÁaiøÝLmRõµ’æõâS}@ÐeFŸ2tO畵®!ãÝ £×=/ò+Õ»’“./¿lU½'¤˜ÆúZžÕ ”jkjUÛXøÄ¿#Ï;ohhÆžeµL’RɤRS Ÿâ”ŸÎj}3 Iu õRC}á‡Ãi&ùYm×n~’T›J©vŠùKltÚtüªO‹º:ëku)#= ¹×½ ç'YÌ ™Z?NÆäŠ·%IjªK1.°’HèéͪÍb¬Íôü²—K27¶éËwÿsU€b÷Жϵ›÷„€[ æ„ô?øG½p÷Fß  :N¼t©Æ_ðžœe£AÈPÿÈH^¸{£žzªÛÓ‚ˆ¦SO]¦Eg¶ä, Bj’ÉœN9导)€HºõÖÛ%ÅÃé‘) YAH¯G ™X£0©!à¼ÑXchPR‘áXà„üXƒž®Ê5˜ÀUù±AWY!©æ„p^~¬áHOH"1Åò3ÃØmš6¹Y^ViÜRÎ~˜­[Ŭ,VËý*£]f7ËôúñUNÏN^^´{¬‡cU91ÝnáK¥Ë|^, p““;yUrÐ8)Èm'O4»ë¹>œâu›»ÈÄt†cpžõ#z=˜˜îT·×CtJmßêÛz»Ÿ;Ýf» ¾õ/6«ØvKÕµÓ½åÊl§ØßÄn];Y¥Ž¿a]N´3ì¶iìrm8–:Ñíãv£×N㱜¥Õ¾fîWã³Tý0ì²ú›d–Ù­k§ê£TyÂR¯ xJµ£ž7b§-l‡kï ‰Jã©’ý0‹ãȯFtÐŽ½JË´ýÁSj„ÛÛªT‘žðÌ ¡Á_Zö¬j‚êÚyVA+ApBÛoù±ÆØ{BBô²BkÞ¡®ÝÁp,à– ¶'òcѤ&YÃ[Ó+äd´ÄÈÕ«ÉK^mÛËõªÖ¿1ˆ'Û,ù±†§Ã±ÌžRTl’·Y·‡²”šHnõ”€üevöÕl]§ßSRìÛu'ê:Õÿ2+±í[¥«¤®½:öŽÜb·a§­êèÓ±ÜxcºS/*t2M%ªÙ³?šÓÛ­„§AUº¾U¯_øèT:'êÃês7ëă“í §ÛX¥¸öˆ^0ãÚ#zÀŒuOH²²9!v'¬}ø û,QÙ'xÝ6rº•kT=+*@ö#X¢²N{ÛÈr8V˜Þ <òcP¾1@x¸òˆ^°Rdb:AçÙ~OÈ­·ÞîID[‘÷„ŒÓš;wŽæÎãY¡DÓUW]ãü#z Þ˜ÀS–sBRô„pA~¬ÁËAxŠ €§R¥“ŒillQ_ßöÑßo½¥]«W_£ƒ;/X9§øº} îúúvÛNKOO•ÕòÜ¡ç¤ñc¿ŸsízIÛr–IÒì~z&˜++‘¤îþ¯ÿázÝþ…H’.»ì3e褓ØJwà ו7ÿ•„”kÑ¢…ËÚÚV¨³ó.ÓåwÞù3-]zúè²%KÎ$mÚ´!oÙ ó…à:Ïç„´µ­Pw÷cÚ²åy[é{z¶©§g›Ë¥àσîîÇ$IgŸ}fÉ´™^IÚ¸ñ7®• €w< BÚÚVäü^ª7$»dåÊË\)oy„dzA2Šõ†d÷‚dÐ £µueÙéË]¸Ã³ $¿$ê7Äl½!¤Ê®®vuuµˆ®?+#¿$ãì³ÏÔŽ¹o\_²ä ËÉè7þÆ´—$ì2 £®®vŸKŸ[ÁD9yr®ñÆ}¨NÙAÈú®/{#™'bYÙ²åù‚Gù¶·w”½¨†Æ=)T¯¬ ä亓G_D(I·ÞÒ®Õ«¯ÑÁEÖ²îÉÈï Ù´iCλBD‡ësB¬æ‚ä³ûÞ§”;IÕ,}fߌÁÀù@8x2'dݺò‡p¹)3I5ÿçrÒç¯g'ÎÈvÏ»ì9$œ§øÏõ ¤³ó®‚ùP «@¢X€Að@pxöt¬¨É: À‚ 1 ¨Œ§oL:&µî‹eOH¹“TÍÒ3 ¨L,ƒÉø'¶AóÌGNˆ îÉÖBŠƒÖuâ"ªí‚ Æœ¸°Eõâ^+M)¿ œ0ÈàX ñDWW{É4^6N£Ønm]i«žƒ*ìåÇuÇA6‚ˆpâ æÄ¿(˜~¢>D×2AB… ©âX÷fAyëüÂ57º˜˜Äx€îþ‰zÝ„ â𔦠—À+!@@¤@´qÆ„y*¹Ipc°/Ó—,9Ãï" €hèPîþ¡î‹ lOHOÏ6Óÿ¾ýíò»h(“.~ø›€r6à‚p×WÀAHÌp1å¢ý§„ðT '¦Ç]¥ß6´¶®4}Ã3P-¾ga½†µÜa/?Š#A?‚(@™Ý›h ÃMq8¾B¦Ú†x±ƒ¶««ÝVÞÕøn–¿šõír£üq¨ûby\€lÌ ²ÐX zâг6!»ÁADå¨;à•ÀÇjoïð»‘B3ººÚù¶à*æ`º{yi B6mÚ ¥KO÷»¡D#6¾¸¡€°`8V…¹1æ²Ká/?QÁ—²ÁF`”YUN`EpDô„DTvc0l Ãüò†­üùÂ^~§„ h¸P9zP)¯Ž‚³û‚¼ òºüNm+Ìu.…¿ü€h#ÀІ@> »¨4䣲„Y«L @Ô.t 4/{™Ž…Õ4@i¼ ù R†AÙC=ÙãzOH[Û ·7®àF€;<ŽÕÝýXÉ4ëÖ­×7ÞèAiu¼5N1ëÙóúØŠâ8`Ž€H ò—‘A.›—B†o<Á1nPâŒk`<„¸€Æ4` €§B8Šádà/z`üCÝÛGà©(%.ÇAOyòžäŠj„Ë0ØáI²nÝz/6AxZ)¼ð >¼n÷¹„tvÞ¥E‹º½ Öè…aœD#9 ‘DÏðÁOyBxŠ –âÔ›´} Zyñbõ­>ßöÃ)!I4.Þ!à8zrÄA}e¨·ø #htT'NAoL€‹Ó ¨TÜΓ¨îokëJ¾4 ‚Å›ÓqgÖpåÞT‡áXˆ‚Ãð AdÑå ˆ›já4â႞"Šž§0ô&„¡Œˆ6‚D yÿP÷Ø·À§c€…¸ÝÀO\sã… %ñ˜^Äå…›ï9ñãÞÆp,D^Ô‡E}ÿ Lø¢°‡ ¡ ì”?ìû%!ˆ½ ÷$¹lv„½ü€`"˜?‚ àÂÞ{ùΈràô} bùB`KØ’a/? øì6ô*m¶¶® dc2¢P÷A+?AªFß}Ô1¢$h7B lÂx…±ÌpA|E?!°-ì߯‡½ü‚FPZØÏ·Êïf½µÎ Bb(¨Ó8 î B€Ð 'â‹w`À A:FB€#0AØé 2ÕžÇ\¼äº&AYÂÞèÍ/Ø÷@q^߀ƒ|ÃG´p¬!ìBP¶ì†;xoQ÷p aTε‹ë\0¤ü.à5ïä¢anºqA*BCÞ?Ô= ìZ[Wr?{—ßAŽ_Ûw=ik[áö&ˆqÈæwC¶˜ —­œ{Îð¤'¤»û±’iÖ­[¯o¼ÑƒÒâ$Š †¨5ꢀ¿ Â"(×D×'¦wvÞe+Ý¢E ].I®ÖÖ•eObÊOŸYÆ…ÊãÅu“k3¼Àq/(ožô„,[vVÑÞuëÖç!K–œájy²#@;Ñ Yúüõ‚U¼¥†€1œÛîñ$éì¼KÓ§O³üܬ¤§g›iÚöö}å+_s¬l^à`—Ùõ‚/9€x‹z;"ŒûÇu¹zž=˪7$¿D’6mÚ ––fÓ|–.=ÝÖöÌh'–Loˆ¼íl7Œ' ¨ŒXÂáWIûÏîß=èmKÏ‚«Þ«¹ ÍÍó zCÚÛ;l!nŸ” Ç€òý†„U5çíøÅÓ7¦/[vVÎïëÖ­·L»iÓ†‚evJ1É@œp½s‡Ûõš?Ãh ÓßÓjèhµy”»¾“m7³…AX”äi’ÿ¤¬ROÄjnž§ææyjoïP{{‡cåÈ ¥²ý›¥Ï^Æ·€÷œx¢‹¿µ³‚\ŸQ¹dÊäGٜئUùƒX×Ra0_Iýqß‚X&+ IÆãÆ6m}ëEIÒÕÇ´ª·÷uÓÄ-êëÛ>úû­·´kõêktp`§iúË.ûLA ÑÖ¶BÝÝ™Îik[¡;ïüYÉ%KÎP*5˜U®)EÓ‡Aæ !˜Jsâ wÕl@0îW\ wTznôõí6]ÞÔ4G7½Ù%IZÓÕ¡-Ÿk÷nNHFgç]Ú²åyÏß \ÔEAh¬ØÁùØåQ\ ÷¹„´µ­°µ,›Ûï 3QxÚ€êq-ÜçjÒÑq[ÙëÜpÃu’K¦‹/¾Mòê[«¨mÇËmEm;Qöº‹Âߟ}€ß¢t­ŽÚv¼ÜVÔ¶ã%O'¦€›‚:့¸Áçùœ¨VöËBËyÂÝôÂk^!BɬQ¬QAƒˆ&®@81 Žóêïå$jûÄMÅ{OÔö)Š÷m‚ž"à)‚ž"‰‘(Ž'¼…óˆ}†(ìÜÅ1‚(sýéXkÖÜQVúU«®p©$‚À“Gô.»ì†’i·$40°Oýý»,Ó45Íý¹·÷uJÀkxOÈâ–DÉ4MMsrüßã¨Ü.µ¶®4Mk–Oö›féާ8_•ì{9éÄSœ¯«p_ØŽ/߃LòävCÒ~ "ÙŽÕA”ŸÞn>ùùÙÉÑçã«’}/'=€xŠóuî ãñåÙÄôÅ-‰‚;= VâÞ R®r–¨^¸Šp¨NT8¯µu%ç`÷m¸)ÇŒ'=!ÙÁÆâ–„žÜnä,éAÅáÛ”¨ï_Ðd¾UÉþñ@¯à>Î-8Í­û¶'AH~ÐQN’==ó3½ ވʅ,ûÄÉçXlÜ£Ñ6ÏOŸIDATUdFêÆ €$Óîþìå™ÏòÓç/Ï|Vì¸2˧ÜírÜ" Âx\:y~r>»Ã­úòlNH~ bW&à`"º=NMÒ Yì›×üè>¹Ù¿Qª#»â<;Îûî„Lý™7åŒA.öÅ€Õv‹'Œ­‡ßâ|ßvòüä|6ä{—§Ó+ DPÈ*â·bÕ0Ë';mv:ħNÜ<¾‚>«Ü}/7}\™5²?3ûÙ©ãÄ*»_À Ü·Í•{~ÚI–}wRïÛž?+;a.HuJÝÌí,7û,Ž'¯]qª·Ž¯R郠Ü2}ªÒz5®U©Ì ºX¯(`÷íBå–݉}êù¶û¶çAˆDüQêÛ£R'XпÁ¢Äê|+5„²ØÏÙù”»ÝìÏ8÷g8y~ÚIoöç³’ŒÇmÚúÖ‹’¤«iµœ{ÑØØ¢¾¾í£¿ßzK»V¯¾FvZn`Íš;ôÅ/^k»@ÅÞ˜n¥±qJÙëÂÏËF  ÜxBŸûúúv›.ojš£›Þì’$­éêЖϵ»ß²jÕ  œì< þðe8Nðª!Aƒ§0ÎKŒ ÏÞ˜AEb8–Õ$ÁCOO„ðT$†c™ùÖ·¾ëw€H»á†ë*Z/²Aˆ$-]zzÉ4K–œ!IÚ´iƒÛűUŽ|~— ñQNÛx$í`EÛ‰tRÌ’%g¨§g›zz¶©½½ÃVÀâ¶žžm9¿¥\ˆžžmjiiVsó<׾ݜ%KÎPKKsAƒÀ˜L0b5b§± B>€ò¹ŒD>!øªçd0é $3ï€3zz¶iãÆßT•G¤ƒM›6¨½½Ãïb‘áÄÓ"„H#éݾ½‡`¨B{{‡¶oïqäé­®?¢wÍš;ÊJ¿jÕ®”#ŒlÜø­\y™+Û¢&Óóáä«#žLL_8³ðýûd÷½ ù‡Ý$3‰fË–çuöÙgÚZ€»\BV­ºBýý»ÜÞLQ‹-ÔŽ; F€ džRêÔ“J}Žå—L0²nÝz¿‹ÞºuëµcÇNÇ_“àÙÓƒ$»g$¨”à§{>òE:)õ± ¿™üÆoô»ˆ)·Û¢‘ B::nó»LÄjNÿE¶'€=oŒßm+Ýìþ)Žl¯¬ ¤¯o{ÎïW^µRv:Rþéîï.úùú®×í_ø#Ûb8O„ðTÉáX·ÞÒîE9øäœk/°•ÎnlpåU+‹~^2Y½ú[N/i›­tvcƒRóÆK!L<"n¼½dNÅÌ à)‚ž*ë=!-n•Uʇ PŽõ?\ïÙ¶xc:s³û§8ö"B;ŽÀS!æ„ÀskÖÜáX^v‚€Ri¬>Ï_^MÀáä>K•ïS©4Nxª¿—V­ºÂ³ía~ˆ×ûì·êŽ ‘æÔ‹ýâÈ­º#@äE)èðz_|ï éëÛîxÄKUè€r„ðAO„ðAO„ðTÁ#z}÷Ò‚’@%}÷Ò‚eAȪË?-]þiO  ~ŽÀS)IZ}Ë7|.€¸HH2ü.€øøÿ”~:0ªtIEND®B`‚snd-16.1/pix/fmsweep.png0000644000076400007640000025650211147553267013334 0ustar bilbil‰PNG  IHDRz7`(bKGDÿÿÿ ½§“ pHYs  šœtIME×(D“¸¸ IDATxÚì½y´%G}çùùý"2ï½ï½R•T‹$$@B%±ƒŽe6³t#µfñÒÞèö˜žñØ=mºí±{º‡ñÜÆvcÕÌ ¦mðŽÛ6 ,hABR $„¤R©U½÷îÍŒeþˆÈ¼y_½„-$¡øž“'ãæÍ»¾û~ßüý"âcŒ=@iù ŠŠŠŠŠŠ)*****RTTTTT ¤¨¨¨¨¨¨HQQQQÑ£É@®¿þzD„N8¡üõŠŠŠŠŠ)*****RTTTTTT ¤¨¨¨¨¨HQQQQQ1¢¢¢¢¢b EEEEEÅ@ŠŠŠŠŠŠ¾‰ì#å^uÕU„سgOù«= ùÇYû¸ÿ¯ÿ÷õ¯cF#L]£ã1f4B»v]#Æ £º¼ŒX‹¨²~ýõ¬^}5a}DD@òóËàj\DÓsVj-ZUHn‹µóÇÓ¿¿(BtŽ7ä~uï>Fàó'&O{[^ò&O::™ùfúÈG>‚s޽{÷–ÿ†¢¢¢$³e [^ô"¶¼èEèq±m‰mË–ïÿ~¶ˆ¤ oÌBð4Ki+^ýõ<ùÉOæøãgÿþýå/XTTTô©ô)*****RTTTTT ¤¨¨¨¨¨HQQQQQQ1¢¢¢¢¢b EEEEEÅ@ŠŠŠŠŠŠ}Ë–¯ ¨¨¨èèÞëáÀ­©-,±ØÐ– `Èþˆƒ}pês`iG1¢¢¢¢‡…>õ1¸ô/SÍeH>Ô lܬ@e¡¶i_Y¨+¸÷J¸ïKP[‚wÌîøêb-GŸÆ„ÅÛÇ4÷g¾VN™›JÐÁÂ/ÿn1ªBã-*zd«½ûn_~9‡/» Ú»´„Y^Æ,-!ÀÚUWáX¸¨?*¾«b¬ÅTZUØÉ$‘s­M´[UŒ1}›Q“´SXÚµUÕP°6#2¿mMn›|<3F#xòó‰>°~ÓMþä'Y»6Ñy5*Š`E±,J DÁlYãV• lY†-KÄQM˜®ãîÛG³çVˆTѯÞñv$’6ŸM¤HùÔ8çh›#ai 7?ž¥¾ÉsŸËh÷îô9d=b`Šo~ó›{ïE]T`ŠEEE™Âê*³Ûn#Îfˆ*ZUK« ê­k¨k$ßfÁ7¬¯Ó~å+ ‚Y^FF£t®1½öÁ9F¢÷©am ø0Ñ{ê“OÆîÜù|…Æ[TTTTôm©ŒÂ******RTTTTT ¤¨¨¨¨¨HQQQQQ1¢¢¢¢¢¢b EEEEEÅ@ŠŠŠŠŠ¾ã*(“¢¢¢¢oS_ײƒcšþ×íÓ ÉSí$·œ,‘ˆHd§³ÓŠ}7è.ÿ+LÝ~¼38g ^ñÎལàƒá.ÿ¦qï 1 "‘Ñd J@mèo[ëÀ€hÄXj@%pDNâ€nG% Û)'ÈORóüb EEEEŠÖï…»/ŸßÞH»J€õ¿…ƒoí³€,!(ÎYÚ¦Âûl­¥BgŸ0$Þ¥}T!xåLMYDD0Ö#Q ØÚ¡&`Fµ‘€1«51cCÿ>D"Äô~TF=Ñÿmˆh ¨îDv¼s]l'ü30u1¢¢¢G¡ÞùëpßmÄ ¢Ì·®g¶»-1g1=G¾†Üö‘ô|no C¤ºÛ\ >]ù‡@["BÚ—˜BÔTjRˆÖ$ ce ¶ÈÈBmQ…,Y¤¶È¤B£EŒ"ÓënÆ8„Ï àDï1ÞgOä½Â+Á“ȼëÀ“~Â8Qz×a?»¿ü˜<õ©‰©U d®Bã-*zp´zùåøÀ˜Ýt&Çp£Š]^ÆL&˜Ñ(pAë3™ uZ‹1™T[W°4JDÛÉ(ݶ&5KŒÙwrÿ'?ÉtÏäà>Ä7ˆ‘ÔW€ ÊœB+šè³t° ’މ`ŒÅ˜gë ÕPU)¸W&ã×sÛhz?U•Ú£tž¨ •‚*ÆhB·«&úni¼¶#ó’Ž3£éùÇ#°u¢üŽÆ ¡mXýÛO³v9Ä{÷cï9ˆß¿FUÕˆ‚[¿Ÿ L6CúŒ fÙ™IHÀÞÄòï%:ˆA ^ÂŽ·Ð~ðf[¶¢O8“Ñ _Hý}߇ž~úƒöÛ)4Þ¢¢¢ïˆüÁƒ¸}ûŽB’pèpíù 2 ×v÷38wáø]®’n«æËü.=¤1ƒç˜gÃc›Ü¬s$?·P“#î®»p÷܃N&ˆ«7ÜÀìë_§Þºf{ö !…¬ßø’5\{*äÏnO: {ÒITy fûvÌÎèòòƒþ7-4Þ¢¢¢¢¢oKeHQQQQQ1¢¢¢¢¢b EEEEEs•a¼EEEEߦ~ûšÈ—$F¤.µaqºGRßzn¿áéÂÙÇ)***ú®Ñm-ôÙò¶î#?qUÀx‡ ëJDƒçàZ` € Úïƒ(Q¯æ¨ö%W •‚*g§üún!Š°Ó §=‚¢r1¢¢¢G¾#ï‹-Ö9¬÷hôü÷CŽ›ÖZ*ßR·Mºß;¶NÒC‘d;·&i¥"¨[TñjhMEÔö&ÈXC‰*\#/¹+ÒVß³¤|ÿ²p–µ¼ÊÖûï±HQQÑ#Zë44¸Mïûûø$—ŠÖ¢çÖà1Þ3n§ç±Þ±Å´|ÏJD}À×…ÄH@ÑúìÀ«Á©% 4¶Æ‹¡KkêÞ<œ±)óˆÉ\ •²PÒ x ¹°¹7þP"Ç©á/Τâõœ‚AØÂ¤HQQQÑÕ=ÜÊþðõDº,o?Ï­ÜÈ×{ò­¤ií㉜–okšv×›ÉY"¨Lå‰v`¢Hˆs£ˆà%e>(‹ ‹‹––Š6V„ÖàCl•ßTC?ó¯ª[Ĥ÷SMÚôúÆckGTALL ‘ýx“8¶aùAÎÅ9‹ï+RTTTÔéÎðs8GO¾AñÁàCºÒ¿/ÜÍýá¾t²„”ì°žï“1ì·Æx¬8$±Oúî˜xW’JH^ç³)ƒó&¿ —߃ó– ®58gðNq­Å·–à×bkÐVp­™#­¼P[„ôþF[f ¶8r}{4™Q¹d,¦ò貈ÐÐWõcŒMÈsØÁkX–g?ü d6›ñ ¿ð œþù¼ò•¯äÚk¯åÍo~3gŸ}6oxÃضmW\qozÓ›xÞóžÇë^÷:&“ ÿøÇyÛÛÞÆùçŸÏÏýÜÏ-à†zÇ;ÞÁ‡?üa~æg~†—¿üåå?§¨è‘¦=—p•PŽÑÞ÷ ànž@Š T胡ië‹>ò†‘@ð©Ì#š!†‘JØ%S%ZˆÐÜÖhQ1UÄ„ˆ©#˜ŠöÞCLMi]…󆶭hÚ ï•¦©i½%xCÛZ¼7¯´m¶—Ì"F%dC‰t,(„d!z%´†ÚEÔ x¨jŸL£ Œ–gã©—ÆÇM±#ÇxË”ñúkõ¤ÁÖc}2 ó‘[1™jpŠU‡Oô„wÓ‡ÿ82ùáXÜõl˜ì|h ä /äàÁT3¼öÚkùà?È»ßýnnºé&~çw~‡—¼ä%|æ3Ÿáâ‹/æ²Ë.ã /ä©O}*·ß~;üà¹ôÒKyûÛßÎë^÷º£^ì÷~ï÷8í´Óúç¼øâ‹yõ«_]þ!‹Š¾“ºê¾/uÙ„p+lgêÚ×¾sñvw¿ö8TÖB=J‘ÚBUõPFk-R)ÑØ14 b(•I€ÅÚ$– ª3·J Dc`\eøa•Ž«[ÑÜ{/>ôa¦û¦xˆ1âï‰Ah[Q o°!™—õŠ„„jA‘˜M-$€£w)» Ÿ£!µÕÁØG¬O¥³ªv›Ì£Zn©—fè²£ª<¦˜Úa+ßÕÓæßÙfßýЫ;–ï¶÷BûÞDç=ùePŸ S‡¡}ì30/yöÔS¿3r×]wqË-·ð‚¼€Ûo¿íÛ·³¼¼Ì³žõ,ÞøÆ7rê©§²{÷nD„ç?ÿù¼å-o¡m[.¸à.¸àÞö¶·mj ÿøÇùã?þcÎ;ï<Þÿþ÷oj ëëë\ýõ›_üoÑw¹îú©ŸB»²‚æ€kF#t<Æ./'¢¬÷„ƒ9|Åøõµy°1]Si6Ã…L²AÖVÑû¡Æ`ŒE­AG#L]§À\Yå >¥¶5‰>k œñº¸m•Ωl2‹Ž‚+’Iµ&÷Ž`k-RW ‚d³H?›‡äçP¢éy…Ô¶R¨’ž‹¼ï`‰Ýc€Ù_ãà‡?Â;Tec"ŠÆ”Ù()fGE¢ô¦Ð‘~‰Òå‡ó¦®”¿OAÓÙ„Z”Q„ªRt×ñè©;‰Û·à*ÇúU×ÝÜö$Ÿ–ôÐ%MHþÊæ4ÅÀI1f3‰¢‡è?Bl ¶àZh«ü ÿóä§1zñ‹ýࢧœòàÈ;ßùN~ú§š«®ºê!ý:|ø0—\rɦ÷íÝ»·D˜¢ïjüž÷|Ãû£÷´{÷¢Î±õµ¯la±m bž¼GÃû7%Ë2'ÙŠ›ZÛÝ'òðúòB †Æ»kN<ý¥‹ ”1‹ßOþ,¢š¾‹Üî>“ ¾›îqÝcÈÏÕxÃ[~Ë u•Lsi KK0žà÷ÝÇì†á¬glç_¾ø¦×^K»gvi »¼L{ë—i®¾wû¨÷˜î5t„ ç'Æ„t¤ª“ ÕYgQŸszÒI°m[Ÿ 0™ »v!Û·vì ®¬ã Ægœñm?ŬýýÝeð[oßh¤‘à᪫#h8:kˆ˜®øWö¿wݹ^IX]åMo¬xÆ3-ÇÅC,¯ÞG8r$e:@ûõ¯säsŸK†WU=Ú~tæ™Ô§†3¯jY‹Ùº³mº´„ÔßÙ¹#½,--qäÈ~ó7“o¼‘ÉdÂoüÆopõÕW³ººÊM7ÝĹçžËÙgŸÍg>óbŒ\vÙe<ÿùÏç©O}*W^y%çw—^zi_΂´Ô)§œÂ®]»8ÿüó¹ôÒKyùË_Îç>÷9Î;ï¼òƒ/**zÈtð0üé'Ý´Þún6ïÿéÍùÊÉY0L†+#G‚ð…;sjÁ^þóé´×þ‹í<ûÛ9ï)ðŒ³Ò¹ãsÏeË+^ñȸ˜Ùl=w½ë]œxâ‰xÖ…^È\кí¶ÛxÙË^Æžð>üáiÖ%—\ÂÏþìÏ~[£°Êz EEEߎV§ðcoF?8²û…Åc í¸Á4†í8¬+ î‚Ð!‹9+,Ô§Òþœ'ÀóžïúßaÙðƒ½ ÔŸþéŸòô§?Ý»wÿ£<_1¢¢¢úë=°Ö.ûáß…Æob×g“ìbp¿ÄØO2”0gd™<“Ý—ÚxŒxLLCqUÓ ó i|DhµÂ‹ÁchµÂ‰Å‰M“3åW^ú8÷”‡ÿ÷^V$,**zÄ裷ÃÅ_B6…÷ÏŽaCmÉÔ£> !`‚?ªmƒÃºl!FÌmïPIç|šÈH@m@«d QD„u;é £k;±4ZÓJ:Ï«áq» /y"¼õù°ü0žî]f¢=äºrF?\¶+ûüõ>¸ð+©sZbêt8 ÷·%Ñk{S8k1„xô#Úª¦MÜ«ÖaÚ”At¬Î(lp=dÑØlÖ¡„Þ<º¶Æ”iØÎÕ*`ðè$ uèMÃKbf­ÚeZ­hµb­ZêÍ£1sqÆróžC—|Êò“W^s2žŒòG>…°Äk9‘­LÚy8Å@ŠŠŠ¾Aæv¾ÐÀpðEnç‹|µa4ܶ#øhæ&à•³Cb_Å(xozUh”èÓ9Þ¥ûc+D/‰ÛãD"fšÊNÆ{êõ9óhÚdm2•Ô6!Qy­Ë%§l ¢1µ™·æð|žhì;ÅE"†lÙLÄÆÔßaf9™‡YòèÖ#X­–9bWX·W[Xª×X³K¬Ë„eYM_©ðÆE …Tòóg2¯‘ôöày3~‚syO`;-RTTôÐhoøÚp$]á!¢&¦SËûäf¢óU+R¦‚²ÍYžÛZZWá¡mªd>QuCP\cñ­!zÁezmJh5­‘„à6=ød$(D'¢=ø4ôUCÊ>”T”T’r)ÈV.•©TrILí<2ÊDŸÌˆt %µ%$ƒ ,“™È¼­’² µe㘤ò•n ø‘áp½…Õj™ûÃqÔë KíÓÕ1Óéј>#`G.™\å°µë‰ÂjCO6êgË´Xqìå„°ƒU&­ÞX ¤¨¨è›¥àÎO/Nr;æ>À×_=­¤à£âc Æ.$ÖÔDÔzL¾š&Æt»¼Åµ–fZãÛÔn›´ö…w©C2צâœíɺ¡Õ~ïRy¦£òФ×!¼ß.šŽ‹¤@c"ôvCjU³!þ°?B}ú *y)¥¿ªç‹8åçFéwëq¨„Äë̤@žîÏÇ­ H 2ttI­†  ‡öÁlŸ§>¼ÎäÀ:[V#U¤m*D#£åBd´2£7T£–ÑÒ S'£PÓý-RÖ§’ÚÁ)#;c2Z§6 q&´koÆLÝùçÐýg`üYéÅ@ŠŠ ½õßÁlm‘¼ªlNÁöÚýpû‡wiœá‡£*1´3¦{ö;Ú®@ÌbDàæ“åò^òH&Í >ç#ââ"¶Ô¡I™ƒ7=µ6„AößxyÝ IæÐ+2'Ï2o÷Á<MåÕЗq0ù®A 1F¦·ÝÆ¡]Ê‘+®èãsâJž!M"ÉF2K4¤÷­1‘h5ÓDMçFÁäÚÑk{¼ Ñô~:oPó{î>—ÉŸÇê¼Ýíë* sOt_;ow{•‰UžÕmL¦ûfJ¯Ñ>À_wsÅÌÑ›CwÎïè‰|ðÓ§€I!&yÅÀ{ï_Áå5I̺Òì²bn”Þ H<ŒÁ€WpÂN=ˆºÈɲwžü1&ðLûÅDãµùRÞl¸XØ ŸÒÈéîO¢ñ: „°.´²Äú–­L;³ûI,¿êU¬\pfçÎG¼ùÍoÆ9ÇÞ½{¹è¢‹Š}ÇÖÖæÿ0}c‰Öäµ+Tº÷¹¾Îô†pô`¾ôV%¯«‘ÑîYVu±ÝQh;zo÷3¾?wøÙê:tÔð³Itßž¾Éî9TI¿ žcC¦²ð¸AÝ{¯ð_ÿ«O™‚!í%e'oûýŽM"ÀQû8È.Bo éX—b~=É%¿îµC&G ˆIÙXÌ™Y6ZM[#0µT³È/¹ ‘ ¼Îÿ–uº9fÐqGL‰2Î=Dð|ÁÕ#رvì@NØNµ{7õÙg;Ž0ÃhDýØÇ2Ù½]^~ôH§2½¨èÑ£‡`:%×Ö’~é—ᦛC¿þ¹J`Ún¸±E¬GL@ŒKæ`b|2½a¤’T *an&9ÅJ¦‘ŽEÉ(±ŸÄ% ?!¨â% 5öB4à²4‰$afaf`fyòÚõüÐú{x©ûSvÊ~¤mª`-$ "Äш8™ ;v09ïB6ÎÄ‚f#09«0¹$•%Šôº’šÒ“scZ½/›Å®|¥ùD M]ü©c#˜\¾htÞžšd&NašËZøãø÷ùØiðêçÀ/ýèÃÿoY ¤¨¨èM¾aN«•¸-òSy*Ú„ ‰.ÍüŽ™Eè'ó|:=&$u—¤vM¦A$ªô÷GIí(B41>t“2 Šh šTöÁä¬B²iäL"æòTÌ&d>‚,JÈ£Ù¤7tœ<ñ/õQT Q i±Ü¢I†Ñ—°ò6Ëë^`¦óQU.}‡—·pùÿ€{,üйð¼Ó‹}—é?|:pd}N§ÕxÏå-&$ŒHå“i<öD—f{K쩵6¦aÄBìuÃtƒ¦ky‘Ä“ê¢3œ%t÷“;Žvmð¢)û!äã}‡·¦v2 r›\ŠêŒB{Ó"‰}ö‘\¾êz¾Ó ÅÄÎ3V%,I&ј<‚*g%ÃÑU2oÿö-ð¾{àUO‚7~ û¬Âç!P!g?éxL½3šã}6•d jú $Í.¬’4iäL¤i%Á }‚J&眆»Ï†Â=ïZ\~Uä=çÂ#å8}øü^Š= _õÛzŒsX—öWñ\º¿a<›Rù–q;¥nvàÉ «ŽÊ´ÔÒpÒ ŽŠd @¢ÜFGD°Á¥’‚ÍŠÁ÷ÐJÊ:|{׎"}{ìƒ6î˜W“ AñÙ(¢(A QÀ©I†¢š%=>ÈÜh: ¢™®ŠÄœ}ÌM#Jêâ÷ݘ[UBÎ@è²±à º0ëÛmÆQ›€¬GMV‘qÄÙLæµ#f£M]ãÁzÇm±åw ?¶ÃòÒeËš‡Gè.RTô] 5ü|Yîn]nàã~. k©lI¬©×6 £õµkÍfÔÓ†*¶œçgŒ˜a­cfX“JPµO¯–†*´멤EC*/™˜ÊPÅDß—y >NbCöÀüj;H+¤û2²Ü«Y8ž¿öÙH÷¸ 2¿_… ŸÏ;êq’ÎyÀ@Ì’M…H¢«äãH6R’DEPѼ,†€%‹_Áû©ÌXš6LŽÌž1M©}ÊäÆÛ¦iÐ@í©¶¶´¶¢15ÓjÌ‘É ÓzLSÕ4¶ÆY 'ë4°ÄvžÇ¶ðÐ.R ¤¨è¤âçhCèçDˆAøL¸…Â~¼3=Í6¸*$Â$/í*1öÜ©53ê¦Áª£ž%S°ê¨C“LC5 Æz¬¤ÎoSå¶:´Nß(i€&‚nÖi>´ï¬ƒàÞt¯¦?æ5=SËßÿ§¢,f ¹=ßwm“ƒüDR?µÄÔ)Þ&n$zÞË™ÿz¬fhd·™ŒiISÅc.Î…Î4¨Ò>¦žzwÏ=ÄnetpÊÖа¼>eÔΘ¿NFãK²†hdrÜz2ª¢Ñd k£%‚h2ªÎsMè3·Kp\ŘWpgò Æ,)*z4kʸ—w3kǸ6Ñl“!Xœ3„ ìq·ÐúHpšÀ…Ph¼ðɰÂ̶Š^z81Ñ\!u<ã“yà°ÆQ¹6-¨”³ kÓ"KUÕ¢6ô$X­•iÓÊ{•OÃ^EñÇõ IDATÌ p´98±ýD»”Tx*>ÿ‰'ðßßöôÔÏ 9¨w££òvÃGw$c÷Y†3Ñ»4K™W_¤“ E»aSæí˜{±cb„úÈ:b$ ÓÖÁ _õ''c'Ù˜°d<‘ŠˆMFÓz¦·Ü7ßÌøð”vÆÊú”Q5cÙ®RkÃd´Î’¬aÇŽ¥ãÖ¨kR¢©„åL2\gì|åÅlÃí+\ŒðXNâElç_)*zDé¶¿iž6,GÇ-ü2ÄkÒ•lLÀÁY3bÖŒðÞ0›ŽˆÎ`‚!Ì*ª(h0ˆ³XÒù»ƒIË~ÞÑC&ÕjL 4iþ‘„—˜Ö¹°™Pk*¼—Ö³¨Àh@+P‰¨‰h…Z¥ûŦcR¥c©ŸXñ2¢eL.rѲĵמÄW¿z^,A,^*¯ÿW&®bÉ{É|©!`l“ÜÒµãü lb "Gç ®!ƒ;ç%>âàA¾v™, cè†^qÑ®;Ó„ÏÙ“=ì¨g7ZcR­³´²–J…8ì‘dàhbgïY²k tæ.ƒ”87 ¹ ™÷¸Á6ý4¬}Ú]pê«á0´níSŸÃ¨Ðx ÷Ѩýþçìï{Q°´ƒ–šáf-f<Æ.-¡£f®s Ö´YuE¬3u¶£òVU:oHµ5ŠX“¨·"sò­i½™>[[0´»?Ór«|­hM2ÉmÍ#‰L&ÙæóݯÜr[6 Œð±ÿ±…·¿ã°‰XÛaßþ „f@­í–îîØR mdñØÙ…0Ïz×ÞèäÇÈø¾yøËØÜY ¯âà½ta2 Π̳Ÿ'Ä e]äîîÏ.rg®nÌ.Ø$øwÁ–AGu<ºÓ:Ìcá9äe¨¡¹«þ%“¼îQ«ÿÅyö±q­ùce+±ÄA'»×ùgmÒÌôÔÎ MåþŒ–á¹O‡ßý·ðØ]VWi0.”&í¶mØ;ÔŒ¢HQÑw™B„Þ"©æˆú†÷îØççk„zNTÇ’‰ Fáé ÄknwÐúy@5a!uØÉÙCœYűŒbØöÃa²r´9„M cx~ü™GdÓu4úÓäYƒ,CX4‰‹çHÜ<£é „ ŸÀ™ùÜ 8èÏ€Ÿ}1¼l÷#ã·YJXEE3ýü§"ÓÆcB"ÜÆøƒÏºL(DtØvZ6 R¦áÔ¢™2Ûµ±0HŸ‰t&‚fé&ÍÅÔ›Q{˜%ø F1ÔÍa¿@w_we>hKˆý¦]»›)cŠÓ!nh/¾¾³` yèëÀaº~‡KÑÆœ‘tÇb˜ó8ì¨ôÔß9ú}Ã^$/0µIyL6ŒÛ˜ uíÁh«Ý¹.rð¿>¹HQQÑàbóêi˜™v»wù7W¶TÁQ»Zî=0>1¦„D¶=ùqÌ ¶™N+D\†êM³–E“‘8µ}_‡š€7͘óÞ@”yPï:€;³‹æ !‚ñy?˜‡ >wõm=êâêB:êCú<.¦¶Ù8òÞ‡ôd#IÉOèMEâü¸d3ëêûM:Câ`èðFCò¹:ÓªsÔ»IÆ’¨¾Ç¢s´Ê‚¡t¯‘ÏëÌ;!V‚¯ ÎZ|mðUÊ£‘~ïÞpgäÿÙù£g »'ÂIÓH] ¤¨èAÒo†€s-•s˜àÀ9~ãž–ºm7SŒ÷Ô®áøI‘+ŒÇ­€õ®FNmß)îŒEˆx5=êÂKk*¢ ­Vã¥Ö&²m4‚š°hÙÕ´ h6¦½hS°wÓz´ )#ré\ÓzL“Ì´ùxg!ï]2ãýÜ0|@| üý±˜Íe!ûÈç„4¯¤7a!ãèΖ±63ÆÑJ^`j˜Ì3Y`wuF+óãÝcCêݯ®É8¤ŠP%ãV É@ÄÂÚQÅl4Â-[Ž,­0q•ÅÃàøþÊ ƒåe[ ¯W)RTôHÖ Ç:íBÀxwrOlû> !r}h©šu*—M£òìå€u‰=*׿êPB wJbÄÓ´ÖT=æÜk¢Ë¶ZõÙF«—oõýq#ž”ÚÏ!Ác^ZU›€Î<ºðûfê1m@;spÛxLë“©4)£¸î‡ ÎËI’yR2§²²5òÌ„Ô}àC*Q LbLbฺYÈ, ™†²Í äX¦qT kPfŠƒ90ýúæ Ö:W9ŠÉ•*t:o«öÔ€ÎTz³Ê%Âh‡Tú«ÀŒ=>$h¤­mUáÇ–àÈò k“%šQÝÓx½1Ü"‘wHä³x^ÇNžÊ ËÔÅ@ŠŠ¾å&Ïõá³)8„ Ó®‹wñ¹p{ N!)Í#–NÒ€±i™VÑÈãh©M Ö$zmD0>-¤£$£Ó_ÉöDZMW©>(K+J-CZ‰ÃâƒÁ·?S‚7x§‰Âë¤ß„õû _ûÌéf1‡ˆº”qÌîÜùgÍàRc´»€l¾É·Yý:üÕ ßê·yé³¾–» â¼#FÎÙ±—K« }y÷ýf¡ËQ€Eæ™›˜ÊÑý"‰ó ¥3›Hþ}¨ô(ýÌr©bÂÜûB¬b‹µªjië »ìåÈÚÒa¬´£Š#“•”]"ýoÅDÏûÄs&ÇñÎ`7ß‹¡*RTôИĔ¯¸ÿ@ÛZ\k Aq΢bdO{SZÔ((!(j&Às%bl^mϺ)Ô€¥¥\%Ï‘°âˆUfYÅH@ûu1\´´ÞÒ:Kã*|HíÖ[¼×Ôk Î\kÓûò‚k Ñ+Áœ3Ä øÖœ"¼7|â¿Á¡{Ç=A„æHdß—<=WªòÚAaêo0Û{£È75„ª^¹›E¤IÊR¾¸õD¶ŽÖó¡ÈsO¼…ž|Soß,ó¾ý¸ñ}oì–·rªÏJ"}¦ÑEoqp lI•¾V¬uHŒ˜‘§Š){­lKUµÄ±0šÌÐ¥@;©QÄr9rÀE ¾#!¤RÞm:ÃÊ8Qþ9[¹à!û*Ãx‹™Ú¾íÇ3îÿ?Á}‰ˆ0kF¸6]µÏš>¤u3Ú¶êWÏ QQ›2 ÉFj"ÕV =¡5˜*¢UÄŒ#¦Š˜QÀÔ¬âÌ^Æ´²ÌŒZ–qLhü˜Ã7ÜÆô®4®"xCÛ$ãˆ!áÙ½OYCoAqÎ AØsÏ©ì=tBš•„~ü\î¸k熠¸q¦·,¶ûøÜµeea›™Ç·:6NýÞl6ߨ¸ÑH&(.ޏzâòüôã?–Kg³¶ÜÈ6{䨗‰Çú‘㜾”Õõ‰tÒ˜g£]vÚ›K÷=Ð*€»â°+] T'´ÔÛÌVÏhÇ,µ'žz%íÉÔãœÙ½F·æKŠk,®±TÚ2®§Ô4¸ÃâË©·¾–Èv¶§a–—7%)ú®Öç> Ÿ¹8¯ ±HæÖÍþéïþ ¸îèqü2xÀjª‘*:ªb-L¬GFB¬ªD²% ¡Œl&Ü*2¶é©ª D´UÚWU"ÓŽªi4&!ˆEd‚KdBd‚Åàï¸ þê¸ë~lÐÜm©ÓbÝóµ<|*?ýÁ-?Á½³í骖ÈuwžÉ×ïß¹V+ÌËáÃh80°Á@ GM„ØØ¿Â&¦1¸-ƒ‘ÅI _ž=‘_¼ñ‰ý¡ºíóì¬A„³Æ_á;éýßÜ@6™W24á0å> wæX0‘©$aôG‘ʶXë¨Æ-Æ;ôH@\À¬zª»ü€"ŸJUó¹'ôG·žüÐkûÑsê¶Ù`úbsl{T[ ‡„öû~˜Ñ?9¿d …ÆûðÓú¥—rø¢‹°£¦ª°ËËTKKèxLTÁ¯¯rø W4d¾ŸMþÉÔ8 ©mÖWѵ#¨&Âmqš€†‰ª[Ád”h³Ku Øã,R¯2©ÖfòìÒ(öÚB©´£*Óh5±ÉêzŽ)¯-HF—ÛŽZ[¥ûȨó<ö?Qm3üÐt#p 1s Tiê_„é×îæà‡.áàŤÝE¸{íînK£«¢pÍ왼çðÿÜ3¥ºãðÑM³]˜@7$ÆêüXdaƒYôs4†Ìå[ ß*xj£mbT ë‚ ÌCãÜ@¾‡0¸Âˆ›Î¯i9ÁÜ^ø¡“/ã§w)Dáñ'­süJ{~ºœXØÏw‰à3½0È…>€ï¨†1ý>–G°Cúùt}&’YšÈ"Csc¢ㆶƒè!:ˆ-Ђo!¬¯Ç¿ƒõ­[Y?ñDªsžÄ¶W¿š-Ï}î£Ë@ ÷‘£è=³={ðGŽ€ªÚj%·ESà퉶ªˆ1ˆÍIqÆ©÷å—aqvùfý Ã2Óàœ>cŒ‹ßeÜ/²250‡&Ò³óíÍŒåXf2ÔÒÞ~øy{yòikà•×ÿœ²)F*ÆÍ}2Äùï¦kwŸËæ ’ª‚ªÆÏ¦¬}ñKL¿tV•ñŽ̾r³ë®#Üñ5ª¥%Lmin¾÷µ;l,zl›%ϧœä–W°§†9ù1˜“ON˜öãŽÃ‹ës≌žøDÆO{fëÖÒRú@Š®ºï4íüö{þþâC)0‰\uMN¯ª<Ï„9:DÃ`vr6n6sgA6iËbF‘Q!6fi½’n®…VïÚH*¦ˆ ·¸Á(ºó†%&úS"sSŠQ·•»á¯©§uÉÆ çb ÍcpÛ°h2Ä GæÒÝö™A…@[³<åI¨†ÿüFxÊ9éÔ“v>×ë눵ˆ1øC‡ðGŽ Ö¢ªóÛ9»{ïE¬Å¬¬ UuÌœ¯‡Tº²‚.-¥môÉùåâo¿nܳI·Â•ôÓ`À›²ž6EwÙ™kïó»8G¤Éw™†4Z̈ïç§hÌûÌÐêfµ«$l»fã@BnÏû Òé=ËfËʲ¹¥7˜‡¥Æ¨Ä Ù4´Äе=f¾úw^w=ÈüvéWŽ ÒÍ ¬KÒ/™ÛAçk´vPò[L†.ü¿S…ôGχ­+å7þT:Ñ‹Š€.þ ¼ûcóÃþûá3_ÜP•9m“Úƒ2¥y¦ÙƒŠyßD˜÷ShÆ}$.Öù¡!`¢Ç0ß:ÓИ×>Ïm‘¹¨„ÿу%äex D²¡¤öüävʆQC›”°æ#—H·™Y4Î4r»ÿÔbò¼›Úbð¢ í¢6MÌ4qà If²°NÉüÏõúw¥ý_ž³üϯ…§œ^~ûÅ@ŠŠ¾‰Ž4ð7·²P„þÑ‹`½ÝU x»Ù°Î‹,© ëFH”ù,lŸ²<Ö¹´i>‰‰ ¨h‚ÇÄV´Ñ¥Ì"¦c9üQ¦Ñ‰HL™ˆÆy"séÚBLçäìCzóˆƒÅ çë¹5Äv#&d˜ô{͉bž?œïç³»{ãˆsãè2!Ĺ‘4M¼ÌfâÔâ$m­V õ¢­­2Û*T{ÞÕ|¥HúE¤þæp?\ò–ô÷ü…—Á vÓwÁN(ÿ+Å@ŠŠ€ßÿ|ážtE}prm.‡t«Ñ¾áJuXòƒøÙµóðÊŽ e\fFyõã=•k“Yx—ŽÅ|_H!±3%Ì $·»pjHbÅõF 1ô3á;AÀˆŸ—ªrö 2¿¿7ˆ†Þ4X0yæqTú`ÈpŒƒ!´¹lÕõÉ„¨½¹tíÎ8ÒDíwÙGŒƒÒVH3CT|L3÷CÌF"ó¬¤Õ*™‰ZSãÕÐØšÖV4¶N`Ckú}ì—!^¼hø­›ÓöìSáiI_Ç¿ìÞV ¤¨è»R>Â5Ó¸@nýÙk"{×<=Q…CÓȪ×DCUAžnçAdÃ:=‚Üå½O›mլŶÛ¸´wKÞ¤ƒ8Œz*i{C°!@g$Fü‚Qt³Û»óEco(jæFÒ›F6‰³¢‹"¤i•°Á8b^‹»+_1ßÖÉ…9›|éÙ@6NÀŽ‹Ã­ãI…A;Λ•¸ºìÅaûÌÅaû¬ÄI& dãðÑôYˆÇÐÚŠÖ$vXSÕ4U2”Y=¢©kšºf6á*K0J°Ú_T\.pù4}®¿¼*2ÑÀ¿;CyÁáT 'Úb EEHýzð„î ß{xëÝ ^¹¿Å +¡G «u5›dº+OÓ$ ­m&CíÌQMÛd£nšGœµTMzͪM{s)J’˜ÍD3Û,g#]Ó˜:¤r–ǤlÄÖ ^IÅ,Žh›Š™ŽXŸMh}źNXMh©c%Ô 5õŒÝ”[4r£µü•Â{‰œËÿ»°V)*z0u{¸+Þ¼P‰åZör¸¿Ý¡v’‚KDzza·@՛݆*]•ƒ›Y‚SB£„6ŸÐfjmf MQ5-õj“ŒbÚRÍRp®f-Ö¥ŽìªiûRSÕ´}'¶u9»È£¤DÓ¢Phäo¯>‚bÓˆ§A'ö°sûóןÂ57ŸÌ±ëDCE^òœ›xÒ™wÍçFv™ƒ²`“ñŒþO¯œ›ŒÎ ¥Û÷%ªaéjh$߬|5[sÞÙÔ<âÀTÅ}Ž hNg]«3ž|6“ÍD !3ż¦vŒiÍ”îþÖT¯=ßCKEã’ÉLuÌluD@Y“ÄQ3?1 Å®`jyL•3O“¶=Öñ«8Nf…ïç)ŒñDÎý®ù-ó@ŠÝÇ;8쾄ó† >(¢‘UÙÏ~¹#L5.Œ¾éLÃCÓÖ¸ÖÒ6®±)´ 4çÛdÞ¼3¸&ÕÉ}kzÞThRðb2’î ºMAÓ6©T¥:7 Ñt¼ë°­C5÷S8‡˜d7~å$þòïÏCRÄKA=Fb„«¾|êb„Ý`óÎjé¯î7 Î AzðTÃ5Ä7yШnyö³¾¼P~Bà^v¯~Ùßg#Ù$ÓšÇ7Âg E65®„5äKuF0d=uÙHÓós£—~}“þ\G_ÚŠ>lûvH%.<}ç{tÒNûaÀÁçWîS™F©²¾<ÁÛtaâÆ6â’d ¢ ¾i'[9l혬¬SU-“ñ:£ÑŒ‰(ã Ï Ï`;ÿK1b BùÜq鱃‰‡~ ÚË:@WÑ-¹ä;ò­$z©±SyT=1(MS³>Ó6ͬ¦™ŽÎ0›Ž’)4Š›UxŸÿégU2§É(HxóRçg+¢“¾S9†´ìh·lªhL+îEŸ ¤mAኻÎa:­Ð<[[càúWLÛj`Ã~ƒáÕ{¾Úï´¢;ò>÷QD‘¹qÓ@RÎEÜ$X/ Mèƒ0yfz :X»|l-þ›ýÎÑç@`ãDBbA%lI$ø´Nˆù¾ôé÷ÁÊ`™€ì£éÜrb{rbûÒXk«ôMƒ.Bžœ(™ &$/PÕ-Õ¸Ebdiy¥å5*ÛR× £z–²ÓQ=Ýúks@â®çÀdG1b @}üáºO-Ž‹ßˆ0 ¬Ã—ÿ[êpYÛ7œdZí8l+ £·ºÊì¶[ 1ôÏd~ÑÝsðr°Ó 4Mwñ’ÌÁð‚kê4ÂIo]ÉÉÁ‚d!ê|lÈÿèNIçsú¾‚<¢u†ÿpíÏ÷KÊ"ðÑ[žÍáf©7о¤yÂО«3 çÀ< =óI4ÎIëÓ¤è¾<$ßx]§n¶wŒG%/±G–̯òeh +Ót³©ø|, ÑëÜl¢°´4ã_þè§ûTä5?~=/xþ×¾qöÁ± $µû$Áp-v:Ãèó¶|nÇùã}·÷i ì0}~n×N‚ F¸@t‘"¸HlÓóÄ6=.úmÚŸ^?†ô\~îî;î¬=J¿. !™‰JZ]±²-Fýâ<¡¸”sÚËatJº½ó øÑ_,òU¡ñ~s­ä#yç;±“ áÀhš“TÀHÂA ‚"XQÌh„LFÈÊÜ:TVƉr»z§DgÎ@T¶×°4 Ä(¿ÍñÞ÷\ÀÖã"gžém ·éÓ†uÍ{é R—°ÑxºŒ¥)ú9q°£êvLw¾Ï†Ô™LgL ílR.€Ëßec ù˜Ï^æï¡íl0(ÿ?{ï.ËY×ù~ÞKUu¯µö%{';·BB¹)ÊETä¨(àý(Îè=::>ÊÆAÑQ3sÀã£sŽxÁËÌpPTŒ#Š¢8*"B¸$P‚3 IDAT„$$äB’dgßÖꮪ÷}çß[—îÕkïÀI`ÕóôSÕÕµzuwU½ß÷û»|¿&$/,Ô Ô­¾ïf 'g°9WYƒÍ ‰(ùTDÕ~h„ä ÂtJÜØ ºê*ªç?ÿÄ'b¦ÓÏÚ˜ó°I¢_sÍ5½ïî²z©ž÷<ÜW )aŠbQùÖ£œë•l͸̰S¸µnQÁ¶“+ÿÕåd>'ü“g]Àä‹Ö¹þóØÑç39ûk¬Õ,î}ëògìTz»u–TÇŽâ,nØþéŸ34!é,Ë]G†ú-¤j¸d‘Á÷½?!Ù›ÚZ͵±¾Å-ÆElÑölÃú¨¢‡^E (NM–_×3e!Éè~é˜ÄX ÑÙÔ']12òݦD­~5Û-XOç®×7†ËÇf4Ý —gǦ—r—>|eDz‘F›s -6 )¨‚­‰ ­C¢ƒÖ"Á“Z­'¶%©)舡Ե8Î?ßpþ†|üÀ¿Ðϸw/¬Ow¯ÓÏ•e@v—‡õòþà>4<ÿþ«¡meЄbúðfÔaÖp‚ó ¸”$"V°> Îè~HÆb¼æ9Äés  Ñ± —ó¹s9eÁŠŠûeaÅÞéc=€tæTŸ €#Õu͇¤Üy‘íò ¦&%HVº"HÐ|ˆ•Ôo›’sP&R[@0©-{p‰­IJ– ~Xg)’—¿Äðœ/Òø’ç¡]M©‡õ²Û²»<¬–ÿðßá~hÇÜ|Üð±ÔK†TgEÖоN¥ÖÛÐË•;51î‚V{9°¾Åø„8ÁúVÀ ÖEe ^YGì’µ²r†dd$KŠ÷@b•¤ËH¶c&„€ÍfäÁ“åÛ«qÍÊhéÃ*#ÖÁ óNʰ“² $ š]¹ ª(˜”2AåZH«RñKj%HÔpWP1 br}USO•ùý¿÷¼ùÝÚþ¦¿2ì߯z9|Ñ»×ö.€ì.»Ë§aùÇ;ஓ:8Þv|ÿoH/an“*Ò–©ÁK –‹· YsÊ¢€ª÷äM@Œé;¾“µ8«}Éó-ÉeE« áÀ¸H0ŽÎ4§@aUZøD²®h\Ï4ÄØ &¢ýóÖô¾Œ€BÄL$—<ïÂ’åšéQˆa84/"=Û0KI`sb݈(€d/›ÈV&W%Y‰˜„ˆI ,Z\i½‚M°¤P`SÒ^ qØ”zð1´½ÔȇﯨV¼ýg<Ñ9^ù|Ë‹žl¸üxì9»÷Á.€ì.»ËƒX~üïáèŒ>ÑûŽ&î8¢]ÞEl9x¨¥’š2*h”ÒP¤Ü.mošTÐö¥¸žû)g# ÛëE%k±.ê€îŒ†§¬Eœ`¼2 ˆ¢ñ bvÓÉ€ q–Цc! FÙ‡W›ÝöìJ ò¶I›w`±¢„w{w7Ã_dKÚ@,©Yõˆ"Z —+Dr•±&Ì] Qp°$Z\Š}Ë¥A+´lJ9Ä¥ÇDq½"qmä4"´ &jSésãØtëüîõ%¿qcÉã/.ù‚G8žy!|ûcwï]Ù]>¯—Û܆Ë;Žo¸YÍ‘LH=ðuMÕ(HTRsùÁšR&qŽ7 ej(¥Á‰†¢Jiú¶ Uf%B’@#Çý·™\ìb‘¤ oIRêAƒVtÛBÊLCr(*7JŠ+PD,åy¶2‘”B $+$ Ö ì#e H=ûÐræn[Ȳ¾‹q¬Þp”1P:br…í^KÛKå*à˜4då211o“Ýxƒ‚G—’&Þ£`%±=cŒ¢š^$ÆkW~24¶T…㘹)Áxj_q¿Yãï,ùÃcüÄm®:èùwWX&Î𸇰œÔÉmò“ML|Ó{“²7rT}î˰†ßþÃz¡çÿ‡‹Š]Ù]>—_áîóà`ùÓã‘÷ËRçu œ5T¾fÚΨBÍ¡²fœ²P¨BMa[Ji¨Ró‘BÚžU”©Ø…DeY‰öþ#|çF )˜èàœø§?*´K™´Xój:c®\vì —´BXìY8ë Kö>±P½¦{({~ÓFîÛSÐH=hdB?§t¯õûÍbÈj!„µ @†UÂê¼?ÌÐ ?j|7c«qu>ììpEÃV½"±›¢¶»HÂ'›cÏ>lÒ¾‹Î +‰î7¢Ò46—«¶8‰Ds7ÁˆPûŠY1%Ë©rƒSÕ×Å /¼e/k|ס’‰3üëò¡1Ê6ÀÏň‰ÂíóÈo TuMÑ´mËt:Ã&ut)ªTJž€ëi]ÁK?¦FWMUò”}ž/ßkÁ¾Æ[ž`ÚŠ¾»UX»Ë'µœ`6jÖPÊðqBç—×Gü‰˜VYÆdsÎÚæeh¨¶”iÒ2Ï(DbÒÎñ.‡§b‹/%Ê {ÍuÔgóT‰—@´ŽŽT¼ùõ—º¸¡ž;ŽÞU }"0X—š¥Á׌Æ.ƒ,Oûe{ŸÁBý?Û%EDpk†É¥~AÂ|ý 'úáý}®Ãò˜Âe/Óƒ‰,'ËYç?ºÜG÷Òý—‘­Œ|Ñ¥óN™}Äž…tˆóag«ëDÁDÕ†6¡2ô9éîSèÌ"µý¶O¡«ùúßħ ÊÈÆã$R»ŠÖXIœª6˜’µߨÇñé>æfB¬*SMÀÁëÍa<°‰†å>ÃËñ|ý‘À¿ç.ÚäøPh™ÌæLÚ9Sf¬omö¿IÙ6ãûk«µêˆ­ë£Uy9!zGt޶,8ì ζ‰¯g/ç,ö1Ù]yx,÷ñqŽpû`+šôñ_ãû8™"!zBT Pû^C(EUÆ5­`C¢ eº9£ žÀd¦!)O`ÒÎq>R‰Š-¥dÐ(7\{ˆßzë5ù}ÇÎá/ÿøQ}S^/Q² »bAc”;8m3äÈÃbÅŸíÍl«šÕ–@¤š¾C:ÿ¬ßD‚‹^sò<ÕðZdÅ¡çïY`1‹p±X‚Z‹]„’èAÌh=lÇ|\ìv´vXFÛºÙ^7àòÃvþ'iä…2Ú¶22ÐJ©·èL\­-z€›•Ó¾ óÄt/3™Ò¤’ºª¨ME‹ñ*ó2ûöÙ‚‰Ã~Zï…Dä:y7!yÞÿ‘Sùº'(ë­¨™Ôs&圉SÕ5ÑhAÂÒØR-w­§v•†õçwã4„š¯ÝäìÀ öáyWâÿiþ~»!¬ÝåS^"Çø¯¼¤£§iJî­à¾p”¶-hÚ’m]pQphd¹íÔª’n§·dZ¹Z¥i¨æµ‚26*yM ô‚ Þ¶Ú’«_ó2íðö‰[?v»ïÞ¿( ²± 4ÆLcE÷ò¶°B³ið؆;u?³½¹ÓvZ`&ŒºÀ…ÛþT/$89Tpï“· ®ø–ý\þ {—>ÒªüǸ°W¶¥ãɰNªœÆ0€Åš€1!ë ·yÀòó€£ÍÛ-Ž'&ß /-ž/ žšBf8iðÒêÄAR*z°‰Îõ¹®-·FÓ”êÓ*B«=&âtÒr›ý[ʪ¡²‰¶¸œâ0¿€áSuÝ)¯åXœ1›y>:ÿ)Y®l DŒê¨%¡(Z*S루©\ Ef¢àQÛŠº­¨ëŠ&è½¢—uöÎg/—tÛeq>â\ä&þ„‚ˆá1©áRû“8ÖwÈ.ù4,wþ5„㋳ó%î‡û¿|žÙx=åM]2ۜҶuSQÏ*bt4ó’6*hØ©µÆàT|P4m½j!#ªª+*Ph}}øHa³k¡7AL–w|èiXñEà·Þö|Þñî'çRYmÌÃô¡Ü$ìN ±Ä4ÆŒÂ,ÓŒ%ä$eaÑ}y÷X¶‚ÓÈfÈx*;üýXé‹ .èR‘õà+þÝ9\øÄ xℇý¶ÏhV šÙ&iÈ &£˜éÁD?”%ôlÅzÖ¢ûSf+m~¯€£ÁHh²O`݃ŒgÖ?/˜á©qÔl*¸°IÉ&ž§(ÙÂ¥–ÐXbm ­%¶†X[R„ÔBlŒ†æ$‘¢¡ôªvkŒº8óóðçÿŸƒ`a³ôs•ùѹÏ^Æ©MÏ©­ R²´m12å[‚õ‚+ÁW‚/#~-Ql$¤ðœ’s8ypêÎ'NnàæŽ°UÑÖ¶L¤ ®rª¤˜´øJ Ç|¥RðÖe{§ bD¨ªšªT rI2m zðh-<â«vd@FËŸü\ÿ·ÊˆjÙéÃ1(WÜüLs¿¸vÚéË4åóPÑ6!xMèåB?;ªÂho2ý…mœ` Áxƒ™xLi¡ð˜ÒaJ‹)¶rúzixÕo~ÇææRð[ïz¡‚„O Vôû™€tà`GƒtÇ0ìÒøÎ(|%£œ¬³:ìô`ãç";ã ²=ä%£\KMÊÙì4“N·“7ï%Xh-û’5ο´„hùŽWïçœ ÝYþh‰Õq¶qÞD–Â]Œ@%e`éöu 2˜¹ŒÚòó„ëÙŠà¨3Ø56Ïû ž†DÁž™²× *F"Ô5„ †u m«ÛóF÷·ê Y1 š”EcEœG˜-ý,S S²ôŒA¬võúpÞb ‹qS9-ÿ”§àþüÙlÆu×]·òµ‡º¯´­Š¢eá¿û®¾šöÚkqÆàÁƒ¼µ¸é·w»w3™ÀÞ© UlL¡*‘ÍhŽÜɉw¾“æ®;£!«ƒ*ôj{[k Nt¿ƒ‹ºmlާ£7FU “B•t'EVÛdùõü(œ*ñ–…>*U®5ÎBåTª£ðú÷ư ®¿UUzÿìýñú·<Ê¥pdsƒh€b #ÅÚ1h8ôÝ­Y´J%”CQfÁJu –)VŽ¥+ÞïLa¬q(l!,¶Ì(bGbGb2`uª: Ag–¸4ZÃþý.y~èê½\ù¤’K.v¦‘„üèZ?²RÀw9î¹?ë–ùZï®wcôþ.|fÉVïmœþéƒ\ø—ÿéÞS¬o¶L’ˆ=«Ä´3ÄDœ\ž87L–Ìrn!Д'JP‘KH Ò@l-­Y»Ž»â‰ø½ÿ ߀¹ðÂÏýÈÉ“'yÛÛÞ¶òµ‡º¯Ô5©i0Þc½ç쫯Ö:õ[ç>)eÛôÀ´ü Å%Ï¢t[–½J­íÔi½Çx±¶Wª5Æ`œS5ÛNv²jm!gõ52¨ØNÁÖ7—³ƒ"¯5‹³}E2^ûº€Xá®c†_ùʨ5m¼£H°žÐp¹žÔw !#¦‘A#åýDí8LdF i³Ä"d´Þiÿ*‘XŪqX¶GÅ:¦± LÌèø@¤å×H~½{‹¶ÌR‰p¬u¯þ·3˜·¼ø+'<éÊ’ç=Ûñì/±+’<ú¾²€w;™w ?jwœ¬Ì¾Œÿz'÷(3J🠙eéçé´ŒGªrôú¶(ãÈ•JäLXÊ}÷ ¿øKù:u Þþø»÷Èp­ÚÑù]¾Xz^ùý\Âw^·ÿÑ5Õ™uE²¯ŠvèÓ8–'\¼‰k#\´Æ¯ü\M:öëÛÙ|÷»iï¸7™`aóïþŽæÖ[!„…ôlsüÅ>ÌôÊ+©ûX&y åEáÄL&ص5ìd‚)>³ý2»²»ì¸lÍá·Þ¦ŽyÆ¿óVáoþQµ L¦ß©ÖZRR&¨rIQ18Üt¾«Lʳ»4šÅÇh$VÁˆIŒï&Y 1KUO;0“´”D°w‚…±–ÝöËâàÓm ½3áÂv"—rŽÀ´›Ùºüû„œ Z§7÷Ðxý.µƒÚçcáI†ïûáœý†—<ïóçÚýó¿‡[îÔßõÕ?/Üw,»Qº¬à•UˆgŽ!÷–iz;ÊY±yWÊàž24.Ÿ‹ (QA¦´ð†×—>.¿øáû;ïÈî²mùŽŸŽŸŒ4­ðŽ¿W[q›i~rZE#•À4¼EJQ°Hù¦´iØî®2›—<›c¹ÝHÚí“C8y_7ȧ¥›UVÆÈ,iHÌ"pŒAhœ/9#Ç—%æÁ’÷9Ãwc4øtûì(l×W’&;bN†ÏîF¿…•ÞÞ›$f0©½ 76s䉆ÿô}†KÏÿܼnßò×ð¦·kú}×'î:šM½²g‹tòú΂ÏJÉÎ “¤»Ní‹”å K $_—Á̱Í,1Œöç¼O¾^ðøÙïÞ]y-Çfð7·túGÂë~?òþ›T ÐY•A« ¶XˆÞa­ÖæGç0Nh|I*AšMÚÛŽåY]ž=»‘ðÏ»o€ëï\uD<üɆË.€¥éÎ?wäñÍb:H/c.ÒÈêuTÙj„Ó;à-Ü1fˆ„ãnxF”^·ŸÛp8ÀÇŽ€Æíò£°žÍ³Ûîoš\ÚkÍÖ2:Hù6àBD‚ÁUÜ Ésõ×Y^ôDÃS/2Ëë÷Žcpí‰Üšø‰7ë$Ç›ÐûÛwתþ¦¬ïÁ#:ͦ@|¶±íÎEÏ —& ²*ÿ1š tuÙW^ÃXùƒ]¬°ëÝ!‡ççí…ÿò]ðE€³×wd@b‹ÿÛÛµ+ø“?ü`¤L*LèŒv ÷²ç6¬Wùsgi}u‰úxËÉÿqC´Nˉo‘®ûÄ@œ.+}Æn½^ÏÇìYƒG]´°ËŸ{€ê±—`¢ô*°&e9˜z1ÁnŸ)4¤dUÒŠOÑ)æv¾ÖôfPÛ`²¶—|—gÒÌY«·˜4z³MÚ¹ê‘(R«Z=¢r Ázîüó–Swèl­=¹ûOO²Ø~:&a˜3çLîáA=¦„ÖÁ%^„)<êÂ40ŽÓ€Ç* 鞺0Öˆ} ƒ‹L$YÛƒKr¶w3ŒÞéëDÄbáH…#:K(=±pú¨¡òÄÒÑN ÂÄ&žX9Ra‰Kª¬>/unÊE*C  :‰0Qð!P…Z}9ŒÁÇ@]TÌÊ)­/øÚó×yÞþ5^Z~öªü³n9:Ûäš»Nqˉ9{æ')B ªX+ûÍŠÌ­+zvÑøR‡÷4®Töl ZW¨€¡+4 k]VÆ5ƒ>YúÌ6¿Ý¤£g«‰Eûà4Z§ñš~²bÒ¢Ù—ÉÌR¬Ñ"oIÞ PL^ïµ"´Lš9M ß|^É+'ç³ »òÉ/ÄIš~ ‹ÿJ>I‚3‘£õœ³M&aÎZ³Å´ža’0i潌v¢qÄÚP³´Ösó5%7ÿŒeó¡Ý4KÁ}–¶w„O6$e>Iðx°!.–â‹SÄ {Ö…=UËóû€¶ØÈš KŸNV¨ó.†°ù˜÷`ÂRx˘m`Ò…½¢Ó0yÛoÇÂ!NÃ*¡ð=¸ÄÊep±´“‚X( ´ky{ÝÓ®+°4%aÍ“*Ûw9;™Ä9“8§ˆ­ª"‡Z‹åbK_ößçäúÌž½\ê,SòcæóUƒ=–ÛÃÿ]¼SaÆÍm :v?“z®3òzÖË #Ô®R§@ëb¼Îë:û³§hU³- ùÛ¦^9ÚµIõÜÔÎ7¿ÖIgÖ•RÎ_ˆ—5aÈ-Ú˜úœŒÁM¢²IgpQÏcU ë–­)óµ âM¯ Öåmçà«Í/cûBª¼»ò\î—»¹#}\ÅâÄpwÚâÒGrç© ¹u!§²hXk·¨‚ NÚ¹Þ ¢³˜hͦãïÞ| Ñ:î¾~÷¼éœ<@ÚA?ªËö¦1€Œ8õŽá¦Ua«Oö’’\þtà³Ìv–·…Ҹö‚Ñí9ÉSλ—ý匫κ[ÿƒ‘Óþûe&2¶¨Õh…öåNú.ŒÕ1”.G’œí™LôÚñœ¬ˆe-¡ò9o¢’¬²0ÑýízA˜z¢w´ëÍz©,¤L¥zJ®Š¸2?&Q%òMCiZ Ób]Ò5‰ºªzS.1ÚF¸Žç[¸ Oà žõi»Ör/wp3¿Æ{H™5™$ˆÖf[*}nF„Æ–*ã(žZ*‚xZJZw–A¡giXKn 5Az…GI¸IÔ{Ö%н­vŸO„rC[˜uÁîfëâšS½¬|]t¡9ƒNK¯äI\Ì¥œÅgß÷wW÷³¼œäÜÞþmëië’¶õ—¸§¹WC –gx c„¢l±6á‹ÀÄΙ0ÇV o¦Z£æF·Ýx6oø±ÒÖŽÿÕyôÞª~‰i¤,ã0.%Z ]ìw [ɧÈ.Ìò"†©Áƒ³1€(C¹}sÊí7bÃÍù§=p°8Å¿|ä_ž12¶›•‘W‡Œ´ºú°V y[œ*CaФo>Và ÑggI…í&–jHsŽè™Hr–v½ÐýL%*wî_ : /ø²¥˜\(ª@Q5EÀ—-UÙP-EÙöUy·òÇjœ®¤–½öç˜W}Ò×üá5Ìü)žãœàwñ¥]ˆÐªkaÛz‚ñ4mA…ªB‡‚†¡€Ãõbq&â×Câ¥4˜R-—«FeßËiƒMB½úˆ„,RÚ…»P ´6á]àF÷çl™s8À‡øJÎâù» äs†ÔGáÞÿ¹"ÊcS¯@Ò&³ù”­­5¢8æ³ !¨¦NÛ«tWÄàʈq‚ó_%LaðÁU¢* SÁWë ›aƒ·ÿåã©eoÿºïªx:†aGrÆŒú+Œ&^%¯“9 (t%*§yIðU ô`â»fæ³à­¤®T³«éui¾09™*BEàµüm7½•s‹£‹ye Yz­_Û¡J§c"c/t1f!!/¶Û΀#f`((À¤|L(}ÿ>í¤èÙN;-úŸÉêÆh¬àJuˆ´…†µÄ€/U%EÕ⪀±‰ªj(& ÎE&Óšr¢`2ΨªZeÓ«†Ò5ØY‚–¾¯aÕOŸ$£{‚ IDAT—Ê"{ ÖE’8fó uSÑÔ%››B[PÏKêyEŠ–z^ =µuA ‰–¶)tr ±Ñ²e †RTÆaPÆÑê<,DÈÀB Ësd'Ç4ô.õÅ£Ë[Y¾ZK‚· ' ? E¢ÜÛPžÕàÖ"“sÊ n=2Ý?íG–aAPQPЋÁ)#L†ÐxJß0)æZD°éðò•”û¾ŠóᜧîÈC@äWšY®ÀY´¡`~7Üñ‡«%Èóà¢É'¤b¢b„“ª ³V¨šíÄc¦[XÌšÇTª* 0™À´âG^õ ŽÏ§œœOùoÿíªEaB3t PÐ5ê١ɉ‘`_¯›ÁöÙûª¡vf#;Î2û8] ðrnætù³š™Ø®ï"šÅºç£j€hùµsqq/Þx'ÏÝxÏßb²˜/éd¤<>^FR-ýþ L"£$}έtÌ%9Û»úŬs–Œ²•¾»?Wˆ#ÛuZ¶ˆ}™°/B¯ûT”-Æ©,Y5X«UUcl¢(BÌ™*´Ç­¾ïr~ùÚoÍR`†K²„èTÁ%Ú¬ ­ƒ¦äIOʽ’ ~øQoD¢íAA‚¾nP  LCeeiöÀE èÎJÚ.Ãß1ÓlEŒÊ™†Qo…M8›ð ÅZKyVCu ¦ØÛb§b¢*¼¾ ½ÅÂÂenVß.úeè!éyk€G¡À´Ÿ„ù’¯ùüSã]µ¼ï}ï#¥ôiWã=ñÆ7bÞö6ª}û°UIrB{ÿ½ÔŸ¸ƒäQQBo0VÕnµø£÷`ª¬+`QÅΩÊ:ï™èzZÁz5ÄúZ–®Tׄ²ïuÛ;0œ”`î/Uíöº-³èˆÉð’o½ŠÄ=÷MHFFiäÐ ž]h*æmÑÁ±g±[ÛQ¹áéò)÷Ó ²ßÝÔÎ䙼1Y"ÜtÏÓœ Ÿ ºB2 ¨ý*‹äï 2Båîø~ÿNÉÿ‘¤ÍGtªÀ9ÙÞ ¬Òí3ƒ´J´ì‘ë©æk×ÿ‚Wx3O~Ä£;+½¦¬öz:±Û‘ÖßBÁ²…HI¹$T–ån¯h†÷^6LìŽéšýuÄ4)­ä}=W)ï3ùkõ\ `]\è¾à¾zÛ·ô寷†‹ù±{_ƒŒ(ëTò@½o±¿Âœ.ä¹JƬ‹ã£þ Ãa¹›Ÿüô^Âð䃟ÈjÕÁ4§IçDÅG°: &*æ›A$!½æ°X‹±†¢´8opë8A½õ s잊²®ˆ'7ÀgÏ“-Æj¼ËÌŒzsysA€DUâ%@ª!… Éï!L÷2ß›‡ÎÅ_ñ8ö~Ù—±ñŒgàöïÿü×½îu„8rä¿ôK¿ôa ñØ1f×_OÚÜÄ:‡+Š^í¶S¾ueÙ+ëïèb¤vë]V½µƒjmç-Ð)Ûö°]–,KDB^ÝþŸÿ…Èfùåÿ»åžã-ø8¨ÜvšRièý&ì /Õ1 d ÝþÜ5›,ãŽ'k#ÆD¬‰ ymmÀÙˆ±ÙµÎvǦѱÙGd¼½¤–~Pê˜Q xä6oK§1mqHrÙfב’'&Ý'ârÈ$o§‘#••Aó¨Ûî5â\ïä,Ä(˜tâx£L–áu|ý×zžp¥e4‚Ÿ¹p¬·¸=Ím—dË\ìqÇûVßI¶ŽŽ%`#£÷“”¶}¾Å©÷!rbSÃ÷¿kî~|–°‘PËRWýÂès†ËìÂ#àíÎK]ßy2ôª'þ…5 Ž/þ"Ç žovŽŒv÷œµg$RDòµÛÝãÞcÊ3©4B°w­obëÃ×c6gLÏ:@:z”Ù‡?@}Ýu´½‰rmr:!Þw/H\\,+ºwb IîŠÀªÆkÖ7¨žðª+®À>¬ÅÆàÎ=—òqcrÕUØ}ûvCXŸËUX÷Þ¯v¯y¼ïƒ€®ýHC0A¶ªÍ ‘1®“¶c½lÂ覊KL#LY™;v÷µ 8Û*H¸&ƒEÀÚ€ukPzÀè€$ƒ1©Ÿ½vÀar½«×Ž2“Ϥm‘COꦕR‰dIÉgÑí RrÄTbAŒ!–úžH®ýwÊ@ÄÉ ÂÚ |~¤qâe¦°¢ÚFY¸ð‘‡=öx¾óå–—þ/pèàçn±Ç}GÕ³é'þá}ú›}àÉ6E(¢!èóNyxlfe¤;&;G;ÍRèqéLfQÒ¿oÚËÿ¨›‰Q°ÖsÞ9– ÏWVù£?hxÖé¡çœ=8ü³,)'<ðñøqµbp™Ï@ûÁ´Ýn#¯E?p¿?v}ý“²Ø‡ùò›ó^ûz¸óz9l‚IÈòÒQgÊ‘!ÏÌÛîºÍM8vû JØ­“¥Üx V—Ô—Ü‹z•«›:Êy×ÀáZœ @l›0V}œMÿ¼c(²Ä@ºçCÈÂŒ@dn’.T#CKÅf1+dØŽ©@¢Íâ3€TÄ”K=)ˆâhMA0ž€'Zí½Pm$²ä|—s+G–SÏòêÙ“1:?ù¯á«Ÿ œó¹qM¾ëŸàú[õÔüôàãwB¤]ȯ»&;pË‚tláL…q;D¯v¬•suçFrþ®Ó ë@&Z=G&ßK’"?õoàœƒð5ÏóÏfwÙ‡Ïòšß€÷}Lo†·ÿ4it“¸îFIP†Ì4Üóq¸éz¶yzgcÍ 6Woùµ‹°½…éàë|8ÿìs8¸oªâε™yäP• Kà!XtÁDó¼Ë!¬QèªÏdÊhl3Õ"© eeÀ‹Ä &±” $¹DG‚€2–`´L4H.5¥–Ú‚õ’TcäNt–ÛkP9–õ¾è*8¸~øëá¹O|x^—¯}¼ç&øÀpÛ‘U×dfjÒ1´È.¶I|˜R +ö¯bfɇc§ )ôøÄ«³~ºÛ›3¿óûw¶çòGx°‰s´ìݵBÇÄ\ݳ¸mlÌLcÌ>rËŒ ÃÍR{(>Æy›*€$™>¢€â38RT ˆÑc© ’ šG (pÄäÖÓ¢ÝÊ­+zvR»ŠÖÔ®¢ñ%!ëW%¯šV½?û²½mNM=þ0üÌ7Á—^ ÕC÷Ú<6ƒwÝ ?ô[pó‘ûÏôGƒm_lЙa-iAõå°YÚ£«‚Ò¿1ƒ°åèÑËÊ —Ãа™KŸû²gKŸ{¾:½ó31vP-–ñ92Û/ûev30ø•ï„óÏ‚g>®í‚Å.€ü3/q;¼ùm|çÇàÆû¥Ë[¿ý(ÜtΘš>tÓÿOE dÕû}r1ÒóEì×;lRžÿœû2ëP¹c4‚aÄ>…¯ÈØÚ|ÁÈtdÕ•ªÀaÖCXKˆDÓ'Ö5”剡@’!І¯Rˆn·F™IGcK¢q@‚ñ4¶¤ö­+¨‹Šº¬hÊ’à½ê9»(6ž¼ô ð o¼ü¡u}^{/üòG¶ ¿w½YØf¼Å’ê¬àbÄÅ„í×)ï6%\Òµínß!]òZ÷Ëôr¿µº6–hUW¬×¸rNÑYo¬®Lãâ•åûÓäοæ 8¾ûñð´swAc@>ÍKÞ?Óæ£ëO¯þ`  [-lÎCï¡!Î0?–ˆ4ðîÛášêÌjhgöÉXôG%±§Ç‚reé9S‡÷ð‡ÆÀÆš~æïúæë1N˜T-\pr€ô¥’Ën}Kï?.Q†ƒˆés Z“A%ef’ )jõ•$£IõèµK|$¶”l IlݾÚWD\ ­/¨ËŠ­ÉMQ2ŸN˜O&½fU*ì‚Öäz çTð–§ —”†Ÿ% ˆÌ…·Þùå%šx º¨úFǾç¡Í2Aå=\©êš¢nñm h[жÕ\Zð1èv  a%oçòæ@X­†¼Üÿ°Ðt™Gù<„l)×ѹP¢wý}ת‰¼€¿*hËBeÝý ©ßˇŒAFÀÆÄÙE *,ßq‰ãeÂã&f@väS_~¹ œlRüÂ5“fމ24ý, '?.lþÉýªúžû÷Ý÷ CKŒïdˆëvÞvÉ o§¤U8´ê‘–ÖË–±ÛÞh1½oïœ/}Ö­L&-/ùê.…²–r ²Ðî{%F w9IÚBŸ ¡“¬Èô Zš£'E=€hgo0^u’’í·£¨ Ÿ$C@D¢¡±¥*»&K]T4…æKê²bVM Ö3›N™M§Ô“ŠÍ½ëÌ6¦´“‚vª"‡ÁGUÅ}ñAÇWì-ø¶FµÛÿkkÆ<ÞxOË›5W¦(™SLŠY‹Ÿ|(7ÊYCµUSÍjж¥œ7 ±Å7ê+³ .F5%ëXZ°Ñ± +ia{|9™‘°È¢;d‚ Tv×D·Ý±Ä ÉØ8’QO›¶TUÞfRÒ–ú¼™–ú˜è#L<¡TÅcq›“V…(Åhîl'¼ò Æ{~´ô»² ;± á8óþZþ5îç=laD¸ek 3ŸÀ¤ž“0$ã'`s^qôÏŽüÆ)âÉD¸m~úÝ Nt¦‹Aw9Ú®Ïá]Q½Œø¨¾Þž!ý±üow<ºó8Ú?rOËÓ•ÿ̹Ä%ë¹ù©×¼çœÂõå±ýÕ7¢%Ë?É(¡Þ5f³éšç’í…#%çAˆ¦Ï‰(ñ½œE qI2¾ §`"ÊFˆð´¦@‚QuWS ÑPÁi¸«.+e&Æ)x”æÚÜ·N=©˜­OÙÜ¿Îlß”TZl™z[à uÂyÀk9=Txì§õÚ=EÃ{ØäWÛ{¸is“9"4®d«\#«Ì T§jÖŽmQÎ3hœªñ1PmÕM«àW7 1àÛÐ…¡ —´ˆÂÅØƒ…M¹ "³Ž¾h\¶*²MŒ@F×E2¶ß×m'l/Ó1‘ÌF:fâr1„_Œ¥©J¢×ךiI(•Ôëóµ ͤd¾oB³Vb¼jˆY¯VeT¶fR‚³<9Ëçÿ‚9ÌÃ^&8Ì.€|¾ÈíÜÈ1¹Áp‚o1×b…z%mKÀéÔ:n~×~î»e;þÀsÏÛOCºÙx®f1>—ˆúÜèP‡¹0:%YÖ>È&s®‘›¹%l"­¡‰%MRm©8ÓïÅÌ\p!2=1crJåÿË­¦O•³¦†²i”I¥€‹Z®íD_3Fz¿c¥gU¤íe «äLŸ.|¥µ‚¶qö`’ó!’Ìâ•{ï¶;ðHÆÒ”e:Í´Ôè@QЬ•*?-™ï™¨¨ea0Q ö‘ª±/Þœ‹º6*:ùR®d?.å 6Ø· ŸëÒȽÜÜþÄèÑqŸ½-§R®Ð‡˜"Š£™—4ó’¶.˜×¿÷ú'sÛõ¸çÚ5N~¢`eỬËáÆk#›ñ]¿Af>ƒ„#—f×;+ÚÅî:÷»qÈÊ,†ƒN Û:–YtOËÂpR)yÐ6)©æNÈÀTÀŽˆöF„¬GLÖ"Z–…‡Kq/—>ònžó¬kùžïºf5à­(ë”Ñç“ÔUeöuâvÉô`Ñ?¢Íª¬ºÝ©²¦¸&Áö9‚ˆäïÒ±‰¦qEQs¢5ŸÒ%)j˜d>h¸kR1Û˜êV¤Ò!Ô?QuÜ¢j)¦-…oY¯6¹ <ÄÙÕ„î(6ªá×ûƒ”<~åµû€üg6à „Pp¬ÜGÝTÜ<¿“Í6ö×i Žz«"Æ ”µêN™Z•hmJLNÍ)Ú+‰rÞô¹‹¢i(bfVúœ†±Ò;[£@aŒênõÛ2 a2(¬t~Ü¡6dY;¬›ÀõÀ’¤+ûîÂ]Iì J)ÙÖ6¿Þú¢µe¡ì3‡´VÃYÓRÿWzx b ýîŤÅW_ÊiC5©{ÑÉ·\ÄaöPr>¯`ƒ§îÈÃ@îø ,ÌxSû.šão  j¢S·JSl¾¹‹D±´uÉlV±¹µN3«h·*ÞqíÓhë‚ÿü+_˽÷íÛ>âÑrV+˜"æGÞödàH D’3˜Ì>’µ= £Ö¥½·„5Z¦h¤‚Vªœ¯Pª]%‘V Ü™uXQõOÕ¡­c!& „ÜÉE${,HkuÝ8Rã dÑ¿´=Æöÿþî«q>òeÏû kÓæ  Õ%Ù—ó56PêÖYû!æ}Y/hÐÕŠ ~°è͇ `“Ù brÊJ:æ‚릯î* µRÛ{pKRéN‹Šêµ7™Îu6ëÕ¤¦,œe‹/‚V¼å0P š¶$FUtnê¼½5!´ ~ÍLÙRŠ–<ƈ†­r¿‘i¥Cu‹5Ê |ÔûÅIÎct@Á8XýûqÕ*,‚†éfõìYMVW¤Çúhc¶QÁ$‘÷ ‚ AúÐļR&!Q“ô_=& H̯ 97“gÓY%«1‚³Qg¹6â\ÔË¥ÞÍà–ã‡ù¹÷~wî{1YÁÖ ³ï8ÌÄ%7ÔI2y*!}ˆÐä2òŽ ¼ø’¿à«.{ç ÐkNEÿòv¥š<¡Á¢ÛF½fL_ìa ;Œ5ø™Ç>B®"‹b‘ýþsæ#KO–Å'—';ÏC7aˆC­ß7:¦?‡ù}BÌ× 1&£sØÆ‘ê² çz,dÙ‰¢ý®¦û-¬ Q¬'8E¸û¶Þû~̼Ŷ`“Á›³qÇ7 iÿÙ”^Havô(õ‰¸óÏÇ]x!þÒKY»òJÖŸþtü¹çbœû¬Ë›ú³k®¹¦Wã_y<0ç‹x>_yîÅüö¿„×õ"¶‹zÈᦛ`óQÜôñ+xëÝÊÝi?o9ry µK³Ti4š9‰9]†º×y’8TúÀ­ý±þÀÁ~ÜÁŠâ1guêb-—ó›ó¦û>¦c%ËmÝ¢1PNó¼ L•Œ$]Á$Õà²)f‹OL\" lLH£Iv©¤LIµ%Õi nyb]’ZÏ©­½ÜðQÃSŸñ¾ñ¥s®x|Ë‹¾Òòô§=6vø~;)áîÐþ²8=ˆí´d°¨Š+£mÁGbc‚‘×ÄÀªÞô[‘›?¦ŠÀ?÷2k»œ”„ÇלI¹×&õ’0}¹w"2‹§zÜÝßͨ3[9Ùìçd3„`ßúÁKy뇞Óÿý÷¼ü(çŠ †G?ÚðŠ—»í§d¬˜ßiûbGô²¾ù¶ó%‹$Kþ, ‹•“Ôåe\)­Ë –ŽjÆ놱Å`ñž#Ì?|õ#?‚‰I‹)Á¶((;÷JÀÖ5Óºf2*†Ä9Ò|N8qöÙðY‡mKÈ«b0W^yˆ—¿üJ~äGžIY?ê‰ 7Üp”ïý¾? G¨¹å–C¬Ëdq#] É…x¶Ï’ÍNÍãQzxÝT»· |âAÜãÏ&M Ìš'Ù¬ks’0_”ÉØÁhh\/ºAót 2¶7¹+û95bSÊ¡¬˜¸”4¡Þj¼¼s¦s)i(«5¸˜”4 ÕÒxh-qkBª Ò¼"̧„zBL>W›ÁEÃÓ¾Àò‹?o8x@mQîËlÇŽëö¯ÿ¼åõš¸ñ&áÄfì Löº0ÉäÜD–±ã²dŒ Œ hUß q©¾£?Ù^¿“}Ñ’ç,‡Ÿ5ÆC¡†t9Œl°o\v©ÚË^ ßü°6…}{Ù]>Ï–ÏÙàÕ«žÅë^÷<ÞñŽÛ¸ùc'xó›?ÊŸÿÅ‹`±-Y²p˜EóŸÓN™–ÀìÊRË"Kg‚Eé¶»l/þ©çàž}¸×þéDÆÈX¬HÌifr;•Ð’ìVÒ $lf N2éØHÔ“— ¦\ ÐZL0¸‘Æa:6R—ÐXL€8›h(«ö„Ù±VÕÜ6´¢Õ0ß~¼ðÙðܧ=/E?UÄéõ'Ãyé–/y:|ë×ë¿ø’'Ãã.Ý\wä! ÿv唺( _ñ—ñOï?É'îjs\6?ŒY ãP•Œ‡ìÄ@vÈ+˜åæÀ˜ÈÈgBº×GeD½Ý™†2Ü€Å^EZ«Àš¡Þ%²ìp·#‘¥Pù*_É¢ sK®ÆI¢ D4Áì$åp–à%`‚n;‰Ðh.Äň´ÛІ¶êÀ¶ç4G˜M¡UqÃ6„äi¥ –J¥FŒåðyð¤+à÷~BSI‡å×ßoyÜr|ø¦áT;‰xiQùg²¼>A+|²Ä¾±‚31³ Á¸ýV”…H–W_(•]¶Þ“tÒIì¶vìç’×ÞÇ<ƒE®?¦£Ìûúb Ox4<âxÙs᛿ìóc ý…7Ã;?ÀvÕ¡Óød=ë ð£ß´ Ÿ%™®¹ˆâpk‹áª4ŠU.Y¤®ç?ÌêDß¶È2Pd6b–ó$9ÉgGÒÕ¢Jìš°Ï»ûå‡áiç DF–LÛ’Ì«Lv QKû»ð•M˜w Ä$ÁIP ‰ ,& .&œlPp0&Ö} HëðQ_OÇÇ„ fU⊳‰†¸ÄÒ¦´R0—‰ šŠ™QÙèßóeðògÂsõк>c‚k>¢Û/lÎèe=ŠÔ2Is tí x(L«ÜFe@Œ±Û±‹ :RIÆôªÇ]wù\wùÓ;=:ŒHß½oºNþìKÞW ur19ÖEÛ«G-…>lÁÜN1ð‚«àû¿mÀ3.~x˜ò­øÄð/߸Pè#Ç"‘ Í’KÊÂÝ㊋ ÿá媗ö¼ËwäŸ@v¢Ý í :ìú¾JfEèj@Fá«…ÖN³ü1iT‘÷÷¡+¶H6êI]ÊlT’:qØ\¨zï…«Ÿþðsæþ÷wê}õkïÑ‚,øT,©.XµÓKÀ‰ž?'qˆ£ £}CÁúÞ—&ËÚºãe_`( øÅ/ÝyõiýãP’[ÂôR°UöQv‘i,ls"‹a•ìgA$p†(yEÓ—žm `0é^ëJN0ß~ò‚ÃpùžEãž1ˆ¬" ÛÒ9‹"‡&ç?¬ä˜¼Äü<ö]È6¥¾ÑÌ%u6´1Ë\ˆ„ÕP2в²«¡H ¦5˜ÆP¤Vkâ[GÛ,¨¹“6˯[IÔ¦¢¦"a9Ul°é×™NNö°±¯â9~ðrÓ§|š¥v^niàh€_û8üÞm‘£'“fÎÞù ¦ÍŒIœ³Ñž¢–"µTRkxJ…¨0Ÿ7²czÐ耠ßÎýôƒ±)›ðÙ¾9OÆ‚• bFs˜ ¤ ô „¤ ‘Äö ‹2º¦"›‚ SD;ò)0"*0i+mε3§`²U¬1sSfÅ”­j S:îqìÞôxT ûÝCgŒyÿLˆþŵpצÒÊ{+Ûž63Öš­abj¼ ª•ܽ„^=Ø *ÄÙI¨xâŒÆõvÁxõ¤éÀÖ{Î9Ëó±¼øÝÇÉÉN­mpjcƒºh¯.àî3'f×?[GÞzL¸ñ茪®Ù¿yŒý[ǘ†{ç'(¢Šî­Å- iûÅ‹&ÈÅœ‰}(Ã’ú™ªA2»Ðó’ú†Rúðh/qne»ï f‰©ZIˆØn!‡²Ðp¨DIÛ«æv¬¤ iYI}’ÝJRGGS`5ãʹ«-¿ÆÜMh\É©É'&{Ù,×ÙZ[c>ð g{³/r†§}–4kà盀 ‰Ÿº×Òa²5§šÕLë{6O2 sÖ›M¦aFaZ]‹vð—©éÃSN"­-ús9÷õ˜±žy1é/k¯­¾ÖجÏå\opÁºãÛÎ-xåÔsŽ1»òé×°sÿƒ¬f#n ÖŸ¦FkõB~+€d%€¬È”m aí fÄ@Ì@l?%T ±¹1ª;®kt“Q3Z¸l/Å‹/¤|å£(Λœ?X®`h5 ·»MY¶NëoL~ØÎr£µÏƒã úÜç™·M‘"†^„¯E =˜t!“U×”lf4‘ÿ½÷·íªë½?£Ì²ÖÞûÔôJRH#€„"1ˆ ðâëµb¹zÅîõZ(ÞkŸ_õzÕ‹½ðZÐkŠ JLH äHêIrÚÞkÍ9Gyÿø9æ\k¯}NBMð¬ó¬gUö>{Í1çøŽ_ûü:ŠLwÝ2ÓLZ=2ÙEkJfõ„ƒ»Ná¾]û8Ûh­-?¨NcƒòãB¹Ñq[œóCáfªâ}c×Ñ#ì;|S·ÅÞ­û™t3ŠÐ±ÞƒelŪRZDqEõP$øŸ" >#u: èíøúî{*H•êÌÕq*rÁ¥Ê€Ã8‡ÞúÓ,féÝ™1ýœ >#EL—c/HNIŒDÇ@cªXß²S ºk˱z-=enkoì–ù³%]]pfi9S{ž£Öù"v³‡ú¶Ž8Gi¸Ç…»˜SðÏ íMë™Î¶Øuø“nƤ™±6ߤÐX±ÜŒo$n¥e3å´ÍÙ‘©„¹e fV,±Ö”Ì‹Á­7·u¯ ^‰‹°Çìk®PçE“Š]ªã[ØÏ£™²FyR@>> ?;³ ª³¡8\tØA@v(dÛÑY½X豌,=²>Æ’Ç£xˆY * B×@ÒhƒâìŸx4ûž²õKÖ¶ ÈR²ÙØk—s ’xÐ["ø‘¨,rÞE\:4…CãÐtùnc'®¬Ñ£-&t±¥ˆG>&xñ){é1QAgÁÁ†;e1Ñ ñ¶¬!¬žph}ô~Hþx ÏåbÎTk\ .d/û>:—Fø'þ6àãAi²elÙ}ô0kn“*6ìšAë÷í•ɯW&[Y(´Éâà•ºë)“-‹~;øÐ—»ó ©@æR=‹=?f´:1–}â„<ö쫜Î$ôsÑ&F•Ý™Aéü;œ–9htœwVç fzÂѵ ɲÓM-Xü¨ªˆ¬)Å6Wbµãj®E}œðè÷sóAnó[ü¡¿Y2þZ+éçÎSÌ;ŠØ±6Ûd:Û¢Ðu;§ Ö8&n†±Â++c têßš 2–¹«cVL˜ÙIŒ¹­i)ic)G?Ïi3‘\™ì­"-éÜ ézS>‡ ¸‚ÏÀ|ŠkÁæPv*ð[ X¨–óGaë¨Z˜\Õ;9’G?ªÚí8€®vÊnZÊÂZˆ/Œ,Ý KHÆ£`ºIck¤¸‡8ˆ‰KŸQŠøZä#/¿£—ïâ9òT{ìŽH—¹ŒtS^ËLrpt~Eõgx‚)tzfP4E¦EcѪD©.=whZ MM?ei(úà#œacKÉEœKÜÀw)#,dwP_GÑÒ%°ÏtqÑâ;Ãþ‚#…³Ùk¦XÓ±?Þ‹UCÅ~õú…é{ÙËþÜÑ,¼vs¼…àû΀oøñ¿Bë@IËšÚ¤¨;*ʪ“ü߈(è$`ª (÷ym²P­óûý=`ðʰ A™<Ž)=*MÊ£‡¤ïHaopbÿéI"Ño4^Ü•8ãÐÉzêƒÃ9þ5reöTÞ ]Œëð)ëË#wßæºfÆ„ÎIöV·Uà½É}oBм·ükʲe®/¡®Ze¾’½ÕJq¿æ@÷Ü=k¸ÝßM3«xŒKpÅN‹øûN,dÝ1ig”ºE›@]Î3¶½¢A•[¾]Xvä–ÙÒÐâ²Û´»™Ï+æ[–ùf-)Ј–¶ƒeWTL¡•ß­ô1N¸hZ Óa£¤åtD.â®g?Ï8i|tÈ.m«—ÓV—K¬ÇKiŠ1T@ý8ˆÅ A-¥ãªúe×ÕèBÕKB¢ãvˤ·4ÆcÂâØŽêD̨ØÐÄØ ˆOÿ·KNz4šG?ï4÷e§sù3vm7¢–Æ1 H_ÍÜ/2d‹„œûÕ}²JÈVˆduèÔ}JÓfËÅÐd—˜e–©ËÃÐb˜!ô9[Z fy\²IÁ–9%Ç(ؤLï:‚W„Nî1ÀmNáß{¡ïTä;¾ýë¸ëî½C£®…„¼¸Ú¨Ý±—œ/gœ~¯{ýëR¡]%O»þ#P”xJ5ŽO…§H–@‰£DœF+–ÅH4úײ€Œî rÜ[AÑÃ’«²Í'—¥KsÙ}*#l²…iiÑtZ,s –Ël4_3£àÐÁC$´ŠØ‚óßi| Þk¼SÄNc”æ^^õ>öRWsʲñ6-kG7Ágü<ØÓ!ƒ;^"߸Э7ØÜ\ÃyË|.˜}¢–µȺÆzÙT耱«„ ­mÄèˆ*ز|UD¢Õ`5^[µÆŒ=4l°Å)´ì¡a7›Ý^ü;þ•æ–û𥴎à[T® h±Zk(&P}'­ô1^Ħ̼ÖHÿ#¥m)T‡öæ01Ϥœ~Ø3aÿgœ& ?tK„¤#çêR¨¯]Œã Èq9u#‘Èb± éEÃ$!3#kÄôÂ’Æ}­ˆÚ¡j‡fO:ÛôÑFÁ\S–'=ïTžû²ý\pUµ zqÅXr‡QÃìñ˜äÞñùuƒËÇWãZué5ÙÊX$ˆ˜´0)BZ˜Ú4žeQ*ØL‹WGÁ&†KCÉ1ùÞó}ß÷xî¹·øÀ­§ó—o¿bhØ¥G`??'ìè{§dIc¯AqœæE/ý¬ÕìÛçù®WÀ'¡xiü’Däq/Š˜j.p=o’b~Ô£>úØéã¹ætØ øüžIâÑÏJ™‹˜ED0tšô¾ËËKƒÂaã[ð:7$›nxÞtòØybçåôîB"GtôDŸj“¢€–>,3A¨ÁZþRŠD²ÆVÞSF 9X+T¡QVɽ0`-X …£åya¥ ¹´` h75A[%svã¨é˜0g/‘)mÜ ù·»à·ŸîC÷R˜@]w(-âQm4UG9m¥ïPän¤€Té˜Ùõ®Ç¾‡ÁgRñ@4À¾gÁ¸Éeð´çcÏ;豈l§ñN€W¬µÂm¥VX#ãE¨.â2Ч,5XZŽ:ÁÈm–Í‚p°ÔË|$½UbFˆef™‘€,‹‰J–I…³£ ¨—þ¹ð¨p ¶ vMJ~á÷Îæ¼s û÷ëí =G Ϊ˜RÜAdX°\†F;-XäÝn?&/.íœ#& J¥kb4Hœå¦#³­–û±ýüí;'`=w®ð 9>ErûõM»²hÄmq¡D¡W #‰I@|²d;…‰ŠSö;h O¼Öó-ß>'ÍYgiN;ÃŽŽâÐu¯W´À Èg’æ¶znÇ~ÉZÇÅHdÈ~lF™/ùÓŽ&øÅ…ß·™pì‡D‘Î)ì=7Ž~.ÄExeþb#*îB* ?©1[zÝhy½§ ›46j #ðRQIÿGÐ6ÝGŽ\gЦÄœãõwð¿þ;p÷Lª@]¶PI «£”¦òhÜ‚E¼¼÷·žöÃ=öãb q¡«znº‹fcGT‰~äÅl\=ÏzöÔSÿãÄ@v¢ñ®^Ô²ìÚRÙ—Os47Ãô™`ÉBåùx›®V%~ÅÕ)±j$ËÏ\X s;zϤ…oAlz×Öhìb'ŽÌX¢Jž‚‚Úrdnø’gßËç=cç|ö„¯ý*s‚ØÒ*ËM-ÅW-Æ~s|Ÿ]ÑÿŽ×ýtÇý›ž_üUÏmw9¨Ó§¦c£”½8§ããÐo~ù”ÙÓR;£Äã‡ß·õ% v”îˆ8÷Š»|Aóûo5üþ_h˜žù´‚'?Áò„ÇZž}½9ΜhŽ>6!y`ŸY%Yq‡ù\©mq?NLA^b³õoý[Ï_¼e”­¸¼IÛæV^šä‘W!FÅ©§h¾ñìöÏ«¥c­¶'Ì åÈ ›¯)Hwá‘Oaþ‚ýl½ï=lÝp󦥨³x÷Ýøn4P‚÷ꞌÏ" Áß4“çC„PTèý§¢Î8u꩘ /¤¼ê*Ö/»ŒZK‡F³±žNOº°à•ìLÌ]^W‘t㠹诀ú³Pö’Åb!ú¼âúûÎǹú ­gÓÉnF"bFÖÈò£ÅDì(.ÒM¬‘Þrq#+§e•m²3n,­˜ºšG]dxÝ(žüxõ°˜ûždûü—:<ï»ÙÓ˜& µ—G¡ôñ¶iû,ެ•kqdÇ&ãÍÄøÜ£FâKcÞ‹I›,g`.Ý™œ¶^rÞé†'†â»_®(,œ²ÿ·»Šðæ¿„×½>fÚ06pç=ÜP6J›ç±E™3—çk”fاë;×…æŠË ÑkT˜ÙU—+^ýƒÃ|*gœö±}/ø0þþû‰!`&âlFwàÝí·Sœr xÏÖßÿ=›ïxtÅú:îŽ;h?ò‘,ª!eÛ•çŸÏäšk˜^{-Õ%—@U k ª®ÑÓ)º®ÑèÉä¤ k•€(õªTe«#ãU=îàæ Û‚ëåô³©‹s‡ÔÇÞÌß"i• p8JµìS1ó8us“΃©ë AD™¸x·#+ÃŒÆ6]4½{¦‹˜dÒÛ‘€˜än›Yù®­óœbO©ø‘ïT<ûÉpÞ™Í9ÿ§ƒwþKäíï‰üÒ#ªP|L;  rÃ"’ZfA‹Fp|þ©Gñ°¸ jx?Œ„Û«ATº´›è´F ošfºòz§¸èløŽ¯W¬O/~Χ¿hüùÛ"·Þ.Áìïý‘CGBjÑ#Èh”X×…—tWˆý9ÞwoØV Hr/ªQÌJõóã“°û!)¢o‹‡ªTüä©\ÿò„G+®¾„“·‡µ€¨ ¶~ÁéX:¾+KVŽU‚€hUrÊúUl§n÷ñÇUÝ@Ô€XOEb‘ÅÞ9Ç?™’AKÕi~n4Áj‚‘"¹P(¹xl‰ÊHPŠô\¥qG)‚l›<2Ž#ï·+!qwÍ´Šk/‡Ï"ü÷—>´æûk,ð÷ï Üx[DP(¨±Wi’ Ê0¸JLDC-‰F‰AL¨›m]ðT.Ð[P—þó°:éRߌ8,F*‹”R"$.‡ó57Dðhˆ^Q[Í3Æh~÷êÓjáù­¿ŒüúŸ´ò¼ûý‘»ï•À1Z²bß*WE¼Ñ(RçNÒÆJºt**ã{ä˲+2ª…Ø•ˆÌ‡êc N¬¢´ö ãÔÞ9x²è5ºHqÁÙ’¯öª¯V\uáIyØ ˆR&§ˆ€§äÞ%1‰«Äc©ÇG^QØÁ‘ðØ#wŸÇ™“A@âàÛíw$q©˜k(ô„$[ , Ȳ˜ô‚â­ÁY!Ï:kå^X\iˆVKÄBÉUŒ\^Ű;£ˆC–:+»^^kTnW;Å7>^øÅS?EÅCð¾^ðš¡Ã*G4R\FµPGœÕ" uj”\Jµ5Áúèx¿Ã8¾ ‡˜×øõчõ(fÖÿÿ©ªŸ\'jäÖR ‹iÁx/wç1Îl´ø ¸ÿò¹šÏºÊpéišGžúð¹fÜ/súž^ýÛÂîU*ч•ˆEÿ˜BC‹g¥ðZ£l •-õ¬xt”Œ´œ:ßo󻪡G·¤l9ÒØë4Ñ×! |L ÔB¶Ftq¯‚pÀú^)ßò–§^.ë.V¬W'ä¡- z®ó_EèD@¢ßéü<¤"¡í¢Yµ¥FHö\buäš=»8wj,m^ó%ñè­’ ‡Ìše‰JªLs²1ò<‰‰³– µ‡±xkèÊ_È£«,]UàK¯ ®«…2ù„‹ÞÅ•@|ñ¿#jj¥”´¦¥ëû¦š/¼Êò=OTœÿIì2÷ão÷¼ùÆŽwÜ NŠÙpB{Õ>à‚•ÖÁQѪ’Çœo¹îbË+¯{hçÀüß[|“ãCw¶¼ýTºD)ZaµË×Ö§mŠ Î£o¤æ´Òu#Ç3˜Þ5SŠ.Û:Øn Qrå=~(·R^¡£4G#ñ€@ÆêÈgdœÑ-AHŽ˜t8„ªûÜÇ•¬O-ß|­áÒý꤀<$ÄL8åòdtŠèã &µï¡M­:£^–ÜYzÅÊ!ÛU«"µ |Á™-{¬[¹KÍñÑã²[+ô9þZDdALÛ)˜DŸ²bD¥èlA0"*]YˆuRX\Õ[%–vRÒU"*íTØBíZ¯Åb U²VÐy—G€ŸÖ²s/šŽªkr¿‡‹w+~é©%ÖšÝn»m“{؊Ÿè6,k5~ôPMüïMäïw|ÏÛ79z´×RÒâŒÅh/ßÙÄB |ÎZ\™¨¦…"óÁÔ £ö*9¨í\1õ'_Â¥åbi®:mTnæ„RÄm.ã0{Ouú[Œü„Âzî¥o±Î¡|¤t-Æ ¬ðh)rh 6vOñ¶ä7¯+9·Öì·ŸÚÅêƒóȱÖñó7vüÍm›øÍ[­§öóL.6X0BöZð%Q+œ±rmé'‚– ogdÃã•H4R×õp] VjÕ"—E$ó¾B'KÄ/ï{©¬3Ù¤ KÆ1¨Üߥ‡H*/xußj!îîZ/õ„o¼¢â)gÈfðò‰¢ÖŸ>ò°E™(Å:¡“´ï¤WwtÓŠ[Ë· ßj|§^:¯­¶FVU’y@ábä˜óüù]ðü3ïãŒj¾´<ª!s‰‚Y }nÚuõÒ½6 ç‘ÝMPR“ƒà1:_dÖ“Ó–4],èTsç,m,q¥ m,é&ͤ¢­KÜÄÊ}j‰E²>tD»À¤™Qµ" k~“{5<á[îç§\Rýé#¼ëÝ÷.£UpqÇÇéÔðßqE~þwW¬ó¡³GÙ»Kc‘†I­-å±(Q6â¬ÅXOÈ^JŠÂú §ÊEt¤±Uç幋(Rë]áXéÐ^.|åc^Æâ±Üh!9"¹R‚I›€d5F›\–V‰»Åj‚UÄBIl«Ð"â*]y Tð˜ Oá: ×a£p•kò‚Vº6Ö;:S0·5øü6xÆ™ë\±«ä©uÉ“ËO.ýÿl6Ü7ŸóûwmqÏ=÷acº>£œ´ìUZHµ)ö§U 3RÜ”΢ጜÏѨÜ4¬H …X\Zi‚† X š¬R,dù\X¦1eÿMŸT¾7½(ô}nt¹Ï‡Êm DX¬wI|Äõ¨ƒ kLJkU)pIc™~ævÍ߷ƱÉ:_sVÉîºäE“’G˜‡¿uò°µ@´pîg½*¹¯dá[Eôˆt­&& Äuß|gq­%t²ð²˜ô73rgÅ$°·høÖG¼›ýåÖb¼ZÇ‘˜ÄALÆÉú×z‘ñÆdËÅ[34¡±6 Œ+„øé ¥q¥¸²‚ÖbLJ‚14k%í¤Ä—†f£¢›´Ó’fwÅ|w›Z܆ŭ[t0wnR¹†»¿æÃÄû8hnš¥ óéÑ;õKYÕâwa‹/w{FI¹G£ƒÇ¬k®úɚΨs*¼‘ž ­dÁ4‰^ê ÁièÀ̦ñ˜&`æ;s˜Îcçò¨»€iåÂ×]@w©5¯K’Úöª°èž\ȸëçT‘w˽# ¼`u~J± C¡ñ¥‘{%wW[B©qSC(5Ê C›€Õ.càK×Rú6Ã+×äÅ«ð¸u÷ètƒyY´fßdÂEõ”W[I©Ûû ÚvŽÑòñnšæw>„k[Öçǘ43"ŠÊ5rn'úp§‹lQ·¶ÌÚÎö¼5N§sXÛL§Í%¥ʈ’;rJ¼3—AÆbX •JW­J¥›±oÓ¤]Aâze¨g¢L±[<ÚKÇM$Wø.ompÒãÃè˜Õ¶ê)Q+6ë5ÎZ[§*K¾ŠÝ<‰š –úa¸Ÿø H1á¢Ï¥Ä:œ¸"B'c\ÄuR`Ý·6Y#" ®±ø¶Àµ!Øî-3:õ‚53ªC¼üÅÓƒ«-‘ÑxüZ@ü§}`$3k/é$é µ¸¶bñEoeìJ›§«ÅÅÕ ˆ+,¡Ð´ë2î&Í®ŠnRà&–Y]rëÛK”‰|øû¥³"UéF=Wõ>üe!Yè%¿¬1ã¦^KâÑweT£q."‹\úÓ%(Î~ªÇ;ÙD¯ˆ­‚T±[Ózt²h(±s‰hÐm¢Ìº€vâÂÐnh?*M ·§h÷"Ò‹¬ãê$j…/M¶H|iV„DbT)^5•y¡ˆPJ². §‹€)¼0‘ Oa;JZ¬ò”4Ê \/ ½¸+ŠœfÞ%Þš\×þu\ƒ&pÅR|Ô×£åýü#ÃmæO¸"Lç[”m+|¦®ó ¢‘z]tÊâBK‡ÅEé/–µ%xÙôE'Þ‚4!H,3•d*±Q©°Ní›\‘8$Ü¥S<÷šOnGe#Z§»M¨v3ÐÐ(—z× ;Ë’ JzÛ÷pIöÙ?oŠ*y=[õT6I}#0OäL®á NåtÎæü“.¬OŠ kM\X¸˜$ˆ˜x0ÕÅ.âºtR¶à:ðMÄ·Ð6 ×h\gñÎŽœÔft晑#Ý;›ŠŸ¾í™¼æ’7pZyxµ%GB’Â*!%©G¥òI¿pW:÷¤ÎŸJ(¥Q:Â…Ng Gð:Ay-¡Mî.oS\ÅÐ:ÙÝùÂÐÍdw×ÕíÑ’{OùÓ7_€S w½×§:I¾€qøÑ½qàY©eÊö.‡q…€ôá¹w<£àwäÆÿ*?_ÔžC×xŠ¢ãs¿ò6YHÚ”¡äfæ³0˜¹Ï4¦‘]¥J}Ú1[Dë#ÆQûxÜl¬¾OÇ‚+ky¬EÜQd·•×É*) A+|-ÖHÔJ¤H¡)+™dÊ€)¦§­Ç–N¥µÃX‡-e)tÖ¢tEGQv#Øo07ñq rS¦œÃ+ðuv«ÿ¶hhLäCÜŒC’Ižž\²¶pòoºç-³´m–Ö¸Îâ\ºÖ:9w½Óà ×±(\Š DÞufŒÅ°šL­`ž¯¿ IDATç6ÓK’62}éX©*=ßêT_¢µ0©´Š(0ÆK>„õÐ&ÊœX™'[x!ôjOaV;Œ 2/•Ìa¡; >»òtFÃÈøC(ºS¸'žÁ>{ç©—œ´@>Qˆ©&\õ•b(²"\ð­F…-åIôOKì4®µtM‰o º¦¢™ÕtM…w%1ZàÞ¥tšñXúsœZâ.|ÃŽqãsêc\:½/Ÿìù¤ð .®ÞB‰I.PŒHÀ±ÛÑ8¹¾‚ÒÙ* F\[ýg]i‰Qñ·G¯âÏ?pÿzÇY#­L¡I]¥FM¶š…°C·FµÚúX’…V¾,¢(ÆÈ‹8ê›ú×D4>ûñÿƧÝ˹ë÷pfuº,ŠÞªè-#ÊÅÏÐ~h˜4vY©U—ÀèõmîÉÔ!0ê‘uÙgÛ¥Ø ±+=;|¡‰&ùïK#±…ˆG¿ ÙÓ¯Mˆ:¹¶ O41¶t #¶ðUóU-EåÐ6PU‚–·ÖSÕ uÝPŽªn¨Ê5ØÆQêƒç}7_Ì»N¾_Ð<úâ›Ø·÷vÑC6&MSÑ´m[д%]'ãv^â:C×Yš¶$zM×ʦ,E׊u‚ÆwFêAˆ»½uá½N ©!˜ðΖÆÂ.ÆãôèQ‹iXyÿ3²(Õ˜O—÷Nb(V$ R•12VL¢(-s¤Ó{E!¢¶ž²ÂoY¶ÔeKa“ª¡®æLÊ–étÆtº…&âZKÛ–’ f]ŽëÕå )ê/’ï½ï‰PzR@>f©'<ö›D@´—^á¡Ó’«2²´OÒ”„Îäæ1> Hè ]SrìgëðÞrâò–8&ò¹tzÛ5°».¨ïç[Îþ‡…PÀ‚˜ô"ÑÈÂÅ$èôÚXlz7XTDš EFóö­«ù½#OãMw>QR_S&‘¤óŽrQÃÈúèÇ xû%!ÙÖµ‘Õ±ÐqÄ/JÈî ŠìFÿz¹¸ú§¸l÷GøŒÝ7ñõû~g‡0¤$ërºår6NξbEÀ|9Œ—\”zÛR,Š|<¥ÉÅ´xL™["*ä`zn;cRôT4‰(Sah;,dý‚…’^²¨‰˜h#™uEåøïoýV”Ž+=&”ŠùQ)xë?=†o{Äè€Ï¹öï9ïô;…W4!(bÐI4¯xêkèœlHºÖâº4î,ÁI†ë$ñ#D…s&%L¡’ˆ¨üzßv7¦Œ¹^0d}‹nªÁÓù W;ò,œ«z±–§,<£óU›g§MÈŒÚz¡üê€Ió"§$»«,:Jã°ꪡ2ŽJy¦“µí01ý?£¼žF5,!îžò(Ï‘"à]Âó¾ë¤€<Û2×Ö®ýîWFG—BeÄqhSÿæNá;ƒÐj|gñ³Àæý–c‡w}pž.”H a‡`ð̙ͣK¤Tž}…ôÈþ‚ÓnákÏù'öLá¢Ó’)ž„´øå¸@O+ q¸hFDؾ}zLqÿ˜öÍ¶à†ƒûø¶#ßË¿êGpTMF\­~Ë•¸@½hø‘h½È’¨ÿvÌ}\²@Æã‘8,Z#¦OÌ3ÂR1`L´[°1²7c͵üBõ]\¸v/{Ë™Øxj¤[+æMXÿ·ãjÆK|ÅU=cúBw9„jxM©DSï ÊRâ€aKÇ-Žº˜2çn™É1*¢Ž|Ð?‚ÿqß·Žxj»gûV=ÕÎ[vµô‡ÇQEw:N›Ü›Ð",ßsÊq~q€à5»Õ(o‡ì‚¬„Þ‚Pé÷Åñê=™ Éoý¿Õù~K‡¯5r…Ç>U{|n,0TãÂxLÞ^˜£d]«ôL› ¬(¬@ùRT6P )U¤´‹ÆhŠfDV*ˆÅ>| ‰‡Î@µ—°Ùá7[<†ùYg³öò—³öÅ_,á“1¹m£ñ*(×!¸(<5 L"m褹}X7ÁsßÃÁ[aëPàà·=£ó€OÅK”wh£æÎv7?ÿïåçÿý±\~6|ÉŹçnðUÿùÊÕ¿"Œ¶\q¹˜1ñ¯âÈå#ð&Ç›þ¾âç?ü(¨¼PjsŽ@„""Ð>V%Hט^:«UAtFå%ñPÛ/ºLR5+Úúª°ˆ·ï«ÊÇñ'ÿ‰‹Š{ºuîé Ït¿Ë—LßÇç_y/©0ÞÏ[üCX=O«>«öhqÕó´yXª´±ýŽ·¼%ð7oó`=¿uÿSø ?uÀÝLúÞ1ÈcŸ„µà6ì…AmÏ|Pj{]LöÓÉ9pw8S0èÉZxù¡ŸH¨Í…æNž¿÷¯Ák®{ŠáéO×X¼·½ž0µêã1ýq\š»xœ+wÛ¸Ÿû4§ùõóœÒxã(P«ŒAi2m ÊLQ ­E[‹²]–C’'ßãåÃp}GçˆÎ‰·¥ið³¾m鎡;rêšÉÕWcõ¨EÒYíÂ*¦>뵯$:…‰ÄÚ0x ž;…ßôø™æÃï.¸ûFE»óc¨ù;õ>z äx·õõ‚K/ÝÇi§Mù_ÿëz”‚3Ï\{PÿËæ î? ÏýOžßî8ØÌ L€ÁÒ§¬äô{“SZÃÉ"0冻ò+šl…^'v¶@âª>ñ:f EFÙ븈´/‚fId|ªî&A ûÝñ¼`£(¹ä"ÍÏý¤æ‘(v­ó°¿Ýwæ-üÔë#oùÛÀGî Üy¯x¤È`&›°Œ‹á»ãÓjñT]þL¹‘Æñ17²^»‰ì,gî+8ë ͳ> þË×ËÏíÞkNÞ>Mn_Y›ð9?ûJ¢—>Ô±) Ÿd)×'<÷÷^ !r×Ûá–?.ø÷·¬\ɧ“¥Œ!†@Ö¸›`þÜH€ÒZ‚ßqÅÎíA‰Í¢'öÔS'üÂ/<“'<á4N;mÂ?ßo¾¾ý7FމÒ=¥ÃªN¥׈qÒµT¾æRªjî…£]êÀí¬}ªà]ùK¨{µ(9;,U=f@·(IõÑdñJ*”û äqÑé‚Ît¦ + BÂ…›(Ãýœ›8ú{"nÚœ_}.¼ê…ðŒGÂZùÐ9§?t¼çßáù?EFœ¬3ö.©?ììu5?K.¾…¶Ìrr¨…:θ9Ö¥V†Á†¿)ôáþÚˆjhýêÍâ>mÌ*í¿›þžÇž?ôب຋¾ êûï‚Þ»xõ¾öà¯Þ/ã3÷ÀÏ~Íâ¥ýìˆN¹'ä“% žþÚWsË”ÜòÇeÎ_½8ÇÕ"’ÛÉ®¸«t1,ˆId¡½å¶H¨Z>ý®ßõ¼¥0Ê®ØÑ­¶³ø}îçžÇ¹O<Ÿ¿>ãQÜx7‹ eÕ ç(Ú–ªi);AaT®É¨Œ"$áðƒÕQ„.õ DE¿âm7ßùÛ#NÖx·¾pÄ¡¶Š s®ÃPÿ¢]µ„ˆòÂzØO‹” îÇe×£?ûqª f¨ÄïY`ù8«Q­ñ…`DB©á Ö 8£ŽüæµpA¥ØûIÊG¼ßí³À—¿­cÖ6‘Fiš²"Z5Ôºô›øèøˆî"EÛa['Îå"ÖËX» h¼_„®ñ_! Q§ØÕN½k #Bo÷˺¢ +‹ñÒsÃŒZ‰ S!¢UÈ”€3 ‡) ßq¹áúÓ¬àÁ£nžîØŠ|Ó;…oÙ š#s/›[H896ãøÏBÓÓ7£á´5( üî“à%ì·'ä" °ü‹•âK–†’B, >&÷€QãA¶zÀk¢F&ú’k‹‘Ïx¥ kôz`»5’D¥ªy\ºÆ10 t.û4Õ«¼rWíâÂëJêùœé| ë“f&t×è¨:éÇ`£[ ?ˆ†Áçqoiè²ûª­ u‚¸P@ïóÿW HF´D‰Ã^%Æ—NR" N[|”Å©¯©ªl4uESVtEÁÖú”y]Ó¬Ulíž ÂeRâj!¾/„[=_pzɳwY¾¼øÄ¦>þöæŒ?=Üñ‡wÍ)ºŽ¦¬F3«&Ì‹šº óN¸^§˜wT[ Õ¬Á¶ŽrÖb;‡íeÛ ­×{¬B¬q>Wá÷TYÓ<ÆAü³p¬š·Q{æeZt¿ê­Ž µ4>Óf# ÏÞ2lëÔ^ 2´«­ˆNe¥Ý@j(¥IäᮥjÙHhÍ#«È ΪÙS–|]ù©ñõü«üÁ¼ã®£s~óöÚ z?(ÙÐD­˜U:[dë9Dm…Ïf¼ÄÎhC¦tÌÀI¯Mn•´YxþnÏc&‘Ϫ Ozˆú¸æòËK¶~Ì@4lDY ”ç±ÑPVåÑ‚€è‘€¨‘€Œ-mA\t_åñ²2r?Œ$”ƒ˜²Ÿ²ô"Ò¥Ç>Í6î;ÑÖϲ\{ýQÎ?o“õICÝ̳{ªô-Šˆ Q­b&f«C¥JåQ¦UÏëéEDÖ•–Dz¡´\YG(—ô<(ª•u®¶Oá{a|i¹Cìwïâj­X"^Ú²Ì.®¦®pJ®­©ëš©H[•l홲µgJ;)QUD[iZå Æ‰q ëa‘ŸtwñÍ1në`Êù\À>N9) ‹€(ý»¨" +e@¥;…B•A#¹®b߀(þ¢I¯«$&=dMã±wì„Y·+,FÖGg®¨(Ȳ€h/Ta:±Lb+i·t9Yc§Ëd[”RÜ^Ÿÿ´æ[_òG9¦‹ËB`ðI'ÓB£ãà®ê]U£G¥Ü©Qƒ˜†‘˜„ï%…ôT/ ³Ðx¾=‰EôCÀOvÄ rÆVZüï¶ DM3©Äfk—X"Ai˜ÀŸþÒ#¹ëÃëÂ22b½j#ôÕ‚.SmÏã Ô»¾ ¯<ÈË~à/pMd¶1¡ë4777ÑtsWÓ5][HYêeÒi|kä˜4*Ïy}džc嬕E#¹«4âžê­ ã†9Í–F²:z‘Ï©Ö#kcA0âñbz£öÌ£ä‡Ìdë]‘:Ų’5Ò OW9þÕU…X0F¬‘ t¶F¼·W·&ŸÑ…àìL%H{mvâ(ê[8ʪ¥,å¾·2œ§Ï¢t-3ãõÍT\ø ×•Àœð}l1åÜLã-ͬ¢mRs¶¦’9œË=8M7/à!4r~ï±£(%Y¥ŽsÊ–R·T“†ÉÞ™ ú×;ì.—¤ÓEî"ýOtꆩXz×ó9j?çqò²“òQ ˆZ§<åèÊ£jO,@—J±4TÅUe™´I"T[LßÛ¡ïzÖó‰ÔRœã ÈŠŒ™å€YH—WoDŸ-~¬\Š8 “]dlµ¼×¥µSÄF[C˜[bgˆÞƒ^i"}ÿ—ý O¹òŸ¹òü[dÑInº±HP¸þõþ×ä÷ÔêZã8âuõbÑ[ý8¿$€Ü[%½E‚g¡'Dˆ ñíö>h¢ ¥ÿ™>ðþ¡ƒgño‡‘­šWÿâ èœ]ñv"¨3øvüùÈ•WÞÆ—¼ðm„„/Ü…7Q©ï¤O‡ïÌ`™&¢ŽvûP*fË£·uÙ¢ècRýkÒî>,Æ¥ 1«\jìkeO›8"H‡¡Aï†ìçz õôÚä‚·‰ÀkD8 þþÔÏ&ØT´ƒà™Ò'ìzÄÖ.C"«ºÉ(õÉt†-UÙPOd·_U kaÛºaZ e)×ùV‹›ó·Ï2k&4s‹ÙÖ„¶)i›’fVსkd@€n^HÓºˆlÒñ!ìÒxÕŽr"­™ëõ9å®–ªñ¨÷ÌE'= t±`6ŸÐ¹ï >ša#§£fÑR˜N6zQæÞ(O©$6Ï`míu’Œsúç”…¥×™\,¢ë@° ËÚ‡Š€­E4 ðÉm%©‡†h ¦a0[ 1¨í»´Uè«U®¤ñ! £øI¹|DGŸ,äìǽ€¸€ö:…êĵ-q“V“…ÄÏKBS;›„dñ¾ìœ[ùÌËÿ™ÿ÷å?»ÀQƒÛ”?‰¨R;g¡í¼¥càt-ŃBâù˜“ bŸ™ågbŽÅ ’ÃGùœÆÑ l2zù}7Üy¯}ÛWȹrÇüÓK8>·,rbÔL=Qñk_ôS¬— U¸ò£iá×(æÂèaN2¡5öô’È'p¤êÏߥ׿íƒÌw² cOŒa˜£ñgüèuŸ „iû÷œïÓ8} Bˆé=iÏ ¼¨Ô™NxÏ­û>æŸWM½"v™æï1çD«¸½Ë›'RÌÔÈñ4鮵À­ª€µ5­ac‚:ul¬Ãz;|?›¿÷Çø;ï¡ô0iÅÝ­ ( ÑJ7J5.+0ƒå¿MàÇ1¿”tã ¶"&a±­‰zƒ®ÚÅl÷^6÷Žºì26®»Ž'= {Ê)Ÿžr÷Ýwó3?ó3;¾÷ú׿U¬sÊ牀Ă, Á‚QP¦Lvlu(b*R‹É…”É麱œ¶ ÈñÈ»ñ8/.”¥Œ$$r°w™Þ…•ò÷é^Í>SpNùHl¤Ï‰j¥ß»ê´ßXT£GRඦ¸YMðEêeÑ·F4|Û7ÜÃ|\÷4½hq=Ø öƒÙ°ïØw#®áU1¥´kÿ¿âyÇ;÷ž)o~ûÆ€úÈ0Èrtì• Ò HÐ>íRû×>ïÞÃà¢È.¹ð:õ­0ùy &¿žW+=ˆˆÃB½ÏÞµÀ7?ïV¬Ñ|ß÷ÙÑ\Œ³ºU7wKýD<ް¬x?®ø¹¸Äh_&KǥϬ Oßrsä ÿÇ •øqÈLyõ<w¢8e} ÍÍ»þÝX3® T\}¥æyÏ3+„g4z´¹Ìo¤.K[“²]ÐÝ}7î·ÒÝx í?¾‡ö†÷Ó¼ÿ,žÉî=ÄC÷ƒòX ÇŠÞëÁ °2<¡ÐY7“aÞçß°o?åå—S^yåUWS\~9ÅÕW£&Âl†* ôtú×…¥ËuÎxéѵ—b1£Qeô:«¡@üâ)€î”#ŸóÊ€î€éDˆ£&A™Ý£¶_ ¥Ž' R%¬ñ©c^À„2³<&x¢ë] ¨KÝ‚v‘Ø*˜V[ƒq^b!Ewæ~VAkp[º­)¾©èÚçJ"&/¶g¥ø_4\}¹b÷®‡ö¼‡wÞ?òÚÈß½ÓsàvÏÝ*M¯TOö#F;´nÑÆ£Ã‡2môæû¾ÃB¥ÝœÁË(_ë˜NºGy„˜³§¬vå0Úal›ECi«ŒCkŸÁ“}ºÅv'aaç*ºtšÆ(âATo‰^Šƒ+ ^2Â|´„ ÁQ-],Jz,zXÃÐ{þ‹Ÿ Ï~:\ñHøÌk>=EcÖÀþPÆÿz¼îFAOÎ8ú¸½“תØÍ*»ŸÕ²‡`ƒì;rªÕƯ~1<>ÍÅ—^»7ø{ø Èd‹^ñÆlu#,¡~¬Æ++Ð=¥ñIXr¥sº€Ê㟽ÚÁD?A2Žb±ðP3BFˆ"©µbUh$î¡<˜è’€HÑŸòíq¸“8ˆ .Ö­wi5Ƽ 6í"ns×=ª& IDATJhJT§hš5\Sქ óXÓ©B,3 ×^ Ÿÿøïÿé¡3×?û&øõ·À_¿stlŠÃO;Šè(i±8¬rR»¡$˜i”G1-¤ÕÚ¸Ô>Ö%«ƒl…Ä%ÑУ}  †j”ö«ZbLdMxWˆU4>Øœ9æ¢ÅEÉk)‘¿ÖŠ +©¬_ŒmÀ爈<ù øžz,:_ù£pÏahüÙÛØuŒcÊã¾€Îyu1MªôC;ÚjøDÜ–+žˆˆÞÎîR«¯ï§_ kS¡ ýÖ÷Ÿ‡€˜é:—ýÌ¡ˆtºÈ¢á”ðwz¢k´=_É 2@‚²ÃP¥L¬¾Åfd±q΃U;=¤ÆÏ=*]y‰…è(1›Dû cˆ‡;Ü¿ÎÈz‹¸¸îË!6oÜdˆú@|Þã˜CN;.º*`ùëaïzäiO=‹Ý»?¹ØÚ‡àŸn‡ç½\âBi/q¡ÂwT±afÔqŽÁSÑ`•Ô¶Hªc/ JÅdytе^DCƒÒ.3±>FØòœG Z~ˆûJ‘ÜO=$ÒÛÜÃûú>âÑæZï+‰tØ,&ªhTE«KAµ¤ ï1ÉæW¿ 6&B¬ÝU?ô¯×ÆÁŸÝ$Çð¹?>*‹ÕIõ©©}š²Ž!mºÌhëŸY@⨽@ÜNIØ."j`|1Ðúû¸µ€Kz¿Áê3ÆúbÊ8Nb]nWž ?ü"X«„ø|R@ʲ¶ÎU¿ñF¢UY@¼Ñtº$…×VÄĨ¼» ¦G†Û@}Õm豋YC,²®N( q;…´Æõ©˜é"1xÄm¥ƒ‹ žÙ¯ÿ;áC›("áPÇÖÛ/,pj^-þßV@¶9X‡Àæñœº¿†W]µoúÆOl y'üÉà¯> )Ë¥o©ÝœÚÏ™„S¿…Nг¢Ú•´¹Òâ¤(PÉ1Z¡´C/)’Æ ©¡Æçމ,áËóÔÅá˜.÷õŽHÀ<¹åƒ·¤x<ÁÉå¥Á b”Jæ(©£½€RÑŒ¤Ž6ª¢U%*˜›Z0¦¢Ñ‚ÊJg‘Á5ð¼ËàÅ—>4¯ÓGáUÿ³Þð.€‚ÊÇ¡•€TIíç"t‚ýP> Hn18R½€ˆ‘FsµB@Ô¨ž…¡ž¥Üä ½Ð›Æc)‚ô¨éŤ1U¦B÷’1ú»køÒÇ ñ§ŸqR@š²±Îcÿì+¢áµ¸©z1qýîÁHå²Ä>lœ‡®õíÝÞ ­;? d¼;é‘ñ ÕÜ* uóÔÑC Þr”ùÞ”aŽñˆ“Åí¡â¢“>§kŒÿÄQñØ÷ÅνÛ`”!“R$ëÒ°wO ^ü¥ð’KÓ†‹.Ü`ÏžÞJ9ÐÂ?†o~OäÐaOl:Ö›clÌ2õ[¬»c¾£sê0G©Hæ½RÐå§Áç‚H­-.+ J¡­ˆR(í3ó –²’²Dï3±Tê­£NxtÞ Sã.“¾V@£ Ù¥BÌ;^£,PQĤQUî‰275­.étÁ–rÌ®375Çêõ a¬'†]5<éøÞKáÑ){úTÜ:øp ïº/òŠ]€ƒ›1õ¢.TÝ zÒÍ(BGÕ5T¾Áâ¨ý\j(ø§V‰}¦&ôb‘ñ:iGi×ËGqq‹LˆN}iú÷û‚TX =ºUÂ\kuIkeÒØŠÖÈ󦬘•S )Y£8c]Nßx"¬Y¸¢†ZŸO¹€Ø]ë\û®ÿ/[>ÑZ;U2AbyhŒ^DänÓŽÃd æ©ñË‘^Œ<ŽyŒ»åå½”…õs7£Î¿s€x`kÔ‡D Øq=ª(µØÜj'و١òq'·ÜØ¿°,"²m[DÓûÈ‹^ø.½d7„ÈË¿õQìÚõÀ!„ÿóhË›Á{ïoXÛÜd÷Öav7‡Ù3;Då&~ÆÄÍPˆhØè¨b“EÃ*'‹AZd¢V9‡^Ð4òšX A–¥P:Œ$ŽÆÃŽUÆNô¼ÉP£æLÒc#õï;?Š![(š0X.!fX¤Š2îµFUi4­ò"¶e§Ì©™›š£“ ¶ì”Íz#ë»g_—D«øÎÓ"ŸW)>ó“Hn}« ¼mÖòsÃïP¤íå¼e²5c2Ÿ±¶µÉt¾%sÚβhTNQG´!dLÈܶ1vGCa¼€-uä‹â±,&ùTÖÛ¬’^LbP¹Cf JâTJŠ [-¢‹V$=oÊŠY1¡µ%[“)³ZÀˆóº”N¡Q:òM§FN-àË*Ã#´:) Ÿ2Ù½Îg~ð÷pÚÐé2õŽ(²p8-ˆÇâuzì1Ë©Z'ö+}JUTP¨Þ%žOÅ‘±ûcT àµçé^÷ü[ïA¹ét )bFà±hhµÝ]‹qµ­BêÁ¹°V¹±zñŽ›å2†&^Þ»êò=”Fóš}4_¼Á¾½u=,f3<3~ÙææCG(Û†][GØä^&~ÆFw”µvM`ê·$e¨B“¿Z;ñC#¯~©”ౕ7UP e"ÉzBGbòeG%c9ÞIÔâ”]X#«.F•vÀ)>“ª‚ÅÐ I@ÒϦsÇ/»äTmЯî°âŽ‰Ð©EØZ%VS–-3Å9+HµNKŽÕëYßÅÜÖ]ß`kmJSWœcWűEd/ÿ@Éý̉À·ÇƒÜÔ´–Ž‚rÖ²~øõ|ÎÆ±£¬mmRú–µÙ&¥Khvž“ÊÐb´Ä8JZ”7¤Q^° q Ã`1öVÇ8ZuÂMl+T1æ¸H?'(q9F¯r²CôŠÖ”¸hñÞИ*¿7/…¬Ü™‚­z*@ϲæè® æU-L¶IAWh¸ÄÂåùjvñ$j&XjìIùd H±gϹ÷ÿöÞxš¨áä¯ÜDwÓ‰,l«,;ûûR5ΡèÕá±ÝŠŒ~ÕñAd§×Ôm’1Ž®wK4áô¦øªf’ͱ<ãÝÁ÷|çå\óäC\ü¬MŽ>¡ã]ñ^®ó÷ b¤lœ¦a`ßbƒ‹ÓXãØç6¤Ë,‹FºðMôR¨DC¥ÈÁ)›þtiÍ.ÇJ5c­KU8 EÊëW÷°;±¢ • ·1‘‹“¨DH*Ó¦\ë"P ÄD£cùÛrZÅDŸÄOK„¢ ]ßÂLYè)Þ6&ûØœ¬ã‚ecÿ>6×ÖqXaIÙˆÖ©éy¥y —«‹9ö) ·ÞÇ}Üoã—ýõt¾Å¹‘Dk¼g¶5gß™ lt¬on–HcÖÍKzjâ;´ iÙ¾•%Qv^?3¯´JB¡E4º|&Q©]#ÝD$ ÅøYŽâ“…{ ê:¦öl¯éUKpZYZp'ËÂN䩿“>ºfÂÆ¾}Ò(±ÖÒÍ&xcäói‚¦q4fàÙú<žÆ9œË¹<†K5ëñ£OòÊ]q©ÞG ÁÓ$qh+¡hdH_//·P¨´Ë_Êéå6ôÑFïÿÅÛ¸ëoO²qÓ¶nß”w·¶" –4wPùxѨ,t‹h¬¢EvšO]âp?ÌVÜáõŒ"¡âXª¹VdßõJ@2ŸÇ¥šŠƒ_ùÍ;ÁÝÉ9Wu¼pà ¿æfž÷Ò¢•x³OÕmëí&“¶8žŸ—¢¤‰¾ØÞ¥Í5·_G5PeaX2=RÒž’÷zP){^DDU)Œú±–gy/jQ)ÐùlÔTµ˜a‰£Ÿ¼´i‡ñ1û̧׭S¢©8oq½ti ¾Á;ÃV»&høhØpûè7Z‚רf\Mëxwswés8·qIû.ÔÏ}Ø×ÚþZníþ–ã‹w÷ñ”Aþ?1 I8z%B±5—¨ÏZØÂa7MYˆh(±OÖm¹N61žL:ÖeÄ.orº2o jÉŸãÃØ1/?®àîcŠ C”H$úÔ±å’/ML¢éµ4?x%íÙ*zMS„eÁ”®Ÿ‚¦c‚ä=Ó6”TµmvâðÆsý¤ãÜÉ:÷é#åñ\Ä·<â×áGm²vø¯>ù®"²GÉ¢¡SÔAJUå"Y•¶ªsNiš‡\©#³Dù›3,¶û‰£eºwHÏ JîNA§xö³>Ä¿øoâÅ_ñ´XíÑ&¢mD)ÁÎ%eS¯šÒøà˜hñLð´x\zÌQg(› ›¢MI_&vÙ@ÄÔ#ÿÛ±hUïf—óéq©€«R!Hã%"I¥ññ1Íù0`ph†tÜc0t鸧¡CÓcc* ã’Ù—#úHÀ÷ ï5¡SD.ü NÑëV0ñ.‰ª“<¾6FÚ¦—¦ƒv`m¶%8ôÐÓl#œ/EAóµó8£ë'lmIú̆ah$ð²+“ñZjQÐFÄÁâ$¢0£Ê€¶é3¶égMæ@ET32¡”¤GÁƧnÃP>3Uê^¡ ¥ªxŒK!Ù±1Ã<=à• ÛRD„AÞÿàå½ÇEBPéki”ðÁHd¢l‰^œµ#uZÖÚJ}L©(fSÆÓ؃û`mº…ê#Z} vò¹¶Ž|LÎÙOV@ö>È‚¨,ãqν›j¡0Õ¡ª¼ËÂÙäW~è.zçxןd«ëE,&QL¬t„6¥«rŒ§+É›}“ŠõY4BUÿÈÏïuDí.5è/>ÄN¬m¹â:ìZIk…ê UnÏ3¦»B% .ýht""ôšïø¦¿DÍÏüÔµ9×J‚¡&Dò¬D›ú«Ú²YÈÏ .=—E#ö!o‡ôüx^襨cY4ÔŠ¦nï6XZ éSÁ=‘ÍcÒ±ˆˆü†$(¾ŠÂÓ°HÏ;lìäg½‡aï8؜ܽ'öèdÑ‹C )Bôò¼ŠA†j>G㓵€OàÁ¸TãñÞ¤tNêSÒã†ÉÞ9eø¨’˧ʧFêJÊ*T#ç´j A ѤߣÀušTLàÂ4ØW¢Å’EP+Ÿ£9K +®”(åoNåòòÙéÒá ¸$¨at ¡‚>:¹‡ ŸG ytB…Žé1S¤£O|>¦ù DJ1F*7À£[4º+iÐ’î€s^íEBÜ}ù¿‡É¾=y(·÷¼ç=„ ÷ÀáC¼ûäíi÷ÈRZ*®Žó–ÓIï–ݶ®æïv]ä†8ú!ðýßrjâ¹ÿô‚Ðâ4Â4y®·A„ ­fAlU7lü:¯Æ¨$TÈRv)½8ì$õÄôN²’¦R¹Î‘Úƒ—Z+ÞPM#±¹tãò±Ooy>éIi­!½£‚^Éß;7°0œ{ ãå/9Á+¾õ^ž|µ)»ÊP D Xê” ÛÖªsaù˜ªé3n˛ǹØ,ƒ]ëvÑPýd\Jqɱ/b“£“ñX~Þ$••¿¶OŸ°Çľ‡÷_O¢ËBö‘Ìø¡¿ LL@HRá.¤½PÜ9]™ê|‚%glW÷òøÍ_r#/ûÒËùtð@à±—ù±§UYØ ‘6k½ü<ˆ ä9%k’º0þœ®Ù2 KaªÏwõúV;ŠG¬ú«ê«YUÆ4ãgÆn;j'Øc({âü=ï«:àHˆ–ç£|n>°ìLªSó‰’PËyFuwç=lý¿¢»þèÎ ¥Ûƒò &üOt&ð®Ÿ/u¯Àîƒfú›^†zþóižüdôd²3ùsQ@^õªWáœ+4ÞC‡qÏÉÛö‡»Ó=Œ72½#ñ—Ž7¾iÁkí z­G­ „IDÍüD§Hä!ß2qNÇ…ÝV×´Il.´x5Ö?B•ªÊԸȇ*r ;D KRY­ ë*}¥*0]ý|^Œtuéª6’Å1&H ¯þ¦¡Ë®ŠFæ ­†µhø¡ïzÿùÑcvZØw^ìY2B:Ûç­–™Oü¶Û¾7îò¯Å%Š+)²,4ôGžë? ÀÇS§#?ÿK-4¬Ô0A’9.|a,•½z¾§ÚXx9ÏTú…‰Ø%ãxÍç]xù‹ç‚gñš}ëšüÁf¥ûo‡ãU+€Õ×° j–í]†Ëgñn3ægƒ'îf¹«ßÏÞ¥¸ô‰;‡WéÃu+üÒ©JŸ+3~­ ±èoüï»w×=(Ê¥¦vù«Ê¿¤5íEÑ\tæ¼óЇ£@ïÛ‡2fO@vJa>|˜“'O~J÷‰û¡ï#?÷ó‘kß1p׉9ÇÏ̉3žõ„i$L™Ã5†8©Ä¢ ãÙÞ0î8Ì‘FNIåçkñUí£ö>ÕB°«ëáLÌ×§áÒ¢w™¦ß©› ‰FŽVt•¾2Œ]ZF ±ÊEØ«q÷;7BÎ lZÔB£¶âfËÓ>oÂw¿Bó’¯Qœs”Ϻ[?À‰túþé#ÿñuÕ8nûøÀ‰3Õ8h¤B­P‡£•щî›#H=œwo¤¤U£Ä#ÃøÙÄÞÒ(Í“Ÿ †eÏxªæÇ~D~ß¾u±¾Ø»}nÞöø½?‹œÙü‡×n¾eÀS^Ÿ§Ž8 ¨µ¡5ÄI$νmD@òλ© uLÚç:TÅñ, õÄ{P#¸~Þï°{ŒÕkwv|ˆáÜÚt-qgaÑ•Is©ïÄQU”]mÞ|õÕ{²:ƒ†-ÁÑ«-KÜœ ·4j€ó~ìû4/þbÅyŸBróíðæë7ßùÙ_Iíª: l@µÕ:b“x1²ž`(ò¼Ž’æIPȸ“!;œ+‰?%â!ó)x‰B´Ož*N£<0¤(Ñ)b߃r”¶Ö~™âE/ôÒ—?[qé…{‹êž€|ŽÈË~<àzǵïèʈ]¦2‘0 èµ9~¢Ó3Gß4ÄüzÛŠ€ä]ÍyÎdÜäª]·«DÃWé+¿¼+$ª1‰•€ÔQH¨:Ç »J=üdU@j‚pŽ(T‰Ä YÌ‘ªn­2Y¥³LŠN¼'ò]z¢’Ô•F¨¹ÁøˆÚ²°Ùb‚´ƒϺZs`¿å‡¿Yñì'?ú.´?ykäuê8~¯ç=7¬n—Ò2³-¨‰#6`!±"XqÜŒ:'ï*$Ï& ù|‰Ëñé¼ÓI@”Wè’x(”‰8…vû&}/J'–§À!CÐ<ýIšsŽÉÜÄë~Dqôàçæ¢zç}ðÊŸ­Q«îÉóÂkHí È£M@6:øë}çù–Ÿd*6.Ÿ ¤ý01bPå§5ëšFRW“H×L+ÒV©ÍØuDZ(Êä\s9®D£³ýçjÁ5ð±NgÅÑOâáˆ^U†—bÙÄGWâb*!1IdNž†ûN5’‚t©2g¹¶âtŠÖ4ªW2SÑXhçŠç³0¨‹."Å/kùÉ—¾øñеö‘yž¾÷öÈ]§<¿õfÇŸ^×—A:!˼C0ºˆˆ·Õ:‚…`4>1•Dˆ½N.š&GDKæ{ųµ³ÖÙÉ„@'äéø, Ù%SK±6â`Ð>Š€ V¬•“€èÔ©²%FUˆÃùïþ¹áÊ 4O¿TsþÏ‘xË‘­. cäÚEþï78™çQ‰É¦e^IGšošS ‰èŒÒo?ì›(ž÷8Ø?ÙG”€|äüâ;æ=ox×Bˆ®ÈÅÜÒ´¦ÑÑ(¼1hLƒŸEâÄÑp­¦k¦øV¢Þ ¨tåÝuŽ&²€ä¨#TQÇêqÕ SÃÊc¾ðƒx¨+Ÿ†ŸÒpŸLJ¿ûΟxîpQ¥PF%*U&tu¼*9ʸõnx÷MË"tÇI¸ýÛócY=v.|ŸÅ7 frÕe©kX.Èozºâ^r1_÷u—=bÎÏŸGàc÷v¼í÷ÞÓ3‰LW'8 7¦ˆF0Òò*瞆Ö'ª´‚&âµ&E4ÉžY#_+UÄ#OÛ?Ø@ª,h…uAD%ÁP! ¼Æ/é,gÄ 3E#Ú±Vbf&Íaòú.šE|Náz© ÏbËEÇ,ßødËs/ytîÀý½‘÷~\hÁðnÇ|³§‰ƒ4§Ñ <3;Ÿ*LS[{ÓŠ€Dñ.Êó 1*^zâÐLñ}Ï„'Ýψ€ÜÓÃ]ç­w:~ùýsÚùÝ邌ž†…ˆF¤£ÎŒö V ŒXèÌ?×*:;ÁM4½mX4S|# »Þ¶Ò"êyÇM •@8P鎓¶¼rì±tðéQ襲듋Uñ ÑÉD…tœîÄXñ»Æ©ÚÝne8KBµ*÷ 5Ñ(tÒhÃݧX¼õ#Ë5ƒ^·ª"Ÿ†ÕÙê2Ê]agæŠÜ÷í³ìßß”(ìš§æ§~êiœþŒÇ¾oSÚ6¿ïí§îß`c£Çv›Åâ²IÑÉsÝ+Ì.#ž5qÑ V›˜ ÑÁ"6F8^bG ŠÚ²!¹Ëe.ç¤YXMÌ'{:út®Mþ4Ú íA J03iÓø¡ll²€„ýå`© ‘NO£ÎЮÏP³5^reËËk9Ü.}îºïè"'zÏßø­;Ö»M67b·`:‘6ˆ¥@P‚  F>¥"$#;Aš¥q:!O¢Ì)7¥¸ö–#ôÁŒ˜•✨ª”TE˜ UôÕöáÆ¸’Š;¥­V§ÿÕîõm™¶ÌsfE@êiúX tÅ "ÿÛ<–Ç=v"¼âÓ4Ûà[ùîã®ãÞÅ)Z×Ëî7(-±Æ{œ–!GA¢á¢a ¡GŒ‰†(Œ.‡Áe,‹†’Ü•`1¢‡ Ë` ,yØH3ž‚‡B¥Í¦fˆñVöNÑ©.“-~–b!ã&V™V"2Ò i:)— †=›@5a ñ"&:I}E‰~˜± IDATmp8cakuí„3kû%-—"©—r%籎&p Ïàé§èv3ãd¼Ÿkã]¼_/fUë‹Mömm C`Ú/Ð^ÀŠhh‚xƒè±¦á’Qg' ¦¥Ók,˜Ð;(ú`ððÄ 3.@3¤Åš‰¤Ô•Ro¾•ŠÔæ»<ÿŠ'bq<™§b?Ã<ÜG/Lñà„ÿëúo§qÓÙ‚}jƒY˜c¦â“핸‡ETA·tz¹›±Ø‚ù0¡÷-kéºç ý¢Å ï4®·x§ ƒÆ¥vÆàaá+»5`ç’+n¶†Aع!ð"¹žaúD]uA¢ŽKô‘ŸW¹Xî„#¦VJ9¨¸" Õš l«¼óËø»3—‚ŽÜ±ØÏFh·#äóOëJ’cÛr$¡¶G±>®êìÐöp€ vdéïÄØ¯)˜ªJgé G¡*dÁÔ§&„_õç`”浿z^8á6~•“|œsœSl–…Íx_ÞgíC‰ oé]‹s†Á5 Þâ‚Áy+ÇÎàœ0¡—ó)úƒIæTÁ'´x*RScHÒûR'^Lï÷YíjT5y]¼Èä=*b¢!ªˆÖrÏc".A@ˆ´œh<ÖzŒõXã±Çj5qXíh­ Ëë°ÖI}%Ci¢ÇYIá©m¼19¾"<‰x?HÃáOhÝ8Á[¸-¾™®Ÿr§º“3~Cîf(ÿÖ´_`¼' ±Þ{Ûˆ¼KIƒÓ3µÆÀŒAM”|íÔŒžýt÷Îéo¹7ohB@%‚o3KEwã™XH-e­g²ÖQ±­Š“·MvÂÔ*`´¬qWq)—ðÎã¹{òpäÀÍ{ßzÍÄÓì4“€n5jªñ¶a“#,8È‚#,8ÌÀ:˜Ïxû{˜ßïèºä2Ö7øÁ¼¢ïÄÏ:8¹ÈU@(›NôCô’¯´s©cè1s/ydç1}Š(\ú:fkÏ„‚K?“óú§7G—VËQ(4Uû%©weC~?ÂÍîБ?Ûxïë/“ù´ËìE-;P£®¢ªIy]Ñ‹ëFµl¼MLvH[ųt`-EÕ±^•¤~MœâÒ£×{¡ ×Þ&ya/zñu¼üŸ¿™sŽÜÏ“®¸™Î5ô}#ÂÐ7ôƒAß7ôC‹óF¾?XñŒèåÑ{ƒëE¼1‰Aá½"x1ñˆÉ7æ¨"=G:Î…±Ä3:$Æ<„ôU~U5”³x ZÇ©h“¿/b‚’³6!}?`Mj_µk=èHÓ8¬õÒ&ß4Vím;¤ï9¦mOÛ´ÍÀÚtAÛLšžFât‰È¬qò|ˆèaÉúëd(ձ̆S@ê›þzæg~š…á£Æy“æn"ºñr×AæX¢ÆM×·t}Kﺡ¥w–!}ÖÞº¡!L1}ê?ÁOŽà˜$*ôz~Nèç–Å_þ5ý‡oEõŠÚ¡œÂ4žÙÁ9Ú¦û¬ÞÂ¶Žµƒ[Löu´ÓžvÚc¿ôç¡MõÇ –‰íXk¶Äò`Ó0ñ_Ælý[A]Gž±' & ‡N^÷?¡öÏ`}Fhf¸é!‚г-Žhè9@Ï~AÕù5Î|à8ñ†?eqj xM ša°e×ç#Q¦×2ƒÝŒ—ã˜Át^:[C”è‚,É»ÙLê³×>ëmkH}£ŒZ„±ŽQF2buÄŠ#›>µûóøõîëÁn çñþp…LÅçÙ ]MŠ«*êÈ"§Âëã"ÕsA-§ªXj\9^Ї…›gÙ€Eí$,‹†ª„‚ŽM%šå‚»¯Šø ãM€Ëι›/¼ú}\²ÿ.þÙÓ_æ†F¢Ò¨é‡FëQÎ!YðÎÙ$Ÿ.|ç 1èò|术 J)z=î»Ã²P°KI¨¼æAnq´´ZJkÍ*}Ji­üšTãÎe’ú’ Œ (-|.ÛHër­ÆÈ±Ò¹üö»ÿ)woœ‡Ö"jEí" jE@t}"m•ÎR•€äaÇX}X¡úYŸ;¨=‘ yM²üÄ¥?Í1u—Å›™Å-I-!ƒt!ýý¡Ž Âòq)r‡eß™l±º£QdöªOŠý¸S3ôv—€ÜWá(ëŒ$c´’R”®Å5|H]-¹{-äkîü_¹c¸Hp²&×Yä~ª;€ öÁù]L7Ykæ#±¡ÌXi^vñëù’óÞ\þȃê~.P·oïÝÛa_‚D&€lB"AÙÄ´™Ìåɯáð׿ì+ˆ“µôqŽžCþþ òFÿùõèãÇ90Ó̸—‰Ý® X#~(Útæ)6PLR+³ÔǨâXC)‘sêe:ˆ=Ä9„aJTûé½ec€Ís/âð÷þkö¿à˜Ã‡QMó¹# «4ÞÇqòÄ­élVÉ?@¥ pÕ Hûž­÷¿Ÿ­~ˆÅ 7W ½ªÊr9@-S>ØÝPÊTBQ«´µSZ—;ª*æç•Z"•îØ«wÜcùõßkP6òn÷Xþ¼{´^î™ÎÚ„q§mAŽ‘±¾á«_Õ.|%¡J_-]¬j9Òj…嵊XY­ððQ+j¥¢W„DÅìJ%º:6•›0¦³teÛkªD%ÔJFÐz#“ó]ÃKú?à˯¸•¯ÿÊþá\j;59?ÌŸüän»¾í1VZ¯ÚϤïýÍ;þú6‚#¿ª€XSƒUßóüù¬RvýÏî”­D> 9¸œ)Sð¸ðaž¯þ<=§ùWߺÉáƒ2Uý{»%WÕlõ§=ÙŸÄäŠ+PÖ¬8Ž@¸ÿ~Ü{¯Çßpq¾¿ÿ>†;îÄOøÀ‡n¸;¬«NÖ(¦¦Úë‘~¿Ó. Ædn•çˆC²/Iö$.B‡dbÁøX#qvSÒ]C†êĨÏ1¯—ÏÓ À'±÷œåI—&Z³>ƒ×ÿ'ù“Ž>Üz¼1¨‡ñ!‡ÍMüéÓ¨¶Eƒ?uŠáøq6ßö6†;î`rþù¨a`ó-o¡»á´÷r*;ó9Êû¥·'”ËI­%¶-¬¯c/¿œöñ§¹òJ¦OxæÜsQkkØÃ‡Ñû÷£¦Sù¼Aöh¼Û='à 'NÁ¾YèHéPÞLp+ïðBzM½ø…ª×Õ»µj±Ï¢P*ÕãYïU½&O¿g¼Jªè.µW~Ó«Ç;o¥%­“޳€DÎÈç3ª^Îá«®€ïÿNyùS>>ÿêGÎ{>?ÎÖ»Þ…»ÿþ3Õ44çÇôÊ+iÎ?ÿS’ŠÚGéím€Wÿvàä¦âmï“rÐzD#_ KBF€cŽ>‚Zö‰T|®¡X=öc: 2ê<ƒR`\ŒeÊXÇPæTÄ[zÒŠ—Û2³¸ìž•é\5¦!3~¥ Ï%AÉýøK÷ŒcIÁf< Ë"’Ò.²(†1š©ë%Y@HŸGoeRÈÂ4˜1õåàYWÃKž?üòGï9¯ýåS[pí{«ü|Ž›8ndš ›:^1!‹+J°$ »ÔÅê×ÔîR±š¸¯­ò¬’×£m‚KbB-¥ªD¸ò1ð„ËáùOüFön{òȼ½é†ˆó‘ã§"¯üU!vjP:24 X ¡8ꔪò9—=ŒÄÞìA*ÑÈ©©$*q·„Õày.b½Ã¸4]ìtŽEù:‹C«ïÒ`°|œ§œK´±"«Ïﺀ­‡l0õRTRÄ$3¡Ò÷½K\¯M—‚ ±vœ·2î­&ZE´ˆç†U© !-ˆ6-LYxœ­¼M̘ðÕèäëßù×ðŒKàÊcüsóÆãpÝÍW¼F†Ù”‰xkˆMµ@çšš®Ú¢ó9™75T¯)ÝQq¹ŠX¶iVìbül‹X*£¶úwÕ]…ÎŒ?X´ùrCò¼r‘oÿbøÚgÂÇO<O(öä3Žø¾?wèøíw .HK£’*e¢€ ›)$êj†ì‰¿xº@=c÷Ë¢ÁXP¬ÄB2¨¨{™Œ7iˆÑ뜈EzÌâ¡cÀ:7â,|š~‰Ó¥B‰:”#2à¨V"»V•ZŒJ KųF; ITª0•²˜.zéØS"’|œ±5A‰˜8#"â¬eh¼5 Mƒo4Þ\kIž¹X2^5§À˜žq‚¥ À?¹DñeWÂO}Ñ#“@û[ˆ¼ývÏ{n÷¼ïv·¦ˆ‡³V5V x ²5Îõ¤j@s›ß*UÝ¢þžÚmÄ)"®ÖNê{¬¢£¨Çy§Ü¢*áªE,?Ÿ"eÿ2ÅÓcøö«÷cO@>·[‘Sƒ,¬ßw]Ïݧ&®ãÞ3¥"M X ];Ò­m˜·3á&%’ìžÒ•ó°[D  †(QĶóØn Y8lï°ƒ£Y çiú;$ÁèS¤üø˜Žs$a½áz±D#†¥H# ÅjÔ±}¤E¥Œ‡, +õ|\ Hú×½N¢æÞ “Ò]) èñX%±° =b >E'CÛˆÐL,®5¸ÖâÚ&¥Â©ÚÑñ’¨©Å ©¾3?pΚBµ–ß{Žá²‰âÈg¨à>Døà†çUïó¼ÿÞŽùfÇFðc4оi‰F ÐZù,üJô#+'u0J-LÎW•ís•!£à š'VèlÌSk1 1ÑR™­’Á–&X=ÖÅôH•ÆEZ ·*q_uàÌÜÎQi/ååo´^XMk94U<þhÃO]chæI³=±{oÁ'w{çxóÖÀdXðg÷,øð=ë‹Má4¾çÜÃ&ñ …ú•bhT%•ÒtŠ@Þ™…cç0‹€é<íÐÓ¸fžîÝ@ÓE4ìàhºM/Ïé â= ,2Ø•#!­H4Ì•€z9Ò¨…B¼–DEéï/µU¥ªÔvÑ8›€ÔHòš.WäIáÇ´Öݧ'|äîýÛ^ç£â}7™¶³gÛêîVxßá•pá:‘@L ääÏeãˆÐW¿ô£ŠÓð‚#¾uöwùÝåÿß™ŽnÑóë7= Ä#Ó#ÕL@Cß´„}•Ù„H™ö6½G÷B6ƒO´é ›“ÞF˜ z’=ïªó&Äå·wYò@1u}K—GoüÿSšÒO ¾1øÖÈë¬Æ7éx’Ä'ñ¦Ð56Ã@3 hhœlcêþrÞó÷v >ÒrpjùÎK¦¼|­åR£>g׿½ä!ÞÎÐ3 Sãÿ’tÑ3ëæœÙšsw?p`ë4Í0 bdÚ/D ä¦3S¢–H#cã3õ7:;5AÍ#zЋ@³509ÝaŽÉ™Žf>`;G»Ùc/Â10ÞÓ ƒ âcJS E,ÑGIO¥èÂx_ÄÁxáíè ©«|¬2Ê" ˆªD¥‹_U]Vš£|¢©OP@Òít?Å…„úPŠ¿ýØ…¼ÿ®£eáß §¶š]„`§ žø…ãáˆÈN¯4]‡‰.ÇCß{¾âW¶–Ÿ¶‡x¹Ö> {¹3 ~ÓÝÏ[7îã¦n`Ú-h‡žÞ´(bAŒ;c™739?Ià¿즓ó¬ó4[²Q±+ç£|⽉HØA¼‚î #ã-¤ó§A« Ç髲yP í¢G©½5ET²˜Ñ0Ÿ"GßÈã0kð­¡_k˱_3¸©…VøS×Ñx‰ïÐ1кëÅB§iã3ëû¹h}}Fñê_À„5¦˜=ù\3œá#á£böGáfîÖà IM¬u['èêi'¢Ð£P:eP ¦¸ØÐʼnX}†·°i\ØBùÕ›³%»»öLO»Õ£]`²ÑIÍ¢÷4ó„Ðîl/¢ÓSY(r§”R¤eG˜EÀ)àçâ8ZÜè´SU™Ôªc(̤mÇz9ÒÈ‚’#Õµ{I8dݾws?ï¼ãòòÚ?þйgãÀƒTVj”wùÙ‡# êA^³ixûq{ ¾ñUÇø".àùÏ?Âç}Þ'7àÕÓs=๕›Ù’]µ„<À:&¸héc+ÐÐÎà;9c¯ˆB¹H{¦—èvs/GÍBvéfð#$ÔËùÈù–9n>³³¼!É5‡ÿŒgOeŠ3¦<tâBåT£€DDT|#ÂRÄD딊pc¿ÞŠx4†a½ÁO¥qE5BÃÕ6`&Û8LãiÔ€U‡lô &tM3ž× 4çp>Oã(çrqñž€|. ÈGÜop²»ï5[qέîÎg­³Ù\<Óžñ^hQãúØÒucë† ƒkèú–aÑzÃ0·ÄÁz_ëõFø[!¢7%%`¼H.r·›â|f‡]8”ŽE4”N‘FôT ªH£\Ç@§–\$ý”E#_KÇ*.‹C>ÖòýœO®¿_¯±ÛZvÕÎQÈÏ_÷ÕÜzJ†(N-Öøð½pö©³[Ôìy>Ay(£â¿©i€×\³Ÿ‹.š‘_ú¥Çsé¥Óý ¼Ÿ;Üo ,Ô” ,7r›-¾3¸Î2 ÃÐÐÏ[¼3E4‚×øÞq ½ƒ4h6‡’’ja›Ajj*DÙ¸øTó¡DŽ>€ò} õLÐNÉRú2áwJ-LMYL‚Ö"&QD#š”Âl$‰Já&ÉÄËh†Y#‹Ñ kr¬LD5)k#¶•Ú¥i=vâÐ6-wê°£iìDÛ‰øÞg4ü1pÇ8¹„—í È£^@N¾üf99»Å/2ïÞÅ04lÍ×¼˜ ù`°­ÃžDì,¢éh&=í¤# Y æ‹[[36·f }ÃÖÖŒ®k ¡›OÒi xMäbÕbŸè¾ÈÅZPÍs¹ÐŒOæS*áá'í!YŽê(")µd¼€ërÑ[øDqù8…Ý¿$ÙŸ;QДçQÕ±¦J‹bVX³NÁ;>þ$èÖAÁ_Æ/¼ãërŽkĸ‚Žß¶€Ç‡ q‡E=|’gàÙD=„ål"·ƒë¢ŠüðO¼žg^|ø²g¾“¦q¸`Ž6xoè»–¾o††Å|J×M„»5aè éç­ ã‹ë%]–Å#FE2U>ÊyH(ÑŠm¢‘;ìrçQ"Úü'åÈuɱNe>˜ÚŠ€ä[¶ó%Š€diÊ‚bYëd¾5©Bã'F®w+JD È0#m‚DÆúâÑÑLL#ÐÃf6`“éÚ‚étA;éYß¿ÉÚú0ʧkú*Ö¦?& =pôY09¶' (yà.ø“Ÿ\nïËÝ÷ü.¸JìcÚ¥L&„éjß&-zÿ=µè™FíŸÒÝq;‹;>.]ˆA±è&Ìç3‚7,æ\ß¼f1Ÿ¢¼"öš¡kD(œ!ôFæÒòJ†rcI©X„$ïÚr:)×&r Ci±U‰š…¤Ž²_€2q\äSd õ˜r*â ªc]‰ƒŸÏâ±ôX"ËÇÛ¢t­ÿ·¾Š¿¹ý "o¼éYÜ7?È’=n¡ÿæs¤­&žmv9>›¨Ä]D彪HìFQÛ)ÝUëÊ+½¯ßü‚71mzþÏÿ8í„‚»ŒXt­À½œ‡D$Uê’ÙU£çs/“|£Wã‚îå)Åo5vNe¡(çl ÅR ·ÚÑÿPf€Îö1–‚:jÛ[”.&[9*!¦®¬˜f…´.õ” õ(ƒë°m û¦Äi-ì_‡¦vëk 5!xæ7ÜÀÉßÿ7þC²‘•^£‚"¸&5„ƒLÁꨅžä{‚_RTêþT‚ÆNnªZˆ•©pÚ†ä_@Á<«ôœ¸—1‚׬†Æ€ÑÐhy4ZÞ ­äÑh”Vã÷òóZ Íͤžy“¾Ö‰î–Z(Ë÷Uõ=5â)æ}à ·ìñá'ò oþbБ†u¶üt™ *WÃX!(²xÔ¼£Yæã]©üXúSt&xq¥ƒ«üš•ªöÈØmB>V­ÅQ~1-Jå®¶]îyÀMj]9îâ!?^™ Á_M|“05*rlz KÀÆÀï_ú/!ÂÕçÜ®éQ6'5î=*µ‰TÍÝ-׬(¨÷zS¶ô|Áé§s˜ºC*ç~èõ§lx’‰»œ 1pÕkÊ^!?•âäXí9²ÿ •iåéÅ„OMš -y™¨:ž3ºz/ÄŒK~ùãϹ³~¼fTåö™]š[ ŠØ¼o g¶8s¯´B'¿3|ûR´{\ši2´Ïx³§=µk®aré¥ÿèX“GMïßøÆBã`:Ãþï¯Æ¬­ (¬Mw¥ä±±²²NÛ´jyŽ´ð=¦Nò ­Mù`ý]wáý1ÚÇÁ¹;ü…Òm ZktÛ¢šFŽ™W)…®È»…Ìk,öªZ¨ó]Ž«EÚšñäË-ƒ¦:!óß§>[Ñ.WµaýZX¾øuuÕ¨Êx*ýÜïünäÃ7 ÷èîS-¯}ÃÅÝ-X mšÚÊÃ[Y4 Ô1A•AW+o¥XbŠb0bY¬üžzQ-ÈŒ[©&ñLྸV0_pÓŸ3üÐkyÑ—xžûìü;ôv€^>§¶G+‹>•(,}î+¯_ý¨Ýý,Tõš‡…T¶Ä»™1.›l{.£k—Óf¿ð8y2 “åã-þ¿qÛS'-ŽŸÇnéÌÚd­‹~Ûäz.3g@[.½´áßÞ‚Éײ–ã…S76é?ø!ÜÝ÷Ð&O¡ú¿›«ejß>š‹/¦½újš+®@µí^òHëŠÞ?¬¤ÅÒ…õ)ý„>e/ú¤n‹NÞ/ÿÔïü—Èoÿž,p7},pjî’h„Š…ªH#.›ReÐ]aoü"è€U­Æ híÐfÀ˜¥=ÆÈ÷D(Ú8#‚J»Àu˜4/ I½ƒ#–¨ÎV¦O©®â÷1 F”™„ !H£EF#j¢·EL¼kDP|Cð->X¼kð¾Á™–Él&ê ‰^Ä$Ý2«+/<ÇrÁQË ¿\ñÊï€éŽüÇ:U>“ó»/cÇïÊ5À[þ~î)ïçnˆtÎWçPÙ„Ý3;‚+«ƒ¼aJQõ¾™áñµ\p®æµ¯‘eâ‚Ïèæž€ìÝv½m-à·þD®…÷~éuÕaÃx‘5^.ísEsŒZIb!îŒ$@cĤÁF‹“.å1Êaô€1c{ í1fRÄáRzÏ%<)z–t•%Ík7ªB5ä¨â’±’ª Ûq§TVZ«´–x˜‹ „âD¨‹˜D¯ñ¾I†Mƒw-Þ·ø`ðÑâb#ïL”w(¨Ôm¤U•8Ò—óÆÞIŠ5/x×< ¾çÛàÜÃð’/ýÜ9wÿÇÛáæ;äøß¼î=Y¶É!cXjã15¦¾Î*;bçÕ6û‚ÑJA5> màS¹ãÛ^“æÑù>ï ÈÞmÛíÛ~Nž®‡¿¸Že D1¨Jé)x9Òð#*^ùˆ ^àŒÁcbÀFGSO}£|y4Z$ †±}IIiã@G´Š@HôÓó²“ÑéÚ•D”!T)«Ê ¾ˆ:»€Ô~äŒuU"¤ŸÁ”è+“|ÍE@’âVÞÒ¿ IDATòÞBÐo‹˜ˆ€È±Ã⣻\†Øà£¡§e Á)Ë -NK´"øôÔˆ°Ê‡BÊ€Ïyüü÷Â~vž·¿ÿ×ðo’¿ùÝ‚»Ž³ý½ˆU.z'5(y"v6µ*Qh\6MÛµŸ"‰RÐ;ׄ€¯||Ç‹àŸ>oO@öäQr;5‡ko–ã7½^óßwÉ@h¶“TSrVyPÑ£}Š&¼—‰Ýàhƒ<6 Øè°Q¢‰ƒˆ…^ KjUÖòœ6¡¤­¢¢Ô9¤‘@D#jÐÚÉõ«#Jû”_ŽI`RòIG)–;ƒSGÏj²š–‰ÕZ°* K‹KŽF‚.‘XˆÄö6ƒ "6Á7¢»Þ‚• ×½Ì9¤.’ÄGSÄË@C¯EL:5¡×-ÊAæ€E­–xOõbúß_} <ó’Gçù{û)xïÇá½·Àÿ.ËçNBPÝÆAÇG¢tQ>‰šV¬ HéÕ<™в ©Ï)ás©ôtÚâ•Á)‹S¶t…•Vd ç†_ûnxÖeplßž€ì È#ìW&¡¸wþðú³ävWE#P&ó€cãA> ]Ɖ@4aÀŠ,Z¶JÇ"«ÊÄ(#Ñ…6"R÷"ÆmÄÚQÐ:Oo¥’h¤ÝfLÂ"^Þj‰µ$¢vMëÇâK—„#Æe¯÷Üq›»Ÿ$ÚвMucJeéT³•6p¢Â»¶`]Lm·Qã¢ÅG©£ôHŠk ¡W->š" ClX˜)I‚ÒLlÃ@‘«àÇKÀW\—€yÖ£ãþ³Á}n¼ÞòÑ$«Ý•o¸ŠqÍËÚÏ\WÕëž{pÜs}ß lÄ]f´¨è¼ÇvŽÉ¼c:_0é:¦aAkzš8H U‹`4f& hU‰†J†i5ÉAUâ¡V(Óq‡IúZ@’µ²šŒî¢¡Õ…‹7·"½ˆeŽB:3ang,씾iy`í ÷O¦|ãÝ–o3†ï™)ÎU{²wûoss1Áߎeá:ÑwœèzTŒ4ÃÀÅJ¸ì•,(•jãth7úYL7´‹ž¦˜mÎ%•¾g¢!IµŠVËEicmßúÕDš é)eÅûD뀱^RV6êÒ÷sꪈ† éy™ÀW”ñ)££P:&q¤Àè!°= â}‡PÍ'„$²Îë¥(c±Àürvby(¯ž”W•€Èq(ÞÝ*\Ëâ4*fbá e1Ñø4¸¦1ÑK[pF•F&·”Ö FDM¤sËzÓâ½ÁEË¢™J½D5lM×èUKo[6›u6ã:›Í:óvF?ké×[ÜÌò& ïÔ×GÏh~Lá-öÓØ¦;8ÃÀ÷pøPÐ ¾gqÞ”Í 3¼í³­9kÝíг6Xdë{¦a!››Øcmª¹yÁh•, ð£€è„Êê$Zâ‘ÏŒZLvJsJ³F,Þ#zˆV B~"H‰^·ÛŽ{#ˆ×rÍž^;À`ú¶åÿu3®õ-/6-ߢÖ9ÂdO@ön»ßîå8wpëÒ®ø:îæï¸7¥y52÷Í~¸h" Šo }hñƒ!tšpF½@£W´‹^ðð½x‰L6%Òh;£½JÚ©µ¾— N9#Ñ…Qž¦8—rvLO)GÑhäõÊF|lB% ¿’žW©=UéˆÏB Fó(T7%²k[¹’å5£Ä,IpBá)e{ÜeÄÝ"üŠkñ`»ï{Í{ HDA*sèÅL) KJi½÷—pû-GKÁ6¦)hD4£W2_eÎ$†1Å‚Æ+˳>ÿc¬í„í¤×mÞ΄›e[æz†w†-¿ÆV¿&ÐO7¡‹ü‘v*ŸÏÇíÀÿb߬/ãÉ\È¥\ú)=×Opã6>Æäo#:…-W©ûøMƒr‘f#ùßøÙé9mßcc¶˜Ë&&ô´Jp"6 5Wë ›¦Ô¾ECëʺ E™Wøpj%êPËŽš¬4]Ȧ'½¦•÷/…ŸÂD3‰>æf¶qô¦•»nLCDÑÛ–¡iÐ1Ð7-}Û‚†¿%ò.ßËU\ÁÅã螀ìÝà¶ð_9É{ ïqÚœà8ÇeÁHËÑ~ Ï F y}Sî~0 ƒàá½3B÷í¤“'t²È!&þVÛ &Þ ž"m/Ñôƒˆ† }(Ù©å””VAvu/ƒ~4ˆ€_Ä$ûi= ˆÖA%›˜]Í( XŠÈ= 4É66 í8ù?ød ”"¨ä‘Dƒt‹CaŽ4F7Ã|r<¡¶9˜¬Ô?ÔQx[R$uñ$÷H½ƒ€\ûÆ'ð†ÿôLTÝ©·§B>ú‘ó8~÷±Yg-~Å"lÿö ™ÍœˆLŠf„¥å½Ó†—~ãßsùÕ›ô[-.Z:?aèI5òy)±S¡ÍþCóNNO¦Ü69Â>{†ËÕ 9Ä|Âçü\Ëmño¸wÑq[’Å|ÊÕƒÅ-lax¹Î½B‡ ç¬÷Xï˜n.äÜL ÊDÚЗH¶ljL(ü¸’¢Jç²VI4ªcUÍ -™¡©åhdÛç¢*Ñ &3õÄFá§?1¥Æ±eÖŠÐÜÌ¢ˆ·fœ-2”ÿg‰Öñ¥.s=ÉIŽr3.æùœËg®ÿw¯ˆþéºx ø3ÕůˆñÃ8ÿ£‚z¢¬¤qZ•U©Ÿ±5eksưh™o®ÁX̧„ qPU# ×K^¾«ŸÑ©bÕI“²é¥ûDëÔQ•:¢¬!0Zæ6´Mùá”r2Æ—:FŒ,º cô`c*€‡²i›$+ šÄô²²…Qv<á¬KTOò6Ç’ßJP¶XØz ymH~‹ f,ßr,KBzíÊñ(«[Kù¾ZZ8Æ~ÐÞs”ãw¬‘9\ŠÀk~ìÜxýùËh”4Q®òTyZpFjK¬04ŒÃn•ú±í¿Vù˜µìIÑ«BˆÕë¿ó»ÿ’óÏ{eF=zîSßGÛ ëhmÛ³¶¶Åt¶`ÒvЧ°ƒÛ*®Úžc”ZÍÉx„­­5ºnÂÖæ~0¸ÞÒw-JE‰”Sñ*:ùe1JSZêzÀR6”ÐhÞ”˜8¦I5AdÊ"/§BÞ-‚aª(Ã,Aë«m¢FÁ€² 5=U„Öâ¦ïØì[ÎÌ×6¦ôSó)Å04„ 1­'¢äl¼\oVàŒ¶që™NÌfs©éÈÜCÄtG9´ö³(¯àØWïE ŠÛ»ÿ>øß—}±uu¿û¿Ãý¤îÍ’zÉ>V‡Rà•VD…sI:ƒžkÖ{Op–颷Ou7X)ÌêXÄ%ÄàBÿ$‘DÓ.ÊX¿ÆãS»l(õŠ’ZRc:I…jÒ¨Z#I«äk« 5(kÀ:Ö¯· ¬B5j6Z“@Ž þhÌÈÓ†¨ QÉŒº¡ñt OÏÅ"Y²(è%qéÊÏËÚf–<×wJlç×*à¿oý‹#ÄqèÈ;Þr>·Ý¼?Á-Óô»Ž˜ƒ±DÞ•ÆL6pN"fp>Gó9-¥¬XÒL’úT(@¤!AH T5é<³ •a F^/íÞé¼4™3Gùգʵ@äzØê¼`ý=“¹u¦ 4-®ÙÇÂOéÞ}=‹[Ä ÍáÍ9n«% ‘^ˆ3M~#&.¾õR;L÷œRË &y.%ϭП€þÅÐ)8öÐ/þ÷0ùô“È©·ÿ7öî<Í¡]8ºH€Áùˆ›EÌ,bæ¹ïEÒOÄË@ÝÞa®Õº†G^KȳKÉ CÞ…Å.œæÈ[þ%rŸ /Ä9ò„{Ÿº4ÞÏÃr×ÑÝ?‹[nAD°ó9ÖZÄ9ܼqiŒ÷ú…˜ùÁñy_¾´f þÓS6s´·|‚Ô]‡»üžž!"Jîµã¶izš¯ƒ”ýÆ9Ýo zÝuܹîÝè¢38n3tÝè"r…?¾`ê ÃóëE5׋«^tÂÝš£_ÇŒñu¢ïxÜÿ¨ŸßŒ.X»’H’•ÕSOœ¯ó„ðÐÙŸøñrøç?âè‚V³‹ ˆ‹Àê¯ÙŽÌŽTáHäz±W±(hýl+TX'ó•ß_£ÏTZ³Ê¨¸QÅEÊÿFÅc¨Yy\pÎqV%íË´é÷/i„"E,Æ"Y49 &•q­š(ròqv>q ä%>Cc¬R¦GÚh ¨w|‰åÑÿ9nb¥Ügˆe’þ»¸ Ð\s-þ/F.¹”8ó»¿‹=~œÍ—¾”ùÕW?!2ÍLö´´J`­×ø?}sæ½ïËH†å2qË'Z-Ttã:ŒWѨâME@²Š†‹d#ˆSâp62À 2Á²U|…˜D!—h1UÇe²V„WXk]–\ŸYkåºæÐòãŠB”Ó$£~•T.cɵфhÇÀ:/’“Ò}c™ é,‰™ÜY=Ör°ågKj¹óäΑÚÏy¶ç ,øç?,\u•~´g_úÌú¦Ý]u²ó9yg‡xò$݉ì}ä#ˆþèQÂwrö]ïbqÓMpö¬ÂFAB€ÅJyMFd6C67ɾж·™¿ò•lÝp³k®¦Ñ¬Ç|Ž=v {ìfccJaM2ÙcÙmŸ‚ÿõú”Í÷þHâá‡uu”“ÐçÑ­(pѺã;p*R;ÍùNI­6#6J¤!.ÑT•-BPÒI4m•k*Ê2ôî6CëÕl²®«sbbÈ¢]¶ò(}Ũèq5š:ÏÝñJoñ" Ñ(·«’0E(¤"jj×¢TÚÏFƒ„’ú ‚‰Ò ˆ”Žš98$(š?µ:”´œk'Îdˆ±Ô­d]ðð¯~Dç ¾åa{súÎŽ-œ:ÅÞG?Jî:ÌÆáÄ Î}èCtŸþtÿÿ5[[l¼èEl_=³¼3ŸÑ?÷$ “=eí¯üSxðuz<ùØ-¥h‘ÂÙ"õ5,ýšÿҠɸñlÁ8ë>MQ’5}s¬dléyÑE§\E•~ŒY¡ko©SÓG&YÊ„©eÉD ™Ç™Êª«OG̦mH¢3œ ÖvZibÖ¤ˆ‡I* &–Wçt ¹µH‚#-g… 1Yˆ³%$GD‹[ÿðõŽfn8rHøß3}ŸÊ6­ÂšìIkîzDÛ¹ÝÄ~4i¿ø4°¶<>wˆdžý¼R /Y9[eý¾M?™Ò`*éE#Yg+*.Œ%шÆjta3©´™ÍV"ˆÍºÊNtePm®˜ô’ Q2µÞ”b+yüUñÇŠ@wÙ«)¬r×ZºòÕêx)ü(CÿH¥ñ¡ŽmYækkº+ ã˜¡SØ F£¦´‚ÅÆ¤ó!m‡I™µè±¯ /8–χî×eØ­4Ì¿iF´–_øc ¯¹6üôÝŸd²É>Kû‘Àê]±Kܸõ>­[ñ©ãY-µê8·=Ï£œ#<]Ï$²ÄbDA’¦t#ŒÆÑ H ZSæ8"A,ÙjZ*”ÆMÙQôŠIbt©´h„,Yŧ9VÑHFF¢11ý¾ŠV‘*2ˆGþ,{ˆ×(¤ 2RÐò’)cé;·š,˜Ò9²ôèBbÆflDk,‚ 1a‹€Hì°1Ag¡ë°)êÒÝ(Ø Ù•U`Yc•Þð­(Ž>bù ÿqƒN<¯ÿª†Ù¦gkCxó Ó51 Èd“{ ƒûÛ’fI™?’øþ&L—˜u-;; ¤kibË,-irËÕ—.±YñÛ>uø¬‘¢ã:)m‰$1}åqÛw#LF÷'1:—á¢:x+`#Á¸"É$kˆR¢cˆEXtñ’F,¶ôpJ¦T—QT ôóÔ zÓ‹ RŠD¢!=¿«¦²dÔÊã yq—¤QúªÒcQ±¨Ø”¾R> ¦ðµL@J_ “övI¥{='¢¢‘#&Ð7 #hºË¥@r/ &j´³í{oDöW+MãÙ3$ ï½ήß$¸†ÿþè&]Óð_¿Ö`œá%›ÐÈ“ÿ{~Ó,"=þ-·À»Ôˆ.×%¥_FxÛ«„-¯7&—4ðÜfÉ&ãí]æA ¾ãÆ“‘÷<ÒáŠPÙX챕–ÌY0gÁe‡ZšÜ2 K¼ÕÔT[ŠÔa²¢Û}îzG[E£²Œ¢±}åp0®¤¬L¿?%ãQ ©¤®¢q*VI·ºÏMMYå‚Qñ°FHFT`¤ŒÑ­Œ„BÄ X’Ñ(CêÜG©°¯"cX•%®}KΛ½¢?«F¹/8Û'$µçE„ͦßWÄæ„͹4 +äÚ2v9 lЏ‘`´çFŠu¿Iе·9j/”lTl²Ä©À }2LN=#*‰á\³ÅÙÙ6ê£sÎnmóמ?g{îùö á9æÉ¥$ÿß2só2âCËOß×rúœbå7Â’2³ Öhl«%_“#XGë^~ÌñÚ -]ãù“sá¥vÉž†v†–P+¥Ë¬ïßæQN”|·[îÙë8Ûf»K6v÷hbËKÂyZàmǦÛÅÛŽ†–yXà\ ÉŠã¶^SUU4\ =»Ê¢"hº*.–¦õm?qĕԓí/Ü`ѱ$+E`œŠ€±ÑèD»È©(ÙvLÆÉÄB6¥Þ.•BÑT*Rx]‚ÖýI,"‚`KdRÄcòÈʘóÀÏ—ÃRÁ(å•Y+Rz”¨¨Ð Çê8cKßz[¢›3.sO6Gºû´¹—¤ $ ZÏ `SPq™%¶µ*&%%i Ø¥Ð÷Pñ¹S\M¡W¨ ä̹f‹…ŸåÌöa~-¡]4ü¶làf3¾ÓâÒ°…cÎŒ§ $ÎБÿ‘¼•%>tœØ=Gwn‡Y\ò‚æ¬"’’ª;ñ¥†Cè¬/}íÂ.KKâ`­k8a,ÿ¾sœm¶ùeñ\|3ž×±Á–Í'™ËžVaMöínçQvÎMñ_ÒO€;«4Ø`´ÜGN~ׄ/óÅ¢´BꘇÖGf,ih1M¢ÉÚoÄ6:Q^ ¼&'„""U4]dŠ mqE\/ ÉX¢˜eؾåhG_Æž(Ž$åŽ4Úö4÷• N%õH•Ç5~0ÚŽ™[¬¤¨ÆôÂgs‘ʨŠp@EåËRÖì–¿$÷ÿ§‡I{‘‚¦,$ÚzN0ç¥cß­c÷1Šî4=µýìÄËßtn%Ú‘¤4b“Ê{—ö±ák¿ùnA£Æ"|{~£¿[?³y˜Ö5D±ì5 %ŒhŠòË¥|¹\Àår1Ïá ÓðýQåö|÷¦=~>Ý£i¹ smìqèÜŽ~s˼]ÄaR"aXÚ %ò¶¶!Kg=ÕïYåºåU%kÞ)Ç úîˆ_Á!^Íå|_6E “=£ŠOp'o£Í^ ¿ÁZÏ=ݧ9ö­SW.ìÇ’Ñîy]™kˆÊâr.à—]Õž-–8ðRýø2vE4Dû7˜Y›NMìç1ªˆtâWzL×mˆ* ÑX:ññDiÌÊV£ˆˆh4A®ýªãÚ -k+ƒ…™³lµJ6BH†Jæ>ˆO¹clØ]^Èë9ÌK>¯ëaÉCÜij×nòÐbÉñ|‚®ó|UB¹T9ášÀ¦ì²aö0.êÈs¡3Šf¯ £ÚܰlgtA;G†ÎéÊ¿š´n [‘PÆbj­.Qÿ0‰–+ðt¼Œ¿ƒã‹[P3E OG[>§~·Çk¬^äB ÿŠ(ïÒ¦B{[,sÚEÃbw®M‰–Ò‚³Ð¶ö@{ŠˆÑî}9Jj°¶ÐDÒD}TÈž³Ú:Ô6çTPlq&àfi2Îgd–1 ˜&#^É8B‚€§333:¶è˜™Ó±¡ACdN !јè¢'2ïÅ!âK”à{!HøPc‡DSœ·+Q†ôQ#¢oBaGi§ o4£±¬±ÈúÌÆ>{øî–ã_ 4_2{ëCÜü_)ÁMA¬ŒŸcúï ¸ñ€ñx›á³ï'%#öÆþïá>Æ |'dçÑ8 ßý?Çó¯ÎéÅ?ãäéc¤dèZ_ºbê÷Ýù€óë3n#á\Rv^cIÖ±ÇaΞrœ}°eggYX¹ÝÂc|Rˆ¤¿©‹BšY‹Ÿ•V óV[&”®Öjš\é½ÞxyÑ(Þ…À¦ü0&>9ô•Ð\< È$ a·¼ÞÿŸ¡Ñø1»ýÝUÙ½9ñkŠJ·Œ°åÍz'Ü.ÚNÉ ¡Õ†T!¸Þ™ÄhU(Ft_)dÙþ®©"Þ‹Ì-ÒXLcÆ ^0Þ s£ðÇzÌ 2·ÊöòNyc΀ódïÉÆŠ@D< D\ÙªÓÌÉ8"ŽHƒ&<‘¦DžˆWá,Ç5Aã{ÇŸp£±-þÅ‘ KWPãºPÔÁì Î uïçñ8XL~ýߟâ–÷ïö“÷ß²Çí7ž*ÖhGQœ~T‰ÇYÞ³¤F*1|žxPðÓ?GöGë‘J^]A¶E_qôcaÉYÀϹø!¾áU7jú4þÞ·þW]~\96!!1AŒH—`‘` DjôYŒÀÌÀà ÙBjÈÖ÷œ9i,8Á4¦ÿþ²1ƒYCò3ºæÉmÒrˆ³íQμëýìÜ|?áÜŒC]"ïcPÅß IDATzÄdü¦.i6[fÛKœ̶–*VÛ%Ôk¬Çþ—¿¥!õźBRVúîÈ¡¯yìÁò%Ù‹¿ü™) {{{Ü|óÍ{"h¼_HËË%ñÔ)ÒÞžN–Z/ŠU²¨"¨ˆ¾ïûà–©“÷F×(Î݆£‡àØ!²µ„v½[naq×ä°‹Yì(ºÚ*pPÌ@÷\6êKŒÑ%› ë _ÔkÕ”ac`s¦(ê¹/_7ìóŠ©–Æ)uæÁ+Uf:9o )]S¡Â {º¯/`HMS>!Ù¨“Öh–È`Ö§‰Tè1ï¡×¬Œ«0Ú?Ì)Œ¿í¯NÞö«žòh‚6Àú^‡ñâÛƒÄà ÑH >úá8rì™ô¦G¸ÿx§K¢\âÜ™À²…¿UDA*Ìqµ÷H?îÓR#aš"! kÈù"‘±¬¿@fU(ä<ÂHDJ:‹ºì5I!ýŽÂY”ÕU˜^DÃEÛçð’ ƒ/ÿ’Süàwþ>„ÌeE.¿´ƒK•þVY¡fô°n ûúB¡ô{]¿¿3¯ÌŒ%¹ 2–¶kعñcœþ÷?Çò–{9lf^´;ü,ÐÌ4U›}ÆUl½Óζ†ÿ­ÓZ”Ë#·…Ì1HsÒ.,ÎÁ™hØøîÿ‹?òGžþ4ÞÞñŽwx쉠ñ~!-íî²¼ãÂCaŒÁÎfˆ÷˜ù;ŸƒµJùuù®ïBæ³Eíœb¡-_XC:{–öc§Ý¾ ^xë=¦i”ê[¨½Æ9¬÷+D_Düzýâ;SÄÍ =9ú÷dÀeK¥ø2€YGdW|¨ χ5rïh,f¸petáö~g`ðº}ižóÝÉÃ~B¯¬ÌìO=vË¿¼oѬ|†où g®zß{îIüÌÏv}ôræŸýðYpiõQE? ª8ýÜ#áµ÷íûmòè°þö£ä¼)©µCFÑ€ä!²Ï$ £“rþÌ©°¼æ$¥Ð‚³èï”F)¯8ŠT¢ ‘JNÇ´—‰1 ¿óáánûÿø^ØkKwB«Åì û M(B5Ò‘hh±Ä°ZÊ¥Á©ÖÅ5½‘Š€T'jÆÃZP0$«QÁX,öEk)¦Ï4ÿñ½Î8pÌçy{E(uiŠ…tE8ݶZÖŽÆþîwÀUWêßó/þoš øbYwâݧ?ÝÜì?ˆ8‡¿ì2Í(<‰lZÆ;ÙdŸ£½ùçà·>TÚÿJæ®û27ÝIßR8_&øÒ$[—‰ÎèUW™õç\®ÆzGnGJ`󬧟Ò(ÒH#Ç›GSW=U'¼¾”v=Òà<ûòyRzçÉ\ ÇóÁÕÍèMêâš¾2#1©¢V…´—ßÏ2Ì‘ˆ”Þ&…3Öi/@Û¿†šƒ7ÿJFJã¬ÿþAÁ üë¿'<û¢?øï•¿äü%—<%®I@&›ì1ìC÷fî?©Sò÷?šù?•zdü˜ô+eÉìÆ—–>õ¥Ú˜‚DIÖ]¹â<šðÎR®ÀÚr´ìÕäAê|ÀÊøh’™‘€Ôãý>Ù¿¢i¼âiÅw¯‹ˆìï³~B|&!¯ ÆúrbˆFLý;0Ìå˜ññQÚˌ޸F#õ=‚&ºQ#úÖ Ÿ;(Æ^‘ð?OèøŠ7r~è[…=ßpÝs…g®‰I@&›ì<ö}ïÎ<|V‘6GÞ}kâîZË‚À±çh£wsÏÚª¢­E¤0·¬)˜x½3NVÀ ø’ƒÊ¹ÐGíPãÈ™¦‘ó]е¥­ÕLädz:)F Hú&TC*R] ~@M|^õûYÒ—ÒP«ïÌHìù_ãeÅãÞñfm\Å¥ŠÏxA­{ZI}™áù¡,ÉhôQߺô>11)·-LL¤d°1òÞ+„÷:nøR×XþÔµ–?z¥LË$ “=“l'Âm»eý|Î,ºÄ·þfÄG%›œ8u¦#G­2ö¹ƒ ¸ìùŠ’HÆèZ|£QÅÔˆ`µ">íR#mJÉY½âìhªŒD#×ÕF¹O­ôBQ£€ëVÏ—¨©—Ú J 1(üPbF$GYa‹ “ÔyÖGåUÕm%çV£4eZŦŠÄÊ¡¡U¯öƒ/瘡kcEÒÔþ)ɘÒX8Y!¹ò·tE”K³.mþ5Œ±ôÇúÈÄ2‡ý-ëÃX!‘ ³n©¯˜ibKÎBʆw‘ß½ß󎓞ß3|ý•s¾íYŽ6†+æÏLA™d²§­ÝØfÞ½ðA¡~÷ëxûñ%>vÌÚ%MhÙÞTà]å3=wCù[Z®l&£·å+tß`µØ²3žh-É(ë(K°®‘`Æ&WrôbŠ(äaõP.©”.aBÆ„„têÄúŸcÖãh/=7a»2.Є2.?K.w×it§WE£‘5¡è»Ž£’•lÕj•ùº€TÁè;.Ž"‘*ãG²šú˵ŸJŸ–è1NnØFo‰%z=%Î,Ñ’7dgH|y^cúþóØR ,2F|èhºMЋœ#.ê÷!£l¶ÿvvƒ·lÆ:ÜðºgopÙ|ÆŸß²“€L6ٓٺBDe”áyŸ´üTÞEr¦I-Ë=]¶<´lÙ\ìbRb£Ýãå‡;=§ÓˆŸJ}ŠI‰`\Ÿ*éŒWDF.æBé­ÑFg¼b¹­Ã}n­ÔÆõ©«lÔùº.aÛ&LŒØ¥öD±Ë€]D\±mÄ.c/¶‹ÚÜ©ƒ8têøm±!ª¡‘¬c›¢Fk¢QÇ&éß >`¿€ä‘€° «ž›×¹YU@*iXÖ¤lûö¿¥oK2šòªâ‘¨H—Ÿkj0£âál/&Ù ¡q„™#5º/l8=ofé6=±Q\zܰ¤™Æ%\ 4±Uðgì˜Å%³¸ìÅÄÅ@FÓCdéf}ƒ²·¶‡0v“wì.ps~¨ÑÙ÷ ˜M2Ùd_,û7³H‚ô’:ù{ò9~!ß«‘A¹;¶6rAÎ8˜§ó¼à2Ÿhhq604]Ûcµ] =¤Qr¦3ZTEE¡ökè¬ï¡ž€%dG@º¯ü¬öïLÖHƒ!G”TÀ´ »Ø.a—ƒPøº¯‹˜vˆ$lûI^ÛÅ^LP‡o;¡HÊøöI#qˆC¿¾õmJ½WdÆ8ºè{«&; ““d\H:3¢ W­Y¥ÒŽ#“>ÝåLŸþ ^Eý–;Ð%- Õ¹&ËÖ‘Ìå/n 3†™#ÌÉÚ­FĘAnqã¦IXqÊnótxép¼éúŽ˜BÆÇŽl„E3×¹1Î9Ï›†¿Îµ¼œ—`±“€L6ÙÂîÏïåSñ=„ xø” 9n ÷hç‘‚‘7&‘³ð5F™A¥—VjéÌ.™±Ä¸¾³”KŽ”{|¶Þ9ß6{BttÁÓ&WÆŽØYBtåa‰ÁÛ"Á‚%G!«¢Q±ö±Š†é«¾r$‚m5Ú0)«€tI»ú-6jJŶ±O7Ùû\½ ©O»HT‡^£~qüu\Ñé½€$üï÷UqÈÚ_eiÈh î>y zÉÊ<Ȩ)Ö˜ÓccFö¦W²ÓΆã}Ô2<±Ÿ¨/-„ážû6 Á¬¼ï|3qÿóô¼,M&› ctîD4:¬“ò"™‹¯Xðª7<ˆkâTPÜ,*mwÖÒøN‰Ó¾¥ñ-~pMÀ¢l8‘Ü£Ø?λJ+ß+±"lp”/ão>m®Û©p²'Öönƒ½OX3³p®ý>ö÷ÐužÅbNŒê Û®Ñ»Ë`T(¬v²£ÑEÁù€± nt>`|Æ4;ËJFm²~EHÆ+`Qtl°ämh8w÷ƒ,Î ÝÒ+}¸st#EKÛybTèJ¡YŒ*$Š DˆQ…B’kåsR°êl£R‹¥LˆKíò×ELÈØ”0ËÚ##ã–Q›9Å!º¨ùyD'ÍMÖqMIÕsö #¡]âµÑÔJD!«â ý@ö Èy£ŠÏÆ >´sÕÊRÝ*?zÛ7p&lÔ7«lM˜FË–»BññRÇ?ŸöxÐÓòpÎw|×»™o¶ˆd\xé oç‚#g˜m.˜Í[|Ó±¹½ËÆÆ‚ÙÆ’Æu‘Òö ,3·dî3[ægKýÏpøUS2ÙÓ9Dø¼÷ǾVÇkûÏý>ìüÞÚuXòÛÑà‚g]Õr(ï 6÷9rã’2ÂfJç?Ð}¥±ˆâwÛ(ËË7à¼>ü Œ'È­l“hè˜aØÂcqqîºÝwÝŽìD|0ØdÎ1KBŠFIÄRÔˆBrVÑH ¨LÁ”ÕIzŽd]•b(f E9F tø#4›PÑ0¡¶•ÍØ0ˆIM9ÕÔ’˜ÜGƹ YK9•eÆõç±PôçÊp~/&¬>ç3 ÈNÜäú/•ü—®>·ùS×­¢ãëë”&-²?Š Èʾ>÷µ_±òc Éâ±NÎ쯈_yê_üÉŸüú•eÏ×_s9µ‘¹ïxÅÛÙØX`m¤™·lmŸÃ¹8|²4ô;ÉéëŠ9wýãñkÿ\vÍ<‘ö¡}ˆ”Ò“žÆûeig‡´»[®-¥°õ¤ßºµ…&Z~ÆZÒÞñÔ)Â_øÓć ûI´ \”Bë# bµåªí–°8UØ~…î[W³¸²ÖÞ–÷™yØž+îzÞÀF£ãÆ“ç 2÷dkaÃ#Ît_ga6ˆ¾3¯aËñB6fÖèJ¦  ì‰¾°D™KYw Bñ=w÷œüï¿ÈÉ_ùU¹®D¢‘N†œLih¤±¤Er’âuÉ­©µi-9”~l$KEìʲ †ˆnSîË´Í” Y9ñ:`õxÒªm‘R½mò>+c¢ë¨Õúúxäôÿ[ê1>úȳé²]€×?ðdýðeâ[x8òÀ×;j9˜¿•×DAÆûä=8ß¾üø¢Y•Ñßàà0dôyÆÜ®RWã%pl¶ƒ$áu‡ƒ¿ø¬ŸÃšÌî~.0gú7•ñµBκ ³cHrÐAl¡]ÀrÚÃÇh^ó6_ÿzüóŸ¿ä’/(çêi¼óï$„ð¤§ñþAYxøaƒBΧÔ]iLÓ Î!M£t8kï ™ñôiŸøË?ö­äåc-ÖZÄ9l¥üzª¯ñ1*$â]#QD{_ÆÕñƒî}«ÈY]F)õ˜ŒÈ¾bâo%÷Ь’{Wˆ¾f?1U»÷NØ—}© twípؽ”æšCÚ#¢^Ð#?¸*õ ùD‘û1ÉøxÁö¯ãûûsÆ"?öïýù#Ñc?*MÙ¬ÝiWá^!È2¼ÆJ¤8þ{¯¾ÌÎYáÍÿf^jU4šxËm7°ýu4¶ñX)ð«E€ëÈö¢ïš(¤•É’QÊHÖÎ倯7<6Üñ|âqXÈc IÞ‘ÿNdȆ.É|~æÔù™G¿ :ÇŸØø-^âîâµ_›ùêëG7{Ö’S"'Eè¦2N]G e®&%+3Í„²sãÌOždûúë¿è2ÍLö Ùioo-%òÆùŽËãwX"Ÿcq™|EiñÔ³°sn8áý¿ ?ôÃÅQÚD—½UJÿ‘¸J– ˜<Çœ-‘ƒÛ×–4N¿/­‰C^{Þ>á8~åñ È ý?¯B×ñ*’Wú³ -~óêï¼þ+!8cŽË/´\÷"ËOý+½zÖ¥OýâÃid²g†ƒÙÚzFýÊ¿ò¸÷Áÿâ¯Â/¿kR-¹¨Ëój+d3 Æ|®ÚðIÖû:¼q¥ËàX4¤oQÛ‹ÊsKFó9õõû9œ²KKBÖÒju~.¯Ô¨Œ»6Ž)c|Jýfô «é·d Žã­ãø‡…˯×`ýÇþ1ÜðJ¸êù“€L6Ùd_d{ÃÂéÝÁ9~àcpâÑ5±x.£»çq¬¤¼rzR­šÓW·¬5{Z‡Ã"ŠM¡àTjÅ{!˜µâE)Ýêëb€ñþõ}ƒäóÄ£z“ñ¸TȯoSI‡&)Ÿ@ƸCª ¯ñä—9 Š7ߊv€ÆxœV’‘2ôø¼^ÔeÈyàc¥¬¾²ì·9*S*4HR¦ØÊƒÔ³Èê>´²¼x,uYñÊê°¶çMáõY&éû‹¯ÇAã,$L‘²­cȈÖ•º¢ZAÖ%cJíIá}1B®M¶õŸû'þ2¼újxѳ¦d²É&û<íß“9~vX‰õîÛ…O>”‡Â;\Åê¤îú„õx’zLôíW"‰,=7Ëž¯UXQ=x°D/E lŒ½H˜T£nÇâÁ ""C}K#ÃòäÇ•ñy¤OU•¹—ƒD£ KÂìÛ&)ã* ¹V÷ñÈH¹©tæd SäMt–à\¿éÿßùkðâ›àÕWÁÝ$ “M6Ùyì#ç2) i›ïûpæ£DlN¥GRâ¡=a‰Q<¼uäK¹l$}©µh"1"÷®Òv%)ÊÄåk¹.຀ÊÓ²1b%â*èä„-äì…¢D6 ¢asTHiEj:j<îSUR+c¡öE U Æõ-+|®ñ²g±§²Æ)¬•H$\.2UîÊŸ³H–> Ñ2«?§”h%ZÛ3»¢±d¯È•`y.´MÃÒÍhg ?gÏm°t3‚sÜd 7="œøø/†—n)ƒsÉ&{†Ú¿ÞKœì"6†Þñ¾åSmPGlSTTüE‰V¤GÅ;둚ñÒ;©>MUðí•‹e[ej™®¼nq‹€ · ¸òþ¾íT,‚ ˆM*.…^cÖ1 #E0rT!‘")"f”’’ÜGëQÅ ˨R^HU ûö÷õ+c¼Êz²¯‰ìgœ éNÒG½€Ta‘aE‘;)Èc¥¸ ì1YemE¯ÐGÙδMCëâ–eáæœó[,üœ3óÜo³lfüÂ|ƒŸ¿Ûð>7ñ«š'§ŠL2ÙdŸƒµ$ÎV"ðÈ~˜nɺ߅À¬[ò‰e"tŠ —œ±1rùEY±ñ)yómŒVÉ¿­iz #Ž·Šy·ËˆÛSçß,[ü^‡í"~Ù¦VÄ-¾í0)õ¢aRµ*.ÝWðð5ýärÀŠFÖÄ^8Œ ‚`s\ëjÞ‘hÔ9 3¤©VRUk㕨£,“=°’^VSUç‹>Î+"ù€d©d4ÉyØ_£äÒx+ŠUöY¢’„FbKWJo0ó¤¸ù™ÁŠ´MCœYÒ¶aáçìºM–nÆÎü»Í&{³ 9r!;›‡øigy§/CøQ¶8ŒÇc&™l²§Šý>!–;çj·r†ÿÁ}½#ªÇ2ÂQ2 £wñ6ñÒMílW'^sBvÄl‰ÙÒeO,”ßÒ˜–†-DH²·$dìB£ · *)â÷:Ü2 BÑ•†XË®O%¹6ôBẠŒ±ûè¡OIIê#A'Æûè¦ÞÙ’F%UÆBaJzÊŒÀ‚U4Hû£‹òèE¡¼F¯ˆÃèqÞèCVÔC7ãª÷µd¼¯@òÀoëS\©ˆIYT²)ÐÏ±ä¬ ®„Üv#‹lfÜá@7óäM!o ?gig‰4[ëX4s=|AO‚Žb9ƒá¯Ññz.çå\ÆU\1 Èd“=Yì wó‰ôÕiàÆFn—ÛI$uˆ(»+by ûså¥wÁ‘ZC ŽÐ¹žÞ£>ºÖô»%¶åN¶3ä‚VQþVqT6¸’ ‘Gפø¢ë#‰]ج),ctÙ¬ AÓbIÛµŠÍ}Ä!9«Ta¨QD‰<êï]¿‘ÕhDJ[Ùú¼:ÆÐ¿N/EÚW£E°Œ„ÜG@ÖSYO„€¡G ý6 CRÉQúŽ…ýkXé[›„ÙHä™`Eì‘HܰÈV&ZÛ¨€Ø9­kHbX4sZß%ÊAzºï#$>Àqq1ˆ¿< Èd“=!¶óAhï_Ý'à‹7³×ýPOÿIO!j×Àg•Ì€ñšž±.`}ä*2 AʹˮaÙÎhÛ†å²!vŽvé ­'C»hÈ!u–ÐúñƒUgSÇH€Ï9 mkS2Ãäx*0Å0Ì-ØVW@aÀ/»ÞQÛ )'!0eß8b0«ãšªê¿M}zªŠrܘ‘`´I}½}ãš–GfU,ÆçõãÑ–5®×Ai¬ÇóŽäuŽV.é­"ýyu_–~ÝŸFç â!6ƒ³©b¶îHÀ¤¹!Ï€FhiXæ!9â®Þ\ 6cLÂù óP%¥HY2íL`&KNÇ¿Ë6ÿ›ž Û_ ÍÅ“€L6Yo§Ãÿøƒï.ÍÈ©pòÂâNV VF¾è=ÆÍÙj¶ÉÞ‘½Ë{>F/V1y…ŒQ·¡s¤Î)Î}9#w¥‘PçqïÞ-=… ±u˜˜Ébá%×´HЦw`)™!¯_šcÕóĬ!ÖóààMæªP¬A‰°¬D}Š©¤—¤àIj$²r|,Uìè›{QÑma£•­Xö–‘v¬?30ÑÆÿCƒ/š‚‚©ufM Öh"û¿ H¿»Ãêµ6Ly å>:Ë8erÈÄòœT –¶0ßfÙöÈÜ!G60‡<é¾»iÏv¤`1eow;]–ô÷6V#D±ßtÚºÀ$œ 8TÀäNážtßI^€l=ðø²oƒ+¾z±i¼“ýÁXx挂­Uºo!âŠsˆs¤Å‚ðÈ#Ãy"=,°Ò€E¾ë/‘O= NûT‹‘žô+Õá؈R~S€½‡asÛ…îë•Î;s°9S˜Ï`óØú:=μVV7^Y‡Ïûn„îäIÎüÖoqæ]w¨Í«ºôEr)f$u˜$¤>·H64©`“l ÉÜb³`µŠLÿ’ðc–LÙØŠ‘Â¬Îºì·úaÄ€±#‡^Ƹ¢¤ÆêïîRŽmùZ£pKkû¿¯Ô¿³+pFkzYEÀ–ÏkÍàô­ôäç¹þ0#ã:,síaF€Ì¾r,f¯H® „å3·aM<ÈÜ{¼áÄC~t,þÜRŸ«ÿ±Û.áþø ÃùEiþîŸ}/¯~é]å÷¶úH˜ÃnÃKŸ 7ßÌÞÏ'=ÚÒÄ€ ‘Í”0.a¬þ?Ä£¿AbmΧö—‰¥e@DQðñ°Ì!Ç ò¤3BºäKH¯{ñk¾{É%¸cǰGŽ Þ?sd¢ñ~¤ëhWjï|ŽÏïï1››°µEvÊ֔ߗÁa3Aè_xÍÚ¹Œ(ÇkŽ{ìØ…Ñø€ç­€e%e¸%° ‰”µpa¥*û58ozêüÊqçðþkTÝAD~õãw~o{?õwüÚ+dw9OHç'¯âÀÎZå=ÿþ_<޽õ…l~ìbþ|úI¶.½˜sÇ#²àÇÒ_+ê•wi\mS*Û)‚ -þÚkñ_ñü—}\|1ËO~’|çl\{-ó«¯~BdB™LöÌÆ!„ÇvXç»`Ϲ÷õä³<ðD”ÈS”+pâ!(Ý}{ûðGà{`Í¡—¦VgÎdn»=ï¯ÒE˜û©¾²"&˜w4©O^¥9Ž(hdÎ%MYz¤Ôq#K^h?Éæ‘Mþó¿ø4{ï?ÉCÌ/½„têçÞóº»ïFbÜ·Xw ¶·Ù|å+Ù¾áæ×\ƒ4þªó9öØ1ì±c_Päû$ “M6Ù“Æ= ÿõW>ö9Éyé»Õ¹÷UîyÔÞ·xàq!ã¸Àq¥¯ä}µ)Õ…«þ¦• k¼˜8•ÔeÊe=[ÙFtEÌÊÎêq4ÿâá%|ùÕO½ÿ×4‰>Ùd“}Qìô9xìîÛ9¿ùö¯dÈê­äâ‡2~Œ— ™[ýâƒ*áGL­ÊÝלì [Ö¹[#yQhb*¢!–”upä,´Òô"³ÿÛ?f¸ú«^?ý&™l²ÉžÁö±û•"&oWIDATáîGWàÿüÎ'Yeve†Šõ<<æ——âG‚VÅ3brQ Ëóê¾}È”q\ÍÞ2ŽDÀ°_xŽ•¹†G[ø¶ßf(lÌ )qn™9»(`Äœ•îk^ªÕñ.|êp1¨8İ"ånUþ–%öÅŽ,¢Ç’f Å8z0$å‹å¼/’èEã z¢ót)¬b2ÆÔ°&*cÂoMY%ŠhàˆbYÚx:ñX‰XZÓ 6k"Ž`œ‚“N¾Ï¿{ÐòŽ_²¼ñjÃ÷^ æÉ÷=™d²ÉžÁöKmæC]¹c¯°@àûï)‘CL=¹×Mò½‹4]Ëaé¸È¶JüÆ´¸¬cU|êzðQÅÃJ‰:Ì€7¶~KšÉz'n‰ý¿ÍQ…¢H’¡sœ(Š©´Ý*$ëÑÃÊXF¯qØ0^¬¥km«ˆÔ$[aÖèÃÛŽ Ž…#.k$b841ŽNüPõŽh„’{Þñ£»œ}¤á·áëžd*2 Èd“=lÀ^u¶#ïw'ïçÌÄ 1sW2|Úê !H—qËÀå›-® JúÍ>w4a$]«DøÜáœFžN«¦£36©hˆr¹|ìT(JÔa\ê#q:§QÑ%–Ø;ê±TѨÑE÷ý<ŠUa©é%¡œûң݊Jzñ£àщs„ ®ŸóhM£¢áæxÛÑuã“FNQ'Qt.ÄIèÓ}QÊrh Þ±lfüð;Køi±üÔü¶±Ì´÷ð$ “M6Ùgg7q »,ö5Iº‘‡ø@~˜˜´WEL eŒ©¤W¢!Q`.Â娬­fÑÒ,ZlŽÌ–K”îK§:Œ”‰n[P)àœF.é>cu.£ï-’‹P”È£ ˆ±©Ú0« EM#õBQÄ¡:öñ8§Ú/“-çæQoó•„ã^ ¢Žºo徇:B–aâ¼µ ­ÑÇÌ-YØ9 7Ç”H«¥aÆ’M»«s&Iú@AÄÔ¨Mlîû³  ü2¯ãb®çR®åªI@&›l²U{€_çÞ»²XU• ÁíÝqÎuQé¾Á¢æÐc´\Ó9Îö°¿†>)”;ó¤€@#IÑYU‹ö±¢Žß‡N[VŒ¼±* ÖFÄfMSY4lŽÑ‘z¡¨M©ª€“0^…E\Fœ.§­}Ä«hŒû¸µl8ê9µÞb,,ãm}þXTêkôbƒY™Ù×7dÔípü¹êRÝh,­™Ó²I+ÂRælìœeqæ,›K †Ô*ÙÍ5êÉ4ó Ø&âš’Îs¥q—þvÎè¼Ñ.ßÅr2_ÆuòílrÉ$ “Mö”·ááwÀEa%-’ò'èâÿ­=@0›Ééjàè–3Ž´ž®ótKO×zbgi— 9[®–Ð9½ëî,9ªs«û `àK 'G¥ÄöÅÚ&‘³ÞùV付¬©¥P±OCÙÕé×N„¦¬Œ2*âò Õé•ý5ºè·.#Ä•G?Î`JG?cÈ¥–"‘H%E”Äö‘°¤Ò›ýIx×›¸ÝÚ£´‚(ˆ¥@¾ÿgF4` YVÏ3£ˆY‚YZA1,3m;lõŽ:Zbgµ…jé%‚ÑqNÑôØó>RJ¤+m·’wû.ÓnRO";ê@X#›¯tYñêP-`Eoôè â)û°q|ÙçFt^'#¨£ø_΂’q$ñd1$|ƒa¬ÎÚ“Gûs¿È×Ç^…bXô«ŽÞŽDÁöbö ÆX,Ø7^?G?‡#!DJnÛb(•ô[¶•þKÈÞü¥o)äÙJš| z£ÛíMؘÁf3Ð}·7 iHÝÝñ{9{ㄳ§{¬#Àn%ó"ˆ8¥ ‹`D0H=‚Et›Íç3º¯%³Q ‡SÖÌÁ¦"JÞ¹WZ¯+¿Gã{"/C¬޹ªl*¬Òލ½hid´¿-‹“¯Ç+Ô±Ž+ÀÑZa ûÊðØC"+PÒö¿?ÆRÄ"Qz$‚Á"$ÜÈa[†E¼eΣˆ„Ží…8ðiÔP$BÂAÌJ´1̰"þ1<ÅÈEÐKZd–ïýíÿº süÓr‡mG3̶—¸Í¨Õõ.•Hlè…‚•9òõÊü8z$"o{,ÿ ,À-ç¾eçØ]À™£Ïáèÿþ&¶_ûẔcw²gˆ€tÝý÷³÷ђΜÁÌfئAœÃXÛMÙ'Þc\ùj{‡ü³SgÕ¸ë]¹óuýÝog\ÇFÇݽ÷°¸ùf:÷JòbÁЖ{LñÄ:Ìø3![ÙV‚¯s•×êq;óÐx¬µƒÓ-}pÀcŠo™T;ëê …Ü;F§¯P|Í*Ñw`,2ÂЯõÜ8ˆÆkFKLåï:¡w…ΫŸÏŒ´é80`ŸCß¿}çžÿœÇ š”UHo¿Í}È)Ú;o¥=;‡—½{Ù½¤[o&Þ| m·$Ý5¦ÿš)¾’îYã^ʈ_èò=…w4Žq؆´ °„K.Ã]{ [/{²\î½—fkKo>O›`Š“Mö8" ¾GÄèªþ¬¸¶—â+Ÿõ+Oö$µ´»«ólmK:y’îÄ vo¼‘xò$ÍÅ#;;œ{÷»YÞtùì¦í0FVúgÉH¨´ŽSÈÞ“ç3’±}ð!G²ýêW³õÕ_ÍüK¿Tç‘D ÜÑ£¸ /Dšæ ý'™l²É&û"[8uŠsü Ë;îÀllômÖÛ»g@š†ÙW°qíµØíí/êçž&Ñ'›l²É¾ÈæŽåÈk^¯yÍSësOÿºÉ&›l²ÏÍ~ûxä\XkJ(<û(¼ìyOßßÉ&›l²5ûù›à7îõ)ˆø|¥ü°w|8•W‹Å’^p±ðG®‘¾ÐQëY oºÞpõE“€L6Ùd“=éìÎ=8Õº޶døs1Yé¿6GLΘ2ÞYdˈä²X8+_¬þ ŠZiežwhÌÆð) î~ñÅœ$£Û Ž_ÿe‹m,Áx®ºÐñO¾ÂÐXáEÛO­“€L6ÙdO9ûH ¿¸›Ôù§¨Ž?¥"‰ÿ÷ÁÀ'w|¼I…Õ&'6š€ñ]ØûHÃfíÍQSªyd¤ß7î#RÉÀÛãM‚q}´Œ"N¢(y·ŠH0†Îz>b=_÷aËææŒï¸²ÁXËß?æŸÿ‡I@&›l²/Ц£[Ÿ;(¶C毲Ûw-t]èIÀ.δ÷uJöIiÁ>t LC¶ãG²"ã£F.…^lŠ}42Ž.$çžø[E£žWÇÊ(ä¡¿9B4vU4Äí¤3¾dÊy¶TÔÃÒÏøÙ¥!9Ë{ö¶h›†c·ÙF8ŠÇ> —wO2Ùd“}Aì>Npoú49Kÿ £[à­ù^îOËR'+N\$³U~¶ñ]iJ%*åÀU6Òäk£"åS@ŒŠ†IƒPT3)õs6kc§:Ÿ1îRX›Rõ}DŠPô ÅÕ· FåvUÑè¬WT»õëúžA´µmyì‹7)dƒL6BðŽ™dÞT„ìÛy/á2®äÙ“€L6ÙdO}{þ×,Â9årECJ¢ãBù=‘Ns"Ÿ$EC*À°”Li)žyNž[¥úf-í76õ­j­U°3¥)UîzL¼›¬+ÐGI`×DƒÔ“Œ%ç +äÞqzþ:ýwLþ­Ç"–dT<‚4D‚ÌéZ¡Ý‹tÁ“[KN–ÁB†EShãný@ÞµNxYµÏŠ ÜMd—-îãsWó''™l²Éþmq+,>yÀ!÷‘’ðHøvBp´Ë†1Z%'Û#äÉBµÇ¨8¤,ê¸-ð%’õuK¯ 2=šA‰½¨Hô¤ßJò5Yû…ØÒêÖÀ£ÉŠý° S(¾ÆäÓ"2ÐxÅöÄÞŠ{¾ž„ï·_¨º•êëû׉¸BôuåÜú|[(¼3" O—fìÞ}'{·}а´lµÓ*û¬ñA…Í%šME¸ûy7á,(‰· Ü½ïð^›tmÎwÙœïâ$ðPü«4ù1ß1ƒ½½xÉ&›ìqØî£ðëß­wͪz½R‡À*ãÜïÁîï)“1^¾D)Btl&íRC™΢у(9”ð[É’õ7a$ô_›ÁYÄ+TQœUНS–—x é×"Y‰½b²ô°L‹8ß?W¹eVYfÖ’%GKD#êäcïð·†PŽëšªñØ÷ÀÆJôU‘0%žq=¬±’‚U`š^`–îpê·ïcöÉ{ñKáX±Ap61Ÿ«øÍŽf»Å6á>ïpMÀÏ:Ä d͘ԧ֬Q¤¾äÒƒ>> áÁàE°õ*‚<ø¥ŽÙ•W®²Éžé2Ñx'ûB[Z,ˆ>JÜÙœ•è+‚Tb!ßɘø;"×s{a…öàÀÒÀh¹$~û7иŸØ-{<Ð+Fz˜£”»jS(¾Òs’2æÜCêtŒH!Ö»pÊû©F¹L)¯=˜Q[S¨¹Ç‰¾3¯0GgGãº5Å×=ß{ýÌ®¯0HWH½Þ(¾•è[„ ’{ÍhOôuû‰¾RÞJSe|Ï?¶+X÷uНô˜÷uÄûЄÌ{îé¿õV¨À©Mœù½ßÂþÆ]tŸ¼›cËÈ13;²E³™ñ{c›%Í<`]Áµ;ÀdåV–”V/òcÁ{oa…› » »ôˆùQbô¤]g-Ý•×b¾áØxýë±—_þ̉Æ;ÙÔr&;ÇÞ­·²¼óN]ïß4JÑmìl¦ô_çâo9`ª,ÇzºsÅY–KM„tòQö¾õo±¼ýòr9Ð}ûfOã½>œëiÃ"Ò“~ÅZÄû‚±¯bÆ@éQ‡n«ûsí*ݷ컆_‡Áé#±¸î¯Áõyuù}Wɾ}͸BýyP³NîsÝ%E4ÌJznÌÖñíÃsÎwîAé¾Õsòðz9Ó|ˆíÍ/áÂWÿYäÅ'Ù ‰ ïIÒ±{×mì¼ç½Ì.º€îÄá–Oêd¿+ÿ3´9ø#d}rÒmªãBå&ÁQg]ˆ»¾ä"š½˜æšk0_nÖSœl²É&{¢îCBÐHÔÚÕèöôiÂÉ“¤½=ìæ&ÄHòá0ó9b gß÷>vn¼‘îøqÍZËüª«Ø¼î:6¯»DˆçΑE˜]qöØ1d6Ãln"³2ŸëkÎfû>Ó3*™l²É&{²›¸ƒ]ª9r„æÈ‘•}U*¸õgþ —>~_3ýË'›l²É&›d²É&›l²I@&›l²É&›d²É&›l²I@&›l²É&›lÉ&›l²É>›–ñN6Ùd“}öñ)XéR¸nu*¬g_ÀQ®âù“€L6Ùd“=]ìýùŸS § z‰‰Ÿ4r‚‡1’ð¶ÃJ\‰±¨äQµ{Ýû‡ØãÒB'Q4J‡ãKyG¸ò™! oûÛyë[ßÊ7}Ó7ñ†7¼áÀsÚ¶åÇ~ìÇøÍßüM¾û»¿›ë¯¿~ú–N6ÙdŸ›åNýjïØ9ùÕó†8`™½ðvb°¤`”ö!É(S eQ= " `Íå Ljt»ˆ‰É±6)äЬ‰ähè:G×)Æ=-±- ÊdˆÉ*謁WÅÕ“°>âg®ù!öÄpà®áÐÆ÷¶pì« ¹øIó¯ø¼P&o{ÛÛ¾ù›¿™ŸÿùŸgoo7¾ñûÎ{ó›ßÌ+^ñ ^ýêWó–·¼…ë®»Žn¸ászÏ e2ÙdOû†GîZuücX`ǵãiÿ‡2Á½+<²BêµÊÿÊΑŗó1}îÏý~|T Å< ÓÎX ü:ÂM›ñËÀå½ЬÑF(t®KXahh/^sÝÛj¼z½¹¹¹ô¡&ä{úÇrî}ŒÚxYg&ú÷Xœw f.²._ëÅ€uù~·íŸ7¬Ëûùep.îîßÜå‚ °eË–©“@¼½½‘““óÙKX¥¥¥0 ÈËË£4!„L ¨¨¨Ï&Nÿ²fÍ(•Jëì¶±!!!öuÍÍÍÐét€ÐÐP466ÚÛÛ@{…B¦8ÎÏ9wîNŸ>øøxû]X*• qqqøóÏ?qâÄ û]X …ÙÙÙœîÂBcc#t:*** ‘H8 @ee%"""ð7Oê:tè<È)ŽŽŽ¨ÕjlÚ´‰S?ŽˆåáǸ}û6¶nÝÊ©Ÿ‚‚deeÁ…Ãs±=ׯ_ŸÏGppð¤­R©„ÑhDXXظûJ¥X»v-|}}Ç݇ÅbAaa!8Ài{d2V¬X??¿I[F…BÄÄDNq=z©©©puuw===¸té’’’8ÅRRR‚¤¤$̘1cRÙÙ³gcåÊ•c¯d'HYYûòåˉêžíííe8÷#‘HØpê#22’sÍÍÍlaa!ç~Ë;wØœœÎýÄÄİ&“iÒ·çÔ©SlUU•SŒ­\.g¥R)§>²³³Ù¶¶6N}˜Íf6::šóöäåå±---“>¶jµšÍÊÊâÇæÍ›YNÇ©ÎÎN6==s,;vì`ß¼y3éÇì—LØw {öì¡ù!„Ð%,çÓ×ׇ´´4H¥RNý ÂÍÍ |þøsioo/<==9Åa4a4ñ+Çç;"“ɃÁÀiêì¨Xч^o½Ågúôé“Ëùóça0Àé2®««+Á¤o³Ä2::Šááa¸ã.£Ï+`fÒcéï»;x<Þ¤îã/ùéK™pÝɲƒ„B!„¸GÛ±Î'GÅâˆ>¸&GÆâ\»#·ÇYbáóùù,Ïœ9“ûIÕA±xxx8ý1KÕx !„P!„òýLÙï@L&Ôj5–.]J{‘L===°X,˜;w. ¡B!äçD—°!„P!„B „B%B!”@!„J „B(B¡B!„!„J „BÈH £££Ðjµ0_l§×ë¡ÕjAÕX!äÛ˜ÍfhµZhµZôöö~±íÀÀ^¿~ýÉïòy R©·nÝÂ’%K°wïÞ1ÛŒŒŒàرcèêêBdd$D"„ò•är9 ë³GÄb1üýý?i§ÑhPQQááal߾˗/wÞHEE¼½½Q^^Ž… ¢¤¤dÌvˆˆˆ@yy9^¼xºº::"!ä+={ååå(//ÇêÕ«¡T*?iò,Š‹‹‘œœŒœœÔ××ãÑ£GΛ@Ôj5hmm³Ý½{÷ì¥ÜçÍ›‡ÇÓA>K¥RÁl6Û_áÆ40ä§U__oOÏž=ƒÏ˜íž>} ûœ72ŠŠŠ022b???òÓ³X,hhh@xxø7¿—ùá) 455!..µµµ0 ËåÐh4€'Ož &&………‹ÅP©TØ·o²³³í_.vwwC,#** ÕÕÕ4¨ä‡ðêÕ+dffâäÉ“ãz¿Ó%7âòåË€ššÄÆÆÚ×]¹r}}}€ØØXûùæÍ›Xµj dL¡¡¡Æ…  N‡––û]~*• X·n²²²ššŠŒŒ ,^¼W¯^EWW*++Q\\ŒºººqØq&ƒƒƒ8~ü8’““áééùÁ:™LfÿyÙ²e¸{÷.zzzÀ0 æÌ™ãÜ Äßß"‘³fÍBLL  µµ)))H$€ÄÄDô÷÷C$!66–ùj^^^ذaƒýu\\æÏŸ   @PP|}}íë5 är9vîÜ ‘H„çÏŸÓ ’)/33ÕÕÕH$‰D¸víàÌ™3HOOGii)†AZZêêê——‡Ý»w@œò6Þ°°0„……}ð»ÀÀ@9rëׯ¸¸¸@,C,Ó‘@&Ü®]»‘‘AA~eeecþ~Û¶mèïïGJJ ë-¾¹¹¹c¶RßÄÇÇÃËË‹ö<—¶¶6ÔÖÖ~óû-Z„¾¾>ûÌãðáÃ4˜ä‡ö¹ÿ¿›Ò „ñªªªBCC¢££ÑÝݦ¦&”––°Þ¡Å0 jjjPRR‚ÎÎN´´´@&“A&“ÁÍÍ ùùùÈÏÏGTT”ý²*!?;†¥: „BÆf „B(B¡B!„!„J „BˆÍÿ¿GÐ@KOIEND®B`‚snd-16.1/pix/polyshape.png0000644000076400007640000000265311147553270013660 0ustar bilbil‰PNG  IHDR5ƒìûŒØsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ:pN+IDATxÚíÝán›0ÐRåý_™ýbbÌ`_0Á6çH“¦:”‡/gšçyþįM5¡ Ô„ Ôþ1MS¨‘išÂ?ð•P;hó<ÿÌó,Ø€Ç}¶/ÜN‘6[:·9ÐA¨Ý¥$ôô€êå'À+BÍÍ ËP[‚«4À–kp®3-HÞ(Ø ¯£`{!ΓûÞÞñwvÙSÇÇ¿‹kjСeUê@_¿¾­¼RËj‡Yi»g×7÷»5¨BX/Û¾ïhYí°¼ÿÌú-jÐa°¹i·O¨A‡eç]å£P 7Á&Ô`È`C¨B hÁºÜLÝ Ý./]ÖÊïSeYKß&µÒÃŽ¥ûÏ“!Úÿž|› Ëíõ¿l— 5¡ÊO¡ ÔB>O}°AƒÀP¡VrçØïÔ¼ûYóÎè™¶®Üõ@;tf{'ÿ»¦ò9h‘¶ÖßHý]Rí 5èHnjŸ;¦ò¹R…åÚ:šJ©d}S?+Ô€¦JèHh¦|lZàÉ`»ÒCL•¶zjÀcaVã:ž@®^ÇÛ+_…ÐeOo/… X֥ʹoMKTÚVî}{Ë·fê¡­'c‡Vªtkyðmn|ÙÑÜpG?÷ßï"Ô„ŒDù 5¡6ˆ³£ ¡æ1)¨b¸r‡³Vrvê¡Ò»ŸÛež(€ÎÃ,7Žlyô(2•O­¹ ÏN=iÇÔC0£©‡r=­½Ç’rÓYÇH/íL;¦=¹®ÊèÒ°Kñ0P/nl½ b¯ÝÆï“€í¿Þv ^‚Ù ä½áÖ˺ÖlCù ÛHegi†tMT‘ 3õ¼,$rã¾î,MK>'ué©t}sS驽h‡÷x×xÁµ ƒ½d–kÀ©A«¹6£eoîsJÚ>j'ÊB :R:-²¼öÉîÌ礖]_å'0¡5¡ Ô„ Ô„€PjB j37Í1£]†ZÉwR/ l[”ŸB @¨A²l¡5›jtÇP„€Pjð—§ jB jB @¨5¡µ73† „œâYUÎò<½7j¾£P~5@¨5¡ÆÜ™E¨F¨5`”>B @¨iïzÞ5¡Æûè#Ô¡fäåÆOµØ£p ¡B¡¦—ÖâÁ×cÏn µišB;}ôý½„Yô±%,žÜ‘u Ù™7{Óz+9@¢ïïá [¤«jëÝÂ6ï-„ùiú8ýÚtÞ½í½@=®·°¢f/ÿk¡Vr6¶sW}Z[¡^¦žémšëk}ß²¾¿‘Fõ¤€îzjë;MÑ¡ &øš,?÷Aö^2ã3øö$AnûÚ¾B @¨5àµþ{L @O @¨Ô÷õǤ¢u ì…v¥ž2Z«{ÇoôõH>|¾½žšÖ¨o/”ŽŽßèÿ£ù üäö™g†ßó·n¡ã!Ô¸}'7sí;ËP¡Æ+Ê”eçOõà–׎^_ÿüQÙ³m'ú¹Gí“þû¶ròjb>57Æ=s§J’ÔµíûŽ^”@¹k6Gï§’3š_ 5Ó½ëÌ}ôµw©ÿ¯«Öw]ì}V®GIü˜NmïÔñ}=šŸ'6BdG²“½¯D½b5q]J…3çßÈëÑö?þ$´|Æß»N³=K§þ_p%= ÖYIìÙOºÚa¿2­Oî~‚@ÓShÕÑ??8éǽËIEND®B`‚snd-16.1/pix/firmant.png0000644000076400007640000005665611147553266013335 0ustar bilbil‰PNG  IHDRìZ(ðÂsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ*'ò%ëL IDATxÚìy\MÛÿÿ_æy’HJÑ@d ‘!C܋냛̙¢2\™¹ÅÅueŽ\\C„PIdL$s£)’4Ïó|†ýû÷ýëtNó©NµžGÎZk¯½÷Zkï÷^k½Š¢(PO¤ @@ Z^€°X,„„„ ¸¸˜o~bb">}ú EHHBBBPRRBZ•Ðî „µµ5>|ø@ƒÐf«.ãܹs`2™xñâÖ®]Ë•—‘‘³gÏBFFyyyxýú5Àßß{÷î…¡¡a'}ñâ?&½ÔFxðàìììPVVÖæïURRyyy––æJ—€œœÏ_mÏÍÉ“'±hÑ"2ˆ­C€Œ1®®®èׯ {÷îðõõ(**‚Íf#44={öDEE¡W¯^½8iii¬\¹OžD ¤lß¾³gÏÆèÑ£‘ššJz°•£««‹û÷ïcïÞ½8{ö,i*„‡‡càÀôï-[¶`Ïž=¤aD€TGyy9 ¡ªªÊ7ùòå7nlll——Gz±PZZŠoß¾ñÕÔSVVÆõëס  €)S¦ 99™4@HÃxÿþ=Ο?C‡ñÍÁ¶mÛ0zôhL›6 999¤'…‡ƒ§OŸÂÜÜœo¾¶¶6,--¡©©‰?þøƒ4@HÓ²zõjüòË/X¸p!ÒÒÒHo 9¡¡¡}ºÝ·WQQ$%%!&&FA#..Ž 6àǸuëéÍ6@ÇŽqéÒ%œ>}ÞÞÞíº-¾|ù‚N:AAA ‚PÒ&>m|}}1sæLôìÙÇ'½ÚÊÑÕÕ…ŸŸºví “Fù?äääÀb±PRR"#E¡ÝÎ@*066ÆÄ‰qøðáýuZªªª°µµÅ‘#GHcTBCCeeeÈÊÊ"A 3Aáââ‚)S¦àÑ£G˜8q"éÙVޏ¸8\]]1iÒ$¼~ý h÷õâÅ „……ñ¤çææ’N'ÒX222ðõë×;wî\lÛ¶!#** EEE :ÖÖÖW®\±±q›ØLÖÑÑ¡ÝU¦:C:ðæÍ\¾|™ÖÔÙ¿?¤¤¤êUG¿~ýÀb±pûömLž<™ôn “œœŒÃ‡#00³gÏÆþýû¡¥¥U¯:´µµqàÀlÚ´ :thõm¢¡¡ žtIIIž´§OŸbĈd ˆ©Žììl,_¾"""°µµÅ†  ¢¢Ò ¯MCCCŒ?çϟǨQ£ //Oz¸ˆˆˆÀÅ‹ KKK8::BQQ±AuõêÕ vvvXµj®\¹ÒîÚqõêÕd@„–ÛD§( žžž˜;w.:tèOOOŒ3;vlÔRźuëàããƒ?~Þmž?Ž `È!¸páæÏŸß`áüô -''‡¼¼<âÿŒ@ 3Ÿ|ÿþûö탿¿¿@—&¤¥¥1xð`}Vï¾}û ¦¦†k×®aæÌ™¤¡ „ö>ÑÐЀ¯¯¯À×µåååaii 777Ò»ÍÈãÇagg/// ÔÔÔ‘‘ÑnÚÓÓÓVVVd`ˆá‡””T½7T늩©)Øl6BBBH7OŸ>…ƒƒΟ?ßdFÀúõëÛM›&%%ASS“oÞ˜1cH¡ý ¦døðáD€4eee¸xñ"ú÷ïÏåv\Ð(++CEE¥Á*Þm‰±cÇâÑ£Gdðˆi*-ZDz·pvvFJJJ“[Œ›ššÂÌÌ û÷ï'N Ò´Œ=ëÖ­#¾ÕÛè=…ïß¿ãÎ;X°`A³8ü2d¾}û†ÌÌÌ6?«+))’’¨"@Z111ˆ‹‹£  €ô2‚‚‚ðéÓ§FÕqûöm7›f”½½==z„˜˜˜6Ý7ÈÎÎn²=BA`ïÙ¦þ’:vìOzsìMÃÆÆ+W®ÄÍ›7…ºîß¿ß"îWîß¿‘#G6èX‡ƒÕ«WãñãÇä)"È ¤ifãÇçùëÙ³§Ð6ˆ……E³Ç9~üx‹Ì”cÙíää„©S§bРAÍv½’’’prr‚££cÉÈÈÀŠ+žžNžv¡5 QQQóüuíÚµYnnÚ´iõŽ™––†]»v5k'ܹs§UiŒÅÄÄàÆ°··‡œœ\³WDDšššHHH¨—<~ü8.\¸@žv¡5 –fôèÑxüø1nß¾]¯—ã÷ïßÉȨøøxDGGâÕ\óöíÛÛüæ;ÐÜ´ù`Ëååå(//¯×1¸xñ"æÏŸßbׇSSÓ¦ë|11°X¬zûû÷ß±bÅŠi—qãÆáÔ©SðññÁŒ3ê|\qq±PøÒòööæûA“––FÞF2ÖYH}(++ÃÛ·o[ôº“’’ð믿6IÝOž<““Sƒ–ë*\î·ººº””¬—™ŠŠ úöí+þ–––pwwçùSWW'o# ÂÆ¢E‹pþüy¡¾Æ &Àßߟ+íþýû°°°h’e‡ƒ .4è«÷äÉ“ÐÑÑÁ„ Z¬½êû²ÕÐРÝü·Eþþûoò&#",LŸ>½Yϧ¦¦Æ£%tåÊLš4‰g†Àf³±mÛ6¸«ß¸qc½ùñ㤥¥¡¦¦Öbý³oß>|@aaa«ê§îÝ»cëÖ­X¼xqÊ›ššbïÞ½`³Ùm.R¥½½=­-˜‘‘èèhò ˆ$ŠŠŠ())©vFQ›ÍÆû÷ïѯ_¿ËÉÈÈ ::Ïž=k’ëý÷ß1pà@Þððp¼xñkÖ¬á{ÜÉ“'¹þåÇãÇ1iÒ$ˆˆˆÀÎÎׯ_¯³•ö°hÑ"¨ªª¶hŠˆˆ€Á`€Íf×X®°°'Nœ€­­- Þ½{‡W¯^ñm¶Öq}âÄ 0 zJ "`Ž=ŠsçÎáÍ›7®ëîݻزe :wîÌ7? ~~~:GTTTUUy6ª333‘––###¾Çddd`Ô¨Q5Ö=gΜÇœŒŒ„¾¾>$%%[E¿³X¬:}‘;88€ÅbµÊq]ggg¤§§ããÇøöíy»ˆi ”••±~ýzüùçŸ|øPë5Œ3†oú²eËpêÔ)ºÌ³gÏju"©­­ GGÇZÐŠŠŠ°víZº~aÁÄͶ¶õr’Þfǧ‰‰ ýbXH D€Ì˜1²²²uŽ ¡¬¬\ã·† R'g„>>>(,,„µµ5ž?ŽØØX:¯S§Nu¾‡;wÂÚÚºÖrÖÖÖðòòâÙ;éС_ ,ww÷vý¨««·º%¬š(,,„——˜L&$%%‘‘‘àÆˆŒŒ$o> õ}IˆŠŠVk°°°0üþûï~Ú)((àåË—5ÖûõëWž4###hiiáîÝ»5{íÚ5ìÙ³§Î¸QÍôññÁ† СC2ê«ôÁ?ÿüQQQ¡¸žÈÈHôéÓ§ÞÇ5 :tÀÔ©SñâÅ ôïßÉÉÉèÙ³'œajj ???œ:u xøða£²„õ$&&âÍ›7˜2e –––Vçê?~@\\èÙ³'455@ç÷êÕ ´Š%¿Ð¹ùùùHJJB¯^½z±MqppÀ‚ j5°lnLMM1sæL¾Š hjjB^^¾Úüæ_ìíí kkkž¿ ÏÈŸ>}jPß>***˜8qbµv>l6›öRðäÉ,Y²ëÖ­Š8)"@„x{{7É——‡‡äååñÛo¿q¥'$$Àßß›6m‚„„Ö®] ggçjë‰ŽŽÆÍ›7±iÓ¦ZïÅ××·Y¢ìeggCNNŽgÓ¶¥‘””„ŒŒ _•e8}ú4¦OŸ===¡¹æšâœ?¾Vo ‚î׊¶ËÍÍŵk×È‘@Hu˜™™áõë×|µ±^¼x!C†T»”Q\\ {{{®˜Ç¯õœ999øøñ#Oú¶mÛ ««[㞆’’\\\ðâÅ ¾÷òöí[Ú•ŽŽm¯ªª zùíóçÏ`³Ù|-Ø[;Æ C\\RRRxòž?Îõ{âĉ˜9s&‚ƒƒ…ò^¬­­acc#ºÌÍÍ1hÐ žt===ÏÔ/_¾Dqq1"""È‘@HC8uê/^\£Z+EQ\›­Ë–-C@@_û7¢¨¨ˆç‹rÒ¤I000  kÛ¼©UûéàÁƒ}ûöÑ3àñãÇ£¤¤„Nc±X­Îá&£ªª SSS¾1©JJJ rrrxÒŒŒpúôiìÝ»cÆŒ´´4 K—.ÈÉÉ‹‹ &Ož,kˆŠŠEQ :VWW‘‘‘|]Ÿ?cSøûû E úp÷î]cçÎ5–ëÚµ+Œ…æº9Òè:*+mmm õœœˆŠŠ‚ÍfCYYhœŸŸ‡‚ÍfÓiÑÑÑ5:è$Ò.PSSèQ£àííÍ•^¡­2sæL®ô={ö >>¾VG{©©©pqqÁž={¸ÒÕÕÕqçÎLš4 ²²²túáÇabb‚¹sçÖëú¡¢¢BF-!XY5º®;v |—zZЉ'bäÈ‘ªÃÒÒ’GHVÞXÏÊÊ‚˜˜”””è´Ž;BNNŽ« ¸Æt^^^µûM"@Ú-nnnÈÊÊâz €Ÿ±´>\«»o‹…ŒŒ ®8"222X±b–/_ÎS~ðàÁ ­— È7ЧOXXXÔù%"%%…ÒÒRx{{Ó1#Ú"Û·oÇŽ;ê}\FFF³nZ×ÈÉÉ ´Î5kÖ@II W®\ÁìÙ³ù–ƒ¨¨(—ñ)›ÍFjj*.^¼xõê’’’àp8ô—gFF._¾ŒÕ«W×xÜÑ£G1aÂèëëó|1?~¿ÿþ;O$Ã)S¦`ïÞ½uR•––Æõë×ëì=•Á`@BB¶¶¶xôèßëGAA$$$l(WRRBïß+£FB×®]qéÒ¥Z¯{õêÕhwîÎÅÄÄèe¬Š±RÓ˜æ hVRRÂó6› &“‰‚‚0™LäççƒÃáàÌ™3(..EQ<D€´jÆG9•””àÓ§O5~ÕÄìÙ³qèÐ!,X°@àK`ll\£§ÞÌÌLüøñƒïõŸ‘‘‘X¹reâÙ„††‚ÉdââÅ‹°µµEzz:wïÞÅb¡  6l oZ"@Ú¶¶¶ðóóCJJ vìØ%K–@SS“§œ¾¾>fÏž]ëúúªU«¸,ØCrr26nÜH==ååå\_ר©©AQQ‘gï¦ò—ùÒ¥K«CRÁüùóqåÊrèÐ!ôïßæææBß§Û·o‡»»;âââàååCCÃ]‚$%%áÌ™3mzozôè9sæðŒ›‰'ò-ÿôéS¸ººÂËË‹'ONNŽK·BA¤:ª>7ÇŽCVVíN¨:·B"@„SSSLš4 &L@xx8¬­­!%%ÅSNFFêêꈅ„„þ÷¿ÿ5ùµmÙ²ÚÚÚ\KN%%%|cq¬\¹ÆÆÆpppàëOKYY§OŸnPôAà§{yyyZÕS˜éׯŒñÏ?ÿ 88˜G©*eeeíâ&##S«²†žž_ŸnU133CPPЭ[7žöûö-WZll,­ñ˜žž0™LlÚ´ >>>زe ..aaaämLHëáÈ‘#PWWÇÑ£G1bĈ˦¤¤Àßß&Lhñk®Š¶¶6Üj#ê 999\»v eeeX³f ¬¬¬ø–ÇþýûñǧÿÿèÖ­Ö¬Yƒ•+W¢G5–e³ÙHNNæ™±÷êÕ‹Ë–DVVbbbxòä ºwïŽGÑ8—£ÑÄÄD¼{÷©©©xúô)Ðqkøyq ´CâééI;ŽssskñWQQA@@FUc¹¹sçBUUµY6«³J_¶lð]ªºxñbµË!..<૆,ÌBÄÝÝóçϯ¶-EDD ¤¤„ÜÜ\LŸ>½]y'®©/•••!''Go´4 h›û˜˜hjjBFF"""ã«.™™‰ëׯӞ‚‚‚è™cNN(Š¢­á>|ˆØØX.ƒÙ†ÏZ¡±²²¢Ç-^¼¸Õ4РAƒ §§‡Ç7ùRƒ““íϪ2“&Mªv™MtìØúúú\¾£²³³aƵ¹A¿téRìÞ½»É„•ª}Ù©S§jgZZZt¼õׯ_#<<\ —nnn°²²Â»wïøúz{ýú5=’ÉdâÂ… ÈÌÌÄÖ­[áåå‡C¿GÞ½{W«­¡• Ö̱cǸ¢½5JJJ––ÆôéÓy^jššš8þ<šäÜúúú9r$NŸ>ÝnútëÖ­´-Cs’——‡„„ž¿Ú¼4†††033ã™™Wþq÷î]XYYÑé ,àœmÖ¬Y¸zõ*ßóÙØØÀÕÕ•çC¨OŸ>øôéßYJii)rss¹ «ŽÓ[·náñãǸxñ"(ŠÂÞ½{üŒÕC< 7-b¤ „‹°°0;v¬Å¯ÃÏÏM6ëi¯„„„ÐëüU‹0pøða®`Ú´iôîÑ£GqëÖ-èèè ..ŽïÌ¥:_s=zôÀáDZwï^®elEEEäççÓKRÁÁÁ:t(€Ÿ¾Ø*b˜Tåýû÷ˆŒŒ¤Õ¶­­­aii‰ˆˆ<|ø:t@bb"-dºtéuuutéÒ·nÝ”)S yyy¥™´:444лwo¡¸Lš4‰caa¿ÿþ›çOUUµU\¿¨¨(­¨©©YcØç†òüùóZ[¶lÙKKK¼yó†¶éª ¨¨÷îݣݭ<~ü666 ¥Uš+f&oÞ¼All,’’’h!¹iÓ&°X,'”"@„š ´˜«ñ¹sçâíÛ·Dë…Pglll0bÄ|ûö óæÍ«1¶Mc5j—qcjj*­žüË/¿ð }îÜ9dgg#==vTUÞÝÝþw×®]t™üü|¸¸¸ÐS………ô’]FFFµ³""@í’Ñ£G#66 ˆ‰‰®®.ìììHôfÍšÕ`cQ ¤¦¦ÂÜÜcÆŒ 0Ë—/G—.]h[›C‡Õzø¹\Š?ÿü“'ÏÈÈׯ_‡‚‚¢ÉÀiŸp‰‰‰´Š±ªª* PVVÆUþãÇÈÌÌÄåË—éØ(èÿ߸qƒyyypwwGii)ðúõkäåå!""OŸ>å1ð ðÓPµ=ØB ‘‘‘AQQüüü““Scp-Bۡ¯À^* ÄÅÅ1xð`|øð’’’ ( âââPTT¬v\±ÙlHKKsy® ‡ÃˆˆHªÅ/_¾¬5RèåË—aee‹ žó±X,:t ±±±¸uë ¼¼œÒVRR‹‹…   ,Z´àâ₲²2„„„ÐÂÄÅÅçÏŸG^^X,þý÷_?*Ç£çp8\þƈ!´*Nœ8E‹áùóç8~ü8i™™Y­N5eddx´ºNœ8ôë×ÀÏàTµy h *Gb¬:ûºrå ýûñãÇ077G\\ºvíŠÈÈHžcBCCñðáCzƒ>11<ðÓkwåeè·oßâÁƒøøñ#nݺ‡C[ìWĪ ==ýõÒÒÒðîÝ;"@­‹ &`òäÉÐ××G÷îÝIƒ0kÖ,bêÔ©——§Ó%$$xœ|*((`Ê”)uŠÍ2uêT 2"""èØ±#é™I‡¸6ç±yófú·’’ÖZß¾}Ý»wó=ßÌ™3yÉñÃËË‹'°\Uüýýé¸<‰‰‰| <ˆüü|<}ú ?$sss‘‘‘عs'écðìÙ3?}¼ÀæÍ›‘™™‰àà`Ü¿7oÞÄëׯ¹ÎYáÉ;33³Ù< B QVVÆåË—±oß>¡wáNh:vìžtMMÍj÷Èꢫªª 0 ØÙÙA[[›^šZ¸p!F¬¬,””” !!]»v¥2e ½¬T¬¬ï+|ƒ IDAT, ÀõE/(&Ož\­j²““_Ò£Gð¤_»v """ðóóÉ'üô9÷ýûwž²?~Ä;w=‚››òó󑬬,âáÇt=[·nœ?žömV9îQzzºÀ ¢‰!B‡ºº:rss±jÕ*Úãï½{÷°jÕ*Ÿ«¬¬ l6†††ôl¡2æææptt¬ÕõÿÑ£Gk+TÙ§^=ø:±tttDQQ>}ú„/_¾ðä¿yó†VHxùò%._¾ àçæåeºèèhøùùaÅŠøôé²³³àÿÇ‚ Ãׯ_éß~~~´ZtÕ廄„äææB „Šˆ‡•7ôÿüóOz9KEE²²²tYPÅUžß&{HH àçÒÙÍ›7¹ò322PZZŠåË—Ó_üü„Lm6/ÅÅÅôõUÁÜ»wçºæÏŸÏea_AS]]‰‰‰\H+xñâ^¾|É×uKii)222põêUp8œ8q………HMM¥“Ùl68-6nÜwwwäææ‚Ãá ´´åååàp88pà€ŸûXEáÎ;ˆŽŽ&„@ Ž#FÔê zäÈ‘µÖcjjŠŽ;ÂÙÙ¹Ne­­­ˆ¿þú‹N·´´Ä´iÓ ##ƒœœ@||<´´´`hhsssÛ:%%%á·ß~£µ®ªÒ³gO,\¸°ÆÀpÀϘóµ‡nݺA__111|¹¹9<È÷xGGG\ºt‰Þ©|î3gÎÐ^\\\ðþý{ú¾õB ÅÂ… k K–,áúÝ”^åää ¬¬Œ’’¬\¹ ’’‚ŸŸºwï%%%®YKM×’ŸŸOû ¤¤$]ITTœœœª}É6†?þøÿý7<333z£öïß_käGÌ;—¾çÌÌLž2±±±5î“ìܹ“KÐ$ÀÀÀ€']LLŒvx((ø9Æ¥K—$%%Ñ»woÚhQÄÇÇ£k×®ÐÓÓCll,O~=àääT«•LL ôõõët®šŽššÒÓÓyÒ™L&ÒÒÒIÛ±B šŒž={¢gÏž®§âÅ_Ó§O§_ŒuAWW±±±ôqL™2âââÐÓÓÃÂ… Ñ«W/?m?~ýõW¾/øê Ùl6JKKé}555ž¯þ¸¸8hiiA__¿NQ!ù¡®®Ž´´4¾yÙÙÙ\ž•냆†mMÏd2‘ššÊHŒ ÔT¶‘¨Ž; ìœJJJèèèÐa.\à§ÔíÛ·i2qâD®ðÁHJJ¢gaãÆãqüز²²è¸(UÕš+¨‹cÊê°²²‚——Weˆ;w¡‰ŒŒÄ§OŸxÒ Ûe{lݺµÞnTÆŒ#Ðh„]ºtÁŽ;ðýûwtïÞ½V×úæææÈÊÊBEEJJJ´¯±Ù³gW[~öìÙô=W.7sæLLš4 ÷ïßçj—#GŽ@QQ‘o]•ÝÃT½0™L:˜ÜÈ‘#ùFÑÈ@hÅhiiñM5jO܆PÓË\ 8¤W¶í¨ï=+++ƒÉdbÊ”)““C||<,Xøüù3fÏž’’DDDÀÖÖ;wî¤Ý²e Áb±››‹ôôt,Z´#GŽ„‚‚òòòøÚË@hs 8°VËïê–™*Sy™ø5ÔÄÄD(îQZZúúúPVV¦g222ÕZýOœ8ŽŽŽÈÎÎæQ¯^¼x1ÒÒÒ`ddD»=騱#îÞ½ eeeˆŠŠ¢wïÞ••åòÔMf ¡]²víZ¾é £Z¥†Šeº ++K«üÖVoCPWW§-ËŒŒê|M×À`0 ""Bo¶W´IeÀ %III¬X±¡¡¡°²²"„@ øQÕ¸°¡ˆ‹‹£ÿþôïŠ"ÂBÅòÖ¨Q£\YÂ"„À/v;ðÓÏ” fUë·³³k°UySAf Ъó=U—ˆŒ ©¿"PWU{~tîÜC† ¡›˜˜@CCƒ@híTÄÚ¨Š¦¦¦@l‚:wîÌ¥…ÖØ~N1‰!„ : ±9sæÔz,ƒÁàÚœ4rrr}š^Bpss£?À*?·o߯£GxêÈÌÌ„——ßX!‚°±}ûv())ý rrrX³f ÏtæöíÛÐÕÕð3¬äþýûñ¿ÿý²²²àp8ˆ‰‰¡ó_¼xeË–ÕéäZZZ1bDƒB8fdd ¼¼]ºti’†yûö-í:¹5Õ”” ‰Zýÿ46›OŸ>¡wïÞ­®]êJ}±Ùl,^¼˜þ=uêTܽ{_¾|Áرci _~Œ;Æ ãIö줥¥ÖTXÛ›Åb!::ºÉÆNURRR ***°È„5‘••…’’ž0¯MŧOŸ ««Ëõ‘ÞRã„¶E¡ª¡¬¬Œòòò¢rrr(Š¢¨›7oRñññtþ‡¨   úwhh(ÕøûûSMVÿ‚ ZeÝ”¿¿“Ô]PP@ÙÛÛ·Êvi^¼xAý÷ßTQQµxñbŠ¢(jÉ’%TQQµtéR¡kƒæbccÛe?!%%EEEdP7111¨©©AAAW®\:tˆwUßQQQxöìÞ¼yƒÐÐPžú8555¸¸¸R!@rrr`bbÂc¼%.. ¼yóÆ k–{///9r‡jѯÏ;wî´Ú>‹‹C¿~ýPXX6›Í•„oß¾ÕÙËhS’œœŒqãÆq¹ª -- ]»v…””WlêöBqq18€#GŽààÁƒ(++#Ò (((À·oߦ [¿ÿ |ùò…çý—›› ¨««óÌ2€ŸFŒHHH „………‡Ã‹ÅBBBfÍš…äädäåå5ùùïß¿gggÌ™3ß¾}|ýúáááGjj*= ::áááôwïÞ!55•ËÆ·oßøÖ‘™™I§W®ãĉGTTT«ïÓ¯_¿Òþýû÷À‹/âòZP”——sõy QXXgggÈÊÊ¢¼¼œóŸ>}Bxx8˜L&páèèhºŽ/_¾Ðc8!!,‹®øéµ¡bY:++‹§Žœœ®ô´´4?=”W¤…‡‡ÓuT®»òÿ[Z§§§ÃÁÁõ>>--­Nï€vPJDD=zô€‹‹ fΜ‰÷ïßcøðá())EQ8wî233¡¦¦Öl®€ŸšFFFx÷îîÝ»YYYúaY¿~=>þŒÃ‡CSSÒÒÒ …½½=V®\‰™3g"77rrrÈÈÈÀÈ‘#M/…dffbݺuضm´µµ¡®®àçÚçŠ+ŒŒŒ ¼zõ jjjèÕ«W«êÓqãÆáÌ™3èܹ3$%%±nÝ:tëÖ GŽÁêÕ«ÖÖÖ-¾Œebb‚5kÖ`îܹHMM…‰‰ ¾|ù‚=z ÿþpssƒ„„D“„ mMT¸òä >LÏÌ"""°lÙ2¸¸¸Ðc¸´´YYY‘‘¿¿?deeé½ÌG᯿þ¢—ª?;;;hjjâðáÃ\udff"55—.]ÂØ±cüÜWÛ¸q#®]»†üü|úúÂÂÂ`ggÇUwåÿ·ô2à±cÇ››K‡Â?~ ;;›4.¡-³iÓ&ܺu ;wîH};wîÄÇáééI— 4wîB ®®ŽM›6 ¤®ŒŒ ¨©©‘F%@¨ÁÁÁ\q^"@B¸víf̘èÛ·/Þ½{G…@@¨™œœ(++Ó¿'OžŒ;wî†!Õî”””ààÁƒ°±±ºº:O~PP0þ|ìÞ½^ámmmÑ¡CÒ²‚عs'¶mÛF‚кf NNN°²²Âž={xò~üøgÏžAFFׯ_ÇÌ™31mÚ4dee¡¨¨ˆ´*@ ´g’‘‘===:ÒVe˜L&DDD ªªŠüü|èééÁÏÏRRRÐÖÖ&­J íY€TÅÏÏ |ó°víZ(((àóçϤU ¡= X[[cúôé€uëÖ!""йsgˆ‰‰áöíÛ;v,°lÙ2@—.]H«6²ôG¨ ›Í†¨¨(DDDè4QQQP‡CˆÐâT»‰nff333ú÷—/_èÿËÊÊbóæÍôo{{{ØÛÛ“ÖlÖÖÖpppÀðáÃIc‘‘‘ÐÔÔäÒÂêÞ½;Š‹‹‘œœ MMMÒH᜚—¼¼<¾^Z›šôôtÄÆÆ’ ‚›š×¯_càÀ-rî“'O" Ïž=#Ñ Ü»w<é™™™¤qD€êOTTNœ8ÑìË€ ˆ‰‰Á÷ïßqéÒ%Ì›7tF3bľ >>>¤qD€F~~~³Ÿ“ÍfÃÃ⢢(--%Ð ÈÉÉANNŽ']TT”4¡ÕAö@pssógψfñáц Òš`³Ù8q₃ƒ›íœ¢¢¢`0`2™t‡ÃÁ÷ïßQ^^Þ$çü矰páBhhhàÂ… `±Xmº_§NŠGµŠkÍËËÃ;w0~üxò@ˆiMäääÀÞÞvvvÍvNuuuÈËËãÛ·otZ~~>tuuñáÇ&9ççÏŸ¡¥¥))©vѯ™™™xõêU«¸Ö³gÏ"::š<Œ"@µ“––†ýû÷“†h"œ1tèP>|X试Éd¢¬¬ Çç›ß­[·ã§ÍE³m¢_»v <¡ÿ²:wîÆôôt<|øãÆkòs²Ùl¾ñ®ÇŽ‹GaÀ€d´6‚¬¬,:tB­yyyÈÌ̬6ˆT…—btJh73ÿýïpuu…««+fÏž-Ô„>}ú€¢¨&[>ª ¯_¿Æüùó›ü† †Å‹céÒ¥ä‰ Â'@ÄÄÄ )) IIIˆ‹‹“–¯‚¼¼zôúúú¸råŠÀê\µjBCCñöí[2Zqqq¡¨¨²²²¤AD€´UZRåõû÷ïøçŸ^o||îܹC:ŠÐ* KX`êÔ©¸~ý:ýðW••ìÚµ«Éέ¥¥…?þøëÖ­ãÉ»yó&æÍ›GGGÒIÿ7#Ûºu+TUUoÞ¼ABB‚P^«žž¾|ùRk¹3f T„ö#@¼½½±dÉ,Y²îîîm¦ y‚1½|ù©©©Mªb+&&EEÅjC¡^ºtIh_’ÍÍž={ ¬¬Ü¦‚6U(xíB€Ì˜1ÿý÷þûï¿6:U]]½Ú=lÚ´‰'½´´âââu² OHH@aaa½½ÇFEEAOO¯FõbŠ¢ 777®ôêœ÷š—ªýB ´{Â`0 &&11±Vó%(&&žôóçÏC]]#FŒ¨öÍOõ÷È‘#X¶lß/G,Z´ˆv[†×¯_Wk›¡¨¨È7ýöíÛHJJ‚ˆˆHµ÷Åf³qúôiž~°µµÅÈSÑ‚HIIAZZš4Öʯ¿þ èÝ»7–-[†»wïråùò¥A1Ä_¿~ ‹…‹/ò}qèëëcõêÕ5ÖÁf³áïï_«CÀqãÆ!>>¾Nëé•!~¢Z–ß~û­YÂD€4þù'¬¬¬¸Ò<==ë]ÏîÝ»qñâEžØ'×®]k”±›ÍƵk×j-7uêT|ýú?~$J ˆi]G¿~ý0aÂdeeñÌT²³³Q\\Lš@ BàfݺuèÒ¥ Ï{ZZRSSÑ·o_®ô·oßbæÌ™=z4i åܹs¸uëÎ;W­Ûs###˜™™áäÉ“ >Ojj*nÝóêIDAT߾͛7×XNVVV`1¸mllÚV¢¢¢X¼x±Ð÷郰sçN\¼x±Z·17n„··7^¿~Ýnb555HII D@¨ÍæÎÝÓÓ“¶è®¯utm<þK–,AIII6ŠŠŠX°`<<<øæ‡„„`ÆŒ\kʃ ârJ˜ŸŸ÷ïß×zM’’’>!!!µ–Û³gŽ=ŠÏŸ?#33ºººu>Ç–-[`bbÂ÷Ë<66K–,A÷îÝcÇŽÅСC±{÷n®r5ÏÒÒOŸ>m‘«¾¾¾Ø¼y3nܸCCÃz»gÏœ>}±±±t›ÍÆ?Ú…`177‡y£ˆ© ‡ƒY³fÁÈȨÎKW•¼¼×,¤½Ñ¯_?øøø ..޼ÝD€?}ZEGGcöìÙ¸ÿ>ÜÜÜ   Ð¨ÀT222°µµ¥#þ½yóOŸ>­5Gu3¢†Ä©‰£G¶éÀB, ùùù°²²Bjj*®\¹B/½5”éÓ§ƒ¢(ܸqEáèÑ£˜|)))¡¸ïºúÊ7n=z„… ¶Š—››‹K—.!&&Ÿ>}‚½½=æÏŸ/ÐYÛ!C@Qnݺ…Í›7ó¨>wëÖ ùùùØ»w/¶mÛÖæê©S§âƘ6myÃÚ—ÉÊÊBzz:¤¤$ìÙ³½zõ‚¬¬¬@Ï5tèPœ8q6668~ü8†.ÐúgÏžÀÀÀ&µ’ž?>FU'ßNééé’’‚‚‚BµeDEEѱcG$''7x9©*111())ÁÆ¡¤¤ÌŸ?:::èСƒ@ÛÃÈÈ¡¡¡X¾|9V¬X3f´»‡ZCCÉÉɸrå :wîLBÚ¾yûö-<==Œþýûcîܹ ZNª/ÇGTTT½Ž±°°¨6&yeÔÕÕ‘KKKtíÚ}úôðÓçÔ˜1càííÝä÷gii‰C‡!11®®®Ð××ÇäÉ“«-¯ªªŠ 6`Ë–-°°°hÔ¹“““áêê Ìœ9k׮ń šô~eeeabbÒ®-Ó÷ìÙkkk¤¥¥ÁÙÙïÞ½#o:BÛ ÏŸ?Ç¿ÿþ ‹¬Zµ ;vH|Œ¦`Íš55jäååë|L`` ~ýõWÚ–²²2† †¿ÿþ‡¦íWV®\)ð˜ä“'OÆÜ¹sùzåmÊŠeªiÓ¦aÆ PQQÚ‡`ݺuØ»w¯Ð޹† ¯¯ÒÒRzœ~üøQ`vHB-º‰~ýúu888à×_…——,,, ¡¡!tò²e˸,Ê«ãÔ©SX¸p!$$$ê\wåõy999ÄÇÇ7JSJDD¤ÅÚ‰¢(cΜ9èÛ·/ÜÝݱhÑ"¡ÀÏ}™¶†ÒÒÒhÅ„}ûö‘·¡õÎ@ÂÃÃññãGÀË—/‹]»v! @àëà‚føðá°²²‚¥¥eå^¼x‡: Àþýû£{÷îèÑ£Wzff&bbbê}±±±àp8pvv®ö%ùáØ™™5I¥§§ÃÊÊ ššš¸zõ*ŒÉÓÕ‚TøbKHH€»»;:w¸¸:¹†!„n¢¤¤---hiiAEE;w†¯¯¯Ð º°yóf€ÅbñäõíÛ7oÞäÙ3™>}:nݺ%°zpp0_ã1ƒ%%%|øðwïÞ­“gߊeÂÂÂ:Ÿ?44ï޽Ù3gˆð*¼AOœ8 .D¯^½Š¢¢¢6©¾Lhã¤G077‡¹¹9 !--Ýf¾†zöì WWW¾lk×®ÅÉ“'ñË/¿ð=®.TPjrrrصkê|ÌòåËQ^^77·:•þü9áïïß&â·e<<<š$œ2¡}"Fš i‘‘‘ANN¦L™Òà:ÔÕÕaffF¿Ø+;k”——GÇŽk=^VVvvvŸñ%''cÚ´iðõõ­S,va¡bo ,,  h”Qj}HHH@RROº  Q«Î•••‘››‹mÛ¶áúõëäÁ$ÒèÑ£^½z%ºnܸ .×ßýû÷ÇäÉ“k´±´´„ˆˆºwï.p…³gÏÂÄÄ„VQn-lÛ¶ ³fÍBŸ>} --ÝlÊ›«ÒTËJ]ºtÁ¬Y³””Š¢ §§‡çÏŸcذaäá$"LlÞ¼¹AŽA`` :uêTmþï¿ÿ.ðs^ºt nnnøüùs½4Ï„…°°04ë9‡ Â7†ù¡C‡šä|ªªªPUUEïÞ½±`ÁôêÕ ?~Ä®]»ðòåKÜ»w<¸„à MP?DEEyÖùUUU1oÞ<5Úø®1¬Y³F u>}EEE|ó)ŠÂÁƒ±zõêV)<*Ób‰‹ŠŠ‚Á`ÀÞÞþÿµwþAQ]×ÿìÂ",+HÔ¡âü¹j‚kE'ÚLª„D­q4QØ6‚S$ÑHJÊX'Ñ& ŠÆj 0?l2£KÐbŒQTÄ5¡@UD%†*?*?]XYØ}ýƒ/ïËvÁhRîgfgx÷½wÞãÜûÞy÷ž{ÏZâËݽ{—;vˆTa@ìA~~>îîîDGG[•»¹¹Ý·C¼3øÍo~ƒR©$ à&3 €‚‚‚ƒòedd`2™~–o§»Ùî º÷°+•Lœ8Ѫì»ï¾###C<Üa@:‹àà`9ôHGa²W®\Éûï¿ß%÷·xñb&L˜€F£±Ëõ ï¼óóçÏ·YÇ"è¾´f±”$ •JÅØ±cqwwçÃ?¤¹¹¹K’ˆ „éñxzzâêêzÏœÞÞÞŒ=ºËî177×nŽÑììlŽ9Ò)9PGkfÊ×_¥RÉÂ… ™4i …‚ŠŠŠvS1 €8 !!!6 ˜;w®]®?aÂÂÃÃÛ h¹fÍvìØáÐúussÃßߟüü|¶mÛÖ£â`ýjµÚf²‡=— „éÝÊR*í2ÝsÿþýVÎúçž{ŽÌÌLÔjµ]þW•J…Z­¦¶¶ÖªüàÁƒh4æÌ™ãÐuéããÃ’%Kxûí·ï+²rOâ‘Gá¹çž³iÛjµšS§N±dÉ’N]—"ä9þ}:Ó§O·Kâ&½^oã¼`óæÍ½-S¦L¡¬¬LöûÔÖÖ’’’Bhh(Æ OƒãííÍÈ‘#ñõõ¥ºº•JEqq±ì9yò¤P’ {þýûãïï¿¿ÿ®œî޼ð œ8q¢Ó“ót§Ø`‹/¦ªªŠÌÌL eÚÙ³gYµjUhüýúõ#**Ên“ºcÆŒá׿þ5Z­–ŠŠ ›ýÛ·o'11‘¦¦&êêêÄÛRÐudøðá̘1ƒ3f0jÔ(‡S”J¥"66__ßN½ÎÖ­[;Üm÷œ[·n%::½^ODD:Îj%¼#Å´iÓX¸pa¯´¶»óçÏËçŸNss3W¯^¥°°½{÷Š·¥ ë ˆ££R©Ø¸q#ƒî²{X·nÝC†Ìš5‹ððp6mÚDBBÁÁÁ=ª^çÏŸ/÷ÿñâ‹/RYYÉÆ‰ŒŒ”‡K‹ŠŠ€–\8·oߊȈP&‚{âîîN||¼PD&((µZ——*• €úúzyhoÓ¦M,^¼˜sçÎQSSâE‹„Ò¢"é¿üå/åžÙ!CÐh4rÎððp %y™è‰„é¦,[¶¬G$Ú8«W¯ 99™3f0hÐ Š‹‹åý&“‰ãÇË)Dï´w#†°º!)))v+°YYYœ?Þ¦¼;çeoõ…Ìš5‹¯¾úŠàà`þñ-._¾Œ››C† •, ˆ «?~|˜††  ˆ0 ‚®D­Vßs*¯À±ñññÁÇÇǦ¼»¦ž6m¾¾¾455ñÈ#ÐÔÔD~~>¼óÎ;,[¶Œªª*:DXX/¿ü2¯¼òJ™ê-¸7â3W tÈc=fe vîÜ À+¯¼ÂÛo¿-—»»»“ššÊÖ­[©¬¬dÆ b¶·ÆÆÆ“͘Íf9ÜFcc£üÉi‚žÇÒ¥KñððÀËË‹U«V¡V«­ÒðöéÓÇ*~–Á``×®]Æ.Ks èBrôèQ"##9pà€Í¾ºº:þò—¿ðꫯråÊÖ¬YCdd$ÁÁÁ ­ =Œ‰'âêêŠR©dòäÉ@‹odÊ”)”——·ûáxîÜ9ššš¸pá999½"ûco ¹¹™~øA.6l$99™°°0žþy«“***pvv&44”3gΰgÏ.]ºÄ‡~håDkhhàøƒÍE[W¶ }q8;Ó¯_?FÅÕ«WyõÕW‰ŠŠbÉ’%ÄÆÆ2eʪ««IHHÀÏϼ¼<’’’ˆ‹‹£¾¾ž %öÒÐÐ@jjª\óÀ‚ôz=ÎÎÎÔ××ãææ´8„“““mŽÝ·oo¾ù¦Ð¾@à øùùYå5jóæÍ£¸¸˜ôôtüqœœœ¸ví“'O&77—={öÇÚµkY°`‹…yóæ e:0Jþüç?Ë?•J…¿¿?§N’W¨räÈ %ÅbáÆ 4ˆM›61tèPœœœDU èeŒ5 …Ba“ìlÀ€TVVZlc±XHKKãðáÃ@ËxYY™P¤£öX¿~=………DGG-‘KÇŽ €¯¯/!!! 8Ù³g³hÑ" yòÉ'ñóóZzëׯÇÉÉ OOO,XÀСC™9s&ÁÁÁœ:uJ>î÷¿ÿ=ûÛßäíÊÊJÒÒÒÈËË#==](²'>}úNÿþý–YmÓ`ÊYéFŒAxx¸ì\½777&OžLZZZ­€÷Þ{‘#GR^^ÎØ±c9vìO<ñï¿ÿ> ,àÂ… ¼ð üýïç¿øÙÙÙB¡Žl@à§àää$ÿíììÌ“O>IAA¡¡¡h4”J%‹E޶0zôh ill”—$&&b4Å¢Za@AodĈŒ1ª,11Ñæ8///jjj¬¦çååñî»ï’——´ÄÜ*--JD ôÆÏøñãäéýS§NeΜ9Ì›7_ýêW( 9´K]]qqq<úè£,_¾€'N––FHH%%%lß¾½^À7„’…=7 Ñhèׯ^^^Œ9¥R)‡†?}ú4¿ûÝïäX[·oߦ¼¼œšš†NVVeeelذ‹ÅB\\™™™"?‰0 ã’——ÇŠ+ä!—ÇÆ™3g„rþ gggvìØaU–€‹‹‹¼ýðÃS[[Ëã?ζmÛÈÈÈàÓO?ÅÃÃI“&qäÈ.^¼È—_~Ivv6¤§§c±Xäó;ÔeW]¸¼¼œ… Št >úè#+çïÑv½Ó÷ßOZZ‰‰‰ò"ÚC‡É‘¦N*ûÉ'Ÿ´;eµ¼¼œ½{÷rìØ±^¥÷‹/’F£!''GÎzMqq1Z­–šš–/_Naa!ƒ///¶lÙ¤I“xíµ×0 ”””`0˜?>.\3+ :‡Ý»wÓ¿ÿ®1 cÆŒ± r¿”””p÷î]FŽÙ)÷vüøqfΜép²‹ŠŠpuueðàÁÿsÙMMMdggìpz¹_ Å}k±XäõQÐ’p騱cܼy“qãÆÑá¹Ï>û,Ï>û¬Mùõë×eAgcO}›L&rrr˜6mZ»ûÛ¶©Ù³g-ëEyÙ@«¤ígë4áÿæÚµkhµZyùAgrëÖ-êêê3fŒ]t™Í£>ŠZ­îòv"ç+’ŒŒŒ éƒ>è4ùË–-sHÙ|𔑑Ñ)²ïܹ#½ôÒK©{pþüy)11Qºr労zõjI’$iÍš5Ò•+W¤èèèn§{^«¶¶VŠˆˆ°Ûõ<(9rÄ.×úú믥ýû÷Ûí[·nTZZÚ­Ú‰ð?“I“&ÉH£¢¢Ø°adÓ¦MBA‚‹Ãe$œ>}:f³Ù!•½mÛ¶N“ýÌ3Ï<ÐþƒàîîÞ©/ÂÎÔ‹½ !$$DÞöööæOúS¯k‡]ÍSO=õ@юĆ èÛ·¯0 ?WWW‡m9.ëîîÞi² ^^^©AïÒ·½ü]A¿~ýD¤»ÓvÆŒ@ ÚÝÏC¥RõØyƒ úgr/m“ Iä ÁO W;ÑóóóÙ½{·M¹ÑhdË–-ò¯m®gA÷fß¾}|ûí·îoÍiÓ•|ÿý÷üõ¯ípÿ§Ÿ~Ê×_-*Sð“)//—ß_ñññ@Køü-[¶`0Ú}ÿedd––Ö®¼¦¦&¶lÙ­[·„–¹ü{öìaܸq6Þ\\\ eÖ¬Y\½z“ÉÔé÷ÓÔÔ„^¯çÒ¥Kr™ÙlF¯×‹$]÷É»ï¾Ë!C8pà@»:KKK³Z¿ÑUÄÇÇ3gΜvì_|ñwïÞ%''‡ÂÂÂ^Yeeeèõz***D£þ‰xzzJpp0ùùù¼ñÆ„††²qãF›÷ßwß}ÇåË—©¨¨àäÉ“6òbcc å­·Þ¤•úúz†jÓPœœÐjµ|üñÇŒ7N¿—¤¤$Ξ=Kzzºœ„§¹¹™³gÏR__o78pÀaë³²²’ÁƒÓØØˆÅb±Ú§Óé0›Íuù}ÖÔÔ Õj¹yó¦Í¾ºº:zè!T*½î™¼sç»wïæìÙ³ìܹ£Ñ(¬ÁOÀÕÕ­VKBBO=õ·oßF«ÕR^^nóþ3¸¹¹ááá!÷PÚRZZŠV«¥ªªJö¨ªªB§Óa±X0™LGII ÕÕÕ~ý3gÎÉܹså ÌÍÍÅÏÏ•J%×:<“••…N§“¿´ÓÒÒøâ‹/(**â›o¾‘ÏÉÉA§Ó¡Óé(**’eܸqC.o5PŸ}öIIIèt:Nœ8áðuzîÜ9ù뫺ºšC‡qúôi’’’ºÍ=F«:èíFˆŒŒÄÏÏ‹Å"·ù“'O¢Óéä!å~øAnÃm3fggËm¸  “Éd5¬yéÒ%Ù0•””È2Z¿¼oݺeU~íÚ5yÔ¢µL§ÓÉ2Úʾ×ð©½?R®_¿Î¾}û8zôèŸíÚµûzôZ¢P(˜8q"o¼ñ‹/¦¨¨ˆ¥K—ÊÃUŸþ9«W¯ÆÛÛ»S§È š››1 øûûË!ZsG_¿~]>Öd2±hÑ".]º„Ùl–‡ß¨ªª"%%…+W®ÈÆb±`6›1›Í¤¤¤PSSC||<ï½÷ž\Þ*Ãl6#If³Ùæ Þ˜7o;wîdøðḺºOjj*Ë—/'%%…Y³f±råÊ.½Ï™3g²råJ"""¸}û6K—.•¿ §Nʉ'¨¯¯—C ÷š››©¯¯§©©‰††ÂÃÃqww§¡¡E‹QTT$·WI’HLL”ÛðÅ‹ÉÌÌäôéÓèõzÌf3ÅÅÅ,\¸ƒÁÀöíÛ­zÙ­¹ÚwìØ!˸|ù2œ9s†U«VÉåû÷ï§®®ÎêX³ÙÌÞ½{¬d·ý»«IMM%22Rž·`ÁÂÂÂxþùçmÞ£GææÍ›äææòØcqôèQ^{í5YÖ‹/¾HXX˜œ…VFt9ÒèÑ£¥—^zI*++³Ú·}ûvéÂ… òvcc£.o'''ËaJKK¥uëÖÉ¡5$I’Ž=*íÚµKÚµk—ôÄOH¥¥¥6! Ún;zXã¢×ë¥+VHÒæÍ›; ¥“œœ,™ÍfiÊ”)rÛŽŽŽ–öìÙcÊäü£TYYiÕ®cbb¤’’I’$)((H–ñòË/K»wï–>ùäé³Ï>“_»v­ôïÿ»Ãg£7??bH7 11‘°°0víÚõÀç.[¶¬Ã}ß|ó ÿú׿ Äd2=PWöîÝ»ÆN]@(´%00Í›7óÖ[o±~ýú{¶y‹Å€ ”Ï6l˜Õ°Kccã?÷ïßßFF{Näö(--•=B‹Înº€tcRSSIOO'77—+Vüh4ܾ}ûòÛßþVÞöññ᫯¾¢¸¸¥RÉ;w~ôš³gÏ&&&'''ž~úé»LàøCГ'OF§Ó-ƒ‚‚˜0a}ôYYY899qõêU %ÔOLL }úô!33“•+W$Ëðóó»ç$‹¹sçÊ2 %"ðÒ¥K1b111¸¸¸Ü×3Ö£êA,$ìTWWÛ|íWVVÊCOOO4 ’$QSScslÛóM&&“ F#ËpvvÆÕÕFC]]ÕùmϵX,”––¢R©xøá‡EÅìŠÅbáÎ;xzz¶f§¶¶Ö&”GCCƒÜÃpqqaàÀVÏJ¥âÍ7ß$66///y ƒ‡‡ÍÍÍxyyµ+Ãh4¢P(ä°IµµµôíÛ…BaµÂÛÛ'''ôz=>>>ôíÛ—ÈÈH’““ED`_Ú*j/fQGq©Ú–¹¸¸ÈÙÝÚ“ñßç·ÝV*•øúúŠ t J¥ÒÊx´¶ùöâ@©Õêvc_uôÜ´×®Û“Ñš¬•¶÷ÓžŒãÇóÏþ@ž2Û[øDºoñŸ†IEND®B`‚snd-16.1/pix/all99.png0000644000076400007640000000771711341464473012616 0ustar bilbil‰PNG  IHDR§Ñ¿íSfsRGB®Îé pHYs  šœtIMEÚ '~_zaIDATxÚíÝÛr£:Ð åÿÿeÏCª\ÌEH­ÖZOçL&1èÒÚR°ççù|þ€Ô&M€Ô ƒ¥ÞŸŸŸµ?ÿ¥AèQ$ò¾~ÿobïYïZœýùóùtâ @—©× .ùSïõÈûóMÛV¸xËovƒ})ÞeþÑŸ|âåîn¸uþ~,‰ê˜9ÛõÊrñ‡t‘î¾Â-Pé3žërtüû·ü7¼Ç 7qÜ߸¯ ·<w5oªá¦¥ò‹^ù™¡fÖû{U¿Ù¡

Ö¬YöööAAAæ°2•y‰ð›o¾Y´h‘™×àîKß¾}BÑÑÑüÏþóÃ?P©Ôõë׃ŸòèÑ#kkk'''ð ³™5kBH(êt:>ŸÏápâââlmm###ß\â8Î€× ]#--M.—Ÿ>}º¸¸x×®]‘‘‘III¯³šJ}eͤ¥¥±Ùìwß}÷yi®]»VRR2jÔ¨¶L Û±cLj#úôéž¼~,--ßÿ}b;77799yРA¶¶¶'N| W•bG£Ñ|óÍ7L&óàÁƒ-ŽjÏÎÎ.((ððð8tèT*mñ<µµµUUU8ŽWVVªT*ð Ë‰ŒŒÜµk—‡‡‡Ñhäóù_|ñEUU•D"i1ñóöwzI˜••åèèH,_·~ýúÇ?«Ÿo¿ý–˜†´~ýz"œH³r2>>žøt³téÒS§NYZZ‚æF#ÜûwÞ)..Þ³g•Je0ƒ:t(‘æÄ‰EEEÇOHHX¸p¡••U÷k^ºtÉôñT£ÑL›6íÊ•+Ýw .ÐSñõõ]¿~}ccc]]]vvvfffBBÂíÛ·W¬X¡P(Bþùçõë×8ðʳ^»F„b±833³éž††FY˜'ÖÖÖÖÖÖþþþàøñãwïÞ%H‘‘‘‘‘Aô¸¾&:88 „ÔjµÑh4ʽyó¦……EXXB¨W¯^½zõzðàAÓòm÷îÝ7oÞÄ0L.—7;í°aà ¦Ð-x…(F,¾}ûêõz>ŸÏd2-Zdêüܶm›³³óÖ­[B‹-Ú¾}{EEÅðáÃM³–B ,X°`BhãÆŸ|ò †a!‰4iÒ¤ö,­––6qâÄvNî …—.]"–©mÛ·o_´hQ;OrûömµZÝå7#•JO:ÅçóÍÁ,ùùùB¡°ýƒûÛy37oÞÜ´i“é'…B¡Ñh¯»MùìgÍüÑ´Íãñþõ¯µr†U«Vi4‘HtñâÅØØØv.唓“3nÜ8GGÇöœ¤¬¬¬¦¦fÒ¤IíÌà“'O¶ÿ$ C.—›ÃÍ‚‚‚31‹MYYY—ßLïÞ½ÓÓÓKKK‰ŸëÖ­kOÒ•ë‰á||>¿ý‹©ñx<*µ½ÏB£ÑìííÛÿ\2è§£Büµÿf¨Tj‡,´Õ!fa±X¨7vîܹï¾û.  OŸ>¯»:j†¬X±¢ý'quum} !Ô´¢òʘºÂ»üfìíí;ļb–š‰Yüüü<==ƒƒƒÛK0F º˜®/ gÏž ÙtGFŒÁår{‚a /ÐM!"·¨Ž@"€7I„gΜáóù[¶lQ*•-&¨­­]°`ŸÏ¯¨¨€¼Ì„ÒÒÒO?ý´•D¨Œ 6<;̼DxêÔ)N—––6f̘ݻw?›@ |ûí·›7oNKK;|øpqq1d‡“’’òÇ€ÚNQQÑ?üPUUõ¼¿þúkCCCZZÚ¤I“vîÜiÖ"ÌÊÊ6lB($$$??ÿÙb±ØÂ‚‰Ú«W¯òòrð€Îx©›íÊæÉ… –.]ÚJ‚ìììÁƒ#„>|ø — ‚•{†Fb›F£CI$•JÅ0,%%…B¡iÈd2™L6 T*•D"éZdáÂ…&{ö„6!ÐÙܸq#%%eîܹt:=))éÎ;ÉÉÉ111•••/^tvvNII),, œ;wî‘#GètúþýûÁt]Èëá?þñƒ–——ÿòË/“'O6í=ztvv6BÈÓÓ“J¥æçç——————÷ëײçeùé§Ÿ®\¹ràÀ¥K—Ξ=;+++00pÓ¦Mwîܹÿþ¨Q£ˆ˜~}úô8pàÕ«Wi4Úœ9sRSSÁtÏ£ªªª¼¼\¡P”——›j¹zõêØ±c‰í9sæ=z´¼¼üÌ™3&L0kz{{ÇÅÅ¥¦¦R(”¸¸8ÓþèèhbØ4‹ÅZºt鯿þšššºf͈óÊÆG!„>þøã˜˜˜;v´X¡Š‰‰™:uª§§'X¬Ž9rèС€€€ÔÔÔ[·n;¹\.Ñ$ „„„ÔÔT­VkŠgj¾mB??¿Ï?ÿ¼ÙÎ5kÖ4ýI„×^Õ«W6,111$$$""bÛ¶mÇŽ;wî܆ À8¯F‹ñùW¯^múéååõ¬cC›ð …ÇãÑét‡#‘Hjjj$IYYÙÊ•+;»k€Žà)wïÞ ‰D"‘hÈ!DÍ„ çÏŸ?}úô¹sç|}}ïܹ“m4U*Uaaa@@@¯^½.^¼Öë*àEâÀÞÞÞŸ}öFûþûïkjjöîÝKüE, 1fÌâ§©IØ´Ÿ íbÈ!ï¿ÿ~mmmxx¸F£xã Bàu3yòd///¢ØQm!ðr´s½ÀLEÈf³'L˜  Á^ÐFˆå<;L„ùùù†=xð, m§¦¦ÆÛ»Wˆðþý?ÒCÔ@xY<<\ÜÝ;@„!!`Pè$ €!€èB^ñ;¡X,Q*U!kkˉ РPh‘BfÀq ‚‰By«ÈhÔ9:¬$Ä0,''·¶V`0 CiiÅ;w;äVt:Á`FƒýÛƒŽD"Óéé©1©T 2™†ãøK]Îh4FƒÁÐÎÛÆ0¬í_¨:õ•D§³L?étN3gÓë ÝW6ŸðåD¨ÕjÿüóÞ€}Ãï^80¿ù²¾{7_.W4ݳsçwYY×ÌÇЋµià%™L¡R:Â`Ð:£Q§×«*++JJJ_êryy÷ïܹwöì…vÞvaaÑýû]®@‰¬Ó) ƒ:NñðaQ]ÝÇ{,[¶Z§{qñxíÚu3a}£Sª£ l6›ÅºÂf¯ ‘Ä•`×ôúí$ÍT“J¥ÒF„‡Ãæríe2™L©¯#„x<.›Íª«;ö˸q£ÜÜ\=<ÜI$’L&ç ¶¶O£|*J*•¢Õê¤vv¶VV–8Ž——Wÿº¹¹´­¾^¬P(B66Ö66Ö¡ŠŠ*¢Xpvvb0èõõb.מHÉåÚët:FÛØØh4b––{{;„Puu^o`³Ym}‘iFcó÷¢««óõë¹nt:Øc0 …Á` nÃ0©´Ã0*•Êáp¨TJ¿~ár¹¼²²ªéãXX0" âqT*†á:ÎÎÎ!¤ÑhRS¿Ÿ:õ„qZ„££ƒi›8 ‰Db0 ™ÉdÖ׋‰ˆ–$R‡E_k©J×éš/-ëëÛ;7÷6goŠÇ¬TªjjêB..Nt:]­ÖB„•JussÑjuµµuß~{ÈÍÍÕÊÊÒÎÎV*m$lÕ4‰3H$÷¦¾Çf³x<®L&'“É„ïq¹öNóG&üŠF£²ÙlFãääˆ E*•!dggceeE\«®N¨Ñh\]›ÆÕëõ*•ÚÚÚª¾^Bж¶¶2¹q§ˆ°¨¨xèÐÁ,Ö{&"„èôLƒa ¶@§S „$’†ï¾K3ý;eʤÌÌßÊÊ*x<.BˆB¡,[öá¥KWòó 1 ³µµY²d!F-.~|ôè/nn΋'#„ÊÊ*233dñâäsç~/*zº©»»ëßÿþn³{+--OOÿ·éçܹüÛ·óLUe;;Û¹sùk֬߳'!Dl¯[·iÀ€§ƒ-ÿþ÷w+*ªL¯Þ’’'mq82™b0hžýÃßß÷áÃâÐÐ>ÄO•JuïÞ¹\>~üh„ЩS™G§ÓYZZVW×¼÷^Q¨šòïñãÒÿ;cÔ¨á %3ó·yófÚÚÚTVVëõ†º:ÁÈ‘ÃBuuB…Byóæ-„qZ„Б#écÆŒô÷÷%Š‘ŠŠ*;;[77×K—®,Z4?#ãœ@ ?~4™L èœbŠa†–öSlllêë%ŽŽO£îÙ“J’Çã&&NOM=Lt4 „¢¢"}|z;öKYYűc¿DD„5|çÎïfÍú»««‹)ø!]$ª' ŽŠŠÜ·ï éŠ“'Ç]ºt¥°°ˆBhåʚݕF£ILüÇèÑo?ÇŒ|åJÎãÇO+2 λ~ýj»ZÇIDAT?O×2tqqš1ãi,ç;wî^¸pyÈA®®.?ýtÜtÎÄÄé„·wnÇL+H$ uu‚©S'#„þøãjii9B(.nì!ƒBÉÉKw¯®®IHˆ÷òò Žê×/œÃaŸ;÷;ñ388pûö½›6­³µµÙ»÷€Á`øõ× ³f= †úí·‡ž¡DÒ`ggÒ!Äá°,-9çÏ_þ쳕Ä˸î³ôíº|ù"2™üý÷G«ªªsrnL™2ÉËËC¥Ru”M®_Ï•JCCƒ º@ tttpqqöôìE¡P´ZƒA7¹©I„,óÝwãF#Žã±±£i4Ú?OH˜H§Ó‚ƒŸNðôì5lXôÀý›^+!!ÞÔ&´±±îÛ7Œ(Õ‰UÏõzCrr¢••†aßÔäO]ÂÌ™wqq&r'1qzNNî¢EI¡úúú+Wr† ´råGeeÍ”³víÆ5kžÆKÌʺ–œ<!d0èþùTPP@eeõôéS‰ñ?~4ñÎzž„‡‡N™2éøñ“ÑÑQ÷î凅‡„¹¹¹"„RS«TªqãF8qzïÞ ‹­[w „¤6¤p¹öÓ§Ouuu¾wïµµUxx(Q¿lWe§Ì¢‰ÄD©åììà[Pð°i©Í/Ô§™””HTL%á”)ñϦï×/\¥Ri¡ƒƒC[®bggKniH‹Åb2™e¨¨Èk×®‹Å6›uôè‰eË>Ôëõ 4U©T5iå㦎£3 ÃŒ–––8ŽÓhÔg}¶‡ iÇŒÁ`4õ)Y,–••Õ_H]<‡¦™W(•JSÿ·çU_/Fÿ«Óš!ªåbñSßãñ¸}úVTT½¬ïýùç½k×®V’HˆÛÂÂ!´té‡!¹\¡Õêììl]]B¡¡}ärq]¡PÄåÚ9;;u–ƒƒóó ßz+ŒL¾Ø¤VmC¡©ÕJÓ톆ö±¶¶"êÄ«®ÅÚZNNîÝ»ù‰$1qÆ“'e/f=xð0;ûæàÁ[ÔqN„Ð!ƒžMPPP”Ÿ_H<¼@ Ä0cXXŸsç~'\­woO„‡‡ûÉ“™!­Ü•@ ¼¿-Öq 3’É-TÀòó cb¢šÞYYEccãÊ•Q©Ô¢¢b++K•JÉd2ûõ 'Òܸq+7÷¶ŸŸ••¥TÚ˜“ssôè·Éd’R©²´äÄÇÇ …" 3J¥DOÔZY,¦T*“ÉäññãB/þa0çÌù!TUU-Ö;8ØÛÛÛegßŒŽŽòññú«G—äííÕÒ2õt:!m³ýƒQ"ið5íY¿~kß¾¡!â®ìOd1“iAì'ª'OfVVVM˜0&(ÈÿäɳS¦LÚ°ákwwW„Pddq™L4(²¾^Jìqqq&Ò´6›ETà‰·N·¶¶R(µµu-¦ïÕËí“O–^¹’³lÙêyófýj„ E¢z£ñåz§)I«“F×è”:5Ï“×Ú}ÓhTkk[2y™üˆL– dS£Ù¬×2y!‡Ãqpà) jmmíèèààÀsrr$*]îD“Àßß·±Q†þÎ;Èd²L&Ç0,(ÈßÒ’CèÖ”ÒTo¬¬¬¢Ñ¨4ÕÓÓƒFkþúàñ¸ C£ÑÐhÔAƒ"=<ÜCCƒkk ™F£Nœ8Þ‚ Šh4ê¸q£ £»»«›› ÑçaooçââBÜ•¿¿ï„ c›ÞÀsUˆc……---)2±Žµ^¯¯¬¬6u™¾@(JGÎÎŽ¡ÐÐ`©´‘D"ùM¼)ärEDD‹Åb0è<:Îb±(ŠÑh´³³¥PÈjµšè§1½ÝÃÃCêë%l6kèÐÁ¦&™›› qç~~>*•šJ¥°Xìþýû²Ù¬†©é¡¤ÒF^gèDZüü+SŒN§{ô¨ÄË˃ÅbþåÇ®ÑÑQIFÏ`0ýE¢zjaaáéùtòA` _}½¸oßP__ïÀ@&Ó"22Â×·wdd?‹TW' Ñ¨t:ÍÛÛ‹Åb9;;ÊårjmmåääÈåÚ»¸82Œg=ê¯~5²‡‡›§§‡¿¿/‡Ãvuu ô'“É:ÎÉÉá½÷Þurr R©îMmåááîììÔ»·çàÁo©ÕjŸÞ,S­VÓhÔû÷îíÑú·¨2AµÞͨÃuj™ºîa)O“wW{·ÁØ ʃżðÆB'’‘H$Ç[ì™xsÐh´yy÷Ølñ©P­V;8p=zµóܺõgÓ0Æ]Euu ‘GMãÿßÿ- x9Ï[´(É”ƒæOÓÏlÏûä76""¬ªªº{—„$‰ˆÅ“˜8=9yÉîÝ[33ϱ¯ý,˜C¥R™L :Æb1‰g{ö¤ž8qúüùK¶¶67®5Å!4+po2Ý™¤Ñh?úh•Z­F-[öaHHŸ»w理ìB±Ùì””/étÚ?»x1 !ôÖ[æÍ›™™y~ïÞb±äÚµë‹%™Â¾~( ‘GññãüqõêeGž¸x1kþüYýû÷Eiµºµk7ÁßçÎåGD„­^ý…X,™6íãÇOoÙò/ ÆÙ³çOžÌœ6mòˆCBz½~óæí„ûN›öÎСÑpíÚÄׯ_cg×õ!™äò§7DVææÞ>xðBˆËµ[³fNg0 SúŸ~:îììxìØ¿BÉɳMÁÏÍ]„ͨ¯çæÞ&"Å_¸pùÌ™_'MšÐ,Mròl …Ù/<<Älߣ?ÿ|òçŸO²Ù¬Y³¦ø.^¼rãÆµDB>?)-moJÊ®´´½!¥Ryöìo¾¾ÞBa=±çàÁ#W®äÄÅutäݺ•÷Ì1·§›6m²¥%G ?·lÙ¾pá\":<2^,–ìÙ“’œ¼dÛ¶Ë—ºmÛÆqãþÆåÚ›‚¹<úÙý•¬Y³ÂÊÊ’ð×áÃc^xªòòÊääÙD¸òää%'Ž++«4WŒ´‡>/¼«S§Î±Ç»“ml¬‰·Ë„ cÇ…aXXX0±Çǧ÷‚³B));ïÞ}P\üdÆŒiD`÷÷ßwëÖ]ûö\¹ò#3”Ÿ ÑŠàp8~~>jµfݺ®\ù™F£A­^½Ü××ÛÕÕ™( Y,Ö† Ÿ±Ù¬7n{bbÙ·oèíÛy|~ÒôéS»ðqŒF#‘#3gþ}àÀþDoáo¿]$ZMÓ¦MŽˆ_¿~«L&C·êïïƒúòËOÉd²¯¯7BèìÙó'Nœ1ôz½aî\~PÿÖ­»ˆ ïÄkÔ”ï¡5k–wy&Ðt{Ú´ÉÄòxÜÏ?ÿ'Bè‡Òÿý2™ÔØ(#Þ’\®½ÉVtcm —••=tè`:cãêê²  >¨CÇŽŠÅŸÞ]þtĈ??ïŽ=­™äL&ü¸ãGÌtÒÓ}úé—~8Çã¶1½Z­¹ÿAë#fž — ëไ…3ŒnÜ&€îÎäÉq¯á*P@C­¨ªÈÿ3߈Œ˜c°[O­Pȯ_ïúÙ½z½ÑÇÇ«Nkøý÷?ºüéŒFc‡O¡@étÚ¬¬kfðt˜‹‹S‡Ÿà æðt†·±Y÷Ÿ:±TlÔ™LRž&¯ÆP£ÂTZ…Ö[ééÏuk¥cƬÞ1©:¢c†=ØZ‹iURUÖé,*BHd5ä29KÌð纵x¤½½™Ì›4A"‘ôz5d*ЄrL.iˆÄ¢¶vÌšC7ô< c@„"D B@„ðfÒü…N§7‡å} §¢ÓéZ¡ ©¯æß2 `)èûÙÝsÏ=çÜçž{ïyÎyÎóHsçΕ@ ‚…@ @ ø±Pî ËåÂív ) @pŠ V«1BàÌT@¾úê+&OžŒN§’à'¦­µ‰+>cÆŒ_ a‚3S¸ãö[Q*d|þ‡ƒ˜è$©ÿü²,ø…d@pF Ë2²|4Û%% ‰`0xTåJ]Óc)»®¶’7Š›"ÎlDîz9Z;¬ìÞ³—Ë.» …BßïG©T¢PôÜFøñû}B²@ 8#Xbåàa?–õµ0šÌ¨5: #2ý+N‡»­NÅwؼÈP_W‰Ñh:JeE Nsä Á`¯×‹×ëÅn·‡^ N'ÉÉɨÕj!IÁqÑÜÒBá¾ýŒ3 ½^ßo>ŸÏG D’@¥R¡T*ðz}ƒ¡t­VÛë<·ÛƒJ¥D¥R…û²F£é¥@dó–­DEE1 7瘮# âõùШÕ( ¼^/†@ €ÏçG«Õ„g>•ââR:¬œ7fôqË|ó–­˜MfòòœÐ{ùí·ß‘’’Lzz­mm´´´`2š0›MÔ×7 ÕjIMM ß»ïôü~?ͱËÈøçöGMM-ååœþÄV¦àôD¼oÿ:‚Àëõ P(±YÛi¨¯ê3¯Ñ‰N¯­”È2’$QY^LD„ sdt·çÁOuU)É)™x=n0šÄgÇäËëõRSSƒÁ` ..µZMSS“¢à¸q:œ¨¬Äçëß|¯½½U«¾à“O—°ø“%lݶŸ/¤x|¶b%/^Ìg+>ïóÜ}Ìž=û¨¯oà£E‹ikkë·®¸¸8"ÍæÞƒŒ#\Ggg'‹JÅȲÌÒeËYýÅZ<eåå|ºd)‡ãË©µµ•ššÚ"óÚÚZZZ[Žéœ£™}MHˆÇh2âõzù⋵4Ô7âr¹ØðÝ&JËÊñùú_!---cé²Ïèè°óõ”—°lù l6Û ë—V«••bÖY€ŒL08ÌOH™8˜ÛëuÓÞÖÜçÃaëZM‘=W”—íÃfm# àõº)-ÞÇãå}P œA¨Ž%³R©$===<ܘ˜Hii)˜L&ìv;N‡£Ñ ${–bµZÙ´i v;µšqãÎC’$¾Xó% ñ´µµ“˜˜ÀycFÙ¸iíí혻 öK–.gü¸±dd¤‡Ó=n‡ÐÖÖNgg'@µZÍ%S/fëÖm´F©è¯½_¯ÿŸÏJ¥bÈAädg³g÷ˆãƒÿ|Ht´…` ˆ!€Ãîà‚ ÎÇáp²fí—\zÉT¢¢"0›Í šˆ‹#”q»ÝØ:;innÁ…J¥¦´´ŒÂýûñûýÄÇÇ3rÄp4 ;w¦™¬¬,†æÁÖÙÉwßmD’$äà¡AÈ~Dt´ǃJ¥æüIP©TìÙ»—ªªjT*CóóÉÌÌ ±±‰»váp8Ðh4\yÅ´°FÕÐÐÈw714‘‘f¶mßÓé$66–sGŽä@e%%%%FŒÆÆ @SS›6oÁçó¡Õh6l(ii©lÛ¾ƒAyy¸Ü.<Í--´wtàt:Q©T´µµ“““Ýçýص{7‡5k¿äœaCIIIfûŽ477£Ñj=ê\Ì&3[¶n¥±± ZÍà!ƒÉÉÎb÷î=x}>V±–ÃÏéQGKK+7mÂëõ¢×é™0aV6oÙBll,--­äæd3lØP¼^ëÖ¯Ççõ¢ÕhÅC-©rH9œ‚ÒÝŒJ–eÒ3`4FöÊÛØPݵ¯äPÞØ¸$$$ÊË IJΠ½­ ‰¬œA¡g¡€‚3‡cZQ*C&,á“ 233±Ùl´´´àr¹0õ1k,8{hmm£­­œì,ò‡A§Ó”e<ƈ233¨­­ÅÖÙI]]õõõ 2ƒÁУŸÅÇÅõò¾Id¤™ÊÊ*ÚÛÛHJJD£Ñ`0èû5§:HyE«VÁöí;›D5 ƒå1lh>š;vàõùðûC«1ͨFÅÐü!Xm6š[Z©®®Æl2a4F„ë$‰¸¸XZÛÚ¨¯o >>c„Ö–VÚÛ;°X¢p¹œìܵ‹äädÆŒMCC#%¥eÔÔÔRZVÆÐ¡ù ÍÏg÷î=455S\TŒÃá`ô¨s{ÌÄ{½^$$FŽAGGååÔÕÕSTT€Ü\LF;wí¦ÓngÓæ-( Ο4‘sGŽ —ÑÞÑÎw71pàRRSص{yyy466QRZJ Àét‘žžN~~~ø\½^ÏàAy :” d÷ž½áv²³²œ—ÇycFaŒˆ 55…AƒökÎ4 7­VǘѣHKO£¤´Œ††F€BR°k׬6+ÕÕ5¤$'3tØP,–($I"'7NÇycF“ššÒ£Ü††vyyy œ‡Z­& âv»‰‰‰&))‘ʪ*\.*hokgø9ÃPk„y© kñA– ƒýþÈÁCÕed9ˆ„„$õþ9¤|Èá îr0HtL–¨Xêj*øý¤eä†?‚²X…gÇ´"Ë2~¿¿Ç‹P¡P€ÜeÇ 2^ð‚u¶’OVVµõõ¨¬bÄðs0DÂýÄï÷ Êü~œ.*•ЏØX %P€V«còäI½ö47·ÐÖÚÆÄ‰¨­­£¼¼‚ÌŒL ýQµ-.6–¬ì,Z[[é°Z»¦ìؾ•Z×ëÁëíÛ<(>.ž˜èmvbbEEEÒÒR{(塼qTW×PV^Azz~¿ŸêÚZ¬V+Æåãõúðz}ÄÇÇ‘”R¢l¶N” jµ†¸¸X4 Á A:;íØŒF±±±˜#͸›šÃuY,QÄÆÆ`0è´Û‘ =£eå]²Ôâñx°Ùldd¤Û£­V« ¥RAJrr0ˆÓéÂåráñ”¡ÑhB«Z-z½Ž¤Ä" J¥’šÚ:öìÞƒF«ÅårõÚ vP13›MDGÇ R©0 ˜Íær'I¨¾wõz= …„ÉdB§ÕÒÙiÃãñPZZÞ¥0ªÑiu ÍBm]= dee¡ë\³Ù„V«  C+·itX­TTT Ë2ºQ!åV­R“Ÿ2466±Ûèõzbccioï ²²J<؂РˆÜÿ ˆ„Ôíï.ÏYû9Gæ ùUH• pºì( .§“¹GÙ@pV) F“‰¸øxöîÝׯ^I’HKKE¯ÓÉž¥Øí"" ˜LFvïÙKSS™Y™áþqècQQ‘ø|>Š‹K±v³Ûw:,[¶œqãÆ’žžv¨³ªTe™êêjÚÚ;º6¡+e™’’l6^¯—ââbØ«m&“‰Ô”d¤nmiii!(Ë KuU5-­­}÷mÅ¡¶çæä°îëõ(“&Nè•72*©«ì1£GáóyÙ»g/Á`„øxü~?JJJimmÃår‘7pf³™={÷²¿¨92-‹ÆérRX¸ŸÂÂý4uS>êêëQ©UØl6å Äh4¢ÑhÈHOC§Óáñx1M$$$PQQZ­ÆçõrÎ9ÃHMIA¡X÷õ7Lœ8KT …‚¹9x<¢,ÚÛÛ»@Û¶m§½½ƒ .8Ÿæ¦&$å ¤¸¤¤_å­/¾Xó%J…‚©S/êùBR©ðûüTVU!IOcc3ÙY™¨Tª®‰ŽÐfÿœœ, ÷í§¾®žáç C©Ráóù9PYEfF:--­ì+ÜÏùçOÄf³Ùd¢pÿ~ÚÚÚB«n]3ÒÝ_j±11—°¿¨˜ºº:ñP èš[££­…€¿ï ¶è˜¸Cï8©K Ê”ûPfBJJ¨àЊˆß륺ªI’È0”ööª*KIÏÈ%ÂhNÁÙ©€(ô$ç8b¾ JÄ ÈÙŠF£Áéráv{ÈÎÎbÈ Aøþbª×¡Ö¨IMIF«Õ͈áÃiko'%% •J‰Z­B’$ââÑézÚß'$&0zÔ¹Ô74`±D1p@nx¦»¡¡ C„ƒÁ@CCS/$--5¼OC¯×‘––ŠF£eðàÁAjªËÉÎ,ú @ 8³ÞªsçÎí×°tÅŠ,XðJ)ˆÍî#W2ª F’œ±lÙ²•ÚÚ:Î=w$ii©?Y;Þù÷{ :”áDz²:dšyȃ–Ãá`×î=!ó<ƒpX!8õ ˜#£inªí7È !ÂDG[ Ñ1qh´Ü.;N§½Ï¼J•¥BÏëE§7t•]ZÕUõ4et9í F¬­X¢ã¨«­ä¾YpåUÓŧ-G½¢”$ô*åóéUBœ¹DFE‘œœDbbâOÚŽ±ç!::úÔžáè6k{ðo£ÑÈ„ñãDGœ>HM 5ø|ýDZu´è ÂÛÙÙŽÛéèwã¸ßç#ð£×‡Vךkðy½t…é]¶µý°u Á«€heñ*!0àXƒž´v È7C øP*DC@­F{L.œ#"L!ä,„Ò ŸÏ‹? öv@ðc£$´Z½„@ 8»»ÃFBbŒ˜@ ?2ûö‘›3HB œ] ˆ$IDFŠ ƒ@ üØøüÂA œ9(„@ P@@ ÁÇ ñkÕÚÚ†ÇsÈ`t´N‡ÓéÄét{hïHKK+>ŸŸ¤¤„㪳¡¡±‡?ö„„x”ÊCn‚=² :‡Ã‰Ëå&6ö‡», ¸\nŒÆ««Õ6IknnÅh4 ×Ÿø ‚--­x½Þ>¯ñhèè°¢P(0›M¢· Á ¦û·Àçóãõz‰ˆè;¾M[[;n·›¤¤DXP œÕœ™3ÿÀ[o½þ©®® ¤¤œ+V÷È»|ù*f̸å¸ë¼þúÛ{ÔétöŒN»fÍ׬YóÅÅ¥|þù=ŽWUÕ°cÇ¯ºº–—_~3üÿãÏîvM+)+;pÂoΞ=…ÌŸÿFøß}÷ÃÃæ_²ä³^ië×Ƕm;EO‚“@÷oAQQ1ï¼óA¿y×®ýš_ýê¶^ß+@ 8Û8!+ ‹…G¹¿WúîÝûˆ‰é¹êpÓM×±yó¶i6l¦¸¸€©S§’’|Ä:‡ Ô«ÎŽ+Ÿ|² ½^^­Ø½{ qá|¥¥¼õÖ»47·0~ü~ùËkÑéï³ÝhŒÀår inn!11€²² †C«íí|úérÒÒR¸è¢ ظq cÇŽB‘ +*ª:tðaëÜ¿¿˜óÏŸÀL  à!¦O¿‚ÚÚ:6mÚÈ\xádÒÓSyçÿðÖ[ïÒÖÖΈç0|øPZ[Ûhmm%9ùPÀ¼`0È‚ï`2™øÙÏ®¦¨¨Y–Ù¸qK—r÷ T*ëÖ}KEEH±š6íâããÄ#GÁG}ŠÝnïúîÍ@’$®½öšß?ÇÃþýÅãñx˜8q¹¹ÙBxàŒç„¬€47·PPðÑØØÔMIÈãÃ?=ì¹ee|÷Ýfòó“Ÿ?˜—^zã¨êܺuñÀ‡Ó^|ñåp9€üüA,\¸¸›ÂIvv&©©)äçFuÞcccèè°âóùÙ¿¿„¼¼DEEðí·ûlÇÕ|÷ÝÞyç?TTTÒÚÚÆŠ«~¬›¸óÎûÈÏD~þàðªÌ!yDG[ÈÏL\\l—¦#++“?ü$|þܹóÂmÓëõ¼÷Þ‡¬Yó5¯½öv8}îܰk×^öîÝN[¾üsñ´Á÷p»Ýáïßœ9àßÿ^ˆÑ~þõ¯/öyng§;îø=ii©äçæÕWßg'd$..–yóžë•~î¹Ã{¬ ô…ËåæÓO—S^~€ªŽªÎQ£Fôª³¹¹…Ñ£Gpýõ¿D–ƒá¼Ý÷gÄÄD3xð@4M8ÿÑð«_ý7ï¾»––V~ùËŸ…Ë4(’’Òp¾;wÓÒÒ @mmYYácûÛ?yðÁ‚ã’÷Ï>=Üî·Þz/,ëøø¸×c09òœfpÕÕµáÿü ÌæÐÞ½^×ïùW\q)'Žíñ>?VV¯^Ïç7C œrx=†FNNΉW@Ž—ë®»ö„pW¬XÍe—]tÔy/¿|êó{îpÞ|óߤ§§ö›/%%¹—r´hÑ6oÞFLL4EE¥Çum+W®¦ àŽ~71~ùåzÆŽ}ØÞ‘ðxÜ\{íô°™XAÁC}*™@ èÍÿüÏ#=&Ÿú㫯ÖãrÝ{\NLL& ¼EÀ/”@pjñþ»o±bÕ×'G9÷Üá}¦Ïšõv»Gy’gžy€¿ýíØív böìÇ4h [¶l§ à!~ûÛ[2$ïˆuʲ>àÏ~Œ™3ï §]tÑd’’B{~ÿû‡±Ûí<þølfÏ™l5’]»öRPð=6먯õª«.ëñQÙ´i+o¾ù@‹%Š+¯¼Œßýîöp;† Âwüšgžù‹-åø= .æî»o?b]W_}9óæ½6¡zà¼^/'ŽcæÌ‡‘e™3® ç¿í¶›((xˆ)S&¢Õj©ªªá¹ç^ÀétòÚkosÛm71{öãá¶Y,Q<òÈ}¬_ÿ]x¦îàýLHˆgÙ²ÏÃ&^·ß~³xŠà0ß¿ÈÈHrr²˜8q,sæüŽ+/¾ø,’$ñê«oÑÔÔÌþð?ü{t:£GŸËO<ƒËåfúô+~p;ÿõ_Wñ|£ÑÈ5×L;¡mr8\Ô4vDt™êü[Ñ)ÛIˆ=⌧ jjj©®© itÈ ID[,äå <áu­_ÿ ­mmX,.½äâ“r=~¿ŸÊÊ*ZÛZQ«Ô¤¦¦sØx5¾ÛHZj*©©)|óír²³ß; †Çãî*G—­RkÈÈÊ£²¢¿ßOtL<*Šðû¼dæ îR>N²"àÔAB:¤|HRÿ Ž—ØØbccp¹\4553(o ÕÕ5|ùÕ:âãâHNIÆïóÑÐЀÏïÃf뤨¨˜ó'M¢¶®ž}û III¦µ­–ÖVÆ˶m;¨oh =-»ÃALL4^¯·k@ïÇåtÓÚÚÆÚ/¿ Ü}~öíÛÏ¥—\Ìþ¢":m¤¥§a ¸¸„ööRSS¨©©Åd2b6›©ªªfòùIKK _ËAÅ`Ĉ ‹ÏçÃátRVVNfF[¶n#11ŸÏOYy9L>¯×‡,Ëø¼>œ®P`Íí;v2xÐ bbbظi3­­­D[¢Ù·¯ÁƒÁæ-[IJLÀåöp ²’)L¦¼¼‚Ý»÷’’‚B¡ :&šH¡€¯þ ÖKÊÈr×O×{#!±·ƒ%›­=¤¬4ëì*Ûh4“š–M}]%ÍMu( 2³¡Rªü'nD–åð†:@ ?~¿ÿ4©—"Jîú[*ÈÉB©T2dÈ`ÒÒRñù|hu:lMø}~:;íØ¡à”:–‘#†³s×nl6Á`^‡J©$”‰Ž‰B©T’‘‘@jJ Æå³k×n$IÁ˜Ñ£ðû,YºŒææÌ‘‘Œ76|¿Íf3ÆããÅŸb4™8a<°ZmtÓ?Aô]æä*• ­F‹ÓéD–åÐ5 D0(³þ›oé´ÛIOOC’$RRR8眡=ûj @uu5ùùùäÌ×ë¿¡¦¦–ÜÜT*ƒ¢£ÃJQq ­V‹J­&(‰ŠŒB£ÑˆŽtÊA‚ÁÃ( ÝW(d¹Ïü¡•©WZ0 ÂhB¡Táõ¸‰‰I@©T ލ|“¢×ë())wT ‚‹%ê(•îŠ=V>ÂJˆçÉS@ ´]‚ÚÚÚØµk7¹¹9˜ÌfÚÚÛÃ3•JJ¥B!)å]ýàAy¤§§Q]UÍÖ­[‰4›ˆï¥àÁ`xuD¥ åtZm=…B$FsÈËÑ÷‡¡ã:êêëIIIÆnwÐÖÞFBBh@)Ë2~€`0ˆ$…Ìùö%¹©«>Ÿ—@ €ßï›|) Ô=.u™é¤¤$IsS3»vïA­R”½4g]«Á#ÎUì2ýå?¸J~qt+»ºª d™¸ødš›êÐhµDYb kMå„( rs³ÅMàGF–!pa>ä ŒÛíîxö4½:¸GÀ³ Á‰C¯7`6›©¨¨ 22ê°º!dÂÔØØ„ßç#*ÊÒ§7©ÜÜêëøüóP€áœìlع뇷Ód21zÔ(¶mßÁG‹2±±± ~ÍMÍȲ̾}…tX­¤¦¦„•ᤤDöî§¶®ž+¦].O­V3bÄvïÞCyY†qãÎÃãñöYYY9û‹Š hµ¢¢¢Dç9xÜNŠ wöyÌ`0’–žÝ¥$„5>½çÉA$¹Gÿ øýT(!à÷“ž‘‹J¥F«ÕR[s€€ßOtlüZÅ@ δZ míí¸\ŽCóß ôº#†GÇÁƒÈÉÉȯ¸âr C×ÀÞÈEMÁïó¡Öhðy½ètz›ƒ^¯gÔ¨‘ƒAT*%cF í­@F«Ñ„WRþßô«Ñju]÷WËäÉ“ðx<—¼\X IDATH’„N§C©TrÁäó‘¤C^Í&Mœ¾í—^2e×*I¨¬Þ1RR’‰Áçó!IZ­6¼\¥RqÎ9Ã0™Œhµ:4uWðx½\S»êª+Ðj4H’DnN6)ÉɃT*z½ŸßÏÓ.Ã`0IZZ*ƒ‘‘N0(wåÕ‰ŽuÜ„& Æ~ÞúÐEW'‘‘QªÕ44T÷Ê ±DÇZEE ›j¥¤e¡P* ÊA &’Rqwí ’NÔ Hï -Á´ß;Òn÷£*U’$¥è7@ 8#p:x<î~ŽÊø|ýïí0#ŽÙÍ»^¯'EÄaø>mx@¯R©0™L=Æ4zºî¡.<ðW…Ïé¾Êѽ¬ît !sªïˆˆøÞÿ†nýÈØoYÝÛªÓézõ7¥RI„Á€V«íqm}µ×Üí¸B¡èѵJ…º+R© _CÈ,Kl:?‘ÈÁ J¥ŠÔôþ-—‚ÁCæV¿Ÿè˜¸ÃŽûÝ.Gè<9ˆ¤PôY¶9Ò‚9ÒB 8â^³¤€(•*T*-íÛ ™8q  ÷¸¦Ré0Ep$@ œ¬]û!ÕÕ倄J¥$"„ÕÚ€ÉdfÉ’å˜Í¡brr*uu5]ƒ;¿þõõäåå! ~2RR’III‚8Íp»a…áð$I¢­¥!ç£ß1z—’èõ¸p9¢lƒáÄ+ nÙM‘T†Sã€óÕlPìdtµ R•ñìØ±»ßsM&cxÃTwÍ{Ĉa¢ÇàŒÄI’DzzµµÕz$I"99µk¿$>>Žˆ# ñX­íDD0›#IJJÂÇL_«d‡#Âh>ê¼jµuäñ{*ûÁ{@ü Ôùëz*û|HÑù,[¶£ÑˆN§#11‰ÒÒT*III¨TJ’’â‰C§ÓSSSEZZ¦è-@ 8c‰ˆ0¢R)IMMa×®½DFöüà'&&b³uaèaq¬" =Ýk ÁŒ ÒÑaëfvx#i^z½Ž¸¸8/ƒ¥R‰Ùl&ðc2™HJJ¢±±¥RItt´¸[ÁO̦M›ƒŒ7®ÿ—Š,óé§Ÿ²zõjnºé&ÆŒ#'111ºÜXÅÇÇÒÙi‹ŽŽÆã mÜŒ‹‹¥¼üQQ–öá'ˆÏç?^¯—ÂÂBFŽ8·ß<Š“Ù‹Å‚$IaÿχÒc¼ÄÆÆ×L@ 81lÙ²…ùóçSSSsØ|Ÿ~ú)Ì›7ââb6nÜ(„'“ÉŒ$Z•HLLÀë=äS×lŽÄãñtSVEÀ‚3‘“æ†7==ƒŽŽv¢£-ÔÔÔ!ÿÐá%™ÔÔ\].»~L>ûì3Lffæ)uCZ[[±Z­dg‹˜+‚¢¢"n¼ñFZ[[›oõêÕÌ›7€1cưråJÆŽ €Ãá`ñâÅ}žwÙe—{ZÈbóæÍbeGp‚ß÷™’’„Çã&22 ·ÛÙã˜ÙlÂnw Á ¡€tGB»ÄIkU» £)Y’g yëm~Qãr…^¸J¥NO0(£Õj©®®£¦&äkØï0â0K4'‹?ýéOüþ÷¿?åòòr …"øQ¹þúëY·nÝñ½LT*rrz{ì¹ôÒKYµjÕi£€¼ýöÛBœPœN7›7÷tÎâóùÉÏFLL ……Å=V@€p, @  HZIõƒ®Â“eç» ;{¸áݽ{)))½fRcb¢±Ùlhµ Hnî dSn2™ÅNAdY¦³³“ÉöïñxÐjµx½Þ^6´ZmŸûG¾ïõîT¦®®Ž5kÖˆ/8¡ÄÅÅ1eÊE½ž-…BEyù»$&&ô:ÇlŽ‚B9å½Ò „J¥F­VàptÐÑa¥¡¡‘1c„^à§â¹çž£´´»ÝNqq1³fÍB«ÕbµZ±X,444À3Ï<ÃìÙ³Ñh4Fî½÷Þ3JV«•¢¢"Ñ!N-ZÄþýû6lW_}õI«çwÞ¡ªªŠ±cÇrñŇӷnÝÊÊ•+‰ŒŒäž{îaçÎ,[¶ŒˆˆfΜÉÞ½{ùä“OÐjµÌš5ë°uDDèèhé‘ÖÜÜ‚Ï'¢‘ ¡€œ0RSS9rx¯ô@@Æf³SYß}÷µµµLŸ>½ß™Ô¢¢"öìÙþ?77—áÇ‹»+%7Þxcÿ®l˜Ífêêꈋ EHU©T<ðÀtvv ïu‚“Ɔ xë­·˜?>7ß|3ééé'å¾téRV¯^ÍSO=Åu×]G^^©©©ÜqǼþúëüç?ÿᥗ^âí·ßæÅ_dùòåüýïG¥R1eÊa.+§Š"Iee%½ÒÛÚläæ}Tׯ¾úŠÚÚZ’““yíµ×¸ùæ›Ñëõ½òéõzbbb¨­­eÅŠBŽþž)Š^ÇŒF#F£QMpÒðx<ÜtÓM$%%qà 7œ4P.—‹[n¹…ôôt®½öZü~øØ„ 1bÑÑÑ|ðÁŒ=š1cÆ‘‘ÁË/¿ÌöíÛÙ·oÏ<óÌi%[ŸÏ‡Ý.Üôþ, ßw&ÐÙiïÑoG‡N§C¯×õHóûý=ÜS N]L&*•òÔS@N~øaØãNEE………œ{nï ëéé餧§#Ë23gÎäÅ_>N馵µ´´T-ÇUŽêLJaa!ƒ>¥Ú´téRž|òI¡€ÁÆÌ™3)--=íÚ™™I^^†¸Ç€ÃÑ·ù¸N§cĈ¡(•"úüÑ ùâ‹oú<–‘‘Î!¬ñT¦¢¢·ûøcø)Î$¡üûßÿæú믽C ø‰Y¿~=Ë—/gùòåø|>!Á1à /¼ÀòåË™?>QQQ'¥ž¤¤$ž~úi>ýôSÞÿ}:;;ùꫯضmo¾ù&³fÍ";;›½{÷òÊ+¯pï½÷’››ËwÜÁ{ï½Ç´iÓÄ ‚3I¹øâ‹Y¹r%eee´··“››>vÝu×±oß¾ðÿß~û-C‡Ål>u\úvttàóù¸úê«Y²dÉó¯Y³FxàœH’þ9¿---â&þ„ 6Œ^xI’˜?> 8)õLš4‰§žz µZÍ‚ HHH÷Ùwß}—ÄÄDî¹ç®½öZÞ~ûmÒÒÒ¸ýöÛ™1c¿øÅ/ÈÈÈàŠ+®7ì(iiiB8‰¸\n ÂfëÂ8áã9+ï½÷••Õ<ôП~P9åå¸ûîY¼ûî³^¦§´ Öÿûÿ¥K—²dÉ P«Õác^xaY±„„ÒÒÒN©ö¿öÚkTVVrÍ5וbQWWGGGÇ)¥D ?„‰'†ÿîþÜžüñdöìÙ<ÿüóâFþ„Œ9òG©gìØ±=þ ##ƒŒŒCfJ©©©aYS§N7éyòÉg™7ï9!ˆ“„^¯ò=Ix<^ÊÊÊ»Þ i<÷ÜS?¨œììLž|ò^zé ¡€œŒBëëëúpçå :æ²®ºêª>Óï¼óÎÿ÷ùT ²²’ôôtfÏžMss3÷ÝwßaÍ Ö¯_/fÔ@pFñØcfݺo((xˆ‹.šÌý×UÌœù0/¼ð€ðß?ü? zš›[Q©”ÜpÃ/1›M¼úê[¸\n.¿|*W^yéY+ËÂÂ"ÞxãÜn×\3K.¹ Þgþü7øè£wHLŒÇï÷sß}¡GUUµ¬]»„7ÞXÀŽ¡ÐK$÷Þ{±±1¢“~ 6ñÞ{!Ë2‘‘ft:-ÿû¿óøðÃOÙ°a­­í¼ðÂK´·wpÎ9ùÜ~ûÍL:#†áñxIHˆãá‡ïë3œ„ÛíáÁÿ„úÞrËõ¬Zµ–k®¹‚¬¬ î¿ÿ1þú×§P*•g”|OŠRWWKjjr¯ô˜ËYÓqŸxâ ¼^/ÉÉÉdeeññÇóî»ïÒØØxXäƒ> ˆ@ 8«éèèàþûï§±±‘Ù³góÒK/¡Õ†>þF£‘Ç{ŒY³fÑÐÐÀý÷ßϘ1cxùå—Y·nwß}7—\rÉQÕÓÔÔžR*•<÷Üsèt!× O>ù$UUU´µµñ /ðî»ïRTTDkk+÷ÝwK—.¥µµ•¡C‡òÀˆ›vž~úØl=fèƒÁ`¯¿ƒÁ 7ÜðK²³3innaþü7ÈÎÎ$##!CòxÿýEgµR^^ɨQ#HHy‹:ÞàÆ¯£ªªæÐO¥bÞ¼çhiiã½÷òüóA’$Ö®ýš[o Å~Z¾|55uBéƒE‹–ðÜsO¡ÓiÙ¹s7K–¬`Ö¬¨ç³Z­DFš¹ðÂIÀ¡UÔ„„xž~úOhµþð‡'ðz}}* jµŠŸý,4Ù^QQÅ×_o ”‘e¹×sr&¡]ìÄâr¹(..F«ÕÁoû[4 ÑÑÑ\qÅ|öÙgBH@p 0`Ï=÷¯¼ò ÷ÜsóæÍcòäÉL›6ÊÊJ, sçÎeÁ‚TWWãt:™;w.ï¾ûîQ×óÕW_1nÜ8æÍ›‡Íf£¡¡!|lÓ¦M<ÿüóÜrË-|ðÁ|óÍ7<ÿüóðÊ+¯ð—¿ü…çž{Žï¾ûNܰcÄnwr¿êp8zÄÒè+ÞWg§Ž+Vn¹å†³Z~^8 ‹%*,¥KWVÖï¼ó>¿øÅψŽMû|þð¹&œGV–ðˆv$úê“IKKeìØÑa™.^¼ ­VƒRyäaö«¯¾>·ºº¶Ç1¿?€ÃqfÆíQ‰nubYºt)ÄÇÇsÛm·õ8–MYY™’@ †ñãÇ3~üx>ÿüsÇÇår±wï^®¼òJ ùË_X·n‡ØØX–-[†ÝnçÒKmf|øðá( † Öë}m2™>|8û÷ï'33“ÈÈH†Î!CØ»w/~ø!O<ñ„¸aGÉyçË#<‰V«á¾ûîa„óxä‘'Ñh4X­¶p¾ÿû¿×ðûý(W\q)QQQ³iÓ6}ôþ³ZŽ%%e|ýõ†°7~üy,\¸˜Ï?_Kcc3÷Ýw7ii©LŸ>ƒ¼¼<ÿüÿ0gΟ˜2eRX–£G$2Rì;í‹iÓ.á©§žE–e‚Á &“1Ü?7lØÄ#<É£ÎÂív³jÕÚpÀÔÔÔŠŠJøŸÿy†@ ˆÁ`@­Vsà@ÿûÿ±}ûNòòrùå/Fjj2ß|³1¬0&&Æ3iÒ8^}A̙ׄéœH( '¯×ËÞ½{˜/--êêê£Þ0ßÞÞNss3BN2¯¾ú*sæÌáá‡Âø‰q¹\|óÍ7<÷\ÈdgÆ >ƒÁ@ ૯¾âÙgŸ¥µµ•3fÍ{ï½÷£Ä]r¹\Ô×׳víÚ^Ê‹ o®¿þ8NÔj Z­†ÌÌt®¾úrÔj5<ðÇp¾¼…"äE/""¢Ké˜E0pL;[>|äö’ÇÕWOcÚ´s½^R©ä“Oz®J’Äwü—˪ԢcöÃEMæ¼óF2Z­6lõë__ÏM7]–½ÉdäÑGﻜ?¸Zrî¹#ºúmF‹Z­"--…§Ÿ~¼‡ì¯¼ò2¦L ™o45-))ãÞ{ïÄh4âp8…"è§ÓÉ‹/¾xDÛã‘#G²}ûö£V@jjjذaƒP@‚ŸÏwÚyí:±Ùl¼ýöÛüö·¿¥½½•JÅêÕ«™3g2Ùyã7øÍo~ƒÇãA–e W^y%+V¬8¦º***˜4i•••=Òp¹\TTT¡ý"‡ƒP]]Mll,/¼ð·Ýv÷Þ{¯¸iGB¡Àh4†ÿ×h4<òHÈ›ÐÍ7‡”ÆŒŒ4´ZMx vƒA/xy„6I÷”[wyD©Tö™.èÑqT²×jµ½úlVVFxÂäp²—$©WZ(ÒKtvÚ9ï¼Q(gÞŽ ¡€œ \.|ð£FâwÞáž{îé3ß°aÃxã7¸æškz¤øá‡8=µ\¯×ÛÃ.V 8]øË_þBmmmX9Ž…Ý»w³zõjŠŠŠP*•Üpà =ÜòVTTðÙgŸQ\\ŒÇãaîܹtttPPPpLÇŽËí·ßΦM›hjj¢±±‘ ðÇ?þ‘˜˜îºë.*++y饗¨­­åÎ;浪ªŠ»îº‹[n¹…ôôô®yOdYÆívÿäíÈÏÄ_ÿzÈ©ÛíæÖ[o>ŸøV¨Õ ¿?@ зL‚Aù0}“SîÞÿPî¾ûÖ|-‘‘&þô§‡Âÿ{<žS溼^pü¹Î*dáÂ…¡˜'’9sæðè£RYYI||<7ÞxcŸùÙ¿?ß~û-&L§ïܹ“„„’““ÃmûôÓOihh@£Ñˆ·šà´¢» Ó¿ÿýo!Á11qâıdFþ{èС,_¾¼ÇñÇ{ì˜ëIOOgåÊ•½”€ùóç÷Hÿ~\˜_ýêW§­|m¶N–,ÙCrrªèlG©°Õ×7õ{üË/×c2E 9ÉA²³SÐëµlݲ‹¦Æ6JE× ¿‰ÎÎÐ>“ÉŒFÛ÷Öáp°hñ*“ÓDÇ;EÙ»k S/¾X( ÇÂe—]Æ”)SøøãOX¹Û¶m£¼¼œ /¼Å‹÷^Õßàlùòå=ƒ¤¤¤pàÀvïÞÝm¶ ÈŽ;1b„èù@ 8n²²r°XâØ²e‹ÆaˆgÊ”)ø|ýÏd+ &N¼à¬—U àÃno" ­|¤¥¥¢V«ILJ¢£½‡ÃŒR©$%%ýÅýï™MIËbÄ艢ó¢”ï=!åœU H÷ã}ùbþ!´µµaµZ™1c?ûÙÏX»víÏ9’í¥Ëåâý÷ß›øý~,X @pV`·Û)--Bf«J¥’ÊÊJÚÛÛ:t(a×”‘‘‘deeQSSCKK &“é˜Ó–””àp8ˆ'9ùPüª––jjjP«Õäçç¡=yM®ÚÛÛÃf£££OK9ñÅüýïÇ>(..>!f“Æ £¬¬ì´7Á¼ð Ã—GK÷~P[[Kss3™™™áX`MÏd'Z­–ƒƒž;vb2™Ž¹ —ˉËÚ4a4öÚk!8={@Ž“eË–ÑÚÚJBBB8íHKó’$…½)t' öøÁÙÈ›o¾‰Á``éÒ¥\~ùå\rÉ%,\¸-[¶0iÒ$¶oßÎùçŸßïgëÖ­<õÔS\uÕUðÚk¯1þ|†~Äz¶lÙÂÌ™3¹é¦›xå•Wøüóω‰ d»öÚk¹üòËYµj=ôŸþ9`Ñ¢EüãÿÀï÷³eË–-[vÚÊúÏþsû555'Di1b gݰêêj®¾újvìØVdß|óM’’’X¾|9>ú(ëׯgûöíhµZÊÊʘ>}:’$qò°X,@h¼“œœDSSóQŸ+Ë2¥%ŸœNô]›¹«*`‰‰!##ó¨Êðù|ȲüƒLÙ}>~¿­V{Êow»]H’„V{úŒ!…r|ýõ×8p€­[·²xñb¦NÊøñã{^ZZMMM¸Ýî ÇæÍ›Y·n7ß|³®@ 8k)((`àÀÔ××ÓÔÔÄþýûY¸p!üë_ÿà¯ý+?þ8V«•Ûo¿[o½•´´4ªªªŽJ©¨¨à™gžaòäÉØív:;;à È9çœÃ#<Âõ×_Ï|Àßþö·p»¾üòK,X@[[Ûi-놆^ýõi:.|­ÍÍÍüë_ÿâ¼óÎcÿþýØl6¦NÊêÕ«ÉÌÌD©T’––Ƙ1cø×¿þEss3“&M"11±‡¥A^^^ØùÊæÍ›ùòË/Ãå<øàƒTVVòŸÿüç´–eII Ÿ}öçŸ~8M¡P0yòd&OžLuu5ï½÷ ‚yë­·ųÏ>ËÔ©SÏ8ÏT:¾Ç'>>žæ–Ö£>¿´¤˜˜˜XâZ‹P­YÝ5jUÑzËmtt´e9bëÖ®ÁjíàgÿýËcnÿšÕŸóÊÿÍãÉ9Ï2tØðc>×Ží¤¥§c‰>¹Qæ7nø†Ï–-A¡Pðó_Î`Hþé±¢&ã`åÊ•TUUõp©;}út!@ 8Nîºë.ìv;o¼ñmmmèõz.»ì2î¼óN ä)§µµ•”””°¹ÖÉ”)SøýïObbâi-çÜÜ\æÍ›Àƒ>ˆÛíæñÇçå—_`À€\wÝu¤¥¥ÑÐЀÍfcúôé¬^½š††þùϲ|ùrÞÿ}î¿ÿ~yävïÞͨQ£HKK£¾¾€Ûo¿^x€3fPZZJ[[Ë–-ã·¿ý-£Gæ’K.aÕªU§­,SSS¹ãŽ;xðÁÃiÑÑÑLž<™ÊÊJ–-[Æï~÷; ´Âö¿ÿû¿ø|>f̘qFºÅ5›M½"§¤$ãöÙ3”ÃaÇãv¿†ÿºÉf $âöîæÀÃã7šÂJnss›7n ==“¡ç ÇãqãñºÉ0 ‡R£V«Ù»g …’˯¸ €Mßm ¥¥‰ŒÌlò‡ã²iWÒØPߣ]µ55ìܱµëÙÈÀAƒûlÿ¾=»yóµ—Év99¹\8õRª«ªˆŒŠ¤¬´„úºZ.¹ì Ôj5»vl§¦¦ €±ã'Íþ}ûhllÀét0$™YÙ´¶´°ñ»oB}--s†‡Ìô×~±Š{ï{«µƒªÊRž®ŠL»òš›š‘imn¦¢¢Œó/¸µZÍšÕ+IMM§³ÓFVvÉ)?žcŠ3ϱðÌï~÷»æW@ 8~î¾ûn~ýë_óÒK/qàÀ&NœÈK/½öZõÊ+¯pë­·¢T*’ö555ñÚk¯pŠ?6¥¥¥PPPvIuu5ÕÕÕ´¶¶ö;8v»Ý8N>úè#ª««Ã+SV«µ×Êиqãx衇x衇˜4i²,c·ÛY±bUUU|ùå—a³¥Ó½^ß§uSS‹-⦛n Ç…8èîyîܹ¬\¹’ŽŽŽ3îv{¼¬ûz}Ÿm[·c³ÙŽxn}]IÉÉh^Hùe4o½‰ÁéÀå:dÞ÷Æ+/a0D`0D°mëfêë$ ƒ!‚·^5œïãÿÿß~ƒ!•JÅ[¯¿Êæ(Ü·ƒ!‚U+—ÓÜÔØo»Þ|u~¸žÅ‹>¤½½ïPµFƒZ£A§Ó¡ë L¨R©xüP¸7T׫óÿ „âá,óW^ÂïpÇ-7ât8BíãU‚Á ¯w»Æ]Û·S[SMC}­­­”••˜”Ì^Ì¢…„ÏÕju¼þÊK(•Jæ>3›ï6|ƒÁÁë/ÿím,_ò)ë¿þ’šêjÞxuþÚ?Ä Èäõ×_G­V3bÄÎ;ï=ö …",G‹Å² ÏÈÕ6k)Ý;$>.ž¶öæZW|B"Ë—|ÀØñHL Õ;墩áôƒÜ~×Çív3çÉ?Ÿ˜Hzz:\x1ÅEûIMKï·ž/×®ÆÖ¥mß¶…›o½½Ï|æ1p`ç›ÀÀ¼A$%'£ÓéøÕ7‡€;¶³uóFÊJK8ÿ‚ ¹âêÐ{låò¥È²LbRRøZFŸ7Ž”Ô4Ö¬þœå|ûõ:ÒÓ3ÑëõTUVð‹7’œ’B `ÕŠåDw™–þæ¶;{Ô“KTT4 ·A( § <ðO?ý4Z­–+V0bÄ£C èƒÓ9ˆ$I˜Íf¬V«P@~"þû¿ÿ;lôâ‹/¢Óé(**bæÌ™<ýôÓØl6&OžΟ——Ç=÷ÜÃÌ™39r$W]uÕQÕóóŸÿœºº:fÍšÅ<€Ýnçé§ŸæñÇçÿøsæÌÁb±ðä“O2kÖ,$Iâ±ÇcΜ9Ü|óÍÌœ9³ß˜O§ _}õUŸÏïAs©ÚÚZž}öYž|òI, .äç?ÿ9~øaŸç_y啌3†1cÆ Ù¼y3¯¿þz¸Ì5kÖ°xñb:::صk×ÓowíÚÅk¯½†$IÌœ9“Áƒó‹_ü‚––î»ï> äsöìÙ<ðÀÌ;—æææ°|‡ˆŒŠ¢££ƒþ¢x½>ŒÝÆ_ó…×ÿzýöíÙÍ¡G·bHþPÞ|í˼©“ IDATe>[¾”‰“&“;``¿yÏ5†çþ>Ån·SVRÌð‘çöHŸ0i2Ûÿ?{çVÅÑà¸ôÞ,*ذìFì-Q4š-,Ñ`ï11vÅ^¢±"Qc öÏ®`¢Q±béÒ{çÂ÷ãÊÆ+h4ÑH™÷yx¸;;»³{¶Í™9åú5äùr¯ð"8è ³¦~óÊýØÙ;ðÅaŠïêŽmܸNû\ù㊟*)oB‹–­yõago…ò†ð¿ÿýC‡=ìðß²`ÁfÍš%.†@ (Ó888°zõj¥²/¾ø‚/¾øPÌ$Ť|:ˆµ«–“››Ç¸¯'KŠ’’òãT›?¯þçDl«ÙÑ´y TUUp¨^ã¯÷aš¨¨¨ ª¦&µ]£¦#5áÁm«Ù¡®®.Õw:‚ÕË–žž†ŠŠ ßL›UlÛššTµµÅµSW445Ь H 33“¥K—bddÄ€wê~W´mÿ¿ÜÏ¡ ¯qÅÌ”P@J…¼o¿ý___\]]ÉÏÏÿ×/¤6mÚйsg TĉÑÀÀ¢££Y°`cÆŒB ”¸yó&666dff²gÏ.\¸Àµk×ˆŠŠÂÅÅ;;;9~ü8;vìÀÕÕ•‚‚† ‚¯¯ïµ3cÆ ¶oßÎܹs%$99///|}}8p ...xyyáííͰaÃhÓ¦ kÖ¬aóæÍŒ?ž®]»þ«Á¨ŸŸ-Z´y,ŒŒŒþµïÓµk׸yó&½zõ*w~TG•"£¹¹¹¡¢¢Â¾}û¤õÚÚÚ 4€_ý•ØØXêׯOÆ Ńÿ tuuÿÖBäßÒëã¾BÐBùœ8*@ýú„‡‡cnn.e'ÐÔÔTšxW1---ñòòâ»ï¾+²NEE…¤¤$ªW¯NDDD™Œ.¯âÑ£GÄÆÆ2vìXÌÌÌhذ!K–,Á‚½{÷âîîŽL&cïÞ½äåå¡®®N~~>¹¹¹oÜÆÂ… ¹té’RYtt4gΜAKK‹ÀÀ@Ξ=ˉ'¤oÂÙ³gñõõESS“ÐÐPüüüJµ²wï^Iñ÷÷ÇÑÑñ_+ •+WæäÉ“ÿí¾~øá<==ËDð³gÏ’œœLãÆX±b_|ñR°‚¾Ğ={°°°ÀÆÆF„ò‰ÔÔdžE† A”Päy¹ïd?BHJ‚çÚõž={°··ÇÁÁ7bhhˆ¥¥%ªªªôèÑã6ûw‘ZnÞ¼‰³³3999â ‚rC­ZµX¼x1¾¾¾¬\¹’mÛ¶qöìY¼½½‹ Ä1|øp~üñG¢££©V­šà[’ŸŸOff¦´œ‘‘Á”)S°°°`Ò¤Iœ:uŠ-ZH>Û¶mcРAlܸ‘‡0fÌjÖ¬‰¥¥¥R‚^€ .H!›5kÆ€ظq#{öì!<<œ5jHIúJ+Õ«WÇÉÉ |}}iÞ¼9 š°mÛ6är9nnn’²7oÞZµjqðàA*Uª„‹‹ Ïž={oíuîÜYI)œ¶} ¬¬¬¸xñ"ÖÖÖâB J<¥1შQ£†¸x%€ëׯóèÑ#¢££iÕª·nÝbÖ¬YtêÔ‰úõëK3iii,^¼˜={ö°~ýz6mÚ„½½ý·sàÀbbbøý÷ßiذ!C† aÙ²eŒ1‚Ý»wKm=zôooojÔ¨Áðáà ÅÇLJ*Uªðé§Ÿ–9ù¿8[G‡hÞ¼9gÏžåÁƒøùù±páBNž<ÉÆ9yò$‹I:WÈ7$E%;;»Ìš*:uÀÈȈ™3g©çääÄŒ3PSScÁ‚¤§§—9ÄÈØ¸Ø\išZšâ%' H!~~~YYYDGG ›QA‰¦4'"|xV®\Éýû÷E¾ÌÌLÜÝÙƒ4h@nn.Æ)rÙÚÚRPPÀþýûßú½hkkËöíÛE¸ÕŸ~ú [[[ìí퉎ŽföìÙhjj2iÒ$¢¢¢hÚ´)šššŒ7Žˆˆ\\\J}2Zccc<ˆ©©)ñññèêêrúôié{´k×.©nË–-ùí·ßpvvÀÐÐ?þ˜:u ßjÕRä%ˆˆˆ 88¹\ަ¦¦´nÝš>}ú ÿÇBS.kkk)¸€­­­´¯Òª¸àêêÊÕ«W144ÄÔÔ___œœœ$‹ ccc®_¿(¢lÉde¯;feUÕ—&¶RSS‰ŽŽ~ã}ädg“š–*™êêꢧ§‡ººH-2ÂÞ½{Ñúè#–,YÂüñŸµÛ¤I“"íiii½²~XXûöí+6I”@ ” ”Ââêéé)-«««+-׬ùÏh5h œ™¸p†ÙÐÐ¥ògŸ+W®,™+•vÆŒCVVU«Vå?þÀÉÉ {{{É”mÔ¨Q¨©©кuk´´´¤XM›6%==]RíííÑÑÑ!66V’_rr2¦¦¦Œ9RÊš®¢¢"ùˆLž<™;v`eeUª•B…öéÓ§’<*V¬HõêÕ©U«÷îÝ`äHE~‡áÇsùòezöìY&ó{ Ï—++9Ùo<+ž••EjJ2zúú˜š*Öôô4BCB¨X±Ú::âe)ÒMáôqaùw•`ðM°±±! @©lÉ’%ÅFÆà]òâ¬Qá·OCCã•3ò/Û·o_¤Ž³³³4KRHÕªU_¹Ï×Íþ—&ªT©Rì¹4jÔˆF)•ÙÙÙagg'nÀ×KåÊÊÁ tuõ°³wàwÿË4m.üD„RÊ®ªÊÖS§JŇâÏ?ÿþŠ%Þ=ööö<~üø­ü ïŽØØX|}}IMMeܸq$$$0bĬ¬¬ˆŒŒdñâÅL›6 ÂÃÃYºt)7nÜàæÍ›|ûí·Ò~¾ùæ† "™¿¼Lxx8£FÂÚÚšääd6mÚ„ÎóQÕñãÇ“œœLDDk×®eëÖ­DEEÁš5k¸ÿ> bÅŠÒà•@ x7$%&bldüêþ¥ÑÏžaai À~Ÿ½üáUE†}5š;·¤ä‚ú 6’Ç’››KDX(ªªª|>d¦¦fü¸y=I‰‰tîÖƒæ-Z²iý"ÂÃ004ÄÄÔŒÑX³rÆ&¦Üø“*ÖU1j, ‰ ¬X¬È*¯É¹¦ð‹ý˼ëÞÛ ¦0oËÎÊBMMÆ¡?³x…¢Ÿtíßñ»tô´4ZµiG³¯¿!++‹ïæÍ¢¹K+š»´¢]‡ŽxNôÀ¡z TUUY¼Â ¿Kˆyî·b^Á¯ðbûÖM¤¥§abl"µ}ùâynÜ$%5…ÅËW3åëqŒŸäÉ~Ÿ½ŒÿÚS<$åNñóƒü|¶nÝÊÍ›7íÙ“\‚ž<¡oX67nÀë¦Cõõ?¸0}útòóóÅ+Ê,FFF´hÑ‚þÊP˜ìÏÁÁ˜˜¥emmmÚ´iÃÁƒˆ§k×®Lš4éoÛrpp@UUµˆ9L¥J•ÐÑÑÁÁÁëׯcee…žžöööœ>}šÆ3fÌ/^LË–-K­¬½½½0`W®\ÁÊÊŠªU«[wöìÙ¨©©1gΜWî/%%…K—.ѵk×rwßfffÒ·o_ žxÞ¿Ÿuë!KÛ¶mË£G¤è€Í›7gàÀœ:uŠÃ‡—ês?ƒ5³þ/÷ÁCGpúÔ âã°´²zåVvöŸ8ÔØØ„ÔÔT<'z ££Ëàa#^ØÞ^j`ËÆu’ŸÔý»w¨f'fÎ…RÈðá }îüp¥qc®8À‰f͘4qTd„’Èo¿þ"ýÎÏWÌž4lÜ”µ«W›“CÛöòôiÑëVÍŽc¾‡¹w÷uê9“——§xl‰Móòò^Ý‘–ÉHOO~+/Òªm;q1˵ò\]]KddâĉäååÑ A† RnîÓ:лwo@‘gæöíÛ˜››sàÀ¥zsçÎêÁÁÁÄÇÇ‹‡ü%ôôôxø KK+ HLHàÙ³(k)GLûrøWD?S˜lêë`jfFßþŸ€¦¦V+b[ͽç¡555™øÍ4ŒML011%óy†ïJ•«ƒ¦¦&Ýzô`ë¦õ,ø~ Ý{öF¦®®ÔöÀÏÀƒ‡"SW§~ƒF¨¨¨Ð£×Çäåå1xèHqA…òžžž|öÙgð<wI¢ÿþ\ºt ssórkS*(½¨ªª¢úû]àu}:þþþ?~œèèhªT©‚ Ë—/çÞ½{ÒH³··7èééѰaC6lØÀÅ‹3fÌ+Û9|ø0ÑÑÑøûûS¿~} ÉËËc×®]Ìœ9“‚‚~üñG|}}Ù°aW¯^ÅÖÖ–nݺ1}út¦OŸÎ¢E‹Š(//ÉíÛJeÙÙÙÔ¨Q ™L½ØÑo--ÍÿDÖ…å¿5jjjÅ&o, }ü"Å9§›™™½öûUV±´´$22’ädEÍÜÜ@Z.¤R¥J’ÒVÈ‹éK#ï2˜O%ëjØÚÕ/ÂÊåóÇ„RhÚ´)Ô¬ùv[PPP‘˜@ øçÄÆÆJÁ‡eÚ´iüùçŸÒò¬Y³?~UT yƒ{ëVVE;⦦&T¯^{ûjEÌ—’’RÄPÊøã?ÊõùËåïfÇØÄ »â†*¡üîwúìGø€|ò 4o^¢ÑÃãHlöÉ“'¿²¾O¹ ‚²É©S§hРíÚµcÿþýÅ®oܸ1={ö”‡7ÅÄÄ„† ˆ®®n‘~sss¦L™Â°aÃÈËËcРAÿú|ÂÃC }ªôwçÎmq¡ 33ƒ„„xâÉÎÎ)#@&ƒçY,K*êêꘘ˜`ôB¹œœœWÖÏËË+÷‚G@@þþþøûû¿6“@ðO2d]»veçÎÅ®ïß¿?}ûö-=ëMfîܹ¬\¹’úõë+­KJJbÇŽœ:u 555Ž?^&ž×-[¶üí7#!!¡ˆ9чÄÛÛ›¾}ûJÉýþîšþ7åL&Mš¤TöôéSÆÏ‚ $§þ}ûöááᇇ7nTò‰ŒŒäÛo¿-÷Ïx~¾œ˜˜h222ÐÒÒFKK›””d¢¢"Éý¡€þ;\\\hÚ´©„ ÄIpp0ÁÁÁäçç ÞŠäädrrrÈÈÈ -- wwwÒÒÒÈÌÌdðàÁèèè––FFFººº¸»»“žžNFFîîîèèèžžNzzº’ÃË <˜””är9ƒ büøñœ ¥ãÇÓ¹sç×΀’.]ºH¿ÇŽ+"x+vïÞ-Í<œ:uŠ^½z±yófÔÕÕiݺ5õë×—BÁ®_¿žÜÜ\)H§NèÚµ++V¬ 11‘mÛ¶½²Ï?ÿlll¨_¿>çÎÃÈȈHu Xµjžžžœ9sSSSŽ9ÂO?ýÄ!C”ê–F¶lÙ"É. €7n°cÇ©lêÔ©xyyñçŸâëë‹L&ãÖ­[Ì;—'Ož°sçN °µµ¥_¿~,Y²D*ÓÖÖ–ö‘’¢ðkQQQa„ üöÛo#—ËQQQáÓO?%44???iûöíÛcll̤²ZµjáææVìùܾ}___@IrúôéìÝ»—[·n±jÕ*êÔ©Cß¾}9|ø0ןçSQQ¡{÷îÿ:¢YPP®®®J HZZ:::¨ªªR¡B)kü¢E‹8tè...˜››Í–-[˜1cF¹Ïÿ•™™‰ššEÖNjj*úϳš=Ágïnœë7 S×îœ:q MMMü/_¢b¥J|>x(^+—‘‘žŽL&cÒ”çIK÷ìâi°BéþÕd2ë׬âäñ#„…†Ðëã¾ÔttâÔ‰cÔ®SÛ¶ÐÜ¥%­Û¶'6&†7oÀÎÁ¾nŠÄœ‹¿›OAtìÔ™ÜÜ<´µµ±°²âw¿ËÜ¿w—ñ_ƒ–¶6G~û•;·A*>ýì *W±fÉ÷ßbgoOAA¶ÕìiÔ¤ì > ¤rìØ1¼¼¼øõ×_‹¬»~ýú+CN Ai`ôèÑEÊæÍ›'ýÖÕÕUZ~y}qËÅQ«V-¥z'*5iÒD©ÞËËíÚµ+²Ž‰‰ÁÛÛ€ßÿGGÇb빸¸¶¶6;vàÉ“'4lØ=z _Å.]º “ɘ9s¦Ô…R¡R³lÙ2’’’hÚ´)áááÌž=›Û·o“ššJÇŽñññaýúõdddð¿ÿý°°0d2öööœÞtëÙ›a#Gsçv¿ÜOXX(»vÇÄÄ”ììl};ÆM›¡o Ï°‘Š÷ÎÙ3§èó‰ÃFŽ&"<”a#GKíÄD?cݹ3L˜4…m[6àèT›Õ+–0aÒ.]8ÇÅóg9{ú£=& ¢¢ÊÒEß2{Á÷¨ª¨0Ì}#Çx0läh};¹ Ѧ]{š5W$ï]±ts|Oô³(j¡¢ªÊ/|¨ß°j%ÜU@( eœÊ•+Ó·oßW®ß¶m›¤€¬\¹’æ%ܹ^ MMMÉÑÞØØø· £zIII¯ ÑZ¸®N:R™––2™ >þøcvïÞM… ¤ã|]–Í›7Ó³gOrrr$¬ILLDCCiUªTÁÎÎî½É777—‚‚ÒÓÓ¥ó}Yù7nœ4K¤§§‡–––¸AßÖmÛóÃB…‚éP½.­Z£o`@÷^}žZèý,ŠÌŒ V/_‚¶¶6ùùùT³w ';mmLŸ‡þ¤ŸbVÓÔ±ÄX@ IDATÌ --m©@&S§÷Ç}153ãÓÏÜ126";+Kª£©¥ENN†FFDD„£¢¢‚¶ŽŽjÛªbEZ¶n Ààa#ÈÌÈ`×OÛzüH¡Ô?ÿ¯¥­–¶6ª**eÖßE( %€â¦_…¶¶6+VD&“¡¢¢òÚºOž<Âþ!jjjÈåò27êTÈÊÊbóæÍT«VnݺÄÂ… hܸ1;vdéҥ̙3‡ *°sçN.\¸Àܹs©R¥ ¹¹¹Œ;–Y³f½2_Òµkר¶m***¬Y³F*ß³gþþþT«V‰'’››‹‡‡ÖÖÖxzzòË/¿pþüy,--™:u*2Yéý”š››ãâ¢}}úô)ªªªôéÓG2ª\¹2þþþ4oÞggg6lØÀáÇ4hµjÕbýúõœL@@žžž899aff†··7êêŠü*…ßÉ^½zááá±±1cÇŽ¥ÿþÒÌ¥¥¥$ƒí[·Ø¼y3þþþxxxàèèÈèÑ£i×®ãÇGWW—‘#G°bÅ œ9xð ß}÷’vðàA¥ 3å ]]=RR’¥¤¢/“œ”„Cui9=-y `ïî‘𒉣¾´nÛžÜÜÔÔdÈÔexNŸ­ÈU£ÚÚ:œÛ·oÇÆÆ†^½z1aÂÆŒCpp0†††â ª¦FMG'¬«Ú SWG¦®ŽCuììÞhF pÆãCðÅ—ÃÐÕÕCGW—ÊU¬%_Á ïV!‚Ò‹¹¹9±±±Je999KÓÚyyy<~ü˜›7o¢££CõêÕ…àïE‹IÉÁ cþ ÿ”7Ò®];–,Y¸qãèÕ«IIIüúë¯üïÿcÍš5Ô©S‡“'O²dÉRRR$dáÂ…RÔ¦—y±£¢¢"…y}¹sóË/¿ššÊ¦M›077gùòåôéÓkkkz÷î]êå[xÞÅ»àÝÈòU÷VáºÂò×Õ+¯èëëK3 oƒCõô¸_6·¤\qþüy@ŸÜØØX( ‚ÿ„©S§J¿wïÞ-"x+öìÙÓ'OÈÎÎæÔ©SÄÄİfÍâââèÖ­«W¯æðáÃüòË/X[[“œœLÛ¶méÛ·/õë×gútEl---V¯^ýÊvV¯^Íxüø1gΜÁÖÖ–72vìX¼¼¼hذ!ÎÎÎT­ZPD)Ú¶mûöíÃÚÚš•+W–zYoݺ•€E‚Bÿ ‹wòíy×>%   6mÚ$ º´nÝš¾}ûréÒ%~þùg´´´>|¸’ß˯¿þÊŸþÉüù󉋋cÕªU$''Ó¾}û2¡Üþ¢Ÿ…s7àªx–Pr²³„"ø{:„•••”V J:...RNZµjEhh( pHŽŒŒÄÝÝ]2úæ›oèׯ666Ò~nß¾µµõ+ÛéÒ¥ õêÕ“F›Ïœ9ƒ……ÎÎÎ$%%ññÇciiɃe]®P¡-Z´ÀÎήLDH»yó¦ä8’’‚††¹¹¹œ={PŒ>7oÞ\Š€««+ Èè]8ß¼ys4559wîk×®%;;›ÚµkS±bEîß¿/EÔªZµ*5jÔàþýûRÎŽÂß>äéÓ§Ô¬Y“   Ú¶m[jdùìÙ3ú÷ïOýúõ ÅÇLJððpüüüX¹r%YYYÌ™3‡Å‹Š\$…yR~þùg>ýôSœœœX»v-o[¤,œ_fCÏþSÒÒRÈÌHǼ‚Õ?–¼Ü\¡€ü“‘ž›7oH³²ÄÆ‹”ikk£££C|||¹Mh$J…3/òâìmaþ†B444ŠÝuppxm;zzzJÛÙÚÚ ££C… Šm(³áQ X³ft ¢¢¢HMM% €ØØXZµjÀ¦M›hܸ1~~~’’çããÃgŸ}Fvv6ùùùÒ€ .ðàÁÚµkÇþýû>|8ëÖ­“”ŸÂß[¶l¡iÓ¦¬_¿ž àíí]j²Í·hÑ€øøxöíÛÇèÑ£‰‰‰‘ÂækkkK¹IŽ?Ž\.§k×®’‚Û¯_?V®\Irr2:t(—Ê@uÇz87r/¸wûO‚ß§K¯üXöí\'·eèСÒï+W®”¹ó»sçŽxJ‚@aV@ ˜yúô)€’Ò1vìX¬­­)((`üøñ¸ººEpp0“&MBSS“=zpòäI)C:€©©)½{÷¦uëÖXYY½6É^×®]9wîmÛ¶eÆ ¥Jv111lܸ‘Y³f½¶ÞüùóiÑ¢ÇçÚµkxzzrðàAú÷ïO:uðòòâáÇÂlZPf&Xe sssär9 BÁòÇ(å@Ê#=ÂÈÈmmm)ñ#("-_¾\i¶£°|ðàÁҌԔ)SŠøÅøùùI3…š×•5BBBøå—_$$P˜°¥§§“ŸŸOtt4VVVÒ (2ůZµ ]]]rrr¤$Œ2™Œ¼¼¼r}?††<%+«xƒjvvÈdêâ¡ ˆàC‘MXXUªTáÆ|ùå—„„„@½zõ”ê>yòDŒò @¢oß¾JYˇ Æøñã™<%°°0˜0a€” }èСLœ8 ÆŒ(íÂÜÏÎΆÊÖ­[Y³f #GŽÄÉÉ©\ß›‘G~£á²ÅJew€]Ýzðý’ï¬{éÂ9455iÜ´y©“Q^n.QQ‘T±þËl5"<Œ§ÁÔª]Ãçæ¢‰‰ Ü¿{[;*Vª$Á?cÈ!’ÓdLL {÷îÅÃÃäädtuuEèS¥íV®\ɰaÄ‚2ÄÆqww­I‹@ð*Ú´iS$Z•½½}±½;wî̈#”Ê^•y¼wïÞJQœŠs&wvv.ÒN:u$Å(UYæ[¶lIË–-‹”W¬X‘U«V»¾¾¾d®­­ÍرcË̽%—ËÉÉÎT*Ëz‹€8²œÔ#ÂQô€[ÀWÀ²Œô"aŠÓRS‘Ëådçd£­­¾¾ùùùÄÅ)$¨««cl¬èÅÅÅ’ŸŸ *˜W¨@jJ ¹ÚÚJûÒÓ×'--ŒŒt ÑÔ,YïØÜÜ\¶lXKrr2SgÎ >>ŽýûöRÕÆ–[;pÿr8à½kV+ñû?¾ö•¤˜DðV8;;)Û»woúõëóã?R±bE!4ÁÊÚµkyöì€ät)x?lذcccÜÜÜ„0ïµs-’. Þ†  '„……)¯S§.)©‰»}00n@3 n1uݹѤisTUUÉÏ—3døW\:Ž'PPO×]·>{v‘ž®P,4j¬´Ÿ…ófáP½&ºvc½×*)Ò¦¦&ã¾þ¦DÉwçö­Ôu®ÏÅó礲¾Çâ ¥>ðþ=öìÜNNN»õÀ¶šž=¤:B¼êÕ«Ç­[·èÖ­›†à?å‹/¾@þ<Œâš5k„@Þ×hçNÖ®]ËÏ?ÿ,Á{¥yóæB‚·Bž—GÕbLèôõÞ,© ðà ´€]@t1u«Vµa’ç4dêêlߺ‰¸˜Ξ9EËVmz½»·©]·•*W!++‹ÜÜ\ΟùÍ]Zqâ¨/Ç|3cÎô HLL@MM ëª6ÔoXòü–>ýÌÌŒ %¤4¡*‘²Ã¤I“^Y–’’"…XÞ7úúúadd$2ú¾GrrrÐÑÑ)÷Ϊ‚NHHˆô;..Nü;¢££•¨¯]»&åP)”õÕ«W¹zõ*RùÓ§O¹zõ*=*÷2”9@.` h¼¢nFF:éÊ÷®LM†ƒv|Ô©3\;³ë§142ÂÎÁu¿œØÍÌa·Ÿ<~DNNúú´ÿÈUÚÞ{÷Ž'íÌÆJëõ”^LÀõbYdd$þù' 6D.—³oß>(&”455ÉÎΖ[‚7eéÒ¥’ÆÑ£Gqtt¤qãÆB0ÿ‚ÌÌLúõëÇÖ­[±³³ÃÇLJììlÒÒÒHJJ¢Y³f¬]»VÊ;sôèQ&NœHll,‡ÂÜÜœ*Uªüm›²Nª*èê2Hzy@¾FÑ÷\zz:kV,#99 3ss*V®L¯ûâ³gÖUmhÔ¸)õ6b÷ŽíäåæR±Re4µ´©«Ó´Y Zµm‡÷îܽs‹û àì™SÄ<7%v¬U»ÄÉ'==ÔÔ²³³HMIAGW—>}Ý8tðg:|Ô ¿KhÓ®=ry>çÏžÆÌÌœ“ÇÒo@Éèÿ ¤”sâÄ )Fû›ŸŸÏµkׄ"”!<==Y¼xñßæÞ„¬¬,–/_(2¿/Y³f )))LŸ>   är9¡¡¡üþûï 6L)cy$..޵k×Ò·o_@1ÃÉ×_ €‡‡Íš5#..Ž9sŽÃ , ++‹•+Wëü_^1íÖƒÇý¦¥…ás?ÿ¯ÿÜ7£+«ŠÌ˜»@©¬mûhÛþ#¥²ZµëòÝâå¯lsÀ ¿"¹Mž2£DËgïΟˆŠŠDUU••Ë~`Ȱ‘4wi…ߥ ¬\öŸŠm5ÔÔÔX¹ì\;w-1Ѿ„RŠiÕª{÷î%11QŠ~àä䤔éÝÃÃ)S¦ o¥¥%ׯ_/Ñǘ””Tf³r þ?~,… ä»ï¾CCCƒ!C†ððáCöìÙÃÀqss“|»fΜɬY³5j={ödÈ!,[¶Œ~ø¡ÜÊ222’Ÿþ™o¾ù†-[¶¼¶®±±1 77—#GŽ0räH’““ùî»ïˆŠŠÂÔÔ”Q£FaaaQnåYÍÎþëÖ©ç\îä3ì«1Å–·hÙš-[+•Ù;TgÖ¼…%êø…RŠÑÔÔDGG‡üü| ¤òþýûséÒ%iYOOUUU¥š ‚¢8;;³uëÖ}ŒOŸ>ÅÆÆ†˜˜qÁÿˆCîîØ¡°s– ÆÅÅÑ¡CâââX±biii¨¨¨ ©©‰®®®n·¼‡y äêÕ«<~ü˜€€ÒÓÓ0`@±uÇŒC`` 2™L £¦¦Æ!C°²²âðáÃܺu‹Ž;Š›ô ø|ðP!„R†P@Ê!;wîdîܹT«VMC Jxyy±lÙ2æÍ›')'ǧråÊ}JÍš5077ÇØØ˜ÌÌLΜ9ƒ¾¾>˜šš’““C~~¾ÒÀay¢  €ü|¹x•d’P2äò€·P@@ ü£Ns!NNNXXXðý÷ß3mÚ4úô郺º:M›6eÁ‚$%%ѧOÚµkWd{Á_Ô¯_cccôõõ™3gžžžØØØH™Ð¯_¿ÎÞ½{ÑÖÖæÛo¿`Ê”)’ÜkÕª¥”ȱ A]]àèèÄG¹òÑG®tì芵µµxsý *T¨€ŠŠJ‘ÎÈËhjjâé鉉‰ ÇŽcĈ€"™ÀƉˆˆ   €¤¤$HIIáôéÓäææÒ¥KTUU%Å¥p»7npúôi˜?>.\ %%…ãÇ3gÎ"##_yüyyyDDDÁµk׸víÚ+• [·náææFJJ ~~~¯}A@zz:¹¹¹Jë?~\D¡Z½z5ÉÉÉ$%%)ýegg³~ýzÖ­[Gtt4999¤¥¥½ñŒÞ‹Çò6ëþÍ~ÿž¾}û²ÿþw\qqq( Þ˜››+)þ%qß Ê"yyy`hhˆ––™™™ÄÇÇsìØ1)3z!™™™899Q³fMRSS‘Ëåôë×'''ªT©B||<öööB¨oÈÕßýñœèçDž÷QTTUÑ70Dß@˜ãå>@Yä§7ÓÂ¥‹Wx1éy&÷ãG}ÑÒÖfñ /š4mÎO?n.vÛô´4öìü‰Ùó2nâ7lÙ¸N¡,oÚ€<ï݇ÿ}/&X999dgg£¢¢BAAr¹\Z–ËóÉÌLCEE¡edd––ޱ±M±ûÚ¹s'÷îÝcÞ¼y¯)¹{÷.»ví¢W¯^åÒD¨gÏžoT¯nݺԨQƒ† rùòe&Nœˆ¯¯/þþþ$&&’œœÌƒ011¡J•*8;;Ká{öìɺuëÐÓÓ#((///Ο?··7ššš¤¤¤Ð»wo¸sç5büøñLœ8‘aÆ‘™™)ë… ¨[·.¿üò ÑÑÑÒK9??Ÿ°`ÁÂÂÂxöìYYYÌŸ?ŸÖ­[ÓµkWV¬X\.çÖ­[|ùå—EÎßßߟS§Nѯ_?Ù»w/QQQR—Ç…···tn›6mÂÔÔWWW)1Ôo¿ýF÷îÝÉËË£G,]º”[·nñùçŸ3oÞçåå±lÙ2¾þúk¥¨–‚×ó³÷¯P|GÝö£s×îdefâ³W±ÉÐȘJ•«”y9Þ»KõŽÌ9 *0zÜD‚ƒžÐ¹kwœj×aûÖMÅ÷Ýss   M444IINV xÅÆ`ö½·(XáááØØØššBJJ*ššÏ•“l²²rÐÖV 88gçÅîcÇŽÔ¬Y“?þ˜¥K—2räHLMM‹Ô»}û6üñ3gÎäСC¨ªªÒ¤I“rõð½m¶T;;;¦NЧOŸ¦mÛ¶L›6¾}û²}ûv:uêDxx8nnn¨««KÛ5kÖŒFÊãÇéÞ½;ݺuãÀôèу . §§ÇçŸ΀èÖ­r¹œM›6áééIß¾}Y¼x1aaa´nÝšùóç“››+uÀ³³³ñññáã?¦OŸ>tèÐÈÈH444ðññáäÉ“ 4HJÔŃèÕ«½{÷&;;›””rss:t(Ó§OÇÑÑQº·mÛFTT7&..ŽŸþ™O>ù„zõꑘ˜H¯^½ðôôDCCƒØØX6lˆ««+r¹œŒŒ <<<ˆˆˆàÈ‘# 8àà`¦NJ5Ëålݺììì°³³ã·ß~cëÖ­´k׎E‹qôèQHõêÕÑ××çÈ‘#4kÖ 333¾þúkòòò¨R¥ ÷ïßgÛ¶mxxx ££CÓ¦MÙ¾};•+WæØ±c4mÚ”Ç3xð`._¾Ì;wØ·o­[·æÇDMMMR¢Þ„åË—Ó³gOôôôøþûï™4iR± ÿ¥K—xöì3gÎd÷îÝäååáèèX¢ž…ÔÔTiÖ"55•GQ©R%,,,hÓ¦RÎÙ³góý÷ÅÇV×ÓÓ###£Ä%ûý÷ßùì³ÏŠ”·lÙ’K—.1pàÀ÷ŽŠÇËˋڵk3mÚ4~üñG.]ºÄàÁƒEïIP&ðõõ¥bÅŠ 2„ÜÜ\¦L™ÂòåË‹­;iÒ$²³³¥÷oáàÒúõë™>}º0Mÿ´ë èéêê2a²""ã¿ËøÙ›Oú (3ç¹jÙb"Âäå1ã¾&''‡øø8¾™6“ǰcÛ–{üïMÉÏÏ'==ƒ‚‚²²²‘Éþ©‹‹‹¡F GΟ?‡¡á«5ü«W¯òÅ_H# !!!Å* GeРAèêê2`À&M𤤀øûû±yKKKãÑ£GåÖÆ²eË–\¹rkkknß¾M‡xüø1~~~T¯^ôôtŒ_iUØ9ëܹ35kÖ$$$„5jpýúud2Ý»wÇØØXI¾îîîT­ZUrÎÓÑÑACCC©žtîÜ]]]š4iBdd$ØÚÚ¹fúúútìØ‘ôôt´´´¨Zµ*û÷ï'$$„®]»¢ªªŠ ‰‰‰\¼x‘îÝ»£««K»ví¸ÿ>íÚµ£J•*hkk£¡¡!FsõêUiÙÐм¼‘®×§Ÿ~Jdd¤ä;4eÊ‚‚‚¤úÑÑÑRýâ¨^½:M›6-Q!n»téòÊwWDD –¼ú¦¦¦xxx`jjÊÕ«WqppàîÝ»%òXßkkk6mÚ$“ ¤ïêîÝ»Ñ××çáÇ|öÙgÒ{ñÉ“'èèèM£FHLLäÑ£Gäææbee…‰‰ Ó§O§U«VÒw×ÉÉ ##ŽöM026æ+Šwâ/û}hÒ´9¹¹¹RÙí€ôí?°LóøIE£ jhhЫâ{¦©©Enn.––V<‹ŠÄ¶š¡!O±®j#Õ %7'‡jvöÈd2PQ!/7—œœtž³ IINÆàç˜z/ ˆL&CCCƒÜÜbbbŸ/«#“ÉÈÏ—£ªªÆ£G©X±"À{Y -ÒyÐÖÖfÍš5¬Y³Fê$Éår¥¼ïŠ÷æ3==ývì–.]ú¯ö}êÔ©¿­Sœ¬W¯^ýÎe}öìÙbëš)ý²Þ³gÏïûïüçÎ+ý^·nÝkëNžkr¹œœœœ"#Þ†¬¬,ÔÕÕÙ°a6lø`† (ÌtUTT”fWKËy¼È“'O8zô¨4¸"(ç`##>ÿüsŽ9B:uhРééé„„„àììü¼ÃF£FHKK#$$ † €««+±±±¤¥¥ÿgïÌãc<ÞþÝl6׿¾äBE"APꮺJuÅ:ÚÒªêIQEµUÔ­‚ª¶¨³(ê¨û>rˆÈ}g“ìõûc“WV6΄àý~>ùdwöygæ™wž™gž½Ú—‘¼Ü\Ž>T*<##ï{Ô7‡ Éýû˜óÍ"œœéÕ·±E綠ú`÷˜>О'^ëÕ‡IãÇÍs-xsðP||ýX·z%›7n ZuOÞ~g¼pýºU?“”x‡¯æ}‹••5]»÷`úû“111aàÝ9áÁo ?_Qùgg'ú÷ï[¦S¯¤¤Düýî Õ·ºØ«W¯Ra}úôÑû~êÔ)Nœ8Á!CÊýþ—/_毿þbôèÑåžvEZ¾©¨´+²®¯\¹ÂÎ;ź~ÈåòRý àŸþy¢²:tˆ¸¸8z÷~ü­ó©S§òþûïciiùÌžQtt4QQQL˜0á±ÓX¸p!‘‘‘<³r¨T*Þ}÷]æÎûØilÙ²+++Z·nýLûÌ“¦qüøqΟ?/μE¬­­õÆÁ²ÆE///¼¼¼ôÂ"##Å ,@‡¾¶Š‹+=zé×sã&Í^º: mÜ„ÐÆMJ…÷~£?½ßè_*üÝ©è} ªÅ§_ê« º¹{TH^Ë]©Rʼn*UÊÞŽ¶··î4ý AƒX¸p!H$=µ’€€V®\IHHï¼ó‹-ÂÝÝ›7o2kÖ,±çŠˆ<:ubéÒ¥˜˜˜Ð°aCáðcVV>>>\¸p'''fΜÉçŸާ§'wîÜaøðáb剈ˆˆˆˆˆ<[¤Ñ.Nyñ¤åJ¥¼óÎ;O”FóæÍKYðzÚå(jÔ¨!š‘yÑâÞ÷Z¹rpp iÓ¦âyLŠu”õcãRýÊÝÝww÷§–¯ò0EY½zõ'NãIõ±MMMŸj½UT9$I)Õ‘Gžt±+ƒ~¼¥¥å©õ‰ˆˆ”ææõKde¦‹Q‚Œô²³2ø{÷¶gžE^îË!€<-œÙrУ¼l4hP!iW¤ÎhE¥]‘umgg'Öu%CÔk.?êׯ_.“w±mŠˆTVd2fæbE”¬“ŒŒ¤•¢^ŒÊ0æR)ääòòsq©"øyZœ9sFoÂËÿýGÆ ñðЮqss¬r•ŒwóæMBCCqqq!::Z0Óˆ¿¿ÿïïääTaf»téRaõVQiªëò¢²Õõõë×qqqÑS ܳgJ¥RpXh(mµZͶmº•+++ZµjÀ®]»ÈÍÕ­>têÔ©Òù¦¸sç;vÔS¯¹·l·oßæØ±cÔ­[OOOñÍò4iÒä…,WRR‡t»UÅ»q/^äÊ•+´hÑBPŒçøñãÔ«WOØÙÊÉÉa÷îÝxyyéõ¿ýövvv‚Ùï²úô©S§ˆ‰‰¡M›6XXˆ‘òÀ? &÷XºS*•¨Ô÷7:äQ͇zÁ¢FKI.œ=æÚEBš´zæy¹yýRù2‘¹óo¤t×û»’hÂOËÖ#•Þ•yrrr™7o1S§Î 9Ù€‰ÎwÞ"ÏÕ\¾ %LÄ2e üï÷͇R©äÇÔ3W™œœÌ¦M›ËåDEE‘œœl0nll,Û·oG.—#—Ë…4–,Y"„­ZµJ˜ ŠˆÜËíÛ·8p àå`ãÆdff¢T*Y½zu™¾%¾ýö[¡%''óÛo¿±iÓ&222„ð… Vš²îß¿Ÿ«W¯"—ËùñÇÉÏÏ7x]jj*¿üò r¹œÍ›7“””$6”‡ °°‹/¾°å[¼x±Ð®wíÚÅÍ›7¹rå ûöíC.—³zõj²²²HIIaãÆzí'''‡Ÿþ¹\ÎÑ£G9{ö,J¥’¥K—bjjJ||<Û·o/óÞ'OžäĉÈårV¬XñLÆôÜܼR•ÉÈãž–ŠJ­D¥*þÒ3ÒÈËçM"$€I¥Ø:{bëì‰]/LåŽÌ˜4šº"ôœ›íÝ{€ààzÌœù>óç°i¯ÕÂÌ™Å3(éïóÏA©¼o>~þùg5j¤·;wî\† Bdd$ýû÷ü€Ü‹••íÛ·'22777Á‹r‡ˆŒŒ¤Q£F?‘û— 6è}ÿå—_^Šr'$$°bÅ ºwï^j¢Þ­[7:vìȹsçÈËË3¿AƒDFFÒºuk233ñòò"..Žzõê áW®\©4åݸq#ýúõ#22©TÊåË— ^·dÉzöìIdd$£Fâ‹/¾;ÉC°bÅ öîÝûÂöŸV­Z í:77kkk,XÀÈ‘#‰ŒŒ¤aÆüöÛo,^¼˜>}úÉðáÙ={6{öìÁÏÏÈÈHÞzë-¾ÿþ{nß¾MFFmÛ¶¥W¯^üþûïeÞ{Ù²eÂ;ÁÃÃC‡•{ù$÷QY¸s'˜˜XbcãôþÌÍÍĆ/ò\“••Z¥Ò K¼“ˆ©ÉÃùtJJ¼Ã­[q¥ÿâbQ«K[SÕh4¥œN?)Z­¶BÒ© ¬¼ÜF¿ÑE^.S?ûŽ'F&3!$¼ ]:ÆÆ|òÉ÷OtØ0¸Ç¹Øƒx?vvvØÙÙqúôiŽ;ÆÈ‘#'>>ž•+W2}út±݇Ç «ô={öäßÿÅÊÊ €Ý»wcff†J¥¢E‹ìÛ·3gÎðæ›o¾ž_]]]™:uêcûJt;!íÚµÃßߟÔÔT~ýõWd2©©©`‘“3gÎþ*öïßOvv6nnn4hЀµk×’››ËСC¹|ù2;vìÀÄÄ„àà`ÉÏÏ'!!¥RÉèÒ¥ 111ØØØpãÆ ºuëÆ¡C‡8qâ}úôáÂ… ´hт˗/cmm««k…—/<<œ¬¬,æÌ™ÃôéÓŸØBVe#$$ŒÂÂý÷dž…¢Wk”Úñ(vF'"ò¼RPB‘¥¥N91)é‘Þ[…J%UK…Ÿ;s;{{äò» ®\¾È¼Ù_R³VmFý_¹•aÞì/¸s'OO/FŽW©ê7jÃ:R’ïjt}íuìùéûźy¬½==ûô»Ï\=—•Ë—â_#–­Ûá+~ú¹¥%=zöyþSS3ÂZ¼Â·ŸOaômP«ÕDí¿ZtxF'€ìÝ{€•+×ajjб±ŒÆƒ+]ç¹páÇŽÓór{ëÖ-¶nÝZ!Žî^4üüü¨V­aaaøúúòÁðÊ+¯°yóf<<<011!..Ž¿ÿþ›:uê0sæLæÌ™óÒ×Z­fÉ’%‚ðТE ªW¯ŽR©ÄÑÑQ€_Î;Çßÿ-8Í›5k&LàôéÓ\ºt‰Ë—/ciiÉÂ… ‰ŽŽfذa|òÉ'¤¥¥áîîNjj*û÷ïçï¿ÿ&<<œ™3gbiiIÍš5±³³cÕªUÄÅÅÑ£GvìØÁÑ£GiÑ¢'NœÀËËë© )))¬Y³†qãÆ½pÂÀÍ›×Ë-Ðjï wî$bkëĵkW±²2×Û -,,D©TÞXì"Ï5éEjà ܎¿].V áÈä÷?ä·_7ÝíGø{666‡èúÓý{),,$ †nÆ×¯ì³¼ ·ãùrî~\²H'è\ºˆ‹›ÇŽÁÓË_?rr²9zøœ¨[OggÏ®hµZj¢V«©îéU®e kBAnacýšUd¤§³ìÇïy½w_Ý|5.–ë×УWßÒÏ%=u«WÒö•\¾t‘=í <¢Ë~\B“fÍÉÍÉaÕŠeô0¨ÂÚF…¨`Ié7|"ƒF¿GNV&vNØØê[niÙ2œþý{3|øÀ >‰ŽŽ&;;›èèhòòòxóÍ7Y¿~½à•¸oß»æ›o¾aùòå‚ ±bÅ "##‰çÖ­[|ùå—„‡‡“’’Btt´¨§{±µµÅÙÙ™ÜÜ\ìíí…É…D"A*•bbbBFFR©OOÏÆ*R©$::šôôtnݺ%´Ÿ   Nœ8Á¹sçpssÃÌL§f‘M§NÈÊÊt:ñ^^^˜˜˜mtÖAd2¿þú+C‡­4åmÑ¢»wï&::ZP+¦OŸ>‚JVÏž=ùí·ßˆŽŽfåÊ•O´Kù²P«V-š7o.ì€Ю]; „B¡ÀÑÑBBBÐjµÈd2=ã©©©hµZ ñôôä•W^`èСØÛÛ“‘‘‘‘~~~tèÐ[[[¢££Y¿~ýS+ãܹsiܸ1™™™DGGSXXHŸ>}„±úøñãDDDлwo¶lÙBtt4«W¯fРA„††rñâE¢££Ù¼y3ݺuÃÙÙÐ8xð žÙö+W®èùcéÔ©“Ð&oܸAýúõ˽|YYYz**•Ь¬¤R)……*õžYYª™""Ï…äææqýú§î£í§— T*Q*•\¼pû÷±é—õ¤¦¤èΉ-Y\掌J¥"6F÷îM¼s‡¡Ãß`ßžÝ|õÙ'(•J¢6¬%##Ÿ~øN¸Ï±#‡9}ê$Ë—~OaAJ¥’/d˦òWŸõ¨Z /oöíÞEÃàFÖ¤K·×ðñõÃÕÍkW®fø0ÿ¹3§ñ𨊯:vfûÛÈÉÉ&59™ZµëÖ„3§NVèó©P3¼Ã'|ŒÔؘêÞOžØ{ïÁ¡Cðá‡0cÆCEù矸qãµk×&**ŠÎ;S£F ÝŽLT:tÐsp 8+³°°ÀÙÙ™¨¨(@ç‹à­·ÞÂÛÛ›;w qF©©©8Ê”AÕªU™1cýû÷çÖ­[:tH°,ÁåË—111!))‰}ûöé9Á{žÉÊÊ"** Ž;ÆÕ«W2d#FŒ`ùòå0f̘»ÑؘˆˆáL‘ŸŸçÎãÂ… ´nÝšzõê±}ûv222ˆˆˆ nݺ•¦¼=zô`Ë–-DEE1vìXŒï-Íš5V½|}}Ñh4DEEѦMjÖ¬)v’' $$„5kÖG÷îÝ2dQQQÄÆÆ2bÄæÎK~~>Ô¯_Ÿ}ûö•òŸaccCJJ 'N¤nݺ¼÷Þ{,Z´¨B-ìÝ‹··7¾0€&MšpðàA¢¢¢xã7pqqÚOÛ¶mg´ýúõcÙ²eÔ¯__°7aÂæÍ›‡««+ýû÷Ò¶¶¶Ö³ŠÕ¶m[þúë/¢¢¢xë­·*d…6??Ÿ‚‚BLMuý;--#£»çBrrr±´´´22²*|çI£Q¡Rˆ¨œë½>WW7LLMÑjµÈ-­°±±xj‚ÈkW1Jç4õø¿G¹qý*1ÑÑ 2 'ggöüµƒ€ã*òòغ9Š›7®qèÀ~º¿ÞK7^ÚÚÒ°Q#6 ÅÑÑ ™ Çÿ=JR‘±™è›7ðòñåâ…ó ü‰„Úuê²qÃÚ ðŠ<Ξ9E`P-ƒjðãw éþz/<ªV^G©"€x¸:`Ÿ ÀW­#£T€JywèÕWÛ>|¢~¨û{ûÃݺu3DPPP©ð’fQííí™0aB©kƇÈÃ3aÂ4 2™ >ŒL&cîܹÓ°aCºwïŽZ­Ö3Rð<ãàà`°ý 8°T˜¹¹¹ÞõíÚµÓkÅT惮]» 5j”Þwÿ2ëFÄ0%Ï•ü\»vmf-È÷ÀÀ@¢££ ¥~ýúz*M*• ™L†F£ÁÈȈ–-[ “úâþ·jÕ*¬­­IJJ¢E‹O¥|eµëfÍš•2¡ ·pô¨ãµ‹‹K)Ú6mÚЦM› -cffUª8£Õª‰¿­çÏ%;; GGrr²ILLÂ̬âµ,--‰×-íÙ³Sì\-°i02’r••599¹b] BˆVøýæ5½)[Â[Âg7·g㔵uÛv|ý姨Õjº¾öz™×YY[3zÜbc¢áã^‚CB¨RÅ…i3f á2™ŒÛÿ¾«gUfææŒ7Ö’p7wwæÏù’C‡ãààX©ÛJ… ÞÞÕQ*õÐÚåz Fg†wæL¸w—aʨD>D #•J… PÉÏÅϾäÿ’«æ"""%ê}ãÞ~bHhŸ:uªÁߦÿD·µµ¥Zµjbå— Eùù\»v ;;»R¿'&&!—ËÉÍÍÃʪ⼫ÛÙÙÖ@| %„”Þå¨U«åä—í%¬ÏûHW’x'¡TxvvV©°Ë—.²xÁ<²²2‰Ú°Ž×zöfèˆQL¯Ó4ptrfØÛ£¹qýšgë–M¸¹{àéå]f¼||õ¾;9;ci¥¿KÚ·ÿ¦M™¨[ ªÅ ¡Ã7q2“'Œ­– Úãxyåò¥xûøžšJPPm¾þòsüüý¹T¤=áãë‹‹«ÎïÚÄq£iJ¯¾ýi܈µ«~æÐ¿‰‹æõÞo`mmCu//öîþ …BA³æÏŸò$’³^ƒ\ðMQ+5ÐH?Uöo""""/1..Uør/ ## µj=ÔAäÁÈd2¼½} †  Ú‚ª¯îì?uëÖ)RÂîŽL&»¯ùÞ'yÏjµâs-¿úT#Zh­(aÙžŒŒôRá®nꛩ¨ȼ…KôÂüjðåÜzaGdàÐaØÙ9PXXÀê•Ë™ü^Ù]FŽ«÷½UdiÍú Q¿¡¾ú¸««_~­›ÃÆßŠ«¬W;uåïý{„<Õ"?_ALL4ÉÉ:•07÷»;M¯õì-œ“Ë-é7`Ûÿ؆@ ‚ SùsÛVÌÍÍiÙ±óË#€¨TùdfÞ{ˆˆˆˆÈ A“&õîûû¨QƒÅJ1€­¶v Ÿ„·ßÏ¢oæ’——‹ÔØø¾ÂGyammCXÓðrO×ÞÁ®Ý_ 0TLX}uV33óRñÚW°àQ)’¤¦¦qûv‚ØEDDDD^*¬­­©^½ªX""ÀÛ÷³²¶&$4L¬øçE‰ŽŽáÆÁL)èê:88’žžNn®è¤IäùÄÒÒŠêÕ½ÐhÔƒJ¥+FDä%B.—Sµª'±±7Q(zfzƒƒ+Î/Vaa!™™Yâx œœœ}}«ŒŒL”Jqü~T,,äÈå¥ê 7'›äÄÛb%• ';eaA¥¨—{½Û¿pˆn€¶À©TŠ««;¦¦2rs³9s&N\yn±±±ÅÂÂ…"—„„[¨Õª =t*""Rù°¶¶ÁÚÚ‚€ éé(yhµZlmí*ì¾II)$&¦M¦E–«W¯é†V[¨~úôy¼¼| N¤E £Õj‰‰¹F£Fõ žGº|á×.Ÿ+ÊlYýÌó T¾øˆ©©9UªTÁÆÆ†‚*U¡ØúDDDDD^”ÊŒpqq¦  œœŠwBXµjUª‹•ÿdf¦–1O1¥V­¤RQyX4 »w'—ù{ƒpê7+ª’²~å¢rI§RÛ±µ¶¶F«ÕPP Ÿ¸ˆˆˆˆÈ ‹Z­B*•©dªÄ y¡©$''—´´tƒ2°&$Ü&!á±±qäå‰BˆˆˆˆˆÈ‹Ga¡’´´t®^½©©É ëiþüïøçŸ£}}FF&?ÿ¼Vl åÄÆ¿Ò·ïPbclmôöí;Ï<¿YYY¤§§üÓh4â}ΩQîØ‰³HmüôÂ4j5ÿì\ÇÿÆàaÇVccã:­bcãÉd¸»»ŠOMä¹GçóF£wðTDDäåâãoSPPˆF£ÁÔÔä…ÛŠ^ªTjŒ¥h4Fެ'\©T:ýF­ç ³°P§nŸ_@LLJ¥R/e2™p¯bgšÅ÷yQ(YµZƒ‘‘D¨‰Ä™ÌµZ-ÔµîZÝw¥R…V«êK"‘УG“ÈË»«æ§Ñh„…ábgÁJ¥’Y³¾bîÜÏž©“àS¿¬Ãkí*½°<`MhS§ÍÐ3Rô´8yükV­ WŸ~4 m,„GmX‡©©)»t¶g)€He¸ùÜõ´Z¯`âЮ¼þzw,,,ÐhnÄÙÙ}“IIÉÖÄÎÎV|z"Ï%ffæ$$¤œœáééýBLÐy†?~* |ÉÙ³øúëoiÖ,Œ·ÞÀÀ#ñññ$''SSS† éO||[·þV«ÅÄÄ s.^¼ÂÏ?¯“ðð&øúzsèІ¤wŸ…’åY¼øGÚ¶m…““#Ÿ|ò ;{2p`_V®\Ï„ £±µµ!33‹¯¾ú†7ßìÍòåk((ÐynoÒ$„×^ëbð>_~9Ÿä䬭­˜“:°ÈΦÖÁwÛÐxÃÓ ©Ñ³9APì°ïÊåKzÈk={‹ƒZe@ óóùtÊ0y9¼=éSæ~<ž„øh";ö,’_á§ŸVÒ©S{œœQ©TÌ›·˜‰Çiddd±cÇa¥C'Å›`ooObâ—þÁ¹ºº’ç"¯))É¢™B‘{°µµC¥R‘““­BÇŽmŸë²mÞ¼ oï»ÝëÖ­Å„ c8zô¸fi)g„1X[[±k×>λȡCG˜9ó}ÌÍ͹té ¿ü²…“'OÑ¥K7ÖMþÆŒ™„¯¯7K—®¤mÛV/dû¸q#šƒ”ZMiÕª9çÎ]äôésüï£øúë…|üñ{Ì™ó-&Œf÷îýØØXS«V ð,Ê@Ž9&„«Vm@¡PðÎ;ùzõ:sæÌz¦åOzŽÀ$àM èhàÚ‰cGá\¥ )Éɸ{Teð°‘\<Žë×è„+[Á…sgQ(ò8{úY™™ zk ·ãùyÙRš6 çò¥‹tìÒæ­ø}ëöïÝ @ÃF!ôêÛß`>n3çóY¸º¹3aò{üºy#‡þÞÀÅ ç™0ù=üüXúýwädëÌ`÷~£? ‚CD¤\‘èVpvn]Ç•ó§HN¼ÍÏ¿ŸÀBn% ™™Ù¨Õj–.]É€}HOÏÐKB£Ñ`aa†™™&&¦ØÚÚbb"#99++ùKÿâjÔ¨·oW~¯ñ©©i˜˜cf&®ð‹ˆˆˆ”¤~ýz$$Ä#“UçÎòóó ªõÜ—-55íæÅe2ÖÖVeþþ =­ÒÒÒ„ü””TRSS……ØÅ‹—R³¦N¨HKKÇÛÛ;;[œØºõOœí###¤RÝïí·‡–=]“ܽnÀ€¾XZêϯrrr‘J077êå—ý-ö û0lð8==)|„£“Ë—~O\L4ׯá˹ 8þïQîßKÏ>ýÐ÷uæ/üs /˜G@@úÌŸÛ¶òåÜL?†æ­hÜ´E}qöç³Ê¢²ã IDAT@\]Ýøô«¯ùxúûBX—n=èÒ­‡ÿ9HãÛñD´Šdåò¥4 % °& ¿™+ 剩“g-F‘—Ë›Vbgï„Gu ´êÕ•+×î›VÕªÕ022B¡È¥  Ÿ[·âprr|é_\ù¤¥¥Vú|&$$ Tª°°0GDDDD¤äZCaa……¸»»£VkˆŽ¾ù\—ÉÊÊ •J…‡‡·o'P½º§Neöìo¸s' ggGºtyÕ`üÎ;ðÞ{£Õj±°°ÀÜÜŒààúüôÓ*Ö­‹ M›–¸ºVáöíÚ´‰àÈ‘cÔ¬Yã…j~ü÷ßêׯ˞=ãä䈗—'Û·ÿèÎÇÙ‚5k6Ò·oêÖ­Íñãÿ ×NŸ>€M›¶²qã¯=z‚wß}‡ÚµkÚP¸®}û6‚°Ó±c;Æ›‚\nÁÈ‘Cñðxúïp[` ü Ô<€8×:88âø¾mªTqÁÖNçkgÜÄÉü¹mk©k2ÒÓùñ»EØØÚx'á‘óøÐAî$ܦ{^wÃþ9HLŒ®wèØù¥ÿ*ôdч_¯ÀÒÚ–: K» ¯[·«WÿBçÎí™?ÿ;BCK{~ iLBÂ-DDDDDD^d²²216~þwŠ-,ÌùðÃÉH$tgƵÂ;ÿ矗 ‘èÔ‡¿ùæ !^ëÖ-„ßš4 Ñ»N"‘ðÙg ×<Ÿ1c*‰„fÍÂ^¸ö0jÔP¡ì-Z4E"‘Э[Gºté W75jø uàççͧŸN/U_ݺu¢k׎zñ'O'î/™f»v­iÓ¦¥^ügð;ð0þã֭ߥKt>+ aÍÂï{}XÓð‹Z$ËÈSä‘““Àµ«WøuóF’ñõ÷'¸Q(ii©ü²n gOŸbçö?hûJ:ȬÓèúÚë,]²ˆFèHVf&2c׬y„(€”7vVøÚe0ï‹©¨U*äV™H%Z´j]CoÕª9µjâì섟ŸÎÎ¥%׳gO“ƒ““r¹\¯sˆˆˆˆˆˆ¼(ääärçÎR†WžGî P|VQ"‘”z‡—ü^ò³¡ ¯¡°’ʋƣԡ:(«¾ =ƒ²êïY &¡¹´m;SŠ&¬—¥µ-÷ämâ”»êO]_{ss ükrýÚU cfNuOÏRׄG´D"1B.— ¿ÛÙÛ3hèpÒÒÒ07· WŸ~8;W¡oÿº¹®ƒNG.·$¢U$­"±´Ô©úøú2ç›»ûœœœ±wpÀ¹Š‹`àE5·ýL šþ Òé0“2@•úžëŠ…CÂG±Äji)'==ƒ¬¬lll¬Q«EÛÏ 3µWr ¶²¢TеDDDD ¡Õê̪&$$bd$yj‡V«%;;G|èÌý›šš›[¶úb \†ÈÏ/@£)+077ÃÈÈ¥RIa¡aã3ZÍÙŸ¯v×úƒ08Wq>ÛÚÚ ŸjÞ÷ZKK+ƒ¿;9WÁɹŠÞoÖ66XÛØè…™šš–ºs—R÷ðôòIE å…¿ lJÕ¼|öÙgtíڀ˗/Ó¿4 111,[¶Œ~øá‘ÒKKKcùòå|ðÁå–Ç;wrãÆ |}}‹æ š @ÌÍÍ17Ó qss%)) ‹ÇJëÿûcÆŒ)—ë6lÈìÙ³iÙ²åsÕÖíìí)¶„ææêJRRò㸺U£º·¿8PTRØùl3§/ T‰‡ˆˆˆˆˆÈã`VÅ ¿ˆŽŽÃ<¯´¿…Zµj`bR1&zéÓ§ [ÅNJJÂÍÍ>}úðÏ?ÿè];oÞ<2‹ÎE|ø¡Î,îÚµk¹rå #FŒ(•þŸþIûöí™3gr¹wwwLMMiÛ¶-©©©|ûí·x{{Ó¿þúë/llløóÏ?±°°àÝwß ((ˆ³gÏбcÇ {6666zV¡ªW¯NbbâCÇóÍ7ñòòâèÑ£BXÛ¶m Ó™ þå—_¸páíÛ·çÏ?ÿÄÌÌŒ°°0öîÝ @çΩ_¿>—/_fݺu„„„À¹sçž«vnnnŽY‘0§kkN$%%=0ž½£3>þAâ@QI9~tÿ³@jÕªƒV¬‘Ç"OVÀen” ¯VÍ“z5JŸí“JÕ‚¯†òæÚµkª{§Npss+óÚ VëìYN:•¶mÛbll̨Q£Øµk—°Bʼn'hÓ¦ W®\aÀ€œ>}šœœqssâ>|˜?ÿü“½{÷âççǨQ£HKKcöìÙ„……±gÏáÚ™3gòå—_–{]˜š™–òømccMzFª¼/¼¶oßž„„þøãBCCq*rŒwèÐ!Nž< À{ï½Çÿþ÷?:tèÀŸþ‰¹¹9-[¶dïÞ½¸»»£P(X¸p!-[¶$""‚ììlX³f !!Ï—×l+kk¤÷˜Ë­V­Š|…8ˆ<ºb$w?DDDDDD##5†ŽN©‘>åw¬¯¯/ ,`Ñ¢ET­Z•ÀÀÒ¦K™7ožàM"‘ T*133ÃÑQg™²wïÞ$&&òûï¿cmmÍØ±c©REgÆÔÄÄKKKŒ122B­Vsúôi–-[@\\ƒ  _¿~˜››£ÕjQ(4mÚ”¦MïšdU(*fka.çø‰(òôÓW*•¸¸Vy`|òòòHIIá÷ßç•W^ÁÄÄ„~ýúQ«V-êÕ«WfüøøxþúK畼  ™LFdd$„„„мysZ·nÍîÝ»Ÿ‹v®ÈËgÿ™za*µ ÿ‡SŸ‹¿gpÁ;_‘GuO/d²ÇÛ<î,2™ ÿ€åVÖ[q±I¥¸¹¹‹\E ºARй¹­X{/!J¥‚ÂÂ<±"DDDDž€øñ¤f¥Ü[ó•Ô÷¬ñÔó¡V«ËM™™™899¡ÕjÉËËC¥R¡P(077gíÚµ 4www~ýõWŽ9"X/Ž¿mÛ6"""xõÕWqpp`îܹtìØ‘f͚͌ôL²¯ZµŠÏ?ÿ€qãÆ•™ÇãÇ#—Ë©VM§·VQfŠÓÓÓðññ{ýðYÁ*Y—2™ ¹\NÓ¦MqrrÂÕÕKKK¦L™‚——‹/tçXär¹°ã"‘Hpww'""‚cÇŽallŒZ­æ‹/îz‹_°`Ás#|€n÷(¬I½0­V‹¹¹©iVÅÒUK…Ÿ;sšÂÂÂÇ@.^8Ƕ-›Y¾fÃcÅÿeÝj^ïýF)aI&“‰HE ‰&&–bí½„è¬Ÿ‰ˆˆˆˆÈã"W™0¦þ€J‘fΜ ÀŒ3055E¡P0sæLllløþûï;v,ãÆãóÏ?'##ƒÎ;ciiIëÖ­Y±b…ìØ±Èårš4iB«V­øõ×_ˆŒŒ¤V­ZÔªU‹¿ÿþÞ{ï=!î Aƒ°µµE&“ BŠ……Mš4!88˜E‹ ÀG}T)Ÿë¶mÛh×®Ó¦MãСC¬]»–˜˜.]ºÄ´iÓ¸qã³gÏ`ÅŠL›6 …BÁþýû‘Ëå¬X±¦M›ÆÅ‹Ù´i“^ú»víz®Ú¹¥•hõ]Pgdd_î÷Љ¾Éæ(@Q»N=Z·iGnn.?|§;cäââFï7úУgþ=¬¾ióÆ ÄÄè,Œ üvvöØ¿—ÇÿàÕŽ]ð ¨Áâoç³yãâãoF“fÍIINæð?i¬¯"7ΗhÑbeeÍa#9ö *•н{t»\#FÅÌÌL@—;wîpäÈêÔ©ƒ·÷]çÏŸ§F÷5§{æÌêÔ©Àõë×qqqA.—¼666–èèhš7o^./yïøøxÌÌÌDO’ÖãrñâE|}}+ÜUq]'%% ‡âŠù÷ß¹}û6;v^—.]âÒ¥K4oÞ{{{qæ "ò•Jmð·jÕ<ôß> ŒŒ¤H$Ò2?Thµš§–‰DŠQÞÒ´Z5ú…h†vÌÍÍ…‰’L™2¥TØ€¥©bá K—.zÿ½÷ø½÷©Y³æ]AM.§uëÖ¼ýöÛÏE}þøã¥Â~ÿýw~ÿýw½°“'O çBŠ)Ö¢¢¢ ¦]ü»Hi–.YÌðÑïpîô)î$Üæ‡Å <|¤n.sá<¿ýº‰N]º—Š»w÷_ »ß|ýo͉ãÿ aï݃_@ ºv³gNñzï7°²ÒyP·±µ¥k÷×ùqÉ"Â[èÎ@}úñ‡¼9h(# ɉ‰üôýbd&&\¹t‘ct}î«Ïf2mÆ,QyÒÒÒØ°aAAAüúë¯ôîÝWWW.]ºÄ›o¾Éîk¾î‡~tO·nÝJ—.]ô„˜’Èd²Ç6…÷ {üÍÇN÷È‘cœ9sžaà a E>*•RxI?Ô ÉØ µº°TxFF&99Ù¸>„~y!•Êm)¡§  ˜˜||<˜ÆO?­äÀ#,]º£{㊼x¬Y³†‚‚‚—²ìÅ&’Ÿ¡aM˜?[§®V#°&­Ûp;þ––••E—î= ÆÍW(X»úgìß[´ø A­V!5’âî®ógÓ§Ÿn|tusÃRn)„Ï©ÜÜõU¯233p÷(ZÔÑjÉÎÉÆÞÞž}ú q‹=ËÈc‹\.§eË–¤¥¥qõêU²²²Ø½{7‘‘‘Œ_Ò¡a±…””f̘趆GD"aΜ9¸ºº À‰'°µµåðáÃ=z”?þ˜‚‚®^½Jxx8.\@«ÕôÀ<Ü}±0qâDªT©Âûï¿è,n$'ëlWýõ×óÓO?qêÔ)5jTô²U°k×.>Lvv6½{÷¦iÓ¦œ9sF°£NÏž=IMM¶}||;v¬^žòòòسg¯¾ú*ß|ó ×®]tfµZ-çÎC*•òË/¿0tèPêÖ­[æóùꫯ¨[·.C† A£ÑðÕW_Q³fM½Ãpéé鸸¸ÐºukÁÜ£R©Ð y~‘™Z`ëì)¼d£¯]bþ±pÑ¢Ý­ÞØX¼#Rü¹x¼,þ^ü{HHCBCƒõâž9sŽØØ[¼öZgaò­Õj…4$#ƒ¿Õje©0…"× ‡éâ÷èÎÊó½÷5œ‰ÁÝÏ+ý•ª€¬{&%ë¥ä=îÏÕ«7J]{ï}ËÊ·ÈóÅã.b¾(ê»O ¥RÉçsæðó²¹~í Ö66|6{žÞQùävíÚ…••cÆŒ¡iÓ¦z»#ß~û-—/_æÛo¿®_¿Î©S§„{8p€””¾øâ 6nÜH½zõe̘1,X°€-[¶Ð¬Y3,X „¢ZµjÂo›6mbß¾}´lÙRˆWÌÙ³gÙ´iùùùT­Z•ððpX¾|9Geûöí¼òÊ+boyιͤ Axù2tÜtÞéߎfmjÜÑ»vÊ”øâ‹äææ2gÎB¦OŸÄðáãðô¬Fvvæææ Ø—jÕ<˜6mññ ,_¾€“'O³dÉ2²³s8yò4|ð. …‚%K–‘“£$jÔðgÀ€>]–}û²cÇî¢HczõêΡCGiݺ>>^|øá§¼ÿþ»œ8ñ+W®ÇÖÖ¦h1¦Ý»wbÞ¼E¤§ë|Z8;;1~üã«øÌ»ˆììòóóèܹ=aa†M¦îر›ýûPµª;o¿=´D]ç1gΦOŸüÔÚÄêÕ«IMMt~Ÿ=)ÇV‹­S§}ıààè$¤Ó´y„(€<.?ýôaaa¼ýöÛ$''3sæL¦OŸþÐñëÖ­Ëüùó‹ð¹8p€ t‰nݺśo–­àááAh¨ÎkìôéÓ…]ЧI£FËmÛ¶-¥npîÜ9a²Ÿ‘‘!xœ-Ƨ¨mÚ´‰7"8^˜?>7n,zI: ᯽öšPî²Ø±cÛ¶m’éÞ+¨„††’-äÇÎÎŽÈÈHîk6PDDäùÁÎÁ‰ú!ál^ó=§ŽÀÃÓ—)Ÿ.~èør¹œÑ£‡ammÅ_íåòå«T«æÁ¬YÓ˜<ùà Dõ9r11qôèÑ¥h º‰B‘O›6º—îÚµ›žH¹zõº–±±ŒªU˶>\Ÿ!CtP'OþÚ¢Tªøì3]žSRRŸ¸n{ôèLPP J¥’3¾(SñõõÁÄDwÖïçŸ×ñöÛCŸi›Ø»w¯°`¸páBŒ••íÛ·gîܹ,€dgg³cÇŽr@ˆŠŠòbjjú\ô·7>’bèú‹/rìØ1Ú·oÿTΈ–'wôv)ÌLMqvv&+;ýñ«U¯nP¥Í½jUÌÍõUòýj; ÅXYY— ø`Æ'¥Â† /½Ñ¡S:têR*¼jµjz麸º¼Ïç%v_…4ÖûÞ¥Ûk¢ò¸DDD°sçNìììØ³gݺuC¡P˜˜Hff&111ØÚÚâêêúÐinß¾ &ðÉ'wILL YYYÄÆÆ þ’899‘‘‘Aaa!ÑÑѬ]»–Þ½{—yKKK¢¢¢°··'%%ìí퉎Ž )) kkkÔj5‰‰‰BÇ···ÇÌÌŒÜÜ\¢££¹pá111„¿wïÞÈårAe©Q£FÂá9+++°±±îsëÖ-a%gàÀœ>}š &ðÁ —Ë0`€ båááa°ÜÅ\¸pY³f±zõê¢Â}B]Nš4 Ðmï×å­[·ðððÀÆÆwww233±³³Ó ffx{{coo‹‹‹8sy0·3nÚ×(•…lûe9 ÃZbna >T|ÖÖV|ßôô @g¦T©Tw}ž¨,ݺuäĉSEDGŽä ¿©Tj²²r„÷7 q?c)KYÖK’––Ζ-Û¨]»&…ÂnPÉߟ6‰Dx¿«áççWª^¦OŸNzº.}ô,Y²„ëׯ0lØ0½…²„„vìØÁÀ1bnnn¸ººbbbÂo¼AZZš`«zõê¼ýöÛ¬_¿öîÝ‹……S§NeÏž=Ô®][ÈgeUQËËËcáÂ…ÄÆÆÒ AAyóæÍìÙ³€®]»Òºuk–,YÂðáÃÉÉÉaË–-ôë×ÂÂB¾ÿþ{Ξ=‹ÇgÑ¢EÌš5‹´´4=ÆÏZ­¦ÔyScéÕÃÔÔ SÓ—×J”(€ÜoooÚ¶mKTT­Zµ¢víÚÄÆÆ…ŸŸüñîîîe ݺu>7oÞÞ}÷]–.] À¨Q£„…­[·R§N¶mÛ&LèKÆðóó£V­Zz+%eñÎ;ï‘‘A`` {öì!88˜zõê ;2öööÂVçO?ýÄÑ£G…X*•’””DTT5kÖ¬ˆ´k׎››ËÀ>|¸`Ñ¢~ýú´jÕŠI“& çB<<<èÕ«yyyBþ_ýuþý÷_Ú·oφ „øC‡ÅÆÆ†®]»€mllôtPÇǪU«×ZGGG´Z-QQQÔ©S‡;v0dÈ¢U9_ õ'!´k×Nì%""/˜2}ö2òr²yküGe^WµªNµJ"‘`i)'++»Ìk?üð3Ž9ÎW_}ûï¾Sß;÷2mÚ,š6 ¥aÃúXYYrðà zã‰ÊqæÌy!-cc)Ý»wÆÅ¥ «V­G«ÕrýúÍ2ãš™™bllÌ´i³ŠÆ{[ÆõDùY¿~“à%¼}{.ùÏ?¯åðácLŸþ)cÇŽÀÜÜ•JÅÁƒG01‘ «ÃÅumnþô'[)))Â;ÆÃÃ㾆P>þøcAP;v,;vÄÇÇGxîÙ³G@>øà,--éܹ3 ;¨ÛµkWŽ=JJJ ·nÝÂÓÓSPÞµkýõ/^¤E‹,X°€ääd,X€··7Ë–-£víÚ€îŒf¿~ý*]ßú믿hРï¾û.'Ož„Žnݺ ó•1cÆÐºukÎÓ©)•J®\¹èT–ÂÂÂ6l[·nåàÁƒÌ™3GX !""BÈD^n¤X)^e:OÉï÷£¤©¾†  Ÿ Å/yfÁP|Й>vìöööÄÇÇ žG áêê*ì̧clllðÞƒ.Ö©S'½ïº¾#Fè…ûøø”JÓÚÚºTXI/¯&&&‚ ѳgÏR÷nÙ²¥Á2¹»»3räHá{•*U –ÇP˜¡]%ssóR¦zEDDž_|{a èÛ÷uz÷~M˜€K$Þ}÷ÔjuQÝKŠÞõhذ.̻詶 á°|ùrNœ8¡÷>¾+ðaùò媾¡E°V­Z žÐûôéC¯^½Oè†Ø²e‹àX¯¤'ô{ßíÅ pÅïÅ1cÆTJ¤$ 4ÀÖÖ–ììl¾þúkRRtN'‹Ï|ÂÉÉI²J2mÚ4Œ‰‰‰á—_~yáä¤Û\:ÿŸ8`WR”ådéÍøEªú÷ïOZZ–––xyy=µ{[YY1zôh±eŠˆˆTZ¼¼ª¢Tæ<ÔµFFF¥¬ßKõ~/¹hbðsÏÄþA*$ju!?üÙ{ïëììÄâÅKÉÊÊ&8¸>&&²R®ŠË •Jï«z¥V+©W¯ÖCNâÝ0555P_¥Ëkè¾™L›6 cccÆŽñTÛDff&û÷ïtÖkÖ¬‰J¥âСCܾ}[H.\¸@DD666ü÷ßܸq;;;þûï?!þÍ›7iß¾=¯¾ú*­[·æûï¿ÇÇLJ¾}û:ÕgWWWÁŠØ¥K—èÑCgÕÿŒ»ÏÕ™˜˜A`4´`VpppàêÕ«ìß¿Ÿk×®‘œœLNN&&&ôèуäädA±²²bÿþýäçç#‘HP*•ÄÇdz|ùr¼¼¼¸sç 4À××—C‡ ϪjÕª/ü8•šœHA¾B°+)…Êg(€h4jrs“+eBZÙ‰ IDATÅØÚš`k«;³ð´óhiiTi를x–föDDDD½ï¿?ñ©ß·gÏnO#Ñ¢ÚvhMÛ­ï޳Eæ´T¸ùÎ~ýú \†ŠL&£°°äädúôéCZZ½{÷æ?þ 99™Ž;’““C½zõ(,,$!!Щ™ššòÚk¯HPPÿý§[Évì2™ŒÞ½{£Ñh˜6m†›7oDpp0ÁÁÁ‚! zõêõÂ÷ãAõ©ÜTÐ*)ëW–Ï.íc Z­†ÂÂ<ñ)ˆˆˆˆˆˆ<&)².j¯ü­0¯ªNÔpò®Ð<´mÛ¶TXñŠý½tèСTXIõáb…Ïõë××û:_ÅÜ{7·»êm¦¦¦BZ†Ô²*#%½¼S·nÝRþºªW¯NõêÕõŠëè^8CÏBDäyÇX¬‘§ 1ʃ¿åfçb|GYለHe%++µJeð7[;=5P‘çñ鉈ˆˆˆˆˆˆˆT*2ÒÓ153+õw+.Npúù ¶ÿ±õkVê…¥§¥‘“}תß?pâØÑÇÎ点³Å‡õ<ôÈÕ«7+"""""""O†U-°)û÷ë7b1Í:è|"Ô­S·ÜóPÒ·ÇÇŒyyyLž<™ÀÀ@ÁìýÃ’™™É¾}ûèÒ¥K¹åñøñã¬X±Bøð\}Y¹r%ýû÷âë‹ ¿ùæ›åîa¾2c$•baQÚã½D"A«Õwp˜Ÿ¯ÀÌLçs¤°°©TŠ‘‘Mš†#3¹ëÀ±  €?ߊ³sBš`mmCfF:&&&def`ieUæîJ~¾µJZ­ÆÔÔS33âbcP(( 1– y.NObd$¸”ÈÉÉASdLÁÊÚ‰D"İË166¦° @²ÌÌÍ011}ážïC 5 7LDDDDDDʃ[Ò$¸A??_ZÔÑ)Ðhµ( Ë=ééé‚/ŽÏ>ûŒâêêÊ‚ ë°w~~>gÏž-W¤ø06À¡C‡ˆ‹‹{.žï¿ÿþûHˆ¡ëwìØR©dÁ‚¬^½µZMãÆÅÎs¯ =u_ÎÕµã5+—F5OO¾™ûÉIIÌ_ô½®ŽæÏßC.·äø±£Lùà#6nXÇát~WükÒ³·a?E=:w I³p4 ÆÆÆŒ?‘ää$æÍþµZ…‘‘”¾ýàéåÍ‚y³ÑjµH$Ú¼Òsss¶nÞ$OõÓ0$”e?|'Xxss÷`àa|ýÕç¨T:£?2™ŒIïMC"y±æà-€h4(UZ±•‹ˆˆˆˆˆ”#õýW¢Té ¾è\™HË=ÉÉÉ‚•¥*UªàèèXö$¯ÄnÉ!Cpuueñ⍦ê|˼òÊ+‚ :Ç„ÿý÷&L C‡Ô©Skkk¤R)£G&77Wð„nggLj#Xºt)r¹œ›7o"“Éxë­·„ƒè*•Š={öTÚÝÛ·oóÝwß‘žžŽ»»;99:“×%=¡7hЀAƒñþûï3kÖ,233Y²d “&M"33“O?ý”„„9r$aaa,Z´ˆüü|’’’èÚµ«ØqÊèãâØ¹ýwa÷ÂÒÒŠ>ú„Iãï Òá-"HII¢Š‹+Mš† áí_íDçn:Ÿ=“Æ)SñöñåÝ©ÓÉdÌþb999ØÙÙ3nâdÌÍÍÙþÇ6®_»Š§—7µjëv,SSS8|èõãQµ*¶¶v„5mFLL4i©©4kÀ¯›62`ð[(•JêÔ­€§—÷ '|<’"""""""òbabb‚“““ Œ¨T*d2™Ákûöí‹R©D«Õòã?Ò±cG6l(8æ½vMgÑ+11‘ &ЬY3Áa`±?£G’••Err2®®® 6 €Ã‡sìØ1²³³éÚµ+µk×&99™ï¾ûŽiÓ¦:?#666ØÙÙUʺ<¸÷|Îgϸç}Îûý~IHHHüç)),áÞÉ{.+Ì+ÄÝþÙ‹éšššÒ¥KÑÁ¿yóf…Jè‡æÎ;( Š*ÉLäììLrr21118;;Ó¬Y3aÜTÄ?þ(ú¡¡¡B5]ÕY/ß×ð÷÷:µºu뢧§GRR?üð666(•Ê*ci 4ÚkÉ’%,Y²mmmÙ²e |ðÁ‹ñ€(•"^Bí¹)ÿд¹'ׯ†àݹ A‡akoOfFŸüçÏžá땢4mPêúôãúïÙ»k'o y ¹\Ž¼Ì ƒV‚©ÉI‰|¹àSrsr¨ce]:£W¦¾\.G.—ÓÒ«5;·mý˸)5š“9°o/y‰,öõy…zõœÐÖÑfï®ÒYÈ ïOA©T|ìñéëÔµµ{ÊýìçØÑÒÒA[[—üü,Ο»Ž·wŠKþ¾oªŽŽ>FFÖÒ¯’„„„„Äsê±Ú·òuNN ùù™Ïôÿ¯•Ó¶ýKë¶h±FÙœùŸi”Íð›óŸ¿¾Od€ä+ó¹%‹!O‘‹v{=®jß”è&ja+7çîÝÈ*,|}´´´4n²† ¥\çÿ$_ý5……¥Á®õêÕJݲÈÀ…*y×®]qqq¡¸¸ ±´´d̘1äæ–ŽèÚÙÙ‰ø€)S¦ˆøO>ùKKKlmmqwwÇÐзß~›‡KÝSƇ¶¶6;wFOO ߬Y3ÜÜÜju[6mÚ”:uê——'  &MšDFFzzzÂålêÔ©$%%!—Ë111AWW—ï¿ÿ¥RIVVX[—ÈΘ1ƒ””ñýEÁÞÁ{ÇZuLîM¥—Æ¿i€(Q]ô'±E±¥SM~Ȯ҃Ÿ~ÚŠ¡¡:::ØÙÙsÿ~$r¹kkôôØØXaaQ===bc`gç@3®ϲ“go¯Q&—ËqvvÖ(wtÔì ªÜ¦ÊbVÆßÒÒRí?”º}©(¿ñYKKKlKWW]ÝÚŸŠ´nݺeXXX¨•add¤V¦j£ò‰LLL0©aŒ‚ijeÔØ R#<%žID‹>&&Æ88Ø#—ƒ±±&&ÆX[[ahhˆ¥¥ÎÎŽÈdÅèééUø¬Žß~û­Ú:ÉÉÉL:•íÛ·KWZBBBBBBBBB¢ðL³`Y[Û””€R©,gÍ›RRR„•URSÓk›yyy,^¼˜¨¨(Xi½?ÿü“íÛ·³bÅ NŸ>ÍöíÛqâ‘‘‘„‡‡³qãF:vìH£Fèß¿?¯¾ú*ãÆãå—_fÆ lܸ‘¤¤¤*w¶„„„„„DMprrJã«W¯¦}ûöY˜TXZZ¢§§‡R©äèÑ£èééáéé)ŒŽ‚‚RSS¹rå Ó¦Mcâĉ¥ÙÕÕ¡„žžžŽ………H-ÆÝ»wøðÃ155JèÎÎÎdee1oÞ<‚ƒƒ9}ú4½{÷®umy÷î]Ú·oO=(,,‚FFFâ @¯^½èС...LŸ>Çóã?2kÖ, ©W¯†††¢¥¥E›6mظq#Pªÿ¡P(044D&+””ÉdèëëóòË/³{÷n&OžŒƒƒS¦L©•méååÅwß}Çž={°µµEWWSSSJJJظq#¦¦¦b´I“&Lž<mmmìììÈÌÌD¡P°nÝ:âãã±°°àÝwßeÇŽœÒø333•îx ‰ZBnn.ÙÙÙdgg‹AB¥RIvvöc‰«P*•þ#ÇYÛ)((xjõË/{Û£6^Ÿ>úœk×B9qâ GŽ••űc'Ù¼ù×ÇÞæœáìÙ OýXƒ‚N0}úñ½¨¨ˆ ¶píZ(7n!55í¹kÿg2’––Š¥¥¹FyYt ‰—AƒѬY3 TÄÇLJ¼¼<>ÿüsâããExMIHH`ݺuÌ;÷©ãÍ›7ùå—_(** mÛ¶¼þúëµ¾mg̘¡Kó$õ/_¾ÌòåË…fʵkר¾}»È¨åíí­¦¿"Qsš6m¨QÃHIIeÕªµôêÕ ;;[ÞxãUvìØ#êegçðõ×ß`kkÃ;ï à믿';;---fΜ¬±ý#G‚i×®5ß~»žæÍ=xô(öíÛàîÞ˜›7o±oß!Ú·oC—.Þ9,ff\\ê3h/AA'ÈÌÌ¢nÝÿŸåؼyÞÞíiÕª4#ìäÉ~øû/–  ‰ÚOƒ D€ø’%KhÞ¼9õêÕãË/¿ÔPB $77€W_}€sçÎ Åïnݺilÿúõë4oÞœƒ¢««‹……ÚÚÚ4mÚ”¬¬,Ž= €••ÞÞÞ„……¡¯¯Ïõë×ÑÕÕ¥oß¾„„„àããCûöíÿêlM®µÈéÓ§ILL¤Aƒ¢,44”ˆˆa<ÙÙÙ‰v),,$""wwwBBBˆŽŽ¦nݺ´oßžëׯsãÆ LLLÔŒ¼qãÆáììLxx8ÁÁÁÒü„gòd? FŒx«Òzúúz 6ø/ƒø¿ýö;±±qtî쥥ÅÅÅìÞ€ŽŽ6YYÙìÙ@PÐI&MGzz™DEý‰«k#Ö¯ßÄÒ¥ pvvÛüé§­¸¹5â»ï62rä[ 6˜3gÎü^^-033%(èĪí%DBBBBBâ%""B ¨RSÂÈÈmíÒnÃ×_Mûöí¹víšܵkýúõàöíÛìØ±gggš7oÎ?þÈ«¯¾JHHùùùXYYallŒ±q©¯ü­[·ÉdìÙ³ Ú´iCNN›7oÆÜÜœøøxÂÃù|ù²Pc¯ÆÇ­[·pvvæüùó$&&¥’ªó\»v-Ÿ}öëÖ­Ãßߟ¬¬,¶nÝÊgŸ}ÆÃ‡ ÁÉɉ«W¯¢££ƒ±±1#GŽäòåËb?*q»wïÌøñã¥ù éÑ£+K–|FNNŸ~úÍ›Za½{÷î³zõwÄÇ'0`@222±±±3NNŽâ×_£KoV¯þ ™LFLÌCLMMP(XX˜“Ÿ_êNwìØIƒ¸|9„Q£†ak[Ÿ>=o†äååÿgÃ$DBBBBBâ¥aÆÂígéÒ¥¸ººâää¤QO©THjj*PªÑѸqcìììèÑ£‡¨Ïþýû111aܸqBTÏÚÚ²²²ÈÈÈ3){ö”º¹ÄÄÄÄ©S§¢¯¯/”Ðß~ûmvíÚEpp0^^^œ?¾V¶eRRÎÎÎôèу=zpýúunܸ!f)®^½ZéúöööŒ=( 0NIIÁË˫ºwïÞåàÁƒµVåyA©,¡¤¤„ôôL8®T*)))ùK4[‰L&Ãßÿ{V­*)üðÃOþzä‰i—PTTÄþý‡ÑÑÑæ7^%))…)S>dΜb_*}‡±jÕ—äååÓ³ç+U£Rü•”” “ÉèС ÇŽ¤E‹f}ººº|úé Ä2gçzÍ pâÄi´µµ˜>}>>}èÙ³+ºººLŸ>‡>}zÒ§OOÉyÞ8tèû÷ïàìÙ³øøøHO¥„„„Ä?Lnn.ñññäææ x‰gŽŽŽpÁòóóÃÑÑQ(¡'&& %ô±cDzdÉ233éÚµ+îîîtìØ‘µk׊õÇŒƒB¡ÀÅÅ…¡C‡Ñ#GpssÃÝÝWWWœ9räúúúLœ8Q¬Û¶m[¬­­quuE./MЩÚÀ²eËˆŠŠ¢M›6¼õÖ[µ²-{öìÉš5kسg-Z´ uëÖ888`nn.TÜUq2}úôaòäÉèêêÒªU+233i×®üñk×®¥AƒL˜0A(¡'&& %ôÂÂB¡ŒЦMÞyçéf~ì{_›•+¿Ô(wum¤QnllTaÝÏ?ÿHí»‡‡ú»kàÀÒ™ •ñQ¶ÌË«^^-*¬ˆ´Àîöšf’úõ*<&ÉyNèÓ§}ú”úÛU52!!!!ñ_&99(UªÎÌÌdÛ¶mäçç3räHŠ‹‹)))ÀÒÒò©ïûÈ‘#¤¦¦òàÁîß¿ÏøñãÉÈÈÀÛÛ[º0ϘåË—k”U¤„nnnÎÂ… 5êªTÏË2thi† GGGáR¤R?×ÕÕeàÀØØØhì§C‡⳩©©06f̘QëÛÒÐÐ???òQ£F1jÔ(µ²þýûÓ¿µ²iÓ¦i¬[™ºªß"!! µŽ¸¸8¢¢¢(((@KK‹:uêàææÆ¬Y³˜9s&ººº„„„°k×.¢¢¢˜2e gΜ!))‰Ë—/#—Ëyøð!YYYtïÞ×^{í©›R©dï޽̚5‹©S§¥Y•¼½½ÉÍÍe×®]¼öÚk899áèè(]L ‰ÿ<2@Oj†ZÈ“  ‰‰‡RTT„““6lÀ××ÂÃÃÙ¼y3ÇçÚµk8p€éÓ§“••Ž{÷¦sçÎÈd2Ž=ÊòåËqvvF&“‘™™ÉíÛ·Å”fGŠWÛwjj*þþþÔ­[Ẅ<é,EZZ111?~\­üúõë$%%¥£óõë×çÚµk„‡‡3zôhÜÝÝÑ××—n„§@xx8üñÇ yî:::³µÅÑ•š¡v?=’"!!!ñøàÖ¯_Off&999jÔÍÏÏgË–-â8ž„¼¼<¢¢¢Ä6Ö¯__ku!žfΜ‰••VVVŒ1d2VVVÆ$T‡¹¹9o¿ýöS?ΦM› %pmmmFŒ••:t ]»vµnbBi IDAT®m«{vjZ? €>úH£üáÇ |˜èèh¸ ¥)>UÁ¹*]Å‹kcUš•qõêU¡r­âäÉ“UŽä~ôÑG899ñË/¿½½=ööö¸¸¸Ð¼ysaüÜ»wÐÐPÑ©zWªßÿ .бcGq¼W¯^Åßߟ€€)“ác’˜˜ÈÎ;Ò¥:uêÇÎ;éÒ¥‹ZÝY³fajZ*ЦJ›;|øp‘f÷믿F©Tª­ãããC@@³gÏ&;;›˜˜òóó9xð uêÔFν{÷ظq#½{÷&==²³³Y´hžžž´iÓ† .ˆíº¹¹¡««Ë?þ(ŒêÚ ²qãFîÝ»§LðàANŸ> ”è{xxˆ{577—Ó§OÓ³giÕÝ»wsùòeÜÜÜ>|8èèè`mm­¶Ÿ¨¨(~ûí7z÷î-ÝÄ’"!Q–ôõõY²d ––– >ü/%P —éÓ"##ƒØØXµ\ñÅÅÅ\»vV­ZPPP@óæÍ9xð ®®®4hÐ@ü°µnÝš+W®PRRBff&ööö¸¹¹‰åmÛ¶åÂ… ÿZ¶lIhh(-[¶äÂ… b[­[·ÖX§,.\ÀÓÓ“[·nÕØ…åïrëÖ-ììì011áòåË´hÑ---sjÛ¶-7nÜ 55•Î;söìY ^^^=zÜÜÜØ»w/­ZµÂÑÑ‘ .°fÍ&OžÌ±cǸpá , //®]»²`Á<<<âìÙ³ÂÅ J]™d25¾¾ „„„н{÷Ǿ¶³fͪQÙãpæÌêÖ­+¾óÍ7ôêÕ‹úõ닲èèhŠŠŠDû?|ø={öPPPÀ€HOO§¸¸XÔ Ô0t—Õ«WóàÁLLL¸uë‡ÆÀÀ€‚‚¬¬¬Ä}-Q9e…÷íÛG\\\¥u×®]+Rä.^¼˜C‡‘››Ë’%K€ÒÌLª˜ž7ß|“-ZpàÀœÙ¸q#-[¶ÄØØ˜°°0ùäV¬XA`` >>>äååqòäIzöìÉÇ155eÖ¬Y9r„àà`zö쉞žb?wïÞåèÑ£L™2…Ï>û¬Ö¶‡¹¹ …B£\W¯æ1\¹r¥BwË}ûöqøðaÞyççBFB2@$žÑÑÑ899ÍŽ;HII¡°°›7oÒºuköìÙƒ……XXXàååEIII…ª»5%''‡°°0îܹƒB¡ //yóæ-~Tsss™?>666Ìœ9“ÔÔT>ÌÎ;1bPêûÍäÉ“¹páܽ{lmm¹qãqqq¼ýöÛ\¸p“'OríÚ5ºtéµk׸uë={ö$==   ‚ƒƒéÒ¥ =bÏž=œ9s†ñãÇsúôi‘Ó½I“&$&&À„ ¸}û6GŽáöíÛ¼üòË$$$pèÐ!‘ßýÒ¥K„††2räH Y³f=\ºt)ƒ ÂÙÙ™„„’’’hÒ¤‰7nzzzlÞ¼WWWêÕ«Ç©S§hÔ¨yyyDDDŒŽŽW®\áüùóÌýû÷IIIáøñã\¹r…F,ŽuÒ¤IüðÔ””0þ|Ο?ϵk×8wî÷îÝãðáÃtíÚ•èèhÒÓÓ™ìß¿Ÿüü|6lØ@xx8P½ºjÐA¡PPTT„žžfF¨›7oréÒ%nÞ¼Éùóçqrrª•2––èéª *…÷šbmm]éûëðáìZµŠ>ø@Íùàƒ(**âîÝÎzóÅvT¢…ùsìØ1vïÞ @ýúõ?~}ZŒXQTTÄòå˹ÿ>/^äÈ‘#btðÈ‘#œ:uŠÈÈH”J%ÙÙÙÌž=›}ûöqõêUrssùðÞ‚ƒƒyôèP:¿uëVâââØ²e 7nÜ Û¶mcïÞ½ÄÇÇÁ•+Wˆ'>>žÅ‹sàÀâããY¾|9çÎË.\¸€ŸŸñññLš4‰O>ùD,;sæ +W®$>>ž}ûö±lÙ2¶oßÎæÍ›ÉÏÏ'11QÌ(=ª687((ˆq¯¨2B•7nòòò„»KUû~ZŠÀs%%%äçç‹ï‰‰‰üôÓO>{e155UÄmjdÛª %%%ÄÄÄÔhp$%%…víÚ‘••EVVÕ¾g töjܸq 4ˆ;wîÏž={Ôê=×£ÚÚ˜™™aff†©©)ñññÈd2ÌÌÌP(¥z›6mbÞ¼yÂÕ©¨¨…B!Ö2dˆ˜ ˆgÚ´ijn\ÅÅÅjm?dÈæÍ›Ç¼yóÄ»·"TûPý744äÁƒXZZbffFÛ¶m¹téR­h˼¼<ÒÒÒ8t艉‰"ìóÏ?g̘1¢®––iiiâý¨T*yøð!AAA¤¥¥QPP€¶¶6¹¹¹â{ZZùùùøúú²~ýzüýýéÝ»7ƒ ª•÷Vbb%%%‰¿¨èh k¼²”ÅÅÅÂØ­Š+Vàïï±ñv¼¼~äàAˆŒü÷Û£  €ýû÷ãïï¿¿?¯½ößÿ½4"!QôîÝ???’’’øàƒ¸téÅÅŤ¥¥±`Á1²Uå…šV¯^ À¼yóèß¿?C† ¡Q£FjuŽ?ΩS§ ÁÎÎÌÌÌ ¤¸¸˜+W®hd4QoyTn?¹¹¹$%%Ñ«W/µu7nL`` ÷ï߯âÅšHTT‹-RSå ¥qãÆUžÿ£GDÇéÞ½{deeˆ——QQQ¢ÃY•»ÁåË—k|Ý*kUGû믿ÆÇLJӧOsíÚ5¼¼¼ˆŒŒ¤N:O$:Ann.jíZÓ{¬:âââ())!44TĘššV£ êÐWÅÅ‹5¸³²²£—Õ­_Ùy”]ö8”‰¾xñ"r¹\«óçϯÑökҦǎ«v”yß¾}e÷ïßçàÁƒ5:—‹/V¨Ö|ëÖ-qœ*•è¿ûžjÙ²%çÎ÷xÙë×£G&MšTe ô‡~H¿~ýÐÖÖm«ú?eÊš6mÊ«¯¾ŠŸŸþþþœ>}OOÏçr$3,,Lˆü-X°€üü|ôõõ™1c ¼óÎ;¬Y³†Õ«W3sæLLMMÙ¿?©©©;vŒáÇ‹õ׬YCvv6§NâøñãlÛ¶MÄäFXXÞÞÞ¤¥¥±hÑ"±îúõëIKK#//Oº999œ:u www DBB3fÌàæÍ›lݺ•¯¾úŠO>ù„;wîThøþÓôïߟ7²lÙ2Ú·oÏðáÃqrrÂÃÃeË–áìì,¦FŽɲeËÐÓÓ£{÷îäää0zôh233Y¶lnnnb6öüùóX[[³lÙ2z÷î-⟺téRá,Im #=k++´µµÄ‘\&{ìçù?þ ''‡Û·oÓ±cG²³³R×Û… òòË/W¹nÝ 84øwÛcóæÍjïúõëcllÌõë×E¬œd€H¼ð$''“ššÊÂ… 騱#¿þú+ŽŽŽb”)!!ž={ •ÛÔÔTæÍ›Ç„ ª5@ÊSÖ·õܹs,[¶ŒE‹©nÊd2¾øâ ttt°´´äý÷ßgΜ9j®*å;™"ͧj”6$$„   *¥"e_ ,`ðàÁxU§°*æÏŸÏðáÃÅ÷7nˆÚ€€¼¼¼*<—9sæT¨@¬ª×²eË¿Õñ.{ ²²²D›¥¤¤ˆÑú––ÀíÛ·±²²ªp;ׯ_~þe¯kÙÏU£ª^\\kÖ¬åùùù¢3«‘E) à‰2ö¨:9 , 33S-ÍgE”=©É=]BBB¸~ýzµõž$ȶ&ÇrøðaµïK—.U˦U™ÑRsæÌ©P½¹ºã,k€Ì™3GíOOOgñâÅ,Z´¨Ò}Ž9’€€êׯ/‚~£¢¢„¡Z–•+WƺuëDY›6mDLB@@@•.b¿ýö›8qâ?üð~ø!½zõ"&&†¸¸8d2™ZìLmä믿Ö(ËÍÍeÞ¼yåÍhoÙ²E£¬¬¶‹êþ+{ª®jà©"ƒJÝu‚ƒƒ¸víZ…ƒ+ç¿IE=}ûö¥oß¾je-Z´ E‹je*c­ì}çããSebUðzm%11 {{[JJJHMK{ìþA¿~ýèÞ½;zzz4kÖLm`pذa$''cccSå6Z´€£GáÏ?¡^½רW¹}«èÞ½;ûöí“ ‰øøxêÔ©C~~>ùùù˜››‹«V­bêÔ©œ={---رccÆŒaÅŠÌ›7uëÖѵkWtuuÅ_bb"...$$$ ¯¯O||<5âÆ¸¹¹‘””„±±±˜˜˜ƒ¹¹9[·nåܹstêÔ‰7ÒªU+’““qpp 22ÑY«Ê€ùý÷ß5Êk’–0--ˆˆòòòÉd‰Nmaa¡ð-¿ÿ 6hl«&u‡ÌÌL’““Õ\/N:¥Vçäɓ°HLL.™™™jb~ùå{@µ^Ùã,eÛpÆ "Ö¥<>TÛNÙõj’5""BtÆUÁÕP:nii)bvíÚ%Œ“Š:#Qþ*êX¨F¹nܸÁ;wªtѨ¨SU6๪ûO©TŠ4–<àÁƒUn{ëÖ­Oå™OMMnU………ÿ˜Ÿ{ù6¨¨Mj’Ö³¬ëUEÏÉÓxÖ 4+³³3%%%U—ª¾±±1™™™ØÚÚŠ……E…õ³³³IOOçÞ½{Lœ8‘#GŽ””T­{–м¼<ŒŒŒ„[^ff&EEEÂpĈLŸ>>}úˆwymcÀ€"ƒÕ‹†”œàŸ!//—ÜÜ<”Êr²sª+©©©È¼&—ËÕØhkkWk|¨èÝ‚ñãÿvX»v-cÆŒÑÐkqqq!;;›GÕúÁ É©…¡­­-‚ëtttDÙµk×Éd4oÞœñãÇóù石sçN5j„çÏŸgÚ´i¬Y³†)S¦!F˜CBB„ßñŽ;Ø·oC‡å矦¨¨ˆsçαnÝ:æÍ›Ç´iÓ8uêóæÍÁ³Ë—/çèÑ£¬^½///>þøcBBBðôôäîÝ»¬X±‚5kÖ°`ÁȈ#xûí·EüA§N4ÎuÆ £‚%%%¢3zòäIÜÝÝ‘ÉdÂ>22’ââb|||ª]V±lÙ2Ƈ®®.III"M¤ªÃXQçòI9pà@•~¥ÇWË £òÿ® • UEò'Nˆø„Š^P5éô–oòËÊ~þòË/5 Uû•_ö¸”ñyM‡šÞ@5‚‚‚„‘rïÞ½j÷[!†ì1݇‚‚ñŒü“”oûǹ—­[·Vø^ÒYN•~åÊZµjÅ•+W0`€pÿêß¿•3:ÖÖÖ4hЀ³gÏ2cÆ ¼½½+µ/oˆ<ޏêžP*•¼òÊ+lß¾üü|ÑI*ß®EEEôïߟP§Näry­éüÚÚÚbkk+ýˆK<dr9J¥’Ô´4îGÞÇʪNéó#{öû.((Pë'4kÿV¸EJJ ‰‰‰¸ººV¸|Ê”),Z´¨ROÉyÙ°a]»v¥Aƒ¬\¹’áÇsöìY¬­­166füøñ|ÿý÷ìÚµ‹;w²qãFöìÙC÷îÝÙ½{7‡âÖ­[¬[·Ž3fpøðarss133CWW—o¿ý…BÁ§Ÿ~ªöÃ`jjÊ‘#Gpwwçܹs˜ššràÀär9–––¤¤¤Ð¦M›*ý¿çÍ›‡FjÅC‡‘””Ä•+WøþûïEƤ'áðáÃâÇ6<<µØ„„„§:º›žžÎ'Ÿ|òÔ¶WVÂã*WEMb *âÌ™35ZVU½ÿ:«„\][Õ$ÀYâñïãÊ gggbcc)((àþýûÔ¯_Ÿ+W®¨ÕiÕªß}÷]…³ 2™ SSSÒÓÓ{”µ*cÍÅÅå¯L3BCC±²²¢°°PÌú©‚ó ¸víšp¥hР‘‘‘Ìœ9“1cÆ––Æ{ï½Gûöíéß¿?7nÜ`èСÿú5ùé§ŸÄ I“&M„«Ð¹sçHJJÒpÿÙ¹s'ÑÑÑ"v£¦;vLdxºté7ÆÄÄ„cÇŽ¡T*éÑ£Çs{_ÛÚÖ%++QzÀ¥²t0Ò¦®Nèh—zLÔ¯_¯Lå3?ÂÂÂhݺµ(óö†Ó§Kÿÿ“?~œŽ;VªV¯P(P(dee½P±^XdÉ’%£gÏžEOOO¤$„ÒQP3336oÞLƒ èܹ3:uÂÅÅ…–-[’œœÌàÁƒ;v,}úôáÍ7ßä»ï¾£iÓ¦™™ÉÛo¿M@@‹/fÙ²exzz’””ôD"\*¬­­IHH [·n3xð`üüüèÝ»7999b±,Æ ÃÝÝ]HuêÔ‰^½z1þ|µé?SSS´´´Ô2þ„††2lØ0êÔ©#ü07nÜȇ~X¡JkY\]]Õ´j¯¿þŠL&{ª³ÿ5,--Q(Uæî|òÉ'OÕ|–Täÿÿ¬±±±¡¸¸Xm6ìiдiÓ§~>zzzØÛÛW:kô4Ñ××ÇÔÔ´ÒYÀgÉŒ3Äû÷Ò¥KXZZbkkËš5kxóÍ7‰ŒŒ¤C‡œ;wgggîß¿OXX@©&Nu18çÎcôèÑпÂÃÃÅlÇéÓ§éÑ£›6m‰!7n¬ûõopêÔ)ñþ ±nnnGªTÇ|ìwÀîÝ»…râÄ êÔ©ƒ‰‰ -Z´øG:¤å÷i¾Ãœ),Ì‘~Êàà` PXTP‘¢üGžwU" }úÀ²eÿ¼\©«4 Üæ322$äE "a®±cÇbiiÉW_}%Ênݺ…››W®\!11‘^½zѨQ#\\\ÈÈÈ 22’öíÛƒ‰‰ ®®®2gÎöïßOQQƒ ÂÍÍ ¥R‰››‹/æ?þàÞ½{ 0€,,,HOOG¡P ££CII fffhÐ ºté¢E‹ÈËË#%%oooÌÒ¥KÙ½{7ÉÉÉxyy1räH‘2XâÅÁÐtt - þÒ§}æT—(FÅ!Cضm|ðÁ s=$jPèµjÕŠÞ½{#—Ëy饗°±±¡Q£FôîÝSSS–,Y´iÓèÛ·/ÁÁÁÔ«Wwß}—+V`mm-=?úè#š5k†¯¯/ýû÷§[·nxyyñÞ{ïáééÉ+¯¼ÂôéÓÉÍÍeøðá\¿~N:ajjJ·nÝhݺ5õêÕ£sç΄††Ò³gOîܹ#R¿* ”J%¾¾¾ØÛÛÓ¡CzõêEqq±øátrrÂÐÐP¤õöö¦nݺŒ?cccµ™™I“&qæÌ5Åãê°±±a„ å}úôy,ë~РAÌŸ?¿Æ9λwï®–žÀÜÜü±Õ¤£¢¢ªÌïÿOç\wqqQKõ+!Q[ø»Ï‚JØñqyðà;|öìÙƒ¯¯¯F¹««+·oßÖÐÈÎÎfìØ±øùùѸqc._¾,\:¢¢¢pvvV3:ËÏDGG“™™‰““ǧyóæ4nܘ¦M›Öšk˜’’¶mÛ˜>}:...4kÖ üýýÕ2±nÝ:¾ùæþøãÜÝÝ…˜©J×`ýúõdff2uêTñ§2`,,,HMMÚ1úúúX[[ãïﯖùêöíÛãïïϬY³X³f ¿ÿþ;=zôûyøð¡˜QW•©â™:u*þþþB“ÉÏÏÎ;ãïïÏÈ‘#4Rn? ¾ürË—¯©¶^`à1fÏþ„þ?~îúõ0fÏþ„‹¯H/–g„ŽÈåPÃ<O…äää Ø©\6_$¤sss¦L™ r@—íЫ„š† &UiAþùgÄ^6øQ&“±yófá¢$—ËÕ´!Tu7lØ€L&cýúõÈd2‘Aê÷ßW[wË–-Èd2>üðCΟ?ÏÖ­[Y²d ü1S¦LÑpçZ½z5|ððìÔ©SµœmÛ¶åòåËÕfØ166ÆÅÅE´K—.]Ô‚ÐW¯^M||}X¼x1 …‚›7obooOË–-qtt¬q[ß¿ŸiÓ¦ ¡8nÞ¼‰ƒƒÃ¿£þ  @dd$¡¡¡qôèQbbbĬNEï]KKK|||ðõõÅ××—±cÇŠß•²ªõíìì044ë«ÜcbbªÔ,ª[·.wîÜáèÑ£=z”Ÿþ###ú÷ï/ö=iÒ¤*ϯAƒ=z”Ÿ~ú‰û÷ïW:õ$ƒ¹¹66ÖÄÇWî6t‚=º —ËhÙ²9W®\'(è¸(ëß¿7û÷"ñlèÛj¨ú·QÍÔÖô Ší}Q ‰*;°Pê†Õ¨Q#|}}9pàýúõ£_¿~ :###´µµÑÖÖÆØØX-'÷ðáÃ5í»víJË–-144Jg‡š7oÎÈ‘#Ù³gûöícË–-L˜0Aü°øúúòÞ{ï±uëV¾ýö[ŒŒŒDÊK 166ÇQ7/ÕqÊår¬¬¬ªì Nš4IcyE¹ÇõõõÅ —¹¹9Pêw^ö‡qܸqþPÊårLLLIJòùÎår9cÆŒç\v„ÏÜÜœAƒÑ­[7úõëG—.]011¡{÷îÂÕÃÂÂBè·Lš4I\·ê({¬•ýÀ«Ê­­­5 ªŠÐ××YŠ|}}E[¾ÿþûXXXˆeª4̪ÏUµ½ª­ÍÍÍ©[·. Æ­¹¹¹˜wss£sçÎ 2„ºuëV˜-Iµ/Õ5¬h¿å—Aéèoy±1(SØ5¥ìùV´¯êÚ·|JاAùg ²gÆÔÔ”>}úàëë«æþذaCúôé#î'¸¬Î ,‹‡‡ÞEªÚrÚ´i 6 ccc Éd¸»»£££Ã—_~É«¯¾Š‘‘‘†à¦ÊH}ë­·ppp@OO#F`eeE§Nxùå—Õ¶õSSœëküYÛ¼Xú ÿ-ZT©Q«« UÈ=5öîÝûXƒAµÁ#âŸDrÁ’x,5j$>«DÔ"##Q*•bôKE“&MØ»wo…WWWêׯOÏž=±°°Pó¥Ö|YèÒ¸qcç¢âèÑ£øúú²mÛ6ÌÌÌ„{Yƒ øúë¯E²UG÷úõëâ{yªA­n¹¯¯/AAA¯ø³Ï>ãƒ>`þüùb¤ÐÝÝ]lÇÄÄD¸µ999ѰaCá boo/fš<<ÚÚÚ4nÜXhí¨\7T硺FŸ}öY¥ÇóÙgŸ=õ`ðŠŽ¡&ûrvvÆÄĤÂvlÖ¬ÙÙÙå[lhhH‡4èË?•=³gÏæáÇÕî§aÆOœzõqTƒ---ÅÌK@@5Ò¾1b#FŒ ##ƒ¯¾ú 6oÞLVVnnnBKçyW0.{üeg~*ê8U$”VÝ̦ZßÄD-i‰‘‘‘Æ~TYÇTï~ÕlYçÎ5¶çé鉧§g¥çS6½¼B¡PÛWE×MWW- CêÒå«H€çˆÿýïi¼ÿ߆ à ½/kLbb¢Æ Fu¨bÉç¹’ ‰U‡øË/¿D.—s÷î]bccÉËË£Q£FL:UˆÉµoßž7ÞxCü üzöìYáÓÎ;)**ÂÛÛ™L†B¡ wïÞ\¼xGGG1c2zôhôõõñôôDOO¹sçÒ°aClmmÑÒÒâÀìܹwww\]]166F¡Pˆ™‰)S¦ˆTÆýúõ#::šÜÜ\µN~Ó¦MiÖ¬¦¦¦ 2„Ó§OÓ°aCLLL:t(çÏŸçÈ‘#\¸pccc:wî,ꄹ¹9;vì`È!XZZŠY†;vˆ¶,+â¦T*‘ÿ%U¾ÞöíÛ2d;vì M›6tíÚ•›7oòÝwßѲeKÙµkGåõ×_`ôèÑ"~ôèÑÂÈÞÞžøøxÜÝÝ155EWW—6mÚ””„ o¾ù&P:30`À"""ðôô¤{÷‡caaAÛ¶mÉÍÍ:2íÛ·'((ˆµk×R¯^=:tèÀ¨Q£¨[·.õêÕÃÍÍ wwwµkóÑGѨQ#ìììËålÛ¶»wïâããÕ+W˜:u*ûöí£Q£Fèêê2hÐ är9Û·o§mÛ¶ :¥RIQQ‘˜Á=z4&&&j÷-”º\©ŒðöíÛ?QL˨Q£8uêFFFÊ¢E‹„®‚ê¾® GGGÈÊ•+qttÄÖÖ¶B¤qãÆ$''« &&&888póæMìììprrR[G__ooï§–Á«eË–xxxhdË{–Ñ´iSFŒ……Ë–-ÓèÜ>N§ÙÏÏà±g²$^ JŸ™vüøãÏ—ЯßËbYLÌ:tèÅýû×ÑÑÑÁÏo*+V¬ÁÚÚŠÜÜî¢l}SSSaˆU´\åšÕ­[7 Ô5Áœeg–TuËî[¥ÁR6UUVeë©Ö/›U«"÷×^{­Âó(û9??ŸŽ;beeEff&¯¼ò ¦¦¦$''Ó³gO5jD\\£GÆÙÙ™èèhttt°³³Ùuðöö&??¬¬¬hÕªvvv˜ššÒ¶m[ „+_Y· UûTtÝTÚ ªe¬²]µå=z‘‘A~~>ÞÞÞâ^JLLd„ èèèЮ];æÏŸ££#“'OÆÊÊŠèèhFŒ»»;%%%âÇÇÌÌL¸Íikk#—Ë6léééÜ»w…BñXYPd2Ù¹ø˜››Ó°aC^zé%nÞ¼©ö¬>ùy}¢¢¢P*•j)[4h€““K—.î15Iõ[þ9RU$êëë Uo¦OŸŽƒƒƒ˜­“x–ÈdЫW7ÂÃï —Ëqum(–ÙØXsàÀNáòjiiÁСoHÆ ÐÒÒBK FŽJtôúöíõܸï=¯´i›6Á_?ÃÏ„%K–ˆ‹ÇÁÞÞ¾F3È’"!Q ªŽ›*æãŸÞ¯Ä³CWWWt E¹¥¥¥èx—58ËŽ´—½>å¯UÙñ¿©7¢±/ÛñýôÓOÅg+++þͨJíyáÂÿ±wçqQ•ûÇ?³1 û.в¹+*â‚[jjå®um³´²[v1—rÉnVÞûÓÊ«•­feVjfîû’i*î¸ï¨ˆ²É6Àì¿?FNŒ€ !>ï×Ë—Ì™³>çÌÌùžgùîÇÁÁAj'èÐ!d2Ï?ÿ<‰‰‰\»v ­V˨Q£Ðh4 ¼¼¼P*•Œ7ή©•J¥’j» …h1BÕ­¨…\.ÇÉÉ©Ô8 …FCaa!ÑÑÑe©=bÄ,XPæë²¦3†7ß|ÂÂÂÐétŒ1¢Ô{#FŒ`Ïž=h4š2o²ÆW"¯M³fÍJ4Á, <4 aaa¬^½šÈÈÈj&û~7uêT©¦/""‚#F T*Ù¸q#ÉÉÉŒ9Rš×`0ðùçŸsñâEf̘Q®>< ,>'ëÖ­£]»vøøø°lÙ2¬V«TK[UnÍ2]¼f¸²4iÒ°Ôd-[Ú×¼ùûûâïïk7ÍÍÍ–-ÝÄYM4(,´ý_ÙRRR0¾>|8?þø£ô0R ‚ Âmµk×Îîuñ›ð²2^?ž¤¤$’’’x÷Ýw¥uL›6=zOhh(ü1ñññvÃJϘ1ƒ¥K—âííÍ„ ˜>}z)7EM eÞ¼y·Ý÷ÈÈH»àâÖ×eM[ÿšÕ«Wß±½sdd¤TG½í¼...¼ûî»ÒÓÀ3f0gΚ5k&•ѪU«èÕ«—¸ðîANNŽ”¥yáÂ…ÄÅÅ% PÜÆiÞ¼9cÇŽåõ×_çÓO?½ëí:tH @Μ9C³fÍðññ©¶€qÊ”)vÙ¨+3ø°X,>|T\Lw©nÝ:û><û,üôÜÒuµRäææ¢Õj+<^ëÖ­Y²d‰@A„ªH`` ]Sôwdd$ýúõ³há™gžA­V³oß>~øa&L˜À† ˜={6...9r„E‹Iy(˜>}:{÷î•Ö^¡~J¥’wß}—:uêРAš6mʨQ£Ê]Ë9sæL&Ož À˜?¾ÝûZ­–iÓ¦IµB¶'É- -è —ššÊâÅ‹¸~ý:;w&??ŸI“&a±Xøüó’‰õd23fÌ %%…/¾ø‚7n¶á¬K] l9pöìÙCÛ¶m¹~ý:AAAR&t'''©y޻ヒ³³3W®\A¥Rñ / Õj™7ož4¨ÄàÁƒ‰ŒŒdîܹ\¿~]ú¼ >œ¡C‡JAAõë×gìØ±Ìž=›;w#eB¯L‹³YNÛ¶m¤¾w%½\œœœQ*Ë|4)) .»V_ojµ®\I©Òílذ+W®”™…¼ys(åYJ¥˜7o^©ƒî–J¥"00„„„}ôD"‚ T ©ùUÑ¢EÿwïÞ]êWTüIò¥K—–:ÏÛ~øÕ :”5kÖ —ËÙ°aƒÔÔÉÑÑÚ·o/5ÑòôôÄÇǵZ-@AAAìܹ“ àáá!íGE8;;3~üxöîÝ‹ŸŸŸÔ$ËÛÛÛn½õêÕã‰'žÀÙÙY4¯ª–/_΄ ¤>8sçεk¸mÛ6æÍ›‡R©D­VÓµkWvïÞ§§'ƒ à‹/¾ {÷î¼õÖ[ÒrŽŽŽ|øá‡øøø––Fbb¢4`DQ&ôâÛÉÏÏçÿøM›6%--¯¾úŠ  ]Ï—.]"11‘‚‚©‰Ø'Ÿ|ÂðáÑËå¼÷Þ{8::2yòdôz='N$11Ñ®¤Òo¦” är3VkéC§¤$R·nƒÛ¾žzõkõõ¦R9Ty.$°5ÿ½ÝC…^}¾þ~Ê ³Ü²³³Q«Õ÷ôݶ璓“E"‚ Ü?Š‚ˆ[û{Ô©SǮͭ$‹~ìÔj5M›6%$$„eË–ñÜsÏ&%T¬Ìý,ÚGµZÕjeÈ!ÂÃÃ¥äÅõìÙN‡£££Ýȃ—/_–òÎ :—Roô~øabbbغuë²ú)¿ŽÏŸ?ORR’Ô”¯¨æÅßß¿Dþ©âL&2™ “ÉTj ¡vhÕªÕû6l¬Y=ÍšÁ½öÿ¯¬LæÏ<ó cÇŽ%**ªÔ„¼"Ajâ5&E¯oVUf͚źuëP(v#’ Õ£M›6œ8q‚C‡Ñ¢E >þøc:Ä÷ßo×ýÖ@ÁÛÛ[jÕ·oß;Þ^»vMz™™É¼yó8tèK–,‘†î¾U³fÍX·nüñAAAôìÙ“iÛݺu»í¶;wîÌÌ™31<÷Üs=z´Ìæbƒ£ysÛ¿o¿…Õ«¡cG¨h·²ýû÷“““S®äƒ·óÊ+¯ðÕW_ñÚk¯‰¤6Ú¸q#ëÖ­ 66–~ýú‰O¤ ÂßàN7°Bå+ÞVýñÇG©T¢T*>|8Ç·­¬(Ó{‘ððp^}õU©oRQ¦ù²<÷Üs 鵫««´¢Úˆ©S§JÍW¼¼¼;v,...JËúûû£P(3f :Nš÷Öã™2eŠTk÷ÄOœœŒ££#žžžµºi‹P~/¾YY°s'L›ÑÑPžQ¼- [¶laÔ¨Q•¶O7¦°°o¿ý–_|Q µÍ#<"öñRU ‡ ‚ 5”»»»ôwñ&v%û"”Ö®½ 7[þ‘š ééãÇÛ¦Éd “Y™5kV¹†¥¾[ŽŽŽôë×¥K—–ÙDQ ‚ ‚ ¨ãÇÏ¢×ëË|ÿìÙs·]ÞËËoo¿Z]FÕ1Ø2‘=z”6mÚÜÓzš4±ý+îʘ0Áö·³3˜Lɤ¦>Å'ŸÀÈ‘PÑÍo«S§NL›6ÌÌL<==E"‚ ÂýmøðáR³¥ºuëòÊ+¯àææVj&ôÔÔT¾üòKÒÓÓ=z´ÝˆjwòþûïóÎ;ïðí·ßòÈ#Xm™ÐOŸ>]®ý-…BAÓ¦ah4Žâ‚º &“¾Ê·1iÒ$€œûùÛ¶¿bq¥ƒôèQ¾m¶k׎ýû÷—š T ‚ ‚ ÜWÜÝÝí2¡Ÿ;wŽÈÈH5jTâéñÞ½{‰ŽŽ¦W¯^¼÷Þ{L›6ëׯ“ŸŸØú”•ç"77—ÂÂBÔj5X­VŒF#‘‘‘v 1333Q*•ddd P( àÚµkRíBPP …‚ôôt)9aÑð»`4ñôôÄÍͤ¤$fΜ)%9¬ìvú2¨ÕX­fqAÝ•ÚÓ mïÞ­ AX˜íõÿ[ržƒáæ`mdgÛú—Üêå—A«ý뵓Ó_Kß¾}Y´h±±±tìØQ ‚ ‚ Ü¿âãã™p³=‰““½{÷Æh4²bÅ Nž<É·ß~[êrÓ¦MãìÙ³üöÛoRçt­VËË/¿\êüíÛ·gÿþý´oßžÔÔTêÖ­Ë7X±b—.]’‚ ™3g¢P(ðññÁb±——›7o–‚zõêÅ7ß|c—lnüøñôîÝ›aÆ¡T*ÉÉÉá­·Þbûöí\¼x‘+Vиqc{ì1qâ…{¶uëV\\\hß¾ýmçkÛ¶ä´ÁƒKN›7òòþz]X½¾r¥3ŽŽ¿ˆDA„û[HHS¦LaîܹLž>ž† 2iÒ$Ž9ÂÌ™3™}:GŽá³Ï>ã_ÿú®®®R!—ËÑjµtéÒ…¯¿þšŸþ°%Llݺ5FÚö«¯¾jw<...Òº† FLL ¾¾¾Œ=š:uêTj9Ú‰иq8S§NgÆŒi%æ»qã99¹DD4`Ò¤i :€ØØ|ðÁ{üñÇ.ÒÒÒ©[Wä-™?>sçÎ%&&¦DàúË/¿ðÉ'Ÿ0nÜ8>ùäiú¸qã0™LÄÅÅqúôi> À¸råÊ=íÏ€P©T5&oÜ–-o‘˜˜Xbú A} иýµ>p`È-£“½Åþ3‰ÆßH›6mÐjKL/((Äd2qåÊUm^¯'4´¡øA„jößb½f‹DUZ-EŸ[RCûùùñnÑ#×»pkß __ßÛyûí·¥¿½¼¼7n\‰ý,2eÊ”ÛÏÔ©S¥¿;wîLçÎÅ Ì™3€‘#Gnwoz·²²²8~ü8]ºt©Ð>¬]»–¾}ûÞ¶6®,f³™M›6ÝU_¥ÒŽiÇŽ´jÕ¬X"Μ;¬åG»WÇŽžž^åç©J£GШQCtº¿zÓäææáííƒR©ÄÑÑ‘°°¿. ÿ:â#‚ ‚ HZµjÅÂ… iÙ²%ÇŽ£OŸ>$''¶,á?ýôQQQ¥.«Õjíú#•‡ÅbÁh4V¸ÜøñãKm t·Þ|óÍ /?aÂT*U…3§ÿòË/Õrn«$1 Fd2™”ù3??™LŽJ¥ÂÛÛ “É@~~>YYYøø¸”k—/_¦Aƒ·G¯×säÈ|}} ŸdAA*ݰaCX½zmÚDpøðQ^{í¯&:_}õ…Œ7OO¼¼<Ø»÷99¹têdëXßµk'6nÜŠ§§Z­3¾¾>¢P矞¸¸8Z·nÁ``íÚµÒ{/½ôÇ/3yã7*¼]¹\~O}pî%ø¸×åïµïP¯^½ÊN»2É«b¥‹…üü|)ú2Mèõd2ÈÏב››‹ÁPˆÁPÈ¥K—pt¼û‚¶Z­¬X±‚÷ßÿ¶óF.\ÈùóçY±b…ÔiMA›‚‚éoƒÁ€Ùl¶›VD¯×“••%ý+mž"………Ò|ƒAšž——g÷º6ñóóå±Çz‰îÝ»ØõßèØ1Š.]låU*Ï?ÿ4ÉÉ×Q( ð(}ûöF­v 11‰‘#Ÿ©–ÀûR©$** ¥R‰““‘‘‘v7éŃNg—‰¾~ýúÒß¶ûNƒ(лøðôôD[,!INN&ûá¸*çÜVÕÁܸqƒààòòrHMMµ 2®]K¢Y³8°•ª|»°råJÜÜÜìÆþ.ÍÖ­[ ”ÚЕÖIAd'N”~—,YB“&MX¸pa‰ß˰iÓ&6mÚDŸ>}èС}ûö-±>NÇG}„ÙlKʧÕj™4i`kÚAÛÒ#Ôüã%uêõë×/×ýV@ÂÃC -óý¦MCîz]¥UÓF, f³½^R©”"ÝÙ³gÓ¦Mzè!š7oÎÒ¥KéÙ³'±±±wõC/—Ëí,Ý_ýµ\Ëèõz ʵŒÁ``ýúõåZæêÕ«KIšîFRRçÎ+×vâââˆŠŠº«$@-3€Í›7]®/“Šl§:–1™Ldgg—k³ÙÌÊ•+˵Lrr2åz2%%…“'O–k;ÇŽ#**ŠFUi9oÛ¶èèh»'¨÷ë5pýúõ*ßNZZ^^^åZ&==Ç—k™S§NY®)³;vСC|}}«t;Ë–-£k×®å @*²šbÔ¨QüðÕò€O¥RñòË/£T*YµjsçÎåwÞÁÛÛ›6mÚ°oß>i^___^xáéw.##ƒ‹/rôèQ”J%………Õ:€L¡¾«Åd×2Ãjµ’’|í®–÷õõ¢Ø}\ çÏŸ':º=fsé}22n}ƒ€ÿZ€¸ººb4æWÙ6š5kÆ—_~‰··7J¥’§Ÿ~š©S§2xð`:vìÈüùóËuŸò Ù·o{öìáàÁƒ´mÛ–>}úðË/¿MŸ>}˜3gN¹†0þÛª¶téRâââprrbêÔ© 6Lê„äìì,õþ¯W¯#GŽdêÔ©tìØ‘¡C‡VÉþôìÙ³\óׯ_£ÑX®e E¹Ÿ”V„V«¥]»våZ¦M›6åÎZÞ2«®sSË”—L&£{÷îåZ¦qãÆåª-(ú uèСFž›N:•{dšz­Õ­[·BYt«ãx‰ŽŽ.×2eVáßß=zô¨‘禪øûû3iÒ¤Ji¢’ššÊ7ß|ÃÛo¿ÍÀÙºuk¹×1{öl»ÖÕ€PXhÀÉé¯ï™7²ÐëEçåš®nݺv9`<(ýÎ| © íÛ·çСCÒë≠#""˜={v•l÷¾ @žyæžyæ™Rßûç?ÿi÷ÚÓÓ“Y³fUéþ”·ýnÆåOº¨P(*¥jüNÜÜÜÊýÃ[‘$=ÕÕæ¹"Û©®eÊK.—3pàÀrß–—‹‹KµÜHU¤Ìz÷î]k®µ¢&(5ñxœéÕ«W¹–)OM«ø¨Yš7o^"0 µkîùôÓOKç¸øü¥ñöö&88XZ¾¨£z\\_}õƒoool·.ooo\\\˜2e o½õ&“ ­VËŒ3ªµ<²²²ptô§¨ò+11rrsá@ªRyªõk:—¿å RUñòòªpRšÆÉÉI!¦6pww¯UCFÖ¦ï­V{³Íyíàééi×¹T¸wÅÜ=€;vì]Í_…BQêƒÂÖ­[óõ×_—¹®âý”Š2Yÿ ò)ÔëqÔ¨INNA}ùAÈýûßÿ®5ÇR5&ÕiܸqµæXª£‰SuzöÙgÅ÷@ Õ§OŸZun^{í5ñC%T¹ô´47 --­Ê;â ‚@*‘ƒƒ–ÒFyÈÎÎA&3£Ñüõ´týúͤ¤¤ò Õw3kÖ,füøñeηsçN~ýõWœyå•WÊ5‹ ‚ð`8tè?ýô …‚‘#G–Ù?//Y³f‘‘‘AÇŽ¥çÌ™ÃÅ‹ *u„ƪ`±˜1›ü¹³»UÑ8:âícË@~îÜ‚ê7@&…\!š` Âý€€ƒAWbêµkWpqÑ¢ÑØ>àÛ·ÿ‰Ñh":ºü%o¾9¾ÊxΜ9 2„Î;ÇܹsKÚôâÅ‹:tˆ¹sç¢Óé˜>}:3gÎWŒ ÜtöìY»‘¯n}-NÇÊ•+¥ä{S§N-³ïá¬Y³ˆ‰‰ÁËË‹ 6°~ýzÀ6`ĸqãØ²e «W¯®òÜÎÎNx{»’—w] 7#™LFttko6Yôöq±›ïÂÅ;›™™ÍåËË|¿  ØØýÒ6oe6›ñôôF«u­Ue,“ÉÅ…P]ÈÝÉËÓáååA£Fáe~ +[ZZ>7Ÿpx{{“žž^ê|ƒAj×îììŒN§W‹ H?¤Ìœ9“÷ߟzõêQXXÈåË—iÔ¨:N‡J¥ÂÃÃüü|222ðôôÍ„ZÇl6c±XP*•(•Jôz}™ófddàå倫«+‰‰‰<ùä“Ìž=›õë×S¯^=&NœXåûl0è1 bt§’÷%9e–Yi, yy:¼½½qvv "¢¹(ÄRdggbµšo–YÙ÷{……äŠÚ¦þûŸO9F(¯yÈŸƲtérÔj5†¶m[‹³*÷‰¢œ1‹/fâĉ¤¤¤ðñÇÓ§O/^Ì‘#Gðõõ¥S§Nìß¿…BÑhdêÔ©¢ð¡˜-[¶ÆøñãY¿~=6làÑG­²íyxxpåJ W®¤ŠÂ/W¹ù¢P(0™ì§réRâÍ›ìQPw)8¸d¾877w²²’9~ü°( .44„²jÖø¤cÇ(RSÓpww£U«–նݶmÛrðàAºwïN\\œ]r•]»v¡V«‰ŠŠÂÍÍììléf«<™¾¡¶ £M›6ÒÓÚ Ø%yjܸ1{öìaݺuDEEÕšQÌ¡8”J%ùùùèõz<<<¤÷rrrX¶l#GŽD&“ѲeKŽ;FË–-¹xñ"5"99Yªtrr"##£J÷×ÙÙ‘&MBĉ«“©d€Q¿¾¸7¨¨¢‘"NNqm>@þ¶;¥R‰ƒƒjµJeõ «8dÈ233‰‰‰!77×.·Â®]»¤ä5 >œ˜˜~üñG^}õUqµB1ìÞ½›_ý•¬¬,’““IJJlÍKŠÓõèу'Ÿ|²B9p¡¦Óh4Œ=š÷Þ{9sæ0fÌ»ä»ï¾“š1‚}ûöCXXíÚµcàÀäååCFFF•%ͽåÖOü«Ð?Q–¢<ſ۟¿rÄUñÕ¦×ë‰Ý_bz^^mÚü•-22•ªúó :´Ô/ùÉ“'Û½®W¯sçο°‚PŠ˜˜Ö­[Ç“O>IJJ ?þ8¹¹¹ôèÑOOO4 ñññhµZbcc¥„d‚PÛøùù•ši¹nݺìÚµKz­R©5jT‰ù tß&2A¨1ˆLfÙêNêÔ g@îS...<ù䓸ûûKW4iýúõE ‚ ‚üM°AAAxðÔ¨Lè&“žÜÜqVA„žÅb… ‚@ªšÕjÁdÒßüâµ`2™ÅA(r¹ ¥R) B€T·¸¸£>| •Ê~==½1™Lhµ.bXOAá¾”••‰««×®]-ñ^DD­[‹„v‚ ˆäo€““nnnxyySX˜ÏáÃGhÛö!òò²ÄAî+ Wð÷÷§Q£pš6mDzz:yy:L&#7©ðº32²8uò”(dAþ6f³Åý€( œœœñññF©T`2°XÌèõ¬V+f³h+‚ Ü_ôz=, F£OOw\]]ÈËË'77÷žÖíííIt§¶¢AøÛ ⻺uƒpqqÂl6a2YÄAj³ÙŒL®®Îäååa2™€Š%èµZ-X,FQ¨‚ ümîæ;¨Fw¢8sæ4.Ä“‘‘)Φ ‚Pk’”t””Ñ]„Z¯J¾åbc¢3©KL¿’ÇïVë|WëqtÔ “ÉÈÉÉ%--??_œœÅYAj…ÜÜ<²²²),,D¡Pàéé! E€T„Ñ"£A«~Òk‹Å̲¿¤ -WW·»Û\­Öàèhë„îääLNN©©éhµZ²²²8zô¸8ƒ‚ Â}%??Ÿ† ’˜˜DAA>*• ‡¿ÚÉd¢ŒAH…ìÚ¶–‚|½úcÕ’o™õN Ï^líÂvìØM›6-qqqÁb±°qã6{¬W±/èλ„£cé5þ¹Gœ=Aá¾têÔ¹2ß+((¤{÷N¢AHyäfg1oöçœ;u„[V³cóJfÍ_…«» ÀáÃGiÔ(ŒS§ÎÙŠÝ»÷Ú ……zRR®¡ÑØž ¹¸¸ ÕjÑj]9þ¬8s‚ ‚°°pêÜìÄ]³%&&âïïOFF¹¹y¤§§Iïuí-N¦ ")/7wæ,XG̳½Ù´jž>tí5(ù£°|ù"#[•ºÛ¨ ®xzza0b±XˆÝƒ·8s‚ Â-¿r/“ŸŸ_ã÷õøñ“ôíÛ.µÚðð†¤¦¦’““LVuã䥥ßZUsww+³…… ÷iàåãÏÿ¾]Í£ýУ%Þwvvbß¾ƒ„„4`Ë–í¸¸hKÌÞ¹\F~~ž8S‚ B­d4ÈÎ6F\Ü¡*ÝÖ±c' ið@—·\®Àj•‹ Oj[¢¿Ö€ã:,Zúùy¹øk h”°ÚæyùåüþûNìËï¿ïdòäq%Ö£ÓéHMM% ÀOœ)A¡VÛ²e3ÞÞ^Uº GGGBB T<˜Oÿ-V3V«¹\ɤ·{¯°P_ÔžU­Ö‡Òoš*­•«ÑLe]2TÊõ3dÁl.¬™H‡ö­PÊSp Tž@ XÀbµJóõèÑÕîÿ[]»–„Z­&>þ^^8;;#‚ µIfæ ²³³ñòò¬¦-ÊÑ8jP*¼¿›6þA‡Ž¥gŠ×ëõÔ©ã_æxm•ššFjj:uëÖ)ýFQ連Ӄ€ìܹ¦MÃP(¥„ ÑhPª¼ÏÐæÍ;ˆŠŠ¨™ˆB¡ÀZ,Ш(77wœñòòÆl6a6[qttÆÓÓ AA(ÎÙÙ‰³g¯’››[ã÷ÕÝÝ¥RE^^>NNθ¹¹ÿÈEó ªb6ß¾ÿ‹\./õ†³6“Éd·¿g“‰kE(V.•Ô‡¬Æ¦[mÞ¼ ­ZµB£Ñˆ³-‚ Ü•Î;ÜWûÛ¶mÉ'‰J¥BœHAjµ€ø‹³#‚ Ô:¹™…±ÄtG³ KÍ>~þùW.]º À«¯¾Xîfcf³™íÛÿäᇪõçùóÏçsãÆ ¦L_fÍÊŸƲcÇ.ž{î)‚‚êÖøãZ¼xññ—xå•nÛoiÁ‚ŸiÝ:‚ˆˆæÕ¾ŸË–­Âßßï¾z(±qã6y¤'.\D&“\ê¼óç/$;;‡ þu_~>*TÏk61tD¶m†Ùb¿(‚ ‚pŒr3;-ûØ`ú]ú÷kÊjŸ=R£÷{Ó¦mhµNŒ5‚Q£F°eËör-ŸÃ¬YsÑéòÙºõZ}ŽçÏÿvíÚHeµ|ùš2çmÓ&??_küqmÝújµZ:®?üô¶óØ—† Ã*´­ƒãn[nŽõÖû%¦õêÕÖ­[ÞW×ͺu›¤¿Ï»À¹sñeÎ;dHΜ9wß~FÊ]rãF6˃×éFA*ƒÉŒNF Ö¿ÞéÍz²²²ÉȸQb~ww·Ñ/D¯7àä䄟ŸO>9ƒÁÈ?,âØ±“ôéÓ“~ýú”ºügŸ}Ë/>‹¿¿?þ¸„ýû»Ÿ1cþ‰L7mÛvðÔSóÁsõê5ÆŒù'f³…Ë—x䑇ٱc7®®.5úæ2?¿ww7©¬žxbyy:æÍ[À¥K <ýôãtìØgg'ÜÜ\í–߸q+ëÖm Y³ÆŒù ¿ý¶šfÍšðý÷?ãããÍk¯½„»»Ûßp 8JÇUPP@VV6«WoÀÑQÃÎ{èÕ«;<Ê¡CGøòËo:t>jK4}èÐ,X@½z¼òÊ ,\¸OObcàääÈ„ ÿâÒ¥fÍšKNN.Û·ÿÉŒÓÐjY´èWbc0xp?ºwï˜1“عs7¹¹y Ü=ºráÂEþ÷¿¹DGw`øða€­Fá“O¾ÀË˃1c^aóæßÑë <ÀäÉã øÛ®›ÂÂBŽ=À¥K „„síZ23g~ŒÕjÅÙÙ‰ñã_Ã××OO»n çÎ]`Ë–íœ9s^ PºwïR{ìl=f“Yü‚‚ BÈeJp*í¦ÕDÖ’Ã[ºººRÓú¥ÇÄL$,,˜Aƒú‘ÃܹJÓË @’““qww§°P³³3YYYRSžÅ‹—Ñ©S)è7n4‹­cô›o¾ÍóÏ?Íõë¶lñéé•2ÐMu;t(Ž  ºŒÿšTV;¶+uÞuë6KeúÙgóHHH¤S§¼ñÆÛ,Yò±±ضmC‡øÛËÝÝS§Îгg7æÎýñãßbÀ€G‰ŒlÅèÑ/I7Ôßÿ3³fý€Í›·±kW,/^¦eËfÌû!×®%óí·?2eÊxÆÿ—.]æé§Ÿ–â‰A b;æ ¦Ò£GWæÎý˜˜‰Ry„……0mÚd¾ûî'iÚ'Ÿ|%Ísôè –/_CVVuëÚ]¿Å×SÝ 9pà°P„„óᇟ2cÆ4 ×®%óý÷?3iÒØËæåé8räß|ó‰t,µ*iÐÀWüz‚ Bé”(¥!¯¯¡a¥?}­i÷ÛE7}å‘’’Ê¿ÿm»ùŒ¿Ä+¯¼ ½·gÏ~:u²µÕ?~ü‹ý*el/((ÍMíÛ·E¡PÔÈ~ ÑÑí˜=ûÿÊœ'55Mº^|q8;¶¿ãúSSÓøì³yÒõP¼Þû~·«1eèááÎK/=Àúõ›¥éï¼óÈå¶áÈ{¬÷}q,•€€mÈ6¥RyߤÅbÁlµ6‚ BÍ•”EVa–ôº »Ô5{Ÿýý}9|ø(……¶~ÁÁõqtÔ ×ëY³f#`kÚR–€>úh:k×ÚæoÞ¼ _|ñ-={veåʵ„†“’rFÂñòòäÂ…‹dfÞÀÝÝôô Ö¬ÙÈO?ýÂ믿Z£Ë*8¸ûö’šÃдi#Ž=!•UQÞsçâ9tèÔ¯_  ºøøxIóååépvv–²¿“ŸŸû÷–ö­Aƒ 2çMJJfçÎ=\¾œÀéÓçhÒ¤!íÛGÒ°aøÍ€Û›ÆÞöf|ïÞ4Ö¬ÙHNN;¶ÃÕÕ•¨¨HRSÓìjVüü|X³f#gÏžgìØÑdgg³yóvΜ9G\Ü1Z·nIãÆáÒ~gddT—¬¬¬ÿ]Ѽy|}½‘Éäh4j©V£¨l׬ÙHŸ>¶ŽëK–ü& PÓ“x+z÷îýnYo^¸p!C#—Y‘Ë­ÈnŽ­P(pqÑâààp_üF£Qüâ ‚ ÿ¯U†kž ¬„ʃ•ÑØ1”Ѐ`ÊzÞj‘“››Í¦ÍÛhذq±½$ è‡ÙdDå Äb)û÷.11‰  z88hËËW­X™L†Á`@©T0dHÜÝÝñ÷÷%//¥RA¿~ Õ–ž48$¤¾tsäááN``]ºtÄÕUKçÎqss¥K—hBCƒ)((Äl6ÝŽÚT¥RÅb!8¸..ÚÛÞü–åüù‹ÕE&“c±Ø?˜Ôëõ¸¸h+åk£FaäääbµZ¤rñóóE£ÑPXXˆR©`Р¾h4j²³spww# À??\]]hÚ´1iié(• Ú·oKHHÔj5õë׫ô~yy:tºüýPŠ(•jT*Û `:(Šb×@?¨_¿>>Þv}•òóó±X,„‡‡âåå——'-[6'99¥ÒvàOƒAøøx#“Én®+w¼½½Ðj(((¤oß>x{{áææJ~~áá¡ôïÿˆt=5mÚ„´´4ºvÆÓÓ½^ONN-[6ÇÝÝ__Ú´‰ 1ñ*J¥‚:uüyè¡ÎÔ©€ŸŸ¯t΋_£—/'âçç]jÿ+2‘+*·j²´ÏHçιrå* …FMýú¶ë>99…V­Z T*®Ojjžžxyy T*0à1+?[û…ó—¨[¯Îmç1›Í\OI'À?€³gNé*uëÚð¦?‚ ‚Pˆœpÿàûrß##[•˜Ö°aØ]tTüi·w‰éÅßïØ1ÊnÙÔÔ4Ö¯ßLNN.Z­–nÝ¢k|Y•ÖLª´áhCBÒÀnš7½{÷°›æè¨©PÐUÙÚ´)™»&<<´Ä4?üýíŸÂkµÎ%Ž«Q£péoµZMpp}éu‹ÍhÑ¢™ôºY³&4k֤ͼ½=íÖëáá^b;J¥²Ä´[Ëóv52Õ¡øö‹oÜ«W÷óvèUò»E¡(qŒ5Õ= —/_A.—Wxìê;÷еkÕ|‘Œ3‘O?ýA¡æÛ·ï ™NHÕí78¸ƒF »móžJÿqTjË•€ýN“ÉLzz*žž®w\ÇÆ[¹zõ/¾8™L&Nð=ðõõaúôKçC”§ ” K ke’ÈO?ý‚R©¤mÛÖRb¡£GO––Ø:L¹¸h‰¿$ =×´icêÔñçÏ?÷0{ög ‚‚êÞö Êöíb6›Q©TtëÖ‰””TŒF#gÏÚÚWvéÒµZÍ™3ç¸zõ^^žÜ‡ƒd‚ <ÐÂZ÷F&ÿ+aÛÂ/? +%??L&}µî‹ÉTP¢™Naa! —ñô¼ó°-Z4cÕªõ¼ð³↹ØŠP”£ Ô÷€˜L&ôz&“.«Ž;Áλ ªÀW_}Ç?ÿ9‚Ÿ~ZJ«V-['™ñã_#?¿“É„N—ÁPv›Õ… —àìì„R©Äh4²~ý²³sزåwì À×_ÏàÁýYµj=7äÊ•«œž=»ÝS³…U«Ö#—ËÙµ+¹\ÎäÉãpss%00 D{ý ¶ðÇ»xì±^tëÖ™~XÌóÏ?Ea¡žU«Ö1lØ*.e+gÏœçjRâw}Én3ž±\.çàÁ#\®3½^O@€™ïçææ±sçáîZIOϤE‹Æe|‚ þâe._¾øÀ•‹©’uº§$44˜öíÛ¢R)¥øiiélßþ'aa¶ö€ññyíµQX­VvïÞÀ°aƒèÓ§k×ndàÀÇn» ê±nÝf¬VpvvdÚ´É,^ü/½ôœ4ì[LÌDrsópuu‘ÖwLüš ‚ ÜG¶oXÎï–sþÔQöïÚÊ_/'¼IK Ín¾Y³>åƒÞàÆ,.^¼ÌåËW µõ­8sæ‹…ÌÌìÞ½WtÒ¤iLú§N‘–ß±c÷=ís|ü%øàƒ÷0¼÷Þüç?o—:ï£ö’’²Mš4nÝ:sêÔÀÖq³¨V¿Jë…:^Ô ô\1..Zš6m$ â*•…víZ‰‚¸%ñõuÅ×W”Ë߀ܪ(;å“O¥ÿG¤' V«•¾}{Ó¼¹­ãÐäÉï•èÈvâÄiêׯ‡‹‹€ï¿ÿ‰Áƒûãî“o¿ýJ¥’ÌÌü÷¿³ ¹}¾«W¯‘˜˜$ΰ Â}ä?sñÁÛÿbÕ’ù´ëܳÔù¦M›Ì¤IÓP«xæ™ae®³[·N·ÝæÞ¿=ÔùŽóäççóÅßJM”=^íåëïóUws>A*9éÚµ#_~ùk×nbâÄ×qwwã믿gâDÛäIcñ÷÷åøñS,\¸¤ÄõsÏ=ILÌDš7oBÆ¢°`Ábºw»uêðÎ;30™Lh4j&Lø'NœÆÅÅEš?4Ô6ŠÄüILÌDêÖ­CëÖ-ÅA¸(Jƽ3¹\ŽR倣Sé7Ë›6mcðàþdddpîÜüýý8sæ< ‰ìܹ‡©SËÚ†¹\ÎÞ½8~ü$£F=ÉMÈ+IDATOûýÝw?ѽ{WÌf3õëÛš Ÿ9sŽ””ëìÝ{Ö­[Ÿ_€L&cðàþdddJˆV«eïÞƒìÛw ÊË7$$ƒA'.4AîïÄÕÕµDJø7Þˆ)1ß /<[êòQQmˆŠjSbúŽ뤿ëÔñgÎûÌš·í6vìhF~IœUA„ûñI©¤žk2wÏžARâ%ê»PÊ­XoUdÀ€GY½z½tß«Ww ùã]Fitņ äqóž~ú œ2¤¿Ôô©´!.ÁJ\Ü1t:û›u³Ù\j†>}z’p™L.3™™70àQ®_¿ŽÉÔoo/y¤'çÎ]ÀÓÓ“>x€'žÄéÓgèÕ«Ë–­‚ "A„ê`kš›VP;@ãPo°¦‚níö¨P(¤"§NåÈ[­‚³³3J¥Ân,}ø+C£Fávùne2鉈hv×ûPbÌ¢>ŠÅ•–Ç`óæßÉÏÏçìÙ wÕ”Ká @¬V+ƒá¾9H³Ù$δ B-צMaa!˜ÍfQ(Õ²ÝÑ£_ÄÁÁ¡ÂË¿òÊHtº|d2Y¥g¹A¨5ˆÅbA§Ë¥'‚ Ô(®®.Õ¾MFS¡å²T¤Ë²À°¿B:¶ßV‹É‚g3ÞjwqRAˆ ‚ ÷®@f`a_©ïé2u4NªO÷¢I– µ\ ‚ ‚ Õå®k@ÒÒ2Ñåç‰A„J`TØš_•!=ã—.Ù²•+•JüêÞq©×Ó8uê¤(\Aþ6V¬øùøUN¢V;!“©D© ‚ B%Ð) ïø»«uölI}օöí:ˆÂ¡F»ëÄÕUƒL®%&‚ •Àä`Ãí‚ 5>¾¶ÞéV+˜¥Ï———Écň‚ Ô8:]Þ½ ‚ ‚ TŸkÉ)œ¦aÃPTª²Ûj)•LžúQ`‚ ÔH­Zµº÷$)9KW2pP‹ÚAA¨•Š_+w22J}¿0·W«^· >ºuë& T„ûJ¹“ÉLÃ&-ð÷¥'‚ p5á<&èiíHrr ºü|œpsuÃÉÉ‘]*ÞžhµZär‹Yš n"‚ ½s”9вASœÍŽdgçàááNhh(‹ 7™ &“èÓ!Bí$ò€‚ B àççÅb :||¼ÉÏ/…"‚@Êá|©Ó¯§$óóÂïï¸ü…óç¸á¶ó\OI!//·FZYÇ[D§ËãëÏ?­ÐºÆ&v÷ŸËqeggñýü¯1›ï\ÕŸŸ¯ãËÏ>¹ë2±+Ÿ¼<öìÚY#?å9޲d¤§‘•Uéûv-é*»vþAffF¹–³X,ìÚù‡Ý¿"¿,ú‘¤«‰vóoZ¿–“'މoGA¨Fjµ''G鵓“#èk)‚@Êt%á2Ö®.1}ýÚÕ´iuç›YŽ‚ü|»iÛ¶l"éêUéõÖ͈?¾FÚ‚‹S'Žãéå]¡uçädóéœY•¶¯……üºägîßÇé“'ìcGâìæuss'33ƒ´´Ô;®÷ìéÓ¸»»ßu™g2›¸q#³F~ *8·gן;W¹ÁaVKÿLffK~þNw×Ëêõz¾œû1™™dffp#ó¯²ïÜõ!–-]ŒÕj•¦õy¬‹.Àh4ŠoHA¨&îîäçëÈÏ/þÕ©@ròuQ8‚ Ô:•Ò¤{Ï^lß¶… kWóh¿ÒôÓ'O0ò¥J¯7®[Ã#}û°kç"Z·¦° €•Ë—Ñ!ºÍZ´`Ó†uÌûò3êÕ ¢Apcߘ@bâV­ø €7&OÅÉÉ©ÔýÙ»‡MÖÐû‘Çè݉˗.²ðûoˆhÝšƒ·ÛŸ¢¿÷ìÚ‰J¥búµÈdðï÷þ À’ŸrîìÙ» ¨~]²ˆçÌ-1}ú;S=f^ÞÞlÝ´7ww6¬[‹³Ö™ ß K·î¬Y¹Ün¹u«Wrèàžyn¡aáÒþædgsâøQ¢;w-u_Ö®ZÁ7_}¿¿?õ‚êóßg³7v7_þ)2d4 åíw§KI®&L|‹‰ãbJÝÿâÿôC‰y6o\ÏÞ=»iÌs#_àƒÿ¾‡^oÀÑÑ‘7§¼ ÀŠeKI¾–DßþƒHOOãÒÅx¬+ׯåÉg†Ó°Qcéóòòˆ;t.Ý*u_ŠŸÇŒôt.ÆŸ'ª}G¾øtééé¼õÎ{(•J~[º„“'Žðâ˯X·»vþÁï[·àëçg·ÎÌÌ .œ?OT»ö<Úo9ÙÙ|ü¿ ªÏˆ—^à£ÿ¡  µÚIS§•¹›6¬c_ìþñÔ34nÒ”ëÖмeß}ó5ݺ÷ [÷ž¥ãßû·TÞ —/±àÛy¼6fÜ]FCÃr)>žììlí×_šX·i©© ÔÅF¶kÑšcGãˆlÛN|K B5ÈÊÊâìÙ3%¦‡‰ÂA · Bæ}1— çÏÞ°Ôy~ߺ™v¢ÉÎÎbÿÞ=„…‡ãëçOÌØ |4ó?ô~ä1êÑ“øóçèÝ™F›HËïß»Gº‰ý¿÷ßaÂÄ)l\¿VzßÍÍ>õcÕŠeLù÷»ÒM±ÙlfÞs™òÎ{¬üíWމã÷­›¥×¢¿ìß V÷æ$¬V+ï¼5‘ž½úà¬uaÜ›“8|ðÉÉ×*TF×®%I wþñ; 7aÜ›“ÈHOç“ÿ}Èë&–º\ÏÞе{f¼?ÿûhŽ´¿¹¹9Ø··Ì¤{ÏÞ9|ˆ–­Úàéé @›È( }™LF÷ž½î:Ãîídfd —É÷æ$öïeýÚÕ<Öo¯½>«ÕJNv6ÿûà¿L˜4•<õ,S'Ž—–õôôâ£ÿ!ª]{ƽ9‰ÿ{3Šc¾.}±»éÒí!6oXGFFº]ÙÍwèÀ~ÜÜ݉;tˆ“'ŽÓ¹[w‚CBxïíÉô4‹Å¸7míŒéï2åßïñǶ­Œ{s©×¯3òÇ|þé¦Ïüˆþƒ†°ø§…\8w–ßÎcÒÛ¶ãðÁ¬^ñçÏå©gŸÃÍ݃ÁÀ†uk[Å¢àÈ჌}c —/qáü9iÛEǘ––Êü¯¿d¤)|þÉZD´ÂÓÓ«r?ä ÙYYüst ®nnü÷Ý%2% B¢×P¿~½Ó==ÝEá‚ ²\I¸ŒL.§n½ ÛΗp‰Ó'OJ¯år9...vó¨ÕÔ NÎÎ8kµÒô¡O<‰‹‹+½µÆ‘ÆMšIïk4är9-#Z1ý©´j‰\.Çd2IË*”JÌ·ÒðñaOáââŠÕjE¯×c2™P©T¸¸¸Ò­{OÖ­^Y¡2úrþ‚[¶ó4†Â‚B †ÒÓáäçóÃ÷ó¹x³oÂÙ3§ËµÍ ëÖ°ëÏœ=sš Á<ÜçQpttB&“Ier¯<½¼x¸Ï£7ÏŸ.¤«‰|þéLF#z½¿›C7;99¡R©ì®«ÅÂãÞ¸í“ýúÁ!øøþUSQ¼ì—E?òòèŒ[­KÑñéõzÌf3J¥Ršf2ÁjÅŠW\\\éбMš6£UëHiÿ, ©©©Òu•——Ç?ž|ƒA³³VZç£}û³får–/û…èÎ]¥Z‹KãY»j —.¶¦v¶u+4ô \\\yþÅQ¸ººUú‡\åàÀ'_Ì“^[,ñÍ'‚ Âý€$^I`õŠßxíõñÈd2iz½ ú$^I ^P}éÆÿàþ}äååbÅŠL&Çl6“••…^_ˆ./O 8Ôj5ù:‰W¸pþ\©Ûurr¢ud[»i‹…BÉ[ÓÞ`ÖÌÿb6™P©ÈʺqóÆÓ„B¡D£q”¦ÉŠ2ƒ•J…./¬¬Ä:xÇÎÝâÏ”h2ôòÈgyÆGR•¥‹fÀà!äææ Ñhl7¶¹¹èõz²²nàêêFBÂeT*oM{Ÿ çÎ1}ÚTi³²nðë/‹!+s_}‚kIWiÑ ·b}6T*ù:YY7øcÛV }€åË~aÈÃîxλõx˜?~ßÊC=.sžŸ\Àk¯ÇÙÙ™¥‹&=-íæÍ»ý1ÞZSÄ*ŠŽqÉ"é½â5bRàéèȦõk ªß€ãÇŽØšÉlƒ_£# ¥£Ñ(MS98 “ÉÉddeÝ íúuöÆîàô©“>x€°0Ìf3r…?&L²5•S*”h]\ˆ;|œœldr½C÷0ä‰'Ñåå1q\ cÆOD.—ÓoÀ žy~$ÎÎÚÇP§Ì²öôp~]²ˆ^<Êöm[èÕç‘ÛžŸµ«Wp-)‰—_ýF£‘5+—Ó£WoéÚ)’‘žŽ››»]@pùR¼T#)‚ ‚P™½{÷~·¬7/\¸À!ƒ‘ˬÈåVd2ÈÎѡҸ¡ÕþUk±wÏnžþ¼]ð¶‰û÷Ò2¢µtƒÕ"¢õx³ÑLó–-ÉHOgÞ—ŸáèèDzzÍoöiÙª5kV.çäñc {z8XÁÏßíÍÚ‹ÕZjS/™LF¾.%?ÿÈ}{y¬_êÕo@XxC¾ýúKìÛKƒà`ºvëNÇNùdöGØ·—ƒ†™‘¯¿?uë¡VÛ«ÕJ‡{sôHׯÅÛÇ—V­#ËlfàááÉú5«J4‹:~ìí:DãääÄöm[èÝ™_ýÄ¥‹x}¼­ùÕ¢Ÿ~Àb±p`ß^"£ÚQ'0”ädV¯XŽ\.£K·î„…7ÄÃÓÅ?-$ª]®§¤Ð!ºS©ûâàà@§.ÝkØH ‚CB‰;t€Më×ñÒ?G#“ÉÈÍÍeãºÕ yâIÅnRKãééÅÚÕ+èÔ¥[‰óaµZqssgààÇ™÷Å\bwï¢Kׇ¨S‡ú ‚Yòó˜ÍfìÛKë6‘¨5šRϧ—·7‹þ@Ûví¹–tµÌff]ºu'ñJO>3œ+ —ú'iÕ:’•Ë—±cûïØ·—©ÓÞ§^P}Î=Ãú5«9°o/£^ýÞÞ>(J~]²ˆ´´TúBXxCŽ>ˆƒÚMÖÓ¤YsÚuèHÛvíùìãÙØ·—kIW‰h݆Ž:óݼ¯Ø³ëON?úÿíÝkl[õÇñŸíû8>Nb;Í¥¥J›F×v©ÜöfÒTn›41·q0ÓØÓÆXH UÐ!¶!61º 1¶el¬@K0­QèچХMãšØqb;±ÏÙ ¯! ¸%ICòýH–b;ç8~|t¬'ÿó<6\qµäºjœ;Wgœu޾ôåuz¥e»V¯9MÉdŸžþýSzýÕVÕ74*‹K®;â¸OCccé¸^wÞ:iIÓÇþ~w¢X¸ºlùÉòz½J&ûôäožÐ믶ê¯\¤†Æ¹’¤¿>ûŒ>·bňccÛ‹[eÛ}~ÕjÎÀ$I%+*žg{{û”ËåÆìzeY• *亮\ÇPR{îy-ù„sLgž7ºã=ÙÜܬÇÿ•¼G^Ÿ#ájGBÁȼ²'¡§Óý#’•Ùâ“Þ÷·ßª;~pwiåãhÝÿ³{´`á"e2UUWk݇Šÿ•ã8Êf³ã÷OõgûÀÆŸjþ‚…Êå² UVêü /š²Ï¯œBü™zœ Ȳ¬QÿP0qìß«†¸)IjkkW2™R$2ú’ØXlŽªªÂrœ‚ Ã^uܯ›¿{»Î=ïB‚à3kÒ'¡ÏÆä£œ÷}å5×Ë4ÍcÞÿÅ—nPû»ûdšZ½fb:†Qvò1ŸíÅ—nлm{å÷›úÂi§OéçwÝ7ÍÚã4 qfÓ;ééNèí]oÉ0 -YÚT*6ÎË÷‘kËËU(dƤüöµÖÕÕ7ê„ùóÕü—?é̳¿¨æ??«¯}ýâ) üü ?Õöuõõª«¯ŸÑ眺:Í©«;.¯½pщœ&Á„ "L¥RÚýö.ýçw”L&Kßñ¡V«Gë—>rԟʵoß^}ðA± úÍ;”ÍdõZk G0É&ddþ‚…ºä²Ë%O±…n__¯~|×zyûKºíæuÉe—kÅÊUzâ×éÿ.msÕ5×ëåí/©ùÿ³¢±˜®øæuzååmúã–ß©µe»,X¤ïýðdR>²I‡:J*vŸ:÷üõúÖ5WªvÎeµxÉR]}íõzö™§µí…­’$WÅâ\Iºö†ï¨2\Yš`š' >ŸoDŸªªjÝ{ÿƒ£ y·¿ôb©éc¿xX½½‡Õ²}[ivC&3(Ã0tÁú¯ª§»[gœuŽš–-÷u;;*lÛ:}±8y –$õ÷§t߃?W0héŽÛnQ>_ж¶–þ–»¾{iv¤8w¡ºº†£ø,$ åJtÒ?ÿñœ¤â ˆmGt÷oÒSOþ¶˜@ ¤µîÜ ÆÊÚ_Ó²å#ö™Ïë”SWhÞ¼ Ž_L}ÒRÚǃ1™;ÆâÚ¼é!ÝwïO$IkÏ<[II+W­– éé?l)=æ‘GGz/?ù=ÿ\³6=ø€¶>ÿ÷Ò>¯Úð Ýó£âåRtè_¯µ–¶—;þß²pщڼé!mÞô¶|h°€©3©s@Rɤ‰.ÕÕ7(«?•RW×!IRMM¢±¸†r9íßÿž¤bûÏ#Ò$iÿ{írgDG¢®Cò›fi•$ÑÕ¥TªXøÞ8wž,ËROw·âµµ’¤žžnÅbqe38Ð!IŠ×Ö*ó > 怘Í&õ,;)ÕXHRض¶Gž`ÍŠ ´dé˜ÛÕª¶®¾aÄý±ZµI>$)/þ´¬q_À H@À'‹Fk‹® C’ ÀŒbŽ/ÛŽ(2GÜ,˧;w3+ L #K2]Wr‡° +•Jé­·Þõxee„à Ëu­\¹jÔã–U)‰U$ `™¦_ápà#I‰«¶¶v-^<Ÿ˜Q(Bà8ëí=,×õÈuÝÒmÏž}ŠÅj0±r¹¬2¥ûƒƒårC ˜ÝÝ]òzý’¤D¢[–$(f$j@˜ÇÑáýòû½–×ë%(H@$Éï÷©÷ƒ„òCƒD€cà:yIfé¾iV(*—R{û!UUEä÷ûäóù †º(Q`‚¾~ãñ˜K–*~Ï64ŒøÍB!G¸ÌîLÛK’òù,Á@2–ÎÎ. "À§ÖPh€¤;v¼¡x?\z.*¯%HH@Êaš¦¢Ñâ`¤P(¬HÄ–eÔÒÒª¦¦åŠF#rVH³ÛîÝ»´fÍé²,Ÿç¥ÓêéIH’,«R¡P%õH@ÊGT]]%¿¿8FÄu" À8 Õm[ªªZ¢÷ß_…ß›fñ9ñh7,™¦¿”|€ò8ΰ‚Á %ÝÀ¬uÔ+ Ùì :::ÔÑ!-]ºX~¿_‡Hð1†††tà@§òù‚"›€ 9GºvìÚµ[¶V,Fá9ãikkWZáp¥¼^C>]ð€”Íï7K®ª«£r]WÙl^’O–U©7ßÜ­ÁA¦¤f·PÈV Ôž={USS3¢K¤ir­Y³Ráðè¥ãúúb;ÁSO]FT$¹jjZ<æ3Ž3Dx€|ü)TòH …,9NžÈ0e¨µ0 'oˆ¦&5éêü¯L¿—Hpœ¥û“ÀÌN@lÛÖÍ·Ü*¯—™LÌ00£µk×!†¥ $ H@€Àô÷?O¬¼NÙ_SIEND®B`‚snd-16.1/pix/smoothsq.png0000644000076400007640000004265611147553270013540 0ustar bilbil‰PNG  IHDR„ÔÄ(íQsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ 2jÀ(é IDATxÚíÝy\Mùÿð—ö¡"-’µl “m,Yg0ömÌ f†Pˆadc Ã5vÂX'kÑ`1?²erm‘¥nÝ6EÑžt˜î×Õv«Ûí.¯çãáñйëy}>÷Üó¾çœÏ§ŠD"‘€ˆˆˆˆˆˆ´Ž# """""bAX¨ÈÈÈŸ$55W¯^Ell,%"…ËÉÉ‘kûŽ«W¯20"ªòìåääàêÕ«rÝ—ˆHå ÂÛ·oã»ï¾+ö 222°ÿ~ÄÄÄàÀHIIaªD¤0ÙÙÙX¿~=þøã”´½ BLL öíÛ‡·oß2<"Rh18lذ·WûöíCLL X‘z„B¡wîܳ³s±Oggg >³gÏÆ’%Kdn—H$…þ#"’Ç®]»ðñÇ—x¿ßÿ“&MÂðáј˜ˆ¸¸¸·CÜ‘|8<<<°aÃî‘ÊÓ+êggg8;;ãöíÛe~ò””,[¶LfYjj*|||¸$"¹Lž<b±B¡°ÌÏqòäIüóÏ?2Ë.^¼ˆ®]»B 0d"*–½½=ÜÝÝáééY®çùᇠ,[»v-¢££akkË ‰Hµ BE¨Q£Ö¬Y#³L,ÃÇLJÉ‘Ò 8”YVÞ;"¢ÒúpŸ(¿ $"ªLEž2š””„+W® 66W®\ADD„ô6///>yyy€jժɜ~ÕµkWØÛÛ#>>“&M‚Ã#"…xóæÌ>ÑûèuïÞÝ»w˜ššbìØ±ˆG›6mЪU+†GD*¯Š²'¦‹Å°³³ã5„DT©òOå5„DT©;bUª¨å5„yyyذa¢¢¢Ô¾ êÕ«èèpznM#‘HM›6iÄúŒ=mÚ´Qøó걫‘¼BBB0uêTŒ3F#~TÛ´i:vìˆÍ›7KÏ€#Í0uêT¼zõ sçÎUû#ö"‘[·nÅ… 0{öl…>·VýŠC‡!##Cm×!##‡Bhh(?ååC‡!::Z­×# @#ÖC“$%%±=þÛæ³È÷èÑ#µþþ¥ÿõå)S¦àСC˜6mšF¬Ó´iÓpèÐ!L™2…ŸU âææ†:uê`×®]qú¶½½=–/_SSS|ùå— ÝžjMAøüùsôë×b±3f̹&R„„„ÀËË S§Nŵk×øi/‡ƒbåÊ•˜8q"bbbÔrbbb0oÞ<}ú`öìÙ8}ú4îÝ»§–âµk×bþüù1b¯}*‡×¯_ÃÇǾ¾¾¨_¿>¶mÛ¦–ë±mÛ6téÒƒFBB^¿~ÍÆ%"¢ ±zõjkÌ‘ÁM›6 ÆÆÆX½z5[½xñŸ~ú)NŸ>­±#Žÿõ×_pww—ñ˜¡îÞ½+=\¿&Ë?óQßµZ9ኑ‘ ++KmÞóùóç½zõ’.=z4~ýõW~úË 55Õ«W—þÝ AÄÄĨͅäÙÙÙˆ‰‰Aƒ ¤ËªW¯Ž}ûö±qU¯ç¤÷¥§§#//O«3àöI}?™™™hß¾½V¬oþ¾Vþ¾©_ý£GÖšõ1cÖ­[Ç‚P/_¾Ä¸qãd–7»ví*õsEEE•ëWÞììlDDDàÕ«W¥z\rr2 fÍš2Ë9´}Ù˜™™AWWWú÷´iÓàçç‡ÄÄÄR=ÏóçÏQ®÷çÏŸ—ê1‰‰‰ðóóÓØ û‰ˆHuŒ9RkÖ·fÍš¨U«žúè#¹×¨"9rÆ cDjîæÍ›øôÓOµætѲî'Rå»pá‚VNÒ£G\¸paYÔ«WõêÕ“k´ÑŒŒ ¬Y³Ó§O‡™™êÕ«‡]»vaýúõr¿Þo¿ý†øøxüôÓOÞ]°œžž.W>|ø–––°´´”YžÔ³´G:©üöìÙƒ6mÚHÛàäÉ“X¼x±ÜGŽ“’’°{÷nÌž=[Ú–mÚ´Áž={®ˆŠŠÂgŸ}¦µ?ÖDEEÁÞÞžá=ŽŽŽ ÓÚõÿ÷ß9ššº|ùr¹OGÓôýDR Ú:"AÒø‚°°ÁXò5lØOŸ>-ñ9nÞ¼‰ððp|ýõ×2 ×ãwóÅÍ™3úúúÒe£GÆþýûK|ìéӧѨQ#4jÔˆŸö ôÕW_áîÝ»%Øb±pss“.«Zµ*ÜÝÝåþeêÌ™3ÈËËCß¾}¥ËÜÜܱX\ìcóßãW_}ÅFSQׯ_‡··7Nœ8¡µëß®];v„÷ôíÛW®\ÑÊÁ†0mÚ4­èA“­¿03g΄@ `'Pû÷ïG«V­´îÔf¨]»6¾þúër .£´‚P$áéÓ§‰DJ ©¨ÁX`êԩؼys±ÏÊÊÂÚµkáåå%³ÜÀÀÍš5Ê+››[ìsøúú¢M›6øè£d–8=*qþ¤¤$˜››óÓ®IIIÀøñã ÜV§N¤¥¥!--­Øç8|ø0š7oŽæÍ›Ë,ÿâ‹/ ‹qåÊ•bŸ––†-[¶`îܹ2ËóŸóðáÃ%>>-- uêÔ)pÛøñãñêÕ«û¤¶JKKÃÓ§OñôéÓ ÿÅÛÒÒyyyxúô)´&ã§OŸ">>M›6e‡û@ûöíáíí­ôïÁʃS§N•ú”zmÈ%[¤êÄb1ììì´²ìììJü‘–TÃóçÏabb­[wÔ®]»\Mê)ëÍ^¼xiiiHIIQ©uuu‘›› =½Â£ Ehh( Üæåå}}},\¸õë×/ôñ)))ذa6oÞ ccc™Û6lˆîÝ»cÇŽ®{ߊ+Šlä¡C‡r翲²²ðôéS´hÑ¢ÐÛ‡ †cÇŽ¡cÇŽE>ÇÑ£G ÝÓÚÚC‡ETT:uêTäãOž< ]]]™£ƒï·ç¦M›Šý5öرcE^›Õ¢E øúúâ矆­­-üñññ8{ö, 22ÎÎÎúz^^^ؼy3ÒÓÓ/]îíí­1™Þ½{Wfç† bܸq055e‡û@ß¾}ѺuküñÇ2E¡››êÕ«§ëøêÕ+¬\¹Rú·  $=«†Þ¹víšÌ6AU;v =zô@5´²jÔ¨=zàØ±c:t(;® +jßL[ 6 S§NEJJJ™>¯J+¿ùæï~iZ°`J„gkk Ì™3§ÈS.\¸€ž={ù«W¯Æœ9sàççWèíiii …E:u*×!ÞN:aäÈ‘øòË/¹5P€’Úãï¿ÿFNNN¡Åœ¼íQ\éÛ·/þþûï"ûÝ•+W´öôòzÿÔkeý2?uêÔËæÍ›'ýjjªôZÿÿþ[¥ó›:u*ªU«&³¬eË–<¥ª¬¬¬0}út™e[·nETT€w—(8::âõë×*TmðàÁÒÁÍò™™™±?ȹó–O•wb/_¾ ggg­ýÇÔÔÎÎθ|ù2 BwåÊ:tH«÷_…B!ÒÒÒT» TG"‘ÅNþ>yòdlܸ!!!pqq)pû¢E‹°dÉ’"?pà@¬[·8p`¡ŸÞÅÅ...ضm&Ož\àömÛ¶IïS333tîÜ…„ùG8`‡ú í[·žž^èéá˜0aààÁƒ*½.›7o.p \HHBBB```€-ZÀÉÉ ü1¾III8sæ €w­|h„ xøð!°víZ•^—'N(çùóçðôôðîŒtéÒ…Û,5”‘‘°°0Œ3F«spqq)ÓTc¤<·nÝ‚““ªV­Ê0ÊHã B@€Y³fyû¬Y³Ð¦MÌ;·À5Y7nÜ€bG066†‡‡>|X`'ÿÎ;–9}æC†††hذ!îß¿_hA˜––cccÎç¥$ùm}ãÆ;0 Ø¿¡;qùôõõ1wî\ >¼Ð‚pÙ²e8räˆÌàBŠî“¤:ž}Z«søê«¯0sæÌB¿“I5ìß¿}úôA­Zµ´:OOO¬]»¶Lgj|•!‹‹ ÒÆÆyyyxóæMÛvîÜYèà#9r$ F²qãFŒ5 µk×.±}}} \_™””|÷Ýwü´+ÈÎ;KÌÓÂÂIII–ÇÅÅ!//¯Ä Oáââ‚;whÏôôô"¯7ý°OÆÅŸ-)) ezÿ¤\ñññðññÁĉѺuk4iÒD£×W__­[·ÆW_}…æÍ›ãúõëì8sæ Ú·o/HXÓµhÑ­[·ÆÀUþè7ý}BïŽ|¶ŸH쫪ÄÖÖ111ez,;áÝÀG•Y–››‹°°0é>>Xµj•Ü#«õìÙS:gb¾¹sç–8¯]ûöíÑ»woéëRùÙØØÀÆÆF&Óëׯãúõëðððë9:uê øûûüýýaaaQìè£ïóðð¾f¾7nHß©G?’·¿©š’¦PÒ&:u*0U©†ôôt…BQľ# ÂR~Ðk×®-å xw„féÒ¥r?G½zõpøðaìÞ½žžžpttDÛ¶må~|~A™árbb"áääTâc_½zÅ ·Õ«WC‡Åúõë¥ËŠ4¨8'OžÄýû÷áéé‰û÷ïãäÉ“¥züÒ¥K±hÑ"™/ç¡C‡jÌðôš,$$¤TŸM4hРB§ëÑVaaahÖ¬™Ö®ÿÒ¥Kå:ˆˆ”O£•‰ŽŽ†™™Y‘#B¾oÆŒرc:v숵k×bÈ!hРA©^ÏÎÎ[¶l)Ó{­U«¦M›†U«Vaß¾}8sæ ªT©‚>}ú°—V‚qãÆáã?Æ“'OP½zuŒÃ‡cÿþýìÙŠþDOO®ùY,--áææ†Ñ£GcêÔ©˜:u*\]]•ú^kÔ¨©S§bùòå=z4vîÜ KKK6"U¨ôôt¤§§ó;ç?ÇǃðàÁ†¡bbbbx)͵ÄÖ­[K¿ÌèþgÛ¶mÆ'Ÿ|Riïá—_~ÁÞ½{ñé§Ÿrxc{öìbcc1nÜ8¹î?oÞ<|þùçhРA¥MÊûõ×_£víÚ¨S§ŽÜ§›éééI/*æt%DDD¤©ªT©¢õgä(÷?P™Å`¾1cư¬ xúôi©ÓªU«J+óõîÝ­Zµ’ûþîîîe¾¨˜ˆˆèüùóèÝ»7ƒøà»øÃÁÿ¨rÅÄÄàõë×pwwgÿqrr*ÓS„`éÒ¥¸yó&ƒ ""¢r;}ú4úöíË ÞÃétTOTTîÝ»Ç ÞÓ¢E $$$HG¹gA¨ELLL8é/‘–ËÍÍENN Â÷Õ®]›=ƒˆˆˆH©©©°··GçÎÆ{ªU«&͇TÃŽ;0aÂñKKK<þœa¾Ã‡ãÇdÏ """’Ù3g ‰P·n]†ñžüiÀΜ9Ã0T„¶ÏïZ”ü+W®dA˜ïêÕ«ì$ƒÉiIAHô¾ hÍEòíÚµcƒQ™´mÛ–!J‹ŒŒÔ¯_Ÿa° $’_ff¦Ö¬ë¨Q£°fÍ6:•Êš5k0jÔ(QˆÙ³g#<<œA¨€üÑõùãEAfff033CTT”ÜQÚLŽK–,AJJ ÒÒÒØR faa!C†`ûöí˜8q"!@\\Cø€P(Äž={—.]‚««+C¡ Çm3}hÆ Ò#ª&66– T„ºuëbúôé˜?>à •Õ¬Y34kÖ GÅÌ™3U« \´h@,cûöíl-222BýúõÆ0ˆŠáìì @ðôôd ¤aaaprrb$åáá!ýÿºuëU*ž2JDDDD¸vílmmakkË0H¥ýõ×_(¡|š7oŽªU«²•‰ˆˆˆJpõêUØÙÙÁÎÎŽa¢mÛ¶hÛ¶-¶lÙÂ0*Ù™3g¤SPAË—/Ç7XþòË/øôÓOQ«V-ö ""ªTYYY044dDjLOOzzzÈÎÎf¤ÒŒqèÐ!„PƒÞ÷úõkØÛÛ£K—. ƒˆ”.11––– ‚ˆHªW¯Î³ˆ×’V8{ö,D"¬¬¬´b}]\\!!!l|""’‹ŸŸFŽÉ Šahhˆ¬¬,Q‰Î;‡víÚÁÙÙ™a¡J•*000`AH¤Í ƒˆˆäríÚ5tèÐAÃÛÛ^^^ ¢Ý»wééé ¢666˜:u*þúë/„ÚdÅŠü€€wƒï° Ô"FFF8wî’““± $"""¢’ÅÇÇcèС°°°`ÅÐÓÓƒ¹¹9ƒ¨ä¾úý÷ß3ˆ”fÜ ,óòò““###ö"""¢¬^½öööÜw’c'{ìØ±øã?F%öUGGGQ‚9sæÈ}ö ž&‹Í›7C"‘°7‘B]¿~_|ñƒ •–?¾HÍš5‹½O%­Ñ¾}{†@DDDDÄ‚´ÍªU«´nn%GGG<|øODDro©²‡¢~ýú<µ™!Qé%$$hÝ:Oœ8>>>l|""*Vbb"Ž;Æ:ä4iÒ$;v ‰‰‰ CÉ|||0dÈ~TоÇ‚P›Œ5 ™™™ ‚ˆˆˆä– ‘HÄ äÔ´iSˆD"dgg3 Rù¾úË/¿° Ô&íÚµÃüùóÉ…!‘–RÚ´AAAÈÊÊâùÖDTiâãã ˆŒŒDýúõ )ÝÕ«W‘’’¢2ï',, sçÎeÔ‚““C¨„ïð={ö ,,ŒaÈ©~ýúÒýžâ(í¡žžôõõ¡¯¯_ᯋɓ'³‘Œ*UªH·C::4lØaJ ÆêÕ« B"*-}}}=z”AQÿþû/ M›6 £ úöí {{{ÄÆÆ2Œ vôèQèéñÄÆ²jÞ¼9î߿ςP[L™2111 ‚ˆˆˆ¨™ššB$ñLRyãÇ/v$„¦Q£F ‚ˆˆˆˆˆJÄ‚ˆˆˆˆˆHK)ídÜ={ö -- )))Lˆ*Å“'OpöìY€P(„³³3C!"¥;zô(âããUâ½têÔ‰ B*ÿÝmooaÆ1 u/»uë†ÜÜÜ ßÞ¿óçÏgËQVVVèÓ§€ÿ ¦@D¤l:t@VVV¥¿+V`Ë–-lrðòòÂÍ›71bĆQABCC!‰ £Ã˪V­Z¨U«ž>}Zè¨ÂJKÖÞÞ 6„½½}…¾Ž¯¯/ÌÍÍÙòDT€©©)6lˆ† ÂÌÌŒQ¥°±±‘n‹*SRR£œÌÍÍáëëË H¥5mÚM›6E@@@¡·³Ô&WµjUþªDDDDDÄ‚´Í©S§0iÒ$X[[3 """""„¤M.\¸ ÕëoccƒéÓ§ãòåËì DD$£Q£F°²²b¤Ò._¾ŒÕ«W3„DTUªTŽŽŽ;Æ0Hé¾ûî;^[C¤¢|}}Q·n]8880ŒrhÓ¦ ºwïŽ'Ož0Œ rìØ1èêê2ˆrjÙ²%î޽˂PtïÞöööHNNfDT©ÌÌÌðêÕ+A¤‚^½z…ÜÜ\QN†††ÈÊÊÂÉ“'©´qãÆàÂ# IDATa×®],µ……D"Ο?Ï0ˆˆˆˆˆ¨X,‰ˆˆˆˆˆX‘¶èÒ¥ C •׸qcÔ­[—A° ”OLL ìííѯ_?¶,Q%ªU«^¾|É ˆTÔ²eË0dÈ¡-[¶Ä;wDعs'¬¬¬P¿~}†QNÆÆÆhÔ¨Q¡ËhTA ‘H¶:Q%jÚ´)=zÄ ˆT°QœqãÆa÷îÝ ¢¼~ýšƒ)ˆ¹¹9 PèÀ2DD› æADDDD,‰´•¿¿?C "Òr·oßæÙ3¤ò233ξʂʪZµj077gDDD$ã÷ßçõõdúôéX¿~=ƒP€/^ 00}µŒ5 ÷îÝý{÷Xj²-ZÀÙÙ§NbDDDDJ`oo‘HÄ H¥Õ­[©©©HMMeA¨éòç""""""* B""""""„êÏÎÎlU"ªT§NBÿþý©”/^àÅ‹hÒ¤ à •ŠŸ~ú‰A° ,ƒ¢Aƒhܸ1[•ˆ*Uff&Œ©”ððp„‡‡ãóÏ?gàË/¿„®®®ÌµYT6{÷î…™™ƒ¨ 2“ÓkLAœœ¶0Iéêê¢Zµj ‚ˆˆˆ*œ••._¾,3z#‘*rwwÇÆ5¯ $z_dd$0a† J•* ˆˆˆˆ `AH)..Ž£¬¾gÆŒÈÈÈ@ll,à """ÒrݺucAH¤m„B!çG""Òb¡¡¡hݺ5ƒ •–””„¤¤$4mÚ”aT ° Ôt ˆˆˆ¤öíÛ‡1cÆ0ˆ Ô ADDD0ˆrxüø1?~Œ~ýú1Œ baa¤¤$„šÎÝÝ»víbDDDDJ2mÚ4lÚ´‰AJëÞ½;‚‚‚¤ë)ë…—,Y‚””¤¥¥±”äîÝ» è=B¡{öì\ºt ®®® …ˆ”nÆ 2C¾U&¥„‹-ˆÅbl߾ɑÒ9;;C <==U éÿ×­[Ç@ˆHézôè!ý¿F2Ú¦M¶.Q A¤D±±±°¶¶f¤,,,P¯^=A*-44”ûôJпÍ+×­[‡Ñ£G³u‰Š`dd}}}A¤DyyyÐÕÕeTéΟ?ÌÌL´oßžaT ^½zÁÞÞ^fÀ*}ûöqŸ^É4¦ ŒŽŽfk’ sss†@DD 99ééé ¢‚Õ¬Y"‘HfÀ"„D•àøñã˜?>ƒxÿD ˆˆˆˆˆ!i¶Ë—/3„´oß×®]cDJvᙋ÷‰ˆˆXi‰S§NÉ\¼OTY8P©º¨¨(ØÛÛcÀ€ ƒ!•WíÚµñõ×_ãéÓ§ ƒˆˆHË­[·_ý5ƒP‚™3grÿ«Œ®_¿‘H###†Á‚ÊËÀÀµkׯæÍ›‘–ãà{ÊckkËý/bAHD*øa×ÑŽ?òDDDDô?zŒ€H; 6Œ!‘ 9\àä䄪U«²E‰ˆˆˆÞKKKXZZ2 Ri·nÝÂÏ?ÿÌ X–ž@ @Ÿ>}P«V-¶(Ñ{Μ9ƒF¡Q£F C Zµj…V­Zaÿþý £”öïßSSSÁ‚°ôÄb1[’¤ÒÒÒ`ooN:1 """R*˜˜˜àùóç ƒXU†Ó§OC$ÁÚÚša± $""""""„ZÄÅÅ…!i¹,]º”ApL¥=xð½zõBÛ¶m BR”¯¾ú ûöíCBBà ""ÒR€‰‰ ƒPò>ØÚµkD)œ={éééÐÓã¬xʦ´Ä—,Y‚””¤¥¥1u%JLLÄ›7o¡Pˆ={ö.]ºWWW†BDJ·aÃDFF2 Èáû-Zà݈ Û·ogòD¤tÎÎÎOOOBD•ÂÃÃCúÿuëÖ1"ªTsÊhïÞ½ÙšDDDDDjªW¯^ aéÅÆÆbëÖ­èÛ·/[“ˆˆH…µmÛ7oÞdJ´páB¸¹¹q*&%³¶¶†››û{),X°ýúõc,K///YYYlI’Ѹqc†@D¤bôôô››Ë ”(==FFFÐÑá8‚JÝÁÖÑ‘‘<È0䔑‘ÁX)ÆŽ;0yòdADDDDÄ‚´Íƒ‘ŠÑÓÓã¨×•ÄÀÀ€!ÊÓ××G•*UDelŸfã`;DD¤ ÜÝÝagg‡.]º0 %yýú5®_¿Ž+W®0ŒJÚ;wîƒÃ¹sç0mÚ4ØØØ0ŒJÀ#„®oß¾X°`ƒ ""Ò‚088˜ATâ>ØÖ­[Ë0Jpúôi†À‚*/Ò%"""R¾¬¬,äåå1bAHDDDDDD,.;;#FŒ`KqI¥";;›A#99çÏŸÇÈ‘# ²™7o:vìÈ–$"""â>’JñööƼyóD1ÒÓÓq÷î]tèÐa° $*¿û÷ï£wïÞhÛ¶-à """"bAHÚ䯿þBZZôô8£  B-W«V-èëë3"""-’™™ CCC 2„ap?L¥ùøøàûï¿g,©¢|óÍ7‹Åxöìà ""Ò·o߯ŋQ¿~}†Áý0•öðáC8::2„T‘ž={†„„ADDDÄý0"„DDDDDD(mäK—.!++ III {Δ”ÀرcÙ’DT¢øøx…B€H$‚½½=C!"¥»~ýºt¦¢>> ¢ÈÈÈà¾|%SÚBWWW€X,fêTaþøã9r„AP‘?äï ={–Q¥hß¾=C "•ÁkI£\¿~!± ¤|:t`¡DDD¤%Ž?œƒPE888"""Ƽ¼¼àííÍ XRE9r$üüü‘ÈÍÍèéé1 àââ aÈÎΆ¡¡!ƒ`AHDDDDDD,K)33£Fb+½·ôÅ_0bllŒÌÌLñž›7oÚ¶mË0X–Ý‚ Ю];¶"‘ ª^½:^½zÅ ˆ”lþüùÜ?R1Ë–-ÃüùóÄ{"##õë×g,‰cÞ¼y˜6mlll‘Š„¯_¿fDDD,K'''±U*Yhh(&OžŒÓ§O#++«RÞC||<úöí‹_ýUîÇdggC__UªTa#‘VŠˆˆ@Íš5Q³fM†¡BjÖ¬‰ºuë2ˆöý ÂwîܹƒqãÆaãÆðööÆßÿÍ–Q ®]»þùçŸ‘… ÂÒÒÁÁÁðòòBFF†Òßó”)S0lØ0ܾ}›6mb#Éáĉptt䎶ŠÉo“£G2Œÿlß¾'Nd* ÒÇ#ÎÍÍÅâÅ‹1vìXôêÕ éééX¸p!ºté¶Ô©SPâ}¯]»†ÇãÔ©S€¦M›¢ÿþèÑ£G©^399ù]ÓÓCµjÕJõسgÏÂÊÊ &L@¿~ýаaCŒ?U«Vec©1¼yó†AVÊÊÊBTTƒ •SéGoÞ¼‰›7obÊ”)€AƒüýýK|¬Z´hÁVT  `Ù²eÒ¿—-[† ”ê9NŸ>þýûcóæÍøì³ÏpïÞ½R=~íÚµðòòX[[ÃÍÍ­Ô免DGGÃÎÎŽAøä“O`ff†Ó§OkmÁÁÁøä“OØþ3hÐ œ8q‚AT Ó§O£oß¾ ‚T~ÛhggÇïK„ïÌ›7+W®”YÖ±cG\½zµØÇ?~111prrb+*ÈñãÇC† ‘.kРàÙ³gr=GLL  „   ,X°ÞÞÞÒ"_W¯^…£££ÌÀ0;vÄÝ»w‘žžÎF"•'‹9°Ñ:tè€êÕ«ãܹsZ›Áµk×о}{vRšsçΡwïÞ B­\¹?þø#ƒpýúuØÚÚÂÖÖ–ah{AxæÌäää`àÀ2ˇŽÃ‡ûØÜÜ\äåå±èÎ;prr‚žÞÿÎ$þøãáää„[·nÉõÞÞÞ˜5k–ôtßvíÚaøðáØ½{w‰ÍÊÊÂêիѪU+™aFŒóçÏKOC-L||aÂlݺµÄ×xðà.^¼777™Awww¬X±¢ÄÇ'%%áÆ…¾77·bßCnn.’““Q»vm66UŠØØXÌ™3#FŒ`pttDXX˜Ö­÷õë×Ñ¡Cv€p;]q¶nÝŠáÇÃÒÒ’a¨ }}}XZZ–¸?¦-}õýýEª\•:¨Ìš5kàççW`¹™™ÌÌÌÍRY³faäÈ‘˜>}z¡·geeÁÅÅ5*p[£F ‘HpöìY|öÙgE¾Æ¶mÛЯ_?Ô«WOfyÍš5Ñ AžH(bÏž=€K—.¡gÏže>š“œœŒ¤¤$@ZZ<==1a„B?ÚîÙ³g¸xñ"’’’dF1vppИSÀ³²²d.sX½z5:tè€~ýú±P6l@dd¤BŸS"‘ 77úúú X…éëë#77‰Dk3ÈÉÉžžžÌ‚¤%á¢E‹¼;´}ûö/z¶°°À Aƒ°cÇž~£&&&011Abbb¡¹'&&ûx L™2ÞÞÞðõõ•ùÂ9räˆt  ’ ¾}û(*SRR””Tâ¹ä–––Òðíܹ“§’R‰œ¥ÛOOÏr=WÍš5eFlݺ5¼½½9˜C!>ŒÎ;{Ö‡º322’Ù†-Y²¸té;Àbbb´þÈ€‡‡‡ôÿÅý8^[¶lá jÂÍÍ [¶l‘kÀ=M“˜˜ˆ#GŽàÂ… ì*¤ÒF;wn‰=›˜˜ 33“ÓK(@«V­ÐªU+ìÛ·¯Àm@Ÿ>}P«V­bŸcÖ¬Y8~üx9 W­Z77·BO}Ÿ>ÿüó×8q&&&%ΛԮ];À7Ø ¤’jÖ¬‰””ñžôôt¤¥¥¡S§NZ·î;vDpp0;Á{rrr°iÓ&Qž={†V­Z15иqcÕy»ƒ˜˜­[÷¿ÿþ›€aéyyy8ÇúíÛ·Z}1nY5oÞ÷ïß—Y–’’‚ .`ذar=‡žž|||‡‹/Âß߿ԃB´mÛþù'Ö¯_¶mÛÂÝݽØ!Üß7lذýáÙ³gxöìzôèÁF&""­ãíí ///¡F¼¼¼àíí­UëŠÐÐPŒ7Ž@Ũüðnxüø1[J¾ûî;ØÙÙaÇŽÒeb±¸ÔGZMMM±zõê2¿###¸¸¸À××·Ô511ÁÛ·oÙ˜DDDøßÀl¼&K½4jÔIIIHIIA5´bŸ>} ­Y_u¢òGûôéƒ'OžÈ\|»ÿ~|õÕWl=˜5k–Ú¼ßV­Z¡M›68sæŒtYZZçû"•‘?¤8èèè:%‘¢œ;wJ˜TKïÞ½ajj*m?mÙç,ïߤ¥¡““e¦E¸uë–\ƒÒ,333tîÜYúwþÍï/S2×JüôÓOr JC¤ ... aÿùüóϵzý­­­9ÐÇ{8 œâjýçL]ýüóÏ ÔŠuÍL°eË–lx„eÓ¹sgŽÒ¦ÕªUCÛ¶m1gÎ^Ðܶm[µZÕ«WK׈T›¼#“vpttä€p $ qÿþ}ž5¥¦¬¬¬pÿþ}…B_×;w¢S§Npttdó ,›iÓ¦!((°bÅ Œ?VVVl½2hÑ¢…ôt¶+V`þüùj·¦¦¦°··Ç½{÷¤S’X[[³q‰ˆH«lذ €ƒƒÃPC0`6lØ ÑëùôéSa„ lt„eשS'Ô­[ýõÂØ±caoo½{÷–ë¹?Ü'€   ?XUÔw€"Ÿ£¬ŸUElÃÊ»íTdVd®ª’©"ÖEU2åsȹ-–”`æÌ™–=~üX'‘H$’óçÏK%‰D"‰$ëÖ­“(Ba¯[???Ipp°R^KYï¯,¯,ñóóSÙ”õþ¢££%@)ë$$ÑÑÑ*ûþÔ]aYeggKnܸ!ý{éÒ¥’/^H$‰dåÊ•’„„„ y]míCª¼äv\}¶ãê®°¬D"‘D$I$‰äÎ;___‰D"‘ÄÅÅIV­Z¥”÷PÏQÖϪ"¶aåÝvVT.o®ª’©"ÖEU2åsȧÈk…B!<==qûömxzzÊÌ#òË/¿ гgOäääÀÓÓÇŽÃŒ3RµV¯^]i¿–åµÊò###TøëÀÈÈHesPæûSV011ŽŽN©£££•þl¨ÊQÃåË—ãüùóðôôDJJ ))IæL†É“'cË–-ðôôħŸ~ŠÚµk—ûµËÚFe¡ê}H•·“êðþ¸Wo"‘HfŸè÷ß—Þæëë ___@Ë–-Q¿~}é}¦M›¦ßQAŸElcË²í¬¨þ\Þ¶Q•L±.ª´PÄgF“ž£0U$‰DS6؇†­­-:vì"±XŒÃ‡cæÌ™ ƒ”ÊÓÓ€Aû±O±¯ª<F@DDDDD¤4êaFFtuuahhÈ–%¼}ûéééZwŠ%U¾äädŽHìÄ>Iľªt/^¼XÝÞt||{ö,|ÈÐÊéíÛ·HKK“Ù‰ÈÌÌT‰÷öøñcC  [·næàÍ÷è³g@IDATÑ#4nÜK–,Á‘#GذT©}2''û÷ï‡P(dhj"339992ß3oß¾UÛõÙµkºuë@€àà`<~ü¸Ðû?~\ºW»víçJ' /322PµjU˜››#))©ÈûU¯^ݺuc++ÀÏ?ÿ,ówhh¨Ê¼·èèhésU«V-rñ§Ÿ~’þPàâ₺uë²a©ÌÂÃÃ¥G›6mŠððð" €ñãÇÃÜÜœ¡•S\\¶oß.ý;)) ÑÑÑ*ñÞ’’’¤mÜ´iÓ"wT>þøcôïßÀ»»øá6,UjŸLJJB§NФI†¦&N:…[·nÉ|Ïddd¨íú|˜­\N"‘—.]’Žô$ ±iÓ&tëÖ ³fÍBµjÕıcÇ‘‘Áƒ£k×®*·.ü¡€”Š_XŠãïï4hЃ ÂÆѦM4iÒ...4hìííQ£F \¼xÕ«WÇìÙ³ajjªRë‘––†5kÖ`ñâŨR¥ –*•µµ5CPÃmáÛ·oQµjU8;;cöìÙØ»w/îß¿•+Wâ£>B=  ¸»»kĺÿóÏ?HNN–™vŠÊO-æzñâ…̯îb±AAAlU³··‡«««tØ_gggÔ«W ‘H`ff333\ºtIzÊIDD„ÒÞŸ­­-Äb1€wGóÏ7ÏÌÌ”9+ fff,I!7n,=*ŽÆKo ’öIRœAƒIÿï~„Ê×µkW$''ãöíÛÒyscbb­”÷fnn.= ýñãÇ2G[„B¡tÛøâÅ øúúbÖ¬Y,I%ú$©ç¶ÐÃÃÎÎÎ2ÛB‰DWWW˜™™áĉ8qâ„Ò÷ÉÊ¢I“&ÒÓD?Ü·?räˆôÌ/ƒG-N™2Ë—/‡±±1&Ož,]Žƒ¢{÷îÞÍ]òâÅ âܹsX´h[¼ŒêÖ­‹k×®!!!;wF\\œô‹¦nݺxñâ ðùçŸã£>BBB‚ÒÞÛĉ±cÇDGGÃÃÃCº!IMMÅÚµk1|øpÀÅ‹@º³¸hÑ"Ô¨QƒKeÒ¿øûûÃÓÓ®®®2_PÀ—_~ [[[\ºt þþþÒ‰­ WWWXÈÎÎÆï¿ÿŽB$ÉÞööö‰DpttD—.]®´£š4i‚ŒŒ xzz¢I“&?~¼ô¶üm³³3âââpëÖ-DFF>úè#Œ;–K•Ö'E"Ö¯_/ÝF±OªG±/‰ððáCŒ7"‘"‘:::000€¹¹9¢££Ñ¹sgôíÛaaa*½>ãLJ¯¯/¶nÝŠ±cÇÊüx±víZtíÚÆÆÆ¸xñ"RRRpéÒ%ÀôéÓaooÏ¡5íUœÌÌLœ:u #FŒ€X,ÆÕ«WѱcG¼xñÎÎ΋Å066Fxx8Äb1FŒÁЈHáòj8;;ãÂ… ÈÈÈ@ÿþý! áìì ¡Pˆ&MšàÔ©ShÒ¤‰ôt""MráÂ4iÒ¶¶¶8|ø0lmmѤIdffÂÖÖB¡æææÒý5[[[†F,‰ˆˆˆˆˆHÖÿ!*îùÖAÔIEND®B`‚snd-16.1/pix/samplesviacolormap.png0000644000076400007640000005123511147553270015555 0ustar bilbil‰PNG  IHDR^Ë&÷û^sRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ*¦¥>Q IDATxÚìwx”UÚ‡ïé“ɤ÷„ !¡J¤ˆ"¢à¢¢²E\×^± »²6\»è‡Š½¬E\\@PzB(Ò{^¾?f2™!3!eR€s_W.˜·Í3çœ÷wžóœ&Ùµk£= @@ Úž²²räjÒÓÓDjA;°råj¤" }Â+Bx@¯@ üˆ¼)c6[<Žiµ„„ Óé(/¯$&& ¹¼þ‘F£‘’’2âãc‘H$~5¾ªªšêêÏ$—ÕàZ»ÝNii‘‘˜ÍfŠŠJÃߣ:L&z½Á•>åå!—ËœiZ‚T*qÙÓ^X, ‹]ŸÔ„‡‡µú¹¥¥eX­V¢££Ä[%èt˜L& ÁÁ¾ßI_”••£×Ðh m?á½òÊëéÞ½ëiÇ.gæÌøã,Yò!¯¾úqq1®kŽ9ÆÓO¿Èÿþ·‰£G÷ Ñø51_xa›7ÿáñ²ÇÇÇòÊ+ ½&ü7ÞºußpêT.?þ÷߯ ñ¸677Ÿêê22Z6ÚcÇŽÝ,_þ=/¼ð”ëØÌãŸÿ|ĕޝ½¶˜ÀÀ@æÏŸÛ®ðóÏ¿aõêŸ]Ÿâ¸ýö[HKë~Æ{·mÛIFF‚‚´ νóÎGTTTòüóOŠ·\Ð騶m+W®ö(Ÿ÷Ý÷O>ù]»¦4zïG}Æ/¿l &&Š>XÜ~«V«øòË|ž;vcÇŽjp¼wïž|ùå\~ù5m– O<ñ(cÆŒlö}ݺ¥øüM;vì"3óH‹…·),\¸ C à»ï~ÄÆk\Ÿ—.]Á?®k’ð.Yò!?|¯×á‡óæ=(ÞnÁ9ɃÞͤIWðÜs¯øí™MŠñÚíP[«sý¹sêT£FMà /áäÉšö<;+W®fÔ¨ ®¿>ú ›ÍÖì`0]vY­V·0‡‰n˜ízþ®]û<î7îj† »”uë~õ8>cÆm<öØ“¼ùæ{Œ5»ï~¸Ù6õëׇ°°P~ýuË—Ï!éÒ%€×_›‘#'pÇžbe6[˜7ïItÉÌÌrzÈo²wïëo¹ån¿ƒÁÈßÿ~?o¿ýë»_ye1V«•œœ\FšÀ÷ßÿÄôécÔ¨ |ùå2×½ü£FM`Ú´9 Âÿþ÷«¿gëÖN/âsÖ®]ÏW\ç:wüø Wëäæ›ïô¸¯¦¦F(€ U˜Í³X,Îrj套Þð(o›7ÿqÆç½òÊb~ÿ}›Ç}ååþóxF#×\3Ãõù‡–ºâ"‰‰]ظq ·ÜrF£±I_š}‚o¾Yéáy=úè¶lÙÆˆC›éñ>늻,XðÇ_Àí·ßϳÏþ“ÔÔnÜu—g“þ—_¾ãõ×ßnPÿùÏ;¬\¹šÌÌ#<üð½-ÊàÀ@ r¹œÊÊ*JKKÑjµ¨TJî½÷vn»íf&MºÑã¾Å‹ßeРþ<÷\½7sçþƒM›~jð¾ú-ÔðÓOßú5öìÙÇOÔÇb7múÉ“'6û9/¼ðT“B ¯¼ò,W^y}»eòÈ‘Ãøé§_0 /99ùL™rU“îûê«o=<ÛââRó{÷`íÚõ<óÌ?ünóÀ0}zû¥ÑSO=î]w&N¼œ+~`ùòï=òY h S§þÅ#Æ;kÖínÎäÏïÚ±cÙMzæË//l‘-òŽJ„˜˜hÆŽ­̱cGÒ§OÏs&“/ºèBžþ5NžÌ%77Ÿ .èÓ¤ûz÷îÉèÑÃ]ŸÇ{Þ½ &Œ#""Ì#¼pÿýóxã„zÚ„´´î ôH.W´Ù÷µZx {÷ ¤¤Ôé©IHKs4﫪ª9tè0••Ulß¾‹ääD’“Q©T¤§§Xïí$&&x ¿j*‡ö-¡V«éׯ7ݺ¥™y„²²rW<ÆíÛwqâÄ)jkuìÙ³ßCCCC1›-lݺƒcDz©ªªæ¶ÛnnQfæääÒµk’Çñ“'OqòdUUÕlݺƒŒŒFà‘.ýúõv…t²³O²iÓ À'Ÿ|A©Í¶)%%ÙgÇP™ºáwÛ¶íä™g^düøKG¬Õ}¨Y×®Éde¥²²Š•+䯽Ž^½2ÈËË'''êê¶nÝA÷î݈ˆ#22œ¢¢bïKLŒ?ã°Â×^{‹ääDâ<Ê™@Є‡‡‘”ÔÅã½ËÈèTê(§YYÇ\·uëúõëZí‚zçòÖ[õnM]÷Fv÷Ý·ýëLcIu:^8Èë¹òò –,ùˆˆpNÊÅh4Ñ¿_§ÀäòñÇŸ“”Ô…ÌÌ, ={ö ((ˆèè(¾üräÀƒ„……ѵkr³Ìh4²}û.×38H~~#Gcôè,[öÛ¶íäÀƒ<þøC¨TJÀ¢EK°Ùlètzrrò5ªÞËLNN¤²²’ï¿ÿ µZÅwÌiQ†Ž ¿þº‰‡ºÇãøúõ›øé§_HJêÂéÙ³áôéÓ‹ýûòßÿþÏõ{† H`` C‡æ×_7ñ¯ÍcÀ€~lݺ“ÇÈcÜtS1b(ï¼ó‘ëù]ºÄ3}úõX,6lØÌµ×^ÍÊ•«9pà ƒ `„K]÷^|ñp¾ýv[·îàŠ+.cÈüþûv¾ûîºuKáÀƒ$''Cjj7rsóY³fëûæÍ{°°PL&‰‰ DEE6(gÆ áÇײeËV×}‹=T*æûZ†Õj% ÀÃYÑë ôîÝ“>}zRTTÌ?®u•·ž=Ó‰ˆp8«VýÈŽ»ˆˆçÀƒ\xá 5üüó™;÷–.]áºïÕW"“5>.833 É¡CÛìbu2^¯çê«ÿÊÏ?/‰!4‡ú×_?…¡C5뾕+WŸ9ÔPTTBEE¥ÏóÝ»§œQáÛ‚ÚZ¹¹ù>ÏÇÆFÔ!’•u»Ýû¹  @ââb;Ä®¼¼|jjt^Ï™LFºt‰o“àœ¤ñwRë1ñ«©DEE V«ZdÏ…wíÚõüò˯>Ï/Zô¼×™LmͱcÙ¼úªïY$sæÌdĈa’ÉÏ?ÿšÏ1ɃäÎ;çtˆ]ß|³’Ý»÷z=§T*ý6+G èlüû߯b÷¡¼C† âŽ;niö3{ìÛ#B @ÐŽˆ…РÂ+팼ºº†ßß&RB Úêê$99íbpº@ ´£Ç«Ñø}\@ øFÄx@¯@ œÛ4˜@!‘8´Øn·a4š‰sY{›!‘H‘Jå"7Á9‡ÍfÁn·5.¼Je v» “©–œœ|¬=S°Ù,m§þrZm´È!@pΡӕa4V7.¼Õ¶jjäFl* ²D R»„bE5vŠbV£°ÉDj ¿B &»‰Ýæ}[‹¡ný“㟓;Oò—¸ñ( 2^zé m‘•Jf³ÙÃ¥ %22¹\ŽT*E©Tb6›±Z­Èd2.¾xéé©"Áù-¼fÌí ÷O«5Öb±XXìH$bc+úhµZzôHgëÖ­.1–J¥Œy1YY‡HNND£Ñ‘Ñ‹ãÇQ^^Ftt,ii=›È@p^á—Q J¥’ÒÒ’Fwˆ‰‰£´´'N¸v÷!¼-@£Ñœœ‚NWKDDùù… ®‘ÉdH$϶[·–¯ßk6›1™L^c³Ù¨¬¬<ãu@pÖ ¯VDNÎI Ý»§4½nÝÒ°Ù¬€cëó¢¢âfÁ`àÿøï¾ûn£×-[¶ŒéÓ§óÆoP[[+rX t:Z=x622’âbw/Wâr ÅdÒá>¸_¿Þ•‘Ñ£YÞîÉ“'IJJjôº×_72{ölòóóIM­ï¼;zô(ï½÷^£÷?ðÀDG‹¡m‚6dóç0à*îP3t¹¹”ïÚEÂUWux’T¼ÿ>!7Ý„D~~Œç÷ú+³·esðØÁ†^gµºÔîÓ§¥¥E×j(..vm³Ê™äææ¸®±Z­ÄÅ%4ËР  ®¾újJKK[üc#""˜8q¢×skÖ¬aáÂ…Ìš5K¯ mÙ¾zŽépá­)(`ýßÿÎeŸ}F̘1jKõ_2cœ¯Â! çž¡·bPñ£'°Xädd$c³[êüYŽ9F@@……y^š’’La¡C óéÑ#øxÏ}ÆÂÂÂ[müÉ“'9uêÇ?ã–áuÞ÷¨Q£¼ž;~ü¸Áy…HHÍ#&¡D$`ÕéØsÉX.ûÛÛã•v$Hœ2 ‰‰ÝSØ“°Ù$œ<™íõÁ¹¹ŒãÍšÚ«Õì:g2™)/¯j^X]ÍÊ•+ÑétL:•èèhÞyçž}öYÌf³k›ó &ð /˜˜HXX˜(MA#HDxPµc+üçCxô‰ö54…ÜÜ\‚ƒµX,V¯çÝ=ÜÚÚ* †úÝmkjj9rä=ztmº¡r9Ó¦M@­V0cÆ †ê1Jâ¾ûîcýúõôïߟˆˆQ’Ž2÷Øchÿýo‘”ȇAr-×ÒâŸËèÑ£±Z½ ¯^ïßÅÕ˜4i’DZŒŒ 222<ŽiµÚ× _~ŽÖP ¯½Õᶘt (ÊF/2¦îýÈyµVb‹…W*•qâD6%%E^Ïoß¾‹™3gŠ%èX4P=XBP'°åøNèz|&Ê%GEÆt6b€žmÿ5b=^Áù!¼rJgˆÐ“ q1ì™ \,„W Ú ÓNŠ(„W :À»ü¾ ö~*ÒÁ™W¤‹DÂ+ø™Úb8þsç)èlíþ“&Š2âÆÇÁV4ç¼ù½­9W]]Mii™×sbéÇóœW/…ÛÇtsºL‚<‘+(U ìˆ^£& íÐ=Š®H,{…ðž‰ÒÒªª*(.ö¾ÒXPP(Ùç3‘" :;aázC… 1¤t yŸ~JÜ7"QÂ{fá-%!!ε Eƒ¦TD1„ð ¯ú(’à¡ög°ÜÜiÌ1Kä(cD¾BxÏa²nÌÆœrE8ŸÇüUä‹à¬B'ÓP¦ oóïÂ{® I 8»Ù<°Ãm¨Qh) hûõ¸…ðž#TI‚Y-Ÿ(¢ lå™ý~eÜùµWS)PÅž7¿Uo ©åÊ;Œ¨(ãw‘A`¢¦C¿¿ëk ›œtJÔ„cÇŽr!¼ ÿá'ÖvZûNѹfŒfy‡ÛPn eEÍ_Dá4J0IرSMŽÞÎF{8B¬Ó{2aÃÖ‰l[ÄöN°øajzÁFr1³”­|б•¥-†AXè<íü|E  ÅdÃŒ±C¾[¢‘"QÔï…±ƒ1RÝaiaCн÷æÂÛâŒq°†õÑñ{VU…PC 5(;ÜRÔȨŌ%?Ñ»SäžLvѽÃí(Ä1Ô.)ÆÜ€GO&TTQʾê4D£¸XK%!Nç¡›Û®äíM. TѶ‘ ám•wyœR2;…-G’bRBýÂvötštª$¸ÓØRÆ× $‚?8СvìÄá}WÜ¡x)TŒ)&gAGqœ*ÙC>%ØÎqi:o…733“Q£F¹þž}öÙæ5ÍìŠ)!Ÿ‚¬›ë©±±¾äz“ÎþNR!t6N’H}ØÃ±NaO ZÌõÚ­ q|·5Y¤vxzTs˜ÍDbì€V›U-cÓ+#°#¡†¶"==7ºþæÏŸß¬ûW¹RöÑ—êNSµØe”š¿Í(ØÂp¡²>šÖÔü¸·EG5])áiÝ–Ž1àLJÐ]²ƒE;Uè(ë 8/@Yu§Hâ(ݱw€4Ù¥Ê3ÂØR5œSƶ]=N„Z@©®¡[à fsvœN ˜:AŒ ZÌ&]5Z.¦1~êtNpˆ0¢ùódÇ¿>QžLau,yl'œZ~ïÀþŠ­‡‡p!¬¥J„§…)Hw ïh‚ù•ƶb¢;ðVê‚Y]k&€Ë(@¬ÛàÎá=:™3±—𜱔žjú¾tåXø¸ FdL$„ÕT4ëž)¤‚³g)Z!¼­ €8GÓ(»ã{É•–BžU‰Õ.ÃlPtŠ42¢:ç;JZT)Õ„pŠDNܼVVî¡’ƒXýjOÁkUkÔÍp@L¬§m6Íþ<¥Yׯ³DQc÷o'årL<ÞF=8âhuAx»­ã“1N£4ðru":›†Â£ëa®M½ÌùB‡`±É±vž±³v“Ëy§)?Ía#5|cÒc±ù§ó§ŸŽàG[ó·Ö]ÌA‘rÀOâ4269vsóÞ©©ŽvÿާŸKa›E¼…ð Ú„ÝT/0V ¦leç1Φ¯;Èû`(wÄ„ñfaóo·"CgÐ`óSe?6vè ÊÚ["éU)eC™’æÚ(XVÔüû~£†R#ù·€µL†}OÛŒnÂÛ Šˆ&—‘gGó,°Ê>ÉgG_‘lm>6ð0İ 6W˰ڽ/+·¸ ¾,÷aÚs²d¡Ð©Ž@ì èý'N»àsXÛ3•ð£—î”ãv Q( Øì'9³:Ò·¨6ò…ÇÛ¹ÈqxVdŽw©3P úÒ¬¶N²F¤ÍYˆ;fGžéÑ8òÌ ·l…ªvìŸ)1FRdŒÆÛ\—*)LûªO³Çb•c>¡ƒ? ½Ö§Ɇ=í“&&”XðÞ?Q)‡É½·†Rc Âoq ŸåDoG²Ãíÿe½œb¨8†Ù¨€-À3fmö=DÏ Ø˜ÕˆMQðrVÃÃ_•À;ý_IR÷̯}¤—JË`V£7ùykÊj(®ò=ÜïP9|}ÊÇÉ  ÔOvX¶œámmóµM¾Z?ŠÒ >É0¿?¤´`ß@‹ ŒþôPõ`«’€XÒ±óûþ›úºDÀµHõÕ¯+¼̦Jx/ËÏ£M¨¸¼%Ûq§pû‹x|ï¾hwÚê¥\T …ðÛ[ p (kDäkÎ^~@%‡Û?³ÉóøŠƒ°ü Þ¥ؽ8Õ²û ù9dù©c"_@‚Ô- ¹­?s~€R?.W~2E­|tšli$ýJô°ú”êýdŒd ’4â…î÷qn¿Ÿ Ì!ôUZ,L Oõ‡¹þu¿.R8…ÍÛ2´ùÀv/ÉiðóÈŽrbiD˜¿ñ‘ozçZÀãihû6Ïãå(×û-É-á‘+á§“0,´…Àîø|»*oe³OŸí‚=~ZŠ´|2’}´Œ?9÷4²ZäÎb¸ò3Øë/‘©=CS6×G ¦ª1h±[zÂ…¾´«Ø·­wŒ„·6ùל‚€LÀ›G׫Vnk†‡ÏнÅ$Ãma6Èrd|‰–ív¼cµføìO!¼ƒz¥ÁÀV„)Œøµ“äÒXøK—V<Àìß&lŸ`ÐHú,Ý †Ü3ØSEûvÐýáåXM¯ú* KF?¬ñs·üÿšvaq#ç –ŸÜÀ©]`t°§^xïþ¬Þï˜j‡ãŽŒ/¯…6:Z:3,ËlõO4—ª¢`¬5RØÝÊ'ýgW´âéw9t,‰˜ 8þž&/—Cl,äæ6lúŸ±rj{|Rïø¢¿G®X¶NNäAõ™*¾C8FAèZoÂÉ|q-Ölp6óýÀàxøjDº jøÛ§ðÕûÎ|„BÚ‚½§µ~ìna­îPÂÛ’û}¦&õqÈo|°ßÞ,ØZGÊ×Ûáú¶l³AiC7äÑáíOÚ?½´Z˜2>ýÔÞГ,iÜã™›÷€µÆ­~þ…Û‡ƒ¾=Ûë.…¥ë`ÓN8ÙFc;ßüö5EàýÜOyzÈ[o„åÿu;`ÔA¥—¶üŸþOÉiÆØÍ0e,ïè‘CVÿ¶…ð¶Ð˜6ØùáTC·uùÏð‡s|æÖ-°c«çùw7ÁßF¶•ðZ¡è¸×ö­÷¹O5‚¾³Vâ3~øØ“cüðËwµXýn°™ xo½í8´l+\qª¼7ëç\ wÿæò"·íF‰è pç“°|EWCY^à w¶O1™5î|BÕnÙìûÂüã~ûΧÇC¯ )‘‘¶l±:„·ÚM„ [÷|!¼Í¤\Z(Î0¶úÈ>;'ì> ÷¿@á.½ ÊÚqÇ[`u´—î|ÄN¶Ûˆ›JK¡g¤’B+ööýU/?kã¡Ç<»î J`_\7ÃéÖš[ååÝzÞK‚„)» tŽD{/¸rd@J($•Þ+3ôé“ÖÖ'ŽF âŠ×¹2!û¸Óµ¯Ê ¶z£¦m3¨ Žuz×ëó¾-Ž¿Ö¼Seaèu>bdE€ÞBAÖqTr³y©öG€ÚÖŤL%ï=ð7†'Cx˜„€ ùùÎ<¨.ƒªRr ¡K ÞvåËm0: â¼tmÛVK~¾Sam:°›°š¡¶D×0fìvÚGáê…ŽšlÝ¿°™ë_j£ >øþ\£fÉ&“¿íª¢A׳ ôÔVxz* ÿæÝ !Øè‡e|«m •ÁäD¸>å´“ePU•ëW= _éõ 9L *=­éiÛŸÙ‡c'»ž&^Ί'ZÅÌÛŒ”‚Ù‰®sTÖ¤ 쥱Õ[í|ð:¤­¾à”¡uC ¾þøöíêë#óœïJ•µA|÷Ç«1›íŽón-¢M›¬”•µ¬üjÕ¾C 6°Û¹÷5xý~!¼΃¦ðòËÙ¬XQAV–#Çá«ï*A! PYöö[ØY£‘1n\ ߟÏÂ…•Øí°ú¿0zj`ÃFز¥ÐÓ ·ã6&9¯ ¬*¦AW|‘ÍÕñÎ;e;­Ö¡m½Rí\9 Úrƒ%Û!Gà–EK–ÔRRR_1©”pßì:%0µø«þ»ñvìÜÈÇÈʃ úvkìI¹þO{pÒ‘ÔUf°ëyî}øøÅT*){÷–·ÿËUî¬çÊþä×_/%+ÛN^1 íÿ{K–äóÙgäæ:ÊöÒ¥5>Üš™Î÷Ø£ÒƒÈÊ2¿­õs“…ðúK/à—_J%ÄNq¡…½ƒøæ›R*Ê,`ð"§*/q³fò—¿´2>å¶¼”B!%##ˆ}û*Y³& »ö²‘šlG¥4ƒBµz**¨ªÊêðÔ+ÜÛÖ­º¼¼»ª7ÞXÈ 7쥦4–ú ^6m’qå•Ç]µ@@€Þ”º½}þ^©455&|7m:NMóË6€ÎqÝDòúëÅX,mU”8â>¾zZàO3ï¿ßƒéÓ3yê©"¶nÕùÝ µÚ‚ÍV˪_mÌš¢F.—’›ÛpøÂäÉdfêÙ¾½š9sê_sÍIªZµðE,ž^·gÅ3þŠl*«¡kŒÌÆ•@7Þèð"ví’0vìæV4,õ€‘GŸ…eª(*2PuÂ,„·Ý©2A¯„?î¨!ívBC¤TW—cµÚpW  6–.Í'+«,6bb€…Ý»kÈÍm嬅'|Ýï,°5•`ÐáebÑ¢Tî»Ï±àÄ?ÿYH÷n[Áæ¿n[Kž÷ xn®ÜÜr/¶1s¦”›Óƒ”’—çìµ2V!µ[ˆ‹k›, Q3sæ,^¼ÕÌtcàÀXvî,ä¬__Æ©S6‚Ôìèn—Q^ÞFÃôz°X Æ9>¼K“Œvââ|þy! d¢×;„73³–¼¼–{c))!”•é©®2rùåA”–cÇÿ™×\RV+ÃdªÆ`0QPPþøî»Jžy¦5cðä§•á#^ã¹¹;=úäÉBCuÔÔdºîÍËk}¹.Ϋ!*ãùZ_Ñ ám.9ÕPpzFÚÁëV%9Îó0PIy¹™ë¯ßÎêÕŽÚ¸oßìvûö¿ïu%Á1/µÆ‹·Xë,<Ån[æb·æU[yt5§Å'­N[*Üu•ža6ÚZiÕ*=“&i<Žýíoý¹ùæ-ddÄðÚk»øí7+ññRRÜ_•ª¶IŸòR06æñÛoeÜÿ.Ž3²¿Q£•ZÏžr.»ÌQ©ggë¹õÖ=lÛÖòØïèÑÉde•““S:g¸©À³}Ÿ—§ç›oœ1©CuP¾3Ý+¤2ÿ䛵¸>ÖìÆÏ?=Z…Jj„ªBWYÚ¸±€äd9IIr·òæ‡Ej ýšÕBxýcóæÒxë­Ølµ8z²$˜Í&®¿>ŽíÛóÈÉ©Â1]ÍìïÝ*€c IDATÔðæ›é(•êÑG·3eÊw~^)`Àd²y©(ÂaµÚ‘HªøüóÞ,^ïò$†_Á+¯8<â#GÊyòÉ_ýœf¹.þöÛb†•/q«,§‰u½ÐÙívÌæÖ/ûí7#F¨XNÕaϾ}F’“eë<Òʳâò#Ñ#<¼¸z»wo%‹m&/OÏñã6úõ“!‘@*.¼Ðѽ^P`à÷ßOb±è[ß_k·±Ï¾É@8%%Õ¬]û'z½…¢þü}÷àúë3øðÃýn•“FìXË£&L¥`Èq¥É¶mFú÷—£Z ¶ì´˜l™›Wê>ó¡qL&P6iǬÝBx›CYYëÖ­óúwàÀ&>Å€·…?++mH¥òò4ØíuÍçîº+‹¯¾êOuµ£ÑJLLz½Ž=ê ­Ž´4¡>\Á±c5ìoæ‚,ûöéÓ§áÔ#Gô¤¦ö`ܸÜŽªpô$;Eïݺ)˜6-ž´4¥Ës SPR¢§¨HÇÈ‘+9q¢µÍ+àî]]âZ\\Kp°•kõ#îÓ† ŠfçÎú@VV·ßþsÓ¿úHYýøX{ìÎJP ö:{ÎKÜZ-ǼTjpâD5EE~˜¶¥ ¡¸Ø‚B!!$DMýÜí+¥³,yzmZ­œ+á@`æþû»ñé§RZÚŠyèÁ‘ Wº5÷¥né¥àС6l(A£YËGÕí§àÈ‘DEE‘Ÿ¯bûöR¶jÿ½¼v3ØŒ Ÿâ

ÜþŇwTâQ¹½øâ%üõ¯ëø×¿¶sð £ùºkW%»v5qÞæ{; Âàų—æp(P7êÀ×ÔBÇÊHß|“ɽ÷nA§ký„“-[j–ñÒK#ùàƒíx.{grŠ«…Ó×’¼ä’HÖ¯/ÁæÚª"hÅŽ©Cùò;=7ÞãÖ2©ç7ösÏ=£€`wµö(C=´•—_¾Z¹³ôîÝ5$&ªˆŒTyØ3ÃáÕ¨T2’“µ~PºütyÝ­A~> o×®]Y°`×sŸ|ò Ë—/÷yïüùÙÌŸŸÔH³^å ÷—U‹£Ãͽ‰od„úeÇŒ‰szãµÎ¬oä…oñÛlì\uU7}ôS§Ö  ¾Á‹:kVO/ÇQLÂýhO2õ1ñçg€Þüúë)‚HMõúÜ\O>¹Ÿ .ˆçÇw1n\:»vé0 ¢ KL‚J0”ºúW_!—ïä?ÿ¹Ð/ßxóÍéÌ™“żyî-³SP­8:™úxïSOeré¥ÁNn¥ð_~YÈÿ=7ˆ;Ki¸ì—·ô°Öœ7ù%-vﮥK—:áÕræE!N±7ÑdeU¢TÊHJäGá5óÚk}…ÇÛ^ìÞ­od‘ä´f• ¨béÒÁ„‡¹DlúôÕ|þùgø¦0RRÂ9~¼•…WÒ¼uEE¡iÐtöf hQ©‚Ñj()iŽgw¦ÐD]ìTæu%JQ‘FMPçª-¿ÿ>‰ÄÄxޱ±w¯™ž=œCk‘€t˜Óã6øxE<_“Ÿ~êψ{1›¥ ÆÞ½Ü~{Ë— KM†#'Ý÷I 䤥ÁŠÅìß_Œ^³gû»ÛƒúUùcýâ‘,\Ø“¡Cc¼ä›Â‚q”ÑE‹.¤¨è6gyéâü2?廸[IëʬHq«Ä¥Î÷ÐêöYFzz8‡µ°U¨u}à÷í·Ç0mZŠÞöÃÂÒ¥¦F’±af(R®¿~ˆóSÌæ _I.sz,ˆåÉ'›SÕ{X‰GÕýwL™Ä•WÖyÕÊF^‡·›”É€a|÷]sâ™™¼@uÿz«ÈOkÆ:0 œO>Ê;ïTS^®u^ܨK—6Òª„xÇ4Õ¼<=F£•®]ƒ<~7ê`ƦA©”°sg %%J¶m»œuë.!**”?ÿlY‡ßËóà¡çŒ®ØaB‚’#Rxí5 ÷ÝgÃn·£VË0›S©øδóÇÆ“Ž2*—K¸á†Á^ò'Ü#í )*•ì´ïÖq~[G9éÞ]Ë AQ¼½n¿³ÎÆ:ñµ»¥C°ã=’Ô/”ýÜv[ 7ë)á¿U"‘ám¾ýÖÀÎFt:;ᆱuÅø< Á±‡Š'÷Þë>=4â ͤ 7ï¯9 ýÖÒÔ¸p—.þþ÷4GxÃÄ–-&NLôqµÚiK¸óÿgî,Yó3üæm¿·p5$:ì ò’vAg|ö˜1!ôíÝä°ÇäòÁ>Ä0ZÝ#Ž«Æ`°Ò«W˜[ˆE á¶Lêò(:ZNJІ?þðÏÞ3ݺ…rå•1nyÐÅ­’ì æÓO˘93Ýi“Ôo²pゥ^òêÌ!šôt)ÁÁ°}{k–•s´Š‚‚d|òI_ÆŽ÷rMåf·£•†$Ú)þÎ<êTš"„×åpNÙt¯§2ñÒK\|±šcÇ‚ Òø© ¬‰—f–´îÅñŽJ-cùŠ®¾:è%Èaîcv~ýÍ·ÉÇŽÁ‹oØYþƒÝ»]×Bê©Òx‚ƒ èƒ]ENŽ•ÔTï ”Üv›’åËu¼÷^([G²t\uu%Réi¿5@ÁŽcq*JË€ ¥RFTT˜#½ê¼Xß‚÷Áaüö[_‚£T¤*Ìh]E­‘ÝÙMhvËeõy#m4›¼TJuù«rüùàÆédBÉ6s”JaÅŠ 7ÇQ^_)ÉeÞÓF¡dï>ýúiùðC ³çøO¦7@Y]âgÍgÛKq2 ‘(%Úð> ˸Jj œˆ)ª(y¾%&·±y(nβJ%eøð`O­­«è×DìôÐíÜqG8³fEóé'0óe½³ÐÚ°‡Fo› …£ þëe[•°0ááðúë¡Lš|ZHnºIAß¾*PHœ/GÏK@–æóëûöw–„’‘‚T)H •ef¦ÞíÝcX÷+ôî ¼m!.‹W«Ïª¨Ì†Ñ(#1ñôÂ'§±Ž¼À@ Æi‰‹SºZu?nð„7ÞØíTä³Ïzú¼îá[íüøk]ºD’–&áë¯èÞ]Áèaþ·M ß/Ih¨”ÈH×M’°#SÂqöÖ®5sÙøg ÃW?²DW\Šs‹PGKºn¨Ÿgø§áK7k–šÁƒÝÊZÒèfweF;}FÃÓMØ,<Ü­²¸ØíõUkãÊì°0¨°ú~­Û ¯×­É¬o†7*—8CÇ2¦O•0érEƒ°F—8°ì âXWW*i4òqÝløÙרQ¬Iuž·š#X° Æ¢‘ñ曡h4R¡\!é™[iÙ9pð(PÝØèK…ð¶ Ng«F·,€ŸÜ÷BS¨A¦$1QʬY Ý!µ>úHͤIŽa+ß|cãºë¤ ZM<Òx­;~¼‚Áƒå ƒÍ»¡k7%±=Ïùfs™WÞ†ûîƒq—(62$¾½Ñ#GÌÔÔØ0à4Û›°_ÜÝwËvˆÐÇ+aöƒðæ· ¯{íÿÀ؈§Ø7ôGK¸æšH$6¸ò2)ýûK!„@†×pÇ °m‡’K.iâøO->û‘^zIÏC8E©7uô<~çé" ²þ6 Þ]âÕË|ÿ}7Þ¨ôŒùÈ‚Ukàò‘vߎ´¸¾ ¿WÑH:Ö·Zò«à“| hS=úÆùÛß‚ ÷,ãýz±ÊÆ5×8&x nÄfÀ\/-o©±4ã—5È´uÑŸlýÖmJÚo¥@!¼î…Z w=Ü{³¡¼f= È” mzOñÖí6.¼Ð3iŸ{î¼]Ñ´H «¢“!4LfØ–ÇË<_¶¹sáÿ€—ž'6ÖÓ¾‹{Ãm×¥‚2 Ô*m›ûÏ¿¥Ö´…E¯¹ ¢£áå°Ö1¡J·qäk¶^Vmªˆ†¹M(}Ç1‚µP²î»Ë-ÜS‡ª<»¡ JaÕF˜|…÷ôÂÛÖ(ê;¦TpL k6Ç#p6ýZA\8¬X—]èŒÕ*œÔÙA»ôØYB“G=7¯ƒÂCááÛ›n×ÝS!=÷‚ ÇÁ*ƒ··Õ{àÏÍt|ÏÜYшÀôì³&{÷ ˜1¹éöLé=ì ²iF©[®ÂW)îæP(÷l(¼ó=ÒñæÎjFÆ…ú%9Å7èê+\ ‘^j–NþRx·å‚^pãP Ò{ù‘^aEâmðM$<õ!m>°H[°ÖẞÆÎ£Ž°É°Œ¦Û±·Ä±¥ÝÈ!žEÐ&iìb IåW¹Â[‡®µôÀ¤T(Öƒ>†w…|W¼§óß»aÓ þ3kÙõpÍÿê=¦*;ØÂᢠ!÷’âå6(’£ý˜V2xd¼0ˆ… Ä%ÁÀTx½1zX Äû?ïœi³ë\úœ(sô°Ë¤p÷°üâOóâ$i6¤Ã­~5ãýkà³0°+¼¶×3 ÓâÉùª–µ æ „_‹á/ꞸÆMmäí÷÷ҲߡQCP$ê†_|U,ïÀ½w!¬ºl*mFºtï -Œû݆ôM{¾¸Ë™G^*#õEz”=M~/²BxÝÙ¿šÿ›èX•ê’X~'\Ð¥ wn"=b`XÌèòatj§“ G,VÞ2/Èï¨!¢@‡þɸaÇLÏvã¿8ÓÇÝÛŒÇÑ,nAzͼÇì0) vWÀ·Î¥u?? ÓF»]0XÝ.i’¬…Œø)ï´І£.›„os•eù5pIOX8w_S=Ä-Ú¯œœW‹äœ‘Ì [D2!­s˜¬„/.ƒQp‘Æý ÿÞÁFIVéŒYðë €Íexl/†;.s¼¸†j;ΞQ°ã8LÜ ÄB@ ›‡×Ì T ÂÉ®'~mW6€Tž‚ãÝC ÍPm+óX]ïæm*€¸H ‡][`„ú÷jÛïyŠLï÷íx;ärü§b!SÛ°|‚ª KÛ\gøe½ÁÙŒUwl©¥ði?ÈÔMîH3€ # ¸ß: Ð'^²Àa·‘&Kâà•f´ê”øKœ÷á×Mò¾Ã¡¶ü׺ø«s…Õ€f®7#•ÀÕi´n-r9|S Ãâ ‡³e4J_,B ‚³„Ž¿ÎB/|ž};‰MéÇ_c¼ ÕRH,ôQ¢eÏ33@ —˜aÚi^Ûƒ›÷œ;“ZgǬ(˜jƒMJj¤Ì5h¢ßëZÑVŸ oÕÀÝn^óÔÈö-Bxç12˜Ö„°G&bÍ èøU«¤X‰‘´™ð<Mð.dz–õÔ ÷?RÙ„B*‰‰„À°6\Äü¢GeÒR¦«àD4!=˜‘ÿÕZ¥_ÓA¯à¼d$jnžª@‚ÿ¬aÛ¹ k¢‡€ÖNa³l¸©kQuwQvüµÔÄôèÁaC@âßÞv!¼‚ó–ÉHIî$¶¨RŒFÖÒ9ÆçµãïînBl¢ÕÓ=Ï2„ð Î[†v"OWmFmì›4ç޹ïí @qfÔq†N+¼ƒèMZ þÂ+t0ìúaËp¿y¡ÑÆ·ÁŒÑtéàÊ1€6 #„W è`dX‰'ï¼üíI(Qy×´3”ËÎÑ©ç­ð>|˜Ûn»Íõ¹  @(€ c ¨ÊÕTt[¢)BÙìµ+[NtAÑ©óçéÀ¦wN á=iiiüòË/®ÏŸ~ú)³gÏ* hw¤ÈèJ"¹˜;Ü–0Âwr!lozÉÚ"ÏÏS$ 2™Ìõ'•ŠÙÓ‚ŽcL&¸ÃíèÆ ´x`ÿ¡¡–~ì=‡+[@ pãžæ.ýÕQÃPþÂ+Ît‚¡]D3[„ð A{!Aм£W:Â+Bx@ „W „ð @¯@ á!¼@ Â+Bx@ „W „ð À;-^W¡P Õú^LC"š.~Þ®]»qÑEa0¼ž/--sý??¿€òòúσQ¤¼@ ÂÛ\ Ø¿/‹÷UóOÊaüø ”•• ÓUS]]íq>99E¤¾@ ÂÛ*++‰ŽŽ¡¨¨‹ÅâqîĉS(ŽG3tè0ìv»ë¼Ýn¡@ „·%ìÙ³›nݺQ]]å:f4šÐh\[éX,*+K°ZëÅY§Ó“—WĸqcD‚óŽV»nެSxètz×çââ"@ŠDR¿…svö âEê !¼-¡¨¨¤¤Ìf §Nå Ñx\SPPà 5Øíväò–9Úk×®eÙ²e^“ͨQ£øá‡Dî ‚s/ÔP[[KVÖa‚‚´TVVÕà®–  T>ÌöíÛèÙ3½_Ľ÷ÞËÝwßÝèu3gÎdãÆÌž=›ôôtRSS]ç***Ø»×ûÎ¥™™™lß¾ââbQ2O"##éÕ«WÇ /€L&§¬¬’ÜÜ<¢¢"½^³ÿúõësÆçmÙ²…_ýÕõyòäÉôîÝ› PZZÚb;KKKY³f×sûöí`Ö¬Y¢T ‚F™2e ß~ûmû oBBFŽáú¬×0`€«S­.¦MïÞýܯTª|>;::š .¸Àõ9,,Ì/‰Õ½{w.\èõ\nn.{öìñyï‚ xôÑGÑh4m’‘?ü0/¾øâY÷ì½{÷²gÏfΜé÷gïܹ“ÌÌL¦M›Ö&¶øá‡ :´Už‹/Þ}÷]FM=Dyq£¬¬Œ%K–0oÞ<¿?»¨¨ˆO>ù„¹sç¶¹ðÆÄÄ´¨¡[·|ðvärE£×Ùí6ìvËe>®°ùÈîÝ»{3›Íœ÷ÜsLœ8ñ¬{¶F£¡¶¶¶Mž/—˱Ûímfû† ¸è¢‹1b„ߟ½nÝ:FŒÁ!CDyq#??Ÿ•+W¶ÉóOœ8ÁºuëÚÌvÒ¢Î5©TŠR©D*•4ú'“ÉÝæQSSCvv6ååå”””8Ãý˜>}ºËËX´ho½õ3fÌ ))I´‰A§C~¶Æ›o¾éqlòäÉLž<¹AàôëüÕü 8+3ù‰'ž8+íîÛ·/ññgç°Ã3fœœ,ÊK;ÉwÞ)„÷\b̘1g­í—]vÙYiw\\qqqg¥íå¥ døðág…­bÞ®@ ÷üä8+íNKK;kC0W_}5)))¢¼´#ÁÁÁÌ™3ç¼ß%eeÙ“~Uª ìv&S-GžÀj‘‘Ñ3›Íâíö&|…ýŒW(hµÑB}Á9‡NW†ÑXíW.@.Wz¬:æ!·v;EE…„†6÷ºiÓŒF=HHðÃÛ±Š‹!1z÷vËϳêF+deÁÑ£ Æ5nðÀСš6l 88˜þýûû¼f÷îÝTUUqñŰqãFjkkIOO§k×®¢ mÀÁƒÉÉÉi4¾››‹Ýn§K—.²k×.×¹îÝ»“––Ö>¡³YÕjòzÎf³±yó&&NïqüÛoWqìX6‰„mÛvrë­³ˆ‹ëÒð À€0|¸Cx_z 6o†qãà®»êRÂ!ЫWÃo¿y7òÀøâ øüs8v¬Ã2vÙ²e>ú(6›[n¹¥yƒŽüÁ/¿üŒÇr‘2ldgCck5<þ8œ8Ÿ}V,*Ê!ÐAAg]xôÑGyä‘G(..fâĉ/ht:¿ýö†ˆˆ×°°#GŽpÓM7¹®ûã?ˆÅh4ÒµkW G¥¸¸˜ððð6›*,èHOOoZ½óÎ;±X,Í^q±Ý„·¸¸„¯¾ZΑ#ÇøðÃÏ2d —^:Æ¿_âc†ÎˆÅbaÑ¢E\tÑE>Ç>ÿüó,\¸ŒŒ ~øa8À°3Ų­¢ªªŠ;w¢T*‘Éd.á]½z5ëׯw-²4uêTfÏžÕj%%%…¡C‡²téRt:jµš)S¦0hÐ ‘ g)_ý5f³™éÓ§{=Ÿ••Eee%ï¼óëׯçwÞiV¨¡Ý„W©TÒµk2$%u!**â¼ÊÈ{ï½—'Ÿ|’ððpî¹ç, sçÎå_ÿú—Kx'MšÄo¼ÁÊ•+¹ÿþû‘H$üûßÿ¦²²’Áƒ /ªˆåÚk¯E«Õ2cÆ ×ñ»îº‹õë×»>'''L÷îÝyùå—‘H$üðÃ$%%‘——GDD„Þ³„#F°xñbnºé&,XÀ’%K¨©©q o^^o¼ñ&L@«ÕòñÇóì³Ï˽÷ÞÛ9=Þ`®¼r<Ë–}Ǹq£‰9¯2wàÀ,Z´™LFpp0v»ââbÕκwïÎSO=…Õju­ÈöꫯbµZ 55‹ÅLvvËVKIéŽVÛ”µììß¿G” @P/šr9}((È¥¤¤Øë5‰‰ÉÈd²³ËãÐj u}Öh4hµA„……RSSͺuéÙ³eSh©­­Àn·5zݺu¿’šÚM”4@àB¡P\n¥wï>>ü'6˜LF×5]ºtq.œc?»„·ŽÀÀ@T*11qètU :ÀŽÕÚºQv»Íç"îuX,QÊO*+KHHHÀb±¢×)..<£®tzáíÖ-³Ù€B¡@§«¹,:‹cYhh02™›íÌ÷tÚù³]»vG¯¯A*•´Ú»‚¶ÆhÔ#—Ë8y2›ŠŠÊ³Óã=~ü(ƒ´´î¨Õj´Ú@‘³ ÓRPPˆD"¡²²ŠÐжÞÜÜ|Ž?Ñè5!!ÁôíÛ«Å?$>>ŽââRÔ?~¢UÏ‚¶ ªªšÂÂ" AAADGGñž oYY9MWÂbî|kÔëyæ‘[øæË÷[ý£4Ç´*•’?ÿ<„F£iÒ;&“ùŒ£š$ç6› ‹Å¶m»HHˆC"‘4XÒµÍB ê€`ƒ=E°¤(Ÿçÿq/F“  `ŒÆ–uŠéõÜáÃÇIIéêóü™P(ìÞ}›ÍÚèuaaá-þ@pn"—˨¨¨"'§€>§oÀëD©Tµð¼¿èiRÒz2nâuèkkxáwò¿Ÿ¿ãã•x\—Ÿ_ÈîÝ{¹âŠú}ë¿ÿ~ C‡&*ÊSÜjkudf£°°¤Ñﮨ8Ð"›÷î=Ð&× ‚ó‹ÜÜŸºqÍ5]-v¿ ï›/ÎgÍ÷« G¥`Õ×ðëO+¸aö½¤¤õêG#ó¿ÿýÆW\†ÝnG"‘ðË/HMíÞ@xu:=Ç£¨èôµ|%ôè‘Nll,6üzÎd^ÿþ o×ïþ–K/¿âÿÛ;󨨮<ª( D‚¸ JÄhl[4ecÚd:tkm©‰£§IPd´ÝW4r@‚FÔ´¤Ïàé>'n¡#MÒIP4Ú(›ei  d‘ÍZ˜? ŸT#PÐh\îçœ:U·îúî{ïû~ï÷ñãQ*L(mLÿäóÍ„ ã5j$sçþoo/'3rä³X»JŒF#:]•Ø«à±`ÿþýV¥ë±×ÕÕGGpwÖ™ÿp†ƒûv:)MÛ™×mll˜5ë )üÛßþg§åÿðÃwô飤¹ùŽŽ}quuéÔg"?µµæ¥}”JëÖ ì±ð<€;wêØÆØÚÚbkkK}}=2™ŒÆÆF¼¼†ˆ½, ZZZ¸zµ¸u @ Öûdçj°³³£Oóp2ów ¶¶v”•]ÇÆF!Å= ØØÈ)(øƒÁøPê3xx¸?Q}([ƒVbok×e9rÑ•@ðp‘\ ß|“OE¹Vôˆ@ tÀÿá0°ãøìì“(d÷Ñà1À?KáµZÃgŸe¶€sç ÄÕìììøä“غ5áçu5XÃÞ½{9yò¤Uióóó™3g¨T*T*111’º»»Kÿ«T*Þ{ï=²³³©­­Åd2a2™Ðëõ9r¤Ëú""",Êsrr’uãÆdggKqUUUdffRSSÃŽ;¤ÿÝÜÜØ½{·tR\¹r…!C†Ð¿¼¼¼(,,¤¥ELwÑSÖ®%8x†ôijjæèÑlôzÇŽýYJW^^Á×_çàäÔ—ŠŠJ~ýë`ž~ÁÁ38qâ4—/_!?¿€¼¼¿[”ùÇ?þ/UU:¾üò4ÍM‹¸Í›ã9rÉÉ{X¾|·råF«¶á7¿yEÊ3y²?6¼À´iNfôè‘Ïॗþãõ£«« óæ©>üÁ&“‰mÛv"}®\1[Ùii9þb›ý»EZaûöäçHy^}®ä¦3 ¼öÚ).4t‰Å 6½Åš5[8wî‚TÏ[o…Y5¶FsÓb{7n|“É„Á`dÙ²ÕRº«W‹INÞÝs‹×Zº{›½aæOŸ.…ïZ¸jµšñãÇãïï/ÅEGG[äÍÈÈ ªªŠùóç[éÃRZø¥ÇŒƒŸŸù•½çž{ŽØØX)îòåËhµZŒF#Z­Vj‡¿¿?ÅÅæ7UJJJÐh4DFF’žžÎÂ… Ù¹s'%%%–±Àz®]S3aÂ8)|÷wCCc‡yìííqtì˼y³yå•—Z/êÈårll̶Ä] Ô|W››+:Ý-úXÔ§ÑÜÀÓÓ­¶’ÔÔDœŸà™gœ¬Ú†††Fôzƒäc-.6Ó£FùRQ¡E«­´¨óAз¯}û>œ‰í÷íKÇ×÷YɲX±b=Û¶­oµîG¶q”JZZzmÛvpüø¡V7G³f-àóÏ2ŸŒŒØÛ›'˜¹yó'>ø`‹zµíEE%¤¤ì•ÚðÓOå„…E–öA§ù(å8vì/¤¤¤¶ÀÂµÓØØˆZ­yðÂû(ÇöíÛïy†d2jjj˜:ujÊóññ!22€ HaÁÏËïÿ–ô»¶¶Ž¯¾:ÛÆÏú ï¾Úí2·m[ßešÌÌ/¸téR¸­à?©ŒÿK¾üò4qq»ÚIKz­OôìuÑínÚrëV5ü‰.,¼ŠŸß/{ßÇëææF@@GeæÌ™|÷ÝwØÚÚ2nœå•[¥R1iÒ$¢¢¢èÎÖjµäææ¢T*)*jÿðàСCìÙ³‡ŒŒ œÍ~¹uëÖ/¥9qâ§Nê–ð°ÿ~-þ EÐûœ=›Guu-/¾øï=Êá¨Õþð‡¨6ûj uu·H{>JbâVÜÜÌcß.üïÓ—rúô_-.í|rs熞þo¾ù;ÊÊÔ\»¦fñbËã-:z5®®ýXµjÙCßG&ŒÃÞÞžòò{Þ¶l‰'1që{\nÚg±@ï¿êQtv›¾xñbvìØA`` /¼ðqqqØÚZ®-TYY) ±ê wwwéÙ]|}}[7lááá¬X±BŠ»ëÇÝ»w/‘‘‘ìܹ™LFDDD;occ#Z­ÖÂßM`` öóó#!!Á¢Þ{>2Wîܹƒ‹‹ R¾±cÇ%‰¹ wILÜFPPˆž2e+V,E¡P½DŠ1âY&qölS¦LjwÝeôèQ|ÿý9‹2£¢–àé9€àà™$%¥ZÄmÞ¼Fú=|¸w·W²þøã$æÏ_$=,Þ´i5YYÇ¥ø€€£¤¤”  ||†‘е8Í™§Ÿ"((„¡C½Øµk;vv–ç]uuµE[/_.$*jeë-|3AA!DE-aúô{}Ÿ;ötº[øùmcé›]zxP^^Îùó9sæk«Gøø ãâÅK(fIªªÒñÃ牊z¯×ÛCLŒùNµ¦¦oo/À컾páZŠ‹K8Г#Ì.ÄÛ·oÓ¿¿›´­™™_0oÞld20À]òkGG¯²Ê­$Þ\ëEÄ›k‚lj–;~üñ|‡ñeej&NôÃÃý]ÜŸþt˜üü{£'–.]Œ§çRS÷Q\\ÆÔ©¤§gœ‡‹K?22Žð«_½ˆ››ù¢©×8pàSÞ~û¿Xµj“ô «Wbb":¸+°åÖ­®_¿ÖaÛ/]úÇ}GÌû6ëÖ-'--gg'V®ŒnmžÕ«·Hi½¼³dÉ;­fqqI8::<îS(**a÷îÌšõ:Gxÿý Bx…ð í1Z¸v­¬Ó4ƒ D©´þe„Ï?ÿ?~ñ‹ÑŒ9€7ß|GÞÞB&“S]]KUUe'.9Æ ½¯ð~øa¼UíÁh4’ðt‘((¸ÈÁƒ] ¯˜€W xJQ(døø ëÕ2_~ykÖl¦°ðjëmýBi”HïYê&œqvvìv^w÷þÈå½7S‚ 'Ž—ÜWC‡z±}û†î» %ööŽâ¨ìwîÔ£×7ŠŽݳx †& †&Ñ3@ð€³“ ^@ Â+!¼@ðøòÿáCcga2¨IEND®B`‚snd-16.1/pix/sceq12.png0000644000076400007640000001370311147553270012750 0ustar bilbil‰PNG  IHDR.€f‡sRGB®Îé pHYs  šœtIMEØ6 àÎË#UIDATxÚíPåÇŸ½ƒŽÄòP)D@I=.AL«AEEÄÄqŒÈš©lgì—ŽE¡bSVjhŠ?rÌ”Á©*Åñ+OÈa†ÂÀq¿ØïOíìw÷ÙeïwûþëžÏ>ÏÃñºÏ~ž½½Ý÷b8Ž^TZZ*“ÉÆŒC‰+Š©S§>õÔSÇ‹‹‹F£··÷Â… 1 c z{{ 0 ‹ŽŽž>}:ì©P(:::üýý—,YBôt'nF£ñÂ… }}}ÞÞÞ©©©ÞÞÞLAäp·Dds"i|óÍ72™L$Á¦¯¯oLL aO’’ª''žÃ ³WT^eÕ ÂÓv€p^ƒ©°°pïÞ½?þxSSe“N§ ®««ƒÍ¬¬¬²²2Ç+**233Y‚jµúµ×^koo×ëõ ýýý8Ž¿óÎ;ÅÅÅ8Ž|ñÅnÉ-##£«« ÇñœœœåË—³‘ÃÝ ‘H§a±XÂÃÃcccgÍš5kÖ¬èè茌 &Â.&VÈóÌÄsa–ŠÊ‹£¸¯ >>ÁÁÁ~~~@ •J‹‹‹_}õÕüñðáÃQQQ"‘(((hüøñnIoâĉ'N ŒŽŽž2e S"AÄE,4,ËÅ‹³²²Å΋ I•O<æe¿$‰'¯ üÑÒHR}}½F£©¬¬466æååÍ›7/$$¤³³“è£ÓéBCC1 £% ù Ã0£Ñ [¿~=Çñû÷ïÏ™3Ç͸UUUeggŸ8qþ¬.‘H*++»»»éA¦µÜíY%&×®]#_™„ÄÎ-!Y1QåÏ„yÙ©ˆˆÏ\A†Wü/q\E6¦Z¹råºÿ$‘HÒÓÓ,X¯Õja[,­V Êd2Ç œV£Ñ$$$ÆùóçwwwÊÊÊ–,Y"•JÝŒ[kkëc=_wuuét:™L† "‡»+"H²Ó¸víÚèÑ£Ù±ó{4’’ª‡'žc 3å3/î²aáiÛ/áÖ­[ú:::ª««CBBœ7CWWWeeeXX²i¿”Jå¹s犊ŠL&S[[ôhµÚ#GŽ™Íf??¿ÐÐP©TúóÏ??ûì³999Ë–-“Éd^^^ô @ ˆŒŒüþûï'Ož|äÈ‘^x!11Ã0…BãÆãÇïÞ½Û÷°3t81&nááá÷ïßïëë›7o^¶lYzz:2ˆîTDvf¬“²d ’’’æææW_}6™»Ô.ïT€,¢°BRšÄsØá¢ÊB˜¥¢—FX«V—¢mÿñÀpò·Ó@©T&$$ìÝ»¹Õd2mÞ¼™ÉÜå‡~¸}û6ûüì3íûÊËË™šClVTTtÿþýAƒ­­­ …‚ìííýå—_ª««¸ü-.92JbwîÜ)**jnn4H—µˆìde0Μ9sìØ±'NF«’pÄDC«ÕÖ××sÁîp†€%%%—/_Öh4ׯ_¿xñ¢«D²BRµ9ñœ‘™;wî,...//¯¨¨¨¨¨¨©©q5ªƒfãȰ—.]:~üxaaá ô°ƒµFÔÄñCgg'ý ‚tþÿ-]¸pÁæ)¶oß¾sçN䦜œœëׯ3 \µjÕéÓ§Ù'gŸ¬µk× ¦¦[Š @î ¹£ð¹=+k-°e8rÚ¶Ã~úé§þþþ£FZ±b—ÿݽ“Ð!™Édm'U¾<âÖ;¶{`º: 5ÒaÜZÛñ!æpollþøcÏaeƒö  = Žã‡¶j> Ënm3U¾<ÚàØÎ§«+Òaœ»íøóh4šwß}÷þýûµµµmmmðç9³Ù¬T*ÏŸ?ODþü7ß|³¾¾ ×ë8ÝÜܼpáÂ7ÞxÆ¡nÞ¼I_¹reÚ´iðõÏ?ÿ|÷îÝyóæ=ýôÓ»ví‚:tèÌ™3,3“g€***‰D}}}o½õVÿÁƒÏŸ?7ùûû·¶¶=)MBƒáƒnÞ¼I¾-Ó¥ÄýÓ¡0äpD‹‚Ë6Và? ìââb²¶'0´-ßè»»»óòò 7oÞ\SSãQIè¤Ì5jtzƒÙÑÑÑ`òäÉqqq&“iöìÙ"‘hÆŒägÐx{{ÓãÍÍÍ&L€¯U*•F£Áq|üøñ¯¼ò 444..Ž}fò €ÞÞ^“É!‹ÛÛÛårù† -ZDt îPšP}}}µ ºví¼'ÓÅ;CkŽ\QpÙÀŠ,²¶‡0´-ßè“““_yå•”””7®ZµÊh4zN:;3ÉÙûŒ˜}fò __ß””@yyù¼yóÄiâ Í`0'¢4¡V¯^Íýà¾}û†+)ƒ‚‚¶lÙ G†Ö´¶¶îÞ½›h–––fdd133“ì¤òÁèõúáµqãÆððp&\Ö²"D·À¶Š¡UÏž=[TT4\_|ñEÂYÀ¶|£ŒŒŒ„/üüüªªªžþyç%aGGÇ'Ÿ|âj«Ë·ß~K<,ÒQ™I1ȶa×äää" ÉÏ?ÿœòýþìÙ³.EuÚ´iëÖ­s`yD:¶;µfêõú>ø`D!mÙ²…8™âÀê:¨œ½fmܸQ(R~ΣaäÿŽ–jkke2YwwwbbâþýûgΜÙÓÓÓÐÐ`0à1 YÈøèÑ£‰µ³§§ç÷ßW«Õ …"--íÆ”!ƒÎ@Vii)<ÝúèÑ#‰DBÄF£SJ«ÕîÝ»—é¿øøãÉ(§M›vèÐ!WHÖAZÅ#@xvú믿&šä&}Up‘}›ŽËVìØZ055555uäæ J¥Z½zuCCÿ籂þþ~§&áØ±c]d‡ujffƒlîTï¾û.Ç·½xñâÅ‹ ª¶•G/lg¤«X,vñtuj[%'­Y¹¹¹\‚0"ˆD"xØÔÔ¿FH¥Ò™3gÚÛÛq¿téøÿK5¹¼ {ðà|ŸŸ¯Óé‚‚‚Þ|óÍøøx³ÙLîÌex¦§´´´··÷úõëðÐ .P3SJ*•nePVVÒsÖÄ#CkŽ\ÑqYË 0X`{CÛòð‰'žÈÌÌ$>zô(>>Þs’Ðy™ hÙ¹}ûö£GJ$ÏIBçe&@§Ó‘ëOÕþòŸ»ÐÖÖV[[›——·gϬórX©TÖÖÖvttäääÄÄÄÀËcèA—âÁ㸾¾¾îînâ‘Å8Ž?xð`̘1‰D¯×‹D"ßpOKKËÏÏÇ0L¯×ûøø Û°aC]]Sgèêêš1cFTT²é !ítE"QMM ô~xì±ÇF­ÕjB¡8vìŽãð±¬B¡P¥R³I¥R•J… ͧà(bHpSUUUll,ûï¹H/]äœÃÈÊÙ é¬)¬Æ™:Ó§uCWÈ,û¥¦LgâÙ³ÝÕ2ÓT¹=$.äð{÷î]½z5&&æáÇB¡0++ËËËËÕÊ£SÁ"± +!r×Fdp䢮r¸âÙÙ@$ÅÇÇ;uÿ3f05!ÂÝÚéÂ_åŸyæ™ŠŠ âbèÐ…aØþýûÓÒÒNž<9{öl蟤V« ÿ€X,V«ÕB¡šOÁQÄàïÜÍÍͳfÍbŽôÒMLL¤Ïyúôéábål†tVÈ"þñ–––›7oVãLéÓ"“Ð r þ³—H$ÕÕÕ©©©r¹œi8½'2Û]-3H•{ÑCâB¯ªª :uêTHHHYYÙ”)S–.]êjåÑ©`‘X•iצdp䢖r”gÝúèp‘ítÉߨ6mÚ”›› /k2eÊæÍ›-ËŽ;._¾ 0™L;/“É„ ŽP,Ë—/tÒK9§;±¢ÉŠžBd‘­Æ™:Ó§uc†ÜÁÒ­Æ™†³ôôÌ´ªè±à"ïêêjll\¼xq\\܆ Ö¯_¯Õjݾ<J•©²ÔJ yÔüÑÒp Úé¾¥„²³³ÓÓÓ“““á7†íÛ·øá‡………{öìÏÝ‹Åd³vø3328BÉ ÔÕÕEEE‘od`á¥{ñâÅÆÆF襋œÓX‘…d…L!bëĉcbb¶lÙ’žž~ûömdgä´îÊ;X@dd$\«q¦XzzBfZUôXpQ†K$’àà`èm#¤Riqq±Û—ÇA©"+!K dGm¿¼x6 i§{òäɘ˜˜ùóç›Íæ–––òòò¤¤$x©Ä믿n2™ÊËË#"":;;ÉËahh(†aôàHÄB!P__¯Ñh*++yyyóæÍ[°`r,“—.eÎ÷`E’•F£¡§Pdd$Òj\,Ó;ЧuW†ÜÁúúú²X“ÅbJî!™iUÑS«ÕL¸(Ã#""È 3†aF£1,,ÌË#GªôJXXXHßµu:½twwÓƒr¹œGÍ- ‘è—‚RìtåååsæÌ1™LUUUãÆƒ²&¾KMœ8166V«ÕZ,¡Ph±X´Zm||<†aôàˆ£D'°råJbkNNNzzú3Ï<ƒ¤j4“’’Ξ=ëççGxé"çŒwVt!Y) z «ñŽŽzç¹sçÒ§5 nÉ™ZH°þù'Ýj9iJîQ™iUÑcÂE.“ÉàÍt"‘ÇqF“0aÂw-©"+!r)Aþù‡äQ;¦¦ðbWIIÉ®]»ÆŒ³~ýúÜÜ\"¾cÇŽ¤¤$¢yçÎòKøj`` ##ãĉÿý÷ùóç÷íÛ;Ÿ¼c–NÕb±¤¥¥ýõ×_eeeo¿ývww7Ëœ#‹(¬˜RÈl6ïÚµë—_~ijjZ³fÍgŸ}ïÑEvF~îÊi‡¥8zô¨R©üóÏ?׬YsñâE–áôž˜™‹XúpÇ‹‹‹7nÜØÔÔ´sçÎýû÷»qyäNY ‘»6² ƒùO<ñNœ8ÖÖVÌÍÍEòbÏž=ñ,"ÚY>ÿüsˆÅâÀáp@&“Á`0 ­­ èíí…V«Ess3^zé%( |÷Ýw())ÝnÇìì,Þ}÷]œ;whnn†Á`@ww7š››!“ÉXD›‰‰ äççGní¸ÝnH¥R¼÷Þ{øío‹¿þõ¯øË_þ‚k×®áСC¸páÔj5þüç?ãý÷ßÇ«¯¾9Ö?þñœ9såå娮®Æo¼ëׯC­Vcdddkš„D´s £°°0òZ¥Rþô§?E,//¿þõ¯---Ø·oÄb1Þxã%ÇúÅ/~HKKCee% ¤¤X|JH”ä, ²³³WüüÕW_…@ ˆ¼.))Á믿¡PøÈÍô…àS(ÈÊÊäää@*•nȹÆXSSSp8¬q¢L©T.J[!¦&áàà ÆÇÇ¡V«Y«DQ6Çü~äJÄçóA$A¡PÀn·Ãår!+++ÒLt+Zx:ï÷û‘žž¾ä˜n·*• @sssÈÊÊ‚Ûí^Òì ƒ˜žž^õÏœ9³äõSO=µ=ëðáÃÒ.%J66› —.]Â3Ï<‰Dhll„T*E0„ÙlÆüü<Ž=Š>ø¥¥¥Ðjµ€ööv>|ÃÃà …p:ÈÏχÃá€ÉdBvv6T*4 àòåËøéOŠ©©)LOOC.—£¢¢‹÷îÝÃk¯½¶mÊ7݉¶@}}=Þ|óÍ%÷vÊÊÊ–lÓßß={ö`ÿþýP(‘÷Ÿþyèt:¼÷Þ{øÝï~‡`0…B††œ={}ô~ÿûßc~~Ÿ|ò þùÏÂn·C,ãêÕ«xë­·ÐÒÒ‚ææf¼ýöÛÈÍÍÝ6å&ÇØó󫯾‚@ ˆt #¢Ç›žžÆÝ»wQQQÓqü~äêl1³Ù¹þð6‹_ÿë_ÿÂþð‡¸ýܵµµÈÊÊÂþýû£>ŸÅY]]]Ìa`Ù°°äÉÝÃÛ,~ϰ€“'O¢¿¿?¦c0°ˆ(.Äb1@lLjf'~&ŠN0„H$bAÄ3°8ø™(:ׯ_ÇéÓ§Yl%>·Û””‹ˆØ$$ÚBMMM‹zÿ@ ¡P¡PŸÏé÷411ôôtÈd2€Ï独¥Ñh0<< FƒP(‰D‚¹¹9¤¤¤@©TB$attz½"‘@©©©«Õ ±X »ÝŽC‡áÎ;صkT*úûûqøð᤮Ͻ{÷¢··O<ñ‹v–žžˆ©ŸÓé„L&ƒD"Ýn‡N§ð`ì¿¿îèè@YY¦¦¦:ÃÃÃCZZÊÊÊÐÓÓƒ@ €3gÎ@.—ãÇ„ÑhDjj*Þ|óMôõõaffF£¿úÕ¯ Óéðá‡â•W^‰y>¨íN£ÑÀb±D½LG«««Q[[‹cÇŽ±ã(m¨ÑÑQ˜L&¼øâ‹ ®óóóhnnƉ'–¼ßÝÝ’’Væ"~¿ÿûßÿpöìÙø_aq!UÚ,ÍÍÍÛæ L&{$¬0¬–!‘H"ƒ½£Á›î”pfff"w‰X”ÐjkkqêÔ)Äe00>>ÎÀ¢íoapîâ.igIMM…Ëåb`Ñög·Û#ó>1°(¡Ý¼yÏ=÷ bS(ðx<ñ ,—Ë…ªª*TUUÁh4²ˆhÍvïÞÁÁÁ¨öåàgJW®\ÁÓO?Í‚ 6 )ñù|>ìÚµ‹A{…EÏï÷£¯¯&“iÓ¿K­Vcvvvé_.¡999ðàIŽÛíF(zdŸ]»vall 2™ ÓÓÓÐjµÐét0›Í¹\µZ «Õ (..Fww7T*Ud,ßìì,ôz=œN'ü~d©t"V ¨««C~~~\zwÏÎÎ>²4[(ÂØØXdp®Óé„J¥‚P(|dŸááa<ù䓘ŸŸ‡@ @}}=|>_äܽ^/fggñì³Ï®^½ŠŠŠ ÈåòH/gµZ––¸\.èt:?~œ¿´*.B‘nß¾‚‚ †¤ú¹ƒÁ ü~?är9 ’Ì'Ÿ|‚sçÎEf¹X«˜îaUWWó)aŒÆÆÆ  “.¬@$1¬’ÔáÇ£š6(¦Àª¬¬ÄÑ£GYú1øúë¯qäÈ%•’’twwÇ7°(6_}õ^ýu+ñ ‚¤l 1°¶™[·nqy4"Öö`±XxuEÄÀJ|ÃÃÃK–'JFÑ ‚æÊÏ[`dd„Óçaýc‘9øy LNN"##ƒAIíÈ‘#hnnÆ /¼À&a¢2›Íœ¯œ@zz:ìvûºöa`ÅÙíÛ·#cìˆh}Xqäóù T*#« ÑúlÉl ˜œœLºÂ‡Ã8yò$ëˆþßzWω)°?¯÷)áää$gw "äääÄ/°¢Yù9s '"(•JÌÍÍA©T®iû¸ßÃòxŸ5AD«‰Dƒ›XápSSSÈÈȈê$ˆˆÖr³!ƒŸN'pèСÇn_TT„ÖEeCR5())Ajjêc·/--e÷"ÚšÀZ°Ða”ˆ(᫾¾§NbiцÑh4˜žžÞøÀ:sæ §D&¢ URR‚îî¢¢5o[^^ÎþXD´*‘H„P({`ù|>ôöö¢··xê©§Ö¼o^^zzzXDôX™™™Läõô2 }$Vš{y%B¡pÅÎ¥DD_àÄ|…%•JQZZŠÒÒRäçç¯{ÿ´´´eÇ -¾(Œ=°buàÀÜ»w5BD+²ÛíÐjµ[X …‡5BD+êééÁ¾}û¶>°Vš:‚ˆhñVzzúÖQ46|åg"¢Í²á+?¯•Á`àD"ŠßV,´Zí#ㄈˆ  B$%N`åææbllŒ5CDðù|J¥‰X*• n·›5CDŠ,˜ED´“ÉôH, Ê›î'òt°³³eee,a"ÚtQ–L&ÃÁƒ###QyNNÆÇÇ‘““Ú ¢UEÕ$ …ÐjµÐjµP©TQùO<ºº:Öm^`m­V …BÁZ ¢Ä,""1°6ƒÓé„ËåbM ¦¦/½ôÒÆÖF ~þå/‰ï¿ÿžµDD¯× ™L¶ìg[6øyH$B0d-€ëD¬´l ïaѶÁÀ""‹ˆv¬åæq9°\.ªªªPUUµ!S$¿öÚk¸ték‹(Éuvv¢´´tÅÏ£zJ˜’’‚óçÏÂápì—yB!B¡k‹ˆØ$$"цš™™F£a`QâYvñ‰„ ¬ÌÌLÜ¿Ÿ5F”ÄV›Ì3a«¬¬ ííí¬1¢$e·Û¡Õj7/°6råg™LŸÏÇZ#Jâæ`AAÁc·ÙòÁÏ är9XkD”øMB8zô(FGGY+D”ø•••«ÕÊZ!JBf³yÕ&aB–R©Ü°&&m/Á`ð±].°t:¦¦¦XsD´¬¨nº»\.ÔÔÔŒF#Ž;Æ’$¢¨ùý~ˆÅ«ÇQB ~&¢ä6::ŠüüüU·K¸¡9ìñNDÛ&°4 fffX3D”ø•ŸŸ³ÙÌš!J"wïÞÅ¡C‡¶_`¥¥¥Áét²‰’Èøøøæ_aõöö²g:ÅlµY6$°D"„BN©EDÑ kêÒs`­9׃O ‰’Çìì,ÒÒÒ6?°6 —¯'¢mXÇÇ­[·X;D”øEDÉc­]XD´åÔjõš¶MØÁÏ ‹«ò)$ÅXñüœ——£Ñˆãdz–ˆ(±›„ååå°X,¬!¢l-“öm‹À"¢/ A 0°ˆˆMB"¢ SWW‡ŠŠŠøVCCÚÚÚ6í‡yñÅqíÚ5Ö*Ñår¹’’²æícZHµ¼¼|SgkËåðz½¬U"Šý K¥RA.—oÚÉI$øý~ÖÅXDD ,"¢íX»wïÆàà kŠˆ?°rss9 3ÑÔÙÙ‰ÒÒÒuí“ð+?gddpùz¢Èl6ãÔ©S›Xñ^ùY,¯kÞg"J|cccÉd;«I@gg'k˜hÉÈÈX×ÀçmXéé阞žf %¹mX\¾žˆ¶M`ÅXÕÕÕ0q9Ñ””¸\.ÖÑpÿþ}dff®{¿˜»UVVbnn..?`FF&''×5²›ˆS?öìÙ³s›„ÅÅÅ0™L¬i¢ ··7ª‹mXJ¥‡5M´¤¦¦îìÀ""ÚVÅïD ¬u ƒ˜œœÄää$œNgÜN¶  ÃÃì5"ÖÚù|>tww£»»cccq;ÙââbÔÕÕ±Öˆ¶±©©)ètº¨öª[ƒB¡ÀÉ“'<èOO999‡ÃëZËŒˆ‡ÕjEVVVü®°¶’X,F0d­mSwïÞªÓè¶ ¬¬¬,´¶¶²Ö‰¶)…B­V›uäÈ‘¸Þ7#¢ÄÁ~XD”ÏÁÏ‹qa "ÖºUVVâèÑ£q?é}ûöq\!Ñ6äóù •J“«IÈ%쉶'›Í½^Ÿ\EDÛÓ7°{÷îä ,6 ‰¶™Lu/÷mX\`•(ùD54g~~ÝÝÝ€ááaÆýÄÓÒÒâ:𚈶^TWXB¡©©©HMM…B¡Ø²“ÏÈÈ@{{;k‘ˆµ2‰D‚¢¢"ÅtÇ?V'OžD?k‘ˆµ=(Џ-„ADÑs8HMMMîÀ*))áÓB¢m`xx2™,¹k×®]œ…”hèïïÌ£—´*• n·›¿D;ܶüü°^xõõõ¬M¢´µµ1°¶jðóÃd2æççù[I §¥¥eK¾g|||ÉëÎÎNLOO'w`%’sçÎáÃ?äÿZ¿ß¿ì¿×ëöíÛ+x0vnAUUULçù°ÆÆFƒA„B!ܸq/^Œ|¶¸åc6›155…¾¾¾UÏcñϳÜw?î|öõù|›6+ðŽ ,@€³gÏâÎ;ü߸Ãĺâwccã’×ýýýøòË/ …`Éôµ|×ÂñÆÇÇ100ÇÙï¿ÿýod»††´¶¶Âï÷Ãív?v-‚Åßëóù"Û.>Þ‚P(„ÁÁAüûßÿFkk+îÝ»‡;wî ¦¦n·333¸yó&‚Á —üü‘n@Ëý¬‹·]øîÅÛ-w> A622p:°Ùl ¬Õàþýû\Ò>J@‡ã±Û­µÉÂq‚Á ¾ùæÔÖÖ®ù\jkk1::Š\¾|—.]‚ßï_Óù-ì¸wïþö·¿¡«« ããã¸zõ*ššš055…ÎÎN\»v-²_uuõ²?Â`0ˆ[·nÁd2a``.— /^Ä—_~‰¶¶6Øl6TWW£­­ ƒƒƒÈÌÌÄ7ðÅ_Àf³Ád2! bbbbÉq‡æ7"Mº¡¡!´´´ÀãñÀd2áïÿ;æææðÙgŸáàÁƒøñÇñÍ7ß@£Ñàĉøâ‹/ðî»ïB*•â믿ÆÐЪ««‘––†˜L&Ô××c||×®]Cmm-¬V+fff`2™"÷ºÎñ¹Ùl6tuuEš ¡PV«èêê‚Ùl†Ãá@]]æçç144éØ}éÒ¥˜û`€èwÞy'–twwC  ¤¤$!þÓ¢¡¡2™ iii × q»Ý‘¾(}}}Ðjµ‘%Ëìv;<Od¸ÓÌÌ zzz ‘H"ï¹Ýn455azz …b±B¡>ŸMMM…^¯Çììld£Ñ§Ó µZ‚G†TÙívttt ­­ .\À“O> —Ë…[·n¡¨¨õõõHMM…ÑhDoo/ººº  1>>ŽžžTUUáØ±c…D"Á|»ÝŽææf´··Ãf³A£Ñ ¹¹ÈÉÉÁÈÈîß¿“É—Ë…‰‰ ÌÎÎââÅ‹¸}û6, ÚÚÚ V«qóæÍȦ`0ˆþþ~x½^èt:|þùçÈÈȼÿþûèíí…ßïG{{;”J%æææpçθÝnèõz455Ááp@"‘Àl6£¾¾.— J¥W¯^…ÓéħŸ~ŠcÇŽáöíÛøì³Ï`0påÊôõõÁjµB¯×Ãh4B¥REš^.— ÍÍÍHOO‡^¯Gcc#œN'RSS122‚®®.´¶¶bbbáp}ôär9”J%\.zzzpåÊ8NˆD"\¸p~¿W®\AQQ>ûì3dffB¯×£«« N§O?ý4„B!šššPTTéP‡áp8PZZŠÖÖÖÈþøcV¥r»ÝøÏþƒP(„œœ|ùå—°Z­H$¸wï:;;QSSƒ¬¬,|üñǨ««ƒN§ƒÇãACCt:ü~?._¾Œk×®áàÁƒøôÓOñöÛoÇÞ’ ‡Ãáõîäv»#Oå~øá<óÌ38þ|B])´¶¶&Übb±J¥2òW{ïÞ½èïïÇB¤§§GÂxð0! !555òžD"R©Daa!177‡@ ©T ƒÁ¹\Ž{÷î!###²Z­FZZ, 155ùlAzz:är9¦¦¦°gÏŒŒŒ`zzz½v»*• 2™ ápyyy„V«…ÍfƒX,†Á`ˆÜ#ÉÍÍ…Ýn‡H$‚T*…V«…H$‚ÅbA @jj*\.|>rss!‘H`±X"ß5==#GŽ@*•¢§§~¿¹¹¹P*•€L&CQQÚÛÛ#Ÿõöö¢¸¸6› N§ùùùÈÊÊB__žzê)tttÀëõ"==yyyhkkƒT*Eii)l6l6ü~?„B!‚Á öìÙƒP(“É‘H„ììltttàÈ‘#ðûý…BHII×ë…ÕjENN fggaµZ!`00;; Ç©TŠââb´··#33‹Á`R©GŽÙl†×ëEnn.:;;#S±Ü¿J¥z½óóó0›Í(//‡Ûí†Éd‚\.Gzz:Äb1ü~?¼^/ \.Ìf3rrr R©ÐÛÛ‹ÜÜ\Èd2ø|>ÌÏÏ#==^¯“““ÈÈÈ@kk+***àóù`6›a0™™‰»wï"++ b±sssèêê‚^¯‡V«Åðð0 Cä©×ëEJJ „B!úûûQ^^Žâââ­ ¬p8 ŸÏ¹Ô“H$ XD´3E5½Œ@ ˆ4kÄb1K‘ˆâ‚S$‹ˆˆED ,"¢X‰2ø™ˆ’CLø*++9Û'±IHDÄÀ""‹ˆèÿEuÓÝår¡¦¦Àƒ™Ž;Æ’$¢Ä ¬”””È`ç(ÆN±IHD ,""‹ˆX³Ùl;b­3"J‚ÀÃää$K‘ˆâ"¦ÁÏO?ý4†††XŠD”øWXDD ,""í¨ÀB]]Ý’÷¼^/._¾Y<•ˆh+ˆËV»ÝndggÃãñ<ÒUÁh4â¹çžCCC€G?£­­¥IDê7¿ù òòò––\.G8†D"Áþýûa2™"WV6› jµ:²¼:°tð3¼õÖ[Ë~ÙÕ«WñòË/ó3~ÆÏøÙ²Ÿ444àôéÓËî—‘‘ñèVNNNäo¿ýóóó°X,P©T˜œœDyy9nß¾C‡-{Ð={ö,û¾H$BaaᲟµ··s?îÇý’|¿P(…B‚‚‚µ7 ;sæÌ’×ååå°âœW‹/×¶ÒÉs?îÇý¸…Â5‡ÂëœÐ* áûï¿G8ÆéÓ§!‰333¨­­ÅÞ½{QVVÆÆ7­Ëwß}¯×‹ ¸¸ QSS©TŠŠŠŠõwk°ÙlP©TÐh4˜˜˜ˆ¼_[[‹óçÏ£¯¯%OËÞ«¸páü~?Z[[át:a³Ùà÷ûa6›Y@„£G";;iii‘÷úûû‘——‡p8 §Ó¹þ¡9‰~¿¡PR©333¥RÉ5 iEáp6› ápíííÂÈȬV+„B!þøÇ?B§Ó± ’XOO ‘P(„‘‘Èår¸\.ƒAˆD¢õ_aét:¨Õj(•JèõzØívØív¼øâ‹hllĉ'Xò´ìº½{÷Âl6Ãáp@§ÓáäÉ“(++Ã3Ï<…BÁBJrv»·nÝÂðð0B¡PPP€p8Œœœ¨TªõßÃ""Ú*ÿåËg ·”>IEND®B`‚snd-16.1/pix/sin3.png0000644000076400007640000002455511147553270012535 0ustar bilbil‰PNG  IHDR ×`s bKGDÿÿÿ ½§“ pHYs  šœtIME×  !|øÎ  IDATxÚíwXWÛÆoXv)KS¤À‚šÒDƒ –E}±¯5Š, $yAbÔX^E1‚(¢cAÆ.*X bA”Þû–ùþðr¾l°¡ìêó»..9sÊ<ç̽3§<©©©X,~kxee%*++É’)µµµ‰Do ¯ªªBEEЦ>%%%˜8q"?~üÆðgÏžaõêÕøùçŸñôéS²æGFMM ¦OŸŽ¸¸¸7†çææbíÚµXµj>ž™2e 3yòd†aæøñ㌠“˜˜ÈŒ?ž b¦L™Â,[¶Œ‰ŽŽfÌÍÍ™çÏŸ3 Ã0·nÝbÌÌ̘¸¸8fîܹŒ··w“Êð믿2ƒ b¤Î/X°€™?>Ø››3üñcnnΜ8q‚Y±b3iÒ$fãÆŒ³³3“˜˜ÈØÚÚ2Geã+ÑïA´-}ûöEdd$ ¸¸«V­B¯^½°eËö âçŸÄÆÆ¢®®À«nØÚÚÂÖÖ–M£±Ìœ9†††ÈÉÉ‘:_PP€ÈÈHÀìÙ³QRR‚Q£FaôèÑ=z4^¾|‰Í›7ÃØØþþþÈÊÊjX AÈ^^^dyìä%yàŸ¿º AïàÑ£GRÿÖÔÔ 33UUUì4§OŸ¢®®Ož®\¹‚ÀÀÀ&•!** ¨ªª‚P(ÄÌ™3±jÕ*Lž<ÿùÏ`gg‡ÔÔT¸»»#22nnnHOO‡««+úöí‹9sæ`È!ˆ‰‰ADD›®Bk»k011‡‡-ZD-‹¨‡µµ5FŒÿÇ5jŒŒŒ°sçN¹¼çºº:”––¾z СC”––¢®®ŠŠŠÐÑÑX,FQQ€ÏçCMM PSSCee%jjjà3ïßEEEû6¢¬¬ MMM”——C]]^M¼UWWGUU»þ°}ûöàp8(,,„D"ǃ––½Á„¬Àãñê ÃßRàÕ²Œ^£®®ÐÐÐø×ÕÕÕÙô^ó:Í櫦¦555©s:::ÔCDëBo0ÑÆüõ×_ظq#ÀÓÓVVV DRRÚµk‡-[¶ 77?üð`âĉ3f Ïž=¸té ,, §Ñe Ã… Øô¸\.€W˳gÏ >_ýµÔ´€.]ºÀÌÌ §NbÏÍž=lÉÍÍ•êoÉËË£E°TVVÂÍÍ=NOOÿèl0uêTìØ±JJJX±b.^¼ˆèèhøøøà¿ÿý/0sæLôë×£G†……ºvíŠ+W®`ÇŽ¸páÂÂÂàêêÊNŒk(111ضm.\¸€ððp¸ººâСCWWW8::bÊ”):t(´µµ1|øpܿLJP(DPPttt°{÷n)ÿ@-.0úúúR7lbbBOÁÂçó¥Ú‡µµõGgƒ°°0XYY!..žžž`‹-‚’’¼¼¼°aÃèêêbêÔ©€ÿüç?l\†a0{ölhjjÂÃñ±±ÎŸaÌš5 ZZZX¸p!nܸÁ†q¹\Ì›70cÆ tèУGÃ08rä\\\ðé§Ÿ$ ®]»†ï¾ûŽú`BV°µµÅ®]»pìØ1v±£¬óðáCp8V\ÀÃÛ7o–ºNfæõ²~ggg”——¿ÓU§,róæML˜0k×®Eyy9=9Dƒqww‡··76mÚ$åýûÚ)¸ÿ>ŒëfÉŒÀxzzbâĉ=z4ììì0räHøùùÉM‰ÅÞ½{áéé‰Q£F¡oß¾8þ<=9Dƒ>‘ÒÒÒP]]Í~â\¼xQêß²²2ܹsEEE¬k†¸¸8TUUáÚµk¨««ÃåË—!‘HšT†ëׯ£¶¶W®\X,Ã0¸té„B!bbbPSSÖ-11jjjRÎÆ®]»Ö•K«õÁ4„uëÖ!33ÐÓÓŒ?žžž¨¨¨¨7>/kÄÅÅáêÕ«øå—_X;v ãÆÃ¯¿þŠ/¿üR¦Ë_UU…;wÒ¢Á6¢¨¨³gφ‚‚œ1|øp|ˆyóæA__&&&000Àž={àêê ¡P;vì@@@ T/¬OŸ>ÈÌÌd§xË"999(//o²o]‚xm.0¿ÿþ;Æ÷Æ0.—‹þýû³îùd¼¼Ÿ‘#G¾üòKÀÁÁ:::øþûï1sæL$%%¡S§NR]mötß¹s¦¦¦ ‚n×®x<žÜºFÔÖÖFII‰L•©²²EEEèÔ©=ámŒ¡¡!îÞ½‹Ç£GÐÖÖ†²²2N:èëëCMM ãÇÇÙ³gUUU6¾……ÌÌÌ0cÆ ôêÕ«Õ˯¯¯òòrœ:u †††ÐÖÖn=©©©Á­[·Ø¿ÚÚÚ&= \.—ÝàKزe <<<|½¿¿?V®\)3寪ªBqq1 Û´"‘Hª}¼vdô±1fÌ©®øøø`ĈX³f Š‹‹!‹333ÖAðj_¤ àìÙ³R«š[###øøø@KK ‡n]¹~ý:û÷Z`bccagg×àt†*S3cKJJ¤”ú}èèèÈdGu[#‹¥ÚGEEÅGg$$$ 55qqq¸}û6–-[àU'|aa!€W#~)))¸sç€W“9_/IÙ·oÎ;×䙼¿ýöª«« ‘H†a°ÿ~ÔÕÕ!** 8zô(€W³‹³³³qæÌäçç#::[·n­W& fòjkkKÍ}]¤¤$øøø48™éè­®®Ã0õ¼z½ %%%ðù|”––ÖóVÖ,_¾¼Éþ[›eee©öqàÀN`ìííÙÁŽ5kÖÀÜÜH$ šš¦M›???̘1:u©S§  €éÓ§£¶¶ûöíktþýúõƒƒƒf̘²²2ìÝ» à ##Û¶mìY³päÈ|õÕW;v,JKKáé鉚šlÚ´ ;wFDDnܸ===ÙØÙqÊ”)ŽÛ”8-Á£G˜•+W6:ÞöíÛ™+W®ÈÄ=ÈŠ-i&ï‡M›¬EZºt)RRR¯[·nxòä ºuëFß!´É(RuuµT/xCöÖEÔçêÕ«o\Ú@„ÀÈ;þþþX±bE£ãÍ™3!!!m^þ×á„ìðí·ßBUUC‡Eff&ìíí!ЫW/Ü»w‡Â_|Q£FáÛo¿EUUûcagg@@WW×Fç]XXˆ1cÆ`„ øì³Ïpýúu6ìÊ•+055ŸqãàììŒììlÌœ9#GŽDŸ>}‰””ôîÝöööR3ÛD`¦M›Ö¨YC$AI©ñ_—GÊ_)A@BBÌÌÌа°0\ºt ŽŽŽˆŒŒÄÊ•+Šýû÷cß¾}ˆˆˆ@II rssŸþ9öïßÈÈHØÛÛcîܹÎ?%%ººº8pàÂÃñeË6lÛ¶mGdd$´´´ƒÂÂB8p€-ÏÞ½{±lÙ2væñßG{ÛD`úôé•FÇ333Cmm-ÒÒÒ¨Uþ q,,,|ï0¢õxñâ~ÿýw©»ÿþRÿª««ÃÂÂÚÚÚèÙ³'{žžºu놗/_"##ƒ½¾±XYYÇãÁÖÖVjv½’’¬­­¡¬¬Œ¾}ûLMM¡­­ ssshhh 8xð ø|>fΜIŸHM娱cpvvnr|.—+µP­µ©©©AZZÌÍÍ©2e+++DEEaРApqqiRwîÜÁ_|Ѥ-Kš¥¯EQªªªH$R®nI`Ijj*ºwïÞäøëÖ­Ã’%KÈ‹ŒŒŒ°víZ|òÉ'MJãÀì®mŽŽÆŽ‹>}ú`ïÞ½ò+0ªªªì>¼ñ!póæMœ}šœÿþýñã?bÍš5€_ý ÐÓÓï¿þ ///¬_¿>>>7nÔÕÕ±k×.¯–ëëë#%%Ë–-ƒ“““ôg^[ûä•§Y¨¹¹¹ÌÒ¥K™òòò•Ά ˜Û·oÓ ^šÉK3yÿ-%%% eeÑñRC©­­…P(”ù]äͦ۷og_¿-.0***0`{ü÷ï3‚àp8RíC&"¶6`†=îÚµ+rrrP]] ‡ƒN:A(²^ìÚµk÷ÆydùùùèС]†‚‚vt—.]Ø4$ ž={ÐÔÔ„ŽŽJJJP\\ à•›.—‹ÌÌLˆÅbtêÔIj$«Uæïn›C`lmmÉÝã‡ò §¤$U£óqgggÖ/ò©S§°ÿ~¸¸¸ÀÉÉ 'NœÀæÍ›q÷î]=z¦¦¦ÈÌÌÄ¡C‡¤DæÉ“'˜8q"nÞ¼ .—Û¨ü³²²0qâDôïßçÏŸÇòåË1iÒ$¯vp  Aƒpûöm„„„ÀÛÛFFFxôèÆŒKKKxxx@EEóæÍ“š£$òå—_âêÕ«­.0yyyìÆpÿ†o¾ùþþþ°²²jÕòŸ>}šu{HÈÇG§NðçŸâÓO?EBB,X€9sæ`̘18|ø0222ðÛo¿A[[ .Dqq±”Àܺu éééMÊÿéÓ§:t(üüüðâÅ üøã¬Àœ8qÑÑÑ000ÀòåË‘””CCClݺeeepww‡‚‚öìÙCCCxyyÑD»¦$幩èê궉w¾ââb´k׎*RÆxí¶466–õ‘üÚ·îë0¨¨¨Ôû‘;qâ>Œ1cÆ4¹ †††àp8066–úÄRTT„‘‘”””Ø9:ºººPUU…¾¾>”••ñÃ?ÀÆÆwïÞ­ç±’† d¤¦¶¶Ÿþy£â•——ãÒ¥KhÓòWTTàÒ¥KX¿~= AÈË—/ÇÏ?ÿÜèxñññ¸ÿ>víÚ…„„„6ó¸}ûv¸¸¸ÔH¹˜^½z!''G®‡4;uê$µ¬½¥a†>‘d”óçÏÃÁÁ]d¨§§‡%K–àúõëpssC×®]¡¬¬ŒE‹áàÁƒˆŽŽ†²²2üüüн{wìÞ½ .ÄgŸ}†¯¾úªÑùkjjbëÖ­8wî¾ùætéÒ‰022ÂŒ3ðÇ`çÎèСNŸ>ÀËË \.kÖ¬ÁÁƒQUU…àà`DEE±iËe'/ǃX,–ZTÕÒ\½zl¶ôfÏžøûû·šÀÄÅÅaÁ‚ôDËݺuƒ±±1{üõ×_C("!!&LÀÌ™3QZZŠððpäççcÏž=øä“OàèèˆöíÛ³¾¡¿ûî»& B|ñÅؾ};’““accƒyóæAAANNNppp@pp0ÒÒÒ°cÇ 8¡¡¡¸qãLLLàëë‹””hhh !!¤Ò*Qõ6ŒäädôîÝ› A4;]»v­wZZZX¸p¡Ô¹nú7lذ&—aðàÁõ– >êåkii KKKöxÀ€Rs™¨† ˆV† ˜2uêÔr‚ i,--/·†WWW‡¢¢b«-þœ6mš”# ‚h Z¼“777‹-bóòòäÎHåååÈÎÎÆäÉ“›-Mp¹\deeÁÌ̬ÅïA,·™;ÅwQYYÉú@ÐäéîÄG*0úúúRΡLLLäÎHuuu(++C‡¨Å43|>_ª}X[[“Qè‰ ‚† ˜¦1fÌDGGËmùÕÔÔØúZ’ÚÚÚÚÑ—ššzôèÄÄDz¢I`šCCCÖËWKråÊ•ÙËÙÛÛ7nlñòè~`””” ©©ÉzY#H`äŠÃ‡câĉd‚ !‚† ‚ ˆR`¬¬¬ðøñc¹ÞkIOO¯Åg7—––¾q› ‚ yjjj¨­­mQÇSñññR¾/š777ìÞ½»EítöìYÖ·AÀȉ‰‰ähJ†9zô(œÉ$0ÑüTTTÐV¾2L‹-vôóóÃÇë—ÇÕÔDËA«©I`š„¯¯ïÏËãjj¢å ÕÔô‰$Ó4×n‹m…ºº:Äb1ª««[$ý{÷îÁ‚Z:AÓZrÁ`]]RSS[Ô!T×®]QSSƒœœœàï¿ÿžZ:A#kˆD"äåå±{òAC A$0r‡ÃiÕmdå‰DÂîwL$0Mä›o¾Áþýûå¶ü}ûöm‘-XÎ;‡Aƒ}ÐÞì¹eÓ¦Mðòòjñ|Æ#GŽÁ ˜‰{÷îÁÜÜœ A$0AÀAÓ\…B<}ú”ý‰DÍžG¿~ýºº:ªÑ¿Q^^.ó+%‰Tû :ü°hñ­cËÊÊ"Õè›---”••a¹­kkkܾ}»Yû9rDj!¡,R[[+Õ>òóóé©$i8:::X³f {|ðàA¹0Ì™3g0bĈVËoÀ€¸~ýúG·šXUUUª}œ;wŽžJúDúð)))!?¶AC A$0òÊÆåÚ†jkk! ›%½ôôttëÖZ8AÓ´oß………Í–^rrr«z‚ëÙ³'rrršíÈÑA#ä§§“ÿ`‚ !‚¦èر#^¾|IµJ$0ͽ½=bbbä¶ü...ˆˆˆø×é<|øÆÆÆàóùÔ YãæÍ›°µµmõ|­¬¬pçÎN^^´µµÁãñ¨2‰6E‰LPŸ_~ùEæ×ð ^-n<~ü8{\QQAV'XêêêÅ‘Qè©(*¢]»vì‡Ãi±¼ììì+×Âårÿõd;¡P.—+÷«  Ðjíƒøß`ø|>FÅ«ªª¶X^-¶Cbk1sæL„††bΜ9MNc÷îÝró‰Çår¥ÚÇO?ýDO%½Á|¸Ü¸qýû÷'C Ló“ŸŸ]]]2AÀÔÇ××~~~r[~eeeÔÕÕA"‘Pë$H`dO?ý©©©r[~;;;$''7y´íÒ¥Kppp –MÀÈ"þù'¾úê+¹-ÿÉ“'áääDIÀÈ"EEEh×®‚ H`ÞpCŠŠ°··ÇåË—åöŒŒŒðüùóFÇ«®®—Ë•›90 Œ\¢®®Þ¤>Œ#GŽ`üøñm^þ+VÀßß¿ÑñRRR §§G£` Œ,rúôiŒ9’ A$0oÇÒÒñññT»AÓü|þùçxøða£âCSSSfÖÂL˜0¿ýö[£âcîܹԪ ™¡Å×"åççÃ××—=nNÇÜÍÉ;w`aaeee™(ªªj£mUYY)wN¦ªªªðÃ?°ÇÏž=£§’¦áèèè`õêÕìñéÓ§[åÆ6oÞ OOOlÞ¼Y.+FWW?Ã0PPPxïõ©©©èÑ£‡ÜݧªªªTûˆ‹‹£§’>‘‘Á?Ü5(*¶ÎW™ššªªª|}LL ìííe¦b¬­­‘‘HÔ ëÃÃÃ1mÚ4¹k€ä®F>_Í””Ю];äçç7èzy}^9õRTT$¼ Lk¡¢¢‚O?ýIIIï½644ß~û­ÌÝüyó°}ûö÷^—™™ .—‹Ž;R‹&H`Z ¤§§¿óšüü|‘¢íaeeeÐÒÒ"cÀDó"‰póæM 0 ÕóNMMÅíÛ·©H`¢ùÉÈÈ@rr2‚† šy˜NC͈¿¿?V¬XÑ*y={– NC|L4uÃ=‚† ê1gÎìÚµ‹=VVV†ªª*JJJZ…H$‚X,nÖ2ˆÅâVÛ~GÞQ"ò@nn.Î;‡üü|$$$ ,,ì­{(ñù|,[¶ K—.EVV´´´Ð¯_?6ü“O>££#µ­F"‘`ß¾}ptt„±±q½p‘H„mÛ¶A,ÃÓÓJJ¤WÛÛDtt4Μ9ƒM›6ÕÛvW,cÏž=xñâ–.] .—Û tëêêððáCøùù±çôõõ1lØ0|öÙgðòòjP:kÖ¬”––J9Nòä BBBš|ßÖÖÖÐÐÐ`€yzz~TõÎãñ¼Å²óŽ^ªÜÜ\Œ5 ûö탩©i½ð“'O¢´´\.\.WʳýÉ“'‘““S/ކ ‚¡C‡Ò*Chkkc„ ŠSXX___,^¼[·nE@@€Txll,nß¾ 333<}úTjÕôùóç‘‘‘Q/ÍÕ«W###†††øé§ŸdÞnóçÏG]]ÝGÕVFŒY³f5¨½(ýSñ_Ovrr‚‹‹ ƌӤBtìØªªªõÎëëëãâÅ‹¸xñb³ÜlEEø|~ƒöon 555PTTl±]D"êêê ¦¦Öb ¢¬¬ šššï¼¦G˜ƒžžÞëLMM ººº¨««ÃÒ¥K[¥, ±ÏÛhÊBK¡P‘HôÆç£¥¨®®†’’Rƒß"ßE||<ÊÊÊ/0ï«Ðœœ>|nnnï5ÎÛ62kîÞýyóæaõêÕ-æ[wÏž=066ưaÃZ$ýäädDGG·èÃ$¤\"´%%%Ø·o\]]ß[½zõzëùÖ(ëß»¦M›†ýû÷·Zž¯ßì<<2´´´`nnŽU«VaÞ¼y(**B`` æææ¨ªªÂ™3g0zôh2ØGˆÒû>sþÞ9fii)µuFûöí¥:âÚ‚aÆIM¶’7tuu¥F8äªñ()á»ï¾“:÷÷ö¡¡¡%K–Èô=(((`Ô¨Q­šç'Ÿ|Òê[[ZZ¶ÉÞår?ì#ï[¦ÀÀÀ€~êÚP`A«æÙ¹sgtîܹUó´··oûÒl!‚ ZNÀZLñNJJJÀårÁçóåö²³³ahhHe%H`‚øp O¤„çÏŸÃÝÝ;vìxãįÔÔTDEEáâÅ‹9rd›”W"‘ 443fÌxã„»ªª*lÚ´ ^^^oœ°I4ž¼¼<¶ÞíííñìÙ3dffÂÍÍ !!!‰DHOO‡««ë[‡íãââ páÂ…†eÊ&<<üÇmÁòåË™ÔÔTÆÛÛ›ÉÎή>eÊ©†a®^½Êüïÿk“òÖÔÔ0Ó§OgŠŠŠww÷záIIIÌêÕ«™¸¸8fÓ¦M2UÿGŽavìØ!·í÷åË—ÌO?ýijíÅÝÝ)**b¦OŸÎÔÔÔHµ“÷µ£wA‹‡Amm-âââ†N:ÁÚÚ¹¹¹022bûkÙezzzHIIAAA,,,о}{™¹¡PˆØØØV¢•wnݺ…¬¬,ôîÝ—/_†¾¾>fjjŠœœzõê…ÜÜ\lذˆGhh(Œ¡  €qãÆáÂ… ÐÔÔÄ¥K—ZumMdd$ ±`Á‚7†—”” ;;fff2aÛÒÒRøøø`ñâÅ­>„Û‚ƒƒ‘––777ðù|˜™™á›o¾ðj—Ê£GÂÈÈ1111b¢££a``€Ó§OÃÅÅÏž=c×nM˜0W¯^EûöíqöìYôîÝ{÷îÅèÑ£qéÒ%8::âÖ­[àóùˆ…H$‚³³3ÌḬ̀jÕª&ÏxopÜ;v@SS...$0-ºº:ÜÝÝqõêU¸»»úõë öšÁƒãÂ… àp8HKKÃÉ“'add„… ¶hÙ–.]ŠÅ‹càÀ000@aa¡TßÅ®]» 0oÞ<¯VÄ~þùçmfKeeeLž<?üð¶nÝŠêêj¤§§£¶¶гgO$$$àØ±c2µèqòäÉHJJb׎™ššÂÛÛÀ«õ>„  TWWÃÝÝùùùRâþìÙ3dggãøñãèÖ­¾ýö[”””`êÔ©puu…@ €¾¾>lll0pà@ÄÆÆ"##éééàñxèÑ£G“ï¡wïÞìÿþùgxyyá믿†¶¶6¶oß777vajNN['°nÝ:‚;W§Q¤&pèÐ!œ9skÖ¬Áµk×°xñbìÚµ xúô)+0~~~FAA¼½½aaaAÆ“s®]»†ÄÄDÌŸ?€ô:/‘H„   Œ%K–Èï%‚hRRR`llÜd·¯Ó022’«½¸ÿ?j £eà¿ÀIEND®B`‚snd-16.1/pix/fmeq43.png0000644000076400007640000000034111147553267012751 0ustar bilbil‰PNG  IHDR ðcZ-PLTEÿÿÿàààððð€€€```ÐÐÐÀÀÀ   000°°° PPPppp@ŵ pHYs  šœtIME× 2 ù¢ŠSGIDAT×c````TÌ ,@:Œ­H7090i¶¦$'Í] ]² Õ»ö09(2°2(1°01€Á³eÀ -Á!IEND®B`‚snd-16.1/pix/sceq40.png0000644000076400007640000000212511147553270012745 0ustar bilbil‰PNG  IHDRC"ò2K~3PLTEÿÿÿ°°°ppp```ððð€€€àààÀÀÀÐÐÐ000@@@PPP    ÀgF pHYs  šœtIME× ÇˤµIDAThÞíZ‹r¬ ’@Ýåÿ¿¶ èú@ÄÖé]o73ۙ⭇˜îI:Þ5œeVÃK:g8¸ÌCƒÉsc(˜ÖkE—`À‹ûã=?}Ÿ\Ø÷­±öáIq4TëdK€ÏP»á)À—nãņ̃AÊ1ŽïàFØþAåýohMßÌÊAóL«Vi8 Ÿ>¼“n¤óÅÇ3œõN¿ÊÃ.n„íTÞÿŽÖöb™Ë’d|¸‡¾ðøø 2°Ý»xÕÐ.ÂJ?~3uø|š…› Ñ.9” ,‘}ª§÷Ьž•„\‚*ï¿8ó_²[ôÛû¶B;Á]£ù!5õÁ9=ÈùXFÉ{¯æßYNÁ¼K°ÂAåý—2H±Çȳ¸c¦ŸÃÇ‚×ôr˯ÎQŽÅ›Ãå3<‚mZ_æ!•ÕÀ¡ÏüÎk‚Ê áq] ÑšÙê”Ý{ä•ßîuÐÞiz&‡9!<­Ošè¶}È*%þCTž?J¤°tkº^CÏá(rašÔäRbÅ-&eIú®ú&(|"WåjGëm/-Ì“OÚU0÷–ûƒöq‰jW„…‘rº‘ï»Âì’C¤Fçêb=tl3-Ìvú1–‡JM.ØZÔ9‹žB|iá‘Cñ½ž Ur0¼+‡RÄ"A4S;)VuZ7ažòÒ‰;ckëßx¿ßæpˆ¿f©mÂh /PE¬¿}˜*LZ8f(´¸éS2“‚ód®Dr™C½Q´—Kl[ú ,7(ññ@Zé—3»jçÉF¡¨j1xãÿˆs±E{½¸áe>˜Øöîùõðƒ3vfôÏÝî¢zžìo¦ŠCTöâµ¢½>šØ/.'ÛQåIÛöÛ®/^ëçÉBj®L~Ç&EûæSZÚ:n¦Ñkõ<™:Ÿ£+ÂÏ`‡£¾µ£×z#ïÊ®«‰‚:ƒ»[½žÓ |¬–Ÿ<tÌaT´÷¶4z=‘¼ªªVã‡QÑÞÜÒèõŒ#:ÑÖ”p.û¡ëžÄIÑÞË\Nhž &}÷"ðÃfËÂÇN‹D¡}[ˆ<ýÃDzŽ'hÁÛ‡ÃoX£¡Eøøá´ zÕn?œœ³/š_"^ËܶIEND®B`‚snd-16.1/pix/ampenv1.png0000644000076400007640000002535411147553266013233 0ustar bilbil‰PNG  IHDRȳCßÄË pHYs:ÊduhtIMEÖ ‘ IDATxÚí}yXSWúÿɾB6‰l‚ *×j[µJ]Z·±Øjk;µNÛ±¶Ó´¶3]i«uæ«í¨}ÔVq©Zý¹ÔÝ*‹ ‚ ;¨($¬!’Üì¹ÉïkcšõØÞÏÃÃssóÞsÏ}ï'ç¼ç=ïyáºáºÅf ÕjMF7 pàø 2™,""Âf³yhll$[l–}' ¤ÕŒj\›8î±¢Q+´V­'¼ÿ—GÆŽ¬¨U×­s•Ыô( E®Mv fT×£CLnXÁä2‰$"à.±t=:º”Îpœ‹ £¶€¤#áÚ| ¤E©,*jCÎÓCéidºÊ£¨˜ï Àp´a΢DH:’ëyE—wÄ \»¼Žë‚T7ç‘눀*0[ÍâC®»Â]…®'ÛjÛÜ «ÚTz•¾we=“‚#)‘”ˆJ[ÅvúÖ™XéÃ1QQDè& %E\Ý{µ±¸QV.»uéVgC§º]ÿ}~ÇÍŽ¶Ú¶]ÝeS·«ùô—ú õ€+?^‘•ËŒˆ1ÿûü.iWaNáùÿ;oDŒváú õåÇÊ»¤]Å·.Ý䟳àæãP9Ì•d¹ÅÒ"5K¥fiå­J§KÈNŸ»”]¥7JV‹•êGå„r††jÚëÛwì`vcIcü´øŠã"a ò¶ä‹ƒÓþ’f—d±ÂG…ÇŒ)ÜUØy»³æ\Íøåã­¨µ§¥'41”¡úQ1IƒÆpçêˆÔˆº_묨ØÀÍü›Ó^›¦ëÑ 1b‘¤Ü+¹T?j7 òçK鯌9&2ú‘è°¤°¡¤ŒeÍÍd9j\”Íf#“Åf³Ù¬6ÔtÏ>%’ˆ¥¥ªÅ¨5N\9qòË“é,zÂc Š; “f³Ú¯6š æš³5€„Ç4r &#†@$‰D‹Éb³Ú†±¤f©[>˜ fìÏŠZ}´XC!q!¥?—ÆN‰%QI!ØÁìŠcÑiÑÊFeù±òÄé‰vá”ù)Š;Š)¯L¹º÷jXr?š_úsiü´x®ˆ[~´<þ±xù-yÕ©ªÄ'M:“Ï/,)ŒæGOó£ùW÷] ? *í±öÈïÈQøú9}K¸Øy1¿+_ߣ Dtúu:û±<œÇñ0ÀÚh  6«ï÷|éÏ¥d‹Ùj Eih˜)(¢3ȵt®·ÛÝyC~AL‹Âb4™ Ï[Ø6 jô³øE#ÈÜ„Ž JD¨æ>9i:®M½F^iQGP·Öª•µÉˆ¸:p<àÄÂñÇËh4~öÙúìì ÙÙš›[ß}·Íh4ÔjÍ_|sófÌ ÎŸÏÅ ÉÉÙo?YPPˆ•³mÛ=Ï$6¾ðì¹¼»ï¶m»ÔjÍý>-Š¢Xe*+«Ý~k?î]ùƒ˜’U*ueeÓWÙÙJJÊúXƒ100@"Y#‘¬‰Â ã‚s¨T*€ÍöÏÌœyãÆ-LR©ì’Ë;u:÷^ÁââR¬¬¬E€®®n¹¼3?ÿ2€@ ÌŸŸ‰‰uuuôÑry§çg¾ÉZe&“é©§fúùùl6›\Þ)—wšL&“Éd±Xž*óõ×ÿ‡Uæ—_ΘÍfÑÊå ¸uëöúõ›ººº^ÊÇ.A-@£AäòÎîîž!D¬+¿«Úl6cŽ¢VÀªU/—œôæ ÞüXgÎüªR©.œÝÚÚö¯}±qã×Îïf… KÊÊÊi4š\Þ)‘¬qÛòego â¿øâ²ŠŠª¼¼ËL&3?ÿʻªš;voÝú_@^Þ¥ººÇŸ~á…,/U:{ö‚D²F&kùôÓ¯ßÿ­ˆÑ‘#'06˜Íf‘Hºuën+㈢¢k5*¹½½cÍšWOŸ>_UU“—wi޼̎ŽNOåçç_‰77·¾ýök7n ˜ÍæÙ³§‹DCÁ™\XXœ½¡§G5r䈜œýX(‹ÅZ´hž'½1Œû&ÖôéÓV­z;6,*##ÍUæöí;MM²€NS“Ôm!4ÍþŽe²–)S&&''b-SFFZnî%ì«yó2ëênzaÕŒíÞ½ŸÏçÂÃæL™€//¯¤ÑhX+% [·þ©Ç… çOœ˜þ¿ÿm3™ÌYY‹‰Dâ¼y™Nå×ÕÝÀꟽA$>ûì¢ääÄìì d290+—wp†ÈÄWzú8‰dTÚ\PpåÚµë˜>µZ­½õ†XŽho飼»qñbþܹ³ Caa±\Þ9aBzHˆ€N§³ÙþK–<ãöB‹ÅrîÜE@@‡ÏçUUÕttÈ ®°¦®îÆ­[·KJÊÆŽMÉäsç.²X~ééã\ˉ:tlêÔI…BYUU X´h~L̰`ÀèÑÉ wòò.…††466¹­LTTV:8~ü”Á`@-™L ˆöر“‰‰ñÛ^¾H†]ÂbýιlµZ9¶X<¬¹¹µ±Q–””0Äì­¤¤±x`âÄtÀÅ‹ùuu7ÚÛ;\õæ„}I¾Q"£Úb3üX(Švuuñí6ÐíÛ€±cSL&SEE5 >>–Åò«¬¬6M"‘0$Dàzƒ––Ö¶¶€¿?+.nxMMN§ „… ¥R™\®ÀÎ:;MM2ŒdžÈÝB¥Rc&|JÊH@YY`øð‡ÉØ%]Y Ã†EÕÔÔ«T* 88˜Je¢MLŒ÷T>€J¥0 ¬|§ú`Ï…™’T*µ®î`äÈT*Õ‹ÞýX7b¤Z«6oKžGb•””•—WÙ?>ýôS\n@/êê8î ›>}Z/ )/¯r’dfÎz3·k×>“ÉŒk4šÙ³g`tÁ¨­½qùr‘£!îÆpÄ~rnõæH,MYBB\dä=>úûû÷®ºsæÜÖbhié 0CÀ¸\®Ñx×ìg³ýQ5ŒÍØÉc.šÔÔÔ3gÎÀÔ#1111ñîÊ>©T𙙉k¨+’!`pjІĸ@]ÝM*•VSSg[ð† ‹ €Ž¹—ÌnN¨¨¨ˆ‰‰Á"3qà6àñxQ¿9åm6…BµZ­z½ÐÕ¥ˆˆˆ€æö 6477—••¥¤¤rrr^}õU??¿¬¬¬ììl–••…¿ƒ‡—XD"¡­í®£Âb±‰ÔÀ@¨š5k~üÕW_a"‘H"‘àÚ¸Ü 8pàÄ N,8þãýƒ\.ommmooÇ_ Þbõ'ioo—Ëåø‹Á‰ÕŸ6lØÌ™3}ôQüÅ<]aKKkssóoŸl£FƇ£ˆ¥Pt:®oa±X¸âpà£B8±pàÄÂ'œX8žQá†Â‹/öôôà/'V"=====]*•ž8q7xWˆN,8±pàÄzPøå—_`Äš››/\¸#yðàAHÉ·ÞzK¯×÷c%•Jeaa!d]]]0’|ðR©ìÇJêõú·Þzk諲²F¬»»ûÃ?„‘¼víZ]]ŒäL.\¹¢¶¶vëÖ­ž¶,p„V«]·näSoݺFòÈ‘#®é²]ÑÔÔtøðáÚÚZŸ’eeeùùùxWxŸÃ`2Û½Â'RRR:Ó=z´¡Á÷0{÷î½qãÆŸòÔjµzÛ¶m0mÛÎ;ýõW™L6ĉuêÔ©þ (õóóƒù‰ÊÊÊú—MMMƒâ·?Ä»B©TÊb±`ú#xh4šÝ»wðW»yófHɘ˜˜Æþþþ€¯€Çža@)ÔÉó^YYù믿Â\xöìÙ'žxòjµÚ§ØÏ?ÿþgérîáöíÛùË_ŠŠŠ¦NêS8-- ¦Ì7feeõ}òc`µXééé‰äÕW_u¤À\h0¼ä&q$SFã¥K—`$Íf3…B|@«Õê}÷<;òòò`Æ Ã‡‡É‘——7mÚ4ûJtï£Â‡Â݉êêê7nܾ}»Ëœ8q¢§ˆ±~ýúµk×j4Èzž:u FòòåË0bÛ¶mƒ1´±Ò¬V+L™\.W(VWWãÄ¡PØÚÚêû‰D.— S`rr2d&À·ß~ëS†ÇãeddôïSÃÜ·fÇkllĉu×*‚ÔÚüùó ŒpUUUUEQF=ÀÕøÌ3ÏÂÂúºýâÐ!ÖÍ›7!%;::à›¢þ‚ ‡à:ܽ{÷ðáÃË–-ëãØŸ+ˆ°'7üƒáh®õÑGúÐ K׿’ýŽ9sæô{™ãÆ †œ‚Œ‹‹KHHè‹kú¡#ÖŒ3ú]²±}ûvO† ˆD"IvóæÍ––a*•ÚÚÚzëÖ­^?Å  MV«Õl6»åçææBJfgg?~üOQ‚Ñh´ÙlØF×0 (..6 ØfÄž@"‘¼l³ëˆ)S¦ôËS t)àôéÓ€ˆoÛP(ÌçT\\¼oß>ObW®\°Ùl³Ù¼~ýzŸ“!3fÌèèèøç?ÿé½%3fŒP(Dħ k«ªª|`Y6wìØá}dÊf³KKKFã¼mØ­ÏŸ?ïE?§OŸ¶;Df̘ßp¾®0((¨¬¬Ì§X||ü´iÓ°±¡OŸõ«¯¾úÕW_½õÖ[mmm>ͬiÓ¦mß¾ÝËǸqã,XP__ÿŸÿügíÚµ> ìììܸqã§Ÿ~ê]R§Ócjjj.\èýWŽ p𴸣±±±¸¸;øá‡jjj|¸mÛ61³Ùœ——W___ZZ 3ˆËËËóäpÑjµ˜·sâĉo¾ù&‚ f³ùA¿¸Áa¼744O~ ŽŽŽ³gÏb™½;öã?zŒa0ñññ>»B±Xìçç7oÞ>žN§ÃÌÊzq¹Ù]M9990·ÎÈÈð2Uøðáùóç?Ärœ®Ú²e‹÷ѯ}päqÉc÷šŸŸ?nÜ8˜1׆  kûÜsÏ­ZµÊ‹Àˆ#°Æ²­­­¸¸ØÞÊú¼Ä'|>2 ÚÛÛCBîíè<4‰uìØ1û1Ì$ üÄŸ»úŠ+RSS}Š­^½ÚÏÏ/""ÂKžzê©ûzüo¿ýö~/ÁêÕ«=ÝÎñ«ØØX™LÆ=ýXŽA#jµzáÂ…qT@ xi*ìÞéÓ§ûŒ5HOOÿ׿þ…uŽn¾ù欋Åo¾ù&L ×ÃÁƒ!÷žñ÷÷Ç*ã¤FAüýýO †^[cƒ›X.\øòË/íOœ8QWWç–.eeeØÐ 3a„´´4×è¨;vœþüäädWóÕªUv£þ‘Gq«@OOOSSSnn®[í=£Âšššìßàê>éèèxå•W ‹=ztGG‡ëÛU(>°úúz™L(qêÔ)¥RyéÒ¥¹sçz—DQrVOìaI$FKKKÓétN†‚ N“-Àmi›7oÖh4_|ñŒö<2¸‰•˜˜(ù Nžw¬{òtáO?ýd?æñxØžunå8cµÐéô””ïŽ~Œ±±±;vìHHHð.¹oß¾%K–H¥RÇ“‹/v•ÄêUžÅbaÎ3…BávàâXàŠ+<ÝýÚµk0Ë úé'×B/^ìTíAߪÕj§Vç¹çžsÛ¹sç;wìoe̘1žB4E"Lœ±ÝµñÁøƒŒÚ“Édááá{öìqºÖ©],//g0·nÝrmn]1|øp{O?ý´ëOÑŽ¥K—ÂTÒ®F§J:U{Ы©©©¤¤ÄñŒP(tíPc‘t:ÝØ±c]KËÍÍ ß²511Ñ“}íˆÐÐÐeË–9¸ÚCŽc±%K–8žq yÕh4F¡PFï÷ýþûï±8O‘HÄår—°¿¿ÿöíÛ333íg–,Yâ4úÊ6 ³¸·F÷·¿ýͧ0Œ  …òÝwß9n–>{öl§ßƒ½LÈXû¸¸8Ÿo[ÐÜÚÚä3f&--mÅŠŽ!\.×Ë4Q<ÀÉD$½x›k×®µ/>9wî…B)((p+ùÒK/aÑ ^°nݺE‹9 w5‰h4ÚØ±c]SÞ» f±XÿøÇ?`žwÞ¼y0áuÁÁÁ$É窤uëÖ¹µÏ\+éSÏvw—Íf#‰ƒ¾ÅZ²d‰w‡§N§Û²e Ú@£Ñ¼<3™Lž4i’ã×þÎíì5@ËåNŽ‰Ë—/ÃL až3Ù3ŒÑ£Gûô' ‚ØØX§Jº‘Y*L&Ó‚ `ËUUU'Ož"]áÅ‹½Ï×vwwC.óuõAJ* 'óƃ…YNYYYð!ŠO?ýôK/½#éÔ±²ÙìåË—÷NÃgÏžu;r9r$dxê $Vmm-Çsû6¿eË–^þ WÎ;v fµ£}4€½Náµk×.[¶Ì©á i‡DxxxUU•cgªR© ½óƒÃxþùç=™º},¹¾¾~€?fTT”[áÑ£G;Y~íííˬá!“É£O:™‹f`«°°Ð­çÝ-<?M뉚?þø£'+sàTòÎ;ž¦4±cÞ+**ÂÃý Ñ;;;Qýë_ÿêt~éÒ¥N#öŠŠ ¬—Èð'íÔ× …ÂNÓÏÃù[³'NÀ®Ìãp8NÎ$ø¬ñ éúˆ§Ÿ~~{ww·ýØh4VWW÷ÑÃÙ»±€ÏçCÎ7 \bY­VÌA•––†ÍzHgdd8å0‚ÌUäjOM’#zvÒ <èä[{öìq¼äÞÖ˜‹Ån›6mÂ8ù ¯ƒ'k/,hxÀÊ¥¤¤ô1¿ÍâÅ‹¿ÿþûþ­ÿ“O>yúôi,ϪT*õÿ8@[¬ëׯoݺuÏž= Ãíüš=nîܹ›7o†ŒWž:u*¤~ôèÑʃ×××_½zÕuð  q\îçGŽéßÇär¹/^„Ž \bÅÅÅ-X°`Ö¬YØÇGyÄU¦¹¹[ŸÙÓÓãs@ggçž={***`œEEEnb< ØŸN­V———{zyb±˜H$b‹;¢££‹ŠŠ׃ô3gδ;Л››}:ŒF£B¡X°`Á $ƒÁ Äè2uêÔÇÜÕˆNLL‰DÞC‚ÞyçlÁÖçŸþÑGy‰q$œ—Í›ˆD¢ÝAe2™L&Ó;ï¼ãVròäÉØX¬©©içÎÞÛÑ/¿üÒf³}üñÇgÏžõ"Y[[ÛÞÞ^TT;sæLŸ1Ö‹åìÙ³F£qòäÉždìÛØØØÒÒâ%™ùäÉ“óòò CQQ¤“o@ïk×®uÀN§ÓƒƒƒGŒáÅûL $ÉÑ£GÏž=ë=ÌèÍ7ßÄ–˜zA1b„X,nhh())yôÑG?ûì3OaqãÇÇ–ƒnÛ¶íÃ? …^f¥l6›Z­^¿~}[[›÷W€ÒÒÒÔÔTŸ«R5ÍéÓ§Ÿyæ™5kÖŒ?¾ï/büøñ—/_Öh4÷åîL£Bl‚ìÙgŸåp8ãÇ÷nê^½zuݺuÁÁÁL&Óû‚úo¿ýV¡PŒ7.//ÏKLH[[[[[Ûúõëù|¾wÿÙl®ªª*((‰D<ÏËûP(µµµË—/OLLôMÅçó¿ùæ›òòr‘HäåYx<žX,ž={öúõëß{ï=ïÛ<öØcçÏŸÇêà}æ“tZ€?XG…n‘ššºjÕ*±Xœ™™õÄO¸µv ,0 þþþ#GŽÔh4b±ØS™S¦LÉÏÏ—H$'Nœøøã¡Žxá…Ž=¶råJ/‹&üüüžyæ™uëÖ-_¾\,{éãfÍšuðàÁ÷ßûöí?üðƒgÁÛo¿]PPpñâÅuëÖ1™L»£ØõÖØ LUUÕêÕ«-‹'ýžx≃_½zKà ±±±³fÍjkkƒ_Ú ”èK ôˆ™ I5@§s UMMCbb  ®îfNÎO,–Ÿƒ‰Æã±M£G§r¹,.7²¿$•J333+**ŽÁ«Õ¢Rµô$ó ÛE­U›·%OÇã'œX8M:n8±zôôôôôt©T ó‰ï qàÄÂ'œX8pbáÀ N,–«§§G©T§gÁ ííí•••[ÌãÀ»BXÄÇÇ/\¸ÐKPœX8pbáÀ N,8± ´Z-¶Äõ|vvö¦M›èòvC–X»wïÆöâvÂÆ%Éœ9s:„¿ƒ! (?VBB¢}ÁÍfc0(Š*•]æwéeõz=–`ˆÇãÅÄļüòËÙÙÙ¸–qb¹‡R©0› X=­V"´ZÍT* Àfs—ð¢(Še2ö²¢Í-0×(v,—Ëñ¾êÇŸ…””˜µ¡ˆÕÝÝÍçóôz §GÉd2££#Je—czE‹å¸œòÈ‘#••• 111€•+WJ$±XðàAN7lØ0L’J¥bÇ&“)88&O_}}=dHI•J¥×ëa²»ÀßúöíÛáááÞ×%ßW™:N©TÂìPò ôóÆoÀx°¡ˆe6› ‰DêéQ‘HD€B¡ ÀÚÞÞŽ%¬r‹‘#G&%%Ù þïÿ;((0oÞ¼††2™lO¨h'–T*}ýõ×a6ÚËÎΖH$0)YYY)•JaëÿýïK—.…ÙвL©TZPPð'ê§ßºBŒI‘‘‘Ri3•JÁ½ÞÐÐp›N§y¹ÊiÙ¸cj¬ ë#àÓJCJòù|È´Çð·5jFëÇ2Ùl6dÞ¹~×OÚXD"aøðá|>_¯7¤¤¤‰D6›ƒ¢fƒ™”” ‘þ´™lOY z- ¹Õü­áS¾@–™û¯ßõÓŸÄŠÇÆŠÿHºp¹Ü1cÆàfò„P(„Lf4 ÂfŠŠŠ.\¸µhÑ""‘èïï’‚ìܹS­V/[¶ ~ýN·{÷n¥R¹hÑ"û‹Çãñx<A°\Þ:ºð .\H$ÝÝÝX4;rss'Mš$‘HvíÚ…¿é?¥¥¥ ‰dÿþýN_?þÚµk>,(\ƒ>7Øt˜;w®Ï­=¡ˆE¡0)†ýAŒäͽ~½/M… IDATg[lß¾ôÓ^ƒ6–Íl¾·ynCÃÍQ£’ùù—©TJQQ‰X ±C»GnÙ²¥«« ËúÁŒ;vîܹçÏŸ¿|ù2äÆ@ ÍÍÍËåáСC#FŒ¸~ýºÁ`˜8qâ‚ ~úé'2™¼zõjøt±0BBBŽ9R]]åCÔh43gÎÄvà9räHQQQ~~¾§­új¼ëõ‘H¸bų0ne/X±b‚ 4 Ëüî»ïbΤäääÈÈHE}¦Ý€‰DS¦L‘H$ÙÙÙ ¯½öæ„\·n]eeeKK —Ë…ÜêOX,~ùå—- æÚe±XöL-Ó¦M›ÙXåuFô.­(ŠÕ&<âVÒb±˜L¦¦&ƒAçóy¸ö‡$t:}gg§^o äö‰XZ3%8önèê÷ÿù÷£Äyi±8œ€ß ==ŠÚ(j]]-þ2†P T*»DÇáp½¯"V—¢ãË/ç,{åí¼3W.žúèŸÿ@^UU HJJ8~üÔÔ©“ýü˜™¬¥´ôîvpL&‹D"íÛ÷þJ2ù>7wµ£½]¢(‚hL¦»¡ST*uĈØ^‹Áô#S(k_œ«Õ¨N—ÊkÀÎ{-[Ë 0›Í(ja0˜\nnܸ…Ç€…PÚÓÓ)ÜÚÚœ’’ÚÝM5MJ¥Âb±„… {ßb1˜¬ÿ“óþßþÒÙÑÂáò¸ëd—J›ÛÛåŽ+Àh4ZXX@0™Œ6›M«ÕáÄðc=~°¥V«­VT¯×‰Äøøøúúú>u…t²-œGÚ±kOEéå`?ƒ‚ HKcµÚæÏÏ,..³8A¬V¾uÅ18í-kii‰Dê±RG‰hT0%}8mÀD"qüø4öƒÁ`P©T&“‰H$rÀ]£6›Íd2C7o6›Í† ˆJ¥!‘HزøÞ ÁÁA±±q¿‘̃ÇÕ pøù±L&´A& ¡ÓéÊ]æ‰Ä?‚XsçÎÂ_Õ ÃØ±IPmfâ½@¢@¶ÝO‹e2i‘‘B\ã8~gW¬WIÕÝÖ»Ó8Œ¤ÇÅ¡ˆ¥×ë;::í;;qeâp… Ôv£w‰Õ!Ó6’#ì_ A€EvO,*•Š+‡{Ëh«ÍöL¦Ÿ#[¨T² Ö¹‹D"0™\ƒ8ÜÂBø]” ™LôÂ76‡F$’þˆ_€U©Zð6X@„€ºQqw˜Å÷–RÐÓ¨ð k©Õj þ¶¼Ãd2Ù§ËîšÌŒ~pßN£9›ÍæÛãH´‰L‘,ô€_~ùæzH1WlܸçO””Õ^»iÄþ.^ëØ¶}_ÿXá&‰D±ÿ57·»»s§é“O¾îîîéÅ-Ü·X………›6mª¬¬œ3gNxxxNNŽJ¥ [ºtéþýû›ššX,VVVÖñãÇwïÞ]YY¹fÍÇ×===999‚DFFÎ;wëÖ­ƒÃádee•””ØSâðÁ*]m£ „f“飼öÙ÷r›#ˆ¶¾þ& 99±««;$D`2™DK¥RU*U{»<(ˆ!jiimo—3ôÄÄx‡ µXîevQ(:ÃÂî®äs”ŽŽLHˆÕju\nŠ¢Xö±x€J¥0ŒööŽ÷K‰2™Ls]c¹ma2ï%ÐNOOÇò$&&–——ëõúÔÔÔââbARSSãââPÍÊÊÂÄœ–ñ߸q#000555((Èl6···K$’äääòòò’’‰DŸ=ñ!G·²ó­•ó>yûÅw^y&.)5nĽ ‘û÷Öéô:þêÕÒ}ûärů¿æUUÕlÛ¶K§Ó9rB§ÓíÝû³N§onn½s§ æŽk×þS§Ó××ß*))û}g °Ûí߸¨¨+ »ïï,œ:­æº&À?€šÊ‹ãañéN¨««ðùüåË—³X¬ŒŒ >Ÿo0jkkÄt:ÝéÓ§áááÆ ãóùEEE×öI¯Ç!BË z÷óÍ×®\(-Ì]úÒ›$ò½AUjê¨k×®_»vÁpžïŸ>}Ú¤I~~L‹%“É“&eLŸ>-:ª—HO7iRF\œØ)ž½®®»‡ç Á Á¡©¡«…l³Ù+‚˜,w…+V¬ÈÎΞ!!aôèÑ8o`š>åË-‡Žíß,t\ÓÒÒhnnMJJعso[[GLL´«ù¿sç^E}t ·._. Ðë “&e47·æç_nii]µj¥LÖ€$D"a~þ•‚‚B'δ6­ÖªE´¡D_R /@”ÈMʨ¨¿¹þˆÜ¤V«w7xG[›<,<`4èit‘,æ»±S‹Ûo†Ãa—•U ÕÕÕ]VV1oÞl™L6T*Õ`0 F‰è˜·G¡èiiqtu2‡¿›etÆï–/_ŠÉ›ÍfÑ8,Ë?•Jmo—[­Öà­[üûßWÝëˆHæ¶‹Z«6oKžÙlPƒÏ¾ã¹Ë Fhh°Õ¢PÈÀjÑZçŸ$s¹önñ¿ÿÝìïÏzá…,᮫3| †«‡‚Ïàóݧ›0á{± Å~ °GF†çäìW*»^yeÅ}Œ Õj|ùAàØrôiic`n·lÙâ^ú±pàè pbáx ¸×šˆ¨ždÆ5‚£×0Q€þžXÌæ-¶LfsNE¤ëÑ |ƒ]¬¨Óñxz›‹3z«þwÄ"’ˆf’Ùlun±3Â01´V<Vè†Í+ÈyGò%#a}¬ øªúÎZô°ØacšSæ&m:—ÜÖ Lz'ù,3t‰è@ò'µmO–‘Ì[ùUœ+¥¤EܤUie)û8Œ¥ëýiœ¡í<œ6³¥Š+éÁ%êÂÙŠØ5‘%D<:±Ì2ràÍ%²“‰¬la´…ôz/ÏÜÿCaˆÞk»d†ûÛpóˆNb)6Zï}+ž .m!-.²c,ªÚVÙ§YÉ…ÀX(èAM.5¡b*'¬ØÄ°®v`ö7½'û¢4@ÎÆïoímhC†S%卵Gš9ãés„¨H!<~€Ò&&¤.­½@Z2dä+Ò~¹©çzk&’- TÒËcÔùËlÙlM‰F?H>–;ÆjïF‡O‘_¨0p¦4>¶¸bÌ‚àü…>–Y‡,GŸ­ÔWÚ:0r¶ê¡NñHL,] á`T¬B÷ìå\ìÞr6_´ŸVq>]Ò Xu.–a¾L2ÏìâÔÅùf7§Ãft.›&6,}Áu~Y6Úó;¹é¸ý÷þð“Èøw!þ?}–ôýdê_®¼zõêøø­8d’%¦—hrà«ã3G98º=Œ”9üPFý5[ü/™ˆãnpœuÈ+ÜŽ‘.ÐÖ»”™×]²¹Öû9E•Y lK:pÏ,v;Êp…ºfçê‰F®Ð<ŧÔ¤ŒÕ‘¿/ã '‡îkðÙ*cô?c>ã´“Í"´øâP2Ø ^—`’øôz âÚÃ-i…t«-SG¾Wº¤YpH ñÑupò~úÆ9×5'€^Qð—)C6²  Kb¬ Ë E-ß©•Ù„A <öåƒ{v}Tdº8õQMwlEÓNW’c 'ÿ'e~†9)>¿ñ 9/ØÎº9S¦g:1"]ìp\Œ…{D$t6IÒ'‡ªªý£4S†ï2þ)Ó¢¦sÖøa¬ßh2âÊL9Èß“­À»dØi±Ì¬‰­ø¬ÂmKwT? SŸ·Økmj8FÊdˆ¯!8ÆÍ.µO`+ò Wsð¿—™Ú´“Ï>z§+­Jœ¬ ©Ʊ'¢‚®AÀy†I!\êmêÑ3Ã_ó¾ùÿWv"Ç{¼hêãa-x…ëó{¶®ÊN©µnã‰ø,…?¨$ä“É#™TšÅ™WÍÊÔMÞ{ñ_ßi%ƒ¢Š½ÛHš¸IÛöò‘© Hâ+I:´#†»[¼šú}wD¤»ÊÒÜå²vʑޠ¡¡”7¦ˆ"Oe¿øv‡“D±vÂÌ8D÷ÑÈbò/å:&â‰í"¸aFA`Y :ƒ·_<\ýÜ¿º &¶E†•|Êtü¿±—¡âŒÍwƒÞ‹>CP÷Åve'4LÑuÙ^ùóÃðß­„|.Ò'»Õ‹Ì [ÿ…µ%S5//ñwZ„Øýp‘“Ê7ãU®JÊQ–žÝr¢Nü èä%RHN@Þ ëÄtûy³H~+ñ±Ì?Ë]:ÞïsNZÉæz¤‡oëy%ŽñÐN¢gí»ÎaÝ=¬µ¶†R©T"uM¡@ –@ Ô¤ÁJHHøÛŠ2™ŒÈÈH¡1@ðê VHH³gÏþÛŠ„‡‡(´&^ õËþ3`ÀvïÞý·ãââðññá‹/¾`Ò¤IÒy___Μ9S®þï¿ÿή]»øè£„–_s|}}±²²¢gÏžB‚—c°tttÐÔüÿ#Ä‚‚444ÐÖÖþÇ888àààP‘………BÃj€B¡ ¨¨H(Bðò†„W¯^%..Ž7n0aÂ\\\¤Š–––øúú2`À¡5@ðj –™™7nÄÄÄ€ï¾ûŽ/¿üRª8gκuëÆgŸ}&´&ÔA<==éÛ·/ãÆC.—3sæLìììpttD&“Àøñã5jçΫ’¬ììlìíí±³³cöìÙää䨔ççç³téR ¹}û6#FŒ`Ú´idggKud2>|¸¼ÁjÞ¼9ÖÖÖ˜››бcGÚ´i£2ÄëÓ§xêA$##ƒôôt† Æ·ß~ËþýûÑ××ÇÏÏÙ¸q#ëׯgéÒ¥¬Y³¦JòvïÞMË–-ñóóCCCCÅèDFF²~ýz”J%+V¬`þüù´iÓ??? Ù´i=zô`äÈ‘å –@ x}ÉÌÌ$((ˆ¨¨(š4iÀèÑ£UþíÔ©íÚµ£OŸ>˜™™UYfÙ}G¥r>))‰]»vI‹wžžž <˜:Hu-Z„••½zõzþP ¼¾4mÚ”;wÒ¹sg•UþWŸŸýúõã7ÞÀÔÔ€Ÿþ™ÁƒsíÚ5‚ƒƒyòä 3gÎäÿþïÿ„ÁÔ ###¬¬¬Xµj-Z´xeíHJJ"&&]]]îÝ»ÇÅ‹)((`ݺuxxxйsgîß¿ÏÊ•+qppÀßߟk×® ƒ%¨<`×®]œ?žwß}6oÞLFF›6mBOOèèhNœ8ÁîÝ»ÉÌ̬’<===ÜÜÜÈÈÈ`Ë–-èèèBZZ¡­­¾¾>ß|ó =¢AƒlÞ¼…B§§§Ô6}}}é¾õÅ£^ttt¸~ý: …‚Y³f¥+y®®®ôïߟ©S§beeÅO?ý€O•ä9::’››‹««+cÆŒaܸq\ºt SSSz÷î @nn.]»v%::š[·náêê ÀÌ™3yúô)®®®XZZªx+hTWz™LÆÜ¹s¥ãÀÀ@ùøãÅÛòšãééI·nÝÄ*² Æ©¶–¡¡¡´$ pèÐ!¡]@P; –@ ¨½œ?™LV:¬ÒÐ`èС\ºt‰ÇÓ¨Q#úôéCjj*QQQ*«xU•ijjZÎ=àúõëtêÔI Œ‰‰áí·ß **ŠÔÔT¬­­122’®“î¯9Û·oçuH*ëéé)fظq#2™Œ¬¬,6lØ@XX˜äá>kÖ,BCCùì³Ï cÏž=*ay/Bpp0_|ñ2™ {{{ÂÃÃUÊïܹØ1c(**B.—cggÇüùóÒ0ÁO?ý”ýû÷«Ì_ ƒ¥DDD¼ëâÅ‹âaV½{÷2iÒ$7nŒƒƒ ¸»»3iÒ$¶mÛF||<-Z´ÀÕÕ•ü‘¼¼¼*É+Ëî2iÒ$ÜÜÜHJJR)?wîõë—ð6lˆŸŸŸänQ¯^=~þùg|||ʽ»Â` jÄñãÇ2dÈ+mƒŸŸ'Nœ ÿþÏ-·²²¢G:tˆôôta°uääÉ“tîܹZÂn^”ììlÙ¶mÛ?Ö+,,$::ºœ{…0XŸŸÏÉ“'1b„t.>>^åßÇ“••EJJJ•‡„wïÞU¹zz:iii\¾|™/¿ü’Ó§Oãíí]¬,fΜÉìÙ³111áÑ£GR™X%Ô€ÄÄD ¤¸=kkk&OžLdd$øûûÍgŸ}†L&cüøñU’7pà@¦NJXX—/_& €Ã‡Ó®];Ž9€““NNNäääàââÂÅ‹qvvfàÀìÞ½²³³yë­·Xºt©0XºÐ¡C.\¨rNII šššèêêâááAAAºººU’÷Ö[oqá•û[XX ¡¡!Õñðð@[[---ÜÜܤóÚÚÚ*)e´´´ª¿‡õWO÷üü|ñ–µMMM•èÏ3JõêÕS‰Û«*½ÙªàŸ ”ú…ýUî_ëV»Ážî ¦CB@ gݺuèêê2lØ0™3gr¹}}}<==9qâÛ¶mC¡P°qãFÚ·o_%™3fÌ@¡P`ll̦M›¤óÌž=}}} ùꫯ;v¬TþÞ{ï±víZF±±1666ØÛÛ—öÅ£^,XÀ{ï½Ç¬Y³˜9s&‘‘‘DGGãççÇíÛ·‰ˆˆÀËË Þÿ})kËrþüyðóó#""‚èèh©ÌÓÓ“ÔÔTüüüðòòâÔ©Sèéé1nÜ8tttˆgÏž=XZZ²råJ~üñG)¬H,@ èÔ©ëׯçÔ©StîÜ™ØØXîß¿ÀÇ‰ŽŽVÉìY¶’÷¢DFF’šš ”î(óæM©ÌÂÂ‚ØØXV¬XA“&Mhß¾=GŽáóÏ?ÇÌ̌͛7«´åÌ™3Ò&Â` j€‹‹ r¹œõë×W9N°ªL™2Ö¬YC¿~ýèÓ§ 6$>>==½̈* –@ L›6õëׂÝ+m˪U«hÖ¬J¥’ýû÷sôèQ tž­W¯^ÿ¸y³0X`dd„\.—ÒÉ|øá‡téÒ…ääd:tèÀG}„‹‹ Ožùä¾ù把Špss£°°777ŠŠŠ8yò$/^dÿþýܾ}[òxúô)[·n¥¤¤¤ÂòŽ?Ž­­-£G&++K¥¬°°7ªÈþõ×_‰ÇÛÛ›Ç#—ËÙ¶mIIIüüóÏRæQš#¨ß|ó Ïž=#22®\¹Â¾}ûX¼x1¾¾¾ÌŸ?Ÿß~û;wîàääÄ|€¶¶6cÆŒaòäÉLŸ>¾}ûVHÞ!ChÖ¬AAAåÊÖ¯_ONNãÆcòäÉ :”¥K—Ãýû÷qrrBGG‡¶mÛòá‡Ò±cGiÑ¢…X%ua°AA 5ÄÌÌLÚïÏÐЦM›Ò¡C©¼cÇŽ´mÛ–?þø€¦M›Ò°aÃ*ÉLMM%))‰Ö­[K¹²š4i‚™™mÛ¶U‘­­­Í“'O€ÒØÃ²I{a°5`íÚµ=z”ÌÌLf̘Û¶mÃÑÑ‘Æ3jÔ(ž={†»»;2™ ///¬¬¬Ø±c³gÏfÔ¨QtéÒ¥ÂòBCC¥&.\Èܹs¹~ý:kÖ¬!!!oooéß¿?6668;;óÍ7ßÇÙ³gÑÖÖ¦W¯^dddHmá8úÚcooOQQ»wï®1/Ãq´K—.Ìœ9“9s戇ú©ìñ§¥¥%ÓÐР~ýú”””P\\\Ú“©_ ÒŒ¥õêÕ«°¼?ß ®-..FKK«Ü}ÿ\¿,%rYzõêIŽÏ¢‡%¨ÏK9ü×sÏK£üç|ê•áy÷*;ÿ¼ûVT¶˜tuÇðV×Ä&AíåîÝ»øùù‘™™ÉöíÛ¸téNNNXZZâååEdd$žžž°yófÚ·oÏÈ‘#122¢C‡,_¾¼R2§OŸNqq1†††¸»»KçÓÒÒ˜5k 6D__ŸÅ‹3zôh©|À€¸ººòÑGѸqcŒ££cõ,± …@P{¹|ù2.\æ’._¾Lhh(S§NeýúõìÝ»—àà`¹sç;wî¤oß¾èêêâííMŸ>}°µµ¥M›6’wîÜ9’’’ ¥OŸ>\½z•îÝ»àååEff&@GGkkk5jÄÈ‘#9xð üòË/tèÐyóæáèèÈ„ 044CB@˜øàƒ—&{âĉ˜šš²iÓ&úôéC¯^½hР÷îÝ£aƘ››ÿíµÂ` jÊÁƒ9vì‡ÆÒÒò¥É]»v-M›6E¡PHm £{÷î"E²@ î¤¤¤ “ÉÈÏÏ'))‰£GâììÌÝ»w™0aAAA,Y²„ôôt²²²X²d ³gÏFKK‹û÷ïWÚqtìØ±XXX””D÷îÝT)?{ö,4lØP¥múúúøûûÓµk×r»T‹9,@ yçw066ÆÎÎSSSÞ}÷Ý—&ÛÇLJððð¿ÍߥKºvíÊÞ½{ËIa°5ÅÄÄ???RSS¥¹«š&++‹G©C?…BAll,^^^Â` êNrr2çÎ@[[›èèhÒÓÓÉÌÌäþýûäææpãÆ JJJ*5UFÙ>ƒ7oÞ”d¦¥¥üyó8}ú4ÞÞÞå®ËÌÌdêÔ©Rœcbb¢T&V 51PK–,!<<œiÓ¦±bÅ æÏŸO§N¸~ý:ܼy“‰'"—˱··§wïÞL™2…=zœœÌÒ¥K+,oÈ!|úé§„††rëÖ-öìÙÃÑ£Gi×®û÷ïÀÉÉ '''är9sæÌ!<<;;;† ƾ}ûÐÑÑA.—Ó«W/I¶0XP6éþg._¾¬r¼eË–r×ݺuë…äuìØ‘¨¨(•s*Çe½+mmírm›4iÒsï+†„ÕHvvv­jϵk×xûí·Ÿ›ª¶.±gÏ>ùäñÌÂ`U'óæÍ«UíÉÊÊ¢Q£Fu^¯IIIN÷2)**bÑ¢EâÅKðw¬\¹’‚‚¡ˆ!::š_ýU(â<{öŒ+W®”3°))),X°( =z4666;vŒðá‡2eʾøâ i"¾"¤§§3~üxììì°µµ•Ü X¾|9#FŒàûï¿G©TRTTÄêÕ«1bk×®•vÏÉÈÈ(ç8Zm+''‡¹sçJáé^3¤¤¤PRR"ñ/äåå‘••%ñ?òóó¹pá‚ÊŠ€¯¯¯äÒàïïÏ–-[puueëÖ­lÞ¼™éÓ§³k×.233‰‰‰©Ô0¾gÏžøùùann.å¼JII!227778@aa!YYYœ>}777Nœ8\.`ïÞ½„„„¨Ü·Ú&Ý Xµj•tü×I4@ðêhÔ¨sæÌáÊ•+Ò¹²8Á²]—---iÓ¦ mÚ´ÁÔÔ(]í«_¿>ƒ ª´Ì!C†Hÿ>~ü€V­ZqàÀòòò$Owmmm²³³ ÅÚÚ---ÂÃùyó¦[Xí=, ŒŒŒ¤†††xK‚ZJQQ¿üò 'N|©‹2šššèêêCûöí¥ [‡ FAA!!!ãííÍôéÓË…|‰9,@ ñ÷÷§iÓ¦œ={–¸¸8ɹóepåÊbccÙºu+šššPPPÀ‚ èׯ‡BGG‡ˆˆâââ¸zõª0X:¡P(ˆ'''‡øøx†΄ °²²¢Q£F˜˜˜pãÆ öîÝ‹‡‡999˜šš²lÙ2nÞ¼‰——ººº–ghhÈš5kˆç»ï¾ã7ÞàÈ‘#=z”±cÇÒ¹sgâããYµjõêÕ#$$„ü‘S§NÑ¿ìíí¥¶™™™I÷Ž£ —Ë  [·n²|ùrš4iÀÌ™3133ã§Ÿ~bß¾}@銡™™nnnìÛ·Õ«WW*ÖÔ©SQ(àààÀÈ‘#‰ŽŽFSS“3fNxx8]ºtÁØØ˜íÛ·sâÄ ¼½½¥y´²¶•¥MK PLMMY±bÅsËÊv]îÔ©:uR)[¸pá Ë,Û­¹Œ®]»ðöÛo—«kmmµµõß¶M ‚*âëë+”ð’=¬:Dff&ñññBµ„3gΠ§§W§Ú|ñâEi³¼¼<‚‚‚èÙ³'ÚÚÚœ?€¡C‡bddÄþýûQ(¼ùæ›ôêÕ«R²‚ƒƒÉÊÊÂÜÜœ–+¿té={ö¤°°ШQ#lllTê?~œæÍ›K=?ÑêCÄÅÅ*!¨4e)’ׯ_/KJJbîܹ¸»»£££ƒ­­-‰‰‰\¸p àããƒúúúL›6­RÐAAA¬Zµ CCC.\ÈéÓ§UÊoܸÁøñã)**båÊ•=z”Õ«WsðàA 4õö¡C‡X½zµ´Å—èa jÂ_S$,[¶ŒÅ‹3}útŒŒŒ°°°`ñâÅ@iŠäÛ·oãï )))•ŠHJJÂÝÝ=z ©©Irrr¹Þ©‘‘PºáºuëˆŠŠ’r¿>|˜¢¢¢r¹àÅ&šÒ®];ž>}Š£££ä‰þ2ðòòâÒ¥KÒÐôÓO?`ݺu˜šš"—Ëñôô$((ˆ±cÇ’žž^ý«lвO]Û¿ >|(e}¼zöìÙC í+\+Ù°a+V¬ S§NìÝ»÷¥È|òä )))lÞ¼YåüéÓ§>|8Ÿ}öaaa4oÞ??? ÀŽ;ªß` *OZZZ¹$g‚WDZcÇÔÊ`•3wîÜ™V­Z‘ššJFF‰‰‰äääHuJJJ¤tÇ/rÿ²>|HZZׯ_gîܹRŠä“'OrôèQ¦L™Â­[·(,,”|¯þìƒbK P ÊR$_¼x‘iÓ¦ñã?òßÿþCCCÆŽ˰aà eòäÉÈårèÕ«S¦L¡k×®dddо}û ˳±±ÁÖÖ–Ó§OÏ/¿üÂñãDZ´´”zsÎÎÎ8991~üxIMMåêÕ«°eËìììˆÅßß_,u¢yóæ>¾î¬'Ožü­Ã§B¡ 33³F±uëV?~\©kÖ­[Wá_žââbî޽˩S§jT™­ZµB&“!—Ë…µ¨888°cÇŽ Õ}öì:::µªýOŸ>%##ƒ£GVêº 6TÊq;&&†àà`”Je…êòìÙ³W¢É+""‚ýû÷c``ÀâÅ‹Ëå'ß¶m>ÄÆÆ¦Â»AAA$$$ük½ììllll˜}ê´®bccY°`Aµ¬Š I›8q" 6dÆŒèêê2cÆ •Ò¼yóÈËËSÙ{ðU¢©©Yãʪ_¿~zõêÕüDåKø5††ÆKùã¨i]ijjÖxœíËÒÕ+y”]¨$"¬E½Ï[½°··Ç××÷Õõ° ¶SckôèÑB»j„xÞêŨQ£^I © A­ìa]¾|ùS¿nذàà`¡m –óÃ?àììÌǸ~ýºÊBÛáÇٴiHYºIDAT“tìîîÎÁƒŸ{¯””œ«5ò£Z –§§'ÎÎÎ,_¾¼\™——ï¾û.aaa¤¤¤ˆ7â5£¸¸˜}ûöñäÉ¡Œ:Î¥K—èÙ³'nnn|ûí·lÚ´‰o¿ý–¹sçrïÞ=¢££éÒ¥ þþþÒ®];nݺõÜxÇ+VàææÆÂ… k—Á*..FWW—ÂÂÂreEEEhkk£T*£Ï×Í›7£¥¥…Ïž=C¡PHa1%%%dgg“›› ”Æ egg“B¡‚ÄËBPrssÉÎΦ¤¤„¼¼< …ôë\\\Lvv6OŸ>E©TJ±rÏž=£¤¤D<ˆj wïÞôîÝ›àà`FŽ)ýýêéé¡P(P*•hhh ¥¥EQQEEEÔ¯_ ç>ƒÂÂBôõõ«5ÛDµ;¤§§³gÏfΜ‰¶¶¶x ^cøõ×_Ù°a_ý5Ë–-£¤¤„§OŸ2räH²³³9{ö,ºººL™2…cÇŽñàÁ®]»†ƒƒééé,Z´ggg\\\øé§ŸÈÏÏçÝwßåøñã´nÝš¬¬,ÆÇ;wˆŽŽÆÀÀ€O>ù„;vàááÁÊ•+™3gÍš5¤8tèðb‹(aaa<}ú”áÇ×Xûª¥‡ecc#½8lß¾]úõœ0a{÷î¥M›64nÜX¼¯5¢qãÆ*Š>www,--Ù½{72™ ÌÍ͹~ý:îîî*ɹ¹¹ÈårΟ?OLL 2™Œ¶mÛ0iÒ$\\\ ",, wwwœÑÑÑAGG™L†¦¦æká[[†„7näàÁƒÒôÎÇÌçŸÎ’%KhÙ²%FFF„„„ðÑG1lØ0ÂÂÂÐ××Ç‚³gϪÌUϘ1;;;æÏŸ_mm«„‚*ñg‡ÑeË–áììL‹-øå—_ˆ¥eË–Ìž=WWWd2—/_ÆÅÅ…óçÏS\\Lpp0>>>üöÛoãââÂW_}ÅöíÛÉÌÌdÓ¦M´mÛ–ÄÄD´´´°µµ%77—ƒ2|øð sÔ.„ÁT‰ììli{7¹\Nƒ ¤p£ââbÒÒÒÐÖÖÆÔÔ”üü|²²²Ø±c#GŽäÍ7ߤ°°zõêaddDff& …333rrr022¢¤¤„ÜÜ\ôôôÈÈÈ@WWCCC¶oߎµµ5Ý»wA, æ¸uëfff¿Ðõ………DEEI¹¾êÃÿ}1ì@뜤IEND®B`‚snd-16.1/pix/usync.png0000644000076400007640000003326511147553271013021 0ustar bilbil‰PNG  IHDR-RîªsBIT|dˆtEXtCREATORgnome-panel-screenshot—7w IDATxœíÝ}´U}ïñÏï<äé!ò’BªP¼ñF[/´ø°¬"*VCðЬöÞˆöÚ^´®öšRºzÛUì²íª«^õB¹Õâ‘‚¢âdÑJÔBÑ H} ñˆ(ä§s’s~¿ûÇaNæÌÙ3³÷ÌžÇßûµš3¿™½÷ÌìÙ³¿³÷ü~I=@M IÒ×{;«.ÌqùÕ¦ï› Z$éïö|µÊò€ÑlÐÒšž]øç¿xµ>ùÉOê}ï{Ÿ^ò’—dNüÂ_|4_éH’>1u¡—tþÇБ^ØlÐÒ›îÎ.|ôÑGõÙÏ~V^xa® %œ&€z=pÒ/åJâž»C½“»ÍH/äpÐ2•`LOOëÑGÕøø¸Ž;î8­^½:5Ó´4X˜ù¿gŸ~*ÓæÏÚ¯^¯w¸^÷ôBOKùÉO~¢ï|ç;ÕI'¤»îºK÷ß¿Þüæ7kpp0v»¤4ó]vôkôæœ)IºàáT\šfáØh»ÞóAA¯—±Ý›ùŸ NïõçŸï”Ô­_ýªUz·~5ù½ù9ëEÒ ´LÏûP’î¿ÿ~mÞ¼Yüàuä‘GJ’N9å]vÙezÙË^¦•+WÆ".M€Y¯{¸¡~ð÷>¯S>úç4¾òË%I_|òßuÍ·{+[UùØòqì Ö†f~©¤×Ëþ‹%3#Ó¹Ó ¶IKïõ矯¯}å+Æ4ÞðÆ7&§b|§%pï½÷j×®]s–Àù矯[o½Uï~÷»500`ÞFZÀMäÆñØÖÿÐ ã´LI=õ¯iÏîÓè[²¿›X§|Ryz–ôf¶‰Oï+_¾Eo¼àM’f‚“¯|ù–9ëŸIÒW¾|KbzÒœo›ÿá 'œ w¼ãš÷ÙoþæoêCúzè¡yï·ìÛ·O÷ß¿º£-ÚeÕ¢cõî¾V§->I‹èÙîí:ð„ÆÿW}wâIÒ­/¹R’ôå½ßÖToZ¯=j$éK{þ]×=¾mNz-¥Þvô¯i¨3¨ÛöíP§Û™—gwª;›æöÜ­ÿûØm±å Ö“¤Kß²^—¾e½$éõßû IÒ‚ÎÞqì¹:ïÈ3´|øH=3=©o<ýCýãÏÿE“݃Îû—OŽ´G¾‘–Þóÿnç¦÷å[¾d•Îozó̈ˆEz¼éÍ’f‚” ý`Y°Îì(˼ôKi9öØc‹$-^¼X¿û»¿«»îºK{öìÑÙgŸ­n·«½{÷jÓ¦M:óÌ3iÐ:W¬x›V,¡sVëˆ#Ž˜—g¸-}zûÃÚûÀZöÆÓåûÁä£:mɉ’¤Ýûöègÿ\’´ë}E'_õýé)é¬#NÕ¡é)=ôÓGtòq'ê‚Ñ3µrò}ðgcê,´ÚÇ´|êxì é‚X%<Ö-ç§_ï DÒsI·×í¦¦'I·|ñ zÓ[f¾ 9¬ŸÍÉ3’^Xê;-IN;í4­ZµJŸùÌgôàƒjõêÕÚ½{·.¹äuÔQê}ûkÎi@¿`™$é¶í[õõ'8rŽ\r„–ö驦ÕY¶pvݽO?©7¼ç"sìrÝöñM’¤3¦ŽÕ·¿u§Ž|ùJ]xÌÙ’¤]?×[Þ÷N ,Öÿî:­xá‰sòìMMë§vëÐî íyr¯ö?ö¤†~\#+ŽVÔÿüþÕÚræŸK’¾úõÛõWÿô1u– i`Ù"­üɰÎzé©êõzºøÿ]ÿñðtÚ§ëæ¿úGý§“^¤ßÔÕ÷mÚj“òyâßv꘳æåeUÇÚ&Ï;-2¼3~ŸÄ¹ é¾ô…›õæ ß:o™1¿´wZ²~Ó×¢E‹´aÃMMMippPNGN'WšPWw?ùc½rÙizù¯ÑYkÖê¡gÓ·þÝxïmÒÓOkzâàìºßøÎ]Ú?}P{ÎX0»ìˆ‘¥š¼g·½h¹V-:N’ôoß½GÏ ÷´ðÜãu÷¾Íëxw§»úíû>ªŸ}ôNiº§¡G¨×µkcO\ªá5ÇJƒ½äÄI’:Ž>÷÷ÿ4oÝ_yá©úƶ¯éî¥ïcwÉÂØ|‡‡e«êØ@Ûdýö°¸>zžKº½^75½´ímË'9üNK’N§£áááù…a.1€–ùó^¯—ÿèHuâéú¥«ôò_>]¯8ñ ½bùéúƒþA‹·…ÏL<«cG¤EᯆïH‡¦5õÔþ9é³DC‹‡µpÙȼ<ƒ¶tä·NS÷Éê tÔ°nc.ÕâãÒ¢£gÒžîvõÀ¿?o½'Ÿ~JS?VWÞóÿôÊÇ^˜¸¦¼ƒ|Âe«òØ@›ô”m¤¥£ŽÔéÌkƒô\Òí©—š^à·¾}ÞöoyëÛô…›o²*ŸóNËÂ… uüñÇ듟ü¤6oÞl]øÀ‚ tÙe—1—@뜶ôDݾô^}ñ_ïT÷ñIýõoHoøÕWë¥'¼H{ÿ÷÷tÌ»ÖÎY¿3< ¡‘…óÒéNuõðäÏõâ¥'ékÎÔ‚¯ kñ –jí‘§Î[·7ÝÕ?õAi­tÛ/¾£ëÇï˜]n2Ýëj°3 ‘Å‹gÖëÎÌþÁÓ?•$  èo?õtÏOg—ÁÁA½âôµúÑøCÒÒA½xÁñº}é÷±7ÝÍGÒLy5·¼U;h‹Nð}#ÝŒÓÆf‚¶q^z.év{ééIºðmëfÿý…Ïmž³ì·¾}v™©|‘¢?ŸvhîØ+~õ×ôµÛnS/ãé ttìòåêÞÍ\bíòÑ5ïѳ§ï×c¯Ý£¡Þ€Vy¼$éG»ÔÔãÏjb|Ïüæ©•z½®nÿ†>túz­:ñd}õÏ>¥EÃ:jáÒyëv§¦µbñrIÒ¢>«gv<¢‘W¬ˆ-ã®É_蔑ãuák/Ðé§ýŠz#ƒzß}ŸÐwvÿHw?ú€Î>ñ }úßÐ#{Õ¡®V¼à8-Z¨õÿø‡zæàcúÄoüž=”¼KNÍG’±¼U;h™F±×ëé­o¿ÈiË›oºQçS8Ü6N/üÿ6z½^jzá2Þ|Ó³Ëo¾éÆÙÏ.|Û:Ý|Ó³[ÏMï0ãHËOöOëg¥RüÝ§šœœæ €ÖùÒ£ßÒ‹ž;F'’-\¤}O?¥»¾{þöS×À 4µÿ¹ù™šÂ®ôµGïÖÈãÓºdíùZºxD·|ý6©ÓÑů»pΪᶴ{`J{JC»—iÁ²%Æ2~ôŸ×ïûzÂJýÊÉ3_I¿gì^¾c>ôÀ§´~ÇZ½áe¿¡ǾP‡¦§ôðOwiû=wéá[whøõ'ëKãßÔ‹¦–'îcoº›˜©¼U;h‹,ÓÃf¶y~úUô”ŒÓÃ’Òû­·¯Ÿýûó7mš—öçoÚ4»Î[ß~‘>Ó¦Øô¤˜wZ&§¦õÔCÖ…6Y2d?ßšâoî¿Qûný¡º¿˜Pwò9iJê,ÐÀ1‹µàåÇk`xH¿~ëôÄǾ%I:å(©×3.ëMuuýä7õþgMý`¯zÝ™—ìÿòKŸÔÔÃOÍæÙ›êÎÛ¾75ÛÆÞûÄN]ü­?ÑÁoüTÝgž ¾6_ã{µäø£ôÛôñ¿ù¬¦~úŒzû§¤Ž–.ÐÀ K44yP¹÷ŸõÔ¿<˜¸½©nb>¦òVuì 5:sG2\ÛtÂïŒDÒ >Ò“¤Ïm¾!¶¼ŸÛ|ƒÞ¶îâøôBr{Xœ=ûŸã[[´Òâ__¡é§Î4ª]Í|1ý@Gƒ ‡µàÈ%êNwµø]gHOÍŒôº½ØeƒƒƒZ|ö :íéà´:ꩳpHÃg¾Pzn¦ ÚRÓöq<ªÎÑ‹Õ{öÐó¿ÖÕS÷¹)u§»Z´t±þËÉšzö thZš~þF1<¨¡EÃ’:Vû˜–ñTtì  ‚³=õtÓævÚ¶§Þó tfÛÆ2ÒK½™³^$½°\¿Ó’dÙ¢a¾@+ kxÙüoLœ1óýò‹/–žA]Rì2IÐÐQó¿ù*º^Üö&I‹–,––,ž³<ØfxhHÃG™<¸×íZícZ>¦òVuì M.\œ¾RŒ™‘Œ¹mcÝÓ“bÞi9zÑõŽÌœ—$itás‰_:}û®;ò&q¸^÷ôÂË%õ¾ÞÛ©?¼ñ¯se>=·oB;Þ;fi€º˜÷NËä—¬n¼³²è_g\t®–\ðËs–Í-S“3ßÊòÀwêž{¶•Z0¤³Î:Ok_½rβ٠ep``ÎgžùŸË)HºæšOK:›Lwg^a -ƒå— "‚Ød~Ð2HРz³±ÉÔ!I Óà ÑØ„‘µMx§@­Dc‚µ´ òN €êEc/#-ÎQ±ŸõzO×.7¥·NQ\öô­ë¾ÅT–¸åU•Ñ–éœYÖº[.}B›´eô“⧇å|ß¶ðiëŸ'EòylÒÊRi|ªsçÜç…f»]@UÊî£'¼ˆÏô0Õ‹ÿÊã^Ä÷5¬Tö”¡´üãFl?÷=ÜÖë=9oT!ijXR¾iÇÚ÷hˆ« Ÿ¤sb{¬}´:Ruøè—Øöl6=̦€>†•Šî$Ût6]: qûþ¼ªÎjZ«HlÅ“`™í±öu<ÒÊӔ㠚/­ßíû½›¾³Â~§¥-­,ûaŠ*ûQUîºÕ½¬å©Û~€æK›ñSt^Y%Œ´4ç„tá)by‚ ޵qA.A ¨Bû{ÑØäðï´4èÇ%éÜ•‡c] ¦‡€º¨cÿ#›Ì†0ƒƒ¥¼ŒßF>£Ó:Fº6â^¾*+ï2·Ë«©ç ‰Ï>N46)uz˜é[œ’^j7­SôÔš´çã¾!ºÌf_MÛúþ˜¤§÷>Žu4¼ÓÑLåOÊ?n½,Ǻ¬ºÇô0P¶ý›¾­×o‹›–g”Å×Kú\'‹<ûa:i¾óÍÂæÛ²²n·NÙ?Ðék=Ç#îó"€‰Ï~‰ï>YšÂ¾ò|(ì+À‡ø‘–lï´Ø¾pS÷é0ìG½´e?ªPv_ÊwŸ,›äžÖ–N#ûQ/mÙ€*4½/;=¬I¿Ó ½¢±I©_y i ùÊcð%áE|‚Õ³þ–k®ùt)€°„ßi9¾³àR¨«Òƒ–mÛn—$½îu¯N]7e‘¤;ïüfaeP_¥-ëÖ]<çï´Ñ–ðË%—¬/¤Lê­Ô %e $¶„GYYF[FFVÏû;úŸés—ô]Ö঴ %:ʈm1½Çâ:ÚLLLìœó_xý`™M âº>w¥-ÑQ–€i´Å4Êpm $aq£,Uª[y€ºpþÊã­ÛêœIðaqvì¸oÞW#mrÎÇF4 FKÍ42rª&&¬º€9-/]øÒÙŽ”¤k®Óå—¿_ûìNÜ.)`‘fF[žxâpÛ·ß1ç·Zô¯Â\2m”%°cÇ}³ï½$MË+ËÈJ0m‹€æ`$¶= Z$iË÷)eq?(96¶I7^a•Fl„•èKóá@$ü™M€âº>Ðï¸y€, Z6o¾aÞû*e‰ $’ Óg®ëð§”éa@Fä§”éa6ï´lÙ²UW]uU ¥€xm¸a¶a²Ê³ïý|Ü îJû(ÒÈÈ©Ur9ÿÔh‚ aèp¡ßPç-@‹%uöú¥#82rjßì+ÜP/ÜqÌŠSçc[粡´´XÝ™º•ÙTy©C( u uRE},2Ï6\_Á>ÄíKö±îZjÈwÅçBj?Ó9®Óy—…c}ÔùxQ¶:_'ÑrÔ¥\¶šV^¤ãœ ÔMm\ùuÃç›uŠÁ±E™¢õ­ˆúWt¶IŸëªMîÀQGú[›ÎízÕ i ~\Òæ?Ø7þM¾IÔUÑÇ´Šs61ñ`cêJ–rÖᣪz×”óš¦Nûa{½„§‰ØŽÞølÛÃù¶ñ­2ö§ Ó\Ën³ÊÈÛEÚt¬èzY×Ér ù¸·º¶5`zXí”sÔSžóRÕ9Íš¯K‡/¯"FÏW=ÎS·ÒÊã³Ã "ò¤•ås_ù„×ãK<꯬)”EËúð©Ì²Rçë ¥eŠ~ZâÔñB×íØçEÐÒpU?‘©úæX‡<³ð5í¥ª4²¤•ÔÙkÊyëwqç©Êú\ÑzÍ4ßb4mÔ¥êü£ªî/äM?k'Þçõ˜5½:=Th2‚– ŒŒ¬ž÷Ÿ«겟òø˜Þ“”†Kú¾×³M£NŠ:N5­:h/«Óì³mÎÚÎEÛšp_©Û¨g‘×aÒCˆè·På)OY÷¡ê:–ed%nYÒC¾ª÷³*-˜˜Ø9ï?Ÿ²tXÛtSòÙÈ—=´k“FßV‡óZ…&ì·¯ÑשIy:´u:®6Ó²’Ê´µ®ß<ÖïªjÃ| UZW‘žM^e>HÛ>ϽÛ$©OUŹKjoÚÜÆ´ÔXÑÑtPém~ëÀ•ïÈ·¬7¤¤F¢È§øE<Ñ75zÑ¿Ël¨ãÒO=J:öiõ»ˆk¬ˆº.gR½(û©lËl>+JÑmpžôÃÁR\Ú¶eˆ–'é!—ô\¶OêøVGÏOQu¡¨ý+òžäº^A}›«¼ïÇõ‚–hS…N–nЏÛFÖQ——–Ëæ’g÷£m²Ö3Û§€¶é¹nï#0½ƒbÊ3ËË<þ<’Bø~êœ'›eEñùt½®ùyÔåÛíÚÐV§µGE¼«™öP¢_´ô)ßCSG¢ÈiL¦§ð6OÕ‹È[²{Úi;²Ý.ئ®W°_¾Ž¯i.}•p9òlWVÇ1MYÇ2®]V>Ï:¦ëÍG‡3|-»óE7_£Y;uiéú\¯*u¹îêþÑá,£W®Ó0MÛ›Ú£èCÒ&Ô§ºöÊ@Ð'u¿ ‹Rö~Õ(U9ÝË”—K çƒï/+ð!k‡.)PÎ2‚lk›Ömӄ˘§sU‡sëªÈ2G±¦¶åY§Ÿe]×´Mž)cYWÛ²U!o½Múö½¢Úéh;åLE·u)sÖ©sE|YFÝ´4LÞ§VÑí³6U=©Érƒ°QtgÁ$:‚’ç\¹¾ë6¶¨c^dV—›€Íq´yšë2ý©ˆŽ‚vÇ%è²"§eM¯êiRu ì|µëyF¯ò">å9Y:Ë.êR_¢ª*WmZVu¹ùFÐRCáÆ4)’.ê"©CeÏÙÜ€|½è³“WÙ#e(z_òÖ5›éqÁ9ÉZ—òƒ"ƒÇ,Ó‹˜ÿí’·Ïú”–Vž©,’yúJ–Ž’ë”T®m§ïE—²„Ó)£mt žÊÎÓGºYÇ:ô/Êâzn].õ#‚x¾Ñ©êôã:"Ñ`³ˆ‘„¬Ó;òtHêö4ÉtlMïÑI 'iS´|0ÍÁ¶]×—¼ïräí¸FÓÎ;·=OÞuI×g°’¶i:SÖ@Â×ušU•s’´ö,ozUmëã¸æ™Y’UmiÕu®©Z¢ì§¶¯ŽCÖ9ÆE=•°¹™–u³-âé{Xg•Áï¼mFI²ìetØŠzâ[‡àµ(u¹®ó¶mUÏ"Gó®Ÿ5½,תÍý)Ë´Û¬òÞ/Më}Ÿ,"x+ºÝ5 E(¾ÞºëHê}½·S÷ÿìû’¤÷ø&íÝûˆqåeËVjß¾]³_sõ˜.¿üýÚ`·qýõëGk×®±.̺uëúë?£¯Ðø¸ùÇÆ6iãÆ+44thvÙÂ…SÖyÔÕÈÈê™ì­¶h‡‰…~ÀÜ·ƒ‡ŒËGGWéãÞ"Iºö–MÚñÞ1™×De‚Ê~ô.Kø)°iøÞö=˜h~¦4£i˜òL*)¤2šö%ZÓßY¶ÛOÓç¦ý G›ãœ6W=nY–ÏâŽí47SÙ“Òs9æiûw¼ÒÖIÚ.é™êOÚ±Š¦Ý×´2Æ•-é<ÆåÔ6$-+gÜõ›¥Ì6ÛÆ­—Tg’®¥´z`+O:6Ûø^'íøHÉ×_ÒºÁßiu%,Ký‹nëÚ¶$Õ«¤k:­ÌÑüLûb*{4M“¸²šÊWö´v2ºÜ”oZûër~ÒÚ“´ÿO;NIõ/îܤ]á}³i³Mås©?qÛ™ö9\þ¸ÏæìÇÞNjy›„éa ár£Ì{sÎ"kžÁE·½Mg1.ÿ¤4ãØ¦“çWÁfŸƒóµØ–¡iÇÎ$KÝ Ø_×sàó˜¦uHŠPtú¾4¡ŒEªÓþÛĶê´_Q¶e«Ó>$ÝG’‚ßeȳ]ž{aç"éþÙ†>Š-‚–šŠ«„IѦsŸ”ŸÄ&˜D;*IÛÚtj²\¤IùÁW®—¯´³lãcŸ³šYoø¦z‘'0w‘v»–Ã%ÀòÎ{Ã.ËÛñÊz<|Êy¶/ãš/#›À¡È‡GIåÊRçâêKÕAQ´#4’U–,íDÚyÍûðÂf[›>GÑdz¨||×Û:"hi€²Ì¢o:¤†ÉæfåÚ0¥}îóÉ…N²kZYÊTF㜧ãí;pʵŒÑŽÜ:¶â¶+›ëuâr¼²¦åóœØ>`hâºÌ2G;›EȶëøjÿòÞëlÓ®áèºEŽ˜ÊPV?Ëýªì@Ïçý¹HEµ]uØ·2´4\‘u¦jJØWÑA[ÞmªRT'h£²žX—Yޏ¶ÑWÀRÕ=¦ªXE—¡êQ²¢ÒêW--QDCWÄÓÿªæˆºŒ,ø|]'U–µn7£*Ÿl7M“ËÞ|¿”e MÕuÆv$)Oº®Ÿç½÷ØŒzÄmŸvß-ê|¹×û®Ë¨sVE<Σêü뀠¥Eê:Êbš6“7Ͳ4¡Œ>1ß4mܧ¦àØûQÅq,#@2­ç2u)KÞyÖ¯S}nûè7ækóù#h`T‡i‚mm|Ûº_Yp,Ú©ßÎkÝžÊmÄï´ô‰:ÌWͺ~ÙéÁN¿÷~Ýo4õ³Zu<þu,“Tßr¡¾Z*02²ºê"KÓ;M/?šzæAK&&vÎ[F ㎆€‘‘ÕÆv7ºNTÚ66ieM@3Ø´/ðƒ Ð:Ñ $ø{bbçœNF\€12²zÎ6.ùFÓqM@ý…Û®ór´-FC:#Úv*ûýø´IÚ(GðyÚz¦ &Kžát‚€).OÉŠ¸~²ÜâÊÁõ],‚–† c…$¦NS¸“Ô”ú}î³Ì¦§ßÁò¦Ÿ~g$K×ó4¢Û»L ×3Ó(ŽMpdº6âF€¶0µ×¾ƒƒèCSÚáuâòMÁ¦eS®p:>§±6AKƒøº!¥Ýûé(ƒíûJ®sîãØhcžÔ)Ê{®}ÎÝ>vòÂ\:z¦²™þîç_R§<ËÔ¨´ Ú´<®IKêÐGÓ1u‚’ö%.ÎÚY…É€6IDAT÷ÑAHJ£ì#unÃÂòÛ¶×XZÐáò+­›þÎs.²lw-eÉ;úï¸ë.øw–}6¥w?¶}`·M\þ¶ApRÙl„Óˆ{¸V÷k×wùlŽ}Ó´4€ÍEWÄÅhjLe±iØÊ|bdÊÏT¶¤'1¦&é©SÝÃ$iA¦éœÙÖø:R÷ã-wÚhAÜöIë¹Üü£ëÆ£¨¤NCÖNAÝÔµ\MåúÐ+)ÐÎsÝ'µ7qmrtý¤[Úõ›tMEÓv $òÿ6÷Ф`2n¹ËCÛõ\ƒ×rÓî5pCЂTy/ú¸'F6i§ÝtâÖIJßö)Røï¸'…miãžr–d6éø¸›¤ímÓHZ7ëHW™ÒlÒw¹6M£&®×v°M8½´ça3j^¯ªó ¥‹{zí:Dì³ÓWƶMÒ/û™•Ï@€?yG}‚¸N+Í’§)à —h‚T&nZR™CÉø7 _Ô½*z垈¶#hA¥â¦%ðoÉÈjMÒ±Zƒ@ýd êa4Àˆ"hPk-€F[´Rh=‚­C'€v!hP €6á¾æA Ðý ´T øÅÝðIŸùþF­~­ìèÑúü]v½oÃuÖ´}X2²ºqen—cÎùáøb{}oÎY=´T`bbç¼ÿl>C±Šh”ªl,MÛ…—å-[R0P·>\Öº•­,MÜïºÖý¬e@:ŸÇsPYïEŸ?Ó=¬¬<“–•Œ5 AK‹E/ȼF™&)êXÄ¥[d‡¼ˆ´³¤çR‡ÓÒ¯jÆF¿<¹NªË®i˜êFZ} ÖÉ[¿£ž´NP–üÊlËn»ò¬_·úï£NÁ¦ÎUÌ»4EÖo›<]ï>îÕiý8—|Û€ ¥áêT9£O³}tJ‹Ú¦‰òŒh”yŒ|uþ²lçkô¨*Eç?9±Ó*Ðs}ò˜õˆëº¶ÛMNìÔ¤å(µËºÑ|ãþ¤YU}*ꃯº“·~U¥ˆ +ÏúYù¼oø¾ù ¬ª51}VD—7í¦"h©ÛJÚoUª¦3ìCy7¥~Pßýܤ³<™ÌòÔ°èCÞca|¸ŽÎù¬UÑõ]L›%KFV§÷¢ö;é³& M½×åáZ£Ÿ¹¶IÛ•Å•#Ëñð(ÕAKKÙvb²QÚ¨òIcÕŠÚo# >ËÖ¤€,èXõ2Z?‹Ø—,O]o˜.£.ùWuÌÚÖ˜þm“O^6#>yež¸™~ž‘:øUd‡ÝGÝwíWØ®¾/$¥aºw$¥™¥,ˆGÐÒ.O\:IiTRàSöÅçû‰|ô˜å}Úè’_–ô‹º‘ØäãÒ1öQ/‚óaûD7ÜÉ5Õé¬z—Îs–um—çe[moÂIOÓö-|n]ÏMÖã“%/ŸùÇ Ž¥éØø*ƒ¯ëÑ6Ýp‡.o W¿ª Î\¯×#>·¬÷Â<¢u9)}×}ͨ„×÷ñ`Ç”FÖi .SW%»@ÉG?¥ Zj&®b&uÌâÖ ¯Ÿt‡oê.7Ózqes ¼lòµÝ>©ñÌ šf…)}Û´’΃©.ؤkÓu)_ÒöY;•IÛ¸.wÞ“þ?n™éïðòð>DG òÿ¬7+SY’ÒwéœËãÞ!±ídØv]…; ®×ižN‘é o\p—4Æìq÷SÀdJ7)Wás=†6mX”K›nsíÆ¥•”Oôºtb£e1µ?>¯÷Mi„‹ºé†å}¢-—m}Mû;kp’ÖI²é Ú¼.õÉTß³vÞ³H €‚§]‹iR.íuôï´:“åÞåDd­OqéÙˆë¸ݶemÃÛû Lg¹¿%îáHž:÷0"hÙšrÌ£#©÷õÞNÝÿ³ïK’Þwâ›´wï#Æ•—-[©}ûvÍþ}ÍÕcºüò÷kÿÝÆõׯÿ­]»Æº0ëÖ]¬ë¯ÿŒ6n¼Bããæƒ?6¶I7^¡¡¡C³Ë.œ²Î£®FžoTîÞÕ«¸$hº³Wvjÿ#å—Ž®ÒǽE’tí-›´ã½c2¯‰Êœq̃’ü ͇™žÆÙüm9ˆ{²·½éIªÍt½è6ÑòÅ•Ùf*TRãö1.í¸ÏLû¶qù¥¿¤mLÇÏ”wÜþFOÒ¹M;ÏiuÌæجk#©®¦Õ9—ômË•4j—tNm·µ-G¶y%ôõ%û§ð®ç+`{¼\Úƒ¢dÉ'i´&éú ¯ãºïqëÛ´mq£IáÏ’Ú†¸¶0º®MHk/’¶±9^ií[R>¦}Hk;âÊ‘¶Ü¥­NK?KiéÙä™e=ßy¸£<Û4ÓÃjnr¢š!?_yšª`YR0­þ,)ߤtÓ>+â˜GËÍ£ç9­ qõ1Xf³½Ëò¸uÃuÊ÷q+ê<¸¦[Ƶ_—[ÖrYþ¦Ô+\¯?×m“ÚŒ,¢×~Z iS®¸.e —'k[X„ªêrž{\–2g­‹U±¹.êTÞ:`¤¥Æ|VVŸI›‹ÊeYÜ“ª¤§wiŸ¥‰ jLåIZî‹ë~¸4lYr—ýÍ<Ô­1NªqAw;Ûié×¹³”µ3d»~Ñu´nu:¯:?H±9§6÷µ,n¢»Þ\òˆ{‚njlŽ…Ëù¢ƒ W¾ƒ_׼ꪟFZúT*µé©Tž‘ÏòØæë;Xð‘fÚ¶>¸,aRG!Kú6Ûä­+.u¡lyž ·Iƒ°*ø*£Í5êrM7YQíHE><+[[ëL[÷«ZP‰¢ž¨ÂN•ÇÕÇÓ»ªžêÕI´Ó`†ÏÐ:]cI£,iÛ¸~æSŽ!šéa5ÅEž®Ÿ†D«À ­¾šX÷›PFÌà\ÕOÖ)ŽiéMÂH Gãˆ6¢^P‚Ð ¾Ó¸îØØ&mÜx…·²¨·Ò¾=ì¼ó^k\¾eËÖy˶o¿#6¦ý¥´ eóæŒËM£,’´bÅêyËx9è?¥þNKt´Å4Ê0¶0ÊôŸRÞi Dßm‰e £-þð_Jò´ŒŒÌÁ™˜Ø9ïóð2›ôl×à¦Ô E:üMbÑo 3 F[|°Ä##«g? ÿ;ŽëúÜ•´lÞ|ƒvì¸/5`)Rx´¥Œ@Ã4ºãc] ´¬[w±Õ²°"§%¤”1Bb“>Á `VhвiÓ§œ·¹òÊ?’tÈa ÊéeUOo#ÿþοe òç òçèçüë®Ôo«ƒ,###« *Rú;-U›˜ØûNKø3›H×u}îú.h‘’ Óg®ëð§ï¦‡Á¬ßƒ/ö¿¿÷_â°ÿý½ÿÇ€ýïïý—8uGРÖZÔA €Z#h©‰~ŸGÉþ÷÷þKö¿¿÷_â°ÿý½ÿÇ ß÷?Máß¶dÉÑNëONî)¨$š¨”¯<¶ D®½ö:mØpiì磣«fÿ½wï#9K  ó;-££«æ*Ñ¿›Œ¨h¯‘‘ÕÆ~^\Ðuy?à–Š•xbbçlEÌ×Ô6²©åàG\×t]Þ/´´e”š$éæ[t¾e?YYíe¿úµƒ`F?ŽŠ¡±A  >ÚxSnã>@SÕþ–ðË÷Á¿e€rE§(H‡;õ¦9ÖáeÑQ’pZ6AÚ\ðhZ¦ôãÊ—FZyLë'¥e:{µZ‚¥M/Þ@Ó„;ùÑŽwÜô§pG=úÿ¬ù¤íâÒ+‡KyâÊO@Ū}ÐÒvá›=7<ýÀu¤Å$(%xøfÊ7©<ú[Ð6DnÄõ]—÷ ‚–èÇŠ ¹¶yq#6#E0®#<¦¿ô¤kߦ=±M«íZÖLOúâž"¦mNÃUÜû#Y¾©+mÄÆ4Å,º~–wcöJ Z®½öºÜið> ÔCÒˆGt™é½‘,ú¤÷PÒÊ—µ<.Ë]Þƒ¸+ƒ—V-Á{+ª1>¾SwÞùÍ\i´:hÙ¾ýmªº@ß ¿´ŸU«ƒiækwí'xJ46¶I»vçX¤¾òøÚk¯sZÆK )G¼Üyç7uÉ%ë ÉèwÁÈŠ`%PÊï´œ·þÊÔuÎ^ÙÑÏhrrO¡e!xü+"X ÔâÇ%Ï^Ù)=ÏpðÆ42À^‘ÁJ ò %XîÞÕ“ô¬×´m¾^-ºÎÆWx-ÐfeôŸK Zæ's—%]¥½{±^øÞ÷¾¯w¾óçr(ƦMŸÊ´])AK889{eGwïêÍYd|Z»vMâçëÖ],IÚ¼ù†Bò@³ýE˜mÞ|ƒuŸ:ϱ,%h‰)Y–´Ñ[ëÖ]¬mÛn×¶m·kË–­©Á ú×¶m·W]„Z ÷£·m»]Ë—£óÎ{m!¥ýNKQ£).Ö­»XË—CÅ /¾G¨Jýqɪ‚ <¾ƒ—Rƒinà’ejØèè*ëmV€æ+=h‘Ü‚• P Þe‰þ  žþøÿØK:¥¼ˆ¿æ¸ù¿¿ràÀ3²ý]–h€b°/íØqŸ^÷ºW[m ^ Z6l¸T““{ŠÎ&ÑÚµkôÄ» ^€ß,æë[z+™V• xÙ²ekÕEZgË–­zâ‰ÝÞR¤”éauy’ðÀ;ï‘•¨V-i_±Æ/œ ÍUW]Uuj¯ècÔÚ eÓ¦OU]ôÕ;-š§µ#-Šñ“%OZ­wòäQ^òs ZöíÛ5çïËÞs‰öØí¥ šcÛä¶ÄÏ·~l«>ýûï%/¦‡¨5‚µ–:=ìš«ÇÊ(€†xý.°ZÏ6–¸ì=—$~ž´\~ùû­2Ð~¨VëÙÆiïɧ-¼h`Ž%v«ùŠ%x§@­´¨5§ßiY¶leQå@NÑßЊ´õc[KËË)h€“'òöÑ6˜ ÖZÔZîéaNgöß½^/or°Ôét8޴̵×^ç´þ† —T’zéÇã²dÉÑNëONî)¨$õ+h‰vœ‹îH—ÙQ'(Uø£ š¾Ò¨tàÀ3¥vTGGWI’öî}¤´<ÃÎ[eê:g¯ì”~\Šd»×^{—@-8ÇRuç9Næéa¦N}¯×›3òÏF«ÉvïÞGR;²áNoÙÎ^I4/›s\•Ò¾=,f²Œ^„¡¤éh¦€ÉuÛ¼lØäe ôÒÊÌ}*XöVZŠÚ –»wõ$=[maPˆF|åqÐIOš²÷Yx¹Í:6yÙ°É+n½´23š@Ë™‚Ç–ÑÑUóžšG—GGHLÛÅ}ý·yYŸÀ€>‘qÄ%îÛ¢²¾pý·)hžÑ—ù}NËÊ:âbSÓ~dé|×i*šë7™ÎsR²ý;«V½ÓÐt–÷9A @MlØp©&'÷T]ŒÚ)û¸Ôáý–ÉÉ=Ú°áÒJËEQÇŽ ñõCŒý¨¨cGÐD´)H){_*iÙ·o—÷@’\_y E#hPk-j @­´¨5‚µ6ï+×~ä¢y?eXû‘‹æ-›´lx绤w¾«”@¦‡¨µ!Iºüê?«¸`Ö‘Ô«ºçÿƒ@/Ô*PIEND®B`‚snd-16.1/pix/n5-all.png0000644000076400007640000171765411210265624012755 0ustar bilbil‰PNG  IHDR~eˆ(5 pHYsHHFÉk>€IDATxÚì½g¸UÅ–°ûÖL+ïœÈA”¨ Š0 ¨(ŠŠ‚((˜‘ A@DTf% ‚" *Š"$çœaç¸òLul8ǧûØÝ÷»ý݇÷Çd³öÜ3T5RÕRJ)%ç9ÏyÎsžóœç<ç9ÏyÎsžóœç<ç9ÏyÎsžóœçÿG(ÿ_?ÀyÎsžóœç<ç9ÏyÎsžóœç<ç9ÏyÎsžóœç<çùŸç|à<ç9ÏyÎsžóœç<ç9ÏyÎsžóœç<ç9ÏyÎsžÿ¢ýÃß„0! ôŸ\Ãò(à¢. þtžDðr (¤ G z#"ñÞË  €´³ÿS°pø •¼Å2þp£,a§ùHNw¾;¯<ÈCâV}~­2]𠯻ë1é¢ìÃàiú £ÿíyÏ=³`+pHE  žýÙT¼€‹Dà €¿]õ?~¿ÿÓT·¹’€$’$à’@â \ÀD’¨€ES .* þ«k $’£€_9#»2ˆJw4åµÉ,’Ѻ‡ßÂS1êèJ¤;‡•ˆ@2³1ÞÍ鑦¯È¬ÉHýµ´šˆ'u?åClê*ÝÑPÙ @ÞYùˆ þ³’E’ÿÌüWÕ’WTP ” d"ûì{CõSÏž/ù÷SnÕãâÏGûo÷PѰÏ^?TÑh‚çO-ýçg«¾ÏH`‚ÅœÁË$–ó4&£Ý_ѹˆc+> ±šk‘Ñ•%-•Ï–”@¼fôBp#ñ[ ­GΗê–5üý³nÏÛ^Ðw§nÑ@¼‡Åd%–â1¾'‹KyZ¸|‹‚Ê:*¸çì[þù»K`Hú €kñ‘äf\<<‚ÂHlvº£ñœlr”»܉e»¸`Tí<}=Ä[W.UÑj€ñZhˆíb çF‹B%ÐBl÷v«$LJ?wˆ=é UÕ4ž„ Ìlˆ LÌö#¼ƒ³ÆÕO뀨£ @шë¸I¸L%Z\¸¼ ( ø“4ûùïËukEHù›ÜUkå¬Üé;£šÀÙcêgÏÿhþ]Þ“üXÌ‚Ì\$ ÅèÀ¬ÞÓAÞ#jÊÕ`ýž8‘§JÒ!qÕ¨H/~¢Jø%ÐGh@z¬¡z(#òŒè“SZ‚èJMàq=ˆÞâuà Ñh'~.d Bà>,l|ty  ÒX$ÿvðÈò$𒼤ë>´…û¢¸ćD†@åè¢5à\l¦@Ú…9“ -\÷70:¼ÀMâ ˆ¨ò=B&_‘ŠÃ&>¦çæÕ”¿é“p’ÓÀ4 „ÎêV ›s3 ÷ì{h€çO6@õ¸g¯¦ò/µß¿´ þÞ—y¶çγ纀ò·>7ÏÎDÕö†HÂ@>y@:à"@Œ ü«¢%ÓeºÓðìÓV[ “’¶L ŽÄpA†Q€*Ô³ŸHv‹úxé@ l¥!Äŧœæ*q%®œC¡tàmNË ‹œ>`[Ég¡°í¡pfú‘Sp|ÊñŠÒý`>é,uªÒÒ/K)ƒœå9×@ê´”<f…ÞàÓiƒ pQÚÕà¿>åðNk j¡úP!¾Uºá‘Dˆ61àsÆU8¸\…ŠB Òr<;G|À6ÎéÎÚ€Õ½ëýS+A ð–l Q Nçt… ~#ò}ü@=:E® ”5@®‘ Ai¥´†)×| ßÅK'4ÍäItÂòa~GÈoåi¿ƒ ä :ˆTÀ‡ð /`´³VœègßÊLÿË‹iD¹(Wÿ…?¨…ØœÓR äÙ÷•$³«íFyv„ ÀâO+ HK ‰D9+œ½²DÃ$Á „ìG}÷v1úr§\ÄêãÃEÒnzâyDÜ<}]8¢Ìcwq5ÕeÔ“Q>ͽD\‚›ät} 5A¤’¢#¸ÁdgüÙ^:Hö¤A$úY¾úí¬Nð pNÂÅÙÏþ±OõïÝ·ZŠäßÚùÜ'âì9îÙ>¨Ö«íþ9OâÜ»¹ÀŽ€|‰­àcH/'AyŠAi@K à Â¿ðƒÎÝíaP…H%P‰hXHüH$àAüízâomd êY_êïï#þK^’<ë±U·^õÌ ÿvý÷ø<ÏyþW±›–r+Ùáô#Œ”óe{„¼’K{p±í Ñ­t1¿sÀù†„lQfàuš„u0Ýð%\rivI¦€ýrôM„ó]AÌ—šu9šg~vS ½mÖ%‹ßjÂ)””É$p•$mQ”GÐÓÿð «µåV$qÊ$ÈÒщ‹ €Í9ýãC¼(€ò¿,óyvÎúÚ¡:.=õ‘@ Ÿõ”«g‰M‚|®jäß›gÿ<‹˜äãÈ‘¬A•›éKغ™Y®Q”Ç—ÎÊü&|#V8ù ŽI¹±¢np‘|„˜/@¾@7–à>±™´c*ýYÏ-4!B‘I%AA Aï2 ôÍdSÿR í¡°É¹†êâãqòÄd>§>K°ù§ñÛ‰oà+ðßbgˆI2"~NI€u¼ ´W€Ó;±¸B. Ò^]y'A7'1 •éò&0®È9Cºú“¯ÅÜ£AãJ¥PÀœ³ÔÕ‡ Àâ(PŽ (x¨¶l%>tâì\|nކscä?ÿŒÌüß‹äï[áÿÇïèž ÎÙÃçâ~÷«ýÓèÙÈðÅ@ÝU®¦Ú[Ôqð3•š°…íÎ:>—®3„¤}WÙ1Œès'’ÈÈÊ3Ï ”¾ßÆMÐû®£ÂP2T>ÒÆ ©Zð(é‚÷–iß^ÚÿÛWÿð;Ò?­ÀÊO€+EPöq È¢6pÉ9çÇøk~äsd•ÀR9ˆ/Áý£ +äp×¢‚=\¶GV®uW@ÁkÊŽçwQÒåø#÷Š÷Ìi !ñzEm^MÌwòégšòY(×÷¹{À¿³eõEM‡‰eœi¥ZÔ¬q»ø ô3âCPî/‚*h¼{Ö¯ž:þ=ª'£r@’…*Iâ’Å·Ä‘üB¤0°€úd©@µ£qεÈÀàœkQmÈV¯x8g@WÃ*ªdàÜÄÆ"Øœ 4aPL 8D È¥6Й ’ø¤•H*Pèg üÿ pªÍyy-ÒIÈcçV9Ûªå.¦øô@ZPcÛz‘óñ†ÍLªøb]{Â…?K+*·Ÿ#£î-~[ý~¨þvú4>óï,ÁñÕ ¾Æ=ž"«3xޤ½â¾ >R—»MÔÈàÎãŠOˆ£89‹Ô·P³/çEпé vpˆqb.¨—’áý ò˜ÒæpOs Dsr°•³¡‰ÿÉÿŸâJA.`¸©òp2E+Lw-1¬ç™Æ²ük¸Ô]tæJœä“Ï Æ{ÙU7öpr%%ÉáÆ·¤U}_!0ªŽÄ½ÇýP¶iwHµô» õzßÛÚÎ÷){÷AàM5ƒÙ/òm0¥ÁfÆxÔ=À=5w-Ôçjo–uy;¯cI¤Æ™ŠWŽÅꎂhÇM ø¹Dsq)ˆ$wƒÒ °˜bu€;ÿüÇFF8Á³ 7‘4ä -åL³©@ÊŽŒC¸í°ÁÝN6¥n rÉtn¥»ä<êp}Ñrqì_ðw; O­ÀJ <2=šsâ T¶;ñ0”]uä ”¹Êî2çBÅ ÄCX”ã>u^ëÖò+At—s`‹|ä`F{‰¼ ø^¿œ©ªÉ­ê+ˆÌ7?MeÖ‡5:`ZêÒ‚õðú?7®åoSå6z_Ê«KOïÜZU`Ì­õ Å—õ¯çIÈ^!w"Åâ„Öm ž  Ä_‘Õ ƒ2ʈ#Ì»œt ƒû¬«éÅÏÖÒÝÃöW¨vÛâBwhåרꌬOY¢nNñQ©äøg ©r)6ƒ•8•!$&g¡a++ÐДÉHÎê5yœãœ ò–QD·?Í/í‘ »§.^\ñ.ùr+ G¾¬!Bˆyr¾ý.ï9ª®Ár®ªÜ‚fÎ-¹Òø¯}ñÄ^*hH(R·ÔBV,(DDD>…d/å5¨˜Z5ªn/€Ø n.TI(}üØWà›d퇴aÆHÝ£¯ƒÀmdl­±ü™þ1ò^îïàYjÞE);AÙH3ðÍøÔWq»AOs9ð²˜Vϲ^Uõ&ÈéÆ[]ج‰« *³x.„Û†Û@y¢8¢G̈Ün¿ ‰«õ/ úZâKHñÓ –'k>¤òN‡ì陫!;Ö°;çÚÖõÐBá‹óާUý|§<˜²ƒ¥¬Vý|J\»+ùXmDLÑ ƒ( ç‚þÿ÷~6³2LJÒ¿|êÞlàl›]@ñÙ6©N¶ÒHç?6«ÓÕâRN°º”r2èÆÞÄD 9ÝL뵊SPºã·ÆÿÆÖš°÷‡_²áØÎ‚QP´Üý ÛB?‚»Úw-hsüËAÎUŠ!õÕ”× ó¶Pp®®Ý2ßwx.g¤OûÔ¥f?ð¾©ÏïDß{àÿ%¥7¸¤FgJ|ËÓº’£ñÆö}Us<šøFÛZ4s0(ó”v \ïûÅ T° Ä}ÚÀ…ò- .Åœsº« "Î,öÛr+ïdm`ëÀ}̽ÜGÂ;ÓÙ fÛ3=À¶b{Àj\9âÃ*>ˆz:‘Ç*ž†Ø²¢w %75 j´n=™¾ºmM„÷ݺWR!>÷I~"ÇøŽHíE|šÿ2ôûo{뜼WúÓßÎY›­& p  œý9ð§+üŸ¤ZbÏÕáZ¸àoOû?KµýS˜d&þœdKàERÉÇ@ª;dĹáÊf»·˜Ž=™Gã#“¸e÷"u%×ÌI­ÏÚM·}±“§¿*ðNí÷q&0>´ÃíìyRñ%“ê“éëؕ¹0™™6ÑòbdlS¦C½CÚsPÓò4‡¬¼Ã }švx5AtO!ÅBåm„ÈàwÅdmκv .s‡ë<ÎYøúÙ$iõ[þwCÊÕR–@#(g5—Ÿsz¤¨öƪgA‰D"Øì†¸ @î– À]#ëƒü]®w†¹"Ûãõ¡èrë(Üì¾GŸSêÂÞþn8Ÿøê Ë¡mž>\8>4ê Ò;ƒ¯žØÊïj(ß)×€H§à?k•éœ äW‡ƒ$çæé©ÿ½Â®(.ð UÀò=”Q*‡A`cñ÷$¢àœ–­NÆQ„i@&  5NduÿK}Â87’ÿ{}]€¹ÁzÙä­,w±=Â{œ¶Pt«Òòm1bµœr½&ª ÖãZOÈè¬.‚P¹Xb"ãATYôÿÓ=Nç´Ï9a#?8ü=âp®Ã{öxQ 0Pù¿'ÜcãIlþ^àr®\-@•s¡Ìjÿa'&ý¨øÏ ‘€|]N¹Ë½õDЮch3Åg ^õ@dqóÿÈ[Å9 (| häâlRýï!$yvŽý{ÑXõÑ! tã\¯ÿœr ·êÖm¼ðhq»|°b°Z!GØ_(ûk3[™aâäR?9Ð*áרl$›oÇ~Ïþ’ŒïA0ó1ð,ÎÄ66™=ÐOÉtøS¦ðYà¾@sw°'äOy¼ñ¡de¬½(<Î"ÄŸ@£ÆÞ&ÛØó¤±”ÉÊ>P¤¸Dw’ÀJØM¸ŠÀMÔÊ¿¹~Pí)þë´w¡û¸kÜFà~(ׂÝ76 Ç™ÍáX-g>r­„ÈžÕþ/àè$ï"×W:\Y?a7e\,7þ0[äáñ 0Ƕ²Øó±~‘l`ôÐj:B=¢ qV³ÍóˆÛ‹fÚ`ç}4å Y âBYŠ$KlBˆåâ(bÐò×WÅø²Öÿ•–tÇ®ä¤ÓgÖT*Mœ}„•5ÊIŠ2ùÏ‹9PY¡d’ARFPñˆ 3ä)&2ZäŠòyÙ2Ét2äˆø2Bn¢\¡†ó–œöÞØØî&m š99º‰áÎeêR†[÷Y…Ôvî¿ Þ‡*.`Yè¹ÜߦI-«›ø©•.ó¡ÑJ}¢ñ:æ‚ÖVõ~ñ-h#HÞ8«éªS^.Æ­ö‹$’гiù|\,¥(äÐâì¸Èò0€¬³ÉýVÊÿoLüydDZã„"`g€Sø¤“ƒà1B“†B:’"4YÀŸm…?{}UÀi©ƒ‹\Î;¼‚mqG¢ž’#Ùµk´–åöëbU|éÖñì*x¸)5«ÖǾ$#ÜRi jz:X¹HÃ#>Â0~Ö¾aœ–­ßÍ`£±Ò’†Ú õ¤æW; ÄÑHïéSâÚОûÒÿ8ðpå©!°;¿t<”¼âOÌÃøAŸá—êîAŠ<½B¿Ø7|µ•{AÌã$ˆ+¥ 쯮Ö €t^.ã%›h…¤g²ÂzÜüâoË»Á}ÜÚ‰ÑÖMKº-!ñ‰U7º—Cåb÷%¨|X·ÂAZÜð O'”ä—ú~Jäz¼ŒH>ãËf«1ÄÓªš“x=9HÙe}ªvPž³Z”•º]ŒË\»ZV¶a[ΞJ?­þªúÈÔïœOQ?‚F¾@'hØ5íy¨Õ$¸R®Q›ƒV¤–€º_©¾¨nCˆSz-޲ˆ|®)Xäs‹á€~¶>½ÚÈÿïU¾&ÎV_IªóN‰Áÿ”R]ÝUm ö&Ém4%F{¦cIû#l9ÝJEst–€û°“ öû5°:ÅÞ‡ŠhŵÈÁèïˆ=8é°õÏ;|»qwæqæÝ’£òjùwuÑlöîf>á²Sžrf/ÃYëšõ`©ñr2(¯ðݪÌb½¶E ¹ºHÖ±U2|Í“7Pb¬NN#S}Úl‹ðÏMöå^{xfÄ—ÕÌÙ iÓ”V}D]‹[TA¯NâVPþJàIÍòŸ‚Uý“Á@Êí@õгz ·^ÑD&ApŸFw"+ä:.ÝÀÍÝÀýØþíÌ· ÜÄ2¡ü9*w9CáËnœÒ´ÖéÁúaô¢=¾ÍÌÐ>÷Ü*ÛTnÑWºDoQŽ™ÛŒK˜›(ÖjÒ;ñËiV#oðhr~¨Á‘ýɾÈè.§"ÑÝx»7¿ ©ËÔLõRŸ@ú‘Ý¡=GÙéoa}Ä­¾.Ö@ú³ÃýÙû.[’GEmÑ=1‹¥Þ“ „÷3óÞœ7éPó}»¤õ¤äLá]Hy‚>¼Im)¥nmÅÚ§6]ù ¼—pèBÄilà:Ò€0Ÿ€[$ À­¡Üò@ò({X¼‹´.”÷#b_¹' ¬JÉEÆž/ážÜ¯6C–ÖÇqgÁíg´}ú³ ü@ L9C[•lB3rÇÙMJE'@«Z ˆŠ½Jo&*VSÚqïí ‹uAUy”°rñYãý2!Ñäù®Þ!˜‡Rcz«)ª‘qÁ¤{ú›?ó´ç>3‚ðßá½iÞûí|ÆyÚ¸Kå8ŸüLÆõ£ïØ+Õ<‘°'‰”ÐéD5L+q-Â÷“µÒ²õ«¡åo5  ßi>±å¯ª·ÅQ·ê]Ú|Ý[¿û¦{ÊØ´©T[’|së›t¨x¬r,+åÆú¸Ã?à‚—åIu¦]ƒÉZ/¹TvÔîëÝeAÚw‚Xš:ÔM2:íyw=®zÐý%ôWCJ}ù5ˆ¯EoP›È¾ tf!ȼ Ε\ŠÕà”¡H3ÆkˆB¯r…î…ª”f¸P-…+-Œª·É³g‡+ÄfgJF!ï'~ /ëvÆ0Ò|È0H&û±ž7ã?Ê7±ìµÑâ§E7Dta¢ b}Ĉ7ä0ÄªØ å¢@â ow8~ÛÑ!æþ±¶B¶€w¯ƒÏE€± Þ%ºÐë¨O(@霭ò–ûܦ΅ÎLû*$à€U‰XÈdp·í ú‡Y±µ_‡ð¦Ê0X³ÜâUjCÆÛÜÂiÛÝéùxp„ž)/¦<ýzý ÒÓ.ÃO¯`#ÌüÝÓäŠE‰ØÐâb§­­'‰Q‚n!vR3!Ô¨Ä`ÐZó>¨M•U DP^SÖ‚â‚è£ÊFá_†'þIãïí`6#ïùš{5¸Ë?@Nq'ƒkñ¸ùn¬r<ØCiÎ;îdtþ"Âû¢ñ5äþA.0â¿0;ºìÎ…Q«çÝ7xø{e±Iõú?(ç’Lw(®»É¾ÝÌsïæ@ò>^§Nâ3×¥fiW“w^hLâÊßiiQkõi<ù}·öÄ>3^þŽr:‰…G¨ Å3ňµIÍ„”/ ƒ<Îà#Úº)ð*hW«U*õÎý¸½‚m<ûÀ3ÅmžžŒß5WTT5Dõ ýey' ­"ñ ;¼í-È;+Ÿä&½›ØÇvCxæàˆ'ËŠÀópJ_Tñk¥ŸŸõwR~–mÕúÊo¢¹…w°]µÓt9My3m>Qåj÷v 0Qn¦#àe?aÙ€íŒ'"šRÓí)>倛,Ý&îr"‘ìs¶3œTãpj87ƒ™ãì¡Ò½Q=ÍéäRe'™—á˜Kì‡n,­ ĽÉ_ |Md $Z¿R«b÷S•ÓNüBZ¶.¯’+³v]vmbÖîÊæÃl¾l³ö-/ýJÜ’9_|„ðä¨ãÁ¨­vã õ%PgÓh‹‡sa°j÷öïë\`& ÈÅEp ’‡äÐŽc8²1Û¢¸€zØ@stÀ%4ÂÔGç\¸êï…sGy¶4DŽc'pàì*‰¼ÀçbÔž£=®hASzþ+ÛP翃Ä!ŽÉŠñð«d –2!ÙYä”5[|É{–ÍWr£5‰¸ó®ã“Í˧ãÆï8Õ¥dfQ'œº«²êÁ©Ö§Ü¼SI]Âä#—×ý[O_Ws­ÜQ”Vs¤û[I(ˆ §1º9ªY µ3Îï¾â`ÿÄ%b•sEl7GÓ3bÅ\oô‰÷g¿ÿåØD,_Ÿø:tãD_ð펭Ï£‰¦àý5ù>ø::Û!7¾ƒ¬›}!Mæ@è¡ô7°ƒ ‚—’ðJí„bÔôâS;‰±M ÞPǘÂ!àAµ?ˆ<%…ù¨ô€:@Üê>fƒü…v Òÿ´~I"AF)Ñ…Tp ÎB|$dàe#£ä´æ6Ù_v'Êw ¦ºh+»0ŽgeW»=Ý«ce¸vVYon‡ˆ¶¨jUµ¢ïBù‰;¡t‚ù ä/õû!þQÀ€Øçž» ü™”tˆ5 Üf<¸ Ê–$ 8ùó™wú…'!W!2Ê’¡ÁûYp‘•> YÏW{¢Æ¦ú!}t`3è}Ô‰XêõúXtñ®qƒŒŠ6úq†aè׉Ë9*¦q#ÍÜ'ðϬõþïóß»KC ‹#T§¸þîgHp"Ø,gw»@œî…tDÊe±ç)H~U>«ìp¸õŠëD àÄDz!Öá·´gÐ÷®OG ³vB™Ow!}lâÔíï™k"‡Á¿×j¹#W@J…gÔýÉ¯Ò£smFÌ”3Ê:*•'Ôi¢›º[ã|gWÚî`)p®ì?óC‘,g 'Á¹ðh:~À‡ d’èhû¹Ú3 B÷lê^Yú÷ÔŽ ŒŠ¿õ^)@Œ$&$°""ÀAN ! u€»èøOõnu;Tkòé¬*yЈ‡{í^·¹\€t?‰¬BÄ^)ª Ÿ…'À‰ÆÖpÌkŒ‡¢.‘{áØnó¨µG© nBÖ& ²Ó3[Aö§iApƒ8 b’Ú©lRt„è(^±EI/)õ€€hòO=}uÛT'¦ÿ¼j(ø[‰ß¼æz8³î&û+F™T2 ù º âûÅaˆz­~`çï Æ•™ËÀè,"C-¼o#üOªpÒ»Áº‘:cjº×…žäX Žùˆ9AýÁÓ(:ƒÎÁ`´?d¯ ïá3£Wt)í‚DLd wä0"” gBàÛøžHù,K± fß9$³.Ï›À™”Zú,(?hQv(Ãõ‡è.4c0óƒp˜D‚S˜x©ýŠõ˜€èÄ£ ×°D'.“‡äRš ¨Om 5­Ô¦öÿÚðfŒp€À1N[Ùd ‡|Ï{)ñ=ïC¹0±ã¬`;@=LbN~óSšÉŸÍG˜.'ÙOsƒ{yt+$ß?] Ї6†S½«ÆÃá*ž†£W¦ Èe¡kp‹sRV T½œþ Ë]‚CZ\™ú§"/y9oÄZ‰§#“P³óhô6ûòœ?’ÙŒgCâ%,íw÷stí¹ î¦ÔB$ˆËÄO2B XYP¯CþXP_È{áŸoB÷)8(ãUðA?»Ä·»§qãmeo”àBy)?‰åC°ƒ£À~òÍœ–³äœ1‡€yÜò§+Kiü½ðס&* 1È£¼‚r¥UF¶üØúœB·Øó­-ÜQƒ“}"½áÀs.ìºOÝ ܘz='‹³2/$«ä‚”kÝé§?Ôߎ<¥ø¸¼ü*åYzFš{ïd¢¿áeWBð±ú&¯¨—–]Ã'†ª–ïk×{ &+½ÂCä^í÷ÀJ÷sÑÛö:E®ïG÷yÎíÞ3ˆ±ˆ”åÿ¶þa@ÆqeùºY(›o9ü6äŸL4Äu_“&Òp£—€]Ë; %pU¢7¦³<:iè×âŸ+ãA©/º"”Êzà)ç_p !ÓÄ4š¹™g”LõÅqµWf(‰­-ŠÛÞ£‚ˆ‹½[îÍñ‡.p­õÚDk›·-ˆ+õÇÁ¬¥-‚H{ßw8òWÏ.Tó”çæVöìg†}Ðcñ{ô3ܪ־Ùdµo (}i ꛢ ”_™ ¢R\ês,vÒ™s˯ÿÄ)õ9û ]Aà4Øo»_‚û1σ{1¥H[•/#­9ìÀ‰·–=Ñ#aq ·W:b÷WÕP¤œù‚[Í1±ŸI&;–oÇ»ª¬3”ßk% ,[c^‹rìß88y"o7”=›w%+ókŒÄW17ïF¾,?wŒgòÛ§ÝlŽ+߬\U2DÏåþX‡ì7Ùỳå’“¹¾,:ÆN1tn¾¢tñ¾mb‚öBâ}/æ*ßÏÉ;èbÈä­<ëic^å)47¡™ŸƒÞÐãú{$?G?›@ýTkÁ z5Á½áNå%ã/hŽCà²Yƒ¯Ž¯‚¢¢Dgý¬qµÃÎ(ž—cÓAÞ)fƒÿ µü¦ˆô¤ "õ/5<±©ÝÉHñ‡HeÇA¼N>p’Ö@3ÙäWr'Š›¦–ƒës~g‹; Å,qUH¡$ûØG v¿² âõ•Åߘ N'ï“àÌ5&‚ò¬g˜w'HU⇽6X+½oBåkÞ—ÀãïÀi³Ê·€Z‘û<ÏÊ ¢ïh’ïXÝY÷Ø\ùўǰX™:‚áîã9è¦@U­‚ l;ý¤ m;‹¦¸)×i~”À5…¢à#¬?zך‹¬!ê‡áÑžô ´O$Ѓ5ãcñ«)ÉÇÁ؛ܪž¬ÿ Ék@¼b¶¥ÄžÆ«ÖX`ž=´o¬KÀþÐÉ¥SA»Evîaˆ•â*.OCò)ç~OÖûƒ;Þ7 (õÏy»aºg8‘èâÏvsµÝåëþ]ˆÙþ|Ö‡½ÁJž°®ó·uÏ$>Sç%&ÛÍé\5ŒÛé[y‰ü•G+zóvùw|VªÊo¡d¿@ÙPŠÀÙÍvP7ó6hó°@ì/Ñ”¨:E™úiÍ!Ð*}2ø«¢Æ©ú*N ƒr†èC¡„vz¾ä}+ee¾Qr§lé™+³Vé©^Í\ÂAõáÄÊB߯¿ #tC²?Í” ’EÌò½dþA»PJü{¤½Ðs¢ö—€»F‰~ Ôø«ógìUÜM}ò'!/û2ç[ÊÅúàPg¥2Ct´ž®qƒjÏæ×9qíEOÄ9-Æ»7؃xÃÛÍÜŒ©}aGÚ{ m¦­r·{³Ã%Ê ÎmŒ 4°oÁNL’^4gº ƒrµ¨ z#¡ƒzJŽv¸ý q‹òH‹=Ó•g€íz ¤iÊãP>Z ÛZ¿<=´Ëp¢{ô;PíŒk8»_ýBnt»¨M—­žâ-ó%5ÑÄœËþøM¢5)ñqö Ôˆ·pÇ#cwé¯!¢7˜oCd®4 ²ObÄFjÇ 2BF¡²? ¡|@¬ ÈUáí =a·íqs!èÇÝ- '@¹ÀL€Ö‡} ô·:Ò”¡êlSÄNÝåýÀvñ¸óÝV`ßæŽÑÉ7 ’³- øÍsä½j>ÄÇÆƒØä¿JŸ ßr†âƒä3"ô"ûsÈk‚€ì8õ!{:G!£µ8YïøîáXún§õ3&0@>rŒö‘ûÔïµù• > œïãîP rŠ/»*|Mã3 {‘{ Ôåžœ]Bƒ¬Êã–¦N„]Ý/ôƒ˜ ½Þ»ôxÎS žSÚ‚v~7¨»äíœu¼•–4ù2d¶´²‡‚s‰ó2X§¸œoÜ«Á’vH䘵 ºƒ þ¸“ Kù*g:8ùíեȒŸ½(ù-ÔÑ(›Ÿ»¸-ŒiTë]xä]€ÿBUÞn †}=oÞÄ­—A:ö.uÌãHûúÈ;Ȥ7Þ%þAl$2œåx¡b£½«è€UÉ©cýÕYzÐðü"¾ÜôQúc<³uz-Üù5µCt&õÄmgná$•Ç£ì&µèrý2(î¥Alhè]PßÊêjWcXíb@këïbˆ1¬\³Ò~Lk¡éž7Á릂§ÈÉÆõ=¤vDxÞæïvq šw»r5úçZ²ŒÇÝŽ\ä§oa¬<Á‹Þ@ÚJâj;soh«>ÐVz–¹Å“Î"÷9õ¸¶SfŠ<㌣vé·²>"ç>棈n„o”Ù “»AUSB»‘††"+®5ßG)ŸV0 Û_³°'ò^(°1³æŸéN^FNþfR2OäFÉ(.Ü ™Ñ¤ÙŸ¦æ‘Èî‘þÞ´Çsß•ø¯ùy³x¹†eϤeúf»=ï§|æfSš †ÐÙ÷¥œŽ?P(nÂã)㮟ê x>RïÃV*A™Á… ôuA>(g‚hx6aV]½é%Ôq¯ r9?ƒÛN*H§–|'1©ƒÍs7Ï;äû5½“¾ã¯¬Ö•åHäÎg{Y:8•eãÀb^öºâ½°*2:)1x¤02Ž’Šåáyì)Øã<§`kú Ü’µ¹yt+é’»ŠçÖ¸™zÅz,ZŸ ã’K×âÆÆ›¡Õ>ùjÔ ÿþÑ2ð/ˆO€¬ú•@û$qÒ®¯ Æë‰ ©×Vþ„𠯬ŎÀt‹²euãTÚU5†P¯z-äI£Qí£Ü(fiå ô(»ÉÓ£è”Ñ Xý?®™7sPŸ ©ÞTÓýUÒŽr¶~½z]»|ü?ýPÒe ØY²$»ËOÁÔiJÓ_OM.§a/,¯DQZ‡oC(·—U"<{ìL¿_Àü*~á¶àtï;\¬/ÎðzЃ|L+L^å¡¡ïÅÈQ&§”sOZ827ý­È”Ô°)Ó«tžH< é]*Ï€bd 2PUù "ôEi»ü¯V6ãêÐcé-)Μõ+ÍCfÍ›­›õ£µ{ØGHÏ}Þ‰Ð%õ0ËYm ‘zƒö9èo) A?¦äƒþ‹ÒÄ< ˜$ïÙºÝs3¬Dâ ¬g S¸Xž‘g8Alâ.î¢) h€%Zˆ(Ô¦6 Yd!¹ˆ‹ðáââ"„B=êá#D íoc#Aâìš(§“ã'‰uvÓb,Žr‹Óœy@ )Dc5«QXÀüLa )âq阘0Î2üëU'u ì@'HÌp]ßÝ ±|w”|h¯²nl‡òO”Ñì=nié\tük}»ýVáf>¯:XzœÅ—Ú©4.Ú”™,ÖØ‚ˆ>“U¢„bP<)õÜòŒŒkPª~K=ˆ,[Zˆ8Õ-={â·§ áúÒ#Á±rjáõžHsõ]þ¨øXþÆe‘¹r²êa÷+ÌŠb«9‰Ähu–Y‡C$Dï§$ Oà–úµæÃ¿ë=PÔ›!(ö ‰¯¹ û†Í#Ñ<²;ý5֕ı¥gÑE³ì‘ްæ¢ÇÞw÷¡¨B1мò8ŠØHOÊžÀ“¤ ¥ªôÇuÊߑΕb9NÜ£ÜFT¬õ C»B¥eU?ý]ú|ê†GòÔ×°™¦¸1q†r¹^“]ñ¸ú¼´“}ÜB;4¿b-Ý=*Þ¥ Tþ™“‡i™•ßBèÓʄꖮïU•oAÊoældÖk^QcyÚÇ=8½˜›Òvdçz$m,'´•iUî\qIÚ÷yJS^×’éyAéZ/ž­hL¥çÊSŒUÛ~n|TY½Öîvy.u  pݑԣ&–h!Zb’G&5©‰<{Ì&—†4DÅÀ@œÝnü­¨Þ¨ý‡°)£ @© rƒÜ€‡Ó¡²ž½H6rIŒŠÈ0çø—É¿?S†d ƒtù¬Ëå|Hn”Hœ”£ˆ—_L_áQe þÊ[Ä汊ixb7–l@–?YÞQØ;ÞNÍtÇ‘Û3 (ý%Dz—2[á”]Ÿ#QÃ#2îáÅ’²Þ§É©gÓ'ÊÁ%û´£á_™ìO6kؘÁþzm{¹è«Å9EÙžTœÏµï+5¼£ ¶2‰)§¬Aø•QöD\_º}š˜²ÙEij&¹I¦'k×ß*âãGjýHKióo›óïWù#Џµ"I<­_Á¢¥ãw—õ ó61õ•Ò.ìM¼»èb,rFá’¬ºÅ %úyÞö Îôôåî¨N÷3\·\ÿÅ]êsY«\/ÛS‹þ僩Ÿ|Ñs!Q7¨Õ'é|%½hÖñ`-¼S15ÞÜøÅj仜~ò.ˆM÷ÝÖIí'tñ=…’üXëùÎ7‰~úRï· ˆ~çƒWŒJÏLëù~a]8=°šþ5³öÐÒZ“œÄ°’‚èi,µsÕ\tãd¬/ø6ãîX1øïuBz~4‚NåM t©fvø%ˆëU(SÇÆ`˜®Ë&ò5ã±#y‚ƒÁ­‰ßY¬J죃Ö„ Ô1Ç!B ?Ú»Ï@èmy¤÷U>‚àeJGÐo“Ý!½RÛÞB¥Ø¥N´Nb«´@”ˆA¼Ç05·Äîv €lq/¸s䈑õ ¼×ùÌQ¬„ÒvŽYen¤‘rjÑ{ʵ¾A+DëYÎæ¸ô=ÎEÑ_ƒßÑ#¶Ìxß¹Á}ŸÒH…q_ùÊ´W 2–• ¥½³/†òo²#Ê›åÕ»Nö œÒÕì7Y¡\›}›csnã÷Š‹srXxjxê3ñ>áˆrAåôPI5ÙôVÕ,ªù;Ë3ÆÓÈÌT>J\’¼\,Ș/ÃïŸ;†æ¹0qˆ›½ó’¯RÇï‰_Á/zŽy¦§0Q þææ8t}¹5 Çß?ÙE«áôD1Ö'€îJåVÿ7¸)ã.r¸¸í/@›A,­ürûæ›8ª_öFõ¯Jf h$_u…´°G­.ØZ®³SyØ< ⑇O_m6!ÌkÉJ<Ü£Þ„®~é}Kñ2]Ì’§pE_å\.užÇpîM\JÌYàŽDu.öÿªçª›ˆ¯º·ãñvõwCw¿’O¡:“=íÀþ^]c½¢¥¢š/z“`»êO;lt†¤â}â+Œ ðóæBì#ï!zß<¼±ÍÞ <í/c‡¼(P!¾w. Lð&Ýç½Û=›©êÏÆ;Î0újk}pÔÇ´3ܧÌK®ÊSR!¶µr˜½J7€3‹WÖÇr+Òù]Ž Çõ*w#è¡Ï”Oq¿“J>ûœ5îfÊ;åÕ¤d9=¹"yŸ³C¯ãäãá'÷t½–ì¦Ý*ç‚Ú™Á(â"ì>ž]ÌtžÁqj;»Áº˜=¸âkºá¸í”M$ݰþ m¤rU¡¤¶ˆ°ek×QžlêYÃVí!OSîKF¼67î‹`[»µH¼áÿ¦±˜«ˆôíɶf¾˜¹š ×–÷'ƒÎå;(ãÑò™øˆ—þøJnœ‚„PŠ^„Ù赉ƒçUåÊÀs—¾Ó|ŸAö€š7Aê,H:p;¤®õæQ4Å Ä|«.æT ¾Ö:Ám*Ïø²â¿;x–û†™/¨aÏeñ>õ/Ïa¾4¶ž=žºñÉ nHú1}‘ätvû×Y•¨¿”a‰yO§ÐÈzÄ“ôüùÀ³”r>­1Gé{»røâ¬õʲO&z¥õ¶r8ÊÉ…üìéj¶âïOÖ|úŠ}vŠ=¯ÙMùÙXk #"ŽÊ£|bŒµ— ¨s­ö`=¬^–}“û(3÷À­ï»ž\öT®Ð:CÎf¥-È‘gû!>XÜ©bx[k;I&Gêq³$8?¹}A.ÇF0ÔôKü7ƒ¬á¬y±Rn·¤[9œOåBðߟùD6U}òM£?(y`=­¦ž¸ܺ¾ßÁì(kBô—È6(%G€ñ¨\¾Á\Žôt‘˾¡±8Þ£œfwü>wz?5{¯¨x\ý+®ðVa9{´¶QGëOw_Ñ÷ÇF¡UÔŒµ„d~t”ÎŒ<Æñ[Á;!~ ÇŸxÕ³8~ÔO¥|£¬C ÷SŠÀXæAíã®q| D¶X ²½XRSŽ å ^GšÓÄqó[í#°&)9kçkÉ>þ¥üÕÿ4vüÊ`9ñ_B;©ŠíL)¤vôº”+0¢cB?AtvZk6ʧRÚq‰štêÿUɯ&2 ÈÇô;1™$ò8N´{$­r³²QqÈØŒ(½ÊÛY2Ë÷>á‚–)ïñÊ©'²wRPP·Ö½˜ÅCj· WÔ9Ì‹%OgUÚ ¨éy´ô1­ÙdžÛC¨}úˆžÏÖüŸÄEà4J{”á¾ï!½Ì»ìU·‚ö½ÿok{Á­‘lö±» èú[Bú7Î ð>Þnn1øBª…âûŠâzÚ»›Ð¼µµå¬óåyW>Ç\O ³9Ïê/ñ>\Çݧ´¬¼Ü®£öW[:ï3Å“nýÊ4ó§Å[í¯)æç;R¯Ý{Ø]¯Â¾xt·{'Žó®\Izúƒ² ]Žâ8†xŒyîïa‹å=²¸Zz¨]uTÂc¸6‚ÚžêÛ¨‘CJ rz­”CÞ“Úr¥l›žÔ Ü:Ú:ר”Ê\c‚›ËºÄ$b´Wê¹ßâʱF(âGñ 8wE>íw¹7z³§’@I_3ÉNæÞÊÏ1È¿\_¦mI«¡†=Ì²Ò¯Æ ÄȲò[xúV”NÝÒ£%+Q¥—| ?Ç÷!s¿‹¶ÂÍ Ø7£f†¬š6\,$™Ò Ð oèë´Æ|èß’1ÖýV¿7W·Æð@íNîQÞIŸG×¥MU4KÝö` ¡9èψš`ÔuAþ(Ë@OŠ[@ï/ @6âИÀá à°( ð4ýƒL[ÊV(ö ¶‚ýŸà&3äLâÎK¢ˆÊä+¢ J¯–IžQcôl?Wë‚rÑs­0´lƒDøå‘ Ô=õœfS;ü¿mœÃWLÇ൲) ʼn·ŒæJneíÓi#ÐÞ³þ°?UʪÇ •ÎöÇlK,¶“`t²ëò›½ËyžN‰ßíKkÀ›¨‰žÎ{PUÏÙJ¡; ¨­ÍÕ»ïŠ×@¬w‚è§Ô©¨°ÔbžÆmÕTF[ó´Óäè‡õÛÅÕvWíjµB¥ÕWïGõvÆfÚªoù¤þ*Z”xcÝhÈàD ÷úÄ‹/h“À0ÐèAPßðf‚ìú¬çã#!12¹”zö³ àR¤2†qœfƒ–x(#‡½ñŽ ®#YòaðZWuðy ²Î7•mfïP7>-2–Ñ^ÔÎ5é®&KÛ¡6É_ŠWÎß5–½ÖéŸ:‹`ÆjÙKÙØFŠu­ºƒªp/ o$—½·&vîM‹àÿ{æ*ö{’ÒÍWÏù Ûèîô']málÇ0RÝ!x¼»iŽá¶vŸ@á9yÛý‰"žÀ"ÀØÜ¬ÔÇ+ÔýÄÌAâMª¬åŠé|­KTk¬`eÕjuM__ÛâynèMÎ_Ú®Ó9€`ÔS Šó_ÿýeJÊ;gt ,öy0}Ñui£ø>r,cžªõ¹²êìZöA³¶Ô-–»J×e? Årt©¿¹Øõ–f¦ïcaòm_õ€š–LGÔ¼§¬+;ˆ–þcx6=Â_‚çhGM g€aECêU“ “WAÚ¥• ü_& S$§"Cç/ã”÷¾ò¶øž‰­r»)?&$¶‹K”÷â…®{,1…ÜšïY¹ÈÚ!Ž òˆŽ±S) •G 8E}R¢zðݤeCð£5ˆâ Ð,e¨(Ý@xÅݸÚaõ">¦áÒsÅ$^²±XÉʳëª÷p¿8·iØŸÓ–Õ=RýÝ$Õ ªzæê¸DõŠ%!'ÓŹÇà¥еÊ~\K&ÁîêIÍñAÕ¬äfˆÖµc™ï\•îPuŸ‚ÓÇÝ8Ý*! ÏDì÷ûzr²Üë¿–C{õÍòçàÏÔrÌœLÕ¦?ÍK©X`‘)¢ÓßÀ¾ËÞ Z®ýˆNtç¬ÇÀ?'c!¢¬KÞT¶”)L‹ŒûË’[žÊÁŒÉåO2'rWi>ÑÊ»O WðŠÊ®ä?¬üžÔ@ òsüþYál ÿC±WP}ÁØ}¨ž„ó%Âøp—G}Š;دܫM U¬–·‹v|­~Љföeƒósîüæ-[S©4Ù´ŒÔ¼ûu€Åaø;¤ÌƪÛåÂoqä/á+±y–ï±E§;º\ÄÝxؘr?Òî—hm­-ÿ Û©¬˜Œ!—ˆ-òË3&”ò›è¨_êYἨþšx=•EñËØæk¹ˆÒ»ª“ª 4J³AÜÞúwåÀóPø*Ќχ`fUDè©X'béÙñƒ¸¡ÂD>©7¼Ìµ|í}4ñ¾ö\¢yx-Õpô'~õ<9H—¬{>Ì”QVM<¡›ÍBHß-÷Cç=ÔXëí ¹kCíNéÃq|;´Ó½‘ÖaäkW³Ö÷’§Wj1­Ÿ1žñ¼,¤´B hõ/ÚíÏ;‰ÿ¿ÌÙi=êíh<ÅSœ kVóK‰'kX}9/1ˆÆÉCV[d"ͺQ±3> FóàT ú8}&ÖN÷qgCñkêÛPµÓ[e®¿;nÉ/\2“o¦½‹Ô¦>­Üñ¤:@”=ÇË(A¦æ‹5kVd>$Ôf€u©ú ˜«´ˆÈ2ßeP¹Çw7våZî4Ÿ[äâŠ;Õ¶B”tW;/Zƒ9ÐêEvr³,ÃŽôå3”ø÷Jñþ‚î5j¯G†rÓáx:f:XÚeb>íCÏ00ž÷¥b+†y–Øg]€ÐÞÐ_:ðæI¼zÚ©Uxùô¡,…ͺì ÖïH³•{Ž2NnAåñ0.ÄHžRîG•£µF ˜êa4Í'FãqßàKˆÔ5ÞfGzsåœÄ2µ>aßê „’£=yd§¶ÕÖð^²¡6’Ö¾ýž¢Fò5½µ[¶O^LáÑnñý8¢}¸•¢ªAž®x´hU]ðßw =Ÿ©í¢&vÚØÓÏ£ëëKoçq{|©M{û–ð ž“á@fb›:.ºŽÙ¯ÅSQ‚'‚»ÔÙµ’b Ôé婵–x_ŒžãàY¥ Ïl5¼/ ÀxCýÔ”Þ ¢äã°RxΦšª7\­Öÿ-±°Îjõ¿üMlÿ¥qaÒ„&ì¡+hqöI,Àƒœ ì#îõ¿Ý<±û­‹À|ÔíU ¬çàT“ØOpú¤ý"]â À=ô p êx÷’Œe„~!Q®…âî¾Èzu@|‚~JVÔÈÒ—²¦CÙ»™­ îÍ Úu$ˆåÚFP>Ñæ¡:ÛT…DÅ(o7ÆÏñ÷eUt™šæœÌ :qßÊfóœ~¡ïj»æñ«2;S_Ï7o$ž^Ëz]½ÓœÅõCs·»y3gõç>sN Œ­úäŠvî!ôæõJð¨ ýþý¶úÇ €ëø‘¡UwÓ=í¾ý«ði£Sw#=“+_Gˆ˜Qã·ª Dù89Ä÷)¢h™n)eêëz’B/¼˜r\¸ éTf¾ŒPtm5RLŠõwbe%÷–Š_Ð̇2Ž€xBLÇo/’ϰ7zÆ‚ýøéç8c¾Zˆˆê“ØdsýôŽøéÏPÇàÆ'z¡Z—?"cŒ"TÏsžn´Ø? [oì?̈èHß*Fˆãþ«q”¾‰ŽÌñ´òÅ‘‰}zœÓ[•è±o '£RìB‘O$]¤ÙÍ”§AY/D⇲x[%F€XÑA›ŸŽcd%‚äzÓ«®ãcošý­U¬Ö ŽŽMUÁñ?xÊšM°Ö’üÓ%ÞÝšŸ"/Ij¹õXi‰kAdš‹A/p@"Ë| äi«5øŠ `½îlƒŠ‹c=@¦¹·© 1BW!娧9ˆíÚ£PÕÓõ7jŸƒgžwÄ)KAíá\ééŒ*[y+8ÅîÀ¬U¶¦ÐQ,Ò/áSç1ŒÛùM}NÎ ÜIÆQÊ 3ú’’8™ñ2D_˘‚}'s JåëY«x¹ìù¬÷ÙQ´3w.oçÏ®©1øŒ^c;ƒÏÔË}Î^Ð%ev4á.âÄ-ÆóLhiî·nSŸcìL| ì3®ˆæRµy´”CiÓãSÙåoϦ¦¯fÜGVðx¼ K½£€Þß“Ú,ñš7˜¸ Œ5özð6ˆnBh¶5á]’¼•ﵓòuêzˬiÆÔ’7 éqw¿ÐKîE‰ÈŽ€§è9œ@Ï¢U¨êæðC„•átc•ÇU6ÐÑsoxŠ!3È0ž2Å£n7!ôe) Zj‹ÉP¦¦¾ ÆO{@Ú•a¸+­: îTÚåà!Ï ˳[Tû087ÎëϯN0Ôä 3ÏP–h›ýˆ•Ñ{Ål¿ƒî¸F˜½¸ ⇽“Aïêí Éþšà«éññFÐgøßÂk´öm#©¾ámÌ|ws 1äºd_Ë’§¹ÅÌ ÖãÅ¥ÁÓþ…ÉCúJe©ý"ÝÈ-·él3Ø%^é¬ÎYˆˆ ?"71!0ÔµœÂV w‚¨'¦%Sü ’Žœ©Üi5¡„¾[Ä{4‚¾{•}œö|«\Åw•:Sž/´_)ÒØ›0÷Ú}Hèån-Ê ÷uìØGò‘/†‘dˆèŽ?(«ðº”™4rOè›ihiÚ.´nÒgƒyÆë ÏI®Ž=è»%ÑÍ?o<âÍ’ŸÄ‡x·YÇ’Ÿªc×»Óù¢j9Mø©âV†RQ±ŒÇx¾t( .+¹—*(Ä:Â3Î|L1¾âD?ô£àIˆ p‹z ²ê§UAæþ9Wž™©kÔÐ’' ãwïí8¾Fñ“¨¡•É2¶‡z«?òJhŒ¾Ž‚Ò-’÷x¯´Ž$®PƒžÇ¢!®\–ÀO±»háû1þýCv¢œî~'~Û·8öšñe¢6¶w\"€êÍŒÏAxöÚ3À·=±R7ÉEÀÄÿÚ<å)<º!®ýZ¯«¬‰V/=þ­•ýæå /NœâSnº|ã½×z‚›=£¬W™ç9á<‚a,1kZní ¨V9Çp´áN\ŽºQ<ŠÛdšÓä52J+N¨ %ˆê_¦+ÃÀùžr°ºÈlc=ȸRìDL9æ0ãBwÞ¨b£cp?™ÿÊIû§©hƒÍÌ7º¢Eî‰OC”ߛٵ2©BÙsY—³½´cÈË´ÒÙY ÙX<&¯3Š¿¯õ:_å÷¨YÉúÓ·å  K~«œÛìo  v/_ÇÇçɘ'Ê€/JñÜÊ÷ƒœ®dûrõÇÊP·‚§˜r`ü6ðÄÕ1àVÄ£`úÌY`íI^žÜÐÈ[×ô"qð%ädõjàNý'~ðt2wRß·JŸîÝe=ÀcvòžòÞä;(Ûh?‰Rëb%˜ìÜ@‹àHûj¶o[ß36p§¹†R­ƒ]Ž¥G횬v79Ÿ0ÛÛÀÚÉïñöÖ;¸I|™7:I4³¹³ ×ÉE –ÓÄÜÖyÌï•;Á}Ü{•Ù~ !~…˜¥C<"Ónó8aî2ºs›Yn a“Ìòl¤“ç-câF\o}ý³Ä¥§_N{ç7ûFL»±'ˆ7yyò7GwžÞÛ¯|‡Q0\ôæh‘ìo+/Ršk­½oå¾QÜK´ÓwZÈ ¼à¾Ïö(Y¼K/ÿ[Ê.J>«æs·ù~i7E;˜À“¨ú4§üK`H¹‰Æðò*ù¤b#Ý”;•ê“ô°j* ¿E§°ú‘ÁĨš‹ßGÀ3Ê©Kƒ`ç*r3›2—Ø=ÑSoCÑBï*7€{·Û¸šëQ™¬W^À…ê×T…seìÈïlbvd½R@¸ò'u?éÑ'Ô†T¹­¼óõÏÊàWôà¾Ð›òèWi‚}¼ÿOn0€½M,Ò53¨ªçýÌÝ­/ ì·Oë©y¢£3},(-Éúˆ3¥3³~”Å%“rº‰:¯Ôx3gªj–QxúH­GH?ýj­ <½¶fw+åÌŽÌ¡•Z¹£çÌ]t©œ8Jÿ伟ù8ûs½7SS.Ф:î•‘\¢™‹+¦°Óù>|—ëíª¢”‰‘Ià{92¡==Žº'ü=ø¾‹¾9ñ¥&ƒÈÀ±„ÿ¡Ä޶ŢTùJ£´ö¾e5§ØW¿œ×½OG·È•Æ.g£}ZÛ¬þl…X¦xÍ+h!Æš+X*®µê“cšæ ÞöÎVœÈ“f#ºxgÉÝì ”:QË®°¯ï&wd^¢H`’[ÄBé Åc ßß‚•”+Á ‰î4Ä åku=¨UúK¼j¾¯„1¬CênnQÞ6 ¸ÁùÌÓ™h¢–~½Àsƒ§®záÑ•žÅjký½—Ö/ôKÔ_Äv:1ÂÛ‡ù|à p‹½Ë i¥¥€þxb ˆ»Ó v‹îwÊIlg˜ð¡Gzè•äGzWS\ù€ó5Ë*¶f—`=R#Í=y¢MÞobiÁU“ćgFœv˜T3˜?„ìš# ñfîªÔ?x7gUÊ'Ü–Éé%kdÖªù¸»²iùz4ÍWÑ8­}úWñ½¡“~Ëî;¥-Jœˆfq¢wäzVhQ7bÇ£@8v50;‘à¼LœØÇ&û1ƒ½Š*F¸gˆñ3©j< ¬¦6ªþ,‚¡£‚' ¤x/ø½\ÉL¢‡ümþyÙPîe­lzµ@Ùûx}—öG_My¢S:Ò¡jgÊ ª(I?ejÆ<({:# J·gµû–þ‘^lz˯ Þ_^uÚ˜f?ê>¨z½ŸøÞàªÀ3©K"·òMpfù6Ê•îáÝxÕ:•£‘Ê÷•«ÊÑ8®þááÚªNÐK_B`fò „ž8ÄR†–§ò]ÐL\Žz-6I†ýÒ-Júõ”Ñ9xE~e„òI|㊆Eû°0L¬æÆ·¢ïcØM£Oƒ:2¹|X·Chˆ£€÷û ÕSï_W¹×HåfDZ¨HûÛajhÓÑÓÚ$¦îQ~FËpSv ÉçÝÕ©9¡×Á«{L2ämŽŸƒ\… €D#@uåhœ*àrq+ð6GIŠß•Íd;;e7‚åoWl™)zb–ŪŽbÄSÌwp#O$?@ ·Hž†Êló>(Ûÿ*æXk >Z™ ‰k•1™'î†hDs!²Ñ³¢ëŒ“€?Ôôñ¡Ë°e§ÀBj%)ñhèç1ÈÊñ•F›èÓäá¢kq­c]‰'¥>ŒO¹ÀÌŽÛ—;Òí‡kçhÛvÜÿ+¸¯ÇÎQ1˜¨®™°Æ@ôvƒ]¸ÒU{vt‘1%8AYϘ ÊIy=ÅåM}CÀ·\Šì㽤ÝOŸJIÕPOì&evÚ £½¡T —€7.kKe98Vų ¿÷­QÅ,t=£¢9aïºòãŒN±î&\ÀñdÀèPöJU{¶‡ÇT>O´ f4t{I¥gdÕðoI<æ³UçX¢8­"à ë3¥9Ô™àë õrR¶B¾¡PçÚŒQ}cê#DR&ùó8¤§¨Mq±úƒLÔOjùÎsÔSÅjõ ÆjCµ¡tÔ.Ð.àb%GÉaŸþƒþs…WxI¡„\²ÈB9›N31©^ãÊ9rŠå·üôs—¸K8Áö0ÈeŽâ„ss =w&î"×iêž¡{¼Yâ0…ö÷F~ŠÌßéV6/2÷DvÉH”3Tùàè©ÊÕpxx¸{ÚÜUAlMÉ/RvãrmÊ*\ë®´kѨŸþ:K¬Æ::óFÀ׿-R¡ÿQàzív¤“aXs¼ç1H ô^Ñ‚À•}Âÿ ”6O{Š{f5Ä(铱ìîš@¶{/ÜAzÁêd¦+ÙɃtô®Kîd£Ö9¹—ïáäÅ ÕgÚ³¸ËÓÖF/ï£fˆJí¨ý%ªÚØœ Ú]Ncêí®ôã ‰%¿ôEtí8»ý¿à&änžÄ[ôÁŒ÷½yÁl/vñ…hªl—Y™ˆtñˉ¼ã\¡dˆFn¦ö¸ÚÅ™¤Ofˆ“TnçVûç²'ñX]ý³y8y¹ò­Í6>ƒ:ÉuF[ÔÄÊòˆßä¿b½'ÀùF¢x |Qbs|âè?îCªïÊИ¯m–§\…È\â7r_ªÀÍWâ=Q ?U'M´Ñèî7î&\õ”r5Š>E‘S&–B|\ä lOçòA(Ö`ópjU'ÃùÍÙ/VèWWœ’åQnÅ;ê`çfØ‹’<)ú&$ŽrK2Š¥÷µ£ª^s ƒì9àœ0‚TÝN`W%S Þ5Ù Ý(Ïp1jö ¬‘¤!ˆÞâbˆNrAY_³°ÓÕ@?a<ˆí†Õf ïÓÆ#¯¾ǽS¿‘ Bñ¬`±òœ¯Ýëý#(s7…,òs(…‰ê'þÓîrÿuräÂŒ¥e½Ò[S³\f~ƒS:9û^ö½—¥1§äLÞ³Ì-ü¦f>;saͯuzk-•ONFóf[ßõL›–L3]-%~“ ª5úÍ}+½«ïCó=‹Ÿ¢Ïñ¥g]ô~ö{Œžâ@z$ºžˆ¿G\£µï™X#2¾‚·ÆÄö‘üáßqú¼ä6ðµ°J±üÇ¢£Ðµ_å;|îÿ,–N3Ï­V}FS­É,2>3SÉÓ'ø‹Áó5ÛxR¬à2vÒû/ÌaÏ—-ÆLýìH ‹<÷è{¨åO$3ÇH Loõc­.Ž‘o÷#©>¬îâ-¯¸«l#®Lß#ÚµÑy\/¾;ø½¬/¯T†ËmÊzo[bÊþ9”2Ò¬Á|Ù<Ñ‘i¬©ØLé9}xË—õ¥r‘ãdËÕlMvQ^²3"|åL3®!ù¡0Ì©ÂU-X\¨®£¢‰·®1%¾Åw’÷ë7A´ÂxXì"ËÓܱÇñØ‹RºaßOnc–µÇ¬ƒ+Y keòzZëO(/‹¥V×P+Ï¥»Ë?ZóCÑ7zEÁlË›ÜуÆ¨ªLÜ‹ŒhƒˆØ¼ÈŽÔ ,ž]IW±;xœEÞUþíÉqúëÞ*»¯\{&q‹ù7G¿N~GŠ®X½ioô¶ŠÁ˜me€ö¹³ ´çœ8¨Íåµ ®wу@Žr1È?Äxp3ÕËÀ.Ð/g–¦€5טÖýe>7¿2ú»#­ÉÆ«ö&³qÈüÊL• KfáD~à^~)XÔb{Åá° ä váTÜ¢Á1Îü€Å÷…_#ÜË‹_£µ¸¿ì%õñAä í%þðIOgšÖ’©{ÉIù\9ÆW(2z¾xó*O‘R ¡Åj:Òk˜*jZM£Œý¡‹ä!ê†&ŠÙ4 …ômæzÏuêí±ŒIUïÓ#¸(r#WøÇ¿ß‘WÙŒÆD Ø BKcƒÑü2±ü÷Æ_EóN¾ÆkîLì@÷ò•¨jFíYˆÔzÃS;þªd;½×–Lgk`¡Ù”EH߀ø,ÿ³O{.5{ñ´OšGÍ¡¨úç‰&ØÊöåh†_vψ䫨¬#ÀSßMe}|2˜u•R0ú)3Aí"K€§ÄGÀ{ün wØÚ“@¹#”©[Ülˆ_I#°^ñÐHíHüjÔ5½ 7¼Ô3 W{Ã÷ªQ’ÔxƺÐ?œ¤xÝy3ÕÍ¡¥w›¨Í‡áþþºSu\Œ5ÒÜ"е›íÏÈR.ËÁn… ¹)©‚S&fùœ†äA1 X«lƒœÚõRÀ§èS 5=t#h·Xß"þ,VXƒÑ|‘zg@|’Üâ;«xo%Áݯ÷§ä PfkÝgx쇬Ðô¾ ê—é­!1¹ê4عN¤¿[ãgHlŠnŠ݃]UUR‰–¾7s5$ëR±f‰g!õ·F㡼iŽ"mŠj¡:‰Øx× _Ã-ÅK¬lnϾI^Ç+¹wÓ›-y[ùÀgdßœ8cÜ\o•øbÆàÄÞà ¾ oJÙÏ ”YU}HKYyŸÊà¢ðqf†ÆEïæ£@"Þ˜€ïùø ¹Ã›j¾,òÚÉ[¹@ÚnHHohŸ!¤NKTõ-ée#帢'µˆÈ‰â>ªÜÞêcTÊFê­|m¿¬?Yg<Q'YèˆL¶ð^ÎK±—) ÞÚKçp"t =òaÊxÞªú1å„|³R]ê:‰9Á2&F_ô´Q*ƒ¶9VlozÚüŠ`棞}H éeJ½Íùü¢LÂ'_5ÇðSq·Ìgäe7egwÉ%970µè–>É¿µÆ#B;sE;p¦~ÞãrOþå™Û¢³JG.y;zJ 8¹%ü~²™<Ŧ²€ºž‰ö>cÃ}ƒCHhn¬)g;ƒÎçâQ@¡5â pWˆïÀÙä|ñ•ÛÀCÖÈë—Û´Û Aè1Ï;à¿KvÇõgÛ¨ž»+³øÆBÌÝÞ—ãƒxÁû†Yâ¶ô M©a½,ފݘÀÜ”•ÉÓ\¤ÿf=‚©Üø™ãêÓvwꩾd+<Îl~ÁH½'±‡ £Ñ޵B™9;bw*{Õ­ ú¯ÊíØ©Ü)ü(^µL~f¹ŸÓ’ù±Ó˜UµÀY£7ÃôN^Œ(<è9F=ãg§ýÜnˆä/r!_–ý¨ÜÈdûvç¨Ø~LùV|èn¥ŒkÝbünJôbpŽ©ƒqÌž¼‹Oä`DR•™P~%KYVt¿¯zy„…Ô*Zšœ¤n®ù›ó`ÖOu’Åx—d -R>ªº-Љ‘o7K"KõÚrN¼Žþ›—¸QŸGKs—v/ïYk<ËÑì>¾"„ÓÚ_Jªón(Âi·YկʛÎ;±'þ'ì.ÚNÃ#ß2g„Ì‹]FRyØ7 56~{Ko¿ÏäÒÌähÖ[q™“| ‹9ö5¤‚ó8.Š˜ÀDAô¡ÔMXtÔÚRŒý ïjQdz† ù·ÓK)óKâz7'–)µ¼9N3ÏbÏÛV3u‰ø¥ê¥Ô÷ ÉPü…€ò‡ö¾»¥öǹS gÌäÖÒ¦Y~š– Îy/ Oä¾Îô¢Þ¹·Ð'~áâDAÝš8sæp'åÔüç²·Æ­¢'3§•?^Öß{² Aò’§0°ü-õinó¹Á<^­Q_[O{ß°ØdªŒZêlödko%/c[ô«ð!îÔnˆæòAù‘Ú ­ÌÆÔÒãÛ0Ê'‚§aäW0¦Fw@`b¸? ß þãQÇUÕd4ÿ[ÑûùÙïIáÓÀpó"Vù['t™é{ž{µ˜›èÌ'žÌÄ0Ö%oIÚ$Ìß“¥Dô͈:wš£0Œ½öݨ•?[9èÞ+—8V:493eº˜n'»>•ÜÁ}jKP:²ÜÙÄQý¾GÁ\!¾ˆ"@»ŒË«¡¢XÎ@ñoó„qœQz7–Ä÷éÏ`«‹—xFi /6[²PηEe±=œ6øm6¬u6•Ì2åXÑh£¦Cµ÷±ÄÚ›¨b¡1œÙ¢çg÷+åc¬3UË2Ž8›ÜfžÉæ]Þk´Cží”çÒ^þÅŒ–³:´ç·Õ;.Ù k×¤î‚øû¡§äœp—”©ö/•Cc’ݳü£#'bcõ‹ÊŽ %$볕GBûØÇ=¥d€q¹5Ï©©”„o2×rc ÓÔè˜LLa†{_4‰½©}T6 !T´åªò} šñtð¤Çs‘¡Ê~Eú‹ª29x:–Š”¶UÝå÷ñmÑ9êÏéÂß²SnŒ­r ={+oa†÷ÓØ³³²Y>þ†U¾ç»é꾆¾å­+ïÄrrËàñ׌©à«zÄá“`µˆ—ƒ˜&ÖájÄ»¢œb[¤4V‰{ö†»SgÿB{†ì[q«½B,`•¹)Q+J ’ýåÃñÒ  ³Cš–¦Y9éjº*7§GÓ£²iPUÞŽÞŽ®7ý­ô·ÔÚò&y“ëõýêûUÜáïçï§Ü©ÿ¨ÿ(âêcêcb9Å´Ÿ¶Ÿ–åòù YñÛâ·¹ÄÆº¸÷¸÷¨wG“Ѥ{u¸{¸»ü)¼"¼B¸W<,Þô‹ôSµ‚ >TW–%Ë,£wlFlšïoßõþývwç ÏÃúJ¦¯of6B|¯|š­L–ïb$‡Ø{A=¦æAô–ª¾8‰ëdD`ºçkÐ"þûPŠ¿LÀ~ÿ•¡÷äEôU~k£=Ä8 þÖ¶´†`ñÞ‹ˆ{б«ZŸB‹ Ni„UõxúJ¦VMÈHÊ”²—²]1¼ø¶œKiWÜ2K—ûó Cí£õc~宲–Jk¾ G‚ý»5åg%”yVíŽàZ㱃mdy–K<·ÑRí^vUÚ|m2­Ð;NNÃ+Fñ¹ê ¾ÊMb†–"=‹´Dj§Ë•†žaXÆ(_;wvÖ÷å]5½rúýÖãÁ‚¯Ù3ƒƒåßIßIwBhYh™lè»×w/Ÿ²…-ò>çsâÔ¢{ñàánÎr–Û".ââ1ULÏ—l+Ù&+¦§+gì­öV%£´JiUubüîxuIÁñ‚Zÿp›è×jèN…²8g çÄ+1®lHâ%þ¤|†ÍÍ´\ .øž퉬"ðþ}DÅôï@™’‘Ñ6És8ZÜ?U÷)#ØË*eÛ­*Z–|YNôÎUŒ-ZºÕSödbô„o5¾²wCƒ1ʆgŒÇ.ž]­¨[Î(x¦B¸z J:Üì“„Øýé JÖ×ÎM¨^%ÿ&äìNý̽žƒ©"òCí“U°ÕôÔ;t÷/¶ª£y†™.¿y&vƒštÞï‡ö¸žwÌŽå”™DÑUûOГC°µ‡ã/¡ËFN›(ÿ—Zÿÿõ@¼Ã¢©/͈÷ÔÕ†æv*Ù“èÌg¿k÷Ù¯ñ@þsöû+ñ+|¥Î\ª`»O³ÄÌ”¯¸]&ï÷/ð>N,%=ÔR]G^¨Hýr¥õÈåomW«R¼_+TŸ‰NS›¨9ò7ÝÐQ?Ö–°PlÒÊä êCNG¼âE«yછIs=þYp$»|µ}óyÎsÎÃ5ò}ÛQâ뼃z>Øä×Þª¨ö‘Øg*­ã‡ŒB´`k{$–»#q´»BPuM_Ūâ†êZ*ºØÅë¢DlæQCh¾F©JàO&V‚ÿFâ^lïøÄL„ï¤Ù¼£ãóØí©év¤¶¯A|>Ÿ8>yR[e¾á~¨­ÌÌ•s‡´íTûOíáФpï…¼ÅÏc†ª˜õàIKâÓ{(oÈçµoíÆNk¥‡ûšû•2Lþé΢®xǺűüºn”JwŽçE· ÍíÏœ9§É/øË^DÂnSú‰Z”E4QK”åÂòôÐ)wn´ã è÷¨ùìÑê¦ûii+íôü/ùÊ|?2[Ûÿ½t˜lÀôÄwΡŠÄœrºÏ½É” ¨ÇùØù9äz[É~ÈxÒ“B¤ÕñýŽžø”iâ06êU^©½ˆð·•ë¸íÛ¥UçX(åûŒ]¡äs¿'5áoïÉ(Û̧šMg¿gD¤ ÛWýüuãg‘¡±8Áßâ Pý cßBàóÄ˸ÐÁwwêYð‡“Ð|ÏÆ¶`{¾Òæa¥-–£ðqߤÿÿ„³œÒ²›¤¼§$x¿ŽwCCSc0<3RwãzKSß`ëß$oc‹SÕQõ vCð~j}Ú s%h÷ºG@?e·e Õ ”É,„À ñ=(Ç… Td,ˆªöà™-À¼¦œåÃ@M–O|‰:Ô=ÍÛB-â½!±Ì˜J™±Üáž2õmOR•­Ú8V{ß›`®”uÉÝb#ħ©#x³d¹·#_ÅzÉtñZøYÑK´×ẛÄ󏿣ÖHÔT{‚ÜEG(>D5ˆ¬õ¤ X®üP³G6Hhó±Ó\ˆnœ‘ˆoâ…ßZÝAÓß÷¾bYê&RÐû¦Ñ5ó\ÛWø®vÎû ¦63ç=\q/ˆ“ò`² é¾ê¨èveó"M¤=ƒ&sE]të„;Üž¡¹èæüäY´ÌŽU€ÄÜÈr°.©íÀ9œk¶Bæ<ꯉmWª±=Ú+Ve{òg#nö(˜M¬xj$oæ¿i6B»8#ÜYÆ3?r¯©©òÇ+iϔ󅷓™‡"ßä, ¾_ülb‚þ›÷‘Ä ±Ë¿<¶—wüÇ÷ñ–iìTÿœd/š¼Î|ï»fy0j›]Á˜jÍAªïº](S5¹‘¸<€"²ÅÊ»9ꤻC[аk‹™bšÞAê¦ï)b‰ŠÞƯùç“?¨%k-vŸÄÓ¾î©7byû[÷š½ôGEo[ž6vzÎsÈóVæžølñ@…ÆeGñÚC‚ÝyN©èÙÏ1ÿÿ Ýa¼e7œ#ÍÕÕšd_;P~¡˜w+Pù3¶ÜhYñqVÞ”y9rû3Ùg’Ó‹Bi? ¿bˆ«k¬áÔ¿ò<˜qˇ-?K×ÿœeö ½k•S¸þÝÚpRÉ¥ÅëðÈ\¡|M`9¥ ßà7`)+Á>@!¸s©Áï²o@Ú/¡‰ ÿ¸Z Þ1z#0^Iœïuª§·uø›xÌ¿ÆöQÓ×R*Î.ý!­4Y•q‰ìø2 =íÌ`7ÿa—QªçÕZæ' ß6ŸÊÛïA 79J‡ð&nf'ël7j>„Qš«!m•ø <¥æãkéì‚è,ñ (WÜÅܬZ zß41ì¡â ³‹1äΘ©÷õz˜‰¶j-ôD Å ¨4OúùÂÚ¨Ú¼MSM22ÜS$Ç%ïÐ2õ²³t. P‹‹h%5/Pc{<-À™Zn3¨i¾¶Ñ(0)»fÇq7»¸që\iІáëëY‰gƒ±Ü´’±Ç+w‹ÍgŒ½µ¯âS®ÙGòŠ{*fÞnO°Âã·î¡¬ÂÅ;‡y%W-jÅÎì™Å÷Ó%ëRÉzd /mÃçéSÊ~á¹ôze›ÄÖôñÑ‘ÞJÁù‰vž³þùwð}£’sÝ|X­%-s¢R‹GÍ|¾{àµ~Î9½@|íÔ.ËV@1]€qä,¥P¤~b¬ÞŸжž€äiÈ=J=Ë nÔkÚ{ŒZeSú¶ªï&‚[ ‹~•™`bIZh†œS´&c·(mЄaLüï 2ð>ÏÉ7»¾/2¶’uéßr¹]Ð>wj¾“[ 3 ÆfžN/î—>0–6‚Om‰ÐÛ߈Z¹t!¼u©3óe^äšèŒê›Â»"Uiƒ³™o»è_D¬žÊ»èæN÷qö¹ÛxŽûE®VËžGãôŸ­ ó-I¼N°¤RÔñ]üeD ½èiˆÇck ˜]ö(•#‹Aí}´?Â=ÁÓ<öšw]êRÁf‘CÄ?ãJàK3S½ì›æ›êûΛ±9Ü6>H¶¡{lLâ¯Ê×Rói¬îL“SÍɤ%‡¥º!¬÷ì]¸š˜ Á,ñ)»¼µÏ­yf;ÈÈS¯A°¹; ŠóRGA¾*Ç«Xœ¿«•JàyX)Ÿ¡O„²™r0Ñ Aóeh%­Í½¸n¨GRÛꌻÇEÀ¹!ÿÄï Ňpr•oÉ’ëõ¯°ø[«&Å» d‘¹á¬È¸´k—žÃN”ÏÙ‚žì"š¡Æ+êï!£ ý®•þÊfFt{Æ;üy8g%õ‹»æ¾!çß•q¶•}¦M-Êw’ ¸–ÃV_,â}}IÁs|¹xÆËùkË­ªòQþáÚ;*®.Ð-–ȘNõp¹Ðî/¸«J ´= P÷?d~¡1ØÕþÍ_¸¡|R²yO'ž/»P< ð¾†¢ ]l83¤ŠýQ3OrAäU¨/gÒK³ø_²1ð@j •ÉNC¨7•Ÿ¿;>…ÿ&»²$µ'ñ5ωٱChž{"o ý/–ÍÂq"áfhâ²o@4*€P6†_ i숾O=ÿØÈA~óõMÛ¤¾J‹Ôeyþ²²ÞL¤ Ü-øi¼;NªoiWdF/¢e‰GÁÐA°Ö'· Úœƒ±%`,7­njYä-T%f^ak¢,¾‡Ž¾‡Å%Òe¯d yæ²Xk&gÉÚýJÔ½.?2ËÜBm‹±ÀnWt´Èë¬Ïú<û_yX¹­Ìqë*ß*ÇÝUœ’Gål2ÈÄ&‹r¢•ó‘»]Ùâ±(Ú3rÒYk¤ÌÕV‰é‰_ÕjuG­íHWvÛ7•Ùâ›Ô.9–UofnãHÁÅk:/û¾Ìì‡?eFg#ì6Þ/Àú*ö$ÈíàöL^ç¤ù¸u,)?cnò(#”bµŠÈ´áLá ë~&Û ]ÁJ6wW*¤Äí­€•llfC\7þÆŒG‚=Pâ!%V”Ö õåjé˜Ì{qK&”ó3©pnîjžÌŸ—¡š÷•îÞ‚%òŒ[Š-úœÛ‡ô9ÉöáDÞqáÄÒŽ¤°F>˜fsÿ#z¡¹Bë ¯0/–w¸µD­¨}f?¢ÌVw¹ƒU¯þ»ÛXÞ-zÉ•ì79*–‰£ÊHyD>¦,’‹ÝÙÚgŽ3Hßï̶: Í>±žUrYãXWß]ü'Kg´è¢‹Ö2¹ßazï!÷Sr$£Æ‡©g±EÊ^õßVê’–l¢Žåd|¦2˜‰O}Q>QVª|!QG©­åšsÔzßÿ ¯/ëïlÉÊð÷rîVÖ‰®Ö/2êé–ð‹ª¾Sñ¥ì/[Aê{Ʊ|¶Ú¬ÒxVªrñœÔ€‚§ÑÝ}á+¬`”Sj?‹.J­,ˆ?’8L°¨_ø$èÞ°†îËŒ6‡Ø=¥•Aù²ôc¥‘ý •ÄOÛxCk#·±Ù)Áп1—0BÝ‘ø‹/Õ“æw—Õ”û“~ﯞzñ-\¢E"àóû©kb©X™Ü¤ŒRF™¢ÅÑâÔÓ‘Ž‘ŽÖ]ç瞟›ZjYE©·ÕÇÕÇ­Ñ!Ñ!É&d )>RÛªm¹¿t}éúDSÇr,÷ «Y-“´¡ 6ç9/öhã´qZV³ZyB¼.^W¾P«Qɮɮâqïfžã9#&/ÉKúù“üÉÓÛñD|£CNÈölN—þ‘››“øÉÙ@ºëÊî ×ñ¿^Q´sîÒT[ÂÎÕÔrҜǒ¹à6ÎèÖ}²G­˜] µE‰M7¿%¢$dMBÂñ¶••b›¼çÄÖú¯±ÔÛRo›˜˜ý “JJ³N.žûZÁ·Žðï÷+ìn}]Þ}n?T9ý×ëTþC¨×gä%äœ[çÒŽŽ.}Óø®´%ã®”>•òÖÉÐ|åQÊûø-oH¹½Ÿ9ýH©=®N¥« xƳ14§6Mü*ÓUŸé¾)Ú0ÝùJtJ–ºCi–ñ€›ë~çñ\ä9r6§¿O‘:NôüoÊß~ ˸uy-2#'5W6ð€7Ëufâw¯%±V`V9p_÷tÃQ¼¡­Äõ1Ê û7;ÃýúNC”Ô¨@OlY]=ƒô•ÖGI®ÒoõQ0wz>…à`=ˆžZ§ Ï&ã*$‡{íŠñF¬£ïpjú$¸Õ|ݡ˜ìšP’—\ቱÈ`‚ã«äY€+·â¦>a6®ý—õ48¹,“Ÿ%Ÿw·‹s‰»íçä6-ËrÄu¡$«RÙ36±é¼)Àq J¼¨þWãÓ®/<Ôce nKÄA={”Ëñž ^4‚þ˜õW³2½8lÞ0kÐ8q¨xºýqBÏ™o_ïq%?õŒéX>3ƒjT±~–­ekË´,˲‡Èž²§­¤¶¥¶9^ã5§ò¡Ô¹ÈEfq tÄÖ›‹ÍÅJ·À-P.nnéïYu­ºZû>û>í;­‰ÖÄØëÌv–yê–vyú'ïNnñ^ò¿•~\•î2=‹_2LOá$Wi e±ž âÿÜø`9;ñ³M¼!ÿ@±k8 ÓèƒåL6Þæ»Ô9O_™GËб”W²¼âC}R¨¥•õ„ø­ðhÅÔ¾åT˜Ç÷·ß©(h|ãÊçPo:•7Âå5æÁÅ#æAdRÆW ©K F8¼ªÕ‰/ÏÁäC¸Ú…ø:,ÏÜÔʼÉáh>;Ù<¯ÛG!‘H`iï;O¢x_Š—¡ªS’+ѵ]â'ðWM&±”ÝlB3†ÇŸ@¸#@ûHvDS:ñÆÿ3çÿ÷€™ìfÙ$²žz\({‹ìäR· Ÿê{­µÌ‹ê¼Î1}†³”\û¹”º±óÎ- ŸüƒNÈ;Hc¡<ƒsÄž Ÿò”´#†}«žÛŒ„÷†ÑŠ„·±îСðeñ7}ŸëÃ8éÓŠ¹”«}D{÷¸·ƒh$[yVjí©ž?4=RªW÷ܯT'Œ[¥Ø•ö5Ï©m•÷pÅ´P'¼ÁïÀ’(Ö°À*Hm¶£à QåÅ\g*gP”ÓÆÖØÃ=oÒ]ë™Ý‹Å‘hÚ|S³°¥xô­8T<ËcÑòÁsrqt~ *šFø£Çtßãìˆ÷òÍ„ø _„7’»ý·Ù“œ®îý+½z¢µæõþí<ïûJSÝwc‚vîØØ|²0ãÿršå>‡ßÄÐä}¸´KõäŒ{È<Ã5¡Ù¯qSô±Ÿ#h_³WJ/a±ŽëTD¡>exD P¯¢±X}€lù„~•úüj4¡3<í0Ã_È+h¾6XÒ4Gç•àSnûº9ÍŒeÞæEk­j¼Uæ!” Î.ÙEE9·ena—ÜBÉ÷—ÿ“ømo¥Qt¿õSåêbÿÕh•‡éz5½üd3yãå,½¬¨¸…ï\aO»1íÊ>6’ï-+/y%ãïH:glrCî¡òe £sEfæìp?Žz›„/S™ª‘™üêÛÞ‡íy*V“`ð­È3à»'¾B£ vŠ …@–57Ô2BñOНa£o|²>uüMR_#}é‘®ø}ݬ¯îmoinEýwç{;CyK Ouc…¬f¦aiííèò“¼gèüÅ ÿû @þ‰BïÒ9<:tÝf©úß;[TGYCDX1¿æ1«Ôü—~ÚH»-`Ú1 Åov-6Ú+Üž¬u^µFñ äe¾ôÕSFQ’Ô Ô/ÜìÌ@õ½®œÁ ¶VÖ“Š?Î]8Îsjo²b‹E ³¼S´“TM–é½IÅ7©×ÈSð U>÷½ìùCY[xÈÈÑ–ŸªÓŒsÚ¾×ñê<® ô,ƥǃÂz¿ΧÁK ßí[êËÖ[ Z¸m@ùMÖ§Œ—qCuðÄ^óÍc}|±õ 7#¿Ë5üYØE|(+ V#g$DD_'¥ƒY ‘ú» µÎižÑ×€òI ;º°¤1NržU“§cÄa|%~w2ÏJµ,Ä,½•9åQÅs¢‰R'5Tm®†SŽªñŽ•ì€IDATkWÄ}œ7þñÌ¢·\—ZÁ‹|ig#YÅÖ9µÝàLa?ï›#íà4ÒoAòç …É^\áŸä'žMd&<âAÞˆej%ü«¡Ö“ë"+Å4Q±´œÛ’¢oÃņ’Ýb;=ƒ}Ñ"r‚æÈd½ib÷|ðrø¶ï¶2"ü*Öˆ’ ¯°9X.±3ÙÇýÐú7ÕY΋¶Š?*$êñ•—œ‰7Í=ˆÈyS¿û ÔL÷®p1š€¼ìÆ@ëïiÁyã>}/ªçÙxÂéïyßHE‡ðkÚÏ‘îü¨ÞéADÝ> úÐpgRžSá©hFYìqtï²è?à{-ö&¾Mþ ¡Wâ_Bhm|=®¯]ìŠdk¾ô§ÂyÒ[[û‘ôÀ4d. bÄ“@îÇ ® â1«¥6ƒ³5þ0¸¯%[‹ãûQܶÉ×1Äç©§AùËÚú‘Ô0PwXï¾À~´f[Ð>w£ í“Z߃’iùó0Xi¤ìq ¦ê Àó ·°%ò$Oß‚˜¤¯õÄó`¶ôtåAÆCrKút¤ûš='™.žFsU2!>B¿¢Ûœùœ9âUN%sõR–F4~fgéCÊQ»~2ÂÅDoQ™Š±QrJd ¡°@árµ/¸OgD±*7©õ6zæÙŒ×Á·[¿êýfÝé[ƒ©¿d=ƒô¾Q¾9'”DâaÖªw9~žÐ/%ejBW¨¬T‰ÝÄ6²+´ÓTs+DÊ#9b}‰T¾VV"åEv£ÊznCJ• iûQežö.a§Š;ÓÖ°hi¢UÀA³šé‡øÄùÅјhø=ä8+Wñ™÷ˆUøíaÚ"Dªª5ÝÌ3ŸLŸg!”›Xí*ª3´îBVTN'‹ä·àµ;Ý)fÝ´ nðÛÕo”$v¨Ì¬¢´ô]Žæxæ§µH-ôIJ§ŽgÜÊlYö/‚“X`—ø-åqë㨑n-UGi›í–Ú[Æ*kƒÔvF‰ïµ°3…le¢»œ eƒÈí áRQ·’:‡%NŽ6ÕýÙ¹¡²—š÷ÇœÁÖ;úûÖ›VŽÖ+uÐ± î;̈¬•’ ©A꟤‹•ÊL ü«ŽàíŒ"­ ÷z?–šWÔβ4ñ0•J®Å·2LÛdž¶üŸY”ÿÙÀ{Š5‰Ú½ª‰S›ÿNèg2ÊU‘NaÅÌ…±*¥ß/ÿÝ®~|õ˜]Êù ;É#põ—i^X ÆQÛzC4ñl“3E5Ï«ŒG ½ÄÝ1Ö^¼‰ÞÖ^<ê(¶ƒº”FÀP.'‘àtÇ Îܧ½À·GO‚ú›€9%σö´ò#(Õ“ÓAôq‚ 2yœ”ÖPëŽOBÄ`”·¶¸õ÷õ3©–üío‘ÜÉýþ'Ìæ|IŸä_œ“µRƒ@H’LM·^Àp‰Ë®¯¤º;(u"W1 —}$n³;60íÉT¿¬áÔÑ7¦‚ŒnåNÓP ómãI·Š³ŸRuj–E¦}!¾ Ÿlàû‚T¢yj íܨєXbh´o;przóÅøÈ`œÏd0Xœ5²4^a[æê;kjMNufMñå`ÿì/ Çs}·{s­|›ü7¨’7¸ E"wgÑ<Õ¼då²Þ(õÈãÃØòE–²%T»_&¸5öš>Î_'Ù4pÚ{Ù\!“†mŸ!GßiÏr·ªçe[w§:A¾*Q™‘ò¨èÏEæ1éŠ[ÊrR§ˆÜ¹šWüeý¤÷Ió€wØšlàïËw‰Y¡\ùh¤uÚ º‡÷e&äáÒšgXV¢f7g]шœ–¢ÞõÛ•·Ú Pù­ÿ=ùÁŽ<ëÞEªãŠ{}Ï'«_˜ø9º=þg@áÉ™bÛ÷äg\»4˜4f_\HX.½¸‹=vÝKƒPTOx®x;Cå-ñkÕL¹’'+)"‘ýÁ·‡Ap§bú]qš:‰°4y-9Ê6Œ?õO»´$›ã¶hÃmßX÷O'ÕT}OVu¾€k>3hîþZ¡b¥|ä?bˆ5¢ˆ)oB~Oû (gõ0VyA|‰x”VÎN°ëé—P”5òS¼‰]b2–rKÎe·©s‹C®ËR>f“ö=KX£—ø3EC³ŸG@¢µçÜè4Ÿ@‰lÈj„n“5‰‚’72žb^Ñ¡ÜãL,“Û» ·Â-76VšËåEÞÆs½NÚ®HßèIeðµA¬àÀÅ94eþl£?ßoÌx¼;•<µåÈ}æhé_ÄëM3Z'§e5«p%y k{Ö;—ëÔ ü]—NÚ«+e‰ÍI7cª÷רø+íÕðxoïÐ[áNj~zqÙƒ´ÏèT6 -mQÄ¥AÚžh=Ü{ƒ ñÏþT|ÝSmxÉ0ì  ýîþÌ Q*+?*?ƒÌÔ¾§…ÑR¿xUH¾é¯ÏSñmÁ“Á¦í›6n–vÉKÓø«°{½3Ü7µ)PT÷ôÿž–¹ëÙ¢hË»Çä'k x9~Æ8NÍ;qw¢ËÜ;âM½5'ž[‹¢u…þò‚ö:áçc¾#ÍšÊ%4Çd8ŸŠé.>Ò¦¥¾ ÔÈòßx*íA%žórbŒ<æßY.&ûˆuüÝL?*mñší3ïõJãSPœf%yH¹»x3†RÖSù2ºÁÙª¾©ÕM½Æ„ä˜DóÕñqè_Å:áç•m@5¼Ñ÷PݬpOHeF®€²6vÄíX%PžŠ-uz2Öë‰Û8Î+±Ç<ó±Fn{˜ïn‰µ§NªÄ<¢îcƒ²ŒÖxñƒVu§œû¬ù„ú„ZÃÞâ¼YlOöá»ìÖ+íXú±<àìq6:2"kºoЙOåûò1ù—”ÛÊ-ÅÐêjÕ½‘Š‘œP÷ªÏª{ ƒ×uãv¯|¿Ú™yò€>Ñ}_Nô”¹¤©_EQw«]KŠ‹~`¾çpÆiž,ºžÚMÀ홂óÎ`¿É\+dºsiM”^õ }š½ØL *ð1'!ðƒüRí+îSžÄ¥†·T3 5JÈpVÚÔ/]œÛ€Òâå®r©ðí¼…Ì¸S³¢%C·V^/\[Wù¸ñ]î$ç÷|7ӟ=)ü·g±ƒ÷nü,ÞãïÏÈ?xúj-u®=üx{…à{K^ÞôágnzEç¸ç7¿c•y®gŒ…à™Z<‡‚‹` $Köj ø–ò<è·Õ±`oqCj"pΜÉHyÌ…| ±géÁƬ_Ri|1ö‡ªB»ÿ=þöJÅã%£È×tŽ‚½\|²¿¨€ã^$…ßÓ›õ¬NTä TýëÓmåJJh×DW1ܨ"„¶Å˯‘Œ9~¿ÝWoU—òp²w†êiô«Xó'?êùÀ³×ܦϣØl&Þ¢/SäUÎhÕ­NLõ\2_§§v2ôº¾81üÏFŽC¢_x5ýÍE±9Ú"ßÛÊe)~±Y8ànuNRCžIÎfx6ú&mË~Aõ ‹Þêi-ûÃb@9Y]O\ÅÊ®pK´ ¯fŸ²(õ‹»TiÈÌäyw¯»%R ^Tw'âÚZ‹øE&OÒŸþ‰)ÌbVê-½™ÞÌ|LÉT2Ít‘)ËTþTþL=¯¶QÛ8#2Š2ŠÜ6V3«™yDÆdL¶Ì­™[Sô·³sOØçìsî·dA£{t}Lü§øO©“Ê0e˜v^¬k´@, ¤JÓ¦¥MóS§þ¶{¹/¹/ÇܪnUÏržœç¾ŸŸ/Ÿ7]Ó•+ì­öJ¥–ôÊÖêgˆsÈÙ&PW»+ÝOý“•laië¸!vøÿ!ÍúÉ™ˆË1 ‹Æ<îMoc~¢¶¯ÿˆŠ>Âî¢ÌX@œ b¢¨^þ¥¾ÓªG‹ËbÞ¹^©·œs}F剼t£Såϸsýh•nbÊõüª»Å†Ë?WÛÊÁ«ygÈ:76g¾]Ö¶ä¦þCá\å+¾—¥eñ:Ïf½"'ù­¬ÅO¡dozs¿ä°§Ú­ÁÌòL02åZ=%:O(idMJê+ÛGcõk«ª·íþŠêvލq×ÃN}«3„2ЩHš6ÚíÏ}âTÈâUTÈù/Ê?ùª:©h&%Ù¿…MtÚiøHI3÷p7cÜóD”CJš(QÄìè;ÔpŸ.ÚB3ç¬5š”sG4¡HžuÆÃ¥â™¤™_éµ±§ÔÇÁ_×h‡bù­`-ÔæA²P¿Œ/¼#ÁøÙ»ôãj˜è |ï×@4Höó°¿ó_sae¥eâÆ—rвÝÙ†­yíu(zÒ*¤¥ç·Ø,>÷~# ”nqöR_y-*xú‰zÖu&åDeNÄo8›ÈQç9!4çsD¦Fb©÷D£Ócÿ œoJðFþÑ4Ö¼K­1H땲ÑT·j–5ge`—–ï.2k˜ R+½½< R§œœ§“SŒ}–OÆdÒ¬À·,µwzvxvص“}“}­ýÙ«²WqS )!é“å@·÷q›8Ç9у®t{œßœß[¸¯pŸ½Ý8oœ܇Ýþr»Ú^õ‰r£¼è<*öˆZnÛÈÐÈQŽË§¸Æ¡dYY;ÖñX Bˆ7D¯±7ý<¶ÛAÙ ~‰è¬ ìFP?榈f/à#ŒlA™“÷2«É(ÿ«˜"zä5G÷=™¶$:©|c±ùöJuä¼›'*búõñUJizum›ÈKj…8zQ«2œw&å†xyêC¥–ñ8Tܽ þþ±ÏANO¾ ÞÒøv¿›üoàP¼3xÇ¥¦ƒï`ªx÷Å£ài™,‡îÙälßÖÔJ0¾6§‚qÚ~KûÂ|ÅøÚ]Ð:šÇøX¿j ¥‡’ã¤Ø¥œ^¥Ùÿ/çÿw€<þâ7ç¥è’ÉcE¡Ur eÙ×f3ÞõŒqÃ`Õt6C´²õ8xLù=¨»ÅH0†‹-`/fØ5å0p«‹!µUAKÎa!½¿ç[BÅã•q  מ¤\¸¹þ:¨pOé6uá éÓ'Ú`xwúgðl©æª”i=™¾AÚJ\”Ï%"»ø¿'h_H~ æ¨ä8Pk$‚²?ud˜OÀ¡¬k–öÉø`ãkü% Ÿq°à‚;]ö,îcd‰%Ëow*–¹uÌf…¿T꬯¾Ñ¯°³>&ç­;a‘™w2ÿþÊûô6òVž‘oÒ;÷xÑ£ÔÉ^^ewÖ}¥·¸”q¤ìYñsÆÞ’Zãô}‘Ç‚‡Ó&%**ù–¦ö™w<ÝœßÍ}j½”Ú¥¬’)Ó8žšI˜'­oH“X'MöÃî¯ ‘ë¾r€ò€Ò@« ½¬7lÀðLe—ÒÞ¨ïöT>7ö:}¦qÒZîÝn JýàK*q#ý»K#Ùµd²øƒœ–®¿°M^¾è–¿¾¼#jÜÞPá~¸]Va]¯M¯´ÊéråroǾÊ’U16-òFpu±žÜÍC…GüóàNÅÀû|iOqNóY®¦0,Ð'2Ï·"ŸÊ³úz%?9Z¡m±ß¡VŽÔa®UžÎ=NH RÚá²·ñxZ•}šüuÊê‚ç|Äï®øSìÛ€8=ŒØ_ÃÁ‰(·}ŸXñI v*×­düí®6(y¼“̵ÂÃæQÚéU}^nDÎyjãÅNý8=Äôrzf|Vß <ÚádCPÊÛ×€dÈyÚƒ`3êa'«{ÖaÅ-·¾H¾ð³®¬·ªËe[ýCÅþØ=¡ü’è¦/J^tŸçáâ#©\Ј(• »h !µ+ófv‡êa¤5®ð6ª‚õjÉ«èúˆœŸ‘FNÂî±$t³7'7Ð[ëäÿ”°»Ý)¦º˜¯Ö¤ÐZûœ]æ3‘±ÜJÝãt#l¨†%/¨!ëßøqÊÌ™ñ áïÇ—jƒfVZQf]p¶Q.µ„ T°?Öÿ!Ã|Q<Ï“Î{Þ§É´†ªí¹ëÄý£ƒÖÒº(ƒžö­Êò­cµzÔ—ÆfºýôÖl·‹0’Sƒ´1rŸ8™^5jÇZz÷‡Ö÷ynîò7ǵ&²57­ÇcM݉±Þ¬wŸL%7ö$RT,‰!ôFÅ{Àû¥µXl‡D­²úÛ2¶°öšèäV±? LùA)²?átèéTÃD¥ÄôIïÏá3Z†+b[ÃÃÈ¡áÐ ?ÊÑï@o^šÝŒºÑº —hŒëMÅl”@2¹‡~#:“ˆÿ¡Œ{hîÛ.׳™™ðŸL]1œc©ï º<ù2>.ù'¶Ö66=Ù6Ö äªÄrÐJ’÷ƒvÀiN8þ=Øì—@;b­yÚzÜל9à>+†‚Z!Y ì/â=Áï* GË|GA  @¹mV{jªR?…Öƒu!¦{‚}ÅîÑkÁ40¯9­‰gSh1/íÙ-0þb^´Ð»;~'8‚ÚᣡڼRN¯Ëã‘{¼'Íæ)<ÅedãÍÏä&FÝ^N·¸T_Ž{%m%šoxùÚˆêkê÷@÷l2×ó´KoÊY__ÿqÆ_ˆ?™ªý­fâõ¼f¼BEíhBPmhõ§•òäak]œbT¥“_G¨·üK¸Å•øC¬ëØIºr$mi´“×Ðx’œîç§Ž=…˜øFýŒtjr¯ÝF{iWMmAÈOüùÌji"GÞï[G±ùˆcpØî'žåLr¬ý i²Kp {S÷Ø1Óœ,¾Æ±ÿæCæ)GFÏÄOàó­U[“Rþ¬¾—œíU‹x#Þ1Y—DÙÈðVNݹZö0+…m¾Ì5–ü€³ú~§{ïu~ÓJµýÉóZWïñä>éÿUÜKÄø* x׳øÿÝpîù…q“eüj^þ] ³ ˜gÅó &$‡³™õ±÷ÄpÔØ/â_ö'‹¥Ålk¥Ü#?ö?Â(žÎmæÌïVº£_ aà;¸é/>ÂòT‹_håÖ”«hX¾¥­ÒÓ¾–ÏØØ€öÿGíü_ÂçqßHgÞ,úí¤žwmå•^éM/rÎ÷å µ/nyàJ퓳 ÓE[Á^ d˜w}ùØFŒ_p½KøG«ÉýøE_v‘#šQyȦ+È¿Ü=(àžÃµ.ÝÀ?F9z_g¤Ö–= ž~H°¶Š9`ouÝݱÀyžUèî8u2Ž;Ú|èžNí£äå¶'°šÉûc,ã£ì\9ŽŽpaEjŽ0¸+ý¶¬„(,Cx<ÏÊáZ/µ9„>LU€èÅõ¦ª€¯TÞVÄWªO‘RÞf/¶¼#f€<㙀Oöסȿ´Ài¦·Gš;ýQ´Ý4ªjC)Á§=):zž1žKý™~ȳ«¤zòI0š$†qÐ_”˜Ã·æ³É³|nž?Žj}Og¤rÌ×!uÊ æ3©Áz15 éî‘¿FGÓ!ñ¿xŠçÕ»Ýv„vöL¾M¾`µfƒ÷–óŠQ©§‘tJŽ«bªØl ʼna–#›@ÑÀØïàíM|ïóÿ¿ Èr ˆÌ$»Vb pVéêOZøúøž‚ÄCîï÷¥o{÷àð»ü•{“eTÕ*wƒiîX¾‡©ÍÏ¡ÇxXÌK‹ÓG©øA.ôÝÒ/%þÌ|ƒ/Kò3gólñÚìÛ¤ÿ³—TáŸ92§ðV^0µÂï´»Ö¢âÄÕ*fpñ†¿Òn{òmOÖ¯ñgJ«k ÿ§©z»wÖŒ+ð$·ËrÒ¦S&fä®%¿R¸Ò nVßx\ÈÄÞØ]$Ê–—>ĦÒóe£yüÆ£öÓÒ8Ýðö<Ɖñ‰Ï´ªêÍ2ðýÜ!jZP ½ã-/ójÞɦ$óo œô?1ÝšÁ§X”Úì/6Ú™ý]¼ÍÊÆFÏWÖqc¨'nåêºgœÝN©¤}*?f"«å 1AŒ3e[ù½øXV!Í|ì¾­¿èp&jGÜyö=žiö ÔE£Cj—¹ÀÈHî6 #?:#9UøÂóËpç}hÔèvQyþ«üaYƒÎl9]CùB”?šï:zÆ[ž1eR_€yMÖbê¿PrB¼ ×ãöV¨ð¼ •.ɾ¤*÷5ù;ú).ë’ èÁóiqN»a’á¬SÙ‡K¢¾ÞŠOìKd)Mí¡²¢ñ”ù”øÜ÷mü/Š!úZŸ{Ö„?UŠd†u7÷G¾PÞÒ_¼ïV-¿ÇÛ)ß|$´7¾+-Û˜îö0U#õ=û UèÉ¢P,`¼ø‰ôp§rEýÜÍDjš}Îó›Qÿ2=×·ŸeÉ^¼¦Œ?ÍK,òfÑUv4ÆPAyßxÜê8Hvt½<›jâ@¼hËbi@»HÅJZøc*¨íyn-ysÛ"gËæëž–žò©7Éäþäy7ÍMKL6‹mÜænóÄ@w˜;,Q¬x¯5E¸ÂµâZK­¥µÞ ZÁÔm­‰ÖÄ]“*LšÓÜÝ­^Çë¨ÓÜïÜïä|1FŒa­l.›sGݯîW b?Æ~tïJíNí–ÛÒÿMÿ7°1Ü2ÜR þüÙ)‰¥b)íSû”}Êi ÓމcöûöûÊ“ng·³öà‘]€÷2†ïó=׸¤NPö𥷠{8ä‹3•o}ç°Å»™E.g}‡j9‰5¹¤JaÅ?ÄiwzÅ~L¦G¥·xOoXî¼½"+âë\¼¯òït¿þRåÑr÷µxuÄß—?ªyòRVÍ^T¹øvõãl¸¼ªÂÆä«7oe(¥¾ð<µ8?n¯¡ üEne Ìÿ.‡Òï„QjMš8ïù0Aó]?ÒÏÓQ—‡ÝæöWêfw˜yEÁ.fÁàØ”ËæäRç8ÅߥVÑ(Y༄åÿÃÙI'ã/óA”èÞÓ6]ìGä~ž|ëVAµ§@Žø/Ý/ŽÊ&½YqˆG37ß©Ã^ƹ‰ʽ²ÒØ»‰&"[~‚ÃHyŽuòªÙ—Îä¸O ät·aç+Ÿlws¸7Š“mþÄ*³…w6ƒîP:›£q­„7Š’zÔmâ)ÿû BÆY ÝX N½  Sa RÝÁü+Uò' ò¸û#ß|Ä|Š#î¸Ä?¢‡Rĵr¬rô=þ6ö 1?¼8|É­Ê%–8„!*8+ÜßÜ]ö÷ÞǼOÐ3òräeë/g¾3ß ÒˆF2‹ L£©M1‚e,÷èUõûćvº}¯úwÑßE_ð"¿²C{ ôm€ôœc²·)³Dkïe‚Æê9Ú'0†â´¹Â¸´éÀŽŒOI‘›Ù‰ ™^¾§ û#ÙFçØ,Â_n2ɆΊ¶«x˜gIJ¼6ò gBf8ñtÎ@ãD‘·Ê\º^ßZ-›#W×@ ÿ÷ÞÚ÷aŸ°æ¸T¹Ú“núõÒÜ Ñ)6P›'¶äT*][-î’Ö;ú1h‹â•ÁÓ)6B‡¢ƒgUò2ÒãW pO¬xû¥^€ÀµT&øGDO‚qÕI_÷h0¦»›Á{Їíi(B×Û˜h<—øŒjWžà¬Þ©ô2ÕýνSü·€]œ%™¸¿Œ7Þ¯¤<èCíÏÊfÇÄŒÿkÆ£wŽo’ð€sÄÝf7÷2ÄÞ°3A›¯&@_¢:UìÓàÜ”õ!c&D&6ý‘zÜïµV@3£X›õ¹à+õ~GZÉx»>iÆÝþ8Z¸F*ÜT×¹”X¡öâ¼ä»mdù· ¯ñ´ÓФö«û>¥–èÌTw‚½Àÿ¸ûSå!!Ü'±c Õ£øS/ùÚóµÝ5°‘»e~$DòþÐa9,ñ¨x*üƒ–ã“?ÚÖ*d¤ææ?œ7&X¿èRIÆÅáÛé]2š”=¨}•õdÁ;üVîza(çÜ)CæN.0¨Qn^Ñ.^ÌYWú$Ÿd\-­ÈŽô‘€XŸÞ%<ËÓ&45æó\,IÆBiÞí©¿èî¹×²ÜZsÓÙ¦ýè,qƒêu÷n¹GÀ•G0P8A?’@¿ÿ2 B¶â*g#õ“ãùHb÷ST˜ìÇe}vê…ruêO,¥—õ)Í”Gì­`L¶jBÑ.ó(ëÜ0vð‘‰,Ycf GûÛ-@{RV÷ñðµr ´‘ê\ðkÚ:HUVæ’ºHuÅ0&Âf{ñÐÝ­ˆÇþÙ=Hº½_ç¬ÙCA61½ÚÑïôB%x‹;¢c¼ y²›ÈûOK°kØ'!õ¹Ò’óŒõll\B=è7ýN%&eŽ¡Fì×\¯8YúKng~)þ)ø]¸Vô].^k*ûÒ¹0˜Ì/É}ß_$s2dWªäbø—ûÞ ¥¶²Â£™Ñ*§/e™¶YFYÈ•Ä\¥D}‘|íTði¬â™ÊUe4é ‘›(OŒÞ4¦WöK”¹ÛÜê”ÙMéFU‘iÌgŒÜîÐÞªCˆ!ò˜þ ¶}ǽJº,ð4DILžw·vÜÖº„äÙx ØYú40˹ÑÖyÓ¼âÚNãMDé¼E,m¨gS•éÉ ßÊÚÉ5ôJ¢Û2¥º›¥¡X¨2µ‚“ËÝ@z7s¡íu§¨–|”x¢Èì‚àK&càiîÇ wBQm¾0¿OæóY¼Côeu¬·ZÙ­—ú”󩻘­þ¬C Ö2¬—Á;7¹Rõâ:ØÇ#+ÀÙ~dûè~P÷–µIbÄË£ĦcYÑìòî _¤žwtÞ {«ª±N›ÊTZ´B2@á¶ý“§=g¬zÎvZ˜!*[)_'弯>G}VŒƒÔ(V€²89ÜÝî:ð]´¿î˜ƒ=UJðÜovg^êGH½!n€2×3 ÔïLSê‚|Y^„dÛø‡`ÿbt·,tì#JKHNö%ÀÌ5: zc&/û¿Å[éïÉ’ØÞÐ rH´Gè†x*ÊÜM½âYWØ\R?cÞ²mÁβØ'žOÂë“ì¿^$’u« Sy7²'í>svÎc8Ƈ9»ÐËÝU¡ˆXh—wIã:1ž2®ª9|êyS\¤šáxŸ¥±žWùUÇÌA'<¸£TOzxC›å™$R3¼ãÜ%ê½bë˜èìsmuiæcnG9.¶HL_¥Õs[‰çóþr`„§*—Äk⡽hÊq…uòñ£i¿©ô=’5øI<z^T—1ÿaµ‰ó/{yFtòmPâ–k½È%w˜1™Î–k_ ³\* 05Õüаõ³ž‡°ŸÔ®óGj¢ø—djSšf ´rÉ`àUÒc "ÿ"œ×(!ê­kŠákﬤ‰[#ãõ­ÎòzFôÄÝÄ’O‰Ë\/[#°)^œ¨Ænë1gLî(›ƒR‹¨m:#™ï|Ç-³¢9–{‰Ø‡™›U)LÒ<Ÿ¨GR-P¾æœoB¨ '[îvÎx.ú5ø@UéìÙèiN+î¶d˜¡ß#Zx¾4›àG£Ï3íÎOÉÚ„Ü}ta/êÓÂXêèúr}‘VÁwY-‹Ïõç‡ô~\•õyºÿ½ôÿ?!ž/kíäjC'× ¿o‹[UBUEúI^/“ZTä') U!Sâ˜rÅjQ¶Q,Ð5³5<%|¾Lí,o=¥;†5/9 U™äF »A¨ÄþLÞ²G€±@yÔQR‚ä0xGrBIÊ6S¤Câ_÷6h9öÝ >G¨ã(Uð4¨›ESÐöÑ MýÌÑ‘âT¢ˆÆâÑŸ1öDχÞ×c‹Ec¥ÔÓPkЧ [õ°Í÷Šv°ÿP²3ïÙ/ª§9í;¨ßÍû£¥œg<î„ÄŽäRÏ&’útw*Ôlw;­íå£l'?”@SçŠ]L—?+Oc[´YlM½Âød¦§"Ænx>¢Kt¿ïCD¢Ä×GYãéÇâÐã/yÞ7ؘ$³ÔÔ)\ÍZ¢„åhÏ)ÙDv÷Mw–+‡½ÏÊXðJ¨«ÒÿôtVΩŸw°G¶NrÉ'Šleˆ»Š|ê¸óɯ(sV‰6nÒùŠööN¾{Ó§õX¬%ÒÝl(ZµtÊ™¼½å·‰§¼X?¥t_O«Y²¯¯gÊNŽ22mOVø~k–¾þΆøv^¸ó©¼Bÿ³üŠÑsuâsh£ÿúíc(Aóð·u3>qö]8—¼â<™¼ Úા©nºû¶ÕúQ´W‡Ú«2Æß“ñài_e^`o„LÌH-6Ç^/V¶áÞ±éêöDQt }n®Oüý·b?NÍZK¨õ?æ¨Ño¨V:E"zÆ>&/4¼|¼ìs¥múÐä½—°ÊžP†Ò,ò®ü 5¶ÚnɃö3`†,?8­pꤞ~M}‰+›jK ±ÞIã;>&IMe”اwUf:ƒ}sµE‰ªÎStf¡S‰: ÕQ˜‡£¥%wk—hÃ"u nY®s…J S‰ÀNí}H¼i„öU½@ûŸúÂÿücø&pV„Ôàt×¾„(ê8OWÏpà#o¾Àïþ¶4€àWøäÚ‡Ú4 îáþ |íŒÑ>òz#ÓV_Ùðœl꽕ӈɅ‰Ü¿y:ÿÇÜ?·Â}È›WzƒÃ—FVéÊ×W?¬¬¹™¥OçfÛÛ}Ò[o‹ý?¥þ$·ù™.æÉ SK¦Û[ÉÏXßXGù5YdÀœí"G8ËnÞÙ ~’׈µÚyéž­æFWýŠÑ<^ýk ½jÝM9}s­ïܹã+w-K÷üí/–Ž¥À|×xƒ×t¥ç”Rþà-ÏÝî¦O8Ïàñžw¦RäÍ·Æóµ_¦þPŠýÑØÊÀ‰@ËT¿ä´9ºI/¾3Hˆ>Ê «™¢v¬›µMK ubb-8oÄn‚ç@b9¸ù¥oƒÛ)RC>-OÒÿ¶Ó—m²uìkj着ó¹m¿iý"‹åµäDù–l¾/ëÈÓænïçÞ‰æ ëuëuûic•‘²ßŽN‹N³²´mÚ69Ðu]W~$‡È!òF2R,W¿U¿Ï%$03üSø'ù–SäyšçÌÓêøDóD[­¶ÑÍhªÜå=íýT{$/=£¬%Ê w­h"j¸»½Ï1+·Ú1€!¾íd«~ï¿Hµ|p B>øôz/ßeTâó³^c9ûÊý̛|ãÞ[¾1Èæå÷‚wyf'}NY0¨r3¹ìzNåÄ7×OUËá‹Ëëk|̤Ëíj¬ƒËMª/ƒ‹?”϶§ß4¿]Ñd¥Î¥ºîmþ=·J|*^:ª§ ÿµcê< ïò½J²,¨†§@±ÛÓPi–>QÞEÙFlñÏäGª‡tÏþ9‚‰¢…qœ^êò«0âùᦅi=!õj4JëpëÄ%ð‡¼ý!2=2Íb!ðµg Õ¼h Ú¼¢¼á®7ˆÆYkƒû3¤rÕIq€•xhÂËÿ{üÎ žˆ]ý]Gý€è òc1ÌiÑ|¸ñ¹®à(­ #v¨‡1¢;Ý}hv÷0•‹å^ËߥvSž5‘(Ýe³øp–(5éèe¾”61m¢ú«9Ìf× ˆ ˆža0ƒ•´¥-oðï1•Ml’gƒvÐ Pf(3ÔmEŠ.¤£µ|›JΗœw^¦1שHEã=s·¹Ûx–|Š|¹¢ ‡^&BÓ´wå9ƥzÁû¹éfl§eö+¬çhöCüŒ?çI`PnMΛÇÂågs+wáyÙ¹Jcñ3*-à+5-7ÝLfªÁ=%_Tš¢´ºÞ¼V~ÿW«÷“Ωu¾‡Ï·®õ_^(WutôKçè¾ÂmÁ …ªµœPégdóbDzù§úPæ|êåüé=!¶¦I]Eøš%£¦úÇ}ƒÄ<Žùº‹7å8ã]×L•C­Ð_û=Ùš7â˜ɵ2ìqìÈØ*F lG 𪵜/¬Ä*ò0„´%¸Çí¸õ³¤Ü+gà©ÿªü“Ë„Z©ð'w„ïSã°ü„cEʫܔG†ø£ÝXÇ Ê(Pn‰MØÊÊT ã“D;f“à ¾t¤:Bvˆ/œE弓œIL7…º™ c¥ù>M’Rÿ W™ãÍDQ6Ê ³:ƒ¬eõûyÙ̹¾í [ÙØsåp5m"8µ—ÁšZ öåÜBló·òJΔ«’Ϩë¿_¹&RùÍ.ŽgYM#륱åÊxâíôÅâ³äæ[ûoW,)YTþÌMæ‡>²¦þ¶WxÏИ‡´BTviåù€7´v_Þ¼Réy–ÞȨô§\x«cvn¢®®_¹ÝŒ~ª6·¤Úk{?—\€X¬h ¨«omî-°¡Â¿ù×!§SáÝ÷Aá{sOé Èñ”΀œ+¥+°³rKo£e„Ãy3£SîÏØ‘øÜIVjboŠ£,Œ¢=Åf3]>ëOµ{üI÷™x:1>õ"w¡Ì‡‹Ã{Îc¢2ä¿lö»ü޼÷rYu"¿©Lšhžx ÉÊD-,†&×b( ÌàÖ3×€ÚÝ|¤evmµX©¡‰‡mö½@†Ò(•OˆE€Oä m ˆJÆû +>à'ý* }×ð~à;à÷‘$V /±@J®fšz$þ­¿!•ʾÈÚEziǬ(ÅŸfÕ‡âh¹0^Èù»à¯¼Õhw¦åUfÑqå; n?Sint­TžÝ×ÏfÏ‹mñ\¸ó0Ÿ°¥¸I`/kS +~Ävõ«¼Óäx¿É0 ð‡÷"Žú¥c¤z.Õ‰ùúÌÀE¤²0¶ ¡ÿêíb¾Û2ezª6—Ô9žÆ4ã–ïA ižØÍ?¢ž²/¹¤êj$Ù-fRWÌõNy÷¶5ì¿Kï¢È=iT'ÈÆàztóÇÒŠ,ŸÖŠWÍ—Â™àæ…jQÎZìös–» œ BT%Q¬fJ68 Ä>Hþâ3&vUUhïLEZ£•=D“RÄÅd+÷šG•itHz €5GÉà„U>R…Ͻ]œ“¼²õNôõµUn‘ô|e0¼­eÏ{ÎRTV²!Øß|ûÔwÁSÂQ0¾äUÐÖ&¿¦ØøÅmÃãíø·<é©\2FÎ 4.ÓâõóÉõ…µ9¡ÍŠ^ýöOh™]ó€J› ¿†œ¼¢;¤´”{¤à$d´)ý²Æ”ý ™Ã }Z¤#VZ·èk(iÅ[òhè‹­RÇ•Çõ¼Â*ýÆðÍÒ@¯Õ‡ÙGýOÂCEáuä׈En²2ðvô^ ~;‹l{Õ?41|ã“aðOúÀèevÏBë,ZϺÜÚy·6h[åoÀûr%&¶“”p+©×Áù] Ný"Xïé¯@êßÓà9 É</ˆú÷B<Z ‘ßÓC¸bÆ "%d„J·¦/g_YÒ*u2ú¯Þµøk–Po><[°Æ˜EƒÄÝåry—š9™$ƒOWûÝÿm`jh¯Q“™ž¦ô¦Ÿ¾]^¢ŠÞ.¾é£FïZ×Áˆú²ä|u¤=Ü­§.×+¸‹Eu´Ý]9åŒqš1Äû¨ý3ÏiÕéXò°“®=âÎäšñ²URù²¬Ê]j¦²ˆ Ÿ{ƒ òe9œ Ñ—<Ä<¢-e[íZ{Ëì h±vJ’ñþÚv ïTõgŠ \+;¤_¡²ïõ&Æ×«E ÷ü¬>çž)ýQ}Äíê©©ÜçÞqgˆ½Ú¼Ûn¡|f¾®fà¤Vñjj…ºž]öêûDIû ÇïMìÆIO¶EMìý Ñ?ËÞ‡Äɹ™¸ñÎVEˆŸw6Bøó$Ç@´¥ø bËØ ù[ãƒÁšîëGªú„†aÈ fõEøÖia.êýÀ¸èüÞ2åu𦔞àÏÕïÿÝjwå’A;Ì5,!’ãPhPÚÕ˜;Œíù!vÍ÷NA]F¥™ìOóŒ÷R!fÇÙ™¨\!ˆGEéÌëÞŒx£¨’®löVõŒ`w阒•>â%»š¸á{з_<éùÜhÉ×ñ¾DâP´ >-uz6¹dk«=È æŸàÆ?´1tƒx~é^0‚νàÿžW!TK|¡ÎTƒ )߆ÐFqBƒÄËÖ–(„ªá…àäC0$Cp ¬àEÚ¡û‰y3–_ÒÅÿ£èLo_w¹ŽFþ8íìÖŸV—ºû´^Je{“’§%m´Ï, ©í³Býqûqл¹½@yËé Ü”—é„tëˆs§³ð`;ÝÕݬIµ-²†^C—4?h§ÄB-ª>ʳ¡›êjʧeŠ ØžÎÊn4_ЭC¿Ìgd5:ûW8~Öz»9 JÄ"YJ" ÝÍ\Ð뺃±ÍÎn4ëó ù®»Š„;œÆ¤D#e3žÅÊ^¤n)ëºPV’²ïQŽâ$7ñkj+êìÏÈJæu®,¿*ä g¹øÔÝÏhå'g¹ý1ïØ/ˆ!à–(ÕqSËÍQRŸ™³8j6?Ízk€"’ðô“‘Ä7ä™Ý̓tIN-4Ä1w±þ1]ìóv/lóv¬£D9¡‚ë•â=ö"´Ó(40â¸n‰w¸[µ-xl´"NGåo¥µœ)f+ÿˆOäçr¼¸nÞtÞU,óKÊ‹O’MÉ'#ÞÂmµäY€Â`ßi ˆ;.5Ùyë{.ºk•”vΞWö†0efre «ÞqîÞoš*Ûz-ï³õ?¿<¡Ä£Ö+›jþèqïv‹õ”MÅf¦ð€2^|¨ SE-‘:ƒU;UÃl#žKtN¼€“x.1Cæû»ÝqZ™:Kä•(e+D“ÒÇKnŠþ±nEóx^\°/aŠwJ>F‘ïþ;-«{Ù÷Œ®xI¶åÊq1…û*Ö“»˜Ré#×±¬ÕÊ©ð‡þció —*5³ŸÏÏæÝ<7çhÁ(¹3‹³ «RawÈ~´ôNÖ„’Ѩ™¥¥.{ÓŸ.«Ìëi KW³7}}b“Üšfw·LÏv»vjªÖL¶ˆŸâI±#VÈ ²]â: Ä{©på”Ô¿(bjêpÄ®44CÜ>@/ç"ÐÛĨ À³ü (êÝ@T4×ü@Oã'`™ñ(pË[„Mšo#ÿ_làE¿Æ“ªîêT2¶{ßL}í¹ m‹g„ZˆnỳJ¡¸oÖnZ~›[¥…sNѸ fùo‘·ß«° q»mŪp'?¯ÉT^f}¹MŒ ¬r·+½EMk–2J̰>Në¥äÚ3ÒŸ“^aú»#D7óºš-U»¯Zw[Ï‹MV7ç/„=ŒèœtGŠ~vDÿ™ Vgs ë('yÛÚ®¨j¯¶Ÿ$iÍ0¾ÀcÞ/cåùPˆÕH°ëy¦AÌgÏ¢ÂÈ&Ž%Z¸5Ù–|Øm»K¾[Ö<ú’|*\>ºC ÕVz?cUº›sPžÒ?WÚPíRv W¯£½†&žæ!P¼ $ áçQ ä›ÿc™ÙÀýÀ| 1 Y\ º`µ0'¸#X`†dQ LÐŽè?¨Ež•ÞæÞKÞO¼ýôâ4„~e6dNbd–P2Ç"!'€€Ü—»y+¹ •†ñ!TØÇ~(ßÞ¬ ™•£‡ÒV ©þŸ\šPg‘ÜøïƒµÞ3þõÔ.à“sUêL±?¼®Žýq½R¹•…çc³Ò߸Ôº´è|e(È×ÓµÉâlɾÍ<]èoñÑž'I±04 þH©]j=Ç÷7»>+äT™É ¥ºú3ï»åœ{YPº¹(å_íÛ‡n¾Ÿ|;žŠ~‡ôtѠ˯íŽÈJ瀾@](z@p»D_‹} ²©z7)å¨~ƒ£¢6¾  ƒ–ZëÛ°rèŽÞ )Ú‚ÿ=ý%à$GÆÀ仦yRÙòI5ÜŽÊH¦{LP¾T?€ðÞaàZÞsºd´À)ëäB¾ÝÉß Ñ·¼7Ýû“w´â­¸‡@t»y¡ì,}i_úÇPz ²Sám¾Í+G«Œ©\‘«k­x¨b™çÓ¢SsV_Ûëù¥Ê Ë1°æ—SP½Û¥.:|"tɾv;©•£ÚÍû9HÚmñäÜÙ‹Í; A¾T-:ŒMzÑe4Ža •|ÉäÅFÊÙ´’bh´à ·RÑ¢oÄóðâMæÐ‚ •ýìO-HýÆýÜoùÎp{ó¸ùOò¤Ôù„Oø3œ¡'>|Œ$ABɤ! µ.<ÍÓâÊ(ó|„‚bŒâ8Ç=UYÍjÿ#|Â'Þ?9ǹÀ^ªQ5TÂNï!)<é%  ÷?¾o½C ø¯²Ê­£ä6¢)äe0ò.“ÂWé}<¨•¾`Y•O³ZÏ©ø“ýmà…ì‡#Us*rï|PíŠÒùÊØº_òɹu•ýÎV«;H¬8ß³Fƒ„ïR,¯cI…üNÁôÛ{#ë´~Å]rÊ)W‹BÁýñûJ¼á¸ošl= †gµVp:óŸ“å!¸Yû;Ø^ÜÄòtK -á[ e®ÙF}Vœ˜$˼/$êˆ}ÛRSè|ÉüÛ«›¿#ÕçSŠvÊ®Œê{=õØ®œ :rxú˜Í ù€û:ˆ2{/˜ï<ð#¬-ç¹™gþ÷üÿ¾Üy }6|™TI_»§ýçÜúx´×ek¢ÑFŒ# t¤Ìn,<‰…ÂO†÷ 5ŸúÎIm/ÛM©_âož×_b‹´½©ØÊu•{Kh=ÝæÔÕMÊX«½­.tKµ­twŠÅFغŠP¶Æ³G¿äܾ¹Þ¤\ʹx’݃°Nå< öK• Àèî ¡ÉBƒ"G X7:‚»“:ZðÏHUþ‹q›Oývb5ÓôÑfe:‰“ž{5Ä\ß^~´k‹©dk·ô ˜<èáVO5BØóÍQKþʱñŸøÿ?üWá.ÌF{ŒBɃ¾çI©çDI¤Æ±MÛ²8ãP>ÍèÚß™§Þdö2&²áMÝ.׈[–™sÅ ûGG¦þÒjiˆ§†UÌâlVʲÞ7-ð9ž6F\>/ñ¢h/ûDUsFQW‹»ß0X¼j^‘5Õ&i÷¸]þ” rwfº|ƒEòsyH~î+÷ŠÝÚ`±i3(ÁV"¨h² ›5y„!²<÷Æš‹w©EÜâlZ_å° zêñšûTäYq]ï""Î)y–ôu6°£ÚoàêòX÷:·AÓM0“V?°ÃÀÙ©}ÖÑì¿äLHÖHÕÆq^ÔêâÚÛ•ë„’w;ÐÔí­·§©ÙWÞáŽõ§(G"ÑÜ:ÈãÜãœâi­Ì,O]±ÓwRÙ„áiÄK(z]Ûïr­+x¦‰™ §ÜÅ`Ìt®‚G÷4m®{ƒ°ÑÉ}›×<Êde¡èì<#¦{Rö— ¶]1Žoô>éO3¨äöŽÝ:8x9ómƒr_Çä—V‚ôÏËhÇʦAz8<3°'2Í36rR_y]ý=5Œç™WֱΈZ›´™"(Ò¸_|óŸ_€‰h ßqY}«ÕuZäûcûµív~t/Cü¾p;±"ôOô*φòc“±×â?¡ù’‰ÉàÛ›¬ ÞzfuðdšuAßbWm«ÝÔ§ÜZ ^e°—"`«8 ò/5œ&z7°fh…`—y&Bò€w¤²|ÅÿØï…¸ªÁ­¨/4Ž­‘gÒÞä@xxðQëõHÿšä¯ñûŒöѹÎóJÕ¢óÀ©ÂÃú|>Š®Ô€ûÝ 9shªÆsS7÷zö Èè–þŠ÷wë$ª¶4Ñ5Þ3ÎÏ|b<@PŽð4¶úÈÁú O;·@ýFßjý¬Tä;¯²Híš|•?”ûíLólµ[ò“÷9k ù†n}AwåSëu>¦ÂÿTËË{€¨Ë×úXg™|D?g¶vr³Ì§œØ«}ýþ#tCŠ•òWKù¶Ü퉺]S\KlA£ÌSO¿‰V5®†(s0›eO‹©^¾ª¢p3‘«>æN3¢Ú3•YÊ—¡éÆåië-c*ÂùMûÄVm$=>}µá¦RÇlSX›ígÅ ëcë[rRR\ nMô9–œáïDÈl½’Ä·'ƒ£#ã¯Ò0º0v72ÖÆü;â,…èÆÔ-ÈÛìþñ»E©äõw<áÖnpl}%žÜÓÙh9VGð tšC`­rW¿é°}Ý›úV9 <“R% –ËÀxŒñàÉVG ëMµÐWäþ zL»A­øqy5¦ãUÞ(¹v‰­Ñ0'‹[¹¿øê&:\}žõé÷Ûå˜îyšÙ,ƒÿ)Ïþ§] œ>É8¡å¶?ÓîeúWÙvùÑÚšœz—Ohî¼Ë‰ÐKƒ8g멃ü.£îz §u´¤ªàñlñtù»¬¡\ï úÈU8¿¬¦‰%¬i½V[*• óh f¾Ó¢ïQ |ÃY¾¥„@%€àCAaÎ̦?ÿ>€€ ´ò×¥Uü¿x;Óq~¨ªw¬‹ÚÕ3ô‡=£R èKØÀõ&ŠüL=Í3r…ú ÙòqŸò$CEÈh*ÿVîó¾)©‘P–ií‚u¨ º¨­¥Z¹¯É¸èíüÂxÝc¤žwƒ}•ëée©­”O ›åÁ·ÅIÚÕ:F'; •9î&^ñük¯YÆ£ O¹+pôfîPÎ*UÜ~\Qûð™J®{“ìT‚ LÆ*ý¸ä Œ f ³¹íf*÷RÁé­>I ù‹x…Cnu1s*ê?bÓX{TTpÞQŸg®5UsÔ}öb­žþ¡×»b¥ÊÔ7ùÄ¡ï’Ôkê@g¥qEœsîMŸ/všÓ݉ìOeæ^fr[b'®ù£Õs‰gâ'9ÿ(q”÷ãÆŸ•ßĤ&ŽN²‘•˜¯ü&î.ù)zŠŠá{G¸/™.rø2ÞCú•+îe½X©è©êÊñXùÈ#Èä'©Yˆä°d-Þ‘£D}~òËèñx'ûUVÛsÕ‘lÑß}%×*o?ÍäJÿî>c|F7¹ß¨‘þ’¼Ykp†—5_RkÓ*–?ª„Ýße'[Å{‰µ™O–kúŸÉ/ò¹þ QòOþÏíÀÜÿ³øgÿÏÕ`8ÃjS‡NÒ¹#,ë†U¨ê¢5¹_kͪԌTšïy[ƒ¿U =zIªègÄÍ/~ƒãl-;Å ï‹2›Éþla›÷’ÐiáÍfª6]y“%Y¯QSJÏ£¦V­ò^ð.H5EýR#0=+ÍÑÆ…Ô0Ú[¿£}¬±¸ÆFsõµöH.«·¬‰r·f[‹W•Ç­#ÆQÉÙaüFùnà[*Ó=ë>,QÑiò²›õœÇ0åyw:%òdù?Ÿ­ß‡hÀÿüaxû€Ò@ÜâÿÅÝ{ÆIUmýºÏ\¡rçDÎ9‹’• J0JPDE$+ (‚$ADE%)‚‚ A• É9gèÜ]]y­5ï‡êv÷~ÝîW÷yï9çÞÿ‡êõ[U]5טcŽ9òÄ¥0P}@Ý8”Û€OëM<§ô’Ù* U_Ao±Å^Mob/Ƕ˜Yú‡¤Ø“lç8ô£ý&J…ÒŽ— …fÙÇ` ôt6„`çyEù@ì« n'ܰꨓÍZÆõ¬ÚØñXd5»˜àHÀà7å4š,—?’K2ÞÙ@\Ü€\ƒŸ†å7¥½»~^Îñd޷Γææ`jÚ,™$¿ö õIKÛNn_.Ò €4ÿ: Åÿ#pË?Ð<ð<¬ òV`) YH¥]È _6 ½Êž ?£ì–Ï„cl7EW1D[@9j;æË4YÂ+bE¬9Ln’›Œýb¬+;ÈurÙÀúÈúH>¯µ EwºË|øððˆä49Mi(ÛËöÊ3Êaå°¶S.“Ë”m¬ä'íˆÑ¿Í•KÚFù­¶^œÃa[Íwd9å#.:±é8àŠ×i¸ÆÄ4Càð¼‹ä–§*d§ø®,P†zöÊÖögœ«¬+qóx#Ò3i-‹ÍkÈ î_’æ o™fÉ;e’Ïò]jZÂ{VZÝ -~)ü·šwä9óiG ÖÆ6°}%®Õ½0N„êµrh´—½µ×ŠÞjSìÊ!q»µÓz ÞÏïD¼+=v _X³•{É“íxÒÆ³ óCFðqÂÚÝz{lVUs-¨·µ6ht“~6ö?ÊV¥5¨õ};¨2@ºä`0š¹ ³Ä'àù$æ4vý†m8ÈGPÀXh®„Òµ+Ôõ¨úÿ²ÄŸÃ=Ê̪³ ^l-/€1Q|Ö±èªÜ™%RÀ¯nY^Ùæ õµžHë7u/.c›æc·È"_ž …–ÁTRÝÍäUBú\®@ì3Üá³616<Ò¯p€é‘Kâ+1ƽŸTwcqVÎvgÒA^-­ Øº×šÓ¥`:)1¼•YS¹ ‘ñžg Þ&Û•]ðœ~NéZ09©Œä¸xJP¦Liàzà1À4†ê?DðC ê TÆFVh uÈ yÄ…÷;%ß:jÍuü±‹)EùH "Æ,JPÂhˆ…e|ÀXÓˆ!ÆL¢<åÍopá²jpœãÖ!ñ¤x’ºòSù©ÜÏJVʶ$’(>%@@ÎFGWz° ¢­È™ÊFù“üI¹ÌQŽ*¯!j_ (P70žñÚ^ía@ê‹€ ¾D]}èS‰Çƃc ¿‚c#Ap. œ¹NÓÕî™Hª»k¢gêKeÐSŠfÆoããXÜ>-±+æM»kÅ3*½w?íZŒW‡s%ôÐP´°Æ;u}”1ªÂ˜RݵZÕ>r`ˆl‘ý†kôΉ0X@iʻᙄõ‰âzÐô[tǦy sTëÏHÞW¾'U{˜ÞJ?×zÑFsÚó¬ÒÑšˆá¨jMASß2ïù±9ÄÃÖEßÉ& |Å4°åXeÁüPÚAÌe$k­«žö¸kþ]ñ_ª3ù^Õ6ãÍ¿Ér*Ù&ˆ7rl…]I£–ÈNTê‹7P½»ek‚Ê¥=.Gªv˜@ð°Ò…°rŒ40BXbÐÕÃZm°¿¬¿ ÊlW%ÐضãeÛà^î\ ñõû ù¿sÄV¢–«ŸãŽÿqw-(ø&æu(Ð<½¡`Qì8JåçÅ–ÃÈ»ézÀš~SĆ~V§§´ö×0¶¦\à^ó@åŸc·8ÖßUQ›’ø]ÆpV§”Ì|Ž= 3»²Æz"«%³|'²r¦;>É~×ù’>2÷ƒí$qàØÁvpTâ68+²\nƒk(&–§’„˜Æ ·ÄÆÅÖØ4RBqñ–¡¿â¼|ÂuRéèý>¥<5³ÝiÇÈÍv¥– K )íŽëï§5’É%'¾®ë|QßéÐ,™8cròp°½P>Êîß”ŸåëÚñÐoôV7*w3C¹í}LŸÃꬻcŸ&&t˜ËÌW–¹îÂr·HÜŠ×Çÿ4x¦ø>{Lð^pžÊ=àèº ¡cà8˜ ¶U¡>`ë+棫O€°j Û¾ =K®žnîfšv2ÒžrÊ =F–À4Ò¹…n~$&²ß¹ÒÔÀù/ôü?« 4­Á×Ì®Èa²BùV4ÄÅFòˆ“ÓåUl‘QfS°Ó¦‚½²ºŒ2Ö7à[Ù.CßjM%‚Zä{0så\ÐŽ«?»äq¬•ôåy1ä«Üñ‰Èª3¨(†¿Qð2Ä,²è&jÑEî[é+7°‚¥&²1yYôEÈ2ÂIH^N„,+n`ÈãlÇ#›R‹²"ÐPÖä–ÕUù˜ÁæO|Ç@>áIºXcGÊÕℽ‹íˆ¢4à³¾ä6n¥<§€f3]lã­Ï˜,bºG/k}x)ãÄF„Ø­ì“/ÑAͶêaª›-ªxYαXŽêâz‹)€ÁL@£›Ä0¢+?ȧh Xô"Àkr=^ƒE?°š(u šÓ•ꦘïð ˆ+²7ÐS6Q¾Ö—DÄt– 3MZ,È»Ø,>f³©nåò:cä\Y“6j"‡¹(^à7ŒI²,çmw‰§qS¬‡pÊŽ_ˆõ€O"bà÷ç•]¹ 8'æH¦Ü¤V¥µy]ý‚fHÆH+Vù ü¬=fVWûÑ@mæam.†ù†@34­s ·ö8¥#waXùÖÓüúMtàyz.ñžý©ø¡tVʧZ{½™ØÅ-Œ/È©@WÍM€úæÞ@hocÃð¿.ïç´«|ƒ:ÆYt"¢¥ü¿Í¢+qFެÂU¿..pÒÓ•Aˆ®db“÷c’G ITT顎5¥(ÃR‘ÇuçiqŽxY{ˆ‹8ÅqîhoŠý$D:c`Ó®1)'KÀzdØzD-í%°¼‘N §(Ë€tík`=“Aåf0k†×Nm0°CIsµù(/è#Àz_Ú€^"Œú‘V jˆ»‰ˆ,Aux Ul—ïx@öå¶(Êjå G¥Äorˆ;æU DŒÈ À:ù4/‘Çù ;dÀjCW}„|£ÖVN³Á^Q~Ç+jge+¦Z‚`64Äë­oÌÄÃZÓW}À¬Éx¥„y¯zÛ¬ÎÛÚL«1êNóW¼ÊAk?iê k“‡1˜óJÄ~†O”˜²ôg”ÉŠ¿Ó«°]ÐT«oÖ 0¿^»ƒê˜pÀL/¨õŒXôCØõv‘‚ÚmãnÚ‡F]Жo‚:@6µ‹¹ ”AÖ7 hò+Wän`€¨ ¢‰¼r®X²@<ôT»ƒù‹òXnõU0_Tïc¦þÒˆÓZ""em ¹i¯§É›‘»´™òŠQäÈófuℇs¾!ÊôLQ (iMŒýŠu¶Z oQàZ³ý1±”VþAÜ'P°ÆáÔš*W©¬.™ ”2[SA¬—oX¥(á\b<Ä7r•5•¶ö!fEŽ„k›óy͹JŽa…¨`T'&2L]€ô¬7ª2¿ëÙ¯n¶R¬³¢‚ÖÑ\&óÂn4gÒÔº­wðÌ•;yÓ¬ÅuãAR)¥ìc9 wˆJÓä 1ä5[Wp=)wµ$4B5m÷ƒøHâU'X¿"ÆrˆÚDYBR¸´XIž–¡tâFp#¸`µRR@sq†NÖ4u?ñ‘þÚ/(Prp†ÃЇÖê½¢¹ÙÒÐxßr*CøÈ<#Γe42fsÆ|T¬R~c«HËÃ> ÙÛö"š¹E}¬Gx ¬5êk`Ô3€1Õêê»Îï!X"†üé‡Á™`Ä+ÔûYZw1 ”^2ˆ©5¦RO–Ħ抙 Ìã(c­½ ôæ&ae—¸*â•QÕL]‚ú¢ãG‚b¯ÙƒÝµäkX`ŸXWÓŸ7wפ–þlÍ…LýOÁ㊱nM¹ÑØf‚‚¾¶¶"V£ú=ê`úÉK²f@óDlˆD@ÕÔA­ìÚ‰6 _–߀ÇÐ ôo¡`7Ì æ· ½©Õ"Äç܇]ÌäpÙê ÖTë4˜eÂÝ ô¸·è±J(ó9¨MÑAû@» } ¬Ð¨3Ôgˆz ‰ª\ÇM@1)Ï+Ê2*Ñ^éBU•¸E-¥)çAœë@4P²A?·xÒXJ†£å–XSicûFâaõ„5‚©îÎVbE s1Ös,;ÅNf‰¹jesËÃò!1\VO*[GD7Æ8VZih}¢ôäŒf“‡bƒ15lWû 9ìRG°Šh"$`¨ Ê0y°±i5=ÑåK¼ –g›Cäu¼‘lõº>‡dÈx1—¹Z¹_L°üxÃyÚ³¼¯^© å1±”»Â1j 1ª%ÒøÌh¢ôcXä¶¢rI&>cz¤)»XîìFŽeã  « “!²#’ Ö,JQ.<Ÿq2ò ¹feê“aµÉ1´Ö’!íú5ÒÃUäIôà7ä‰'íýð›?[k‘þ—}0”êLìê Í ÁVÚáÇm&XÇ0Åë"™ý{˜»µ!¶Ó¼©Çê¯ó½}™ÃGÀ¹Ô/Ë8‡:{ÒQ÷¨gÅÞ{òýì“G­nÄ:úk ãî‰ïŠðüSño±þ:Võ¢Õ‹¹@®æ1hâ1­iC¥‰£;ØO;•¹¡Ä)t–0 ?ÊâÂIbT©øS-, €^ì3y´ 5³€$ˆÚÏ®0‡Èǰƒü”»€½r((Å`ПŸ@úÍŸXnPzŠÀ&10De@ÛD€Âüþ?úâ°ˆ`ÿ7Ÿ‹ºÑº¤ 4(lÕ1²Øï%ü …þ+õz#{À`¢kåSà&¯c¹´â<0Ú@p|]ì »(¤r´NÔ"©ÿ7éñg2°ýGß.öëQŠ| À£$!‘€@0›N4f$Ù÷·%úŒ¹Ì+ö[µ"—j©û _E¦÷Ã@Q°(Š(wDu­ôbßÿQáû^bþ0¢è«Àˆbß݆Ÿ¢Õ"‹ÑZûöè¬DSÇ0€Üó·iøŸ#:Ç7˜ À'ÅžÛ*výgˆ>õ%Ž?ð(ð>@a3:«€¢™Ù @g(”ZÑ×r¼ À]ù d±ç°õÿ çÿß?J†TŠx³øìE飻ã`=D{ þéû£#øïјÀ Tà:›×'Ñ.Å9ü(.•'íÞäÿ4Yÿ[D9úðàþ—Ï( Ÿq3 ¸¼Á`ðP0‰TÞr?ÈDê ú  ÐÁX|Þ_.FãéÀ?ÏxѵDö²ÌIÀ` þ¥Ûòžå9ûxÄÖX÷ðˆYŒf!ˆTüý™êÈ(DD-~F§€T>ÇÃEÆOqh-+¹r?È-Ôq/S€‡„.²hJp  ªÀ§ä÷4à&`qP g(j$•þYUµýÎðaà'΂M‘€Á¿ÚœþÁ*`-:àa'ÐV®L9Pi =@@.ì¢3p‹&HÒx&Æò&3”]L`ìß:þkf¦;cé P(䟠ð×Ð("…tøÇ,þçˆe?p(Új‹«-ÿšž&* ò-p• €§1I¨ g©HÀS8îŸ{öÀXvÓñßEFbtõÚŠ=sñ;Ú¿[‘À»Ÿûû™ŒTúÓÉž§!@  h+øÏLÑÿ·å’@‘i=%šMÝÓŠ©¤7øXà `%Dä·Ø@YA0ÈOå.C¨ld¹¨ÌU`0F´åkæ‘Mw^þ›dz #“—xŸwIDR‰Fjò4p/u‹î€òßðÞÿ,¢N¡ÞôŽ3&³¿X”§?ðFãŸÝQJ‹b#.½ìGú1 x•²@)ª£xØÁ8`nà~Â@˜ï€m¬:ÈI@È&D@”@Ù‚Û`í3ЬTšj„D%îˆË2Œ$×Iᦡ¡x¥™‚BåñS nÙX#P€ûpðwXt•…§TÔy°$b€¬KÐ À\2…Ô>"b!à4§@:‚"ìc€ÂÆQãâ¯Ë¿¿Žâ²àzí÷Y‹®;Ð x‹>@kî,Ž"̹ Cñ…†ÿßQŒ’ã"W±šÅÞUнþ‘Óþ æØû£:ýŸÑSU Øx¢ß,v?ª®g“xùðóE;B2a`< r ³@¼ ^Ôšš¢ ‹ýbŠæŒ¢tk>€ˆjä¥x¨Éf@Ãl¨™¢=¢×™Hà*¸HÈ[XÀi£àG"ÀÁBS§'° æ ,¿pØÄsÀtîFá¼ì>¡.6¦âˆ£ê¿_Æ_ž»âœS|­ýZ8P¤×ýÑ(‹þJÔñ]¿qùw£"D˜½ìEàÇ^èTÍ'„‘8 )AcS@î“»A$‡%ßb ~V°(E.ž  £egå@“Ï£ `Š)Ø9ÁKœä¨xMÔa ÇYE?9˜U”÷Èè2“£l´<“çd_v‹áÚ9‰Ÿl1l¡ {XÇ×|*7ÐOù%tÈ[‚­á'¼»Øéþ9m¦< ”V?â'X‡ŸÚ<ˆŽIˆ *eØËNÈU‘~ìPšSÑËò‚ø–>~&H¶x 0š¢M©ŠãH Žd’€ IŠ(ƒ‹T¢<Uq¦A]L4j¤<¹JSTv‹.  %* é |,úƒ\ÅãÀ$úƒœ.fÓ d<Ï€ì"š{)I'ÙŒtǬ‘«ŇòCrùNôç^ý<Õ ˆIdKO¨€,ÑH¾ÀZ–©eù‚_ÅbjãUÞ  >ñ1 ¹ÁÈä*â©Tb?å22€I]à‡Óä7P ²KÃM´®“òw€µìöÉà 1 Äi‘¤Œ’ϵE= DБÀ™¼&f-y¸N ‘(8‰ ã&L IxQÐH·ÄMµ Ýö䃵ÏZ²–¬ ¢¡è˜¸Æ´*S‘,*P…$’L<½éŽG$‰xT9AÎ%ŽƒüødÔy½¨Ìr \@X¼Â l|b1&WéN9~ ¹xž·qr ˆqL¦Êi ú1ÉërB¼ÃÀd9…V±… ò[4>–[0å,ÑŠûX-B$²77X†!W¡¡±•±!äfT"ü ˜ì&Œ³ØPå,Àä" Ù éb—"鞎Dr“|8pBG'‚D"<”D"±££ƒDRAÔ•£R È¥$P85pÑ&-@;Q7="ô‰–*uCÉó@X<¸è¤Ò—³¢- ÙÆ`‚˜ r"ám1]öaÈ^â# x•þl•K©Æ2vc“ð€|šrxÙ$îGc)ÉÂô*ÐPÉÇAN`3‡ÚÔ|ؤ"s•ëØå/üØQDq OpXÅ À‰J‘³4ª%XH ‘`àªÓàâ±€tò@l@yVù ˆ#þopÿ* †ô€ùùÀ¯8I@€Dà©@†¨\¦"È‹TNS8N}$'iŒàå¸Î ¶báL46 ÊoP¹Ã·ÜæßÈ£¤Ë9ìÀÂägìb-ë¨%ÖË÷XËR™"Çr?Ki‡&Þ•Ã@YË«HÑUÎÄú¢ŠoåDZ%xy›ãÌ£6 ã°@¾ƒB˜™Dò:ï£!åb P`_¡kQ€­äÙ[€håì¿EÞÙb¯Ñn´*쀌†/¢ÚdTß*®ÕEÑ}:º»GC‹QÏJ4‡½.P€Ñ€DK ê‘ðШG  '6=Ñç /¡€x ¦0 PÄ»XÜÍ ~ã5*ó¦ø ›ì)¾G•]øx@ìÂ’­ÅO Û3Š¥Ì¤¶ìÁEnÓ$®  *¤Ð“Ï9'd§x…Δ²hƒ…í°¸Lyž£4e# ÍYÁ=Üf±ôã&†xž,tÃL¤Ä=\Â\å- $· ЖۀIà/Ô²€k¢¨Rów ñWñ¥¬Àu9&¼TŽ—8%ö ‘Ç)Ñ€ÀâE.rFfÉ \Å †ˆ•±P ʳ2;‡X‚ÀÃj|œP®s^ÜR‡‘#(5Qƒ”Å$Àq Bx±Ä'ýÆ`<Ò2;!•JÊ'(L:é,ÒYOš¨‰ »¨Žâ<¿r:HVѪŒ"‡1°N¦bRU>ŠŠ‡õü€ä‚òtBD€4tÀްÁËi…ÊrEo|¨¤¢:æ£ÖO€¨ £ôd…^Y ‘ykí…6´H% Äa¸…^ô+âAžEE6S ¶¢ÕUèI@§‚Â>tÑŠª ¶à|x€2Ä€I @g?pŠŸ« îǘ€Š„¸ ¬–€—Å ¹•2h´ .o[›9Kf-‡ä¯Ê|ÞdŠ\C¢xÁžTäð™üÏã0A¾ÀÓÀÓrð0é€GÌ ²€;ÜJ‘ ´¦ǹŠ&›°•Ïij´c©èteØ+ ã’èFœX@%4êR€‡tÄâà1¬`5qòf’ ®‰ÇI—å÷Ä˾”¢uÅ|’„†‰Ik T¢‚¨Xh"í"|T¦;ЛÀKÜC>q –lLY@{®ZGeYŽÈ:²§¹,®qXyQáˆÈà;‰ ”ä^Þ@r‰/Ä‘¨$Gåjà:ÛˆP•Rè(ì*¡e•‰e‰±(X¸p` à&ˆ%ˆÃ„)r—Û±(Rz \€°ˆò‰BÄy"ü¾n`®£× —\Fg 9¤-Eoànj6B€*É" Hˆªbr K)L\ÆMRб#ñ~ @T!H!äYt °€4€I {eܼäµP†r*pšV J@æÊ+ Û±äre¹ÊJ6¯”}ÍP¹C>NH:E>v1‘v@ML $*E´ ^-&þ:ºm¬¯¸ÃÏÒËEF±•›rã¸#’É`5IäŠhH¯Ð€<ñ”x ÏR?Õ¸‹{h†EIü„d èØEnŸ¸bcŒ^§EÆ{ô:‚(…ÆM$稃Á*£sF´.s7pŒ› ÇS XÉMÏÐVHù2Srý¸-;‹M|ÏGtå¬r‹¶< yAÎã]«5'øŠø‘0³P±‰S Ö‘¼Iu³¨ %Ô @ѯaA@ ó€…È¥P ª¦ô‡DüäP‘Ï´f›iƒ%WR…ƒ¸u±XÂ(,ÙF>Œ†%â@<+J!iÔ"‹·8G 9ËÄb‘CUúQ‚U²錳¶PŠg¸‹‡™/ZÑŽÒbë@í‰h^¨†DÕõU$bÁ‚ÎݬåQ~d† Ð_Å&n"—M؉çP” )& "@¨PA ä ¹ò;^!Nv¥%Wå"ÖP^FðÑV®ä¾§×qÉuT³˜‹ œ¥0p 7Dµ¾œ¢PG@.C@¬e)j`’£´@Åà:+H~‘LUpc!yQ˜úG'dT5ÅZ >³@|À5n³&p·€)¾?¢ÊÖS¬¢»Ù)>asÒˆ0åH.Ë~Ø(+¦0œªâ^YƒèAÆË•IØ8À—|ÊM†ó(%?It1À ؉H¯<.bÄßsEq€ WÈùÀqö!åFù-^²PD±¨2L.ð [€\bÑ‘è¤!ظ‰dgÐ䮣2 8$ÏPM:e€&â#¹“Ú´Pd•ëÄà”³@´e0˜DÂâ¶pbpMöñ)A–á $WDˆ**-£p*:¿P‹r"*UÅkØp‹ÈnÊãvàsÐø×ì¢Ù á㿲‚tÚ2»ƒç ša¥¿vq;Êò—öAÁRo_p÷öL£ fxœ…+îù¤0¹qãÓ¾"^ûLK®÷¦SV¸ÄbNÂO;.î(4±‹‡‚þˆèmÅ>ýߨ± ŒGbѽ3jFDwÓL (¤Í &@e6óšÃ7Œ‘SHa·ÈưšÍÜOš8C+ŽqƒŠ\` ÈÀUNužÃw¼„©ò[ù΋NkñP—nÀk²Ð_ŒzÈz _g:P‘F@YêùX jÒ(K# „¸ ƒ&ÜO˜ûèDˆŽtAåD*ª\"?Á^è²ßÈ÷ ,! Ðÿ?  0 caC/¬oüW)EŒ0’Û¨ú¢r]>üÌb`¡\ ò6‚l,Ž¢$AÑ”ëØå$– ”•(áG¤<€Dˆ5üÌQÖÒ–W9n$³>9Ó„pÞÔã]±]©´çÜ8uc(§âÇ«ƒóCðtsG$æãØàÞ˜ð6º«qÒ ¤;ï-&Õ.Ñ‚Šê=%|¥¤9ãhÌ[€d!eþmF?À‡À9Þ&2¨E9àAŽÇäËÀ â!º ñ…fò ÎËó(ì: žúShÂÀ ¦à–…ÂÃs%£–2Ÿ8ÀJ>äç[Ù:°”ùrrxç”ûâLÞe} sŸ£Óð÷üazòª¬&Då , \à3à!:˜-ÞÆñð˜˜T`$AâG¡ì[uÿ•‹Ìß_mÿ YÑÅ3Åîÿ•Ü÷ÿJ½hpñ*ƒnÜ€‚xð:: &&"€``/^¢Ž0à#ð“ü„Itb $á \c#6NpøM^¹žM„èÇ.ìò,1­®l#`Mñ(o2 Ö‹c„%DÀz›€qžÅøÄ{â+"Ê\šb9 ‹¯©O˜6Ô'LyÑ0ÕiIˆRÔ"Œ‡*xè@ƒÈï4)B¸08c/tåü}¨Åæìn‰èh¿S[#ØÑ‚"Ù_ü5º2=¿ß‘…#w qH1Xäà!B> €…tt²¸ŽÉ ¶áÇÉç8'É;ä~,c=!ù{Qe~´ €ÁlÊÕŠ9¢$ˆžÔ%BsÚa£ý‘”£.a’I) ÂeŠì| ikT$Ñ|QYÈaQnü¢Üm¾JÀ pâ"…¡ ¤‘ T Âßž™S@y@¨p÷ü#¢{t´Bâ$%?ÒñY.s8ÁÀnŽ‚\%o«¸¼'î%$_å-t΋µ(”gP7!J!‘â‡èú;oüW Êò óé å^,–í&¦ðÐAìî§-S,9H)Æÿ6ê…œ÷g2åÿO(^!ôïU¢üö—M› Q‹.„ƒh%Ùa9ø’7@Ž“ßO‹þÀ qI/% bQ†Ihò´Œf=÷®ÉoAwŸŠ©Àc¬!">ãItò>=D щÑ4ç1IÁB%„òûÜD‘eþ5›ÿi@ã„\.êš‹öt§@Hï^éWæÄgJ×€+„b6ÉRØÕQÃDW°M‘OS”A[ÍxP’¬æeP21€…Ñ øwå±QÇ·4žs"_Ú3 ï³¶#ý‹Å( 9NŽ@„ø #Ü›žhÁWÄ~õ/ÏÈ!9OÑXžËÝÍý\W¾3ŸPV—ե੤¹"¿ûˆú1.Ï΃XI6p‘8 ,_†ù1Èå/ Ÿ«@é/:bš’Šòxÿíø-,ÀÀà¿*µUÜþ5üWåö?Uvÿþ«àÿsüC,>ÿ(è– ³‰)·bã˜üd«/È÷•8ËÔÑœû—ÉÎL>Õé@¬üÂ|‡× ŽÈÝòù¼Cê1qìæÝ¢gdՙƔ+8r±5Ù¾«yÏsQ)펥‰³c¢“²Ž2© ­z5æ7îRzÿ§~—­¤‰8.*ƒÞ’n }‡ÜAÒŠe>Kö‚f@ºœ|)Ï‚l/—ƒ ñ,ˆb7°z âÈ’IÊ0¨&J±2ÿwªeô:°¦ìì!I>‰ä³]ž’€cLúpä*%” < Tí€y….qó÷ F•Óh@ –bš£jüˆà3ÿãüÄ9ß7T5d\gwøffE›å³k2ÆQ·Ô%žÕ&–rËj,ÿV™—°©,  HDTοÉz ·X± «ÉË@'ñˆõâs“Y<&>ÚŠïjìb¨@TI6ˆ  ¢A üoQÉ"…oAEC–¡ /pSvöËNÀ:F|O> à+m)òe/(oˆ8ŸcQ*{ƒ¼]v¡ix¤¼Âå¬w•S,Êù’¡±×6Éotú.ôÌ^×Áíç®ô%"gÛ·aÄLJÚ†ÓÓѹ…»b§–üŒÎî”O3Õy55‘óúäÔý8”i‰ó÷ÇâÄÏäEì¿–ÿ„¢¹`Ö‘@WÃMoŒ¡•vŸËÁqÇ=–›ÊAçXê ¿m2’–lG`Òò÷*ðrˆ¡ j]«4€ë”FPèM ˆ.¢6ІN@'.ï‚èN,Zèÿ‡äQÐ?‚t"(¤à.9¼ƒo)†=$“Éq4VɳòcösÈÀ&‡ˆqèb¤8“r8çå€IDATø UÄó •Q kÆT,Va¢0I9—®|)_Í»JÄêËá–‘ëû„ ïÔI)˜•žG0«ê•cX¡[ϼSýÖØŸä|‰7éëøgQ“n¦–Ä7.eZ¬‘Ú€+1÷¥­ÇI]À¶3®¨_»k!”v?%•i¶’Ä()Îxòé£÷à´Pmã¨Ë*å8O’‚Æz$Ã8ƒ . éŸvœ¨4‰*d1Àuf¿0øoìÆË+ÜE ýiÅt|‹&¿ ÷EJ%|]ÞZˆ°–‡€™çÿŒ1>ïÍ; Öÿ<°×Ž»ôñå@ Ù瀪¸jƒò–m7;¸d¯â9Ûb,žíQ¨/Vqƒ äòˆç&¹@9n’à6É@IîFsŠ;”¦)iX$YSPØ,‡'C?bÐÔh´¾*ðU\÷ +•âO0á@*ßÑ €ßgÙæð À^Ùd& ÈÙ¢=–Èe BÔ@­0h¬à-x„ê¼Æˆ‚åt2Fä&´Íe¹V‡fbƒÞ€ˆO-r©®?…!ÖêYÄQŽ|tòPI>iƱ•|ùµŒq·ÚC¶‹$Ãí`5*ÉIzg¾¥UA)ÉùÒ…´–‡Þ²ÆTó‡@/ˆŒ-¸á×s÷C`KÖ³Ppf#È»tûqÈv¦ŸAfý|ç'ÌÜIÝy[ƒ¹Èœ³¡Î‘1æ`,WWû.4ç1õ"¶©" EmKEBî*®êØä©@c G®c ºý”mR³+vβq_áÖ{Ùë E_ë^6a#tæ «¬2E5`°ÒaÌ =N8ä-¸B$øR 4³@ÞÞë9bÜΟVðŒù%Zˆ†ØËÚ¶!*Û«'a–±×[r‰±®Rä"t‘ä$Q Œÿ V±¿J!þŸuJD3Q£cÉ Œâ4¦lA:–Ì£]š”$,?§66k±¸„‰_jAôÑÆ40 A;zÑ."¯#xÑ´‘jVÊ%ä‚[CEº°Ÿrè‡dÝ'´¡þ·Îî¢ÙíPÖeZ_=}ý¬ë53sQrKA+;’›—š±·ôÖDÂìAØÙ—‘¸]åÕ­Ôó4Žy“Qîñ®-Ôt,ö„ã|Øö´D³»?1œâÙatà‰ÃÌzü/CÒóœ‡Ø Ø1íUÄ­Y`k§î!¼²ºÒôÏ­ÁÚ#š€˜¢ê meà’KA¾-O‚\Éu Oìñ£8 âVƒnUk‰œr¹ò<ˆöÖÃ`­c#È~òM°ÖZ‹ ð±ùø}Ö.ÈõÊ{!ÿ¤‹Ì ˆeˆì.ª n4ÐWÉW*å"ÞÌŸèë¿åíÆÅ`ß@Kκߡª±%¦b•ÁÄ7l~ kT›`["~ª|VÄÀ¤£ÊKømm•ʳÔB)Ô~ÍÂ6  Ðn¶r­ã@ 6d¹ØÆiŽ‰ÚœÆ0°D©ØÄê‘F‘#Sû¿ÆÍöG[æ?ƒA´2&„`Yh² éD,BvÂÃ9XÏkÀ<怜©¼œ-Q†G±Ó@D˜|M‘“%š‰ùû^oËψ†l)^…òÝÅpþyêSÔ©S0d+`ƒ¬\•Cx–“Àwâ8ùÔfA¤ø;‚‘»¦èß!<…¿F´¶¨èZù_®3¼…Ia&±|ÔF€|•®ÊÀ>Ö§ÄÀuQ¨%6÷°hñ—Ÿ6j5Lå;àS¹ äk0PZ¦€Há"ÈÓJ;a¾ÆK)q…tÛÐ0ùˆHì…¡Žÿügœ<Ø Ç‚Täm EµoA<@H”2åà’XÔ½zäeˆÑ0 ›T$ûÑÝ,‹΃õ’¼ÍvëŒÈ“ËVt ?.¶Bà–Ù®L6_„[b”ªƒ Ì5b:+o€VFõr l@".ŠZîZfU"\°ê ÓGy›<)¾ç"ÃDaRF¸) ž¨EÿS2áÿ~D×ctÝ©ðS…‘9bkq¬ä!å\*#,™Ë=´À±èE˜¢¶C~TÀÍ: ¹•á²-°œ5˜úkê,Q† èdàR~ï,Qd“GS þÑÔc«Ñ@î 5p@þ ç@t¥Eõ’¾éÇÀ…¶“{Y-¼Ød®º2 ô—]é w…ׂ\¡Ž:)õÀÜfs§¥BhMþ%àiç« ÌŒÁƒB3½ù…ÿï®kxîqïw¿˜wÁ½:þ"¸Ï–Ú‹téiï˰£Q©²|¢”®XJfó}é•TÀŠÝZ áÂÔî@# à.\[ `“às–ì(VŸˆ6FˆjXÔu8hŠò{'‚"?b„a4lè…õ[ÿ_‡Uìõ¿—±Ý÷ î}ýg/( ¹r"ð›Ü 2QVéS&€HQê€pPŸðï£¸Š ¨Äd–*KàŒô§Ks‰Wxñr/6DÊ^|Ÿ´À—×2‘¾Ñׇ"òÎ_¨•Ï~7èJÒ'òŸW'GŽ2_µòu ÆŠù;Ï»E¿øo"ég;©É~ûAk8‘„:æèö‘æv°ÍýÁó¥¹ô/4\ó¬c  o…ð0™ ¢‘c ÄNQ†ƒVVî9@lÊó pÔH€Ð÷aÀw¯z”ö¶ß@{<Ür}êX0>×Ö€µÁÞ¡êtðÖvA°š¶Ã7Y…–×Öæ¤gd¯~F®÷º”'vÓã--l¡£ù›™Pývx¡ª£ŒáØËvŠt‚äÓúGP¢n\K(}:~Äïrí{´ëß¼@Àaå†ÙŒù41ìå¨ÈåRÔ !©Gak1€J@ y@'ª¨”.,Æ+êRùwUŒ¢1êÿý 2D8Á`+§Ÿ¹ò[2€<Ê‚”¬y”kH™M,B¾Ã½\—?Ñ›–ú½”å 8†$žó¼T$瀸f0%ëSdz¥‚þX—ǘ °]yǾ›Á×t~*']ßG$Ÿßìɉº0]©‘ó ï§CËKJZÙº¦ù)iï­Ï‘CìÍe)³W*KÛ¬7ú´&oPJëð7žt%X7s2`íÁà»i¹ þ²YöšjÄoTúg£m+Ä´·%€+Õý(xŽ*ó@ÈY'ñ·q%ø;m!þ=þ¼9„äpŠ@ ÖhÿOà>"=À7ÏÞæ6ÈÍW¶·šº¼.u/ÁÌaº‚##hïG¹ÛìMÍA¾û”dzs –û§{_¡·½Íåç"£Ýîd¥`…x¸Rß öTü:Ø«Ô^ù JÙ3j+(l;©«czAÊÅX7Äo¥¥ä©”JŽù ( D¬<`§Y°ÉéXÔßqxfr!:pXE>P†,³‘@‚€ƒ“‰ªb£(¦UÙüH³ PØž‹º$ï#@ÎÂì¦0’’ ß§*^ΓŠ[ÎF‘·”XmÕíÀHQ‡¢¢Â„êÉW43at+›Ü•ÌÞ¡Cã¾—ÈE,¼"Õä}7çzzŠj—~öXÖÞ !5.¿[fÞºIÎÌ›ƒïâôÕwd õgâ6!⻥M%ÃóºþGœ6µW=Eb&ÙzÊJöcöá ZL\é°Î,÷—æI['7~ÉÏvd(uþ6ŸÂc/=ͺÌù£ËbzžLÑyÜÙ*îYÙXïŸX%â!ÿ™Q_âsî¸!J ¤He+$NTO@ÌqýÄŒã@kÏà'Ò(Ê5þÏñï»xþ÷(ãÐÌNfeÜq@Ötk;Fö(¹%Ý¦Ä Óçé 9˜ó…6È>–áϤoÁ™Ü•d{×dÖBzO›#ò:½ûTÁç=9¼²?ñu‚œƒ¹Ì÷ó!©ç v§ö#Ħ8÷C,Ž.à9`¯®·õ•àVœOóu÷8pŒp¬[È}ô_ík1õ Îá¨Z’º§ZÖuD&²MùÒìGÏpkWµy‡ëb¨¼,l8©ˆ‹jâ}Js\œ!^&+× Y«•|Z8Íè`}ñ‚é§ßÉ¡m#7}cq„ÆGšAè»À3üŸ¢'ß@-èæyÇû¾‰¬B×1^EÄdÚ–€{ˆí:¸[ÛòÀµ:¦ØÃŽË w û×®­ ¶vŒMû‰(/:BWÑý|ǯ֫r7וO™G)ñ:Š,ÁÃl‘D+¹T6ã)¹U\!bõ6ßD7—š@d…ÜLÀøÆ× ‡ÿŠ·)FðNp 2é—ѳ±ÅÅ<–þòI`2¸L:`ò °V¶ÙN4!™4$ ˜Øø‡\? £P×ê@Ⱥ+Ô{Þ´P[j]i#wðÊÙ cýŽ_t<1OgŠùÁGİö¨ï 5Mÿ ¡•2ª`¨ö¤½ôS.G.ÉÁÂT†PŸC §å8ÑMülMa·õ¹¨F.óyƒxy‡y^Ù«t‘OêXL³Ü|ñû+°Ùªá|·edM£¿Òž‘F‘ üJ‰ð½9]!¸NÜ Á+¾Œ£øÏúh(®‚ßÇA¤÷ƒÀ[ÿ[h4Âû¦ü ª(nÈ­Ú¶Æî|°ÙX z²õ=¨o#ÀÞSOåùðJUÃ?€þªZ4M€X¹d­à°ïŒ‰€ÚD ¢,«@£5OÀzBÜ>vøÀ0E/>ù,éz‚O_ur¨$?Pê=[3(qÒæ!Râ–í ôÔ!)# 飒cÎ%eކ2®RÈ|îÔüŒ l*7U‚P¹ ®1ØÒΩO ô_r7EýL‹glJnÙä)qD©@Iâ.À…°‡DÃ…DC60¡HÏ‹òUt) (P˜1jq‡ääç@ˆçm)Ê‹úkØÂE°ž—g@>Än`/)Ÿä*ãè²;{A.—Ó@˜¢-(CÄP/r/¾ÃàX|ŽÛYC_&ò0íhqðrªa+óG ø½U ÿ@ r²ÇZ•Ù“>]¦ÈW?²}G‹Gc‰Ÿ÷O~‡ —VÆÎò/Kßh;s§LFèyî o²ðÆ7Ì`Mν ׎r]Ðã+¥Z°Ê¡³o¸aw} 6×~¾æyçeËÝñ‚|‚÷?±˜úŽò#ã{­T¨r¤œÒÝq94A̱f„&sØýaðc6ÅÅ„¯‘äyĨ 1"Ùà¬iö^Æt°Í2ë‚óœÜ öóæ× 7’“À>P? žá‘ƒ"G@:•™ /³ÏG1 ÔgÅ<à‰ÈC项ZUàåà“g ÔÅjÁ)Ê^w&ü×Õ~xJÌßû¶o XIK‚–¶DðWÕ«CöG;Èïå¼ÁåÜŸ=-ퟚCs›+^ßÓÔ!Ó;šÒ ùÃ>¹/áøI˜î~5s"çËÊ/gWy¹à!â«þi"¾©8G&Ñ£Ü[J‘´¯µÐ“ºã ö¥¸Ž„=¯¥&b³¿ä¶aˆA@,daC)#@¸!ß Íx† Ÿ°N÷ò¦xLlEŠ9ä¢1†D£IÆ b8Õ€¤·Éž *ˆ ¢9È 2xе@…9‡ÊQq 0 [eþ=(Lù5g€x4`3w@>Én 'ð–¼r^à)²0å›x²94@>ÃP2 vØK&ÑÞÿsx…å@3:;Dz"d=ó+0ž0N°.bä ÉÈ]Ÿ#§À±Ž7hs4ßY…ŸoÔD\}ýè1+^HÛY)uD (Ò&@éFöê4Èó(Ä'Ø«€c¨þ¨åµ… Îç ˜÷»¤ˆ6™ú;5ÇæÇl+SŽ6Ó Äö€ØMOÍA†ÂÓ!> òIlòcXŒxˆD÷€?¾à]Èœš×~0+CF{Y’¶tBåZÆ¥`K=àØ‰p•Ò éØ?Ä®ìaß?¹€ŽpÍjàGvóà7?v™oñ°FVq”㘢*£LÃB稢+:𵨠܋ ÄTîZ’D0€! åA$1ã?àü·Âf1….ÖèI(bwæ&ªñ(°Î¿‹Uæ~"V«È3`=šƒn´ .!9^ÅÕ`^¤"¿ËD¶rÜ×V6“Û}_bbäÕd¥˜y@_M“«[ˆEJd!½IÂÃ¥öXýALU>QÉÖ¬—E*:’¥âclVàˆHæE¨ƒò*‚«“Ù”pìÆ_Ó³b{ÆÊ7Ë,W6â1Ñ‚ ˜B¥ªˆe`'@QŸTbdbø³Š½¢U`a¡abb ÿ^Ëôÿø ׎È$dRœ'²6[A®d-Ò‡am¢&gÅô¥ŸÖˆ6ìß!1ø A& rP²`8øÌ;Ù;‚§123{#noVTŒ›w´ ØÏ_pܤʅ©žûyábs÷6ë±ô¥·£·ÄŸ¾¥ªŒÍ:ʹEó½Û8wlø2OØK…G²TÙA]}qøM,½™1EóXûÀa†Àz±œ3}3!\^•àôØó›°Ìtÿ׎5G‚)ÄO <$T»ån°r@_a lsE.˜V`:äÍ‹iŽN–üe”%ùÍñ°H] ÁÁj fA»@LÔc]h§í;Vø{Ù‡±Üð»Ò9imÂyå«ôŸ¨×!ë3dÉÑ™§I¯yû@¹Ÿ}ý¡Ôs¹× ñõY(ó¥¹’>r<•øiÙ(‰­«Nuw‹ªÝ9¨­pÆÃ3ÜWH±¢²Oø€o@¾.Àñ)ÈÆ²?Љg@^—¿‚,“èb$÷SÄ ñÐÇ€Ž´Ä  -Q)YX(ò¿Š(#Ç9ŽÅ÷ü€Æ.€œÇ7À"¹˜Ã&³ù#¹ ˆDO`9KA|)†ƒ8ÆŸó7û~/— # c‡yèœf‹¯!}dË#'8}’pîäË>l7çYObÝþÊýÖížwPoÄÆ}‚¸Ÿtž‡¯…S?áÈ­³¥äò•ZI‡Zç¦êCü¦½€GuV9FE{Ë„Æ`[WJx•˜®m Wç{3€ž¼$©UßZÌœS÷þ *uëë³ïÃ’9™¯Áugd ¸o†Ÿ÷gþÙ`{K~1XåÀñ$;Á¹ÁwÄ]®E˜qµƒXböAÕêÙžÇRg³á!ÙVìš‹_A^¹Ù [èum1º¼¤NkMà 0jøïGÎ[wa†™ß£…?sι<4 >оƒH’z‚ûÔ-à hËÀ×R Þ‡õ{Áû“#HØŸâ<ƒÍw¿+f[Ü{ä{Ûy†øœ!®²òmk›}–ï}N8•¯Œ6–ºÚ¥ïͲ‰ÜØáÙoÓ)µaÖvR“Êí‹Uâsïx¬´oB hežô»!Ñ|âÈñtZ|±$ å³´ÝH>ÎZ©q`¯Vb1h‡mOKYèô¦(zÿPtÓ›Žüûú—è磪ϟ¹ŽÿQ™¢+`'xϘ͓ä3’'ˆõÔ«o7E|zk"×gmïý ‘¬É#Ñ3fÉ— c£+²~q-¼3=6©w–Çn’w®Iv‘xí×’“¯ŸM˜>˜S[{ ÒyíʺÑèö£z¦sF™m‰Î •qÆ©ž³4s?dÎ¥¥+AËa†+1ROÆÙjÛ6·(Wõ‚ Äa[F  õþ_)p¥ˆ—é\}bÅÙjn僿ÁÿÑ“=΃ONƒàè^Õ¬NÎ~eA¿R[©Jý<0̱ԟÄû´Èó„’âà ö˜î¡¦`¯gÏóæbp®3_gžœޱJ p-Òû']ÝΟm‚£µk8¯…¯‚LHZž‡”ê ÖA®`°@D5]#ä3| œRÛe"Ÿ€õh^[ðÒF€<ü‚#"5 Ø>¼ üÉ¡fw^΃‚TÿÛ#ºÎ$ÈgO‚@y½3‘üåŽæèµ{¨ž?ÃQ…½·Ç;‘ë£]ó­Ö‘_Ä+þ%ù4ð.%ž‹Þ©æq¬©vFñTž€Ü²Á äOTCæª`YÈ>v}¸7˜ƒ ¦uÁ}‚_Áµ<£\W\¥œãœËì‡Ó¶ Põ¯AJ½ °B[²½x’®ò‘%æÈ},Rž”‡€WÈáˆx“²ƒ’-+°‹¶V}ë´˜iM`4ÓÁ|.öD梱"”œìÿ!Àð}hÞ‰€· hùgÎ}êJ€˜t€˜_\_wI@w&8ßpÔ°ï°CдóÀµ,È6ÊTàŒ( œæ*pÖê⎠!Ë45ò€‘^€* h~‹ãÚO Ç{•–Qàh缃–²ql<î«}£§”üüÿg8 äP H°^šd&@`_F<ää[X¹IyÃ1¯oõßÀ¸ê•Wp^~Øý}¯+ ?Ñ>½yòrúßx;u:ƒ¯Mr¿XšïTFZe«~Z'—gÕFZE³‰Ò#ü“y]¼÷®ù&s‡XPæ ó=YÆ&bÒ•*³e•1üZIöd“HS*ó–õ6jöqÙŽ³‡iâ¾ÒæÐ,f˜rY¾t§‡6Ó¶Ú0öû‡‹æÍð$‡6ЂÒág¨Çµà{á†(ÁyòL²^ÿOò&øê†¡`Žù=ø‡ÙW€÷’Ur.v@nUé{hÔvàb”—uÁ~Rï ¦‘[û]_€K¸×ChAúNÐuÝ®¸ÄïÁj¡mée~L´éòa™V%ñ0gK£näP:‚óFÉG òNè~02’Á:¨tíÛ¸GÁŒˆa¸ì{ ì=JŽïüœFPpï­«àx9÷”u〴1¹Sb ‰¤¥•%[žKi Þ ½cLõ¬^´(µ,§õÒ:ç,`^êëÞ{ &7(˜†#i£èå¾toƒ m>ƒR‡’Î@òé”™;'öe°v¾êej X5ºø÷]ñ-ꈋðãÿðîÿ)Xìá·hJ«¢̃Y÷F.Êw.ö3‹ŸÎ¿§t£õÕI¶¶4ºÞE¬ ¾ú™šy/ê›HÈyM¿ÍÍÌҞ͜¼}ÈÕJî¹µ+îYâ¯ô+¹S¼~ev…›äž?W²\¹?¶RÞ¤œtç7^Ä­u;ŸŒµç(WX*Sj=ëŠc4ubûÛ]X±i(±_ò Ä Ô~$ìŠa;6OŒìÈKÎϬ—Ùí¹¡.c—kƒ¬g~nËmB½•Ꮊa'uS>÷Me”­E ›QZ 4+î9á$hóB-pÛª4°¾7Gc'؆?¥väsÐâƒ@ùX”çYsèAït×Õú€«¬c;8W„50cC?‚1G¦‚ÜÁý@¾v(‡lÃAû!ø0,ã DFznƒ>Áè ÞCÚSÉRBè€c¥4/ø´ÏàHÇTŽv–B†žv^Åð%¸¢ç®s}JFð‰)¾dÏ\}sµ’þŽ*ôËþ–çsj‹Éô æEæËÉ×äƒáJ¦Ò8+Ûã1®m¦]¹·6Jµì{CEN-cËKõÉñP¦¤Íÿ.ÎË 5Ëz’6E*bÄg«¸{)¾’Lv­*ŸmTfCuŒ[,-Ý@Ô•‹*]Ò† Íó®ö *¯sŠ8¦v¹þïðWròþ'wT§aà(¶Âô‘_þä á¨nYüÐähKœèÙuMä*]I(è!ˆé¹â nßY#20s¿á¾ðÓ¹‹‰ó÷ïž=ƶœQÖÛrÝíËöWi}«£3]t½ðFòcp¾e)åÎ8¿’ÏæÝ¶ý"—#Ñ*á˜w<ö´i×P’¯äB̰ü§ÀuÙ÷$Í ž‚” ‘Hø(2 âF²âÞTOcÄ]±ÏBÄ|çQPÝ9:sÚ^!æ2Gõ­®µ$iåR¡·â/±<#ó} ¬frEîŧiV™ VP~4¤ˆ1Œ©QÔòâ$ˆâ7*A¼DPމé@.¿ñ…'Îüwô"¾ÖœãÖíY<Ê¢¼sêQƒÆ4F£€4ÒT¥*lØxð ;¸üï#Ÿ|"…é¡›ØD˜›ÜDr”£le+6ù›ü ;¿rÁŽa±’½hòKŽ˹La…¶¼$kƒ›Ø îtNŒG»31¶4Ó ¾/³@[”s“ËÉ ³[ð}Ú{ÞdžO¼îûYj 9ÁuŒN kcvš÷PÅSÆÈ'Ñ5Ù”r®3Ï’f»ÂÛÄÛ–„ãÖæNͦaÝb¶aÓþNÚY$ÛÚ{ ýxÛW 0KLpM*9KɈ|‰ß±7ñBöÉÚ€O¿Ë½¡vs|M¼pÂ/ú˜eA©cÆâ =²IGóE ¹E *Íã”·´'å/Xò¦}6ŽÈ„›Ïa³ÌœDÐÊ^üân…ºA\-Õajî…ê¤üÉ"?±UνXñä6D$<›7#eA¾†žæÌýâ.ú†BÚÁdHkkZÖI8)NœÇïMªÈ« ++¹é9X³Kô[i¯ Ä7¬@2ŠSH’H&‚$aø­ öˆ ÓèC ˆA”úSè)ƒx‡‘t¤ iNÊÿz×_‡,ì c.lÒ5]°øh¯q“e¬Âäs6 Ëyr#‚å9ŸƒÀ\¦räxâTµ‹è ÜKY$@rÈ£p+÷5Î=Bkn~ykïì„ô­ÖNÈL³W€ôòv0oÔqµ…Câ*bÞîœT Û­­‰UhxÛ•¸I~u{IÒ Q57Æu=¨È1 Èþ…rør³¸³ðxŸ³mn\‹Ç=)—þø¸N”,–ñu~$n¿>–²±¬Oø(~dø&uu—qi†¢µ‰”­¬qhuÅjp|WÐ"µô>àŒ ?d‡Æ‚‘¯¼ º_¿šK©j=kÐJ¬ù%?ƒÙ+ã9Ÿç@ ý)°Žù7,{$«8ÖCì|Þ…`]Û00?Õ’ ´Â^%¾¯Þ‚Iöú41>ÒÊP>ÿ)G¿fŸIuW÷EÇONÜê§=‹ÈÿH,-ü ägf¿ ¶=¹=@?qóy¸]íÎhˆì NFÈ4ß÷HqÕ·–ŸÅwr¢yƳ6å¦w¥R±úˆPÌŠ£æ¨µÇk÷Bõn$­¿ Î)jo°Ie$؇hŸƒ’-2³"XRxäÀªb…Ý9 2Nz@^’9hò°¼ˆÅt¦ã•RJ²E]Q?wq¼x ÿtÀœV¬‡ <¬f .Žpx ‘X>›Ð”)¢.ˆ8‘¢4aàU^§-ˆè†ÔW\åp–µ`ްjAðCã*ø÷˜?CäÙ ãòú`GôÏ„ÇQpfªHÌ‘Ž¶…\ýÆÓÐjÉÑvy[{¾ävF|l/’nÍ‹«‚qóô3h7Ê<ÆÌÛ%âÓÛ×J±ÿv›ÒÕXrãõR-äÉë IS>¶~»ëe+Þ3 t¥HP?“ðQð,mG‚Ó©s"tÝV'2ÜŸ$Îg­þîž*ßÑ+{5ÄwM¿wp68ƒÏƒ½·5œúïýÓ z¹€Ô#â=p¸ò]¨æ#JÒÖ0\Ÿ<õsqr›Õ‡{"•ýw¸Ï<åÜÇ›Úm ~mY~”𻑭x”—Í0‡y•FøECeäÕ[nç3ò¡”¡xÅöP.{#küíèñºVkm¥ Y%d{æ>­ Xï:fC¥?ÈéŽÝÀ‡®ý ´×f³»ÁÖÚù ¸×¸zƒ¶ÝuÍ1Ó~ô*®ÌUêPUŸáš@Œšš$ºäÝ{F׌î®ÊŽò%µ‹áúaGìÛöØÐÅàL®†Rü6~¶ôçq~¹¡õ.ùUVsðNÏn ¹er@Vàäõ¾ 1—BÓ 6ÖP!fYd;a×eã4†3Ã1œ­®‡’úµ•=)‰F'ö»¾0¦pªD;¹˜4-hm'6¹ ­Ñ´ªòIt#g@Ò"¥4è-Ä9`&^ Ä!¬ òk´Ü›ò=,_u9 Ÿ}šZoî0ù·r}b—‚uÔTËüDmA0w¥Ëï#jWssî*žÜ2¾Äðe9–¡tt<^Ÿk*ä–tß9M=£Ñ³*ƪ˜=ß‘dô³?#ÞÌLñÌçût껌¿3¾ôFñÆPJÈ´gßr~žùs¨ +¯ûÅ N]Ÿ$ÖÒÄø&e/FòÓUžFis`ẓ̇\w-ÌÏbŠgƒ•bÕt®Ð? ®SGØü%¨­}˜N—„#‹Å±OøvPÆþPÁ2PNÛSù2ö—Šâ`iaî_Ç.J‚4´÷±‚¥<c½þ,¶ô­âeÏÅà34wNñ/bž«u ©]_N‘*J—ð›`\ ¬Àßr¥D:Ftí2  µ\ öúœûGþºÀN÷pÎðç5Ä8 ¢•\ «¨a  = ÀN^kŸÈYC½¬¯ÔÅ Ë*Ï¥ ÁáÊ`ÔRÎCdˆvBϨ] ¸J«þ"ÍmïBàyÇVís¼¾ƒ -\ιÂNO–ÉÆžl ñá]¢›8jTGÎ>÷«!ç+û•ËáÏ‘ò¶ù0ŠuHƒÐAÜ`Ûe¶m¡èÚ£Æy°Ö9&AfY_DZÓ²ŒG( æRqÌl£ = 2‘g!ò Á~/ƒ!ÔGnFµÝÍ •æ;qVkÉIîUýHñ¨¶œïù•ù=—™`BŒ0€r%°É¬Àö™_›)º\Ä=C©Hô@_@Ðá«Â½„ ~å9ìÍÅû´Êsñ £óˆtÍžÈHÎGnò†ŒÉ‘Å‘˜Íì§™GÁ†î~žzèî.ƒ£ #‘Φr%¦½;_ Ù_` Ø4Tíh¿•1 ~SÊ(=€6²2ÐÜr¥iÀùðjk<Îiˆ´Pæb‰ ±ßƒã¡˜‰ÔŠ›_²1ëbØO±2æ¸÷kò\KµµL¥èd˜¿Ü `M™Þn»ú䟕v¤ï|þÌìùZ B¹½~ÛÛ#n8j^ËÄçˆÏž–|=ãdŠ/ssjÎ;·ÓÞ—O¥¿‘ÖÇj”Ù#ö‹Hž¯¦6Ðx9¹oÙ?«ÞÇü^o®VŒø˜ÒLØz„ Ïé4wrJ»?2”OKö3`fOÂNLrØÚ5c­s Ÿ6¯óln:‚|…yW¶Ñüˆ„VZ%HË“©±P™Â¯y#ôB8*hKQ¶R˜jmÛfM5Gëõµzá»EP7d'Aänë” ˜¯…ž³¿ÖÂi‘ ´1ò b橉S×9Œ³àoìÎZpïržüWîÌÏ Om0Ý9_ƒ½¡º"=r@Nÿt´Ç9J=— ¹ÎKA´âPº‰v ª+AY¬| ÊDÛ p¶Šùœ?&½®÷SgChuÖש\®Ø2 @,v³®y|¿¤¿ÂkÔz©S!?”‘ qï§ýÁ S ’£ž«ó÷>‚œKgÒüÃÉ, l¥©¸ºÁ¾˜†i¼†ò®G¿2L)Ë«Þò,äf„wóbvß*ª%^ÉN`lÆ›~%ëâœÜÞÄÆµÌŸƒ÷|þDì’üïÁ³5Üâîww„¸ Îsc ®›§\ÃAÏS´Dû; ½­5%/i(ˆu´1/ˆéÔºó6ÐN¹r²9¬Í™eÀzQÎëDÁ ˆ¼ø"ÃoÎ[®‚óo4í=a&Ú„s{·eЉlÌ ¬»S""e³ŒGŒvâGïjc6\#=$^´¡«1,æ 3ƒuc‰äÀKž†V Ñùs=³Åœ3±Ï1<½AÒ³xnW*9ëÖŠ2_È7'–$^mX~½¨|Õ^ñ½.u*¹x뾘˜;Ë'Ô6WYa8]‹ûw©¹3@(½¿O•˜‘ž1ÌMê`+Gç&³'ÒýZh1Š{Œö8÷ɲ`ÿ&T Ýu·h†éÊaž‹IµË}®r¡ÇŒ{mãlÛyÌðÌòo"Ã~²à4YÁƒ¡‘tµ× $âmC5i¡~ê/ÊXãp憧€í“ð—àÐÃAo8j+ñ8§žñ¼ð‚-Çë#¤žƒøæF)ÐÏf¯ãUZ€-Õ|¬v²3Èøä-Äc?DŽiíÀucÐÿºrãà®V…Àz6(7ÝPPÉó¸ ¡€9Iy#Qz¡úÏéÑý—­jlÞ%fÊÆù?¨ª w›ºÏìì_Ê–ÐMygpü…Y018Ò«ñ È¸è'Ù~_j#ö•jYq¼¯YR „raD™·m?æØ®YœÎyêZ"d_¸9Œú“om£[Æ“·nÈ iŸ¤o©¥Ó—‘œªfO¢KRϼâ§äÉ¡7µrqëlðƒú:Gíüfâ!×|o'&éÏø¦³ÚfLjÄβ³)uhÁ…R§´ÎÄSÆàM˜¨v#ÆÝP½ âè—Ð\»µ`,3ç@L_ÛHŒ8†C¤„uî´ö]D·:Ѥä4y¤ô÷Pæf̦¿%úÛÑ[^b°)9á\ó1üJ„§Í¹ädÖÚÉ6w0–ëyû"™\É«eö 3ó‚ÙV>—Û„.̽µ]Î_Þ,«ãŬÎÙâ¡PIw0sì0æªo“”?Ãv’_sªº\œÎ¸æN`ñíê)?ZnML«.îºös¹¢ÕÅß*®€óÇJ§÷\ˆOxßWÍ;ÉsÐÞ.u¸ãXë,ȯÁøÒkU ¥ýà%ù‰üöà\’ÝY+’àm ž9#ÀžXJÈ»¬½[À¢KÂ;!òjx5i‘îÁÜÑŸ¶ŽÈMJ—ø>‘a˜C•¸éñ†§RʵØèbUhÄ•ßBR/Ñ J_ÕÒÁeSšAÙ¾ÎKàì¨šà™¥ °m!y¥ó<ˆÌvÖmÐÊ*%èó;å?-ü›UtÃ|_îu˜Ø ²!'á†(h z/õ¸õ•?|k­Šp«i8²·ZBF ó.¸ó"ƒÀ×RkŽÍìBÆ{¶z”ös|Ê›¾“¶jV c±˜:Ó€7 >TmDòÖé3Q²N¹çBöáÄ…wس2;Å?™jê§D Û^E÷›‰ùÙ1q0ö‹K<ï³îtÍkñì-72Ý’ëËŽÈøRÔ-‘Õ—N¥ÊeoáÞ”ÍsIM‡ ¨œ˜c”§jüãª"·º.ØŸõÆrÓ½ÓçæeÇù@Æ”½hùä³)³eê&LS~ Jçé­)ëzOÌ jêÿCÚŸFÿT¾ýÿøãÜÓk~½Þó„·y.™"!BRIQ ¡$Š$ J%‰ )E¥‘TŠ™"™2fžyÏãköô»q]×wýÖú®ký?ýþÏ{í;ûÎÞ}Çyë8Ÿ[7åøT âIßíÈÁã¬+}‡ÃÃ~„½ËîZ‘”šv‹ûžeÿû_z•Uq'ÏþeEúã´AQ‰ËÜ#yYš:„B³ƒÖ‚äߎG¸3¹Ú}„Ìè6Ïd c‹}›nøQDƒ…é1j¿ÏØÊÕ{Œ½¡ç½Óc£jj>N}¡þ¼Ç:!7•Žð5ù¾gPø1ÝÍJó¨óF}E¢úRSßûc²'Wäf‘Ø"7qÂ÷dò~|;î…5»À±¨v*†t±f KÂÍY"N¥Æñ‘ôTèGN+?W-2§+-÷D 8å=ö±Ðó|l¯ºoWcl·Ú¢4(? -}¾õÐl~À ƒéë@ J> š8Áÿ”Óìÿv5ƒÿ9oû.llÎRB ÿupÌ ÜÀy;h©åw~'dO³§ñ7ÝéN}û°}ØnHWºÒBœ'Å'XX\ÿogà¿§j¨Áb=ë©&N722²È¢Ùd ‘ >£M¾xNäC4{±ýn^ã È0ˆN¢šX)h/4 Anžÿsý©xfB†¿ Ãó1›)¬C•ö¤Ÿéè‹lûWR÷»·q´r‰Ò’–ew¦©heDzÿÄ*‹ç"Yötn/\eÝÝ?0¹¢£s)U•‡½aî NM»ÀÙH^f#Q› ¸wÆÞãi"U—Ébg…ÅhzÄ¥Xö„ü9H™=Üí1äíÒ£ÿ[¥ÿo,¥3UÁXžÏ«ËÐò%fr‹ÖSï…¥ùŒnHަ ÈãÍA Ÿú¤þ5HOJkA{(9Äùä9àu3¨…âH’£Á>k} ¼Î+@G¾;[¤ƒ}Ý¿”c±¹¬k?ú[Îö@5uÁ½_mæ0ùKpî”?‡Ôhçbp-—_G$>s@YâØMNüUEvúå$V8×U ö=‰ØöYwKDú•´`•¦nÅŠæÅN#BÝ<#¼]bÃ!>¹VÊÃrãDøn×åi÷±x€ŽXâ0¦#ËXé x…ÎâwžâÆÿ3­n¯®žÇJÎBêýyðÞ’ ÎN‰G±®T ¶óýa„ÖÝèKÒ±0¶§v§9˜gµÍ©£\”Ïë‚•GíÑ곑(ûäAÚbd¹ªz)GŵXÂn!Öï!Š)/¦­´4m¢xjy ýín5ÅàxkûoÊ¥G¸hý^£-cšùŠuŠ*ë%õèj)¿˜iJ/ê.ígôÊ0ÉZ5†¦oWg#%>’Ÿ¸ðîw®ö+Ĩ>ˆìðŒ‚ØÏ“H¬v¿ևɣ´·Ã‰$v*`üFB«²oÄéºh«´ þ"¼òÉøa÷GæÑ@×Ñô²Ž9¹¾­~Ni/=g9™@o¹‰˜fÿ(?ÍáQÚ‹:D´˜ünÇÛÊßH‰.µŸ@¬Æú ”Ç¢÷¿'gbI½Â Ü|Ëú:Ô7Œ4f‹ =áìMŽ4Rþ’^¤¥¬§®rE\Hn戲ϸ‡0;R»¥hk:D­¼Üš%TÆf!q¼ÜF_¾a»ô€=Þ´¥bQb}§üE­è­îâ&s‘v„VFgíu:Ø•rZÚëÔ7õ§¤ˆL¾áZ]æ~‡´pkÿ[ ítLF¯MsíÅžÉü’TuUö×DªßÊQíó•£só+·äÛ¢a™¿` ïß·•™¥÷¤e%«ê¼£¤^|;ó.°€§‹ûI!Û7d½Dß䬣5ßy %--q„‰þ‘•”ø2¸ï¼º=údçR×™H'Îh«¢Ëé‘ý¿·8Ú-NOänœ*‰àÉÁR—º|tòi<b“+ÿ‚ÿ¶€Õ˜¤öU_`» buðyµå—3|\“ãsè蜜 ·!9Œ§Ò†ƒèIT¿ ºá|ô9jgpܬnç[Ž·ÀÝÙù-$Ë´q{Êó $g%ÿí^} Bk–ú¬æ$n¶š— 9ØüÌ:¼´“—Š—–îϯǾcŠö¤ý Bz:Ò‰{S.°ò6H·~†ØO©`ÆïzÚÛ¢ûþ`~fß aoÄÇÛÆðT«QP$N€üœ9 ·Ò—h Úíw ¹| °¥éÀre€84àmëy`£«ÙAsãYšñD¢’ ±A½d'lˆ˜Ø‘@ÇñÉð‡ü†£z3èT9Ô†oC_0ÛJ+6R^ô³)õfa ;çkè•Ö„ÞˆÀ frÊ3Š2»¹w,9Ârqœ q£87s7hCEcÐ^ĉP7Ò¤K¨dñ‰=€,náN°Þ0{± Ìgy[È…fj†ú¹\¹ i÷¦ŠšþœÖÒÂîã,ó’|€sþ ú ú[Ž^Æ_ö·$¬ºÚrV”ýëx‰þ–ññùþ”œÙšÚEYÕmþid„†6œIƒÐôO ÖîÎúŠªº™[¹±êíœ;)ª˜™÷'uÊÚfo4âÓ‡Ç"®Æ6ùñ=÷+׿浿qß§5Ó{K‘dËÔ2ðôNþÀŽRsÙk=¨ÿM@»h$؉¥Ï}¾u9p‹ù5¶UbíF„gÛópHßQ‹Ãó1ƒâÜŒç"Ä‹P}ƒš®§ä3Hzku5¤œê £Ü܃ÉnI^ì ¨¤4VOMÊw$·TÆH°-ó~°¶3 õ¾‘„äz~‡ä>i èïHQˆ>–˜ Á‡¸"å©oŒí`;Ã9 |Ê0[‡>õÑ ’_ëMÁ÷­g ¶”’jÊ>Ï"P{.'éø¤¤Ñܺ>h]äZlW­ÈCÄØæÒÐó Ìrô¥)@ OwG3ÖUf·{¥;&THÓsßk±UôéF"íÍü,HîO~‡°²<û yʨ…œ[úAŠ|W½«"Qü;cB?…ïç«’ºU÷‹¹ùßXM¼»ëNI¼íZy¸$7m™÷Ãðs?Š_B¯Tæq*\X±"uªogvdLõ†Fî¨uÒ4 ¾Ì¥ÈÚ`W²}ÇûñEkó¡öT™Õ³øÒ{(î1'’óåÄcHŽɽÇK©ÛZ‘¾äO5 Z_‚4œŸ€œˆ°íkR}ls»²˰´½úlGvêšëÉd¶<+Úñ7ËTWâ?'¿:‘ü‡ê)OŸÉ㹪G­f¤YYÎ z»¿×-Ûs’‘¼ëÍCüäimã€ç¸®Ê\ûß¶ªŽà7ÙÃå‚Êeùm¸X¾¢ÎƒL)é^8“èõGê÷dþµ~õ‹hweeÅmE÷æ?o^úiZëÚ ÁÆÊð«7ë9pv‡1ì¸ú ?s<üº6“rÏiÇtºåžñäqŸrr6ÔìÁR¶hW¸Q$‡Òä7I‚ö¸Ô C›d¥Që¸OVÉp´Š˜µ+ڈثèÖ­Ñw™«tŽý r›Øz ÷ÆX½ŒÝI Ü…ñ^Xâd‡äì_VÃDÐ6µ¬ìd0ÖBp<™Øfµù4h÷$‚±Íªå>~¥<ãO{HOÚÀ¶<òt©'Њ]`¯MÍøe°:xæ‚|.z"£\õ@›š ‘ßµHsß©cv3ˆJv†XSùgÌX#Ñ%2_ÝÌéX'ǃ´ŽT¹“ŠôñµrXvm=ûT|šf}Ëùжœ%¯2›» ‚m÷“yÂ{– Ñ•éù”–©>ãx1ó›šê:‰¼+坿LÈ-/u4ž”öýÙ~e7iïÖK½Ì]ß^bSÝ7‹óø8o~i†=$¿}ÅV19{UÙKdfM._ìÍZ[ÑÝÓ>k`¥âÜí¿nüãá px¢"s:²ˆ‰ø#N(º…S„‚÷ñ±|*þ!§”O=IHþÔwÜ.«†Û¾Mœ7ïpŸÙœ7¥—­RÊ”™b–m"SÆ[är±Þ”åiø?rû2î}ßÿØ5þG2^·]Œzcï<|­<Áßâ„ö9nó¼fz¾ºŒÆö3Ž#Ün͸WÿÖ5…¥ú#ž'Ä[©‹ž‡ð™ûRGD¾äl"/x„F•¿Öܪv4ȳÂoC  ¶ˆIÑú ½-½àFðž !é³ãpv…–ÐÛóSèQ†x~‰ÞËOÞüdÐø@kJ«x™øíÒÊè)4G~âS"ÒªxŒã—ÁQ˜: bEò (-R€!'ƒïEÜÞ ‚{9ŸzÆþ ´€}Ä›%Î@z_G?P¶Ð¢?'/Bð||>ðCAl¤^1‚Ü÷|·ƒs¾# â 5ÒzÛCé‚ÔPkà ’§€u@Kñ¨£ ļÊq0G9÷@¬¾#„©;Ý—P•í¾"±“bû;¥¥Ü×ÛQþDé&÷£ŠE™ ðÚ×ó¹Lšò9ãG°^•Fi²f¨§Ð’.í07E{÷12µ$&«kbm[y—_ ~IÕÙþEg¤¿êÜyÍf{ÝV×$¾©3ªX²oË_[Tæ§NîÌòoÙšýPÅL%3s}õ½žOÒŽD–9R¾ç ñ#ƒÂè yšLô!Ê•7˜ël¤U‰çY­mOd‡4<¤Ricn¡J2o ±Í !ó†y+zãÌŒŸi¼ùBß#ü¬  ä?ç?ÿ—ok›9+wêËx7âò=v»³èFCëN-iyõ^jºu&•©Vš¦¾V ¥òR¿ª=“åzJÍ6ªå½‘‡,—ôuus Wõ¤xð Ü|šÃ,Ц#x ílÈèOK*™ÄýhÎgh#]v·J]•#JߊfÒd>Ͳ©+±žåºOÄG£G^¨îˆª^ ®×ÁóÀÕšo‘¥Õ‡@›YÂ-Žã±t&»›Ö\³Ÿr ´¿ˆ§K“áÕ|l¼ŸåÌ«^°ùè‰p:ìû ”FÑ™à~3¹ Ä¥Ø2ÈùHé …C¼PPìý;·Ð{‘ñªg7Wóf¾O7W©¶›"Ïýn'‡\×\¶½ÉñŽãu>p r âœËïò‹â’¸Ä9i¤4’J.s™Ýé.Üÿýê[Óúÿ§[UOzþŸûÿw©ô(G1ô9ú~Ò7èx<µ*õí ‰ÜËÆäWÉÕˆuITrlRòGúÕ¬ÿůת+»,êüGéÜØ«puF¬/\žOBd®VzÜÿ5«o€Q?-]OK¿€YÜKs¹½ë-¦š÷±ܳaÎs߯PgèšÇ‚ämþ•è‰üaÔX~à=þ &2îdDЛՃyU§³kØQÖ/笘ï]»(>*oa/wž¯ØIËhÿ;GÓö• ¶îJ{Mʶbž1Y·\›ÕGS]´=Z'}©ª©ÓRÒ:m¢ÞLž©õÖˆWt¯»…2üéÙÀOþ…²Ô'ÍI\μG—ùS š'ðËO&žà ÜذìÍÊíºÊPùªôнˆçCßXmhm®²J'µÅvBÜ$:RËýU³¥ÙÔQá+œæ*Û¦2:’×xQ[!µ³;·ÚÕöbñ¶¹¾ê±ÓîªýÆÆV³Ë¼'PWrj‹£40ž­B\/º<Þ«øª«ßJN“3¤²è8>tÜ(¿Â"Ç À9e€uqw•9—Þ1<’·†¾c\¤%‚&Õm©”ûÔNáÅU»€Ïä ý¯ÔÞ±_£û™Šê¯ûûÁAŒÔ¡Æ˜Þ¢ =ÛwA£éêgPçe74:øŽ쇬u¾*lÿ"×E¤ô;|m9éÉpwãAwW+.Ër !BBƇ¶´ÅÂÂæ g$I¢“I&ë¬ÖFfp’“\%Ÿ|,ÒHºÒ•Lá>l,,ôÿkª@F 00ðØsí¹ö_v»‹#.‰K¢¯#ƈ|îå^ Äp1œgXÌbÚ]èØ,f1‚Å,°IbàÀÁ$Æð\btâªýLí¥ð\q±&¹ÀíáOãa–œû‘/.®ýÎŒ†óãíàü)»;D»wBüÀ“ÔĺdΣžÑ%{# ðj?¬Ög`,ZoŸ…«òÓ1Ã3_Á ¿•Ó#´'w-®àšüõŒ©i{¯ýVÕïù×Ä{åCó÷1¤$‘îÓߨ’Õâªc1Wor¶¦{ä÷Ÿô°§e<ÚlÛÕÑw™¨V™ˆâV •“‘ÿ7æÿû@°íè§»gy.>iÂöÄõ…Ç6£18Ƨ¦ƒÖI¿”G¬wA©›R3 A Zé ¿£ÖPN€¼Ú|Acã/ ¶·`“’¢š*GÀ.ÏýWW¸t°Æ¥ž†Ä:÷$@1S0¼¯]$Û˜!* ¾ÊÝô­j3ˆÍs·‡ä ev8Û;‘8åþâO»ÚCmÜ}ª_óo†xJ> Õ Ê% v=™ÿ|±„]ç«Ò<”|­ìyÈ»¡ä,ä쨘ˆûkÅψlµj¬})ç>ýÍÐz5nO­ÚE†=¯²3Õ(UÏaá¨þ‰hÍq ƒÛ°åá‘oæÔà› wŒÇ݉à>nìiiühßé•à¼j9A9d<€­¬0§cz¦©]‰ÙSô†L’|\2ß47Ú˜óE~ÀŒJ/IÓìîvší·òÈ"Ëv‡@9ÃYÊE™¨ìöŸò/Õ-«»J‡¢]£%ò›JT!×w0BôÕ/K2óyr꼑\ª­Ôxõ}Hæk:¤®hí°ã¾Í»`-ØóªŒÑˆŒQ(ØYE8P³ßæOô‚‰tàÅì‹V‹¬+êéÊ æ°£4^÷ƒ¯ßZ óMQ°ð6º6¦ÞN_]ØàQ¸ôi£ÃvøüÊœÌøžD/Çu£Žïñ¦«£wbêU¥$°9Z-J|©ØZ§‹"åx*’ÆÇ Ø$êxˆ/Âï¹39Û}.™@xN˜¿vÈ]Ø#×JëÒ÷ÿùúoßö;ß®„¿>?sÂ?Õ¼êc xŽwƒóÎÈnpnJÅv~ŸìŽÐöJ317¤6!kŒWÕµ±zö%ùQ±ÊúLjŒa$h5·öŠ…ò"ë/ŽZŸ›Ø(>¦>=ŒŸÌX5¯Ù!Y!¢öˆøœÏJ êI°7É•üN‰¶Ûû¢R,¥ÈÚ¬Zñ¬±Ó÷#ô¯QÑSnókädFš†” ªAòo?H´–2 zÖ)Aô3ß.ˆÓ>Ðvw=ý៱é®ve¯ô"±ÀÛÊîôÝUIÎGªÒkhRÞ+]±~¾(ŽÔfEß„xz¼›58Ð@œˆôóz¼oW.dCÖÄÒôÉ;RÙ‘Ò¬*sd.¬Ùˆ’q¨f®ôHm>JzeðcxB‹?BëÁ÷dôWlï¾È„ûÅXŒëÞžÑãÔu5ŒÏ´SÎ@²œn˘cS|\1Ÿ—6 ƒÈÀ2ÞÀs?ìÿÔ>ýßÿ nÃy>Nù-â$änö: äLŸò›¼Hoîl$r“G\?ˆ‰ž¡lŒLñíexäÎÀ9Z…¿OÿéÁ¿Ò¾£¦¶0}ñêÉê­9_@ÅãÙó),kYð rñ?uCÉÕŒfÆÕʵîüÊk±Ùò÷WöXË _zMìäP´~«hË:ºâˆ®îa ÝgŸijY[¬–€ügÎPµ·—é´à V³a~÷€ d€ý´û50Œ|úW 08 ¿!²!Ù_zK}Ó Uªö€øGjˆj³ ’ë<áCÞ{ ºÕÝ‚¤-„Ä÷ýX•ï§UA´Èo"Uçûo§ üÛŒ·).žäëcür‰EU·Ø½Ñ+ËígQ+ÆÛË¡âî‡b'ßA¹¢´×ðÂö>¥°=8•6ᤠòëb Hõ. }me”|H/™[A¨f3ZÐÄGì±BÚæÁè4lõkWg0*R=ñÆecZ³ˆ`›Ú`>i̓øC‰¡«³£râ„îóˆk)¶ÕЕÑËæˆŽ·"¯(/ƒÜ!ãEìªçãs0­îîU„­µžQ|[½æ‹ê8_ý³ÔÃÆcJñákß1¾tÙ5CõŠÍ)¯:ϸ[wJ—¼ó9žþHà®Áâ²û6 »#\SwºúªTÅ  våx¨Û±] o¨—T¤- 4%z"k¸ãMì¬FÊ%DNÀ?ˆdÖL×$}f#|é#äz\\Õ=æL×ãÎsµyU¤i:é/¿é{‡´¢mþ-ýz "Ö톥ˆ› ¨kÚóصoeB¯~$³7ZåþìÜQ~kæcNÍFï?‘ï#ojÝ«‡X7Š®É|ù:#´ ò„çŒz™„¬Góbk·Hcï¼ À·Ê×ä™É&à›í[ ò }–£ZÜ‹®~§¤S¤¾gî WÞn®ÂV||„"/”–z$[áÒjÒ‡‚ØaösaõdlÑQÙƒ%&PŒ ).°ß·oAX‹Å'åhŽÓ˜›X„œJ…kˆ‹¾fH排2~)1OK ô•æ[HzTÚŒlúµË1-òjÒNõaiB¿VÅïŽg*§².­s­›S{¢­å~eoLý’~›òap¼£G`RÍ­âÕLª~ ™Ù³z5jú˵£Òß«ÝiýCëÀ÷P¤|‡"½Hy¿Íå”kpüj\+'1œƒ“+ÑwéõIiýÖ¨²e6Ç–½V_,ñ±Ä뢔ý­Ü‡yF¹aNR“£W:´J^p¾Ž/ù¬»3´fPë|ü¸óþö¯A«ÿsò‹›K°ÛŒ.¿ Qõ’\I ­kj¹vÙñ¼~³GW¿ ówQFާÅÄáÚÛ3®þ5û(Þ²õ¹:¢T/0¡dC¡ÍÑk³ ûsÓÕF¹ë¬e»3®ÿ¬úÃ3µlmTRo»~ÒXÀ¬s}XCêÔsx8{ò[ÒW?à !·÷í£eDò7«/ ¤‡Í[ ë%.bû;™ÏCæ ê~D ‰½Òþ0ÇAZ™ò¤_‘›€ï%ã2É@©ö 'ýgì¶´óËFQj’v·ëð[üv$â!ÇY©¦®wBüì´ÑŸÀy2>჻}ü8[ÇÓÁÑ(¹s’‡Ái%5?ÙT%ÕÔZ+ ”Ó‰W@j¨¥ÀÝ4±¬drØéÖ[À>†ÞCÀÊRvn%ÖWÒ_š®‚ñ‹¶ R½µaò8¾„øçïxÒ• ñ bûÝ…iã@8ÚÎ׊F¡‹«T„Õtj¤=f¿^ý›³*ö{Ê-â•[³ ¤;æ§Tiƒ)ì°ZæDW¼óqØŠzŠØG©þ§õ ú#‡ÆÉ¹ám¸%Gª!eÂ]ñ¹ÞÁÁqÖãNåzßÄã¹Ic^¤NVZ²òmc~Ùõ›¡Ž¯x"ÔY<”Cù_Wl±k²•÷ä~Pù?d~R32×NæJúð,Kó,ˆÝmÞéþ)ñIjƒsWjbê&õ^f'o•òð$Þ¤áÔÇHÊD}#€™`õ°3¤=Ê>`•2xXµàËÏëVÁ££¼+ÿÍÊo¼ÌïvÇõNôÛ×;ñ‚Ý ”év¨ßšSA Y]å5šª—k{Õ½z­©â×½Ë ¢]niWpNVCñSÍM9ciUÙ=_‡RQg:m¬;®¿•_ ÅÙ¹o驲ÙYDU­ñ[sohúÊÕYì*ýÌþŒiin€ÜmRo~É­ƒÇ®È-vrQs+Vq àHM7×ñWœÂJ?Y#!å´ Æ!G¯Z þóµCÆÄÚUqct¤OŽ6ÅNk\ó>ºot'o„®°Ûÿ…1ÇÜãØ-ºGL.Ñ3ò Gl-™ÊÇq?u’éÑm¨š#Ñ Œçb§Ó©0X§ã/ƒÚßxâ}#ÇÁÛGü‰#q Œ×RË@¼aÞŽ‘t…à]Ñ)`>¯¯µ¯ô>øÞqZ åŠVP39– ÉfF´©ZPþц€ÙO¼â õgˆ÷æ¨M@ŒÒ–ƒµÚá{£c7£ý€e®>`=讃-¿ìõc5ž,dk€oãü+@iåØÎl5ø³©­’9†‚ª9“qTË|«òPf ¢üþÜoHU¼–ûŽ²Ê¼Õ¤—vÎM§^ÙÁ:9VôZv–±©\räVíÒ›Cù!°›H7I»“[³zk›jw¥ÍM»¹*àØž™VÖro*é ys‹§ð}A“²Iü{Kù³¼™“U¹²ºÕ̃ô/ª§âK~Öêàý:¶Îlçú"þ†¾Û¡êÉä›*öÓ©|9 ôÒÐLjÁ¼.Ü`à f?Í^t#N4l0™¥êüòï2 ò¿vÝ ;/÷Ÿ zëØã Æ£u#§A u?@¼ˆþA£ÅŽ[±«?²¶"›É£Üâ½w¼MêsLí`ÊÉ9²„SÙ{ù…N¹U\¡QN}J©—û µ¤g„Ÿš¼Tšw¤Ç¥¦US”ÏÓç”}Á¾¼ve6ó¾­¨BÎVËö@NIù$È™]þvŽU3‘s¢rä¬//ç׬åUCè—©ùÒøÐÈ9¥V“/øåÚ¡47ÆÔ‰Ç¬òô±éc•ÉZ…V!~¶^³^³‹¦¢)NÚÒVœ0[›­¹Võ]Õwú*s¯¹WÊ“ÆJcåÁѵѵ¼!ˆòá éW3ÃÌP¾­i]ÓV9k0{8vWçTjç’!³H™UÝ2Q†k-i´‘Þ÷? ©ίÉ'\CÁ¸â+[õµ;âïx3€žµ•ɬVhRFvˆ&ÖŒìSLrb²K[ªOÊš.~+¿7/ ¥ZþH(í’ÿ%vɽùiˆ’suÚñ[Ñ÷yìn%%õãÚ­uNâ/z3ãj*»ækíÍŠÖz˜¦ÅÓ’Šß#’’bÂü^|˜}d”½Aœvу,u6RÚÛ¾áÞOÜ#ÕT‚z,æ.™΢¼ÿ&õ·–iÊ4ëÉW~²šJ“kÃfs1ÓyÞì&Žë«Ì“t'°¬æH’Ÿ?À§é1ÆjFÌ®‘¯ìŸ!ÕHš Š,Éà8 Ý îÅÌ…à¯â¤}ñ¤:Š4E)Zç¦?W°€ÍEÿÔ»ÂëWËêÝÌý׫²Ö§U–¸äòF‰›1ª·úÐ%5!§ H¼-™àëì®oí)p °îe·cqòk9Ûådx>ø9‡jîÈiò¿ ÿµ`Ÿ»úç‡`àà(»&àɵ¹±Ô¶Fœ7é‹@¹’ê ê}ÖP ¢*ˆYê3  ®ƒ2 l˜Sµ¥ }¸ò~ËbšôØGÖõT¤ ˜Sý°ÓÓ¦âAj¢| Ì›”®¦¸A ùŽ¿!u·»’yò!ˆ}è7!µ_^ Á‘n¢ç½‹ þ‘ë1¨½Û;Â#ü[Hÿñ¾€£Jd´b`x›ã'”^ªiÇSžYWN«¿ª¸#î:vÑCÖ‰_æû‚ºÅuéOYŠŒ¼]¥‚꼂Šö“ÙEÆôൊu<Ì”Š×9N‡j‹üQóW˜[u˜JmOTŒ¡Å¡ûBíÂïDöÄoˆ¥HBl/Hn¥-$û0 hÂˀLjQ}%€¹ÀÚ`W 4q €ÜP•w]¹ ùAþ‚çÁõ9߀k?›ÀKçoa匳ªü7x‡…7åïåŽâêzµô»¶³p Û¯¾Ô \~·á;œ¹¸¶‘Æ‹Ÿ7hh^¾r,ûRxnh–òiäcg{tígEÇÞ(ãÃÄMêKÞ=‘<‚îÅ‘Y¼—¾#ôqÇÝÑÅhéÃã‘rüð\ŽUa{ÂQáó‚c·öd } Üó”t $7ÿ±¬¿ÀþjÉ8øèѵì*OÃòM¿ƒätÖÞËoŽO¥o˜ã©Hyyß‘žúƒþŽñjÿÄÃ'-TÓR‹Á±Û|žÅñá©/Èòübä¡°®Æ´V=‘5Ü"›f`?f}”ðXíÐA¤‹º =-5…X6¹P=Q<‰~Xm€HŽQйbŸVÎ2Ã#ÆÁ)JŒårc%hžt eEr¨Úšm‰eÚ 6Ç]Ú6’ÑéîJ±i¾÷!Ó^†`Äo@$Ë›€ÚÎ(TOµ^ß(û"Õ·¦oÅ®®“õ¢r^V)T¾–qÄ|¬¦­¸Xy‰ÊÒ½Ì`qt NÞH¿™„ýmnp¬gà9—Qý¢Ü'³uEsnÉZ^µ›ÆY_VmBd«[“ÊÜSÓGÚìÚ<šv)tíüÛÃa¦øü‘U„½÷DÃãYkˆäž\;“Oë³Ä~P?Ô¿Íi4åF£¶RlerU*¢%¦HàÇÉNq²å“#äZŸË=ÀxYíÆZSH4w5D™s?$^p?Ñ·}ç õ?¡ºþ[!ônúl¨y/㨾+s+F哹P*Yy¬¼IžÛ>\:8s}üݪ€ç©ê?cÄ’b™·áÚQq3ѲCžnx¬‘ùE˜ù#;ì¢Ø[álŒêüÉÞJžão.³R^”Üà i{ù¶ª7_=Ào>µf}³Æè•æ$ïŽîA]då[µQŽeœýÌR_ë°M8»Ip>zd;vÚƒ±-ˆ´Dx0¸sÂ*xgl:ËŸ<·ö€ý/ƒ'ñ1ˆ3]ü Ï çBNUÔÀNoúá}5^ Êäaüi®£áJÐbÉãàMƾçæÔÃàš’Z Îé±As&VƒæMÀq>R”[äh½€Ü$t¤£u†rLÿ¤¥¥ÓÀîISlQE‚ \Ä%;ØL7»\ïC‘õQb!ºy§»3ªóo0ž4&@²¾£'è½´}Ü¥ž„äXíÄZi!2Õëƒø¯žW!¶Ç†Ð,Ï*¨Ýè áBÏN¨¬ Ƭz>ÝF®šy3UC2NPY=-ë¦V¼ïz%úN²— œ˜åg‘˺ÑJÖpB@wȾ¥}¸×¹ÊAZŸRÁÑCu¸bœ騑LJîGA‘Õ&ØFYh%H½íæ µ•*í…`oÁ ¸E.Øk±Àb_{¿ºÔÁ鹈谲 ¦{ç·8¾€Äß©ó òœ_AÜ;ƒ­,„ý»z/Äò“Y`<¦N£Tž±gGIÒÕQ€#ÞÚÐ?5B|ÃÝ©;Ä±6ñˆþ ô­­0ÚÑKÿÇègŸL̲5ñg"§úª…òo‘O"I÷ b !Ç_ÒJ‡4Ó9èúRŠ#MwèHÎ5¶€‚GrMÐZÚ«ÀQGdƒs’}´Wø‰c`ßô±ùJ?Ð>ª¨Åö~R=;í³X‰ì”»=3Ÿä=»0ýgoz,®:Óª< ÉþÙ¿U˜¾„ü‡Ã4üÿ2Lšz„cÎ2ÿÚÙ4žË dzd¬oD|Xø²z9¸ÀìÎÎòÕÔ§GE-1f&àâ¼·†«|™Þ A¹ßÄ&Ëw¸îÝB…ž”šeޥɉ”hžDpMŒ?Fg×Û©|­]Kî£\ýÚp :Z­qz[§2P…Ö÷ÈjТHŸÙ§(å[ï¥SÔ·ž•î¥Ò:&Os‹úMŒÖj!uõ©?"qÑ"™üÑñŽd±ë+râ}yV§DSñkì}4hdq*t‚‡‘B=è5=Õc±¡r1¨v°jJ”ÔÖWwAZIÓeP¯°a?l×7àj.U"ì‚*xçt,Õ«GA9®W’rœVOrDõ§§]QNïÜêœ@„uÕS¹ÝÙÌ}ÇäoÍ| G*B±—/íRvEÑ­@$´ äÇ0ƒ}V< Ô#G1Ø71ÌŸR AœNËZ{[Bbtél°SÞ ÄÍÎt`¨¶~dƒõªçâ©{ï‘HKýID¸2§SŸÙ@ãç·j)/EŠ_NÜB¬rÐßMJQI'\Yk­MœÉ>—J£yfë'³WÚ)±*–r¿ážj#¿ä{'T®î u‘úë†Ãxý…Ñeà½ý\Gãï‚gL| 8ë%w€£®Þ ”æPÞ63AžmíéñØ1ù+0WÉ€y:ôÆÎRHüê¬ø6×BŒ¸Ç=%zÌ»ÕÞTéhÛ“©¯ø³ë‹“ýûÏɯ°ðéCÇ\eÿ±µÑbZÖ*^ØÁÖˆÐÈôºP½5sT}½*ÿÈ}‚³eÇëÜD³ëóúYUeZFàM®S•3bså®E§L·xãr€ûhra"Rç¦å³³3¡+çK³«ñ’§ò¤wR`º² r$´›[Ô¢è)¬ÀQ{RÆ>îÇ|ˆôL€ô¸!s/­ ð!ýK€´<@ÚítƒÀo,'x‡ˆ&àáªÿ4«Ì§Ý_É3"sÅHïïáQ4÷ŠÜÍ Ï‘Y ÷½{ÃÓ:ºÙå‹ÝpωÍטäûàš–¨Ç¸Äàì—ú ´õ×A=¯ŸmžÊaóUëP^5.ƒjOá`%ˆ×í]`ï”^{‚´,¡´SS¶ÑB}ô4õHp4†TwÇHìv?ñB÷ÍûÉÝ ¢|S òƒ÷mŒð¸´ùÔ­)I¯¢´æ¨‘µ¦¶ÈÕ;ñ¤™-¬øÙAë`£WñŠu"[/Ê]øÒúS]Ï6ë8É «±ù );%o@³R–þL¼!˜šr”±YÙ†f°ûSGŸc?É ã.3BããÔH¬Ô7µOSb[×¼t’>=ß|.o”ýfbdÞ›-Té›–Ö»¼PreßYº–dþ]eÙ8r›Tô‚ìïªëC†¯z dhÁ–Øi†Æ"üßGʉzÛÆÊøÓÝ5ñ?¸æ$ñ‹ã’^foV›­Ù¤Èf/ΉƒöLi«x?)iÌžÊÏ46ûª£DŸÔ©'#‹Þý”Kußî?”ÿ™Ëæz;¹?—ÇŽ¶„ŠJ÷C`|  „ä ÷\ˆ ÷Ž‚ÈßÖjïÊZe_†ŠïsŽ@ù®¬ÙPÙ íµÔŸµc}#B™‘MΟ*.ÄUmQ©ª{ÄçÅGí péc€K¯[žió€¡užçQ² þä$= :p_® óæó»1;ý)ù`ùËÒììPegzäì.û‰PîøªÝ$³s+?Æ‘ýCåûýI•€Œ—*ÌMµi±¡¶¤‹XŠòt³¶Šœô‚øû˜ocü½X¦ÒÏ™ÞÉ9IŠ Çü*ü.ÉR,6¤¯bÍAmÐÁâC@ÊLvz$O‚Ô/5 "{ÂY˜$ùakD·D»€7|འ> ¶r!•­·€`«Ø0°*ìɶн Ü{\û!Ü&5 jú¦®‚w¼ûkˆïàXå*ý>åH]UšùŽã1Pžðþ…Üé,Bs ÖßT¿úfÿçÔØÓzâⓌ¾8Õ6®ü””þ’¸±z@vG¾­ê’µ£bnÎve·ç:¡Ü“ë‚Ò7óß$^’(XÊõ’¢zëiz­oÁ(î˜ù-¸\^^ò¶ÕœÔÅç€áeàÛ {¬£uû¿6þ G=K|˜¼)ïcׇñ·Ó ׆p_÷þ‹Ug™—‘[~²×” ¹Û«ÎBæáÚîþbít‰,ÿ ‘5à¹!±œ%ÉÇÁ±-õ%h/O€ò1ïxXï öß-%ð|¾ü^Ü$ä".‹¦ÿ"õI½¼ç*óç¬yb(Ó]B?P=®Ë÷Á^Aƒ'ä«<†ißÍçÈæuš}гDì;€«s¹ã©Ö}öœe³ÊÏc±YÔ©Ÿ³Kh`ßC+dÿÛø¡àUR¿Žä}‹…]gÈo„Dƒ:¿¡R–ߘ¤Õ?÷ñ[â§{‹ïçLAß’V<ß¼$Ÿcùe%Ù$ò*ÊzãÌ›^6r/–ù wMùÌ>ZÖŽŽy©ê^Ö’ŒÆæŒZS™!ž¬¸Êu{BewV¬>!ŽUõ@±÷T]ƒÀ­ñ} üî ©Xõ³à2€q æÏÆ$°:‡,°÷FÞÂ’ŽÇïBrf±Ò^ FE¢£ç ÷¤xT¼'&‹h@ýäÑ_ôOþêê`ßjßšjäúÍõ›9Û¾×¾×è'zŠžæ›ñqñq©vÚOÚOtÕúkýÅ—öl{¶}?×¹Îe.qIšSÚ°´¡~"ýHú­B»C»Cë]9­ršu[ÚÀ´®;ªÏVŸÁ´Œ´ ÷«ÏT<£{J<nOäƒÈ §[n/ïòÔÓsì¿5¯µÏuX'i¾‘”Y=ÜKÈdzê‚ÙÔ;x"c(0;ÓlÏØ,ÍJbÒ*»‚uYC‘0r›ržÊü+4QÊÓ)_®_j]¶·Î\ÒŠÕù¢¢>õñÿTxŽâ+ÖíŨ¢_ à·«ó wÂÕιR›Kßst+›¦»º‰z¼uu/8r%‰Á·Wo£ É«u©¥èúI²‰c²¾„ðaV)=H÷®SÇÓX;awGQN ¹&<2övÅ·ÃŽúÅ'!ëíü±þÛnüGÞ¿@襯ôbìd¾~ÂÜc¼ î/R&‡¤ Ô™—<Õ«±SyVk’Ò^© ¦ï;Y ùf˜N#µ±]¤t,kµVŒì­+›8÷Š'áÍê!Håª7cêç5 9¹ÌéãæäN¥ƒù»¾–ï“C’ã¹=öº”ÉÅÔŽØsöûîŸjGF×§=ä½µøÎü ײ£nQIŒUySJb$ –ïCÎ_W2%ÿzÉDìü÷ËÚóMî·¥¯ñPþÁ@ê‹@=»¬j‰4„œòRJy¸ü12…£"€ŠTdTýv¤j °±æQð¸cýÁÜZÝ$=2ób?ÒUo@Ýc‡ì†Î¤ãDt™ÚXmëk®1—EÏñ;¿Çn÷þéý39Z:/OtÒzk½õ™ªOõé“”ÅÊb£~rrrr¢‘:Keõ–•5_tœvœ¦}Öò¬åŽ¿ÔíêvVÚ-í–Ö]ö)ûg…_ø©ÇMÜ$bbX úé3õ™b÷õS×OÅúØmì6Ê‘` 0ûù.ø.xÞ¨nZÝÔžkO´':^L}•úJ»;µ?µßÑ^_£¯q%åHù9y%©y'M„ýGh+ýã~›l_Kt*Ò’”Bš 2T€Ì.9£‘½;÷9`}Þ(lÌ<“v<ÿÇ)Í{ƒ3îtލ|·ÎZN½S÷%š(ÌC¾z¦Þ“l¹6³ð?]mQ¯´oо——ä4H®+:ê¯LêâÏ¢Ä^±\ùYtñ4N¿Æ}ÎmÒr¦¹,»Ë%\~,ç¬x+§Ûéeªö—5›K¿DGÉmD³“è ýßœÿï €‰`WeÀÑÊ}¡¶bh·§Þ—þ”¿Å p^‰½ÊËúFP»Û/:ÆGJÙšX…&÷Öžaœô´–:òàfˆm±ÝDìR#¼â^s>ìï@æÚoûWp;#’}±Œ¹‰Ç‘Œß¼GÀøÊVÁh¨Ý ©eÚzHwL†ÄdåNH¼ê¼â-¯@üum9„þt» :À—áqîLùJ vH`Ô œ„`û4‰dµ•þ4×Ë"YÓi\1÷Ü]òÛm}Ý‹o–)èveÏ48på©Â¬ë=Ð Ÿ+*¦¨à­¢J;· Rü‡Pê´*ÛÉáܾ‘ýñåÞáÖÓÕ-䩸ËûcªjÆ~¨|š7qU¯çZWÏ¡9xn®3qR:‰Œ/|;bcŠnD â+;~+:$ÞD…Ä0šCj<_€®r ¦]²OƒÕÆ®.Ø ?C¤ƒ¨/ ù¤ö ü@)8¾ÇŽù“ùÜ»P=ßÇã^„Œßw+&Ù½¤HOÛG%­¹ÌœÆÓTf~Ï0È}˜®æÖç"Ws i¤îÌü:õbú`ׂÚwòûЇŠ×7¸.¶i؋ԥۚìD;ÿb“)ÜuöÏOêÉkòÒŒ}ÆÿéøŸÆÏbFrxÝãXⶬrâŽÏÌV4wåÖ668ž«Þ~ML”òks)m}x Ò/…÷"Ò]¡ðšÑ:ØþIÑ6ß²H+ðŽKôÏ]‘]à.bxlú p×QyH™ÿy°&ƒ½N{8ñÆ¡“ Ç’Yàí—±Ýõ¬úwuå v:ï²Ú79¾±Ï+ä ½er*O¸OÕòf¢&¹ˆýHjseÑ‘Z{Ñ–4Osûˆ÷7&CÈ‹å¾Sü®Mbȯ“ ‰ç¹¢Ã­Ø¤sàúQ-Âv$äíØµS¤_Qƒµ,ŒT–âF1Fi×ÙcßêÄLkª3ÉfeŒã5kƒ<ŒµñöÎ&Ý캄/ºÆë€ÈUר}2ð*„[âìä]• 5PýV^"7gÌǪj•vÑâ³¦à©ø)WC* f·å½Š ãçà…Ôy"¥ ¨d°§h$ð|Õ·ÀŸž@¢Îkäâ,x„2óïD þœw¤+'vöõ ®ÍRÊ95©—Þµæ=ÔŒí5íp¤_®Å g ùߊªìðn‰¶á·ëD–«(ñ¶óÅä;Çpý9ÐÞÕOr›µ ä~–R*pH «Dn‚míW–"ŒGÔ¥\ч9›s,YàœÁÝñJ÷ט±orä+„N;µÓþ"X½0ãjwFòk2Ò>Õš½±ÆµŸz®i™ªªUW¬kÜQY¤VaT®õ¶G‰ÛiY MÊýÛW\pâôqédxò¥j\Z£„ÃΞ<Å3Ž~v1hyL!¦½" p;F!³S™.ÆÛ×”5æSwW7HŽWú×”ïàE{hÍíT©ªž$ÓyOõ«Øþ_Âo!òëD.BÆçµà³¢]!mTÍßày,gÔiôR5ÜÚInâÖ± R'ºí/‡ EVCý«5:¸ŠcÕ/4ü{‚ð<ë ¾´ØIð¾ÍïŸ)<ƒÀµ.Þ [_Áµ&¾´aI/8÷€:?>Ô—S{0”:ÊhùîE¡ô˜ñ²}QrÙÇQ8Èå"Q1XÚ6c)¶ÿð¼€iÚÊÓÈæ„dH-TºîðÖ‚þ€ý8Ä5õUˆE!ñƒòDËüÛ qáîzLú»@h@ÆçºÉ•TÕú´R´ÚG2ÏÓ¨Ú™õÕ•"»•ά ”Ê|¿ÄˆÌãLÙ4d?„IeI:_cD~ÉÌCÑv5žþuÙ±×¥÷@}@ìÅV¿‘Ê0ä“Ö½ØJµx‡ü£] ÊIÑ ÄZc?ˆ®Ìå‚v#H~y1ˆö à~êEl“!`Ÿ´£`ä&¯ƒµNÞR®g èWc™XÆjy>Ââ L}ýÂúÓ1¡o´F!žd„Ý×ó&$½ÆPÐOò5è1i)è-¥rHåa½¯tŸÕ6ö• kõ´3©¦ê"íÏÔ5 }¨w”ÓÔæÍÊ~Õk oK笺ŒBöY;Ì·âšuÁ:$Ø¿™Ÿ+•V–!ËCtY7ÔwÍi¦®åê½ô2­‘qojŒM>c›Z2z)q‚·êh«dÈxÿ!ã?ç>þ+ÔŒßæFŸvYy„ÎW[lk_h‡¥u2X'°Áh¼ÇwCÂÞã.¾»[y¡j 9„ó%/ÒŠ×Þå âêf¢ÈEO³ˆÓÅcåM¶y­—¸Ï¢úç;–®feÞbM“–iŪ´õ¾·”;ì>öÒ›U]Ê»1Ù¹Z´aoøÞò9ä*¥RÈ\H›‡i>TH—(¤íH[D@úç^¼E*0¨,¡ ûërÌèéR¤Š¨C|ìéù¼«£Ÿ¢ywGº"{7Ç À][EÒ5<>ÝýRâ$çëñåHŽ!©UçÍ©³u’~áÈ×½¥ÆXÛ˜-ÊP«BzËŽH·û"„_|ö œû©¬re'o¨10ÞU&Aj¦£1$ýÎ× 9ÛÙâw¹Ó!ÖÀ; "¼“!ú“oèó½¯C¼Ð·Rz¦ÊøK™cG™B±DÎP«±¸’Û”jéI³œöVZðUöa±ŽŸík|o {·4Û>k-ã+ûËÅçÜ&ÆŠuÆ>{ÙýÅA>4»Ø;égLH­Â4û)%Èúfù"º±„N¨ú>ñ'7'/²ÞhƒL½T{QÁÅEQÐ?*¿ÛzírD m¬»3ö[ýÌñþþRz¬ÜÕFJj{=‹C •=þÆ¡Óò:ÿÒÐuéÁÀ­‘ýÒa_è(:»ëÅî@wuLÜ‚êÚ” Ž‘¦ä€Õ¤Õ$ŸèöŸÒ9°)gÀÈuôÔrçíPû`¯^0~Rà еãο½ ÅÀx±C(öotT‚uŸ{"D[»@d±çQû‘x×§zר*—•;&Eg'G)Ö˜‚ÃU‹ì!•?‰¥óŠt€¢1×vñ" wI³Ä; * ³á=À•Â* ½n3€ºçÈÅÈ«G¥îY‚Ÿ UòbF{íRùBÆää–ܤüü²BåL*Ï$–“¬\…;gCù µ®rät®ü2ª² }HÍÇÔfþT"‘1­Öâ4E_©5œ¨ý È ^$®~éŽË>þ\[ãÏA¢"xìű# ¦’=Àº56 ÄÚÄ00žND!ðƒX ÁD(fóDGðöP.´ØÚᙡ¿€ŸöB«?Øk­2‘âeˆÄëàt»WCbš5¬ e-0Áñ4ˆ|Ç`Çœ+ +À} éÙTyû¢ƒo)®p ¯2ÒŸ`¤Cçî·âg6bmåó9¿#UÌžIÝòïs»a•M,HG*UaBñµ:x¤ˆzèrusáa¸Z/kmôéʈr¬h–• —ÚmÏïû¯Úº¹“Å…ÔÃyp¸¯7ZF4ÃÓƒÙ‘¡¡=|_»«h*‹Š6‚²¦ôȯ(Èúæ|v*·ݬ]™{¥©Ç¼Ïj%×¹Z:ÆÚi‹Ýg¢_È}=sb/ƒ{{l¸^IÞ ÎþÉA¦·õI{'HXí@_¾šï>mQ7ñ)yù¿I|Ž\ØÛ² -ÇÙ€)Ýj· Æ£L% @~ÅD±»¢€†Œbí'‰fÆDãsœ}Ro£‘L†Ñq$Gcói°JDìÜŒ# …ë41±Þ^ÀYÿ+ Rÿ Qár$ÊëoÅ¢ª^Är3㮥Qé`ž]4–ê,º¾mu«‹Š™\çýâž+Ø\<“pþ®’/pä·(ÅïùËKûÐ?ï‰ÐëɹþºÌ©È~<ånn ¨2ÁãÈ}™„Y5ƒç«6¢0¯æPß ÏýÖŠ8ßNø!¹«²\Jr+¶ýad=Â~²v·'þ±nô¿æwD¿ŒwHôþbµþŠOr4tÔOŽ0üF ‘¡¶R[¦ÚÈoÉoéõSŽ”#Ù5Ò6Ò69:P(ÍÒ¶§m—2J;”vˆMMôIôÑ1 Ôá&n’¶óOˆÖù¿äÿâ¹;414Ñ^½½@È{Ä{ÄõiĈ˜R=m“ö«ëóÔ’Ô'ÚÒÑ\wsŠsîÒ(i÷²ÚM½æù-9Ör+3ؘö c) ôÅÃü´‹8i‘> ø9ýUÀ‘¹xvKâ8s>Å‘cáÀwdLÇ+êåÜg•ù>ðŒô*8Îg×G×k§®Ž¬÷”H\ÝRþ+ï5øûòðF7!.m­×Àþôêê\¢Eå7iõŠÆêEœ?7’voÉiû¶s?ò墕}õjkûqñYh¡÷mfÈet$Åti:šzŸh â–Ô l†2¶¥˜V4ÑÓ5ÒyÓü ÞKº×Þ‚¥Þ¨¼Ó„S 'söÿ ü¿G?rgÍר¯ÞሹÛ÷¬þ†u£Uä‹è#"eÆ÷5Ë~Ôg¥Aà{Ìì†H63¯Aøš°A¾Iª5*Ïën)É®Òìd©ô5èm´©XúÏêkØ©š#ÚÔq3ÎÔ]Îi¾Í9™ÜH#9º@‚ë‘ÁÉõÂÕÒ<yÎú‹µÚx½½•™WOêPý­÷rƵ"‡ø² um ­êm»úÔ»±¨>;êi×ë²®NÇ¢CÜ[ç¦âa\.xºx G ƒç"0™FåOˆÔ+}¸V6‡ºP¹ƒP¾ÞˆÊ³ØØU…>­@yõ=€R{#6þj)í‹V¢Ø£Ã}­«ô¶vG²¤vÒ-áIÚ9íh¬È‘åD××–ÖGî–ËÇãuìÍöæØ/òÇòÇÉö^{o2¤­ÑÖ‘ä¨ä¨Ø/Τ3É(eˆ2Äþ!Ô5Ô5r§ý¼ý¼á¤O;îºêê‘\iU[Õÿíž&4¡©Šë]×»îS± ± Ö7b©Xê~Øo—C¸q»>!FÌõ€Gp?àoÔ÷Ý \ñÍÑÁ{¼ ”ˆÌKc§ÿD6™Y³Q˜-ÕýnÊó¾$Ÿóêò7©|h7¹~»ØýGzïX—‚LéTQFƒ¹ïÊ» :ðóå¼Ë©¹Ô¡ñÒ/¼Þðz]j\ÿ@ªÞåÙëCM«_Uo+NŠ©ür½§²;S[=]‘·¦=é‹K?ñ4Y¸]¶±Ëý"*Wµ²Ÿ»ÓE'ói¥‡^–ê+2vÉC€IDATÕ:É»\-ý±¶ÒHY/ýßœÿï €ñ@á'­áĆ­Ó ¦»î÷ˆÄ&pÜbëV# ŽÉ›@í“Xê(½))µÄ˜‡¦¬¶û1Q(.ã‘Î&_¥FZCû1q‰ÏiÈKâΊwÄqƾEªd´uGì.°RŒD6CÍÁEÆA*á Ƈ²€ä^…Äl÷WÿÕ1bNçwè±ÁÊT.ðO†ð/f§5„ðå@vußÌ_¨ªY›±€¬êg2¦ðJå¾ìÁÈå½³ÚAegûpÇÔ´¨8ˆm^“²¥™±íyÜ Êþp~‘;üò^hØìÒËè Æ_MG-MÐŒÝüް~¤>ØåØ`ç!¢b( )ݰÕÛ‘Ôר‚í8É8ׯ\Duí£œ¨ç,9Tù¦Õþ‡30 c@¦UÜ[ÉßœÈM{9˜1Ü™Vëz¼vSÞ*õ@é …9|}õƆýàb§F:û/¬n6†Î,mü¡=÷ʤ:]ã·§¾÷47ΧOVö0)m<éÞô>ìW§8&Yó”>Î|#GúYÚd”‰jEXNhÓôn<›ºœšÇ›úŒh7ŒøWÕãQB¿ÕWuílðd„†´µÑ; ml$üSÃpO‹À}§Ò2¼ï”ÁC”– ŽÿçÀ ½ï% þ9uð0µðÏX¾Ö¡¯‘<¾ÈLtO)·Çº·é£S¥ƒÖkñŽ4׎'ªXŸØ ³ÉÓK/'jŒLÕâ‘'ÏC|XòFPr¬àie—¬¦;mtƒØf³Ç­¥à+çƒ/©¥@Ì”»CõAëE°×)OA`„óOìÈÊh0Ûiã±ùŽ¥Hlq>Í[ÒD÷T\ÑÉ®Eö0g+iB¢`gÃ÷úëÑ,´ÓWÁg}3¡67ý¨ižþÔ¬ÈLaVÕÏZC²fRÖÊÊoÎùœ†åÏäÞÅåe¹mQV›{ÁÞUVǪ9•º›¯ŠÚfÑN@¾ZûªÄ“Ä+W»Vàv~Tw ;3ß÷LçsmO¨'+üó£'¨t¬¹‹¬ôgt“&Ù D¹ñbÆöú€GÉIýæ}I›–xÝ1ص6“…ûùX:_ºOE²Å.o—X±Ò}câS]Ýh©MýšË<êISIØà51¸O`vPb#µ7úïÎÁDâÇœ_²5±Ñ³±6žóö´èe·m¿íî~%y ú¼+Û™¸¤µ N”ôêwÍnò]Å ¦•ÜÂâáùÎë¨jNý'P<ã ½ÜíèëîÇ'Ê#V9þÀná©§ÙèÎõ|CÀÑ3¹\³Ä%)7>—f(3ôÁâ º_¿Ç´©ÆP†è1F9Z$爛õGÊÏ›fA¸=ùKíT«QÑHe–M÷šX9ä?X«BÚéŠËàý§îóPßìpË ù)uÿÅ€x?8úý1ðpÿà*h2¨&Mj{@z›Úkà·C@ú›‘-à+†ÀoµMÀókl2¸/Gê»KìFpMNÜîÉV!8߈^­nê:h—¶ }$߇¡ÌI¼‚"õ‹}D¾|^¶ì7gßjXöx@„f Ÿ/r©”Ýœ·‚γ˜æxú!ë;•}Z¡½ ©'\ ÑÁùÄ¿pvƒx…wv´“ç&ˆøýo#Â÷û[BhjàFmnàs’Ácm©¬™”Ù‰úUfì`zõÊìÆ”_Ì;C£²ýYi¶Rñs]ÍùTÖm²ŠJ*cçn#å]pC 4çX¯LÊu“ó6t-]|€GîšüCý–&(êKœà3éY³œ*µTtåyù±]~ÜÑ UL­nÊ Œ} fË %ïq›(Zs0PÁn– 8èyÌHõH°ºHØŸ»:ƒ>;9Ì5J'°2ÔwAÿ0ác‚:‹”qL¾@2µL¿¯Q_þS¿,‚ä<«+RÊÏ÷½£|‘Ú`çBênÉXf.#–Z#¿'™“¸!ù;Ø‘ônêwÉu0tW¼{ÜMùÛ1]ߌ­Í7ÞÆp*¢ÕóŒô8‘îUÑÄrÆÙ îJ-JÜa3O™çð8ž×Fº5¾[Õ*pt‘†“P¾QòqjÅ© š)µVCûi¿ñªµH9môÓ…´(~µæê_˜æúûÅ=iõ£s3ð/Àÿ­³±UnýµùSóÀ~#õª½Jm®œ­sÕÇðkìðjµÑ˜f—ð¸­~XÒUýK$äX7t»[è>R¯ªdk­ô®tp´Oìá-‡²èç^À‡ìqôHn³ƒŽÌ…öïJ7kù™ò ͤ§¥<ë-ñ´rÕüY¤Ë¯ó0“9a?*:Št¡P´Ùb÷•;Ùc¬ˆô®ÝÄœ*µbÖi¹ñ†9XÚ‘ÜM;qg"„Ä]±CØüMãðjàîà›ÀþÊ @vÅ€hÇg9åêÒÍi±ýÍê~†éž6%m–§9¶¿§ÖS}ÙŒq>%õÇáøŒëls 4îÇå§¾L/mMòO9¿×~¡–H ¤µz¿ô,×µ ý9>UëËšmÉoÛ.s2B¶¬ÃâQçÝæj±F{¦Û¿Û›hê}ÕèÆUszÒ–¸/ÇÚ„[Ï2NSi.¶4 ý{#Õ¼É0Tûi1Š$g˜†ßî¢,'àX)½N޶MYŽ¢Zö¨¾Q~€/¤.Jw2´íR ~/ïåYg…<Îê˜úPþÙÒí,·v'ʤ°q‹ãeF[Ìã¸ôb(»’ËÉÇH>aÐËøLíÉý=dZ&*O’ž%m#{ÍŸ¯*Æ$šÅ;q9ôVE‰ûǤ~×´óVöºÔ~p>‹”®©: Ž´ªAYj~ ¢;ÇÁþ‡ Ù ê\mXÇ™†K| ú-ü¬¼Ž%:z²‘RG¥ÛX,UúÞa²²Â;‚ÏnO{û=F68tûÈA~¦á,ijÿsæÁŽÝE^ðJñç˜á †"WÇX•¿#°*\€T^@—n¢£êmu—âÛÝÙvÛš·íÞ¢½þƒcŠý–\×½ÞþÞù…·ý=¯;g‹ú"hm~¹…ô>w$D¼?Žäåèû4SöHóø%¾6z•ÆÆG±o 1 j§‹¸Y½Á·“l¬Áÿ,:aCz ´À€´^X(B'…„XE±þ¶Xxü‹ÑxÏ÷ûhâCäê‹”ÜÄí²â¸'6„9îóÑŸHºŸÝ‰Ã=1ñ1¸Æ'>×ìÄÛàx.ù58F¦6ƒö ¾Ô†”ró$È%f)HØKAüF[`ÁFÚV\Þ ¦_™úíÐ7©ß@jœs"$t×mëàì )͵Ôk®ç!íwÇ6P{*@ܯ4ƒ´£âAp?o¦c¨íÄ~ò—Œí”‰÷,ƒ‘ìEãÛ|J=à€ý¤ô4س¥\°:Ko±@<æƒâ àPÛ‘²ž—’höj© SMK>ÍI‘+…¬ô?¤æÖV£©ÔúÑZ)0·×“®_±Çc›!gD"MÿS/f7w$)/±C/Ö&`‡WÖüˆnŠüÆ…XXE¡Á@"ô:¶:/|–ˆ´(² Ÿr!<ÓŽ;ÚA£Ê9Ñm Çzùmë{m¬\j~,%_¶Ú(“ä2.ˆ÷DõÄø8aïf¾XiO²GHéÖ½öl¹Öèg†äzÉšÖ/Ï·JpÈ?ú!ë_ðï¡•ñ&Ñ3Ãn? Õv©»é ‰›Ù ‘vÂ/Ô,ø¯ZDµPù-0ª²)˜?U>¦ú@\I]Jms:b¬›ÔÇ" |G]ŒªºíóÇ»Kª/Õ¬KßXû[ÅçóžÉɇ¤Û³ÆÆ· ³î·DhØÐTžÎÕÛ ô­W\*lÆÌ¬Sò̪÷´îYK‹wCÞº’UœÎO–<—WYÖžÕ¹Ÿ”GQršT(¸²#Ubd~Zñjö Õ_Q'cLuÕñP¦õ ß°6Ely6Ô¶J´†pK¾§Cx9yŠôÆ ‘¥([±_Ûâkí©g€Û“+Œ³ÀƯ@£øÀœ`ÝÀ{¢@$¤rCåa C}¨ÖrœX༠܉ƒ{àõÎ#AÄ÷%·A`§À+@Æ·i«i§¾í«›šxT>\žû#³ËËFiÙëùÓèXr¤à=vê6aÉuOýZ®^YT÷ˆÕôÊœ:¦q¥|Bö€Ø¤ÚÏäËåò:”fÍý•ƒœ‡™If£Æ4’]™«1D}W!>ós C¤±˜Æm|@þ­=9e Rj²(Ä“<`ŠR¹°< «-ˆ^,ê rÏš»Àÿ¨ÙÜ“ÇÀÕ×| Ò,ðàî àô8>ˆ\f‚}ˆàšs£ oËìC_™êýÿ&õ9øÝ®“ðÔowÍ‚ðÐÈyâ²[/òEH(fg,>6/ŒÆ»À½p9ù:Ø7§¾C±š¥šbÍË<”8@#±6Óœì§LÕf9–dÉøÐ‘w&¾u}¤ž .‘_*Øj@°ñrŠ(lü½ýåMîæ¤&õHÚ‹ëMç«•yÐw{É“êð<ï•%\lðãÕ\Š ;^Ëg[áÆë»y­n~ÑyFÖTdsµNß’ƒ¬ÏoPÛ>ùFz¾õu¥*½ËeY ²üKn¦yùsÔòwå<„ª2Q)¬jÕ”ujÞ®@fÍ>l¬HjwU‰‹öpÑϾ=~“”Ñ4c¯©EMÚÒ>±“\LlÅœts‘ó©ÇÉ&=uP~Q~ɸ]ì2¶›š{Œ¿éG?ë~åWÞGBÂ…„$öb`HÆ0NöÈÉ«GÍ%æ{Êʉkiìg‹£Èwîf×<˨߽‹K„¼}hÄ>ç$÷}ŠŸ2ÿ(i7±#} ’™ÑTV> ³:‘ÎÙÜÙÌ¡2÷S‘SГAxêÜARtÈo×õÎ ÷ÈŸ,w+ù´A¸¼³á$.]z«q„zµ&sPÎnhü=\\SÐ;ñjñ[i}ÊÒkÆ+Ã/Øênuˆo37›£Ó¨GaòSÒIO¶ ˆ"=>ãj¨Õ»ÓžöæÓüÎïf¾G÷èŽW9‰ý±N¬“v³Ùö"~çw9Š„¬tÆOšú q¢Ú=4¤…c§9ê\D:u]K±(vgàÆô ‰××·)e¤û>Á¥}á‚/ÐRœ„¬4žAdiôÇ•5‚g1sžá2çòûSTÞ›ÈÈu+Ñ‘ê¢2>/ÓÞèë’¾0üuþêÆâÚF7Àå=M?‚3_7}Sçîmv™Å§×6Øc¸Ô$Ÿš¥oy÷ÔÌBÒƒ¡“Ù]HFÏçÞ7¿ÉúRu†Y Ý’5Èøùÿæüo´”yûàX·_>ƒÚ'”ŸÁß¼¦8>' ιåÏ€ÖWÝ .¯x´Ý¡  t–3©TîHd)?V·´Ò@¬±æS=„^2§Ù͸£jÑŒ Õ°Ä·ZÜo¡¾ƒW&,lýóÀ/}¿´’8×Aü UƒÄl÷tˆ¾æ©†Øã¾qîõBø‚ï <AúWÄjO¤‰×|–ù9™Õ²îçDÅë9+Ù[ñDvˆÇ+em1·WöQ÷ÖTõ9[²[¨wý öãº> ‹ùÖn`H“Þ´°¿kêætPÊ™êkQ´Ýٳî ÕðÑ+a¨ÿ͵9PøþõýXuׇb×]\âDÎO–-³‡å>‰Å^ñ›·Ö$Õ)´©1—ã5#a×t µ‚ïD†Ãÿ$—± ±á‰ €T'ã€~Àü À®ý¯O õŸPžÐv8óÜ/¸¦øðϸÒB@Aæ^.RœUD#±,ãWë+çž´A‰«mm«.4モÓõ÷ñùå_Þ½Ú¤ñÁ±5µß9 ’E®tˆÝé^±—=Õémá­þ&Ø‘“þÕÄj[¤/ÄÎN¯ÂSóXÆ(U¡ìÆX•9ã—_Íy†¢òÍ9ïšÎÒ >#2+V‡­%¿ò5¥)u;…ñïë Âi¡›öb»w»nå¶ø×TÇœRÎÄoæ[í)Mb†rÖ®v”?%‡"Tu‰xŒ‰R{å{‰x6ú®õ·øSyÍÎödåXuh}ý”¦H¾E<‚ÈZg$%å±Û¾TÒW¥-„¬0¨zûðHû¤\ÛíFt°Kõ_D…u·ù†xÉþT9G¹ÑÊœGÂ\bMÄ©·örÀ¼è28§÷5?åa}‡‘úBüŠ¢ÇHÇN5¶‡"RKÄ *R>ÖáJ&íÞTs±Yöl)6CjÝ+ÙT†¤÷VÂŽeÕT"´‘Æ4p¶°#à{Ožµn¸3 ‘p<ÎnBÎ\^!Gm -Ä&×di*—½MxJ¹+2œÍ´tîTÿv|gµUß–u£“¸=5W¯âS×c9^õÙÔ›´¿6ÿâ¸÷˜Ñšöäë]Ù,K{ƒFw.N»ç‡´D0ößòÉ-UÏÂ?=g|©Ñ×RXê£j”¤Øšl®Õs¡[¥Ag(}ˆú‰k(v—ð P§u¥ŸkH#åÀ˜ú ÌK‘À®g_©ø˜*óÆšÐù 9„4±'ò+­Å ÐŸ|"¯Sé)¹ô!HHþƒŠ”ÛÁZl Ä¶î² Ætë1jW)fwªœv,KVòÃã…›~Ñ»8Æ¡Ø{̤IäEêrgø¤8źÚ9V7Ô6 ÉøƒÞWpˆ¼“!¿Ëw!/U0¼Ï¨“±¯˜ýΰýg¿YsRû”ç¹×¹±$‰Wp8¾M‡\»L=×®¹<É“*ÜoÆé9 «X¬â°ø]}S~mߨæØ÷ÛGźO.¡y‹T8îhN 5@L ¸cïÄtÚÄ\ÆGÝ • ÌŠj‹"o÷%ÊYåþÛzÜåSÍAê9}™Q]Œu-3êð¶«v¸7-Üã­íÄhͧIÐö;^‘¢¦Ù±tP9“é¤Ü!ÞåF²E:MäQLº ¨—ˆ±âô¤œ¯îBDmÒAÒEe(ë<¶©Ç¬_Á÷¢Ó ô‹Ž|Qö!p ëжÈý@’e€¶ÀžJ[a‚SaÇ‚Z&UB¡Ë¡8BˆCÀFÚ#äE%d¼hŽpz«Å ?PŽb¨§¸ —]KÓºAÙFº *GxÅš¥Æt©EèÖgÚ,c£ÞÍ*ÑÞä)ë˜ÞÇ|N{Qvrú«ìþ¦£Þ#Sì'yÝèÀk´ ×â —ŒÏEoî ­fÍiJOm¥?;ñAðsû?sÍ+„ÃSÍqW|R& ,T\Å¥ýÀ Úƒ¡—fBpG¹ b€üÄI9äûr#Ø%¼Öa4we!”ÕäAúÛ©ÐéÛA/þ¾¯¤8§±õÅSn.…ƒ—·¿Ö$€ð|à\(˜Yñ°²¢ä˜ ì_‚­„טŒ öÕØ÷c_szF—$}jÃ4¸´ÇRÿáôÐiaõþ˜QѵŸ?Ó7T„w„_T®c‰˜ABpdpº:­à¥ÂB½E™»è+µ½ù`þvQêºR˜Š’¾À‰d!‡êôº×yÈ©uxµÆwHLøÚ{{þý•¤Yáڔ, ª¹²_…ôñW„´¹&Á”’¼qÉëò×ôqþI&þX¸˜y‰ÕJ.Ë÷㺇v‡ZyòCéͤBéX€’&¬€²dî'£üQÀø WÌ$ˆü/1¡FÀ~cÐ&ì|æ“ÀIk5°4 s pä—S¼•¿R¥jŸš6¸¤/bÜ ã郇Ïàœÿ>ÀñŸäsˆ:ȈÝ{ Þ bRô~çs_Š·C 9>YM+Ú˜òCr÷¦ÍdUÖÖŒNL¿Wýs6_^óar/­ªÝ€ðù®5³ìÆWÎ%g†¿°nõŸ Ýá[IœI~K½»yÍžû }ß}/ÑDÉÔ–‚ÝG¤Ran‘µð›ÉNM0 3öJ*˜WIc¡sBÕ­‘ÖA- †éÜá°2;t“³Ëì¥þŠQÔ´"§üãz¼¡N¡ ÜEµó‹Àni¬‚’IùeV´ˆ…ê§»V;uÀæ%PýŠ•¤¨çkvœø7Ÿ?pŽ"õQ½çß‘ÿ'’µ×—Œ:—ž;I¯U« m î„òÖÕ +÷áT ïG©È e±Üqk+ä¶`©uÚzîK'c‘nÝÊ´„uÕ’—s¡F“+óø(#þêrÛN+$Wò¿ËΫ~Ñ‘øìtæS”Sî?˜j—H.üN"ä B± PÔ ¤?JÚ" ì€ ¯Ü ö:Ã Ô d—‚íBŸ„¾0WXǬúÎ,§ @ö‡”Ój)€Ö@»ÀÝÀõ€o  xûŽÿˆ®î à k› f?9w7£!~ OCâöC’ ’Ÿ"R¿â¤ %@ëê³Éà@Æ@V++R°–'$E}S0©æ`eæå u[bœûµž<›Ú°®Sç-ᮓ…uš›5ÏÞšt>{þ½ÛéºNŠxÿÔ€£ÅêTŽe·Œ>F¯¼ï=;9çú%­&†rŸWÅÿrü Hšœ”„aûƒoâRUÑ‚ÑÑK£¯@ nI ˜¡ÐA _QTG\ÚJ-dgg/غ瀳 ¨!Cy\é0(q¾¡ !æþ´iÄJ<ü×¹?ÔöN¾´ FÞòL0»‚ˆ¶ºÛ2œ= nvV‚Ûç,§P~êb~Ù_©²£˜”µ”®s·:“¢p¹6·ó‚{>£PŸá&î•`¼ì7¼Ë(NðÕ$*`{®·ë†ã( <ÆKžF¡ ,Yô< Šýã'o*NÉcØhq«x’µÃÄ87Õß%> ÌÍØá[œôn«6éÜe6Õ|v ·×›v¶)»ê¥\Tp×~a­k¿¹@®Éß(””ô“ó\ÁGê Ò3_£œ«Wóñ!³{ @î8€\ ùÉäAþݤ@Ñ]EÏsŠ0J«9÷ƒ3;¨õÊgË/TÜØp„KŒ2#²;£ 8œ‹88r)€ÈµP@ÐZhýqÀ=À½ ÀóT†‰‰ÊR¢z¹1aqþ}à‰qý ±ÅJ$¤Ñ ’ãyRÆÓR x ªM‚jûШUc6g¸XãNê«NÚ V»” ËœOk?£¾xK}/œ*lTŒšÞ…-YÕ«uwZæ<‘æ·>¼ºîE [YA@tW/Ý) XfŠ:$çËˤ~³ô±ÚùZî ›ü…¶¸äsJœÐüœ¹xïEG-9~ ÁÀ”‚µ nJØOa ¦4ƒ½Þuå¡¶fsürµ¯%þòîÁúøåi|ö/(´¢¨±ê8d­®¸b&h ¹†#¢J´ûÀý”= |ý)ƒè§ý›Éwƒ;¹èmeå}Ï@ÑÆ©í±= Îužoô­ö8åEuy¨DD»bÃo‚{tp ›=]ÂÑŒð7 ]äw¥o¨au¼¹=¦­ÑE_¶À5ÄšžÛB"•/RÐu† \™æ= ÝV@D[ðV8WAûR9ÚØð{ ûæ¶Ðëq>ˆÉ3 ÚWcAtùëü¡ÒTȹ7 –5ÐÎ@üBs„F;K„²ËPS\Ö΂ N”dî.iÞ¦%¯÷“ÒûÀ;½"Q˃xß«x¼#‚à¹hÄ€ë6s,¸&Zwƒëû¨w:ë@©îÄ€ÒžRyJ9ÈÑœ£ê`¤ó¦þ*œ¡/óvÏÛjæÙ¡CÞú|Ëw *¢¢<ÈŠWb"J'Åf“_R÷$o‹¯CR¡™”FqA¿¤RâòƤ –çs ’Ó¬`NvÂÍÆÚâ™Qï–Õ ¿ÌžâQÑQTÔ7v£ÄÜ?^ÔßÔj6Eѹڀ¾)´ôÇŒF|çåÑä1Õk'G¸é«ä{Ê(§žs³ºIy×ÎmÄX{ÕÕöÖíw õ«/¸\öB0^•™®nÎXdTк„!Ï"ŒûÕþ__ñhhƒÍ:Ä%/9ß_¾œ'9#oÔ‰ŽþF½—ÙMµÁˆo€½Jo,P:c™M´¾hÜ©Næ¤}PmåÔ³Qïu;o‹ƒ¶”WØk~(£Eª™$»Qhvc*IÆ‹òCž1º‰ ÷†ïŸÐÎèË D¨'ïêÀA¤1V¾0胡|¼• Ö­V*R‰-{õ®{øf`ÒE0º§ggÜ7:7ðš7^ÜÆ÷¾ ŠF±§³2œÞ®ÎA{£>[ϳ×Vyms/k´Äp d‹ðB½Ac]Û̌𜵶2H/4Zckõ¬„¾ÜZŒ¢ÂGÁþ¸î[pû”êÛ õ•is›¬SEÕàìšÇ/P¨Ýi6d©W>Ÿaî·¢^Õ¶Buu¯²°0Ô9ê0ý‰¤QèX>‚#ò­¢Ÿ(ëå&ª‹‹ÚnŽŠcÊ;ÜD.Ïb˶l%FNÑ~DsÖÙ`É$O ÆÛgÔWyÏç,e¯1º| G³Á°ì£baóó4j¨Äü¯™Hbð)óU’Ã),¢zx›‘oœP’Ï“|KLÇ[уˆÂ~åµÀØïO$ì«–ÑWÍ`½Yˆj³wƒšz©ç†k!<3ƒ,Où‘Ýî½âmÚzÜ$²Þ7K¾Èž‹ÊfÐ?±¾—#=SÅ@§®íþÕy^ݬě7+ïjkÍÃÔ—_†é‡/rÅ­“eTÌkVw±CùÁü’ÛÕ£Æ$’¼Ø»)¯Yª·«M4ãaèÊr–à¨=í¯p\éfšóŒø„%ƒþ³Ý ÄX< ~•£€~" °…ÒË/ }j=p^˜ï«³ÀµYÝJØh'–€±Yûа²XÇX¯¹:WôlbÌóâL{½û^2hç™gîtՠĸÍÕÅØîêOq¸›ëŒ3Ú7ò”š®fÙ߇¥ºÓÜdnòq:w+ïÒA¾•e|Lá?”%¨æå&V T.—‚µA†`qÇèçz£||è&„ùKéàýØÙ‰”%åн£d3Ô¨ú¾m F>ϾÏ8æƒë=­.¸ÛéCŸ Ÿ›Þ<±ºîø;œŸÛ:§-?÷ w39ôL­ µE*Ý´•ü¿2þ±úGJMDt¢÷7„ÏåÞùWÝH5,Ž"Ä'IÊ„pF8 § 1o Ò]Ëõ1‚¥@ˆJ"ôvè(™VœÖöCHù“øá¼O9°Z| ÊkZ60I1A^å ¨s”º <¬<ê4Vûn÷ç^pµcÀIV€w™ýø}öFðÔ23~Ë‘=+ˆhÜ…Œ™ B¹®2Žhÿoözú–ц…þ«Ê<®÷eˆƒHÏ"2ž>÷­ÎÓàj¥Ü z5u=–¶V]Ã>­\«F”6Á7…©jó¸Rç+5à.“_*Óã2¬ÞBKîc~ËÌøÕá ®žáޏ’z›ƒå–ŽÐKƒ¾ÊÈe)ß_36øÆê¼`¿jMóQÐbYÊ0ëP‹œ·@Ý@}¤üÎ.@(©2IG1rˆ³ô~=@–‹Lp¶‹WÁ¹¤¶g±x)WŠ ?ת#컵÷@|®´Ä1Ï+ §õ;À®>ˆc½¥ÿˆmmמB±âôèF[=‡ŒÐ‹îWØoÑÆ“bà~BgõO9Rº\»ßÙì²”™á»* º˜ã¼õÅ›aǙÉÀG¡Ïè#pî4!hð*Žt¯À2F»ƒØ?Y—°Ë™£°ÃÙú œp#õ3È®Ÿ»“­ °sé7(y/G)¨^¢¡ZŽ˜‹šwºd<îwÍÑëõ>wÿ-É_h½çŒíõD·:òüæÖ»‡+RD#ûÚ‹O¬bQ(ŽZ.0Åž«OWÊýI¹ÉùÊñ¤nÉ–öMRIb7íyÏïîZjŒrV]¤,ÖoV¦+Ä<ñ<ÍõwŲŠçK»ÐÇísÿF¶÷¤{>ºÊœ»íNd)uñpéâc*¬å~r­$39/^|¸çRáM.ýšýIo×Ó¿Ö(àtÝëjåk€ðδ¼\x‡7+Á¹ò¾RT­v¦x¶Ztö^HŸœ½‚viÏæ¾Àó©e¹ õJ^š'?–߉å‰c Ú²8áxñGr^|ÓÐ[f’ï{(߯~ åÕDu(Û'¶@Å:AùdªCp2AÀ†p„ž°^0ßp~°_`.€ø@¹  Ð_p½JÜïáÏu¤o«Á? Q£x¢WK7Äv^÷D-2ïð?ìîU±,!(ºžOÚ#öæMJïÈÈ«Ó×AÖKÕ[AVǯBfr­©p1\#r–§e“µÑßU>ÿ¬z½#«wùN]oœì<¡ûäÛž#êŠQÚ:³·è‡èh· l§™sö"n³¾èNWk‹u={ï­a¤Ê ¾N’Á¡`mkÀúf¶,Ëã9½=[å-`´Òo†Ð(³6„û)» ø«ó1”4œDçÑB?ˆ†ÈàVåy(ífF#Ãû”¦TÜYQDLvJ¾K¾^²¦¤±Ó(wAQK1‰råIQÃz–"¶é×h“˜¹åŽ=›AÛ¢ÿ-þ?ÿù ¾1ùxþ“ŻеµÛÀxT~UšVÞM¿Û—Ê'![ÞÂ÷¡dg5[RÄÈ¡Á k°•ã«ö¹~p½M¼¾IÏUwª—Õ¯t¯xŸX1Å Z›”ŸÅÓò±,øŠéñÝé]ϳÎ.k4³Ï8ü, õ†Æ2¤¿Àþý¨º™°×Wˆpå?Áϱ.»€! ©¥ûØ“!*‘Ö B*ÖÇC´69mbº$¿z1¤=[cÉySt®›pá¢Ðk½pŽmµ.Æ®}öòædìËòËT{´<§4#:Ù9’sZyƒ‚Ü ²5÷8£±óæ³rÔ…ÂÏ‘PÐ%ëPø,Ê&qJ[s”Ås *ñ:„_³žÇ0OcÂWZ€4»Òl`¿`@  (Yꀢ¯½0ßõ,ˆ€g è×4p«<1wD?ÂQˆ{»!þ5.@â„!i ¤Ä ãO½Â—TTÛ!ËY•^SþªÞœÖÝú2ºiâˆòƒÕ~×r³ºÔ[Kö™‰õësÏ™ç|(ï9-\p;½¾þMÖg^¯v¥Dfk®/.´ö‰»”§ŸzYsãÏéËÕ஘•D{¥ÖÄ-‹D)Èçäjð4õÍ@&* ?ZÍ@[«#Ýwè7ƒUj™Úá{Ü[ œëÍB(éžwìcáæ ®UîçsV‚¸‘Ñ`?$?oµØuà÷)„2C‡à©/g·ÿ¬¸ûà à·ÐÕ—`ØÓ¡R(½Çtƒþ± ´YöDÐî·ç‚rŸÓÄRy¨ÍewcDMp[ïj细ÅÝ{¡­+©îܳçÔýuFŸë!ÆÖÓÏÖà†ú}ÎÿȘ:×/â©Ú­rC©;CE…#½Ç ë²2íê¥1Vöjnƒ¼´œqäBþ4,ÈOAƒÂQEã(‚âGˆ‡’¡$‚±6¼˜¼ µ²`5€Ð÷á…Æts%€•à\pö0@¹@IPûhM\ó<šç^Àònš{ûòšx.¹C̣€„ÉÉ‹™IÉ‚”W˜Õ6± Òq™NÕ_uÚ±³ºe§iÒ¿´êÅHˆ)^ã)%ãò¥FÕÉ;Ù¾a [O6mXì93¯AÇ:so=¯é\šPRò|E.ÅsRë'ç7ÞBYLAÍoÉÒê…Úó­>”Ïdºú‰ñ&­šRÄRõ>“K”ì!Òîó}Åôµ‚(A•÷(]´qr…X¡æ;¿ˆ‡DsVËŽÙ )’ŸycY­½œg¥ó`Þ£'´)Xbü–Z ÇŸT¶AòÂ?óù¿\†ýì‚ KÖ¾…Û€a…­q´iÓ(úËáùà¾dž÷vóÐFX»1ôVc\Ú »£•Ÿœ2P~wvñØ-Fbð‘,ÇE¶Ð Ë>ÚÜö@u2Íì -–yöçú@: ôNHë.÷#ˆð~Ïdnô¶†ÐÏX.ö[P±Ï?*¾Ž©€²¨h e[bž†’Ÿâ[`åÆ]Ä,~.q ¥…âרeEí½óïPî+xÖnÆO9ýXNóì—E2®9;qòÛ{· Uc1YþÌ:x:Ãlæ“g£ÛÄwÏ•æç¾'ï.Üvnƒ˜XÑÿ\,…®è¬f|ß½Ø"µ–A_¥íW¢Œ!‰3ÝoVèQÝü™EEîG⚸̤yƒ¸7iOAH,JZ\ð(ž„%E?qk| 8¤ø‹%Ïs5vlpiÞ÷ƒ¯ÈëÙÁäÒq5ØSœŸÁÅ{âß&\x_R î|Oò&È{<¥>¡ÜMiý)¸º"=“ÙS¢ÍEWwÇž/}К¨·È)WsàÂq6r´ì˜7igÎŒKÂï•ñø¾‰¾;jœ' Õ=C~¢±Ýô®Â}¹8êZ¹ Ô÷™ j‚ü©u{‘JWÙEu‹;w¨Jm§/ŽÒšRôf ˆ½,ц ÞåK+•¢1¦3 ?††aìõmŽ5˜ó`^²¡ÈAj!Âê`—árº))¨Ö\i£9”¾`Ü®L³•Õ ÌäT0Þ•ÕÁZ©¾ŽRq¢d"B©]ñ>ø¿Wæo4;ÀwF=‰í[/Žcy7+ûq{Uñ~ßrâdŠg±:ÁºC;åþ:íÁ  öcÁìLQû‚ëñòe@º:Ôê"П(ß \N®cO÷‚ô³Ê`Á_çÀ”¢ÇW¥Ãš¦jkðmUŽá¸üá(ÖíòcЖÈ~ ¼ÂcàÜÜáëÌ sƒÀþÁŒepÅà•²I d–»@ÕË;‚²5t\W± -7ZvÆžê‡N!¶Ò†0ˆ+DLmA®TŸû€> Õ\èŽm´u/A âÙ¡ë|M!ˆº*ÖF¯‡²}1{1KºÄíE/š™0“W‹ú&æ°¶ kR Y+¯KÒ|ëÑüq“³Koð­)õ[?i‹³µ›y.Ø8n# 丌­òßÊšºp¢jÅÖ`/[|ÈM×Ë8½TN’÷¹æªuí‰ê,­®é·É×­Å.w”9™ŽúõæËXbµÕ‚|ï÷Æ6¢ÕSæYžÓ ì%œWßµ~ËdMŠ<­éx”åYtÖ8í9g)híÁÝÌã`$‹»Á™TðÒvnEøR¦qÊ·I¹>Þêòe~ò½Ì¯LôÜD»†kƒ6ÉÜ¥Nó66Ú‹RÏã¡•4VB/àö ?ÃMžáFGZ¹¦‡ËùHΚŒ½$ô%*¿šGúl§&øö…Ö£Ê<ÄöÜ[ª)Ú|7~§ñ·€ò·¸¿R ØÓò¶ J7<[Ê.Ì ¯>Õ›Ãq¥U8š<ílt®3H|P^ÛùT¹¬?Ä$¥oµ3TúÊ—Ê ð9¦, \]yŠ–¢Ž)6Ð[F‹bä*ÑNΑŠ ¼_>KÌvÞ3F(mi5W ´ß,;Ïd{»6—öN×wÃj` Šñ­PÁ˜æ„ÀøžT–˜S T[nAúØkÑ+ö.Ô@”¥™ ä›ð7æþ‡Ñ*¾ŒHû¤Æ ð%©´(ówpÏ·žEú¿Ð¿DxòÄBλVâc’×/ÑÁý„|ÂéìŠU²ìUÚ ŽYYÚúU#…2o=ã!®h2ô:åúäð8 =ÃÍëdGïDcŠxßõžñÃ´ÙæÃxôæEBj?KCu¿mf"Ô5á9¸9ï,׃έÂþ” ëSs~'JéížcúpÄ:û[t¹AÝê yÄ»òC[¤¢¿¸˜ÇÏ ³•q˜òñš½Ði);jÍЙ©¾†p2EM°k«“ÀþA; æõʤµOKÀ0s]ï ¹¢?€>«y0­§´t„ñ®ë0:ºŸå’}Ÿ>—ÆH׬ öl 9ÇU@»p{× º›ÝµÅö£öqm†ush£ò¾õ«}QŒ ÕãUf…¶r %œ«C°Ø¾‚÷È/ |UÍ‚ÐhR PÃ\Áæb”¿UxDjÉ&ˆÞï]ž~ö$p;ÛÁs»ö$¸—1Ã3OìFÓO;ãQ\YN xÖé'!~ú¸yà{¬Û¬¿Áù»¬©Ö{ô)~¼¤%W ã *8j¿h î/*Í/çÊÁ—p,|Üï¹²½rRÜ¢´Ã.EY¨ÁÊ ê/zÈ®r%°J¼N{û{ð¤ør±ce|m1]ý !?·“@h>-âS’ƒýl ÌäˆîÓ|q¾+àa@=ÑB·ûCÉæâ·Àng”Céú¢é`Á#³ëÜ`°ûW<ƒu›kB|zw&ξÞî§°éHDÕ“lþQîîáêE‘ÖBô ØâÊ$GÙè/ýžºQ™¢È;4úuŠô±®;ت;e_Í”IÎõJ êYyZùÕªN}­³ÙxÍ:O‚:ÓÚJŠºÄîE5¥‡½E;ä<@PÅöàR³ì]µƒ=Ud;ýZ-q+èÙV ù ýŠ’ Û:}A¨½úëæ7`}ã$²TÞ‚Ã ŠAì“18”‹§pØÌÇØòN1Ée'¶¬ËZÂr–Ø‹W&ˆÑ”È›•±uÖs~GWZÐÒùLí‰O.T:£8ïªÇðØ+KÀƒãÔ×¾E:ƒ9€8¢[”+!5Ÿ ûzýFe-Uß9r…v†Äp‚ëmb-Sù’塽Êç¨Ú‰OÌ•ñ­é² ¯µULsªì ÆKÆB)á`÷ñô³˜wÁœ Aè˜ýÐØµ‚ãì¾`wÓ:BÐm¥‚yQ€ë\Ì t¸úh:¯EoˆvGýþ7ø»üM°:tâP®=°ðpáKÔÓ\ú>¢Rj%WO¹'»¾u¬/íåbSéÁÒ|ÕÉy,g®ˆÍ.Ìʇқ ó¡¨QîJPäypý¤Nû³ð‹˜ÞW=7a‰.vãC(Ú@×U÷+.7ˆ/¸M¬b#? ›S<ÈÉêgPÖ¢¸;>}y;ø_Ò7=¦Â‡Tf—ñiLƒÐÌL(.kÌ‘Å"2êÙõ ­½2©ü¨¤¨ÁyÝլ䃹¿q[Êsy÷N¾;®¤ nA$¶(Ü Û‹ž¦vÜØâŸX×°¤Íâ~.©±i‹Àß6tÆnä©kéáqZˆ@h‡èÏ©P/JPC§°Æ40g˜€Õ @vpŠ(PžPÔ´™€p¿KÛ›¶îsÔæ¼o’\©­ôü`×ó]Ÿ…oú€*jź ¤CâI(ð'¾Ê™‚IIÝhSp éeró^Ní¼z²ÚCx ”«iÌHWsWGH.“Í çä0ÐËÑ` ‘Öyå °û*ÍÁZÏ$¨è¢˜à^¯ÝŽ­Tgø åÚ¸²imÿT®d˳¾»¹ÇÚe|Ö6ï`½nfœsÌÅ2 œ_¢»B螀LKÑ ô´9Â÷ÚŸCð”s¬,ýC0§jéj-3¡âc:TÌ6o£‹~YV®ƒ¸‡×É6NëWXé/O©n¿_sl݃ö3uîªÛ–½t‘]ÄÅèEÑú m[·õÐK þÓ§dAŽ€#{Ö€â/òùµH\ê>cte¸g=VhK8M.Vº2ÍÌ—œöõÔ×¾HzŒÝù/¦¯¢øê›©dŸv…‘9ƒÓŽË­W§¦|ï„róŸ+]¶˜û¯^– ™v¡³2’%›ãÎÊáò‹ø_EšgYÜ È5fhGµ ø0àG:5”Á8Þ£V¡zκÁš®®ïõ=`o wØý0ENDZê„î=ËõŠ>ÂÕ CÑWù ¸‰9 ›ã6qä8ê‚óý9„7‡@AitóŽižÅÑKþ:÷[Àå)e½`vmc\òË9 ¶ÛmÀN?°';-ÁzÉéæry(ŽpÊo ìNjpkÅ„¬<í&<Æv×+Üe}¢Ï•¹æ*}­}§ÙGM1ŸµnæŽà×ìCVœà©Ø).q¾t;:ÕJçÊ vI>µd¦ðAÁSrÏ÷B87B¿Eƒ’¬@)è#C½°¼i¶Ž3Äs{Ò%ò jø=±%y¯Ë™sÌϘR+`¿Ú›2=ª,÷%ß·)W¯W{Vïyñin¬5æÊ ¾Ì¨yy]2Nd>O“Œ>¹S™˜òZÅ‘ò‡¢Tó©BŸž#/œÇBÏ» EµP˜… E*”>Í2(Æ0(mÅ%(Ÿ‹ÊR¡$‚±P>ÖÖ6pö™S@~d•ßÙ­@6r®¹ÀY"Uviñ ˆÚÊ÷ •ã@gõc ÔàܬOu’6ô‰jB5ñóåÝŠçI1•šîá²ñÁÞb¼ <Àwú(¥ Må9ñ2kj\'ijψ7 ê¿iøo„0›€­tæ+o£ò¿ûÐpX-gQ,³lú“À9Ìf¥œÀ86‘"Úó]hF2½™ÁD iÊuÄÓ’îœ#Vt“_à¢/³hÈâ ÚÊí˜ÌO¡1U>r6]@|#Ú;¹ 8„‡lªcSÁO’OMlYÈy•]HÜ´âzªq˜õb%=x”3ÊùÜCVRƒ aS™ŠJ¹FÁ+ÒñŠ!l¢-#™XH:¢!¨ Àn’È–ýÙ,/ËeR/!³·Ha<‰ò}^Ù<‹%~Ñð1ø’ÁH÷!F. ëdkàð Êp¨Ém(t}ȦcèK1Ÿdâ ÊÇ@î  8…D&6d²ø hÏfÉüÎeù kØLWî`7Ó±¹ÀATNË7€Dù0Ð\,n #šñО—ññ†‹Áb97¯ËáJoÞâ;d™¸Ä8n櫱Tþ‰¬cùòc’Å@ñÒhÍ.„ Nòm 0x4j ‰åþ®òXÅ>½0ÜÜ|†{JÛ8™Ô,ÛâšÅ>åÛê°ÜWšöèƒÕm<àª/vó½fÉ/h¬Ž Ÿã’Z¤ô§‹x_/6ˆÍF¦5†OõÙ†ùþZfcrÅ6s)akƒœŠË=ÈÚLŒâ¢5Qz–ý<õk{"Ѝobå; åŠ@›fÆã8éŽ@ÈïÔÛ®ÇåHõéêjó 0g†êBEЙÎ.÷ ðžöXXÞ•”£Ù¿‰ÝÀk¢78ÛœÀX¥Ç€¾X|Ö§XÍ]!{äGæ÷Z.qy>8Xû–ÍÊbm=?X•A\ߨw¥ÚU}›åqu'GÃo©ÿ É¥dȦÚ4FX3CMp¬= Å®©N„н%«Áš)žk¦¾ìï‹®‚wµw0¸¶ªµAßÄ/ìÕkS¤¦áNvöˆö¾uÖH–«îð&¾#M›!¬sFsÉ{ÖÌägm¤µS/³¾FWÛO‚~2üŽÌcQ¼ÉÎÎhcBõYlÝènÍr_ëЫœvoz«FõV I>^ó“æñ&ð72€®‘<JgÑŽ¯@Ô*kËSÊíMyWíZå+×ËŽÊM†.7òÝ+7ÑÜùMkŸÌ"[¹ˆ‡<¹SΦHñëÅO(¬£ŒÚrhr[ˆ•+íIrnäR´S ùÚ6ÅV óñ«ìª*Ì´k‡ßÃ’è^4'Ái öcΰ÷(/‚­HìçYÆMF0Ÿ—ÀÚ-ŽCx¾q‚ýÂ# vMí¡ào’0ÄMæS ´¤1hQœq.t©/w5C¨ýÕû(VÓùjSy–·”¯ÅXû7Ú)Mí{HpYŸQ ”9qØ»Ì>Ät¥ÌºƒîN+§¯kãå‹„õ:²nõ€1œb)a}‘u.N9«°”Fb5«ÕgÌF<蔈SÎn5Îù’eÌâùŠøÙzœÏäÃÚf†k;¬»•tÆÚ[y”5ê£<¢D‰bÒ”Ü$d ׳ƒŽ¢‡œMQÊ Üd;^„óº1¬žE MRš€|ÉÊ{œþ3ˆ“Üv_¾§”;Á®íþT)aÛï(ÏaËÛ¹‚Ë|J©Îãš‹21Ay‹hÛ¿sÑX]Çeq‡2›‰áÕÚ;Œ]Õ.|eLSå^ãFm ©ö(ÑC“6ýí¯ä"°·¸z€µ×VÀ¾"Æ€s¿®‚õ¢u#„»û@4óvóÁÐb0¾(ŽÏxïNP{:@qY}AŸá~ÔV²!¨û•|í î’oƒb²ô`«"Pž©ñÀß`üú˜ÙÃ*FÒŒ¾Ì#‰ƒ…@©ÌPüÿÙÀ²×Ì*ç‘;ÿ'!¾ÿެ*Ïüw?.«üõ ‘Žæ«ŒMÿß³€HcÊÖä×ò?Kª<Ã@E•ë¢ÊÑþÓ¸ÜSåºYe~‘šûx.Tz97VyÚÒ*MÀ@ã*÷û«ÜÿïÖíT¶•EWOêŸÞåÿ)T†Ôç §*W÷?Qdåžà+ª¼‹ =xoÙa„«ŸCÑ¿ôtB„£+€õù1øGÇ<œRvÈêÔ •Sb(ÈûœùP–V´\K=IH9ÄnãyÊ×Ūi FˆÕyà‚±Nsûk>¤–ãça¥-˜¯&:Q ®v¶ÓèXÊÏ@¹ø–öxY!%Vl‘MˆRNȶèL*%b15ePH!6ÑÐYDwÑ]ޤ¦²Bê œ €ˆš`…¿çsý“Ü€ÅUà¬Ø L™à<¤n9Q>Æõž“þ¦ðïê{kИ†\æ§þæ* Õ_\1¸¶“#kàj•Ý‘MÀ³À5‰æÿÓ3ÿŠ–‰|£ý§û/coâñ0CÞ <,â“^€^ùͱt$4Å TCFàÕYHîÄRMä¼€+äT¹â M•QD®¸ª<3ò©\. \“âéÔ 6@¥—§þ›ñH@"Q©fÊ€ xA.û@<ÇmÀçX€†‹Gåu §Ð˜%B ZSèÿ'nýiE"w8UF÷ç79þÿJ_£Ù\†Sý¯DÞö.ë(ݨ> ž›Dˆ™T@x¤ ö7T€9Pö‡pS’@Y+úòn¾‡pbŠ\Ì«dÊ+$1»rŸSîlaçœNâ+Ù@öà¸8樜§½Œâ2Ò~Ǿ‰*F{$ ØSä6pú(kÀ3.zÒû°¿N°¬ô(jØ®ÈÄQ’Ťê|ˆ¥ß¥¶Æ-‡Ë®<È#Êr¾sÞ’ß“¦ä8qŒv_‘ÓxÂéÜN´²VsÏ¥ÉN’xƒÔ(â:Ö‹C/—kægÄh þióGLÔˆÐK©²ù#f¦øWp4ãŸõkFhgšÐqèˆ`.w’c·àV.8ŸÑ†¶Dãæ²ø•|fð+Ö‹O©-¿3ðð±XüB š\NMœåFLÚÒ ?ǘ-zrÞäOqÄ0 àa\”pÉìâ::²Ém¬Aˆžr1XÃ-ìD£+ë@Ü&îå ÐŽm84"‹ µÈ§€8ʸŠI!?¹˜)D#šB€$ŒAD]Ht\”ࢉbH@RF*:)˜Ä“H1©$SAŠh‚Ê&ºÛÅ­Àaî¹”îÀbî~÷€\A`×#ÙMmNSŒ†àI@ã0IDbC,P‹ó@…@W1iŠŽ‡³@ ,ÀÍ9 ° ©T.*@$ø)ýƒ¢e Nðcr XŽÂlü€@\”nfkÅÓÀ%bþિF6¥øèã4–7 È™r%ß©÷±ƒZ¬ç€s=™ЛYÃÑ€_åãe7#Å`†Xdðˆ(¢‹2º¢È]K´™/G%â[ H}`!­p€ÇéÔ¤ ˆùØ .£‚,÷(’¥€÷ƒXÌãVþ34üå,&C‰.ß‘¯#É'‹E|ŒŽŽ`È%r6P—T@â€ðáù#Ë€í¬¢IÂ!Œ@CEPLhNà>nbPN 9¤RÊ!ñ8u¸@ ¯a£ÈÇhȼÏmdÓ ÉFåÄu –Ãô*ËÅ#\,g•p“èTÉ?p-0ø$UF˜HôJ˜³Œß²›õ–e†[Qx—LYGÎ媫»GpI}P¿,­Èó8¹ü(Ž’M™MF¥Œ‹¸¶yp“*e6²#ÀQqå·Ã5ÉÑ\ªÜoUùTd7*Uf‘Ò¾*W\ÈÆƒt|xœ÷ÑhÌ¢9¨DKˆCH*RŒO"¨MmtŠ)Æ#7ÊDó)sðÉ·äkÀÖƒ¬/= æ‹oAd‰ ˆÑø‰ÏAº¥ *¯ÃYù p”C@Bån²«Ò6.êS[4ï¢Ò@žî÷lêüL÷ƒh.?¡‚çù†ž >.`?£w8ÄÒœš–_¡ˆ »9!¶s8À b[áð£ü8Å6àwJ±éC4Ù´¢{H¤Œå²¨'Ö08~§Œ(l ˜@`²’CU¸’JîHøƒ7Ê "H‹JSº/ñ!9bmåo 2© èDq-!¯1€ˆØo)X@:—i <Á@pÆŠ€Oy¨Ï-À«$‚xõ§q…2à;bAdá€|›<—IÅ&PYLòxœ ’ai#Ä)qDù‘²#qäаÄbÀn±I;”ÈÕ(œàà¦ÐZ|dÐ8‡|,;<ÎV·Š¹@ç 8ãœ~Àn²)` )Ÿ‰yHÀFãNî C4ÿM÷çÿHX²¶|¸]JàÆ[øHæf?°H¦.P‚Ã.Î +g¡â£K©ƒMwîCð¢0À>ÖƒÜ!×W8ÄÑKŒàÅd•œ…î|$Ÿ±ˆáÀ“Ü ´¤ ¨Ë)ÉzÑI5ƒ W.#‹^Œ¡Xü$?eóœC*†ÃMÜ„" äuY€%*ärqœ¯P˜ÉR‚tä(;pcó%×!XÈØr5QY‰V!@Fl¿DZìý #É¢›ÿ\•ãq@Çò E€M*ávñ/VµÐð~|@4Q@.®ùb$¬-íD'Là&t* Ó@ôÅú¡‚x…y¨òë‘¢+‹iÂ1 Á21]ác“ÄÇXrœØˆ`„üU)ä ºñ ûqäH¾àL3E^QÅ<`>P“Î wrDí3„‡ØÏ^Ù‹¡â5š3ŽÏˆg +‘Ä“‰`¶¼xR,îƒ|¼x*õ®¨Ä®éº–äޑ͵òÇÔ\ :þæÈ®|ÿAë8”±7ðОÀÁ”kìkWi庺¸¸Ç€÷±'QùW«ûß%D4~1à ð%±pn$NZò4±@ø ñ±èO.†˜B—q—Iš8„¥ÒÏu™S=nbyDKº5q/ pÀPV‚)mDNµ«Üñ 2p€t@¢qMÎGüÐt, ~e0â'E8:"¯†×@RŸƒ*œ@Gð°dÀ pUŽä_=ߪÞÞ¶*ï§U‹¼Åˆ=·ñàÂ×¼®÷*WúOôï+•ÜKˆ{o tžã,Ð;¹H>P ‡DZß-} 3|Gé„9!Üá´’`)ïhÃZ}2Š˜¥ƒâÕî@¨Ï¸ïÁ⌽‹TÑ^ rÈ]Ÿ‚¦øhJ&‚7áÆ¦q|ƒ '©F ïQÈZ¹¯ýVànnWßÇ' û+¢Ä1ûY¼úW±'IfŽÞ›ãÀ÷üÌ=´ã aÜ'øUsÅéÎV„E_ü¢ÉÔâ úÒT,%zTÃ"Vœ¢”6\&b21ÐÉÅE’ÀÁ¨$"áÅM‡2t¢)b `ã#€D§(LÀGp¾¶)qaüqîF¢ÒtúçŠU]Ôp•ÿEà³28àB• ª âÊñ> ˆ(©dí,‚ÄàP‚‹ a<€EM* à`¢c#•@¼E˜k¢Ë]ɨ‘‘›€^e®Jnqä,$.Ô’lÜ8²Q³Èá8p¥¶=,ûAŽ!€ÅCÌ@u>åyja‰™ôB£V²’Ÿ¸—{+!ç¤*#"ˆ"Y$3Äc8˜(Xèü†Ã&ùAù'päk8Xb<~lîÆƒÅ͸°E3R\Ô!¨Ž ˆ« øqáÇ x+UȵõvU 7:¶ˆÊñáPM&éè˜Ä¥¿¡‡°AþŠlB’€%—‘Á:9—bY æ«ì 7åbÕ˜‡—7x‡gH@!Š×•ôrž’-ðÊßÅ`„x ],¦)0‹Fq?>têP…Ú´ÀE2Õ‘x‘8(ˆ?²Õl@E`c¡TfY(ÿê2ÿË>øçø¯$ÿtU5bVòXäŠ)ãZ~Dn@'¸ñ.ÀSÀ01q£#€XQ¸ ãªÜÑ‘oòà qÀ®¥•J¥YŽƒ‚I*nNÅœ‚œ.’\¤ØÂY“1þÄcËÖ´F•{YÀ꣓y‹~8|Í÷|‡ÞÜû7øšp;Ó™M7ù>7ñ<^$R.A`‰'àGJÁù™s säUg)†ˆgIžã×À°ctZÒ¨É ‹ Ä`?6P‹<@bJ“((' (%È%8Oçh §°GÜìæàn¹FôE²–‡,¤!¹„›ØÅQüÌ# ‡Å4DCßÄ6 6 TЀ(J¨G˜R갪ˎS…Sü@ PN..px‹ÈþDlNˆ2¢@›Äa ˆ JfãP€‰BpI ‡ï¬ë¹Êí$C3ñ§0Å"$šøš«² ("H #Ðn &ð‘ xI&º„rq=!‹€Ý„€LÑœkø|¥¡¥`Ë-Ô@â%K$h$‘ˆI€dT~# ƒlâ(#…sì.PÈ!ØÉJà´ÌÇ"S4$_^•ÏP&n£)Å´ÀD¥%¥Dш/8G=<øH¢ÇPå\Äd(eèrðƒlÊaÞc!¿s‹”yLyŽ2Èa/)èæ#riÅ3ì¶>«˜F‹ò]Å·²Ý®c¿L–€8í FÍ'GÄi“P*׿GŠÅŽ[}øds$)cqLÂÀËrÉ®€‹øpdg¼¨ÒKuŠe3ÒÙ-›áfwQJW¥œ¦Ü#žç ©Á.ÏrÄ T_“"›T ñ -ÑB ®Š—pq‘ãxɤ+Y(¸8G/'hŸc%Mˆ ìBa+ù˜ìF£š\"³YM“EK1Ud"¸`Í PB<Ÿ éB ŠiF^QˆBs.’C:BDaò1y;»Ñä(yøŠ\ÒKŸ,£cêxé¦Ì'“®lב(HŽ!qÈD âì \Ÿ÷ZQíì0Ey‰Ù •*M•ǵF¼%ÅŽ‰ûAŸÐ•s>#f?õ=·F¥¡»ÏG?‰¡ðGðµò(PÊ bh\™ù\ Ào@%$,ÒäÉ»ŽjD•óˆÓÑøUƒ‘óV"’½ ~¶®…C#ÎKC2Ø4D dzrÈ)f ÂO@´äAÎáaNãÝ8+—Š#\âG:¢cŠŽ„X/£D)&„Ÿ‡ñà!LO¸"¡jBHÀK4¦”2•<€Â Æ‚x_< ¼Às@ ­e€Z)kþ™T£ýÛôš\kÐ*õáÿ†"{â›$£al ,½Š|­nL'‚4™HTÀFGàÀ‡ƒ‡hâÉ£ˆÓÌ$žR¦QÀ{r >ù¼ŒK抭Tp›¸¢…»)b ‚ŠÉ§MÀU¹7%|‡ ‹×å^lÙMLâûyŸß銔_)ƒ‘JC© G¬ÅÏ!zÝå€ÅÊÑÄcD‘O è…b/–CPÜ€;¹•ºâ%¦Ð•‘t¢=ݸB* ìGИƒØ¢ ǰiË trAkù;Єó@#\Ä…V‰Š®…M"éR‘4²ªU@y•¡a ²kAH*gDÞWMc¨ŠÕT%WþœG±è*Ç íFlùHªyz•+?¸jM#lt2Q…Ë¢°—ÖÀÚb²Ö¨ Š5ík´pŒáLMÓø†˜”÷”†$ÇÜÏ´§#9…Qéº]sZ" õLà˜´€ße qp£˜K>‰â!`ñ@küüû¢V§ò©þ Ìýÿ}ŠÌÚÂô?E7ÿY<ì0"YI¢\Þ‡Â&”Ç€º|tÇ4DÂ1ø¯e€æ"è@2؃`Ïßo+Ù'µÿWåï^zoähg5¸ÎF5¦ÌÝ1y,Ç´/õbnS·ûQ'~+ÐÜÿ àè{UDQ¤Ü/ñÿíø‹Qö«û‘Œ(­ƒ%Ÿ ~ƒâYó'ù!š‰töû†þÓÿ3b]5÷61X,—å ]¼td ’æâM*ð³‹ö¸Q°¹–÷ÿÿEª*Êp€É„A>‚ è†Ê"9˜/^RD(f?ЊX ÇFRµ2‹d !¼„ñð!›å†p‡8H߼圗«Ë'²@Œ®}gEøoŒ³2ó=x´ 12wôΟ°bïO?†î*> ._Òt6©ç¢6‘%z»®c:뱸n•nļ¯š•ÉØ T° XÍÀïògàG€"Ö›xxšV@â8Ñ H¥×¥:€XžJó¡ji4 *A„-@1EX˜$’h\•9@E@.—^ù A$Sð‹7{yèHK /·Æç¿‹§qdpŽ3@}~—…ö+ô²fÎÆ6¢óÓP•Js¤çñjbMô`Î3ŽáDQ2’©C’f€¨¬0¸ö#2Ô@+ø ˜ÍkÀNùȬ2Ù l’€Îbˆ×¨ÔÁ’*C/€N2'Z±•ûþ€WÀ–{0É¥…2âPÀy L®çYò%Z)´Žñ PS<$óR  &h A è \Ä~DAÒ¼œ&0f0Ÿ–”2 I8pÂÚ˜W;¯þeJÚÕ̳ûàâ–“Ç ¤]éM üfÞÕ~«>Z«ýºN;Ô6ç߬Ö"8ƒ²-€,P&¯EXÀ%4®5v» Ÿ‘€ó ,RƸ…‰Àkœºðà(UV9òïzÂdñ8nY†D'¹ äO”¾Ê¼±À>.mXüÊ @j͈ª1ø$2èD,`sØË~à4€dÚQÚyÔRDO I®¾ÁÚ‰ê úc¥è˜ÄTVßÁK€Cs a(Âñ†‚1÷rmL9„Ò…YÕ ä‘ì{!çì¥fPV3´®VäÅÂåã¹çàü-—ïðزH¼Ç?’æÅ•Bü’èócÔXˆþÁQÀû’o4xëûfƒë‚ëЪ)÷ò¡½¼’:‚6Ï¥(“£A,c/ˆ‰¢´7ü·‚ÓÏ €Ý!tÈI¬ÙIlç^ù+„ß)=á}Q`¿ ¼æ›NþZ ÆÖÀ<ˆi³bVzïø[j …ØôZ§Á» =DØýFq‹: sÿà¯$ð4äB±Q"ŽJ$ýZ=RDÆÅÈóòA 3 ^kÈT †X  ”!ÀµV‚Îb€ôq…kÙå7«/ð‰\ œFGʯƒß€R~#â€B§½œËg@¢#°Lbß5ððOÍ¡P8Î †€ñ‘œhdØo‹åE‹Õ-,+h­5…âõ§ç¹K¢¼ü`Ϋœ(þ5k?¡À¶¼]xÂo¬çƒò»A›ïšÊÇîN œÕ»ø”Dp~ gš½äpÊÀNµÒÁ, EÕÐ>¡Á•* d@ðþà¯PþRù0(½¾ì~(~AªPöQzr¨x êçèbHl–ôØÉ%µÀ5ßùÔ'Ã7€6׸ô_8¾)žúà™àIwý=pÜ·€š¯í½—¾ÔÓâIP.É)Àñ9(wÚƒL=A¾OàY¦‚}Àº ‚mJó{wkCøá—ÀŒC ˜an…ðÍ †Ð#,g¨âuSÔ½à¼.6€¦ÙqÐØë‚T=.žpµýé»pWÿ m)ÉÅn–ͽOWÚr3´îlk,I]èLAÄW¿'cikȈR´F$«Í)G#@‘Ü»ôdc* pØ)å”Q b. ¸¸žn@ Q€Î#€OtF¢Ñ A"Ð4$ÊìKq˜Tàé¿UÿxÍOÑþCÍÜ_yDV%ä÷aʰ‡ÊЀz,nAÖÏÙòq`  üÈ6Ž+é ¶WÊ’kiõ2dM¹ì\q®S¾5K“/” â¼eåì K`C~4Cƒ¥¥Ã1ŒÛóF¡zvy7òƒïå¤ ¼ ß[È ýµØ2,‚ÑÍðAì%yéþP¼ŽÐw‰îH=…G0ÕtøÕpÕŽÈ‘ÀNy ð³L9•Z ZŠ =0¨M4:>B4Àf/Ïy":òä× çŠG€[DoÏÊÄ\àotÿzCΕ³qŒå[lžÏ2!Ø€¸ ³éÆÞ¨'íͼWÂæG™Ú¼¯ÎäLeo‚˜?=O2Óy[î“]и]¬±Ž!@1I;±‹j|Š´¨ä àÿ£J:b Üh(x€ëß4-ûŸqòFÀ]äÕ‘@A &°+¯X@ Ü€§Òwб±È! \DAÃÈB9(@).¿£ŸÄbð ùò-ÀápŒ£„Yï(,aºœÀóÀ,ep‚  ~*SÁ%Üø¹L9or†ãÖ,î ƒ]J(ÐMN~Þ&ʹ)ø«,Âñ}­ìC‰{O=QË„ʃ”§ˆR8øÅY̕ǀb01@²˜‰,£D²€®¨@s\@+|@ â€T¼üïš™˜¬ãÿ}+"³2Ùò?ÕFòå#á kþû?ƒH‘ìõ£‡¨6b»‘ ×£ïR)ïAC08.[=x ÐÕ<`)Ö•È@$,¬!±Ø › x(#Dã"¡‡Ð»ÁNK½ä\,ÊxE¼+ 0‰^@{>Ñð1ˆB!]Ô&¨ñ7¥ÓµTÏWkF"¤#wUèU #ÇÈ>¨ºã"øVUP;r%"û#)¦yUžÓ·RöæZCµst$lûE)nÚÐLŽËQÊú*o²¬tñ²¤8b¦%§scülæÃ„GE n‹2||M4з2ˆ ¸I&9^úaˆÙâ{4¾` ……WÜN…;1tC:þ!ÙªÖÈ_#YYƒdów%OäÝDP¥¿‹ýw#ùßÑÿýhªÖ:ÿ³³‡òv_XO ׬ò-DaÉ¥è”0ø]ξ¢ÈT^~U @ôç)`8aÀ@ÁF £¢ó2s¹ÕÙBs>¥ûi ôe&’_ø ÁƒÿÒ×àú÷€ÕòE‹ˆ†ðu®g³ùö±.bVþþãoQ–½Ž7‰.XHM¨ÈV ±#eŽ·(íJìî´þ(®“ŠÁrýzy'¶¶€}4Ò~T–­”Yí¨%¾-ÓP]Õãç1B8áãŒqÆM£¡ò‘üR9á>†w{>üNWp†Þ¢ˆ'í:g+6#íGé„tNËšås^á§9ˆÚb8ˆ c€Ûi •† ö§g«²xCá?g@ÿŸHMñHà6¼È[ £8rž\„ã,À¢þ.lÎ(/Ñ™¸Àô£6±ô:cq‡ÕQ°œ,:‡$„Âá0ZYSëFÞ(\älåtþ³ê^Òs6%í ýÞ|¦3J)ý[sdF?½º{+N Û–É€„Ï[ÆAÿ-Vyר/Éý>%n¢ó†ëÕjacƒâ«sٺˆŒ/åG˜)GÉÇ•rU> þ¹,÷f¥!xŸ7€»·h Z;Õ®#J/P__€rZ_z,-€äýÀá)þ;@pM}DÞtS ˆÔb?Ћ7ApRÁ9n7k¨cý»=ÌÚ²˜œR—ï€qHÎ‡Š“Ê w’àäˆ1ÈÜZºÂÅKôLÇÈLQ~$6¯u¨³•~ox îNœß(­±ƒb’RΪ.ˆ?ãþb‹=õÁ3™ß€u´î¨ÌõŒÀ\!¶#ðP‚ÅoÜÅRû›¨ç\’è †âÇQŠ[Q˜"Ä ~¡+0‹»¸–™ÿbïØkt+Àݬéb Èž”#e'1å÷ò .þ!vr^½Dg戯ØÏÍäs‰Æ$q/ñ€M 6*’ÀvšáÐÅj Ö¬Ð+d—7³¾”çJ©#.äæèw1 kËÔ1®*šÿv/{ÊzyÏÐ$-áësx(×öÿýiÝudl›Ý{2…I‰™›Ø>ý â_¬wˆŒ¨@.Òt7¬“áŒUžHùÂiDZ„§x•`ÔJ¡â§¾ þ·DÐo!XÅÿE݆[Q}ݾèoTÕÌaå¼9gP” J * ˆJ0JQ‚`DEA²Q$ (I$JRr^ÀÊi®™ç¬ªq>àï÷ìw¿ûþÝϾ÷žÓ?¬Oëyæ¨1Z1ª÷Ö[Kzü ÿ“cþ?®ø~y@Üj¯ý<òq«²‹p««æŸ°@þW0gC4Ï\Áße7¢þ!¢¶ÊgÔßX_U)êÏí¤ièÁK×ø¶jô'íÊ.>„Áààû„ÓnèÅøTˉôuæåM6º)áÄEz’ÒnÈݲ>ì¥êjÐÎèƒÀ¾FíÖǵLFh!Xî7ªÀÚ˶ôåpLó8AÛ¡ ݨè JY DKîó~Ñæ$˜·°º@ÿ‹Tâæ”a1Ï+߀:3u1Ä÷Ä[+°Œñnõ‚}&X—'= âcqDok*Èub˜‡D ôèf½5JtQ¤5J´WIŒ¨˜Rð*¶Ä,ÿ ÌzAŠ•5ÚA|lF•£oå:kÍŒ#UÐ|b¸½Å+Æ.¦Öï¥ çlÍi–]´I{UQÐÜÂeº·Êöºm°; Í>ݹ”rQ “ ” ©OÖß,Û[é^…õÀ^Ž9h@b€Ä j°€aÀ¿Ço%gn‰h&ýãýÏÂ{ å* üÍáýÞ·¾Ñþ{JîV"íQ  Áu°߬wÚ€IDAT *ExA"ø… à©ÀI2ˆá§%hX8-psBýøøOñ›ÿat·ÒIÇ!ô˱{Ë,ÿ¯±DWVj-ŨŠÛ•cLËÿÎZNåÙwÇÔ¿>³N¬H½ÞO¼TT£Hc˜ÿ×È8brbô„ã.¢yw¡KB7÷,öx³’¦:†¤Î‰Ôó3~ˆÔ£OzXGúC¦ŠÈ|†2Hí%|ôŠÒ†)KÀñ9`馶{Wµ,›ì…`)^åm%¨õÕ;@YÆÿÜ æ cÈ»âs!Þ-ÞbÍ(Ä´ø=^/wCdšÜˆx×P¥?1µì¥ Üb©OúÕ!®$J®”9ÚòŸ•ãŒ%‰ëBí¬4·ã¥¦3#m¡Á1|ÜQ£š/÷%Yc⻄}öEÜí¼ßÝ›LK£ÿa`ÿw‘ƹl2§²‡NÒFOŠOi@õ9‹nTÍ©n'Ÿ¿ôâ~"èäD%`9 Zóöÿæ„Ý’r> @& ýüK¸ÙÅN@•¯pøW±º@Œn‰3FˆÕ4JI ‘À5’£€` PÀà&y@¾< ôŸV^ù{D·¸ÁnÎR-/1oõÛ„± ¹2°9z¯ØPý£øŒY¾¥Ê£PøºòWνnÛɤó}”jâ…߇k3'2=t€F9F¼F“-êG¨µŸ¶eAnou$~hy\»,àÜâ}cEmàÈ-7:Ü÷æìæ' )r«'#F}`9gA>ÍÀí| ²›\rÓAÜ*Äoçe½I&‹v@{r@ô£Ѐ à1:ÈRIìÿ0…­ÿRÕ„oØ œàÈeì–sX"‚Ü‚xˆÏ@Nç&Ð) >O€ø“‘ ²è‡ÁÜ‹Ö,AýüÄAà~ºb`û»_¨Äøÿ…ÐUÌÊ¿ŒoQ*&è&Wó_Òð‹1Fl¡]ÍÌ‘¬NØi¹Æ/É;œ…tö<é®Íh»Ý©QGÉP P)àO ‹æð÷~l[(ê‘Ì¿Dƒ’ ¨S)¦þû“?Uû«¾€óOQm!’¨áÞË9ù£}§èMgËêxNÛgÓ«"Õ?©‡Õ|–]ÜO&“˜I7aTzp/çYÇìÔ'ƒ™;L,:H¼B²`ÈvlÙ†ŸAž’ ħ œLåº2•–œå{ŽÑ‘0׈ã ïß-ÉETnRH3«Ñåžð&dðÃð7XÊ67YUÒR£q™_ùP¶¸ð6@œíb;­Rz˜dM¼“K=†*5©k}ï?ð¿.td¹±4¼Aª×ZþW×ÿªæÌb:SˆYÆóvlaæ "š¸ÕñGâELo§Ä еv¼ë´w”Ÿñk°$¦}§l&Ó’,ÒßRKt§ÆsÊ2×Ò–,ÑP´åšòþ„î9äñ¡ÙS=?³Ú:Û-ùAyÛÝ„éü¢Ž¤>+9ˆ“½Ü‰¤·”+ˆ¡ŒÌBc¸*9 ,' Äyzƒx›ÀË4ñ¢ht§ð)CA4%˜É` FPÿ>~þÇ÷ç–/p+À"~¹™+ÀG¹@þÌäÈQü <ÌQ£(9•Ä”ö‹U»(n±ÏMÀøokIA1.Êè|/·FÞe‡H¯ÜOsy5Ô”éú¤P‘ˆ@<›ƒ§j£≲yfù×µÚ¼w±§­Ilkþ°oWB›póÒZúžæSõ¹òeŒ¡»õñî>Ž4رمSص~ȧ²¨¸°ip_Æ&ý˜¾ }b0…7\/ Öw”¥ ÆÕq v²4m>E X_e±¼Dž2Dk"ˆ{éˆN{‚ Úc¢q›\ rO| ȺÆ.IÊà¸æ`óy0ýñ@ßÎ0ׯ&I+ø—ñ©ø#Í]œ‰˜†—¹þ›B—õ‚ãÅ$Ò+â–ÖŒ-ùÀÑM¤á¾Ê­JgÌÊŸìG1d£¼¨öŒ¼çQ’”´OÁó)`/ZLܱ]o‰´%–Ý­ÎOyk¦Ãoi ºÿ)üã¯@¥qÙ 3'P ¥[¾ð§X°»eÖðXë.Ê-£µþv–ÄhÇÈsÚ°ðªà Å»(ïŠ?å3D,»-1ÙÒ9Üñ½ÞÞ–äz5ü’òºsmè :$Ï OC¦ÔŠ^@¤õ‹„¤>±íà~Øžg⿃»¦’ Þ–r#8óEwp¼£Î‡¤X“µ%`Û«_q›b-Ëú6X’O8£Œ1’›ÀÙÌ·äÛ ëAÐ{ÊL0þ×Á8b~Ñ_̧!æ5ÎCh’Z±?ÍuPmŠ®P=AœªíZ"TWZÏC•jë^ÑÒ>­h£»?ãJvxòivó ëˆÈCþÏU/Uº¬Ú%âòý%R¡r…v *k*µ¡b˜º J[Dÿ„|%¶B¿Ù;Bêåº ©cÂï Ï‚¥-íAQÓ Õç=}ãýÁâW«Au)i`Nžù~ì.P/âk+çf0ö…æC8©¼X+Àh*ÿPsŒ‰±FÛ„î>¬¤‘¥%‡ëÆÖx3ñZUyB^óuRsêuXþ _“‰è3Í»™-%uÉgE6³U¬ .7_G—r±ø1kxYÄ"{Ä>¬¡QBcc¬A³c|7ÕÆ‘È^¼ñÌH.7b£bóY^z™¹'ƒwÈö•6Cå­’¦æ6á)XdéOúŵ¶£DÿJÊ-Çvá¥ÜÇâ¾â-™G£ü© /Vx@©_x ¼TyŠ‹òaÇo|jO!›y–HätÛ¯öÇÐÜ–/l7Ár{â}10E¾Ù@’0Œ–zÄóB› ^-ß„x– ñÎb)DÞ”!:™VyŒ»!”*ÿsÞ*­ ¸A”BìI¦€Ãn}Ü-lÇÀüÓÿ¸û:óÀRh‚2)V ¶õ2hËâ'ÀvÔò (%Æ^k ”OyÄ"6€º dN1Ÿ˜\ÊÛX”÷­}¢‡íPʃ€EÚg |d¶¡I+‘ÎïÓ­D•'µGÐÕöè ‹Ñ ÜÃq0ga0;šmÀ8?‰bd¯bç_ ˆëYˆì®n –#©£Ðã§Ä!4_yÑ«¼ ÇýÂ$ÇØ²ûÈÈXà7°dÕ‰W+R6‘RÞÞñ¥÷‚°ékó·Bæîop*»u¨XþUû[E#½NH '£Ÿý’¤ç:kP7q‹{& ÞWK³/ÃxA{•›!·>޽ÕÃ":¯–Þe=®o•uàÂŽÍüy¦qBº~௩—ã;.ûrßP>ôq¸¬Ç­5«}"=·^ùYÖå¥UœeŽwxùNô„!å3МO•+tOh dÕW§BÝö×!û|b¤¿—Ô ¼Ï{“À1Êí놄,ù™: á²ì-ꦬ+–7Å+ñÞßÂ¥þ=²Q˜àÀ 4g ÈE¬sÙä$9˜Ît‡äU Pü b8÷ªÿÛšÛI¹„M@Ù8)N€èÇ ¸%O­¤(ß‚PØ b‰HRþ Ký_æ’n‘V QQÄQœñlŽÒß÷µ9„W+V‰/¤Zþ°¬éÿ‚Äèþüη*ß T! “ƒÉĮֈÍÃvj’§1ÕWîÈ{„fåϤÅäÑÒb¯‡¾¢´ ­Æ½á¡ØZv’ûø¬ÑÛ2I^Ì‹ØNs ªûX}Ý'N¢WµW;¡UÞfÙËmo«3âïO°ÞUj·GÂ=ªÞñüê_RA{<úp“•@¶w6Hû—131 _S5d¹^:Gæ¥|T¾Q$d({ˆVi«üôZ;ÄU´&NKÔÛázrqÿ)o»^&î}>ñ<‡-I0IJ%ácU¦ª»éÃ"ô¿±ò©Ì 8z†yd™b7 A<(n‚‹O@„Å/ °ƒ^܇DGGû·ºâĉÿý¿âßJ¿ÿ¯â–Œå-IËï÷oA'Ž •™"dG^F€ôËÑ`–*p’@é¯|*b8FhĹE𣰕ó²;NµÂçyXRq)†»ò<ñP¹¿"°?ª ª’õQnÔ‰¥`^|L@üõµí²\r¼~ÚûbÿÕ9ÍX^Zžü¶™ ÿÊíáÕÕõâ÷àM»ä½³Ð¢)odÆþóý—y˜‹fmÑ6_á‹‘¯np$ú»·1‹,ÝS¯³ÌÝÒ}˜˜gŠ·7Vk×ȇü®ÕŒõ¢Äq¯ÓF mxõ½”Úç¹Ö’ “eµ—yØÜ£Vóañ¡k¾+ÆZºë­y«Ú-?ái×÷r'Ò}€„:ԜǶГäsÞÿ)½@ýDϽ ÇåXVïÑþ"*ë)}9»¢¼ÅÑCêhs«ö“â3Ó¢¿ñxü)qš_¢™á-ãÓ騡B+ø\—UWXï|Äoê%)÷Ê_}_Yw$×-:C¯¬n7ÚË—R)˜(v%?£¯%_Íoi‘ò>{6 š·9<kæHãODú:ë#24ý˜×šQç\ð/Úg7ˆÙŸ<Äì„‘sYùQ#ÏAϪvöÃj[¨&‹9Œ¦)&8pŸ0Ì©æBä$Óy Ag¹J&yœ$€Ÿk˜˜”“H"gÄ@1yÁÜ t V‘&ÒÐéO²‰#ü?yanA߆ W¹Šd{ðÉbYŒÊNv"ÙÁ;Ø&ÉÃÔF#—ë\'¤5ÕØH%&îÆÈ ÞÍ@yXiõ?@ªŠ’DìÄYÃ&¬þV1 7ÊÃÏÍ?{…Pé±–ZEU–­/p¬£¨j¾µ{¸¤º)¥¨‡ö<ÄŸ7žó”S}½2å7Æ\™’âëë·×O£½êÌ&¥Ð™Ù(6 ¬Âµ¼"Ç:ƒ2&ÙyRäÚþIt"‹ŒË8òÙÉÔvìÕô¯ìñì«‘ ßÚ'„ ívÿ§¼ãè­Ã9wN¤ë<2Ü‹¸õf¤;׳ lEѽ MŽ=Ö¬XsPëEÚÚ,úhÏêÓA½'ºÔv±  ö0;€Ò6ÖÔI².hým¶Õ|”«æd·Ó¨õ€Žb3˜¯ÅÛƒ> fƒØ/îƒ ²(†ø`Y¢õì‡ÀxÃúè¦Í Æríuˆlt} æS¶G ò˜m*Ć;Ö@¬®ã?葹öPZé^ÈõÐN×9ò|e +ÌTß—ß(íÅ$mA~¦'%çÿN›ôzù9<œ6¯øcϼ§j-jÅ«1³û{£dýl¶ ˜ÖÚ•ƒžb·Oš 'õÓ·[­¥F“ðz¼ñõ4MùA&°?[SO#k©-Ù'ìÅ`;«.àVË\ëßvÉÿÿ[­_ÿR¥‹aò/‡‹n,²›á'),BÿŽŠÖ?ÊŽ%s•bnåNëëì,¿ÝºŸ‰¥c• ‘þ"²«¦ÄÊ)+mliE»$<™Ø ïµÕ©ÏqþÒ¤š[hòçÆ:5ŒíÊ~͘™Ð±z•ý±7¸7s(ÄßÊíIªš¤¸8›X#÷E>θ÷“éÌd´öOL°ÿŽÐ{}Šë>ÌI-´ž,÷´ÌÕŸ¶ñ8‚±2!#8[âUÿ*í¹Á—@î÷ú ¬óª÷º5^ÏEÖƒ÷¶h+pß&îïµèp–(eàè/w]çØXo‚½®¹,/Ùú‚õt|Qµ*QÁ¦ŽŸ ¢v0æsµ5˜Âë Jcù*nÑ\¦‚̘—lì†ÍøBŒy‡e¦lËÆ¢?kìý'ãyˆ×ÑÇB,Ó¼ ±ÁÑåÜ$ÚBt€| ‡¬³ ü©ò+TŸ×¦ƒïœuøZ:ª¡b¾3|žæà/KèÑ1ôHøŽÍ‘瓦órl«uolL¹ åuC«©_±&ú$JÅP{–òÑÑ >Ó’¢Iü¹L9ÉæŒñút³gÒ|ã³Ð$׋dWÝU¶‹¯AÂÛ]è–9>Ð_~‘±:pŒµ©Dn›S¶†wÐ>±8¾ƒ6Þa±Ôõ$/QÛ2×ãvä‹b¬®Ÿ-Õàè ;À:Óú,X7£@½©¬m޽'¨™@4‡€·Åã@Kqda$ âs*ºþˆ5•€YoIQ¤’?¸y×ÜÃ_¡–%üî+û³½úˆm¯ÜV½Æº•¯|#\2§â ç.‘X¼3iÕ¥U‰ïà½yÕ{™W zò£×ƒ÷ª=¼a{"ÿ[¶ ÷Õ+ìA)»Ã5ŠÅÕ¦»€þ©Ûíž™B·W9æ£%ü°Ü—•oÑ-Gbá·lU÷ãS'êA¬âùÀ·ŠcÅc¨[ç·g“˜1ï±[¸ÿý¦E^»™ì›×ZM½¢·—MÐ~ oa€Ú>òߪgýãP›D.V>3Eñhü’\ÄÛí!•ÆÖƒóN¸¶)ô ØzGçc@´'8æD*Á:Z_®Zºì%±'AeÛ’øs …•y` Y–‚­$l}ù(+Õ ·š4¶|âJ¼Äüt‚اv äú'zÒV ñÖ–Ÿ!z]´‚ÀÛ|þh]N„z;Ncr›È`÷)â¾9ŽÀ‹ÞrS8œ0MÜ^yÐù{üP(›O«j)q*Ê“õc$WL‹ï†rS›euŒPø• ECX Jÿœ%´/·$üä]jqt0XGªËÀÒZþÚ%¹¬?©ƒ@ùY?n™d«ƒäLTy%ô*X¬Ž ÐÞoÀ\»ÊyË †Ö ôxèD•ª;ÁÔµJ¤Hsd >†c‰ŽŒuyÓæ‡¨É^pœ†ÐþÈV]ÝBÐî#™&DkÉ÷ ðX`Ä/„‡àŠ 'øG\ÙθñäXñ@Z®@šCKuòâk6'Ü®/åQO¡|‚îxä"×ød{]г]c™åN0¶jÛñÆ7«µ¨6²”Í"I®½ÅW¦Ÿ;Ä&¡ch=Å& ç°2IN‘µ"?çóÕ›mÇE·!=ÿ}äWÝ#§qcÆ áæäúîä# ±‹{Ùm´Q6ðx 5cÍvâ e‘3r•ÖÆÃá{…Ô/ÆUñT,ÉÈ#ëØÍ3Áo”ß)ñ»ä[t¨Z-¦óFÙGѶpr^'n«½Ë…zíw¨sí½Ü÷ÍsjøÝeîô9sñ ×(ÿ m2µK²õûàæTq¢ô‰À]ò‚¹FzDG V²wÃn_ ` `{@í  Pnu1Œ$Ø„&~½Z6ó˜¸ô9rÄW‰å „h@(€ ¡0Àÿ@`„+q@ø| }ïüXiÖubhO›O‚«ƒ¥Äêø*°¶Sš‚øÈxTAmP¹b+é -¥„¸m¤‰¢]´”¢jŸhO€u…c2hoXž#¦®÷cZ2œ]±[ï²[ Xg:­TÛæ»Ç°Nt6æŒý´í7Þ´ôT˜¢,§¹dœ©øÖÚu#IÊ7b!e¬ëUbꋎTâ–ÃPÍï;.Ù;¢ã3ê’‰ë+ÌN¼¢ŒqÞGãvËažŠÝãß„d¥};.³DëCƒøÖ&XüOUÔ§…9+¬ó2ù7Oóxò—±íàý£ì}½ë‡x^ ‹÷¦#©òg©wRѳÚ™ÜÏåôÉù*u²s®•²1í››ïJʶÂïø&y` ¥<,Ö‹})ƒä'´÷²ØØîÑ´_©åtʉò€í1׿&KšÅj~§í±¯—+ÑÇÌU6ÙÏš;Å&çN¦ñ³1U® ý3[l¯Aû•Úô´õçÑbžøa¶ÉŒÄàñ ÈGE#ŽA.&©Tà§«ü†r$!ÎÊoùKÎ’µä4cœlïÑ÷̇¸gîâlð!3‰Ëþeiþ?”¬î®\‚êÛ”_ ÐO»„9¥$ê–â6j÷ðIÿHù²¿Guµì_RçŠàÍç”§DÂùΩ«á\RàÒšº)7¯×]Ü)3Rr©º¿6þr#.:©e§/汩»ÙéÄ4Hœ¬©gÕ óõª„ØBcï@û P?µ…óRõ †x>òc§4 {"=†žD¸E°8š‡ö€ëíàR°×Ц€ÇNÛ¤`XWENƒíM_”zp¬/mQ¨T_ô&X×éÏ¥q4ê' Ê@YêY#”3Öh=U;ˆôwA^ äæ0ð ˜acÄÍ5ß ö†X¶³èiÜ¡Fž r¦Bä ë Jø¢éî*Õt¿„îïœØ-|2±ê&˜¼îSïâ¬VbCjùꦖófù•d 3íÛ‚_zˆ#¥oš)¼_rFtã—µj7аö†Üiá†z^úÖô²_½=g®Ot|•òÑ¥ʃµO…š¹ççA͵ÅËsµŸ²ee^»…±™?;Þ3“Û¤”÷£)£Ìá¶U Gõjå=O†oW£RÖÈð¸úÊßå ×Ç¢!'œ*=ܯ¨_pU9*ö‹/ÔYB¡³¶QÙ̽§õC©úÛ„öߌKÂìNßÅEFñ‘š&ï&WÕŒßÁÑ€—A®4€:WÎç3b(·‰G@Þ+rø¢å5d¨AµD~]ÅoWÃitRÖó@¨¹ÒÔ8«OP^‹ÞÏÅVëÄẑZb£ÿ#u—¸Vù5I˜%Ø>äÂ:ޱèWæ&Í@»<³ÞJŠn«“=Vô|ÎUßUM?à{ ð¸ãáø«ñùܧ&›m)o[jéµ’¦Øº”½®ºÝ³Êf²#ãDYmº¥m*ÿ™½¨*‘:¼<I«„Ô»*ºAò½¥?€»_qWðö.ßIð-¤œpýÌ—‰1ïиÓ>'û¾ÈsŒK¹ùŒhÊ ½[R¾±RÇó%$PFCÂÏê>p ;T8ê °ïÑ–ƒ;j}¬…ÚS >£ôÑš¯€*B@âÿ±Že€K”uIs¼áS±ñ¾W¿"ïé- Œ1½?TŸ2¾'^ÙÍhŒRÕœ/PËÝ¢”QÝÄ*_´v`sé(çTº\?`?¥¿äŸAQeŸX&‘ÒÇÙýæÁŒ(ÙU³!”-¨9Êž©ñ3ë+_ÊÚ#— ÈêFnáöÜ 1òú™ùÆåÒOŒôÐGB”ÌVt ¹¾Ë±+å‹üë"/=ûÒïœÊ*¾R@Ó•†¼XS‹4–FNDo‹=½¹Ò—Êä{íÅ2w±RnuI8d~hÛ§÷0 ,?tͪiS½ýÄp†ü“ɪpïõ¡ºÖçY4³¦o-«Ý/ÒVŸãur*žgŸL(:Æ:…êøf«©5?¢nôÓZse›¹ÛXlÞgV-Úk$ª·)?*÷™Ûäpñ $}Êûzب«]Œ{ôþ6#öš,´|yOž²êá]ì°¶ d¡Šg|Pµ8£õDøLs%˜AµØêRÎΔ8ÊĬ£RðmÚqyS§ÈÝôNM£°ýüÏSò_w¬£•¹óä3Ó†1«°rËzN»†É ×—ÆnÚŸ5+1œNíCò¬eJ˜õ”Ilµ¦›õùÑò*qcÖAyQ_.ê©kuƒák|(>ËI}6oªµh¢éæ*®iÓÜ` ¹»²[fr]$2‚fÊçò^F©‘Êq¥6>ÃÂ$ÂázŠJ z¡V‹gž¶ª`®6‚Ù¡uÖßèoä[–3'2\qÇ u#£â ¼É+ üŠâÅÀóáÏèeY\YWNHwšuü­½«=]Š*E—¬>7£QÞÜ‚Çå–Ü{ »âÉ~´hºgNbQÝÛõ>èu»(Ѳo¨u õ;û_P³¥·'dnñL‡ì’—BvRZ7LK¶šÂ*¶²šÇéAà_¦rÿO“;ù–H· ny¬ÿÝf[9Ý?НT¦"óÏ—×$vãTàm¬e³ãDykýiÎ\yÑ|”á×viAâ6;ï’;+‡&Ï•4ËzU–j}=üOe Rž+¸Y»«,¾Ñ¤F¦ØV0­ÖIÞ¿>£î$"W#uÞàäå.5{¸öeúÁ…¹^­˜nÎËe#“³? æue[LJŽ3SI²ìøÏ7–N†Ÿ­F)mcÔW~¸geýê?xÒs0\€×Û"(¨çù \€âú#\îè}àêÒÁ².ºìM#çÀ±^ÿì7b£ÁÒËÈ¡% ­±äƒÃŠ M/hŶÁVQñ#蟙íA¬•(ex‚†@Žø˜¡Üfc¥+Ó-óA>®4ó±ôUÖ/@ÿ\Y цÖûÑîý3ÑÚOCd–m5DšÛZBužg5ÄÆY߆²_PÝÄÓHèϯØoyîâÙÒ> ãYTañ.1_­xWdF ¿j©ëÜWü‘%%Ëv#›ßküQøˆLÊ}½¡ìÎ…%âdú°›3y,}\ {F hï¦G “i˜®1O$D‡ê§l>ù{ùfê{ÃÕVË©‰#åÓøp^®QOÞC—ô£äbIž,ꀳH} ܪRi+‚¨'Çú'6÷vëgàJ³ÎÛOÚaH(s* 5RçeçHcäû@;.Ž¿5·Þ«MÀNn‚ˆ‰2ˆ/ÖëBpmd>D·èÕ|-ºBí¢ÍÀÿTløÌXTšÑ7‘>»ž‚$è³¹;ÖQÛOý².ÊùE+¬Åªý Øueºóg)±$lc%x&G{ZwÚGùêçœçŠ7åî£Iá½5nðíõ¯jõÇwuBND/kõ{â½¢Ôz)þeþÝ饑Á¦ËöfÔãA•÷zè>I9Ô‰{NбxüáÚà9J×3¡ãà4‚óÀÖ"~œ"T¶¢£Á~5TÖ#kÀÚ<ö%X÷Gƒ¥›ÀzU_CL«û‹j ½E™ºßÞ »åŽhm<ì¹Sb %J& 8!~Ut—™æ tyØ’CXæÛwb1LJ°«åç b} ô°-bk,û þµÖbÏØ[BäiK;÷uL€èH‡ ‘ûíM ˜ç>¡6ö_Á_êyyžÕàoìþ Y–špáΛǵ²±‰A¾¨8œtš\k£c«{ЪìcõK¾¼åoˆeÄ‹Ýâ8–òþ²)oÚîfÍÓºËbgVð.W3:ˆlº'·TÏÇ~ðìq¾ü\{Í9È— îÔŠÐî­z-auÕVp‹êmÌöü^]›…®úÁ*9ع5ô(ÅŽq¡UÔq4Š>CKk«hZÚÇzgY§—Š,íiã v­±ñÙJsiÊÙ4­¸ÆQÅ —éS®ò»ñ¤á˜.­&ÇclW¨ˆ½ãÜAV8ÛñÂ5<ûy6Ø×s]\öwKtÒÖ·"i ²zaÊHDUiÒ£Pe&ö6î®|Ô= 82ÔÙ>®rt´#÷þÀ¤ç+üŽ­üE÷%d¬ä ùHÊm–Ä ¼4=uñÄe΋(¶W䇨¶ÑòCžÑöê•Ô²Ìã]n·ug2.Ër}§˜Ç«_ÛCK¥NàE*Ÿ~ŒtG­žÏþïžœÑmEïÂáêûOƒñNôUY®WAÔ³Ýö¬´§‘Ú!m?Bi R¡ui|ªÖ.y\ûÝWQáiXØŒ† †¶,ÔMÛëùÊ÷9ÇÜÿ_§dGÐ!ya0¯gxø%pÿáo –pô $$D«Áùgè3°~¢oçÍÔìXs°Æ4°÷‹dXNXç…¶Ç¿±ÎÖ,¯Ê! òe`$›Ÿ6 „½ªü \K@måº Üܾ¥IË@;!›@à†=¢mm]!ÜÂn‡ÐçžW1cm%˜UÏ»+Ðç<éP]èN¨ª†·)ßûj'¹ˆTú?bcå³Z«jŒt.û€Vô-ÿ“̲ãŒE)žÏp(hF1TX}àý«ÁkZ7ócp~gk Ê»¡±˜ŽRû;˜JÝèl4kS­ ØÛ¶ÀÝ`{Å™9âÍXS g­Œ½b°0°Ä «"2+^ŠTÒÔ‰À Z1u¢ÓJЕK<¶ÙWŽ%–ãŸÊûI!¾/êã“@ÞëZ±îч1dg„Dà0ªèí¾Bfx!èݵ<Ðó-vÐohÛ øFüe÷5&ïÑÀ|‰ö…ÊmEkA. –€¡”~C•õðn~I¾‡<”¨“–àphàꀎ\"`o`;`}@  N ÌQæ, Ÿâ[0>å!ô&9+/¢åd<^÷ßÇ}áË 5æÞé‹e>ZR"ÛÇ?Sn'Ûx]=§ 0îttÃbN[TtŒÞëš Ì »¼ãÅ HÚK ÿ¢ÔwØVÙ'í&‘Š'2{b/} §œÓ%£s>¦IÑÍŒ‡Ìž5“ûfVNw]¨(¬èëú&ôœòŠ:.ÜÆ T]w¼>‹™ÄÆÐ´¤ŽòZøSm—•µŽñƒ3ßå’õKãSL¹,TÑÊ¡«‹õºX•c±`^i Ú sâ Aÿ<þX–iÍAY¦¶†ðÑbïh/@t°éýùDWÊ 0VÚCèJ,bYÿ‚A.D³µE³ª©P­û¶š)Úƒ£½ýO0÷†›‚Úˆ‹ L¥Ì÷Hå{ ÁÙ[É{wK*X÷«ëѽ=÷§,±ÍÚYXÁYÛµ}´šè¶¡ö…ã]½)·Uöá´n‘¯â³µ·£»cž[ò†¥KìGîR×JA]µud†¶ÕrƒëJRl4µ”Þ±FH­Wò6„òJd<!ë€ü,ò0.>è-Þ<¢Ä&Û:]-¿‚üSl#ný̯õ\0 Óáð¡è="Ù®T}Äho9Ç»±KŽk<ÚÊ彨èÈË\‰?2)£Mé&°Í.ÿ’™Î‡"Yñ‡]›Ã-Ã[œ½]·Y«zÄU3c^å~ü}ËK¨Ÿu£pÎô“%ߣ&o/=ËùÄú¥?ɲ„e•ÑÃ;¼ú0ÓÝ©¾¥ìvÖ®”ÃÑP±t[Ÿ‰§¬bçåŸêwÆbs™z.>Šn¢ÿ*ÅÒ4í™Áµ”\«ÿ}ü›Igâû•dÑ¥U·ÉqÊÝf þ”o™g©ÄJ-ÒD¦Š]¾¯¼Dsù¸RƒÛÉSÛŠ™á¶Ê,vĺiåxãqËtW†pëËà+·¼¡û¬òÂs­/Æ^ŠUYFî0:k¯;‰³Ú´ÊÕÚµ}ÉÏuÿÔ^ÍßÒd.½Ól?\™R÷I¸¾·îøXë¢Õ™‹U\õ‹7T×w\®™gs.”ˆFrOÅ·¢˜ê29KLJ©’ãø<[e!jÚ%mŽ„ òZr1!y‘Ù–Òäo”HK,/ʯ:Z¿LT’Ü›«>`“'Á¿ŒW“÷U 'á‡à1DBgmpßèAÌýkè>¬îw‚vp¤’Áa‰ÙÀ}2PìOÆÇöØp¸b `ï>»áë±À2Í(ís=´¥±Ao~ Ê(9Dç˜h¤h Fý`Äå>0®x^‘éØrŠYbs'Äk¹o}šÑÂc½ÏClœƒ`oW#?ã*€P?W?u7ÁðW{V£Voô6å×êSÞ‰TOYÂЊ“)3¡pUrC(9Ÿðjèœï]ÛçÕ÷ÇÊçÙZ2©zRr%Çýã<•”†íÎÆ²(>$ý_24xE,tŸ< žWÊ–A²ÓhŽ8«BÏU×O®’Òç=WS¾¹îQçÖH>ÿ$Ôìzn9ÔþéâXÞÌÕÏ=f¶ËZ7'¦ï‰÷ÿ˜¸ËúF¼Ôý ­FLµuñnŒ¯±Xy± â%oëØ5ð¼ë ‰'õÁ:1:´Kúcl®½À1ƒ×f÷lµ˜öjsцÿ}üvÈ×ü½‡ß{îZaÕg´±ŽÒ;ÏZˆ€ìh]¦;ÍÇÔ Æró/Í¢Uáe‡2ëâvùû9£<',æjéLù-ùÆ%«¡4ˆgis•E‘ûµTñtÄgŸ­´}g;'ZWßáZ¤¶­ø<ݦ¬-{!÷ :o¯9£ %7†ZÔ2k” ÌÊW–NÛ|®zM¢^1%ø.3JÚÄÎ’ruŸa`¯<… –tÊÉ}”ÏeÝœÉò-Q”}§ü€;ÒwR|ØÕÙ3¡ð/¦.iŠ7ýXÉjÎf¦–‡L{¼ì5DúΪúÄÒÏ– CKýÈw%ùFU6¤¦ûö"÷”=Hº§j-^¯šø]+Óû>e¬œè;ÎB{0ð5†u¤#F‚Œ<‰Õ¡E¿ëÚHpYôéøšl®¯å\Ór \MÅ9p|®$€çe­ 8§ZÇKôÕàýÔñ3(}¨U‹üÏBÂyç×`ϰJ`›ôr«ßÆ‹„‰þa3v,ª¥1ÈŠÂľè:™ Á÷ãS!”f–C §ù4T]ÒçCu¢ ¾jQªbJ]ð²Æ‘ÁVö%˜¡c®.¨Ñû<ÒWþåù–ßÈN¹ƒË¤&?næ7ëkþý¹é¼UÚ2ï1^(ñ很³´_z#®”^Éà …g|+ ïÏê.®Ü¼7·{òÊ{Š-7·zwDfûZÇ—Åì¿vE~EAÑ>£žý,奃•Ï¢Ÿd¼ìn]=&¡SÒüÒ— ’~/:ÉñäÌ‚”§MÍ—$dNÊ–y¹h,cÒ–­3ÞLîS4_÷>üÇ)­{ç=iSEo‹þïãŸÕ§ïÙõˆ,~éÛû¿á ÿQ,Îñ¶|‘¶¯ck0½‡”d”ĺÊ5°=bn×Um0ˆ%ú2H*ðý«ð ŸŒf€™ÉS ·b5˜>¢ »¹Áù4ƒè1åEŒHW6£2Àý>ø*õF²]EQä[º»ëõýQa¤ý%¢}Þ.Þ¡qz¬Ü™îænüéU$3?ã<‚ç2~æ3dìâ¹p½„çmKKUÑ0­K.{å(n(Že|P:‚2¿.úZ™k+Aú¼b7±ô»ò·¢¦N»™DuêëdêmúYsGj ý|¯hwyv•OæqorõJ–¤\ ú±g‹Ø^¢Ù˜­°e^Q>€” "Җ؆ŒCΗ!íywgÈy"u FêŠÄjTe‚8Âæ4>ÚÒ„áÀ¿:äþÅÄ¿ÅÏ÷ã'N"‰XÎFgù¦œ"§ÐNôýþ¶ò ’H"‚èߦåÿrU¸Åv·cbblj“d$…RJñÊ|™Ï þâ/Ž+ J‚ˆ()J ³hHC´ÿ f.þÓØf±ý â>ÚÓ8TÙ€,–•Eˆ‚úÃáú¼ê¡òNý.¢åOèu±Ý˜aÖ†‚~ÊŸP°ÚÚ”¥e;Ýd òhJT˜ÕO¤Î’­E}{ßêÕ‰r£àRͼã׺an×y‹¦Åå5þ’CŠk烅{]q‰Z%;qÙÆDÞÇiý¬:“DÇæ¨Ÿ®Žeòã¤ö­fü„¨—ôfl/0(v'YŽa±)8ÔñF-Roǯòˆ¬4¤Ð8c|ÛÙfØU—QûSbe/mˆÓŠqHc„¿VºƒY×&âr(u°‡ÃjŒ@àqKq§õª¢~Ëh™æÊþ£ø ØÚö°¼-îÝ#ô?¸Z¡ï¥f0¬Å²ê žá|õæû´4OðXêKŒŠ;³C–þåǼŸ%ù ]ø³†];.WÔš“ÿ¯×Ø|óQçv)è&ºgY‹ï¡Sö 7¿åíìžÅðRÖ²ê§#5¾3”Õ y¡ðªüÑø¡p™8EVá$R).ø‘5Ì*ìCéþ>¸œ•ó¤,DϺÓ:rÏ8’Ñ=_[ë`÷¦»Ú2(å«„ŸM_˜„^z³”ù)ov—êúFîLè’ÐTæºt—. ìSíS…fhÈ›Ú9íœxÛrÈrHD”kÊ5jÚ„M(c˜ÊT^¤&5éüËh$F>ùœf)KÉ3z½Øßßlv5ÓÌ4~‹O¿"‡EWEWÈá±ÊX„«áQá5r]ÕUO³"Ø&¸LÌ­ø½¢µö{ŪŠ2õÅJwàR·ê½È{¤Æ&轑õÃ;ÅùFˆèµvF l%]•ŸØÏ ®¯¤—RûòéuFr’šíÄ|œ×†º®.©žÐ™Œ눲×r?–òz½¯ˆÇ¯'Ô¹ÎÊKùuóQN}Ug•ÙìÜ•Ü6±v¿¦^ŒxC‹ÝK‚Z_F¯^æN¡ChlÊ£²/g..׈ì¤6ÌzSjø{ožöÏåÃeýÂ;ùåÔõðN>õ=nÎ7Ô ÌÇàC_„6Û?ݱ=ø V϶è~ð.‰Ö—'ج…ÑRp~i öw"σ¥­Ñ b‚5¤×˧‘! ]3ëOú» ן¥©¾ÔÍqÀëÚC ŒAÜš™¹ f»°ôᬐ <“Âl7@?fsþ¡Öb­-c!2\³@8ÉÝbO«S ð¹c &:A°™óUbÕ¹£Uwru€ª—š¡øH¸ÄèŠÅ‰ Y[ñfr+ª :x÷…_Yø>ã—P.W¿•´>á¶â¯¬uÒÊo8œ×ïú=²AÞÀ1­ñ|ÑE±#³¸x÷g®/♌Š»31}nÙÞJ»èyÎ51־ꦶ­ìK¦Tê£3•%?È ¢¦˜åWäYbw‹øbóéîbNO²q€¨ëˆ¼®T°ýÄOPªåÖ˜KàyÙÒä£;ÐN†‘8x[&mˆDbì÷!DL[ñŘ\«—At+[‘¡é|ƒìÇPnøß…U¿ ¾+eåGÊ ÄHµÖg2ûf¹…pZ¢r-ó$÷¢gÖGBJ‚ñ¬umâ‘ð—éߨ=U¹OÓ»ørÎÓ¤ßü«f_Ü—WÖÙÌ¥3÷ÖúM¾zå§ŒV•ße¬3òÏ'Ï4ß6¿×¶ëÒ“D\÷f‰êè¬ fwû}öÍ*ËH=`Îoi3( Ì¥æÛXÌßä:´ú—<›xòűŒd™òÅ?À?ŒónÞºz&²Œ!o¼lüÁωŠ>žeáä…»—0;>¦ªq9Ê7 ‹½ ê~pKÿH¼> ÖÐàèŽAÑQài½ ®üKÁ–h,—âßÖ÷ôþàhõƒe®> ¬WÇÁš/ÂÐÞ“ ³Ö f¸Ë  ¶6tV©ïêßá®Êõ2A.‘Ÿò‚E´‘>W Ë7“2ŸÂ#Y¡ŠÍ¤Z¿éú™±æ e zì6å]´è –¡×Ú¢mç!|M{‚«“ üºm.øí®r~àYþuŽÓPUíy *¥w1²â@r1Â×+q&×+¾N%+*§§Œo–ŒHýIN.Xi9Xý…|†ųq°£´»È'^ü?a)ž-¿'~IáEŒ’÷ÄìžQÖß™œñ¹ú!×’½ÎG©>cIiQéÃ’¸›²OòdôèמUêÉXggû;¡ìU®i¡ÕÊ!÷/¡ŸÁE( ž»ÂÀy-\Ž6ÑÞ`»óƒmLÜÚñWAË4# ——@t =È5ê0“Ô1` ÐbÿÑú Ķ×!úžs „Ç:Ax®óYb¡§\Y¨ÁMÎú2*uŒ‹Ì µ¶¿QYêX®ÚÝ¡ ¯¨ 蕟+gÐJkYß ´â3G™¦?“ §µ_ÓßÅöW<íÉLª›þ4uRë{'`µ/ ÄgIïà†%ÁXÉËJq?MíÝèÏ›W¶¢«½“%—6ÖF¿j'ÌK¬²ºÄÆêÝÖ=&JF`©²P³ ¢~†µG9ÉÌÿß(˜Ñʲvüzþ…×6rQq§°<'ÆnýQiKs[‚ú(¶æ;ÄÕrª•d Ô ÆdéçJ9@©¸_öÑêç/‹nPö…–Š@™_ÕÝø±jšuO°7¤nõ? á$4 üöþ¡8¡Càœ ¶Ùñ…àÚ»¬Ó#&h+k`?â%K7°WÆV‚hžæqY âká¾NÝ8FÌÙ”­F¢›¬Ó þ«­âŠÖ"ù¶Ý©¶5E†ç9ÆŒd¹ö¡¸â®§±øš'ìá-¿’ð5V7J´²¢ªARzTzî1Týj}0p@÷²·ô!¨W²Nö%ëf:G‘%G)Aæ{žkq]'$OÏÙ‹á>ïhˆjd^õÎx°]U¿ëb­/R;j|Š¡~®o%¦Ý!¾Äg™¯|L–ÒE†¸Wxã¿ÒÈ:Ùï‹“ÒKy5šKr{ÌCª¨©h¸ä¹˜.[SÌ!mù©šO]üÎo8"¿Ô3(>Öמ2yÓÝŸÑFIÅ­ˆìA3Úh#°Å?3Æ Ì­Ž1寧€ø—jÄ狘‘_bm±½JO„žcù ¢_@.u&A {,áqbí*>¬Pm E!ŽöB÷ý\î%»½ê+ª†«೦ëõ0Rö»"Øí§åiŽÛÖ+“æŠY£Ôµõ¿vünoF‚ý¥5 Ž­Žl4Ww‹ý´mÇl§Ä h¸ü… ·¥ÝÝqá¿|ÿìŒXz’ö_t 6‚Ê9Ö »íBx›íUˆôu´‚áYDÔ×Ó£aóuð®`Wõgž}ÆJ_=×ÏÑ;ƒeÎgƒ]]ßù.T_´Ï yÕ¢<N¹¢à[’ƒ½¾Åj<›t‰Ì—Ô/äHëW 9´·ºÝçÄ*ñ`¤#Õv2¯—{²½˜ŒŸÁò ^ÙZ<²¦ø ¤G±}õ!ø{ÁQ e#ÈZò>ÐÝÑbM•)`8Åóž82ÕöÄ׉)_ƒØHó Ä•YSÌrˆ­2Aø¶øX¬!pÀwbSâý ¸¨z&Äò„ &X‡)çÀyÃ}’§¦¿®b‡ûÙþ;¦gƒ«+OO×HW_ëK˜ž«Ž¨Ž‡íGeUÕ¤ÚzË{èj‰é+Q­6¥,Ï„a¹5ÉÞ‹–}F*‰ÚF}#ª%×ÚÊc¡2yS=âÈ5‹”Û#kð(_&µ4-b~d“¹ ‡>™EQò'foNÊi¬¤_ìSÙ‡íÑ—Ù‹"²¹›˜ÑP¼ÇŸ–s‡³¿À'.‰. ¶†ùu¤±Rƒ§<š¨g6þ*ΚcÅ01Ç(U[ÓÖ8Kelf$‡DJ¼yœŠ^ÑÀ¥jµË]Ñ—´úÜÎŽO/F*õ>ü¢?RÑ™€8V…Ûúvåí¬¶UCŒÉ¶³Õ9ᨽn,=Tå®pÎ µrÌõLð_µ6õ4ø¹é½èŸHe˜ê$’?Ï‘p8ÇF¿Ûîè°oÕ A©¿ÚÒx Z ýÞl¾šeþûø×G1’ÑíW\Îeñ‘˜O˜ÍÌ[}d‹D:€ú€ú<€å M@³èÇÁbêçÁ24~Õò™uNô´ãëøð Ïa[Ûê¾)¯[2ªNflWe9yë(*S{>\®ÎX¸ö\íÛáfÇô cNÑ_É3¯Uä¹UÖö'X›þW–ÉñpêPpª˜Ÿ}ìè&Ü7}áÇyʽûDJJêCf)HýèÉ ø‘ò ¦xR¾âÉ—™Ü–<“´žÓlO@íÈãv¯-¥j!Òª~ቤ¤ê–<ø‹ÿ-Z¸çT¯ÃîUÿžBíÀ3'´é}Îÿ61ûް‚Í588Ç"™àx6ôX§Ç[37ú#X§E–€å¹ø=`Ýaì-j–ËÑ– |` ñ HåW[ P¾·Óõ`¼©N£œ•`RJ@Ývb«m?B¬ƒå9ˆŽp:!ÖÄ~B{\Û!’ï2 ¸Ü5?yŸÄ¨®ò~¾‡óXSu"ù_”NHͲ¢·R;;½§ãw[ÎØÛ‡WkËÄæ ÏSGC}R¬ÄW&< ®bKkH•™`iÊ­1÷ÈcÖ'¸+¾I.Á½d®“­b=c[Ƈ1¸W_pýp¨A}û¸’9Ñ×ùèîào7£}í½n猲S®êœúEÛ¡Æá›@»®Žƒ¼÷®‡¬=?CºZ|Z*IÍ+Ç?ñf[Å~s¯ ¯Œþn£¯Œ¶5€Ø@m/Ä«T¥öcš¢¶8—Y'ÀdË|Îüí.ðoEå¯pêß;½<ÔžÁùQ(ޱŸÁbÆrÀö|ü0¨#¥”ås…¶Œ›Ñïì…loáEžlüœ0üE .nT·HÈ!׿5áv³Žo{KôëàI§<leŸèÚ µªŠGOc+ÿœÈ‚ˆk& æå%d¢\ù™›|È I^Ï™C;€«TÔxŸŽâ®ìõô彜Ab ³ ¤[îÏœ ª8gyn/,d@æ´Â—ø)û÷âMLOŸUå¥ôý%)X3DI6¤=S6›XÚÞ²UXÒj•äŠo)ê¿À“t—>,賕™õ«Ò䎭¾ÛÄ Îû/±1Õ.Œˆ»òBõÏA7ý~«X¬jÝðG`¦_u`t-S‚‡@¶Žl¥F<¸ÝtgƒØ/ýjäSPïQzÓÌ& n5ˆª@,PŠÀ¼*¦€a† ‡ýW l½•¼Œ¸²¬Í\\31Àñ &xfc×¢ÐZÂ<žØ„tM^M;ñIÊ~9PHí%r-OÞ„G´I¾öé]YWÜ+½œãÅ÷§·—‹Š~˸O4+|=û8wÕ¯1Ÿo¯_c*âÚêšãàê#)ãÃå.ûŒÂ6Ñ»ÙvÙÎ$’λ˜'o¿¼_<ʼ⤘"s½Ó8ê>ú‰V‰û+çcdŽ7Ê8Y£“iý5sõ¥)µ´hdYÂE׸ð îS®_‚UއÜycb¤gLåƒ`iv‡‡›Ù:²5ù‰rõ?½øØÃÈYwNÈ!ßøAƒcñÚ²'ô™Ñ9|y8ØS>o|)bht@ÀÊNóÁh׌Q‘£ˆ·áTÉ­±Ã`‹Ù¯á±¶ìÂÃ4öÅ›f]îA˽½|žyÁoüÏ‹ç Ù‡ÖÖáŽ?h«¯—OÒ0”¹;9Ú½¾ß8¼ÅûàžÎMdú@¹‘ÛŠ^”äÐx9·=:us[ðCr^%›Z¹7Xÿ:íKDzbËÖdys>ýr&rtNèæ)ñFvyqêg®+|†ÑYÛŠ_¢]æÜâi„²ö•MÅ—¾º¤7ÓÛVO¶tþDÿ’4ÑJ»ñ1fywö‘YþŸQP²(õ|M±q±¸(S‚_CÚ$F@f3ËoÕÄö=F¦ßU„šl::³,uçê¥ÍL^h^KŠ'íÕo¦wNoÊñ„Ì„ š%•$ ¿w¬w¬R۵µB-ÖÖkë™yëpþÂAÿUÜJñ_ç:êP·^®WÐÞ÷’ï%cz…^6?õ5ð’eÅmŠ]Œ,ù¼$¨)ÙY>Míãßx˜UUG#Ÿ’^|#|²¨oü4¢`\<èõŽÒŽ->Ï1 åa$d>ÌH\ޤnV]q—rzp\lH·›¤ô´O/ïSãºÜ¼™—+·Ý ä¾~ãöœ?˜w}vÞ1ñP¾­Ö´+5kä02?’¶.¼¶4Û1²øÑðU^¸RÆfŽ_¼B-Þº\@.«oEÔ6;æü†,½¦T!¾:w4‰ SnûÏÓð_&’ݘ /Jf¼Éþ_Ù­4_ÊWõDŠI |#ßQfý¢PKó?-w©£ýÃcG‘äðn>Œ‹.¸$ØÄ±8²,ØÞ¹!ðLøIÛ˯™hÉáNÍÃ#8íe|LÈ]I%waæ¼Æj²kÔ1ßWÇçµµMÍÅ2#Xãg1N|žÑÕ­%¬ <“|Ì~¾ôÉ<­7¢uvPyiD uN=Ö¤]ÿðÖ^sߨ—98ºS‘ ߯kª ÖFñ6î%Ô3²ºpÔÈHÁË*çAž°½oÝB¢Ö)>Ôß™äÔ?¬Ë<îÕøÄ}˜fðÊSýz~õFšn2¯àt¤Êû Ö?š±ƒG ö±ÿ0W¤é,? bjà^ð0êBR¹¾ \s£€=à7Àúyô,Ø7êoƒõ¹ˆëÏæ`éOíPì6Ðò© ªßÊóÆ+ 40î1ž¶ j°äAKÈbÛ;`ŽŽn}G¬Ä*<ßÙNn‡ÈËÖ›½b)€ØÚ{¦C¨Ê„°Ýù±`±«j`—ûjÕo®o‘U“{"‚­=÷SZñ[Ò**¿JüNž.û+­‘èY¶9yŠ|Ö÷±å”¯Y¼%Ö’gˆ‘^”"Ñ­Ò'óèïîÎ%s|­êÓÁö~gûÊœùIÞPêfj×г榫/ÉCµݸ!•Üä¢TÞ̬]ô€²:3P2‹oW “IÉo/E…ûÎØªð{¡Iõ8ÑDQ5Ô•£ä ù`…“ÉÆ½¾š6ZTu’˨ª®'!ý!T‹¶^O=AMˆ‘ ØÀ8ŒL;Èõ\QE5¨IµŠ‹ æ ØNrýäfpµ` ¸Ÿd*x†ÊëØ[ôB$Ÿf.2ý’hÎé­IÓîL±€íˆgGüš=âœ~ß3Çúuõù´.¢ViÓÌ÷ˆ}U³ æ…)uu§¨]-Ï]Ü\ó }²ï‰ŒîfG㡤«â[ã;ÛNº§¶È~ÞûŒ¹„=£c'Õ´´#ú]Úõ ½!óõo¹„”Æñ]8-è*{zì …Z†¾„Sòš–‡–§ÖÆîaÇ1x[¹û‘¯B4“×o¼wã>b‹:¸š\[Ÿƒ[ûÞ,µ\Ò;13z(:‹žŽÓÜSu¢w”Y€-eƒÁòUecðŒòÿ Þç#7Áûz8îÛõõàN¯Ç”øTp|ëÿìëô•`Ó¢YHÛ*½5Â2Ì?Ÿ‡µ Ö«ô±¬4'ËÍjÃêoŒ(>÷wrÙêJ¾b¸ÖQ&c¥ž¼“‡•1¨Á¨¸‡sÕ‰ ´³¦Ž‘Ö‡k(¢ mbÓìUñYÊYÔÈ7j#§:·AÄj›Á˜£‚Š{.„~tåƒ/Åõ>_ó„ÆØªH‰ð Jú*w&ž£´Ì‘Ò˜•ß§n‘í+O§×Ón†SßdmÅçÎöÕ…Ñ«,()¤#J±Wx™pów9ýò59íºÏÀÈ˘JÜ>¦F'„µ±³šË«}GP]ZB•8Y½IÚ<Ï)ãE Û„Ø ¼ê¼=ÀH÷‰èX]þhm°zýžu´Ö›ÃÝÔ Æ­Ÿ~TÝr5Œ»lëE?ý.íSÕb\´Æ-µŸ´×´©æ!eŽRGÚ”2õ8€y—Ê?HQvïÊÄ|£ÚüFÝc¶2Vj#õ¦æruvt˜ÑÃr.R7ԵǸM­é‰SœóUÂZæ%éÛJ BY›6Ãÿ»õiZ15a|KIŸ‰÷l'†2ÒqÂê§»g„£éÉí\éTy7Ú¢$ZV†g°Zëd³Ü>Tìa¢mXMmÇD¹ƒFöf NØ[¤_›A=9_Ë´Ò¥ú­pè'E-qG|¬È±œ×Ÿ"ÏU'rB]¼òd¿ÖžU$uéI"ïý#ôÿ¦§jøæ¼ÞCÛW°U«o«ËTõ)󈡪]eÌ<.ÆÛ2.ˆ¿Ìcú÷Ì·,5…pÚëÇÑÕæf>X¿‹C3UÖq[ü¨¹„ÙŒŠö¡wäÈaŒð²ÀTÔ`Uõ6Ð×T‚ȽÕË !z<ñPsð´{Al¸šG:ƒ}tì7°8ã™`mÿÔqæG`™gÖEÕ—µ¹ŠC¹C¨`®UrÀlcí Æ~õ+ˆo±Ì€Ø÷ކ WX^…Ð\Gwd¸®3B¿ºÞÇ ð¡ùw{·ò‰ÿ7¯ƒ7«$LähÕÒÔ}¤—L/—ùŠ÷…O†/(ó+Ž™;Ù\,hG¯ü¦,cX¹bÏÅÐgd6@µþ•~’sÛ‚£@YŠtµDXf˜31´Mft‹Û¼‚ͺ]ÂWÚ¡ðVf[»ÛÆrÊ2S¬'¦Œ ƒÕò‘¥Ôƒ¡n±­CU2ôÎì…þ™ˆ‹6;ý”üäçÙ+²˜Ã%2ÍIHråF˜¯2EPN³Ý\UQÉý|(j"Máñ"ŒÇÆÿ,t}…{7šnÄ—35~UQ9kjâÖÇ|æªõ_Ô8b5ø-~›rÄzÈßz]Õ‘õi ¾J‘‘-rBwY,í+@hm1Ÿê‡P¢Au&ÄÅ~ËѨéa³cÚŽš¶CúhN]ëˆî¼¬|LÔ¶‹ÛÁÞ[”b8oZ‡³î‰#Å~IÉÅfÿ^½Ÿc¶-ð`j¿Ñ·qÅ‘{g—÷Æóf¯â¥s*o»g…¬£7/ºCÉ4™~­Øh ›(å0íӸ˘nI6^WtK}½RuªÝ"o_r3Ú\[K¦ÑÒù ¦¾ÖQˆ%wÝÅ÷fkÏy¯õÁ¤žÜn;çÎå[ûKb„x×ÒEä>ùh$ƒ®ÊÎxœDå-@¹"Öeb7Q£Eøiñåx¨à!O*½A;ä}Úy ó Ò Ã|4’5>4¾ä¶ Û+:DDºAdZø7 Ðþ%DæDÚƒñ¶z7D¿‰×‚hÓ¸ B»" ªÙ¹`@d´q7Tωt‡À‡!ªëE;CüG1EæNHëý$ÌuMÅtí¶µ#žÖ/)›{”u?Ø.&q{¢’‡Å¾Sù†‘Ú‘÷ÙkyQ¿Â ÛŠƒ½Ö5z#î²OVÒÎú•žÄvíÝéa]eýÚ¨¾¥N6’Õ:ònó1JúŒ 1ÂyIN’lfôÛ=ú÷ /‡A&«Às|2Ñйë4¡ºWË9”iïË;¨§®2GÇ-Ž"E™¸‹ñº2*}ž˜€f¬e.YvJ,¶¦ÚS \V„àlõ¨Ô(ÁÀ.Õ…]{QM+õ{Ôrù߉ºf÷ø8uÞÀ|C¬Ò›Q‡ëÒ©^§FôG&òZ|¨µT†BM,¼¡Cl§{°CÕ±*^§z™SËrˆr­,HØRyŸDíÍP„ez¬PïkñËb.íaùRÜc‰ˆNF¥¶ˆNÆbe¶rÐȳú,¯›-‰–—eoåÕm6#q_êîüÅ]“­Ãî÷ð_ÁK²dòJæœ(<„2i ZS–/ÒäIù†ú4Ûl+ ´õ†ÈRw"óÝÇ!ë¾)É rqÊl(ë—~?”–¥¡tfòrPʼnÓ"“*'¹Wó»]5«ž·¾Rö|ôE¸&®è³@¿º ŒW—ˆ~ÆÓ¡¶®©rI¨¯u”2±úfp°5K5ô,M\kô #m­y+ågŽ‘ÒÈJM'R_¡6¤|‚J<å.4Œd‰{ŠŸë¼‘|œ†$'õ¡LÞ›x€ã‘÷í nß6zFû.0'iCUf{>÷ï§KÂÅÀëüìÙä‡|÷ÀgdºNg£¸~ýÎ9¡6àø ò8ÛF~û}‘9`[»¶ý±`½¿ –MzCP»ëQPûÉ“ VȈ)ÈNh¬“>ù³h²Zû̘ú-èã,¯Qeyâ‰Ö¦ÒD§ÛuˆŽµ7ƒ`kלq_Ä;*û&¾Uc’žÅ¬^¬!«ªScwEÄdôŒûiÙÍ6×ú”¾6áEˆïp¿Â6}nÒËŒS_I¹“EÊC¶Ü#7§ÁÈ3>ãó]×åbñ§Y‡Å|œYó=bè3•÷%q›xŽãzغ=ábÙŸ‘Áÿâ˜þjÕ:Y,þu`÷W=ö*«¢>û7Á¯‚—]oò\ —ó.çùª±öÊÄ+–É-+Þblzò2H{´¼=¤ªX)UÕ aµ¿x·ùÊÀf­iBúá—‡¡æCñOäd> 6Ý[©7»þJ¿/õå–z!]m9«æ»´t5ÍÜ®>¥Ô—yj ¥©ù6kÅ[tå’(`gd¥‰ì%(ï˜[ÌcJªqÎh¯6йÚ×Ñ™z=KaôíxseMè¬9F÷)X°øÚ# äSbPúœè… J? ®ýi¼k¼[ô6eújÿhªÂžJôúÖw½Ú>´_ N›sP¸\½žyÀ”„sºéG[ãs¤Æ;é]w"OóRͰ w†x%t3±ãâï•ÇÓ>ÅSÙÇnœ“S²)28Ÿµ±x•°eä—¥{Úì’#ÈŒ‰¥©ƒÊþ ž¶§¬ç“?©ê`ÔN,1øK´æP1Súù¤j—h­N¬~”¸ªJá¿Uw%.Öʰȭ~†òB¨C„аšïžåZôÈ™‘£ îŒ> ÆèÐwàLWË –Z z»xH¾ÍuüÀ+Ÿõˆõb ÐA¬Ë\{0ßRg‚ ©A~c¹Ê÷ö ˜r—íðØBÕ$$Ö ¯BfÔlj֗‹à½H*çÛ\ø ´º™ÿ$ÿÃ襓°áÈâBˆäû?e€øÄ*‘‘w£/C¨(”úGú)ˆtŠ,…P¿*;Ÿu‘õˆj‘±¹ê/Y!÷ëÄ5ˆí‹=áôP!D´Ø+œ¢ã, ÃuÁ ñÓý©ò+9:Þ“2ó—H-Öɬ®gh3yÖòBÚdm¾í‡¬=êbNv;só§ÇËÖŠÑ’k_%ÆÄÚ9#Ók+÷K]íêVV·¥ý™ßjtÌBŽÍ{áÆ4ùrnë›)ÊšìÛ ¾ç¥œ…Ó˜y°à7ÞÎ^]z›œ‘ñVÄ^³›JQIm6ñUQMyH†KŠE¬-óQªì®Z‡)ž®Øú/%qú•~ gEK TÒ ä^¢´­–Tp˜7ÉR;©Ãâ%îî”àk)ÍRj‡ç»g¹[ÆxÛxÇúxžôŒÔo³o±o1{s¼9F;õõù$ÏðŒüÝ1Î1Žççñ¼œ#瘗¹ÎuÞ@A‘£ÑÑÅ21Ÿ—yY ˆ‰A v v”ue‚LPj Œâj|F|¦µ õÔ> ´ NѾ÷-÷i–®þüo:šWÜUZÇy®ÌW^hßkÍQê+³M("ÙíqB– Y ró§úAÆ%¹M9™^ÉYùeÎpqͨÈ6ئ~‘¾FNt­óî ü’YW}°°[îR9&ÿpÆòdþØÚ Ä=Wþ¨¿WÌ»XZû\ äÞoœ¸>'ù¥òM¥ë.ÞÏg핾¢7 ¯×Ö¦2§x„û–ê³Þâ¾PºeØz¥6'êý#}'V>– 3Þ_\ÎÞöÿåÿuàBrbxW&é*ëŸ"{²Ôv¯|‡g”îr(†ZÈzT9Cl§Ržä!ÊbnÙ—#ÁGŒÎˆ@LïÄ£¾;cŒÀšèd¸wlÂXÝŒªo6òÀ¶P¾ ¯1Œr ˜øÄ,&)J Ì!–± Z)é„"½-å<"kZêñS¸íø5Ûcœ×rþ@ÇÐHû÷Ž×rôq¿òN¨“œÎ»þ£œ êŸÊlUÇÄíè•çå*ôª»Q°W<Ë<>/=†Îò¢Eäsp 'çtt2žF½Æ²úx-»…;³ð GßìÄËOAÝŒóÍ 6hµƒ¼QëòU¾š§¯-î«Q~3BýÜÃUžðÐļ腊¸m/fñ0s ^•MEQñ4%ecé#ž*Ï'ÀâŠÑb¢¸P¹„•âjÕl5—]¦ñsEóSõ;^l¡L}3Q2¢W€„àMÀx t 2 z/@¼€¾@ï`ô?0æÖ²(Ç´)Z>€UØN8’œGL—(r>â› Õ™¨}I‹D¦yùH=—v\ Jwp“—3?â i¤ýA¹ÌÈL –>,Ϣì_@½’3îO~Øs´bUödË”‚Â:ƒ9pi}ƒÉÔ<û@““d\Ú8dÎ;}#W4 H`üàžeÓ¤/9Î0Ù(q;‰êpÏjzª7l%ÆB­%$Ïiw˜ L]¼/Ãr!#EÀ¼‹<ÙÖìÃ[‰+\§xûí› c“zößßþe>19鬿Œ+ b–N1¾"¨}B¥žÚ‹æ`eüF¸Ä¬‡øÏ¿At_éO )Ï‹I÷áØÓàþ%|˜m«TQ§Â¯¢ZíÆw`ÍÖ/€¥»1 ÔcºZб”a`A¼!˜£”EÀCòs ϱä g6H![‚þ Ü ±íÄwX&Ad¡ýDCÖ— ¼Ö±‚ﻄë¹{B`–køOx-ü]×ãöNˆÒÌ721 µÊš|œ¤Š:©½)({4uçË&&?dõíÐ6Wuˆ}$+ ³Å‘TtL¤°  èx½ nüˆÉ K„ï'Œ³áj4fÕj¨­ 3*ÜÃ*ÎI= 63#{ݵúÌ®ñíµær]Á_˼l_Ñ%±1ë|áze¼\ÖD|œÚ *ÓÜ“¤:Åö»·DÆEg96é?…:j»( |LøßER8ŒPæZ±HÔ 7‘}Äúè>±è,¥Ÿþ€üKÌÕo'HŽQM>)òNs•}â#®+Ch!ËÔÛå4þ²øÄÓ|gB_YÃÖY|'9Nóƒù{Yr¦g/&Ç<»¸Î®£Ô´<èܧ¿å\d_zÎÝÈz3àK,ÒšU=–žKrQ^ÎräÍ‚šÃW*êäÃ…¤ÚËäçÎåDã_L9jö¶´ö6Wî·?kùY¤$ؤ›g<ûõÕ#Þ­‘9ÊBçÂèYòí_ÆÚ“fëÏE2:VAÐz1v‚¶ÝEµ%;þõ¬Æä(ñx­_ÅÛãægW¶ÌÛÛ¾†µWCñˆßþÉÀÿ8á’ߎN¦àëãY®Ì‘XÔeÆSX´Fk KÐpcX±Šñ™ ËCÇ ¾:âó“êR_•6\7?åhÉtpœl/Z <»õIàœŽK‘<°7 b¢NÇnëÁfë=bËÔùá›zs,ÓŒÓüaf<Îj9ɬÁIù†ØÆUj³L*”füËUr©Œ¢Žä‚ý#­¯ª[Y¿C6¦_l¯#‚µÙ3Ð"Ýë <Àn…À)O=Îs=|ïðŸHx|÷'´ƒªû“Æ«¼/ñ¶WîI½—9íS.ËåGÓ,ÉÏ+<…õS.›ª²¬M*çIJX~ó)yŒù7N³ãâ,– ´]µy^ ж¦Œ†¤9mÁÓÜ{ŠõN‚bV¬«–ªÝŽÅ˜n…aýÔvE›¬ÞË}úâªí8ñ+g¹¤Ö‹é)§„e‚ö£>—,ËWæÀ‘ðG "²h¥ |"Ÿ½®0«ƒcxŒwbAPY6@|£Qñš´Ý®Œ˜UY‘äÛ¹®| Ñk #ÜÄòQvßï?—áãÿï×c=×k{ï•*ÉÎe%B2"É(•H) ɈPdF²E‘²eìõ2^û¹óúþðyÿöù¾ãÓõ7ÜŽó<¯ã¼ÎëLEVÒ¢|]ÐJæC;¬~*O¤ŒMo*z&6LÔyÕ?RÉ£CJÓ JÍÄÆz3b¾}ñ~’ñ7â€?Môá]u|ä ëýýäL¶îëƒeŽ{OŒ¼äÙÌñOU&Ê'öŽO}WûÒn¡˜ú'öRþñJ${ŸÙ‡):k5À)³ÿ™V+jüL—>ÅîV›K<Ïçõ¥þgGÇ;ÒÌËt>âÝ“ìvtsï¹ yNI´’Dµ–õDU¯%Vèi»/Íiƒ¡OuÇ2N]l•A¥š\ÏÚ<™Žºc]çq¼„2™Dcß0 o°Ä+n5/r¹;ܶV7ˆÜŽ| ÑæÀìý ÔhN!˜_Yý ¸ÇtÀŸd§‚ÞÂ)½¡ó$h®Leˆ·Äñ.ˆ³ÿg™ò.¸1õ%ðÚkµÁÙm ëM_0·ûoBl}p2æ!¢eÖs9üc¢ÉpAÒtvçwO}šãyÓÞçÉœ÷“~ðÆÔ÷¬7‹ˆ¦Ù™ÌgiV?ÑáNZÑ°àŸ¤kLò©ü^jZé{ˆà¶€€Qa|iµÿçÊb†#wQOëdÝᢱĸ‰ç‹Êm²œ‰0²ØÄCµ¬ü’iÚmŸW]™Éo¢˜«¯w{Ðݹ*ó,>ÙÂÄîMÑR©äýE¹xØ=DaA–Zšâ©ËÄjü8ü"3Ñ÷<'§£rM©ŠÚTžÓ'©ïPÖ½Gkv‡oª¯ðk`±úû­»¢¦W_._º£´Õw»—ñÄ8VUQŸ½Ë­Kgg„·‚V–>NæNÑ×éFÔØ æh¤Õ^=ƒ°:«À¼KW°-Q âQ™ñj< fuµ)¸/:]@}5ò-„®iÙx‡eøDùë䤯‰× |鎜WGƒ¿®vüûõ•Hcºyáëx›yú„ü 4²Æ–Å'Þyfé¡›û@ƒßõv!¶ùþLÐné›@ü õ=ŠÇ(1Å_<³8ÙìU›ó’ˆp^Ö4ž Õãoí–(Mr W`+³‚sŒsb¾þ‘³–šêrëu+[ÍóÜ/ “°x…ÃDÕEL'A ô>¢Ž<¾&úÑ…˜ø›dDYu+ÇyY­#;âçcqÊÛ(?Bqï»·(îVWÞ"ÝK‹]!EŒí#êQ A.‘ëñ,É¿D´•Z}r©©”!híe,#Ülc /2ZÑÝš«š(ÞTíSJz9ì³ÒÔþ<ß¡ßEá_}Ó¬š"¥ý¥¦yÛÝ¡*Þ Îc¥ª“ë&ð‘cQœÝÖ =(}ñóƲb¤”Òˆµ…§cSÅØ;Î<›ï:£Ä1»ÀyV梼‘8v…‚Ýh^£x p™Ùàá¾ VýèK`Æ üÀæAÐÊ)e Å—Ks¡bü•jÿcF»‹ÏDSZó.!qLö1BÙ r‡2d¢z ÜVZœúS`Žñ}Qá¿ uC¡ðpâÈí›ø+X­R¦€ùCb=ð¯‚}7!öÚP:®”ð]Õª±][¦r]ëíÕ–9IIÞ!±%£§2‚cÊ5yâ—N-eØ'•O@žA:0N¼'Ãn1ñ€çX¬¾"çÉâ€×VÖT*ËŸÝÙBs{ȵ¢²3_îb£§xÁ!.3C{L}»œžè퉭ô­Æ‰ö—kÅÍ(¹óE}·RÁ-P„@©“ý5¨‹"Å¡½9h=ÒSb÷Í™>¡~i¥kÓìÅfª±Dm{ ØÈlì;éX?µ¦VÞx_O~²^­Û,þaˆ(Ê@uÏðïœ;»·Ú7«Û ßDûOH»Ï.ðíâ>è׌ ÊOâ3ù€·À½H«& â}ÐÉ‹uÁæ`ÔO?úÍåñ‚ ¢£È)®Üç‰Ü{ÒæpNe÷€uâÑg¼í٠唉ïYT_àŒe‡¶‡Vyoe¤gÖÒZZóc¡ÄÝÚ;ú7IÝaÎõ´R1º…IÛí „SfYR§Æówڨ—X_f·[™ eg‰‰ ©°Mþí œŒÍ±Ï~äsæ<`£ûøËõâA`²rÄå(È "ˆ¨K@î³€Æn –ž‡$Ñ&Ê._oMƒð¸ø˜¢W¨(œ˜.+2.±¼ì J%¯/z»Óê I×ÌÚì'–þ<ÿèù‰·,=ñ¢?¿ðbz%ÕŸ3²ø2”ûgJª4¿·¶ToÝîW!›Êÿ¯¸ Îî)“eõºZ'31rKÙ“x77î§O/X’üsRkÓ5·kp*i手iïõM|†e½&¶^"±&:=ÕÝ`&š½À[‰g·T>$l'«åH*ìhWç|ô¾»My} Z²-r%¾Z&ØSÌ# §ä$’/_x„Χ¹MŵNá®0ï>šöc‰Óÿ¥þÉšégø­çÌ—Á>ï¬åO "»à)”<\1RÕÐEHÿœæÖ.ˆ/‰¥€qÊ[Pا`äÊ®ö.Ù âOZ×€€>¬_Ýß± ?4@¶G£x—WðÒ}_Ù‹(8Ÿ)¯ËMªòfa~ì_ëŒqÓ/Ã˽™Î[æ§±ÁÖÖ`3†+›’Q×Ù­&¤&¨q6ýM¹›ZÉw¢½9–.ÍodÍÌñ°hV¦¼5“#e{»Å¼Ì çV8³dF°ÏãMnÅÞº&¹Ü¦·3©RË[sø¾l‰»Ë±K¾3“„’'ïfq¦ÔÒû!¹ øÂUÑI{+ç)7ņûE䧔Κ*ß—òñcå=&?šB_‘›s–zlÊî‡'Öç®COæµÄò»¢‰ ùÜ»w„BwYÞu9еnÜ  q¸1¶ˆ| ½ß­ àì°ÿð¢^2€» Àû?/?ˆæÊyõ%u€ò2€¡£üÍB-wO'uBðwè:%UËß“;‰ •%šYœÞj¤hˆ·X‘öå“i½ÙÁéMù’¿3ûyƒäsEîˆwÜÕ¥- •<ÇjµU‘wRÒ´ÄÜüE™(ÝDN¹=¥òwòÜ•¯«(ÊïWž¯V” —.•-”cnL.R<ïÄI›®Ž‰¼ªíº>EfÂÃ7’WÉììÂ"y¤º¤GÄCrB÷ÈTêë &ü’rË·BŸŒx¤~îs±þÐç÷¹‡ øwÊ‹ÿ·òÿ½0KœY›*Ì¢Û©Zâ)æÖ¸åæÕ—;y(öˆ·i ÞËQešÒ]ŒTsAyAÁþAÎĵO¨} þ™x5¶Èé9í) ñJÞ&ˆžtS!²Û« Ѳ%Xéâ[ ¢üî¥XåµÀÚ¤·ÁqFëu™?gØdY—}‡eUÜ×Çmfèsm¿÷‚8û•b)|’,Ì:üE n^y¨9Çùrþ—áñKò7È9¬uÂ{`HPâKýûy<êÅSÉ®MŸÔ›n&ze°K‰dâ+õ•9=ö T¶?=÷åŒ'Ó2n禖Üp]cdùœ«¯!+ͼr§âÄë5ðUV‡¥¸¡†8¡Ï¡¯ÒFË£Ž:ø)FhôŸ)îMû‹Ã/ÄZHø•Tâ)7ø‰i›d7^J%?á“ ,o|±ñÊùa±ïÉ&R¼6@ ÁiýF‘‘VajƒÄ¶ùeŠÞLÉJ+ÿw¯îª¶•sçzÔè)9—_ùºœrwv™«îšG—Ó³½áþ–ŒÉìÇ8ÙZO–µD‘Ì“ÖBmkÂCw´úsÁiÊ?šçÆTÚ‹0´>Þ|„–ë|úu·((7½R ñѤ™å>cÉ;¶0xK­þÿþå›Äå‰ßêã?ùǽ‰P0XJ¤þ6I˜^ª^¯,îgÕ’ù´¼ý0øNm ûÝŸh‰z¯™– wOˆ±Æ‚ãYý=1M}?Ù¿âK¾“¿O´*Ñ;>‘¬*ËùœŸæ¯U)–Å*•XêO-ˆ¤N1wñý‘^'ë*õŠŸ¼_”x‰AYWH*öÍýPTͺ[¬ò£¨™×rûóFêw…/»ãŸŒüì®ý?é.ô7±Ž9/ÅÛv­²ÛÍþU]æýèHå5yÛI-åB·œ%›xψ£¬díÅAqH¾!Ž)ØÎå5Y¨´Õþõš*¯é'½_´ýEǯ;Ú:«½ÿ¨3ßvÓ†EMZ­—*LI–â™Â‹™_â=8U¢?Ü–%RPnR¢·üçîs%Î{Õ?,Ö×ýúq0ó±{$Ò#q¾|10/°@y*É™ÊådµE…ôëñvê†Ôª±†ÊÛ¾–Ö!|Úñttc§¹U­m]FsÌCœñGív<ö¥Ø‚ÊzEs¾YÎhüjck èÕœ?A-åÅÀøÑzʺäföÌ ½(lô¸G¢hó_ lÈ鎞;ê·›°'Æ8¾`×Bjw½>8jK7„®¦¸EðÔu\#&JÙ?àèͽ4\m !â²§qŒoY¥p¼Ù…#îÃéæä}…Oév÷#„Ú1ë_ôz‘%„‚Â'Á?ÖüŸÿX¬+ÂçxÍéç«k¦RC/É2AÉ1ZËÍâu«¤»tÊz ›âwD2÷‹Tæ†rÄËQÏ)W½-ÆJ2œO|GI2—i'ho>‡[èk¬Q§yœôäïNÚ…“qòW¥¬EË›ŸÖ…ä\3m8}³_ÊHfvv⟢ܫVä-xÐ'#Ë ?¬šž¿5¾^ì¿·OîæÕë7¹Ékw†ˆ¾¼ž¿3©3qÞ*ý>þ„Ì’+p’ʤ\B&oI:†®ÚVU ;~ŒDc(_Ư€^RûÛ¸h¼I!ÌZ˜zC_}ÒÔ¶b"œ‹y³qõG©“¸¯ÜÓÿἘ(þà”ü›7¸À]µ.Š÷4ÅÞ5¦â¸Â=Še÷¿ƒê–× y£å>Òœ=n GvW3À™%gá9Ueo47‹’„íºÂF³kó=8*-H·©&åÝÁÊ j:kĪٟÉÖTTVË= õðj‚϶÷Cà ïKbÁFÚsüWm—‹¾Kê#:·4_Î(59¼êûƒi¾CÖ”òg(ͼ¾oä_ÎQõC½«U^¹êó™÷¨ôâí0ý~³>c±ùŸø–[-©m”6‹PÇ8Û­ïq—S<ø„=Š€V"C'¿V?h¸¤òì*÷(þŸôà ÅÊ_òpÆôâ·ÀyÎ*Êmç&ÖÚÀ¸aEò…tpƒ­ž¹ÂžIX¹È“¨VÖqBncñéïà•@Ñ:EjBäãcð‰`‘ °Cí ZCÖüÚ;î*Ѽ)Ê=ð>2+Bø9å$¸¿¹Ÿýµb>ûgp=3VbüÄg¸»@~¡´ŽÊæà}¤ìÏTz¡÷{¸þ#ÄgúA<èìÁîý64“‚Âé »(ù4±¿Ü~5ñŠ÷SAñÄdçëðzßs±uæ¥Un-¯Þ£<ч…ãÊ% W:0V,*„Ç™ã꼄–°,P›_=ë õ|C)ÊÜà}?Ï&óð|CÝ/QŒÓr Œ*ÊîhKòÞ†ªž¦ÕöùÝub³6ÆY‡Ô¢Ö4o¦ûš¶Âý”M 5 Üq/yÝy+¸Í:ýšöhÚ>ÑŸpÖKdw`=¯à9¯ÒlŽ èênT_¾ö’z(Utõ=¤·Hްz±™³ÖLm- µÕÌŽý¥îÅ7ô,twˆú ùqŸö)Éòsm©ü=ZByIŽ ”²nP?&–Ú¼§øÌüAŽ –ó…lk=22Qͯådª™çªœ6§‹hæB|˜–©ð[GÕ¥ˆpû¸ör¨—#Á?Õ»B,¡»¶ˆ@àŠTèoIŒÒ›NL Fô÷Á7HfŒ§¬k¤([Ý©úÊÀ4» ßÊc?áeB¢½¹Ù×]øôs"g³?‘k7­y+ÎÁGãÉ ÖÑ{ò˨ê¨z²µÝXè\«üïj³©çk¥”£ˆÖ3vŽzÆ6wŸ©¶Ò›¸:Ñ{ƒ¹êö j‹”He¶U¡Ö L%ÝýO|o>ƒ¢„Å6V(ß+ó(à *3Rà_NÉŠ ¥¿Üòy^™¯ŸÂs«y›QÜ^:ò»;5ô!óÝÊ;l°ãÑ$,g”1 Ù{ÖÏ^o°®x‡Á¬ëùÀ|GÙñ²öZˆ?!‹@ÔsÓ ðûØf0[Ó!wQ~<~7"@S|Û^m%iY¼=ñä¤`cüÆLw(a£‚û!Ù¾ûò æûSÚÊÏü]X.nưÝ/åÊúže ƒ|·”ݱú#¥ŠÛUA­e_½Õ£Ö!|G­ÞÔô·²î‚þ…ýƒŒVæYZéÛ?ó¬vÒÖ™¤7p3XßÎtšá×_uæ¢kš—JÀ< JS¦8ÎIÐç9APŸ•gÁ½¥¾ʯއ Œ`Èà½@¶V¾o7äØ ¦k+À»­•çŠÒDHY‡kïTúq+h÷1Ý*ZòªÆC>·W)6íW_AUûœ‘Omë9­8å}/àY­wQ¬×Œ-²L}º¼m­7jËsöŸê÷¤=XÔw{µpÌCj›/©õY+ëöÁˆhND¾?¤Œ§0¶Xß-žŠ¢¬ÜÝæ…8k¾¡Uå“Ì1ÊQ\­¦«²˜˜£þÍß/Úp’þebfln¼.dí}pœÅ¾}¾òãø3(²ÍcV:ç<Û¹ÊpýKQDhþ¡”‚Äåë<\~é€éOÁŒ kf%O{’'ø.í1Ëy&uŸñnúas0%ÄÇ2¦Þí„aêëVJ`‚^ÒêîkeL‰UÒ#vB‹ GBB­Huÿ ¯DŸƒÀ¯fq̈wä¼/ÓC¡1ÈH9]·[bè?»·HU&{uAýAv^ÃÇ`·£²^öbm3Ím¿®âÅüF”ÈðÀˆ›ÁgÁY0AiÒ ØÚ× ”5¾£àsô¯AùJû´×ÔÎøG\…`±ô½â^°ŽSE›éÔåÀ §16Ëît”}õé LÃG„°)^Ub–ŸÁ¥Ë#o ,™Æ×¾¯¸Šò—3ʺ_^ëX佨’HJâÆØw©Ç|—­Š½È÷‘ÍâWZuÕSòˆWXôŠxÑY*îЖ>òe6p?‹êNŒ=KÌÉ’ŸaÄ×™PÞÚCôø«;xÏù×혟»8vr ÅþAi„b.] ¶Sš›ïµ€¼îæÛäÆVzé\ÉíIàhnNÁOôù9yw9’S?K»ùüÇsýWÖã?ùæCp?Ž”ʉRxl–]°e31Ÿü•–[—]ÜGÞ<È<öf; ±.‘ àï™÷Š˜V}{-Ä?¶W€³™Y`®bXµ¼ko~ bgà (4cGÀ)£×a[aŸ¸”w¼Þ¾FÞsñ[î#§x|‰3ÞE:ľÓË?²\ðå›k¿Pè[c+Ä‚ÇÝe3ÞõKTÿ‡V„£ÁsÖS¬Nm®N£Iò0»=US^£f±RÑcžWä×ð’xÝ’ÕÕ¹2sFúükß+‰÷]íDvåE×Þ§J…·ŽÊ›eÞô ¥ìëwËp¶düÁ"7µèø‚ñ‘’Ióx÷Á\±†%÷ü¬²zËS,{ô=å‚GŸ‹T¾É~†Þüžý­ˆç.§±¼í<¤þz¾¿ ãÓ _¤½Øiötëó±ý“5G|-¦Dßç#åt4Utb{¼7_ŠGæ*ÒÞ<ÊiÛÛäiù»‘‹äj·™dzyhèòM ETEqPÏñ€,u‡øI®ÌS&ú ä7¾/éÇè`{¶{#‚-X&¾hòK½‚17ýõµ䔄âbŒlžÒ•cRJr”)›äTÎ|™?‘Ñ[úÑŠiâ-y³Ä61˜q¥?g(”zþi÷â¡ô7}w+ÝNýþö +D­kŸU}“Ô+½ªý€ÿÂäêð¯[üýhß»iIí®Ì+j8W¿ŸóÕÝï»Y0¼ˆ`Ž^»ôyƪ’*Ð1ðG _éŠÒ”ôžÂR™yèÊ@Q ¡%¨?KìÓ`®Ëi ÚÖÄéÐqÔwËÀw>ùÿgØÿÞ ”¹xoÿs·¾%ÿlã)Æx ýߺ‡Ð¤íš82¬Ç`·x Cn7§CìŒ÷ÏkäSÑüÒèDå"0¿7vðÓ »¨a0›©Õ ^˜Î7¢ <¥¿Þfu3Ñ?»‰V™?×—Žˆ½k<…U[Þm÷=ñ»=ÚÁ.öG»ðc#]å'ˆØáÞêpôð»Þ,(üMÿ ·ó*䟔D‡v@áY1'|JMFÉ.ÿ Š\óè22iºØKnbã5:ûßuVówRs£Í’Ív¦¶6g@Ñuâ;oQêÖ´ØÃô#IïçnKœšø8«BrŸÒÝ\ª(ÖãR1®V;wù(+‡n,fSùî—w#ÅOæ,6ÿL[Wx¢pbÒH³yÞac=§³_¢$ÄHãÊÃlW?ŠÈò ȱåcöää—ù¹Ã…ØÃ®ðQ“£Ñ‹$Éñ‡@ÔÒ™,Rœ·e#pnÉÛ”ðVó3žü]NBR‡?ÐÄ*TÅyñ1m )¯]7)aü.r)âoJsžñ€)^J˜ˆ±I!Rh²FÚ¼šþ ¯zËŠNÍhYd }H/ö·¹ŸyœÒúæ´í·®'· ÷KëL͹Wì'ßõ‡+ÊÏã»+«k<§šW](;«Vá-[Ï6‹uÛÍœÔJrr¢o¾ü4p”Ô øÑ&cXüˆ’˜šc.·´õØB·Ú"DQëy4¥™û$Ñ`ŠÝkjYWgº1Á~çñ¼K4ôe:ˆþ²7ñ’M ¡äSÃÈè}[¬å?,AòÎ"©µº!—o¤Üޱ5¾ÔZ-ûi'Y\Ä5–pQmj5§º2Œ›èJEï"™b5‰ÒDùU¹®M#E´VêqÃ+áLæ°•¤ ±Û'·­í^ñ¿xÙ [*ïºÃ lä>A: «$ºÏ %<¼[ñ! K3H¶?·´ú1x­ô;àí1ÒÁfüN£˜½|¿A<¸Ñ1 !Ö2´ Û' ‚‚÷“ q }ÉûPs~M»ÃáœÖðö#%óuÞz°3½Žûqö°äQ±ê±,ÿ‚¿3^G*½9ö`2€Ù¹og&ÐøÁÈ/QpŽoÅ&«&‹åù[ˆ_Sß±òJ±œ_ø$sIA-n¤-Œ¾D¹bËeçX±%¤Y?dôДèÉôÉþ¹ߥÌI»[øzpAê—¹™¬ç|H4ãßÜ’Ó'åæBj‘ìùö~ÁÏÔ6Ò ‚kc‘Á)棳õ4ùÆTÏd“xËkÇre+íåwœ]Ätïu3½Tã~{®ßAÆFº â=ö@ø¯¤ŽP“‡Ü@úœ|˜œþ=õ¾‘ºÅN¼755'¾4l%µvU_É„ç½y²e ›ÆêF%µ^âëJuu¾:´E 'd¶º7íÃøµƸø{ÊAÛèG4PÞ‰¿…æË¶ÁögÄ&qW·ãµPüéö ’Vlºö½[¿ÿÏØ 4½ƒ»ŒïÜÀO¼"(Íì‹XÆjw$R[eíÁÖËØ~ò•šE«KÚÚ{+&)]œøFb†?ú¡9ñÓ}Ùä…Òƒûj_sžòš8εH̔ӵ³ö8qû '¹¨|¢ÜµS‹?£(É‹¡$ª{2¦à(µ"ßrå,㎛m½…ß;ã°_j‘\ݽ‡ÔCnfÈÒtµÊ‰cê'…%8£|Æ=©OªÚ­0 ”ùÚ³jå¥Ãdˆk$‰ùêúÊwµ ””óô_ùËí¨ë\²z'éo½â¯Œ_x„ózA´t‚ÑoC¸BY(ø'µäiÉ{!§\šÙk3îÀ£‚b«p²Ö¯ˆv÷hú3n⣄”¹ñ9z9?Ææ*=š¯}FÞÝ;ÚFö<ê”0Œ‡ÞÚ¢m,n¥ÞÆN~Tò(nBO?HxÃC¹ûK«)ÇóH«ÁFîëóØOºö“Ò…ÊêBîó¤ò¬£¿>_¿‰«ì0'SRýPêÚHu=ÕÅìx1ât"&‚z2éÊ7äðËUÀ}váÉ­¹î]æ(ùè²%Å J!äNmkœæ@ÔûQ7 Ùš¬…dÙ@_1KÜ ÑÛòB`¡õ­üÚøEßd_Òïê ­yÊÿV5ƇFgàÞ6?%;X7þ§Œ‡‘«¤([¬”Vpï’î߉â›d—F»ã=PôÞ,?öE¤¯t®^«¦¿cWíQÏ ¡Ô…ÿ?Ç^›/ÖÃ]Ö:ò,J,Å:‰ð °| ñ^Cúv™o€rÀ:ŒP›ÊqàÿÑyÔN'P–³ôÑñ* [yOƒöŒñ"ø×™;ÀúÔ~˜Í+ råï ˆ‹‘Àp¥pC½îhY¢ª:¼Íú%pþRW‚¬¨Tû­=XW;àǃÔ-`×7ƒ•¥Ù`ºJ?(H7>ë–~r¯ú@üDðKðdàn¤[°/jÞ— #¹›¦¶{Ås/<]ëA‰‚ÙŽ yËÔLÈëjí‡üþÚ—`uM)A4½L•G8I… $÷‘Œòwc>ÏÈBZûÀÈuïQרíöl}¼/êîSSµýöQÚ=è,d[Â4«Ï˜lDÑ.[%8ÊË^> µ¶*ò›ÒÙ®‚¥äzŸ Œ×6xÊbo=†sû#´ßœànà,¨3å40b^O­8¢§ÌTŽ‚x,BÀ$Q ÜEÊàMUîƒ;€¸K”u¸ÂÕZa»ŠÒÝ}ZÛç¾®¶G7cê >wU} –›lÔd’8ª×À6[hÓ0£Œ3$8Óõár¢î’YÞRÕçNr*“í“^OX ¬Á0ÿåí9輫ËlŽÝkq­_Ä›¨qÃ>‹ë)ÜŽìíŒcR`¶ØÀãP‚6‚¹Á—åß¼ÄyYhœ'/õ¾Úw–#þ2ÚÆOàø5[£¶Æ;ñ´¿˜ù<õ%^¤X¯VÉó öªÿB?v9'û›š¢sîY„ÿ¸xÍ7Z^½™3 üçµ&`ì—]põä <]RÝØ¥íc§sO›çœ „úÕDù‰7^y_4’Ž˜æ%“Z8GnS´“r _S½GøÄªžME§å“`W!Pj >ʯxN9Q„ÇyiÊ*ž²î(ÙòßQÌ+ëèôpKY½ùÑ^ä¹´¶¶(ûøÜ)&7aÅX›0,ܱ» êXÁüN½‘æ2(œn^„‚æN ÈÝkVÃä^*WA›ªä@ú©@Ÿi]DêÉÞ ý¥Ab@O ‚¿sÇ7ƒoÐü{)BØ(Ïç^­’z̾ ŽÕXkÙ¯ç›KøÛ_ÌL&n|c9¤†:X‡ðô˜y‹ZÊëmðI;Ê:ý²5œvz;çªíÞH­¼Ó¡ÝuOƒ¶Ôy´$g+hUÜ¡ØÊn¯?º¶VÞQÓiÊ:o ¨¥D[PjxóÁ½ +ƒò倉ÜžŸ›Äð^Q€òƒüäÇ"œ¿ÔsàRÿ‘ DYT'Wƒp÷(Á©­m×Ѻ‚}Ê78¢t%f&GÉ·.¨—‰;7À¼mŒ!lï2®4oúÆsÌZä{›âf)ß&ž‹Ÿ7sÜzNŸ+'YóôÑngûøÚzÊ©L–9Ðûœ4s¼z #þ…¶•b-d=ÞŽ¿Æ¯´‹¼Xñ",ųWø[`åÿž+õÎNÍVR½t¸Eà?øÿÎËvGðêÊ%ñÊÂ?/Aþ­Gÿ@|R¸,8+­ ¹ò°Ó= ls;­5Êr½¹\iË•ðD¯&fø†\FËpMJ o–z~b†ø'¼N-÷u1• \ꢸÅvò‘dWs@>Aq+Ãýqgރ׹¥· >¿4¡3ÛîhgË»¹sÂÕäç g.-ò+æ~/ÂÊdñHÌS\2ð´|­¯Ü`62/S2÷ÓÜÁ²‹˜.Òä]£±Ÿ»ÖúØúØícŸõ:Ú?¹¹2Í{Úc¼)óR†¥~¬¬¬Ø¢ÂëJù¤;I¿ˆ½F¦ºF}%E&O4júŠÖ1sŸÒA*_ËN¯1=£û#>†‡’C* ?ÉŸÉü¼Úwv2Á>”3†ß'sŠ®IëÄçxÉy†7!¬¯EîÖpÖÈtº²ÚxÖ™MíÀ.ç¿ut-M:ƺQ9='^ƒ·ÓÞŒÎ2'¦drHù9µç£çõä´iw¾Ÿ•î~ï" îþe¦deA‰Y‰Plçï°32²‡£gLÊíH‹Ôw ¯ÚÝÆ4¯øW;Õ£{”Cò˶\ecá*Ò,2 DÙÈl»b3€bS@Œ6§ͬÀÓÎ~ Í©ز9àã ÊµÀ u=°MÛr‘^øÐÈùŒ¿È"À³¡¯€Ä„ð(L¸LDTLŒ“¨O¬.‡:ø.ÄJ&U3úçOOë¢üöð~Ñ¢p/µôQ’nDË–`ýƒâevP˜Õ¡t9¸c–~–õÙŠ´‘ÿÄ‚‰‰Î@ßõ†;2e>¸#>g§?±ò¶¿?ƒd«ð?ØJ™Ô3¬w¾ŽUd‚[9rÏû"ÔÅÞß…´¿‰HÇT†¢ØCÜïÁÖÜ…à|£µ³£3â¿É`_§Áš$At¦{âq7 â¯z½qâýÅATÛÒó‘{ÎJˆ®õþ‚ìù±~0³ñ: ’k¦ùþ‹ÿüËg[`^9:³xÌ$àO#©¼‚á¹Ö:°Úå¥0é=PŸõﯹ{ b™‘6À»Æ[à6–;ÀüÚZÎX$WÓãÑ ùc²Ë‰!òœxž/s‡P™[ùãÄr”‚ƒ(xùËèáû4ƒØrÙÌ.î×àts‚[ÁþH°ë`€=‹'î,#]¼©H ¥Eyð´QySÝÆuÑB/Ån¡³‘ÚR}ùÆXe:J ¢nÇ mS,i5S‘/þzêðàÍœ’%+¥î:ââ‰k¯Uy‰È•5_$tΨ<‘a—º”\œ¯Ü:–¼òÞü þÔÛ/ºO²ñöÏÁbtλX¼kWËŽd†~5TH½„ó‰OÐ7xF-Ei}¢ó+Òˆ¨âœÓ8þ݉ùà¶-, z=_Œ5¡ûÀ{Öç`Þ¼ž‰®Fó´Åÿ·òÿ½Phz´Î?Ε'Ñn¾e/ÆñöÇû¢9Ÿk•A‹…ƒ±8ü=˜oÉeàþéï ÚçÁç@o¦W95º­}) –êCA¾Î\°–ÍAöóû@(2ƒ‚½@Ù-®Aá<_83´ vû4ìè$cÃç|“åñÛÆoBÜЋ¹J¬®øÐ\!_ 0ZÇWœ„è¯v2^4ßi‚+c| áÓfEˆ6Ðw@ø¬W"­Üâ=¥†Â;VYÈ9owN_îŽ#å ¦ÎSªAb%Ù‘”¢octh ]9ë/ÆW$„¦Ñ‰_‚_ÛOÊâ þ„‰ò,Ë“òµÃf¹Ày53ü iBây“Ô”!·'ËKŸ½\ƒUF_]E³ —nÖ&µ\ÿ»U”Ø‘ý¢=!#žÛÕþ0ÕÍû*Þ/åëøÎð9£/í 2)Gjns¢æÜ$ˆ“× ø£àÃëA Žþ|Û ”0åí8PÊ=xÞ,@ã€l¥pX»\1&œàÿœ ²TBc`jrÀH-¤¦mÂâAêNŠ%IƒyÊÿ{B95yFà‰¼éÍ}ÓryROx0´äHß][N ¯÷®tq®e¥r4¹Ò¯T^ìaÁ¯iK¼—ý÷ƒÓôìÔ–j]õJ0Uf /¥¤ù“;ÍfâBʤøV¦'ßÍ£‹õ…]‘ˆÞËêƒê_gÿÊwúûU2ü÷-vꯊo§ù>!e·{]dµAˆdí.Z5@=ëv±ÄU¼ø…i8mî Mü‡pÞdžà×Y/q&üÕ¥#H÷²B[™{DCýRl ~„PZ_rU á2•o Q?+)…2cx¢4m½ ©´&'÷S\/SK@•Ÿ¤.ï·ÂG`½Î8_Y\÷}7Õ.®N;+ ßb•½Ô)$ÍZè»Îw ˜½´Q`ß”K!ÞRüÑ>Úˆuö…ØÌÐt0—…²!vÑ_ Ú%6…¨H順 IoBáâÔbñÇI±óŸMMã»X­ÐÏÎîí~äY«ÌPºB¾_¼BfþÆ5ºNU2¿ð*PãŃpr_ŠýŽfÿú ‹ØYxÑb!J´ž7ˆ¿óŽ˜^˜%u~LÙV¼nê[i¿°F‹Ê‹ü¢•’^²[¼ Õv3ò”&ñ)ì ÖñÆÓP™» ×ø5Ò 5q“Y•fÜn@RR¦=Ï»1ßøÒýÍ8{Òñ%uEœI}ôwì‚ÄûÆ6Ë ¼h}¡Ÿ1|Ö/ú§z;ûª¸§w°‹ÒÊ—éfãeuqŒ-Á®í'Ïy¬ë¤8½!Ò¶{ÝZ±&Æ•x¹x®Þ-r9~]ÿ;?5VVŸãÜ iZO$nQß2¶–_ȋʟÖ-#æ[„æÿLO¦u¥¿ÑF«Ÿ¤ü˜Ð"–¤öðŽÏ¥·6×p%´"r‚}k¬ô7w³; E+ò¦®ZoaºY&zh™úeë øRc÷Aon?Ão•£»ù'ãí]`ìVj‚¡ä>¥“{ -¤òvÙ?þ×Þ~'Rw+ßs†îÿ¥¸ó˜#¾* ÷+׃¯Uä*hõ•LÐ —¥^ðÐúä–Ç•”/PÄ픵äªK"cyO”²ʢ܌}ÆoTˆ¬¥µý°‰¡E¬¤•чµÁaËj²íÝ9¿â¹¯øï¢È±ŒçFl¸ãõÀM.œI®ÓÆsxÍ+ÂGh[pÝ•vcT§»3ißöüs©|3æ@£(w¬H`!íÍ–Z[쮡jèÑ‘IïBôïÄP°-i9ä=J'ÓÇAö€ô°#d.¼š±˜r$aÿiâþŒ×µž…y¢3óºÈ…<.ì”6’YfVT‹'õˆ#BÆø<eGó£o`¬>oêÛÓØ’4#ÚƒæÚÃøÏè#Ö`ôàõøçàÛUxW=">@ eFú"Œ³î~ð‰ mˆ·Œ³ù5A+Úá=(v´É\H-Kµˇp©?«Áú­‘Ú r#@>ãž…ÀûÐó­Åàk.OÞÕºêr§!¨£Yúóy.È ¡!`¼#>íZþûà–rž1“µ 4“©À(7¼B±øW¢êàI}x ïº06L]Ë×óOïe2ÁzQ½vÈΟvªB,ÕoµÈwLŸQñ©þolfŠq"¯ú4ÈÛ™à'×U¨©ºÌ½üu »¤“7ÐheŸµ¦Ñªp»ûˆ»…»µ0ñü¢îÌÈ\%äÐÙª“k$þIзßyšqþ çý3Ä\yÂh«xn’¶Si`Dš1Äzƒ˜¯£ÕïõÁæ/¤oZó‰ú>µ—P]ën禯§5WïhÿƒÐŸpj£¨Ÿ9)H=èܽ»»¡¤8AßéÍ1ÉYªpÛ‚RSt±À] ê*Ù”2 Â’gÆ¤Èæ.Èd¥ È3Š<”úàn߃|]ô9K;ÎsªÜëÊ p¤ÌÖk"äóJ2~J ·/ë§ 8‡‹´¶Ñ¢ 5¿÷½O7óIí1¶ý“¿z|•¾‘N ßX\s—¾ÀjT?rãîd1ÎÜï•¡Q¬'ÀÚÍ1¢ñ«â‚öË…Xà Nã·„…ê16w˜eÿäÀ ³”:)öá]uF̦gèõX_ÜÐÍøhÔÀ:sž½Õ%°)Gª^õ7”è5^û/öãFàïº/ž…‡ë ÐHù|+©‰¬¼‹êŸ)ϰÜ÷‡òû}½dYâÙB¤ w>SúŠJOe«S›|­¾!ª¾æ¥4n9ûÇΗ`Ê¥H'™ˆðõóZr‡ñ¢/ŠèM FÉÉhî yYÐZ­çNS?%ÝÚp^Sr7×ßg½–©UaDî})׎j¢ûµJ<2Û˜s©aÎVWáÅ7;óQ£8 áÚ<‘KPØ šä'±ÂÒŒaS ³~•¦v,Óƒ¤@à,è¿;ã +ÉÆ4ð'ˆî\ ”æ>¢â3÷oC(ÍíµWÕ!Öb¥£o›Y‰!Æ{ñÕœ œˆ—åQà¸Y“çÉÑ Ö¾4/‘é?iµ¤¥o¶¹Ó×ÊìFYÃØäìCícØÆ°xM÷Ü÷ñŒzî.ý¬¹ ¡tòv‚õŠ‚ÖɪÚ(§+h›• ›u”ç½… mä5<±™¸ÞR™Œ®$RXÆ9 ß+î<Î- +'@nTCàÍPß·®8ÞUm8Ï-lyÞÛfUçŽôåãØuŒbhn_õX};Á:­ ,û]ý6ªõº±ÇzÖ_#4öqÕlh”ã—øWÛŒˆïõ]bsì¯ÀeòÍUÁz ¶-Ÿ‘OlyÕüÐØäN±¢Új«¬ÕY<ɽK½èNgsbK”$šÄL~Å‹|ì•@‰µWs ÿø­,xòÞäPfÀKþ‹ù{•M;–~—¯~pö'Üü¥±ß° “ìWP#/¹ñ¼†‘÷zx©Ùó:‘þÀžJFŽRX‰"ávÎfRBgl}sBóPäƒüBn#Q?¾ÎÚ³ º‹6 S½¦8‘Ë‘%hö|w"x¹" Þ—ôgŽÜ®#~o¼øì¦^šÜŸÖ>£‰;E뮎q;=Œ°;$±iÒ¯™\ +ºœ¸}ÇùÄ·0 ØXx¹ÐÒ—ßïþßžøëi_svÌåš?Gô籯½œEFÒ5c0®÷f¬J±ŠII5´¤|xœ¼_©Å¿¡Sî\ìÄ$jã$:¼I‹Ä½b $´à„n;)8Y;¡iÚ-R§C`¯¶|¹Æð7Þß·ÚÐg(%À×8pÚ¡ÞÕ÷:×”¢ ÿÚýx1á}Ë¢™ý-ƒ½Í×¾¶ö4”äæ,ðß±çƒÿ¯øË ×wTP*ZÛA+n+ ŽsW‚ZÙùÔDï_P{8σ²Å«j#êïìUxIxÊË^R=([¡Êçô8¸½yÀû"ÈßÕ ¨aåÐQ4o˜þxï¹ÁüH½Jc0¸Ecç¤n€·E}Ë©ï[N¡SèuÃ‹Ö æã啕ߣ©œˆÅ|èëJc6Éñ½þ|°#Æ*ˆµ÷}æ`£¢/“µ îáhõ„ý„ý»âÍøbSåiž óº0Æ.îQ5úµ*xÛ§,äaÁ`»"ôkõ´ovkr}+Õ¤ÿâÿræ‰EäM]>|.¯f/1û2"þ›ú³l"„–%*Zíôç¬ò3Mél'š_˜ßƒû¡[SÖR»è/Ê´B3Ü–žn/ùž;‹ÆÊ$·†²P¹åݨp¯üuµ{ú§©ó•tß,õ5õù¤¥ Ó•nÆeÅÅOÓ!w Š˜íüÚM‘j±ŸsÄëâ蓌 îëžò9ÆSÃ¥è~6ç!^¼zöPsçàTÊ © †„ä3úaHl¥Ü†„šú,"Ù¢>!ß9·}i@اˆ·xÑw"6Ÿ¡²)É¡û% žvÛÚÝCåhQ| ÌÜ z#5˜]CMI8œ5^{ªäëö‹r%nÝ{«ø‘¬1Šy°§˜šý ZZÕœLÎ¥>_ø§ìš\6²ÅÍÕÕrª–™oØŸùbvQ»ª¾–T{¥6ˆT»¢ú+¹ÎN¥%¸óDðfŠ]Àçh@}ÛdGPÇÉOÚaÏAª ÝÕônºÞO?n}iÔÒÿ±–øËëµcÇƨí#’*«wóï§–oæ~[d+ù÷F¯Lâ#‰n(×”èÉœÅ63Ü{œþ7 Ã=“?ã½èÁZøí®~úÏþ¨ž¡Šíô©î(o?ÙeEC÷K>ŸË-Z^rw)¥¸lWαÃw–í²Gô°ºÉ»áõãéÎ e¾»ß¨Lòö9ýÅ®¦ø©i7•‡ùÀ+þ ù©•Ë×önõ–¹Õ]‡/ãl³©ñâJUˆw°oA´ˆ·¢-e-ˆ¼à¦C´¢Ö W[» rÇ{rÄWôé»ãòkÑŠÿU³Ò•ë\ºÿÙWkñ¼Áa‰Âï4æ„L¤'#ÈUÛò§8©ØX^«h †¼fDÁééÕ÷–÷,xoc€%m î&ƒÓA}ìE|öïbXÛœ2`õ{!~Ô±!Þ\V»ê@äûçV-?'ö!ñø—b8×ã½”vTÏ_dUCæ~ïŒÈ~øð8%}IiÖJH++ÎA‰‰6^Êç¢2q±ü 5%I{™|Ñ7€ÜÄŸÔ¯¹ô´ùüêK’›äþO½6b‚COš†Öv¥v(à»h ,‘; Vª“B‡²f‰§2>¼Óža%n®æù²/çðbÙõWסV*»!›Ë¥?¼gO/òM^ëh891öWAq½©ûYÎqˆò:óœrø¡Jô¡…'¾Ë®‡Â­¼YäÈFEÿ̧PØœaNÁ„XE|`¶B‚}Œ;`ÿ%]p?àx d&ð€¿€¢¬Q–(£X jqô¡b+øÏ2ü‡°!x Bfò›@fjÓÓA>Ud:¸YE[€¼]d·EjF>¥}3Ò¶xg§'õˆ\Iïøþ±Rò-í£»²bKž¹z¤š}>§ÊZô+²ÍàÆÝ" rªÞÝžríº6>ÎúTù‡Ù§SÞFD+fþÌ`ñC‰Ï8¥ç%£Ÿÿ½=B¦>™â ®¾˜}¤³AKg žöxWkãªhÆ #!γ ÔïíÐfùl N|5(Ý­/ÀXž¼¼œ£PöëÙcAÝ”|üÿfþ¿6ä% ×®*pmÔ…dÈ]á=QÔ{ä¹Dms?8KŒ: œPjÏ€(*ßwO¼ÄÝ@ceŒoÜ5·‚ß­Å`÷üÙì²®(±æïÁ}_K†x ;ð¾Ò–CáÃ@O\+î;ÃÖ?05#üS(9Z…jÕò·æA¸ˆñ“;6œ§Äæ{'˜=íMÀŒì'ðEžc\±®@d¿ò œqZ@ö ðç` u‡üùè?Ã×ÖŸ}Œ3ѸiéÊrÔ¤f2‰µØ ‰·iÈã lÏp00€ktö}Lq^ô“ïáùšÉþäÖ0Žtß3 ø‰VBðm#?úvŸ Cm d¦Ýk ^(ÑùNg®—zãn˜2%ÊÝïŒZâ—‡Ÿó¸híÇûÈHï•ÿ÷WÊØüÊî ¤á–ÎÉ„ñÏœocÍáV}–—îTÕV:™Û•]²ŽsS™/“íÁbŸ¬+³ÅÒÅ_Äù—Óâ 1XJ±Xí$‡)e}y]Ôú$g¡>Ãpœ–ÆF}™=Ñ?Vs£ç“©¥Ã’›h›óF¥j¢ ·|úôÇ5‹tÇ}x«Ä>”¬j%®‘wg|™s¤Þ¾Tbª³þîÔôãñì•þŠîÙ’¦v@Õ3—ƒÞÛ;%»i7ŠÄo(‘´gc•EçP«èX>PKš‹˜´Û:‚­§Çþ@W«;8šð¶ÙšÇþ^ÖeÚëÏÛ»p¥v*ªö§þæ_ ªÈà+mŸÆÕšzQ´·£Ÿ"äc=~_|pYñ@}h h4N­böÿ{ü÷~f-§M±£ÔúkÝXþ’š€O\q¸C¨žŸêÖD~…ˆÐ8ùxåq\¾f ×NñpVÙ‚““/Ë ñHT`Iš¢ÙÔ³>TtlïC1‘êuŠ|ÿTñyµÕÊywJâ*ù·{JùQ<²g3É´"4³W`X[”|ˆ÷ uë²nBl—>¢où¶C¬˜ÿÄfùkC¸n(bÍ| <š±·`ÆÚà+Ì¥SØ ­¦cD„–É êÏ:½ê"3¼2ÞŠ‘Û>…»Ŭ÷x!|Å9?ü›z7¿Ttj¤¼±ò*ƧCá# ^ñV ~vwë©\LéSjÏiU´)ø~UÆsM[,çP %Ð…ºº¡<ê]þ¤P›)sFü%°[”qo²WþæE)ª óvñÃÍ4ùîW¨Ú;T-Åmòƒ‚ _Ìoú’øpx8|óÅÐ׉• ýÍyðŠ¼ n·ØxP£/°‘åà=pØó–Å÷@uß.P„Ö‚oWêHü”ô„^@·ú>F†®¨ßó(ñ¤¯¶L ­SN¸s}û´wcšò²úKì!$$ƶA At^òTsÙ¡E‘ndiÍdî%µ‹õ¥­Ñ>ú$žÿ»Ø[(W[üÔ¼~%R |U܇à+ïÆkø2coqJÂ6J»ÙèÆõh3ziûäx¢úáØK²—º vÚë¨ö¨~MÞÏ|ZYÛ!6¨x›Ûÿå@®î¢­—ÇqgûÐk¯¦ÒΠ6×{s…íLvÛÐO¼ïÍg„¥Ûz93ÝËxÚsÞX”ä‰b%Èï-ðªÐ œór%ˆ Âõ¢ø´“ÊvìG“½í¨Ö7Êf”´þZ*ž×B©„¬ÆœTB;(‡F÷++¼iu•–î»Mì=î·âk‚ÿ×l˽ȱњ–R üÅ„ßQÍCFu”x}ýDü‰£ >"p"}Ó à•PwH¨ áò‰@äPb n%.G†¿NšI<öN¢I~VÉÐ"oi¼¹òtt¶UònxÓù§ð±¨ÀÖ¢fþiÑŽê¥bmð2†•wpµñ±ãè¾q²!û´Þ ø‡(¯2Hÿ•óü O¢‘|AÿIœ—/k œð)MÔ:^+qH|å~#‚ÚPg?¨[ÜIP{¹• ¨§eMG¼Õ ´<ú¨«£ nWÇ!ƒŸÆÖƒRÍîŠÐºò èwÃk@éTü‘À[‘÷09PŒšIƒA+¥Nñ±l ¥ÐSôòÜð~Μ©^p»ëSÁ}-tä*³ Ø?©ÛÁ–šî\ã°Gqâ¶þ=˜5“VטyžæKø¯^_b| ‘oB7!ž¬±þýÿb`äNì‘Û‰§¹.hÓ¦°Kâ-žÈ*0.˜ö<æ,uÇÑ$üKàcæù÷׌ÈJI•‹drVßC6âÚ%§¯–ªÌº‰êb.Aè“`\°¯ƒ>žúuÇTM{ B»«@ûÞíÊÇÎfÐ[zWAiã õ”Ì¥•\âI·8(óØ Êpï#äpGHª‹Ê ‹ŠS ³•²àR^7¦”zñ¼aú)pÏ•@ö% Î åi°h?"ÝùZ p¶ëwöCýYp^Ó—}[ïö£žuU‚gïô-À2¥‘EÐå“dXGý#¸kn4æâ3—ùÇCøw}ü-¯”ÞÀ¹®6¢¯9ÑûJä›ë"cé¨YxÖË ý)د¨9‰¯‡ÿ$Û÷t¤&#2ÍJ4H¯ýwÑÍØ¾æ1ôP1+ ‚ï‡{!•§cÉÑç~VMË,2;þ‹}{pþ<¸Ó~APö|z½tKW‘ú‡îq„ñ>…°¶ÀR¸¨n¥dOµ·N.KåK^YÒC¹|&£nUµ¾ÞF]ö\ÎOg þ”÷Åc| «œƒýä?¨öï4§¤IáüÈ%u„z -‚Qù„Sñp /©¥QíÕܰ¶ŠÑÜŒöÕSæê-ø+öŽzŠrÞ=Q˹à.!×z×éLªý’ú̫房Âûo*B|/U &‰B¼fïQ‘þÜ®x×ýß‚QR=êekÍ©¾»úpŽë­Üv²…:F.u~Sµ˜m 4i?Én€ßüsÁ ã¢UƒYj4žÂtËÒÝ×Eÿ-sžòý6žRÒ]†Ï7×½ Ú=÷YÐ>1¿ÃÌoê{ú=#/^’Câ„S‡Å¢P/*?Ð^¶§’˜&â9õ²Sƒæê%ß2•x4ÈÓ,õ.QLuõm¤‰O}eIÿæm’Ô$ œÄTFÕå_ù‹ƒlª¦uMäL¥xôá ozÁ­îï(ÍÁÛ:BTör—cÛ¿²’kN#ÿPòä«¢ OÛo«xßðÖ*-Ài%6 ͧ´9Hw“ÞáœW¢ëN¹cõ¾\vþU·òd¬£o/™îYý}|Ödý ¾˜¥¡’ÕY»ìýíUl÷ó)C,¿øi­ñ!¬bØ«•û×ã_Bf6í!ù©'~ûüJ{ÐNå~Ñ îº§?ë÷àLˆÎ”£!ÜÜÓ ÜO–€¼ŸbÇ ú—|"=å)°ûªoƒñ0X¬{1À`ïå•q•ˆ¨â]ö|ÙëÞJ.³9 ê“úÀ/â\ÙT4D ùHeœàMQ„ÛIÕ“þ¦³)[xfL”Í|ßù nÐC)$Oø•¹£o÷ÙK´’&Èaî‹ a©1ÐW(¿u›Ê’J£ðWá4ÎÇ»F¿»Ì£‘?x!þjdÒ¼=‡ê, ã6Ep“¯úº ¦¾²ÁUt†P-3àr“˜/èŽ$;dk“¸¸'vó—^Î>ÌZÿ/J†Ácú_¸RÔ¡n`®vŸ§;[õ*û¼´þÓNyµƒ’b Sçû§[D±¤½æ®ŸÆ6SCÔ³L†®Xc)©_· ôÖN„6Á¾zÿøW Ìóƃñ¥y„å_ghl@,MÁ÷²µÄ}V‚ÖØ:âg7¬Ô¯€ö”»Du9ÔGÎuc3À¶dy 1ÄRß¿ØÚ:õ>ª¬¢ŒCñêxkÀÝj·çPÂ'8â#éG³_SMðÞÐ_Ãrkˆ£àì¡+†93P LoœX}G4÷Gß,p‹ªfĸLÔú@+Ëè:>g®q”…±&þjLµÒý3Å«=™¿ct• Ì–úwN3w¦hhî07P/þœÞƒôØV+ ÝãnED/x7A™R:§ö{S÷£‰×Ôéÿ%þg½tõæfï»ì¿?áÑ ž—+ý‡ÃÁ'Ì»@v—qÅ5µªïà\~2 ×9§_ôåS_<ðq_Ýзüëâ–ßrF:Dl¢jôÛœ7ñXíe"hç@ˆ}žÁõž,Š)ÏÙ«yì©]cŸæj­é¿]p“Pjå"·píº±B"+rš‘è[ä_€–ܪX ¤Ê~¤}ÀªŽboŒm‡øó9!òÞÍë ³rÞB—+ŸàÏj=Pƒ»ôg¾L¯3Ò‡2ÕxÇ}‘¯}YI­¹/bÑßäúc’ð©“bÛ(oÔÒöê·­—ö„üN_“ú‹õ@t4_´b ±ä¨¢ÝI˜ßO %íÉ›)Óó÷“™œSð.Ï'Í — ýU˜’Ø.: ‚/Ç‹Bà÷Ø]ð{v ¤‘cŠÐ;¹¥Uqgâ)ǸΡaq_4qåhi&')¥hç=ÒßG±×{Á.n<³¿˜}‚ÿB´f¨„_Iƒ ”ô:¢ 9y¹ד;ð#¾@vªý}GyÖ_Vÿ”Jš2’ç¤è†á_9ª@C ãS9?µ9ö6*Æ?wPÌí¬TG*ÔÃc¨(N;oŒ5ñX§¼Çgú9õ,;?ˆÈø Úc„ÞQY¢&¡ˆöâg>Œ ÓêyCÔ÷•ùÒç\½AڟĬñsøí›â}„3_ù,¬T°ŽÊšß%¿3…*`æS°.‹/ êƒ}ËX ÖHu)äÆÂàGBà|RËÿÀÿ¤7ùä!:š‡F€ÎÞ‚ëD8"Þ ²gË·ÙÂZñé²kh/Ò øm„³¿ *x“­ËàÌÔû±{ìéêT°Û‹’`ÅÝ0¿6?ó#ñX£5 ±Só²>bÇœ0B8ê´H¹72L$BdŽ‚ÌÝïJa¼q5WÜGbà\ð-„},|ìEùÕ ï᭪බöAú"†AÚ;| éÛÒRªvj@Oé¬Nt{ !NBˆ:Á&@» ‹p©›ñóøDÍH¨zÁlÂz‚ ü•ôWN.»’—ÝM4íÄÌ)_úz-ìòßÝZ‰^¶ÑÝZÞÔ"k—Õ¸h‚ËÖÊŒZòhôHò>Іo†¶r=o°qr&ˆ»šºÿ<Û¡ð<(lÌ“ýŽjߊÖ §»ÁYNSào4 '€^@ïE|:Ç!Лf:‡ I·ùRúpRRCê ^2S¾´WÒ ùëXKþÏ?4Û_ÿñÅmýhVj‰}Þݺe†0ÿæ•Ërôê’JïÒðßJ*Y·þ­Vr_®/¿fÒð{%‰Þùƒ$õÛÛ.Imp”ÆÅ:±ÒÛç/ÏOþ‘‰£ÈMhæï@¯„ÃÆYF& SêcEì»hzKoŠþ™; |ïhÃÁØ)_=DMПж‚q·‚>ÏÞêÈà]Оˆ5e¥šê‚PwàÃØP;¼Áñ{'c3¶ýßÌÿ÷ €]ÀÃüé`çÅþ7C$ƒRR‹RT(ïlo¸€¨àÔÚ{Á뤔ù¾^Dg;ÈÆÊn`½¸r‘7äwʇ@E¥:ÈŸEpL¸à=”AöTjExä)¥*¸ß+ëqDš£¹ë•×UJ>®|Ctcš)zsØ*®–g“¬Gº¹Ã)á}­FxìL„wYh d¸Uijà,uB@Wõð v]Á®«Vt@±ž¶§#\×êJ;QÔdŠâ ð¡ª?aò/ (óäMÑG¤ðXT#Ä!Ѧ¬WS'S×ø…2l÷zÓUdyq«ßÉ 2” b=†š%^uÆpPæ<Íb­‰û#šÚÍéÎ+ú §8%ÔçÜ.H­´ó,B+êj >ö.‚RÑëjù<]¦€è%¯ØÇae8ÔøŸŸ-ÀG"0Zìé‰ÀaNƒ÷ºR¼ñâ]µ•*àµQàÜÒîã¹ÅµD»¿ºŽcÎm&Ñê2¶¸?jÃ鼦ö—ÍÝZ¸‰ÞY\ÎjPg|F\©”ø§¥´£˜<@Çç.·”´(T3ØÀõG¹úªâÎ%ìoc(¯ºby3\d$(É.xâ‹AœôÆ¢ð‡RÔ:Î2ð6)wAmé>Y(¾ÑÂ>²±Ôó4N¤”ýŽèÂÿ@Uò8|¥Ÿó;O…o»~Pþ!¼Ó^p÷ñ:p‚·pÕŸùG“Iœ¡4ÿò›Ù´Ä7Ƚ)C²S‹ŸªexOY¨,E:»ÄTå_¡±Ô ŽÑB–Ë(KÑWÛ-J¢Æ.‰R v'èu§.xŠÒä ÊÏà(!Ëñƒ{]]ô¦ú|xòQ Õ)ÅYp>Tá¹µ<Ò­¤,Cµ_Q?Ãs…ú ŠõšÖ—ˆ¯†yÁœ¡ b ÝV™¾voñ«|MM¤„sÀýÏ~Þ<ˆt¥‘ˆj§8GÀþHìïsí°^rÚ€uï‚[IL;U¶q×8ô— 5ÃÓÚòˆnJ夸äf;©-Ñ¢ð®[ ”iêû TéQ‘µHQQYM˜&î>iÏûvqŸ€úyî7VU®6Ýr2Ùr™Ûž,YI%ÃãäPš¢.õè-gðs¨Må5a!‡ÖVÿò!Ò»ä^BÈeò=L±SÉE÷¼§qØ›àÜä²zP™F®ÖOûŒSZ}Ñžz¥þ¡ÔS_wk¬ípWãSŸ”›h®•ÐËDÑVœôzƒ²Íyˆ§ q±E;쮦•2Ý©êy ±Åž„"?cèçÜÒHu[)n¸P´éò}P︭Aüè.µ®wÄ%9Ô½u m-Šþ¡– ò_%Æe ò¯wKÙÀ%ûÃ@L»ˆÒ Ÿm‡ú"gøiŽ×碘ýÀ®n”3nL…øt}ÄzO@|zp(8™ÆeÿéÛƒ«ä ¡‡3x2œTÙûÖßLZÓD7³¶× "c"ÍR`×N¬ˆ›Ðº\TíU¯:Ž6@~ˆ¦ß£Ûµù¢¾¼¤Þ¢ˆÜ§ô]=ŸxEýÆýNÊbw.qu–ëǯey›9 ˜n9J¨Õܨ¨¬só@éA ¢¾©Þ~loŒW•œõ~¦‘2[íOWÜ`ï‘q±›¿QÅUùð¬0p9(â¸ÞB1UÜä{î)Šyh·UšÐΫ(àI[Yôbj=Tï®"ÙëVWôú¨hävQÿ"æ&¨w¸ƒ•wîœWr¼)ÞK¢˜7‘Ú¢–ÓBþAi§”xÜα7A{µð-™å««øÜ$Mñ0ñœ¿e|>}Õ¦æ(v¤7Wò·Ò%¾–gõãvdB+Õ÷·¹Oßg½ ¾¦ÎÿVèOX@ïa?£06ôÝí ïe¦þq¸>ý#=]kß ï«Që¤|^=Õj(K8× R…§ä¿üúÒfuÚ_-K¿"+PåïŠi?ËéTÑ—:¨«÷&PSùĺE’Ú•RÄ•ån_JL4@Q[y~4a›_£ˆdQU½jôEˆ[±ÀK³€è*ÖÍ¸Ž‹+®¢bêo‚ìaÔáØ›ÀûX4™,®‚;A= ò/õ_pÏ)£Ák©·*'Áî Ü÷¤ñ¸[ô¸GãÝÌï ½(Ø_+ úÈðÀœg< ö868mô|ÜÂþ˨ñ"YdÇûÓH·g_H%ö4Zô=³ÏÉÊÅ×3ß[Ô'G¨Ï›ßyY¢¶^Îþ‰‡Ú0g6EtŸS…ŠZ1{ ïªÕœ+¼¥?t>ÂU‡¸-@ÍvÊ¢êgÝŽ ÍwW‚ÚßÙˆ«½åÎEU†xÕA=âîÁQkÊ1X¢•³žB¥w°ºBÞá‚(ê¶æŒ²‘ÊTm=A5%¤Ì$¤Ôq›‘ÈA7Ž_Ü` ºèE>šˆÊ&@IŽ…"(BP‹+¸Rª¥P½jgàeùÐC< NQäA1¼ŸÔéà]QŠƒ÷PqÁ»©÷y¥;xÔxž_=„p7h6¤&‚;Vcj¯ãº£´wPÝeZ ¢ö1u wª–J–ÓC[Eºûœþ%¬Åz?rÜ]Ê@yKŽ”OÌ_å,U¬,ó8m‚¬ ÅôWíÁ, ¬·^ãºò³5Û×ÉpÉdf©²ÒY¯FDXÞö‹¤‹géXõæ•û¾ÈÚ¥vùOøÊYà}m¦€h&= ®\¼+êâŠz^ETÖ+{ÙDsù˜%$dP(ëg(ø”š|Ä9¦qÒ¸Tg¥ÏyÀw(Z#ñ3¨Gdì£ìù•VÞ# ð,ˆlQ´ù,ùŸF&îMÑÄ-†¼É-7Ä,e.½™àiÜ㲸Bïɬbc0åXq½×A¾EEO Œã*È:ìNˆs ¬Ò;Ò[ìÙÙ; ôµATòö8KŒÎJwž"*‹Ð›%Ü]y‹³ô PÌ‘_ïc‘«¤&‡/˜ÍÓìÇò‘ÌCˆ‡b#žx]VÖÓ•úXlä×9F€Ÿ¸à}ϲ@zÞײ§ *Zx ÄqnRW”÷”ƒÅlï O"±8N6?(5É!Ó{ƒšr3·ä1þk($¬ôd”üÝÂq1Fœåñó<º¨LB¸$É)¨ìUŸDEe+’€w ›”Æ"[4–9ÔÖKåt™Ë«´ߢª‹hAGoQÙƒ“b˜xWy™4– eÜK¥¬ÂUe§ò¾Èå )#ûÑŸûâ+jŠ­l@b1!ï‹bÀ›â]`…\†ôZŠ?‰ˆ‹ $NT¼BÀûŽY„äb7 ù…?hÊ|K%9‘†lmðXÃK(²¾ì Ø¢ ˆ¿õ/€ÍÊÿÉÿ¿| ñ Þû|d"ÈL%¼²2ncYè)à5ä*°[Ýò.S@é¨5½¬ï8Øyöip÷Û}€²œNZÑxFtn‘¨Tõe} ˆ½¢8àç00Rú@ÊÀ“¸Äı„câOñ9Ï1J–/Ý{dˆéàí÷4Pr•ÎÄô#‰€û‰œ ú×zô)F ð^{D7 ©éLr®RÄ9dE:‡ìâžó™åîÑß@ÏYàžõ¾2DÙÄÏ¢(m¢•@l‘@4’Åq•{â2E£&ލ¦ŒcºhèÝ’¢"Wd7P~”›€òÎ*C½ND²—Êw…8 b uqåsÄP•—XÀ>¯ãÈÃE  ‡×ä‹,Ù–@‚ _æ°[dûƒ;¸+6óÄŸànñfA°Uò7ÀYñ_vÀ<ÁŸñçYLì¯p1d#‚XhœB£ «Ù'ñÄc,úêÓ0d'·0É}de°„ ›óÈy[V©KäU€ÌPÆ×À=ü¬w¡·¼Bo.xëä¿à5 ä¯â&x­¨î]Ù˜£¼j'c3¨>åoéÊàuôÞëz¬38 ãW@뤴µ4ç@=)w€z  ¬! Ô$P¿%OÉç6Šò¼¬Áe¥‡ê—!e¾w[t½D¡Ì Ü*ßg¯ö<¿‘À[$jX!‘æ}ÆšÛóHÒçØ?SVj áIãšý2ž>Øê‚b|h½šS‡íwy›$u'HsÉsßæwpU^ïú€gá‚Æ¯Qˆ‚† òKöí¨D@. ÄqLOrÄ8Z2 JSŠƒú‹Aù™$ª1ºpI—ãÄE Ü?Õ‰$9•Œ¶`Ÿ3l¤¥ë‡VYãÙvßÖ˜Ûô¿¹iT#òw{Å4Úà™U•(fSe7ž=\|À×LñMçœ^ß8AMu_1\È1”K²‚×d>ˆãüâÕ@ŒÉ Fyw@ŒV‚øGq€G Ê*E€~rˆéî!eôÀ{+ˆkj%`šÖ8çôîÛÿsïgE±5zÿ«Ã޳'ç! 9Hˆ €Š*Š• ˜#**& ˜Š‚DQ *HœãÌ009íº»Þ{ŒÇã}ôÜsß{ׇšþõôîªZµV­\ý°¶P¶¨ÿ™Ìÿ: dS T"‰Ú@ þÝeÕ˜ÄKÎâÅ÷6´&¿ÿD”KM®ÀÂ(”ßqx…Ooyˆ$\ß¶ÿ Ùd¬ÿÙ(ãxÙÀ/F©â.fhÃ0àT.,PѤ]òû¬!îÌn @ [óqâg`A}“1\Ç€Ãt6ÐØŽê¿¯ZkZЈSD¼_‹ @¡#°œ×€dšoÐð¡|šM Âôºs¤g¼ZMfD¬Çá?£Æ·$(VÖ€¬ 2þÁrÉÊYI’Q&.À‰ t  Ø€z|€x¡ñJÀË.`3kŸüXÍ> †hÎP %^ ‹”ÐpÓ è-ûE. “ÿ;–”&Øk âO˜üW|4b;ÎÃ1@`ülJi´â\ /rÐ °Pþåíæ_Œ£iñg´ÿêêZºnÚFˆnrmÒ6C|Fö&­£Éu:ÑHI¼éÏÎÿòþßH¢ÿИ̠%w~Ú" rA2.r¹’|Ê©úG}t§9Û­i|C÷HLþŠTŽò5a9žjêe™|žmÊvºa·ú0†dŽÓ†u=·á´ yœd³@NFˆÛ(GŠyâAPîæM°–2ä$9Kê})ª1•u\NÔ¸˜™XbA9"ž&b6ÈøM,7ÓÇz„;0ÅLñ!Wð7ðGÈÆ¢`‰—ÙÁ ÂÄ.'ó0O€/D §2ä#"XM.ÈÖb8È Qf|IÌ@Ê‘¼ï‰j޳J¦§L*ûè™g ÈZé†ÊqXhÊ'Hñz9‚s¬ÇPX&*ù†s©æqT$«0Iæ 4ÎåsÞ÷ÈyÔq/0•,£HŒ“k9J’OwŠhNKÖ0Md2Á$JÐåj¹Kœ&¾q€7A¦Ê@: 7ûŸèè¤G çÑAwJ€›iA„ A–“‡É>z ðag[éÉq9YlàZÉϹ“«˜/Æp›¼„k8%\‰Éº¡âg5EäÐ’wäéÀ rE´ç,ÆS¥t–]( *û³‡^¬¢PŒ—w¢'g#8ƒˆIòN$½äí Î@ „ÅëÀµòa`<Ó˜ °¢À.Qb- H.¶F"¡<ÉqÚZ¯¦¸ˆQõ·hÇÙê#ÜÊLNPÁÿ·ý{ˆïñ=,.ëh@M‚C€(nÀä Ì—€ pq7`GY€–ºÿ¹ÜûoÎËb pð[ùD±èÀl¢œØƷƽ¶©Þ׆þJ÷3šà°€rB@ãœ4ê<ñë]ü€  É| ¤° hÃy@3.²hÿáPÖrÿ3ˆÏ+.cøu¼— `R ¨ìâ¾à°u@„tÀN»›¼'.©â«Ñ©É˜ÿ3Éòw¡)õ×6iÛb ˜éß¡i³ÉÈÿü¼ Ä‹÷×NÓ€¸Ü–ØA-PC-à¥-Pø/ÌâXÞMèÊV@r& ÒÙö§YÄĪP'€–R€<Ìl\&c¸ˆSP%@6`e˜ÓÀ—Tÿ*”'˜ z}&¸Vº«Áõ´{ (×hƒë2÷P~U/ª(²Èû/ÍÿÏk¯#PÀºÓ €Unæ€ö¹îbD ˆ¢oS ²ü(f)ˆöâ#À´ •?Rr8Áv`Ù@y€çߌ þ÷¸÷ÿ}ˆÏ1®ëÆ÷—8•$t¾øÑqŠŒsË?ùÂ?Ù¤Uš\Ç9¡€-‰Wd¯‹h ®íÍ8Ç-·LR€Æ}/.šî3M­?Ëlr'n_×q ˆQT²(æP‚Ø.Ÿ±¤%ç3Ä:+Å3Àçœûo»ªcH7Ï€x˜= .âÐןVïïPèþ&×™@)逧‰ÅþNkø§Eþ©Ï3ÖdœMýAÿÝÞÿé¼D“¶éøÿJö84j~qŸ×6†Ð÷ùŸ±×—ÂM®ã­ÑäÉ?[®Z\ÆGÚÔ~µ5iÿŠ:þ¾EþWØúû˜¦É|c€D*PMðâZÇÿQOÿ-Ø@·?ݯ~\CíÔƒÿ7uöÿ=hº®4™QœÂö ¶ÀÆNº4ùÿ_ÁIÍ*Fý­hÄâ0’ÿ I܃Æýþ¿‹ß¦o«ù}\’B@ °häŽ@£”Éý}dÛïoZ@¼Âöl Qæ¶j2›?¢)žÿ)ünÜ4z,ÿþ:PTâ‚vãBRËOÉ3AvCäGHn½°£‰În°€pU€—:$%˜Æ ©” õâ lìåì¬d *;è UöÐIsJ‰²‹4™K=aQÉ¥² ARE”0åØs7)¤Ð•:êñ@’B3z fC|ëiÛd–zca§ ½øŒ½ hTjÿâ«,’~Ã*ÖSøØ’P›=ÀLbÀVZ èD0û¿¨6Mi%.ÞN|þÂÀ„€×Àç8 (Qÿðfþ…ÿý¬þw¶ùøjñÑh0Ä!I°øPnŸø³­›à;.ÚòÆàYVâI ˆß { ¨€ šQh ÷Ÿú_šÑ¿€ÀŽ!LŽÎÄÈã{R£`9IÉÿDÔTrȦuBˆÿ”ñ ðŽì<"²“«5üc#ާ‹ðð+Ð躉sDÜ ›r©@#µ¹š`®)ˆ&÷ãŠña €0v ¡Êÿ曾ç(ÐHÇlÆx<œÛŒ 9ÎIר @£’ùr“¹ý¯ÃÕÿ-Nù;ohúd\5‹sT*¡Ü" Ù_â%®öÅU­Â&ïä{ÿÄñ^D%GèJ6­ÿUk«ìaeÊ©>£êNù5Çy™:åm(!­µíQŽÚæ;-‚ÊÚ)lçÛPiN„Y7Ýâ”þc,ÄÕÉmòI$p:K\À—(r!ÃdOv¡K€³ébÍÛè âÑèN? =€, €ª¤5tYN!pœ:à;qࣰ‡,à{º‚ÜI7`}€#¢#0Ÿ3õô¹ž³mô ž_€ï؆ À'Xô_¢‡ÐpÓƒHrØ‚ Ĉñ%*ëä2Ö° äÒç8ïú”o¡?¥<Š…B`#†@Ç Ø!±áBG#Œ ‘N‚$4$1ÀÄÀOô÷9ØPĈ"åovcÇ ÕhäR*´`ô¿¤æXHì(쬢?S¸‚[ä!Âr U4à'J%%I‚0i@'‚n‚ÂD°#ñÐAÙ4J,@ÇjTìØp¢S:,$ „¬EbbGCå^l|È"ïŠ °’ÎXD0ØÑ~OSøžÁH†ð†qoVíØƒç¬Ì=ð<¡â.{ÞÃUòòÑMÊ>©¹˜Èž}ŧáNz'7†”·ÜŸb¹?Ów`8KÔ_ð¤&§¡ÞvH펙”ïú—ó,çœJ çPîy2íBl 6¿BºÇ§vÛŽ ‡[¿a‰%bfc¢SŽÄ/bCÈÃòœhÊ­ÄÂ.ÿ Dx¯/ÅÈci‘Á‘„cŠ9ÂCCÇpcÁÙÀÕæƒ(™ “·ãiµ¿Í>”ü¹£ÈŒ/;íB×g]„5tú±qû$ˆ“lè¸ä3„p3 °±q‚($I6Q"ä"‰…F”4"$ã&J‚L®F#…ÓÿÑÞ/1Ý<”°  x‰Q¢@*Ð@Pp~4À›H @2%{œšDB§lÊmJB» þKÒM É€žH @ )X8°£ 11±0œ"hØðédRK˜/£ÈÙ¸qó.nÙZ~„`F)w#Ä—<LlŠ‚XÔ¿z|”/zêߨÌ¢å`½iåƒÿFoˆ•Ý@Øþ$ß–úxÚ¥ØÀ¹Ö} ØSÃÁÕ7åp<ìù l×$?©v°=‰ŸOv 4ê qî%f®Í86ãú•Ùäyšü·i²a Éµ¿I/î&Ïó§çCc¸8¾h–׸—h ¶ê²^¼@V0©öI m…º [æíš'Æ)š¼ÇŬÃßú€0o°É1!®ÆƒSL"èI’ ) 4D¢÷0IHj#á>µ€P“4n¬‚V(tæE@üm½5¥ìñ<€d T$ ¤"wœØ*‚蘿sˆ;‘Q-h ÆýJ•˜@$‘Ä‚DѨ·IFâÀ‹  ÉoØTâùiX²ÉÔ'AbÜŽNºü»Ò‰ètA##Q‰ £FG%ŒŠ Œbh@5U \@¨¢É8>AàNXšL–c•ý@Ýï+a&hÔÌø¾ ò€˜¬ |Hb8 Aˆ !b@˜ðï{L(AÛ~ ’X'?PG¨#BcØÔ xQ€r‰½Òh¤Š”ß÷š¬Gr”5€½@>v,r11É%Š$—0Ù(X´ ‰ƒ ¨¤Èm„É=±ã¡ It£ a ‡„Ð ÉÔJ‘¤²!:± èÌ>๋BЖb,ZQ†—"øHGP‹¨@åaµxªG<ñ%¾ÇÇ÷òÆð˜¢²#ã^«øÎíDIMB¥qOv“6I&!l¤à%›4Ê(D¡ˆöHˆ¨ì¥ °‡^ÀVºƒÜA'‚ì¦'¨&•Ý€d ~÷†´Ò8‰ ‘H MAœ(¿Í ¸©!qo®™Hô´ÄЩņF#‘@¦R„@# V ‚@¡·ˆŠ›ÿ™Èÿ:äQ”!±H‚(¬ÃÍî`)SØò°uÏ0JëÒQ"óü‹Ð¸K¼‰®—8rˆ©eŽÅ5ßþ ‚ZÅNé‹ ¡}Ç@r98JEˆ5DÇQ䄈Q,bÀ^Ò êå ÜXr6%ÔT[;Pä ‘‰`6DÖQ91{øRí÷€oþ‰œU¼Ô™æHíß|Ò3¨ð=,{¯ŒQõÉc9G¼®ã'?åWVð½8“4ºR‹Ä ñް¨„‰=Xè  5Qý‰Hˆ=ñoÜ2MÝ^‚ï¸ùãóòßÞÿ3È?ý_þÅõ_Ýù×wY ®ýÎ’½Él-$'s¼ "¿/Ê®E£ËõdTðdÆï}* $ÌËé€ÿf¶@-&^®A2åX¼‚‰ •ïP±˜ÊOøØÂì5ÂXÖ[Õë º¾f+„JÞ_nE:J]Ÿ¢Åø¡z–í^[2"5˜_ ®s3×W9éý¤ïAýÙÆRbŽ4L¥Xk."ö×QE¹ÒUD•èâ¨:;^ù0‚A¡¯íMtÖ©ýƒ£4f©œJ”gM76y{x׉J_råýâfÊ`8 L3çc“=cSQåØÈ*„Õ&ú˜OG$Ǣ!–€¤0ô5ieäˆQiÓ¨¡D]¤e"óOEpÁllç]TÞá%¯a Ð€ ž:NT$ š0¹C$hÞ@$L£x®€üC&¿ø—6ΦfF£®‘b N:øã}[¿ßWªm#õ‚Ö¤j¥ñ¿Z‚šå¿üGI¼Õú½?¡5ÉAŠÓSîøÕÉkåOwÛ“bP üò “ŠDOd‹ÿ(.iÓ†:ž¡)à„ˆá¦€#´³."Õ¾4|"M›Ž*^r8q‹³ÕüD˜($ã&‰(L‘˜´ìÜÉ©Ü*S¨æMñ1‚+éBfB­«Hì*P™X]-±ÒLLTDBŽ›Ef"Êack¢ uYÂh@8ñ¼ ð' -`G F‚(é@7"RLì\…‹›YOë ³„@çCöóˆ«57qZ8iÒJ®!†“^è\Éý<˵ôc8gPB°7a €Š8ûj|ÿ°ŸÏõMÛ2Å…êxZ‹_´x@¬á îåqõ"Öð„­‚‹X®¨èMòOîsù‚Ã÷äoÈ _@€Êà-Ñ8“|§08›æHˆhFw 7‘Ï72á!§`¢W'ƒ2bxù {ñÕl6²ä&Y ¬ãu Ƴäk\…FØâK1ăœ À Tkù½o ìcìÊíÌ\ÎOVY`%f¬‹OE ¿X•ªÏoNÍ|¨Zò(TŸ_}*$G2@Î̬Žà™áYîé/€ãDŠlÍ“¾ wPßu]⻸ЖB_böe¤2A©‘_ÑK´e. ¥ ý%îäŽ$ð¦Õbñ¹Ä]/qîŒgÖÈûDk¹ƒ¸ÝÄ@L"QéÇ*YLÌ\ÆbDt+a´èT¬G·_ æÚÀjÓp?4<_õÔ¾[sª‚}Á—éëe K ¨îU~!X׆_‡ÌGr¯ÁÏßþ ~{êÿœþ4÷?i“'!N§âw>þ,¡Ë `p“76ʤ¦”0€wI;ª@éP]I…±vçèÁgôÅŠ<~äm÷Ýíöð«-%o:׫7¶°q@\Ù2‰AW>vœ<úfýO¡©.Òè":,¢5ðÉÀ‹5é`ª‡¼»´8K÷~ ·î͇šw6¥+¡vP4 j¿5΀š9Ñ]PQ}Ê6X# fAÖ̶“ wÎ7`;WÎu|´¸ l“ÁQ¨´]Êå`{T)m,σjƒš«¤ƒ>™- z˜-À>2éb`“ù+ˆ¾<"‹r£5 ò ÀzD<æ*k ˜Ÿ[ýÀš ®s¥Ø‘17¨UžéZ‘Ïb¿ò°ã ¨Í<ç¶ú¥sXÜ ù÷;Άü±ù…7¾ÇSDÓ*»|ˆÍõKG“´3: ,XÀK´³õ!Ê8^ÅFî&qÚïªFŒ&+!€™LH˜ÔÿI°ÙÄ$†Lè'ù@4I¯jÔþ¹ 1a”„L%AÇ®Škr:v‰Älb+5ZRñë“ÚŽ‚‚BPq2—o³ Éb>Bð+<÷g7paéZ¨ÏY…’u›Ÿ‚½ëw\‡••×y«À·¬Þ¡¯ƒ3À:À6ˆõ•í@ÞÎ"p^ë €#ßñd¼—^jA´¸óô/!©ÚYI¹.Û£æT¤û÷uàZ` ôÏÄåàÜãz©ç*û®isŽMÉç³*ã]¤6ÙqB'½KûÜîñ†xô yí@œF2PÉM êI!üo´$Z#€Õ„@žÄqÌ)Á(©kr%›!úŠ÷ˆL¬¹~¬ÁÁO«ö#ü×t…ºžWA¬§6 D}r&ð–£P«êu.Ä@1‚ëõ…´¢¤ÕÈf%­Ú"šÉþUìñôë9Š‹!%¬à6 1°wl9)”„³2ššÈÄ~Ú¸»ŠÄŠË„Å£üný4juŽ„®Ûè ÿg·µýMèTMpšü†âøUcùW›ãd>hâ5ÿtm5Á@\GW²;€nNÚYðïý±D@ x è¸)@ˆ}€“Ùt¢5 {ùš×ŠÓèâí°y:ì×1ÜÅù­ÉqÉn­¨Ñ^î¸ÉFW“"$jÂ'©ó€Zúµ Ú&lP•ÿI®þ5ÄñÐðûuc.ýɰq Nþm|ædïÿ‡ÁlüçãùóØâÕ=›Ük hnVr'0™õ4VNDø°ÿPéC‰{'Çø×+Úâs7–BüløiÿéÌþ§d©Æ“8Ÿ†8Y›qrE¬ÄuœCÿu}ý‰'}_Mÿ+ÿpnƒü½G+a7:~¿_ÑÏéMgap2 à ìÀH®®ä&ÀLhb& ¢ãxIɈD*í¿ÃJœº “ÉñÀ·žé_cõÿÿzŠßã2Ž¿ÿ›¦µ?'¯Í„%žD#ÞÿHïMuåû¸ èólÓÓg÷ì¿×_@‚Q‰Í|«)*^KáúÃõêaVïûÉ5vÝìì[w0‡5µ·W^ ZùlRÊêê6Cõ>Ñ ŒR×p÷sBò™®à~S›FØ}±çö¯´79Ëö”Ø'¿°]œôYjL¹S˜tå^ñ&X—2&Ï%&3…[dŪ"ˆ•GF`F~æRÔàËþwÀ0óÀ;È?é»(z*¢zDਞZ¡m5Rž°F@ÆÃ사gd=/ÆP•s¯»[Ö#Y½å7©[ò¾ ”ó[>ú…ÔÎäH~ízú[·ðl†V=½ÀuK"‡3é_¿,L´[þwÞU"ž³öD$H¨4FÀõÿGËXÿW…Õ²‰"üg0Qäx.M¼šÁB ‡§dá¢1óâä[šfkÄ7»èš'6Ê­H`:‚oÑ‘öú0·t$©Er‚Å(¸äf104‹qµ-Œ,<ø¦þ6i[†ÛûXcvmTvVO;4“W+Ÿ®ÛC8Pí¸G(hT€±Z<ƒT¿M"=ÀBï &ùŸ§e?a_bœö·liD³s±Ù;ÚLZÛ†'=Âýlu9IZRÒDP[GÚàW‹=WȰ;>æ\¶Z#9&N²v±KÒ‹ƒ¸…Ý¢ÝüZx™§_)Rd…}:·ÈÙÑKÀ¼Ãw6#Œîb(ƒ}'¸)Ö׿™XìZ9 -4ÌçE„¿ ÖAà‰†5 ?u·Bjõõùˆœõ9WP•Q—Ó-òÍÝ~F¨†ƒ=·ËÍ éÐÜ1#·8D’MÂÎtžJÄÍÿ>Ç·ÅLÀK˜Æà™3á¼Rh¬bˆ·êÿ%iäûÿLpųâ¼o- Šä$/ØLtšZaüÞ›üƒñ!"‘‰Üøc©ÔóÏè¿–$nü±+DkƬ[Éñàgæ­¬x-¶ð9@ÿ4ã;PÏ5wƒíYûHоqúùútP“cA¹5Ùu¥}^q‰lK²¨J{KVŠ<ÏFKaPú½êMXÙõ,A±#´E§±øÛþ×áÿô:ÿÕÿ âµ^eX”PB¤üÄKâÙ¿¤Ù±»¿Ç'Á¯‹ºðC`ä±eHçáÔ!”¦Œl›e¦ªº§‰«ÐíMå®s”sc¹ ˆò Éè¿vߨ‚“…‚qUºžFºHB¶„’'RðGIÕÔÌÑñ'Å5ÖDY5š¸ã¡…x>†Ä˜ uödßMñý¿ ¸ÇŠð 6 1• ø€Ñr Í¢Wе¤Ø|´¥ëÿù²?¯;€ü~┕ĴSÂC1µÆ(ºaö MÅ&ñ±~·u€®ìmxйÑÕš çtçi¤Ù‡Û®CÚ6¸×"ôklçciŠÃ†¢UÚ¿f¿¢ºe˜R¤Î—m…icäŠ^É««Hso„̨xR~[!égísp÷Ô=àÅÕ >KÄì4f±ü¿ñ«¨£9ð™ùD‹•·Bþ­¶PóŠÒ j:¯•ݪ?/3‹î»BÍËJ1|?–öG«SþÔ\_€òÝ(žR7Ž=OTžÏVl¥ ’.ä#h>›QÐòqÏ&ÈY™þdnL©„´‡RmÜ7m¸õÔpJmEÄöHêÙ^kHZaÝÃ)OY9Èä\‹Hžh~ öûä"ÐrÌ ¤@Þ„°?'¾ Ö9L.äÙC®å{¶ð"ÅMbå»ÂKwÞ½h!«é‘—E&„j ˜_ŠÁø^9"¯ŠàKS–ól ?™Çê¯"ð¥ ï0ì·êÝÐpaÍcP>¹¦J¨š•Á-ÐÐܬ…†Ë̱tÊ{bçW¼,w ±tOÖ]hÉ^g¡;c=àü¥÷þmŸ]û÷—Ñú¬'/Bí«X_ÒÔ›D(?Q ò. •RL|†*sˆ%–*/ä¨1Dd1W b·È¡hÑQæð¿)_ÄçwÈwðT·–èUq‹È”á²”;­ªÃÕöOe¬ú~ýáØºc›õfÁ!Z‰XpQÖ148&[9öíU« 8Ûàö|¡/àjgqWäWe¶žü„Ò´Ÿ#ŸÐ,ßkÜùͬW /Óšžcr¤,Pžƒ´—eØÛ)w€;UI×tqª …be(à  ä)´ó­Ø@¨þVù¬(éàõ¡cÕ{Ä5ÄÞQMD•¦ÍÄ*oÿõÐVgzù÷ö|c«âæ9ÿ™æ)˜ •òR¼£Í ¨†¨¿Ô\ŽjÕÏ •#µ3™ÆOi4¨CÈWs€ü<ÐôVæjpŸg«Ç|í7`Op"8¶ÛÜÀ¹á­ -—‚ãÛ çO‚m6”{ÕÛÀ¸ÌwhQe,RY¥]ÊfMù†t¯p+È®²³B@8ý:ÙêRÙ¼AÍMþ"ÍC¥[l€âr¿ òûÃà=ÝÛHv•@mך§¡A)}Ô÷kgAÒ}¾9þq²çŠ 9”S*^¦mŽ[-·®KwÉc‘—ëRCÑ®z°Ýäè—Êþv¯™KèÓâj«'FÞ 1-w†òd­T7Aò»úqH¹ž<ÐŽ¸Ó!ëí!°ŸÿíhqM4.A•?µqøûzGS¹üçë¦Ç»ž4röïßY¸@¦³¨ä;ÁÆLù›¼8'„iãšÝlyæ}¿–h7ìY>NTup.Wžj>BlWëØwèucÓ.ƒàLg5D±î1‹6@š< ¨ ÔßÔlH ÿ.P_²šAhIí5ô…+bÃêÆCR{Çù æ…ZƒíRë(¨g‡ž÷—® v 6€:8ôxƤ¶ù~u3p9]ׂ~ž1l“U ê¸èq° ÔÆÖÌHuªµl§¸¨Šìå L%ž&ЄŽ, ¬¥ ÏaX™Tƒ‘KŒ›eDYs Ö›ˆ>!›CøSëtˆîÔ—‚è—. wi{;c ¨-mŸ£ùD±¨óú,$¡~à^ Úui} |Síþ¬fÒ1­f;Vª¯ìi¼…¶bSdÛ»o‰Œ²Ý}þ ±¹¬í9ÄÞ™§zNµ¿ù3ùÓéÌñ˜ØËóLd>Ð9‘‰ý÷Ü:±ø…v@ÆÿPÉý¿‚`“¶é13j",× ý€ ÔCRƒŸ“ºecš”LøÌDz§´ÁÀ…@Ò‚ÆŸ¦G»Æ)=ÔäNÜçR ˜Ü hñ£¤á:01ÀI”zÎ%Hjì}œ$™}ñÄ6[vd¸/ ßkÝB´â&ã;ß¹\ŸoôÛvÄþ–oý¯ïi3«FoéÉ]ÇnÛˆ)«¢§wUÚCj†¹Ò¿q>iÞæYj;îs2·eNä4ôÞýŒµ(ž3 }wÛNh>ÁѲ™ —+Ý@¿P½ ôÓÔ~ úÕ¨.ÑX‰œ“é)ð_°h›Ö+üÀT€Dø©iMÍ߃`â"ò°Ó¨óRóq0>°Öá4‹!aDGD%GË'çÐ÷H‘ϱ]çÅØ6$»öYC¶]¤úk¿«¼X¦šû]fÄ™2¢K»ðÅö†þWÊÉâèÙÙêrµ]ªì§mÆ*.eŠã3u?­šþ"wéµ ¼ìa#.¢’‚«É.ÜÔz8³ÉŒÿ6Èx½ó·ø@4à Âx©9>Ì\ü!µ¡ñXJ€áMhø¿ï¥8~އ©ãÖ^a`-1jù•<ÒÍB>Âe^…K¥×…3XAY°Ÿºœ¼Ðb¶É«Ë~¢£¹}Û¥J‘êÜþSì€ØÖj’ñ Æ™ëÄV”V«Å(I”Þàè¬wÇ…âsPîHÔB4M>ØHÞDbñ6•åHt~MÔ Ä€T4CPɉªð$R'4y÷Ÿáï‡ÿ9~ÿÒ?þ;4VæÄ=™þL_¢¢FU˜€ 'p&v$:V"ì£þ%e”E´ZY{‰XÕÆì‘Ö©t©¼Éôº=ª—á‘BܘîÌçQ]/‹WÀ5V[Ž>ô¨èDcòÒà/‹Âä*„\¶ýaä[…7’ýÉõ¬>þjNkD©éS½?,h(YÀe¤/ãk"¥/PÇjX 5m瀷Zà\©ÞN$|QMwöRß`ú¸_WÃ<`fûL‘ìçKÆT÷ËÑt‹7Al‘;ÁÚÁ&°â%ôØ%À‘Ø6 +ôïQ9ÄŒÀYF£›®¹ÆyQù¤w!ØÏKù “5ˆZcÂ;ˆäUó ®l“ëQs~‚ ·[ ù—)á£^ðF*¼‡ÅÆêÃ-œelûÅ|T­Ïš^Þž›šß\Ùƒó[T‰ÈYÿî–óœ!´N§ä|í÷5÷t——PÒ?3‡óo©ó˜Äê|¶!¸ !"”`a§š$lœ¤YbvþNÀVÂ#€­”«Ø„© ɲI2HÜ84Ò$‘8›¼íÿ$œt H|ø€*ª‰ã‰êðÔ?Œl¤ýãçÜӜƴ&Ùþ.£8¼‰—0é$ãàjb>N·>ÁÍUÆ (Ü/ÂÀôÃÒPGéJB'¶Öä¡8(·‘¾÷²«/Á߃ $ý£ Èzã¶Ü@õ†pù(¯yÞ¹’¶lÎ̧ûæô³ K:¼ÕßÔ¼Lëšß²Ú¼®Ó4P¶fÙ©’GCf‰í0(ã¹!ñ3ˆûåÍÀÕ'À,ñ^Ö¯G? fûVüŒn;î_L_Ç$Ç|¥W«C9¢•}*hk]÷[»•”ØZs¡Ì5æZ‘]·Ü+úoLeõëøH¾-£#ÍèÈ>ä+†Ò‡éÊ#œB¯…)ΨX£=Ä×¶çÕZ½ŸµA}F- ­´ œtV¤RÂÓb¸QÈeVss&–õ —¢X‡Äð_YB4|o\õß»”¬üKȱuÎûâ›s"K=öÔâòŸù´ù-ǼÔ<§®ˆI-îRÞ¥¤wzR%yÞÎÏ@/\Ó²deÛÚ#Õ;”¾ V«©n¦ /ƒdÞDÞ`6*6²âß»a×Q üœøÊFhE„ H'‰F±œ)¹6À›xðà?w Çà2@âDì(å¸~B@=EB9^ ˜j ‡BàbNZb'^RÙ˜©qâŠo<»TÃBâ$L Ë:€ Ö<@•×âåüú}$o®; ¥îÕváË_)Àó&Wé5cØÖY´.9t"ÕrÚÀ,nµ­r?ËžTÝELû´ÒŽ©Ÿ-;ãÐ+ôçé ìg¸u•’¤N±~s,—5EéÁ9ò¸Üïêë#r­¾Ü )çZ[Ø*:‡:BÝ–`¤cR´?¤œbø ª¾ 7‰]6ÜYÙýloBJ¾»3¤]j[Ä' TÒÄ81ÁÔƒhÍÀ9b'ð8€hb¯´€p"£¼0hè„ Ù8Êû gËŸ€xäÕÖN„ùjè9ðŸlõk¢©Pûc,ª¾Š â–j9”{D;äÁ‹\s¡z‡û(J}Žû!.­ß­u0Ž{ç3?xjà;| ƒížòÂ/ó@rnøcEÉom»×ÛÝýSêÝU×óS;.fOŸJ:÷ÞêH¦¢ý×Ù¿n—ï8Jžã¨˜MÌç‚è­¼œÃ×Z?h,ŽçÓ[ä`Kä™E8Y/ú§_ýwáÏçž<±8ží`$8ò¿ˆ‡zã¥}ñ¡X Ž["ó8K¾=5tcÝs\{$'t#Ów™êDîû­Äs•ìø…3m´5uÂ.µ­ºiBòß韡^[/¶2©Mìj&ÉÚŠŸ)µÍvÞƒb;“Ú[‹‘\ls’Ä©¶ËA[í<ë:”É¡S­ÃÚc!M¾§Œk¸Ñ )ýÅéæ-<#.¶¦‹råë ñœÚÎέ‡µ—JífózzÈKBv¨Ïõ/kqðKHîÛ ù§ yª­!§»r!$¿aóAjøœO‹ ÿ¬íûJ[g°—«Ïz‹ãQ°mОõ})(/èQPº‹A †Éçad/éâ# YŒq½µdMh‡å- [DÂû-–±·bBôÝØˆîî‡@ž C8bm¿n>Uë¬w¡ê+q%ár‡>DZ¯ìgòÔÑ›Üs8»dOZ{"Úr>­¾Vü˜éXõ¯²j:Ñjª‚7…%`Æ´ fˆC`¶‹Ý 5w©ðß–Õ Œ×lûàØwUxÆ‹AêuÅ3 y.Èü d\‡R¯©s¾ˆzö!”YC@ëžî‚Ôa—A‹Ù e®k(QwWm'š3`½€®Oû!ª}ûéiPWÿ#30éK®‹ôsm›Ãvû¯Žþ¡úAû·¡ˆØâ¸$Ø ÅMGêJç*Ä»i4z‚þ&$á#ƒûhE m(ÆÅ¨„;'F³˜Ô3‹FÓ½éq2ñ¶éW:몠ñlã“ùøo|D[øx…Žì2zƒà6LŽG_ÂkEÞFs yáÉfW´ðÓV¥¾Ó‚hUv9–AÅ÷‹+èº{ˆã™º«g`xÚζi÷{§—.JV*î“ÄÇ%X­H:Þܳ³FgÏë…œèéý3Ó!ÿ-WO)6s9„ø‡Ø(ÿ6°¼ÖÝàmS5ôÛõe¾#s'„W?6O‚ZÜÚ:k6ˆ¥áï@¬\Ѻ/ئʰݭ̓,oÎom÷AlJ`,Pde‚\ Gƒ>…‡AÞyŒr-+nxÔ_D\sØÀ-r)€ù@ü 7c'€ù3 å£úkHó%íV¤ÕÌõ –h炘í¾Ü<„瓬É8Ô™êM} mR¿Ü^…PQÏ‘n?Ä"äLyä¶€™š ÆÌH Ó˜[DªÓ2b&™¿b»Öæ°Õ³Ûù Ú³üðꦢ{ÎqiÙÚz5T‘þŒ5¬j™{º=¥ÖíèÑá` ñ㩽Ã#Ý¡µh m·;:±§9®9šõ‹íƒ’æª#ñÚ³œ¯’b¯u^C h:ŠØ“´ ”9Höò3€ÈD™¨ÞûÛ ? æ/ã^6£* ;Ø)°™ÞŒ¥`Ñ•‹©&‰nÔq 1@' HûC>~Óš¦êÆŸ©Ip4 üB° (Eb£%k­iœÆyV;z\C meWnà‹p5P¹‰­²Üÿ=]"kü£ù&ðXÈÆ¦Ú­Vž®¨”?+>èú‰ïR{3d[·b ÛyZÒ õëÖ§^~ìãàDûë‡gМ—Ë[‘C¶åâgfwU—Ó9«Úº )WX· ÄAå. ¾¡ÒG²rUlyz[QéëSß¹í¼úßPÝ-¼³ mŽo¤Þ,×#›÷•/"r?e.¤¯Rê Ýaß )Ë´%àrÙ?WÀ5œ1û4°mµ?úÏÐ^Wú2Ëý9¨å¶À ž) ,e;ˆd«/ȾÚo Dâ«“ñêô¸“? `(°Nþ 4X»ì <>r—?¬ñ‘»Àú.\æÐà[`¨ÑÁ87˜á)‘›!ô[äcð§Ævƒ¯(ÖY;P´FT”O¡êm"”|æœG´HK™ÆG¥÷䜠¢rRöÌ«náz:´+Åðù]€IDATú°šSuÝÉ:þ_‰cÇ«¼¦Ãcõ\™½_‹á¿¾¸4÷Ég·Ô”eÿ˜üUýb§«ãÞ­¢c·s›¹«ãÄÐD ýô&¹`®m3dá¾ oÊÅîG 'Ýž^ƒÝöLúj„hïš„ö³«dÛÏxÖÍ‰ÌÆþ½fÈJÕžÀ™òý|¬¤—õ¼ŽŸ\ßQeëå¹C{B’Á~õY41 •ËÐ@¬G¢ŠÇä–D"”±b>€ ÈǰHøÄD[46L?aWEÊï‰ bN|Ô†ÎÅ-ï ·Ä;?øé¡Ñ©t5.¢ª!C¾OçÚÅ Xåkõ é\ü„ë5z]ï<Õz²¨Äîö¦_j_T7é°jëÎ ´×6Øs¹‚7²Ç2Áø1©–ÒŠ¡ÜŸvuõoŒiý­½º]]£Ýzq ¢õ¥ê§Ðìq‡²7d¶€Œ32r±’êÒžC±!Ÿc ­Ô*Ñ•­˜81ˆrI¿{tš‚‘8iA± ¨&äàúý~|/q$BñêôxJh¼çÍŸ<;EÿÃ?ÃIǽÙät3QlÒ˜Ê0Äåz £@âª*€r€‹i“Hkä$zi¬Ø‘Hì‰ß„€×I—Q>Á´V±–2s3ºyÏÃ]V{øöøCÖ=:•ÊUF7rŠ[ۮ䮃]\pû®sÓ0ü·v©Ÿ™mK&qf°&kM Ø¶ªåñH+{n»·½’×ì–Ns1§¿ª=‡j÷ý›éÿe@'°dUWyÓ¤ëœføèë×&}^}ª©³ñè †ÐûØyJ9Jåëî=püT¹ "}Ò»@³'OÓÀ59í4оW^ù®ù ÁÏ Ö Xkh Æ|9ôWcÁbžÑNÆ>À®?Uá7Aèûh„Ƈûƒ÷ÅšgÁøÆ8¾üºzð›¾eelã£èÍ]wCøãb áÀ÷èìÔæðºïy£—c¬â¶$æmJsR9ÊÍ~f¤ØÑl9ǹ¤`.‹1še 5SH¢¬Å(’e8¿Pô©ã:=Å(;‹'òÆœ˜,˜}l5l+­b®Qú Žœ/Žõ¥UŽZöf~Ï~¬í[ÍAÏÞÕ}­µ:é¶n Æv\Qù:› ­lHê(ªˆ$=¢MÂîX¬TƒºS9 ³ô÷B²Æ£>þ§˜ü3ÙÌf60žñTIC”‰.¢ $“LŒ$’¤‚ tâ¥Kf“èÙÉ2V‰‚††J Hê¨C`b¢RG*唣áÅ‹38KYŠÀ#qŠWΟÆyÒÍ?5.žÇ½It!¬þ<†?ÖΊQ8aŒÆò÷`&IÞ!b1²¬º—=ûŸPŽý‘â{þˆJûÒ‚c¨?Ò¡ÙÎ-jÓz?Úú\:¿Üax/è3‡ô¥i Vßô÷€ìÖÐ U̾ç÷bkõ7ß´<ÇÔê¯O6?o𥿨u;†*Oµ¹ §mlÒ,ÖfŠb†«ª\OK±LžM‘˜HЬR®ÀOlD稘D5”s€l"„‡çõBœÆÐò Ú á}XdÛüugI§v¯ÿS£–ŸÒ.ŽÎ@AìZüž^Æot°Î§Ä#¬ë0ÅÆhTŸ§Mç>à!눘ÆEЬ­ÚyD´¾ÚnìþóÕñ\cüh{‘VÑ×mwòX¸«òŠñ^¨ÂëÕ1B/ËñhÁ`è^Îià_MGðN‹µïLí ÌØ¾È¨9ý©€B ¢G³oU­äèž=ñD2½ ž>:•v×w¢¦àXÑ 6t)´ÏÏïÒºõ Üá„ZŒl½gfÎ)™Ìvý\ð¸õµòŠ;ÕÅ`·*çp¡çT1kíT.u£ØG¬[ôäo4͇ùŸœøV"§^ör Ë$?Ë…Hav¬DxÀ HIœç‘ø”ž‰•² !ZˆÞ1x—§ QzûOÀ¢hHl¬Ep‡L¥ÔzqG÷Yßpià2s5}ü}•뙜¯èPayÞ*úE§vÓºvrõv’N<Øp§ï{Öãäíí¶3wa·µ!éûÄñ( êò0¦8ï5úD~ðàÃ÷Ëïl9ÛÈÚó°ÕG£”™+ćj†!§åĆaèóÍW‘Úx£+ºú¹‘Çýú<ó^PîyV¬0fÓÇ™!ôèB¡z¹p€ûŒÈ=P7·þU¨³E†ƒk{C˜Ó£@rgß× Þ²Žç ï “ÍŸÀyŠ\®%òpõs½ ž¶f h‹.ûD°73&xJñ(N`«(Š5 ¯wÍÍÑ`(¡t^¤¼ÑËcà ôˆõ3ï$AÝC¶WØ/à®{ 2Ãþ>øÇ¸"ƒ=½ѱNj>ðô†ÀcÉ{)ó­NI&¯!/y•ŸÚ{‡F…odO]{×:Ö|í«ÂQù€ü|m™—>‚æÜÔr ?F¬Ü…Ú”êz{Ë”{O”Ó;g`élÚç *Æä\ËûÃ[w¾Š½c½{3‘–ƒÓ{pJöØÜøÓS³«Q\‡µ‹±´æzWTµL?›=Ê"›CšLµßÃ^°mç9~ЧRÀ7"7˜%Îà[„“Â\&:ã"‡Ád#é€@Ð „Bãù‰g [ă¿0 ØB `à¡F~Dˆ(Å!«ðÐRV‰3H±¾%Ìyò*ˆÜÏP‘sÅLÑ—YÁƧøÌ»c4ó"£„âØ‹ÕOÐ.°®úeÞ¯¹¥¾–Ì’#çsÉ¡ !øy÷¡´rÅžë [ʯʺœj>ê½&ûñȸÀê|ÿSãÀ󨳛Hs]}uÿËï±üøÍNõ×s}¥þÔã|¡8+w‚­»6’å6¿œbõP_—÷X–öˆ:Â\¬Þ g\,Ú©§šNÇêØ,4ûðXGq»± C;ËXƒ¦Õ§3S›gå2¥³qíÔ·ÌQH%— „âã-°}6Á»$äïAfRÃv÷×\æy 1°ñ öÁ†’O‘AJP‰Br…z$-ŸƒãˆºS8lƒµÇ@{L›úC|Š_¾ây=ˆMì2y¬)Ê`¸t‚q½q§X» ¶Û‘ƒr„šÃ!¨ÁÛ•tð'„šlí¡^º€Sêéà/ñlFÖß’ÞŸ¤„©«›–ñ†Üy"­…µß¦›”V¿äÈÊØf&WÏV.å…ªKÅX¬ªQ|€Rµ•§ ø¨ñ ß+¾ƒúÃz ç&_ ®‹ò$äLoq3¸&:&Bx‹7dÇ@؇0´ŒÈ$P. ^º'<\é\FĹÏ8Ê£ö+¢­xFëâ¿i_l>„pÒ ÎñLÇJÊ@¹/êu >ˆ à1jÀ: @¼`Œ°:„߈ïG{,ðÍçƒ7U9—o3îæÙúÔBž~o¯ÄôïÕ†£ª[ÓÖƒí㌅ ÷wBʶÔ ùMù;!õ{ýÐ…º‚-+v7Øýò†}††f?‡ŽŒvÜ&Np–½N¼DŠíH¬Cš§Þy3É…gôü”Ÿfì/»×¬/{šÇº@8NL–R¬ÄnÚ%k8.Wó0g[‹¬ODºxÔqX©;âRºÏUÞ™®_ÅRñ¹{mÛ p–ö`R%>m·ò(¥È:—r¹ÚÆ*S'¸¦Z?+n»e-âêè~+WÛW˜óh«~Ä Ô[³­eØ´öæ[¼+Þ·¼Xê~ ñ¢|Í S¬+¹5ø­ø˜-Z¾¨$ê¸ÄÚŠ­îJ³4ÔEû@¨y¸‚7„^‚HãN°­ˆ½êE¦ÔýÖJPÒ­K@YÏ— Ç â±»ØzÝž•ò+ðk}kLíSûdT­—£/Ø_ó Êý 7*óSÞÆ³Œ³ÐÄ:ñ%PÏH yŽzgE—3Õ<»n7ËS])´–#SœHc¸w¼Q k·»Ä:‡£ µ$føjÿ7VkWôرÍx£ócÏ1ZºŠÉ =îƒ4Ïtl@„&ÄBôõ\¢—|¥Ø"›ÃKc´ :éØZÜ•‰Æ=«0’UCGI¯á”ä³­½ü’Ü’/eOW+4 Ý÷ð‘̰wçѪÅä&Šežê‘/ý}ò·6»>He™|LXvµ…»J~ I›S Mp„fíçX>‡”/D-ÈrÐNž Xb"~ïeÒAC¬e­2ê\6ÊE¨œËåæR1:6°a0©‘{c·à ΔW@ÃTÕ õ×8ïƒê')PñcÒl86ÀóÕ%§e”ƒ×,0?,Ý‘»ÃÿqÅáTµ¢«ßçl^ù¡r£ò¦?œª®hq;³O³ªi°®v<Ïâjû6bÚ·Ú·èÑ u·@t[àà î+ƒXßâÞPç€2DYf¡™V½¸ø„~kþ¼#Ë÷š @´á0 ÿ0çö‚øÀ˜Žôy —…?}wƒí9:€öûAÿ‰\ÐQš ç¨ÍÄvu •xã;@¢JT¼Äa‹”Hk©˜„%žw!õñ)5hú)­Ùó3Òs]½I×Û8çƒm£ã~°9µ`›¨Ne…Ö×v:‚+0Hé>”™ú@FàSP¦XƒAži–5)döR é’UÏ dÖ"ˆÌ$ÀJ_(™&È•ic”3½ÔO“r뼜™²°®šu™gÕ-¥"%½¡JšÚЛ,Ùð29ßû>"Yõ† ésï•ȤIà) ÌG¸_= î­ÆóàÝÎKb;ÀÑÛÜÎ_b?m«Ûùá¾ ?"ÛƒÞÚº”{•'AM–+@I±\ òh Ââð±xdP±ƒ\'Gy›xÌÍê$0‚Ê0ˆÞ¯Þ±óµó €h8îéFUÃŽ´'I«{3óÌÚÕé÷a«]žý6¢Ú–5*oÍ™*çU½¶3:­®‹>¾º qÅñ%Gå%öì–³í§|(wålä}±!i/Ëåñ'¢ãŽÛÉ×>-yMž‘~Ií™ÑÒW4ÜðAÞýI“Ê~u,Ì_|¯2­¹÷x¶Hj³¸ÂA´Õ©• ±5k]¿ò| >ÈPµ2BßÜK2ñÊß§37¶û—å5Ÿ™GþZ붯ևÕîç\_ó.‘¼ µ*öÜñ 1ÓçŒm¾ m ·¤>b¬OWÛÃôª5 œ).[tl3c—ƒr©5”=É% ‘´ÄÈÚ`öˆDÀ˜§¾ Ö]¶ ˆmõ… r›xBÍ#;Á¿[+ïÎdh˜–œ u¾”NPýAÚuD«Ö¤uÄV>3k>sOü˜q¾õ\YuòÁ'k~r;«_÷=nË=¾Âj¯u' ¾.ÿšz¤}1yÇ€ù常&¿§Ð.g2ê8lÉZùÃ<—³¹l˜¼3g@Åk¢2ûçòÏpfï¬~ÜœHymü;!çCÿadöäð¢Ã’;cÏ µ½/’ÏêÔÒÜ¢¿ÚC—Ëø¹E?±Ž2KПdiÚ|±©m#ø”á€?ñ•ÿÄjû¿ô>yÙæyò5¤q›ìˆ×èÁkèÆ%ŠÏ´^d鎕s™\P²"áC3©©-n…½âxÒ Êû¤µ¥®lPú;´*í’±ŒßŠÍAÉΖ÷r¬äôæ1ú„/eWÃjß‹JqéB<Eg‘Í' oSi=žeQ³7• Ûœ—•·}ÅÑœâ?ú¯+6$+©èDÕ°m˜xå m›yÓð¬óyŽ«ó!’|^®‰=ÿIO°Ý¯}Ƶ‘sAŒŒ¢˜‹@tý@¬çXà €,’ß å9b7Âòz_òX^c{d䔥-CšŠ˜€0¯TZƒìÝöcðí @š™âDô5kø¶†:QwüÛC‚p´?z 7ÖŠ¨9QíËmÁn±g…ÖðTl‘94|»\oÕÔo°.Ð/O.bYí,ÓÂ{¼{x-ŽCÞàgxò‹Etiu•¼X<]øžÌOßÒjmý#îÁ9¿ù槿㾡öƒ”«ÅÕõ÷&¢ Pëù†iÑž±Ì²ô”TõþcøTœ½b¿˜+?¼Q9˜ëalä"ÏQ厪x3sbƒÊ‘–{‚s9Ñêj#ƒ´ªxãÔE¨†ómDÞ@׳ÐìÚÔ[ eË…ÔÖ)9íNµ%èho"µyZW„"^M||ãGwÆ1Ž,€,v³ûÿW6ˆŸš{:B>ÂáX•‘‹F æ0„ÙÏ’Ðpwè%dY½oáÊQa…`q}à|êO¼#§rmå£ú{4/úØ®ðñ‘ó<™ØÊê’Ÿ±¶GÕ¤½þ‹³îP®>þrûKÙ\ÒСêðiG×´É òÈ……oÉí+ðD–ŸŸ>¯®³ú&5¹[¤ýŸ&·Š× ɬÞŒo†vvl|Ê¥¬´Žuž`ùÏæ¯—ƒ<7p³¨Œ–=Ì5”(·[;ÄiIË”‰r'ݹFvfŒr‰5C|#‡0LYgÙ&~‘N;Å~ï‹ Û i§õåÊ{HåˆÒ 2­|ê¿ÓºOñf%¥É¯DªI©þÊD‰göD}b¯¢”ýdTÏ’=ŠKV"!~F°Fü Ò©@šÕ„1Æjƒ<«%¾`oýf>1Wªí©òÊ{)¿Ì½â>êiΖ•)U0Ç+k ê¶6Cäq®ƒð4² (Í*ŒºI©~DòîÞô·ùÚÜm©Ížmã)KË8’sM?÷°çÁŠÇ›íàÂê™Í^¤oÃÔâ¤ú»­eW(éÈJê¯hI‹‚WK»³¡`R´«153-ån_­¶Eƒ÷iDáã¡S¸¼ù-±Z.É~Ï´hÙìt­²¶ê_“š{³s7Zn÷dô$ÓyB=.Ú–ª>ê!Em ÚÔ¨ò5’W…A„’N4G°ŽÏ¨ˆ¸3ÓHœm÷·ªQ³ÊÄ7Öÿ,$È»­å`\lš`½a XÔ\Æ\k8†y“L%Pw8h©8ð²£|qôN|åkÌv”_¢|DZÑPÝÏES©8Ê&'M•ê¿tM üjjÉŸ–“Ttz—RÎÙÿs‡‰‡£o‚Ï¥L«Sø|ˆùÂé <|ô ÷À½)èBjë¢czÌܶuá{ 6@Þ¬“ ¼Ì; ·(=A½ÏZâ ¶€8NÈŸÅ\°^ׂù©õ(ï8Ã@;µDúêgƒÑY±ë*Øï0óÁ¼ŒGÁ~2¬}â*P~ÑŽ!¬Ôðsœm3ðÏȹw3wÃsjW¨ž¥ÖZ£ƒ¯E’¬t†{3°ù§’N80Š[pT.&ÆŠ}/ó û·_ömž6vôlssMNöM9ë¼E…{“÷Uu«<¡¼P~Éq/þŠÃÇ^'éðÄy˶€ÈYz| ŸeO¨jÙÏJ›ì,e(Yémm×SŸò´óM¶¸f%½m>e¿Ïs‘½²†§Oƒô¥y_CFË”P–G@r¬8‹‰Ø²r=èJ”Lq˜#€K™Qx¤;*±Ëq¡{yÆñAÆYÔ›éÁ”ÇVG>ç¨ï4]¡Ì÷¬5†YF¿ºGåër³¹VÌ“ ù˜õ}6±h8Ü´¨ù…ýb€íZÄ^±ÞÇa ‹9M²–ÊbÏ(¦xý-3Vs–û#ÇçD´ýá©8]C\Ÿs¶ýVŒ$wF4ûñËõXŒ·?Êy³¾Wáaíke¥Y¤Îˆ]mlif/ó Þq¿cT³Hý[ã0ã”cæP:h·Ç²™h¾Í!:;.5#bˉDÑkÎQßEIß)!¬øå¤úºü ”9™ny½D=[èÇK ׉}جf¢ È%Ê­ÀBÏÐŽƒZ–r„š™G¡ì1ù36ËJæuPó«< Âį(*ľU.ë1-‚Œì²=0NÕ«¤Œ-²»y9¼Úö­¼2ìп7»W«"ôu±‘t§Ð»@‡) 9œgš+^dÝoòf¨¹™QP³FÌo•{V¹N÷)¹kí^k©"<£ô—Áù›–‹pìbR~éîášÆ=/RLš#Û5˜|ùI태‘Ü!ÛÍaá÷ŠjÏ´Žª¿ÆwTjGôw¸U»ÐpaS»ºïd©’\÷¡,ÖŸËù˜WÄõ‡Y¬<©üÆj¯–ûd3 }ßÊJ¹°ò,nÆÅýò>QN4–‰lñ¹ìi6ˆ›DJRXFzóÖ¬±îTFÐË<ØFG^µdŒõªkšèiøŒ ’­£öÓÙÍ ÏD±¶¸ö£Çz‹(Æ[ö{Ù­7ç‘ð…чøÑò%¿Æîèóf2¶Ø¯ê5´ )÷¡Æ¦§ƒÈ©b4ïEb¼ Ñ/;¥aZobÔˆúˆæ?LÐ×·ªmuúT„܉({Ý D¡%%k“28#%<ÿlç¿äü½]é¼ñœµªBtAhÓ<ïŸSººÆ~á }`äT¾²e×˺j=%û¨ŸH“/ůœ`9ùâsšÉ3•³8Ýj®|'™µ¶¨˜™àx„"ío@ðw'–ú%ý w¦Þ õmR¯‡ÚꌠæÁÌW j~î« ¬Ø–»Âª*’¿ÙÜQ¶2;Í©µ’¶ÔÍîÔ[”_bLãŠÚg5|›Ýb<Øß)ü ÞÌQÌrWDïg£^X YeáL&ÆZK¼»Ñ­£æzH+ɪnr €¿î}äb°æˆ®`ì‹Jç4,Ûý€9‹ðŽ)»Ô³Ìi’±»k˜ŸY§í|Ï10º.‡È…õKÁ·ÌŸ útvAÔjË~P((¥@ë î¤Úš(B1•ë@m¡#ä9L§Û“é˜áL‘sAJ²’õìW±%ÕeÝŒC;3ô48Z$'ƒ­¹ùN}eñ†ÞFÆ=ª ÍÛDÛk ¾¢.a•VeŒ`¿È0RxFý"³ÜºMœÍ—¶†›³¬¼½èÙìœ#g0:w<·GÒË•·Ï%]•dyŸ²uO^Òp\ý&å‹úJiʯC|æ9â/çfwMð\Z¹’‚~,çÍ¡Šcmlèš) Üjd‚úH`á\ Ö„”N`¶%=מ ‘ÓÝ¿ C…®™Üü­ìï».¥«¬÷Ý—¼ÛZÞ01õ³SýOǨô•»ßñOº•ók¿‘^ÚUåBZ•üH×Ï' Û±•Ì`Âñ‡E3Òj6«&ö”dRßìgãG´Ú7èÈ>ßÌÀ,¶²"”‡‘šÙÌðúOÒµtc£p ·’KrŸL%Ãþelu\kK¾ó‚PoœÚÞÈB„úLõV4%°+F±¶ù«Õ\¡m ‡­>É•âźgÄ{r\õzùSÖèp•ø¸ûó–É»íf‰fĺ^ë芭ͩî\(üÞ“ N§6Äa~}¤h ¶Ãê6P®ç6HU@é%Öö¢ºÄ,q¨;•™@9»at᧪4…¦÷7p( ¬©VX¿Èn`N6W‚õ•ÔÁ¸Àš Æ]ÖÍHc£õ=¸ͺ Œ îDĶê Èô»ÙqxMp2ÚžÑxž'ÆÒw»S›G¬4ä¹€NŒJÓ,‡ºÁ•åËj¶”éeJó÷¹°¼ºà]ž(ëœ9óØ»-~`iéþæ8~ÌÕâI~,z£Å½æC%sÒ÷ÔŸU?Kù¦¤eÒêðë|/]ɧ¢æð¹¢ #ŠÐû*×Ê‹ÕIv5Ý ÝoÝ&³ÿJÿùë €.rµuO¬k7#M­Ø¸¥@¸u·k71ûÍÚ&,]WÂHµ®D*É1Ä,ˇäqC9 <ŒE?ªAÜÇvàG<ÀPä¹]WÂhFÏð2„x[€¿è¿ GÞ Žñ¼þ:Šù”êƒèÓ‘þ`eé" #‹°Äm®V(‘TóGŸ}Xá| "Wš# Ö\ ‚ßYEÌl£GуãbXxȸNŠØ·ê\ºD¿R„ªF¿‚Þêì` 3õÕêùIäsNŽ|î4Ýh‘‹dðz:¾煃ݙÔês³0Ú·ÙWj«ª}άÔsŠûjZ½Uä¥EËÓ‹Æb>~l¢…8¶—ïZ¶9ÑŠ» ‡+ëìÑé½bjòÔïPÊV2“£ÇqÝ+ 5KØ­õó.$j_èÑÓÙ#Ђ-ÇdR›Cá=黡U¿ô˱ZµÈq¡¤K¾š Í¿ÛZ™q0ë6¹%…”;9M|",yDKÖ†1IÕTC®RZ+YØÔõ€¸Kí¢¶£¯ìAwf‹nt¡5&’š<*qLtï²€ËÌK¬k囿rceLæ)1ÙØc¼ÁpcPl¸Çem§G¿8E¤ªº2‡ß_¤ µþ›àd }PGN­¾ŒhIOßWl©èi­Äšáªeg¸!õY‘ßÒïâÌØÀ .É~‰ýä´x‰¼“¿@ºÍä_¼W.ѼÇRÚQ‘ZÅôí²>D­Øn®‡úŸÍ2¨{Ûj‘§ø¬¢>åi0ç©»‰ÊK46c„¾•{‚³õ‰š‡mQnŠ&9ºrn¤^ïm´’Ï0.¨‘Ç£*ʾWË· Pš4L¨Pÿ «vŒ¨Y!~ $ø²í{Ú„3F±&g„?ÓòK‚í ´Ë1ªcw4G_£¥θ¥d·Ú¶EúÑ|ѱpfÑ™Ðzsñµ|ØjÞ±)8[<|ìnZ4Û[z òΫ½1Ü9ýVy_õ•ª—Ž'Î Hye)azÖÆH·¥×­b§}´ïKŽÙ«ü6¢öšÀƒ²r” iît§‘’ÙÑi¡·¸$­-dš¼²m©=!£6% Ã}“ý6´´1i›˜£O°å°Žò^ÆÈmrÕÖjNåõ,T±Š-â1žsŒþ±›ˆY/ZÃñˆD§[Yé½:º ­¶YÃ`<ú Nì­9jÞõ=BèÄu SU×!z)¥Gž«/åhéWá׉ù{;Ϥgô•T?ÝÃËSÀŠLϼÓ¬ÉÊa?Ÿætã®Êêg\—ìO¾¦vaáÝêÊcV»äjÙñe ÷ïh»^Gnhó ¹ »ñmõ;™[†Ç©­eOþƒr—HêÜU«‹;•BÜj»@ÿ‘Û(+}´è!¿Ý`6ç¨ç¾èlFkå±.”Ûö¯ÖÔØ&úJcèïçšdÖrƒ9K›`¬Í!ŸA»ŒHõ5u9Roo•‚üÑ ²Aš ôdmxE¹NüÆTk4ÈlyŠURÓËÿzI9Šï¥h)Ø…WƒÞÇØŽüË@”Ù6s\uiØ5©vE±·Ô‚r˜žÀòàJ0>‹ „èõ¶÷A~íz¬[¬αÍãZ½DnÒzBpªc„W9Aðþ¤Ë ¨:÷ïÃäùXþžìñµJYÃ)ÞËSÎ¥¼þÉ´Kx¡î›ŒÙ̬¹&m|´n¡ö£7fþĜʥtcOE;øºl5)ë Øï¥²´?%ˆŠ%ʽÔ$Ç”zV·êc<Ì)mgÑ‚vm'Q(onõ££-s—Ú7{×$MO~¯Â§¹cÊÏ‚\«<€Ì;V>rVÌDd¿VQÁÁ,«ò.ÈXY3ƒi§×®—GÒNo°ËnÉ÷zߵֻϊ]m¬uf2̈é ü;¤¤&‰Zˆ}ûâåèQZˆ.Ö£Xj7« E˜òL`g€,σ8¨~‚4Ë2Éæa(¶m—«L÷Ë%Êë¶¹æ u¥z8rŸ~¦öMHólR"Þ#é(?ÖÏÊšÊSU+rn#­ª{þÔòÇ |Pza³×äûÇ;6ÿÌ*¬x¢àMùcåúÌKbû?pçEV%µS&*ÏîÇ®¯L»ÁºPË·]ûV½ÊõªQ¢œ©nŒ^FWû ¡+0c÷yJ‰^ÙÒó8…ýÏ$‡òDýH; ^©¿Š‘3_·ËŠôa‡Ò9²Š¡Ž±±|쬎nãkû3‘„:,ªó¬V$·q ¢+ûb@(?Cs,0.u™ñ#Qõ³šâ3/FÑ c(åô¥…œ ÊUf˜°(·ÚŠuRŽMîFT½.<‡¹)˜e~¡ìF¡$¤áެ _‡4Ú›¤Ò³ÌD¬ ¬Bƒ@/.õEëe°ÏŒt'¢¬V~BWWXÓQÄ©Š"Ìó …²äÊ `¼n ¬ÇmSÀxKŒ„ðçÎnõØZBèRç.-q_ÁuîËÀÿ¢ûðßà¹|ߥ”B} U…ºUéA¨sg?ʪû2fѾÖçN‹ôôž¯ªyÁz儘ZÅÉÓÇ|„¥û8ú9¹öAÑ›غG§ã¶Eb&íìc·‹³­W˜l›9z¹—Iqþb~¡ÿÛƒ°Êxa)?½kd4ç ª=Y8A»[öQJK¤¸ƒ%XRkQ9Ÿå`^%c8@ô°¨kˆÞôT¥9»• z¾6ÄGZOˆÙ®Žèu©·ð·Ê'P{£­9DÊm[‘usí{Æ\Ûb‹´ ¦s14RÝ Áíìegè3}³ìšFGQïßi® ËulVh†sªÿ4k-Ò,‚àµ>M»2&·ø+}uR{„¨ °W‰ èþØ4~µÛ¬y¤:GéÏÓU{&¼ Îol2ÍÖÉZL–ýõ'PŸ±º²Ë–bm*Ÿ_˧õÏ+,¡Ì1.µ|ê@õiÙ–íÎ×ùøÅb«aÙÉ|‡­£a7•þ”tù"–ó kÉš.£Àùaå4T¹L¼„.×+µ`®ÉÔóÑ¬ë… Åÿ­Ø úiú žnÖûlêb\ÎEÊùrFp¡òÒ*—7odžõ„ø\dKl5œe ¡¢¥–ƺè³âWöÅ~¥Œ›ÂNÑâØ”£Eòâ Ïàfl‘efvóFçDäcë/”·CdšÒCöð½‡á8ln‚ä…Îkˆ©øÝè=Ï»¿7ެ֧ÿúÈ?Ÿ2sî–—Í·¦—HÞww ¢<âI Ôˆ¹I—†k¸ÆÙ ¶ï¢/ýÃúóP÷s0J«€XG}9D¿Òn£Ø¾"o¸fÉ×ýãÜ7ÉKƒßº]ruè5OO+Ý×)å#kšOO9fF¼Ó’¿7{†^÷ø"W|úEÁ¡Ö½P_mô††5ÎÇÀØÚb(«Õ¯³~`—>ȶöŽ{’F‘o[åXMFôÅç“f>¼›²D=Ä>q1&Ub=%æ Êqâu¤4¬É`üœý÷ßÏeüÿ_Ç|®sŸ'§=²³Ê–¢¬Ñ …Ò²ÊJJ)#JJT„Š$)Q!de%²7ç~ÎÇ<¾?¼¾ŸŸÞŸ×åòîó?\ûãz?nã~¿Ûþ!k)Ã@¤kãÀÓäcàt°_‚Ôò²Á ¹¹€}g¢Äž¹±ôcÆAâléWj’j ÞÓÚË™lÑ%%¯AlMb6È5À}Œsྠàw0©ÌS#e^F¨WÕ‰ÐCÒ¼aöEd„² ’Ù•×§Úí -1®QݨçÉ 7 ßOG-=–Á®`# Z;ÿN0¯Ša µûȵúyo. u¼ñ¦¼¥~&ö—©æúÕÄjs³;‡¤¼åfÒÐ8à··«ßBWAií{`Ý H+Éé”êÕý³E€á¤Ä|$EªßU´À—¯(—‰Èvj6ÂûïÎ'ê  Öׯ€sYÔÙCÞ½ê<ð.¨yr©·Kéë廊ë}ã ç67_:ódO¦8u•Ñ༢O‚d‘[Êr®ý ~ðÖý ÿ{é5ˆ¼‘˜îýio6KL06ˆ5Ñ€bêY%EZÃЗþd-ÞêÅÛ/éU>{DŒ¢¼úëÿ=þ¶é~³ÿKM­+£ëåªC„,ž¨wμ¿8]íódY7fd,ý7³Ci =ãPüy·Ot€ð©dä9sA?ïƒzÆÝz%1ü_µYà–×÷œñØ¹ß µ+ìA|múnˆ¶NïeÛ3>Ò¢¬¡Pô\æEùCÉ®Ìé^ƒâû3pV”de,Lõ,-¹'þIl†¾¤èEg‡®…hÄ‹9Ë™óç‰Óýü‹ – ®ôÂøÊóÄ@A{ñhòg{z œ3ÀFËÀ%§¾åÏÉ9ú£Ùy€­å'Ó7çK¿j…@ä]AüÃøPn-ßÚy{yœë¹³øZÎÎÌáLR ] ~RPª¥WÁÊ%›ø3kvI{6gN)ÙBÏÌŠeóGúÀ2‰š~wÌ$?’û’;Â/Çû¡…O'F ?“\Ž"ÙX‘zÕ\dÿ fo;ú$÷I££s4Ýk j%?ˆ¢hòPJ¹ hôG‘¯)÷€UW‚ß_óÀµ´ƒàL7£`g›ï‚µ0ð3¤6ÇA¢4¼bw§¥C™ÞŠK3…âòÙ§¡ôì_¡DɹŒ]Ø7ç8†Ý,ç Òâ3.KË«|Õ}Áû[Üi ÉîϧööœG¹¦vª¼žê÷âQÊËÏì4ðæ¸C@äм»i î,.€œÃ=¸îJ¢hî9æ²À ˺wHÔf¸w·û­ßÔvr{j¸º…z±¿Š× Rû.®d€Ñ¿è# ÓsK:)Hœ³áé^µè¿ Îm™ýÊ¿ð¥W—;üêìгøk\Ó¡ËùÜÞr휌„{¦®‰“™7ÜW¹»Ü~/æ]&7gA´œÇHBî- 4½Yd„¾¤˜çñÜžædíï„ñ zÒ›.„ö¬¿^™&öc‰Åë´àkÚÓ ›qjso­÷²:ÎëâÍ×fx‹Ü”Šv¡?‰ƒVš< ññµ(‚„¢ „±n]æC §‰mT¼iÈYw³.º¬Tp•2§4]Ÿ…Ü+»õ ™+^þ×¼$³fŠƒÕ’‚¡‘Š>J²ü@÷I‚ùõm“úޏ‡Pu»ãõª;8a5/?]£àÓÀˆìàÕÛEŸJ®¤ òŠË[ ò¯7ær©Bøz®ç¯¾q‚åûݼȚr¹·ÞgNn¿‚üž—Ÿhlç§½é¥J‹ò»‚§¹F¿‚­Ä me;©‚&ÜQÜ„Æ -^†Â'Þ.”È1B¨åþP{B¥dü¨í†ü¼Ð|”SŽAÎý¡Åš¬ÿ iƒ-ý&øzæ÷(ª#Æ!å&ö É%Ž‚Ëywˆ{ÁM÷7ƒõ§½DwuDíÔ]Í·ö@ÙÎÔWœMgdá1ë¼¢ N'´o»)½ö›çQ\lŠ­|ÃSÚq 9ãä(Rån0ËDÃ*?D—ÜÃþ½iu#•ãZ^+¥gA…JíteEÅ0__~¸ê)üKª­ás£«¿B³³}«^ó+_VÁ»—Ödþ\ôu,W}ùü?âKfžúJOÈg®eˆÝ7²ƒÐ»xIÚKx±&á¶}Dn9RbGð'J ב·¶ÒƆh¹äý§@ÐOÞCôŒ¿´¥¨ÕΦÄD;ïIRFvà!ªq(ñ4R·Ã6Bû‰Î \gø/9­Aõï€xžÀ«rˆeä€l,žòOƒŸtf‚Üå–"¹¸„ðƒZC.;ù‰ù¡iò‹ãú§içÞe=B¦3]®Á k0ÕzÁžöâ`¿çõë¹ÜR°¾¥¸]µtˆ†R6Ø“” eËšïïæA|›l …9õÀú÷Vk(÷Eà3H³° ã)}núvõjh¹[Šif–ãt°h ãÆ½©Ž";ãëØ^j䬽¤ù[+ŽQ.x1<:ëß‹Ï)¿TXyáˆÒ·j›³¹¯Æ…¦,®¶÷ü!¦V?ñ. ªí½¼‹}UòÊ:&Ò22¼@Acu>\o€&¦Ý¸ÅmÌ¿qš~´¹yÌ-ÒS>\èRÄྠ¡¸Pp;¢àYtdÑ!räù*:šun²€%ÍÇõyN÷¬o³*¸†V……gfü•âîÌ»³ÆqÙ=é^ô¾7ˆËþ”QÀ$L’äËn²‚r»ÚX«u£·—]d_q›â#ŠçõÎèSŠ×?¬U*±Éúm¼Íz£!éT¾M×´Ù¹ÂȾÉLȳ @þ(@ùeò ¨°J<„žß’N…L,ä´,óÎÓ0Eˆ8/‹›XŒá| ‘ã„!ë=þ‚¬T†œ¹LÜî€r-(å¿A óÇ'7¢gùûøÞ8VþYûôª%Í+m».¾m&Þ™åµ yàl¿Ûž úù’ûXpår¾]Mäß$ÛnfüBÓÆ/ÛKXZáRr&-Ô¾Ö ¤ßV¤#ª¯Ë?£‡ò-(³ÿÿÿcACpoÖ>ØmÝ?LÂKÛo}‰ªíM ÇÝk Ýæ\A¿ºÝðµ¼OðÕ'½ú$µJîTíi¯+¿+ïÊø¢’[F#ýyÙŽ¤œÌ&„¸â/A(-ürØb¯Nµ¤FLÌ‹ñåQ±M>«¦Ðï§=B1¥Åâ”ý'̲\:¥6œé‡^fpC?;‹Æ/ÞA„è!?AQð.€R–èn;QðT þ§Ú=àߦÔ÷~õ^p›îç3£RcAê¾`¬æÁ§ ~Ox!$j¤!¶8­.”ÍË€XI¹Œ'¸½lrÖAN}œ}?‹ke×õË•¦²ÄVº~Îj¾>…}\»qMäa]ï&ÞÁ¼¾Um·ÆGấ´Ã+d‚`qþoUĆûú ΈǮïcOî„Ô<.UûM ¬i¦võuÄ5–ƒ¿-ÿ0Ä6gÔn)Úh“Ó©0¡ß‘»¿`†:(·eáþÌÛW< ;Û/¼‰‘Û¢d?dž.¹2oÆNBú“ѽ¹'þ'„³ 8 Õ?;=ÁxÝMú¦÷5(Xâ+±äX¯¶~xcŒ§Á¾7ð1¤N‡VAòzZ¢±4¥—³âÈ’™"Šjd'^x0§£”Eoäžõ‹ ýÜWý£…ÓòâòTÉ“y¼ç㿦…í¯b³•ïìöiý€‚º–ÜÜ^列Üc<àÝTïõ^·ª0\û<¹dp 5œ``´3œÓfÇÔ"Š/' ¨ê/¨ü¹];U¸íÎÑÿßåº{!Öët]þY^-9Ž+r½µ©MNžã°^Þ1ÞÈ´úàcíQ¨f¯ô‹Î1\ýë7„Vß…4Þ´^Ç×òüû)QUÿQ õ¥\ç†ÒÃ.ÄSz_Q$>"Ä9õ²·‚å]Zp—zÄoK¾ø.%å½–ªFEÏRqFŒ&ÈUNF€ÖV<À¿nð} ¿’÷ ÷:iÑ5àô5ûó]° üÉB?@R ¿‰Aic Ú"Mè÷Biý¬­8%µ2/+î’sŒÏ þÎ~Ý[Xöy¸r¢4ÖP›X4Ø{…­…ŸGúÑñf±¾„´›×õYd”=’±»8¡:Z“òQÈh—3?7’ëáj?ÙïbhOy@ûÚmÆçÚ׸Úq÷#|mŽhL¾_»—ˆ±C;E#Ù)ú´q“ÆFísÎz¯Eâêç©¢ÖVÖUjp?¹nÏÒѤį6ÈŽöv±UÁ«fšê‡†P —+ÏRàŽ‘KIxWœÏÉ’cÅ=¼&kÒÚ«ìýÉ,OQkµÛXÉô7iu‰¸“•w0ç¥ÎAQìEòpw²ìkt+æÏ«~ì~¨žèŠŠ #òµjC¨¦x„B3Ï[ÄڣT ¾ })¾£Yp‰ºŸ‡ÍÎþ ÷!ýªøÉ©<cýJó—T:íÇ’Ÿp/#sCL~ÈO_ˆhZç? ÿ«;¹x9í¯”Á×o/h€|WÝÊ_¦ç=ç¿nœÕª¹?¨ÛÂíìjBQ>HC×ï²?àD¤•N£•“Å¡/­(¯¼h¯c¹ö·;ŠT¨±UFÀ/õ;B°¶ÓÔ»ü3`¼aMÃõ?çPƒÜ·S ‚ê0'ú @yÁmÎëN#`)× ¨ t!ðÿ,¦ås¥ÐQmbƒþ$°Ì=ÉG_†êVðН!5SíÎxc3xõ´ÁQµ½Â˜î F'He›+AÞk| 1iæq*>7øu¬ï$.£ý³ÉYšëô²s©œ8oofDü]1‰¿»G°¢?Å÷£Ç‹µÎ(ÑÜ€²Ên]d`N¥öÄ3Ngï d|âî`Wà¤ò&9Æ÷Ìa4ã«à»Úw´2óJ¨fª2OŸèÿ$[é/ËÖþxu¬ú WG9¥_w^C•ŸÜ×8«I·=Í£v!)9ÙÛÁ©ÀÃî~4ÿ”§’ ez]øÎŸ%%_„#NuN1Å/ä†ýŠ˜NÐ\/ŸÃU}y !>ËQ™H I ñ;>Aqä^åBf(ÛIùoËbJüÝjm"òª6T†ÜtYOœtî5NÀÖÞ$ÍûS«AÔùC›ÁÞqÍ·™àmg™1×á¾­.•ݷϻljïœq²;cíe2 ÇqX…ní!Õ\ìÁ³{ò{“ŸÊÉ”³*Ѓv]¢$Zù·¡ÉŽew@`¼?/8ˆïQB ½ãˆ‹Ç—Afç»ïúüߢ¢W¼· ˜Â·ÉüíqïWá%'ºÙæ÷šçíÕG‰)î*±‰ó~R *RöW.Š ò€²GùG”øXôò³d–Øêàwå¨ßÕ·µç½ù~Sm¿ÛCV'{´“ÊÃn>›ÁdÄÀÏ ÆÀÛ îê`_º‰²ŒäJ¥™ù¨l ¸òµà­à ¢‰ÿÅêÔÕæËSäiYYÕðåM+‰âSâ£ißEásq!šÊáktÒ áp/¬&O‚÷´}ÜÇ“cAæ˜÷€?Tûœ¿“÷€ûœ+ÀûF}œ~}HÕŠùrðgˆ.œ¥$;'o‚=E¸]_©ÛÜe{Û]±eÞjHüÏRãÂàÈÀÙÈVH«žs"ûµÜù>ódÚ‚à Üì6YEèékÃ)ŽjSâ™Aw Mµ"Çbªñ†‚™tæ€1CÞ¦¯ŽáíeùºßTߤ¾í>¢´¼Ê.÷#·k3¯zSAL³¿"¥g:³)3vËq]Np^&¢Ùò>¤yÞ3ÑÕÝÞBB´òbèúHO¢òˆh€&GÒ MÝåOÄ}¤@Õ9‹O/ñ’“J1øwˆVx²LÙå 9 Wä¨WÀ]¢–rÂë©Ô’mýê£âˆ·Y[@ÔÛ¡¢¦3ZÛEU§³Þ Ü›Z¸S|íä+ä$÷/u7Wåuo“˜-¾qõwÒÌî ò©˜8®µdH¢§UB<±'ÙˆáN¸x+ƒ¼ç®@]ßiƒë6"Rw÷†õĈiïÿ÷)Úqà~8ÜwÈð§\¹Ì€ô‡¼ÏÝ7C7Ü/¼i¡ërSžh¨VCã ó^;ÏÌ468÷éß6: xXçÕÕµî3â”zÓ_J‘ú·Å7,Ö¾¦Š{D)•Ï{cÔ'd†÷½žÉç9ã÷U{Šñ¶{Úžk¬²¿µÕ&'¸ßhm“Ý¿Ôie·ù«YR’P4¸z«=µdèÆUóûÕ5t¥Ýz4'us¿óî­½¢ªÿZ¢qàËÔ{ޝ=b5÷uìOôwCösþ`÷!?›GýaƜР‘oÓ&ž  ÙÞÎB5MÍK•'/ÔÎz7í){ Z¨µõä¶sgAÞû ÁÍkã-Bˊŵrý£¹U1èP~/¶Õ‚L»I¤‹¾(ö¬± íDY€ué_–¾‰Ìxµ´.‘ŒßK{@F¬¬2=í…Hû6&é—øœÁ%‰ÍXá®É*˜¹Öb3Ûz˜r'դ볳øz WQ‡Ë[(êŸþu¹„€5ô–)]­Þä=¦äùGe9^p/r”™Þó²9–û•ü Ó¾ß~‡µîb¥5õ½‡Í( ­ÉJ®ügg±6ø³3‘ôp ¿ uƒ‰‰^æ+2E+Ó#ÄúXÜ©×]¾2°üÇ€cþ)`«{ävëà’•Jf©ø-àV"ø'6D×hðËò‰È¼ÒCÄü}ÑOùÕ]âæèK¼ñz£P-=;3?çV+WdÜ&¾Ïê¯O繬7µ” ™ò{d8GùZÇ# ¯JUÇ Î·KÑC‹S³©•ÝÆÓ™e±N¼Xù;ÿzä?n»‰Åy/èó‹&J2v^ê¡åWyÿÊpÎVÚéÖTså{&Ur­7T¨wsŸæW¸¡ñeù´›Ëò.òúeW³ýxºñ-3‹;QŸ‚¢ UÎE©*diG΋¥ƒ9-½ÒRnó«–6!MN+sÈæ\Y2Qâ ãÇN€ä\TH|`ÍH½à.PˆbÙ@îPP\ñ? A{ ‚“€`[J!ü7 Ü–Rȸ8fú+lÀÊôh"Œœc<#ªæ6”oäÝ ü›“Ê’ì«lSëgTpgL.))÷®h|ãÍÊç±/O«’‡zqkõ^¨gÛ×è€ø·WÛ¼gÚVy;uïµÛrþ(«W|2PébÄ3ÅGWZ„70±àÃL;¢{rÖ°Ø{0ó0c¬9ÆlªÑ´ÇH)¿×0½–òuDªƒó¤,o9Xßùg`fÕOSþdVöÿIùÿlbšÿ5=nÖz÷-°o>úI†‚R¤€Ô÷ïE𩵘uH¸;ß)¼Ë\£¯%øQ®•ßÊ_•týËLpB— ”a¢±ö@^‘ý’ù “‹Ò_%)Z+¤»05 ¼3Êã¾PZðÝÇZCo ™æ´ö^à¯D©ÉÁÔV»ƒÜ¿Å»Dœꧨ©­§PSÈÕH§šò*ÒÚÇY”DC·¤ºó¾}\»+9U!ù†üœ@j¼Ø„¸váßoAn-¸×dn†È;n/HÿBTÂIÏR6£E6ó"­²:"›y‡}Áéþ9Ƈ'dla¯þbª;~z߸ƈ´Dbotƒ6(|öê7|œ6ýòaÜòO^z•ÌŠõÏOcpåη’cªu;»D4©þר[eHa÷äCåžM (ÝI—FÁkâÙ7æ*e7T¤ÁÍÎ n=Ä/Ê3E™ÇçÅýä:1¡ÌoÐ<:D>ÉÌh3QK ˆZÔ¤W¢Ь›|‡ý÷’åÜBÿ>w”ûý4ç†üÜ›‰ÍN¯ ùE€ëoþÿë©Ä* C}(U–ƒ¨¡½J–r\+G±ú»~]l ^Ѣꭴ*¬QžÈx ¨—ñÈ3*ñ¬ eM¤Ÿü1ç1NûÇó^å/9£|Ê}ŒFzþÓ >›·Ôû:47çù™["KŽW~Yë~ùÉ:òÕÉüúÃt<~Û/ótçê‰T‡sWy ñFÁÔÜõѪɩjvé s&/ß"}|Ðz¦ÂTò3¾ªfŠws>ÈÚËPåb´UÔHò"iÆÄ¬§Ø\}Õ{#¹ÓÚh€¥²þ±—ˆ}_§ø'äÞn‚ƽÞhz§(—=ôzžÑÅ/Cê œø”ÈEÀ<40þðÞñ @Ù'Wýd6ˆÅ)àKÑáŸ6¶¼¥.Fõ;)? û#ý{qܹzê&p{‹7ÁËÕ[‚?ƒÁ²xî<í(ªÝÌxÜ´ßÁëd,÷¦q ¼yÃøNG³ ‰˜'‰&VK¨Y|¿^Ý¿ÝÖ´Ón÷ä?êHg·@h©_e]ìdÀ{‘l©üÃêÔ!­ÝMø™rv'C@j”ò%^tOª7ªý©²JûÙc‘7+^Œ›˜}!†YìµÀl¡d´ 1)4L*khͼŸÅ[ÆQk =2>´MÞÏ $gzeYãEûÒ:¡¯Ó×ݘlŽÏ~àÊÏÚÂüÊ>U*WÿäÂ>¨ÚëÜ·Œ«±àÜ0œêo_=IJ•,I•f½—è«\æÔ*}Öã?]ÔPüŃJ6KGx®ä¤25ú'BtŽ6'.Î%~c9 ’KØ#V¦ÚÈ{¸ÛêË~bŽ.Îs§÷7äFg!iþãÎA” ¨ÃMg¿RÕü‡;Åof19¼c¾Jž\œBÙ&üÍåÆÈù]ZüZ?33ÖâÓ { Š˜—}–bõѬÎ~H[–¹ÒöÃ53žíÉÞè]x®bc¥Ã…Gn{ˆgý:uXqþåoÉ&gûUn,&”Ô­ð+–Øžu—×OCú.g1Zå½±Z¸YÇ­©¨²•Õ _\u†3{Û_áë}¯cTÚWÿá·DP²ÿïù’P´‚`±¶ùQü]%²„?´?¡TÏq¯ i΃Wû{orB/q—ÑAûÀn‡Ôƺ_QG+ò>m¡œÍNõ¦W—xß¹@ ýÂ'CX(4óµ·¬ <){‚H£<ȈXlSö‚?P{ä’T_ðóÍŠÄyM{½+r$Ï»W3¯âªÛÝŸ¸œ0K’Š 7Ÿ»c´*WR#üÝôu7IÏ{[ùÝ+/+£9í½ëe+ØôóøVmý8ÂJ VA¤¾ |‰¡£H„ÏAü¶ÈLˆ‡Ó·@iïŒ]m9 JGfÆ!º0{´VüKø}«›}¿Ö9šïŽäÙÂæ~*ø;‚ÕÁëi4…²ÛS!1Õ÷À»ðál·»ð®”»Þ“›z]‡+¹žzZnÉèå¶äž|WY,zdL çFÅNá”Ûi÷ÆÈißÇ9%âÏäÌ´Öú¡ÄoÁ¾fø"³ypW¼‘±(í²—Œ}i¥‰Ç7x%qF¿’^œ¬*æF:$? Ôc}LZ`•sEËôžÍ÷/€6C6ÿºúÈýju•ŸpSô'Ь§‚íäÙÄÏ¡îî©XƒÐ÷ž›È ï‘ÿ$7F4oGâƒÈVwŽýuäºÛ7¹*ÔÑÏQš¯ûo+‹DÀUÔ Å×å;³NÏ©2O¾ššñ.VÊÁÎjídB·o2ÓhìþÌZÆÁš‰ ë7í‰ÔHûÂJ(¶¦‘¦ tb„®—ùèíµ eQíã$놩Fð?Ñ€U'^÷À8›–e 9W#0ŒÕ^‚×Rãñ´o­öøFko%J`™3…Æ>{9êP«=íŒjmÊiåR2TëæN%K›ç¦›Ö2™P Ж'Oƒò¾z?ˆÕZoPçØÿr‘òCEOïe:ŠýÖ>9Y¶×ÓÅÏâc/Ó¹C¶ µ¿Ò¼Ê‡²Š=ƒ”¯&ÞÀôVæ®Ãçù'ª?%Ø…R÷ª8Çiû&7R:—ä=Öqã¬ØävÖ¦¯û•Œ!­ þaìä=æIL·‡³ ëdŽÂ±V [Q@¬JdØoV@Ù¯Á–û)­ X“";¡lXúˆNIÏ¿±Ë¨U¶4RÍoçœ{M¼0WJžÐ^¤´tšÖ“e±îê ÆÄnê7©»Okñá^+t¯z¤2;­\u¬ªg¢¡Z0¿QNrIáÁÐMyi7ø†›æ±›ij31M·~B ¤Iï}¤•ËZus Rø±JQ/0‹ÔnŠB]Ñ–þLTÿÒÇSÓÿ ǯÿDÔ\E‰8f4康ÔíÄ}Ò÷ÿå}¯3Ó°d¿aÊY€ë 'Œæ5`$Enž¤Ð›­Mâ¢}͘Ã^=YŸŠNMêQÃùF|Leç*îwؘVꀕÎBë,šQ=U‚º‹¬ ÍçµÀ½²-üˆß‚ªAË­ÍsÁ-¡o½æJó€ÕH½(?µïfbP&¡JèjÒ 80'yÓ¡ {3?†žˆ_äebí~˜=–o€Y翜€{üÃ%³Ø’¨1>“FüâªÎn­†¸l×ã…КÔ4N„·$'3Aý"y‚¤f:«X’5ÎjÊq-i_b“q2¹KÌqÞ µ÷:AhZrø›e/ÜÈ~k&Ší5GÑ»O€ñáé¿%ßGñZhÖ^CPsc{Àé£e€‘©7}3½@´”ËAtàY Tî9Cm <Â0õW‘öU«2•ÈAá;½ Pæ|©6Ái ¯›÷‚ÿ‹6œ<%R—Õy`Ÿ0_»VàÂɼ“Ô ,ë<ô?øÿy²ü|2ŽÝþúæ´ü{$ÓS ûMÑ+>¸¬6½RÇ:Ò*‘]hRÇé˜hG¶Ûj_NAðù@)eÆ`]ÇV×j¿°So¢ 6&+òsðÕÌ—å.£HÉæˆú˜?ˆ FKqŒÞæ§æ‹t0^”óEýA#õÿwk³hÇežw’FJ}²A=¬¾ªé1ÝÚ â51 ”º8%o‚øIþlf#«Á¯Ô¢È«˜ú˜ˆ¿­´-çüç½û™áTv¶•ÖDzûE>Âýнœ™þv°n%°¯Éíàt/@ò+«$*Y¿BꄼÉÜ]PÖ6µ â=jý–û ì_{@P #ƒòk"k¼Ýh Jæšô ?ÌñÈLåO,Óe6U•ÅXJÍ#²ÏØìœâÑà½!…ý'õ x«xܸO9ãw3«kyÞ-ñ·¨ç¸â_}³=Z\0Î9£yHku ÔÌuªr6ØÐéIw»rÜXëÔæ-­昶ÐóPµ?Ý †–ãGUŸrg£(?Ê/AI÷ @{Ã{”cJeëýª <'O€2\ŽÑ_| hÔÙ‚@Ôú  üòpIý¼Yšn–(rŸvÏýWµP¼„úež¥_#é®Ôª0ÇIÓ›ó+õ¬¶[ꋈث»¹Ý}Âô¹ìÌП©oôÉ̵ßÑîðÊ9+ÏxŸÉ8bý $[³ÔG°¬ýê92zG\çNzV›ŠZ/ÿõDHÜ¡öûõo,ÿßòö#…o•coloêg¼Ä¹ÔCÔ.:x~‹èí|]p‚âÇh'µ¬l4–ÚïÒH›êôÁ î¦3ªþÛA@í î &€Ûðœ5€j¿…`‘GÒ&y”ƬŽç1ƒå±g)·Å¶¤°l³hCªÌ¡½x¨¸£œF“â8È ¥ÃDP˜ñîú9ŽEk*½äÈÄGb›«7C…®z/h;"~_ü%¯Q@ œuÿî‰éÎÙÔw©ˆÞ-ÿÇüâÈ'éÒ? tŽìV™Ê ÷q†¨Ýì¿è‘»3m¾¼žØ‡ì.:ƒøÀJ¥Gâ¤ñw¢9"ø£õ$—Òóìå´Éž#vñCÖgnn½¸3ç=¥#dÔpÿ!–ã‚›–6M %™‚w$¶h"48^ªæ†Š]fnÚê¸O"<2¾œP¨^2Á~ÉùJZ›Ále]½ÝŒiî!Ð5å›àM0“Æ „j}½;!í ÿ^éÞ}تíÞƒ¡îb Íä9„ÏÙ%QOÔñçg‰s\D'åZñ=é¢*ý¨ã_To’ð_ánÊüÇDkÒ•ÏÔ Ý+êçèî-å1*ÉãšÁ·“6…wÜÍjžw&kµèâÝ©Y¼cý®öõûx=Ë»S-eÎkî~ºkÉ'ÝiàOÅ·ëhQRÁD'¾µÆi«XÜG#ú4¼úAÖ{fŽû/îö½£ à3íõLd^Ò×m¦æ£§PæCr´û:¤Šlõ/ù©·›Ê–àÚw$¾¢Ì: P¨´uÆp)º®´7Å~&%úQRôŽáûžÝ „)'¡±G\'Ãm¦¼_‘(ïíWö‘mÕ÷ºSÉí%¶’²b C’oÊßxÎzF4õ—%^“Ü,÷¼2,¹ÍÍ‘5ãgÕ­âUezÚƒi2ãÁêÁºÙ™uƒ÷SšV‰qá_å]ÔŠY…—3Z3œÈ& §=¥Ü µv¦êåqÂŽò "p”ßÐŒ7œò¦™îý.Vs}p"?—ÜÏK™wUw#9ȆEž¿6NýªüˆËMÅ•Š=.§jÅW2•Ç\{ »bÿ«o¡Vüùz„)ù?ÞÜÎ å®ó3s†¤ÅWÚ˥èÜ@w¥Vi`xÙJ„()[Ç q-»y-qœ#b}2Ì9²RÇ 0Èú‡|:÷“+:8ÃÑðÜ[¢†gq?)4çÑüÙÇ.íISs¸Fuå:%äê'¸b|ÍERæ_”cf 1uå¸Ðî•mÃé,›Dº¢Ë[é4ÊhŽ ,ëy³ÇÕõœ ÿ!’Üéí¤½|¨ìgõGÆ9Ä49=8J´öËÇŸRøå•¡xsÃ&o¥€m/´KÙåÎR;ÒÕáÞÍë1‘€=\(ìA²9É î|üÔuù2ÒN×~DMŒsÖBâ²ÿ;$šò Äg*$²¹e¯ZBq“Û€Ù¹ä{¨øbÖHïêŽÌ ú>ÈúÉ ‘ÛݺؑÊíéï(‚‚Ð34áö´3º..Éùîy½A°…óÿêÛ¬¼¦¶L|B+½\|Ñ,’8VX‡YÚµ]LÏ|÷RGz•ÿí\>½«V½çñ o]{IÞQuüÍϬ¼r¿Å®F¿×°ÛÏ0ËñhAv,ÔWšLR‚ÑøúÌ€DÑö@j—Ý}ã¯r‹iºï½á¥¹ö.@å:\¹ò×5h{¾ZEÿxy`lõ~ÄÑÛØƒqE†¬GÒxÇý‘¤ò4ªºÅjK@•ò[lÞTSØJw ¶ÒB~Œ«Ì’#ðEušËÈEÒCÌ”ݯ© ‚~ÇÔaJÜ‘"ÅÏ@ºhïk`·ÐËð¯+ Ðåâ=Lw±q¼Êfxª²’^À·ŠzXÿšYz[_€“ªÈCw^10#Þ'ð3x 嘷‚wr+Þ0(ÉK¬4‡ÊÏ“‡ô_¼Úr¦8b=ê¾ÄçñÛü ´'duâŽßbïË¿!ÙJ,‡ÒBç$ÞÅøp1 ~¾þÄ3þÝ€ÊM­ÁËî£g¡§5Ð2 íM­ EÁB·óƒM™-kv˜-©e¸²’óéºGö—^fPb™y2øM±¯ÿ˜ÖòV}ugn‡«E¬Bß‹çÄ‘jß^|½Uwœï‚Yíøõ½PñÊÍL9"/³xS)kXüròéÈWÖ“É7Ìkn"þ»ZêeÄzª×hûVT#JœTâ9Â`Ý `m°·x /P  :z[óyó=À¶ÄÆOÄNd‹Q[éâ-ÒG…_wzòCzê±ôÝçKoËž¡×+\”_"Æ^Ó+ÿ ç­êÍXzvuõR¿òõ¾Õ.‰!·ÞÊŸÉ'Vzæ.1DÝd¶%f¾ÊRÙwÛuÑò.ÇË!2oOæ¢¥Žƒîœó;ë{}Zê4£•לú´œˆ唎t=$V‚øä¿ÀÕ1ÈèÔ/’\<ùµw‰/ÝÜŒ7>³ŸD3ÞôÞ ®¿hýK±¶ßkNe}¨¯à©[­ïPÕ8Ÿ2E;áEåeÌa‹8+Þ‘ ”‰üÏxÚ/Râí âx·äPñ&94ÝÄ Þ‘ÊB1I®PŸæ{êYQÑTŽ·ëÈÇ©›~\L”øs”FÞx§#õåéàDŽxÙâ-lïks=†¿CüÈ÷rzθ}ÜAtKÞ}¸šêlCÐùEöÁOÎÓûbZqã ‘Tå8$+™u ¹0°RÂ=!¥›Ý!&Bâ÷EƒU;ø!k ì ‘¤F„@lL貿-1N½;µÍw¸=ÖEkF¯Ä±‡¿ãAméÉLezb‚\…LŒöc¨‰[b”ÄâEÿFÔØL¿'Äöû@ê}­Ä÷¸p^V"½§r{0Óô- 4“/ËýÏp4KôàoÙËφ ’·3ؘšìÇs‹UŒ)¶¿C žO|†¢oJV­¾÷DÖG¿%.~k=¥Þé;l‚•†Rý¿²˜…¼±ù&Æoïe€\•ê€ ´rÔšÓ_’i¼ãýÄ»æë–êøï°Ó¸+ñ'Rï©Ì'×M#ÕE/ñ’œêŸàë‚Knk1ˆ!þ|qWÅj’›þ/ò ]ÜÛüMt!%‡‘&ŠÄF,ÕQœq‡‰ÓüYTËB³H<&Ï•÷µ r¤UU¼Ìÿ%ÑËÿÌß å»ê«J¹Ú\É ´Vd8Û™¦—±ÇêÜJûTè% ­ü^SãBO°_ÐÇ"kÄvÜÄõð!ôÔ5SB|Px0XÍB¯AòÙ€±÷CO@ô@x8v|Aø9ŒÄôð<™z)ÜHN(*6?öçú+ô´Ôd#Þ¯u¾faüù`êF×ÄÞF–~d¿‹“¼;ü© YiñP(ü(yú§Î>æIåmf[hBÒX,ßÃ3"â ý¨»•„>Iì$¬fªÇ©¯þ$5ŽxS4öÚ(«µ¸|Sìý©¯ü⽦ÜT'ñ gäo²9ÔòYz(Ÿú>>Ãä#«óH#Gù‚\§XÁ‘Çâ×üõ¿ø†˜"GË»D7™’ûÕRFxAe±|Ÿ ¥†lîí5qÅK¢ªwÝ[Ï|·µÿ8/ð2¸CÄjNX?s?W¹“€õ G©á^*•œIò;„^¶•7BÃDEæ„ø-i~’?è,¯kÑßSï·*‹§4=ÑŠ»Ì¬t¦f½ëB¹@ëÔ“ôˆœOý@8 %êkK|Š8“ZƒÌjÝí®}Uÿ„Êÿ%þ„î–½’šÏ~–ÊäC·{|=KÛ/ó”94D¬Tmn¤nµ'7¼,®¡ú£íD «ûýM¸áÉ4ÐIU@Ó4åoˆüÝ^®ïøýÀ°’ÏãŠï½‡PÕwU?¸$ZÇë!.“R†Ëã†Fû‘òDb5®7OyWù]ù”#b>šü­òZòM"~©zÅOϼS«·F“kË2ñeéITš+¿q«Z`.8ô§À[©]«ŠQ¬¯õÀ:j6ƒdÓÀ`/׈­ n‚ÄÒ€€äŠðH®Ö†Xfxû¢w…—Ó¹lOúÛ\+Z|Ó“ñ¢NüMºìPÒ2•&~+™êgpʯ]¹:WÓ‹k^az¸ pŒ˜»Zþn~®¼ »ê}•‰Þm®ÞÒIÃ5Ç^IBœÃ¹Àö ³»½CÖ5þ±#â°>ÝZAMcŸÛ M[äÜCºy¯³´a^w m¾Ý´£Þ)¤Öß퉧ýîÞ‡PûÉFxê%ož2ÙËÇP—>RTáRTðÄV^“o ED~‰ÇZQÁgr)Š˜¢ÌDõˆãÿ~­&;ø_Œe ÒY .Ãv‡ha 1IùìÕ+àžT«£ùóõýà´1ο^éLÊZd4¦À¹©?J9§šþ4ïÙ›ô¾¼ç¤3Xeí16’o/ +iÃãÄR·Ëƒâ¤xPTëK?.‹ ôf‹ò åeÌyœ†ò©øfñ¼¼’ó¡xÈ&4ínÂuTv/¸óáͶƳ§¦¡:³½CàÌç°êÈß!ñm<¬ÞâvHTs@â~χè«$~½¡dª÷ĆXõ ÕŹóñ«¿uÇLÔ*uª/oB±dhºr‘‹Á"“eïüË ¥Œk ¼#gÙέÇ΀£¬”eúÙÖ¿aÐrÇ+7´ÅVèG¬³xÙ笯¹ê=j —•ÍCŽ'Ž?Ùõ0ô=Öýd›oЇHäJ¼'AOõÞFO8m@½à<úþã ?âWã-«6È^þv\uŒüÔÜê8ê9WÙ‡‚ä„_Ü&_ÇQÞ'‰$„‰à"#éÈ4YO1Qý3ÊCäAñ'®(¯ô àìоEñF ×ÿ@™‹î)*àÝf|Þ6£=Òß"º RëQp·‘²ßÓÆpÚ=¹jÝÔ·âXºù0{™mho}e±ÐªakA „+©SÚë(ÃÝÅþ›¢¡µÂ©ÈJ¿SÍgé’ñæôelã9µÑqkúÉ+œ»ÜñÍάŒ(ÍãëN}¥öyÓ`Wâ ¥Œ«ÅíSé\(~-ZßKî¿uFž(ÙyýUn)›bÙƒã•8ïTLU¦¿Ý‘„å`ÿm*ÉK,&•åÀs"›ªn q§}†Ÿ(oâ·'gË4°ßWï¢n q‹Ê¥Ž;†ŠÎvíCôøNu¾ó­2ÅÚ,f²Ï¼’~?£¬×Ü­ü)öªÛi û*Üë¥'K{;¯-̽N®WÝûÅû4ýñ´¾þ¤¼ÛË­ LŒmö MH®MÖƒÔ7SW¨÷Jèksî ¡©r+•…Ÿe‡ÒQÌÖr¤-~ r^â.ˆ”˜«Á¬i~vë²$¨'ýqH±(ñ%—fn‚¢ðE¥6i#cMå‹‘é~uQ;´Ù@›Œnü‹›y ›s‘Þ—Ô6ÖË\¿w ©XvÿÀ ã>ç¨öš>É~GýD7Ý×…›¡üìæþ.Ö©oøS”›zŽ?_ŒQvË}Ê~ã)ñ­rEi¬Œ§™­ÜÅó|#’"ÃXªtÁ«´“èZ3¥dd8h¯¡@ðN.BîöÈ©ïŒô‡í þ¶[‚ò¶›—Ó”9\ÑÄ_ê"w(—•G€ˆâ(¼:¤”†òYÝ©I)W€4Æ‹”+X²»2¼v~œYê~¤¶ZmåjÊ*,§«ZDŠ«ê‡(ÎEÅÇpÔÛsÕ§Íâ¼×Ò˜…Pf©'iýÁt¨â¾k>Ga²·v·ÚÒ;i…ÕRo‡8§tpžPª2È>ì5€T$¹šå-=Â9uhnúê}G/„5ý¦„Â:EãÀþY›ÑϬÓþmö jèŸx4ÖÏ;o݃žV9m1Z†š‚ØD_ŠÇA™¯Þ2C ¹‡Å`åº#!þk´?¤æXÃÁ[,ÿ…’ë¥Yà®g$h™ÁÃP2¦´1(Òœ‡´,ù GS]Ýi2ÛÏÖ‡x}¬JÎ/v#™ä‡Ô3Êkj;·žòŠÚ0t¸(TäDžR&Êæ<&ë–õawf5¿?”;nþŽ“qH-AϮօ̟õ$„.y Ò‘_!ÜÝ?áÚJvÄP¾G\Ñ"ˆ§ì¢,¸’Yl ¬•çå!ãB¨²¸]ë`}Àƒ)QØþÇÊ7Õ>S×Ü\ÏoiošÄ³Û^» µ|Ó«ÿÈ:r£ *ß}íVåW¸ÚÏs×]k€_qõ“t-§”íõZ¦WKµŠ¼ßUâcŒÙ(QOs9ö uQ¢.~¼<$W$ó’·œjöXøF@ú*€ÿ€Ø |  ìÐKŒ&æl€`@¨#‡±ˆG*!8—ö ëÕ‚4Ï{ݸíL Þ›˜ÙUÿ²x[ù>4½þhÕ©p¡sUUþv¾~U_š—JðüõZ•ã^Å«Ë*q—ÖÌ©ï|» Ä¿eßNÿ‡Mñ¹U›ËMâï *ƒ”ûì”謬wSQY“žF£XòÚÀDó9|»Žü )óŒZ`‡Ü¥h)Ï2¶åŸÏжAªª3¼³Æ(ÙXš£þùz7„ßËýÙù¿ ùWê[Þ[5 ÑŽJÛÚùý™“û·³€ÊÉ·ýЬŠôó“Üо÷fa%WË+\ dI‹2íŒhGMsß“¸ðÅ ŠùAüˆ.‚¼NBv—óÈIµ«+Šˆ—½¯>HíAu-A}€2Œr%ß«>ã%ZOº'ÖéP¬þzSìT3u OÔî€è\ñ™·Í¼Ê[VU§1޽[ÝŒžœSÖÀN¦{×è‹ÇÀKžÕF¡&§ÈQÿ]:x”Pö‚=â_i'áÖ—W߆d‡³#!{•¯@ù²à—Õ@Ó 2'ƒì•ÆdHwåWÈÌw#"Í"ˆD¼3þ/úÇÇéÜßÍ'ÚÁdˆ#i×R#Yœ–j‚zÅÝ>b·!©,öÖQ'z=mÇþd½ÿ`qw†z "7[½²žÆ9O_{›‡*l½Ú*.¸>‚Jù“‹}ûÞ¬_’‘øÞð£©!ÑAf;{^ÙHíA²Ê P!ú#@4 ñ@¼@j €ÕÀÉðføƒx@œЛmÌ'‚ýBÍ ä¤&IAzC‚êK‘íò7ã¶ô  ¼˜~Ãi~¼¬¬Ü¿ÊÏ·üÊ5áòQ쳫m¸ðIÉü|fY•=vƒ‹¡ü‰ôkr"ñ&e˜å ZГµyY wÙ_V*O„o¯rÏg\Iûœîf¿ÔV‘:«×a†ÙÆ«¥ÞJéøæ:õg‚úç¡gäÓÚ—ÖQÿ;5ÏüÍ$&ku¼ü|68–Æï>Ã4íáÿûò/Õ¾ï@Ñß½NÆø¤ô­ÙmQÕ,ëAµ•²…,½JG*Y"¡¦è ÚôègÀDåyPî1Ç€Òß¿Ê÷"ĹEš@P~r†6ü¡‰@>ÉNðbiCµþà¶‘—ÀN Þ<Ï+`熒/‰ì·×²œÑɇÌÏðÝ€ùŠ»ÕXv/ã/°˜åÁº ™88€“ì<‡n=|‰‡íãn`ÝLåÅè/¡Ÿy:63pAn,(c\ Ûy=ù¡¸7ÕWžâf¼¶8ˆ»aÅ÷Ñò*C’{ÌŸeº„Øg^.Ä4aÀ­q7‹ Z域 sŠÿ^ú‹ü…Ÿ±_†ªÇ“XÁ³n&fä;î¢K Æù”y‚IͦŒF7#ÅL½–¬ÂWúû,!ª¡9õôÎünùʯ¦Q:@d|U𧸜7ðÖû¢[ÎÄ›û”×Êo¼ñ ¯”y£²üÅ›Ÿ!Êu-8 ¹Jñ-ܬÊîAK¿3±œ›á;“uýÓ¡)ö0ïM}…3ŬOòÿñº+«ýOå§ŠÅ0ö‰1tg6–8)úù)ýÛ´žZÈݪ¥>æ46F¨Ÿ[uƒÅ3‰‘ ˜±s™ë¥-²³·Ö–Û7Z”ï 7»åÿÈë×—ËñÒnž.ÿŽ_±d{î!ñGâÑì ~êŽÐÝ"•öU• Õ7%[ ·üªø zZ'òy&2?5ƒdh¼uˆ >ź úžäÝÝ!ýc«˜"q ”u²¤ Hí¢e€¨®¼ÍV*ø/ÁJ¸üCíçg7 ôFÄhÊð!kuÔIɬз8åu5à–÷i·äY¿ºÒ]»Ýß,N2Ïû“>Ú0ÿ(%ñêŽG”î¾Å©ôå@~ŠþêT§$õ›š›‘åéú1šrœÙÌb±\D5úRÄËôKŽ•*§Ë¶ˆtÊÏÕ²ˆùŠrˆ:‰”ØÊ ðzͤœó€6›r®«~·ê<åk9AÎWÖú“ŒùÊ4·§¸G¬÷Þ7¦ñ¸Ó娩žæB {Gú»œuúý±Rß›CØo`üKËdç@u$÷'"S݉ßå 6(4 ’ó‚AòH0±Þ¡b(ÝPš †ÃÌL¬‰<ÏœÂÁF²’ÝBÙ•|€î±ù¢ ûbõ‹Ÿb ¹šÑÞj¼Øl™BM˜ê=ûÁߥëœé`-×jB,îÏ„ÄPZƒùtæ³ÌyBRK‚:CÖÂÒ5F`({(@è/Š"PfÑô,e"R{FŸÁþ‹þÛ¬I²œGøX¾¯^Ô›³ÕÞ{iïKõ§ºþdÄ¢qɧ_¢¼¯$¯ŠVj=q!Jù*]ø]ÙNÒ[…–Š—Æ¥Sn!‰¸uù7þ½ÕŒ›äYc˜~Ý¡a—óÙíËßÍž´Æ†!çGj+_ŠiU”ßèi¼UéžþløG±08Ç›à}nþ©6³JÅ4óµäl¶D²‚Ú‘ë‰ÆSyÌÊГù4d$3Ç| ±Ç\Ÿ¬Œ“ªÁ¬ÔiÜ`wg=^¨­ÛˆÂ@ëT-NVqyªhZÏÓÔ­Té®Y•i¢1ä?Ñÿ?TœK¦pñøµ‚Ûh« öãì ŽˆŽ¢Ìh"^çz`³{ƒ·Íâ/ÑÈx4ÞGNÓÔ7ËVÚvw­û¹òº.ÝÛX™lîDè¬Ôñf‘«ÿé/`{à#w=oÎNrÓ>¯ 3LEXozs¡èNû,(Kå³µEËÄtVÓ¸šØâo £àmgÊH5™ö¤ö"íÝ„â¾2 ¼/”f ~¢YY=†xßXj7RkðUüAí/eôÖòÇú×ÔjÞmËìN^+¾³~É\ÍwVîqÒZ|§S}"ñ·•ÌÇI:†ƒ÷ÔÏ!öwÄ„äK¡[mþâ"qüø¶ðo(ÑA‡ÓÛ3V¤>M»D§ÒÉ‘®t¹ÑÅ\ïÔ!DQÙeë Ê•þ"¦Ê‹%·ËIâ¬êW~‘þPþCIJ?““ežÕ¦Ê2Z¡È¹š'š{ÍÕ©Úo¨rÎ,s/³TI¸íÅ6ï~×ê» (§6uRS{Dž@* ¼Zõç 迲d77ˆ þ|PöwƒrUþ„#úɧ¸LžRŽªÌUQÉåoðW(O€¿TUÀ¯¬@ùMïuX5Ô®x2G†êPg½Ö¾¢¹÷–fQÎ¥µ§›3P#úoiý“^¶xÔ+ô›1ÐîÈó,°')œ°f¸§ê]»ú Dv‰¯é*¯÷°[é+•ÑÉïE^øûÄ÷È(ˆýÅÀàæÔXn¥ï®a§ùWò+î=‘œÆm¡¥‰ÞÈP5Yã÷Æ (SÑ´Ž]ž†Û›5xÊ‹ÿ{òýnPÜøV”-¯–‹æÉ.Q=¹YˆðÉ^ä@²6^xOb;f žú ýœxá:ÉãøæòTgôÀ¯É: NvCp®;ícAé¢5‚P$õ+h/X;ðÕê~g½/ÓØ¨-«Ë]¼ZI–ñƒ3ÔÏŠg‚¯Ê  ZÁ™ vOû ”qÞv`®l‰ù›§!ýÆê„÷¬ð9åNà®x‚¹Í«g/5›¢º‹ôïÁí$&ƒÓTýRwXbàä@j“úÄë?„Ĺ`'HT Ý©{C&VüdXbÆ?&‘¥/„³Å9i*”LȸɤX›tƒŸ‹öîI}rãu¶—\ÓëÒÂë×`iႚ˜°µ•^eu§¿ÏësŒwmKßnmàr€Ôì u±zãZ e?}—ÝW¬ ²nñˆVÓúߨíLÃ3šÛ­ÑõGÜze¯ë¬'‘êLç-lýU§¦~Þï jܽÔBo¨_x·ö‘¿ WYî.µ±ü_,fR,“y˜¢¿¿Dy>#È¢5pVœÆ“Ÿ‰V¨þ u˼¦r.½Ä:%AžUËîq£ ‚Ÿø œ;´‰H·HMa{_h[0ÝFFxyÊp–˜;ÀšnÄð܇ô{ðíF#4w®nO>`Ϲ¥èwÿ£ÀºÔÔT–z’ú}|õJ%=Aw÷þoÕßï#sìÝo¬…ÖÀ¿n‡ä'ÊVHÝ­/ ˜Î7|Ïô'ð˜õ…RKd6”½ws#ˆM |EëBµÅ‹`”É7!X[k‡§Ÿ«QõEÖX¾ ¤‡³é£­Ž} ú}¡üWûÍ»H'}t°‡_lÓ¯$ºº×³‰?yšFï<>£°B=ü1•°ìÂ%~ݹ)úŠ˜Î%àôW–QËê¯T¦0¹TíINì[õ/HÜ£~*3ôE,v¥ó {’UJÈþ†ûÀÂφÔ#nCHœJµ‡äÃêWkã,‡ä¯ÂƒØ¿ò*ĦjK¡¨¯û8B«@y*׀ܵµ>ƒª:Á¼Ëy„}ÊùdeWˆ®\ ~ ¿aV8¤=ÁCj„"#Ójèg­äQ/¡7 ¦»åÕÓú(+F c]²>—Ã?§¾åûÀ«Xv5¿slqFß‘ú—F¹–I%sªó¶qÉúCßéü Æ(Ï'Aè‚û*¨õœ"bú 'W xIªç¼yü¦ÎðpKŸêM¦“2Ì”GÜ\²õ—•{ÈQ–ÇP¤ã6Q&Ï€rLNÆ’‘FO }µ*ø‰8âWjQƒ™âYNùMÕ ÷ˆVJ†_ª|ÍÞ2í †z)ó‰8ƒÕ±¤ÙÏê­@Ž×wàØ‡ôÞèÎ1ópîв 5V3ñ+aTÙÕÜH4Õ'PÈi;_?,ëX{Ì;ÅÄøþÀó4N|ZË(ïÅÀ!þŒŽ×^÷V k£”:3n/©ýÿ ý^ìÄL¼øwo•Qš¼3zWx™oâa÷KF$V;é¸v{£#n¬¥|‘Z¯ÍC$^V¯â¾–h‹SôMÙyDéÑØ¯P²4¶ ¢•¥ úy¼Òj”œ€á,”]Pý3¨øn; Lç8Â-Ïßü"}+ø«µ($6Ù¼¬z«š,Bj‰@)3x„`ê=§”bˆ>ŸÃÙ™ƒi«Í1ÊùÑÈúÈËòÕÀsfUÙ/òaä]ʲêd%lý†~M1c £{ų†œ1=Q¯ðÆhÓ­û¸OÎ(óñÓ‰S(éÛf™¦/5'Õ2ÜÈÝ`LvŸ} ÿ2x›>[ëàÝiN7:€øÖ{OœçP—šÍI¸ãâ3¹èvž—õE6õyË‹Ûc¦ÖWÆq1Ô(|FÌÌü0ò$Ÿfæ‡ Ê‡Ó?¸Ø;‡ºhԃЃÌkîxœ3ž#[]ÆÐ+xÊÛ†ðNª‡ô÷ÝûÄŽ@?û fÆ­%ôË'ÀœH5EÑç9qM±Ç‚úsØa­º§€°¼z Ouƒú—ÿ1h}Ýc ez¥À(1ôçÜ·Aë` Ŷß7‹Ñq굩s ¸SºÀU±¨ Þ\uÁoc¿NkÑ(g~ÊŸÊà|î=nv 1ˆBþÅKÅÔ¿pœ…懵æg©z’TÜ34 ÉÑÃ\LmÔ?ã¨ÓÞx‘tëŒér›ý—y?­K2ÍÎ,öŽ 9ÍþJï´æ)wgWuBãhfÝÿÂÿµƒGþ€Í½§~e«’ÿóÂé.ðƒùE`ˆ]þÃ`¾`Z .»!iG÷ƒu,ö2¨o)ã@Ö¤*ðˆ¼ ä»ôOñ7‚ñ~h$h=‚?Cê‡DMð®’1ÉxìûüÅÜ—êªàuH\v†PÈp¾¤»÷ñÞK€IDAT¢~7”­HÌÇ*}ÖÞ‰é¶ÖJ7£m¶-®x¶ü*%30͸N…¢²[[h“¨_ü*÷FË_MJÆ_EKèÌBË<)ÏBN%c#d¯6Cz{ñ ¤;êaˆü%kC¤¡¶"Õ”ÉX¡2Ú`O£ ÕÓDz/Phb}h“¡x¯h…ì÷úˆå‘†îBúË%þ@æM­¿qÜVz`_t*ȼ²ÖØÁDÉŒŒƒ…ýx0ý™ÂzrUÖ…ÂöâîrnþÀ̼“׿ cö¦›kñ²>(îÎ’ì'£×ýé;9{‚“¬œ!f=çc{‰ÑÍ«aPGù¹ã•›r¹kˆîr›ÓC.ùkyþ×4 /cÐŒGÙ,Z(oò¥¸OUåq¿ößT ´zòå>½™W[Goå̸±Öjì¥×7M£ß,#c¸x¶ð|öÓ¼Rñ^²/.¬ô£‹J+íò'Þ(¨ØŒÄ»Ê¿ÂÄ‚.¹›ürHæv¿‹µ ÒųyUq²ž³=Ý¥Àî‘>žÙ¢CN!×µ·årëÊ{ÞìÄvlÿ±pe4ÿ …’Ïc×ò½;½þÜíÜ羈íìÝÐìþî@g‚ÒÜ”ß vk‚ó ] >ÅÑ!ÙÁYƒlx ‚/d¿ôRþ¿oÌ¿º†Ë«'Ž¢ø¤æN¡ºµÛYiÍ£0~E©€–½Òÿ“±Ök„âGýóíkQ€¥¿¯ÃÐ&ø¢ÉUÞ›Hw¤ºÁ[ò1lûi‘…çÜ®g¢„¢Z,7b•Òº××j³ÉMlV+sÓ?h쑵Raã²øE4W÷àÕþHM¥šÑƒº%fàqž—ãUÅ=}D-s÷¨MXœ˜b3*ÑTôâµÔSJ-ÚÅ›zÃñ¢Qÿ#Ôh‘ý”½ç¶„ä¢ÀsPÒÝ^%óýß¡à‰+7ÁPvävGrMBNsâåd=Èì!€Hk‹m±ýf¡³Ô[¢Z`Jì%&¥ÏJ¬awøÑätì´rñEjc+"·'{áª%vdh»3Ý(ò€ÑNùŽD0fßÅÁ²Q2ƒ"çGÑYîKÛ_LÊìV:{Ì[%O #³SÑRºe/¹§CÖ÷ÑO!}Vtw§Uˆg7 uHU°6vF;Ãô n‘³^›à•s)¯ûž¿Aì÷ò¦ŠlŽÊ‰â”Ø)ž=Äñ„'®*]¤¡~¤¥¼×µ£ûþ±ÞÞ^mVÑ{XeÁ~úÀÔ÷‘3j*¶;£3uK3rkâÞz»Ân”ë/V£\›˜ÿ˜|ùÚÁ —Ý/®}W®•Ó¸° ·{¬æÍ~c—ÊüÈÎø<ïKòËV(•hZ´0 ¹—ŸæÏ þSÕßäÏðx+ó€8‡¼è¿,ÖkýãQ††*wÒÑLW{ŸëKµíÞSÚÕàE·¡’;;¹WßeýŠä'ûGÂgœLNéŸú¯Èî‘/k>)”7–‰DÔ«ÿAþ÷ó}?Qxæê×§žæOo“û$Íô¨û.RÂoŽÐ%'*¢ÊM.«&jˈòX`ŽÜ –óÅP²“ýe’XÍCÊ‘-¿Õ¤€®b=Ù÷:²‘Å~S±†›b'ƒü7¼.¢ŽTÂ%â±ØßÄK^K÷1ayYúþñ{+ŸÒÔý[¯†ð†é:qg¶èÎ/ö$³ ½œŠð݆Ê/(Ékæ °&¨M!Y1¼ìrfS°ž ý“šg,ƒø³z¬J ĶD%j÷#-qàmî‹×JKçz4˦Ò/BE (;®W²Z8åÅäD¥¢cÝjl-n -Þ<àAé(ç(ËÕ!þ¡qÜhtåiH5»ñ„÷ËÅä% ý$ó ÒAü¡íØÈ`ˆP}öPfÎBc‡Ùo|Âór›¾D<+¿U_`éêvš(õyJžá¬x_vG%‡k €üG+º§†‰öÁ±ò"?\wÔádìs­gxF,_{5œ¿Wî«'ž W¿Ã¨´î‰2œÀ«V =ÐÇ}´™î· ]ñ¾å™TËÀÓµ·ÀµÌ"°o[OæáäšH𭉻×Ëf‡—¸J,ùI~ë,¼í¹©ŸÃšœåÕ âïv­P)3†€2/Ü“¹Z Z«·Ú4ï|ü#µmðžø.>K=E%ch¢"ðFr­uú4õ#„v[ÏCx‚½‚“ã_‚uò °Øz ͬž`¾äü Fë30 sŸ´Ù£@µ§•íÀ7ÿ©ÿí g³Õo7ñ„\çô4ôšêýÁÞtñ™>È*ÂN{o%Åf}/%n]'L‘5Ûé‰k~ç}Áê{«°´„/YomñJ¹.îõÎQ5-!Ž¢–õv¢[CÜoZoñAù©ÁMñ«ø†­œ2‡Jöñ ZFHù[ã]ðê© HÉ•¢+ו·´LJ½ßµ‰;•ńԨ~žæúL}ùÉ“Fe\ýýNLåy½ªôeSå#¿±!ÔoÝq„eV}XMƒø4Ù6tw&oê›hšø#ø~âÝÀ](©á|H,5€èCaM#·CâÎPoˆµ7؉ð\dÙSáÍlŽnIK£bÙìHߥžÓ#Vzl/£béî—¼¥¶ã­è9¹‹Öe%wãÅtmjÙ'þYˆ“Ç¡´¿=b‹X ¡»*¸Ÿ[-ÚVe?¨uÜ ¥³´-䂺Œ÷@ýQleˆÜNJ=@ˆ€2ØÝJž2”™¢R}†8JC¹¤²DíC¡4ÜyÉ^œ|˜³‚2%G{„ënK9ëW¢×]ƒGñ¤”ßàpÎØˆ›úÜQ0y—٤Ɏ†KÕDîÅ©dë×â©’þ°ñáÑZÜ^iNflxÃÛdUŽæxï=£¹¿Æjªü^¯É™H"^™g2$ªSl|‘lϾ@Iò3bi’ËI‹ÄR'!LÜŽø*¹?¼Ãþ3´+õ,_r’wÑÂü%ù µÌü” |çŽC„¶Ýl‰ÔÏ?ü1"R÷Þ'è¨Æd碀’Twn¾»’ó7;ܬN‰öKü2 ÜÁìê”ù´Ï­#îyu’QÍ]'æ¹—­Gp)r\ŽÈÏœ‘cŽÓ€;Ä‹® .p_ l7sN°Åhå¥2Ü#TqîôV ”ý~-°\ '–¨ê< J'žCÓ”çQâ‹ÜoPÝfÞcÈ´'ôÇñ´Êª¯¼­~ˆ[VÞߊª¶ÒbôÚH,¯¢ºPµ)ûSõ!Âj±a¡‹Êúnp«é6Rb„›e¼É_Z-½¼‚êj ·ch1s­÷õ)lI´g315YÛÅḚ‰%R#±"¸¢Cÿz¢eá8”I_ƒ}/Ò¥ôî´öì-½žvƒÛŠ‚†ÄödÌaKÉãçÔ‘¢+d–Îyø2£þ£(ÁßË-åcã ùmµ»Åïi­¾v—;I<¦½è~ÏëÚp»û­®5¦z™”ê::íŒ÷íí Æ½úì7Úz H×Î8ÏREõä³$Å:·°2AV'¡¯—!<¹Ø=©Œ—«P”N~T%Š  ªrƒgðä' EÊâ|ÙOI"ýcêz,ÿ3åL®hK@–W>%á¦kSIø«¥¤¹ã´óð u Ü›úýTt†h?‚{LKg¡Ñ RÝ¿ÁÿUŸÄç­²Œ;ÿh{_º÷+»}3ÙФµ½^3yŸÒ!¼"^È‚ŒîÑ~l gÄë²$r=q¼ôÞñó„Âo'æ£Fn%Ê üRj„žÍ…`×T7ÝŸ\Á¯cA åCBõM«Cúxïö!Y¼úÔã8¯••Ì%=56Q?cbòoœôM±[˜úšø9ˆô±&@øŸT  R !´.9Ì/­Ã̳΃Ñ;u Œ^ïM½ ZÄ©ƒ4^÷<ýÕ² ´5¡«ºM ³^_Nme‘ò7U¬’Ÿ©¦Ì¡³h—ºG®æyÞ“;½ÊaûFpT¾/æòVÎ^¡·h-w¤&ãxšø›oÝÍ ,ðK¨î4ÐçàÛcô—Pìµ¢ X‘4œŽÚŸÔ´—!9)ô=$G¨ÙŸn 132Wƒí¡tCäiˆ†WCaÓŒ«)}² |æ@b%k3¯“v37{.ܹÓYÀó2ÛYÔð^/eî¹Íuz¨ƒ ­­Ì)ýÄDN3˜Kßp7£„~ƒÀ ¿PFͽ"æÝ¡w5[Ú-•eÁ—­×©ø#Õ‹_”щG9`NJv•#õö^±>£’ó;3­ÁŒÌDmÐF¹K ¶ÞÀ ¼bïÁÔGº«Á¨om#•RAÛà5ᆹÐiÍ/ê÷34ú;é Ïòo€:ׂ6ÞiÚw/¨7ý@©æUõ#t ‹£€íŸ%.UŽl b/»€öb7Ð^ü ²«øä½xß9qí´ÅàÚep3½9ào HpO)ÓÀ[k| Î :"FwùÆm¡½ÁŽ©Wij›šUPmÇh îBMë¨Y'µ[ÿÕŠ+P%¡ŸÁ­o.BZ½ÍAÔŒv0užI•¨m“Ñ”åÉiIûñ!ò«"ÿïñ÷+ÒèÄ7 sVw=èÎߦº9°2`w'Ö©oÓ.z[t+~¼‹™ûÉie3½û ~•®¬h| Ñ1òg(jhm‚X\¹®ýY8 N”ÝŇb=ÅÊêÐäŸì‚Ä¿Î.p÷ñ6ÈaUÿ"e q\Y ü¨í„òë*ŽÇ /ÃŽ¬ 'd¬ÊÈf“þƒ:“JºœÌX}Šº'òkúpôÔ“öX({±ô ¤}žþ"¶;ÆnŒ»}÷Ö¼kQ´ÒA7ê¢ÈšñŽP6æ† ¡üYÑ€r oå&D^§!RÊÐ*ù» ÐO«b—û(¤º´›jE<·¿}žÖ›Ç0ä%–#E/¥=BŸx ;’,÷!7ò‡×šÉÁÌ+‘7¹eÞƒ¯*Wù-xŸ?]œ ÷ ¬‘ó£Småxs·²ßkeµí êFsVj,ÓÔÖ.7ÛQ%M?ÎUqȑе (+•§Wx¤Ïtð·‹l ¥Ò쇬S`·HuV¤%XR1°zwÓŠ`9þp¾–å 1ÉLúÖ3b"•ü˜x’þzûŒçØ•W¯R}¼¼7òŽQŽïÝÆw¢<ˌ۵#ý˜ëL]ŵÎÅ£• ¸°¬À…— ðNüaÈjà—@f‰< 9ã‚û!ý1qÒnú{ -¥yÖŸ•öŒ¸¡ûýçl`Ô“§Í!nÔÞ'*†»'¿ÀÖO[!ŒP½ ÔÝ/!<Êydkÿ˜cýwp‰ø_#½ûü¦èÚ ¾¢·;—¨fY£ØmŽNÄù(p´ìuù±,KŠ6æÆ²¶ N›Q2Œ—3·”­!’>4šéã5 ¼05‚Ǭ¥`þa¯ã†÷$¨Kesà7ÑøF´‚:Ü Æïà,2]H 9+í22º2í~Ü’6™? ÎYA½Dznyñüìim5˺—ce³²îæR¼NÚT^'?ô†ü'QÝXÇ…œ 2–ƒ›ØJë°ï]‘Ÿªwøíئý.s•ÅêÃlç¼ åMvy‹Å~i9¥¬¥Ÿé/ò×q^~˜% ü÷EsÑÈÏ t Ïÿ86ƒKn¡Ú–,g¬ü‡ónû ªÛ«üä|-3hb×tUjÙkÙˆL]– R'íš`ÿ¦½ %K‹3 ×¡m1\ÏíøRþ¿o€ÜyúwR?ý}9§.(× <Ôn†ð'xobêëä# GzAã½úy ¨AxÄo ä ËÁ{Éü>ÊtÐNOƒÒM´«¥¿’{Ì=`Æ”¶}A}$^DÆ6›Ÿë·“HÖºrÞYl6£U¢í} ´ƒX …/»ùà? ž£,±"Íc÷AV?¿ ²î£"dîäÈr ñŒEÊTV¤}(/s"íˆüÄbo&TQéžèÌu£wb6ùi·'€¹1u´¿ ¼Åª úãö8½ÀiÐw. ñ‹< æa0–ÚO‹£o*)s&)×9š¨¡EùѽM9(wË–âùr¬_,ßP’ö'âNýªuƒÏÌUÉÍâzè½ØAFG^oÄ?˜TP­"0Ë;—@ÿÙ{´Îò‹ò¦úxcµ&àÖ1.‚]787™ ½†–¸3­*ßÄ®¥]g\´búuHi•ÌE~×ÒPzÜK–¾”uƒ1-OUMXÁÉ'’ ô÷J«X‰ôâMâ$”ågfq,Z[Ï’Õür‹d{óZÆ4fFú™/+ rW‡U†…î³ÛÐÊüÑ?Áwf;?ŸïL×ûLþ° ï‚öªùšó¨²O6±î¡½ÙÊÞFÂÜŸjÎÆö`®]ì#Ô ÞîºÔÔCîX²•/dC22êßF<óA9÷He$g|.?HV?qI~¢Œv&øý•Er?CmãßæCÅï^q…l1ß+Cü\¬Ä÷1Ìð¹ ôüe_(?ù„\ ÞXÙ˜IR¹S|ŠP‹§¸&ßVYz&«XžrÄÚÃHtå0B ^ãEï¤ò¬iìUï’sÜ êtw¨±^Éõ ý=ÑÒù•^ ¶ ‚ex©öæ¨Öס°¾QGC¼r¨RÛÌÙ/ŽBò“`Nì—Ð'ˆøòpG´XAømbe‡Ã]ˆDŸHëBŸ2/|ˆÎemÓWòoÑÀôLÞ/kÚä6²ˆ¯¢’+¡ô”€â©‰ªPT@ñùvKý ÑZ-¸qGt$«&7‚ºÌ[á?¤áÕ¤Cd(e8áL@wZà)c9`oºþ,P¦F?Õ=À<åW}X²Š7Øã) N9÷ƒ¸êv~u;¾? pÅ4À0û³Ã·W;¸Å;cND÷Zê°ü úT±Æï¨6VzKKySŒ—o0DÜ!‚\‘ƒD=:Q•åÔVzíݯոûÕµŽî"J'Ÿ 2]þJ·‹âÐøêÌ@mcEúíÈÀµ¬OåË3ø¥{$t³|ËÔmf_mjâo¨›âûÉ5G&²ù.2+1†5i«£ø<òD*xZãäÂá'Áè•øBÓR- Ø:uBÛ“é˜J€™nû(³ÒÀ¸×þScÝA?Qý:„Ô×¢yMí4ü/¼ö÷U/—ð“o=ÍsÙ»Mlµû¥RA9gÈzu¾=ƒ+^u»ûÅ#ÞÃRîgÜ´FÙ3ÈEw³Ðõ—½\,ªÊ:×t€bÈ@7ýz ¨ŠtDÒS¼A€¶2Qú¹5+}Ž^)WÇ‚»\ ¿¹Ò”cêZ@ÕƒÝF9¤y‹¨cªO£9)m õŸï²Ìi §±ÂûÂ܆©>,¥¥W/ð3§=Ë\Ê|­½v'+ËÕöŒànQ9µ,2ŠGâãyäÅî ÍDƧEÄâá¶Û‰BÙ•P1”†ÒŽCé¸ôÞȲPš‰(ù!ývþ-ý2}uŠ/eŒâ…¢7³ngü:ÁrÎ ëŠRºÉÀŸ¥ùÚ,/}Ì=ƒ]ÜÈ=Q:Ç_ %Mý2°gg>™5j€ì¼Ü@íé~JUw ®é»@sÿÔýg¸Õ¶÷ ÿfÅî^™•È9çD‚P•d‘ @Q¢"*"Á@V A I’s†ÅZ‹»»ºÂ|>4¸9gŸ½o=çÜïó¼ãC]}UUWÍ0æ¬1ÿã?Æ¥@kÁnІÉÇ@­ë-¥¹¸´ÊH¤rÒé‡ùJy.**;X¢|ÏfF(Í)‰#*ñ!š°ª—m·eù:È9ÊUãØ Þñ&¸õíWÀ;älﲯ(Øå ¼d$ƒÕÂÙÎByܸ«íÀß3X/qzL)6Ŭ°2#6C¿'ÒÉWœ`MT+$äåuᔿxA'N'îίL³ØŽÁ®TŽ=Xðfì”Âdd¼Zp[38Û,1­Â#Ñã Âï‰ý=Ü #°¥ðKž ̦¢û²Ò&ÐÔÎóÊ›±ÖK®©©¹Ã¬¢ÚÕ¡'Èè•o|Ët*ÃËSÿÉìÂaÙdÐC<þäÚï’1QŒµ.+³ÅÚ'žòž°žeHø#Vé"lZ“xÏJ äWógñNëÕw áÕ´+¡jC¼qèùv°7$&jŸ!íNv„·Z³ÀËô6 msœ…îVÈÇzD-Ñâ›kÁ]!p½x0 êD=b“ügvwBF| ±G_‹4zø>BZ7Ô:xÎ/ú~"j؆å 6pÓûÁ¼BEQ×7“‡#y¾Õ,6ZZƒÛ×R.44½–SS–Eƒ-ãwP¬ ¿¿j~½8‘× Ö…¼¢®36~äæɇ¼ã àæ•„šx91I» ³aü(W~HòqäÆ;ÉyùFzb·8ü>}œAµwr´ÎåÔˆªÔ3ÇZµ)§µ‹lÃ3–Zñ(¾:‘B¶oXùÂèÍ7Æ1k»Ínî¨Ú#‘&Ô0®Ù&®ÖÐ_{ÝYÚבúH-O”FhïÛAm(¼ ýÊÏÞjPš{_€ZÝ;Joð“Š1Ú' >“”OÁë©xàÌACºÕ1HÕ?¯š,„H³,ž7N<€j%7°½eÚgXÎ)ÕG8ãkEˆ$}7J¨†1’"Ö`£4pxeŒcx…úžC±7yñl¼Qáff‡ä?Àì” s&åjžGÕ¸C…_!ãÊ皈¸§ Mdü™P2Ľ\ð""F .ƒ¸µ–b¼‚‹à¯yc'Äìñ5(ÒùÞn`ÆýuÍ·›CîG‡¯"?+«bɸÐ|±2¸ü³Âà æé þWC­Á˜‰ë_foAv9Ÿ£ù ×cŒõ˜J$ŒìÁxÎŽ½½3™=Ù6‰Õ†Éör¾ÖAn§·ro¸…÷¥òU$$±ÃŸâÅROlßÝ=œ¹ÞF¸±–N tJ‚ïwvBÊ"å[pêZÂÖ1œpÞ!å5|‰¯);H”ÇD_g¯Û/W]JȾGù$&ð%Dv5!2JŸáu¾fکχÐÄØcb¶†ÂÝþYPpÍ7òšæCî´¸Ÿ w{|Èÿ1ákÈí?2>Jü–üŒU‰>ðÒô†l«]ÞšSá•ð½\÷J††Ð/檵Å×*2œOÍ-áíXfÓÈC”3«[ëP¬^H#ÇiŒð݌܅e¶ùѵG¼2(f]ë2èÍ `tˆd‚>ʹND½iïÀЯèùVG<õ3ýc½Pp^=%Ûx¥Eoû1ïWN)µäKB ñæ‰Îf–¸ªþ¡µ›Å‚àyXì–Óå1ÒdÓEÖ"‚+îCã]P8Á(ŽÓY„yW<§ô–Ý}3…!>²«aÈêò.qÅíjn¦ »ß¢y¿˜øÐÍ’ÅDy×õÆu&)PÝ-ʃ`wõ{½‘ßÌ:`W×gBäˆ9 ì!ú`ÿjœ+οÜnê~&ê…-}›qª¿,—#£Íbô¶*›õ0#)¾ó¼>Ëjêf<›W3/§è|ÏONxêýM°›ÒN&œMæÓ/f»9±¿JÌ×Ü™h‚_Ï×Fž ×Õ×Dšf+³‚M<“ìÂ×僼^XEý™çÞìî¼uu:5o6…À%Ñ üåÕÖØþ4ïqTÿÓJ,ýÃbãÍu"ÑqÄòk/ô"ÎïTÒÛ:ëèhu Xiïþ@ÑØšîZ4šº7вÊ&.>m‡·³E°Q¦€[Z»Œªên\c€Ö ²_ÓmÖ†ÎèƒØÈ)㦃ÖÚ> |g=Ô ®ü…¥0 °:@^m€¼:7ÛØCµy •JŸq£‹¥Aj•ôm_JŸ…çëìÝ@šqò*ûb¾õúòv ˜qZ¶õ—ÝŸ<Ù¯æ$l Na›¡„®²ß×”’2¶r²×hÍ.Àkò~Àob%ˆÒJ%°‹¶L3ú³€¡ÊÕa‘ãWF{ÍÝTÆÓ.PTýÀ»ìuŽ›döó\Ç[-Ú;£ü«èçÌÖKñª}Líb½­nFf:Nä\ ÂÞ¤5@ õ•„ð2ã2„GûÞ%|;‰f?8býf.€‚_L—üü.)¹šÔ®ÆsTಔþºú[­yèôàÜê¼ùÉ~_µo~æßÎñ›ÚN{K¤"Jh?‰” _qå mÂ_¸]Æ@è}óÈ©ì…Jȳ¼Ï!ƒ›9Ø;!8T­ ÁzOÈÝeõ€ðÈ— ïóZ‚¯·ÿG-ïÐ3ÁÊ ]ÐV€yà.Hß^,JW,=búùæ€=)ØŒZ\qÖû'r3TÓøÍI¾²@¹—ÓÚf¥ÁÈ…ð[8Öw¡J˜j¶z•’ø…Cq߇le©6•ÚTñŒ²®?q¥ dw¾fCÁúë ²íæ|0fʀ˅%ÁX Á|B½žÜ º*F‚xM¾ êcr6¨çµ® ¿¬ ÆXÿ8q’*"‹¿X¡zR„á µ(Œ…˜Õ{ ù?”Oâ÷7‘ßRÄ?S/#fiw¨=M]ï+c=LéÀÝáÉ8æ—áþh¾:á‘\3³¬TRý¯Ù¥(ð×¶jã3.Z'0õÏ"Yàïç4¿Y Z²Ý´/Â+A­ê}ˆó1è8™ ÿît5ßû´ˆS´nN&¨›Äs äÛ»vKP窃^3˜néP)CÌ1 ,PF/9ÏίRdv@uw¼ÄˆÌ‘ûÀ«æû ØÏ‡9­¯“>ש!®#­ š»×œŽ«6‡pE#"åÍçÁ)®­‚Ðns„"æ5°K›Ë(°zúös­°‚qü›É>¢êkiµðÇgýÛ?kåžØb ¼rZ\oKÀÿëq/>«;P“0V“AI60O¸ “í€B€üB9N¶·ˆ·ñÀŠ ÿîÇÊ  ¹> Ç?×SrÁZnÏŒ­Yk2Nƒû¶ÿAd°³S +ø†,ÄߨØd±ïKß$ß'¶×d×H6Yú}âÊhc¸A¥³œ‰ªü*àÑžeò;¨?éÝÀþ.4dN8ò¸_gä€^/§#øý¡¿ŠSP$O”‡Ø]Ò€øýƒØJ±Ïpcê©Ã½ˆÿ{ÙÅEÙÄOÂ¥©!Cásø}DŽa˜[í~`&[GÀ«ê¼æã²™î´‚PŽÓ;\‹åå#1 MîQ÷€£˜Ç@¿Ë|W~§æL^we-GíÑr{”r=?‹½nrÔnÎ`O׊[i^óû[¹Ø0í‹rÚW–áW%Ë{‘ñÊ*ΉVtSêÉmÞ!íM'kh)ò´;ÇhÂ)·¼¹\d*iF–˜úÈ·W”ý?‰‡Ti>,^WßÔßfˆ_ˆ—E½ØY†O|YÎ ôIkùŠFùw;Ï ÍrNKDlнxÝû®¯å ¨2 Ÿ \à8Så—œ±’ÅaÊzÉÊ=èrŒÖÍÿ£hb†R²ëgÉÕFª%I ”2\^Ïß®òöKUYíu—µÅs‘§ì¥Ü°—È×xÖê%àn+Á[ˆ¾¤N@ ݰºCð/@á&»4´8±ñ˜5Óþ‹pÿÚ0x(ÿ'Ènœ÷ä®V%èoÛõñÜլƎZÃHµ§ƒ鹿l¬ o0⵬áÙ£U@SMcè/†wC¤¡ýD4¥xÛÔ* ¨¼¼ÇÓà,V‡€˜Äp{«)@gѰ[Mi†OŽWV€÷‚â€w\´„Hw%›«‘¦êÎñ¶f°_}[}3ì*'åcÖ'ÔvËk™tpÎÈý¸n1ï7Tg¢¶ì¹î°6Y«ÁþL°ß– ÜÜñó‹_'/d5#ûUÐ;»Ÿƒ±Dôà ôb” G—Í ÒwÑ”…Ú^$;4xÔ«¯¬R~tò˜ÖÊm‚¢ìqË¡jsÝC Uö¶ƒ¨éå€ò“—JyD-YDijòˆŸ¼“X²}ÐÅSb'ЏŸí ŸP®‚<¡¶7 ì·¢6ŠÎUí ÛÝ«ªÆ:o¤w€_Èð‚ògåo{Ô7¼ùMÞçd U~ÃIå1öc‰¬G•-™I‚®"M.Wfð€×JiÅWž_9ÀPﵕXì~®~Áwº^ŽqvÒEŽ–c°í1”G‹ s‘´á5+]\•ñÖE¾’ý­ˆ˜)úÆ‘4Õ¦‹¢—ikÓi­¯q—Pßã^„O:žò©§ ¨1"–‹jÞ¤›ú¾äe<û¼¥œÑ*¸uˆ5V¸G¸Â³²•Œ™ngʱB^&^ûÉ)îR@U½LPöËW +S»à+{A4ñÚ_ŸþåÃÌÂÛöŒÌâÂå>ÞnJ›ª'¹ê-t—PÂ膉˜ySÖù2‡}OÈûˆ8?z{©áô‘ùLÔFã¢Öšl>óräÃÝ»eÓ)Bª:L)M‚%¯É5^l䙌uîùPÀT¾a~`ˆºŒš7 ¤I±˜JZS±0²Wyšæ:µ% BÇDgŽ;USŽu7«ÕE+¡ð’W nBØ£´2Ä9kO#Ý£Ú0¶:ÝÅ»ì³;j%‰µãòû’ùëí74ƒÕvMå9'4ǰù$2Ú$YÏß²×N1>âó`s–üÚòŒ>bŽ=Þ¬&Ôˆ¡œõ&J›±V’ØÖRjAx`äź.X7”j뜆py1BË0x•èr\øE0L΂nb€žA.hÍ´ãj5µ?`)=]Œ% `¬àEyÉeYH³ÝMô–7½ÙâÊ:›øŒa‘/Å`¹É.%OˆNò¢hG_cüˆ ÆDƉ)ú+rcµKL"V­+G ÕÄ"”õb00W.Ph%ÚâÉé²;Š—ÎýìrˉM<ãþH²\àÕaŠùNÜ!–ø­ø?äY½ª•+zù^17î¦v§–öi¤¢3” ~9âÇ3>°{³Õ¬ë¤ªÑ=òöC(z3§#è¿;‰`ÄÛ>ÐßµçƒVͽz »¨"߀ÖTÆû0(×v u5@»+4”°´AÍIl j±–‰@@)Œý;ÐãÒ³‘ž,š¬]ZÁ¸„UÞ#ü`—´uv륉˜‘Šv„²Óy!®:qàÖrÚƒ¾E>‡£lð¾A†FZ¢kåEø{*ý!gM¨Øcí£ wû f‚þ ˆòb#„îv ÁM’cÀiD hMÕÕÿM`?ä]ŽŒu±6 ”ÁÚH°'â­¤y/xŠò ¸«“Aìѧ⊦úe"îý#rå#ú§b¡ùœ0—Ò–eÆÌ“|ÓÓ}^+ï51îO‡w…4 §Ç=†®¥ME-Ô}U!øx싼O¯ù; PxWìD^,Dl]ŒÈïp!×;‡¶y“ã2²àµ˜]LÌ;¦u?iÏèüOœ|Dþf%P8‰å7Èû"§÷B\FùŸ Ð(¾ ¨_¹ËAûXô-EîíkQ´~"”îò$(ŠÚ ž’eAùƒ& Æˆ‘bœÒ !ª{}¸ª<$uÞc<Å8­”!ŸÕÌä2ŸˆO•ÊÌä¨Rš£ò·5›d/öÐH†å78ÞDåw4ψŒÞWzƒ»ÒXîC‚Üjö§ž·ä8ãn°¶dIÐî¹¹³ôáòFà´ó±·ÌHö½XØ“æõPm^|ŠatÒ”P}ŽõBÕqâ²B |›Ã»pc…æbø6…üàë®þ‰áÀß/Ü|G"ü`!_¾[ˆß8l=E]ó¢ÝÆ»¢_S¤£Šçeñp"‚á4ë¾<&­ÚÅŒd(È’¿©ÿ„rØ_†zkdA¨·“' ÎMç »,¿¨—ÜÓŒ«ÜÙì ¯œP{Ũl<& ½mîd„Õ"rŒr¢6ˆB9äpwRíÉU„u)²ÌÞjyÓä 7wLÈ]úÒkÇÝYVnõKånfD4ÈÙzÒ–Çßjs% =gxŸ2Œzz.ÈjJ.sW€¹Ð8¾¡ÆL½‡¶”|-/Ò\™ÉéÀ£ÅC‡ÔƤ¦_F„Òô}ؤvöÎh÷s#²ÁÜEª=_Y ÖDý~ˆL ̃ÈłУúi(,£ €ÂÿU÷ñ/G†æÄ·Ž?ì˾9ÜÌ@»J½ôŠT!©è<{ ûñî r”ónQ:ùºÙýÙÆûî|òÔ½î‚ê÷¶Èñ*SJŸÌ¤ñˆçÕ‘W±Ôi쵌ý *:§ÐE¡žb\·k‚,°ª‚œŸtü×òŽ‚ý„ëþA<å­ªš=A[œf†½¼Ôe ÔQ» Ü` È â`‡ZHÇo˜tÀ-oLåy¯8/‘¢‚HC¸›„Üeúu›½.`ùÕ%H÷Ke4®;_}š°ÛA݉ãVÒž&Î= QÝ=â2‘Uö!nÚZ&¥ÌqásH%bÏÿÁP„š‡„ØIá« - ϵˆ[|3¬î`ì±Wƒ^*ü;è‹Aÿ¥qSPEÉ êþ û§ Ÿ8CòâÝ'ÎŽ‹lå¼)îLWë»!^Ö¶ºãÅPµ³[–Z/¯@LUg»øPûÅ=Jõ%‘Áeõu·ñJSL¥±Pæ;÷bˆ¶"K]æNÅ/’"óE£Ø8ÙŠ‡Bué‡t/x ãß”uÉ.ò ;½W䊈jL%I Ç€þ6Õ€ßÈEzÕ±‰µ×ˆñüÄG¼Å|å’¨Â.í´˜ÊTû.å2R=(:󆳓yM”§‡\iª8r¯û#šûŠúȪb$¸ÍEWpúkíÁK1?ù™÷(؇y¬ s4ÈCÊ`µ1ê,¦–€ð}Òn¥¿…p:õ9f7WOòA û=_$îô"¼àVðª°Î¼ê㈣{—k»½R(J¼7CéìNuWˆ’ཌª¬O¢jÓäzPÆD @îU+Ñr݇‰(ÝX‹%\o™¢—{ñ¢‚´XHåeYLÌ ï‘Ai*GäW\I g¸ŒÇ—ÐÑëÚ=n:äh².RÎn"¾åÊYÌøwiê59ò~å„·‰ž ´ ÁIPRðìùZ \qXùŽÝÞoZV»WD®Þ9æÚãåRNJÐ=2„,܈ä4j$@.X qÁšG¬_© Á¶Þi¬-Y6mÆÎW  p²A,ú#õ:”ÃÕvx…\1Ÿ2jò¹RÆzMÅãîÛ¢Ðÿ}dÍdŠýEc×¹[øÊ8koE'#]HV¾ˆÄ£h…Þeð%x÷qÊyÔeáʼ.2"}å#ÊuøJZ1ÒašðN*[œ»åe§õ»2K?+©ÇbÛ‰¥ ³kæ™2Ó)7{÷ò›·Õ«$¼ ãh¤&{• ý½Î¬ç üP”£¾lÌçôòán»š¼*>Q[ˆM¬Q}²#ÕdwiÑŽX‚øð¢á+‘ÇY"âš’/ïÉ;íí§b+U¹&Rr)ž*îçÁ€¢Eqv*‚øNÙ | ¾²&ëYí½)2¼=ú!2݈,Ãj§«¾“Šn’ÚŠ!Þc¸ eW¤½ÌìðôpwÉFD¬íÊ5´ðeã¶óV`†®öEDNú# %–HŪ=DT»ÿºþ»#!8?\““çžWÊrÓµâYù¬VŽçCóDÏsZ1À Zà8ÂCÑœ×Õ{ÁþÕ[Ö$gØIΧ Ÿð=öEY‚­Â @®¡Aø-{D^•o‚¬¬©ÉûÁ<âÛ 1ý¶‚š¨Hð_0ë€^M= îQ»!äŸËÞÆtc¸ŸÚKÁ×Üß ø…4pî ?kº‰«&kM0¤áÞÖ¢àpìÈv‹•ÁͱKƒéÅg„Pvk pU [¥‹üН¶&Æ€öÐß±ýÕ/χ‹+VÜ¡Z¡£àíW‡€ïáØÀ{Ⱥîãáµ $ª×@d¬å3_’A¼$Ú€§ÚÓÀ)Z ^ox“Ý7A¦iKʃ™må)Z DÂvà¬ñœÈ­ ú¦øÞ9v?rÁX7™NéCÄk&&ïÉE ´ñF‚ò #Aù0Žò•:)kGÖ¡ë­}÷‚|Ãë ^Ýð× µÕ>sF\D.Y-  ïJ.8ͳ,PgGƒoƒ÷øžRŠ‚¯-Á´(EÈxA¾Äãº÷3÷]ÄîYñ _Ûã ›oº¥ð©­ ¿ïAiï­­ªtpµZnáµ÷óDç Xë#[¡t“g7€’xü_;g0I‰@A6ß°€N´ ºÝFô¹âŽûÔ¿3ÿ³e@óŽóà"•°†|`Å€qHÀá?ç@ÕþåøçR"€'>$SA€ÀÿÚÛ,àv_ü£^™¤ýßá b[Ñgx ä@z[¨ ”B•@C1€¾Àm(þOOŽ–Ó¹£Ñߘ‡²¹ % pH4bHúKý!€øšü×¥³™ÏH$JP@Ñ;Jïû§£¸Õvûä>9À] gˆôgX@øŽçü;É&XÀn …6Àóx ?F.ˆ’DwzˆŽAýo´Âíy»NýøâŽúý+ùç^æŽ3Qù߃ÿµp€c¸ãx@žà"p{N‰êÙuàö(0D%ª·ùôÑÕ£¾Õª”¿ã_Ïð%[þ€ÂÀí^Pî¸×»ãüÿTþÑ_èŒg60÷o4ïw¯1aóõºû <ަ|*¾/àmöæ‚ZKiú[ÊP"=ók¡‰7Å1^\»”7’e hµx›d2¸ïȰJ8 !°Ù8¡!NEðïÐBä¨l¦®ög¬ àºù ϧô@·Sé‡tVËÝõ°²†Bs¼ò.¦UM~Ê“ZåUÝ”5¼êVf*ª6žT¹_[€ä”»á%È™àý¢VÀ’¿«`Ò^:àžW/‚\Ç@ðb•x\É(îƒÊ%®1Q™Ë@éýíi¢¬â”ÀvŸ·&2Âr6õ OÌò d7@yšÀól(¥õà 6±ج4:Û €…²°)@-öƒ°´K@YïE/ Zx ^Kfµ˜ \–?Ä2-˜ ²“ܤ‰K@5Zq8À×hHÑ ¼“Ç€ªJ_ ¦7ävñ:ðž÷2ðº~p¿ý!ˆÞóLà´øQ¤ÌðHÕÞöβÐ5å׳|EÅf0>rÊ€ûƒ|ÔLñ“Hõ5«x)êP·z=€­ÞylñC¤ºHÔ_d‚8®½K*ƒè$'f’¬Ï‘“ž×ô‡)Je¥ñfºr ? oÍXWÒ±€}ÀnÎ:×€›à‡…ŠI¾c±œ¤(&£©Ipë8ŒB) ©N‚L)<ŠàÞúÓ H¡4PÀq¥â3‘Äq Õyd[ùˆEí?KÙŠ@ñÀwôâÉj0xŽvÀx:ËY´¤(D*°‡S@j#9Î<’‰C¡—lb°“@5"À) nÏ¥.§•Ÿ€=œöRÄ!z’„$\+8€E, b8ƒظ@< ƒ„?gE‰‹K˜Ó\G¡6E¨Èv’ñ(ŽD¡,‚[ßXþ Œd,W|‡à,›(‚ÉBüc‚ˆn¿úP€ Œ¿ãÌó?w·¿ [x¸m?zÇÕ|¢ÛŽFçÝè;æçñx@ ¤¢µ@>8H’~ré ¨œbÙ@4·í þy”IÜþ&ùo€'6 £SØr@l§àcPŠÔ¨ý#JŽ< øDMà%Ò€Þ4jÒ<ˆ[6~ÔjVþr‰nÛ‘à²PY,b4ƒRp€öOk‚ÿ-‰jM.pÛ’ ÜQ¾hÿÿ«o}´æ*.à¢ø8*—ÛåD`3AþȶwÄeõ[CÄx@â—8 ”¢°@n‚«)—–Âég¯r¯r$—-²’Ú'm¸Qq_‚ÿÃØžÀÛ¼Œ¾EøŸZiQÛ&j7ÿ8”ÿe,y¼Ç$ây‘Ûý•¨ÆDÇÒVà7úp;½âÛÀíþ3þÅ“ï¼=FÊáÿ§{£«<“¿*ÑvŽÚùîo‹Î=Ÿ æ  Æÿ¼ÓÂÿ»"ïxkTS¢ãu«X Lb0€ü@Ì`/€ÜÀ| 'ð €Ìk9 j ÊØó.ÐÍ+9¯Cž?¿*¤¾™rSüÿf­žp>¿ˆ(ÎÓëˆÆÀí‘ À8à¶vDÛâw¸µ§\tôãà5Ùd7Ñd-¹d€S ”R+@)|àÍòR€|✒¼B'¯0€èº$€ÄÿÔ“¯bñ9ob2èoÕÿNÝ»ÀÓ¼ Ü^ñxwôöÿw寬7ïÔÿ›wœO¼ãüÿrEK4°±x•§Îr&Јš€'ÚÞQÆh¿—n¿T€[Tt¦5ï8úîø}»Æà !°8ò%÷W¨„å~à,)ÀV^²åG€_$aQ(dz@Ÿ!٨ɳÀ)/ò€Ò|\‹}r0B¤?"A>Ã_3‘ÛØ^´^O!ˆÚž·ktgïý×ÈØGþ"ýÆI$§eYlz ýϹ}†Œ€,î-QV=Ôbà"䊂”ÞO #Å!Àº…ó&É@À{Ø® .¯¨@„ðC€aÌáöW^üÍñçár{ÌžCæz§€JK WˆàFCà»…ùÞ¶÷£%® ÀI €©À4Ñr …¢@Ù[ÕH$¥Ap‰¢À *9”¹S”VQ8C#*ÉgCoPÖ„>¦Š2H«%ºX— ÇÐÉz®ð]š8SÝëT|Y%:Ž,|’¶ïÞÅѦ‘KÜW¸¡ ¡x4f”ö1™˜˜ÇÃI#ÒgR4v]r ðÍOŸ|G{YÀ9Lµøéì@È¾Ö›ä¡ ƒŸÅ6µ39&:R•®b8 ¢•xLÚSJ4¦-å¨#Ê¢S DJPA„x,tèÂ8Ñvôx °äÀ¼ƒìA‡±ÜÀ½"š-jÈVBeÐpIF'‚ÄÀÔ[ÿÍ!\ÇΡ'pëÔš1xD| 4bˆ<'ONrHγŽÛ†ÄfY ø ä(ù3ž<ïMD¡³šÁ&å†Ò›Ctg?CQ©‹#ƒòm4©xã@ì“çAìR[ã0\œ$Œ ä¡âRÀTŠP H&·Ú%jôÿ@‡’L@à§)f¼Kàà´[ß•(u¿sGO¼Àå;Ú1 "FÍ:wô\ìmšpG¯DsîÏàà6$=þ+xäß‹ƒ÷gÙßâБ@]Þ<º ‰@ îÐ俤üCr¸ÄQ’¿G\ˆj`܈:!‹·¿æñw´“~ÇQ½ãxçRõ_A…êÏùWeðþé¼¼Õ–ÿømßñqÇ}QûFãÎ÷ÿ ¹M,¸³4ÜÑR±ÿ¶Var @[ùÆ#À|±°h˜ÿÂÙ}ùÖв0)¨(€¸¥ÅÑžªvGéÿ3ˆì"ÿ >þÇ+Ñsy€äá*`“ .îÄßJw%dl£É®VËòåRíx‹Sæß*ŬLØÃ³qqÔ%òDü‚¢p,ðfò~nª­Íçñs€/ØMMž‘¢‡Y T§ °‡ó4@c.­ø‰Tòå6Þ#"_“‰Ü@yÙ/w`‰—E],ÆÊ,Jˆ:X¢uˆ&ƒZ ¸?&Åñ`a‹‰?éäB€b$qC(ä‘\¤5pdpät,`•€soQäF\`?~`¹˜4¡#p@ô®Pä<’€áTùýðX+jàÐJ®Ä¯p—L¶ã±“ŸÐåX™leHÉe]Ä1l¡ˆ‡èˆ®¬¡>—”$ü¤7~š¡ ì»e­ à<®<‡‚J67X@rÎ/g7°8ã•ÓÅ(~¹üÙg±N=rîK’μ±ŸÝ§NžŸ@³Ð ïfÄ6ðõePj뤇(šðzl.’2ã§R<¦Ž¯/Nàgßeð¯6šƒ^O-‰n‘­ø"°è¸áÛïÿ„ññ/ð½vÔ<Æqß'ñ]yP±ÅbV)ŸªÓŽYŽ#zûØ=tÔ^ñ5 h¿‘ÿ%®m„ß­E=±XFxŒu¢ŽÛÆ~‡´péüõHû’Õ€’¡†OP?t¨ð_翘Û‘×¼`>;3¿ÉÚÀՌ٣òšZwÉÅ×Ng$Š¥þf±!1.n<é±½T› q;ýÅy徆½ŸáÒ­« ÿÛCï2Ø™ ÞÊ‚O,úS“ ÑWŒän‘FQÖq/!6ò4eäZŠÄ ž$D@6§”èÂ`ÊQ…mh´ær¹‹8ÂÔà)ŽQ™9ÇãM6â’"w`2Ÿkžå,r S&aü†dà3ÝE%à3š?S Äλ°A8㸗b ï¢ÈÙTEÉá±0ÙŽƒÃÊ£È5\%‰ßqqXÍ7h|!öcÊ]t"×ù ›!bñbr?&½IÑŸÅ@€À@‹¤½”»E*É5÷ð;ˆmüÜvQ[aÀ­«QRÎeµ.ðKx@Ö$ŒÜ.7²å†ëG/­àò•—Šsðø¥S]ø!ëk/jpŠý ¢¨Ãñb§äq1í©¤ÜLø$î{y1nzìL~Mºžô %bêÇJÃØ5Im°ýi1ùˆ˜ÉÐÔ®z ~í¹mE×!Ö1 ÿC¢öÐ ·Ò Fí¡UÀmVÔJ‹~û¢6Ü·¾Bm3pÛ­sP^Nò®Òž›r²Ͻr7UÄxy„·éÍÓ¢"Uô¨e÷wÜx ö<ô“‰°‡0 À‘o‘À . ó=€_X ì¥$ÈM„qXÂf`-—Ѹ@{?“¼Ïr ›æÀ.€\Â5n;ý ÐD/^á¶%ÐKtZRãÖÉ/r*Ú‹¶˜œ“Û@<(ž|¸ wɯ@tÏe©€‡‹@a_pFî’3ø”¾gR¢‰‡ärMä41SáKùÏ ËŽJ9ñ¾¾™‰b/’¦H `‘˜Äe[ÈèjeÈN͸Wúžö´ðiˆY÷1ºÆÅ@ 0~$øçÄ΂@z’¾æñ_6Û §”¢@çxÊܲѢ”‚Ãÿ/œnSÖNȨûÿ-­€Û·(p{ €D€|rAžÀXäp€Òþ È%„QÕÜvþDÇiÆŸt‡Faݨƒ) 3Vn¯"¢½]FI˜ÑíØû]“E×…Á;ÆE0ŽZ„Éx :!@N%‹¢;e(ÅZ9Ô{’ Hp¥£!‹Sx”éâÅz,uÕ1o4þšœågy”9¬}(NMq/W‰g¡4ãrð¹òЂIÀ iß‘‚CQjyœB£2¯/‰Š€KM¼ó jˆÎÀk¢ÈR^k¿+¿ŸÊú@2P‚v GÊj ^W€ê¢HÅ[< >ºÒÈeˆ†t,ÎUIN°è ¶€|CæÅA¼,²…ý@,-€érÈ7dw$IDˆY¢ó¨ ç*ËxÊ’¿R‡LodŽHâ~F2A{Œq,Uö`ˆ&äq€0>|xd1‹î<ŽrÒÆ,$8Bw1Žx\ås’PÅ6ž‘J*ÐØø)ò à!…KøÎ5J2™\òñ‘Fv ï‘Ü^-«x Ÿ"¸Ž¬"€der?Ëq„ÎM®³¾8bÉÌ@#À+€"6Èh µ(açXŽñ>!ûÈÖ“ (T¡‚xä­:Eä¯\¶‘ ì&øÄB¶`ymÉÄ%‰!—PÍ+OCÆË÷°ø‰+˜òyõÞCÕ7éÈ“L¥®œCE¤œçj8ÂuÖs™ò¢ûÄ·b­xG¯O Ñ?«ù¿vtºð'ù)B"ø™£ jS˜à}Ò¸4›njÖC ]N)ÇwìIëÈMšIŒaaˆ¡Ë(pÐ@,' TÀâIÚ]½¯€Lê²(ÁU à—ç€[ 3Q@F§:õž¨ÜZÖÊs€G,ÄCr]”EpЧ¸ÊÙMÊ!Rå1ÉNr\$d€˜ Þ  ‡I @丄œ‡OLAæL½ø3"F‰«Á¹øw+¯cŒùJ˜Ï¦ÀãØ2/ÐÄ"ú ˜‰I#ù S€kòn ×€‰L1MLzˆUX4f :I·ØaQïì?"1þ£1& øþ{ü¿+QðNžÇG</V`"„ÎI!XއWø?7ÙK K Rî—õä'”!‘$Ñ”Òø¹Áz.Q’wEO¹I”¤—äM$‚üøX"ýDs¬ã.P …“x¢¾x„ò$r)OãÃ])E£ÒIÆÏó¢*Å9È3ç Çñ±Ÿ*”f*§H“ßpÝi‚_SˆÅAŠÁ€ëy€T s‘˜ø·8ØÑ%bt©Š2sªp•” 4’*;kQ ¯_n ¼èTƒØN%>²}€,^v1 ähJ yÎû„ãõ¦€šŒ¢ ù²?±<†EDÜ )±bèA‚XÂô¤yt „NY@ 2š ›à'ЉpT·ñ嚸·úþ#T[pÇ™Â;î¹ÍÒÉ: 8X”Ä$“XÔä&!2Þ\B îc/`“T#(E¨(×ÑEu.©\RY¥<@IŠ’G6>ò°ØÁY JS€¨ ¬ Æ-ÀìïÏ ’4® È 879ã~Ãeù°=4™éÝ‹F*‹ð‰êu¤ÈÖªƒ¢üÄ‹xàrBø¬«ÿø†ÿZ<@¢Ùw´»@68Š‚Åuyä-“7êêt© Ä‘†Äw+öQ»E0€ÿšù,þÂïÿ-ùg0ý5P¸I™$ôT §3ééV"xﺄGg¦ÂõûÞFžy÷·ÓP8=?Y®[Í¡TJƒoq½ÊFjE)HÑEk‡Juc4.¨u±øƒx#“nkò ÜèòSù75ÀApƒ$Yä!poQÎÁ[\«®­ÂmGœK$ ”D (·8ûHDp›á—ôg˹nM¢°@ôwÔE—þŸÞý»`r?ÈÜ3ö n|W¸bÖ™áÅO ¼§Šbú›ks°oy=n@Â:ÞMI¾Êç¾E’™e®Kä¨ñLJWªè>æ%èŸÎfªú^¢ƒLIEêø6ޏhjù¿jûèõ¨s' îÖð0 "…€… Üø³ýÄ-Ž£‰FeƒÀEјÇGÀ½ä.qüggß?zð<σÔå àQÊ%Dˆò”Þ¹£þÏîBûÏ_HN‹AEyŽÞd¾ã‘Ðýb7<ͧޢÂgI±µÌÒÈð7*! ÷]úrv_nY'®Í†k‚1pþíó»àHSùp¸Ñµëp±€o›ù”Qá[(ó\ÉDð]Qñ²s ¼ëÖ6ÐJP‚«²6€Ük¿æSÊ;èg¦‚?Ù7̈oÄ|;´¯•n sÜ\0êè¯Y+¦ˆC^uˆ|QØÜû+Ð÷TðM¼ ¹E®·ûiGÆ©ÍÁÉf8„>µgC¨{è(0 …ÞõŠãæ8éôËÙl(¿Ï;)í.Î?¾îU,XÞ­62¾ÉT¬Œ»,êê«Ýìõír§c$¤ªAdüãê8ĈÂéÏCƒü¶gÈ|F0“8yÜvoQ˜·=À-nc2-¤ Ód]à‡›Gy d ù8П,Àë,ê߆uåbà‰Í@D|b׿)©GtµŽÌq›ùÁ9Œ®{O¯©>àGjq›9{¤|KS?Ÿv•™Ü ÇIšÊ€'åWÌ !y4‘“½OÙÃ/^7¾b:>ÙÁ-ÃÇBÑÖ²N6‰|B"k¼C蜥‰È_ä§h2à–Ä‘ÛBm1¼G %؃EÁ^Ö7-°çÁ"¹[ eæ\È=~³:ä4´r!ccfdÜum\ÙŸ5ÎU»ü œZšy?d—H~6ùTYå#(Z!é4ˆ+ᦠ|Öà;#ÿ0ª@òÅĢ”ðÄMŽqãÛ‚œ ‹æ3…ˆ¾ßè‹j6Š}Uåë ê÷z[Pw3@Te(oÈΠ6Y ´R?²É¯ÝÜ›…‡AöË@ÖUžwkä°ËŸ§”3×z=Ô7²8ôF¤šÛÂ}òï휱 Ò’§Aüš”u?!¹ÄtIƒïɉ¸Âs ´¡|@ À\¹X-¾þÖê7*Ø®pM¤¬J,¦²¡ÌM1ÅfKÅs ñðØÜÍ@ ™4øÓ&ù¿gCl‚ôË{€¬~’ãpåKüŠËù†·š¯@®SâŒo…¸Ö!˜ÉaB²ùÄðqr§xÏÙÏ# ¿ÉmÆ×rLV-Ì‚™ óûµ §ZÖ|Èû®ð\ùþÂÓ) …¿å ÙE®œ÷Ëp3Ð.ŠR`.TƒYKi³øu³4d`!ĤÄT…Àpÿ0Ÿô¿J$p4nš©Ä¶DÑû.¯eüÐöû&‚¶(P´óþGAiøÔ5þAùÆâ‚(  ¬1ÂûxÄ\1xH/ìÖ>î–c€ 7 ø òp‚M@7eP×m2-Òä»î4pâ .€½,ÔË^Ÿw/Fd~ágçU·)ØkBéé, òuæ´Õ\ª:8ä<\“¿Yù‘xä(‘ ö’ÂNàĆƒ2ÛW ŒþY¨’ð<ÁØá)‚€ùFÂ|Ó*q'‰Ê™´7½nœ-ò©8ÆAõduÎ_P)Ê  Ì0@epÛ>ú«Úµ¼',sûÊïià-“³‹^b#†R8-¾f §AšøMl#YÌçQêa£b dp…€K>P–nÜvwe°(Mà$?>ŠüÀu.Åhœåp“ €|D©ÇàÄÉL ÀÁbIò8‚Kiš¡"QøžëÌ‘£ÉLAå%Öà“8&9˜lïÈ'Û+†s]©DºüU¯Œd>²3%¾âc`¸oâÈUÙiƒ'r‚ ë‡?ÅòJÝCP›‰OôŒ1I§+íl%—L¢ùZŠp¿ ËÊà¶ð΂¼Otñ@Ü`ˆ]â óxx^ü¢ ‰Òøò9 äãqûKE›í[ñ`Pð£±Ñx bÿ­È­K¸øñF½…N‚ƒMa®"QoYàÑUB”bC°ŸPåÏ«:a ‡|`3Ù@®¼ä,&?É—A¶à8ОÑàM’߀—¯¨He¦HF¨¿‘K¡P0•›èò^^Ѐñ´¢;ÃS°èP8“ûüßЗ‚ØE¼N,ïSÆC’Ä"”·€[ñvÿYþµ`mù)b³5çžH;ªP;Áþ½o›Šsâ ±>§ú/‘WVž®ÆÚ«V°›b“S¢sÚ Ú¦ÿÔÐû%qjÂaï€1¢D§1#‹^ ¬¼IĦ^ PŠLÕcòjiîõ=ÉZ9žzôãs‚lã4±GqÀ¥.ˆ)Tž' ÄÃøAîCúp8K&È÷ù8Ìà B 7Søœ.¬óÄ+<à~Á{£[”FùºŽ›7Å; ×—)6ç¯Î׎RþÊNí){à•E|áÉŒÇX‘©ä~Hü•]7šÃùå×;Aö¤+_‚Ù#'Jè{‘›¥óK}Ï墫*䊤îé_[óÕ³.J_í]↨Zél )–ýFûéþ÷9K!ó)A ô[ü—k€JQàgï0Í}›§dQ®1WÉá'>p–Ò"…¤RŒªrnyUÿß”¿ ÂÞ /-ç8®<Îv\y0B.¥,º·’fŒ‘AâùZí"/¨/™<-Ρ~L\\¯xωÝLöÞÁ ó¾€Ãƒµ òÇ?ò”Z@üΗ4½|ÏÕñnŽwÞF)\#ó 4Ïúœ/ÔXˆ]Xz.˜91WAô—õÚ$sd×Éß öêÌw!’š{B_\û *e4‚uOãæ¿˜ý2«ÈÍ·Ñò/ÛÓ!%¥ä9(½¥Ø‡ØiKŠ_@/²¨VMæÕ«$²„FåGÈä%ý’؇Ã|šˆÓ<†GøÓ]Z…å¯,>™åM1E|œG@Ì—ñè!ªbSž-˜D]E.&ÿÌÅÿ¿‘šëß§CøïŠ´—‹©¸¡ÃŒG wù¼b¥‰5Þ§¡±LdYÑoD¥M›§ ¡¹Gÿìg'>§vÆ“`îáy0û9&Ï»õøØ<(¿b‚nF³Tßeíç¤ÿŠh@ý؇â6PÑÿ…‘& n1ß{£µv¡îå`Ü÷v5Ñ0¡¬;Š> õÝ$ìøtú£ÇÅy!ðYrøâE]ð?«4ßYãiˆ½Kº Ü¥ç‚Q¨vc•AHÍc Wß(Æíˆ&ÿÿ¡rÇ­TZ¸cÀž+?wŸHei$ Bß:GÀ}³ öã;P&ùAàí}P_QH+à/Ë~œÒ"DIù1¸³"»!t¿»ìòîކ î¥@Á÷^.öÍE"=ïcíËÿY•,á/®-2f÷µ&j™ÈÖÌMtÊoœÛ‚ÈÍÎyéYùŸÂfÙ/Âå¬ÂD8ó"7áÌ4€+OèÁ@KH¼Q®${Ŧ@ÊwÉï‚O‘σ¾T$€¨9æZmh‰45E–‡˜HÌzp’ ¦žäú{Ú¯i“«cðKìaàp¿kHá~ •—^3÷1ðÆ‹ñ âµ00SɹYü–Z˜ ⺿ìêr¸([Á9)Ö‚õ«—‘{9‰-ÚÆ”E=/·3Å{@Ïá´<èßIIg¦ZÇí$˜sy;îžXWñ'Žó=/õ§º«9oš èã î#Mo#3@›j w_y¢”¿Ú¬ÇßPÿ›h2ÞiŒ³ë{!„W»ïARe· ýâºÊÓrcÌie–|5æ€2Šs®’HÝU÷PœfZØêwÜ 2CÔ¡ÝrÀEIjÑ£h„c9~JiàÌb8ù¼ïÜt .–XY𒨂Z®|Ù›´Mपâä5S¢Y¶8ÀïÁ⢨ ÉÏ8¬`&CdÍPžœ,òýˆá4œ—ib‡Øæíg¢$Ú`1‰×1ô Ì\ ðÉÊ*âõ»xT®,h W0,|r¤l¥”—³Ä|ÞõVh¼äuuGƒÛÙ® n^ÁNfzåÔZ¤Ù—í'8é}}2ïº7¼-ìp+ŠYTr|¡¹‘fá\lkOx3z°d0„~!rQЧð7Íz‚$gOÎý$¸9êFt÷q>D‹t פ„ÕÕÉ/V;Gدu€pk;-4ªð74½KÌཀྵUíYÙHlgs0Z`nâÄ%ø¾Äˆsôéé]lõcǦ¾îUTî­ñ :™uï¥2÷‰]ýe~ñ¯Ð 4 p‡bü„†&çpd/øÊ] òf‚x”™ ò‰Ú`án P©/F R ?ˆNE±ƒtàI ¯RÈ‘Of+Mñq˜Ÿ€ð@¾&»€ÌS1XÍãvÄ󯄰Äü j9øµ–p…n2…/#žìÏÓaq82Ù ´ëeõ\ô Ÿ˜‹¨zòq#Ùéx:¢dfW»ÜJɼù¹}œ²Yó àåŒe ä}~ò“ÃÇÀãm€‚â7ÁJ ^u¾ês•o(ûXÞL{x#GÀmx4’z}w>×êôuƒï^jï] 0‹³àGß(ݺï˜'ô2` 0Ê‚ñ > Œ1Æw ß¥¿ZX 4G¨ -÷} b©,ÊE ôýALñÕ‘kTÞOâx3ìž*†ît«€½ÒÙV|$ ,ÓÚKÄ¥·Ås‡©u±œ>Æ›Ä;S¬d«IÉ)d{ï¸%Éýüo •÷ŒäÊ-v%r¼ìÐiBb¦÷¹jjrc/¹"Hà—{¸€Ïi™÷-ù–H/û{ïB¢z/»÷ 2þÊjkõß +ïG^£Hl1Úû¶³Ü}/öósÇM|©X‘p;q´ü©HK.Víäô¦T™·Ì^2#í§¤÷ŽF¦xîVêÝ¿(îy°ð[ìòÂú¯^YS1ó%™œcH¡œJ¡D0˜Ž2Þ²)ŠÜìfü'@ÓA4Ç1€®DNTñ(5Qi&j5™ T P„\ Ñ$˜bÜv sxÄɬ6³¸‚ —ïëØ ò;ÖŸpä‹$ÏÈÏ@æ«“B±W´$ëJqæ+ˆpX>‹A éã÷H2¨ï*ÝCÔW9w¾˜þ ¤^ë‹;)ý`æJ†_,¥dì»ta_ʘ±Ûâšú>nb´TŒ„^Euo¯¯húœH¢([ü>Ï g¥yJæ•§D$u»ÚÃW‘ D˜BITF¢ %JDЃá@-'¼a^="²«ˆ`(õÅHà îâuR ¨#zux(MM Y JÐ (ÊMà&. þj³((@!:·"PÈf(pF^®3 ¸Èà›-r ÈÅ\ò=È1ò §ø)ßÔŠQ~âCL1ð¡y„Äã2®¼Àãvù´aß'†\Õ•Åt<»Ã¸›7ÎR8{®­æJîƒ[¸÷Ú°óű.5¸ö¦2Ø_‹©erÊ&Tº\ùºîó¾ßJ?ê4Š¦Ñ”ÏšÜ#f1X}çŸõü_;^c‘l“;…o6W6EÖÌMö/É.ví’úê…Á÷É:ªÒN”ý£1ë%GO‚×6ó2(9E†‚Pâ+ü²F™Åt+Êæ³ÔË.æú=¯ ÕL^æ|ž2'ñk§j\•ØõNИ´ãËÜ 8Ÿ¸Þ­ƒ/~²Û/¶›ÓÅì(öBÜ"çP>u‹‚ÖR}ÌêÐïñN€vC¨ƒhî+ú0pRJ€#Þ$RXZ)ÀÎQo²7o°¡yÝ ¯¨±‘ÙŽÞ!òc~†ñl¨Mxz,ÿx~ž22ï­Ü#JŸÌÕ¹E•¼KU­,1÷B/$ƒ¯9×W‘« [&'‚ï B¦÷V‹"ŠTÎ=ÌÙôÉÖL/ÞžÎÄ–¹Ìrû@É—ÅÏyj±‰™¯1©z÷›M)^¹að*—ûFfмüaý”,nfBòTßtHX÷3‘˜ô¤70Ìå _ÒUé­4âešr–¦ÄROžÀE*âžãw¤ó™—Œàº,‰TŽˆ?°ÄyRñqHÔQ@7»yÄÓ”N‰ñ Þ¢P—”?>ê=ôneH•@ãÏ«âVvZ‹ÛYT£<­ P™J@>Ù¯@ö”«@ú™d .¹›å˜rŸü¼‰¼Ì8b¦°°õ‹Ä/ʤ™è²7)è\ã^+AU†§Ó—@öx"¶š£ð˜U‘-y² ÀS×{Í%—ï6_¥Éé*I÷‹ÏϽR±˜¼ñÁ`v‹ úßIá0 XìJ˜GrÚc…Þ †¿8tEþž%½ê¢ëÕý•xëÄø˜…è{÷ǵÖ^îÿ1³õ•^!§~8N¼–(ü€´‚.¾ŒpG•H¦@5ÓZbø¤W¥ ¶YÂ,ߣ~«CAel¹Ó)‰'6Šõ ærH¢*ИV d#>9U~ j[߇w=ÓˆÅH÷-/˜«ªHw¸Í«+\ôHïup ÉoX¶â°ÃAw‚ŽÆA4ûÑ‚-œ¯ ò«øÂW/!³5‚xç!T[쀼Ÿ­Ú³)KÎ䘰ͻ±cótHè\p/mq¨ Jòº` %b‰“Fé?¸ä¼Zô®¤ÊvÂÑR;r–+5+—ÊÛÊÕúÛ¬"Lª´]í@¥R1,íU_'!'¡7ZìØdÛX¬œF§7GiÇóTâ3~D£¢\-w‚Ð#çP^öð>õI±D#té"BWPšŠ)ÀZr;g^&‡·\ñø¹Ï8ž``?¹“kÿw$ꋲEsÉåvôN·-£f>…ÜÜÌ Y‘Ïr|]nb5È[ÈÖ³EE ÕÄËè§q¹OBe'bÄ0˜Î³ˆ[gÿš4Z± ØÈv@ ï.4ð•ÈgÈ럈MˆÓ±¾ÍdœÿÙ·˜a×BúÙ/ó[už\n/óîóúº}½•b9żJÃøIîYqÒÿƒ]žÕ?<*1ç¼Gñ|•Ù[×Kí¬W(¯ð7çÀ¬$?ªÈ Þ!ÈkA¶á"PF€ìCØ“½NLQ†(;!âû¡ ]ýìLå„^õ!ï1>‚ +Ÿö`M–C 8K€ÂÁb-8)>\}›ø5X ¦r—k©l³Ç¨xìÃ”Ì wG|I ÿ~_(½ ^AëÐ!ì¼NÁå˜9ºB^ –AÞý9@v.@¶Jø$×UY)jà/õJbm/{µXQ÷áߦ~¨Y±\ÁrFT­y˜ö5{{ƒä²Kµ“üVd‘o€(X>æ<嫌G‹¢p ØAú¢fËn.’£NYnЀKìÉJ¿`‰³œQSì%ÄNª€8Jk ‰DPpPoqM1ÿ ’¿Ãíº3 FÞÚ/ÇÁ%Œ‹K ø–ë ë²d€ã ¯’ƒ%]Ò‘²ÍñI‹ºÙ’òã4¦‰'€ A¼ƒŸÛ™Ô¡ЊÍÜ`þ;r¸<‘I—ÏuëÆ›â3³^ì²¥i忤?îíÕ”ÆÎyåï7§“bˆ½ÖWØÊÞÈcì§µ5Ù1+Gˆ¤>‘r•Ù\J¹€›¤z;Qü–îGÄ7Vö‚ÏT>=_z Ñ 0æÉ®xȘæpú e[`3›@TÖGƒºH[ÊYäjb[üâ{{¸Wà-óA>È(à9¼êN5T;™Îàu 2À ƒl$&¸Í@>ç¥ã2Ó[€*•;A¾%2AyOùx]â7YÜÝã`W 8¹Þ:ˆ¬ô­§'„Z‘Áiî1dÆzÅEäÃÙsùU}3u.µóOaóéÏb“h{ä½8Uv %iuòÎRŒ‡o â*ͲÊ"7æ"%ñ sŸH‡ë¿q ®½$®ÀEÆ:ÈN4o€ZVO8-¼R~.øY¾'¢tW’9Yz7å”2uñìNé‰V£ØõeÑÊf°B$rL4/÷®½«d¹³„潩Ž!'þGùzÜQ…Ó1=(ÁtŸ¢öbŸo¼:†£³rŠ+Z@ÙC=¥†º*jQím¤ò;ÑEQy„xªã£ƒ“Dˆ}p9%7rC~ç<Ëfw£Wƒ*ÞYÅK²rU@ Cìr9%¬äH¼`@¸(y÷©.WsG©ã)–ÝIÉ÷._饖p«ú$—«ôm‘­×*ë£ì³™…z³ˆs~‡ZÿŒrŠ©Óóï$q [äL÷«Ãè},È0Ë‘Á·þEôdšo”B†ÙWN庤xŽt_PÔFÓ†Ñǯ,ö¬È*áêߨï‰Ú/‘³4Q[W¨«÷ŠŒeµMä#û6Ùs¹Ï\hwÂ5]»ªÞÓ Æ`÷mðÍv}à{V;J8°ÄÞ‚O{”þ Qã”×Ô7´‹ M`¨z9 *Êi bøÄ89 8Ï9`šr9óÆ¢x¥Õ¢à½äTÇ–ÕÁi®WÙÍíe Ðí¢öy”ð ÷!°·††à× ¡p’ ÊÓr ØM‘àvÒ¹] ÎjQ‚Ûµ_ÁŠÓAþb½vÁ<óôüÎf&g> Y=ã¾åÉœû7RâÆúØ)n¿pI­aþ&âÄÓYMôÌx„Ük ^ÿŠ$Èü›9Lïö”’ <&¾9¨ßÇí‚Ä*EÖCÂ&ÿ‡àÏÓ§xÆú|~í7V$æ³z"¨µ¼"8ê{ÞR¤šãýŽ®ý¢¼ÆhßËà(Y€±0.Fÿ@ È–áßAôòÊ‚x_jMuxyô™C?±Ê|Pï÷µÚ,šõ¨}öƒ\£ ¼ÐÁüÕØJÛØí˜‘‡q 3T"œÇqiŠÕnçgSWiL{„²” Vºû©ÖzöÓÀz®`Žÿ'\´@uøjÈ¡à‹÷Nö¿¬-À \f<¢Ñ·ƒF@‰uwßû7ôß–ÓYñÛÚEktrk'YI/ºvà±ÄÛ'Ê'®²AÂ|û Ä9±%ì›â˜4w2˜#즠æ Áp•PÆRxŠuà4ñXÇ•Ùîltk¢º ÖfPÎVs0{½Zú^Væ›ðˆ¨­ô@¨sÄ 4R2ñìôGXM˜Êç7Î3Ö8á6¤ŸxD™ÆU_q{ß:Ϲ¨ë>'ÓI~¤~À’øx„ÖúP®0Àk-†¦ƒl‚Ÿ¨LoJ8Ó©šùœxêÓøÈô´Ó¤©ÈY53N)Îçʫޚðên/XpM•§´¾Šã=îÔP»»Ýì:ù«(iw•™Hk°a`dñǬÖÞ|V„-ÛÁ'8Ó XÇ}*Ÿ pÂ{µºhöDß  §3O ‚uEEv•ä»N%ÍÒzÖ,á!H»;a"å"“@;âíÿ­cdhjèð Õ'€ï„ZÌQ©¿Àƒedqnêz‰8ÆX}ºVÆnÏm½ÉÕ*ÉÖZu¥‚­®a%Cä›9a\õJ Ô±è |mܬrò<ˆ%EÖI"Ä>ñpVsp«jKA¶óç°ü]_É9¯ºöޝ#±Œq_4z±ÉmãüÊ*û.ŽRLðÍðƒÎ4ë¦\ER¸5ëÐòß¼þ1îj;ÜÙûñäcÖHQ#õi¡´ÎßÄZ§‚W¼aI÷–=®Ô«7dW_Š‹bú«]ýógÀùIû'#WmÍy‘|­΅bõztH³’–EZiîøµñ‹°M·È½TQšÄפ3—x„&”äû[{èüGùQ¶nt¿„h‚˜«D7k}øWqTð瀚Ærn°óF –³ X™çlŽ"/ýE…/÷I+/ëcç'¼ ÷ù[Àå™EÞaö…Þ‰•xúÌ‚Ø+‘Oõò­½þüÕ°>#k¯7^;Q0.¦ª² ×ði¨ŸY‘Ï"5“’òWŸ jÓ¸V ~0 À),X nÙ§@âÛλ È]Ê[ ~QòÁ9Î…ðÄìñ ¬SŸÏ ϧtA20?r?¨;Ý—@‚S VrF€ÖÇ{´$fƒñ5hÛ‰€¾Àx@7´ÆÚ`ý;u%€ò(€2@©·v»sI\7 0œžö«Ä‚=•ûp9Â÷ä«ïΫ¾‘^†«J«˜ö˜êJ£9WÔ£ºGyõ©Øe4ÒÒgòžþj¢àam±|”4u¡·a,KxÓû”"M"‘©@ ;ŒNi,•σ\•õ>0À( ¢|¬ò9õA¤ÓÃŒç$yCQŠòKªÙ÷Úé´µ?§ó»÷¸½„¯ÁÙGËqjzÔ²™™Ö£nw§j|ÿôà7 3;ekêð²_TþŒ³}ÚzêÄþëúï pÿ¾ªðY¦½ñAÁ×j“ÄÇs‘_±_N\…ï”Ñ,ª8Ìx_.Kï¿„Ž)eŠ4$Ïÿcœ#ÞeãJ¯Òž$Ì[±¤>@¢‚ÅôÑ­é¾Cÿ£1›ÑXòhd–ÎnÇrÝDt„Ew |@D©~]€(­ËB»Å“_ÏV‚<Ì·/Ø(§£ÞÜÉa«m0‚¬-ÁjbÕ¥æ"Ž…'ûÅLàú‰ûÇRöìàØëØ•Cڮ̘̪êä«3®UOŽÉ\**«âÆ#³}hSH9¾E¹i5HL›ÎaN>!&„&ûö©z³›´*ÝŸŸ.Æ–9êÊ ¢žu?‹åÛ[)55‰(Y=`a=;=ùrÂ@”Ä÷c!¦P»bå­ùä;üûµhäŽö ß?ÜѶ wÜM\@Þ ¢óR”F\þ޾ø¯$:Ϲ„ ¡áÃï=¼= ·ðHήe·™Îþ \™›W ¯öŸö½IÒÕñ‹Xp¾QÒ#ô:33f½½ûL7-’9öÚ 1ìÜëöTž½8ˆä7Jè‹QØ3©#–Nú3ñy}†Úùì—^‡”דÜVŵÀ/Ú·Õæî%~ý’óÿ¹˜ÿÚ À=ê^Û«Vù·SK~ãàcèÀºS”–lË:oºs³Gû*x£âŸ-QVä3“ åñ/)¿)ë¬AŒþüç UsÎ⠔̳¸‘ ä~Jªö€;L6K8D3ç±4É'%ù‡ƒü9é ~¯BàBîa_H¹"ø/ú=Ù@«§$¹ó´wÕûÑ”Sêv‘F1‘wè)Ë{äd7AYè‘o©Ÿ:KÝ–¢¢s—û½r<’nÃÕ\C¹Ì}•`ÁÒÔ»óû’¡ŽÌ}ÔÜì!ÀYЕŌÅi/“ÀVã߆„âÅž˜ñu n£y’vû² é+c%hþ‚n`v Õ&œ°\éÂĘ®áœŽ¿º—EE~½ò‡w&µbAjaå´qp­E`¦È…cˆ*—¯NàÓʵ3G‘P¶cV<ãKŒÏ†]<ÕnˆZìn9%µx“]Iqz6_'|?Ì}Å\a¨¥ó@å^²‚L/ý‹&Ä=%Ë/p7=ÅTºµqÞ?4]ÀCÅÂá*&†¬D'pó.¼[Nb(„ÉBêRD#*>$ÈL\`7Ç€ó *@1å¨ jžÒ KÝ"¦cÞÚé¿t±Éæ_S„úË“´ ³×ÈZgwøøä3ê:ñùѦFs3«ˆNV#åoÎW,œÌ45Kž¿^ÕWM\nšx]Ï•.~xâx³ÒåOŒMß%÷žZŸ°/g²œ—P&qâõ‡h)j˜uøËâÇcÀÂÆïüúH.î”|‰wO.1‚ô‘’aoæ¾FEŠe¦]|ïÝÔxÅ7<ünÒïÚp»zÉÚüæVIÅul—1zíØó” ˆ@ .jßÚO“)Zy”W>·k¢+%Õu¢Y”Ke3tZC¡¨ÔDE!M”#Æ; /sP%D€+j:q²³œË¢$ª÷€˜A /ÀW”rßuPÜöòcÂNE%›x»ã•-0í8ÙÕ:Îpw‹5` õæ‰ì½ÐB÷‡CqŸó„H ¹ìÊ=yHYöÿ°öžÏZUO»î5f|ÒÊ‹œƒd$IÁ@V1€ "Ù"DPQTDQ$£€ä,’sΰòzÒŒã|ø½»ÎÙõÖÞõZuú/˜³æU=ºçÝãnˆ.³mˆîp¶Aá77Að{¹Ò&hS ´²È c„H}HÝÅéàŠâ®NÏtnóLæŠüu‰…›âïf¬KŽ*(“z>øó C{®jÅ+)W/tû7Þ«qµø úW®jÿˆ[qŠ?¥ô§þfÈjØÁ±Œ}fKË(¨c¹S¾Þ«¢›\<¬Íâ8PB”Dâ#Éü/çþ}8àå%ðçËÑ ¾Àžâ2Е/`/P èB5 +õA” hJY -ø_WZåý¨ÿÏ´áŽßÿwÅ·À.’üÆ> ˜ ³9 R€ïÉù)G?IÅc<åñå$’èÂÇ@}LLDŠ:4F‡C.™èüÉYNò=¿P[N ݃ì¸:."xÂQ—3ø|ªØçÜ—'#ïV©©”Ž]å$m«ìV¦¡ˆÿsþÿ9©{tÍMع=ë.œ’­Á1Jö…»§S.à}e®GK§ ežz^6“ýÕ Þrñ¨^ÖîL»Ì¦NuÞ6úÅ|ÂÎRîQV{&ÍŠîŸxþ 7„ª>éf-"¨;Ý• ¾É@P>ÃA{ZN~ðW€¨‡øb80Käl*ƒ¼"þ¿ ÝÀu”à Q-p—)3B;v_mø#Ô×!¹PÛ±CjX§Ôˆkêiˆ–PCñ[ê](|PùyãWý8¾ßY[ÄÙ¢±zK¿@¾Î!ûAÎ&æàÅÄ>àNì-  Ò£Ÿ~ñ3€[4˜ŠÑ \Â!ª EÔï ?W)ñR_mFh#~¶¢”BfÌOžâ|ÖÍ¢2­Ä˜Øvoy™©r¡uOù½Z…hÉìzeÞî%¦Vï[!·nŸüm,¬>;YRö/ÿ±ý¹PKýà·ìOKŒ&œýT™%ˆÔ þ1*”SE F°™LÄ–MHÿ_ñâ?>‰%H'IKÒPÑ=JoòCù"ð *PŽ zSTã2І Ð꿤»€¤à¿!” („›²ÀZ¢ÀR€"š€C8N9`q•µbyjs&s…UØl¤ƒs¤€¼Øìd£èÀãâ>'Ìxê]kÏýT¿ü.~ò™[#PòÚÔ«fN½ díã+`Ý¿åŸ\ŸÂ(Õ¼êNuoiWóš9ÓÄ8QÛÞΣƒU×xÔªŽÜ”lˆ¸igäÚ/ Ô´ßÂ3FÙGÚ|ëIe†]ÔEN=PÙ³À˜é´Åãi/Ëèë‡pÍLo–1Xyôl÷WL}­ævÕ{ˆ„ZÆ{Œ˜2 [ék\BW¾ç¦øAöŦ$#8¯&¨—Àó/:ߣúg”Úè~®ú< 7ø€IDAT’ÈFsŸ÷#ê.ÒN¢;Ê»èÎVe!÷®5âÕíOЬaÖ`M°Þ«½Ói_–õñ½?d;Tçm øse*$ÞR>k•þ $¿ÒžƒØDý"DŸ\‡¢wCí xQÊiÜX(õ´èŒkÔ‰ÖMÏaQñ»é{üQ"{œ>Þ‹jµÂ±ÊyNåîPKó]n9íAÖ䦊pî¼,j¢çv7kCQ£ t„د¡A}"{=¸Ï…V@lx⃒+áªun{‹ÞD5ž*œB½²¯j%Ù^jµ[™ÌòïÉVP1 œ.[ÜM¥:S*Ù?û-nÇN¥t5¢ûBY‘õñ±Zý’ý¢9bEö–DOî¤ÏL¬¡dúždÒ–[· ²Û®á7_ 0Å­wee0Fy›@íÊh åAÚL樹à=¡Î%å:XŸk¯A"Ól ‰šfSò !Ì¢Ÿ¬¼B“ì…9-"Üiù­Âe݇¢«ºÕ°Xï$jÐÆ<“ìkÞÔ?’MÊnïëãʶ}mZ202\ ‘Þ`xUÐÿnRô/È:3 ê“z¡Á„jî\çá`£&Ñàb uͧÉòk‹#nšÚSØ^-&›Ý’8¬vI–G˜}ì£TO둬KT)iO£dàU'!Ëz–uúnǤ†ö¨ó.ÕµˆU©ó6"ŒŽêzw hÏØ6h—“WÀM Ôó¿ÃRƸπRä.%©¾í«äË H’ê,ÿ)B¢«_‚Bå®|Uœà*®ÜÇ \ŠÄZÒÙÂt4¿§V Kîöÿ$èTS\2”ÃÆß„øLya­UÞ Íx3¼³Ÿ :ƒ}G)‡e¿ w`Ƴ©ÉËþ5ˆ>¢ýîiõ3ˆWâˆ]6¾†Dš™ ñkfUˆ­ —Ï õC~Z…_¼*mw’JJ”NñçC{5¬.zÄ(Þæ³Âêl/êü‰ºEŸ‘U𷺛¤=‡H +Pá`Ê,lR—{xgüI{iÑ:‚ü¢ß"UqBãZý÷–ŸkýÀ{E`Ïpofs^®kºŸëKQÏé¬|…iÕ£€¥Î .ÑÔî¨ì`§79ÙŒZf+÷{šEêê¿5J;Ã…k›ýPÌb·V`½ý;ÔñV/ÌŒÍÿÍ äŸ~6ÿúÚ¸²vÍf~R«å<Á³æ²ä«rf¨x~Z7ðæ‡¿·g¨¼mf¸SôÊH¯ŽÞF]îßQ Ekù­xB½&_P7†.²^ùØè#ÞWêjUDYõ¦š¯|£Ö ¼§ÖVö„ŸÒZ«õJ#1%ÜÏÿRüÅçâ¶GRe~ uw 4s—ÿ¤¾ã^@ŠûÜ2ˆÐU{×üi¢ûÃ¥ìjt÷þöŽ‚­öƒŒRn%ðâî0H:µø+9WºHÖцæâÇqØ!¾A—O+µù™oôæt1[©4ö*&ÈÑÞ](Ø©¯¥¶ Ä&ñ9$šo€Ø&n@2dÔ™¡ÍƒÄ ýgð'hÙë%´lÿ¤ã)'Üö‰G ÚïhÏP” :¿PÓª¥Ngqòmù%cg’Ãx:QŠ<¬dT<Ûùb©2Šþ²{@Ñ#öF°vAAe»9d~Qº ¤¬î„`%‘…\¥þŠ«þÊæÄd¨a`6Iã+™Mžñ¦óçõ¡ò@ƒüªðs*¦ÍÅ»»>rýz“´ý®ÏøÇë|ã±´vÿóR›ÇãùãÒå½.—ׯïªw+”„gÅ¥‚Äâ£Et^NûC™cÔe‰:Ü[E'qGî Å/¶^–}œëÑí@\] \7çƒ:/˜ þ(¯â/æÿu&Ȧêp¸cÁ¾?á€|Št ïëNájd9P¶S”ß©JÃ@ýGÌãmQÔâЮ Ô,yÄF? DC9Do¾Ñ¨Õéâw||º)q•éê1 ±Ç؆T^Ôá”ÈD5g|Á0µ‡òÛ¤¿ÉÇf,ò&1s®y˜zEÕT1žÐn³A{›fúnÿk–koq^vÔ¢‹X’x^úÊîÀ ÿGñq4ŸKb~p»ü‘«ÊÿM±]ͧ½è%?ñgûÇãOŠÐãORš‹Òä3n‡×‰MâX(_ÄX$»+‹ü¦þ|ÑPvsbLö×ñ?Qk¡ õs–þh¥,§¼’ŒæQç#å=ÚÙ¿+ùˆ¤îÎÃöž(è† Õ©%žÈ;Mègçe¥Ñ§fˆ×•‡J=óoòÎÔý™„ö×ïüE²8­êígcfÝâäŽìy©¯›‘!eç5‹+^(G½j½ N“U®sáo¤–=áþÉÇ%kˆFòtöÇz‡Ò÷#x7²24Ž?ƒ„ó‘y×üI¬Ô*OQBk•Y‰*ÊCF˜,‘-[ ˜É" Š8† +5P}œgÉ!$‹÷±™™EÌŸ rÙ¿ê_ä’¿¤h{íg“ùݪWä‚Äöä{l)îêQ¶ðM÷1±ìÎRó[¾¿M[…vcZÚ¬ëý2/\Ý•þ«sçò•ð„¢1·çâNÇB%²áVwyÈv±+™('Z’‡{a,°õö_¡Ž<ÿA¿ˆ<-eä”™èwÒË ^)•k¨¥æk¾(íÐYêú³(û/G_ > é¹?ðaZ¯»…<ùËí_¸>=ÿ(ç²²bo³¨Lj"DïRÛ’â•ȲsQ3k8÷AÚýÞÃX©Iq#õþ@"Ò;âBdfà ˜cÓN€Ù\V=|´¬H#Pß×û‚²6²„x„ýoy˜'GGð€òb8ÐkÀ*Ê›å³ /ø äã® ~"þßöSà6K¦=µømHzÎK4cu¡¸JrMë9_ø¨ö) ~6ï᯼*ÁdÞ™šö ÖÕÛéË \ú3s&Ýί,UÕýþöö¬ëÉ ûZ°Qî`PõÜ:©ÕXQT­ÜHj'¾Éø„š~‹´ç‘¢^Öǵ ²Iq‘|O~Ææø–¼ÏiéëÅÚýÏÕâx¯WvQ7PPâè§üÿ,,—¯z+è>ÿá>îú¾†ów<3ãyþÖª•XÂÇ¢[È]ÒN—¸ÊH £¯¸ßh$$»ÄŸ^5rÕSüÌŸþhw¹êF!ù-9¯èacŒþ5=µLÙ Õ>_Ti6T#¿GÑLPZÇ[€íÞzÌ= ÏÝ É Aà6?ƒ^´«ø .ïø‡Ü1Þ:»@2 Ñ ~ v ø UÊ #­è6ш»J£”e¤WÜ^a2Y)Gµ0ʽŸ>Í–( Yƒm!ìÉw ¸Êí )©Ï“e!4R³Èt÷-Ö›å!Ú·Éa„oF#¤¥¦û’v‘‹Z'›‡Î/ºÕN&ôâE•veF^JõJ/]ù ­‚um'Nùê7—`”ߺŸÊ^½ý1ÕKµ+Z*ß-¡Ê]N¯ÔÉ)ODË*›SÜ#oF^,^ Z„‡Æ+p#£±wo«ÉïÊÎÒGˆ’¥g›ƒ –?NA”º*B„'éÅPfiê0—èe€YŒä‰“ ÿ÷jù?4ÁgA¾Û¹?ǯÁµŠÅSØš¬ì—•åν^\F¼}ýg¿|ïRª7‘2wPŸ&Ï^ÑÄ…W3>ãf´JÚ ™áGÉÅÏGÔ‚œ9©3ɹé–r-\9Oä]jRŤóE·Æ¬<Ó·Z3î9—Væ¡èCwKGV^™ŸÜ«|wê0àœ´û#öÞ9ŽÐª±ÿù ùkqý“A›Ô%R ~mT‰øKe3«Ü]j ÎM¨ó¬Øî,¹ƒ›¢gê}”QoFfó¡Ùܸ"3ŒŠ<&¶˜™²3}Ô[Þm²•Üc4VLBñxƒ¶ê~1œ=b€2–<Þ–7i 6Ë.„ÍyÇ)Ïe bäȲŽ\*ᢨ,?çŽLZýɵ›)ã}îŸ/EIጜË+¼ëöe Ýa¼Êîzû7.:{Åw\q[ETwG8½xÁjൡƒÛZ«Èøä=ö½xö½b ª£è$GØÀ¾©Þñ3öH¼ào»’~’oùÓ!wÕÍBP7‚ôÍ?!2K4ƒt-0K9o ¡(XÞùÂPie,e‚9Î2î„K%gOJ4¾Éé^$ZåUÔ³Ô#—ëašCε¥z¹É÷£T?~écÜ*‰Ë#Ñ+Õ¼s/OT¬»Aã²'§¼@vaê¤âZŒ²ŸÑ%¬Ç Ô+Á½rt5W›.ž¬eFtÞ©Œ¼AçÊWÒ›SJé+|$¥È@PŸÿÛ÷þ?ÿÿeòo"8.k8ŽFoî£Wá»ÉÇä'çÎç­Ä<ß7¾–/¬qË1ìDWåwñÙÕBóJÁ´ôËò Ù,xôT œÒëNÿ´^¢ÔµúYùÔ:óÓý‘ÉN¯f"ŸTTP»ýÛ‡ÊyN÷=øt/U=Ò[¥ì…R¨EþÒ¿Þì¬A¤²àJèªý9¡v ô{Ýë$ô.îx‚ÆPç~vˆ Τª«üKÜkñR™âÔ@¨Y² Èm^YÐÊ»¿b+ãôfèZ®ó>Žó°lƒ¡´Fñ.`r (ÉC ¯ˆGÀ_¬<¤’WÛ÷©ò8øÃ•€­úà®T/+Õ…à­o¿‚Öœ¥Æ>°Ïè7Á©¢W÷ª~âUõxÅŸŽ¡:ßê-éR´ÍÎ KѦy¬ODÌjR´†ß­ææ!B‰75—Õ‰>,æ·DWÿ{~ˆvH|Ìþx5±;ÑVÙŽëïWDÆmµZìì}*Ä>ȹÚØØR=0Œwm"Ê’ᾉ'±ÒáDËe%ÕÄᡎef_|UÕócø½Ú×§Ò¬Rù‚ù·üËGèU˜Yô gÇeŽý³u–?‚¿&KsǼßJ'Ýld=BYã'ës2Ì•öÇhÆ1k5¾Ù&9ÍXëŒsÝ×\ëz¨Úbw%_é«T4¸ßQA{Ï›BEm§SˆZÁŠÐ/û5A4u/¶UNÞ_ Nqk‚ÚQ¹ Êt}6ÈAñ—@vQÇrŸ¬òIñøÄ÷Ê@,WTðSµà¢Ö¯Ò ­•÷ õ*øËõ$[œ[þË”±MyŸ<¿™z—ÜïŽ v‹Š8‰’‰[èùÕÜû!ZG»…Ÿ|Ó„,Ü OAM67Š V?Ð ’Ã…Üî ñnÁ?ÒJø+¼â¯Ò¡SöS2ÖÌh¿a¯á÷¢§ƒÓ)]x)ÐCÖ/~(°]\=‘R*ñÏôyxöS‘×À[¾ˆZ4ÄÉ"q œëzòÓce!ÖÁM¯©q¬µâMˆ¶ô†³«ÎΆÛSo½)çˆÅG7äbäAµ6ǃÍí4Ê—¯YÃýY†?™UΙƒ(ù˜i~ìe’™]½%2fÑŽmi+Ùä-‹ì]í®æbí´=[P/—¬¥½eL±W3T§Ž8¦­p»)é¹^+V¨qDì•·Ie¦¸«l”Ë (É)ns㿲URØ»íbhÞ§N=s¥ó½Äo_ô^×c–ÎÑÀúPM›Xdn'Ëš›Yü3é7Áø²ÜnH;_¦nx®W-ô½4i^Rø³u9éXêM7¬ueÊ ßÕõLjþü¿@¿‚Wœ·•sEçǯá²~£ ½ÿ¢ù»°œ¥Ze¹5L„Oí# O­Ⱥ@«˜Õ¡^‰wxÑü2抙jýͳ ÷+,ó­DKFGk!£Œõ¦QÚí0îwFã+ÜÞøz-ÛGýœÛØÚp;‡b="—pWë›,%KˆçÔâwã[û[²”rZ —ÔR‰vÔP?Nz´ÕC Hˆ:Nû”šœâ å®ü !òE=|±PžDá¦pŸ¦¤Rà?¬Ï¡•“|\ï#u›x-ô g¼¡É?hè¼TäC2EÍK=…'ýAâ[LÇH9GPx­°­Ñ)C1ü/¤ ±>¡8ÒÝîmª€aoÖîB¬A ö £+Ä ‚Ä;‰8óCw˜i éüUÜ"‘×Côåöï~Y±)K¥Iâ¦þ:cÇÅ!¾=à%x$ üÓ?ïíf}ÅÙ´/S'Bʧ‘¡Hõ”µ'£¦€>Y)‹0Z‰Ñ¸ê)'LQÀ!G¼jÖæx./èÍ´ÏùKë£Te£zÍy–\‘áM ¬±1eå©ëO vbªnð=P®ŠÀQF(KP 2IðOÐ<ÿº\C¦_)±eAägú^- Ü%n3>‘ƒ{ä÷îOÞ`qÛÛ-ÿ!ꤸïRÖÛ£4 Ím¦b8ä{(v`ÛïÑ“ sðí ²ŠÔÅB\íþDYT󨻬¬G Ü'‘ì$ªðUèSõGž(6™pèû–Oý þ-Êùßcúv¶W9T—m‰îÞeÚ¸åD(Róº€ÿPÁi—r".ámƒô½‘F`*ÉqR%ükõÀ¸ào‡@@ ‘~Ìw”Ú ½¤íÃÐgÎuahµœ¢kjëa™›í…tLÙa]æ'9;ù7Ϩy¾…œ“|œIþe,²õˆºBó/ƒuXƒœáíE:íïqÅC<ƒjæ«'Pôn”B“MýTðú0”µlVŠ_Á_ã| ö0u5è4×k%;ãZó2¸š=I*Oˆ§pì'ÅK„C$y\—:¯hß³~ÕF¡XeÍ=Tp'™wɰÊ¥ ~Ã\ÉçôžòJlþÿ®< Øöz±‰j‰é›*¯± žÇNºÆFÚ÷á&<#‰VÔ;ù(D·Šsý‚2P0ÛùB”?€µ>sFð˜â@ G3_6¥PŸkOäŠYQ½ÈIc¨²i´õëQ;PRh40và1Ò]ǯZ&å]ÓŸóuå^ç ¿­*Ï{µE_ÑÆ/vë§¼K<æ÷GÖWúcÉŽs¿ëC}Œìæ"håýàýÆ9Hú,–2D[QBó”FàµV–Sì-SB¤Ø;y=µf©Vä@Ñ–Þií}yˆÊÊGòŠ»A}[6d¨rÙÓýé"Û9à3ÂNiB=û>ù&޵…ì¶ï+Éq‡‹Þ²«3Õ¬-¶'>pfñ±³æ4̺‹ßøDåûSûXNùµ`Êèî°kiü$ŽÇ¿±;Šs‹’µ]Öüâ6Ú¡Ç ‡+é±Â‚7ô“Êô\z5sTþt-’5:Q• YGâÏP!µaâ3ôÔíÉõº’œµÒ=×;Ú$÷he ˆÛZwðJi·Áii<îoâ$Z„ž‚Ä2³~ñÜp:JÁ?¡~äæÍNMõ¾È32æZ©Q2µä—E Óú[Ãí§RÚûBu‚5ó±æédy­›øÄ~7hrÝkI¥¬wÚ<Žð¯!<¿¯lÏ4­®™ä~ãÓÀS<ä×Ìi€'·X¿¢È¢!BN LО™TÖwŸÿ$ø£É6ëÛ!y°h7xSÜ÷À_( ñÕwàï‚ÿ‰R œÆL…XÓÂ8xïQìΣ,´žïy:ƒ×›°Td‚¼-Ÿ{ mÁ H—  ÝÏU¾\~#ð}x=˜ûôV¾˜@=µé¸­Æ$~‹ñÓ1Qÿ]ÚòÍP£ÀM±Û¼©?LFà'jP-x^+I¶1G™ ÕöOË•ê~¿¤_C\Oxc!Lï°’¦­óe’ò»S†WUÁˤéíGê×ݲu7#E ï>ö©›åG´%ýPŸ”«@ ù‹ ‘B{Õ&ÜÀGàõSf€o+Ï‚ßWýüzb3ÈVÊ2¤÷—6á]Uîçg²¦³_}CY*»9÷*må›Ö05×W«)òV«ï‹~özñU“ã|™ÌÈ=„(ž?Ôfüþó><=ö>ðQ3ˆ­»zˆ„ò@,NÐh›ÿß›×s÷Ù«C ^ŠGÃU’Jq»ô/”^¹¿dLù¨à§”K}=¤—º]œÉŽza³ÊDàdåDg gŒ÷¦_êà ä È+Î;lïwfrÆLµ–QÛ|л‚ªþ*'RªY¤ŠMÞKà÷S¢$½.Ú9ò܉Ƴû”¶#ÙøD÷Ä_‘<ñrÑ@]æ®L) J~4Ò‡Xnyw4óŒ+7CdòÊÕOÈ#~½!Ë*ÃSpû5³&¹nãŒ2Sî)¡!Ò¯¤]„ð1åQþb/åØý`>Ÿ)YnMd°{‘…ÈzL¶¥(í÷è@d«î;”+ó•™Xf§Èq/e.Q¯Ç[šã#~þ â©,%'ÁOYMï®ciúè»ãeõ4+oŽ8’:>w'¥\ÉŸHvj^ÞaJ§\ˆ6"šö\²zjÈñ‘}ö5ˆ´ñ~Áµ¶çAàqðßãšW Œ)ôíJ‚ÖÉ b|”sòˆâA¾è~®º×{GíŽçÑN œnC:}tÃzIiHž57C|´1â?[!šÊ‚¢7ƒa¢…ãCç¹/ï÷Œnœ¼Þ¿ìp{@¹LÎ_ß_f¡ºàÙR×\ßê™yÔyZš‘µVfàògrn0É)kfæýԲƧÿÍ«þSá9øŒ2ÓMÝ©­ÄUn(÷Qڽߎî5¶é¯wY¹Öód("AT禱—›Å‡£›(ÝzÖì.s`zéÿNùÿYðåþŽ/¾2ãKJþõñÖV”2'§ ß«ë+öŸÏóÒFî kQ•ßäŸÜ4/h‡‰)ÅÞvªëóY…¯nRê£h7•ÁHïÁÄ6‘;™‡¹£¶VŸåFñw?ä²ßÞYGLeŒ£Ø_æÆ*Ø@œW ?¡œ9¿¸±\ø6Z?8=¹Ÿ ³”õ»Õ±‰/EFà¨ëÒo8?RCdº‡IW·êQ"Êr¥ºŸë|…Ü­·E‹T ”ÁWÊ‹‘øòAÆâŽKl"nŸð_¥€[úŸÜõêx™œ"‚Ëiw•±A^´—0ÁiˆóK"ü™2îÕ´ô(þ1åa‘‘\‘šMÒJ’ÆÚ´cN9±!eeüZz3slÞkå³µæ·vTúTÙxm^÷yïÒå­Xz~CÕBž9;¨¢êüréçÒ™yëolH9~·‘ó¢rðZШ‡>蕆¼ý%q£°kfSÓeä“ÉSW5ÄT/ëÿb‘tÙæî÷²s?UF»Sxìøû¸¤VÝ@@É͘‰¢ÝªLnð+ýqž3gˆ°\¯mrûÉ¿ÕÃr‘ì¡Éç|_¬P[ûùªÿºX¢½î«ôPºûíPÅ6ÿQ*éǼÒ»K:¿_´ƒ@Žß ˆÊÕ@Xœš1äõ]PûÙ}€qH¢ Ì­ú7¸ò+~_WOó§ö¢ZVö·+;äÇþTå½sÜñxÆÕÅ“´÷ ³ ç-+ÙŸkö7Êj;_Š¥4N®v¿çs«¬º®Ö8¯.¾µß—<¨¤¢%/‹£ˆDÈ ‚uŸbBüE%,8÷.ûÇçBúoÆÃ¶M‘íb5N¤Ð#†R“ï#+Ä>ú„G‹Ö|ÌÖ{Ê~æ$m˜ÿ™vCfZ/нêܸAÃ@^l? 7ï\5ãö%”P¥ëq”¬à¥Kx±4Ã*>wj';˘—ÊyTü'7i½Túœ¢zá%TÍŸª¾²sá§.-,ÉŒP(÷ „'F3(ox¥Å{é³Ä›¼”µU¹EûŒÁÚ*f 4#-ûíàKÈ”|ãUDæ3)=Á¨¤B°„Ñ"ï§çYò¢L‘*›ˆ?Ä߀Âß@mæó—WоŒ½þפÀíd¡nÆcå­NÜáò‹ñ¯¸ K_¶¿½ÚùŽ:9·üMŒˆwÕ5Î&뤿$òŠÏg¶faÑ•Ì=ìJ\ÉhæÞæ‰ÔzQ#õ#óPÞâ {®×¯9\}ýlËz%I99½n5™üHõÖNå ŸU4Üתþ–a†j­RÞÚwÿ¦pÏÂi¢k`ROwdç'@ö±D 0Î'߆àPk6¨íœ9 Ou¢øÚýö=XF®ã è]Ü]èú~§Bâ¶Eè¼½ \ö2A{ÞÚQ¿(¯>¨E^Ô§µù”ó9º¸!Wà(ËAœÁyZd•„†.uq ü±ä^>Õ²À¡¸à7Q¶€¯«ƒÁÞ«6ÄóÊ;Áۮ堺³•Ý`½¯V¡‘ ~5ý8µÀ-Ò?B:Uµ–fd»ÓÁx’ù±Hà9¾õ4ïá°6ÏÈ¿c›µ·½UVm¥™}N,aA²¯N×äóþ\vÆGziä&öS'ñˆ¼ˆKuÏ#’o+w!^–ÍÿD~bMÏ †@gû 2õ„±›h¨%/âDj…æ²ßèM”L£‰õ#¿² l߆Öããù‘óÆ®Âãæ1ãìí]êó%:_Ú,ê”ç—ó`Ù ç39^ùŸ‹ý\vä幕b…Žß¸taâº?;+hÛöó)Õˉæ­Àó±ñš¼k'"ÁZѳXêëö!ö¥ÌòcÌ®±2ø©DOõ}9Óï—çïpšx“Ü@ e(Y”ðöà/¿%ÜÅ$LiЉ(£¹!>gðýõê?XÅ—ý<ê[—Å´~ÖÑþöÛþñAT7O16ÙJ7)ô^ l%-¾7òŠ|'±%´Í©Ë«Á½É¡fo£tá¾Ô2êáœfãĦk“ËJÑâÌÝšuY|±yõž4ȉTY€_¸¢ô×(ù#˵€7߇§þ[òÿ‹ÿ'ð‹o_Ë¥ï:FÛRÖ™i-§8P!¹‹Hà¤U“ ©ÛÃðÍ}Ö2\3Ë:ˆ4+Ø·1Mé|Ë£…F‘ñõ•]öušê¼Aü¬O¶¦ÑÍxßkHuuµý-ž^ß«NB û²SýAæsJmê,ó³Å9ªÒJT“ŸÈJY‰Jª[Uà$ŸO. ¶‹®ÎTù²è§¤Ñ—ÅòœøJ–tnù§(¡&EU,QDo±¶_ô÷Sœl|ÿ–^^TåÕ"â¿*޳ß+xœVîLE󛨵ȷ³ c*ÊOŒ´+ê?rÔ>*䘻<ü ¼«Ê5,ËNéDÐ{KݱKfHÒ‡âÆ¿2M”Dj°"Jì«@ˆ lÀwï ½Œï˜ÅÂØ ÐýlÃÕ/ú%­NZowl€²ÙzÃ?‘äËÒ aT·O°$žë®¢gtoàÿbOD$ÞÕ‡ E¯»¥!VÃ{œ€Þ¬líuÈß—8Ñ)îJàLp>Øë”8ˆkæ‡XññEÏ`„~ÑŠáöáFP<¥`™JOå¤?ݹÅ~ç­hw¶Ø•Øyë=ÙE&Úó­–o-Õ´;‰æ¥~¡ž¤ÙÄzW활\á_³¯lzmùÈ™v 0Ö× 8ÚÔ!ÙÔÖÀ »?rÔh Ñï€ÛAíï7;¢P2TkÂUf’¹'#$Ÿ ×Θ'ïI»7s3»ÓNh••É)ݬ8zA\ ³ñž{¯jÎÖw¸èº»[ü8ÿˆý‘ ñÙìŸõs{‹ÌçtýVÿý³r{Á]÷5ùÍÛ—“ï‹ÉÖ‰dBT0'4Ü@ód"o'6q'p,Ùž3ÁPâC<ýñ¤M»Ð)·~øÄXco¼ Š^Â,ë®Â3ÆÛ`¾pþ&¦JÔGÓR¬t õïù…›f‡d=bÚl™M%=CÆ©®-Š7GèúQP$wZJVñap4¯+=¢#ý»¢ŸµGÎá‹Ò®²‹ÉTÿ°’í­Â *÷0…–¢‰üO¿¦<$ƒþ<ñš¬r·‘ÿ …zMQ,Kf¿¯ìá×x5žöꉆ8þ—ÁWѼ Öd„Ó1\ŠÛNÔÜÂa÷ÓÄòAë±ìµ"Ç+e]&duˆŒ%è¦3‡µ=µ18¯iŸ!­sæýxÉp`Zr¼Ù_¿Ctux¾56´Åî8Äñ"%xÄJ†gP7y%Ø'//R‚a´3‹¼…¯Ð?~ÕªC~ñ0±• Ñ™I§ø”þZñAû"1ߘ ±z< Ùó«¬#jÔdI½¤c‚èÍ-fr]ß(¶R ßt[PUO—!Êë ”RDôb®ºˆ‡ÑÔ(³R{…Ê$ÅtîÈ q^é/o(ë•'emùºÜÎß”2BÔåE1Zì¤1P]ÀG·9(«‰]r§,#öÈ-²²|\Ì¥Å_ò–Ì#¼“r“ø‡r=¼êRâù-ÙˆâNUê#œ¯ô79ë&ü›$lÝyŸ7¼¿”‰¤ØSèË2{,+¸ë<Ìy‚ÎŒ%hÕq_ÆSÚÅ­örhù4ã­À6·MÃûŒÈ å¼ÄYc¿f¨RµÍˆ•üûú±ûÚêÛ¡ýtºõíõz}‚Ölc'¢×üÈI<_¨qYûºø&·"_ Ùë÷’MCõNœÍÒV‰Ã¡bapð’û’¿Ü«.rºkCÌZNOeŽÙÒzŸWÔwìÚÜ“èb¤•Úç Ð÷Û?á?phæ oZ¢ˆÑÞYÐ »'h”^`xñÒSžÄ7¿wÚ ŠQÖg@ã6èçă ÙiàðÞÇ:€òQñžèr¸hrŸ¾OY¦Ì@qëÇÎ#âžQ4L鯉¹P48ƒ!Ñ*ð,®] #ìÚn¤=)TÇo©´ÄŠV2¢‰77Js8ñKè; §¼¹›òñ#Á:&«ªR½P1ßòJ'¾‹¯©-¨}ÈnÎÈø#þú¾—\ƒÛ¨Ä(º$£ä<^ø$˜/Tõq²cßGæ+·¸nfÊ?8cÖá–Ì0‘µÅõ@žlEGs2ŒíÞ@0oˆ‘²³ÖHÛêŽUªSÜfÊu­×TÔW§9U¨}ëÌõ†×Ì3ö×Vzû½)Ö;;kx€€ÿh3ýµüiŒs·’)~#‚PÈPÍo‚/ø¡¨OGSSèA è.îà8Ÿ‹·eIeÿÈ‘ÊržuûúUñÝ,ó]tuò åírJKÖyWôG¨îǵ•Ôp ´/À9©} ÞTcùþnåE¦9ûõe~;«¼ZÑÿÙ›¤üâ5ó—ݽé ÖÛÚDnX«¬•Êþ•Ÿ¤kÙÒïUç §Ô–ÿ¢ÿ}S¾sΧ¢õÛÜ.âfòû‚ù¼oJ¤àY?+UQ­”D7ð#j¸åcØW ŸâŽ·#¯;%åÁ¢¨œD™ÜÞî-ãQç/ç¾àe¤ûB(¡_òúè=ô6úo’ú—ÖMž-©t§¦èíêïQ¶¹ÝœzÊ[^/ùº´p˨EÖ;NH¯’¨ä5ÑVûjàºrŽ×3FPD02Tw”³ÄôÈ/à q~õ©Œ)8Ê_Z1º|Ázˆ9¢›ñcôŸRËSQ¿Ÿó¼ª–v^¢·?2v™ˆß/º!›Ø›ñÅÆ´Vhâý<¿®ì‚êóV+ _?"?§]4 œ îÏàõÑ_{tâ!°Þ±*,‘zâßO 6$ÖâSQH.¢$_SÀÚ"Ë5] QM>Åaš÷ò-d>Pa˜—*”š_æ„‚ú8¡óæNôà.sDÚÝ!ÐQEQè^õ„yI)á÷D_ùD`Œ¸)funð¿&¦qÛ;Àmõq÷¿Ök+?»ãÅ‹Ê ·‡h õr—‰'´„sŠ9ú~·3Ic¿û4ª:À©Ž®/ö>ã­Ó‰7ÔNþqjj[=Áiu­³™;ÊtåuBb“b·ÒÚ€ŽÊ9! ÿlå°>B ® 9bÍÅÞ«]FgEe<ÿ¸²¼ÉjcLÙU™TR¤9gÔ·z‡T… [G¯É'r‚z†VÎxãš1X-ÀOÜÕÞÆ³÷hÇÑÝz”^5M÷çÚ‡µkB™epA<6èߤÿøˆÓK¸teÏç‹y'z¬¸¹É‘þÉ×íÛlqË؉oÇ}ýuàlËYA±úhô^RŒÍ9˜š³œ®™gý“ùƒ‘š¼/ò@à%kaàºÖ3ùйÎ(H¬Ñ ØN–ß¶Ò°õ#ÖWæ Þ]Pz—Aëïžå!% þ4})x£´‹àÔ—âÚ-…hÖðÐϼoí þávNœ]±–0’ífzüC»¶±4ÚÈ«¯O*¬àŸeqþ ÊQ”7‰ë¤Þ½Iy§/IÄí¯øŽ«7VŠëè·vˆï¤uµRŒ0–d~Ïw%Ìì™DJgg6ÂRªCJ mYáJ-Õ0æƒqÇ{Ô¿íì%Ö"•_c§áïÄ cY,Æ£á.b:e‚;reqjJQmšdþKÞÕŒ«þO¶™ÞNŸ}Ììé_ð 5²›æV¦¸ä7y¹¤dŽ,èËδ7‹H™6º¨µ¸ÙPü=‘™…y„BïE³ÐC»bÏQÔãI ~”pÑWªÑÖN%`Tµ+ÔJ»qtÕðÇQ¿–çPD_QEÖ%0Ø ´#àý¦w%Ù®Kt§–™v»PcHn >‰Å)½ žùbµÓ‚P•õäý–Õ î/un®)]‰£w•«¹Ïˆ§>çÝ'ƒK¼VÚ,ýÿn©×D-ù³¦Xþ`Ô&E6.ÿ%½€8…š/¨ ‰ˆþò ÈYÖWÀfŠÀÓ•ÚHçªüá7Eá²ß_ùˆbg‚ŸKП¦l–™öXK'ý¦ÊZU|^´Œ´´ÿNùÿYðäN?uCø“¿¼õdâ`"‚t?Ò2î“ò2Ñô“é_!Å)çs ½PüŽ®Ùä¢ê«DÐ?PŸf:wñµúJm„ñj`Ây.ÿqPöù!¸%ãPªj³@þá®ñ˜ò7+Š/sO´T¦ƒÜ¡ŽÄO®Ì;‡çßàI v° تý¸µì’hþQ}ÂÙè@8ÍĨ‰ß¡°-ô1Jrƒ› VÄÏçÇ×Ç»Ÿà¶¹CÑåb¿#ï)ÎnjŠFtæ9õ´œJÂèäz‰»n'R¬o¼óXö7æ|P:‚ºRžE°ÐßA¦»Î.O¤è^-‰ÔÑLÌÀû$ü×ý„ *he8®•5ÒX¬,x?ž£/Âá7ÕG7Ða‰ïµ^\NLՆʷ®VYVöZª{ÜSv¦èî–vºQÞÎ0±)þIì!JZW ¨nRï%5ñŠ= ‘È÷á&Ò”[hQ¬ `ýnt„üGîÔ>»=Ò~PNC侨[xi'ƒ¡¦ý©`Yd³?”WSÎém¹Ù©íðG)µùây£l¼˜¡wðS®YIf†«ZåÑ Ãø&q¡lOîGš_'}D°TAwv‰E}h’úÈÝG¤½uy„ ïì€J‘Ó•üÞ™ ïœIf–nZ05V.c'­ò_3®ð×Ý•Ĺ[‰Æ¤çó7_ñ È.:$ÏiV´+½´7÷ªv")®i­í%åI+Î=J û7J¨ýŸH•îÒ(’CP‘~C~ˆ UýBʧÄE%½weHoËew‘ú,gù!ôµÜíüf”g—ÙËwiD§Šµ45[,–u37ñ¥²Zp’{²þ¡6;3nË ª§=k™™R9/XjDÀ¼³¶ÂOúƒ×÷Ü3R´¸T«NžÈ®ä­Ãc+¸ñ{¯9Yà ÿ´ÆEúùwÊnQÇøFàk0&6mM…R©ŸÖå*_¨=þU $=¸ñÎÙI°`ƒ3²w&÷€øÂîúç,2·Vàí‘(Æ÷¤ÞÀ#Œo­£xZc§©ÅýMèú/î&âÚ-¯.q­È W÷ú…ÄÔþwä+_x›ÉVÆ{¤¢-qÞ§ýÏÔ¨,¯4a£¸ª¤ÈëDèøâ(§òí¹.·ªŸôÓØJŠ*w“Âc/]¼CØ Œ%$ßPga¸%ô î0qͽl\ïQmš=UôDXÏ!°“Áþx®¢üŽ’¼˜„p"F2þ”¹á¤N²ÃzØXA£Ø†Ð_¼bßîcIìó`°,³<“£ª1ÐÆêÏ»½DiÖ'Æ{.Ä7Ú£­õ_¹“~.K£ A"¶YTÇŒ/WrPòï½±ì?®èú–Ø‘…âœà7ÞôÈ>å^V††\5÷ZÒÔB-h¶´Ocî% Ìž½j´²ó¾R:ò|ñm’æ¦Â$LQà|¥Àí×hª‡/Š]ºÍ…y•¦^É2un6‘KŸ3ÜÓ²glu¦eŸ°FD?p&…û}œBS¥Žõ´^îa}7ØØ Nbàu" îW~Ûÿ$Oà¿L±ÔW´Šx ­AEÓŸa3®þ²ßˆ¹ÌùB¹¦=˜,knÓ3ûÂßk÷Æ.¤ÿªÿPt%ËÐ7æ‰ÒåÕÃ7?+K¹}µz唿ԺzK–_žUi Mó—;e+ô*Jí mÊþ—£æ¿ ëVlýþ°úDAW„,Ù#¸ÇnÝö ÜÀ×±¾8æ ë0›û²Çø.ñ1©æÏÎ Ü œŸ§´ÑÏË¡©qÍÚCÉbêëÙØþsê ¯Ào¥öb~å:›'š¸K½gDE‘-·R›¸;¬—dß9$¼vNUnzŸËþT’‘Ê! B{•@æKŠšøCÁ£Ê „YA sKi¦Œ b?¦ô#bÇÄJÜð­=š½F©FWãÖWN‹kb¡¼IQwùÕ½J]o¯R¸Õt—µ^u67¡ü“ܤåÒ2Y2¸‘Uö=úI¢‰Õ¡ñ v®ë-p[‚%ѬÚF&N|]`"jü`ð JòxØÂ‹¿f¦¢—ϦcbL¨?DsCGw¼Œ|]¾Ÿì¬·t/Ø ”ôD-ïeÆÇ¨Ýy&ZÛ}Žãñi²½ceÅÃ$£õä±úÞEˆuñ+@¼X> Éfê&°Ú)å ÷ïèz0¶¤O‚ÔR™ ­VjÐߥ;¶Èv›aO©wÁ{Ò®ÆËÊÓHu˜ÚÛÿHþŠ«_Ñ?GS–iØîXû}ö'Ï%ò8( µvìs/Û’mNåä¹Îß :°KÎãwräl™m÷O<(Fyu¼fÔÒG–KÊxWùœ³-)ÄQm«×û"ýP?â›Ó¸/2J‹Š‡#EcžJ®7C ÷¢§|+˜áã‚•Ý–Ì ì÷7Êiæ,ã”›©oP6ÚÔÍû­Ü—‰Ýe[dfââf$ñ"=‚;âßsÀ|¯êVj>q»TÔúû_Ô?õ¸”ßäî/Tþx|QM(üÓjŒ•v2¹–ë©‹¢õÉÖš&†‘Åj}¦¿F~®dÚ#Ü/ÅÁ¿ýOÅf»®û íÍk¾A»¼;n/ˆôe0ùÁrŽtré•»Ê}?s‘2%¥®²þ9.C^sï<«ø5ó-m5Û#ÛÕ,2 3Eê9iÊvì°¥ÈFÔ{™•R .•;_©?Ëþ~¥·û{Fk~ðŒDvØõ"µXe)·ŸIù„ö$)y)Þ<ò#'´>8‰1Fcôøó!ˆ?¬_C@¢|` ›@á¤Èp¼xQx'V,y™PÜ ÿÁ‹wúDÏÛ{ dÉâÃÚÈd®ÿ*Ó¢3åïÜSØ-VŠPCD‹ïa y))5;s7XÒÌ¥²~Å×Iˆ¹´ÔF3‹çŒ lå}¼ÜÃUÝäõ>}¿’#÷x•ÄÏâ!õuïo¨žÔ¶øOàŠY~ tåWo&sµòÍEúÐTöñ›ã‹oùEôBI…”.)HWƒ_NnååSð‚Úrp'‹£ÀvõŽ×A­Án·“zŠÏ¼{Õ ¬-/+ƒü Þ %Û+íwaž—Û¸ßþ‰»|j§ŠÑ¼ëü-‡ÑÑ.Í,tû]îã^Ù¨x ?S­ú¼^&ú³>TV­ïaæ2$y]™þVo˨¡W “-RþEê¿Ëš³ñ¯?¬ ñ^'êñ»uFl‘Ç_ˆù‰¿”v·‚°(©6ŠÁ÷ÁåÎ{ü^¡¿ÊÒÐbëaÒƒéöZo1-ìØ×”e‘&ÉöŒ3Ê$;Bèh|;#õ*Ößt ¿•ÚJÀ=ˆL­n¯"5ð³ûf°Iô)T¿«W/˜m·DÕjÉsi­«ÿ.è_Æ4Šò¯;‡@yV6­’ٌŀ{3þv ?äxÚƒ²Ž~ ›“ò¢V ˜¦]t-r[x¨÷X@²…:œŽzüŠ¢ Ø?*]ÀYlîÇji°ß‚úD_ Žçrh8·Œ#xZ/Ź<-å\rR(Ÿ:±§C1*Jy’—ƒŸË£yŸ©×5ü‰4,Úíì&»¸PN øG¥ä~û KíQyw2â•÷!¿¨ßË’^ò²Hnɤ™¯ñ ˜ŠÌËFÅpßT«Ã5âQç’hb4ph“íƒ`Üc?Æ]ç×í©|¬å:ELÒëx[qõÎZÎkK½ ¥”¹ngªé¦üU÷ÚÖÞöj!Õ†²4B\–‚©ž j¾ü”>ò>  wz@ªr äÇ¢HWÙ^Bù—êZO¤– pcKÔl×^`¤³ÉÜK?÷ z“ÎN†1¬z[p–™rО®?-«8OÇ%î×êwRÆ¿U ï@•¿Øl”›Ð‘¨£VùŸãï çž ;â«9;¿®ºŠÛÓÍž¡Oõê‹#¢™=ÕùKþ–¨V\QH<¢B•DW2(ŸH¡¹ÉöVCª'º%!­Cþ5D|Tá‹ÝžÎKÑ9àt(¸œw—ƒùž"@ý”ÅÀe˜zjè샹0µ ™•À°ƒ¾[4Îz"Ô±š"½XKò½ÚÇ*b“i†? Æ…ÜQ”4îËjA}-O´âúæ¾H m££)ýôuxÊêÌûQ”÷"årÂ_Tø¯]ÜhÀð^¿€¿UÛ ^MçkðR=œÉÖ p¿ÔžrÁZ^ü"¸?OB²lbÄžŠ¾Ö m6ĆÙM ñŠÿ#Ä#´‡xKªCìI&CÔa ~Ä4pþ T‚¬Ôò%¡úÒúå ãý”=¸æq¿j¤»qÐ(%FQÞø–Rì dPh*ÿ d@‘GPŒi\åÓà«ò•Œ¿eB~môëݾÊp­‡3Aäë­ìí 5öÚïð§ÑÇ.C±QžEwc†û4®^ßÙˆ¦7´P¨×sûsW=áv#Ãxѭϵª[Úƒþ]²ÔŸÝyÅRÿD <áÌçCo¨ƒý+ Ü/s@äˆ_@ía¤‚¦É€w½Và½à>Þcêûà¿©ü„ôJ+õñýsJ¤üUÙŠïÒb{;”,4³Þ–=N]å"nB1)g÷6×P½¡Çн›úDp®»Á~ÀhÑŠ¥ærý][éA¹Ôÿ"ÿWu?:ó,Yùs>zýöžâj\r:²Ž­Ör^•OYë þrG™¾‹MsŠ8“ ³èŸKï„°ú“(w‘ÅM¯L@$ ®M€ð×î¯QŠç!å'C( 8À( `ü  e(ËÄ>²䀴üÚn»@òG€äZ€ø€âŸ¢3¿øT”‚áx\)8Ì|?ŸçY‘׈y´ÍÎãr@ÞlÖˆQ¹{ÙéÞ_8œteföÖ_(ç*/(=„ÏjWñšS%åy1Rö«BÊc%‘Ë@û'yB(EÙ®ïý†û2„~7óñ4Íî†i•þ×É-¼Ä}ˆ6—:ºæv%Mï’\Žg¼éíÇ6Ÿ-#4—sñ¡‘j¬6Jù‰Å—Òû ó¤•@ø^ê[À›Á§@ïg\'ž}KÜ¥Uúe óµ\o1ƒ>òå’ÜII· OÑ5í¶Óü!r6o‹òôÇ“•YþjQ UQGrF~&Ÿd¯I!÷(cÔWا´R/Ê.îçâîØo(Ïû«´e¢ªÿz¼·˜ëÿ¤ÞÃÛ^Mîöÿv¦3(uþç ÉP.d-þï˜ÿŸdÜ¿Ûv¼¿ÎtþóðWøˆeÄ~Ä7WC ®2^½ŠøŒaêÇHµÈôÝb,BÜI¬m±>ôÍF=ðw¾ æc™'@[ªW÷b~:ø;%¾Œ’“A<Ï%•Á r üÖâ9ô*U’tçX¼: E†‚¿PM@²Bì¸Ãåc༪Ô§¾xŠ}œ9¢"8/¨&WMøPüz²2xG!1Ä_9‡‹jÁÝNçŸR×ÕJPº]¨)¤òGCÉÛáÎ2×{Rk;ë!-ª>…L£NE¤ÌÖ/°=%O<ÎŒÈQñÏ…[–ÛÙÚ³æñ.¬W7Ç‹ù(p$¡²!L¾ÈóLòKH}Óþxо†PjÚÓ@Í× me¢¾sÓy¡®$†Tˆ—ÄöÞM^á&ütÁ+q×õsÅo³*ÜôöG¨¡27:Bh\îYVÁÎø¹øGy>mytºw:e§õ‹7=¶4÷i³´óªãëWýûÝ6âi2íx‘ˆ;‡¨×ü!À¹œ‹L ]=@Œ}$aqRûJnÓÂÆ×^i]3¶;½Í_õ«Öó¡®ÊñU)½”¯‹¦¥=/^/\’õ-½ór³³‘9¢ä³ˆ[ß–ý†ÄÍzo¼Ò±âuî^ºQz­3ñZ™ô…¹}ò·¯ß^hïSçäO1·ŠZÎäRWÈ—³²†“ê0¢º?ð«œhæ4W”\B¶µ§` ºÿØ3 «USºBâûÂ\|ýhÖŸ(Ýïýq:(/j_þ‹ ‡ÛžçÏõs?n»JÓ ­ë|£~àäòl Ž}_\µ¶ ²< ‚œgAýÉåû Qóº+±ÔgœLtµ—÷0WÔOx„ãíD­/´-ø‹k¨îX|ÙÄ+…ðÍd)ÔØP/üOÅàyí{|µa ?~°–ÚÔ ê]|?âì@)îªÄWÐsWÌ‘W¸[jÜ¢š²X™Šxßx‘òþC:|é43Ö’koQäíÄ6³6Xí«|”¬È’½Di½/Oæ­Ð—ø%œK>ç„ Ñ>qЉåZ.&Þ먑(´cx‰ü@Ô¢£é¼×ør–6@i}åw(Ù4µ:2½„z ‘vØ®ÌÑ´´Àrê§u]åW¡^ÊoñŽjNð¡¨MÉŒ¢x.ïeîˆÏ žO¬¦|ðZ¢;28ÞZ‹ŸK| F/»2˜ÝFøúP»(qån º–üäîEïRvÿ‚f–šQ1^36!ò‰ïFgˆ›T-Ìà" úR %@q €ÄX€Ä"$X6ÜAܯРÄ~’  *ƒVOM€ðQ€”E€™¶Œb¬´“¤Ð>M£¢þlJį)mÍNŵJ45òóþ*9VmœÓ§ÌXÑúæõòµÈ¿V¦â7Ø—Eõ äž=]¹'Û.|R¦gñµk_…?ÏÏ ŒÔ=wÛ=%•’j¿” j¢žÙ+P50<8‚ÏÍW* ¡¥Ñüƒý4"Eýø_ð@Ѹûöžë°¢¤û1¤F’ÃÆ27 ?мxªzÌ»Ážþn¤y1>™¤Vä\E'ä#ËM#E+•˜ÀÃêo^YÚkû¬ŒÕïQ—á¨ëbcеba‚ÒYä#•2ŒÐ¶låªlŸ>‘²b¯\ERôö+F¡’Lqžb)ŸTöº÷€œ}䃙s€¿üà.²Oƒ77µ2®ßS½„æìðkÐÏý$rétûð­aÀ]÷¯p‚{\n#”lo4DXÅfœoC‚ó„þ$ÂÚ&üdqx1ŠóA /qÆxýñÝ;TI¾n¬&=oa¸ºÓ;ü#Šu&x›Ý… C ä·ÉUú1ïO»»X”hï}Êï±\¥iji„VT&y{Xz`}±àv¯SËÀész¤Ì†È5®à§Lâ"œ® G„ óvð‚·•3Ág»ŒUöŸ 43x·´#ê@ç°,eVwG ÕÍñ§M«ï8ˆXÜ=E¡úŠ×¨²Ù®B±95~‘ò¡[ (•ÞôÎqd‰Fwÿ@”ÜœÓJ|˜ÿ4dÌ+($™úpqO)Š»Ð.²41DìŸ\&™õœ©²–&-9AœõsB›(o‚¸_9ˆígk‹Dwç í3¶¸]ÌEâ;k@ðQ-©„ç‰P\MI¿â™ûqó~É ¢<šƒs©Ôã7ÒJ¿Å[g³{Ñ73Jû_{j ®V)ý§øMi[v³½ž2†Ÿ¼FJø ý0J–( ¡r‰›y¨8ÄÛšCÛ-å¦CÃõÿeYô/#ù Vòúº˜»—äßÊXq6ôj²Ó÷÷ñj`†õ7ÌK‰áqÉ{é`°#ÌJV5ôõÞ þ9­6%Üjo÷}w­Ð”!îUæ"Η$cõí·¨¡ÍwçR®º ¹Æ]÷wŽú…^îš{å(Jµ·6ag)¯±Ùxƒ5ü$Ïzo³2vÒ]È墹î*ÒÍÏÅAt¯¥l€«ÞU>"?í¦ñU´ÍjS^òç([i^ô‡W‹–‘¥Úq\ù‹^ßî¨ØÔ•35ÎQu!eLOÿŒ92¬ßa„ß@ÿa,4ó÷€zŸ_(·¨wÝ{O|àüÃ\gHpwã?Ky+™¼Îë¹@UÖÅï –ä¾ä“áëÜ?£çàFV¡Å¶„+A|ph#Ä„ÁоÉ¥I|e¨“bk#oR¯xzØæƒ¢ÂðJV/ÔXï8'!~V¾ÆðâK~¾Œžsþâ±âá8¸ñEÊ?hÅ_;—!þ·!ÚÞ¢?zݰŠt-³EÙçQ‚ý’ ny:yÚ-Pùk@-’ ]Å$µlÄQ²pŽHE§-Q¥¾¿K½+tLå„ú2’¥²:RTt+.¿ øÀñÑ #”!¨þ0FƒSÂ?rŸÚ¼Õ þó…d¸­²'ô : -ø²\O"x¿–àTðS?'³¡ºâ˜<<©W°Ëc“‰ ã‚ÿ$Úâ‡~ŒWæñÔÇc}Øe.ON§^¤g¢²ÁM–†ù§hBxßc$[o©t˜@¥áÿsòÝæÈÂë'w‘˜;¢èAb²1NäëØc¡eö§¾ëÁJñß‘›ö8d¸\r^°|ìt³”£вúh=ÌoæD·3ßšÇûm|å¼!‹õù q÷«£õZn†r#¾Ý»ÍLuªÓÔ7ßÁkè^åug:ȉÞÀU·„‹0¶WSð'sL+ö¿¡±¾L9‰eõö’LŒô3Ñø–(ŠX(rñ”Oм?ùŽ_ˆ†óv©cÈðq‘rÆm ¾·H{E\Ð#`oR7‚è¤å€øS×Þsæ(„öŠö5ü[Ú0o—ñ¢øÚÍQ–ˆ’ö†H_Ž%žRßäN²{pëÃã8–ܘF"1B_K0Z'ü-ćއhïÐMdlj¤)D„ÞC6ŠÌÇ-:™Zžd¢Yx,­sö¤et~^ê>¶æ6Ћ“»chTô>£˜Z0’t6®ß“Žqß<ïW’ûô/ßÒŽ*K}C­«þå>«ŒP»-X¥·w¡A È)QÏùƒZ–×›ózEw =ÔLï ¾ºÖ݇«çúOá+óü$¦xÛ­Îqí´L%C¨båøP&(;¤ɪ±Dþ ÔáËG•–ø~T &$^}*¿ “o«« zÕÕ‹ "iÕ6®#ª}ÁY¯ž¢r*ö¨Ö†Îr§¾ß§&ß§/ã+ç^Í•Q¯:ÖkâµP꺿û?ò‘³ÃßÇ%÷bl Žù{ôæ¾ÔÎ%‡+sÌ¿uÈN)Y\†Ç‰ì‹L|uzŠMó&ÿ¹”÷gÛ3™÷éjñ­Ì:¶Fëé­“MÅ·ön ZA1ŸWã-ÝÇ(ðÚäœçëàíø{쎼«Tõ¥9]ï•Ø¨<¨’B40?Þ?Ãcâ«hl–(O‰àæäAN…†:iTL)›Q2p5Q©Õt?G‰~êMå*¤®ˆåƒ8k¿FÒŒòÉWA{Ý?Æo"Ríàþ…¯–µÚ¡*ƒÔ= kñ'€€óð[à#Ðþ·=ßû('jaUÕüU KþnWïOð¶k Á]«Où‚r¼Åg`Ÿ2&·S NÀ‡à¶ò3!¾4ô8¸/é¥!¹AâÑà›àxÚ4ȯî‰o Š4Fqî5;@ÑìP!ÉB=\Y˜š2NEmSË  gø¿7¯EÛ²;¿‘uІ¹¢»)³ª÷¥CÖÑS¨²•Ê|hðóäË!¶ùwõt¥„·@UÔ—oØiLL h´O€9 fuënûìA”4j9=°õ7íW±ÍEö»ÜÐ7¹©Hý†ó25õ®‚PKØO¡èý_Aïí]ù(ïz=@Yëݵ¢Üâ1Y Ä\ÿ¨ýeE^% ¨ SEK{Dð/)™øþ"%EÎT¦cyœ!æaϪ=Aö8«ÍÖxîËü†pÆèG8ãÔ[£&õÉRžÐ‡â$Ïh50Í]\v¦é£¨iÿèÃëQ£³gB{¡äø”9”~½µ¹¥ÿçøÇÆqþú Wjù}m³½¬„q$¿ñ¶ùž“cl£»5W«ï5°7©{éò/'ÙøLþÉÈx ÿ&¡ØD<~O|-ÎñOt¶ý9Jñ2ç$'vp™šÅ»òGQÒk_¸š¸¹Þù”P†¶”Mw”MÜø˜î„ƒÎ(f†w‹ ¡ËWšé•ª«cïÖ/‡,í´ò,YšgÍ%UûEèµ a1;2Rù¯ÎMÝb[°¾Xáä Ê2±ú(òYç=8²;äâðÛs?¸ÍàÄþ¿jÊ>pº'G€uÇ.÷Sm Ä/6çuó:ÄÆÅƒ`=¬Ý‚Ä÷r Ÿp‡B¢{‰ŽP|‰!P8“ˆh€MéC tç Ô¾r!í3sDjûñÌZ(Áå"×ìåg míIðU‹õƱ©<êk´AŽ*Ûå¥@†ùÕß•œ¨6/ð–õ ¯™9“©kô´Ê²#p*y“mÆM{,ãõÉöÇœ5¯[ŸaszÆvç¶ÞØ_¿×€®¿áî@ÕÞw*€fú£@íâl-Mú»É Tù6¨ü!À /_ÕåQÑпJ: *ꀯ°Øå¾JPÞrò=È%JxûÔ[àwÃÁOSJ€_G îçê‡øþ8u£™o”±éÝQKá&jµpÝ|ó),ÿKÍÀLœ5JKxõo‘5°„¡!RæýÏù—Í9t&æG¼µSîQ"^g¯˜èò ®ck—É4û!؇˜Âg‰ó~”ãÖ,¢À*£®çBr•$>1¾_q\,V¶õŽjÅJãs-!^ã„qWéë§èóe\.Ò爟•L}÷éԯŌ41Ëäüì€÷2о×æßŽþÓÞlüÈ{îtŽ› \ƒúNª| .t p¼ï QSÉõ¸r;äY h, @|ãO§«_bJhÏkñ̇•ñ¨öw\gE4aT¡aà>e&•c»µÛHqNí‚´?Õ¶£ˆîê@ZæÏðÅWÓhAôÆÿóÿ‹Ûµè@6¤üÆSÞÒ V~²>„v ”HªY”ÖÃ`öÖgƒòbr,B{Ñ? úWê§HsQpˆ=vc„Ø]8ŒMi]À¿™× Ä£öIP¿yµˆq"¾œÉ‘­ñFDS/Ƨò‚M4ãN ,ˆoÁwzY•P´ëO9íÀlšx’¯û½P©®æï R}Êoƒa†d•”g×ñiZ‚)vaf ­©© é·/5¨@và ïÁ³ œ&ìQæ/xÏÐPº&niÓ"Ï$ʘz%¦@pvR!aJ{‹œc<¥ðÓ@±øD¹h¥l¿Ö‡¶îGæ"þ±f˜s yh2÷Åg§>ÅR@áˆt ^ȬÌмZ™ÙÒÍ[]b¶·õÎê̺^óü—3Ï{}5#ýãÃã™Æ¬¢ŽÉY¢(6)£˜{´ü›<$Ž7| ¡Å²Ú#3CÞ-ª6Q_yžƒ2ê>D%ûɼ0½ƒ‰ß0ýõ·Î€Øq_Eº±ÂwÁ­r 7Ç€¡òõQúÿ'þ¢”\8W)•:µ¸ñŒYV]0´_AÙ6®ÚÉ=€ʱ–"ÅîßèæPwªñ™õ"©þw^й€`®qæ’)û×À¨á j³xI°ßP+‚ý@C› êt9@6ኡàçûß¡Èá…‡A~¯”¿‹£Bâ’ö(¤\42AùRþH…ÄU½ RG(KÁÊ24ü´í^° ÕKtM62¯·‡…Ø‘N¦ÀqZ›‚7œéÆ@ñtA£À[Œ.y-UŸ,^Ø>—œi¾ˆØƒ#T1y‰j‰ZâÊÄ~¤ˆ3f5«=)šâ…hwï(ø½3_è?EAò‹Ü±ç˜rן¯—¤œ,“llô’~=eJ¨„7˜zÚãNCÖÚ&Ÿ¥Lþšx;Îc‰½HœäV„6°¸ŠÂî™|èX‹â/ô·!ƒY‰®È—èhôI–·È^A¾Û,”Á-5«ÄT‚v¬ó”³m:£G_•ϰòR§žŠ67¿]Ñ+wEHïÄ6—è”¶³èg´”zEù<ŸZ7^[î “xÜ_\nuóK›Ü)Þam¶gúëÕ|¿ÈÛ­æÉ \'¾—Ø&·‰âyõ¢hèÎQV©©~†öºÚÏýD§®°ç§'ùB¤¹R%º1ås®?‘>/ÿ™¬Q¨yK4;«K}BÑ횥ë“zëbéQ´¿Ù¢Ì=N¿›—Эž¹åSï‹õŠ 5úä·‘ÓÓªVêK¾4µŠ‘š›º5R(SXÜ¡¦Ñ7P‡aÎM­º±Ãž,Îù§¼ú”N9ºžl±šFäð¯§#h[./A–¬¦HDÚEÛ@šó‹ ªwÔ¯ø-lƺñž^!qœÃz®Ò… Ù¦ø:+Œõ~Þ×9©ôÓ^°gãhÅZЯ =j½"犷ýVþe¥©‘âo`U¬×‰_ÍKÒ¢…vÃkÉÃZ®ü .üê}@ëô_ÅjЄ¬ ”§4È—ÅßP¼Pº<è<'Úò`©æj=ˆ9êH,WæpD{VyžÌ„P"Tv*(ßùÓÌ#Jm¿bN¾øÄ½`ÞÇXç!å ÜvZCÚ:ïk€sB/Mídçàý|êÔôÒ>öqÊÓøv¯@>š¢N@2[¢ê[" -ÌA»1åuÜP…èxâý߉ ½ª|Ú/.䥸ÚE=,HéPüµQÕXRü8º!ä$^Õ;ˆmŒ~òc>..s'Š]² DŒüQ^âM/tu¾×E»B7¤ÚÙëÊâøm å~¥žèou¡–˜AU²•ñ8|#¦2WyX­šÜ¥îãå!&íõâSÞÔ¾ÅTv¢PVˆŒÂ-vK¤ Ée•ÿæ‹ «çØåW›ätÙÛ1ünú•Ä~\piüšx#8+þ }B/&Ÿ½ƒ)‰º¢gðTrrÈ,oDKs7_™ë·å~u—¼<«¹E›NsÉ8Ák{@“Ǭƒæ¿w¢T(毌§…Gy—íO‚/zW­¡Á’ÞW¶Ô绽õ?Å@q&Ûô.Ù?C k™ÍÞÚܔʱ΢jêëñžô }kÏ ÈÎd6Ï„ß=…gH<‡ha—ƒðñ‚] ö-˜‡Êå1ÊáË¿û2¦2ôZ]â)ù>WÕ²I‹í¡'c‹¸ð­_h(².óM°÷žÙ(•ãUQ{)§œ›Ê8™jw¢“ùž=ËÜÊù®s [édçÞds'ÉxýUo)ŽwÞ)ƒ’c¿M‰ÈQžVÖ÷ÉÆ˜Êf‘á)ò>D^ÍøÚ†+µ˜lôPÆ@Æf-N¬×Ø %ìTÐ*í òšÅKÝ5‹Êrìu»ªeA¿®6çå0–­©R «“)¶÷«{I¤.6·rºp²ø„žÚŸÆ~v*eÍ{)ŽÆ´D-Á9Ê3Öp£¯GÍ5ÆàÄeãYSé¨ OWO‰¡ÖcFI*'fFp:>ÃüˆãUB¥ùÓ<›úÕƒYæÃøIá«(Áå¡c$Úák˜º›HpÌhÌy4þ9û7SrÉ?`æ¢ø5å 3|gy`¬Ö1VK¹¬ Ѷq¯rÜžˆ¥N=éªôóÞ"!î(÷aˆ S€êïõ/AÊ‚Ò%0²vUjŒcôÉÉ‘$õ1Jg®) Ü&ôÕF*W«×VÎbKU¾B)ýa±”rb(qýÉT¾—×)¯d+“H~!ÉY9˜Aü!’ã?î}A‘¼H.[åÿSjxiÐä».·½ON¶w¿_@i¡Ì!àþ*&Q=òJx?©ªR¸kÁUî`¦DNvòMÊßJ ¶†ÙUü›£º3I3ðw<ÌìÀÁØŸL‡b_ñSjqb ÍS6Å—2Óãåx"|%öZèv²#„g$†c‹.À¶Ûÿ‹íGÿ ÿÐú¼C0»EN8"q#廸«±1Ò­ñ8áQÑ<ô@÷óBc°28<ù2?µ#L nvšS6°6†ßZÏ…îIµ©çØmÄ8ÎÚ˸#ÖZ'qýFî4çýä9Ÿ¹‚„ÿ€³Ç¿b÷Ã<ÂãVI»+j B ´¼^É™t „'ê¥h._õ¿Å+žæ¼MÈýÝ/Kعåm¥ª2Ô”‹]*Æ"C'õwp•qjWêF_pÇ!ƒeôñ¸–©¼…ç¬õÄsbêe|ý9c Io™C%Kÿ•tÙÅXñFÎv UŒÕ3Ûá =_»ž¬fÊ*ëöUÏ*­œ§Äjmˆ“"jëgí/èd§5R?ð¾d´Ƶ–nó€69YÁø'4 yØhùJ™$Î8‡nRB¿-²zêi"%6”æ{±U|–º8n°6t©¸9ßèó“÷R*ý~«„¯%nÑ44.z´ûKïI|†0;Ú©h’Ìs°û(ÞM<z* Û$zƒrÍ ñ©÷hƒÅ„~Oì.ª"U _ïä>Œ+^L¾ƒ£Ô’ù¸šéAá}10VÛ€½ä)¤Ø^t Å¿e'Ðü7S› ‰ÒÁV¨þlg 8y¹(^¡ xsåß`Ÿ5wÛ]DÀzÛ v<ðhm‹:Bò‘Ð2P-ã<(wµ¿¡øáȈìwDë­!HëRøGðWzó1 +Õ"_À g„Ñ„ÉÙæ¥aaŠUzi䈔ÈÖe·mÒÊ©WºJ§ÀLå–·VŸ®<î|¤zÆÏVVNX‡À¬žÌcšù™u“ ¹ ù4vàSû1c¡=•³{ò;ÊÕœ»ØFÂiŒ©Çm‹€1Ë^Iš~цêfáë ­0BÍ–O‚1Ã; J+€­M—cñ•Ü<%ÃŸŽ«U¥2R&üæxÊo~&ž²Þ÷ð؇/zËŠ . ü½"†JX¸(¾¦ÔBó=e ªwMd#øNýÍ‹kÏ zmÔvþ*ƒÓ\»€â60Dz«Ô.Ôr.j•ÀùMÛÎÉ`{|§¡ÑéÔ×vÓ0ñ³1ߨNÿäncדUÒúQ.½nÊËì/±øù_T>ó¨¦OÊiB¢Ü7|ÏGy£CgÉe¤–ƒ^\*P“ÔÄä`e–»‚QUOìü©>‘¸eÎ0êÄvè#ÚµQ8Ö-¥ÄÐ%áùh•še<Θè8o V"¢>1/ÃÄÉo’waö“yÈÀ–Dž7ëøg°‚}ÔEcQáxD`¿VÅX®ôEè¯'† è§µzãah«ÍÁ ULtÆUmñ&Býξ͇j]©qPIsæ'1ñŠG‘‘Ì#•"….,ñ?ä y^ôcÜ#šáÊýi¯ ¹7¬~àýnYM>þQ«=øÙηàoŠwï<s–öàŒW!YÇ @rž< ñËÎK«!Æ@ñ!€â¯˜ y[é QU» ‘Ÿ+”‚ª÷WXû2^‚Œ[¡aÈÐ@õ;D ª÷ VàÿÌÀo8æ±:p’Õܸ7ö² Ô1Ø€Z!ÝíªÍ“œ,±Äج.®›í¬ cíeH¤K²5ïýä,~Ñ>K~@ }°wgšýžQ79šªÆb§&ª±Ó €ó'†žt2@¯à˜H}ˆ÷ Rmë$ú7nu˜³Oëä\Àc¨(4úÆ[á“f~НÚÞWH¥Ÿ…¯Ü/!• n$Ý‹:#Ý" ¼—b ¨G´¿(;PüKj _Òü{8‹êU6>DñG*·Þ~u?ªWF›tûª/"ÝjZ+·™:ÝÚÐн׵Y­B­¾“¡DWÔû´ý<û/;ß4RÌ¢òjÃòCÕ9ª¸ÛG?n|iuÕ¿”ëb)úÒÈYN9éìTaPÒKnãÓDc¿5kmÕÖ¬·6k?c·#zðˆý,nØÔæñÂÿCÞ{F[Uty¿¿ZqÇ“9 ’%(’QDL€˜# ˆ€ 0 ‚‚9!¢("¨€b€  (ˆ"9IΙœ¸óŠu?xšî§ûyµ»ß;Æw~¨±Ï:{תšõ¯Y3UUdnhN¶W&©Ò6'°Ó½1ì/ºãØ^ìÒ–Ö×XÉV'«áŠÉÞ\]ažRÄ!qŠR4Q‰æWàaú È`º_"èn$A{§/kén÷dfæ{28™›)FMÝÁ ”D˜Y æK±ì½Ê\Ìòù™!\îéÆýä„.‰v×¾©µ³`‚rIöwY1®Iõ+ÝÈñ㙽Qò«®4¯ó!í2D¦ºBÛµ‹Až§> ²½=ˆùÊ1¼jaùÛ&W„‡þrªxY=ƲÌ`¤ÑN¢ëQç¤ÞÍ\Jgm«‹­n«8HL›ü€5¢™1W Qº °×ïsT¾è7Rò¢dZ¸ëuœ#¥0Rž„À©]*À/5Âr_³7Bú;Äçú¬Î^Õ¨”b½¿2›ƒú¹jO憮!l´–E¬Ôêkki®\¬é¾"Çpo£Ì#Î0Ñ1˜p¾¡qøD²%Wv¾avä'E;ík{ Rmè÷@„íƒzÂ+Bñù·ÐÒØnBÚçk¿â ÿ{\ý3o=’‡m R³ÝÀ»šIåð…à_­î…à×z7ü¼"ýÐãÚ¤\éFPãóµõs{jŸàùqq>vdˆþŠ‘–FszkcédýªßÄBóáZ‹é$.S;°•âÆù¿ØÀ ò Ø~ï °oÚg@N‰> úy‘µ .Bð™`5PNÝÆ^}è#A›š Ú!µ ÔÝ—@û=ð(: @Üe-ås]€¶'çØoƒü<õ#†€tåý ^ÕÆƒf÷Àée MòlÔr¦€ºÀù”gýS`î’>([¸ DÏô °>ý@îÕÃ3ª5püråûGß&û.8Sò>Mãdz¡yµÌ­„3½ôäÚËõ…¸ÖÚN4'©oæ+G× ‰:¯“¸Ô©¦NCu'©²•;RoííÒ&û¯ÙÏë½½­öíæGNyjUÀq>ëÍB§Ø™hýß´k ËÍñv©ýOBµxÉyC^‹ïÕ ?¢œŸÝ”H¨(‰¨ÊûÚ-À}é;Ø,7;%œÐêŠ çó‘\L@î–1Lù¡„*Çh AV÷ËÁïï-gŽøéÓuò@0 ¬>éóÀ{Z;Þ6íbèplÑs 6é«ÿÆ ÐüödãÌ<¿dʱ;í±¨¡ßÜÜ@–½ÅhšˆP®õÒsµ· Ì‹3@Íó®=ጵ³» ´^þïHu?¡öµºƒÒR½ô÷å ÛûÈò·€øHAì"´G€Cb*È%Ê"ð¯Wÿ‘Õ¼5¡Àƒêgà>ì pKs^™ò!‰èÛÁ~SÔ«wðp‹Í` í °î4x™<3ƒšúЬOYj|ÀEMß “•é~ ’EÁÑ”gº„+È)¿ËœçµÎ|/¶¦øÓ©žœ)åp|²¾-öý$ÞTë@i"þ$³ö¾¹m¼ZP0„¾œÈ›ÆçTÍ«IRnËšÌÒô2#ø¸¼²¯‰m¡sÖù‰Ÿx=zS¢ 'üfj+zÖ©ôlÈšüŒp& ÁÅÖìœ^ ÚLÿ õ¶Š‘ÊØÌïÑUk ¡/Ò7‚7š/qÕ^Ç• )ïP¿ä¸·P«ÎAy—~ŠÆÞÓ¢ 5¬YÆpÞЖb¹W*U‘~Zl$ {È> fúw‚ÒM¾b´û¨ï9­AÚïj{ù< ([Á@sÀ=eÚ`W/€=)<’E¢oŸåaÇ×FÀˆ/ÏžÀ±Y œhìœÈ&k]¼N(7ñ@òQscÅGV/õ¼¤n¬áXf¨UÅÕo@ÕG’ Žö!‘e‘Þᵑ†ŽÉIþ/ÆƃvGåóÍt!¬o!d¦¤§¾FQ˜ÝpEýrXÒä)/ý]+øØAˆõÁ<ä¶÷äFDääÖ/zûlœ€ F±[ ùÕx[÷SI ºVëW×VÈ>îsÊGòY·6?JÏ}Ûñ­èáëüKpS_ØÙèrÃäNw=ƒS;ŸÐ:ÚOi„4T¶!¬šÞHÎ÷rÁ¯'K€5œÎ}î¦E!t­ XWÓ¿âMùJ ¤µe™þ­>Š%ÖÊHžÕ—ql[=‰®ͧ(u^R¯'ÏxI ʉŠÐ—úω.J/w•öØ]gp2—‡î@·îÐZBzx 5¤‡†–Bæ²àHÏ0#F¨"uE¨$"á¾90bçG‘Höˆ|M(–.d^ʼnèJ¾‰U–ñn¼oðVoSj¾Ò#µÌíIëŠî¹ä&æª'P·*õ â&k6”^VÖÒΉy|23¢]9‘5„ ø,)]˜ì5ëbr±1‹Ã¦‰Áåwjð²z˜ã2­ìfºø\¬eÕ/ïe½ü"Y"öøXË›n Òdìa@À̀̽éלÇé~åà„¦¿¨ÍÉÃe”—âSÇŸtñ¶Y¢D¹ÄÔÀ£ $ƒA[ú‰pG0›æ4áDdtà;ªF¾ j2nNÑn°ÖFë÷$׈XÔMµå‘œ{“;in.IŽæ®à…éCÄ#NZ –%[BPØiˆ>–Y ÁLù2Кw1 Å޶ïC­Tý»Ø¨˜ÅÍÎ’7ÖðDѤ£in<›n€<×?È•ö½ÎÅšê·q¤ò)µ,Ÿ QR÷£ª_YÙ«­¹Ö{ØžHw²ì¶<­\jWɬÉü‰å®ÖV#ÝÅÚq,™cÜDP¹'ЙO”ן3Õïc>Á%Þ€àK™¤_xŒ>Ô4ÞóÂÊhåmkyè>bÉ×Ì.LL¬Þˬ„÷¢arPVgüÄ»f=”ØÎÐ÷P±!'ƒ‹DK0“ý#ßAÙ€hW(Ÿµ–ïK«FžeJliÎ+|ŸXzÚ»¯ÄQö%^”qÄÞW–ñd¬†ûVÅRç'H‰¦9jäÕñp"¯W‰ÓøFu ?&r­òµ3 COh;h©÷õŸ¥X/vPEkN„«tíÿiP }|I(§Ôª|+Z‘Ë×ÜËå4÷оH$uÙ+?–3¸‚7ˆqµ¬çOD“ Íu(ž¯ôãÁ*·Y¬xÉàg¸NÂ_Í'rù# {×1!ï1‡$2bAt>õù"ØÍ_a7„V¦‹Î¡Y‰VlÏþ4ÙœÇ#‡“»éš58=ŒGÂ+ã×â…ÞOý†™÷ »CâBnLµ€ðU‰§!Ø?u+ÜìºmÈúÝ.¸†@vì¯#?“É^ßÕ‚¯Î)ûŒ¡©¯!4)ùDæ$tý™á”õ„÷ÅW½’ø’hhxºý‚ ݧÝuÚhÿ ëZå½p?«6ϸGÒ{°Œ{¦3)]”ÆÎ¸éÇS °«ä«_¢¦ÎKkèö†ÌψìáÊ^DqÃD;22ùÖ ÄåPøb ;œ˜[1é¿æEØ_8[Àìª^µWæ”BEóL)œx9¾ ÌîÆ\Ý•§ PÇl†T>RB¤Uÿ0 ­À©Leо Ü'ÔåàwÐ[#iÖÅÏ×ãËÃFu<«›ù ž÷DàN:™/‡±DÔ cxÊ.à ýíg§uè(+â¯ñnrPtk¯Fó°âe擘åò÷@jOÖ§P6<°J:ç½99Sec²®Â+Y™õ<Ú‘©ù/s~…È„½Å«•ùYÇöõbD­™¹lÒ‡YË0uìÏ!Ð×þÌîÖ¤q¿3”´Qh÷$­iÞï¤ôÇíiÔÔ‡8'‘úFWGÑj¸¯ ô;< Ô&Þ L·ïã{ÿys1(ÓÝÚY Ag^1UÎqû€|YDFîº d™rø>ù³½¼ºÁ^ TQ'€;Ï{ìË?2Y+ç+e¸ •[Á:G=ß]mÌF8{õY”x÷›9$Ü­æ|ê¹·éŸp­½Þ¼^ö`åw—Ï ¸žÐhe¿–¯Ã«X—Žq¼j³ò›¨j:©zÞ¬V3×ëµî@4ÿ×ñ/yΟHϹѩAúp$øǬîF F$B¦Å¢dièC’Ö;Á¾rgü"ñ•Øp¨4v-í¹/ÑǪÜÿ˜ƒÉ]˜Ñú™iäæG­‘fÌ_m߮ޓWÕ¾?X+}a™ÅèŸÊù/¬Q,2gVr¶/ ôå‹dËàÃ|Ÿø<4œ×‘Ái<ßeÌðÍTg¥gz™ß^‰2¡ozºŒ0$ÕT{Ô1ÐR%,…ŠÌ¦*xÀÝ€ ¥µñˆ@®3MuA—æd{ŸÎùÔÙ©.`¼¥oµìÔã ?Uí(9™ExêŸÅ‡QÕUY7ñªx§Êor¨,±gŠsÅ7~Lîâíñ1$—0\ö,iƒç?äç¢z¹Ê»à´ñÛû€Ó†Ú`DZÀ:E¬™„ô&$¤AƒÔ4„Ä$vAò+Îø)ŽCÅ<®²>Ì‚X;­9ä¿Óh>Tµêµ@_ÿOÈîÑaÚÇ`^é,G°ƒ—I#ô ¥t Ž—Ó™|OyŸ?CwyëügÍ«"õí'Ä dº¦x<Ü5³ˆwuí G¯NÿJPO«3›Œ?R/rRÿ-ý®±ÚºŸf'o%2R#uB혾ôÞùüÑ›<û=ÐÔ… móZƒño‚Ñ6Þ[)¦a½å=ôÔªÙŸòšvT&h­4÷5¤z…­!”VÊÓ .pË@­âÏ¥Žl ¢Šì o&0E|(j_`—¨þtå3ðÇ*MÁúËÁTy äÎàhlw¦ †[70•;ýn2Ê%NW}Ü&æ«xîGÞ=¨Ö½ÙÁÛáÝ™Lø"ðöøµ þóÀÐ}Q° ˜½ÿ:þ“8´bïtNMŸ­õ }ì»@oöyóE°.ìd{â&s"$ûŽÊmþ8íFï#ÿ3Óëì“<’ø ³XºŠ¢35u“¿;ÞÖkka¯F¤çê# µ×° äƒä3鬟‚²öÎcpüË’‹¡èÒCÇÁã| úq;ˆ!ur;€÷4€7ÀÝBm°péý(„Ò8X ü¶ÚtHôÌ”CL· C+ó:ãeÇóç¢5¼¹ñ\š[š›'¿TÞ“CÅ¹Ú Ê&yØ{Ùë(ŠœX*F½c[w%½·¿„ß(çBþ)²!;ÁkÝÂKiY㨑‹µ ÚßÜÁˆû„šhCÀüÝ}‚ç+›Á|J­ æ#¡;@·ú²@o„¶Ó™|›x”µ)(#å³Xœ‡†%/sÙã§ELÿkéàû?(¨æ<#ä9ó‹P2ïÈ—ÖKüÄqûý æGóoãî¬g뾉|Ö5Päw¡,0‹Þòm@`¬µ@m4°ž%O8N±?kxFåuµ†Ó’üPÌêLWí!{OcÖ\©ÿî>ƒeÜjå½äX¾“Xö3æÓs"Uîí$2°ÆYŒP¿JÝÖñ€¡›i ÚŸn{¯ÊfÀ7" D1y@#9ä/Jo-õBýf`-Í<ÉÍYó!¥ì÷'o6¤ž }¯!Ö!­¯´ïÀ¢â˜·‹'È.Ûa!©'[j©úOvÀü«Àëþ°WuŽ>öí{ d^Ìöê}¸LoZñ6‡Ä\Ð{;Ÿbk|C4ÐQjÙô¥îZ^Qî–…8Ê"5]Û(.v®Æ— K|¿Û:М™'T„,õǃ<'«'Èì¼[ÁßÊbp÷ûéî‹tEø_‰°ßõƒó©Ø öfûMÈÌ÷/†Ls+ÒŸxÝÛ˜ é”8bÇÓ÷Azšö”?œV¡ldz)Ä‚ò#(ìÐúr¨RZûm0ßÔo¿Üz˜kåCfõ©ñÀ²’5ྶýSÈÝìƒ*Q!ïß«š®4‰_Ãõ4-ÛÇ÷¨§ZÐÍYœw(‡Ô×!°µj˜ä< êIk-(ûÕ. mÅ ÕÔÞ ­ï!*ŸioP¬~âùQ‹øåìÜ^d)Nðj*8ŽìüD¸^¬yJÌÄò?‡0½âSé)•Ð}Ü!¯Ì¾~Î…§êày©Ð¨ÖÊT ¼šê7`=i]2·ê—мÉO;@\¯·þÀ^ðýÕ s®<ñ%wp'CÄ·B𢿠‚½í?Àü$³´l§è·È¦ìç¬m°µÔ+í¶ &Åí …2÷‚R^€4vf®î‰ÿˆàIÿ cì~ kð&(£xÁ^ðsµßA×_Y¤žÿúœš <û¬>æ“àféÈ/Y Öã¼Kô;ÁþFÕÁ~A_‡´j.«ªº‘þÕœ©%á{‘™s‚I„ýPx523Ûh]Q-´3ö[äb¦ß ?ÀW‰óÂSi]üEø^Ù+ñŽz[z¯ÚšW'§s¬ìk²â1QQOî…ÒϬYxé{NÞš¿ÐËæã‚‘œÏ„üÎì`C^.OæL"˜ùÖlc°]´Dú()ç¨S^]½ž“mœÄuBæù¸ÖbóÊÓ ‚ÏR–y;¦Eª8²Ëµ#[è‘Ü˨øíÑ~¬mĉåúa§Ô)£ž{·èJ1Ke®ðd¹G¹Ò—ÞF¥‡›ñ—)7Ù)š2ÚúÍ{K¹!½A.P®L½À¸ñ7cÇn¢FÙV#×ãf5oðZ¤oð!¦†§º°/ëFý  U÷p ?á„úø†»Ö|\¾—¹K¼Ÿµ)•C¾Q+ý2^$‰¡fIÏÇ׫§K¨ü ÝCVÝÝ8¨ý§ŠÑ \ô×ñ_Iûϧ8c¿ Ñ­¨èƶp"s>²œw98àoõG¨wxyöeŠwžýƒm#¼ç5·7‘CíDDMç*žP¯vߦŠÜä®eDºªU‹LV‘Ø€([’J‘ˆ®P%¨wgƩǓ‹~Äkµo‰\ ´– d¶?¨+ê_ ̬wwCѳÖø ™uŽù'¢bã’a ¾’Œ¶F—y^M(ÐÒÜÎã%Ïsd ŒçeûEý0 ûã3"â-óBnÖf~‘R¦= Çy#”#Îà[tL­Q'Ý9´Žu)-ÔÂ䛡s!ug`.$Ö†O@bWø H<–õ2¤> \¥Ó²Gã'_Èž‰’èü„ñ'†díçƒòœìl¯x5|žÿŠóº6õî$§ÜO´å½Šó½GqbÈ“èå—sÄ#bŸW´ éÚzÙùÂ5åxWPWqi^8æÅÀ ý| ·6©iÀQ’€Îglð{Òë §3Pî¬Y'@ê' NºHäÄbå'*Î(š,OÐ ²ò7å†`ž‡œ÷s^‡ðÆ4¤ƒ’ìéY‚oC‡,•AÙGK9Ù(6S#ÒЭ'†Ú…d>Õ:ëRMDÝì»’Ã ëËÔaîËê™hIØÐ’Cy-Ò-ý8nv“d-ôMz-„–%ž„`Wûß™ù7xÁÉ P¼Þ#êrñÜ‚j4øW»ÿ+*ÈLïcÛ¸ÃzïÈ=²½¾XŸg·VÛ;©ÌÇâ]sPæK´Û3½˜îMKãwAj!¾rĺ‘–"Ͼ™lÑÕ*FQuÞù¢u=hx3±“Y ÐŒrÿIñ—~Ùþ“ úþ:°/ÎŒ‚ðKæLÈ\˜:VSëCÐ;k= ò[ðRðg{m@~EsP®U^‡ò’ûÁ½ØÛ?‚c ½éB/âuuxtÖâॕ×@›Øn™ºÄE1àÿ®uc[¨ÄFˆ:øB ,@1¦„_a‰sC`‹d­Àåt³G„–Ѫ†_£›ü4´@n”m Ë{#bqnâ¼P?jǯ)z€IDAT1VÒ96*Ô{³Ê­ˆä¥áó bwx2”NÉz â{²ÖáWÌÉnŒRZ=ëÊÊÍ^ÏU±TVçõÊÙÈÌØ¦ÀÖÍéõ^¡uéìÄF&fÖÜF½`ºÉÅ\îTe6žqÔŠª –ËÀøPõqÕ{¼–hJWs°l¨þàÎò׈‹ÔÞ²«ª/s@<ç¯öî ÍÖ^ÞõŠ)7¸½ÄŠ¢7y÷ázû¸!VÉ÷âKÀ£\‚¯ˆõ(ÒÒ&S®õó;Ó´t)ªtÜwÔ|Ff'”\é%RúËîÞh¥±œø–yrbr‹(ôD #–sq,ƒ)ÌâÍòDàÎòZ™˜öKnÛDW.ϲ/0!'wY˃ð†Ì~ôÜ™åâ„j§¢d¯O½šU-þï´‡l'–¡þÞ0ˆŒ>õ%„üû.‚‚YíWBÀøëÈOÌƒÄÆO¶ÁOÍZ nÏÂÏ~0Þ%‚åòcÖÚÒ&¼:j_É‹‘‡Ó¹4ü{Ê½Í ‹eiƒIÜ“î‹%Ú¦Z‘#ŸOW¹%3 Ø”ÞȸS@Ö´j£¨-¬?™^™ EÝû@M¸]!ÉÜ j…ë€ù޼ R¿¥ç@AµÐ pâŠ~ l÷]Ðvñ=Tû3«øßú_Â1§" у—Að%ík8Ù=±”çÕ+ÀŸª®yJy´aÆnH õoõãàˆ~¼ûôAèæó §÷‚SŸäþÀ• ®^€OÝÀ;ÄœC‘ãì-g“þ[x7»#ãX,Ú¾s¯‰>ÍCñ=Ñø$VËèϺ2;§&VE“pf±ŸÕJ?Í%å9o@qŸ‚+ᔑÛyblÕbDò³Üê$“»Í»Pº-´æÌY•ZþV»7D÷;sÁЬíH³ƒý*^àëiã2»ÂÈrC}¢Uêºt¨­Eœå •:Ëú ¯/¨¶WªçŽGhü¨WøMAÑý¡ f{m°Îý˜â=4šŠ^r-3©Î.»1t@CH]ùä:wŽ×R튮,Ó¦¿DÎvåG7¨«ÀG {µ:ÜK·ÞùÆÍ÷R­7Ø;îà5Wv@z¢ñ)Xïé?’°2:(Î ¡ øŠø¥ì`8‚Ï=Ö^8~ªô aüäw.½^{ñ,Äu‹.‡†»ÿ†þ?)Oü¶ñ{Ó’:°wT¸ Žõ¾áS–z2”&Ëz'´˜@âžàdp~ v„ŠûÓ÷’ÜÿYÙ§øFŸTo¢U×Ç ˆtŽ[~8y-dýo¡µé7 :1s+„§¤ž† Ÿ&∮ªXÆP€ÐñÛ@o.Æ@`YE¤ö´#z~Ú帾<¼U˜}Kœ§´¨Z!ßR¤êø¥Ì*ë?Imµ÷'áì… Ùë°Á«Ï(ûXÖ…ÄÓÊKàß ö@ö`µ7 le‡4Ý‹dÌ}So$¶»õ4· éLW!¬”x2볂®Y\ýÒO×@¢ad $Þ -‡xàX(¹&Z åûòÞ‚ø/QN È;*ªçkPÒ¤ðmŠJÂ…T;~8x½¿ æÏÎbLǃ™áb]›žË›o“ǹž¹Ö]Ô }d§ º<½Œtpbf‰@›Ìjò·džC1{¥wƒq¯}½?0(E1~JÍd±þ­¿ŒGÍ;œóÙ`´²óÁ¬ç¶mkj4ßjëí¸Í¯7¢¾®Æ~…ç1"qx‘’ýøñ“öH”øìÍõÁPÓ]!œc¾ Æ|Ë„ ®ôó"u ¯;sÀˆŠ  ÷•G@_fvµžÁUÛ»ÇÑÔUJ¯+mE V*y+øRn¦>ÇxŽýÔu€^þ$ ¯7⽸΀æv€µ ³ ý6@z @r@²@ì1€DkL(ÿ *ºÓÒmôS ß™÷%ÔvN5¨r8ï0/´:Ctœ¹‚_È,¬à›âMÌÈù´¤Sà)ù3OGRúk|Ìáj¹-ØÇÌw1¦9+¬Q<ã$—úMº)í³N¥ŸgIhnæ)"5õžšŸ~“xðŠôÅd.wïCd}eÝåéA`¼î ƳîûØÁÜ®é‰<©?8Â)ýQWcš1Zl!n6M~OTÿC¾J_­³äçziú[.PŸõêÉyênu¹¯<›jìÏ̹²\„e¡_ƒše;¼­×O±OvªËr «¬ „hLƒ[”ÏA>!ÚBfr ÜŽb*±pMå0YÖ jM¹]y”Õršœ¯,ð6¦HÙL_÷¥ƒXã¨YǸܛlŒªŸý3†7ÜXN¡U_¬gk¦à±Ti¶0:ô1ÿe÷À±G6œÄÿÆÖ}béKÕÛ‰T¬@؃W£Ú½Œö,.›êÆøL,Ô…‰;CMx<3EKØsÝ0‹S˜Eyb¾} Ñx>jr¥Ö bI{TÔsÿ„ø¹â3(À?¥Kœ×!ýh #— ©ÆÉÎi›Ð!þEE覒™-VoËÑ>•ó,ØiïHF}!ðdV{°æ{_@bSæiÐnï„‚ kN„šójo‡œrìñ¡!àpk’ˆíz{9 GŒBÇ¢/¹„ET訢HLFú 8qHò‚ý7€l^|+¯Ì‚ÀDç)ˆÖ &Dßâ(D¯Ù¡ ÁÎ#`>‚ æ+¼ Z~ÝæbÐZ³÷JG4„ød€Lø€¿ ÎfÀ·ª;CÄÙì5çbóõ‹)Í>ZçR6†:q£l˜ÉF9мÕùQ=ÇXœ¹ˆGƒsÓ31Ä+™#iO†ìÒõ«v.À‰Ô´Û¢›wاHjKR'0ÄB1=r[Ò?D-ˆXö; þ̽x,5¼"%ï$'€suà&¿ç¶eKâ°+ü  < ÁMÞ‹ mñÐU¾$•Ÿ€6ÞoàLkžÑDyd6è +’„…ôž•!Ä o>¤vn¹Oëö}8ƒµ½`uºü^è¿"PÂÇþçÿ*ð¹?…¢_Á˜XX¡*Á(˜]Õá¸Úéƒhæ&s)_èš_!ÛhËÄlBÚd{$ÕTË w+Õòªúo‹MÅŠœÏf¹1nnÜM>"}ù”7pAŽÇ@nÙ -Åo¯h G‹Ô*œoíeõ梛9ù %îte®=Ã[‚f-Ñ›ƒ=)õ'dÚ([ ³‡¦:ê‰m ÝüF_èܱÙÞUk®tÿ™œ¡î§í·€¹Ü\ú\¥Ðß~”£Ê¥`Ž6±Ø»¼IVGÐË#o€Õªh58õö½„¯Ö;¸%÷Aç?dõnâÕ¼­r!KsöÒÑÞx¨o#¾ÏÚ›h$¾Œ¬LÌå£ð%‰0Växzfh~ª;2¸Õúa.³ê‚ù•úÝÎV0®rûƒ6ÀßêµþqPÚËm œ 4S4ð¢J¼ÉÚp÷‚û‡>œÅæ,°ºÖCúæÐu¾0´ +¹8ò1f²G´5ÄfFwÊï_E®ò$&hÄ7;/+QĹL+Þ(StMmÌ> õ65÷ãGg?¬¢Oc‹x´v{0›ûðÕÉñ”™ÅU2¥Œðl]×fSJâϳFi)+”OÍù9ß'OùWp}ÉâMÞ¯2‚íXwi) бã[ø £üq1÷úŠ¢b.ǼaÊ:¹ÞÍ/Ú)bòúœ?èf=žh‰çGO¢ZEÉ_Áêæþ N&‡†y«¯ÑÁ¨ò7 €ï@¾ºèøùÖ]÷É•¾„È·Lì­BîPÌîÆ—©@½Wîã&+ ú÷ÞG Ï—ÇAéOF]¡7! ]ïËubcúkù¶Rj6$_”{;–‚vBt——u и[f§ÞA™*¿Ž ç¨…àí6~¯º6¼[Å6p. ½ þ ö°ºé—€ÝÝX vÕ@op¯1\H»F;H½î NT] ÉÉ ñbðHì Ý ñf¡Í¨ý 'ÂkÉ”oF ”·Èúšêe{³æx¦q8Ë»§øR¥fÅÛ2 *ö‰6Pv…Ì@éõ~58ñtêg(Ù!³1ý2vÁ§tÁ(¸„UL,¸‡oó¦fi^Uå}Ùw²/5ÉxÇ|7ÑZtˆ6‹ŒHl‡ÂÕRpuhXê}¼ðŸ™jàXf˜=­î`>ì.í.w7èõ¼e 6òóA1dK [(À<1üÝj'ðžÔ>÷½78;ÀîØ„é‘Î ÿÆË)Âs䕉û£Ï°)þ[Ö#²q졈ê¶I,5sS“¼Ky½ì]²‰¼”$Y§ÞÅkTÚžH{?pØYԱǡAj .¤MòÁ}Y[Áãy÷Cõ@­6ø9'µ¦ÄCÓ“wâçü©Ÿ•ô» ?å?ÈWY íïºÐNµØ®<½2¹Šù …&æªÔ"d„toüÐÌÄ ã®ôBDèÍø;`ÌÌ» ¦z´…> ÄÇ &ÿuüUà€ÎN¿ÿƒÏÈy™Žâ yàsë½RùU72Spí?2ç°Tc%˜ªþl/av昵ÛdwD÷ž¶Ú#YdçâŠÉî1ÿ»'š1^ö·Š#!ëå[(},5ü.Þ.(¸Î¼dÊÿ›÷€ú0—€8J_“ÙÞ9 ‚ Œs¡ú°èp(síG¡"Û¹ «DËÁí¬¾©…²D@ÿ ¼˜~ n°q 2þr ¨¸Eþ`äâŠ9Ÿ1ìËÓéí=\ÅCb•yŒKÅýÁ/äz}åZ{R¤®p’‹ÄãTIÜ‘w’—oƒxë`â—DçC…™ £ !Ö.ü3WËê Å# rðíç²oÇŠOÎÚÎŽ¢Ks7ѦèXxóabËË[‹é/ïEõŠ÷„%"3J®Ëô€¸ŠÏÉ$!6-=HËþüÏ‘`v|ý8àj ]ÛžPâþ o0:xpÎÚWDz¡¬†ôGGzà«/çoÁKIOLŽ4Fêƒrá…ä ÄõÉi€ïï×!Kzíò¶¢î=Èü"í|‘}…Cä\,"'ÒÃoÏ9‡õ "ÓüZG#Þó^ƒÐ9¿'ZŠMÁc ‡#¹‘Ø}Ô ·HÌ‚p~27gXbJtO¼%z"¹Âm3§ »,5ÂïdêâD/)-B7òúS#rIq_~yý·Ñ$oóU}ÉnD£âo¡€S3—g~åH,+uµüyÉŸ°U+9ƒ:þÕ©ƒl÷ú§Þf›Ö;cðHà%ë2\÷ãÔb4y^f5®ÿgê8B ´ïFÕ;»/½-@lukCíõ '™)é!ø°Ò¬‡2s ðŠº ÜVKH H¹s*Üü×üÇÀ=ève›YÞ šF€]ËË…ò¡©æ½,Rä~u X§ü  ?™÷ýàÍUg>!ô2¸AõwP >ò.ó°;è @]šŽo÷6¯ÀóZ–¡‹S‘\¯†òÁVB#8ìÏ߈¦ßž•aº[+«OŠq¡~î‡Fx?~ `G⯇R«tpÎ(o—õ”ç„À‰—²ž†âÕ…Céyy-eëóš!NÞ™ó;Ž-ÜÂäŠùëxëÔÜð »Q|mJ›‰‹øÝóÏmÊ«ÁI-Ð2pÚÔÿDýЛâ×TËÕÆ~¶z«a¹ç‹gÄçN†¯zçâ8½ø]½ÄAGý˜{ Žñ©w1ûÓÀ¶ÜIN„rמºÖ7â.úè“„àX ÀŸCT>ÎI±Àb7¾,äqbþþVê%ö+ß2×=WßM z‡bs‡Št,ï§¿FËÐ[Êr(;®÷&¡Þ¤ ÿR‹/C«ÕN²Cñ…®µOÅ™*Jcí©YådE€’ì‹Ë}DîˆoÃ*,J|‹š]?1-§ùRÈz+þdýœˆBÖ­±Uõ¬Ff]oéX^̼Èìg°-PóÒ£ùî¯#?q¤ÊÞÚ ?W=°ôê±Fí˜i—»#¾½6Ñ%«ij‚¿2”òîË\¨uÓç'2ƒ‰›8¨ìJ-g¦XŸª%ƤÄv:]R ÓâÚ'h¦x[ÃAà¼r‹­€vLvÿ õ8M­Ï ÅNˆ©ñóUp ÈǼ$xcÜï ¼Zü$ÈÉò7—)c@îe=˜Uõw!Ò+´d]åˆ=l÷ó9s7¸“”©À4=Ô7þYU{ ¼„ñ+¸A=,,/h ò§À%à¾êbW¸%ø§ÂmöŠÈû‘Žæ°4sC´#ý˲ɉYEÚîT$P_K§åí¢[éàìŽP¢æÿ Å?æM„S2ÿS8q]Á#P$«&àÔÄ*yPÒ¯°*äé yô‘wÒuA?쬃È©&øz™5¡²!‚uì!`K·ã„; 7eŽ‚öˆïb™™TO2zZiOZ¿$=ž”ÖËíE\+ó¯#¡YuQÕ Ê½„µâtÊÃb BÑ´Gi¨ ‹ŸÏ%8Þ¥ò¢¡á"¡¶á Ýy˜ÞT°›l²D!«ymp|5}„&¤¢39AJ» é}â]„pÏI¤càn„÷7œÁÞà –kÀÞeîw…R Ö•…àôÌçýG°ãæ›`?£=‰ÁÕ`_´‘îúWˆø3þŒ–7‚’û‹GB¸YÙ s÷•C ×ç-›A÷þ:þý= åìß)ÞÐøä%¨Ç[…öc¤ž ß‹j¥‚é?ƒ¿#â2<-õE¨JºDÿ唟'ÛO†ð¢X'Èj¹?'n¬M »kbDZïAÖôx„Æ%ò T/³‚3ìAî•æOövTIw„ÀƒÎRF;¾•ºQèXò í¸ÕÛûE¼B¡÷ˆ,·dï" ØßÚ#þ]`½%_ƒ„êÏåq1%âI0ŠÔÕ 'iq}쥯Ös‘ý’¾8ª¼â×Ö¥If¿9ÏúÁ˜Šš^©[z6ü$¿0Cr€™±§²šB¬wöý{(ûO¨8ž+ ,?¯”NÈ7 ô‰|JfƒS ŸÂ*霗Âïh¿Ð·ék™ƒÜÜàÅÔö‡“©o¸Ðh–.§[øô4”H:s5Ø&Y¡íIV Ì!·½ÛÚÁ2 !pUfz¦û"׸ÂŒ¤Û³Â\è¼Ì°ÀŠt¾Ö»Ø·ÊÏŒ†þ2©/ó¿•ßkûý-«‰´lì_Ë8õqçe𦻅 xçŸyÍ@ã½ÊV3w¯*¯P›ªÚKò­üµ@©Ü ¨…"²H Ž(»L´†ô¹™Òìùz€3ŠZÁÇþñ+è;ô÷À¾XËo¹Vº¯ bªêª'¥îç«Ûü ÚKÊ&×2îQV»õ'øÔ~M?FÃÌu³S‹"u¸À©¥Ÿ@¤eÍlqþÝ5Éjõ™2ÄÀ¿Žÿ=ÇÁzzòp¤­w$ï ß ™¡1~4ÔRÃÍ}¼>Ô â×÷Crad22¹<’‰—F~ÁHþ\Áಯ£k0c¿dUãíøèP‘¬ˆÏ3fgš9ýø)þŽWB<¶>ó*Ñø}æoP~ ~1$Ž‚QäœÀ0\¹`v¦˜1>½1í@W9Z'm:“@ÙƒJúá+7±)W3•™DÀŽþ¤pÝÚ4Fqÿ¤ŠÓŽ(Ø-ð!cXo¤k#!ù5’‹P ùT̨‚+hÉÑÄÁŸ«•Aö²ª[¡ za;È«™¡öò!Õšáȵútw‰jW÷kÛ‰Ê%úur…ßBÝí—EîTûz—ÊÅ}Î(¥®È³ÛÈÏ´}û0²ÚGÙ÷"”=ÿEwÁ sé.X–I(­XöÁ`=H…ÍÝÈD&¼,=x¿|N(ŽŒ•G7r2y{ø)jÄúó¼+bc”9ISÜÅÒØçBfTy>NÅUrzY/5Tü nÒ¸sœ¼'³N´öAùHe$§;€xF6³A ˜C¯?ðˆ”ÇÀçN±s=¨Ï™—ƒ½È_ ‘=y>ì«ñ ä…òú@ÖášÀ“ö§ {-@Š·A¹W,‘‡A©ý"(—h£A)9 úcr2xO¼âõq°GXwB¼ÖÉÙ˜~ðàöd”»*~­fòV0§ò(D6s Bé€ÀO'ŒÁzK}€V¹ãáe;€ œ¾‹Ô»À;༠àÐGä8ÚQã:dý˜ßŠ?#7èäÀ`w²ÝcæÕ†a­KÌ‹ÓOB`Búw> ON­f‘¹+S›Ï¢3 ÈD榫a¨yÖí(¬Rd iê„6Ím ¡R·.Û¿ƒ¶_€À‡N ´AîIÐ6:wƒöž[ú7nOPgx)Ð~‘k@tñõÿPWy{_älðoW·€ºANæŠçA¾n ÞNÿ×G–€2NäLk*Xw“@¾Ìžoƒ=Oyì;Ìñà|§ w¢1ì'Ôw!Y4°\·$Ô‚ÿIÄ¿ ¬ßC¬Í‚±ª¿µ˜¯g·µ\þJõÔݸډÀ64uCæ\–©-ͯäA¥½ÚLV£üV.$iìò "ñer+ »Ê­½/ý‡™˜'#¸ÊuüˆF/ª{8 TÛ€fÂ@JO¤2)\ª‹ÕƒòUÅD·Ê•2J|…¥²õ»‰KQܱ‰ p—Dî÷u¿#8{íÁêž)÷ž`]È<›Ö ÕÅJì‰P%Ýtˆanäón#ð¥ß…À9w‚7 ñ2å½ ÁfŸ€»8Q€tw'_G(å6h»A~ÏçxV‡¢Î¨j÷d;æ30:0RœàÏÐÙ™úFUa9C•úN{,÷˜c­×8 ÿèì"_Ÿí4¦Ž®»31ôÞ m‚—…®,óm„v®×Äùþ\PÖQÉ¥ò8‚"aš(Qj‚T6‚ßP©þvÍ7 EÀë{Á©«×Ç7æpÂÞ`î ªuÜ)_³;ˆjÖRÿkH½Á/Ü–üQÜF«ô{ÊõŒF˱ƒÃ#QÌ×Í^ 4pN"”œ§AÛç A¨Ùæ[u‹k"TKy”cꥂ"îöó÷3U4” ñsgùëPJ~•ðÔýø¨…»å:>CÊ™{ŸsX˜ÞÎ,1D4ÄŒ~(j€ú"×BE+¡7Z™LÜï®´&ÊyâbYj§hãwV_Â÷j:sPÜŽÊ𲃷@_9…Ã_¾Pûýõ@.Yºjì\trØ8ôî|ÐÇ;O‚f8@»Ä ´rß}`f)({D;ЖÊ٠γ¿u4ëHŠíÞ8ÂʾŒFŵŸ*Wéýe>ZÅQæÉ¸ £h.Â(hì"€.ÖâcܪhD•ËÈ‘ Ý/@žTzƒw­:äBñ¸î¯«q;xª¿ƒ7Xí ÎCjpziýÀÙ§Œk±q#صƒ€û‰^¬]F 2ªÑR¿‚}¾YRc½!9'X ©¾Á9ú"4Tñ¡P×Ä_R;¦ûp!«ÔÉȘ—>ÓœO ýLè3(—ΈeèSCkq35ÑÃÝì <••­ÀñH]¾âýÈn.ĉl&ÏNÑÄûA­m̬åUãRkºXøÞNqµÙé§ŸkwBÕ7¹@Ëò @MxUA=êG@)£:0@ìA¹FÜ~HÕÀ/UÏ÷'Í·™v ÜGŒ6ØvµÀÛÖHón>Ê|bNô›Û‹´Îv÷g¬t"åñ¸œø÷âqˆEIAÅfš à·C€Œ¿:߯‚‚â7BÃs2”!R>-8QxMÁ×^"nDø½Áú~{Dø})v8!JÂ+’ÚË%\«­ŒËŒõ™ÁtÒ—d~c@0×~‡{ÂÛ­¸ ë{4½Z¦Ìë½[ t_¦ hj dßa Îë)Qí¯ã€ÜÝÊŸ9q¿oÝ‚–sI:Š¢ÖÉì`µ<ǪÎ@e½e²ÕÏdvaÑÔ¾ Sì²m¤ÌµßDˆ>N{P:9 ËúTy iŸ´ª#ü›ßÀ{Ç} Ì[x´ÍÔ†äµö}@3¯èu••Hã|e ‚ò"YV[ÿkð»1ü•AyEýô#ÚÛ®ê×i©5!PlÞwÊ p6i K_ ê9Æ'`mÕ¶ƒXo¾ÖAóRïÅQûWa¸›ÌÏ8GÚ¡]|íô Ma˜¬}à¼ÖDÕt^dÄSzϼ‹—¨È^‚{7ا<½/~iöbËÿr´¸qt‡Oh¹7Qµ,™³„+ËÍܼ[Ô=k˜¿7Y[é›ìbSñUé÷iUz»ÿ,””w1ˆ Õ_‚Ò®î{P~ÜŸ)}!9’ï!úkÞ#5#m ?úœ×Œ´ÚwO€ûvz&D29çƒÿ‡ý.ø/z[ øPnÈYÞIÐoÓ«Aä =®‚Û&µ ”?yÄζø @öôËÀGÞþ4zƒr~$_9ÚÔe¿AäTÈ‡ì÷Ô9øá¡,%“½FiJ(ë%ñ™_347òPb(sƒÇ[YžóNl5„»%֓ɾ$µ’@Îm±ê¼0ù dÝiÙ³Ÿ@èDò„S©‘Zj †ÈÌä>ÜМL´à7%I"¡ýÉ]¦}Í‘'Ñ…æßÄ?ñ%r*|~YêÊã 3kyNä:ù¼®¬´Æ’pOÙíTý.÷. }?¸_Ú×ñ‚?|ݾÄ'ÞÛàê,¥«ñ–;XíŸù­w(–¿üÍn?P~¡xo¸€ÚG„@™B{pæ[Áiê´ån5Ær#Ì•Ó!yYJù­œ ÑeÑ& }kl€Š©I´_´0h)ã'p÷Ë‹@]dŽïy3¸‡x´ÌRp|å5Pž5–ƒû¥’ ôÔ¯RÆÇà^ Â—ýÌÅøJKóc4YdöÁó·˜KQ½õfg¾öç·¨/›ò‡V¢¾â´0Bê·ÈÜÌUÊ´x–1+‘•½3u{èH‚m bMø"H*‘Oñ*. m ,ˆ^AAæòȸ±Aú3Nsë9 jUÐÃ,­×Á¢®ý|øÉ›'³¹Lkáö#£MqÇ£)¥þhê#î3,QÎõ7“Ë~€÷ÍNò†1ÔB–ò±aq‹Ñ^SLåvnÇæ5þ¤œÑr¦8‡HáRÄOd@¾‰²H¹!ÖøocÙ1e ¹zž°H>ÈhÊÝ$xFÛBBXüN©õ†à5ÿ7õvvè­Õ­Ê·xVuå32Vqf'áŠ7“À¬ž™á÷3ã ÚÕz Â[Ò!0·cî,ó÷ôÜïî€ök`öLý@Úk]D0Ðß[ïÑ'\ñ9ÏðUËÆJuFÿuä{×!ý)‡êp¢|cHê‘ôb<ñAæ*TõSÆ’¯å.Vë·ºWÉ,q¿qžwœÚ©ïÜ)ÌÒ_ð>å'ù®7ËêÝÁ5ÞrÐß’3SÙ Ö§*x¯y*øùn?®§À5Ýz ‡úuÀýØ}ÔÙ F–ÖR#ÓU!ûšˆ å½caPg0ø—ʘbÜyƒ²c`Çœ}P1'ñXßÛhwkAùS½´µÚ&pÓÞ¹ le4È» ƒ PiõA®Tnå!e*øÇÅ `ï•3@¬Ò¾u³¶ ìËÅN QG ^‰ú+žò•VÕpô—ùÖ~J,÷ÔçQæ ×$ÇùPï€pjj?ƒ]]¿ŒàÄôMà|¯O+x´mÊ*^çEª7Êʹò6ÐÉëAiëvÊe)®ò½«’R^÷ÛSNßÀkœ0j[?²M6CÉSÖ¤ž¡£ †¾¡Àø¡|R® .A(”¾ µ‡“Ä5¼qÀòP kYo‹ÉùUzrNúUyV„Ø''Ê›Éæ¤BMZÊ8U¨Ã²E ýr²¨Y0TsΩéÔ$é{(²}ài ¨dƒ\äÜþOá} ÞOu?'0ä¹üËÕ_€ÅàÿîEÁï¦4¿^d¹ß<]ûäåðÏQ†ƒÿ”6øÎ? v83ß}Û¾šŒæ¶C+Ø…ü;G­'Å{ë*ÝRÖý°jƒ;Ié¾ÁNàe´a`]x“Œ7AßͱÔt·.zùòÔ9Dü²t”@°¿ÕÓÜ`I”ðäÌT0mû90k%]Ð~²[!)oÂøÕ=ÌYî(Ð{§" ä1Ћ¬W@?êOÇQïvy\=¤½ëÏâS{¸{>è'ü6ÀÿÒÚ.Û!•åCˆÀhj€9ž «i ÉvòZÈŒâ0èW)€”ª·TYêÃÚÇ$¼ß” DäSJŽüFÏ¥»ÓGiçž0ÞAu®R/[5WƒÕÌtÁöÍd U!S< é.ÁZY² U=t$Ÿ …d¯pH¾y*R¡»@?ŸIPû{ûˆLv Áȳºƒ²Á½iDœ"„‰[æýö :Î ¤n:Bïàíc×tát­ÌÿW;–BJÛîCRÛg·$¥ðk²UÛ£=,UÞ²—ùëD®<àr»—gv¾oÈõ{‚{ŽÛÄçÞ/lÖodçù»½Æàäû @í¿E‰¼ÝÿŒC2*ßÃSR¢-'¸Úo†É)ÖŠl@ÐP‘â8 ÑD#¥ ¼/å½¾üNÀx\íƒç&’$ETd°ü‡Õ0½ƒbÏ©÷« 9…¦ÜÆTÖ©i?k[I¹auõÔ'Ôñ|(Ú)ÿ65W¨þsbœ+¤nÐàÔ/ø”NæÏ*åÑ¿ŽÿX>Ž,ÜcSj¿î‚ë6–‰x×臉xokÕë'®G7ŠÀo§ÔëBe8Ëô9H÷ >Ûë¦÷Âôlu"7§Ò»r®»RÂsÖ•úªùíØïÎS«‘râBB™[ÊoïƒÐ|p¦x£Áë¿Ôýë@9J[Pv′—(Gp@I ‚²ˆ8A`:ˆ¥X ê#AÎ"² r1€ŒøÛ‘ààƒ<À»À‹xí¼AN{÷\»€Óì"æ‚;Q¹£wƒqƒ£Dy 4‡ý Õ;@ÜÀU‘a *þÐÖr RUxÚub mŸVÀ\eb| W*d ®»‹sC¿º­ðÜ @káÖFQWùÕ±µQn?ÒZÜiOZÙà·¦\ÿØ}‡êƒi05• 43ûqŒÚ¿/R=žî…Pjyk@5ô|пOæb«ÍÄ q®^…yTÈkå ²Ýî|­ì™/ÜiHc«üEîr/õçŠÁÁÙb?Ï”µ°¶cf9Úã„íNîtÂR£>5rºiÍQܲŒà©¶é+ÞÙI‚§güD1ð!µ!ô©ödõÕ¯1M솲ëÜ}¿ò)Ò\¬} ^‚°Ý«Å˜æ*5Ëì6îäNÑÛÔéêD,»…ØÉX%É`c–bù}Ó?ÐÞwÔÖZE4ýëø/ åë«›ÊÕ¸6°ìÎWÁî¤=±eÁÁÈL‡`+<ûÍ`s´äåÁóy¡¬Uè~Jú‘E,Kd™ÝÿUë› ¸“žØÁý¢žÜlv0ÊíÍJ#eVú5Þ7We㫬‹Òż.~·¯ã¬û­EXægv7ÌàSéBÐãÖ; ÷@h„}Œ½Ö ½k_Æ(ù&Ò˜ï‡PnT?cIæ Pk»Ï€vþè"¡R]Ù êq¹”ïË|W<ê|ûyPªxóAŒ©¸dÌÛ Ô¤7P% /ßâ•ðÝ f+w—›H€;Q+.?^yz?8?kuÁ»&8üç• Á.Unû.£;xŸËÏ!ÙwÀÏÐñáÀÇ ÿðÏ8ÿW€B Sœ$ˆe3àÐ €}¤¨<…®ò}ÿ\×õœ³Z ¸@ àp:Bô·é_½õÿDÞYeåÊYOT>`2ð;àù—­­üõQ*Ïm­¼Ã*€Èÿ¸î?Úëñ ²èϧ@.ð&gÆOÿoÕ^€“H@bâ4oÎ.Ϧý†è…˜8@K `< p9þéÚÏFl] ƒœúË}€ýÀ~êõÿe«Îž;8¤èc°‹õ@†&@.š€‡à RæPySÁ<¹@¼Ív ï€?ÕHyäÙòE *š&‹ß¯:*—üƒ;â,ÞŸ÷ŸJ ¤ |$p«˜”óPxÚ©0ìŸjû¯È$ à°0½1¶<<Ë"À•GMl ;ðïgÕÿœÎ–z< xL4ž.äà61pÉ´¿ÐÓÿžT9Ó&èÀ#Üì§ð4/Mpó/K»¿†ä¦#Äíò€fEïûCX®ó‡ÓÇä 1\vÅñ‡ùµÑ•åHÊä~7É(’¦r"øCä1_ö1UöGú+d¡ó¯•¿ú6e§2'œRrÄ@q+Y¦¢U#[LãE²ÝRïDú mSÅ× ,OA°L/1G™¾ÆµàÜí¶TùÄûÊ`ðžög£äJ¾­Úì?”­J¢ø‹O@í¦Ø g‹± W( ‰û׉oó²r±L)—)‹Ä»~ñ/*牌ò*ÞkâY„¼«(ôŽ™ ÉöRNðK• ðwªóÁ?Ì ðÖi­ÀJÙ²•ú i«‰ú&AûEu$ß»×3Ù'oÅq¿›Ñükä÷}ŠÀ›Eü·©Ï=‘Þ8Z üm$ÁëÌ;ØyôgÍßr’–òe„£ƒ|×Ûê‹êÇ ñw€b+ãýçE(·w¡=DUj€ªi7õèìï@ÐhÁ¹ / T·×Þ¾üîEÞfPËRPï*¨W«IP¯ä$R wû±U]ªÔ“¿ŠûÕ[¼.ôQêûÕØ¥mõ“XÚÛÞý˜2åuÇ@w.À·r¨“}ÊMþ§ ’@ÝáC*ß{[A§l T¼m¢«òQ^;޲2û VR•F4åÄß ùÇ Èi$½\©’£¾‹ëבMÙËn$åËøâb¨~Pþò#Ù”“bˆ/9 <ÌnðKü¡ d‹À]ä}£¶Vª ñw ¨%÷üœ6 |*^·“÷"˜kô™à-ñûu•õ)(5”±`~ed@µÚ€×ÅkÖFû¨ãµ—ÁÈÓ_ï*Ï1”<¥)¸;½> ~¥¾2 oáeûEäGòÙâ$ð¤x Ü+ýwAi¡ÔQ DÄx`x¨`1ˆkÄ<ÿ%z úÅ8橈?i"> ˜|ï+¾”?‹Ú´W+øRȇPä«jlÞSV§‡lÁ~Oˆúì÷'‰ì‘!e4‡ùA²×R|([smy}atàz²År¿„9ßî"ëñŠÚŒýb¹º‰lb¹|@¼.·PÈ ¥ˆœÏ^ŽpޏŸ.Be*ûåLTyD ÅUÙéóޏ—ˆçÈAWÉÆà½!:‚ØBP‹ð+»€í<¼,ÖƒúŽ‹ç æ¤¬Ìµ¹›É nA^Åí ,—ãм]â Rêy\NÌëK}<1B؈y Bó&øCQ¼«_½˜8ªÚJN9DNQOÞ DØ"*k‚ØÈ5 Ö‹¸Ìs-4q¡˜Á%,æOÖ“m\ËíÌP=Þáî¿‹ÿÿtu¸Àv4à3^ž•§W¤\ZÐ €*ÿî×ÿU­ÿÓVAŠb`? Z´²iÈÒ{þo‘ø(€Â`.¯²ø °0áï‡"p‘@$9,g*pO5øWG<ù§Ûfåd°÷Û'Áše¥@\.N@`·9ô,£K(F¥œR¾ ‡<.àœÿÀ÷ÿ8.ðÜ\/~æp\rdH‰4Оր‰ „Ä9@FœÁŽ€¤à‘ý²òJëÇ€4UbbÀ)NÅôªÓ¸•3Vçß$颃èŽ,ÿâÂ#¨ìd$Pƒ œ™•Úì¿Gf¥Mû'P©½Á6 òè¾ 4 s€ú4êpÈÆòÐàŒ=z¶–[ùÙ8kÜ*wÅ•žõù°ØH7à\€¤5 h pþ›Üø€o3öZGàŒ× ÓYíûW…3ÖPœo€R͸Pxã¿Ñ®ôîü;;¥þ?@ÕðQ)úÉ? ø`5Ç ÌêqP“ª@ $ƒ€wÜâÙ–»L| 3x ôþÍrÿÿY˜XÀM˜Àåôq3à2Ð8œ‘{'33æ¯ê'O¿§òJy ¬Œuüåþ— ß¤·­­ÖÄ#¢6¢ÏÿyLÎ^ ~N2ÊÛ§µîJç{sÒ§û gÖ’Ê~øgÕs¶Üª|€g=¯üæÁp%IË©@gјG ŸVlú[#SÀÚ³Úš@u €ÿÌa6`0ŒªWêIØ€ƒÁ×Wùÿ>ýOµ³ÿw©Òߨ çwÀ¥; öeV®qYÀ™™w¶×öïÊïŸøTYg%Ž3g•åÄð›S€ èDTú,!ˆgÕYÙªÿJoöÏ*+)œñˆW¶§-ü£Îÿ@ÿ*ðï»ê*:ð³<^Ծȡ5¨Ì¹H±:”ây¸x€D¶°4ÕYFºär=p‰?‘?iÍ|‹Fˆ\àI ®=íÜÍÚƒÃ9ÔB§ù@†€‚EH“bìÒÔb8@i ø´h¨ç(p "4./`¡SAŽãÊߨ €bØ|6#¨J MNä$EÜÀ T ü"ê“!#ú³Ÿ t¦)Oâãs/Êi…X=ípOr ÂÔ¥„§ä…”x%V.åÊ<­1qD›I‚S"E!5IQ)d$°ä|ö hK1›ØC;ù$¡Êóår|‰óPijD€vÔºR¨CS  u—(PN.Pz:ÄS€K§°€£|ö#Á@ Ò¨~Z˜æ&1À$DÈA € 8kÀÀC%Ž‡ŠŠ´ÂÖ➤肋Dâ#åv@9­¨”D²‡0 Á|4ŸQ É.@ Ì7¢ÛÙ&úRŸ ¨F€Ë€†àL(¥æßšÜ@÷¯ð#pœ2 *7àsŒc(,gÈÇБ =8Ì8y˜_Å@¾ QúПl<*Ý ‹ÃI¤¨Â.²åtš»‹íw±EwñIµØXƒBUÆ*æé€@¥ êÀàLx¦KÀå M°ù¨ÁvÀ¥DU²AÆÑ ¨† D‰©¸ÔšQ(¤ P€þÞÕ œY¸Oœ%ŠÎˆ(ÐÐ"Þ¿…û,8ã¬7Áâm|½¹þ(OkMP T,2”b ï´p›! ¶±×ØF_ð9aþ$< î J àB@œ1“=4À&8 I‡tÊèÌ33Œã'Ÿ)”ó1ŽãàQÎ! `ûY¼¯4Î*UJQëŸ5&•O*ÕœdD˜@gúuÉ*[\ -m±1Q0è@šGx”“(äÒ‰WyƒRö“¡û0‰FЈ (@là\6iâ€Fàr¦ã)ÿìøÿ’ªQ "ŠPÿ)ü{öÒóÏ*ÐÙh¨4-§0@> À¢€Zgñ¬R- N_w$® ÁY5WCŸÕ†½|˳Êýg^e/C実3øƒN›‚ÿÚõ)EÚÐÜ+Ü7ÀuÜùàïðŸÃ6Zš†VSõ¸‡áœ¤: rKã¿fŸýöS§Ûl ISð¢@*ïÓ9ß\À%†Ä ç´;Lùw£X©Êü§*ÂÿÝö5 Â6ã:gÌÂÿ®x6Ï’%ØêS‰dƒ"Šþzòo¡óÿ¬oŸÈöÌÎ çñ#€3îÑ¿¢VÿORþïÑÙjç?ß­à>* ~;HÈe%P©×”­ÕâP øçÑ?›»{HgfÙY¼ü;è©”äóåÏ `)ÖŸâ9ÐüéŸ1ô¿EÿÞ·Ž¤Ài“çï˜qI@2‹¡Þ^|o¸«pŒVt£ˆÆôFU®Õ»bŠáÊí¤ã„P©ÎNlj³ƒcñuÈÂÇ!‚B†8 & G8Êq 9 €ìÀ'€@ÁÂjPèI'à8'€lJ©"„ƒ "$±…à#‰: bþãy> „2ÔÓé( •i:!@#ä‘…ä:)B@9 ” PDÂ~AVù#U|I„øÉvþÀ¤B„‘dâtjVe²@—ãXþOöqªz»c”xŽû1½Õ-ãhâþ² ª–9%Yœ(OWŒdΉ¥Å“eÕÝþûl÷E Æ1ZÞ¯n¬w[­ûÅáz¿Ö¾‹· ¯ÎG4ÇŠãšì=9#Ù“S-w ‚U#ƒ‘F®Ñ¡ÍÓ_5¥uGR[ÍEjWÒ AaeËi­¨ÒqR)É* ñÊõüàYÿ={ªœ!•t¥¦2õ©R"V"Ú8뛕IR•&ïqàŒ|èœä\ÎHã¿F¾|LÞʇ«[ÿq§Ü‹ýÁZåW´È×á¹ä›×¡›wÉèkt“œÀÈП„‚iÍ5Fr\ùLÝI†ýâÅÓéo•e¥cé7àß{ä^’Ô IâJ,àBB@7$И æi}ÊÜÓYæq$>a< ‚.g’TÂgñÇ?ý. 2ƒa¢Q™h"e D!­ þǨ¥OkÎ&gœ dqr€r ‡B „<à$Aà5€#TJ© T^xè"€öTUIŽ%œNP ¬"‰”[È x•]b¹œË§¥}eïNž…b€+WË;ˆû ½½8ÞZw3ëÖäXbéPúsˆïˆÁN·´ÁâŸË>@‰/_@&eÞmˆÜƒÙO1v…8ÁYÁ’Zý £kÀ@êsõuxJ¡R„®ýatåeÈÏåu ìÑžLù$`ŽEÐpDŽú ¶(` až¹Ò_‰*ïp©GSlò¸“Oø¤åÿ ò @ÈÿW2þãþ(n{»¸=Ü0ΙQhn©7?½1}™2+H+¯…˜Í?lUEôû;wð'³¹–Iò=ßÇe“üO«/’EšaD â!hÔDETàß s%¿óUh&§³™®r?I‚Ô§99\ŽO„lª ÐKt¤œÄiOD:)ºâP‡G†Ý@£RT0èH,,t¹•Ài/ƒÂ!TNà£"ðñð±pIà ÉÇã!>¶¨ƒM‡ú¨d(Ä&Oˆ4u¤ˆ"©@¢ÄJQ¨tç¹”â CG¡* pÉÁÅ&2TÂxøD)ÃCgÕÈE!Ì!ÂògT"|MM E”‡Ä…©NYTÁÃ@¢R|úú×J"$ŸëPˆIU^…íÏsê÷¿u}ŽzªÛ”@zqê3d|MY’t¬m,‡¢ò~e—â场U>¿gÌ¡8ŸŠÆÊÍbyíXÕÝD«,œˆ•›É ‘‰šY+†ó#×Pº5:˜Ó¬%¡îÖR]ôQïe“2Jsi"ö)%”ˆ=<$ ˆÓR.}–ô.?KURmšg4”MgIø‚³$ge¤ÚiÙgô½ÀY5˳~uŒCÀ¯Ô²ÿ¦eñ#p&4å’ê€8ýöl~”KhÈoþ6BÜ.&Sš\H6!êP‹f4&Dꑤ‘f; TvDcY(lÇÅpÁ^¢ÀAª[q\Ñ¢Á?v0»€h@˜*@U¬:sˆfœHsÆkçS „ñN×)‰ÁEÄǧ  QY‚J|6QÆNòðÑ@t¥›$4 ÊÅ"À^²È:­™Tê3ë€3¾»Ò³ð¼í¬Ùq6ÕΤkV®n•Iô᳞?kNUÎèH•eþ¿q@äg¼,ÿDÿ*Pʧ.=bAbÙ±_ ®– ¥_œ,„ß}Ä»jª.®y ¢Ïe…èÀè ˆTÏ­Šú3÷1 õXVKîe“1‹V†ŠI\´Ç昗y”ò8H¢€`-€3B ‡€#‹‰¡°@f+Y†JB\ Œ”E@ˆ$P D€*§Y  8$jpÆ-xP.fŠøX|$‹jø"‰Î¯(@؇Þ*…XŒNxÜÍTZ3£|å½Ê:t».Š}5š×0Ñ?1èÔJÔx¬Ü†ÄŒä½Pòü©íP:bÿý]úª¬…ì±ùÏAhDîíØÅyÕ0ŒªYÃh%F‡¦ÑŒ7ù„Öju~árÈ%ƒ:!8“Ë òô_°›»@VÈË€Ôzщªø´¢:’&¢*õ1€<ΪPdQSŸžT•°üûèÔ™x˜þîø§K H± 8DÉ)öã³KEe#°ä¯H`’˜Ï0žFˆ*Øx4Ä ‡ÏIT~V#üʵìæ%"œË2öP–~éŽKI„úhõ@4<­þ5òð\‡J/ùR¶÷â³”Qù‡m¢©¤$ bq û¹ƒ^Ô§íþ)&Ñ4³€2šHAboÉcØeCNL"]Ú±¼!9Çî=: ûPƒCHg-ÍzjM­WY—gÝÁÃæê©Mnðò m»¹‚²À‘©3ÌêhêÍZ[b®Ú“lQUï@‚´2 r Ô.(o ‚x—3ÆgÞ鱪D°daƒÜŽ þºÓ|¼ó /|÷]@ñç£É)nðk¸o‚c&Y›x’w&BêÇä*H×Ïô‡ÌÔ̈½^üÄï?Ñôê¯P¥Iõaø j=…ˆÜ™s#R_… |›û ªñrÖxlq(`¾r•*É#¥åÒ™ÁìCcài‘1 ˆLÂHΡXî&Êoä’ÆAŽâe-2ä×QÑx ]䈖ԡ1Vâ“OeÙ} L9Ãi@7/6Ü’É?(é‰y”ˆ?“+YùœíA‰Üœs ^úìü>üsœùá&¬«8¥î/Q»ä•²¥ñrÞ/Û;}v©'I…oÏÌÄ /ÎÞcNˆÎÂÕjFøš.'Ö™—oÐ%ˆ²ˆ1TÎàGöúmä­Øâ%f` ŠC r hD#ÑhN# Î’\‚¿‹×÷×Ô›É߀Èõ‘‡„0:`a’"àW›8P…8P– rÃÇåiiix\'@”“@ ¤“Ž…Ao’ôBÿ_vÌÿGßïýœZŠzróÛ õ~a üÖVg¤ö²r•sƒËàtdD¹SÜ\R&êFí{PZ»uc[}x—ߛ۸^°½žÀj€Â§ÀFL ZÖsÑjÈ´_9™Ù;Y^úx´¬ÇJþ·—¹x8#û#ÔPìAìÖ> ¹èÊQó}^W>6—±œÙj>ðð7QâàŸ`Þ"`3s©4î¹I $ JßèN5ù;®Ô‰ o° 5Ò(7za€B&÷Åüï£[õÆ[¸>í†Ýë€ÏeÀ¿± ®çœù€sƒ›üD$°pB Ap•Ç.áþÇý9FÜðÉë™ÛõYÖ,j°ŒkÒ²KsÚi÷¡?ËÎD³œÂ1óò0ÅæîB-èû \>{þfÈMÏ» ò²ã­à\Î¥‡á|"ÿÈkð!çBÆ-è.߀ð÷ÚaÈ<ù2gL‡È¯n龂÷—@¸U¨hªƒ t*í&P³CBgA%dƒú@<"¾q3:¨ã·ƒvܬ¾ëMww2^O÷`!=AžP²Àig×ËŠ5FºCüóˆÔÏñOñ ÞˆÄàD‘| ù$N¦fCñºäÓP”ŒÕ†Ü ßE–˜\/þ8Uµºé_˜¿gýž×.OýuªS+þ {eµ…ÐÚ’/¶70W¬-E3¼ÎbåPd#K8:ÄPª©s9ìDAÒ˜š  àó pýHÊè?®×í,ý¿\Ãÿáþgœ÷ÿ6.*ß2„©TÆå ÊévM6u¥®?ÁîEŽ¿39é?å¯DØC »âÅû_ž‹¿õZM(|û¢ùW¯œ†kçv‡Â˱Öp-^ôÞÕ¢Q¨W?Š=Ï&å÷gsè…’µèTålÅ_ùJ©—L²Ðн?±3[D{£…ŸÕŸ@¤…ƒÕѪÑåzC[ ÑQÓ!\9}+~Ôˉx*úž©Fú2Oç4'¬®´"©7ÿÀ¿‹’HqA)Ïn!ÌïhÏCþ§H1Wù Ä8£7’gùU^·Ï GêgÈ|ÑÉ>9!K;»(’ƒý¯ñùK4Æ’Åîãhò€÷"¦<äíÆpC©ŸH¹R“P­…Û d¾­ª2Ôø7˜ç¿ãd‚5&¿"ªÒSyÔËZEвC‡(`‰1S¤ØÉ-hŒÏE@¹‘©ä G97`¾ üŒ¼¡Ü "ù ˆp±(G!P¨ˆ†GI T²ñ0Yü]·ùä‚ÿ=IEãï."äãù8üM »ˆ ¥:p’j€C}  |t A:q.r˜ çYŠ‚ËÀvFýÇÛ‚ë%í! ÂHàñä³|¼°¤Ü„ Ö˜Ø:¸òÒ‰7¡p÷µJàž±öWesPVŠ8(]”e ¾ð×AdAviŽÆ@{Hÿ"åJÜÆÉP¦|Ôé†êh­1¨ûŸ@©®§ãŠÚOhÊ»úl}´ú@ePN½ÞSxÿ]Qüÿµ¥]ˆ:[Á=–ú üþî:¤\ïWÆ—âˆ×Dž2]«GDÞŒô¢¾ºåò ’Žâ6|²øä#Q1Á)|§I¡qœP–[QüÝÖ]¨r¼ì‹"ƒòKT³FFà*3þëÿO@S*ìê÷ú—p¨ÔÚ¦på‰k:÷oÊæl¢”iá~0š¸=!2Dÿr*ÏBÉgB(,±0ûÒKæ–Y(¯e=Wå~QèþÊ—ýJbZ™æâ~ÎfÌõR!ôD†¦"t’ú,7ßVƳ^ÉÓ³MÝI¿iào<ãºù_ÂÿxòOÉ?Çõïy=9»R\ǯ7Ø®‚H¼Ö, ß[JS2¥Åƒ^ÙFICìEÄSÏâÇ~Q¬">áü•úê¯Ï…nbZjÒ™2Ä Ö^˜OøÜ·g~„³/Ÿÿ.+Þy¯;Ë!5Ð{œ, !8(ò6h%r×@D¤^€Ò‡²ÇB–< 9c³ÛÏ©˜$œa”i*Ÿˆd•yȦýUõk/‚Yý¹“ž9ùrGCâfîOT’`VÒs´² 8CP,þ ìŸhÛujÿ?~ãë©sá?~Ëë›õuÆNÑ|ÒãN@½! ô׋£1à2E@)Â\–¯±‡Rî5¤\á­¦­}Ø-6P½Dq¼ƒ‘×EQ¤zöfí[{þ©îô-ªuªNÞç—¢çwµÛà5¹ý«ÇPô“¬VÒ‘B:bq0YÍEÈ)ãœÊ.òC ^WS©h¤R“Z׋çý—NÐ/¿×ñ—°ÏÍ;¼ãÄç'«ÂñkWl8S·°œ«X©«æc  Èù¢~p7(2# Oú{ úeàMH›˜i·fþáÁ‘`œ0@Q¨Fð!P“Jô‹Á ~þÄ*Ñ߆Ü”àG §ú.xÉÄà NÞ Žæg½;¶ì·ì7!Ñ·ànˆJî‚ÂpÁpœÂÜäPôk ’PðRò"½êUÌý ?–/rY¾i"­”•3©ïá¯Y• tJD¦­ý…šY9£Û£±¬U"Ó£»¹5ôD…—8ê’õ=¥sÊÈ(Yµ—7—Á¸_—ºÁÓâ 2š«·@~¤*`þúú§ÜQŒ=À§òú†w(‡4$Ô¦ˆë ™Ô&A# j`åð€Ú "Òè(¤¡!¨t#ÕúÏÙú¤ñŸÅRÁõÂ%ìåDR$gIà“‡‡J.>p8ˆ@€<Ž ¡ ’Ó7¸„‰ãqˆÊ(쥬å4PòÀ·DÿÃ’¡ã¿°ÿëÌÂèäÊÊx,MQÙIE`u@.ä)<êR™«BÅ'ˆAòFÈSÌnæ.Úùë°¼îÊÃÈ{‡Oí£ûLê-*ÙOÔ£¤_3Þƒ&ú„ð· Ž ä‚z:ô&(¡0(3Åa •þ6ÐV«´»r¨ ô>Ø@.¨OÈ£¸p̹ÎÞ,‰Áuo“î`¬» pp[" ¯;ü¹t¿œï‡ü…y_9ŸaÙkcß°ÒÖŠ÷Ù¥ca²ã®'‘2Sâ]b]QгbQˆµ-ž‡,˜Û‹_\d·FõBÚsŒŠ; eZ’\Lƒp99/» \rfgÔœ9gñ2oÍ2Q¢?d<ŽÙ\òˆtΙ€0•:ͽÆÁ§ù\mlÔ¡Œj,æ%6…^¡F¤@½¾þÍbþÏ.<ÁÀYd/1Ä78W€R2¨)²ÚTƧ·ã£Ó¨ŽÜIÈ p£4ðßµ'þŸìê?g÷ïXÐþô¡xΑŽà¿¡»n¬„ü8#fAžÆ¡":úÿG¬ò¿pðÿf`]9ñ‚™n:$¾+àÈwj'È­,íVÿ dýÆ&(ÑZÝ%·2 ÔW±€m˜üï…†_Ëz › „$…$EA„(`Þ(ô• @»áñ®¿‘ë³® è7â¡à“¨âoI§¿ Óâ?¾«Ç5þæ<»61$1²dó2ð¼\,å€|*ñ7'Iܰ´ë£O:ãe=Ԣβ g/U3èu©”¨ê·É݆°3r›r%u4ž FâóÂ;(Œ={µvQÂÆè±Pê'„u‹þ$2^ä½L t;" ›:EPxòR„™f—…¨©‡PGÖC¤“þ„W…2 0Å)Ñ-%—A肞a½Ä—¸W•+4 ?\é]ÿ-ãìžNeK½j"ƒÃµ^6ž¤VÈg%’©Ät« r;)UÚ!qoÍ!¼@ÕD%¤Þ@|‹¼¤&Á´DgЮ³ÜZ òŸòÿ‡ ñŸ‚„ ’\%Á¯´"Ekù6’9 ˜¿€ö´êãÕ0€$)@¹á{þkÎóŸ|âëkâú [E È#,f𭀪”Â%ðÙÄMüI[$ 7ºNÿk¡êŸ=h ù@‚L ]no¥ÿ'Øõýn`ud2ÕQ   p·R“Àé£J–?ñ(üšp6‹÷]38/²ÿ*J¼«ÑüÔ{ÁÃüiÉàBîMÝ¢¤ã&kª*Zòa±ܸ±b[ÜÕœä-û‚z3$Oˆo±SÏó†­‹æ<—ß.~†Rg£gºñµ^6áèõÄ:· ROœ=@8þæù.)âõ)ï$¾zE­"¾Ì²@ù*¸„îwþÓäƒì&WÄ ¥²Á;Ÿ_¼#îbð++íÁÙ\ Àþ*Q¬E;Ã1psUöÖ)¨µvÖÍ ·Îøôß8 âá‡5ÎùøýJ¬WÓ_£cðXZ5JFŸ¬ð2Óf׎3RKO»‰·¶fL–RŸÎ|YîáhÚpn¢zh­² 4“‰¶’ħA®Cø[éºìYMàoÞöŸ¥\Wø§ÀÌ?elþÙË}8¿.ÆúÇýÿ½‹ýzÍízô#àz”uäÕ¸èMg`: ù6’¥É7EûHTeaáS´°'ßLlHtD¿wèäÎ<ôœüõÏ—áLÃCÕ ñ¤\Æ™À÷¼^<\ÔÔþZ6øË½E :»ÅÀ!ïWð²ë€8h= þ¥ä>Кʙ`~G 0K°2¥Mfd@Z¤äV÷È9Á3é_CðrV¼“Ñ´_"Ÿ€y6{¨iæÐéS@í—6 Äzg+(ùái ô\o0à‰ú ŸôÏ€¼JÀTù1ȯ¸ ¼ùëÀ/é–¾ÿ9X‹.| ¾!N±Ï(ðÚ;mù)uøŠË¶° î6J=N@¹¢íÃQûhÇÈ6_JœÒØ»€aÔËì ú¼´i@m·ˆÑ"âÎq]UêàlEä‹d€?LÙF4#•:tá5 ½çüg°ì{¬'9PëáñËè ?š™ù_Mê¿\ÊÊh{Ö2ΜØ¥·húñôz`/¶w[Ù~ÉøP|ë~ç jòû;HÔ(Þ E_X‡kt¶)ZzªXð~fýø½¼_zÈ{¦\H®-ñºqgêPäb×R—j.u ­A•6öZ*•~L¬Ç+Û—#¨Ùoª‡¡Ä.QB7k*îõNƒú ºß\å7#®Ì;ñ”l5ŵ†XÃõ#yšLyJ”Žü.hn)ïi"îÓj%9 ]J:í¨ÎfÚ€7D´û7».ä~.{AÞýò¼Ë‡ôú¨¹ÃÕ0%N?¯õvsNîž´¦^¬û9÷/sÛµ˜UEä+¤ ûOÞ†{®gÑ®Œa'¸·dG!kG•W!ãÛ´(D'ê!c}àq0V{Õ ø¢>Œ/Yƒ§ùö`„ñƒ› ú©Á(ÊÇç1/t>ï_f®‡ý‘YÍ•f‰¾AÆð¼6êY7åL¥ÝÖ&öÔݽYé­9¢ÊÚ(ýN`7dS6Aèe)˜å5 ÌGµ2 ?«¿š¦ Psŧ ² ì×^Rê ¦Ô"\ÆJýO ?R¾³ PdblJ%ß_âϹȾ‹MÞ5§4œŸýÞ”vó®R)µF|‰´Âî>DáË©$\!йpv·Ú’²Gûê¥d³ýCÂï[]|–öpªÄ…'‚÷ö눓—ÞWš¼V%:?ùZö óŽ›^ŽO}³ ”Ú¨ÿ¹û—ò• &ó]ò–äL:½&êðhákþL®\H²€’{_ÓÇSzë p‹Øï¿Ý|äÂÕÓŸ+ïnϯ?:LŒ¡êñâ,"ïTæ:ÐWUú²[UJ@öðìƒì§ÕãîeCA-óÀŸî> Jy(Ý«ÀUù2(ü/ ñcî*ðŽ+` Œºl„dý‹Ax¾Ù´:n8}®Nùjl+h‹•Æ ½'¾µª’¼é¯ï{‚SÚ^%ArœÓ\So ‰šîaˆ?%ËCr°rŠQšCü íîS‚ !r-Ä •Êï„ôÁzkÈš¼Ñ÷ÅK‰ÉŸ ô­Ÿ‰Þld¡DZ©ßñ{p‚Û/8ŸE4 î!ÖІGÍ©{Y8W¥j6nu¯ª“Õwâ®È°¦Å¦aÖÖÔ.´Jù^j¦ZAí3ê}i‹Ë>T5!Ü=àBhNøAÐWj»€£jpÓÿ²æb.s€Ò¬$Mq£0WëÓ꺲åuÀë%$ð%dS.ò·Œ† “‰§“GØîÆï^›è(žWVŠ~Ü%þÄ‹Ëw€Æýÿñäº`ËqÀä,y¸dåìç6îN=‰—ÜîO¥ðÚa­:YWW«ëd‹ËÄ5÷ÑÃ;uËþnÿbedâÍËgñ¬6©–HuNZ[3¬…¢u£Ø­íR_”󴎲±ª|®ŒñÏ)ß)ãé(r3Þôkˆsi[½[øSL“[Á!2˵ |-ƒ *pÄ›€3òyä e0XÔGÊ#A2…¼âùê‡c„_VÁ ¯“·¢†zú]Xzû©>l>ˆVôDƒý¥d²¼Æ²“¹5О¡¾Uæ{çî¬2ÃëµÎ¨M æ9ÿ2³9á'Ôm¶Ð|Âßk ¤ØËßÌÓÿ<¿Q†TÄ'È$ê’Å)|j xÀïˆÍr6?:ãA±žó„bBÉ’ÁG Ì>s:dÎ1v@¤R8‘_B*„šüï§ôëÝÿ~òÏŽ‡n€äAzↂó\ào§ÿ÷ÿ%þq•xìGpšº@U¿Wa5(8œZ±&Ö«·!•W{{ép±“Úb+Ì˸©ãÆ´DYãá¢—Ë f·ñœÝEÝæ†bWÅMVE"^jBà3Ô„PjCÒu,H¾á­AZ̃ˆä}~ °^Ò@ñÚÄ×Pxùð2¼`ß Ñ‚ÀC¸ìF xÚ?¡çB¯€Ñ»¨„Eæ9Å]ƒ¨*-“ú»…CD=óý’¥äy½JêóDou¦ø¤`?³ÔÎ…3±o»æD0ª¿¥T…›î7ûC¹áÑw¡ôÀ챑0€:UÀîîøäœËÿæþòWÿ”]û§%ü'ˆs}¸€¼Þà&«Õ€ÿÂô—9ï¼@ÆÉÚó„|êÌ^Ž…Ÿ0ÇC * x.pœGýæÑÉ+¡mìBA jò3P²¬ž¼­=Âeñq*Éáûü‡HU8#Wb”™¤E)ÝÌXûÌ/ð¢}•ÉH³‰¶ ô­ú,½™–M\=a®eº²R9Ná¨ó¹Cü ô&]ì_·á“ÐᆨÔÿïŲøÑ…W™Ã>àmÿ)ÈÛÜÅì—Oû)’­Æcþ‹Ne¤WÑm€áÛÃp­GåÇhÎtg/2þ£U®=ìþ€rõ0ÏÀ…”°Ï4ü†qíù`&MãB÷0C>ca±UG¿à µ£ºÕ]¥U¦OʱHæi»(‹§îçƒäHQ‹¾±}Γ8±®n/ôÔ,1R]µSÛáLÂ_ñ\ìÄ3²7±Ä0¾T>%Ë»Íø ÍÊ›áÒWãpÞ:‘ Ñ]ad†]øÚý½"¿ATI›ÊFåK(˜_ øRýU"Dʧ¯å¢?R¸à$k‘çUµ¢ôÝl1×jöè¤z?5â¬Rìæ©¦ JªÙ`|oõn³D»ä쀀,›>¶ä}¨Ñ™f¯DÓ¬ÕhaMŽÃ2G%z k-²Ÿ@¦Þ¸Ï¿y¹rºßÖ{ï €³[DÀ¯¥|Ê×ÉíÈ`;¹?\O½ 5‘õ!ð•›É™H»@Y&„雸Çè¯@·àíÚ!†˜äûÆ3ÞRoVÓâü¥nRî¶>`­þHrù›ÙôêÓ¸‚)· K¿a”C”-¯€ô…š¡„H€~H» tSýÔÖšÚ·Ê Яb«ké…Ey‘Ž%nvp?£pË1®ÓÁ®sD«W”âi J·xšëãz¶W8Å{@&aÀâwà*e€B*YLtL ‡Ê¼Dˆ•²,ºœ!O€lèä_Öû¼„Wܳ^ðnòæBêo XéÞëPTÝ[ ¹ï»+àÜwJ3üÓ%µ­¸GZ‡›±:¶9°J¶åôÞjû%`‹ÈMžv^‡ÄHãZ,h§Xe=«¹´UóÎàħˆôâžîíøƒw è´ÿ,¤hUñÓ+ùöÊ(ê:ç0š‹ n4öƒR×¾[ï$êc %®ŒôZR(¶Ùé$ý1äºø ,íëÀ/T7ß7î éLÍ=Œf|”õ¢½ü¡ŠBïS9›Ý/èOÀUÅBñß ’ D~ë°„'VVpÛ¿úª…&öª7ÿ ówÜ>GN¡D?|ᬈwà˜ýˆz€ÁîïúEÖY%ô‡™7¥Šæ®çbbêé~,ógžrXaN¼6‘jÑáþr÷ÃÐ" oo ª˜ã9梴uîæ Œ\o©þUN_âzëœwÝ_´âÈ;RQ^0ËŠ…Ê¢ÌùþãBUô3Di5OÎg•˜&¦«Ï¨,îÕÚ Gì%]ý‚Ô7ˆ ÷Ý/±óÞPÓ0ŒÿÄŸd%$Ëû5@Ùç½â#o(¸óÝí¨ê7ƒLÇw -&WAà¬x ¢÷ú÷B`·_”;´KéÏ ]㡌m?M@™.{ƒüÝ/ÏRƒL£5x+üb°ÖPR1Q Üî²$¾S!¾@t‡ÄÓJ [)wAÞ¯z%ìü¶ú ß2¿¢›¶BoLÏbÓhG¹F?äµôæ+oxçÜÄÇöãiÛ¸Óšêçs[¼_r5O&;ÊŽ JJu Ä:ã ÖÔ}b½ ì¡¿y’Ÿ#‹‘iø±o)(;³vMüÌ[Òz!Œgå)lÓW1Ìs|‚ªu¶Süh¶sH†ïΧúF¢95MG}Šñºçtàac¸þuŒaÊûøú!QE_­œå'í k¸œ¤”ÈÆÊ î0ÙG¹WŸ&G(ëxK¾Mßâäʸ´f~{uòdiî)j!.Èï#·1WÜ¡n“+ÉãMn#‹,N²…5B•ǽ°ÜÁ‰»Å Q5ô˜’ÏMæK¢Ðokת<#·+]d¾~†iò&m¥xÄ+å!ÞðVû›èì䨓ø3íãiÇ©¯TIÿ70¹Nÿ£5 äŽøPòu2щWœ^ö½Äb³òú÷ÿlöG‚xQ^U¡è¨ Ê)/úiÙtÀ `L0ºèac:€þ€V @ý@y@}€·”oO\V<(¢€lxþ2@ÒÀ›x~>%ˆËš\%Ûøš‹bSúL2µs$a£\ö@F†{äDø.Ø=sž–.¨úoè ¼*ƒê~ÚxGò¤w!ëyÛ¹¤þ%Þŧħ\f)ó*¹Tgé„y–ƒTó?á a¿’ôÁŸE(Œl¤g#î3V_—º4«;•néÿø¿$ÈW8zú—YÉ+K×½HX»”Þ‚°ÝÝ©KؽÙ=Œ`º>›Pê#ë*§Ô»À-JãÙŸzOÅ€ÂfಜG9QÕ/’ó¹D„CòS9E<íÔ¡­ÜÉâ$}oź'Ó€ËÅ_1R©GE\~žŠ±ÇùË*É\ëm'&§$›9“˜W0¡ÈóέÜDâñªËCljc¢¶òο€š;}¹ÀëÓÇŸœÚAûš“Å£ñn~o¸6]yÿÂGÞ(?ºÍŸâ_>8À|MN?!#wz½vž•åLÉ[ŽZ–Û 2·f9"ÑÜ? Ê;²<ˆ–¢,Ðøœ·A~/:ƒl«.Äö®ð0†Ø <¥Ü§­§®Q*2XL×öãú‹µChömxÕopü/ôÛÐí¥ê£òšUJiï¿è-»3AÜémÐwŠ,»µ3œ1êËœHL³¶ò¨½S,dlê.Q‡Sñañ“ ·?Ö’xÉiÞÔäÑ’m­¾ÀCWoh¥^Z±±5øMêKvG/éx4ò•Ò¥Á{íz´YÚÿ²ÙK Ø‹•Ì-Éï!x_ò'¥º³MN³#,ÖÄ÷ƒ3»h„vû{ ò-Ê}Pµ½1ÊF ¡äsÚ[V¤U„ðYm2jáǶ kõм*2î\å²ù;÷RJ¹•Þ,ä”ü_¨,òÙ4“S_LþÖò¼~NHÎ?VÁÿDxäºgþçÁEו’O·¬>8r ó0—«²3û)A¦¨åÏ¿p¯3Ÿ÷ðì}ÌFÑÚQ|…tšp3âÆi*ÿb$k£]›³g,bPÏô‹rÿñÕ%²xÀ)Žd‹\sˆ:ŽzUn²`}Ù%)KÛ‘Zˆ>œ:%©³`Ö,0G[­ °+uè£ÜÊJ í7çyÐ[ÛWF7ëv|óg–f:;Q´YJ ðY¨%‡#Ç_Ó#pÄŒó‡1%ô4¶ñ¦q CÿË|”1Ñ6 íôø…g€¡þ<fÖ2P6†×‚Øì@þ¡5ÑøâPðÆ8 @¾«T‘²”Ó ¼5 ÝVJ;„·>¶ˆηÖA†[ý­üf…­AÄß%Ž¢Å蟣X76£ûMÔÁ¼h^DØãŒ¸3a°,}6ÄÛ˜ýÁþÈÌë»`Iodðk© æZÚ&û{²ÚÖ·c]6ÿâÅx/u¨ÕÁ,v[¯( 3“%¸i‰Ýþ~~NŒän–ƃòu©ÒZeBÅŸ”ƒÔÞcG ¼Îý ÂEj=m  „7«ÛðƒOO£˜«Sµ)È ìäŒù|ªãŒù‘wX-t»?“’ΚyÕÜ„£¶{IJSOÿf¼d Bø®+ƒ@ßrµ.”ÜS”¥ÊPJߦõƒžÚ r~Ô Hï:Œ~ËXìÀž´îèÁ¡¢¨¯Fâ +µ ^õ¿±@ñÂýç@yñ °›ÁX´ÏùÙ›‡ê>ë¬`©½+™GùdyMëùø¥ÜÏPòZ¹CI\™jda_®!S2ãPÍ{L¼AW+jëÓÐÞ+Ÿÿ!kó&¼4 Ì …Íå7æ4¿žÛI¯mxÎLå-sp²ûƒVê ‚#ãYnîJdt‹ÕšáeÉïH.¤âÆÜdTu^b1¨R£ðµ?R¥‰¿§Z öRÏKë)?çHø5} áðÛJ:ï‚Ùœì6²¨jŒÖç!ÕÁ¼¥µ ÷“/²É|Vž™áŸàè%å%ôÀ”ÿ+¹”Ër˜{” Lå<0M~4åO@² ø›)<š’V qÔYÊcÌô_·û€D °ÆÈ×Á ÅOˆIx{Å y¢èKž”¾Ý•z^?w=Çœéñm¬³Kû[•ì¶,L½)‡C¼‰³‚GbËù»ð„E-þ,¸ Õ9Tq­âð'(ÎÁ‘(Þqó}d";ÔáV 4$¯àhè k“UÃGéX”ŠuÞ4‚~"þ–~ÐÞjOäéÔdÏfXâcµ ÑøcªþˆÿÉ€H”ác´d]íĶÛ@ª—똚‰*Þ(Üø÷ˆM¶ŠÑ”Ñe™šù'˜ŒºÀû½bÖ†Àç¡Q¸;o˜÷VBhjèPgÉ- ›úãÈ%Þ%tQÈÓ ׯ i¤ÔÀ󊘎æíäNð:)MÁ~3ˆ—‰Ý Þ1~qŸ6â³ ‡ƒ>Þ^™jd DVé}põ^©í(Áòò ”Pkq'–ÙÇ?€©×µŸdŒÙʯǃÁ3þ`n/·ì…Z 4ûúßø~Yä?DrÏ¥w¿‡«³ Âp®pUVŒuƒàÃÒ„È å$‚3¨ÀÆÐ5Àëáæ~)”teP°ZÚ7Þ—ºCKûmm¬ÿ }káZ‰¾9ÙÂû¬iœjÂìPÏÄTòîOíÁ79CðõE/¢ùñT/0¯1Òù=p£ÓÝØiåÕµ…Ïèó¸l®~Íó·Àv2-µÃDµªêcTS¯ÖS™ÆeªQ:Ê{zˆZ¾"Øô<Â’G€Vþp¾À¡èd6ãàŠM ASŸyÙZ XÉ·AnR^Öûo,™¬Þ;J}ðe¢ ?âŸb¿[ÖYNÌyÛÉ£¢3Éý€ÌÔ÷öD“ÕmûŠU(±]~?(X([Áµƒf3H6 ŽÔÝá""´×›œ†æ‰ Aóäì`>ÛŠF…?ì ù+¼·}¡fÛï9§¹=þº-)z(ÞWü˜èØÂ}ÅÝì<ìä·Ú·…;båh‚¯Úé“QÒJdüæt rÍ!\!¡7GùJë,§„±^¼Aýy79j}wŒwôLPï·÷^B_ ÚReˆ?üþ æˆ§AMÈ?@¶ö²Y39¯üÄ-l§+øš ¤'©É09Œô =%ýUt?Ý;Ü/êƒßR™Î·!È’b 眳j+Êúc9„â.ãÙgÿég²¬o–¥‹õ°Û…ºVçÒVÕlJÝâŒ{Ľjÿ¹õûÅ|zt¶¿ÜÛóQY%Ãÿ4S^u+Êáìt ÿfpžòrÒQŧìrÇè5yÈ`VawêÕÀzÿàO¥WѾbɸԕD¶õ|þ‹þ€‚þ v¶„@÷Âû :Ñ«‡Ù®”à ôS2xB©Ç+f)¥¦<|ÖÌ‘]Œn2‹"óÕ@i¹@]*öæ«rîdñ½™í^¥G´¤s;]BX'ð3>s~FI_fM‚ÀZ«<(§ý»!r0õ%(™î= ½å½b±³ä;J'îHv«½ÿ:ˆïT‚¯XwA2Ó;ò]¯=ˆ”—r˜<«^¥¿ÒdSÑ äÛÂo©R(T§€ò§zœ b+x…Æ:P u1Øe•4°Þ Ì­µÖÜ‘úÝXÉþæG˜É'µûèžfî¤g²Làqº'[A¢‹”ç ïÓº»;ÝEïTTm@çøÀÔ,Žms!œh¥Î‚âñÎP´žeÈ‚¯ã&nþQï0zb^`dV­ÞrfdýE"x“zÒôÅ\ ð±qYÞC¶ÙYäœÙˆT3f{­¸?p‹:Œa²#o赕S²:RyÓߢ„¬¼{Õ¤ñ“ÿ¦2XÕ]ƒSf{¿ ¥Œ=”üí N÷Ž1Ä¿÷ß ©ßâþ¥žð—¡¤ÑÇúK)Kqàkù,*­ÉÁí™KHVç x˜jS!¹è¯ºDœ˜zQ/¥ù…§¾Fº7+~Cmx…ª.'N™wŠ9âMV¤ßö/¼[yøh¹Ámÿá%Í[Ÿ‚Jò/ù[ü-F[¢Îl1ì— ?Þ.~†K–¼Ø˜r|{¦¯·RyþJåÔ·Z2aZëõµ~ö&cK´¬uÜL¥?ì|§WÏI·VhOgî´¶ÍrÚØ÷‹~e›;(ȸӭHFf]?‘ ~?K7Ì•Ú.¥¼jP—{Åü¢Ü-¯‘R.ñ‡iH€Q±‘,Ù[µiåmÔÊp‹ÿ°ß• ý¨¼ ™ ^C$¢J{ˆuÖ‡@ÑMê÷œ-èhŒ£BîŸÓþOW*®~gêî¯yçÍ^É#—#F…X§ ô¢ä­ö”ÀÜâA¯•(¥·€Äβ—!u&}=È£´VšÁ?ÂK€Nö+à.I̓TqqUðp~/%žw…Ûl™| œwøßò#ÔO‚ó¥?Rß'òÁiéN„äáøYpòîÙ–éÀWÔaó"Èïø”çÔwi Ê<‚ö…P@íB:ðŠÌâÆÙƒfIå]0Æ–zY+m­ªã©ïj€^ÖØŒª?¦ou€ú¾94rˆ˜Y;r˜Z]y–âP^Î)N©(M2ðf`C“"ËÑÃGo³—Ÿ½’wÔ)v6ª™îZ™%†{™¯„Eu9Dq”Ù²Œò°í¯O*…²ŽrBÙ,;à)Ãä+\5d >µdgtÑC6DŠU²:‚Ê€Ê+ 3Å›xrœøUÞ,¾fª÷‰ˆð‘¶D<&¯:Õ;ýRUÕßÔ>ü‹,¶§Õû¯vþßÓÙ.2¬`þ”ÑÈØS?!”—JV!a¿Sà„×J¢¼,ÈçÎÉrœp§¨ oW·«¡»´B"V%û[<;â·Bs'ˆÑ8²j0ËiXÃ¥ü±™,Ï_^0Š 1#\fu,.!x¯][H=3ñd–÷zC¤cr”\Ï϶á}þˆe>I9Lã)1‹ç•¹Ê§î½Z¹Ô«¡Ô%y^l åÉ”/h‹üubºúŠŸ’ã©ã÷öÐÜyV¦ãÛ;™‚býÎHCBì&^‡"[y ¿à.1 %ÿˆ°y¦ 5›YoÊSrjÁ“ȺöºìKÓ„cšä¤ýQ¢/”™•Yu•dd+oƒy{ ÒKS 2U[fNU~á7…hs9žYÆm|OŸo‚cÕ)Üd&•²Ô5{ø:˜ß¹ùP¯îeËuú#àþ ~*6ù*C£S¼r€·U¾#¾}EmF¥îpƒûª3ü‰N{Pï°žsmÒm^ñ— ¾Í›ÉCEOC dÑ«]]ô[b¨Šn…è騏‰Íxª“ü5pÄYÈ<ýWïKZkÈÏ©¨\Éde$›«_Ó5>8ïEnGƾJ;‹ˆ]ŒÞÍ…¢ÙY%eÿ¢®i~•TvV¾ß:™“=ّܿñžkÈìïuv>ë«J%­•¿(\ î;Ê`Ú¸‡Ì*à\N__óqd¨XK‰è7ÆXf„ËÈ×¼„i(­¬Êx=;ñ³"gݹ–q1Q^j•K•àZk;‘°Ÿ,ãe÷,D:Y?ƒ1PJ.9ž¬©‚üÓz®h*hÏl5y9B-å2ü3µ%ÚÐÊù´§Ô—y&}«¸àω Öñï6»DÖx‡³Bºà â]9Á w$¹éǼWÈ —ó[BpŒŸ ÆÓ~IüÈ~1E¬÷÷±ŒäR~J_£åŸQ—â5ÑטF„ LçkZ(ÍUA7ï¥/]â·3ƒ«Öå}J¤bêQd¼Œº/öŠò^"©~KqR*Ûü–¥}íÌŠWUv&{ÚÅ¢QlšxI„®èýDøBóPº¹?ú*ûµô.œ_æìq¯î½©[Jk|n®Zq„ž¢Œžöo`¦Ãyɰؔ¹·Àê!™?‰á—ýsGF„{·ŸYŸSà÷?›Yq‰×½°t¹\ ] z4+s”‹þ°œêò~5·\¾=-°Ü|Þ›,¤ÛÛYÃq¯§šþ²½;¸ÛéÏs£ó.Au²ó±l,>rßß–K•»µEŽŽ¡6ñ>'(ºùcjû½¨Oû‚ðÔ§A}Ây˜Ì§ ¼([oaƒX#Æ‚œÅ“Ô* >¯ƒSÂî“Z ”+êy÷{ñ9¶{«Q… ²¼XC4ÕRkEyçaíwÞ§µ#ÜÿÐèBeyÂp¿Rç‘™w̼‚§ŽÖ[øjâ%í>ï8=”án»T;q·ûœÖ„½© îY~LÎWêsKòÞdõºhÅËIKnÄ*î™ÌÁLm¿ü:Î>í#óÑÓ¿ §3(u/10r\™% CŸjö½X\J8Ú6‘‡m™ØM÷ðo©ì.KÖ';˜´›Bô”ý˜§œŠ‘údÉX8»‹ßÚ^= J%«3dD•' û¬6 ²š[ë!|§y€TæêÐz™/ûé¼8$W…ªúõ­ÍzÞ¯bVÀßÊ…ðyeK<iæxw!¢mèÂ*m#Ųe`‡èɻʣü…o´P.°K/Èå]Ä(²ÙI‡¾ør»IL©%šqÙýPfKó† ÈÅb,wZýå|žHUä'ñ]ªHÔdTñJTg¨ú2ÞHÌ"–0•\¢E·*È-±‡ÅOî‹vyå©äöÂ3ÜsíB‡8G·ØÎ¬œÙT`mÿ•ýü%¯å–•²þS!7%²”Ö[B+ù~⻴ʉµ8Áš©eÛ“7±4™‰ Ö°.@à½Tg„¹Í™Á¯S(g?ˆo^MžAÑ_õ.â›U’Ïãèß[ËÑõ×¼J`{•6Ú»=kõt÷T½ŸóhCœ xZi·6ªZäftʈÒÚË ž²“¡|(öËýò{e“<-¥¸D®,`k¤­?)†±ß¬!þ+ ~ôÛÉa…9âCm¹Èâ "*O*•Ö2ׯ¯®VMt_è•)ô\GÃõß‹FÐ\A \·™~šãé%øÜ›oÔá°ý¸9–·ìNúNr,ãÂöfs A«„±ßê«WDIÝh)'xé,7"⃽!ù˜™ñáÁi\³»§rOâLh=»ì†!âåÌq|Wü9Ë-ïŒPºY çø Ù[¦3"ö¦b¬³©ö²40ßO~Ž'ÚÆÃèrLâ&®}KÉðݱSÔ ÿRü¿E«'"#0(åB bª w¹ýAÿ^Þb Aþ$Z€\£½†ôÞ6ÞëZ0ŽH¾¾Â£‰a‘9ò‰âsik9[žq’iEûÒF¹…/gìwÇ»DsdÄŸ)#j…ŸPÊÚ#Ì9úù²xC©~ï¿ @p„ žöÛ{»ÆÖ±ŸPž‰Õ´jŠ@ZÛÄï4Që¦~bUz‹x}6¦&»³ßüÃþœÍiKâ#±Œ“‹F‰Ôh–z—@àëÔp¾ ë~mK¤~°Sb)!³È)ÇŸF(YƒFú9k9f§2h£­7xR¯íŒö[j7Yõü#jÃõ6)šxÀ™'–ù#‡‡Ú~ŒXãžÁ}Ý•(â_˳àör^€´b%ÑÊêp>v7¯øÓ€b6Üż ¤‰õ@#ågPue 8÷b@þ‹þï¨/Câå ¼X nG£(¯©U(°;jà‡ô•ü,««#¤+Mõ”{Ð謞w?O°Ð]€ßí±ºÅ6ëÖ4°]ÎHQÅÚA¾ýPà‚)M_½ÉGÌ—ñãg¢$ãZ¿)Ü‹XüþÀ&"ÉP¨5MãO¯ñLò‰pˆPáïa6©v¡Î¬+Z¸Ezq]ÿÉ.ëõà»Ä“r%‹bw»‚G“ùZ#ÂÅ¿[½qYjôøR¸Í;±çÝ—!å¨m!‘áŸ{¯º7ôB‰³(iCÂ=QDù5èDPÇŠbïxw¾RÙ â6iúÃAQÄï žåsP‹ *“ Ì•@ÎeÈ $€¥À;é H½1h}õVê•Ú 2¬F*ÝðROå.G¨ÉÔI”`U17è«%Ђ÷+mù00ΩK«`C}<†(÷R9\3øw+YÂöˆ¨£¾rGÆ¿°I¿Ï}wNÁ ~DØ2Ý LæRð)ñ*?†*ÉÒ¼>¬ö‡pº¸KïõNJwÌßSÅ¢½þNêq†F^OtçjäîÄCø¡õÖg4 LýJå`Ä4"Úöd>jŸÃ޼çXè¡ï³æ_öüàcN)Šp¢«Ú[òg\cwü „z{jµôÕÅ•AÛ¢õ£z~5лƒþ¥²žßõÎ!9F=ª}-R^°žòŸD—Ëw”/Y#Ê«‰M~MîQ ýÛ©.'V2̸I¼F-¹Hn@á0YHqŽ‹`?H3’/Pƒmöâ93òˆz’Ÿ¼Å·rMâqÚÒh¬äËy©Öä{ïh_ˆCî³òpΉ دˆJ`õ /çcGœ)ÝD¬Q{U$¨û{h ®û–Ö%9Àl‰’¸+Xƒ‚ÙØP!ÖÇü w…çcY_…~¦D,JcZñðH?‹+‘PØÑ¬ìöKµ+’–Úš´Â™ö>?!ð`Ñ­¼L¼Èñjw> ÷ÄM¿¯b_ÖÇ“d5T$ËèÄã1]P~úîm”hÄ µ¿\'ßÓŽ+RÞ)úRÅ¿IYGH–¾²Öß(¦«OËJâñ=©Å9œ¿”ò“EŽ?’3b3½PÄUʢɆ"‡[ Š8?É£âø‰œ—ÅâEù5»”ítöš)wú#µt±^òO Åe{\”ÍyF¤{5ä‹àüàwo}¨ 8G­ƒ`Ov>å¡j+˜U~Û¸Å<ÉnµÚÿÜü­…¤NíÍ?Œœ·W-ÅòXKãKº;wèyÌs.«+¥áÞ©ßì5pË)¾»Ã?AÊïoç';ÝkËiëêrŸ=Jÿ“õÖ_ê_Äí–jyæÅ÷+uÉN”³{p‡\pék.‡¿UËðUp¨r-´“áÝ, tp­r˜¡*ÚhïvýníW{¿rÍx!Ù“¹¢‚Ý€ÒÑ É{9®>˜ü”§›Ü¬¥Îâø5í±èÆag;»?ƒQ×ùÄ›N50føïƒùƒ“ ÊDz6Ó’Àïï—ý m˜cœ×ÀÿÔZ ò;”»Ì$èUXòˆl þÃέàUσ謼þOúYšÞÄøÔíë ü©¾ þe夞1àÏqHÍ6_ûYm $ëé- Õ'P Ëy íûÌÙbãÍÔ-ò‚ƒèl— þH‰¼áèË ô¿HVP¦&Ϫ¥È,ÎsûCÑw/—ôÿ„¼æÈk•Ru±Æ]œÎ|ãæ­|]òbÅ÷éfŒ“WðMÛYÄE3Èë¨w)¤¹¹^ž%iHÙ‘£FSqLþ¬T\·¶¶VÍöÞ¿hûœ²âœÖÇ-Mmí ušˆÙÏ}©…Ü¥פ=–ÝúiÙ„bu‹³‰°¾Ò+'*e¼—ÅqõOž÷‘©´ó~ÃTkË—q•;”W‘Tô÷õ›pžò¹(ìä)<Ù_™D\4”ÓâO¶aú_+݈»OjïpųÅ7¤É¡Úd긟*¥xÖŸ¢¦hã×úc;K´9TIŒ¨x7µ_<¯VGDþlïÅ9Uªè+g/Ògpwqñ*OúCµ›9iÖÈYê`YìÝ¥Üá'sDmï€nÒÒî¦T£Wâ¬Û×Z'7¡ÙK¼§HZ s7´þ¸ô:}ô:‰ˆ÷‰6&¿[S/(œ‘<¢§%ë'‡?RErq&41õ¼ñBxR ý¥ènëI-ša+¢Tè¨]Œ¹îhÐÞuÿu»|Ä»Ìj)­À+¯Ár6^Æt¢zk–XŒþ³‰õÁÇÜÜX—@§W¼O £ýIâÉàwVãdµ`7{ZÙžl)kiCófê­pg’ÛÚíõ ›§A¼§–渺K¿™–úTs&§ÝyÕ?›š‚pc©-`WL„À_éU¡ÇÃÌ!5¥  ø/+Áû^Y ÎF÷1HvNÞÎËî°~ñ*CbJò¤N¸/Cêsy왜» X¥0ÀjN ¼±Ê2í§€ŽbȪôZÈa 7øß€„ ø>ÚÒDÚz×Õ»àG¦DVà§-Kß…¼ =¹ÜŽý$²•/ƒaý9|3!ËSß|™N¤žÓγ/X]DhfÜë?H ó#9×(%ŸÃÕûúÕ奯ÿ‘S ”CþÍêœÀ8¯XÜ-–º;é¦vu›ðÚÛû”CÚón=j½< fËV)ëÝöü¡>&ÿÂq¹“¨Øêwà‚ðï㔲IÞCŒMÌB‹›(‡+æ’1qž«~±•ˆÿŽ:²Þe‘…)V*­©å•RÏJ}[ê9_J9‘)ÿÕÎÿ{àvòüSþT¿ÔŒ¿Ä³þÔÝkXâ¥'ûe¬Y¼)ÏGTW)Ú†îÞiñݼº(ÎÃJMÙý¼í#þ\úÙÅKøö:ù*9Ö[þk—<‚j-ñ 8¯è‘©šj_DÑ4{Gc[ÜüpµÝ•øÒ¾æžòIÎ"j»¯fËê¨ÔƒìIÛNfáŸI‰¬à$¤èH#Q«âfúë}x WõxE]"¶¢0X>ÉQ¿$ÛØâuçVV¹kPä=îx^c¸ÝKÜ+7¥"ðR8/ÞKæÊÙß*Ÿ"nñïÅ5~ yì 1ÊOÈ—à>­—FfÌ,]òªyf‰L£3DVúí!íŠÒÒ¶ˆ’–T ÔGnƒèDe D«©Å Ä°ƒ›¼_1BsÖô lóVÑ'XY™Âf%½•÷’ºO´wžW*ê?9ǹC¿Ù^ÀGê½î5sÝŽÕ-Îܧwq»ñcðÿ¤ÿ Ÿ"”wøôƂ߄à×ó@n¿€õ»ÿ&¤*‹6ै]n]ˆsÁ ø“@}Aªϋ„Ôí2Æeûä‹¶/ÚÈm²;HUÖU¿ð:)u†7.q@íOð:÷û+¼¤Þ_¼f|A%íÛÿÿ)»¹›Dý…Ïu=Ç{>سW¶rß-ó%Ýd4â06ó™ GÔHßZ‡Þ \C1»;ÅHc²(ƒª7åv|½@ÙŽfÜ,ßBêÛåD`¨þ µŠ=’«Úsâ™ZOï,ùzs'g”²©lÊëeo3Q|‘Lc²ö›Ò™¨º2­ È‘ùý@ÝOû•»@½‰e >4s@L‹Ly¶àuÀ5Àëë¿ç^t‡¢zÊsý²Þ\NËjºÉ`wÜÎïÓ»)ʸƒä^‚©ÞÅÞg¡°íÚÒG·f»UNT©É[Ýz`”OBòY÷w°î5¾„ÂõyxÕ/Õ€¬ÆÊ1H¯&?ƒìéºéuD™V `§¿(“ŒvV®Ð4Z_}ȹÅl¯˜ñ‡èù\¬+EÑg<º71šCÃR÷„^NÆñû’Sp“¬6çR¿ ºõ (’A›ëìsš•zºCàN¹´”ã ÷ô®€¿+uqö5Te¬u++•ù#˜«–Î}‰oŒóW“¹Æó…ÙòÕÐüØJÿh`”wÎ EF%^r>7N&[8–òž/«æ>¿„ó¦qXž²‡i_‰žÞ.%é?âÎ%MÔqCHm’pt£°ª žÝñŽâAÅÔï䌥M–Ë VÆë«œ7z¹­µõìQÚ-zûmãmqâ‰pSµjAÃôêoy'3cÊmWdùê´¸0®ÚíÄÎÞ^å<ëά­çþsÊ ˆ·¹*Õ§`qîÆÈO—w&¶ñà©Ndc‰Àm¿3¥ëü_ïàyåa-ñ/`xòfÈÛ÷·Ú›a¸lµ?ݧ˜˜ó¼÷]lk(CŽˆ^ä#uM©ç®§—xÛ/P—¥}šúX}*ØÐŠŠÑê1ÇÂWƒV’oÔáö,6²®ÁêöcŒ2p’ŒÖZ['­–¿’Ô{['i¾wBÿÕþ[Â@7ê%š#übã$˜?;ýA}Ø~xƒÞà¯3'ƒ‘ë–YVîe Õ€5äƒ\ªm{ÃÁ›oç”q”¶Áé$DI»j²1S|®,{€Þü.ê÷`Õ2lî™ä'j˜àÈWµ ÔHž0êóºl¬¯'­ð)s0yþó)ÆÆÇ:rÂ]l”—b{ôWübï#5á\rûó˜•é·a{ü”B£Dso0éÉäÅw%F£ºóŽVÃO¿Åù /}‡zCéµµ2 èÏØ´i¡_ŠÞå³P×ćLHëïÍáHNb:5ýsH…íduáaVE =䎆È«=.¸oA0äõ³†wŒ®QÒm Â.¸üŠâxÂsmÔЪØ3¬1Š 6²Ìè›Áê`•dect­õŽŒ–÷Z:„?*üÓ’jžš´ÛšLû‚¹<­¡_[Ô3ú9? #R®G¨¸ Ü„øX> ñó€Ö2D‘D•{ALP>[Q^‡¢¯äeðÛëy\£®åd¼¹:*©_´mþæØ&í˜}¿¿ÒøÐ›O›g¢ãôæùC3ÞRZ^IdÆI»Ô²\ ûô™_cì>ñà§2ö`•߈ÛÀÞþWöø³ ¯LþääÞqáŸHld§ù\rý[SßóW Ó¾+­j²†ù|ê^LBæ9û¸¸»¸9®áÚÉ ¼àíC3§¦îD1#ÎL0óSƒAÿÖ¾ †æžã6gè‰ÄGôÕŽë5ýÏÕã^ ˜œÜà®Á &¼ybŸÌöoá1ÛI+»g,?ãoøièþ^¯%(UdH­–/@Þçž öóþïQNÝé'Ô!ÀX¥.ÐU™ ²¡’ ;9Ù¯)ˆÝ&ºó\ðšúg¼cÚ\ù¤ª.”íxTÙì-–×ÓO§œ]/؆ÒÎtí ïÙ Œ÷©h=|€‡í¯Ô~¤’ÕÃç ñ,W“Ò|š’‰Í­è©u!ìþúR(z!ø-~"3ü!ŠÝ.0”½…+BèïúžCÎØpW6=r™”¸xË¿’¦Ü—|0¾ŸûãÌ ·ÅŸñ{ðJ¼¹ä6½0•L7ýpÂuG!í+ónÕvz@øaÙ…d`œ&ë+#¬MƒiêxÞ oa0“ƒ÷óéüÕóüÍ«ÜétÔÇÛÔ¼øìm>ÜñÇ¿rþWü®K社:ЬGµuàtL®`­±åÚ›ˆ´ÔfȪRÅ}ËøMy0qŸeŒŽù":3þ £õ‰#¼z#õ Ó´x/›Ï§‚¸áÉZxLòv ¦U€ Us¯`†ºg‚,ÞÇãŠx“ž!ÃÖ©ø&1Šæ÷0Íä0ZH‡1F?oŸÿœÞÞûXV¿Ê^†r›_Ékê2o7¸µ™ ä{÷€\ïEÉMîsÇ23ýVyˆöŽâKšâ¾Ïm‹Ü£Kñ9÷ÈÏ)‹Ï5Ž Å{tFu닯éd-–·²"s™>anÑévXÝÊåµ.•ŸÕ®”HŽÒtÖÎ;[Ÿ Z?u UµG•qÞ~×ùÖ¸…FöðÐ`ý¬µ¦85Ko̹ÄZcnJT }V»P[üä§¡$Jj¤yb/JC±÷ÅJ~ÊÀ(>>(nž‚û=Z•ÝÅ]"c9Yp&ú=sׄ+Ë1ÞhuLì™âfÅÔ8¶w%2p•¡ýµ¶¾-ø8GŒ¶T ]X爘³•ËDÕ˜xÆ_ ½DÒ? þ©þèTª©“½³LRK¸‰h[ÜìV?ñgpZëå4`•vÆÿƒêÿ¦)/»m(Pg‰ (¼æw#*¾ö“«ô–ïC¹)¦‰û‘þ6y”˜¨¡ô&(K*ˆzý…JRnaY´Tó­WNÿÎÑ’2®Á“nTÍã¨{Ÿ– ™7I»™7ÜÚërŠwUÜç—’ã”Ç-¶-~åÑ*“Xøpܬ£ºZénü± ‰‹iÇfÿSðÈNülLä[§ŽaÊQöd½@äZóLŸ,ç#sJb¥Q€c߯­”Õ¼µû_¬6Šâüég·µM‹Aj‚lÈSöõv"±¾‰á¨~üûèZ’¼Â˜ÈŽP9ùm°­5™U¡]ʳî»zóÅTo7ú$oÆöIu¤[8+±œïµ6 …-å®$”ùgò*†z‡½ Ÿ¸¿@´Ar0Ú[ÇÝÁoãÃAVV>…ðÔävà'ÿ6ÐV»+@ïþøðã| ™ r\â È-²(ëõ •7VÖJ™b-M€·SÀ©ï¶o±üªþ>p+ËGÀ¬ÊA~ë7õ)p;¨÷ÓO)©Ë¡æàoUH˜°_Ò«C²”ž‚â¯BŸ`ÛÕCª½*° ¿¸uè=ô"BóiY¸!z’#-è›ï¢î¹ü®biñ¯2æÉ  ¾ÿ#\mWüG­!¥Ïñ~ÖîÛŽP5sfN!ëõöNÖ?ÔÛC µg2ÛÐýïå“zue«w@ߨX^o5 ÝåTe²~ÚʦȸÏÚBZ`“}œ&FÐz›Ûõ¥Nhqﮄrì)£tu[‘£Žuž&]ÿÎBPùEîs­“ b¶×Ô÷¼;A¹MÎåQw/¨gį î6ð©÷x‡J{öƒ,`4°RTÿØJÏ•ªàÎTF€o( Á©ë*_ÿšV˽E›‹å}£¼B~2½I3Jö¯¨@0´ð_Ø…ŽŸò9³¬›¢QXœ­çœ?Q›È£v ã{ÎzjÓ‰¦®™•‰x{õUĬ­ÚÛDÜnú«<â–·¹/»ï)M…ÞiQÎ.©¼ÎûÖ}0Ÿ&>S{sOâ‚Ú¿ð–k”Øm'—•­:Àyèâ­@kËý÷#0O¨Kô]j@Ù\§2@9xõ)îwœïI­¸Wƒ1°Îˆµz“¥xîô`OT>ŒX,ÖÚJ@àjZ”êû ;µrJÒ´¯DWê‰Nþ9º*1Œ†îDZß8— F¼¤neZt+¨¯E¶€= p¸×œØ­.à­òžޱRÕa°×;w‚U»©g½ `U§!~ÄÚÉ»ü=:N:$¤$æ³ Ø©5ʃà—ÖރЬ„»¦ò9¯ø¿x}A.Þý¡àÓ]“5Êd”3ñKW/y žz)UÝèoßøƒ†(4q€É÷¹‹"cŒ7|s‘7‡;‚•Ò<¡,}ªÿ#(ÚûMõ®b_V}K›æ­S—©Ÿ¹aVqû>ÐóSï€YÊû–sÊpw4ŸÙ¯€þ 7‡„ZÎ-Om;›¨ÖÕÿkÊ"Ê@ï2%µ·å~¤ÈñâÇ©ïËEDgù*ÝÈFPw°Y!xü¦|‚âçÑË_¯=JÒóH©)ßS,ŠRäÇš4ÂmCúê³ Eú¯vþß[påÎâ]¼³¸™¥Pa]Uµ'}¼±Zâú0Õáb²PùœÃ©”ú™®(ãýkνÊeïcÚ‰Ýî^9sV?¹áV÷)ŽÙ'ýE¤R™E­T)w$zjØÔi–¸è¦£$çÉ[ÁÖG þ¶ÿ×ñ@b‘zÎU?û$—(ˆ…‰Ω—œì eè—8­6u‹8ãñÞ\Òv0ËÚñ ZÊ'0Ôx†rÔ (é×–yT ¡˜BMçN>¥¢ý™ü‹ªNaJØ {.RP’/rc±!¾ ^™Ñ¤’Oé; ¸u ¨ügðd/R›C‰·ôC5Ëø"ßÙAÈê¼ Òøó!ò=.D‹Õ>D¯ ‘®Ê ZA)®[y£(zSyK¾¨æíµK)z¨ªµ†AáWS¯p»ù…¡qÀr>áQ³ý_i“¼‘”×úz½«¬†J_Aä7Ù=x µT¬ñ¹rôêÚBŒSú‚s’W!~H Þ8cˆÙzi(¬dNĉËÀth` C >M¿Øfu¿_.ñºµ+õ%n"ÓËB‹ßÇ`—ŒÌ½iÅOAi¼©%2j!ÔþÁ×)Ò?ÐkIa¶Í¬ê_ÖÞO{ÕÑ¢ÿ•ºS}È×yÉ¿Å;OÊ«å,ögã» üïPÄ?#¡!þsü¦"7³&±M6ñãZ€Ýxòw¢f>™Î r¨” é[H¯p¨ÄPgðªÚì_„ÿ£üÞr9q~á¨vl;—µ¯Œ¸]=(¶£§ÿy5¸QœÀ3òý6xº%ë`žW¢¬¥:xF#ŠQÍé ÌÔ3½¶XÆP5Jm­ƒýFµ)Môûµ½¬Ô.[Ëh¨§kÕ)­ž’€ÚÌoÅl5Ú&åò>w+©`MòÔ;ÃÉ﨓:Å6 ’A^åóä ½è(†ï‹çäûÎCb-_Ëwäor)‰{åvm$OeÜD=¿¦GuïNçêùë3q­oâ5м†ºÅQw›º›b;ÓYJ «µwQûšÿvj±{º»Æ8HXÖã`ÝË$HM§1Äv{ůäm…¼wO¿ FÆÕ%Ý\» ¥J…²!ûWm-vÆë|MçÐz:,½\€a´OÌ@ȉê"0/¸ó°ô©NØþÈÀÍ`ìq'’T^/îC®³M±q´O´wI))ñDuö ãËRh¼è¾@ÄûÈ]OÐý ˜AT\ –Ghœ®¬ âE çnã ˆq̇äÝú)¿³>×›£Z¬²æL„üR; ÉõEà´ 4çN½ù©ÓfîJÝo,bF²_à{RmÌV¼+¸Ÿ>ñ´P3Þ5o“g­zжݧD‰Ôj¿+g“+ÔóäOq7 Ä[ååúÀ‰sØgìrLÊ* t›…:‰±±·Å °[8žÑ%ßob\4¯¸%•"ÄR‘…‰£˜‘‡’e‘!É=– BpfªËìZªá.‡àÑX`“ó¾õ¶€>Ö×ÀLÄà +Fwáo&Ž.rcO1Åé A†˜¤|G?¹YÌãwïcg,åÙW)¥v-ÞÔÛü‚oµÃµÝõŒ >^8tÝÃsæ+]féœ?˜©7¼ÅZ];êl7ƸëÁ/¶€¬ì\#ê… ÓiÍpÒq9àÝŠÈÇÂõ¹HÙ)÷4óMq ¡ü$÷!()oEˆÝòR©ÍH±’rÿ.¾Dúa‘@‘e”ŠHï¬,Èñs‘9ÍpícJeDò<+0Ãu̦hɵÊsüdÖa¼ÿŽV‘m"e –Z¬W"¤,ÐÇS9T¬ö¾õØïkš°ìóésèeUe"$úë©–¬Lc|òûP’>ɶæ)HLH¿ßÞ«¥£mIkˆL- .DÄçKCѼÐIdqëÈAüâ›Â3ð GD^à‚eES)±ÚøØ­Sô¼è[ÇQÖÅ[»5ÉŒ•·óV‘^|3XËŽu‚P›äXüȽ”C‰tâ2BiÀéÀýü.;›#Øi «ôÛœ4Žƒœ®±Á-@Ó’îeÐð²O>Ê邘B5à”¨þåIð/j-p½VÚh4ç°ÞœÉn_c1Û¯[üÉN 5äÎóñnâUêqsâ{Î@qOV@áxL(ü †² EÆq vÆ#Èè[¥F#õÊL”PƒÐnzfÞ\ê'ùXøM¿–PÃÉ£lˆl÷Èê¡^º·ÓLE?°Ѝâ%†@ÆÏÅ¥©/_ÉIgËÀviIkø/ @î)E{má÷i/–¢ªûc2rá*IÂSS-‘Q±]¤‚U¬^ˆÐ=ñA$¿byÄL5ä×àôx?œ@,5›Ê¡•‰– n¶†ñ¶ñ©üÉ;hj^Ä©­·'¹—ù¿8ûïÿ/Çø¾ç~÷jï…ö !m•iXM‰BJI(‘R4ˆÐPJJ“¤$”JB%JH{özÏ×:÷qýðù^?}¯Ïíöq=þ†ûóq>Îãq>ÏcYd¼÷>UÜÒC¸‚åÔb¥vÈuä½Þ|§šøÑÚæ¢'½Á”•EΔ‹?+–b'~I¯ÄÒW†« Üè+„V Ñ?Q)³£tÒ˜^ý`ÌJ¾f < ℬ Ô“ "@E± xC䂼Sü |©íÈu#×qƒzxUý¡”×n°Dy BG½ ”ÍÃÈ ›º7ì¢Ý¦–26“Ô¶šWY–:£?*G›šSÄÎÌNCÐ@_}š²òœe É‡ô¿Â”nZ[ï˜VS|àäÆ14³8r‚z©üø LHm4kAÒ‹ëÈô•hˆH´Šý‹“þ7òFâþ¬Íˆä§‘g¡0“; œ»#ò÷µSY{ø*}Gövn.Z¿a¿ ounJ¿I›¤%zrOr’ߟÇÄç$’£½g‰&ûbz?Å[Qý±ú*”X*§O+ï9i¤ŸT:QZ|Î-4ЗÈAD•"jp³ö'ÍÉÕúð'0‚ù .S”óò>Pc®È% ƒg€Dp¹‹ÂðwP^.ÛA%z ‚”Ì'½åu~ iÛ¹â¥í'©'7)Ýïåk*5½W oã=³b¢ý£_„SûLõé{P$‚Bc¢RÕ-Ö¿Í<ÇcÖúÔeîŠß’rjägñ}üÛtÛ°þ?˜Îv'qú=h6>ò‘öY𱸨4÷š¹ÐO ¼ónXeE¹WÜ• (]*9‰:ñ»ÓÛØ_›ÊÃÍ^œéH™ØW©K=™ ñΉðÍIö+(±xúMdt? 5v_æ6&šÍ2—hnM ˲>özÑpÖš}½¸f¦DTþn˜Å¯ó”ëÚ·Á?Ú´à/É“æl¯$Ú:/AÖãÞϬñVy!ßzG¼3ü+ w³ÁMø¯R:ZCޤtj‡»Í¿΀¬WÄlë„X„•Üãm€Ôˆ°:ˆ§ér>Èâ;ˆ¼-Š ~U/ñj¸ݹ¡($ÌÞÚ\²”2ê"|ûŒ²‡CÑõ )Ù§m`ºú—Þjo,#n5ÓÜ®L0~EÓkësd‹Œ¥–ó&Ç åN½uš²MûgÒe"QžÌ´ˆŸ¦~ÊÔ¤úÄlÔäkY Ý<ÖRã£Û ¸${1Nâ­˜…Y2/ë (¸?«/J®æŒ¢^ÉÞ¬},»òYÖ¿¡é®PŽ'vdÊM¬WÇÒJŸW¯7?GO”®!çkg‚ÙÁ­¬Ò0l¯ÍÓûùŠHj?yíAkíúJ7ŸÞXŽé·xÅ”èCýM ÒFú£™§Õ ËÐ^)ñ·QN!ÇSV]¸®¬ó[aª5è Ô“³ÊÇaLÅ—Gúb;0%À¯lz‰ç  Êv¼°Š8A OQ Ÿ¯ÔëăºÚ(Á¯Ê.®†}ÔWýÔôÔÎÒÐ_ª¿ÅoŠö œ>úƒœ >1n¢Qª¢ÑªìŽ &œjLSÿwüóÿ„üI¿½?Eˆ’Îëý‘N[m/¦;Øú™þ"õ[>ȼnµæU§“Q¯2"-©ä÷²:PßýÊ|‚½©úo²ozƒö¦ß>ÌRsœ×Á ÷í'úÚ·&:ÑMÿñÊfFÄUÌÃÆ¡Ì¥b´^z##×R+¨õlz)Ì[ÒãhyÂÍÃÎ=ù+Ò?Ó©¯tb¸ÑcN ¦!íª`ÌÊC¼z¦¨ƒ. ýì„È ÞPN†»ÁÐì# ÎÇú\Æ©nÀa㨪øÔ¾2ÊÝÁpPº¦:‚¯7 ˆ‰úÀÚ¬ e)wƒ¼9õ.x[¬nì÷@ð…qÂ{ä àQÛƒ±ž¥xì›ÌƒàvÓ.AêîÈhpVD‚û»Q’·GÞ†ÔÎÈßPR7ú4nâÍx aâ÷xEô’Ÿ³{£^¿žÝˆOKRÙyƒ~Ú /.~·ýZGÉ*ƒ ¯]c´òGÐ…êúèì­”R×*(ï_ÌßÅ[ÁzçÅ(ÃØÌVkcÓ[~Š<æ~ ÁAcðU§1È—Ì×À¿¡çDwð¶Ê÷Ám»9`oûHؼ­ú×~1¼R_ìË|©MAêc~dZArxÄ’Ø Ê)}ÁÚeM n…°‘ó>XUc; jÇ7@Þ€2¯!óJ—:‡WztÞ ë— ¡ÖÙ€’åYýØÃ.>Ôûyc-Ñú GZ¨ÏSËú$¼F`Þ'—Ë„yÒ¬,Ö~g†ß]í \ñ‰G¢YÎó(ÊV{èó\•ÑÞn‚ zCï²ìaäúŸˆ½Ö)·+ EO9Yæ¼ ¦þ¬7E]<Œ® £¨ßŸ`¨;ÃÞ f{{@ûEn{@y9(ÊNÖ8*ÏËûAüÅ‹ 9C\‚p¶¾äDù,øÙr0°Æ¨ò}ÿ H-îÑç¡¥¦†iü¿9×þ× x -ùUy†F%“¹šÛYûåfKíÏÛ÷h¿ðƒ5S›Eåym´8žl§gT=Ün~¬:™õïŒ;½'´¬È–ðµ$xR–WFzWýëäe&»²ÿÑkò@¦@4ã¡ÔŒÔÝ„ædÕÌ®%_ÔÙH¾â%`Ü«ì†ÈF Ü»RÛÀ[‡ á1 D£d³€)þ+dÔeú)B½˜ÌWÆ ¥´¿TÑcC3;(e¿a|.Z:éȇÎx)Þüá¯ôk¦{<#˜Œ~NÃ47¹ÍéfòMÜÌSòSL}£¨Vcî„ðù8¥iÅ5Í0ö«.ÈлJÏáû}½õ¤ìUÁDì§e[Ú§eZnKÿ­Æ„•þÂX*ó¼{ÅBû›àžJç[ˆ²Iµ²lŒ?qK#ÆE¿Ïû.øÌ¼_Y†Ú9:Ȩ߈oÂïx›ýáH¹Ãý‚Nêuÿh¿xµhgn ¾ PyÌËg²¸†Â¡èIw*³™%æˆ†Ô´Þ ËÒVž¥[…|ïFñ†ð4o?9(jGQä½FWܬ¾ÊÏØÚ[†MHI™ÇQØ/þKð–øŽ‚ò÷)¹Óí4q‡2[䤱#mpQ£yÚV ë7 <³’_Ýœ$§ñ–1%Ìå¢q‚~”2?Á¦–ù“³®Æƒú1öé?ýi­Žs{J_ëý(Ø)*ÙÍÃ9êQõÙ™zÙ`¿Øg”åéPÅ• ¡øÞ ¸¯…Y\ŒCm§É¨h¡,‘½CWøÚ÷1n×TûqWŽ¥ÓZ]OÆšž¨…‘Ù‘>ƒªJ]ãDª6„ŸØ7ƒÜà¶}zÊYËù´ÑÞàæî£|¦ˆûô²ÿ(:bo0 Ôqú`̺qª¼èFTSþ Ÿâ°]ÏÏгÚ.Gž1"ÌûNÚ¹Ïz–Þ;9=ùÕ]–'¹œhé+keæ‹]<˜|6’Ãü³Æa*Ú¶Ù—¬L ­€Ö™ÑÖrTûh´2µ,Z™-™ÜÈÛò—ôMñ.ôOgß,üÄ-ÑÛƒÛRy‘òîëvhNqv9[­þé¼ôUkjêqgŸY:1Êõ•'RäF>É„Ölê¥{Z9U<&ë ™WÏ{HnòÕœ…4PÈš&~Ö’fsQ½ÔXë_TXIó¼‚Ü£<-vRþ?ÿ?úŸR¸»bä,sõœuÚ{›õ‡²_poå‚ñHz2[#ÕìWXµœAL7­L}N[ÛÆ”2_³Ã3f:_eöw’t1~q'ƒ9ÜyÌbÿ¡‘q;àéc‚ëª{G$/c“Òe(VfD[ÑßÜš¿Ž‡dÃå&3ËnLnXâ4æísí" Ô‘ú´R–¸Èà51¡lâ/#X õ‘òvŽ!‚ŸÔ\K:³]\wÒÊá“ôs¿Ð2”âf#ɯ™º]ŽÓÞ¥º{“±üÆAE¤ýŒuá? ®ÃÍY÷!ƒÚ ÌÔ¹èKäņ›ø3]Çúa ¥Yêw³£ÌrÖ¤¬kñ.ÌŒ‡‘Åâ—Ì x;ó‹ÂûÍmF¦ä.½…u"3S\5ï‘1ߘ}¼t·<…A~s›qƒÝɳ\#©ŽçQJ îäˆÑÇY‹.¶(gìʘú¹ôÇc|²Øã2]qŒ—¼¶˜¢I"áç_&G3D>±=”Æî ÌHõ¿täSˆ®=ÿ-z“ÞrœÒœ±ªö"}x‹bB¥MÔ}ªGA0@û“?¼*¹­d¥tnÅꢞӂ¿z ú3oÈ”s÷*»4¼3â)î ßÒÖ?E- Ažz+WôAtöîÒbàï4*ƒ{ÈJÑßî-©¬Æ`+¤|æƒø+TKÞÿF¶N´ˆÍušΊ^Ï|Pr&Vä6r£ÝüWX\RßEaO¥' ñeî«Ä8[n;ŠÑ¨ê*æÇ^¬Rгÿÿýÿ‚a1ÿÚV´Ò/½ò#ûUdtef8nÜLÜ…¡Ûn]þÍjeßF”¨Ê&Óv7s5vÍ}#³œmœ0«g\yÅxFþÖÒM9Âë¥ä8§Üµ¼fmvþD„ÿ¸’Kѽ‡ù-uÞ¾›œhÿ ÙÒð&M¿á^Ljœ”—@¼æ~‰J·à%‚’É^ ”ìÅÊ4âbhÐ J|çeˆ R>휨á‹r°;<œŸ‚ãÀq|[¹2åiˆWÒJ3I«™¦TƒøOfc‚Ì+b<>Í´wédÏÕJÑ^ûÕî¯Ú!^µ¾3ìq*êp® ­õ±zN=h6ެe’¹)R¯°¦vØ(6_)“õƒu+gì}zUÚ¥ËF·ã¦[F:òhê‰ÄZ”ÄÔøÓ`^M=‹H<k€ÔVEŠ×²Æ j¥3ãÕi™ÊèJM{«‹ïrÖóª¼#«—æfvFwd%«©¯è×džPO‡ k”ú5©²‘ ùÎõý¨™É;!ù‘p.v…ߨkŽ"öYŸÓΪaE=ÛÜ _ö6„ªÙ'†Ê%?\$ª*„w2Oy3ì(*‰ÊärÒ¢OÉêÊ«r¸¼S<+ÿ•çÔÖra°FyןUÞ¿a1¯;>ÍðÒ-Ñ(Nnf7eϳ›¿JAâ‘8ñùÉÓ˜‘í…ˆ¬™ÉDb_§jÄ>ÏŒ…hOg:çcëRŸ‹nÍ\â¥èùD¡¬oôý½P{[Ôvf){Ãûí3ôP_tkROý7SŽ“½Óíi™t¢º·2=ާƒIÞ(Ñv»Q7sŸû (q÷GPî[㔼o_C±n žõ4ð=·m£í•Ú~½ÈæTQÁotMôÓF²â}DÄz¨xƒÍÑFŒ2·DÐÊØ³ Ô±9Ÿ`ªkb/ëmá¥øfðp§ãµòr¨•óTx’ÁL ÓÐ{-|”§ùY¿™÷;ã ¾KÏæöp˜e0ÈÛR¼ áž”6òF×èÆ‰èÚªc™jýhÆ©®=–žÎí=£;š¹.øž\±TäsEûžTP®ù_3LY¥}"ë*¥”·Ø+&‰Í²Œh(uy)¢»üTŒÄ1“£œ&d9šó/`²†çå ¦‰±òñ𨘠?WÐ4æds…ánÑ>Ü%:Ò*ì)î%_Ñ|6y·Ê‡þŸ9øS~’~“÷­ÂL>u£³Õ½Û¨’•—:Ä|ssêeæEÏ'›fµJv%mcqBÄâÿÕú_à$íó5&eÿ+_Q~)ó¼~VùË^Y£7‹E%6TÚžº §ð‘äæÄßH®å‘ØòäbædOK†¡^Rà(O‹1d¹_©±Ý¾jgн·Ý¸EyŠÃ‘ÁÆ$’~£> ™6*²‘]úŸŒÌÜ®oåÉtëH‰Ø/ÎDþ6¸‘o½¡w ?4ÇŠÐêû”ž©0ñ/èC#ÒA»/s ¡Ò!]…†‘¦àUËzÌ‚ÌlÌôç9‹@Íõ†"ÅíáßT ³”ïIÈ&J’IÚ2s¥ÒìÂl«L䕸øàŠÕóÖ‚ÑÆ¼¼6^/aªå¼º|fDÜÀ|Ó~—¶Zï–Z3\‹KúgžÁ:cµÛ’õêþ†i›½°´‘Áv<ýR}4ˆâ¨Ÿ†gº\EŠÿ9ª©­ƒQ ŒC€h8”6òCP.ËoAÄÙ|Ç`&ÈŽâ!ó•~–Wê‚Ü,Î{”»ðK8xîå}j†¾ù9•änå;ÎKµbðVë7q!è£LçL&c–á^¹CžÒÍbåi]æx†¿ýÿ\”þ–Ûǘ{íq(×Á½•hæfc3Ò©n¾‡çý¢ÿC·~”)¶ý™—ý¶æZ4×R2­d†õ#§#:+b ëŒ8ü5ò©^&³=’§?i_4î _Îü¥·ðÞQ§‹ŒÕŸð›[2S¸jJn`ktiªˆ“±Í©jÌŒöH5 'R”©ƒ“¥%c íN`}é<‚ˆþà<€;œòÀX\„h…tUÐ*y3À¼Ë¾Œa¼ fÍÌÐ^sWƒ¾ž mÊÜ­šþhÿ8ƒ¨ì<ÊÛþPºz»@¹nM¾ MRë@¾¢Ù¥` È”9ä ¥2]ë^µhkëÏ»2Zô¡Âçf}?8…fm ¢Z䵬¥)¶GBʇLŸ¬+ÀT·,xýF¸î1QÕkù)Ý\Iª8>cpæ ñ,ë‹á³ kªdš…Ë8¬/Õ‘÷Xý•<ÕºÒeýýQ®Q?ö’þ@-½Û¹O9bØN=®O;o’mžÊL`Gt•݉“fÒ¾‡¯5ÕYA]s_Ž‹‘Î5lc¢ó º1Ú}UßéŽóDЩOK¾MRT`!I«•¿•+Ú:ÿ0¥õá µ~Ž©Õƒß¡,p?åW­Q8“J„ܤ¬÷]êkÕhŠTf¨Ýáp¿,ˆcòAM1@–À|¥ÈÖÞHy^y!Ðòwð„fs4¨.·Q)\n&yÀÿS¾Ã+þ £w„[”5äyϪ=¸á4ô¿¥´ÒÂÅ(¼: û—Nb•©í}ñ ’‡ ²•ÇpÜ—´æÔtm³!ºÜ*þbYâÅÈ á“ ŸînB¿Ì„ØsßyO˜y¬K>)ÇÀLNä½[´ŠµNïæ.ЯY9©'õ ~¯tG¥ó’Ó‹—#oØÏÐ'ë´6^,·ç«¥‰'6d=CV¦é—).\‘2Y–èëV!X’œËugÕ üæ§pE Þ¥•ùšºˆÖ*µÙVKµ¥LpI”3öØxI#ó3è?i&7)KvƒÒüÚvê¢_áŠKÁ{h> …rþ›`NÖ'‚Hˆ6 ßçEàÊA˜‘°‚íø nOÌJ….ˆ†ê0ð:¥$xód;ðwÉöàVe2ØÃÃaàÔUÁvP!}Í»R[èéÙ\†ävlH¾E)(.“¡¸›ô È“WÀ—y´Úa?`“}"s¢«!7Uê}(÷PÅbdÞG9•qK÷Êù3z§,@·–:ãÀ!ñmô€ù k#çü‘ÜÉ¡<]£ÑtÌ …e|˜¾¡.WË;GÔ¤5ß»SôˆpNÐ&f#©}î|Åg±Rþ` #RïÓ@a-êG{;Zëïž°Œá™Ý5>iþæ=ÚQû$¨‹`tõ"•¡þR\ýï`4ŽøDiIR{ÈÞ@J½%l€&ªg±•»ÂZ¤ÔDC¹Ì•­b˜€+ëò5BvЛ+˳ЂIöB¯UT%KmdM"þ–þÒÓƒï1ÅOLûÿÍùÿ¾Ð䉣»q¶Õ¼ô^¡ME &¨•PÝ{µ”„‡ŒbgƒÚ—|/¡Õçdæc6üRÖzvØÍÓ¨ÉUÆ&Ú]¬ÌÍT5 sLià•Ø½‘éWŒH­S?æéTïg%[Ñ™<$»"Š]û4¤ºM¡¤¼èEÓÜ®œQ΃¸á ê#² ø½Ós€Ù Êrnù»œaað:h ¢_¸¦ýr·âAz{â_ðJü“àJ?¤&¤?wµ¬^?ugôf “qÜ»Å:ð*kg!zé? «Aé¡ôseKWW«è ˜3߃?õÜIÈjï„r *œÁRÔªm†¥ çq1rîÒªbg-Ëq5ëxX‚?$ÞóºiÌ-©«œŽÝ“~W64fª‹¹‘ÙîzzGÚÛOaêç¼±äZ{½šXÊ*ïM°6ù(ÇÃQ¨`Í–ÓA¢ˆyÂïäfHߣ–ø3ŒÖ\WßÐvpÃŽjyw ÍK³K›ëœ›#w2Ðù2ö6×JÆÆÐ6ÙЪäîõ¥Ó­” \§UÝÄÚþòÍä«zå½~mý®û¥EG}¥÷X,lí {jz_P=öˆû#¿)=½!44O¨b}âí ²ª¹>QÑCxÄ"›[1‚õôÀ56Hz;g¸5ÜÏ!lcÌsª^"eäÓÀ×À/òEšØ+ YFÕ!|!:"OÜyó‰ÖâwP’üßåÈYÁû;fx ÷R_¿ÆÌZúˆ'µ«Ù/DZ=IÚ<,SdEü‘«’Ñ›B뜼—¸9<ÜA–!Å\9WÛ¦• .«ßé?ú]•Õ†~6Õ»ƒ¾Ü¢æ¹ õ½k7![9ì§²-Ú1XDý ÿ<Žÿcø»!Ê,¦Y¯hIÖD d’$µÂÖ˜á&ÿV¼ÂÊ51DLþ¥öá&U5iþ£7¢Ð©¡Ö`®ûŒÖœ¾þtã]ºøÇôtÑÆÒ7ÕU?<àŽUNø¥ÝÛøÍÀ~æÛ Q›5™³þ£ä¥ËPÒA¸†=Rw‰/!qKø $þ`>uÌ4™}ãf(ÛÖùʪ4Ã-Ó]BI™µb ¢Œ*ªfýÀ#Åß©—ã~á½r}Å{‹e³+ý̨ì£ÅS‘ÙZ*r7'z ²$–àF›»ûÐs‚DÂ|#õ=X·;W ‚}"#¼°¤ÏóÁ˜YÒÄ÷zO0?Æõ@z(È¥Á+ š0Œ€ßÄtB¹Pÿ ¥Êu.ˆ<|o™v ß_§§Þ,õ87"e‘îŸæ!ÌÌŒh 2éÇbmÉO}[MÙÄ¥ÜG8™—ÕœKEätä⪹cø¤èz©K2Q°«Ôha,,s”£7¬øUï×”ÁÜ¢+l¡êÕ'~ùGº \o£|Ãß™3¹•yZíZîgYÙ›JZ¶£®þ™x&²®ìzê?jãÅj÷0ÍÚ£Ò§|°85 %¬çuF† äo˜òœrQꛆÓpº\üp¦Ø¡žùOïC ¨ÏÈ““ó‹©7ù)Ûct¥Žé€ÞÆGé§©lIÐÐ(9D,ö¡3;«¾û ºQhF‹Üjëûè}½wÀšmÿŒ£دpݨ$+ ›½b.êÏú•¹a”¶=¤V‹VÜ¥½˜8Ã.½¥ÓVëºS©#g õ'Ìˈp{zG”&n^¨(;ÅzÞS÷8ŸËá© `?QYô×Eù–õ­¨)f[GDžL¨Ç˜¼ž¹›Ë²¶ù81ÙJû•lï Ñé÷ÐZñê ¹ÃûJéÉtoš•¡­¿S_‚ĉ»;­[À9d|Î ½¤®Gb8NÏèí˜ömÖ2dú¸ù3vʯ$’¹dUççÂ&±é¬MÞ{‚œä꬇8ëhYO³²ø]shлàa¥WZs¤ør•ñé½—»òuôçËÕä?¥kØM"Õ¢ næœI…eåC9§‹×ˆâ¼ü’Ž É]\"¨”Ȫšñîé²ošÚ ‘éγÈXÛ x‘ú™úyÿnˆ¶u_}„W´éØ K»9ˆB÷ˆ”ì€/j°Ø,¶¢ÉúBà ëe e‘5É ÿ3L»¦õ/¾Ü|Ž|çAë §2wÆçag¶F÷²-™ÎÞljD$ë<ÛKÖgבˊ‡Æñq²~îhùZñšÜ{D¥ˆo še%ä?‰ïô!émîåxr‡<«ÆŠòû¨[ Ɔ÷P¹”ˆæI²Õµ¹IÕÈ*KÜXžõ‘¼jvŽŽ–Gbuã;Äø¬¹ÑŸäýÙC´yþsdòn±ŒiÇëµzß-Td9ÿá¸ÿ£L3HoüúØ~¦` RÜ’ÚI;“ž…ŒMÏE‹VHÍee¤†³Œ£÷¥²$vÔÄ÷Ö^¾ ŒiÎw®©¼­Ôu §Û¯ñYØ1ý1s‚{•²áw2¥”G¼ãT-\—˜öŠ{ìfne3ݯAÛ”‚`ß”ǃF >óRù lJè¾æG5¶È•Àf™ÎOþ­àþîU刜 lb,`Š[6ÔþQ΃vPËkºqßÝÅE4¯¹¬z=ã ØO±";#w‚7YY„¤‚~„ ì¦WC ×ë+ ج?Ž­ö²6`…=ͯyˆ§­8ž±Vñ>«"ÝùÖnÚˆæê°›vMÝï ˆ°,“Š”åÉTìþüž¬a$¹+ñ~ü/HFV@q§øJH¾‘3’uãå ø¥¬NxEße@/™“õ$³‹~Íz’YÉ=¹õxûúžØä0UØA}4•ä6Ê”|é„ÅŸÊï0ЦArMð<¤Ý„êóáBlóo0ub=ÙÅÖSüLk"¿‘­Íåw¤¶ж"ɰ Å1 `àÝR~ÞËN#@Ø)O¡íqUædÚ©-ÅžÔ2Ùv™—¬dÂQ."2É-ôã D'” 9ŹQÈÉ7ÿ…Èn(~ìM±-þ®òoe½eÔà·x®ˆ³6úAðc0,rÖêœ9­ïÈ2é7qÅSéUûÚÃAÙcŸäC±Î‰ñ¨Kú[Újq÷u¤b¹…ÇO-ÄѶ+0„ãÌFð‡ß‡¹îLŽûŸ‚r‹?’îÁƒ(â6?ÍNf†’Ùa9ïIÞ×ë«&‡Ýí¶E *„o¡V°‡r¹¼@ Ê‹q8r*ÕÅWhr½¨‚%š¨§0USÏÁÊ,ñþd”‘1ªóf€ªÓÌhúPk&Â[Ä£8´4~ÆTÞ4·‚?M=Œ2Wƒ×Q‹*›#ïâ{Ÿè“0¬§bQ‚pmäªsÂ,Åj²c“ÙÆÑž|èWˆÖ ;ã÷1L¹±åßò3õÛôÙ¼EôLLHù’ý±öÈļHeDÑ=9OC‰{ Úç‚dëø4¸v#ç²äù\Q(spþêîÜb&—ËÀšâ³Ù—Ã× ¿R†”´±7°»ä`ôÊ+ï54¨¹­lÇhb~G]u¢Z.Ò>/É7”˜ò“ÿ‘:Ïh ŸŠ:xŽéæ@9ÎbXXL¨o÷‡ (kƒià=)|°n“mAý"ÈèÖ=ÐXÅÓÓõÀ~<˜"¦$Àêí”.‡#©êtŒä¡Šwkä¡÷˜:×¢¿ŽæTÕï@³7Y?à{?YÓÑì©F=ægn·cÛfdÓó#…H{³u˜K‰f‘}ädšFª²,1È<Tó•Dæ…ô6>MßMýKö¸ÑÒ®¬ÇMìö§c¤Nª÷Cr)/CaýK] ˜rmÄžÒ®@$­®íœý+èÛd WDÐCÇ7,%Z¯` š_ƒæÑ”Ê(PZ8AþœÊÛŒ: Ä(9 ì –á})ø›ÃÉàŽƒß‘(¸µIƒ“Gm°_¦=Ø{Ø ™ÓŒ€ôíAê!1R³ù µdc(ºJm(ü’(äo¦$>äoÐ)×!··u J/eC´ŒZJÿ•# ôy¡œ,õÄŽ+"£+Â&ˆÈ¶`"ý•+ vPÒ¼ËÒþdotfð(ç¬VòIžÄTüf\QžôÆ©gÍáv}–ë3¿óilV¦*õ¢Ïg†1Ï;Í0£ÂÝI…è§ ÕµéöcDŒëá-ˆxÇôiå‹ FäOç#<-ã´ÇÐp_ã/ñ)ýátYþP»Êã<¥÷q>c¾zA{¡OIJN‰ÞÔ¢‰Z×|œ&úlj)¤š÷eø:vŠZÚ6&¤³l€Â ñ4ˆ=ò-BYQ((¼à}Â_a¹Œ‡æ=MRO,‰q@¾•y†‹Þæ*…ï=÷7sn™ÛÇZíûÿ7çÿû@ ˆñ‰‘˜Ù#/¹5Úšƒ”«”ïñüÇô­ä:óµ÷Á|]¯Jyg¦Y‡ºæa£ Šmø[™`^å”ò\´{­­± RÖGW?JÖ‹ÎR{y†V#s–Qj9µ*šè>a w/„´oÀ­hgÀY’jâwÿU »ÀmdCÜÉ, fAôiý_q;ƒójI P¦©UäDðûg®¿ÑüÝò~È|ëô7|¢$zŒ^V=P«¨ A¹ê:9!·«±ìGƒ™ VÎzbýs¾‡ U«ÞÆ nã“HuPçä=á§î ðšx‡Á]_»!d^JCØ÷*pmôõàl®÷$7|EN±ÚgP©.n!à ñ j?DßL=ªW÷V‰Õbc$N+nø…g¼2Æ.k˜Žá•ˆýhzW±›ênsõÊ©¯ÊS\W‡Åò%{’|\|*~6gäïâ.Šeõaù[X^ÍâªAo&nrÏÇ¨ç¹æÏ̶?Œ|Î+ö¿Á…ô’Hšìä«ÖmžtÊiU¡.¦¾?£b1Mô=Õ&…GÌ&e*{BëkÜgÇh,jÙÿ²0ú|f1UÍ*nNd]p^¦Øèàîã{#iwc ­ƒÞôÌÚé–Fh/» A¼„ÈF hŠ·Ž@yÜ»H  Pgb™éL=†ú7Ÿ›cÁJÊ{@ކðŽ€¨(~Y¢žv{¯@¬¦÷¸«â5@ß(ÛCÅÿÝûÿG&y¬ýb*3«´3Yf»œ‡ˆtqDz/[XYD–[ɱ”DÞa47¬;ìyÈEO¿¿zD}Ùë%2;¸ïÐÐ:à=Iu§ë0#2Ò@D{Å;ÄïÚ9¯57¨ì¤\ì´ß“lywxeÍ[ÃfŒ ?÷¸¢²ì‹¡­•‡h§Ê°2©<΋ao°—© ÁºMª¼ 6ApZ©GèN’µpRgŒI}ªÚ˜ºÆ %›†é“Æöê7SË©ŸæzfŠYŠúië´2T³ž0údž6iv8U<¢}”¹‚ªÌ r Z'Ëýàg7ÀÙé<Z.ó@-%û‚_:ý/ÿ€ôi¹ÒG©ˆæž&2áU²Y,’5ÔµÊ+¢KÖïY8}ƒŽâü2~^‘9^Kæ)G½ÔQúxIùÄɧ9·è31äuwGiñJ=à.Ž€¸È.`q°d«p2È»í÷ÀÿUÑÀ8át‡ vøhûy Ä'b.P™F¨¢›Ò5¼Á½6)ðß×Z£ù%†Dó&šO3ÎzìÖ!°—F=HWŽ6CIݖ墦bñäõä°¬Ÿ©Y\3g4§K–äýΣEGKOù«Ê.³¯?žS7üµèQ« xƒý•{uŸ3ýâlàÌ"]QÓvv WG•z‡Òñ¶Y}ÅV#+üNühÆÞõe…tW†ÈÁ×FªÅb Blà Èùa ð‚˜Ò“O€¼ªÔ„àso%˜·¤«`“ÿñûª[•;ô®bkÙ§3 0²îO?Éý‘çœæ„YÓÒC$L¯Ç‹,H?AÄf'ð­"w2éø¿ÞÍDÍ}v#æ˜ß8­¸j>íLbˆñ¦÷!Í?ÝAülv´GÒØ¨ ±ó/¢©ï»Ï†WôÚÚß¼È7wû•Õ'Äæ°5˜%ß#¿`›ÿ0Bù¯8®ý*×s7y²)=´=òc„þ'/™âY‘ îkâ~^-˜@¤‰Ò7r§p!Ñ[YK?u³ò©\,V Ã7ÍöjÛ RX‹?¼£ÚxÖû'­gîm†Äq‡ªû¹Ûþ2¶†MÎó²íÞÆ|T«¼Y3}ŸÕR¯EÚ Ôû£»‰¨’í@xñõ´ôe®ÓJî)v†KÜ€ßÜ”÷<¯S7çuuµ:Ö2š,î'~ .:yûÿfŸá`ñ(ÿ5QÓ½ëÚìÈse§_(ý}|xpBß)Føý´?Y,Ǩ]i('ä?A õ¸I¶²Ír¥’á\p\ÝC4x'u"ˆ‰(†wB½Ö5çynSV‚~X z'ÿ ¨ß‰¥ ~™ÊΣ‰9 4§@Æ•¿ÐƒnZ?ð˨¼ÎÖ*ð6èÇÑìE‘éTp^·¦Bæ§hKM_ŽÕcÒâçäôD&ûEžITÏ=%Þ(êTê;(È/SC4¿Ñ0·­_´8v8Y+½P½TøBp'û®ôc1wü»——ù÷Zk3 eR™,y-úgô6æLÎ{ŠOòìènºÄ(ç¹7k‘Ý6øDiß$‚úæÆ¢¯2½ëMqäiý;ªqšŠÿLÁC š^zßu£4ÂxÊþüxävÄVØÏ20Þ0ý+Ç&d*°Ü*+WzÛŒ"ï¸ÝHT¥Oæ~Æè§mhêKï႘a?Ê[j ç0/;›Ü´ 2_Ê´;…—œP:ûIP[{?€¬ì~ ÞTß¹ÓÛ a· Á]Þƒ=K¢ÈrþJÜAz&^ÖóæFüH¾Ö×¼¬F÷*IîGÊ—9œ¢ªX¯½ˆæî@¿òT¦4z<;ö+èëÍ U-ˆõH¤ \?⎼Xî"„=T(hÎ`ÑŒáѧÂæÆ~4ÿ ³xk!|ªuŒ¶FxÛ­…Ø~‹ÈünüÇ·™FÑJG½ZüåÈäüYÖ'Æ<ë/é7ÇMf)]"w)}r_¦dU¹Ãë ì²{€ëy R+ü Ý9._Á¶k„y!(§Èé …, +ëË”_ÂN‘m…×ø^¿ê?B¾®FSZ]ž™ Ê2å ¸·h7£$Ÿ0ë£/*ü‹óaFCj%ÚàŸÈ)å:%z#MãºÒ'܈ÐÕSŠÕzÈàºw…áqõU9j¬ä~ÿcùýÝ b“ÂÏÌ9h2ÔSB‘Ëâ.íüoä+`þ]a#ž©ê½1Œ‰Îð?¾z¬Ž±V™[A«VôX5´“hYý¢#HÆk‡óy>~ÌÞÆ¬¬Ur¢7ͬŸ•h)ö +19u“&_f•OþÂèø]©¡èÙNÉCØÖ©1cãKŠÐã›S}@»À(än´‡èo7º€±:q¿æBäÔ.ÚÍþX·Âq²Oürð›(“]?µž×¢/ÛŽs»~?ëÓŸ‰ f˜Îeü4Õ‚K~~ú=Pzب¼š„RþC©º´Òk:˜#ݦښ™€0³ü;fÎFÌÌ­éE`¾ä`sɽ+¸à®à²ºØÿšîîrw3 „ðßÅQ–†¢‹ü <+†ã¨V _¤¦ÎmC¡?$¸ ÛøEÛÄír¿üÉÔCP–W€×Ù a±\ ™Óî9‚hÍHªYͺ‹nåR6eâÛ³zp ]Ïo´‹Œ¦V0D{™ò²‰ÚÛ|*¾Ë­£´òÌ™7:¡ø­_0”FV!” KuF *[“AmŸÅ@·k&ÁÚÇ6£ÈBG¥—ÛÉ]Ã1ùQöbªöx––ž¦–çÎRÝšé1¼äßoýLƒÌÍ^©U”¯"¬Æê/¦¼z–²áÎÐ× Óç¬W(nqßd…_:˜Éw¨Å¿©÷xÙÈ+³L¾P¦yÃû‚e¦SáVÙKI(×SìÂðÓ¢=¼Á Õ‹¼“hòjP€¬—<Í+’[ù=ºßíÄ ž MuDWFG;8í¸9³F )x“ˆÞBmG–±ŠD• ò/¶<$~E†ç—½{‚Òö=Ê‹9oÌf™¹GÜÊÙ°¿2”·3žf’dвYÔ·ß1OEªSy<øÎ¨¡j¢ƒvžoµ§ÓøãêœâõôÄO6¦¥åÍ`µòrbhŸ”ôÀÉêb?‹©½À(ø‡¥…½¸¥ìã…­ø9µÁl‰ôfF¦R;oÝE}÷1­Ý¢û“¥ ê @jS‹ŸE×ÿL¬cIê Äk¦ZBVnQ”xçäÈøž’©–µÜLë¬QvYÊÇ{§ÿfZÔvSqRù+U“>áÊÔ/|“©‘™ÉmʼÌ!lã}wíK6¤bXùM!¼hoc³ 2}Ü? è’yÂ1Þg¨îf*Óƒ©Àÿ( ‚®PxÉ=Ê3\㪨 ÞB/Óƒç!±G¾â%žíccXýÄ Œò¤§O€; šgýÎ[ÊEFª7<¬G¨X¦]Y) Ò3~X ä«:aú³´̉×mAc¯»Ì»]ßèí4FWƒ8øÛÁ¬ï¯äšú¥{™B½V0”>ZÕÌ`©­•ñÔP_ušP  ‹i/öˆ™øÚv÷Aš)·û‹䘛A h J#÷%â]9oÄ3„\P¿%&géOƒ|ÚaKûudðz¬ Ûx[;AN0ͳøÕ¯ûMÎñþb¾s»UŠ‘á~mx+8Mž3/¾SÞ/Îâ:µv„™ïƒO1ã7³ ‡žlÇü/É'³‹%ÆsW;1¢ÜGþj’Þió8EÎïüËN{cì: ¯aQyZØ—Õ_(ý!: Íù,ºß‹DÞFfN˜ÈN/1Ò(ù­9ƒ†æ–¨ÂíF¤€¬HǘOIê`¬Ô©úsă·ìùºÔbÊeM Ç1_OaDßOí1+±‚?3·² ó(èVrh?§€¶Í)ÖâÌa0&8cÀü8ã€9ÊŸ VïÔbгÂz`¦¼ÏAŸbßZñè#’UAÍ 5?YÅ Õ,J‚(ÆAìL| ÒÍ€EY{!üÌ{ä×Ú0vú‹À/º4¼{JýÿNû#Ó xG½Ä7V=³"ȶr#E°›Ò2…fypžÑnÅsç«ãp““"‰e c£é–ø.ö7·—¼•³‘]…Jçqÿ¥?K=ã7*Ùn¬tšç]á¨jÔèÊR›nzÐÍ3Õèû~ê…c2;y3·rz²®eÊ2ƘŸ™Ë×V¹Ì”D?u“Ü»5Ó͸Ãþ¢½ÝøÖ‡éçÉX™Á`4î%bÚ™Y42=Ϧ‹9ÇéN+#×{œöÖ÷™O©¯M?ò½yÄÿ„ÙêE{«\©5E Î*“d ù§(ñ†í”ß”Åa‘è¡.ÐÝΧ"µÕr0]å]à„þ*Hgd'þ.î-¨ Â¥¼,€ÿ¹|›ñ[”Ã`–×ßæµ’¾”è2=—UÌÉéªG0 爾ò¯x¶¶Œ »Ð!¼Ùh­4 ¶»·«Oo‹è­^ƳöÿοÛ\cíõ†´¨xJfHÛØËg~eãy.»×µl÷ª«Øê&cÕP½]b:ZæHt8_‹ÀîiTÁ·ˆ¾ÎÓÎJó>HGºU"ú>:æÆÅÈú$ÇÆ~d‚Üß©¶JoL‰¦T1ï0[;MDKÃm—ÜÕü =+ÞÇQIlÇ-ÄçúÑ( Ru°Ü4ïƒñIPø”: ôT÷ò¢¬†æM’í \ŽÑÍÜèáR`‘§2Z <ÎUêð:Èeƒü ÂÚHÊ„ó¨îËÞCàïBg7½Á9H po; ó)ƒÀyTÌ„ôlŽCbƒÜ E d/(~]Þ 7äHtå dÔ @>›ó,˜M³ ¡šn†ÜÍ}MI@…meŽ@ΟÚXÈ­ úûeˆl°¯Ad¥_†kYŒÙŒŒáIFÆ×©k©½“4vö/1Òj¨ ôöë§ÌRöu¥·õCú5®Y7eJcZeZðBV?{ b%öôµ"öTæjû1óg÷!”XåÌ»`4²wàhî½èÑG½M˜z÷J¬öFJom)hã¢o‚ºÚú”%‘‡ÁÞz‚n¢è‹ã?@Ö°2+ ;ÌÚ ¬õ€š+÷CðGá9ˆ¿—wȦ¢yab‹ªWñ\íþàè‰Ñà+.©%>åPq>Ÿ»r2AþOÈé]…œÝT§(ÞÐbMŽ'ör–óõîÖ`÷‡ÈA½Bpܽ‰÷œ‘n{\ûW·†>Â}ŒºAЖùE o€:VÎÐBŽ¡'‹ï@¶Õž€`¥ÚQŒÐr©î}mD9ç5Ñ÷PÉ»j¾*9õÏ¥™ZÆ›§^P.ûm²»Ñ<œg.%OO•SdãØþri·H·¬mv#Zê×2ÏPé“ÞJW³l¦ˆâ?8ÿ’¥p]ºX­lÃ,í_``<ÈÜb\¸"Îý Íó®^ä/õ­`/‘L6*e•çP­÷ÃQ@ÏL>p«,}‡ñ"hmå­Tò¿…ðWåPç^ð7†5 tÓ v6îŠ9 â[Š€›™ø_âÏÿŒ!fY¥A!ï%ˆÝî…ë%ÏPÉrØË]‘BYÑ‹"”?˜[ŒA^ZMyÑ}šg­<{"Š9×.ÇÆonclë~gS´%îíäë—ý~s¨WŠúÚ¹`)Ft‡›‹ðöùÇÀ”²Ïû_A8_ÔÇ4y§{Âo²¯ÿžß)ÈÇÀÐs!¶FJcc˜¿Ê>` »¡pŸ±‡ˆñ²šEÄûSûøP¿ÄHãv5‰UÆ~|ÙÜjBùà!o(%²•ß”¦þoÁ9ÆDÈW•së,Ïl’Bÿ0G®ÄwGoASʸ¯’§å¬ÿxcÝjœç´ñHÎ&(÷Cý»-¯h“2ë‘ÉÜÂ~p±F~”ÄéâèUð…×^ßW®žS¡T™²=¼÷­S‘-Îm±ÛD¶s>2‰ ^[ëU‚¾F'vÉ©æf¶µ…oeO«õCa=„ Fez ‚ì匶g@pÉ9îœhŒ›ýCàN žõóÀ¥Ox”wÅfà$y ßU&BxE ¨ ~þÆðªšok{Á‰G¾ÆM÷ŠžÄȉåÓ0Õ8~^Ék9=˜^²<! Ö”®€Ì¿gr_á°Ró à­¬Î~&5Ž´¿]/=ïwåÌIY±‹oŠßͤÌZ½ Õ×sf“ûš¦¢Fr´(m¼BuŒÈñdÑo º»Ó@^ÊøÊ­Ú,T±AM¡EXžõ Ü#þTV€M ½•¨¼Ìvþ'þ_ÿ\íŸ+÷Ò9vÐE÷ÜZ©Ÿ!25ý"Jì‡L âãœO1âWl Ò2UͬïôFD¦fþæ’•Hà´Y?èLk¤»‹úVi¯7;EÁRm7‚´’ëÍòÿ´cÁzJ…—ý\Qßöªƒ=Î{Ž‘ׇÁ‹û¹œñ_ +s-2Uç-¿cØ’9¬ q‘î¤ÈpŽ;¹…MŽ9¤Åqå¥b·+ É)êÄÓ„Á]Çf›ZŠwR]Ô¢’¦%j™¥SCÊ·«Z_Ù«PU×ù£ô‡Ä*¯[d:8¹ù'(L?jAž19òèçc϶"ÖÔõ¹ êg/q&RüÛÜ?Á-ö¾Ãó§†Ã¸Ó™Ρ“6\”ç«KNú.µsân£Q¢&iíý°=ÙÞ“â/n/xÊèÀ‹7ÙïY±òלgŒ9¥åÇ­™ÉT©ñZ·økÅ•E$giqÀäœ:EßÊdîÓ …³ÞKÖ ]|cêîˆVÍÔæ—ÈËΑ¶î±[PÉ*çý@-ýIoeô~„66ØMT#ç!ÄaÒâAž|T¬àjøœÖ˜óÁGÚŽz;Œ/8ï•ýdÂih=H)»r´=›Òócg¨š^‘ó­‹§geIÃÜÓ"^øjî5(Žg¾_²9–ãŒM3‹J:»¿)ãò ÒúBm1X&Îǟȵ”NâÁ`S¶…ûŒ;ʤ³f‰]e×G i˜}Þ;Â÷Y‡ ñpÎyõ0õ³º«3<þ‡ºÂþUÿ] SOѸԹäË4‰åf“¨YÁ'bÈÎbêöþÿGრ¬JÌBä¾QPŠ”µ$ùËbŸ§†Ó*¾.r.¾—šAó1¯†ÝCtQÖ¥ZR›n©õÔ ¤?e³ÖÁyzÌW”³ð‹|Òná~»>oÙ>ŠøÓ­Rs†ìåµ…`§{”Ác t¶‚6ZŽA†cÜö}·|‚3©v©&VUfÒ»â‚èLÔ‚öù ÿî h;sƒ‚ ^¤;h#´²YèH°»xW‘Ñî±ñˆJs›±ü²u®ƒt%Ò ]_aÞwJbèw…/Aúzæk¿Óº‚6Ä<ÁñÌTyÙüüC: ~‰ÎÇ÷û8£QüWÍÎXaµÈAns Ç¡Xåµc¿½Ø[Ï£bRöau™Ý0²':ʪ|"g«?ƒø   xuÂÀ_$Zƒ÷¦ì Ñ\qR›Ä,à3N`¹Qµ >ÅVW¦†ÎxîL_÷%¤&ñ¦ZÏ} Äì`N $ÖCø»ö>øïÊ)àN NAbdêMŒÔ^íA{@¼SÌÍHŽõRÖcäx/ÄZBdhô,ˆ†n{Bó¶Èl\½´ª€l/óЕ‘A+TëÁ¬9©?büje¨£Ä ÊY/¨‡®TWAi#ܲUìðÜøH¿yþ+àž`d”gÁºêï&cfŠ„H£>Çã/*ï{–ùd$'ÑNT·¼D¾É}¼D¡ldAÉe¾1(±ð£½í!²Å¾«Ìââòȇ¬%Þ0gr¸òÈŸ B-~¬N×40^Lö@‰=›¨±›2wpgÖ éâjÎt×—b_ø3sÔˆ÷pb$Û#›SýùËù)y”rΛ©UÜdôÊtĵÛ&Ocè[ìßÀúÈ™ƒç¿ŸÜŽê½ì,FÑ7{õ =&Ñ¢[äRP¶¤×¿Ù[…~i·à.ëQq„é?J¦ò‡U_)M¬wv¡yþ.>ñJ{ûäÅØßVÈýùíó§ÙYWâÛÈÎ}6¾\~“êWR%¦ Pã)ñ´ø$ìÿjÕ´lñ®2G9.ê{K“ݹ”|½x€bGÊDO©KÍñÁÜéœLØ45£Æt·Ebµô´e·q‰ÝñüFÈÈC91„ý†x¬éÙ­Á¬Ÿ9ÓjþçÖÏà==òŒ3Š0ø*þRnôUí'9‡QÁs2‰æwVös½RûCܬŒˆšïz Ä{戼]ü«½w ŒqÉk Á‹|ø=òOÉÌH¾{ (Ïqç´þ˜â¾ÂÈÜ‚+_à•ŠáŒ3z’ç=g,$L ˆ®À‹¬]Ñ£+Rc¡àùâ—@ËN´³Tá~ÐÛ”ô#•è„´^OODÄw9‘Ù‡¯gQ'¾FÖõûX Â7“opÒXZBñfú³ðSU¸‹©é ^·`È«¶ êïvȬJµ_{®ÓÔo;¨§¼“ _õî] Ä )ˆKÁ= ~ †ƒê++Án–n‰ÞîO›¯2 sÎ}¸(÷A°:húúÀ?ê$pˇ_»ÕÁ{32J†yÕ@ï)€ PŸ ÁZ´¿"õ ¼fþv¹Ì¿¨bc¬;ª¿Ü• «ú#Àí Æ ÷q”Šao¥†Œ{øÕßiU ¡¿gdÔ¯ÃÉä(dÒa-9•hp$r Ü"íÁyÖOAj­hEë-.UȺFþ¢Å¤Äj´*¤JYWí¿©ÂAÏ¥ZÖKö_èÖ—™Þ`Ló–‚õ¼3œÐ:ìØ„jsù šå¦Û>%Sž!ú·b" Œ/“‡¯/ÕZRÎØ‘)Ã1=ã_í¤ó=(uÍ·@WŠ€X½Œ­|ü-/ˆ¹é2$âân‘RûqETÉ««¤D å ùŠˆPZüdÿKŽÌN” Ïȶ¢RG¾_À~qÝä“É_ Øù•;­7 Àÿ"’ÇÈPÊ8xï{Á+9Çq÷èÎĽu1…Òn'u-gµÕŒ؇ɭÿ5ùÈΡ¯ìÉ—ÞÆì¯¹¤·šºUDåð#óˆèä=QÜ”sN9N,sgéKlqZ¤ªñ¥}¯ñ Óµ¬·qÍÀº Ìdô"XZô("].Ý•ŠÖñ§Rªs€<}OæcÓ‹0;V–&xrS‘é™îNL»’óxÅ™×ÁqÓsÀ:–*‚àd²ø«Sw€¬¾ ”7í{€÷R·òXæ>Pž 6‚¶3ý#¨#¼V`<è½úµD)ÐÖŠÉ tV‚¶×Íu‘y?hwÙ‚’< b¥»˜§7.‰ú óW@¼¡Ž‡ ½:Ä^# âgQ¸)ñ(„Im$øï’Þßñ%àÿ(æ‚*»ÁžY N$2Ò¿ç|éÓÙ¡¤BÎ9dÉöR·KtË{–:EcË\á¡ÂåñÚÙÊeV{’g²ê-#çÕu­šoUiîÎЕ{'s{ÔßS-i;š©È„ì÷RsØzΑŒ‹]L•b›ùJæWüXÚÝCÙXßLY0 ÜSËØ€U?³͸ͽo=éKh&“OuÎëÇ«²¿Óh™À8c¼2>¼KýÞy9h¥Î‹,G‰9ö-Þ&±Þ+ç.ätö>¡&orZ±z‡ux6UßYK"÷ÅdXÆ›ÃÅäïnˆª¼¦”æ|nFYÉJ½ØÉû|x‘°™ü=ÊNJ눾,Í]¢äf«¬Vš’ƒ֔8ÓØGÏÜ…fe*%WË]Ô2šqQ/±ETàWu­~‹Šû³>UÅ9 NâoCÖ@6€ÿ_ø÷ i¢9ÅWÃ¥ê^}XäøÑÒˆ…þåà—Ýõns;Ejðý¨ö_¸S¬›ØâŒ5oàÚ‡I™ˆQÒ嬸™ññÎ}Td5ªÑ+RƒrÆÝÑÛp“Æ>ãb¦ºÜ”¾KöÍ™ÈjI¼ºþ`þÁH~v•b]]£uvÎò zR˜<¨žA²(X†ߣ<ø~™› ¸›ÓR5“.„ùÈêý GÊ%àï îíÑ´:Ê2ðú; ÜÏtP¶()`„ü(`.ÈR”€œ‚áx€ %O@ÐM<Þßì÷#pˆqà|ÂPHwA"î‚âåü ¥eyÈoî@õ!ð«E_¦1ø-³ZCª§´¥J¨<ºrÙmÄ<(3&–èÊðdküV_ûÄñèÍ‚ì¸^¢d5È9}›hô5/Ê-ñâA:ÇïPðb¤y°Ð©·Özgrʼnh‡ôýœ.L¯ šû\æ<㤗33ê¦k2/’ënD‹Ý”ZŒoVOM!+RÍ}¢Uœ_ÀxØy¬#v-Ò?h¢?•lÃÍf#ù ›Í‘n*›ì¸aÜo?ƒbä8Ë)R×Ñ^îÖvˆ\ù½ºÜ¯´Wµ–ôW¦]ë-¯XQÙ„!Îù;›Ò—ýôµ†0€s R =,'W€WG¾r­ØÄWÚ5Ö‚ßXþÅýÃî™+Ú,1¯«íYi_EäÕ¦D[ÄÇAU¿ñ·ò¿¦Ÿÿ}àˆÁWL0§þöÈêJ55 ܧÔNàÅ¢Ã!¨§/û›ÈXH·4@ɽ±VÉ ñ!ñb|ZbD|NѦìfÌ*Þ¬äÖë»ÕJÜRðŒvUõ¼‘Š">%áÞ‡E, 6¢°ÏÁõzWïâW¸þ@ð$÷Cp ZžÁ 4'ØC±ÎÊP§‰îàÌ)ÈJ•rö–®á¯¨¯ªµA¨ÍZÊÎà·+zÄAãPËÇ:þ²ý8(÷šÕ û§hc0ón|Æðâ+ Úf¦A$7ë ÈQ™i ¬½Z "GËœƒ°Mêø³.|꺰dõÐR ¼«»Ì Û€÷£xÂ9e~…š¿¨HÅ¿^ýÚ[ -l+²æ|½Ô40Fø_Š¿¢üÆFÃÈ=T4¶Gö¦S­½ »éu!Ü¢?a+5A÷pŽxägâ'à¸Ð9Âcò ËÅÑp&ˆ½aYîV¦ûÛAyÇ›K#¥—³ ĶÌDØ'»‘ÃáoÞ5›‹´Šk·Ëßãæ8·DMÔLn¼û’¨_—hÊøè¶Túgý”îÆ·9å2× œ»3Ï£ieUÀ{7 –ž®ƒçÿL@÷L„ þ©7RË@yO†`<ªÞ柉^ šû³A´äuÆßJµÄ{àçÛgA­›ü;€IDATÄ? ¬UžyÔÖêLkëï€\jï÷Lé›A}<< b¯ùOÈ‚¶¢ ’Vgú"¬?µºˆ>©=ËŠØbñšœ+zóµ Æg¶X•÷Pêª%©§YëOw¶p«½‰ ª–ÙŒoß忈ÏΔ'OÞêø(~}(eÚ&3@y^š Ú…c°Ãé|Ìà¿<"ý”ù*ÄkËf¶¸C¹ ¿q‹ÝR‘0ÞýzyHkJ5ðˆŸÀŸcLù‚¶2©ý 3CßM™y¼ˆY-u:rˆxê·È‚âÎ^3Æ$›1¢C‹p8‰Q^óÏ)„MÐÑüqtG:?"J&‡Â/IB²:û!kDÅ^Pþ*u êäT€Øíy½À«P”B„}> í¯zžÊ¢Còeº&ë'Ñ×+È|«*ÐN„6¨_K¢Ž˜ìRŽCÐFyÂþzð/˜åÀÙoƒ“Žü™ÙÑ×!}%¾#õdÖ³h”{–ß ¿Ê]SôQ^ž/ú:{‹»5¹'Ú=™çX÷$P‹¯®g\I`ߘJ/¦_iEˆ`¸Ý†öúÕpAüݸ‹ª–œ[ J4¼ ‚JmÖ‡E êy=QÕóz!(iÇA½¨N@í‚JÀ•°ȧe}õ„¢ä9ðë!ø9\ÎK9»€r0ù?„K0ô'ó·"sŽ»ðr¿K @^´[C¬iª.Derðc_'§¢EŸÈôfy´œ]ŸãV{)³"Yî˼¹ì.§ôñAK¯¿:(8äÕS•]Þyªé[ÜcL—4¥¼ÞdöÇn —r­x¨Ó’ìØ0Ao¹ß ÃyÅ{ŒÒåoÓ?¥L‰åDYŸ.,!-þ”]©,OÑ)t.ƒÜL”ÊX„u«þ7?LžÃÎQdU’§Õ|’Ö4³+AR«Ê‹îÛÚ$úkã§ù2dÞ/{ƒÍ·õ¸û™YG”¬¡·0 õ€aÆÁˆB+#æ=ÆOÚO™¯Ñ”ï“@^ʲ—ÿ4øßgo†HwýK¯«x %“#ºÊqêïøáói‡œk|é­ñgÐ6ó‰ù©òŽ¿™¹âK¯ ð”lDe{š²õ—#Ö|ûÏx9Eùªì}aÿ¨VéV䯼Hb@ÞüøÏéîÎ3‘¿ Ûs”Ϭ‘™S’¼¢’OCÖ#‰ÜŸ9Ñ/3ýÀzÖ1ÁìèIÐR~ ô=APªÈ©@=ñ3ˆG•v¶RgBÐKoî«)¸¿˜mÁ>)H-Œ/„ä?ñHŒOÄK.ý…žîd~æï²G˜·§8ž>/ñ‘ÿœb\yÑyŽç®6 ß$}v™b°ìü'ºN预ú¦h*„ñ/¢)³ kˤþ<ùø@MôÿDÿÿŒÀ=HQóè2D´Ù©ŠZ‡S#9š3?})ü'¾ÛkœYªK–R][Åf• §ƒ:7 KÔR×H÷%WS†ïRûAŸ˜ùWy7³-Üœ^‹"Je6ò‰{Œ¹î`È M5­—Wôs»@Ð1=ô;ŤkOG„¿{¥8/> îdyd‘~ —NïHT”#äßæE뀾G‹|i#î§”IôµäXéhæ:çÝIÞ[4UŸÒsÄ’üjâ;æœ.ëÏàãÈÑÝôwßEèá‡jmÿÑî+ÿ ’³ÃΠ´ˆè äEš‚Wà ¢Zì ð|s6p"ÖÝožÝÊ«ÙcÀYßM,ø2ûWõs®R8Þ›t æ–î®n7¶E‹­w"éeÏ!Y•DØäµB½l®=X6.çM‡koŠçàÊÙè2Ô+ß„%»ò¢žGË'õ{Ã*~Ü’cô!•_ì«¿\à×”ìåô®–Yõ«J× úWäÈé_ªÔúÁAP»ºe@Ûª‰¢¼’>¥öÑF€Ö!TAùÊë<˜úOýXy E™<ƒ*VÉo€(å0DiJCø³ßÅ­ w‰Q EYð:;¿@v‘Xnžµ¼Ÿþ^™WÙ@¡™Ë£TÊZÌ)f©WùÞÙ'š«'K.sw™¶ùŸ±«ü–‚_Ë4,x·ìéÄ]hæ¦üÆ)R½RG ºíZEP¾i3 ÄœÿL~Y‡_Ȃ𞋟€zoñ¤Ñ­à>ŠÍ–%/P>öa²}˜_æ<•ª,‰u-žÇ<µq”Œ»ªX2Ù”©Êør`b:nÑ" £$c€¾+Õ4ÍÞ.>L—‡`lê'ǦN‚~ÙmW³¿"•>NM„Ö;ø€6Œ³¿b†ŸÎüÆ[Z7Óý7ƒ¯”j,òg¨¡Ú0h#—x_ïŒ ¶RÖYÿûówßø%8ê_ñ7ÉkÙ¿ä6û³½ÅòùðT¸Û8l*ýS_¦êËQÅ‹KdãÒÏ”n®¡oÓ¾V½þ«?È™±¥ Ze뜎ªtÎ ê·3¤ox!䥰^ðˆj°Pþù›CLŒ¶P6§Ã¼ ‹‘^}û&¤æ}ƒR<ÖØ W§D‹åT¸Z¤<W‚ȯpiXöb”‚žæ7Pé|ú ñ*Ñ‚>âñJï;s¹¡ýa?@{ãI§ëãÝqœ4ÚxŸ31úšw‚.êKnŒ¨>+ÌÐÓêáÔ%jØ”µNPçið¬o½ háÒ’·Ð‚µ93 ïGy'ÐÌoÁðp$°–m ng>„_©o߉w€_Ó[Ài`< r±Õ›0ökЇÐÙ¨ÿI®Ü§ ožV2þ½øÛ•…¬O]ŽNÇ/×WˆZòµÙ‡ 6Kƒ¬Ò&Ñ ñïêëÏ`ø7'?½Ýe ê)û2Èôø¿ó/ïš٥…˜ñ¯ÏÕÅ(³;~Ò.§×ÂM}ï‚i.3¿@1Ec¡( buáx¸ 6ÄÞ/ùäÙümÀƒ‰qxêÉ’Õ8úáüa|k>*Õ`µ¹Ë;˜„צ%W¨â~™¨Áï¸%#(éšþ)Š’}ÁÈÔX»Ò߀þ·}8‘¹dMû9¹öýà7H7sdxü™‘ ýäÇAöóC¸Ø{b•5òW”ã„ú ”:“õ7äÿUx3@}Xm ü‹É™(¤ËyGAÒ°@Y£—@ð†²Üžâ ¨£­JàÚ PÆX=A­ ©Ê£d"=Àø2«:$?Î| ÚÙO@p8<^;e$ÈfGˆl£äDöƒ8/‡[‰¸¥È¤GÅCKLQ;BQ¶õ8ä/Íî7>/U.”*çAÁ´2 ¨ÔTž‡ª=.€¼†îˆv±¯#Ìeö6Ìøí¶Öcéu`îM]óÿDª;ËðÍVNE ³Sº“Œ÷‚·ifÝåµe…ÑË›Zy™Ífýµtý°£Ö\>&oV6Å 51?q³/©¡® »+=Õ)r9¯üîuæÕ2ÝÄmž ~ï+YéΡ×G7èÅ$~ŽˆwÙ£µ÷‚1Dù‹Fõ5(i*öqgb7@ô^­6ÉćêJtF¨ÛCü”¤´ÛÕr§xF™<Ta«_¯ôp+íÁi§î£»]ÛÀZåÁð¢â˜ &çþïüÛ+œtÊl»ÑDì¼ÒQí¬û42‚M²®1\¿ˆ©G+µí5ÉHø2Äî67¡Æ#Ö7„ç†xëIE·[õq‹N²›óÆ0S’”´Ê\õ›¨_ Ôsk7æ>îQÿ[þÙíõ·MHîQ'èËõÝêµó—ÕÆJ£¾-’T‹µa{Rð–šß0ľ3ºì]æ­™æÈäDÿ‚è÷±çÐÒÒ ‘g¥(k,¨FÓÒHß…|]‚ïÝ\æyü'©xãÿ-«ýX®\Èz&V:zÄ)Æ¥'iç}–.ÅO™•ÞhBõ²7E»_» êYOBÑÍþL(¹”)Ö„àQ0r'è5@;"û‚Ú@ÞênÑ”Ø@“p;° ä÷¼ðÿ=ô“„à§Àý‰›!3WÞg @º &$þ%% À¹ j‚ +‚²ñv`þ[®>äË)Ì vØÏ‡• ²W¹¤ïvë@âdIŸÙ÷ƒø©0 ‘¡Q›ÓíA¹Wi¢#c RNÙe̽{=Œ@öMaKÈžlU {åÆß</Œ¿ÇÙåBÐÙTÝ—Ò¯‰Éy‡’ëXc¥&S#ûZªKrº¤þa®y-ýÃck2OÄÝô"ˆGÓÀT½“hYÂ} b5“_1*Ý/ò£œƒ&²yÀȤÞbšuY™ÎiëPÑs\3fˆ»ÉÖ+¯ÝÕ&ꦠpåòbúº[›Ì>AèçÿŽHír×1:²åìLï÷62‡q¡ÃªRÕÕçÙ—:í'?Y+xÆþÝá›Ü#üL‚]Ü‹ªŒÃ)mîUº •sŒû±® ¿+N*P¢<½¡oç@É,åc^Ýõ/TK͔̫ À×ÿoÎÿ÷;`ÙÁ–pcâåZø5h ÞumíôílS¾ÿ7íað6©‡Áy/räÍÚ>p…ú:¤‡ë‡ ÝÓÜOh÷µ¾Aq†›;ø0s(2Š‡Ò¿›«ew¯³ÈØÂU2ØE˜þMè(éÑüÉW˜©ó\‚TŒÇA<­UœÊ^yÜ^çT„¸^7Ø÷ƒu6¾ÔOÕ'ÀÙTðX·d·cYöb`dXdÛðïóˆ|õepµäiÿ>ÃòÊþ´õ<(ƒƒy ~¦¿ Lt€ÞÕj aµÔ0gäü ²®WaÕÌeÆ •'!<ä¼ 4 _ÙxKü¢«ò9(¥£@ð”{¼9‰± Š£Ž×)ùfð—wžOäÍþVò›í.T—–W›”oí†èÚùhUq@qå 6d5(Ÿó%ˆº”yއÝÔY‹Jþ"n*³À7¤ƒ ~Ó~A(“³pQŸ$Nó§‘rîå²õ”>ˆ¿#õÉ¡©ï{ÓhÌrúrÌ<æ f§¾8èG¿èW®¤ŒšïìÀÓ?ôÖ gƒË o /ƒù«c‚¸á¯­²í~}…ûˆ?ü• ÖPß½–o€¨äÌ‘VR äPª;‚\.ÃSzñЏ5ÒU9oô¾Jõ‡ðKç2w¨ÛSßâ m„÷Ê>vìuª¢ŒÒÿéÐ,nzû;æ`aô˜ç«œ¨ü®×PÏÛïêkí|ÞÖv¹kø8{€w"Âù’PûÌÓX` õŸ—õ5'3“ɲS%É jËmú÷þb¼öpê ‹¼iæCâ`ö÷ö'´–ÍýgA~lÞ±:áûÀuçø‹‚íÈp#»p凬äºýge ÈÅœª~ \´rAé^‡ô.­%RÝ ö=FMð«šmÁ}B éfÆÈÜj} ös‘7ðÓ #·s-}1Ú™JéJæÔ`‚·VN/—g!Ñ[Ä‘ÉÂD”Œ¦دD×AäŽ*@ä·27@©çîõÿCÞÇYUl}¿è·fX±sšœsR¢$‰‚(‚QPDP0'Q1‹P2¢  (HÉ š†Îa¥ªîݸÙïÞûyä9ï{ν÷Œ?æg­Ù½æ¬0jŒQ¿ê’g2¨¡Z ?/êƒçHRP†uWå:É誚zŸT¶“ÄAˆÆ¸GÜE‚ö¨•†a>mýB/»¡Tþ8¹Ý¾Õ·Ë\óéû|]"IÂôMŽøÀ¿9r?x߈-ŸiõOªÓÌ;lÀ,qvQAÞ âN%ASkTñPM ƒÚ­}n+c9¸ï˜'Á¾ìy¬ñÞˆ¥x`E…ÿ%‘EAÅÞð_]§oìAcJ´Ø¾Ç¸~Øé!¢E行ÂöbºЧ2ÀYc4¢£ù”.if4–ÇÑ/ùZ€Ù^A[=fŠ6Äívð¬ðÖ.[@ÏÑsAïªeå# c'¨¾Î"`»Ú|£îµßèn/«<¸åCàDÝÄ÷i6 ´žvÈÑ+]ÿYÁ…ÀŸùÃÙ¾ªøHhTÜö†½øZQ2n õ(ZüŸ‘nü—Sð)+]ìóî|ßIñ~l’&Dçh3¤Û0|‘gõ£ÛÈWEg“M£XOÀlí6‡Ë5CËPÉwxæöóRUž|´bl¶DVÉCÓ1öÄ?ï÷‚·§÷&ˆ®^0oò€h?½¸G=Ï õß|÷ø¾e^É2A{Ï­Wi½ðñ” ®b€áœSÕü˵B‡=ƒ©[\1¡¾–<UxC VÞÑD…7ïÉ„}kÊ}picj ¸üe¹<È®—~d /÷3.Þœá§qÎçåžS‹£ß{«çŸáI~¸p¯Ñ1³=àË h™> tþàLl¨êæ —Êù€åë”»§lµ(é:¯ÅKp­€ Î`ÿqp˜kÀn繿cè©DܹZ<ï»§è{团†¨Î;4`#ÔVµLDM‘íl¹RíÒ–ºE$™Ï9·Q`|hÁx;z7èõKÞ=·d,è¯Väþ­\øÈÍ|(Wò0) ^²ówR™г9òÖD@…M(dE0*(· u +´´™i'ù” iq ‹õžŽ8ÿ»Ê¯ËÛω´ãù›Yœ”X<_ú“^G™¿_ßqÏÄëvC—´»VÞ(~ÜïÃɽ\ð†OÆnç‚£“à46sµ{Ã…´Ñ‚‘·èÀبËBq[ä.ÂŒˆUÁÔ^ˆÝ‡©~ŒlÚX'Aël½tŽu½¹³ äëq0se5°Ò#Q0ÇÈ9 †Ú­ÁubÛÁ³O´kPì+Ð*ËB±MÆ0<Œù&vsìµS}áìQ]})¾wØ`+§–ªû vJÝ£ý¨_/z°¯É¶«Ùûé<ˆˆr‰+úªÕT`z´ÈZ/nö^òM!A¾"¾¹ŸfàÖÖ‹À³Ü߬/Ø ê’‘ îP½%¨&ž­àÌÖç¹&Ð ÔýÞ"°?ñœ1ÈÙÔwÜš¾r@I`+®Þ*øzô½@†ºÃƒ5ñšëýmÕrõƒH,®œ8U¸1¥+"Ô-ð²`o‚Ä)špOA­¤MP8,iõOhM$ÿíľäŽL*OfÑ ~aŸTŠõE¶w–¨7iY”…BUQ%h¡›¼Õ&ƇW5}&«&¼âè90?0Öƒº3| Œ=•ÀxŸþ }ä } ž úã^ÏÕσI‹A\t΀<"Žæ ¦ÈK@}ñ)ˆ×µm ¾uëÍyäIlP?Š üñ ãÔ÷à®°‡ƒ³Ç™ˆt^;åϵlŽ$ÌçgzÅ} «D_2úzç7fpÒ°âí|ãÏ*ùhB^ø!|©÷†zC܃%G N Õ‡¸-áÑìPèB Üû#¨òXCñ×Àù‘¦;ôCüùÈ¥*`\º˜hÁ3±ÅhÁ5‘ ¼ÅÛÝYC:¡ðw$«Íá”—*z®÷Gk°-6 ‘* Gì3à>^ šnO­…½d\t3˜Ô)0úÉçÀÚÚžâ ˆ®.ññ»çŒ¶‹í1ÖPù“V µósôèp÷%ý5=߱ͮæµÉîí q'Û…v‰Û?áÖø>ôŒŒmw—'ûå™X8vÒ­”˜™¸_?¸ÈѪäüœ³ßéA.Qmop]pƒñD ] —v{áÂ~<©ïÓ÷i½c½Ïêó\Ë=©¯)y¾¤nG÷˜ç"“Ã_i7hyž&¢³ó v™ÚçÞ(óóÀ^„U"€k˜³!jkÞ!P긷¨Y¾{@3ƒ'Àšæ=ÎAp!˜Œ-ËÇm"_yƒ¿ð“6ÅÒ}7®·ØRâ&¼Lëâ›ã_¤SÑŽÄÞ¨7áDQvüB( $| E·$t¤Äo!’(”ŸÝ§ ù:ëið´s_DéiV7Öó ;’bßB· Œît,}޼áÙdõÇä uŒ§äÇ8zwšQ[ý€¦Ý`}Jh—A_æþZEG›a0æØ&È-ò}Ðn¯€èÄàΧh b$¨x= ÔnÑÔ”Øg`êÿ Œ·Äà¶ã!p6jï‚{I,Û1ˆ‰c?olGwoÕêâZQ}šµÔ·M{ÕùòJòûA¤[äNH¬^Ø[ZLƒëÿ_x*º•Õ¹ü:Ý,þ^û9ýò9Ï[ìÒ+x2¹‡ÅæˆÞ`ÎPç½ Z;%ø$7[…Æ6k°1Ot˜ç]œÈOþD«úïÆ°>4Pó7ÈÀ¬È9oKŒÐ™ ͺÍÓ.¤n õß'¡"¤„†A`FXƒ`«ÈzT ÿÉhoðÍŒ6ïX.ø*ÅʃçiëWð¬µ/g 5 ̵Îk`|ë¼Æ)w- Ýy ’›@ ‘™ ~%´ù ª¨ŒÐÚ‚{HûdOc5¸ŒJà,ÔçÏO`UöŒûA¯,Ÿw D›øNA¤—¯/DÛC¸m`„üq t$~8²¸MÜqTqJR{Šú&z8TøJ`„Uµ¸žÞ×(¤‹ŸZâ^6{%«ØÍâ­]tø_ŠÜ‡ãéo½‚'¾}¸+©æo΃˜ñ¹‘-àyÖzÛw¬<¦'‹¯ŸõxkYçÁ;ÈÖÀû]ø4ÊlÀ·(ï˜÷Yk,7‹´n²©ÞÔmb=ÅYû´5•ñþvnu,÷{«&cÅpÇÅÑÖºsh"îs†S˹×ñ‰šåÄè¨Tˆ±În¿ÉË –¹kAëLMTè®è¯XI<µðŠ0¹ÈÐyë2ÖÆÖ1Ô*•â ¨êsÞ„ˆÃõ}a´Dx×·¢Tލá#2ÝÓÝØ vsÕŒ—=÷[ŸñÀ%#F³>Nákês“ÃuáëiÌ»– ƒ'ÃP/œÌ¬Ày§¹¡‘mi ¤²¼oQWÝæÝÇc£·׫ ’:ÏhC­=¾NtŽÌˆ"S½`†§˜Ã¡¤¿ÿ(9ßBUýí¡è„5Pr!î(ÔƒIŸ•ØYü{´¼Ý UXŸ‘TLÿË 'ðDI‰oôlátväͦ­ò–Ø7£òã´Öˆ¼ß܉Ý/ºr3ùJV¨) ¿h,=Cuý3±D{wPÝy„..ƒ˜ÈÀh ä§NWtpfP ìîl±80´eq·‚ãeèéÁ à_“<Ìî =A_åýôÉžÕ goÕq§Ú 6} _ðÝNwkXí ™¹÷dΓPôkæ ?\ì@Òv=’yÊAü×R‡„“Ô‡¤—Í£´Î{âç‰!á&¶Bü7´dzÜ%íQë[OoOÏâM|—Ô¸äfn £rê”’:d’o¸;\ ;þ†PD y(#81Ò '®]´G†a»†º¿_Ä ¾øÈó¸¾&‘º¯,Ç_ç¼*ñÔ¶*¸-Ìsn ;N´tWØÓHðÌ=Î#j£Ý›çµ]ÖÏüfÞãNá&»‹Ã)õž"¨¹>l=ìL"Wµ‘»øC•yÜk5±çáÐTÎÁcÍ—‡Sª)ºXÆR4ãAuµpÅñ)ʘ§Øè9‚[œ!3ñ²CÿŽwõ ‘ÂMá1€ªß<ÒèG¾K6ŒÞÜ÷¯|þŸiXTU·á¡¯x˜#OóD('*ƒx€.À,u;0]¤™eOxÅP^B¨xF‘ÁüÂf®# ¤‚Œå<-éBqBÜÉB~/И¬DѰ*ˆ# xFüÕWÀÀOêp»8œŒ²ãþ&INÑ (Ð+aþÔ! Jð3 Ô ö­ ‚Æ!`’Ø8*0Ä, Onµà§1p—q¸È@àAk.°Ü³‰Ãc¸¸˜ð/õ÷Büi $8Í@ur»‚xÞû¨öy\aécи¬­@Й³X²+‚µ@¶¤°ZL¶ÚÀxU}5‹€¨Š‡b&‰ûId¯ú%ßSóˆâe6Åbýñ¦1ºÐýÅõñ’¸TýA}AQ‹u¤3ØÍz‰·(a„vå1Ôƒ¬£½Vƒš,çaõ>!ÂÚbâ<ΣU]PÕÅ÷ ªqè§SBü‰&þ½±Ôí}v‹Ñr—Ô,ÎÓBëÈz±”ÖäªL×"QݪÅè(ng5]E†;ŸÊj¡º›Êâ{c8iì»PÙ‡À¢àqo¨YÀÏÚ`Œvè-7˵»°O'ÿ¾ÒÕ!²$E=g‚n5ŽŠ'ˆ1Q¤ÙœÝäÚñ®Ú§*ºcø”Iú¢òQíO¹ƒUwiïê“©)’=]Ý^ÐA|D’¶„‡À¨ªú’-{¸cI·Š Cv•Ü*`WT© þ0nÓÖšIâgá×ZØ[xÝ]ê.æùhi$‡øÄ3f0>Å ¦8Á~]L¤ÖW{D™(y–vò„¸ â6í+`‚ÚnDüª§Hî:Èo´aØ< Êaª щj&#Ù¥n¡šü€ Ù–Ó Þ&d3l»ÁxÄ:ÈA޶ƒö®yTÈꢚqD£2ȱ÷‘ôQ qEGΣãŠWÑpÅmd+[¬æ„l(^'ªñ6õÕŠØ#TÐ;ª Wdˆ—Õ ÷‰Ù~ê‚8£*c‰ª?ñS€©ªˆWùDD}ª„óÀR€Hávà¢x˜ÆÝ Þß7 T+qT/ÞAªBª`©/‘Êh2UôFÊûD-4÷ˆH`ŠÛŽQ4’Ø„-÷±žst¿2AŸ žAÓ/‰½(õ´Ý WûÂ܈!ºˆÏ@~nß ÚA=˜(çƒHo€zHÞÚB³¨ªÎ žqÛƒè!VÉ|Do u@­R7Gµñ@ ~š©a Û~tOÜ>à”ð]ÿ±—!Öëü)¸ô Á·×z´çT"Éî0îwªƒ¾ß™NTï©Á§Ke1UßÁ^©¸Ëй ùTÔu;0Ù¥¶ÝäA<¢‡û8)Ü#ó@&ªÄT@öÁ+~–}Ôyõ‚»GùãÚ7b¨›/½b¯Ü-S¬½%ð”øƒõ”so’Û@\fp?¨Óê ˆGÄë Öß{ljºŒ©Æ· o'Am"T/Ñ´ŠÚ«¸jö(šì/š Ä&cšh¡=Ê7ÎÝÚ*s^MeÖå9É&1Vv÷·b™û–¬ˆ°Ã^œêâØ˜ äÚ=øÖî§—cV4Î;T-¶{F3ÇþÒó­ºÇÊ7—s:6É›"š[5ÍÃlt½Âoodu¢D_¤PÇУýD"®AGˆ,WGÐUºïG1[Ô£ºÛ'ú)EÆP¦ïñR‡Cf{þ`¨¹UMÇ0b ˜{TS0îQQÐÞUÏ^(¦€ðòˆ¤8Â!`~ FpG@™äZÇýYò~uÜä»XlAY Å6„½WüÊ)ën¾g¦õ¾˜L{k?¢Va“¦ïðt炈÷}ÉhÙD;Šâ3²ò±hÔÅÈã`.R€YÀ§àí­·³¡L³Ð…å ƒðxÊiÕlqvòŠù¶ç)ÙE›a,´žå‚6ÒnÆ»ž]¶Ž×(‡Q¾€³a¬ ©‹â_€$š@µò? ø´åJ •i\Þ¢? Ñ€×Q–aVjŸx°(=€Æø»¯$ðojöJ 440€¨ @j0 €EW=a:uø€#œà=€ÿI¦Ä5Qé(ù¸xž[—¹PWšçªß”Þù€y›—“ð>;¹ ø˜r@Eü5–×|Ðÿíä ãkÑ],ž!p¹Ðq€ká§ÿ îµ?¹Ó‰S]Qâ&¾BŸÖ[$¨É|D޶HÝÂJ7Ie¯j¤Îh­ØFMÕHõ"^¬á4Ñ…¯Aeª8PõUS5ù›¾êftòU]4­vÔ#ÊLQ”¦i#œŸí7¸I›«¿ÍPZ¨iLÒ’ôÉêGYQVg}h§&pDv°•&êEõœºSK×ÊÑVë®u£‚3йÁ‘µ‘uòoo'ñ€¡ %.G‚¿¬j|l|(.øNùNi_ËûäöÚ¯Ú3ÔÏËžWÄ&ù‹ü™ ÚÚ&úÅÇ:rØSÛÓ^œ·§[$è­õA„ì®N>ߛ馆ikÐ8E ¨!ª78?«ö 6‰)À§âÐ.Šö@ñ"¸› âWq?ˆªBÃ¥@tCŠÓìc,ïq“8Gåˆ O¨›DuHlUMt5@,µHÔ•,úƒœ.š6ˆñ(ïr1¶m©qT3qRhªA1˜l¢>¯pN[ÂÍôQãÔo$s ïR(ž³ð‰ä G*’•â2¦Ø&¯G“£ôwAÿؽä4å*{[¶!6äc*8K=à< ÀELÀƒj2Ô­ ˆûÍ4Ð>¶ï5‘ ¾Ðý yä:PA‚z‘VÀ|QÔ"v˜©Ö`Ëå"„Î&¢Q™© žÖw6FÎ7,ËSD_ýq0~Ð&‚Xö÷Ù_í¡ ;ó ÷Y~;¿‰öî›NºxºEµÔúªÆdVò½ð‰wTMуñ*U7Ic~ìv¢Îg/Â('¯ÇÔ>r_Ç1¹_!µåXbúR÷vµOìך©{yYÜç¶§–"ïÑB9Å ê9YFPÔÕÖj‡Z jô€¨¢ eòCÐûh€mØ·9V2,ÏÚ¬ à€2ÁyÍ9Á~þ|°þ´ß‚Hj4 Ä b/h§ÄkÀ›NÑ Ì|³˜sÄâ­<åÄH'ôûÉ ç0 D[íP‚Ià¬U_ƒ2º€6[ÿ¬Áª´íz!p‹æšiÍ€ãÚ“ fèáàhkPj·¾3z ËÓz7vº³t‹g]¯~qÆ „{HŸ‹pFkÁgÜ Z?~vwƒ|O>j¢ŒóîË@3·%ð²ú ÄVõ.hÇ1AûFè¸b¸œ„‹TS\qNuÂIØÌà‚šÏQà5–­2A ç%>“GT[#W=(_GäCL–ƒÕgò>}h£Ïæ#­žö®ì¨}9Á>& AÏ“C9¨ž–)²¼ØCU1D¯Ïj•Œ&Ÿr‰jÜJ ùŒÈ+å,²¬ÖSƒíœ¡ ´ ~TGÝ¢b·¨Ù+§èh®W×;ƒ¬Ä#@]jþ%€u3€p·îH\F[Z‰t~gÇ5ðÿp¨â?ƒcf+±„üX–Ú#žñÚ·b%ùêžVŽŠx›CL`æç7õ9|,ת{Õ/ª3ÙêÔR]½©5;èÈ ­·è*V1RÕ…<ÃP1€x–‹Š8ò.ÂNeM¢Ô7܇G<­ŽCå ïªu uUå@4W ’ Tß‘ LW5@¸jˆ/Õßò(°Q=b¯cØ´VG@Œf5à’‰7âRÉ–Ш.¦ó©j¯Ä|`s@=@õ!Tq è) @•5A§Aåiw‚üU 5[ûäëâl5MûS>*¦ò¤ªKjÊi R&iê]ŸM=ý'š«i¤jcÕ ~’~µ’g´zêâTGŽ£ôëå„ÊaŽ~NõÀ·ªå€Ãо–§€bU b6Äꈲ1æ‹ÛðŠìÁg4%@ÛÃïœq_–sÉWO©½Œ5ZrQv6Êr ­X WIâ5P¾n¼¦ ÔkÛ‡ÜÎj‹<¨UÏúXñ¼õˆL ôDŒ)nº2Ä1ïy=(:EÎÙßsÈè­Yì2“õ¡$¨lÕ$`! ¾'èÁx|êN–¡ ¯8 þwŒ8”ÙK{ #¶ÒýŸU^.A |`<јûŽç-½*QKÉJ¿ Fƒ¶M܉°?S(NØæ™O5­.‘k9#zQÎÁ¹Ð&6eÆãDõgEâå8‘L6^­'ôZ2­Áb-ëiÚhÞÐ6°\Þ ^ ¢n_àw¿¥3È[t×ÝbD‰ÉêÚ&bîÏâ9\gžV Óm«ÃïülÂQ76>e‹ÏѬ6ú dø=?dy}¤úD^¢Ÿ³_ŸÄZg’*Dº+Ä4眼ìrîXpkÀ}×X L¯‘¢+@µU{@¾ëNzr+¨Q4Úz!°Õ`,tGšÊ爻Ä<Ðúš_3µŸA|B Û¼Á³Ð3ô7µ• VÈ Rd;à¼ê j ö<ûQÐÖiõ@ûPo Î@w9°ž,ÐZ[œÖà®þf/}3èúç63´æò h¶ÛŒß´ª ·ã‰é¶8ˆWÿÜPdjÛ­‡Ü_xN/qÏ140ÓÀ²½\†Ô—Ë7zUw51}·º ×8$áj﹓/–É4’õýªÇôeî{tc—üMµÓùReŠS2YÅÄöjRįZcqFŸ«ïfˆ–}GÍCz?SåĽö×ršx[o£Òiçì—:·Ï‹o(/çËÛQâUFQNî‘74ïmÑ£ƒ›Á÷–¾Ü ,†ÈNçQðÍÔ‡€ÑP+vª÷@c °‡¦8"_ìF8›¤ƒIrû@à'# Œ8-Âseð ÓGAd–|§®<ŠaÖÕªü;>ÿÏ€õÀAºS â˜º8b ˆ§›@„Ú@G€|ÕÈ!œ!ø…xàQí1àN.!$6.>ø…zꚪ*²I¢Ð©b5€8… ̧ô{.XœbŠÚ,Å¡€³À,:1¸ÈIàç4§^,$h(b(@Cˆ’T"ð•mKßxõ–ôß‘ÄÅC.§1I§àrÁuƒ-Ê|¢Z?sȳrPÏ@,6@´oédÛØ ´áfpúYẇì\4íãs„v^ß¼+ÖƒÚ§f€–«ÿ€«Ý.z•9Jɹz†+ Dégí_>_é Ën4 ‘ @-Fâ<Éut€$ ‹ ²8@sÀ¢<â;ÀVS€Šb:¯~š‰?@Ä´ŸÅLlÀø'ÐÁý«Å!ÖA QhrBeÉßÈ¿ˆò(Á¡D}|¤qˆ½“,À£–1õ¤‹莠ÅßWÀzÝiøOãZÀWÀ^õÐYÞHí, ‰Yä°˜Àhî+Óî —ï»”ùÕó×꣎AtAäHh?ÒǦ? )íRß±O» ¸L&PŽŠWxPU$ ê’ªhêCïj«@<ÄÀzó2P ¨‚ ¤W@ÏUsþŸ2â®™6Ð÷×Zàªg]MÿæReóª4£T5 |LE»ð q p€ ÀOxàS;T1 ÀP © ô*½¯ivÿ©«úUÀ|à P6¸’V^*\K%†ïª_ýŸ£ÒU»ªW“yULÖ³èN÷kx~ Çã(@!þc¯®R60ØÀ ` 3Éç€à2 J%© .(/€j  ¶˜¥GöM¿ªŸ:€: ÷¨€6€d^Ê@^ñ7p€ÊŒ­€+3zõ:eýTéQ›UÖòÝÀ›ò0¨¡"¢žp@må4ð‘èJ’ ¢&.xôŸÆçï `©€/ИL@âÚU2Û¹ª¥¥3PªJWiéÚö^Õ× ìàKÐdP Ta!P›Ë@<€d¾»ªUwÙì6Qȧ.¢0Ÿ @ô]:®Õ¨\ɳòÿËèª«Æøïçã^-²À]hÀ“üÜDmÀ¥< _µ^¯æØ«9ùZéw *cÀ8“Å ~æm"*žWù…Yä3CÙAžú=\fó9ÊjkÅ*ñ½Eõ½2T’UWUMÕå¥îuÅo¼"ªØ.>a¶¨¦FÒ^üªuÄVµZ-ÄÇk,¡ªZ$Ÿ¡®¦´/IS‰ª)UÄQ±‰Ýòkù(?i ´9§”`7•Àª—E%B¼À=\b 8Ãn£Ó‘Z*‰@¢TSj¸•uj•5¢„€xY›B¢Z©‚$Ší] ü8¢UQ¨iòv3õDPËd{OhØ*aU›>šA‰£]¥z¢TcUÿ=»úÎEÀÁheÿ¾µ€®Þ±•òеهI'‘Fù?ç¿ ÁÖqçÁSbNûÏ?PÅ| Êи¢ÿøô37^uçê™ÿ/•®öÀ'#þw‘à  XÕf«"PõÕ|à:5DMhþóò^º|äÎ? ´tu0òŒ!J9 qâë€zIÆÀ¬ê{ @äýwr×YG ¤~ÑVЇ+¡xFÑ÷PØ#ïPψÕÑ}–‚Zuˆ=cÝÚ¾— ê¦ª7°·Îõ?£9¿•¹ùÿ>½  æJ½p„—€éêGà#ý"`S0Ëøö¿wL‡ˆÁ²’#UA¼ÄûÀ;ôê!ïÿ V\4@g7°–DÀ¦ ¡€V8@9VŠQ¶£ÿŸ®ˆì§‚>ÀA5 ÈVãÎD€Õû@K¡÷kwõƒ(pe—û2ñ/íºZšÍpK¥ãŠH ñ?Ú&ZWö‘«žYÔ[çªg–¾ep%„åj) Vh§¨wM#Uªy;ýÓ½Òýv  È9h@&@}î ) €Ë ÿª>—¶æ …Wµ»ÊU½-M×l ¸ ê,@ºWЮú¬_õ¬‡éþ{RWýêÿŠ„-}Žó/óðŸÈ½êóµÕgúwTº›oŽ üÉn@Òи@9exåF~Aç Ïr Dñ5€à ø¯äÚÕ|~+€û4€(µ8êˆ~Ô =׈R»±Ô^htÕµtE”ò|)Ö–\±bþëÕf@!.øïFù?;$iÆ"2ÙÇQŠ\¢L!§W„@©1f]Õ¼+æ_G Pz$ªyjñö; ‰=Up‘€ýyѧxÍó¾qqík>by.Ùü‚N:¨Bp˜!@œÊ#DD¾T hÄE ƒ1ÚÓ™\bœ B9:baÒ€LŠø™3¤Ó\4Ñ››Ò˜”R @LJ—Žb’¥Ö“H ÕIÆ@’DyŽR‰1R‰rŽL |œçG J¨œ%†ÍYcòžpؤz‹£<--ô#àe77­ùäo¡lÈý}_>œÈÞþ-œ=vtÿPœ Úhß$Ð/yÖ@¡›} bÇÃ/‚\B_wèç!Ô§p/„*àÖqîs¸÷H-)_ |›%à?íÿúàð<À÷w?¤Ö®VTaôfˆ4õî+_ |¯—‚YÏ?éë›Þ Ç÷tRcbâ%í#bÆÓ){(fž¾ A”ýÄðѤlù…®âŸ+€”¤ÐH¤ˆ°ZO‚ûmÞ.Ù‰%`;bé.ÊÉ$Ï©o¿B‰ö‡±’ _ïä_(òûÊOãOÉÛJLË7¶â«ôº4$—cxH¥nÙö¡T ^ „UD¡¸„@0Š4Ã$³LUü]ʧ¨7Õ“ ’Å#ÀD@bG™N”L"OŽ}NaΚý!‡Øþ±Ó÷¥8'7ÖÚ:cG7EãR$kв–©ÆHÇpö3|ž)œ‰µ}C%íG§½OE;®±£â@ªÖ‰Ô­^+¿EUN¤ä×¹‡B2“¦¡Päa)ÔD¢Ày> ŠÉ6|TQ/0ÛÝ¢9DÄzüd É%…4•K qHâð‘C&Å$")$•rMp 8Nâ‡0LÒ€šbð.¨¨¢HÌŠE[àAJ€qÄñm½|ICà.޳½hdNÜ󜹸â;¤NÅ-ß·éHôÀ­åû#x)!“Lâ¨Xtâ©%7‘Çes%¼d"¨† ¤‘JTëab@2q@<©@LÀÁ X€0‰@I@>)(ò¨F!%“Bq‹s”`r“*œ¢Å ñGlR‰ÇÁ!E5pñâÅÄå4’D’ð…ÄðcQ€ËI$ââ²ê744¶“쥊 4DS¨@>ˆç$íäGð ÅQ`•6 0ÿÖ¶ü m¶$ó pŸZ DD3`°zÈá8åŠ} C¨M|ÇVñ-E å<ÅêÓyAΊ¦|.w¨:ôÒPH#hOc$hh4¢6û©£î $ñ. Å8. pÉEД£@¯ß0D •N´‡ÿA ?€Lµx€@}@°TJxTUy‘€zPÌd/?q'(`Š ÁäEΑ¦=ÃA:±†Ô&ŒI Ì ½¨ª,©â+„ZA¾šÉ[hây 4u™0ù…øŽñT¥‡ø“TFÑ[ôã˨D&¨.60‘›x„îTçuž¦ˆxNQ:Ÿ1•4šR›xf4'9äfzãc;€4*:¨L#à0;Át>à(1rð’G@½ÎaÎ"•Ëœ!…Óì"½T¥"'ùŠBµŽ‹ù‘ ’(&›$`Ò- àEG¼ÜH7.²†í<ŠTsXŒ&J8§ØÔgäËÖp*‡'f6ã²þºg%ñ¾ÛÊo¥ª¸^0Žs|KU¸…'9‹LÞ"@̦µM˜ÒÕv\rYJUрݜT/Q‘Æâ0µ9E6MÑ SI]ñÓ˜†D¨N"y€$œäO \ÂD°I§<6¹äbabÅ[¦±-\Š)&FE*’œÀRÛÔ6ŠEц Õ©Ž—u¬£˜RðÐ’–Äa` q€¸Ô¢\\ LL ö±ƒF4"ÀQ£“JLΑT.Û2¦s–. bÈ$xIÜ2& 0I.àÁÅ$A¥@¿F* ˆ§„&(L²lå8‚¥ê<ð-P¥… ¦‹n@îC‰“Ü„`)iœA²Qh˜¼ÌŸT  µÑ¦Úq1Ö>¿:wŠ ¢Þøäçq8ÇODÐh‚M å¨D>¨†Œ1ŒG{i¤"¹{”n{K­ºËéÊMüª µ@<‚Ä‘ä!…Ðñ‚cÀ:| ÖrˆYø€ðG¨ÜJ9¸ø £ÑPÜXÜ Tg`q8É~ ‡sÀ%~:ñ9PõZ¥¿´ålš|óñÛ9j]Ö/GM“ïL¼ RÒ¥¾ˆHÍ/7”j–Õ>@Bj^­HŠ×2Fã#…2—êÂ`ÀPÞ‘Ä.¶ò8ϪÏÉW“Tor˜(–qF\¹Ä:“KGHÃ% ¨A (ä ÉbäâG¨B  8ÉQ :ñ@1¹€" 8„€³œúÐ8Æ àwv1¢€Yp®„ŵ¡P‹ÚÀ&ö€DÊsÅÕÂ$Q|À9!ª TŽ¢*¢ÌRÖT ÐËÂwjŠZHRI —ÚÀQê£8FCJµ‘h )¨ýeðX*ˆ~äiØ@y2/Û€ÓêKP˘ ŒSCqTUqC|GÞyÄó'ûx…1ø¹ÌRà#&BhTŠ‹œww;; ö=;“Ô¬{ŽU¦èâèÓ·cŸ{òd”„’V´’u±‹¸—^ȃ–_T´‚̼í—ÇQɺ»¤n,.ò!Â÷­¾ 3á\BuTdAh'¨¡¯F&JÞ†cþé7Q2Ãù‚¶ÀXƒ7Ø=qš¹À[DÔö9qD}s‚ûIÜ“°ˆ‚ÈëÑÉH¹Ê“®y8åÔ¤"Ã:ú×NgqoßàÌSŸù ´zÚºk`ÿ?˜ ¦ PŽ{,vp|ÚP‰ƪ¸ÑùÇ( ¿óÞÐó¹Ã©X4!ÇÂÌrÑB\~õÂõx‹Zæ÷¦œoš™MrÕ-µËá¯ØµÞSjÕ|@ü‚ÊÒK|ah*™<6‹¹,¦#Í™d² ( ‘ÕNÍÚ«0¨º¢Ä0 7A ×]1ê( •³@¤ÔÖUÀèDð#Ë¿ “eÛØè€Uf û[ø€>®„È…‰JHŠÊvŽ¥×T 4 ›ò]/QÈ¢"¨ T. ›l Æõ(ÒDŠñQ\\Bh”'A¨^&uÓ€VìrX ìà pJÍõŒêÊ—pÄrêaˆ]¢°›Úl!MÝÅ,$ÅìFiÀR6Sþ /:=©—uYYíŽ!˜¹ãh Ï¡!{–P^»)0›s¾wõ§ëúS;ÕS¡çº¤~„7¾oªM$±Fõ_©mØÞ:üêß”þ MYÏ|b3ŠCtv0Tq™~„Y HN‚¸ž(P“pŒ «,íESP{ðƒ¨CwP§I‘Áu@9ƒÚËT»X‹Ÿßéu üKùZeT¨xTá%(.³› uPÔ¢uY#¡5ïñËøêT F-nÁ‹¤ •áQ¥Ð¾ÿ/ ‹(Ýo–†¢•Âå¥{¯RÇÇuÔ&TåŽpX­Wk©Ânõm¨LsN°M-ÁQ½é!Ž‘ Pß¹¨Êh €s€†â&"H¦"!‘¡u /O’R­q±Yªâˆ©Îâ5Ââý•+ÞÄa3IxPt$Ctå4•'’Hæ2‰$SB „x–åÄSG܆ŽF9 Ÿ½ æª¬ñ s€6b8¨j$JÔ 7?Õ)Q+K˜Ttâ¸È&.Pƒó‹&¥{|5‹ºd¦6QbÔæ&5Ù®*à—÷ˆ\êŠC\DЂ›¸MÄ©ŠìO‰lQ‡ûØ Ä8K)ŠWœ0%üÎGœ£-÷á•¿;s<;xúuµñü¶#?‘{´Üþ‰={ôyâÅf£&y•<{®º°Z3ã­*Ë8›±¢V„ÆñëË/ ê‹ÄÍÀCG£Ä êsòЬpЋÀ-\@â54¦©œâW±†áìcz‡ÓøÉåFj“«Úb¨t¼ìCÅ—4áêÑŠ|:G'>`?åÁu¾à ' ÒâCºŠTC”¡ÿDÿÙe¿:ÁdÙoëEnTæÉÛÈQMµйÄrU6g¹ Zˆ0{åõ]ÜsùÍyQö.^Žå¼Ç<–•w?¹Vvx¶»P8à\tN`X‡e‚Îø0£•B»ÑÜûC×£™)†øš ^Hª]nÙ ÷6z‚ÚÞñÕ–ªæšQý~‘H­Š¿¨ 'RÄnF¥ âV‰ tå4ÅÔÂG<^:€øˆ×€×8 ÄØ xË&=øçX‹ÒèpÅlR”æ>8@¢X j!ñÀ¸Àqê¨<6Ó^õd#q²X,$ªŽ±_¬ É,:éc‰½üȯ¤–t?µ•ã‰3~gOžùÏê!6ÓwŒGoÑ̳Jž+há´â{À"‡ƒ¹8n4DâB-ÀÚ묅ÐñP°Ú:€gTð H‹ft†ÄU —@«lßúg¤ƒ· ­@/ÑÖƒ™OkE"˜5ÌE ªí ú;ÝA »ÀÌómCéGE°~-¨Šˆ<•9TžÝ´Jæ*ð}êír…ÝTuÕ¸, àlydt@­RÛ@n  ®ÞÇ_ݸ7®#Ä÷«²Ì¼­±•bfÜ7)oð¢1KöàwO@¯Æs™>œsæ m3‰z í{üÆqõšgbZÓø<¸—Çô2žýFß´‡¨¦ÕòK* ÁT’DÊÄ+ò½ãyPÿpÀg˜´Ò®ù(<à¹â`?ùç(ùãà<((<A^»¿ídú¡š{$¶Üu© x¬Ò^0 3ÁyLHµðH`¤ö x¿Nì …/ç߯þÕ`-p+ó¢æ@ø—È1°ýîÃÊ-`Ý™;äÖ‹{ ½^2júêCõY ™Pu[ÃVP­$L©V‚<^ãctÓ—Þ„ÚÀŒo.j¦¾G=¼Ú[k«É@Šc4£²ªÆƒ8ÏŠØG%JÄjÄÄt<è ° ’C€$”ws–xî[A ¤¥^ä,–|¯ªÂf Ü8êëÃmya8Ø=sšBÉÛLJCÑ çŸ„ÜIgÂp¶ÂáI[p¬J÷!0'y2$ß’Pêf€/ÝO8Ј/ $ôH^EÕD­Ö@~ œ¯¹ƒúÞÜe.ªtCÄÒj x‰Úf_ú€v™fÀ@.ƒÖš0’–€C#(+*öÿl¬Ui4ApÅuVêȪ (êòª‘â¿þÛæ4`rx‘³(æÒ[ 6ó0ÔÛb¸Û)¹ˆ]HÏÑhyÍmü¸ÀHàöƒz[ݪHt@‰/‹  6qÁžÇ`)ï³A“±y†nxÉâ7ç(‰”ã5bÑ!Á“[þgàÄó»|Äþ|è@™]œ[D0¹Eå±ú¤w©ÞÖbÅf}$QÏýžÕÚ›äùþð}E4øHÊ£hÞ5Þ×PÁÊåžÆ«MÓŸÅçËOé€k® ÄG®;’ šn6Ãk6JÝÒ•ïÂdË{ñ¢1 ƒêüR]ˆÇe²V§RáA\ûžÂÖ8j‡lC*'™FN]ÞŽãü±H¶ß‰=Iaè…ìëá…m1K6æ×†XWw'¦–ÑYÎ,Dd‰ÝÛãvD8ÛŒWÑ dfw´@¼Ì¤ZžNt`2¢ÒÁZï@ÅÓÍŽIÚ_{þàŠº=¨aÔLúƒåªH4a¡ÈÓjG"­yŠý/(¦”_ÞCãÞAãMÒ€v¥Ýd •mèkQ Ay2ÄSE"I@: D”ÇS”‚ý¥ú±tÕˆ²«¼ŠSä¿\ú ï”òv¤,šF^õTÅ•u©ýÓÒvÙ4RP(ŠÑ€ ElNaÅÎÑH¦7Ðä¿È_ùïè8€ú@ì"lÎá èPWhÀ]ÜKžÊF’Â6 õ!ßñ§S›·yðÒ§|$ïËÔÅûn(£iR\ŽC†T‹„Qå7õ×§´ÕáMjC;®AŠ”n3&âàªGè܉Îoê`'?šz8B;P×3Ä<ª)"e %=-Bàá,°‰‘ d/ˆ=bК$ࢨ Ü.2 ´k.RóÈ~L¼×ÙÃÇYÝpÜ~“8dÝ™MËðÒK‡~µd)±’r…𩳠»±¸'ýíñ&,.3«‚½3šÑÆ{¸æQõx¥Ò22ñÖÜÁRH˜ ,4VQHúùLÿœ?‚Q@žJV«1ÀfµØÀL ¤òAõ!è$x¿ HB. HbX@¡z ØO¨ ´JÄH ŽÇˆö!ˆçUePT7PƒiK”(~æn |PÀQ¸ÄP?‰a ®“@íf61Ñ“T<´G!´6®¸4ÿmeˆu3÷¹¿ï™ÌJ{rÞ%jº…Ò‡’…#èîMá–,V[¬1Œ—zñNk]µë1¼×yÖ󕯤Ú:õ‹æT,ñ`J²²°‚š> OÜ|q<¥qO‰%x8žŽª‡€í* Tm­ ˆ0#4|<˜þû˜1õ—›´ÿ£zþÿš%ñ_K¶ë‘„ùÁ92SnµW«‰E„€QWõP”qqÔ·2Š MPÇÑŠG‹ääG´žrÖåçisÎ2¯äø…Ïù°hÑ…aì,º\ø(‘Ðwç§ã5ׄۢ%'d¼qVùa(ÿÛ‡"¼yÉ}9ãÙœö$k‚´ÔažIDö âß¡ºà÷×¢˜¦¸ü_¨ 2Hc¬Ö|5Õ)Ÿs8¢(u†åÓˆ‰ƒ@[ü RÄAZ€}‡ÚÖ1‚ [ñ±Ø6ªàÌ?p»}Yäp&«HT·ˆñª—¸N)Ñ›¨ø„™DèJ(F—sq!|\cfí]œgBÚ²k™ù©»íË%O­€Ü‘G#à‰ºÓ °IëŽJÜìƒ Ö1oD,3³Àÿ¦ù?çÔqà˜ÊuN«ÂÆ^-³×uÀƼxPÒa¿.»p±ð7ÑÌÂ΢PnÏ.¡B¬Ë…µC“ÎôügOD ャ¾hyOæ§Cñt' …×;ƒ ä%y$¦UgNG7×Ë,ðþ ËCà™¸/À{@[‰«?¨rˆùF-0õcêkü$bˆgw` —;/È6³/’¬ßE”$³mâ „˜â»´x™ÚX5¸è´Êq/´  :ð(OhȆ¡/AåcêD?.ªë´$ÙE—tª$´¾…mzð™ÿÁ¼Èúö»¶Tn»ÎïÀ7± š8S‰¨jÑKœUÂíOY=4˜[Ý®V ìå>Þ‰ÎÍkŠ”ý-ZL…Gájš‹Ñ¼å’`xÒã f3ÿH¤aèÙàý:Ø <›ã?DÓÆú;x%?A`£AÿŒÓà{NU†0ıq–…k—mß“ˆ¤7mp¬ƒ4÷0Áw™¶ Æ s¥Ði…¿ú|un€ÄЀu\àsàuÒ±‰ã=\5QÕª‹b4!ÕŸxT1&ˆ$ÀU—q° ‰†xESu'®º¸,ŠÐE:6~Ž"ØÌ£æÑ—R'‰~•ô¯hµö×_‹€™ÀŽØ¨æÑæü®ºwf¨»¼¤ÇÝꑺD"ý/íà í¾0­èDÖËÈœsg_ìÏ¿ˆºXÿâDNõ’70r„Þ‚‚Õ|†J\Yi-vUõeôøÙžwÐ|›µÆØÁUztÿkæzlß÷ZEŒ¸6qo`$Þ–Þ;ðTÂ6¬`ó ‰lõÝ™tIuóøSW [_ở,ý\ð *‰KÆ{èÚO/v1Ò»%TöÓav£5‚WÈŠP@Â_ƒ{ÕU\5Sö_<úϵþ­ŒûÏ€“TQƒ£çyþãíNùýn­2çô·ÈÃRwˆëÉR!ÍVKÜâ[µ@•k•­Nhyj\¦ý®ž¶WpÄ]å^e2GÅ÷F9• nŠ>ˆ.Î}.2öš³å<¤î&yÙ=‚ᤪÙh±Žò7Lç õ5­»NçßËö‡ê¬?RÔÕ­î«hmu‹ý§_qŵ­°ÙI÷ßZ>ì–çÊýäø´Êñ§eÙ)ªf¤'.unO¢Zñ¯©à;+ñ•j"ŸO@Œã8P"žõ¶¸²Ÿ±d†ú ŠÇk{ êÕn„¢ûôg ø^=mµwï¥FÌy9²aDó/ôÖÓŠÉ£+xÕ= íËïiûù¥Ð²ö-ª"‡á‹nøÀyÔèä}Œ™‰¯ƒ]ÇÚ ö¶Ø Ë‘ò>m8Õ`ýnÅCl‰]%ž€¨²ý{^…Ä„ôFúSÚ-à9¡ðo4‚ç#íY¾rž@¼« >¬ ªrdð[t=øJ’>QQ5{s¡ îmÑ“õm ßµïýûøÁmc/û9k¸«Ô§àŽ?€£‰_!úfäW”£kO!bÍeH~¢Š…Š/‰¿‚;ƒGP¾&€æ½O«Éž|ýzw‹0G=Añ%žÚ)âÌFòA"žµª¿îSÃée´d–š¦õåOuDŸ"¦1[k«µ‘åÅ m¡ì¦­öÎPXÃ몊¨£ÕRTwª"º°\}AÅøô ÆÂék¸“óúßO‹ÅmNqdøCÙnÏ H°ö AKHlæãq+@Ö\ lüzuÿ/ â8 ц«AÞ¡ß úqÎ. äyZÓH= îH@¬­Ýœ'µgÁy[¡¸X=ˆ.tn‚B»ø7Èý:{4ÄÈ™ Úó…ÀÿI4’ûò ”»Åx§|Ð3 #5EŸÀ)õïÕ¢ÄõGX’Ð]{SUôýšXCvòN n3»ÇɶúõÞÓj¨¾VßC¾x:a‹ºQlôLg5uUp™f즮2´šªËUêþ.~wGÄ®Ók»]ì§DÈéž»H”‹u‹ŽÔbÑv%59ʳ5¬¢Åîe<¦›Ý®3К y.O%K‡”¦iµ å·„u?PHˆ›«Å þ-ã;,ß·ÖØ*’•êup§`ƒ8ãµ Îr/‚ì ÎÑLQƒ ]¯~îâvК‹3@95‡ò¢7†ÈQ™a/t±×ú…LºU•MØzƒU"Å@ñ7ú|ˆ,×:‘›ÑOzÑ0RUËõãÖð MÌïBÇ.TÕŸ(™u½æq¼UEíU×¼"Íp®ÿSTrQä¢P(Â8‚„8G:9T‰}Ìa5Í™O  ¼úŒÙ]Ìq²ÛéUøàô[z…ÈÇOˆ»/>¦È=_p¦2©–\h —ß´¼`K[ qgk¬By_6G!ÌïUcðþ <è\‰òŒ+€‚Hoðþ`Üz¡õ3˜ïê§qͨYÇøU-çÅ`¡‘,¦0ñöãì3kù? [¯E€t±Üí‰RÅ‘4„ÖÙ÷ˆVþ# V©þ jˆLP£í… c%“qÔâOòøÉO9÷Gc" Î7…ƒÙ/ßòüJ5¹Õ· 7¶£ šìå釰-§#Êéd|±¥±Õ;ޱà”xÆ¢¢³bëÎxsD•Ê…ÈGÑzkqáÄMuAR]ý{ˆßÃ÷Äó!¼‰^ï+Ô‹KÔk2;©mÚYž –T;g_ÐTsìB¨2]=Œ¬ÔVBK#R!~‡q/Ä 7›@œ®M]R dÏ•ÂÈ·+0(l„*zRˆ«%\²P(¼eªA®$'‹²+=G¡£Pd!pÊ ì À%E‰À-sP(òH<€FWâeDYÛB” ¼uUºù‘äQ¨¤ „ØŒϲŠ+ÇÜ]‡—¼©RÉr¯ÿK;V“òc´Û"º[=`Mq>ådìù–P‘gT3†ÔÓ“s±Ÿy#içoó|(§g}nÖt¾Êy×xN}Zdf1³¤¦±·å>!5 º[$~VíìËÚ·•¬µ‰Û}+Ñël唡Î’ž‘3 ¹6@âjAB]Ñc=ãñßh…8ž{Œ‡ð˜Ìjà­®½ÚÏp\ã¼9[·Å3Ñ…C t¢@ÿ{ʤå¢( ƒ$ÕC-’¯€L´W‚Ûкœç¤†í&:³ÑbýnèVÁêûŠîÓ!´=PøºÊƒìÆæ0( =ÈÉkà©À¤¼¼KUZÁ\óˆ]©°‹q.–ZÜ“±áús¬ŠL÷làÝÐÅ 47éÏÛ‰;äÛìK:œæ·–ú%>ÄÃçésbËñVXèTF”× ­Ä H©)ŽCüãaH¨lôƒÀ\ãx LžÍf%0ËyÏ€¹Í“zCAÔç- à”žþï¤ÒmÌÕ…äþ;ºRÊ¢ÉÔ&k&àÚÕÉD7[àÊÎÞ†TÑ6]C[Šì&¹m•yø÷{Þ~7ï|eð6N.Çf=NkÀPOCÏNââÞÿE½3^ϲžÝÄÌ Î-ÓÂq½# b‰~6–Àœr³‰e<ê4Ç›¼×݉}´j´Äû ¤\ ,C%õMjH¸ÉX Æ„¿ÆCá¢!ѱqÁØ@ ¨X–¿$J®œñ‘^EðÂ\)Qa”]K%V©¤)ÃÒR ÿ ¾ü;§¡UæÖùÇ_K7aöUîÑÒÏ¥ú6¿¬t¤¤4#. °HA㚢3Š2DEL^¢:6.“à<åÊr ¸'C~!ÔŠŽGB^Ä= 91Ù²'›½Qù?™{—>lçÜå ¾÷Õ¡Ü}žäøX¦>-:=ª Ùß‘J2ïEw–¹è¡5Gv€Y;ëUb ß›7â ô³©œ¬Ì~¿Ð&ºÇ̶b{4ÊCÁmÖ"BÉoZq}ÇÜ,H™eÍñ-£Òtù(B/oÍ«ƒ~RÓ(ãUeƒ8‰Èãà1ÜÝ2J6 "ëõ×zDóµÏ‰åaÜ7Ò׳‘Aá[<áõïåå°0¸‡Ý]jK´©ÚÀ…èä“ÝÆ%‘jâYTÉZ;»èÕÂe"¹Þ» ;‰ªåÉ5êéÆ`ÝWÏÿ …×||ûôßP¾LyáK£7xqþäß¹˜wå<ï±%n OaV{nU!_œØl/5î tŽÑLYmùiXIwа+Þá¼…™¸Q« i¿x‚^ìï)KÓ ~= øóá>,AQ3±¨)’‰r‘êX8´@à6:P àEðÏÎ2£ìŽÎ?bKÁÏÿ;Šj©«®¥ªS®Pº¦$WŠŽðq%oæQà{Ñ€ƒø€?1Ë,ñ¿¼á¯ïò#°£EÈZ­ ÷ù \~[ôÀÎodcf5÷Žäì¹Þå—gî4³¬ìðÝÜ>h/àú’¨ºÈØ’Söf­pOa•Ä‹çñÄ*y‡A¨Žµ"Óň$ˆeé);Ë3¢ï©}Ö£ê>ðLÒ³šÖ´¯Xb¢ºe®uzkŠ@ŽPÛAÌRƒ@k):€Ø¦Öƒš©~žT½€,ÑÜ›UOp»»ˆ}f;Ý(ù½úa" ŒÃ½ç½ÏP#ø’ð9Éf;cBô'ñYüõá HMlîTÂ_ ëIHïç~I3TeHúÌüÒzz«Aò/qßBRb\-~ÃLÛ™€ 5l&?!¹_ýE#°™"àbS‚Ä,ËO)  ¢€¤2}QzGÊ“À•Ðó¿t”êƒR] —å„I®ä¬—ææ"¹R­°¬XŒ.`# ¯:A}1ƒO´¹Êu!ÊÖ’Læ”´†âê‘6P<"v?ä½i—çÈFpa”ù>vþ~ïxÌËÝ|wðÖ™îʪÒ彿]±…¡žô-þÔCƒâG¸“‡ wb…LÿA<ÅÓõÇ¡x–;FÔÚ…Š³ãCxš¨"\Ïi}Ò3T›LDï4s¤„µi‘ŸÑ½ã<Ãz·9ʨ E=y›ñ¾ö+O‹®úN• ß,O«bÔwb–ç¼G¼Ä¬{4—*jm)à;ñ6ÛiÉ—"‡JSoò5Ï2WTWÅnU-ÄZ¹†Úš©.©¦´Uõ"]Åϯïõ¡Ž¸7©Áßg§7*·[IMÄ–\ñ1Ø)b 8Ôˆ.7FàÚŸ‰µè±¥"Ì/áFÆxµ"6C{B5 wÖOËOcÓÃYrÍíʱ¸öãêztYdsdlœ\‡Ï*¯µB·¢Îˆè'Å£²ª\ ÎÓ± Äö¡ŒfmÝs:£ù½Ú\ˆë™ÜEÞ:¼ÅO;ÏmÊñ4ôΠ¥÷×ä°HÓ;õUØổýÚ4£‰8¬oU/Q¤7ðÙrˆ–ìéå>D ϳ΋ØÞ€SÓï:+!xPMxÉóE$Ìף𬼉Ãx´Æà«kÔBy7±Á/Ìm%.P‚þ×*ú7’¹ŒÂ@& "I UŸ‚zEÜ ú9û¹®ö˶„âëÔg`™òc(9/o…¢=ü…çä¯uÉ|ñj.âÒÇÞh¼©ÞÍž£u°j‡ÇójøBñg$ßt© "TÇé‰(~ÞnEÍ쯠h£SòYM!wiô{Èmg= v­U†´ªWW<æëðÜâzÀóÊSW¶G˜i²×û£ü†ˆw-3Hó¬ÔvRâ­+\tïKZ»‚ÖÄÌ,±æ}£ŠmÊúãž)îlÑ,pRþÌ’@5·+Qÿ­êI¼þén'Ъ0á]¦æ‚gªƒÒ~R=Ü£‚^ט ñ7p ÌÃâ P[N…èƒÎ×P´0å;¸ùsíAðþ•Ïÿ³`—Ô¬ò”_žUÔöÝ(ƒ^ElUQ< îoÆÃ ¶‰ƒ`-áp¦šiàÙ«¿‘Û´ lm¸q 36G›éî'z>tƘOªªî]È·¿X'׉·…²-k†µÎ‡ŠüNEÄæiƒ)‰VVó¨y/ÔŽãÖ/öeVÚ…±ÞlŒM)þŽ_"ÕÎ&©ѳçªeñ˜(GÉ•«R´ò/¢ÝàÎõíÑÉÏgzT66vé_¹Kõ¨ö‚ jy¢2¯ò+O ðc‰5ê%nYê3™¯?&?v·k9ÎÛîJ­•U[6Õ3båܱú³‘zò1(¼_}©U*~‹_¸¯ä{üb û¤ÏåFµ?yw‰5ÉYp»‹­<«&xW³O¬5o$æns›ãµ*t·¶û𕱜òNœ.ò$8sbOE—€õ¥¬QËy"c·@ìG!t6ú”›Pm $/J™ ÞF*>¿fŒ|ž×Dðo´mw8 Ì?Ìa ÍŠ%€ñ ‘žÕAþ^<Ä÷UçDàYõ ¨wi Ñ^ù´|4âhˆv+Èç¬Î]*¬Ùò79ž©åw Ò×{âNû |‰úÎøNsŠžæãÌæˆç&u;1OCÙ/I™c¼\§ÞÑq åú'Þt÷6Ñ×s£3Kü¬%:oñ¤9Û̽úcîW8ÆSîk"â.½•ó%¨Ž*GìU`q²>ú\¹‹(Òr¨ö!P/2ˆDºƒKΧJr«d­ðÎa„+ë_‚wyâP®VÊH^áé ƒåHþ͆øJ®âÐ+ N‘àM¸; ¨|ºEÚžoTc®J·¾ÖRô™„ßóSd|㣯PÞß9öyþü¨Dy ­ˆ¸JÖ `Ü`o_ë^0; ý)P‹åvˆuwBxv°øî¶K |6~[È¡ø=ý PKÔ_ÏQˆ=§5€Ø)Ý v¶¶Ü ¦úÆìŒqŒfÿWFcðõCPÞiÚÍÿMÆ1`Wlø²Ì™"Ì1ž ˜ÕÝž`ü¬M­mì"˜º9©M*Ùƒf¼w?›µåÑt²™hÍ#_ß™²Sö×9Y£Æ9ßò"ž¢×ÔXQ5v‘fŠÅ¬¤¶\ ÍUי͘­ÆÅâ!¿ÉYÞšøÔÌKóQr³y/B »ÑåçÀ’ÚŸlç“Xnp?çO«eAG»…ÿm {¦±š±{ÁÞnÞá-Ö °õþÑQ~ïò÷`4Í}’͉% O!Þ„°¶„qm¬,ŒX{Rf Ô–h}£Z¼Uü&=Ú´úŃ©å±Qé=ÛåúÙÓ þ¸õ0Ľí~ÁJfmHžê½’êú§A\ÿ¸?!nk|5ðÅû΃y(¾xÎè[@ìâWà<¸’Œúÿ­TZ”I¨³À‰ð* VApªç¯‚b#=fZùg î9näÚ" ˆú Üö0|¡ýÂåÓ'âå.=¨§zmçkY²ýÒKþÖ³£w;jš/h›Ü!æAOŸg…eŒ÷”ºž©OpÖúúWF»‹úG:‹â6Ʋ©j=Þd«-Kˆ× ê+Ñ,×m ÑÏÍ'!U°C•ýÕ1œ&øÅïzOCd÷0D¦{ZAÑ3¾g±­Gý3™çÞéû“H4Õ€IN+ßk«™§)…×y¶Û»¬\16:À<ÆÔXö…»xÄ?ìøÎÂà\³~I%òSNvç‚ïÙ¢*ê‡êAJ¤¤7Ä/ ¿ ©M¢@bu«1$|}‚†Ýâ63æS‚Ëd9ð­PUÀW[{¼³õ ày\I0.ŠN`ôuª6Bvq{Ü-`®5R@û„¥ º©±| Z<ð–V jkþ°VÈoA¾mžYÎÎûc)ÁzÕ\ N_Ïu [êãÀ}Œ{ÁíkÁî¹ ´1²܉òØ;KØê1Ýž#EÚŒ¶–ϘE\´—v+,kטÁ=&Wéµ>¿ÖϰgÿÁj¡RõM¹cD_¡<ÇöÀ z/¾¨J‘¯úöùFǺj}?FSÄzO‹H«û‡ŸÕ"ò£¾‰î!.Ð1Ü™¾®±û±‚¬VxvìG¾{ã¬î¾ Þ¹ÖIðíõ „¸ç*Ö…x_Æð7HJ£°z-в8£ÿ}u4þàÊ!×÷\s^ÊÿIº…–Æ·í Æs…×áUs²–ÐÏ~i÷D‡^šÆ¡Ï²ßÄÉÓÍ&‘‘Æ=yÀøJ¦ùë@è=CîÇIçQîzO¢hC°§Ã£ü_жè›à9²"m‚­‘þwx¬8Ûÿ±\'Ïkýbw…žecènùBÛ.|u"JLO;Y-.ÞYÂñ¸¼‚70gíõ»µ¤Hkò}¢X3Öáëiíc‰}zZÑ”ÇYÒF©[ ø¦;ä÷VPïrD†ªjƒ¸¨©å¢äÓZØÇá(»‹±]~í™V¦wD«xÛ@l™ïM¶G¦VÒ:|ÊóãÈ÷đ۩KÃâ>CödÑÓ<„›?‰yhöÌô}¨@j®³âILyº}Ãkš En¶Oxz1}±wÄ 3g¿‰Hå'3næ©À&ã:¶Æ*õÎ~9Ì{:Ø#–!F³5rF¼ä{/<œÕq ¢Íx$þ\h}U"0)¨EÄŽ{Óz3îýØ$ˆ-V ÙÑ/!0Îì‰o&oƒäý©@|«*_âf'ô£®ñ»ï>NˆÑ´®¬¹úÌŒÿ_&—ÇHþ''gi¹ Ÿ€Z¼_´”ÝΗF“hÝwi?ß–û5äÉâ3;Ö EŸï„H'í5(ìá;Ž“—· £äYÿæÔ ±,2&~ 3Ã+üŸ«Š…Ý‚ÓÔ™ð[ÚÚØÎn(™­½Áá¾<Æ£¡5…,:YÒ-ºÖ¿JˆÖ†Ðz@x • ÕÎBê-5~ó’ç˜såÍ }FmÐD­=u@žE(m  IâÐn)qQíñ¹HAi© ê:’êU"(6P äBš‚›£n1C܉ëv!G@=#êƒ=ÛÝÁ`ª WÌ8 b¥~úïO‚Á8ùHdнÿ‚6P4 oÑKÈuéEj¥|H_¥ºQ­:*GÌwºÉ(ím¥&‰5¦~{>«xÚÚ€ ösÚ­L‹v)Ù ú¡Þô¼›L—„.¦É¤`mígûG}œÛ1ÒIôH‚ƒq­ÂÔöùc­II9WR…³ÚÑØíÄ%ŽŽœ… /ú#Ìh'*÷'Ʀ‚oRl0xûŠì˜ú*±}Âç8ÁORæbú¦/äOŸôæ ÷Ÿá%1‹§°‰ò*&SÿZ?\ b> @i>Åÿ™Ü²+y³°¨ÎcxX_¬ÑT&äð[-§* ¬9Yw£Â3C:"ää¾9ˆþªä}Â÷“…¯úBñQs7ä5߉ÛX†‘ Vã½¼Þ CY;·˜yÅOƵ£îåÅþ'íoc˜…íxŠ¸Ð½þï˜Q°¯dvžnƒéͯ¿;Ñ›ñ>¦™-_ ‘÷+à{S×RÕÓIœO+ùxn&ñzÿGjz¯ÐE×ÖEnKuL‹w¿µõb7^I©§Þq+³ÚÿŠº—˜þ•;¯ÕÔ½eΖ¯#Äûô'¬F‰§(à ‘…K}áQõ©Nªiªt µOLÂq|z†tõI¤¸SÕQÛ{RkPî•?µ§ £ÿþ„@f­S·ÀÒ¯T#ˆLѳ@ÖYHù‰Q Í™i´a¹(Òª0Å®¨ï`g´“¹ˆb·Yž»¬ãz–Jpfš#Øh_oVÁïTÐ'»«UC­»l/«ssÌ1¬Øõj žØ2^X9ÂßEÆ€aÌFE µ_VKÕ¢oÉå\Ž>Ÿy3|qŽNvÜQ½và]Vò½o“3@Õ ~¨¯Nˆ/üUxŒó¾í!ç£Mà 5šƒ³¢ ÄA£‰=Š—ƒ=#›±ôÆÎrYd8ê9¿£1_ Ök»u*ž2·D?q®×*rîÒëŠ+\ÝmDÂýÜÙ᱑öºð"z,f`fXÕÆàÔlø‡ ¼¬âf1 lY0WáxåãÑ9Uðï:<‹ðoôÈ¿:¯š‹ùFozÓNÿ(Ñ^c7óÔ«ùæ{¨.FÐØî´æ?Â`Ú¸ûx©®- ÷F ¸Ä ,…xߺ•Y~rч°;”5ÙQÔÖzó*]Ø‘-¸[‚\SñwŶÍ¢›!µýÂ瞥%ÃÅHȬ¯ø‚"£ØUýšYîû4CÀù‡‡¡rYˆÝ.›²âÒZPã¨O’–Á~Чñ¨+R!Xƒ´é ×w‡cm¸”žå­AiKoPzˆ@4àvÓ BƒþV ïÙXÿœ~'ƒæÄAŽw—½õ«°©n®ÁªzöºÇ(ÌTùN˜ Řfåð"íÍa™S s'uôò¨ÊíRgVie®Öh9¾*ÛŸ%Ï]¬f{õ,8›.^„pLö#0fñ¨y”!Êÿšß ü HüåÞäs Õ íÙŸ ˆ‚Ý–<ŒÔ|¢þÁ`Eµ¨õ—ú[:Ôªæ'`-1j‚þ[úaˆvŠž‡HàfüyÎP½6ý-ÇãϚυƒ#Ýg2/‹…±3ÓÁÈËŒ@ƺÚ_!rÈd9iöt2ïl#Œ¼ðiˆ·+^ÍpDÞókBÔÎ4úÈ{ÁºÁ­øÆ`H,(}²Eô‚ÀŽ]†x§à$ˆÑ| ´f'P¦Îñ—ý'س2/šÃ€7â…³¢¤TL‰EÁ¼±l.˜Ö2ͬNàŽÎ§¹ñ"”?‹CVX¤ŒxgÊKjÄç¡¥HÌáÁÒZÆ {Zö^Ú—ÇÅ_bFi¾ýë.u_¡¹·­¦ÍÎØø¦fôÉJ2Q½Æ-æ¡üb}yžýÙ…ÔQJC Ñïª,’ÄeÑWð¿ÿÃüŸ+Þd®:¾#þ<5u¯ÙÙïœ=šóRúÝ’§#µ‹™J«SãùIì?þ o¡Ÿþ@YÏÖ0¿ÖOlÏ{½e'œ¼¯ò>€Ü†zC,«©¼ŒEAWˆÏµÖ4‡¿’ПuÐÄ|ÔšÆóîp9mÍ¿‚ëAkb×§‡Y=zšbíã‰h RˈêU¬äJ%'õexz­x?|Uüï7&›¿# Y¨Ÿ ~gQî’ ¤=)@}’nPécyd—ð"ÔÅËÉ9ôÛ€V< ²¿r°O¬æï ¶|ÎuÔúrKÕ"íyÐ?VbP|µz‰ÒÚšZE^yy™R¾j®#â{Å·ÒÜY˜¡™ûqÉW,sÇÊìpËÌ»˜mÿ]þ[coè“q®ÊNH-Œ›à\_ÒôméʘFm{—¬(5ٯϹ'q¿œžÙ¢üQe]E7*bNEgvëß$ß#î~Ÿù©ï~<3 ÊïÊäB¸Ö¾ ¼åÙ§Áœ9ö ç](}?| b^æn07g€ÞÒHCdvr,h{½ UhO‚}FÚü1~™˜žq§ÒSù%¯CµŸbU¸WQå(~’¨Êµl"·Š_PåuUeüB%ŽøõBDxYl†àÇÒà'‚75QB‰*Àà²-à/6nåŸØP&›(ùr2pEz ø¯¦>·1‚M²¸of'AzOð"nºG°£ô…øÚ–5ÉÏð[ÙÅüûiSzwîçT;Ö²Óì «Væß~—ø?ýSýÿ"ã ½+º_·½läœêšË O¢Î^g$´ æ®Fõ”––^í5ÑÆh~A«†§«ùz|°{·>[ûÌ>/^ŽWË¶à†ø™,Ö{dËhk rÆ‹´].™_d¾%®O°wpw¤FÐâ©T[<‘òסGƸ¯"Œ•™"tõjÙ "ŸØ#ùFy1üšÉz~f,¿éç¸htu¿§¶º3˜¯µ¿a¦:Åw¸N;*%=Õ¤ª“P•Ò™4T*Y‡¸YôÒîDÙ°(}i ÊyâȺt^U&Bø%7 [d–³2X¦ÿÄ%峨A6Ëû¼þtÀTïäIåJõ>þb°òªü-v˜êb¬3.riî5ŒUn¢-÷+Q³ªö ¦â»“âÑ"ëõYg}´5xõ´ç!ó¡U ={ÎÊ2,yŸí±WÈd¤µ Y¾$vŽ¢¼‘±™zz7ò–þVYG}¥52v»È‘¯TZT#·´‡Ý ìÎXñþöüøÉôHTó\zÂ|+9h\îG™6à ÍÖ¯oæ)°ïÎ8 ìôhð¸D¶„}Á}'Ýô÷ÜAO+Ï€Ùȹô…A.¨Ï9ïƒÚ‡Ê lÐN€ú%iÓ8âF¼KþÁ˜’cà«ùï|Ò\™¹ì yqÎóØïÓÀ©ISÈÔ¼™Ç­ï!»!¶2“Í#Ú½}bû YšÓ-u4çfDYE®MYy˜›âÇò}ùãXV¶9²tÎ{UªÊ5í¡›rkƒÿ‚þem’±ƒêùÓÏEhýã=&¶šF ú ½{ ‰Ž™»8y#»‰£[³›X“s8]ˆ«-È>€‘·Â¹·ã3CÀÚ“ Fg·Fìhò èí²½ÈF+;‰œq‡Ó*òU2÷ŒwÝûi%—õàŽ½ô]%gCCŒ‹ lÑ.yÆû£Ò“n+¨ñi £Vi.…ê«Å}ó8S °þ8ä¬W>€hcµ ”s,õ˜êj±´KÊ W˪ ¯”ƒñ¶ú0(E¢+È"|`9 NP¬ä[ C܆AÈ\¢ n¤„Ëåðòä+À¯L¯¦\~PvÐJ+àâãá.¸|›lЏ8Ty‰ h¼úÚùfFORÁ"ý.š‰Cê¸Põ•¹5ö)h ÍRDB˜ÿ‚:*ºG½Ã¸Cù,Ú¡m‰wkrò%DÅ¾Ä  o6'QLjçöâŸØ´T{¨è}¥¢rÎ"º¹^),N&G~muÆpož5‡Ûß@ªRµ5¸é\ïJö§þåAµ8xŽg•-´Ñò YG¼“}h”¹(ÐÞkÃt|k7 ù•ÄiÝÔýìÓþ N÷3j Ôå"à'L Û/EkïR{"Â%Úð׊Á×O ÜJf€êV·že¥ý¦9ÏÛ ÏàÔU·?–O2#5†x 0ÑË €Ô-êbÈޝýÙš¡àϽ¨dô½Ìý_1Ô«þÓáß‹ñËÞPB­83“ñ¨¾•‘±z»#ãµÎœÌÔ›ëí–òÂs€IDATÊ¢Äât/¾3:fªñ{ÜÊTç`â¦tDÈÆø"R%s5j¬Ø~wgTôȆL 0ÃÌ|ˆÍȼŠy-8ƒ[–LÓÐXä6ãXø™íƒ;<µÛ”ùZ³³hî§õÙµ§{_‹¿küí;dë=$òˆT?§´€ÂóúÍ ßÄÐÖŠ2PÖó5¨wŠj }¢ Îb€ò– 4ûߪÿÿ¡aJ~ AyÂÙ^£ðʽÀ`ñT´Šá̧ÁËç1ïø¯b8¿¿×XË좟Ԫî'Z·f»ÛÙš-ì¢vzo|5'ý‘éH}zì%ÔH¾Ùü:¹*ľ‹ý€&›$?1'q#Ô†‡A©þÙGÈW‰¯³ÃEnQI{;^)òwÉsf_m^ökÆéïø=h¬ >ãUµ²òw%»TØ ^’}@}EGZ¶Ù™³åŠ×‘Ö½?ŠÚIžEj¡øEy“+@,¸‚:<¨”Ù¡?l,yB¿ ¨™ê Êe ˆ@ÞPö‚lFág(Ù„ȱüá>±˜!'Ò*üG¼ÃÞ;òsZ†Óà þïáÓ¨Æ/Æ"BVPñ_ª½ØFÅ…„RíAe=‡3šÒƒcÁ8m‘xÂ_§ß+–{[µRÎúëô®†ï%õ&FÄÍÕ»ÆÚyu4-”2W\ço .‰Ð»2¼œ‹zSŠ0‚BÆEVzÂ?m}"îÎÞ(šG¦¾ç†ªï¦à7­_æ seãÈœk’«8e¼çFˆå:éÏ!Ò/Û"×dvBäŽìjˆlJ®!4²÷¢DïôÚòm$íœb¦õKJc«²%|‚¯ä§îËL¿q?“k‚žÞù°’ò½ý·Å¯Õ·y·±7÷»àMì‚ûÂXU*³ â“h±õü¹ç• µæVˆ-PgA¼§R”õ\}r8M9ÿ÷?þÿ+$·.×@ð¶ þ̰(w+õ!Ý8åǃ·Á9#AÉšðÈô`”w”ý,Na\Rµw)¹ÔIkΉ³ŽvMx*ÚMùÞ·Ä«"á^¡¦!{¥õ*؇" ðÜ^ÑÏÑõÉ‘-`úzp^Ê‹C´§ùø=rn‚JU²£•ìËi ‰YÞC< ×øO2´¤ÜÿˆPÛ(¯æTÞ åÞ¨¸±ùL¢Ù¿l–gåIsŠRMœ®Y³ñ:&æÖ˜€nÞ|Èý5(4^Žô ¿Ònó¦ ¥¾ø×?%ΙS¼ÊDŒ³þ— êÎx.¶•oÑ&²Ì)Œ zð5Çô…þ_hZðfPîñï­BÖÁ]Â3 <|Pï »¥ê^¢Ú »‡ç!œÏ<Åç Œ”«€õbZ˜VêC˜Ôï¤$h.odþnP‹ÿ«Oã´}GѨÖ;¼l©„vÝPdGu8xkÕõÜêPçÑ-Ü¡€ð°6Š„oé÷òû¼ÖMhÁíog*Œbòýo,Wkì—è8é•Oñä£mbœ2Où0hY¨$\¡Ôæ”óCbùörw"{kGÍì}òANd'‹?Ésÿªu5'ƒçŽL€ÄcªÅ¾ø]âsÞˆõ4‰o¢‹øCF"(Ó½§õ¥Ú;v_6Y³²uxÃÐ$ësг߲(šg/­œ‘*NsÐOøA₽ ”ãÎIPöË Òuv]àNï3¼2ˆ”É4˜‡¼F “¾ ÆTñ1¨‹½ÓÌBä”<ÊÉp»=œJÅC@VSwÜý®ªÞáëñ`ìvº@æ»ÈjPÆ+çcÆQ7jùÀOÖYÐÒ€×Ójê§éRHMŠ}†HüîíÒÚÞ`®ý‚ F©pÈÉV‰zæœloV¸O«3Hfÿ,ÿ›„r\¹Á¨¬ÙaÞ3Ù ï_g(~g[W st£-šþLöwD´±ú1˜k³÷à[ôÁhÖ‹âi4ψf²…q„*át}Ÿò•_C¹ 5òÎbÂýŒ¶îy.׸xN¿Ñ»“÷ÝSøúkÁ~¦«‹ÝÅ`¬;y¼?˜C ÕsLç…»1µþ· Þ&sAé¶1.°AýJæ2Z¹”Æ …à¼ì Ô“?–Z¢¦×µM‚¢ýOýÿs@5 Éîrß´g>Vïç§Š›AÞìk=+vBØ&rÒx7|ìžêë4Ô¶€sŸÚL6Ö"ÂùÚ„»Þø hªAÉ6®B¤7 @~bÞiÛGè¾cµEñf˜ƒè›]®?ÔI•*=ƒîœr–É9ž^¤C&<ËûlÄÆKýî¾€ž>¯ì„ô,å([ÞŠ;ŸX Ù×.í¥ÜÿÔ5þ0¿ÒmÐ1ÔßdC°îÊ;bƒ¿øÈïñfW»@¹Î.í¨Ø êxe#žò3#œçw"ô·s#8"w#ÄnÎ!‚áÞb𚤆€¿=0@ïY ÞT¯¤¶–-ZóÁZàÌG€{„Û ý¿œ¹²>õ ó0« r$ñ'$êŸCäð{0»d¿€Äω@ï˜É…xa´?w‡Û@}7+!bDßåtöW0kÄ¿1Å Aámõר] äòˆYD@–Ë€áÊ_H¿½=‘í^þˆkó—€s.}5—äòèP*[Õ…&y‹j-åûD^"FÝÈRSw—`™1åê`^;ö¼?S}H{ÊYCJ¶rg/øÇ™Îvåœó>3ÄÞÕ|;ìãªÞF ãà †ŒMw"ÂŽÁç„úZo*R_ o@ѧ8=a/Pv«Ñ{¸…·úv7h“ÃÑ ÜiLãÛ[ç"»wQÚ#”ÿ2µ/Í/Òp{á%.É O-”Ïõ{HÓ@öDKy‚¬lÈfYÊ>y'Ì(·ˆä|{ oùÇ/½ƒNŽn”ù9x­J'@XUÜúà÷Ӥ«¥nÀ²eÎax#´‘Þö!2Û¼àLKÀýTq!uØ;ÎÎ@Iïô§ —Z_ƒÙ\ŸÊÑð<CµM ŸÒº‚¼`«`ŽÒ›"•ãâ =ý{@ýM9ŠEH›”—‘b¯€\%{<(®Ù—Õà?ê…฿‘]šúé °{#\ß;…Ï™_Aê×ôxð‡Ê»®%ÎCvBÐÜŽœ€ìUÜ™’ œG/ƒjë”*ëÊ-Pù°ú;ä-T^«E!¿Ryõ/¹”û¸ÝjÉ ±œé‘ù%Eñ‰¨ÉWs’L®°ò^áÂå±¹ƒiS²M$=ÂsÙtùe CÙƒ‘'°”¡W¶cJ¬°þ#t5¢J-nR €P/j¡ˆ…™3 ßšû5Rü[Q ¡½â,¹‘5sŸ¢œNÿ©à™?DzvV¡`—×þòÂe$âô=áûœ8÷›hÇÆôßy_ñ@¥Å ‚ÚïÖ­†Jùb˔֙Ä20÷+#\.Fð:…æ"e:}­k‚yöŸÄTîòZ!c÷ß#Œ9Þ\Žè«ýGëôš³.Q憗 ¹=÷Íp%èu½ó¾΀ð[ñÄð-ˆÅŒÊå½@±ä=b7Ès¡€Ôå+ÞSûC4¦ý/Ã÷{(-ÓÛµFÝ éJºá+úÃH»²a#ÔmÚ(ú^? Wk{•RÿÝðfÑÞýÚµxßýT¹öh±™ïÒ¤GóƒÓ\tÀË\Ы¡—G/^ñóÑû° ZÊ8W`ø½àÊøën›h§\·ü%~ÈëW:…ëÃdŒJ…;’¯CÁýɧ!á'ClNêNHôLÿ‰ÙN?ˆ[é' º43¢o8]›¼Œ9î^ˆöà(XûK¾­‡¶ ¬ÝÎ3xÚ ·]œÏè§=@+µk¥{yFû§|w(©ò‡åGb¿Œ¡‹n4zó˜¨Ä^¥¾LÊúìÙ0¨±‚Üð€Ó 5øÇ«ïR´ ‹åpÓªó®u œCì~FcÈøú[²Ì.½™7­Û‘©GͳPÖ'þ$"5=§²bkb*~™’—ƒ^v¸RSê–ý]¹;“/^ðc.÷ÍÙí­KÕ‰T”mÉ|¤¶Ñ»ÏFÇ<çékIÓ›ñÿñ3½ò3ï3ù¯_DÊkràÅ;Õ<Ž{ÔÀωNzßàok¤ò–;Vm`ÍÏ|MMëì$´èþ´A «á¯ÈVûuÂÄ}™ÙÔ‹Ü’nžpz¡Gkdo£ƒ³×êëüŠ™ï=Š0ºg_«§³ŽŒãÁš›w¸ƒ8clqgck²÷‘Òw0Ÿ¨ËüHµ©²[¾«ÏðºÉ·Õ‹¬•_ˆXX$ es¦K':ŪI«ÔÃuÓÅ?[ R%¢3ërg¨ÙkÝ­ÜB½rWü"kw+ŲP¿M9*÷†‰Vá½xÁï%Þà#ïéÈFÎÕÆ¨öX½u½÷Œ†ÔqfYYã4T_ãûq+‰ï²N¡e¾2–C¶Z$ ö#‘r‚LõX5û«u=AjDd'©ýÑÉä§&Ä5>H¶‰àhű^µçÇÆÊF¥+Â;XóRÖQ\éæ–®üÂ\Áy£#”–æNªÑÒêÉtqÌÚA‘7ÍÈ3J}à ²jiÝßíûÙH1”­OL†ô‹Ñ:xÉòx>zÙ ‰">K¿ÏãõÒâ Ù—úìŽþ\Nåø¡éÃÀ̽é­ÿ€†ç€èùg^ù˜˜3cM>íc=UŸ¢( ÿµ¶ÕíMj¿H»ÌuÈœkRo#"~:Is²ƒ ó‡§C‹žN¿ŒUÉ|‰ˆÕM×…ØGéï zø©sžéIYô w/y±û&ˆl©ø"NOj˜½~£× Ž9ß«—äPç+ò•Û³‹ÊíN7nÑnp_ät²0³ O_í@W„÷$ö7AnCfBÎÃâ1È1”¶3J@t¹¢@¤ƒœ1æyP›‰çúå"ZE¯…7Ðx^®êr)÷Q ñMVu°¯uÏ@PÖBP[À**@Žá-„qÈtñ×BØ é#^ÙÝAH'ƒ :&¡´‡¿’Ó™e·Ê¥PÒW ƒLLo Ú瑾¸AKs †Ú0²ž¼h®a¹lõˆˆë"ëdBݦ=íG"›Ù¿õ ^¯C•ôæX„é{c¿a&ŒŽCK ŒÆ¡¢Yâ,$—åîôG±ÚPþjìEìË“Ð2£s¯çÞòXü8W–/ÏùšQ—Fj×ûíDÛTSç .'}UP³üéì(.§ïm)ãÕªA|f½Ý`~§ßú©p8(]¨Z>ƒ@íÃqÐ~ D>>hïð*(ç¡ _º³M©b^-Äù“¸BÜM{ÒüM3 šÈöò=è"VJÁ‡ ’±‚—¼ð®2äf¥ø¥œ†àw ¼“a3Ðv5œH^Õ¢i)c®zÝÿ9þesáb×›à§ÞB¨èjž&TWkzݵëÐÜ_Ä5`ÛV7ë_€{þؘ½ð¼žÆ•èîs!ß:]õ–²$<­z²Ïåï¼ñÊÄ ™,gQ´oj;Wç÷I}Ëìè ÔôÌý:õA¼({jâŸÔ;š±ñ©U{<Û¢SÓ ~«ŸÅ<ïÜD:úPö7r#©ŸHYKÜLjG3é`ìÍ4ð¯Så¯DY q #íþD®šã^Å€@º÷ÐZ´tarhxOã;Òkfü¬¤W, JÀ(d,÷-õxÌWÙœžl ü/{Ë—ŒrÄ÷Êïàæ†ò“ÞkuÌŸÀh®¯¯¦RÆ/F°Tj¯èç \¥Çq”F¦6Þ¬IKjšoò\æGÓ¢¯~—5šêiýLÐßh/î±*õ2 ¬iìI/²>¡RúXþZÈœÑSP±(çgH>yÊÆBù]¹-¡\ÍKCrQî¸å_%*aœßœ»Ÿ{ЧVºÊöä,F—öV«&G«}ù+œÛä^‰Ô¯Ù?¼]ÿAìÇÕFÊOþO¢‡vÁ Á8à~FhÜê¾…b8¹´Ö·z?±ÓÈ 6¢ªSÜ?fQð&žÒΈ®· Z ´½Ã Ý(¯åGÿM¤ú¢¼„œuP¸”|y‡› ,VžÞG‚8Ewekõä‹HåUñ&„s”ÊžÕ¦"ü;ä^¤'oþú?o4BDþCö…ãÈò}/!ܬû€rdGj"Â%ú7ÌÓN ‚FâFð†©ÓÁ‹¯#ƒ7”GÀ®0Ú Âþz70ªz›Œ~hv?ã„û®ñx×›G!ÝÖZB–æcDR“ÌGåûö ÚÌ 7|FéíUk‡ÙΤ²sdCÚ¦'‡39ä-½ƒÍÖÈ’Õ<–°Ô/ø=îª5‚÷Í_E«lMñIôÃŒÏ9Ëì¯ù#± ÝOôw3%Øê.7ƒ•³%{"¯8§!zÁ=Æiûh‹· ²Äú3^CÐ_ó?sw¶ˆÏÕQ`=mß Šì%¦¾ ƳɚÔò’ n¦(m"-AŸ¬–€rWðÈCY|Uî€`·ºäóê>®W¿†0£‡0Vƒl ³2„¾ÏÖöƒÛX[ öƒú ȶ3WCæ k4Ø{ÌáÜ­Š´÷DžF”µŒ¾É_â—ÍŒ¯¥¨¬FîûÔ¼ì$Ö„cËŠÅý28MPzIíIá¥Ð¯ Åó0Õ-> /1©ÅrÌÊ?]ght¶–‘KÊ3Œ7×¹7‚5>|‚aVÂ8%3Æ›êDÿuœ:ß›§Äô1îIê]m imq:‡Ý 43¿uço£‡û¡þ {ß(öÆcè¸Ïƒþa¸´®ƒÔw¹›Ê„àPuyi ‚ò„ÿRû[>‚uÂy1ÙoÚ6ù9ˆ[Â7ªw7‹§Ay™n ɹþè.ʇ*ÈëK"×!Œ]ÿWÎÿǹè]~-"weQ®3ˆþ>ÌLDxo‹ùˆ`s´"ÿW­„í>‚Èn¶>Aä^«ÿ áŸZ[ð"Zˆð÷r8Ióð*«»Qí)ëm”!s[cÀyÁpñ¹VGôÔFã[jÛ¹Ñ^ì±î³nP Íõ‘FQÒKÍ¿"GÜ”VÝílãd¦…: /y¢¢˜”q½z#ùúÎ „z\½ŒÐ†‹oÁXP÷NDYIÍùÈ˞݀t{•KPò¸¬Wb³A»ä—€Ò3|¡ò|DäXÎ3HZ^¾¢·Ò”÷T!·8¯A— ‡„êQŽ·²èmš‚ÜÇISÔào³#‡½/Àý»xx?²¼6î<ûp Ð ;veÖCf':d6ó7$óØa'6@¸.ýˆŠTÍ©b½,†ôö È©ge Ó¥øY¯s!únä °‹/ík¥¹ìG‹î½L{´UÚCœ¼x=“@¾iQ6DП#à~Ér²êÍj"ùƒZ”swì`ÁQÞLô5¦ðWô kG­s~"øMo,†úóÔó9óí•Ì2žÊvcƒ³“æ÷îº$¾³wrTyÂÝC›ÈWŒ±ç#•3ÁIôÈî"ÐÞrï­·SÔ­rŠõ¢? ´ ^MPž· õ™¤¼[Ô_O#µ3Ù]„Á]Ù cfg¤æTóm&bˆclþC d;Q#ÛÜÜã,Ef†)å )èþ â3Ñ‚·Ø%KH &Gñ+ísê9ÒÖ^e7OWÿY¹Uú”!ä–ÔQz…ŠUʲ ŸÓˆ¹Á;ÁÛÄÝûƒƒ ó¦Ë <á´a?ííœtC¤ûŠhŽ0¾õWƒ}Ÿz%dyïƒ\è¶õm<ÈíÒÿZ{8ÄîЂ˜ê߯'‹Êv€õBl=(‹ü8"8_ѸŽƒ¦YB¿”†êàq*ƒ715ü*Ù%>'_c½QîF7ôƒr)môÙàœ _†à~ñ,¨c• àUf@¶Sm¸öd†xÁ/òòB°øÆÜ¥5Sß‚YÄY°nàMˆîS^ï3åWðkp;N°Ãÿ–|Yª.çvqY˜áQ[Ûæ®g1?¨Yg0µŒNÙ%àïÉŽA þI=~¿ìÈàÖl„\—jáÏŽ^…7Ô›ýI ?Ÿýd‘ÿ uìiÜbÜ ñ²òe gd®ç'¥hoFs)€K™ÍàŒ“BxØ8 áÔHMP'-ÀùÈìüªï„ ¦:é÷ôC„÷NdøžìÉÛ£û!ûudApoø;ÉTCe?Q»Ö›5iÍXA¬¼‰õ:OTÌÑtžñZpª™ù8W‰Çj×Á¬úiZ`ˆ 6¦Û¡)G´²¦Ú]”…(7)Kƒ2å†è³¼)ÿz…ÕÅâh¡üšdιÈr0ó?' –ÿ¯%ÛKðg .²bYÞ—ÔŽ)uð@ÝÃUÛüsQŒŸ²ã‘±ËÊz„u]Ð bŽv3E‘ćT|(›2ßê§¼ËUÖH¥2+"_Så9#×*óµ˜z‡g©iãAï):ä=ä|Šî?ïÖç—‚þ's¹»ôÕÞ„ö“÷ˆ=þ~êO‡çYWxÉ{)_F£Uyš!H©º{yá#X¦ÌAíIÔÃȇD}§å G«›@YâõBfйâR? ìÓ~ñzÐÊ×™;¡¶#€Ô=z+¤ù—öŠû™þÂ:©/‚L®Ùª/Öç‰^éåV¨ßžy6ò®~T©Œì²+©c#·§ÿå¬õ›v wg9,7®q»h?ÆòQR}roC8kÏÿAy°›½´ãK'Ê€¿œ~wð ‚+±kÖËnB¦Î¥„úoò{Њ“ý;ùB¾›¬á“ÉßAö°ÕÍì­–;t‘ÒÁô¼`Ý“™æ§ÎK`>å6Ä5û‹0ôœª 7ºû¸^!¶ó·öÈ™a{1Ozá ÌUS2ÅFù—L’'îàm6Ë7D žOr³:Ji@êà"ñ¨¯,N[e }e p+ëû@ ÓfA8<; ‚î Ö³žu‘q”qÂxÂ/˜‚p§[#ÀÝ“hˆLçæÍ#[ñvÁ;(e*Ÿ Íåe•[óðÅ¿ª^ǘ‹ç<ëý–¼ƒÏ/½)¾§ìä) ¯Ú9e±¼lþoðÿ?t=¯¾œŸØÜâV‘‰·G1!þ¼÷A°Îšì¶‡Š•ÇÓõ1¢½3³ø(z]zÏÆ¬ôj–'¾vz‘ŸJwãÊÈëöÔ虑ýÄ òœ“FFos ‘;2Ÿ¡[júa0:»—)0¥{ެ™Þ[4´ú§$¶Ù!TùN›á óŒA,'(ª}Ñ?.¾‹¶ ¯»Fî–h³ƒ,A0Ù_†*¢ÁqüÄ\D+ÙåÜÎ+f¹¼‚SU‡i‘¹"<Ž > ùrø!$ûÈJ`R[5E7Ð*[Qª¼'nä¶K…M¨ï¯2òX«+JuqŸÛ^ù[øÞ­Mä4íµ¿wµ>Y7Ü"­u>µ@û]òš¨ÇDLÑÒ rÊ}<Ò‚<»©ù%;³–º—«²Ýz`Þï ±g£÷@F3ÿD5߉!4š:ª(ÎÍ'Oÿ&¶ ÔŽ™Uô öeO ŠŽNœ©üèåˆiV½øpž+\—óŽúo2¦dwµõ·X¤Ow劉vƒÙ )Þpö!Œ¬2ÄBQ ”/‚ÛA«éoDòIðB™ëÞ êÁd°®w›ƒwc6 â’sdGˆfr9P¹Ì¹Ë}”öÊq ¸øEl®@V(³ÁŸâÞáTe7xºZ ÜNÚ]à>¬CÚ]ÌéûdtdzÄkAj_l3¤çôC&§ç E)!· ^ù±J«©(“ÿÇK~ª<–ù—¡ÊÅ  T¾[r"òfyÌW¢_Ñaù_g”*G¨{Åu•æÓñ¿/ψ{”ÙéQz‘q[R€Ý2;‡ƒ•פßå¶ÄÀôDŽÇó’6¾•“™…‘¸1S‘K™G9‹öÈø»©µˆèªÌÇdbWg·ýîìç™È¶äG¯Îne´uZr\´K(½u‘3ÂîÊiµk¶ãÙoOæ”¶×mT» Á)Mï&»*ø†‹Nÿìµ`}éß*;¹“@ûɳ sMf2>JŒD¸Û¯@ÐÓí Îq®‚ôuºõXi9\Ž>§ïC$T+BÂïéw#HÉôE¦ÌÞ aSy´\õVDîñ& žQ[ ôÚ(韽#(™9Þψü9 Ø–lP~ÖVB¨ªAìÕîëóA°§ˆ;­¨ß?`ð¶¡Ax¥ÑEt³Špä&+X ÓX0Èÿ$rJYTÖ7rÀº'¼-ò•¹ÚüHý1òx¬.ùéÖæÛ©Iü’œù“êÆÜ ýì e»ržƒ`¯³"º·ÙYŽõýÞï½C©½£óSp­Ø©>—ƒ•g¦ áËŠÛ8‹4–ðqEçÊ]Ù^¶\—\_<D$¦±LV—cA?nà8wruyJæv±ŽÃÀ ±W©-®äÅÐP>æ Ö1›ÒëDjéÕÕwäÇj=¥Xî©8£Ìâ¯èCŠÜYñ3ÄjyH\äòÿkáã>ŒÔŸ/úQeßrîVÇ¢ø›Õ»QÜúfOÖi×#ƒµÝàLÑ¿EºcõÃxn\«™®Yʤ ½yÜ;¬â ?anôM³èÒê²H{Kröë ¾9yb{ÒcQã]Êß‚è Ù]{Kú%ˆnI]†ø´ìíÈøfû#DlcFãDìál'†EÝìR¶FÞwޗǬ†Þ_no¥§~¥=˜õáöM|ÙmÊÔÈD÷&ÊÎ àœpò…¾Á_†ë±ë€¶4x-g@ø$d7g‚Ñ&l ê9’_gî†D íußs29îfðGøõ+±€ 'Ø ¤DԖ꯵»§:ÂZ…ÖH÷QbZ["= ¥éqöŠ –Æ‘G üW«+§åK‘aª¢T‹>›dNÑŽks£¿p¥úT<‡== ®Íyá-s¿÷|î[`þ%^c¥˜Êgâ;p¶ˆ:éwµ…¸ÞW±<¾’=‚«X[1Qn×»sƒïs²ÍO¹åB6˜ê.Õ,œ|5îp.ãXm½>`Þ˜ù€º¼æ/`‹Õ?û W¨¦ÂîøA·Ò˜âwFª'œ1}«W„Á,ùDjú7úOЩu !•Ëþ— Ý-#5Âý„Ê01(Ýè ÊC¾Ž Rj«Õ<¤ÒŽåèa_·*ƒ>Ê,rÔsZ7LþVF#Æ¢;ª›õ?Fmƒs(Êÿ•ÿJ„±²è4¢°‹ßÜ?à øN=²º¾„À¯&{aû/FÁ—MÔéØþsJ5ªºË«À!V á5f To¢¾ÅþS{áìÖÏ@öñH/²ám‘dYä,-ƒs‘a,Ž7#S¶ÕCì"mxqŽu«ÕVY¬½^–‰Cñß]ƒ.Ù[£µ)÷ÎOñËÙ®žoµT«eV“,ø1õ ÔÃiÉΤë°)ÔíJ8‘û ¬x÷ä&%îý`MOÚ§ÎË`\ån‚ÈI;DʲhãX Ñ™_@táq0?//šZ_CtFfÐ&£‚ü×zÌgŒ"P¿ðoqúÒcàoôkƒÜ§y ^Îyb¥î/àM½Îëȸ9Âjâ¸[à ¶°6ƒÿ¼Ö ‚ÁjdµH9È®±µ 6wn Ô߃ôÿ Ï!¼w„ÈTUó 3ý¡”$_”Ó9—|^ù±É­Æh¶¤n{øp>ó!ãh”üÖ‰¬h&ö³žEiظÙ2ÌÄhëdä‚:‡·¬«ìjäE†¸ÊoÍnñ˜W¨FãŠwV¼®:v ³ÚÛGijVÍ.u€ó5ÍI®Â¾øÈÌ= ÜÏß±'¼¿ÖÝîã(ú47¡?â­ã÷i¤¾Äo‡Ð ½öTýp”'ƒEj‚Ç ôÖÁX¥®hª¼!ŽÉ|úëqµ_0•¦©[PGŸ üd¶å`ð3H;‚ÿräBíùð)õþó÷ìï.îHöü¨_ÿ$R¾*šuLΠWy! Á,çsp+çnå¢zÌŸH¹3—2ùs™HµÈG8õbÝ‘²‘?‘z"¯ˆ‹Ú°õ_Ⱦlþοº ©ç­se5Afoˆ^Bdî, /û\lçÒ_F:ãf^‹ÝÉC©á‘–òHEGåßÌ1ÎÉ»².&ÏëœòŸ2‡1“uÄ«¾MS¡â5vÃÅ1e5 dÆ©Á`üíýæ€è$}$hs‚‹`µ°ƒòœ³T-øÔiX ­à$ˆÉ\Ê\º° ȧ/„ϱBŸntçx8þtZû¿¡ ØË8 ÙcÈ–#!» ¹ õ"@E ÕÀª—È9ø 6„Z3¹¢’wÀêO°sÌs£ÕA«N h£¸´Ø Êd\ ŒÃy)‡r¾$ŽrÎ\[˜G,wFÃ3äædso ?ª?K4ò]pN–F&©þOúÏâ~û±À*±¯âçü¾ökÄ-7³Ž‹fëLµQÙ¡”D*yïÄžrk šÇìŸÀxÀ^‹Ôú‘åöÏHí)ÊÑW³3‘j}ÙanÎüÀye‘²©¯öë§Io¡:EïKÔø¥xøÃ­ ÝÐÏ ´Ê¢ (3˦?U©ÊK¯>Äñú?h5©'þˈ»©¸çÛóïÛÏ{«1Štÿn~+AŽ`˜ìŸ|Ê›âeú‰ÝâVŽpˆy¤ýï•×1ƒÛµ£8þ&u:Qù²ÚßMhûÐ]Oý”ÒýŒ<΋qújY9{…z"HÛY¾pWDßCf—¤{rÒéf|M­l®=-ù3²í8™Iª©kÃÆ¼à}ZËÜÓ`ÖCP†¸S@ôw§€uoÎNðû^ìZU=¬K•P¨»!ü*; ¼¥WCØÚOo²Œßª¼îÓ©¯Àí‘ á/êŽBð½Ùmnü^b"dŸwmðG·@Ås} Uæ>™+Åk`?#öBY[’dؽô§Á@1äÍtÓP؇B¨V—ÊPx+— òõ(P¥œËUfq=z~˯òîäÑtm|tpÙ÷´Í›X~–wòn-oNƒœ?’÷q!1+õ2W'žJ†Äúl䌱…hËÔÃ`ôös‰}ÉIå~w˜ y¢³}´¡™Ž@C¯#(·DÚõ‡þ=èÛËö‚s^â”ÖØèÏw¬ú2ø5õUÈ BkŽp&šà_a|vóH °Ÿ‰|ÙyÑ ÈÌÐØ..¥§$JI%&ZQ/iç¤9T>5ß–¹yWZµR]™*É‹v¶´_àdö|Ý‹¤ô¹õ¾'ÏLY›dµ£Ò.øM‘þ­ÞSbFâ!ï<«ÂýWY¬- ®§¥zλ‚ _r–H¼šßŒ0[KÍ'¨÷\Í#4šVÂ&Nªõÿÿÿ{æå™»º#§On÷#"þnÃmPmc($Ú*·!ãßñ4D;°ÛÀ¯”%î0—R}‰?©o}hwcF¬WäG¢Ñ¸Y1f[÷vy9&üÞ«K¼›}‚”lé>ÆÂX‘»ˆfV/;CZûØbä¶Î^ƒ*¾t' ˆÕl\?óø¹þ~ˆ~í¿Ê•A9Ò˜âÏAˆ+yÌcéŸÀAù ̤ù:D¿wÞ¯‘}Ü~Bu›ü¸MT¶Ë-àÇk ú@P¼ÙþϹQŸ ò~m.ÐQ4{§ÙÄWJuÈÔÖ×—oŒ÷£&Òéj,C¸;¬ì°_Õû1 ü‡h[Nf¿·–ð‰·=Z‡oʵ½I¼žiïÌÖÔ³þL¾L†à&k9èÙæçês&ѳxÙj¿Ñ\¶¬äŠ®¥ImWÎm—Vξ|šÃù%%Vú¶´‚ü÷Kï„üYe!äþR~òîÊ~ •Ö—ÔëïäZÈyØiñþî{È-3ÀºÑÓ!¶Ú¿¬1©zHó¯àQB³µ_Ìã*Ç#®.°J‚J"¿ô:¿uY¢UÝ(ó¹Þ€®¼à×áYºí–oPÇÿIõøÔî\‘¿P“P^"jZt¸ÓuÜUZ?°[ÆÞ„ì†H!dK£›!õ@l2­%DòßÜé~c@ÚË#ÿ ²·Å>ÄMï­D¦ÿH\‰V±"w"ùRîeÔ²œüù ôÁJ·–L«ÜŽÞ—~-,¤v‘]éŸà•Ò–V¯²ëŒXw¦“<Êu™û«ÜBUsDå=üšsBkKýšUÞl ‘[»¾ñ~ØJo;³÷ÉÚɃèêöä`„Zþ òf¦–AìÙŒËS} úsª 2vez<"ñDæoJCœvdâM“ß“{:}±Ø÷ö«´ŒÅ²ß…yV+¥û¼òƒ|4“~‡ôVš÷¹oò)«Ó¹´c«};:sU®È~‰náfHÿž´zû5á'¸Ó-@ŠzÞ5mˆ¿üMîvBkµ¸ _Öu{â„-¼±HOw^F5>‘ÊwÇw1úÂú‹&×(O)«y$wpl¾M¼H €íe `·rÊš¤ H~o¯€œ·ã wbÎpþÑòu\ŒnŒÝÎEÕhªüdT 8MÄZPzèKÀ_„´ë*7#D/æ^ Ä™È8¤loï*ózäin¤9ˆa±¾øüÛ‹šÑ~üån‹…4Q·DÖ„kbωÒôOf”ªÉÚçÙšlnn¤QŰX+¨X”û&”ï¥/çt*çe(9i ºåÀI>œb–’[@§²XÞ&–uKL—ãS§D6y§à¯²|o+ÞTš R‰\(ß—½ Û;ó×…§0ôþäh.h†Pö Ôãb0"ìÊvuÈ¡¢?Èû•IÌ Ÿ„à5µ¡{•¬†ïÞ ü°OЧð]SÿCÉ+|%{¿“FÈÖÎë[Ÿˆ´ö{c±IaoÈÙ–;Û+g"bïéqÅpBšÆ&'0£Ã•>©ÓÏ­ˆ´ Êëqã<ÅŸü'ÿZª„ÑÌ1Š_ÿWÜ GÒâ8ó|jÛ3“Çžs}²1‡ îH Ä«å!^9}òS#!ñ{²2$RNÈ?Wñ*v¬oúc¬øµéÁܘ{sú4/Ǧ¦3/vM:Âͱ—ÂUž«¯Qš¦nmI¦*•DãÌþt÷e—RÃlf·Dñf¦»‚›mÑÿpg¥;CØßù¬—¼/ ùh2ÌXx+X7ÉšàÞ–éÉ¥àYç;2‘•b8ÕœóÙ ݷ.:Ê~,íñ Ö½ˆE…S¿]rvð:¨1Ø)ç/0 ø–½ÀBå;ðgIÌ–Vª÷*¼ Ξ¼<ô[Ìü•ûG^”»'·±Éº1úE^å~z«Hsò®?NèÒ^B%ÖYË—Á]cLq8r-P9ÒX})çD®DÈűåìŒÌCzU£÷àéwä,¡ÜžϧŠ2Þšä>ŸÅ¶ôA£*™’%‰³\QñlÕ-Ȥ—»Q~6ÀåVæmpavÞ!¸t$/—+Üåùsá⪼÷ø#uCÁZœ}?îO'—Šhj}åFÒЮj3HÌ3ç÷ :©wz„o)ÕÔæþ³ŒTǹ—!~}0”뽂WÂbˆT.‚&ƒñàß ÿFƶû;²Uð ØS•`Ý$—ƒn2I-ù.ËÈ 0D+t9^yA·à¨xE‰€ú„> ך§,ÃÈÖh•Œë‹X‹ªÕ©jln:æøT™<.+üŸãöadºûçµ)9ŒZ%˜¦Õã‚ÿ¯ú3Mü}ꤓ¹!‹Äk`×0z€[OÿÜ»­4ø¿ûÁ]¤6…²!Ѷ„N^4¢•ñ.¢ôŸÔµˆbÿÒ3H–¤¾AT—<ù5’ÿBÞðÔeÈ™]1gÓS!çõÌ4H\i¯„Ä[ñâËÓèQÏžÃÐè¬à+÷_mHôËÌ0Þ÷¯Èóa07#Øþ–L&r³û:ÑôÕ™= ¶v ·rV"™îu@hú‚ìãz`“}ôÍr¨ƒ ç_€Z;x Á!§Â+@­Êm Ͱ3È¯å¯ >#AØ¢5°A)ïR8 üݬó Q ü%â,øJÈÔí°YQ7ö”=Ä/_½ J¿Q0RÑï‘L´F¤²*ƒľ"Púź ¦æj¯8~ˆ¶F;uo¦SäG(7óî…Š÷ }H46À¥³9ÃáÒøª&”_¿ÎÈßEï~ Åû«´ƒ¢‰U7#/Ϊ< ôåJwÜßeoÁ¬mÚÍèBo§ƒK™4#”'¼¦ø±ÐÝ‹ùÖ æ¯n3¤ÑÑ{ a¼äzHý˜ûÂX—9‡ ŸQŸ#Œ»’ŒÚØ~•ÓÊ&媫Ü,¡všñä+—œ4޲Ë=HDt7惶$Ø ŠG”7SeVõg@Ø(v+®òªs;F¸A>NwQ):©ÊëÆót ˆŸ Ãî.ï.ý^Bù͸Ÿ8ÑøÍØ­Ô×kþŸóì7:|Ð’SR+Á¿Êû Â}¹5@v» ü‰Dõo0_æ[ºrŠo¼‘Öã,ök;¸|¨Mű0ü[µO¨êÔ2:!í¤u¼ÎzWDöƒØŸ4PCÉ"ã7H¯"ôÞ±º¤ÇKÐÕ¬8Tü}JnŒüËL÷Vcº¿%ÕWŒñ^.z2üÙ|ëTËÔÝŠU¥¬b3 Ìß3wâVß”®…žÓ7½Oò-Dô5'òв&ÄMÍ}rÐòú&/‚ÚÇ­‘B§X#ÝÝ`L³oí«€¹Õó@ÿØô'9 Ú[é@,?‚þ–Ö Ô!å%ŽSû€øRÔ‘+ iò‹àVð?!|2Þ Dž[ÙM~Ü1±Uh±}¬w&AÅ‚x}pºÇ*»T¼¬2dòBÞy„S™åÇCrSN–Ãå_çK¶|tnSÚ–Oá^þ%ÿ”ÕŽ?æ~”l"¦_jEŒó—þ`#W\‘w õ­ñÍ. ä7/¼-*y•W#•¸[ö³fŠ_Ã;ÌÁFû/ñEÞ1ûÐfeÐZ‹fjóœñ»3‰»"]³žù«×=o„sDnO/v„S ç½l?¤úžWŒ0+Ù„úh÷¯Arˆ™M`Frƒá&¿-' ê'á02æ³À¸Óý ò‰ù¨*] õßóL&Â÷É@b³”OÅAˆŒHªo6¢Í2­Ã— Òa£ è%ÎLð÷jAÄ•AÝ.×ñ0ð“ÛÅw´y=D®TÎ@üq±ì·µå^ÔÎ@¤- dþ°Žƒv‡V룮 p.ê¯ äk1È–Ö<ÚûoG_ãXN…ýØOGâù·yÿp@¿#l¢®H÷ˆÔŠ=’j(¾ ß÷ïæŒ?>8C-w¾<…“Ž+m¨}q¶±‡üà÷&ñ»*ÊíPðEê!¹Z Þ*ÇÒX9´G¨iïq¾ÑV{’Öºywr‡~•÷$ c¡—‡Ô7[or›;ŹͭúÞÐû1Ôk¼¹à&²w"Õ˜wG©éÔÅRï³O3I£Ôâf!J«+'”ªá)u3Giª|'N/ †³ËlÇV;+_Að èGuå~¹_,V¶3©,Wlð_²vqÔ›¤Ý ö8ó+pþŒlìõÑ(d>ŠŸ L!RåL…ŠOs7‘®¨“û§Êzæ_¢¸´Q¥¶ô)ù°Ê,î(~¹Ê>ºøvá7üsñ›Âïy¥¸S¥œÁ%¯ê.=â/ç܉߀ì™ZâIÜ3Ê845š~b·¥¿ƒØìà129RED#‘2‘/ìXU2¯ÐÖª£êáÛÖ Œ.«ŸhG쪜Q?³¤èÒb»-Ã•Üæüž}Ç©‰/ö£§FØ£ñb_‡/àd‡¸ÖõC¨÷„O€ÿ¡¿ŠJ5sÕáˆË9™mäe—:-¡rg«¢¿©O[#˜g—-¿•œ7Z ¨5Åx J\ûo(ÿ6ø œË¦C$:GœÂä áa°·J‰X}ô×À9 >³ÞóúWÎEc!sø™ÃyÖ¾h^]­¿#'y)Ya}©¹\+²WoomÑL+“XI$}ƒz–@û>wªº'eØ’»‚Ü€åBp«w-d{{o Äà0Dj¯Š䙯i;0rã¬ÒËÖlì‰Øÿ¤Qœ¿:Ó3Õ$1k/­ò‚UZ¼¾ÔÕó?.©•ž)Y„š_T® ån«ˆr2g]²6÷%ÞM:üœ3#=›Ó±UÙ#©gÇЭ ö ¨Ö&·6ª±Âë…¢o÷롨Ã?Aޱ\BІ"”;”d8Qy;¨«™Ù ßÛj<@hŽô¤Šýpt?Å™ ±Ïy ýW¼?¥jæ Å«X˜7­l^þ(R¥§*ýM¼¤ZÁö\Nç·ô·”žˆç'7§f«±KcÂix¾#­Q¾Ì†Ô¾òƒX5þÈUÅi sGÛ ê=ö_Á-‚ÐLŽÁ0¸|3x‰L d^¤üÂèëvÔ‚*2 *þ@&&dÎ r¬T /%+3.¾'ýeñÊnkV'^̦d“è ™*ö“ÚÙè„ì~:;µS 3±Ôp³ G²¿f>ÄÓvdßCŠö9T}­}([Ýw!½0½´ƒNDÐÚxÌéLH;wJp—­SþœãXø‘#h[ñ‡»C;$Àq&‚5A½äCnÂ3÷žèÅ‚JÆër(3<óeg¦Òœ5¯3îc§R(þÆûå7\"ŽÏµ™Šìç4N¼—¸Ä¹ªÏåláÚôg\”ãÆ±PõùªsQÒ‘²‘,ÖºYx#Ý ¨Ã™øƒ9#©–íýê/x¥‹UìBõZÐÛÇŽ?×¼ áî2^±,rÐ+š!´²*!D¥Ìd8'‚º-^ÛÃ&Þ ÞÉÔ÷Ï(×'ÍX&þ‰5Z-âùt–ºÈ¯ËI?×é½çŠÈ^áä‚v‡oBpOP ~ÂdB34G`–§ÌŸÁÛm©„iÃ=Jqù° E¥ TÄðl7Îó²þMÂAÁ„Þ²/ÂëEµ¯×g – £Ž¥¿¢þœø'g[­ÛÁ =Á›ÙÇÁz/ÑÔÚË„ú·æD"üôrŽ£oÈJ(V¡ZQé'5©-7?€@µóA¾¼@èM¶·UQõ×òM„úU΃åïó_âwÆFaš-Â×é½[ßVD:EN_ËñÜ-ˆë«ù\^3þëXD±PJFP\¥‘ÓˆôÌ$šÞ¾ÆõgoK½Îa{}Ù¤-ß”Û3SP¢{Ë~³ZêÄ>I.…Ä¡òYÈè´ì¿X9‡Ê^àϜə=ü’ø*[‡a ™žlÎÕ2)±F[Ž#d÷äh~ÍìH+”h29 6Ï´€äù´ êû)BY%ó2ŠýevDÞô?€@ͼ ™«ÝÞÈØÁËà|–)à\¦»3Ër©;‚5J%ÿ0W¤&:ã$Z{Ó *´špùž³’x¢]d‰œ”~°ø>(É«Ãcy£rºˆ«ã¯ÇÎÊוÝb…ÜÀßTð+ÍË5ôàlñºò x7ýræ)JJ÷Ÿë*ÚŸ´ŠêŠ3r6ðB2·ø°¨’î|®#ÛÍ•Ñ!ûNiÊ?Œí¼ê$µÃ|íOÑ'RU™”šQÞg½ò‚ÕÜ-ÆHñhG`QÜF8V.(íµÁOÇ—!äA÷.¿uxœ†šÂl·?VCãÃäuzûðL¥ñ£ƒ¸SÎÕNM¼Š{ò_Àðž,x¼Ÿ«š¶ã@e¬?¼Q %–:›Ê©•ÊŽåÜ,ójß\•ûÉužû(wFïu¯†Ìý^œû½é œ ™>—ψ ñÝ<òüšòzÌø—®…î/–1«•ÛüBÆ šŸò ¡ÑÓ Þê} Î"q ©¯–PD 0ÙOàAµ’iáF»£z"ׯ ÊíhþL9?ýµy„=ÕŽ‹'ð“³ÔW¨ˆ¼ÿÿ"g+ÅXìùoøg'—Ko£ æÑ°„óÞGr O»mŒ¬ô5ÚqÄ]9G±×IdèàT²ÆâûO™ß¢9ÕŒçvuíS‚ì ø3ÈOÕGM'MRû#Í rR½¬W J‡”Ÿ±¿¬5(£’º0ÕÌtùfˆ${XþäÛÁPïΔº:8Úç¨÷ˆö k_¸¨‚>X‰‚ºæÒô0¾u©º”–Ô~á à û ðªø@˽ÄDçAð;ȇA¾–ˆ¯e†#½ìνÿ)"te'p5·>¤" AhÏþŠp^2nÅ®x[Ö§fæh„a~Ù½üæ‚×EäòC•Fâ–î©t.<|É´¾LáTˆ«Š¯¦9VÜ8Ç´ð™:ÕYUµVÍ÷Ù›·2n1×ú$8n°bÚLïKýj÷’ÒNeãÓœ‚Ì|ZFòì'ù1{?¿ÅÈÅÕ·»"#O9×¢Fšgšƒ¶,[H #§"r¼¬DêÃìÙd̛ݦì2s‚t5G9(7Ú+X¬_–»˜eÄÜ{±õ+|Û´*áçdõÏ‚<ù’š´;Ê.bYP[®Vk]å­Êq?O:b…Ý:ü‚ŽF-î_è£å¶+[d9÷F/296ƒ$+àý!"R9“ýAhMÅñêÿ;Îÿç@3Iqúlm¯³Ùø@Ap—9Ýè%”sb5„#ZǪ( dײÎâaù×åƒtïʹ^é,k–Œûƒ ²¼›¤F®û‰: Ó`ÍçO¯¥9„{›ž¢^äõ ÒÙ–¬…H/²6‚Ö5Þ¬Šä*(ïyÕ’Âæ™±ø®“‹ªoŽî¥F4|Å¿éƒ÷Q©' Ì þ•[~·ú»·$9šáNŒ('Œãò\spp¦1Àÿäÿ)7¹§Ú¯ µ-€Ù ûkįvŸA¸Õ.¹ÂëúˆØÕ fó:8‰Ìpðÿ _ÅÒ€ó\0xQßɯ© W]È~Ï:°=Qþ9õ!pþUà‡ÈmÀ‘[@Yg!.ŒùPyWÎ@Ð\#?áWáLH®¯XÉne![­ü(øI·!½z©h俀Ñ-ð@Í ÁÜ,/õ&D>WºƒñšxÌ_•ï ~¿Y ‰Ú±=_ĕ¼×}ð*•$,ŒüƆ%ö%ŒˆÕ¸hòAÎ}[ð[ó¥ÌVq0r,u©Ä ô!b‘Ié5l‰ Ï6âb¼^êv¤õHö:ˆ}•C¼³ý ~äJ§-VÓ¶Q#ë³ÁºhŸ#4¯ñ¾G1Gy‚3ÖL§3)ãwg »ŒZö÷ük–ƒhg¼“™Ìµjx kõƒö­<§¾eL—ÇUÝÑÃöÊ^ÿDçÈkò¼rIŸòì1“Aγ²P¶ÏKS!2òœõ)•Éûo<Ž/žMíEË{°ø+ÈÑÙŽ_²—Zbм¬ž ´PþAU6Ra¿¨Gh7ªk!2K{Ý›¡õóvc †ð¾ÁDs*ò¹ûU•î“4 ¼`®¸7Þ9ºØPö«z>›ÖÀ¿„A`àžA%)ß‹ ¬SŸm{z?{AÿŒ½ ?‚h–|ŒC‘^ ffúAxøb(ß…Ï€°”¿@l‘/GXâ!ñ)„¹~(ËýÝ6L;ìò{à~¸”ý<Ù‚·ô«À>é·†ð1í,Dn¬Ô”‡s@þoñs´PãûÜcàTsç÷Mx?ˆÖoÏï ±‰Bë7½ ö¼²!à÷/¯¢Cò%Üä+åƒ1Ý)%íx"µÛÙÌää0¢x¶à1W$.\Ÿj`•ÅÛd~‰>gœ«È‰$«$ž„¼ïÊçANÓäÛ„‰.iƒ“± 黨›˜Íggä6û2wZ ݪìÞ€nìòŽÕ—ùK1ÔŠ 5Šú‘ü Ô—eÉU<é+¶¼ZI“ îמ ÔY¯N™wÖ¸š/¼êAe{¤Õ‡&ÙµÑû˜œ¾_ÃÝé7sº­˜óJÅ÷yÃø­ôxΪ }ù²DG ó¦õß8¬® Žè.j£ëšaõÈ?Unw?P/ª«m‹¿Çù'¶È™ÈE½»ó¡9ǘãßÛE(þ[þÝxÆþ“ä˜uýmu,k–óªûKp#ˆóVBì6â3—>ÿÌÞÿRÒácéQ6-µÄÙŸèÓc]³9¨‰Ñê›,Ž7í8‰=|Ø¢¿/›Ff$g;ej7ãýÔAŽä|›½ŽTâRƦmt­½‰ÑSÙ·‘æÛÙ…H«¦=Ó,vs ÖÃn êÏÎA°ZzÛÁêämó†l.ˆoå °Îe]Pj(Bn³ì`’rŒ{‚ë@ía¯ÙUœåy ÔžòàõAŒg*Èj9È a{#áLðtåIŸˆ<Üé×½W´„»¨ö$cèŸêwíècAÉšÛÕÖ\"U@éí4GƒÝŸÁYû 9!O2,¸Vlã–Ì'jWp»iŸ*ï§o7úê™E$UK Æ=DÂgÂûpÊv2žÒâ9Œ Vñ|ƪoÔ¼?èVI«1¿d®5'÷RfIì¨2%Õ þ:}ÒÛbùýÙ,à„[aÜÂ2w´ù$Mœãjº«ôûnc?¹î9s÷ec¦û³ù%Š{Îê‹â¼”ýËZåıç8øÌªí Ó]½·8£5nÑ^Tï ¯@(¯R »B³¸…&òÖËãÆã «j{©ä·Ð–o)pâf÷GëaÂlËÈëd³ç¢uÉf¾O\IEꑸ\Ÿ»Œï+”Ü:,-<ÿ:—–VÞÁØâ®UÑ©ø‡Â'ùób—ª+Ñ/N­¢‡+.íÈi˜ÞRþþÌÅÿfèÒ>q¯ÒIì=½W½’ÛJ'™íqSßè1ôÔ¢ô›óÎÜbTÚSçÿöA–Š*Ê–L9ûÄÙòº\T®¸›ã±†eSði˜¬C¾z"ÕbñÔZˆßQ1 ¿PñÄÿ±?†Ü?S?ãÅoÏŒCO ­8ÀÍÑÇíŸ_îÞÏîØ$ûépžÙ4¨éÞ¨êrCö%^EÙ¥LõßÌΡžÞÆ9Èqå»+ËšÙ‡@rþB1ñß}ƒ7Ãéè= Þû"¦:0øÕßòŸ  âB}ïizy÷A¥Fæ¿1JïËùÞ— ¾ £ÀB¾åí¡äm1JÊ”»@ߢÕ5nÿ9ýx_©«Aé¡ýéjÊ%DP¨å‚~õqo³Ö üeúLË­¾(ÊD«/ˆBKç‡òá‘WTŠ-÷~á×Ò&±sº(¿ßHLJÇ=Ñ‚1é G乫 ½ÕÞ(Îrw5è?9qZð ˆk•å äéÁïfÔÆô.DgR‘úÞ?ÎÌä}L·1dŸä%HÎWžÓŽŸšÖΫ¦Ž*o™»!÷Hùë5®ÍŸ;‘9í˜Z¯¾;‘<@íÜ·Êoä眛*AbNúuj'Km…Ø‘ì yÕ~¬_`Ìòžã¸_´]áP…Ý@|,ÞÙK\á9Õƒð_­+ø—ÍYàl0»‚ýp´!ØË"!³<ñu“cr>á»òksoŠ{sÖò|òRb¢—WñNô‹L›ìJ«zùûOe[ñ‡áœ9_ŸÑä]hÉxF;1ýezF‰L`z婱3¤"ÍSy`NO¾EÛèdã)6Åž6ÿ¤6Ê}èûŸÈï*ÆT\ A·²– ®H½…Ç*æ¢ZÏ”ñiê_0¦^!ˆgS.Zìžr›Ù‰ueßq8ç7ûcvå4to®Š _Oý(¾·~M'©UòNÒ§«~SºKÕéOè ËìÀÁÊôÂfdç ¸3s È?ìþ ªe_­©³¼ÅÙ¯‘œq'!ÔÀ­B&ˆÚïs4lŸYHÜø\>Äj±ÕÏ¡¸>XG±=?{ï‹-r¨¬—j®ç™Œòð;#äȧo=ׯÛ{‘« 7æÕå;çE;)Oú3ý¿ä1_Ù$îÕ&¨“ÅBå]‘–CRÕ/+ë+½¥ÄãodzÊ4£½÷¥²¢¸å‘ÉÊ1PÝ$þ¦­Îê?Rõ‚ Ñâ?ç5 ÈQnPä P›Ð\é«G˜¹»<47[‚Ë ~?«=xõÓï ¨×&Æ‚×Ò}Ý«pà®  sÂ×Ñ‚7å×Ô –©¦8¥¿Ë4Ìâ¤=ÎS‘™Jþ—‘p@xŽ_@RÇB0Jéa‘oP+¾pk`—–géQr»ò;GÊ~0~ckÙqeF°.½œ¢ WdvË ¹PvC©¸R–þ ø·æL…Y]E^]ø%X?F^B5oÝD >˜]K¨7ˆ˜ø{²=lE\9«¶µXi”m²}Õä \q©²%£SPÄ'ú×8bšY­z ¹£A>Š{*UÕûãÄFÞÙoámåƒ9£ Õ§ð´þ³:Ëí.”œåÙ¥m|!É«b÷gü— ù>\6¨«Ȩ̀JUÕè~;k2~ÎÓÎ5ÈDÐÒ×¥¶!â_%%SÖ´üŠ  .ÿL½¼5^´¤ÜG.L_àžèÓÙVìÊY’™äw‰ô—‰d1.lPñ%÷¦*#µ¾©}¤:áûÍÒMÑ|=ù eƒèé,E‘ã3¨Ùå¶Ó‹Á‹¤ƒ¹Êû ‘YeßêWc£rÄ›ƒÖ̾ÄÓR÷º3]Y\Öª*UÂõ©D¸4Ìß Þù¿÷—á[mû?ü™Ug~;éi锋PAQB”P@BlEE@QBDDEDRB:¤»ëÛqö¹bþ/ëö~îûúý.ÿÏölÏñbmk[g̬™}ŽÙýX3Ëz¨´Uh¨Ý^þ*ûÙqã'刵ÎÉ5GñLn»œ49Ã~À&ۈǸ_fRªb#t^ŒÍa~G•ï=ÝAõ •[¨ÎËës­¢ÚOKÓzªOÙƒWôQfiÑDå1s ÏŠ~šÏ³’Oí3º‹±Öb}=oÑÞÓ…ŠöoFšSÎÝ¡îñÏ»Œû=°«GÝb‡Áêã{¨ïl§µó%Ø;™?¤(‰6Jd¾¶×ý8þJÏÒŽÅîb¬RÑ®HŒ–iq‰Ãæh°G80?͆’ÊAÑ‹ê×PòŠ~òg¹;aå1^¥œÿáØ{Ü[çÝÒï”åòb¦=ÔÜ/cî¦kˬ‰õ¢“x9¾€2ê^çu¡{C¦‹jJsó(hïÙk@/o Ì‰U>Ð6‚÷íh˜KΠ¥hÕÁuÄiNÌIÛ/¥,&Èí"„×°5q UùØõ>¨gìw ÒQþ± îk(©‹ä¬H=ˆên(ú“ÓÒÓ µ Ê,¾ü3þo}!?Ö²ò;CêkeE=ë°'Èt{€`õu@±N©’?cý—h¯¯v"åy'þšÞ}ÕPÑcã¼Ï#¢ÏsÀxØý ¸§¸úC ¼¯¨Ib;™Û Ð ¤€Uµp1سŠ‚½>ò¨vp;Ãs΃¦Ç&‚çî@©œå¹_ýD8î’À»Œ>âœ6$4›ž¡e!7> ãÈð7 ŒŠ¤@dk¤&ŠŽô5)¾ ´œøˆNÎîŠýf½èUð¾£Tkgô(‡JOÚeÀÚjvëó.(.i‰º7ÔŽÚ§=o‘Üx0ž5ƒû˜» D¦Ét~¤nu+ìuÊI(:ûâ×Õ—A>åÚâýÀÑÝÁ~ÄìVŠ™ò <NŠÚÛ~VßIÈÞãù‚M¥ä“yYݨO(oF·Èg”µwœ¾â¦®:ï‰Ä`GÙ•ââ^N+^pO“O²–÷Ïr½1ØÝˆÖ̲®ÊÃì/ì­Œãºcˆ\ žc7]c•%òno‚hG¨ð¸:ÑYi~¬RÞù§þ߬ÛB¡lPpZdù0GÌŽ<¨ÍᲨ<§UwÕ×ÊPxm¤bt}¡Oq=§lV}¬QNk™ÎûÅ#•îVõ~ÑÜ*gdp_|¼çI&G˨ ¢#]wà‹¶tã-r/¢¬·VaOíð,u¥¿”;|€ú”7†¢%{Ã\Öˆê.ï9n°"Ö–LÆFŸ!Ïü*aS*ü¤?Móx¢r‰Ã¹m”ñDÒzÓ„ >Úú‚íó¼´µk£¨ScâD ½„T¦DŸ@QöEã íV¥et9hï›çÁ®ˆ÷ˆ?À¾#Ø x ?¨Ã¢3AmîLë¦ò$È|}(=bƒÝ(öØ+ ä"­äp×^'µ÷À¾hNë-jƒiW >ËŽAt‹çD¬¶Ç„ÈoFÌð)ÿQB¡uþµÜ vM˜D8øRÒÌ+–øÍJ6§Ìf[Ñ’´ÍÌ*ˆ¥Mž‚N© äÍ þâPÇ@MåH~Oñ0› ˸?äYûÑô˜œ¸®Úö¥,Hú–ž‘î²¥ûRð§ØX}ž÷­pCôüP?R·„[ÒÛÿløZxêDËr ñµpm,w¹ðlÏϱEèþ¯"ÕžŽ¡ #ÛüÇ—NÌ}=rÅØúiÔ²Çàò8ÑÏ8åZžÏÝÆgVʹVÊÚ,×ï¿á„ÕI²³sMíáâU¥·/.Ê#VYNÉûìÝT`‘•Mbð¢uÝ;^zÉw}+gBp´¥‘/‚Î=è¾»Esnˆ~r‡¤—°QD;„ˆŠþøJR훤:wUjÃ] Áÿ‰ó»SÌ j¼×£ðu¶ÿ:,4„kúxµˆ†2A<ÈQÇTÇ‘¬4RÞ ’üL[ÊΨ¦Vç9e¶…ÑJ ÝGžs\ͳŸ7ʉ­õžböÆ×«¹\¦cTd¡ÿyŒècžwa¡F„g¹[@`Tâ÷Þîÿ‚[¼¯Béo WCéX;dñØäˆ¢Î‰ÎçyS> ÙÍÝÉ“åù¢'¼¹Q3åb~¹Àzå¯õÅSð´R®ß¹= Æw•·ƒ«¾÷;0Öoƒ^Å» èè|¢˜½ êð8‡œ­à<îL†hÁÞb¿ñ¢A–3b G©ËÀŠ86˜g•Ù`5”µÁl¦ôk¢’æ µ%D«[SÁk&?î]~ ê€qÆõ!¨óÕª`fk\¬˜Y³@$égI¢ „Ë…£|/Aì%+J¯–zÀ©„¡pWáQtL‡È´àlˆn,ª¾VÊìI(‚´z®ÁrBùR…øR.* ¤4ÐF “[¸Ó‰'­uæq9)Wœ`kb­žùµ{±Û.y?,í*} [C?ˆ)¥sÂס²ÈÄŽÁ×±¼Ù‘ñèICƒ'ê žƒÑVàÛ‰¯EXϱ àEáW‘®¹±¦¬sEb> \™IW7ë}ÖõÎ*u«[s6(gíw-„¦ ·ºQÁyÖ^@ƒøæb*ù¼òiˆW²¿çP¼¬ó2A5×ñ“ÎçCüIùÊ:‚?œ*ÿ÷ê*Ç9÷€±àìÙð9,ê|c\®¦$²_¼âNÑœÚâ8”­`WË!ö‘:¬¶j_ˆõ22ÁþÈ• ±Ú~ãz¢§<ÝÑJž¥ˆP†;Ÿ’Àýþ!47÷‡y/'Ãx!Þ‰—΋ÞÀ,M0–£ 7…Â{9 %SD]Я{‚ëIm:¨‘Ø ªrè{º„úƒè g€ÉlàSk-È*¤ƒ,K 8*.°[ç²è±ªR€ý®Ò ì<µ˜­Ü¹`>æÔ=3ý}À2V«rê Gkqà­ÄõpZ+Ó€}ƈ}}D+׈´èo¸¿÷0£È%ñ*à5¼ßÍ<w;c@_ã{Ø('‚”±ŽÄí­%í1œY…U”Ÿóñ•û@IRîvâÓä—bÙNYGóÓ˜ßÓDoºCOô½üBé›P-4˜ÿ™àv\þp¸ø‹´OõèqðŒ ×Ö~ÐÚ˜AŸn‡A­*^ž‚²úØÍ´ßÀzAoæó®šíévAt£w>„[ø–@¸‡/ Á¶þs|"ác+5x·÷`ìçˆn<*2¿vìKïB¦©å“x/ºËñž·ªÑÄ^nÔò,‰äò¬ìnÌ0ïÉÈo\Oì߯ZíK\{%ú%†ö¼YË›[‹¢c¹P\Ǭ5 ½hßýDd.ع¢=¸‡ã5¿Rtðô埬øË®­û³,XÓñg(×7c<$Ž·NCÒ7ÊnHþØx+a—L$’x“Cœô¿fu°çøÞñT ?(V%êÁZx‡…61̸ÎàÞÄáFù> ÿBÔ;;2Ãwoô.ϘèŸà Æ»‚g`h0hÍÌ*à͈>úãæ0º:mÁÝ8 (YÖu0þ`/裟‚r·|ÔÊÐ×…ßVÇîçI.Òι¢X™L’m@þd-{º[–ú—ƒP#!ÖÝ Vu1¬iz5ˆ уù„«9ćëiyÍu¢YF:„†x{BøKW”âk¡Ïü5‘¥­}Iˆ¢ Iç¸(õ÷`Wîñ”z<j‘œÊÔœî®r¡çCåÉ-Ø/ºP&ÿ²/§»!g;ƒ–lñ6ï u5!#í>5‹™™÷ÄÇÐ<«aä¹>c—ùUt~Šß˜_‚qoÒãùçEÓŒœü(dÌÏ2*Î…Ô‹EÓ!åéÒʘPº•ÒĹó\Iú‘$ßð)NxïŽ$§BÔM·+¤ØuؼA²ÞÜþš§Ô©vœêiû-^TaWùLìCÊjÊœòj WœÃêP|æ7®ê¬7·Mh=áyOôKÏIbáGý:•Bký/’Ü–” ¥fRK(n–ú¼›¾ò¿ÉÌ (¯ ÃERþëé•—3yXôÉâ®ÎùbcÅwW¶:‰ì¾ð¾R‘ß/är7®~äÍâŒN(ü 9ΡZùBè,Ùž‰ñ+œ¶¾­"Ñînúƒ±a Qœ"»&m³? TPO8VútÇ¿-j"ÎÙ¯•^¡¥·W¸ ?–N@%ð€{x4ä}Áý`¦”rBðˆã‘sàþ1¾ôÁö2ˆw+ý•|qgô$éê*3 äêxO(CíÃöNg‡“D-²âµÍ‹fC³£±ÔXb?®ŸÓÏXwD§G§˜›õAz_ç}WEW†óîMn&šø¿óÀ ××NQAŽ£x“Ôç §9#Æ”¾_ú¡3Ãý{¶ºÆµÃuP;œ|Yù¬PŠ"OÿÊ.o»õ—ŒÆÝ®q‘ná3Æa9JÙ ÷Ö^ô.uìiúPŽ„»‹uÌä3og¤lïÛî|ç- 2ê[r;„ãî1 W'•Y1i9™\ÌêI­ÀêžÚ3Ò0ícFãJ_Ál×PN|qÆEq#·IæóÜ—çËÚ€+÷íÌ<”œNY{ grvnÔ+³®'—ñBÎä¬Ã½Ë» ÊUwŽ!k‹^F(h!qõxu¤7Ó܄ˌegìuÐ[ZIàyÔ¾€i¤Fn ;›Uàþ=% -OSåÙxÈíkðTŽî{{d?X¯σk¶ñ4èJò$§A4Sú€sÁž¶_ f¢¹âc’~×% ì:Ñ• 'ÿú>ç'ˆÓ~óXz?Hðv= ÷l[@DþsüŸhd¥Òøµ'ƒ>*¹ÏhŸ0ª(_}€#OŸÆ6­³ºÛ Ǿošo$—RÇ|Q›±•¹ˆhy·†-ã±9ÍSÎB¨¶7Ì‘®îWpB’Ö¢ÄM÷Píp %³£!·Æ•p®å™Kc¡Ì¡k_CÒÃE7!µn´vº(ú5ykQ-ygâ*±¦$‰{ì›Å_2H?YšÃÿ=ák$ƾ L@ª‚çæöÀ] Æø –‹>ñpð$(_D'‚Ö; Äs±) t°*ƒ9?’êJ§ ȸ vûØÐ?U†‚H—Í@éMGÈmY(!ö‰Ù’lÿHú"A‡ÈkDïrÞÇ+æñ¢·Dî“€ô®‡ÒAò5ðìKò%÷aˆl4šƒ¾ØŸòA_8Å Q0ûSÁ©Ÿ¸ Ä””·ü”_1å¤4®ßŸð™5,}« &¤oaPþÕÌÙœÌí–ùNîËÙSP®/(»®Ž®P®¯.û!„‹“.@æ!ë” †_ÿs‘†à1ƒïƒ±36^3¿…È4÷›‘z(îãÑ™ìp=oCmwNti®Ñá;ÀuÁ:‡ånoþ‰j|*;!Ü‹Cmˆ«Ä;›Ôæj{ç)5ÕòZ«¸ ÝcÀQÞ7°(Pb-$!ù€3œO‹š79ã?,âªëMy€Ói^%¤t•IöÕPûp%Ößy—˱7åÛTQ*IQwjuHL™§¬'æ<©|‰Qp8†ð Žçþ¿d¶eoÒQ„ï?Çÿi=øLwÎ"xi¹ù !ß\Ý!]m©ósIoáÐ/m”+‹kÅ?(Õ¸êdÌ SÔ6–ðCx˜±“mj¾1•/\ÝV2}Xu[/»÷r9v)©½¢O¹GòLtºq‘ ¡Ÿ]i¤EóÔ"+tÜý2êÍ@„žò.€’‰…=à.Á,Ô=ÞçBÞÂÄ-Èà’¤XÁwýÓÑ g95 \þªø ˜Z<ŸÊ©‹¯`%‡Ka'Î œaoB¨ô(É C­©ç¿üÇ·7Ò Å;&œÞÚ‘#à¾?:Ü5c•ÁU7þÅæ0Þ1û‚~Ùz´rÎW Þ°ƒÈ°ËxU\1B¹ò¸2äÊ÷`Q–‚=Hÿ¬ºúrˆ·vÕø ×fœØ÷(Ñ|Ïwü1|QJCIþ̓M.\Ú?±Jé/Ém øŽÔýPx5µpAí´¯ñ¶Mžf/Îñ½júS¬¾9M>G¤à[ß~–û²gÊ»~ÍX-ì¤Tw&ÏûÍj,õßaÛæ"£[Ò¡Éx<õ‚§ø)éñp †&¿š„æin§‰gBâ¾Çƒ÷ÊX]ÿóá$ï H}ÏÀȯ(žš1Á&ï@6ÍÜmCàΈÀ{]YžY%#Á¸©¾‡ÛhfÍÑ~su²*ˆÒøóñتˆOá.9Ìz˜b„¹™#æ‡ñ¾D5·5zêÇve9½ì"b†)¿bEà~óò<»å|\îšâŽe¯A”4µ†¢Ù­ÑZ´q¯X\GÁÿˆzæWK?‹žtQ_ò¿áüßg…¯ógâJ‡N(:J²y]mJ±9€?©jvPV³PÓ¸¨ÒV’Y£~Ë^ÿ>׆Né+Ù«`<¤’õÜËÔ®vØõ”1ŽVÂÑÊ¥wmp ‰Ôéê3زGbÍ9êºñ‡S š”8äï*ˆ}”–ÎwVS(m("JW¸*ãôl£LÑeæR‰‰Î™b¼á>îN­äíñÄ“ÌS?#^X_ W¨H(´ÖSeJ±¢~bgÊ …á“”'üœ¸Š&™@ÁÓyoÄšK@_tÝÁ¸µQÕd%!ºÔë¬ñ€8 VÈm( úa‚üIàWc98Õ”ãàÔR¿㥴r ¼gLßÏe¿ã ÏQsÌ™ ’åEÒ9 r²À®e g‡Ý4ÅÛ âÇ´oÀliz§´<°‡¿ÚÈHOÐO©5ÁÙŸ\»“ê€þ²> Ì•gŸ~—O‚ZÓð"”Öâ+14a<œXòŠ­…N9v…>1˶‰…w*—”ŸŠ?ötvýPãÁ¯NÓ½±è¤ó”ç'0_×2©«¯>¥æÅ6*w¹Ç+?é÷›­ÅNõ)k„pý­ß™¥ösV‰‡D ªd‰8ÆM6ÐS~*;ª^évÆè½äbsˆ>ÏdÖ5âvëx‰k‚}:þ¦‘c½fßtÕÎ ¬œ¯æ"U,¢sp’¨9 xË÷öÉióäiV&®ºžL×Oê"»­QŸ²¡§ÈMz$ô'U|G"Ǹâ|ZA<ö\d x~޾‚‘¤Eû€;=„æ ´VB¤X`Pìmˆ—šÍ@¯æ\×YkD­XM¾•% ¡¦\ \ÿ‡èÿ—É£Ö°Ï5žuUb]AôŽb©Ù®„«¢û[ÂîIâIg¾»v)2A ’o0ÞØ8Æt½_è8k½ crAi/0‹äàï„'‚ع´œÈ# – me«Ó|S‚o‚zÞÚÞ`4úU³¸nZ¥H½Ž¸Ží²ò¿Dc¾×Õ¸b_i"ˆeFSí©Äûú*e*ª¸&;c•^@Óhœ»ÂçÁ<*G‚Õ‚ûÁŠx_w˜£{Òuø@}l´`ýn|vMW8={±â>«Dzƒè3b"²t¢zQ0ÉÝ“HÉ'™w‹Sõ¯¿çÎÃùÓåæ‘H]¾l¢/{‹Ü²,â1œâ]êM’2gáÏ|³l}≗³ër]ÜCô-h*oœ;‘ÓO„/O¿Yß³?Å Nö~£0'ë•”)¡‘Þç.\+™£òï(®¥%_œ¤HŠ—Lâ‹äEsp§˜'¨“¸¹ä"aN¸/~ߨp˜˜ïÛÈð‰. Ñ8¿Œ +ÌD£¶ý)ŠGS)n¢Ê<Õ Î¯z?’­=ÆPˆÎ÷T [ìMÏÏTŒôô¾Šjéï ¡îɃqŠßMüJ/¤ÜKAQ,劬P”žÒߪ]r1éØÍ¢¯’–—Œ+­¦-Í9F Û¯ü†Ãž‹£ÈbΕ­h ¿º‹^E󜌎^f5†ò)§ˆû6„ÞF£q¨5Šò2ÇAm%ú1À{x†…TÿÇðOZØã¡ôs,R¼»a_ ¿±/Â#x ÊÜàЂQ¥¸(É>¸\Ÿ?JØóBñd>÷¸B* ¼;(iÆîè¦À›\sß\Ižòc°™že‘O¸Yp(4ÄàЃHûëP „kv|&ÈXô90Çÿçíhwõâ; hTð"$,ÛÀLŽ-ÛÙ ñ ±š`=óCêÏž‰éJ…­›±²ˆÏä2䚀ÝSÎïi÷HH=žò1\ú>ï8P u×(o¸¹Úü¼­üe ¸¤¸-8oº‚³ÐUØå] r®§èâ{äLû+°¿!ÍÚ%ÞÇ DÔ\ã]}5ÅçÎ`N'd;®LFÚ÷¦WDÄ»j_A8ͽB “êBø׳¸àmÅu(ê“RÓyãÓ“˜t³Rêl»OA-=¥pª}‘+7ŠéFúµ‰¬ãµ ÀÍ1€}m/»ñ·¤EIŠ/Ebú±][–|QÖ֬ıñîgõøÕ’ºà]Î2p·p'¿c•ùDà#¼ò2ð²|œÉ¯ ŠŒçEˆøB™€ 6ZÝœ-žÈ~,˜‡`zÑO@Vq7Ñ–+¶’GRI_ùVó12µŠ³Š9™w‘ô „Ôàºû+ÏüØ8¤÷ëX9TÃ5.Xûô+´‘KÍ òú…›pÏÿ êÿÝ„œ#¶×>²~Ï…’ °>É9f¯â$P sãbñ&ð©qMæ•|O­SàªüÞø4¬†ïWðï ì#OYW²„߬aEIø½ÃKŸÄT ÔÄKKö¡ˆ¥Àú£ôwÐsC_€öix¨7Ã{A¼©Ú±è(h[2h‰ð½ûy§XŽc…µÒI‡/Ì?âÃã¯ÅzªßhKb£í/ìŸcj¹ÚNóW1\¤[­ä£Ò6C±š±$k•þ½>Êéåíï}Ae<8zþ€üÌj¢œ8&kxkx[(Ûb3chf.7Çñvº–þ§Ñðúo×?¤Ø²,U;aþ`ÎVŽã7ýZdod¯&üŠßçêŽEšéyщ‘-îþî ®Fžßb+ì{õ âGÏ7âZp)Ô§'Õ#ÅùÜ×â)î"°Ç'< VSKPâ©À^¼dݤv@²Ý(Ö6"Àî àÜÃàÕe<ÛÄžx²Ý›£A¯o<õJ¾UBá9}*äxŸGÞ¼žxqýŽÔÁ¹6"k./Üüªl_´kƒ2¾³nVJ¬ìnOR6A#¹ô4óÿá È…Às9/‚Ͼ"ÁUâ9 Špoññ=„Í„®½\I†›#”¶P4ž ÆcŵAë“çý¹ÒVàÕ®ÞÏióëÜ÷¨(»ÇsísY­Ë(m,÷'è­W+þÛ:X$Qµ%;Áy¶èeE¥íA½è®Ìè~ÐSB#ÁP’ J‡ÐZ,-!f ±8ô {ØÛ&7‹“VGëN»‚ùiô.ã¤{`¬½ØÂO± xèSŒFÄ|½ølñòè" 'K¦ÉëæƒæMs»µÇ{Ä›Gkm¾6ÇÉ8¯œ¿'–›;íDéD[1Mlq…+4Ë:œµÓ}9<-2j§6á_.U­ž× 6ÈûÈHâ»ÀʄЬÍôÓJo *Þ*"™c¬ç(x ¸<ÌÉJqº ¥û6çöóNàáëƒÌkÛÓ:¢\} ÌSpíò@Þû™õ¡(’,À—ådCÃ9aH~$pͰNc& ˆÕEõ¤DÛ êc"aâÆ(ó'tï k-ÂÝ*ò(%ÑŽèÚ~e9øÊÆ€’âä‚áÖ§‚q<¯GƒÒ-–Î+ž³àéÂ0PÛ °¢SÁî©l1Q ·›‡ÀyÌUD³ôJ`,r°_8?¦opY;ŠÙ|€IDATþ³—^†ðOž²à¹¡<‘eálð6‘5.ÿ”ÿ›cµ8{èz.Ñ3‡åIÖ§60î•]‹®CDÍè ®”ï"×zWùKߺܮR}ž¾Öó‹{€ZÛÊRÏ+JøEw "ûüßQÃ5À³×CøvakõŒ?PJrA|nÂ}à~)±’z¿€.p}MLB¼·£@™Kñs@^ÎBTíÕ‚TÐ6ZcàêD’ö‰k*QåæSÙYÊÝ%Dß`/­CÝ1¡ä Dâ¥UJš„Z˜:@¨;p8Ô 1Ôxì½Å7AÍU¯Ý/ܨYútOèÆ+À{r4èo+ß–ª\„À…â^PX’÷ XC‚÷&t*xÂÀâ¼_¥ W+ Iè 1äA»  h G–ÐÞpABâרšÊ9IZ;9ô”&æTùG†·ù7³;ÇNƒ¯?ý-'oì¬ðòò å'£\«Váܬ–]Š:$w­’ò Tÿâú4H7д'"!p¯ ÖïãÑ.Ø'ôx³KÝàé‚å=ùÃ÷iô Þòn³šò¸§Jh7“ÜÕ¹ê\2v”¾àÜ­‡´¯Ì¥šÞj=#†ºÇ-PÎÄ·ƒH‰e1ÍYŸ$;w˜}DXäÚ xÃí¶[zñ’y‰ó O:I¹øªù=eÄëöQœÄ÷•ªhîDltù˜Sçæ»"5ý×Õc(¾lµf¼ŽLDò˜2ŸøùÕ²!Ò®#˜©ÍŒ?qΗÊ{8{1u86èÿÿ¡¢è¸tøâü‰Òý'þ¢j¶Î*5“Þj½>ñkÕ”'‘ž%n …£µ¯ˆpÅHçqW¦{2££ Œt*9ëž&ÎÐÆS_?PzÙ½L?˜{ToåNtmTÒ#Û,ÔdR*ŠÑÝgó¦ZÑ-0D¾gÈ@ §Ï‚ø¹äèžU‘û‘‘ž)^Lík;CüfA[8;¡dTê)öÙ?d5–K ªy§soñbïË¢SÒ _-O{?¤(¥®ç–'¾ø™±þ¥î<Ê%ÄŸáxyÆ¢xG„§÷×èipWíWíØZpÍ3ïýW«"èm,¨åU 4uÖ‚¡p˜™ÀgÊpí•M`wÕæ€õ¨¾ÌsÆ ¿êñîÆà= ás¾5ªâ߬–´Ÿj¥5{Z²9e1vÑÔä ‹ë¥4·•þ˜0;^?°&¡V8®?[¤*ä4N×àÜg½çŸ.Ê¥.-ç¢Eú(}¢íXú*_&n.}ÛÑ}AÎDjNö’WÉžÀ×4ô>ª®ÒÀ.>ÔNáñ¸‚=±\ëBŸ¢zj>Gõ¯Ž†„·Â_C§ϱ=ñ(¾"fùú˜÷ò·yø%Žº{„§:«]ícõmMŸ)™iÊ÷fA´6¦ïjtMK®Gvð»û¨5‘çœ^ñÖ,–µâ³8«40ûSIûÄ à6·˜£QXm/c©}ؼ”+ò ¸OÉ2dä=Më¤ý$õ×:€·ò3ȶò*°‰© îY`vg!\ÿ)V Ýú¦Ñ âü/û þ[R$M¬Æ&­=®VcŒë câ#\ÅÝì ×U—“à¬]"=X–™8Þ4ÕC$tÌ)âsW{Y+vÊñSà´0+ñ¢õ‘ÒOÌwÍÕ¸“ìI¢øÙh¢Vâ3 >¦¾ Zž¯éîáà®âÊïb¿ü=¼~Ì’A‰'Ðó^‡Àäd¢¸G’J6ûÊ@á;®²æ=H·[9¿°YÝFSðÌ¿b§¿è ¡VT«µÏì„·Áþ¦t¸¦%.ñ½öÞà.P§¸7ò™^È–} ˜ïÁùL| öË‘: Ìpw9P9 ¶ãür½hö>{ˆøœW”#à´ÌYŒ«½i‚s§]\ºw¨ŠºÌ™¡Ï â-l ʯ®à©ž6ÄAeXZü<„Û—‚üU4íÇ;§Cxtép`‚û.ˆï‰-Qàþ[ƒçÀ)§u„Ú£¼%Áæ ¡tì…i´Æ‰BòU¥¤¯õnƒ„ëvoHHˆA¢¥îã¦7¢w`°k¸ZÝ-&hkœú² ¯x$»ªk#ýýÆÖSâ:’ÒHºÔ·sÃý›‘ã)ô~Ç/¾«Ñ‹r¬{x¬&›|N¬‘xß½6V›7¼Ý¬/Is¿UºœÊÆ8«.¸ÖQM6v}íêÜ¡NTÊ™?ó§¿F/#b¾Á4·óùÝ9çtâKyú$Ç-ù6Qµ­ià~\+‡øÜy ´ä}àv”/A¼/×€óô¯‹V Êc àú3@Cý õ|òVˆ¬[€@|DfÊ]`Öu7¥§QÄRû~(]å.ÿ=¬'ôŽ­ì™Ñ'\3 Zâݑ߽ãÊ|Æ7šüð'ÞÖœ n÷ûä}áµjJl¬9{"E!?ÄT$ÌÆ”[ò h#@Ÿô…ÜêeÕŸKÊîMUõku·c©ãôêññø½ÏÆÿà¦Ú9¦‚òF¸'Q{Z¸ŽRëFÄë ¾KL}6:ÇH íAÑê…ÿ ¨/!ênaþúg±Sài8A©vØ”DŒ@ÄE\ßa.&hôˆe ªkÉ,×ÚÐÏòkµaü%–+¿)»Ä‹ÚÖÒ…,O]_›ŠvmT¾“)'Ê_H•û´|ÒÄÛ‰ï¡è+•?@i{0b'Á¼ Þ â!_¶S vaBpªÐìTÝ;í¡_ ?ÄÞUÒ!:Ê5"Ý|ó±ÓI «(Éá·Ø©kDÚ¥^ VèÇ„ ± Îb‘[XKÿíæbqœóéOAø¤/Š˜Rn ŠfÆ$ÐL;‚!„rˆËý%7q²Ô"[M,óOŠû*W“;"•ƒ_‹G¯;#ÚçŒ+Šù³Ü Šcþ×ýÕã˵÷‹’Ì3FŸÜû¢•ŒeÚÌH;}’Ö7ü¡þ‚/9|NéI ÏRz×GƉ»¼G¾µ\Ùñ-ℱÇlH£µÕƒ´©v„'•Æäɵυ·zÿ°¾ˆ~é}$öU¨—g\ìtDñ¬ Þ–º¯¤ª5šÓ9+ø”¬Üæ®dç×Îú@ö.Xå»@úÍÇÄ¢Çѱô/}ÅÊ£6ÊêòØLÐÛÛ04e1Fl¸õ3ˆµÖPàOf‚ºB<Ä€œ(–àü¿Á>(ÃÁ¥xºAýå‰õv{§/¤J‚Ôf|ÞJ¤êžHkž0 _Iè ‰_î#”ðmÙø•gˆ÷ÛðBg¤1A>lg¾1P¾bÏç8lt×wû0¶•“ZŠËMXÙ*ýc¼þ)æøpiÊ"£> Ž+6¤æžêx+ŒÒ”–/™ú³òŽ‹_1KÖEQ7JDî‹Îí»Ô…à™®Õqu@n=AdÉ:€G9 æZûuˆÕ¶“!ŠÝ57eoó´Ì+IYú#.œýú6Oè€ÏŒ­à 6¶€9JïÎz×›àlò| ÑýîÁîå©ÚSþ¹(ÎfïûØÊVÏûœ6רÛ9îmrxÊ—õþäÅH—<Ç·=¥6ªùxÊ[`OM}”Ö ôwÓ:rÊ;"ÝO½„’´»œ}ƒôɱ,Šß!æfÓ~±­èÄ•ÞèʳN}ÔÔ¸ß7íá¬wðÆWyï"Qï轟\ß}yÚsXiàùE­"®±‡¹"^‹]Åeÿ>-»…JwrŒ$å’˜¿®Î sTì:Ž¢*{¨jüáÉ–UÅ:­‘øÖÜ/ËñˆÕC¼ˆ[õøÊQÆl© ¤œ3ÉH¡l‰ˆ–H”š®¹4›¹ŠWÉWêÉ3rŸúGüåøDyÙUÛe(•Å41V¼ª=¥ QkGæF¾°ï Î ÎsÞ÷fx3ÔB_e_e­£³ÜY.öŸ)>㜤=DÜåv™jµèéèb³»¦[(³Ã}Â]åZm&)´à1{s<#ÞÈ\ä|îÌS^±ÈùÚ4WÕ”AŒ‰ T²ˆŠj¾Cxâ[3 Ïû%5!B¸*“—°Diò/ F&=òîä_И’Ü‹8k“çr\Mð.•Ï%nÀs¥ð¬s>µ Û´²é3®¦é}‰yé¿£Äo¤¿OÜ9š‘FgõôÞ|扦.·?NNrU ®ˆ†Øœÿ‚IÙ’ŸýSyK¤$/€ÌŸÅöÝ•Xˆ¢?hFAYŸÆ½†+TOäŠV[ÿ©}jÂ!õ¢û)yFYXÜT¾£<ÛàQ¹žKv7y¿,”Y|ž´‰l×ýRCu>”_1#ø<å™_Æ>¨;CÀ^±ƒ Ærb(ÖÒÅÌH;q•œ|±Jf;‰'ì–êI°JÂ]ˆ[ • ¸ÍžÆrî²Ö6«zlg 3á =3ZÙ©£Lñ–õ !?õ@ãÃÿÿò ºs’—è/@Åû”÷ ¶AybAZCx´Õû4q*vRY×»hE§ýA $¬O¿”~àº?÷2ˆ§ý]¨ÂÜÔWÑdJìgµT>&_Öó+gÜ#ˆ9§ S^5 ‹7]aÐUo>ÐË|ô¶âAÄ&°§2\»È­¾z¬zÚ&$­B-A[£Ï ¦ÒÕ)p> œìë« ÓŒ54VNü3EGâQm¯¶ÄÜÓbzüf™ì2Ù,ŠT‹T3¯h3´ÎÇFÀˆcÁ߃¿Ç>qš;mñռռ­$+ÉjKÆ3žÃ¸q‹^d“­œŒwˆw°Åߎ¿íÔ®u¸Öaý”5ÇšãLF¢ë·ÔÚ©µÕ:´ …œ*ëèëõqγöÛöû~–ð¢3ÎùE½¡”XšK£, Ü“‰sÆ¿—$ùj w€(J} äœDDËô f§µRÓ^¤}‹ädÆ2îŸ$çäµ~Yy,+•}JÉ^‚¨Q¦>zh^™ ˆ¬+÷ 8-Óš@VY­ÜQ)6ÒO•v­l´7¸+:ã ©w¬º¨{ÜëìÊà-#¯cèv´UæZÐóÄ»àZ媮ÕÁ#@;µ-ÙÖPPºú§€»Ap+8y*>×Ú°’GÀ^ÉS ¾ó.mWÒk ŽË…ÀJ<À›Î×Í;ÁYV´Ìǒʘž1R?4‡øEãpFS f?ý*Ø;é±;õÅ`LaÐíŸ2×sN)±ÊÝ­ rol?Ð.ú0%Rø=ÖäàØ; ¬©|78™áF ¶ÆÜ tpeƒ=/´d_»X€ ¨ o‚Ü/Ü º(5@LÖ΃ú¸ëCÝÕå K´OA)몣-ˆLOu÷¸ß±Ö÷pÖ[äVßý@µ„I@4¡Ÿxˆg“¾AP˜Ò›Aâ”ÿsëOÝÑ žN?Åûy/e¬¢yþ€ÌÕœ*~;kñ@×2Éá.Y•Áî˜>Ò³Ô‹P­zØô’Ðàß&k™ësHÜfO¶ëUð®c/x;ÊVàŽ)ÍÁ3#^ÃóDø¢®Õæç¬s;ÑÖ43Ž&^³'êÖ"¥v9=>WT½Ä󮵿!jš5b½d?÷ÎUQ:½áÞ=Nᓃ­e˜2ÓÚˆ!ç;} ˆfVJ-ݾ—=5Û(×È‹°¦P>X#Ú‰TOm*†«X©@åÊ5Ô8ªó$>ì{­x‚C­«*¯bTä½bŽ2J"ñ PÁ¥'suã+\å„ÿö4ð¿\ú0œ*È÷·îL°"âC­¹ñ5;Ôö|½#n£½QŠÛòëÏbdž¸R"º#l’g\ëyθǻ…áN©7‹ú±ï¼=´:±—=Mýoxn¨+µO,S…ä¬|8ùkê8ý$8Îü(æ¢ÄYð°Ñ¬ê),×f×£ÊY}!ȯ=/b»º™ Ðô£VY:*K·ö÷»ŽÔžtTý¨°YD¸vF? Të„>+Ý'~Lx) Ñ6áîàzù+‡ßCaP¼MÂ]ÁýIl)xnÄ0¬XŒzælÐO9€vÌšê¯òAPNÊ/A¬Df(ÁùX™ ö÷ÚZ°Ÿ1~ƒxw}2Ä;¸2!6×ó(D‡xá„îò¿ ¡«þÉä&%~(sÛú;_Êù¥y-ØÃ;?z8|È“¬QÕ#E egjåìW_cBn72݃ӵ 4×ö3,¡‘1_TËžë½þ1ѽÄ<^ÅÃbßëâ[|óÕÃÑǵWRî(ùšíZiyº%%–>Âw¾FÄ›› 'onÀJêú -á±à9H\ ­#Á7%䟌ôDõWˆ,'îÝÎ`–÷”™/;»?#Û|N¿ÈêXOÑÒeFxT¬Š.á÷]ÑÙ²¯}-–"üíc¹M+¹Y\Á–õÔ®¨r¢³œ¸ÒdEñ È_ÄLg”ºý¢¦s@l &«‰«9G…Rçie'?ÉòGÙ”bûm3H¶âMlç¨(‹ªVÔ¦‚RQ­Îóˆ°ˆ°Ú œÁñZ Vò'ˆ‡Ü™ %¢«0A<††‹ù#Ï‚ÜoÎX=P⸲¬¹Ñî µu«H»]ì7l9S\DcÓAÙ«µ©8s@™l| ñÔàVÕ7Ay_9 Šª¦Éó`_¶šƒ\%/ƒ1ÛŸr—sXÅÑ@ì ösˆ_Õ¶à¤ÚkA ¼ò,g‘Ô`=[X.j©Ÿ‚•m=L´OƒÒ“‡€» x”£ VWG]ÌÜ¢½hÏr1Z²º˜*È/iâ|!_åš8&[ó!Sdž¼©œv<‘ƒÅzLý„]ž!²—Ø,îÒ^´{ò…zQüJYy›s,d™ÍžU>"SUÆr˜—ìÝò úÈʲŽÈÒâKzЋ‡eÙG¤Ê;Ù@÷QÂBã,»dŠ3Ž ês'(÷Ðì>²ýG ¨3&MK§¡ï°šƒ¹YŒe—R”޼ ÎÓrHÈuˆ¼NŽØÎ1(VF|F<N}e68÷+a,§¬8„&+y¬³ßYò'£¥=QŒa¾ÓN^â»2ÉH» ¹{2ûÁù‘í ¦pÄù3p7»€2,¶qøœÓ zËí€GñžÖ´Öžm uÅ@l•3At'òp|"0Ò© |/»G¹bœrSì2ÞC“Ç¢]r±ýP,ú6P 8+—kE”&¾ÁHÞ+°ÁÑhŒ0Þ±R­Îöð"àeÚò¡þ ÈÎæ+ ÖP”¯õBpŽZËA~w€V¢+š€Ìä[à‘ØRMôD¿¸6•ð n¹2ò ˆ.Æ5ÛÕ°R3¹bí´ïf–üY;"›[ë͘xËYo§É¯yJT"äLŽÞA1Q‰áiù"åEtQË=r¾hÌE†Q‰tÙ™R.:Q$é#O<._“›å8ç¶ŠãÎFÖ3’§ùZZ¶\F½„|Ð~& D ÞG*Cœjå¼ö¹j§)?‰ÎG\Tv(:OÓD}Ú9@_^–£±Å\çT%I®#¦º©‰õ²79$‡sRùdö‰'€äuYŽâmåÔÖv1åœUÔ'A¤j]IÖϨq\ºæˆî}œÅÀûÿ4 €’Ïnèp`êÜÆ´Ä{ Ü/8#À;Qm„åÙ-žGñ,^÷“ññN}¢l«.Ž'´ŠÞÁúo±'å®Òøy6ú¾Š O}ÜÜŒßs§y{©Ù M™'èÌ´×7›¦¨¬[ƒqô]æù‹ºÖIs-j êr<¢ÝWDm¥Š(WhŸÄ+ŠûÔÞÊUÂÆkÖ½xÕwœ¥ÜtÞs6PÞ:ß à[YQ byr§œ-r9Ëd÷V®ÊjZ'ÚÈ›ñ heOsµ"M†É§ƒ½\5hä4VêÓÊ¡=@5k¢'Óì«×FØÕõ÷ ¶Ü•ÖRCBlk&Äï7Þ†hkψmvWÊx<´ðÞd.FN¹;Ç£'Å÷ÑurÕcå~&†ŠiŒ°?J`º¦ÛèJ«0Õ|Ô«®ûÁqaPF»–rF/&F/§6†Ò@þŒ G=ŠÅkJS¶[-­6òŒ5(>žF2ྛ¸Sd½'B¢~DÒU9oÎÆRޖ䣹,QŒƒâ´<¥ÍU†È‘êJ–sA™¤\²û+;” çe€,'Än™ÌK"&€h&Þ MÖËŸåt%‡ÑNu¶¬`?©l“Êöâ;b‡”¹ÖcN)VgGFÇÉ­ˆØ0ÎSþ\|C§àâùh°‹²‚륟J›‡ìªÞ5¢M’^þ&2±Ff3,ò´ö¨%?v@ØÙÑÙ ¾t‚pÕà$0‡E_u„ºâE?…Ø3¡d`³ljy¥´'BßA“áÝŽ@µh«ª$ýcøoÙ]æCè.¦eí@_y”ò*(7. jÉŸoäAÛåZåé".V8Wp‹"G2T<¦VÆàGg¸ó”ÉŒe gvü)73?e#ç†(ÖÖ+ï2AÔ•‰1›¶ÅV]¹Vã'ÖiG•iâ §SD¥–Èç³–=‘VÆm-wÄ óY2õj¤Ì‘Uv–ÓÜ“_Àæ| ‘#Ñ÷Àï\Æ’Åu¼h¤Š-àièJíAµ1DŒ b‰h Ú 5¬EÎPÝ@ÜÕÁ¹É½à䓪£|ö~^úËŸ@Ä•yÀoÊlÑCPäûLA€²8Âr6ˆwÅL†Šî‘>œ÷•Þ 7ˆn O‹j˜ÎT岿8B‰£(ý¹éŒS(t~RFÐQ®f­ìƒ‹T{‰hËÇr$#éïtâ,§ 6šü€`o—?€ÑÄó¸¦ùÿš¿$øW‚ôV²¨„@ eÀþÁ)€xë9+Êle+˜V|˜oÅå~¥迹–‚²X©²|Ä¥^m"ˆJÜû·nñn øûj6À_/­^lä-àn΀yÊ|b)‘î tã(g)â9ŠA(l%…ªÈ“ÔRÉTö éÉ'‘«F€ü9 ?—KÀ|NöjÈà'y D_ùˆ†Œa8Ï€Ø"_Äæ´¨‰*V˸Kzè%6ŠWå2zÉWè l‘w# å›xx‚ž$Š_åp|ò2ˆÅt ’ó¦<Ï44±’(‚$92¨#¿%ÈA<Œ³ÅëT£;­är£œƒ­TT*Òß¾fç!”;”ÚìgÃäi'ÝIç[±Wì•ãdYFøÕ¹ê\~u‚Náò‚¼ ëËGå£lT( ˜ª”Sʉ1Nk§µéÄœ)¼Ã;«;Õ¢!W¹Ê7vS»)åÕ}ê>†Y­Ü£7ӛЦNĉ²ÇYé,§šÚG}DvÞr¾æ~FË4BiÈù1yC¤£SŽc@?€üTŒe¸x8%R€ùbpÁ@†8¤ \›±eêó‘ðòŒ<¤ F•‹X²¯ò ÈóB9ŽO@~'š åJ}aN`ÊyCFåxÅgr¢´)/v‰?µþ<¡ÄDL±ÇþÝbŸQEyD²ò&È<' "KY ×¶™/ð¬Ö_þàü"Û¬ Ô#Í QKÔ· ¦½!Uë Pv­œ¡ XmA=*G€£Û?‚|ɪb´¼ˆ)pîE§DÎd)‡HpÊ*;•Ÿä÷êPõ YE‘=älûs{ž=íle"›ØäìÒNh'D†<-OËTYYV–)Î1ç˜ó>ýé/׊¥b)Õ¥.u‹YL)ç¯ÍT'‹t‘.ö –9)N „Rsf:3…Ðoê7•†ööâ]{«½UÜ'®‹ë¢·SÍi¢|«,Q†+µÄTqÈuÚ)ßÑT^+hÆBm$ óÔ ¦š ìVmµ À)µ2ÈïT7`k€­>”ê“¥£UfÊvÆ<ÿѨÃ9»¯v–_ã ôûÑ̨^ˆfNÑÁª§…ÀÎ`x#ÎnpÙ÷C|¤SD'§({èj}µ2èwÇ ÁFü‰¥¶¶î@•;”‰u¡ó.ˆsÎj`ˆsÄ&q”íö$L¢j2º›|©A|®n¥]p8KŒ,PÞñ—±ÃNb‘ú —ˆF@ùPìëb×C}@V‹Ÿû•„7@y0ž Î ‘Ô@N6.ŸÈ?Á™ªý ÂÉø \ Lšÿçðwþ”£x7úµõ’œËQ›‹b ]å5ég5kd!kÅK$‰"Z‰ ñ:{DšÑZžã²d­e6›Ä'¬çŠX* ›×«K¨-~—YÔ`œ¸ˆ&‹9òeXÎûbª <Š¿ËS _³A4t¾q\Ve¤œ \’%‰»=”Á²M8 ªËŽåM¹ ¿¨Å à¦,´’Õ°,\ã ÐÒùó K QVúÓxF¾Œ{ô¹ÐÙb¹’å<ÀB’H¤˜ x8ì¤3Èv|¢oõhr)1wˆó ð ,7˜ÅR?ð€HÂ"A)Æ11]‰‘.gk£Xîäˆ ÚH·( Ó9§"*‡ˆ9¸e\<NHyä[䂆³Ô²1XŸ‹@ÍqN¿rÄUÙ8Â"_Ë@¬óÁâ ˆ¡r!0LšØbª¼ •Ù²˜×©¯vc.i#%'ƒ UåtËä³_Üϼ\Lgµ³”1´¢²|áxy˜ªÎ!ÙDyXø¹Ë®Hñž†¸Ÿ]V{9Mœ‘{ä^žÓZˆwä2õñ1ÉâšXÈçkV’#& pI¬ŸÊ=Ö«ÒÆÏýlÀ±’ePO*£€¸<„"—ò9ùÞEÚ³ÊE¤¨MÓÿÿEËÂ.ØÿÂ¥,0§Ê Xʺ žP_ÞTû€(¯ô»µX Öi~×Z~õèeµ(¦U¨ÎÃŒ/WÞÆ«Ž70ÈyJíKù€žÏh¥¯ö­Œ*‹øÖ:'Êð`ü^ÿËxÍ­Jwˆu¹_ä~ž æNM¥UTuw@Äçë ¶@‹#KSÝ­ÑÇ<>ò­½®ÝÌ ý®«ö%ó9DËûXk—¥¹ÆS|Ë9ý ì\åM¥›ù±¨¦2?Ã4¬q¨Ú3V)ŠVd§ƒvÃòú¨Ý”óÎtPF:(Qù(Yb¦l L÷ù,®rd{e:8AåNŸ*sÀî¡î§…6¬³ZS°ŸÐžÇ4 ½"Ò,56r-ÞZ«äŒ´ÑÌ¼à ¢0VŽg)À3, ß+ªñL¸ÕCí#W9…œÅž½ú(ªû÷º¿Fje"ûˆi÷Çâv½êšL©'Ëc± ¾MfëÇïÍQ0fÇÑ!Þ˜Ež­±ß*w›‡ñ»zÄò@«èÜOÀI÷¼ÐuPîv¶‚±)>ô\§èÕìW1õ“Ötm¬Ý¡Zfì'CÌÒfY›xQtµ‘Ï.{¯‰övÈqÖ6.ª¿Ú}eEû7vŠevxË©ç,gšò¢S—zN¡3¯HsÞÒœ×ÎûÀÏr;8›œ#àþN}ÛzÏ>Žˆ5±ŠP´2¢”­â` ‰€ÄÚñ2ÈKô‚ø(§tkQo4¸“µÿuПè½ÄYÏj $n‡'·v“óÿǘèhÀ›Àíeøýÿö½ë`7ŸȵLÞ–x‰z€"2Ä3ä@ã_°à_¥ÿ§/¾±‰*°šî@•ÝÎN5ò˜É7\çs¥ tQ*È©ìå.ž“ÁçY¬çEÑê?lE¸…´8ÿm6à  — ò'à³€qâ5ÀäI@ÿ«µþÉê›ÿ“É¿Ža@Á ²- ‰ †ÈCá³à_î; ž=înÀ ¾^à©pß·ï¹ dsÈÙ ”JDM¡­h ´n#(õ_½}k+ø€C| üÎ ,:qæ¯ca4Àû#üïø[Ùÿó÷—ø ¸µ¡rÎß®WÝp€š(@v“øØÇ5`Ïmh”à4M8$SøœšÀª§©r> üõÄA:uÛ¾ù€¸ÕRÉ«í-jý­ÿéŠó_­ÿß[ãÿ†äÿ“Õ Ù d7%hÉM “% ¨Ãy ÆqÞá$Šì@ûå !$Ô¤¡øžQø”ÍШÎ1n‘Ú_m›ÀÛò<eÄ~®ð*àÐ …]Àe>Fa¨,Ã'2*–q—l+{ó–øL´¢&?òý¨)ÏÉ;Ä>=¹K(,¡1åI¤!’ ÿš'îáE™Âä #Áày‡¹ \§¸‹º@ R€Ù â •ÚÀ1n×É.¢`aRŽÜ ”SXT”ayŒLñ×i#·‘Ì>£…òiQ?èEcîm¨ˆ#.‘ÂZÊc& ¶ÌEç%ür3Oó¨ó ÷cñ=¿£‰V”QLm,Þ% M<”•œ §<Èvr°•8R¾@'l#M\d<ˆùâ{ù X+~±[üŽM’°ÜƒF]±¨ðWÀ¾¸,crQnBC)6Ê‹ Êd`k@väuà~~6Ž €‹¢КÀ42© ¼Í$“¤ÊWb&ˆÆJw ‰ð¿FI üõªkA8: &°höï«©œ /:PŸ€Êe@§2F 9@2QLž#]þ Ìv¡ÈE„xTT'—ô$œc?ÃDgºÓ@H6°Bä2”ZŒ&D¸B °  >r€.¥ä]è ̼µ Ï€Où(¥È@à,gò”ÇdÓ(a"ñÓ”¦¸ÿŠqV°XÌb¢<ȃ d .\À†p‰¤ ¯ñ‚ÉL&Êঠ]€ÞôјË@KZÙ´¶s¨D p\ •¸=£ûHÖqänŠ篞½µ‡ñ­´U2ˆ,€¼†Q÷_žÐ!¸I}ÀEY ‰ÀËX ORd;"År ÄAlL¹•õìÖò Ð]¬Rcr“…¨¤3÷_ñK Ðˆý…À€B™|xðnF.>\r3pÛSÏàkêpK¦ Øb*á ÎK@1Í? °p°€ }€Lyž8e¸ƒ„ØÌ   U€ÁÔÿüß6›¦ÜŽ 98Ç|à°¬ |ÈŸ Ÿpž:‰ßAªcÿ5Ҧˇ*r.ÐQŒæÑh* €r´ÿ%Îþ=š¸ÅDnïÿ3;øû¯Î·cà[éÆêý¿¸÷ÿߨ-Îý#°€"Fÿ,z‡HàUcxø‚‡¸µëO¨„ø ¸ˆŽÿ/îbpM¾ l“^ Höšó2PUôRÄ ÎÀ€Û徕ŽÝ Üæd·xOÂßê{¸­œÜjŸÅÀíGyn­nl@à6Nnñ­l–ðÄ?¾¿|à6»Õb‡ÛúÍ­ë·z€p›%fÿí$’B‚Tr(–›ñ°ÄG"•(@ÒI܇ƒ[´@ñ³Ÿ9Çm6-ñ‚[›=y@&ð* àp€ÛQîíßü­ýkñRà6“ªÿ·ZßJgePü·OOp‹‹ ø[k¦·1z ]7þÖs·Xùßy¨¸Í>oÕáÖXýûžô·F…ó·šß*%Êm§ €ß© §PˆŸ[ó-áæÓåò0žt` Ø€à6#/úÛ}ü]éóR è€7 àð°¨MEÀÍz`"&ÈNtCÊeeŒ3–t*¡Ò”1ÚÝH$—q!¸Å,õ¿b„û¸µCù+«Ë.à¶?¸ÕCµ€ÛcèVÜ=ão=ѸÅÂn£ôÿ†€ÿÿ˜ù·»r’Ý€)Wpó2ÐS 9I~$‰b¯S˜‡yÁ_cQœ %•›ý€Ê'À:æbo¡­1A梃(åm "é€Í3€ú½íÿ÷öwüÈ»¸ @L 3p{ýRæüÿ7ÀðG‹7ÿ7õúÿfÿ¥Uþ5ȯniér€ < ÿÛow8Ùr ¹¢€¸õ òxqk<¼ÜžÍoáøŸ©bÿû÷ €qÙ•òWyƒ³ò^bÑœ>¨ô&©!ŽN*^ åð£r‰Îs ßsŸ<Š‹TQ…d¹B>„!ÓŠÊA± ÄÝtqNü"YL¡eQpHáE¹ÏU)zÒOn£­Ì0«ÐØ6¢£É0†¼ñÕÁ8¶ý¤ÙGIWïA×:»ƒrÜ©ª©ùA}˳¨Dc—´u >T%ŽóJ¢Ç‡.—)ç˜(ö1ê$òOÒ •OQ¸]‰Ø…F!¹ ‡ÈQ”uæÐ+Ž”?íÅlb"Ÿ\¼ô¦Å´¥ibW9.?¥ –è@tºSˆFü/éׯâ–ÄÅE=žDRÄŸ¤r’¬£!r9-gQ 7ØÉ5Æ¡’À)¢\–ŸrÉù*–¼,.`¿8(ÿP2–$å3îuÄ/Ø4¢8O*ªÜ¬+èË9zÕÈa¼s”+·ѷ)0s‚OrÞ\|–+¡¡… 7½òBñ´|8zýòÕŸ0oô¹Y†sfíNlO%O;™—¹4­̉YIìNl”ì#æ_œü î¾÷ÉsH^„iœõi”Q7º†óÒÂsZ®‰Zeñ°˜Í hÃHÊ<dsøƒ#ˆã’k‰Ð’oò’l κ)f`ˆCÊ(†‹«¤ þ“—Àà0Žyòïó¤LC‚xÁmŠs‹nÜrœ5Û”?@Ü"c·&žêªeÿ:·T "‹;¹ x• Àx$ÐÁm™ÆrÀ-O¯ÉFÄì‚ÈL\²“5ÇêýËJ‰?Ža>é ªß芟 àéJcAÊa ×Õ ð±ðq7 ÿ&Š…‹Y€&Ÿ^e=0œ3@@’2þ?\‘¤Ä‹¨ÀB,àuñ`1ÐxøŸt`p¦@9û-õÂoClF`Dš„†@$%”ÑZ¡ï (–³¢Ãb5!þUô0øŽøò!)”ò $žÈXÞד¾}¼'€£µô¬ÆTRõ÷p©.ã5lq]ÛMœ$à³8Âà^YÈ $ˆ¾€ÍyòH"Ÿ ~¥Èù E^åsÒ¹$v£r‚4*Àæ2¨4B-åãXÔbqjÓ„NÔRÞÄáN*£PŒJœÝ(¼Â«Àe,à94à˜äq ®³7aÙ'Ö‰P¼Oé§äÈ%NXæk^_g„R¬àš(5®וf¸© ¢ PLO&a°‚)ÿx~¸ÂD¹šœ®±æÜ%Þ’chÇv~!‘›jUt±\o‡d¨øAˆýDqÓ„ß8,۳ήù”íxBî‰îŠTfKäHx$›"©á_¹`Yf)‡dcyMn£šXË»ªõ9ûåQ™£"¨¥0¢·qÚêç<@ÐüÚBîï gŽ·úr(ôU¸«<\òBðUùrpTø§K4½ >–”åo&’Ë·(—Çh£“’Š+eeÊBH<›@÷õ~ÏCþ W©ì*ã>̯Ú8#‹6b¼}kµ+•ô›®vTæQ}<+Ä(ÄhÃm1ºü×轸¸ý”U1ø/ú_Ç¿§jÿ7™û_ ÖæÈy°¯Æ3Á¨™°D eäàûk,êÄyÝšÇ!VX—ù]Þ',®ŠD è"›J4#¹Šl%‹òD¹Fk ¸AEjq‰LQ‘T*q•*s¨Œ*` ~¢@â_RS!·ƒ<ª—(Ü ‹.QU^¤G¹A §É!‘U”û‰‚œ‡¼ŽälÂØüFl ÅÇx¤:ȯùˆsDâ˜2—Õ8\’ç°ðáÇ¡€›8äñ‰èdSLUrYIªü–JJzœö¢®røoþôŸ˜\àO =G\Ùä,fïÈçAÞÁ; 7‹ßq˜)EQ?æ-.sšb#ÀdáâCžf7iÒŽ SHŠÓ#ò4¦95:5ôXÁv‚Ñc‘ Tv–ÚŸãS Äð¤&|Á×ì„}”Óf»k ´cž òWÑSÿƒß•‡Å´e‡¨#î ɧ%*é¼H7à,E@:ùÀêa1™b4ù$ûX 'Q,]tGȃ<­ÀË%ê1†& éd$—³/éxH!ÁŠÐH"páÇ!„ƒ@ǤÙÈ¢De%ɤqoH‘ciF" ů$Šf2?HÃêH¦óPìN\ì‘SMîéC*aõ)­Ø§Q^DÁÉvgWä=œ–ùT¦¦¨HSF‰âyªŠ #ñôzÒp¸I„.’ƒÎ)`pœÃèb7* è@2©À1v§äA ]¤wÐð“„1/^àNº~2šÔN±ç_¾@ü5ŸJÀ&˜¨€I(C9 µ€¯™ ìä (ÒQ‰’I” H,²‘)K(K’X‚Cÿò‹£Léb?PJh$ßVó<ðŒüäC,éç<Èù²È"… B„ðâÇO Å“H˜0.Ò©ŽN:ࢠ‹ ²E”LÒƒòÄ‘T@Êþ+Á#¨BœB*!É¡ …dáá4퀮sY ²>È>yIn9A”% ÖƒR@7Šuœ‘OÉtN˜½iK€tj¤D˜Bš¨A4ñ³èGÌç%üÌÀ…›!\d‘Œ‡Dܸpáþ«ÞÕ0pÿ%ØÔ#XHà1þ’&Å­Ôü[;ß’În Š·¾o¢ƒ<‰\FÊ %è˜h¨D‰"‰¢!ˆ¦(8Øœ§ˆ ìã.êãAj¯ÿü¿Œà"8ïÊq< ”ã%:äc*‘Âõ×]Â_ÉZ¹¸-Ìž·æý©è¬9„ 2ƒV”wºÒ£¢)Ø"¢<Á~qHta/©/wÒ˜DÎ"‘SèèìÆ “@”?‘(ò$&:1°9 ø)á¶L—M6A*PBÈå*W¹@   Ÿ&4Áá7( Hˆ¥QD.Ú¿oúwBí´™›\88xÑÐHä:×ÿJ­UâHà"I#‰$²É§€Ê$áGC„Fe€å)иͪn=ÀÒ@´ ý¿®Kº©$w£²Mô$ÆFÀÅîù#=ßDo`9Ý]dsèË% „ó@Šœ ÌäGO’ƒ%;Ènhòñ<ïñ:=yZ«ÉqÒ)ÿ—8sK.¿ÕŠãx“@UfËÕ EÚKä6„ÔxäÝÄ@¤¡€xš ÀZŽ%lñ Õ)&€Ø€Éj ºÜr€x“œB%FYÙ0ƒ+ Syƒ8ï‰b¤2],Ã¥mâ=`ö?Àÿ/¶Ý$Ë'ܼƒ"¹Ðy 1±Žˆlèl!jV‰Ô#ê4¢/nç=ç;ܱVá ÄÅONoLOïÝh®½ ×0\Ïø’¥OHÜH–6ÏûhÅW|)‡QBi$¡so’Ì Êl¡²]–vHÑJÔDˆø@lä!»I†²ð'BM("kèÀ%  AW‡ë€A ÿJ%äÜ:—·Ò·„ð[‘}ôÿþåØÿh­¿Ïž¿ÆÆ]¿u~K}HÉÀí©éÿå?þ’¬ÿ~¼•­ Hª'4ò¨…à4µ“·Ž¢!ð'€4¹‹†À9Ê5)ш«8(bQ— ´ÿ‡ºÿ ³ªÚÖýÑ_iæšÈ9Š"EE” ²bA$ˆED‘d@@’ ˆ¢dDQA "9g¨8óˆý~÷^kŸ½Î¹ÏÿžûÜ÷Ã|úœU5Ƭ>ZO­½ím$€ \Ä¡…@)Ρ‘#~òc€ËŸ@Œ7Aö—˱¸›1˜Þî£Pž‡Aýú<"Æ2•ÕÀzØ:§ÙÏä:3Ó‡ÈX{K€¹6U@iótrg +R5Q=ÖˆKÊ/úŠg|50ôQú ÔÓs|QVÿ5•)åz¹ ¡ßêïŽ}Ô0¿‘+[“k¨ŠÃX 2)<.ˆ)\‡.U¹E”n­£ªØ¥~ò7ìßÏ(æ¹ÙÞ8iÉ•“ÏYT$¥DuLò¨‚‚Ÿ ˜ÁÇ.¢¬¡€òYò¨ ÜH#^å(eåFΊ>ÜH3VÊ(b„Ò•W”›E'$µ pðÚÕ•¢€¸âø¾rº¼ b0 x D²?­8iÕ§!‹dGq3#Åz²W,¦9KÅvJs‰94¢hÉ>㱊ÜÁntãG$wÈíÑŒ@Sþ²¨ÏŸ@瀚\*QN–2€ÿ¿ì‰ )r@^¤PHuà8Õc\ä`/Í­âv›¹ o¹óüÌ-üÆq²XËE<>#…&§#á ÕW¾ˆÀd -¹!†sp+ìÑ›ÆÀíÙE wЂï1Ä}¬Ã¦«ñ1H.®eˆ,Zrè/÷‚èÈk@evuä 3«€µ,À‘ÝØˆ&]gÃ¥rÞ+ Èú*_W§fµÕ•?Çg¬­A›dìn‘ $²úù>AßÚÆ–ðùèVÆDöòVð•pJû{g÷&Ë÷M$Dut¸6š–h$ (ôõ–b9ws7YÁ,åDjs‚?b¨ƒÁ_ñõÈ?DÈÄ?Yò¿ ’ý™åšûº!¹#6¡lÝLÐýH±Ô¸ Á°èM±ö³Mù ¸µ@Ê‚È~ —îÀýü³4Å‘å¸MíÇ{™.(œL>2W®ï–ô#à­qîFzsK¶²Ú‰‹,lûõÔ(f:¯§ç°Úz;ÓŠ|³kÂ&'õeÉ0ôô±ôªŸ¨ ÞGâh;ƒý.NiÐ ð™ºrö指ðÌÒçÁ8c¬íÿ<ÐïÊÖpU×X‰Êß9f@° ¿!Õñ„Y×É¡ ®%䡹Ø@>¹ ‹wÁ{Šdìn“«èjÆ!+þ+šÛÖ©ÎS%‡ÀfÈ|ÒE±—´‡¢s— ~MìfHz™|Hýé”@Aé‹5 ñ^æs(ÙRü:X3ä`›sÊ®ÊýJ]Îê Ù[Ãm!kqø7ˆ¼Ѳ9{ x)g$^phžÄ2ò}7â7îb£Z3P±ªíëÉÓÚs¾]tszчªZ[¡]–çpõ[ålTÞYU•kA9ŠN'4`$QlWç5Ô‡D'L S‰Çùá¾K9N›{iÊljRÜÃëöf{ÁøÚº–Ø<â~‘É&m=[EÀ^e΄ÌðXwœøÜ³±ìÏõ‡)2ºGôçû¦sÉXìÈ>_Ýœ]˜š®ßHU-a_x¦/NñºTŽZy'=-=%³9ÕÓânÁ«µõ(<­üˆÉJ/djaÉ(°®µçaò“±™¬ÿÓ¹HÃ|].AÆ;%|œO=`ßÀYQïC Ù†£Y3²:Ñ:‹øRÏçÛŒ-u2÷v.eç¡E&ùWAàsýydxApF¨²Z°lh 2øGðms øjÚ#þì >m…ò'Bõó*ÈV™ øÕ{9F,°Ÿ¿qä#PÆjw ÔŸ•“hÁËèdñ. c½ ¹@iŽÊ JC„[l{xöû‰©èNÄSÀ9îë[ë.Hl—‡ô8ë ¸ã½ŸÀ_Oý¢µ¢OCöme =Ÿ§£„WªÍ“Z2Z·Õ'Ëm' Þeð‹ñPH¡q›Ïek„{£lŒä%±U‡¨T¦3íé‚GÑ–ä£Ó‚4p'ˆú8@3 À‡ ÜFFµð×lþâØý#T †~ ¸À9<`pØŒ r÷•¬:t$k‰"XF˜˜ÜX|Ãq%X#w+”sÀË¢ Ðëo<¥?€´WäìƳd e%ˆvq&)|8Icð' .ÝyIî—[Ñ Êñ/xXôÏT8Ôöæ 7ÎsF«¬ÏÁ×,ïkTeQ™îá¶RËxƒš9©!ä_ m\A[À’G€îÔ¡Éõ\Yq«cÐŒë )-!Êí8ÀÝHà.ü@u|ÿ?±ú…är%p€ùd€/p@~E›¨X|œf)&??‡ N!°M> ²± >cÝ8€‡\ÆÊ¢+˜ EïÈq.|P6Jhw’>' <€Ø€Îà[oÈž¬ná~`*§€Šx šP¸‡C@%B@”º@j•Ä=@6 B+À‡ŽÄ…‰Îõ®òþ®öÃÏW_¯p#u\"¨dø09$äY Æ6à,'óì p€ßQ?Èù² Äìã/Žè¿‡.¤™/'Ë|¢œè€+gWñÌ¡_ñûwd¡‰°ù-pSÇ/ìÀH%{“‘9Æÿ¶¬8ãýC³ó®±#ü>Òx®ô; F•ý¸&ò ¹³ÿ“ó[ yPÞ ¼+fƒø&HÚS ‹¸› µD{4ª3ïâûKÎ`â! ‰D\åò:W)eWfú´Åÿëçù¿k÷ú?´¯àÿ‰‡úßܼšAo\ýäÊ;‰ÄB ð]ÍÄ÷_ ÉÌ å{¸œá<þd:û9 ¬³A>Ê7+qPš3öê=¸ÿ4’n!#½ó§³Úv.—fGb©¬ßXª½+Ú™kø©”É9¢áN|z5#㊓çÿ{\äbà/×vò?ÚhÇ|…Jÿ¿q-3ñÚ‰ ˜‡«|²œÓðn!ƒæEÄØÞ^YŒa妻€kªmÁ~ĉ‚óP¦,Ýšy*è@Ö‘œÛI…ߊ>L0to™ ôðßùœ²¾SÑ'yG¿±üs¨bveÉ}‘WT¦ Iâ/ž® Ü.Èfb9ˆ\DryØ\KG Ê2Êb,~&¡5¯æã¿žíml@¹Jíüû$‘ÿÿÁ?öÃ!\`8žœNŠ7q8À—À>bhlAÖáüš@Eq?ˆ³Ü4øpÉ@\ÉŽ·b¢·æôõl°^8?„o­¶EíqSÃKÞÁ{åˆmÊïÅG KðJ c!œ¸L‹!×6C(”]ô¦Ê!Ð;)›À¨êïú§ÚBmÃÑÒF Šè¥ÔÂRn—_ã)‘ƒ%¢HV’a‹/Áýƺ¬F÷¿ú>]\ø¿Üßÿɬ—|vp“½Te,”Yt÷nHf1ƽ)>šœ!E?³î,éKØê›lI¶µÖ}ÌRùS!ünV/bWKÅyÜצL]&ê×WJMefà:$G؈Ç,Z¢â ’F‘Ü r½€‘|"Ä^®hÆ×  ·s+ÐDtáŠÒ‡EE: ¤ ¾Ëë{eN¶°àj®äÿ ö?Øçÿ~þ×™ÿ¿~ø‹Nà»*câ’FEc1:|\”›€C¬~dð … " Ì£gÈ5¢>(ù—K¸Wϲ“±PiN’Á ðþd’}Ù:d¥×žÚ„Lªù~¬øMÅ+ñåß}ö)ðuŒvDFúFë“ ®É=Î%C3öa­C¾4®ÉîÍZ}~N;F)]ï‘¥(Áߨ'Ϊ~$ÃøAówóãþ·ø×€ú 3ųáü›©~[!Æ€÷ [yDužž¤ˆŸ|[¬ñ½\î­ÖaHGå9p·)SAÜäN‚ôj÷uH·Ñ"àv”¬8M!9AyÒÓăÈä(í2"yRÏ…•µÍ? I3yAËõ–›ÕÔ?íB9XÜ` Šå|fޝÓ2¼1ôάñÖ³9ý,¯²?õ»ó3Óǧ°SÛä3è‰2Ù –‡ìiÁìP Æ ‡i;N*­h4äHô`=ý[îð?¡LwvO+Ë­…¢EÖ%ë>(_ÓšH g¶Óòš¹> ç¼T!TäÍã2M!ðœRB«Éýv5Oh&ø?r?o’±µôsà{Ý ^ˆ}@'¹˜*æƒè& F|r è BÉ̃Ôdïep^T?1Ç*„dg¹쥲dz9 !~TÞñÎZì™âˆ•U]¼Ä›ÊhÒçßÓgá/8âŸÉÏ—cþ•Ü}j§þ©yá\'>H;$‹17*iìl¢!ÜØÕŠ&0.ÜÇ Þ]úg¨:¸i[¨z¹Æ,Зdfƒ6Ô.€À(¥„s¾ÒÇA½†³¿ñ¦W ×?LÛÀ'Æ·]|Ø.÷ùó”6òE£œÒÒ=¦yêNw‚â…BÎ:ÑRûÖzAœ ×v ¸9o¼{=NÖd¹-zBö…@Bî…@R–@à6€®ºˆ“þƳµŒ×tÙ þÎèYyOJášo¿àæsÇ÷åesøœ× ¡›zb©#>cXè# q#Ü!hòUîk@œ¦6ˆÔ9OýE Ï*E8UÞBË 'ŸÙ‰Bµ+G¼ Ê™í´f‰wS¬‡ú¦·5SW¼í2Çr—ª-Ѭ-bZéäÔ±V*³yÜ¿³‚QYŨ‘û°ÓB¬4º/“Ê~ÉÙL—à³^3Üpo&jh°w ÈÒÒã1 "ÍÅW ^/¯h5?üÁ`½|âoË©¬> Ä”ÇîDe0¢XS Ž&o×næëXw} ‹“ÛE_'^´Ž†™pünº¥–”äBæ1i‰pl;ñm^zÉ¢J¯p>˜W5‡Ò|7ñµoˆºžž¾Gô÷©¦•w®Ç5Vë! Ôµ²²¬£P5(Úè«&H>g:ðoØÿtiƒ“)GþöáÚk,=öŒÖXN»Ü]ÜÊ9×–‹ï>òN~Çó¿¢]ìx² œ]Ð ÎïõN‚Õ=ë¶Uò ;Vù}>Ÿ7ÔFjÈ/¼NÙ]<œ×ì=ÀL}1(Srà¬?‚SͬÊ«¡bHî(¹”kC¯€³} Þñ•…Ô¯x²§^ ÅøN_Ãvßd¹‡üÇõF<'ú;â¨Ge 4e­[„á¼Þóé%`|¥u—óh+‡@{Pî‚d=ð†”\òHú4^ŽtušW ê5­ÞxÙYvQQœË©@yQýHˆ™ÀPý3°?Íôox ,ÃzR}í ó•ó2˜¨ é!âg0—(PLí6Èý>»"äêzSÈ©©ý9]µ'‘9óý¹Å¥_æìU/qs(·ì®§M(=Ô©%ªUÝì#+ü¦ÖDT(«=9 •)àW¹ ¬£4¥VþwøG ¤É€”}Áë@J¶öó8\ èR„ü“rTÇ@ÅAðW0 põšW¸Í…80•;*À9zŽøÐÅ)  ÆÁkËcg1€Šòk°“Á™¯t‚@˜üžÿ;pݨüÅDÄi îÀXk(y#9¯@³ƹü;•0.=§Í;Ï9#líeN`—Ò”½ºŒ÷}Ó2«©hœ nô*ëMˆ;•UEmk½&û'9 ÑüMìš,/ãwÏ`æLw§ã‹vå$dÍ“¿B°žrDž—]Á·´¶ÂzÔ; ¢¿/ !×Aü,ó@t—M€¯¼ 0€›€ç8 Øb÷-Äfàw€,VVì¡1ä³`;l÷]¢à,ãHÇåµ|K΂ägês<ÈóÈËh-Eeµa\\á‹3©èe½ŒüÂê ­´0«Š–¤;/¥ÇÙßÐ0ùb¢+Í”}G¦±-7ÏÝe¿šQúD"&r«¿” °«î׿[4©aqYe»˜(½F/†RªQ¢¯FÞ‡¬%ÛÀ 6à ÿ“…ýuXvM¨ÀÖãñù(Øôà*ÃÉG“q6]( òuÞ*¢€¼•Až•ÓJ\®pg!› p x˜(ƒÅK ?G1œZÀFjƒxƒA\Ë8ô4"8|ŒDãZïÒ¸ ÔþHçý÷¸’¶\—8PLÈ–¿áÉí©í8‰¯2S0 Ï …s åë8WIÙÈÙ3ýi}üãPÛöíòOÖ=º=ù¨;˜VÚÀÊMåSÁ^ѲÎNãëœßÍÛ•_*“éF·ò¿{aªVžæÅÙ#ÅvDž¥ÿ ¹¹>²Ž‡¶BÖ•´ð+‚Kÿ•”ô ’ (F³8ÍFêbó’\T@å`FzÄo·Š!þ´€‚—¼p)Oü—ŽßÁ™þÜ'ûf Áÿ£Õª÷ñZAÙ—µÒPeš1J¯ðO‚œÉ¡#µFy”~P ¸ödQÿh•»€¿¤XfqpH xû?2®aøÌÈÿ“\®¿ÓûØ©ŠïVê“ìÝ#¬pÑZ2ÉÉ…¾XøÒˆÂÞ‡A¦¬(à’v°ü`§çuewÖ± ÆmÁ?µùì 6ˆöu—ø½rõ­YbLÅ2ö»„+ÞåiUê&e ”[ªÎCÉ{9XJ-S€>蟞ï?»Œ‹èr Ãä¶åCfˆ,9W<"¦¢Š=T‘â^`¯ÊËý?ãŠGCã/—èÿ}XWyUþŽC¶%ëAÞÂn58”µ±Œ¤ GÄí´`¦òMx‹ø?õÆ?J9ü'2 Kg9Ö]8¾ó:!Î-Óàógz„Îl×'{“/<)æ%‡ž…6™g/?B}`É0²÷G.ȯ|­Ë?iuäÉì¯í—©•—pæs20ÇKR1TI–¡^–å £Rà’hDéì[¼^dy½EcTßûj -RJVB‘çø™4äÄY¨Ì§Dï%¯-'òhfµòÕ•±KvˆÙé±Ê<*¥ú¨w°½à}6›òúê£ M(›þÆSpÓƒ®â‡Ó]ß>âöL¹èn ¼¸@s)µXí} F±ÕÎóV±Ü+á1çC6‘å\ö1z¤WàïR!ð¹Q¦…úJ¬ÊE¹0t"k“ÝÎHUì`N¢cåßíVýÖÙN弟Äld¹Û|kåmß+ýÆ—€ÐüWçÞ•÷‚à¿Ê?8ÅWÞ\v0A>%ûa‹õ\@÷ˆÙ ÖPD>ÃiÀ_sÉ¿³^^q;þŸ¸8ÿïÀÂú²d¾Ù‘‹ O° WN“KP…%ñòmù]4â[FPŽ06’'ÐÿIfðm€ç¬ z8óôs*ÀÅÞiä©Ú§ˆ e|Ù{|‡¸›>öh›Æ_6¡ëPZŠÝ`4äðøgéõ^]^ðnyM®æ2CÄ­œd„XÉy*³)^ÀŸPx‹rÀCTâ/¡«ÿûøËÀ+œù àÒ bƒìBEÓ©F†>dqRÙ€M9¥ Q>$i@\=«þó8‚?Éu¹ ^[GÅ-¾Îmzb¨’áí£Am„|ûTTˆô¬üÕ9½_Ñȳ5àŸ§'@a…”äPpðõµè³«\ õ¦öRÆ™G]߯ԣŠÿWÿ~VþÌnGn vôZF¨53ÔváZ^åóÈ]²Ÿ0|_x‹(‰\ðV žb *‹G ü³—–(ý!:Z<Ú78 úÊÏAVÔËC™q" ”ÿkçýë@À÷[yø¹ÕIN~ë= FoÝúAÃíé€XÌí€B6°—kÀ XíÁöy ÀÞ¬úÀ+§¬g‰[2íÕí`µV®ƒô£úE%ê`÷ðbƒÞÏ[¡é(æ7¾š¼ÀCêhÆ'›ºàS 2±ÊßáH½2÷RUöÔú9•òâ‚YÙ*˪ôpÛb_f¡’¡$sNk™Ì¶'òvú0«IÚ—.Y_¨d"Áðb>åÍÐ<ü¬ WgðCh¢÷ª÷ÿœRÏ<)¦éõSƒX—õrÆdudzúU&ÈFæd‚¾N©# ¶¶šÑ!3Œræ/ }hÞÚQg<®s'B°¼œÁ-ÞEðM£=ø*ŠaàÛãlQF®eŠú5è[hâ.ù>ˆFîpy“À›®ô¹E‹¬)>·ƒ3RÓµË`Wð¾€´«îƒTJB|­vÏ©u x°oÄózùû“‰=y‰ U>؇ϋ»…g˶éËÑ.âµÔYcžN?Iº¤¬úyEòBÅÇÄ9(¶”®pùF׃KÕ½.O‡&‚¿y•š˜g\caä Éþ at7'âê üä$^ñ})—s {?×^”Y¤‚gŒmÔ6f©š;C_/*8õÕ9îvj(d bjq¦A}¡yÍØa½Êßçv²üAûw˳f9\5äx¨Ên»Ä#Vh'¨M½ ¨™?Z!¬@Îà6OB—öâP®ùÓÊlžóŒ¢£¼õÎY³yá+[Axo³´ÝAñ¬Û ¤<£!4DH0‰š 'ewPfqäB„Lƒû“\ öLñ޽W½-óšRŸ‰Z¾ú:Ý”|õkê¤Ç(eb€á"¬›ÕÝ`,×îñ‡Fyíȇ3ù ô6¾u‰±Äliç@4äfp»Úó!“»dR´·ÄÊëP‰<¡­é7V;Ã{Ìj©½`­s³@N ÝæQ»˜?SÌîN[°êj+ÁyðR[ÈšŸn¹9b”Z­ÿ¹÷•Ñg¼»YR/ñyΟúgÞÒ°ãJd+Šã=y«zçÔ¾¨zÉÌÆ«pN£T˜%@ÙVr8äTÓÿ„ÜWw!kšï#oòÝþÅïÁ¿Â×´\¥DDKƒ(§¶Q ¶â]uÊüW7£ ˜œäUõx𡂪€ï*û»ðG­€ Påjšô­Àr™<ëuYÕ ^e÷ðÞ¶+€;<ÕÒ­R‹ ù©õÄkØw@ñw\¾,¯‡‹)^€C ª¼ m-µÚ]a»ÿm%ÜÌp/w NÌJ,†ÂÏROá]Þrœ3 Xvü‚q'ÊÁ¬è@¦¼»Ü1Ù¶p…^âLÁ…²oËN‰þ{ãB|B…³³ ÿ¹_ˆ-9½†´˜U¹.27שDÿ¬)êóôö_Õ©¤_›^B¥P)u5nà1õ´œg\£FÝ£ú1¹ÆzBœÑ'ÛG >4D÷]gvA |i¾Ä_–µ™„>ÛÊ祽}WÞgµCõ½c8ÖŸ ¾lÍ´/ú»ï}o*ø‰åøLé ¾l/z‰W‹3 4S‚šË× >¡1’•ÁÛàÖ¯‡²<©­·Ÿ{ì7¼¶ù@[Ö ¹ÒQõ ئ~ÜÆ5`?£ÿök¾uཥ·AÚÝü!Üq>“V¡q#o;wù.2­ä]ÿloZàS.Ä>4ÊÉÚöê„ÌPí¾I÷Î /ðÀ‘Š™ÉÃÚã½ fw.(äéhׂμŠç¯ÄŠŒ¿„Qæ:{Tß*>ÊÕÔW¡\@U(ÕË YÛà ÒÞžoLpŠonäOöhGñ¶Z>ÜœqÊ _˜É¨‹ØÍ Æ×LÂU ©ŒÊÔ2W9ËÿoòjH Œ:ði·ˆÏ سùŠ—í9ú÷«;¹ÿðú¯+ñü#»ÿŠc¾;¯‚ÂlÍäTxè'‚WNžú‰- ý¬L1…3ÿq­ÿÄ…ýiòþàÇôOlðÆ¤ŸÁrŽã9ÓMt'™ú-ÕPL·ß·ÜMpù]¾„ GôòØç³ü­§æ÷2éâ¤H˜{#²Vú¿÷.Ûëe27fŽ“•zðĺq !ü“q] #Õ½±2[¬½¬‰œ·ŽðY¸µ{€5Ñ/KPÖ{•Iú‡‰EÄCe.År¢œIÑIdDYIA€wÄQj%|ÊQ¥î5öqÜ­­w£Lñ>}3$ªûÊ€yÒ÷Œ¬¾lgl…o£zﲉ[ôÕãÙ®s?´’6™§=€ëÝšÒQ½Ÿyé–ÛÞ‰Ì3gQ`#mì–4vû)ÇøÍþ–gðÙ¿&«ò£hQtuƒ×™¯Ó5ÜÍ?Oþœ§èνzõ»tÂ=kÀšº›W´%%ÛxX?™îAµèÓV²ÂËŽŽ¨#k@Þq1 òªË‘Ùü½‘š‘çÙš‘ÕœžÆà –èC‚&׊ü~<±@ÌF¡?ç‡<4”«\ìãà^”=À;'ŽËÑ î‹Ai ¾ÖÒÄBñ|Í»@µ«3ùo»ð‰¿ƒ+¶þõâþëÏþª¤™Å ;Ê7@>ÊB 3‹À;%Ÿ³äÝœµŽ˜ ÊpÑ (&dãÇ#P(…ËN¹•O­Ÿø‘¯SÏ1ÌÝÏð´ó|ì8½Ó½’Y¸ÉçÓ ÎXp9OnKíµ›áâÆ`8ÓÎçâHf•A)¬ÌÈXÇè+¼ž©|Ïk ?UŠÒ¥ÅPv¯HucAr—®RRRÛnŠ’YØÍG¾Á5–ñjàtö§¼¥ûE7Rªð¦ÐÞø^ý˜Bí2]©Sœn\¯ÌƒúhQM¼‰*~I*ÍDBj@^`óÄhΊI”G¡†øžZhæGüˆOˆÑbmôçÿ‘¤.Âŧî†I÷°“ĨÞ>å0@ìïVµ6H)žë&·$Gé¹à®WTœT‰º -=@»Ž¯RkŸòa‰¥µàe™¯9r«ì©Í–Ÿ{-Õ=ÞBúªƒä£J–rÀ=¯ÎAg¡R2µlÉ{Ÿv’nâLCþµK~Bƒ`où†ùµÞGþÚ ÕÊ%7ðcÙÕ©,¨67³»Ü,ozùÍr8”þD9y×û†Bö2¿„¬ñ¦ìmŒÇ2æ½pÕúþ±ÔéjS:‹EXÜL•a¬F%p¥.ÙÔä€+­§Àë%€—GÝäc  ¿×Üâ{Úç¯V¹H⟵®Œó?ÆÀ1¤(9À&2 {ó+pž0È'(yHvnæ}Pn?€ÚF¬±€Gs$ÊÕl8…ƒÀvÞäoòeXÆ!y 5uÂÞJ«1¸Ï¥@fgê#HµÊ쀒ÕNK(Zì ¸<—Åpf£nãžIûw¡}3œæí££?3éð¾ûR‘Ô^ÆA¼p/ïòG¬~ð5y£ïÏë_äÞP5ÌYã°û*Ïúj{ÝðôÀÆÇ¢¾—¥†äFïm¥²·Æ9 šxœ_•E£‹Ä}N¢Ÿ{?S„ç(ÜZç¬Æ ™Î^´À~‡Pg ( D„Jñ!èó½Í <èæƒ'ëü~ª=cÿ«ÿkN] Ð#þ*™Ü×ÎÞ‡t¿å,–Ú3ݬ“Î; :2¸$+•Ä@Фw\»MÔ ,E×:"åëæNdFÑ\ e®.På­\ûqýZpÖ~¹Ùk é…Ú£(f$ð¸Tƒ7Ó9þCXž_ÝHabÿZNgí2ò9™x7PŸŠ^‹Àž-ç§ ³ô@ íCeˆ>Àï)õ´¤ýlf }3‰¤Å¼`BÅÎÔýúnš&Ë §d –iÓ±B9r?_†Îxµ½u³bé&lÔNTdg /u‘-¾“é‡#Z¤#Y™aTÓŸBà-+ ¾éfWð·µ»CàÞÌû VqßOæ[ :¹gAï“. Þj‚Üâý îšDU°ÚuÀ›"ëzš# ‡ÈÈ÷´r ´Õ.ÀmáäBºª?”ÞÆðêó*¤æÀã{ìÏõ»ÞîÀ&LýýÀzü‘rÊxÚ ¶£”|®(I_'JdØ–ZBJ]ß_W÷;B·Í® Œ·?Æõw±_uŸ3Õ!~ß~ó:/z Amæ=Œi¸—!½]Þ{øÅ8þô(“…(¾•ÃåîÌ_ˆš§iäfËtA79‹ñéaã#´ê5í`·nzzDƒ©xÀMT9O½誽 ÊÚOh²»³‡v#/*uµV8Ö:y„ÂÌïÆMXbˆúO˜øþd˜SQ;J3#ÇűÌ}©RìZ¾Š©WÕKé¿YÕô¿Qz¸ÖÆÍv³ÏÜj~O&Ó…i -óA(Õ#1‚)ÉÕÎ",M/bó'!Ù:`Aq…ì (/÷(äüohù‹ ζÄÚÆxÿFñ1¶qó±Ô¨¼KŸÇacXú)Cí}ÃFØ'^F—/ÉITôÕˆÖfokO_ÉÇÑX ¢²¾´ßZ ú0Ç–( ¾¨Þ¢—ÿGÈœ/|Ìv9°;3Àf …äë:p.+iˆEû 2Þ8 8çVpŸÑçY{x£µGÁ»ŸÜ-FZGI045ºøF¤-yÌ×^]lïR¦ûûgž¡ÄøÆüt&ÇœÀYÅV1-´uN1®á:ÓQõ}ö]à5ðAî_[ï[°ßñÎûÅY .«ƒµQ¶…T‰¾Âûõ?@Tr' K.È_píO„Ž'‰1ÄUÓ¹†®ÖIã½´{$¯15&;³K¨é>íoÏÝ¢Š›è˜½òš*òzÿÅèÍÎCêjg¡ûrPïov¯iº‰êK­÷xWëi5Aͽ߾‘|íE{›EõeŒèþÈ;L ÅÿÀ'¥Ûžü¸ß=À¶ƒUõ @ŽrÈ-P¿`Ž6Ï$ˈFv—àÕ)µò¶V黲Ÿ±ÊY òÑâý o²&³$ó1°Ÿ=À3ÊfP»ö?ëï€7(²2ã ›€ã$V@¨ƒV Ò¿»ïwJv‡Ð}$dö%Dh[Íñù5€R%}øë@#<ýMï7lm¾lŽîÛ&Ê€öµÈmƒ<Úýž‡mœÕ« ØŸº„fhþ •ƒÁ ,ÝÈ~ SŽ)‰kྟÐðË~öz 1•@œô=L&ZÃ芟<çˆE"^Ç ‹Áj˜‘`ù“›A´Ì f5œ_õGÀÚdæBfƒ22œ5`Þ-Þ…Ô0¯ †œGÀ,ËëOo-8'´ÇÀmÃ<õVíªÿ`äY^òMã¬MÊó‘.ér¼[æáxiš{SJªã^΋ï@1ï(jçR±ƒ(Lï…Ò·ÙA©æÖZÈ>åªÍS&A4êý Á·DgîÇ!¸Èؾ¾Æ(0&1´Á¹ Ï¨Ÿë#pÕz¾PÅJww‰ÞK,eWrÅjîÃGÏä³ó²·z˜Á”1>c™|Ñ| Ç›˜„æÍÑ&76Q ì£ÞgàD½;À¾Õ<™ãîHwu3ªãí‡xO¹ b¯ja(n¨½ù½õ£˜OUôË]‚7¢œþ*»óÔ¾²“¹ö! ‹ÎüØÐ‰2N½ùAü»ægFÉ¢J/ JrËïÁ(z¤ü"Þ-Yªœ¬áö-âžÀ‰r·ˆ„òzé;å41Ó7¥(¤öcÞI×]MƒüsYUyÔz*wnöñò-”_aû}‹3§9çÉ™GóÐ!ïþ|îíì6F Ÿ½^m/¶[³X©¤ïá ÿ¥Ì,²²?JÿÂsÊk!§‚š³Yæ/³šÖz%û# ÿ« ͬ٨¾‡œh~»襼Jà_b¶qŸRÓOæu q³ØƒÐó-UÒÌWŒ×ÀxK™ ÊJYŒ»åA2Êzy?ª¸QÌÅ­€wByèäw†õw^Y¬ž €” àFÉ@ú!ï^°>@jƒvweV|Š:œ@¢úÇ“?êßc”<ìËCÉ_TÓyÁÞ© î ìøÇÞTôØ7Î\ÈïõÊ-P³B%øo(Nÿ©õ`}±®#âמ™›ÐN}:ÆKæÄ˜VpsÙ"ygI…P–P ï)ß–‚‹µÊ·õ’—žÎþÎÎÎk¬ÄÐ2_{MÕ^ÑŠÉg}E¿Ê´‚ÉÔH:ú¾ˆiTóÊÌbRdqf6£ÂyIÖÌ:Ø“œŽ<›~ŒŒÏKvÁç[˜:ˆ_VK|A,a¤ä 7ŸbvxËÎtáÙƒËÊh¹„˜òi §üC¹' :;ÔgŒuv1¯çŒðf’ŽFeÊ ç~ð_b3äUw‚ïZ‚ Ï 2dÖ“ Ý@+È®í;Êh:€ýœûè_¨ëÁ?NYD¹–¿‚=W\š:h`^öJÀîàÎýYm>df¹…³¬‰@?¥/¤¶¸Š[9}!Õ@¾é¨X ‰¯Xˆæ~©æ’ŽR1¤h²ú$jf—ž'ßJ¬S6» Í8g¾ næÛT ø%¹^éÇÑÄ:e&vɧ¡Šèñ=¡¹Ù¾rQ0 ‘‡³>cJf9dÎlƒÔ“æg¾rîÉ»μæL€Ì²ÔØ…&~BØ5ó¡,ÈŸ‘Çb?CvÓôM˜¹š•Ñs~³Ã(Ù]]ÂØ‘ªV1gˆ€`ôÁå+Ô R+ë[ƒPß–ßqH.Ê.bšö%äžgð4}H˜Ux†WÌlæ bˆeÞRµwz¯ÛëqÜÚòª3™Ú`¥dZÉc`-ó^ÄLõÓOb$CzYDb; ¨þÓ¹ÐäÓ üÍ@oÚQ¤´8íÔy;¿IÑ@v*ãüs¾^Yßðkô@ø:Dß~ÌœPu–3ÊG¢=Ô¸OYhÞ¡Ü–ZáýÉ è%rY’º“³¾M¿F­ìUÉkpŸ§z è”üò±øRÌ¢'R¢Y›mðYꪂ æ&ù8χ¯Wry.«oÖ ô |ä++{»s*º÷1)ÔØz3ÒMÞ€Z*‡¡Œ¡ÝågøjþU9›+ÙÏÿÃw\mY2*ïFu w7ª”òiñ5ˆ7xK|!Þ£)€v´1R ¤ˆ’K.'©G= EŠdHNqŠRÄ(!ÀAŽ£åx Ž‘Ë,¾E—³å4^c5x«¥âIñ2–zIé¦ÔS^Fq?p#÷{®–ô©\)fZQPø¥3.¹s—{ÝðŠ2¢Õb'õEL)ج¾ï9±û–ùÃ}‘è…_êÔgTqZ`eùª ç?<Eçýæå¬¾èúÚàvœÒu#Glî¬eNjºõ;¿¶‰œVšˆL î²O+µëj£[üpn+â}Oi±ø²Tv}J÷;u™¼Ñƒ[d½Ì‡DÈD&iÏzCÝWÄ òC¥—øS~"æˆîç²2½¾þ̶›çÌE×o?‹÷fà‹Xaú eVdò8S‚ű4ÌOùø,7ÿqY?¤ßFFú'OBø³’}#™êò±Ä7ÚZü®üÚ~—˜ÓZÞǃÎ×έLu>˜©ÈïäN»C4=§³½Žþ¹w8!âÑš^‘¼oÄ»W¹Ê–øæC¤¦ö ¨iQÔ ”¢ó^'‚é –_a¸ ÝmÙT6a‹ŸA|Èh2ÔÁäIz㈑b8!J¸Ì9<ùŒGŠß9…±|Š*_e0Gþ ² sAX»Ä{¢®Š”¼ B{DÐ@^b>ÇìP4Ûù.~ïÞ†ri‰| »øzÕ¤^þoz c ß×£Þ¼ÔP–eªˆÙÄb—ͶP2C~…{‚Ó¡h”ï.¸Ü57I%ú'Ä·dWõš¥b?%€ôݨœàõÐwJºïV6){ò®÷JÝ%¾ÔÍT— ó9Ç_g=Rm 5J .¿‡'ƒd=ÎS¾æ2¡Ô¶ë‘PoRvò¸z=ë½g•¦ª%')å.ù™è­Ttû‰mÊn±EôÕråóÝ?Ä9Q^®æ#—[ùM Çd½hFJó…üƒ˜¶"4ŒÍ¬ü»ÉLD¯“}{ìóÀ ÔòÅ5”ñà}§ìYQLç ñˆÕý­v¬!ÊÍ™iLÙH‰’v›ªcyÞKøNÑÔ{Sk'›‡õqbxêAÿ(ÙZó}¦>@WÓ}/Y…ÚGAKùBÿÚé”~AüáF²jÉJÆËéérêKÞñ·0sƾ ^dk2„êÿĉm(‰—cœðÅ/CA{ç(U?ó5DÏx?`gGÄWÕÓ»#4H»@,t­¯+çƒ!Ÿ µïhgúe‰S_ù%¯—w”`Ö.¯n^F †—*Aô åP— @upMœú_ºò‰¿ÙõÿÄ•õåJóNàn‡Är$&É›àâ*o2$«)›¨sa“r–_c÷Ò©l©ØU˜—)cvÄJ~bĈíSÊAì;å~(.P^‚ËkŒêpq¬ï8Ó-Ú _ÍY,>Vê˜û”Îì–úëq´ôoÆ»¾ç‹_(·çÆ.ãõ eèZiÅõ5„–Õ¶rcÚsífÞÇZC7íŽV¿òws+w郭eb²šg&a̱Ë6–ÙŸ‚oÕ¾¹Öý Ö?s;°R?íì!¨¯±¿ÑÙ½„Pº:¥A)í g8»@kFwp¹O÷³÷ˆëì‰ Ôš ŒþWŽþ™à¥ç×æÐ…µ'Ú°5ÕÏ}ˆZÚðÌ8R”µ–ƒ,K{2â5¹øXüˆ.ªs)ÅasŠDÈx‚ÏWÒ‘ªVž2†²ÞÑûHÈVæ›èÖ5å”õrÔ7ðÛ—ÙLÀZêûáäGÀn¢ÝƒiÇ_#ì¯ÔO02?ø—BæucX›|¹~Øÿ(ÓoøVñaº§ÿy© ù2¾1ð+¿&Ž;2?Ó%ðçõ¶—ú‘¥‰›Ý—蚸K™Èmæ›ÇËñ´oêÅlÈþÔ(‘¯‡~WÝtRýS;WX”=4õ%7…ßNæS=8&ù&vð&óVôÜ‹évà?Ÿôƒn9¿@ddjh—ÍèÙnVOþtò&Càٌķz}ÿXÔ2ºl ê’È›ÙáåÜ _–_ƒ|Tݳü`Ýä¶{‚~¼=²¡œPªAfš f7£޳F;LÊapÊÌ÷çm7[»“ñµ¾I¼˜®¸›©?üƒ)²~ ¼È–kTr_Lû3w'ÞçÚd+}R¿qŒÉñ÷íÉØ‰JLC·–ÙÛmfA²n`”|íÞ —:|ñ'Î ÅVŸ³V¡é5øÈÖσ±Klmòøµ@!x§‹Aù’ã|6W ½Dr1®ã-@Oˆ S²—ïN4püÎ"°¦ÙA¶Tæƒûª™­î9p“ë¨é=ò30ˆ d¾ã#H!˜¼JT_„¬YîjÈ}$D§ñ dO@¤%_CÖ+òvdxH‡/k½†jˈàOŒ4k)'üO¦žeo¨¾¹œ^zm³eü­_PžV ÊhŸ:m 8Ï¢¨_ºg€êr;äÛ çÈA 6)+AÓ.’/’ɌлQÂÍZ?íŠÚvŽfFèçøÓûÖÿsÓ/6“Lß쉗|­¼ 9I©îb7íåì*ð Q¾Ö1çˆ6(k¹µVÍ ´³žæMfÚP¢¿n=C4ÐÊ*æ@àæOß@».e|íÍQ­§ó&å}#RëˆÊrÙëÐ+jú:öýíEtqöo­±·ù8›w‡’GPn¨”S×Ñ©"Æî¬Ãw1¥Ö%ì(U pµ™e= }^ØÞ@â€IDAT`ÅÁ¶ K§7€›åÜÅÀS_êã8š—{ӃǪhÔÉú5ëcˆtPöP30Êîͧ‘„I³`Oõ„ý¢Þ_Ö!e_¦§rheæS "¯¥úSÿ!ó)íC7dîd޾8ó >©Ì³ø_›ÍAâŒÄ Ô0ƒ¯w¦ šÑßz ´:îàhkXÚùŒUÝ –£§RÏ€2› è½$¦º#¶ƒŒì™"íÏÊüˆIsg..?x×"„aýFu9”Iñ­ü ²›’Ä'+è— 0Ðhºì$àÖ£;ªW_ìçsîk»±ÜþúR°Qoë²®€µXÛ ¦ð]Vuã Hµ tk’vÿÔ¿;Y*ô†Õ&èÃN>¼=¹1øO•|¶Ø›ñX—Ülé^ŒÇ”ÛÜþçÞNÖЙè¥Ëbi©¯‘ËJ{ÍÄž2Õ šór^û‚O ôñ‚!÷Ã’Ï!ïÍ’_ §tÑÈîQ…¬ãu Úºð'ÌÐø¢šX‘kS"‘ÿÃÎ0ŠìzHc“sBî9òÕ‹¬f¯Cò±bbËb4Y¬—å Žò‹×C-ǭέz;ê8 ´H»±Û ú¶ ¦[ú'¡¦^ðéYŸAü¦¬ x*{$¾Šä°¯08øỺ5ÙDÕë2ÿ¾ýƒüÎm¹]±‡£‚9ô×û ô~pNd„ÞS¡KÞa²MøTöìWÌõ¢q 1rÚ'O19ô~ê:~Íiœ¬ËìðÆdu²³–&¾€ÐÙØh¼P¯ô,”È«Émv¬Zí¿‚$;AxJú'j¤,:Ï$ž`Jpjb¥·Ú7!s»ÕK›"½A™ÀïéOi^f£oRæ.ܼ'ÝŸÑ_Øwƒ2Îl¥i ü›¨Ñòê]P6„SæÏðd(S6«1ZÎס 4ó®2‘¯°˜¯(ÉGþ¡}¥ áÏÖfïø$õ{W<ÎWPxI)FÆn0î†øÿ!vg”àT^sî 9¾§5íùòiåõô¦@on‰M-õ÷'&”þ’é3¾ÙñkÃuÐJ6wBñ¸`'(x¹ÔDÈ|˜U»äãÐ]è—KGº@ÉûYQ¦X‹žåRâžÈ ¸ô°ž4K”¼3í2tŒç;«y%IÜÆ\YO] ò΢$øÒÒß*ñ$èñYê|Ï‘»å‹ì š8 ",ƒŒy9 j»¥cöÖ8€ÌN€d_€ä‹™ÖÀsZïœn”u›ÊÍ4*Utó ´½©ÜÊn îÐjüûÖŸ¶àÔÒKoQ¼x4;œ®/NóYæ]yfæ€1€L°¢òÑÌ÷¢ŽuI¯ƒ&Ï)‹Ù¥ß#O¦ªOʽÉÙª3ŠÏ™íÅ÷Å7—âÍ 7Øœukâ+¶å¸ñ§)=–\=Qü2zørª"ªšrú®€À¬ô 2Y3_âKÌãr°Bº¯†Œ£W0;ó&úÙÉ\«^V§^ ÕÍɲ¼/²ÒÓø*¼È<ÚhŽÅÈýÐ AXõ^Êy²:0Âû”sP!þÊ~ŠBé§"m1£þÀyôÜ­‘0ŠØ"`RL‚² _WÊú^™UŽ\­²pðÊüU²è>¯üUÛæJ6Ì•}éVô{À_9+YTå gQ‡Jû§³¤Wê$FÉ}éöˆBʃSuŠAÁ‹fM¸ð€é‡Ìru+Ä“êûp)—\c´†’ºþSØÖë¡ÍèæÁJŒµ†G~’(ÏùïµMe¿ØŸW~uâ–>É ±¯ƒœ’óÙÙhñÑÁ¶pylä (¼7{<­ù×çmƒø—ÙÝq ëgŸfZA Ú§O=›½\6»l(sK.å|…íM­5 ÇXV±9÷ûnÌ醳ÐyC9iÜäîÃDK§­ø‚„{‰!FÄí­m·ßDWÖ2 ԥæbÇê«÷¢ÂrCü·¸é/—Êí4×ÉE@<1YF65$9Ï·S?C„Ÿý÷íÿ⛵Ά}ªõ¸¨ Dér´Ø^ZäT¥8Q÷<8ƒŒ ( Á|X} ÛªÞv;­º½X;‚㪆‡kWÛ¢˜?¯x'ÅEjÇ^òãVw©8í¬ùþÒl¶¿ñ»T²n×Ë"ãc}cÈ3§‹”œy¶èmn¶ÌÄo´-óuü ãò–Ækáfå$ÞAÍÙïáGSû :/þ:„*$Z@ð½ÔÞ·0C”<ŽÏŸtp8š©K‹à©<:îýBÄWÞÚlžÑî×Òömâ×èæ T5ž1Á‹lrþ@1úºaÖt«ƒßð @[êµå”·JYZsÐ:1¯ˆÝPús œB·È22Ç›¢‘h ò‹AÜGà]Zy”ƒJìo™ ÍÒ@¥#nrÒ<Ê÷ ë€4õšüAìL5íÄWC¦²q+¦øLŒD:ð«Ý“>áÔôW¥]Zªßr>žå+Ã'ñX`VìöHuŒâaJ¾Èž Å箆’ìœç $–}+~âž»=ï:ÔÂ)yÕvñ×ÒÝ™t黓M8—¹¥Î`Ô¸>éôŸÊ=èâzù†ÙQ9â*ÖÆDç[³À˜ž6Ø.:Óy!gƒ5ˆ%j»23|KÍ[Qižg¤>Ov Ø“y”0‡œ èZR ÄòY·£j뼞¨jG7Ô%n[Ðv6x› zÐ;ê!kx[{τצƒáÿ_íü_fˆ9ØôNŒã@ö§;?¦O¸C(Â,u^` eÅ*o'Räò-•Å'\Bã:Ñ›˜¡\f¹´­ûh%[%/ÒÓ½&Ø™^[ÿ×,ðJ.ÜC;©Kù…(fŸÕOMQè”Ñëã³ãþ±Ttɧ©é­—Ægæ«û0í› 3&ô Ø'• G$„¾÷•çšä½ÉñµœUÃÁÕÚ¡;°| ‚qþŒUŠ ¡Ì=ÁŸ½öºÀŠì`z¿ºÌWQ®gy¼ ¯¬®wRÖ-S0ˆµtò;îJö(çÝßxN½à¼Ï7êCöQÐ'™O¢¥îHmÅdL|Ñ_Í× ˜šÉY™Á_Úúä#æD3k@Á æn…À¢Äöêö»ºôË—ÏB¢£l TeUl¹H¹ tô^+…Ö·Ü3úýà4Òc˜ÖwÂÂ0—“ætß}.å/€ôüÐΦJB!i$W…Æ‹¡‰3Y•ù%öYvuž/¹œý•¨[´$«È½/~ÉW!yÉz“•E½yŸE—o¦1Ÿ_œ"›SçÜ7ôÇM´ ¯A Ï®* Ôƒy[°²ßƒ/ü±ówW–t¥kÐO&†îGØzU¹ÛÛ⟧Ö»êã¾ïÓOòqöúäët1eVópvT?.úŸÉ¼CaÈKWb€Q×¼“k‚³ÒQS¿`VC ünƱügÂ3ÛÐü3í=¨¾ÃÖXÒzO÷I¾åñ.4ÔâlãNcŠ“áýHÆ O½‹†\«/qóP´i‰/Y f•én|J˜úb ­ÿý€›ÐÅWÉ[¡ÔÃ'·×AüúH·3èÓ­)À Ú» &ØjÁ…:àÍ”÷‚h%÷ƒè%nÙ–N ]m ˆ…jO“­ ó‰^þÛÑ"º›驾† Wvƒ˜ÖÛgü‚næjËÉòo÷?O=³·ïF>±&å(TÆûë2Ô7,å ¯À·™2‰5ÁÖ¼áömRw+SBSÅc¿^ÛÞËWºŸï@<âNA¥kr*È#jYð¾ÃÁ"¿h¤‘\ßHÜ©·G×wúû€ÞP†@ª€U¾h(Ïû™¬ Üa7­£²ÒЇ"¼«>š˜&à2ð%® ïÆ·&Áɰßò+ `í0„ô)!S™ë ¹QžøŸ< æv€È^Yw"x7¨Ó…ÊZÆò­b1Ï€²â­ *[É2‘áZ&*o’0þ‚dž¬¨ì±V‰?ùÒH\à’µJc«ïq‰ z7µ?…ú÷j{t}–›&¢¤¼3„Ìò#’b%Ÿ‘¦¢èÂe¯ŠšFõÖª[)önÐËm×Ñg™ý¿?mí½¾·PÓJàz¦&o3¶¹MWdQv‰?å”J·ó†ñ]ÒÖ\-¾5³I)ˆÎÍ,ç”o[ú ßCf?Ž6Gâ÷¦㜺ŞK¥`‡ÌRêhQ{ Â÷§ÓüSþ _²^íÕÌ4ˆ\•Ñ©ü·éÏ1Þ}?˜vvn<è3.­Ó*1 ݹR+ÇÊ&I{ý ãôµ¤ÔÎû˜ò§‹lõtàY„²LÔFˆ§øK “·"d7[ÅOJ™H–WMk‚ç‹Z"Üéi(^«è1°ï.xŒOg’v¬Yî0¿‰•eŽR’|xÚ—mRjøJ%v±K4u½+¨×ÄCà{Ìw޶Ëú[o«¼FP{6VB?õ)öRN—þ™ ¶õÂPï fh/øQŠô/éΠ‚#$•úî ª …wä¢ ~™/Û—›KhâUˆ®åOït¬<ž»Ø¼Å©¦fƒ­$wƒ;ÚÑ@/ïí€Ì;ñ‰ \f 0NÝžcuïKwXgåCà¬Oß öƒr"8UÔ[¡(¨í¬;ŒE¢Šo”ø é_ï¾ËG[ÜßMÚRG5«B_¨m [àGQŽÚƒç¤|¹ÕwÁ¼ O<žÚ‚#–ZÇ0ô:î«ÀÔøyp‚ÿm·è_˜‡AkyÔ ±{@”²sAy4³´ÖòPçfní¡tm<µ)çQµþn6K”wågr)[é&+¦Ÿ¼–BˆEoʉõ”ç¡q—±åñ¢Óè²jàM Å/àÕu$8?èqpê¨ 8£CÁn öÆÈ‡Ø^³h· k;ª53»éôãÙu$&äž@/©”½K-‘7QÈ¢@™=|pâl¤'¿Ä.ð&.~þGºÑÚšº‘ò5ä7' XŒ9Ò¤üñÝÅ=&Š7Ïî¯Ø€æçÌ)•®UtÒèzÁµ¾áµãs¸‹³D³¨¨SånFgm >Š&Ô‰Ô‰|k^Ïáyò0GÃÛØíUñŸ1îIÿ TЋ“™™56õ)£CêvNgÍI_O,\#ÕŒÑþÞém¼àoŸy /8Éú Ÿ$—ck-í¯Ñë2ãÑüõ2wÚëÀw›û$ø¢Éc Wd)†ÞÕÞBF)­öͬäFµ‚^—úùø-\¯ Kï–¨O¶r<ö¥(ã¼GFœóZR¬4ä2MÄ7⺑ËeFËêJÛ»Wûš”Õàœ7Ç[E¶×P™Ì§DÓ˽Æ8Hw×õ±­åZº}Ú°ÀþÓ( ™7•Yéö‡âVÐrüAzJØFhÕ2‡1ÔW2ñâeij[ZãÁZéÔ¦‡‘ô6rÃ)+ªÕ ÞÌÀ ÷þp OJW/·)0éÂkzLå¶UMfÈë¨(w˳î Do€¨ÅQ÷{ª(›¬À‘ô"¤Ò't[ìµ{¢i“Âa|ê‡òû´£©¸vºÌýÂWJyƒÝ޼ÅTç%F¸‹"oÒB¾™²åñ*ÝÄa†%?’epy†çÉ‘ƒHÏ‘Ÿ‚³Q6w‡lˆ™nª>OŠUÊ.òÒ™s zñCôŸØôµÃâÿhnÀ <ˆ‚ý£¤B5åÏÆDã”ýV8-¶'¿ÏîËÑ’höO´)z%ú ^ñòܳˆÂï³>gûÅ—ÂÛQjà'šñ7úPЬÍõðëÞóὂƒ=Ëô㮋äγ. •MåYCõïÝÑYë©çóJ ðöºç-LÖP? 9ñA¬2Ç·cú6$Ó:Z:Ö‚¡V‰54 ‘)‹ù&1BãÍ1‚G’ïAdˆ ž“*O0´(ù:×ñ,&ëÈí¬ IfK º¹Ò­c(î³Öae¤Ò>s–áÊw™;ñ‹[3ÍFq¦B;g­áˆJ×ãøÝnjÒ®‚š|ÃTA<à\´/AÑèÌõàÿVìÏr àȇ™s O Áîc~ N_g;¨ëÅІ*+mòP —€hO3e„©kœCà–rŸ=Û˜Z;_7pÚË  ½ ·±W_Ö4e)øñAÑ’@‰þ&¸-õQ徉¾™tR¶ú›ÒOýy„ÕƒÅaÚRmÏ®WTC-£vòfõaýà4èod²<|…)Á—ÎÊÌ· GV€¶ïwHF‡dËl ôKÞ  Êc8¾ý9*ZöîÊÕ™?#Ú‡è±Î—{0*gk`wÄ7GÊï²'‡lÖE{†‹CÑ'£ßòTDÈÉjø#­“— ølúeNÈŒ^æZð72ë€ÑÓ>„0¾²ó𴛜%D԰מ;”O½ûi,rä±›ÊÇ\–»ÔuÔ÷6«k¨çÞ¦oA8'ôÙ`mö-DX7 Œtëàdd:|–Ljy8J"y4\VŽ?¹“š±Ѧ¼ZRM¾8 w‚hÞ|0àoMý6Uɧ‚Oq– µ'ÍØÁÒžŠæÛâåR#pBíçí6Kâí`¹x:ÆÅïaºoy¢/õÃv¼Í}uÉ´JD±‚ÛJº£ËeN¡d?™Ü‘ñDZÃ¥ÃËú=Q6áœtžNŸåîð¢d]Ù%xÀég¶Õȧ“õÀ÷Jz&?š¿&^¥‘ÍÔ屨Èä$„6Ý<‰ré…dŸg&‚œ—Y)§¤?F»6„ëÊ,ðÍôj¡ùxßÑW~CßHs}85ô[¨D‡€­µ#–ÕÝ¿‚æÁßõ ãK¹ÙßÐLs•öÔñÝá«ÈýÑw"?))äNjS—GõCú!jÊ”LQ–ò”G!< ÙÆ6j¹¹ná>n¦ŸóyÅOÅnïYšYÉê™!tNí2R¦D¦¬/˜¿9TÞÀØØ/¦Ÿ™ ¹6}—hCÚ­ }?vŠ>ˆ’žäûy ÜæþP÷„Ë€ @H7pˆÖá,*ÈCwÐSúÍè[Y¤£4OчyãµRÚ-î ¼­}[ÀÓtˆ®"m–FÓ·fíuIöJðÕ’7Bb•…n´Øvg‘®_oÅro‚1ŠÉÝzë2ôzXOžÒ[ DyÌËÐÐy×;D;uÄû(w"Ìï(¤´9Ûý€‹ò ‹ôk‚k…ðo‹¾ÃqaÑßµW"»ÄYÙ× ó±»DNç71Áߎrâˆï~.ÊÇŒoˆ+ñð\÷ ß¡â^rÍmSŸ)¾Dž˜“x› LAç/~û¿gþObêõ.t 8w°ó= âÝå×óÿ8E*dÈ–”Kw%œIç÷¡i½”ðg>Ó³(Êþ@«"Òfyý}1Ò_ËÈåÎèB^'6KèoëÂóÊÔxÊèJQWm“Ø‹a”OnƒðC1B¾xcä?‘WÒ7¡‡?‹N“pÇ’üi”˜Ì€ðl}©5è)·$SlR':ó…2&y+·¸›’ˈqmúmMÎF-h˜l§þL×÷×Ô[ [f²Á]ŸØ¡Í²1èŸÚb…êóž~­÷<þœ#¾Ã4UlÇa”ÚB4(õSd&ãseu£7‡SÌ׉ ÜGð[H„®å’œí~d• Êwr\ä¾È}bdÖ˜¬1âTÒI:òÂY…³x‹ƒc#‚¦*ç•ûĶ¢ëKfà9¶§S6Ö=é§F¬~úwöÇ‹3­pSÎAª[ÒŽ¹@¼€Y<ˈ‘¹Ué‹HORš@êHŽÑ‡ƒr]ðQí‚OƒÞ2« Øc‚å@¼¹Íæà+ïÑ‹oyS|ŸY©,7†‰•¾ñ‘êÏrÙùÜÚŒÌ4‰ä ˆ·¬\pïÊ΀Ì-Á½Ý÷¸!_3°*e:@ v5öµ7š§óhqÓ*íåÜRœ¢ÈmÍt'*µÊζƈy\vä‚ïisùú1çýìÅ,WæÚ/RCûØ)æ¢ö°Û‘ Ú%ïA¤qÄÚO®ý”Ò'TÁ~xîÇ™‹”NWÐÞ¤V°ò*žñŠ8J‘2•“¸â4Is¼Hû¡ª÷ã(®ú¿ÖùøßÂ*æ¢vÓÅêlÏ ˜«ÞmH ’¨C€ÆÆj¢Þ'^+²Ü·2&†³ÖWš,1Ñ_—,o =a_؆.Ÿƒ¥ŠžÝØ÷0Ž{V½Ã|ÇhŽânÖû0Áª®ûð³Œã(f¶o2#íújI —ìݾv8‘ÇÓ™‘¬äÛF<¸ ÓN/ÙBF–,Æ•Jr‘ÌLVõ±ØpД<Z~úð/J´Å–M–GöŒOe|hAúüá¹É|>â¶dt`ŸÓʹ[?î<—þ„^Ýt-\­A&ĹÂ'SOSU{Âܰ†eî±Çú¼[ÌŠ Ö5àÍ6×€ºÅ ^³„¿UŽ€RÓ9Þ;îuà¯">å}¹ŒÎjO}½Ö *‹.àî–åÁ'K@ü¬v³D¶†Ô\ï'ðu6N@q÷iq½'¤ú¨ß'ô) ³|“A[äÕÅ8ÞF B•1Ìt°3iu’÷íD+1FÓÜ]Fÿaƒ*öÇ‘Y`EçQõÍ^ ÔuŒ–eÀy&ø˜ãÍùüÖ=Å*×£&Ïhq’Ŧ3íò·þÞòe¾”u´”²ß‰Þ~ý·æKJûð—™·p5#Ý„fjkó)žÈŽ›ù÷¿`£h[3Iû×ÚýxÌ×ÁjLy=m)¼lüaíDÑÙ¯àøopÑÛaý7Wkb ÆP²¼þØF«?Ž:•2J_úr^?—Œ y7è³Iªiõ"imqê—ä2÷~Ú¨s 'þ›î¿<1ûXªÿdb¢ù¯)MÅ/ìLÜ)Ác…(”•µy‚‹\FÒI¼‡!1b'C¯r@©ÏR¹O…»Š–‹¥2ª TÞöNSNÉÄJe»ÛBiÀçæÐ4*¸­•˜Ó|:;Ì-ê0Z™V 'Íz6>SÕFa¥.E 0;c3!qÄ_Ô–¡ñ8ú‘à*ú¤ö0ÔO}…Po 7¥¯Ô,ƒN"‘^Å›æøÈÊjmOÖ Áëãõ—•“Ê%â±³U_d_¦ê‰þb¹‘—ÐügB#Ô5Îû,J{ø Ëò ¸e p²ÕáàÿÞm n3/ î×ÊãÀÃÚ `<é…À^ÎÍà SXÏ&Õ G+?ÛÀ?xÍô¾ØÎ0}2Ò~W"­¸ÿ|fo/JÒç‚öf œæ‡Ôc¡¼L‡ëÉù‰ZÙ­DâòÑ]””tŽà«’`èA‹äó¾ìäÝV;ñkÑ`ù=o]žÊc¼}ªˆ¹üzy—!¨d¶/ÂVëEw£—¹Töaȹ͸ˆ™…x_èDüw‡T¾£lx¢úC#{Ü–²w`®|æˆÚPÌOõeQ8•ºB5’8–Y¹Ñø¼ôQ£/&>ä·Ž(â=g´ða›y‰ÐÕj{+ˆ5ödPFjS!ÞûòhÈ6 ›ƒªñh#ÝC †™óÁ·¥Q`¡õH#Uj/µ=(qõ/Іû'ƒ•ŒÞò#µ¤Áq @>ʽÈ\­œ‚d}»uÔÏuÀ;–nlÔÖƒò޶ôÕJX׸?C` ïi`¦p@ÿF~¢½û4D 10›T? U7¦çBö@NBþEæCì,]!g¿8†H6a9$«ø„[#Ébv%¯a¢èüÅþìÀ<ûvã’‘ã¶p^ÑßKsƉÚ*»½¨Ô^w¿¦›þ¦[«–¹PÅV9”‘ò2ˆ´â‚#ŠÁõ©õÁËS€ÛG[¢ÝåNIoQwZØ‹´UöYÑ^,ö¶…Æ2O–Óõ…¦ùšïΜTº–r(R/uŽòàÓ‰fü ]MIÊ"nj7#C^j:Qß"s !7«9jøÉ¤jØ>F©^ ÿ&_“ô# %Íí Ÿ*lYkù˜Jçÿ´þBwÚò§ÕP]̱âK™¯’Åwõ0>²Ä×| Õ“|¯V&c±:Û›Îwê~߇¨J“ä#ø”Ïã@dúW‚(–÷sÕBL6ªA|ÞãÑ]ôó>4ßdŠÜžÑ—¾ÎVež›_õ!Š%ÜûÁAÞVR\J¾õ°Í],WÞû}Ëš/Ø‚ â ðŒ6ô=ÞÓà›g-Ãï®ÁÖç¤oG×W¨Ïêo‰û1´žî‡¼¯ié"*´µ©ŽS¶hg¹WüU¾J>¤žôv˺b›o·¸ÊA_©|˜g”™LA/‹‰Ýòw¹œ_Ççâ+9_}Ÿï½Ÿâ…àÞè´G±¸sÁùžÙ mU>…tí+‡ÁÛ¥Oýz¹œÞ^_ð¬¤Õßù X'’_Aêvw'D3é±%\'3xRù^]H´OûÉoù¬¿–ò-ÑA=Ëpï«ìsÙë£ÐE‰‰6^RVËMn–h#>pbÓRö)qƒÙOiåHluŸù;ºò–¢‚×V¹j]ïuŒ»cµDSÞðò@,r/‚rÄy ”…r°Æ– ^ç{y‡g=ìÁ PjË"›äMb—©àQÑRÉÃõ‚"Ä×ÞÝêó<ï>XÁ!çªøÇžèŠbÖ ¼‡k®õ½Šžú$…dƒÐ <n ±¡‘Y8±£A”h(kve÷¬—ù£ÊË}šuÕ93e÷òò‚ýâ’j¬õK­Q%-ڟѬº_UC= ±á†ð_Ôdïÿãû_¤·dœõÖõKEáo“r¾á¹¿žÌ«çÄËs2.DÇE¿6¾9ÿ£ý egr#U…Á©œT¨q-­3Þ }Ç“‘'"íboÑ8<‡&?û˜þ^}Ü*ô¿ª$s9z>¦SŒÅgÓ/¸;±Ÿl¿H5#7¼>6–º¾Q©[hº'9;x,Õ=´#ù#øÛóQBרMÀŸŸØ¾ƒVsܼŠðu·Ê1ãÎÓ6Éëé© p\†o ƒ‰ÚÊô½¼kìõ¶ÒA9àE jG.ÿÉjÂj#•éÌc¼¬~&?a¤Ø.§ÉÖtæ"wq–…ÜD ö‹¥ðpA’rÅ[ò´;„OÝÑÁ¾ô÷¨Ìr-×OÚÞë·°õ‡Ñ­^ò°Ö…>kõA«ºŒÒê2ˆ‡C'}'@^H¾ ÎÛ‘Ýà?b·´‡áKÌòúâ:{ÄZ{·)Ýä)ßõä¥ó­ó¼^ðÕVVQ¦$¯Mÿ8_¾É;P«Uä—+¯†Ogõ‹Ý”sNi[¹)s7Gï*î)[&üLOõfŠÉYUÜŸN›Ò(éó»$ÓøƒS}Í’Žßðpzµv‹ž±#Õ%ø@à Ëo˜¾î³>jY?=žWh–î!>ì߉0Âòxœ1vD‰£Ê¿îLéÉñ(ñ§¥JŒÕb)9Ê‡Ú Q‡jzR¡×£—\a|Î$yÕÿÙ<á»âNßA¹S{רêôÓÒî2Û„ŸP.$jf<ÄìhyVO*ª3³Þf|eÃÜ…|Qžó”ü¸¼g~Mv–OÊÿžk.~™3T¼ÞzÚ%ßø3Ö„N+cçþëªï:Ÿ«I_‹Ä]^Õ"å?›¡P3£{x§W;ø‡²&QGyÁþ­jœh7~ò׉=ƒ/´ VƽÁmñoP2Jªûà†çVFøjšC!R˜j™§¢oc‡Ç%F Ÿ‹ mhsº€Cý“#îéÖwãÆçšôkÊT}|z!÷)'’³¸Ñþ1U͇ìJ>ÃFåˆùO¹íS‹ˆª–K#åû;®±ë¤ÖÐzUÞiý²Žåy£ÕtUæ‚åX+Ÿó1ø—ËåØ,rf¡¦ïN6F ßìŠGØýìcÀ yP‡ãÀ*y”[”‰sPéeŠpªö”·E×n ~ÆEí ˜­Ù úóþ9`wKÁi¸d¹ÖÜ…FW}5QÅ2g[ý‹”zÓ8ƒëóKL}Ph >kWª’•¢< Ì9áÍ"áT„úú'‡ö…Ê·Ê]¨üYŽtääƒS’|Ì–‰$hÉì/AŒs—€ö‹ö .·¨!½…¾ƒ¯«ùØ+Â+蟾Ò` sË®¯£{û.¼]u‡Xš«è+ôìÓ·ó^îüò%²{îßU?Ñ*ëÖès<YoÊ‘/â­D8è&odDè\ú3ÊÓ jû{[µÈ1Tk2†ÑßÉ#WûÃÍ'SÍvÿæ”ò ÉëÄvn’“ÅfÎ{õì÷®Ó^ Ò>®¥Ø^ìû¿ÌÇ}ßq!ýzpˆ¼”z5|ʼn¿ÂѾ©}5g +öä}$Òå«sïâíò#9ÿBуUaž0S½èê>I‹Ô\îµÞˆŽýU3ŽâÔŠ¿âDj"øßt>ÄœJf ½wÓoâ¤_¶~A‰ç¦¾e’w<=œ §aj ×¹¯¦N0Ñ™™¼à#íV>WF»¿x¶~ZýZ®t3lËý"ôPà’tÕû´ÕnO³wºÛMÛ¬}êM—‡ËiÃFȺlg»¼ ‰Dã gò,Ï Ÿûš»Hy9þwü,·²‰-ÊTííeuErQêõSç7÷7åOg«¬RfxsÕsŠcO%“¼gô¥L³×*d¥y`ˆøšeþÙô5–†ÆàQ˜¡=™ ‰D2ÔKOû¬nà½h× > ö0s 5”¾öh†Éo½él¶—È.¼lùx€¿’ë2Þõ¿úZÙálLΠGj†=œ=¾6ÊÝXF'¥†~F}”ª ÂÐ/€Ù8ð Âke¢¦–Ù³˜SÙÉ}†ö•³•.(Ñ"öyWãßãØÅ2 ùÓœ–4ÄKÒæ"Ü 5Ž’ÖR‘0uýj6¡‰ïpà^ªõŽÁ<¤¶Ù=ŠPKÔÙxJ¥#íDGH«A㨙ÞÔUlõ8º\aöBc7¡©ZžG7»wÁw¸öýÑS˜þ»kà£.ãÿkÿ7ëàÓú”¬¢Av3¯1O…ºÈ‹À]ôGÚ ŒÇpƒsÅ_HoÚ×n¥žÀsúøÓEÎU7a$§ëóˆËßõ†´Kýf Âðßåî…Šc‰çq«‡T­C¦ßJÔGÍÞ_UÊ–ŠŽÀõÕÍ@Û ué^ˆð¥ª›héû‚#mÍõ¬Œä¥KÒé·¢ØïÇ&Ò‡ó±è?MPÿ'YÄålâ3 šl‚Ê„ ÔN^åµT-Ð#Vhš}¬’XgìøÂxW¼h ó'üÜ—þ‹º'»Ç73VŒ·+î™7ò§üÅ.—u´¡b‰7ɘ«ÕõN) DÀ›/y;½³žÊ)²ÒËÒ:CÉ ß˧€ï¨SË©%wÚyvOk]µ®LÓ뇕”ú®ºT}SUUW=Yu¬j™ºª?¡š‰oRƒ•ëÉÅÊ*÷°h¨¥ßôîỦzí{‡Öú¥àãì+‚ó¨ëñÕ_«Œõ`1Æ€~4c=¸¦ý"0Ä™ fž[ öÖ~pz¸_"Ü3òvÅÏ⮇”ÛxÈ[è“ûõ곕˜¯^uâ_zˆ4•Ïè)°Ž×ùW é°< M)]ßÉÛÍ¡¸I¸Û÷”ÜAË6W¢O(ƒ›>ú‡âÌÓΣ|¯Ï·æÒÊØb樸Åòñïfk× ÇÄÐÀFWÇó¥0•íh¡vp~C¨¯ˆHýh¢ÕyÅ÷ Ô–… †Ê›@4­@¼çÞ v›ös@iÉÛÿ'@±¥ªw<š¾dR´™tZ‚|¯2”G”}ÄÜ#‘ѽºÆŸœd[¢’5ÖCáRzºKEºsÔ{¨ï´Që±ÎYbë5‰g÷ôM{˜Z éþ{pÜ'ŒÉèéˆaópòýà¿â$óÀ±¶r§o¶$øêû|HíIëSœ«…ñÚhÖϱ@ÜR9œŸ«Ne±0¨ßÆ—ƒnG3Pý/€?7nÐ5`¦sCèר¹6ØÆÚniÚ-j*q„×ÅÁÄf¾ñ=”zž¬Å©,êËz© &™O"¼êä.ðt®o‹y<Ì¿Á·ÐYÞ\»+8X10K½}à5·ïÄ&3 þ7ÅjÐÛ*ÿ‚·ÐͶòa2Á8«Mt¥ûD7?ã'ß%PÚkaˆÖUlP}þUàUçCàe_ì×ôÇAÚÎ.pwÚƒx/0”Ly¢ÏŠ%àÝ¢Tã÷fj )K}k,$_ËÖ«Å·­hÅÛγ»_˳Z¥¡ù`uÓ¦9\{RŸ—!Ö#8ª’á"ˆŸÊr°J·PE“Œ*nÍéê<,²›‰–èkj½`ž'Œ'·sÔÿaêž¿¯}†©6©ºÜœ~”bè-¼.ÔJµío³+ø¦˜ðŒ6V]ÒZ™w ¿_I6ÄS7)*—}ìoÉÒë¤Þ¤–xBüÁú"ù.jÅ7WÎ'ÑW3¬QT©»«3¨/󘎮ö ")ŸåzþÏœÿo ¹…¹,ŒÅª–È},5‰ùñ!öH°2½ŽHv1œÇŸÚ܈ËFQŠC”ndù&«QfÚYìafùÓÊà{IÛ,°‡©WT|CkùÜ]ªÍÒt3¤Nñ½–¥·—ÛÝ ÚæÐñàL±Ã¦ÝO‘i‹ÒH7ÍÔDEêuß\rüê›b'Ǿ@Wß¾€Ð„f£i¹¾§òjÆKx^ÓÈ T¯Ìzfn‹”‚ döA7,‰\T*ÄÍéÃŽ¿iÉ ­ÀÙßÊMïï1©ôu§þ ]ÛíñDäöj¿S/¥ƒÆxq 5Ú¸‘Å™íå2ßYë›'2ùÆ>n2çûâ4öLvAšWÍÑDüw˜“È2Ö[?¢§n²›cè¦3Mm~ô1n-„ò¾w/ïˆp•ý Dò§"ámVæ’v«Õ ·ƒ~œbûEý i»®QÄ?f{ÿ3œNw¬‘ÌWM™—Ð#÷‹éq3ã" £©ÌÖ”VG2Ç 3Ú=ð]ìj|–°­ç´ÞU¹Kyºü_žbGéó„éw) ,»øƒøœÓéÀfê„wgæáä$sV¢gÔjA†½ ‘#¾Žèýƒ!Ü–nLÎ8iÕâh¸‹hcÿäû2ga|¶ˆ©o&§3&·wõqn0>O·§fÎ;ñÕÔð÷O~ÏØŒhÜþ’t5DZÆ÷B`€]'üBz6þ‰_ƒð¿çtÁÔ’Å,ñ/ˆÕå[ã7o9ÛŸ¦ORàÿE~Nk#ÇüTžÑý¼ÕOÌgízb6㜵âÛÀïî}ÌO¥ì|žÃÝÙèºßÝ Ñ ÷-ƒë>ÍÛüß¡“ÿ‡’sAÔ-/ƒðµÅYØÚ-j]Ý•ÎEh5ÝqhÊ[?±EEÒÄçå,lu½ƒï1 •ñâTÙÜø…¹2Õ|ö4Žy{ÖM(ÊÁe(îHk*XÕþ\p®° ¬Éêq0ß mç¤ÑôÕúH× VöµºMÅCâÍÐí¸ê®ÐyT5Û_ŒêÕÍJmßYîcEúyZòU²Z½’5Õô••]ÔUú@gåb¾³Ž°ÒYÍù€ÛdwÄgZq_ª¹"SsF‚Þß› ¾cþ;@ûÚkâzû%ÐÿòuÅEu)³Á»Ç îRó=ÐͼcÒÞ]rÈΪ ît$Ø“ÍQ ש ÖöH°KÄpÏhIpÖ«3Áí­­ƒÄ'éÆà ì‡ô:gx ŒEýÇ ¼]lOš›À &n¯Ô U˜Í zsl.„{Û]@û9Ö‘;‘Èœ¿¨"3c eg.Å¡±bÝ‚ɾŠÈñ–ºïfo±ÑÊðÙ Yª_¡¦,Ô.‰YS¹—§™.z—û•7ÙÎ~o—¸Sl` 3éæ½&G‰[ÝßÈo›ËÏÙ˜ì ß ÃÓ{åWÑÃøÜí„9õ¶>Rg´á‰a<ïoßÇ]ÔLc…Ñ=u‚nÙM ðéû“¿á–§Æ’øÕÂï&.oÕ‚7X³À—e>þßR¯zûø¯Möõ1ïuÈGˆéTÂyÊRr¤ñ(»´–Æ$ ­è¢Ù­¾ãýÁËF eëÕ¦úi:*»KË^ <˹T«Åu¢µ{ñ‚zXvEÆþÅ‘C+ÊÄÒ6¤._ ãuoåÕ$~ǸÙ~DLÀSž¢Å®tïzsØ‹í¨¯é€[’ø”ÂàL%!ÔÊyŒ]Ñ|ðeèß1•—°}ÛÜ+èú^q-/êß+ó(ÖצOó†Ñ'È?”šv©-Ƨ<ï&A¸ÒëM%ímâaùˆ·ˆÙ+Ý*íÕæu»ÈÈ9J!ï¸×‰”ž]©¾§N÷íÛ•–šÆaÞI}Š#ö>Es YÄŸ^{ànõWpgÛ:8(g°3RçÒ÷CÕª!öžøäÙp}Ⱦ½°d.~bi†ÎBg5د'žÀ»T³ü8Jlgâ+š—í©®‡Zó jè×IÙä )ø¢rop]h`:/²…õq5ЛݩÏ-QMÛwV²õ7ùÖSÆÃ\5ø³ihÝW]—,§À·ÍúÌßÌ?üI07@ðä9úÃà/°þCµpŒ³ö8T½µ“íFi2P™.à T¾f2‹x€-à­R–€Üªå‘rŸÑî%ä$µã`½ï» Õòü/ Òóü½PR‹CÍ!U.Á™áMTÆΘÅÑØâÌ Èª§³êÈhÕݹuÙVq(¯­8[v}Á &\]Pó[1äÊùœevªÂVY;vD5Ñ&·;-Ò'U‰S8"4ˆ9ìdÛ]€ÿ—|íe_óóöVùâÃ?ú>ºZ~þnñëÙby àb4þ‚…┺™^‘;ôÛéZ£†ý(ž?»r0®±Ot$¸Öøž^¡lå3¾ -·[ùþ{‚¿Äzq$¨FWñ2Äó¹W¿mÏ4µ2Ùãc÷€1;„Ȩ˜†èmEϼ’¸A¬ ¸<1üMª‚1™7!TË@ó÷³_Çñ5pº0Þˆ?IÜWÏþƒŒmb-õåCd@[Ÿÿ³|JUy‡+E'ßJ7%^Ð[Ê·ék-vk¢Ÿ»Ù[Ãh·Ä-a4¹ìN3ˆúê q(Q››ÔmJO}Pý%•© ÇcÕá<)¨io·ñ‚²Ð;îÖá~û5ýoF›/ûFÐÏ‘xÚ§Z;nH) jùpΤï×ô-å÷ÀjÓÌr0e<é)ü‰çLõ}e¿m%}?ôscÈUrwõ$µ£hVñ³òšóBò<›ÒhFFi)Ï*EgBÞø¬pæ3Õvä“‚/«ÏÔÈÿ¬¸õ#?ûÏâ¡`\Ñpž®Y|u¯üªàݲôÈ[Vþ›èš;¬ò=šd?^õ³¨ú…y™E±™ñd,À ‘cåÚ¦ðŽÔ íÇ@ÚÜhëocéf1'Ïë­w«Ýï•wä÷¤²T&½ã"Åx²=€Ð rLùáݯ´äle‹wPËUy_k3µ'·õ§”¬'}­•“fyà±*µ&áõØÌÈB±³ã²¬ªQvœÊÓÙå?åA-_Uh‹ââ’šŠ¯ôª“ÃúËõ þ†óþÂ'¼º½§ƒrñ¿¯öJ_ôve<ñË”êià\›^ÉñÈ™@sY–½Ø7E”G^ònä­À7±Û¬ÚJ;½ Þ˜ÕÆÇñÙ!~‰5¥£þ]UžZ?6 ô’èH<ãõÄLÔðKñÈÜý Âë+#XÁ†±Þ‘¶AëðUm™œY/½FŽÖ–ï¥m Mucˆ¿Wb­ÍDü8ßz¾äDS›¦%å'‰³L÷ìä\\m€õ;ÊE3TZ¤ÁSÛÛ‹PO%þc‘{¸dƒ7ò1Ÿ€õ–9ds”ÑèÉû“wàä<ÊÁuúF‡a'j§žFÚÕÎ1 1“µXcÜÆPÊz ýOß§{€3]½Ow ùt4d±Ü1ª •OzÏ@nͼ­Pöxù @Ø·t_°9(³ý9`oñïû.cS3P´™á:øbAóŽ29ÜGìS4àmï")Û¥/+J¦ˆWõ êãý³d?–™ƒÓïà%åÇP´3Ê·è7€ë(_ã¥KeÈäÏ¡ûñ[½;Ѫ›Ñƒº•7+7ó~Õö@O¯n4C[Ýäü’™ª>PuG퉪vy·Õ8ûmãºT£ÐªÀ²ØqþŠôˆ 1«¿dRæŒèŠ33b‚‘á¡É|ùAè§Ô÷ìñ?nžáb †ù1™†á²F-uŽËÙêz!ÅÀC¢™ò³\)«ÍÅ9çSí,ÎËFÍíaþtH·6«M‡X•X™ñŒ¨_ýhÖbœêù™Ïr¼úr¤­c ÃX÷ÅC¾bÃÌÛGÊËìZíËÍœƒ\nZ™,â?¥Û0]Ä126Ê#©´¹¦)Ù)¾’ ìw9ÄfåKÝaÔvÚ‹äŽÀÖƒâûdúbNE2U~^ùªûtô=.TIPW4Ñ3™Æ/U¿br¢÷anŒþCíðêè¿ì‰ühw±†ùµàÇñ¶¬°6V¯%ÉkÑYÜ¥ÎOüE+}^òIÚzóbÈçâãq£Ì#¨ñ}Õ}ÀènVƒZdú •L6EÕ¯š:ØËão¡¹«“Iøî­ ¶õ+ƒüÒíÏŸ^¥µÒ=/_óš;¿ë/ò¾ó‹]ÏŽX¥î·J'÷†Ô Ôû{>ðnòêZ­Í±vó6k’;=giÎrž8ýât{­»ËÝ%ks×Éb‚„l,‹úÚm‡B⊌èwÑ=ž/²&2Û÷ƒûŒûøÝºß¼U½âûÉ¿ØÎQ¹[«kŸuFiõÔÚbãV s°Þ9#–ÓX ²ÿ°wq“ìlޤ™u19œr”™ÉúÑë‘öÿ„Ö/c38“ÌàtJ惸#ó_°ûÛExÎBynú{÷]º+O¦‰ò§^N‡äb–²NûÎßF¯ÖK<©Ö!ÎÜJ!û¢² ¬o´gp’«#w¡¤Ú)£˜©Wp’Ã'£wû¶bƳÂSØ/õ·òNÞA0ö9ÕPÌD–~˜Uоîf‚éZ=¤ñ@hªÿ©H L½Ÿº”o\à*!ïÁ ?q½Ò?Sé®m§JøRc‰)WÍ ¨ÊfŒ´Ò;ók`¢è‰êݯïB÷zuÈrW–&ÄJ|n'¥jçì- 'à¿Í@Îz0œí Y«œ®¸ö™ÈTT­¾¬@X£½fhÎÒàB –XŠn^Òþ·¥Èă¡cxáúʳ'|­À8ì[ˆ õ×ç#ú>F ’“ñ÷ãÏ@bc¬„פÚ2+v(WN@¨^ô!ÐDß`¥o@éCt µ«–þ½~m´ G´£÷ò†=6ZÎí–øIÚòaôn"½aˆä½`çV÷Àózà|2òÑÄ6pÅ¿ocü6ÌÈeå |Fo7ÆíöâØçŒWž0qQ6I½*ÿ0Î(¯º4Këám.4s³:dÔõ®­ÜTÝÆ\ÞN£TO{¼•÷ïÿ «²f¤f®zY+Ò.ɽï½ä4k¢5QβŸ²Ÿ"ÃkíµŸƒÁÊýÇ*þ”£«®O«¬²\ßÓ‰‰ Êý6­“Þ̾ßjw(uÕ—õhønm·q,=4ù‰ö—qP™ÍöÞä#t²S–ÃA¹>𹱩é¿Ak’q ¢CS5A_Ÿ=’Ó~§÷ x·+IÇͼ‡3Ï‹9^£òÇ©òf©‡øÑm©×û³Èµ`·r†ÒÉÌ5Îó°½Èçc²=;P€iÖß—¾¢oÁIÖà뚎–8Œ¦¿é_ˆ–ZúWà×@<ÞÊ)ñ š;×må¾t+HJeC ÄÖé¿A¹¦z2ˆÛ_¡¨3Ë'akV?@ž‘iB¦o–eÚC´¤–•ìL}3¿B;gcü;ZðE¢šºLIü‹ôßngRòøÚ™&¤—Ú³À &>_cw#È«æ`°ê›Ÿ€¯ƒ÷=XÍÓexM­ûDò$>±B$äû”ñü^©<jZ͆âñŸAŽk!ûD$‰-©ýÀ-œ2õ7`J*^ã05µ”)Á~à%ì¤ßôÃFß Ë'ÔÀyϸÄïE–‹â^Þô¾Ñ^grN4·ëˆfd¥ŠýßSü8ò/ÄÇFfCõ¿Y}p+Îë#j”£–(øJ{×yÎ<\óG4Ïð†kgƧó\­CétÈiŸFÀ÷Gz3§ñÔ.»%ï!àë–:B;Ÿšœ€øÃíƒ?üµ]…¸˜|UŸŸNƒï¼uÛÿ„<€ékãoü&úø£Éÿ÷'€fp-½2R©4‰K-.ÍÅT•}1D¡| …ÎRCG£'®ü‘< ®˜Š”MDgr•¾ GFÔŽØöj ähíU’¢—v+nYE¡¦>Ñ÷øæøŽ3½j´¾N˜Žpu¾GuÞ·¿€t3{ BÙåþˆì©í¦Cê/u-*¥öcóü'Å‹fRÛ­}`ßÄ{ª&7RX>Oûùn}µCV]¯$ümVëôä /ÜÙ\˜=Õ×·êäl1%tob24:¾—ý¡R˜Ü–¼ƒþzÖ~öøç›¯°Á8e}‰n¬³MªõoÝNØÚ+Î~te”¼‚#~Æ@3x!5å81ù·Ú‰ˆ;[½ ÏmnôB±^7n¤»%}‹øÀœO›äãÁ5|•| üžˆÄo oB?¬å¾™Ì6î6ß±6j½£ßy-ÄѪ¥^ni”n(ëÏÕBpý¥M´çÇK½øHê¬ö use¿Bͼ32¼àhµšoC²Â€Àû(øO\ ¼¢¢(¼Å;@,ãÕð7æ|£uXęצîCÎ&£¿J~ÌêàÀäkl èNz|‰|t¿jßÂ-¾­Ìw¨o¥¶¾~ãk3ûdŽ¢®ò”õǸ`mÅ‹¿é3emÅ ”{/P]ù“}Õù-•Gñ‹ê,¤7ýÇ#(O=£7CxKå%Tÿu•iPì¬OØ¥¿ýއE¸üNÒ çq­uàa¥Žü8"V“ä’׿ìUñ{­‘ä;‡käñRxåÕ¶3Í]b/3.¯¹¯!Ø‹¿‚=\ÞúÏU×Bª“ÿ,Èïýƒ7*ô;¸¥àsƒcÁÞçÌAMuußïsïo\Q¨=Ž–zY|ÂÕoø1ßùÆ-c´²L6•ûù—†ò£Ø~âîQ\Âf?ƒôhn‚XGy‚ý í6:¾æJ-½·8‹Êéyß™ðs v§V‚:Vi j©ÿPF{5@dÉÞÀqÿxPÓ7ƒÜ-çƒÂKàþ*µõoÁ]\¶ã\éÔÃuÞ‘Ë®®¬D±ï”Oƒù¡üj¼–?’צ;ƒÜÙ©*û:(¨ÙúÑ@Äõ00‘·A.BtçØWPýKñ8 ¦¨¯³*DòWÄÕÇ+nFúÏÙÓi ¶W6¡‘/ì4 :23xÁ|K–-ÐÆÿgy×Éíâ]}D öaˆ4:x¹¹˜9|î.L>3æã {EÁ]¸Û•¯)ʪR'˜ãM“sÃ?¦ßHý¡˜Z³h'Š´Dl 941šé­âÕ„‚§£ÇqDIúNd¨«yJä\2‚=*?­«] Á°«BdBòQÐ_µC`t¼è§'øËÇÁ÷°Ï€PM98ðßà‡ÿË1vÅÐT†&Ù³p|·]N‚þ¯º†›ôzÆW<¨µ´ž’׈­©…îFÎðFpUñ{ªh‘Ê÷ÖR¿d¢øˆÁÞb9ó|ÏŠÎ"I(‹;Åía”+Yâ=%¤O¡ž÷o:”s2‰Âlïkp{xËÁ{Qƒ7[tËJö÷c¥è}kœ‰ '*:ƒï&õ:0êGßûÞp4_ËÀgØzµý³ô98< ?©Žó++cµ¸RÃp¿C‰os‡ó=—á8@,ïqÙRu½A‰ñ™üÔeÃ}ÊØyõ["2SíÞ\íuºˆŽŒ“ÏFw0ѳYŒí(Þ"tû~v€ù"mÀlÎÎ ˆÿKˆÕæ7HÔ£Àø"êfAþõªAžR§@º õ%èÕYXk­Í Raª§•W!|wÕÛâœÕ’Õfͪ¤Ï7®˜JUUºMéyæñ‹ýÃþÚ+âUÁ>5&ÇŸÍÛ‘µ§´NõZÕÍü¸´³8RãÚ²¹¨yË“4ͽXõïe½^} ±Œœè‹¼‘ˆµ£yF»Ä„%! ¦Ž’˜ªØ`Úà[dU é•vkÐgx?ƒ:Ê=…«TËðÄE!qE]åVp_U¾ï-ŸSK«IOûŠoióTà;H÷ÔdNjk°¯Ÿx2ÜV|/ÎÄòØÃ™‡0«>Ë6¸¹jWîV²Ë׿/mK:çÃ’3¹½¯ÊÖEzÇúÆÇéÝKgÈ­ô¨ô¼{¸¬ö(¸][IKþñ¿ì¯I-5å  ð%ýÿk(/§¾õùÅÚ{Ò°æð#òÊ•UŒá€vA§q©ú¬,® D6§oû2Å­Š©ìŽÜO@i>Ècú0§‹wqŸrsº&QwMbe‰iÌÈòGk£Ê Õ[q”“A4­Wuè$îãt´p÷ª~ -K¬ã«„¾°5 ;Òv(‘‰îÕ™ÅôàµÉ?iâËMÜÆUã’ú5uý+Ý,ï.mMr–3GdFV;ƒ™zy™= ¼}Î̵Þu?û'ç;°Ï:ãéˆ{9“ÊMâ.t¢,ØoÞFDåor¶V¬ÞŠ"N« È•ºÚ•pòI½ä/zeŽ;Ôø@™¢=¡Swëké'êùuRbTY„€Ó(w#èëc/ƒµ>Ø äõþú`fÇÁí¨öïˆ7étsF`&»’‡?!Ôó¬uó}Ã;±Î<êE ‹vUg~ÇL¿Å¸êEˆ9a³´´§ÜÇ– ù‡£íêcù]r¾ “s´¤[˜šË# wÔª*Ên>''rìΪó7—^¡{;¯jdÕØW¾5ïþÒ)É¿³ò9Æd¿Y}Z~’Õ"ÚŸ-‘ÃÑE£H*a˽áú‰ÖÊÒà´ôefà¤y;-VWn1Î:÷1L}Ìý©möT„¸…?0I(¯ÑLÎ?1×ËÕ΃3Kÿ›gíî¾m` ôdZêëà>I¾žÂª¸?c´ŒÆÂç8T53ç„Q1,÷§+nÊ_/òJ¶Þ%¢ÅÔ%÷j*o¾óSù¡ð'ѯWNW7Û'”^g'¸ØwíF«%4„Iÿý¶ÎJ‚œ¹ÒRYÅo¾÷š¾šéqÜí`6a¨û§Ü‡)W†zå¬É¼èÔ Ã¹-µ’n±iñ ؾ7“ÝÐCoV<Ö/+À\ý¸¥IÔOâ…àÿ¡ZCÅËâ[ÅÞ ©r_‡*ãÕÉßÕ§ôcYtÒ×'²9:=VÂÛr^âo B^ºCÓóâG‘b`â ÒÛ“z•|ëˆOÒ Dª[´(ötÐ^s*!¡Ç=Цº?žåÍ…’®kègHª»ÃVú“»hfLgQÑõ5z&¿L¶BÉšýªºCvá*ûävòEåFqòÒí䩈K¯–ŸæXh`ÄePÄìçT<Ïê„åTу—µ<ðÅC‹àJ(ZÁ¹O€[e-€ê¿b—A¿{¬wWàK­a¸-$›¥+@Û™éCó¶É®7é›,S?ÅU¾3êƒ ââ‹ÔU×寂52²KB€©nD¦ýXéžú£øRgõV'îñk|œ8¼‰Ñ~™ch\U‘=Sž­Ú¥Ù±uÎûô*® »2¾x©üÊXZþ€m¶™¶w‡ßËØ™X˜ÿ].eã䔌—”YîÈÈ7J'o`èSõG«Ÿ/K¯°_ÒþÐ>5¿Q[ûZØ®R qjÓ@{Õ~—iúV×/¤ú©h€AŽ0˜‡•ÉïWµ–»F?ÎP{±ÑÌ}Þ<¯W{8׻여J#+½Ô¾A½!ñû›òxÕGnŽ2®j¬MßÊ?çê/´â $Çcm¹”CùÄX¨ _ÿþÜ(£ôÈèšìËÿ¢Â‡ñÌɱO¨¶ç¸}˜jRùŽÑ1²2º^o!&û°•½Z[w7h½Ì ÇS×ãjOE?ÇK®K<ˆ’Ù!õ ¨”¾ â¯TO4ýÉä.jG_ç³ Œ=â^ö]’+›Ùk·‹^ä{¯iÕûÜàŸoÊ(ùtõ1°.V/Å ¿™Ü‰Ê½ñ¿QSb.(ß%.a{4¿&_A‘¾øL–&þŠ9®Ÿqÿ¤­X—º‡sÑvñòZã:­™½ÓÖíçÍ9Zõ~ëVC¯oÅ¢wEûX×ø¿òï·rœÛœmvF –÷KU­ª<ó™Ð´Ð4òB©P†7êÊŸWþ4Îý#÷}²òµòµ»ž,²D3¾ç{yXY®,§Ï'ž—ݢâÃÜÁõïªW¨fEËÊë¢Ýí—¬cJïH‡Hgã€ù¯ù¥f§¦¾ÕëzKc¥µÎªò½¥þ®>ã¿­ì÷Ë}'¶ü£óÍxNìŒPÆÑÚÛPøIÞI¥Mä4ÒÚd^BX&J@™šÕì=Þ 2Y€b}¡€ØákIdk{)óä,wxs¹À k(vÞOþ³ÖÏa‹é†Êm8ÉÚÆ_èñ½¡ãh±m¡"¨›Q—“åY'ØZñmî÷ÜVq]ÁR~*ëŸõ«u¢zˆ(©üPư¯¾G&"únè&4½SólüµŽgôá¨~Uy‚¾ É>cŠz©¯ñz#’“Ø« ‹Åy[{UÔ¥…2Ë-BW[ÆÞ¡Ÿò¥Ó‰ë•ÙZmb±(¤ï”ß2Ç}ÄrQIZNÕ·òegŽÉFæbRn±³—å¿ÖA¾`$³ñýöë4h ÝÃPû¹è ÔtþÕ‘VFx'.Õ^'4ûµ?8ƒõ*°ïÓçѺ¿b jòÿ60KÀil‡Äk8B»âo¾£& Të=!1™;!^ßúÂ5Ó!4:¶œEe»‘®YÕžÎâúô9åºôAûQ~ðbér­`r›P½âØ!òÜk+"¸áóÉ»Põ‰ñ.`ø=ڬ翀;¸úðß`÷ýEk &£ã᫘Åínvâ·©›óxSëÈl§¿ÒLyÐú6ù ÔÌRg‚{Îü1£nÆwî¼ ^4̲Èk·9Æ•ËEÝÍ'ÂCŸ2+¿M~k©–Ž.½Óìöwx¯ÐƒR²ŠU²¶ø[ü-ç¾sË+Ë+•)áOÃëõn¾K¾KÊíÕ«'ª•ÆJ ý ù½ù€ö—˜§|åÛáLH ÓûËuru`•œ" ÿ1ì[ݱš)ÏŠ=¢nøv2œC HK¿ú¢Ü&PöYÉJ0^®q#TöM´±Ù·Å{.x…¸øU¿•Èáï!ÿÙÈwB L ÈèEÿªO²žåË ‘÷vىšè%ÕZ W¯­Õ.®ý<\lRØüçõñpC½D'Ƚ’ºÜ•ªÃ­F*½ÛØn_¤KàßÔ ºøv™ÇÁ8èÕA;[ópµš©Ý¨Úƒî 0VÙ[@+w<í¨³ ©§Í‡Q•qj1è—â­€u¢7hÛC~ÐŽý,HšàåÊ­ Zü"îÇ‘ÏÙ4·‰³ ø×ÿÿ—´m΢qîÕ+øÕŸòÞ±@¼$·ˆÛéQVíæ0Ùê!¦r9ë~žÊxu¨zë•J1×·HÏc‰­)˜òuuº\Vä©ã½•YŠ!η²œw-×x††¦®Â€ô2ý.š˜?ú±>½<¢ÒÞü6ô#^èx?”@2Ø’o¤¨‰cÁ{Á¨c>z¹*È7³ƒŽåBêí>H/ñC²‡- àZ!°¢º¬s4)÷Rª1Yò¯â9K¹“ã*ÔP÷Û ùSmmw`˜vÁ:@†ûjznæç*Jñ—±àïgž…ØÊdop{§:ƒ‰ý1Ä&¦®ï:s&ï9kÀ4܆`]I›PÚÇì µ>4ë+. )/÷n·ˆm·PF su¸°Lg[ß>;0Üë´ŸÀ¦Ž¯—~ D$ðÈÏÏàˆ»fh²®÷90B ¢ƒÖÀ7ž¸'pe*ô=d‹Œ¼ì›âœ.ÍŽóRÅØüÇ™PÖ"?”ž)¨EòêúÂG°Š£…¾«³k]&P¤ÖÙçî­; ŠFf~ 5WÙ«Pê ©zræÇqs (u'Ð9};s[¢9 5‘ Á^éA®ŸZ„ë;èe¢f¼[‡¥–¬‰á/w»ñƒopúqî÷·4{rÞ¸”¸ÂjãZó7^ó]Ö>f°?oÉýÚ ÷ÙA­£•»J›Äûa±+ò½|„,ï3g‡cO9Í k ÏñZÉX§9%îcîYšçOVº°-÷¤÷:BÉ.x@,ø9ÿ߀ìÅxÕNEœ|¹ünB¢?ƒ×Ñé²97mù”µâ*(ϨÛÁû^\„Фgö‚¶ŒþzOHO“+~Ò#åÚœÔuÆ—˜æçÆLÒîjßh„÷’¿3ötÿxFÅûúËõ&¡šF=јª^W~ˆýʽYµ•7ÓpYNOÆuç˜#PÍÛ#_‚¡Ù‹A$Ìà|/—#œ‰ê(ó~ã ”TÇà §Ç¼§¬¸QîÝoµ×ØŠÝVogN¶ïQ³Sc½,ea¼T>Áñª›dw”ò'IByÁÑâwp%ÆüU<x­dgù¸ì>e)YÿÈÑô t¢û²ïvÒúÓ•µñùn¬¨‡ð÷V¿‡àgšÎSâOÐZ„ö€ï%ã:~÷±WÐ-X_.sî7ÆjYñþϪöq—7,º‹e¯˜¡AÕŸ‚òN‘%UOB°mrj¸i|„ÆGÓx¡îfJøæèd~ O~ÊôPÀ®ä·ðÍÑë¹7Lrˆï} µQ{Yœ0oà{gRê]âºgÎ#œÚdþ†«6·š‹Í×@n´{aŠù®‚¢´´ö¡&ê9Í‰ïæ“™z• éÃñÿ •ú?‘ü èYÜ–’€{ªˆë½·Ã.èÏþý7«yùJ}/P‡qJîå&üJçÔÙWœSÑÄVFñ¬|É(“äÚðït•;Ówò€×ôÌH¹c/1À™++g×Õ>Á±N{ÐÔOÄX g¸Èþ ðÔdK°÷ú} ¾ˆýöŸ™³ÒÚ ¦™ñ&X¯éQ°WûþEMwwv@t‘8DÛDRù„‰•ÏéS ôgõû×øfŒDmþÄŠzŒÀ¨ Ê^Ûœ9÷6-„Ì_kõýcç®1]]&.šyxÆ„¬.xblj2®ï›‚÷°éh¶ÀÇÿ *÷'±Õ»'qžyŸ<²ˆQ^:º7Ö>‰â¾î!Äò`o4ç¢÷ºw§RÕ=ÇB„SKT‚s½¸V…üœ¥ÜöxŸV[÷ 8ùþ|°ÎK Rá«Ý€EÞ{À“ Ù˜ ø|àÈû²VHd•wo{ð;_會ôÞ¼&ëï08-dW¼ÔMf!™%Eå1<{›9Û]’êƒåí5kôæZû0¼õî»aɵØ^¡—ÆU70ôyôAõá[ÔìvJWRõü›Ð²vþ¾d(ª²ÁèIí¬ë¯ÌæÎe™’H8ü©Ýϧ¶90>Žš‘Ï¢ÛÀݽޅäWh¾åÑ} îI,¾Lý Ú¼Ô|ŸHžÀŠt&øœÄð5Ï€¥+!0Õ*£sÕ“ /TÖCp;§Gyé?N@*¿«<9°jŠˆFŽ¡ˆõvC*”gœö2GtVžsc8ÜËŒ<¿Qª\V_ð¾ XÞ-÷’‹é¼u¼Ê$kËòx#eÜëYÓÙÊ Î5ÊÝÜcz6·šmùÏL’…’:‰ É{¹ SÀ}Š|MNhàú+|À+ú÷@#%”ºòmPjŠ(Žh]9¤ÞÄf5¨®—}ÄU«·ü‘#ºÉÚžÿŒë¸,fQDÜýXÌÂg®å<éKÕbùnO1–â ² ì~ÊpV©7Qä¶TáM¯@Ùæ´G)´jI…[Í€¿Rwò&¦ÙG;€0/+«!=Ê0ÁòùmÐWôƒÜ'szC~§È­uoh åO`÷KïC‘%º‚ Aæ`ê‰- 7Ç‚ù\z<ä…jÎÅsæÅg zÛ“‹é¤_)üÔh­˜víêñt’íêmǹüyõïÊÉ’Ñ•‡‚cŸTwþ–91z¤ÆæÌ‡+Ú§ï Ü­i<XU­«ƒ2>¯,šåÜZ]Èc·W¿JNÖäèuÎHÅïæÇðˉ0¿ç¦î <0ÂR¸ÑwÊj)Ãì¿Ä&½­«3PÉuD…+÷ „‚ABöV*ˆy¯ku©v#\6#¾s\²B¹¤R¥S´I¾6ÏÊÜ*ôè³YG˜Z5'«³ªDöjV*™[ìEÕÙ2íEú»U­Nûµ“%=ÜŽ´-›ÈÜI|Ê\ÂêÃâC¼H7ªü_VvHJÏàÖ$ŠQyÎmŒtü/½ÿÿ§¢Q“¾ÖÕw'ò“?ãJ-å 8âY¿ö2yB<š<æ®c]Âr—J¬àGÁ_¹ Öûgtû‘ªŸ9ïø¸‰Wä»^’g¸ÇmWìUÔK 7Ó쎗§ 騈·EõÇãKÁ:›Ükrd¬È£± 6L£YÜãúø'à»>=Íw8uüO¥oâY_yj&cÇÌ}r¥ÿC®sßVŽÊ¹ÖmL’ÌuÜ—šg¢£s×{8/âqΓò’w£ˆ;Ü ¨©yÞË4<~··ä-ôñ=Á—Pj€zZ=‰©ÊjHïWÏàÏë HÉ×¼B"é/äD–³Y g¿·Q(¾V_SP3µVàUg?‹Ç•Êu(NEè X?è9`ž ë6u1¤†§ ~‹¿.^ìHÆzüñnù JÉÊ{*úäÍñе…c˜tõ•LŸU·ºŽºªx§7‚ͺò ¯¬ ¨ú%ôƒV¹]©ˆdg âóoæ£íÍD«RÝé¤þtlFe›Y¯:ÓBéÌŠ+µîÉëZ¶ÀÉÈ~äÔ¦ô€ð c^,àûH?[½Ë×9·¢ú.Ñ"£Q´ÙEŸbf†Û(ˆôïäéÐ5É™ §® l±~eƒqоöZ†÷eÚjïC Ä“”ÓŸ:’³n/m–ûµ1™F¦î¿ÃèÉëÃk Ñ=ò,££—#“œù¬ÈˆöÈØÆ¤¨“9ÈiQ½#£AºoôÛàŒxôÃzQù;N?å¾Ko»¿Òãü£ÞVÌ3×ó//œÕùÁžvê ”es,u®Ú­açÿd8^œ:Ô¨šÎ$FøòŠ0VȘzsù¦ïÞõs+´„aF7¨AeŸož’Ëd-ìíábòëÔ@’ÕûìL‚Áì[AÚ bSå_ ;–%À $¦ã(R‡¨òŪ®r4x‡ù³ÕMÝ©-Ka¬û}|$ÏÅNGÛRÛ¸6>™Úb}l7XKð´ÝÉ›Q¼ñ:¨¢Nb5ÄFÅςؘŽBè9oT}Ý bžy”SV” ö*P<ûKq-K}CÀ×S¼´îIõa}DV0N¿¢ÆøT{:½@ºœ¾ú)e¡yÁ9¢ÐKɦñ“'8ë=ཊ¡¼©½"6g~”};ýaI]ŽW%®€çßÝm&ˆ,ß+V 9Ï7 ª¯~Dmÿ£ <yÒw¥tpbþ‰ N:=ÀþÊÝæa§hµµ»À^©ÖBuFúxǽ ¸bo“y¢ ‚ëèi«ÞYìÔs¼žìíŸñÜð½xÕÙYçñUÎÈ]ËÚŠóÉže} 6‹ÓWwÕ¹Âm—“y£œ«eø¦–Z{¹ñònz*ª‡ÁWüÀî¢WÄ4¿òQPü²¬Ë­v;F‰cYs=4ryÇ!ò¾# ²š›ÿ2.c.Ÿÿa€Àiþ!aä²Ôöj4L¥&?€Ó‹;•†à<`­H×$LÛø@Ûøï´eBu/6A²¹:’Õþ%ÈrU«µÍ"NÆËe>?ø_ç[ZÔx@l¢Fîa ̯ÿ_ÿçŠr+=½é¡6ìŗ㈭N©¼ŽÇ­=µ“ißdŒÑ‹¿_5;s^°AÙßvGEQïIåÑÌ÷y ”vþþÖi+ÀüÕí ©«©³ºÞ9gÊ£(nËÊFœö¢åq³úšù³óÈÓ†¤3ø3y;•’¥øRÁ¨‰ëÓâ÷ Šñ—P+ºW®-/^ Ê3±öÚîÜeÃJ; Š†‰Ýý²¹ˆáüp‰©­ÓùŽÖÎ6»ÖG[n—Ü;•²ÔÆÚ•t€Î|ž¾¬ü¦tµŸ”ɡ֟^Ð Ù½÷¼ÅV•SÛyÓ}ÝíáîtfVþPùµÝ'x(xˆ[WqœIçï:—Yhh©È/äR¥'=™h•YeÞ—²JV)5rëåÖó?\”[”›¼+]‘.ç7#lD}­®Ür¥»ò˜¸$kø‘=¾FÉYÉy¾jn ³?ËN8¦u†²mð.÷gw~èÞÊ •µôŸµìÈñ­·;lQ+Ý$uR9`o@X=¬$8‹¼A`¿%Ò «Ô/€áÁKHÙ\¾‡":Š›A>¦7äov2¦-×3ìc™x9–™Äªê÷²þÅ®XY£ ^Ù‡…-W×¶¥õÕ65KI_žPk»®Œ¯µ‘'¯Ü÷…sª¬2ðDÅ/æ*JÊï×çrMüHöü&ºe½DVN³‚‰ù-õkšúUµõ5N‚Ÿô×Óç©­o°Ë¹M[¤ß)§¨wº5åe®6Ü­TšÈ´ü—e©2Ÿ÷aîNºúÆzï³SàFH[ò&Øë@-îæ :Š·9]u»òã²Q:ÿ’øŠ£U_«O˵ñ–šÉËrâ5R±4ûä"Ò‘”×ð’¹Ím_õªó£þ®`$ª}R_VcµXÃ}q°ûzƒo”z˜Ïù–BzŠhíß@r¸ïzgµ@<‘ß*{Ú_A¬aú0Ö$úƒ¿k -ºw@d˜˜é^ñ^hNaêEeŸ¯/O3’óÎaï;)ÓÝ¿@<áŒF-ÿ,ÑÔ©Õ_ ªj‚¯mâÈÉUýA3“}!Ñ=ÚdÍh- õÑäû ýd}ÈÓÊ釨M-û~g÷‹E©†НR÷ª3”gÒÏŠsKO®M~n¾¤ S®Ø×U­¬ZåÜçÜgíËWß¾ú¦}Ô¨0*änã6¯ƒœ&óvÒŸþr8¸Àû”P"~e*S•–ŽÏñ /ú\ô9‘ã{Õ÷ªvÜ]ç®Ó.ºÜúcîî(}š¼EV{OÑŠ¯(Q˜¡,4ª MÍqZ¸Oký½Ý‡¼væã³®A:¸÷"¼§"ëA1ÓO‚W–Õ\¿Z‰+ßòûQñ…nâKÔÈÏL¤Uf.¯ñWn[ÆŠƒyio_V-ßûUjÕE¹’Yk!o\ÞVÇ€Ë×Ö>‡vywÝ(œ¿£~'¸x¶àHÞ¨ ëœÇ¡áîê†õ\²¶%ïýöÔ+x¾Ûåè™%Ée`´IÏÀóÝmº(¾œÔp„6Í›ƒøÂz[{ è†ÓO?’ÚaÞAÑ¯á –V3^‰­Ôa)5GûO]qYÇákû+B¢¡w‰„øÎ«Àür³r–<þ±Pæ½íþHžòÿOçÎÿ™Õ¦IaÑ7—ÆN½ãíÁ“ùÔÁ1e-nÆh}<Šo¹’À,ÿÊEf`qãô8Éi" ¾Ô'±F´1‰úr¥>S=SòŒQGÑÄØèÛã=©öô lUJíGõ3L7ó_CãÔùÊ?'†ÎÐ\ë| ©ÜêˆÐ’þ¾ÀìÐbõ›Á\ÑÂ/d>6ùM ÖHÞåQ÷P{™P¾M5­wªè7™“ ûzªÝ°}>_šù³ÓŒgì1F3e…ÝS$câG¥øH~(z0ÖlátÃSž!Dõ/öT\½¾·Õ:b׆ôP3Ü)éwA_å.X:u#ˆKö@ÜüÄÓ¼ç‹J7€lç=î"w)°]nꉇ€"Õ¿šû@a¼îcêjH|%_)ºþ.Zà9é" ôšœ<q7•´Í°e’›"_‹ï8œ;š¡ìÍlÈ`5+óŒ ÿ`ôŒ7Ì/ekI½«).Í*\Êàâ…hR”®Õ€½E•uÖQpñ¾z>&œ}¡ng ®ÆsîdNf¡œ…ݼu| zÎ’è½>Ÿ¢øN¼ÈÉäL´ðÛÉù¾/À»d‹Ÿ†Ö¯(Á‡«¾_DVs*H¸-Ð-ZÌ¿Æër‡ÓÝ9ëûÌ«!ŸÓmï 碖ar{‰”Û­ÑÅ.ç]BÖ!«û¯w>¢NõÍæï´0vÊ7ñ”œßqªF¸/Ò;PÅItnôVSYZm7FMžqN zye@ù¿ )¥”ÿï1Þ%x6ãÇOaS»¿{@Fo_kÈzÛ·$²(ÛÅ%H ·BŰô 0îôÝj7­œÏÅ`Œ¶ä1­.P¬Ïåyß°šêÇÁ|QÛÚ˜ÀgHóÿ[mbð%NhVp(u«ÿ M"$¯ _þJc¯õqÆd–Æßò¤VÕ·¦P]˜ÑÊÌz*še÷‚r-ï ¨œš{JÕœ»‘W¯É¿Š¸Ú¬ „­¥Ç nçŽâ²ufVTk Êz¸ùœ¾ú1ÏR÷òñ úŦò{„w¦îrŽe «œ Q'v‘:¢8~˜'}3ùùþLå ~¿ä8£œéÀ;•àê½8a«Ñ£|kìä.ö¨Ù|JR½ì¤7H— ‚^pÛ¸ÁQ‡M¸ÆÜxɧ%Z `í$¢G)…ø å8Tí!Ö/ànÐPZ>M4•õéžýs%}Λ^\œ-uN–u¬œ=ïï+PV3ŒêQ6Ñ£N@Ô4ÐGq à}ú@^¹85 y/ä?¬þù»•»x-¯—~7Óóçú6'oóy¾Õ#¸œ?£2‰¿ CåGäæœ©¼ŠÌ]]ŒÈ>í ÙïFë@Îç‰!ëµè£ùhzd.+ï¡û¨Œ´3›¢„ׯq&tX¾ï¸Æ oK*!†¸s’%<£ýžº´ÐRxCNNFµqÙêH†y"µüÊTò툘™ ‘*± œæ$àŒ÷6äEðy÷¡AK*ÿ)ÌýøjÜ:Hÿ¾«-‡•Ý“®ÚLßrYG|Y=Ê«ýeK¯#‰Ü^²>IË”]ñ©áCMïáVìʽÊ\týEòDø9ÅãŒ9Tôq0¶3ÈzZ߀b·W{5G†H~Ò­üã µ#p’þÇ º.²“"“!öZƈ-‡Š§rn«^}¥âb–ʱümL)«•ßšƒe—jœ'pubæsöØèHeoÉ,ïŽ]úŒ£\[Ù1ã‚cu›B¨UÝjäù‡þ§ÓK¢Ùê‰ø/4öͽÂ6u‘|—–úmƤ’-Bˆ¿é êÕÌñ v2ÛƒÖ~ ‘¸„Àr3-A¾/›ƒ\(š·.P¼Í¾íXÞãéW0ÜI®ÊÃn†o0…Nó6/8/¹Øî}²)º5ÐyÜÓ¾'Ájêmë˜ìNGý0¤¦Æ…äg•îòy3µ7@.Å`gÆ{ƒúe¨6غÁü3Õ”sa©óæ2°‹öœéÌôg¤o—oCº¦ì±AV’º ñ>Îõ²*æUûÀÎ.¿òÞö’P窡à¤hƒ(<.ºAWä!¨ÑTöÄλÈ]èùS8¹o(˜„–ë•7ã§Âw+;Ò-÷Ùª»Q3ºTÏ„«c¯ r®­œ‘%‰^=:®Cäóh-5K¤ ’é4…Hºz+ø'Ù×Cȳò!p¥ú5ð¦ ÚÇ7€Þ¶qü !biþã ˜ãD xzç8?PÅÓ¯¸£ØÍJí{.JEY« bš²Ðû]6 ÚQO|Ênȹ"Ì2W´ßÊï½T¹³h-Ú¸/ŸØ¿Ò›®æ9Ž2)ý¤[¤rñAâ7ê@üB4M%8shþõø ø5Á_ɨË=ð³ |+ÀèO;¤ïNj Œ¶¸\Õ?}ÉÕ6ÊZtÔöñ)ªé!Û*ßRÄã┲Sv•?‰z ÷Éâ)ïMoeòwüâzù¢Üï4–ME û8ÿp­ù#ÐÅniÂ~·{à7¾t[eÜÀýÞX¹„eI®Ž­|Rx ]©Ö΂xŸ×A<¨Ü¢H|b†XŠ+Ÿb&®W  ËŸ|l÷Húsl·ÂÍF•“C‡P7RÇPÜ ãZço4Âîíèàî+S‘úqý$ˆÞâ„xÑ9J‘¢S)ûËrÎz÷È$>¤÷Kå£Ö¼¥äºÏcªWÒo äôË7Ô³íýÎ ZÏä1ëÙзÁö=cJ*=ËÿöAúœo[ðÓÔ#Œ¼—ú# š1|£¬{þ6NmP/9'@kë=âNZ(ÅàÕjƒsÊxìÆF¤ÙÙÿ"}›? éç?ÈÖ©}¾Ã&éüÝÓ…Öý@¢¹ÕV³ª™£«·VÌq‡sÕçèHªh ç%"h¬â+®ñ¿H;œÈyZÉø“‘nb Z¨H6@ NS`(ÞQ¨W½`5äÜõÔÿZÿË hœª¢‡‹–~ucßž£»N ÿçtø×ñ¶¶;|ˆI|Ó¤ЧÁ“€¬³QØ–|¨Ù”8\"J¢ÆÏ„ù¹Æ®áÆü÷©Ÿx&pKÀ)sðå¦ËΓÈy«²69ùÿ”÷‡ì“U÷BVAÕwÿYõÍõSåtÈTã÷@ÆèØ8ÈR5 B-Û!òEª„/¥F"Ã߯gp)x·õ6u}Ý×½ÆáDït}ÑKÝd~ÆùÀV«&ù±'ÍG¨þÙ¹ÏÚgwCh?ºQ8á ¾t냗’Ï‚+¸Xƒ 샡\ ÎxåkàN-KÞ©-ƪþ;SĽþGÊõþW™Ãhÿü¼hüå”ûƤæF–0<¾4£œ>q/|+^õòÌ”ê»r‚ª-YM¡jqn^y¿œ¶(å‡ògósÉêðHY ð~,¾¾Ö^ò.=—÷­—^ã¿®ì-¯¿¸ór¾,fù—™Whhix…‚Øór?Òq¼í·´lµµ£HÝÉ#­œ×S&%¹lt›ÈÚÔµgÆ3Üy1Ù[?í{]}ÒÊÅqÏWLC 5Òk²GÏŒï–ÏGžSÿuë„—xÿ:M3{j_Øû‚³õV×ùÂ8ª5µçkŽþ“ÓKûW+—£¸SyËm¢<¥Þë-‘Ó-ÎÉ1µ¹ìéS^—MÝyZ¹{³s»¾Õžè”«§í¶Oß“žéÒ¯O¼é¼¡ÕŽõvº«•wsÄ•’;È¢ÏÕO©¦êâ^$Yç÷mNͧk¢5CÌÍñ;ØlS¦„rCnÌÀ¾˜ZkÌj°ªÕªÞÁíÃ×=õ_دð_ù žÿöº«êSâBá_â1dÍvrÕ…ed“Uk› Þ ~²í’üšö¦ôvvi[é"Ϩ›•¿½Ìû̶ÞòŒ<í…œ¶öP/š:”~~ô§ÒßÜß™£ZSµž¨¥f¨T醽[•ƒN7w™²OMõÅáè¸ôH¶çgvŲþ> §¡v'°$¸ìIz!¸Ãý'A^ì¼yÄêŒà¼ê ^›Œzà5Ï’ ÓY—qØ—ÓÙ¹#¨ÅÌüç9Æ‹ù³Éò-LE z‰®%ŸôÅ+îTø"¨¥£½RÓÏE›k'yâÒü:sÙ{yTý¹„Îwªù±w¥('’ŽÞߤ¸—ÿv»Ññâ+Œ¤áùéb,ÎÕ“¹åÔ—|Jüt :{×^y‹_í¶æ m€ÓÂÿiVoê‰]r¼šPÚ{Oi¥¹Û3¶*]bK+Z*Žš²çQ#£Ÿo*èwȘ¹Ñ•÷VîPðµU¨ÞÝ™GB­!ô[ưn°»@47:žtò²5’2¹Z<Ë?Nk²¸líWÉTwS)7 È‘1±œÌ¸ž(#œêäÍ Èe !ð¯#"» oM^ýôúþžÿb€m¦†×&‘MÉ´å\€ï‡é9 OÒ—ÈQiKl°~°¾§_ºaª_ÉgªæØ7…~¤¨|‚þf$ûòÔÉ(Nñiá=Å+¡f~Ñý¼^(‹žÀ*x¨äQŒšm‡‚Z¥Ãù;ÿÅâ;iYÐ z»óNö}âlY1Ÿ‰¥_OªôKŠ}%•µÉ—K*š‚¦VÚ÷UÇA{#v´c­!5§¬ n¸Ð\Žêy±¹¼/¶Ä?`j¤àQÓÞlWs‰€±Ýø+U›ö´LuõÏJ½% ¡šÏËžòætÜXl,¶¦¸ÛÜméëÅF±Ñ :ƒÖµ«ÚÕíd¼l¼,¯$&¦Û‹§ÅÓò’6A›@«`£`#í¢l*›òƒ7ß›ïåEÃѰ“Rz+½Õ;•æJsmB*’ŠÐAýVýVïǽܫW(]”.¾Ö&k“ÞN{U{Õ6mÓòýl-²ÞðMUV*+CŸ»‡Ü’Ð7^¯fx„=Ém\àTf(Yrf$ŒdCv=S3w äc9­òÜ@§¼g€¹-ñ()ØŠBÇ9줬à&ã«5ÚÚÜ;UãFÕ_úW­»ùärÇZ‡É»2¼N .ÿRw\¬Sç \êV÷cì ·×¿ý†Û¯\ýÖ¿ªdõ‘Òµl«ö=¯9õ¢ÜªÝŸ1ˆ¯µ²“&Á‹þLò|;Óë)ó¡—‚qÒ]O}µ¸Éë¯êÊE÷1ʨã¸"èNuæCèû°öÓòçÚ/³¿z‰S—ˆ‹vÜ—=ˆÓ ½èeAz§àõå ˆÊ%P/x[ ~Vé ö>µ#ˆ-êY¦Ö¯ñEÃ9™‚ÚŒe8—µÿ`‚ Þ«s® S.ZwJíü-/XO2Èje¤9í|åËÇrúxç0̉úï`ým¨`Vùþóq)¤‡ú4H.õCroøYHFõe±3Š 1…ÞPÔ¦ú)ðý~ñe(Xpy²fã¢7µRÅyÔ(\ye,%5–“µsßt&Uõ2º‰†%¿°›á%;y©eÇ9%——ý‰ÅÃå`¨Ë«WûÊorå‹ Õ½îѱ <= ªšÜÅUúÇQ@vòS¹YŸ®<žºE]¬µNž¯ˆ§Rß»ËÝ·ÓŸs˜Ãé“ÊÊÖpw²;ɬëuò:[_+û•ýÎÜp§p'™—qi}Àæ¸éOéPB‰ÌGAa0‡9¬ô¢BùÉ{Ä{DÙk?g?§ÔPóÕ|ÃvÆ:cõÎîîÆpõõÿçÞÃÞÃþ·äOrwàAïW¯88˜1¾žlµ»ÿ"‰ðu¼ËS c³Ž ñ@öSÀ´ìzÀÒ\ø"çE`Q{Ù5RH"5Ö“à—ZH2¦V7jø¦gÍ2—ÖÈÒ¯¿:¤N”.—úÕB׋cêäó·4¼ ëôw׸øba}(è Ùƒ­–P£ ý3L‹ŸßÕê% ïµ§@F™©BÆðÔëàïýT‘ Á>¦OÝ(–™]Á¶–þxº#hmd§Ž ë¿¹?2[¯c^¦H{ÆMð¾–tÞÄR§(‹0´U^G‰™—ÐØàç-õ1‚~œD¡±øE–mÅ7Ì¢½»ˆ§ÝŸÍ"â;–}ˆ¡ÿçüÿ+ªAÎþñ÷ár›Ä  ü)žÎ(&¨ëU@iª}Žð‹±H÷#åF\uœþ5žó£ú1Š66qÉök¤âkFóôã,S´5¾$Ä;¸Ïêî3©nì yuÜ¿Äó©gߟèmŒà`bEö~$PßEV§3žCÄGVBlq8 •õ#{ ª"# d¿ú&AÕ-U­ À¥ wbÉ(È/Ù‹UðpIŒüC¥‡¸'w[Å çÖ/ŸAq®ê­Î¨íþ—šB^å5˜Äª›P…­E˜µñb‚LŒ«æ%kO%F©ÔÇ@Fzð²y0Ñl `U]œýÀ ·0Ô© (Þ‡@]€Æ¢0•¶€PÊ€#Êànýe@7Š5ÆC€ãëÔì”P66zøAt¼Pе2||Ç¥Èwt§(÷;€¬î M‰„ìw3l}MtLÞ&±¤|yÁPܱæG,)ÖjÖ—S®4«;RpéŸz¯Á…çãôÙÑuFx}K·eÕç±…AJ^þÜèTdü‘ž6Œ.ê¬ÿ0þãüˆdwï§V»]A›oXònå5ç>;rÎyócòn9ˆ§“ÝvüÊGòYLÆŠŽ(Ú!%ˆ.Ê”÷yÊ§š§µXÊ1ÙÙ­|ÇíÖmÆoØfsÿwèéüÀQH¼\é'CÄs"½!vKä}ˆMɸÕg—Cå̬£Pu]ÎkPÙ2w”÷Ì+F^œßhùï…w`/+Ø#'”Ýú)úšû6eWú°™ÉeÂ8‹C²Ñ|>ˆLn|ËïùçaèÌ{À×KÖÆÔ‡QŒOÄW41ÊýÙ¬Uï·Ï2QÝî<Àu¹»D¶VÊr/z)nKô‰V‰£â k·ó$ºû¤¬Ka 9Á T²XÀ?LV2¨sÅ44sìT6AYÍÂPD¬ô¦…GŠ+î•ø~&ÉÁÁoqì­ñ/Мý(8«Áž*:ñ*ÀþÈ» LÇY nÝаâJcˆv¹tÒŸ·kxìÛj¾Ä ’ƒ+wÛMëv¶s¬#´ƒô¿n˜7yÓÀº¤¿ ±š©lH·Â…èZ÷ ˆð@¢«!ñ‚°ŒpAÀªIDAT ¬8}âYæB½amƒŒ'ìYPs1+ ÎèPóvl( ÈBà*èè5úc{¯æ†¡z‘ö¢ï–’ü]coùnZf®èùG*@ÎÜÊ+õie?ÈΫj™÷&?œEñW òiå`þmÞ™OÄ—C¨Q²SÎBn‰ÿÖª}࿵[5ür^ÐzuÿKü/Åïúõü³©K]¼à`e0оÏÛÂF àiíOàW% ˜ÊvÀ'Zˆq^O/0Ýà³=`°]ÜfŽMd*‰sÉ'ba€ê#ÞH€@ t ÐÀ?ÀßÀÿ8€/À`¬lm ë0S; n^R®lá:{èàí¥8ý9ò;í2¸_;µAù.ÿ}PÖÜZ/ÿ+$|ë©ü1rµtr_+â }wFÞ.{ŒWsVV¬¦Iî슟‘¹-*ßFdµ¨ôCöôêo +R• ™J´1D¶G5Èh[‘³ñl‡õ±Â—1·';po`zú Z}é‰lòOvæ[/(qÑÓ좥µ Åk`5ESžwÖ€÷¨ý6(EÞàÝëNy_ƒ˜.»€(¥àÝ€ z ÈŽÊ U‡“ôo 4JðØe<„Íß»¼ GbÏ¿ŒjôöÓJÍ˹–ÊʱEK9àU;딈M8éiVš×Í»ÄõÎCà{Ylÿ³†Àpêƒñ%@ÛJ>¨Ç¨Dp@Vâ[̯`+\«>—!õpîÅ_?À«Ÿ¡Ôû€|_÷cà‘z7'ët¡Ô=ËôçyÕÊ´âcj:o]çñKïs¢f‹¢ß±jõ+þ£puÑU¨Õ¯xŒ¸º«Æ{%Û‰ÞU2’ùeÎë÷Œ Zy=~À-]Cµâ>2„W}¤WÞ  Òn‰'³rˆ²èx0>±çíª« Ö$ꂯÔÑ!©WL€ÈWêp®©þ RC+ŸCF*¹’ÊŽ¢¶ÖCt÷ÞÓΪïÙ¥±Ëñšvïü¬|MÑVjIUî’ë¼ß¼2Ï'˰ñá©“Ô•€YeF…^qGÅPe²@øµç”ï•~z…û²7P]¦úβÅûXÖÇ$/Xe_B•áQá‘Ya€, «@Îû¹äÅòàà/ø“é{å§FiðBô÷š/и¨}í÷È»2©Î“”]|§îÜ‹oÖuP.–ÔÃùóë~Iƒ³ãêõq?»4>K«ø79S±/üÊËì;u=Ï0áÌ{@òä³êô´§2y4cÙ‘xã-ò•¼ã §Êî…íkWÈ Ú`}¯&gÉCÂR†)Ÿ+ý’O¦Ö3½D$ïŽßHž± T5‹èÞa>Ãí•1€&ß4zx½Yê:îÜËYWA´¿At×§ sNä"”ÉþÆ».»#Ìò´]gÜøÀÀÿI®º³ËJ`ÜW^1öÝá r)õº¿ Xš±š€×R¼›š˜Š³,ñ’;­)#ñ·Ô 6$:fëc¯ÌP«j»p¡:Wn£ao/}€¯öéK« ÎÝWF@-»èÌšg¯\åÏZñâv\-|Ú!Ö%t;”´¦&LJÛ‚Ò"€Ò–å[Ê?æVÞ ÊìXgðþ,݃£µKìÆr¾,{ž“NòZÊ3ööôö2/ú¶“p¾‹_ÐÿÐO6Ž4ˆ40ßóò½üôûœ}.ñiºnºnòíP"”p~tÎ:gÓúÞñ½#ÛÛ ìVW+`Òó²OeŸÒeÛ¼ÑñçãÏ›gªGVLVáàp‡rF9£Íÿ3ÿÏÈ¿â]ñ®(¹TrÉüÒÕ5P[ž“ç´_œáÎp}º¼GÞã»]ŒcüwɲGÀï\r.ù€ð8€p?€H.@f[Püþ r–^³ ò®Á¹äŸ¨Ñ  . ! –ÅPk/_Aí9ø 3£n´UÝLñÅågëÝΓç××qáüõofýù± Ÿã–sï6ʦõéGô‘‹Ï=QãÚĬ²–¾©—4ï’Å“ÅlE 2¯ÎÎý£oS/ØN«B öÒ’ï[˜|‰c¡Æ2¡ßgMp®QZ*ºý¸Q/·:°G{κ´enOgÜl/c’•ëþÄô¢Õ’õ¸¡WÄ?ÈÐ"û9é㮃pOK‰ [(H‰ŽÀ@1 ÜNj ¤Ñ„\Dr©¾ œŸ•ñ\I;Á~Ôi«õ,e+6ð5Tëÿÿ_yqŒ‡ëx“duhºš`{Åo¢LîÐoa¾3X¹‘±VkNÚ]ü·cZB»ŸÙË¤Û þRh¤·…6@²Y bÃõ­Pµ5û#Hª÷AùÒì$Äû?€¢ñéPO_lõÄyê•_þ‚Ëuú_¾BÛ:Í/PVëõâ®rhÍÞ˜è‡_qwúRy5@¸z+Ê! t9@Ùn€Ší媦TnˆþC ¢Ë(…ä.Ž€¬úÿ´wçï>—ûÇŸ÷çóù~¾óš—µX,2ldˆ¥‰Xæv‘$Mf[¥Q;B™¶ •á)6QRXh+ŠL%‰"Jfˬá;?Ã}~8ûœëüpöuíÎùåœs}ÿÀýËëzßïëzß×ýN.j„_J¢>€Ø*€Øcñ£É1Æz€äqc€U`÷P@gåAUÐîжè=ôÖžVÞú>àØ@^à8ðº+‚ÄpHmI]ȘÉQÈØCdådݨ‘‰„œ¦¨b­kZŒâx~œU¶eõ—­»g§×ÝÉÄK¹õþÿo½ë÷áÀù¹ óéù{oùëÕº•h¥k´Þàiµ.V„à¨h=È~¢bx¶D»C 4჌sU}À="Ò |C#WÀ¿41ü““yàË3ǃÿ‰ŠÖ ý…ŸÁ¿¥r h/h L¨.DӻыÙú×FN¹®×xV[›)û©?æØ E~è+›åɲ =«)ÇD{e·uùsIЗÛð±ƒ2‚j‘øž²ân"ÊÙ¯òÜÓø5g©hAÆ?ŸÿoF]ÏWï9 Ê1äÊý•å —(ë!ÖÕ>®z®1HÙJ›ƒ¨d+‘|ª¿‘—@ÝáIEš‹Ý¹5á)¡ÄœáÑÞó&©ÜíÛ…;v»¯mýû}GHå åD¬¾ÿ~O݈¬þ<8Qçý*?ò]…òùéßAåÒ´fPq"}?”¿“ÞJŸËØ—»¥AÕÃ{ÁwöÊZ¨=ÿÆAd®Y<+çÙ’h9£K–pov÷²U<˜½õfÊÓ_«˜+dœ 2³SÞ²Š#£Ôzu>`V ‚á!äRšÅ¸cS¨A"ò à‹ÑÄÇ@j2 H&§šÑˆZmÚ¶Äì§€2n–Ø õ< Õb Sk$õb ¤ç^÷:ؾƒ¸Iøï¡ &°‚µišú' ¬4/.ePZGyn -O¯ñŠÌ¸^²!§%W‹©õ´¬u­¬öÑþê :‚#—¾å!Ä…†õfqÛ…ƒYÞÐÁ²EžOcõäa¥a`ˆ·¿qÐ÷†kpåbâ5.W.%‘÷t¸™5WTßéß–wmPÅ2|ëÙóã!ý@ÕeüKøS¬«j þ‚H%fDK±}c£Q‚IüÈu_3m©õ‰ûQóþxáYÑìÓëÆ÷bˆ™‰(F÷ØLLí™äZBÊÄär„®šÅdZã“‘r@r/ÂØ’¼ ÜÏÈY`ü’¸´e"ÕF²a7°[€2ÏÞqŒ¾°£ð! 2Žz÷ÿW9ÿ‡Y%-°Ë°ß“¹ÀgòØSh¢^§¸B°ÄyñȲ&0›)@¾(V#€vô9 Äíônc!¥ȯlƒ\g0H¼B‚*Rƒ(d7iÍ,ñ#rˆø‹‘âªÈû _‚l-¾ ÄIÝ8²‹8‰%Û ªTˆ°•"Ù^º'öJ)òxD*r¦xD™&ªq $?Cò­lˆ`œè4gpŒ¡À û4’*TlJÅ-Ø”Ñ K^¡K¬QüØæWl¶² )×Ë1Hz/’©²¸NALôB‘•óQD6÷¢ Åݨ² Et§ŠœËTr(@ðµÜ äˆÆ@-òË\¢\§œ–L ­2VÙÄob¯¸€Iœ8<ñ#ç˜lgÛ:'íõV> y^6ÆÍYÙ¸W®Q&2@|‹â86 ~Üb‡ü…Žâ&çhÏ2®²ƒµâUYŸ»Ù!{b‹Ý<"ÚÈBkå|» ,’ A g+𕜀-^ã8 ëä{ì/0g™ÍYv³ z²‚r3ûÄbŠˆËÌÆCWy¨f-ð «A|…r°œœç G©rKUþĹäPz3µ ˆ?ˆÌ¾üƒü(9=š¶ih´Uî Gø‹âsù­e+$Óð£ ?ü{WDÅz 1‚÷Ð(3FNd+;•g¸Ç^'ÞໞrŒ?‘¯¾i!–¡Ùõ”\°u XKÔÇÀÚ¨-s–úX“´wÀ¥Íó.m/+]—Á|Üõ(q£X à1žÓOñg£žò µÀþœÉBqšŸ}Å 6j ‚=¨Ò^$Õnª J e&(eZs>­”¸{2Í*Öãåî-4£ƒyŽ Ø^aßbô´wBu†òÔ*‘WÁÖMà¢ÉЩõ GKÁs7ÙØbˆl‰bì ì*VD>ÛÕG”«¼•µŠ$õ‡¹Ž^–"V‚öÈ'a]Y¸Õ‰ô£ƒr†Ü㪃KÖ*ow‚½Â× dÛpo ³ïK0„f‚º:˜fÿxSP«ý›!Öÿ* ™6(ýü/ƒõ‚!AíéMB2®bœ¾äâv0WãÔ©`V[;@œÐÙ\Ôƒd“do¨~(üÔýº1Vå…Ø³‘vP1ºt D”ßZ/û+Л3©ï „pEðó«ëC$]õ? rIFÄ.W~OšÃÙ¥Õ4’pKîÄ­Ýk-íQs8h-¬1 õ5zØÊõak¨7¬> î±vÊJu¹}”áVM¯Ê: 6°ƒáûÔfÍ«Ay\Ô~ç €ªÀ÷…p¤sw:¤ÝZØ©Þ"jW;£PUÜ ô!ø°@¶C{¬™H0» €Y…p2wÂ\q?@ä@l@¸ ´@öðv𸧠À{èu0À} x*´ ®àÚ‰êUTPF!¦Âñ ÝñаÌe±+ ”CÁ Ýëý¸Õ¬Þ¬Ú-'~Kÿ<çVTÅ_Ñ™<µ$~XÆ]/ÕüÄv³äæJ[#7m«µŒW¬™F&Ô®cï1Ìž ×ÏÚÛÀ~“@i#‡˜Ä.kD{`¼ò(˜>åoñ²ú+¤Ï}áÂ]ŠN\»¡¼…'åå M.öVjÉHNWÑÂÆFc¡ã˜ëk»#˜ŸBS'aR4@ ˜(«@é P廂i´¯z–¸9š$¬jžÁc´{ð'?”&$§$7BâN-’h™»i\€ð¨Ä)ÇŒ*ˆb4cZ‘ ÕGÁø‹= d–xä%iñ±ÈÄ.ºB|ªü’«ÕíWç `&¤.ªs$![ÛY¸E 6ˆ#ÄAü„EBü¸9ŽMGñ9iLÕüF/FÐûŠu²7ŠX&‡{™b• bS¥rˆ9L^’³A<Í*àM9Äh^ÆÉ¥˜Œä4Ñ÷Èpù6my/r+&`sœ¯QhÏà'&òpŠ •+€J5ç&Pú÷¥iY€I.GÐQ´ªhN’8w¡“N/ž!Nc\Ô!•×Åz0Ž÷yBN“žÄb™xUNg.È'Ä|à9±älú‰}Øò.ñ-Šì%Îs@6e7ÏËzd²”® ð:’™ê l:Š[‰‹#BEeª8„—Åö)àa¡seg ¹xd{9 ä·ÖÏ _²×&I‚_â9ÑxEyäÝv}àiXb¼rŠJ{“Ý’› .Ù/¶ÌçG<ÜÃI²äÇrºhƒºQ L¤¸ƒR½õ:ˆ#€ÉYDðïgÁ"2Aþ•\"ÌD¡ŒOE;" Õ¸DOq†¤2JÙN3ÑF™Ê e…ø+µD>=YLƒ¾è¸˜‚:ÿþÛëÛ«ÿ0žÁf+0~I®„ËÏm‹HIï q]?ÎB6ºß&•Ùî}sÂ3C>d©5Pê&ml=b“£ïK<€Ë]”Ü ®’y O1Ž‚ëc0è¯c1\M“5Qµ÷Ìv¸Žñ޹ZŒ&Óì 3oGr·ñ‚]VK aŒºXŸß›s@>c].šM@ì³÷ƒ|Ùúhný â»5ÈÖ\#퉠>,¶¶BÙA¥1=ù2iÕÓB¾ook{=ùžzbrIr‘ýŠù€y?3Ägby4§U\å*&wp'yîîf"Ýêaõ—ÍænºŠbš2TΗñ›xWYHRNT– ‹¶êh@WFšÒHSkYjH×QePåZäk“ÕÕp«g·>®ËÄ)ÓÏàQöˆ‹v}2=’-õÎ%*ÜLj'Ýz'‰ˆ§;Q©£$R<›¹ÊÝ]†«Åxc“=w£â2ç1ŒñÛÜ Ç̧𫟧ŒDÔ¬Qw7ºï]ßÏô”=ø…~ê¥#ãÅIe¶¸ EnS±¨O>*óx‹<{®½‚ÓâQÑ“vÉÝ`o•;?%@5¥ ßµŸòÑÑbÈjY ²¹ÌÑ™` €ÑˆË  €€p‡åe ‹K Ê…h"žQÈ 2D' C< ì¨{• Fˆ¦¿#ý›ADa=*».N¨oáŠ|§ÍÅ»ª©ì4z‹Qf®¦q)ÙXƒDäH¨cm†äHµ%ø¸ÎAÊC† ÕYvbO³ìÚ'àݦ†ô C•ž®Þ ÕÑ/AêÑ”…0 €rçïhy,ù3ƯZ?àº4—·‘5RU}Y„¸émÂ!¹-þ†ÕYwã²çêãÁNDþ Æ ÿ0°ïTŸót²$‡yü`¦úGƒ½RH<¥~ ¿ïa°¿V¿‡h-Wˆëž!ù`r=¸'„WB {$ ¾[£!Ÿ7êÃë¿]Œæ»Ã¾»íÆ`ErK,‡nÆ v¼PÏ|‰õ€71 É?‰Äi d<T%ïüÆ`bhÆ·x¹dãAŠå«¦hhn “€9 Ý.â7Ì"nṓ:Ô±b\â’üJnì7E¡(”íÉ"KžÁƦ?!þí>Œ@0C䣣++ Pš%ª–“Gž’N )JJ¨Ò¦¢×Êð±ÎõL4W-"]ù[ïJ¤{7 ôí(XžÍžãÞÓ€â=‹…Ç›‹Ê_Pƒ®"ëEÿ;‹¥M(?ОL!JNA }“rOèm„Xí@Ÿf< Y3Kà>‘x hm>ê`Ë÷aëÏ oŽ*ÀUÑí1Ïd„ÝÞ[±ž¥ †úÆa˃þ XÊ Ñ7ø%ó<ÓÌîu<šÅdåCëôÆŠ ìhú¡b¶w<\ŸTc”o¬±Êgý %žË 4œ›ÅyY« ¬ydxï¿|òÏ^µî»>j>|ã)b9Ëo,AÍYº=ûÑÒñȬã77ϸts8É̵¡é nJÈø2Ïorcd¥˜„Rý2 #“]ر-þ `&€0ŠŒz€b,ë#ñoÕ§#€˜ ¾ èûŽÞçé=èþÓDp{áãõàÏrµ+ߟglõ?íY—¾…?VôÍž¥/çþD´¸enî/^Së!v]=]ûʯm¬3ŠÌKÝêc÷…·óš&®^Ëõ/½ñX´¾8síϲ5‡ÝsÞWç—×ô®±Mžk)ÛË È¯Ñ¾â.eÏ.ÿ #°¾¼®ôQj/ª’‘W5R»T–@ð]#Y]J¶€¯Ÿ‘„´káØ› wCke4ÐMùÒläº5òV¤[5OÔÃËn-ö§dÿØÇÄe‹øe\úÂäMTùS¼#èñ¾Öâ„™¶G4DX]’'!t#Ú²~Ó3àZçŠÚÚNÿü}µfÀ2ùÄ6&Ýðñ‡O¾ ¹ ‚mÿ«œÿÀÃáp8‡Ãáp8‡Ãáp8Žÿ»þgo„‡Ãáp8‡Ãáp8‡Ãápü¯ä ‡Ãáp8‡Ãáp8‡Ãáøè_½‚¼*bÜWðIEND®B`‚snd-16.1/pix/fmeq15.png0000644000076400007640000000250511147553267012754 0ustar bilbil‰PNG  IHDRY+å± —3PLTEÿÿÿààà€€€   ðððpppPPP000ÐÐа°°```ÀÀÀ@@@ ÍçðØ pHYs  šœtIME×-4(<]¥IDAThÞíZézã* E"à…Íïÿ´Ãf0$Æi{\4_S—âøDhÁ&ä÷…""%C~\4“ƒ†ß¶ ,ü¨¾hûk:‚Á3ŸDTªæ•3fÐó…Hç—s%sâìdðÔ/³¥­â2>áàæ;™\æ_õe|Z’žG„í:,d‘ƒ¡Çáê–<†^D.ƒ¡‡Â+eÕÌÏâaÔ³Oû× ±lÝUP"Glâfc€€Í˜gŸµZTk}‰¤8*ØÊF.üïÃ^ž]#p© Ìö|Á{_èKÊ-h€V éVݧF/Ô&ùä&ÖûíeÁ{…ÞÔJÓ;™á=ƒþ"F_ÉýÄ3ðm•šÙ1ÒåQk /H¿.ØÒ¬M»£zÓÛ¼|¢à0è/Nm>::R"_GŠý}ê²¶³–Ìÿ«²`C³øòðÑfV#éaö„6/E³z° ««¨æn§UëíýV[ð^{ò¼Lîev‚.fhéy ›3¶ÃæäÝeÓ¼Öë3-ܳmª¦ÐZ°ª™D='¢j¨%ù<o´†„YvãÞ<Æ ! OË;aaF¿Ÿ¶AqŸKw8¨&0Û3ªm”·–¹¡pmÁª¦K,ÆšUC•IÄ…°­œD¤r5¶.‡ß‡1âÌ*÷Œ/1x\œ„¥a¨g«T¹×&©"beå•Q?Ikú·NuÁªfâ_󉪡J º‘µœÄ|²¶:ùð{ ë‡!¥OƒûEBXfó¨—)Öœó<-U¾ÕÑšÿH™Í¬i7Žð{XSCÁ…L%ÔWÜ¡ \#C¤4·´ÇRK¾Õ“­Š(†A‘¸Ø#¹–ˆ iBl¢¦À° ²Œì Ëüþè繚dXg†ûu]þ1Ç™³¼?‡sŸõsD2™L"""i°DDÄ!""å „„„„„4kbï½÷–-[???Vžˆ¨3HVV\\\põêU…'´~ýzLž<Éd8pà«ODÔD"‘ÀÝÝ^^^ OdóæÍ°··‡ƒƒ&L˜dggãØ±cl""¥ÕÔ/®Y³8sæŒÂ)--E—.] ¡ñw^éêêB$¡ªªê±ï¦¦¦"''§ÑñuïÞæææl=""Uï¿ÿ¾]fèêÕ«8{ölƒÿŒ±cÇ"22’­GD¤ Ò^\\\àââÒàÿÿôÓOl5""%ÀÛx‰ˆH9äwÞÁ°aÃä®olÙ²ß~û-²³³¨©©““[€ˆHE5ù–““îܹ#|ŽˆˆDFFÂÐÐP.“ÉPWW'÷Û>}úàСC˜6m²³³áàà€íÛ·³úDD*L¤j}aéëëÃÜÜœщˆ:¯„ˆˆ DDÄ!""„ˆˆ DDÄ!""1@ˆˆˆ DDÄ!""1@ˆˆˆBDDÄ!"¢Ö£¥Ì3'‘H*7L*•²Õˆˆ «©©Áýû÷å†ýûu¹DDÔ1øJ[""j^!""1@ˆˆˆBDD """1@ˆˆˆBDD ""b€1@ˆˆˆBDD ""b€„ˆˆˆBDD ""b€„ˆˆ DDDÑRæ™ËÍÍÅÎ;å†UTT°Õˆˆ ëÒ¥ F%?ÃZZl5""% ’Éd2Uša}}}˜››#22’­GDÔx „ˆˆ DDÄ!""1@ˆˆˆ DDÄ!""1@ˆˆH±_¢Vòꫯ¢¶¶¶ÁÿwqqÁüùóY(RìÊ„¨™Â°eËásRRûs244„¡¡!Ž;333xBÔYÅÅÅ6………°´´Äü^x C*waQ§•˜˜777Œ;¶CÃ㑪ª*8::âÒ¥Klb€)«ääd¬]»Vé6Öb±+V¬ÀùóçÙH¤ô”úVFFÞyç¹aeeel5j¶ÚÚZ¸¸¸ ++ 111Jn/^Ä´iÓØ`¤Ô”º+“ÊÊJܹsGn˜,--Ù• 5‹££#"""”~> €_|‘F Ö¾°HÑœœ|öÙg Duu5Te•×ÒÒ‰'ðâ‹/BCƒg›Iùp­$µUUU 4þþþJ¥P¥ý¥šš8;;ã—_~ac’rîä°¤Ž:„;wîàÃ?Tùeyã7••ÅF%µµƒâí·ßV‹ð€‡bÇŽlXb€µ¥ï¿ÿ›7oƃÔf™ÊÊÊàíí-tìH¤,x ‹ÔBII """°jÕ*”””¨ÝòÁËË ÚÚÚX±b´´ø§K ¢»víÆŽ«öËYVV†5kÖ`ðàÁppp`Ĩ%ÁqëÖ-¬[·ŽÅ b€5ÍÕ«W±fÍ\»v­Ó-{PPÆ}}}®Ä!jªüü|¬\¹ýõbcc;e BBBPZZŠ“'Or… QS,\¸ HIIéôµàÃ…¤ x/)½¢¢"Ì™3ÇŽcxü555077G^^‹A ¢údggcõêÕ …ŠuÛÖæ’’’0wî\ܾ}›Å Ñ#R©>>>Ø´i~üñG¤—/_ƪU«póæMƒÚ¯ÒÙ±c’’’pàÀ£ Î;‡ßÿÆ c1ˆB;<¼½½QTTÄb(àóÏ?ǘ1c0|øpƒ Ôy”––ââÅ‹X¾|9$ ß:Ù 7oÞÄ”)S‡¾}û² Ä!õ—””KKKÔÖÖ²-ôàÁ˜››#&&fff,µ9^D§‡àà`Ìž=›áÑŠŠŠŠðÆo°Ä!õ Õ«WÃÕÕ™™™,H+KOOGXX Amާ°¨Ý”••ÁÃÃiiiøý÷ßY6"‹±~ýzhhhÀÉɉ¡Î wïÞżyó䆳ÕT”ƒƒ.]ºÄB´ƒÔÔT,_¾zzz˜2e BmB$SâÇ{e2¤R©Ü0ccc˜››#22’­§äÊËË‘——///=zR©”O“·3mmm$&&âùçŸg1¨sˆD"èê겕TÐéÓ§qåÊlݺ•Åè@ÕÕÕ¸té„:_€êùùçŸqïÞ=¼ýöÛ,†’ðôô„ŽŽ/^Ìb„”Ott4‚ƒƒqêÔ)¤¥¥± JfíÚµ(++Ê+X b€òHHH€§§';ôSb‰^^^ÐÐÐÀ›o¾É‚„:NUUª««1nÜ86lØ œÎÒÔÔdQˆBí£¢¢ÉÉÉ€­[·âçŸfQTLII ÜÝÝQ[[ 777hiq@ jcáááHIIÁÆY 5àéé ‘Hƒ Ôú®]»&eìÚµ‹]¬«™Õ«W#==VVV˜3g B jIIIxë­·ðǰjª¢¢ÞÞÞ8p D"^yå… Ô|¯¿þ:’’’PZZŠ»wï² @ZZV®\ ===L›6!=™L&ƒX,ìÝ»;wî„T*E]]‹ÓÉäääÀÑѧNÂÔ©S!‰X”f(//îH422Rûž4 PJJ Äb1¤R){k%T*ÅôéÓqêÔ)ôéÓÖÖÖ,ŠJKKñÅ_àã?ð÷ë™W®\ mmm©¶’’|÷Ýw€cÇŽ±3Jj££#†???Lœ8‘i‚   ¤¤¤à³Ï>†­[·•••2dÈc½Š« ¥î·>úúúìW¸qãJJJÄ‚P“YZZÂÎÎk×®egŒØ»w/6oÞÜà«&Œ1wî\¼òÊ+˜>}:„¢¼ÊËËáìì,|NLLDnn. CÍfmm~ýú!<<œÅø___xyy¡  à‰ß555…‰‰ <ˆ0@ «¬¬ (:Ëd2deeñ/›ZwC!¡_¿~prr—_~ ]]ÝNû{yy9®\¹777H$”––*ô{###˜šš"""ÚÚÚÐÑÑa€0@Ú>,nݺ%7lìØ±¨­­åÖÚݶmÛ0cÆ XYYACC£S,sZZ 1qâD”——·Ê8—,Y"¼úÀÂÂBåB™¢„²²²[¾;wîàÃ?ä–‹”Êwß}ØÛÛ«í2ŠÅb\¾|{öìÁåË—Ûl:~~~èÞ½;ž{î9Œ?žÂy²7n3û÷ïWšùÛ¸q#Μ9#|ÎÏÏGff¦ÒÖsÀ€000öÖ[ouØK”.@ŠŠŠPRRÒàÿ[XX@*•ÂÄĤÃçµ¼¼÷ïßGuu5·DM ¡¡]]]ôìÙzzz6eee(((€T*UùQ´µµadd$õµ”©©)Nž<Ù¤ï*Ý%ÿÇãĉn´Ç¯G /^ħŸ~Úèwd2Î;Ç-uZ#FŒ; €+V`îܹ6O.\À¶mÛ„Ï•••¸té’JÔsôèÑèÙ³§Ü°>ø“'OæÈ“¨Ú5ºº:á6½ËÉÉÁñãǹ…!µâææ&wtáææ†Ñ£G+õ<áÿþïÿ„ÏaaaÈÈÈPŠy[¹r¥Ü­Òk×®…©©©R̤eggã§Ÿ~’–››+tÆF¤J,X€É“'cÉ’%zzª5„‡‡###™™™rG*íÅÙÙ3gÎð÷5e}Ö†¢dÊËË-7¬¤¤¤C÷‰bhhˆàà`€™™™ÚtÑñÏ¿½«W¯â‡~@```›NëèÑ£xæ™gC† ÁÀ•¾> PWW'×=ÉÚµkåî©©©T*å֌ڜ–––ÐõFhh(^xáôíÛWí—»¸¸>Äüùó‘€ŠŠŠSSSSx_Hpp0œUî©~ˆÆ×_-„ÍŸþÉ¢P«ÒÔÔ„……žx㈺{ðàfÍš…üüüf_'9r$&OžŒíÛ·«t- j¦²²îîîHOOGLL B­ÂÅŇb!þáܹsX½zõc}Ô5fâĉèׯŸÚÔ’¢¦än‡þä“OPSSÃÂÂÜÜܰk×.•¿0ÞNŸ>+W®ÀÇÇEEE ~ÏÚÚÎÎÎpqq™™™Ú,?¤“8zô(jkkqúôiáÍ„DqppÀ’%K0uêT¥îI„…… ýWýS÷îݱoß> 4cÇŽU»åf€t2<ºjpttÄýû÷YzÌ„ pøðaôë×Åh™L†¸¸8\¸p6l†GEEa„ j»Ü|'z'Ó»woôîÝÀß9Þ¼ySØs*((èðÎã¨cáÖ­[ÐÕÕî¢&쉋D9r$,,, ©©‰o¾ù!!!°±±Qïåæ=²mÛ6œ?¿þú+_TÕÉÒÒÒ:ì½Ôúôôôpøðaµ¼;ˆ ¤$FŽ ¨®®†H$ÂÚµkÕâ= ™®®.¢¢¢`aaÁbP³i°ÔTÚÚÚðôôDyy9Þÿ}XYYASS“…Q1 @LL à Ô1¼½½‹¥K—bÚ´i,ˆŠ:t(…£J¢–à),j‘@,# gÏž}¬+zRfffðññ½½=‹A­‚·ñR«‰‹‹ÃÍ›7ñŸÿü999,ˆ166FHH&MšÄb„¢¼’““qëÖ-¾K‰$%%aøðá,µ*^¡V7|øp¼üòËGÿþýÑ­[7¥ÅÆÆ2<¨M(õ5²²²ÇÞiÁ.ÉUdÏDCNNNprrÂ7ß|ƒˆˆDFFò͉íÌÒÒ,u¾)..Fhh¨Ü0n€TÏ;#wÞy›6mÂ_ý…ãdz(íÀÖÖ~~~j÷žrR¼Bíêþýû8zô(Nž<‰³gϲ mÄÆÆ»wµ5‹Amw¦% öddd„5kÖ`Ïž=°³³cAÚ€¹¹9üýýÔæøuSSSœ8qååå077‡T*åéÉVзo_œ={FFF,ñ„ÔWïÞ½ñì³Ï¢¤¤çÏŸçÛïZ!”oÞ¼Éð u.vvvØ¿?Ìb4SPPºwïÎBP»á),RŽŽŽ¨­­Åõë×±}ûv”””°(D ¢¦yôìÈСC±hÑ"¤‰–/_Ž!C†°Ô®x ‹”ÒÂ… qýúu|üñÇ,Ƹ»»ãÓO?E¯^½X ⑦¦&FKKKhjjbïÞ½ÈÍÍEuu5‹óÎÎÎðó󃎎‹A<!’ÛÃÑÒÂæÍ›‘‘‘wwwhhp•}¤[·n9r$ÃxBô$ûöíC—.]pïÞ=œú½zõB||<”v>gÍš>0HJwaQ§”››‹ØØX|ýõ×8wîœRÍÛ¤I“ðí·ßòQÄa€2ËÏÏÇ‹/¾ˆ¸¸8¥8Ú6l.^¼ÈSW¤x/uj½zõÂÕ«W‘““ ôïß¿ãþ54`nnÎ𠑪ÙþùçŸ „™™Y‡ÌÃË/¿Œ#Gް1ˆB¤Š¦N lÙ²í6ÝE‹)õE}¢úð9¢™5kfÍš…1cÆàÖ­[xï½÷ÚtzK–,Á¶mÛðÌ3ϰøÄ!RÎÎΨ¬¬„½½=¾ÿþ{ìܹ³UÇ?nÜ8ìÞ½&&&044dÁIåð.,¢&J¥ÂC¬¶¶¶(,,Dyy9$I³Æ7jÔ(DFF¢k×®,.©,^!jèééAOO ÈÊÊBHHìííºkê…^€½½=¢££Ä#Pg·ÿ~ÄÆÆ6點žž5j‹Fj×@ˆZèÍ7ßd¨Sâ),""b€„ˆˆ DDÄ!""b€„ˆˆ DDÄ!""‘<¥îÊäþýûøüóÏå†UTT°Õˆˆ {úé§1sæL¹a`«1@ž rôµµÙjDDJ€×@ˆˆˆBDD ""b€„ˆˆˆBDD ""b€„ˆˆ DDD ""b€„ˆˆ DDÄ!""b€„ˆˆ DDÄ!""Qc´”yæÒÓÓ±jÕ*¹a¥¥¥l5""H㌱cǹa£Gf«1@§££ƒ!C†È ÓÐàY7""eÀ­11@ˆˆˆBDD ""b€1@ˆˆˆBDD ""b€„ˆˆˆBDD ""b€„ˆˆ DDD ""b€QSø„ÈÊÊÂøñãžXHHJKK1hÐ L:•Õ'"ê,RPP€uëÖÁÄÄDáñ÷÷Gaa!455êêjÌš5‹-@DÔdýúõ1b>|¨ÐDöíÛ™L†µk×¢K—.ÈÎΆ¿¿?žzê)Lž<™­@D¤Îâää„;vàöíÛ8sæŒBILL„³³3ºtéèÛ·/444™™ùØwe2d2Y£ã“Éd¨««c뵑H‘HÔô)((@^^Þc_044„Nž< ¸}ûv›ÎøçŸŽ   ÿ¿¸¸QQQÐÔÔd+µ¹sçâøñãMK—.!00ð±/¸ººbÞ¼yí6ã›6m¦M›üccãf]Àÿ§sçÎaúôéÍþ}mm-"##aooߢù(((€X,ÆÈ‘#›=ŽÜÜ\äååaĈ-š—[·n¡[·nèß¿³Ç‘””µh^¢¢¢0zôh<õÔSÍÇo¿ý;;;hiiuèºRSSƒ¨¨(L™2¥Ù㨬¬Äõë×agg×¢e¹ÿ> ð /4{™™™(++ƒ™™Y‹æ%!!†††èÓ§O³Ç ´h^~ýõWLš4©E;¥-]O ºº111˜4iR³ÇQQQØØXØÚÚ¶h^ÆŽÛ´/ÊtêÔ)ÙºuëúÍêÕ«egΜ‘æíí-ûᇼÌÌÌLÖR-Gyy¹ÌÊʪÅó)[¶lY‹ÆÑœö¨OsÛãŸÞ}÷]YXXX‹çÅÞÞ^–••Õ¢qŒ=ZV\\ÜáëJqq±lôèÑ-GVV–ÌÞÞ¾ÅË&{÷Ýw[4Ž~øAæííÝâyY·nìÔ©S-DzeËd‘‘‘-ž+++Yyyy‡®'2™LVXX(?~|‹Æ‘žž.›1c†¬½´ús ¾¾¾ððð@uuµ0ìõ×_GDD ¿ÿþ;jkkaccÃcE""Õäã{WWWÜ»w‰‰W¯^„‡‡£W¯^r§Ž9‚={ö@[[0~üxtïÞK–,AQQ¬¬¬°yóf 0€-@D¤î²gÏÔÖÖ>6ü™gž‘ûüí·ßÂ××÷±ó×ÇGpp0êêê ££ƒ§Ÿ~ºÃúÊ•+JQ|X[[+żlذÊÑ1Ahhh‡®ʶ®!44T)ê1þ|¥¹ÒÇǺºº\Oþ¡ÿþMºøÝîÒ£G&}¯±?ü‡MGQ–ùÐÒÒjñEÞÖòèkeн{w¥™eXW444”¦&ʲÁ€nݺq=©g]ÑÓÓk¿éñ ŒˆˆšCsëÖ­[Ui†»téÒá§}D"ºuë++«Žo@MMá¹çžëðyÑÑÑÁàÁƒ¡¯¯¯뉥¥e‡?/$‰ðôÓOÃÒÒRiÖ•*Å‘ÌàÁƒÑ³gO¥XW¬¬¬:ü®H$‚žž,,,Tf{,’=é±o""¢z(Õ)¬ :C‡…X,Vè·÷îÝ~{ôèQ¶¬šâþqÝjžS§NaçÎͪ˸qã0tèPlÙ²Eù¤¦¦ÇŽCJJŠðoùòåHMMmrx¬^½Zøm||>ÆÆÆèÝ»w£°€€ÔÔÔ`Ù²eèÕ«—\—6±±±8|ø°BÝÊ„……áàÁƒ2dÞ|óM<ÿüó µéÈ‘#-Ü1???Lš4 ... Ž+-- þþþèÛ·/–.]ªÐÝ;zzz˜6mšðù¿ÿý/LMMˆ”””'.Ghh(>ýôS\»vM¡6:rä~üñGwe"•J±páBìÙ³ƒ˜˜˜4¸G™žžôéÓîîî Ý,ÅÛÚÚÂÃÃW®\Á„vðôôD¿~ýš4>WWWdff w*Íž=+V¬hòü$%%ÁÃÃAAAB*ýõöïß!C†ÀÍÍ ººº‹Å8pàzõêww÷ïF’H$@II‰Ürœ={áááØµk—Zý½GDDàÌ™3°±±Abb"¼½½›üÛ¥K—bÅŠrçï½÷ìììàììÌ»°:£ÔÔTaϲ>¥¥¥Ø·oLMMaaa””” 44¡¡¡Ø´iÜÜÜзo_…¦»qãF„††âµ×^CVV–B¿ ‡£££pÛó7püøq¬_¿iiiøî»ïêýX,FPPеkWìÞ½[¡éöë×OXîÐÐP >¾¾¾¨ªªÂk¯½†C‡5ØÁhHH.]ºÔ¬6Z¸p¡0Í™3g ¹lÙ2axCá‘™™‰   ̘1Ý»wWxƒøñÇ ÓHMMEBB6lØ ³µµz•hª¯¾úJø½"á£G GÂÂ#88 ,@]]|}}‘ÀÀ@ØÛÛ£gϞؽ{w½Ï«H¥RìÝ»}ûö…­­-„Nd}}}ܸqC­þÞ“’’°}ûö67D…††ÂÃÃC®k™óçÏ#,,L8‘‘???œ¶W¼`Á¡wƒèèhôîݦ¦¦xûí·áããSïxîÞ½‹œœØÙÙÁÝÝT¸ŽqqqðððÂ`ïÞ½XµjF…ªªª’{ôè÷Þ{¯Åí¸ÿ~¼ùæ›Âç;và7Þht!==“'O†››[½¤¶ÄŒ3šu§ÐªU«ðå—_*ô›§žz óæÍÃðáÃ…aÉÉÉ(++Ø1c°bÅ øùùA,ãîÝ»°··ÇâÅ‹…‡–ÿ­ªª ?ýô\\\0cÆ $&&";;`jjŠÞ½{#::Z­¶6lh³q3@ÔÔ™3gOOOxzzÂÕÕÀß= 4ðòòÂõë×áéé‰7€Üµ†3f@OO©©©puuE@@îܹÓà´_{í5aºwîÜÁÉ“'±råJˆÅbL˜0á±p¨O{öݱXŒ½{÷ÂÓÓ'NœÀŸþÙäß>:êi‰eË–áÛo¿>ïܹSèhñâÅm²Ì_}õ&L˜€ &`È!°¶¶Fyy¹0¬9!¼lÙ2ÌŸ?}úôQ(Džþù÷4MmG)DCC]»v•»àWTTTï=â½±gÏž(**’;ÓµkW¥éš£#Lž<ºººððð€H$‚ŸŸ€¿»Ã766–û®6nÜ[[[Ü»w¯Á›LLL…¸¸8œ8qׯ_¯÷{º“¶µµ…¶¶6òòòðÙgŸ¡_¿~ÇÛo¿­2uÌÈÈÀ×_ [[[””” ¸¸¸Ý¦]RR‚{÷î Ï,]º×®]ƒ««+lllÛ&ÓõööFxx8ÂÃÃ…SX]ºt†¥¥¥)ÔµŠŸŸ.\¸€)S¦`À€õÞ Aïß7_,++îP«¬¬„H$‚ŽŽŽòˆ‘‘¼½½±uëV\¾|—/_ÆòåËë=ljj '''¹a111ððð~ëåå…/¾øB®“Çθ2,Z´)))Ø¿ÿc¤ÿIGGç‰{Ê2™ ñññ000€ª««QSSÓäùéÑ£455a``Ь~®†Š;wî§%ŒQQQ‰D‚¸¸¸êìÑ£ºuë†ììl$''Ë iŠôôôÇ.ÆZXX >>yyyÂ2µ…·Þz _~ù¥P/‰D‚ªª*á·±Zëéé!++ 7oÞİaÃ^wµsmm-ª««!‰„a2™ì±;¢þ©®®qqqÂçììlèêê6é wM¡¯¯mmmäææ"!!#FŒ€žžzôèÌÌL¤¤¤ÀÌ̬ÞéijjbðàÁ¸}û6Äb1 „›*$ ***ÛÁRuׯ_ÇåË—‘’’‚ŒŒ a;ùïE—Ç–}×®]8räΟ?Ë—/ÃÏÏ–––˜={6߉ޖ¬­­Q\\Œ€€¿G½>®®®õÞýáëë‹>ø@ØSS¥§9ÛÂÝ»wqúôi 0'NDXXlllœœŒäädèèè(Ô~]]„—_5v×¼yó„v¬¬¬lô.¥¦úè£0räH¼ôÒKèÒ¥ æÍ›‡ü‹Å žVùçz%‘H\¯ l add„ƒâƒ>€‘‘lll0yòäzÔÔTáŽ6kkëõ^’’‚¨¨(ôíÛ2™ sçέ÷{˜;w.P\\ ___…¦3sæL¡ýôõõall ggga˜††F£=üøãxÿý÷…‹Ú/^DEEž~úi<|øP¡—ݾ}QQQ‹Å8~ü8ÌÌÌ0oÞ<”–– À §§‡W_}(--ÅÎ;ëí… k׮ضmüüüðÔSOÁÝݦ¦¦€k×®A,ãÝwßU«mÁ‘#G„›444„v5j”\fΜYï åöíÛ‡µk×¢¬¬ 'NÄ¢E‹„ÿã“èj,** 111€õë×CKK 7nÜÀùóçË—/Gee%®\¹ggg@PP\\\êÝËÍÏÏ6Ô077opÚÎs3FxßàééÙìåùî»ï““ƒÍ›7ËýqÌž=û‰ ^¸pÄ Aƒšfaa¡p bÖ¬YÂŽIvv6âââàèèØàoCBB‘‘!|ž0a‚BÏŸþ£G–{Ãã… ðÇ@$=ñâèo¿ý†þýûcÈ! -³D"¿¿?€¿¯YYYA*• 7*û ¾¾¾rëUnn. Ðè-×ÿÓ§O Ÿ{öì)¬C¿üò ÌÍÍå6z‘‘‘022zâNKrr2$‰°‰_}õ¦L™Òâ7 v& R).\ÀÔ©SY%V[[‹K—.µè5¾í­¢¢qqq|É„ˆˆÚÃÿë\nêµmIEND®B`‚snd-16.1/pix/rmspk.png0000644000076400007640000002440011147553270013002 0ustar bilbil‰PNG  IHDR»K£ÈsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ# Î&Õ IDATxÚíÝyXWû7ð/K€°ƒ ".hÕj­¸ÛE,ÖÚòÔ"yŠ¢Xq)@¥(nØjpcGKp·i­u© j­¨(X÷Š‚¢"È ÏûG_æg”% Q’ÜŸëââšÌ™9sΙÉ=g2sF‹1Æ@!„4“6U!„ „B(€BQñRZZŠàà`¬Y³‰¤ÑôUUUX³f ‚ƒƒQZZªðÆXZZbçÎÔ*„¢$,, B¡ˆŠŠj4}TT  !¦ðƈD"Èd2jBQ‡ríÚ5¼ýöÛ€aÆáìÙ³¦?~<Ž;†?ÿüÇÇØ±c©– !DHs™››£ººW¯^Eyy9¬¬¬¨– !D é¾ì.\¸6l€©©)Äb1|||˜˜H5M!šÖqpp@JJ `ß¾}øä“O俇††âðáÃÜ´££#Nž< ¸xñ" @µL!š@fÍš…ôôt”””ÀÃÃCnþùóç‘ÍMOš4 %%%HOO‡··7Õ2!„¨!­Ö4” ÇC||<<==©e!DÕ{ „BB!@!„P!„B„BB!„!„ „B(€B¡B!„!„B„BB!@!„P!„B„BQ˜nkßÀøøx;v¬ÕWdhh(:tèðR×9uêTÈd²V]îîÝ»cåÊ•/}½ááá8wî\«o÷ØØX˜˜˜¼´õI¥RL›6M%¾<¾øâ 8::¾Ôu®^½ÿüóO«/ûÖ­[¡¥¥õÒÖW\\Œyóæµúr>³fÍz}¤¶¶‡ªwÞ³/Gܼy3Ú·oøøøV_±«W¯ÆäɓѳgÏ—²>///„……ÁÀÀ U—;++ ?üðæÎ CCÃ^c ‘‘‘°··W‰×!ÃÛÛvvv/¼®œœDDD¨Äþ³gÏÆ€^J•J¥ˆˆˆÀرc±páÂV_ö€€øûûÃÖÖö¥Õebbb«/÷©S§Ë‘W@c(,,T(í  Uâ`ò÷÷Gxx8¦OŸŽŽ;¾ðúd2ôõõ¡¯¯ßªËݧOTVV"""/åãÌ™3˜;w®J´»¯¯/"##±páB˜››¿Ðº>ŒQ£Fµú6º‡üÓO?ÁÏÏï…×UVV†ììl 0@%Ê>wî\„‡‡cõêÕÐÕ}ñ¯Ñšš•hwgggÀÆáííýꈮ®.¼¼¼ì?‘£¢¢ *,,,¥¥¥/@~üñGL™2¥Õ÷>ê <»wïFvv6ºvíÚâõ<|øëׯW™3phß¾=:t耋/ÂÉÉ©Åë9sæ *++¹T888@(âÁƒ/¼Ï/X°qqq*Sö.]ºàÁƒ¨­­}¡RYY‰¨¨(¬X±BeÊ>räH¤¥¥hÅ?¢K$•ù­ãâ₼ðz>Œ>ø@¥Êˆ„„´xÉÉÉxï½÷ÀçóUªì>>>¸yó&’““[¼ŽuëÖaÞ¼y/ålöUZ¸p!bcc!‹5îxŸ6mÚ Ÿì<|øEEEèÛ·¯Ê”[WW‹/n½dëÖ­øä“O`jjªR;ÔÀQ\\Œììì-ÿèÑ#,^¼?ýôT••d2ÊËË[´üÅ‹‘ŸŸ±cÇB >iiiH$Í^6//ï¥ß€ñªtìØ¸zõj‹–—J¥ ÃW_}¥reÿý÷qýúõŸ4Ý¿ X¾|9TU« ¿ýöÆ÷RïrxU‚‚‚””„4{Ù'N ÿþ033SÉÉÅÅû÷ïoѲ«W¯F@@ôôôT²ì}úôAQQQ‹¾LöîÝ‹qãÆ©ì—È‚ pîÜ9œ:uªE'MwïÞÅ!CT¶ìJ¥Í^6)) nnn022¢ò²DDD 22Re+ÔÂÂvvv¸xñb³–ËÈÈ@ff&þûßÿªlÙß}÷]Ü¿¿ÙÁ³°°mÛ¶…ªëÒ¥ îݻ׬eÒÓÓ!•Jáàà Òe>|8Î;׬ÛÎóòò°qãF«l¹»ví }}}ddd4ûd±mÛ¶èÓ§jïô¬ÑÕÕeIIILlÞ¼™íß¿_áônnnjQîÂÂB¶bÅ –ŸŸ¯ð2?ýô;pà€Z”?22’?~\ãÚ1ÆfÏžÍ>|¨pú–ššªeonYÔ¥ÝuA”bôèÑˆŠŠ‚Bé---Õ¢ÜÖÖÖhß¾=ÒÒÒº®/•JñèÑ#L˜0A-Êïää„={ö(t2==sæÌQ›}¾S§NÈÈÈ@^^^“iËÊÊÀçóaoo¯ewpp@jj*x<žBéý^hí´Ø³Oï½F<ñññðôôT‹ÊMMMÅñãÇJëææ†7ß|Sm¾L6mÚ„¢¢¢&ÓéëëcÁ‚juòpâÄ œ={¶Étƒ R¹»íš¦ÐYæææðññQ«²}úÈÍòä ²²²êý#„¢:¸WÚ®Y³Fîävvvpwwoö {ö쉃"..úúú5j”ÜüššÄÅÅÕ»ì“'O¨E!DÕÈÈ‘#Áãf˜šš¶h…+W®„¿¿?:uê„‚‚|ýõ×ˆŠŠâæëééáû￯wÙµk×R‹BˆªAƒÕ›ÀÞÞ—.]‚½½=þúë/Œ1Bn~RRzôèwÞy‡ë¹dgg£S§Nxøð!:tè@µL!jH‹=Ýí¨Gyy9"""péÒ%Œ1ÞÞÞÐ××çæ1...øê«¯R©±±±8uêìíí1wî\˜™™)´1<ݺuCÛ¶m©e!¤5ö:tuqâÄ ÅȫԳgOŒ=Zië—J¥8{ö,FŽ©´<ÊÊÊpóæM :T©u•’’{{{+-£GbÔ¨QÐÑÑQZ‡Ƙ1c”ZWååå¸qãw3ˆ2äçç#??öööJ-Krr2FŽ ]]]•n“W‘GAAòòòп¥åq÷î]H$ôêÕKåëKQ:::ÿw‚µ"nnnJ]II ›1c†RóÈÈÈ`AAAJ¯+???–““£Ô<<<<˜D"Qé6gŒ±ÌÌL¨ÔÍÖ®]«ô²xzz²ÊÊJ•o“W‘Gjj* Qjûöíc jQ_-AO¢BiYo$888¸µlÌîÝ»ñÙgŸ)õÚ]÷îÝ•ú ŸÏG·nÝЦM¥ÖU—.]`kk«ÔKÝ»w‡ ´´´”–G=`cc£Ôº200@·nÝ`ee¥´žéúÛo¿EÛ¶m±téRäççsu½lÙ2téÒ111èÑ£vîÜÉõz÷î-lù|>fΜ٢º7n:vì>ŸÜÜ\0ƸÁUE"W×ÎÎΘ0a,ªHÙº/Y²„ݸqƒ1ÆXnn.›7ožÜü+W®°+W®pÓß}÷KKKcŒ1V\\Ì.\ÈÊÊÊXFF[¹r¥Ò‡Ö /×Õ«WY¿~ýØÅ‹Yii)óðð`Œ16~üxVZZÊ&NœÈýgŒ±)S¦°ÒÒRî/$$„Éd2n}k×®e/¼]÷ïßg‹/憑J¥L&“±ÄÄD¶wïÞ¯7--½ýöÛìæÍ›¬´´”?ž­^½šeee±Å‹såÊÈÈà†W‘J¥ÜçyyylÖ¬YL*•²‰'²+W®°72777VQQÑhÞ2™L®î&OžÌcÌÕÕU®®'MšÄcÌÉɉÅÄÄpéëÚæéc÷Ûo¿}áºÎÊÊbË—/gUUUŒ1ƶmÛÆf̘Áå»víZvöìY:XTÒOã—,Y‚uëÖ!77–––Ï9C[[›»&ºhÑ"¬[·ñññ066†——ÌḬ̀téRˆD"øûûsË®\¹ÖÖÖtЊñù|Œ3†»\1eÊ€––ÌÍÍQ]]Íý€ & ((ˆ[ÞËËK®·9þüÞ¦òòrlÚ´ sæÌŸÏçÎü_–É“'s×óŒŒ ‘HðäÉ:teee±X sssÿ¾õ³® “ɸºHOOÇ0`À…º»ÿ>׫€œœ€¶¶¶\]K$€¥¥%f͚ť—J¥rë{ö.È–ÈÉÉÁÖ­[áï‡<<<¸4ÚÚÚ¨©©¡ƒ….aÕÿ2þ|ˆD"ðù|˜˜˜ÈÍn™9sæ ¬¬ zzzÜAöí·ß¢ªªJ.¥¥%µ ŠijDQ;;;<=ºN`` 6mÚÈÌÌ„D"Aß¾}Êïþýû(,,äÞw“››‹˜˜>·/6¦¸¸ÿüóÞ{ï½&‡ÉÎÎFUUœê >K–,‘;6ŠŠŠ  ¹2_¸p &}ûöEMM Nœ8>Ÿ‡F‡• æHvv6š¥¨ººwîÜA·nÝêýúuèêêâÍ7ßT¨Žn߾ǣ_¿~Ü6$&&" FFFrAÅÂÂB©#I5ú „Ïç?w0Õ©ï]!zzzÏÝaebbÒ¬ž¨†§ï€ª»Žÿô­ÞÝ»w—û Avv6’““ZRR¹»®víÚ…ÌÌL,[¶ŒKããヒ’ìܹÐÓÓÃñãÇáååÅ}ž>}ãÆƒX,†¡¡a£yæææbùòåÉdÐÓÓƒ««+¬­­aii‰o¿ý–ÛïW®\ ]]]X[[sŸ?=n“¾¾>–.]ŠÌÌL=]wéÚ´i#÷…]ZZŠšš…/]VTT@,sщD"î2RkkkÔÖÖ¢¤¤Dîs+++îħªª žžžHJJj4€¤§§ãرc˜2e jjjÀãñо}ûçòÖÑÑá~P~üø1JKK¹<«ªª`aa’’’ë¨>R©”»e¶î’U›6m¬k@€„„.ï¶mÛÊÝ UTTmmm…{ú¥¥¥ÉdÜÉ_yy9***äÒ´oß<Ü¥:îJ¡!ÿ·ƒéêÖÛË|ö‹ðééN:5¸¾æŽ¬jjj*7Rjc=Ù§/³ÔwYª_¿~Ü¥´¦Ô7rjCyË]Ω ZÕQ}ôõõë­»ÆÖólÞÏÐæx¶mÌÌÌ|i»víèà !šA,ãÉ“'M^F•J¥¨ªªR‰3êüü|®wDB!¯ ½‘BB!@!„P!„B„B¡B!DéD$¡°°••• ­´²²………‰DÍÚ˜ÂÂBn 7B!­[“Ïäåå!&&ÅÅ۱±ŸŸ_£S‰D"lذ>D›6màããSïS¹õáñxˆ‡§§'µ !„¨z$44_|ñ¢££1aÂn°¶†¬_¿Ÿ~ú)¢££ñùçŸ#,,Œj™BÔP“caåääpãëôèуÕ´!³gÏFXXΟ?üü|L›6j™B4±Ò\UUUÐÖÖ† ôõõþÝ„Bˆšõ@šËÏÏ{{ÚG}@ ÐÛÔrîÜ9dffbðàÁ ¿ØF]ìØ±µµµpwwWxXuñ×_FŒ¡Q宩©ÁÎ;¡­­-÷Ö>MqôèQàý÷ßWø·Su ‹±gÏðù|¸¹¹©OÄÅÅ@mm-ž{)Íܹs±cÇnÚËË ¨­­ÅþýûáââòB¸yóf\½zGŽѸƒ)::‰‰‰Ù‹‹ˆˆ@xx84m¬O©TŠøøxDGGkämdd$RSSqùòe*wqq1~þùgÄÄÄàÉ“'ê@¦NŠÂÂBxxxÀÊÊ ü±Ü|núã?†••<<Ö®]«1ûxyy9rssÑ»wo>Ö-,,`kk‹k×®QyQ·nÝBÏž=é´Dƒ0Æ““ƒ.]ºh\Ù333ѽ{wlw‰D‚²²2zŮСKX„BÔ+€Ì;Üô?ü€ÀÀ@h”ÀÙÙúúú'''\¼x¥¥¥j_öéÓ§ËÝ<ðã?bæÌ™j_îòòr¤§§ãý÷ßèééáÃ?ľ}û4bŸ@hh(7…Ù³gkDÙÃÂÂTêÎ+• •••044ä¦ 5æyˆêêjðx<î.$‡ššx&B,ÃÈȈ›622‚X,Vûr3ÆP[[+÷À(ǃL&Óˆ}^“w©T  Êfkk‹ÜÜ\ê7j˜¶mÛ¢°°PãÊmmmGid›ëèèÀÌÌ %%%Wv•¹W¥ˆ»»;vïÞ­ö;Ð… 0pà@;pÒÓÓ1hРç>;v,:¤ÖeßµkÜÝÝå>svvÆÑ£G52€ÂÞÞgΜQërA,£sçÎÜgnnnøå—_(€–ÉÈÈ@¯^½4®Ü7nÜÐØÛ8= gggÚù5Lyy9$ Úµk§’Û¯R¤K—.(//GYY™ÆíhãÇǯ¿þJGœ†™LéêêŠ={öPi‰“'ObàÀÏ abkk‹ŠŠ TTT¨íŽãëë‹ðððç>ÿðÃÕú2ŽD"ÁéÓ§é,üãÆÃo¿ý¦ÖeLHH¨w̼¾}ûâêÕ«j]öÐÐP|õÕWÏ}>fÌ>|˜HKˆÅb@[[ó®°åçç«lwöE0ÆPYY)wÑ eee077×Ȳ¡M›6*»ý­òº¼¼¼Áª]»v(((PË©¢¢&&& "haa¡¶Ï‚äåå¡C‡õÎ366†X,VÛ1±JKKaaaÑà|SSSµíuËd2Èd2ðùüzçwèÐyyyj<¬¬¬ê§££ƒV {« ¿üò Æ_ï¼ÀÀ@üðÃj¹C:t|ðAƒ=/¹w¯¨“ÀÀ@|ÿý÷õÎsrrBjj*ªªªÔ²ì;wîÄ„ ê§¥¥…±cÇâàÁƒjYö‚‚äåå5x×aHHH½—xÔAll,fÍšÕàÉbïÞ½[ý]ht!„Í C‡Åùóç5®±:wîÌÝ7®i>úè#µ= ' ÓÕÕE×®]‘™™©qeïׯ_«3c« +W®ÄŠ+M3räHüùçŸjµ³}pýúuµ(Kuu5 бcÇ&ÓÚÚÚâÑ£G¨®®V‹²ÿóÏ?xë­·J«n7ŽˆD"H$X[[7™ö7ÞÀíÛ·5òX×ÓÓC»víZmÏ[%H×®]ñøñc|GŒ=Zm†ù®ªªBVVþóŸÿ4™¶oß¾¸sçŽÚ¼h(99Y᱿¼½½[õ¥Œæ***‚H$B·nÝšL« w#) ŸÏG÷îÝqåÊ „BÔ‡Ê)S¦`Ë–-jÑŒ±Ç¿RwÍ-»¢££Õ¦üÍ)ûÈ‘#qòäIl÷… bíÚµt¼·2ºªºá}úô¯¯/~þùg•o„””…îBzÚåË—Õ¢ìááá8uê”Âéû÷ï___ôèÑC¥Ë]÷á¼yó^¦S§N …jqévãÆHNNV8ýàÁƒ1þ|¹7÷©ªÝ»w#88¸Ùß­iŠÎ;cèСª@€Ÿ‰P‡§²ß}÷] üðCµÖßß¿ÙËøùùA&“©t¹ÍÌÌðùçŸ7k™AƒA"‘¨E»7öôy}´µµáëë«e Ý4òtÏÓÈȨU•½n[´X+º¹œÇã!>>žžž „ÒºÑè„B(€B¡B!„!„ „BB!@!„P!„B„Bˆ{­C™¤¤¤`Æ Ü´º½²“B(€(‰ƒƒ¸iG-B!*‚.aB¡B!„!„ „B(€B!@!„P!„B„BB!@!„ „B(€B¡B!„!„ „BH½š|Hqq1Ö¯_ŒŒ 4¾¾¾àóù ¦¯¬¬Dxx8ÒÓÓÑ»woøùù¡M›6TÓ„¢i= 6`Ò¤I …pvvFxxx£éÃÃÃáìì ¡P¹7BÑ È7лwoÀ Aƒðý÷ß7šÞÃà (..Ƶk×àêê*7¿¶¶ÉÉÉõ.Ë£!„U _~ù¥Ü;É{÷î ÿf¯ÐÈÈ555¸ÿ>ªªª`bbò\¸ÿ>Õþøc¥åq÷î]Ü»wŽŽŽJ-ËöíÛñ¿ÿý<O¥ÛäUäqïÞ=ܹsNNNJËãŸþX,ÆàÁƒU¾¾¥­­ ??¿'X+âææ¦Ôõ—””°3f(5ŒŒ ¤ôºòóóc999JÍÃÃÃI$•nsÆËÌÌdJÍãôéÓlíÚµJ/‹§§'«¬¬Tù6yy¤¦¦²¥æ±oß>– õÕô$:!„iU—°„B¡ÒÖ_[[‹¢¢"´k×NiyTWW£¢¢VVVJ­«GÁÂÂB©——òóóÑ®];hii)-‡ÂÆÆF©u%“ÉP^^®Ô6©ªª‚D"………RË¢.m¢ìc$ ªªª”Ú&b±µµµÜMGªÜ&-¡ ¢£££ÔàzzzJ`mm­ô<Ú·o¯ô<^ÅAÁãñ”Þ&|>ÿ•Üü¡.mò*ÀÀÀ@©y½’²´Ö6iU—°:tè@}BB4ëê¡U]Â"„¢:”Þ©­­ÅöíÛ!Šªªª&—9tè‚‚‚ ‰ü;*ð´iÓ  °yófÔÔÔP BˆºÝ»wÃÀÀB¡#FŒ@ddd£éÿøãäååA(bêԩذaªªªŒÕ«WC(B("##ƒ{˜…BÈ«§ôÑùåîn‹¡C‡"44´Ñô;vìÀÆ={öDnn.Äb1æÏŸÏ½W$-- :t€­­-µ i–ÇcåÊ•ÈÎμ÷Þ{ðññ¾¾>cعs':vìˆáÇ¿Öí”ÉdXµjV®\©²u½eËìÝ»—›‰DˆŽŽFJJ ~ýõW¹‡!¿ùænÔoBä¥ëÚµ+ %%.\€¯¯/µi¶M›6ÁÕÕï¾û. 66§N‚³³3~ÿýwlÞ¼sæÌyíÛÉCff¦J×µ§§'7²Dqq1"##Áçó‘››‹+V`À€´Cª8•z0==ééé˜5kµœŠøá‡P\\Œ… B  ==0þ|=z€°³¬¬ŒûK à?þ[_hh(,XÐâíùì³ÏðöÛorss‘ŸŸâرc‰D˜Ì}>iÒ$<~üXnÕÕÕ(..Æš5kšÌû麫 @u¿ÖÕõåË—Ë–-ÃîÝ»¹ôgΜ‘[_PPV­ZõRöƒ;wî€Ïçsw_ݾ}›Ë7&&2™ŒU¤ìGÝׯ_ÏN:ÅcìÆlÉ’%ró9ÂŽ=ÊMÇÇdz0ÆËÉÉaK–,a"‘ˆ¥¤¤°uëÖ1¢Z²²²X¿~ýXvv¶Ü Mý¯Çd27””ôRöƒ«W¯²+V<÷ybb"Û»wo‹×›––Ɔ  cŒ]¿~-[¶ŒÝºu‹-Z´ˆK÷àÁ6oÞ¼ç–üø1›2e “J¥lâĉìÈ‘#ìûï¿g_|ñ«©©iÑð ýÿý÷Ù®]».#22’ÅÅŽô¡8<(7ÜÏÓßDµ(ý–¢££±aÃôêÕëÿáúÿ¡­­ ggg€——6oÞ @[[[ÀØØ¿ýö222púôinÙÈÈÈWò`y1cÆŒwÖÛ˜   nÚÛÛ[îiû—1ØfÝMʺ :~üx´mÛö¹Ï÷ìÙÃõ ¤R)z÷î ÆöíÛ‡¤¤$@MM ÌÌ̸˵C† ££#›Ì÷Ò¥Kr=†‚‚‚FÓ›››7:°èìÙ³_J}$$$`êÔ©Üôرc1vìX:0Ô€Òˆžžüüüž už~ÙT///xyy=w邨¾~ýú5:¿¢¢Bnˆ 8::r¯8sæ D"ÆŒ£P~—/_ÆíÛ·¹÷Ø\¿~»wïnöÓ9998vì&OžÜäð1.\@EEÅsÃ[¸ººâ»ï¾“ûìÑ£G8tèWæýû÷ãçŸ888@WW¿þú+2220eÊhk7|ÕyÕªUÜz.\¸€   F·³²²çÏŸÇ!CêìØ1ðx<Œ1B¡::wîJJJä‚CII ²³³åÚëÊ•+°µµånŠ!@©—––V½_¸uwà,^¼XnÚÐÐP®2bĹå·lÙ‚»wï*@<ˆ­[·r$99)))ry,_¾=BLL k2€Â××"‘æææ@‡`bbÂåkii‰M›6ÁÌÌ Ýºuã>>|8Wººº˜3g>|ˆ .`íÚµh0_WWWn=„¾¾~£u­­­?ÿü!!!¹õEEEÁÄÄDá²cÇ\¾|Y.€Ü¿|>_n(>Ÿ   Þzë-¼õÖ[t°¨âñMO¢¢˜Ï?ÿ111044l0Mzz:Ž;¦Ð%§×íU hHÔ çNˆÒÒÒзo_ü?ÿTxcIɱwIEND®B`‚snd-16.1/pix/sceq29.png0000644000076400007640000000146011147553270012755 0ustar bilbil‰PNG  IHDRŸ"v‘ûy3PLTEÿÿÿððð°°°àààÀÀÀ€€€@@@ppp000```ÐÐÐ    PPPxr- pHYs  šœtIME× / ÑþšöIDATXÃÍ—’« E ÐÀÿí ¨-hqÝ×Ö53:íÔÊ5\W!JT(Å} ¥æÆú„Ub€+Rõ—Ô é±ÿ7'¼Æï«#ÝÌR¬Õ&)ÿçFêºÈ[!d¼‹> ”ÞGd“/K´è#ò¨!Ov*KÖ‡ ç²ÆŒüå}Ü(…°¥-`Zç›MRèÄòYåvÚ`+÷Úé}Ö$E_>ÂâN^ ¼Hÿ¸˜q5ù<]ã?iGÚècy OàX–õ¸ölšêeÓ]Bgðgõ9¾Ö´úŸõŸtû¡À#wÑ›™TN>5 ©U×|«Š]–¿•Ýü.T¤˜X\²ä ª4x&²€˜ºhÓv} ÀÀ~ÿPëy&˜šPÝ0pxÅË šàXž:±ÿ¦séûö:ƒ33úz›zÏB§ößcÎÿOuÃÊ(g†pb§{ÇIr£oS·pt©¯¿ÄÚ(/bêîRÔ8`Sûp¿J^ãã1õÓpÿi áë×ÚmL­ƒéåµdЊ–»˜ºƒ»l%]*øELÝÂÝësïÏU ½€¥XøíôE‚:.ÝNÇ9nÛmûÇö«‰ŽÂäý«Êû·GçIEND®B`‚snd-16.1/pix/sceq18.png0000644000076400007640000000174311147553270012757 0ustar bilbil‰PNG  IHDR|b¥Gg3PLTEÿÿÿ€€€ààà```ððð    ÐÐа°°PPPÀÀÀppp@@@000À§/½ pHYs  šœtIME× 3­NwuCIDAThÞíší’ò …) š¢÷µ/ú±Ú²K}ýAfvJ¦‡¯ÐgNUê9ìÓç©1èER/ ú@Þ´Ó6£Uã Ô˜/§õÖfÚËw:´wñïJù,xÛ4ÝvLj Å£€¹.“9Ьcgôp¶8 ž†‹ˆ4Xú‡Q–¦ó4˜²)´9Cœ–ܸ´Ü!Š[«Ë4§%רPgqúF}J<-yãR@P&öÂç °s1ÚöNß.QÙ¡òŽ ‰6öšv»䪱õY£‘FfC>ÛÒ ÃG¹íy·Ž õépËÙîT=Î‹ïÆ¨–!Fµ=ѤÕtäBŒš›bT,‹QscKŒÊóÏcÔÒØ£ŠRF•Æ–uÓ$pµ4¶Ä¨"ÎbÔÒØ6’8QöŒ³ïh;FõèÑã»ÿ›¶Ôà›ÞQ@¯”ÿÛ,¥WØÎ´=Hª¤?)½Þß”§ö°¦Ú(Ò+Äù9É\BØ]óZßFH¯Ö'q†a¦‘ˆ^sðñD¯¹d+L@åÜÖþ9±8-y)Ù z%mŽaëÅó’ç’åM@ˆ=uÃVo¸™^Sɲôj®ÇC3 +6 sÉÖš€mv.ÙN¯=zôèôšµ55u‡dÞ«ý£)&÷^ש¶‘¦XÂmH¯Û‡µ‡ô&ð%¼µ¡ žÅÞ«ÂúÆÝé¹Gʪz,É_aÓÈYön*]ÚD¯Pù ,‰3ô “¯uiiÉKÕðÞ«£¯9z÷„J—6y¯¹jXz´/ú=½ZSf­Â¥ÍÞk®šŠWØÔ§÷ôJÂþVãÒz-UÿÂVGÎÐëä}K[ª¦½¦CFN¸^{ôèñUÁ»Ÿç.ïÈüY ½‚åÅßú³RzÝ<%ã—sèÏš_Ð+µà2j}&ç‡?k–o³=+¥WêÑ:;¸+¾ÍùáÏnö^Ú-Rz å€!ÓÜgqµx¯¾Ž^¯Ç‘éaÎŽxþå@ºâ½W úázÝÍ¡1ŒãËH½æªaéÕÅÛC¦Ç9¯#Ÿ½Wºbé5ú=™ç¼l¸L¯¥jXzµ·Hš ™ç¬âOölªš z´ôºŸÃóçÒ«µßC¯ÿÙ"^œ±í²IEND®B`‚snd-16.1/pix/iir.png0000644000076400007640000021631611147553267012450 0ustar bilbil‰PNG  IHDR„dx•õsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ61TÍ_^ IDATxÚìÝw\×Úðß:‚JS4A0Q±E¬Q¬±&ö$×ôë½o «QcŠ)VÅP,(ö‚¨ **A•"½ƒ°ô=ïÞ+ HÝ…çû;ÌìÌ<3gÏ<3gÎá1Æ!„B!„t8| !„B!„tL‘H$ªïŸ“'OÆØ±c¡ªªZçÿ###áíí+W®ÀÎήÞù!ÍÏËË ÊÊÊ011©óÿéééøí·ß CCCèèèPÐif{öìAtt4ìììêüYY~üñG\¾|êêêèÑ£6tûömlÚ´ ...õγeËœ9sèÓ§´{õ>!üé§ŸàèèøÚ…;///|÷ÝwØ´iE“V¼566ÆëZ|ïØ±«V­Â÷ß !ÍìøñãÐÔÔ|m9üå—_ðÝwßA$áÌ™34BÚ8ÌÌÌ„ŠŠJ½óøùùa̘1‰D(//Ç£G(p¤ÝÖ÷¯¾úªAIÇǃD"á¦=xð2óí޽ǎƒ½½=E&š={6BBB^;c |>Ÿû[*''[·n•™÷Ô©SøüóÏ1{öl .! 4aÂ$''ãÚµkõÎ#‘H¸rø²êêj¬]»VfÚÕ«W1bĬZµŠ‚KH °··ŸÏÇíÛ·Tfy<žLý¹}ûvdeeqŸŸ}Ššš ,!­T…Ba­r(‰P]]M%¤…‚&-¿lÙ2™ÏgϞşþI%í7!üóÏ?±X '''Œ9ðÎ;ïàÆ000À¸qãðË/¿ ¦¦Ë—/§hÒJöïßÐÐP())!==Ó¦MLœ8_~ù%Fމùóçã§Ÿ~ÇÔ)S(h„4³Ó§OãêÕ«HJJByy9/^ øì³Ïп|üñÇøâ‹/ðã?B(rõ(!¤mܽ{—.]Âõë×ñ믿bÙ²eÐÐÐÀÞ½{qãÆ lß¾³fÍ‚··7ÊËËabb‚Þ½{SàH»Ç«o؉’’²²2×Þº¤¤àñx€ÒÒR‚7v(coo888PÔ i"±XÌ=Ñ …PSSð¢ eeeî.hYYcPWWí÷Í;£F¼yó(¸„4Pyy9ªªª|>Üt@%%%@EEªªª ©©ùÚï‰D`ŒaõêÕ\BZ@UUÊË˹Ϛššàñx¨ªªBMM w-+OCC£Î&ßRÒ'„çΣà…VïÂú*®W§K+@BHë©/Á“&†õ}&„4UUÕ:o†¾:MEEåµXBZ‡’’w£æuÓë›—¶„ 6ÀÁÁ 066n‘uhhh`üøñèÛ·/]BˆBùûï¿Q^^޲²2”——7ë{×B¡7nÜÀ€Þj9555”••5j•••ÐÖÖ†ªª*V¬XAX¥§§# ÏŸ?瞆ʳšš˜šš"66¶Ö kmmmôîÝcÇŽ¥ƒKšÅ¥K—Ý»wÃÐаÅßVWWǘ1cêê†4ÜæÍ›ÁCYYÊÊÊ ªªŠŠŠŠ7Ö½o[/æååA,·XîÓ÷î݃¿¿?vî܉ýë_m›–••!..jjjxÍð‡MRZZŠÓ§OãìÙ³7n%†„…H322°hÑ"¨ªªBMM ***¯mªô¶âããáîî[[Û·þÝnì“fióGJÓáÇ‘ŸŸÙ³g£S§N ñÄdëÖ­ˆÇªU« ¥¥%ó¿ÂÂBH$ýôSðù|¨©©qÉ ŠŠ ÷Z\sÕ‹'Nœ€ŽŽ† Òfûž““ƒ9sæ`ß¾}uþ_ØÚƒ_~ù¥Å¾_CCÓ¦MCII Ο?”BäRdd$‚ƒƒ1kÖ,tïÞý•PS4¶c„¦4;æñxøöÛoßøŽ9‘/iii8|ø0F­põçÇŒõë××J sç΀ÁƒcðàÁ¨¨¨À‘#Gðõ×_cåÊ•ÐÕÕ¥ƒOMII©Å“AàÅBLš4‰î‚’Â7»yó&®\¹‚ @]]½ÎWoZW½m½8vìØf½ÁÛºººðóó«w[}ëzöì‰^½zµøz455ááá#GŽP) „È;v 99K—.…¡¡a‹&ƒméMùggg…¼™ªªªŠÿûß šWEES¦LÁêÕ«áïï“'OÒÁ'oÍØØÏž=kõõòx<¸¹¹!99‘‘‘t Þ æççcùòåÐÕÕmõzIYY¹Un¼é|y]"Ûê ¡M«$„À‹^ßæÎ‹={öPi „ÈÈÈH¨««ÃÍÍí=OÒš®^½ …~âð6Ý©¨¨@CCŸ}ö ))$oÍÚÚÛ¶mÈ#Ú,)<~ü8ˆ7$ƒãÆ£Ž0_—3µ÷411AJJ iBˆÜ$ƒÉÉɘ5kV»}*Hו+W0|øð¹ïŽŽŽ”’F©¬¬„²²r›¬›ÇãaÙ²eضmˆ×$ƒ¤ƒ'„|>‹/†··7mBH›;vìÜÜÜ($r',, l³ [J ‰"JKKCvvv›nƒžž EänܸAÉ ¼$„IIIصkvíÚ…üüü6ÛÉnݺ¡k×®ˆ¥#NÈÿqåóÉ“'VðçŸbÅŠ” ŽD"áÊá½{÷Ú6UUUصk–,YB'ª¼$„êêêèÙ³'zöì eee(++cüøñm²£ššš011ÁÇé¨ò¿ÊCZ>éEë–ccctíÚ•‚Aj%„Òr¨­­ÝfÛqíÚ5z:ø555Ìœ9»wï¦`Zºw={B__À‹ÞmåáfŠ»»;7EGTYY‰¿þú sçÎmó§¶”ʱ‰'Ò{„V ‘Kôt°þ¤pÔ¨QtÝ@†P(„••¢££;ܾWTT`ÇŽ˜3gN›Þ\£„PhhhÀÄÄqqqtä !-Ž1†M›6á_ÿúƒÈ­ëׯÃÉɉQ‡ %%…šŽ…ááácÇŽu¸dÐßßæææ” RBØ0nnnúq:!¤õ’ÁÀÈȈšŠ¹ŠBUU•‚Q àÌ™3”… `ee…tˆý-//Ç ¬¬Œ1cÆÐ @ aè««cúôéô^!¤ÅH$lÛ¶ ˜ÜÝÝqôèQ:!Íš þý÷ߘ6mtuu) Dnedd 99ƒ ¢`¼eRxöìY„„„P@ˆ\ãñxX¶l¶mÛÆX»Ú·;wîÀ××Ó¦M£¡œ1!äóùrsàTUU1gÎìØ±ƒÎBH“TWW# ëׯ‡§§'%ƒDî“Á .`êÔ©PSS£€¼eRèéé Ôû(‘{úúúðôô„··w»H ïܹƒ?ÿüéééðôô¤dPQÂÀÌÌLnvÞÈÈãÆÃêÕ«Og!ä­EGGÃÇÇ–––Xµjôôô((D®“ÁÇcèС” 6’††œñìÙ3ÄÅÅ!44”‚Bä:)œ,B:ˆÈÈH¤¦¦rŸ“’’›› PVVÆ„ ¨Q¢I`ii)LLL¸yzöì [[ÛÝŽ‚‚\»vMfšX,Fll,÷ÙÑÑ}ûöÅ´iÓèÀµF.ÄZ Qqzz:"##e¦}öÙg°¶¶V¨6÷·oßæþ B`` 1 fÆ 5jâ%%%%¸råŠÌ´7"11::: ÿ™?>(SIRsPÒ\$ Î;'3mß¾} ¡¡a³­G$ÁÀÀ}ûö¥D°•••É4ÏÛ½{7nݺ¥0Û?räHüôÓOt _†çÏŸË\'zyyáúõë ;|KVVž={&³û÷ïoÑušššâ›o¾‘™¦®®kkk:ÉÚH‹åÆ«¬¬ÄÚµkáää„‘#GR°È[ãóùµÎ±3g΀1Ö¬åPú]QQQðöö†™™\\\ЩS':ͤ¸¸ááላ‹Cuu5† ‚îÝ»S“òvèåfÀ——§pI`||œ‚ABrr2$‰Ì0Ií’’ÜÜÜèBJ&!!tÔ !­šVTTàÙ³g "—\\\pñâE DÉ``` u Cc {÷îÅüùó;ܾÛÚÚÂÒÒ’’BJ_OútpÆŒtÔ !­já…ؽ{7$ ƒÈ]]]èééÑSÂWìÞ½›’A¢P’““abbÒa÷ßÖÖVVV”6B‹L‹C‡233ÛtGéé !²rss±eË@TT§ÕÂfΜ‰`æÌ™  *77ÚÚÚPRR¢àµc‰kÖ¬„„„`Ĉm²#GŽÄÁƒѧO:(®\¹‚~ýúQ2Hêô×_!## Ü´ýû÷cÖ¬Ymú[²wï^xyyuèccccƒ°°0deeÁÀÀ ÁËeeeAOO|~Ç‘¯E÷ÚÚÚ"‘"‘ݺuk³¬®®Æ‘#Gèé !/ÑÕÕåʧ¤…YXX ¬¬ ©©© šÿÈ‘#ÈÉÉ¡Àµ÷J˜ÏçÊ¡³³s›m‡žžôôôÛáIqq1nß¾MÈz-Y²"‘H¦ã–¶îE?%%¥C?|Ù¢E‹püøqdee5x™þù>>>·.ê;¹oß>f‚Òæ>þøcœ;wiii "wFŽ‰Ë—/wødðÈ‘#X°`DaTTTÀßߟÎÛÿ …øøãqìØ1dgg7x¹GQBØš8Ðjë***B~~>Þyç*!„6·hÑ"œ9sæIá… ŸŸO#­¦£?%,..F@@&MšDME‰ÂH$8zô(¦L™BÁx‰@ ÀÂ… qôèÑ%…‰¤Ã6m“„0;;qqq­¶¾ãÇÃÝÝJ!D¡’Bz1ž´:gggܺu ¥¥¥j¿oݺ…Í›7còäÉ” ’·×&3¥¤¤ ¢¢‚ÆØ®')\¼xqƒ^Á(++ƒ¦¦f‡íü­ÕŸ~ú‰ |Kª®®ÆÝ»wÁëPc±B+)Ü¿»®€è=HÅ¢¯¯ &àðáÃm’6Çù"íÌ®!žúè#|õÕW” ’&»qãΞ=Û*É`dd$üüü°páB |’ÂO>ù^^^X¶l>ÜánV–••aÏž=õþ_ØÚôé§Ÿxq¥k×®-RSRR`kkËuåM!òÊÒÒßÿ=Ž9‚cÇŽA"‘àöíÛØ¹s':„Û·oCKK«YÖuÿþ}ôëׯՖ¯¬¬c >>>øöÛoé`+XRøí·ßâÌ™3‰DÐÑÑÁ˜1cêœ7%%{÷îŪU«š´Îªª*ðxúöí‹_~ù…‚ÿx<ðàÁ4©þmª‹/¢S§N8yò$>øàƒ¶MЫW/@tt4nß¾Ýìë:t(5%„(œ)S¦p$$$ sçÎ?~|ƒžÐ4”­­m“~w³ü´iÓ è+¨ñãÇcüøñÈÍÍEPPPóhkkcÉ’%ÍR§OŸ>UUUþ®1cÆ sçΈˆˆ@rr²Ìÿ–.] MMM:¨¤ÙÍœ9¹¹¹ÈÎÎc¬E®o@EE"‘ˆÞD666°±±á>ÇÆÆÂÒÒêêꨮ®nöã'½AÐRçECèèè`òäÉ2cg¶YBØ£G.(-u÷„B……ÀÜÜæææ-R1µÕòD1éêê¶ê ÛMUZ†i Ý»wG÷îÝ) ÊÚÚЧOŸ­çä¡þ”îã«øtB!„BHÇôÚ„ðàÁƒ¯í ´¤¤¿üò üüüÞø7!¤y]¿~½ÞGÿÀ‹Žvî܉͛7·Z¯g„t4 ¸víZ½ÿ—H$8xð Ö¯_ßl¯Bïùóç8räÈkç¹rå D"ž>>4BšYbb"|}}_{ÑxøðaØÚÚâ믿Ɩ-[(h„´q2¸wï^DDDÔ;Ïõë×Q^^‘H„ . ##ƒGÚ=¡´€¼|çÒÐÐ8pàk.--…††ÌÍÍáççÇMðàA­•333ñÃ?@GG‡¢NZÍÒ¥K1`À…Þ‡²²2äççsŸ¥=ç¹»»¿v¹ÔÔT€L7î999غu«Ì¼QQQHNNFXX4¤ÙyzzbìØ± ½UUUÈÎÎæ>wíÚ˜7oÞkŸ>|øÓ§O™¬ÕÕÕX»v­Ì¼!!!(..FZZ4¤M988`ùòå ¿ééé`Œ455‘ššŠE‹áǬw™ÇcÈ!€Î;£¨¨ˆ{?pûöí27bCC?…¯…Ò“ÿåžo,X„„„4je¯öÞÉÉÉprrjÔ÷¥¤¤    Ñ/™Ÿ8qnnnÞ¹sç0jÔ(())µÉú›²|nn.âããû¦n{XXlmm=¾SSÖŸ––†¤¤$…O³²²páÂî³»»;ܨïÓÓÓ«ÕKYqqq½/·ä1 ƒƒC£†UˆŠŠB—.]`bb¢P¿)gÏžÅèÑ£!¾}Ÿ^7nÜ€™™Y­îô"..|>½{÷nÔ9˜””ôÆ›„u©¬¬Äýû÷>!|þü9Μ9Ã}9r$ݤL(Ö*‡"‘=zôhô6^»v }úôiôN>„’’R“:2jËúN^¶¡©Ë—••áêÕ«=zt›mCttt»¸ø=wî7¾«M“‡X¶lY­ßóž={âwÞiôwfdd --­I×*•••¸|ùr½Côfù‹ŽŽ†¦¦f“b’žžŽôôt¹ˆIS®Sä-&ˆŽŽ®?!´··‡½½}­ €çÏŸ#;;< Ä7ß|ƒU«VAKK =zôÀãÇ‘––ÆÝM©OÏž=±hÑ¢FíÀ;w––֤Ġ±ë^<]Y°`ÔÔÔÚdýMY>)) !!!˜?~›l;ð¢ÛòÆ^ä4eý<@\\œÂWh½zõªƒ¼¼<äççCUUùùùÜàü1cÆ OŸ>°··Ç­[· ®®þÆ÷´´´ç¦£ªª*xzzB__¿Q—‘‘ÞzÙ»wï"55µM~SrssñÑGAEEå­—UUU…““ÌÌÌÞzÙK—.A `Ĉo½l||<"""ðᇾõ²b±¸]4•ìÚµk­c^TT„ÜÜ\!''‡KÔýüü`bb‚áÇcäÈ‘FïÞ½¡««ûÆõ,\¸<¯QÛ(àââÒ¨›$ UUU :´Mê«æªsÚzšº|QQjjjÚtÚËÐ}ôQ­ß£ââb””” 33úúúàóù¸vížùÜæ× IDATéÝ»7ìííˆ3f4º…SCuïÞŽŽŽry9oä)&#FŒhÒÓAE‰I½m–êk=oÞ<™Ï³gÏnñ èééµÉEÔ«OO[Û»ï¾Û!×-ë—W“'O®sú| óyüøñíöõêի×iîÙ:wîÜâEŠÈÅÅ...u^@¼lèСMzêÖPVVVmyøÍ¦z‹êÎúØÚÚÖ9\Ÿ>}d^›èÝ»w«ýÞvéÒ]ºt‘‹øÈËy#O1éÛ·¯\lG×®][ô†Ÿ@ÔJíÔÕÕ›ôn„¢®»­×Ïçó¡¥¥Õf µªª*ºuëeeåV_·@ @çÎÛü޹"h«sTz~´öx¡PØfŽºº: Áç·î0°JJJÐÑÑiõ;<4hsÏ ##£6[¿’’tuu¹V±¾–‡màóùÐÔÔ|cSÅö~²²2tuu¡©©Ù¦Û!O¿³òMMMŠIÏ“v¿ÔL*++±}ûvèêêbÆŒµæ©ªª‚”••1wîÜFu®@ð¢§>___”——cáÂ…u&/w ߥK¬X±¢ÃÆ«¦¦þþþÈËËòeËêLÔ% Ž=ЧOŸbÅŠz×t,Œ1">>_|ñEçÌ©S§d:/k/ï(56^§NBdd$¾ù横ªÖ9ß… píÚ5|õÕWmš¤‘öéÆ8wî/^ CCÃZÿ¿ÿ>:$óšPGNïÞ½‹'N`þüùõ¶P‰Å¡C‡0}úôFwÔFHSH$âñãÇøüóÏë¬Ož<‰;wîpI¢——ÀšÙüÁòóóÙ£G˜ŸŸ_ólß¾edd°äädæããÃäAyy9S4 ÙæššVXXÈ***X{´k×.–””Ä233Ù¶mÛêœÇËË‹•––²ÂÂBVYYÉ:2___ÏòòòØüQç<‡fÑÑѬ¤¤„ýôÓOT›i›ë›§¨¨ˆI$…ŽÇ‘#GXTT+++c?þøc½å°¬¬Œ*ä1nN'Nœ`¬ººš­Y³¦Îy‚‚‚XXXcŒ±uëÖÉE̪««YUUU‡*ŸoEª_nÞ¼ÉNŸ>ÍclóæÍ,;;»Ö<ìÖ­[¬°°•––vè2ÉŽ=Êcìï¿ÿfÏž=«5Ï£Gؾ}ûcŒùùù±øøx¹-¯«säQMMÍË—D"iòµ®"ÆæU,**ЉÅb¶aÆ×ÇÍÞf©  ]ºtAïÞ½‘Pç<™™™èÖ­LLL’’ÒæÙtee%6nÜØ y_î8xÑÍwIII«lgrr²L¯™¯GGª¤¤¿þú«Ì8‘íIrr2zöì ƒzi/..ÆæÍ›áããSkü½Žæñãǰ°°àÆP«Ëƒ`cc ˆÅâV߯†œ×u•ÅG!))©U¶±´´T¦3Ÿ†lóÏ?ÿÌuþ²þùUUUMŽG[ºÿ>úõëUUU®“†W üþûïðññÁ† :t9¼sç @Pç9¼è°FÚ‘’’ÒkÏ‘ÖÜîWË]]òòòdž×U^[Òõë×eÆVnHjj9‹ŠŠÂÙ³g按‰áÞêÒ¥ kÍ# áççüñÇrq½ÖV¸ÞºõõõeÆ$•JIIá:¦166ƳgÏär_þüóO”••½q¾›7oÖ:/Z³¿¼®ÄÄDøûû¿1ÿðöönÒ:·lÙRï5}xx8ŠŠŠäþ\ŽŽF¿~ý ¦¦Vïqæóùµêcj«ù?ååå\¦ÿþ÷¿ ŨQ£ÀçóWWW¬[·.\@xx8V®\‰¨¨(¬_¿ÖÖÖ>|8>øà® ,_¾™™™èÚµ+Ž9}}}LŸ>ÁÁÁpuuaÔ¨Qرc233Ñ«W/Ì™3—/_F=pðàAÌœ9êêêøá‡P^^ŽáÇcñâŨ©©ŸŸ?~ :ÇTÓÒÒÂÂ… qñâE/š*;v QQQPSS×_~‰Ë—/ËlÏûï¿   DDD€Çãá?ÿù”••¹ø 4cÇŽÅåË— øê«¯ ªªŠ7¢¼¼ýû÷‡»»{£»OoN¿ýö÷wGn¦¦(ªªªðÛo¿¡¸¸Ë–-Czz:ŒŒŒ §§Ç•ÅíÛ·ãàÁƒÇâÅ‹QZZŠ~ø***>|8æÍ›‡øøxìß¿0cÆ hjj¢  ÷îÝCii)/^Œ‹/Êœû...8|ø0>|mmm|öÙg¸rå ¬­­áíí1cÆ _¿~‰Dˆ‰‰ÁðáñråJ0ÆpúôiDDD`Ĉxÿý÷ëÜ·àà`„‡‡càÀ7n®_¿ŽŒŒ H$™}/++Ã!C0hÐ TUUaãÆxþü9–/_ŽÔÔTäää <<–––˜>}:=z„ƒx1ެ‘‘÷›Ò³gOÌ;?æ*Ô™3gÂÒÒ²UëªU«¨¶III‰DÐ××ÇâÅ‹qéÒ%¸ºº";;ééé066ÆêÕ«ñìÙ3 >_|ñŽ?Žßÿááá˜0a €'NàÞ½{PVVÆ7ß|ƒ«W¯ÂÁÁ¿ÿþ;† †÷ß—.]â:í‘ÖM?þø#$ Þ}÷]Œ?.\€ªª*.]º„/¾øñññX¿~=,--1bĸ¹¹Éü¦,]º´Îw󪫫±mÛ6dggsMwî܉ÔÔT˜˜˜`Þ¼y BFFRRR0cÆ ôîݾ¾¾HLL„©©):wîŒsçÎ!// pww‡½½=Ž9‚èèhî7¥  €»99fÌ 4ÇGdd$TTTðõ×_·iÏæR'NÄĉ§OŸFfff£‡4!ò%$$·nÝ‚££#&Nœˆ .ÀÕÕׯ_‡­­-âãã±nÝ:˜™™aĈ˜4iþüóO"<<Ÿ~ú):wî oooäææÂÜܳfÍÂ¥K—```€#GŽ`îܹ¨©©P(Ä;#§OŸB"‘€ÇãÁ××0mÚ4tîÜ999ˆŽŽFQQ–,Y‚£GbÛ¶mÇ”)S ®®ŽììlˆD"têÔ +V¬¨óu³ââbˆD"())áÛo¿ÇÃÚµk¼èÜkÔ¨Q8sæ """+W®„@ À† PSSýÛåÊ\ºt ðùçŸãñãÇX¿~=,,,0bĸ»»#""§OŸ,Y²YYYÈÊÊBxx8,,,0sæÌVï+ ¡¾ÿþûÚõqs?ªÜ¾};{öì»{÷.÷x1Æ~ÿýw–ššÊcl÷îÝìñãÇ,&&†íß¿¿Í¯VTT°ñãÇË¿ü¿—mÙ²…eeeqŸÿïÿþ‰Åb&‹ÙªU«cŒM:•ååå±€€˼¼¼Xtt4KKKc^^^ìÔ©SìÖ­[\3¡«W¯²‹/²uëÖ1Æûá‡cŒ]¿~={–[×Ò¥KYBBBÛõ²¤¤$®inzz:óööfŒ1–››Ë6mÚļ¼¼Xyy9 å#Oœ8‘k³zõjÆãöK$±òòræååÅM c[¶laiiiL,³›7o²’’’?vþþþìÁƒìÉ“'l×®]Üô½{÷²û÷ï3Æ»xñ¢Ì¶wdGewïÞeÏž=ãÎÆ;pà»}û6cŒ±3gΰððp–Í~ÿý÷V߯ɓ'³ÂÂBî¼Þ¿?‹‹‹{cYúH¦,fgg³Í›7sëZ¹r%W†ë+‹kÖ¬a¡¡¡Œ1Æ6lØÀÄb1cŒ±7rû»yóf–““#ó=¬¨¨ˆ›æëëËvïÞÍcìàÁƒ,&&†UWWËüîœ={–]½z•‰ÅbÇRSSÙêÕ«¹y®\¹Ò¬ÇìܹsìêÕ«,//mܸ‘›~òäIÂcìÒ¥KÜú_÷{Õ\¾|™]¾|™Ë4± bçÏŸgŒ1ÎΞ=Ë5û‘‡æˆ7oÞdÿùÏcŒÝ»wrÇ266–ùûû3Æ{üø1ûçŸj5Q’ÊÉÉa7ndb±˜eff²7²’’æææÆ•3isÚ   nùµk×rMÂ~þùgVRRÂ~ûí7®é£´|J_K©ï7¥.³fÍâêré<åååL,³Ó§O³ÐÐPöÑG±äädnžððpvæÌÆc›6mbÇgË–-c=’ùžŠŠ &‹YLL Û³g[³f WBBBXVVÛ¼y3‹Å¬  €û-nI÷ïßgL,³Í›7³üü|ÆcQQQÌ××—1ÆØÃ‡Ybb"‹ÅìØ±c,""¢Ã–Ù¸¸8æïïÏÄb1óööf™™™\ŒvîÜÉ]kíÙ³‡‰Åb¶{÷nî\‘7?ýôW®~ûí7VPPÀ«Û¶mãömÇŽ,%%¥Þr|èÐ!vûöm&‹ÙÁƒÙÝ»wÙÉ“'¹ë†~ø]¸p………±   Â.^¼Xg=.½žŽŽfÇŽ«µ®Ç³Å‹3ÆKIIábþ²¼¼<6mÚ4ÆcÅÅÅì—_~‘¹výïÿË$ =z´Ìúׯ_ÏÊÊʸú¶¸¸¸Öõ-cŒýõ×_,--­ÎXxyy±°;vp¯QDFF¶Éñ•^ åææ²ß~ûM¦>–^ƒÔU7ûÂ¥K—bÇŽÐ×ׇ‡‡7][[›ËæçÏŸ___(++cæÌ™r‘-¿íšÕÕÕ2w'¤wbbb°iÓ&™ï´¶¶F×®]1eÊnþøøø7v›?dÈÀwß}'3]ú4ÁÀÀæææÍ²ÿb±˜»cRW<‚ƒƒ¹PðråJŒ=šÛW,]º[¶lAyy9***`mmÝâÇmÆŒ8tèÊË˱`Ánz§N¸Sììì¸íôôôìÐw=<qSù”Ö˶¶¶ÐÖÖ~íw˜ššÊôÆýèÑ#@(".. ,€±±q½OȈÌÌLèêêÊÔË999ðöö†²²2²³³Ñ¯_?|òÉ'\Y>|8ÌḬ̀iÓ&0ÆZeˆ[[[ðxõìÙÎÎÎØ´ifΜ)×OSߦKËÑË-¾¤åxß¾}Ü€í#FŒ@ZZšLy †D"Áµk×j Çó²—¯gmlljÕñ ©?ëÚ¯³gÏrc©‡‡‡¿ñ{¤Ë;–+£¯vôò“Ħæ-AZïß¿_|ñ7]]]ëÀìåúXÚJªEšŒ.Z´¨Ö´—/Ö`Μ9rU8ÂÃùǦҦ¢?üð÷ƒ-½èTWW‡H$Â!C0zôh 4Û¶mƒ@ À_|gggîÝ,'''¨uâB"‘àÎ;°¶¶†¥¥%öíÛ‡Ó§OƒÏçã£>ÂãÇk-gbbܼy~ø¡Ìÿë;9 ñÇ )) ýû÷GïÞ½¹ÇîÒ&!رc¹÷>®^½ÊÍ#m²#m‹¬¬¬ ‡°°0î}!Ü»wÛw@ÐjÍE§M›Vgâ#¥££ƒÿûßÔFä&MšTkÚ«ƒÑŽ;¶Í¶/..kÖ¬c ööö°°°ÀÀƒ@ @vv6ôõõadd‘H„>}ú`úôé°°°€¯¯/‚ƒƒ±`Á¼ÿþû\ﲃ®³œØØØàæÍ›ÐÕÕE·nÝ ««‹„„ˆD"ðx„B!‘œœÌ-/ qéÒ%™2ÜÜ\]]¹ŠEêå y@@åð•¤ÐÙÙYfÚ«‰À Aƒ¸ò€Ïç#00÷îÝÇÃÌ™3QSSÕiBÕµkW$&&bÍš5ððð@¿~ýðÞ{ïA$AKK K—.Å€PVVÆÝL)--•)#ÒúÃÅÅ6lÀÈ‘#! ±~ýzî|RVV®³¼ 8ÞÞÞøüóÏT>“’’¸ß>}ú@II ÕÕÕ¨ªª‚@ ŸÏ¯õ=&&& ÂÍ›7‘››‹±cÇ"77k×®…D"A·nÝÀçóÁCYY÷[rýúu®,vîÜb±·oßæ’àÖêÙÙÆÆ¦ÖÅ·•••Ìx–¯^»ud–––µ~ÃLMM¹›ŒÒ¤PÞçø|>6nÜ@555hjjB$A  ""'NÄ»ï¾ ðù|¬X±ÚÚÚÐ×ׇH$‚lmm‹²²2XYYÁÀÀ Vâhnn___¸¸¸àòå˘;w.222¸ëKiÒ\W¹´³³ãš§;¶Î:ôU¡¡¡ÜûÃãÆƒX,®Uï½ú=ÎÎÎÜ{twîÜÁòåËÆ-'-ï½÷þþûo¬X±ºººÜ~ôïßعs'ºté>Ÿß*7vÞ¦>–Þx«¯>nöa'ˆâ+//Çü!sçšÒò¶nÝ OOOèèè`çÎpww¯5^ŸŸÈup@‘"‘ˆÞ‘%¤:xð úõë§°ÃP§2¤öI!6ks2BHÃ|òÉ'ظq#ÊÊÊàààPçà±vvvÐÑÑ¡`"‡ÞÔ¼•Ò>ÙØØÈ4;W4ô„B!„tHwîÜAZZÜÜÜ(¤Ã¢„B!„B:(>…€B!„B(!$„(ÄÄD<{öìµó>>,BZHAA¢££_;Ïùóç¹.¾ !„…J§L™‚¢¢¢zÿ‘H„5kÖ °°¢IH+yúô)D"’““ëçÀèׯ\]]±cÇ !- ®Y³÷îÝ{m2Ø©S',Y²?ÿü36vûömüç?ÿyí<[·n…H$B`` Œtõö2úóÏ?ÃÞÞþµ ÂËË ‰ëÖ­Ã÷ßO%¤$&&âÃ?|í}Š¢¢"?~œ‚KÚgB(6~ˆBØØØÈL;~ü¸LÒHi~‡ƻヒ^½zÁÔÔOŸ>…††ôõõ¹yx<ÔÔÔd–{ö,þüóO ,i¿ áæÍ›в²2899qƒ­ššš"<<;v,~ýõWTWW×*$„–³sçN$%%Çãáñãǘ?> //•••€?üûöíCII /^LA#¤™9rQQQ¨©©Áï¿ÿŽ/¾øPTT„N:ÜÜÜpâÄ œ?_ý56t÷î]„„„ <<¿ýö–,Y ìÝ»7oÞĶmÛ0sæLüõ×_¨¬¬„‘‘z÷îM#í^½ã>þœ»S©¬¬ UUUnº¦¦&x< ¤¤ ÖÎWÙÛÛÃÇÇuBäÌܹs1jÔ(Ì›7‚AH‰D`ŒaõêÕ BZ@ee%ÊË˹Ï:uÇCUUª««¹kÙªª*”••ASS“k>ZéÂsçÎQp‰B«÷ ¡ôîæ›¦kjjR !¤ƒ*--­³“"©AƒA(ÂÑÑ‘‚EiSÊÊÊuv(£¤¤%%¥z?Òa–°aÃ888àñãÇèÛ·/„B!Œ1iÒ$:„"‡ àççÇ}.))AEE÷Y]] .¬sÙÊÊJlÙ²ZZZ”BÚ¥K—.!""/^Dbb",--¡¤¤CCCL™2…Dš]aa!Nœ8îÝ»#.. ‘HPPPPï2÷î݃¿¿?|||ðÙgŸµmBXVV†¸¸8Œ1“'OFuu5ž={†uëÖ¡sçΘ4izôèAGšBÚ@NN:(..FEEºté‚Ù³gsóhjjÖêåuA•!„´Òæ¦çϟǪU«àèèˆêêj¤§§C$A[[ÆÆÆðôô¤`‘FÕÇÕÕÕ2Éž¶¶6ÜÜÜ™™‰Y³fø|>ºtéRï÷eggcîܹðõõ­óÿÂÖÞÁ˜˜,_¾ÚÚÚ^tß·o_âØ±cÈÎΆµµ5<<<èl „¬¬,<}úùùùÐÕÕÅôéÓZZZo•øÕçÛo¿}ã;æ„¢èŒaÆqMMutt`kk‹¢¢"<{ö k×®…ŽŽÆ‡^½zQÀçĉHKKCUUòóózzz˜6m€7V»víZk933³¯COOÿüóO½õq«'„...µ¼WRR‚žž-Z„ªª*ÄÆÆbݺuèÓ§&OžLg !„4ƒôôtœ8qUUUÈËËÃ»ï¾ 899ÕYÙ4 ú=ºuë0{ölôìÙ“Î6By% ÌÏÏGff&Ƈ¡C‡BWW—C!-(44‰¤QËvíÚS§NEVVÂÂÂpïÞ=ê|FA9r>Duu5&OžŒ®]»ÂÀÀ@a†/iÑ„0)) !!!€üü|ôïß¹¹¹ú.KKK|óÍ7Ø·oÄb1&L˜@/åÒ¹¹¹Ø²e ** £F¢ ( }ûö!!!“&M‚ƒƒºuëFOˆD"Áš5k!!!1b…9wâÄ äççãþýû(//¯Õ7ÆÛPRR‚‘‘<==ñèÑ#¬]»3fÌ€¹¹9ZŽ ¤¤©©©¨®®Æ”)Sàææ¦°ãW¶hB¨§§ggg/º*ïÕ«† ÒèïSVVÆ‚ . 22’Æ0$¤‘tuu!‰OŸ>¥€(ÀÀ@ÄÆÆ¢ªª ³f͇~HAQP|>Ÿ+‡"‘Œ±v½¿ååå\Wê`gg‡¨¨(™x¼<Ì !òhÀ€¨¬¬ä>»»»7ù;•””`cc+++øûûãêÕ«˜?>[Ž$$$ <<ÏŸ?Lj# ©© ###…B…ß·Ý ®‡9éëÎ;7ù{õõõ1mÚ4ÄÄÄÀÏÏ*BH‡H322I“&aâĉ {'’´_W¯^Ebb"€cg%''Ëü_UU•ëJxÑ:aèСÜçšš.A~ÕËïWõíÛpÒ& €aÆÁÑѱy.Ì…BÌ™3‰‰‰ô´P>|åååHJJ‚©©)†ŠN:AOO¯]í§Â¦´JJJèß¿?444°nÝ:Ìš5‹ºï%„´+?ÆÍ›7‘˜˜ˆ>øNNNÜ!m­°°§OŸFee%—ø :ƒæêé7½ó_÷1;á IDATWïŠõ%„Ož<áž ÆÆÆâĉ2É"ŸÏ‡§§g³ŒŸIÈÛPSSƒªªj³~ç;#•+WâÀ ÂèÑ£aaaAÁnqqq¸xñ"rrr0uêT¨¨¨`Ö¬YívŸþ§……¾ýö[ìß¿W¯^Åœ9sèL&„(´ÀÀ@dff"??cÇŽÅôéÓÛE“¢øòóóqþüy¤¥¥A(büøñPQQi•ÎÞ^~Bhnn777™d±¦¦»v킪ª*233Ñ«W/˜šš¾q8Bäö"](ÄìÙ³‘••…Ë—/#::šÆçn!>Dyy9~þùg¸¹¹aÚ´iíî)`»Nw!çÍ›‡Ç㯿þB÷îÝe* B‘wñññ¸xñ"²²²àáá'''ê)”´¹ÜÜ\\¼x)))PQQÁ˜1cðÁ@SSSn¶Qš,&%%!<<óæÍCEEž†ÈM"xëÖ- 0ÇW¸÷ó§NZkš¶¶6´µµÑ§OŒ;EEEHMMÅÎ;Q\\ sss˜ššÂÉɉN"׺uë†nݺÁÀÀ/^Ä•+W°páB ÌkH$=z<@ß¾}amm]çï„<ß®°°0¬_¿¾UÖeff†•+W"22;vìÀÈ‘#eÞ? „Ö‡. °°°€««+ ‹áç燪ª*˜™™AWWWfx Bä…±±1V­Z…¨¨¨Ÿ¾œÚØØÀÒÒS¦L¡“DÞ¶ңGÌ;©©©¸|ù2.]ºCCÃo¾Jé8ª««qæÌH$DFF‚Çãq•ò¤I“(@D®dffâÂ… xòä FŒO>ù¤C&‚õ%‡`gg‡çÏŸãÉ“'ÈÉÉH$‚¦¦&z÷î.]º`ذa,"ø|>ìííѿܻw"‘ˆ§³½v²X^^Ž   TUU!::`kk J)!|=###Ì™3©©©HOO‡H$B=(9$„¼•ÊÊJRRR @€ &€ÇãQHäRFFîܹƒ˜˜hiiÁÕÕ•:_{ƒN:¡ÿþ€Ñ£G£¤¤ñññÈÏÏçš—jkk´´´0|øp i3<°··Ç½{÷¼׳{÷îèѣƯ頋Åb\ºt‰«ïß¿Ïõx, )lŽs‡IGymaööö022ÂÉ“'å*ÒäðÌ™3À%ˆRæææ°´´¤3…´ksçÎ…®®.FEÁxEbb"rsse¦)++ÃÕÕÀ‹æ:4XO[Gkk[ÛÆ.;lm­­{W«Öª8°"¢€ (eOAö’MH ÉᅵŸ‘Q„÷ëºzÕN’“ûÌû3ÃÂÂP[[˼¾wï^¯Øn333˜™™)Ü·îß¿ÆÆF…ävÅŠݾmo¾ùf‹‰(—Ë¥š¿nô\jËËË›]ýýýaoo¯”É•L&Ãõë×yyyÈÏÏgþfkkKs¼ôbööö4J\;øùùÁÛÛþþþŒ§4õz’D"Á7l6ãǛ͆ŒtXS áÖ­[»ôsãââ ‰PRR‚þùNNN4h%‡pïÞ=dgg#11‘YÆãñàîîÞ,aìÏCÙ÷5ñññ …Ì눈lܸQék›\¿~©!¼{÷.óo°²²‚££c·oÓýû÷›Ýc›¦æÚšššÔg÷9{.5„Í.€ÊÖ<¥±±ÁÁÁÈÎÎFaa!ÓükÆŒ°´´¤#ƒàq“¯–F&nº9566"** R©|>, nnn`±X” ¥0jÔ(æß¾¾¾ˆ‹‹Cvv6nß¾ GGGŒ?žéGZVQQû÷ï#11ÕÕÕxá…0tèPƾŸyº©bee% P^^®ÔI`^^rss1uêT¦™èÇ 6›ÝãÛçââÒâr‘HÄ´6 …àóù·Ð7n8õÙUö„P™¥§§ãáÇˆŠŠÂ”)Sðâ‹/RHé06›Í” Oš4 2™ Ëåàóù°²²‚µµ55]&J• Ž5 HIIÁ0hÐ L™2…Ã'DGG#''‰‰‰ÐÓÓÃØ±c±bÅ ŠQ0vìXÜ»w³gÏVšmÊÌÌÄ­[·˜$ÐÇÇVVV½*®\.W¡Öµé*‹qïÞ=ˆÅbðù|¨©©ÁÅŪªªððð ’ÂOoݺ---ØØØà“O>¡½Oér***L³±‰'"''¹¹¹LrhccOOÏ^9Òé[ôõõáîîwwwÄÅÅáàÁƒ4h<==¡««ÛïâQVV†øøxÄÄÄ@ `ìØ±T Hz ™L†›7o"44¶¶¶½2 l‡ÃÜc§L™‰D‚ÈÈHH$ðù| <2dHŸüý”vPCC> mmmÌœ9´× !ÝÆÚÚÖÖÖ˜4irssñðáC|ñŰ´´ÄàÁƒ1iÒ$¥h¶Cú·¦ZÃØØX>|666°¶¶îóý £££QWW‡èèhp¹\Œ9k֬ǣƒ‚ô ¸uëÂÂÂàååÅ4­ì/ÔÔÔ˜.S¦LAff&òóóqýúu`òäɰµµ¥ä°?'„‰‰‰¸pá–/_N‰ !¤ÇYYYÁÊÊ ÈÍÍEff&¾þúk˜››ÃÓÓS¡¯b@@ÜÜÜh@ Ò­FÑ£G#66ÙÙÙ ——3¸C_HE""##! 1nÜ8hjjbíÚµÐÖÖ¦€ô*éééøã?àááO?ý”‚ÿßïßÃÃ2™ ·nÝBPPrss1eʦöiùùù033ë·´Ýšòx<‚ç~Ñ‹Å8räôôôðñÇÓÙAQÚäÐËË yyy AHH†Š & ;;”’M «««qóæMcüøñÐÖÖVêä°¨¨—/_ÆÊ•+%%%ÈÈÈ@aa!’““1nÜ8p¹\¼õÖ[4#鵤R)Ž9.—K] Ú ¢¢///xyyA.—ãæÍ›¸qãrssáííÍôñ€“'ObÖ¬Y=2Òj¿K‡ŠÔÔÔç6WS"XVVª$„ô Äk¯½†¼¼<¤¥¥á»ï¾ƒ¶¶6öîÝ‹Ÿ~ú êêê$Ò#tttðÒK/¡ººÑÑÑ(++Ã7àêê MMMŒ=B¡B¡†††=¾½§OŸFee%>úè#¨««ÃÄÄvvv>|8^yåÚ¡¤W“H$8zô(ŠŠŠàççGÍ Ÿ‹Åb&·€   #''ÞÞÞ¨««ÃéÓ§ñÉ'ŸôËZÂ>Ód´¾¾§OŸÆìÙ³annNG>!¤W&†d¦«¸uë¶oßWWW¸¹¹ÃáPH%†MÇeMM "##QRR‚óçσËåB,cêÔ©°³³ëTb˜——‡þëz………ÈÉÉäää 550þ|èééÁØØ˜ÎÒ§dee!,, Ó¦Mk×9BÚöä´PAAAX²d îß¿ÐÐPØØØÀÆÆ†ÂÞ–FDD 22~~~” Bú xxx $$?þø# 1eÊ”çE$¤» 0€™»wÞ¼y€ØØXãÔ©S(++ðxζ–ZêØØØÀÄÄÀã~;MS?Éd2ìÙ³ºººÍ&¡~ðà222˜×æææLíÈèÑ£±xñbÚ1¤Ozøð!‚ƒƒ¡ªª ///JŸcrhoo   „„„@.—ÃÑÑ/¼ðTUûþ¤ ½úfff"<<ÖÖÖøðÃéˆ&„ôIžžžðôôDAA‚ƒƒqìØ1xzzbàÀ”¥ÐR¿Âøøxäçç7[~ÿþ}”––,,,PPPàñh‰ƒ†‰‰I³‰¾Ç‡¥K—R ‰Ò*((èÒ®J ˆŒŒÄÇ©V°’Ãììl$''ã›o¾¹¹9FŽ ##£>[sØk¸¸8ÄÅÅÁÇLJj é€úúz$%%***( ½€……^{í5@HHîܹƒ   Œ;ŽŽŽàr¹¤^F.—#&&ÀãQLMMûÌosrr‚““ídÒ/ìÛ·¯Ë¦|ÈÎÎFhh(ÌÍÍáïïOÁíMÍFgΜ‰œœ$&&")) =z4 úTrø\Âäädœ>}P\\Ü%Ÿ)‰pôèQÁÏÏŽXB:H*•¢°°  ) ½Œ§§'“DÜ»wAAA‰DðððÀ„ š Œ1‚‚§dšÎÃÚÚÚ>•ÒWíÙ³EEE ͘»‚X,ƱcÇ ªª oooªTONU‘››‹¸¸8$$$ ;;>>>ÐÒÒ‚ƒƒ444Z|MM Øl6´´´úgBèèèÈ”–\¸pY^\\Ü¡›^ll,©¯ !]@[[sæÌœ9s†ÒK™™™aΜ9̾ Á®]»Àãñàêê ;;;hii!''‡B%Äb±˜}wÿþ}Èår !JnÍš5€«W¯bçÎ]ò™III¸xñ"–-[F‰ kš2ªIPPÊËËCCCŒ7Æ SHÃÂÂ`hhˆñãÇ÷Ï„°5¿ýöÛ3U«gggãÚµk066ÆæÍ›éh$„V4õ7,))Á;wð÷ßC("''ÖÖÖ˜5k‰B”DNN®_¿£jêsèëë‹‚‚DEE!00zzzpuuÅ€‘‘œœJ;J$áÈ‘#ÐÐÐÀܹsaffFG!„´ƒ‰‰ 3$ð¸ vv6ø|> àååccchjjB[[›F!$PZZŠ””888´ë=¹¹¹¸víØl6f̘ÁŒ¶Kz/ æ¾[XXˆˆˆÔÖÖ¢´´B¡·nÝ‚lmm›uëè— ¡@ €H$ju¡Pˆ#GŽ ¦¦~~~”BH'9::ÂÑÑ3gÎDYYBBBpëÖ-ˆD"8;;ÃÌÌ ‰‰‰xñÅÁãñ(`„ÒNwîÜÁôéÓ¦+hM^^®^½ UUUÌœ9³KG&%ÊÃÜÜ ,PXŒÔÔT\¹rÚÚÚ044Ĉ#`mm ---ˆD"466öH!m·'„}ôlmm…¿åææâòå˨©©¿¿?u®'„çÀÐÐ .d^‡††"11ظq#,,,àîîŽ"!!Ó§OÇ€:ô]gΜÁË/¿LA'„ôyMµ„O'„"‘111¸~ý:ˆY³fQ"ØM™2EáXyôèqùòeÔÕÕËå‚ÅbaîܹÐÐÐèÖQL»=!Œ‰‰»»»B(‰pãÆ hhh`þüùÌ„µ„Bž¿''÷öö„‡‡#66¦¦¦X·n3š‹‹  ôÿo"ªª­Î…(“É ‡ƒ¹sçR  !}ZJJ JJJ°`ÁˆD"äææâæÍ›¨ªªÂ˜1cºlZ ÒûÃØØÇWX~ëÖ-ÄÆÆ¢¾¾ÙÙÙÌœ9“YÇÌÌì™ iE"NŸ>Ýê4&Ýž¾ýöÛ€ýû÷#00—ËÅÂ… allLG!„(' ¸€ˆˆÜ¿Ÿy-•JqìØ±?C"‘ÀÌÌ %%%PBHŸµ`Á„B!***ŸŸOÁ%]NGG§OÎmxùòe 6 ÅÅÅ­®³gÏ…ópÆŒ¹\Ž‚‚…ukjj —Ëé<$=ŽËåÂÀÀ Ïý.@€Ã‡£  óçÏoqˆˆ…Bðù|üöÛo4( é? amm­Âh5fff022j6OàÓêêê ­­ ;;;œ8q‚Yž˜˜ˆ³gÏ*¬[\\Œ/¿ü’’!ÝjÍš5xá…zõoHMMÅ©S§˜×«V­Â²eËÔáâÕ«W–•””`ûöíØ¾}û3^mmm‡ö›æÝQQyöÖëõõõ`³ÙPSS{æ÷J$466BCC£CÛÝ™ß, ¥¥‹õÌï …PWW‡ªê³wÿ‹Å`±XPWWæ÷J¥RH$’V Û"—˱~ýz¼ÿþû½ú<,))Á¯¿þʼ^¸p!|}}‘™™ÙfBØ™LÖì<|ðàî߿ӧOwh…B!8Ølv‡Þß™c¤+ήx¿2lCgß/“É  ;59ug·aÒ¤I ÷Þª¨¨r¹ ¥¥…¼¼<¬^½Û¶mkõ=Ì(˺ºº¨®®fÂ_ýU¡@5##IIIX½z5=p‘^aÁ‚˜>}zË aFFîÝ»Ç,\±b^xáܺu«C_6bÄŒ1BaYvv6ÜÜÜ:ôy999¨ªªÂ¨Q£:ôþ€€Ì™3§ÃÁ Ä”)S:|“ìì÷wæýeeeHOOïpì;»í¡¡¡1bôôôºýû ððáÃ^Ÿ6¬ÝsUTT@KK b±*** „žžV­ZÕ,V¡¡¡Ú>>ŸßṕvïÞÝá)g.^¼KKKŒ3æ™ßƒüüüÏי߼mÛ6lܸç™ß{ìØ1¸¹¹µ:ï_[‚ƒƒÁf³[Òúߤ§§#::K—.íP’²k×®^511i÷>¯®®†šš455¡©© ¡P …B6›ÝâyxáÂ…ÀÁƒáãã++«½?((˜8qb‡ãÔ™s£+Þ¯ ÛÐÙ÷WWWãàÁƒØ°aCþ†¾àÊ•+hllŒ9²Ó#$¯]»VáõÕ«Waee¥07kG’Ö‚‚Œ;¶ÃŸ!‹Òâƒ~w>ó@BB´µµ;“ÂÂB*ELBBB0f̘gž÷OYcßzB8f̘fU=bæTQQQaJšÞÿ}lÙ² €¹¹9233QPP 0gUKlll:\‚rÿþ}tøá­°°°S¥7xã7:T:Þßß™÷ggg#$$Ë—/ï‘mg±X˜9s&,,,ºýû‘ššÚ'KxöïßÈÈH°ÙlmÚ´5Kë*³fÍê—ß­ ߯¬V®\‰•+W6[~æÌæßÆÆÆøðßû¶lÚ´©GbÐÙR¿Þø›_~ùåù^[[[ØÚÚÒ‰÷” `Á‚Í–?ÙôZCC£ÛšË¾úê«=“ž:7”i(ÊëÁƒ ƒ­­-Ξ=‹åË—CSSúúų́Ýööö÷Õ_²d tuuŸë6™™™uª™v_|æ255Uš˜Lž<¹Sµƒ]yœt¤eQ{µš>Ý”¥É믿®ðÚÏÏï¹ÁÈÈFFF=¶:Ò$­+7®_~·2|ÑÑÚïÎzº]wa³Ù=v³é©X«©©õHí"‹Å¢ÚÅvÒÔÔìÑïWSSë±Z÷ž>?”i”áœQ†ýð<899ÁÉÉ©Ùr8880¯ííí™ÄðyÓÓÓëp·š¾úÌ¥¯¯}}}¥Ø–§»ÀõÕ˜°äM½mŸ³»wïvªú¸·~wOMM .tÝ)11666êßQåå娬¬Ä!CèIó uuuhlll³ÄK(B"‘@GG‡FÚE(¢¡¡¡ÕÒt‘H„úúz…‡ þ¬)mÅ¡¾¾"‘ººº=RpBú¶††ÔÕÕAGG§Å¦Æ‰DaŽM×ãÊ&;;ÿÚ¬ôy“J¥ˆ‹‹SŠ1”%&‰ñññJ.—Û©f§]“„„„+ºº 555Œ7®SLþ¡¼¼€ššÆŒÓâÀ5Ÿ|ò‰Â(Óýù<¬­­ÅîÝ»Ááp0|øð»\ˆÅbìܹƒƬY³()$]š îÝ»077Ç‚ š%…çÏŸGxx8,--‹/îñÚžôÏ?ÿàÂ… X¾|9lllZ\'%%üñ/^ŒaÆÑFº\.Ç_ý…ŒŒ lذ¡ÅÖP—.]be±Xøì³ÏÐå½ÏwïÞ ???Œ;üñG‹ëìß¿¾¾¾ðööÆÑ£G{å…ôyU¬J¥RÔÖÖ2£bµ–ÕÖÖB*•öûÿèÑ£ðòò¼yó°oß¾×ÉÌÌÄ|€wß}ÿùÏúu¼<ˆM›6aãÆ¸téR«çðûï¿ 6txj‹îríÚµçöÙçÎ÷ß~Ûêß…Ba‹#³^¿~½Í[oܸÑçÎÝŸþ™9fnÞ¼Ùâ:***°··GeeeµXP?üð>øà¬_¿ááá­®³~ýz¬[·)))¨««ëU¿±¢¢ÑÑÑÏíó¿üòK´ú÷ˆˆTWW+íõ¥§8qsæÌÁºuëÐÐÐÀš>mäÈ‘¨¬¬„®®n¿ž6,..ÙÙÙàóù¸~ýz‹s…¦§§#&&|>÷îÝCFFFŸøíM}+Ÿ¡PØæµM&“A"‘(íö+£¿þú C† Á;#ÿýï-®sïÞ=|øá‡ |*× IDATx÷Ýw±yóæÇ÷è®ÞÊÊJèééÁÞÞééé-®S\\ 333X[[#77·×{÷îݾѴ¦  ›6mÂ;wZ]çÑ£GøôÓO›ÍaÕåääÀÆÆ¦¦¦Í&[oR]];wbïÞ½øå—_@úŽˆˆˆD"¦¥éµH$b PšF•kZ§¾¾^a™LƬӔ¬ÍŸ?Ÿù{KD"þùç…š«««Â® hhh@CC¢¢¢˜mlhh`Ö©««ƒ@ ` ›šFÃkº™I¥Rfe2™Â:O6ÅTV>>>Ð×ןÏoóúFú†êêj$&&B @(x\rÝt 7=ä5OžCMë»éjº^Ô××#""Ì:½¦ô6#FŒÀ€ÀçóahhØf¼ûºŒŒ ØÙÙx<`[iii³urss™)_¬¬¬——×'~{[s6vV```³©<žŽû“ƒåuõö߸q£Í ˜Þ(>>NNNàr¹­>訨àÇÄÞ½{ñÍ7ßhcPÒ¶ÐÐPÜ¿ÎÎΘ;w."##™ÒÄ·Þz ºººøùçŸQ]] ¼òÊ+ˆ‹‹Ãùóç<%ÒÌÌ {÷îEII lmm±lÙ2X[[cáÂ…m~·©©)–-[†ÂÂBæÆsêÔ)¤§§C__ÿýïqãÆ L›6 ð÷ßcüøñˆŒŒDdd$455±qãF444à»ï¾L™2“'OÆ•+W6›Í›7C.—ã믿¸¹¹1ŸÙ›|uuu¨¯¯ÇÛo¿C‡1–ƒ†­­-™ýµbÅŠkÎ¥ªªÚâ1#‘HÀb± ªª —­Y™¨ªªB"‘4‹GS’¤¦¦ÆÃMÍ}zcsÑ€€”••A&“ÁÓÓEEEL­‰L&Ã;#ï¿ÿžÀÄÍÍ 555HLLdâñÑG1çð¸ÆjÆŒíúþÝ»wÃÐÐõõõxë­·PXXˆ+W®6›ÐÐP 8b±+V¬ÀÅ‹™V:yyyÆéÓ§aooÏ\S444ðûï¿ €Y³fµyMÑÒÒRºÖ)MçlÓ¾h:¾!•JÁáp0hÐ ]˜@*•âÿûª««±víZâ—_~AEEìíí±xñb$%%áÏ?ÿðxðIKKK8p………°²²ÂòåË‘••…ãÇÓ¤vþüùˆoóûKJJÀçó¡££ƒ·ß~uuuÌsÝôéÓ1räH„††âîÝ»àp8Ø´iÄb1¾ÿþ{æZ <®ñˆˆ|üñǸsç¾þúk„„„`òäɘ:u*nݺŴrÙ¸q#QWW‡ððpŒ5 /½ôRŸhºÿé§Ÿ6{.îò„ÐÄÄ………(--U˜H~çÎX¸p!,,,`ccƒ¬¬,ˆÅânÅ©«±X,ðù|üòË/xôè._¾Œ-[¶0¥vvv˜9s&¬­­‘––†ÊÊJ\¸p©šŽŽfÊÑ£GãÚµkˆŽŽîÐà3IIIàp8àóùHMMÅéÓ§‘––†±cÇ";;wî܃ƒN:…Ç£¤¤ûöíÛo¾ÉlÏ—_~‰1cÆ )) ›7oFcc#îÝ»‡   f¨¨(Èår¥:† †äädp¹\…ɘ;gggŒ1ÁÁÁpssëµU]éÍ7ßÄ×_ ™L¦0—ÍÚµkáåå…eË–aýúõضmd2|}}•ú÷ :|ðsQ377ǃ`ee…ÜÜ\äççƒÃá0µsæÌªª*d2êêê`ll {{{üüóÏ066ð¸)E{Â3fàwÞAmm-öî݋ɓ'cÆ Ìͪé|yûí·ñý÷ßÃÍÍ aaaؼy38¶oߎ††¸ºº2Sðù|Ìž=uuu¨««CLL jkk¡¦¦Æ´LpwwGEE“ŒÚÛÛ3Ûß6lØ€o¾ùR©TaRãO>ù&&&ذaîܹÃÜhû{bøÁàÛo¿…T*U˜>åÛo¿…\.Ç'Ÿ|‚M›6á›o¾A}}=<<®^½Š´´4f€±û÷ïcݺuPQQA]]ÔÔÔ0a„‡‡3çë¤I“7oÞ„§§'€Çƒ´µ7!\·nÌÍÍqèÐ!TWW£¾¾žùì°°0xxx`Íš5>|8Ο?’’3HMÿ÷÷÷ÇĉqëÖ-äææÂÚÚšùœØØXøúú6»¦¤¦¦2ëøøø(ݾyíµ×°k×.”••á…^`_;þ<þüóOüþûïÈÊÊÂï¿ÿ¹\•VGŸïFމþùC† Aqq1Ó $-- áááX±b† ‚[·naܸqÈÊÊ‚——WŸøí)))8xð tttÀçó1tèPxxx`èС8þ<’’’pîÜ9…çÛ´´4888ÀÏÏyyy(((ÀÑ£GñÑG¾úê+|ñÅíúþŒŒ ìÞ½>ĉ'àçç§ðì:xð`;v ¿ÿþ;ªªª°k×.TUUÏçC*•böìÙH$ˆŽŽfÞw÷î]xxxÀÛÛï½÷SðvóæM…óßÐÐàóùØ»w/ŠŠŠ`nn®ÔûËÅÅ:t¨Âà—.]€0yòdܼy®®®Š…D]½!k×®ÅÞ½{all¬0 /ÇcJ—/_Ž£GB]]K–,é•'ÈÓLHHÀŽ;&LÀŒ3ðÛo¿¡¦¦‰k׮ł ˜u¬­­¡©©‰'N $$@×÷[^^Ž„„„V·ùÒ¥KHJJ‚\.ǽ{÷ ­­ gggìØ±r¹®®®øðÙ9µÄb1&Nœ¨TIÕâÅ‹ñÇ ¾¾+V¬`–kii1£Fbâþoµ¯}‘‘>ùä“fË8 p®¶´Ž2JKKCNNÌÌÌÀb± ¢¢¸ºº‚ÅbAMM ÁÁÁÌ~ß¶mV­Z…ùóçÃÎÎ €©©)s£h˜H*•¢±±±Åšœ¶444 ±±PQQ\.Ç·ß~ ww÷Vk]#""PSS ¨¨¨àÀÌMǵƒƒó€üÍ7ß`þüùXµj qáÂ$&&bäÈ‘=²´´´˜±'55E›éÔÔÔZŒ×ÓËšŽÉÞ*88¯¾ú*S{<`Àæ7±ÙlH$xzzbüøñ …عs'ÆŒÃ<4~ýõ×ðöö†§§'³¬éÁíÉó¬µóêÆX´hS0€>úIII ×¼§ {›úÔ55ù Æøñã™súرcøè£PPP€-[¶@&“1×”ÄÄD@GG‡ÙæmÛ¶ÁÙÙYéöÏ[o½ÕlÙ“skÚÙÙá³Ï>£öÿ `ÇŽxýõ×™ÖªªªLa X,vìØ%K–(R÷fŽŽŽÍF%?zô(3œ··7^yåæ9ËÂÂK—.űcÇ©TŠ¥K—"??ŸY§©ùmGž·ÿúë/¤§§C.—#66–)$m‰ªª*Æ555¸»»3ßÿô€zm]Gžþ~e7cÆ \»v ÇŽÃÆ™å\.—™ÇpÒ¤I̳}Ó fÏ¥ÉèêÕ«›-{òaèžù Ÿ—¦¶·jjjPQQ¶¶6<==Jï™6æ***PQQAhh(ÓOAUUˆE}}=† sssdffâØ±c`³Ù8p`‹#Y`ïÞ½¨­­…LLLð×_!!!, /¿ü2¸\.®]»+++f»QTT˜;w.=z¤°= ¸sçÓ?IMM áááÌ:l6[)kØ-ZÔlÙüùó™ôú+ÒzTpp0ŠŠŠ°råJXXXàèÑ£‡••–-[;;;æÂ·lÙ2˜››#,, .\€±±1V®\ wwwf___ >W®\—ËÅž={Z|pÒÔÔdn'N„D"Á®]» ¢¢‚ÈÈH¦fZMM QQQLbÔ”tNš4 ®®®Ø¿?êëëñÞ{ïASS;wîD]]Ö¬Y1ÛøÖ[oA__{öìAyy9†ÚcÉ !-ÑÓÓÃÊ•+±}ûvðx<¦©WÓ1£Oœ8‘©é‹ŽŽ†L&CXXÓ_°©`ÉÃÃ_ý5TTTðᇂËå2ïsssCzz:vìØÁÖòx¼^±Ï¦OŸ®Ðú¤é:úd¢üôqÚmó’ž•——‡k×®aåÊ• Bº‰\.Ç_|Á²xzz2Mßž´uëV*‰'D Ëå¶ZAé»víÚ…E‹1µ¡}%„ýDMM 233•²Ù !„B!Ê$::Çgµ¢„B!„BHŸ£B! „B!„J !„B!„PBøXTTÄbq›°k×.\ºt‰"IH7ûì³ÏÞêß ñùçŸcëÖ­HOO§€ò9r„™l¹%"‘Ÿþ9ø|>3Ò,!¤g…††¶ù÷ÄÄD|ýõר¨¨ `‘þFEEáÓO?e†vmÉO?ý„E‹ÁÔÔMBºÉáÇaii‰¶ºïÛ·[¶lÁ§Ÿ~Š“'ORÐéb.\€––3ŠlK¾ÿþ{|üñÇàóù¸rå öÃ?´ùÌš˜˜ˆ´´4¼÷Þ{8yò$ÊËË)h¤ÏkuššL›6­Í7WTTÀÈÈFFFàóù˜3g€Çs–´t²ùûû3“yB:nÙ²e is¹\ÎÌÍódâøèÑ#üòË/ ë^¾|ë֭òeË(¸„´Ó¬Y³““ÓfM½L&kqÂc©TŠ/¿üRaYXX<<<ðÉ'ŸPp y"##±zõjüðí®www¨««ÃÀÀ=‚àСCxôè‘Âúƒ ÂË/¿LÁ%}3!ôññA|||‡>ÔÞÞ¾ÙDή®®ðññ¡„®8qUU;üÞ¦œ'eee1¶Bžÿy¨ªªÚì<äóùJ¥XBž—N½ÿÕW_UhpíÚ5ìÙ³‡BÒwÂÖüúë¯ðóóƒ––x<jkk‘›› GGGf6›ÝlÎŽ¦š BHç%22‹Åàóùxï½÷ ­­ ¡PˆÊÊJÀرc >ŸÕ«WÃØØ˜GúoBøñÇ·¸üóÏ?gþ­¦¦†wß}—¢HH7k-Á{ºfþé×D9lß¾R©ï¾û.ÔÔÔ˜åqqq ÁÈ‘#¡©©ùLÍ›Nœ8²²2æõâÅ‹»¬‰~`` ÒÒÒ–ikkã7Þè×û‘Ëå‚Ëå6[ÞR-Bo©IÈÈÈ@CCŸ---hhh€ËåbåÊ•´s{¹‚‚,Z´gÏž…§§'ŠŠŠpðàAÈårØÛÛ3ÍÓ{›””1¯íìì0cÆ …u>|ˆãÇcĈ˜7o ¤CÎ;‡ääd¦?0ÇÃÂ… ammÝê{©T ‡___ 6¬Ùz!!!ˆ‹‹CCC¦M›†Q£FQÀÛP__Û·oC,7K£££qóæM…Bhhh€ÅbaãÆ …´í¹¦TVV*ô+UWWǃ­­-Ó’«£.]º„ÚÚZèèè 66 ÍÖÑÖև÷··B÷=¥O£¢¢‘‘Ñ£GcÞ¼yPUU…D"AMM 0`À…þN¥¥¥øý÷ßáîîŽ÷Þ{êêêÈÉÉÁ_|Å‹ÃÎÎÀ㎽ZZZð÷÷‡šš®]»àq³¹“'Oöû’lBˆrرcÖ¯_]]]|õÕWˆ‡P(ÄÒ¥Kaff‹¤¦¦âÌ™3˜;w.~úé'°Ùl :EEE¨©©AEE „%K–@WW·ÙH–k×®TWWãáÇøïÿ 2똘˜€Ãá 770~üx\¿~<¯¿þ:tuu! [¬iÖÓÓŸÏG]]êëë!‰ÀçóÁb±ÓñãǃÍfc̘1´ó{ÌÌL¼öÚkÌÃìÁƒñþûïƒÅb!==Ço÷hÄ7nÜ@jj*S€ÐÖ4VM455! ™×FFF Çô³ŽGœœŒ«W¯ÂÂÂK–,a–§§§cÛ¶mpvvÆŒ3••…ˆˆ|øá‡Ø»w/JJJh<òÌÏ·>„ƒƒæÌ™Ã$5558{ö,ªªª0þ|ØØØ0ï¹zõ*bccáåå…wß}ªªªhhhÀ… pûöm¬^½šY788***xíµ×ÀáppýúuÀ¨Q£…ñãÇÓNxÊýû÷1vìXL˜0‹/Æ©S§ß}÷†Ž·Þz ššš‰DÇ—_~ MMM¸¹¹1…µO_OnÞ¼‰òòrØÛÛ·xÿmhh@mm-²²²Àçó¡««‹%K–´»éq@@233QUU…Y³fÁÎÎÕÕÕLô4@±XŒ7nàôéÓPQQaFÅ4iœœœÚõ½,y[™u!ggg :\.øõ×_›­#‘H’’‚sçÎ1"ºººxõÕW¡§§§°ncc#Nž<‰‡BMM puueþ^]]]»vÇãaÆŒ ¥¤VøùùÁÛÛþþþŒçlÛ¶mظq#8D"¸\.´µµÖ«¯¯‡ºº:TTTP^^™L†´´4˜ššBGGúúú-NgКk×®áÆØ´i³¬¸¸ °²²bh|||Àáp:üûär9Ótµ¡¡¿ýöx<Þÿ}Úùÿ‚ÏçC.—cëÖ­=º |>ÉÉÉ8}ú4,X€‘#G2ß·oJJJZ¬-¬ªªÂï¿ÿŽÆÆF”——ÃÛÛ›©åàñxíj6[WW§Ð$þÉ!þwïÞ ¹\Îã>ý,û4ÇÔ~Ϙ1;vì „ðÿˆÅâf÷½ŽÜ‹žl¶ÞQO'‚Mž®|–ã¢#×ÍÈÈÈVìöÉ544Ú}ÂBéÝžåáœô¬†††N5V†ã¬+Ž7‡±XLiOOO„„„P ˆRc±Xmö‹¦Ùâ !¤›ÄÆÆÒ¨p„ôFFF(--¥@Õ4ÀËäÉ“)Jä·ß~cW#ÿ®ß$„Ë—/Ç¡C‡hòª««qèÐ!:t™™™npùòeÌž=›A2™Œ9ccc) JbðàÁÈÊÊ¢@UPP€ÜÜܯ]§šmEµµµ-&EZö\;²4R<Í®''¹åñxÔ'hjj2ƒ;]ºt‰BH`±XÌy×£Û7ÒN!ä_ìÙ³EEEÈÈÈ` Q†kI7©ô$IôÕ§„°ŽŽŽÌhe.\€““¦L™BQ'D ¨©©1ó!Ñ ÝC&“uj¤2Ò7¦óPWW·GèÄbq¯íCØÕÌÍÍñàÁ iÑš5k<eô÷ßÇúõë)(J¤¾¾¾]ÓÜÿ¯[ŸLÔÕÕ[݆BúºÆÆÆgš;Ò3œœœO íâààÐ%£Q’®‘’’GGG „²&„„BQ>EEE055¥@Ò#GŽ„½½}o‡££#’’’úýþ¸rå fΜI&%„Íéêꢲ²’ö8!¤GìÞ½›F<#J+!!NNNˆ' ¬¬ŒAz ___\¸pA(!l ›Í†L&£=NéeeeÔ¤ˆ^ÄÞÞéééBz@@óßRBH!ʉ”!ÊìŸþÁèÑ£)O055EII ‚^$55Æ £@(sB¸{÷îý±ƒ¦QÃ!Ýî×_Å›o¾I JK$Ñ oO5jòóóQ^^NÁ ½‚ºº:$I¿ýý‰×®]£ù~•=!tppÀðáÃ{ìÇΞ=—/_¦½NéV¥¥¥011¡@¥www D &OžŒÛ·oS H¯Ðßç"Œ‹‹£¾Ð½!!äñxàr¹=öcÕÔÔÐÐÐ@{Òm~ûí7¬Y³,‹‚A”Rnn.¬¬¬(- ZBÒÛ¬\¹û÷ïïw¿»¡¡×®]Ü9sè Pö„°§ikkÃÄÄYYY´ç !Ï•\.Çž={ ££CÃù¥CCC :”‚ÑŠåË—# €’BÒ+XXX ??¿ß%ƒGŽÁªU«èè Õþöƒ—.]Š“'Olmmé „t™””dee!??ÅÅÅX½z5ÌÌÌ(0Dé””” ((ÕÕÕð÷÷§€´ÇãaÁ‚8|ø0Äb1 §§777 Q:, «V­Â¾}ûàéé ;;»>û[™™‰ääd¬\¹ÆÆÆttô¸‘wSccgggXZZ"  Çtcc#Ž?ŽœœŒ7ŽŽ‚>ÌÙÙ™jgž"ª°ì‡~@VV )@0oÞ<øøøÀÒÒ’AÒ&™L†k×®),;qânÞ¼ ‹çþýNNNxÿý÷•b2íÞ¤¶¶©©©ÈÊÊÂ?üÐg§——¾ý<+…Ì IDATö[ÚáÿâêÕ«˜9s&îܹWWW¥Ú¶‚‚„„„ ##ãÇï3ÝÄb1bcc#FŒÀàÁƒáììLc'=—ÂÄÄDœ={VaYqq1,--•âG³Ùl¸¸¸ÀÀÀ;w ûøã)!láø×××WX¦®®ŽeË–aÖ¬Y NHMMÅåË—Áb±àêêŠiÓ¦QPH«ž>¹\.^|ñÅniöTZZŠ«W¯¢¶¶/¼ðíŒvˆŠŠBNN’’’ ««‹Ÿþ¹ß›ä±_ýUa*’ŒŒ ¥ÝV L˜0†††Ø¹sgŸ™‹›ÇãaåÊ•GGG 8Ì.Ð/k“““[[[L˜0ŽÒïùùùÁÛÛ›šŽu¹\Žˆˆ¤¦¦bÅŠÒ.|>r¹[·ní–﫬¬Dhh(tttàááA;  AAA‹Å°±±éÑÑÒ‰rQÖB¹\ŽƒB]]C† ‹‹KŸª!Œ‰‰$%%¡¤¤îîîðôô¤²ú]Âääd$$$àÕW_¥½Oy.X,ÜÜÜ`aaƒRRH”’žžæÎ‹ÿýï=z4ttt((­$ƒ>>> ÒÌ„ p÷î]¥J<ˆiÓ¦õÉÚ3‡ÃÄÚÕÕ‰ááá8yò$=ÛwB¿eT*•âܹsX´híyBÈsgmm ooo:tˆ‚A”–ƒƒRRR(-¨¨¨@RR&MšDÁ -ÒÕÕEUU•R=ëö›¦”jjjðôô„³³33h$¡„°Mµµµàñx´× !Ýšæææö™þ¤ï?~<îÞ½KhApp0¦L™B ½ÆÑ£Gûe÷aÆ¡®®®ßM¹A atËèm„ò$=z”A”’¾¾>*++)O©¬¬DAAFŽIÁ ½‚L&C^^¬¬¬úåï_¼x1N:E‚²'„< Ç~ìÙ³g±páBÚë„neccƒììltÓ^„<³áÇ#))‰ñ„¨¨(ššŠô*‰jjjýö÷kkkCGGt0(sB8tèP¤¦¦RÔ !ý›Í¦f£Diéèè ººšñ„ÚÚZ 0€AH/²hÑ"üñÇeN !¤¿Zºt)Nœ8A J›*ÓÀÊ 11#FŒ @Ò‹°Ùl466R (!l™T*…ªª*íqBH°µµEVV‚(¥ & **ŠAH/VXXØïÇÊÐÒÒB]] ”¶¬ººšæX"„ô(‹Eý ¡gÒ?~¼Ç·áÈ‘#ýr„ѧ™šš¢¸¸˜JJ !Dù¨ªªB*•R QrJ5Ñ8Q~<  (‰¥K—*E‚Þ«žOžç‡WUU1M¤D"E›%RVV†]»vâââàííMA!¤›Éd2|þùç€xxxôض8::"99ŽŽŽ´ciCjj*„B!%„Âö …ÈËË4440ËOž<‰W_}•¢OH244ŸÏêÛÖMLLLPRRKKK ¨¨¨0ç!ŸÏïÑ&Åúúú¨¨¨  ®®Žæ-&­*))AUUÊÊÊ(JˆËåREÔ³Þ‹žç‡›››Ã××¾¾¾ mñÓÒÒºý‡–••ÁÀÀ€ö8!¤Ç¬\¹û÷ï§@¢ähBzÒ*øúúÂÅÅÀã)Jš zŠL&‹Å¢ƒÇÝ3h¤Q%J•ÉÉ“'±dÉÚã„^¡´´”æR"„^ "", ¡¡¡=–644€ÃáÐÎø?¾¾¾8þ<BY >…„þ©½#®X±¢OLpúôiÚé½Ä³ ×^__¤¤$$%%!""?üðC·÷§JIIa¶¡é¿Ó§O#))©Sƒ7ÅÄÄÀÙÙ™òÌîÞ½‹{÷îQ ”€½½=ÒÓÓÛ½~YYJJJúm¼º}b¾?ÿüÿýïÇTµBH¡®®Þ®’ܱcÇ2}ºôõõ< ŸËåB]]½K¶E$¡±±ÚÚÚÏå·Êd2ÄÅÅÃáÀ××—v¾’suuŸÏÇôéÓ! ššš ëäåå!//·o߆­­-`À€Xµj.^¼ˆãÇC[[³fÍ‚¹¹ù3OÝ —ËQQQÑbÔÔTÈårœ9s2™ Æ ƒŠŠb¹öðáÑ””„¿þú VVV˜:u*ÌÌÌZý¾¬¬,ˆÅbðx<¦ooqqq›ï!äß‹žú^êõÿ©¨¨D"êëëQZZŠôôtX[[3¸::: בöª««C~~>󺤤, 1bLLL–––ÐÒÒê²”––¢²²pãÆ LŸ>˜3gNÏ&„cÆŒD"AFFF³‘ÌD"bbb+++Œ9111¨¯¯Gmm-Þxã &HM‰àßÿ '''¬Y³çÎCvv6¦L™ÈÈÈ€ºº:V­Z… 6`Ë–-tvBzÜܹsqáÂL:>ŸÏGZZ¾úê+¬X±–––xðàæÍ›‡ÂÂB¤¤¤`ôèÑÌH”M.]º„àÏ?ÿÄÔ©Saii©P«QWW‡ÂÂB\»v B¡ÄÂ… allÜê¶Ý¾}111€@ Àĉamm SSÓf…j%%%¨©©H$¹sçÀf³1dȨ««7ÛVÒ»ˆD"ÔÖÖâå—_F@@„B!^xáܺu ëׯ‡¹¹y›ï×ÖÖÆâÅ‹–EEE!&&æ_¿{Ô¨Q°··gÖí̱dkk‹5kÖ ++ çÏŸW˜¨šÇãÁÅÅEaï³gÏ"""b±˜jZÈ3Y²d îÞ½‹èèh¦àâéDðòåË`±XÐÖÖfžqÅb1*++±råJ…klII síž:u*ÊËËqêÔ)L›6©üÈÍÍÅ¡C‡ðí·ßâ×_ÅĉiG´B.—ãçŸföMbb"<==™ó¼²²zzzàñx¸xñ"Š‹‹all ;;;|ÈÜ“ÀØØzzz###Ì›7-¾Ÿ%ï¦1®qàÀŒ3………¸téär9|||¡¡¡°°°ÀÔ©S›½·¢¢À¸qã0pà@DDD@WW³gÏnö0s÷î]˜šš¢±±Ë—/§³€vðóóƒ···ÂÃy~¶nÝ ‡ƒuëÖËå2Ë÷ïßüü|¤§§cçÎ022j×ç]¾|ùùù(**b–ijjÂÂÂÓ§O‡¡¡a‡¶344¹¹¹(..fFÑkbll p¹\ÌŸ?ŸvjhšvbëÖ­=¶ 'OžDuu5† OOOKÖïß¿éÓ§÷ù}PPP JI»\½z;wîD`` €Ç5ÜÙÙÙÈÏÏgΗ   °X,Ìž=»Å”êêjìÛ·£GÆ Aƒ¡PˆéÓ§+´|«¯¯ÇéÓ§QPPÔÖÖbõêÕ´ÚpïÞ=a„ 8{ö,þóŸÿx<ŠpHHÌÌÌàììŒ={ö€ÏçCSSñññprrjós333ñ÷ߣ¤¤/½ô’B2Ÿ““ƒÛ·oCKK æÿ½ó ˆêˆúþ+½* XQPƒ ¨PT4–(±kL4Æ<&‘˜hÍãš(i𨰷 &Š(EQDŠTA¦Šˆ"(ÒawaË}?øî}\X,ËÂ.0¿/º—¹÷Î=wfî93gÎéÖ “&M¢·}¼-¥¥¥ E]] `ll¬pU¯ººšœÃf³Ñ»wohkk7¹Bý:ÔbÊ(**µk×^^^¯µ´—I{?~ ww÷&-æÚÚZ¡oß¾¤'Ä ÔHöîÝ GGGâ–FÐ8ƒðúõë ÃôéÓIû$ÞÑ ”ñìÙ3\½zàááñÆUuàå\~~>FŽ)g6¤®®>T¸IG"‘à§Ÿ~B—.]°råÊFÏÈÈÀíÛ·sçΛýçΓ›0íÑ£ÜÝÝUú¸páB£ãúúú˜1c†JîÁV狲°°ÀÂ… ߺ¼l¶òuèééc@ h4Ÿ}öA#0`D"1 „f`fföNú-Œ=£G~c9---b ¾%, 3fÌÀàÁƒþ}РAÍÎ7:}úôccãwnOïÊkÓNTWWC*•¾öOŸ>¥7i„Ö#..®I_pàå^ÛƒbçÎ$Í ÐBäææ"..®É¿K¥RÂÏϯ‘Û­&baaÑ!\C Y°£¦¨­­EAAD"V§)cð–auu5æÎûÚXdd$.^¼ˆ'NàÑ£GDšB+‘’’‚ÿý÷µ9s0aÂÌ›7$B#TL~~>Ž;öÚü{AAA°³³Ã7ß|ƒ;w¡j&,, ›7onòï|>ÇŽõk×Ô¬œ–B[¡I—Ñ#G޼qé:22’ŽÆãñèÿ :Ì© ‘H„’’<}ú”HÐjtêÔI.hG[D(ÊEå•yS^·'Ož {÷î ·Š_RR¹²iii(((@LL i4•3sæLLœ8±M?ƒìöêØRVV†Å‹#66¶Éóîܹƒ?üÀËU{b±›6mjôM­ªª"ßI‚ÚqrrŠ+ÚÝs%$$@GG§Q~ÍW ‚§§'¬­­qòäIÜ¿ŸvÑ|þü¹œXZZŠºº:Òg mCCC…i¥Ø…ˆˆúàºuëðå—_âÏ?ÿTêfOŸ>Exx¸Ü±ºº:,Y²Dé±D"¶¶¶RçWWW7+aMM ôôôÀ`0Ôrÿæœ/‹Q__ÿÚÁ¯%ëÎçó¡¥¥õÚœQ-u‘H„={ö`Ö¬YmºóÓ›Ó—þêNNNt@¦w¥K—.B¹WUU)½'¡©œ6oCdd$œœœ`hhøÎ禥¥¡S§No’ùU P^^‡VæË—/ÃÓÓS©Íë °¶¶~ë裯rïÞ=0 ØØØ¼ó¹Ïž=ãGàììüÎçÊÒµuƒ°ºº/^¤{xxÀÉÉ üæô Uœ¯ uhîù±±±tvuÔ!33³](¿›6m¢ 8zRöû-7A›™™‰ŒŒ :Té:ŠÅbˆD¢fM^S…ÚÚÚwΫjx9‰Íd2ߘ÷Mú›X,n–L¤R)ø|~³eR[[ mmm¥õXM“ÉêÕ«ñí·ß*lDM²uëVª¢¢BîØóçÏ)‰DBQEmܸ‘‹Å”@  ~ùå—×]ŠÚ°a¥,ÉÉÉÔùóç•>¿9÷¦(Šúå—_(>Ÿ¯¶û7çü‡RGŽQ[Ý÷ïßO=yòD-÷ÏÈÈ NŸ>MµGJKK©ÀÀ@ê¿ÿþ£ÊÊÊèãÛ¶m£îܹCQE;wŽJLL¤233©cÇŽµ˜œ›s®¿¿?õìÙ3¥Î=þ?,,Œºqã†Ú¾Wª8_êÐÜó+**¨?ÿü³Í¿M¦áóñù|ª²²’¢(Š ¤233)Š¢¨cÇŽQ999M^çÒ¥KTBBB³ê’••EŸOG÷c±XÍÞ0Ý–‘H$8yò$JKK±bÅ …³T*ÅÙ³g‘——‡U«V©uBÐ6 ( ÁÁÁÈÉɯ¯¯B·–‹/"99™þÝ0 JG“WHHRSS±fÍš&Ý€®]»†˜˜¬^½ºC[„–!!!¡¡¡X¾|9,,,ý=##´"»lÙ2XZZvXy‰D"ÔÖÖÂÀÀ Iå^,£¦¦úúúc(:"‘¨É€}B¡B¡6ŒŒTo&''#** ‰óæÍƒ••U£2™™™ EQ˜>}z‹ûgÚ/÷ïßGpp0 &L˜€Aƒ5*óå—_¢wïÞ###|üñÇV^'Nœ€³³3LMMqüøq…îÐAAA°µµEŸ>}àï﯑n»uuuoô¥›2ŠŒa‰D¢’•eE÷¯««€&ëU__‡£ÖU"e8{ö,¬­­accƒíÛ·ã»ï¾kT†Çãáûï¿§å¢)ûCÔÁÅ‹annGGGøùùÑ{—ƒÚÚÚ5jüüü°zõê6!³·éCEA$½ód“2}º)ÅžÅb5Ë{EUuQ7oÞÄ‹/àíí]»vaöìÙö'Ÿ;wVVV°±±›ÍîÐ{úE":@333Ìž=»‘Q(‹qìØ1TTTÀØØ .$F!¡Õ)--ÅÁƒÁáp0lØ0…ÛÖ¯_SSSÚ \µjTîËwñâE¬^½kÖ¬i2vPP¾ùæ|ûí·8qâD›ò•+WTR¦!wïÞÅãÇURÇÓ§OcëÖ­¦á?~ß~û-¾ùæœ9sFacccXXX ²²R­{Q5ÜÜ\ôë×&&&r¡³NØ 4zzzàóùù¿üò‹JÊ(’OPPP³ëW__-[¶4:~ûöm$%%5yÞþýûårF¶ÒÓÓáààzÖ±!L&þù'8€_ýµC÷Ãääd :, ‰¤I…]–æƒÃá@$µ‰g{ðàN:õF…eÿþýï|í-[¶ÈårT–   äææ¶ø¤Édeeá½÷Þð2§fEEE£2, 8pà¶mÛ†‚‚‚ÛgÏŸ?Q£FÁ××zzzHKKkT&22}ûö…¯¯/¬­­å¾µ5PYYùÚ2iii(..n]ºµ®óºk¨b¬Q;wîÄÚµkñõ×_7Jøjßîß¿?*++éq€L]¼™2ÌápÀápO[Ú:::`0 ( l6\.ñññpssEQÐÑÑD"‹ÅƒÁ€H$‡ÃD"¡W ´µµ‘——SSS˜ššÒ‘•^-£¥¥ƒŠ¢Àb± •Jéÿ7ÄÇÇG΋¢(/÷òÈ6› Š¢ ‘H@Q(Š‚X,¦ŸU$Ñ ˆlV°¡<^-#“‡&2lØ0ôë×sæÌÇkV¾ Bë#‹±{÷n”••ÁÆÆsæÌ¡=þK–,••<ˆ¢¢"ôìÙ‹/†D"ÁáÇQPP€9sæ@WW¶¶¶¸zõ*¼¼¼ðøñc:tÀËüŽ:::(..ǃ‘‘¾øâ TTT`×®]@¯B§§§cĈHNNV8WWWG÷ÅuëÖÃá 44ǧËÈrÀ:”vŸEjj*0}út\¾|wïÞEuu5>ÿüstíÚ;vì@YYú÷ï?ü|üñǰ´´ÄP\\Œ^½zaÑ¢Ej’öj²Žì.ÚÞ(,,ļŒl¬¯¯çÏŸƒÇãÁÐÐ_~ù%*++±sçN€——lllPYY .—‹o¿ýðòò‚X,Ftt4Ƈ«W¯"..ðÃ?®_¿Ž„„8;;ÃÛÛÑÑѸ~ý:À××YYY°··‡¾¾>nÞ¼ [[[5ªwjj*þý÷_zLÉÉÉÁÉ“'¼ "! ‘ŸŸøøxzLyðàNœ8KKKH$àÎ;HHH€™™>ýôS¼xñ{öì¡Ç{{{œ>}wïÞmrLquuÕÈwûþûïÓ¹ CBBP\\¬TÞWBÛøÎÊ ¤§§Ã‚ÞÈåråÊhkk#''ÀËDç2ÝõU=—Á`€ÉdB(B*•‚ÉdB[[ñññ3f $ §º®®‰„.#»¹ÿ¿J||<ÆŽ ±X .— 6›úúz:冷®.­£Ê®ñªî*Óë'L˜@ë·²gØ´iÖ­[פ¾/Ë (Ó÷Û’g‡‡´´´ÀãñÀãñ^Æ6PõMd†‹ì忪q80™L0 H¥RЈP®ŠGrr2mÈ­]»±±±Ø¹s' DGGÓ ~ÕªUHIIÁŽ;À`0ЧO…B >ýúõÃæÍ›Áãñ°wï^ÔÖÖzôè=z}úôH$ÂüùóN¯˜˜˜ÀÎΘ8q"’’’PVVöV›¾Ïœ9ƒ¼¼ ÀâÅ‹ØØXbÙ²eèÑ£x<&NœˆŠŠ ØÚÚ"..^^^8räíÞxóæMèèèàþýûð÷÷G^^Nœ8¼¼<|ÿý÷^&9vpp@LL FŒk×®)Ü{¼\ºtémñxáàÁƒ8zô( éë,_¾E!((ÙÙÙ8wîýIII¸sçìííñÑG¡  EEE-º÷ÇÕÕqqq0`€Ü^·ÀÍÍ «ø¶6îîŒÄ°aÃäܯ]»Š¢àé鉱cÇ"""îîîJ¥ëžxàÀÚÀ‰‰¾¾>rss±gÏÒPÖt¶nÝJëP²#tîÜuuuX¹r%þþûoÚ ìÙ³'˜L&<ˆîÝ»£¾¾ü1öï߇°°0¡sçÎ ¤Ä9sæ   þù'X,ŒŒŒ0yòd=z”6:§NгgÏbݺu`2™ðóóÆ Õ¹ºº[¶l¡õ»5kÖàÆ¸uë(Š‚««+®\¹]]]p8…Büøãðó󃎎D"$ """póæMZßÿæ›o°ÿ~ܼy»víÂÊ•+‘žžŽÈÈH0™LÔÕÕá‹/¾ÀG}0™LôêÕ ~ø¡F¼KÙÂOÃö'‰À`0Àf³1bĈFz±ÊµdüôÓO`0r¹ G}ûöÁÑÑ .ÄÏ?ÿ ƒ¡±û¹âââðÃ?È­Â9k×®¥¼Î;£¬¬ ºººHMMEmm-œœœäÊôí۷ѵ9=1jÔ(¤¥¥á“O>Á°aÆÂÂBDEE¡OŸ>^º”.]º7n„§§'BCCvEÈ>h gå7mÚDçÄÒÖÖ¦ÓŒÈÊ…Bðù|H¥RÄÆÆbܸqtGŒ‹6›MkêŠøä“O°iÓ&P%—koÁ‚˜;w.f̘ .ÐîêÈá¦I|ðÁFRR>ûì3ú¸žžmÜ{{{ãòåËø÷ß±jÕ*ª¿~ýÀ`0`ccƒ®]»ÊýíäÉ“ôjÂüùóaee¥p³l x$aÛ¶m}}}xzzbÔ¨Qr嫪ªè2fffÐÕÕ…ƒƒÂÃÃq÷î]z½!#GŽ|ãóp¹\ðx<°X,:òWÃû¿÷Þ{rFÖíÛ·qéÒ%0™L¤¦¦ÂÉÉ >>>t»wsç" ÑÑÑ‹ÅX¸pa‹¾— &àêÕ«ÀêÕ«éã:::´!ãææ†?þøÀËH«™±·{÷nÚP’Ųmý®®®ˆÇ¶mÛ°zõê61ÙÕÕyyyÚ~MM Ý>eýVQè´ÒÍb±0zôhú¼!C†(ìW)))t™Q£FÁÑÑáááo4Añ* ï¿oß>TUUA*•Ònp û¢ŒnݺÑ+e ¯sòäI€¢(dgg£_¿~¸sç¶mÛ©TЉ'båÊ•tÙl6ÜÝÝ[ý]ÉöÛoÛ¶ Ë—/§£.s¹\Ú[¡ÿþ8räž={kkëí]óÁ`ÿþý†  î]»páÂŒ7àñx°¶¶nñqW•9qÿþýøê«¯`ii‰£G¢²²QQQppp uäQ£Faùòå°³³ÃùóçñìÙ3…ú®D"H$B=гgOôèу÷x<Š‹‹‘••[[[<þ÷ï߇‚‚‚`ooßdªÚs@Vw@>Ÿºº:ܼy§‘~+3eÇ´µµiOºáÇCKK _}õÊËËér·o߯âÅ‹aaaÇ£ªª ƒ¦'v4Éëå믿†ŸŸ$‰œ~²nÝ:XXXÀ××111ˆŒŒ¤ßQ‹„Th¬Èf÷ OŸ>omШs6H$A*•"..N¡rÇd2ñõ×_ÃÔÔL&, )))(--…¡¡!½\.‘H––†’’@ß¾}é¼&~~~ Ykkkº¡Ë¬ø‰'bÓ¦Mr.gŠ>¦‰b±l6›žñh8«Âb±@¯nÆÆÆÒûU„B!RSS±nÝ:DDD !!b±˜îTüñÆŒƒaÆÁÍÍž™mœ” ±´´TxßÀÀ@úÿ3fÌÀŒ3ȲÄ+òhÈ”)Sä~kRÈq{{{œa‘H„˜˜Z_þî»ïÀb±°cÇŒ5ŠžH’•“éò²o¯ÌH,))±±±F¹‹êéé) Töûï¿Óÿ3fL£Ô6-’v¢½àçç©TŠ#F`ܸqˆŽŽ¦ ÙÿÿüóOðù|899Ñûnß¾ªª*¬\¹FFFسg,,,––‡ììl:pÅÒ¥KQSS]]]tëÖ yyyôŒÊñãǼ\í’%á~µŠ8{ö,îܹ|þùçr{¦L™‚ÁƒÓ×ýËãñ0räH$&&büøñpqq¡Ýîd3—£GÆæÍ›AQFމ±cÇ">>žÞ°úí·ßvè¨ÍçÉ“'¨­­Eß¾}ñóÏ?kČǣîM›6)œ(“¹‰홈ˆ¸¹¹¡®®;vìh“ (//'9ûmž¤¤$:ÀН¯/rrrзo_ -- ={öÄãÇqþüyÀŠ+ðüùs¼xñQQQ°µµ…rrrˆnݺaÀ€puuE@@ гgO,\¸P¡.ˆœœ˜™™aÙ²e€/^àÙ³g´ kC¢££QSSƒ””Lœ8C‡ÅÕ«WqóæM¸»»ƒÃá ¾¾¾Ñ½¢££Ñ£GƒÁ`ÀÍÍ ¿þú+Äb1\\\èÉZ™L¾þúkèêêbÛ¶m¨©©ÁàÁƒ1eÊðx¾lv£~¸yóf„……ƒ@h!àää„äää&ËH$°X,ZÇ}uadÏž=xöìý;//•••t~>¡Ý„Gé‹ÚÙÙ5R,ÏŸ?©TJ$N ´ §OŸ†³³3zöì‰Þ½{#//zzzèÚµ+]†ÉdBWWWî<ÙÇ@ 4Ÿ°°0tíÚpttDjj*---¹r û!‡ÃÉE ´ ÒËf7ëü+VÈý¾|ù2¶oßNKh¿á®]» ¡Pˆ#F`̘1kkkÄÅÅÁÌÌ 'NÄÖ­[!‹ñÙgŸi­ÄÁƒ‘ŸŸ¸ÿ>>úè#@ii)êêê ,ÀñãÇQ[[‹O?ý”@P1gΜAZZ$ þúë/øúú*** ¯¯˜:u*þûï?„††bõêÕDh‚IMMEdd$âããñ×_aùòåÐÕÕE@@áïï¹sçbÿþý¨¯¯‡¥¥%lllˆàíž&ÓWUUÑ3•\.:::ôq0 @uu5X,V£™Î†8::âСCprr"R'4ŒE‹ÁÃË/& ÔÇEQظq#ÐÔÕÕA(Ò¿ Á`0P__‰DBëº"‘|>`2›Ž¿([! %Â%´iš\!444|«ãDŠ Fÿµ[çšú6¿úŽMMM€þž«šçÏŸcÑ¢E8vì˜Â¿3[[ˆ™™™xï½÷”>ßÐж¶¶ppp C B‡åþýûàóù4hF×sÍš5oÜcNh?Æ ±±1FŽÙÈíSèêê¢K—.X±bªªªG„Nи\n³"ôËâqX[[cÒ¤I8pઆƒS¦LÁœ9sèmsmá×¥K49éÛꡇ‡‡J¬_sss“–I :$ÿþû/|||šF½¥ÑÓÓ#/«PQQìììFîž-®®.&L˜€¸¸8ÔÔÔáÔJ÷îÝñøñc•^ÓÊÊ ………D¸Ɖ'0fÌtëÖ­ÍÕÁ`¼ÖpmuƒP[[»Y3(2,,,ˆAH :$ÁÁÁxÿý÷5Þ$töíÛ‡åË—·ê=?ûì3:tõõõäÔÆÀqõêUXZZªôº³gÏÆÉ“'‰€5ˆÀÚÚº]>³-W~Ú´i8þù¤Ý´jÓ¡……ŠŠŠH+%²:HÐ4bcc1räHµÜ[__ @rr2yµ…””•_—Åb¡OŸ>ÈÉÉ!BV3ÙÙÙÐ××Wù*°&ѢţG (++S:ÕDS}„‚ò¼xñ»ví¤¥¥ÁÃÃ¥ ••…)S¦A´¤R)~úé'@dd$ÜÝÝÛTýËËË‘››«0:hkáéé‰_~ùC‡U˜cŽ@P5.\@YYÒÓÓ! 1xð๛›®\¹"t5rùòe|üñÇíú[Ô ìܹ3ÜÜܼœÅ³··Ç¸qãTzÞ½{ãáÇèÝ»7i±Â;öOÈËË#iÈVU±› 0™LºòxôõõÑ¥K" ‚FŽaÆÁÀÀ@#ëçåå{{ûÉ G ¨OOO„……A´‡†ÆŽqmÞ Ü³gO‹\—Ëåb„ øï¿ÿH+&íÊŒÅüùó‰0AEE222è”Rš¬@WVV"11‘¼4B›§sçÎ())!‚hîß¿‡ƒž={v¨çnUƒÐÖÖl‘k[YY¡°°´dÐn¸pá&NœHò4‚òòrœ={¶Í$höööFii)1 m‡ƒ3f 00£…Á›7obÞ¼yîÙ[Õ 444TyBfffàr¹Äu”@ ´yòóóqøðahiiÁÔÔ”„ Æà¹sç0sæÌ6dAfîܹ©©©äEÚ,666¨¯¯G~~>F ðàÁœ:u 3fÌ‹ÅêpÏÏnO³páBlÙ²?üðiÙ¡M‚ׯ_ƒÁ€‡‡G‡sY!h¦!xõêUaÉ’%m2—Ì(Œ‰‰ALL FGGGòr m ‡ƒ÷߇†¯¯/ˆŠ¸ÿ>"##¡¥¥…Å‹CGG§CÊ¡]„\.Ó§O‡ŸŸ\\\0nÜ8ÒÒ „·$==—.]"‚PÅÅÅ(((@¯^½ˆ!HÀåË—AQ”ÚëQ]]ââbxyyaöìÙmZ¦¦¦¦˜6mmž?0hР«¾sss899AhFFF˜2e ~þùg¸¸¸ÀÓÓ“¥cìÍ›7amm‰'ÂÊʪCˤE ¢¢"¤¥¥5ú°´Dß¾} Òê;8~~~db %%%ð÷÷—;–––###hii·*5àèè777ôìÙ“ƒ±XŒM›6É‹ŒŒ¤•M [·nðññiWnMMMáìì ---ÀñãÇI"{Œ9’„ ˆ•ÓgoݺÕêuèׯ¾ÿþ{ÄÄÄ=WI¶oßذa HK„\.·‘[Ikùã …B\»v øë¯¿ÈîàØØØ!4 K—.àñxrÇòòòàááÅ‹©¢¢"äçç#==QQQpwwÇ€ˆ`ÚóÇ—ÍnÔy<(ŠÂÆ5¢ŽUUUÈÊÊÂÅ‹1`À >¼MËüƈE§N`ooØ¿‹Å6 ´? Àdþ_ø u´‘H„°°0¤¤¤=WI._¾ àeÔä>}ú _¿~ä›Ô555…«««Ü±Öê4‡†³³3¦L™BZ<@hXXXÀ®®®(..FTT¢¢¢°dÉz%ƒ@hm áêê ;;;ܸqW®\Á„ ÚÜs<}ú033êU« ­­M^.A)d 2***Zõþõõõ8~ü8ììì°~ýzòB”Df£ÄÇÇ#11QQQèÕ«ÆŽÛ!Êí$1½Œ””XZZbèС¤µ„6‰¹¹9fÏžéÓ§cóæÍ¨««#B!¨x{{ÃÐÐW®\isÆ`XX† †ñãÇc r†Þj©M²²²h·g‚j à `âĉÐÖÖÆáÇ;¬,ÚA(põêUL›6´pÐ. Cooo9r„ƒ 1ÊS[2 ‹ŠŠpõêUÌ™3‡l ´ÆÆÆ­²RXVV†èèh¢ç¶VVV5jôõõqïÞ=b¶enß¾MÂH„v…‹‹ ºvíŠôôt" ‚Æ…999ˆ¥¨¨W®\Áܹs‰Û5¡]"ˆdîܹHIIéFa»1ÛêÞ@x|ðBBBˆë(Ac˜0aBCC5¶~.\Àþýû1eÊb Ú¥¥¥ …èÖ­F+….\hµìÄ T!OŸ>%„@ ´[ìíí¥ò!Ô… ºvíŠØØX«[QQRRR0{öltîÜ™¼,B»   €¤$jEfÏž³gÏB,ƒ°¥>"999*¿.ŸÏ'‰e B»eòäÉ'«„¡W¯^ÈÏÏ׸zÃËË ýû÷'/‰Ðn8þ<Ù;ØŠtïÞºººÈÎÎ&aK`hhˆªª*•_7<<¤„v Y%$hýúõCii)ÊÊÊ4ª^2dyA„vC}}=8D+ãããƒsçÎA$ƒ°­PTTD\F B»†¬4 ooo\ºtIcêsáÂL˜0\.—¼B»¡¤¤]»v%‚P¶¶¶&ÀL›7 ‰1H :VVVxòä A#èÛ·/JKKQ^^®öº<þÏž=àAƒÈ‹!´+BCCIÐD5Ñ‘V Û¼AX[[ ===Òj „wD("%%)))çöEPÌØ±cAÑŽ (Šî‡EEEm®þ“'OÆÅ‹Õ^'NÀÇLJ¬ÔFKõßÇ£GDÀjÂÖÖ¶EâŸhì–¼ø;w(..n‘{DEEaÒ¤I¤ÅïˆX,¦W›ø|>HÀÊÊ ‰„DVngÈúaUUÌÍÍÛTÝûöí‹‹/¢¢¢ÆÆÆj©CII ¸\.ŒŒŒHc"´ ûöíCQQrssåŽñx<•ÞçÅ‹$Z®šñññÁ¦M›`ccÓ®÷r¶è áÀÁãñÀãñZä#WWW‡/^ÀÊÊŠ´XáÑ××ÇÔ©S1uêTÒ‡Úš¶o‹Ð< ÝmmmÛä3xyyáØ±cj»@@.\H¡ÕX¾|9x<,XТ÷),,„¥¥%¸šé«„jq}öì™J®“ŸŸ^½z‘–J : Ý»w‡T*ÅÓ§O‰0•• Óê÷¾páÜÝÝahhH^¡ÝŒ3fA¨·ë½„j1÷ìÙ£’ëÄÄÄ`Ô¨Q¤¥„ŤI“pùòe"‚F`hhˆ™3g"11±Uï[ZZŠÂÂB888—@P;555*Ý~QRRBÜE5ˆöq´Õ Â’’•\§®®Ïž=C÷îÝI+%ŠîÝ»C__wïÞ% h°··oµUÂÒÒRbéÒ¥$GAí¤¥¥ÏçãÖ­[*»&I©¦Yøøø 55 ÂÕ .\ˆÿý÷eFGG###ƒ„¯’™™ ”––*}¢¢"ܺu ®®®¤u„ËÞ½{±}ûv$%%¡®®îµãj~~>=zôFe[•H¥R¤¦¦âÂ… äeu 0gÎÄÄÄàÊ•+¨ªª¢•åÊÊÊ·ºÆ‹/¥Á)--ENNmöîÝ_žžé¡ IDAT~ù%1 ÇÛŒ³oc ž>}sçÎ%Õ@æÍ›‡€€dgg¿õ9B¡µµµj­·P(D@@@“oõÑô‹/¾ð2Ìöýû÷ßùü¨¨(ˆÅbLš4‰äe!Ä(Ü»!!!غu+ôõõ¡««‹1cÆ4* àeš€W•襤$XZZÂÞÞ;v쀉‰‰Êê&‰`nnÞ&óë”7 -Z„¸¸8üðÃFåÓÓÓaooH$ ƒD"‘KvobbSSSØÙÙ‘dæÌ™¨©©ARR(Š’gß–ªª*äççãîÝ»˜;w.úôéC«ôéÓ³fÍ•+W˜˜ˆ‘#G"==#GއÃQø MOOð2—pYYttteee011@ €‰‰ ¶oßGGÇq‡ŽŽBBB0yòäFgPEµ†±qãF:*hZZšR×qww'†  b-Z,^¼˜£óäÉ…ÉëÍÍÍAQ”\”ç.]º`èСxúô)ÒÒÒ0vìX’‚DðxôJn[ǃ€šÒN„æ# QWW÷Ú2%%%ï¼ù™@ ¼=b±ø{CÊËËñäÉ",@ h$¯5ƒ‚‚^&µ¶¶üñNœ8±XL¤I ´¢1¸~ýz$%%5YæîÝ» ĹsçpóæM"4¡ŒÁ={öàÌ™3M–)..F@@BCCqåÊ"4AÍÔÔÔ 88øµenܸ×¢s M¢I—ÑÐÐPÂÓÓ“ÞüØÝ»wcÅŠ(**©S§0þ|"Q¡ ‚££ãkËœ:u <À˽IÎÎδÛpƒ@ @yyy‹ø­FFFÐ××owÏ›×îÚ»w¯\?œ0a€¢(<}úT®luu5(Š"ý vtttT`J“ŒÁ#GŽ °°°ÉEñññàóùàñxØ»w/¦OŸsssÒ(íß ¬©©Auu5}ÐÜÜ]ºtiÒß_Fmm-ôõõѯ_?œ8q‚>ž™™Ù(÷Tqq16oÞŒÎ;©ZO?ýC† iÓÏ“'OÒ¿—-[† àÚµkJ]¯ºº!!!rÇŠŠŠðûï¿ã÷ßWêzJÕ…ÏçC[[Læ»{¯ …B°X,¥’R‹D"H$hkk+-CeŸ¹¦¦zzz`0ï|®@ ‡ÃQ*Ü~]] ¸\î;Ÿ+‹!‰šœ|EÁ××kÖ¬iÓýðÙ³gسgý{Ö¬Y˜6m|ãÇW:÷µk× ­­Q£F)-§æô Uœ¯ uhîù•••8|ø0|}}Õú í‹/Ò[šìíí1bĈf]oÅŠr¿/_¾ŒîÝ»Óô•5Z ›¥«Ô××#22^^^Í–Wst>ÈÊÊ‚žž^³dRTT„§OŸ6[&QQQðôôlÖóDGGÃÑѱY,™™™Ð××o¶LŠŠŠ”Òy^•IzzzÓá!C ýÅ‹¨­­Å‹/Àb±hwŸµk×bݺu044„……òòòPXXøÆNÖ«W/|öÙgJ=À­[·PXX¨´òV\\¬ô½ ¢¢K—.Ujv\÷oÎùùùùˆŒŒÄG}¤–º³X,x{{ÃÒÒ²Õ™ùN‰CÛD||<Øl6îß¿O¿ßeË–á‹/¾€»»;–.]Š­[·B*•bÁ‚-V]]]µÈ€Ëåª-1µºž¹9«?ÍÅb)½šÚž9sæ bbbP\\ŒÒÒRZ߸q#ìíí±xñb|õÕWؾ};„Ba‹çÐSvµ½=ô Mª‘æ°téR¹ß555¨­­EII LMMÁd2‡¼¼<,X°Ã‡Grr2 QQQ33³×ÞcÆŒ>|¸Òu¼sç2220{öl¥¯Áçó! ›¥¯©Bç€K—.ÁÔÔ´Ù2ÉÌÌT˜»ôm©­­U‰L¤R)fΜùÆvð&™tîܙ޺£¬¡••Õl™ìÞ½[áߚԦΞ= „††ÂÞÞ£GØÚÚÒJØòåËñ÷ßÃÊʪٳ¯£Gjõe÷òòRzuPx{{wÈ{kÂý5ù#×ðC@ÎU»k×®øá‡Z¼.êrœ8q¢Ú䯮gn· 9X[[+µ*ÙÞ™9s&fΜÙèøÖ­[匴µk×¶J}æÍ›§v™h‚k°ºë@d ¹äææâÆèÕ«±dÉèêêÂØØ˜Nnkk  Äüùó•öpz[ÌÍÍ›å¦Ýu.M’‰››[³ÝØU………RžEoK“aCWü±ÜïÖHdÝ¥KtéÒEm/¡9˳ª 93 mùÞšpÿŽ‚ºV´´´”vkÊî=l˲æp8jY]d0duñ-QÖ Ee ›­¶Uwu÷MªƒÁhQů­¼‡–ÀÞÞ^áö£bàÀôo[[[Ú0liLLL4&€¦è\š$“†[àÚ«L”l·m “ ô¶|ouß¿ªª Ož<‘èZ“ÌÌLôêÕK-KKKQVV†~ýúMójkk!•J_;ãÅçó!‹ahhHFx+êëëadd¤ðïB¡B¡þÝÒ³îm]^ÀË /FFFj™8!´oêëëÁçóahh¨ÐÕX$ÉåØ400Pˤ’&“ŸŸmmmµG!‹ÅHKKÓˆ˜ š"‘H„ôôt"“·”‰Ê B‘H„Ý»w£K—.˜3gŽÂAF,ãСCàr¹X´h`J#‘HpìØ1,[¶LáìöñãÇqÿþ}/ª|õÕWV^?Æ¿ÿþ ‹…1cÆ(JJJpøðap88;;7+À¡cPZZŠƒ‚Ãá`èСpsskTæÇ¤g7 V­ZÕaåUSSƒ]»vAKK ƒ ÂøñãƒÛ·o‡ÃA¿~ý0yòdbTª«íÛ·"‘VVV˜9sf#}íܹsˆ¥])çÎÛ¡Ó/¤¦¦âüùóX²d zöì©°Œ,*øÜ¹s[m…‘@xŠ¢ŒÜÜ\øúú*t½ ¡ƒ‰2 lذ*ß}¾{÷n,Z´C‡m2dñ¡C‡0uêTŒ7*†P(„H$ÒØ—U__¯’2 ‘J¥t4-UÔ±¦¦Fãþ±cÇ0fÌ̘1PXæþýûøî»ïðÍ7ßàþç:ô@qèÐ!¬Y³«W¯Æ… –ñ÷÷ÇÚµkñõ×_+ÚBÆ7š}–äm…+“L\"‘¨ì¹Ý?##£QjŸW¹{÷. ZMŽ;wî¤ÛÌõë×–a2™èß¿?*++Õæ± )lÙ²ß}÷|}}£°ÌÖ­[±jÕ*øúúâîÝ»r+5ªbß¾}›óP*•",,¬Eúgjj*ž?Þì:>zô¨ÙË”©¿*8~ü8Þÿ}øúú¢¾¾Ÿ>ŸŠ¢ ‹éQ²ÿ‹ÅâFedy¹êêê茬ŒT*¥'‚d‘Öš¢®®N®L||<}LöA’ýt™kÕ«u”=ì£,«,Çabb"}L†ì·ìãñêÄUS“Xñññ´< oß¾xÿý÷å>º|>uuu‰DtôçWŸU$Ñ2’} ÊL*•Òu”•i(e?~<:uꇸ¸8Ò94@Q[¸p!,,,èß²þùj›iØ>ö!‘HD·›¦úЫýãuŠß«}ˆ¢($$$¼±É’ˆ+Sdun8¦dgg£¤¤„î3ŠÆ‰DB-M)µEEExðàA“}H6vÉäÚPñññ (JnlT4¦4?›’‡*yï½÷`hhSSSܺu«Ãö—ÜÜ\ØØØx°M‘¾ñèÑ#:åK=ðøñ㯗H$¡C‡4Vnˆm™””\¾|¹Eté·aëÖ­¯Õš[—«W¯¶ªÌÓÓÓáàà&¿Û [¶lÁÞ½{霜ìöÖi+++‡É“'x隃„„hkkã›o¾ADD—$,, žžž¸rå Ýhׯ_ØØX 6 [¶l³³3&Nœˆ¨¨(DDDV¯^ lݺƒÆ´iÓ¹ôH$ìÚµ åååèß¿?fÏž ‰D”””à“O>A·nÝpðàA¡W¯^X´h$ :„ÇcÞ¼yÐÒÒB]]lllè:?~ü˜>øà°ÙlƒÇã¡S§NX¹r%ÊÊÊàïï˜4iˆ¬¬,¸¸¸€Ïç#55•NÀú*£G–Û÷(‹±iÓ&€««+&L˜@×C&GYã‹…££#¦NŠ””z%jåÊ•èÔ©vîÜ‰ŠŠ 0~ø!ÒÓÓ àeôL+++•¶‰WgHÚKn%ea2™H$`2™rmU$Éd‚ÅbÅbÑešËž={P^^N·É“'ÃÃà ýû÷Gqq1¦L™‚nݺáÈ‘#ðööÆ©S§h¥±wïÞ°³³Ã?ÿü===ˆÅb,]ºgÏž¥gE»wï'''œ9sl6"‘óæÍCïÞ½åêRPP€cÇŽÃá@*•bÆŒ(..ÆŸþ ‹Ì™3{÷î…––¤R)<==QQQ-[¶€ÍfƒÉdbáÂ…8sæ >ÿüslÞ¼<—.]BVV­ÊVÊdkÁd2i…J à‡~ Ï‹Åøõ×_ñã?*üXîØ± }úôÁ¬Y³püøqddd`ÇŽ€½{÷¢¶¶õõõ°±±žžþþûoôéÓ"‘óçÏdž п°X,˜˜˜`éÒ¥¸pá>|±XŒ3fàÖ­[xúô)ÀÈÈ3fÌÀþýûÁårAQ&Nœ‡Fud±X‹ÅÜÿE" Øl6\]]Õ°DS`³Ù‹Åä!k÷²à.b±˜v÷Qµ»èDZyóf|þùç6lÂÃÃqúôiôë×"‘sçÎÅñãDZ~ýz/óg.Y²ÿý7¸\.Äb1¦M›†ììl¤¥¥A__ÚÚÚ˜7oöìÙ---P///<|øvÛg0øöÛoÕçÒ¥KÈÌ̤¿›kÖ¬ADD\eðàÁ`³ÙHNN¦ûÐ÷ßøøxìܹ“Sžøà9}î³Ï>Sè>|çÎø¿ “999¸víºwïŽ%K– ??Ÿö”¥Úxüø1x<ºté‚Ï>û ׯ_‡§§'JJJPXXœ9s™™™000ÀªU«@QÎ;‡Û·oÃËË ®®®¸xñ"nݺ‡ƒµk×*Ô÷‰„„8;;ÃÛÛ  ÚK£ºº±±±°··§¿—/^ÄÀéI¤Ý»w£´´666˜3göïß“'O"..Ë–-ƒ……:„ÂÂBôèÑ}ôÂÂÂðôéS;?Ö]Pa‘y=Ož¸—[æž)÷œ™3çDF"&&Ó¦Mƒ®®.1èľöbNœ8aÆ¡sçÎxòä òòò””„~øàñxèÛ·/ºw3gâÎ; Czz:¾ýö[˜šš’²”––ÂÂÂ÷ïßÇÀñÿ÷¤<áááÐ××GRR¶oߎ¤¤$œ8qÏŸ?'©6lØ€nݺ‘w¿sçŽTykcãÆøõ×_Áb±àííþýûãþýûPVV†ƒƒîß¿tìØ<»wïÆ›7oЫW/¡ÉÛÛ;wÆÐ¡CÑ¡C<}úùùù¸páyˆˆˆ2»té‚ÄÄD¨¨¨H$c>zô(yöÝ»wɇ¼µïÁ™?>6n܆a$RÌ›7ýû÷Ç´iÓ°xñbx{{C(⫯¾jÐó–-[&a„;99‘üâÄÉ<k×®Eff&Úµk‡   ôîÝŠqãÆÃáà§Ÿ~ÂÓ§OI„Pñ,¹³³3âãã‘’’¼xñR¡8ÉmÍt†††¤íñx<äççãÑ£G°¶¶Faa!¡­­MúPm \.—”ÇÝÝàááAB¿óx|(Ó ŒŒŒ”hÓB¡îîî}HQQàp8ˆˆˆŸÏ‡£££Dÿ000º·¢¢"Š‹‹...¸}û6æÏŸ.]ºàìÙ³ÈÉÉAPP,--ɸ³{÷n¬[·ööö •P j2iÒ$ :>DRR´´´HŠŒŒÄ Aƒàåå…I“&!%%÷îÝ#®‡bè÷ÿÝwß¡  ‡‚ ¹OHHV­Z‡CŽõë׬ €ƒƒÃGENž>}:vìØÜÜ\ØØØÀÜÜ@µ»Ù¹sçpüøq$''ãĉ`l6sæÌiµ}¶{÷îxôè:w¬,2aþôéS„††bÖ¬Y077GPPììì’’B¾Ÿ’!C† <<œü ÂðáÃÉ·uÀ€ Å€EEElÙ²ßÿ=TUU±mÛ68;;#11‘蛿ýöŒ1vìX!!!ÅÅŸpá™ òööƺuë¤ÊsúôiÒ¶ÅîðÙÙÙàñx B`` ±zõj¢[~ùå—xùò%~ÿýw<~üþþþxüø1ˆüü|$$$@SSo߾ŪU«PRR‚¸¸8¼}û:tÀ¨Q£ÀãñеkW<þ«V­Bii)þþûoØÚÚ"((... «Õ TPPǃ¯¯/\]]Ñ·o_¢‡x{{ÃÈȺººàñx8pàÒÒÒpùòeðx<ÄÇÇ#$$ç΃››ºt邤¤$äææbÞ¼yd¡F¼ZØ­[7Ì™3ÆéÓ§±víZtèÐÔ[Cppp@XXºví*<ðÊ•+ÐÔÔ„««+¤òÇ7úWyþüùسg àååEŽ«©©‘EÍYƦțônP WWWüùçŸxûö-<<pŽŽŽ2Wgþùgp8²»dÉðx<°Ù슺)$䪯¯XXX gÏž2÷·¤¦¦"99_|ñX,"""жm[Lž<[¶lèêêJ¼Ç÷ß/¿üVVVD9œ2eŠÔ½ÕÔÔd¶™ßÿüÛÍÍ nnntJÿŠX±ªÉ»ÇÄü§@<£]ÓÅò]œ‰Ò÷믿"** “&MÂ!CHÿ¯ê‰¿µyyy1bºwïŽW¯^áèÑ£ÐÖÖ&ïRÛ8Àf³‰kdpp0ú÷ï/sUë§Ÿ~‚’’éCaaa(--…²²2Øl6Øl6"##‰heeE\×½½½eND[YY‘‰ñøáää„ 6ÔªDÕ.q €P(‹Å¾}û°zõjäää`áÂ…u¾kII Yñ Àœ9sÈJûŸþ‰Õ«WƒÏçÅÚÅÅ…LnnܸnnnXµjØl6|}}áææöQ©K,X ulìØ±d»ˆ……E­†pk£k×®`±XðõõÅ7ß|C’”+((°C‡äœ)S¦ÔxæS"öƨ‰§§'nß¾ððpüüóψŒŒÄ¶mÛˆŽ$n3â|ãk×®…H$ÂÎ;QRR@€~ø‰‰‰D—Kuáè舀€r_1ä>:u’©;Ö§€jo¡ØØXøúú‚a <êêêú§¸‰Ý?===akk TVVÝ^ï>ÿ?þ€H$"§²l 1–––ÐÑÑÁ˜1c°wï^\¾|B¡Pj¥¶½”ⅲƜ$¸~ý::„eË–IL\‹=N\]]±yóf ãÛ'™¦;w®Ô±o¾ùFâ÷§Ê_XTT„-[¶ 99½{÷†©©©„ë‹Å‚’’ìììðßÿaÕªU …pqq!>øâÆûîjRpp09GQQ¸|ù2ªªª`kk+3µB¯^½pìØ1r¿ï¿ÿ^â¾b1** UUU033ƒ‰‰ ÒÒÒ°~ýz0 ƒ:à‹/¾Àþýû†””Õ;Äåáp8`±XR÷öððÀÇÉÇ]<³èëë[gÒÛ·o#((ë֭ï¿þ www¢°Ùl(((@II 666صkœ‘___òaVWW‡ÃAUUùPÇÇÇ“Íü, l6[B®õY9»Ô¤¦á§««Û$ Ú)ÒŽîF IDATüùçŸàr¹ „§§'™€¯ Õ9OƒƒƒÉjõèÑ£É@õÝwßAGGGâ:ñ*>çÛo¿…‘‘<ˆÀÀ@tèÐA¦Ñboo“'ObóæÍ044Ä7ß|#U $$$`óæÍÐÖÖÆ÷ß///dggcóæÍøê«¯```€N:aß¾}d–ØÙÙ™”gðàÁ$ŠkÍ{÷ë×ÞÞÞ`ŽŽŽäÙC‡•ú¨ÕD–Ìþý÷_p¹\øûû“‰7¤¤¤àĉ°³³#JŠ™™ѱcG„††âäÉ“˜1c:tè€'N`óæÍèׯ ¡¡¡AÞcâĉÐ××GHH._¾ |÷Ýw´Q&$%%c®}ûö077'Ê‚XIªs‹ µ>}úàÔ©Sؼy3Ú¶m‹Ù³g£mÛ¶Fž®®.BBBpõêUhiiaÁ‚())!íjÈ!2£¯ZµŠœÓ¿°X,‰qÚ´iD"àéé‰Õ«WãŸþAee%V¬X.—‹¿ÿþ]ºt!“´zzzäÞ .Äëׯ¡§§GV~Ú´iƒ‰'’s¾þúkaàÀPVV®UY555ÅÈ‘#%Æ;;;lÞ¼zzzX¸p!ôôôˆ·T›6mлwo2Æ©««“P{{{lÞ¼\.Ë–-CUU6oÞ üòË/DÆâ2Š'öjŽ)ÍÇòs§K—.Rº„™™™„[mûöí›T߸~ý:‚‚‚°qãF¬^½ZJ26l€««+8\]]qãÆ TUUÁÁÁAf>à˜˜äåå‘û°X,¸¹¹‘cµG&&&d…«sçÎ044$÷ßÇÝݸ;;;£¸¸gÏžEtt4X,&L˜†aÀãñPPP{{{âÑ£GdòJAAAê]UTTзo_TUUAII öööÄØ #“²&h|||ˆž*Öa+**ȱšúµøÿmÚ´Ç‹ÅBaa!ž­@ Õ+}ýû÷ÇÓ§OI“&}¶ï*/ßfj¶ Ž=ŠäädLž¥u„‘‘‘øå—_H>YlÛ¶ ãÆCÛ¶mqéÒ%*M ¥ •PcccÔµxïÞ½X³f ~ùå?~œ Bid.^¼UUU’+Kþù'~þùgðx<\¹r… Bif|}}ëÔYãââðäÉ,Y²'Nœ ©(”Ï™Z“¾aРAu^œŸŸ€Çã‘$çOž<‘ÙÙ¦OŸN’yR(”ú3yòdÕyŽH$"98kŽ999عs§Ä¹W®\Á¢E‹0uêT*Ü& ""¶¶¶õÊ»I‘†ŠW¯^Õ¹R/ e&cذaƒÄ±û÷ïÃÍÍMfÒú¦dРAX»v­TBi ¥¥Ž9sæ`Ë–-µžóðáC8;;ƒËåBWW999ÐÕÕÒ ¬þùÓ¦Mƒšš444PRR‚´´4XYYI|èÞù¯TP(”†sâÄ AQQ™™™7nàË/¿ÄâÅ‹áááéÓ§cóæÍ`±Xðòò¢B“#ÊËËe®QZ×®]CHHRSSQUU…Ù³g.\ˆ^½zá믿ÆâÅ‹áããEEE¸»»Ëý;½zõ NNN ÂË—/±zõjZєϞ¸¸8¼~ýƒ ‚••aff†üü|´iÓ†œ÷nže.—K…'Çðù|ܽ{—„õ57n܈ÒÒRlÙ²:t( ##ƒ¬$üðÃؾ};LMMéì…Ò„Œ9Æ «îÄ5&_Nœ8eee@§N°`ÁˆD"¨««S¡ÉŠŠŠàóùØ»w/ºuë777*”†››œœœHNzþþûïÄà×ÖÖÆâÅ‹QUUMMM¹§¤¤$ :ÿþû/âããå&i2…Ò„‡‡ãúõ먨¨ÇÃòåË¡®®ŽÒÒR@¦OŸ>ˆŒŒÇÜ9s```@×BáóùtkFC ÂÚfûí7òo%%%,[¶ŒJ‘Bibj3ðÔÔÔ$~«ªªRaÉ)JJJðññÁܹsW«â;wî °°"‘ZZZàp8˜6mttt>IÙrssQXXsssZQuP[ÿ’µŠÐÒVÌÍͱfÍøøøHµËK—.!55•ünÓ¦ ÝLi888Èt}÷¸ììì¨À>”••QQQ¡Pˆ‘#GÂÎÎC† y¯ûpLL ***Ù³göú”\˜ÍçÎÃëׯÉoCCÃZq,((À±cÇTïyìÒ¥ mù ¥ÅеkWÀÃÃFa\\®_¿Ž/¾øS§N…¶¶6Øl61 :„²²2ØØØ`È!õÜÌÌLøùù¨ &Þ·¦ªªŠ²²2èêêB[[G%ÇÄ\.˜1c­ÀÏ;;;(((ÀÅÅ…´ËK—.A(B H€yyyøí·ß ££ƒAƒÁ¢ÉʹgÏðù|äååaˆD"tìØ)))hÛ¶-¬¬¬àááQëõ‘‘‘صk¼¼¼ðå—_ÒŠ§4*þþþHKK“86|øptìØñƒ®¿s硪ªŠ¯¿þš ´žðù|Œ5 ~~~PQQÁÊ•+ÉD€¬1%++ =zô€²²2¦NŠíÛ·£¼¼mÚ´A÷îÝëS>†ŒŒ œ?žüþòË/ƒØØXˆD"hkkCWWƒ ‰'ƒFçÎ]F,¦®¸õHïÞ½±ÿ~ØØØüüü––†ÂÂBxyyÁØØXBYñ÷÷G×®]k5 oܸÔÔTò÷»w²Ó¦M#ç¬]»FFFRn(Š$Ó§O‡§§'Uò›€ ##—Ë‹Å"  Ñc»u놡C‡Öéî[YY‰èèh\¿~ÊÊÊÐÒÒªõÜvíÚáÆ000€‘‘ÆŒÐÔÔ„’’ ¬¬Lj´æ±’’TVV¢¤¤‡hhh1.—K•–ÀãñÀ0 Ö­[×le¸{÷.Я_?¢H>|iii9r$²²²0pà@ÒfÄ…BàæÍ›ÈÊÊ‚¾¾¾Ä÷¸±@¡PˆœœÌ™3JJJÐÕÕ‹ÅÂï¿ÿ%%%Œ=êêêHHH@hh(4551uêTâ¶{üøq$''ÃÖÖ–––(((@zz:5 )ŵk×°uëV\¿~»pá^¼xÂÂB|õÕW055•¸æòåËHOOGçÎ1a„Z Á„„ôìÙVVVxûö-:///tïÞœ÷Ûo¿ASS‹-¢•!ƒû÷ïãíÛ·àóùpww—ø¾]»v )))ä\VV†ŠŠ ”””ÀÇÇGâÛ,&??qqq¸{÷.tuuÁáp0eÊ”:¿½bΞ=‹7oÞ¨^Ðâóù066–ˆñpñâEôìÙÖÖÖd8777oÞÄäÉ“‰ý#Î-­©©I¼OÜÝÝaiiÙ2 ÂyóæÁÆÆ{÷îÅ?üSSShkk×jÍ?yò~~~ÐÖÖ&û¢ °°nnn°±±!‚ …xñâüýý¡¢¢‚ââb8::";;VVVèÖ­í 5›M›6aéÒ¥cZcPYY‰¢¢¢Zÿ~úôi())áÛo¿mÔç–”” ¼¼PQQHŒã:::àr¹X°`­ühÖ‡ââb¼yóG…¦¦fƒÃþù à ;;0wî\p8èëëK)m»ví"ÁpÄÆ_EEŠ‹‹qôèQ¨NÝÓ©S'‰ýE;vìÀ„  ¯¯O#åƒ ÂåË—ãîÝ» C||<†ŽöíÛ×éÒ/ðüùsœ:u ZZZ.åEEEpvv†••IwT§’:þ<Ú·oÿþû%%%°±±A=pöìYºøQ˘ún4皈 4 ÚCF8óC2"äååA(JŒ+µQXX,Y² ££Ó (Õ5ÇZq¾ø€€$&&’¿ihhHÀJJJ˜>}:âããÑ«W/©{5©ËèåË—‘™™ cccX[[×y®¢¢"¬­­amm‚‚TVV’¿ikkKíÇàp8033ƒ™™ìíí¡¥¥dggÃÏÏ„ å³FYY¹ÎàVVVŸ$²©††444$>ÀbÄÆÍüùóiµ°bÅŠÝCSSšššàñx(**Bnn.il6ûƒ”­ÌÌLòïyóæ¨ÞNò>ºu놤¤$‰>â=œK—.­óÚ9sæ`ïÞ½())Á7ß|Cƒ‰P>ˆ„„¤¤¤ ""ëÖ­“Z=—…‚‚,--ÁãñPXXH”zD}6›Ñ£GãêÕ«=z4455¡ªª †a¤r#R>ŒwûxÏž=?hµ1Öß7®ÀÎ;Áår}Lµ¤V›‹‹‹Év¸}û6öíÛ333Ùm²©…ÿêÕ+8;;Ô58᫯¾’ø­¯¯ÜÜ\Úê)J«ÆÙÙY¦ ̧„ÅbaÙ²eRÁŽ(ò ŸÏÿ …öCÑÒÒ‚––1E"²²²ÞÛnŒŒŒêõ<77·:WÊß7©²`Á\½z/^¼ !å£ÛO}úNmžr²`³Ù1b„T™?>víÚEW ÈÀ?É};vì==½&}—慎>1bÙ–Òìall,™ík Øl6¦OŸŽƒbæÌ™´µS(”V«¬45W)6›-3àSÐÐ}€¦¦¦xöì2Iù`222Ю]»f{¾¾¾>]%”c<<<š=»ºº:®\¹RûØÜÔ211irÿ|]]]ºJH¡P( å½X[[#66– ‚òA¸¹¹a×®]°²²j¶2°X,tïÞ?¦ò?Üä är¹êyQß6RWº&—TÏž=?8Ünc¡¡¡ÒÒRÚ;(”‘pÇÉÉÉðôô¤B¡Pš‘H„ǨÎ{Õ£G* ¥ÁårßT¤)>|8þþûo:†üÊÊÊf7ÂZŸÔ LHHÀéÓ§YYY011i¶íÚµ+ž|8•:…B¡P(rF\\ºwïNA¡|$mÚ´¡B3ž>>´´@X,¾þúkìÛ·&&&­êÝ=z„Ù³gÓ† a\\Ξ=+q,++K.&‡ÃA¯^½°|ùrZû­€5kÖPƒPFÐÖÖ–8¦¤¤„)S¦`ذaT@Ÿ€¤¤$TTTPAP$x·r¹\0 ƒ¿þú«ÉËòäÉJ•©5“——‡ââblݺµÕ½{›6mhÁîÝ»‘M~?þ\.Ë)^% Lí>íÝ»7LLLpéÒ¥f}á„„ÄÅÅaüøñ´ö)”ÿ1}útxzzbÆŒTŸˆõë×cõêÕàp8T™ðx<0 ƒuëÖ5ù³oÞ¼ uuu899ÑŠø§OŸF÷îÝ›5öE¾¹ví† †ÐÐP8::ÊM¹öíÛ‡ÁƒÃÔÔ´UÕ‡@ @pp0Þ¼yƒ‰'Òú°[[C9wî5)J“3kÖ,Ÿ* 5) …B¡PBDDD«L7AiÙˆD"šÞ€ªª*ÊËËiƒWƒÐÂÂÏž=£R§P(­’É“'ãøñãT …B¡|"8„B!„¼„ššš(..¦R§P(­’Ž;"55• ‚B¡P(Jë4›“ââba”B¡P( …òYrêÔ)L˜0 €‘‘233© ¨A( ŸÏ‡’’­q …B¡PdЫW/DGGSAP(-”””˜™™QA˜:u*Ž9BA B …Bi¹äææ‚ÏçSAPš ===äååQA(--…šš…Bi|ÒØ´………d¿ öC¡ÈŸÁ±cÇ@LL <==©PšEEEðù|(**ÖyžŸŸFŽ ccc*´Ï‘H„õë×áææF…"ÄÅÅÑ4U”Zyúô)ÊÊÊœœLŽeffÂÈȨYÇ‹E+‡"aYY^¾| ¨ªªjÖ½rå †NkœBùzzzàñxªÝL(M›Í†H$¢‚ ö î‡<橤PZ™™™(,,Ä›7oȱ={ö¾ÜTUUAYY™VN=¹pᆠ.—Û:¿EŸòæÆÆÆ5jF---@vvv³¼hJJ :uêD[<…B¡P(rÊ©S§¨(rOÿþý1jÔ(8::ÊM™Þ¼y}}}Z9bç#'_Ÿ?Ž×¯_·^y5õwïÞ-1£ÒCSS“ö …Òb¸uë Zü{4õxOi¹ˆD"ÄÆÆâܹsÍÚæ>|Z!”¦´´@µg\sqàÀ|óÍ7´2þ‡ŠŠ ***>êš]»vµZy)4õ¹\.|}}ñûï¿7Ù3ýýýñå—_ÒÞA¡PZ Ý»wÇ™3gЭ[·ý;vìÀ¢E‹ ««K+µ•"ðüùs@EEüýýež' allŒ3gÎÀÒÒ’¯ùï÷QPP€mÛ¶aÆ õ*kjj*гgOZq”&44ƒƃàêêÚäϯ¬¬¤‘ôˆH$›Íþ¬ß¯   Öoq“„ÖÖÖðóóÃìٳѹsçF¿nn.ôôôÈ"äææÂÜÜœ¶v …Òjxw,l „B!Qüê=- Ã`ÿþýøñÇi¥´TTTPVVUUÕ݇ÏçãñãǸtéÈ÷žËå¾wŸÕ¼yópæÌò[ìFjeeww÷:ÝâNœ8¢¢"(((Hè5s’uêÔIJ~ðࢢ¢`ii kkkÚ(MYYY£ôŸÛÏŸ?///Z  ¼¼ü“Ö[s“––†Õ«WcÛ¶mhÓ¦Mó„êêê3f ž={öAaFF®^½ŠŒŒ rÌÅÅöööR‰æ³²²àëë 555899aРAÈÎÎFÛ¶miK§P(rA›6mŸŸ/3]Í ZZZ(**ú {¾|ùÉÉÉ&Çôôô››+qž ˜ššÖû²²²P\\L>¢çÏŸp8©É· &€ÃáЊo!ôíÛQQQèׯ9–žžŽ²²2´k×R3ÌUUU¨¬¬„††233qãÆ dddÀÚÚº^A6Øl¶ÌäÚñññ8uêrssaii‰Þ½{ÃÜÜ\bV_(ÂÐй¹¹044DJJ ž={†„„‰>wîÜ9xyy¡k×®ª]þ=z„qãÆÉT–(”º˜>}:Š‹‹€»wï~\ee%^¾|‰¼zõŠwtt„£££Ì­N¯^½ÂÅ‹‘››‹¾}ûbøðᨨ¨@jj*&NœH+¢p¹\”——CEE僯IMM•HuåÊ8;;C[[[â<555´k×î“•] H¬¬¬„ŸŸùýôéS8pÇŽÃìÙ³›× tww‡¡¡!òòòŽ={öÀÓÓíÚµ“þëׯQVV†»wï†.!Ä{÷îáäÉ“®]»†¨¨(¬]»–¶r …"Ì;<}úô­­-QR qüøq€kþüùøã?ðæÍÈ4“’’pïÞ=´oßfffïU¾³³³qûömTTT -- àáá!•ÚBl´¾Ëýû÷‘ššŠ¶mÛeEEE¥Y#ëQ>-Ïž=õk× §§‡ .€Åb¡wïÞ0`9'::;wî„»»;*++1xð`tìØ±ÑËÒ­[7âB€ÿþû'Ož„H$Âøñ㡤¤„7oÞ ]»v¸yó&RRRбcGtéÒK—.•ºß‰'pòäIŒ1=˜1c ££C+òÑÌ›7YYYˆÇÛ·o±k×. 4ÆÆÆR«N™™™HOOÇ­[·Ð¾}{ 0€è²@µûé¾}ûЭ[7 ÃðСCX°` 227n„……FE+¡üüü0f̉cùùùؾ};‰ì,^dÊÎÎF‡j½Wqq1Þ¼yƒ””„††¢C‡i¤¾þúk„„„HxËÕ«Ç044„¾¾>zöì •6³²²PZZŠ’’ ÷{‰q·6o YÆ °˜&ŠqÝ»woìß¿_b£vff&îܹƒôôt‰Ÿâ$KQSTT???2«bff†iÓ¦IœXXXÐÞ@¡ÔÁôéÓáéé‰3fPa4<ªªªÈÍÍ…JJJpôèQÌž=["løóçÏqëÖ-¼yó^^^PWWGJJ BBBðÅ_ sçÎ Þ¯r÷î]©Èjùùù2WIœ?‰¢Oùÿí‚a¬[·®ÙÊp÷î]((( 77Æ éS§0hÐ 2q‘——‡ .  zwÚ´i055­S‘ú”œ>}UUU°°°€¶¶6 `ooÿA×^¾|ÎÎÎÔ¤|4×®]ÃÖ­[qýúu‰ãÙÙÙ¸uë222¤òpÁÄÄ佩ÐBCC†’’€©©©TÐ>Ÿ¤¤¤ÚgÛšˆŠŠBVVÂÃÃannŽ™3g¨Þk|äÈüðù÷íÛ‡¢¢" >JJJhß¾=8Š‹‹‘››‹3gÎ@QQèÔ©œœœ>ºL™™™ÈÉÉÁãÇQ^^.á)FWW***HOO—ú[Û¶m¡¡¡uuõFùGSîIDAThVƒB¡Pƒ°µ*þ***PQQAvv6ôôôðý÷ß×ÀÏÏoß¾E§NàââB…H ÂOj^½z†††˜0aB³&Û¦PZ¢AH‘ÊË˱uëV”••ÁÌÌ  ©©‰W¯^aáÂ…Æ`MNœ8>Ÿ/^@$ASSzzz;vl“ì3ÌËËCyy9LLLšLV ´¹P(Jó|¨V®\ùÁç¿ëîB¡|J""" ®®ŽÅ‹SaP(”‹@ €’’¦OŸŽC‡¡cÇŽ=zt×Lš4©YËÜQ¹ëŒ¯ZRRòÞ¤Ž™™™2÷šP(”OKXX˜”zMªªª°ÿ~lß¾]Êe…Ò¼(**¢ªªŠ â3 )) ¡¡¡µþ]$áôéÓðöö&®_òŒ¥¥%Ο?ž={bÕªU´‚)Ÿ%ï ØUVV†´´4*¬ ‹Å‚@ ‡Ã‹ÅÂÌ™3Ñ«W/*˜1KKK1iÒ¤:?`AAA¸xñ"Ž=*!‰B¡|Z¢££qìØ1dgg×zΑ#G0hÐ Lž<ûöí£B“#´µµ1bÄ*ˆ΋/pèÐ!$%%ÕzÎÙ³gѽ{w,_¾Û·o—ûw222ÂÇ1jÔ¨zí¡PäÛ·ocãÆuƒ‡Æ7pæÌj¶`¸\.*++¡®®N…ñjuÝ¿ÿ{ƒ6<ü»¼¼………çòù|äææJä¢P>5:::àr¹-ú***PPP@~ëééA$½w3qZZI-——GŽçää`çÎçÆÄÄ -- ÷ïß§¦‰ˆ‰‰ÁÁƒ[Å»Ž3ƒnÑï þ†Õ4êóòò0sæÌ:ûMBBÆ«Â@*yz`` JJJšý;ùüùsøúúâøñã´£¶Rlll0oÞ¼Ïî½ÂÃÃÁårëÜvöìY 8fff8yò$’’’Hz’œœ 1??•••T·•cœakkKëèˆÒÈ4ƒ‚‚@®^½‹-–-[êõ°×¯_ãöíÛÇ*++1}úôzÝO @(JDßûÞ¾} 55µz ¯%_/ Áçóëm5´ìåååPVV–ÈÕTÏøçŸ0vìØÝy³²²pãÆ ò{ôèѰµµ•êcо¾¾T(âââbtéÒ¥^÷»téFŽY¯kƒ‚‚`cc#•SôC *‰pÝÊ«W¯PPP€ž={6ù;_¿~ Hšý1ÊŒ™™Y‰¹kãéÓ§`±XõŠºœ—/_ÂÎÎ­ªªBLLL‹7KJJpñâEòÛÓÓ¶¶¶HNN®×ý¤ú!ǃ¡¡a­ÞÇýû÷aiiYïGòóó™3gÎ0—.]b Èñ­[·2 Ã0Ìùóç™ÈÈH&..Ž9räÈ'“sC®Ý¹s'“]¯kýýý™ÔëÚ4Û˜âííÍTTTÔëÚÇ3IIIõºöÎ;L```½®}úô)sôèÑz]ûöí[æ÷ßÿ,ûaQQÉlß¾ÉÍÍ%Ç;Æ3 Ã0ÌíÛ·™´´4fÛ¶mïmW"‘¨ÞåÙ¿?óòåËz_ëÖ-æÞ½{Íö½jŒëå¡ ½¾°°Ù²eK‹¯yæÝ÷+//gŠ‹‹†a˜S§N1qqq Ã0Ì‘#G˜gÏžÕzŸ«W¯2ááá *K||Ù ‚‚BáØ?5ªªªõž±m¬ç·ÆgËÃóå•»wï’U›ÀÀ@r¼}ûöÄ`Ô¨Qxóæ âãã1uêÔOV–aÆ5‹ ¬­­‰KlSÓ\ïlgg==½&®úöíK;Þ;DDD 22, W®\!ÇÉ*››”””pýúuüðß´<ŽŽŽÍžK¯¹ú†<•Ê@~ ÇCdd$x<JKKT»‰®Y³0~üx„……ÇãAWW;wþ¤eâp8 Zõùu.y’ —ËmÐê`cÚBŸR&µú,­^½ZæñÄÄDòoKKKüòË/Ÿ\={ö¬·kWc°páÂfm?þøc«|¶<<_^©-ÁW_}%ñû}‰oËHiš3Azs½s}Ýzж¶6´µµiÇ{‡bàÀRÇû÷ï/ñÛÕÕõ½{òyHNÝ\}CžÊ@e ¿888ÀÁÁAêøÔ©S%&NgϞݤãzsíòªsÉ“L¾þúëV!“&ËCØœ=š;¨Hs>ŸÍf7ëꪒ’R³Í¬p8œùk·&Äû*š—f‰þebbÒlÎÀëµ°¡XXX4‹§ƒ’’<==i'û†Ú¬Þ(ÍÒ6åa,’§2¨¨¨HM*´Æzh (((€ÃáÈEYäeEMQQ±ÙÇ :儼TTT”‹vÂb±jm',†a˜Æ~`ii)ØlvKÏoß¾€o^¥PÊÊÊÀ0L­m©¬¬Œl*g³Ù­:ü°P(ÄÉ“'‘——‡ùóçË4˜E"Ο?ääd,^¼¸Y'(-†apáÂ<}úK—.•Ùf®\¹‚ÿþûü~7 Jk“ו+Wü±ÖôíÛ·‚åË—Ó°é”F'""×®]Ãܹsadd$õ÷ØØXœ>}š(²sæÌA»víZ­¼ø|>ÊËË¡¦¦V«r/PVVUUU¹0Š(­“òòr‚ZöUTTHD½ÖÔÔl|ƒðÁƒ€P(Ä”)S`bb"uN||<®^½ †aàååsssZ{”z‘œœ ???°X, :Ý»w—:gáÂ…èС€j×7yYþoŽ;†¾}ûBOOG•éíçç têÔ ;wî”k·]@@¢ˆ‰?Ðeee`±XPQQ‘•””>j†N$‘ÿ‡RUU%Ó*))©3’jm×µΟ?N:ÁÂÂ[·nÅO?ý$uÇêU«PUUeeåV=Ñpùòe´mÛ666ðööÆÚµkeƒÊÊÊpuu…··7–-[&7+JEE„B!éC à´´\.—LF1 ƒ·oß~´Á[UU†a>J& ígB¡äfE¨!DFF"''ÇÇŽ;0qâD©ýÉ.\€‰‰ ºté‰1µµ!°oß>”••ÁÐÐ'N”ò~ …8|ø0  ££ƒéÓ§m…Ò²ÈËËÃÞ½{¡¨¨;;;™ÛÖ¬YCö¹³X,,Y²îËwéÒ%,_¾+W®¬5ö™3g°bÅ üøã8zôh‹¸üýýÉ﨨(¬^½EEEäXLL Î;÷ÞŒH$’8¶ÿ~¼|ùò£ÊsêÔ)üõ×_­®á9r?þø#V¬X³gÏÊŸßâÞ300P"ÝTYY|}}±wï^ #íÀï½×»ý3&&áááÒ??”m0>>žL êèèHäºÃáppøðaìÙ³[¶lyïú9sḸ¸`éÒ¥PSSãG¤Î €¹¹9–.] 333}ïþèÑ#¬Y³F"ŸñŽ;pìØ1‰óþùç¼~ýºÎ{½;Žeddàßÿý¨ò¼;Ô‡ºîÑÇÚšlß¾?ýô–-[†;wîÈ<‡ÃáÀÒÒÅÅ۶¶Є{[ú̸ˆgÈ~úé'ðx<Ä£OŸ>ˆŽŽFii)´´´To­¹ÉŸÏçC(’YM±›•¡¡!úöí %%%ˆD"Lž>¡P0 CÊ!~?±Ï7ŸÏ'î•âw-//¯n, PTT”)y¦OŸ>èܹ3&Nœ‡>}úÐFÝ …ؽ{7rssѹsgLš4 fffðòò’8oÒ¤Ixúô)ùýêÕ+ÄÆÆ’ÀTéééˆGXXôõõ1oÞ<øùùa×®] Ř1c`mm;wî °°Ü'??Û¶m 4NNNRed×®]CDDúõëH([›6m‚P(„‹‹ úõëGŽUVVbÉ’%HLLDII îß¿=z`ôèш‰‰Á… óçχžžvíÚ…¼¼>šššX´h‘ܯ9’ä2¼rå 233›-²3¥é¨¨¨Ã0DçëÕ«?~Œ¢¢"èêê,X 1Ž …B̘1ƒè¨b“Ïçݵ²²ëׯǚ5kH^?}}}̘1ƒÜG$¡²²’讲úHhh(ú÷ï¡P(¥»Š÷ ŠuTYú­¢¢"BCC1hÐ )ý¶¼¼6lÀš5kÀårÁb±¤äQS—ŸÓÒððð€²²2x<x<^unäÆ~‹ÅÃ0`Fb9½ªª ŠŠŠ`±X`±XdULB¹¾âÞbmmýÁáœ<ˆÄÄDlݺ•(ª¶¶¶`³Ù055Eß¾}qéÒ%hhhàõë×7n^¾| oooLŸ>®®®HMMűcÇ ¨¨‘H„qãÆ}‹íÙ³g‘’’B:ÕØ±cqãÆ Ìœ9yyy8wîRSS¡¥¥ˆD"¬Zµ !!!ˆŒŒÃ0°··ŸÏGtt41hW¯^M›6·™Qöš 6›MÚRÍNÉçóÁápÀf³1lØ0êËÿ?zô蘘èééÁÐÐ?}ú4ÌÌÌ`kk ;;;DDDÀÜÜœLnÈ~~~pvv†••.^¼ˆÇ£W¯^ï½î‹/¾À!Cšš dee! >>>ˆ‰‰¿¿?Æ„„‰œ———ÄïmÛ¶‘ß!!!µNéèèAÖÃÃîîîÃ0`±Xøã?Ⱦ1ñ@ ???p¹\ðx<´mÛúúúàñxØ¿?ÒÓÓammM&˜¼½½Ñ½{wôïßHJJBnn.üüü°jÕ*ÕûƒšÊ tpp@XX,--%\c¯\¹ ôë×2èÖˆ››‚‚‚зo_‰I¾Û·oƒa 8îîî м»ØîÞ½›D'ß°almm?èºwÆ   >œô!±A(þOÌš5kÀãñH$åÛ·oKôO©g=yò{÷î•è£sæÌÃ0¸xñ"bbbpôèQüùçŸ044ǃ³³3ºvíŠÙ³gcãÆ033Ù3g°fÍtèÐÜgܸq‰Dˆ…¿¿?âââH_ Gjj*ÊÊʰjÕ*””” >>¾Y=VúôéƒÀÐÐÄ]ôñãLjŔ)Sðäɨªª¢mÛ¶ …-B_k ]£¦~+‰ˆaRóñ$~K#<<`³Ù¨¬¬Ä¢E‹>HHIIÁ† °páBØÚÚâÖ­[8wîÌÌÌÀçó1eÊ„‡‡#""Û¶mÃøñãѱcGøûûÃßߟx žV®\‰Ý»w“2.Z´ÑÑÑ $òX¼x1¦N '''°X,˜™™aìØ±rU‡bÏ“wÛŸØ`æp8pvv–Ò‹]K;v,Ö¯_‹%‘›ÐÅÅ{öìAïÞ½1uêTüöÛo`±X-b?W@@ñÁ ý`ƒpÞ¼y°îÝ»“ÇÃäÉ“1fÌ‘U«Ž;b„ äš´´4899ÁÃÃã£ÊOž]³ 6l LUU•|ÀÅçTVV’ͨaaapqq!3(...¤1‰5E(õºøæ›o°aÃ0 ƒ)S¦ã“'OÆäÉ“1zôh\ºt 111}}ýV­ˆzyyáüù󈈈À¼yóÈq¢p6 ×®]ñcǰdɹ*ÿ¡C‡Ð¶m[@¿~ýê}GGÇZÿ& ß;s_ÛõŠŠŠ2Cš×ÄÕÕ•¸LŠß¡oß¾RÑÐÞ}ƶmÛPQQ‘H„üü|Œ3{÷îÅåË—!0gÎL˜0[¶l™û·?C† Á7pðàA,[¶Œçr¹Äàéׯ6oÞ 0`@«î‡bcoÇŽä›HF tttDXX¶lÙ‚åË—Ë}Ääüü|ÒöŒ¤ÌÔ•2¡!ýÓÊÊJbå066/^›ÍFll,V¬Xsss‰É2Y÷566–˜lÉÈÈÀ   €ŒŒ xxx`îܹDjjjèׯbcc±eˈD" <¸YëKì&¶eËÌ›7ä¯TTT$»víŠ ;;fff­Ú»ÆËË {öìÁ¹sçЭ[72yóæMìØ±—/_†‡‡> 333L›6­Å½gtt4òòò ®®ŽG¡¤¤äƒ ÂÎ;KF³fÍ‚££#îÞ½‹´´4â½³råJrθqãO~?{öì½$ZZZRºkEEÊËËQQQ¨¨((++Kœ#‰   @žÍãñ ¬¬L<顨¨ˆ¥K—¢¸¸˜œ÷àÁÌž=úúúø÷ßQZZ ²OžÇãÉA¸téRx{{C(’~øùçŸadd„%K–àÞ½{Ä¥Yl6ºAØ­[7tëÖMêxdd$ù·™™~ýõ×ÓA\]]IÂR±àÄ{ÿij@ Ã@$wKYçÄÅÅ!++ zzzd5K¼ZúôéS¨©©¡]»vdÆI¼¢ ¾oFFø|¾ÌBñsÄK‹%Q‹…ââb°Ùl2#RVV†°°0’pº´´±±±X³f nݺ…èèh…BòîÞÞÞpww‡ƒƒQd7nÜØ¬uÙ®];™¹0Ïœ9Cþ=zôhŒ=”ÿ/w©9hÕáï‡*Wå¶¶¶Fbb"*++ѵkW´mÛÏž=ÃñãÇ¡ªª ccc˜˜˜àÀÆÁƒ1sæL¼zõ @UU:uêDÚGtt4X,&NœHîÏãñ ¯¯ï¿ÿçÎCpp0þúë/,Y²}ûö% çf?{÷ß ‚H$’ê+â(_²®Ûºu+TUUÁf³¡¥¥‡ƒÊÊJ°Ùlp8D~~~udN9tUSS“¨LîÞ½ X¹r%”””ðÇ ¢¢}úôÁСCñðáC\¹r°hÑ"hjjbûöí(,,D÷îÝ1zôhðx<"''sçÎ…`ß¾}PSSäI“’’B6êNŸ>íÛ·ÇÑ£G‘šš Ìš5KfÏž=‹ÄÄDèééaþüùÈÏÏÇÎ;Tï_èÙ³'‚‚‚ˆ«’››x<‰AƒÁÞÞ·oßFXXÜÜÜÀf³áììŒ 6¨žáwssCHHT磻¹þ(-‰¨¨(deeaĈÍò|,Z´ÊÊÊØ²e æÎ+t÷îÝ=zt­+ÊçÊ»®¡´ŒJÓò×_¡´´½{÷ƈ#ƒ‹/¾ÿþ{´iÓ†ìç·´´ÄرcñôéSœ>}@µçÖãÇ‘——‡””tìØS§NP½§ÿСC˜2e :uê„'N )) FFF˜={6Þ¼yCö"3VVVRå BII ¢££1|øpØØØàÚµkˆŠŠ‚››Yùsss#绹¹!00÷î݃››†››™|rrr"˜¸yó&V¬X.— ___”••ÁÆÆ†¸³·iÓEEEX°`Y]oéPƒ°DèGÒyýú5JKKaaaÑleظq#œœœdîÁŠŠB×®]iî9J«#00°Ù“²e¤Pš“ëׯCKK«Åx8PÝø@3eÑ\¼PÏIEND®B`‚snd-16.1/pix/fmeq30.png0000644000076400007640000000143711147553267012754 0ustar bilbil‰PNG  IHDRøAÐãÝ3PLTEÿÿÿààà°°°ÀÀÀÐÐР  €€€```ppp@@@PPPððð000 * ô¼ pHYs  šœtIME×5 ôËF;IDATXÃÝ—r¬ E@Tôÿ¿ö%€Ü`uÛ7SgÚío I¥:O´êÏ>W®E|f 0=.~l¶¿H0•çajÇÆø0Vzà±q}Ñ-¿½¿C°'ïŒ9…W– Ú(Î)Qÿ^óÄñðBØn>/ZN·µúÒŠÃ’WÅý,ŸkÀ'Ài£ X­Ññ2»Ž]Ž5?îÕ0.;ÓZÓB4‰(YÌV‚ðC eIå@ª&—}†ÜÒGüpÈVßs‹ç¤tä}+-Kf¿öÏÐ!púŠá+Aìš@ß‘ß=‹ÓKT¸ÅÀçqò´Ê»bu-×fµCo‚1ܯ²¨ô”Ý›îD@ÑìJiô6zŠâLIJ¿4Î m µ9œ7JŽ8‘¶kØs5®UcM}ø‘-Wf O–¦àXñÐ%äŒìd@Öì€Ñª(^GÿOÇü£œ—”Ø=T—äì\t³Ê;e—Ü}‹Èª;ç. " hl¿á—®ÑL€{õë;ß8þýCçCï|­ø=‚¶ÊÚ‡€Vãú§?o›«í ·o¸ÀÍW)î‹UÆ›'"¥çaZM/4ø¹ æü¥oúï:Î~ÿ1ŽÛh_7˜IEND®B`‚snd-16.1/pix/mixname.png0000644000076400007640000016270111147553267013321 0ustar bilbil‰PNG  IHDR„:Ás @ pHYsˆˆÈ¥†tIME×3!\M¡ IDATxÚìw|ÅûÇŸÝ»½’»Ë¥’^H(„ŠtBQ@Ú©‚‚_iJ15¨4)‚(RT@š€Ò!¡w„@H%¤÷äêÞ–ß/É…„@ ž÷‹¯½ÉìÌîÌììgŸ™y†P«Õ€ ‚ ‚ µHº1=.2N¸ï̾,. KAA©5%úzà×bÈ`3îšîʉKŽ%‘s8Õ«W*®Á‘‘ “CÃÙdá}ˆÁâCA©»8fsJ-÷Ôh"E¸¥2Oi©N"ç VnàŸ9ÅYl”@›b`y–fiM°é&ƒ‰‰}4jT+£ÑR©„ H±`m‰¬|:‘6ÑX…‚ ‚ u±ž÷”ºW>'ó±ARÖ F©PÚò|¹â•çùˆGWhw©–óVÖç8¦‚˜©±Fk’IYž-£ÇÑ,-1ÇqF#£×ërrrt:˲r¹ÜÑÑ‘$IÉ@,’äyŽfQŒ"‚ ‚ÔaXžäyN“—R¾j&‡±sœ ºœ£'Îê Æ²17ðôôpf9†fiŽ'9ŽŽ¸}=*:ñÍ.­%”ØínT|ZFN÷à–z]¾‰UÐ,Q,FYž5±&8‚ L&&''—ã8'''–eãââd2™ÚÚÚœÇó&Ö„Uˆ ÈKEPMdMœ)çÓ…§Mü“{-™?D,«çô•LÖVdÛPÚð±éqŠ)¥ŠW(!$MdMœ(§“…'…A¤Öà8ð<ÏUdìä9ÎÄšxÖ<Çs°çÀé윂²1ߨÝÓ­DZ&ÖÄqbžçïÝÿ}ç±””Ìñ#ûq¢¢ÞrÀ`¤»u ’5±$Ë™Å(ÇÒ,­7é är™£££ƒƒA<Ï«Tª¬¬,•RIÃ0­†æÑ2Š È —rR."D<ÏÓ<­çôÖ"k`x†"(X§cy–ÒJd%1 ¤ƒÈÁ›ò>¶ùXÇm%¶:Vgä‹¿é­H+?©Ÿ¡Ðp÷á]‰‡D#Òˆ‘œ”SP”Ã3rR.!$A°ñ E r9zSÞG7m;¼­T$ÅZF¤Ö`9 |Eãé

cdË‘týëÁ_%óa÷Á ™NþýÜï'ÏŸä[ò¾}%" Dh#šÊ›êsõ¿ý%Ù˜ÌÔ!H›£HˆhâÕ¤•}«S7OùúºKܯ޿z$âMÒ©©©…Ý G5uææ™C÷eé³dÍe-üZWØXÖX“¯ù÷ê¿qš8m6K’5Êskbÿ=ño!Y8wÀ\eº2‹É4ÒcØøÏFÒ–ßm<ØpÏóECúჷùºñÇNšµÖ¦Qi™ŸùÈæ‘º¹ÚÊÊŠa¡? Ï oÌ5îÙ¢§X&>’|äHöžäÓ²Ó®¤\¡ÓÂ&Ä'Ø¿a%ýJ„&BÙD™énàÂt)ìZ©E„Ž ø ¼; Ç0¬‰žr|žþÄó<ÍÐ<Ï_-9%óFD¬R!7èó—"=ÝeR € –¦®Ø2Êð ÍÒ¬˜•Ë­ SNNö¾}YjãìlJE§N¹¼áD“Øc"RÛd³7Fn´ÑÙ|üÎÇATÐ-Ý-1ˆYŽå¼­­­‡¡™CŠ›£[‹¦-lÜm|T>B¸#åØÍ½ÛÝzw3™L³Kg’Kå ]z»zÛ«íó˜¼È˜Èá;@n*·«WÕo––ó ç͆o¾ôfƒ‹ äŽr–gÝÝT6Î6M”M(‚Š*ŒÒ‚6Ãng°›Ú{jsqó;ú;"Y\¡‰6¥S=<[6mYϽž·ÊÛl¢@G%‚Ô²%"+·0:&ù‰Ú¶jB$Ã14k’àYx ,µ¨HMŸ¦/Ô›‡éi»VAjQŒ@Ä%¤ý´åÐ#´ j$¬ÝVsòEºóÉý*ÍÑ<Ï‘7o;&•RãFöjàãæîæÈñ|ø…;0~ä;Aš8†æø ˜8–fh†dyRš““••®T*?£‰D¥RiµZš6@®¤–a‰ Hm³9vsÒù$®€£MtUÀ7æˆù!þ@|ž:Ï•u{~nä‘H›æfá͈„m¤VW £)JOiÍÍ‚›S¶M‰½+o'w³v£HJH3,;lÔ~}Œž£¹L*Ó`g8ùà¤á¾Ñ2F¨µÕÞÌ¿yïî½ü‡ù¬ŽÕq:Æ 3¬‰Z£¹­1å˜òuùº_È=—›g•WOYï—è__zÌp4MçKòÁ–Ý_÷w\žMžˆÍ Ÿy,R륽QxãVü-m¤VW¨“Ô“ˆµbè¢éR‚ µÏó@€X,R*äåL‚ H†cM¬  iSèÊ?-btÇ6þ@<ÍÐ<ž‘§7г¦öòp™T2üÿºÑ1ˆ"ƒ+ÖZÀD³4G2úüÔðð yyù`ooçææÚ¨QC©”¢iamiâ˜Xâ­ÅAÚÆ 2ðíx#cäy^*™XVHŠû‰ÕŒš™ŠLɉšUóÏÕãX`†#8GÎÑÈÙf¬²¡RLŠME3ñh Y_–ö¤Y–µk#g”¹ÉXGÖĘH íI{žà^F“³‰á1ˆí {k©5+bÙ¶¬‘1ÊxYdQ})£")2—Ê5_¡5XË(YU \!P%Ï’Š91Gpà¬- ˜K°Žœ#I’8è„ HmÂòdËÀÆë–6.OŒê†áË$A€hñcËMŽ yh–æÈÁ­z·*ùw…•x¨¾BL Hg¢Y¦´e”£ÎD¤T*³·@½zŽvv¶jµ d2Á+*ÇñT#ÆûJáu¬BAj¹X.ËKô¤¬ŠRUô‰¯–¨ÍŸû J¡ §ÛÊmA/á,YDˆÌ' ç*)%P¥N´–Z—êÁ9ÖâJ„ø,Ï>å ¥]!Ó#R›ðÀg§?Òk5Ä1™Œ¬kây&ß ×°OÀ¡9š>+-Á ¯(YÆdd8†æè«éyÎÄšs©¿»4Ïñ@À=ˆ•J$TêIKãoĘAAê4áDÌ%ÑCÞš¯8Z¡˜á8Ø$¾ÈZ1ÇdÎÄ2GÈ{"Šå©§äž/21%ýŒ2cdŒ¹I¹±)±X7‚ ‚ HIâ*óQ墩\UVVÅÃô Çè]†øN>m±¸AAåÜ?—½Ö/¶Œr<˰ ŸÁÎ\7ÕÑÑ AA©!"#ïwšaø"1JI$P¥R)±ŒAA‚ç9Žå(‚dÌ ˜H Ä Â¢AAAjÄ âH‚"(³¿‚ ‚ ‚ÔbBDñŸ‚"Ð2Š ‚ ‚Ô!" ³%H1!B»(‚ ‚ R;ˆ ‘¨È**Ì­Ð2ZXX8dÈè’ÿîÝ{ ü)4tùìÙ JF^³æç!CF¯^ýSU®O£ÑZäyß"Ίk…Kà“OfþðÃúªä¨Õê¾ûîóÏ]»öݽ%ûíÊ™3ç×D5\¿~Ë|ƒ»ví{ÖÓ9Ž2dôÎaƒFA¤ê„„„šccã·nÝQ^ÌË—¯ 2zäȉϗ &D ,`AU¸€Éh¤u:ݦM?šClmm…ƒ)S>ä8®däQ£†uìØvùòµU) š¦5í–-ëÊæhæâÅ«#F Ž.œCQ”E #GNܵkK%s4™L.\6ÿ¼wï¾££=@øè£q,ËV{}~÷Ýk×.~þôÓæ³g/tîÜ¡¼ø ß¿{É’$×®]ªP(ðáAA¤êœ9sÎ|œ““q·¼˜AAÍÖ®]:pàˆç΋‚"˨Š0U„T*urªgxûök×nÚÛÛÐǨV[;:Ú[Ä‚ ‚”%//ïÞÂqƒ¾]ºt4ë4±¸Ø˜––žœœš™™•œœ=ztõöö,?UB\jÎh%0]¿~kôèÉ£GO^¶l9$EE}ÿýªŠÏݱcORÒcê?BCWTæÎoܸ-ä¸téj!äáÃØ½{ÿ9u*ìêÕB¸H$*,ÔþòËÖFRE„¹2ÙYYÉ;wnôè)ˆŠŠ&Âϯ‘9©ï¿/Á?{öÂÅ‹WÌ·³dÉ Ø³ç@\\‚9ÎSˤ<ââÆû$""RHü§Ÿ6åææ ×@’–·#‹bbâ8dYµj=MÓB´ÜÜ<¡LæÏÿjݺB`ddÔ¡CG9Žûæ[8~üô·ñaCAמçõ5zôäE‹¾CC—›5Ã¥KWÃÂÎ=ñÜèèØqã>ŽŠŠb®]û‹F£© /БŖQxºeÔϯÑÂ…_€\.36kÖ´Y³¦7þ^ñ¹×®ÝìÞ½KóæÂÏáÃÇÏ›7ã©Åáç×Ð"ÇŒŒ,“É4jÔûPPPxþ|ѨzÇŽí¼¼<¯\¹n>·uëÍšùÿùç^!r%‘Ëe,Ëtaa¡µµJ hФä=ÆÄÄQÕ½{áçúõ›ÌºpáÊÕ«7>ýô£ª´ƒÚLž<ÎÊÊ Þ¼N§÷õ­ïë[ãÆß-nçwzÊd²3gΚCN:»eË:[[A×.^üÝ„ £ ŬYÓ«íáÃÇ"""ßy§g||â̙ӄ³8Žup°Ç'AA^sõ‘ááçàܹ‹Ó¦i›½{ÿŽŽŽíÒ¥ÓOïܹÃG•Ëå0hÐHƒÁ¨T–»›’Ù2* Ób(šCZ …Uýú^Ï}okÖüdgg'÷èÑ¥2§XYU”£µµJ¡°ªÞ èÙ³Û±c§®\¹¶ví/'N¨ æ®]û®]»)ûûû™Ã C^^^/C­¶”hu!‰ÌóH’\²dáìÙ!ÂO__ïI“ÆUo¦‚ ‚ÔE9jV_YY9ÂAzz¦Y3À‡Ž*ïdµ D+ƒŠüŒþ·(Y³~F¿úêË7ÞhQ ž9söæÍˆJF^±âÇéÓ?®ÆÜ?úhì˜1–3vY–=rä„BaõàÁê$~âÄ™ˆˆÈÀ@ÿš»Žã=¹}ûFáçòåk¯_¿éîîŠ ‚ ‚ ¸¹¹š5CÅ9rbøð!M›6~ºæ HI/`zÊv $I*•OX²ýÇ;þyk||Bppﯾš'Lhýæ›eMOÏîýÛo?y{{Κ5mÖ¬ÄÄ$ᬰ°CO]NDÄ­[ÁÁ½Í!«WÛ¢EàåËW…À®]; ¡¡ËÿùçˆãÖ­ëE/‘P“&"oÚTÙ¥ý3fL;wÑÆÅób·oßóÓO›„{\´è‹nÝ‚ èûí·+Í×¶yó¾¾õ§OÿdîÜE!!³­¬¬æÍûê×_×<5/¥R9bÄPs:}ú¼Õ¶mëÈȨ  ÀŸÞqÆi6j®XñùË/g !S¦Ì¸|ùšV«;}úÜÉ“(ŠZ³æ;adìV¯þTªb 9EQ2™Œ$ oosÖo¾Ù¥[·`|ØAä5§¤f‹E‚™sÑ¢/Ìš¡W¯îóæÍ€°°ó_~ù &N=rä{ЪUÐêÕ? @'M#Ì,³e”èܹó·»CÂRÿýsÜуvyx¸aM¼@._¾¶gÏ¥K¿Â¢@A¤~áØ±S_ýt×ì/^5vÒ¸?ÆÓ{&VÓ“¸(‚ ‚ RkP ˜DŠÑQ£&%$$Yú›¶W;£GÿÈ"°Y³&?þ¸¼†r3fJIßLþþ~ëׯ¨¡ÇŽý866Þ"ÐÓÓ=44(‚ ‚ µÌÏ?oùã]eÃüÓÚÚú©§·hèãã]éÜQb“H T´7ýo¿m¨åâØºõ§ZαänOµÃæÍ?b»GAä%aâÄ1'ŽyîÓU*eÉ)§OE%ö¦'ž¶7=‚ ‚ ‚TD ?£$«é ËAA©ÄY¼“HŠ:>==KAA©!”!¶ÜI$ †Ò±ŒAA‚¢Ä2™L –{Ó“b±ÈÓÓÀËAA©9är™˜ …ÕôÂ"&ýŒ"‚ ‚ µe±€IDˆ,AA¤æ!DDÑ0=.¢GAA^âòþ`eeg0äs{âÈþ À@WŸjÉO©t‰¤Xî‚ ‚ ¯&“N§Ëy61ªåuz‘‘'9+W{“’ÒŠi!\ÁHªr)A’$ÎOEAy Êwi_®Ías" Ê&hIÝd€dx|-i\Ð+W®_¿~«¼mmm¬¬¬,E"²OŸ^X‚ ‚ H¥Ä(d2™ÞP2$2öA||bBÂ#AqJ$’€€À«W/‹D"ðððÔj r¹\*•xxxÙØØÞ¹s š4i†e ‚ ‚X𜠘(Š’J%R©$000))žaá§R©J¥R©T­¶‘HD:]>MÓ2™L­¶® µS§NU&Ó]»víܹ355« AAäµ£ÎÎÎyy¹R©T¥Réõú’’Édr¹œ ¹\^q"7nœ1cÆSóZµjUfffVVÖªU« Ö‚ ‚ È+€ø¹Ï$‚¦ilmÕùùÏóŸ$‰›››V[ ‰”JerrÊS`Yvûöí‰ä©‚õÇtvv~ï½÷ !!aÒ¤I[·nÅÊCy&nÝ2Žfþ¹l™cÏžVX,‚ÔU1ªV«]]ÝÒÓS€¢¨ÂB•U‘¦T*•Zmpìì\e†a˦˜˜h0&L˜°qãÆŠóJOO÷÷÷޽½½ãããKw¯·’’’ÊžåèèØ®];¬cA­–‹ˆ0šæç³X&‚¼Ôb4áz‚F¯)bÔ÷bÎÎ.‚¨_ßëÁƒ‡Â±««ÇåËJHÉ /¯J‹ô}||||ªÁ}iJJÊýû÷-׬YÓ¸qããÇc#‚ ‚Ô=1ê$væÕÏd¢Ï‡oÚ¸±­“' Š6 %Â`ÐYœâìì$ŒÔÇÅ=”J‹Ý‘zzº—uöTôîÝ»wïÞ{öìÁÚEA©«bTJH½=9޹/QyÚ9×sö.ù×.]ºÝ¼yÍâƒÁ””ìì\¯iÓ@™¬x›¥ÂÂ§ΠµÀd2={¶AƒžžžàããߥK‚ n߾ݼyó[jQQtj*ST‚b"8XŽ- A¤6‰Ž¦?.ê‡ ºuÃɯòʉъIHˆONNùoÁR1®ÀqLff–9ðúõ[mÛv°²r´ˆœ––¶aÃxôèÑ¢E‹àÓO?µ±±ôk=–-[&,´3fÌ–-[/^ <Ï/_¾üÅ–Ú÷ßçlÙR4)ÖÆ†ÌÍm€- A¤6Y³&oíÚ<³QÀdjˆe‚ ¯uvv*®V[Ó4]ÉD E§N@ø¤Ò"{ªJ¥:qâDÆÅ˘1cN:Åó|PPD"ÁšCAy}Åhµ R©zôèñÄ?QUöOÝ»wÇ C©Q""Œ:_ÉÈ»v¾ù¦•¨òéËdDPËA—BŒ"/+Wæ2EÓ® (HŠNäEqà€&:Ú$[[““&©k3÷_~ÉÏËã '‡eÙÊŠÑáÃU'NèrržÁE”HD?®¥’˜<Ùë½v¸tÉpölñÞ4Ÿ|b#—uñFŽ×ݺeü¯-Áôé¶X¹(F‘:ÏܹYCÑ‹ç£lPŒ"È‹â÷ß öî-ò¦çá!®1:jTš A‡ S9;‹ kWµJõ ›óµn-{¦µZîÔ)èt|¿~) P;v¸`¨QNÒÍ›W¼–cÌk¹\Todß>ÍúõEs…¥RÅ(ŠÑ—–…{÷Œ ×{¤"#ƒ­WO„ÕŒTÐ4]¤Ý­­I//ªŽÞÈÝ»FóD{{‘«+~—¾(d³fRˆŒ4rŒ“~ë–—ƒƒHhÏ$YK×ðî»Jà8èÕKœ­m ?îþ¬ÒAj‚Ü\Öì«6”Èd ŠÑÊRPÀ&@(üôS^Hˆ}¸ò«W ..bwwÔ/53_4Ú¿¿rÿ~×:z#-[>2™ŠÔèÇÛ¬][+÷u (Há3fd C"‡kÅb€‘#­­­ÉÚ¼½žÛ¾½@0" n-|½ª%¿oŸfà@%¶ÀºÂþýšqãÒÍ?oßö ĉÎ(FëšBB²žé”Æ%99lffe§^½ÿ¾ª_?ìÚy–/w4¿tUúÙg™:ßïèáQƒ¯†´4æ³Ï2@&#˨DBLZ«“Gõz~ܸ´Ú̱S'ùûï§VWj>>Ô7ß8`3F^+1Êc1UŒNÇ¥¦²Eÿ}4l(Y¶Ìñ™±¶&FÞh¬liïØQœýû+ P€ ù Û© úô‘®_¿ÞÅÅ%4tÃð0{vfRSÁ)o¾i•ŸÏ]½jx¾Å+W:€HÎÎÕ¯zF¾ä+df²³gg– ‘ˉM›œk³œEBG]-ÄÇ›„þ¿$:È'L(5ÏØÊŠpqA“òŠˆQ¤"hš_¿>ÿî]#4i" ÷xî¤Tªgˆe·m{ÊZ¢'tj5i¶­¾ ðw"ElÛæ,´mÓ… ¶oß®Õj;vìh0"##333 ‚èÙ³§«k]Z×¾½¬}{™VË}òI©ù¦qq–CØNNâ5k,í¸R)ak[Wç5™L|v¶åƒ³gõkÖä• FG{ Çë×ç¯\Yªét|A›•ÅN™’ñÔ½¼¨deç˜{Q•ŠT(ÈU 99,Móh·m+xîD¼¼¨¥K ^=”F(Fë*©RI aCÉàÁªÓ§O;:v˜6-ìíÉîÝkÖxpç}ÿ> ƒ+kbêÚ5ƒyÙ¸EŽ%™5Ëö¥­{V¦OÏ´˜^Öµ«ÜÑQTú'&/çÎéÛµ“‰Å¨h‘çG¯çwï.¼~ÝgjÓFV•gÜdâGŒHÚvNNÌõëñS§NMHHHJJúùçŸà×_‹ÅuK‰šQ(Ȇ ‹7ˆ ëÙ³s¯^¥Š+=:ÕRo¹¸ˆ:u’W1÷¦M¥ÙÙlzzQbmM6h ©ú€x«V2êñcæâEý#äær'Nè,ƒƒå´Á—™¿ÿÖde±×¯žaÃ7)zÑæÍ¥QNNâà`y­Õ>ÇÁîÝ…¦ÏÈ`û÷WTåIIL4 oðwßU\½jÄ^Åh°aC~däó7/ÁZÞ_80uêÔGíÚåiiÌîÝš½þý‹W³×ªsçôÓ¦e˜m ~^j"ÇΊ–Jú¯¿4ÉÉ¥äéºuyM‘I¸¬5BàÐ!íÑ£ZáØÕU¼gO!Ç=ÃeÔ¯O}öÙKáºyûöÂK—ôUIað`Um¾^UXÒÒØ‘#UUu(CQ„Ð/ýõ—†ep\¡CÏ-]ê0xðàÿ>·Ú×’‹Ñæßÿ4iRLLŒD")îä$J $ ¦þÑV1Ç{÷ e2Âʪ¨ô=bÎÓWÝ®¶ys~~>§T’å-?ªWï wôLdd°íÚÉ>ÿ¼+„^ôÜ9ý͛Ƹ8Óž=…Ó¦Ù6hP>˜yÒÒXøâ »ª;Fôò¢„RÝ´)??Ÿ­JRÜüùYuô9"Xµª¶ý½âbÔhä ¸þý“Y&M²7îùw49{Vœäê*þùg'ã„ cRSS'OžsÆç£|”Ê" Õ´iÓºX\ƒaÒ¤IñññcÇŽ5jÔÅ‹oݺUyû®·7Uõ^:=µ²"ÌV |V[uU””Ädg³66¤·wµIºñãÕ½{+¢£é Òçε›8Q-—WçHëÖ²À@ix¸>44gèPU͉QáâÏŸ×Ï›%‘£G[€BQOÊС*ƒß¾½°<¡iòÞ{©sج­É¯¿®«¾·xÊÎÇðô¤Ö­+¥PIÌ}ŠÑ§¾5·oOžô¨úgPtêT›”føðÔÛ·§/X0¿U«F¿þ:ÃÝÝ}Þ¼y!!!ƒáòåËmÛ¶­[E$8ò=tÈrÖêÕyÇ—òŠ×¶­¬eËR›£øøPMšHênó¸{ט˜héÂæÀMJJ©À9sìÌ{úøÄ›g/\»f>ø ­iSI—.Vr9QÅIe4Í?®»pAû¶±E iM·.ww±»»8(HúñÇ6&?p` ôï¯ô÷—X¬ßzV ¸³gõ°ukÁƒ´…5JðwÆq°aC^¥áòçËÖeß1’@.'ÆŒ)e¹hß^fg÷œó°_51*—“ß~ë?þ˜'•›69uìX#†®®âƒÝÆŽµš0!ý½÷@&“ 4èîÝ»:.>>¾Î‰Q8{öì¡C‡BBB¬¬¬ 77÷øñãÓ¦ 6­”Ù ,Lo1€{íšA¯¯=Ó—››¸E ©hß¾B­–²W/ÅÎÅ߯“&©7lȯd‚VV„Tjù=ýå—ö¼f϶ËÏg÷ï×DD×­s4¨šìÞíC‡¦®]›g^yP|óÇñ[·DEÑ}û*ª}¦7Þ<èÖ±c’yR233—/_>tèÐM›ZÀÑ£ÚÉ“W7±’Ó~†U8¡ÍÉ)e¤!°±!`þ|{OÏWÓA’äðáÃïÞ½«ÑhâââjMŒÖ9BBBÚ´i3wn_¸uË8nÜæ7ßìyìØÓC„®uäHÕþý†/ÛÀ PÖš~½^¿hÑ¢>}útîÜùàA7èÞ}y·n£ÿþ[û4…@ ªÚºµÔ"§ÐP‡³gõÿþ«‰@˜œ¶i“S|¼éðamAšŸ|R4¢šnø¶OO±PÔf22X'§ØÒZÂã¹ça¿j“LF“`þúëÑÑâ9sÀ‰î"A’@TÍÏqðø13rdjLÌ(‘(ôÌ™B‘(iâĉŸþ99rdذau®Ä¢¢¢>ܯ_¿3f¬_¿žã¸>øÀÞÞ~èС1»t‘wéRª¥¤0 µgúJNfÖæåq*…A™¼ûlΜ9©©©ñññ úá“'OŽ1Eç™>}z¿~ý®\¹bmmœ˜x$9yÁ‡¾•¥xê¹B׺n]þ€J¥²Ô«T,&Ú´©Õöé§ŸŽ3æðáÃ~~~¿þúë_íÝ;-*ŠyšŠåø!WÙ7Ó½{RçÎò~ý Ù¼yÑ V³fÒfͤ4Í÷éSªpXö CØÿüãf1`-ªãûÏ”f–`2{OP*ÉóçKP«2Áý¦кµõñãðÆ‘Yóç5løä÷VÆ''QTmeE>~ÌJnß6Énß6ò%^†{öhòò¸ðpË—­ôzýáÇ•Ê"ÛØéÓ§ëb1={6..®Q£FëׯOIIùöÛoCBB~üñÇÊœëê*vu­Õ&Tv YïÞ¥zŠ*ÓT^ÅúøP‚·ÅI“Òvï¾þ¿ÿµ3¯ÚiÖLzï]rº¤ŸŸ$5•mÑBM—œ`k+jÞ\zë–ñÎã¦Mpè«y1D- ̲èÐA>c†mll¡»û ??¿©Smììʽ†-d7oV´XøßuW®Úµ“…‡{TÞ2š™É–]_®?}ºÜÓgδ É®x¯ ýî]¼ØþÍ7—¡U+iß¾–ïø $ ãFFFÞ¸qÃÞÞþ‡~0k×®õóóóöö¶³U²a×NûIðññ™5k–F£9qℵu‘¼8vìŠÎ'’˜˜xîܹÿû¿ÿ›={68p &&æ­·Þ’J‰Ê4!ÎËÐÀ¢££/_¾…BñÍ7߸¸¸<~ü>ýÔ¶bÙºõó É=x@¿õV‘1(HÚ³g)éä$ÖÒ½2´n-+[PÑÑ´Åš¹óçõß~k6BtR«=„]:—-[»wïnܸ1>zOdÊ”)X•$88¸aÆf¹¶~ýzš¦ÃÂÂ꜎ïÛ·ï÷ß?|øp (jýúõ°wïÞj¿‘eË–;v¬K—.óæÍÓjµ+W®¬¼¯†Š{Ѫ}T˜¬¬H¹œxü˜ñó“@j*Ãq˜hR*É’½èµk__*'‡óõ-Öh¸¤$æ%\yüœb´K—®vv–sÚ8ŽãyˆŽ¾ÿ;¦¡C‡2$44tÒ¤IðÕW_yyyÉåò›7oæååÙØ<Ù‘‡ŸŸD¨TkÆ«²|µ¡P(<<Šlïîîîîîî)))±±±nnn€”aРA¡¡¡°hÑ¢Þ»woðàÁùùù)))æ~ªE KQåï/€ž=-‡‡ììDek‡Ñ£G/_¾fΜټysŽãœ³²²233+ÖX•Ïåôiwž‡-[ 6mÊ€ü|ÔêRÂÚœœð‘ÉH‹'Â\, |€L&ëÙ³'´oß¾yóæøè!U§Q£Ff‡²Â¯sçÎ †ÒºE“&M„’$…ǤC‡‚ù©ºØºuk^^Þ—_~yçÎ}ûö­Zµê›o¾ùé§Ÿ¢¢¢ÊZFk//ʬ[„Á­››ø‰}µ…¥C©$_N8Ï)F ‚¼uëºE V«£iÖÙù…YÔÄb±T*MMM=pà@nn®››[›6mŽ?.¨«ÔÔÔòÄèëLÓ¦M-¼ ººº.X°Kæ‰8pBCC³²²(ŠÚ»wozzzdddÝÚÀ&==]¸‘+Vܸqcß¾}‡ޝXŒ>ÂÆª“&©-V•]¸ ö°-¡Ò,÷fôðZ·7Âþ÷_í½{téöc¹§nVóç—ü°ßh‘Ȇ ð¹Cª…U«VY„,Z´¨.ÞHÙ‡bݺuÕ›Çq×®]3 AAAŒ‹‹Û·o߃`ìØ±Ø–^1úÒ¢T*?ýôÓ“'OFèÕ«W¯^½.\¸ð÷ß›¿¥ä¹Y´hÑ–-[€¦é€€€eË– †{÷î _çuˆþùGès;vìØ±cÇØØØ¯¿þºM›65‘Ý‚ æÏŸOQÌ;744Ôb©AJ sõj©uQiiì€)•Ï¢U+é—_ÚÏ™“U¤ÿ4 ‚ƒåÂÊ0˜>ÝöÈmh¨ÃºuyÇŽé`üxõ™3:µšôñ¡Z¶”Í›õÄŸ›à`¹…ëï€iÉ!3A^NzôèqïÞ½‡:;;ÀŒ3`öìÙƒ ÂÂA1út(Šš4iÒˆ#JŠƒ6mÚ½òu™•Ŧ§OKnÔˆªÍ]|^úõë ju‘©O*•îÝ»·³ÈÉaSS‹ë±aCJ°/V/£G8p Îe ~ýúk×®­Þ\xž¿wï?~|îܹYYY .<þ¼0Õ¡$®®âþýK9me~Ègpãzã†188iÉÁkÄĘΞÕoÚä$ü\¹2·woEppÒÇÛ¿þZðþûª¼<..δzu®9fLŒ)<¼øÄ*|“5Qw¯, %}W9:ŠêÕa±Ô9xJ88ˆ,6¨Cxzz.\¸Ðh4–ÜZváÂ…;Í"(FËE"‘ØÙÙ ËJŠnR,.ùóUeëÖ‚™33Í?“’|ªe/¤$$IZÌ–&B¥ªÎÑämÛ §MË0ÿŒ­ïãSý¶4±Xlq#$I*Õ¼8}ÿþý‚«¤¤¤ŒŒŒ-[¶Lœ81""¢rWH<Ófo¾i%8Û*ñ**éþ𫯠ôÎ"fÙ êòNDjšÂB. ÁüsÁû… í±Xê_²ç̱ u¨»·£P(,ºDó§;‚bA:ÃÊ•+ÃÃà &&&!!aÇŽ÷ïß¿ÿþæÍ›qÞ‚ ‚bAšÅÅÅ%>>ôz}PP`%‰‰0`‚ ‚bAšeÇŽ‚Ô××W.— óú÷ïokk‹…ƒ ‚ E¤f!IrëÖ­sçÎÅ’yahc ö»âŸ^º– ‚ (Fë L°ÿ¹¡!8b‘ R ÓáQ W¦Ž½ê°e -±Ã³7C£¯‘ŸBÒ–¢cÊzåb‘ ‚Ô*÷çBÂÎÈ1ô1a‘Ô±/#š¿~Ýо½‹A1ú*såŠaûöŠwOžlÓ¸1zM«èõüœ9™UI$‰+ÐŠÔ ¦OÏä8¾¼¿ÉÆ´ÆBª3lÞ\pû¶¡läè(Ú¹³°2) n×PŒ"uÁƒS:u’­® βe¹<ëÖÕC×Ü/-Z-§ÑpëÖå<©ûöÛ*II–僃“`ɇ–-er9V:ò2²eKÁ©Sº+E¢r›èÍ›†¿þ*ÔKëå…¦y†‹5Mš1v¬ºìËH$//*.®R&ímÛ fÎÌìÚÕjöl[++’$±€QŒ"u={\Ÿêôþ—_œ¢£éE‹²§M³­»[e¼ÚLšaeEN™b3{¶]ÕS\¾Ï™“õë¯ùC†¨Zµ’áV7ÈËÆ˜1ÖOuzߢ…îª Këåeß>ͽ{´¯/Ur§‰'We%hÑÂÂÂôC‡¦®jÚTÒ²%JQŒ"/:ÉCCÒÓÙU«rß{O¥VWê˱ÿuÿÆšüˤS# Ø´çþX’/–öíe¡¡ÙÙìòå¹°i“sµïÀ´d‰Ã¥K†öíýý·Û»ï*°Ì_’·AadÑ1¥ßÏ_“û–Ë a«žõëó$¢GÜç¦È>™ÇŠ6œ¢j~ö) „züå—üøxÓ{頻}¦.]ä]ü®m\z,.AÔÒJ „/ƺE1мD´m+kÛV¦Óqƒ+wî,Ôëy¥ˆ GbyˆØ¥mì 1^¡}á´n-kÝZ¦×ó(`úôÌ-¤!!öO©ÍÊÀó°ysþ–-žžâ³g=š6ÅÃ/iû uïÍã…ŠQ¾R±2PïígO¿TS–J‰9sì woÅ­[ƇéNäOmí¼E*HÅä^€˜%Å?}>«v1*Õcß¾Šü|.,Lœt䈛\NVKß•™Éœ2½çÞ»þ^ôÎ"¥(F_w1š››gb0d2´²¼`¬¬ÈNä:É=<ö8Ì™Ó  ‰¯/åì,>^_¿>•Íp°ukÁúwy ~’¼|ÈåD§NrHî:”C’ÙJ%uèл•9W˜qáì,¾}ÛØ •šÊhµ<°,¿paöرêŠGÍ×”¼+Eë8=Ä„Vê”z}€ç öÛgˈ²‡úÿ %`Û®ä_š7—6o.]¸0‚$ïœ<9@,NØ”Mãî]£K¶f`‹—¦ô ”ƒÄÛ4k&/¯¬ÎãÎêõüâÅm»tq+n8õD"‘šÊØÛ‹ärâñcÆÆ†´¶&=b„’¨(še‹Óüë/ÍãǦðp¸£„D,c£˜˜””\öëÙßßËÀ\ìû©†pè¶*øû´i1ùùúcÇšüþûñ>ð¤(B$" Ž¢–a™êœ9v’h8¬°——sçαlμyðûﻎë^IûˆD`4ò§OW·HD„…¡ EJÿ0ZÎB_@Ê¡}Ø3¤Ðà‹gˑΆø•@@ÖIR ¾3ÍΚ7/êÔ©ž—.ݱ·whذñåÎÀ`e•æŒjc egµ#Ï@ÔÖ l™ xŒ{Ù[V|ü±cǦO‡«W¯Þ¾MÅßÒ"AÀ0|Ù!™3:“‰çKHŒÑ£­+9»yÄh||œ‹‹SÙp5MÓ¯oqÜ‚¨Ï¤.à6¼fóÊø¢¸÷QBØÂ… /^¼Ø·oß©S§Îš5 V®\ùÃt¸ŸNNfzô°zøvtÛØü7£4Ÿ‚—Žo¾ù&<<¼W¯^Ó§OŸ>}:¬]»véÒ¯‡­Ô¬ädFø¿MYTíî.V©pé)ò$~  ×ÚuQ­x|”ØC㯋äov˜ppé·^ ¶X,>tèP÷îÝ»wïòé§}ËQxw+£1n± ´òçÕvSr/àt`̬¥Š3¦Áå^e,=Àwö‹mPׯ_¶X;räHppppppLL ˲ÿû_o'§âî+5•aððgd°:çíMeg³ùùœy~üÆÀ@‰ð] …¢×:„)N¸@øF b–@ƒ95›#ÏÀã­ðèWu´Þ@@Öð7œC7à€ämp!VíNl9þó)ßlÚ}y×®]C‡=räÈÎ;/öðõó“øùI aCœ&XÎ4ýÖ§w¡åÎjÏaýúõ¾¾¾Ó§Oß¶mÛü1räÈ“'OnÛ¶mþüù•LÁÍMlþ¿I“rªûˆøÿ<ªxNÿ•X·¯6íáÀå·ÕˆÕ@YõZµ ;ÈÏ×|·ñÊþ L~«{÷î}øða˜yòäàÁƒë”ÜgKm6Ëãl6£/!®ÃÀuCÞUÃc¸6Àº4ZTÛ“² Rþ€~-›®ÝÜfË—÷ã ž={6I’ƒ €?þøWò6P·el8•¡OŸ>kÖ¬Ù±cGbbâÔ©S%‰P'N¬{7¿r/ü'Ú ­| —;fEgÃãßÀç³ øúë¯sss—/_¾lÙ² îë·prPDÍS^M¾vTà<€” SE&SÏž? 4ˆã8°±±Y²dIZZš¿¿ÿo”¯¥œó 0¦ûèÒ%UÔ!›‘:A³õ¯~ÃÈ+cv…Öu±Ü« IDAT§î…äm5š¿D"éß¿¿Ð_ñ<¯V«—/_žœœìçç÷ÿ÷/ëÓ´…ÔÞd_äu£iiiùY k-?™;8»³,}ÿ.PA`¥‰õFI¬| A·,b5“_=¹§þ™G\‡BàÏÐP$Ÿä4<;;;,,L­V÷êÕ«k×®`kk[=9Ò@g[&¬‡‚[O9ÑmÄýš¨—®Å¸û`Ë@¹ˆ^¤›CŸ‰'fee?ÞÆÆ¦_¿~:uªÎzDêÆT0åAþ-H,¡¥»_Ž÷%‰¸Pj¸–¤ `­¹m¯^½ºiÓ¦«V­š4iÒ˜1còòò–,Yb²éÎîöÝ€gjð¦P¥3EQ#FŒ bYö·ß~óóó[²d‰Éd’Ëå ÅÓ<´HÁy Ïó÷ïß/z‚¥bïÀÒ“Aé–ãׂíÀû“§$.÷ý³¬Ü._¬‚x²¬¯ Y‚Eƒ¢z¯˜¬²»Tˆ}á]P¢ê% ¶.:.Û›òÀ˜ tܯÚd¶F @æ R'e÷þûï7kÖ ~þùçF}óÍ74MWª«ˆ>Xd…´¿žíÄÆ‹áÒ›À³rwhø%€¢!ö=(FŸŸS§N]»x|E¯ZÍ”¦éV¯ŽãâââNž ÐÅ?ÁÝ e@€)«z2v çY„9sæöíÛ]ºtéÝ»788TÁápv8hî—îГÁ˜fÍk2XÕÕ“¼ â° T4‘ªTˆã›`åS›×uîܹk×®uìØqÀ€U­G¤ŽÂh!ñg0<:¬ƒ,'=uµ{É¥9¼ î~"´í´BÕ™3gÜÜÜV¬X!9Ž[¼xq=ÜÝÝÿë©ljÿv?~üLjÅâM›6€Z­~¦Ó9ŽûᇢgùîÝ»çÏŸ·èegRÞyÂãoÙ4íƒg¸Ž’ñËíð P4m9KG )¨@Ÿøô7…ÛUšöø7àŒ OʾªÓÌ¢1dî qJ/øcÇCøí·ßÀÚÚºfÛ ÏBâÏÚh` Áñíç¹—ö]‹ ááWª@È»‚ŠÑçdøðáǼG·ÔB^3fÌHOO=ztÏž=7lØ‹/~ï½÷ŠþlUšm°ÓŸá‚JÆ×ÅÏ¢AY™'ÀgÆ“S`µ¶<Æ>éÄjEdvÀ¦m5$Õh@þuÐÜoê¥ßð‘ί†-:*«b¾³@êTÕ¤dîEM"õ¯:¼¸ ÅèëÃÌ™3Û·oïääôÏ?ÿøøøøúú®_¿þÏ?ÿœ4iRE§Õ¤ }~ºEðp.äœކœsEá¶íÁ®S©˜/Â^ò°ÎPús¬¸X,þ„ ÕH³Ÿ é Hÿb—BÀj°n”]u¦¯ tT‚üïŠëQbBBBÜ©S§³gÏ u¬m‡„„øûû¿óÎ;G­_¿¾¿¿ÿ–-[¶nÝ:räÈjËñçóÇ/w8…¨(Y‘â _ÈÕ‚÷Çà64 bÔÿß.Á¯¬|@âyW!geµÍF{"~_Cƒ/ çÜŸ $Uôž¢ÔÕ™…mÐÅa‡„b´fÈ> †ªù¶°ë r/ÈÎÎþã?T*ÕèÑ£=<<Μ93yòä?üðí·ß>yòd+ÁüÙâËðG¿ÂýÒ¾„” -»WeP·ªÃM"ï2h– ¼ tN©úÓ hkÑñ)ÐÅ?!©‚ÛPxçù¯Dâ޽^–bI;láóŸ®~”yžfàP$¼?†ÈÏ e7¨š‚Üd`ßåù“åYHÙanÛþNàÖö˜à[tñâÅŸ|òI~~þĉ===ëViåææîØ±ÃÖÖvذaMš49qâĘ1cÆŒŽ­©ÌÛ^ b5È=¡Gį‚! w•?ˆUõ·šþ0ù yº°n=jöF(; ìÀm8¸ ž[clÞ‰(ýA]…]¹L¹q ë hîUé"Y=¤í­³m…¨©/¢×]ŒÞ™\4\RŧÄõ@PÐø«1cÆìÝ»×h4ŠÅb¸zõêŽ;‚ü“×Q–-[öÆolß¾]øùÁtê4¾´J»b¹V)ãpÑ| |gBì²R•äYãW|¢¢¨ m¹ÉÊ=AêhØà ºtèP*•zïÞ½üü|ÄýÒ–@Úò×qd øQÎÌ>ûçgr?仆]7·g½cshø´ÖwzXaÅ^Ù45¯@ ß Aþç´V‡ÑPKÿý\@iÚ›€ì$ÞÙ[eá á–ÿ™GT`{‘áG9h¯ ŸA 4²$‡úã§Ú%šÒÛ ø&ý—êËÁ‡¥ ½–ß_-ùi@Ë¡/c娺ºšF£EEEMœ8qýúõ¬/,,¼q嬗Öú^¼) Þÿš¦.™0a‚²²rkkëСC±X¬——WAA ?¶Ã¼¡¾¾¾½½ýÍ›7úúú«V­êèðhllÜö÷Ÿ€®vQÛAþqú/Y ªÅcËÚÚZ …òüùs55µõë×êë—íÙ³g‹Æjzú–– /ü¼µ¦LДùËmb‰@T“ùŽíu ­ h ùwú_G¡¯1¸þ’/Ë ½ÐZJ/I—&—è¿ÁàÆèÿ‡#Šó ú9Ààþ~ ü;ÇNTD¬§ý|822¡qqq}}>ÑlÎþe¥X~&;Éý®\¹ hnn–‘‘‘‘‘¹|ùrNNŽŸŸ_×g„Ë%Œ˜\¤ÿÀ&ÝÝžõŽâú@Á®W‡ebaL?*@C*h-Z›º•»ÓñºÈOÖ1Ñ€ü ¤º–U?åxä§ÿÌÖÈYjÁR èøó\AX+q} ü;x=á?Q4ä\úYö–BPO¿™òoÌccét%ù“Ê&³ Ò£éíB1]$.ðíÛ·GýñãGRR×ÑÑùðჯ¯ojj*ÇÞþ„ÖÊüòæ²'K¬©ùŸé **Êí0¿òõë×ãÇ—––æääìØ±CGG'??ßËËëòåË@\ƒ~ëžÉ²Ò( ü>ÓºÍA>|øpìØ±úúúÏŸ?/Y²D__?##cÅŠ>|BB]çk@\ËX×1  8P[@ÅcHœüŸ1käƒÂ ð㿇§v;µ pssû¹yuõâÅ‹ƒƒƒÝÝÝòkÕÑü³¶CFøÿ ÐÀ9îÞ½;gΜ3f Xׯ_‡Ùä9µí—ç8|+ÐÛËñ9w¡á¦M?û»ºººåË—Ÿ hPýœG7¢`èh.ikøÚª@¬9@À¾ˆÊðXB§YO1X€Á*Ã$AÁ)Pö/0ê+€êb( EÁ £þßÃXmý¤ò É€"3HÿšR(ïR, h-¸E6ôíè訨¨¸téÒŸþ©§§·qãÆnŒ à>8®££ƒL&·µµV¯^}àÀmmí¹sçrÌåUŸÕÖÖF&“;::ÚÚÚ¼½½MLL8iŒB„Äà ¹µµ¦€&ÚžI¿Y’½Ï¨Iðÿ[ÑþIãg¾ù—o„éSù`p@Ò„cõs@¿|’¡³¯_¿€l^^Þ!Ï-³'ÈIS@!w*8LQ ˆ5ñ 0·ÐsŸ“'OÂìmöööûöí;~ü¸ 2èЉ)†{÷•²sç@u5f®Ù!?÷û=?š„Áµ«!…Ç·òøYòÉ“'ÅÅ?||V/“Úû3¡<–†ÎeÜAHƒªgôßûƒþM‘ ÿòMùCú„b:ôiµ¢Ú\W[ä* Ÿaîõÿ¨~ ê}¾Ê ÁÌføñÆL°pẋóVVVóæÍ“””¼uë–à…ÐK¶lÙ²mÛ6¯6aÂ___Øò#A«ý…#GެZµ*?? //¿téRx#QQQÜ;é† òòò))) n©cžÐóÑýg+ÚO‘4â±Á3ÑŒŒŒëׯÿþÝÀÀÀÕÕÕÕÕµ°°088Xwîb0|8¨K81vó¤·ƒ¦¯œ\»ä?tuuÑïðŸþùçŸ îΨ¯¯?pà`ݺuãÆ‹ŠŠêèè˜bk ÆLìG7RTTE·mÛfgggggWSSsôèQ333`²ìçFÔ ì>ÓIßVêS€ög¹pႇ‡òï«W¯¢¢¢Ö®]Koz6eüÔ@SûÐÚ™/†Xw¢œ‚jî ˆ;.• ö 6´±øC ŸñUt`½púßÙ¦L™"xépŠÝ»w£ÿåªõÆUΜ9ùwï^JJŠ‘‘Ñ‚ NŸ> xòäIrr2[;› êÛ 6F9²hÑ¢{÷þëØ§M›6|øp6ïÆá`Ä’ÿgóæÍPR{ëÖ­/^ÀÞ€€€þu#~~~påwÆ °]¼x±‚‚‚‰ jÙ+Ì*þ0ÈÏ`}–+W® ÆhFFÆ£Gf̘QQQqèÐ!z4q}&£¾–Ÿ"t´×‚ï!@i>“Ÿh4åÔ—s¥ÔJBÌønŠéá¡‚·F€€~Ç£G mmm?þîèè˜àááåÃŒÑ.èèè(++#‘H€‚‚ii餤¤ýû÷GFFΞ=[ðÈô†ÌÌLé%--]]]ÝÚÚzþüù˜˜˜]»v±¥?À7äææ"7RZZŠÃá"##CBB.]º´lÙ2N…J¥Â³¸»»»¹¹íÝ»Áîþ"ê‡)ØwºWoôáY#K¼ ÊËË¥¥¥I$’¾¾~{{û§OŸÆ_XX8yòdAJ1Ú5D"ÑÄÄdïÞ½%%%’’’ÙÙÙ‰‰‰BBBííí?gFèöööТ8::Þºu ÇS(zMÖ>¡>‰²é‚bmm oDBBÂÂÂ"::Æ7pvÀ†ÅbaÃ=mÚ4gggaaá;wî”””ôëôðGFFîÝ»·££ÃÖÖöýû÷>„-§ pÆh׈ˆˆ¬Y³&%%ELL `cc#))YSS£©©©«;øRVł܃¬6ÐÝÛ«äiƒÕ«W¿xñ0qâDqqñ äçç2Ä‚§¯}²wvú«„  ¶° ÎÃà€ÅO5Çõë׿yó¾#8ŽH$–••©¨¨q1‡ÊÝ»w+**¼¼¼I@×¼·´ŽN•%á[…ÔŸHqu=ß]k#³áÙÅŽ=š@ +**šššš››ÇÆÆ"3c”]†:cÆ )©Ÿ™?---é³Mú FßaµMæß€ÖˆÊ€¨*xØH$ΘñŸ£¤žž×Ó½4~íu ô¨ydƲz <4Vý7­$ÀÐ@~†4N }#¦¦¦Ü¸öáÇÃeú½{÷~ûö-((‹Å†††:88&GtJÑ%PõX>˜Î{¨ê8w ±â ¸Œó£ Ô§€Öï?SךÝxéžíÛAwìgFJq}èz!ƒs‡n0ŒQlc~§ksä¾àDªÕ”?RpR@é7¶å£YÊߎ•Qàû€De 0·72Å]üKHibb¢ày èµe]‹Þ JÉàûe0Ä (Ì”?Òø|¿ˆªœ ±´×, ªq½Ÿ öŒQü…Â\ 2 ´ô @s=Àak/ƒ ÷ hø"0Fù…¡³Àheð£|Y :~ÎÀ$?ÈϵoÀëq@T‹«Æ¨ìuDb?§ü3ÿêBÃÒ| oR ŒQ~Køù³¶ƒÆt gÃá Lxi0ò¼4¢ZcT`Œ àKÄt€˜ uU{4|¢@X‰Õ.-E ) Ðh`¨`‚oÕ¢Ú€FùÙ%^ ~” 7ˆéôîÐ4ÐôrØ–œ´ ¼ô=üO¡.9kPŸ Ê€âº`:Ý¥£´ƒÜ `zMP~|ó…þÿ§Z(  $ ¢t¶¢ ÀIôêà?JA{=¨{ ÏÓþC€À͆½½ï¼RR?NžÉ Ó#m Z Àrhú ²`ø_‚bãÇf0ЬrãÆ }cþ”粚(ÿ}©ÑàGi7“|Ð@]hùq=A à;ð20!ø£Sg,ôÃbM `ÊFàöÐü Œðx)A±ñßs” Ϩ ¢¤ÃwNãl\^¦WÇ$ç¶* m1 S! À Š` ²7\§å°Ä=–øß_é]ÐRðó³ÖF%ÊïÏqï^"‘HÔvüWñ—çXþ/hÎùå›.ÿ„Ä€ñ9`|N`‰ àgÂ:²E¶!±GQOS?eüWsÿû,3ŸD^ò3<ÈÈÈ Êè<«Zø>۽ƊñO}90>ÔW v@"˜8466nß¾=99f–÷ööVTT¬©©y_z¨ºþ·]{-XaA‰ñ'MMM;wî|ûö­••ÕŸþ¹víZEEÅÚÚÚ;wîÕ£¨çX„ˆK”˜€þ•J}ðàÁÁƒ…„„nݺ5eÊ"‘ØÅ~ª)&h™Õÿ/ÈOŠ‚ââ[h4ÚãÇÿùçÀíÛ·I$’Љ'*©z@u– ˆt†`ftàpîܹ)S¦ÄÅÅÉËËß¿_QQ1//oÿþý0Ùãàe–(?séÒ%KK˸¸¸aÆݾ}[QQ±  àÀ'Nœøõ9J ,Qƒ†††‹/ÆÅÅEGG/\¸PZZšH$^¼xQCCÃÆåš"°Dù›ÖÖÖ£GÆÅÅÅÅÅ999III‰ˆˆ\¹rENNnÖ,%*@`ŒJªªªÎŸ?¿téR%%%Aiô_êêêΜ9³hÑ"555Ai$9rDAAÁÙÙYPýš'NHJJº¹¹ ŠBÀ 2F:Dú?ììRQQahh ÿ%“Éÿi†üøñСC¹¶%K–š››;::šššMMM«W¯fgÎ ""âÞ½{ð,XºtiLL ‰D‚×¼lÙ²°°°•+W:88ðò)øûûçåå¡ï~HJJ:vìØÊ•+,XÐÚÚÚÖÖÆt÷¶¶¶ÖÖVºrƒ¤§§ïÛ·0iÒ$ô^4­±±‘L&×ÔÔÀçØÞÞ÷]µjUKK «bGGGss3ü|÷îÝëׯS©TÀ®]»²³³á÷ÎÎÎŒû.Z´(!!D"Á›õðð óòòâl¢N6ikk«®®†/ÅéÓ§ß¼yóéÓ§   ô6‹/†Ušg4440VºŸ£GÞ¿?ÓÍX|ÓØØH£ÑÞÞÞµµµðËiÓ¦ùúú677S(”¾jß`%‡o:F»páB|||FFF`` rãýõWqq1Çí‰wïÞ}øðáðáÃð›7n|øðáÃ$)!!g%üùóç   ÆÆÆúúztuB?wø ™Lnkk[¶lÙ™3gaåY·n½½=r´ÿý÷îÝ»ðs`` ì’Ž9’’’ÒÞÞN&“éª_kkë?è.éŸþIOOï“× ¶¢è殿S(¤q£ƒH$®X±vÁ4íÚµkAAAÇŽ#‘H0qo`q…èö÷¼}ûöäÉ“°ƒ8yòäóçÏá÷›7oÎÉÉA6{ò䉡¡áׯ_‘obcc‘•±dÇ-[¶”——#›EGG_¿~1f`oÈ´ÅÛ²eKYY™Àå>>>qÿG_ŸU†îøøxø¡½½=-- yf;vìHNNF6#“Éè'ݳ×ûÓ§OhŸ­]»611qùòåð…),,„}Ìëׯ333+++0gΜººººº:ÄÂëŒ!C†,^¼ØÇÇÇÃÃCUUõÁƒß¾}‹‹‹‹ˆˆàåS())AšTäšóòòÈdrEEEaaannîéÓ§###áOÉÉÉhcñáÇgΜㄬ¬,x„¬¬¬ŠŠŠ––øþ|ýúµ´´499iЫ««—,Y²mÛ6UUUÀÞ½{á¾Ðä%_¾|Ùºõg®ÂºººÅ‹çççJKK‘ÂÉÍÍ-((`ÜWVVÖÅÅ>Guuõ;wîäææÆÅÅ!%ÆK¢££åääÞ¿ŸHsssKKËë×¯Ñ Ù‹/Ö®]ËË«²¶¶NIIA*ØçÏŸëaΜ9ÈfðýEê!™L†/8ãÛ„|ãää‡CEEEˆ ’••U\\ìãヌ%*ʳ»nmmýí·ßùùù4­²²²©©©µµ> xãÅÅÅèa^ii)º“ë•••ñññÍÍÍHcX__ÿâÅ Ø©_¿~ýæÍ›¥¥¥3g΄%'' ¹²²yC YØñBBBVVV>>>6l˜0a²eË âãããââÆϳ†-ÌâÅ‹'Nœˆ®NÞÞÞß¾}C³k×®·oßæçççー°Ù ¾øÈ`¦¬¬ V*ØŽ%$$&$$ e’——wùòeÄxE€;–——ó ¦!ï¼ØŠ"}%RÓ²³³7lØœœ $h0 ‰Dòñññññ™4il÷^½zgee…lÑeÖËæ÷ýû÷ȼFkkkRRriiiÈ£yýúu\ÂóÉd2ìå“““׬YÇ–€ïß¿OŸ>m6¤¥¥!O¡Pœ«ªªà¾ÕÕÕèÃîˆ3»ví:t(cû)..†#Æ>ðx*aP£ìó÷ß³¹åóçÏ{30ÍÏÏ?wîã÷ááᥥ¥HUóóó ûôé6õ˜²²²ÜÜ\ssóI“&õañ655]¾|™õ6!!!pÖêðáÃŒVøÉ“'SRRîÜù™úòÎ;Ðø@säÈ‘¬¬¬7nÀíYœëû÷ï÷ïßçe ôò9–——çææš˜˜À‰"~#""âÝ»w¼?/RªåååGþËuáÂ…ŒŒŒ .À¡Ý©S§ËÖ¥ŠŠ ôŽp&ïüùóÝ?ƒ½ºŠò'ïÞ½ëeÍÿøñã­[·‘‘‘"""ùùùŒ%öêÕ«Ç3î~úôi6‡‚d2977·°°0 €K²±±ñÊ•+È çÙ³gè_‹ŠŠþý÷_ø9!!!55•¦`çÎmmm/_¾üòå ë³§¦¦2Ú©}ÛW=ztÅŠL úÜÜÜÜÜÜ={ö0ÝñæÍ›©©©¹¹¹—.]âêäÜêêê¡¡¡YY•¸< IDATY‹/FfÙCBBãÞÏÏÏ××——Ã{ô€aáÂ…È -#FFFX,öãÇ,Pcc#‹n]E’’’ÜÜÜ8¾–Â=c”+'Nœ3fLnnnoÒÑÑáëë[__þàÁh}FGGÃpâĉɓ'#‡……ÁråÊ• eëÖ­hC-66v aooïãã3uêÔ¾*±GEFF644lذáêÕ«ÞÞÞL·ü÷ßCBBàç‚‚‚mÛ¶Q(”•+WÂ…¡°°0ô œœ@/ß#¯ß£GrëŒŠŠŠØØX …Ò™oÇa}=ìLQøøøØÚÚömýojjºwïž««+€J¥¢=X¶mÛ¶{÷î>/Õööö{÷îActûöígΜY»ví‰'0 …B©®®ŽxzzþlÔh4XÁ–-[w„¿yó†nÜøàÁ<|“M74úðá äYƒžÝj/¼µ‡Þ½{·¡¡aóæÍœ:c||<‘H„áï¿ÿþôéÓêêê.÷º}û6bŒ².---Ÿõë×÷UmG_ ŽŽ¦Ñhÿþû/™LÞ°aÃõë×i4Z^^Ý`¬¬¬ÌÓÓÓÎÎNRRòÓ§O¿ýö²¤Š4e H£‡œ499™½öóó+//§P( ÅÓÓ~àY ÔÕÕmÙ²åðáÃß¾}CJyñ‘w‡5pfƒaž° **ÊÉÉÉÇǧ²²’*Ôƒç¸råJøv£=ª¯¯ÿúõë‡Ð[¾ÿŽ`yFGGÇû÷ïáŠèâÅ‹ïß¿ÌqΘ1ƒq¦™Å=BW"ºáÜÇÑíú”••!ÀwïÞ8q¢ŸŸ_zzúçÏŸùÄÜ0±¢¨¨¨÷Q#gϞݷo߉'æÍ›WUU«Â‹/á) #¤¾¾>&&fýúõIIIgÏžŒŒÄbÿ{Fµµµ½tà6ÕÕÕþþþ«W¯®­­ussÛ·o_VVVNN¡¢111!ð³­­íýû÷/^¼¿páBø^ÍûKŠ¿¬¬,*•ZXXXQQnMèkffÆ8‡ þˆˆˆ_"sy™L®¯¯WVVîõŸB¡TVV¸—/_25:¿}û¦­Í£D²MMM]ú‚c±Ø»wïgee9;;+++Ãà÷ïßKKK‘Ý«ªª`pLff&z÷ÒÒRdÅÉÌ;÷Ò¥Kè/¿~ýŠv>{öìÙ÷ïßÜ®`ÕÕÕÐ~üÈøÜ{†¾¾>›¡ÝbÞ¼ybbb¢¢¢ååå™™™—/_¾zõ*ÓáÜóçÏy9)ØÑѸmÛ6ø¯¢¢bUU…B)**’——î†Ä““c— _L2™ÜØØ%%%5nÜ8¦»WVVJII¡]JÆ(‘™™ùúõkÞœkõêÕZZZH÷ieeE£ÑâââÒÒÒlmmg̘!..øë¯¿† ÒïJRLL, y‚ƒƒסvìØ!))‰¼Bþùg—‡}üøqKKË«W¯o6nÜH·M``à_õŒpp0ã8ûû÷ïéééŒÝð“'OfÌè)Xmmm£££ùáJ Ž;vûöm'''› 6 ‡Ã!³M7oÞôööÆb±hç*¸¹¹uédræÌ™ôôt¤“c¬‡\"99ú¥ g¼xñ"2rFŒx òDššš¢¢¢ cknn.ƒÑÔÔì•üÅ‹°o†îûèŸLMMG ˜4i:> ðéÓ§‚‚‚W¯^)((èéé­[·îرc¾¾¾ÞÞÞ€›¥¥¥ÉÊʰ?ww÷ .lÚ´ cŸ={–Å…Íš5 ú?ÄÄÄ0u1ç*7ntww\½zΕîÚµ‹©Ä~ÖÒÒ’‘‘À²âÆeGDD¨¨¨())Án´³I"v:ŽðõëWt·EǃÆ/''Ç¢gY¶l;'š4iRqq1¿Y™c´Ûdee%&&rãÈÛ·ogaSb±XèâùúõëC‡-X°`„ ýº$EEEýüü,--‘oŽ=Ь×ÿñÇt~TŒM‘H„¥h¢££ÙY¹~ÿþýµk}®úêÕ«ÈÜðáÃUUU_¾| ÿõõõEÏî…÷Ó´=cêÔ©OŸ>åŸë‰ˆˆ€« AAAEEE/_¾„ëìoß¾…‘¤BBBˆwÍ­[·þøãöµ\\\ ÁÇšöövv6ã6h»922ÒÌÌ ×ó dÙ‡î{0ÑÙ,)¿/øÍ›7K–,‘ø/‹º‰‰‰©©)‹î?11144ÔÏÏOWW0wî\ºW;##CFFFQ‘‰Hª®®îüü‹vz©««Û±c‡­­-\½}þüyQQïKFa߸qƒNCôÈE'55USSSZZšW>þ|Fc´©© :YÒ 8o޼ɥ޿¹¹ÙÉɉNâÌ™3«V­bº}MMÍ‹/ž?Žt‹W¯^…¾RLaì\zLg>uc”óÈÈÈx{{/\¸ñ›ÎÊÊ1b—N—‘‘‘äïï/,,¼téR …#W¯^mhhȸ‹§§çÍ›7™Z®íííh­¾âܹsBBBtmåáÇG…Ì. þ:Ç·³³C N!m½¼¼üíÛ·¡N"‘Μ9ƒ (=z$** prr‚ÛtFMM ÝÏÜb444à©ÅÅÅEDD_==½ÌÌÌÐÐP(Àç´µµ±®i***åååL]HyÉׯ_ÕÕÕ_½z—Èkjj 3äñãÇ"""Lwdt-(((PWWŸ2e òMII‰¼¼<œ$1b„ŽŽŽ­­mwC8H~~þ¤I“è‚„ $%%‰D"ô½+--•‘‘¡›ØëÿþûogªvÞÞÞ0,;;;!!a̘1ŒÎÜt+** ñyÍß²eËþýû MMMáú¸¦¦fppððáÃáDûÑ£G‹ŠŠìììöîÝ»mÛ6d†¶V•••‡úâÅ WW×·oßÖÕÕ1:úKJJb±Øººº”””I“&­X±BZZúÛ·oè•k¨ôB·cCCº’sŠÊÊJGGGtz”èèht ,Ò˜#Í©¾¾~|||o‚ôõõ333óóó]\\–/_Î%k[GG§  vôp™Ž@  |ŠŠŠ¸áÀ ÏÈØ±ðnjkk«¬¬´²²¢ó±QSS+..f „ G.5>>­F"0F¹•J¥ÑhT*uÖ¬Y0ðeÇŽ;wîäÒéþüóÏ€€€7b0iiéÙ³gc±X†Åb1 Ó(K Ž‘µÑÙ³g~ÿþ=''ÇÏÏ? –*òï¢E‹Ð÷‚¼K8·Ã!?}øðAKK Y¯‡ÍS}}}YYÙ˜1c\]]]\\àtr(*•*//¯¨¨˜––æå奥¥õáÃQQQCCCÄ…”D"AgíÄÄDsss$*¢¦¦&** €ˆ±q–U«V±07i4£×9rìØ1è%ÖÎÎÎ>DA¤¥¥ÕÕÕ¡„7 ú矘º?îÞ½ñÁ¼|ù†Ž?¶õ–––Œ£Í}ûöÑ­Ð={ÖÓÓ]‡ÃÂÂf̘]>¶oß®¨¨ˆÁ`úðñ?~<==‹ÅÆÅÅMš4IMMmòäÉAAA&&&***h :ë¿Ô åÍ›7¾¾¾¯_¿FîJ¥"/#FcŒS™2e GÄõë×íííÅÄÄø°¶#MÁÂ… ±X,â£Åbÿý÷ß¹sçb±Xdò ƒÁ`±XMMÍñãÇÖ¼³ÃÊÊÊÚÙÙ\\\芃Á8pÇkjjâñø… Nœ8qóæÍ±±±t󦿿æèo>|øÀTž¥—DGGGDD o>n¦AHhyìèèèÞÈ5úúúž8qbÆ ¾¾¾ÁÁÁÿüóÇ×µþúë¯sçÎݺu«ªª ½¶F÷øîܹèóÊ?,[¶ìÚµk………MMM:::ÝÚ7,,lÁ‚Lš9s&zˆË{ÄAjŒ"ÌŸ?Ÿ©R†»»;âƒÅY† ]©ÄÄÄfΜ ¥aŒ-Z´gϵ··ïèè ‘HNNNyyy[¶lA†ï|^¼Lã.aË;qâDt`òÛ·ouuuÑ«6#Gެ««CÖ <==×­[×ÚÚ Ý¶ T•©S§ CÖ¸ÚPàp8YYÙÊÊJ‘ððpXÍÉQ)))QQѲ²2qqq))©;v >\CC£7g”‘‘ÉÎÎÞ´iœ1bĬY³Ð öRRRœœœÖ¬YÓ­#6LIIéäɓ۷o—••EÿT^^.,,]¼à˜1chè÷úË—/Lc@ÅÅÅ===9•uR`ŒvJKK S²éÓ§ûöqpåÊ•ÜX¡ÃÛÛÛØØ˜Íuttêêê¸ÝÏu tê¼Â‘#G"¿âñxSSÓÎæÌˆD"2={vzz:k?QQÑE‹u©¢ª¡¡Ø£èaqVVÖÌ™3~~~%%%¼¯iqïÞ=þ\¾_·nZ"ÞÓÓ388-ìÒÞÞ.¸}%fffZZZ²²²rrr_¿~Åb±BBBt3•¹ˆˆƒÁãñ¢¢¢8½#ƒ!ppB¡Ph4²:Áˆµµ5œš4iR||<‡£ÑhK—.MMM5jÔš5k‚‚‚ZZZ¸$†¯®®NW·¡#5däÈ‘pœ0sæÌ¬¬¬/_¾HHHÀ+ìÖY~üø‘žžŽø"'ZºtéíÛ·óµ1¢¦¦†¯š&6òÆÈ¿nnnè‰pÖ ;88°¨3ÐÈ#d2944§³ ¤¤äÍ›7iiiHcH£ÑÚÚÚ!<î}É †мMÊÊÊÁÔÔ=‰ [o%%¥;wîTVV¢ÓN² ¶¶¶¬¬ Ê·OBB‚îÖÝr9º§`Mrr²‘‘r@"‘8}úôμVàDx·4•ا¹¹>|61))‰«á›7ofŒúEPPPËÍÍ¥R© Ç744¡ûk¦…/0F¹‚†††’’—‚æx€©©ieeeqqqJJ S ±c¸øûûýú¾@ LždtQ“ˆü‡spp¸sçΉ'œ¹äÆÚ³éŠ1cÆÀ–é°ïÞ½ËZP‰«L™2ÅÈÈHIIIEE°NÞÀ1ƨQ£`”=;HJJNœ8±³Õä%K–0UwZ°`Ì’2oÞ¼ÈÈH"btyž8ÂÎ;õôôЫótŒ7-aÑcÈdrbb"›Ù¿þøã33³ÒÒÒõë×ó¿šëׯ/Z´èË—/T*™Wî.üñkcÂff)v6Û³g÷’9::ª««#ÿjii Ož<Zx7nD»ø›››ÿþÍ¦ŠŠŠ‚‚‚nUÑÇ?Y ë’ØØØ‰'"“…ìcooöë= +W®ŒŠŠ:{ö,z´3cÆŒ˜˜¸œ¸eË–Õ«WM˜0AAAÁÀÀ€#Î---Ož--©obRR:jò755áp8111]]](TnddÄ?™0ˆD¢ªª*zíREE%==n ÍŠ‹‹é^¢S§NA~äƒî¡ŠŠŠèI—.ß/55µÎ4áMLL3ïIHH ;E!!!'ÝesƎͦ—())Á„ÆHdÒëׯ¡#F«©©2dÈÝ»wé|åtÝdòùóg##£ÊÊJ¦  ÀNщ‹‹Ãv6VPP@féX<>eeeÄ]•õS†ÓüQQQW[Û¿?:,fÊ”)L³a7ŽKS‰–––’’’ðsrrÔÔÔFŽinnÎ:û 4Â:››G‹eêV¤««;zôhή˜ÁVTLLŒB¡dggÓ5e&LxôèQCCƒššš˜˜˜¼¼|~~>ÝAªªª%H•••‘KÅãñ"""ÈúäСCKJJrrrºl éjÚ‡Ð.Ë---\’£]cnß¾Í8s¶bÅŠÐÐФ¤¤­[·²ïÝ\QQ#»§»èüW:cĈ;vìäeÆ tÁ¤pDž€ÔÖÖfßA¿‡7nÔÕÕE›\½ö=P ÄÀÀ 77·¥¥iÜ_¼x??{öL^^ž}÷Œ>§[‚š‰‰‰l.۱òeË‚ƒƒÑßHIIÁž{âĉìO™°k-R{{ûî½|ù’qQ›Û°Ù°3¼¤Kz‰.%´r0#ííígÏž]³fŒŒ ]exþü¹––V||<ÖsvŠƒÁÀ9 v6Þ½{7;²ÿ'Ožd!½ ÜÜÜ<))É‚H$BÁ»/_¾pP_RR=¿K :S?`_²·gàñx ƒ^,ÂãñH[Ú©©©Œb¨tOVRR­`…Jjp㎦L™RWWgll|åÊ•.7~öìzQ"((I‘€púôi///øYMMmìØ±ˆ_§ò3¿{÷îÈ‘#c”»üñÇ=èÃlll’’’ØL>‘››ëîî>yòd´GW/‘’’Bkjð%%%¬½ò¹Çرc;‹lE`\N]±b74#‡.""ç8§Núþý{$iäŠ+xà‚Ìܼy“zëÖ­£ë—,Y2bÄôKñÛo¿±=Yµj ƒÁ\¼xqþüùMMÍÑ£G?~¼».%ÑÑÑãÆƒªé.\àÈìBJJŠŒŒLgfÍ´iÓÇl½ÇÉɉé\Tº]]]¯]»væÌGGGºôª¼§¥¥&¬Âb±ÝºÂp<¯ÛܹsÑ¡NÊÊÊÕ4xyóæÍ G"ú111LSsÆâÚ»wo¿hš\]]×*ûÕ‰…þæÍ›‘´^ÁhŒZYYÁÅ_(qÌt›††´gL]]ݘ1c ºœ!|ùòeĈ½÷:‚qhu]¸pÁÃã¡¡«!á]ÒÖÖV\\,**úíÛ·šštØ5aaa$ †„„7³³3£JζmÛÐÍ´ŠŠ úY@`öadúA[[[DDoãæÍ›H` ’x‡ÃáñxaaadQŒJ¥ru1B^^ùlggXéj:Ý Ÿ ""ÒÑÑуD)=ê2—&›ÄÄÄH$$úÍÚÚZXXýÜD"½ØdffÆÂ¹eÒ¤IМ•––†k[ûö탾’’’AAAFí 2dÉ’%êêê .ì,¿3t¥{Ä€ôôt---¤ž#Ú@½¡°°PTT®ÖùøøŒ3ý«¾¾¾™™ ÍËC à\‹\…]VûÔÔÔºº:kkkKKËÎ|àˆz_wÑÐÐ8tèÐÙ³g“EQQ‹Å†‡‡‰Ä>”Áÿøñ£¥¥exx¸‡‡t ›;w.£ßä”)SÄ6PARRÒÚÚi,,, ÑIçÊÔÇmÕÁž’®·PVVÎÍÍ500@ûjkk›šš‰D555 qãÆEGGÇÇÇCŽ3a´K¸¸¸8£U}ðàÁgÏžñ[r;;»˜„€Á`èÂY&MšôàÁƒúúzº˜ëææfd2¸7P(”½{÷ÆÅÅÑÅ¢!iñ455Ñ=S— höï߯­­­­­=kÖ,ø¯¯owCK‘”²²²b|Ž×m`ôkHÃv«L˜‚Á`àëƒL‘’H$$ªZBB¢³B G$*[[[) ׈zÏöíÛœœ¤¥¥GŽI$z½Ô‰,–iFPÆaöرcñx555??¿­­ÍÆÆ¦Çá)ÍÍÍFFFè,hvvvœívÓ$ IDATöììì c(‚ºº:£žygÈÊÊB_CȺuëྣGVWW———·¶¶&VVV§NRSSƒÅ››Û³  ëAyúùùÁ„¨›6mÚºuë©S§ØI‘•íì쌈 t7ìéö8yï>þ¬¥¥Åf^Ðòòò––/////¯ªª* ›ž&•Jmnn>>t¢iì·]ëÖ­cg¹œ²Y0SRR’––Ö÷ïßkjj^¼xÁÎ ëòC/5õ>~üÈþ‚ ­ÀÎÈÈÈ ‘H|â‚_XXxíÚµµkצ¥¥Ñ•sg¢`êêêBBBèY0[[[:Í ÄKÁÚÚyÇaó‹ìˆäšÇ`0ººº4 úpËÉÉÕÖÖ" •PXàòåË GåÈÚšÀ펎ŽÈ˜`×®]†††ÈøÝÁ°?'aaaÁƒa÷ªU«XDÞANœ8!##SQQáêêEH$Ò”)SrrrzlPîØ±ƒõüß}]\\Ðߟ>}š#Æ(ݬ—011innNHH@âXýýý?}ú4qâDEEE—àà`t؃ÂÃÃ7oÞÌÁkPRRb_d¾»tY±û ÎÎÎ7oÞä‡+¹qãÆŠ+Ø+ݳgOĹYx"ý1ûæHHHHgÎm›7o^¿~}ÏÒœö IçÑÿÚÛÛ?þ<-----­7Æh`` SŸcŽsâÄ ÞŠŒ£n==½S§N!ß,X° ,, ­'@ÇåË—Ù?>Ï@jÝãcÄÚÚ=åO$Yäë¢;š““]$%‹Å.\¸ðÙ³gÈÜÓÒ¥K{à½'++˘疳 ^Q;;;Ä^´±±Y»v-z€B÷nÃXÇf4ßË—/ÏŸ??qâDn\9ƒÁáp«W¯Þ½{7kàGmß¾L&;qO9uꔽ½ýÊ•+™ê²I¥xôèÑ7oÞÀÌì$ á+$$$àÓ¿yóæ¬Y³nÞ¼yãÆ º‰¬ l†3KHH å9V¬X1zôh¸o—9ââããeeeaøøñã7mÚ„œT^^ºŽ©ªª†††Ò5'N¬««ë½ÿâ‰'ye99¹¯–2¥££ƒF£?¾©©éï¿ÿî“xÁ.a?VÃÁÁaÆŒ³gÏ~ðàƒéõ3yòdìÜc,--»LD Ù²e \ßggÀ€þ×ÆÆ†é|?²‹577×ÕÕUUU555}øð!/•Jmkk£Ñhð-£‹ö;ôõõa{…Çã™zò†}ûöõXð‹÷îÝCÇMΜ9™óã:::±±±=>®]»èÜë¡ñ°zõjv‚äþþûo555ø™@ Ì›7ÍóNŸ>ih#c£Ä4=•µµõï¿ÿŽ6 5ÖŒŒŒ¥K—feeq» (c433óéÿér-[^^žq$[L:2hlÁÜq¬›››[[[ çØ©=3¤ ‡G—ë•••âââúúúâââˆb``0}útP©T$¢°°p̘1222%%%Ý ]âŒåååKKKcbbzœÔêéÓ§x<žM_%‡vHWUU•””„š#]6µµµµx<žµö ‘Hd 8•‘‘ioogí9ÚÒÒÓA±@OOÌbÌžóÙôøYøøø|üøQZZšB¡ð^+žýgÍÎf¢¢¢$ g7oÞ455¥R©•••………=8©ŒŒL—“ެ‘’’bÓ ~ذal®Ö±ôƒlfdde´‰D¢„„Ù_¹rEXX8,,ìîÝ»:::ý(åSÄÄÄ _ÙÓ§Oêêê¸4÷Á#FŒà†±Âû¨2QQQ"‘Ø›œ¹¹¹päO§©®®ÎŽfZŽ#ÈÈȰ£? ++‹ö]ÉÈÈÐ×ׇŸ›šš¯^½Êí„LÊÍÍÍ}õ{vG'>º{÷n6=îóòòÜÝÝy¦Ô“——÷üùó.7#‘H±±±ˆË ‹=xð`NwéÒ¥üüüŽŽÿ~7ÊzXÉ4G7@OPiii±™ã±÷ØÚÚÆÄİؠ¤¤¤[ŠÊè8€½½ý©S§øJÞ¡QWWß°aÝ—¯^½Bt °æòåË,‚ü$$$ º»°cooäÈ''§TPòòòè𦞠Tzï\”™™ÙËX‹^ÒåÊ÷@+ÈNŸ>ýóçÏÅÅÅüP=LLLк(Ý‚D"%$$tWÛU`ŒÀ¬Y³vüÄÂ35 _¾|éææÆ j¦äçç#I&»‹««kXXX·”ó/]ºTPP@¡PvìØ1ŒQ[[[MMÍßÿýÚµk6l ÑhÜ;ºiÐÒÒb?ö³©©éÑ£GèÅ”naccÃÚí%sçÎe'Ùk¶nÝèáá]õõõ=П:|ø0£QË%ªªªçÎËÅuåÊ77·Î~×××ï®1:wî\uuõfŒÊÉÉÍ™3篿þ:|øp—^‰t<|øÐÂÂbĈ½wþÎÌÌtssëI ¤ÂpµÝîÒî¿UHZZÝ4yxxÀET‰”˜˜(0Fû+pÕ•7çba^äåå½xñ‚…¶å°aà »5šÄb±l.Sö;°X¬ššZ||üË—/û°QcAGGGii):”›ß@ü[ôôôzæóðéÓ'cccmmí>ÉsÈ „……¡BrrrJJJQQQrr2û»ýúµ÷:D"ññãÇþþþ»víb!aÖÚÚZUU¥¢¢ÂÎb GhkkCk>ð€7Ș™™mÛ¶íÂ… ìïURR"++Ë‘uaYYYÖ /`øQ/Ï‚¨ s•¬¬¬ÔÔTŽJSS“ÍeÕ>„@  c ´´´ÐùÒaÒ;wî š¬c´°|ùrnä‰fQ×1LAAãO4F£qd޶­­íÎ;ˆ ?ô÷¦œ;wNOOýðççÏŸ—––ö—»ë²?øòåËçÏŸ{¢   M›6±¿ý7Z£F)((ìܹ‹Åâp8¸˜pùòåÛ·oóø2„„„°X,›#Ož~ppð•+W8Õñ³SÁ°Œƒƒâà+))¹iÓ¦’’nûö1…D"±Ž±£R©½¯WX,–Åhª—A~ïß¿g3Úrï޽΄Û|||8"¨ÇcÐ;•JÅb±BBB”â¼ÆhFFFSSG„{ØJ?òmmm,ËíÙ…¶¶6´O d`(ïÆŽ •‡GõàÁƒãdz/tɳ VÆ8Íî²råÊsçÎuöë‘#G&L˜ÀŽ4:Ç¡‹Ëب¨¨ Uý'666_¾|9xð ¡¡!2høûûùò¥Y¬ø777dâMFFfß¾}ÅÅÅ\•éí<˜4iz¾pD®kΜ9§OŸî–XiHH”òÝ¿?’¢Œg67è“Î}P£µµµííí½ÏøPSS+**búÓ·oßϽQ}ã%ááálz 566®Y³fÇŽâââýT2º3a¼! 2dHee%’Í‚xÿþ=WT?~455USS#<¾µŽŽŽOŸ> ÷­ê2Ø»wïÆW¯^͘2»©©© XQQΰàÔT ŸcbbÒÖÖ–‘‘Áz³W¯^q¶Ñ÷öö>zô(ÓŸ$$$Nž<¹nÝ:…™™YYY·upI½‚lß¾}âĉ=â“ëùþý{UUUoPwIddäŒ3x&bÙµkWÏûýõâx°páÂÐÐP€››[ï…S©1ÊNFf6Áãñ"""<žBè’ÐÐP˜æn°ÈÁiZkkkt’ªœœ‡{õꕽ½=‹Íš››…„„8¥Q¬§§×Üܼ|ùrF—¯¦¦&Ðûé,k``À"Óï¿ÿΑ¼G111mmm¬…Í›ššÞ½{·iÓ&¾Z³æŠŠŠ ¥K߾•+W¢S$pKKË€€€±cǤrŽ711™>}úó,êr¨¡¡‘ÐåìûâÅ‹y¾¸ªªŠi~™·-mmmÝR$ä/^¼ R©uuu’’’X,6<<ÜÉÉIAAa եɓ'£ÃÎ\]]ñx¼¨¨(Ç­ AaŒ8p€SY¹544ÌÍÍ‘Éy>aÈ!ÜŽ žòÍœ9s¾~ýʃì”ì7Ú ,ÐÐÐØ·oßüùóŒ #ÒÒÒ666"""***&Lè½P×`4FyÀíÛ·˜–2ø<à7 ÐÃüùóuttÉ={¶‘‘‘‹‹ £ê~~~7näÔyÕÔÔÞ¿?Êð·ß~ëÒ%àõë×ñññ’’’œr)é/Ì›7/<<œ…¢mMMͧOŸ8ÁøPÊËË¿}û6a„YÎÖÖÖcÆŒ‘——_¾|ùà©]£G†‹ªÂ"ÇUÏØ¸qã€_¹FãääXUUU/^<°oVYY™E 1Ú5‹/¾ví8þüwïÞÑ嘆‘Î}8µàëëÛ3- ˜ó†éOׯ_'‘H›7o3fÌ`]«ªªâñxÇÚsTHHhúôéÜ» …ÒÚÚÊ)åäqãÆÃ!kkkedd8{åæææ¬…¢êêê””””””$$$¦L™2ØêØ!C<=={œ¸¸Çf ê~}}}EEEª!îØ±-^—ÙqJ‘””dºVøñãÇ}ûöÕÔÔÈÊÊêééijjÂùKKËììliÖ8®úbkkþÆÃã[:üì %%U__?Óh´ÒÒRŽ¿Dp ”EòÞcÇŽyyy7®O´ðú‡OŸ>åææ ŒÑnPRRÂÙÔ ’’’---íííèSdffâñxÆ(?ž!''ÇÚ?ÅŽ-ñËÈÈÄÅÅíÙ³‡ãfJÁÐÐPCCãáÇ}x eeeOž<áÔ\•c “òòòâ¥xNNNaaáúõëKJJJJJ´´´TUUϼ;äÞ½{nnnÝMá8ð——G»Ï¾~ýÀΪzgZBoß¾mjj²µµí×I{Ï7-ZÔçý¯²²2gˆÈn´µµ5ª¸¸˜³.d08„… ‡:Œßï_HHHqV!X°Lßèf[“““;Ìã’’’HúœtônQ]]½fͤž-]ºtذaƒöY[YY¥¤¤ðrújòäÉ©©©ü$ÇYbbb Í0vìØÞ+ô;´µµ………ÓÓÓêÍ+Ì---‘´´4øïÅ‹y<5ËOOOö3Mtɵkפ¤¤º•vu@B ¬¬¬ž}zÍš5T*þÛ­¢»ÀÃÒh´OŸ>‘Éd(ß10ÈÉɽ{÷îåË—=<<õ Âèµ(0FéIII>|8Ç…ú :::ÙÙـϟ?óÿò½{÷æÍ›wöìÙ9sæôLCÀÍÍíû÷ïmmmè!÷#ÜÝÝŸ={åè¿~ýúæÍî=÷#F@UgήÑ#HJJâñøªªª»wïR©TîÍ…6 º2744äçç§¥¥‰‰‰ Nµ•——#î›999ÜÓZRQQ)++£P(eeerrrx<žJ`öìÙUUU¯^½ ìÁ8¿££cèС}jmmÍ¥ƒ‰ÄQ£Fíܹ“A~[¶lÙ¿?üÜÚÚš’’2~üx7ØÒwÉ?ÿüãëë+0Fû’ãÇó[ÆvooïcÇŽuk''§'Ož466>xð`̘1[¶l]TT”‰‰‰’’Ò@*À€øôGÆŽûùóçæææG=zP¥S‡ôF,fÓ¦MAAAVVVZZZ‚ºÄˆ††@€«y¼!66ÖÆÆ†K133ó÷÷çjÂ4­­­ÉÉÉ5QYïÇóæÍ»yóf?6FËÊÊÖ¬YÓü°ÖlÏÈȰ²²"‘H—/_戎@/!Pžû…®®îäÉ“»å5¥®®^RRòñãÇU«Vééé‰DÁÛÕ¡¡¡#GŽ466600àê‰Îž=ëî£Ã=g %%¥åË—÷ j¤gøúúîÛ·ÏÄÄ„OÖ…ù³v-\¸°¸¸XVV–«¯áýû÷‡ –““Ñ—Ç‹ŠŠb))©+V ¿xñÂÌÌLP…XðçŸÆÄÄÄÇÇÿøñCVV–{'ò÷÷ÐÓÓãö©««s[×iøðáoß¾}ûö­ÏšÊ~‡ÐòåËëëëYg å_c´¢¢âܹs+W®Œ‹‹srr:sæ ’ã‹Ž×¯__»víùóçqqqœMïÙ3þ×ÞyÆ5uµü$$aÂÞ( ˆ K¡8Š€Uq"¸·âqÖªÔÖ…·‚¢8ê@DTªµ"u€â * .Pd/™BHy?Ü6/Ĭ’ðü|÷žsϸ'7Ï}Î3ttt† R]]­««+UËBGGgĈBXM%&& ««¡¡aûöí~~~­vuðƒÃá<}úôûï¿GÙÙÙ©¨¨à¡¥nyÓ÷íÛ·råJIÎêþýûW¬X« !ºeËq]Mž…QMMM.—+m%€ÿ¹LêëëY,–––V«ãømÊõõõ999ÖÖÖd2¹S:=þ|<®œ““Ó³gO„•JUVVÆÉMêk,Y²ä÷ß/,,ìâ ,==ÝÔÔT’¯:ÒÉÛ·o±]`jjš››ËgÅqãÆ]»v­ÕA{{ûââbx—NOO×ÑÑ111é”Öi4š‚‚BuuµØ¯ÀËÉlccóúõkIŽËÎή®®Žÿ%*¯deeq¹\1úQȳ0êääÔÜÜ,\J°´´d0›íðöíÛÇï5'Nœו¿oÙÙÙÅÅÅîîîmO)++;88È®uZddäâÅ‹;±&L¸råJ ?~|Á‚_›Éè,¥Ç!D"‘fΜyêÔ)Q.bmm=jԨÇKÀ LšùñÇwîÜÙî©I“&uñg{ÇTUUåçç·k )–%*ë¼zõêüùóâÍkÛôsëÖ-{{û–¦$½{÷¦ÓéÛ+OOOñ^sêÔ©/^ìÊ÷úÈ‘#þþþížRVVvtt„˜¬pâÄ ??¿¯•dH)é$888<<¼ƒWAÉÌO§ïÔãáîíââòìÙ³®,Œv¤}êÔ©.\{£íڈ㠙Lž2eŠØcVUUåååõëׯݳ}ûöE¥§§wÙÕõòåKccc,r-£Fqq±¦¦fK';yEWWwÒ¤I]Öú Û†èÝ»·„ß8?|øÐ2ädÏž=ʧ%K–,IHH»ëkvv6fÄü5$™^UÚ(***))%•³pàçx'4ïÞ½Ã#hÚ¥K—xn¦]k×®1™Ì©S§J¸ÝçÏŸ;::òþ]½zuDD®‰ˆD¢™™YNNŽ$‡©¥¥ºfÍš®D,//ﯿþ»ý£âÁÍÍ­ê[z÷‹‘.žÔdåÊ•ËÛ΃Ëår¹Ü–ñ¹¶lÙŠk£ MMM\.WƒÕÑÑ100èšaž"""–,YB $Ü.‡Ã!‘H-hjjÉŸ?…Bquuí‚ég™Lfff¦““S[×. C"‘8ŽØ_]tttÄ«“nh&Lèš{;\.·¹¹Y,±E»0:mÚ´ØØX¼ý‘QgÛ]=z'û?{{ûÊÊÊÎ5‡í._¾>¾«­®úúúçÏŸ·Ì¡ gßCCC^–ÎNdÉ’%‘‘‘]PÅ)ž€œ £VVVïß¿£Ê'''çñãÇÓ¦Mk{ÊÌ̬S<ì>þ¬££ƒŸŠ%,,¬m”Mù†Á`¼{÷ÎÞÞ¾•©††† x‡k “ÉjjjUUUb¼&–Ù×n'&&jhh|3êÔ©SÓÒÒð¶C*š››ß¾}«¯¯¯­­ÝA1ccãáÇ˽ŸDQQ‘šššèyãÚ¥OŸ>VVV]ÍOnîܹü,›={ö‰±Ý–™Üy˜ššæççã:^ww÷¦¦¦ˆñšË—/ç'}Ô¯¿þú믿v©ÕUTTTVVæääÔ)¨ÀR›ÍÉÎþÈû«®–ŸàJÍÍÍl6[QQ±í©ŽÝ5ð#""ÂÏÏB¡´<8lØ0>÷§RSS ÔA*•êîîþÇtï[dd¤M«Ø«…žžÞСCcbbpmÅÃÃ#))IŒd³Ù¡ci!¤¨¨èâârçή³ºâãã+++¿¹•A$) ŸÚø$!!aܸqí¾´ã”xVø|µ~ðàÁàÁƒ;(   `ooÿþý{:ÞEVWrr²££#?)3TUUÅ;-»víZ½zuÛŸ§ü¨ÄõºŽ=pÄxÍúúz,Òsǘ››s¹Ü¼¼¼®óøúñÇ… ,aT`òò>ÕÔÔòþÔÕiË/`øùù8q‚Ÿ’—/_öõõí¸Ì²eËxqݺW¯^õööOŸ>={ölÉ·»`Á‚ãÇwÊgÍšõÛo¿uÕuàÀÀÀÀNizïÞ½«V­j{ÜÅÅåýû÷Ž5‹ª®®þûï¿…ŽIwñâÅ)S¦t\ÆÝÝýåË—]'Úô¹sçf̘!¯£«ªªzþü¹‡‡‡”ôÇÜÜ\UUõÕ«W]duýõ×_}ûöíxKGº„Ñ/_jõôt[þ‘ɤ®p«444$üÔÃb—(++ãÚ •J;wî–-[Ä«§‘N&OžËgáÐÐPñú&ÿý÷ßx{XïÝ»700ð›:KQhnn®««SWWç³|DDÄÒ¥K»Â#bÓ¦M6làÿ{Çb±$㱫££#ya”ÉdXZZ¶<ˆåïcдC‡ýú믒䉷³³Ã’YÈ%X<ïŽctH˜%K–œ?>++KîWWvvöµk×p %Ä0Ê••ÉzòäÉoÿÂ{ô ><11Q­“É䀀 û_?zô¨©© oû?Ì­þâÅ‹ÿý·|ßÒÓÓ õõõ¥êõÃÌ̬¦¦F\ ÕÖÖÒh4\ý¸ëëëÏž=Ëÿöœ‰‰‰ªªê»wïä{uåçç³Ùlþe…ñãÇ¿~ýZ2r»wï ‘ð„¤¤¤´5†QRRâr¹b|ïÕÖÖ^»vmÛd9ƒN§øðÁÖÖ–Ïtq4M[[[ÂA‘d‚äädþÝ¿ÔÔÔú÷ï?}út¹Ÿ–””GGGü‚Zâb3ÚYp8œ†á9-‰7 ï©S§æÎÛ±Ü&— ÑÞÞ>::Zî]S/_¾ìãã#m7qàÀEEEâʪðµÑñé÷€êêêþþþçÎëÜÌxóìÙ3---ssóNiýÚµkcÇŽíôp?-9|øp@@€ž¢:::–––ò¢¢¢¢"##cÈ!|–722233KMM•ƒ±7îúõëâ ›óµeù5V­Zµ`Á‚óçÏË÷ã7… £2£uqqYø/ººº’g"“É\.—ÅbIlÈ ƒ;k±àììœ-¯ÖW\.÷öíÛÎÎÎÕ Ä a±X\.·]݉»»ûýû÷;kìæææÍÍÍrœñ9//ïÞ½{¸>Í¿) ;::v çÑh4)ña{È[fnnž™™ÙÔÔ$¯ ¬ƒäŸ ))I__ßÎήí©uëÖ………‰¥•Ý»w·=îääôâÅ ÉGJæáææöäÉ96c“€ßˆ\iF;WWW ÞÐÔÔþã?Jl€èÙƒ7 »wïîÄÜZ………&&&¸6ñàÁ€w €ÔÔTÌòO ¶nݺ~ýzy}8Ìš5kÿþýšššÕrtt|ñâ…dzØqI<„㯙Gã±51uêÔ§OŸÊë®tZZš‰‰IË$Õ|¾–••1 Ñ;P__O"‘ÚõTÖ××/++Ë0‹‹‹ŒŒ¤pþûôéciiÙ¹iuñ#;;›D"á½¥#WšÑ¯1vìØßÿ]Fßé¥ àåå%—až„þ%^ºtiDD„ TKTèØ´‹-:vì˜ü­®ØØØÉ“' 7!G•ˇɡC‡¾¶ŠÓ6mÞ!Ò: áâ><==ýóçÏ™Áƒ¿zõª¶¶Vþ†öûï¿2„Ÿxax £2¯uqq‹µÐO?ý´}ûöŽË,^¼øÄ‰bφ EÝ"...˜×”œ}ß®\¹2aÂ!*N˜0A,QµÙl6™L–€¹êך  »t½½½ÿøã9ËøÌápîÝ»×¹ñh°/lÇüôõõÝÜÜâââ¤á¥÷›enß¾mffÖÊ¿c<<>þûï¿—†¤Dˆ¸Ò^¼xqذaB¤upp(,,oviàÍ›7åååüÛ"ã*Œr€BèÓ§OßÔT–––JF?úôéÓ2ÜØÛÛgddt|…qãÆ%$$úþ§¨¨(gŸß½{geeÕ¹}سgÏ‚ ¾ööÙ§Oѳ‡s¹Ü?ZXX´{¶GƒîÜŸªªª‹- —§ÕuñâE‡Î]`wîÜ!“É›gÉduuuÉèÉ µ´´¾fcaaññãÇŽŸ¢ÕÕÕŠŠŠ‚Fµ;sæÌ¬Y³äiuÕ××üøÑÚÚºUÞIÂf³‹ŠŠpÊéÊ'½zõK|¥ÏŸ?khhð‘ §OŸž3gŽœ‰=Ïž=ëÙ³§†††4£`3*¥¬Y³¦MmPPN?ê?üðÃäI}µpáBiîa@@ÀáÇE¼‡Ã‰‰‰‘ò˜Ø½{÷nhh›¤&555YYYßL‹ÚÕ¸}û¶Ý×lg̘ƒ‡’^UUÕÖÖöÑ£Gr3“?~üᇄ«>iÒ¤K—.‰Ø‡/_¾$%%ùøø´{ÖÈÈHKK+33SÄVâââ&Nœ(å·Ã××÷òåËòôU•Øc—ÐŒÚÚÚª©©Iì´oß¾•+WÊñ‰‹‹Ë“'OdÅᛤ¤¤èêêZ[[ WB¡L›6íôéÓ aüÿýUcƒž={666ÊÇTÔÖÖæääôë×Oè+„……I̯ËÃÃ#''GŽcOªªªZ[[ËS¼ä]»v‰ VˆÍ1AÑ×××ÔÔ=Šðõë×ÇŒ#å·c̘17nÜ›Õ,±}ª.¡¥Ñh$IDcŽââb~¶Bììì¾¹?.:üØ àÇ­[·<==åàËÆf³ß¼yÓ£GUUU!¿BD¢‰‰I~~¾ˆª‡£¥¥Õ¹³¡¯¯_[[Ëd2E¹ÈòåË8 ʶmÛváÂùH²'z²SkkkÑ-4øDWW—N§‹Å½º>|ø’’ÒYQ®&Mš”ýòåK9X]oÞ¼¡P(_3¼éj˜››úôI”+¼|ùòýû÷ÂùòÞ¥ÝÜÜNž<)󙟟_SScoo/=Â(ØŒ"„P||¼»»;NYY…@\öÚBãáá‘””$ë·õË—/þù§(O±™™YWW7hРÎ톗—׫W¯ŠŠŠ:ý¾ç ´ ‡ÃyüøñàÁƒa*0FŒqëÖ-9Hhhè–-[:½R²¾xñbi=aoo_PPP]]-ë«ëÌ™3S¦LQTT”alFfÁ‚'Nœï1zyyݼySÖG!P®pˆ]»vI2 pÂhJJ Ÿf…ˆnÝéŒ3æúõë²>Š+W® 6ŒF£uzOÎ;'å–è’ÄÑÑ177·²²R¦G‘‘‘Áf³œœ$ÖbWÑŒ|þüYb‰,--ß¿ßõÿüóO vâ”:99I,€+äççWUU‰bχA£Ñ¸\n]]®½½téÒ¤I“D¹Â¨Q£d%F¬‚‚ºuë6oÞ,»««¢¢"77Wô§9‰DÒÖÖWØðo"–¸ #z¦16›]]]­§§'ô._¾ìëë+»«‹Á`deeõéÓGt'zÑw·¿‰¿¿\\\yy¹ÐW8}ú´»»;Þ–iݺuý:Ι™™’Ü î*šÑ9sæÄÅÅÑétùx÷jjj"›fšH$:99edd444Èè4†……­]»Vôë 0€Ãá<{öLè+›í2dÈ´´4ñ“““ÍÍÍÅò,:Òã(:uêTQ²Ô¼|ùRWWרØXôžXXX(((àºÃ€………?~tww—ÅÎó“ÝCÖQRRrqq‘ÝxÉrœ™Yh¬¬¬TUUEQ ˆ‘Ù³gËnˆ• 6H~W lFù¢¶¶¶¾¾žÿ¼áZZZŠŠŠ%%%xt¦®®îäɓ˗/︘©©éàÁƒ;P¨„‡‡/[¶LDóäÓ§O¯Y³¦´´T¶n(›Í~÷î™™Þ)ÎÄù]%544dÝI ‚ƒƒ²³³e®ç‹-úù知äUGÐX’ƒ Â/ÞÂ… ?þÍbñññ_‹[).†^SS“––&s«kòäɱ±±Rҙݻw³˜±±1ÞñÚ´´´Èd²”üéëë3Fæ\Gêëë·mÛæééÙq‚ŒÎFåD3:räÈ?ÿüSÂår¾™zDAAL&w°‡Î`0”••EÜø ÑhAAA¿þú«lÍáùóç¦L™"C}¦Ñh¾¾¾B yòäÉ€dë6©¨¨}:bÄñö|úôéçÏŸ—¡Õ%v÷''§êêj‰Å¢§R©îîî²kñÆ?>>>qqqaaa2Ôç?þøÃÃã“Jž²²²œœ¼#ß…‡‡‹ñ‚ß}÷§§§ ­®†††ÄÄıcÇvŽøÎG°EÕÕÕšššUéӧχDô8i—ùóçGGGKÏ䨫«kiiåææÊÊÝ Ú»w¯x¯éààðêի޳iwð¨Õ××—žùquuÅÞ…ÉdæååõîÝ[¼ý4hÐË—/E Å/1¢££½½½Å«¸êÖ­ƒÁ˜Š‹£þöí[±_ùôéÓ^^^¢xÁ‹‹/¦¥¥á­…Ož}†LLL***ºÔ·ÏÁÁAOOO‰QUUURRbee¥   %]zþü¹£££ µLLL˜L¦ØÅߺº:附±±ñòåË÷ìÙ#ß…§OŸÚÛÛÓFK H$’²²²p‘érssµ´´¤Ç„F£ÕÕÕIÕUttôüùóebuݽ{W,ñðFA3*$þþþGŽé #:thzzºXÂ$Iàûfkk+–ØC­ Âû'ÍÑѱ¶¶öãÇ‚V|õꕚšZ'æ‘áǧ¦¦J܆OŸ>UTT8;;KO—Ο?/D@rGGÇšš!Vš,Ò»wo"‘ˆ‡&X¼p¹Ü¸¸8ƒ ‹—ÔÔTSSS>£g÷·ß~›5k–Œ®.eee777™Èøµk×®Õ«WK³0*?šQUUUIþžáá2E§ÓùwŒPRRâp8’ õ¿sçNŸŸ~úIš@FFƧOŸÆ‡ÇÅÇŽ+µ)òòò”””ø4 ‰ŠŠŠB„­««Ã):½½}II‰”ïv}ùò%""§¯À?þ¸sçN™~ü¾ÿþÓ§O#GŽä³<•JýÚã:88XŒ/~FFFT*õÇ™ÙHŒÙ³gŸ9s+3æíÛ·x¿{¸¹¹%'' QñþýûxGIc2™JJJxÄ1¥P(éééGj—‹ÅÚ±cÞáfEFåG3ºmÛ6™ÐÞuÀÚµk·mÛÆgá)S¦¤¥¥µûˆ©¨¨hnnãv?æÆT\\,ͳ†ß¦’Íëׯªòöí[+++þ‚¶¶¶™™™¸Î”„Ÿø;­ðóóÃ/”É™3göìÙ“žž.µ«kÊ”)ÀÉüW___bI˜0ììì222ÄxÁ††‹ÅúÊ_~ùeãÆíž*,,K,[!!!ÀÃÄ_\¼yóFUU'û"uuuìî*À•––š™™ ÚÜ­[·ð Â-\`²ƒΙ3§Üª#FŒ¨ªª’æ b ÊÊÊÇ—ra´«ÛŒ?~|Á‚ÂÕõõõ½|ù²(­WVV^¸pûŒE722}P™™™MMMbœ(---KKËÇKç}ÊÈŒf”Ífó4áíš0„„„„Ñ£GGDD8;;777Ϙ1ãýû÷uuuX8ƒ¨¨(WWW&“ùÓO?íØ±CQQqåÊ•¯_¿:¨Ê°aÃÆŒC¥R{õê5oÞ¼¯ëÛ·¯]K{ssóÑ£G:thëÖ­ÁÁÁd2yРA'Nœ ÕÕÕå¿ eæÌ™JJJ[ûƒq IDAT¼#óçÏòäÉãÇÅþÃ@£Ñzôè1þ|žEæîÝ»CBBæÍ›—––Ž ß´iSAAATTB¨¬¬ìôéÓŠŠŠC‡ A)))ýüóÏÙÙÙÓ¦MËÈÈ Ùºuë… °‹6lÿþýgΜÑ××ß¿ÿ„ ºwï~ôèÑ~ø¡®®.++kÚ´iÁÁÁÎÎÎ={öܲeKCCÃÇñÖ«až!!!k×®UQQÙ²eK@@€¦¦æîÝ»g̘ahhxðàÁ±cÇbº„   —S§N 6LÐVZ¹ÓnÚ´iÇŽ¼=MOOÏ   Þ/ÇÕ«W ¿ûî;šàr¹;vì055íß¿ÿÙ³gíììlllúõëuùòeÌb¤¼¼|Íš5ÊÊÊx‡›éÑ£G¯^½~ÿýwìHMMÍ¡C‡BCC™LæÖ­[·lÙÒÜܼfÍš]»v­[·®®®îàÁƒ-¯€­½}ûöùúúvëÖ-22òæÍ›×®]ÃNa*ç°°0^Bùüüü… ®Y³æÆáááû÷ï:tè•+W6lØ€úûï¿×¯_•ôððX±b®Â¨¯¯¯™™–ÆÂÆÆÛ§ÆF„¸yó&™Lvpp˜9sf`` »»ûôéÓ,X``` ¤®‚Htss›={6&ÅÆÆšššêèèܺu«ºººÕ–ë²eËnܸÑ6Ë9ö@íÝ»—7±ü¿°1™LŸVûõxøðùúúš˜˜„¢¢¢’’’±cǶZ<!ÿ[·na{M¼qmÛ¶ÍÑÑñò分†{öìÁ< fÍšµk×®VW˜7oÞÔ©S[-È7®Zµ SË{yy±ÙìË—/›ššþüóÏÁÁÁS§N¥Ñh}ûöÅouyxx¬[·.)) û×ÉÉ ‹IÄ{Šò,¡8PWWÇb±† &ÐWÞÔÔÔÁÁÁÍÍmÏž=ööö;wîÔÒÒ255=v옻»;/ ‡——WssóÂ… §OŸŽÚ°aƒ ¦/-Ÿ!!!þù'ïkÒ¾”ÃåâêWçêêúË/¿´znoܸñÒ¥KC† ÁäûáLJ„„?~ëÖ­GŽ©¨¨ÈËËÃÒÞž;wÎÚÚúܹsƒ ŠŠŠÚ½{÷½{÷g̘ѯ_?l)¦¤¤TUU?¾åêÂ*R©Ôû÷ï—””;vlûöíwïÞE­\¹2&&†L&÷ë×Oú…Q™ÑŒFFFò^>²³³ÛºØÛÛçæænݺõäÉ“OŸ>%‰›6mêÝ»·šš–ZmáÂ…§NRVVNNN^³f ‹ÅJNNÞ°a‰D®K¶¶¶¹¹¹aaa/^ìÀ\æåË—¯^½jY 77÷úõëÉÉÉ!!!§OŸÞ½{÷åË—…Ð?µõ ŠŽŽ ŒˆˆÀãLŸ>{‚ðžÉÉÉ'Ožô÷÷ç%¯ ÷ööÞ°aC·nݰƒúúúsæÌillŒÅ&¡±±qÓ¦M½zõòöö¶³³KNN^¿~=ï"áááýõWrròìÙ³ËÊÊV¬X±{÷îüüüÅ‹?~œF£YZZz{{‡‡‡§¥¥%&&&$$´ÇñcàÀyyyæææ ,`0¡¡¡AAAÕÕÕ!!!›6m*)) Ü·oëÀ #,,LÐ@-ØC¤%6lˆ‹‹£R©Ø¿‰‰‰¼Ù^¶l™a½}}}>¼hÑ¢5kÖäççÇÆÆúùù½zõ*!!aãÆ“&MJNNöõõÅB¨æççïÙ³ïôwÊÊʽ{÷>pàO7£©©¹lÙ2oooeeåõë×{{{‰Ä;vx{{‡……ñ¾×<°µ·råÊ;w,]º4!!{v‡‡‡c1MÖ¯_ÏK…×½{÷äää;v`koÅŠ±±±&LÀ.ûÝwß g'JJJ¼ì2¯_¿æ}xcÄ„ìQsðàAÿW¯^‰Òâ½{÷BgΜÁš˜zôˆB¡\½zU JJJË–-[¶löïöíÛ/^œ››»hÑ¢èèh^âß;wî´Ü)"Þm«7¢ððð–?@í2yòd///\§÷Î;­Žüúë¯þþþ÷îÝÃÖÉíÛ·±Û}íÚµäädSSS¬ç3f̸~ýº¿¿ÿ£G0Á`È!ÞÞÞçÎ{ñâVÆÍÍMKK«ÕO-V‘N§»»»÷ïßßÈÈÈÛÛû§Ÿ~Âl`öíÛ·gÏþ³KâÁÕÕõÄ•Ýo?§†Íûíæñ¼Tª“YÓÜ̹qõ‚³““^·ÿ'?¸x1>#ãª*µ=ÕEO‹¥££©¤¤ø_ÍŸ“††2BHMMŸD’„X0`Àvûömt*,Nÿÿ¶†×(Ÿu'g=adGÌ¿6£@§qF©FA3 tš0 šQ Ó„QÐŒ&Œ‚fè4a4£@§ £ :MÍ(ÐiÂ(hF€NFA3 à‰2íhFõõõµµµÛ×ÒÒ*--…iÄ%Œ¶£µ¶¶a³[d±Xµµu0§€…Ñv4£iiO šš8-644hhh!„H$‰Dþ|¨ªªêààÀ•èèèéÓ§+))á7„ÐíÛ·ÍÌÌzõê…_+,ëÌ™3 ,à¿JFFFMM««+ÿUâââÜÜÜôôôp®'OžH$'''þ«œ9sÆÇÇGUU¿Žåææ¾~ýzôèÑüWILLìÑ£‡……®ÓõæÍ›²²²~øÿ*W¯^íß¿¿‘‘~«ªªJLLœ:u*ÿU=z¤¨¨èèèȕӧOOœ8‘J¥ò_¥°°ðùóçãÆã¿Ê_ýellleeÅ•ˆˆˆ%K–ð¿#Êáp¢££-Zį_¿®¨¨pwwç¿J||ü÷ß/ÐsûË—/ 3gÎä¿JZZBÈÙÙ™ÿ*gÏž;v¬ºº:~ ²   ==}ìØ±üWIJJêÞ½»¥¥¥@ßÇ„„!e6>ʾ"½1*++ˆD—Ëår¹$©Å÷°²[7“/_ªBå埫«k)IkF‚ƒƒù/_SS“––&P•‹/VTTôýñóóèé|íÚ5z•™™I§Óª‚JII ÐÒÒ¯cÉÉɉ‰‰U©ªª9r¤@â‚ ½ª¬¬|þü¹ ÓõáǹsçÚØØà×±ìììòòrª(**êéé $¿Þ¿? @CC¿ „ètú÷ßïáá_+õõõ)))U¹|ùraaáŠ+ø¯’••5oÞ<~•…˜®¨¨(%%¥Y³fñ_åñãÇK—.HJ´c©©© U©««swwHLbº®_¿þæÍjåååÍž=[ ×6A;öéÓ§ÂÂBª=zTMMmúôé½úûû ¤ÝxöìBH Ž±X¬~ýú ¤Gøý÷߃‚‚ˆD"Ÿåþúë/z•-P•œœœÙ³gÛÙÙñ_¥¸¸øýû÷µrêÔ).—+bëï¿ÿ^¼x±±±1~ 2--D" T…ÉdöïßĈüWár¹B £ÂÇåp8**T*U!TZZN§3x¯A,+//WII¥²²ŠÍæhii"hƒðšQ„P~~ž¥eo‹Íá°UU©ÿU›ŒÆÜÜ|.—«««#ý¡¤¤$Ð+©pL˜0A í£èéé3F3æçç‡w¦¦¦¸6¡¢¢2mÚ4ù˜®´a'µ‘L+}úô111‘éš2e Þ·¾{÷îÇ—é5j”@{µB ©©)¨­”L:U Û*ápuuÅ{ºH$Òœ9sðȘ1côõõñn¥_¿~\.W¾)îîî)k% Œv4­eeeïÞ½o«ûd0è ]GGfü‡”””¦L™‚w+Yl-ŒŽ5J3&g‡@|¡¬¬,о¶4O—@VJÒ<É´bmm-7Ó5qâD¼›011‘€ì.™éhÇY8444Æw+’yv <wA„Dš1cÞ­xyyI`º2ÿæoŠ@r’F[kFut´ÇohhÈ{Ûhi§üúuÆÀ±íûÿ_‚@@ˆƒ@@a´µftØ0÷_ 1mVSçL¯YÖÖÖt:]‚òññÈ¥Zºuëæææ&Óåéé)Ó€hjjJà=Þ××ïûŽrqqÁÛÜ‚B¡Lš4I÷o3„ƒƒCKPÙý¦ <¸{÷îx·baa¡¦¦&ÓÕ·o_EEE¼[1006lÞ­LŸ>ïàâšš¸»£¨ªªJ@Ã=nÜ8¼×°¡¡¡v ‚ÐæŽWW×Wv¿ýœ6ï·›ÄóNP©:LfMs3çÆÕg'G½n–b髚š>‰„û =°Xt:½‚÷¯×(Ÿu'g=adGÌ¿ ¼7½4ÐØØéææ6nܸ¼¼¼J–——/]ºÔÍÍ-44´¦¦ÖH!¼ßkŒ§OŸbÇ=z„ILLì :“É}úÄ`0°ånnn/^¼øòå Ü{6¼½½ûõë‡}Þ³gOPPBèìÙ³¼LH‹-:vìØ×ªÇÅÅañ%tuu{ôèñäɘRùF 0Mx³`Á ‡S)ÄÊÊÊÐÐ3ÃëÑ£‡@ÉKEÈ8£ ”¯ùÊ55q¸Ü&˜Y€oòòåKmmm,„§££#ÞÑÅ@V8yò$Fóöö†©è ©%“Û÷ˆ/))+//ÿï£63 dåʵí”ÎËCóæ¡yóoÓ|Û¶>„†¢yóП~µSII(- î²KVVÖüùó333±ýýý·lÙÓ{÷îÕ××—@ZD@†„ѯå¦olûWYù¹¶¶–W¦¶öKddôêÕËýýý‚[_¢ª q¹(4Q©èúu俆¢£ÿ9µx18½~Ý~FŽDK– ¼¼]»výòË/EEE/^¼h ÎÇÇgöìÙØgGGGccãëׯEGGûøøèêê½ s™ÜòÂ}úôQVVÆ>+))îܹóܹsžžžS§N…@§sèÐ!WW×]»va *cbb^¿~Z¿~ýñãÇŸ>}ºcÇvúôéææf*•Ú­[·uëÖ}ÿý÷666ÅÅÅ·oß¾wïÞ¢E‹æÍ ²Ž¡¡aLL Ï#ÙÐÐpÏž=zzz;vìÀÓ–-ÆÆÆÎÎÎ<ÓA777&“b``°wï^˜O¹FÅàMO&“W­ ²rFzüø?Âh ~øá‡vó ´ÝíúñÇá~ +°X¬™3g\¹r…N§ïÞ½;==ýÞ½{¡÷ïßÇÄÄŒ3&88!D¡P6nÜÂ( Œ?¾Ý¼GZZZ.\h{|Ò¤I­°yzzzzzÂLÊ™0*¤fôС¨ß¿ùñã§Ñ£'ïÛ·­W¯žBöqÐ äà· €.E¯^½lll*++B...zzz­ Œ5jðàÁ¡%K–H “$NàgtÙ²….œ4ÈùÆXá%Q„ª*jóè┕•Y[[ÛÙÙÙÙÙ}þü&…$}ÌÎFyyÈÃîòlj'z÷îýµríbffæååµqãF*•:hР„„„^½z¹¸¸Àd ¯ÂhûÛôí:or¹ÿQ£þäÝë×ÑÎèÍ俆‚ƒQK{‘ü|ôôé„Ñ‘#QN¢PЕ+èÜ9¸‹È"QQQD"ÑÙÙùáÇ c×®],«²²òîÝ»×®]»xñ"…B‰ˆˆ6lØêÕ«)ÊŠ+^¼xqüøñ©S§†……éêêúùùÍ;æ9F¹íI¢Mþù×W¯¶¼Ïšš§Ná«#˜7}» †† ûÏ‘âÈjjj‡:tèö/–ƒcýúõ؇–ž/_¾ä}ƲoÃÐE„Ñv4£,}Ô¨ábhÿÉôë¯hõjD¥þçø‘#(%}÷Ü!€..ŒrñjÜÂ……!„™Üú”“²²Bp‡º¸0Jc{MMìÿ_P™‚Ü\þ‘w9ÿFûþó¡Õq@Öhjb‹"ŒŠS3Ê`TÁý0ø‰3J€ið 3mFˆlø‰D")**640•””áöH9l6KAA!Äd6´:E&“<<†ôèa&¢0Š—fTAAÁÆÆªå]]=I!…ÊÊÏŽŽÎ ¸ÁR Îøô)§OÛÆFfEEy}=½±ñÿ"©‘¹y„šEF¹‰ºº¦ª*UEE™Åjxúô™¦¦&›Íª®†wÒKqqɧO¹}úØ64Ôkjj(*RÈd¥¼¼Oü_¡35£!‰D${õê]WWC$X¬¸©²›Í"“IDb³¥¥eeeU}}¸„Q¼4£$©{w3T__C ´N% ÈÍÍÍLUUeMM­ââ’o–ï\ozBnî§’’¸mrÆ£G©üR3ÚØØØÔÔ¾-*…B!‘øi›Ãa³XÍÍMïßg;;;‰DÌ Q‹ŠJÕÕi4ššX„Ñv4£·oßk"k·:A§×•æ½›>}’¾¾ŸÝ%‘H!cc£7oÞÓhjJJІ†pdŽÚÚ/\.7#ãu÷îÝTTTø•ù(Ó¾)§Í÷¾­Žl_·TC±ÁØØ˜#xO u„Pii9›Í)/ÿ¬©©YSS“–öî+€ÔB§ÓI$BÜÌÌ7ŠŠŠ\.·{÷n]Axoú¦&Nƒ¡¤¬¢@"±Ù¬[W§=Lºx-‘W ¡¡‘B!‰ÿ˜¥2L•ÿı'“)VV¶­.ËápLLÌTTTÈdŠ“S¸ÇÒ ™L!I¶¶ý”••Z š$2‡ÓD&DFÛ׌žÚspÛšEA'ÏYvhûOW/D4OÏСJ¬Àºu›/žÛ»w/„PCCìY‹._þ­å?~ÚJ÷© @Ô×7¨­­¡Ó!Ü=2†††ÿÛÓòDEE…ŽŽN]]]]ÝÂ9Q©*óçÏ´··Qm_˜-.ø„:¶ç—¼œ÷·®ž÷š0sõæCm‹½{—U]]Û¯Ÿ]ÛS Å̬;ïßnݺ3™ --íOŸrÙìFXÐÈÎÎýØlv“D+ UF‘ñ’D"çä|lnþÇͽGžææ=:®.¼ftÙÚˆ@ˆ?yëêy„»§·’² B­gÿãÇܼ¼üv…ÑD]AYYÅ¢ªªRAøæÍ›ššmXÐÈÅÅELf×ÚàÍÎþH&“èôzª¡¡¡²2õãÇl>CÈ g”ªJ[³åȬ%?ô M4µuÛ–a³9åå嬺:zÛ³d2Y]]ÝÁ¡¯ººZIIQccOŽdƒÎb5ÖÖV òƒ¢¢"?UDÍÀ´ì§íLz½‰Ô¯¿[«S#F ýãÄž=Í»wïvòäÙÉ“'´* ªªÚ§í‡ïáÎÈ,_æ ÂÛŒšk2±»·o¨(/1Õd"„ÈD.úW¹9rä0½¾}íBÚÚZ؇–Ô×׿yó:'çSÏžæd2 n€|ðòå+}}]q £íhFGNä”crªšR뮉8ŸBMÿ-Ï@ÛJ¢!6›][[£¥¥ñùóg:addØ6" +Ðé 6›]RRjdd@ ð•R^HÍè¿ÑC¹¢wš@ Éd õ¢¢b]]ŠŠ ,-€ÌQTTüåË—.5äÚÚ/::ZŸ?WÔÔÔª«ÓòDÕfTTUU]\\[inn¶²ªWVV¢P(°š-444ú±X¬®6p*•ª¦Fsrꯤô§%ªX„QNýÞ¼yŸnV29Œý?rä·6ë;S3ª¬¬ K@vášÚñšWj"“¸ü„ýº0ÚØXÇå6!„ú}÷=MK æh›ØôN!¯‚SÑò`e^åE; ]3‘„Q矄œF&¦0Ñ@»Ô7×—7•·°ÐZ¸ÜææfNÛã•••’÷uinæpÛÄîd0ê ?ÕW¯^>eŠÏ¶m{$-Œ–––&%%ÕÔÔ$%%!„,,,ÔÔÔîÝ»w÷îÝææ&1;;{Á‚qqq¯^½ÂI JKK½½½?~üòåK¬º……ÅׄÑÊÊÊcÇŽq8ÿÜ­{÷îùûû§¦¦FFFöïßkèþýû?ÿüó£GnݺÅ;B§Óa¡ œ8ñ[uu BˆB¡,_¾!syêT_ì,ïsLÌe++ˤ¤{!+/¯á¡¬¬ 7±’nnß÷ïï$t7 Šòó JJÊrsóBÞÞ£-,z|­ðo¿Å”•}F(88!wÍÛ{4‰DjÕá…Q‡û÷ïoÞ¼™w0))iĈnnnÿŽÙmÁ‚111GŽÑÓÓC544dgg#„»uë–““ÔA+………QQQØ¿oß¾UVVFuïÞ=((H]]!ôÃ?¬_¿>99yÀ€£FB½|ùò?þ€µ €¬säÈqCCƒ=ÌB,+,,|ݺàß~»ÈæxŸ·n ÷õëî>!ôî]Ö_Ýwrê{âÄo#Gzü+§Ý£ÑhVV½„ëI~~a`à+¦( IDATV,urê‹:zôä† kÔÔTÛ-lmÝÛÄÄ!„÷矷nÞ¼>&æòèÑž˜0Ú²ÿ £_#00“Bfff¡óçÏOœ8±¦¦!¤¡¡±oß>þ¯fii9jÔ(žt;qâÄ… bÇy­´+(S(X¾È: SU•ª¡¡Ž"‰!!Ë¿V²[7£õëW“É$„PYYyII)‹Å./ÿüîXW×AD¢HêÞÞ£gÍš‚]$:ú·Ì[ÕÔT1[M.—ûâÅKášL£ÐÐÕ«WÿŒù9…††””” „Nž<2}º‹Å^±b‰ªê_bF ‚¶ör:µ+yhiiµ[J¥R©­3‹¶º‚’’’’’RË#­ìAyå[V›Q¤.ÕÖVef¾m{J]ÖjœJU9qâP«b=½q#û¼}û?Þ8ÿ®4jÔ?ÚÓ‘#=xLíÒÔÄ~÷.«]ëOÌkª%ÊÊJ›7¯oupõêå«WÿÇ’UEEùðáݼ êzô(íÒ¥3$’BhÿþH± £€ â(¦0#®PÆ*µ#Œ†øLB ‹„TÖXöûç¤JFÌ 1ŠØU!‰JR³Pƒé$L݇ºÿknÄ“a>IEND®B`‚snd-16.1/pix/later.png0000644000076400007640000022655411147553267013001 0ustar bilbil‰PNG  IHDRËêAsRGB®Îé pHYs  šœtIMEØ3Xäx¼ IDATxÚt¼[“$Ùq&ö}îçDD^êÖ—™0€±„¨Õ’IÓÅd¦½éêiŸõ#dÒ“$š$[#  ,H€À`fz¦§»ëš™ç¸zˆêFÏ[V–ÕUqüøwóäßþÅߊ7µúá8œ]ØGŸxïu3=óêÅ—_þv^6­Ã1[F¦uv±¯ƒY-»i~8´ó«§1_?ÜÞ^^}xìËë—÷»:ž†›»Ïk\VVIçg9L·O?ü‰p~œï¦¡,â!Žãüð—öãßüöw/ßäw¿÷ä‡?8ÿ¿þî¿{øî}[¬öï<¶ÈîOϯÊÖâ«/^l.žß??þpØì® ÜÜñË/†ÝÅóÏÿ»ÿúßþðé9wÿÓ¿ÿŸÿÏ¿¿¹°å§?Úÿò··LÐìf‰ÿþo>þ¯þòGñï>j+•€Åʘˆ"-€‰… EvìèäVÅ€~$´'F˜“P;Rl•*F’@lÈ!´˜›"É4¡Ì4:²GÒ|RÐ=š¨âAàðR,šYc `Fá°½~=ÿ?¿zù_|çùÿúÿââòƒýøÙ³‹ùù?~ùQ·zsUÆÿöw?»¾¹') _Ä»/|ÿ‘À7Ïh`½I¼÷"NQÌÌ¥V2ÜKŠfNµH Ãj©ÒŒFšY†2S™Å,–2V©…:É f@!î–Â`>N1G–‹óò?þÿîé¶yÎf—6œøììÉ…·ÓMÏ<œŽ§¥´`êH.ˆÑm×âΆÅx%L{iðòZÙË“«éå«›‡6— ãv÷òË»ãqY–Ϫ;9î—¾8[¡bÜÑsØæ²œ¦ñYŸOwK“—×o^¾ØMûÓ©Nýt8mÏ2Êä›V.Ú² ã@³©œ=}úakÃÍýííñ7WgW•ãñë›Ïþþg_¶ÃñÃï~p¼¹}ù2çCÝúé>‚onîÉ][ðOÿøéÙ0œm·›áì«/Žÿáóß|çãÅ­žón³aÏ7O¿øâúÓÿøé‡ûÝÅEµK`>E„,IP eŠD3³ÌLÀ*èd$ “…,™$2ªÂª¹t4ó ˜²“LÍ” 8D÷b$Q ªr'PM™2s‡G—ÑIæãÿ@Έ;s6M€gˆeH«™GÚ š‘Æˆvo~ÅÒÀÙK:Q̘™Ù-ýš1{HX×:ô®>ðjùý£¾uŒ€ò›/{WJ|< SÊ&„C±˜Ó”P¦Òá’H&èRöÖÝ}žOãX3"¥Þ *ÆL-#3h=™*¥l§"¥$ =•äa^–êäôMËÙ¸IÈt›°›¤h£òD˜•$öR<•¢Þá^É€p/HdyýâËÒÒ÷ióÃý2Õ-懋͸Ìýtu昇Êe_òîøPwχ†¸žÆQ6Pn¥ìÏ>¼¿~3 C±T?,ËÃnÿ·›+ô¹/ §í¸Ù–×/^¾~5S,}±‚vÊžr³çûï>åõM,óCËð:üñîxŠC,Hw›Ü‡‡Ó2”ÚŽËáëù¤—_½*¥Fë›ý´©jìÍ÷jþù/¾øÝ¯>¨ž<f…œfëíì¹,6@‹3œ£D0A(t 2ÓMF+ÄÞ˜±BpšKÊ•Ðf¦0š“ȘÝ6 `š‘…’2i™ÁÐ’pCÝÍ2c]7p@fÁ"ÅÁ8/MaÌݽ(ÒÝR ÙÝjÒÜã”ýè(ˆn"%‡Aâ{Õ±v„|WÝiŒøF}­-çíEl}1e$¤LÑ@H $JRbÉ0R £Göh”«ûzÁˆ^™Aq>-‘$z$ÈÃ$ ųa˜Ri–óÜ”êK_zDde(Ãàuvãv§³!C0+)7 I²mÑ Ø+ByrëѽfffGé”ù`Ü“}G›Ë¿ÿÑÙ“³ŸýìÓ‡ƒ²,Êp|¶ïIåtÿ áæêyýäÙ“ž]}þÕõý²;åIÃè‰á8Ÿ6v~¶â:+e·,÷C%ÝÒûÒ_=»ø°–ýÝíâÃn>Üýîů&'øÖKCmÃv4ÛŽ~ñd[Ý"ËñfŒCY°”±t-ý!X"ŽÏ?¸ˆЇ»Ã§?üá“_þâ_7ûóý4ÕÛ›ÛC¯ž~ÐzÏ7_¿GNàÁ8L£Ys¬'‰²b©$„¡ÁlŽ[swÍ ™±Is&A/•€@8BiŽˆðb ‘`Í̈€ 0‡ÕŒFžŒ `™f ,™Få@s£YŠ÷ÞIciZoµ t)̜̈́ꙋ›g "’ÕQ"DŒ5€ ^¼–|»¢ùv¡¯ý€$$’‚Þá(Œ¿ï.ï!2€ï.B­µ0<¢±†„)’ÕM©ÌY "0U;,én¥8@e¶yÉ”¯ 82`)´RŽ•FL£[)Kën\z¶ùÔzД‰âeªãvòi°^·VãP m7Ûê “JÒÐI÷67r$›Y2¥(„÷øÒlBnaN„ò·ÙxE«%²øÑ³Ï?»]>¿{þäÉÕå4.Ÿ\ŒÓþ·›y8õá³/â‹—w?úäüƒŸ6׿ú²¢ì÷O¼F;µ±›q{O«ûÍv;ìONªÕqw~?÷­íÇèql†Ø>|ðôƒï~çò?þæ×fËùî‰púüº½x“d¯ÜÃxˆ˜Ó§My¸>Öq¿ÝlƱLÓþõëÏ«çGßýøxìÿßÿû¯Ãˆýé?ÿòæØK@Ëò°ÝpÜù°=;Ü Y+Õ…€–=)s#(4…NV’HG=!ÀB2R™Jc(A…dš¹`)II(ÕBHuŒÊXDÀ¥Œ®.ÀYÍ+Ð24=2‹sfGDA¸¤Ì™V̆TÉlÃX¥(2ªBáæ£²[qwTsß•Í ­Ò\"¨RJ®ÌáˆK|W€‘¹’Cöm6¾­>ö>þÝ@ § IÁlmO¶^œP)Bº¬t½9Ö `5ç -Iîw©›Âȹ+ZÆ2 ¤SÄP}ÚŒÃP7ÓÖË@ÐÜ%ÑôäúæDì3J†D‰Täl”Ô‰Y8Ø› ‰MFgªÐ¹²›‰<Y~óÅçÍŠ;?ùøÙ8á´œX.ß<Üî/6ãîìë—:Ûž÷¥|ñu{}ó‹ù¯_ßœ?ùžºn¯ûýùG>)¶ùù/ÿeÚÖh»?ùÁw.¯v¿øÍ]ßm®ÇJttk³ÀR7s›[ ÷G–qÚ•öÑît8}9·‹»cžíέÍÃ07/Vl;íçãM™†Ãq¹{sŸjy5=ç8ݼ鵎ۋaÊz¼y3/÷<ÔÄòáÏ{Ö¬Ø\ˆ»ÃéêÙ8‡µ¼.-lpŸF¡œzk&Qx\Ó=mÝ*$3«B'+àNOB˜R@M0rV#°C=Õ» ôÕ¤$u1RFÖHFj¡A 09j„!5¡¬¾]÷Š|¤ÌL%±‚ò™É%Õ–i„Á™¹&¦”ôT¶D’,¢ N ŽÒ'C‘d£Sïê„xlÕ¹VH¦µ\VæÏµë(Þ–‡ð^q•Ñ©j–)æD®f¿ï;¿GnF FW‚Ä4øqÉžQ‹+¡ŠhJ‰æ†êûó ÜÇqR«ϤH-sºÃ’»×Lš[(k))/æ«•ëÐÓR2X˜*#ŽÑTÌj‹{Ò$÷¢ˆ{á2‚fSäqEfn†„]•'çS[¼wžŽË³Ÿ]™ßo¶õŒæ7¯¿|¸zö,WO/¯/Œ1}òãgeö/ÆÍðêöá«/OWuü›?ÿ·¾ÁÏõæW/nn^3{[º»Æ·wîÎëzmý,•eð¥õèþäÙpùå§tõ<Î8}°ÇÅ~û¦ÝŽs¯ÃÃáëÍtÕÁ¥qÊóËý4í^}ùUø&{È£ÉÝÇË‹ç_ßÏkUŒÃ0ûá0h³²kœ°4æ'ÊÊ""U*ÒBC‹0K¥…PRˆRlÙ#¶hÕb’’‰#Ù¥`Ì”Œ’.4C[R6qc^€Æ º#N œ' ƒ.ºÑA'³SdÕÌdG‚ƒñÒT*ᦈ¬ÒBª…(5–ùQŒzd(zŸ´HÈo0õwšÖï¹¾¾©éí™HD c-<¹™ôxº”ÅåZ›C9Ð$7R€zê~i$‡Á}S¦ºÙL[7 ³Ôz¬4¤z,³i„ïŒæµ“J¥V˜4’в—êÑNr6ͰZ2k9·´j ØC¬N}¹7Ž‘ ’–(½!GÊ ÛÈN ô±<{^^}•ÕwŠûXl3m…Ò(Ò6û·§çÉøä'ßCÓfËO?ýòööõù°?»œÚ±û~ÓQ>ûôÓßýî+ÕíùåÓàÊPà´\]ŽËœ‡ÖŸmΜýÕáœûÀTKÝ`Únç/ŽÆÙÛ1ƉÛçÓŸþô;_¾ô_þæ¦Çýf¢b¦2RSµ'WgWg›7_ÜßÍÝË%Ôz?µ^Çi°Ã $̧“`F¶·´4JwÌE«øg–êF²P¨¬VHc XwÅf\×Zº‘˜V·0(äÆ`™…–d(ÃP÷ÔÖz¢C rÚtJ˜lY7iŠ1“È0'4‹H÷J:DeÈB=(HeœhKCâ(î{„ù˜¹‰L£G˜ax À”o™ú·t-¼wä›ß9ÞÒÿ÷jie$+`[ÛUïIâQDB2ˆdXñÞŠênç¢R9ÖÁ¬Fá8NCÝЈŒtN£*Ñ Šq(DËÙÈÈ,^döÕN¡$d-5%dw·žapE·²ŠŠ=í±è¥ÍóbÜgºPMÜO@5«I§À1{­uŸ©Ì‡r|ȇ‡Øoç:äñˆ\j/”¶ÔiïO?Úx}}È8.þ*wYj½=Ý]mÇo_¾<üëW_|öúÔâüI)#•aRoMê»gÏÎ>{ñ»û‡Ñè×77—Wgó©>Ô¡þú³Oý»ß¡n"ç¡ØÙÙþº-oîn.Ï/k9ª÷v²ˆÆ!éVüÕ«ëΦiX¾¼³«–ÃmÂûR·Û‘~\"¢•³‹óåëëyÎGm_DÒG˜NÀ èiCB䨔³ÑÊ ”)$ét§j½-n…´È9å4š"`®GÄ•ÆD>Âûa’¥ìR+æ‰(Zu5†Dú°.=·)È„’—ÐÍ*ÀžVÍêÒO0DrpV´HÌð„11ƒÚiÕ|ŒšÙÚ.V¦o1üw=e-¾g>~»–ÞÓŽ4>¶œbÖC$S*†Ì åã6²jîD*ÔfÀ©±úÙÙY¶‹bÅráîäaH`Æ$ň™\Ü7–ÕiP¬7ŒÝPRBI¢º»q(>RQXÈp7³‘æ^•$¬ ÑÍÜ"ÞvÂ`\wÚ[÷ (k·y.¥NÛ‹qÜ–ãiyõz)õâanÇ·ӱã8÷˜{ï*§¼ŸOWÏÎÿü/?úá?Lw‡‡D Ä!Ûf`(–©tóT¶–××Çi¨WçãayøôÅgSñ­{ô¥C³ø?ÿÅëƒÂ)£Õ‚]åÓÏ^^¿z“ñà&/çµ^œú”Z­:˜n‚:‘‘aF2ˆ.u€æE‚2@ôˆÞÝ“(¨t¤ìQ¬B†²g,ä X¤£²$&è9IKä¡õ#­ ³0{1ÈI†â[2¥;áA™¶¹ÜŒg%K–ûùøÐ®›ævû8´^Sé…‘‡ž7éí·/¾¾?Üf>LÓ6³O‡RÆÔB?nÎK’fÃTžºÛ8+~X^ß¼ùê|;ö8·Ï..~ôÉÇÅN÷÷_N‡,›²ý°»É«cZRq8-YtuᥪeŸvçuØôÖ‡Êâ¸wû³ó"^‹ÇÐÜu_J3ÄñáVC-î.<")w  A@Ïì‘ÊBnÁ*uf§ã‰\u2’4'¸²ûÌì AŠ.à†œ”(Å'÷I¹Â6 ¬âzÄ뤘«D„Ì Eª#ƒ2礑D@¹‚5C 4ZÍõ­Ó#ò̈hf•(2Q„ª´ZwkǦZŸR;bç¾&hXùÉÛ¾±ìùíÖò–ñó)Þ£1J‰Äï =!%•Œ3+æÔ[)’kQ“ ‘6S°u-ô,Å`9Q¼ ¢KT)•$M>˜îÅÉ4“2W›µÖ©–ÁdYjEŠn‘‹t;¤B˜“ÕEtZº·3rz*Í6¸]çJ¤®Ëýñ„:½|s? ۆ蘭ÛîXÇœa9mê€8<œ¦&äèíìòÜý¥y­¬»mÚ·ãù«›Û%ïv8'3[§g-c‹¼;žÈqHìKé½yµïü´uüîëcªœŸ?=Þ.èqÿ ŽóqâÐÚÙv}@M`Þ»Ãòp¹/×˱wÜÝÆñˆHM㾔ͲŽGôå4?Ü=ù`_Ì”©GØ]•MHšI‘¨Â(¤y0i1$a"©B$,˜aJ¢‚DF— ù˜Ñ™™+ 2’˜²7²’5¡žKõ±ž!33‰Énœ ÕÍV ÛŠÄê€P«Öìvh´#ÐSá(K‰3+l %Dr4À¡b¬„¤€@!k¨& •Çó½Ð{âã.ï×Ò·PÙû™³æ‚„« Õ–]ãC€•â°TÌûÜ¥QŠ•2z“PdÒº™eô:8›yª›{æzwsb+bÍÞ¼{L #¦q€ xϨeØš°Ö© Împ(æ¡¥õc±àbÐXf…/U9–Û»Ãf{vœãp:FX–  ŸÚgŸ}¹ßŽÇãµûþþøæ°”Ôö´¼n‡0”a·!Tm3eýúa–`Å`•%À.¢ÇQ´]ïóë7§"¿:ߟzÿíŸ}ôdûÓŸü$ñëß|±¼Ü/-–S‹Å9”òðÆöϯZŸ3¥£sÆ?ý“ïþüøCöfÇ£/KnÎ÷-J1Kļi«\þûzJhÅcf„Q €2ãqK¡!VÇÓЊ P‚©ˆ KÜLæ¼–Q|x«€‘-–aœJñ(­-=r(eéKª·™õ#RC ™Ò,…²¦3‰a½Ñn…X"*í*ñ@€bØšŽ<-K·»‹ð¨úý験!*š8ª\ô9”ÚiɇS&§Ö¢:Ç|8¶:ЋeŒµž…Š9§@ÌËífãj¥çÒs×77‡ý0lJüàûõoînwO®Î§±.qªÇ‡Ó¼ÔRÕdÅÍ K÷œ9 »º;Ûžm¶gé¼?zj»Ùy-wÇ»RNƒŸyyùdt{<°"M!µÞ–#Ppä–áŒUÖ»[ ÀÍ„²²ÈT7`\¹ŠF@2X@° 9‘✚I/uH5)@#«¤L%Bkª2Äìæ!mT˜’¢ÇjvZ¡yEx!Ô ®0º‘aÉ![µ¸L$ l =àäFðÌ&1* ;õ6 Œoðzþ¡Ìõͧü#äÿ÷Ð+$³32{ÂM|ëô‚zW­(FÒÌ̬ôìTó,î4´ìBH͉µ!ˆ«œ9¤Â=[ÄŒž)§»bÀ)Yf1+k„‹™#¥ÖRA¸Á¨F£¼$S”™ T¦è)uZK$“Ò„–º9º9ÕKžßÞ5:‡²¡¡¸õ((õx:„æiÜ%$ª·h˼F--3–6»%PŽKÞÝß·>ÓÇPí©˜gÈíu/ÁÜÞßÝÔ¡øóMpÓfVm&îOǹn*ŸîÆÓ`w7÷·×¯¬ý`¸xv1¼øúñ*‡s¯»‚¼¸ØýúóWmþ4U¶Ó²¼ùú³'ÏÊåö£ÁÇÝÅ“d=5f_"–~ªF^`†X)ò*ò#Qq’x\Ü$lª0¢>*q"û[Û`½÷Ðã¯+"½@ÙÁŠ4ˆ ¤\¸²&›k@RèÈ’R¥!i)Ì`P¦\„&· †¸¤h^”E€f2€p·q É îUÈXœi¹ÀJ½sÔ7#ÅäÉóÛ¸ìí?¾qòêÒ¼ Mr…‘x3j5(3Uk1óTšÝ@ö¥Ù:i`æô`–BD‚I[ù]ÀÛšê¬ÊpèКµkãXéîr¢îÅ3º™nV óâ3eÆÑ9&°AL%0HIäŒ,ÊF#M°…QÌBl‘Kj6/vòR³ÏTÓ}¨"3ÀËXË0T_Í&ˆëÆ:ϧŒ¥E yöÛíEbhQV˜˜CáµÒ¬ú.Ûp|¸£kœö,¤û×o?ûåWÿôÏwÎ=íÍ—¯^½º~8âòrw¾Sk¯Ëááþpuîm¹i½HxXn§ûï}xy|¸q}ª›³i:ëK¿¿½‹oÆi¨ç»ý³Óâon‘†U–ÊG&S¶fTÖ,•Ù šùð R‘«ª“+ €ìdO5=Z ZˆºÔR³òHÜ Mr©B\HМeH*$1 +)gb–º”’­ÓÊ6csºÛh\ß{d"á™Ué™Ìh3Ô2ÂPº4Sk ZF*B‘ÊDHßßFVú½±øíÜ×UÀÞyþ…²†¶W•™$i\3Á«}©èˆ¾Î›DFôÖ2=Ö­ 0ÊW‹?BNºùÖìîªã°ƒœr$¥t-±VÌCwOXÐ×h…Œ³²ƒG`6‚X »If f`Aõ5 QÝ6ä µ(_!hzVmK4péyg¯ÞÜÔÊýn´=NóéÁ4[¶óÝD„¢Ã@TÃ8V² ãÔ;È2N›2ÔÖ[©ã0îR„8 #ÌAk=¼ªã¦«)Ç¡Ž›íÞk­nÛi3/ùÏ¿{ñ¦-²6ï¡ñöæðâÓWÕüÙ³'ûÝÔNùùo2¬ÖÝÍqì³N§O¿: nõŸç{ßù„V¼ О=û`Ú\5Ãn®îïæãaÊ4X©D57s‘·Ù``–‘=%Øjɯ̄¤óÝNË©{Zsw³‰0Òh”$IwOź­ŠJˆ0°½ ÝÒ‰*Ä”0!h¬ G`ÁN•«)6('ÈÀ ŒØ#ओ  XÀN†Ð€`3ƒ±·Á­‹9Þ‹J꛺ð7\ù?ˆÙ¿{úþ÷{Ò²Š=¦ÞŠf±j]ë©™p³:{‹ÁÜ‹›™sÄRÂK©u¬er$’rªÍ‚–Îë+ÍÌ •Á•ï;Í3³™­G)„”‘A#Wá TÐaT3u*׊,÷1£G÷(Ä 6/‰õ¶‚fã¥õv8ÞÏûín;µÀétXæ£ÑÈt·Þï©®ÐPJfXD/ÃÖÊ”0Ò"O™-ZÎÇÓáp­£ÃA Ñ–ÈcâaiÒ#è v›ˆyY.Îvwžå¼ßö\¾¸¿{è?ùÉŸ=¿ôÛ›¯ßÜza UûÍù«ÛÓ?ÿúå“'—þÓïŸ ·ÈØmGs[:N3¾zùõõÍ L z¬A×äãm#¤)eöY¹Â u˜D HRë–‡.ä,WŠ(fc€EpÐ$PTAŠ‘ˆ€¥*a†ÐN 8U°u+^‹—A²•_ &ÐÜ4ˆÁiy— ˜gÂ(h†rI®øOiÊÞ¥ÖüâwÿXëx¡‘oÃ/z—Þ—½_í­:{®"^ªµX_„54aŒÀ»´ @¹ZN‘ÌkïÙ#ô÷Ò‰¶ IDAT(Whå9ÊneIºœjd ®5\ZdÏXzŸ#Z)àddÌR»‹<€:x‰¬\ O%;=y 4+J5 †âÜ årïÀ0ŽJJV†â¯^¾¼Øž•‘n”@[š “[™Úr—c¨•-›heÜÀ"H£m§’¹ô™óña˜j,s?ÝLôÇÃÉÔÆÂV7ž‹Ï­mÏ Éb*>|þñÆúÏ/ÆÃ›—w_ÕÍÕxvq8”9nÙù7õ—‘§ýâ>»OlÈVè6•ϯÏüàÙ™Óÿþ?üóýõ-KßþàG˒ǧ6%Ï.¶¯OoÜ  W‹#Tô¾ ›1}­“˜ÀÊïW²GªŠ¢ìàଉ*¤q!Z6o3¹ÆÕùyTxõŸ¨“ÇÆò­Bz<²xŠ%Üh@13¢¯m7TŠaM0¯!yS*”*C‘ÒJé=|pGSQ)¤òÎ9S$])÷j,4ËDª¥jC©æ¥ÍF­Ì‰]ÊtßÑ*} 3Å•Sæ ëòžÉ.ö”èŒèŶ¥jf@¹“º•Å6Û‘äW_}Ö—ãùölÚìæ¡‘ê]Ó|º¯5Q³±§õ:òâbgÆlóBŒmλë‡8ædVÄÛ¯Þ´­âxº£Õa¦¡ö8ÀMÑãÑóâ|ØM<ÜÝî‡Í_üéó¿ùɳͲ\]>[ýçÛùúg¿üôö¦}xyq¶ß*ØRR~òÑóÝÅöË—771¸ï†’óÉN%–áææFËíq>¥ùfÜ·†L2; Ypuv4OtYš”™úi• ²“‘ˆ34+f %2|¥>ënÊn$d´Al'×€q$ŠUÉ4rßÊ‘B˜fC[¹l” à´²&µ"x¶vha&2‘‘G®cgVYFòœ€˜ÒPmP–Çu¹²á:š{²bm—x” ïû}ã=Òòhé[dF1{½¯¤°µ7†(ÉìΠ Ö‰=˜i&2EsXé=ј½·å´2 DÂÃÌHsŸ Iª2fqI=2dÆZ‚J¬ÿbH[+©"ŽÄ`$È Ê Œ•òÌ”jʰU¥™r‰~ýNÇ£S†”—êÕ‹ÝÜÝÚ¸}ö§Íæööv3¨-,€ G+I1¢;nlÔùîìõí+¨ el¶ÈÅäH^>yò«_ñêËÃÅseŸ‡±® U’6îï},}tuóõ VÊîÙÅþ;åòÕ‹_޼_ƳS`»zýõýç_¼>ß/Ç;͇¹^.mÌ/Ï6Ÿÿö³vÒÍõýn{ùðÐþá?½¸ÜϧYêÓf*VOÇ€z@VÌWØE`é½wÁv@t©K£@…w G4sšUrŠ9@ë W1PJšðè'°ghŽu2InU*Ê@y‚Zab5ÿik& î&=F]×nŽä`2‰4'S€ƒkvÓ¤J®X¢‘LZJIT#c•D3…ÇAM­£&z›.þC?ñý¬ñû¡¯wìfË €î$¡.¸™r´E£RÈdyÄ‘ 3ËZï½EfJQ‡ZĈBë™é>ö¾ª·aV€p«™Ý=HžBФ¹•ˆî\?Õc)e”`fî«[ñzgtäa°ˆ dFbDˆš©ò8éEd¦»&‰ØHJÝ€4l(Ó'ÿéÓï~÷pr÷íæ,³¤Øû)ÕÚ²¸ù~³)`,}>µÃq®ÃøôéØöÔaãVe“ª•õãŸýÕù×ÕÊoÿùW/~óÛ¯?ûBK›ç%Åíp¼ký0m·]ùp8lwÛiç6^LãþÉ4b™Ÿ\ µr‹·žÇå4(¿ÿt²h½ÙÍ›ûãÍ zßï.Š=òò链ÿÑõAÿøO_¾úêÍv´gW——ûÍéþJ祋0®Þºè&ÅDŽÄn¶ê\t”rÒi&3™rµîm]ìk7àæ7š›)“¤àBÌÌ#Vý·÷XÖA.³Yy0ÑQ fÁ ×Á÷Õ¸kÈ®èêëè™)„2V™9°Â×åÉÈ8eœ ³ {Þ¤Ž´iÃNVjI#QÜMt¾EÁ7'Pþtñì÷Ÿ9Á÷ýJIzÔ‹Íܘ±6§H…™p§;œÌXg J1¯4ºû02ÍB¹ÒŠÓ‹—"Åc°-ån¤2g ƒ}5¶Hn†ið©Ø4–[)Õ§qªÕÁ½Ð Õ–B[à>¦¥…NâðP¯*üɽ“é/IKЭT©B^L΄îK_ŽMå“?¹¾?½¹¿Ïlãh‹Jd ‘Ù³÷¡Ž›í®?.)ÆFÛ~ZÎÎ÷¼_¼ú]ë†ößüÙÿÍǯnùâËÏïnñòÍ]»{¨ž6ìYœÌ6·³‹gç—Þ¾ùü£íþoüìãçåóϽÙnôƒó¹‰}µû)¯ïæMݽîo^½zùßüåûƒŸþÝÏ?¿9Yµé³_ý"9¾ÙܲäùÕù4 p»ººœ_½¾ÚäùvØTÛNI]“ÈÇY<­«D"2uŠèµ˜q”$ø:`…GVoäctË€•›33ÖÙÀÌ0²˜Œ„¿1©\?!¦Óšrç&ÐYò‘¹¡¥U $“4‰@Yí³P†{y»È™$U+ LwßHð*/Ñã¼ 8ô$`Å¡­Ù{[³Ã-þC–‚Çdãcöe­Ô·Ä€G ¥ë=SrC*Ý©GâQYmùG=PRÏ|[p9 Å(wF&KµÖ•’ÒTM«ë,3é¥Zká…b–º¶Õ¹"ÁÌT‰žkèË„È<¸On{3€ hIsVpý ‚Iò@C˜\Heª”¯¹o©dÜåÔŽÇ»ŒÓéƒï]>J«§åƪ,ôo~xþ×ý'¿zy(ÐÅ™={Vî? ^m/dôˆÚ‘l •̰G1#EHZ']•Aº¡®ó³L!ÓaZw5XôX‡$%먤h–æŠ!C=±qÛψ7´æ,A«|üTŒNúã¢7ûH™x7–H“jñqžiÅê”±H!t¡¥”Q3j)‰ÅCaš{ÍÄÿOÚ»5Ù•YzËÝcï}nyC(ueU“l^º{ºÙc#Óƒ$“éèê]zi“YÛ˜lzØÃ¾“ź¢P dæ¹ï½#Ü—â$ UE²©Q>À`ÈDæÉsNDx¸¯õ­Zí¶¦ßrho,‰ow½^\øf%ö†ŒRq¸Ê;h&VírQâ"B„SDÑš‰‚`J&a¸;ƒá­JxŒCI–,ÕG¢`k¢d6M#Eµe.•]3]ÔPK‡œª&RPÑÐÔè@n ¬í YЈ$­iŽAªN‚…Lõù1 €J3•e{ñ´-«»‹îxŠÈKEI"C?̦Ç)5ã~s2éfû›\Ve½Ùôezvrzt6Ÿ4çwæ¦í/ÿë¿ýÃ/5 ùá;ïÿù/þêüîùùé†PF×¶ço½MkTõ{ç~pw2×ÌÔ¿ó*ch§~x¿½îÒi7Õ˜Ú“wÞû“n¶8)™›«Mb3o‘¢èj¹¿|~ÕÊ(yX.¯NïLᱺÞå]Óþì§?My°Ä¡I™Ë¡`§˜0‘ZŠ»y­÷jøKõú©bä:€ðÀ ’!•¦¥u|P§œõ:«³¯~7ÒT:0‰0 #ë)UÝÈ!¤Pní‰ U(Õ²l"FÃÍLUÔ-U$1–Ø‹ ¢9$›QôXd.4 FÀ,/™‹çƒžåwMë_FÞè“ßh„oý߸óy0éG'x¸è Ù4ªB hpᎌž,¢"ÕCo^¡J&Uî…ôR É~õôË“ùâ¯~ñ‹—›OùââU¼xòôjèDºGŽŽŽîÍæÝ®¨.³ªÞ E Ó"R»¬5R%‡TDHb*FÑŠ(©b àꥤ Ü©jRD!!¨0¸ì±¬ø %i gJ“ô­Nê;±Ñ Œ£Ð!t§è)$4ª¨´P º xĘˆ '‹ˆ««×*¾ÑDª°[b‹|kÍà»Bc}í¿ã0:ØZT"˜’E•Š/SÜdx==‚ƒä'µfmDà`—S‡hšPUs"Ó¦i"A÷hg3±FZ3‘V›¤É 4MEQMpH7™¯¨7`k8–FUÅÒ‘ªECÕî½X>¦F‰bÖ½HC‘  &¤³Y*q¶ë·Ö¡mÛååªÝŽ!™¹è}2]LLFMúôé«™Šxl³žµoÏ^®j[ØKj†<):~ðèî¾éÓÙiFuõj3Êlq>;yk¹ÏTû±r»ß>ÍíÖÃLS3馩‘øìYŸKZmsÖéÐ_&MŸ|õõrß—1ÿÕp÷Çþò·_ÞKí?|ïÕMÿõ³›Ó³;“ã·š}~x¯ùèOþé§_l?½X~ýòÙÃ#í’×Ùb­•RRwcµÔWo¤¤pÕ¤¤‚¡’!J¢!¬S~*ÑJõR²öë{‡‡?„f3‹Èu¸žt‘š¢¢ô’(áN@’j£Zµ1›i#’œCH"Ì&%ê†'”TAc,Lc5H2gLT{Ef­Â8 (šD³™¶‡’*pzùÔæï›UU]Büþ€’ßÜæ_«÷õPDj“”¤¢0M"YMUJ‚Zªõ­" i?æÚxWmI%TKDPœ>Œ»6µ¢R DÓ˜Kλ<öã8 }é~þœÝ¿W˜“!¡QEh˜5€¦”HOmW²w©¨oÐM¦ s)t `£hMæE¶ÐD&Q1UªP1 {"÷"A6à$ýäDíxzssóüf“æ óénµœÌq<ûÁXVÚ¯§æÝ줔ÐÔÜܬö‚½µ›­ÿÅÛ³<~õ‚³EžÍ"M/.¯N'ÇÛós=xçù‹Ëܯo¶ãât>¤ë—+7µý~øêzûòÆŽföþÃw›E·íoDìÙU¹Þ óv=??R¶+V8íû››õ«ã{wCÊÛüòH›ÝÏen¤•ÚÕ5ŽUÆæÅ+m•  4¢€!2^½õ¢µùXk’‘,€ˆ´‚áU,@ª5¿JˆXг"âÄ0IÁR…QE[š’Œmê®ìBBx¨ ×*!Ò hÍŒènÛRqË$ÕN¥1Q´Iµ1mÇR­ËZ5gÕƒXi‘ŠÃ)ñ}Yä›ÇÎ7µÖïÐJtø¼u ă¢Ç’êòà‚!MÔÌJñ[$¥¨¤‘¤(‰ £ïû]?”ÒÅÇB„G”ˆå5pY5_\¼xëуiÛ)ÂDkÜ4m°nE’,5š:™¨LPK^¯@PÑ)PÀ5Ѓ Ð@21.41‰ðd]ñi ;P#úÄ«‹PãzÙìn´U›ÍÚÙ[è&ÑIÆÉ‘ÈédºÞáx~|gb³­šé ÃçÏ^ýøìô£ùâëÝ®;šß½{úåÍÍå~õ'o?z{1Û_¿÷N{uÖëMÎ¥›´áXÌ'³ ûaXݬŸmúiJË‹R¤åýGwïÜ9½ûÎýÕõfû²`§‹y <}þÂûWOgÇÏ®·ÞóÁù]¿zõü:27›ë¯úí¤•_ü§ŸYlïŸt?üÑ{»§WS,ö—ºÙ›`Œ¨µˆPÀK‘Èäph4ÁEØ•†Ld#b D„¨ª™E„ÇhbìUkß@$ZoáRý-"L¬íÑÚ\cHx-F,@ã4 =h’V‘¡h¥‘¡â`ï)Y˪Z?U§:Õ»{àÓirm®·oeaØ¡dzsÂx åÖÜ›PŠÛu"oüË·Í^·ßMUUá^}‡IG¨*«¡­òŽ éѤÆ)„Eôö‘›ÍúÉ“gŒ(D|[~óm=3úå³gO»¦µÈC?ö¥d1 CAšI„öÁ½æÁ_<¤$ .)C]ÄAŒ…vðÏ1lA1GILAñ€JKºzu¹ÙË8n'š¾Øêr£Ÿî)5h$ÚHôËWÌì)g§³g}ÞÌŽŸ‡nŸ}=i)ÓÅz¹š}øÓÇa\{9Kúê·¯ÆNgÃ~ÙmÞÏåÎq1.ï?œ>::û·ß¾ ݽSòè!O¾ÜF,ÎÏ»>úáÅÓÏûm)³£öhÖ=:ûä“WççÍóåÕæÏþâ~{„O>¶›«b‹±‰/?ÿõ/þú‡Ã0¾ÿá½ßøúןþ˽ÉB#J@µºUeFxñ2 $PT Å( ¢edT¶ÈÁ%(iUSÒKÅyÒá*VñŪQuÈ·‚+1k¢ö ¤×ëºBBEª3 „®tp…¸&Š’‰º1·Nxˆ¸Gb˜"2™E£vTU‘š)`C¥U‚Éßå—×gÓ·b¯‰÷µE~×ÔõLàAÕª³«V…H K!H¢*ÌLˆ&5Ý]štp UÊ<ô%ÄküË›ƒ~O¥ëÕÕ¿þõª4&jðð¦Ñ2R‘’à‘Ðj÷pr ÜCżö1P‚‚˜}„GhJ*Z•\ß*þ”D“%S¤IMÜ´£7î“ÔL<'Û’›eÍŽÃlÆ©µóù6ç¡_M†Õu’ÙIsg»bÖ.çG7™º Ïe—×ó“íôj»»¹,?½÷ ô×ýjüt»òé©–<‰ýƒfòóý\?ýúòó?Æì½Ñ…Ú5fg'ÓÍu–â’/Þ~çÁÉýÓ§/×O//K¸'Ýî_6«fù/ÿð¯«ÝÝ£…½ÿÞ£Ç_¼X-¯mËu{³ê¯o^ÎÏðÑþôY«WO_¬£Á•ƒ„¨VU08¡‘$¨Ô•VÕ€äÌD$‘D ÷A•¢M¥ÜFQ@@ èÁÛ+DÐåp¶ÄL­øîÈBmêÈ H€ÐGU %Zý*qˆN€dJÐUBuLi ™1 ê/Ǒȩjî!¯,·7ò×`Õ7g‹qGÞ²'åÅ×ëÚ›Ãû “àFª š‚‘³‹TóºgU!)IÝÝ´¹ˆVñ˜43z–ßÑœû}$Œ[ò EB"¨ƒHPJ¨1;Yú¼Û*§«N’MàE‘ÆiªÎÈÉN½ª‡P1›ÏÁ½Jçò¨¢ÄÒéT’†wX®û<ëÕº‘ñtv²Þ œÞM]³ÛK‹éé$;Û¯¯|:¡³G¦iÓ¤6a:Y4F7}z²Üß¿Ë,öéÁüDäÊWãjŽ»Ó{¼z¹zñô‹Ó‡çñÓ>y>nvý®È¢µ$Cî×§‹³W/w—7ÏîÞ¿{º8™MÛëõv»[­/·/n¼éÖœüý?]˜¯ïŸ?xt>?Û–Ü.·Í¯?¾yq}q~oÒØ‘·§÷üÖ³Ëaÿü2ˆò D4à=Qœ¢Ò@DÄ#M¤%b¯*t¤ð ‚áÕDÜ~¨¾Ô„ê‘!UãJ!°@ †‰HåW¸°¦ÊâbЏ´"·4P øZµ ŠH'bÀÔ¤ î"’UT%âe¬#mHšÈ1|g U9X¢ó-NâÐ;æ·ÔÄ߬Ÿ[Sñ· aoTBQf8xÜêßǰö`þ©73‘ µÚ-(Q1 {)<¥TÑQò À÷VË÷•Ðß9]˜£Jå@wTÔ Žd‡Ðª +€iÒF‘ÆD2¹¬ð1!šˆI„Bý…55n$§RÆåØ ÕðÍ«¸¼!bïÌÞûÑ£îülƒ„Ü7V¤® v/6˜¿Ý´´žû²ßû¦èÉâøÎbÑGù¢Þä§äÕânþzè~»KÍÉ{ÿù·ýÛOe3üÿÃGgg÷Ïæc»[újÓMLwëõñdwþèm¶'ÏŸoÀÝÙ[]׿w.n^Ý]^ï G“tÔ»GšOçGßyôÙ—û¡{>~²ʬD<|{‘¹q¹VNR@KæÌ¡B"gbT_ù(Kᄞˆò:lǬŽï¦"7çd©{.™…*êä(hxÐù׫­X a˜™GR ™EÚ*à±ø½_Õ©‚tÓY¸‰TÉY&÷b^»UeBÕJ’§ÉÁܬš¢^oà&’Yë¢0Å4…›üVv+—äkX^•‹|K%özÞqâ[¤¤4rÐ*2‚dxEjª LD˜Rr÷`Xc–LE’%"šÒaIá-Žoõ¶ùmó¿AúsÄaòÅ[@””œèUR¸Nš¤ÅÇÚˆ‡Œ‚(Q Æh#6zЗ&1¤?ýÉŸ_Üì?{ú¬”Áˆ‡ ÞvÏ®ýj,çÃ^¯^Dâ89jæwwë¡ðà—«µ,KLšc°_í®D'¥Ð›a+¥›s}ãWD'Mš6ñöÔɯÆÍâ¨ÝHô:ÿôëÍOÚ…ºæãêIÙMVÜLš~>{÷ìôøèìXâËç»ýxÔ.îŸtwOsø²šèŽãÓ95/×Ãú¦\¾¼˜LŽ»nÁҦΦ×ýúå¦îR°ÆT1‚‰hÚõ…¢#wŽA%Qæ,žL5þâúþù†Uör}Gv[ÙüðÇÞ¿»H”&Mb,G³ùi;ÝîöÝ0¼µ˜<<ÆËËè|¿{ÉÜœŸ¼ßùêj{z÷,KõjÓ {‘4l®¯Ÿ™uÝ~Ýw†(œ]U¼òJÜsîÝ !U«=‹5ˆmM‚Ó¥ªU`. J”pÕæ Œâë–p"¡Ö„¨Ö¦©ÕÀŽCk, á¥4ͼ@ ¨ ºÀªF xí#T”á°Q´I@£&qàŽNÃ÷õ‚iUsá š!…,çÖ)ÃÍÇÞ¬SóíT7ʇ÷ÞiÛV'];›‡cµ¼ÞíúÍ.–k/ÎqàÕN* ÿ`E©N|KYLTp¡IÈh“Ô*ÐÌê^of^;¼îžRCFÔš&r„ª%ááé团Ê>Yêà @M2ÇÑÅ_;Dš’j¢ÐPH­S ƒ4É£‡Zb . Ö,·èSÓÆá–%hB:ŸXò»sZûÖù)ûý ŽñîI;Ÿ}½ÆÍ~]Ž¢‘¤y?}GÝo†q÷NûèH†í“ñbýþù·><_n¶Ï_­¯ö«§ Kh6ÍÑw‹c]wG$mïêô¢¿žÎ¬ÈêÅõÅ“7“fö¿ÿÏÿñÁÝŸþí¿|üÉu³Ý A|vñqjš÷ßùèé“õ~;Ș­<øÙ‡?AþìóËÝFõÁÝî/ÿìíϾZ>‹UŸ_6MZÌÏh,ß9’Ýær÷ªí&º˜¦mJq/t N}=FH@5Ýzƒ1¨ÂÕp­ÚMµqé©pŠjª©$ŸT4Åy÷üd·ßm¶Ãf³-Ù7«=–l»·û(F?ø“I†Ò*R ÷Ð&áæ_U÷vàNŠ˜{¤$"Ú¶ÍÁM.j·³æ<6À«/Ÿ·3Qù÷ê°×⚈ðdc|3 0ãÉB¸—ASXÓݪīòu«jì!ZÐTâQ\¥U€°€ÐÇTÚ¦xîsßzßLî»Üɼ˜LÏÞžÛÿüíÏWÛÇ's=²ÑúÞ ûù׎X IDATÝË›—Û¼\[–cÏ×yzd‰ÏNµ,î,ÒÉéÿýéåêjšNu~~rzÿÎnq¿lì¤Ë¥õMlwwÎŽOÞºÿââêუŸtÛ·ùË}ùëå~Ú¥ý~pKWëI¸Ì& ¶å“g«û›ýùܵõî£{¦ýééÉÍj3DlVe’N:óIÇ|p?µòÛO_Ÿœo®§›ëºÿÝΠca€ ¡“¢P'\ÄÁL!Šû Y'b;€wµÎ×C“JÉr»HêHA#ü–kA†Ç!§$*ÿšAµ¦ž3š*¾‡ˆºVòµ'Ó @*‚$D2QHWk…LÕ8F”‚Åìþ°_íú|ÿü_Þ\-·kØ~Ø®÷ã«Ëgg§'©‘qÙgŸ>ö r¹´íB¥mÚîfu=Œ9¼´]ÛtztvœÚtÜyˆ+Ù·Ûa½éAdÔ(‡ZÝ¿¾áˆ™šR+ÜK¤¦Ù5ÑÕ© 5!Ý]SÒªÌÛntJMÓ4 Í’ßö­oÓYñÇ|È­¤3{HÐDDÑ4IÔvÃЈX£PA¥ðÕ‚áöú_ ŠhD3H/Õj"¢¦FìÓ0àòÕóݪ™´å“ÇW› ÚÙ£Ùñ¬ïŸÜ?õ?éš“ýüäÎbºðþúºmíjµšÌf'ç¦ ¯_½Xœœ,N›$›ýz)fyŒû¯dÊ~ÄÝ£eY¶“öÎüO^\¼8=9::Y¼zö5»nìû™4öÁŽ'm¿¾|òåe¿iš±œÍãá½Åóëm§¦ÍüäxqqùôÎÉüfàõ“¯OŽïœ¿µÝáo~óñùé£dúÞû?ùR?{²Ùñêææ'?{ÿÁvu}}%5–ðйúMh•~Q„ ÌVÄœZTÓ$X;Â5u§ØEdD„‰‰X@Ýûâ­-ðõ–÷oTϯ )¯'¤«°¢.¬šÃE’“*EE:fBŒÁ,Р¹#DúÌ2Úöbu½Â“ñôÅ—_|òôryÝ&qÏ›~è&i(dp·/Ûýz2É2DÉ×î(–¨»øÐ6ÊFDJT2‰”š“cœÃš4›æÕj×Þâð8´Ì5›$f*QDHJF–Of¦­ˆFd9pÔêF«c±PÂËw[^¿¿ûõºK¦&˜µ*Š.5mÛyD7ˆêv³ÖÌ““#÷âê–”(†C£]T5%ä.H5‹Z—‰0ƒM½$©›´6KÒæÕu鵸EFú(o=üpÚÅ~ùõrýòº†ã£¹ÐRÛ„ìšiwg6çá£&ßœwoM4ï¤Yt Ùöý~×P0>MͱӫÜOºaÒj_^Ý|½œªüèÑÝËßîž?_þÉ÷ððÜÊõnù Näþl>û_ÿ—ÿpvzçÿí‹{²lÓ¢“nØ–>–nŽI{çÁ»Ë›Ý“Ëk6§Ëý8M“íF?üèvòÕÍÊE§ûÒ|õdýâÅõÅÅ«åre*5‘ÐLâpý¨Š^4C,æµp›.* EL”΃ØOª$ý¶9¦eE\Ѫ0€•-Æ D2+¢Æ {1­ºzDÔD7ºg5 °š$YÊ ³Qè¡–pðÑà I ±fb}¹*EŸ^|õÅ“ÝgO/QúqDÓ´ýn7^(ššÇO¶>xHR‚c9SE«Ü¥é”ôÀ8øg_¼ð¨Xy$E2QÈlÚ™Z ×ðù¬;;™î÷c?xï(`%bÖ[[L9ðí“FD­òUDëû-(ŠÆ€¹‘æ¸!U`µ+÷M$øðÝåòæ´”Àèa‚Ò3€A#ØhÖ;¨Œ}n!9;¡¢iÜskIF D(&Á1Bˆ)Ý=\ET’{1k¨ÁELér÷%Àûœ©»ˆ/—¯V«Ëæîi×N××7/_?üèÁÙý; ›ÔžmwÍõúâëgýf•Îç9Ö—w&!ÛºõàY¬iîÞ{ø–½ß¢Œý;?ø0ÛÅé‰m'ÃË:/:-ž›åº¿¸üj~GfÍ_þèƒËýê³—ãó—ãóçŸn—[ïw'çG³4ŸèúzÍêjÓ7ÓPÝåqš:µ6`Ÿ\­wóãiÙ¬šdM·øÕ?|ºß¼”qì[ˆÅ£8‡~bñZJíÄCü°A¤» ä½ÜÊF€Ê¹‰Ã¢’Û9D¤ƒá(%"²Š¹‹i,A?Pv‚jÉ,N†@ÉR¢CÕ꜄1DÀx€ùM¡0Ü\¼xúbõä‹™¼Ù ϯÊÍz©%OçónÒõ»žÂÕM¿•K ©tÛnÜ+~ÛÄ’•ì%‚î**ŠÚ+ªÆ `ŒA€Û¼·ÛAün?N:[̦m;6»¼õêÕ¢B0µ!r“÷zã`JBJm =‰ÕÖY£ê(ª zÓLT“ˆÞÂ=º²Ûæå{åﬖà¡fo[à¦fP`×5 •\èÕÀ$4 ƒŽÅdÁBuäˆ!,Š0‘޳†@rîò®ô×Ýý·7ýÕÞ›Ï?ÿJ¿~r:o˜Óý{Nîœ_¾øä¨+]w7—è’?xþrw}yõþÙŒyÑ,æèæ‹óvŸ¹¼|uŽ»ãõõ³2úfµ»wÚ œMSì¸,wîþóg˯ŸíbqyÝÿóñÏß¾óÓŽŽ'ÿÓ_û¯~óéã››—_þoÿé¯1>ú››¼¼¼üò?ûù{þÙ««ý?ýãó›ÍkÙô=‡e<;›[:].³²ú>æ»Mÿ¼ÇÙô´™x¿])jþVj­ôø8§¦&ðÈÂPI*µ)_j±]áÐ"ˆ("&¨B,REËÌ¢á^ b¬ùvI«"Q$%‹ˆJªÚDb5? ÅP £PD¨–¤êY@ +:$@k[Њë‹gËO>~üìåêf—–›Í«›Õv7šÊ~ˆÙqZnÖCøèÎ’¢ô1bä½2fép(<0Œõ&& ˜LB¾~½Q%”.ëÑ·ÙûÁç ŽfÖ†ÖT BÅ¢P«n7îžmj5Ux¹€Œœµ1³Pƒ—¬jx-ÂmÞH>ú¬ì=Xk¢D(lT“È|ÞMç³íj‘¦“cqÍ¢*¥15•‰BsôÚ´Ì[¨ª1ª˜&¥–²+5÷}`‘ôîûë«Õ¤µ±÷ýŽíì|z<^\^l68^ èÍö7×]ºº~>\ MgÙô—£¤aŸ‹œž¼ónøjµ¹Ùl.Òä¡N›7¯Ú¹Ýë훋¯á¤íDZ›-¦ÇÓ§_l^,¯úÐã®ëf§®ò´Ÿ^üóÍóá§ïßûðÁäÕãÕúfûñݳÓϯ—œvÞ=;:Y¨ÊbÑÎçe?î ËnßËqS¼ìK±,ÏŸ­&“c•Ýñ oO¿Ún>æ·/{5åÅA¶KHLE:’îYlª˜#G„¥úÚ˜TÔ4„5kªF”Ü¢µ!‡†©°ö²õþ Hýçˆ( A“ˆY•.+¼„jºÅñÖuK7À"ìm@nnò'Ÿ>¿\å—«áòå*ã~¸svê9æS \ÆÕz,Áœeï‘mqS¨JK GT)þí`½<å ôJ}"ƒØe/ƒÇ$IJBU’Ù£&ÓƒUB•z¼ÔÎ{=+BXÍ*VéÏj¢Z“·ä;^þ®ëÊwd›t1i[#$úâ*Ò¥¤RJégó)CÝ÷ĉ¢!ˆd«C¸¦ :n é £¥qÞˆ ¡#]¯"MÚ]ì_>÷ëu±îc×!Žà^Rs³ÞÞ9ôéèéî¦m6µ—ë—»˜°L¾Xú|¹êÒê³/Ÿ¾\â­·›dxzùÛ£;óI;Íýú^óþªL^m6Mç“ó'›å§—»k¶¾ÚOÛý½Ez÷ü¨™}ðùOs¹Zî†26Ðù?~ü©£ŸÜ{çí·ß;Ëg_?~ñôù>5i·_OÚ4õŒaÜï6ëUóΤk§¹÷»ÇÝÞ9ù?ÿËþç_úñ8^ÙHzE¦×=š5Ù3Exñ!‰(-YK¶*u²¯¢"R"šhwHÏÑJ  hÔw4)õþn)¹û-•ï5à¡nØ. Õ†4©Bs/õ¿ Å,)ªc¬Ž#ävÊY%/qÐm„»‡6ÍË—Ë_ýê³ËËõr·{üôÕ8H›dÒ6]ÛaÉÞ¾Þæ\4uÓq7ˆ!‰FðߤkGà Èÿ]ùPv8¹'†Û‹N» ÔQZ%mZ)™$R“Ü“IM“ðÒ4¢ ¨”‰‚ÌÉùÍZø#›`c‰å¶ïÄš$Û$Z„G õXúÓD¡Õ%Y ±% C¤h´¢ê•ਯxõ«”f ¨4éoþî‰cP€IË>†z.¥ЧO÷>ú¤“É—Û~,Ì2QÙeL}Éùó´üõãe—úý–ÛÑš'Ÿ4ŠQGÿ|k@ þú«/=^’<éfçû~ðÖæaÒ¯†qwÕÏÿîz½X4øäñ²˜”Ü-¦ÍÕêr”]'9o—ÛÍZS¥ -TG“I/Îq­yG’¯O\Jfvùåß~urÚöÃ>Æ~’zÏR*Qj×R`˜ðLÑ!š! Gac ‰Šã¤€TEª”È‘«Žê6UD%uì(Ϙ Â:ùÚÿ¥ˆ$b„XB‹²ò¾â0´ÖºNwZöŒÆd1x<ýú«/_}ýbs}Ó߬®3´´­`6ow«ÕõÕÞ×öUøDH¦* cÆk{Ëwþ{ ßCâ¿VÕ®qî£-<š¥.I›¤ YR²šY²Ãê‘Ãá–´v¿$%‘ÊsQa¨ia|[ÚEüþeüçY™ @ƒQƒ¡5ÇY+,6G„‰€Ѐ,"áE8ŠŒà‰Ú,çg`ÓØÝÀ:i›yqЍGÀ"ýæy^[ÝÛ*;zD‰Ò¶FååXÙHÓŠ=L¥x6âËË Ô[A"B÷å¯&#K'4‰"LÇ`ÀèQ†"CñþÈ4 Â(\¤õqùò_I'ÌVŠL*))¢Q¥ß¿ôì*êâO<Œ‰RÂ4HÀ‹ƒp"HÙƒ„YJF¥‘¨±Njy膉Tâ¢3„nÿF–•TŠJ½úˆ‚ªpÑQý$"bµW¤­…8”·Üa+ž®€Š÷Ú D5‹(£½YöŸ|þå_]¬ûé¦ÇõÕÆºéÙ¼v‹£ÙÄ}ßLr3¶»l3¿Ùì·û!:QÊAÓøÇÍ'þý5ónX …y;Áñ¬cdj`j :Â)€jº…±J*­‰Îƒ2rkŒûCãùï›WT¥51@Œ"0—NEM&Ò$iÄl:äÜ'ƒB*rdfdƒƒ” uqG# ¤ˆN< &ÉÚpˆDDŸ†"‡‰‘ ðµÆÁoS¥ÇƒâOF©.Œ#pZà"ªŒ\»ì,o$;(cíZ—*Às8$ô0—ΆÌGˆbBâ‚$,=dΔjôÛHµ@Åm{q"9xÀª’0=àì@¸×ÍüÀC‹¨…µƒÈ²¾Mq¯ â,DV=ô ¿Á‹©šûÈȦ;E­æn¡ÚWdU›wP g„ˆG-µ"-U']Ä‚LÖÖž+ƒªâp°½¾^ÿã?üËn<ÞåÓëíîêzi²½¾‘ÎŽæc¦‹8ÅÛG”¨€ä7ˆõø÷gÞLõU7ç‡D£‡Ž¢;bØF§rÔVHŸ·]kMò(fV¼võv–%¦µ‘,fÖððÙoŽþqsé¤KBzMZ’’’‘\Íèe¿Ïõ'5è¼ñ‚…T‘A' q(¥5%ªŒâ°®õtn$raµ³4ɼ¸(r<Pˆu¢ ™™ JȬm¬ jHš¤@fQ$Ñ’EDcfb¤wB'mR •Œ`°R¦IÅ:"™û ô©u%¦É&“.‚ð-Ф4iJÉÐB¤z°ïó!ñTSĘ €;Ýá™1ÅvXQ&–%Ó!lÀ\©òŒBIbÓÚÆPˆ"P"‘¡5Ò‹dÍ1„X&gPåp©“¨PrÍ—s˜jÄ«æÆ†ÑGЬ1=É(T ˜hRM£_^¼üþËoö<³4[n®o6ë««›»§÷# è:Y._^ݬֻ²Y»½‹‰{=É‘ƒàæ{Õþàýä÷­Q³1—×_àñ-ż{'F´ÊŽ®š­1S‹Ì®íꮦfª(9‹ ±n½¤ÊnÆœI½Õ,Ëm©Çï÷·Øg²¿>ŽL*åóy³†õºïû=e!ј2›À¢øE“£ ÝGô€ÉCž%D¤N‚-E)##§1{xû ‹¢8»Æ<¢*f(QH?<&bÌeR¨} öÌ S7áïè‘%QÀpƒ†²UÙ…35VmŠdT18)ª¢z›¶.+BAR£ÍÍ´”š‰Ré¢UBÅëjQ%0Ž‚ƒ¸çˆ¬ÂT“5<ê© ªÁ¸6ÂH¯Õµã*FF€F*”AHº-®$X t¯m®ª&nELÜC\$LÈá*Ò¨µÁ‘@¨„¨Ž¹ýô³ß\^‰L×7/7ë­;ÌL ï>xpzçìÉ“¯.^î®–Ù S˜Hš¤J¤¶1•¡ønÈŒ?îùÎXã;—‡!ç7Çä߯íì£×°˜Ü…wÓŽÍ-²°r7k‚9Â݉pfèšæàx ¼•Kò÷çìá[mԜ誎öR)©´m+h•.aÔlÚHÕÒ Ñxì"2¤g& ™ií”4w·”Z‡´I¬Uu‘ˆ8ä ‘4E2¤&HÑ:+rhRÍœª…)ƒ„é7™)™ÔÂÃLɰμ„(-%'˜RŒú‰…9Ѝ¶mj+eÅ–L…MÒˆR_Ew©P¯ ñQ ˜1e•,în5ñWPéu§GÝ>œä8ÌÑc ªA"2e<~``T>ÁNªÒ0¤ŽÚLA!=œ ±D:8jáH¡$«½O€3•/ \!€>š&‘D† œE"pò·Ÿ¼úoÿôb?6¾z±ÏÑL©ø~·Ý¬¯>üè#(>ùì‹‹ç«ëM©ù1ca?.ÙbÒ&ÕR¼!:Õ=ãw¼÷ÿ[Š¿³àù}ywßù²Ô¬º~trX/,¥qÀb¦¢Æ(`Ð]"TÔ„fð¿µÊÊ`þ«ºKšTRkŒ0Vš8R×4Ð,¦]Ûªtf; ©ïP@¼ˆÁ“Zï½@M›û—ƒúkª˜ºš‹ä€ [‘yʹx:W7Œ2BBDD5Ž’D(dÔ±7k(IáábsP>’k²cã@ ñ,‡Fu~m¯+,m£fõÕäácÐCTøà5ø¦2±‹ˆ¨š*].58N&SJ5!Š Á&év?>Öl²Úqo›štUÕ”‚X)éVc¥¤¦Úî#˜ˆ“Šˆ¨Q=¤oÞ^š:FU»°ƒ2bqÈf9Vµ¥ÑEÌ¥}~qñ·ÿù¿}úxuïÁË6Yœt_|YQ/ËõÍÅ‹7ËLL¦³6$v؃õ´ßeÏyߪŒÁª¤Ž7ÄóÿÝß±Rý>ÔKÝàÇ@_К„¾ßwÓ¶i-¢R9kÚŸ[»‚ˆhs¢I©—¡6Í_'±ü»Küõ)פ´Û *B0¹ûQ•^½ûÄÄEF“.|Ͱ†¢êñ8ø•ëb*Ð8ˆÍ‹§Þ]¸ Þ4&¢ $gŸR=›R²ÊTD=–·fêN¨%ó5Ûþ CD<”;DUŠF¯ÀQeÍj§?»™VÅG€Î0IÕ_yÔîÀál“6%uª¸¸3ŠX¢¥r~°N¾4Š&I”*œ]8mÛ½w§mšŽPÔŒÙCuÖ,VÇŵdÕ«{þÀ¬úˆj§U"Ü!¦H·éªU†¨ÐŠKî18QHª6€FuÛfõÛ*ðôÕ³Wÿçÿõ_ÿõ×Ëîä<µÇø>?°^_ºIšvv$–ºÙlã¾·¡÷í¾wVMÇ7ӯw‰ þÿü¾úçû€ðZ˜m3Œ…ˆXi[I–Fв¨BDš¦a€Ý~(Îß—ˆôûÀœÝ^¢kÓX!Í"NüPÿXr.)s5 Ñ‘¬Qj7*Œ(êAæÝ«¤Fa#2UIDDéOý—ïý^Å‹Ye–Ólâ±W#¥4ñØ«4t§tjFLöD[]™‡rŽ„äôüC@ÉL8xôª»Fµad$Ó ü$BBQT²AJXª0è‚DŠ*Š÷¢Tmnq>¢IÉÃKà€Ja6¡¦‰P ¨Ñ°“®Ý{µ…ÚY%/@ÃCÒ‰2¼Üj`I©`Qº¤´ž{”$9‚I´Y;RjŒQñHl„¨R¼ªŒŒ[…e%´„ n6»¿ÿÕ¯õ/KO³wî Òd6í7}Œº8¹wr|²Z­óàûí0öe¿íw}XJ9çï4sËíÈ‘ÿ_:`òßÕY~óxyý÷ƒ5(3¶>Í>›s>Wª©2û@*‹û8–?òÇñ{c*pªUÓ¯I КQ¨†R6&Ðd¢¥9£LÌvŒIáHFå«!“—}•&¥d9F ˆ0=ºß‚Ó¤“ðhšZêgÑL1™0„hÕjðùtÌhº3°®‚Ç"3³Š!£šeo‰á)©—A*MRÙ£Ê@†êヸ*ݳªNíÜGá˜4šFõfC"Ì"û5C¸fÕhR$µDrÒT›¤^öA˜ª¡…Q1±¦é&óúæn€Ähà-"ð(ª «´u(ó¨Â+|Oj*RD©CÃZUzp¨¢ Ž*¡Ì$ÉPéj M'J‰Ú•.y†«›þÙÅMw|§™Îÿ/oo·dÉ‘]é­µ·{Dœ“™õ‡ºÙMrŒœ¹“L²¹Ñsèô¸’Œ”ICª9²¨¿Ì<'"Ü÷^ºðÈÐèFwiÂ`Y¨{ýâ<ÏœçëÃûëã51÷5³ëÙÍiY@›¿z÷¶KSCТ€ìüNÛ)ÿКùWî<üNϤB¸4)±Ì£œ0:],ÃÔL3Iæ†%<ùWëw)3œŠÃTì|:ÝÓ³´”ÓÂÊÄiYNÀ÷$3ÌÌ0ª÷{³"'з cÚ¨ÙÍ¹Ž `ùŸÿÇŸ¸ÍP£ª›E^èà™á&ãLœR÷æfXd=sìŒ x•8ÑfEÖiêýØÈIõšt‰x[n/">o×\#nÌ=tq+™³{éy1NŠ­˜…´ƒsŠIHšEDº,Åð:òP@PáƒÛk³Trˆåãv‘Dë0ã†ÍÌ^ÅptpÞyX3FÏš˜Ð¦”a¢L†‚2*ˆaîîÆo0( ·IGÊÈ2Û‡¥6šEvÔ avÂEª­áÝ»íëwñx-/_=W{Ø®åÝÛ {ùìõ_þ¿?û;ùåþ¡Î§½_Kµ×¯?-^¿~û¾%ÿâÇŸ¾ÿáþº­bšu}ÄiÙSéˆÐr”¾ÝT÷‡÷Ÿ?øÈ~<- ÃtÇörÝú2oS-„w¥Lôêu½L“ÔÉv^¦ÇëU⇈„e¶ö8¼w™iÄTËãþx*s/²“¢x>ÎÞ‘º¡è2H]æ CD7lƒ‚eF¨—çw'¨¤faSÞY±È©˜Ã6iS^¼ÌÝi²9r…(ìÆíìV"Zd«e1Ÿ3#ÕØãpàFºŸ<¥™œ3›9{†Ù¤0Kæ ûÌ‚NR3N©b‘Ým‰~… ‡Ÿ(U3¥÷ƒ 78.%á©£ 6ZPHÍÀÐ:\+ÄEO£%ºG †“§ÎêÌq9"†m’ôì}tÎ¥b¼)3W%Ü]5,f¢ÌfœœlØÉ K1¡î[æžÑI¿®õë7Û»{û¿þö×kN·¦ûû˺íÿñøO¿ùüןq|~7¿¼¹y~s²—Þ[Kp¾¹­¿{ÿáú황ïÝwõñN¯§é–~ tò¯¿Ë|{höÛ´|౩ö.Bu¦›;>ô‘ÉZýcAÅŸ²RÔ# G6“ø¦¤²G¶úÀd¬È2СnçÌMPÄŽ‚ìÊ(bFš•EÄÙJ}d† |v³JeÊ|š…^ŒÎ’y¥õRo"‹›Ó 9ÒÏ)¤5EñÀN÷µðLvŠ„¹pÌ´2ÍlrKˆ@=r†f£B0£“³ù„ìèæ6®b!23áq5¸@–R†½ÐD ˆ4*¡ó¸aƒAA ”—b„$A’Ù}¼wœ„‰2…¹¡ix1Fú‘qÄø~£35£ï” Ò€2$j©'ذ,<ý@=sß¶Ç”ýF¿ú<ÿËùùÛ7ZÎÏËTþåë·ÁòâÓÏ~ù›_þÓ?þüý5?yýüÓŸü˜`ï]Š-âÍÛ·o¶ûK;<°œ›Kßõþàeà_0[w­»ÌÉÈR‹™÷6æ˜æ^HîmèԬ΃ou¼èi[ÆÓãž-tž¦Z( v´‚œÌ£µUHñšQ`®»È 6F$Á­¹M…gÒ`€yMqU®f%ó3(k™{>˜1$&znz¡yFdÜF‹½8d‰UI±Ò°ÌVüµ‡`‡qHÔF7✠p'gªJf kV¥SGÚ§ÿ"LJ‘fôD ûh ¹«Dq¯@Svc*b¤3ú °£«ŒÚ42ó© F¤ ÈÝð]Êl:²²4êhÒJͬ Çz2w<Ë IDAT+2B!jbä6…š$ ¢'ít}ðËš¿øÕ¯ÞÝ«œ_šgkíñÏ?yµíñwÿðO—­çéÚòW¿ù\{3ضµx{YCOÛƒþ¨#¾ðmƃþàÉê¿oPöýeKm=²Ô:\EÆZlžê ¸ûì åŸ ‰oòTÝ(¹TÒ­÷yñRüÜâî|k ³ÂdFÐ"2Ä–)ã4<Ê k©Â&¹zB;Êdų#B0’E©b^À!¨ÌNæ@9Õ2g&Ø€kh3N)¥8Ý’VŠØ­Ìcj~0ªUÀjv‚êÒüf fEr`§4‹4­@L¡)7©t<° A¬DÉl Í àcfkŽŒnCôàSq3ÒÍ…:ð\FWÊ̆ˆ˜$ÁÈ4+©q…» B*$#ÍÌl”Žî%Ð4¬—†#w…0:1´üøÏÌ'¦©hÔÐsK„ ªDBÜÄy]»pzûžÿùÿþ»_}þn¾ûtYN—Ëý‡7{8}ùõWÖ–€ZßÞ?Ü#ϳgGëj£ôqÄöñGî Ç]‚ü7Þ;~¤dØ^®ý4·Û›ó•Å¢§ÉÔÕ#×m7òw )? Ÿ¦Ôz¨ÀRyÙÚ˜ûå80ÑÞ“»2·Ra6Õ;¢˜%FÌÝô¸€af‡› GwŽ»Pæ”a$’Ô•Ü s8S*÷žïÌÓÍÌÒ Àžº˜môžÙqØ`½”$/>‚ lÄnÖÜE™æ0›ÜªY9Ú Ž‚håfÍ=Œ…Y3RÜÁìD(vä„AEôMê43ÐӚЀ>hF9ÅÁ”ÜkÊÜÏÀLÔcÉè»ÐÉž±B eSl ÿ!'`Fóã ©¹yFË8=¡ã±ïp•Ú6ÖrÄ>açwïÿþgÿígÿðÏÓédä¥ÌQªÑ½»Ûù´ù•¿ë«‘ŠPOõŒ1"‰Ö•„j­ÓÄÁXÏ›ìvͳû¨Yj┘äSBR¤‚†ÌFfÄc¡­;æs¢‚Ã#bVžÁKªÁnsX2»›GÈŸ ò2û,,R& °<mDJ §aBkÔ¼¤¤ãÛIè`B 5³2>’Y棻:ó‰'4I½iZQ­¤Ì8Ž~È|¤™§H+<Ø‘âðEgä6ö"X)ì’Uxúw™Yž£Ì0Lf= ƨŒ><©+$¨¤”¤^ë’ª©©µÇ_þê×÷³ÿ:ÝœæÓ¹Øôpÿþí›w=Áb÷moõ ïNw[Û·®i™þúÕ‹Ø÷qYÝO…Ûß„¢¾UzÊÿŸ×†¾+ÚìÒÚòziË´Õ©ºyqôh3¢VÞG|çOrÜ1WŸ‹-ÕhÔe§ã).õ´Ôwéá**¥ ³¸“ ŠÌNŒ–AÒfâDCïJiî‘™¥k›P ì:|ÌÆž¬ uõâwTÏü@LÄ-y†]·M ’!VÈäL«†.aR ÀÜ, MX¡ª ÂD&evÙ£r Ž2³™("Ú¨šY"w޹¼1Ó-{¢Òjä>€EP#:°¤dÔ¤0›RI·A19È¥“D2¤N`:*¨à”häFF0ìh˜ÞŸÝÈõƒC"Ý­¢‡°ÏÁŽf•ífm‰8Èñ´Ú6~ùuÿû¸ÜýõóOœõúðþò¸>ÖóÌUXçN$)¥)‚^ ’ý¸pƒÚø9½åÕJIÁ¸Kíc¡Aº ÎÑ` ;YDsäÇ©ÝÕœd(FöŸÇÔ¼¨Nr帄™;òÉ•‚Eª )7¯ƒ)X ROZµþ0§ý÷¸Hø±ÍxPïåäÄMöQ‹…píGÃD—>b1øt»aݲ­ít[¥h=X9ͧœNÕç¢,å¤ìí÷öúÈóµNñ±˜E˜’‘S…Ù0©DñÙlÊ0dºÍÅJgÃШÒS“ûÙ¡ ôìæ`öÎ\ÓÜã]ÔÙ¸Ž·Yo£]¦rb‹Ûd͹Q aÐh&9ÒÅP`ü¸IQ¨’¹:-³›t€Â£3Üì,(3`D·%rKÉâ>¦NJ‚•0¡AM0ÈBŒXö 윱¸¢ÁÈL­ä(›o‘«[— 0Ó@ue'œ8°Â8Fà]™R¡6”ÌØÉ£à43Ð{'‡µâ„th#d˜7·Èf#¿©¡mß[08ùrú—ùj½äõáñúxYw¶ÄžêúŽ=Ä€j˜˜NÕÅa´­[±bÓ³/ïï÷ÈbV‹µœûvë¿‘ÒG+~f-•¸—Z aLL^Ãòº]™ê¹[Û(“yz6y4`ŒÈ Hi2ròáp²uËÙl$b|sÞ{úDKmk”z=ÝvbäóéÙü¼Ö÷üy‚…6!÷»g¯•×wo¿z2~gÛsã©z!Oç…ÆÏ–©–R愵7§édÛT-úV¦’rY> zz](£5ºƒ]SP?{£¿q.€•R{ìf…h‘&\eמA¤u´HW ÅKïáVès*Ån>A LЇX9Š6`¹õxðr tXR ä(ULˆæ5µ#™‘&`9Æ£Ï^52ac0Õ%ñ‰Ñø”¿5Z•Ficù¤!í =ŸUÝŠPNȬcÀyÒá½ä4Qj%™PŒ G¢OÉG?ÞYãÎ’f°…®,‚¤Õ¬ ŒåÓ«SŒ@ª?',{ÌV͵îÑùݧ|PhŸN_œè“£RËâËB½cÛÒƒ’è)ý.jD=âr‰ùæz{„Õ2a9/)a Ó­Nõ÷MÇÎF`¿¬ýr-†H–iš²Çz½N Ú~·˜Y:èƒðpgšÜo3öÌfV‰=ö·æ[•:Ev‘,>hæAç9»M{ç$F‡À{t-ƒœ3sœÐˆ(Þ$3›Biæ•ì7Åa\$— X59œ„]"Ô¤,$q%o èÆÙ8¡\Ìû°9õ$î¯þêaV2s”'JA‘þ ˆÖÔ£a¹QM7™;f§0úS¶±ô0 ™êäˆè¥Y‘B!³£eÅt`%b¦è]&4䍿ùæô#sƒ©uüËço%è÷÷ïËü|½nçÛùÚz|èC¸+äYe¶Ð©Ú'/Ïë¶¾ÿÐoØ“ÖöÜ2HÔb·Ó™VÆõ)zpEtqô}§RñinüÍXé¼@Nf¶›ÙÈ;}ƒ£"lxg(ÍÎÉÍݵšÍK¹9/Êu»Þ·-”\êT«ëº=ôÞõÛˆJ|Ëöß›¢ãþýý|Þæ¢GRëÚÇ[bªK4öCéHaß³YDî{¿\7àÞ‹ÉPQ3xÆpÐlÌxí¸R0ÔÞ%n¥ÜI)Ü»{B+Ý|v8¿B,O±žŽ›¡gÔZ#:Xž)ÜKU>ë¾Ô¥-“·Z ;-A·)#*;KJŠlÅÏBscƸ!Œ£³F÷;Ù ;¬VÚ†C‰”ÑŠÑFLæ®–6# È9"”‘O63 p"öÌÍIeH£i͆åP˜ ¹™çcÿ¦ÕÖ|´ÕÐŽ–Ѓ0©A¹‡ÔÁ0šBèãè\¼’…DëýóÏ‘89?¹»{ùx}c¥›ç§åq{h•XŒó\N3>\¢§zdöu>•OÏ3÷üò݉U³ÌDaí­õ8î)B¡¥ÒÈñ7 c¿žxÀ4šÃÍXh@ Ö–£$œ48€zÀ2pšçê>9ÍD“¡ÖRk­½mûu/e¹y>•ZÅòþýCæÕÉöTVÄßát„T"âë¯K}Ó£öÔ\aeØû¦ÜÀ—dýëâ›ë““$ŒÁÆ#ÜHŸÊ\÷Ë¥N“H“MN"{ä5)¼`ßz´Âs¹gœzaƒXÈ“{P¦Ù£eªÀR…2¢F¿ºÇ*÷¹uGŽ/Fï3¬ -ÓÝI »ovLÀxæèÍH¢“2ß²]Ý-UÁâ¾ âñbNk¦À8¶]2¢™ƒ`*˜÷‘q8Æ•n¤ÊaFVløYŽ[Ž(Ò§‘ÚñKÈH)éŽ4ꘆW/Ò æ¸ŠhR2ºà0C*‘R:kJÊtóĨÏ.E»<^þñŸþn‹‡Þ)=ëû¶Ìϗžþêý¿ùpÝòÖùòÅy™§i™ßx×3"1¦ÔviÝ”k5ïf|~w¶:½ÿð¸õ¶E’2X`05ÕñÃàp©Æ[‡F¯\–ijí ©iO¥Ñ ¨á\\¦y®SÓTϧ¡lûЩN§[/e[¯ó4ßÞÞ̧ªìׇ‡mÝ8תÞ×O[ÊwÆÑZbÝs*È÷o¿¼¹½+ÓMï}½^¥öh<'ì÷j)Ï–åæ´°˜ŒÑÍlžoê4eß_ݽV±KÑcŸüTüdœ¤èµ|Bpm‹—[áBT³%³lØÀT‹ Y$ÏÜÝ&ÓD«Ð<ŠˆfSd—ºyFOb‚.4 ‚äÅŠr=tFi2$¢¨ÒS´3Ø%]aÒª{TNL´J/~ëa#äØÜvk@G·:ý£Åiˆ•ãÝÓ“IX†Ól€Œ7HK­´-ÓÀ›ñûguXÙÍ(Ž’º2ÈÅ"G¶ÞHtM³õ³Ì£ò”N3PŒ¡1ŽƒeŽ‚QWðrY÷Íi?êÑZ¾ÉÜ+ïö=2pzu×ÏÏÏŸK-÷—ËþØ¢åL¾Zê_ÿùýÅW¿øê26ŽWϦÓâÅËýãö¸ïr©ÓÂJá¡_ó[W ¥<"P­Ü.‹“ÍéµLµz³Yš¶^*²ÐF „Nõ´LsÏv¾9GïµÔåælD-…¬¤-ËœÙÜ3µ“šO§×eîzØÛ·ëY;ü5ã VйE=Zïß}®Ó§Ÿ|ú£;µ& ¶½õvù}=âÃ岯ÜéCµØ>í"š®Ë¾ÿ™ ¡“™¸Ãtyê­ùMn«aê9 oÌlÎèàf´”e”4i/ŠæÎÔ8ÕR3vâNzŒ gƒŠ»"V·%ý Ô)#g²€+l&M*L™èòT#.@’“Tyð(„ùH†YĤ¤AÄ3“ m©‹ûDœƒMp0P{&iÆZ3bŒ.3!5 •èt‚Ã4šÀÒ])ŽŠ,Br ŒUäh¥§d ’™]rº›ŒGõ\H4%#Ó £ÑN¸™383IB³¡4m]˜~ýÅÛøÇ_~xoŸþè'ñÓgïÞ~E›¾x¸N~þéŸýôùó;õµ[NSöývÂë»ó>ýäÙíd…6½²ÙÞ¼Y[Ïbþþýºî×]ôþ8i*vEþ–`ÿ4üÍ1¿@‘s)HNežêâl=Öy®ëÚ$!5ûR]óâãœ<ÕZ|ž§›óùäHdLµ*23%ÔZ½ˆV[Ûiš§ÈvevÎÓß#ÑŒ9ráÑ¥º>Þ3~²^/¨t¿Måû·¿úoº¾U“¤”vÉà£hÏ( kß@ÂÕz¯eô{ú =6é2z£Z\B-T‰JÛZhÈ;ZñÒÜïž¿¼¹¹µãÅ*,©,u(ò¥ÇŽL‹¡í§œ9M¥îv@GžÄÓoŸží‘K- ï['ñxùüùËO£ïËò¢·«â_ûµÞÝ|ŒãÌFÈ~ö2ÀŠÇ>S‹²c*7ÀÚ[ è„A ¹›±mÝŠ;,A3%É`0/T~0°€S¯Ru7 ¡\Y… hFÊæ¡éšY#º$d7› W6²§6„‹-dfgpɌѶ!\3(ä 2ì8Í$ϰ6)SK±*¤ò$^#”Ù”2BæCèlÊÍ,£ýPÖEZ%M"±)íæ£R^ŠôhŒQ}Jó e×*%m‚L‚Òa%5ˆÍ(b§Q˜àSjí> ‚5”†0ØÁÌí+l-¯W\ÖåË7õÅùæ±Nv3—åãåñåë×7ç×÷ïÞÝÜ.?úÑë\¯èvšŸñüGŸýøÕËÏ.×öî«/¿øßÿ~oɦ1%Œ<™÷ {jÄÙôdCþn3աϦZ.—ÇZ«ÓæÓ´,çÞ÷ˆ°DßûÍù†fó¼ »{LSüîù C8¡p…%Ó=‘{fû’HÇ1^GFïÃð%ç;z(HDb[»›ejoûÿówÛÓ¤xê™ù0³oÿG1;OÓíiê( Í¥P½·fµX­ÜÝM¤yÉ"ù¡3%zj˜…Í­.¥¨ÌFo7ã‰2[Œ­¤œHXƒÆa¢NÑi&ÅCrÍp¹‘M}“f3˜™™°“2K„(‰•FéM`ÜÍò¼Ù¤œÜ&àQêHƒ¹d~ _GkÖ¦Aèbiå í™2+`Ï„‘¥ÜõCcæ1®££ƒ™#i6GŒAޤMêF¸1²“åø©åÁŒUfª A˜IŸ3s@Ÿ”#b 70€F£'Œ´´—”[©vÓ#½÷îç¿x÷á2¿yx êi¹u«{×~y¸¹ùQYîçüÉÍ«Wϵ¯±¾{u{º;×Ooÿâå‹—ó<ßΧÿå?ýO?ùóÿü—_|¸·Ï¿~ÿóß|ñþ²Ÿïn¢sÛ6±¿¶Ø2½ú d³Ò ñ|*sŠq[ ˜ªg¶ˆíòØzï±]Á,“Õ‚yž–e¦}]ÝæçÏŸ{=K‹-` ìÉ6€w„œÉP·âÅgô\3¸”iͽI•–px:¿aéK[‹›¹¶žn,†kkù= ærÿ×Ö£÷ëå’´C®uºq:M¹­>\ʧçÌ!ó2E7Lã³4)¤b|–J/“TG”ÝŒ DFî$‘S0 lsÜ’¹ï›sJôR‡+Væ…Ø{öÁö%)‡‘ pÌy† º÷îpˆV'éN„ ¹O€Õ4Zx Ô"{ÄC­w]»ÙBÚQq0Ž8êbB¨H ¸%7È%ƒJ˜«A¦D˜¡Ô°ShDMFE=tÄ¥7¬€ø_ ddï*¥ŽZ ³‘èŠÈ#ìk¦Ç} ÔY”AÙpä"¡¹V)S;½­÷oî¯b™Ë-µd`Yn_¼øIë5è×Ü©vm—‡›©<;M‹÷óé\«AYÜn—ù/?û÷x·ä'/_~úúÕ?üó?ýþ>ºef€’*y.!:BÜNäŽâv{ž™Ê“˜Á½_¯Χåt»ÌµRÙ¶Gˆjyº»«4¤ ž=ãèÊ6”{÷"…»øÞÚØÉçù¼7­¹9{Q³â„±­í»ŒUº—ˆÜ[w£ ÎßÂÆê‡}ø|J(”'¶Á(KÏ=2õ±û(Œ…V”îöèâfL`ržÃkæ[‰ns‹YH%3K9›#é,¡fpÿßþןfÄb79h¢™HjDŒ´:ȮҨÒM˜žO¤Š0$•é€2pÍÜ©ŠŒÑ £™Eæè“ˆQefc1Ê5;ÔÝ&À‘F?¤”Öc¯×QG›2Œc¹±ƒÖ•IsБèC¤¸¡-šMàˆŒ)gO5Žu3æo´7ðÈ0wÁ2m pù IDAT†F¤c{n”m[ :Ÿ§b~wûâùóçµÐ‰ÂTlq{{[¬Ò õ‰FÛ@šÓ3ÒÜlTuiܱcß¶½õ˺òÚZ1;/§B_[ë¿å§'¨Åju 5^øA.À·¿PÝ–ZJ±É­k-uªî^k=-‹ÈÏ^Ýýû¿z}3CÉ Z9ŸoÌšY*¶èk¥ þA؈ Éx”ûÐ,öÉlga+Æe|†Ð£ùXÅ«Ò 3Ñ‹/]`¢Î©¬unû5•B‡J¨ (ÂÆ5ºf8S•X ] “™e¬‰BÂp“êî³F2ž öœKª›îvEZ¦¤jæ† ¾Ø‰™V3c&’¤6€â^¦ŒơԠuzßsJÅêaû‡ÌJÆ8p'(¥hãä‰}ð_r+™–˜À"2I¸LŒ˜ìã(ÐìÔ"NËòïÿØ^?œç×—÷¼î¶®o_¿~}w÷òþÛuoÜ1—ÛÂrº»9ûã²ètJ¬A#Kñå\F)×ëOžÍÓ|½´×wÏ^,矾úìíÃãç_|ùõûï·¾‡2e(I¥4MÓ¾í$#z†Xnnoo§R½Ø<ß…Zµ2—3(¿­Ëòlš¦}ìÛCÆ:ÏeYž&sßúöÁÊI6Ñ2µ1kÁMÏk)E©H‘NCäšj^Á½—¢¾íFÕZK™ÖmÕ÷†X’¶…š'3C…Ü“?æ~8ìLÂÇÿMö”“‘ ´¯[5/>•r¢QÁRÂ>²³Ô ldƒ–ŒBçL>:{ª§&çLß¼(“©û¡í–ÌššœÅ%@¸ •&°*wÓ2À™ÚIssS' ÉÝB‡0³Ce”|·œÕS¾Ò{fËlô)³˜§tUÒp2ËÜ¢¥ÂŒ„§x‚ž 6³AžXk:QÚIp`V¶Ôfv2Ìf@®=Ó=†Œ˜ê #g ¥hJ'n$5;T jÄa±É (‡×9çÃi'`€!L©c\ñÍÜKfrDÞ´"pC×ÔUi¥ž"Œæ£G•Œ~TøØ¡…“5³›g$ÌÏDDlO#OŽ÷h»{JD6õti¶:•Iy½.ó³/ßöuïöÙ§™~s~v÷üõç¿üE.V²ûÞØ/ËlÅJZjÑÖëZlxäÃëT«“1O7ëž§:_[žŸÏ¢µŸü¸G¸ôdy|| Y¶¾^¯÷µÌÄ4Ÿîî/©>ÕsYNó|NEôîÅ%Mó2¨N`<”ÝçÙ·°â½·”Ù´(¬í›-ÅÝŠ<S)ÂÕ¬Ÿ‹ض_{¦ˆÃ+u„²Lz,Kæ Á¥XæÈŸöÃ)Èqõ.=CrãÇØçS<†Ñ/X ·Œ›)ÍGzÌlÚcƒ¹Ám<8„,­¼u+>ùP2&b§Œ˜ÄŒH:¡Œìf]Ø#;ÓiÅX"Iл w„Ä5³ž¤ÛˆtT] è`7ð (‰7RgÞOP;Àwã/ãÐûJFÀ qäiŽž“¡eÑž°Èì€Ìâ)Ô†1Dpj¿V·S«4’X7‘ì‘fV#36em €ÑÁá6$FÊßÄ̈R¦cìæƒhì¥<…Ã̇çD>—rM»Ú®Çû÷=ïhwû®_ÿ꟞½|>Ÿï2Ë‹ÛèQ‰z3ï×Zv·V|´áÁl–HÖì9lNfVê¼´-ŠÁÂtZ¦y¶Z.ûukEãÝ‹’Ô~sê¡ÖëÚŸ=c-±‹¾¼¸»³ÊÂpËÌŒÞ[o3ÑZw7z¡—HÛS¶œ"÷Rç1ôwŸëL¶õâ¥Â<”™ãµ(wë$YÜg÷œË¼öõ²ï¿Õaaœ¦iÚ·{¥³œ&#Zæ°«Ì Ñ{3²¸¹}Æü­+)¾Ôz»œÝ§Tï¹™ÁÜÙc­üÿ({“%Y’$Ëî^fU53wS 9wvu-X€°a‰/Æ`(BcšÐÔ]CäP‘op·AUE˜/b/3+»²º°Ž/<ÜÌÔD˜ï=_ýu©Õ} r”¹ I± pGK‹A=7‚^X¶Ä8 ºáA²ˆ&ÔâÅÛvO1®ŒRºäV<úØ.½úØp›dT.bÜä¤m‚¼Œ‡ߺ=¥Å ·WБ¶ŽåãЕ¸kÌF!ŒXÈ’¹™õº ýlâvr2÷Tdrì#â~9A%³’YÌ<‘JËMÐ…É|9vƒ7‘‹4Â@}DX4N´îRƒÒlŽ>œÞƒecí•Á’202‡ÆH@Ú®}kÊè]ÏŸnS-_}ùp|x:–˹—Z÷­NËTr¦ÕnÖë\'Ë^Ü£W}>¡ôÞ„ •¶gëé^[K‡š³)§y2›vàÑ¢ÅæeÒÄ(4º Б©’´P/æ•RvÎSë="Û[ô¾ʈÞ!ú\†@JLSÙ[‡hNÉ"„L+•´ˆížü<Á7›ÍjkYýqi¶p1£Ùhs©ž=if^Øí>ЃÑ3×}ÏžcE=Œ 0_¦²÷ýÖ±½;+ט’µ,‘ YdFv¨'%ëÔ[éÔû^ÊÑp¸oí¡ÝýT$Õrèí“•¼2ó‘šMÁ¬J'’Åg¥zoÒîe¡*m¢¬ÇÙ,Ì$`[fË\†®Æ y -2/`5VzRê sŸÅEj´â5Æè)>³ßl$3¤rK…yÁ} )33eC!!û€ÊÙAšïÜ€î!æ€Ôa|ô!'¡YÞ±"½2kªæ,Êdf‘iîà=vƒáP¼Ø ŸjÉæ»üòòÑ}¡™Z[ŠEkµ.§OýãátÔþažáLˆÕ'È£‡UÐ<¹NÉb1Btٌ̄d…™-= ´E˜{ŠmªNØ[ôy®${6  ག¥TI¯5 ö=d*óÁûvSöZÊÚöl[¶hm•'m*e*@ä£e ¬+8ØXÉ©x³0cdëM/ëm˜Ôÿtaâ¥ÔZ·¤J5ª$ôôt¸œWxñZÙ¥¦züalöÏ|±dªC{ý¼ä$MˆµµPDêrýhöo u\èçéX¼BtzƒxJDÄÙè†vi'é¬BÏÜï³ë¡©…ÚŠ‡¨D@¢ ØÍ‘a4ÏwfÆp!'°7÷Û°g$Í„4›ÄÉùV¸ñh¨=/¤€Ý8Ã=3œL Àï M²0ˑΥRHrà^2W¤ŒG÷ViWŽÕ€ñÙ#Ô„ 9“UX lfŒ=n$¨bæÐž™ä 3s îb$3S0s I¸Ït%#Ãh=i™ñùÇQÜ@Eö}ä‚É©TŸ–úòá“ÕwóòTëãºëp8ÍS1EFW[‘[l×C)N‡‹H¼¸T"sß÷-8ÍÐ##[¤Xk4ºY¡±Xo½ï=)˜2!/3› â䨷½uÁeŒ¥”ÉÉè"cüÏ–j1¬K‚;æÚBœ äÙ±èÙ%S8dƒ:äf.uD##£™I>JÖ­õÛ¥g¨ÝM¨ †•Êоm Ìm¬ÆzO7“óÖÚõú™vÇ`ÿÞÿPflHÒ—yÞÛ‰iªÂ-±NvTfo׈«—CöžfN†¢›2{[‡² `‹yÔZ{xf§%%£Aká,%mÜ"°ŠE)C6–ܥΦTMÂÖãæœR »râ¨|‘Ü3{èjÞÉ’²»» ³*5`£g"¨*‰èP+ÅR™©Ì‚ AjìÞÇ`z@µÝФTsG&±‘†´Ï\¯Rü9Ê£gÅÔÞÚ Ìî9êz Ú P’fFÏh°ýH°4 nÜ{ãô’‘n®l™;Ébîuºô+íÕõ™'òq9M¡y>Ôw_þ(ZWìè[¬Û·‡ZŠ#új.Z¯Sìý¶î_VŸ³ÚÔ{š™Y…|Ûå¬A”j¦©&,1ëJ Íò¨°Èá~ØöØ{[ûm^–iYªº_udÒkMY´Áp€a(Ö¢LF¶"¶`$"£÷ÍÌIHðRG9203€-³ ¹Éé°ŸÃÁ‘=²ó^/±âÓ¾_#ö;ƒ'¸×‰¹æùºÞâŸÝE’§ã<•ZÌx§ÿ„™æc¶¾ÌóÕ›G³4&¥ˆÕ\šÁá F'GJ«>‡mJ(jâF\SVä¬,°È´‰YŒÌ݈T!XêCäv¯Íb’ pCoRš…BÄÂrR µ¹wåž‘Õ&±¤vi‡ÎÆ7‘EÚGîF(6A›†¬=ev3Z‡È”ZJäIŽÒJË1]1ŸÁ)‘’;j2Y¬<)2eb€+P!Òª¤Q è2MfdÕð˜ú Ê L5Z•Ʒ˸…±K4=ÇKNÒàè& æF"S‘Îbt™C.„‘Ñ¢L¾»í7¾~üåÞ—[çyÝ~ö£§ã<Ý.«Ûôòüû¸\Þ>VçNÛÇÛtòÐ{2ûõ¶}ÿñòý‡ëÞÏó<Íóã´<´Ö€P‹Ùc™k¥ÉŠÜåDk`–©ökwS)Þl¢ÏÑ-} ­Ø¶©TÇÞ»ŒžñÙKå´w¸™±´ÖeS=z©Ní²D0‰9ÉÌÜûFúÅhŽž=³Uó1ì¿ ¨Eše±$`ߨ½C­•Ù»Y §«¸Ðb:=¹×ýÜ<ÍïÑbþY_Òå²Ý¸x:.¡¼\÷ÇÉã²*ÓÚµ1ÅÞJ•Þïi.;!=÷ø}7;ôì-;8јZEÉJOÕ³¦®Þ‚T!ñ¾‰kö×B£g¶ª„ÃÕlÜŒ•\2ÓX¥Ýí•°*¶Œ4ï½oîIWä‹Hg‰ØŒfV2¬›¨!óþ¬(1Ì´¹‡Ìdðqm ¢{ZÜXÆáXÆ´ŠV`Ãk¦òqÖU#qËhˆ«œ yŠî ûìŸ_3,@1ˈÕÌ0Ή.¶TçÝA 6†ò†±« #SM÷¤bÛÛÞyí±Ç´gy}x{y‰–ûz½,ǯɾ·Û÷ß}·½¬È…hm¥¹™§ëµµh/—õÃóúáӶ˵öReeß{½š¿>œæÞŽY§¹´Î}Oƒ;Üåî^èfL eÈK•¹â¶u%3ZßZ[1òÕ^z’DVj!²u£Ì3»g :MÙ¤ÅÐ[™kHfî¥\#AUcþ ¢;s8hÁá‚E°‡&÷Ãl—}Ý׫™ùr½}nçëŸËºC^SçCñóí}Ë,ÅE´žÅÌy˜êŽ'¥Ìw3A»ôÒvw$m§u" ;4$*XU3YÊt’‘7š‘Yˆ…¨¹Ÿ"o;ÔK1©-sý‡—a˜x#u=ƒ™œ61¹X ¸™€Ì>ÑElPu–á±÷èI‘–4"R­A³Ù!d*UmlÐ#÷q·û«dÁ´ÂL, 8’Ûwhê(ḉ‹®‘¤Q;Ù€eË\Í'€‘+°ç@ÐÅÒ½F¶ÌHYi/eŽ´È ØÉN>RŠˆÕ,÷í,úuížc>þ[«Þ4u®ëþl•u½æí²cß6¹ŠÝ³ãÅÑy9ßÄéåºþðüò_þî:ÖdPm¿ï¹î1/Ë«§WçÇ}&Þ<=žެ™¬nÙS©3M£Œi¤1¶¡¥¦Ãñôäæ 'Ä®ì¥ÌŠÜ{ 3¬éddËÞÇåúŽõàØ#9Í=#G ×ÍA(TTçRJ±­ÇçR#ö>ÏÊÏüÔå€ ÉHÅXŠ(÷ ]Zþ%™8Ã4U©P§ÃñôðàÎÛ˹Žêvï“™—Bp“zÆVª+®,‡Z«¢©3% !÷Ü™4aä¬Ë}ÿïÞ´íøáÃûëvÛ¶‡Ù8µV/çØoíd1•æ†Z<“u>%¦¶©kºÞÚï>¼üæwÿøißn½Ýö¼œ×ëóKˆ]¬óüÃûã4Õ/Þ¾=oo§Ã«bó2/§Ã«mïÓ\‰Þ[§U¦§šX2½–ÃTOM”* ¸Z/F‘,Å¢mR(G2‚,µÜ f™]D! )¢µ`ªq–6)hƒRå…˜@(ï ¼?É©ÜAG=÷u¥O¹·:Íë¾æñzˆ1ÕÑ ¸ñåÓÇõr)…&ö½Oµ,µé…™kj‡õZî³ÓŒ0cæ*t‹€•”‚ÝåÌÙÜ+PZÛVÊaœ!KÏFÜÌ´ÈOÅÉBfÄBÀ|ÖİŒ…nR˜¶Üš£[góˆ Ž]¬F®dcY¡ô;{ÚÌéw“œš(Z`ÌÜÆB%ÔÝ-•”‘žI€fuˆf^¢ïª˜9ìビ2N\F¹´§Ýs¬¤€òÏy̱m(8 rã,t¡IÃ<È`wŠ^RDÚ d•Iy%k*%)'òd”óãép*ìÛíC¿-åàŠ—ÌN_/—ÛÇ÷Wì2×užrž'=´—Ö­cºµøtÝÿþW¿ùp{ùx;_·øøiýýûµu*!ÆK[þáãË·ÇO§eš_=>}ùîËÃùüôô–Ó‘¶°€ŒÝæEk >Ï“ù”‘2FP|š{6@‘;ŠVªoëJcõ)z3LÊ=÷€rœ¬'‹ÀÖ/R¶­Oµ`Ø ÜIõ¹Ö´Ï ±QÖý“ûF¸ÝnëºNËÌ¡ïÿ*{ýçÂp±'Øo;Öqø®fÉžÐÖûõÎ7©žñ’Šiš£«.½õd³²÷–šÆô ƒ¢šƒ¹ w[¦+­ÀkoÏÕkfPÊæš`"DK¾GãAé´.íR¸—ÔN‚²Ìœ–RË;þ ¥•ž±'ÁiuôéÇ®0rC‚þH„ O™›´bh‰ÀFy5¦ÔÀ ÊŒ”ÂÓÌ‹l7›SaˆD5ÔÔ^Œ™ýók’™](HFßM=±bü<`†KjdGöHi®¡kB ãÎ+¹)csóT‡•0›z\z4Rý0¯ =<þèç¿xÛÒ~ý›_ïûEFGV›™þýï¿›ê¼Lyð}^ÖڶѸõÜvmM¿ýîwÿÍ7ÿ«oìñÕ󵯛.×\æÇꕦÈ~^÷ Y¶à‡@[jýÙ~~¹öÇÓ§w±¿Ö—‡SFD¤zï"Ìíáéf½÷”’NºY¥K¹¦­FóâRúTSÊ«Ö-ÚÍÜloÙwPÛº¹³÷v¢ƒ÷i0ØKù¸xߢßwõ²;ôçOÄö©mßöˆ¶ÞŒ>MÕ«×ÔÞÒ»·o[‹}ß3[‹ø¯bî6Fœ~‡Vj2kÃ=‚âËcj’à¶ .°šÚ2éVÕiVcZ;ÐV(f{ÛhKðâ¶XéÑD¦è%ºÑJ䪌Z^EÛª—è7˜'ÕɆœ`ÇÐ¥Ø!º¬r$ä!K…±%|ï݉[†” ì ‘ÉJ·ˆÝ,{É•Smlƒ…‘¬LÉI݉Ñ#:a%ÅÌfD¨ÓJÞÿ}1ø“ƒÇ›¹g¦¹enïrt²uØO!Ò,ÔÆ~Ól–ºTÁQV‡y%,Ê0ŠZÐm˜™w8dN7°‘ ­ÙC¨àã»/¾¾nûáøû÷/ç›j¼}óúü|U¯†Éy>XkÉÜz¶2.Ï—Ï·Û®~xõª~xýëüá¶ÆÛ¯ú“Ÿ,S} x½Þžo纟£!ZPÉž}×úÛßÿ:û~¾om½ÞÖwoÞ=ɺnºMÓ4?¼ÖHí­_·›×e™=Õäˆ)±Þ¶ûïÈØz“Ðöl}o!d€ˆñf/UhN“;¼gì½G {]–RŠ—¥”¥iK™ÀT¦híÞqÆ]Ò¼öèJK:±7><=_ù·¿ÿ¡÷>/S)Tt˜CÚóŸÇH¾zýú0G¶½oëj´ižó,)²«Ý¼2±‚[àb8 M¯qaÁÈÊJ nãŒdFƒeå#«Ô¢÷H %ûË4 •éÖÛ3!Ø2øZ0)« ÖŽ*Oå 9©¼ +ÊN©2{®mÏ,æ2R¢pIõ W€ÝËa­OÊâÐdKlê=ÐÝR$1r³iï¡Èè‘Ê;N nãELcK£9z6°J~ÇÿÊÕY¡`6ƒ†Ï )@#ä@‡e&ÆõÎ&¢Hê`$hFå&Ò8EÒ9ѶÍè™aĶí­Ý§‡‡ùñt´¾þðñœ?ÿùß¾~µ^W çs Ç ±ÄmÛ^ÎÛËÙÅÅÌZ»=?ߌÇ_þÛŸžæã¨æõr[OûmoçíÜ/ﯷÛõÒ/d©^zoŸ?ÑÓŸ—yºßKS±ŒýùéÉJç%"Z·ó¥]¶íôt@ïû¾áµÜÚ{ÔiÙnëÞ7 z´–¥µÞ£zÆž™N“Uô>Û4+V÷í‚ÞîUz:™ÅËäõàrC—vqYÖþÉù99÷plKÁ°wí=FaènÌÉpÓöÿê+%¥÷?y˜Êãéñº]ö¾ã|«c½Nsk+½D®¼T—AU‘Å&± /‰€ènR¬ÈIÈ3”‰[&Ýæso­÷Œ¤^ß%ƒ‰ïDƒi$ŽCiÅ€bVg4["V°B蚸Öv<ABQóëÚÖ {7–ÙTÖëw¯_¿ûò§o¶ —Ë~^ÛûOï §Ûm½µ 0ŸŽóòt:>æ—³µwoŽÇäqÛ×ßýöÿÙO–ùàÂ2Ea¥Ü¤LµÙûÞZé8_®BFl=z‹Ü·Í@ß÷uÛÚ¾E´OŸ>ì pº\/g 4›ÊT}òe®^&÷ŒÞ­ÅX1>—½m 5·æ(E¶Lu¯ÓËvý³­{qö®LuÄóË9¤1[{ÿþ@fØþ9W÷8“í»Z½EÆ`)7‹/ mX B¾Þ÷ð ó™(J¶v#hX"+¹É®¬µmWÅDZ’&ÜK$2"s+`NdïF?»M‚Ã(Åød»Ïˆô2þ$‘ã¼äf5s&á ìd¦²øCÄ÷æ$2rŒÕ;­Bè- “±ßGíLÚ[{õhvCöbSh¨R7:¡IØÀ=eD’ÐÑ£1¡+é¶Œ”Id'“ªãã ­ôèd£ƒ ŒŸÈ¡í6²@=¡æ0Òˆ™$äR+=»™ÝçŸZ¢œÈˆ¼mëþû»o¾‰¯¾h¿øe¶ ß½z:ìö“¯~q8üð["š ,ùq}X¾xõã/¿þ)ú5Ú‡eÒrxœŽ3 ÓKÎÐ(ÕŒâÆî^{ß/·óÞo×ßµ=¶¶¾ÿþÛËõÀ¾g€ÑÓŠ÷}¯sÙ¶ëõ²ÐLF¨gëûÓéñõÃÓñð®Ì'ó4FôÍ25XO ¢Ï3ôz8ˆuß#…§å°í·ýO‚õ¡!ÀHK´ý\ÿ}Ûÿ¬öøgmábV ntÇTmÝUœJ äáä,µ÷øPKQv¸G^“ @)µ÷)ª¥öí@÷Ü5úÙý8ìó|Ô¼ b‡•…ê>€ÕP…V‰ÅiÊÍL9º)ÎFJšá7ÈJy;p'z®n•V{vd¸»Ù$$$³…w%ÃÝçŒ ˜±“ôbta#&£GvÈÍC$™‰$Œæã”&9 #ÄÁ{Ó(6v ‘Ê´T1HÙÄ:Œ\V8Æpæ%"ÍfÉ?+™ÙžêF—HL’yõ2úwµg7SĪ\ ‰c-¥º–¹&±½ÿÑW‡Ã±Ì_þâßüõû/T>ù°`*¶ö}å@Ã3Qêr»­ß~ÿé‡/×µw~þË¿úêýÿ~ó«o¾ý×l}Ø`öï®×ùô“Ÿž~±_~óô:‘q½l" É=P™¦2WË´}‘hÛÚÛe¿|¸}Ü9eòz½¼ùðÝ·ÿÊ„]Z7˜8út*†â5¢‡¢GœÜ ÎÝ-¶Oú IDATo{ýp~ñy©@õ©ÎK"·žV µ©‡3‹ÓËd>ÏK­ÓÜÚº÷õýåòÀÄÈ{ýûÿ‡Ä€Á Xo;S³±·Z2°o;˜6 Ýê@”R`)Eq‹¾"{¥N$ÒÜ_﹭Р£7÷Ì. ó‚ˆR2IV³båBtÊÜi26ÊŒ”Ó¡}ŸüØs™êÕ‘0{Lб©ÏfK*ì¾°K·%Q¤Š¡†>9­”Cj¥  áÐ#ÈÞ£Αgg‚ã>âÓ.™ 'a̬TA5ó½ÝÌI b72à\¬öu”+iTÍ;z1Æ.y¼ZN¸´+t· énl¼´°mZëc2´X†”Ja]ןþü¯üãåúþwK© ·Óãñ«¯ÿývkSÞž–Z9O¼;×»÷˜®ë§óm\T^]¯øöÛ­MÕ_k|õã÷ßÿÿ“êñÿúþ£ùô£ýö‹ZþêïÿþËüöÒøî'ÿþòþÕùã|<â˯¦õüÉrëûóžµø\ý`V¦°íëmëçÛúéåúÃùãË˶mm]Ï/[J‘Ø5 —hG¬í<,È8Ö²õýr½Œâñáx¨éV½Ę;w3[æ¹QªóñôÆë)„½­ïz‹þ¶-ðG—ïVGý+…¬ãEÄQ€íóŸÜ#µ·;9¹·j|£¼'u²,™k2ÁUÚ‚Ñ Ë¾šRëÔ³“Íh":e ÑÈ=c"MrÂèÕ̲µâc­ÖSiÆÞ"}Ì螤¡{ ø)ÃAdݤjÒRÆ7ãîí-’»-„§`¶Ü3›r2Ì"ÃìΗ¨Rˆ5qÅ=ò·e$yœNåî>Òi¬~ô!¡0–”AEšÌçÐMÚ¨4Ìcs÷+Ãìi^”~7Ü‘’eŽðxdîc£êv€\*™!9¸bð]énnó¾ÜÌYžÞ~å¸íLa;ŸyùîñÔFöY¡ÛÖ®[ž/µë¡ÌËå¼}üø¹ýìg_¾|¬±öSÅÇoþöøöëÓ…ï¿ûýééë¬4Z@Ër`A9Ìýû“s:L¹<æûßýÎð2ûSöéê=lm ¢_ÎçóM·ëþñãËo~ÿ}jF©á…¶zE.n¡Ü3®}Ï?^¾u§n¢ :±4¢G¶èëÚfŸÌ&àJŽv‡;øÁJ÷Ž€^kåTüz®ÓÄmûSãñ¿^7ùgg0û¼´ùöŸ„ÑÚ,qJšCp0±)G3¯§JÝÙÖïKY2žÄÖò%£•òš3’ J•Èg¥»Û`¤›[dwœ"]î‰LE«å$8p˜ùRŠÖúÕI`!+ Ä´Œ•Þ͘wC÷Fë•Ãu§¡s8„>1DL†k`†Â8–•Fp0›D‹¼Ò\I0Y²ÓŒì gÂA º¤ûœ øApIƃquSæúY^×`xDÍÜqwwÁ.„|ðõ¤žY臱1«#Õ4¦ÖÕ(Å3_Z_ŸÑoÛõÓáͬK6ß¶¶>¿²­j§iÙRÀÚrëÓÇOûe½¾\®>ûW‡w­¿,,K}šüáz»œ÷w_LúÖâÚÛ‡ïþOâÿ.Ø Ê“÷oÿáÿøî׿^_>^–éÇ?yøÉWoÞ¼y·^=iÆRMH©ÝnÙ[ßÛör{þø|î¯Ö=.ëÕmzz|ý¸–ÒúMðñéúéºî×m‹ŒÉŒPWŒ[¨å%ú–Ù§åT=Î׫ñšúoÿ—Îë§óUÈh—Ãt8zùÍÑ_Þ|UÝzêºnÓ¼•;óêF§”Jqe6)o×®·ï?^>\[o8ž¾|ûNm—°wž÷bx»­k—ìX¦ã<=µíš}[J©s½µõ¼Ýz´Klû­OçƒYj'0M¥HFf2G·4|݇ía:Ì¥J­¥¦éÚÖ;AO0½ëÝ«ÿÂýä¢}“ ‹×Ù[#ÀåóÃKýj¶R."2’‰BŽÒy%œ#DóÌ9²kJƃÔZô«yš×’VR«ãŠ4*ªOÊÙ$›3ŸS7ãOS»”››%~¤TÜJä¹øAÂv7Ê–-áfX¤J܈-sË0X“’(9 ‰ƒã˜«ÙNt¨XÖáßJ)"A9¨ ² ÅXpO¦Œ§ˆ™…’©"¶ÄJ.™NÖ;ÝŠlÞ]æ£A–Ñd&|è9sø s€õ†ùHbfHróPÿƒzÅdK‰0è³³”qd[j™‘Yª'V¯µ…žÏÏ·ó‡ÛùýÓÉ‹E[{ƒÀ\^¶óíÓmÛ.7m[é½'¼úâA9Õ©¼w<=L§‡òiÍ©ØÏüËÈé|>Óp9?·ˆm»¾yõH¶¶Ÿ‹ã¶o°ÜöËã‚Ã\Nó2×eÛ±õí|»v¡e®Ê[µ²,åáñ¡²ŸßŸ—§w_ýò¿;ÖÇÿðþ÷ï?üZhf¾”ã½X²€˜½<<½½¬×½¯Û¾?_>#NSÙõx<¡î‰!½Y,§HÃÍ#ÔÚ~šçe©S‰‡ÅzrñXáT,¶ü¬<‡þ²òO#dãn£ñzcŽÐ~‚{ÔHû»ótsYYLÖÈ Ù©]9E6s¯µF¿:f)ÝM‘Cg-ÑxX`@d\Í\šŒUä>¢UÄ"^ ˆ»F`ª·RߦÚ¿7>d73ªK;8w [ÍCêl\ }|åš3‡G‹©Ò çØN…Y‰Öb®XC»ûH‘}.3ºr"¸å DJP¡3u1ó”Ç­ÝD4ÂGîæ‹2QVåM™@bÈédÑè« 5’È®É>¤|„™ Â2(‚¥Ä@é‡ã¹\óãÞµïÙ×µ"[Û6"öÖ‘r·||œžæùeíÝnk|zZ&/õ±”Yòk—Ënçã㉒mÛÆ¹´O×ËyO­—Õ<%(Ò].Ÿ<zì[jͤO32lÑç:+1’îŠlûnî³U?,eY¬§?f¹lqkÉ{ÕûóÈø¿5õú³¤ è1ø‰ÆûßÀ?p'&÷¢Øˆ™¯š@F檴b%•¦¢`±%£•ZçˆÛH f¤ÒãMÎ%±‰Ý®=l’ó”´&rvº%CLèD;Š1G0° ¨‚ Ø?Ûú(lÄLp8À¹8ƒ@OEh&TåÀ}J%9%Y&t¡µæ~ŠÂ˜“ Œi›¤qÂÉD¼BAŸ¥ñôÅãHÅø¹ÿîÍH~>– »u’nî9N]÷DLðŽMä" GÜ­}#ß<ŸŠ•ËõÆœÚúì¸Y!"aà c;=Ôu×m͹ÀتÏK]ÚºæËºú4 .+§§‡åÁ×5ZðÓyÝmëÛ¾®—½ß¼2»e†©Ñ×káííÓñÍãòæéø°Ô¾r½nëåÚ÷Þö^¼˜0·¶ÓÓ©^÷ÛÞž[êoÿÓ~~þýårÎÈy:þÕ_ý¯^ýÏó7ÿëùå?“¶^öõq*‡ùôé|~óôêéé)ûM±C‰è>S)·¨™éPxA‡lpÒˆRËÃãaÄÚ§Ú§Û R1Ÿ½ïqWÖÿ¥ký?¹Ó“§e2ro;…*œk鯔jÑéø:sNî¥ìw £:)W:1%:ÄÔXBóVrÊè™y»€ÀFÌÒQ(‰³£Oõس3=IGn©ž2òÉ©ä[ò†à ÃÂÉ•3dD'3tSš×C†¥v/KF* Ù•Uº˜UÃ”àˆ¨•G,:E“²ˆÃÛU#WPÀ˜2€#SÄ<ô¿î3½wºeȘ’hL”)E›2Âi£Q°þ!ù:TÆQB2I4è$ 漘‘Ò¸ü8îÝ5Ñ»RyI^Œ¯Ö6l¿ÝÚ¤¨¶#F*Ö¼÷½÷Íœ“O ¶îõa»å4•Þ¶ç—O"¶Ö•ó¾(òcÇtÝÚÛm}Þ÷VÊÂrœ¢õj^—=,§wÓׯ_=.K¥ZìRÖ¦™³c®ÓìSn[ßs>އƒe0²X‰ëo±?/hßýãßÿ7eúõzûíÐýâG?ëûúͯÿK«nĺõwÓÃòð*ö—¶­S!ØÆtH=œ8 ¢;-b¿ÝV¯æÎlM‡CußN§ey|y¹|óí‘ÿÒøëÏœ©/·Íñ$ °͈Åm$q»®Å*µEoc\®!V ÙLI˾ ]œ{{‹p¬±éD…ùˆ=j6l†´TsvÁ{ø–ÙŒÃQ¢²—â=6°WXI¤±Ò\ºFï¥Ý‹TS›¢É’öػܞÏk*ˆ×  xV„8Ãц“U<÷o›Ð#eVÕ7³70È"vÈ ØÍö„9kG‹ÜÌ’c¨#ÁTtÝÝu(À*¹°Gt³I"9T,Ù¥Œ¾qwêmw/‘ݬ =3†NæÈ¨˜g&Ô€!ÔÝIîÐ-[:¬VÞ^®åxˆÜƒ"V¥NÅ<¦m϶å×§Wo¤µZY¾~bÛóùcâ|ùý¼v„\¡ÒЬX­¥:¬ÙT,·ÙTÀ7OǯÞ<½y:žË~[•ë¾m½­Ñs i¦âKõÉùÒ×ýò\ëq©Ëét|8Íuª†Ÿ}¹¿\oÏ_Öÿìê€=•ƒma=ö²o•¦Ëíñe?|ùÖKF‹mß$skÙ:x¤Í½‰L3‚&¡Ö2/nµˆÍ$wŵm—jhúotTþô0fŸ}Ń…u·e»Ð5ð{æ&¸ã‰ò¡Ît—2)o=÷v#¥•&í²M\Üzî4“Ù íÐ˨EÓJˆ¥à¾†Ënœ ˆ»ZwÌÏÛ®PA.HA³›©ïa=´N ­¸Ô…„QrWFd™šH'6QÆ". ‘ ·cd§DMÎŽÌÔ®»³t2T¥†n0cQ 0‘án©ž"å6p{v‘N4ð9&ún¦ bâÀV šz úkŽj¸ "“)GI¸Ü’Ì2f3”Ým–f?L¯Ù“/ó±^ûe)p¶TOT(‘9W+ôiÛ7ô~:ÖZ™[ïì-ÔlkýrÛBÆr<ÜÖÝÇ#”6犌¾—JeÎ3Ùã°à4=½}z|<Ú›§CQÛãíy¿­ývA ?Z˜•e©¯ãÆ5?µç][´Š¾<¢_½þâÍ«7Vp~þáÓ§_m·½í¥ø1®Û´ð«ÇÇ÷/n)Z\®¶¶<ž–Z±^Ïûz–´LÅֳ©ª‡/2]ØSQ—Ûw¯!mûjvÌlÙ³÷º¯YðO,1qIÒîEÊCöP¡-ŽRزw³´òÐ÷ŠCï4’k)žqÊCyIm¤EŸ4Ó(†:\óàT˜NcëçRf…€)`äM‚i"$õûWK‰Ø Gò6r„È 9¥]Iº€‘˜ 5ˆÂpü,+K€´ ªÐu¢¥ØFðñàw7PÈ ƒ¤Ÿ·aƒ ¨“–Q•ƒÇÎ ¹WIÒNŽ|õÚZŸ9ZÜi-3… (J3«f:r€Á`ô”…‚Ð5“ˆˆ{Ëêä4<¾©v +e´3ŠUÆNØíå<Õ“»í®‡ÃCñ$)T£+h˜ŠûÞ»s*…Ë|<Ÿ¯Û¶\ŽO‚‘³YÝ¢Ûª“šY®Ûæîa݇&x„é¨ZýáTO‡ãìí0Ý*èa™…¨Å<÷h-)Íóü¤ÿ³÷éµíʲ¼Æ˜s­½Ï¹÷½g;"3ªJU=$Tl€ øE¿T $øt´iBBH*PŠLU’•é;l¿?÷ž³÷Zs 뼈Ȉ¬¬HnÃ’-Û÷Ùïî³×šsŒßï9bêåvWI>ŽúAó‹·x®³·w{ß®_à©ÍqÚn–Ƹ±éÍÓŸ®ý/¿ù6P[ó8osÏ˾‘׈)ÍY‹$o`†kKï[‹Ù¬Yuªf¤¸8®ï>}óÃË< ÿíÏÈ_‚ýjê˜z0Xµâ’ƈì™ÉGñ©“‰uïu©J²ëÇÀ&sZØhÚ±@\Öh@·O YµŽâF€òázÍ–tÐwƒˆ‚öäîõY,®§…œ-ž¨‹]®IxŠŒ.Ý2žìÑcÖk‹n¥lbÍÍL.]Óˆ 43 T2`DpjÙÊ&²UËÑŃôà‘"%¿ÂIæýïOò±ÛËK¿ÜŽ00àöX$­¦ƒ>±\``"P.pÂ0¦…ˆ  Êaw° "ÓvTă×ÜÕ0²Qd&#BdW!-Ûqe=½}¯3NcÙ2«imöÝ®1ûx»{¿nÇ˾£@£¹¢G{zê[SçÜ£Õq@¡‰šn[ï³p Is˜d0.Û“5<áíéãëx9Ç,}xù¸_®—ýÚžcoOož~òšçyÜ'4çªjèï.<ëÓûIÇÛKkÙ¶­¨BÐa'ÔªÌ"´õ¬…RÒœ·y…Èýi ù‹û§ù×ÌCþ×\Wü;¦¢_ Ð~Á.cª—9Ïù±]b ™‚,Û>͹:Þðno‘aEäÌh¶¦äE>{›þ&£c+ÝZ£­–\¨Rcƒ'pHë <Œ)uâ"}›qµïò€¯äÆúu¬­ÈæRÂKÁXÌfÊaT„ ¯DCÜPþ±‚ÞxüŠLb}¤Œ© ³"WHž@à¯'™d·m¦Íõ©O ‰u%ó1”瀫Pp7„eHõ$Ú’V¯nÙ X+IPAr1{yU2gÄS©“3PPزª‘ÇÇ_¾{þƒÐ "í&×Cµu ÔToöÌîØ2Y²èò¼¿yzk5<ЬKƒ•·›èŠØHŽ¡coH{ï}omË.°Ú"si™ÉáXµ–f˹µÆÞðܳk–Tã—ß|}¾Þÿô«¯~ôîÝq=Çý:n/œv½NžÛe{3nÇqÖyOàõÓbª12Â5æ8ŸŸ¶äLºE5èŠXø‘jìâóy¶¾™ÂQÍþë Kÿוßʹ¬A¦×û…íYŽÈ°#[‚C¯ Fñat_²ÛR±¨£µwäFƒQÍÔ D.±›áˆÔœÐ=§¸¤¥Z ¾5ÜÄ.G ÖvFUÆ N8a0vù$š,ÆÈLø"…6àâhF\P;™Aw°Û~¼eG-­4ƒD3¹è‹y{x}ñ†Üí;8e¯V .|0H•Ѭkð©æ\o꥽_ûÏßTD€ëŽøeýL£>[Jã¸qñŒ ƒÀò{!£›™éŠº³nÉÙÒ~¨D˜=[69=Ü[î[“ª4¡uÔè‰íÍv¹l³]¶Ë8kÔ8Îh±]¶ã¸³)è­µ´6lûÞ“ÙÚÅ-_ïß3S¥9-eæ<誌^5÷ýâì`dC„Û«îŸ~þ—ç/ñ‹·ï®ï¾|úâÝžžß%{Žý³<ß<µã8Ç©ãv?>}ʨ§çëõúLÔLVÆb…3-Z;LjDq{kz†ÚÄlÞ-÷w•ÿæ/~þ@,6OpÔ:Weàj§€†ìrÙ؉ž¸Ú7â´dTDi™dé0Ð{_d[U¦²¡~ «>0^íÍr`F ˆ ìl†‡ÕeƒŸàŽÌàd¨Î¬ÌdLù#ü t¢·¾Ïª¹‘pq4ñD¸¤O‘ÏÖF®ƒÎºW,‰à¤×ˆ«‹å€@z1¦°¤‘¥µ’‡53ó¡u H¯0öC°ì ^ÕÐ\éÖˆYu·ß»uv@àÐѤƒtc/¥EÁp!×Ó僰ٖ 0÷þ“/ürû.l}¶é‹Ù7Í™¹O„2VÐûÝ›K¹¦’Ù¡èy]m§-ó¸¾mOÛ~cß·1î[gC…fqyzkçý˜ˆ«1IF|«Y­õ…$øôüôzÀ§m·Ë³Z&öw@ª(O?¼ÿÙ7Ÿ~þ5[/Õy¾^öÝbžÇ°ùôôFؤãã÷ß?¿ýê²?íý ÏŒAö@V©õ-ûîÈ€Zd kÙSªQ%ÕßøÆøÛï*¿Úê×CòÂ¥åDÇtÉŒ»åàž½]€çš‚»eû¤7›‘ò\Zödj*Ø©ˆláWÂȆˆN\“OáÒ(c[T!âbžŒWy>Y2ÎÀläÒÑ|²×‘,ÙrŽ@0 øŠ*°ÛãaÞe>ºSºf¼îˆÓ¾YM†À ¥pQҴÑc¹ŠÄœˆM†pgÞ æç›z_/øNûd¼ù•|â3"Ôð4næ iÅ3ñ³ýQkƒéÅvé0"sÉÁ $pXÇšì"Ó‘/ÏO>þ\5ˆh­Ï’„¶u#‘ˆÜö&#Ø¢5¿^ú>ÊàfõžûžÈQ&[ßZ0#[y\¯—¤¢œ$[ß̘åãã žòŒÜ¶ýÄœgFî{׬ýùÝåùr ÙPq±€ÌŽ@¨îªY³Ïð©à ½¼¾'¹WŒ9mǸýº]Ÿ7÷~9æ]£÷ËÞ-¥é²i—UeO áVFçöÓ§aÿŠ©÷Oˆ× ç£_*2c—%•+`hË9AÎHyNùN"bƒR5"²å® iéFvAÖ‹pSÉÚ[ð…¼›]s*²‚9á;.ÄžÀ@Ðshy…¨ÒUK§êîö AžZÞj\hÂ3cŽåÝþ,]í¶<1–“ÙŸaÄ+'i¿’ÆÄ̼âÑ×UªÊØPÓÞÓ Ea’ieŒÍ*"KÃñLè9¢Á%Ï@Þ0mÅ¢sGª&1è àNŠèR2ʸË#yQkŸÃhe•æc#Yu<RCMóöZ¯ñLï—¯R¨ šä{òJ¿IöÀÌ>¶ëopl݈í+ŠñŒlÒ F`;Ïiàq¬¯½ÜU¬12Þ¿¹ff'"©€zkãXÕ4 Ö<îcŒH7á¹?]^ýÔóÓv½^•mÈ'Š ;£Á=\Ç<îNàM]Þã8ê~Ü×nÏm·Êc‚¾ö ƒªã8FÏ«z†p¼ÜoÉçÜ>¨¦™®×è.?K)ž¿™Â÷ï·‚\áâÏ©{–>CÖàØ:ZÁ¶/ ØroXºùNjB8_Í9kñõäò®öËBˆñ©ÍúŽ|ñ#úÈ:¯^¥È0PpAŠÑæ<"k eD C”—››ñܬÍd—€†‚M†gE>ŠíÀ¬*fÂë¬%FÌšÊdf,…jMRƬG÷dV똦k]+®µ d0.üuÄ^Nx#%œ¤É.5ðN̈¨"ªe<rÝñ#@|t¶ÞT½:: û4GiD(˜Y%ù ‡Ò–ÌÀF›1¨¾bX¤È«*˜kVÀ!=V#k¼åBÉ¥I‰lëçįPpÆzNd‘†—ì!­zôÞmp3K?ô8; Lk'ÉèZ¼;;#רj Ÿë_˶ è¤$#s³9/ßËzÕOKäbÂë‘‹ñ ê(’‘½ªÎó(aŒÑ3‚»ÅÈKMç¶Š4líJî[^Jeäâ>’Ú˜²½z¡BŒÙ‡û”iß>|:îß¼û‚¹õh9]™ýÍvùbNV¥eþkÙÁq;dÊŒ¶_€ñéë¯Ï¯Þ}ù£w—ë“FO±'‰"ÐÒ—ý)]Û%S¥mæÞûØÆ˜ck¯§Æ9GÍãØ‹“á–±`bsœÛVÔèöëÇ÷Û¼¾A¤K²÷sœ¶ñwüú©òsºèwu÷+Ί1G‹ˆ¤¬Å@•N~>ßÕœÙBš–eE@êÖ„•è@‡ÃšÀÙ‚ÿù~ÎWB½?—3_àˆhðᦹµöc ˆF#’¡Ì µª< H—¨1òÝÊ®7Î’»g˜„ªTÈlÙÏÒ kY™Ü\}¤í‡ú'TŒGµž´A´rpáºðv#’lRŽD¬’#dO~HG$",ÉâÒQaöÞj唉ˆeÃÙ‚,FZmIíà3¢iL¯‡Wue]€zk[ñöþ»ïâj$˜`EÎôîÛóJ.Ͻ¿‘ì ðWabzi8VºÈm*§ÅÃé IDATûTN¯ïîó—ÿïõôŒ§ëeß¡yôý+ä;)î÷û9X ­ã1£ï×vˆ¸ÃVÁV¦ŸŸ¾„ï¯~öwü{Ï×·{$¡Ð¼<_[€vÓ½ç)NcÖu»ØõúúáŒÜoãö‚šB´ŽË~¿ÝŒåÒ Ã[Õâ²o_¤Çœ/šï-ûÕ<‘D2²Åã~ñû=!¿u ¶s<*V¿qÕ‰ŒÝŠÌ$jÎÆfæg–ŒIΈ²;lækèoÁís€¶-µ:-µ©13VÕ+‚¨šO¨·ïJ¢’&ÙHË‚7°¯s¾ôî?ðîAqʘuϸ€ZÙv/ ÅX”{®xbIJB. öº½€ä–++ä2þ¸’Ýx`Á{®Â&ÖÖ_ÍFÄ"Ú~ôGa¿J¯Ò(ÙX1{²JI>rE`©‹ÌÀ^5Á!wRò.2 H‹•zü~SÂÖ÷½]ðê<9mTe¨p&auáKù@@åqÜK)_VRFå1¶4òQµÝÇ·³â¸¿Ün~ú‡×ŸüôËÖÂ5iÐ9G›Ç<‡ÇÐQæVãM¶MÛ6OkZÏìÏOïz¿ÜŽÛq|{_ìýšÍ½¯8Dß÷k3ɰÇ\'ðs´È·×7÷¸í±Ç=[ß^^?Ê55.Oû˜åYÞ8çŒ&AÙÞØ©*iæV;s¢jœb¯©*þ;Ñ'~•Á§a{Ìâ#gŽAòœÕ¢1¶lÕg¬ªàìöÚ¨Œª³«”ë>çÇ–WúÛ& 4NiÚ³U|°h#zfC*èNÐÛª]ñmXÀÛÀ%EclÌ30²íõ±ê|©ñF¼8±4¡±_Ÿ5‘ø€ŽZ7X ˆ}»Rµu3š/ó·”–vJgë=8`kù>} ´µË)ßï°“«V‚±ÂDþNç°‡M¿ÕrñzfNUiT­:m#7 ¬Äó²S¯‡9;jÏ&é¤|G¥ièŒH¹Zîcœ >Kˆè|Um«óv¬Â‚\™O@‡Ê5 _€'b¯ WÎSh£ŠeÚ±RýÇð9òååÆÄÐ<2b¿>ï—çs,ÒSH§#%Y¦³Í’ØÙ/e¾ö›t5/Ãd^òºÏ3® Õ84¤Ø<Ûª Ãj[§Öm"©‚#¬SG0ºòʈ¹Âi~½rÐËø'3Ltš=•qŒûkËE#òPq[Õ,M@ø»ýˆ°Ò:8/pÒkĦ·äU ð±eVEUƒwéΘ klÔ›lT k.eF£·ˆ·ë˜˜D ~%<… Üùp»õŒ·Æ¬šg†¡@j Tä“P¯=ûCš¯{IŒÝà€wã@ÆÅ.2È]n†‰-ÁÂ{8펰݉+ÆÝ±AÝàâãþ0½±A„³Y&´Ê¿^P°•ÑÄ ž¹<Á "$×a&ÖAf¹®Ì®‡FÁdÐ’çdnÔÅ,‰ñNª|'&¡ µVaµ;·à+p[°6¥ߥîŒ*%.U£Í©1ª¹ gMÏJå:”CÅ1çYU^¾˜µß5] 6CǸá.ì<%·'o»±Õ¬ö&·ü0^ÍóÞ6w5ˆ&^ZۛƗOãÛ—YžC#Gß㲜3ICÓÀTcn­¼K'ÆflHc˦~µÏ­qRP±l Ùi’aè÷ÁËÆíŽŠãpl¬™«ÿGÿÆO<?ÄÑòƒð± Ãò³cý¥N'ïaîöžØé¯àÅ>É€µg\ÊïO‘Oo䓤 îSSÌ>ŒØ§¾-¾0ïð r)ªL™–¤ÙÚNÔâG¨êçÁ Ch:*qKZÝ‘gIä%Drú.ŸDÚ¥¸‘Íý N®ÿ0\g½oÕ$7FÆg»ì 6Ãd# ."̈ð\³²Çk9mT°ÍhÌM˜’K=ã qÒóÑÆ)Tä¾Js±ä3’+Z±”€}Q`Ae¨jd`1b“væ>'ŒŠÖ˜¨Ro[´50ŽÙZÛ‡rfÕ9àœ"û¬˜“ŽéY<Žã8ÏQCL¶-Î1þõ÷O—'™k94 ‰Ü"Özvþc&rGöÑÌfµÞŸ·ÆptD¸Üä­yÎÉÝ™– Õ<Ýš]ËLlº`(Œ9ÊQFëýjèÓñº¦-Ê‚Á¤§G,‘ú*`ÀØÎÖ ¯uÆ¿Ñò7†ä ¬Ï^5­0 FoMB`K6ù`€H)!»LãpD¯:D%hK}qäm‘åjÎV:52ïf+–}Kv›™m}¬Â3BŒE­<i¸j ²mO’„ÊE¼F[•¡2/ÒAã´ å!¨ÈFS(¢G~\Ò´à]™+37øaé×1.t"í‘~ðj‹Ü`7ÄúT< i ìäžAÇúlêð2àÕJgÅ£ðü¹jl[¥L§®ÆÜ-›çê„ev©˜ H£“›é)’ l‹¨7gýÚäË}Ôµó¨µÅgä,1ösú\yybH§4±&kºK§Ü«¸P?9 ³V˜±­Œ=‰hA3ðqL}×ø6㢚v§03ºÆ=ÒÒ67@shc®¨zrgFà2-†áP«íh`$Ý€$7á• Í<×O]f€ƒÞ€aKš@#ÌhÂІU±ª¢h¥AŠh 'bÈûÂr¹)×½…ÉåfqÙhÑf Ä$‹P¥—dYѤ±BĶæ¸V¥K×rr”|6»ò1Ø7?#)Ž5íÏu\®ÿ,[i·©ÈÄÐj:œ·Û`ÂèÓóCˆûQBLKS.EMÕaÜ"ƶµmÏËu˘?úòiÖíãë9¤_üðíóÓÓW_þÁá‚ïd 8uÞæøúÛï¾{ÿþÃÇ÷ŸŽóÀ~ nÏùv‹ë–³G¶Ö\015ÏñÒrÃ>‘Œh™ç¸:§ xÎéˆY”{UEôžû”L"Z©\£÷MåªÃ˜Ì ‘‰E^)¿û¹ëwW.+\¼Àogq:>ÙWò>Œ!ƒŠŒVó¾X‘L¦*ª9f5DÉÌH¡A³ê€O#Ñ)1Nãò;èiEAƒA4ÛÆ€§ëÜàË2_GÒ‹ùo™¥JD+M&}ªÀM¡5Ó XÂH^K †–‚‚`)ë\Êì`7øˆè^öˆh`³NxÄÚB®–¢'òI°N~$û’¢Xº°ˆC2Ñ3›Ñ¦Ï`PØZªg£­…óì-÷¾"²‘¬šç9†ÎËÅf“*Me´`è<˜<æ1jJÓŽ)×)®È(&3†g4f·ècNpsÎì;Ý>~õƒÿ7f%ýûMŠ;elÎi×”>ô¾žmÏRÏ ˆÖߌcé*£ª2b”ŽÌ«UdTÝHžA;¨Þ¤–ëD(Û—€+™Ó,ãéˆñÀ,ð /`7ìÊElÊ):Vר×j…È5ÿ}äa£ 2D·`"€ªER<€N\í©yÙeߡ٠hR7 ß!Âë¾ñ0—•«à±[Yås}µ@4SXVqf„-/Ÿ8뎢AÛ“²¥d,ñ¥€Š0pxmjVºÁƒÑ…ù Çyê—_ÿòOþôÿ—ÿóë¿ú«÷ÿÁ?úÉþý»m’n-Kv­”gUËYgeÛŽ9ŠáŒósN¹UYbô^ÇiMz˜¹µ½¿¹~õŽæK`2’ß<]"úœª²õëáÒqv12&Æýï_nŸ¼{öywgW$®¶ZpßÞì‰ýiomï-×Þ¸ç…DU¾Þ«m9j ã¸"ØÛ%\‹4ça®‡£ª% ‘d6P¨A;3çy²oVla3Ôv-iÎßÖ<þžáâ.ä’ÕýÎߟô‚q‡^肾J^Â'1m3œUÙIUõˆ¦"ýä01àh…«”(´Ò§ŒˆÌ¯@Ù§QÌ+«Û §thO0>cãEÂFã%ÂR_Ìc¥ÿ‰N ÀôÕG³K¸7&‰(Á™LIŒFvØŸ™óYªEß³Þ>Mt£®dH³ÌUÁW0ÌÁr½Ñ[ì4Œ±´+^Ôð¥µÇâU&Ð Óš&K4¹I'8×(´= A#y‘ÆÇ×ùÍ/?}ÿýí/ÿâ›?ý¿ù³¿øî?Ü?Hðï¿™9g)†TÓƒyõ¡5™­C<‡J­w1Å6Ï£jöö`ûîÍÏO×ç+[ÌlÛyžÙ( Ù­µ|z~ózk—|BôO·c'³ 7ÇöüÅWym»ŽsJnˆmß ì—žÔÃqFóœÃm»Ìœ§ÇqŽcêv/㊑jy– ðœ×-/ýúæÍ~ÙÙ8ØÝ…ŽÈVûyÜî·û¸óî/¯7·sÜr»d,pâãäÙ $ñü¼×Å`¶ÈY²>¼ÿþv¿Yw{¢É8_n¾ÿøÃmê”ǯDzæœßßlüþš¹Sã½Öª·†`LOäì—nATAmßÛÊ`°“0+ƒò÷xZüûÓŒ²Èi_ܶíÇ ¦ï+M<§GÑ讇‡-¦ŽÖBŒ$^á3Èï‰?lvÊòx²¢ENKD7mÏÈ‚œs¾@r7"áÁ¸¤Ò&óóÄwqØÄÂH #/òàŠÑ›f-ß(/×’&g{¸É嵪7¶ˆ•³à‚qEvF· . E&B€Ñ—8nõÆ$wF‡'$r±ö,@s-[A~xùæ—çÿÉ×ÿë¿øÓÿûÏy+ׯ·§€íòÕOþðß¡Žò_ýôÿá_ýOÿýÔt¨µ«¦¬`,èD5(Hȉ`òãíîȉªÒœ>…È4|åÞr»ôËÖªîE"Ñ"®—ÐÖð8j~¸6×cœVÈp--–ç–û3½EOY¹eÏK•ª¦ª¬zùôýíö²??ùåO.—‹ä×ãååþÃÞ¼¼ï?Ý~x}½Í¡E1£‰°u¯ù+iÖ•ês\UÏûvÆIªgιvn˜ø »•jí{ÖŠé÷zV~‹Ï‚ß@°®?ÿÍÖñ»}°)œá«æF\ÌÈäúýÍv±Ó¢”F7&H#—s¸*[ï‰ß#(« #p5"hp^é”´lZÀ0P>åõ°^™GÕ%Û“1ƒquÝíÁ¶ÊÃËüH;Tg„¹vy=b Ç6¸„u…?­°êÖ†%hÕNì}–Z$ì¹Æ]ë¼£»5˜ñù¸º9¥˜@/ÛTwp[yÖGç…ûú¾‘ù¸FT±ªÿðÍë_}ýý¿ú‹ŸÿìgþâßÿðñþËæ÷:Œ%ìú­lxÆÓó›ëõþé¿ûoÿÉýÑ¿wùô²íOïƒgéáXKiÌS Ѷ\åÉ9«ÌÛ¨÷_>¾ž­%Ïû?ü·|ýêùö"¨{ÍsÁ¢ã•ëµJõØôÅW};_®ãõ>?Üï·ó°Edf˧Ƨè^cê "/¯¯§ùz»ýõ¿|yùö§ÿú“/¾xûÕóõ ˆ÷óv;¾?9ï÷ñáÓËý¼}|ýþ»_~óñÓ FK"óõÓøT–yXÇYãØ.¾‘D•@AYb ‹5œ$ ÿö«Šgäµv<ŸÏŸ+‘¿†!Ø{|µ.Fò ~u½¡[ÕaW ±Ê\e¹Û‰Üà˦uNäã|V|jxŠ˜±¨¦8\‰è!¥0ÉI>I ´DŽŒ©i̇œØ«ffZ³êf+ø"0‘™Áݲý)¸•\“%Ÿ ÓêK±ê£Ä#YÈO¨ê¹Kgö¸Ñåc™1«z’ >Ñ(Ý–BÈÙÁV(ó0›yb­®çD¢µv±dê<ÇËíüúëúÿ|ý?ûáOÿìÛ_üðòrè.œËZøÛ¿ñ´­_\þëÿæŸý§ÿÉøþ‡þÞüôëýÝñòpdGoÐÙ#r+‡ƒ^U‚bšC÷c|ÿéåû^îçt÷ï¿yÿíŸÿð‡øîÚ7:Ū„4"¢÷ÖzF¶ýé9ãúîéÍ»wý«é³tgïy™¥©*aNWr¾¾~øáãËÏ~þ¯~ùáOþÞ?øÃ?øÉ—_~ñ%yuÕ»ëå¹?Ï7ך÷*ß¾ç½~¨‰sÜî÷ÇqÜêøö‡÷ïÏþ?êÞíײì:ïûÆs®µöÞ眪êêfW7ï¤%R$u¡l%²Ù–Dô$ òš'ÿOA$ìÄ  @H"F‚sq†iY!,êBŠ÷n6ûV×sÎÞk­9Ç_Ö©¾PMŠ´"…ÜU¨Â®z¨UsÍ9Çßïwûüâ…?zûÖ³Ó´=‹ùjŠ¡tÉH‰Þv; ”Ì!ó}Ù>:_^?¾ÿàµË«‡Çãqäö­ýýÇ˃˘‰ ?ÕU›¨¦ ˜dxnÔôm¸{Ë¢ÞK˜úC]]ÞµZA$Ú’’0;@¶;pT¢õS’ ž<‰6RˆÙýX+‹L¡”L¡$=‹A‰^ŠD0QDT-Ì Ù‰nV“CzµR“ E„%˜"cdbZ…¹QOÉ(Å"†­ÞX‹ D"’b„lÁµÚÖܺï mI!ºD5@S ²ˆÆ5YÉ ºyÓS'Y e³¸XÀYQ ö›‰÷þ›™|¥ŠКèК,sýÎ+÷¿ýòßxéµo¼ôà[¯]?é9'6þÛã?ðS+Åþá?üÏþ£ÿðײÇãû?ü‘¿á]eºÓ1ifºš ݃ ÷†R2‘ÃT7ý¤¨¥$ãX QZ·]½¨õöíçïîÇÃT*0 g¥<„’&X—5zP¬µ~uuì9çu].ÛõUëð`ïë2/šŒy9vw")KÏXCf´ßûÇ~â'ŸöÞÅtQËä.mi ÚP6®©B(27Ï(°¿õÌÝ÷½ÿƒ8?zôæë¯çÑã‡çÏ·&|ûÁ2¨-¡%–uÑÔbƒÖˆ ƒ¨@x®†QÞšöùÿâ“oô‘Œ­*U$”ØTžªب†Ø’yÜ!9 Tëµxz,„fÀÊVz é …S‹ ä%dǸ#&DTÑ‘"SÔ˜Zab‚L†ÌLHÑ-@# (Rây%’"Š„Ê6 Š­J edéPE S!=¸ öd…LlóbQMßé"…¢*’\) 2„ƒÀ·ÞPEj$­l=´îO®ÚÃG_yåþ7¿õøëßxóåW/âøôpÅïzO‘ï˜P’ïmùÕ_ù•ÿä×ÿc}íûûÃÅn:\épTQDïTB ä–(è@µw£º÷À ¢ƒ¢£Õ;»z÷îù½Å«¦cR×5ÈmÔÑA²”é°³.Süxšk'Ø·’äŠGÍE‡*E’Îõz®æ/¾xxáù‹Û‡:Z©eϾ®Ç㺜e2UºzäÒ®Övt_ÈnEK¹°q‰ÊÃóÏL‡ÝÙƒ‡o<|ðh·?ívþí×üØ8Ñc¯º´fªk¶c‡Tƒ@”*TÓ²){ÿ­Æ%oà÷7û§ {“%ÄUwžž°EµkdÆÖ;—æÑš^ù©Ë’âà;bxoÙ øt;y'ÍP¾oÑRîÝ{ÿ¯ÿúzØß~òàñiîúȇ30Ÿµùz>½qûb¼÷Ü ··Ç:•²Ë0Së}¾¾zX­˜ /×WW¯_ϯKÑ2Lj¥·¬îÏû; ¦/juö‡³gOÇ7ž»³>w>ñ+o;Ï*Y§ÜÚJNZzao!Ú“ÞÝ®ä{϶ðígfÀ†ÒÙ|BE!Ê)Ò2Ô¶_#Rêè}+’ib‘ÌFr§Z€ °**X‰Ù3Žf;„•àªvP=ˆ43ÂE²¨(eávϧ¨$cÙâÁ©ZI‡n"À]jbfá.zr_†RÁ‚ Õœt+³“bµf:$€!•BaOsž.Ølݪ2ô˜‹ž'Hè–fÂLJ¢']ª :™¢S&Å@›t(Ëâ¯Þ?½üÊ·¾þµ7¿þÍÇ/}çáƒGmŽMßÊ ÆÍ.Á§Ø[¾cm¼çÂï³NTôïýÒ/ì#ŸXfUÏ"2=Œ°d¬k‹ØH»©Në=UDZ7/Ó¾ù©Eë©—Çûu¸þøÇ?õ±êüìùR'ï’DcÏõÕï| õ5ýìwžýàÙíÊpáéóüøòɧϟ©gg·¦éÜšhÔöûaÇô÷='Ïß»þòW¿õí×Þle 3‘¡*Ô‚®’Ã0™îL‡¤ÿ6ƒ-ßõýÜF,°­!³‘€ÇRm"!f3˜ª29úMÏGÝø*­<—±Nfäjv¦æôEå¼]D"D¤9h%ƒÂôs$ód8”ˆä«{rÝÝYä!2Ð S¡" lÑÀAT“‰Üo4n¥BˆÚ€,"Ù€a!P²dbÈžéŘTÝõ„Sœ„HUÙ9òúè¯ß_¾ñÍÇ/kþþôï_]]Ïèy;ØPk$Þç–ïm“ppv¸øÙŸûùL½º\½Éóz–}eå©›Ë~íe(#‰HlHIŽÓ0ÔbB„«jf„s¿35»5–É8H® M©­g&[÷`YCg2ºGsUM÷Çóõ¸«7¢6,¡Ò‘=áËÒ<ìkóÓÚOËò±¼ÿü¨äÙõU+“ã¹çº,Këóýo­= e§Ýų‡[w‡Ý-Ø<ö·ÎPvÇåúÑ“ûóry÷Î]³ZíªiÕFÝMÃsÏ=óÌ«o¾òÕo~ûþ›D’J-’žÙ1J©ÍI1þ°Š÷z0|ºZ¶"²UƒŒÐHr)8@R6èÍY;ÜUîd´“5ó*õT UÁ ›Ë%BU¬¥Ì"‡Ž&1ÂT¬&•ÜTÕŠÔa@ÆÆGr¡Ö¢·‘ñHËF¹>˜MÜtõ)¢ƒ§'L @Q È­ ¢ ÀÀQd`°št"4ÁNtæH¨RÂ#Š J*¨:%¤<¾Œ—_¾ÿ'òÍ?ù³W¿õÚõ£uªõƒ—Ko˜ÄO%éñ=^LüáÄßý=½uûÇéÅÇûñÚ÷ûiÚ§£^ŸrYæX¤eU=+x’>‹"(ê¤XDë°!Rئj¢6±+]Â%‹˜U÷Áîeé‘È8Î3L –î*hëÉ'Õôè=Ó©¶†¯îk_œ>÷F†J´X¯OoLÃz﹋CUA\^=^ïw`¢Ôˆåú8¯ÇÓrç™÷ïÎðÊdÌÖ=ŠŽ‡r1Þ¹‡ùÁåÃo=yôÒùá}‚ÁÌJ9to*2M·2ø»óíÃþ+/½ôÒ›÷{¨°‚IN(‹{Œ;˜äñ÷Ï]í¿‹_¬ï^'úŽ{ü[_Vy«‚Š€«jŨ6(Ö¢rך,‘c^C{¤ë¦‘Ö” $Æá‹ÈéÐ[DAx`EN*–™jè›U´£˜2ç­Á!ت Ê š…Ï*** ­A3Ý¥2‚tˆ3dp‹Ñdreº«¢[òÎ2".ÒX¸ l¤¢E;«gÓ2£­ìkúʶr§ûÓζçãµBÔ'ríÒÝ…L‰)›±"‘‰fƒ–Œâ”A˼¬²­"ÉLWÑ–’€Ö@xﱄ'TÔh–ÈlËÚÚZŠ}ðÅ쇃m W ºé¥ÈÕ­[Ͻ·nï­–bÅJækŠF?6ÇqÖeÜ]œßzîb:[§ûëñª¯+A-&R(’ŒA”ÑꇞÞlyùõÇÖœ„RTȌ蒹-þEE0¾×}Føöèä ¢ šE„ÞWU¤…HgZÑs¦x-µùB®¢IN6bRE ­Ø†Š€9—Ìkè=“)3R‚±¡I ØU5ÓUUtO`,E=\ULw'Ñ7z è•b6tg1e¤€ªª2'H#’(ÀÆGMUK‚ ¾å*Cdv›ŸDܰƒD@+êaiú‡_øÆï}þ›_þÊ+ß~Øys;j’w3 ÿÚ>""}mëz}ïÞ €´UÜ5͹vÎÝæGÇÛ£*Pˆ¢¶±(D¬· CtºiªpTQ#™XɠН¾ÛO¢¥µȺ8U¬”ð`2¥Ö5k½GFkML3]$T©᫯G+:ÔDÆ:x[Œ½J{þÞÅgïîöƒ*jÙ«¢&PJB6† {›ˆ”dŒƒz{ÚAŽk»fŠÊ€ä’*må`¶«ã³·îÌk›ß<­QŠi­Ùú{¿)Œïø‚½ã®’7CHX-ç9‘"ÃPH'œD*à" YO,)[¹ªÑ ˆ"T[U$ÒKRÉáDd)J\!G’jnáïÅjÍìÉP­™©RÌ.’¢:&Ètˆ™I'µž1iEdÃú™8‰8D“R'S#3Í ¦R4rSÉUB š‚"¡˜œ‡¯}ýòú?ø×_|éþõ†.FÞì½"ØøüÞî¿ÂuH±º,ççg­Ùº`]¸®œwQûö·_ûؽg{j ©,’H¤Âzëª,HÀ‹AˆyÜ3¦‹Ô`šw¯¥PJaÄTJަ«¡{’¾ö¹µ`zµ9Ä ÞûÜÅ„d„ AïÇãÕ+ßùγ‹Rh†ÈöXüÁÙNîÜ}ß´¿°Aö~Õ¾fŠJÙ ‰¹! )Ì}%û@›Æ:Ê &C¬‘Â,kF ì´ÀÃÃkµÛÏÝ­Áû¯ßÔ#%ˆ*‘h=óÝeøï¿HÞúæF90¼]ÇÝzàÁLW3É3²C<¢šÁ`'grø˜ˆ6z±a\1LÓ!3) t&53 dU÷Uª•1C–„”²Ë 6Ý‘ ™‘º ms)FdƒnÖ²µètÉ ªlÔúÕí¿q'©6¥Ã̈u£`Ù8ä]¸!íúfî#ëfØRqµðÿüßÿÍçþÙ—¿ùè´ 7{ÚÓá·§æþê·”ïù»/—×WãîE¨µ¦ëÊe•ãÂë9‚šÔ˫˞w5kªEAÐ0è˜Ùå†aCV ã9BeË@B•T¨Žfâ¥Xº´h5#Ú(ÙkÖ•KÇ)ºX´¾DØXŠ÷¾œ–bÅ×UÕ¢¯=óK_ûú‹Ï¿º{Ëб;n˸{Þ†½ÙÃi–=MtêîH,kÓ:v×tõèed…”e=,нgF‘ŠÈuYÜÝ2"IçD™Îvg/>+F¼üí7¥­,TßVBý¹â÷Äç½scqB¦oYa"ÛœÌÖÍ#›È¨ G¸ÏET’é‚HfÊ) w¹‘>ôL×"d$D  ž4É,\E 2’žÞÅT¤ *!‹©AYMd&0”")¦‰˜p*£eM©d_T§Œ„ÖRÑg-PEDºH!cK¯dlä‡I Âý—¿òðÿæïýÁ—Þ\!ÎÜ„Ù[/ýL‚ïšÑþë<}mØÏvuõø¹÷=¡ëŠy޵ËÒ¤EqªY³µäÙtÞ—h=µª0#] ŒUˆZ¬ÖZ+Ä37úrA­ÞéÍÀÃX3hJÏÕÕj沬VÚa}\Öƒ;øøÉÏ\›ûXÜÅû ²­kFxö7íþôO¦ŸþÄóÏÜôó‹úü #í¸4–Ž"¦{+ƒ³¬*ÇëËÓ|ê´Tö™d廙÷YMÓ5=<椺KØ2÷Ö¢‡S…ºS E×Û·r7îoŸ_¼úæ«×mö2о÷4¤¼û”õžÃ” 4@•·,lTÓd€¹÷A䦯( Á zȬî—7Ñz DÑ›4U°@] “ªrF!Œ…!a° 0’vܰJaä Ý«t“Ð!c/²Sxâ1ã¢È­Ä©÷Ù”qC(3•~’,‰1õFc”ÁNL‘"4&E‘³°R 60G¤›N‰!S Mmº¾šþéÿñÇÿËïþÁK—«Óämõ¿hjû‡Ý(øC–¼¾«“×O<{w¸uû¢õrZrim™s>e´Œ,v„]-ò¾ÝYÃñäHí#Åh›œ±Ç ¥U)V”ûº+ª""ªfe]›ˆ˜¸*‹É¦^›¢ª$µØxc«h–ät÷ÎqžËÚ®×Ç9Ñc³T{H6È—^}ù¹gðìþ“·ÃÅswÆ]YOWµ‹gS¢fN=ÊiYR:mXÛñj™Wo»­+÷TÁ˜™Ã0V1õÖÝÃùèñ“ÍUê`e*vl'ŒZÎŒs½{¸u>¼ü׿ôÆåZvúÜOäÏýˆ§÷“Ƨ£_7²Â­yoBšLù«Êh‘¢Á"4Ó}äI¬GˆZ«ç R€ž4W Q¤¨˜¦%))R!F%û蘹:FrÈ01˜¹À€X’é™Åö‚`4¡’Ó=¨"#Ð"¥nY3Oš™@Å,zI³ÉCM‡ŒDšŠõt5-ZÔvßúÎÕÿü;Ÿÿgÿòk.JPÞn€ð#{ü5•¿¬íø™Ÿþ‰bõx÷lkœ®×¶vY{D Y›'•Ã4^¯KF辊÷]Ý©éDw_„y>Mzã{N³bE{oÕŒ&ÍD²‰˜ˆ¸¡¥Lë‚ 'l("(š€{LuÇ,Ç#Vér¹Ì~Z¯[¦CLHÌ»³v÷¹sB”uPF©µî&-»îei ³y=n:§e^—n§åþ´&ê0Ȳ49Íûݤ†ˆãéÁÕõUr8ÔAÕ23SÝMÙKÏê>}|ºûõ׿ðí×ß|'Êþ{µêß%Ý~Gùø…¯AaOSª#šw«°Ñâ;QÈYȬ"T5¥“Ñ C12 •HD!S9ÇÀ)#J¨"l±º#*ÔRÈG>üþŸøÉ¸Ó»´•m6ïE00™YÍΦéîƒûñâA‘•S´œ—ÁP DJLý”¡[1¦÷uCõm¯˜T vDЍYi-bKæb%'÷ª–éaZÓ¡laY¥f°£';W‘,Èß¶¿õÙÿÍO}ò¹ƒ”¢6L)‹í‹Õ½hͦǡÐ4ÑÆi+ö˜/quyÉ'yqët¸¨“]–µ].Z`ªëzš—¹%†:)Ó0TU3Ib÷š¦VÇzø…Oÿäÿâ “ïYþ’÷ÔªÜìã7gxÇØEOä†×½‚m`½³A‘i¹%ìá¢c†gºª&[ÑŠzoO F€IiýáPÏŠtê¹™‘\ †hñ8ŠZf£È gT;¨j’k)kÆ©Øn«ÿ‡_£l|Ê`*QÀ°à#°eP°9ÍJæŠ-6 ÁpÿIþÖïüß¿ýÏ¿ò`‰wÔ¸(?J‹ãϯ–Ï~öçgg}ïÖš·†Ö²yŠÝ¼5Îvw<øSòEÒwÃÙÒ%Sæ¥3Og»ÉL“!ÌÍRÂBœ&R΍FŠÆ¦ÿ³BÅ6š\жµÁLÌ(Õ³åöªG£¦ºŸV«¢¡A·è—•þÉíñ~âSŸüô3‡ÛÒ¯IIU³2ŒC™ÒÝ3ÝÓ¬÷NŠh9œ_<º¾¿?ßÚ|ùä:Èæ +ûý­d0CaËé²ûÊ”j;²¸[­ Ñ)HêÚ¶èø.ãt÷üìÅ[ûËû×ùË·)$ƒlç®·nª›þFe‹ gê°±š ª )ªHöeˇˆˆhs?©ìÜ›Y×­DD##åÉãWî=ÿ~°S’‚T€¹,4*]„9=ô¼2E¸#V)ãM±ŽHt2$+ " º›ZRDÈ ÑB”H¸™Ð·>ÚðÅ?{ýÿæçÿè›×GßB# ðÝ— ùÛRÈ8”_ý•_UL½ë¼ÄºrnkÏF´Ì®%¹ôÃÙùõ+Ù]ªhAÖR–ÎaƵ÷Z$£Ãn( uH‰0qìwCom]:ÉL+CíBñÜôf£Èά¯z,UÕÊD©R !¨“Îó1¢=Ûc‹«`ÿwþî/|ö3Ÿ¸u¸•-šDHº„–ÁêdÃ`¨ýÔZ_š»;—%"ÃÍÊðøÉãq7íz¯Þcš&@¢"鱞® ãía:tZˆªMV†aØæí5J5š[)õÞÝ;_ypÌ÷Ь|ŸyÕMâj7 ÂíÁ;5ö³ûæ×#C‘ €h+ä<3U0€‘q"fDÏ"R¨ÉSB.˜5±ôîDZޣÜêÑëÖh ÝA(„Û@~ë})ÁK¸˜¹hDÌÐó"»MÓÐ dÅ3!•7^ú ©ÐºaŠ˜íIùƒ?~å¿úïþÕŸÝoM6$„ȻƳäGuK‘OþÔ'>ñÉO¹×î\–~šcuD‹-Ë’ P/nÝ}ýkåòŠÏ\ >Œãš¥­+7Mê˜ÈÀäVã¨@Ó==Ä£Ü䟩îéadu¯KëëŠN/»½ÚðÈä¦pŠ™¤¡çúøý/îþßùìg~æ3·wgF4žD$™Ã4iTm#Ì ZS¼õŒ´Ë+˜ â*˜ëñ4M{ïÙûüèþë|FJÙ‰–Μ竖]©’…J+’Ð:ìõfÔËDC7‰iªî¦iÀæ-ø!Ê/BnÔeËîñ¦å¿µ\,¡zo¦UÄã “Ç!b‚A™Tõeé§Ù¡Cw¥¯³Àw‡5Z­žÞƒÑ=: Â¡”Zj-µØPÊ6é.¥ \OK;5_`6¯-~°ú>ßQÛŒ!oSRÞ•êVÑa€Ee  ‚¢2Ü0Ǩ™¹QÊ.áHSVÙx)(Ê 9‚¯÷nE? r^:§ã±ìG!¯Ea¢’R3\p ¶•}ä)ýÚp˜ E !ˆÄDUpö@ gá5$D dQÝEêVKF†H(¥<³!2LÇ?ýækÿÅoü«/¿Ñ7ó—|×~òWzÜúK­@îÞ¾õË¿ôËÊÚ"ZÃ2£»“Þûb²CV–œç,¯>ºþÐ gƒ–è6XE}º:]–@g“)GSÀ†q$Õ½—ªÌTØÖŒì«ƒƒ‡á¨udG§•¢;BÄ6í4s;¶#Eà\Öëû£œ~ò3?ùÓ?õ©çï>_§1mm§cös.: rC*ÔH&á1Ã"ÐûzyýðÉõ,6Ù0yÒªx,CÝ×ݹª¶î=ªÊôæ€íBeÔ0±Ã8TËð0 T­wFz뮉Þ}öÈ÷Ây|OÀ×;Ûmä6+ùôŠ/À¤’Þ³8¤ö¥(‘!”E H3[d$ 1™b™U“*`EHÕˆB‘Au‚¬Gʦ1ÈË…þÚ¯ýã¸óàÒd#?D Qíî‡P­ÃÅÛ?¾¾¾êÑ<—GhX)ãx0ÛNñøj¹^cum¾­ZE¬¦ª0Ó:J´V¨‰VµIm´TÛìÖ)æ´HU- Ïvº{÷ü“ŸþÄ‹ï±H‰­­­¯)B-¥ì†ºÙôèÕ£DNÞkxqGó€–ãÜ[a¢ÅCMÏU 3Ù“¢ZÓ½¯kQ-¥˜˜Š‘®á’iáÚ.§u]®3]Ë(elÑwCù÷~öÓï?T{WBþûMI¾³š,O{&ï^ajZŠÜàC“ôZ'ÐÈÅã!ñDd=žHÙF¨¨‚tÑÝX¬‡R.´HêÚæÌŠœT èI¨Gì<3AÑ½Çæ ½SRss<ˆ€B²÷Å‚†¨îÉŒ\T«ÊžR"V!=q©´¢#¸ftåøÆÃãþ~÷·?ÿjË òðý¢†?R÷ø·~zö™;¿ø·ÿQºkïláI÷NOT1…YLwýþüù‡'{rÄõœ)c¦¸7“,&C)¥ÔµùãË«ãÚ:4ÅÄÊö¦ÕJÕˆˆˆ$KZO¥ žªVkQCÀ=»ÖM7Ü}}2•ö±ô#úà3·n+e9ÍÞû:Ÿ(ÒÃ3˜ž 省9D견Ë2¯Í3« ç©å¸Ì%užãxl¥L´¾OÜg¡G››$+SÒ»ÇÚ}î}][;^×uvG)ƒ [.skL½Ø]üÝ¿ù3/ÞÚ뻢©ü^L–­Æ•ïˆy%oæÁD°yH ÁÌ›¡lP¼u²'$@˜¡‘™ƒ¦ Cde\Ö¾žgœ&ÙïÎ&Ì¢%"ÆaHïx|}ìÄYÙÝžö»¡ö–q3ÎM–€ÖB82Œ U@UJ䲜Úñá4ø‡?tïî;¥l«": “ZÍPPÒÃÑE´Õ‰æ F«ewkõÆ«§uÍ­o¡–”: \×e½RÓãõý³³s+P§Ñ¢5PÍÊ8›§m~£¨š«‰r"I¤èXË~?²WñŒ*ùÑ{Ï~ãõËKæ_ ÿz{ß4ð7—{6VÒ0 jP5…yœJ=£p(ŧÄ19ˆŒ¼qƒ›Aî¨>¤Ppq¬6Q,Ò7¡"¦ªÉIpq]Š"F‘kˆ&æÂ1˜HUÓ¤ŠIÒD ±9RPÕq2ÕLUU7­î ô‚Õ³Ðó÷>ÿGÿäs|êx:œóc³<Ýùo”]ÿàïÿûçï?­·çV.vlÝ!-ƹ]eBá‘0¨H&‹ûÝáòôÊÕõü¤è~˜vãÎS„=ƒšh¤ç¹Ãé<•2MUµEE¤÷Þ©ÉèëUtW¶<éžuz_Ý{[OO¼:Úå½>sïùç÷ûÛ­·—Öш2±¡ Å kÁÒ½¯+Ö5Zgö]{[–Ór4+méu¨¥ ÓnŸpd¸YÅPŠ'Õ ˆMæÞ’`D)+E7¸%³’¥ãpK´f^"âüìâ0ÚÕüÁÞ[ ¹åéß:¾—-õ¥eSîA˳:0=éªÊˆŒ¼Ñªª–Ì“ €ÃÍŽƒŠG,ÌP³d/@¸Âg 58Û1EŒ"6A°gdHæf'%‹Ûì31¥,‘W€(v‚Æ<šÞ'¦&×­Ao ŒUÔ~ÿ‹_ý'ŸûÒƒ9¬*]ïZ-›ýëâüî¿û‹ÿà/ÛKo´ë¹Ÿ–éÓÀ%')ghs²NFƒï,6íÏž¹¥Çµ7ÏæQ ¥ ™±YÄ2ÔquG4_NíHFU=ð̤ÔÒÆ:’Ôû0tÙ$¹IzBû¯žý´^9¯îÝ?øÁ÷ï†ý8À$©¢T8dsߨm<ÌÓ…U–RE%)Å ENU#_2ÕÂáóÚ’6·qØ©˜"M-“¹4SFº÷>Tsg÷Öûås·ì¹»‡¡J)e›"r÷ i Ýt°®2z$©ž´NédÂÀA©z}:Ã~˜ÆG—†ál÷ó|y:ÍeÇÞº×:¨"·7¤KéDF`(6ý¿í½Û¯lÙuÞ÷1æ\kUÕÞçœîÓ§»EŠ”äÀŽ)G È[ü’×<ä=ÿšA±¶#[Ö…”)S)‰¤Øl¶¨î–úzNŸÛÞµ«j­5çãËC&[”,’%±»9Q¨§]ó6æßø}Ó2döÀ¡·UeC-›ÍT‡:Žfª´Ö½åi^ß}øøô“»B>ƒå=K Q! ZÑÌ€ž¹¾¨ª*p‘A¥$¼3E4K©Ñ‘q œ}‘iÀÁì‚Y)ÝLZ"{kžÜ&¨dRZb+L‰ð¡n$VpÎpOÏĪR `ºy6˜—Â$³ª^ˆŸù¾²P“¢<¾ùßþï¯}å»×^®‰÷à»ï¾ùôêþåůX+ûÓéæöv³lm0öæ®eŒngº—gšŠšÝº¸=ê¶ÍmYËJYh"p–6ª’"š>šÅ I¤ •kãéhe<Ì]DUBç±#¼© ™@)ÙÓ½1—»wno ": RAz4ŠJ#•TŠÀ† $ÔQœLJËXW =W.ˆ¤Y]Ö“ÕÍfw7^ë8]l}Y»7S6“Á ¨{Ó¤Fjk&„ìËJ†šBÏ(Ÿœ—ck+˜ék_ž>úóûOò'ÖÅ~(¿ÿb\Ïö*BiÈ,r;CÃSÍÀ!áD­’¢’’P-&S`õ\DTPµgÔR%•@1+"Ŭž½‰3Nd-”ˆŒÞU²Ö\Ïær"5ò¨’À@r4Ý·Bæˆ0»HG³Jpnø×ÿþk_}åiR "~…ô?iw±¼÷Þ÷^y募ýÂçžïϧàÉõÓÍ4Hòó/¿ìë~ika ˆ@â¬È"…:”i,aíæÔwe\;õĦ$ÆXM,EXÉtF©JµHïét?QPm”Œ³{ÈÝfèËÂX/j¼ôâ ƒ) wV]Õ$¬Xj N HŠ…HªE b±ϸC›6›q™ŽËÉ:Žór}sÓÝ9ŒƒG‹p+Å6Ór¸é &cµjV¤Ž:"zë3D25\NEhòø1™ëºfzo Ý_ûýÒòÇ“NþÕ¼å™JA€gÃR@ðl² ˆAÑ3yª$(d"Ø)ŠŠe”Z&¦ '{Q¬&½™mzìÕŠa—¡œÍ|“­ªð˜­\ Y‘EôŽ`Π Àm`!"á]”j/|ù¾õ[_¼Ò€ˆÉ~ö"+üMÈú}iÅêíK_ú7ÿ\¶ŸÿÂÿz°{Ë¢‡ù‘Ó?ÿ‹¿òÝWžp9q: Éh¥hÑ)¢ë Ó­ç"'ÙËq3Þ6±¡¢J±ðJí½K‹fÍîNR¥µivõWw_ÖSDŠ\ \gŠRû鳿¸»s{ T²Š2„jª6è3¨¹B), £œ•Þ½xHfé½CÏŒ:nÆÌ«ý#¬nvyاp]c§p1+ÃX ´õ%{Rš@bífƒh1BæÖOÝ39f–KòÚ£œN-<˜=C<®ûw¾ÿÁþiü¥ªÉO,u}öÊIÂX25dR¹d”b#‘±V»ô^“"Åa!CEˆ’Ù ¨6+X€ŒÈdS õUŠ]xoªcÑs™™º)„!R¬ Z*1£ªš °¨¬¤á‘Ù!Í ˆ–ÔN+ª·¾õÊ;ÿò׿ûÔÏAÿ>ÐÿÿTÆüQéîoîñwþÏÞü×Ïéý_¸3‰±çÑʲÌǪýFDIÌtw¢CÇÛÏ}.rˆ’gd¨g®KëëšÞÏ~KfÆ AŠª€¥ F+(Ck)µŠjŒS­µ–RAɈîýÔ–ë›}oëË/þÂn¼¨e“‰F1žUjªÅL)DD(1R,SÈâ)ZêÚf=RPM'ŰœVÙî&«âÞ2SÕ˜Ì$ÏV“Å"{¢)¼ˆu¨Zºëá8¯mîÙ=²ùä·z®f6T%×·ß}ãý«‡ÁŸ‚# (Pë¥l [Šx^«®Hd„ˆTÆ$2Q”Œ Ø‘£ÊU‹ªžaø„“ÅYq'xlë x˜DTИ.P¦‹$sIoÌi‘kx§S¨ô³e¬¨*“*„¬€#O‘ë™X£Þ~ÿê_þ?üÎu$žáVäãzý°°ålqqsxÿKÿá_|ïþÛÃ÷.7Ÿ»·Á9äYN‹"U5YˆsŽªAvwî|öxâY’ÔæéùŒËIfJ$»k²T#Pm¨e0-*RŠÖ±ˆ ˜mÇq2-&ÉX½¯=·—/¾øüPTÏ´4V•A`f¦zæŠ@Ïɉcn24’áT©$ˆÈ õæË±uCwo'Á:MUK9œŽÍ—Ö—ÖZD@ ´L›I€Œc–™Ã0˜!ƒ„ªSP ››Uï~j§e=z£ÈxÖ„µõü)— üñkï<|üè Ÿ»ýkÿø¿ÙN—¥œMKOjÕ¤;$‚‹‚f“Ç ªh¨IF¨µ„(³‹3ìøosS··.nk +*¦U)`ŠTUERÀ$ NŒ@å™f)JbVÙ›„µš0žF ¿ùÛúoÿËÛÇÌs?£<3WúXß*?Ô_tNºDøòÞ{¯òtõßÿê¯Öí½ë§“pž¦¬™iâÈôÈ:nz_ÞzëÕ¢ónwQÊ(ÂjYŠ*ÑR ù B22 B&™ç¼¢ˆ¸Ç¹¹ÎLLÏæ;iE‹Ù`Ë?ýï>ÿK/ÞK•REL­–qÔR¡ZJh$z˜{%ЇyŒ‘$[ôîÞçãGËÌu=­mï9G®½/áî½E$k©Ó8(dG±B² U¡LöÖ7ÇÓºžæuYšªFo˺,ói½Ù?‰ŒÍ´§Áóøîƒû×?i1åÇ™¼>Äï^{ó}ˆþÂÝ7Us)#²ˆ¬ˇŖÌpÕL/ª*TP2$s1-‘ €Ì®ƒÝ ÷&¢„GžTTDÚóŸ D,¯|ç·_½Þ€*Ë2“nEÈoÅâ…{ŸyùÿÑÜw7³¯k÷5½¹wÈÒ{ Ow’Îtfdó¬\û¹“C)ãPLÅ@ "Ñ 0™n‹ß½³Q‰Ì„ ÍU=Ði’¢ÔêÏúEm¬c¡’’TOö¤ !b&V G äi^—¥ƒPÕbªRTA!2RQéÑ)AøÚN§õ°ú¬µn/nÕRÖå0oÖeñ–€ˆ „¬ëÕ{ï¾õàzŽ¿©:‡SöþŸ~ÿõ÷[ôè@ÑK¦Pƒ „®ˆ³JIEŠ**,ŠZË :EvÑfSW•Ap§-&ÉD ÙÊp 2Õcñ\S¶(;ŠytÕPœ„$TÞ‘EÀb½I–ø¯~ýµ·oZ"Àöëä_9˜?Žoþ%†Ÿý;NŸûjuRµnÆéö²ÎĪjTü¿~ý=¦»é­‹XæœkžÀÍ—>S7þíÿò޼짺iö9‹¡$-9 ©žÒáb,PIv¥3²‡j5ª¥–ÞŒu;Íóì Ö¸ØVÃ"˜˜›ÂôÜ&/&ÒZëÞ3™iI8Ò³+ç'~)ù¡HêÀ ¨ž%XŸ}ùÖË/ &J)"E¤„+·€Alã¡ GІh ‹.áH¢y#bé§y»·îsú)úê­ŸN‡››Ç͆ ±]o‡ðHFdf²3=‘*%“ÇÃq][²‡×ãÕiÿhÿd¿æ˜;#ÿžbŠH<¾zòK¿ôÒn Nr8×.’j"Thá³sAURu©z©äØDÚ¹3¤eŽ;‘A *²‹žTÏ¢Y’Cæ¤ii"ÝÄAöÈßüâ·þä/®Cø~—àÓ1¾õþ¼¹r·»¬Ó¥Ô‹ìá‹w T«`Wd Ÿ½ï_¸÷¹;w?sŠÃi9.qœ—µ¯¢\";Ä’ôÌÞ3ÒZKR2Aj¼9¢JfxÏðŒÅTD„PJi”*Zƒ”RS,µ$5ÎïX(S#‰RÂ4ªÆ¹+C$ÁÆ\ÚzÓæ9}¿AzæY𝤇w€½¯­Í½Ï¤K`=–ÓIM2éWûë÷ßïénžÎ¾$"<ýw:úöÃùwÿàÍ9o˜IWzSÓí[œ²žs„¦w—™.°ÌU“Œä˜9ŠŒfUT¨Ó䑜U&Ásd2(ÀeJ䔢%3‘)Ã[ïí¿øµ÷Ö8۟ħgŸ|¿®êì¯üÉ2ö·.ëæâ–Ö‹à¢yæT±ƒêN`ˆ¥·å¥—^>̽‡·§uÛÒ¢Ÿ©,îÝ£e8D#4¨T«u8—ÕÅŠ'ÅJ‚6˜(´u 5#•°€­="éé΀VXŠ”Bȳü™˜ž3]J©ˆðsåÒ½…©hmŽœE¤” “‚N"™M,‰ðˆÎs›—eiÇ›ãÍ£«G÷Ÿ>ztÜßôÕeøŸÖiFÊ7¾sÿ[¯=t»“Ì9Ù« Š´Œt÷ †/½‡ÈTì¶ð2ò¨Z6&½ª‚0O‘7@’àŒ§š ¹B¨:ªnk² vÄt=çÿûŸ¾ýî1x–Bÿ ˆç§`§| ôÇ_¹¹~kW—;·¦i{™6%µÔîL ldj.=æ{/>OÈÚ×y]—u]|9,‹ÊŽÏÈná±ôÞ(b¥ª™gÆ3Ûr :àp&€" ±„DJ)#)‰ FŠ(`"•(ç+KµTµðˆµIïéý섨R$Ù–%ֶ̇ÞÖtéÍ×幞A"×DcIžîûù¸D{z¼þàêáãåpˆÕææ>ì‘¿õ•o¾õèÐs0…ÚiˆUUEFÓ; TݨŠÈ QÑ­‡iÄMfc XÝ›“0KU6¦SÄ,ºéyZÛUÄcÁIP"¶” Ó‹IRhõ›¯¼þÕWä3Ñ?þ¥ÆŸt«<Ó"îŸ>~üàñáÉÓù°_[ËR$~ÖªÏ )øóû‡ßþÊ«GŸ s®6õÞHгYL%Õ82 45\˜–j™9K&x2é‚î„gø)„˜nÃ3Ófî)æ eÐ2§ßýʯ¾}â§äù›Ó,±¼‹iŠbÁX3± Â#Õ&ÑËä­RŸ»÷â/¯1óÂ/|á¹{Ÿ«ãðñ:ùÑÜ1pXúøÒþÙ[–»jÝ¡õÈTÁ °4ãTt0Nѹ„Ÿ™Ô DTÆÙEŠÊ9‹Q4[[1*6WGþÇ/~ïêèßÏÄ}Š£¯Ô[çãþæÑ“jì´,»Æá¥—~yî¤C!ŠÌgf¡VjÙÞ¹óR-§%¢‹'öûy]3BÖÖ!çÔ,¼ŸÛŠÕm¦xt±¬™-3TL¥TÝDg4*Ì´ V‚<3£Ãû¢’`ŠÕŠs&$Î(w©E«êf·Ón¨Õ„`“Ì"¶Ýì¦a;M›eåáØžìç‹ËÏÜ}áWÆéòGBSÖâ®JÊrµ¶ßøò«žªØ¥ª ´èV0…Ó D„"y€,fƒX)uˆè‚ZìyÁ†“6(4ö‰cgzUjæFu:~ó•§ßüÞ)~|z²Ãò74â3–ÃñAe0UL‡ÏݽwûîK5(`‡tàÇ¢”ñÖå ãæ9îK[ÚÚys˜Oskž­ùy-Š@=û & I£ ÔÉU’ ÷u9 +YD#UD&!L ªP j§f¤ EˆðU5L³j13«Ó8ŒãPp4»¨Ã­ÝîÎÅûÞÑ^=Ý]NÛÝ òñª5ÿÕUJnÚ¿ÿÒ+ï>Y’áëuïÌ@†ˆ x€ŠÖ²!OîOKëpwH £²Ï8¬ó;îO€MRE Y Ì÷¯®¾ø{~rùÙÌ ÿ}¾ìóôèƒ?¯!d¥æ­»[7N: d¸ Âû¸¹¸sç%‡SÚº´lÎãié="»Ç¢êÑ–Þæbaâz&=S!ÕJt¦ƒnEöû«¶i*µZ1ÖJ‘á)„ÁsKp£tÙ“ F‡ MS‹h©uÜŽãíiz¡ØFPÕ†Íæâ…{÷BeO W‡Ãã§½Ÿ–Óñ0ñ¤¼õÁñëßyƒu§Õ¨W´#Ê©Ç>°B‹ŠT•­ˆ%¯UTÂÈÌRL±Jž/Óu0ÝJœ»%N̹3¿òõ7ÿì½…(9hž->ÿ¹¿z}n}\ÝuYãÎíí‹/ß«ÃEp€˜™X¡HKôbåÅ—^îÔýrrøÚxZý´¶¥5Þ–cë§Ð\Öc÷¥y#’LE‚j­#¥;×qu³,Nj×’¥L"õÃ(CUFREŒYÀѤ ”L)º7‚QÔ¬ŒVÇ2lëtYÇËË‹;E‹ÂÂóââέÝ´[·>ûâ Ÿ©6í÷Çã²|œËÍòÑÝò­WßùÖwïÏk…(Ñ#BTq‹‘JHä3µ„2BmÕÌ)ˆQeëqGÊs¢KÕE gÛ­w?h¿ýÕûÇá?^?ú§ën¹¾z/ý$š(t7ŽC¹uërÜÝÛeZok)Ùý”Ù=òùç]ÓO±¬±¬}]{›×¥{Šj÷ÃvÔ"„‹A" œãF®ÁF«W7<¬Ú£G®”¢Rˆh}uG¦DöÌá@!*´À ̨ Q±‘2Q‡qsQ†aºÜnooÆ© £Y3Á/¾øâ |îöîîÝݺîÿìõ?—Ó'%¹óK_ÿÞ£ý©g‡5bU‘¦òXUÄŒ‘-b"Sd=‚IUªPâlÐÜ7™-âbeùÒW_}ÿiã‡ì¥Osvø¯ûšmÙŸLÝ3‚õêD§aÜÞ’²Q+ªE‚ª èîâÖvw‘`ÐW?ô˜ërœ[Û¨m2éÊ¥/™¡"áÎpº;TEá¬7'‰T2"!"P! Êà*J­¤Z$4(0³¡¦„sx)z.\Žãf3m§éb‡ÝnSLÕ°Û /ÜÞMï½ÿÝï¼úû¯|ç+<|3üØO%>ÌKáñ~ùÚ7Þ‚ÞSFÞ“û"ÐdZë­Z/’5¢‰ [‡D,ÄìY¨µ\Ú8|÷­·~÷ëü/E\Ÿòô×ôÃ÷_×8 ‘Çû%BEµÓ0îDM‹¶DsˆVÑÁl¸ØÝ&á½G´Öš{çv8-ó“h«‰„{0òìÐ ‰X¼-BE@Äçeÿλ÷ûJï A‘:¶~tï xÊdP=ã¿ÄTk°«°¨«¥ŒdŒ*UÅÔ,¼·åp±­/ßÚ´vÜï?X×ëOÖ¤?[Ìß~ãÑ7¿óN`„4«áyã>hÓGæÆ£E–¤7?$=ÄÈi‚a0[{÷ÇÓÍoÿçï=]Êßù}Êj)?ü­ =|ÿ{%â]Kãa† ˆ˜]Þ¾$tigö»í ™*£;z u¿9žVo˲0B¾®g—ÎÌŒN÷ÈìÑW¥yÏÞN×ï½óæºôÞc]=Ó€ KÒÝ; ™ÈH¤ aR„¦0=[Kq0bb¦Z‡Zê¤:Ôa»Ý^¶y>íŸÜ½½•¿f¢?¾SÿÑ|&´äWÿäõëÃ1®ýDS¨ 3,cf¬C½Ì =( s“¸Õc LA¡Póµ7Þûîëþõ©áOÛ³^þºÏ³uóôÑÛ§ÓJoðc–ûWëh¹­¹öTU¨´Ú1¦ ´é¹»Ÿ%ªÈ ZåxjNñH¤”`u)èž’iôôîb¥Eo}mÝ»èõ“ýÕ£+‰ÔÖ"¡Zï$A4”JÙP‡SM Ez‚D4Ñ1ÒˆªVD¥–RuÆÛR.ëp±ÛÞ¾sy×W™çü¨gº|N½^ÌŸ¶÷¯n´\ö\Ámå á—ÀNô”¼&öW‘7ÈQ0@F)CÏ–r’bá¥ÚóÇn_þÚ[×kü<ÜúQ?úzÝ×}fo‘öàêÔü¸»` ç¾î.FQ“ ªRên÷|)[$SÕÔJëÞ"óÒî ­­·Ö×è-ΔÆk=×Õ3…´Z¶§Õþüí÷z?¨´’B”³)63AUJI‚0=[œhj™D A23é‘b5-[™¶µ>_ìÖ´ÝÝyáδ‡Oxü@§.=×ÈAìRmÔb—Zº˜%+ 2G³­HW(VG½¹ÈݽöúÃo¼¾ïÀÇÕåïp´õúñ£·‘kºxØ~ö'7WuŠÍ¦×CÙh t}¦‡´Íæö;ŸM°{_Û*jk‹ÓÜ®¯çý~ÙïOûýÁ=Ú²’E¤X—ÕÝ#Â¬Š ‚j¬‹Ø›÷<¹Ú·åšXÅtrÏè=Ÿ îªæ!‰LD¤'C5!LÐ3=èPè(6Ø0À¬ ãv³¹ûüån4ù$‘i¼Ðš"¥RD¡ñòw&CyK)éf:d†"˜ƒyXn¾ñÊ{‡†Ÿï”'6ËìO¿ýÐæ6”q^e^ŒÝ4@d^Ûv·KŠÇZ¬Ô:‰n_¼ûyHéáP)µ⎔2¯~<´uéI†èÈðså¤xïóé@4BмûÁÓ7Þz²®k´kgFšˆ ¦³NRR$E"T‡ôÌvdŸ }lEhÔ±@Óq7/ÞÞÙ':ö¶‚Z“ÀAoëªO»? QóVÈ<"MØ2FKÑ|ïáûßxõ~þ¼Îøãm?ü‹~z0èêk;-|ò4úÊ¡èP·ÇSŒÃörw›‰RЇ½ôòç­lƒ^Î$|)uØ uè‘Nd¥ÞÝPP‡Z†¡X)µl¶ÙEÛ²^!ØÖú‡ßxõñÓ’=N©’”èÈèàšÑE,˜‰N=wŒ™]‹i-9ã{`¢µVÅFd7L·ê8‘nmwöIfŒ“ÍF…&Òm,ƒ†‹ê¦ûµûÞJU âÐóD¬‘§”à-÷auÿöwŸ^ž¹ìþ|»üÈt1€ãÍýÓáì‘'Bï±®¢–”ÁYçž»íi˜Hñ •a/Š AF1-V#¬õ Jñ4±l%H¦Y˜jͰbÈ‘ûï½ÿêk:·Ð3.ÚŠGô6G,é-ÎP¢„jí½g¦HÑ2FZfM*Ä’"©¢CÝ–r¬µNÓ¸Ù 6Ø'ø¹"­3j ŸÙ²ªÀÂ;ÓÜ[¦#¶ÌçiS@#×ÞMêHÛíÇ?øÖ»+õç›àÇzÕ hËõãGoööd9]©âúÀÃì6h¦–XšgÚv³k½Gf©C©ÓP&‚ "YKá=×µŸë Ë­1B]4JµRj±Í8ÜRÙ!.{vb–À·¿ýÍO>ÈE’šHCº¤&¹f†`È0@È`Jr wDi¦¥Ö‘Q˜iâÉf6»˜†íX릪|r+üàÑMj³2Ajóåÿ%í*=ÊJ·‚IEND®B`‚snd-16.1/pix/sceq42.png0000644000076400007640000000064511147553270012754 0ustar bilbil‰PNG  IHDRMÅ\!Í3PLTEÿÿÿààà   €€€@@@ÀÀÀPPPÐÐа°°000pppððð ``` o| pHYs  šœtIME×  !O€,íIDAT8Ëå”Ñ’Ã EÄ,²%þÿ×VÝÄÍ85É´¾•'“‹½¢%Ì $?‘üÝ4½9YoÑîž³;£Ùþ/×æË¶¼}"†…xcÑž$·4®qÌ#ësmÝI¬|Úí罡 BÄÄrµÓC^è,Œu£záÖH§Ø*ö¥ìŸÀ†:øùŸ³d!J]ôXƯô×Vh”Îë=-éæÝ‰ùc]K©&˜«oSÇjcÚX/NDÕß\ ‹)æïÜ©‘î $÷œ¶6‹üÁÛ‘Ä´Òp»Rhï [›©y™ô¼eËÄÖy0ƒçÀ¤(¬NgÀÜ’ïÁ* óÂlå Ã}8˜8)IEND®B`‚snd-16.1/pix/fmeq35.png0000644000076400007640000000145411147553267012760 0ustar bilbil‰PNG  IHDR {% ‡3PLTEÿÿÿààà°°°ÀÀÀÐÐР  €€€```ppp@@@PPPððð000 * ô¼ pHYs  šœtIME×&eTŒIDATXÃÅW‹²£ ¨èÿí@EZ¸³¶Ì4rNÌS£——ì¡õò(‰|‘4–$—ò­ÔÂÿL"d-Óróí˜ñoá¦ÙjÅ ¸…ü’t¬”ÉGâa*8 rò2ÙÚù‚õ ÿ„DÆs¥$ÖÊéÝŠ•®[SàÔ{È?"I vI.@r®ºSyPÇ—æøÃçÌ ¾eæcU¦/Ü@.«à«$.nžRL„ŠãnV¢ûs‹²Ó‰°Ù¦™+™wíSÀ ä›™ß$±ÿ”èÒP–€Ý°g`Z—ÝÈJ®Ì (Wn"7ÚÅÓ$Qï’0Ëóï(_ _¥(í9+9N¶9Ž·º’ƒ)>5< ¸…ƒ$\¤°’œj™¤òæÖ")_ NÈI6míX3d©’Ù¤˜¼C·ñHVë"ñŠñmœäT;H*_¨T`7´X@ø1XGgÎ΢œýú¥’CãWžhp ¹„]$ØnäT;HRg9¥Æ½ -~¯žéÝG`îÀ¦"S 3óàßôõPpÌ•¶Â Ý0«õ‘„ºØù8É¡vÄ º¤¶ÒÛàè%dw\/«b{dÞ•^öM~˜È#Ë·ßÂL®·=Ôµ3¢0 \! 4;XçàÊ‹>’ÜüGI²ÚAbäMzêãð/îÓ‡)K½ëö­!e4yAº#3«˜\S¯?^ûH”úIV;H¶I à{Ãáðzæƒ/zñ ÑZE^ô‘pɤ'©Ô’gJI-+o·¾0Õ»/“R¯ðfû†ŒÁX%V|R«v™¦iœ¤Ró¦–ôÒž=´žC%I#¦”-×?f'ÿ‚/ºH|%ÿV —IEND®B`‚snd-16.1/pix/sceq19.png0000644000076400007640000000203411147553270012752 0ustar bilbil‰PNG  IHDRŠb¸N»¹3PLTEÿÿÿ€€€   ààà ÀÀÀ°°°PPPÐÐÐpppððð@@@```000e;€ pHYs  šœtIME× x’'|IDAThÞíš‹’ƒ Ey4T›¢ýÿ¯]µUˆléº3df»£¥ry!B¼™}ùÿ=“R*¡é#ó7{bt--pÆ<¯îs=ú¾Y^É¡’}õÏŸ®úÅWývó¡–”®_Jéh|: ®›d÷])}÷”àFª§Ñ'‚ºB¹‰LW–rCêZÑ<œkÅ€‰:kI›7 @z)4•ÅHA’‚j’2ê"„všÌü»{­<@÷;øé©@å<•¦®‘nMkÍ‹3÷W •¼Bk%¸fÛ!¬³þÖðýwåÛsƒ¡k*¾ƒ”hÖ¬Ù¶ÿ”µ´ÊΘž(Ñ 4ý)€Ò/e*S(Ã(}©©L   r8@)”šËÔÊP1(II,S( ÷ÇJêAËÔÊ %”úz»Ýd,S(½6PÚšË1²,M;R>v#ý«$ Õ‘€Öë’¥iâ Ì<ì°™räY{™´>XLá0×ÊÒÄÍèù,éO$½IYÄø ?M\öÚöÈŒôï$½I™³zèš›&.G ó"ý[I@Ô¼qŒÍó%gâ÷ÉM'ö_ç#ý»I@¯½²Œñ‚&®GšeœHÿ~ÐÛMÄ<’&®”yhF¤?‘4K™ÎbVy$?MÜ·‘ õ[sï£/¿ÍµâψÿM£&Ínv¶IEND®B`‚snd-16.1/pix/comb.png0000644000076400007640000033527311147553266012610 0ustar bilbil‰PNG  IHDRLÃpNçsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ3×uŸf IDATxÚì½|ÏÕÿÿ}¬5³ff†Yk–4šIHB* !©I¥B¿¤RI’*•JBBò+!¿%¿B~Îï_33ÌÌÌÌÌÌÌnß?ÎÙóÇFéó~}>ïÏ÷ýÙ¹\ž—íñxœ÷s?÷sÎíÜï÷sŽ#I‡âPŠCq(Å¡8‡«Ÿb‡âPŠCq(Å¡8¦âPŠCq(Å¡8‡bÀTŠCq(Å¡8‡âP ˜ŠCq(Å¡8‡âPŠSq(Å¡8‡âPŠC1`*Å¡8‡âPŠCq(Lÿ7Çqpç ïWáì„WE•ÙNmÆÓ•p’q|®%ßU4gùøÀxz9ÐÍw˜ä@®ƒ³œ°«¤ÿÚ2Òî@'Z9ð¸«&òN>8‹¦­ÁnÖÐbèé@C¢ˆqà-69l N.8Îw™Ã £!Þ¶¬æ´w`­Ãpzã §¶]Àé‹I3ا,O9ÐßíÎ+àDÙøå!,FòšIÓÌ:–ÆNŒuÈ&€·ø'œ`pr ƒ`˜é@o›w'¦;ì¦a¤XžïÇ 3èÃè`óoíÀ+Ìp8J$$áô‚å4ƒ–îÇmܶ,pˆ#'œhp€4Ba‰mÃדÿZ‡ñt%„tœ*HLµß;Ù2G:ê^ÄÀ:ÐÙÖå5‡ ‚™J'œo`Ma“••ö¶ '›6Mœ‘°…º°Ü–1ÀÙ¦nN.4eshgøßÍòlœ¥côa˜ûûk6ýL‡L‚p¦Â8^„‰¶üÞŒ62Óš,£9Œuà9K[7¾t Ñ¡ûᨭۻŒ0¼L 2N:ieb€sH0yÆR–Ù²†™v"ÉöÉÝŒr`ˆcøŸìଂ<|až­—G´á[?z8ÐÇÈSFÃ"úÚ2Æ:°Æ›ö3#K¤›ü÷km¼$ÒS^’å…åeA|&Ú>ç@¾q|cÓ盾ÎN[æXÇÈI¬[lÚψwˆ§ŠISÀ‡<˧‘6¯‰Žáï<Ë‹e¦Íû0 ¶›6ÌÅWeèbÛf·‰Ë<ÓÇÒ~ 6yŒv`ªÃZ›4ãM»8ã Ëœ~z§ZIz—8¤B –À KcšcƵM†¯ËiÆ7ô4åÍsH&Üô§±Fæ:0Ã|›hx7Œ>¦ÞyFv˜nèÊÅöšo9¦ï³Üò(×1ò5ÉòŽmƒ½#èå¢-ƒ`ÓÿÖXþ¦Úÿšq•¶M7˜>ÇÇÈÎ$Ã;f>“æþ,°|]cùœo¿%8eiJ¶m=ÇþØöÛd߯·e/±WÙx3m»-·t­ð q™-o•ý½¥o‹Íw§ý?ÖôM²íßåöFÞ’ˆ ‰"‹@ÃÇ£åµéÖ[ž$ÚßZ›ªÍo½}^nøŸL8céF_†yO°})ÓÐ’L8ËiÆz²¬¥‰D‘DshÇ+Œ¢.[p¦Â—¼ÅZð =éÍpžc"á$ÓŽ9ø’‡3ÄÎ-k š8œp|ÀqfãÔç5p޳'ÒÆ¯Ž÷¿ [øþ¿Ž#9ÊH^cU~S|x õðA£ÿ2Ú õp’ò>N‡!hÆ¿H?ž‹ý‰çþÄîÉÕqRv£°kL»Ø jmD/:ôÐ÷8é PÈ?—Ù{ÿôîòKú=„³a jðiÒ€é ÁG=‹3yâßÇOfBÀ† |Ùàm¾Jx žú›ø FÊRÚVdNåG¸Q#9~µö8 Ì€ÈíÇxkÈ— ÑïêùN„èMQg‡þqpW8dK kâºvžÀ€ø®œW0ÔËat­îWŽ“ ÁSóiT빟L‚¼¿§›²ìÜHƒ†i÷Ú’ˆð޳"S¡º±uïà(‘Þß“€I Úû©Ê~ª‘É ÑçP]‡E´,ÚŽËaA\hXˆö<ÓÄÁþj·AûBßwBå´Ã¨‘å ñ%Tk1…Òl·²PÃO¹ÞdÊQ-ÇÔ§Ÿý#rŠòv;Œžù2x¼K´¿x ÐãýL ÂÂSÜïVØ8…ëµ(,ÿ«,?*ÊðdwÔì#†þÞ²\eÙ!÷(›ôµ£n¸}—,Ë‘Ž1,à}׳ߒKŒÊ}Õ›®e@0j»%þ`èô­'/ôzV”cÆ Ûwô”lQs÷w_òX’ÙÒÐWð}¿kÍÿÍvÿA³Ô?Œí øsÌH{ÒôO?K ®ØMü.±×¯ú¿k¡Wð×FÞrí»ŠÔÿ_…´B}3¸Ð÷lû¾ü5ä•ÿß?¯…äŸ!„3dùÜPôã^Lßɶ*“0ËÇ|û.ÁŽ…9@ªmß>A6Жy„¥œ4í›oó€ðˆ„ûŸ0rnßágä=Ü?™l ʤu ¥ kÎ9K Ÿ¥dû•$Pz3œ<|iÊ*Vô½ŸÚDòd“ýP‡Áþüjl³<|ÉLJüI#ŒS‰àô^’¢qʧ’áúp¸”P¬aú·AjŠjÁ(^¡=³YK#×·*Ä3š¼7zÎà«§_Fs®œO¯®_‘9¢´<Éxè;s(šè0ŠWpŽ‚ãL5é{Â<Úâ,]{ÿHÎÔðœÇÀ›,€ã÷ ‡Ïxg ]”Sƒ&¬Ái"&~ó, Ú™ÉÀ5ÉmúÃèa/£t‡þ „ò †¿è7`ù3èêQf²@-æ,åb?:3~NGCÀ‰ýú ‚I@—B“ÆDxnÙOëÁ©[8ïdð#q¾‘¡­U¡Á% Xšçpjv(ú/£Ì78MÅôáO ®Çà7ÚŸKRÜM,îÑ‚.L¢KŸŸ -­ ñ<Þñé©eY@kœE¢k¿a,ÐÂc@ß ‡#?"=£,€_‹‹Ð¨å‘_ 0Ìù˜q¼H—N?‘9²”zž“ý(è1g Q$Ò¹ÁÏ ìÿ¡©GzÌ:Ÿm£éúÕL¯ÿ$›>«gøï ÒAØà“Ôݰ•-Íî„…ìµPgâ6Ú%Ì%q`%è^Øi'T{€vÛç’0ðf“Þ“?ë¡ÕÄÅÌ|î1èÔ.Ô.³!§[ U0ä±fö/eòõœVX°Þ­ÿâŒãkeÔ¯@Únyâ .˜g@Þ‹×A”< {ßfÊ÷u׉ý˜þW»pòzyƒ—‰g û~¾³/›>ÓÂæƒ\ûFöç9a6ðI¤ØI4Ú£½ &UÏö (ÄÏ´x€)ŸB`/¨ïñ<^(¯,»pȰϵ`gšPãìVö{¸hh'‚ò[Ãþ*U ï€Ä•Ê=gxƒáCZhY×wêØr÷Ûçú°Œæ„Æž†*ãJA*CM{ â|o5š¨òn°G¼©{¢%jdï1t ¿ûÈ *!00úC#~Þ‹¯ÅS&$ùÞHfùRFlåa{øíd6(exX²[•4yeX9϶ò¼Ó>çÚ´qfaA¼›fó Ãð8òÚ]GNëîq&ÓŽ9ul¼:Ý´¤‘Çp;f‡Ûñ4ßÊJ´ý¿@–bÜ}$¡îÍ iµÊš¸~u @VÔ ä4+‘J9’ 7 "³@<Éô3<$ª(¸ðþ?6øÿç¬WÿOú.0ÇýSÕœ¦pݪ<º0‰ÚlÇŸR#Fò—£}QÜß•³Œ;ÂzÑ(~™Ô u»mfëàºÈ*_œ:f²™åßžö£~3@AG¶û†*wÑÁüѯlT¡$Ãâ°´ˆ]j&·;ØaQxKz0šc]#!>Z1€É›Õøv;Ь:"L½V´¸Ž®€JIðfß~ù¯MÿÎ Ìù6ï\K[+pz âáãµýéŸ5&Û =ÓÌAvk £‚_æÕy£x¯í0†¥½ïÚA>Ø#o×é+¾ÛƒicÌ yÔNº¾@ÈiQ‚NLe/1Œ¥Mvÿi4“T à2𗦣yœ™<ž8 ¾´eȃ­÷úZwÓpÕ_F^’mœ‚ö‚¾=?¡>›h7׌4KwŽI¿&º1»©Á+IßzÓlzSŸµåïÁ—<$n4edØú†Í`mÀ=4ʲògåÅהݮ$I 0Mð˜8ÂLÞkª5¦Éú?Íd™gó †Üדþ«.šo¾¶^U,ÐØmÁR¦G]šx¬hSl^Y¶¼¶N™€äúvúÕ¤Ö¢]f+È'Ê‚€X “à™MK´âœiÓPKW# ¶Øx~öoC  hȳt¤âî'í}ÔÆËö˜@ ú`žÇÄ”dŸó-ØJ· ³ /X¾»úl–噟-ÏÇæhé ±eçy€’<ãÜv×ã—pÉ ¼¶[þäzÈX5›Gœ¥½¼¥!Ñ~÷µt$¹Û>¹VEÂcO˜rrìÂfƒåUˆÍÓÕ·ZÁpzã3[¦®[Æ~3NdÕ¾ÀØó É*Oš¬úÓäaä¾OŒy–ç²~‚XXÕä^šn_mòªky2Ûò¨šåM$µ¿‘ 2M›W³uJƒí•o§2 m9‘]¾$Ó/¸Û-É–fe+·±<*ç[§hÛ·B ǯþÛ/Ú³,_ªØ¼,/“m»X¹N¶õˆ´r‘a¿å{h{"mÜ‚~»Œ ÛV9fÑËõøå\2ùf¹J ®DÔe þyMºLKGA½#mÞé6ÿP+w>@FXùϳõ*o듃Ÿ&™pZ°„öâ›~|aUн줖Ë<؈µø‘Ë"ZQƒÝ’E YäãC:!ÄM¡”'•1Ù=LÙ€Y$EÀÝAëI$Š4Bñ!Ÿ‹}üÍÜØ<m÷1ñ·’€|¤H;WfH>Å€é¿ ˜¼ÒL‚»»¬§KH'„||ØK ¤5ƒ® yÿ~*ŒéÔn3~pdAVè¢Ì ã†/³Ñ[WN?–ntËüÁLÄÉîtd›àg¾ïð^ÜgPu;’{Iíô€#£#‰œwÌLžIƒo¾I›Ù¾÷³‚­=êºÌŽ3›µ€®9Ì •âf쪧vø6v<^Í,H3.=Å/¾è°ìW·:>Ä .–‡<Àƒ•—£pÚCÍÙ;YFs¦Ÿ4 Õc¢¨ 4‡yµÛðÈÔy¨tf2ßГågÌ ›ëîÀ™KÑŸ|Ý¢…Ž{§25ïiœ6XZòmþ1ÿ”ÃSLç׺ÐæØ.ÛŒBö°’´g6K_iÁ£F0‚7¶ã¨ço¤ ÑwÑ“oØœPŸ…•[Ñjôb7XÉwkVÔ¸vÌ!3¡4,½2/ £`ô‹Ý $‹Î{§óÊQ8ÑœL~’’ /þ–ßM¡oÐ'T!ž®IÌ„‘f¿…˜IepàÔ`·^ÛmÚ,;)4‚!~ïÓ“o\tÞL ~n-EV£Ü{ÞÈT‚ ‹0Z£Ýå«S#vIçëRÓ²¬öƒDGÔ’#nà`&µ¼Ú×á{Ù ¸ým~µ­\ìµrjëÚÒ«”!$ýŒ©[”Iw4è&"ç3ƒyŽ¥-×ü-0òàcó0_NL üW\4ñ Q5[N¼ÇQ×Ãü’ç!«¡¸ÍW¾À{‹}Îóе4ÐVÃh‰¶@%Ðæ·Æ¦õ1ýÀ¥m‰°eU³mU®’-mZŽ$Ë·<'Ûæ}?äD•0dœ+ùãIÁ‚¡¶Í3Ëæbëlë_’+~ô„kÂÜ_¿*Õâ˜:FÃîˆêÔØ¾Ç˜b[ßAíÛ _­†¦ìîZ»÷˜v‹„¤F7’@ešìüÓ,Šò™3QN¥#VM3p£{iºs5dÁš† ›º³·QÙNì•aFë'èÿ«i—†–/‰Ûèz¶S›ú{7“cüE»n˜@fƒRqÆ{€mR}û¤5*KhüiÛ0ËŸºê[ŽòÙ§H ¨„?9„m8Éö·S;v‡iÛjtÁ¦˜zÔOÜL~”ƒÏYµ‡°†eËý¦úlÂ/ïÒ•S¸ý€¶Ê…S¸•‰<mkáÃÔj %†¬'0á¼Iïg~ùÑÆ¯)˜ ³Ïƒ/dû•$“ Ò%™p’ '•òäàO0DròÉÁŸ<|É$ˆtBˆ§ 3yœs3‚  ÜG\èC³ j Y€mv¬@ºÇYŽÔì?‹-ŠS¡´C {ßÑø‘Ë^bÈLJdÂ9°©Ü•‚þÁ±¨/CL?|–Ë *>Vèóaw³êô`4ë^l„Æ]¡ì.ðà¤eŒ 1 ûÜ&Àvæ:0ÉçžMš„"<ë;þ|Ž¿5 Á†®ÊµÒ µªõõ¼ÆH~¨Û Yu»ÓX»œaô¡nÚV39æ»;ÄΚ §7?÷ËìÌdú2„˜ä}n3ˆ]©¯ªu/}ÆÆ€('[•ÆršÙ | §f°¤ÊC´L[íàÞµ«˜J'Âמ04hÞ¢aEø}t`§[‡‚´™=y‹1  ·oK ™ü3[”¢ôäL^î<ŠQ¼ 3ì@aãþ¤µ(Ë»|Æ„-]y¹î(¾¡'¾“.›¼À?¥.Œò}™WÇbþ‹­i°ÐÎ-¿åwpÖ‹ïïJׄ F#’äè¢Ìä>2äU‚É sÜ7àõ÷Ð06ƒþ¡SýtJžfÀUˆ¼$Õ¹‘áô¦±tÉùÙ´·f"·öõ¼Ëgİ—nó~p&«¹Ë¨UšE´¢Ó’i†Ïl?ûŒZ¥ >zÆy,,8¢l¢õgn¶v/[n ˜ú­XDàøóîö²íQʬô7yänÁJœNé–kú8}a¤à—y‰´ ²dH>>TžsØÄÏõNoáz2æo5‰v¢µ}«@³‘á±â/9ñÚ7ȉ(ÜE7€ÉƒäÈŠ‘i@g€[ ˜íW’€å\`:£ai‚÷Ÿ5y]í]Žms?û\ÍÊZЇ¯S[ždS’€ü n°ië³Å0ùÙz´2y. xˆò¤RgË6`ÊiZÿýMü,Ø_­*þäµ÷ˆ1ËÅT"›bvïsñ09²"dÂavÀ£´ÏÿͲDKëQËëèñCèKÀŠ n¸×ÊH4ì®[{÷@& lð!ýSÀjäžõ¶_E@lƒ;¨³sCläÔÉßfúB m£ÖŒUËj©2M;àccn3 ˜R6C0Œ÷ž®qÈŒ¶€i[Sç˜L}ÒÚ—%4ù´‘Ù+Ÿ1dI]°¤“$GT$|ÿ Ç×Ãϧ`±“aÇŠ8Û®šÕT3¥§5)ßCSìa† ¶ý#ÅʰgßöƒÉAO“E YO­ô]ì ¹*S‡XfÓžNL%$ûŒ¡#Òò:ÜL a4ÌùË´WàÿE€iUTóL©î…­/0Ìc¬ÌEòûa‹âc û)õ…1ÍzðmlÏ¢N¶×†Ð—ëzæóT³iÄu½Õ Þk-{’ñ¨îìÅÉÛ¿m|@þÑ7ë9Ôîv&ã,Cú¾)êÀz¥´kÍβzÎXœx1º~wò8ÿ˜n2©îÌÀ ³>ê^)]‘>£r­äÌaÍàÆÆ‡§òßӴЦܸV2Í-%¶ËWå£f[¿°æbKß;#oð•ãŽâœE»H\Öh#¯±^.ß;‘\?8Ä.•¼}d:×ø¹hÝ«ˆ£Õnò%GF¿Êˆ*o!;¡ÕÍEëR²Ü`-sPÔ÷‰AP婃Þ~%!жþ\¯6î8ˆž>_{ó·vMï>WÒz–õòZâûÝƘRÖÜK ¿GKCfµR$P™ÜÁ¨ hí~â"oåÆqÉ.¿¤ÑÝylÜl¯ú;MÜ Ô„ˆ›ù:°—«NÉ*ºËŒ€®u,ʯÓ?òZ]çý¾ÖUf¬PÈhTÚôÏ+õù0wüTÊ3š®çÉt† OWj°Ë´}püd|$ƒÀ©,ØïÆX’Ã+ºµÀÖï§Bb*Ù%]}at„Ù’TíF/Y,ÉyDüoœ} ™p³£ÛeŽ` ˆ#šíÔf'µðÔ‚WB¾ctUð…||H¥<áþÇ9Zç&œª«Émz=S›u¤O³¡P ^lú˪=ÈÓQSYFsJõË"¶ò̬ó-j,fvô£, 57UIb͉ ¸ƒ>~C™DZ±ˆaôa uYN3FÓƒÔb9Í8J$qD“H”kÇ_ a¤ƹœ —ïÚÁÜh/ùü?þ@ÿ‰ªÁRñ¾Äq©¬N‰‹×ÿ›ô—Åqé ½©sºA:„t ý¥»ô¤¦‰®!?¤“*'DZ‡´T9u×÷⻿I÷‰ô†¾’~CúéC¤Ï‘~GGt“îÑŸâŽ+Ñü“8,}®·¥ãHΣ…j©Ò:#*])Í•ÒYMQGWI麤ëôƒ^§$Xé÷OqZúM˜:ýˆ4Èþ& ïÕ]ì+”)‰32yF:Œ.ËÑBµÔmÚ#8åŠ[I‡µNwK»lÞŸ#}gxö¨f‰ª6Ï’Òú]‡t³ô­-ÿk¤•è°*©±V‹w$n“Êè´ª¥tCó ÃÂb¹[â 齯³*%í0ùœÓ úDï‹)ü ¾–>ÒGÒy[Ö·HKѕֳš “8&é$ÒÛn_!ÍGçUR¯ê[ñ½4F/é‚J˜rþB:†éf=£ŸÄéý©ºU:‚´Õ|ߪ;Ä{û¤¡zO§UÆðh3ÒIÔQSt·Öéý¦‹ºÞÈÚ4ŒüìA\’–êAWEéw¤,סîú^7èœv©ºtC×>tV¥ô½º«ºv™÷ëL]ô;Òi´Zõ«3tüŠ4 i#:­2âiIû~6í§¹¦Ý?Ö‡*¡ :¡ Òe´G·és½­}ªª}ª*-´m>CëÃm³u9‡øS†Ç,ÿV>ÒÍÒYS_@:ƒtUÕ>ý¤g¤³hŸªj«îÐj5Ö{ªËr¤Sè7=¢KºÎÍ×?.bÚû$¦ü•è„*è}}bòßgÞ_Ôõ£—L›këû3š¢Ž†¶=HÇ pVÚ¡šÚ§ª:£Ò:¨[ gѺÏÈçJ[þ!ÓOt­ÓÝúMˆ/¤YzÔÈÅA4Tïéc}hdeŸŸæëa“ÏV¤SèFÓÏzÚðã rtY{t›‘ããF¶ÞÖç¦ý÷™ö“̸¡m†‡Ojšé»ëŒ¼Pó<ßðúý)]2ås^ú]˜:,6õ.h«CºYð—kLœ¢Ž&Ÿ¥FÞ6ëN#K?›qV댼íPM3.l3õÚ£Û¤ h£êé{u7í~̼¿¤ë¤¥–ïSÆXº7Z9=€‰ÀŒs:‚´ËŒ¿ëý®Lž‡MÝ9"é´Éïk½.m3ýín–v™^ª¥Åˆ’ž¾¡¯¤­è€nÕzS:‹‘“ƒFŽë!éœÛ´Ððõ¢®—öº6ªžŽè&Ó.GŒ,Ô-ú]hµë¬J™~pζÕa+;KmÛŸ¶ãÝq“·NcêºÃÈ…ŽX^\2ãáE]¯¿t—>ÔÇzD¿i±Ò>UÕy•ÔFÕÓ½Z©Oô¾™K?•žÔ4Ý«•â˜TN'ÅÒÝZ'^—(kwKpHÌuÏ5Ünÿ¯.Á/æÿÒõÌ3‘ÿ7„b Ó¿ ÉàŒÇÉú_΢AþFÆÒÅZÐŒå8íþ]úò‰§ý2[_©Ã‹ŒÃq6]{â9îk75æÑØÙ8=¯-Y«œÅ줟'ö6gbüÃ.Mßì˼˜ó#C«ð¡ÖØÝ‚ÿÀ³Lè1s uÇ‹¦'åÊ ¨|Ñ*c1›¨Ï,uÃéô<›~ŠÙ{cÝþ†øüݾßÝ5ékvÞËÆÏê_5ZdÆ1Ž„FòïÂÄ+Ç Ü~ž¾IC9Ð)šg®¦Nàég™¸óyöͬFõˆÝWŒ0é#7¼Î“=¦_1›Êû3)ëYÊ=—zÅïuR¶ñç°FŽ`/1tΚbL1ÀZ“»¯Hù5röiã«mõË>i6ذ6®±‰\wÅq« ¼®M”Ï9eäšØ«não¸±èQ¹¸Û#ןð¯C‚{.ðM¹ìz•c̙͒þ =³]e\ŽôqµaϵßB.LÝþ4•SŒ¼õODó„ß#Ït¨³}C\çG IDAT#bß„LˆN8È[©_A64g™‡µ.çI½–8®…={!2î~Y—¨Ánj³ºl¡;©–u€€Œ ÔÏßÌ"Zñ"ãXÁýl|·>ƒéÇ(^áˆûA/¾OêAfpß7+¸%-žÓ’¨º~?•Ä“m§Ó”UܦÊlOÇIÂ삾§ƒ×¹ƒ”éP¬aúïÒ0yåùÄVÉA‰#s%î¹Æô¿šú•–.›ÕÐ1ݨª©Ïõ¶xâoÒ>f´!Ût»Yå6+‚ËrtA%ôº¾c®œöNm6«®V#ð…‡v`ڥꪮ]fE_(<¯ÍêäÒ³Š8¢›ô—îÒõº(8Qˆï ÅoÒaU2+– fõsF¥µKÕM=9⎿T¤Œöa¾ÕºL°ô-4«¨/ô¦˜fãÏ•^ÖwÚª;Lš3˜ÒEô£žg%Øc➦éI³2škµ% ‘V›|çªnÕñ¼ÌÊsÕf|‹ô“¿ý¤gL]K\’¾ÓËfEwÆÔOÍ ðu}-~—x_j£¹:¨[Ìjö˜]¡]4«Æôƒcµex—¥ßMÛvÔý¨ç¥‹–æl¼YæûfÝ©R:«—4F§TÖ”±ÏÔë‚Jè=¡G5Koè+³Ê¾h´bºh´Y¿è qIz]_›ºœÄ«Ð zOCÍ·–K­Öâš g6g£¥}–ýmEÇt£féQ£i;bµ4ç Í_èMSïFs ÅfE{Q×k®Ú˜Õê|[çÅv•{ÉÖmŠ•ÙYH¿˜ôfÝih¼hµVã¤ß­–æ[Ë»þôø¶ÎÊÁ6Kß1»jÞæÖ^žQi³º>dWч¬ê’é{'UN—åèOÝc´gLþu½ÑžÈ®À×ÙüYÅ>\Ú¶+÷cöÝfÃ?ý³,ßeé³j1ü<¨[´Zõ—îri™tØÊåI«Q›ky:ßÔù’®ÓaUÒ'z_Gt“‘Í}&Ϫ`4Ç _~ÔónÍøY#Ç{t›ù~Öðá€n5|9‰K“uD7¹5]›mÛ2骥^Öwf|˜o´FgTÚ´÷:#¿ô¬)÷8:¨[Œöe¡©Û\µ1²µÙðcŸªš¼íôBµ4mû«åÅSï zÖô…ßM™Óô¤iÓ-çeóÿu4íyý©{LÛÿdytʶÉû¼Ðô«)êèj˪'í2ò±NwKŒ<]–cÚøO«©Úfûäq¶Ýì! Ûìx°Ò~;dã[YÔ)¯@;ô»M{Àæ·ÑæwWÛü¥»´Nwë˜ntÉË.U×.U×,=ªuº[u‹áéaÜÚÒóFÞŽ«¢áý+“Ç­ï°åž3ZõYzTƒôÑðžskjÏ«¤Nªœv¨¦6ªžêíÑmúC÷iŠ:ê{u×WzC÷éÝ¢ƒºKéA-ÕëúZé#½£Oõº¾ÖúE÷j¥*è„Ø,£‘ºC¢Ä ‰{%Ø'˜e¬DÌúÏá€bÀô/óžà˜þ”X-cêàÀ5ÐuJ“Þѧ.ÁÝ¡šš«6f½$qóߤUª®]š¦'u\]€é”Êêw= çõ£øË˜½Š¤=%£j?aÑÝ–N˜Ît»¶‰[ ¥û@ºKiŠ:jŸªºÓïz@oè+qܨC½ÒL“Ó¯ú]¸Óݦª õ±6wzÄTê¨)¦ƒ¦¹nÍY•ÒûúDü쎻¶i¡ZºÓ UÐVÝ¡Ïõ¶Qï>+Áoâ'é 2ƒK`ÚjT躀féQQΘª~ÖÓf"Xêbv˜ï½ NHpF>ÔÇ.ÀtV¥tF¥õ§î1f³_ À^­Æ¬XÀ¤KfBøC÷‰)Ò3úÉ€Ë=€i£ ÿÒ]ª j©…fÞjù±ÒÖᘉóëe}g@ñ /¡S*«_ô„nÑAÝ sfP·€é¬Jé°*iŒ^R ]Ð#úÍ  /¨„èVý ô²¾ÓÕt¦ÕÖŒuÙ˜nŽ«¢0€ †¶×õµ 0If0]¬‡ô¡>6âbÀ_†æ?u™Œ{Ôõ€­×q7`ÒR3XŸWIíÑm.ÀtX•´M·Àú‡`šbñ1Ýh€L`úËmvÖI;Á7“ç U0€´`’:hÞMQG`Ú¦ÛuV¥´Z]€é°*é°*™v;é˜ÎZ^òL‡ _´ÕÒqÚÊÀFKÛR[çßlúK6ýy“®0ý®4AϺLM:iM’¼“Ö¶évmÕ:¬Jð\°›5ýÔ-†nÚϪ”™¨-`š¥G >åž”èVCçAóü•Þ0qö`üƒ^0€ê¬wèV7`:nAÊi[÷³è= Õ£šežO[pUPóÆ\ªƒFv§¨£¡q4Ïj‚i÷•–ïÛ,/÷ Oõާ `:¤›¥ó€éœ¥E6ýÕÓjô­^5¤ ì2¼œ«6€ús¦ÎgTÚ 2[ÀqšÓN[S¢LÇUÑŒ‡¬l°ï ¦WL늦­º£`Ú¬;5Kê¤Êé¤Ê^Øþª]6ŸÍ¶_ÈÉK¯lþg¬yò”¡ó¢®×JݫͺS/ë;uÔ ÒúN/ëk½®ª§ßôˆÞÔzGŸêVÐ}úC-µP÷éݨcÅ€é`2ùoLOHÜð/ò#µÔBÑKš«6zS_èu}­;µÙL¸š˜¢åŸ+ x¥îÕ)•ÕݦºUKõ _% F¡ré#ì‹=ƒLQG•Ôyqw¡tå$6KÏj‚æëaý®´TêW=¦÷4T¥tVÜ[(ͳÆÿç+½áLûTUët·†ê=amÒ®ø÷Èåá ˜ô—Y?¦_Å·ù¿ ÕÓFMг.À´OUµQõ4Hˆãî¸-µÐhèNy&«ý¤ÄR›ç×`Qid ¶#fBÿP‹uLÑ{ªÍºÓ˜ VÛ ÕR-µPÜ-ݨcš¦'&Ħ0s‡¶Š×¥›uÈå ¸Ë=cí'ô‹:jŠ¡¥hùË â«ÕX·ê€Ö|3ÈYÀtN7è°*é;½,IßêUЭ.ÀtRå´G·é ½©'ô‹¦¨£ 0V%QiÒÍúN/@vأ쭆΂2tØ0ýaÑd¾Ûø¸*jŸªê'=cÀÈ7`ÒJ3©RYÒVz\;`ŸQi3`/µïþ2öI•Ó6ݮêäÒrlÓífßèLúÕ¤;©rF Ó6;!œs&0w¨¦Éç Ûwã„*èm}îL;TSé./ rB4_à|/ Ð.U7“–õÉ“ŒT`º,ÇðæÀ´Ðþ,`Ò131Ó .Àô§îÑzAŸëm7`:h®6ÛÉÏúM½¡¯´R÷j©4éL!XÀt\ ßÏÙúËhΨ´¡ã”ÑL¾ªoMyg @£— ŸOYqiC÷¸× :g@ÎV£Õ ³~Y®ŒN{¦ …šÉÚ˜ö`ü¬&˜qÄ0ýbÚôaÍ7ùœBi±K+vI×i‚ž•. wô©ñ² òW=fúå϶}–ÚüŽ[Y±b6¿¹jcúì!Ã]ª®sºÁÔáp!ÀtÈK6¯C–Þ}Úœ¸µž‡l¿8lÛé.ÍÏ•6éÖY™;mÚÿˆnÒy•Ô4=iœQCõžéQi`º ÿeÀtV¥´G·i–ÕÚ¯–Z¨OõŽÖénPíPM­VcÍU}­×õŽ>Õ¤¡zO/ë;=¨¥ºM{TS;Ì|6Å¢/$ž4 ºKÜeçD.ÚùÑZ˜ öb¦ÿÆtªƒ‚Ù­» ž[ü¯-n°ˆVto4–GöÎóØÜO›ó¨© œæ®œ+í:SS˜ÎSÜ7l•¹?Í#´c?WéLGùàD-·ƒ)Ñ+—e-ôºÃ'_tÊ™ÆQ"™¶þ)/ß*¥‚êÂDž£Íôæ.!×&ý §7/¬‡“ ŽÝᤉNo:ý©ž»×ÜgfC#Ö2‹ö¼¤I8Ià8Ùh-Ô¬³ÿj˜ÔöòÛ;^‡´ÎÌy‚m¯Õ¦cq&‚ÆÁ&êó¼Ó‹!ôõò£i¦„wâqfâÄÂb'”;¢·ãzIuž!§F ¯£ ¶5¯M_†@3øÄé@™4ˆùË}ò.švšYq¨ae>T<Ÿ®êC½[hÎ2ÑÊcãQ&Àë—s¼VTˆO¥·ïçæ®,ÌÉòßГ¯¿é‰¹´ür Ž¿_ÿywÐ(n3rž¤+ãyœ™¬hzŸ÷î¨4h²ÿOâ¨J7ÆR*;‹q¾/xñ¢‹ØX¹>éOUâA/¯«ZÚ3›úlâ鬩DÄ$º‘§It¡ZÔ>v6©éµó,0î<á$35ª#ZÜå½£0§~ÈnjЇ¡æ^¸v³ˆVŒŒy•äæ½vÒ…®?M­Ý»ØÔ´ž÷.·Ž; þݼ¤W9å·Ÿ¢vÖ¯3©”'“ ÕoÉ–Nwºù– åç‚d»‹­¼·ÏFvxI¯]WµÒvuEUZzlÀ:ÉðÔw¨B<Ó=îú‰#ÚõKðØv78ê2‚J»ëŸ²Ÿ 13ê1³{‡vÙsÁòê{ìk`w¶ùzmMôòÿ L?OSVN2>ä“H±Ô!2üK“V¥,Ù>%ÍMË¿õ—±óMš¦­`;µü>ÃÃßvg"î"ˆL‚³Ïš&-A7R7s+Aö8éí¡·³ž†ŒÌݸnU`­èÊxÊg_£Ô˜r»Nz…ü ‡ö’BA9çèSg(éžBPú ¢ kØtÁÅË8¢Í5»ó,&møÂL'Žh‚2ÎA%’&¬1o6­H—ÀŸÜÇ[dcî]̃üPÇÛ¿©@vü˹‚Á¯àc-øÛÍÓIR2¡mÒ|Âí¡|!gÈÅ*“Jy£*/¬º‡%µ2m’yÉ-,ªÜ’üÚ´ú EOèNÿ?£-Çð!Ÿ¶Ì#$é ¹×ãK­Y@O¾!8û,yøOÖЄõ4d{Û×ðòê^Gfx)Vùßkd1ÍÜŹœH*#iÁeMÛø]eçñ5†«ù\Ý\%ë:å™ÛÞ‚ ÓS¨Þ|77N ä†l8ûüpF÷Åà8kÍîq5ÿÎýÅ€é¿ ž²@3Ìó©ÿ>ýZP |Õá-¾MìùïÓ÷Ž1ө˦҉œk<^#Œ¡sT ®öqÑ·^{™OÁKÆÑ±l¿ÚžûÂÏ>tz0„¾¤põ³¬ 9øÓ…I\72Ÿ×j}K|ƒ[®zT€É¿6ß:Õx`Î Þå3sè•âÅ™¼ŸuzPrg}"†~åz«¿ÙÊî뉱Ñ/‘Yêoã=Ý~* Ø`. .B_T¾p"©÷Í^cä•óò…êŒgDÌdÖºry´^,f6x¬èVz€yð"ã¸5'ž/yË{p’ù(x ·çíd}Í5ᲓC÷Qc¹9%‘©troI·áö±;ñ ½Èš:)|uÝÝõ7Ð?ìcfÜÿÄ ¸32–ç˜èuçÝXºq£³‰o¢_gÓªEÚÙ™(æÔy¤HY}Â’º‘Ü b‘rÚ2õ+íÔ¦^þ–Ô~¨]ÀŠàûȪ}ƒWÙÃ}ÞÆ ¹!×{`ÓPbCï`^d¯<&ò{‰a“GƒÌ¡ YO,u\[»c©Ã»QŸ²É¿ž8àCzT.8æ¡?½¶g´.ÍðVo{Ѹ7â6s©íB>>Ô¸›ç˜èÕ†›êÖÃæ}>ÝÚñÄ÷f€å~G‘{ÈvV7€{ú?ÜÌ{·»ähÿ BlØTX“Z0#²&¦±,áÓ5}Ø@×MGCo*R§3­,gU¹à3®~”åÐÑîáE{AP÷ ˜"Wƒì§›¨ïÚó|ÂDâ©B¾æ‚fžHžÉ[|U >› ˜÷5adØ«.@VäžJ@žíqbFåÒÞG ¸v̘# ®éË'LzÚé0‘_Ùaåª8þán§ùTʃ/ìoX•ø «ùÿbúO'Ä‹® ,`­XB ªçï%>èúù "Œ±–Ì ›6mM a¼·à3zò SSèÃ0&Ñ…µ4bø|Å»f8J$khB"QEǰÿ^mI±Iîÿ*ÚËHì1>:-µÐ˜è>0& ®÷ñ£TUûô¡>Öz^5E캆r_2þQ¿è —ó§Ëlôàߤ++±Îø9½©/Œ¯Ñ>ymõ/’æ{é6íÑûúDßée}¢÷Í1?_%~wS§S*+]4êÞÕj¬‡5_¼qå#îÔf Õ{úQÏëS½#¦I°¸hÜߤÅzHÇt£Ž«¢Vê^³Å–'_ç‹Ò§zÇeß¿¤ëŒ¿ÒŸÞæS8,.Jïi¨þÐ}£—ÌÖÙùÞå–Ôy}¨5_k©ÔWzôõ#ü%Ioê c :gÔÞTB%tAt´e]2ÇœP£ ?nœY+ê¸`š¨*qÀøJý¦Gô‡î3ísÙ¦o)ñ¡ô’Æh—ªkµSé ÉîÖ'ÏÝ!ݬͺSëC³\Ò-:¨ô‚Ëï碮×P½§2:­çõ£¾ÒÆì°ÇøÞü¢'ôLl;^¨–úZ¯ŸÀ1nÿ¾Göó*©ÍºSð“¦éIãËtÒ˜ºë{}¬õ«3&%ë´YwйR ]ÐWzCß«»ë!}¤4AÏÇÜÃÖ„bM‡oësý¤gŒYá˜1aWEÍU±O:¢›tYŽ~Ó#ºM{´ZµR÷ÿœ³èyý¨Ò:£_ô„¾Öëª÷ô†¾ÒËúN|"­Ô½úM¨ž6êk½®¥zÐpÑ8 —ÐT9RYcƺlL'TA:aü‡N¨‚t —C´ŽYÓÐIã“Tî[½ªgô“Þѧª÷ÌÆ‰¯¤)ê¨#ºI§TVt«Ùº_à³u̞٘Ð/rtY%u^{t›á·õmãgë—'ì_i®Ú\2¦ gô“ë!VRYÑKš gië²q B¿è= uùôœÓ âg¹ŽJh©…â„ÝaÍN/iŒ17´”ÑiÝ®m:£ÒÚ¡šÆ„k„8¨[L8'éIgÌ‘wk9j`®ô¾>ÑݤîúÞøTÄ8¸_0iצ^çp_Qà7é2ÛíÀí¸o}ìtÙ|Ÿ«6Z¬‡ŒYð„1á}®·cü säÅíÚ&æsýY•ÒóúQ5E/iŒX-WEý¬§]¦æÅzÈMËq#3gTÚeÆß¥ê:¢›tV¥\²\°‰b‡jê{u×=k6Òœ‘§¶šñ ±V›ceªKž<éž3øÐþ?TâM‰Ÿ¬ßÒ§2›rÚHÔ4~¦ÅÇ ü?ê Þ':á4ø÷i+“À›5¾$†½8“Àqv^sÚ†¬g"Ïñí²×ˆ éš x¸ÚnV&Î p"®Î6çጳwåýC¨ÁnFñ ÓFÓƒÑпhú&¬á°ûÔ¡ŸËäâ•?ÓHc¾,\×ÔKôIý”*P°ÝüØ!åW&ÓÙèBIcZäS êÖ¯Hž[.PwÿV.©+¡žWÊgÁè”—éð"iêflådÛò,¡Åµ _ ßð]â~özžq‚ûYÁêjn­JSVѲŒÏ{¡ˆæ4’£ø“Ã]}ÝÛž{1‚j®[kMˆ&Žœ¬’^Ç…H†×¶÷°Œ“EMä2㘛:0Ãê©ýëµþïy¡©§éÉ7, 5ïò™×g_òP'‡&î£ ÖÓ†¬/Òw±öŠ}ʵýžD†Ð×{áÞÁ¡Zö×ó}a+¼¾÷g ~{/yi6\[÷¯b’:è6‰ÖÇûè•Ç1µör®k žÝ)¬"òëõœh>„%ž$3ª{‰¡ÁÑ;kRk÷.÷=“Yög}‘’jßHDöq²J2ž®4b-)„B:á$³‰údDÁDG)ì§ÁdàC>‘%&gÙþ%I 2›¨ÏQ"]që²Å5žÍ~ª±€Ö|›Ú“ÊgÑŒå´` ÑÄ‘‡/±Ô!…0vR‹Ô"†½”'•xªp”Hά1fÆl3$³÷ÅÆ5l?Ø`æ?.yß½ZìÃôÿ«Ð'gû?›JsA]àŒ³ˆÍÉ…œU>¼§!8Ί«§ß †OÆõórH!GΦñî58u®.ÅØ¶ßvúЕñ^>J$ÑŸ|õb/œ^WH;rñcáôÖ^~õÂ7Q}ünœ4pÚzÄÏÕ7+ÕŸ»ua~‚ûcé®p¬>އ;€"á3ÞåÎ%±ô`´—ŸJ?ó꼑ÓÍÆŸ ¹N híEk©^™8[ÀiZdlôïø ç¾ØU^ä­YÀ ßâ!톕Má‘ýL¥ö[îåì feÿqçþD‘}Ìõ ÏÏœÈH^órFîÌdêõÞó} ÂzÆ8/òôö©Œ§«+γ¹K[  ,ŒiÍ}=WQ™/gíf,g9Íøö•טÈsÜ>|'‹ZzÑÔ‰©ðæ»Á¯Ð}òXz1Â˹!ëù¨õ~‹kÏ33ŒþdzÍk°›Áôcm¹/výèåP^ƒÝ¬¥e’2è_þcŽ–¿ÉKÖÚ1‡ô¢_è ¶‡ÝŸÉã4c9ýÌlÚ{¸sÿ‡jaûXS·±—C¸âEOŤÀgØVÓKÒ-몱ŸÉÁO{•s?+x‘Ôe‹—ïÊršÑ'h( ø¯ºÖf;#yÍË)>€l² Ñ·’ËÐ\²ž¦¬¢)FõØŠEôg hॽYK#æÑ–ÔÀr^2’D„¹Nņ:Ä| _¾éz—^¡¨[2”O=E`ÚyëÂO[æÑ…ID‘Èð%îÀúßÄŸ»H ¨är,N?Ë€ÜL¿ÿ½s«ªÚÞÿg!!!¡™rH‰HI‰ÌLMÉŒÌã-2ï©™÷ÔL ÍÈÔLÍÔÌŒÐÉþ,¥ IDATÑI ‰‰ˆ‘ñûcî½Ø‹Z¿.§ï9Íçéyl³®s͵æ;Çxßw0ÄäÊšF(klž ݹ ~äéÑÇd"9Hg†² ?òL_œ¨¢[p1…AŽÐ‘:ìð1)dªpb¾Ý$2¦';i°ÓHwè@Bý‚êÓ€ S˜G÷©:)Õµî”â_tB7Uœ)yxSH¹wK’<{ºcshO6ê6ƒ-:Ɖ*„k“«TÄÐ4’¥øUÅŠ›¨hWµÍÂí¨GôoÝqçÛÀÇÄ ²Ó¤!’Y ØAûª/C½ÓÔ€%¬D}¸¶ÐÏ@FoðRÿ.´k­@‘9Òè Îåg±£·âp?þ½iRo ¸ì¾h_õ¸C½ÇTÚ_Ëq×ÛÈôîdŒ”UC>ØR¯Õ/Ö.e†éEÁdБ#ø’O>¾dL.ÔaG-ö8RMñpëLpœu f! ! \ôó¹SŠu¤ÁŠ·Àªì®ÁÒ ¡{ÊpÓSªŽTSŠ;n”áÈ9ÊiI=¶d¨;‘›'ÖU ¥âˆÇ•rŽÐ‘"¼$K>m *ˆ" çú³Ð9víÈÇ7Êð „ÌPE¤Y‰SÑO`Û=¤w­rYO³¿‡{SÒ NEzáU|š­žÓ·æ=\ÜaÓLc{ £ 7†“Àbèû98ÂÏ;Ud+ëý7ãM! K'A=¤xv§GC ßÚxPƒ‰D3¶~ U¶×0U°}mýL´]À¦a—|JI\^ ¿Ø¢¥64mƒq¿MPŠ;/8΢WåNÖ2D_ ‡“J¯)Ih5 umz½ÁH,œÓ¶p8:ˆ/)ÐuN´›Ã•ÒÁÄ'2rqd8påÎw6ð h´ëiÜ6])Ë^ÕºZq"bYÃ„Ñ ¹G@KU¼%Ù ÒÎk[øi–Åjeª²BдÆç" JšüTÝ*ƒúÉ—|æ:Má±”uÐ2éÛèÈE Lf¾ÁnáÞù{áÇ!Ð#™¬¢/GŒgRac„!„t&…ͧ—ä)»ÿxϯ/oå 1D麹¦Òe[:,„ùLæ_Ç3™Á ƒ"°-¹ÌL˜Î©o¶ ¿&ᤲ•¾¼´rLM™gPü“Ál¯i”ãJ8© f!Ô“„¡l0b0޳0ör¦-ÙÈÓ%Ëu¥‘#Õ,bî­ûw5÷¼>¯ê êô5iS˜ÇÕ½kÈw¸Åð{!Þ<œ°• ³²ÖÈÇ—(’ôô’¹¡#Ûé꼐ʿ‘®[iU\ ÏñºÓ°}»9¹V~_õØò>}ˆ'ÎðœriK«m%,b¼Õ=¼¼q<ïÕ7r·Ó›#t¤ 'ŽÐQßß”TâÌVúR‹N:ÏÇ—Ûœsô¾ÏÁŸ­ôUÇòi´¥(Ãú½{¯¶/Ÿììj¹çÒ–<üÈ ˜)ÍNh»«}möÆRư†' éÄtBØIOÖbýS˜Ç“Z”Uʬ]C®á&²ô4ÈØ+pÙI PáN?‡Í´Ž/jö÷Ð=#Õpìu &áÔ:\ ^XYhÄÏ—ñj!×઱‹‚”M³?άŽÑq±‹É¶`›û²[º§¦Rå{îI”o{‹î)×TžßœˆÀœ‚ªÃŽ^u;N¥ö7 %Nÿ”Ÿ7…¬pA¹{ËÆ}¯±D!=#â!“ 2 ¢õô"êÝ”ÿ×bt2ÿ}Z’ÎËÈFj±§Ç‹ZXާæZ!Þ¼WÖ—T™Ôo!“K[f1,=/?upbsîvÒ“¹ó¦ñî±~|YÀ÷õî4YkýÕ“÷?¶ÿËëDX¢j¯]!ç…oT –ËU|†ï”㪩^];ùR8£lê/½ß/Â{"œ³8ß\£ã÷E÷í/B¯ËoË­Êš¡‡|$d’ÿ¿)Ÿ\⺾Vöú÷ЍDõÅKã´‘ò„¬–ɧ¢W϶Úö¬’Þ_+?*Gø6MÏù±°ZYHŒ’eòŒ,‘{dŸpEÓíÞS}}N”ëíU²Æ°Í=ªüÍò¤¼)˳ò²\'g„{ÌÇØ,Ýd·,“Qò±Ü'Ë}²DžQõôƉÀ!SÂ×"7É)õû9“«®fêÓWÔ½“—d‰<#ãä%¹IN©24·ªçx·òªŒW•MÂw&'ü}ªÆÞz$J/ySFˆð¹oˆŒ’e²[ºÉ i#ŸËíÊüŒºö[å+yJ^—çd®ô—w”düU o—tרOÊÍò¼Ì”òª<%¯Ë!é$§¥•|&wÊ(Y&Èfi'_Êné&GåÙ-ÝäyZne ÑB~‘Ûä é.»„—Ô{ñ¢LRòQÒþ“r³ª¨þ¹ª ¹KºËné&¼'ò¼'=ä#]~þ°¼+ÏÊËÒN¾”å>ùBn“¤‡<,ïJyG½3GUŸµ–oT9‡W• ÄSòºpAÿ9™+Ⱥµß*Wäi™*³å]yX¹ÕïyO’ÓÒJV˪&˜˜\¾¿WNÏ""‡å.9 wëîà̹Q¾•qò’0Idµ‘{…×T9«Öòì–nʶÁTôvù\衾EoË£r@î–—dœ<'så=yHÈ'/É2%ïHyGúËyFÞ”Çå]yXFÉ2¹Z~’6rB½ˆð å÷ð„pT}ãÕÿ_øËæË"Lÿ4ë¶ø!ºYRø¥Ú.%Ü_„¶4ûß°cOàS{´i ]JÇon­íÑ\AÓvþêSô’ÄõâoJ^Æ`4´Á u4¦éšk]Òi}¬-ݤl¼Xó¶€6ëò¶ ­ë Ѷ^|»6.¹Ü9çˆ"¸¯­.¤+åLgϤ-U!õqÖa_òYÎh–- ¯ÁUÍX—·Ù6”Uܲ6š‰|;QE÷tšúø™Û²£éÖ>š t†Îë.à ÕÙÍ-Š$ÚÙ5o«0†¥:ÑØ² c%#Ya´&@¹ã‰c>“uÒ2À ãKé2ÆZïS÷ ‰Dóy{£®ùÝ>}u‚·ezÁƒ+ÉøtfG<9È5­Zˆ-G6^_;›æïqŸG¨NVi•"êšÔ$}`Ô¿{Õ¦[ë>ÓS…9Èì)Ó”’‘ hÆžcCu^–9µ›J8 ™ÈËnc­¶?Ô¡Q6nj¯†ŽÔ ßMŸeS ƒý%!ôf»á7ËTÀý;yÃð#O"YòÂ\êÔÿOœa|%Z¼§¢¼ôÈQIMÃЗln9}Ó›íº[ûêá± `k‚EtäˆnÕàA ÷$§5{<Û¦ÕLs F¨ÁìH¡y).îMâÀ­òÀ´MÀ+6hý@ÓÊMüÙÌ?mjü0ýM›¦eý*5ÝïŽ0V äõ7nçÂŒ&1ÛdÐvÒ¬ÿ“ˆ;2V…ò>ëȉ‚ÆÄóÃJÐjL¾OM8Jb‡ôq€ ¾¶Š¼Þøƒ{ÃдÍ_ë&`G¾…hZ•õ9L)­]š?/%OÔ¹ŽTó¯´’:´½ iµ×å‹öY€”¶@ÿ@#·iˆJ¼kñ· )‡Zõk¦Œ8ÁÉξœÝÖÄjw¶š-ˆtEbUxÿÕy£y…Féá }Kᜇú \×Gõµ|QÐ8Q{P±G¸ªªF’ë‹x*k[1ZWŒf9ã-âãøpž¸œpR é*xmäpî­Ù ™pÚÁ‹¯çùa0l^§€S.my9z<󙬇ߣHbÄ¢Ü9埮éÌkýFòšEîÏD:…fòáÞh‹ÞÀ|&ëÜ¡H’Y>‘|èÉNæ0MwïÈ3–YL§G2Q߯#G(Ä›8âÊ*Ã1šåLd!{ c )²¨e1–Ål †8â­Ô~³˜ŽEÎÚsÌ'ŽxÆò²!íÀq}Ï1‘.Ü(£[ð%ßnu †íô&˜ CÚnkI!BW™ÅúÒÁ¼‘:LO×¥ÊZ†J¸Á%Ý‹"=uR-ƒY‡ $0œ½„™&Ï™$Ú<@­[c) Љ¸k–t@}oR çÑÊMŒa©aŒgÚt"Ö”·¥_òÙž:¶Ðxâ }Z‡Sƒƒ& ñf#uâ°™ ¾ˆñTàbJ9ø3…yte~¼u ¦/âQéwPj6K‡ýZ—+I'„XÖèv%xp}°‰Œï~n7I2N%?ééÅeqqD‘„ ”ÛµäÑü (:)«ËV#/;Å»ò”žÞë7ct`ké‰q1÷tùrr<Ú«J¯6Ë8®8pU6×àQþâ&™Z YTá„yT⬧aËpc¸Ãk€Úw'÷ãT£î©Ð½5uŽ-ð¤˜:ZàUvÛÊ `£3f€Ó·á=uŸª¬K.äàÏ ‡ª?±gtnæò9\‚HkO-ÛèÃ*†’INê¶A <)f9£YÄxRˆàÙ‚¥dÜ<Õà e~‰‰Ì[Á- è„f š–þç&MÓ¬þkîïÖ“ûoûýâ á·mÿ¿œVýE©ÙÞÈ Åi¡FÂõZÐ2@›šVj½ïvøÎÖƒÓ«,¢¡Àn´‹XOI>ÊÏéν&ŠAÀsѺ6?àE|‘Bò_sO^H¤âzìÈ5r'n Ëã ±EÛ¢<“÷ñ@vë-€Y÷@«(ޤÀI­ˆsB8Uf"é ƒ¶´¶ QÑN£”w(hCA3áL™¢Àç~­£‘³mƒZa‰|Ô–£Æð_Ë~å´wè ID15a‹oà<·‘–Ë‘ñ6¼à2‹*’ àjkyqàdºÔ¤+âå-TÝ,³×i? ¾×ŠymðH^¨œ¥ïïOOÄ®á¶-Çá|2 «A |wØAnMÌãÀÞž=_çë˜ÐtfQ‹=Ó˜c j{SÈD²ŽÁø‘Ç5ÑwJ©ÅžxâËbƒä¿ÛXÎhriËõÙúù¢Hb+ÙFbØ`øH`qĈ×KªÆËìþmíÉ&’dOÈ–z‚Ȥ=Ù:ÇņƲ˜<üÏ"ƒÕG ,5å35®´qÏE o e4¯×®dãuR­-õØSK^†¨ÚqèÍvscC9øÓÓn‡þ¼Ý(Ã¥áGÝBÂì¨ãÛúD]‡©„óT¥¤Çè€%PäEi„2™ùD’L"ÑLaYH ØÐ GE61_òéÇC¤!:sP¤ÔbOñÄÇ–B:ùø2‘…TàbˆØÔa‡=µLc帲Åõ]ˆ`>^Á‘I>“A:!Ü2«1ÚÕ`¯Q†Çwe2 °¥Þ`éÐੱ˜±<­Î­Ñ$ªh“­\¬Á ÊÇ—JœõgSŽ+õNW(>a€âUà¢ÀµP£L,~ÒE=«J-ö¸RN>¾´'›£ 'Òm»P#¶ÔÓ€ CY­G·©ÖÕef@gnkœëU¦;uÁìO[æz=nü€E4`£‘­â%™EµØÓ‡÷‰aƒª1H%•8³“žú¡/ƒyé¥Ja™ŸSwŸriK2‘TâL9®8RM{²ù·M=Ž'ÓjM1ÀéR/¾ŽõS߯Ò&Q2·?wž´i†ÓdøÏ̘³5¿õ÷K¥ß²ý{ üC ·T¯CÓ’.îm ¡M&x5›À!wÝçÈj¿z€¾›èdY -Ðâ@óMÛÖ̽†)2tS'ñ§CІæ{±>joRB\^V!máÍžC‰Á†>=TeŸ`Ì6‚Å"M;Ød›®È478ì £Sk”òPßþ R9Ê4C®m8híÍÇtä¼–Ä÷î²Q^¦”žVŠd*àtÒÆ—£‹;òsE#Ñòвz´$`ŽòòYÇtféQ–`2è±(™ë+Ê`'¼á3ŒAÇ7Èš‘$óLï¥Ü!*&Sb3õŠLê ¯¬c }{RLÿŽ›¸cÓ1¾oχ¢ ðú°2®^^Í›Óc™P¶È@¦õ¢ˆlÄžZ†“`ˆ¹RÎ`ÖñŽÃÞ.ˆáÃ’hH)Ç•Œd! Q¥0ö²Ï6”*œ Ñ£`2Ï"²d2óõznNTEÃI  é|Y*ò2‚ÂI%ž8C´'„tÊp³Z!pÜ0‰šû§ 'Ö2ÄZ›ÇV;Äêп”؃/( áýÄ>ë—!ôÊ0F0:sGªI`¸nQŽ«îŸN®”ãH5Gìï4¤eãˆ7¸Œ‡“Ê2çÑŒf¹znÓØ1+@·Ñ‡" $]ó5DB{y§l !ÊV Ñ$¢ZYRŠ»!ݶ>Ì`Ñ$ÒzéÌ`ÖéîÞå¸2˜uIJFŸœ ð¡ÉVOªGCöÐOŠ™Ì|kÎéQ™'¦«HY©Ç :Èö's}ौÑAA1ž,b<=“U?5 7ØkØÐÀ¤ù5VöÚ¶ÓèÌAƹ6Öº;œÄZ7¦¢¬Óu‘Õ»H$šãàZwFžî”R‡ª7hºnKP’áð/=ÊSˆ·ÚëÜZPå| ؤ›’†ÔTÔË2ÝgC‘$Séw­N†/ÁCE—*ÁŽóúX6·á$àFNTáCÎTê†ÇÉDrœ‰f õgX‰3NTá@ ûŽ…]V°sgô¥ZìNTÙ‘ kÔ·rª‹¢>¤›æ" ùóÓÅ¢KßÌ¥£bÿ÷ÓÐÿܹ·DQQõe¼(ˆ… ÀÍYÆò¶ Œ¤.½//ÃP•ÃßÌ'Jû}éDÃ9-‘¯‡ûqᘭ9L¡ÀMhcAÓŽAN &;ˆK;CYàª"rzƒ*÷Ò¤¿$Ødñƒ«)âÔY%Û$¤7pSŠÇËîh#•Kº4 Ru.p¦¯+çÙ5Fö²TTŠý ÔaÇ»vý _òé“ÂõePãú-f$+ô©9êóTäJî©Iƒdà^0Ô vEÉ{/!?ÞžcH8PéG ¾ÕœøtHg¾.÷³ÌB|Ú·3sWN³RÓuäID1€MSO€w}ú2Éc>û2Ãød¯qLmbQ$1”UÎ 2q¤ša¬4\§7… f¥¸À›3•DÂ(÷åÜ罇Ÿ³ô¨Æ³ùK '•9LÓUN~äÑ›íØRO.m ѵ \È¥­ab«ÅjH&Ò œŠ&‘Œd’Ç|s~:«wðó¼|¹'Üáú$º¥î1Dǰ”žì¤oob–z›T"ÑdHžÍ­M2e„’f”ÃXÉÃñ[‰ …5IJdôXÃ}m§7#Y¡ƒM*%AnÈ$ˆíôfk @µo ð!Š$7–D[éK[r i¹||N‚!ªT‚‡îŒo6á¬À…2ÜøÐ#ŠOæ…áI1;é©—ü0·TÂYÁHF³{jYÅPžÐ†éé=óñ½(¢gíG†”«HT»]Íæðº ¥%0§\4µ§=Ù†òB¥¸ë}—ƒ?•N×RŠ;#YÁAÇ»Á]-rÌVä+éDfúÂ¥ 7ý{Pé¬l(쨣ŽÔà@çÚOõ±>†¥zÕ;‹pŽùµØÓczJ·i3G뜩¤N­Q îL½«>FCIã…3ð%Ÿ7ꆱ>ìÞÁ6ú‡»F6.êÊhRŒÛ«\pÜÊ"çLM£KÿÀGÓkþ/ôáüûj0"Q¿}¿|aÀmÕô[ΨÇB`YÑoد’ìù3úa ²-è\“ñöë|ùm*AFíV]–P)Õ [€×“/qÎ`d¹)â7åÇÚªîçBjó¤R§&ª£ØUÝLµwPƒoÚÇò|Μf¥Î"Ê]†@3¥ä…ŠÛ±+$’ͬ7x+q…ÂÝ8—b\IÊš­­ IDAT0øÎÞƒ%±c™É _è”»7Ë’ãèQ”ÂdæþfÊAqhz0¦„èûy›{ ãñòu„nu?YòL@¼, Jf=Aë¨§È -È€Rãþ¯ÍSZO³œì'E,4xe½U:„5ÄD~,g4Çè`%}7Œÿ: Í6èfŠÒnª”ÕGIY¼9Šj^Å›ÛRÆ03^ƒ…L¤#GH#Ôaìžžj=‚ÆêöˆáE-‚EŒ×v-ö²¦m ±t+ÛÓ¬•Æbؽ0ÂpïuرœÑŒ² ÑËM 8žED“hem±’a|—ࡃ•D‡H"Š}5aú6æûþ¡ÈRÜIs¾Çà-V†CXË­TÔà£\ÑòܯW-: ðáeÿñ c¥Ì%ÆþTúUÔø_uÉïÅSW±Ý6㓌ƅBwm…!½Þœ•‡y\áEQ ¨Û^ÁuC*õJÑ$êuÿ,í9šZ!”q}³ÇoÀ†Cƒ©Ã_òÙ_ÊѬŽ3ó˜·\84mæó¯R澌†Ë\ÔXŽ3#ÌrLE–Øü’÷§ŽKÊóÿèÿÖsýc+ð7µ#¸Q„«D`ý_h±úÏ;ö(>SU²9#Âû"ÜõG\óÏÂ#¦êÚŠÀÉKl{TxH”ܾÝ%ŽÙZÔ1»+;ëãœQRþ”œŸ%ÖÇ㉴’ÓJ¼Ï\é{—éû…A"š\ò‘²;8ÕÌqØaa÷`´màN‘Öòt‘ýê§Dx²Ñ‚n"¼#ÂÇÊZ€kÍÇÜ-pXºË.yF–È3²Dî“…gDxWõÏËò¬l–Gd³<"så9Ñä‚ð‰êã+åg¹A¾“VrZØoz_‰°_I×Ë yNæÊurFY/ð™ð“ÈyUž–WåÌœN‰<%¯ë’só-²K„ݦþýQ„Õ½NòŽô—CÒIÞ‘þÒ_Þ‘Q²L4¹ d<,ïÊrTZÉiuQòì'dµ°C„AJ’ÿªŒõ2HFÉ2é$‡Ô¶#D8lz®ÏšúòGQ{Î ;Dzɇò€| KäùHz( †ÖJ¦ÿ¢L’.²_®•å~Ù!­å™*³å}yP’÷„ODŽÊò‘ôÃr—|.·KùHfËTÙ-ÝäqySxU F(›‹»ä°\)?Ë3²Dž•—åyAŽÊºuÅ»ò°z¾³UŸõ’e’¼¨ŸwL^Qvëe¼,Ϫ>}Cd¬—ûäcY ä1yKYXðƒ<(ïˇÒKvÈýò¶<*7ËIi-ßÈjyBvK7™ äqyS&É‹ò¼Ì”¤‡Ü'‹ˆ“œ—+ä~Ù!|/2Sž—ýÒE¾Ûä^Qø:9#DS–‡Õÿ’Nò½\/Kä¹KËWr«|'7HùH¸Wä%'rFÉúÉz9#׉\@ýnzÖ_J;™+ÏÉ$yQ¾–[ätR«ü3¢þýƒ¨ç}‘/MöoˆÈOȇÒKDÔvò ò¥´“¥—|'7ȃò¾ ’õòŽô—^ò¡Ü-ä3¹SŽÊÂa‘¤¥œ6Â}" d‚œ‘ëä€Ü-OÉërBÚÈ!é¤ßÏ/ÒBä'äk¹EÎÊ5"ç‘e’Ü%‡å¼\!ßËõÂ"ÏËLé$‡ä+¹U䂲K$ëå=yHöÉ=r‹|m2ÞØ%Ýd·Ì”畽ÃL‘«å'ÃÂfeUBÑÇ%ïŠt“ÝÂO"\/Â7jÌ]+?ª÷òg‘–òƒpÖô>"§…û/mó‡Û ü¥ˆÝÿMÓÖýwÝP€Z­htUìN>híAÓ*/½]oS9›.ªTI}_U0¹n˜!Ž<´KPâ® ­¤ev9œˆ¸(G­›W*mrrÑÊÌ®ðk\†¦U› M[·Û¼ŽÓnU|ko¨h™¢Ó†ªäVÓæI1O.]Å]}³hê§èJ9È‹a“¹~»Ñ2⺠n”æË½Ï`£YÎíbË Žb†Rˆ&‘Û¤€[¼ò üªGÃ6*«ƒ°fÆK3m$+ˆ"É çö¦ 2q§”»,RMý{nâÑ ­Ò’ØDOvr׊,Ëü™ÑùU§&i Õ¦1‡7 ‡ø)Ó,¼,­k|žî”â@ ÎTâA‰ÎKY0r¢N oá`BµäB©är vâ­iƒÑ"¬¶w£Œõq1†ßž ]ÌsC•:Îì.nn3%^ç1™[$ɪI“®y„c4³´ä“9RÍ8·E e•žN²¥M;¨»Ž<¸ŠtBj8Üäµ2ÞO{ Þ‚'ÅÙ¿¦eñ$« NïækèbA庼ɰ:ÎÛCUä0ªnÛé­úߨÍúõ;SI쪎䊽õê|Žðry£»{ƒ ôråuÕð#S³ç± d2Ù´Ç… F³œ.iùÃS‚Hvèa$…ÛaLñרRH ç ‰#ž6àL%NTáDwUa]q¢J‡,ÁŒ/ùŒa©-•ž+GBÇèÀ"Ûq87œÕSiå¸L640’:,ÂK)M©¹xâp§”j©Ç–lôq~.ÍQ–f^ßÙ2gCZ×… îÅ ^¥ÈVÎ.wæTš7Ì‚3®jì[®ÙÒ»?wÞ»¤Jîbû=¿_Šgô¿ÌAÒ´ hZíeM ýñ¶ýµJ[ü_šVý7ïq/4­ÜÊëJ·ð-¥‰îþ{úÈY)ܲ/³].ȼ&€É ZÏKyG}ñÚ1r̤>ìo¡ªjáhkÛQœ϶wæÌWÃú†¡¥ð‹7Œ/´ö|<9œ¯ªÃ×ÙUÐjZ1L j”§—4U¹ø#‹U‰™/{p"Ëß2ă–Lr…ek‘9‰ðw„À{8FÖÏÌêŠFÄm¹Ãþ/åOäßY+YC¬Î…À&žwÅ]öYüXåÂwÙ6 ýàäJ_xMf K “D(iTáĺ8.TN*Çè “›Í“L{y(jîkF2ªp«ªÏýÈc ±’Åûµ}tÂk¶Q‡›0ÎZnq¨27#lW¨(—yµžÜRŽiþãL©+s(ÐTŽ+õØâ@ n”Q„—®Ä«À…L‚tБE ¶Ô“A°¨6`Céôc‹þ[8©<ë¹o ¹ßy'›ë0¡z‘$ƒ?Ó™E6íq¦’l¢[à8»j"YÈDËÜ`¥ŽªÇ– ÄàL¥•‰åvzOS˜ÇÓ€I#”íô&† ¼Ò7N—×ß»)$¢èÈýž³iψƒ †èG*ál †á$è r!á8ºig±M+rPå~:ð¹昦¶±£Ž»a˜ ¶ÆLŠ Ju¯eMÕ“¥¸«ˆZ½±¥7ƒ?ƒÊ7’l×Cçû'êÀæ¸0ŸÉTà‚KÆc…’F;çrðÇ“b ñÖûx,‹™eRãØRO&A:ù>rÚéÀÇ‹"ÆW½¬Ÿ»{<ºQ¦›6÷ë¯j©ÁÁpæç´“ž\íUÍU¡5Ü4  T¿Ø&nSçÃùëLýÛÕ§6@$¥L“5-õ¯Lÿ´¿xò1Kð«Ñ´5¿4í¼¬SõœÜ,Î_ð—Ÿÿò׌ˆ1å£yƒ¦YËà$x(C`hcpÑ´=¿ã:‚.¿MÈ,”Ûv}cÄI[ŒŠ894FÞDü¬d´š¶]O•ŠôD6ìl²M*š–‰dƒt…_´rάhB<¼,¨Fá+¯¶œ8h|Æ_ ÍQÞYª1{2hZš–¥üºA´Z. · ‘öv Q©ÀsÙÊëƒט¤jÿ¹ÀþˆPÞIi$7·ñÍåÆÀvWD0sÛ ]jmN­MušÃí¹Ö§ ádŽ ¯ký˜š2O'a;PC{±¥žct0( ƒÉÀ‡26ØÜÓ5›c TªÄ¢‹×oÌs;ç[E[Þ°ÊÖ²VG°¦=ÙÔcË6úL$›@[ryhá6ýÌàd4Ë©slaõ0ƒnÊTú³';)Æ'ªØB?"HÑS¨Ó˜C*á„’F>†kð¡GªõwÁÒÝ½Âæ:C4×ráPŽ+ÔЛíâÍXë¶{èŠ7…ØSK-öœÏ°ÓisíBºú.|šÕ™CÁÁ|6'ïëÜ•qe5J™[…1"]ÐÜ‘ìдãÿ¦ÿÚ—Ä bÿ¯Ïð^ìÁb%ú÷ìï@D\á"•¸·kìQþI¦E×_­õ +A&ÿ÷Ý©3¥ ›#"žÈHàÊ­|?Òæh R¤,~tuáÛyž—8WgD¼šùÝAÙ*tò/±ï1åueø=Eeþp~4Ÿ74!eU«´Ó¤´…¤a}ÐT˜iºøŒS†%³¬Ë||šÑ™­ô5¤ÇÎ68“H4oÅXEG$8ŽR±™ª¢,)˳ KI"ÊJq”N»2¬•‹Ç àç:C”gBÍ"&,^tñ\®"]"ž°,MßTLæé>Ëuß¡RÜõR(Õ8êàð Y6¾1—»•¾tsÜà fX©šª N5xÃZ8·ÁÑ |vþRÆ%/n¶@ëæô¬9˜—"'ö1§š+.ƒ?i„r"×8ñÏc #2 iÎ=t¥) c¥Á?k(ÆSâ6µ, àÔÜW»³#Qç̤“²hÒ,Õ’%x¨(ÕU圮óR÷ÝdÆ-Ãwó¬–uØ5Ž«,8¹Å—"¼x”Mt/M¥ÖçJ½˜îSFscËEƒ%P|?¼í|°2m­Ç–\ÚõØêý]ƒ•Nײ†XºN¥{=BY†{èj°°R–êP‹‡ÀÏZ)§×xQ#ß÷Å@… øƒî‡ïU{®BE¥§+o;Ù$Ôþ©Ç?Åwÿž÷pJ¸E”jêúßsœ]J%t“7\¾¨îŸw?Ÿ+%oÿ=ûº›©¯[ýšíO*•ÙSJ±ö—_ïU&ÕÑf^TÏõâ×ú–Ày¹Ü뀪Ðy‘¿}!¬aµYåöU“¿‹*V»CTaåAJe×ü±>mæ··…ÇLJ¹·E˜)Bxóò}Ѥ”“zë”Iøœ*|³œ”§åyNæ*…Îë¦ýî2îaRëqB¸ÙTúŒR*=!«åayWî”ÏÔqÏ(EÏý²C”÷¥|©T;š:Ï­ò•Ü&_(©‹¸ATß½+ÂI¥nQÇ%ËäyA)g«b¶WÈy¹A¾“Çä-U¼øœR ±¯Q‘Æw"÷È>i'_Êl™*³eªº·E=ë7D¸OÞh,Z=פŒäºž”éy™© ÷šúó~Ù!7ˆ*¬}‹|­`DøZäayWž–WäyANÊÍò©üK’÷d‰<#;ä~yBVËK2Nî£JBSe©ûë&»e’¼(×ÈYaŸÈ›ò¸¼-Ê“ò†ô’…ªx ùE¸F"~Q&ÉK2N^“KÙ¯Šþþ Æåãò¦L•Ù²LF)…Õ‹¦‚Î_‹Lò¤¼!ÊûÂLu7ËIyEž–wåa¹[ȳò²Ü,'å~Ù!oË£òŒ,Qã÷zU¨÷´´RJ¿Ÿ•²ë9+oÈ“r…œ× –»äŒ\'ïÉCBwU¼z¿t‘]Ò]®’sßɃò¾œ’›ä+¹UèÑXÌø#é!ð®p§È2%¯ËSBžù@ÏäN¹E¾fŠœ62AûTQæór…|-·ÈT™-r‘”"oLŸåJùI®––òƒÜ!GeŸÜ£út¶È+ò´,“Qò‚¼ /Ê$á°ê—ýÒENH¹NÎÈ]rXNK+áGUP÷¨Ü!;ä~y^fʇÒKNÊÍrN®’w¤¿L’åt’CÒIå³"û䡇R³=#K„óJ…j.¼}ƒ|'Èj|½oRèîWEÅ9§Tʺ’v³EÁ÷ÃJ‘ʾFÕ1w˜ŠÈ³Oà Ó¶‡öýS|÷²Å€6´Pдßé1q4ZOÐ\øSŒ½.ß|ÿþ)QgÐe_û(õ™¦ýç.8´¨Ëÿ4-û9ß\?¥à‹Mkfù×x+Dq¾lÿ?Ï1 x~H³¥x.Û†c¥¤3·ÃV(îÊŒ&hÓVíÓʺ½)ä!¯m´p±V…uàw4k¶o •_±âÑ4 yÖ$øêO³§M³Rt<â`©½Þ½¬™Ds»Na„¬ä¦¡¦±øÀPëTóCͧ‚ïg'CY¥sYî»×˜:¹H ±7Û‰"IO…ù’O4‰D ˆ ´t)¿h.ãÚÐÆ0B™Š7ck‘jº¸=Ϻ.f”ì5˜A=÷Ûog¦ïtcÊtz‘$ë.ÓææFËm ƒE¤Ã¢…±—T­”{–­uJ![èט*³xÆz³à!:RÍÝâÁGÖëÏ)~‘  c%·Oÿïn z À±æœ*ÂJ®!– ÓÒc†gû\ ÑT-‰(Ý‹j½sL³Åƒ-‹[òÚf1}NJ405yƒY×| ãµ’-BÔûu­C¥*¬‹®žÓ´ ¸ý"RGÓ;ÿ´Óß6eä¥ #·¾Î°Àm)hã¹íòljPé—"à{‹JÑ€I1háÍÈÃÿ”ûiÏ%¿€¿Ðh³âêd]¼¯SM}ý­EB¼•šKsÛû iÖ)º_SvæéËSy•þµFEŸ=hZq“kŒˆ-ÆÚ&ÍÝSÔ%þ€ÄOVJÅÐx»-Ü2¤'Ö†–30±ƒ¦c7süÈ:S]ÁARíhà+w´DÐ"iöùIH8 %#±6è<Ó0¸zJ5ß”ú°,6Ž+¦è¦–ÞòXÔ:î•ÅkªWÀWÇó-ë9¬òfR¬!UI2ÎT’ƒ?)D 4}(À–z+^öpEL½:‡Å³:¼=ˆWfæ1#rÃR†±’ctà³J5³¶ö.¤è&ê±å— {==çI1©„ó|ÝÃ1¢IäÑ= áE¨âÉûM€ï °>>¢ÔlMM:ýÈÓ'³L‚¸­óq²ßF.,+‹#›ö$meŽØHD’ÌPV¡U@Ëuå|éÀÇ~ál¥¯ž–,Å]OÝ8QÅLßé<ï>‹‘¬E~>BGŠñ¤{BI£Û “íRT’ŽááF…n%Τ=µ†I?_)ÙJWöljpÀ‘jžÙ°”%óÇPŽ+ ™Ètfñ ývƲX†êU±ãYL§ '¶Ó›±,6€‰-ôãç ®:s*œTjw†º×:›M†J-‰D#¹Ðj`±¡ŒŒù™{S1*zŒࣄ&]€¹”K5ŽP¬êCÚS‹+å†ún lf1]ç­c°!™¯îü^ Ôè®â*SÖVWfÌA:ë|©, '/Š8NWØÖëǪÄYõØÒªw1¸'ª}›[£š‡U¸é›û@•J함·™@ÔýßjÊë©D.Tü˜þ'ÁÓbhºÂU[lh®¿´Ø*B­%/%x}ˆ";ýÙ iè¯";ÿé¤K؈ø •À¹-Û7ÿâI)ŠßtÌ´DúËAµ=’ ²رÕâzKÑ´Ì&Ûv4Ößs>Å!š‚Ñú ´&ë…϶#cÇ›DœævFëÇeU "6Ètà#è`ðn ŠŽj…Í쉬19¢§WŸ-ר lýøÁŽÀãÞkyhï6Åm²ÄšWÚÀµœ²ãý }x¿´a¢ !{jù ¾·>á»PA{©Ç–ok<9Sçjˆ|ÐÑÌŠQŽùmlx}þp’‰4p¡BHg’ó|+gìgЙƒú¤•‡mìr)Ç•ƒt6«ï³–.’M‹ƒu–³.¼f ˱øL{W>*êI:!d¨GÞhƹ.:ú“ò®zµ)Ìc}æ`¶ÐL‚ô~mÀ†Zì‰aƒ®t©e<‹Ÿ*N–øòsšgÙK 7ðŠ@˜Ÿk;ÎÄ•r^©cå‚îDå¸ 5ƒâeÓžb< Q›˜›7 Äð¸Gã"qƒydÞV&3o uNÎPV±,2Ž2Ü `#‰(fÛNc2óñ¤˜˜Â< ñæT‘7 øUˆáñ̵l§7žS†IDq‹m>64Pˆ7«ʧZƒN’v¡WÊ™ÏdÜ(£Wæ1…lÚS‹=~äÑ©(*¨ÃN'…'9õ¢ÁK3€+»ªóºâÍ2Jq'ž8ê°£-¹Lgd1”Uúb ›ö¤¡GŽüÉ¡ì©ÕÇÆh–ë`©o:sPÞUãhXLø’¯{¡£®Ð3¿7³˜ÞèO5Tñ·˜†*¬ë‚â0Ýì–Ÿ¯œ‹}Aõ 6¯ïcwï9¨"Lw6É#ÎÆÀ‡¢ »5Üe›…e|\m|anqÈçJ»Z¨ƒ eÇs3'³ÐÏ<¬ auû¡¼\>ÞPÀ·+{ˆ"‰r\ €Á†ÝÛ¦qñÇ‘jŠð¢O½†X)´ÉÍ… v¾\.À›#’#UÄà€ÖQü\eSC÷¶):H n·Ëæýš>üœä@Ë rÓçg ã.&‰(ô¹SŠ-õäãK4‰pœÖ‹ yxùVîóØÃÔsÚU©ûó$É Õ³¬ÈÔ”@,f,ˆavétC@PJ­u Æ28Ž#Õ:˜hÀ†%[Æ’E Oø­ÑDN,b<›kpç”#†b¿…x39¼‘çìs³šzžgÞöuqY°÷ýcÝ¿Öý]k}õnÑGáÔC¹9ÓØ IDAT¡½¡Ûä:P±‹½ò87cðw1•­ 6kòóV/ĸ”ÿ¼  ™ GîÂV¨‚Þk ¥ŽòAN<½ú©RpÍ’Õμd ~8cYîD›’)$•|z—ÕHgF”²oN(OnÏqëo¡ì$ÝYÖEƒw’Ãj'Ë·ƒdtýiÁßI5åc^J©œßYàöÝ<¦“Œ^ŠH¢Í!çèK:;È\LeSyû&/³‚J¡ž&)'†#&vpDDøÀ™›J9=³ÌuÉmÎ8Ç6ýžÍ§«Ýäð”,~ 3Üï ÓËÁ_eÂݧüÂròÿH6ÿÛÙþ³òk>,ýuë¬ÿAŰ/"™¿A=^È<à/EJÊ×í;Ùª çÿ.ýu"«ëré./î!e«üOו#ABô¦þêò ÞÜÞ5t]j”HÔî÷*£Þ¼=¡/ïÜ™ìN²wYÌOGóýrw'CjЪBÜS[‚8Ê_¼Ø mðÞÜDž¨Õ…ÄñìK u ñwø³Ø•¿|RÙÄ`^è؃lºé¯ø)ùèÇø.Ç—ã3yi‰åÕÀæ“oWäòÈp²H;žÏ²#{¨e°os(ôZÅ»SÙI:oVôã‡%>Îl÷Îg%¼˜ÈNÒÙ?2ÄÉíxj c£º0ÛÛVî‘~§ŠH–1ž'ór°QÉQ@ ו¬ì»5yü9g,ìêmì™z3ƒ¸Á{ ÌroÃ#kÆÃý«aó5„s\n£Sùi& KY[¨è®ŒtCHd‘¬Uβ5Œ¤œʈU%Ût,$Ù‰NÞß1¥ÛdÛWïYÃV89Á–0±‹Y`,ËÝ(&î*šå¦´v!¢´1)ÌcºÛ¼u{<ïTµ¡Î€{z\ï¿òf÷;­ÀM¿O4áæO‰p‰À;?¯¬ DøÂü¼"Â"œú_.¿#MèõY"°ÿW˜—&œýtøâp}<öë×qš ïÄAЕ¶€>&4øšxø§õás¥"¸Ã$¥=ê'|{©¡.xB„Í n9B~ÓåC9V¾ÖÐøëÌwg˜$·'jba{’a>é%ßhù׿]Ë„I_e’~­ E”¾‚çµ>î6ý0‰”áS¥¹X„ÇE“ŠZ"gË;r•<)’çäJY''˧r´Ëåyé-_HoùBΗ7ÄÁr†| ÇË~ õÞçúݵò˜œ û„‡ÌÚ>ß´©—é_ |ê.³[ ­Ä;"GËM„;Nž•^ò&&þR_(¯i_ùAxI“ ß&wÉ:¹Ò™ UDäJY'wÉmš$ùCî³Ï~“˜ùMMØ{‚쓳å¹CîKäe9GÞ–kå19C>#ä'ÃÅòŠŒ“‡å\yKn”ûåRyQúÈgr†| "JÍp‹Ü-ÈëJ7ð­7›„ÏGiØcä[9KÞÓ±yOÎ’o¤—üSn—óå ù\NùáJMý±œ*ŸÊÉr¯Ü$ÿ”Û5Yï>^ù“<'—É ""rƒ< /Ë%ò°Œ“kå1yA.“‡äz.OÉåò¼&’þHäy¹\ž«5QôSJóp®¼%œ¦‰Š‡ËSrš|$çÊ[r¼ì—SäáU¥'KoÑ=’£Ì9t¯‘ù™®s£~[j—ߦÿöçî$uèî†Éú'X”àN8¦¢«BÃÉÿ«Ÿ(àoÁ&ïگĂv}Ö°sþÉ-kÓa¾WeíüùEw Tšž_‘ˆ5 ¬¡ü¼ô@ÀÊ+úðüøº<ÿ…Õ×k?ûÖÖîäRг/ÕºuL=¢o¸›0mˆÆÜÃú›Ñõ× ”¸…t;}\Àò`?>9¤ŠPê7žíqìeø„µ\’±¶«$k€Sà†P òÇe6xeˆ[ÚsâmPÜ¥ÞôÎì:–±”1yd“ëló_c×ã ºëfŽì¯ Qs 0×ät>2¦C¹ ¦±‹©, ?;º”p„¤snÛ§|Üžƒ!ŒÄ‚åêé«À6þ&ݱžˆÈéŠÿ^&GJ”ûïFrOæ4µDz.t Sc%X»áÆØEN ûLSXÈqå&§C=7æ.²YÊÝesoÈTçÜšÂB7bNûc—[$U<ãâe¸váJΡ&´0j¹°Üݱчvg^CÀ-¹²µ@Íç™û:õÿm†ß¦ÿ妕8¼@ê ãéà–÷¨Ÿ>=f‘ïÉLG*]BçŽnåˆíšäYÚ“_Œ¶¶¯{@½òUÅ&½kÈþOGséå£RûþˆeµÿƦºŸ‘ĸw:–Uqøu”ƒL¦kt§C±±”1|ðž­ÿ~ÀµaX‘?Ö‡p¥"¸“®9÷úÄaYíXVe÷ßnCS­ä æl»y¬ðæ#ÿX¾ÙèþáFàÉBsø9žw·ÀdøÖªã»A~îÊP`íïžÎ³¾Æ˜rítVçD* AµÍäåïîLâ©‘ü»f°Óãc2²ÆRF0 NÇð£êøp{_ÕwaÖ~¼É}ü/ñßÁð;×rþ Ý0 U\þ¢Š«•¤´#2OM‘’ßmóãó"w÷7V¦:ƒQ^ïLƒJ8b›úÍgÿ²&SM„Ó|æpV¢‘êI¦c}›°JáŒy{9&¸†¯óËx¡ÝeR,#–WÊûóN[²M§Ýíä°zµ>ƒb)!Áñ×—=DSÑEð¢“qþË8þn’)t*öúó~ÿb(çˆ=n&ÇyLçžÍÓI¤ØMaÞ’ËíV6¯ä¹œÿ[ñc* x£.•û&;áÞ9›Vü8«ÃYg1‰Ü¶a.ÿUN'éb!Sƒy2Ùî–Ûn~|¥º?ç­*pçz2õ7@õìÏa3ƒ¨"’Vüxsu?§ã|ÍtàM þ„tì'…îX>›m ›\OE"Å„PO,‘9” lb0·Žv:}§±ËMÆW°Å-JÒÄ–ÒŽëG8}ÊJW¯ôfç»_.Ãiýs¬ƒïƒÌúOŠAƒ•>ûíöÏߦÿ¸‚óŸw¬åÆ8upíÏa+="áH…Ú³=r<þ¡W©‘P¯·ÖÅ6u~ ði2V1Ê e5ü§Ümà²É¤"±0S7±ւ•z˜u8s–yÔWt2ô8ž9ÿqnØ­H´ó.hYXF!ùñ\zR²¸½ÚÍßEÇ`£)ßÙŒ{Ô&‡ï$/­f¬ž.†OÌÍü$øKV‡T¾¤¸w%ÜQ Ï™· ¨Ø ô*>¸‚+BQ:Bà¡ø¶z™ý¦'"ÅÜ©¯Ú€p0Ë[ÿnWÒcÑY:¹LÇÅM³ uXß ÏÎÚå ¤‰N¼8%²Òñ N )çæd>Ûév8Õƺܼ²Å=ºïÚ±+¹$v‡! R9œ= ËêtÊQ¨âä oø¦!bt¼³-@¯$‡/›ÂønŒüÛŸµŒ`xi.·Ï˜ã¡7æ»!d‹&u}j$<«r™olLu;€k s*`>´kNBo˜û¾Þ—7–t]¨;I§ŒX7dÎþÔípòÛ¦Y¡ W0†/kÂ8oËΑ¤x¸ÿZ†K ã2–ÑHwr'cXA‘<:Ö¤q³¢0Žðú- äæŠ°' B=!ʯ¯‚ ØÀPÞ K„ÅJ?зúwí… ,%”:šäÞ†i4ÄCc'RL"1”sBž¢`MªR]ãYÆÞÀ3ø¢,\ý¥:5ZîÆ±‹X̤®Ä ¨òö͘@ Iæ~ )"ÉÍl¨&‚kYI1‰´áK%n¼R·•Ì…6UZ«‰`  §†‘¬¡‰@>îŒáÔ©:¯šqr-ãÓ‚¡»²‘ÓæšýbÛ¯~nü®0ýoG=¼^šÆ£ƒÆòÂ&÷=ÂV:ðæ”¾.„­wZ-áÔðrE&,5yäŠõ†þ ýY·r„ä5¹«ø£ìâˆQ6²Ûi`…á4ÏÊ"MØì–ú-À(‹ÀÁNoíßt8qPï%'Â`–"‹™Ä6Êõlá‘ø±$Ù4Íã7pqpžÊ,>©‰Ö¨Âªh|¸;ŽZk£³ ÍÒ«ái²y¶t(›ÜÅú¹æ!”K•´àO þn(Í{õ‰œä jÂìÇn\~Õ#xpÆ$Þ_Ÿ€­nfÉ9Ìä¹yCø´*ŠlrݪELæÆ„E,a"¡ÔQM,žŒD+úêPj&°”÷W%péæm¼œEͬ&G×á5ѵâ×Å!>ŸTHW~¾+—çªâiSV%¨¾ g-#hÃjp£p˜Jýi!æ1UŒ¢?ú²‡ûVL!‹­d“K$U¬a$¹d³™A¼YÞ\²‰ o:œJnÍä“Ê"&s^‚«]1”3‘%Î:_åÁi3^çÌQŒÂ ËKÓœƒ œ0àw…éÿž‚3¢+ÒÖt=0V™‹Ì-}¯kS:~Dç.ÚÃEÕ;áóþÝ’ùý$Ä%¬5FËçH~´b­ì¡ãSR,°,ñÅZqhE÷·AÙ6Æ;•X‘Æ,#J^)žïlú‰kd$"1pß e¨ïš¸—k†(YkÄÔQ²xÒן„eÕÿxûÊ€»kÁžÓtˆQœ æ1t§o.SsV,îî?g&ÈZày[Ýoµ¾ðÏ\NÝã®àñÚ ¬íÆ\û×!&­M 2Ûp±Õ ÁB™Š€¼:;ƒC³øÄ©E%íøpT@ {`'0¾]àŠÀ®V…¯Ÿ.ÑJqìåì¢"N‘*œùŒÏMï:Ï/¬Blg÷·m° 'G›½)Ž]Ö>ðÖªžõʧ{¢x°sR—(´š¹hÄNF±JÃûWÀùI»¡M] v+âÝH* s *èj<½ ªñ©ì¦ou¦°®s suÀjRÉwSÐÏê#9)¤&Bo_÷ÛÂ[“RTQ™½†5;‘»Í â‘ñãÁZÆM_Æù‘ê›TJ^o6hÔìXû~ôë]ÜW˜þ/)cµtÍõ?Ùž™À©[õ†9KÙ–ÿ{á`¤ ÍŽ=h8Üï2ÕÓo/0(ØÚñ¼RZˆˆÖ÷˜¡ yͬm~pR®°Näoòˆ\'ÊŸåY¹Wn’ä9SÞ—Sä-ã‘3å}mçÉFfï)-†ˆŸh{xI„ïD®“G…ƒ"ðµÀkº/¿%¢aõw‰À3½Jóp³Ü#ÿ–+ä).iÊx-OÏÓ›‡qwùt~)¡vE,cTM%Q’Ìb&©Ól&ðÎK1ðr4gd+Î?¥ì%Ž·¦öe™Ì"vПm `%£YÀTR( ˜•Ãfàë‘zè¾Ç?†-ä!š㇠o>LV1Š¥L`&sÈ%›ùLc"K”ïfš®åš‘XkáÌ’RðWgÊRâ¹Îd¬å`µ©M|!S˜ÀRF³k7¢½]„­]8}é7–7'¥0ù¤P@y¤±‹þìàBÙÅiåšB£§~³¹“;ñ§…“¦×0‹Ù,f¹dsmÀJRÉçý¢^Ûëî×á`9¾jÌ–0‘…La9c¹rw.ݨ~#ó5ÜñLd [ÉâÆ‰‹ÔѹL•0«ÆðœŒãHIäñrf'¿yí|î‘W >L€'“á¾ÁXS›p ÖàÙ5ʉd¬ŽñÑÿ’¾; ÞÉKæÝÎ$§Y'†r"¨&™Bî‘mð¼íT Çmk„ÙpFá^ul%'ÝV‹úü|]äJ©ìoƒÞI*WsÉ:j|›²8ƒ«–®áß.EÄž«Âcùîù’þ·]¹¢|áÚè•Nó\ï1µ|D,”Áñz¸~TË%¡;œ|C>´s~În•ã»éX»€·Òµ¾+‡©2´Éì#ÿZ‰Lq¥ÆŒé ˼ù|©KI<ëÏ[1)—n¥†pþY'/Q{R5ìâ®l¡,Óׯ$„zÇö¥˜g”Ûh ^yŒœJÏ¿`²FÀÕÎsECœéJF³’XÊœŠ@3ªhÎF£ëQʈq¶·Íj­*“%÷X pyÔÆ­ZÆòæùóÒh"Ó(‡0x77 Êá„e®3²†p¾]à2{·šµ;œþî»Ký±’]fn]·ÿy0ذþË"Ëanü‘÷¶©ÇÀé¾úŸ ºñŽÚÈ6âG+u„Ò—=$¯~GÕ&sA SÅjlì#TA<¥TéÌCÔŠ>´;å"©¢/‚i`Ïéá¦6Yg¾©zÔ—Á†ºí'²‘!d±•&6f/:i×0jiÅʉný„V¿£)%ž¾»ßÖ¨”&³·9¯Óßã$« š¼ñ¦ƒv| ™`𦃸ºÕ)µÞLØF³ñµÛ6£˜s ”Ђ¿“'&„z¨¥™:ñ¢ßª7õ`m6?Žvùèmiɼ¿ãC;ñ”:f MÊýÑð¬rÙ´U¿ÁøÔšïã¡môQÌa& ”8Ç €fh¦oÝÛº‰7šzÍO‡¹ Ùá·B=ÑTPN Ú¦ÃçV0†ÊÉØýª.ÐZÓ†(ýnqè Nùõc7‰3¥La!±Û?ÒzëMÛ}ñ°:êjgC¨'§íI(ƒöÄ#ñiýAŒ+|õ]}£³m!Ô3²õ)›:3ÎMfLb¡#óæ1Ý™M|tÙã.y7›wÛt>=‡yL'ÍÙÐô­¶µÅȹÒÌ›h(Š9›eŒ'‘b†°‘Ðê}Ú·FS®·Žeg’ÅD–L!ƒØLpíWª(Ö™G@QòÙ’L&Û‰lþLeêkê-C£`¨ :™eŒgƒ™Æ|F—>®íòÒúÚúÅB¦I#êÖi¿ZP'çv½‰‡ÿN¼ˆ¡ÿö®þe±:º¤ÎNBšö»æF§ÊuèÕÑ¨ëŒ ¼D‰ó*!#`* ˆiýX¿­S™6ŽÂ·ù{ Î! öЗ‘¬!l%‹lÃV|ùÚ¡Ù§m߂ĸ|DEŒ`-ñ”Ò‰—s=¬b”3ªÃ‘v`ã tYldSXÈJFO)“YD áLb±s~Oc>K™@`Ã7ÔŸHÁ„RG k}ü —+ñ¢“DŠÍJç…uã1 IDAT©–02…É,"¢ósr½®døŒ\˜§úW°¡øÑÊv2É#ƒ ñ¥Í)»¤S@ SXhö ffå¯[×3—“HøÓÂ|¦9Q[GÛ_jÀ5«˜Ê2…laϱ‡séÇn‚i`ßôPþ:o=Ï´ ãÿÅŒ`-XʻۓèYËJFÓŠÙäòî这~ì&„zÚña,Ë©'„Y̦š†°Ñ™C®~ØìÃãƒF±‘!<ß6ˆk}WD#䱆‘$Sȶ1’5¼„TÀR&0Ÿi|¶!’3†îåÃâ8˜«Á%Ž‹lÕ”ËMk"#tÛÄ`†±ž¯¬ ¸+…#fv°ŠQÄPÎ6òEG8·xÏ£ˆ$¼è$‰"òIåuÒ8• ¶06|YÀTŠH¢o&°€XSá®p$æSG(Ÿ$EÓ«¨™éÌ£„žžŸ ·¬æ:ig.3œ‰u§°$Šð¥9Ìä‘Üñ\—½‚ʹ¥f>—‡o!œ|hçÁâI°Ô\Š©‡ûB8mJ9A4òVM ”À YõìßmpÄÐ6x+7XzvÌ0{Ìzàõºñ_§kîíÕˆä”9‘”ÿ¨náý;œt¸|«¢Mè¦_m_½q,Ÿ0|aj̽?¯‚VÛ¿õæjUE tú>&„= PœxXŹ‘˜µ›Í»ÿË^˜Ÿr 4Cõø>Î>¶ÿ˜9¥Ã”µ×¸æ&ÙÓ'Ý•°~À_{”¡[«ÍpLþ0qäCZ~:lòþSÏíh0j¹)§(ßÎï™9f¾eß³1öÏ=_oû¶Ö($Õ0iÁb˾¡:¶[¾©L¶Õò©¾[kê®v-⬹[‰®ù„Æð㜎”XJlËG:OêL}uænƒ‹·Ò¼ŸÎ‹5Œt´Š~ÐòKÝhƒBHZTD?vSNŒ[¤ õ¦MÅF–!à]s€ÑͬhüÕA}\È…Cn58Õ’Sß!54Ÿ‰MÑØËq½Óú÷ªléT%'iÖ» Z¦ÎÿDWyåF6m:–^éÂÌñskû’Fßã´¬"£|ÕêÚIÊ|—œd½=×)ß´ÑQg$øÏiq:Ñ!VÓùÞ7ï{FÎ\£ÑRUflJ¼[T‰LìûEcÏÆ÷6ùzCDÌçLM!¤d¿¶±×åÈB–ÕÓ71«ljÌ;-7úƦ<¢|@[mójøzsML.~Çhgªìè\GãäãÞ¹P…*«Í*Ã๠d±•A{žW™4¨|ƒÃ¿‚˜Qu7BLÃÇÎKœ×x¨Î?Ù¹Oå‡8(K8ØÖ`)¬í¼JçUøf´¿ý(ƒaÍÏè¾Ö²·°ý[¨‚|.ÔñH‡ðæ/XX|“óâÝ÷i‚ç6J>¾ùß;×FLúÇ ó_OHÅ~Í¡ç­÷Ó¬øõòcækù˜JH`ÙÖñxí¨†èàOÔѹ²‹ŸV™ê|ØÖq™ŽmšWF\§ó¦ú†¼MÇ #) 8ØIéÅÃëJ½Tµ@Qç9­_íwÐíÑGQÓÿ$ʈ¥ž†±ï¡B½÷±p Íðdq§'–‘°¾„gª‡Áh8%­’O'D™„Ú®à€[s0xÉ\Yú¯@˜hRí?±¬286VÃÇû©p^@}ÙCEd²°Å_ê"·+L>æ_?ãKЦDÞÇý-SèåßìD™Z¸ã–E%±”F-¾Õ_b6i›ÂD€);Ä `‰Ð4ñXf2‡šñ¦ÃɘHáÔE%þeT“¯°)-67“@Sv¬)w ¬I¾Š‚iÇÇYN{ ¨üVNÇÁ¸Ë¦0y›þ(Àdhx<3™ã¤ôwô7qç{z•™~Ú&oSF 1'¤i0-梩`Ûˆhø\ûSÙÂämähP»Zƪˆkˆ¥ŒxJñ/= ß•y(L^6Y™06¤ý…h* Y¦mv(L>æÇ !ô²aWð…ÐLbË{®oì “Ÿí›$`”N•=+Lª C4Œ=žfˆjÿT¦"…ÉË£Ž¦žÊî&üÍ»(Ig§yÇSaê°•-ÓŽÁû® S§‘KŒÊ±1ë8‚v}í®0µy‡™1lß=6…©ÝÔjætޱðZ".…ÉaQ7ï¤v£09ÐP#?ü<¦v3’Ì\ñP˜ÚÍw¶9fS˜ð7k¨ÝÈÇ1¯ZL?ûš1‰4ý­6u7FVSO“ …`þí°]jM}ÃŒŒ|mhk§iG–Y£FŽmÛø£ð-ù^Ñì6ó·$èÈ9ï¥õwŽr˜r™ú}M»Ç˜vo4}ê4²ëoþîx×ø¦ÔûŸ@ȆýÚîEJI1 b‰‘gì ¿´M¯«\Ì\4 ËM™qfNµšúÛM{"Pä¢Ö̃1P|:±s?ÒïŒ!³Û¡u¦Q˜òL9°#òš `ÈÖç´ý¤¿Ü¼cev˜6ô32,12N„=ýϥu~³(­f¾#ÌØ—ë\í ²ðÚ!*÷!Ðt4~ùßT÷ëC$ly_ëwÌ6ƒì'˜õÙl»¼:ü†¢ŒI²Ö̱Z3×£Í<¬´Í%‡¬ÓôÇ öÎ ²cM`›-f<m*7} ÆuItìåA¶µdÆ¢Æï$ŠI$˜‚i ‚hj ×6RÉÇVjw& ® š]¤‘J> ³›~¬+¡¦zG–šu?ßô1Úì%wïE$îw&Qgz·ŸŸ_V,Ò²$ $@™\3‰k­œTXKѤ³L7ƒá{è2› à 7­ø‘O*;èÏÃV7YýÌ&ÎRƱ š™=ôv¯›Ctáþãþ³s™Á]‹gñÿE\e$‹­üar ½´`µ åËNÓìâÙfÓŽäGóïÌ`.·Xs¸*k-ç[›8¶3V 7ð–M§šŽþô\N'^ÜÒ1Ÿ[|æó—œQLZúkÌšøO—§]†YtA‡nÓ6prf5–¯à›òsFÜFÇì#4L8 <²?¸=Ds~R½Š[ð‹?ÀØ¡P:óLõÁèﺤt÷Ìf£XÅ©Ã*‰÷Ÿ¼¡«ý|È·9“íxùdÇÐK”bˆÙàñíd%½@ýˆtÌRÀƒ—Ïãasêlžt…ëàèA;#.¢_ú4Œ?^7í¤C—’´ªa'ë% ¬çÝb~æÍ´MùH×íñ,f’äý»—ePÊWÚ–tÓžîÖPѵk6xgüà‡õûÐîÿž<ôm]£þÝìþ°rʵ=ÊÌJž×àØž}¿›szu/“X 'Ñ~=ü>üç﹕±§ü¸_¿¿ëߥtõV·Ê»îÓÜ<×õ™y/ÍQ½Ü¿mvÿ¶5áhr¯ìòíî û{Ï 3ÕuÁ^Ï06‡]áöN–‡£q룻¬‘Ý>ç»þ'êNtû{›ç„ð¼åýø¡ßÿ Oƒÿñ¿›~K€æÿ&MW†Hú¦ü%ð÷‰K˜ÂB¢ ?UÈ·Üæ£b`cuÓÞp—³¬Õ?šâ²ò.u,a"AÛ¾ÖÂvÛ-×Â8ü­Ò gà<™˜ïíB$­›2wp¶±)¤W¼¦™æ&ßê´—éfc!`íºËžaùÀeí[ÙÊåªÝ;|mmþ6¡F¡JƒÊA§0‚µ¼µ6;¯§ULÙÎR&½õígžiS§í¶¥rœžs7÷LÇ´ZÖ6øÇþºp=ë×\©í¨²!_>6Ôd&Ì ¹‹UÌ„Ó ÆZ' «¡fgEÊl~Z^fÓÏPäckâeLeŽŒÓ÷V‚´Yj*óð;sŒÿTØ|ÊV‚Ècs›ØÌ ÒŠ^×›£.û7ɰmè¥\f-‡"8Ç»ÝôÃgÓjÒ(3ms 3q@&¬ ÎU ×òá”Xbw~¤·è½.>æðL…­ý/#˜Î³‡ïWøà“÷ƒŽc“‘»¯¿8}@Ò‹ a#c·?ªm¨°ÉØOë'¬2ố¾´âGÐʯ]ˆ¤¹‹Ñ6´¥Å|¦1ký]Z^£ u 1Jb*Ì ¼…é[îqÝÆ›m>x´þêÄ>D®7~‡OZ˜þTŒ9•轟h™%ÆŒWmCÞ"`úØ»™—«Žu‘™Ë^¦~¨r š¯®ØÜªòñÖiGã×ò)8üÍBÍúì„Ñ£cå†ë´l‡I)Jÿ¶kÌ…¤5¼®HKƒ)7ÍÜCÌÜ›eä`³*›‚´Ø´1ÕÔ[®H ÛÍ<‰ƒ¦AǸöW ´wžGJî[ÚæhJÛ×ÌãSH™éóØÐÿ/ ÿ¬ö­B÷£š9'^ñ…ÎÓÇ~°`ðML]}Ÿ–¦ï[×}‰<ÓÛi6¢NÛÔoâì^pËw-¬AYZO«Ê£$ã,Ö¿¯}­3uõ7ÈM½ù]$ÔM8‘Ðû´ímP9õ¢ê?Õÿ¯5ý 3HÕ‚‚a穟eÙ›P¹£®¤†p¦Öݧýó1²Ž×õO$,|¥Ä³|Û8-7ÍÌ󕺮›&Ëq;›PKÓTùCÝ´ ݲaoÎ8Sz3ì„]/¤€¦m½š¡2ûŠHbèÖg©ÍêM&Û)Ýq–ÎÅ8X“u#‹ž¢%é–2ikïÕ>ƒYÿdöò;  ¬xA2-ÝûÓÁ ¤À‚ZX;i8#Ö¬ƒx°bY¥¿'ËÌ·RóM¥ Ñ´CRÖ;•ža02èIÖlº¡`ôyÓ@ô.³îvêÅlTßÇYUx-”CÈãñ¡ñ,c(ÒðUÁ'sÊä*ž_4v|¤‰$ŠÈ#ƒíd’B¤DDSN ÙB>©<‘?Jëj6ë ŸAWëmVŒrÿ@ÝÿW>L–µÞìDêÉ*2ê׫ÌaÎØY!/"ñyr1¡d²/=T‰ÿ~Éã€üóauþ5¬ž} mƒŽb yxãdÈÏ(³Þük@r,h€åÁc\Ór8®‘Ü2BˆÊý”‚˜ó!&ðϘ€Ì=Ì69üJ`^ñ­ÌK¿•zN`‹aøa¤zi5âD˜u;so‡oa7Bê¢ÿ~«BøY/’•ð"Ì…×1……îìÌžO™š&E>d[0fr×aÍ™¥/!/œL‹÷1JX×ÓSe6„0"r#’ÖQÆé=¿_ ²ÈZÿ"Ä€Œ¶hçȞǯZû¾-ü2÷0tÏg³nPnÁfðíÿ}×wÚŒ‚^¾›¾gVø]Ý£ÍFæy0=õžž‘ŒùªôD$~ÞeêP9FOÿDæîP–&U®æM½U·„ÌnÚÛhÌ“þ¸³w;ÖJ'øMÿΥػÁª ¬\r]WbË*-?mþë.ÅÜñºÊödg—ÍÜjßiÞ0{N›K–‹¾q7§˜'eÞ[º6|{X3žro¡ žÅ#"œð __ÛS SËïs™lþë½»æOì€Ýë/;kKH˜¥ýít¡ˆ eï»9é»í…6$/´Ò(KUª¼Fei¯Ç8yÛúÚ¯þMWd0µé>ØÚŒZ@]FÁ5¸AÚný9'½P#ú~³¾Óq»?ì2?dz̘Uý)EúVö%1±ånmd²£û¯=À´A÷ºÍ•Ùiw¸d?Ê(AfO“hÒ6"os¯•JË}p<¥ É–SöEÛÏqº¬ñ¿ÚÙß”=ou‹p/f’óà½_A$Lñ[¨¾¶µøÏ.B•ÎHº7uºrÝAï˜Z¾¬ûaú¥S÷ S„HÖ/«+VŒu~Ùd7>­öþ:”Âáûi6þ°6`8³˜Í'ó£5ÕAweûé(ízQh³;|~üm7ýsûL‡òŒÓ˜Î<žË¢ùžìåλgNgúÒ{‰¨´!´©Óv7ÈC`AèMܼgœgŒæqÓèÌc:Þ›jy»meùÛ6?sË€=)ç2™E¼¹¼2V9]®Ü•Kî¦á.§ß:ׯd‡ø 5ýL…†þÇ3ƒ¹<ºz,·åÌa6³ðÚ"ºÚýS‚L›¼lhN 4<Žã‹¹*q s™AÄÖÏ»úÚP´:ûjæ0“9ÌdXÍ3ŠRíµ¿¿mš{¢΋}o`R݃úM©Çœñö@’ )ãXV1ŠÉy¨âáðé´É¸Ó̯$¨MïM þÄìüØé K½/\~&Á曑™(ÄåŸç8„ÛmíO‚ÎA^›Eo¹UFÆò6cTkVÇüòµÕfPÒ(\u¸ûÀ˜ñlæiž ]°KˆAuâÂÕnû¾É¼jþ¿—ŸŽŸ‘u»‘c²&\ ….ÿ•¾FNu6Ù{›6‡›ï L¿ýlWR?S–·9ˆÚŒì›lf½`3¦õ¦¬&Sg“­½²vÓ×&SW§‡<Âqù(9êuü-Á(Y­fœjMy¦¾ƒ¤8P½`JäDÉZlH·YëkÊuøsg{MŸ2p)LI¸”š0óo‚)§ÔÌ5Òiꎱ¡øé¶ ƒ#Z2Íüm·iC-jNÞ…Ë'Øô­§ÒBˆ"hT›¾ûé\iÚ‹€5&ZÔGÛ_v!›÷ëœN†ú'’»_Ë ‡âQP?Í"•å’ÁgbûCŠP:œÄÓÑèå6-³º_"ò?‡BØ4ùOd§õ¶(Ê3#â_Ì­¾ öÂŽ—O)¡+÷?4ëE@Í·Š¥A}‚ñs oM¨²– áǼÌDª&š±/7ýö@ßÍXû˜qrøð9Öt!.ŸÚZÛþãcæZ”)«]¿iK< ß=ßëÜ7éƒ ýÎ!¹ê¿DØèýgb)cýÄfêeã ¥Žd ©BH{ÓÁNÒÉd;Å$RF,‘TÑHÅ$òIS´¢‡/6{IÓ³ô»-]s³þÄçÿ+&‘aˆ¤ÿb¡¹•Yâ‡&Y ;‘öåGª/B_Ü}|šÌâ#¬£bãiHŽÅ* —gÙ­ ¡@„` ³WÝ®ÆæñôÏh0ó"ˆó1çÿ…2bÊ,˜&3a:ó°Â„ykn¡}÷‘Êâ(Ó~ël4‹c0¦N¼)µxD¦ÂÁ ¸®•LUbÇ…BÚü×Ôgj˜YL~ÝÜ’@߉o³{ÑH’E \¹+—§çecå I Þ¡tË™ZÎPs0øy N;µœàœ¯X>{_ä„QBGLëÄš+Œ˜óµ¹½Õ¤‘Õ ±WQ´ ‰_# ËË2Æc Ñs>¦tý™Ê¹Ý” 93Ÿ¤|ãé ëx†á×µ¸’妚Ÿv:úœi%Ï9Ðl¤LÔÇ¡59„züÍqÙ ó»zÓ‡D5â¤Hö胿Ç0#û¸šqðDþbŒ’×éñ·(Û¥"ÀV~º÷QsPJØQ*?c‚õDº|P2CGðzøvæXª0î±É(ÞȦÌIÄåÐ ®‹|£a³P3íˆq¬þÖ©4´Ž<šÒ°3 É3tɰsÀE„Tíw!7¾†/­Ô%‡- t]l‚ eÀ1.Çl_›œ %G{É#CçF 4EëšíðÓWûÒ Íß’~k 8ÊíÔ>–$œ¥rØi¢”½]õµ'©²ß6~Rm‹¡Ò Ýc¬¶U« yôóp›|À·å{‡]C./h÷;RsÅE«ÉûX"©Â—6b)#²ý3gâ^'U7®Kú€Þ¶èá“ÒœgéïÓOD˜ÿ{ ƒôóÛ—¬ÞÁ,f“Výº.Ò"›oŸíƬ›waÈ9,eï çuï`¥ÂÉùU¬&‡´Ò×õñDc¼mÙDœ•şΦòXñ8{bKXd¥Ã¥;·±œ±Dlÿ\Ñ]6Ã×ü8ÚŸh6ŸÁ°8àn,[ gÔ#¢üV³xÒk$#kžÒͨWÔ¿ e°û)¥Bÿ¤—y%£?’§D‰go)bcH*~WM{?íhE„YØÉÐÒÿf0—çM‚pʶJ*ËNÕ>íµÝR}l›B€ 9ªI=‰),ä™yÃø`zq…º£4(Šè@72`uÐÕÌ`.5M}\R­ A °!WµiIW„0j¹ù)×7-ß„¸Ð±²¸Ó™ÃLf2‡ØÂt~ÛPžvwD­(ûlüi!fA*m«Ÿí_‡ÿÙ`h 8 ßõ&ªªÕ†Ú´ÙúîR(4?5h™—ͯ-Ãôa-®(8?ùaæ¬?îô4Õ¤ 5b!îQ¥Ž¹bCžTŽõÑbÚiÞ±G§Ûþîƒ+2k…ÍŸÈ˦(8P¨*Û\r˜áBl·õœ” NY:äÖâF9иx#ƒ@S‡áiµ™æ޵¦>ªÖi›§Q¶~†šµä@3“mHL0®ÈL™H®h¿BòWiÚ”dSžqQ d˜ßí²)XíFÉv´eˆQXbL};Lâ ZÔaC@Â\õ´ã♫7}í°!£•6³^.?7GtÝn£,øØÐÇEÏT ‚ŠðS‰Þù‰Ó'oѨ™\û€¶ÛÁÉ— ÑÇ<ç+…†1Ç“J>eùg8Q³¼¬‹ÉØðªÎ•DÓÿQ†²k^‚J(Ÿu1íëª]ëù4ëK®„*Èt%‘T‘²é-]g©°"ñ:Ƭz b`E¿ëSÿ˜Z$¼ŒRïð©jæÊbœþr­qGãwçwÎõî”GQ|7ÙÇšuí@›«³ÍX8LÉæ}\x­Ú×– chÃ—à‚¯hO9’v|ð¯< ó$\çQeì)DPwãA ƒ”.“íÑÈ|¦‘ÅV63ˆw[“¸Äou„Ò‚?äQO/t ¤·w-_æ†i_¢r¼ ø®ºû„Þ¿#Lÿ Ьհƒþ¤± k²:âKELq¨ ‡Wv¾&˜LcÖY_²zùÕz³onk?£Ì‰A5Ö2!rî§°ÌÜBûÒm¤PÏH^â#Yƒ%X}…‹oR$á'´O¶@I$Q„uö+¬_ñW-ÃÞF9²MLZé‚ÿøoÙºø2ES›äGž3­]Xç~‚ïäïØ¾ôºÙt‡pt§Ø¬,aÅœëT–#Ü}:º{®Þ¸«DX4ãFš—ôRSYÜ¡Wê•eX»…!cŸUÙ$Ñ£ïO2…$õ}‡è)SµädE~Ò{.»–0¬ÑBóŠ^ÚïîÐ$ #ðÒú¿Æ®éR¹äÂØÝ +'_«~Q‡ˆRœ’y-“¡âÎS{ï¾`M%³Ôý˜îM;CÛ3‹ž£3Á)jšéFv‘«ç\­ @7í(s¦ÎíºÜ³®UûÑÍ÷qP2û,UZ<ë6ŠCû设fVŒèAÖ]Ôeà!Æ5Ü£ ‘Puš*žc– …ýÏq)—Žg4:Ç¥:€ <õs—â‡Kmqt÷í t)Ê­qG»£v¾æïÝDî;Ã…jw„Ñ#£u”­žÈ›y±Î]ûÓrœm¢3qïOeø)î¿KÒ}É iwFßÁú».]ä¹”öx¬Ÿ=Ð5ÍQ)T$œ Q8Y½»<6Y¯ ¹ªÇ(Ô¯“T‰êÆwm™ÿ87ªùÁ7ëxâø¨Ñ¦´?Q=²ø@uHæFÜêú( ¬8*æö¿•ê”>Î?õjl±½¶Ë)»=}ÏuþÞÎhO¼’ÑÎÿ~·!©KÛíß}ɯçÇô;ÂÔcupr¨npÞ [JË/mW9¼Ã?ãg1–å„îÝçî¿âg6ôx(=ELæáú pb%"Q?^~>ü#u!Ó™GÈžý.ÄÁ1® ¾ªïÉœ²³ŠCZ>zÛ¸/b S¸_µôB›¯‰ %IÐÛäÚá\•µÙÚ]ÿ+¸R ™Çt" ?s®s´±Ÿþ”ÇÆ æòìСˆGj0k%Ü4zs™ÏV=æÙÏh-§>õ1™»—Î@Lt³¯°üÝәʼt!@Þæû(•Ó¤„x0wÌ©Ë_oÀ÷¤LcÚæ{9«ÁÝŸ(Tå‘;ôJrXÍÃ|õ`5ÂAw2‹Ùx-WØüA’`vêíÜ1u¶nlùp÷‚éŒaÁ_éÖŽ:EèF\¨„» IDATw&Әϋs³¸nÆ rXMZíë ·WÀáÖJ‚ÎâÍ%\°•÷f!Þ&âÏ>¾®ƒhSöŸØJ~´2éJN¸Ç†‚9æA†*-V»ð’o&™{^v¡NͶvGÃÂQÿ`«ØN¦:æVƒÍw%Y×C^èÅÂŒš»uî9 ~^á÷.ù¤â_p +ê¬mÛ™pÞtš÷†"6Ô'–޹ž •Su&ñù8#­h3Ê]ħ¼OióYÚ†f#_ƒà´;¿ßQ™~ Q&‚Öáå U£O&˜ü·ÐvââNªQ%g³ÿ Zõ¼~Woæbš¾Û>øH|Z~PÓ®¯–Ý>úHê%býç:ŽÛ¿‘3}vXN²Pçiq¯±kçEΈ5Ì<ÌŒçNZ•åþ§³ácêÔ L‚í^$sñËZŸƒÜ7Ié$ÔrFn±Ñ´k„AìêÍå§\ënJ;–À ß@Ì̸‹9Ûo×9höœñ†rÙÛ.e+¬5¢A*ŽHÕ:³žZÍ·ãÃä ø5: é:— ƒÏ!yí;ú·å˜ núJQœ (x&ñ”Ò@0Á[¾RËîÀsØA¦ïºGå髈–uÌ>äÉ•9~àÕ”À‚š›ÕÏ(¬~‚ø[zÁòF¶ÀKPóÔÀ””ûH¦»×©ü3 #òòÖ^P—s"™l§¤âаd¡+-ð‡-Ã.§†pÆox:`Wö…¤­|]å6‚}÷Ó°ñ=—"Í%d½™ƒÌ<ßeC k̾âccÝ_š‚Ž%°éWV…p¨ :‰ðÆ/ vÇœO{)!I,¦˜³¡ vE^H_öàÛø=‚þÂ’ÉvF²†JXÊ.˜±æÂßXΣ-cÍ”àE'û"CaŒºXcÀŸ× 2ËjAÄÿá¿3}îÓß$¿,Þ-D$ùשÇD'Åìú˜¥¡giÜß™$`황 í¿ l‡?@%Dîø jQÊ™Ìa&O¯Í†«vþ<êGDàv¶ŽËÖ‘ÇÅLa!ïE&"U?¡,£üÄ̆¨¿Â\ØËÌgOX^?JË`ŒüZN „¬ßÏÜÈÛ˜2e!S˜Áý•S¯&ªfqÌ,Ž¿‘æŠ^ÌcTÌÓòPaqÎ.}šì¸§a ìàŽ ú‘¤°Uúí¬ò»˜5â.ª’NfÅà1‡þÆ/Æ|ÀÖˆË)›q: ™rè÷Ë!!à}$‚¾Pw–ËOÄóiÐCspÕ¿÷oMõvTÏó \1 ·ºúð¸A20eÎý ÙiOwÿÎÿcïÝ£ª*×öÿÏDDBD$$DDB$""$2#""2#_33s—™•ÛÌÌì°ÍÊÌÌÊNî23³4333Ï)š’™BTDDDDDDDDBDîßÏ3ל ÐjïöûÛïw4Ç`kÍùœ×¼Ÿûºî2mJ_IH Ü=ΟoÖ–nj“lnM¬VÇ ‰Yß+ðtv؈)‚?Dzìnú}†Ú0v]i7ê?ÉŠ5âv  £Œ*žrСvíteêôÒ¡Ë7MóÖCÇmýYgFà¶ä,AU‡š×ßÊJŒ¦eÑcacÅÎ ¯‚ ôÙ «ØgùÕ[eï™»Î*W¥õ½ª\õØ«?OÚ:¬wíIUÖz˜TóbÓû–AwÏ­Ö‘ºîéa¨——ÆmÛ`;zl<®›ëßÜFccÄÖmoj1Zà|_qÄ¥WA[üÆÖ¾Ñd^”PE òn¾,/øMR µ¹y[Ïôx›ôæL‡uêǿ⨳Å1úP.•µÐ;%¡ã=a×Nõ/oï4^—=–¯y´|¾~4AÔF=õéD`þaGÙâ ~¢2¤­îҾξgúJ">¬`=Éôc Cù„ ŠèüZ¡Š h¾@gBç˜åÛÕGõ‹á­O"ÚúËÂôŸ¶09§Ww¸ª·ª:ýFbj†ä). ÿBºcáÆÉéŒæ]únZn½Ý7Xo¼Žü $ ‹èÏL…œ ¤íJK(©ïhùî˜>&ËÔÇÑz>%!˜Ç ž-zB@-nÆkpÛó©Lf,QÓv:+’›þ,¦eÂd²%ÂÆ€˜À6 IBæè´áÊtõÆ_ü£å#Tb³òØYWP2¨oó ÿL} nÏT+õ«C¹óù%,Ù|—¥dêú˜õ«µY×" ¡§ÁÛ<£êÙ¹š'äžç5ü2Y¾V&KÌô1}{"¡ªGÞd ¯fãQo2‘ñ¸§±àízFv6šÖ¥Ú|+èÃH¦œyPm–-0fžZo«8²#sLOÖ›¿Ý²ÆTÛ,Tõ¶gb!3¨SEOÖroõ—êMÑÎ~3YWž@H÷¸_ʉ,Ú­Þ²íÖ&“gÖ%J¯ÖzµÂ}Úgß2Óªš" .ª%n¹gÕ"j·J™÷™ý¯Ë³ËÇÉݶP›ù÷År"67OÛ1Nˆ×XZ,&[Òd¿™ÚF:?»?Wµ­-=màÃÕ6À­ËZ3óÎô93•žMË™+«HÇut¤ík›£.6«g±u|F¡íË´Ž™¬A7O–¯Ž—.¯éËdú™¾A&“΋µg2ÿª4ñVÖN ¨²•7K£Êô3½Jõ3Á:Ÿ:Ý^á6h+À|=¦<õËŽöëth«%*Ë.^8â÷9,h™X¬@“Eèn³Î•è:xa©b»ëßAº\Åú3s³ÇrÎ6×o[ûép9 ‚:×–¸­=ëPþ5ø=¦Ö>¡êgÆ4ì¥=.ÁËQÌaZôcDCÒ êžx( ëDЂCªìqÐ3ö[†3ƒ~‹–B”ÜÛ:Ü^rPÝÓ Æ¿Îä9Ï©rõ‡$ŸïHk¸YYð< xPG7iù‡8( í@ÀÆ#–ïÖÝõºÍ³´eÑJFv `áKÅ{ˆ¦å.Tñ|Ý>ÚRèP®wWm_Ü^…Ç €*6xœ¢0¤3™ÄB*îÅgÈìÂ\3ˆyäAñ¤šõ$3›‡Ê'D‘Mtg y„±cK4·t_‹e|‘9H•«F×ÉtOR†ñûNjþLZºkàá^΀É˶€ïoB$þ§]©Žˆ1À¢Ãj°•ÛS­m †ÒÀKXA&2žÃÆfDúŸ?í5ðD¯wÅTB X À Máa[¤}Ô¯ oKyå‡Lmš¦U¼ËhªÿÔrl.Æ9\Lƒmƒ Q‹FJð*V¿–‚ÊÀA’pô ˜b±„9=l}™h;:ì®Ó«²õ‹ ØMÀä©ëQa©:ß|,§x°Tø×êûݱœ¬ØÖŠ~îr#‰Û¾Wk[:±( Õ’E*ýM¯§;[p›w€ÒA—0’i,ª¼[eö€‰/2˜¹Ï9¨ú*EÞEÿ•‹¡²ú^ÅSL!­æf˜§Ú¢bP;|ŠN( ï&>Á`æâ³àÔÁ’ÁwªP0h'w$píaUßþ6K¯«:âˈ¹Ž¸õ?A!íH`¾×¶Å\Mlñvë…([µAeB[ !š,\2¢¡Ð£3Áõ©um…{írÝ/#œ½¼ËøQF ©xPÃL†Q‹;áäC&YD“MSxŠ ÀBJà¢gT›”·¦«ò²¼T‡ˆÛŸ‚þrúþ—H/äñ(çß’F7øßÇc¬c2Q moEõ¤c¾ž¼‡ùÿFõàÖMAKÀ?ã(ò>¦¸´ßÊL3c=Ʋ¦i÷‚wMC¯¾'™2âIü±9ñÀLð^p’²ìK©kèE2ë1&Ø­µ^<ÄlpŒjaèØ)žÖQÑÒ;hÖë‰3R—ÝŽ RR#˜Ž‘£ìÛâ©Û OaèÈÉ›ØÕrîöhtL³ü¦cüÂW|ƒÓAç…Oð¥k0b£Ÿ0câ#ÔOo¡§›äKõB7ŠS;!ó OêG^Ü|oF²Ño7ŒÃbv5:âñœ~š‘ > ~sKνæB ©$’ޱRH±ÆèÛ¯éÑ3!fÒ/Ì™÷ órïÇ›J†|ˆgŸS4Œ7šÒ剓¼^À¿çf{š±5u.WõŒš·“1%oQH0ÏD½Åèþÿ$X5üµo*¤¬\MRæð€•}oW²ýhJX¨¦@èŒýjá¿V)qÇ7·,·©g! JÆtP}Ü­<Ïæ+1Þ6Tzéö[Àe‚¨Ý›æCÉT Þ’ó•E€¾4u¾¯Áb«E(ØÄ18U¿‰{kßHœÛÛ®zÓŒ¢©t@®Þ\{(ŸÇÜ®×§Ðfù³·‰–@cÎNÌf¼ºZ‡Ÿmθjk·|áÍÌÍZ›eУÑîPc²ÁDxè´RšÙMêmu6tâlŸ™`ÛÔc ƒ  %>Z˜ÜÙz9h¼æec1TM‹ª—Í*Õ¸ZÉ-T?dÛ^ j ¦×Ejn¼øë>ó·?yk¿µPN¥í~S²`³OXNøåŠ‘¦yÿ‹ïò²: 6Yš¡ ôRü6³òro*q[xVµ[(L`‚uÄLxœwMpñÁ¦â%ª}¢ËvPežº5õÕjÝëÏ"%¼nNy?Ëٿ˳¹çµEzÂlû„ÙozþnzcÞ¤úÎ%È”à6áŽâeŒ`:I¤áZpNm‚vJ~µÊ«Ò¯-ı’Þ|X1z€ä] íypý M<Åú² —,±Žyì–¼²>¢i$1“a,6›mô€U›SH©\m9u—ÛÞX½Y" 8¬# Èó¼ÆÙ 7DOJc´™SÅ4F2¸ásõÆd·4xÙŽc !Ö`}˜ÂSü03IC$ cìéNx¾¦ÞbQÕÝmoò¾8Ó}oä5žgoO(„×=µõ/ÿ°u¼Yo;ž0qíŸîy#7ÍHçâáåÌa½+VYÇŽå¶c.»Ô€¶î<ùïT=Ãë^cÂE0Ÿs±=g­†@EX;æ2˜z\éÏ"‚ :Ë ˜â…n–ů ðRVÒ›Lb˜Sù ³ä‚%ØU×MÞ׳Œ¾Œg"^»NYGkmG]övˆ€úÀ¸nî/‡,1Tú}áM¿0¦æ-¸_ßçf’K¿SÇÎ^P<°#ã˜Äœêa ,|Ux18ýs‡¨åæ¨ké‘ù³ZCRtý×ãÊ»)òzâçÿPÐ÷RÜ©%`åÕÞ=¡Ä«ÛŽÐk°‰x*/Øìr-=ê~† Hõ¿béË2üŠŽQt15xP‡›r §œ âˆdëI¦˜@²ˆfãXIoæ0„>¬ Ž 6OA|·-Y…¤ú›ÚÀñ']Y˜þËÓ$[wÌx½¸þYi+§¸ž¬¥åÈzàWæù›¥Lá·ƒNñ´Yÿ‰}6°vØ-ç§ÍÛ®ãF>½Y‰qñ,Œdaü3/S9¹íoÊ €Ê³ÃÈRŒ™Bÿ¾_³~èÍ¿)gðc2—¾YˆÑ[ØëKÖ¾E-h¯ÏÒ‡`´;Á½q_0»ïƒÔhÅ…¢´]Q…Kä9Rî]Å–§®QÆyV’¹ †aåàÛɪ‹b#‡õ»‘F'ü“áƒ>¤a´qÞ ÅËÜï`àˆ/©×î¼RÊhtƒ>gYï;T¾Í´y1Ìèõc½®6Ùó\SSWs"©ùïwÅ]ý”Ÿ]³TšpÛ®vh«f%:Ju`êÇ hTï-×8üsû4ú&BïÝ×4Xwló¿Z¢^4ûœwò‰&ý1!è%ËÚÔ½ißæFÙʦHµÞ­hhÌɈc‹8Êã¸`Òàš—Xñ‡õ7[ÿ› ëÍ´kº×Îuöv®?tSó}z…óî ÐMô¨”Í«7ޱVåÚÆ®q°9þZŠb-ú<>Ìz7za€ÙÝtþ,E1P_syÎ’$ðmÆjæØé\ÖD¸è<§Ž]~W4[×Jÿ¶*MOeÁùlƪ<­ ÆÎUs^÷u2ëÙc¥e ÕŽw7§pBkèÕ´/mýUçÝ’Z—VLgyn]µqÓ•1¼éôHgc¥6VÐud¾C˜²7Þ~”ê7"y«bŒSÞ…MbýÇ6ûÿ÷.@þªF^áK–Šð€œû“êøƒð–ȵò“ì–ËåWi%r‘SˆœCKùFn‰påM{ƒðÈgr¿—v"‡ÙŽÈOú÷!ä¹]î‘/…="\÷;Ò¼\¤œ”“ÒFd"«ù ‘ù‘¥ˆì@¾”{¤³n»@Zˆ\&{d±Ü)g¤¥ÈnD¾Dä D–#ò³j‡äz¹C– ³DàÛ¦uÜ)ò¬¼.r@?÷!"o ò–þ{9rH:ÊËò¢p@N8¥Ñ^ŽÊ{ò¸“‹Eö"ò®Ó,]–#È^é*/ÊË¢ÌÛ¾‘ÛåùY®9¤Ÿû‘×y‘¯Ù‰“‹å%yI Qc†[DÚÊ ù@Uy@dƒ.ûRDÖ!g¤¥|-wÉ-ò­p…ÿ¥ÒM¶ËQi/r‘ïõ3Ëõóû‘¯äná¬ûUÝ®”ò¸¼'û¤‹ÈqD¾ÓÏíDä4²C®”e–\%¿Èƒ2KÞ—ÇDÎê¶ÿ\×ç}U&9Œü,×È“òŽÜ!KåFÙ ‡¤£ª÷,}߇ºÞ;TúÊrŸ|.;å Uæ :ÝYz¼Dä Â!‘­rµjË:×u?~ˆÈ·ˆìF>’¿Ëò7ußD¶Úêt‘È:¹YŽJ{uÏvÝ>Ÿë>]…œ”62K9§ÚK~Ñ}÷5"‹U™ŽÉÅ"'‘–rFä˜nô}‡må~]T[þhÿ«Ôý‘ýº->×ߪÒ9-‰lUí)t»ìPsR~FöÈeòyCÕí;ýü×ÈYi¡Êó“š»²ÊöÜU·n²]•u«.ïA]ÏUžCå§ÛíA™%Û¥›ZöªqtRÚ¨´÷é¿¿Õ}ò)Âc¢Úu–n—#:Ÿ‘Ur›*ëû*ýcr±Êë3¯ž[G¥½<&ï[kÇV=Ö~@øV·érä€tVÏ}«×ÄoT~’kå€tVÏÿhÍN‰Ês?Žß²QkÞ>颯÷—z<|‡‘KäEyYÕ÷ýó5ò²¼¨ÆÕ÷z\ÌRy|!“¥r‡*Óçj<¼,/ 'DÍÍÕª>G¥½p‘¨öû‘wTùWË­²WºªöüyGž”rV¾—íÄb5çå"ï©uèWi¥ÆËb=¾©}CŽ©²¶Â!Qi­Úr–<(ÉiUןÔ|?#-U{­Sãb»tSÿŸFn–u"'uû|ì–ËU{ý€È¯·‹µÞCÞ’§åWi%û¤‹¼%O«úŸB¶ÊÕò°|,‹åNy_“oåY.ÿ#/È+ÒVNÈÓò–<.ï o‰\"Gä&ùN¸I„Ž"wËWÂ¥z}?.ÒJ~µþçË?eßýËÂô¿}Ýá‚1Œþ`ÄaÔýDzŠ#ƒ_£ù*{cxSù0½ †±íßN»wé*Tÿ“á^üÏX&ãBƒS–?|í‚©_Q¸ëRΦº²–žôc Æ­‹õ{¯Jeæ_û#˲ïDî5xY6aTƒñGDC‹!pÆaÆ/y©68.!Lg¾”ctÿϯ…°ùû˜˜ú’kpRùH¨€“¿Uþtðyœ ‹^¦!«õ¸òÅÚ{3K·Ô³ôO[ÌÚÜ[9»Ë•Uo¦ð€T^ø¡|°ñk¤ÐàDˆ7K臗¹µm'³ó&«¶MœùùV¤B÷y[™’ú4ËŠîTá"ÎwmS~!Ó—<Æ' mâ¯`™Ôñì2ˆÍÙŽûùx骆}ò1÷®øÒ‰Žìä” É™ß5õ‡°Ÿ¢-:ÅCË>…l+èiã²û.<[ ® •3ÛôËÊVÇ<Ò«ëpƒ:º’Í“bð˜ÿ+äC÷¬­M¾ÏÛË›ÙÏ6yÔuý9åƒU½ëV9×½¼òN‘™sµ3í¿ ä~Íùº`vÆÃÄlúŹòNÿå<Ùhj}× Ç”¬ÕNTußôãŠHbóC3¯iE7õê 3>b¾Íê@m?œ°IÛÉ6ߌ㠾ÙÇ›<š¶¿IŸø¯9ÊÄE/ÑxÈŒ_ñŠº·Q]“YOߢåM$ Žzûá—zÌ©þÇk|ÔQž-¤G [±OÇڮ¿ñæ˜&òÝ‹¶:Ø€û›aŠù¢æZƒ}XA¨/¥qX‘ °åkëÿLx›gœn‰(Ýcý“ÇWú42¸æ6Û?¦ï’'Õ f®ÓüŸÂSøèðÊ3ãH6£SÇA×â<‡o•a3º1DÅ)¥õ@þŒë/¦ÿµ2̓«Y4åZ½™˜a vüë”GÃOm2×$ma ‰eÁâEEQ…ÔP‡¥ø“CI`]ŸžÈŠßH;T‚æÐ—eô`3þ5G~Zõž-p­;Gƒ›A~äÁ@pl‚¼¼‘Úa|ÏÃÓyŠ)ôáŬ2vÞXì%Óß&vy\Á•µ» $Óž^ lõà§Øô¨ýY-˜&ÃΔ7°QÄ‹};²–ž|ÂP~š÷¥Ãí‰\¾2‡‰Œ§ÃbKì±ç°$ö º1Â*VÏN‡3a{ ÇLUÔ×òª6?£*›oC lŒ¹éŒà«Ât.áy^c0s•oPΡ[ìÒ}!Õõ6¦1’Õi)Ü—4‡˜MRý•§ëÉî礅8ǹ¾Â« ã¸ÏeO1…˜š_¬î6? Ýîõ¡-È Ž%ô£/ˈ#·¢³=Þ¤±×)¿•RïKØH»ˆdSñÍ?nÕÅL¿Új“ŠÞíØE$ õ?(ß²"›?˜Y~3¨t¬÷»™ä†ïÔ½98‡¶©³ùN«EÜ<ÖÎÖ3qþPÕðÜuÚò'2%´ÌAkKÜJϪ¾4%/LÙw}¼húÚüÚêm>rîú8z{Èî ÇùF›6_¯Dµé¯ï7Ça­ßvÆbóÏtØÂ’ìðµÕÁd®™÷TYþ°«î—Hv>%vRŽÚ&Èsµù:ùbIøè9à EÑZvÈJßEçQ­ó6cÌÅè#ÖTý™¿>:_ 6ÃÌ݈IÿÅÁ,+M¼ÿ©GUŸGi¿¥jÝf^ªÝÖöº…ž9ëÔ˜×m·Y÷I…±¡XL@Ó)Ûæódú{¹Ú|ÏÊm¾M¦þS½ýfpôÆ}¿¿î—u옜ó˺Ïcúngñx¤þªÚ´LÒ^—à¿Fû2ê117ò~òcÒ&¥W5/þ>‡xÊIÇ4ìø›3¯Suö‡‚~—òÏó.£ñ\pšÉŸe>÷’F¾óX¬½·ÝÙBö²« ªû·¦/ËX_|‹jcO(O¹ß-Dz =îf@ÎתŒ!ðIÔà ͜¥|µ‚`Kä5RL@ù2|¯Ã‹*êp#†_¨¤Yž¿Ô IDAT-Þœ¤‚v¬'o*éÁf*ñ&$ÇTŠ?EH1¹„óÅÊA7Dmć –÷î Oé9ž£û0x ¤ü/Àô05)£ÍÃL&R þ÷Ó^ 7$ndSñ£Ì 0yPƒudC:‰¬ªì S€WJñ¿pÚ½yð•÷º³…@ŠSnTãIAdEI|[ÐK‰n6cˆ0tô÷g½'3˜¹Ddí±ôcLÀdRÏ#¡Ð»3+èà †³gF<:eÖ2†B»O*˜Àú²Œ ÊC37 ¨ ¼ˆt¹}[*¤h­Ž@µ˜>8…áÌ ,mŸåØlw„oо°Åóæ2˜*G:Â$t›’©¾Ü_-'ssãn°ù:„BQ@'æ1ˆ Làì|76Ü›Hbí÷–®SsZKDäú\Æ<ñjÍ8®ôÈV‹^éñ¦Êå5hÌñ¸œ•ôf"ã ¡€‰ŒWo¾¥¶öñ± o%°žd0AÌSo õûõ*-€YéÛ–"¨Â‹^UߪūØ09±ý¡!Æ ƒ8bÈÄ£ðWËaÝÞofl³(ºTIdÚ6-/[ÛúA}L ªñÄ;ë¤Ê»Ô€ÍrxªqUÚ/NY1Óì2ú™*ÿ6xm>e “x`’e', “P¡7[w,⃠˜Lý'3¯0,'ô,gsOýÝZÝ®f|»X°Çy4¥ êõ¤Ñz#Š€R_­-Toó[15œLÐrÝß%×£+a»öYcÁœSeúÞ8¬ ºnPÓÿ"<¶üª¬M‰XLBOhhP‰7>sOP;¸®Ôã:ÿœ˜<”5¯¬_{ür) i!7‘´~ƒÚH+l›j‚Rùª/ÍXhùñ]Í߯ʪË]a›Óaú·© ¯åŠâ:©¸œù¶1gÆi̵µ• ’“õØËÀ!Q×»%c™Ì8&á³â„ª»¿òIK󺉤5Ô\¦ÔΪ¬®d«ûf'=ȦS»ä"5þÃ!-é&æs/ŸþR¡|ÄÅ$‘¦ÖŽ…Ç¡j¶â¢µµH½ViO‚Ñ!ÿ$‚†¥} µ0Uw-.KjÏFè_²Ê5`ª˜åj…1‰gy„áQò+ÙWR‰|OmÈ Ž\  „ÉŒe“ˆe¹„3AÌcÙA ™äÁfzЀ ÔP+eø±·!\YŸçŸ7Àë.j|ÿ˜þo¦¦eÞ¢W¥09¥Ì„®Éyôf%QdãO)nÔ‘K8îÔR‡•x“O(i$q #&Ñlx§´ÇCÛ‰• bž2“‡TãI øP TâM.ál"ž/F ‚÷77ϰ3>áRIbSéÍJB«ö[V‡½Yš@ÊʼÕÇ –ÉN²÷†Q_ùrÓ€4†1“e_9_ËÔ\Ö’l¢XKOæ0„}ï†Á“.—î<Åú³3ÎàÇ.2¨Ctûwd%½y“1 4øGè›<ÄlÂË÷Zs³oPÒš^¬áÇõñ´O.c<È| Ž[ŒCfž Ò€KHf=»k"ù›Ç|†1Ó² ™Mn6‹„yt"D(Ë þ“èà º×oµ‚ª6جžê™|Ï.¤‘ÄDÆE6 ˆWù)'Àd2¾ê‚Z’E4ÄáEýY„Wî)KàÓgm ?õ6ºÉ÷zâ+T›M± 0ùØ,‘!P܆r| Á¦/† ÈØb‘ehvRE#ÀTg³˜ÅC†×uÄÕýdkØõ†‚ Ö½î5gÔøÉµ&W›eƤdWèqV¦ëVi~&s±ÒL޲øÚ€R… 0™úN¦õÇW[‰ìB©ÚⳫçD–í¶ô„üt:nPÞ¯ÔS`*od Ô÷›,[$™1å4`rXkB¡Ì¿½ Éäj+‡i}ó³}V¯ú©0¾3Á84Å6MQÈZ ZLQѯÐuÑ9õ}¶­Ug÷¸’¨¬ª¼žšr)«!K¦µÇTv‡´˜›HÚ´ÚøVDز}ªÿ&SÐ2F×£@•§$RizÕ‡µÀµèœ¥³¥Se¿¶x§´€¢ ˜"u™€Õì“Y飭SZÇ®,¥=Ïð6sPTùzÄJƒ/Á…ÕÖùªœ £ r '"o²TzýÁ¨Zy×R»à"pƒ]ý®àÊQ»xuêó<¿ñuØ¥S4YäŠûü3àùýºÐ›•ä¦^î˜êqeZá㪜‘0-ü1Fæ} Ú) úù.f2c ËÞGaTgfó _Rã.¦{< ÀˆÌ!^syN‰w’†§˜Î£¸SK,Û¨Æ7ê¨À‡<Â(!€2üH$Íô`6E6ÔN"Rà¢Ææh©êšp}Ì=õÏÙOÿòaú/¹Dº#p^°dË0Œ]êHë¤[’ y„1…§x°ÿnË]ci|Ø®@ŠÉ4^Ë“©S”ÏϨæµd"TâÍ4Fr1‚nc³ˆd›h*ÜD1›O§áYI'žMÅÚbåhƒ¡ÂhÞ¥«±#UH‰\Å‚¸{(‰ïÐ$M¿²cô/_̲º;Y%ÅTܨà ° i$1¾ÂSQïÑý:ê¢[:|·Ê³ÄoçùÒ×É«»ŒC£ùR¦s«ø³Çðc(ŸÐÎ¥£Lx¨ç,2\§$$h꣘~˜á[>¢ ° 늒y$toáòð\ŒõBrü:–õ½£yZ1x®?ͦ¼8—ìÂB°XÚ—–c “¿¤~`‹æYaùàŸ~”]EWrÊÓþ,b:#hµ¤¿ £L‹~Œæˆ$A%‡\ú9Gýýˆ#ƒùÜ‹Q-ô [΂Ø{ÝßÎꪅÐÂý +ù˜âšN|ÂPF00ß½Ì}Dqµ¹+¸Õœ¥{ÙVFW¾ÇæPH0sÃïçÝžO4¯5U§ŽÓâ×þµP{+úþeÛ7e€×šS„l<9PÕ‚õ½nnžXÑw¨c›~(æ`Mõ~ÖBÜŠŸÔ† ᆲØ$ÜËÎ8dªâÛ°$åΦ¡3ò±¬U®P™Ò¶yß) fÊÛSÙÚùûZ,…ùzãnì»S¨ëÐSÛ¹i·#ÊÚæ8ît¯¢SÕ}Z7¨µZYgò}±¼¡Ê·MÓç 2¦mS]­r븵&ä"ˆ@ùiI†ªm;³(©c´Öy·Ä5õœú'2{vSm§-gÙ}ŠP`)Ȳg¦tƒXð.:i=è®û&Zƒù,[¢ú% ]ÖÍVyrS.Õzæn|À§¤O Á“jüÒŽY¾S!Ê¿'¢x£½p…]nWð€÷¶˜#&2žvS+x¾AÇdt‡‘LSE-;ã°f»Q§ü‰|ôË@0,d€ò)r³üÆ_0ª°6àïO)¡\t?Êü™CUªíkÌÉT aä1šwË­A1+mTÇ-tgCÿ§j½ ˆ ‡ŸßîÁ†²$ØÈ]!‹sÎX„5—€ahùŸ¿Ó_×P‹@Â…û±!ÓyxÛlÞd »~‹¯þ›€/™¬d1â–·×Ó‹5Ìd˜SÔéߟ^ 2PM, £_ ÃÃ>dMä­”†]Ò|ܬ ¥ç¢•ë ´šYGxÀ&‡=˶°«ßó ñ*jvý„×’Ÿ#¯wWuŒð;Ê#a=ÉôeF¸0.ù²ú^¥Tßßxx ,` -Ýëq ?Ë„¤—Å<g*u㫎 óc$Ó0Ö ÏbYø”·¿`vß|Ò‡,à’çË0Ü…MQ×SÒê¼÷ï[Æ£kfF¾.ÇàÿéA7ž÷~˜Æba¯»)îÛñ¼’ I`.ƒ1 Ó“eW¿+.XçÙA’wËzÝѼ(&ð”ë;L z’…)w³`À=Î⊮—UŒóz…´°æééù„½ƒ9q(ÖÌpO%…úØôJ^M}R‹&ß—âO~TÅ´!1vC“ñPÐqî¯@,¤¥ÜäU Ú­5õ^- Æ&¿~^É‹5Q·2!ä%ËßÈ®ÀHjc[5‘5Xä}9n—«|¢[;vŽt)tí ÞçßµYðdøŠ3à €X,ÒI¥{[ˆEm¢. àdô»Îy>yÁdÆZG~bfúts!Ó<slÊ…Õfìn;’tÂÇ=áDO üFh0€Ú´]›{‘=ᜦöh(Oº¢¡:¡5C¿l' |‰-‰×4IoóÀk›?xévk‚ë^ˆïý¥vEWš¾4¸Áæ kYˆ³O)¡Ê™üðz›¾Šk3Ϻ\Ë£¢Ù1µ€N2_¤b†Ç#Žÿ &ÏÓÏð6 1†Ó÷ör½Ëh&1NIØÖ‹­Q`Gø‹ôˉèÛÚHžQÒ<¢eã/Yÿ[u[*°JàÓ?9ÝO…Ç­ürÙ-ȧòyCOåzùA.’ÓÂ:®ÏÿXÚEøN¤³÷å1ùZî’¥r‡|.÷É+ò‚Ü!KUúŸ‰üžnãnΉü]>’¯å.Ù']äœrFZ:háïËcr³¬vˆÐîBõ>)7È÷ò±<,»årE=©hæ"Š‚ý¸¼'-ä¬ðlsϯ¾¹Z¶Ê,yPJ'õ¼I]ß«hµ{ä2yO—Ëd𺒅p¤ñ¢È¥²_þ)O(jï^-ß°]ѳåWd¿\*È£Âgf¾{Ôïo”ÄÂGòwÙ/—ª|·£(ïÕøg¹F^’—„YúÙD¸FõÇ òŠ¢%ŸÑu>­¨ëÛ¥›üSžPûDxG„{Dn” òOyBvÈ•JÊ⤢É—vòÜ$¯ÊsJžà€Êë2Ù#ïÈ“²U®V4é3*d©Ü!¯Ë³ÂWª,<)òœ¼*äFEçþQÓæR”õÓr‘ì”+TúëD–Ëÿ(y‚cºÎ?蟊þ˜¼/Ê#B+‘ŸäZE ß¡ûåÕ¶Ç¥ì“.òž<.œÙ#—©öÿ^Óü¿ÑåØƒ,–;å[¹ExCdŸt‘CÒQÑõO(#r‰¼%O çÔ÷KåEi7åvãÿxE^Çå=õýn]î•ÄÙ®·É*‘SšžL©#È/r•ü*­„ƒ"rT§¿EKÿQ·ïN„}šfoއu:HÙ§Úù€’!‘_õïC(:øMý7%EV«2nE¶#;å E¿ßªÊ¿]ºÉ¹D¶K7Ù*W«gè²Û%ôçf]n•ÕrZ.’SÒZNËErVZ¨ñ¸G•ù'¹VÉZ|¯¥öë∖søESþ—+ ‰­rµª‡¦îà U}ïWr·¬–[Ek¹‚#šâ¿ù\îs’\øUZ9þv”éKýÜZ2`·.Ówj¾qŸˆœEî–¯Ôó{ôpX»#ºvèqýµ– Ùü(×É i«Úú3-y°[ß{NIœÈ>=&7(Y>SsG~ÖŸïQ²_ÈßT;ÑTÿ ºïDÔ¸úYÉ=œ‘–Âw¢Æê:«~Ö‹“–„£ÈÓò–ˆh „åª.|¡ägd«Êc¯tf‰Ü$߉ìUÒ.""ËÇjm=¥êÙUöÊ i+Gäù‡¼!×ÉJvà ~y]ž•r…’n‘n²]­ºlWÉ/rü¬d{:*)¾¡³’‘án8#ê÷_²ÿ•¾HÛ0ŒŒócýgò,Â0 0ŒŒÿX=YËÝÉ ¹mS*—K ÆT0Œê?-í©Œâ½Á£¸IÒ0*À†1û_J/˜B†0‡… `OT8Ë+úAÆ"€ñ\ɬg2c)$˜ï''ð&cˆe› ãõ;)𜽌ÊŸÜÊË96Ö—û¤#›ß'OP!»0"÷CNö"$“õ¦þ›/›EB÷ü­L(y™½…1›‡¸zã6ÚçW ¿0ºá=rˆ`ohw=µH9Ržçr§–¤ú <ßð:§\=ÙÅ †_0¾uË[ÿ§x°‚>|0eÄùo®Í¿¹e7’g°3ùÑݲŸiY3¼ü#NÖž¿£|²OšµŸQ…ï# Æû _úRzæ¯CÆx4âZûRŽ/å<ÅιœYußura\á«L-z¢Ùzºï:Zp{³iD—îÀ½ø §ƒÎcÖ,JQõ©iæûzÈÏéªÂuØ/Ó€`ú\5s%f}¯ÊH-¾ Çúß?ó(žTØ8ô¼öËò*>Õä˜nMÉmx”üj7òÎ)Öäù®J ÓYv!týþ¦÷èã*9ÔN)Û®^¹ß6µÔXHï¼Uêø°Ü²Ð6™S¹bÕË~íyÛ€m°°ðžóŽcJ°H¶+œ\¼çœ¤Ye‹µê¸¿±\À—ƒ* ~eÓùH…¡ mW.á¤fÝÞD"¡oÍò&2†ÇÏvb*~ÅǬ@ljMó5jpŒ³h²Ræg1dÚ ‚•NÿƒŠ©êlD›ÏžrüÿhÀtç1–€ŠöY²[HßsSaŽþ¬½ö/§ï?0©™ ôB}¤X‰ÈÀÿPžEj$!êìß]û6œV¡Aþµ4+`mÃ+ '×á(^'ÅâCŲ¿ ư졊:L!S”Ù`œÿ+¼:iÊÐÊYàþnG˜ÃI§wVÒ›TRÊ'xPÃdÆ’O(Ÿ0o*)$˜Ûê×ÀlÈI‚Q@<üc›$³ž2•Š 0™Ú-Õ®­)$˜LbXF_–ôƒÉðÈÌôaQd+€bLîÔRƒ¥ø;¬H È¡éA´QÏ\+‡nÊ“/åÔàAAdÇZz²cK4mºWñ oÓŸEy‰<¨Á/ªhÀ…Íô ƒ82o*Í»ÄI0…À¤ð]•D—ÀB0ˆy„’¯Žsì€ÉÕ²VTz´uôk_–PyDO ‚ Èª}[S5x^±×0™ÀÔ_ŧ+Ãz\ -ÚoYð‚°tžÜUþ>×áM%~”9&J©Ç•BhÀEYÅÊÏX€Éd!¹@¥W[ÒITG&å`Â×¶‘z(F”'ÕתHöE^j8D‘K'<¨Á7︥¯T¦Ë[¢~7jpeJG¸é:©5£Ú¿5žE§­ørèöð5ÜJ¯¢o`ò±¯0 \JUY˃`ªÐÚXy'• b„L ¸PŽ/‡U{š€©RYœ(†¢NTàCtÉKÒ# b/%$뀘´õıEæ€ë‰ßø£C“­,©=~KŽ©ö ‡òÈ‹ñÝu\7¨îÝÏ´Óª ì€i“^»ƒPÇ]02ê}&1ïÔ“–æ6˜Dߣ$M6«9Z’ЀG¨OhAA„”o±oårKË®U«çwÓÑL‰Pî~1¾ËŽ[¢º&`ê <î!¤±œ¹ã`“ëõ¸ROŸ•­R•73¡Õx’Pñƒ ¶¿âëçðÂk“˜”ù¢*›¤'ÝÈMùéœ uÁ%UÀÓL'Š}JÅ0MrÿŽ C’¸|N+éMHÉ‚pÐ-˜ê&ñS¨Áƒ~,aëäîlëpÈ¡ú5îô\ æQ3F9ij‰x‰‰`”Ãv_.‰)åèDx)îH±,úk€©ˆ¤üÛûªËÿ à¨ñÏã%†ä‡jÿ—ò¤õþÙp¶ìON{0’⵸sÒÇ›3ÃÝ1•êÿõt ½  ?–õ¼ßgÿ\û2™ñ{ÓkPÌ´2ü¸'h!צn¡kx—Ñd5¦ÚüVZ3AÜ` ýxÚˆâ¶Ñk˜Èx2øý€Sæ*6ÂÛ<Ã%o–áçz”±Þ¯³ÆëVŠéøÛÏO€7íÆ$ÚO*'Ìs/“ž%Ãÿ:ÊÝ/¾ðÃ0ƒá¤J§%ÅQÄ8÷WXãr+\¨Ÿ36sŸ1‘kfn#„Æ1‰ôÆÎ ö«Nôb<¹b¥ÒX™Îˆ 21÷LŠà‘ù3¹ÆM8¹ôd-Eœ?ŽÍUó³i_CŸ€åL ‘üˆ.Ô¶höÞy bC0Ú`}äÍ”‡œ¿­f2Œá>Ò=ègòBºRìß´_òcSÙtF”PÐýÒ ¶ß&KøyC¬¡i¾7±2ôv6^•>¬ IDATû\ÛÈýÇ"(õ¸„aA1%øÉ¦À4F’Mî—Ò×k©2F¹XkaC˜á.¬ ¿õ¼Áг£¯$0ôÐyë‘éÕ cz ­ôiK LG*ÛuÐaÁtzÁ×Ѿ¡Üp¢Œã mfV7>`¬²ü¯rÚ©Êñuó½þFM¬:26AÞ¢„»œç‚áe{qö€ú¤Ä¡ý=C (²“sþݡ͒jGËz´Ç² î–9D8޼w_aérÁyƒHw)/pj«bo5Ö*CÚ*vg(ÁBn|£€Ën?° ½.m–J€>Žôhd0ðƒe w`Ô 7ôØäÔÞ$Ãæ„kIÀùí³:¼5_{ @^³}è ÕI­¹©°‘ƒ”¯b°¨±*\çÞ’ 3Ïïòê¶qÎsŸËq–¥‰ƒ¥ƒû9­7Ÿ¥i"ÁÕ³9Zé¯÷‘lÍu³€?,™V˜¿Xrÿ¿•s‡p±·‹ðœO¨«pê?œï¡›¨ …íDàû?7ý«ExUþJ„ExRT0X¶ÿëé¾"Â/"œ¹XŽIÙ'å€b°½/B×?Ò"¼¥ÒzA^‘÷å1™%Ê,yPÞ’§åùP®–­Â#"°õÂ}ø–gT@ÝWå9ç3¹_^‘äNY¬Êøžk&=§Šíò¬¼.û¤‹—vrJZË1¹XöJWY%·)¦Û"pÖùyC„YŠ%²Nn–ƒÒI1RD1}J'Y'7KWÙ+|.ûê-‘ȲTî_ä*9$娴—ƒÒI~’kåcyX8**`¬Yg– ߨ~øLî— r£l•«å'¹VVË­ò¡<"÷ËgjL?­Ÿ{_„UŠ¥óŠ¼ Û¥›ì”+d«\-«ä6yUž“»äkÅlü\±»È>y\Þ“Ur›ì•®rBÚÊi¹HvÈ•òÜ.·Êjņ¼_„Ó"÷È—r@:«úÓì¤£Š•·G.ö¨º²G±p¶ÊÕrD.Ql¿£ŠÁ´OºÈr½bü½,2K”[eµbyUÁCå¸ h»U®–Ýr¹¼.ÏÊwr“b`ÔùîÑ,§cŠ=Ô^ŽÊ*¹M®–­ò²¼({¥«ì”+ä t’}ÒEž–·äUyN¾”{„Å";å •ç DNâè—Ýr¹ˆˆÎ*8ñ U9®XOËå临Ϊ®Çäb9,T mQŒ¾CÒQ~•Vò­Ü¢ÊºC×ë²\þGž“WEö©:žÃb·T,'‰È9Å\4ÇÌ/r•Ê—=Š=ø‹Nó¤zö„´®ãï°tp‘~Bþ)ÊŠqö«bÝÉ)ÅdüTPe<¦™bÇ‹ï-yÚÑßË rN Y,wªòþ¢Ynût¹wj–à)µ/ü*­D~RìSvjÖÝbÅh3ûC«û9.ª<Íœ÷SÅJüQ®Sõ]¬…Ž€ÅÛU½>—ûËïGUfY‡øœf#BøY•ãyA¾”{sñ¸f¯Óìµ3ºýLfã:Í´;®úî#ù»¬“›Uþ;õøÛªÒ¸YÖÉsòªÜ*«ÕXÐ̶7ä?Ê;ò¤¿ût[,E¾•[äiyKþ.©<¾Rõº_]w±Ü©úy« ^Í z®ŸÅ$<‰šGÔçßÉM"'øE­Á‡TPÞÓr‘|*w‹t”C²ZnUÁ5Û–“"¯È ò‚¼"¼$Â#Љw»|#¼,_ o©õ‚÷lkc®Á¤ÿ›—+]ÿ]WÐÓcª6¿Vï‚Ôÿ'Ít *&…@&"ƒþ3ùA1áÀ^gŸ¡÷ê:2ú‘®xáË©2/eízÛ9îܹ‚("’]ô™±‚ü¡ãËÁMÁÊùü½©¤/Ëèà *Gy“7*ŒÙÓ7–ÿþ#Ñh²èÎúÆ/#OÂIó¹—“|~÷óëI¦dP9ƒ"BKèC½Î\U½×ÌzvúER26€©„s«¤ðm]¥X|Þ®.asèýîJrˆ = ¹W–ó‹ýâÙÄШO(Ž dÃ-ÍÔi6Q……sƒ)"ˆ4Îÿ6^¹ 6¨¢ =Ã×Zz®Ðºý„Öî'ÞãGžÿ6¹„Ÿ×Â[¿ê Ä£à‚ÖÆ°¢}”¹\žä]äp·_£y×ák÷u¿¦Ê¨®ÔãWw o·JjêÎÒÇõ¨†^Þ¸Qç¤gcïŸæ>èSõ }J¿á|$̸âŸwCwikU`Ãa\\TK®õ眪ïú“Èýœ·iܨ€jÊ'D–ïn6Ï Š¬£>‡9†„Ìq´ €K‰ÐÏo) ®F“¼íÏácàn#H b¶9|‹y÷³Owbr~Qk±¹c6ŠîZ¦C²Tê²ú˜¸›©7jÀ Û¸ûsAb (ƒq¯²%¢©F“KpÊÃS=›I³m5,ýcëØ«©„iÞ# ÿÿØ;ÿ¸(«´ÿ¿gš¦qœ¦i¢i"B"""B–ˆˆ%3""23333×̵Ö-33kͬ엙•ë–µjeffffffdff¤HH,!!Ž4â4Ò8s}ÿ83÷0€Ö>ëó|ŸÝÇózùJ§¹Ï}ßç¾çœÏ¹®Ïõù¾QiÇ6¢´®ž•Lô=£Æ¡ *Ârr6o‰xcvjƒ½oGûÃËI.¼R:²û{C)k)Wãôy,êáåÖ9 æ¢oB%:öÆjói×vò´v>Ð)JU:]cDÚœ:úð,•G8Lÿ[®¹.rªPj8ÿLy¡œö:àݰ‘‘‡áœkLåÞ+À¤âÄ™@ "…ÿâ9àt»â"P?¼oÂßh¢øB¿­ßMpEܪòøgXê` l´c¦ƒvlìò8¡r¸òŠë¹¯¸3nƒ³«Éa3‰4`Ń;>LXðjý‡ùE{ãmHSÏñ)'Üwgi&ÈaÞT;6Løh#†ÙH?~\‚„<™tKà¤á­ Fñ¥:W)6‡¯Æ sŽJÉå5F¨´ÁZ8§°Ša,ÕŒ˜í¸5Òµ7ÚñU¤s—÷i˜ „S63’EdS¦ƒ >LXC³±;ÍÄQA&—N8kL ¹”’Iq4cÁK[¨ ª3Gª†TÊÉb[k&—;×E¹"s‡øQ˜i&íx°ÒDË8GR¨ öUÒI—sEí·×ÍaNûà{Üìg‡!ðA~!¹”²Œ¡Ü¼â%H„ç3n%›2V0˜G‡LE–+p=…Ǹ»b’ ºpi¿Ú±±µ9ÂQÔ`©r¢€Pñø² ‘˜i=;aú_ÃqrvYxÛá<Ý\FÎ3€g$:°¿‘ÔáœEQ±5‹¥¢Ó­:¬|§î%lÞõó•!°Ö¤ê¼ßèÑÝ– Õde3µw E@#èšBÇ*`~;"¶P_±¾œ¦Æþæ10nH\¬v¸wŸÔ“F5õMI$‘Îö†$5AΊ~Ž:]*üqL‚ß%Wh@¢óÎy,óðq;È!™-X»n¨f®ŒC§Ë€s9et3CP’=íÜú³ ̦4˜KÙ,a8÷Í~Líâ¦ÀCê˜Î´n÷¢'H?6ò±¥?Í â4O½Ç7LÀ8¿h3“™ÙíX;n†°œÂÜšsÕ±éNjǀN*ne23»éòdRA.¥4;Ù~#ù~uäÂyö2­º1BÙð3€Õ³/H¤oG§™Âr²(º6.’©ÓlÖR¤Ý63£yIñQ:5 ^†^‡ 4Oe™ñZÖ ¸gqàÒ€˜™l´“D=~ŒJúÀàÀbð*â6û£"sáûîÀÌšøb°3?GJâQùDï3 „:ާ™8Tßù峞Vœl0ö'ˆž<6EiAeR7.ã‰ø1bµ* e#bÓa üÄ0ÃRô>¡Ät)Ù!×T/bhÿãhÚ±áîV€"=NÖÚŸèHé…¹ã磩4AlÒN6.¤_ǧxÍ 4u¤*®‘ƒÝtäôƒgû.mêI«ø ŒÐ’r2MÄ“Qÿ%èÁs4 4‚±“ÂsÈÔx6ÂÈ=†*Æú'D¸5+c¯bõr½ŸSc9 §Aó¥Ì›]ûräâC–ž4Âõ I·pkËß#Ѥ4õ~ ¨}Oý»¿â#Nv=©À9”!ðDËh^ÒüS¨UÓlg#òD´Ê7_ò1˜š”V—@ô‚¡â€’lhû–`¬Ž G&Yî/°tìÃâÛ×)”‰æˆžˆQpg¾UêY¤z¿†Í(¿ÎÄhÎWIÂ¥4Ï–«j¿pd¯x⎥„Bf1‰„êïµç·ŽΉ¯Â&N–S•P•yW¬Xƒ ]Òp"Ø uxá¢ü dP‰ ŸŠÄ%ÓMŸ*Üöô·S¶!›¾™•jn¥wrž³Œ3ãjùfp ’ j.Î=Tp³e ô~$ÂôŸa:ôý´Ái1jBЇ~ÿ:`úßwŸÀ¤¶Fíÿ¥ô N€?”¨ZŠÚ)b&Rr6“mDU¯…h9[ëÞˆÁvS'ÀäS@Èw¬2¾nAÓ‚Óî³=rŸ¡rÄ99nd%ƒxš‰Ê0l^WƉ<ÂT±’üÖÕ¹ ›ù¥ä¢Ë„7+†0Äýåös9¯´–Ãü§Ç0’Eè ò£¹¥z4ÂücÈ ’™LæM]PçÑ·¼’$êykÈd¹J½! œI-ßT¦ Jô˜Ð!Ìt¨çÝ0áQ{ˆýYñÓD|Ô;æA¸ÊÉÂI+ƒX‰ 4âÅ‚+\¸pàÂA" ø1F&í×&ìë•Ïzí] ÿ7Žf*É »i+X `&_â1˜÷Óœp ¬Ñ€©m;­1'©t§,§aÂGlp§W|Í®W`7 ˜’B “ûG3†ê`…†øÓ°Ñ޽q‹n@Oá.åÙö‚ãÒ¨&¯å3ÅÞH>ë‰kùWì‰4G¦{ûQ´ƒÓ½‹J{_Ò¨ÆP€–¤“ÙLƒ[ÞV{·j¹ &‡tË*°˜<Uï¦WWƉ8Ü»Õ&Ì ‹3o F%gÒêÎ?›´_©ˆS,K¼–¡¾7•‹÷‹×@4ô ¦¦×¡¦?Ì4¦cÜô‹Ê4懞 ÖÆŸXŸp1Tb÷ìQ‘:ÓÉĶì#øbŽÁÔ¼?’Î ¦XèÈì…¹ìçHTÌID·ʳÏ%ˆžlßÖˆhX’#ŠÌï3Ù>ˆDN›ÔûŸú=ã˜Ë`VܪÄLÝŽãɦŒz’Âræ0žÚh ‘1,à³ayœ±´Ž% GO9Œç•y£à–R87·`ÐM‚3fÕáÂÁÞ4R­$ I6€l>|ëÒk”#íiŠrÀa%ŸËlA é@Ÿ˜F7{€ßšÆ”5 EÊfàCs!oÏÌ»•ù”~ÿD?Cb` ‚LÞ¶ fþ³cÙøûIB¦¨(ʆs‡n8çSÆc%õFš«JJï× áÆ‘‹¹²e50õ7É%H>ü «àæÁ/qéÜu g óëfËw»]§Mâ®qO3Ù,gHTª[;ËÍ/#+Ä_³'ð@`úÁ¥!êa—®œgfOd‹¹Ø³"ÖF¹žwm ÅõºbŽ]æe:ÓXÎ5•5XͦðO3‘Si¡„B‚=L¥íؘÍV3€IÌbý©êÁ·…XNÝÌ#Le…ãj¦ÛïÇkìÝãìÜ@"7Þº˜vlŠ´ßC[C1)Ô²‘~,gHß9uX3 †Ó¨ ³ÛûÖù9äRÊKD³u!–·;þx¬ö½Ìc,!xTÔwêH#T[Ïînø `uÔçMœ•¢“2Ÿ†›{¼öÆø>œ>"R=Й¼ïqËDžÖþý£µkXÎ:콺õ™B-íIÇáÆŽ+Ä@¥¥/r.Š"4ƒ]rô¼q '­wi©A_æ1¬b`ç|%uùg0™™á›™·ÈL‚{™Ñã—$_Ê‚ìžÇÔgœN–y+4Ñ%¿MSö©¬K½„˺ÿ~6‘Çö.žR­8™ÈÓl"Yzˆù¦¾$ƒR5°¨îß]Ú%íyø¦#²GÚ¿Ó³}Y`«ÀÂQ¡’z¾ù×åNázQÄwˆp(ÉÞø'ûzU¸D„7EN•ïå\Ù*Ê'ržl‘“åáž×~¥ŸÏ”¤Á6‘e—\,ɵò†\'¯Ë…ò‰2+þH„«D`GÏ}üI„ï•aî=ò¸¼#WÊr©¼+WÈ«rƒ<.÷ÈÕò–èä€pB×ó¿®ä.>Tç¿_’çäOò¢Ü$ÏÉŸä>yX®‘7å8Ù#œ‘*€(™„W”ÔÂ_äQ™/7Ë›r¼)×ÈËòyHî—Ëå=a¾suÜG»Ôø­J‹ÿ,“ûäa¹G—›äE¹@>v*#g. w£’T`—2ú½D>”kå ¹LÞ—Så{õýÏC¦ÕÏ«ï$;åzyMž’;å¹QÞ–«äu¹NæËÍržlQ椢$‘käMy[®’åxÙ'½dŸô’=rœl•så¹Qž“?É-ò¼ô•mr­¼!ïÊòž\®É&|*¿——åÊt§¨2ë"/Ëä¹P¾“>òœ!ßÈòŠÜ(wÉ“ò¾\&\'²MúÊGr±’IøY•ùï—£e'ÏÉŸd¾Ü,""Éýòwù£<,÷Ér­¼*7ÈíòWás‘×äz¹JÞ–«ämùZΔ¯ä,ùAN–=rœÌ—›åNyJ¾—Så&yQd—œ({åX͸ùk9S~“…WEî‘Çå]¹B>Kå#¹X¾’³ä;é#ìUr _ÉYJö`—*•ÿNú(SÕ(ãèäDI9¼-WÉÑÉ÷rªÜ.•íršl“¾ÊˆúgT)º„Œ¨E&‡åd·*תtþs9_ž”»”ÃN„ïEÚîRºçËçÊé%²G]Ïò™|$+I€ýJ&âc¹H™ï•õ®J÷¯—×äNyJI |ªJñ¹XÔ3û8dÌûr§<¥ÊóßS×úܯdö„ r·†îu«2Þ= :áC‘'än‘­È•òŽœ!߈|1º=U¾Wòß*9ŒÝr‚2ûÝ¥îïùLd2äÝ.§‰Pã°Oz©~¶)) ù>$!1{Þ2…þRÉm|#gˆ|§$xT”$… =‡mÒWÍK7ˆp2Ç›M‹(cäód‹ð­Èõòš&òŒÜ!™{ž—[d«œ+÷ÈãÂíæ¤ËEnWå"ùX8³Óç'‹œ,?¨ßkŸNŸŸ(ÂM‡wý9Bú>Òþš]UÍцȠÃÛõ CÑņòù?· ,mþë"h'Ƕ`˜À5a0ºf”Zùjàõ ý·´\J1äðç+^‹ûª,PÒúÛúH ‘jÆRÊÛ²($ƒ…!#Ë_¯ŽLCUº6;¨' 'FØ–“}œ•B,³ŽÖ1NŠHç$É`×"‡J¤¥PK¦³‚€Ó@e~:Ž:WYÏß·àåç:¥Ð-êq±Ûå8äµÝƳ!NÌÆcï1:n1´1U0(ß¿Ch&ÄÑÌ\ÆšˆçF碿—J ™T` ÀÇKÍ·|ž6ý ”SÉ`|Ý¢‚yl"+§=A’¨×Êï;·tª´Þ@VÅH8pñ݈,xµ¨FÍZo«5ë fÐÙ[ønd‚fw ©Gß*˜ÄІñ4i$ï´^Š˜æˆñïÔöG#–6À(bmT•|ïÅcóDˆïñ4)ÀNÍÖ±7ªÄ>ƒJ&1‹|ßÇ,6Ý𫿃yŒ%ˆCeDJá»õ +~‰úÞ“Y¹-ê³=e¶î‚¿aEwàñ‚{ÅBpAk£;Ft%vSÆ<Ä ýJí·VÎïçþ´Ç(@“k˜ŸÔ“܈2Ë·!£tŽS§æ¤•ÜÅ¥ÜÊ äñ>ŽéÖÅ™Iµ¼À­Zj<Šò`/¼e=FlYY”ÓL\ôç6´4~·æPTÿÌÜz¨v0iÿf©ºQ]8E›Cd‡ÎŸ­ ‘•,¡Y ‘1‡è3½®R+íŒV->92bÑ …W€øºöÕ™sµ‘gŒ€I@ôŠïˆÒ96΃c¸ Ãð¾%&Œ˜ù¥ÆgÓEŸÉN׿ÓkY‡fQÒu¡µ§»ñµšH"ŽííIª164÷WÍ[WqjVù¬×ìQ"ÓÍ@V1а Ï(+£”µÊî,v?æàáG¦ÁKÐkX¹”’L]TµY2udRA0CO{‰M#p?¾dŠâk †s“ÊÉ¢0A½9.¼ú² IDAT “ÉG¼wnËñ“é_IHìxe>ܦHÒu¶3Èa‹f Òê<‰â¶÷UúˡԸcŠšl!½¤¾Séx±0ÊøJä¹Õ½®0^Í€ØÕô|Â2õäÄlaƒþ"Œ9~r›>ÇÒºóX-å•B-ñu;Ôa„ÖÜ“¨&‚æ4 ’Õ¶+˜Öþ°â@©‡HeV_ò>î¦Ñäð캖|ÖkfËzŸ°ÃÏZÓe?À‘|ÖSeì«ú¨C½XÀ\þ3íY6Vë¯`ïaöüLEüïHޝÃÒ±üÑ›~éŽòŽÁÔ±ê!Ù÷­/K·Õ1gc @9YXðbôüV5® Ìc˜_6–Û³ç0—qQs` ©*u¹ †±”×¼«´TãsîEæ„æÒ¹p׸YZZ/ ¨­Qï÷FúE߃éˆLGÚÿa•£í§ÞbÑéT•Ùoï·«ÌC5غX8 ùÃ5¡ˆžû£ Ž»s°ÌªŸ‹²a1ãºÿ¢OJm]ЩHè%ÀÓAÈ@çDùË †ãSÜQ ÄLÙ6`À;ÒB<±ðÓH;>ÚÄB….˜¡ÀB6P؃ e>ë)²¯Å7ÅĦ)ylñäðóB3M.à£ÝF¸»Ü7Ä/î¶Ð;p‘B-Ã×áÂA © €-Ï‚ÅpiF IÔc鲕M¡–tªh›C+N6“ÃûÕÅð’â}5)ÀP–u‹& b%†Ø5±ê\_·¤òõðTeÆ9ޱû¢€f¯Â ”|æÏã³Íy}Œ `u·{Êg=ƒXI+NªIÕôc «Àê£E …#µ¤°ŽªISåÚ]"}·ò>Ll ?f:°à¥'ýÙÐé-n!–ªI£3%úB,x{|v£Xˆ“FÜßL~Œš`f˜gVE:›Éa»ñYÚˆÁK«j›ÇXŠY£Q=ê݉¥…Ú¨$ƒxš4˜J ~Œ´™O Üœ¥ìH¬ªß0髦藫{ìØ Ðb‰%Íûµ"zâŽÅ@€6bHæ[JS.Pß c;kHÐ2ˆsÙ”)ÿ? ÔÎÔžC«ù$jI¡˜5ZIûÓLdpðm¸"œ¼ zVËM×0$ðK בû9´©qlϰ1 ù½® \¹‚É7+ÀƳ&èÈ饀Zƒ¶‹`&“Õ5Vv”úPôÇ÷Å?B …y?ÐÞå¶„ˆiøŠg¹Ð0ŠÙíw’Ù¸–„X !“m¬NSÊü…—âob4/C øbÁ@“Ä›.²[¡Ù~ q?(Ѐ4ûWZA¸Mç~œ´RÄZÆeÏÕÞ zV0˜jÒ¨!•8šy2g¡õaR¼¹• Û LS`)*Úˆ!ˆ ]“n2œ=ó aépu4µô$cs0iG 2° Øiìòïe(Á”°Š[é¯ tФu:~¹ZoèJRÎP‘)Ü@-"ƒ{è';*:öÓ¹… øäÃÑ]Ôñin i¼-躢|¸NèßÖM×H1Ö*|£L´Š¡–¾kSÀçµ;óàê˜ ½3½äRÚc©ôC‚´±ÑHïWóá†BÍ9ýìÄjÒ¨îùÉ" i|O›pá š4^_0êA7#H µÝ"8ù¬Ç cƒŠ>m#“ýU&¾~$ÆÉ`ˆtÍùq´ÑO1<×|4.7ˆ/Xñë ǰ=AV0V\8ÅÂnZO±´håÓmÄPMz‚4uíá´™™iànÅŠ'*Ô[ñPJ.u$“@#ñ4ÑFŒÖ§~ŒÚø0PB!V<YÚ„’MÄSK IÔÓD<íØÈA•y°2”ePA&ÉÔu‹°)œâÑ$ Â@x%ƒÈc.”›²´t¦#ÆE)¹j¬Œ Ä (<—ùDZqb î‹JÙ-nHT•†¾ý`O̱8pQK )|CsÂ),b$c™§®Ýz,#ü¯~$MöSyš‰Ìk½E™ÈÒŸ Ì&Ç¿€r²¢æGó‹ÉÀà»ØqkÅIÔ³Äp=«ÈëøŒ…æ?ŒÓáÃÄ‚ä›Óú"¸ >®©s›1¼I#;`UÚ•Øh§_í§Ú{¸Üq “™‰¾TÂù_æ0ž% ï–~È*ðª(o ±,d“¬Oi ç (`ç¶ØÉ«à‚-頻áÍËlHºˆøØ&%¶Ú!BhI?™vl¤º¾ĵüÐ=Òlu$“ÆWŒc.íØº:”’Ët¦1˜ÜÊ ØqGùÉÍc,ÛfdÂBøsü³¤R£½Kk(Fte 9èŠàŒµuXðÒHûÇ™”_+!‰š'…"Q‡/Ôt0ý5ÅÓ‰S[:B‹rñ‘ùUõ+ctv!ºT¸ü ?"Æ_éoH—çRÞy;óO\WWfD§3çV¥ønê(SÎÛ~ºF€Z¬(Af ¬*ŠuÎp˜ˆRî¶GGJz;¼Ä jC?(HàY&0ÀÓàÇO½¬•"e•sÆÁéñõäuv³D‰^³ã?Íâ”pûzØ7̇odóáe…P §W"Ÿ]- häžôxÓ-4O ©|åJã«Ò4˜ L…ó 6“¬I,GGzŒY;•dPK _/KU â¸ÄÖÝúLj1¥ûp/S åÒªçç{ÍjáúYåF­ü›ë I yá¼¾n8Ç´“B-ù¬DIBàÅ‹ *i ‘u '¨ñ ºUÒ¨Æ@€Tjh!–Mäi¤3¯#Åç`@OFXÉ Ùƒ·Dx1¯"Rr{üN&š’™M½…Xl´ÓŽ ?FMêa.ã`ÐH 6’€€–†ÛLN7¾Q¼ÛhçYnc i"^‹¦ñSA&lý#BœzÐ )QknѾp¤¬…Xr;>Çev(°g¯'™: 𯌿 =AònÓŠ“ym·°Ú|…ômŸ« 3ëQ¬¡X%ëѬv:ÖkýËtQÏ?¼)XÄHFy^¡Ù‡×ÙK³|8îcªùÑh^j’Î"•eÅÒÁ3™Ìf£ßR‡×ƒ¿àh–y®‹¤ð¡&þ,¬xèïþ$ê:F°XUˆ™Ôu_?c)ô¿N;÷fr™ ~Xc¾œbÞ‡èoû„51—«çÖå±ç’šªPHjÛ×ø!EûP $…!x¯¾7öa¦Cmx:¥Ñΰ̅?Ó™F,-Q¼·)<ÆÖÕÙ\8`#Üû å ·*Òù¨¦^].][¢é‡};#™Ûiî qY] Òï°­%GdŽ´ÿƒj(")ˆX‰Ì@ÿJYˆ8± âD$µÇèÒoëËŠä˜`®…ÝE~žm†ÍÿLÑ*Q vøA·Ž/,Y|UšÆî˜ß؇™¯vþ¯ ÅüÆòjÓHÊ£ìàrüZñêØwtI<7ü6ž¨º—yŒ=¨/›Ö>ñÀ¥^¶è²yU—Æ3«&òdËd6‘×$Ú­_ÂGÎÞÖæÍ’¡¼W6à×Ïwûdp’—_æÙ·ÊÒó÷‚°W×–¬Ÿ2…»fñ 2ó,÷‡[§q;ÏrVJ-/1šEŒìVÞ¹ÝÙ0›;ç°‰<®mXÞãwÂúSèÏBFQFvw÷vT¹ýzòÉ ’…Œ¢š´ƒÊ ¼±i˜fÓùúý1=žëDW›R§§?èÐkÇ\nô/fëleoÒ¹y°2› ü¡mOUO¢'æ-žä^z wÁsKoÐâˆpå¿ó}.ŠàX+üÔJ- <‚ˆþËãYŽšE‚¨í˜h<¨ˆåÿ—k,@ѵ²Q aßÁ¹zJTò»ªÉìê>ù#`*µŸ §Ûë5_¶]~§âMlõõI'#K­%pþp 'Œn#†6 ðc¤»;Boc@zÐ»Ò S×ÚÇÒ¨¥áÂDb7vHä³My°¥˜Þ¡ïEbÐM‡Ó§ÕK q4kQ °êõGMêÜãí+Dœè&÷ª[,-ÚýîôÅ*^È௭껉  ›†ÊÞ¦ñB †ÆÆ ´ŒAUR®†³2kH¤A³.1@OµaÄÏ›)C9®V™çî¯1ñdê$-•¦'ˆAô4ÏbFðACÔÃC…ÓXÄH³‚$ê£|—2ŒÏ7åò—¼Çx|íÎ(ªc³0âÇLMÄãÀE%<3}"ON›ÄÝY¼g(Ö"5aÑña¢”\f2™9Œ'ˆžRr)¤Vâhæ:–чF0FãiMb>LÔ’BÄÒ¢)ã—PÈú3¬&L*hÅÉEº1l•9¬f¼8i¥‘°V.ÒGäZj8‹FH§Š¸öð؎帀ñêØl;ŸÅŒà1¦`íø‰¥æë¨"IÌ"‰zžf"Ŭ¡”\œ´’Ã6pq4“Ôºb Þp:Õ¤‘Hé-ÿ@gî²Íb*`óî¥ÑÒ‡©<ÂkÞˆYÇdý¡ÉÝ ¼çCÄôìlô]ªËWß%¨r=°îW}îþ¿5 ;˳ ƒTtn”rùBàíƒÛ¿t ÒÝÄf·`Ìö¯§³"_.GqŸdÑoš:zg{ñWѵU ¯4ÀþÑ ×ÅòØÉÊ+ÇŸgÄ=ÕN.ñ°7Ýš_ ™¹%þ‚ñz\ÅIàK—Ýú_¹ØDÐÍ"“誀G@7(–zjñ(B肨ôç!ZJÈÁöžÚZZÄ—zðߥ“Vc “gLTJâkc™ÇؼyÑóç¢g{tt÷ùè´)Øqs•aåAû‹£™BJXËzriÓ¢ Ó'g¬©1ˆJO%S§•x/ch7>W×s½#Ë5SgP)CŽÞMðï|®-†ìè€Lð'íïa?™™$Ҁ÷§)»j#¦[ª/Mĸ•dÁ{¶b2¨T–#¡hLõüb1h)§>™Š,¹8mL:7.þ:{< <Õ6¤H%Ÿèu‹±ã&»ykÔçýØHfÅ6­Z,ž&>5æ‘×ð]n‰"ÖF¥ÈÎ=·ò‚JÛYàa]ïHy8|ÉP–±”a¡ðЙ.Ù öïÉŒ¯ÐÎûvlDÊe+ô€Fâ³l \Øhg0+h#¦îÄÿzеÀ ±m\òB%Füý-èÆŸTd©ã¿gŠ=˜þÍSK‘E½2´ îÚŒèÒP2ñ¡rT*þ³#R*ú–„ÚjÔ#’ÿƳ§TSZ0õtŽu€ ‘áÿsϼ =Gg¶/éÝTï^ ì÷&£[¢¢ 3)ïñI‚*ât|Œ»ÛyÏË)£#ÇŒ{–‘ ­æBÛèt:\CPní)݆Q}>h‹S ðýDZ|n¡w†—,Ê»-d‰4j­!PlÀWlby|êësPܳ1pl¢G#)w^\¯p¬Æ”ï#o ŒlvvÄòíÚduìT7,¡Ëõ„þøCý·+EE’íZp9@ͦ_·¦òµ=•÷êÀf8eL3vÜÑ‹*ªª/*š‰£‰xÖPŒy=ÁnÄý8šYÊ0‚èi!V6‘§yv  Z´/¼S¿•¢ú‹¡:’i$ÚH¡– I£Z«$ “xšÈ¥T³‡±ãÖHÑnì¤RCÉŠÔMýÙ€c/«3éTáÁJ5i¬'Ÿjµk7 ‘츱ÑNB(z5†0PÆyø0i)·fÛ)Ìc¬ªN4«ë˜Î4­”߇) |˜ðL&é§¥¾ZqëlÁ…ƒuh•sͱ§K©ÒhÚ,'Ð@"yƒëµŽ3±â¡1pš-FûªÔ*óîôÏæ.ã,ÒÍUQ)&ƒÿ.£ƒ©æ‡™j~„<ßg¬2]‰;öxô¹Wÿ8eOAß"µ@™í<|ýŽaã™ÆtÕ-)þÑ a9Ž²Ý‘=¦Çܯ”Úën£6- êhÝ­®ÛgJ¬âµ«÷ÛI+’£ç…Í·2Þÿ7’©ã¬µµ|Y”N:ÿ€¿ˆ—Á{€AžwX{ 3™L!%8p±ŠäRJk(Æ‚—lÊpc§?¢qd¥òSK 9l&†6òØD=kc‹B¦>.Ú±±mY&\×'9a¸Ú„éªBs`¸-:üÑ¥#€é? <tYÌW…Cwn#øHˆ®å#T ,©þw½ÿCÉ ä£+Di*…3n Àg͈Äý†¾;“³G$º®ª s”“HÆï}w)Ñõ·B>PÜ€2….˜Ò5¡<zvwõγ£Ë°Ã05ñ’ çʺ†Lº…Àq° ¸+ÉÒé ð€Q¥{ÂòñFhËTjìû²•O¨‡+ÆÀ8ÓYKõÝ¢&…”`6u ŸÔ|óš‰ãÆB¥?“gÆÔv;.“ læõèñV¢Ÿ-ÄRK fpêÉźG‚zµ(W‡¢eÍP&5Î-ÄÒŠ“T¦CNËlÀ½‰>“ ì¸Ù@-:SNÓ™†ž`Tå zË<ÜÊ Ñk>]+NUúU¸±DÅ=Šh$yŒ)dPI?6j©k/œ W8µâÔÒ{.¸±SC*1´±™2ŠyŒÕL¦G²H3!î\‘Ö} CÍÄO“Fwà"—R”Œ÷ãÅ¢åfÃ)˜é #ø%Õú³I¥†ô.>HaÃéJ2È¢\‹‚•“E–½\3ÕØà¼ˆ&â)b-VTˇIÉ0x8*7*ϵJßïXK—×1–yè½Å¿jÅÉ`Þ֮ŃøàR©a÷2Ó÷gPF69ö-àSZ]Ëâ®e¨ëM&8fGWiî”“Åøò¿Eže¿><ÍDf2SÙ~•iÈ…ÉÎ'ÈcU}#ò¡é*ƒJ…`ÂÇi›C_pG÷Sy„UñWA"ñÏe“x |0$øcôóiÅI µŒð¿Æ³Æ?kÖR¤û'0›ÉÌ$F͈:€áÑH>ÅŸ,¾Q;œ£“ýüRÑ©HçÂPF%_­"Ñé!2ò`:ÒµÈw-­_' ïYŽÂZSA×™g:ø`y·Ê°—è›N·±û h íF2âÐ Di‰x€¯ÚC)·!¿ñSí¼ tÉÀ·^`ÕÿH$J6tP‹Oi DtkƒTxDWZü¿  LöªÊ8Ô ÌVâß)@r'|Ø„ß øB‘¬Jà|´uá<•Àˆ_ÛY¯¡Y«‡D8-¹¡GÙ€dêXÁ`ü1áà ^F°8*åc  íÆÃ•GíØ¨%¥Çô\ mXñh&Ï&|=îø7Пz’´HØcÝÙµIÔSÄZMrÀ 7v ˜é 3éGéšHzH©L¶AÒtáâŠÿó7E6þ­Ñ- ºæÙsÐé–"2ì8zßõ€/0Ò-Øpœr2!#ݬp̨YÕµŸV¸ÔÙ­²Ek¹À¨LtóB)­a(+˜'j<0® ÎO§G¿áÑ¡‰Ïˆ&ÔG#ìZìäåöѽ‡{I£º›n”7×ê—áÏ2Ò¾X)ךÈ{Ã(ÂümÐ;ÞÛ-Òc @6e&–H4àÍ·àÁJ ©|Ûš ·…Òx] ï2CQ4SèzÛx«žsõ5«‡Q½ ^M!ù»úDH„SõMìÆs©>Ü…U·3/R¨¥š4ư ÇáϦŒн–"ÊÈf‹£Å#Qœ1íø1RN©ÔDE2HÄŠ‡Vœ,d…”Ь¡8Jú!Ÿõø1bÇM>ë£4v:GªjIѪ-³‚EŒÔ@° AôŒæ%%ÄHÌA¤õ5¢ø"Fj‘+6ëϧ™8hć‰%ÆáQ©F ^M5\ÉG³Ò2«wÁæÛ‹Ë¤Àêr†0’EQÒ ³íwhäòÎïÞ”àãšf©åÖRÄ îÅîÞC‹ýdZqònÎ2:¾ÔRuO–LffÞ=t¾U7vbø‘$ê©uœIŠï&Ÿ¢D)ކ¶*­™ªÞ¹1/jR  ¦¡™ñw39ðd”fKþɬ£@IÔkyoJÓ/`.㨠[ÅÞ¨±Ž§ CÍ•rô©(Ñ"F2Óp¸ Ý^+à…ñ·2Ç8^ªÏrÓ˜Ž“Vú³ñÌa,óH§ŠjÒ(%—¬¦Œlì¸5ݦ\J»rï8èmð²ß¡î7†6v&ĸÐFåþ.~8lÑ%õ¾iÿG#PC‘¥ ƒA²Aú E ªÿSïyR2ägC À¸Ï“‡HR|».„2ÿ7C""F¤d^èÏ:à› ÿd?N¤ä6à÷íŠS0BçßÐG:²d&ÈTIÀë`ɯøâ2¸a^,lѹySgcþ°±+ا[ÆÊx]—Ì+ËFñÊêQ¿~Á *'ÖÐo¥@¥%Ù6ÁÑ:0³ïY û -ȺƒO½;6ÇÃQ+øÐ_È;KQIoûºËT¬¥ˆOV÷§„B®\¼š«ªV±‘~<Ëm=FŒ:·‡ê‡ÇC÷Rôvl<7ï6^{víØXÓÃ.cƒù‹.ÅŒ`œ¨Ñÿ®m{« '¾¶b »¤µ«Iã%FãÂÁL&s^IyÔÿ {‡µcc&“ùó̹=F&:·1,Ð|K(d=ùÜxIÓU*5^Ýl">J²âïP(ÊÓÆ ¡‡z–ýQL°>õ½fû)¬`pÔ=GÉ ´Ÿæ2Žpæßo8𠙯te÷jeDî3™Œ7þ˜£¨1ŸEç!yÚp§ÚlX#ªîaõlúŸ™ÈÓŒgŽöqGn/V¦_º¯Èæ00ð(c oÍûQ÷ñ0?},+PïëOÇðæÒ¡Q÷PAfÔ¿ï˜yHî—gäyO.—åùD.”·äjyYþ |-r¼.Ë}?Éeò¾\*ÈòŒüE•»å ¹ODÇ-ò¼ð¶ÈíòW9Y~Ód»Ü%OÊåòžðžÈ=ò¸ˆ¨¹âE¹I®—×ä/ò¨v¾›äEyTþ"oȵÂÏ"Ü'òW¹]Ø.r‡<#WË[rŒü,÷Èãr—<)""WÊ;r‹ä+9KÞkE ßÊéÂ"×Ëk²KN”wäJùP.‘_ä(y^nz‰|,É~9ZˆN¾”sähÙ/ßÈ";‘}ÒK®“×åyF^•Dö [ä<õûø‡Èv9Md/ò\*|,ò“ôÙ‹¼)×ÈuòºüCÎÙ…ð–Èò”ˆ ŸËùòŒÜ!ßË©"?!ò ò7ù³Èõ÷ åuý¿ ò9òŽ\)7Ë|ás‘Ýr‚ÈWˆlAäGÔ³ù@ä}¹Ld/"Ÿ"ò=ò®\!çÈ—ò•œ¥>ÛŠ|!¿“^²O¸]ä¹R~”ã…/Cïî»"ÉŲ[N;äá ‘ùr³l“¾ò¨üExS„"7É‹rœì‘Þò“šƒT¿]„æÞ·Csòå¡ß½ˆð\è׈À|áþ¨~_‡»IÉý»¥ë C¼“,•8ÉЊ#{¼vx!´CÿjÙ”cm×o¢ns2zÒÔÎy Š<ëD…o7ÿ7É ÀÕti=÷­ÒzI¿¹”þ7ÇcGÁ)Žff6b&†þl •òÙÓjW‘‘»Vÿ—´›tººÐ€¹~Õªåð¥?Wþ.U˜Š"^&ÆÑèÊ€ÖNTTEêÃ3d竲«ÞP‘ _‹2YQÜ¢v`pŒ*Až¨ÒŸ‚<Õú‡îŪ¸Ì2«´Ú²C–K©*‹.hWv'ƒboexÉ”±Õ•Ýý $8ÑáÂîqcŃk´mlŸië¦nG;ý$8ÉÄËù1~*—f’«'Èí›ç`ÄOÛŒ˜_þo§ Â@€–$Q¯ªŸ`¦C‹ÝÅ,šMqØqsû 9Qž|Ö.ÔXZ(î“¥†{ƒ1zÆ4ë#bhãøD7éT‘HƒÍ ËJå¹…ã¢ÒŠ=ÏWkÂ+*%˜D}T鯙ÝÑã?h_À†tªº³à…60:üü~ö&´ŸM™FªÏg=ý?öÎ?,ÎêÌûŸ™Žã8Žãˆ#RŠˆˆH)Edy)¥”FšÆ4M³1fÓ4Mó¦iê¦Ù˜MmšÆ¬MSÍÚÔ¦©iš¦1¦Ù4MiŠiJi‘¦H)RDDDDJɈ8œyÿ8÷™çÌ þê»»Ís]s%ÌóÜçœû9ç{¾÷¯‘uãÚÕy±b×ÒyÁ‡"ÿàR ©#uìÙÈ{ÿV²ÏÈ«ŽÃ—gÝkÿþˆÛ?I\ý÷~ˆý|:êílšy¥Àƒ§éÕ¨¹4ε)«CÌD$Ó­J¥Ä\WßׯtÂÎ'³b[0+áç¥qé ©ãý³[y²GE†ÜÇmìd¿¤÷Û[ñ1ÄÌTü1²ØÖ‹Éÿgåþî­—gSÔæ±—px6[/Üš¨Ì ‰†Ee=\ZÒG ‘¤pvBt’JI<ב›„ÔŽq~1¼ÚŒò¦-“ œp8QîgEiÙlC„Ã>lNùÇc[ üé¶™sáR²cwä©ã_[ȧžCÌä.ÏZ‚«\Lg#¿²Ï$ŸzVs7 ôÇ ¼ÌvÒ©dG)ç•~¯9m⋱åü— |¡®Ê#ܶ¢õ0áÒÆñÕÚ‹9Ž»l„‡ó*øOßJÆpðïwC9,gk$Yà ñÐCDùê$ÑÃ>Ör=$QE3*I_ÙNÓÊ|qÒ€Ÿ&Ã,xŸ£‡|êé#Qœü©7O=}5À-ýðÑx¸:žjÔ¶ Y™ m¶]ðŠ¢õðå‰Iè6”¯D;\à•1/:†8YçSn`ÍÀ-ƒð™8øq·¸ ïU:Ç©Yж\”îÚèþh¾JäX(Ø#åðÝl_¤D`>’_‹ ¿jœÎ?å60½ô‘€­c5œŸ wÁ9%£œvª‚£ù(ÙV¨ù¸º´§2¸$¯Ÿ¹ì£Š J*Žáf„½Ìã¥b?áãòœ–Àë›\‘…ñ¼¬^«qsÁ’¯¬ô³ñpE'ÜÙwæª1ªƒÐˆÛ–Duÿ$Ëp=ÀîŒ_G5e<2¯˜Ïºv2†ƒƒÌâ7›ÊùÀšFq’Dϸ¨5P9h6³Š²8_ ƒî$•Ç䌫=Ãa®žÇQÊi"‡ ªÁÍwÚWpNúx[ñ*6ÓH.í¤3‹ƒ¬a§Ž9ùpI ¤Ž“«†ñpY,a{Äq<žþ¨Ô Ú¡ÖÃ0sÙG*çÍVDÖ:µá 0Œ‡šØÈ´EÕÄÓ·" ŧ–"jÇ3·r‚x)¤.’r ŸúˆoÒ½¬$BØYÅfri$ƒ6ª¨P å»Ý·qgò:ZÉä(å,cnF¨£0Rè7ˆ‹aÎ:ŸÃL§€¬b3ö¾0!êùåé÷RúôAFb̂Ϸíàç®™¤ÒI ]´&eb«]DI‘*þ{O‰ ôؤR|aõ62‹$¨šš™Àý²eŒ³)–´à6Ûáw,ùð?l¦o›­Þ—­ýtÙ K•2Þì9Ä4ŽN;‰ô’@¾ÀI®\#ûÙ ©1YtãÕ¦b«óÛûKI§V2#9(tqKcq1Š3õÂŽP¤`å\ñ`gX8%….Fp3HTácˆvÒɨ}JÉåvg:ލM!”ãì¨!s.0 üs^dó™6ôkðÁQ>ñÐŽŸ:±ÎF¬@“èÁEvÒ)á^*ÊÈï Ç<R'½Öß«¨6¸™†\ˆâÃÞE·°‰5T2ÃÔQH/‰ŒâŒZã$„=RôsvBRG}ô’H…-PÌG¿ÜwИÃA »i°´ôûÔQÈnPKÝ$“@}$à%@=ô‘À|öÐL6»XÈzÖ“Ùô¤ê_24&^KnߟUÂÆT¢¸!"ùOHR8zKÑ¿òåÑ-<èœGƒb&NFI£#Ré>•NJ©¡‹FqRD-©ƒÏªñì•9l>* œOÆs.¤»žb›ñ3@ Y‘ KEí#¹ì#yøy5F#òW§Ñ®Èîâ˸¼§›ß&•2„O5äöÜ»¹ƒØ ±‡ùt“Ì:6àn|M c0&2&+àÇK8ã ³ØÏæ°Ÿ"e˜ó9F ÛXF2ݬä^ÒkžVú¹Ü"W x}'±b6Tžñ«ÀO dÓŒ¯÷¤«>£¯^õL§þžGFŠù–{5ËÙJ)¬å.‚¸¸‹µäÿYUžï’{ʳ4 Àýáøs˜nëý®Ï4èô\¡ ÊŠ“r|Û‹JZ`]Á ác{É¡ ×èë´8?À‡Zø¸ï0ËÙªNôíO*_ ¹.ä¢à׸šXÏz*¨ÂÙ â`Èq!½$’Ù£ô±7í½$Öý ܰ4çût“ÌzÖ“zL==Ì<WëëÔg^GþñÇ :ç]ÁfV‘„üeƒ¿UóÖ¤€u û¼û^8˜[þûFnQsÑ£ñç0ŠÏè«ls~eÍß§%ûf:kF¿¨õßÀ>ð“M3¹#f­û?XÁüU/©ÌÖIßÅNˆ62(ç(«ÿ !Øáû³9€oð$Ûâ¾@9‘t©t2kôçê¾í߇~è*ºœ¥Ü“Q±“LZYÌ–±¹=?Uù›âÏå ³è$•ŽQMë‡ï„Qˆ»˜c”p€Ù쫽r Ñs-¹MV{C´zÞO;Y5O€ÖåÝÉn6×ÝptÆG â"‘ÞH>«Ü‘³ÎÀ)ƒö¸«H£#R‡m7Y¡' -îàa˜”Îç”À&׿ó•êMü¾¬˜âúG â½/PÀ FûžáÞ„/“Dsø/8 ò âÂÏ{˜O-Eª q4\à ¶p¬ïÃÐÁœsÙÉ"•ï©õE¥óY0ì8?RC0€—62H¦›œ¾Ç©J¸‰%l篽I|-qB_‡>8‘x=«ØÌ"vF2×RÄG¶A?ü e ~øTëA™`;ŸœvÔ!ýë¶bøsWç´ñTw†:èIÍA²QùÒZåà|0½C€É#‹\®ZüÉQƒ}¥½ƒ¹ì#—FU‘]o¨ ¯CS¯±ñ£X½‘” %e:4,ø'òªþ…*ÙÚ¦ÑBEÔÒ@IôÄ)Ô©³æêS‹ †qŒzyÆKÃØûÂJ¶>‘eTdè–|¿ZÌC¯(qƒXù÷\ ` É– ½»ßK⿱gö­sêS¨‹ IôàyIµYÚeüŒMØ-c§¬}KEñ}2ÆI0¶ó=8jÞà¾Ò/á%@µìg¹42ŒC‘ˆ7#‘Ðiwè5ÕÆq^cþúåþ½À)QŒóeÏaâaû]ŸgÉèÐ «3T.=oÉtÓM2vB¤ÓN\ÓËj€í"{§ô½Ó6™·€¦akzÕ&T³îÔvÿŽÉŸc'¥ÔÐN:™(jÚÏKj³Ö:ÙµùwÔ! ]LOŠÝÙ0çk¬aÎà)ޏ>‰0Ë <©ÚêŽ1±õ ÐŽM¹j“ M™ÖlíaÂÅ6U<Õ~£8U¤QãIµÁ¶‹œý†h š&¦±8éC&4μ–Ü–?3œu>vB¸yMé”.ÙÒmŒ§>$ۣİbáq33¡ôIëa—1'æá'•>a!P­>ïZt9+¹—ýÌÁ1ôŪ}† QKÅdP/ŸeÉ÷“äo=úÞ!¹oœ(¿ž‚Ú?BôÏ¿„øà‹–Ž6ˆÌƒðRÕAoCþ×XÈ.’÷<¯æ%Cú¯ub@¾¯e,€Šå¿¢ªáãªÍi³Eäë—±³Ë)¾FfœG…”Ýÿ[5Îí"SÐXãdûÔ¦EªèJ›üÆ´mäCíÂ(êyT1¡‰ò>ãY‰S.‹  „Ç>g É÷¼ê;·å}‡**¨d™õOFJ×Ð$ò@Íœ3›¼ÜGxئæi@Æ6 öÊÙŸàæ%•üdû|æ>¨ÖÐ1éǨȗ"‡ä:iXäO½Ì”W»Œk·Œg¢˜‘}Йv>†ˆkxÙZ›ê{WüWYÀn’÷=¯æ1ÙX×Ó¤&ãx¬ \—|WÏ»Gæ(Ì–øuè µ9ÕüÔ.»í,ÁEííÿW•#*€êìCƒÄ©èÊU®µ¥c'f\OAÝ• µÎTNÿ„L£Óç¼7#ìgÝ$sqõ½NCÂ?áfDv;õj /²çzû^a8á|6r ä1›ÔRD Ç(£šÙˆ°ouÏS€i+®çcáAZÉäùɰH‚^[‘š‹pÿÛÃöÿ à(öõy9€w¸Ê¿ ì1Lßî7÷ãw©Ëdáů+¶kOlNÿ»×÷wêúú´ ‘ÿWM˜cá­]f2õ&üzk—µóV.3è­^Á·1©}9—Nù» ÙõwÑÐ[Xú'*ð;‰&L¹ÍWÕNé{ãJf¼ÝëÈ><Ãç©S¸GÊé?¾‹µïо½Ù©½mºŸñéZ.éàêEí‘¶3ë4j(å¨ó£Qïo`5”2pqÔûëØÀõ­õTSöÖúš«¢ž ù»<7g‹ïŽûí ¸¹@” ಜnʨŽL>ø¼: µÉ©¡ß` 4Ó4fœœÝòm*Ë•AŽÊy1‚›n¨V'œÛ)gÉéd'*M·Áx æ_¢Ä>…èi"‘^ü M3it8ü7•G¨Í`"„U +‘Æóe—½Þ~¾œ>²åžú´”G*>F&­,å~vU¨öÖ)³A9õMƒs]A²iÆÃ0itPH*Ùñ¨’GŸ8»¢»à)%S”sݹrÒôc%MLvc fäþ‚ul`-wñëéÓ¸àp€Wê½\™¯|"Òè`>{È£Ìá'Õ‰¨ENgrº’S¸žC-€ÛA>cLòÕým®0?c³8È|öp„iTPE<ýÌäy4àjx]éL‹ÌCô[뉫¨«ös‹ß0DÇ+n¤ˆZö1—[÷íåÁ¹óè!‰ì&¡ÿeîlA±} ’ör/¯œFòo¡š·±ÛÞCläÖ°‰Qœä üIÍQ£Å¶DÌi!¬œCvÑéxù¶È>¬ØšíîÏ3½xZ_UóÞ$ã®Oæcà×Êè•9ö)öŠuBÞ㼕ù*–©_|´zù³Ëo4ã”"§ñ ¸†ÀYñ:£µçªß´‰ H{c2ö.C®4é[ Œ–œƒsÇ)Ú_EúÖ§U?D—ÇäwRw,ÂJȧ¯~ŠöW«¶Qþˆ#2úwyÏ¡˜†cÕàù'ò¶üÉb:e¼rMç¡R;löuW‘¾êi‹ê1t:^ÞsɺÓ,lôtñ qˆÚlªÇt*+?ÁŒe¿T:Vlè†ËgP¾_!¯µòïAùÌ'Ït¼üEë¡vóJÓe]íïålp*Øf… ï¶)¹“„}I’ûk3k™°|¢z-N’ÿ·*ªO½Žü;S÷Ë•ùÖŸ«>žÈºž‚-Œ°Àõ+¯#¿ë1U^' ¿±ËZâ9Ÿ%æ¡6éC±Œs@Öøyf›å~K=JîêòPvü·êyæ‹&‹±\·úN64]±+”œdoZ 9{W¿ J=jÍÚ5ý3,\÷cÕ–f³åóxÂ’K® ‘^1“AâXväûJÖ8õ,Ò.ÀÛðŠòy lylñÿ++ö|GéÀ4Ø–ðFqÒAßk\N8ÁÆÞÄ["¾a6?<<0im¿†Dhö~: É¢…¢À£Düù3Áv_˜V.&vv°˜Ÿ´,€î‚‹òÍÁ5´’ÉOê(—áf»Åj- ÷¼}^âìõn]£Æ†Ð- _% ¹ ½?„ãmÊ”çP ÊaûÇ9N1÷d¯†æ¿¯È!`ôU½ öß v8b-èÓ|¿†8¨*ü¸*ÄÚ Ã[Îg+Ë©¡”ßT–¿;Bõ¦!‡Œá}J¦JßÍGÒnRŽÄCPŸË8s¾–)ÍaÈ`—9t ÆMöÛðH³±'K->­)ïç(åo½¯:qf“¥+Å8˜—ûóÒ‚ä]ðæ™¿€a²£èw'8¼AVüìM¸U™t’€¢7Ñn踖{ŸèÌX’ô€Ú ßÌ!rX6;‡läN0æ{T !wŠcÙn˜‚Õf>zô\ÕnÉÚ“M-¤ÌºÎM§À é­DÎDô£rÇØ¡½îj‹yðáw#~CJçó²L:“}ß.}”rzéžf’à;k|”G¾W{Zª\0cÆ/Õ÷½Œo4F׎ÊKû×Å~_ž&¨]x£åÛfŽ¿Ö©€lÖCÞa‹.2;$ CËÔ'à¥oE¬Æ*G䩆üøÇÆçb;ˆåHܽŒ’+ÇcLà÷}m6ž‰húÈ«ã26™ò¯¸V”üÖÊ«4AÎÓÕÜ=qÛm³äññìÖ(pú1ãÒdÕËÜj†\¶ÔægáÌuýTékê$:4Áµ¢ú;Pì!b2ÜÊ—Øêÿ’EP´ Õ¦°kãB©JZ|„"W-3³±2|/Ïi½z˜ÿ³€)–LÇš’…æY¤&x\P`ë˜É!R:žSvìVQŒvã´<ÍâÀzà첨¸˜îýÓã~ÅÝ ÿ®ÈyȺ€½Ìã>nãÉ-™ðå=„ÃóE„òˆ¹<`kVÀi딟CçópÜà>å¿!'Ô±IH¹ÐkêÅ‹J\{“( <ÞWY÷-ÖÄK-~.µÙÖºo` y } ¬XB¸ lW5¨}«ˆl¯f.û˜ÅAâj_†à:f±MN3Ž!,çínR. Øåû£!þ:54©Š¥hJ¼†;<ß`gþ"^8”À•›;XÈ.Ö6~Cm2¦Í.˜dÑÓ›±p2™Þ'Éô?©¦$Cmî}‹.e;KÈ£Š‘‡Õ)¾è‚&N¢”Ïz¥Ÿ¢¼žWðú^±‹t9zîž×Tš¤?ÚѺɓtvÉKë¢ÜŸ,¢Årjî3t½ßhw²1j‘—U·Ntœ8y¤âeÁÖþ&ÃÆ!c"ðÑ'ãv"†ÑÈ’1ÐìÝdzcΩ¿šÙÉñ±K;Ú|¢6ŒÔa°©Ò_}ÿ‰E;–/˜Ó`'ñîž@ÚQ§yÍD:…yÑ~GΘq4îiÙåûv&Χ:féq¤yètÆèP –/žCÚN˜¤míë¢Û×VI-o£‡ ÆÐg´å•—ùŒ&4U;FæÈ¸jÖ,ƒñIÇ ð?,À¶WôÓoÜßa…té¯ö’à2ˆ®×–Žè¢Mz ò^¬Žkè0ØwÒ2ÁØ:àþUÿ—¥`ù±"z¥-!iÆÞã•çYû½Æ‚÷$Ó{¹Õkmj¿;€Z{rež2U…ê—0òBT“3¨$©þ¯Ö³1šÈáëYë™×±W9ëw¿q` Ã!/€Ù Èõ¨j$Ž9>tLdGä{ùEp&|§ŠpM…J[rÖ$÷ΛäÞÚýÂWfqéÆ>ª)#«ï µ ·&§ã„¥#ÕB`rïéÓ¿~?N”\SØIòÀeª…`±ï~8°X)ø7«‡Ïì—b›Ÿ<|%lgZà×ê¤ÓˆÍÕol£ G‹k?w‚ÓÞ<|ò€ëÍ6Á’·gæû8Àl6°Ž—WÆÁ·ÇÐéÀl¶Î gskYÌâê_V‹J»<ôí²ÀèÍÈC§aF3Õ2ùcÆ0Y±<Ø™þYö1—ß.‡ø¦g ÙEBã Š)ÑÎŃÆýGÃa˜¦&’IŸ|}Æü͆áì󩢂ºÈ>¦¢69åÆïa.Ô&¼Ñ tÈo€ˆD÷t)8÷Á×”Nö@m8\Ø Þ¨1–®˜¾ø¥/i2¦í1àl80˜&·ÑÓ§ ¢|X…zO j$¦¿® dÔ²Ç2¦ÊüZæèq:ë1æÓ¢ôf«wµsøhŒÎóìºäýx£ý>€ÆÌehßÍ.ä °ÓŸÄ¦ &ô’(¯NùÍDfÏ VLæ‘5ËM¤°,‰ò¹Ö ˜^š±‹C&E-¿‘~ ˸'æÇxùmHt¨E>wɤõ·W~ï5ÚÓŽÚÉòVCÚ¥í€|¦d¹ô¡Þ:@q—˜£2ø «êÝ›#rëÃìt£,‡ACW¤=½ÞÊwr¤ŸÝ²ÆfIŸk°œÁgˆÌU"ÿ ‘c§´“/cpBúS"òí”5c·ü¿Zd]5I¦tÍïÔx‰4ãè7æ¯P€Ö'Èã–ñ–¹3ÍÔ>Ñ üâÔ+4݆½2 æ¨LþEÔWý²Z—A›ýj2:ž²ÌÙÉ0”s!39Äv“By40Š“NR™A%/T&@üdå|æ‡dÄ~•Ì`9[y)ÝÏ·ÛWL7Ç(á»í·ÁÕÇ ‡‹U­ÌLñw: ˜þÿ¦IåÈvÀçó·3Ÿ=y$D™LÆÐi“¹!˜šö{H56â4õÐ3Ïå0ÓùôÀeKäÌ5Øl¶N¸'•ëVÕ³‚-Ì«{H-ÖÚÿÉÜdcÀÉD›‡ Z´¼ 1À/E|8q–¨r¹VÀÅ[TÕó´Žg¬ô]†L}1`40…&.ãå7äÉP Áqç|hä8¹YÁõw<§Æ¤M¯X&l"À4‘L&¨Œ“Å=E›ÆÒké$•ÙüL-F-X]XÑj&&ºŸ)2þÉ¢3:¿c½,Þ¦>'L͹τ 2·¹ÒŽn70Üã5øÓã“*÷Õµ {&™ïÓGúže° 1r™€i,FV·È¢?÷ÊÜŒI'LZ>ýìú°|¾’Œ l"À0úá1æ!GžÉ±n˜€É)mº Æ(]ôGûUõ€É‹¡¥»ŒQœ±Ù» }N4€•+5Gœ´Ïk~ IDATåŽa·4ˆ’9pˆ.;‰¤VˆL‰òÍzj°•l¦QaJêDï´‰1]^Ç VhÀ¦Ú'í„˜ŽŠL“Ïö«CMÄünGùivËïfÈ×Hû¥²5És6`è®¶(Œ@XÖ’"EžÃF‘]rÊÑ+ß)ÓQq%rÏ-2.+DöóQ>Q;Ôø„öÚTú™5OEûT9¥¯úÙ0t®Dd1tS&íGÛ$ò%ËØ5¾ƒHÚÁŒ‹`Sã¿.íN–r?‰M³ô2šr®!›fìmaõ^4ù®¡€¼^íâceG"ŧ]¹ƒ<¹;>3B8ìf “¦,T®Á[o«dÊYÀôw—­¾•Ëe«»YË]Ìa?¾–“p ” &à$€É˜¸…0C”9M)ywÒea™Å¯Ë§>:™3Jø×4rþ¬N4f¨¼¹ÑO˜ìÆ ¤Ly5ð˂̋9J9û˜Ë/‹f ›S-·¤íe>{¨¨{Xx;Ÿö!hœÌc7Ñј1Œe…2 ¦& ™p˜éìb!é´3—}µÌ²f¨zïi@œÉ(ÆÎ« *õ½³a0ý"µ—v¾lõµ'¦¯IÀÂX 0ÇÝ' BØ(e#è èž /œ¡/ni+Næ4HŽžHº…a£Ý©€?§ažH0úÖn˜<†&SvóСÍ-Ù2¦Aã@ ˜ˆNìfŽOüŒL.¬cÆ{š’N˜XÎüLhSS‚Á ›€i4æÞqXA$ñ†ùÇdÝù–¶G †*09 æL3HAÙ¼G óµv$ï94©l÷€I›ÞRäï.ù|š˜ÖÒ À4j˜àü†ÉYëaÐ0ú ³XP˜(?ŠYž'òî–¾ÍïT ˜FùnH|ŸæÈÿË÷3 3šNí0,ï{8i½CpsÓo˜ÄÈþ€rb`² @ HÛ ¤½{eÜ–I_êäýû •÷“9óI%Ç41¹Ý'÷ÕÀ^ïAé"o·Ávz ÀT.`rÐ0{úŒ1Щ\•Nôò^˜œêóF®e-wQ5ôqÕOL‡|7s„iÌa$L-EÌc/!ìØŽ¨ß_˜<Ä *©¦Œ¿­I„ou+g®w 0-¾ûw÷‘Ê%¼Z¥Ç_Âv| AVÛÆ0¶ÅafVýœƒ'>I¨Í¦Úòp–È‚žbœRÿ^2·B8 ¶°‚\ÁÆöo¿Àæ“tðy6ÿ ]Í—«Mv›ÐÝåòð¥ñ®„Ú‡G•L{™§ªœ†±}áÇØÂ$í}ž»«o§»á2ur¼O±RYHS€w .ã÷ò–«j÷®0”†±}éÇØæ‡)Þ÷{vý5dq›.ŒNº±ˆ¿…«:SÿŠ­+ŒmS˜²-¿aÙÞïÑRõ•#e)ʉ²Ð¸×›Ô•Qß9ìšõ­¼¶„©Ý{ƒj{«,̳e—ÈÉ7uIî¦é›Iyå¯U&ßí¨¼G3åóTÎìáóS¡ÆxïÞ[`•0 e£Î„7å÷¿L~»BûmJËXNE‡ ¤e`ÛVÌÀJѹä)üÞ…Š:M•3Et'~ óèS¦»7VTîé®<+—0æ.S.}UÈs/²N“{¥€ËÔnùw†lÞú2s zcþ?SžY'L)£€ Ölÿ&QYGü㿳gý­ÖßKc>Õ“t&O PÈø †É䬀š•¶þÖëOº1fZwLZxqŒ-~õÛ¼ñ·Ø9ã³SRïÛ–}'Ò§ çªtÚå£öeü3’¬]YÅ·^?ÞÙÛ˜«ƒ÷~RõÛÁø’$I¢'“\Ó9LOÎûhʼÛÝašÈ±Rˆ$C{ÖUô}’%l÷Û~â ¯ÿ@üdd½$ÞD,€È[ßvAÞ³ Óÿ„þ À§ü˜Ë>¦sWÓëŠÍÐÉÎ:&0 íób2Oš*Î%Ï„îøË¨¢‚ýÌáw¥0ÂõoQÞ£ðOå ,b§Ê Ûþ¢Åˆ41ÎÑL±£fû,‡ÙLµùvf\ŸšÉV¡ÄU¢ß=Æ 3»û¨žBnÚ•~Ù¾ùáÿ¸\ÝGû™Œ•N2"ìÄqÕ¯›~Aå¶›ÕØa9z¦Ë€Üë½4”fI ¶B2¢SŒU†É'c™+º©™¥Á. ó³MØ›z{±Rq´ÉïæËœ4Aûž«H_ö´çù^§êt‚Óe2?k 3™6ÕöI?×Ë\݋戤ÍZ(ýÛªwÞÎêu÷¨ß À:¨î»îþ;Ù°ëë–ym©È¡ÍžÂìí[öÏÌ ýTiÀÒ+Ûô0ᛃ€ô]›ðZ¥°ýÛ3„¿{¥:ìäÉ}ÚQ© ¥ËP(ÝÀm°=ûó,iz@éÖ¬ÜùŸÜ{üß”T@ÑÞõ·0¯å!õ»tcíîWrîºoï+J–$‘KûÒy Ñ%Ä׿¨ž ý<&+hs^Í~‰ãæ•Ü^y7÷VóïÞM,b'.‚ìf_ë¹ ìð‰ÄJÊ9J} ãá³;w^¤q€„©$’ ¼ëíïÅg£äþ‘.m.ÓÔ{ƒL’=ϳÔ÷–Æý@=Ä·©¦Ãw%Ç)æ ³øÕÈt•OåÛV ¼wõŠ&¬·6¢DÏßXìû!‹ã~¨äÝ«¶î„Ë8F ‡˜ÉχfÁÜw0§™¿¾ñã—â~ŽE¾±(îGJžLµ1<Ý~eDž·ui§å¾ å†$÷_Yëûk㾡Fñá¨÷]÷Öî¥M[]8.ÏëÔyo€8I§ú&³ýîh“YªëYðA‘÷QµÐ¾™\…˜©'\P±ýaðBaõ¦ÎZmÔ&›™øj•5þV}žý&úZ'¯ýJ¦ÍwÜn™f¦¢s‡,³Rú±§Õ˜žâý ÉþrË)z’pp†d>î·ô¬rõÍVΦ‰äÓ»ˆ6ï×ImpÚ«Ë·©g}w÷Ð×’)ö{HZŠôõO[ÙËÍ+dèÎnÙ´ÇŒû邳šµZcü¶Å0™:bÆ#«»ï‰0úµš»-ÖÃdÄ:±€¹÷þÔ:¸ãÞmß—Þñ€;ü½+Õ˜WñÜé«MÆk,Yø@T_¦ŸIÑ:ˆf †Á{×+V®·º˜ç8ñ]/ZýÑL`FßSàz Fá¥Ê8†ðQìUu 'B/:×_Ôáø.˜/ ÄÍë- åûΦ3ž±ƒÌVoH)[ °¾_¶”rŽ’Ú÷ltrDí{b²&§ÛŒûcØ€æ~†4ï3,òýH=¸9ÀK¨'ŸjÊØÉ"^Ùë…õn‡p¹æùóÔqP6p›® 5±ŒmTPER÷_­$|ZÞ®)È;QZ†jµ $»Ÿg÷',ðýDm ³ÕÂüRéE§˜ÌæÖ±½jÃùJ;|4OÝÏBvQF5ΦS–C¹fïÌ(­©Ê#΢ižgHóm r€I<ÓTj†×'`Eï™õ1>o—Í>«v[J `jÄÊf®³€ë €,gj—16ZßÚå¾:2´åƒÔ‰ÍU„•»,IÞS(ÉÆ¡"Ù0וIÿë 4Ì•ÃX¾P’Hs`ÏÅø+_R>^1ï%ˆÉOŠe³Ë9{¥Ü÷^¹_±0Œ­†i[ h3°„£ ï–~ s¦®j³a©0… òÛ5bº\"cèfBßüKI½ L‘å04ÿB|]'•én@ÉxhîÍÌÜñ ËÔ˜ƒ•ªKÆQç|ŠYÒ-À4”v!¾ÐIB«ûýd†ž„ìr|†dºi' .Ré¤<ŽQÂ#MÅÐO`8Â[ípÂûÏ2LÿÃ@Ì´·v8<ëÝe¤"ÀDŽkzË[¹"}nJ«â>n#mø™è}3âjð &"M©ÆDGåø'Çó8·ù¾kExÌW}•÷&j)¢Š ?ž£üh'\‘!Op›zxJÁö‘NøT.Ø` ÛÙÌíVš3—ÐVtÌdWlJ#êªÄÿ{J¼¿g½ïN%ïYP‚°Çu+ËØÆ¡¬™¼\§“ðéÄýlcþ®—¢ÇÏŒ:ƒÉ by*üSá}XÉ¢}ˆRÔb¹Ãþ9ì„(¢–ôÁ§­4Ú¨û ,NÈ0]™«À>Å&F’jP™‡åÒÅøÈÈá3ô³+PŒ)‘$é[²ÜoÌ`¾œiN5#e7À¼WÆÌƒUüV'9M»z#ìüjY5°Ð@rì4c #Ûb€”Ó`”’ Ön²6ZcÀšÂí‘þ;'™wí¦Ó„°¢Ãâd£<Ãö`ôI›Vtþ§ ÜS—™h, –¡+šÎå1À…ŽÚ0˜I „ p…ÁĘŒ‘ÎR-cÝ*÷Ë”(¿saAŽMÀ9QVíÞ˜ÏíÆ}Ò/“Iëcœ1v©“¦‹»Á¿ê¥èÃE–#ïú#õî룀þXÆ{p߀¨O¸Ž|ßc0ËhV~9Œ97þÖùžÜÆz˜(c—+í˜} ›È?ts4»Ý˜r-¹V¬ ¼sjI׿ÍÛûþÄ#áÛ(ºïQu? ä]Œ¿é%õVm”©­1†U2h#ŽAÚIÇÇIô(v øDN%G˜F}8åoÞDp€-ÿ­ûäžLÿm@Ô!9R¤Ã¥võ°¾¤ Ãj×8Sî¤7 ¦"i¤È“GmжëºáödØÿlßG9GY4ò#+Ó›Ù$µ£dïxf¥"îa*<³Ñ÷UµØ-C1P¨×­,§Š ž«K¥Â×NX[ ǰUê¡»v|v1l„›ª˜Ã~þ8Ú”f¿&Î<¬¯þaøÕÌ÷?È|ïƒìŒûœZx´³g"ìàsT¥TðóÄY*Òk&ÜSËöSFµª˜ÞÃ’ME=v8~/Žÿ¡hd±+‡@œ €8É J ¸Ø´}œ¾T†ž×Ð÷öǰRiXùlzEG4h3ûÉiÌ[-÷1â^nœ8‡¥?C€ÍÉL¤Ú WÓ BCX¥´øÀô$6À)XßÌO¤\à4ýïÀ*›dÏN4L$£g˜3 ~]D'ËLÏÜ“˜öL³Ñac'ÆJüÙm0ÉÍåQƒÓ =[ú?l0»ƒI2E«f `Ò±’Wj¬ðµ<<•*L¨ ÆLJ®g€ }劜¬wLl²r½˜&‡Œ1Ô µ×## Î3€Ø€Ó*¬¤ªˆ©,dJê·^íÓåR¨PÙ³{H"?í1«tΨÁø ¢‚|¨ˆÇcŽÆà™‘y^T4â(–Ï"DÒºDe7ò˜%ÜûBÈà%·ùÏŠ c–-ýíQzöZ¸=̧Èù( CÊ%\ZÓÏC¥s™;øS臡ø 9?Û*DÝ™IOÒžxIörh"ˆ‹AâH”MÆÍY´DŠ¡'Ñ£“v š6ÛnÀM8<û,`úï~…Ëÿ›ËgÆ<ÏU/÷NÅJ]€{¼œ{G0„~2>¡åTÀÔ;>–üâvA!ØŠ•)íÂUCÌa?TQHñÇ_œ8*m„ñ”oõº¶—Úp‘"lù`»¾(â’•ýÌc/Ó8B'ðÕœ´X²yÆÞº·qØRó!< l•pím$ÑÃßóâøy L¡;Íu"ëz ³êXÇö3‡¹ì£Œj’è!ùÄóŠQ4ú9r{y¡¹äƒdü[U˜ðL›ZÜSP¾#£X5†8s¥yóÊS›IÛ´«ÉèyJ½¡Õ p1MÁgºre[(mTBõ‰¬ë0ÙTdÔ‰ gˆºÆV½Ç–7Î î¢Æ¥û®ËH®z^mh PÑ\ɜٷC§áØ-›¿«tNÓi~ç$âOB½Œ¶cÔ2Éï d“ïPòíŸýiæ¬ý/JRb‘ «°l!TÌÿU«?nåÄbLÍ1-“ßm’ÃZÊo9¿öl _Æß/¦+)bñ…öLЇìð‘;ñ8o[ÿ–íú¾J²cnqŒw´ŸlÇŽI‰Pë¸"û£ÖåÑ,æ‰y×SPÿÇñNán8zïG)ïýbwºŒîXñ 66Õú¾ÔÏì'ždžîË(åwãDí Mé³Ñ×62è+½”„ªXÎVö0ŸÌ 2íæàï%‘ ªhJoó)£:Êé{§N8­ô Ÿ9F8\‚mÓ;Drœõaúï(ÿ1Y!=ò„èLÚ‹Rg†Tv‹·ƒ˜ß¶¬vYxnƒO¹PÂ1³Wïë‚!¢}J`¼Ï‹ég”ÃñçÓA;XL5e<Õ’¡Lyßo#Θº¬Yj£¸¼¤+üriÄ_÷R4 d†Å0qöu³GQ~H£ÉçÐBXÇ/˜©’É-N5çÉï…÷σýp}Ö frˆŽ‘GŽ£oXŒžYg.Ö”43“,òh'â4èñ¼f²ÙÉ"~¶h¶•f7|aë6¼ØÈØÛÃg¡×ŒÍd‰RÍqˆ“Íýé—°žõäÐÄý,¥Œj 8A}ŽüA™ˆÎnú„ŘÄLÿ«t«¯íÉW‘J'óÙþ±[­ï—MpÌ0íiñÉüÍ´óu‚eÆh™ñ²ªž€Š0!ìØ…-G]mÞ":1ªÞlµ¯ŽO˜…vµ¹„ŠlØï³xéì¸ïó–©Èm×щ-µÞ¥ÊxIæîÊ;>ÁŒÃ¿T›á"TÎ1=/Ú\¨#ò4‘­>«¹íÔnø¤CóÜ’½ú/JgZz8†aÐ@Ì.f¦Å2ç›åœPk˜tuº—Áä(Ù£ú`+®´©œLÇå;qÆXj§äÕÂÄt©~d_ŒõKpÒÄõó[!kO7°* ›mª_y"ƒ.-à­MéíMŸbö–ŸA ï?ÏÚW•L>¬¤«ébr–K–ÉX•0é”çoŽô©RÆl*@ePî]"à«庠w¦‚-3LxĦd ɸaU‹ÌóÑ­ÑÝͰÕþE–oýžý)°lã÷ضù‹ŠõÊ‚ŽÕW’D®»_'ÌZñ3†>¥€´ÖÛTéç\hJ¸†œ[ó:,òçÁ]ί²öÀ7” ¤N‡¡Ü ñí:iÑ΃ý >Í ¶Ð»é}ê™)ã¥7²†Mt’J_í{i+ºš÷·q£ç8EÔ²±÷«0 sR~Ê~æp˜éTPÅ0ö2/ì¿üð•Ò´Å/÷Ïà²9ÝôD¸În9|ô8G8œu–aúdz祩2>Û,cáîžê‡‹ÿçõ+Ö<æãUrœ«*×zc^lPÉ×:Hc ©£? ª“­îx—eí#š:átž"×ýg%~ÒÇÔ‚ä\ÚÈà3á¡ZÞ9y´Oé/ä€$×_Irÿ•Ф‡Õ=$àn£Ê¶ÛFÆÛ‡ÞPé€x׋l‹û"ø`‰÷+ƒyo-‘ilê鎧Á ûÜ·¨ñNç­%vÕ>Ní˜Êª|BmJÇlØÓ°œyߌÌ=†Ù¥ ì{Âà„ë>¯ÚKb[ºàsÐzFfÜöK«ÄÉ~¬ˆ4ÎlÆ+]÷»H‰Žì»ÿræû‡  ¤ço'VÿŽvt,F7ùëå7ý>d‹ÎAf‚NÓiVÛðW½-W,K\C$µ÷ÛμæÈ5{ßϰ>1%Ê̹vìšl}ûOŽK_1‹ƒÌéû¯ ¿ß×õ^h†ŒÄ§øzêzj(µ>ì…õ)ë±1‡_FÎ$ãiêùì!~N?G)·ÞÔ>kÃÉ–³ Óÿ6†éÌýkUõJ’°¢½Æ&9ž^ê´ü^Éêÿ.¬”ÍÖÿš«á†ÄZJ8Æ"v’:öìÄ~Q#D—U‰e2œ°ft“'š úÏ¥›dÚIg‹©¥ˆ—šüjóº'D8l9wÁ5 a=\6³›Ù(¦,‡&’›Ÿv07™XóY¬¬AN_S/&Â0”¬ê=é$”ÈãFÿqfrˆ"jÉ¡ ç±SÑì“™lÓ¬‡f&u4K£ó¹f¦Ìr,ñêT:軈vÒ‰cô¶§£#'š³Ðm1¾ŽŸéO¤“MúdaÓìX¯lL&;›”ÕŒR3 ñÆ~¦£çô=²å„>&÷a|âXYÍ‚µvƒErmçb1•!ã_3ªŠn7æÌa´«“Nº‰NHiÖC3Y3ÚnÄÝklÔÙXù©t½7Va[Ín¥`•ÑIBS±|ÂR Êœó ñ|šzNi¿_L[5"£®V û¤Tjy´>'bù"¥ŠÞõl’Y¿NÁÕ¹¤J„Ùɰ@!Tñ*‘!Udr[Ö*‡ä÷ÇDÞ<¬â·17ÀòËrHµ?ÖùƒÑ÷Aò©çõM.X ?õÍá|{åJÂ÷‚M'Îtï³Öü³€é0MÞï:eƒ‰1'LM‘]âÿ—o•Ívnš Ëႊ@Ä·g.ûHû[´³²iΛ 0ù˜<=‚ËT^kS—.R¨¢‚ò¨¦Œ7ªj‘ý¨’sÞ‚fs€bŽ“O=ÙÝ­gn¼§L±áéÆ;X{‰*T<๘C̤<ŽSL}”RC!uäÐDÜÀËjñŒ5§™!û&_S/ÖÔ—Htæïh±AÒ:Ÿ±Ø¶Øqœ0M”úÀyºø®vàuÃhÎ98%WÖ0ã³–O˜F'é£ËTzsîÇ*î«7Ÿ‘Ó&gŒIÎAt==A,'lmiŸ 0 @ã0‘+²®WtC›4'L|Œ¹w@'+( ñ4€iH6ßNÙµŽÉo›±¢Ý&Læ=õ3@Ój€åNÃöá—Mßkè‘Î í”Ï d¾tqÞܨ³™{ v'«p²®Øg™Ô©3@¦öŽX"àAƒ“|¬,áÚÏ똌É:TÂÐf¢S:èÃÌ a>w‹ÚD§“¥jÀ”‹2ék³dÅ ä³Bðܲ¼wK{e"g³Ü/ˆ•ÍÝn¼Jå»ë°î׊®n—ï̃;Ê¿Áƾ¯ª÷:¡j×Mp‚¸}RßÒ+æÐT,_·xõw“ÿršèý`éEôDvÿ_”.4¨qXx1}$I+öî°‡¨$c IDATLsí±œ­ < cОpóÙÃc›ò¡Þ?!|ÌgoØF ‡ÝØt¿–@¸ííí[gMrÿ‹®p¸ð e/o.Ýñ»)«™ùZ‡jÌîUa WtÀçÒ`!\\>@Õ,f©t’L7Ž7,Ÿ£Ø”“™FôF([¢ão$:þF¡çV(sP ÁûÏ¥ƒ$ŽQ—{2i : ùÉ‘üä赈½²[­_õÃb¸6¥‘ ª(àY´ÒùÜÄþ@grìÖibX¿ó%{Èb÷­ˆ5ƒ¡êö_ÆÁé³h&›: )ç(ùÔ“G<¥Î~Æ;™ŸÉ;À„)²œOX~?ÚoEêËøÏ£›d2†Ÿ²6¤ÆûEMÕÔ'÷uî=]ºD³Rq²!ôcÐÕÅ_GÎp3ñh} g€*½¡·Ä±3è6EéJšÙL1îÓs†qf¾‘˜C‡6™&Ú-œ†Žh?¯œÛ´™N›aO`¥%0u©Ó8}†\:Ò9'°ÒŒ(pÊû.ãwNØ'Ÿ{@£€ m~J4ôÀ.²ëÁ$i«ÚɦI6«ŒŒfübMõóÄ\Ú%í/C•Ié‘ßëœ_:ëµ.zÂJ ‰ÈSc~+1î –s÷ˆ/]OrHægš¼¯Ÿ­,™×ýÄR ð~Ì\õ¨¨x£uj[Øð+ 1líaÂ!›’?:ó¯ˆ^ßòcô(jgÜ@QàQj)¢£*|"Œå¼‡í,¡”œE_,›âªð0Ì>ì„xCöÛ ¬v©X¦·yLÿP€jþÿ YÍØW?‘È= þ.éƒÏ&Àb¸¸b€l!‹Ré$‰âF_ŽÞ §•4`mÐ.^'gTn"3Ô=_-JC÷^H3ÙtQM;é´E=ù|£k­UãÝpe²:Ý,€›UÓZg§¦ $L@e0FÉŽçYáûÎø|~󿇺ÂBZÈ¢tÉ¥‚*²h!—F;þ61¨™J4[ãÂÝŽ×Èp<Íì%);ì?7#ØûÂjsàÍE/šŒcìŠæ56¶ƒ¡rÈF8j˜O¦ÒG“¬+0bÇòH76¼.C¶¡)¶½ß?d˜Ér y“ܸ§Ð¦i¾ó`%ëL0~?j€•É.M[›¿ºc€¦WØ„c71­š¹‘1ÒÌ“‰MòÌ¥`ùÜ8'0!€cδ©I;]±Àc°-z\‡b~o²®:ãwVêƒz.ºŒN¥Ñ'}Ñ5«ä~®˜Õ/`ÉÜß“¤™5ÿr…¶,KX¡Vé“Q{ ¦L»4ÚöaåI3¯l”“»~žò±2Ûw¨b$Ÿ[L“õòÞ°ÞÚ`ÏʉýǦ"ïáˆßW„ÅÃþ¨£ål¥'; Oû«€òø£ÌeÙο@>Ê`éE†ê¹hK΀d•Éû8Å,å~zýï¥t>8ÆåÞ.n»;=×­Ý¾æÆ¶xÄ¥XÀº³€éìõ þbV¦»¢Ù´s;àiª4Ê,ø‚g´‘N;)t‘H/ÞÑW,Ÿˆ‘wIÎ(ÇsI e¼l?¼ŽŠZ[7øj)¢–yì%•Nîf«¹'òÞíû7S<ç8ù<yo1;¨¥ˆdAçA\4F(Aˆîg©rú>Œ•ë å¼þƒ{—¿퇯Åä0¼•„óm\g}˜Î^ÿ—Ͷ.Z‹à¼Í#QK6ÍdÐTñôã¼4Þ±Úô“1}UŒ°÷€ýZÈ¢—DºH¡ Zɤ™l^­÷(ÎGNœ^ÎdYÀçÃUéí¬` ™´’BÉtcGƒ˜¢ýuLÊEtx¾ÁBõÇ_B)t“L3ÙtF=ùªÚÜ·þŸ™{ô§ „” °êÁ*ãÒ ÁõçâÚ÷ºb«|P·öÿPØõÞâäÌ´Oþ¿XÀ‘v<ß(›z˯ µêYÞ’P@°AÆ+ZÖ€¬…OXà4U˜² ÊÁ½UÌvÀ¦0쵩>ë ëÜh´é0wñCìÛw‹Ê¿U,ä~*KP@Ê,ŸAuÏuwÜɆc_W÷K0Ì€A`ä9£ž|ì»Â ÞÜ“ð²‰5¬9ú-ÕÎ\° †ùBÜ6¶õ| 9çƒ\ãk†$ølËN–³•²øÌðnX ×ìk¢”¾Ý´’ r¼²Æ«÷‰Žô|¸ Ü|–a:{½þû\Z¼c¯PÈÆ;{‹)¢ëøå à§ŠxzH¢‹:H£…,ž<‘©Ì Õƒ‹ÄÛ_$Þñ"ùŽÇ˜íú™e†”ÚcÁÒsõÓE ½$FJ¼íËL`Öܳ«âÁù®ÇÀ «]÷X~K‰Ðù;s_Ó,U éΧ#Îà[œ_÷~Ȫ­øV.mÖ³†ƒ7Àá 4‚£ë ¥o²Ý~,?%)ìÜxÊr¶î— °þMê²1ÊÁ ¸ñ¼;kçÏßü8WóëØü†å@ß¾ž“–Y/tš6†Á×t2ʤ²¼ú{gî‡ö—ºÏ`•Zaló9šfµ²±›fÄ&į$Ê:wóOdzªCXç€ëŽ×Cõµpó¬ûÄÌßa¢Ë²˜¾‚!H~v|ßvG3»Y­OD§-0å:€UZ¤Xm—ä’Êñ û¾¶[¢}£ô¥Ù¶Z¬èCÑà Ǿn}ï8Öì…†á묵pƒÒw%k:Ÿ±¾7\RMb¸7rH§_9™osÍðŸñŒ·Kÿ0g+"ÙQ „s~É;¶lžLg¯È+^Ã%—ËËd¡šážl(‡ ²äÒH6ÍÇó\‰c/¯LÝZÍ”‘çH =͸ˆÓn à^«¼ à§ŸxúH v²ˆV2y­Í­|!ŽÈ=g©×—œ÷EdL¡K•:eùaLUÆP4¨rx$û_Irü0Çõ_Ñt>Î8Ÿ~€ýÄÓ@¥ÔI+ ôáè{ÃÊø­+¢OEñƒˆlp!Hq<ÂA39º*ºº<—“2öœeÖì7X©˜`Í?PvL†öŸIÄrô·sú.æ}e.Mà óÖÆLY™l²!¬B¾gšG]gN;¨ûŒöSD^/ʦÖ`X&i~ùžŽ>Á*Ä­sìÈFÌû?}àˆT°oÂ2 Ž ¡þÏØÉt2Ӭ载òy¼ÁÈé«hóœN«`¶­Mà¥2NfäÛ>¢s^õÆÌ_!–/DŠÑ+c§Ûn¹r°êdNÃr ¯2˜P'ѵþÒPæüƒy,˜|êD¯¦ÿY‰Ü/ó=€¿CßSDŽLòlšþfù2­ÒïiÒ6ƒÙ\!×CZû3ê™ÑÅÛG!üòG£dõ3À=sVqûôÍ‘R(^0á}`ËÎ!­¹ƒTòJ³—ð&°Ù*¡u”ÀyÃ#¼¶Ù ·ïDew= ˜Î^g¯wTeǬ&%òÒ€ª>P¨L)REüZg#™´’FùÔãg€8ñ1„‡a\¡×§âé'‘^ì¡p”ùo-wÄE0ÃÅH†›À(æ8q ’Fö¡°&ßÇĉÏÄTIr ÏO‘ê,&Á!.Ä×vÒ*„ª3yOÌéD€:úÒt2v@.›HöHºÏèã™îa¹àM3n£X¹´z4رL‡§»´)̓•¯F;Škçù~”©,«<§knÙèu´×ˆZ´Y3ÍØX§ÞµƒµÎ€®‹)kÓË?AHIçè¼spÞ}J¦/»DÆÙX~EÈÆ=0ާ .Ñß:Óv£!‡.V¬ÇJGnêT)XÎìƒÒ^ºÈ‘‡٦гä'd ”qØ+ç<͈Åf›/B™ÓÖãQ,súÿÚ;ûð¨Î:ïÎ8LÇq:ÆétLgǘÆ41¦iŒ1ÍÆÈ)EYäAd‘íU)"¶]ìbeYl‘öADDYD¤ˆ”"""ň1Ò,M³iHÓ4¦iL‡4NÓt:Lç<Ü÷y™ðšB»…ÞŸëÊ•yŸó6çþžïý{i³ ¦…Òj³-g¾|~/V©§mš†í'#è½9{9Ú*dÛ!C\5Cªn®}'År¤„¸Ü—óiÆõþF㈽Š. °€Õ,¼Òñ‰›ŸFf0ƒqüSó Eò@º¾¤ MkB×§£i x͇Ÿ8¯F<èúì ”`R(Þ° :]‡2°( a5·ÄÕV ¼»dˆ‰žÝfF_ˆ¤[• xž‘Ý2„éeHã Ã4¶‘ÁA')\¦°ÄK'yô¤Ÿ -³Ÿ±tO…èûb`›7„Z)¦%Ë©*åžä«§¯55§*óQž%êxVdÇØ"øËh$ðÑA>ä“Â…„[–9!®‚GRÁ [ž´mµßñ’ååŒÂŠyòó½r pØÄѹJ Øi· ¿›£MPAÍ…¶'9‚ï0¶A—mÛ;mâÐÈxòÛ\£þѹD›‘Aj¸ôÙÎ Vù7#UÞ˜> mF]¤”ÍùÊ•®†Üÿ¦ÐÌgd}3òsÒ¶å”±^®c'­¢˜a›à”-fŒ¸³öy¤`ÛSâ{ç’Ýg.*÷y—m¿%SçQ›pÏÅ*+‘ûÕpsŒF¿±27‘bÕa±>Û16$ C0åceõõH‘eÄFyñV*ÅV›|Þ˜Rv Ûf.iº Ê/ÆÊè3+£íXWù6»Û&¬°ÖÂöã§ì*WâäiçüV~ b¢¡î½ÜÃvPA£¸òÀ˜Êƒ,f%«Xˆ—A60‡ƒŒ!H?a=‡ ¹A÷òdªÈ:;AO_Ø9ÿ’LF€·BñöVÓ\‚ŸZDsÉ«ÝEâ„wƒ£•|GQ‡pBÄȧ áV]HŠÚ™ÅxÒQDë@0MÛ®ODÓÒð!§Dòà=É£“JÃArèNýø‰ãHèVzûE`'“ ãþŽE|!é|'i%|]ßË} øQx.í0•íÒ†‡!Q«k쌾7¸Éºï'Yêf=sYT"¦ø¸Š#L ÑÞgÉäh8Žêb÷qþM{OGŽÐÚŠ®§…b¦4?„V £÷j–;c¤¹÷ð³‹0ƒòWLþwvÿ8&{»ÑhžôaJv=!¶_V= °¿®a#–@HU%´\ñylï™mû¼üa? »¡ks.¶MüÓÚn¸oæ7XT¿ 9œƒtŽ/V}5¡ö¢^PPnO¹,ボÃDE4Ô}ŒJן¡ fÎû67~Y¡#.4aÅ`µØ±o£`öo"oÙÓtî¼N&nµ½öRP ’a§m®ìÁgÓùˆe±÷à3úûÛÖ,yÙ¤aIß¿ QnwD=•Ҋtô„fîÓÖ¥7P”xR(Û¶.¿ý/ÝóQ«1ÂKο÷Š×²•F¡ÀEö­zr®åî¥ÖT§UaãÇoÌÇæ±Žil3ë5%ðq/÷pÐÜ’ð·Õ9¼zCeÉ)—Ò±ƒ†ÄÕ^5PïÍé'Ÿ3®Ê˜4„•‡!Üb"ò¬jw¢0„p¢âø‰ãg€1Bô’C•< ‹y¯<¯‡««!z hÕò*s0n.ª'H?e4™nX~BÄDws{›#³ítµ•†Χï2—¹›(¡Šzé!·g.ã››W²’ÅÜÍrþ}þÝÜ¿v!QºÉà 6ÓÕó ¾*¾ß˜I“ 9¼‚·¼ï°9QH¹FqˆZê8@€ºÈe÷1=ÜË=4Åob·ÿV&h=*…Qü[m;6Ãr;ŒAˆ#óq"¬.û: î}@<6UºRbÕ“KXâwÉìï²l×·­Â­e°aòW˜sûÅòÍÁªŽ¾S|wlõÕ„ZNˆ ±Ÿ¶Îý"c8Hxðy¤]&–yeð›Œá å«ÇýDhŽ~˜’Ž'ÄqYmù×S8tÜlš½kâgù‡»øÏ)Ó™žù™x´ŒÈ ¾qrTàìCÁO0™¼¸,ÀÍKê¹54QÆ÷æ.F_švn(qO½ï`‡I¡P\<‚ô“C/.R¦°Há"r’ ¹I–¸Mq5ˆ—.êé'È$‚|¤^dÑè ½ñZIç"#2ËB™–±J@­ãQó*yɃÿIH»ïænÜÌ]»ž zˆÐÇElxld÷uƒ‹“Œå·à€¸c48`ƒç«Â€Èù$¡Ú_áßiÄk BþΧMñ¥»Dgû`ß Ìwþ0Ûa) Ëu¬9ð!‚:A÷iÐ M 7™™YÁÁFöÙ»1K987¼nŠá=·ZXë“gž&´·¸±‘·é™,§MŸ¢YB¤{Ë'ÁÍí_¶ŽáØæü¢9E¥ûTW¯ÅZ®À¾³Dï´ŸŸºÌéÓ¸ößLè¶”.¬ŒÇ¾aŽÜ¬+aɲ`Ç–Øn&; ³Áæô´Â²ß&«w#ÌIÿغ¿QÞÄFhÕ‰áy2Lf'ñÓ¤“Îb¡¦gΆ<…¹ÙSw“Z~ÅóSBĆÎúXMØCA–…g.´ã ƒŸ¸pþ  Դs—sQ‚I¡¸ ÐõÐieŽø«Äðž5­®®WÐUâ©ÑÕDé&J7z²œ¨0}#žâó'DŒ"Zq’–Þ•øK…]¤Â.ñšâª0m’ÀG/94QFÜëçµ7,lÇMÒ Ï£“bZ¤×e ˜a±Lgüu¼éWð¦_iÚ™g¬x%{?½ …ÞM?AÁAeÔp˜^r(£ ßÐËVÿ·„Í:_a^Ì~fAC#`×hÌ܉Ü+ñ5¿,\c*$3‚Ôo9ÔKçǨ¿dLñ¸„“aLŸfÆj8véÖsçZ?#ÝpÜÀ @7²ÝŠå`_.ÿSNE§2Æþ¨Çj³b“Ȱ×VÈå–ÅVÙkû\£n„ìx© 6ýò}F0¶S.ó1²ûž ã8ŒB8þ¼)v [±rùÐRô!Šÿ·ØîèȽŽüŒ•J¿|ê]ܽ÷ßÍé¼ö{>HÁò§¬õK'­S¸Yø¥edšN¢‡~¹Mr=d}$ÆH‘š°„ª)šÒ¶um—¢Ë¸è”nÜQù][åö3¦¤KgAÍ€{Ík„ç<Ÿ]†c¸ðuÃÞègˆ¢$òDÖ¶>깉âñ-¸¼–õ–õޝRVÛDy×c,e©YÖ¤ ‚턈1›ì(ÖTÞ¼6*µ=èyÃç_%˜ŠËRXî ÊhºVšõ¨¦í‚NÙ3•rÀ)„k=f]!m¦p1¦ùœœ¥!®ŒàtK38H:Í©Á.†ðÐC„F*L¡•ÄM‡#ŸŒ×Áóñ0ŸÎÝGGð0DøH"†—AÂôááÕÇ+¹IM>K4ý,d Œÿ Àñ”9—òŒ"“!<$d MùÄñS@;zHâ&2øœøÁg$n›œ.óµ¼,î·aCg°iý]Ð]ðwDÏŠA¯@Š‚‘:JNDü•+#Íø®”u²éoå{ ½`9$nΫedßyåÀ땾œ^D _³¼Ëä24ÊC6fµ‚r@Éï6Ä’!vÂAưq¥œl¡Ü÷˜4ß"<Èíø‰ó ·“k+Sþ“æÙ4•ˆ‹•5 Ý[iý®_ØyU &…â/®&á™È)—õšvÞ[%ÄU‰t&Âh×€™ñ7ܹ©¸2ÄK ͸HòÞLÄÁS\£Ôt±øh§€.ZÝEŒq¤B¦².Ê9J½x4 ‡!< ¾©çYÃA†=Rê¤y—ÐÞ+Hã„ær âÅM’*©á0ƒxq‘Ûlà1øž¦ ÇYX´óY+¦ªOþ7®ò˜ÙvñèUøû_¢=øA Ž=%Ö€t ¼ç?j[^°bhŒx(#¾Ê-KÏ”)Ôp8ôl ›ÃuºÑÈ'—Ë/EM©Nqı7 ïç`e­UI‘`ÌÔK'Æk[Î>ÛçÇmb#`sÓBòÂa—ÜŽuR\ bUmo”Ëk ðëmŸ»M ¹ý«ŽþÉj“â¶í_ç©nU3%”ö>neúÕÁ\Ö‹åŽ@K凨NüÑÊì˃ͥÿÈÌ-?5?jmÝטïÿ¡Ø.Æ!}dÕt4ê%=ërmâѨU!·ABnÛ)¬’òx±Ä\'·¡Ç¶>öŸ­¬\Ÿš: WëIÈÀ‚–ÄqR'?£Ê]‰c3ï)p‹©ÌŠ@£Ørûé'—.NdBøqRò Jâæ¯«sáŽÿM)Ecí5+zÑ;¢òÖLvUM%˜ Å›"®ªÎðŒá^1L`%á£nqU[ ›\qò¿ÎÛA˜>S\È RÙ‰,M˜>"ôPÊ1sŠÐA†±ì7ÜÛ(4V —ÑE.2 ¹=Ôq€8~ª©gYã%BÏrׄ‘1Ö$Yô'H?2dp\Åœ¤I†Ü$ðáe>„éc;S™Ç:³{dð9kJÐ{ž–üñ—„kÖ÷”ÐÂÆgÚFÃQê…ÞÂ÷‘Ãß  ÊFˆ½(ö_Œ³;,¶Æ.á")nŒ)»8Vš¿, ŒÂ>™]NÀcû.×°Çml¨àÝx¢¯ Á”©ªQ¸6žƒ}H:@löÕ„ÚNçn¼X}r9 ±ª“ûåûaÕx²_?] 3€Èp]'ï×Èõ;b¹EDäçí”úÁ·îeS<Îlø©å¹Å6Ês?“][ʘêtŠßÒƒÜÎÌôOÅq0Yu´Õ}šùn<[¥ãêBhJÞ/ØÑùysÿíÿY&ýJÆÚÖÏ/ÅLÂ&JØ„R-V)#®JºM}b{öLº–Hãsb·Ÿâ©F¾§Û&®äñWzЦèÓ‚kà¤Ìg/[_4 ×±„8~š)a>\± Ékò¥î ÓKŽ~7Gmç°7Þ„^ &…Bñ& ,÷Yž5Ú¿Û–lzõ±ØÌWÑäÀ¨pJV‘ê'J÷)Y€ƒ§Éçéx>‚Ÿ™W ÂI/º´”¬ŽˆÁñú1m?TÈÿ®ÝH˜>ʳçŸIDATâøÉ£ÓBYŒ'H?ž èîÜG˜8~Ú)`+Óq’f¼w/ |´PÌ¿l[ÎÓŠÇ>–°Œ1ävd ·ÑNã3¿¦Ïq n’øã/‘ j8útqö?›î³;Na8@cCû™Èn6‡f’ëÿ+šOçI_!…íÇ™[ð#Öû'šJoÙ=/pÚ:Þ3ÚŠY·“á+è"—BÏq´ƒ:z‘ݰ*r5‘Ôw>&IÈæ9‡}¾gØç;…APSã ~;ÔgÄûËdºþ" â°jî,Üý}ëP‹Uಖì ï¨<ƒŽ÷àåÁš‰ÿÌm?0PÏ¢ké$š€*hûaJö?a-÷dÛçåo$Ù6ÐÀÇ­íè‡Ç˳$ÙNÝ1E-?£)ïÆ¬Àì¶É×óGw¡5kYj¡,òM›Lw¬»òïxÿ’nôYšÈ¶Õ}‚xŸI«~•%r¦&°âE©«rˆ”?'„©|vDAù¶úO½åïc1+Ù’úGó±DàJZ)2¼¿Ô·•'Ã…Y«¸œ»yu’‡»v-·LÃïWÉ.apP‚I¡P¼VÍYžuÙF’›È:*F»8ÄÔÍXÛËÂ0Êg ­z³¦à"ôà"efÖŒc¿&‰ÌÀŒî …‹™¸¹ÅÀ‘“!6EØ qü¼§vƒŒa'–„DÊx° ®Ø›$‰›\ºøk"—«|q^Zïççnæ§]3ùZîZø¨¦ž"”ÑDn’ég€païb¸gbï`´=¸H±‰YøHÇOh ’ƒŒ!ÇÑË툖9³ü›øhð(ö×PÃaŽRN?SØA;´S@Gèpç“ô¹)z‚„çJÈ©‰_€~B8>ÐÝšD¾Š…38 ‡=O?£“|šÎÈu¤rG‰éÏ~QŸ©*÷i¼™ŽŠëð0DÎÀß H›Â¦ãàAˆ¥v  ß΄h.ã«útöãs¿ A¸"–BwkôFÞG5õtú¯ƒ´~µÁCäu<#⇌Šé 8¾§@L·yN ,ø™*%#Æz 1˜_õÖîýghäì+( îýïÇ»áÖÎÿóüÛ6ÿ@ƒó„cÙýïsf6ZÉÀbÚÒ%¶ß¾ªO3nÝo„ã2*C¢a×Ç…¨ðÕаõã¦sÃX ô´f³ì€ùÿi9faY[*†Ù¾f€•4XÅ5;ÊW‰rƒÒ)+®(=˜ý/ß?«›‡7M€Rh‡à“}‡x6±‚Pëû=¶Ö¢;EFeEò/Üãþ÷Þ~Ñø÷ùy!6ð:ŠóYÑv´CNúoÔ9pÔuå}Á.ªáÖÍ{øÉÌYÒÆ_ÃQ©` ;ØÌ6Æpù¬e`W7I^kvó=<“̃[àŽJQ*"šÖ†®*Á¤P(o>¸H‘C/%4[µ­–É‹Û:'Ô‰.ŠIõuÓOï\9ßáxs—±Š#8ȘӉ«Y` ­?÷Wà$Í~Æ–1b«YpÁßiÄ€fŽs\ @Mú¤œ¢Ùmgæ:ñºÌI†ÓüÙÂŒ‹·oš^¶Ä·W“æX}יؓى?öÒ}=¥Ýzu®yæ}¿1?:<$Î^ð³1meKz·Ñ*ÌÈAhð}<ûý]§Y ÙUºÛ°à%¡'²î×üuñß™Ól…ÇYüFöç÷?|êÌbûßblæ·"è>rEé'ÈM ó"™\MôGDº:DCÕ<È£“ò!ÉèbšUöÅ‹®ÂŸx‰Áâ÷0„‡ã”@}ÎÍT÷þ‘ä˜+¬i¦ $ ®e ¢ÃV4l/„ ì–{ 2O ‡Ç yÉg̸©$nª8b¶ð)å˜8^Y;ך¦3‚Ñ#0Þõ{+n1IÓ¤)Û*20ÆæAngéþï@BfÀ5Ë ¸bJ©«•O«ìÁ>ÄtµñÝörNÛ1m,Ó|ùx VœR%â»ìËŽÂا¬D‚!ÐgjÂ]2~RAH$¯²b®|ÂåJâf‰qõ‚uîâ^îõϤ«•G'¯,ñò貚¬©Í]Lâ(å”»ËÚmsYÏÉ.š2Ù«»™ÈÏû¦ñ©ð~j9$ZJÝ ÏÜ™'¶G±Ë'Á¯¶_”sL …â(²ÊÎ󕬿rF–ìü:ºD XaD |¡Û[|ð.gÚÌt½Á>)í0Ú7`N¡¹H‘ÂE¹fpû&Ç/b•ˆ“À‡“4 T2u¢–^rXÂ2:ȧ‚Fv0…RŽ"ÆêÈ£“VŠÈ`“"¦Ø2®àíWòä"F7m#D›ãzZeðˆË™¢…b28ð:é&J™£‰ltϦšzj8̶à˜ŠÔvGo5[^´oE"Tñ(»Í(¡Y ÃÙ‰Aã"E«çr˺Hà#ìyÂÐW| ƒxñó{ >C¡±\ÿ‹ºÌï¬Ï7È•ú.õŠ)Èj‡Åƒ®÷0>ýkÌì ìí2¦h%‹…@“Ížsèâb3Ë 61‹‚’vBÍÂj,ù(w³œ‰O0~Ü#¬á6ò¶>cX]Œ­ù û7~Úlb›š8 ×®“¢ ‘èš”+Jv›–”Í2Ú—Ø{ ÖJáÕ’¥®ÅãN¬ Qù=qhèú¸U." ó~®n±„Õajè[¦¦ïÒ¦ƒ¾ð5¤q²€ÕbyÐÊ |oçbôÉ0cÊ*i Ÿ 6Õ¢—V‘˜ÈRMá‚G†Ð÷xд6^?Q(ÖÑüÍOW‚I¡P(ÞZ±5R[߉=½JÓvÁ{&Á+ýpKP 6yrð*êý–ƒšF9Rx¤‡^ÓÈ&m;5¢úåˆÑD™hDê„]ŽI4SB#ôf?cq‘"ŽŸ\ºh£±ì§žjb„¸5ìg,Çc…|7´D8",¥‘ ºÈe2;ÄËfPB3ûk¼7Ra:rIÕmÍ¡—A¼4SB;´QH•8ÈÐF!̧iœdp0‘Ý´PÌaGYíyEð[b–…þ…l!LŸ%F€Nß ‡p/©âQÔrˆ""^Ê4Ò縆päyâyW 8I¢äJb„ðñ2x` b4!Y€t¬ÈàZÌ÷Ä}»B"ÿJÃæ3û»…»ž7›.–ò íNJ¨í„Õ~ØÌLñþÌf£†23r(üî¬càXä#ÔrˆxÅh3@}kÅ™îü™Ùôyíø¯ÑL ë} Z!>ù*Ú(¤rߟ…ÈÊw†jD\ÓNét…U}ˆiÀBÛá†×Ô!_oÏx̃ö²’G§p÷ŒÒ…âøXÉbò‘E=‹E\Ú'Ïf5>n—éy­ñé²}h}ãøtlŸÍRÜC¿hvþÇR® Jû¯týâ4“S‚I¡P(ÞRÁ5Év‰¾ÈÈ`ð±*]#AyÛ¨ác¸_^øsªR hNø#Õ\I‚.rÍìÂA™Z6 ¿£Õ–^TO5]ÒfÙËxNô‡ØœÂïÇ€Rû‡(?š&“©lç¥üw²˜/¹·à à ^Šiá«-øtñ>&±‹5܆“4UaK¨“å®w0…(ÝxbéÌÕSmN[v5ë[µPLùéç(å”ÐÌQÊq“dG)'9l B¶2EÜÇêXá¿“¥,ÅOœ]Lb0ÏË6°q„JbfX“ëF"ÂÍèñ\K¤ú9bŽ«™ÎVúï%Xô¡Ñ âÅzr… ê#L1ÿ EÐý;¢]ÏBz*¯¥JÑS²ëÉÊéá~‚K{'],j|º_‚+G|þZæ‹ý-§.r…ð1*¥# ™Ah¢5Y•lf&•…_2Û§+ú7n?†ŽÌœ«­Mçáš LØóˆ9¹hÒ÷¸¯ý›Võô"Ø^ðy¦ò á>•A2$¦KÃaQ¼ õ)âEWYëšIDF¤1•ܾc”’À—åÊv’ÇN™Nøp§/¶i¢‚#j ×'ÚJ`7hŸíB×s•`R( åp MëA׋Ðò€gŽÀ{ª N Áx²§H8 ~ø¯2sºñOíUP¿ïcÖúuj<š+;’÷µ ɹ£b»“4mB;ü¦xIÜ<º£|ðÛ’±ð¾Vtѹ‘ ‚ô3•íüpî|îZ¿œÔñ­›/éI hçs;]1ÀdvòÑ£|;p/9ô²…xb YÍŠh5…áffšƒì>Æ™®—ñ}T#D% Ìe=ùt°ž¹$qsÓÁ&>>æÛ˜Æûë»ùûêÃì@´âÇ>¡¶0ƒmL£5¿ˆ•,6«Ú¯*ºƒlà`î')Í=fn«6®'¿¦ƒ !\óÄvßí¹•9l(£6¤ùá\‚¾Škx_°§úEÜWSõ,e©p¤¤ÃÕYûÓm$™Z-û@®Ù½dךr‰Ç†œÂÉZÄ}Lð?"¦Ü‚Blu\G~‹p…öº?ÃT¶£µcŠ-/ƒ¤qrgî VôÜÀè£q8Í™Ìäô/ͯÏ^V³ +¨~ˆÂMÒŒµ³‹¨òù³`±tÃ$/ïô¡Oíǧ±¿ÞàïF×uýr;¡hš&O,º:»* Å›ržÝ 8Ñõ©hZLŒò×»D<ÎïàÖJ1•skALÁÔJ7ˆrcr+ÆÆh£Ò ££¼˜ @\]%¦Öž=â"L‡ë··¦Gç×B1|nþŽQJ7Qæ³–: çÃT¶¡‡ï/_È]w/'‰›ïß½+—'XÊRzˆðý# ùAÕ|:ÉcÓ˜Âòé —ºÈ¥Œ&3–,Bä“ÄM­æãl6¥›}Œã;-KùÏâé”ÑÄ ž6¾5´‚y¬c/Nµ@žôr„*¾âÜÈÃé TSOaîå|$XÂ2:Éc7™Å&"ôÐL iœÔp˜v 8Œ(‘KžÄ«lò}™fJXûd`Vø'ôd'“EÅm'ä1µèDd:ú£ˆf²`»sa”3ÅÉ5.耬>Æã ¥¢½Èƒð™à^:ÉãøŠBn¹s^ùùÁipÞ¿¬‹©l§•"Y=^°?q¶1§gçsÝÆf°…µÌçă!¾zûzré2³c„XÌJ:ȧ0~âÔrˆzª‰ã'Ÿ*i`㈢–Cfí]L"—.J9FQÒ¢‘ Yù~3.R¬Bˆ¿»YŽŸ8}„i¥ˆK/áçxÚ) ‹\º‰òËØdî-ÄOœÍÌ$ƒƒÌc½ä°‰Ydp¥›ñ쥅bê"¶{Fû¨ã¿xpª(ž™ª@›œÁï”záñz`P¦éÀЛ.âñ¤“B¡P(od¬Ùƒ®O°ÝÏ ë4mÜ4 kA׋ÅsuˆúLí€[¦ˆ ¶Ÿt×£bši-bª°TбAD`v)¢ŠwÑ¥_ ²ZDpþ!DÓß puIŒ ^¸=»N¸ÎÑÁÓsó¡®=ÒC% tå/ó+øÐÚ*i Fˆ‡×L„]pÓ£TSÏéP?r„±ì7Ñ–×Àø\h]äÒF!¯4xùlå.Ü$ùyz¤á*wœqìc/ãyù°Ïlºû ñèþZQÈr ¼Ë'Š­fpðüܰh1FÔƒJ·¿NÃÿuŠ8¸^ ôC i ø¶O¬ëãõèzµÜ»l©J0)Á¤P(Šwˆ8k·Ü1m3Pf‰1'ðz?º”ÏwÀgòá(è1ÐJ± Pþ©M¨°/…+¶Wвñˆr-Ò!‹g‡ƒˆê<é® M°1õuè‡A»áì€ëw ëSÐÖ!Òü“Àzз€¶!{€• ·¦ ½ÂÍÛŒ ꮇ¯V‹ò¦nt=ͼԋ®ç¼µû@ &…B¡P(ç?Æ6³Z¾¦ ÁtY­·L …B¡P(gÇ¡6B¡P(г¡U\fë£íBÓ6Žì=ï‡IÓŽÀ‡«` "ƒ¡ ¾ÈV h'—."ôC/!byAôÉIØþ†ÁwCˆùÛ¤í/5ìo½Ÿ–÷Óg¸Ÿ±ýÏÈç†?¦sJŽÌingÎã5gº?’ÇÞÈãçûü›õº‹õ¾7û³þ'¿ãr^¾·Ë6rœá¿ýÊUmKÅÛýwîÀrYÎuÛq–Çgz†(ù`¼È9ì¶QèÔ)_gÿs#b²<òÏ‹ˆ“ò#bªJ(ôºÞGŒM”ñ•ŽèùJ0p“þf³‘qì#¯ÿhEôÊéAÜ&ŠŒ¿—³µ]ï$mºÆ®mN§ÎöÇ9nŸMÏ`•Áà­ 3ÿC?öËéÄ¥P(Î<¨«ßÉ›ƒã,÷Ïôœã,îÿ¹DØéÄ–ñØé´”ÑÇ8ðnDp{Qy~:Ì­ùë™{Þëÿ¦®i,ÑÅŽ=º“Lá!¨GDþb)&o'„#”y-Û0JœÁ ÊØËœF,qšç8Ã}Î!–Î׺õR?—ãIPØ ÅÛõÜt®˜Ç9‰ˆ:H‚³;WÃÿ\d›Qvá4ô*žOB>Ù5í$/ªXÒu]×M!t1_¯P( …BñVñ¦MÉhøí }½S …B¡P(.#‘@ÎËq唨R( …Bq1¹l›ï¾±ìç㜩ïùŸûµíÔ÷¨cN}Úvê{.oy&MÓ”¤P( …â’âMs˜ìÁÛç£Gúz…B¡P(ŠK^0IøœM )¡¤P( …âíÈe[¸R‰/…B¡Î …âb¡zÉ) …B¡P(Á¤P( …B¡“B¡P( Å›ÊeäP( …Bq1Q“B¡P( …L …B¡P(Æ%Ûe¤E.UQL…B¡P(ÞyØ»‹\ˆfp^ª+o¬ÄùÔWéë …B¡P\bÉ>æ_ˆfPSr …ⲿªÉs …âòáb$J0) uU(¨ ùí+Á¤P(.Ë£ñ¸›t®ÇÎôœr¥Šw®Xºì“:©) °$]×O9Ižé¤©ëºyRµ‹'ã3ì+ŠK_,T3\’Aßö×ù(Æ‘¾^¡P(ì'U…Bqiÿ~G’)w&ÍpÉ–8Ý Ÿm#(¡¤P(.Ö¹F¡P\ú¿ß‘>§b˜ Å;æ*óíò9 …âÒé6B¡¸\¯,Og«O:ÛUåð¸%å6)ïà /Õ|W¡P( …âì¨)9…B¡P( %˜ …B¡P(.Œÿ¥º.­° È¬IEND®B`‚snd-16.1/pix/averages.png0000644000076400007640000001140711674670067013457 0ustar bilbil‰PNG  IHDRÐv¯aìÑsRGB®Îé pHYs  šœtIMEÛ  +b±N™IDATxÚíÝmÖªJ’P<ëL zþcì‚ýÃ[6•™ ø¹÷ºë\_EH>„Ç0Ëõz]€sü±@à˜îËå2}Ûår© ÷ž´}½^¯×«Ì ¹¿ÍßÇÆèá¨\€ß ÜÇj²µŠ8¿ÆI“ðÒÀíüH8,pß²už°oý¼o§NZ‚xjh¾åx1€ß¡7Ü p7Ü p7Ü p7Üðþž:öËåb pŸåz½Êßü²çv)ù_ ¸@à¸ü[Onn@à{å—E¯î缸€ ÜŠÜÜgEíë¿®"»¯4÷AþçŸÿ_ÿu]§ÀÛc¹û°Ì ¼•Ý•/%3~gkß7Ât)Iº‘ômZ¿i1½|Gð#{";\ÀÞæì™}μ8•ú‘ý7ƒ7Ü·.ðË¿/Ãmìþd±BqQ4’wí›â¾5²5m6-ÏàíñŸ7ÜP† }«ùáŸÃç4õ#QÏoä#Ÿv1å#Úö´¹ÞtðhfÇî(n-ydÆó‰_9@æïáýìD/í›Ó×O¥ÙÓêáM~‚*±öïvÔâǃTtMz%n:$G¼áAwkìÛëg§’ðH ¬'àݣݚ;‡+®ÿú;<þ5¼é¶³‡é* :IìÖ!¦Ík¢XÓ¶(Í$Y'JQÑÆÜ,öaÔ›fÍú碞yeè¨Ãpy2è·“¼J •ÇÖ³Ÿh“-­RhNýÖ¼â2lÞÑŒ¼¼·Ä?¦®ÃÈÛg©áZ޳y¦O2SIÄLÃ4ù ?×÷7ۙľd•Í£_žÃ;Ýi'« _þѾ«þmsø8:šL¿.&_bûñDõ‘¾Í;ŠDÉàbý(šÐpàaæÎga=Ú­éhúÞõ«ãóª ÷´DT<|&‡íäC•ç¹áãázM>uý—­~ ?„•¢x³+>]›Ê]Ê×4Ò ÷5ÃÊYþ°òueÎò`^‹Ê¿WÊÓZW¾4êonTÓÝwåw¤beewm /¥œW=Š*py‚ßTœƦ߆û–bQ'Y§ùÑ}ºö“ l¸‰‹âÓ¯‹Óýh²#ê×oþ5>ù†œÇ—hoý …ŒÊiSé!*ä?éXÂ÷Õ\ž?ïnŸï¸§5ù< T‚fþcÜ0Ó$Q£~€ŒvÄù÷Ýé7ÝéÀÓQù14i^¥v2ý±obò)V&·ã׺­Õˆ­¹¼…+ ­R”ªç³éodù§)JuI²œþ>üZ•o‡ÉÇøÓb±ÏØŽÌTŒD’p`]êé·øöçúßhœ·^ÿyò]w”¼‹Õ£¤øW&ùðÅÚR%p lù¨Š? Ó[1î˜Ð4š'߈6u+L^TyZâÎ^ó†Õ÷¼{îÿ¶µ)Ó$­-V‹Ö»¾l-2íë¨ |ì¹õó+€Ï R}BZåž0NõáiËÖïG;|þÞ±¶™D4LÓ·¦òï¹m¾[ঙMç1«k•Ô8ìйïÄ…aDKº1LK’}lZ '!UJòÃð}Xj§^å%·(_&Rò¬\ÉÇ&-¹ ~½HöHÍlšÿúaÖ‘kXo['¹&óå‰íg“܃3¾ûíÜ=Üîÿ6ƒåÉt ÿÝq>ïzÑŸ?‘GíbþÎ_ÚëëÝ'v4¦yÜŸ%ð`7Ùݱ29›¡8LtVÇúßhœg§ai¹3|iøÛk“*ò\¸ÕÙ±ië¼'nzï𥼺y_&·ÁÖÿæ£]¿«_Í`QLŠÁyUxÓ3[ÞãYðUoÞxþö`ýïƒY¿º©ÙÒöî½ÅûW¸óKV-Á™7ùµÞ¢4<_0oXÞरº£&úøÕ_°…é  y’XGÉþwça³•Ôù&¥ÊGšÍf_íë£yÔ% ýy­:Ï—Ç>àü´¹)Ž6_.—æqqlï^áž–-§×‹Ø:æC¶<«äY™ÊkƒlqêÒö÷‡ËCIÔorYŸţäÚç¶a¼;6­F£jjŠÓMÜ\âªä½„ÍÔ´*™¬µé›ç‰¡Í{‡5¿~€i-0i^åÏᘥmöÄc«ŸÍûÈØÿY‰Œ÷ÑÞƒæä¬¼Õð÷ñçm‹¦2ld?@Óžû“ÍH†q¹yÐOk= ÍóÍblfüŸÞ¼Â}Fùöý«ÂŸÕ*¾-+çg=§búœ c÷°?ÃQ_à-óÙI-©²£æº8¾HÙ§Ã&rõcÞ4wy)´Ï…}Kº½×5ŠÑMò+ïÛ—¢!+“‹²ïÖIäc¨Ïx4Ý(÷_ŠS¼^¯o¸áÛ‚ì’v‹Œ.<´Ž¼/ ¦ÓiåWGŠ^*_”twgÐ&½5‡ÿM¨MPû‘äq0[IÃòÙ6l:›Q–Q™yXâ­4>ZbÉÚŸ¶-jgÞæ$gNû{DEñè§€Êgjø¹øç%ÂÀ]Vói’Êë2*Ð;þöíÏû¶Âg&à­Ð䨙G›€˜ÔG£_ÉûW×Ã$q°Cþ‹y%ÒUra—YY±òÌ4U†¯Ì{¥µË¬BqÒÑÊŠÖà4FYp¸A&c(~¢oGÓe• ¦ôy™?|éX¶~MͬÀÍg„à¤JÚçÑMW3Ý€£—ÎèÁ G Nç¾zjò³{”z§©4 Áy4‰ês•"_=AFÝ6EºUØbFŒÊ–Q†}0¢—¦I·R N¶¼98Ú*’® }3òœ7Ü‹›ë#ŸÓGW±§P½Kw=úþ3Û% Ü<)%ãf=©3DÝ9Ч‹Ásw÷õÃ@Ô£ sò®$€F£Í•ŽNÌÚQ[ÍãWóÒôWþb•19•*ÿÑ<Ÿ©it‹tRàÌLþèŸç¿­¥Çä›ÒR83oš;·þš±; ¿înƾùKª³œê¯Eðs!x:زd·--^Ã!¹ŽìðʵQO‰¾ñûn6Ñ\Ù`ø€Ï©¯šú´x“ tH¨œ_µÌ~Zbè¦t›ÿ¹ŒÎÓŸ¼žÙ¤“CÞ¿6ÿR‘$æá²­t`6 ÿ­¼yß¶¤Ülë‘síýÏþÁ´mÅ«› Ç6/%gSE]PŠÁ®û’4YɯÉo õìU Ê[ÛŽ`—'û“êÇ‘˜ÍŸ—leÿüw»Lìú~W,µëõ®ëÇÍb¼ÿ»^°ëpÅèèÖ²}Àm.CÛ<3þ> l9Å~x¹Ó(M‹…ɘ×áuZµmþ½¶'º¨ÂÒÕt£'‡ ú2ê}B—½{ÑJV[ʾëõº;Flª}nÏáæÀêæwAŸ99iÕRú8ßa‹øÿD8¼—ãürMfío,w *$G£mJ×Ë’uºFçdFúH=\küXJÎ{ô;N$—ôj’å’^ c“‡çñD]’îÃ@<íöP9 &Uù~FuÙfødB•Û¡ ë¸QŸì¼¾¤¦×ŽØÈë ø‘©<ž¿ß6Égpž?¯ýp‡}Ö…Øa üÔ¢x>òuÆ Žfg—ïÅþ(Ëû7‹®ÿ3YÎÉמ[Ÿ0æ¾äÙtw·$ï±PéÏÐô?fëaÖá|Ý«ªÃ;%ñ4J?}¤¾ëŸ\§ùs8ðIq§oIÔ˜Êt·öR]þ»¶½cNE=K¾Û¹î Gôé™yQæ¦Õ¨WñðjÓÿ*™{Y¦ Øõ{`/º/OæÞtUÑ~˜þj ­ë—ýª|Æ“;r=’H’{€ [U¹üŲý¹G%ã%>S-ª7?Ò†7‰àMw~ž,y{J,Kxwet[¨Óó4¸Gywxbsšà±áØîu9øì[Ê=ré·âÀùEˆ£ŸtŸ˜Æëaù¹x˱f¿Qœëú…&ŠgÂõxwè¬|T÷åçìÉx¯Àýøn>{&:E/ˆ!ƒ¬œ×—òµ2\`îóõîļ¤7}Í“îôBŽJËQ·é~„ÃvîÈUÓ~º•„šLe˜þ‡}yw_üáù òÁΟmÅq€©?¿2£ë~Ìýå5xïpü„1O/N¼Äׂè¯b±¤—Ôh’J3ÚüÒKíúnýãi­½RÓíËÀ»¯ª;½~ð!ïÔ«ù¾O6|nx(=G×M«Låræ)¶•¤Þèä® ý™vËìË–®½ù½ëŠ!u땎í:\¹ÈÆQÑS„@àæ “wr}âMÅã忯ÅÅâJŽO.÷1…(§Òñ ‚“pü„4ù>õ£³X pÞÜ\ïÖ~É*A¼‰à˨ÓÅúæMê¨ÿñt±/ KÕÜ/…_Ù˜<\V:0$òþR4XÒ¡bS9m2kyï‹õ袹N.ÖåÚÊJŒF»t÷(™Þ¯ä»ßI¥ pŸp‹W~ØÚÓà¤ð„È<+'ƒõCæáxS§µÞþ„I{*5ïè wÍͨ‹ -¹Uuýl¹¾°½NäÍã}Á·rNÞK‚òOÝ´ÏW>Ñ]‡»ï*œÐÖg²¦ÓípÈ~øæß%(9ïèÑŒ¿iF —ÚE6ú& Û™$Ô­ß òÞ—‡]D†÷Ùžæ×MwEÙ1@}á쵂 F»g…äNÑMö"i%$E¡0Ãt´[ßMq:žä¶|ý"Šn›ÒOˆn/Ò|ÙHz<×oMX¹Ÿù¦÷nàó>™_7Gð³^Pá&¹{Õ¶)|FgÈE…êJÐï3k’)ûá×ö/-£Ë-ïž•x“ø»£ªšßp™õÓØT{®|ÊŸÜÝUãû²©´ _ãî&bF]>¢Ð\)”n}rú|±[àí¶õT€ïÜÓØ7,ñÀ›{ÍUJ¢þ ÞnÑû-Iê|œs¯RòVw‘€o Üýí-q~Ê‹n¸n¸n¸n¸nø9û§.—˲,×ëuø†Û«wÑ`À p_.—[†¾?è Ù°3pWÜ‹ÜÃäÝ”Àw ¿¸×!{XOêߢ6÷‰öõEI:·|îx¾r¦¬,ã±²ŒÇ±²ŒÇʲ{*#]W¦U© ®­p_¯×ü*%÷gOÀÖÀÝÇèM½´€µ¸ñÍ»åû·j…cei…ceY8V–öX8oÞwš€ Ü pÀgº8Σ 7Üfs¿Ìá3|Y¼üÇ “áßIÛ·®êɾ/mß“^%ž” ¿°Â-@¬9~Í~Ç{æÀ¿V ßš¿ß¡èà¤I€ï¤° pËÜ77Çcdn€›×ž¶÷…§ Þ0ëY»=™?ð}‡û:à×ö~M ]£à›÷ârL¯¦K œHÙNô£N…5¶öºóIEND®B`‚snd-16.1/pix/sceq45.png0000644000076400007640000000211211147553270012746 0ustar bilbil‰PNG  IHDRE%â) sRGB®Îé3PLTEÿÿÿÐÐÐÀÀÀ°°°000pppPPPððð   ààà€€€``` @@@µÿeÞ pHYs  šœtIMEØ4¿ÝáÝIDAThÞíZ‰²« eS òÿ_ûXe¹P[í̳3dæ¶Õ 9!†p¡o GCn Ñ#˜ ,»Q¼”|LÚÈ'#ŠWeh‚Å›¢–$¥æDà‡Êçb<Á»²€I‚!7Y™è¾ìágDo›ô2k½›‹ß "6ž/YÑó6§ 1¯Ï ›!5y¸°‡x5m¹'øé-  ˆz‡¥D0=Æ­uÅy=‡8ãÿÏ]Œ›‹dßð b’¿î´-á›mõ…Õ”ËV ' Ÿ“¹w@À•÷®Þçé£u)c~ÁÒ>&DëàaÞÔŸ~¦/’û z¢“9ñÖäÎÙ`_sp#û¬ÏùT?¡œv2Øü±åE«œL“”´@uV‹j(–W¸Ú‡d¯r2GÈwØ7vÄ®ucKñ>|$@Íd€¹(rŽIsµ£H²ÛUi¤vqtÍíHX3’ú”´¥I0ÆÍÚ '…œÌ%؆~ê°¿l_•ì=;çs;Š-+P?´˜±²xõF1äˆei\ŒV×QBpsŸØ‡ ùI©ùäP(ÈÜÛÐ@i€ÖE,t?§Ò‹bËÇÔMÆ„aa {ð‚Q´Î)ã%¢Î—´u¶kN*‘¬òÙt»,`Ÿ5p(d®€mèG ûËGTQܼ$Ÿ³(f.·|¬AýdL®ºœÞß]ѳ™Ú.‹òPF±kN³™V¥DñsClÞù¡P¹¶¥€:ì¯aëQÝÍÅf jÇalÿ_¢ˆYL@Þ­‹ùmVîʆ©gnGLº•¨‚ ÀÄnqÚ\ƒ> 2wÀ¶ôP4dT#l¨zkZ±^[˜5¨™ŒX7Ûÿš˜rÕè<ø²ˆùî’r±.ê.3;æˆBx¡Ÿ¡ 5îÑ™+ÐLpv(d.ÁþÕ@%û˶4ÂL¥KSÏùT›"f *yÎÀÏè{“r€†²wq«gÂí8HÄO?£´a[ú4šÑPɺ ЧmG†Yƒêú€VEÝGÓs~GèMØ/HÑmPrÝÐG“épœ·Q«›0?í£phQuüz}2jŠôLéiÛ~è>t8Ñ‘¥àß:î^rWøx!æ+A„…»Û ogÝ/é¾Ûx„°ò¸u<ÛkËBvzî!Ÿ43þm'ï\e\Æû‹·E³âû‹#¯—ÅœÿÿÖ›w_”¦Ø&ü¥•ÍIEND®B`‚snd-16.1/pix/srates.png0000644000076400007640000004303011147553271013150 0ustar bilbil‰PNG  IHDR¼pü£¥sRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ ( :Œ IDATxÚíyTTW¶Æ?FAEApbr  ¢â˜8£1šÄ˜¡»mÖëÎJ¯¼t:É{¦3t†NH¿N¢™´ÄY£ˆ8"ƒÌ ˆ"2Ë$2ÏPõþ°«š‚¢êVÕ9U÷VßZ®e·NÝ:÷ž{öÙgïo‰Åb1 †V‹Eèíí466ÃÞ~<ÄbŒŒŒ`nnÍ:ˆÁ`0 1ƒ—Á`0 ƒ¡Ï~K—.Ép÷î]|õÕW(**b½Å`Œ³gÏâÚµk2ïݹs_}õJJJX1<'==ÇŽ“y¯¼¼_}õnݺÅ:ˆÁPÇàõòòB{{û°Á¶fÍdffzzz%ý÷ßÿý߈ˆˆ`=i$%%±N^^^èèèy/%%kÖ¬ÁÍ›7]]]2cúOúž}öY™Ï$&&¢­­u¨pçÎ466Riûƒ> ÒnSS¾þúk*mÿýïGWWo¯×Ì™3ÑÒÒ"ó^~~>Ö¬Yƒ„„é{ÿøÇ?¤cxïÞ½ “ùLvv6>ÿüsdee?Ç‹/âÓO?Eyy9ñ¶;†?üp˜m¢)===ø×¿þ… .?玎ìÚµ  ÞvWWÞ{ï=*}’’‚ˆˆ”••o;::Ÿ}öñëŸ}ööíÛ§šÁ[]]ÊÊJÀk¯½˜ù„Ê8;þ<6oÞL¥¯óòòpìØ1œ9s†hÛ­­­èííÅË/¿ø)))ÄûäèÑ£¨ªª"~Î¥¥¥X¼xñ°0$$$àÅ_¤â222t±X [[[j ØÛÛcÇŽ2c8((>>>ذaçvZZZ`oo¾¾>*ç9nÜ8¥‡:†’ ÂÂÂpåÊ¢mçååÁÇÇáááĽ¼ÍÍÍ7nüýý‰;Š*++1gÎôôôÝ™hkkØ1c¨ÜwïÞ…··7¬­­‰{xoݺ…9sæ`öìÙÈÏÏçnðNš4 ®®®OOOéûƒÿ¯ïF3èäÓØØˆúúzÔÔ԰Γ'OÆÔ©S‰Œé%K–Èl¡’ -- Ï=÷:::ˆß[---Xµjž{î9©gŒ¯¿þ:ÂÃÃA|’ONN†ŸŸ|||PZZJ´íüü|,\¸JxŠdâ!Mww7,,,àåå…ÂÂB¢m§¦¦bÆ xð௠ÞiÓ¦i<†`bb‚   ¤¥¥]øIB &L˜€úúzbmÇÄÄ`ëÖ­Túµ«« –––066&ºKÝÛÛ ˜˜˜`úôé¸wï•ó·±±Akk+±ö:„mÛ¶Q9×û÷ïÃÅÅ…x_¾¯œœ”:dŒ…<™Ÿ;wŽh{µµµT{O’_"aùòåʧ1x‹ŠŠ…èèh\ ï¾û»wï&ÖÍmJ†|ˆKÍ0Ô§°°QQQˆ‰‰ÑÉ÷Ó48ìììÐÐÐ@l‘6cÆ vÃü›ü/¾ø¢ô5I/ìP©$’†úÐ8ÎÀÀ@¤§§ úZTVV"** ?üðÈFéï¬L’‹¡Ûì¤Bä-´7n܈“'OjÜvff&æÏŸ/óž……º»»5n;%%O<ñ„V®#Éð‘’’©‚ ØÚÚ¢©©‰¼Áëéé‰ÈÈÈa™´EOOœ‰J ä³*õ sssôöö²Ž3yÒŠ?Õ^^^ˆŒŒ”‘œ$Aš¡p’’5W®\‘ѧéÁñóóCNNŽÁÞûÚ ñðð –¬ÜÒÒ‚±cÇJ_ %þTS¦L‘žPd„Ñ4xIK“icAL yá_¤ÂG†ÆÀ³Ï>KÍéHZ½‚:¤ÁÊÊjXÙTu‘lS>ýôÓ8zô(³àF@ßcÝÔ…–Ö" ù¡Ṳ̀’’hz‡h*) ÅÑÑ‘ˆ†°¼s&•Q?´¯i$b"G2¤YØ™æÐÌÂ_·nΞ=«q;L5I{È+:A£híE‘Þ¼C%4E¢ÊÐC·"„NZZ‚‚‚ôî:Éó*ШL$$bõÚj›”zÀà- $—†bii©q¨‘<“$ ^ÒóŸ¹}û6fÍš%ó)E”œœøùùiíÙC‰Zùùù˜={¶ l]ö5‰gÏа½6xÚãòåËX¶lÑ6‹ŠŠ ¦‚ŸINNFpp0•¶åyðÆŽKMölÔ¨Qèééaõ߬X±/^¤Ò6Mù:R6­ x4 ¥‘¼»45„IláÓìëÁ-$ÐÜquqqÁýû÷y{_‹Åb•CuoðÒ¨¾Ãe°4ÐSO=…_ý•XÛÁÁÁHNNfl€È“«Y¸p!±C!)=ÄP ÉB Ãc¤WÕÅÊËË©TÔ$vRFBJª"Hƒw°„ÆèÑ£5.` -1g}€tRŸ>*}¡¯¯fffÃÞ7äJš[¸4·,[[[acc#󞲌f]#)û;”]»vɨ0øͪu$[¯]»†Å‹kµOh†iмp'RŒäñöööÆÝ»w5jûøñãØ´iÓ°÷·oߎ_~ùE ÞÁuÁI@3‹U ± ¨««ÃĉõBõAX"! Ô¤¡¡Ù÷$‘' IÂHLLDhh¨Öú„ïÚ£#õ5 'ƒÎ"ŠöóÁ××¹¹¹TÚ7nš››©´½sçNx=úûûåfØ«Š¼R‰šÆæuvvbôèÑz1¸´YK^ŸPäÁÑÔ;ÔÓÓƒQ£F ª?%ÎÒL¦Ñyšü¡¦¦ŽŽŽTÚ>{ö,Ö­[§õßdˆÊ>III ‘û7MçcC œÁ+/ÙÀP·*•­bI¼òؼy3Ž?N¬=šbâ´Ñ·Šq|è7SSSô÷÷Sù^M&‡‘d²hcoo††^^GšŠ´P´¥Íçía¾!ÄP.]…3ÐT#òññA^^žÚŸ7$§ iÐC$¢Ý$€h<Ô†.ZœQUUÅ.œ€°²²BGG3Ò€¼]m0uêTTTT°Áb€L›6 %%%j}–æMvv6æÎK¥mE»V|ÖáÕº¨ä&8ƒ·¢¢S§N¥þ=$âJðóÏ?k½$*$,h$кÖ6wïÞ…···Á=¬ø*'7’ÜßšG@EåN]\\¨¥ëÖ­ÃÙ³gÕúìùóç±jÕªÿÎ*ljÍ\Mä%Ëò]È!òÙ’W y0+W®D||<3xqçÎÌœ9Sæ=uÛIlA$%%!!!Aë}D³ž7Œ;–x¢‹PWÀBL€à;«W¯F\\œZŸÕerÇÚµk«ÖgSSS±páB­ŸóŒ3PPP Ögizâ”í,‘®7]#>ËÆéŠÝ»wã»ï¾cño4)ôA3÷àÁƒØ¹sçˆ_ºt)®^½*|ƒW[·nÕŠv¨ªäååá…^Ъ†æà›ŒVp?ílšš´¢ YBWºØFãë˜Ó¡în(ÛµÒ§p}\?ñÄHIIaRv¨Œ  ^%n¯\¹‚°°°a+]°`222´ÖG>„ƒƒÍõmi$¤Ð¸†ºBßôUE]õ]öÛúõëqúôiÇ–¶Q÷yÔ××G-yU¨ÄÅÅaõêÕz·(R>†&)»>¬êpԭƨ« n‚3xuQi†±ÔÞÞkkëaï{{{ãîÝ»·onn­eYŸ>}ëׯ'ÒxÈ‘®¡·’ôI^ P½Òšƒƒ>|h0Ëþþ~˜šš ꜅êÁQ¶Ø¦©ä!dWZã²¥ìé鉢¢"*ç¢î®M©;šJ+Êì“Å‹ãÚµkT¾ÛÐÆƒ2§ÉH‹"­UZ‹5˜UóP4ÉXÕtÐÑ’Ù!Ý®ãÉôMÔ}h¥5]¢®|˜¡y,ôuìäˆ@³œª\i-## ,ÐÙ¹¨ëuÔæüHe†º¦z¹B£¸¸#þ]“<)eù#I9j%¤¡½½‰‰‰{Lid2ÓZMVTTÀÕÕˆôôtÜt´Dëi$®1šNyyyðñña¨…¾Ö'µ†jœ((HéV¸ºÐwSšqÖS§N¥Vn[ÝyM—zï4« #99Y¥Ï(+£h S»cÓÓÓ1cÆ jzz|¦´´îîîÃÞwttDGGuE[—B)Û«im÷ÊÊJ„„„ ,, ׯ_Ç÷ßOmË“ ú3ƒkâ³™™ÓùU€®5È É Ëær¨­¢^TT„¸¸¸=i¹¹¹ˆŒŒ$v¢ÊlllÐÚÚÊû—¬IJ'  ¯¯OëÛ¢å R‹[[[455©ýùââbLŸ>ˆˆˆ@GGŽ?777à×§Šq ÊÊJŒ5Š“G’à£Koª¬ZµJe’ŠŠ NÉ–’˜ÈéÓ§“Xÿ[2IhÅ/Ú£²²'Ožd’‘r !kª*9OCRFàT O(ä?~<=zD|•£Žì­ ¨Ý%K– !!è÷)KL ARR’Jm^¸pááá QuÛ¶”ÍÐd+++ìܹÖÖÖøá‡põêU"ºúúÀ\xbýúõœÊè qëW­Íû÷ïÃÅÅ…ó€¡>\BçÌ™ƒ[·nQ9‡eË–ÁÄÄDp}7¸ðC–;wî`æÌ™TÚ.//çW*Çœ¶ÐtWWkïHTWW£½½^^^rÿ†+W®ð¢³e¥Ç¡W_}...øôÓOÕòÚ¾¡͹Ô9ŸP¶@r_óÍãÍÆ®æÏq.š³ê’““£“¹L“€¾£ŽƒŽ¦,Ynn®LQ/¼YYY˜6mšÂmku¥d”n1¹¸¸àþýûD;÷É'ŸÄ™3g8ÏEbˆ¦<›6yöÙgÍ‹sÙ¿?^~ùeN°··76mÚ„K—.©õ]4¼ß Íá²èá#B4¸J©ñ-ãÖ®ƒ ÙÙÙœbåiVD㓾8›k†Ã5AžN7±§¬H$Bff&•kkkK%{^•ø`y:¹Ú„”(wQQ<==q£r‘2Ò–tÓZ$ƒ‡‡Š‹‹9χÊ_ŽŽŽ*ÉÖñ%KzÓ¦M8qâçã+++1eÊv“2ôu¶Ù…ˆ*á#Ó¦MCII ç¶ccc±víZ½í;yùRÄ ÞÌÌLÎq®®®(++ãÜ6¬gZ^yå}åˆôôt¿/..«W¯Vzœ:‰:º¼êõ«›¹®NŸµâ-V®\‰øøxÎÇ744è´"XXX¨΢Š&Í…”ª1«©©©X¸p!»I ñòòBaa!ë÷õòåËUÚµb,¶¦êHD,¾––ܽ{—³Á«j•.]Jñ¨*••™™‰ùóç+=ÎÙÙUUUZû[¶lÁ‘#GqS«÷wîÜ9¬Y³FåïÙºu+bbbTúŒ>''04GU7_àKQ U«ÎÑÜÚ6fÍš…Û·o³ŽPUœ 3gÎÄ;wX§©9†5Íw bðÞ½{W%×x@@nܸA¼ã|}}‘››K´M%t%¨º¡-tíRµÏÕA·±±QYÊŽ¡=-Z„ëׯëõo¤¥Ù«*4òÔ‰ìó¾È2N˜0õõõ:?]WBÓ4ù´Y"\e·iOO¾ýö[éëššRݦLJJ /¼ ô8‰¨3~ùålß¾]§7ÑòåËñÓO?aÚ´ij}žVÐ5–––2c:;;ûÛߨ|×1O‰WaòäÉJeqÛN2<ÈPõ$DöìÙ#ýuuµÚ*4$ ÄÁƒ9¼ºN&ç÷ïßW©"¤*ècµPeè !‡+×@suŒ/M’\hea«"@Jmb07nÄÉ“'9«iõ¶ & µµ===ìéªø²ý'O²f$N:… 6®¯Y¼9ƒ¡¾ ««‹Ó±š:]¡Šž-«òÈcƒ7""ÇŽ#¾âSåF%Íõë×±hÑ"•>³bÅ \¼xQ+“×¢ªhU†††"11Qg«É””<ñÄZ3~ ¡L<ª<;µD«o}Íà7ª†³¨Lb"é ®êØ´ÑT]Kg¯µµ5ÚÛÛuf(©ízÏcÆŒQ9yª¬¬ nnn*}fÁ‚ÈÈÈÐIÒˆ7‹ÅèééÑ8Äà™gžÁáÇ•§©7™¡vvvhllätlVVæÍ›Ç‹óVE#´¤¤Dí~’¨²3ÖÖÖÆ)ÜHTMˆzå•W°oß>6Xôu“¹žžÎ©FC>4Õ%¸Ú‚pìØ1DDDÏà\+£©[NoõêÕˆ‹‹Sé3|YUêmWÖúùçŸñÜsϱ¡%TÑd...†‡‡‡à~#×8b>¡ª  ¿¿?nÞ¼ÉéØ'N`Ó¦MTÎ[ߓִÍ®’ž\]]Q^^®·}M³gÐFð)ÞËΕº AÚ‹>}Þ"fŒ ×ÄÝ’’âÏ]>bUUEäz]cdd$3o«mð!** ÑÑÑjŸ Íøm“œœŒàà`bíM:»wïÆýû÷EÌÛ©lR»té–/_®R›4â!•­°srràïïOô;•¦¾}û6fÍš¥×´ÂÂBDEE!&&†Jûê„4p‰;Ôó¡W™;u4‰ùPÄAzöº>o},#ÊÊJDEEá‡~ rÏæääÀÏÏO¥¶===QTT$¸ C¾Äâk‚Ú¯§§'"##ñì³Ïjt\IÔñ)«÷Lc»ÛØØááሌŒDii)öíۇ˗/c„ ÔúFß¡Ì(îFÎ IDAT‰ÇÊ•+‰žgCCqž‘‘lmm³ë@///DFFKŠ*%œµòð †+B/Ú@×Î C1¦¦L™‚ÈÈHÞÄPªâ)((ÀŒ3Tj[Õ„o!¡Ž®?àóâRç1¼¶¶¶#ÆMª£5Kë‚(’ÓFÉÊU«VaçÎèììÔÈxôðð@qq±V¯qyy9\]]‰.X¬¬¬¨ ª‘Ôîß¿¶Ì—ƒ·ºn^G¡ÅËKP¥x ƒ!Thkäëu*¸)²§s÷î]x{{S9ïþþ~˜šš2ƒWŠŠ!ܼy“ø¶5 ´U.ÕÂÂO>ù¤FåBõ7Ÿ¶…`îܹÈÎÎö~UUœ©|çHêl»mdt½ÕEóÚ¨Z/¨SÐbéÒ¥¸zõ*»¡ >„Êði,Єæn‡²h B ñéè耕••° ^ÛŠ4e?ôu ^ZŠ #ÝÚŽ§¥Yˆ¡¹Ç‚†Ì 6P'VhÏb†0Ч|š¡Ð”èS'çEŸûZ]QSS£ðºû¼%;v,ZZZˆYôS¦LAee¥Ü¿ÂËË‹èùÿúë¯xê©§ öf¥¥¶1RâZCCƒJâ窲yóf?~\+LCA] Þ‘¼üúÀùóç±jÕ**‹Z¨+¿èíí-WqF[ÁÓÓ“ D=cÉ’%HHHÐÙ÷“×ã34‹õlذ§N¢¿¨çCGŽ´B£2ðU«“1¸1mÚ4”””ȼ×ÞÞkkkªß;qâDÔÕÕI_³pÍᣗü¥—^Â÷ß/¸¾Ôe⚺×qñâŸví•sš5knß¾­ðVŠ]w̘1 Q7th$gcdÔ‰ ???äää(<†ïs%/ Þàà`$''³;QÇ\¼x+V¬àõ9jcØÔÔVVVÒéÕ«W±téRvƒ(@ˆÉ#\ª@i#!•4$bÝtºYéÚ.RÃPÑÈà*ÓÖÖ†1cÆLŸøøø //O'ßM³€Rjj*.\È ^EÈ«ð£‰w—Ö»««+ÊËË?ØäyNÍ‚ûi­´G…žžéëØØX¬]»–zq-ÑÈxŒ.«­Õ××S“êknnƸqãTþÍí?ehb¤oÚ„)¡0øDDDŽ;¦ðu“¿†î"2´ƒÚÚEEEˆ‹‹Sh¬‹‡Ÿ¢ŒÓëׯã•W^Q«ÝÀÀ@$$$>f'88§N"š¹:RŸŸ9sO>ù¤ÚíZYY¡££C­øOMprrBmm-úûûall¸ ?bü»®a#ÝÅÅż““¨}Í€322‚X,f3£@©¬¬ÄÉ“'Õr>Hâa—,Y¢õóV7ÆŸ&\4~E"‘Á̺†D¸„Î OhÒq|wáë’[ÂÚ.;eÊTTTÌfá Ú‰††„ Z[[uòÝ,ù‹ßhRxB—Òd4wî MeG_‹q°%x3“-ìððáC888ðªÃ-,,ÐÝÝ-ó^EE…L­f! ¬¼0ŸXµjΟ?@= M Ebb"›E ‡Õ«W³Ž À¼yó••5âßiìè†0øÍ©S§°aõ>+Ù©ÓÅÅÅððð0˜ë¤l~7äÐ!Þ¼&L@CCƒôµ:eãïï›7oʼ§©K\^œª·4hèŽïÔÚÚ µÛµ··—ÞÔckk‹¤¤$^•éä+ºòÑLÀÐèÁªCMÛ¤¤$„„„¨õY]Æðª›l§K·!¡‰JŸK«;ëêù™™‰ùóçSi[ݤrmͼ±ÔFMt(¯iÄ ±­ZÅ¥¦ï`ÚÛÛµž}þÆo®". );¥¨ éB ¥¥¥pwwWë³ÎÎΨªªñï| …zþùçqàÀA¼LšŠAË(UäÒDYbúôé(,,Ô»>ã{IsÞ¼æææèííe£LK •EILLDhh(oÏ—fíoEh²ËÀ ƒ®d§h.fi†04à[éyêÆ‘’]š¬¬,Ì›7w‹mšxxx ¸¸X¸×”O'#ñŠ©™LiKÑ××¹¹¹€ÚÚZLž Óà2ÈÌK#KPPÒÒÒˆ·kii©‘áÁàÍÂ|EQh€õ*iƺ«[f™K_Ó4JIä„M OµÅß¼yþþþT¾WSEE1í|=ÖU%FRùR¼µ´´DWW‘¶hÊÕ胱;~üx}ºÆíDDDàØ±clÐñ“a’Vš–þÕuuu˜8q"•¶IìJÐÜYrrrBUU•a¼EEEˆŠŠBtt´ ~èÇáàà@¬=}‘Û²°° ª',ñh]¿~‹-bOyQXXˆ¨¨(ÄÄÄk³§§£Fâµ1½xñb\»vMæ½èèh"EuvíÚ…~øÊï3f ÚÚÚ¤¯+**0uêT"mÓTSÚ6)ÕŠ¡¡$bC…Fee%¢¢¢¨Ýsš2Ô#µ$/ìàÛo¿Å«¯¾*¨Å)´Jµoß>¼òÊ+Äì‡ÁܺuKnµJ­¼´*­1´ËöíÛ 2ƒž1•ÖHqssCYY•ÉÁØØX&ß”~ëP¡v’%…‡ޤªɃdœ¿¶b" QœF¥5ÒÎ"¸»»£´´t˜qMb Ëk›$ûÚÎÎÒ×4ÃRHõõ`¡ ÅÅÅðððЭÁËÐÌÌÌ 6ž!,lllÐÚÚ ÈÉÉŸŸ±¶µ2A²BãÐ $óæÍCVV–ôµP·žšC²ì³6 [AñÙgŸ•Ù%ïêê‚¥¥%‘¶‡ÆË“,³L3±•&zoðà×_eë077Gpp0±öüýýqóæMÖ±ÊæÍ›qüøq@}}=&L˜@¬íÁYÞ¤eÃæÏŸÌÌL@vv6æÎK¬íÁÛt‡Æ3ÏgÎܺu‹ú½˜˜˜ˆÐÐP6(54In)¦»»£F"öŒpuuEyy9õþ!½»4’U'OžŒÚÚZé뎎XYYi[¨Ž-ÒÀ`0ˆâåå…ÂÂB”––ÂÝÝhÛÚÐq¥U(£¸¸žžžDÛôôôDQQ‰6‰—7//ÞÞÞD“[%œ8q›6m"ÖÞà8ïÊÊJL™2… H9-¦NŠŠŠ äcÎ¥êiiiÔdÃH2Ô›I²O†!©I=¸hUMM ‰õÉÌ™3qçÎä’™ÁË úÀdUÖ IV3Io…„¹sç"..ŽJ……ÚÚÚ`llLÔ +™RRR¨)—Ъ '‰œœLÅSšœœ WWW¢áfóçÏÇ¡C‡ÅJ›k-•ŽQ£F¡¿¿ŸJ èÁ»4mmmDµl.\ˆÔÔTäcƒi*¢˜ššb``€J§ÄX'òË–-ÃåË—/Š¥÷¯••&NœÈ³´ˆƒƒžzê)ÖŠ‹‹ êëë©xb}}}‘““C%6ï©§žÂÛo¿MÜH—L $“$ØØØ ¸¸˜Ê`É’%øæ›o0}útâò^hiiA@@ÑvLJ   DFFâw¿ûŒj†+W®Pi[¢z@:V~0ÕÕÕprr"º¢w.1ðh¨¬¸»»£¤¤---;v,•çÍ„VÒ•ádžbr3(Ož<)ØknnkkkØÙÙ±§Ãàhkk“ÆÔjsL{{{S1J`üøñ'Þ®¥¥%ÆŒCåYáííþþ~âYã¾¾¾8zô(Ö¯_OüœÝÜÜœœŒåË—o{×®]X»v-ñv-,,¦Wc¸¿¿EEEZÃ666hkkÑ#G°eË¢m/Z´ׯ_'¾.1ªªª0fÌbòœ‘‘‘Aüœ%Ê'OžÄÆ©ô5xvooodeeA$ïë9r“&M"ºØ6joowuuÁÂÂW®\H$’‰‹ŽŽÆìÙ³qïÞ=DDD §§ß~û­ôï5558}ú4ñAA’ôôtV X‹ôööÂÔÔÔàDßãääDDˆ[ÚÛÛÑÝÝ KKKœ?–––X³fô¿?ÊÊʰ~ýztuuaÿþýÒ¿WVVâܹsˆˆˆà帣9žiµ}ÿþ}˜™™QÑÉ¥Ù4 ‡ð±cÇâü£N¾»³³5jnݺ…‚‚¼ôÒKÒ¿Ÿ?ŽŽŽHKK“>gþñHco[ZZðÝwßá…^PûîÝ»‡²²2„‡‡_¼îß¿;vì úÖÓÓƒëׯÃÉɉHõ¾ÁXYY¡··Àãx“ÈÈHiyyy055U2pûömØØØpJ"ˆÇÊ•+‰W^^Î)¤!77'Nä¤èÀå»påʬX±‚ØoÉÊÊ‚««+§ǥ͞ž¤¦¦rŠ“ázŽiii˜1c†Ò-”‹/bÙ²eJ ㎎ܼy““|×sLNN†¿¿¿Ò¬U®í E—; (**‚——|}}qïÞ=™1ÝÛÛ +++©ø¿¥¥¥Ì˜ÎÎΆ•••Ò‡Xnn.F4â$c.99~~~JcêH窪*´´´(U\(((€••\\\¶›žžŽéÓ§+…»té–,Y"³'¯ÝÎÎNdee)õ¼ÔÕÕ¡¶¶vÄÌpIÛÅÅÅ022´iÓ¶wãÆ 8;;s ƒàrMúúú˜˜ˆeË–)5JJJ0þ|…ÇUTT ««‹S² é¹b0¤ÃOT¡¤¤·nÝ‚‹‹ üýý¥•¾$c¸¿¿VVV2±Ÿ{öì‘þ¿ººJÇIEE:;;åJƒ þl~~>Ƨtë:553gÎTúì‡R㮽½¹¹¹xâ‰'WSSƒ††øøø(To),,„¹¹9ÜÜÜÔšgå%‘˜gß~ûm@CC***”†z”––¢¿¿Ÿ“¡Y^^NlŒˆD"\¾|YjÓ|ÿý÷rkiiAAA'#{¤ï¬Îz™Î;WÚ¹—/_–jÂ8pŸþ9Ö¬Yƒ“'ObóæÍ#6º|ùr¥Ó•+Wààà€Ù³g+=Ɇ†NÜHgkk N™Ô\ÚìïïG[[Ñs=z4àââB¤ÍŽŽˆD"¢çhjjŠÐÐP¥ ‡¦¦&lÛ¶Mé ®©© DÏq``ëÖ­Sj¼pmOÌŸ?_jT\¸põõõ2czýúõ8uê”BîŠ+”N2ãLJ»»»Ò‡®H$š5k”Vù!=žoß¾(5Ä0~üx¥2gæææX´h‘Ò-Í––lÛ¶MiøBKK ÌÌÌ”þ–ââbÜ»wOÆK?ÒBÓØØXi ² fΜÉIAƒK_÷ôô »»[éqUUUÈÈÈPªÊ““ƒÖÖVN[°¤ï¾0gÎi9ÕŒŒ i¶½d + 7 Q8oK èææf,^¼XáqiOe‹Gccc„……)]L=zôÛ¶mSêìhll„•••ÒkWXXÈɰKNN–Ρ|œg+**““£4D)++ ½½½œ’`IŽ‘´´´(=®®® œ4ǵ9†Ä*üæååáÑ£GJ Þ¾¾>ÎÙÏÝÝÝœ¶:H×ÛÛ ÞŸ#×p¨¨(Ï<Äb1zzzˆžcOOÌÌÌ”ž#×öÄb1z{{9m­ªrŽæææJ= \ÛÓ'²³³ÑÝÝ­Ôàå:^H÷5×ã ‰”ž}}}022RšÁu쑾¯¹¼íT.¿ƒäsŽë3D$¡¿¿_©¼Y?Äb1§xgÒ÷Œ¾P]]´´4¥/×¾æ:ëêÙ¯«±Îõ·ttt &&F&,EÓ1Âe¬ëÊV‰Dèëë#:g“ç¿I=”¡J²×Eú8Ut&…pŽ\¶,ŒŒˆŸ#ט?®ío“t{úÄèÑ£9=H¹Þ‹¤ûšëq\:®Ï&®¿—ô}maaÁ))„k63éç×gˆ±±1§ïV%+›ô=£/˜››s’©ãÚ×\Lj®žýºë\‹±±1§0D!Œ®¿WWÏ}…÷“˜V 7ƒÁ`0 ƒ¨•FîÜ9|þùç2U<ÒÓÓñÅ_H«Ü0ÈÒ×ׇï¾ûŽx»×®]Cnn®ôµH$BLL Ο?/s\||<¢££e*ðdggãÿþïÿdÊP2„É™3gðùçŸËh禦¦â‹/¾Àýû÷YæÀèìì$ÞîíÛ·‘˜˜(}˜˜ˆüQFè¿  Ÿ~ú©4ix÷É'Ÿ ¦¦†]råÊüýï—ÆìC¿üòKiå*†f”••!>>žh›"‘ÑÑÑÒü) >DTT”ôz ààÁƒ¸zõªô±XŒ3gÎàøñã2Û®_¿Žýû÷S)ðapoqq1œ‡¼+W®Dqq1ëUJoTT±öºººpìØ1¬^½YYYÒ÷¿ÿþ{ttt 99YZíäêÕ«¸víz{{±oß>%kþùÏbæÌ™xóÍ7ÙÒƒùĉeŒ°ÌÌL„……¡´´”ua¾þúk*ï§Ÿ~*·™™™8zô(lmmñÉ'Ÿx\ºô£>Bpp0~ó›ßH?÷Ûßþ!!!øÃþ c3„C~~>|}}QWW'ã”X·n´C3ŠŠŠpúôibíÕ××ãƒ>ÀöíÛÑÐÐ }ÿøñã¸té"##1aÂÀ—_~ œ9sFZõíìÙ³¸uëjjj àq"âÁƒáììŒ÷ߟ]4M ^;;;TWWC,c×®]WôHKK£Rñ‡AžL˜0Ï=÷œô½þþ~deeᥗ^ÂÞ½{¥(::{÷îÅ /¼€ÜÜ\ôôôàÈ‘#xûí·±téRLœ8Q*›Ã&¶¶¶xðàz{{¥ºž®®®ÈÌÌ”>püf¨/&&{÷îņ ÐÜÜŒ‡âÈ‘#xýõׄ  ==§NÂŽ;„Ý»wãØ±c¬3ÈäÉ“q÷î]Œ;VšÍîêêŠäädj•°šÑÛÛ‹ù®7nàèѣغu«ô½ææfTWWcË–-Ø»w/:8uêÞzë-üþ÷¿—VÆ‹‰‰ÁÿþïÿbõêÕ‰Dr‹‰*jÅðöõõ¡­­ ¶¶¶xøð!&Nœ±X,ý?c8HKK“›ÖÖÖpttÄ_þòœ;wÏ?ÿ<àðáÃøè£`ll '''¼öÚk(++ÃéÓ§ñÙgŸáÍ7ßD@@‚ƒƒqïÞ=ÄÅÅÁÈÈ“'OFDDŒŒŒpýúulÙ²EEE°´´Tx^~ø!ðÒK/á›o¾¼öÚk€?þñ3f š››ñå—_x,^YY‰ôôtéÖNZZ~úé'éçÂ|ð¶··cܸqhhh€ƒƒÄb1êëëÙ"v<@LL Œ!‹ÑÐЀˆˆ¼óÎ;سgâââpñâEœ8q©©©¸víæÌ™ƒ§Ÿ~ãÇÇþýûñùçŸãÕW_…››¶nÝŠîîn|ýõ×011X,Æž={¤I8ÎÎÎ8xð Â bb±ß~û-F…òòrlÞ¼Ÿ|ò þõ¯x\•+;;ñññÒ©ÅÅÅxóÍ7QVV†ŒŒ é÷ùùù!''‡]h:1ššš`ooHe!ÿߋŸõ×_QQQà±LÞ¶mÛ’’‚ØØX|úé§Ø¶mÂÃÃñꫯâÃ?„ŸŸœœœ°iÓ&$&&âðáøuëž~úi¬[·îîî¸zõ*nݺÒ¹¾øâ \¸pçÎSznk×®ÅçŸ///<÷Üsسgüüü¤Il}ô\]]¥FðîÝ»áää‘H„½{÷x¼»ÓÖÖ†;wîàèÑ£(IHHÀG}ÄÔTi033“jjJ \###fì*`ûöíHMM…½½=îܹƒ¬¬,¬]»o½õbbbðõ×_#''ÆÆÆØ½{7<<<ðþûïã_ÿú^xáüæ7¿Á¤2c===ˆŒŒÄþýû1eÊ<ÿü󨯯Çoû[¸ººâwÞQ¹Œi{{»Lq€þþ~477‹Ñmii‘‰õ”|–!\ÌÍÍ¥cZbà1cWï¼óÂÃÃææf|óÍ7ðõõ…««+Nœ8íÛ·cË–-033C@@vî܉äädüùÏÆO?ý„ÈÈHDGGãå—_–fn¿ûî»X°`6oÞŒü[·n•NZï¼ó<<<žSII \\\ÐÔÔ$uJHŠIhkkCGGǰq;tì²±,LLLL¤÷Ó`—»ÿY¨þÏÿüRRR`ii‰C‡ÁÄÄ;vìÀÇŒ¤¤$$''ãÂ… 033CTT¬­­±råJøùùañâÅÒB’y¸©© úÓŸ¤‹È™3gâ§Ÿ~‚ ÊIÇWÞ<|úôiäååA$ÁÈÈ­­­ÃÍÍÍ2óµX,Fss³L16ž ¼ Õyýõ×±cÇLš4 7n” %xùå—aeewwwôööâæÍ›8wîRSSñôÓOËm¯¬¬ UUUÒzênnnRÍ@GGG•µe0ôçŸ~ø!öíÛ‡={öHú`ݺu2¯^½Š¯¾ú %%% Û<|ø0œœœ±X,³Ðà2–Ï;‡ÈÈHüòË/ì1r°³³CXXÖ¯_ H«½µ´´ÀÁÁAº³ÚÚZœø7nÜ{¬‰‰ ÐÛÛ‹ŽŽ鸵²²Bgg'Äb1âããŠ#GŽ ­­ ÀcY@‰Ó(..ü±Êç¹dÉé÷I±6n܈«W¯¢»»¥¥¥022† P^^Ž––´µµ!??6l€££#nÞ¼‰ÞÞ^œ9sFiµ=CÂä½÷Þ{u}êëëqÿþ}\»v xã7’’‚šš´··cîܹ€¹sçââÅ‹ÈÍÍ…ª««±téRŒ3^^^øùçŸÑÜÜŒgŸ}‹/Fvv6®\¹‚¶¶6,\¸æææ¨®®Æ‰'°eË…YRSS/ÝÒqrr„ ðé§Ÿâøñãxÿý÷1vìXøúúâø’““ñÜsÏÁÍÍ žžžøøã‘žžN5½ }àáÇèììÄ¥K———‡;w¢§§xôèüýýaii ggg466")) VVVèèè@hh(ììì°lÙ2üóŸÿDee%ž~úi,\¸=B||<ªªªàïï±cÇx,aöÄOÀÉÉIáy577ãèÑ£(//GPP‚‚‚ðÖ[o!##«V­ÂìÙ³áææ†o¿ýIIIpssÊ+ààà€Ë—/#>>]]]عs'±]#ƒ/ô÷÷£±±ùùùHII¹¹9^yåDGG£½½VVVðôô”:öïß²²2øúúJwH\\\P[[‹ëׯÃÉÉ óæÍCXXâãã‘””„Ñ£Gcþüùï¶`õêÕ Ï+66±±±°³³Ãøñã(‹)))Ø´i¼½½aaa¯¿þ¿þú+Þ}÷]Œ3ÞÞÞxóÍ7qéÒ%ìÙ³“'OÆŒ3ð—¿ü7nÜ@hh(óð‚UZ3`ª««¥ñFVVVÒ䆚š˜››Ë”Blhh@oo/¥ïµµµ¡±±®®®¬3 ÓÝÝêêj·<ÇŒƒ¦¦&´··cÊ”)Òã:::ðàÁL›6Mƨ¨¨À”)ST*«Ê`04cp|¿´$tii)dÓªªª0zôhi‚±d.‰d’›››ÑÚÚªVÒœ>óÿ6P}sײIEND®B`‚snd-16.1/pix/fmeq37.png0000644000076400007640000000171411147553267012761 0ustar bilbil‰PNG  IHDR¡-ñýû'3PLTEÿÿÿ   PPP000€€€pppÐÐÐððð```ààà°°°ÀÀÀ@@@ ã¡{E pHYs  šœtIME×%+ù_~,IDATXÃÍX²«* ˆ ÿÿµ *U¸çx:ó$3µµ-ºY6Ù´9Ä$j3H£,À<(BÇfq{5`ØL«%1)š#CïBI‚ ½Áæ.ó›QÂÀ!“@)èN !cǼäk†ükàh”‹¯qCˆõ¹>ø{­‹7Ë \«Ô-öÚ/«úµZ¦%ÈK7Öêr.œsñEË Á4Zt]%,Οj™ºO>6kãG§Ä¶rÆKÞ˜C¤í™¿‡(ÃMy¿²Ê¥RÇÍ·m–·a}~¦üïo±çf“ÿ€PM5e·¿dj¹SèçöÜæðÔÇ‹16ðÛÀ}Jþq0r'q&<·Ýz– |)+€œ°5þ¼Ë æÒ´œ¶S.Îo~,ËW+_wfrtÜ!,Oóܶ±$;å #F õÄoÊW¸5­¤]sÒ¡U^”´êe‚Š‹„2A/·–óD†È A(øS…<—‹ƒÉKC|>qœžÏûv.£]¡ò*ÃŒ{Ñ ËnEK†!O·pë‡ Ý‰Ðm9ɇ Ṍ)ÔŒo2ämv_ÈpCÀJASãß*pCÈ{›x¸"<—1Çük“JîX{›4ÌÓ&C+PÌñZÎY::Gòy{Ê2ÍÒ«Âc_„ó‹”’I6›¸=X0êÙ´¡¶%3ßè¸!Äô–^³g–n(±¢Pá±l"À•8]òé‰e¸®’ÊÅ҉͗M ¸ü"‹oJØÈ'%Y”kú²2Eú&SQSÔnZø`q™ÄDzyY.kº Èûìu)n¿é¨•‹q#°{£V33¡tÖ<ZÚJgº8—YÚ™n:MOû+ÀØmô9ïJf@ç"ø—?ž S«:ÉY¯™ Õm›‹µfõþC¾ ’úŠ?´ì¨v±æ ×UJüòï o\§cÐé»X[¨]¾h®Q6²ïbÿïo€FО{ÏÅÆ‰ž‹ó·bÏņ‰®‹óŸWÏÅ^rw;K|aðpƒ!<†Ða–!”J³¶ã!<‡ÐQ9,CèÈCè>Ïâ4”÷þ剽´[H¾IEND®B`‚snd-16.1/pix/sceq1.png0000644000076400007640000000141411147553270012662 0ustar bilbil‰PNG  IHDR«'GDHˆ3PLTEÿÿÿÐÐÐàààÀÀÀ°°°@@@ððð   pppPPP```000€€€ ”ué pHYs  šœtIME× 0t “lIDATXÃÍX‰v„ Dÿÿk‹G­xBÕuÓm÷év³IÈ0Œ! >/ÁI*!õã,C¿–½–6Œ¹‰‰E§š…á/á˜@ðü~%À¢¸‡«Ó{5;æºcÉŠ’4ªø¯†)üX3&"G]îဪgxrüí߉W5KòoM•<À!k|`‡ëøB­¬V5ë¹ °ïNP‰Sœ4UOìsÝíˆ)×¢Í90†ŒtnÌ„÷µšÂÇ«+\±®k†iM¿±ì=Ãl\ß ;áü•á÷A¨—kîFüœ‹p\û$úʦ ÜuÙΚ˜L”sEg¸$š4•„WúIS­ˆêšL› õw©q(ù·ñ ç {ÞbwFc̘Ÿ_wÛé ·ó*OHÔÅ1aªË nÓ–Ý .NßêP\”!@±‚S²ªyHû–Ϩ‰Ç‰6œ’ÙÛ*eïYïNH()ØÌÃoÀƒ½8 ]W%%9¹‘óæÉѸ¡†Å5¶ S¬yò˦­Êÿ¦aO¦5ÏV}GÙªoãZfÇÞ[…d¾ë¦­Zzªƒrw>ý[yªƒùšèŸ}¥‰2Xô3ó/ÞàškÄ´”¤y:Ú½Á5ÛˆY›tè \ó˜Š?^ÍkA«ÌŸgÏF¿2~(Œpþô,åIEND®B`‚snd-16.1/pix/sceq25.png0000644000076400007640000000200011147553270012740 0ustar bilbil‰PNG  IHDRÉ"› v3PLTEÿÿÿ°°°ppp```ððð€€€àààÀÀÀÐÐÐ000@@@PPP    ÀgF pHYs  šœtIME× &·FxÈ`IDATXÃÕX‰r¬ äŽTþÿkÃ¥ f³OMU±vÉàÒ0tOCHl”q BHò'jýéP¥ NR ÍNg#‰¤ç!ãEðäñý '†Hb€ZŒ 6„´š8£µÄDRéã‰Æy©1cÿåF ”¬èaX=B’rÓaïlä#ã‡L‚Àû=Æ´¯MÒÎE>*¶vÞÏ®bWe@œV$/¤{lHB3R¥!áo»ä¿b÷ýÓLë=Là²}Jëm†{BdùS)‚²ÅUH|[p]KˆG¸RãE:Ã#N‡Hx)”‡¿ ¦B‚ˆ&d\/}çé@ƒ¼ØëJŬ˜ºŠû¾¥ßqaá]…liÞm¨rT[¦ô•˜]Ø7ÊqP°™·]¢˜¡¡ FÔ.~„$½Ì{Ú¤Ú÷¨NÐP÷¦¹Qå1±Cí7Ÿp¾|«”ПTÍQ‰gJù2.ñÿ¾GjÏq†ëʵ¸Žb{T4WÊÉšÞ»Ôã^ ¯2¥Šß“gS¯€àê@ïjÏqc†ŸŸkÛv7’á9mé½Gí9nÈð7Úr×B¨ð™TÑ{‡ÚsÜ‹áAæì‚ß‚--jNÐʆÞ;ÔžãΞ›@c Å­ÆgʆfJ#j?aøW…ÿâë’±Œ>&~J@ÔyÝu“«’”Nøƒ©«Ž± n,[Ì@®X®àzm2Œ]úIPûþ›·ÑXÆŠÒ±äÓ¦ÜLó±n¹¢úí! µœG²‰¯bÂw(J]Ràƒ¥Ú‘äÉX7–-æ®e¹áµHÆ®*ýw_˜€¬üI™¸µT’<"KïÆ6‹y·âVH S•Vw_>Ê,IKÁ ËÍy*:nì™ÚádO<ØÄWˆý9'nwÏ®Ž{¢¸*ôëí6ñ €šqã¹ð¯-ÕŽäèÆž¹Mº*µÎáþc_i¥‡!™ã˜´–jG2üQsßp±œÀw»ÿ"}µ=w®÷%ä7Ö½o¸<ïäU´ß¹±xß:6|ù r7“µ«ïÈc\pOÆû†ûö乊¾¾oГ†ÿÈŸO"xMd“IEND®B`‚snd-16.1/pix/fdbk.png0000644000076400007640000000665311147553266012573 0ustar bilbil‰PNG  IHDRÌî´È7bKGDÿÿÿ ½§“ pHYs  šœtIME× !6ÐVËA 8IDATxÚíÝÛvã¨Ð$ÃÿÿË>O:C¥º{Ηî²G"àèÂï÷ûýþEŠ&L˜ 0`òÀüýým~ëÏÚ ˜Gê÷ûýù~¿,¼–Ú \ãÓòæ»]Ëgn÷a”ÛHGÜçQ÷{Ô²© æ‚æ_­ zÄó²Ï£}¹(ëùiƒÍpýŒþ8ÚèRY\˜o]T༌²æÝ6³Ð(×ÿ­ý’5-–/K”µ6ch¾è§åõ½mFk(ëöãѹ£#9B=iÝçRG1µmïóÿføéý q–Þ½²†¹Âr¹å(#ïséEn[Íç{Ò@@ëŽå(ÌÚ}^‡^ë¶Òç L£5e PA`@”À4‚PÖ3ñ… Óh e Lz°î@ŽÒ™,íóǰW&Ó¦„²êÛð ëûgÙçõ{¶÷]æ¶Õ|þGÕˆš³ìsË=šGËÄ”,T˜ô˜Lo*k@`€À€(º¼èçè´Ù2åæá÷SÖs3uëïܲÌÕÛË‚Õ^Õ{ôJÛº ÌTAhÀ  ò\‡¨´„ÖK‚ù]GÁò^ŒÖPÖðT;(ÝØ{­´íÍ}¾êöŽO`@ Ó”›²˜ 0@`²Ãô¦²†^ÚGîµÒ¶·í­bRs {Çgµ²•ÏC `ÞöúwéþÒÏ÷²Ï-ûyd›À0ЬÞþVGºuŸïXâëoÖÊ`ÊMYóîfã&L˜Ó1½©¬~¹è ¨u§ñŠå¯žÜßÚß]spny³íëF˜ÁÃ2"¹@jY9äjgW-)}Îú^ΔiÓ”›²òA²ÆÞâÑë×Þ\Þëªß]úœ½06ÂØÉÒ)¸’À4ZSÖº¼èÇ—hƒ<û·žiÔy×£=» ÌÔjÀ  ",vú®Ñ¿Ù½F®¬ü(Ì" €Ñ×rÅKc=Ñ)/½¶=†mgàŠcðಡںíÍý:û9{Kˆ L€`F\Þëè~µŒ(÷ŽÍ”l§•Ùù@e ôE`€ÀYÅ”›²¸‚‹~‚š}y¯Üñ=vS²ÁÃ2#/ïU:¾Ü¶Ôª%ë÷ ÌN™ÞTÖpgXμ¼×Þñå¶í˜;‰Qï̱;‡ x¤%D¯`„ `¤9íi‰Ò3r·ÛÖç-Såñ¥R8G¥¬rhFËuy¤ÚþócJ œÔÈj¶Žniý˽µ1sajJ xpîËmy¯Òòe¥mÛ²Ø2ÂìØÒës2^YÃõ½4šš}y¯–‘¥ÀšWoëeŸï:¶.ÓE#  Boº ÌÒM€6oø‹ô Á+k 7rÑ@pÛ+ÄgZÞ«æôBje’ÔÏavÎô¦²†'C¨´ÄÕÞòWOìgÍïÎ=Ú.×î·ŸŸûl @vä–ztܣ˖ß]Zº«´¼Wé  øè2âÃ:R#Кr˜AÃ2úº4¥>0£RÖ@Û¨jÖcÞ Mýà¹É…P,•ÛJ‚†¦mëHaÒ 2½©¬áÊz¾½R4w¯eî¶“Ô¶'C¾´_-ŸQššÝ¾f„ À:©›øKÛÞܯš`MuZŸ™,0„dñßµÛžÞÏܶ#ûﶸH¸ÀtŽJYL˜cr©¶²æà¢ŸA,Ó›AYÕÌmÝ/½¾·í­ýméDï}Fé*ÜÏD@äþŽâúo¿þ÷<¥mOÕÉšß½÷ŒØÜg¬·§>ÿÓóNmû¨æ‹íÅ{¥mOÖËÒï.=Œ`ï3¶÷œ®ýEý2Ðø•5Í_í³¡c袀à3 Bó¿å‘ L€Àá 4ÿ]®Ÿ¯kJvð ®R+k¸+<)—‰À€   Ü2W©m¥Ÿ{sŸsÛŽ~ÆúµÔ6.š©[-f\Þkï3¶Û‡xpÁ“…oî^YCÔvyõ¶^öùÌþ—¶›’€ æ|Üî ¬ Ýr•,@p©U<Örãú Úå½Î,áU:6#La™\â* o=°}o¿jßWêì[èÀtŽJYCô°\KjÔ•ÚöÖ­%GnI½oûÝÚc3–‘GÕ­œÃš5#¶™ì=ͧÄ hPîœyd}䏿À=$”5œ©ÛÑF—¥2¨ÑÅ”¬/$èsÒÒc׎™]Y“ò#¼Û&µÁù:E¹iÉÒ¶QöyïÖ“#¼?_ zÆÊbvˆR¿”¶m_òžÌ½ýª}_ê~ÓÚcs•,€Y„K¶õ²ÏG—ðÚû9ý@ s^Î*k@`@w\ôLnÆ$Êò^Û÷Õ·&@@Ëãá¶+t̾¼×^X–~N`þ8G¥¬!^;,g_ÞëȲf€PrSÉ{ˆŸç0H°‡¯—–5+=EÈs`¦7•5Д¥ó”˶T{˜F—¡:¿¹Ñå^'Y`@ `tùŸm©ÿïaŸsû•ÛÖò¾½ã˜…á7Ê"¶Ïm€Ì²¼×™eÍ~~\% :¯ÜÖË>ßulF˜P¡Ë¦éº¶WÄ+Ý”µ6ó'ÿ(#@„·˜’%ùÅhÄ 0À€g:NjԊ%©mov¬¯ZÞ«f»Gãíp»ƒ²æ¹/;úø{ley¯\G¡ô^ ¸ãšaͼ¼×zi¯Öc˜Fk(kŒúÃ÷‘c˜G—KxDºÐ¯fªV`ðÿ°¨=Ï7cX9n `´é¸æ±tŽJYLàµR_¶·’¤þN³/ïÕ2Êôà€ÀœÔ2WÛ«Hs5(-³u÷þæ~oÍûrû½wls²Êï‘vÊZêrËëO…ã‘ßmy/è„À ó6nwPÖ[.ú¨´ÄÕìË{íƒå½ø'PRÆ‹²¼WîµÒ±}zþcÒÆíÊZ¤¥oës˶7êHi¿Ž¼/÷s¹÷zÿCjÀ  ÂÕÂ#×O˜’;CgŽU`³] sýZ¤ã˜¨)(e 3·»õ…1QF—gŽ×m%E»P0µzIíña ÊÒ}ˆ¹€é%ìŽ,ïµU¯Wg©%0'czSYCmðä–ÇZêö}ëן¼'³ö¼ë™ó³{ÇfJ `gïèöÑ—÷*}žå½àæùáÿ™ùy©SÖ€À Ìé¹ÝAY&ÌA™rSÖ&Lv˜ÞTÖ#RŽôì£Ñ=µAOmB`6öØ…¨/+´Aè‰)Y@G æu½m½ke L@`€À¤Àô¦²&L#e­¬ è À‰=Ê&ÀtJ˜ 0ç`ÊMY˜Ï³:ƒ²&ƒ1½©¬ ÓBY+kŽPo¸ÃGezhƒË¹híÙ8²¢³ .¡YºË…^¼Á”l /@e L˜<Ã4Ñê;Ì›™rSÖD& 0Öôº•õè£F§ ˜/ð™íL@`^Ô›²¦ßQã“Ó¶ê¦Àd «¬•5 01Zº¬ 0,Ó¶L£5e ƒ†ú-0Ñã†!;P-mB¨ L|ÙÀÔõül[5Tµ)|”5t§ÇP5š˜Ã5ᣬኺ¼¼çªäí¿§}é20[ì÷÷7DOeäcmߣ÷|[ÛT”6H[ðöÎW<¦ðîzþ¹;,—?ÌÌ£¥bø¥´ìó(›‘Ëúê/ÄÖ/Ç«ÚàS_l½¼çªs¡½Еeóä{®ø;®û߯Ÿn¯i¬z¿ÌêêŽÈ]© ¢ma¦ÎÝ£šÏ× A„7}žÇžzëwqzÔ©siƒÚŸ}nÙç#þ®úåzŸðî€60kR¹¶G±>«÷׌ðZÚ”6/f®Á•¢F ׇ¦6Ïóà LÇå,0@`€À€!4?éŒ0 G}zÚ™Ö¬ÝÃÙzñÆó‘£–5\USõ*WßZ_?ZŸ?=ÒÛËÑgã9[/rm~ë`©Žùÿ3õÙ”¬^\¨0ñÅÎuKgìœÞÛ¦Àd¨ {G'®êˆÕ.͘[¸¼í§zÈÛ÷§¶òá ';¹vVj;ë×Kí®ô9­¿·ôùÂò_ŸÞ+Ÿ‹ îkÌÛ2Í…Éòzê¿oUð–zaV|¢|Rõ,u^,×vR¯·Ôë½ówo·Ù^ÂòL}î&0-[4îŃ+êŶ# ¾hƒw”ÛÞ*2¹0z«x-T_|ýý½z­êŠ68CÛÙŽ:φíú4E)ø{)—Ö%&¯®ÏU×h"uÎ¥¦âµÁ¹¶Wš ɵÕÔÿ׆MiDêÔEE'ód:ür~0À„eWÉfa„ F˜ð˜ÿšü¨EÛšaIEND®B`‚snd-16.1/pix/r2kfactcos.png0000644000076400007640000021567611147553270013730 0ustar bilbil‰PNG  IHDR²ÑMÏ0sRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ36 ·î IDATxÚìw”SUÛöÉôÌ0CU )*Ò±€ EªTEº¢ˆúˆ‚" V”¢"Xh‚…Þ‘Þû0ÃP¦OÚ¤ç|쓜“L&'|ë{ÞO}g¯µW†µöÉÎ9 ûÚ×µ¯û¾u’$IT´ŠVÑ*ZE«hÿK›¾âT´ŠVÑ*ZE«ÂŠVÑ*ZE«h­+ZE«h­¢U´ ¬h­¢U´Šö_jn×5^BÂóºÆ»®c|E«ÂŠVÑ*Ú¿´Y¹ˆËÿÕ9®Jûpc{üe°˜v×5G>gY)M {ü–°€—*~@XÑ*ZEûßÜ\8ìîƒÑ³ç¿6Çö±ÚÕ »dûš}|I…×5Ïf÷l¢]á_É;$þ—Ÿï vs’=ÿªßÌÿ. ¼ršßcF€ÙÞ5ädW¬.­¢ý¿jÒ¹ÿêÛ›¤£”Ú·áóãà&‡÷)dE˜ã=d»7bwœEægÚÍgœç*_Ç}¬’^ã óÒ¤Za0`3_0§IºÎçµï9ίa5c`ЧEÒ… üG6“ ¦¾‡Áö]påJÚÇU˜õôï·?×ÑCpöTÅ‚WÑþyÍø x,×weiø(ý†ÇÖ÷:?”¤ua,d3‡=ˆ³6º1’Ãx\ž%HaH‡¤…lwL$Áº0¢°%<¬c8ÉXÃÂ|éç]’á®IÓè—5ÇŸg?›ù„*¸® í˜9âú ÛÖøMÒ÷$HbÿeÑçÿ{€p÷NX» baè0¸ùfÿnXø|ø.ØÝà ózïNx¾+ôxœŽpVX» :4…ÒëX€>y Å×¹`™*ú¿ +ò€ËòßÃcÏu˜3,áâ p_ÇçòX ð›0;‘œ+ ôúäA\Á¾& Àq‘ï^‹Î~E¡'Œ• ¼H% ^w:"Clw- ÑŽB­Ž_MT ó–?õ<Á5ÇnâÃøú¬˜YÄXÒ€ªp]ÒèbÏPNÛWéÑÚ,¸YÁg,–&RÝC<Ñ@ødƒÃ@‰Z=ƒCd¤ÆÖg|6"b`ì$¨ß@{žÓ'aD_8}n¼ta<Þ]ÛaP78tìa¼_΂M¿ÃÆßÇ÷À ]®ï¹ýµéúÆ[-pbï÷»ÌË„ü‹ÿüߤùìœþx·òw]@9àôK»,L`vCÑJ(ɇpwû®Èé%á™R$×ë`þÝõà¿tJ÷€U{è9i&9ö÷‰³Aœ5š‡÷B½†ðæ;ÆOkíJ˜3ÜQðÂHhÙJC%rÂ{oÀÆuÐà.˜ôšö< Œ ;wˆÅäÙ¾P­š¦`ÄŽ?àÌ90»áäñ0t ìX¯ÀÁƒá=ë«aëºë[ÜÏ€5KáÊ¥ðÆŸÞ sƒû:æ8°¾ Ž0?Øéu°d8œßþ¿M‚] ¯§Â¾ÏÃb9â{Ï‚Ì_áò(óYê%VØšó2œm &Dg¡s…¬gÅšŠû5<ŽvèLNt¦ëBÏf0Ÿsh\sÄý‘¶"â­‚ ÆY!Rãwrˆ6DJGˆµ‚ÞHÈMCøÁÕ…$;‚ †ÁçÑ+ûIªJ`}ž §<¿á´çdïŸâû;Ì6¦ÒÈö±Ápáy÷V ¶ã$Ú Í•A<©åŽÁ‹–RÓ5<Ð+€ðŸÔŒF˜ó!äæAËG¡[7ˆˆ}ÍÁƒ°à ˆŽƒçC­ÚáÍõÞPê€ÆM _Ðk<ÚKY°ü;pë¡÷@ht‡ö×ÑÍlÝ iϳ|!¼7 ¬zxnÜÖ(Œ…}¬ýIìÞ ÍÚ’íÕLx­'œÏ„CÇáR.Û}›½Å"®=|Ñx(¶ÂªÂ6·6ÅÎðwI‚óÁà€yaÊ–…gá̱Éë7™ ç~£'üMÙ¯!ï4ám‚¼“` s|ñR(Ø.¾oc˜@˜? ¥b¼†[ò¬ëoèÌblXÒ¨g Ø^ïo$ä³2JG°8wg“ˆ³ãë¡a+ˆá .ˆ0ƒÞºržU>gXâîŽÍqŽD # „§X‡‡‹¤©@¢"L qïë¤Øè˜A¢C`¢âC|_2žd¬¾³Á4 M‚ÿOI?ñ“c$ñvH°AݘNT‹otl&'8'm%Ý#‘!A†R*á?¬-ø ¶m‚¨8xõ5ÈÈ=Þj…9³àÂYhú0ôì­-Wº\ðÆ$8s â*ÁoCjªÆnÚ/¾Ù¡ùcЧ?DE…¾&ó|ðäAJ5˜<*kxÐJÍBâ´ëááÇá™gµŸ™¡>y],nq©ðHm‰÷ôA8°Ì: ô—v¯…œk‹M„Bµ?¿‚S‡ÅçúeØÃ :ó_€-+€„óŸ×’»kq÷µ…àÌ>qM8-÷ œß->S8@xmÿR<§’0€­ô4èù—ÃÂÒ¿ g–¸_£Åõ`UÄd‚t!”V¸~$Ên%Áñvˆv–÷l]Œ‘:R,¢ºÕ¹Œ}jj°è³aÉle·¿þOñyË•j aÏZ(´ˆ…:: t`{éW/ÖZ€s>~D|C8‹5‚Ù]=¦<\Þ«{)Ÿ)‰pÓ3P ň®lWW@þ5ñþágæ³PrEÚbgåʆ+ÃÄæÅ{mË?ö¸z)!‹ÐØ4ØÀ=,«•÷±iÈóü ¶,âeôJ£‘úúsSY\ÆC!?“@!q6NÞ^#\áìç¨$»è 2(c„Çù™òK“ ®TÛ¤›Ë>+¹|æîI‰ã¸x›Òƒáyް€ñ$Sê3ᤕÝi µip²Äý"Çí?“hÃ×cʹï¬Ã-]¤†ªKPÝÕ¥ªÄ~\„ÿˆf(Ì.'îºúôÕ^8/^„÷ÞãzöƒÆwiÏc³Á¸‘páÔ® ƒ‡B\\èkŽƒOß»ž{hª=Ϻ_aͱdÔ±c!:FC²Ë…¥_ƒUO= ÷Þ¯ý öü û÷ ‰¬æ-0êEí϶rìb!mÿ44¹? ‰ó-C V}>24Ø~>¶¬ר¢ C7ˆ qÿ…9ðQ/8{Z9÷úÏÛòã&¸p\Œ ‡žû~ìwø òÈ<(±+sh1“ѤŒ×’F/ '¦)÷lÒ_8L× ›T Š¾->‹÷3ËNIZ ÖLñ{2#^57°-ðÿržÕiÇœ/gG˜dä×+ß*ß]ökf…|ê“D#ÌâÜNoþ¬6{þC‚C"Á©°Á¹ÇÂß™Á_|@YMr #ŽO~ òl?“žç”ãWñÞNåýœÁÍ2ßñ¶Orõd*KS*6ºr~W?J¯±Ó1x»øìq²±(Xæš-¬a¦4ˆt 2$H÷@U¤yþ•ˆñ/ÂÕ«`éw— ¯Oƒzõ4”˜R˜5N.Ñ£´å@€5ËáÈ>ˆH€éïAm &äñÀ‚OàäQqÆ÷üˆÕÎìl˜7JŠ!"Y˜wª×}$AÿÇáäi¸­ ¼8âãC_“wE„Wääƒ. &N† C_óë7°þ'0ë¡Ik3bbC_óþذV–íâ`̸/x最}›e ÐAã‡aÄXˆ !YŸÞ ç †SõpÛí!j9,yI,Ò^æBvvÙáÔ:áD.Š€ƒgáñå|ïNØ9 ý¤|¦" F˜õì|JblP¢g9›G\^ E6åŠ)ß,ã*€‚µâœÏ€2GQFè8æè½— ãKlkÁd@g”Ù ï>ÊûÝ^g+…–¨Xji »]’àðèD1ÉÈl-Æ :Õ½Û1sˆÅTÁã —ˆµ)ŒSgfõ³:Ï>r?C„Óìw.¨žK-žã™ì(Ã+¹Å{û6¶À-É5>óô¡ÀqDdägo‡x[YsÍ2¾$ ·0ÇÈl0C‚Jv±y¨Â¿{³YaÚk‚E5¸&½¢}Ñã^YWží<¦}Mi©Î¬,hpŒ±L¨°>Ÿ DÂÓ½ ekíy²²`þ,.Pãfxq TÒÈMqhLFhßÚ„‘í~ïNøþ+±(F$ÃÔiÚà9­/lûL:xªt~:4‹¶•˜Žpâ¤XØ*Õ‚©o†8•`Ó·°áG8# cwèôTù2ª½…ìKÊ¢^©L˜\þ<ÞƒìóŠQÄ­:Cç§ÊÁú‰gU¢تðx‡àÏ`ðñ²Ô\ƒ`úÍœçePó2/cÔ¿2jy¶Ùpp¸òþF“ ÆWüAPÍ KtÁ°tì÷L/ƒž>$à«ËE*]î;Ô2¼`g„Òqp|ä/Ñ‚oìäSàXF¼ ¥[eiÐ{ß–@Áõ¶ä‚H“8¯Ó€DœZ(äw’þç‚I^“ŒMÕyê<úp…ß}à”äÙ IœÛEeiÔãýu{8íÙB‰ó”múÌ8ÞÛ˜\æ"ciã~ç‚i²$ª7ÈÝY“ˆSýîý’t”,ûvä3Á›r f™Ï˜Î/ÒljHêsA¨ê”°µFþ­›$Áúu°êgˆO‚Ñc ~ýÐ×80{dŸ…úwS–{`ÍJør.¸#`ø‹po“Ðãívø`:lÝ ›ÀˆÑÚ1ƒ0f(˜Œâœïå‰pWç–k–B^1Ôi£Æ@rŠÆ 6¥{Í2W¹ÄéwªJe·h‚(ê~Y„ëf±Àë¯BQ1´n^ÌàÎ"f0&½7„!‰z<ð™ÌÒš¶€ž=µ¯¹vYdhñDÀÀ¡PïVmPßøÞ!dŽfÀOjÏsø |ûØtBª¬{‹ö5ë~͈ôÝM…„Jª¼t^ë ™YY „›5Î`%,ÿB,îfà†Û`ðò /’¾¢˜8H‚çÃíw†ø^ÜðãkJ,œ ¨QF.ÿw°ðY8´IY¬M2pÞ^@ç€ýKüÍ+&àÆ†0bdÙñ†³ðko¸šåÏtŒ:èÒ, ¾üäŸ÷gŽ8q{_+HHòŸ» ®í/+‰ä3Õb‹hŠqSž“!`žÆÍŒX(šFgYÉÒ@ó‹äþ ©tŸ“°Èáj@3 T¿ÛþJßó—BMóÈŒÐè9ŠÙ±]1{È=Êp/¥Ê3Êc91äçP$QŸIƤt®HG8îúµL)÷D‡`h:/ã~h,Wcó˜OoF½µÃ0¡,˜{v@Ú0f\h;¾Og8 Û6@¤œuFKzøy \> 5o†/„w?³g€¹P°Áî½ ‰F ¤Û «„=;¡JÁµ$Q»¾˜.  w/hÖ<ô5|>Mì¶“kˆTrZ™Üløe‘bšèù,ÜÂ%jȃÍ?*‹”š0|LùR¥WÍ:¢0 k„ˆlýHù×üöže𲎔š0pxù.Þ¿æÃ/“ýÏáL@»ŽÐ.È9ì™oaÃxå3y¯‹©*2ü»Ÿo‰g«fB±éТ#ÜD~¿878{2öè7ꨌE¹s•ï!PzÔU‚Gž€ÆM!B^<ÈýØß£fÃ^àêÖ[ w¾…Nf¾Àù@™Ó•÷4•Y¢ôàê–?ƒÏÀO¹ßòcÞ ½Ûög™¼EU ¢JýC%Ô{¯ßeÿš§M0A§ÂÒå×@ֹűˆ5ì¡r.Q·aQX š F˜à3Ïxv¹Ö‘&pU¯ ª9õò}üÐFa€^6XY –>ÞsXI1ü¬f.+oQEêáë… ÆÛá€m—±+.TŒ³x7JrwUáß³œÙpù2<ÞúöSþ#—×€Ï?‹ÞðÑÐèvíy¬VÐ.]†»‚aõÁsïn˜ý®ØE { lª-».ý¶®ÿ‘ëÝ'ig·9q>z Q4š6 -oz<°z1lZ+Åû†Q£CÏa6À¬—àj8baøp¸G ó/ýäÅZw>(bC=· GàÀN9¼"žëw†8u;áðBªõž×Õ¬/½ IA–lúö®U§-<—c`²–ˆ‹"»ÂT @T*¼? R6œ\E¥þgi= »”ýî rüÏÓÌQðÈã R€Óv.®ò7ìx¯3E@çžÐåi%éBî»pñC!Mð?ã4GÂÝÍ u¨¢ÚØ\í_VÖ,Q±¡Bý[¶%ßÁ/+!:&¿ª„Úd‚O>ÁÖmÚCï>áÅ .ø²/@Be˜ö–vz3€¹ïCNÜûtV{ž‹á«ÙP\Ié0õ­ð²Î¼6 "L g_íy,f˜3]äíŒI…/Áu4ÎS×ÃÊ…b!}ðQ‘ @Kâ]ø•™š= ÆŒ›xdLï)æ0é I+è?8´Aæ×9ðýÛ 0ëDÙ¬[Ë9‡µÁÒ±PdUÝ[ï…~ƒ‚?k—–ƒƒk˜M<¼2ÒƒH¼Yà芲ÌéÆÛÅ<ãyÈÚF·2Ö ƒêõÞPÏcc½ûºCîŲs”µÂÐQÊÊ‘¿ÙéÆP,Ï“q+<ú$Ôm¨ÌcÝÅGËž#ªåÑÔ›ExN%’}5:³]aƒ% X¤Üí{Èìv¸:„ PÖ][¶¤N½d&Önó±˜xoµÀÏT¸“¸Ò0›b~$Ñ%åegª®—Sžé à,…ÃCŒž²#T™wÜ&X4Î5SU|pÊ (÷5šàjüg,8ýçœ'Ö*í`XñTÖ+yD«©’½Q6ÈÈÝ{/¥&#³=ÉtlóKhI° IyM=Áj€`ºK–D UýŽÁP£qþíÚ¹s‚ ¢‡¾Ï‡—ÞlËfXõDÇ gizFxÒë'³À¥goMÃȳr9¬_Éi"8]KB”$˜7Žïg<Ù < 9NŸ‚*5…Û1%E[F9²Î 6Øñ©àÒ^àÙè§S…l—˜ýCUû9± ¶®3ŠèàюСCˆ{qÃö[ g´*C%=wÚaÃ|eµè íЩsðñ.;,ç/ïET†!£Ëµþ¥ {ôš=îo%ä×@æí0À–)þseItäx¨}cÙ9þx²wûƒ@dª8³lÒ²lòãQ¸¼½,x”¤Àóà¡JåÈìy›6X¢ºW"<ø84}LaÎSÓŠs‚Ïá çè;ß…ÇÕÌ¿) h ÂîŒzx° 4k1ÑHÒ0ŸSÌ6åÌã¶Â‘×%â²$*Ëz±68~÷"o ¬÷ÞJV»3T¢KdJ¯T)¿ê °tœh-²ÀxeJßßv™uª6Vi­È”)nˆ¶ÈhVdPß\FȬÙ7•AuO° à´YàÃö Ȫcì@nT@#;Š9äXåc ª×/»µC´ÞsÛ@uD¯¦’Fã,,»˜ð«¥Táÿ`+)W&@ÖEx¨L£Z@VŒ.Â&^_ŸÇq IDAT5×¾ÆbïˆØÄ&‰:ƒZ¡gNÃGÿ] :sŠ·mÞ ß}.â¾ê61ZFœÌsðñ{Pbƒn} Õ£ÚiÔ6ü ëV L«#Œ8Zó,˜§O è=X$*Ðk°ÁÍ« K—¨y+L{;´$zd3,ûDvüEÃsCÅù[¨|ª?¿§Ž+ az=˜ðJù±–¿¿ ›¿UêÒèÚÚ†èožQd>ï<‰ÕÅs ¦>¬î ™'ý‘!B0»¶AîçÚV¸r<À £‡;[@»îp/%;`gWù}¤Êb„±¨Û³ŠAƲ *£^Ø z¸½9´ïªsuãZ(Ê. 2jÓËÝ-`ä‹HQGÀ+‰ª 2Å÷sÓÝðÄsPç$iëd¤@&[Rvžcc  Ga2r™³ê>Ô†Ÿª·°ó•3DT*$Þ¦’)ƒet%pµ2ä4”M+²dé5Ç$˱|jIôr¢H"å _H“Ë+y¥Ð2óáH˜9aÀqÌ£ÊVcÌkôÓWS‰ôžÝ¥8Åûê$Q½Ü3Sᵩþ2k’,…&©r‹&ÚàX Lm•¢…9Æ›A¦–©vÐ"Ì1rÏ'캓@ø?Ù6o„Í ¹2 }jÖ =Þn‡/?ƒ¢\¸óèÓ/¼yÖ¬‚Å‹Ä9ߘ±póÍóØD²ïC á]Â%ª•F-'>|[0/gŒ }?³§ÂÅóps#a\Ñè«—à“©¢,ñÂ$¤U‘cçzX6[ü'¨w§`ÄZ’èÒY0ÿ=9ÿf‚H%§•æî§ƒLFлèñWÎÀÎ5ŠYÄ ôyî¾;øø‚ ð× %ˆÜÔ¾ z÷+?¦óĸ|¦l–“>¡I0óÊz¸tÂP¹¶ø~åô+`C/ƒŒH®-€³n#Ðü=?K„2¨Y” kˆ$îêØÄ+sÀdUÂ%ÔŸ+±<Ünm¬|§æypyJù¦PFŒAŠ:†dï æBQZ)XH†÷,õáÐP„‹H®÷”gd x¶ªëÕ!¿µ`‚êü˜¾†ÀsEW<—»Ä£Ïp’ènQ‡MÆÃ‚WÁ\]6­t/ûòÎS s^ÓøB%ä o>ÑH¹«YçOÃTw?£Œ7,û«ÁÅŠ1ÆË« X§:ÜCoTB'.¥ÀôÑPšâòá-¥ˆµÂ¼{ª·gHæ’SÁÙÐT0¿Y+(€!ƒÀ`„§»C×®ÚLhõj˜;Sk¨s“ö<—²áý·Á­ƒî½EÀ´V;°¾ŸQñ0ùuíyÜnøé{Ø»E€`>С£ö<ëßVƒ> FƒaçŠÅpä ï"bCZI,ú²¯B\:¼8Qû~Šsaãreq»·¹ˆ± eø™Õ¶­ã#SÅ<·kœE¼þ¨3ñJMZ˜—Ë?=·S”qò.ž¶81–S2÷,ì—óüÙàˆäêedWœ]W¯ú3{< ]¶Þ¤ÛÙ¿AÁeÿÇw‚‡Ú@|@_^ ™kʲ§bÀ ½‡@#9ÖRrÁÕwáÊr%p^ÍèÜÉðPhÕ âdEÀ]E¿…¡<6h‰†ný Õ#àÜæ3>sŒ.0gi±<þ¶Ð¥Ä»<‘,™ÂØ,p^µoZκòb®2ÈDfÑŸ]Qóxá(q±Vb,Š1&Ò bi2£ÒÃÅ è&ÁÔÃ%’ì"ÊT–uFÁS ž‚3 ›S3•)'Ñ&>ãÎ*0´/8+)æuQ_u†ºë pìFÈÏ`ƒ6ÿ'Ú„½;;n“™ Ì½F™‹Ì Ul°p¤ˆdÿÒöÏt~ø>‹¡î­0q¢¶9Äfƒ÷§‹3¥ŽÏAûÚmÍfxûu8ynªcÇk3¡Ük0v$X m£ Ð'OÀÜ÷Àé†j7ðÚiÔ·¦‚Ù=C‡0zï˜?S°¸TxeŠvµ%³aûj(ÕÁÓOÂcí´%ÑMË`ï±ø&fÀ”×Cƒà¹pt˜$híÚÁc%¦öü,â2} ª†ØÜ”'½^ ^PÎÈ ˆ:»”?ÏÞEPRê¿PÇU…/gë{Þmù›QÌЬ­ œ§ôìŸéng‰„[ïÇž†ªÕ€Ö I¸Ëœ¥éà¡Ç¡ÿ åY»Mpa²Â²JÎønn mºB5•$jÙykBW¨w †¿ É8N66©J,ÊUëA»nPë&¶ Ù狱ÆòÏ)†ì6‘èÏãmrµÀ9Š˜t.u$!Ú-\¢fåÌNÂàeRÃ’qìeiÞ³:ùßñ6ÿÏô×­0o„ÂÒ*Kò9¥Ùß$©šï›Çá§.nnñþms¼ñÄE+çÞžìRX¦:%œ·oj Ÿ àêË€£b„‰ªBÂë«éØp+ܦSΫ# 2)V»è#êýûîöб7V«•wß}×ï§9|øp222*€ð¬I,_ ¿†ØDxñeíl0n7ÌœGBýFðòøð\¢{wÃZÙ:|”v%— ¾NBƒÆ"špÚíðæk`,lpØÈò¥=õý,_*ê-Vo ?­ä%ÅðÝGWŽH5 iTªÏÉ‚e „ÜU¹¶Ü´œ²Y'…$jì‘0tHèôsÆBx«+œ½(g‚©/*e„ºŸýëàã¡P(ÇZ#¡GOhÑ¢œïÅ»µ ½‹nú0üåò%Ñ ÓaÃl4ýz709Lp𻲋zR-4¼¬QÊi†í#ŦÄh«Á£OA£{ÊÎqt\X]–A• 2¼0Z©Jâ±ÀÅJ&Ÿ@àˆH…Ç» ÷¦7ŒÃ —'ù|Ã2œñ"<§vU$û"_¡]ÿü¦ÞyôU õÐäaˆŽÁã| ɬ¤+Ï‘šó˜ ’âõÊzAAÐÏ¡—<\}ðiÞX>#Me£®R8ØT£&Ù‚H–#ŽË ûî˜ż’è&š(•êÁHذéAhý^U`o— æÝ…©B¢Tƒ`ʈÀ”pñê´Âæû!Æí‚~¡2–èu¼×TO5<Â%*÷êrÌ`„!ü¼]ª_GÚ×®ñæ›oú~–#FŒ Yký©Fÿ ’è‡ï‹×.OB÷îa¤QÛßÍ©©FÑ>«(.‚!}¡ØM[¡ÚYgví€fˆ4j£ÇjÁ»\0ïsØû§¨`ÑüQ:Lû~¶o9oƒ;Æ¿ ïÖÞ<,ù V/‹­Ú—öüʳ'Cv £&h§…xå8›-@ãAYB ÅÿZ™åšvIÐg0Ô!¿¸°w%ä©Bî‚ñʱ8´¶.U2ÈXc¡ß0xà¡rò^‚“¿‹ü£jy0½ž`·ó˜¯ÀÊ®p)Óß¼bŽ„#¡õceÙàÁ·à̱ÆA³ŽBªL P áòî²1ƒEÃOÿþF©ÜÙpy‰’¯T-½ZcáÞG ugHQ)WzBÁùf€$Ús0´ï€äþ,³3S6—¨7²áCÐþ¨TIÚˆTzF$ÅœCeøq[àjkˆŒW$Ñ»0ÈDdW9fÐ|{M -#HÑKÄ•úW"T’h„ ¼?ö‡#Êr¥3@®´CŒÉ_ýæiØû˜?8E™ ÊèoŽñö=¼> ©*ÙÕQÖ,“$˼‡aFHŠ¢l.Q«êóH£®R˜ÝÜíoòñ+µdW2È n…5EGMðõZˆòJñ¦)Ô+Zâ ÷d¨SŸ#GŽð¸j#˜‘‘Aûöí‰Óò&Táÿãöé\Ø·"caêÚ ÅdIµ/e‰ü£O>­ 4 â óó r:¼òjx òÝ7Ád€f­¡ËÚã/^„/?“ªÖì6œì6_ÍÀÙ´µpUjµR‹¨`aÒ`È Ú™Ã{`ëz(ÕÃý-E`¶Vûí;¸xIÉ\2n¢¶áç§ÙJ>ÑûZA·ž¡Óf5_*Æ G”MIO/8×}ào^¹ãÁÐéÚ.‚ã›ýͺdq?Á$ë‚cpò²d4§ºÙd€s«Êfw©~+<ܪ ÉYyYAr‰7ݽúªT†‹»T)†ë—TÕnó5ê¨À|µÈ?ªÎR˜&µŽ0#Å[ló}ß³Î\³K© ?77@’þDröAgtû VK£2(ºô‘\zÎ?Jœ¢­*ƒŒ DÝñì|íösE.Q‹JF4«²¼È ¶=)³?™zÙ 7‹Þ„ߦã÷ŽJ¨DeI˜M¢, È#Ìp©2nI.¹;Uó©Xgt©˜gîƒøJ7yM8©öi uMŠÙçÓ'à÷–囂u;üQ#‚ÜÊ¡“¨¦“¨&K¢’h]IÙ3WŠšwCÛžÅêÕ«9wîœïg3þ|:vìÈ¿¡ýs€pëVøúKÿ÷ö;P·®ö5ß}ëWC¥Txóíð‚à[_*Bƌ׎Mt»aöð×v¨UWÎM #Ïéë“àj&8#EuóD‡f¼›Ö‹êñ“^/[¹ Ø9ç°npõšXû†¶í´Y÷ا ¿Òo†q¯@†F’‚CÛaʸj„Ò—×:D™©R#Ì$äjQE̪àp~L}LY­QÐgHè4jŸ>‡w+Œ%©Œ™ ©iåƒà¼g²´è¡Ó3ÐãÙàç‰?u-Ëž’jøׂכ¼´®œö7†Äׄ¶ÝE,_`Æ™¬ùpèÝàá‘i0v ܦ’¹ Û ÿ˜ò¡6¯PY´7o«Ü‹ã4dwƒÂü²’£/Ïg ¼òÜq'g;0TÎùM8EˆL=íºCËö«Gr¯G2^ñ}wºrŒ8–$غÔ%,þ*Y/Þ*çø 4☣)n_Ç-&*y+a …MEÂÌ™2Ks*lM:©ú )S U¯0´d‡Èüe”»É¾¬dx}4TrB%‡èÞ9Ô¯‰VÈw@÷'á¯úþaé@ª[„Sxó–FªØ`D äFƪP»*N€afm(†=Kt<ÔÒIÔj˽š"Š(*Q8*ÁKïCFM/^Ì´iÓ|?³† Ò²eKþ-ퟄyyðáLaFy¸UxŽ2jd¤(¯tkyA-ød¶0bÜû ôê­Í„o¾}”´[—-.I"Äâ…aÚæk—aÉBÁŸé¤rA0YøO8¶O°®[ïož…³EÕr3У/4¹? GîW`qŠkêÞ.Xg¨k²NÂ/_‹R@ÎX˜}¯F¬å¦ïàÈ9{ P­. <À™-pþ„Â<œqÐõ9xð¡÷1Y$VŸ ÆUiî‚e9ºŠKBôÐî)£ø¬Ï-†-c§în·‡Ø ñœ‡'€Áœ ¶ì­U’hñ283Ü¿®·›#àŽfмØú¤à¯Ààm^yàQèÔIZ ¥—|g:3eCÌPï^xô ¨ZÉ3Éö8uÆ LPî™O€µAÙœ˜Q‚Äê¸z_ »F#Y‚h›?+‹ ¨ü 3¾&Ó@1Ç$«˜Z’C0=õýìm™†–âR ªÙ Ia¡ó;‰=´Ÿ 'à% ¶×,PK4¥Èp Œ0B~Lyé  ,åeƒñ6øÏ]±TŠôø±Ao¸Dœ9 ôþÝöy‘{˜0aN¹èô=÷ÜÃÏ?ÿLBBBþ¶ßׯ? 5]Äò…“Fí³OàjŽÈÙ³·öbðÝBØô»Hªýê¨^=ôx§æ~ç΃CŸþÚz/œ‡ŸÉR¯¿Q¾´ç“mðr¸œw> Î:µæÉºS'µBˆO…ñ“¡FÐg‰þ€‹DxES9šp–äï?+E}G…[5Ê?Í&/Ö:hô ôÖ˜çøVXù±8¶(‘F­¼¤çೕ­,ê7ʱ‰ådö§¶ûŸ Ú¢aÜäàçÊg~†_G‰dê½æm0ê岪€Ó §–‚Éá—…Œ[¡]¨×Èÿ¸-pd4–”-„[,Ïóò$å~<¥·LT, ¬3hÐAZ=xì)±!òÎã.‚܃;D½óÔhc'!ÅF²÷1ƒê4j#k #NƒÆ@ ’k‰ÿç—çÑÌ“{d>¯*äM£Vªbªî‰H"¯S*‘i‘;0½™êßz#\¨tW ª_‚uêUŸçB%XÑMÇ' pŠ’Ã%¢L2(Êsè,°æ8*‡J$;•Wõ\Iv‘Úì¢Þj©ó¥Oó¦PK“%Q_A_“ÎR½QΟ¹Ysµ Ue”I²C„KÇîˆÃ•ÕuÕeôšdRìr²€Â€^¤ƒzÍ¡«(ðÆo——'C¯§E‹ÜvÛ¿+”âï„çÎÁˆÀj‡Þ}á±0*Èÿ²J€Zb Lzj×Ö¾æà˜ó0» - ýëÖÁòï!¹Š¨¶®ÐÌŸûw€'JT°gžåßÃÁý”!¿¤0\Z‹æŠ`ðRàÉa(°±˜á§áZ$Uƒ/kÇ&fŸ†Qí!Ï"ßÖí¡OŸÐIÏn€³gÄø¨*0z¼6‹~·'ää) écáÙgËßÜì[—s@ EH•·”œ6#Z%*q¨Ó¨=ÚYl¢Êl€,p|˜üCW%x5· ¶€Ókü^ë*‹˜ÁûZ”M£vm ŸÅî²9>=ÉÐw(Üì=ð@Ö˳$x!\O24ï b#eÓ—+²Ÿ†Â d|ÅmcDÈûDrý¦Âò‹íÊR%-:ÁcO@Œ·»'’ù„/^Pg(l‹`çg™,Ûý½’¨M6¸ÎS¢ãxÿH.t¹H²G>¯S_”É¿ ý©Ú0kšx )A*ÉûxUx}œøzª¢r‰š ôÊ¡^)ö×»`F?! yçð3ãȯ 6ìCÕcK–HÃßSÅ 1£Ú)º¿6¼þ‚bŽIRÅ#úäP §5Hdþm±T‰ôPMNò™dªº ªÅ£N®í¬½ÇC[ÉÌÌäÏ?ÿÄ%wîÕ«~ø!ÿ¶ö÷B>ž-²µ4¾^£Œ‘Ó 3Þ1ƒÝºÃCi_c2Šl0™¡Qc8H[ÍÎÁö„)â0ò> æŠkªÝ#Gi'Õ>¸>xKH=ú„>ósþˉL1•Eº6-gW© 6­L­S7x¸¥6‹>ºíפß(b-CŽßïô¡ &дhúš5s ¨H1X¤×a£B›j~ÿÌß Ó¢´ 1ÏO£`çþÉŸã«Â ¡ÁëÚ ‚AªM–áÈ f`rZàø7J¸„9f°‰¨Ä\¹,pžœQ~‰¥æmᙞ xJnÈùB1È2°z÷À#] Me’²€‚-eÍ+j jôôéõXgûdAÍ€Ky´ T¯Ä$ÛzÿB»^y4 ”Ó©þ/K¡%Ÿh™b»Þ¹*ß@æÓR$¥n¤l^‰ðvoÞO#üÕ܉þ†õß±VÿÀžFàª,›cs‰–ª 2j£Œü÷Šæ²üéò—B2ÉDšaeM=Wª(Æß«÷~¼Œ6 YøáêðÚ Ry_¯Ôê+îëT 2KoŽ¥ªÞCº^È¢é:IÈ£VZ&1ºw£u_GhÚ·ÛM÷îÝÙ±c‡ê”*c‹ü[ƒàŸ‹˜ÁÊiBBÔ2È”–‹£áÜIx°™¨F¡Ã%úËJÁ £âaÊTТýV+|ôÞ/\¢/×v|æåÁ˜áÂù(ÅÂÛÓU;úmÉ<¸tQTH6 â5tù+9°ð=‘¼Z—ÓgjÛÍ:C:ˆ…î†FBvÔšgço0¥¿úc&†Žt»aׯ•#þ³ÝÒ&O Ð%¹°çW(°É5æ¢`ÜhhÕªœ M>Ì.(ÿÉo{&¼‰åœ%æž‚›ü—˜2V˜[Ñø®CYãJµú0fRp#ΚNÔfä Ës¾´cþsì†KʺøŠ€Èt˜ðªaã“° ,‚_ :?ç3hßç:–]Õ™èj0i*T)E²­£[É%ê}V>) ˆ©{ v…Û!*Kè 2:u±ÝBÈn‡ß„T‹’3É&¤J]QYÙÎÃÎwò‰L·‹„ØF%Œ!ÂQ%“L„Vv€M] º *« ,Þždó7âüÔ VwF’ªˆ¬.±fˆ–ç‰6 ³L´l”±ºàÍ>]jxçp*&™JvåïX,ªÉø–zªGº|ƯI&Ù!>¿÷žüŠúa÷ÝPšVÙtc(,à-ÑEÒû¡JT‹pS=ÂMMDMä3ÊT¶‚¾t^SL¾ª§4€Ó!&޽»v±oß>ßÏì•W^aÒ¤Ieœ¢U«VeáÂ…@ø_iF#|2Gœõìž$º{7ü¶F¥0DÛíPXÓß,­mGèÒEûšûàÇï„Afè¸I#ÿ¨Ã‹æÃÙÃÂìÒ¡£¶{à·_á»/AŠÍkß }ÍßÀöM‚ ¶y\H¢ZmÕ7pî<ÄTéÚÂynŸO³$À³YkèÚ-´ôºüCXô®`,‘)Ðëy¨âÌÒã†ÀŽõJ.ÑÛ›ÀóÊ¿æâ~Øõ‹ÂnJ#¡÷€ò¥×¼3° ä\ò7ÈÜ~?ôë_«ÿrÎû›QJ£`Ô@ÿоMÆzÈÏôg¨ÎxhÚ𴀏€ GþŸ°³Ÿ?“ò²'G, îŸΰŠO*5«s'À=­„U®-=eÙ Üí1Ðïy¸ÿApÿˆ®t»Â6ÍAXš-îo&bcbñH‹ÀbQ*Õ«+Ö«ž›Çž•Mªâ±±ÅvU½°m*]¡†Gäõ3­XüÃ%tFXÞ*„1xÿNtˆëÔlpñS ¬‚R×Û#Íþ9E3“aÃ}PÍ.2Àøåu)Ì0Þ.ÀlÆ#QTÖ¹üB%¼,¢,åTÊ0ÁwÍ`QGH³ûóõ†LxM3žÑ R9_YG]½ª:‰t½G°AD.ÑÈÀÄè¾¢»ÉÐm$¤f°yófúöUÂrjÕªEçÎIJJbíÚµÒèÿHs¹`ÚT(*€¾àéÚ aòÈË…NOÂ3aÛ[­0í5Q•¢Þm @%bŸéÃHovì(|8J­pómðòXÐr\J`áÇ"ãLçnС“ö<99°HެzŒ›©©¡¯9q¾ùlðh'1–$úã8vH,jú$xó?¡Ë2 á0xì x¶why3/K0Ho±ÝØ4xëÝÐe¦¾¨,´&½X˜{öQÎÅ[æn8wÐ±ÏÆ¢`÷síìøÄßUiÒ Çg÷^A˜Ý1Xß òsUÅiõPÇ›Þ,àìÚc‡+ë!ïJú:¸§¥ˆôn8ìYp¢]Rø*^è¡Î]Сd¨ÎzßCþÿsÁÀ3»îç×qg t‚,u¦ 2Z1Ñ@UYb5ÛHá¾õ3ì”=WÜþ>µR2Ÿx{ŒE6qtsz"{'øbù|çiÎL`uÃÇ£!ÿsAuÎÏ8«ÂTÍ6x·/ÄÇ*æ•—ø,ÑjƒŒê ²(¦ö‘ßÓ%^+©ç’Ã4’`³ê{w ö‰TDšNRÊ,y„)ȯž¡*À²»`nç€ÊŽ€P ¹_ŽŽæD•hÒ#ÜdD¸©¦÷PÍk”‘$¢A˜v‘Ì ïéúâðHüþûï\ºtIÙ+¯ZŃ>Öòý×_ùÉ©@øÛþü–ÿ ]ŸY³´s€O?çUµëÀÄW´]•[6Á²„$:l„vÚ1·¾ø2O @3^»z¼Ío¾V#8ô0d˜¨T lì6˜ñlü jÕƒ‘c´c‹ á¥A[(Øàˆ—«ϸf‰H½Vý!o–cç›'WT¶/²ƒ3ZÔ@¼ýöÐ׬ýý%ëJµ`øK‚µ‡js†)LÅ#B,š„H×¶%\¾ª°®ôº"íX¨Ê‹‡ù;,M:èÚKÔM öý^ù%þ¡Iµ`Ȩàu-O/…âbÿñ µDÌà]–eЦspøƒàà•&’‘ߨJzžÿ# ƒ§Q‹L…¶ÝàžfʆÐc‚‚å"ä#0LÂ;; &ÊÉâCÀœ_6TB PRŠ(ê{_KˆÖáqý&3:ƒR4Ö'‘ª€°ð&07òσ™`WSqÀ\Žxv¼æ$º’ƒ§Êµ)ƒ ÚÁa„Ýao‹²îMoš³D»ì•ÑŽ[`ks¨¬SÎëâJF›•tj^³LNŒ,BüŒ1*ôÎk…qõãY\?šäQ\¢IÈdÅ1{`[ˆ–TŸ€Tm^çèáØ8†7L'-ÒEz¤‹ ½0Éx2É6‚at-ôÄ'ñÑG1}útßϬM›6Ô 'nÛg…8Ìþýûß››ËСCiݺ5………Êéýû8p }úôaëÖ­x<žÿE@xíš0ȸ]"TBkÁص ¾™1±á•JòÔ¤qPT,Òmõê­Í ÷ì†/æ€.ú „ºéÚ$ ¾ýþÚ. q“ò%7?6t ~Z |î¸S{ží±‚ Þ×\€kµ/§Ã׳Áª‡çBƒ0,ÑSú €¶wÜÏ = IDATõ ýÜ.óÄxO‚p;6¼=ô½lûAÄ?zckÔ…á#ÊW­†/ƒQÀ抇žàþ¦åË®«§‚Ñæ_(¹:L˜|s³s:lžíŸAƨƒÏCÓfeÓã„Ã_ù—&2ê IkhöxÙ˜AMZŽ£Ú=-æñ=''\š>ÞçNu:Ìž=›¾}û2yòd¾ûî;Í÷ùw~ùìÜÍ ÏLRXïÏ€œlèÚC$`Ö‡ï¼gNB• ˜ñ¾vÅ€i¯Bî&0hˆ6ÿ̨T >ü¸üpŸ$j€nDüX«"y·–TyúŒ ¥f¨\^ªyílY/Îù:>}Ÿ×žçÔ8¸G,l)0í-íMÇØÇáL–`[-ÚAß¡ó¶^=ÓžUAO‚0ü”é°Â¾µp¥@a›ŠÈò L{¾…Uo*ç#%€.Þû xú9ã%8¾Š\þ™†MEÌ` ë´\õ}I´‘€òÆÆÐ¥Ô½­ì³>üœY]6³KШ)L˜¢üÞœypzœU$Ñ"Õ<µï€Î½ ž*Q¼ý8äoóÿÀ¢¾õïFœøSP:Șº`&œ" µ<Õn» ‰Ó¸Å"ë5Æ«^UFœ«mÀUS˜6ÔYdb̪"¸ªê¦´x6Ï4S®–'#þ9?#Jà­7ÁT Ò²qEÕSoQæÉŒÉãÁ“!‡ ÆÅ˜eSŒI1ÊxûžZðJ_ÈP½oe•4ªÎ(sÉA¿¦)¤F¸IÓ{¨ª“ĹN"Íñ¥þïí5ùDál œª¥Ê€5Ù¡eVUNÄ–µ"]T‹tùŒ25ôªI±&QlWç5Éx2Ez¸ïIxbèôLœ8޳gÏ –¤×Ó¹sgj„Š?ѶnÝÊêÕ«0`çÎcîܹeÆ´k׎víÚñÀøèFJJJh"«@©©©\¹r…›Ã!9ÿx Uuªºº«Öó=ãó½ïãYë^ÍÌœSwWuÍÙçÚû ‚Z n¸ñfhš§@¿÷¤ Ú$AfðІ÷ñ–ÃÊçÓóGkc˜8%w« ä…/çgÕúu"{ÈE`ŠáÝ‘°ùóL¤fo7Ü’ûÁæÀ·°ýc rŒ%‚Ð:v«û7­ùv’[Æ`(Âöýø7Â幃pÙ§«=F·Àî+ jW]™daôa¤êŒ»&}Y¿SòÅg€‹/RY¢‡IÄF€sæ<ÑW— ³íXŸÜÄ“[DüD³=>å³ÓóÛMz܈4 …Î|™ò…d0îw P¬Wb”¦YzÍ{ù¤;T66*Bó$D”KäZ/öW\}ýXš$ãÊ"äxãzFµ+f[1¥âÑ)ë)2Ž=œ™^aЄûnuÁmÃ!h"ŽÖ' FámW)Ï4/£‘!H‰!N©>A™ºë”ÔJOш†M€²¦lÞ¼™Õ«W§¾6ƒ)S¦ü—nåü17näž{î¡E‹„Ãa&NœXçºm3|ù) 0~¼ìÓPÁUøa-ü© áÛw“‡Ž† |º Žø„U8ê‘´4t¼z/,™›.Çw†›n®¿%Zµ’žóÌ0bDÃûìÿ~ý"†jÔyâ”i¹»G6‹ ·vÆå7IçáÜ ê~nñ0|8&íõ™,2Ý{ qÅ‘£ÅôÉ9°¿ª®KK0ä26<ó;úÛˆtqÒž[k€SΟÏ2 ó×÷5ù¥n&¡ öê'†ú}P»2³(g³ k Ю;\r94= …÷P‚?úÓ ç³»n®.X xZ Z7oƒÐ•૪;Ô.ÇQb£Ö¾3ð!ñȵ™>¢Z¢Œ¦è~{7ìïÅþL‚Œ5WØn5x=z÷4â4ıÕ¢äÏÊTçjúZøü\0U]´îlÐÊ´k{ô&yfLÊ\–¨YÝGK”yú° 4¦gƒžXš1š$æ8#ð¹ÙÆ Çã1De6¨®RB±¢` dY-ctE[ˆ™¡Të~£ý·ºŒQ=kÝì¦8¥¦(e†8eÆ qâ”) ª@_•Õ¢®Út‡ÁcAoàwÞ¡¼¼<õ•>|8}ûö¥oß¾ÿ¥[ú Aƒp¹\üë_ÿbâĉFŠs„$‹[4%‘HF‰Çã¸\.<ëׯ§Q£FTTTü—[´ÿ÷šxô8½;\5²°k¾üR Zi™8´ä›‰ìØ.E =\1" d^¹ô-Ñ N¼=´P8,6j›†˜^¬ÀzõÊ¿Ïâ7á½Å`tÀÄÉ…½Ÿþ%3»°^ }û5ü0Ãâ—dvél*,Ñ|‘L‘<:Q§¸èB4¨á}‚>X¾Pn¦–23šçyàØ¾Ön‰ö¼@>»úŽ?¿‚¦[¢#Œmê™+'bðËJØ¿Oc­ƒäÖZ&âðã<ù½´íÇ®½1·vôÏ7aÍ-™$î{³Óz€ÅV=þùrn³ë„ n¸53Ÿ±r9l ÞXÃjpÃç '¹C3 ÆŸéš“ê{ý ¢Œ-ÿO™íÐì"¶ÂY犃ŒIG"¾Xпfž¨Ó\µF£°{  mD-¤i‰fù£~øj ¥SŒFª#‹ISø’ˤ’LÞè k.¤–$ȸն¥;¦zoª¿OÔ /õ¥(MZñ¨³ZlµÅÐä“D¯÷» ¹%Y“¯Ÿ,´nµ»Ioal«FD¬Qšâx qi‰êŠQR-QSv1÷Ã{íàþKÁO¿vŠéª1ð6EõÜë9†/=vš˜‚”š¢”ªE°‘!Nc}»_‘¨ÎiuU*k´ 04¡7CYS–/_ÎØ±cSD•víÚålcz”••áp8èß¿? ,`ÅŠ\~ùå 80çù>ŸË.»Œ@ ÀÕW_ÍðáÃ3f 'Nä™gž!rÝu×Ѻuëÿ‡ a oƒN\]7ÉMy9Œ+æÚ×ÝXXþ_M Ü=M¼KO>½0ÍàîÝpó8)nco†sÏËÍ÷ßÃ?о«hóÙ¨mÛ/Α4Šk¯‡ó.(ìAà­¹2Ok~,Ü{_þ}¶þw;°+GÉûÉG,zó9xíy¹1 3ïÏ?½ûòtºòr8´aÔùËç0cXú&ݨµhj…¥š}jÃî‡ëo‰V¨(úêQ`þj¯­;?¬ÊjY¶îý®„£Z¡(.H9Æè4ó=]M&Áæ‹gÁO;Ç$SÌÙŽ;êÚßÕN´m€²„"(Í›éõ©•”›as{p%¤]©uwI¶,Í>õýVÁGÃ+Ck4¸*YǬ]*Y¦RS®¯ šGrï‘Ò†a•Ýß 1ŠÕ™]©N¡LŸÀS°d“pÔ÷RÜ4LG㈒ŠkòdEF% 2¯ZZ°ÆYLs³—2S”F¦(±”~°$–$X©®$QFýÉEW@ŸAC!–-[FeeezLÿÞ{ÿŸŠÎ€éËo¼1ïù‡ƒ5kÖÔùï»uëÆüùóÿ’2ô?/ŸX¹BT†^ 6yþy8¸_høcÇvÍwßÀêUPä’8¢|èhTÜ`î…v¥%šïðz᱇äñ"L¸NÈÓBŒDàÙÊ|°Yk¸vLþB³<>ª½R'L„V­òÿ~/>&ç7n-¶pŽ< Öòðþk‚wsþÏíûÕð«Š*Žn£ÆæŸÁ.}R¢†¼@Ì*i:ÔþGÿ‚ê`ºØ6;^"°B©+ËtwñÃGÂõH,¾x¬®×§«9\5Ü9f‰¾ƒ°áõ,BMS8oœ£í.‡ßäö5KëµLS wN‡YrŒda³4‚óJâCÒR0á‡CÏÔ%Çh÷1—”»Å®-:;Ó=&[.Q ˜ËàœKá¤SÁ '“kt™„.G¨ï“ÁÛ^ã £.KœÉûÚÃÚûý™¬á,O_¦“L< N€mU•ƒÄb ©…¹â^x³§U’Ë—sre‘c& …ŽK¿f®•Djs‹Jxª¹—1†KŸÀmˆãÖ'ðè•%ý0iþ=·».õ»g|šU™°ò¹½˜bS”bcŒbSTH2Æ¥Æ%J³O¤†d"ù`Sr\6t:¦OŸÎ¼yóR_³#FЬnÔÿcÇÿ,"ܶMÈ.n7Ü;³0&¦ßŸ­–ãÝ3Dø[‚¼ò2yò?«—hó!¡•+`öCBÁ¿ãΆoÌÉ‚öØ£ðÕˆý–›øãðÆ  ·ÁŒû¡m»üóÔwß‚ï?ƒˆAÐɰaù÷yf6,] Á-“s‡ÆfK^ƒ~”bï‹`dž¹å¡=p{8–ä„IùßÏš…ðéò´ƒLÇSDËWŸô¡ö|ýTEÓ­Ç›&ׯxm<|õN&l Ü19÷û©Ü¿|”) ˜Å©çÔóëšðN¿Ì0\¿úö‡^—fÚ›¥ í°ÜA¸A«h÷ ï†+ÒFK\ Ù çù’MèФ’ì‡¾©;ãK¢®€®£Ú¨= Þ/25ŒÙ!¸A+œÑÎENñ!(µŸ§P –$£Óì0Ãǯ‚K‡O“—Ì ÁM®„WÇþV ̓8£¹]]RsµZ˜6vM"2¯Ó¢3*30ª$§Cq˜<ö+1DeHÚƒ-€ 4­dB];Š`c+hƒ’˜È$’Ë“E˜yÏäafYc<¦ cŒbcŒRCœRCœ]‚¢’B‚É×7ÕB(¬ãžó ,ï¬Pg8ÔdWEíLpœDÔ£©ÅO™9’FƒÆMôqŠü úJ ÜÕdô ‹õ3à¨6ìÞ½;Ã.­gϞ̛7K>ßäÿÿYDøÏ'`Ïië-°f5ü²ú’Ö^!™§ž‹IÍä'‡$Rcè}~þ#€M›Äç3…£ZKC>RÍáÃ0i¼8÷^ÐWìÚò½Ÿ?ÿ€Ù3!‡’æ0áæÜ ¿Ã‡oõ¼~0`PþÏì³0ÿ!A q Üyw¦Ñs®ãý‚Ô¼@ïKáÒþ ÖA/|üV š‹áî{ë/‚‘ ¾¾X&Ì&ï49.-Eá[ÑŸS&ÜÚ°]]m&ŠÜÚ,zÍ\0œ«çÚç§Á Ç=ùëd´D™_[ÂᦚY`Tcw¦þw–@úµ?<~;6í#Z¢25ûÓH0¹L~ø¥DÇè+u¸â™óÆ\3B]TÏ»Vc—1†ÛÃmˆãQÑ #¦¤‰7þL$¸Å¡cñIFŠuç‚Ú€ß1'“Œ]ð[õ›#‚ÕÙ`©1F™!Ž+–£îêLñ¼.i»wÆ@8óBÐé™7oüñGêk3zôèÿ•Eð~´ ¿ ýû‹ u!ÇîÝ0ýNGAæcH*Š$KÌú ‚Qcò{–Æbðøc°áGhu¬€B¾o/‚»Ao#’û,z¶o†6í¤Hb×öàÝூÌu7©§æÿ Þ]$ÒÖpý8(ÉÃ`õ{Åzí@„pÃ8ùä<ïÿI˜÷ ÜLMÅpËíùíÚ%vmµ@È£¯i86«r|¹,Ýâ,n ·ß ÅõØÏECðϾRœrC1Àða¢Ìõбë;ñÕÞÐK›'çþܶ­€ odZµY›Hn—è±j=|q5>R×JÍÞn¼%SkYõ)ìx!ÓF-)ËPÜÐg Ø¨¥þÞQ¨ú*÷æž÷%e&7Ý­ZCô|ð~œ› “BVy?ÝÎãa”ÈðîË àddÔk»6MT 2jtD4­Ê,©H$®gG_†PbôgÚ›%‹áA<0ôEÐ"9 Ìbp…Ó¯½É {f¦À'§% ÎýéâkÀºã¡Ü-¢i†¨–%š\º¸±ÎÖ|æ²Pj ¤‹ 1†ÇÇM"E¾É¶lóÇtÜÛËŠ+Ç•PR=æI³F×'<ì·Zij®•¶¨9’"É”c+qLµÂ5TI!ÔWªŒÑJÐéÁ•·ƒ»„O?ý”^x!õµ)))aÑ¢E¼ùæ›_×îÝ»s÷Ýwÿ]ÿ#Çþý0çqiUÞ1%÷Ì%g{ï)A÷?ÜpÚzªeUÿ|\èç“§å/‚뾇Wæ‰]Û¸›¡}‡ü×TUÂk/Šfðô3D›—¯¨ý´æ< aEæhùüGãqxãøú#‘>œ¬î“Ý~þuu±Dí’DѦsã°ogúÆ^ Õ¦Nͽ’€7®ÉDN>£ØâÝ#÷ßçߥM›ŠpÒÃùÀƒ¡(Ç vçéäò=.΢«ÿ2D|d³ 2~œ}¡Ì‹5ås`×#uY˜©}tÐ÷ré>(߀oC朲*«%ê7C—pÑP(k‚¢<‡ÜW§šZêµA:¬zp5-ÑPVKT}?A¬y0AèDqlÑVLÞº¡¸ßœ Q'4M’Ubš–¨ZD´) ·L€¨[âŽÊ€âdKÔŸ&ɤH,>XÒÎÀçê(‹ÇñÄ5íPM[ÔƒhÌÄDã±|a³Rfòã2Eq›¢Ò5Ä)Öű‡”t‹WýiöÂ>½Û.±³«,AI\Fj¶öQ}/ë"ÍxØÔR‹bs„KX$Æe¦(eúö€hÉBX!…PW º°FÝÇÈýlÈ!)_϶mÛòÆopr¾‡Ý¿[£ÿÍÇ;‹áóÏ„´Rˆ¿%ÀÚáµWáìž0tha×<÷ŒœÛî§ß|G0O<;·C÷³%<Ñà…gÀç»î¼+¿pà‘™P[ ]T¿Î|­×}ûdÎWãOa£æ³kXð´Îng «2ß‹Á«O AÆâÆÃÑG7|ÍÖMðÙ*)œí» Û±¡cÏŸpß•°}—Ü„ýÀm“ MóÞoÞ‘oJ3x:Œ¸ºáÏzõÓirIR–1ùÎú¢>¾?³(Ôm:Š61—y÷·ƒ?žI)m-™mê1î~º.q¥hu¢ø×f|NOA­7·ƒLIèy‰ì“ñùT&!(Û¦y[ñ¯å']þòTàna-àl.-ÞÖBúR"OgD+¥2Y¿ßgÁ‘^*ÔÈ%ÌrÆ+y]°¿ÌÍÁ´ƒŒögòßË΀×kZ“9ˆ+ú}/îA'xPƒvq²Éh‡Ò„™w3òPo#îdqŠ¥eÙ{U$,¬5»p˜¢8LQœÆ˜eT’Œ=¦ät©1úàW·‘ßpÄœ1WLÉô+Uß˺psŽwÁeŽà6Gð˜#xLQA…¦(%ÆŽh"]¨¶Eõꃊ¾t'œ ½d$òÔSOáõzS_™³Ï>ûuüŸ)„۷ÔÉòDzåˆÂ®Ù»yÌV¸gF~íÀ·ßÀË/B¿ÂH-d–øæ"X±Ü¥0ë¡ÂDðkW‹wÜ íÀ=òÏŸœ _­…â¦pÿ#ùíÍb1˜9 öm…†¹eCï)‚Y“`ÍGPÖ îš™_›è­…qýÀ«Î쮸† ixŸmáöªiõQp×}Ð2ƒõ§O`목¶FŒ‹.®ÿüàÑËa¥ê ê‘„„–õ<Ü„ýðÊ8øñ3 ²1Šw}møïž…÷gf¢4]1Ü6=÷lÔ»~_.¹~IE1œ? º÷J§Ç§²ÀªóÄi'›¸bj ·ß•é­9û߇ÚHæ¹€±œ7D2Ú}öŒ¦o.N%b§uÛ]B‰~Þí™Y›J<ÿ¢Ëáü`ò‘ˆG©ý=Å>Ôå Ü­„ª¦Ps²È$´A¶ &ñA»¼&>xV'¶c¡L2‰9ËyŧÀíÁnHËŠcšGe/<· Ü3l Ám„Áä$hUZ¼²BQ_·0`4 j,VI2%ê>%š=÷G‹¸ÌÔ§9’*R)4hŒáVâòÚµé×7«á¾?:-L;Ç…'®ÈŠ)™¾¨ªt¢:ädzàLÖÅÖ%–0%ÖdT¢L©.†©Œ*A&%›¨PxÇÁ˜P֔ŋsë­·‰Dñúœ;w.ÿÛ¿¶VWÃ]wBÓ&ÒÖóØ]ø*¬]+à´ÓòŸ_QO<>ŸHÊå¿fÓ&˜ý0 “_§Nù¯ ‡áé9pè´í(-´|-Ñ¿Àë/A\'TüÎ] CП,éCë¶b×–¯°9óŸ ý‡Â©|nß~ë¾tЦ=Ü8.ÿ>/=å^A[ý†e&$Ôw<Wš¦ßª=Œ›Ðp‹wÕ àU‘WÀƒóبUì†UÏI‘J&X”-ûäúÎ*`ý;éókÞÞàÐ'‡v4\ï_[¿NN¿Ú  ÊÍÝ¿¶­ÉAÎíç^¨Ñ †á·Q°wunòʉ݅ªe‰…ò/Á«äÞ£8õœ4!+xW¦ŸhuŽó[Ÿ$¤§’F(ÊÏ(Á7Ñy•ºˆP3-o Ÿ<fSZ.Q–ŸFoî}þ<߀ÙŽX™™üuCw~É ü¹‹J\‰ËÊFƒÍ>³û€[—–J¸â2Ì&Ç$ÿó}gÚXÓ6‰¥HÕA„QØq2&Ñ‘ YÁiŽà4Eqš¢‚1œº–`šx£%þ|ë²rëYÅØgBI£¿X&YƃÇb·†qY¸ՕBƒÆ} K@Á¨d´D™äâü‘Щ;áp˜ dÄÝÿýÆ¿ á_¶S<o¼ËÞƒ±7ÂYgvÝ®Ëôsàúë »æÃ`õGÒÖëvJþó}>i£îÞÝ{ˆL _$À‚y°æC0Xaú=ù[ˆ‰<5þüŽ;Q² óÍ-·oëµ/èìpϽùç£?L´jS§ço×îß3ÆÂá*0ºÝ6ÔªTøèmød¥ ºÎgŠXƒ,Q<1NŒ»k¸ n7Η” IDATšØpdÍøt‰ÚæÓ‰ìáÚënY¿4VŠyòf4ÊûéÜ9÷ù‡~‡ ŸdÎí'&Ô¹ØÌ•[à5™Äg ¸txfâC ÝUÃ7SêZ¢UΣa♄ŸÐnس2M©"ÓFíâË ]—´fP‰ÁŸÂṟU@i¸{–T…ÐHðjê³dò÷ºp(t: å$¢×§É0jÛ45#T¯SjàÐIi¥B‡ÓyƒV?9½TwvÕóåôv³’rvÉðøÔü»Zë»hæt±LÉ„'*ûèªÁ„‰ƒÓ&Ç+éàßìeöÁݬ:ÁŒ'‘Diä\îü÷°ÛdÂiŽà0GªóA·!NQ4‘!ÐOÚµíÑ™¸íÔF¬zœñ.u¹cJF¦¡%bd~Õ),‹Û’¨®sD–)JQ8±ZŠŸ±ZæƒúäªÖ£ëÐúKË}Ô¨Q¬\¹k³{ï½—óe°þ]ÿ›;à±Gàøãe¾UÈì­¢Bdô˜4)¡I¶^o¹ Nî&É…´UÂüçÁh©Ó ‹úi=<÷$y$5ü‚Ü`V,ŠÕwß—ß®-YlúâF¸ü*!bä;/„ï¿k Lº+?»àçaß!) mbCŸ]0‹^€#^I{sþ9ì7+à­ç ZEw§õ„Ñcê/ž‡¶Ã`ï!¹ù†-0îV8±´¾ù3رI#1Î>F^{»óK˜78“1wÀ­Óê'ü¼]&‹3b‡^ýá€-‡$cçR8t°nJ¸D©õmõ®‡.N3cµÅ#ê€îçÙçfÎ,k– £¶>Í`´F\/óøØ"ð.ÌÌUÌ6úÛáôs¡w_0™Qâ7Ih°æ÷×åHÿó<øá•Nÿ´‡d^•8¯ÔÂŽKÌØœjƒ?Ë9Æ—Öî,‘ìŒ"˜$–¨Å©(”/k Ë»B‰Nè­P¿L«?ÍäÜc6ðKc#NEQ !i’L<³è® 5gºr<mLBc G<ž.²Yn5kJDM:)~q™ fÈ>Ô/8t:Kƒí°YÃR­¡:EÐM S¿d4T©íÑJЙšÁå·AYSÖ¯_Ï÷ߟúÊtîÜ™3füG¬ÿ.„¹ÐÃCŠþî{ò·“ÇgŸÂ×ߨÂäÞ…íóÜ3`³ÂØqиqþk xìañ–0¸°}¼^™ îÝ#ùm×Í/±Ø»æ<(½õƒ=óï³y3¼ü´\SÚn™˜¿¨mÞ/<Þ0\Я0iÊ’°ð)!ÈÄ-2‡ÍGÄyz2|§ÒîÏí+3¾† g8¯<$ÄànÓîj¸õº}üüušÚÿ à‚f‰;~€çFÂÁŠ4YÄsÜ8¡³6,…‡2 ,gœ ç_\Ïù/ÃÁm™á¼-;BŸþ™‰©ßé øâÖÜíʓΔïœöõËWCÅÖt!ÔjÛœ$©óvm ìŸ[— £½¶ý©pÕ52œ <•é S›£]Ù¢½h›·BaJä‹”cŒNÓÕi ©R \–&ÅØ#›T‘Öf.‚Ìçãa瀎xºjò«ÿVW²%º±iš&®$[¡É»£é}*£ðòi™î1©–hPÓUY£á˜Ž›{³³Ì€[IˆŒ!I”‰§õƒ®|8Š;ð[™#™#$‡.žj‰šÕ÷’l.lZ¼ãKp&8”Ž„‚3.{IkTÈ2oïíÎþ¶YC8-aœ–°Ì“dS·>ŠÅ¯¤skäaC»tç\§ôBAÇêÕ«Ùºu«Üôõzôz=ñx<ÿ¬Ì‚†^–`¦N†_†N]¥Ò/_ñ¼ùº8€Ü6)ÿù¡<ý8üô½êœ2-¿‹ÎáÃ0ñzú!f‚÷˜›ølÝ ­:ÂÓòKS€e‹dΧØáÁ‡òÛ¨m\kÕ¨ÏÑ0å®üvm¿~ ¿n›`Ì7OjØR/…û¥oÔ-;ÂŒ¡¨?ÕWÀžÝšø#=L¼.º(÷ù[?…ç¤QM%Ðê$˜ZOZÈÞoàÝQ™ÔW+< ºæ¿Dj`ûJ8¢ñM^ëi ÷ÜŸ©ôm‚_§¥Û•ZB‰± ¸N>3½O»n…}«ë¶+ÔE LŸMšBd ÔnÊD¿YûP"ž¥'Ÿ)ì‹Ð…9Í·Sv]ê>®oW(ó IÆ¥zŠÚYa»ê~5ÅŸ­àI$°¤Fk=8“>œæZøôDxæ I}(U‰1%I§•¼bõËëþ¡—à–ˆ'´[ªˆ“Í/ˆ0¹’n2Wô(ã@±ŽÒDTMW(‰CI\ÉØ§<äbBÍ©8\µ[C8­!\™ß¹Ì\Æ(öp«¬*9Æ¢¾´¹˜}|SJtAÜJO<‡E‘¶¨J– ùl 6Çià¶pÛ‚xÔUb Qf SjŠPN`ªS¥ü™’? ²ôeaÔ`µóòüùL›6-õ5{ùå—9ýôÓë˜`wîÜ™Y³fý]ÿ#ÇîÝðôSàrK¶\!Ò€9³Á€{ï/ìš`PdZµ’Ù`!Çúà½%ÒÎ3ZÐz­®†gB‡NaTÈñóðÆË׋ =Ÿd$ƒ·^‡ßÖ A¦gI–Èw¼ö2,z B:fç‹JxõEøì#Aƒgü†åaØVWÃKs`ÇNл$Á"_Kôû`Ö5i©ÄI§ÂW4üÐñþ3iä¢8`øµù[Ö‹ï“=Bf°8¡Ms˜0¡þó?}&Ayu0adýÚÑÏI‹¸.îgösŽŽ@ÍVøõõºR†Ä~/[¹S}ÏÙ™E¬Ïè“©MŒ€½/Öï%ê7JU8ítˆ¿ Þ±uÃvµç‡-â ÓãB!â$‡piê´ïCCHñÁ¾s3Ñ =¶«-¢ê>~|ð`œH[hÒ À!¸Ÿ´‡9—K›Ò­]‚LQ$¶ûN'Á·DäEþ÷$ ´2á×Å6*í\J .E] WBd¾à=›5„Ý¢(š¢Øc‰êÔz—šðÎq¥‚•ŽD§.!DEQI2 ú…'v^ÀNÜ”X+pXÂ8­!œæˆeTDèˆÇ3² µˆÐPz})Œœ .a£ßwß}©¯L·nÝèÞ½;'œpË–-û»'ú—Â'ÿ ?ÿ sçf HKréè?P4ƒù4v±Ìš û÷ÂÓîãõ¤Ûààz…ÌòÍ-ƒA˜9]ŠÁ3á„¶ù÷©©Ûo‚šZ¸¨¿øœæcbþþ;<<Ah~ LžšŸa[S+ß–è¥CrG ÕyHÙoþKn¾®¦pçôüÒ”/WÂÚ¥‚¶zô‘Ö^CŸH¾ýv›'N˜õ 4mZÿ5kæÃ ÓÒ7éœ'­½úÚϾJxq,Ô$äü²c E6²~ Ì’áëgÚ›ÜCZê¹Z÷µ{`ãûiÑyŽê I GS÷oØ«¯Ê4­®jõpZ/U˧íì‡]屢`ÙÕè¡EG¸dx¦f0v¶\Q§È¤ /:èt&Œ¹Œ¼µ™™¬™¥ÇÁ¥W@Ëã€Ãùwæk'³³æ}«ÞØqP™ 3™,á#‡ ÊÛëðvUhÏt[Ñ:®˜|‹Âwí@gâH– =I\‰¦…óËšÁ‚S2Ýc<1‰WJε™¯\EÜurfk„ÆJ"Í£('””,Ã1ñÀá.¼kF‘»–"KXŠ”%,ŒQs‡.&¯Ÿ%Ë„ŒÜÕº5?–Xñ(a\JW" iÁºUbN"àà‘_û³GçÄ驯i â¶e6¨Î‹-a<ú(æEäÕY³Á*Ð×Ñõg]Œ×ëeÊ”)ìÛ·/ÕíÕ«'œpÂß•ï/-„ß|#IƒÃ%—vÍÞ½ðÏ9`µÃ”)…=>ùD4€ý ™¤Íà sáç ÙQ’N^ÈÐø›¯`ñÐçB™[æ#â(ЏÔlÝ$þ£wL-ÌFí‘™R“%®=óÌÃaxàNøä#(m%Ž8ùìÍ*+àžñ°ÿˆ œq×åÏgܳ¾jÂàiS¦KË­AÄù¼ú„Ü|ƒ{Cöp¾*øâ]¨ ©¾ Má–;ÖZ~»¾xGnÖq‡°7/Íë!#Ø›¿‚Z%]<Í`üm¹…óå›añ•PY›¾©ëK$Õ½K÷Ü?Ì€=›ë2E-áú›2MÏÛàÇ« rºÐ¦ö)†>àÔ™û| ­«ë#ªµE›0IÖ¡ö¥4Ì>7Iºp˜k›Ê!6|¿fí’ÃFmO7ˆ5K3Dª€ÞÔ´O5ûìè?ªàVäœìâgö«Î+>˜} ¬9C¢<ñÌ"˜´<³Ó¯}ËV‹’Ê,NˆvÑêÏ,„ÉŸ3»5FoŒ«0]=ŠÌ“„™ÙûNgyè(œÅUØlAЬ!™& ¢!Š-¤¤Ð¦E†ƒFf59žuž"J”N%+Ç¥KàTÜ )†Q¿ƒyú³3V‚«¤‡=€Ó”Ö«-˜bŒº¬¡„djb˜”MT«…°Q¸âVpóùŠ<÷Üs©¯ÌÈ‘#yì±Çþ®z9ŽÿYæàA!È4oãÆVОŸ ë×ÃM·fovø0<9Gˆ8wL’’ü×|ýµBƒAŠF!³·X n¿œq')$)ãûïDgGœþói^ >_%ý]Do™ï¨8 ï¼ a\5*¿fPQàÛµðý—ªëÌ™bWÖÐÁ[OÑjèaØÕùßO$ Ëç§[œíO–}z8²>[.ç‡L0ä*èÒ€ëEíaxïqõ&¯‡N¾—IêE.¢ÀÖ¯`ËÆ4: [äýœÓ'ׇ{¾…]?¥ Žß' —^–»pøþ\Q·õX«ƒAWBï¬ÈšŸáÀ7™¦ÚÉó;-Ù„ZÍ``=ì»þÔùZˆàÏ=ÿåº-Ñ ‚ŒN>·>}ÁS ʦ5ºì¶®Z¤¶ƒ/£5Ýu¨ºACcÂÛÏ“'mvmògE©Z»x>:]-xjÔ†âz4-ÑX-÷߇ö‹ùòõ7æž#im[aþÓKÀ5caþ‚ü-ѪJy Ô ó…¡Î];`Ü0¨ð£±w"È( ,}æÏÑy‹„‰™¯eýäm°c·Ü#–ü„Ÿí?Ô Ò7ÝS{‹6±!Fî†5°}‹Üœ#n”Ve}Ç/ÿ†7f¢¢cºÀuãs?Ü„½ðΨL¯OOk2 ŽÉ1ëU°u8X7ضU'˜8©®vô›!uÛ••@ɱ0à*8¡Sæg]¾Ê÷Õm;&‰/GwÝ+]ŽÀ(¨­Í4ßΈXÒA£ã¡ßHèÐt?@¤oêóÑi 2ZRQ%ìé!€UëãKK0ƒ¤®¯FI7××H 4þžÉuØ×ßV#”ÆÓñGÚ$wTˆ4±j˜ÚÕÀœ3ô¸ ejKÔ{@d¬Yr‰§jÊÜãa×'ð ˆ°8‘ 8!äâ¸BILÁëwqõŸ—b±…°Û©hÐa ¥Z£EJ,MÂÑqvEl±8qéâ¸ˆË R‰ãNÄqǸc"ŸXøÝvšà(òSTäÇiàJ.[5D±5„KÁ¢¢@S•ºªÓ$c­}Ï+à"që:t(¿þú+n·›ùóçsöÙgÿ]ñþÒBÀË/ÃYgÁe—vÍÁðÐ`/’öY!öfSíô„!ú®\!‰:£0> ±kûâsxéèy.\vEa…sá«ðåZ°¹`Úôú´ÇSs`ó/pFOÁw(ðoرŠ›Á-“ Óg¾8[$à’pî¹ùÑð«OÊù¶29:$ÓÖ iy…‰™ºð†¯Yý*ìUg‰~ƒ„Ó6d×öÍbxaBú&ß»tïÙðgðÁ#™D½n\¿¦óË9ò¾“×ÄpN_8­GîŽ À·×õ,5–À¸Û ,ësÛ6'7AFqÁçIKÔ ù¾y¶Ý_?A&ဣås‹} þoÓ^¢¹\j"6Ñ žÑKÑ?¾ÚLRŒ7 ªr‰Í7dúˆEÀÒÈ*´²~#^¢–2=EM~ØÐ¶¶Òx|ÆëFÙÔPß^ìd ˜´—¨'Ù "ÔdŒo´(ÃE§ *‚Òܪt"¶r÷Ÿç²%æÂ¢¢A›%ŒME„vs»!Š5DfK4û"îõtÂo4â ŽCI®Î$Y&¡pàH öx›aµ°ÙØmA)¶¶`zi ã4F°”T~aŠ$£"BC-èm- ßpxøøãÙ°aCê+£Óé0r_ø{Føß|ìÞ-¤—Y³ ËL$`ÉX³FœSzõÊMm­áZ­2ãË7«1®ž5Sfˆoo8ò'yxkaîÓPS-È)_ö_²@?;0À˜áÌlÇV,‡% …1yz&­¾ÞÖë70åEà†kEšÒÐ|4‘€·ÂÒ7¤@5n÷Íjx>ÂC3`ÓF¹fì5bÓ• Žé‡Õj›0=O”ËÆÏa‰ª‡ ˜`äõp~…3è…VÀÁ*! ´;†Œ„Ò ôêÇàwm‹Óƒ¯€^õ<|ó$¬y0ªPk¿~W€+—UÛAؼ4‡S‹.ê —ôËüÜö¼ ?M«‹ÔªõBt0Š5„±#pp)TÅë&K$¯íq!\3LA¨¾P‰r¡Á$¡¦}wè?Br•å|³N2½.Ë·4h‚/^McRh0W²D%øuðáSà6Hë4‰ü²Åæf/üÖfSåšÔ‡’xÚûÓë°a×ö6S¢KP¢SÑ "¿—ÕŸ&ÉØT4苘˜Ü¶nâ*TçƒÄÓ3„BØïdÊÏ—²Ã`Æî®I©T¡²†p˜ÃØ#‰Ìù£ŽÜb;“˜1†‡ Nb¸ˆ Tâ¸wùÇöí0ûA™G]9 NêZ`[øYqx9¶³$yä >o>•5`q RÍWØ×} k^Ttt[Ibȇˆ?|ªÔ"¨sˆwk‡*~K*ñ›àªëêjG»a×JiYj‹GØ–¶QÓÚµ…¶KK4‡CK꺑7I €ï•L‚LV›’° Né-æÝö"ˆMßâÜ©öš"XÝþ¸>“ãKØ®>[x_•øázi[ZC™ ðI#j³tAXt&l¢Zš%-Îâ™ÅДYåÏ&/·7I¼N˜¢ž„üÖ ºüid8£Q[~rºR3;7RÝJ·¢ÈJ(üyähV>s‘‹=€ÅĦ)‚vK›.*¯Ÿ$ÈÀÐñ{¸GtE8t1ºN]'1Yj[´âàѼòÉUø¬E~i‹j a‘-(Dk‡ê“40ÕbŒ&—ÁÑ Ý“ÀáÆï÷³páÂÔW欳ÎbÈ!W¹¿¼nد,€û(Œ½Ëù|(ÙýúåGi¡ Ä8Åã0åΠ@y9Ü4^Úœ}ûÃÐaù÷©©»§Iˆð”;á¸ã (œ{`üubv}ÅÕ…‰àXß'7½é³òG Úe¯C0—„~ý k£.yVh¢¶DóÙ¨-}¾[%½­óˆ¦¡Ï-èƒÆÂ§k„ãn>Òð>û¶È,1)e8ë|¸lxèó¹äÁ¡(;® -øÜ¶}lÌ,=.‘ü¿\zÏ7°`€d ±ug0š×óõþ`Ø·' Õ$ ÷êÑ™Eºz=|vqfr|Pc€c» A¦iÖ÷úapdgî–h•Î8®%•Å;jÖ¥Y±9ˆ+´è(û4?”ß úEΛ¡¬„Ÿ¥±´AÉ„ÙK]]b%,}8JÓÍ"Æ$×vÌ(™TôQIÆ—šoõFú÷,ÂçT(ÑK[´%íã’ŒMEl[Nv[íxôqÜ:ÍR4Ò‰„ÂöC-¹ãûÁÔtXŠüX‹üØ4ó;»-H‘)Œ=¬¤öI®¯}mx!ч>ŠS§"AZ‰ãR”ïmÃóïÝDV§›Ó‹ÝéMµES­Q[—%„]m‰šµ«:M˜1úÌè.]{pèða† Æï¿ÿžúÊ <˜Æ…ØLþ}ü7·FïŸ]ºä×½igvχCLµóùu¬Z%‚û!C¡OŸÂ4ƒ?.LÉcUÃïBŽŸÖÃ+ ïèYÀÌ2‘€Å‹`ÏNhs‚ Õ|-ÞHDبFDlß½€™e,O> ß~-šÁ1c °Q;ÿœ%ÌÒÓzÀБù%#ü žy…»™ÌGóíS]Ë Êiw²xƒ6$ÞõUÃWÀ/ëå†]ÒRR", âM_À¯_ÉùŠ.:7ü{}6Ê5²6 'eüð TV¦Q‘±T¼DO¬§e½y>X—¸bk W©KüÚó¶˜dgË%t.Ù§cVbJùÛP±=ýûd˼z?QæÊ±ŸÁ»$7L®¸Ck_Kß ƒ¸ývèUÏCÔï+áËùi¤Vc€>ÃÀ«rç †ªà÷÷¡Ü—…îôpÇDyˆÒîSþ%üúD¦£ ðš W_É3tj4·ñZ8¸*ª2g‚Idç3Ãõ7§çäÕƒ3 rq¯I>· ƒ»k ´¡NK3›„s |ý˜„Å:™CŽ°Ý½­àƒ ±Ad IÇ• ¹„úïûúÃ7¡Y,M’Éø“×ÐUÃ?›Ùxó3%†ņ8Åz‘! Úü‚“ÿ_r*K”R}·>&H0I”!A1 vhÅŒµW‚Ë‹ÕY…Ùá4˜…‹”˜H2’ˆÓŸ—·²…xà IDATg^ÕYØlA\†(.½cœº.]—Ãw°ó^†ÞåÅZr(…mN/EE_QÆ¡`­R}U˜\Ié„ÑØÝ•S¡¤ ›6mÊð mÞ¼9ýû÷ÿ»ºýå­ÑíÛáÙgᆠmÛ®Y±Þ}WR òÑêS-±g©Ü}Oar„ÚZxì1Ø¿.¼.½´0ùìÓ Cˆ.…´^A‚€£Q_gžvçxsü FÝÇð¹UTÀÔ›¤%zv<4ÿûÙ±¹Ì¡ïw|þ¶ðŠ¥ðþ¿UÿÑÞ0¨€9ÃW+aç.p6ƒ«n€Þç6l£0wZ:áÌ>påU ÎÕó%U£(nC¯†f ü}¢!X<]2Éâpâi0¤žÙ¨¢À·//š.$Å­ ïåõïóÉ8ذ$SØ^ 2\~eÝ}¶ÎŽ7«à4:VÚÏGeÍ”wL†¯æÎW#D©1cå{^¾Ã™ÉZ”V«ƒÆÇÃ…CÒZËðÔÜRŒ¬}¶ ["-˜OÎM¾¬Ù£º6ö§ŠbuCpS‰ ØáÍ­ÀÐÌ“ÈP%È8£éùã='a3&p©hЂ];T¡5kôGa0€KÇ©Ë|05#Là&ÁÖ=Ç1ûãá(Ö0¦"¿ Á"?fu>˜š#XCJ aÝ¡vÌ?Ò‹>¡"Á(],Vì:ž·MDg arz1;|XŠüX¾Ì¶«Š‹La¬¡D¦¹úoc-è{])3^ÄK´ªª*õ•0`Ý2´ÿûø ÂDž{N « ™‰%gi/Ì•bvë­…Í?ýTÄó—\ ƒç?_Q`Áøây’Ÿu~m¢¢HJƼ¹pιpyšÁX ž˜ß}šÁ=3ó#Õp¦M†}»%=>Ÿ_grŸ7_a‹cá¶;ò»ÛƒððˆíX¯óòn55ðôTðúÀÝn¼9œÕ¦àΫ%›pØ pÎù Ÿ Û³áw5 !n—pÚ†$0øä 5¥Þ$é"gõcú¨×ÆgÞÜÍDšRSvé°îß™y]®}‚Gà—w2Û‚U@Q3˜tg] Ì/“`óºa¸ÆRaožvNæ÷ Z»ß®#gHÙ¢J$¥uˆ®…Êë Ö—ÛO´ˆ9dŸ3Ï]â÷oÝx¨,–hÈû/’]Q8] mÍ Q³×êëaË h” ¶ëÏüiòɯ0v<ÄÐRÍý+ÎÎŒËù>¯ŽIí\¸ q܆8C>Ž#ª` ¦uƒV•¸ò¡Ò’—œÇSdˆàÒÇpëb¸tqÜÄpë„$SSÙˆ'?ÏÁì¨Â¨*SVëÒj c '4{èøn¶»Fk‡!‚ÃÅ©âÐEqꢘ6Þ{e*•7!£‚¹ø°A‡kq:|ØU!½ÃÀa b Ç jR8Ì5™DCY[¸äV;¯¼ü2~øaê+Ó¹sgºtéRG*1dÈ®½öÚ¿+Þ¬®û^Rç_{½05¸$‡SÚ›…<¹>$i&£P"¶ÿùg±^³Xáîpla»¿ˆÚõÉÊËWÐ~ü¼ -Ño‚®H½_®cOZ}!é~„g€? FI+,ŸfðEðñ 8¾³øhæ›ñ…BpßTØwPæ|cǨ6]ùÚ‹á@9´<®¾!¿Ïé–Ÿaît¹qF¬0~RÃóÑÚrxr4l\/¨¦Cw™sºè ìÞ ÑOÚ‡«¯…îõHzþ ~™. >#t: ú ¯f¹ê:¨Šešd×êaø0AÄÚ¢æýö~*ÉðÙ²‡Óþ!©ó®¬ÿÿl½ *«rÎߨ ‚ÁÃÀ ÆgmUýE°ZmY_2 7ƒø*ð?œÍiÛ¯Õà‹9`Ó¥‹`’ £¯­[+Ýpðdpê$ú(‰-92ŸA4Õ´D=q~0.,QŸWϸ6>8ÊHcP ¡^,ÊìA•“l‰`m¸5O›;á1péÕv¥>¦¶Fx!Ë|»­#^˜œ^Y¦d±RV[{<žzm[ >#s7ÄQT‹Ã•ePI2úº½r{µÄTVŽÑYÙéÅâôbuz ªEÐ^ä§ÈÀa`W¢ßT«i‹Öj£Õ`Œ¹Ð]9ŽíDUE£F¥­»wïÎ’%KhÞ¼9×]wÝßÕí/k–—ÃHÊx×µoÛ¶Á¿ÿ-î1…ºÎ,[kV‹Oe—.ùϯª”¶o/œ~\>¼°–èü—àËÏ% Ÿî-9çûçã°c´ï£FçŸ'nÙ/Í•ßgĨÂö˜=KÕ ¶‡ë Ð@9sZ?\q ´-`6ºf |ôŽ$Xtè# ÐÍæÏ‘H¦á£¤¸ç}š™v:9þ$>"Œc/|¹LÚ}öÆ0àJhÝÀ̲j̽¶ý™&|ÕVb³êCÑ[>…¿¥¤¹‘x–SOËzÇ*Øö]]RI“ãàö)uó|û××%È5ƒ‹‡Áqí3Ûé5_Àþµ¹ÝcªæmaÜMÒ±PâP5·þ°ÝjDÙ»ÓÐATýhÜcrqÊ;€¿]¦{Œ="íÎ:’Œ8x,Ôt"¶«m‡j×Úãaæ0‘ŒE~ŒjkÔd ¦‰2ªT¦yý÷·ô¢ÈÅnŒb7D±«mÑ"½´E×>?™½;Úapø0hЬÙáY†:{L9ÊØØ ¬¥®õœ¦%jò‚¡Sè.£¤™3gf|ÅHóæÍÿ®j)"ŒD`Ψ¨„;î(¬ÐTTÀuc`Ô(èÝ»°}v·27¡°kÞ_‹^—ØŒ™…q~øž}JÜ?F)LÔ¿t ¼û68<ððcù[ˆ‰<1~þþÑ[hõùüGžx>Y ¶b¸ÿáüˆ8‡S¥ô¸HôrùZ¼åGàÙû º\ÍáÞ¡Í1yú>øbtpÑ@reþ½íi#×zhóISîé«Þä0`ˆìÕÐßgÓgðǦ4R‰;%Ô·>Ø ïÀ[7§‘ßC‡C¯‹s£Aß~xû"8¬h$ j+uÒth–Õ=ø|vMš “$•Dpî@èyQæ÷ îƒu=áˆRGŽ@wÁ·Cû!± *gºÇhÃy+¨Cæ–}”Áû}4GVØnÈß=ž *—PWQôÚ×W×ÎvðÑcÐH"I’ “Zê=ïŽJ£â'Z—ÐÝä*‰ÉùM ìØ—)ŠÛÃmŒQ¬ã AÆ»_VÂoæ±h7š|¸QÜú} .F±J”YñÙ¥,ý©úƇ1¹j1ºj1¹jµi[—Æ0E!ËÞ2ŒGì¬yc}_Öî„ÓUƒÃÁi”ô‰è–øí§SÙüÉÅèÁPR‰ÑSÉSÉ]ƒÅU‹EýiOeœ^ñ5±XkÁV ÖAƒI¢ŒE%ÊZžcîW Û¶ýöÞ;JŠ2íûÿtΓ$#‚"‚¸"#I‚‚(’$+‚*`@Ä„¢ˆ T(º"TDA’*$§!ÏLOçî ¿?ºöýíîó¼ïá>ç>=b×Ôt8uÕ÷º¾a/+V¬H~e|ðAƶ¢ý× áÎBÊ0uª±"(I°`xl¶Âq&?O8§™%?ÏLTAV0b4[R¯N‡'áíÙ›íÜ Ï= лŸ1cñ5kàý·¡ZLxÂØëÙ¹>ûâ ÜÓ®¹.û1‹¾€•‹¡z=r¿1oÔ9oÁŽM‚ sGwc®@뿇µ?BµÆp×=Ùíôvo†'úÀ©RQØ:w†›²´^W/íÁ€†¶zô-ï×Yv}úd åLÐù6¸¾Š¯¥O@PM!¡úÍ SO(¨^IÛýMð«™h-hŽÝ¡cqc¿=!5SÊ´@ãË ËÝåíÚŽ¾)t••ù‰^ÛNäMZ,Zþ_Ë£Áô™bƒK ]wÈ-y-Dû‰mY™D™YáîÁàNèIˆíŽ¥,ªÕöšá¢%ꊥbÒÅóšlbÚÍðUk¨#¥aYÉ„;{¢6ú׫ÉIÂ9V)‰=ŠR FaVè ~¶Ô%ßÖP ŽÅ|ЇÄÚõ7òùºvXªˆMCƒ ºÃ‚(ãˆ&¥žIÑ©ö4þƒçFðxx¬qÜÖ8Öâ| Wôæè/WH8 ×9§KN)_‹ÖnµihÐé'5ŠNwXq$9ã†!ɨM“MØBLî…óšpøðaúôé“¡œ2e &#×á³ëßXÃa‘*qË-BËgdíÞ-’ê_~¥¼û~eèiÁa¥ö€†|Ð[·ˆ€ÞVWÂ(ƒòÛ¯If¨A_ÐHÞöî†V­a˜{³ÂB˜ú$¸lp÷=p…ÁDŽž†íB£æðÀ˜ìsËÃaîL!ê<®3 \ûüómQk5„IOd'âìþ¦‡¸ú ƒ«®© ª üºvììF-`|–ÈÍ+à•ap2¦<¸c\ÚªòçÇB°p<œº@_p™ÐØUvžÏÁ‘½©â©·÷¯\›>[?+?¯+h láʲ™ÿzŽnÍDkzža—Þ"j+}%ŠR™²$œb Ž}ªUù œ™šYÈÊZœÙkˆó\rXTˆýšb§Ïwô¿F _O¯&“ðê6je„óRÖ€`3 É•‰#J2Fƒb„úÓÅš4BNùˆê^¢2äÄ)äœì̱P`‹‘cKc•ÈAÁ­JwÚÜnnñU¬Uëã³ÆÉµHb>¨I< üðS'–¬»sA1¦œR̾€(VióA»7ˆÃÆ% ©„;§~lO4a#üûßiê C%fQð›eN  ùˆ9b˜rJ1啈"˜ëÏ@šöœR9¥8}¤4Ããã&žL¬p vøÅŒP'ÊØfÌWt…ŽýÀæ`óæÍlذ!ù•™9s&n#×Ô³ëß8#TUøøc!5ʘö-‘€çŸÎ1×_oìõ”¶¿þº1ÿQ€W ÂG×ÛiÞš ‰¸Ð Ö1ðzd¦O?wì"²­ýûáƒwÅß3rTv¿N€c…ðÚ4H Ònioà³Ù)ò 90üc¯gѧðó×Gܤt½-ûû¶øøk'äÕ…{µ³¿goLˆ3ÜØ.»4%…¥Z ¬·6ôµ²æOÊ$~\~të^ùóß¿ ¶­K¡©j K´f%ç)Ú ;¾+Ó²4AËëàö ´–?ß{¿Él‰–5/­ÊeÎ= ‡–TÜ-E"Üy·@ÞáÙpzrå2¥&¨ÝDÈ?j H›X>ª‚–èÚ9¸òB™$kr‚{%«…\D5‰þt÷˜pª=z 6loç&ÒüD•̶¨7²>ÊÏÁêðØxm ¼V)Ùu¥µDÕ°O·£Èæ¤ÀÄgIˆmNà³H¸hÏÒï»Bž_ 6 êD‹&™°¹ÃØ­1\1WÄÄM­ ¾6—YA2©Èª Ù¤"™T³‚b•P1TG ÕÁä ‰ßë `É)M1Q}¤vБd£†qF”djEE³T{l’SûÐì*Eaþüùrrrøç?ÿÉÒ¥K™7o^ÆWiòäÉ\qÅg+ܬ.Z“&'»ìÛ³Þ€ÇÏ.°N^h‹VeïÞpÛíÆZ¢‡Áˆ¡bÞ2mZöÖžªÂ§ŸÀì×½ÿ=ÙÏ“ 7” /†)S³#Õ’ÔJK`ÀЪ/ÌÉ_ f¾-Ñ “²ß œ8ÌҾá]GczÊ£â|5Âä©¢åV%‚< _~ Eaás½–õüéðÑëâ"ì©%qª’Úî…§îè¨S$D\{Sf._¹Ví:ض5u‘.h(¼[+s9:¸QÌ,u„C>té¯â{=ÿöòá¹ù `âSåo:Š6ÃÁ ©ß¯“Jl5¡[aTPö}ûå¶òý8k Aø9¯(§ t¹°Ì«(l·ó ûaT`¶@t”|˜Ùž-¯Ä(:BÍÒ¼D£©X#Så|K—ãm¡†DæE]oóiÿ½­:Œ5å4rŒ Õ$-|W‰J©‰ ¾Z,/pQ`â³ÇñÙøTO„A& %%ùÌ8t+«ƒ\[k\d´íß{¯??%¿jž€übLy%˜sýX´mMCmwOLÁ†Ã?ÝÀÚYÓ2‡dK ©&$½ šd‹Œl£8b(®ˆ(„¾æ¼,y%XsýØ´Ñõpy‚xî¸KShÐéOmÝcÔÒü&ètŠÝÉ„ ˜;wnòëÒ¶m[nºé&n2:ž:»þM…péR‘¦fç“uÍž-Œ¤oºÙØóƒ7^haì8cvm Iá{w˯”È© ¥{Hhoî$ìä²ÍÅ6n„Y¯ŠVÖðQpI sÎb3B8„´¹Q°e³õÿÿÚS&€l‚1Ïl-áOÀÇï‹"xKè?ÀÀMÊ!Xµìb&V¿Aöc¶m„_7BÐW\wfi‰?sžëüó`À}pnç‘â°e8”BƒÍ®„ÁÃËE‚ï__–¤‘§.Ü=.¨ä{)†­_À™X&¢ºðr¡LŸ÷ª*ìœÛç—'ÈTk,?›fÞxI¥px1œ –GjÅ&hv5<0N#í‡c}3õ~:JÓ“2j6®}¡&KIü ¥¿e¶5ý™Çª%°»/œìœJ•ðhhÐ,ƒ5´z¤5$Îþ£¬Ç¸;´x¥·¯-4XPÑ–Ä9Ol,ËóâuÄÄÖ ¡¤$Q ', áÎSXVt9Î89™&ך Çš tÏ…,šö1Gj‡\?äú1i;}†gÍ)EËïEÚ[—M¼†öâÌ-Á¥BÂ*‰"¨=ê?+Î(Š=Žâ£zB˜fÅGp¦Tή=à†UNÿ ˜ÿLª08«Ã#U®é Á§§ AÌ ·õ„«®«ØFMŽÁWÃaë²LDd¯÷+ß‚WâðÓýå`”ýtŵ¢U™q³p?ìþ´bs> žÊµ,¥Ç3dÒ \Âm;CÍÙ&±üÃ2­ÓJËŸG‰ÀoÏBnX8Âxbb;µü¿²úë`Í$a£æ—É ¦Ø¢~3Ìè ¤‰4†¨’"ÌäJp2hc ç<öxÌä;"¸íq¼¶8UÆ£Wt‚ÌÎãyï@g¬®„V,ãø¬q|–ÅÛ›±âõqÄÌj&Ô‹¡ŽÚÒä OîäôÊë)^u3ö‚"\9~¼™Çê Y%d[É"#Ydd«„l#;£b>è /ž(²i$$c÷E!t†qEÔ”iwZt¤ïR°^Ð:ß ./6l`óæÍɯ˓O>Ɉ#ÎV¯ÿz!ÿLd^g0Ïð—_à7ª>ÜØ1Ÿ-„åËà±' •VU lÔvï‚Ú ;9›)Ç矀Ë.Z¢- Þ@<ó¤HÊhq•ÐNfCƒ÷Ãû¯C4ƒFÂ߯©¥©*,Y ß*X¢ç7Þ­ÙŠç‘C0¶?(.á z•ÜÄeŸÀ§ïŠ‹v‹«aìÃU#Õ¢ãAž‰Ôo84Ëò¾}6¾ÿ,U@.mU˜ IDATqesñûá«…¢5ê.sŸÙ휗 \þwèd0çìý2²æÂ=CD:IUkÿŸðÓrˆZáš›¡ãmU?¿p¬ý*%(«:kñ—¡})DÔñ¸î–Êmîv.†ƒ»R?BÓ8tTÅùŒ–ÃÑ?SÏ-Õžs;¸öæò„ŸSßÁ±-WðÁã¡¡&µ‘ýpòñžVä'*¹³¶ÍÍšZ‚³2=DË ïýñÂÆõ  . ãŠ)@9Cî° þê 5Õ4BLš‹Œþó/üÔ4£¤`~šdbsÄË=¶FÄœ r1\ö8n{·IÂym;£°r÷u¬<~5¹ž`²%zfQwJv^Ä™ýÀoPl_ ¹­Þ f{“j¢š°6M¡Zd,ö8VWD AG§3Šj•„\Â*‰ö¨6Ô[¢Š;Œâ ¢zƒ¨¾fO‹.ÐΙ4ñ6ÇDÑÓÍÁµ­“ei¦äÖšAÇ`6óÁ0nܸä×åŠ+®`÷îÝô©âÚU½zuf̘q¶²ýG ¡‘‹rzá8~Þ{Ϙ^Ÿ'nØ(ô‰F[¢Ÿ}&Úœ³fCõêÆÝ‹/¶ä„I‚†ndþøøDQ¨GŽ‚ë Ø›…BðÚ+ÂWuÎ<0b‚»c;¼ûH* m¯Ï~Ì7_ÃAAM?)»ìààøú3H˜ŠÎ6UáRóÑl¨ÝÆNÊ>K”$˜Ð ¶ý..ØwÞ½³˜í‚I=Å:ï<òÔÉR8ÿøQ°ký@À"DýwÜYżò#øâù":·ôZ¹fðäŸðA/8I!¨ ºö†î̯~?i:F¥ùÍÐèrA9§ÌÌ2rÖvƒãáò™“`|ö¸S¼oÒ!8Ô=“ “Ž‹Mа%t¿GD”ÞÅ?gþîô°]íØâ¿Cì"ð…R2î¨0x¦¹Ä—ïC>b~XNÿ–† ûŒÕu¥L‰Ä9i${VÅs8ê3‘ãŠàvFñ8£x, þHf ­¹@$K´¨ 3rpnJŽQv.h;GØÏéókÿ(þµhQ6qË‹pòpf‘ ˜…ÙÀM]ÀUæó‘Ja÷G³DCV1‡¾T;OìÑ P>Õ¾XCÃW^+´‰/€è×à?R±Zòï³²ç(䋤ÎuÇRiðéÂþÂóà›gEЊ³‚â§o%+šƒÛ¬e *i QmçJZø˜spº"8Q\Ψ(†Šœ*‚0œl;Я#ŠW¶`Ûy‘…w"«&!d× “ê§aÚ®·« ŽœRbŠYA­-j2+`‘1[%LNQ®–¨‹ÐѺ¨öŠn­æˆ!;b:£ÈžŠ7( ¡Æ@5¥‘d¬9¥ØÝ!Ü’œQÝ¡IÆ•N” š°Öi·ß¾|Š‹‹Y°`AòëÒ§O¦OŸ~¶Zý_Q%I0%{õ2.‚ß·OÈ{ÜXûUQÄ9¶mƒeËÚ&ðøc ÂsÏW<Û)»ŠŠàÁÑPꇮÝa€dç@¦<{öÀïÓ =ŒÙ·÷‚» ä&þö<ó¸0ß~|*\x‘ó‚ŸW@T†ÛzCwî6›×÷ ÀU †1Öz]2Öhs»[nMµö*[±ü°H0KsσA÷CÝ,3ØŸÿ ŸÌH!•«ÛŠ›ÊÐà©ý°õ;(‘Ä1¹õ¡ÿhXÉ÷ äÌï‡ 3 G˶0¤‚8«àQØó ”Ä2aj6*ÎMüó8º«\±¡Ä­n€á÷¥¾%_@ññ¢+.Óz­w Ü1ÎÕnlB/CÑ r¢—OI§´WÈ´BhPÎT›bØs›ªÞx)&=p7æ(<Ý Ö6‰óç(™$™sd(P@ŠXoÌ&—ƒW1.g·3*rý¢ª ÇD@.Êeþ} ÅrÉÍ)Å5¿7ñ}ç'I+Š+"Š¡†Ìð2Š`ãµ°Ú˜1LŠ“j-Q“ Z!´Ù˜Ñ¤í1~ÙŠj‰"ÛÈö8REP—d$ÝjrJ±y¸”ž°[êÛD¸Éh…PoÚÉÃ|ëPh,næˆ$IäææÒ¥K|FBÂÏ®ÿãõïsjýì3hÖÌrÒ×ô—DaêÜÙØóO»C‡› |ÿ=,˜/ ·v6ÖÞ|õUá¥Yû\aømdíÜ‹Áõ7AWƒ„’¯¾:ÃzçÈû²“jâqxyšøÔn¾n0`­¤ª0e"ü´rkÂÐáPå¦ãäI˜9N‹ì¿[:d?ÏîÝðþ !MHØáÑDzKS^¾ø‡@:{ÀuYlÔ¢!ø|FŠ0â©)í•!b)oô‚ßµüè]äòµ¼ºòïAáoðçêÌyœ¯ ® X¼gþ„¿¾Ï”K ×ß « aÄÿ'ìYTqÛÒš/løj§Í-ÍÌŒXJGvq—Ð ¶L“ÙfV¯TÆfëÔB‚5÷âJ“K8"A¦,ŠŒØØ~ä(â9ºw¨î#ª·G•|y¥F†QÊx‰jÿæ‹ ÍàÖ<®G §3ŠÓÇ-)I‚Œ; Ÿ}/O^ˆÇÇu !œ¬ìˆ !»3šÚ®ª;\Ž(Óè—VxòJÀ–Àd RŒ=ŽÕæíäùQÎÅ;.F2©)á¼=.Z£zñu‡EÖÈ2hhД–dáTx´t w$­%ª‘e’VtšæÒÒühÓìNV¬XÁÆ“çÌ™3¹Ëh€ùÙõ?Œ÷í-Ñþý³ðSؼþñc®3Š"t†Í› qºÑÂ9e²(Ó^¬Úß2½pÎ{O´ç&L2Æ|=szvÚ­ç¦kU~·Æ÷"<mÚdG¶/¿Ë¿€¦—V]Ò×ï[`ÑÇ·w#sËÏ?„ï—ùÃÈ1Ukùt4<çYØNxø1¸$‹]ÛÑ}°V3¤¾ % º¯|ª{Ùµk“`ãú¤Ã‡T-Ù¿þܨ18-Ðâè3´òÙ¨ªÀ»=2‘ZÐ £Fsõ²møÓ¿ÃÂÛ2å%&¸êFè5¸bmâŠkáhqùÀÝ" &4ƒf3H'àÐ ()Ê$ÈèÛo«Ú mâ9ÚM¡$”+/ÇH'¼”˜ ô½ŠÈëñ†…{Œ¾­~Ê…ímðÍ› ¼ñ{ ŒŸ¨öxÒôןÕÒýDµÐÝ| ÜtV›áÒ²øÜ®ng"áÜ_|5œ£'“ã àsEq„ÜD¶d›2½ •#Éäúq›Tܲ«/@\5bÆbRÁ¤b5+˜ÍŠ@‹V ‹–ït… ž9GüN[ÕC¶ÇIØH:ô„ÄcN)ä• ä•@ÒQÆÓÃ"µµÚì ‚' ¡K÷õƒ#§!¦žBÍúÒ©S§$¼ð Ïúˆþ_UNácä pø0|ø ]dì˜U+aÅ·0ïƒò™o•­wçÊÔg³;š€ÈYœñ² üÜÜ^H3Œ È9o‰˜¡4–,0ãE%1ßéÛ/ûyއï¬/ÑfͳŸãä xä~ˆªÐ²µ1cñàÙ‰ [E²ýE¸yø/á³»ú¸!Z2þÚ ös{3‹wëwðì=)¹D‹«`ð°ª=HLJ!)[>ôèõ«ø|ÖÏIE8éûüÂW¶"×™µO@iB«&tëS±-Ü 8X1JkØ N±xƒ?À©eÏuâNû©Ö«´ ÂkD o2”˜òâù:MØ7 g\¾1±á æˆ~8x-œn 5¥Lô—.›°‡aÙ•p¨¶h‰¦dt!}¾"$oFëpÌ ^m6ètFqYbަ!Á3‡ræL=¡'tÄp+&{#kþžr:LoêhФî¾ó©sæÔ\?&$#z` ªIEµÈ˜4¤hsEpº"ïmDB1£Z%°%Pm ÑÕ=E]‘¤~PõQ4ä©K&ìÖî´Ö®G‹‰rERr WX´E!pƒùÆÞpñ•â22gN²Ô©S‡—_~¹Ü×hòäÉg[¥ÿ+ aíÚÿÚóW¬€.]À(ä?z^) †Qw›Ÿ†·ß‚[Ú›½õû@ OM1Ö~ýî[‘`qÙBÏhÄÙåµWE²{NLž’©ÆbððX8¸W´ÎÎÄ”$øtü¾ªŸ OÌnn Á‹E¾¡+ÜvGö×_R3ÇC0îê0z\öx®ußÀüY±ˆ”ŒŽ]«&=%b°~9,uÉ=Rù$“§Š ¸½LÈ®>üµ6|t˜ÿ•õÕÃvs%X¨Î'–®°(‚®.[ w\M¢ÒPa]~ù `#/××Å%[ h ætzQJk‰ª:ìÒ¤ &_—jÂ’ëG²ÇA1c5©ÈZ!Ĭ`Ò ¡Y+„.g”½‡ëWM‚IªB«$fƒZ”]1#ÔerJ1åø±Ù#x£*>Müï rŒ'¬‰èË0F]!3Ö7Aûþ`µ3cÆ ž}öÙä×¥GL:µÂ¯ªË7âìú(„FŠL²U÷»˜A=ú¨ñc,­Ñ{ï5v®3g„ÿ¨¿&N2¦åûóOxqš wŒ —°Q‹ÅàÕW ž͈ڶ?`îÛB ?d\e ©þó…°ú[‘_÷Ð#ÆØµ;·ÃSA¦oh×.K‚¼ _|K¿€ DµzíQ4 /<û ä5¸±|ÆI} ð T»@˜wgË3<¸>zY…°U È«H39±æŽO‚z‹–hµJ9¢¥ðñ`Øúc =…mpWߊϓÁŽ t§´R34¹îX1»öà°kiùUtê oM}>%_Bqa Ñ•mu^ptéyZË:²ÂG+”<¤·Ec×]ÂÞþ›ð”jEP ÛµVD)}ÝœX«‡ðÄÓBvÓ‰2Ú¬kÜpP]Â)¦@#ÄèEñ ÚÐ/Þ{n;¬‘S"¸oT §â½°ì³P'9¾^g¯3†¼£¡ Èè„•´Â¤KT_ Ù"u™®þázâ¹~Á UM˜LjšÍ [¬{‡+‚òôç"Y%LÚV¬Ræ9Qq>­êŒQ»3‚7¦ˆ¶nXkïêEPg‹–ÑÚÝuK´Þ;vŒåË—‹Å’_—ùóçcËfêvýÛÖ7ÖØï!½#G?æÈAv9Ò¸Ø~ÉW°l™h^}uöç"úéØQ4X´lH>þ¾ýúÜ#Rг-Yd—ÝA½†pßýÙ™¯»wÃ왂(Óo°Q˶T^š IqÆŽËþzŠNÃ[/@( =ûÂ¥^Ϫ•ðÕ|¡3<¿™±˜©^‚¢Rá s[/¸ä²ì¯å½'R„‘WÍøäIá¡U X Äí¢*lÔ‚§`ýg™.,9uD4UEÎ;+GÖâïÑ‹šìƒ[ïóÛ²+î‡-Ó3 ,úqÖs`âãih]…Â7+&ÈèÈ®½ÅyÌfñüÒ73Û¡E9åÕãÀ˜ ΨˆLrjHБnªvží7ÆCødÑ6µ…2dl2œw¥èA»e2®L 5ÄâŠ áºæçé4§é£pd×¥Ä#¹¸5M¡Þ üÚJÄéùºÏ§3*a™Ö¨I£i*žØã˜Ó¶ÅÇîŒbsİ;£Ø5éFðt5NŸ¬! æ&#éÛMÚªiÌQÕÀjàŽ+³Vfîk­P(£G/ÅíXZßÍZ&ú÷ïÏ·ß~«a O>ù$V«õluú²êFÜ7ßl<’©¸î»@§NÆÐà¡C0z4\y%<ü°±ó,]ï¾ã†WfÓØýö›Hªo{#Ü?ʘÀ²%BpïôÂK¯³…{mlÝ-.ÌR#m‘צÃ×KÀ•SŸÏÞâUUxtŒÐþ­ Œ›Ýç4P ³žÞ—¶|˜ðdvÍà©Bøq¹˜c]ßߟ=ÊjÆ0øî+qN¸áÑÉU{·Ú[Ò.èfhÛzö¯ÚvV—L4u iJE„Ÿ3;aתLòJÀí{B§îG?}Ûöÿ^><7á… OAÃóµ–hö‚ciÈT'¯œBN¸æVÁ|Õg£¥3áÌŠ ]ò¸¨›ÈЄ/àÒƒmµ\?KÙsALµpìŸxž=˜JL×ÓÓAáY¾±xM)RL5-lWÿ9?ï×åÎÅîŽàô„pzB¸Q¼ %‰ v¬íÀƵ=ðº"x]|Î(>WK©„lN# *z‹R+Hª/t“éúa_Lö8ª^1±Q¬NQŒíšnÐåãtÄ🮆dVDì’UŽ’3*¶+‚¬µD ZÜA¼ ™œä„ÁÖz‚Úcˆ¤¿h’,²`kz=ôxn¶lÙÂúõë“_•Áƒ3yòdLÿJ—-ËÚ´iSFzE¥÷ƒÁ ÿøÇ?ÎÂÿè:zT /£3>EAÀÁ qË/Š‹øÈûÀˆ9í™3ðÌ3¢zÏÀìf½¼ú² –Œ ç—ý˜½{áéÉ "æUFìÚ6l€wßO<2 j(œ{þ‚Ï>„ˆo‡›n1p#°Ö|yµ`ÄèìÂy7ÛÖ äÕîV1‹­jÅcðøøq¥˜%ö˜]Ʊ÷7øuMJ.Ñæ&a¢PÕúú-(Ôtw¹u¡×@¨QÅû¶õŸâùéHêšvpk×JZûBá¾L´Vëè|gÊÞ,££± N¨@.a‚Ö7gÚµÅÁѹ™þ©É “hñÞÖ'e×&ŸÿÂÔßRqê(ïòk9u§Œ*ˆPÛ¶0ŠîK›äs´C ¯”æ!Êôµ…áážðK“L?Ѳ;¶ò‰\]H%ÒРKÎkÒ«{&Ýe#Îe„Y °zµHÊèÓߘ][,&\j¶oƒæ—‰â™mÎwò$<ý$ØÌpg¸Ö Ú”‰­Ö½›ˆsô¼ó ””€„f0ÛÝèÆu°ð Q ÜÕáɧ³Ÿçðøi…h‰7µ¯º]«ª°ùGØ®Y…Õ¹{ªj¤ºj|ýñü„[„_ù÷Ê_O,¿|Ç‹ÓãSrµeëÔë9Öά-?LOšHx){!E9ÿÀYšfbsIùÙ`ÐmæÇ'JÈSÅslia»¶4íÛI'üz!ÔNÎ'I2Ú|Ð…Îþ¬sØq»Kqh³A·9.ægQ°úݬ\<d;^_¯+‚ÇÁãŒâuF)ÖL®“h°L‹Ro‰ª¾fw¼°»Y&î `UM˜Dó3`¶ÈX,2«„É–ÀnãvF‰øs‘€„YIþ?ìqTGLH(ÊØªYµ"è‰)ø$ðEÄöjDoÚl0}FèŠÚ°tìWvD±Ø˜ýÆ,Z´(ÕÑÿäÚ¶mûo¿üúý~Ìf3Ñh” …(((àÒK/Åb±°k×.vïÞ×ëE–eqß³aÃŠŠŠhÒ¤ Mš4áäÉ“rÉ%—pàÀdY¦I6'¬³ˆ0míÜ)ÈF ha³ÏÃ7 ¤a¤MPT/…Añ@¿ÁÙ_ÏŒp: lÔ.m½T,{Ð×çÀй)4Tj‚ÃDžaEß¹ß>†"yÇ™.wVüùm‡M¯g¢3ý¸¾CD>£~ÿ 8³'…LÓ[œ \~´ïžÊ3 ¯„ð®ÊmÔt ä€jõ.–H)ΈðuEÓrÓ gÈÆ¦­(çIxâ)$hK/‚Iæén™¶iùJ&I&W‚u¥ùüe±áp‡“EÐáˆf°DO츔]¿Ý€Ë!Š’GO§× ¸íîpÊÞ¬¬tBŸzƒ˜åyl±X:t(¯¾ú*'OžÌø½óÎ;Ô1Âz7¸Z´hÁ€8vì………Ò¨Q#†ÊüÁƉÇãÌ›7±cÇR§NŽ?Ά ¸ûî»iÛ¶-ãÇçšk®á†n8[ÿ¥eThBl?k–H°02{Q0?ü@$Xôéc Ù> 'ˆÜÆgɘõº°Q<${ñŒÇáùgá—P÷¥¥ÂèúšÎ½{áÙG öfS¦feÚ· Lµ» y†Ù¬_Ìh88ªÃOWm¢pl/lüüª@ƒ½ûA»ÎU£Áwú|4€ IDAT©Hªxj‹ÖkE7^þCði_8U’BO17Ü~'ÜСâïÁO÷ÁŽïÊG9kÂ#O¦2E_ÃÞwR™´ \ä\èÔ nL“W„~€c¯—O¡ÐÛ¨gÉGbÒ " >À^,áÔ.ÊÎXʺÔwqìî8 â‰&›FŒÑÉ2Ž h®¿Ì8'QÆ=FÛ91x¥´¯ZkáqûqzB8Äk͉hD½-ª“c4²Œ;l-Ñëz€ÍÎôçŸçí·ßN~ücÇŽå…^ø_†M&ùùù8Nìv;², ÉËËÃb±PPP€Íf#'¿uöjýúõ1™LT¯^X,Æyç÷ÿ”¼ãG÷ÝwÅE좄 Ú[oBi&ëëå颽ٵ›±Â ".Êæ­W#òÏ?aÞ\PM0ð^áÅšm}ú©`‰Öo÷6Ö>¸Þ$ wÿì¶pª ß, k¡ ô¹YÞ·hÞÁAÔ.7`?7÷«'ˆ8Ù tÑ Xú±@‚Q+ŒZµ4%P/öƒ?´˜¢zMá®UÛµýµ¶ÿ’jCÆlÐçnÑ­ðý] ;JÉ%f¡å»½OÅÅöÔ¯°ïÇL”¦?öêQ~Þ»wF&Y'­]|¹`‰zÒ^ÏéWÊûˆ–•YtêFø'ñÈZQ°GÁ-ΊZ©J“fìëø Õd°†3½DÓÉ2Ïw„o®‚ZRÅ~¢92Xƒð’ZWdûéhÐ!„ó:9æøŸ- ×ÑKIÆíŒ&=Z;TÑQYT5Dˆ3ŠÝǥȸ'B¯hŽ1hn2V“ŠE+‚«„ÝÇacwÄp9"Ø,ql&»= ÖŠ5ŽjI`¶Ä±˜âذ©.EÂ%+¸*nUŃZN6á §¹Êh"z[Í&pý]WƒÃ‡³páÂŒÿÑESýo^ 4`ñâÅ”––²fÍü~?n·›Ë.»ŒvíÚqË-·púôil6gΜañâÅ 2„Õ«WÓ¦Mg á¿° …ëÌË/>zV®‚'Ÿ„¦Zˆª*Üc–/ƒy;,à ωÝ'§c¾Æã0áa8tZµ†qã²·‡ÿ f½*Î7ü~¸æÚìç))†÷BIZµ‡Æf/Òû÷Á#@,“ÆÃ•­³¿g ?yï@D1F#ï3ðy„•Ë@v‹d‰¦lávl†MÅ…¾Õu⢪–èÞ­°u¸ Û«Ã€QU'rOÃKàh Ulê6…ûÇTܹˆ`áð̹åè;š]Zñ{uà{8¼»¼ßg½f‚X”~ží}àðwåýD‹w¸k4û[êfíÈ@8±¬‚0ß4DØðR”ñ#9%uÀ®±a¡4•”AƒÅ&"çVgýã{“{hЄÓvØÔ$Ó9&I”ÑÝa¸?zQW·;ŒÃÂá ãVx£"ø7^X›¯ç?‚Û&ãÉõ§2®ˆ&¢;¡û‰ê³:]ÔîÐÖnŽãR%ܪ„[‘PžKÄW“- X´¶¨E#ÊØ­{‡#Fñéj¬ûþ–8V³‚ÝÅd‹ Z¢`Ža6‹BhWØ §,áNH¸UŸ¢àS„“Œ7œ¹ÓS'œÎš˜oM„'n§NضmÌž=›<£7ïÿ‡«zõêX­Vrrr¨U«&“‰Úµk““““$¾ 4ˆV­ZѼysÌf3“&MbÚ´i¼õÖ[4jÔˆ#F°{÷n.¾øbzöì‰×ëeõêÕg ád:ýúÁëkõj2ĸáwÑxu†0îÎf ­¯õëà½÷ Í5з1‰Å¼y°zäæÃSOÓÿM{vm‡k®‡>ýŒ‰ú?ûþØ"’êÇÏÎÊUê •m¡Wßìç‰D`ö bNæ®÷†úYÚÖwÃØ>pä$´í={gG·¾IýòŠX`ì£Ùç–³$œR C{èØ­j"ÎÏÂÉ@ E©>¡¬Œ1¼å#a ª :t‚ëÛWlצÄáûGÊG YÏÆg²kK7ÁÉMîÆÝ"c°ÍM`Ö>ŸÈn:Ìt˜î%ªø ß`‚ 7` •b€="„ó–t;8}Çœ¸ÃI°ùIÎÑ2Ö` ¦Ðàüöȃs)ë´t¢Œ/=l4» t‹Äw§%!2µýǯ×c3“L¤O&Ók?{5Â̪Í-…¿gš«ŒâŒ¢:¢Ø-q\$p« Qe™#s¢nÓ]øœQlö8&ՄŬ`¶ÈÂMÆ*‰Bèˆa·Ç±[Xâ&,–8Vdl¶(fk Õs ‹)Ž…D1t)2ž„‚[Uð( Is‘‰¦Ú½I{µ0¸â6¬­n‚k{€ÙÂÒ¥K9tèPòãoß¾=wÞyçü²Ú£GäÏú\oذaÉ6lXÆT«ViÓ¦eü[zÑ»í¶Ûøiýï*„ bѵe‹¸ˆ?õTv¶c²õ¸$ú,œÌzC Ϲó2#r*[¿mBx§ ú€k®Éޏ¾ú –,§[8ñ9ým+¼0B1èuov†­¢Àÿ€%ŸCÍú0æáì²I‚ÉÃþ¢%zGÏìšA€?~¡Ã¾º0pxv»6)ß/Öka3t» ®Ï2Œ_< öíIiŒ¨ú<±0|7/ÕV š¡K÷ÊíÚaX77ÍAÆ$P]Ï"i¤ÜkˆÀÊÊ·fèк¥IzTN¯‚S»+0Õ6Aýæ"g0y‚?BÑŽòœtDëPûõ$¢tIjþZš¼©,sµBMkq Û rUñkP´OíÚ£Þý«:¬¼¼¦¨ösžfʽ!æaW®…WPÓ Fð$4ç•ØNöþqÐ êĘ´¶¨Gûw3ʦß[ ä”feTG›%Ž“.UˆP‘pË VO§7ˆêˆ-Ù¤bÖ-Õ,26«$ˆ2Ž6{TpXâ˜Í ¬fv[ÅCµÆ0™ãXˆcU8T ‡"æƒn<(xdo\-W“D™Øk6…ö¡F=âñ8 .¤´´†ÚO?ý4g×ÙBX~‰IJŸ .[ #FwªÙ¹CÌ_z ê×7vÌòebn7zLö‚¦£§3„>ïÃù‚òŸ îÝ Ï?#.Ž#FÃUñ´©Â®qs˜ôXöó=ïÌ„@†nÌŽÒV~ß| 1 nc˜øXvÂωã0º7D-0|8Üh@ÔÿÝ"øX³ kÔBÜ TÕâ-> ë–Ãé0È^¸{\Ѻê×óÕ‹°mKªœ©ðn­èû)†O‡ÁŽ ©Bcʇ»CËJüa6ÌÉlUyçÁ¸G2c™¢‡á·G*Ö ¢§ùe©×“8 ûÇ”/|é?»ë LE‰ó>”’M©tˆPš©vQÚ£©€=káÈß'*£Þµ2½E״ɵZK4½=*‹BðeèF{ëãq5ÉD7R²%êÀúïî&É£ÀLµCuÝ ö³W#˘ó‹QQ‘Ÿ†¦¸µbè–e”f¹$¢Ÿc Ò‹=Öå)¢¸²-‡®_…WÈÏϵ†Ò3JüüAˆÉ•3còÈ‘À€™æš"àVs‘qÚâ¸c‚ ã‰ÿèy9xI*‘^C®´Ÿ=:qÆÔëG1©(fÕÃjMàDÂ…„ §*áReÜŠŒÛ$ãu…qzBÄ1L³I)Z[T—MØœQŽŠIÁaUTl³U Bt”ˆ„NUÂ)˸e·IÆ­·Eã”#˸#àJذ\r´¹ìNTEaÆŒmÅÆ— ÜÕg†g×ÙBhl> ëÖ‰ ^£ŒÏ/þ [·Â¢/ Qÿ‘#0ç=0â pâ<ú°˜qŽyÐØŒoß>xuº˜;N}.{صÞ1I0>;p·ùþ;ø|¸|ðУÆìÚæ¼ WAÜ]»@¯»³»Á|8æ¾&L«Ç= ²h-eï+wKv`ÈЪÑà¡âï*…EoÁ…B¿~æ#ÄHžœ»wÁ-OÁñÙTï¿ ‰¸Ø;ÿ|óûh<ólØ š‹ 3éÞ=ðèýPêÒ‚‹úš?®~€—æB\™Û§› KŽÁ{¯A —_gžmþ¥ã§µBgŠÁd n=/Ý Gƒ¨®§w«ùu[³žœ˜"¥6‚ñ×W?âýñ]1ÞMvƒq¯puéTƒ]Ûòi•÷î Žl­,‘H1/Ü6ƒx½o‘J¢„@1ü@åŠ$œ æ!xiÂ'|Eަ—§-(“Óÿ^þl”ê“)É}B_í|äôápEq%»A9&ü6£©¸§X\Kùˆ¦ï & 3ÉýAg”N%ªhÄí1dIÃ-ÅpSáÐã¢Lh|·¾-e »7(œd ÉB›¢a³ÇÄáPqº"ü¸³)ޏl" »]E±EÐmQdIE‘Uì’ŠƒnMí#ØDoBbú £Þ0¸¥¤žÃ m7Pl,^¼˜+V”¿õ÷ÜscÇŽÀgÕn2[ÿë%ÿ¥mÒˆ»cG뀦ªB8â‰Bpo<˜:Eèo½ÍZ¹~½ Õ\x‘ EX©`Ù4qRõ¡±ûP?Âün˜lÎ|ÕuxçMX» 6vmfãä’xêŸbNsˆ4 +î6³ïÚÄZaJ…=±*»î<ùü¾4\s]Íösz>^ ,´:UX¢Õ”R ÁŠEb/±Ì!ŽW½4%†ïÞVmIÛµ–§Š‹êä/«„½»2-Îü2Œ+lÔ2Þóá×—*î–JÐáL¸h`¦2´ Ž|SµM[ ÂFmèÕЩZìmä`%˜5©¢Ì¯@»®ϯ”³ ‡Á&µ„íš=:” ln%u  ni ˜çüu²ÎçÀŒWr…3lÔ¼˜z؃ÏÁããIó­Èõ¹"¬ÜÚŠ¨-Žd‹á’E7è–bå€èÑãB?he›JžKØ®aتáP±9Ô”µš½ät‡Ù¼¯>N\Š ß8ìö.9ŠKRqIQܨ‚•jtž¸†OÕñFø"zyþ 7é3Q°·ì*F¢¾6nÜÈý÷ߟ1ú¼Üjy¶²aµuô¨0ã5ÊÚz]‡åËáûÂÛŠÃM,³fÁ‘£0ë~hÓÆü¿n» ÉÃŒL")ãÞ™ðýxô e8'Œ…`ιHä&šô¯¿ÀíSÅèuÊ­Ðáóû¼¾P$Xh:œs¡µ×{ãX¾lypãmи©ù9Ÿ.‚ï‹nðŒ^bTY“f0P 3¯ b+,Ѧ&£äï>„Ï¥@¤UGgUÕ}tÞž _/LŽ­ÆÜ­ÚTÝ –í-Ëᨚ P­; sõŠR›UƒàH rà®· ºZVø{ûudeðK'Ì´î×OF×?E¾Žâ] =X!u¾(‘ °9 ÅŸMGPk%Š(S~ €ùÃ Žš&—H ßõ„ÅuÇw\9¹“a»aÓˆ2ïý2ˆ†iR‰äx4];˜<ìy¥hJÈ;K`r4ªÇñêq<‰^I¡Ó"â 3*Rè½A›-žêŽ0¡Käè1lŠŠbÓq:"èö’EV¢ØŒnÐ¥ÅÅýµ8¾DBz‚œhjä›oHÂY· œ7Š1ý°aÃØ·oMš4á•W^ù—Ú¥e뿵#Ô4èÑÃz@oi)<<[h›6µvΚoáµ…¢ë<ØZ9w.ü²Æ·–eBhÿÎ"èÚ]ì½Y©?Éóõ k83`ÇEf¢tï)ŒÅͪ¬ æ<$À[cÆWíU¬#‡aΰw?t9 .¶ÐoÝ sg Han–ÏøâÝ‚„ºŸ}.­8cQxãÁÔHÔ–·Í¨¡#Öá³§2 ,]Ï…³Ï­~\»hlþ"ÓÝÅU®»¡r¨ïo³¡4R™ óˆçszÇ™=AÀ_ÙE&yžžW]ëƒzRdc,ª©lÄv@÷ Ø{Æ*òt]tƒãH#Ê8‚âÿ½ÞOaò´Ô‘t‘ɉë>íÎ'èÖpã´¥d¼Ñ´Ñhr-C.ávEp'÷ëÒH2^g[Žì*4\RLd=Ž+7äÂUÆ-ÅÁ&ꊋ4#‚ÉfÉ&‡+‚Ë1¤19.Æ 6áRã4—¬âNÄqé1Ü 1õÄxâ ¼F·›yoÐþ,d^zé%vïÞ]þVžtÒIœyæ™YÄÉv„ÿ‚ªWÏZ˜m²žxB|ˆnͪÌî×c[sY¹ž'ÄöcÇ[K½(>—ôÙ³±&ÿøf5\Ð@Nçž[ósÒ4˜;¿އ;î2·7óûaü8´KØ¢Mž$ö-Íê…ðɨݦÍ0'┕ÂswÃïÛ ê‰§›¸ÛìÝ«—‹õÂfBœnö|îêß'@ â€ÑãáìÕ¯òbR%@‰,º­ñSª·kÛ¿~Y“Ùu•J0x\Ú?³[ïƒË 4žI9ß®š©MTÀá XM]Ò 2ǀˮ]´¾ÊÖ#•RfŒD‹¤˜£ië[ŸÎÁ!Gë>C­¨Žn€jò<{™ ¾ØÊà€~k…qqÅÓˆ2q±îp@áóz.l®˜±ÏÆOdd|¡TLQ]_šl")—H’e’DG^)²#Š/aÇ#ÇIFRñJ*â†|"Ž7'¡ºQNÈ ñ„H8£B?¨h(öX9cÔéŒâtF ÅìDk ÃŽJ”²-‚¢Dpè*.]ÅiŒF½1 _Bçk‚(ÖSþ¢¶vç@ï+¡ _}õ£GF×uÑmÈrFÜR¶²@øï«5kàí·á™g¬‰ÓAt‚_ wÞim$ªª‚ SVw̰®g|ù%‘`qý ÖØ¨ ˜¥1Úœ,‚ŠÍ€ýð!±¤ª"—¯ã©æ÷Xñ|ó9¨@›0êjóûìÞ÷O‡°ƒ¯„S;›ßgÕç5uÞÑ(,|~þ¤±÷ff×¶é øã·TÈmÓ¶pÍØªä¶~ Û·¤º/r`Àp8¡ØÏfB©–Ù­Õn7O«,MÙ÷ìüº²ì<‘”Ñ¢uæk]¼ö~VYŽ‘<ï¸VpíDqNèNùƒL#Ȥwƒ®:hô&ÐâòÑQ ûAOe©ŽP.ƒ•} ¬Ô¦É&ŒÃà¹NvðEm;u k·ÃÈ$ÈxŸ«Â­q¹£²‰ ¢LR>ኰåpm6ùsíQ< 7.[zG]šÇmüÜîoÎÁHCN®»‹ +‚n¥²“@èPqñK›~;¿´â"{Y‹aCFV¢ D‘¡tèq\ÄpÃ×ð e< _TÏL8ó!uí/2@yóæ•ƒ ÍàäÉ“3þ\.׿Åh;[ÿÍ@xèˆcê×N;ÍÚ96Àüðò|¡5´2]¼Xˆú'O®Ù:½¾ýF°>[Ÿ¯7Ák<=V®€Ó»Ã]÷˜wªª ·Mƒß…¶§À”[Ì;ÕýûáÁ{ ä(ä‰s³ýŒ`š.€êŒsàªÑºábxtšqÚòà¦[Ì%#߯€w_™NÝ`àК™¥qUصíØ#ÀCu á|³j¤Z 6}&ÆÕI™žBŸþÕï÷nz~ü,sßNuÔéШ‚YƒZ ßÜœ³t¢K÷sáüK3 ?Z6ßPy´™ÜÔr`¢A`ŠÍÿ*0öú2X¢É2ê†^}P/j‹l¿Oô2q¾?Ýà®"ø²ÈÌ7Ž£3Ì‹‰ôŠD1L<5—[<¥ý‹'R,ÊHæ±5Ö;so0I–)ÿéŠàµGÙy°€?U²#Š[6öåItCKèI9ƒS‰’ãâËñrED“¢!ÛâÈö6[¼|,êtF±ùxœA|ö82qœ$lQ°EPä(vÃVÍI W"Ž7®á•4|‰8¾˜`‹æDD—ëQò;] .Åξ}ûxÿý÷°ÛíLš4‰»ï¾»|¯°|OJ–³è“ÂÿåúüsãÇ[c|–”£ï3»‹'+µw¯ðíÜÆŒ³æ?ªi0ûA8xæ>c-¨ø×_àùg¡m{qN# Ž8KÞ‡O–BA-¸åvsÿQ€9æõ"ÁbÀL;°*·ÓtXºÞrêÀÄÉæ½±¸X¤pTE)ξú ¨x_8@(U$á” ÛÂeWq¨hy ÑjJe‚ùi 0”J`]?P\­Ìu…R#èÑ©£¨xª ¯TÀhê÷ü„ŽT$ã­@œñ¹"8q‘v_g Ç`‹ª¸Qqûƒ)Q!pÊ*9ž9¹eu‡Ñ ¡’BÃV-ÙÚ}|Î >»FL‡” a #Ù„›ŒUdã‰ñ«WŠãëä¨iŒÑ0ØO<Î ùuزe Æ #‰Ð¨Q#~øa€¿9õßµþž_KöïA½V%Ÿ~*´vVÝc~úI褪7l®Xï¿ Ë–Âeƒ+Ó꫉þ¶ý7NV'˜w;vÀ“‰Xª~— w³J$à«Ark Ɉóµ´ž¸‚aè;Îêa>Fýö+Xö*5hÜ &ÝXóz]‡7ž€CÇ (Á… ³‰ýœ‡ç¦‹d1®{mõ¯[Bƒ7¦§, \2N©!bê­ëá›·2G–îº0nBePÓ5øéÙª 2}‡T¶kÓ5ØñlÕN¥€ê‚iÓÅ—(픾[îP#¨ žq/ôBi‡ŸpÉ⎠ü”)¢LRj!û!€o/4H2ñY&__LŒM)…»Nt‰nÐÃcSq«:žˆƒ–e 0t«£'RúÁ$ôQÆ%«H{DGqEðjzŠ(#UÖºBGè"Nž#ŠÇ@7’é“éô6#™Þng§š 7®áV¢8‡-ŠÃÅix˜ ù„j°E5Üš†'nnGÁ]¡+·!œÞŽïˆ.É|ûí·üøãåoå½÷Þ›E˜,þ¬›n¾¥VºÁÝ»aÆpã в¥µëûýðæ"ËðÒþÖÎÙú›È3ìØI¤DX±Qûü3xc¡ û÷´h 7w¬ûFhožfM2òÊ‹°ópäÀ¬ÍG¢3n­¿  ™6Ýüù„B0ëv8p$/LšZ³fàÇ ðÚóPƒSÎ&áfZ˧&Ã'ï Ú`ò48£†/¯Oƒ/ÞHiúNêW«~/ñàϰuEæø1h‡©Ó«Îgünü•0¶ IDATü±.“ sè|. ¸"“ˆ/ƒWß++“cŽa·pëighGö+H©4ÍA&¹>à€ÓÎ'Ñ· ç—ä&È¥¢ë“K„¼ÂV–:8 &äɇơ0NêúÛseòlq|Uøo†Szº¤ uŽñûòÂB~¬åÁ»é’‰4WŸ#‚-”@*IUÁ$GMà‘…›Œc4*%]eâø4¡%<$åR Ùç'‘:£ÈItEŒLÄލ†»X¦v4SR±+QŽN{·Å- @öè1¼Z¯&~úÔ¾hBòFt¼J>r§~Ðùbp¸Yºt)cƤ¾H·k×.ËÍá_¨Þ}zõ²Ö9%ëãaÓ&¨]R#<ù$üü‹Î[!ÈìÚwÞ-ZÂÕ×XÎõë„-ZáÐÒ¤©ù9Ûÿ€çæBYz_`ÍEç£à³¥àʃn6O–±/úów"ÁâŒ^0p€IR†Oß»·‹½Ä!# ®I‡¿s³°^Kzxžr ®Áëtßo°áÓTŒ“îƒQ×BƒÆÏß½»vdvƒÏ„ƒªøÂô'üú~а“ìêr@¿!p\à '»áÕ‡í¶íC¯_ðÂoÿ`ªóõW¡–y ßÄë•¡ë‹qDÈØKTüFGÞ®†°¯µÑÆDG˜”M¸£©Ç±²–ÄŸµu|¶8^[\ø‰¦wƒIIAR6QÈOHxÓ|EÓ;A¯3Š]ÓÊ T¦0_ª…æ á‰'*H'’ò ­\6¡è:{š'ÅQìÂdG¨8T”dGhW±Å4$¿Ä»¿µÇ—H`“b(J ›-R.›pÊF7hÈ&Ê¥IÙ„ªãÊØštÝ`~ÝJÝß 'œÀÂ… iذaa²@ø¨pXˆÔo»ÝZ^ Qÿì‡sÓjdÔ†ïàÅç¡ïÅ`ÅY"ƒ…¯ÀæMB BkósJKáY"ÎèòáÐçbk퟊8§: Åë`¦Ñs]‡Õ«…pÞªÛC8,@°E z…5féþý0ùF¨wœXX!Õ¬ùîŸ%rÿ2ïÐâq/õÙÇ¢›™p½µTŽ—Á¯ ¹ÄÄÌG•/?_µ›qz‘ ᧤ž~Xtž Ü4ÅZG|ß$!¯¨ÓÆL¨~T™¬OÁ†ŸhÜW^cÎä7)%ghÒFޝùýùÖõMïÒÆ…ŠïÑÎ`éÕ•ýD[u~¯ùþN>âíUg –£¯„ÞÆx<¼޼š2 HwšIþ<±3\2„xÁ*ê~!Ê5ƒR™EÅè ¥R½øé$È ¥uƒcÔ&ÃðÛÖÉ—ø$ OXtƒ04“§Èæé•e¼®n{[8!ÀÙiGƒ„DÞŸ' ‚kT°E“ìQ Ecó…pä„DGèŒ"ÙâB6a¡8¢Ø4MØÆ%²Ž0‡!H€¬¨ØäŠ-*H2I[5)ŽWÓ„62–öj²¹]Oèpxòز~=³gÏ. @Û¶m™5kVÆÛÛ²eK ”Eœ,þ‡U($ìצO·nÞ½z5¼÷¼ñ¦µQ¥¦ÁóÏÁ¶mpË4hÛÖüUÑO À”›­<("–Ô˜p‚9łڑÃðÜ“ŠÀ™½¬¹Ûüö+¼ô”ˆ~5Vd-šÕçŸÀgK„\¢SW>¢féC"K_…ï× Íà˜Ip¢‰¦3¦Â/‚_d£–ÂŒ¼¦.á (‰šÁ\¸r,´¯á‹€‚¯ægX·À^ñï'ƒ-oB±?й´E…?‡ÝoÃÑ’ªMµ[ W§¹Þ\9Š)},šÓ.Íš’ÐîÄ¡Fü†\ÂAÉ Ç$mØ–O±B9ªpɉ‘¨O5Ö×>,Áâ^''ðƸÃàŽ¤@0ƒ,…ˆ t—8i·š2ÚNÓ:âq±oiÜCöë8ÝaäR;>-KÖjÉѨ`jå R.W»/„ß#€PV41µÅphšˆ’2º_[ä—ÙÉq„±©1쉄H£WTlJFè/ªAƉ㉮2šŒÒ´#tî' â›o¾¹ümq8Œ1‚=z°yóæŒ·¸ÐªV¶²@øo«xž}VX¯Y …Ð~ì8k€Âuæ™g„È|Ò æZ>U…>*’ÝïøœÑÍü~?\7Ž‚ng‰û˜ušóæÂŸÃÉD¨¯YW|ôÜ1Uh4/ì£-0lwî„;'CP{Üu·9ÃvÏv¸ù*¡ì5.»l&ÏgÙK°âc JÜ?»f­åí°öS(I‘LAÿAÕ¿?Gþ„g‡Áþ’T‡&Â÷U-Ù¶¾{%5=„œpÞ@è3°òû³ÿØü|åqè1ã>“oŒa€ðJ8º9Ó 27\Ü.€./F޾-òÓ:F¹TåãÎcPVrUÈS±h\ŒF]´ëƒ–€pm¨­'è…D2{9Y&B†³LTÃE¹GÙúAw·-Š|Äè‹Å!—‚ËÄÏÁkŒE=’*H2ºˆ^òÃk¸Êl¨/S;¡ãÌ ó„ÐË¥1±D*\¸ l¥`+ˆN¾Æ¡¨è‰’-‚bc—¢ØŠ.Ôkh}1 ŸªáÎm‚tÚ@h×d™5kÖ°qãF@ä{ì±òh¥nݺeÑå/Tÿ{„ß~+\`Ì’ÒëÉ'EwvÅÖÆ›wÎ@tV´|[·Â³Ï@›v0l¸µ{,~V­€ºõAÆÊc;zžyÎ8 yÌØmº_ ß|yµaä¨eâÖ‹s¡ôˆ°k»lˆ°¡3«çÝ£ìÚD3»¶Ò£ðÞ‹¢ ý‡@·žO¨ f‡ÖŠŽª¨)\3òkøÆ¾íØ´:µR õêUEGƒ5§,IÀªÕ¨zÄ»é‘a' Sô¸ÎKÛO<ôøc™cÑôްq;¸x0äæƒr”Œ0_),#÷Úq„šˆîÏgtƒ¹qÑÕU”oÈ(¼q½¼tR wZG˜<\aÈ'ÏÉ”NØU”P¢|T›<^kR€KŽáJh¸eÑ:Ž0ÙºtM„ò&¼ÜQ¦(&áõ‘Üa${ ÅÃKàqRIçÃE§ ^IÅ¡¨8»-ŠCަH9’èÝšHœðĸeRÛžÝ9¬[·ŽáÇSVV@nn.㬒粕íÿ#ª~}ëÖf_}¯¼/¾hÍë4‘€§Ÿ¢ûÛn«™¾ŸÞ¥Î¼KøpÞ;ߢØþWøç#bïrüDÐk6Jõ—Á•CÄå3Eˆ°Ù9{÷À¸‘ÁÍS ÷9æmÉ{ðÂ\ÆáäÓ`òósöî„Ï?‚˜ÆN‚.]ÍÏùå{X»N€B».¶®¦±õ?À÷ßšÁ¸âèPƒý\ØÏŒÉt„©Ýn¾¥jK½Ã?Ã/_gvƒZŒœ«x­K~…_fv‚ÉÃ}Ü÷`ê>ůÂe)pJ—Kù0øj1‚–ýHqHiN3z±!0:BŽA< {O)rü)¢L¾*F‰å¦qEZ:8"à4ºÁò(¢Hæá Áκµ5‰\Oº€>ŒS‹!§u‚Éã÷ru 9žÀ£¨¸u¬–{‹zHv†B>áQdêª2µÊH¸ÂØ¥Ψþ;CiÃFG8¹U-ê­”ñHQY›ö°0ÜFD0‰nÐO$âx2ö& ËhÔ†„Ÿ}öüñGùÛøÆodÑ$ „±:þxëkËÊà…à‚ ¬E%µ}f<=Oq¬Ä2-^ Ÿ-‡ñ×V­G«ªæ<[6Cû“…]›•½ÎeKuÌuâ>Vö yPäúµl £®±vŸÇfA4 Ž\?Á\£yè LŸÛwAûî0jŒ9õÛOá¶á¢› n4ÏMœ75Õ}u>Sø£Ö”g¸jS]QÄ·L¯>xù£)©N0Ù¥u>³z»¶5S3;ºä‘ÈÉLäHàð›P¦VîK€ˆÎ8z÷Åê3ºÆ$I&y°í*ð–¦öó⢻“J*?®/ƒœ8HaÑíet‚éGXé+“ H•ÉqGËÐmS‘‹õÔãIÛ#Ì3DôΈd°E0¹ÒÃx@^wB£0.S;&áò„Ðì*î¸ vÀa6¿0WT™‚°„CQ‘u¤8²Å)©8“9„z¬<ˆ×Kà(l '_-º€$óüsÏ2}úôò·°W¯^œð?ùb­,þåjÅ èÔ ´¶>‚¹OŠý½Þ½­Æo¿‰Î®e+a m…ˆóÉ'BlïpÂŒXsÑÙú̺[X”Ý8Å uÞ|½¾˜z+4h`ÞÙÞwlÝ$F¢ýúX{í6~ +?w\{£»6V,…=‡ $Áù—@sƒeÏÀo†¼BóÂè 5ß'€/¤@'(ù—ˆðåªêÇ…°u]&HÕjÃÇT­ücìXUy¼Y*Ái=àò¡©¿ŸènØ·,E’©Ø=5‡!£…-œ€à+ðKÈÐ%Jð$Ï“5ÂÙ'š"ÊäDhTb¢ösPª!Á&u‡Sà—Îu…:"Þ˜B®W-Ú"Z9øIFwšüÝ#ÅQìaòBŠ„†¯(†É¶”B†…1…"UBw‡Ð¥îhgPI¶¨ÝHØÈßç!G×°Û¢Hz ô8vC?è¬ÃD OBãi¸R›^pÊ…SD0dÁ‚åoaÛ¶myõÕW9Ϊ‹U¶²@ø—«½{…p>íÛŸi}ù%lÞ ¯¼j c1˜÷4l܋֭߳ê:¼ñºÝQפhõfõäãpäÌœeM^qèÌ{JK`ø5¯ӬK[µÞ~IH2ê6™w›ûÑ#0ár(UáòÐßp®üæÏ1lÔZÁŒ»jöÒ#°êC‘TqÂÐÑÐ뼚;➄ץª¨Ü|kÕDœH)lZ Gý)àˆz`È08«ŠQr,Û–ÀÑÒL[´bÀYfÞ›9ÿíÊLÓît »àšÑÆHTàãàÿ®²ùv‰Ñå%ÿÛ^›²[OÇÙ/jebà‘ý”ü=‘K!äXœPHe<é íÆxÔÎ5ƒ+(Q…Ü‚(w§®ŠÑ¬án#ãÚ$aÆ)G±k1ò‚²ˆ^ÒÕr[5OKŒ×Ø[WÇ/KäI âÞ¶POP€³Ë É8“cQc4Z´Ç‡ÇÁaSÑõ8Š.öÆQ®SLÄðH2¶Æ§Â)CýÖ””–1nÜ8V¯^]þ¶tëÖ?ü°ÂÎK}.¼ðÂìçç_¨²Î25Õ‘#ÖÒÙÓãŸÿŽ3VMv¿ùž{NصY´_…-› A#l%þiéxó5¸°/ô>×Ú}žë×Bn-¸mzå ÙŠURφ½»ArÃu¡Ióû<ÿ¨ØKlØRøuZ©çæ„+F˜ÇfíÛ_,ÝTÃàò+k–qþ>5Õù+¯†ÕHSüaí›™™§soD©ðQøñÕÊä˜2`ÈHhŸ&È>üû#õ8*j [v„‹€7´à]¼6é×4H2)ù‡CGqè¤oÄh3*ˆ2>Õ Ñ”U‹mÐö4r¼¹8®ËeŒEË 3iÆž¼w±èÊ â2^‡ŠÛ¦¢„ÄH4iž~lè PÚHÃY¦R„‹L¹˜>&2ºfH(t¾occ®ŽË&î aOëéa ¥™Ì)±ãvD°ÙÔòNÐ)«8”hʽ&í'°ç7€ÖgA‹ÓÀáfÿþý¼õÖ[åoËĉ™9s&‡Ï 1.[ÙŽð/S'dm aåÞ{¡n9ÊšÏéáÃ0u 4o·O§Óüœxž|6ýO?+£Yý¹Sä6h$:+’‘o¾Ÿ·îž-Ú‹Ï óîpQ¸ztÍ,V]‡ÏÃãìƒ 7™ku¦]k¾Ý`ûNÂSµ¦îûÏ_াDô\˜|{Í€Ûz €$Øté%ìñª{_Ÿí_ “ ã&C«jö,÷OIÒ)ºž+¾@dt³?ñ’ø¥î4DœÆÍŒÎôkðoÉt³I—c$Ï=µŒŸ€oÄØŒ¦ù‰¦ú šó˸R”‚b컀 xƒ™R _ÜA‹#°~4›JÔðyÂØ£ñ”L"íHþ¿Ò")?†çOyaIì&¥² ÃíÅáÊÇíuSHo^€RwûAwPtƒ®¸üB6a/]a‰ t§Fž=Œ[ “PÈz»"|F]¨xt¯Ãíô"µ=N¹D|ú§ÞëÔ©Cß¾}©W¯ È~Vf;¿qYAAÀë× 6¡L$àõׄØ~ÌXk€Fžá<ÑÕ ²à:£ëbýʯE뉇€înï ªŽªX[6Ã3s„‰´3fÜ 5Ÿ(ƒ÷€ªAóÅHÔfòÝlówBú<µà3ÍGЯ>û <½œwaͯÛêwàè¡T7˜{œpީήmÓûp`_ª[ Û¡÷%pö9UßgÛpxWå„ [¡èˆÓ=*û`ï§• 8I‚ÌÙ}଴ÿÈí™RŒê|Ko¾7F Q¾?艦Ò%2ö-Ëd8oÎÖmÉOèØ™Ý`:IFIg©ªàŠé丣¸µ\®‘þ3yPjñmqœ~¯–(ß,—5èÆ+6¤‚&¸]µ(”t\9!ôX\<®  ʸ‚¤e°æØÛH#—9%Ÿp*‚(“$ã¸d¹Q8±4hH¼ûî»8p9ƒÏ?ÿ<çŸ~ö32 „Ùʨᅦ ];këC!±—xÚé0z´5ðôû…õZÓæÂ©ÆJ²ÄÛ„áuß~0ð2kmé{B7X·¡#˜I9ü~xj9»ÁãOZÓh>p7¬^Šn¾Í\› Ãc÷ï[Aµ‰Q¥YœÕšO`ù»HŽk ·ÜQóˆ7‚Õ‹…•ZT`èH8ïüªAM Æ÷àPZÇVÿDaÞ]Õ}âøm €-Ãg$FHÅFµÅ€ë8¸lñVùÈêHe\œ&ÁÐ$È£Ôx-‰ž9êȱ«(Ázðe‚a$ßKà /rÙ!|±^%&ˆ2ÆXT„ñƱ»ò¡¨‘zÇq8w…m¸ó‚Ø5Áu‡Ò€Ð Ê$ßaµsœ¸ì¨`‹a“’¶jQÜ’ŠÓW-Ï„6½ Ptæo¾ù&ÅÅÅå/ó /¼ýÌËv„Ùªü¡¾¶ÆÄLÖ}÷ mâÉ'[[¿gˆŒš8 &X$”|ò ¬[W ‡SO5_¯ëBÆ‹B‡NÖÜm¢QxøÐb‚ñÙÖB'X| ž|þÜ í:Á+Ì;âm¿ÃÜYˆ; LfNÄY·Þ~QçI]aøU53KõÌŸ)ÖûÕ‘ Á­®Þ¹+sÙ¡;ô\=p~vW¦#LÒëtâM•;â­¿Ò@…±hЧ÷†Þ˜‰QR×®j$÷ÀÕcSšÎ¨qzT1>¬¤e ÚàŒs¡ÇÄõ?ÔÏóÒÆ£6&ðÆ®¾€Xë}äë:®D<¥4~ʈ2ÓZs¸ÝQ!Ò×tÜJ,#‚É­Çq* 4…Âf„‹rØíÝD~ІÇE é¸BiBzc,êŠÇ«øÁsØA^XÂa¡]Q[ÔH£w)2Rƒ“áønP_|aš9s&O=õTùK—yíŠÎ3g_(ºhí0²'ƒà"¥¯Kj¶‡«&@Ã&ÈÑíx ‘½Û ÊxCA&ÒÑ´óÎî‹4f®ÒEØ:-Žf\;ÝEF.¹DBjrRÿ+ñÆ¿'ÕQã |²j¤L‡¤£ä6€Ú­¡Î‰(E…x"Pè·ã¡¥D<OI&yØKAB<ÏA^<ÓÁQ‘—Å­Gq“@©s"´î-ö=ùìÚµ‹?ü]×hÔ¨£FbÍš5oSË–-ie5’-[ÿ™@øçŸ°ÿ~Ö®]Ë¥—¦ˆ;wîäî»ï¦S's§“+®¸"k4k¥~üQì Þq‡yö_²^{MìúÚúèuölnÓï°¶¾¤Dq‡#0j0ôèa~ÎêUðÙ‡P«Œ¼&µWUã¸ö(<8St/C.³6zý~-,~Mô›·AÅ5±QUÞz6o¨†_ O7‰®€ûF¤‚n  öfNN Ýà½PfìÉ©.è7:Výú/‚c‘TÇæ\µÄßBÅýÞ#`÷ÚÌî±(0î hÝ.sôª‘ê+J2J‚&pÓÔÔúÐä#Ëp%»¹Š‰ö"è3XÜ"ÄW ¤I&ŒCN—sä7‚I7ɯJPG+­,—  $¥Î€Ò¶#n53ªã‹!Üd$Ã[ÒP\ù×Tt„Íórp$”(r™!¥Äôåd?„ݰµ4ûBÅabS !½®âÔc(¹ÇAãNÐì4È«Gqq1#FŒ`ݺuå/Ù˜1cH~^¦W:u²Ÿku ¼î:ñ qúôé¼ù曤1ý¢Ñh9Sʬ.\X)ƒ«ª5j'žx¢ù³Ùþ~¶Eº.íÖ[­³D7m‚—^–Vr xýuø`) XöÆbp÷Løe‹XÜu—yPq($€óÈa˜z;œ{¾y7 Á?¦ÁýpbAÄ1;§¤î˜j”¸qª9gËF˜ÿø#Ц\=®fiJ\…õËa§ÁäŒ:á®i5/¯~]$X$àÄÎ0l$xªc–.† Ë2÷í".¸õ6h^…‰Â±m°û·L‚L© z€+*ì+ëP¶«21&Ù©F\0itêœöœl¾•…ó~tí†SL,¤ƒW#û%‘¶?hOöÛ`âèÖDô”2‘bA(µ(§¥2ô<.½›³_G)•Èó+xuMì J1œŠ © µ€¢–P«(1¤}àsDÑã·ÔS(ãHÓë ŽG=r ¯=ŠÛAR4zW"ŠÃáEjÔ Žï ;€âàçŸ×³bÅŠò—kæÌ™ÜvÛmØlYZÅß“¿Üwß}•þÑétÒÄŠ ¸ýöÛ-­{ùå—™?>Ÿþ9§žz*ùÕ쫽û;Öôzµk×fäÈ‘W[’„ɵȤ×#@»öpvkëwì€'‡:õD$“•{}ü1¼õº0â¾ëȳ°×SaËÐâ15K½ÐuøòSXº>!8¾…ù¸öéÇaçÐé,hÒÆÜà †Gf ‡—ˆ]ì½™ùÚÏÏJ ÖÏí+F•ÕU$+ߣ!>JÈMlÒ¬š×* ëß‚£ÁTÇå—Ĩ²ª}XM…_–f}¾0lle»¶D¾T5[´8­·¸Oúèuß;Èþ4¹CºÞmî¨ÓÞIDAT°v a×V'u%pÙè²äpŠ”"§u‹SD¤ÝN|ïu(È•$¤½œ S~”€”ß„&͉fà €Ì Øp+qÜ’ŠK‹#ç5„ÂãÅQÔòcÓvQ[UÈqGÑŽ‰Ç‘ôM:Ê$Y£Š³ò%CqEŸ G‰âUd%ŽCâ°ÉHu[C“Ó YWp 1|²AhÖ¬½{÷΂àþ»jäÈ‘hšÆM7ÝÄäÉ“iÚ´i•ë.¿ürü~¿éõ&L˜À¢E‹L×|òÉÜq‡ù˜Ðf³á0Ë ü©ÿ F£bd6z´5©ˆÔ‹~û}VìÚöž£Ñ‹/…~ý̵‰‰L›*ز̄ú|ƒ˜~ +†¾ƒ`Ð`sýߪ•°`8ó`Ä8«·9Ø>ÿ¬ÿJøžu>œo¡#žs› à€ºMáÚëjŽÍ*9_¼cŒ7%8ç<8«W ϽV¿™9®tÔ‚‰7BUc5M…ïf:È„0è28³wÕïO€J‘Iå„—[ï¨|Ÿm/" ßÑ y… ƒÂégeŒá¥ pƒ±Á,Ñ ‚Œž ·Î(׎ÚT1FµÙô”f0ÉóúC—î ËDÊ^Ä©L‘qû¢¸Ð°©:x@¾‰’ßì‚¥·QW“ÈõD  @O‰:ƒÆ]ÈçõEîq¹ËÇ'ǰK*ŠÇaK ç5‡ú I(lLB×™÷ôÓÉ‹/¦C‡Y´Èá¿¶>ýôSZ¶lY-œj…ålÙ²ÅÒºåË—Ó­[7Z˜XŸ5mÚ”ÓN;ÍÒ5Ï>ûlj×®ý¿÷B9ÆX³T <—ö·¶þÀ~زxHŒ7­0_?X.ƒ‹ð”,dyþØ µÀÝ÷šÛµÅã0k†H¥?EÜËìù¦à­¹àCƒàÎ{Í¿xlÝV§@mòèÙ«æsî˜ê¾Zž 7O¯yô±©g ÂTû¶)pÖYÕtõ«2%Ç€&' “ðªî³guea1t¤©Â4¾˜{{é$™RN9¨<â-ý˜pªØpÀ•ã WïŒõž0Ø”“d䤯¨_A:¹»è:|F§ñEÄV¢“ƒãuÚHÑÈm&Æ¡µZ¯H2G÷oÂãRÉqéøÿcP·?ÍQÆ8l-:˜Q}?PTð)*IEQ4l¹  ~'hzÔ? l.¾YµŠ i¬ìnݺeY¢Y üß©öíÛ[¹þ«ª]»v,\¸6&ž”Û¶mcåÊ•¦×ûè£xñÅ©g!ŸpÖ¬Y–Öý?—®Ã˜10~¼5»61ƒqLÃGÔœê^œ`6Ñ p®Z €ä]P³ææç,|Ö­‚æ­`Ähk$¡G„í[ e-sréرWtT­;€Ù8~åbøsWjŒ:ìj8Ádôª’)ghk"MYþ@&éEɇ¡WCÓj:üÕ÷§œgÒÏkq2ŒYùµÛò8øõÌÑk)à® ý‡Aã ïÏΧÀ¯’(]ž+T SخڷÜÿ,²?HN ”)¢ŒßNxêÁ€+¡YŠ®„A/G”|¿ §;‚MŽ£xr¡Vk¨wÔ?Üâïø±ÇËxêÓ¦MC–³*³,þ/Tƒ h`çó/®úõëSßÙ¤E‹¦]crtj\³hÑ"^~ùeFމb!‰âöÛoÇi`²,Ó±cǪÿQ’àÚk+‹²««ï¿‡eËà±Ç¬3ẊU«àΙæF×ÇŽÁÁî=pîEpÅ0 Ý&˜û(8¼0æzhaA¾óÆðÉ;ÂçôŒî0öZsiʪOaþÓDœE™!¸U•¦Ák`ï1ðËÐã">²æçóî£ðã÷)°ñÔƒi5ŸJÀ¿X{ (³A¯‹ O ~–*;Âh>#7± ðÜñ9”è2v1®îݧòóÙ÷%”ÄIQFvZ·qã³25G¾F)Sq‡ ‘~qZÒDÈ!îsöy"B º%C.7^9Ž=¢ƒó8{¡°%¶WÊ#·P“ˆ¨:¶¨ ø“®2ÉýÁ¨¹çEpÉ`pºˆ’È‹€;/‚âÌok¨w 4ì Eâ5ºöÚkY¼xqù=FŒÁyç—E‰,f«ºòx¨z»6€• `Ë÷©Ní¸V0j|õös;×Âî?2­ÚJ€>—ŠØ¬ª*D樶ál3è*¨]·òú°X§—Éé {ÑÀʶp1ý†e[Zü“ì—‘Zt„á múðû½(%G±À«ê8].ØÁ^$4oíŒ|^ ¤(Øã:vÁ’°5mC¯)Oþ(Û¯SOQ±#CnsÈo#ºÁºmÀîæ§Ÿ~bõêÕåšÁÜÜ\š5kƃ>˜ñÔºvíʹ瞛ýÌa¶¬Ö°aÃþGë­0o‰Dµàê÷ûyøá‡™9s&`êÔ©Ì™3§FЉ«*ýjÕâòË/7½·ïë¯qöë'ÀÓʨ÷àAxô¡¼¨/téb~ÎÆ°èM°¹Äµ®…ûlXÛU‘à³…=Þù/Âç‰,ÃV§Â”©5’tæ=›~Ž3ƒF@×î5ßcç/°èÙÖ5óæÍK=î…7ßÆØ£¯±ö¾ýæ¿ î\?Á\2‹Á«ó…?l›pù0s£‚ƒá‰ÄUµÃ ·@} {Üo?/@-¯!´î"2k’¦èÆØÒøŽƒ!£jf£–„ϦÜgüÀÙçÃeƒjxþdÊ2궀˯‚ÂZ5¯7È.åçu<† ©¢ ^¿|#Æ©†„CòƒT¯\<8C›Xþ´ËÄèÔg\ª–Î:Â.¦Âž·©TÇå×W Y‡3özÍ. õRïitë+¸Ëöá k@-(hE­@Ú×G}´|mëÖ­-}ÌV³õ_X 6ÌŸ–••±sçN¦L™RIh|É%—ÇM¯yã7Ò§OŸ´Ñ`BìÉ2L»µ4Ž9ÂÃ?\õE&Móó.¢ }{LC°~ú  ЦÝY½>ý1½±V| .»²òžXUõø‚TS§\< 1gØNdh¸òrèunÍÎ; RióõÛ@Ù!¸÷êïsl/嬿jkèP6lØ@Ÿ·ß†eÖ¸Ôï÷3ýÖ[i{ÛtA–ùècÁÞܳ§ÒÚzõê¥:ãü|xb>Ü1 †\i‚¥¥ðép‹`àQךk-wí„/?&={Á¥Ã…ΰ&«»·æ@ÿ;à‰{ÅøqèhhÔ´úõá ³A³sá!¡ ÎñÂŒ¼ª}ËHž½U& ÚŠàœAUŽDˆ‚äw’p«èR>R½@©?,àŠ@¸}%¬xS¤\Ô‚Ä1p†$á™zÑ Z]¡ä0(¾¦B®qÜI`sS\\̵×^[i’á´ª¿ÍÖߪ$Ýô“#[Ùúï¬x€o¿ýÖ”)øÍ7ß0xð`K.CW_}5öŠ`µä=aMVT n¿žy±f¶lY¼=_„òŽ÷Î .5B‡öÃKàæñpîP˜ý„¸guõÉ[P†ï–ÁïÛà»ðì«b¯³ª –A—<ð_±Øàòëà†éàË­L’IhðÄD‘¹¸uzQ¤Ë&€^žz¼Ryüºñ¸¥/NuÈ‘lz.Œ¾IÄLUÕk¯ME>ºéf=ù…Œ;–çž{žÊ#GޤiÓ¦•: .¸àßnþ‘­lG˜­lýÇÔÀ;v,…&f›7ofûöí¦×›={6K—.­l®°w/4h ’IvíÂ=éÞxóÍê/¤ªpé0p9aÖÓÐétkO¨ÎqbÏ/l‡ISjAn@ –ÁwŸÃ á¸.5›¿'€VgÁ S`ê08®±`åÖª†y©ÅÅèõ¦ç`Ûj¤m Þ ÐøThuJÕ†QÄäø°äd¿„Òªœt&=V%óU)l ˆN9È/díÚµ,_¾¼üß=óæÍcÆ ìÝ»7ãÜl‡˜Âle뿺¬R·k׎víLi:¦£Û@ Àœ9s8çœs2IDÕT(¢¨°±8,=—fÍšAí†pÇ,8¹cÍ'lÿEüÞùla gw׬µÜ¾ Þùd(„ËFA›š"³$8¥ôìóï…¶ÝéÇãGUµi#œ{ÀË÷ è¹H#®Âþ*Ü›ôŸ¾„­ëä6pÿtb±ݺuCÓ4š7oÎ{ï½c«ÇÙÊa¶²•­ÿ‹2³ÙÓ4ž={ÒµkW>øàÓë•””0þ|~ùå—š1mûv6lذ=yr•k¯¸â ºtéG¤8:u‡¦-kf°––ÂÛR{bgè?¸<ϰêÄW\/KÇw€VÁgBVydÜ2 ë ­b׳àÌsªÝ•|…Ðú,Èi²Ì³O?]‚C‡¥½Y¾e¶þö•Ý#ÌV¶þæ‡ÙSÁ`íÚµlÞ¼™Ñ£G³zõj^xár+ÚÓ%4£ËKÕ¸qãhݺu:Š @K‚媯¡Û™Øìvš7·`²þéÛpÆyà5±Æ»nüŸöî6¦És àøÿ¡-o+–i-P˜ÂÊDGfÍ-ÓˆY„dJÍ0̦ÑMݲÄm òÁ…‰— &&š˜x &jftÙ22e‹8– d3ŽðbPw†)ï¤Ý)¥„Zηn=¼ˆ;l'G¯_Ò}ž»÷‡Þm®ç~î빯â@o'¼– ûŽ@Æ4³g·†À€Ó9€Ùlö?›žžÎ™3g˜7“Íæ…B!ÄÃ騱c¼ýöÛü¹ÒÒRÚÚÚîÛ®ªª* ¬ÑT ›6mš¾QKó½"Õÿ¼å%_8}I¯õNÓ5ÈÖ­[ùâ‹/ü§ºººf´¿@(„Ú•+W l—””ðÊ+¯L@Û·ogÑ¢EÓwÖÕIJ¦™ÂÂB¸3r¯˜ôÙµAAA÷nE Bxmmm,Yò{¹¬ÜÜ\öïß/É0Bá_áÖ­[|þùç,]º”—_~Yj™ ñååå¬[·îOo^••5£v‹-båÊ•þ÷ï¾û®?#4&&†;vLxä“Bñgx½^ xæ™gX½z5±±±(÷Û¹D1ënܸAmm-mmmtvv’žžî?OXXØ´IFccc455+**B¯×Ë—û’¬ÑYtóæM®\¹Bbb"n·›ÚÚZæÎK__iiiØívšššP©T¤¦¦¢×ëñz½466ÒÝÝÍÂ… dùòå444––Æðð0×®]cåÊ•x<~øáHNNÆd2ÑÓÓÃÏ?ÿÌÈÈZ­–eË–ŒÍf£¥¥FÃòåËéîîæñÇÇh4b·Ûéìì$%%EM<”’’’HJJ"??ŸãÇ£ÕN|cÕªUS~þîÝ»¿oÿ«È)öpmhh@Q”{Ù¶âÿ’Ü·›E£££ŒŽŽâr¹p8ìÞ½›‹/ât:±Ûí=z”ÖÖVêëë9q⣣£444PVVF__§N¢¸¸˜ŠŠŠp88p€³gÏrñâEº»»9rä·oßæêÕ«ìÙ³‡›7orôèQZZZèííåðáÃ\¿~ÎÎN\.õõõTVVâóù¸|ù2.\½âââIƒàý¨T*bcc^jõä󆯯FgÔïøø8ß~û-›7ožQÑLy½^Î;‡Åb!//›Í6!°WTT`µZ±Z­þÙð¥K—x饗X¿~=8™ŠÿNbb"&“‰ 6 ÓéP©TäääECCX­VÝ­[·òå—_b6›1›ÍÔÕÕqãÆIû¾sçŸ~ú)………èõzl6×®]C£ÑœœÌo¼Ó餽½—ËÜ[ AQž}öYΜ9COOMMM¬Y³FLˆY¾nnnÆh4N»Ç›o¾9}Ñì_ÿóuuuèt:~ùå—€Û»ÿéúõëTUUqðàA¾ùæÊËËÙ»w¯ÿüåË—©««£´´Fã¯ãt:IOOg×®]ôØI ü ©T*I·ÛMkk+eee(ŠÂOùÄÿ`v\\ýýýDFFJhh(^¯ǃV«%44ÔŸ¬óä“O266Fss3v»¤¤$ !fÑ×_Mmm-ï¼óßÿ=§OŸžÐæý÷ßÇd2ü7§âr¹ÈÏÏgãÆ,\¸ÖÖVÿþ¨´eËl6 DGG³bÅ ªªªfƒ555DFF²oß>âããyë­ßë}VWWãñxX¿~=/¼ðÂ#™à'ðoKjj*;vìÀh4ÒÑÑÁc=Fbb"—.]"%%…êêjîÞ½KDDŠ¢ðÓO?QWW€V«å¹çž#;;›U«VÑ××GXXýýý“^q~öÙgttt ÓéP«ÕÌ™3‡Å‹sòäI–,Y"•·…˜EÕÕÕDGG³k×.bbbˆŠŠ"77wB»­uNNNz½žáááIû4 477£ÕjQ«ÕDDDàv»ýçÇÆÆü·<·lÙÂéÓ§9yò$Û¶mãÅ_Äd2áv»)--eΜ9$''?rã'k„³<LHH $$µZžýÔSOa±X(,,dÓ¦MTVV2>>NNN>Ÿ×_ááa‚‚‚ eÛ¶m|ðÁ8L&*•Š‚‚Ο?Ovv6‡Æét¢Óé0(ŠBTTsçÎ%99™¬¬,vîÜÉÎ;éêêBQ222hoo'33ó¾Û} !f®§§‡yóæŽ¢(ôôôPSS3áåt:¨_FÃüùóQ‡Ã1iŸýýýèt:Ün7^¯—ÁÁÁ€uÑß‚ãÆY¼x1¯¾úªw£ÑHJJ Ï?ÿ< ,˜°é¸ÌÅ ãã?ö¿/)) ø1®Y³fÂÚœF£á£>îítñÛÔb±`±XÚÆÇÇsèС€c ¤¥¥°yófÿñ¬¬¬ Ï\y<’’’Xºt© –³Èb±àóù8vìÛ·o'88xÒ"¿jµŸÏ‡×ëÅçó166†Z­ÆãñpèÐ!vïÞ=mPœ¬Ïàà`,X@EE½½½Ô××,}¨ÕjRSSùñÇyúé§ùî»ïüÛÞµ··ƒÝnçöíÛ˜Íf „âáuõêU>üðCÞ{ï½)³ß„î·:””••Q[[˺u리cXSSCQQCCC¬]»–ãÇãõz',sh4š€ (ÑÑÑlذaÒ> ™™™äååGnn.CCCÉþñÎλ3~ggfygÖNDDd–=K@Ä€1 D Qo$++ë±Dééé(**bÉvrúôi,[¶ì±Ž?Ž'N !!ÙÙÙ¬"=³˜4 °¨SDDrss‘˜˜ˆsçÎÁÃÃÃäýÄÄD\ºt鑟€·ß~»_«  EEEXºt)÷[ È‚ àààðÄúúë¯câĉfß»qãÖ®]‹I“&õ»€”——###ƒ±Õ€˜£×ëÑÑÑñãÇ[ü¡*• *•Êì{C† aÕ©^ƒddd ±±—/_V¦-_¾o¼ñ†I§9sæ 99UUUpwwgÉ6¢Õj±zõj“o§Ö¬Yƒàà`“N111¸~ý:\]]±xñbV‘lãkõêÕÝf ê6ÍÎλvíbõÈ¶Ž DÄ€1 D ÈJJJByy9÷b@Ì9{ö,ªªª¸BÄ€=ezz:§NRÚ¬:1 ]ggg¥ÝÐÐÀªÒe„ X·nÒÖh4øúë¯Yyâ5BÄ€1 DÄ€1 D BÄ€1 DýN5©ªª2y<éßÿͪÒ¥¦¦iiiJûÎ;¬:1 ]¦NŠÈÈH¥­ÑhpäÈVžx BÄ€1 D 1 D BÄ€1 D Q¿ÓãCMZZZL­×ëYub@ºäåå!<<\i÷•'+êt:”••q Þ ȬY³œœ¬´5 <<+-- !!!JÛ`0°êÄ€t™;w.rss•v_¬HÄS,"„ˆ!b@ˆ"„ˆ!b@ˆ"b@ˆ"„è HZZ¦OŸ®¼V¬XÑ/ ¥×ë±oß>Œ3‰‰‰ÜslGóZAD`ggážÃ#1 D ˆyQQQضmŒF#÷b@þmÔ¨Q¨­­å^@ BÄ€1 D BÄ€=›øèQ¢Þ =J<Å"b@ˆ"b@ˆ"„ˆ!b@ˆ"„ˆ!²=>ëÚµkˆŒŒTÚwïÞeÕ‰é2eÊ„‡‡+íÂÂB¤¦¦²òÄ€€ƒƒ&M𤴛››Yuâ5BÄ€1 DÄ€1 D È“ÈÏÏG}}=¼¼¼¸òo•••hiiÁĉ¹ò¬;xð âââX„ÌéììDgg' Ñz|¨ÉŸþ‰cÇŽ)íÛ·o³êÄ€tyá…0sæL¥]\\lS®©©ÁðÕW_qoc@ºsqqÁ¢E‹”¶F£±© dddpOã5BV:qâ‹À€ÐÃìÞ½›E`@ˆêölÙ‚ÌÌL‚!sZ[[qÿþ}‚!b@ˆê]"Â"0 ϶ææf Œ9Òª~.\0ùõa2¯Ç‡š”——ãÂ… JûÖ­[¬úS”••…’’°ýñb0 ×ë•WuuµMxøðáðôôÄï¿ÿνGîÜÜÜðÙgŸ)mFƒ˜˜›)°££#<<¶c{{{ŸºAÇ’u¦âèÑ£VõÙ°a¢¢¢°víZ«·‹¥£†EÅÅÅÐjµV]Kõä¾h2ÔD«ÕbÓ¦M9r$"##1a³òóó±nÝ:Ìš5 _|ñ\\\¬^pYY®_¿þÔþ! À=sãÆ “vVVÖcû=8†¬¤¤Ä¢uð¯á·oß¶¨O×rÚÛÛ-šÿ¯¿þ2ik4 6ì‘}Š‹‹1~üxÿ µd9;v, ­Ún111X¿~=-ZFff&† †C‡áÕW_}lŸ¶¶6„††ÂËË «V­²hÜÜÜàìì KS«X¸p¡”––JzzºlܸQæå—_‘„„‰ŒŒìöþ•+W$>>ÞìkÇŽà©¿¾üòK8p ÅóûúúJ||¼¸ººZÜgÚ´i²|ùr«ÖkÿþýjUŸíÛ·ËСC-žÿ­·Þ’øøxqss³h~‰—>øÀªõÚ¹s§ÕÛ%,,Lœœœ,žÿÍ7ß‹ç>>fßÓh4ÈËË몾.((¨ßýÄÀîÝ»±zõj¸ººö«õŽ…§§çÿ5ŽÍRÏ=÷œõ× ÎÎΨ««Ã½{÷àääx÷ÝwQYYirÞ9räHܹsmmmxþùç­^9Ì›7¯_m4‡~·Îqqqxíµ×0uêÔ~µÞ§N‚‡‡æÎÛëëbÄÄD¬Zµ /¾ø"öìÙóÐ šÔÔT,X°óæÍÃÖ­[y¼¦gV·S¬ËöîÝÛ­“½½=RRRlªPýn.\hõ½ê}Áܹs•oÙz›ÉEúA£Ñ`ß¾}8räÿ{¢>I'êK|mmm<\˜áêê •J…Ó§OÃßß3fÌ€ÑhDss3T*ššš`4a0ÐÖÖ•J…úúzttt µµP©T|šgcc# •Jeö6çÜ ÿ½ââb\¾|W¯^Ell,êëë‘™™ 777\¾|‹-‚‹‹ JKKqöìY@@@FŒ­V‹´´4À Aƒàëë‹ââbxzzNž<‰€€h4\»v vvv ‚V«EKK ***P]]5kÖÒÓÓQTT'''¬\¹ÙÙÙpvv†J¥BMM òóó1gΜ^«Uyy9ZZZàîîþì_¤ïÞ½‘‘‘6ððpdee!%%›6mÂСCññÇãøñã0سgôz=8£Ñ£ÑˆððpTTTàðáÃÊ´;wB«ÕâøñãÊgïܹyyyHNN†ÑhD[["""‘‘7"// ˆ‰‰ÁÅ‹qéÒ%FTVV"..gΜAVV ´´‡îÕZ¢¡¡³gÏ~âÏÊÊÊÂ'Ÿ|‚üü|‹ûôØäÀX¼x1T*¶oßøé§Ÿ0dÈ“ñ[ûö탷·7fÏžm3÷<ûúú¢ªª S¦LQ¦5 pwwGNN âââ0mÚ4@pp0jkkqëÖ-|óÍ7ÊÅ¥9%%%øñÇñÒK/ÁÞÞÑÑÑ(((ÀŒ3ðÑG¡³³°··Ç˜1cƒÁN‡Ÿþ¹ÏŸvy{{ÃÛÛ«V­Â¸qã0jÔ(Lž<ÞÞÞØ°aœœœ0sæLdggÃÛÛŸþ9ììì Õj ___¥®ï½÷öìÙooo|÷ÝwÿÝEºˆH}}½455)톆ihh0™§³³Sêêꤹ¹Ùf.>óòòäý÷ßWÚwïÞ///“yÊËËeÉ’%’››+¹¹¹ÒÚÚ*………²aÃ)++“²²2™:uªdddHhh¨”••ÉòåËeâĉ’’’"aaaJ_‘£GÊ·ß~+""5552gΉ—ýû÷KYY™dffJHHˆ´¶¶ÊæÍ›%==]–.]*÷îÝëÕZµ··KKK‹É´¶¶6©««“öövešÁ`ºº:1Ê´ÖÖV©««S¾1×OD¤¹¹Yêêꤳ³³ÛòÁïJzçÛ™ïÄlnn–°°°nóýñÇâçç'~~~róæM9þ¼2mìØ±""òë¯¿ŠŸŸŸ*w‚&%%‰ŸŸŸøûû‹ˆHjjªœÿKD€©‹þIEND®B`‚snd-16.1/pix/jprod.png0000644000076400007640000000074211147553267012775 0ustar bilbil‰PNG  IHDR;${²ÏsRGB®Îé3PLTEÿÿÿ°°°pppÐÐЀ€€ÀÀÀPPP   ððð@@@ 000ààà```«‰¿ pHYs  šœtIMEØ (£Ü'5IDATHÇå•ÝšÄ †ýFPåþ¯v³eŸê,‡;9Š6o#•|+ÆÛ6©öY ’ï²í6븰ûå`_aÒy¸b!{‹=‚¾5ø°š.ÖÍ£ìíò–¥ú6µ´ˆŠ¬¥²ó¼òèÓˆX&Æä¯]žD1guêÐhê(P´&NYƒý¨Ôˆ÷Ù6­§ìûQ)EZ Óû§™±Tî%®°œ^kBhæÀÍX*÷„Ê–rÁSýsö”Ìa/‰¿Ëe&ohÉÓ-›ŠA †9„×J%òʆÞ²â(vl¸$ósgz²BÔXõlT¨¬?÷³ªÇ‰¿û"XóÁŸ(É1Õù»ÕáÀÎùïÖ_&«åvÃnQêx>žbÔhkèpõ.æ¥ÆÞÌ;X¸J_Ä­ 3* >ÅIEND®B`‚snd-16.1/pix/fmeq10.png0000644000076400007640000000236011147553267012746 0ustar bilbil‰PNG  IHDRõu ·­3PLTEÿÿÿààà°°°   pppðððPPP€€€@@@000ÐÐÐÀÀÀ``` CY¼ pHYs  šœtIME×€¿YPIDAThÞÍ™‰’¬* †Y”÷Ú“*Ø,.}ûU=TþÉmBªMjò¾Ý´qö©¨þaûÚ?C*þ5Ê7.Zax(Z§UŸù;õOZŽXZöWÒnC¢éŠ@vNÒ.¦ëÜöæ dÃç§\*eÿÞU7½Ý©úˆÕ¡í‘v@¿µkëà®.Y¿ìš‰)µêÜ%Æ–ÏCn6ïðqó]um+ÊŒ•#HwƬ‡XÚiô1ò©4e¦+¿?oäÜ™¡³kúÜåÛ°ÌGJßTלgÆ*$ÎÛ­‹ØÚiô2eŒ†NûÎhô0gÌq‡÷©â8_¹4<¯W2ݨ±£A‘hï I(EŸ»\¥c¶š{êbŒgcµng½†Øí‘n&)'ù¸?Dæ>”p "2Ê׌ 3µÂ›ŠÔu*&¾ódzž[3€Ùy×v¶¹0OK>wyj†-÷ÔåcÍng½†Ø½B &%Sʹ—ÈÏ£ò±×1–µ×c 1^4xš3Ìd²é6—*Œ™’Ãl<¶–ËzÑç&Ï¢˜Í-u%ÆÃX;‚GY/!6@¯‚INÞ·’—È­PÉýÔTÖ¬ÖÑm«=Þu¼²>íYÇY§ÙÙÑVaÌÔ-ë’1Yõ9áhÓ1_OÕ”ñ¦º#Ùµ"89g%I¿}½„˜g=½@Š&%™Ó,·O¬Ø©”ÐÁ_غ} Å£È¾†‹YG%hdvlQâJÖý67J2’ŠÏÂZç±bÇ=Žäk˜]<žXfâQ„….^Ÿ‹ñÏ8ú¸ðâ‹”s0/ž³sG-£¡\9&à TžNíÂÃ!dÛŠp~Ê>ϧ9Í¡ºCM`ÛZh[]Žñ0ÖŽàvÖˈ`š3Wí‘n&˜Ó <¾¿D¦ÂP(«ØÁ"TNK‡ž›XšÂÆ“C¸hÆAüCÕ0rÏ¿p5,ÀÃ0"HÚI‡Zf«™†ú ö¬}ÚóÜWhË¡ÞWOC]‰q7ÖŽàþózÑ›ž* =ÒÍä÷Ë úkdJNn¿ ˆB²då*ÂãP6â¹R—Θ¹ÎP’f½ä³þÖ!ª÷Š×Tc¼Á£3|LQ½Jê%ýòÇððžs›)œkꯎmœêŸ‡œVI5¼ŽúEMç×î ˆ`Z0SÚ¤_A>7÷ä=>Ì·N1na$í•Ðq >|^Óö¾Çê~ßøÝ- ¢iÿÆíshŸþ7ÈJ~Áˆ»dDëŠO'ß;IþfûÚ?DJ¿`C¾ó)©þ‡öǤÿ"Œ:6÷ÄIÃIEND®B`‚snd-16.1/pix/fmeq17.png0000644000076400007640000000050311147553267012752 0ustar bilbil‰PNG  IHDR)y;K 0PLTEÿÿÿ°°°ÀÀÀ```ÐÐЀ€€ðððPPPààà@@@    pppÁºô† pHYs  šœtIME×  +7”¼éÙ¦IDATÓc`E@°ÙDÙPXìvB´aŒÍ Uv`àuàúc³\€Âɰ" nâÁ½{7“’’ˆÍp,ç¸(ÊÉe`P€Š²4``fàT«`jÀÀ $ÀÀ>Qjæq&f%†Z £¤ ¢Ì E ®iæ\o& üÆ 6(™hc`Á"Z¹H›âXĤ?ûIEND®B`‚snd-16.1/pix/tritri.png0000644000076400007640000002066511147553271013175 0ustar bilbil‰PNG  IHDR^Œ4ªÁŠbKGDÿÿÿ ½§“ pHYs  šœtIME×  \~k IDATxÚí{XTÕúÇ¿3Ãàà¨ÜD!TTÐÄ â€]LŽFzìf™ZYNÞÊÒ;ýžÌJKŽf–zòÚ)ÊN^H¼&"¤hÅ]®rf`~t˜ãpf63›ÞÏóð0³÷~÷ÚûÝkgíµ×z_ŽZ­Vƒ ‚` .¹€ ‚„— bà olll—ë._¾Œ¸¸8ò Ñ'P«ÕøòË/QYYIÎ z‹®V\¹raaaî°.55©©©P*•ptt„··7 ®®îÏÃÃÆ #½ÂÖ­[Š]»vaÛ¶mšåR©¶çp8˜:uªÖ²{÷îA¡PP=&L×â ÂÈ‘#;]×ÐСP+++455i-OKKëð·hÑ"ÄÄÄ·‰^£¨¨“&Mê ²ÅÅÅêë©S§ ‹;ì#%%gΜ!g¦kñ¶çرcðõõŸqãºÜÆÁÁ/¿ür‡åŸ}öyš0KÄbq‘MHHÀ®]»È9û-Þ+W® ¸¸W¯^ÄÄÄ ''0qâDÔÖÖB­Vkºœù¿ÿû?H$¼ôÒKä Â|[¼AAA Ò|?zô¨æ³ Ö¯_OÞ#ú £FBxx89‚0ï/AAÂKAÂKAðAðA$¼Á…BAN Hx ‚M^ýura,Lµã›7o¢¾¾4ÿ ‚  oyy9jjjJ¥’oÞ¼™úˆUGŽ=šQ?moPUU¡P+++Æû:t¨Á¢}ðàA¼üòËt×$¼¦Ú±µµ5ãÇR&ÄÇÇcîܹ¨««c­ÌÈÈH<ÿüó°··GMM +eªT*p8áêÕ«¬WœqãÆáÖ­[Ù466B Ð]GðšjÇ AHH Ôg2gΜ?Þ ›œœŒ=o¾ù&>ûì3ÖZö¶¶¶;v,ãÑLHHHÀÌ™3éÎÑ“ææfœ9s†A°#¼=áÇIJeËàììÌèm?²²²0vìXÌž=—/_ßÕÕEEEÙ$&&bÚ´i=*W$¡ªªjÀï… Hió^…Bkkkp¹\´´´°Ræ‰'°hÑ"p¹\p¹\VÆšVTTÀÂÂC† ÁóÏ?ÈÈHV妦vvv˜5kV¯tSx{{3ziªk——§õG(ScÖ©Äb1®^½Š1cÆd'`ccƒÊÊJ :ÔàÖ˜@ @qq1ÜÜÜLz~MMMàp8°´´„‡‡‡Á£˜òÕW_!<<œÕkùûï¿cÊ”)fWÇ)Ù%AÂ{?S§NŰbÅ ½¶ß³gÖ­[+++TWW,¼LÄS­VC  ¹¹¹Wü4vìXdffbìØ±¬•éææ™L†Y³féµ}jj*&NœhvulÞ¼y˜7ožÖ²„„JvI ¼®†žˆ`ÛŒ*{{ûÅ{Зêêj´¶¶B$A$Ãá°26ö»ï¾ÃsÏ=X¸p!N:eò2ïÝ»§yQ„+W®ÐDýAxãââ ‹{¼Ÿ•+W²>CÊÒÒÀ_}Ô¦&??îî_TT,X@w Aô7á½yó&üýý ¶«­­EEE<<< ¶­ªªB]]FŽÉ깦§§cüøñ´¶¶²"Úí»)²²²X-sÉ’%øöÛoéî#HxÍ•Aƒé³A­VC­VƒË5ü”ÚÛ.Y²„•m#)€¿f‚)•J“OÀøõ×_ñÐCi¾ÏŸ?¿G~ôåþn KKË^ë'Þv477£ººše¡¡¡8}ú4«Çáææ†üüü~yÁËËËáèèÈz¹þù'&OžLwAÀ„£bbb4­7}_r©T*Ü»w"‘ˆU'|ðÁرc#Û?þXËvâĉHMM…‹‹‹N»¢¢"¸ºº2*³°°P«[D(B©T¢¹¹YÓÏÌ«V­Â—_~‰U«VÑDæÐâupp€‹‹ \\\ÀçóYÖÚÆC=¤×,4…BÁ8`L{ÛE‹áĉÝÚõd\kûÙchhh@}}½Iý™’’___Íwê2 3^#88B¡ï¿ÿ¾IOäôéÓ ÕZ6|øpF)jˆÎi›ñf ON%Hxû2Æ†ÖÆÈ‘#QXX¨s›³gÏbîܹF+ÓÏÏÉÉÉÝnWZZ gggFeÈår­>ÞÑ£GC.—³t~Ò¤IHJJ¢; áímÚ‹BoÞ þþþ¸yó¦ÎmZZZÀãñŒVæSO=…ü±Ûíz2 ,##>>>ÿ«\®^É'÷îÝ‹µk×2*s÷îÝX¿~=ÝmaŽÂÖ!£I‡XµE%#t#•Jáé驵ÌÉÉ •••P*•:msss;Ø o?ÅÉɩۗz2™ £F2j¹ú„[4v7Ň~ˆ÷Þ{Oç6ÆT#‰P[[KYƒ Â\…÷7ÞÀîÝ»M²ïúúz…ÂËÇߣŒÃL™Êê¹þüóϘ?~§ë|}}õËÛmÑ™àïï7n°ê‡xÀdÝOaεéT^^Þi¤«»wïöÚ N:•q¨I¦ÌŸ?«V­ê0“®ÄÄÄ.ãxxx@*•2*·m4EgÃãrss1|øp£Í<Ó—[·naܸqf{ÄÅÅ!;;[k[ V ^£`ccƒ &tXneeKKK¸ººš¤_ôüùóذaC§ëž|òI„……]xËÊÊàääÔé:‡Ó+oëueÝ0åñ´Í¸óóóë°îâÅ‹¬çw3„#FtèBimmÕù4²téRRÂ|„×ÖÖ¶ÓÔß666àr¹°²²Bcc£ÑO‚IRËžW_}Ug«WW—Óó´¶¶îtèÌ™3‰O=õ«¾4hêêêúä àááÑ¡!ÐÕ¸d}cCDw˜MoNNFÝé:>Ÿ¡PÈhÛ!C0dÈFï}ôQ·“ºëâ0&uuuàóùš€âlAS~ ¢Ÿ ïµk×0cÆŒN×YYYÁÞÞeeeF-óÈ‘#xñÅ»\oŠ.ƒ¶Ií'Ü>3aljµºÃ8\c1a¤¥¥uX…ŒŒ ºC ÞþFwQ¾ >Ÿªª*£•Y^^§³kdÅŠ8xð QÏõܹsxì±Çº\/‰Œzžú" ;ÆvçΓÇ&ˆ!¼]µnô™öÖ[oáÓO?í°¼«—:ÆÀÚÚ}¶ÿ’-?uÅÑ£G±|ùrºË¢7…÷á‡Æ¥K—:,¿xñ"yäFû<þ<æÌ™ÃªÓªªª R©tæ.këJè.~‚1[èðâ‹/âèÑ£¬ú£íE"Ñ»lÛ¶œ@ÂÛ9½1Ô*$$¿üò‹Ñö§T*¡V«uöÓ6 PQQa´r>¬³OÚ?|ýúõnã`ˆD"TVVÒÝÔËHx;géÒ¥øæ›oŒ²¯ææf466v;) ³ÌMMMP*•]Ζ#þB×hcÐÕl»7n`êÔ©t^s£©© µµµZéàõ¥¡¡MMMÝŽÿuqq1jˆ¾ˆˆ¬\¹Rç6NNNP(F›ñWUU¥×8ç¥K—âßÿþ7«×pæÌ™HHH ;‘ áí ô®4}út\¿~Õãz饗pøða£íO.—w9ã­ KKK´¶¶-À¸¾ñ(pçÎ>ÓZf“ÞˆéAô_,Lµãï¿ÿ^Óï§«ÿ¯¡¡2™L¯ô;mq Œ{÷·ß~ërÜpw´O¯Nü5¶}ú÷òòrFO#æHFFyä\¸p.6a¾-Þ|b±b±¸Ë)®l2tèP­€Ÿ~ú O<ñ£}EGGãñÇïv»×^{ _~ù¥æûåË—1{ölFe^¼xQ¯—««+jkkQ[[k¿ÕÖÖbðàÁÝn7{öl\¾|™î(‚èMáõöö†¯¯/|}}µ¦¸zyyuˆÅCbÓv5”Í”8::jͶÓWÄ:£¦¦F/[KKK´´´-³ƒ®8ÉÆ‚Çãiï×_eË–ÑÝIð £MýýÇ?þO>ù„Õã—Édpwwï—•ÁÞÞuuuF{¬‰D+‚™®éã„ñùõ×_É ý]x{‚©S½ëÓM‘‘‘“—¹nÝ:­¬ñññ d´/}Æâ¶ý(ÖÔÔ@¡PòòòðÀ0*Óá?û"¹¹¹fŒßÿ=)á@ÞÈÈH<ÿüózm«Oö^}hmm5(XPPâââzµ›¢®®¶¶¶ŒöUWWǨŸ}ïÞ½X·n~©]Ê"C"š5 ÅÅÅ]ÆÁíËüóŸÿ$•!ÌOx{c üÅ‹ñðó~®ùùùŒ[†ˆøøxVÏmܸqJ¥hjj2ØvÈ!¨®®¦Tï ¯)ñôôdœÞ†)º²3˜’ûßö§§§³ÒMŠÓ§O>ýôÓ.³s˜Š††p¹†W¯úúz…B“…¡dg² ¯A¬[·_|ñEöqëÖ-ƒDÌßßß(ÉU*•Aݶ¶¶½ÝÌб´–––hnnfTVÛÌ7©T WWW±,º";;ŒD› …õõõZLZí]!0lØ0’Ú,úêËårÑÁLEtt4k9ÄÜÝÝ‘ŸŸââbÆ/Ö å“O>é0ÊÀ·¯¾ú }¦ȸLº# jñÆÇã1~ËoaaÁØ–Éø_‚0' ëùIx ‚ÐDEE± ›„— ½¨¨¨—ËÅŽ;È$¼A°Áï¿ÿŽÉ“'÷JÌiÂpLör-<<\«æýA° ¼ .ÔtŠóÍ7äi‚ X!77—.]êÑø>+¼÷)g’‰€ ÓSWW‡ÌÌL$&&bÚ´iýâœT*îÝ»gÖÇH}¼1€Ùµk–,Y¹\NÎè-^‚è $''wȇvëÖ-r A-^‚ Ì‹––³œ7”}ûöQ‹— ØÀÏÏ~~~ZËD"9F™™™°³³ÃîÝ»ñÞ{ïõ›óJII¡/AæIVVÆŒÃÈöí·ß&’ðÁ---àr¹¨««3ØvÏž=f{^{÷î%á%Â<)**‚P(Ä!C ¶MKK3Øæ—_~Ass³ÉÏ+55•„— Ο?opT³~ø‰‰‰Ù¤§§ãðáÃ$¼Aô’’’:¼ü4MMM‹µJ¥Bcc£Áe™lTÃ_|¡ÉÕßrGÁ•••'zí ˜Lx—-[•J௴èAl //¯)¼÷gM°° áÂA°ÃéÓ§jÖÇH}¼AX³,Ö$¼A x.\¸€G}”„— œùå—_BÂKÁ%%%˜2e ÊÊÊÐÚÚJÂKa(îîîÈÏÏ7ÈÆÁÁP«Õ$¼A†„+W®°R /AýŽÐÐPüôÓOf{|$¼a"®^½ŠY³f‘#zȸqã Î 2{öl\¾|¹o ¯®_/µZ •JepY …|>---z—¥P(`ee¥ù¯ÍÍͰ´´4ÈF¥RËåB¥RuêóÏ?ÿ+V¬èÔVsUE"ÜÜܶ¶¶°°°Ðª(R©"‘H+C{<<<´*u+W®DCCƒÎ“HNNFYY{ì1Voî;wbãÆ¬–yèÐ!,\¸ÕÜ^ÅÅŸrå ž{î¹>#¼ÞÞÞzokkk«©¿"‘\.žžž¸råŠÎàÛË—/ÇòåË;<í?Þ ÁñMMM8pàÖ®]kòúÇÄæë¯¿FHHô¶iûAš9s¦Þ6eee8{ö,–-[f–~سgV®\©·¸À™3g0jÔ(Œ?^o›ììlØ5Âëåå¥Ñ'>>¿ýö®]»†3fàÉ'ŸÄÚµk±bÅ ¸¹¹!::...Ý„¾­™L±XÌêÍýÍ7ß°^æ… 0}út899±VfNN Y?W¶pvv†³³³æûœ9spüøq <öööxê©§°~ýz½_vy{{䫆†œ9sÆ`ÿ2©Llbcc1mÚ4Œ9Ro›êêjp8ƒÊ*((@VV–Ùúáĉ˜9s&lllô¶ÉÍÍŘ1c`PC í L§ð¶gúôé¸~ýº¦ }íÚ5Íc““6oÞ z7ÿÍ•3f°^¦ŸŸ«e4È _ì¾ÎòåË¡P(`aa>Ÿ9sæ`Ö¬Yµt ÇãÁßߟ•úÇÄÆ××W«ëÄT…BLœ8ÑlýàïïÏJ—§H$ÒùĦéãímâââ “Éð /€ z“„„dggwè‚hœ>}?þø€öÑ#G nñvã%‚`³iñ¶™Ð÷Í/A˜Š¶7ö½.Ò=ù??´Æè“-ÞŠŠ äæævº®±±µµµ€¬¬,¤¤¤ %%UUUšÏR©”TÁ ¹{÷.nß¾Ý麦¦&TVVj¾—”” ¨¨MMMšëÚ6Œ±·¨¬¬DNNÎÿZ#ŽFlêëë¥ïp¹Ü~+ºmõ¯°°P³,--M3¹ãþ:Íår‘››«©Çm¶]µYSSS»ÅÅÛ²eË6NT©TbÇŽÈË˃……FŒ¡µ~ýúõhll„¯¯/^zé%XZZ¢  ÕÕÕ8räˆ&›çرcIéÌŒ°°0Èd2( ¸»»k­{ÿý÷‘ŸŸiÓ¦¡¤¤‡‚ D"bbbPPP€ýû÷cñâŽrì---ؾ};òóóÁåráêꪵ~ß¾}(,,DAA|||èb÷""" “ɘ˜\ºt iii¸qã°}ûv ¹¹r¹çÎCll,‚ƒƒ‚‚dggkæ0´qìØ1ܺu 7oÞÔùòËf¯©©A@@²²²:¬æ™g4Ÿ'Mš„””ܹsÎÎÎàóùHII18æ¥9³zõjÍ礤¤>ݪ*--Åܹs‘’’¢óº¾õÖ[prrŸÏÇСC±fÍ$%%aÓ¦M½úy÷î]"33³ÃúÌÌL¼òÊ+ˆ‹‹ë×BÔØØˆ>úï¼ó ú½ðJ$¬Y³–––hmmE\\^yåMËå˜3gRSS‘™™‰ÀÀ@ܽ{­­­HMMÅš5k:d‹×^{ æÓÕp?wîÜÑzļ&ËÊ•+ŽÁƒƒÇã!,, ááá8{ölŸ¿àÕÕÕH$¸|ù2ÞyçÀ¿þõ/M7ËâÅ‹‰C‡¡²²Û¶mƒD"18HHoQUU¥%`÷?ªòù|øúúâÏ?ÿÄ7PQQW_}?ÿü³ÙEEE¯w}ôiii(..Ɔ ÐÜÜŒ­[·â­·ÞBLL är9Þ|óMlذr¹ÑÑÑH$X°`N:¥™h±}ûv$''C"‘ ,, ÙÙÙøä“O°~ýzœ={¥¥¥xã7ðöÛo£¬¬ Û·oïPÿÙB©Tbß¾}xâ‰'z”‘¸±±IIIæ—Ïçcøðá8yò$¦OŸŽÈÈH¼üòËšõ‘‘‘ˆŒŒœ;w«W¯Fuu5vìØÕ«W³šÉTØÛÛ#<<b±XSñæÏŸšš€bcc!•JqüøqüöÛoàñxfÝ¿íéé‰ࡇBtt4ž~úi­ëzìØ1¨T*Ì›7GŽAYY„B!>ÿüs9r¤WSqóx<899áøñãÀ÷ß_|Q³~ÆŒذaƒV˽?"•JQTT…B\»v [·n…P(Äþýûq÷î](•JáôéÓ‡ŸŸÊËË5u7//Û¶mÇÃÝ»wQVV†k×®aûöí8qâöìك͛7cóæÍ())A^^ °°---¬žïÖ­[ñÝwßa÷îÝÈÍÍÅ3Ï<ƒ 6hº<<|8Î;‡I“&áoûë]Lüo}ÔU7ÛlhmmÕZwýhÿ½×…—ÐîrÉdðóóCRR¸\.|}}!“ÉüÅÑÑR©µµµ˜4i"Lúè}çθ¸¸h}n#99À_³.«««‘““ƒýû÷cÛ¶m¨­­…­­-š››áì쌔”ØÛÛcÔ¨Q¨¬¬„³³3d2ÜÜÜ´êú©S§`eeźèš$¼A0âæÍ›?~<ãéïqqqý6vHwü?ëOCâ³9âIEND®B`‚snd-16.1/pix/randfm.png0000644000076400007640000001716211147553270013124 0ustar bilbil‰PNG  IHDR .Å­^+sRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ 0ÉP&ÆòIDATxÚíÝ펛0ÐI5÷ËìÝh)õ'¶±s¤ªm†IC’÷‰mølÛ¶ýüÏ] € €,>ŸÏÏçó¶=p£ðù|~¶mûÙ¶­¨ð¯Ý¸Öï]š .õ/ ¡ `$ú³p¸&$Xœ ÷Ô<Ýh¿¹dm@íöÀÍBB¬ØOáÖeMð¼`í €\áW\^\q®aº $/ ¦€ðóóóßõ ߀ (€ a¡3 / € aÇ©FŸÏÇ"f8á6W\Vð€ð—ТäPpØŸ¨÷è5 ®ŸBÂ_áëóùa€·‡„a^J×3/ ¹«0 ð‚ ßu ¡k* -„þ ÇÓ¦  šŠTrzTa€·¸Í—¯(ÒK9· ­m€'¸ÍH¶mÿüi½¿Xðˆ-pŽ£  ò 5¡#4¢ð]¿ 0pw¿º .PìC@*X|·3% €»qv£D ƒ³Ž÷aÄ!á!¡áøïÜï|§ O­º B‹FŽ€ðà‚ÿ¸}nêÒqÄáø³c€!á¢d Ã1hœ]÷º2´Ñ„„Æ¢~ÅûÎ]§¡ô¢n©Ña!áÁ$,B§`-ý–©LÂÀ»Üæ: 3 ÕÕ®uв.¢¤Ÿ÷#¡ðÅ(¹J5ë»ÍHÂ÷[óýŸ;Ë]˜mÔóËMe:ÞbS™Ly^ëlÑÝkT õ¢oµ¿_º.bßg§< BÂkCâ½ô K¹¶ÇFά‹¨Ùn:Z„3> ‚GÅïô1­÷ÑcÊÓ>L”Žf”‹ÔvB³ÖE”´§4Lô¥(Ý®älP%Á@H`é°Ð»Èï5å©4L”ÞoïàS:BÛ¶Žh €ÀÔQ».¢$P\nBÏ©×Õ¯Ï.ünшm_:Î@HàFÅüï?ô³Nu[»€ûXÔçî{ÔˆFM89@baälè8Þ_ì1!AQƒ‚¾W;Ï~sŸº¿ýYž®êç‘gµ1òQ»Ž£&€Ô„Ž3aÄô¬Øã€‹¦Öë@Ôž÷™j{.ÈœY/Ò+èócèèqÑA¥Çô¬3Û…n!!ða~ü£€&zÝç™B½¤¸­iè±ØûÌ}—>ÿškgô¼ÆÆˆý¾BPÉmêÓÞAåÌuFΜ&XȆ‡Ç?¬]Ä?múf=U”·Ê¡öÞqŠÛñ˜zJP‰…–+HÍ}…ú­d!{ÏÑ™Y#:¹P $ðŠ¢ž9}ÖZüçÂDÍý‹ëQ#7‚ÊØ«–Ÿ9žjBÊ•aæØÎÑSÏjn[)Ðôý骜„„àE¯têUnŠRªP½bÄf… rÅ)|SÛÕ¶¥$¤´žBøg›–jƒO.Ü”†¥³¡ªd4ifXšÝ†XŸ´´!ö;¥û¥äX…˜^öhë*í^½ÿ®Z ];ªÑ#¨œyNWM-»ëñv&üåÂD¯c°åÌ`³‚ʨþ?‚z…¥ãèψPUÚ†Ò‚öÊ6”8b·‡~v¼ý¸MìþV{~WÞ¬/Ïî—§õã™þ¹ûqWóE°Ð¥ݶígÛ¶Aèv®ûpžõA?òq/pý{¿×]¿ºxRñ:ªØÝoêCéû¡šŸšG[º}i;¿÷•{ÜØý§†òKúhÿ¼Bm ýÿL¿Õì³Ôã¶î—–%ÔÎXÛK÷c®ÿcÏ+¶ßSÇBÂRDë›2ÀÙ@Pú¡›ŸZ36UèçÂRèïPñw6”ôQj~n,Ô•öCIH+ “gæ7Ÿ9&jÛY²¿R·§ú¿vþtêx‚7„·Ô¡K‡„Ø·7½¶()ÎÎ~(í·+)Äïþ¾Õk§G?ƒ@Ë}Æ~·Çó=ÓÎ’íK?3ŸrìñÞ/sB¯‡X=Øëö·Ô¡Ë$„:9ÕñÞ耑J­ï1=¿¹_©ø_ñyõø¦ÿŠç[ÛÎÚQ¬Ù¡®ªK~Þãö·Ô¡Ö$*âCRo‰RßZÕ~°Õ_½ÖYľ±ŽÝhzªŸsíŒÍ¯)ŒÏ¬Íˆâµí¯iOÍóª]{PºSS»rNl¿/ûLÝ|õÀ áȯÙsîÍùf3’Àm‚Á׈zôýÜê=×H°çbj€ € € € €<$$|>ŸŸÏç3l{àF!áóùülÛö³m[Qá_»=p­ß»44(¶mû'„|ÿà!!T܃Ã>@¡€—„„Ú ±à‚ðý6FAþ}Ì™m€×†„ýôž’b¼vû^Åú(¬Ÿ·Wʹ° Ç5 û‘Á€·{íÅÔ¾§a^b!`ûwúÓ~a3 U!A@€G\q¹w`°€!áJÎR´3Ý(H¾¤gj"žb¿6á{ŠÔÖà« $CÃþïãí $,è»Xú{uæš>¶ml½ƒ3* $Vk8ø¶ïê)O¹û7å X6ô*Æ[ïkdѼ?¬!á¶Åûªß4Ç®ÉÐúÏ>çÜEåf‚Ò³<]±hB—‡“–"üêuWMyеm® /‚ $<ЊSdF´gôºˆQÅtÉhƬ«_‡Î0e} $°tXéµ.b?Jp&”§]°®|¼Ðó¼2|΂  t*(ïVzLyjmËþ,J©¶åÚÚÚ–Üs½zDj•³M * $pA±·BHéÙžYkBcDP¨=%mï>Ø?Æì³M *‚ B ­ÓbE{k[zß=Ï65"صÜN‹ûÆ r‡"( ÁìØ·Œ3 ×Ym¸Û)XŸRZúÿlØHM™êUd]5šÑrZÜ+/ò÷Ö 2;(Ü!¬ð $ –ýÞJ?VÔÝý¸i9ö{¾=¦^•YÇ 2º ,=¶F•ãþ™TŽ_Ȭ´^PY§Â T£okƒvÔµçìhB¯°Öz½SÀδ«×¯rÒ;.n¿2¨”ôňÇ<†’ýsïqaÅ»•ÐßWœ2y…ÑŠ»„aI`CH€)…JËã¯ò¦Ý³¸:Ðgžã¾È:;š1jMÇ A%7õëŠã¬G°½sP)¹*ûÕÅßñú3WôCªVhÃïµÇ :« ›Àvu„nY¤_Q ÷,xf¾œ-†{ýΨã¯Ç~Y5¨Ô°g^µ!%õúo}/¨Y'3úC9tšä[LíçÖȬ҆…Yj”犠 *³Û0²J›6ôiƒÀãŠó7¥Ò>_uØìiW³ƒÊ¾ý3‚Jë7å­ëSR¿STZÃJMX:ÞvlÃè rü÷Èbä8ªS¬¯hÃñ5jÛÈ÷ûcŽë‡®z?:w¡“/Ì lWÀiø6 póДúPº¢- ÉßTfž–÷؆³ýÐc4¥×EG‡¥’‘Œ+‚JêØ5ªSsülCËñÚû=㪓¨”„¥Ñ_ åÚúòcôgNhJàÌ6ľºs„„Æ4«ð¹Ã•—õ+ O *=^­¡åñ{¶^×Rií‹^A¥õÄ­£:Ç߯±¼º %#L½‚Ê™~¸:,õ¾ðhéh_èß½?£sg-Œýìª6ä~vÇ6 7÷Æi>¬wlÌÍTîû¾13¨ôlà }ìTzžUÚÐ;¨Ô>ß³a¥GXjmC*(¤‚Ɉ6¤[îïÒÀÓ£ %ûänmP. íAåMA¥ô (Oݳ¦žÿ>3ªÓ3,µŽ,Í )ÇþxBX:ûø=ÛÐrr…Öâzߟ#ÛP–zL­¼² B dûBPTº=ÿÙû£æôÄÂÒ=¡Qï‹#N½BXjý|¸{`k {½Ûp昘Նۄ„ýYV¸È >èô‚ŠÀ:ºÐ½sXZåX8»Vç­muúîšãáÉm¸Ó{ÊmBÂ>A­²Ó|­ñüÆ5‚Š}Á*ÇeîX\!,ù2Ạ¢ j…»Ö.³C¼éFŠcAÅþxüãÛð¦ããaé-ï wià ÓW™’ˆÀCŠoåX5¨86×{¿š–Vl³‹¤ÙWn^­ +ì Ïû}5E.0 Ü> ¬ÔŽ™o,½ÎîƒïYoü«ƒÚðYêýj…i»«Œ.­pl¬g~^_ýÙ:ãÒŒ6„.‚6+¼†žû¯2Aå9x³ûİþšAåêcóxQŸ™#:+µaæëaf[bm˜uL~_—3‡c®z¯H½.fž`aæë4´/ÞÔ©÷!TViËÛÛ0³ …ƒYaeöã¯Ø†™ÓZ´aÑ‹W]o)Œg½WÍî‡ÔœßÞ!„mT†?ÿÙý°J¼.µA¬×ar»ñ^Zá›:x —!ˆ»Íš¾!á/±óê}™n € € €¬>ŸOðÚ±ÛkøbjŸÏ'zA³ïí±mZ¶ 3ŠùÚ‘  Í·æÿÍÛûoý·]Ñ@á®õ[Z˜ï¶Ò4¡ÙíX¡/´A´A´A´A´Az¶áÏÈòM?ÜOÑš„mÛ¢Óö?+I@µÛ †„\AúYíöÀ\L !€3>›UÄÀŽ‘@Hâ~Wo`í…×\¨ àùbúMÕƒ½nCú»úÎÿvòþß½¶àža_çÅjÀÿ~KjºÀ€¯Øí¡Ÿ•Þ~Ü&ö8«=ï»ï·’}uöxÎñE°ð˜€°mÛ϶mÿþ5·óœÂD‘ýÞw½žúûÕ}‹È«‹úÐã¥>0¿¨¡¹³¡9¾¥Û·~À—¶'×ßû*¹ŸØNlCÉ>Ø÷[¨m¡ÿŸí!!òAð¶ÄT (ýÀŒÍ­™ã›*Ä[>èS÷Ÿ{nûßËÝOÏö‡î?579&Ï̱a›ò¸o¨C— µßœø¦xºTQ[ó¹ß®¤Pýžz÷÷ìÑ£G>Ó üš ¾ÅêÁ^·¿¥]~$!ÔÉ©Ž÷F ¼õ³õý¯÷ÈÀ[Šÿžýô αŸ÷¸ý-u¨5 ŠÊcá8ò¬Ô7jµº5îèõÇû?ûởXû}Z[pœ¢•ê‡Ð¾,¹_zS?Ï6ïB J>^îËH] ÷ç: € € € € € ÀCÂçóùù|>ön>ŸÏ϶m?Û¶þµÛ×ú½KCsb:¾ÿÞ¶Í€§†„PÁ¿¡!(@½G,\þ\HÝ  W/NÞ…ýº‡ý4$áòš§×ôÞ¾ghÙS‘`PHˆû©üêâ|ÿx‚¤=òbj‚ §YØ BÂÏÏÏÍ $Ä«?Àÿ=æŠËwy X¾öÞn¼ÊwÄ©T"€·û£ þ& $ åœ !ŸŸŸŸà„A!»ˆy?Ò°.Ò€ðBû3!}CEiP"nì;ŠPrѵÐÈCìwBá8"!H $Ü8DÄBÅþïпS„®ö« êÕ\Ä-´M(T„FR£ûÿ»¶¯ «|£þ-ÈíÉ걟—øÇP[ Pã6Ó¾ÓsöV £îï8º›ÒT0jP?-ØðÐðf©@PrF¥žEn6BÂAèöo¿_Z } ±ŸåBAêçûÇîÇÂ儊}ñ^ú³ýT§Ôšˆc؈MjQ³ÆÂz !D@Øß–:sRè,J±ŸçûÊ"=vF(A@H N³Úzg34å(6]j¿ýq›Ô)_Á¦&(ÿ²&.!·}ìŒT¹µÇ)LÇõ¥×¬HÍ)u Š’ík”þîq½‡µ€Àô 0ò±s# µ##©Ÿ… ío~\wq ¡…Ý£dGLî°\€€ç1݈i…e* ¤ŠâÒÑŽÐïçÖ_„¶ëµÎ!¶f"÷ÿ+C]ÍÕÄïvl]ñ˜¦¯ðF˜¢´ jýyjÛÖßÍ"6T|o ÄBl:ÖÈÂ75ëXÏ À‹CÂ~:HMqÆš¡çv©ßýín¨@>NqÚ¯¹èùK×N¤®ƒ*øcEI ¨YG‘»xéö³ÃCîz#ÂBÂàÂòø‡w„…ÕÛ ±p:ƒSÉÈÉ~JP®8=Nƒ‰-ˆ=vnJTê±ÎŽ0Ä~¯ä€¡u&¥!¦W‘]s=Ñ¡¢÷¢{@HN‡Ç"µf±õ™3F¥ úc@ !êx1¼ÒºãcÅű˜O‰T€‰…¦XÔ¹-…pë¨Bï"üL[zØäöíE?ö ðÜþêǹr”$t}ˆÒµ-£r¥ Ȫö÷bEx®¿¿½É­³HMq, …%íèbS j×ÒÄžoj&7½­%¬”LuQ(®öRÏṏ"à&¤ÇZ‘k/Z?· ;wÆ«’öÔœù*4ºRZJF8R£ ¡Øï¤þ®Ê…—T€(]‹²oG¬Ïj×¶”NJMW« ±}Õ`Îþ~ß›UðßyÎ̶ d÷qvDõ!\Hnºr¡©ætºÇð µgæ*YDŸºàà1täNñû;böÅ{n'T𷄸T¡ºÿT€8î»’u'¹…ò¹}’ûÐ1ú:#Zî¾Z ™Ö‘Šž÷=²ýǵB£ÏÜ6»x|[¼„`B¡Þã1F?Ιé`±âºw_¦ŠøTÁßã9å~7T,§N \ºP?TˆÅ¦¥åÖÑÄ÷Ø©°Z/SS|„îãØŽÐÏkDh?”Ns õoè"’©vä¶ õEh}P¬]¹Ûs¡+t,y–†¿Ü™íjÂYë…3φĖ8œéëÖàÞ¯¬¹c¦W ½"< •A¥å=~ ½Cà¨Ó÷†ú»ôÌu©Eò%áðXô–­ØÉ RW—Xl]è;ÃXn?æÖÈÄ~ý í§Ø™Öbû=wv¸T±{ÜTá ±u<±“EĦ ¦NZ{  ©xloiŸê§’é5ëJú(vÜ÷X“ëË3S S¯Ýëk§,¦žwjŸ¹â2ðаâ}­Ü'­gÜêýX½ú½tªÖ™v•öAîwRu*€”ô[ɈPì¬a±íJ¾ýÎM;î›ÔHRht¢¤?J¯™SÚ¶’³«ÅF¼jöKêØÝgh¯¤ocÛÆ¦b†?vqÐÜ•ésk¹Ž÷z¼šç{^¡ÇM½b÷ –±×Oêôݹ0ê›Øèkè5ë!€W…À‘gôj 4¹k–\ùc߬·„ª«÷l$©¦ð+9“Zm«ml­Têlo5a§¤ .=›[,\´„éÜÉÎîÛPc}û¦>6‚”kGnê\nû\éñúl7þZ¬æ Æ}÷ø,îu?W=Ö•íÕ>gÚú–6œ©ÕZî·dTiÄñ-9Óö3£µû¬dWÈïÞ€€õôœv§6Ïø’²G‘zæ9ëq¿½Ûž{쳵镣ƒ-£“· µC5BÙáF¿_¿?[ÏÈgºð§@„@H„@H„@H„à*·¹â²«+€ð—ÐU•èÏt#@H„@H„@H„`•ðù|‚×&ˆÝ^{?À|ÅSû|>Ñ š}omÓ²=°`H˜QÌ׎Lm¾5ÿo®ØÞë¼íŠ p­ßÒÂ|ÿ³•¦ ÍnÇ }¡ Ú  Ú  Ú  Ú  Úг F>oúà~ŠÖ$lÛn´ÿYIªÝX0$ä úÐÏj·Öàbj€ €œñÙ¬"vŒ$B÷»zk/¼æBmÏ»ÐoªìuûêÐ?«ïümÛþ¹âs¯íxW!~á9Çï·æ;Ö}±z°×ío©CM7Š ‡ÏçüYéíÇmV{mmOk¿­Ò?¥„µíKõÏ…DçpçB=ô|{2gïçêç¿ÿý™12Þ¯.J ¹ïrË¿õÛ3ú§gq9㹿ñøý|WïÃØžwŒ#$‹-vêÍþûaš÷šŸZºýªýv¦ömÊõOì1B¿›ûŽõ¨m¡ÿŸÝ-…Cíqj{iRÒÿ-Çs˱Ûr?±>«}Ý¥žo,ðœé¥€ÀƒC‚ÅÉpß7óTÁ[Sl…ŠˆT1*²F†úgÿüRÏ·w?„î?õ v(\åŠÂÖoÄ¿úýÒãd¼Å¶« ]µ·¯6 É5¯»XÿÔôñÙׂ:ô†!¡öÛ’žß®c^Ó±ëš7ûýv%î]ÞzõÏJ!gTÿ´~®„î+v\Íz.O:žkŸã¾ˆ…̳mòíós¾t 7±z°×ío©Cïø&“êx/z¸ç›}o{}#¾Ú›ü삦æ¬W†Ö@°ú>½ª?c#*3ŽÿØãåF!zM=ã^J§ޏý-u¨5 À?ºÇÔ‘ß¾¤¾ :SŽÚþŠ~»²B߸Ŷðø|sýzÎ%÷³ÚTš³í©½ŸÞ‹ÃGþ©)\¥Ï+Ö?±é]³ö#¼ª&ؼRþ)x¼5>kŸÚŸeýâø„ ÈÅÔ€¿ü6Óû½Z1ubIEND®B`‚snd-16.1/pix/t5sum.png0000644000076400007640000001173711147553271012735 0ustar bilbil‰PNG  IHDRNMFÒ$sRGB®Îé pHYs  šœtIMEØ 'ê¦qIDATxÚíyPçÇß¡J@i°[;(`MÆk¼ Neä˱Œ­-0Õ±Vgìt´µ^µvœ¶Óqp¦ŠµÚ*jH´HÔXׂ(`‘K‚Ü!›ßû›íöÝ\»›cÁ÷ûWv“ì~öÙ÷É^y¾Àd2ž©½½Çñ—_~™:³¡¡A,ûøø¸r¥Öål$$$JÈ7 ƒÁpáÂzÊŸ:uÊÙ+5™L999.\ ÞºvíšZ­.**¢Ë©HHH#&Õ‡‡‡ïß¿Ïô[999 ôù‰äÏ?ÿ¤¿uíÚµžž.¨äJ/^¼”–––——§R©JJJ=z´dÉ’òòòòòrëHååå8Ž£!…ôb¥ºÉdúúë¯'OžLLþý÷ßW¯^}ðà1yÿþý›7oVVVºººJJJ4Í£G555¯¼ò ñ±ÚÚÚâââ–––âââ¡¡¡Å‹Ð×ÕÑÑ144DŸÏb¥555€°°°ÊÊJ…B1cÆ ÀŒ3òòò )((è‡~@C éÅJõ“'OÆÆÆN˜0 V«óóócbb¶mÛ†ã¸J¥zðàAdddYYYqqqVVÖüùó¥RéÇ:ŽX£G ÃóçÏûí·[·n544½^o'»•&%%Éd2ÇÕjuJJŠV«õòòŒ;¶¦¦âP‘‚‚‚$‰B¡@£ ‰‡òtÆBõzýíÛ·?øà2í7nÜP(B¡ðèÑ£ß}÷ ""bß¾}IIIo½õÖœ9söîÝk4És`±X,‰äry\\ܼyóÈ‹r-UUU7nÜ”––655?°zõj‘HÄz¥„²³³÷ïßìééI¼…ãøøñãÃÃÃ!iùòåééé hl!þ£znnnbb"99a„ÞÞ^âî—^¯‰DýýýıÔßßÊ”)jµzíÚµ‡ …Ô+aÇ1 ›={vmmíÿ™<ÿým ÏÈÈÈÈȈ]·nñšÈsÖ+(•ÊØØØ¹sçb6sæÌÎÎN@{{{xx8BDEE]¾| ,¤Ÿêõõõ;vì8þüÖ­[¿ýöÛsçÎ}ôÑGлK—.ÅÆÆ’“Û¶mËËË+///,,ôòòúòË/åryEEE^^ÞöíÛ/\¸€a˜§§çâÅ‹Áرc‰omß¾ýòå˾¾¾UUUÍÍÍÄõ¿ýO¶Ø­T¥R}òÉ'ëׯ_´h‘V«MKK»}ûv___iiiEEÄc)>>^.—£…Ä;™êâÅ‹ƒÁd2ÅÆÆ644˜L&¹\NýŽãË—/‡¾…ã¸V«Åqœ˜4­­­Ääàà`OOOOOñÖ±cÇš››M&ÓÐÐPww·Ñhìèè ÞÒh4*•ŠŽ¤R©ºººèóY¬”.NWZZªÓéè<–V¬XaBBâ™§z]]‘*‰„:‡”V«•Éd¬³³³éóFã‘#Gȼu¬,­Ôº,!­X±bhh-$^‰ñm¹©S§îܹ3þ|êR­­­'Nd}–áå啜œÜÖÖý‹¦±±qݺuÀ§6–Vj]–ÚÚÚÈ€êêjµZ }L&“ùùù¡óJ$^ß/**zûí·‰×OŸ>ýõ×_ýüüÖ­[ççç700@^úºÿ~KK wÖþù‡oá#‘¢¢¢ÈûsÞÞÞÔ………………¡Ñ†4"SýرcÄëÎÎΈˆ©TJ£¼¼¼¨ÏŸb±Ø××w”ßÞ¤ÜÆ3f õ]³Guò¹ S½ººðÊÊJ ÃD"Q@@Àرc‡‡‡¯\¹9uêÔÀÀÀööv(ÕÅbñ‹ÓÎÎÎÀÀ@tTGÙ©NŒÚÔÔTrNssóÂ… ŸiVKX;::îÝ»7<<Ì¢7+•¹§§§´´´¿¿Ÿ¾^û{³Zik“ÓÎØRm3?~\[[ë@NëûŽ]ßÛ²²2êBø[ˆÓú@5ËigTÛ‰µ¨¨hÇŽ&“)%%¥¤¤„øm3™Lï¿ÿ¾R©$?·sçN(dNmrêÊ6¬dFœ®ï{‹bk§:®­­mÊ”)qqq¿üòKiiéÀÀ€L&ûæ›o|}}·lÙBüŸÝc‘ÜŸêÄ«ÌÌÌ„„„äädÀ‘#G,X@vkABBéòðññ©¨¨˜?>†a111J¥rÞ¼y3gÎÄ0 ú§Ò•gDDDGGñ,áûï¿'žy>ê(@HH£ç¾³³óñãÇo¾ù&jW€„4ú¯Õ‘F±áJu$$$”êŽÒˆðâÎŒ°Ñq/6›Tw†÷ ÙANOTñÄ/‰˜4™L?ÿü3ñâúõë………„åÓHÁNpÑr8v`` Ûᨠº/wl'¦º3¼‡ˆ×T{ Èé úSÿ)ç1®_¿NØ¡E£¹¹¹wîÜ¡Ñ:¶+CMÅæâ¢å2l(¶#ÂQ‹>$ _0{°èTÅ8ÕíñÌm}Àí §'ÀÍŠ3Û sss³¿¿?ñzÁ‚6l0™LÝÝݯ¾ú*`b™äâPS±¹¸h±ÆfêNÅÖ-ŽZ,B aC¾`ö`;ЩŠëµ:Ý{°µ£¢ÚANOÜý§1C–I«W¯6Ël2™***$ 9\^zé¥ãǯ\¹ròäÉ.°ybj?Ý© ØºÞQ‹]¨!lÈÌÅfUž\¿Oó¬l} { ‰DBuzŠŽŽæâ?Å”²LÚ°aƒYæ7nDFFR—}:o Ô©²Ç 0)ö¦ é¤R)qãŠø™ã^‘n'ÒáÇ-mwGåToÓÁ`0x{{3>‡ ˉ™,Jy‰æpëׯ_´h‘V«…ЍÝ[ NÅŽˆˆ°Ä Mò¶jZ¬M/¦Øô!Á¢"‚LII©¨¨ *½ÓÓÓ¹CÚdÉCÁŽ(ƒ· æåååááÁ¦ˆ*,wMÕ´³+½­`óªÒÛ!¡¶îÀ¢Ø›>$XT¤C(++cQüo ’Åî¦n—“Ž Þ:˜^¯ß²e‹êÕQù1Âæù°Ÿ‡·¢‚?¾¤¤Ä=õê¨üaó|HØÉÃÛ@‘`ƒƒƒÇŽûøãªWGBÅzøðaHHñÈöLôT¦S’¡IEND®B`‚snd-16.1/pix/randsq.png0000644000076400007640000002117611147553270013145 0ustar bilbil‰PNG  IHDR^ÿö/bKGDÿÿÿ ½§“ pHYs  šœtIME×  :À" IDATxÚíÝyXTÕÿð7‹l±3(» ¢¸D†R¥b_\ E¥zÜÚIPù•ä*’F)åJ‚¢¡H¹ô%Ñ r–DÁA@eqdfîïæÎÂÌ83lŸ×óðŸ*„t+mi+oß¾ sss±ë¶lÙ‚˜˜ÀÃÃC¸<66¹¹¹^+ ««‹;vP“nqöìYxzz"-- =‚‰‰ ''{÷îy}kk+V¯^ gggüù矰··‡““U$Q}àõðð@QQ‘\ô÷÷‡¿¿§e©©©X°`^Ò㸻»ÃÝÝ]d¹üýýáììŒiÓ¦áܹsx‰zšJJJPRR`³Ù7nœpÝСCqéÒ%ØÚÚR-’Åb¡²²ÚÚÚÐÒÒ’»|Çy@ˆÊ¯©©)\\\vvvøòË/…ë–/_ŽÛ·o#88˜j‘ôx^^^°³³Ãüùóahh(S™ŸþYøûæÍ›©‰Òh¨cEGSCmm-Õ8é àçç‡qãÆ!%%yyyT1DõW¼„ôgS§NEdd$æÌ™C•A”J›ª€ñ†Š9sæ`„ `iiiðöö¦Š!tÅKˆ*Mž<Æ ƒ‡‡Š‹‹©B]ñ¢j³fÍ¢J tÅKHwppp@UUz#x QSSS466‚²¨ ¼„¨Ñúõëáïïììl$$$P……©¬·°°[·nTVVRM“^ÏÂÂ3gÎÄž={0~üxªÒ󯋋 ¢££üo!½Ýœ9sàèèHYùÈ3¡¦B¡ÀK!x !„Pà%¤û£©© ùùùT„/!êàè舲²2JìO(ðBHoA¹H¿&iÎ5G•C(𢠒æ\;pàUQjj „ ¼„Ò·Q®B`aaccccøðá"닊ŠPVV†©S§Reõ]ñväjˆŽŽÆ²e˨¦IŸòÍ7ßÀÌÌ b×744`çÎTQD½—þìàÁƒ`±X¿Øl6U ¡ÀKˆª´¶¶ÂÖÖµµµžtOûù矩b^BT),, ëׯ$&&R… ¼„¨š††ŒqëÖ-\¹r…*„Pà%DÕ´´´0zôhìܹAAAT!DˆF®TWWcÓ¦M"Ëmmmñå—_RÉ)33žžž€ `Á‚hmm¥Š!=3ðr8øùùÁÕÕµÓr.— WWW„„„Ð7¦uuu°µµE```§åÁÁÁT9R|øá‡™-//TA¤w^†a0mÚ4¬]»¶ÓòòòršÕUÅtttðÜsÏuZ¦©I-QROmm™“é 0vvvX²d ~úé'ª¼~ŽÎ,Bž§§'233»>Ñ45¡¯¯/5yzkk+’’’:-;|ø0U2^BÈ¿3ׯ_WʶÚÚÚàçç‡[·n —={–*™šd×¹Z[[Q\\,²\WWWì¸zBz‚;wbíÚµ¨©©Á°aÀªª*ª ¼²ëÈÕ©©©X°`Ú>TYYÂÂÂ0yòäNËSSSEnå!ö„ …••UDáã6&&xõÕWQUUE½!(ðö.¯½ö–.]Úi™²&',--y@²}ûv<|ø¯Lš4 ...˜>}:|}}{Õ¾gddàÚµk"=D:,\¸ÄÂ… %nÃÑÑl6÷ï߇££#}µñ*@CCÚÚÚ~´´´¨b”àÞ½{˜0a¢££{]Ð-((@NNŽðyš¥¥% ¤ngòäɈŒŒTxÐÅwß}G]ñ"ÞºuëPSSÓi›ÍƯ¿þª¶}ÈÉÉÁ¾}ûD–+2ç—Ë…‘‘æÍ›'výܹsqéÒ%”””HÝŽ»»û3uŸ,--¥ƒ‹/!âUWW Ÿ<}G¡.îîî" `ÿþý2•g±X¨««ë´ï¯¿þºÜûÁáp`cc#²üwÞ……îß¿/±ì/¿üOOO <¨¨¨ ƒ‹š‘LCCCä§7탃ƒÊËËŸy$Íd<X$-`çææ"** À“çŠ>ËPÆç =üŠ÷äÉ“8~üx§ƒœËåRw¯~‚a˜n ²}ÍÞ½{ñÅ_`ãÆ`æ™êõÛo¿ELL Uj_¼l6kÖ¬} ýÐ?üÐ/ðXYYáÒ¥KJßîºuëàããƒY³fá­·Þ¢ŒšHoõî»ïâèÑ£T2ª©©¥¥¥Ô×899uùpíiË–-ÃöíÛ¥¾fÀ€ðððÀ‡~;;;¹^TTT€ÏçËý™éA^/»â%=Ÿ………Ø€òZ³fp œׯ_ǬY³úT}%%%©äVÝÆÆ¦ËgaaÐÐPÀ'Ÿ|œ;w&&&b_Ï0 QSSƒÅ‹#** =’{ß¾ûî;jž ÀKzê• œÿóúë¯###C¦ÞöööÐÔÔx›››Áçóahh(²ŽÍf£¹¹YbàMLL„±±1RSSé éKM ……… D```—·I„ô'~~~øïÿÛiYmmm§Y‰;Œ1/¾ø¢Øí455¡½½¦¦¦rïCjj*¼½½ñÊ+¯àèÑ£055…‘‘‘Le;šJjjjÐÔÔ$÷{‡‡‡SàUÕ†;r5DGGcÙ²et¶"AJJ âããáíí­¼[Ymm´··‹]—›› www€‰‰ ~ûí7Ìœ9cÆŒAAAÔíòù|áȸS§NáÆrï›"‰ÚÛÛ¥v«£ÀK‘ÇÃ_ý¥ô¤ókÖ¬Á7ß|#v]yy9sæÌÁáÇ1zôhXYYu9b.!!ÙÙÙj¯§­[·vJ—I—¢°¶¶6Ô×× çhÇØØFFFjIyäȉë"""PWW‡ÈÈH$$$ //Ó§OÇÝ»w»ÜnXX€'<Ô5Õýƒ¤Žø£À«d§OŸÆôéÓû͉ûèÑ#‘Er î³|ùr‰ë´´´ ©©‰¶¶6™¶¥¡¡Hm.ÐÖ–ÿ¹ú½{÷°xñbØÚÚbëÖ­xûí·1þ|üþûïRËݾ}‰‰‰hmmEKK êëëe~ÏgI‹™-wŸi@ s=Sà}JAA\\\úÅ »~ýz¬X±aaaŸàà`lÙ²…¢Y?emmU«VI\Ÿžž.’«ºÃøñã‘››+uû, 'NÄË/¿,ó•gPP>ÿüsÀo¼ôôt™Ê.[¶ mmm¸pá‚Zꮼ¼?þø£ÜåÒÒÒ(ðö7ëׯGdd¤ðGÚIGºŸžžìììäHÑ‘GÕ&Mš„?ÿüSd9—Ë…žž455aee…ÈÈHáUsxx¸Äy‡FXXÞyçTUU!++ ]^%777céÒ¥022BEE’““eÚÿµk×¢¨¨H®Ïüô亊”ûí·ß(ðö­­­hhhùiii¡Êée>ýôSÄÆÆÊüúަyniçÍ›‡_~ùEøw^^BBBðî»ïJ,óâ‹/‚ÍfËü ˜Wº¢¢ÖÖÖÐÕÕY×ÔÔ„ææf±å0sæL˜ššbÞ¼yøàƒ$ö-îÐÞÞŽÖÖVüôÓO>|8Ξ= œ8qB¦æ~ø---2'ÕÕÕhhhÃ0?ÇÓâããa``€ÂÂB™Ëü  è&[¶lAYYY§ƒðñãÇ055•ø4šôLãÇÇž={*{îÜ9‰·ýÒp8¤¤¤HM_icc‡#±ðÓæÌ™ƒþùGîé±6oÞŒåË—K$3~üxhhh`îܹÂÀ*MVV¢¢¢ðÕW_á…^ÀüÀÀ@?~¼Ë})--ÅÝ»w±qãFøà±WŒAAAŸÅœ8qB8„ÙÑÑ–––R/ÇCEEŠ‹‹±råJ¢¸¸………2}Ž/¿ü§NBcc#šššÐÐÐÐ啹¯¯/öìÙƒ³gÏÂßßÿý7ÆG·¯«««ƒ®®.ŒU²}mmm$&&"//¯Ór‹… 6ÐðTÓQW'ª2ýõ×_x饗”¾]kkkÔ××£¹¹úúú]¾ÞÑÑŽŽŽ8yò¤Äz×<ÑØØˆÇ‹]Ÿ‘‘iÓ¦ ÿî*ñPG“†fÏžAƒaöìÙ5j”LÿÔX,üýýáââ‚+W®àèÑ£]NÏÔñO'44>>>`³Ùr]õRàíŸ\.´µµ¡£££’í3FìÓÚ€€ªü§ìß¿ÿý·ÚÞ¯ªª Ÿ|ò‰Ô×8;;wÊÅÐØØˆ¨¨(Lš4Ij0immí²9àYhjjbÕªUˆ‰‰fTû·òòr±«ÊËËQPP€‘#GЬKIIAaa!vìØ!œÉÃÍÍ­Ë}IIIðÊÛÍÍMîŒ|cÇŽ•;ù¼Òoll¬Hw”ÊÊJ:3I”““ƒ½{÷нuíi¬¬¬pïÞ= 4ºÌî6räHlݺUø÷DZzõj‘LqÊ0vìX\½zcÇŽ•)ð~ûí·xá…àáá!ó{èëëãâÅ‹HJJÂÊ•+;­;þùDîæ=E†I«<ðúûûÃß߿ӲÔÔT,X°€ÎrÒ㸻» óüÛzܾzzzââÅ‹ðóóëqû¦«««ò»wïFxx8 ÄsqÉ‚æÏŸC‡!==]äèp÷î]±ÛkiiÁöíÛEòÌ´´´`Ó¦M8p ÈL¨¬¬Ä»ï¾Ûå, ÔÔ §ÜÜ\±“#ªÚùóç‘‘‘ÑiY}}=ÌÍÍE^kff†ææf‰ík¤ºté’Ô¡ÉÒ\¾|YémÊo¾ù¦\¯·´´Dmm­Ø+ÚŽLO·³Oœ8ááᨮ®–y&OžŒÏ?ÿ¹¹¹"÷÷ßÇðã?Š즦&`Ö¬Y]žwx8™EöY={³fÍyР¹9?~Œ–– ¼}Э[·0lØ0…þyOœ8±Ë×…††bÆ øþûï…ÁfÛ¶mrõ –ÅÌ™3åìðÝwßa×®]b×IúlÁÁÁ§™òõõYæíí«W¯BOOOl™çŸ^dÙÛo¿÷Þ{C† 鞦Y0 £ôŒL½¦¦&444ÀçóÅvd·¶¶†•••ÂÛoooÛ¾÷ïéɉb–,Y¢¶÷:räˆÂMw .첌‰‰I§| \.W¡œ ²tÉ’—™™™ÜeŒåŽ5!!!"ËåvZf``‹…3fôÜÀ[WW‡¶¶6áÓGò‹Å‚ŽŽ8ŽJ&-))ÁgŸ}&öFI*¤*ü1¬­­{Ü~Mœ8.\À„ @l€®TTTH¼½—„Ãá`ÆŒRó>ØÛÛËœ³AU\\\”‡f̘!óŒÔÔÐÏL:U˜¬„(¬çÕm„ ˆ‹‹^Eü;¯$sçÎÅ×_-læp8]v¯³³³Ã;w:-‹Å§Ÿ~ªÖÀ;pà@¥lËÇǧ^‡ƒåË—‹LY¢Šî2„(“¯¯/:¤¶÷ËÊÊ’«ë–¼·øxüøñ3í#Ã0¨ªª’úð¹çžƒ±±18ŽðƒÍfwÙg÷¥—^ê4è„ÏçCCCCbn 022BSS“H|±µµÅ¨Q£Ä–155E}}½°Ë_Ÿ ¼©©© z¦Šî0dȵN^]]ýLÏ:¦û‘UNNŽØnzÒ´´´ ,,Ljâmmm 0 S—4_Ý¿ 4555.Úttt`aa!±ÌâÅ‹±k×.|õÕWÂe¥¥¥X°`Ħ—ððpt9b®W^ 00°Ór===±ãÀ é ._¾ŒÏ>û¬GîÛ«¯¾ŠÌÌL¼úê« •¿råŠÌÉyžÕÕ«Wáä䤖÷*//—»½»×^KKKÄÇÇ÷øý¬ªªÛÛÆÆFꌤjkk“ë¸Ð××W[3šŽŽx<vïÞE‹)´ y'¹‰‰¹¸’Ett46oÞ,W™îžˆ®)ñ áÌ™3ÈÉÉé´<##Û¶mƒ³³³Ú÷)<<¼S?Þû÷ï+efwww…n%ɳyýõ× ”+.YÊÜuíå—_ÆåË—…3S<=D·+ÛN•mõêÕÝÚD©­Ê/¬cœxÈÕ ièiw]é®[·Nl¶$qWäòê—O—ü›››²²²džHœ€€¹Î™ÂÂBŒ1B-Ÿ/??_iɃTx]\\ €r5È«¼¼\¤ÃúÇåÚ†R‚,éÝ´µµÁ0 ø|~Ü¿¥K—"** K—.‰£Å$9vì6lØ{{{™Ëp¹\˜˜˜È4ãÁƒÐÔÔD||¼L³M455¡¥¥Eêg¡¦†æ7ÞÉÉ<éóøt·Òÿ<~ümmm2ಲ²B[[>>HOOÇÂ… »Ìaaaììl455 GàÍ™3G¦}d³ÙR›2(ðâÉ ¡âÛÍÍÍ1eʵ‡uë'¶nÝÚ©‹“,š››ÁãñT–ü¾ƒƒƒƒ\“q>}K.KzHE½ôÒKØ»w/>þøc™Ë899áÖ­[r½©©©°Ù¤©© zzzxë­·º,'KÌ d âââ0hÐ ‘ióY¢ŒâííÝ#÷ÍÓÓ—.]’«LGjH†aä~¿ëׯc̘1=®X,jkkQ]] ™få˜6mþøã ¼]144„———ȺnÍHÿdjjÚå'e),,TJ–®n狊Šä ¼ÚÚÚ`±X(**RùÔIS¦L‘yHo‡¹»ªYYYÃáPà%¤¿+++“9e¡:iiiÁÌÌLî~µ³gÏÆ¾}ûÐØØ(s÷:dgg÷ˆÏM—^äY†ýÊëÎ;8p Ü= ÔA[[ííí ¥—ÍÊÊÂ+¯¼Ò½ûO‡2éÏ®\¹"všŸž8ç„……aË–-jy¯ÇCWWWj"™ÞèÁƒbgn‘æÜ¹s˜”kv CCC477ËU, xoݺ…¨¨(@EEÕ4!„¨:ð>Û¶mð$WÃÅ‹©¶ !ÔÆK!x !¤¯£‘k¤_ËÉÉÁÞ½{E–ÓaB—qww‡»»»Èrq`¢,ÔÔ@!x !„/!„ ¼„B—BˆŒTÖ«Ç㡾¾MïM!j ¼øù矷oߦš&„U^'''lذÀ“\ iiiTÛ„jã%„ ¼„B—B^B¡ÀK!„/!„Pà%„B—B(ðBH¼HMM»®ªª ¸qãÕ"é‘RSSñõ×_¸\."""pèÐ!ªÒ­¤NOOÇ!CÄ® GLL #\þË/¿ ??¿ÓkKKKÁår±råJªq"3///L:U¡²üñ¸\.6nÜ8uêÜÝÝ‘––†éÓ§ÃÄÄpõêU:tH¤<Çî]»œœL_Qˆ¯¯/<<<¤^†a°xñâ'—Áššøé§Ÿ0uêTÉýfo¾ùf§e7oÞ`iZZZpûömŒ5J%ñ÷ßcܸq*Ùö?ÿüƒAƒÁØØX%Û¿q㜜œ §§§ôm766¢¦¦Æ ëQõ>vìX™_ûðáC¬Zµ `nn TUUáÂ… XnÔ¨Qb/’’’ÀãñºŸikk“¸^»?ý“QEûh•î»®®®Ê¶­©©©òý§ãKyeù®´µµû\=(RF•çÑÓ甦¦ä­°°°°žràjhhÀÈÈvvvt÷!ptt¤}îe´´´`bbkkë~]:::4h°'ŒRbÃ0 …BQµ\KKKÃ矎šš‘uùùùÂyÚV¯^ÀÀÀNƒ4~ýõWäääзÖË\¸pAAA¨®®YW\\Œ]»vø|>öïßmÛ¶¡¡¡³gÏF`` BBBTºl6(++YÇáp°dÉ\¼x‘¾È>äÆ ĦM›ðèÑ#Ü»wÁÁÁ8sæ 99+V¬@]]°aÃÄÇÇC (åxQ{àýí·ß°jÕ*ìØ±Cdݵk×pçÎ@II ttt0~üxŒ='Nœ@jj*>|Ø'¾ø´´4Ü¿_ø÷áÇûìAž€ï¿ÿ›6m{tÀ„³³3>ûì3ðx>¾Ï£+W®à›o¾é·¦¦ÑÑÑpvvÆÅ‹±}ûv„††âèÑ£€'N`Ñ¢EØ·oRRRàéé‰üü|p¹\¥/=*Wƒ———ð÷ƒ"22fffˆE\\ž{î9deeõú/ýÏ?ÿÄîÝ»±oß>”——#??_8ð"//gΜAff&€'·ãââpõêÕ>yLžêë뇸¸8¡°°„Çìþýû…#þ233‘œœŒââbÀñãDZÿþN¯/((@}}½Úc ›ÍF]]¦L™Ò÷›LLLP\\ +++dffÂÇÇG¸®²²ÕÕÕhooGBB ÑÐÐGGG,_¾¶¶¶r¼é©lmmaii '''ÁÂÂGŽÞâäææâòåˈEDDZ[[qìØ1466öÊÏkff†›7oÂÆÆl6o¼ñF§ï¼¦¦mmmprrÂ’%Kàêꊼ¼<ÄÅÅ¡°°†††*Ý?KKKäççÃÆÆeeeððð@kk«ð»º~ý:ÌÍÍûtÐMLLÄùóçÁåráíí   ´´´ ==ÇGNNZ[[qðàAlÙ²...())Áùó瑞ž. ¸›7oFKK JJJ‘‘hjj"&&‰‰‰àñxpvvƯ¿þ* ÀgΜAee¥Ú¯îcccáææ.— +++ÁÔÔ`dd„Û·ocàÀ055Ž{÷ ­­ MMM¥/jïÕ0bÄäææbÑ¢E000 ÍËËƒŽŽžþyŒ9ÉÉÉppp€··7ììì`kk ¥>]ì¤W©TÿIDAT¸víþóŸÿÀÆÆÆÆÆ8}ú4f̘ .€ÅbAGG•••¸~ý:†/// :´W~ÞÑ£GãÂ… ø¿ÿû?0 ===¸¹¹x’+A__£F¤I“””„bæÌ™€¬¬,ÌŸ?fff*Û?777œúè#9r‹/FEEø|>ø|>’’’ ¡¡‹kkkLŸ>ùùùøâ‹/˜˜###¸ººÂÍÍ °²²Â£GŸŸ)S¦@___­WGGUUUpppÀ”)SpæÌÌ›7&&&prrBQQÞÿ} 6 %%%ðôô„ƒƒƒRŽêÕÐMÖ¬Yƒ·ß~ÕÕÕøý÷ß±dÉTVV GV544ÀÁÁÑÑÑðññétw@ˆ²ÅÇÇ ÛÓÿý;Ã0ˆŒŒDII vìØ{÷îaÆ (**·ß~‹ÒÒRðxšU£˜73á} ¾GóêÃ~Jv$Ögý2k2nšßaj`Š_êH4V©¹S„ªxIÈkÖugJv ö Ó%‡ I‚a¿¥Æ.Oe–›uYS{þidÏùÅxI@op†øU$‚­ÀT¿XàBžÃ,­Uåb«®¹«6™“;1”+9Ä2?å4$‘úí[à¢RýêÃV-—ÕÖ_Ü寵(Œˆ9©ûȲhÏeZ}Ÿ2 ‰U_óV¿òÀSËj Ñðt?“‡}Gª.·†é ð]Uqk«ÈâWÌAâ²jbŒÈ]¡ÀsyŠ@d¬KÉê/>‰^—G23Ìá·ó;< 7VÜæ¥cpµ°Ñ9«YŒ„´nrI ½hÚ“$ã Mı. ÌáWeCSÙMÝ­¨¯.¯¹|§Þé¢Liž•þFbéu¹CSüÜ)ÔZ?­£“¥­€ŽšÑÔuý²^êÝ¥'LtÃ3ǽ­ÛícäÛsü6êRT üp8ÿàÔ÷÷õh÷„Q;ɧf¿á~¹‡o¸_ÒÎj¥ôÔ?9\)m3/ÜŠRŒʳET#í¤k¿ÎU~s“I Guþ³HY/õ˜Ótò?'Hèâüj¿ŒÃAPŽk5þIEND®B`‚snd-16.1/pix/sceq17.png0000644000076400007640000000101611147553270012747 0ustar bilbil‰PNG  IHDR§}Ûüø3PLTEÿÿÿ€€€ààà```ððð    ÐÐа°°PPPÀÀÀ@@@ppp000—ˆæ` pHYs  šœtIME× 0±nIDATHǵ–Ùºƒ „Ã*CõýŸ¶…Æ…ö;Ühé?3,Q¸i¦»ŽµŸÔ­XÈÜxtï–|–Ãý¾·ºSD+m@ ÍÂ/UoÕ‹„÷‹+Dou£жt(És¬š?fŬ&9øõVwê¡h’«¿ØÏ®–L;+’—Ìæø4ÎŒôVwêÑh;ŸUò‹ ‹³Ã„©­¦¤:@i­õÇ’ŽDëãT©{0u„TXCkw¤µâÔÛ$í†hfN£'w ®!?Ìœ3³"­ÕuÃ\F§1>B'dXS—s.€¢^ŸžKS^&yÝÙŠ´VŒº¯Ð†/Óc£•œ'Iæ%Qˆ4Ò [ Úk·§nV´®«ÜÆêºå1µÛhz]-¦_OòqÖ.˜«“ÃÀ‡ÕSuæ»qž‰58‰{}.˜þûiƒâéyW¬žª+шícRYûÅ ý“úZl¾ûàøïöªÖ¹awÊIEND®B`‚snd-16.1/pix/tanh1.png0000644000076400007640000003105111147553271012662 0ustar bilbil‰PNG  IHDR,¦`!²bKGDÿÿÿ ½§“ pHYs  šœtIME× 9Т¹Ñ IDATxÚíyVVV@ee%òóó!##ƒýû÷cýúõÐÔÔD~~>ÊËËÀ“YŽ!„”ÀÀ@DDD`Ú´ixôè’““€Q£FÁÇÇ@ýIII :!!!pvvƘ1cЭ[7¾ÉqõêU\ºt Ó¦MÃëׯáììŒóçÏCNNÚÚÚ””Ĉ#àçç‡k×®ÁÔÔÒÒÒèß¿?êêêàì쌠{÷î8;; Ä“W‡Ötà—===ÁÆÆ†´@Â1~üx°ÙlÄÆÆÒíÊÇLJ"…ÓÆhñVii)¸:²¬¬ŒÔứªªBuu5}\[[K …(¬æÁÎÎ555êm/„ï%((.\àé©«««“‚! ‹ÿ\¾|¹Ñ@øÞz }´q‡„í‘ÒÒRlÛ¶ °|ùr(++#<<œö^aff†1cÆ 33'Nœ¨©©añâÅ|•ãĉÈÌÌÌ›7<×ïÞ½‹«W¯ 0mÚ4xyyñÔ›ŽŽlmmqàÀäää/^ 555:M›X%¬­­EMM ý' “¼EÃáM)`p8888`ß¾}ؽ{7lll@Qnݺ (++ãÎ; ( YYYxÿþ=¬­­qþüy¾Ög]]amm¢¢"¤§§7j?>„””Œk×®¡®®ÇǾ}û°oß>ìÚµ !!!àp8 ‚µµ5Þ¼yÃcõÞ&ÖË—/1tèP˜››ÃÜÜJJJïb÷¿ÿþ£åUQQÁÓ§OZÞ+W®ÀÞÞžhãÀØ»w/ª««±hÑ"<{ö ÿý7öíÛôïß›6mBtt4ÆŒUUUãñãÇX½z5ßäàæall 555XZZò|ƒ‰‰‰pqq¦¦& ???bÊ”)¨®®Fuu5ˆÂÅÅIII066†ŠŠ ÆŽÛ¶Ö©S§0tèPܺu ·nÝÂpæÌ•7<<÷îÝ£åݺu+þ÷¿ÿ ¬¼ÁÁÁpuuý¬óòòò0xðà¶­°ª««qþüyÌ™3§Ñ5mmmtíÚ111#oaa!Ξ= }}}Ú'CCCTWW Ô\Vaa!ÂÃÃÉJ¼¼¼0fÌ„„„@WW]ºtAß¾}1lØ0:ÍÈ‘#¡¦¦ÆãŠZYY£Gæ›&&&<+y3fÌ@ÇŽ ///téÒãÆ£¯ëééaàÀê}zÕÔÔ@NN0nÜ8+üO]h“­9-ˆŽŽŒ›¼fgg‡Ý»wcäÈ‘󟯼¼cÆŒ!' ,_¾ׯ_‡³³3˜L&Ö®]‹þýûÃÄÄ®®®¨©©••z÷îùóçcÞ¼yxüø1aiiÉ79ÌÌÌлwoXZZ"##‡BÇŽ5kÖÀÙÙVVVرc¤¤¤```€Áƒ#//{÷îÅ’%K //°²²Â–-[`ii‰ÔÔTüù矼™µ¦‹×Ÿq‘lffFUTT|Ñ-ïÔ©Si×έÍÝ»w)ww÷/¦9r¤À¸ßMMM¥…ÂUp{u‘LQUVVF•””P%%%‡Ã¡(Š¢ªªªèsUUU´ksî¹òòr¾ËQ^^N?¿¶¶–þKJJ¨ºº:úwII UYYIQEÕÕÕQ%%%TuuõW߉‹Ðö°*++!..þÙ뢢¢eã´zõjDEE}1 .^¼(û*oݺSSSÒp>uUÔOÄs'ã¹0 tîܹÙäh*¢‘¨¨(Ѩáo.:thR¦¦ÞI¨ç°NŸ>ßÿ½Í5¾%K–àðáÃ!Ë… 0cÆ ¢…Pö°ž={öM½³gÏÂÖÖ¡¡¡­*¯««k#ßÛ?HOO§7‚3 hiiáýû÷´Ÿ¬nݺA^^åååÈÊÊ¢{C½{÷æ«YYYt Œž={¢S§N<× ‘››  >°®²²2jjjðâÅ‹zEÔ±#455yîyÿþ= Ñ¿áVXßJ—.]ÂT ´´ô›»ãxøð! ZMÞ›7oò¬ê—‰'Òæ ÒÒÒ`³Ùسg^¾|‰ªª*aýúõxôè\]]ahhˆøøxž¸¢ü`Μ9ÐÖÖÆãDZmÛ6˜™™ñ\?wî®^½ 999tîÜ>>>ÈÎÎÆ”)S0fÌܾ}©©©ê-Nž<‰àà`ÈÊÊòltoq…5wî\zn©¨¨è»ï‹‹ƒ´´4úôéÓ& ••®^½Úª KÐ}I]¼x‘'üSBBzôèÑ.–´´4ÔÏ]ÅÅÅ!,, þþþ`³ÙXµj¦OŸŽ­[·ÂÒÒ[·n…ªª*Î;‡Y³fñ­>RSS…mÛ¶ÁËË £G¦ç¬^¿~Ó§OÃÝݺºº˜0aîܹ 6 ÇŽàAƒpðàA,[¶ kÖ¬Add$V®\‰ñãÇ·îÐÓÓ“ö‡•’’‚k×®}×ýïÞ½ƒ¸¸8m·ñ5¶nÝŠ 6ðDnéÞ•¸¸8 §ÎGÆÏcbkk+ðûG›‹’’zk—¿¿?Þ½{‡””ež——‡ˆˆ ðäɾ),n\nß¾ ‡C·y6›GÑ×322™™‰ˆˆÚŒ§²²wîÜA~~>N:…7nн±†´ø¤{÷îÝ¡ªª UUU(**6{~222­êzäòåËÐÓÓM)))èÕ«×W`a¨ÏmCªªª-kscmm±cÇBJJ Ó¦Mú÷a³Ù(++Ñ#G`ee…;w¶®Â"|MMMtìØIII­’ÿ­[·```@Gú&6;v쀿¿?Nž<Écm.ÌHHHÀßßرc‡ð*¬ºº:”———=‰––z÷îýÝCÏÖBII ïÞ½#_#ዬ[·Ž÷ïßRRR`2™<߇””ÄÄÄx¦PDEEÑ¥K¾ÉÁ̓‹œœ:tè€ÒÒRdggƒÁ`ðü”””„¤¤$L"""••ýj^B¥°JJJˆ… ~ó=L&bbb(--%-œÐ¦èÙ³'Þ¾}KÛÌ)++ÃÌÌ .ÄÍ›7www!88III¸pátuu¿Ù;·ÀÍãÂ… HLLĹsçÀd2qüøqz hÛ¶m¸{÷.ÂÃÃ1kÖ,L›6 ÁÁÁÈÊÊÂ…  ..Ž'N`È!èÔ©.\¸€ÔÔÔF[ÃÈ^Âf¤°°©©©6pü`þüùèܹ3 `eeEúN™2OŸ>…¬¬,½ºoß¾055EAA\]]ù.‹««+²³³Áb±h»)SSS9r`±X©ïq¿‡®]»bæÌ™(((À²eËööö””DAA,,,0}út¢°Z²GøæÍhkk …¼iiiÈÊÊâñ—NlšZé>|8†ÎsNEE‹-j69šrA4hÐ :® ŽŽ[%îP²)™¾´Ã¢]Lº÷îÝÙÙÙ¨ªª yµ´´žžŽºººÍ·²²UUUd °´ …5aÂÄÄÄMd„„„ðÄÞ#B¦°V¬X½{÷ ¼›6m‚‡‡ie„fÁÓÓ&&&`±X`±X;v,8öîÝ üòË/8qâêêêpÿþ} >, sæÌá«'“šš8::‚Åbaøðátˆ1.Ïž=ƒ±±1X,¦OŸNž°²²‹Å‚±±1ÒÒÒÀáp°cÇZöS§N5e•ÂJOOoïLÉÌÌäû&SKçÎqþüyDEEáøñãÐÐÐ@xx8|||àë닃b×®]¸sç,--±`ÁDEE!++ k×®å›[¶lAbb"¢¢¢°téRL:•gç……ììì…êêj,^¼ŽŽŽGTTfΜ ãÌ™3Àž={°eË ùv3$FæÎ ÿÍ344“&M"…/$,_¾ªªª€£GÒØŽŽŽÐÒÒÂ!CèIyÚøîÝ»ù. ÷™¿ýö†ÊsM]]–­aÞÜß ßcÑ¢EèÝ»7ŒŒŒ­…%ÀüöÛo8þ|‹æùÏ?ÿ4ÚeO|nß¾=z´Y‡ iq³†èèhz\š‘‘Ñbùjkk#99¹Eö/𗬬,¼zõŠ>.,,¤m|ÚÕÕÕHIIAŸ>}ù " ‹Oÿ jkkÔ;èúV®_¿ssóÎwóæÍ`±X|Bh222xÜMÒA ÚEEEˆŒŒDPPP»xßÿ·´qãFlÙ²[¶lÁâÅ‹¿ù¾°°0L˜0Ah vçÎpww'Ú¥;v,݆¶lÙ‚¾}û¶Û²Ø¶mÖ¯_ÏsÎÛÛ©©©xüø1í++11‘ž]¹r%ßåà>óܹsxüø1€z?Y÷ïßÇË—/qäÈ‘Fysïß¿oß¾9r/_¾Äýû÷qñâÅÖïaµ’’’0sæLR„f¥¦¦ºººôñ„ ‘‘'''Àš5kðË/¿àúõëpuuÅ©S§Ð·oßF^~†M›6!//, µµµ¸rå ÄÅÅQ]]ššܸqNNN ‚¢¢"Ž;˜>}:X,F]]™™™ô ‡G#G–Da 0, ‘‘‘5jT³çuùòeŽ^9~ü8ïID...pqqá9ohhØl…;vìˆ'N4:ßpmSy7ôËÅÝÝý‹#²J(ÀLœ8aaa-’שS§`ooO Ð…Âb³Ù`2™íÚ³$@’!áÍ›7Ñ«W¯Fa€¾—Ñ£Gãßÿ%á× m†³gÏÒ{dgΜ yyyÄÄÄàÉ“'€aÆÁÀÀÙÙÙ(**ò=Xopp0²³³ÔRiäÇtÈyÌž=@}|Ñ’’ÀìÙ³!##ƒÿþû €#F`ðàÁíwHØƘBsqâÄ ¬Y³ŠŠŠ ƒ““=z„y󿡤¤ïß¿‡ƒƒRRR`kk‹Û·oCQQK—.Å™3gø&ÇŸþ‰… BQQ111°³³ãÙ«èää„°°0(**bÍš58qâ>ŒM›6AQQW®\³³3îÝ»‡y󿡲²oÞ¼Áܹs‘žž.|=,a#00,‹Þn èAZZºÝ_ +=ÂÅ‹addsss˜››#''3fÌ€››(ŠBii)òóóQYY‰Ó§O£sçÎ’’­[·ø&GRR|||`mm KKKL˜0'jN^^®_¿)))¨©©ÁÏÏUUU¸|ù2ŒñãÇÃÂÂoß¾…½½=\\\ÀápPRR‚ÂÂÂöÛÃj)*** &&ƒ!òúùùá×_…””©éaBʼyó0kÖ,<}ú>„ƒƒC›çvÕÓÉDYY™PÈ«§§yyyDDD¯“Ð###DGGcõêÕ1b&NœHVkSYY‰W¯^AKKë§Ÿ¥®®ŽAƒÑ«%‚“ɃÁ@EEù: Mòøñc„‡‡cÆŒtð‡¸¸8|øð999HLLP? Þ+¿á>311‘^-LNNÆÛ·oQTT„‡¨_ñÿôžû÷ïÓÃÙ‡¢¨¨oß¾Errrë /^L¯ |:¡Ö?~ăàææFZ'ÂcP›œœ •vWgΜÁºuëpòäI˜šštuuqøða899¡ºº¢¢¢ÐÐÐÀĉaoo}}}ܾ}gÏžå›ÖÖÖ˜5kòòòðäɘššBTTáááÐÒÒÂŒ3`ooáÇãæÍ›‡ÃÁܹsñðáCDGGÃÑÑC‡űcÇàää„ÒÒRHII5r€Ùâ kùòå´{™çÏŸãÒ¥Kä $|#FŒàéq'''óÕ寰0nÜ8ólþîÙ³'Μ9Cw ''Ì›7@}Öž={òM}}}DDD ¼¼ ¦¦ƒˆ‰‰ÁÌÌ Ó¦M¬^½êêê꣌×ÔÔ`ÅŠPWW‡˜˜Ο?¢¢"@·nÝ-´¸ÂjhüÙƒ,p—bŒŒˆfi&äååyÜÉtêÔIhŒð%%¥&ÏwëÖ Ýºuã9'))‰~ýú5›, E¹4T6MåÝ”ÃAEEÅ/ú¬#f |&;;/^¼ÀÈ‘#…BÞW¯^¡¤¤$•GxˆYC;çýû÷(//'Á2„˜ššP111žóååå””p8zuœÁ`Ð6N%%% ( ´¡çPVV‡C÷æ¸vUŸæ-""BÛƒ•––ÒÓC;w†ˆˆ*++é‘—¸¸x£w"=,G]]¯_¿n—s4„¯‰7ÂÛÛ›>—’’ÒÈ]О={ ¯¯[[[èëë#%%>„––FŒ7þp áçÏŸcذa°µµ…¡¡!vìØÁžËÇÇzzz°µµ…žžðôéS 8¶¶¶ÐÑÑA@@rrr`ccƒI“&ÁÔÔÎÎΆúíNaâÅ‹ôÄž 3uêTܸqƒžÐ$’žžN{ëlØkNIIá9wâÄ øùù!44æææ8yò$¶nÝŠ 6àôéÓÿáyÀ³gÏÂÄÄ¡¡¡8uêΜ9Ã3?}àÀøøø 44vvv8tèöíÛ‡… "44ÞÞÞØ»w/îܹƒ¿þú çÎCzz:ÒÒÒ„Ka­[·žžž|{ž®®.²²²h»~ÃápxºÃBsâèè+++žs£FŠ+xΩ©©ÁÄÄ@½ >ÌÖüùó1hРŸŽ÷É}¦±±q£é…nݺÑfÜt ?žž 755…‚‚úöí CCÃFùü—õâÅ ¡ žêììÌ @T¸¦!‡FZZZ£ù"A„Ìaí˜÷ïßÓþªnL& ‹@ ëÖ­ƒ­­-´µµ…B^¢°„nØæÀÝÝ»ví"…,¤ÄÅÅ!55•Ôš½wïŠŠŠƒââb°ÙlØÛÛ#&&&L@¯^½0yòdDEE!//1111bÄÉУGX[[#&& ,@vv6DDD°wï^„††‚¢(ØØØ &&ãÆCß¾}¡©©‰Ñ£G#&&ÖÖÖ`2™——‡——NŸ>]»váÒ¥K\‘Ùa!ÀËË ,«YæÆ(ŠB‡H! )‘‘‘¨¨¨€¸¸8þùç!%%ÑÑÑ055EXXºwïŽx{{#,, X´hºtémmmz_&wûÌ÷ )999CLL †††——GPP<ˆ°°0¸¸¸Ð bbb À°bÅ ÈËËãØ±c¸wï€zÊÜ ÝDaÚ,«V­úiÿÿ§«`aa ‹Fç·oßÎslggÇ79¸J«!ÜUɦòæöî?eÒ¤I˜4iÒgói…Åû)/^¼h•JîÕ«233ùº”Ðrdgg#''‡>þÔD%11ººº(**Љd·Ó" ‹.ûSòóó¿x_DDm¿ÁO¶lÙÒlC,BóÏãW)''‡g솆zö쉈ˆ¾G‡!´…µoß¾&Ï'$$|Ñ/Ï… „ÊÖž={ˆß®àÓ!ORRR»ôÖÀåîÝ»`³Ù°´´P?÷êtý AƒèkYYYpuutïÞ‡,X°yyy€#GŽ@EE>>>Ì;ÖÖÖ<ùUB>òàÁƒ&­s „æböìÙpttÄË—/ׯ_ÇæÍ›±råJ,\¸nnn¸wïLMMall ___\»v ›6mXZZbùòåx÷îÝ˰}ûvÁ××, –––<ûÍÌÌ ££___ÄÅÅÁÕÕ‹-BZZ|}}¡¥¥…ñãÇ#$$;vìÀš5kààà€eË–!..Ž(,¡­pöìYxxxÐÇÜ^Ê/¿ümmmØÛÛCAApww‡œœüüü轩áááX¾|ùOÉPQQ___ÈÉÉÁÅÅ::: (¬Œ-[¶@NN§NBii)JKKáïï999xyy¡k×®¨®®ÆŠ+`hhˆI“&á×_EmmmË ?Ïܹsáïï¹sçòí™Üÿf„¶ƒ®®.`Æ (..Æüùóy<’ ;¤‡%$ :ô³«­?Jdd$FE · ²lÙ2XXXàæÍ›¨¬¬$ ‹@ . 077GAA}Š7oÞЦM óæþö÷÷Gnn.€z¨7oÞàéÓ§¸~ýz£|vëÊ•+ÐÓÓ£#lðlذ¡I ]AX˜={6RRRÀápŽ‹/¢k×®øí·ßPWWkkkâèѣشi8&“‰Õ«W¨_%ÌÎ΃Á@HHÈ…ÿruu…X,ŠŠŠ°wï^0™LdeeÁ`ÀÛÛË—/‡··78._¾ Š¢0iÒ$°X,äççÃ×׃Ftt4llÆÈLkªIDATlP[[‹™3gBOOO8VII ÄÅÅÊÏtK’––555ˆ‹‹“¯ˆÐb4¥`öìÙÓèÜÔ©S1uêÔFç¹6O?C×®]yâDrY¸p!ý›k£ÕØØØFçæ¶'QX|§á$pBB¶mÛFjð]ÀÀÀ€>¾|ù2Øl6)˜v™t'DaÂ@ppðEý&…E ´8·oßþì¾QQX@@ ‹@ ˆÂ"Z›¼¼|øðÙ4ÇŽßþÙ佉‰‰`³Ù ¨ªª¢¦¦æ‹½¹†m·¦¦†n÷„–C]]³fÍú®vÅ£°Îœ9C»êPQQA¿~ý !!:ü”`Ÿ â™ýÅîû­[·0dÈÈÊÊò½°þúë/LŸ>½Ý?÷[Ñ××oÕÆíìì ggç&¯?èØ±yäææâÅ‹011i‘wnÉ:ǨQ£ ))Ù¬ù!..cÇŽý±vE}#GޤçååQÓ¦M£nÞ¼IŸ[²d O]½z•Ú½{7Å/©ÔÔTª9høNíù¹-All,åææÆó{öì¡–.]J§ÉÊÊ¢ììì~è]ÍÌÌ¨ŠŠŠ}– %ëÜÆÆ†ÊÍÍmö|RSS)GGǾÿ«“î›6m›ÍÆîÝ»555HNNæñ?´cÇìÙ³‘‘‘X´héëx2dúõë‹…ÀÀ@ÀÛ·oy¨©ªªÂÊÊ ,ë»ç¯퇯ö¡=<<àááA«¨¨ 99™'MçÎ?yXP™4i‘·¥YÇŽ˜7oÏ<åþýûyÒ0 LŸ>½U‡½_£[·n022j“ŠÀÔÔT(ÜL·Û nnnD^ÂwÑ«W/ôêÕ«M¾Ûüùó…BNb8J „VXLJ´´´PèøñãI«j…á ƒÁhsïÕÛ’´´4†þÃ÷w (Š"Mž@ Ö7P^^ŽÜÜÜ/îUVV"77—'œSAA©½o¤  à«Û]ŠŠŠhWÁl6¹¹¹ô7ŽdkCQrssiƒãÏñþý{ž0`„Ÿ£®®Žn Ÿ~ƒ ÛUuu5rssy v¶«ÏññãGäåå}“,ŒÍ›7on­‚`³Ù8|ø0üýý!**Šþýû7©¬Ž= ___TTT`РAˆ‡••1¡øâãã±k×.DGG£gÏžPPPh”æùóçØ³g®_¿ŽîÝ»ãÊ•+ðõõÅõë×áááiÓ¦AFF¦ÕßåæÍ›Ø¾};222 ­­N:5JsçÎlß¾‰‰‰ÐÔÔº)AäÊ•+tûhø ~Ú®Nœ8ãÇ#??úúúxñâO»RVVnôìW¯^aÿþý†’’ÔÔÔ¾ú_«Õˆ§–,YòE#¹ÜÜ\ÊÆÆ†'MLL ¥¥¥%PÆ‘‘‘‘T\\Ϲýû÷·º\nnnTll,uãÆ jëÖ­M¦Ù½{7uõêUžúà–³§§'U\\,eÌ­ÿõë×SQQQM¦™4iÅf³©C‡QAAAÓ>ÊË˩ŋSBgøܨšjWÜk\CÞϵ«†P>>><ßùOŽ "LJ¢¢¢ÀÈóñãGÄÆÆ">>žŠ”——óì¡,..FYY***è!VEEØlöW‡8­Á›7o°`Á(++7Ù“!| ,À‚ ƒ”””––¢²²’Ç»´´l6‡6› 6›ââbTWW£ººš~UWWƒ¢(: ‡Ã¡÷P–””ð´+nšÚÚZp8ž<¸¿?Ç”)SPSSƒ]»vaݺu­ZŽg‡‡‚‚Œ7Nh£³³3ž={&“‰àèÑ£8qâ¼½½‘’’011ÁèÑ£!!!bìØ±8|ø0ѽ{w¸¸¸@SS³Eä½zõ*455?ë7êÑ£GÐÑÑAbb"~ÿýwŒ3={öȹ¹˜˜79Ô‡ŠŠ lܸ•••066†••ž>} www(((à?þÀ»wï ££ƒ%K–àÖ­[ deeaéÒ¥`2™°³³Ã… PUUeeezóð¯¿þŠ.]ºàòå˘˜\\\ŸŸOïÙ577ÇàÁƒqéÒ%ìÞ½IIIðññù¢×Õªª*?~ €™™ÙO•Å7 ¤¤===á›tWVV†‚‚ÜÜÜ`ggøã?àääD§‘’’‚žžÜÜÜ0yòdÀßÿ—/_þ°÷~sîÜ9ÌŸ?îîî8zô(ÀÕÕ•Çu†ŒŒ FŒîÝ»ÃÛÛ>Ä;w ¡¡YYÙŸòõ%&NœˆË—/#** ¦¦¦kkkz‹ Œ5 ±±±8þ<¦L™‚œœlذnnnÐÔÔl–Íç?‚““ÜÜÜбcG¨««#)) ÖÖÖxòä ÆÁÁžžžÈÏÏÿá‚ßäç磢¢‚'`kyy9,,,‚·oß"((ùùùÐÐЃÁ@YY¼½½‚ÏÎ!nذÐÐР'®óóó±mÛ6Lž<AAAX»v-ý…ïöL±}ûv=z·o߯† >Û®ÌÍÍáææ‹QQÑFí ¨÷ÌÒpëÕСCñúõkìÝ»—ÖÛÃRPPÀ‚ ðêÕ+ <°yóf”””Ði$%%áììŒôôt 8 §§‡K—. Ô„*ƒÁ‡ÃAUU˜L&í²¤¦¦¢¢¢ÿSˆˆ@WWVVV••…ŽŽN³ÈÅb±   ƒ---@ll,TTTè4úúú––FUU]Æ\-}úôA—.]¢ŒgÍšMMM¨ªªBEEÒÒÒˆ¥ß &OžŒ=z@NNN`z…cÆŒªª*ý¨·šçnó™1c¼¼¼0bÄ 2ªªªPWW‡¨¨(*++¹sÍ`0¨««Ã«W¯àéé 777HIIÁÊÊŠþøÿý÷_°X,())!!! &&F?'&&7nDLL "##qæÌlܸñ‹òOŸ>&L¨WÿÏ#FSíjÉ’%HII–– F“íêÚµk<ÿµµµáàà€¢¢"Zì¤{[cÛ¶m”ƒƒEQµsçNÊÌ̌ڹs'EQµråJ***Šºrå µråJŠ¢(ÊÛÛ›233£V¯^M ¯Ã­sŠ¢¨ªªª&ë|õêÕ”™™åííMQEeddPfff”™™¥££C·«Ù³gSTxx8UXXH§ÉÈÈ îÝ»G]¼x‘¢(Šzüø1HO„›™™Q?¦(Š¢233)gggª´´T¨Ê‘ŽB‹Åú¬_¹ïåíÛ·ðõõ…­­-444„ªˆÂ"„€øøx¾ÍÉ•”” ??êêêBWÿòpp2?—gIEND®B`‚snd-16.1/pix/note.png0000644000076400007640000005365611147553270012632 0ustar bilbilÿØÿàJFIFÿÛC    $.' ",#(7),01444'9=82<.342ÿÛC  2!!22222222222222222222222222222222222222222222222222ÿÀ=ç"ÿÄÿÄV !1’ÒATU"QSV‘“”²ÑÓ256arst¢£³#34q¡¤±´Bƒ$RduÂ7bcÁCÃE‚áÿÄÿÄ7!1QAa‘23R¡ÒqðB"#¢±ÁSrÂÑb‚áÿÚ ?éµ5gž8çÌcl@Í'Y?(î,2MX 3êM³´Y¤iÚ^N÷B«29‰ ÐvÃK´èÕ­`J ¬q¸$½®:û¿Åy‘\äxønNI›\=oKy8zî–6òÇŸ'E©òE{Ÿ'E©òER.lS íŸCéc`ï']ÒÆÁÞ_òtZŸ$S>N‹SäŠE͆Û>‡ß]ÒÆÁÞN»¥ƒ¼¾3äèµ>H¦|§É‹› 7¶}¾»¥ƒ¼œ=oKy|gÉÑj|‘^gÉÑj|‘H¹°Ã{gÐÉÃ×t±°w“‡®éc`ï/Œù:-O’)Ÿ'E©òE"æÃ íŸCéc`ï']ÒÆÁÞ_òtZŸ$S>N‹SäŠE͆Û>‡ß]ÒÆÁÞN»¥ƒ¼¾3äèµ>H¦|§É‹› 7¶}¾»¥ƒ¼œ=wKy|gÉÑj|‘Lù:-O’)6olú|=wKy8zÞ–6òøÏ“¢Ôù"¼Ï“¢Ôù"‘sa†öÏ¡“‡®éc`ï']ÒÆÁÞ_òtZŸ$S>N‹SäŠE͆Û>‡ß]ÒÆÁÞN»¥ƒ¼¾3äèµ>H¦|§É‹› 7¶} 3cšSøÅ4R5¹åpi îØ»RÃ.QÁ àcñª|ê‡fG›w\ÙÇ™Úhí'F…ŒäœxÍtµ2qèD±æ=‘@~‹íµ¹¯r9–²"19«ÚóPêŒÓ#8ºb5C‡vŽ{¢¥ÆsÐÕQTg= 4˜¹ˆBdÅ©Ú&ŠæÜ&¯{ÛiÖ5wV½6RÓÖRAU9LaŸ7ƒ.9¥ÅÀ,\6#F½*;ɦ⯥|´:› Ë`„h’95ZÀçFÝ\Ĩ˜Gt±A|&$Kba:0Ö hÿV4ü¥.3žQTg= |x«¦l΋§{a$JZn#¶¼îÛGÚ¾ŽÇ#˜ÖctŽsÅØðKµêíôû×xqAPä“púJšh[ÁÔ É”Í“:0fàAy=Í´›é» )¥alÒbr]­a&;Ö½î°&äÞÜú‚a|ú sèZ¨q“‰¶gQbl°ÉÁ=Ìa¶vhvƒc¡ÀÜhÒ±¢€Ž[¥ ß¶¸79Ö4éQø.>òØY$=ÒÌ×ÓœâÈÚÛXh0øôÝAaߣñ4/­.©leŽh§kã·omº}ù=Ý]˦¹ô ÝYëеöMKÆ.Sg²ÎâOk˜çƒmbÚûвC2xj&f-O',ŽikZë5Úˬt9ºF*¾r1¿ðÏâfh|YåÅ’9í&âçKÜ5ßVžïÕ&FÇCƒ¿ …õÆ•îsd¦kîZØÚÓr4ÁÞâÆî¸±†Ï ÁW>„øÇb9ÖÆék3Ïn46Àßßê±ÿ(Y(qYq*VÕRbH\ç48Fár×nnÈ w´gˉ¾Læ¿„t@¸¹±µ€“m>ð´« ‡r6 PÕÈÆ>Gç>^÷<êÖåSTe=ªŠÒÊgìIpõÝ,läáëºXØ;Ëã>N‹SäŠgÉÑj|‘T‹›á½³è}ðõ½,läáëzXØ;Ë|§ÉÏ“¢Ôù"‘sa†öÏ¡“‡­éc`ï'[ÒÆÁÞXóäèµ>H¦|§É‹› 7¶} œ=oKy8zÞ–6òÇŸ'E©òE3äèµ>H¤\Øa½³èdáëzXØ;ÉÃÖô±°w–<ù:-O’)Ÿ'E©òE"æÃ íŸC'[ÒÆÁÞN·¥ƒ¼±çÉÑj|‘Lù:-O’)6olú8zÞ–6òpõ½,lå>N‹SäŠgÉÑj|‘H¹°Ã{gÐÉÃÖô±°w“‡­éc`ï,yòtZŸ$S>N‹SäŠE͆Û>†N·¥ƒ¼œ=oKycÏ“¢Ôù"™òtZŸ$R.l0ÞÙô2põ½,läáëzXØ;Ë|§ÉÏ“¢Ôù"‘sa†öÏ¡“‡­éc`ï/—TÖµñ·{òG¼:, ÿ›ä_9òtZŸ$W˸gKµc‰7ŒÿÊáÿØR•͉TÝ›†®épï/ ’µÔÑ9•@0°[8iÔ?÷,_¬2šj«†æÁ›¯Røÿ‹e<12 ZXÐxí6˜Žâ”« TÝCC(1 Æ`u/ec® 3_-ÐHùJ-\v'³'¦ˆ±À·ƒmÞ35[˜´¦xšÑ+Rë„|b¯ú&úN[Ø®5UGNêy%’¬¹±æÉp¶ŽÝ͹7Ðõ-#ãÑ7Òr߯m@¯¦¨‚‰Õ‰‰šÀ3­{ƒ¯P]6¼(ï±å£b:øåªª¦c驘Ç=€¶ç8¿“ŸGóX#ÇhNKY<œYµ Îc%¶pîÞ×ÕâJz |ø‹ê*"–¦Dè/™i$œÛ“w;Y#N­VÑ—$h磣§š¦¢^(ײ9$dN%® –Y›þ‘¦×ùU͉ö¹¯hsHsH¸ Ü£+1¸èñŠl3‹I$Õ /aFÐ@6 8F½èRLcc±±¡¬h­ÀÌ¡1*Z÷c1ÖR6ªÌ‹ƒýT°µ®¹=„ó D 3É”xs*$…“ _NìÂ, AÒ{¥ÂÇVƒ¥f“¡ŠªŽšIse¬f|"×9ÆŽpµaÉæ1 ŠÚÆZôñ²ñ‘ ^ZHoi¤ö ]×YÛƒ1°PÆÚÊ ú6pl”fg=ºím¦ÃHèÖ€“Zb°ERúg2N³GYaw狇 :Z}Ïÿ»‹}BUSNqØëÙ†¾WÄÜÆŽPa!ƺ!œK@'¶$i6ùÖfbÔÕ6š:¸Ÿ3€-kMïqœ4êÕ§ø,¸,tø‡’ª¢¢§4´É.`¸6Ñf´ þk^&)(kiêaž{ÁcklÁœÀÁœCCŽ€4^׿@M¢"ˆˆ" ˆ€""ˆˆ" ˆ€""ˆˆ^/JñDDD@DDD@­ˆWC†ÑIWPm vÎ7À/§›JÒ)p‰xbÚØLqÊbáðæ¼†1Ä‚/ g€O1[X¤§’&ÄéI-!xi6p:ÎŽe .MÃŒVIUˆRÉO&ypÑJׇ5slæ› DÏ—^”»±jxêk"žðGI s¾yÑc³´ƒ}Ìuïe±I[M]’šfÈÆ»4‘ÌuØøÇFbªåÅY3WLÚaÌÆIinuûgsÂÛô„NMDÕO' $’æÜœÖ·ý MÈ 6^~ë‰}$Ùˆ™yû®%ô‘ÿf"æ«ÄÏ>ç™WçK8ÒCYˆUVThbk3¥áŒ`]ÎH#žÊ»)é)jø(£¯s aáÒÍQ:N¦‘{hÑÝ7S±AEf!CZbûm@µîp?aýŠ•”õ”Õ¸ï }=Dm¦c8FÈÐ.òtÞÇAÖ4-­xQÕcËD´YGŸW;é*˜ds[~?&¢uüªÌØbpkq"×{ÓÆŽŸÄ\òž¢Y±åÕ ØÆ:uùþRU꺲zZ:Q3È÷‡fðQçXÛÕujž0^ºðS1&ßg{ÄüèûDâÌïxŸh¹ž9‹â”u5N©Å«)ß=;[g,ÎÄÂýÝwùHS˜UM\óÓGÇk¦kåˆ8ñƒ¡†6¸’oÎ]â¿È¬]2áÅYÞ±?:>Ñ8«{Ö'çGÚ)VûнYºÁÅ[Þ±?:>Ñ8«{Ö'çGÚ)dLd‘Ñ8«{Ö'çGÚ)dL`‰â­ïXŸhœU½ëó£í²&0DñV÷¬OδN*Þõ‰ùÑöŠY"x«{Ö'çGÚ'ozÄüèûE,‰ŒÑK"cOozÄüèûDâ­ïXŸh¥‘1‚'Š·½b~t}¢qV÷¬OδRȘÁÅ[Þ±?:>Ñ8«{Ö'çGÚ)dL`‰â­ïXŸhœU½ëó£í²&0DñV÷¬OδN*Þõ‰ùÑöŠY"x«{Ö'çGÚ'ozÄüèûE,‰ŒÑJ¢cWozÅ<èûDâ­ïX§h¥Q1‚+Š·½bžt}¢qV÷¬SδR¨˜ÁÅ[Þ±O:>Ñ8«{Ö)çGÚ)TL`Šâ­ïX§hœU½ëó£íª&0EqV÷¬SδN*ÞõŠyÑöŠU"¸«{Ö)çGÚ'ozÅ<èûE*‰Œ\U½ëó£íŒ¸tøƒ¨x\F:€òÀÙ&–Î \ŒàâÛØ¾…cæ\«+hiq=5d-šb.%®îðÓòj\t^O‹¿UùÔ›ÉÉñwê¿:“ymCóD$FÐI°-'žÝÕè†GNèED&V4=ÍÍ7’×Ïš|JÐÁ©Éñwê¿:“y9>.ýWçRo-î'QßbØ>µŠ¦ééfŸ„Ü íštØ_º¦)ùoK6)<—¹¥Î{ËÉÒѬ’‹&]»?&ƒÎ‚ìÓüÚ‹’¯<ûže_œ$ì>ŸŸ¤ª`|/0¸´ê%¯s…Ç8»FŽuTÊÈävP†µve,lýPÑ|ç›[˜é>Uj’‡”eÄ©LÒÄÁèžZâÜâÛ XÛ˜•LÊš ZLq°CC|ŸéÏÙ \èþåuÝúGbšÕ×ÒÒææt*ª4,¨ˆ¸ËD@9—2ÊÞ¦ÿ¸¿òºo2¦;v/Sˆ4BÂ#«q5„8³7@ÌpÔã­iC€Yj¢mfi™,ü#\Y+ì׆ÈXízAÐu Øü¼$¯Úe‹ƒŒ üÏ‘ÁñvºKsÅ´7V‚ÞyQÕ=Åΰ·8é$ÌI?†¼â5S…ySìÖ˜ÑiÏO(© ª£…ÏfKwÔÞV< aÍk™§?C΋h2T´ñá¹3SLùØ^c‘Å¢V¹­¸:šÖ |£YXxGTá^Tû5¬ÇÆÜj<6£ ¢c ›>3ž-r-¥£¸¥V„™oñ]ŸÁ¿Ý¨²eð'ˆÀé5%^&y÷<Ê¿8#~H*jeÄ¡¤©u4Îà­+. qpÑrÐEù¯uMÊZfQãb(VËÓ1Î2Î÷<¸¹àœâMÍ€Ò2¹IÇL¸Ãjšéœ3ÝœmÎss¬;¶TÜ¥ŽH1°Ó]=KÍ3é&c3.x¶nh ^ÖçùVÖ¼(ê±å£.§~%‡º–¿9œ.ÙÜße¾ÕÑâýÒ;Ðr粸–èI{Øç°ÿ¡ÙÚ¯ü,~ÕÑâýÒ;ÐrÐØå¹_ñÏÿkòÚ¬ÂLùðþ[+þ9âí~[UƒøIŸ>Ëbt6ûн^7Þ…êçz’@5*pÊ*¹xJŠfHûZîÊ'!ËY¸A$5¢™ºN ¥ªk…4¹†š¦MΊ"áãTØ0øñoгi%|Œcðâë°Ø‚ÞØ1¥z6huÙÁ[Š]T­ã*¸y<‹ã\ÐæAÒç^¨Ü‡'°*L&žY%Š™™|‡¶:IÓãRK†â¥VÕW¤¢È""¡!U±œk(i2ÓÃ0ì.Œ.¥…õU¾t`:αÎX Þö Pä䨮[dý{1ZšfRgÈè#¾l™®i¶±kÞÇA¸Só|b¢ú¥G§ ïµM«XjʼTÕ)§“Í/¾’QË"–Ÿ¤òW’ê|7¿h;Ru[V‹^úô+:gÆ)þ©¦õ °ú‡máTS)ÎeïËìJž!x÷¶69î6kEÉîcÕ^¦©‹ÈÙ«a£Ïmø?Ò+«Vf‹´µ JynVg4kä¦PvO“Ôø·–†.†äX‘pl. ”ÒÑÁ~Ãþ­¢òËê0vµ`P¥ÂÖÜ•¦a$„Uü£Ë+%ë0êlG‡á1 qpLÎÅ —iÐ;aÝV­vnQE7*Pª˜{ÆL‰ZDYDDÄ3EQ’Y#§1À_jZŒ˜x½+Å",rOOc$•Œt†ÌpÇäî©I½^Ä2s ¬ËÌ/žêÈ)e,~yµst|œ#¼jÊ£æøÃEõJN¯Q•8E6RSäüµY¸”ìÏŽ,ÇX‹®Öæ+®µzý4%5a¥ó„›öErDÂ*½.Pã~+090g3 †#+´öÄm:´œám}©V…ëÙiWÅ'¬äÿ4%9 ©­ÊaG^ü¥­†©æ©ì€ÆÍ %®Ô‹ Ö£ðoÜdúÝOç=^ÝÌ6+¦mg­t|9Öh`߸ÉõºŸÎz`?°ÏªEèÁ¿q“ëu?œõ Ìb—ÈZlV·?‹ÓQDçðm»jÐÄ…z¨ªºª¢•-Ô’÷è£ðsû¶o6Lì©îáŸy3²§»†}å8Yê±Hðøb.{`~cßJ æ˜[5¯«/q{7UïÎsT|zƒê?ù93²§»†}åóGA‹?f#ˆº—µ„Ä$÷oÏüJ•KLYñ}ß8zMDËÿ‹îùÃÒj,*ñ3ϹæUùÁòOUM.%-;g¨kìÖØ½À¸žà»å²§e1«Û]SQMS+©Xàèâ-`ÏœM뾕q}c¨&ĪYM-KšbkbŠ×qsÜѯP¹<À©ùNê¾^Ϭ¦§dΦc¸8e$[9öźMï§7U´-­xQÕcËFiÙ%‡º9CįcóyÙÛZÇÅâ+£Åû¤w åÍà¥u>#@ìæ¹“=ai¾Œëiùn é~ƃéè9hlrܯøç‰ÿµùmV á&|ø-Š¿•ÿñ?ö¿-ªÁ€ü$ÏŸå±H:}è^¯ïBõs½Iˆ OÁ?ôš/ûcý+5CqKzi©™µKœoüC‚¬`—÷%Šúù1þƒ—¡ôê-Lþª?äQê\QyåÂ"ù|‘Ç›žö·8Ù¹Æ×=Å:ƒF§áÚ¡›ÿ›ãÕ*=8R§áÚ¡›ÿ›ãÕ*=8WE?§ý¯þEC>1OõHý7¬tÙG„Vc•8-=s$Äi›,´h絎±¨ó¬ŒøÅ?Õ#ôÞ´0ì §ÊÜWŠŽ&VÊÈÚù€ÒA|y£Ä®©´ÕNäÊ¥Do–¼†| õáÀ‚Az¢0|§ÁñúšÚ|2°O-ó'hc›šnG8ÔtŽâç¦ÝuRë¥6–¯o¹2Œ—Ã(pÌ.Hèi!§cêf.46äHà?ì[GÀ‘ÿúE}`¿»ëþk×Îð$Áþ‘]ªuU[©ËÅÿd.Là,?êÑú!o-à,?êÑú!o.{Þe_vJÐ(Ìo(p¬œ¥Ž§¬e,2?ƒcœ »µÚÀâ“P9WƒáøÎM#IDm¬„†¿šï ?ȯôÔÚªõ4Þœ/X×ö‘TÆF|R jºÜI!Š`Ú²èÜæ‡[õ2EþPØºŽ¯kYYƒµ Š¢€à%[î–6ÈØÜö‡»Þ´'øtÒ¹–ôˆ‹B"ªdõVTÏ•˜ôX«i†¹”e–ÎæpÔoï ¿>®uµ«.åÔšXTæõÎ2܆൬5tÑÖÑOK.wFäõ.#QˆA†FʪiduÝüì5 ZÖãp-·Í¤`¹¹±:Oi]v)N‹UU )”µZèô>'¸/ÁîúÄÿšõó„| ð¤W­Àp¶ 6&À‘¤é<ëÆà8[šÚ65½ÀHÝgUvž,Þntûóæ!šã´™5Ôøµp”ÓÁKp‰¹Î7 h°$s¤ð|V›Áéq:Lþ/S‘âθGu`“&ðiiÍ<˜|/€ŒÓ®ZGrÚ¬¢2£&&“&'¥É˜ ¥®­„—µ­\a£RÚ•ô·¢‰tÔêñ={©á¬ûüHÏ–øî/“ø$Ux6Ê5¨dNŽÄæµ×°ÒtæµHâ/’L6òÇÁHêŠbøï|ÒdmÅþE©„äôc£‚«›8w4œÓ ±$}«yØð©à"ä#W:‡_ÓЩ¡kKy¥®ÜD7™î#ûöõ·~Lª ÉZLWô‚bóO;&£§‘íc3]˜öÚú?ù û¶ pà8[‹K©KMÚI: ­£Op”8^iœ×7ëçù‰EŸ¨¦ËUQSNÑqž|ÃS©"Š\"„c”‘-©¦s›œëŽ¿”øÒ,"„ã•q/i¡s[œë]-οx–]•¼3‰é:sÉ–O(ü;÷ì[ëmü˜–BúüIŽ‚íŽf†÷v£ƒaѧºJÝÒâÚFãwN“kiÓÜ"ÝKo4¸}žã6Ed–YÓet˜›)èªiÂ'pÀv׿sQítŽk…-ƒ~ã'Öê9ëå˜ÀC(ØÐI&Ä‹“¬ë^·ÂØ,ÚF4\›F’nyû«Kõý5UUÙ'M.2×E¼þá'Ä×¢øÔð_uŸª>¢ïËY…6> Q°0 f‚mn宇ÂÌf3FÂÂ3KI6·r×QÚÚÅŠ^³¢ÿ± cIÿôô‚÷ýÞŸëp~`^;ÂÞÜ×Q±ÍîHþèì xÔŒprN‘öªÓ]ªc7“>Üù ÏqO}Cõ¶b•ß aLÿËrñØëgR0ØÜ\ƇÃæ¸Ò0–é“£ù¥5ÚI)|xoûŒÏføÃEõJNÆ>©'¦ÅáÀpÂðóHÌ๸_?È4\)l ¹¹þhë´ç7šKM£Ÿ!™îûö-õ¶þLIƒ~ã'Öê9ëÁ€á.-¤`.7qé6¶=À¸ÁfÒ1¢äØ4“sÏÝJ«µR‰|8l£q™î ûŒŸ[©üç­ÿéðÿµú–óp1‚ͤcEɰ$i&矺¼ì à¸.%››™skjµ¯©Y]µ‰Õ/Tô\ùóÌUCM‰dŽ)KW’S=Ť‘¥£9§Gp€~Å¿†áÔ˜FCŠ–fFÀI°þ'IX€áoac鿏X´’AÍj*yÁ…mim4B¢—Ýä‘Â4¸X\žÔ;캵¿çSOÓQUN\Äqp´HyfZ‘W«h0ÉpºjªHÁŽi©‹$cÝÛ1Ò³åÔAþk%vC^h}Ik€s´Ž Cc§ºûJÍ jøðÙNäË'y—!ý | }-Gø².½Ì¹éà\kéj?Å‘gl“¬ HƒR+ˆˆ ¦_ü_wΓQ2ÿâû¾pôš‹š¯<ûže_œ'tòUâ"«ƒàZ#y2ZÍ-sœV ó©YM[K[Ž i뢞!LÆð׳ œò{zFw²¹ñ |J§¥ªŒIŒ/Í:®×¹Íþ:Z ¹ÕK+ ”Â&I ’¶™‘æDEóƒžm›rA±>Uµ¯ :¬yhÒ§žiqæ'õ21˜g_û’ºL_± úGz\Þ §Ôâ{^Öƒ ™ i#:ú|k¤Eû¤w å¡±Ër¿ãž'þ×åµX0„™óáü¶*þWüsÄÿÚü¶«ð“>|?–Å èm÷¡z¼o½ ÕÎõ$""€jÔW²š\ÇARókÞ(\ñãDä6œ‡ÁÏý3UWòâFõv®ºZîµBýTÿjŠþ¢À´qlÇh¸ž)IU>p~dœÎˆî'Æ·‘sQ]TTª¡Ã[©UÊì~RQa´´X¬ØLt2‡´S·AX j<Út+R"Ò¿¨¹rÝ6êyS1ûëÍþá$œ„DX’DDD@DDGʪ\?ôƒà’SÎéªid ‘ fŒ÷4Ê7þ!OCñŠ·ê”þœËx±…áå­.m!hÃñŠ·ê”þœË²«–ë·SL<æ^)ž_b°ä…Á0¬¤¤ËO1¶8£¨¥cÑ`Ö‰˜¸¾ñßp¯­ŸÉ•1ŸÜcúÝ7ç1he.7†àµ83ñ*Èé›%Y /¾ŸÕƾ–£üYÉ:ÀÔˆ5"°ˆ€ªeÿÅ÷|áé5/þ/»çI¨¹ªñ3ϹæUùÁÒP3—¤’IÇðD˜ÜZHkÜìÒG1µtª9UA6,Úx¨b‚˜Q°pQ4pz_%ôXä­òSOW.%5Sé¥wúØýðh{‹€îÐ[~kß™S2–Š ,x6ž)¢wc‹ß!t¥ÅÏÙ÷.&À ß™mkÂŽ«Z>!¨eF#‡æÄÖ=Žc^áþ³¬ý–bèñ~ƃéè9sˆd§“ÃÝ eÏg Ü.ÎÖ>Ë.ìh>‘Þƒ–†Å)\Øq¼bq /IFXp-<ëk'é+ ‘ÖÎq€› i11Cå•T£(ñJXZ˹ñ¹Îy:¸&S8Ãd,&å¦ö˜¤¾ô/W÷¡z¹Þ¤„DP J–â_øY)›µJǰ…×ì¾¾,Õ`Uü†ø‘ƒý]«®š§éj_ùSýª+ú‹".BÁD@DDD@DDT¡Êª/tÚ¼žàgãN¤‹õ™£2íÏyÓ{ê} «jøàcá¸n œ-³sóEíܺÞÍËt*Õt̨YÄ<¡óûÓà}¢"Àˆˆ" x½+ÄD@DDD@VòÛ¡ÉÌ *ÌAÏÈÐÆçCÃÈÙc¼KwÁpL©¥¢ž¾Ž:È™iéÜðE®¿6±moÖáôX•?¯¤‚ª‡psÆÛFÄYgkCZÐÀeÔ¯ÓEº{)U¦óãN%b^zó.Cú@øúZñd]{™rÒÀ¸×ÒÔ‹"ÊÙ'X‘¤VL¿ø¾ïœ=&¢eÿÅ÷|áé55^&y÷<Ê¿8#~FÖ¾\I¸|‘ÇRx,×½¹Á­Ïvqœæç[šö¾…MÊXŸOŽŠê¹Þi˜ã$çMËž=åƒ@Ð4fÛäW)%¬‚\JJY5Oêƒ[!³@/psvÀ—Xkµ¹Õ;)MSq¶™ëa«Ò±ÙÍ…­ß<9Ö¿¾¾kk^uXòÑŠÓ Ku;‰.{ #Þ»;Pû,~ÕÑâýÒ;ÐrçÁ8–è¥9-Øs­câ¿Úº<_± úGzZ·+þ9âí~[UƒøIŸ>Ëb¯åÇþ÷<7ù•Q[V1Úç: s¡S‚‘®}¥?û³[§F­m(´ëyàžEˆ×3ƒtqTpmŠvÇU#tZ[{[tóâ—ÅD4yNè Cj[™úÆóÁ ‹²Î$ 9ÜÚU¨új«IÊS¹ “U8m%\¼$Ñ—>Ö¸{†°¨¬†È|Ó5JÔâÓKÁ¾—›^ñS½ãÆ +!ò?ôÍZ¬}Ö¬Zb¦:T?Q`DEÄX""ˆˆ" ˆ€""ˆˆ" ˆ€""ˆˆ" ˆ€âô¯D@DDD@DD™rÒÀ¸×ÒÔ‹"ëÜËþ>ƾ–£üY¶È:ÀÔˆ5"°ˆ€ªeÿÅ÷|áé5/þ/»çI¨¹ªñ3ϹæUùÁ﬒†\J¢*gÔÈÞ ­‰†Ä—=͹<À^äóJ§åC«F<[ ' i˜s!/Ð3Ÿažu›ßNo>¥pu|XlØ•TÍ‘ìi‰±·9Îsžæ´ò—ÜîªnRÉ!ǦÃ]IzfZ6Ì×879öí@͹7Ño•mkÂŽ«Z1ÃJêlGvs\ɞǰvζŸèñ~ƃéè9sjziiñ: íd‘Žc¯ï†u¿ú+¤Åû¤w å¡±Í²¨Q·)qÉê ¦H¸Ö0ŸxÚ9þRiH/{›rHäËILç:*v0¸‡m7ü€S Þo½ Õã}è^®w©!©85n=“ø†M“‘ñ^ÚÈ€s¬OÙ vEÑfú·K¢ªUIÃÎxNÍnU©+ü±” IçÑ,Se9NdÉy{ÄmÿŽ‹YÔ¬¨¬¯ÛœíSÖ¯‡¹_匠ðZO>‰bŸ(1Êf5òd¼®{X-]ÒçæB²¢+öç;Tõ«ä!îWùc(<“Ï¢Xª2ƒ¥óK’ò7YÑeDWíÎv©ëWÈCܯòÆPx-'ŸD±Tå9KM-D¹/ Ž&—¸Šè€U•_·9Ú§­_!r¿ËAà´ž}ÅS”å%,Õ伂8˜dyÑ.U•_·9Ú§­_!r¿ËAà´ž}ÅS”å%,Õ伂8˜dyÑ.U•_·9Ú§­_!r¿ËAà´ž}rÆPx-'ŸD¬½¿ô©þ¯‡¹Z¦Ê r®–ˆ²^C¬0šè…Á /,e‚ÒyôJÀµkq |>.£† ±%ÑÀù]óA·Ú¬¯QUQM•ý_!ÈJl Ç*éa¨‹%ä1ÊÁ# ®ˆ\p²òÆPx-'ŸD¤)*¨ééÛIOú:h@…î­Zö±wþÝ"ÏG_p”Àd¼NÌx’'ÆA°:œÔBµuÒ›jÊý¾B9tùAŽUSGQKÈc‘¡Í&º! ¬¼±” IçÑ+,Ýûs•ªzÕò÷+TùAŽU@Ù¢Éy {]ç²ËËAà´ž}d±HéŒs£vkÃ\ i°6=ÃbÚ¾ÔÕ~ÜùK­_!rµPc• s£ÉykݽtCKIù…—–2ƒÁi<ú%`Eý¹ÊÕ=jù{•¨rƒ¨á8<—ðo1»þ:-cZËËAà´ž}°";öøZ§­_!rµPc“ºV³%ä&'æ?þ6-ÀÿbNXʤóè•ß·ÂÕ=jù{•¶cøä“K r^Lø­œ8ìZ..NXʤóè•ß·ÂÕ=jù{•¶ãøãê$€d¼œ$mkœ8ìZ{b²rÆPx-'ŸD¬Žý¾©ëWÈCÜ­·ÇU%8Éy8HØ×¸qص8¸D¬œ±” IçÑ+#¿o…ªzÕò÷+mÇñÇUIN2^N65îv-N.Ñ+',e‚ÒyôJÀ„Ø]û|-SÖ¯‡¹[v?Ž6ª:s’òp’1Ïhã±jih>Y9c(<“Ï¢[cÃ¥«ãÔ éÙÁ溚V¸‰6 -»êï¢ömJ•³G žàù Ü-}AÆÖi<ÀØ­j©(þBþ¯–ÐGîC;ÇU9Éy8Iç´qص4´H,œ±” IçÑ+,ûéSÖ¯‘0÷+nÇñÆÔÇNr^NF9ív-M-Ò <8¶:ù£d™4øãs€søìG4_I°Ö§Qûmeiu«ä!î9—!ý | }-Gø².½Ì¹éà\kéj?Å‘el“¬ HƒR+ˆˆ ¦_ü_wΓQ2ÿâû¾pôš‹š¯<ûže_œ#Æéhj1:ŠÉ ‡9ÂúKœ·9$€9!Rò–ª*ŒpH!®…¼Y€ˆôØ9æö'>ÇH¶môjWf n5‰³¢7¹ÒÛ9ÄV óYRr–º’»Á]Ã3‹1¢GFæ´ÙÏ$çf†ÛN»ÛZÚ×…V<´`§lìÄè›>}ƒÙÁç¹Üß&µÒ¢ýÒ;Ðræ´ÓO&%CÎ'‘Œh"Ö×þ䮕ìh>‘Þƒ–†ÆzŠÖRFÜæÌâãÿâ‰Ïñæƒe^•5µ8|ŽãÂ!‰ºW`aÍÎÎ ÎÍî-d@eo½ Õ­QTÚJIgx%‘1ÏpÈú7e±pM—“kƒlÒ[¹ù;}+'KX‘W;/‡«k¶cßNËáêÚí˜÷Ô`d–4UÎËáêÚí˜÷Ó²øz¶»f=ôÀÁcE\ì¾­®Ù};/‡«k¶cßL 4UÎËáêÚí˜÷Ó²øz¶»f=ôÀÁcE_*Y+^æá•¹¬Î'‚î—¯ŽËáêêí˜÷Ó ±¢®v_V×lǾ—ÃÕµÛ1ï¦IcE\ì¾­®Ù};/‡«k¶cßL 4UÎËáêÚí˜÷Ó²øz¶»f=ôÀÁcE\ì¾­®Ù};/‡«k¶cßL 5Y‡ÕÖáâ–ié]~¾”¹§MÚCsô£MΑ} ?²øz¶»f=ôì¾­®Ù}^‡]i#S=6%%_TyÁÏx{¡&G¡ÎÎÒÛœìÐ9ô©jZfRS¶&ë{ç»ß<ó¸ü¥Av_V×lǾ—ÃÕµÛ1ï«\¹r牄’,j,#ª“%«3 ÇM~´=¥À¤ö·Ð5¬—ÃÕµÛ1ï§eðõmvÌ{ée»w)®&}ÍAúœ]Øœ‘Ó¿‚šLP·…oÎâæŒiÒÎú, ÔV>%•††3!Äœd¦¡’¥Î vtD—‰ƒ$‹Gp.t’>KOeðõmvÌ{éÙ|=[]³úôפ£²\6áûq)ƒ™'ñ®G§ãsÉ<Ö?¬’ œÛœÛ°’Aµµéù¥ «—ÃÕµÛ1ï§eðõmvÌ{ëÍ®k©Õ—Es²øz¶»f=ôì¾­®Ù}S$±•â®ö_V×lǾ¼ì¾­®Ù}00XÑW;/‡«k¶cßNËáêÚí˜÷Ós²øz¶»f=ôì¾­®Ù}00XÑW;/‡«k¶cßNËáêÚí˜÷Ób{g3ÆèåcbÜ# .\tZÆú-§˜ßäP=—ÃÕµÛ1ï§eðõmvÌ{êU-d›'d©™óË=!‘Ò2BÑJDo!¯mÞÜþØû^ÿé ,X£¨¦•Õ-q‡7¶1vͱ'5†ý«MìEŽŽ}K[²øz¶»f=ôì¾­®Ù}t?¨¾ÔOö"cE\ì¾­®Ù};/‡«k¶cß\ØbÆŠ¹Ù|=[]³úõ¹[ÞÜ6¸¹ÆÀZ=ôÀÁbæ\‡ôð.5ôµâȺM4k*ÝLpú¸Ñréƒ'¹·éà\kéj?Å‘iBkR°5" H¤D@U2ÿâû¾pôš‰—ÿÝó‡¤Ô\Õx™çÜó*üà‰&ÑAˆUbõ1‡ÄL/±ÿ™¯sš~Ç4±SòªhêrŽÑÕÒÏ ¦c b•¹ÙÁÏ$fܛ؂­²añb’âTs9Â7ðEÙ¦×Í{còXŽpHçUL«¡0âíc(™ ;i3bgêÇo%ù€[Zð£ªÇ–8*¤©Ä0öH821a¦Ù×Óã]"/ØÐ}#½.o Kj1>Ñ5Žc˜×8kyÎÖ|vûEŠxxAÃF oqp/Ý«‡÷+Cci¨—lÕM äF¤ç[œñŠâ5Í…õÙĵÆGæ»8ƒ˜;Vn³u . LUS5åâxCˆ±!âöGUS?ßO¹ô¼2¢ ˆÎH‡ânÄ2W­|-Ž! Üc‹¸FžÛKZEÍô[šüêŽüržÔµSâå€~­²:+;E®Ð_{ £W ZÌ2¦ˆTÃg…ñg×8{_åUaX' Ù]‰Ê熑s(#M®mö(D½”Pt Gð·Ö÷(2Àœ:°\c=8:~NHv‚õƒ¶Ú•†TLé]ŒÔ4›hlŒXXs)Èü¡WÕùÅ7´NP«êüâ›Ú-ÎÁp®»ªò¬õ'`¸W]ÕyVz“ iò„}_WçÞÑa¨Æ©©X5 `6³S¸“ü—R]‚á]wUåYê^vƒ÷âÓÈY{JÛiû CvQAÐ1ÂßNÊ(:#ø[ê{°œ¬¶Ôì'ëmµ2¹SFú9éÙGˆ0NÜÇ:Ñn{vè2ž€8†#ø[ê°œ¬¶Ôì'ëmµ2eü-ô좃 b?…¾§» ÁzÁÛmNÂp^°vÛS @öQAÐ1ÂßNÊ(:#ø[ê{°œ¬¶Ôì'ëmµ2eü-ô좃 b?…¾§» ÁzÁÛmNÂp^°vÛS @öQAÐ1ÂßNÊ(:#ø[ê{°œ¬¶Ôì'ëmµ2eü-ô좃 b?…¾§» ÁzÁÛmNÂp^°vÛS @öQAÐ1ÂßNÊ(:#ø[ê{°œ¬¶Ôì'ëmµ2eü-ô좃 b?…¾§» ÁzÁÛmNÂp^°vÛS @öQAÐ1ÂßNÊ(:#ø[ê{°œ¬¶Ôì'ëmµ2eü-ô좃 b?…¾§» ÁzÁÛmNÂp^°vÛS @öQAÐ1ÂßNÊ(:#ø[ê{°œ¬¶Ôì'ëmµ2eü-õçeAÄ }Oö‚õƒ¶Ú„à½=ÛmLÙFÐqÂßNÊ0þƒˆþúŸì'éîÛjv‚ô÷mµ2eAÄ };(Ãú#ø[ê°œ§»m©ØN ÓݶÔÈ”aýü-ôì£è8áo©þÂp^ží¶§a8/OvÛS @vQ‡ôGð·Ó²Œ? â?…¾§û Áz{¶Ú„à½=ÛmLÙFÐqÂßNÊ0þƒˆþúŸì'éîÛjv‚ô÷mµ2eAÄ };(Ãú#ø[ê°œ§»m©ØN ÓݶÔÈ”aýü-õ÷UP²V9´‰s\ý–úœì'éîÛjõ¹ƒƒœÚén% ÚJY÷“˜ƒ¤Æå§–“lÎa.’¥ÌÍ`×~àUoÒÀ¸×ÒÔ‹"¹`¸V†â•5b’r[Ã?Út]S2ùÍvŒ¹¤e¨±þ–E §š!4Ô£¬HƒR($""©—ÿÝó‡¤ÔL¿ø¾ïœ=&¢æ«ÄÏ>ç™WçoÉK-l¸•<52S=Üë#6uƒÜ\渷Ö/p©YM‡QÑeE='wc³‰»Ë‹ž Ϲ7°÷æWY#¬’\I”6“ÁZG4:ÍÏvuÑ|Üë_EíuMÊX]MˆÙ[_(4Ìq58Ü—<{ÓÚÛ@Ñk-­xQÕcËF8e‚\K0ÆZðö IÔçgke—HTÔT3ÏÏ‘±nnâÏ0÷¹þö ›ÃŹKu99Îs ­æk³µ²Êû,øufÚ)±Ž(CÃÁIuÚnÏœeª6'Ä£«Š•ò4TJÇ>8ÉíœÖØ8ÜÍñ…ñY.‡±«™¶Gæ38ûçX›é°'ì+Q¸®&§ãAÜncšeŒ6Rs{gXk¦Ö°íŽVÖÅkh1 (31¦¨2—Ç,yÖàÞË ëõaNDÔÐKW‚t…NéÄÇà_’°Í¥|d¹Ú.4µº@Ñ©e§©Âé¡®¸óœê·¹ü!–èœE®Ë4 -pu&@‘–|6 ¶RË;;íšÂté62µãÅpI 3G] ãæº÷U»¿bѨä:œFš¹ø»DÐiCwæ›éu³´ó€@?jùtxDØñ~ ôP¶$lÑ—44X ‚mò[N¤È4ÕTµô­ª¤Ó Ÿ#6Ó˜òÂGÉv•—4wЦ«Â¨©[O) >I å™ÎsÞ^ok n<Ë/*áÝ>—Ë7ÖªÉ3HìÙahÏqGþÒúY3Gp- 1,=ÒÂá_If8“úæÿÊGwåYyWéô¾Y¾´Öhî¯F÷Í ß&a"W´f³7C\[Ý=ÅóʸwO¥òÍõ¬4øQº¾ŽæG»µ™º‹‰È $3Gp&hî«Ê¸wO¥òÍõ§*áÝ>—Ë7Ö€ÚÍÀ™£¸¯*áÝ>—Ë7Öœ«‡tú_,ßZk4wfŽàZ¼«‡tú_,ßZr®Óé|³}h ¬ÑÜ š;jò®Óé|³}iʸwO¥òÍõ 6³Gp&hî«Ê¸wO¥òÍõ§*áÝ>—Ë7Ö€ÚÍÀ™£¸¯*áÝ>—Ë7Öœ«‡tú_,ßZk4wfŽàZ¼«‡tú_,ßZr®Óé|³}h ¬ÑÜ š;jò®Óé|³}iʸwO¥òÍõ 6³Gp&hî«Ê¸wO¥òÍõ§*áÝ>—Ë7Ö€ÚÍÀ™£¸¯*áÝ>—Ë7Öœ«‡tú_,ßZk4wòø¯*áÝ>—Ë7Öœ«‡tú_,ßZjøø¯*áÝ>—Ë7Öœ«‡tú_,ßZjøø¯*áÝ>—Ë7Öœ«‡tú_,ßZjøø¯*áÝ>—Ë7Öœ«‡tú_,ßZjøÐŽâý¨*Óå\;§Òùfú׳ոÂÑI-+‰7&I4[ä²;_Üö±ÍqÙ®·1°6þa3£î·Æ¢¸±— Äi橦Ögék‰ks˜ÌAææ ü¡WÝ‘ÔÒG$–„µ´¬’>&ù¬A´ZÄ4æëç¿2ívh÷ºu|«í±‡t wU[Éøè18êÅFæÆØÛÅûhZd‘ÖŒçvº%-Õ¨à§ê*œ!µ4”Åä‹ð’X[ì@fˆ¾F5Í.Œ€û¤ÚÿØ…­Røj]-gtSÃ˘ÝM$‹‚An°E¿ÿuE#êp¬b ¥¤tÕѹ­k_Ú‚c ¿ðPòd— ÐòŽØ¥!Æ&ÓY€‡—v£?Gñs´óÙ"u!¤Ô2Ɇa‘aÆ{TÉQ$Îs¤Í¾oô€¹Çéà\kéj?Å‘]0,Ÿ ®¨ª•ôåö ‰ÍµìZÞÄë»ÜÛØÞÖ×¥R²ü‡`˜Éij,GÕdD£$)I(GY‘¤PHDDS/þ/»çI¨™ñ}ß8zMEÍW‰ž}Ï2¯Îß’Jȥğ‡Ç•?ª _4÷8ÛI³nmÏksªnRñ¦c€Kˆ¶°šfxÚÝ.xÍÐ3€¿¾¾jå%TÔRâSÁLê™GÖÄ›{½Í¹<À^ä÷Tü¨}xÇGmÞiXRÙ9öÅÖ:o§7ŸRÚ×…V<´a†bİ÷C(æ9Íטs­câ¿Úµ±„ª¾™ÿÜ­˜iM6%‡»<9³9ot ëiñ-lCá*¯¦÷+Cc]D@DDD@DDD@DDD@DD¼^•∈" ˆ€+å;à‹ lÒ´‘qε…µª¸2ZYh “ÇšXÜæç{XØý¡J שvL8TBÙç®t Â@?.¥®ÚZs‰ gPA˜I÷²’ö4^ÎpÔ¶7ÓòoÌøf®£x©¬Î.%ãEÚGÿkî*L. §ÔÇ^Á$Ž.pã2’yóI·òVÏ$PtføÊrEFoŒ­Î§Óí' GÓéö|‘AÑ›ã+f—¤¦d²CZý;ä_|5O§Ú_\n’8^dq"À;¹üP<©OËNÕ±‡¬·ÅcãUL´ø³Šý%Gø²©æaXK+øï½F^gÖosu–Nk²_sH ¾¢ÄúYT0ŽÀ5" H¨HDDS/þ/»çI¨™ñ}ß8zMEÍW‰ž}Ï2¯Î™ øR¿ø3û½jåMÑã4&Ô”¦® /’¿Q¸fŸô“òó­ª…+¿ƒ?»ÔšÚ×…V<´rJl(âl2;#¨ÙPÐ×E(ã§„¾½KpÐåY$œ˜a'ŸþÚ®ž‹I69Ê¿ý7µN#•~ 3úojº‚$ƒ—ñ«ðaŸÓ{Tâ9WàÃ?¦ö«¨"H9Ê¿ý7µN#•~ 3úojº‚$ƒ—ñ«ðaŸÓ{Tâ9WàÃ?¦ö«¨"H9Ê¿ý7µN#•~ 3úojº‚$ƒ—ñ«ðaŸÓ{Tâ9WàÃ?¦ö«¨"H9Ê¿ý7µN#•~ 3úojº‚$ƒ—ñ«ðaŸÓ{Tâ9WàÃ?¦ö«¨"H9Ê¿ý7µN#•~ 3úojº‚$ƒ—ñ«ðaŸÓ{Tâ9WàÃ?¦ö«¨"H9Ê¿ý7µN#•~ 3úojº‚$ƒ—ñ«ðaŸÓ{Tâ9WàÃ?¦ö«¨"H9Ê¿ý7µN#•~ 3úojº‚$ƒ—ñ«ðaŸÓ{Tâ9WàÃ?¦ö«¨"H9Ê¿ý7µN#•~ 3úojº‚$ƒ—ñ«ðaŸÓ{Tâ9WàÃ?¦ö«¨"H9Ê¿ý7µN#•~ 3úojº‚$ƒ—ñªðaŸÓ{Tâ9UàÄ~*ojº^$ƒ˜qªðb?7µN#•^ Gâ¦ö«§¢H9‡ʯ#ñS{Tâ9UàÄ~*ojºz$ƒ˜qªðb?7µN#•^ Gâ¦ö«§¢H9‡ʯ#ñS{Tâ9UàÄ~*ojºz$ƒ˜qªðb?7µN#•^ Gâ¦ö«§¢H9‡ʯ#ñS{Tâ9UàÄ~*ojºz$ƒ˜qªðb?7µN#•^ Gâ¦ö«§¢H9‡ʯ#ñS{U§‹à™W‰àµt=Ž9¦H¤lY“SÆÐ÷1Ì»­!¸³ò]m@‘@ˆ€ªeÿÅ÷|áé5/þ/»çI¨¹ªñ3ϹæUùÁ”î{1*÷‰£k ‹Ûq­ü÷[z>³¡ñ õ¡Qïq£g¤å/ŒÏ†É3[& ˆ³á/ixiuˆæiç ¢Í3AÓaÿ-üz>³¢ñ ôãÑõˆo©HZú8_4p:W0Gš.G0$ÛÆ³ñx;Ì{!k€ÖH~=YÐø†úqèú·Ä7Ôǃ¼Ç²‹ÁÞcÙ €IÇ£ë:ßN=YÐø†ú˜âðw˜öBqx;Ì{!0 !øô}gCâéÇ£ë:ßS^óÈ^qx;Ì{!0 "8ô}gCâéÇ£ë:ßS^óÈN/yd&$?¬è|C}8ô}gCâêc‹ÁÞcÙ Åàï1ì„À$‡ãÑõˆo§¬è|C}Lqx;Ì{!8¼æ=˜üz>³¡ñ ôãÑõˆo©Ž/yd'ƒ¼Ç²’GÖt>!¾œz>³¡ñ õ1Åàï1ì…烼Dz’#GÖt>!¾œz>³¡ñ õ1Åàï1ì„âðw˜öB`Cñèú·Ä7ÓGÖt>!¾¦8¼æ=œ^óÈLH~=YÐø†úqèú·Ä7Ôǃ¼Ç²‹ÁÞcÙ €IÇ£ë:ßN=YÐø†ú˜âðw˜öBqx;Ì{!0 !øô}gCâéÇ£ë:ßS^óÈN/yd&$?¬è|C}8ô}gCâêc‹ÁÞcÙ Åàï1ì„À$‡ãÑõˆo§¬è|C}Lqx;Ì{!8¼æ=˜üz>³¡ñ ôãÑõˆo©Ž/yd'ƒ¼Ç²’GÖt>!¾œz>³¡ñ õ1Åàï1ì„âðw˜öB`Cñèú΋Ä7ÓGÖT^!¾¥ø¼æ=œ^óÈLHŽ=YQx†úqèúÊ‹Ä7Ô¿ƒ¼Ç²‹ÁÞcÙ €IÇ£ë*/ßN=YQx†ú—âðw˜öBqx;Ì{!0 "8ô}eEâéÇ£ë*/ßRü^óÈN/yd&$G¬¨¼C}8ô}eEâê_‹ÁÞcÙ Åàï1ì„À$ˆãÑõ•ˆo§¬¨¼C}Kñx;Ì{!8¼æ=˜‘z>²¢ñ ôãÑõ•ˆo©~/yd'ƒ¼Ç²’#GÖT^!¾œz>²¢ñ õ/Åàï1ì„âðw˜öB`DqèúÊ‹Ä7ÓGÖT^!¾¥ø¼æ=œ^óÈLHŽ=YQx†úqèúÊ‹Ä7Ô¿ƒ¼Ç²‹ÁÞcÙ €IGìØ«id \µ¹¶Ò®ÅÍ.-Lt¬áÜúg9¤è@ÓÝVÉ£du‘æ1­¼n½…¹Â­¶*—`Å´ôo{Œ¯”MÂ5 ÷hÒuZþ5W–D¬Í\·s¤É¬÷888´·õe†ÙÍÖ º,¹|o“·îæóߨ¹*ñ3‚ç™WçnÔjÅþž“”æ1A.#‡I3º)9¤8†›´‹:ÚÆ›Ûºƒ¨Õ‹ý='+Zê±à:lùhÃHÉ"¤†9‹ `k‹/kŽåÖdE± DDD@DDD@DDD@DDD@DD¯¥x€""ˆˆ" ˆ€""ˆˆ" ˆ€""N§÷ȾßÜ(ˆþ+MôsúORõ?¾EônþáDGñZo£ŸÒzέK"#.¾,3æ³ûµ.¾,3æ³ûµ^&p\ó*üà‰ X¿Ñ³Òrµª¯ LeĸԆ˜Âç Ý7wt-ÁQÿ–6ú—M—ftÙ_ËDò(Y£ëa÷}IË4}l>ï©k‰Á<Š–húØ}ßRrÍ[»êLHA<Š–húØ}ßRrÍ[»êLHA<Š–húØ}ßRrÍ[»êLHA<Š–húØ}ßRrÍ[»êLHA<Š–húØ}ßRrÍ[»êLHA<Š–húØ}ßRrÍ[»êLHA<Š–húØ}ßRrÍ[»êLHA<Š–húØ}ßRrÍ[»êLHA<Š–húØ}ßRrÍ[»êLHA<Š–húØ}ßRrÍ[»êLHA<Š–húØ}ßRrÍ[»êLHA<Š–húØ}ßRrÍ[»êLHA<Š–húØ}ßRrÍ[»êLHA<Š–húØ}ßRrÍ[»êLHA<Š–húØ}ßRrÍ[»êLHA<Š–húØ}ßRrÍ[»êLHA<Š–húØ}ßRrÍ[»êLHA£§7£ÑÑLf2“™œVdÑrOÓkͨ·EåkiŽõœ4㛨êgÔÙSg¿ÊÑŒ:sʯ¥åˆtÕëž|%]1‰-fì Y‹H¤Dmt»‡×b•®â'b4²ö]Ỏf'¢žóè^?¤X¥Uü‚šOX»QøsŠ= ‘\>¤X¥'Lq`ólK ߈@E$á1öÕän$«b =ͪe­Èİ(*‚ã‘·òÍJ‹ [œ¡S)œ­‚jc2-#ŠàIc …·rNÎA¥.ë$6$h`Lµ`6 bC™S—ØC¸UúSœxh6,"Ž¢”eát>Çã"^ »äuÄ- ĘZ¦=Lñ¹¹'g™Â”=š©¨)Dcp~-ÌhiH.¥áô›Kì±'äqÞ2)²Úb-*(eœpʧ»…=‚Çi¦Ä·hUA)ž‚M~3¶/ùçð'ù"¶ ô4eŽRÝ pÇp.œ˜<Ò§Í Š˜C2c{ˈUREîà ’òë)E>ŠƒüaòT€SÐ,¼ÎÂ>EÁ,8? Y>:ÆÆF¨]»&[ƒˆˆˆH ‚ƒÃ Åf """R/XDDDD °ˆˆˆˆ`1ÀzÚ·ßNƒ\î©òHNN\þ TYç矷¢k׾شi›Ú*…Ž»«ÔãÇ—”ZvòäÒÿW®@.÷DVV–J¥R‰ôôŒU—Å‹W!>>AJïÛwׯߔҽ{‚¿ÿ©7Ò~~¨´ÉÇA/\§  ™™Y¥æõé3ÇŸä'ƒˆˆÞjOÇ0cÆOÈÍÍ-sE‹V¢K—Þ8tè×r¿¾Î‹ ‡Â×wW©y•+[”š7lØ`4oÞ¾¾¿©­¡rsóðÞ{°xñ¼–}ô(Xú¿U«æ¥Ö1..³g{cýúe¯\—ðð'ÈÏÏ—Ò±±q°²²”Òl{#;OAA!6oÞ¡òþärÏçöW±;wîáèQ?Ìœù]‰¼ýû·òSIDDo½§câxF¡P–¹Î¤IcáêÚaaËýú/uа  (,T¨,ÿöÛéèÞýs•Ñ›²œ9sAe´åéQ —¡T*¥º(•⩀ᾴMŸBHåårOtëæ¡2bsàÀ|ùå×ð÷?¹Ü ®x¥zxy Áºu¿HZLLÜÜ\ ®@÷îýàç÷‡T^ÇUysªlûÙô¿5gÎBüö›¿ôzgÎ\üü³&NœŠ={@.÷ÄÏ?oU‰Ü»wï‡ß?ñLÝS©{~~Á߯±>>»¤å·oß( •ò•ú„ˆˆèMâŸø¥  B(¥cÔСc¤cÔ† [Êõ•ÖïÖ퓞"”Ë»ÂÇgçkï8¹üSøúÃ;÷0p Ç ËûùDBB¢”~z.\þJÁæ‹T®l¡C½Ö6pvvBÏžŸ–X>~ü×*ýüùç½\ÑU¹²…Jüòt°5~ü?ÅæÁƒ ÌŸ?³Ìm}úig)¸zY:oòÍ6oÞ«W/~*xÓVûk>B(QµªõK¯ãêÚÇŽÀ_ÝÄ´i“^X¾cÇðãÓÿixš>$$ ¶¶6 S[;äååãÑ£`8;;•Y.22ÆÆF°°0WÛk[ZVVéç\ gç:pr∈è¿7oÞ4ØÛÛIi#£²…ÔÔ4˜››½™kéÒ5øí7˜™™ 66_|á 8tèWLš4;vìE‡¼t´µµÐ¤I#•6)Q*((ÀÞ½‡‘”Ttú¶aÃúÐÓÓ88ØAñ㿇©©)†  søøì‘#Ç––œœLœ8 ––•ann®ò_~9 Ìz…‡?ÁæÍÛT~EXYUæ'šˆˆþs½zuÇæÍÛ¥K‡Þ¿->û¬ÛßÇð’ÇAHLL‚·÷2é.Ä@|C”õ,ÂøøX[W)5/::Vº›ÎØØUªX(š¾¡x m88ز²²T®×rt´éQ¬‚‚BDEE«,322„µuäåå!&&îïËRÃß–••5òò²ùYYÙì="""Ò8ZZZ°´¬‚üü\@­Z5Ÿ RF[[UªX###`oo‹¤¤äço³<jØÐ™™033ErrJ‰ŠèèhA©T Z5èëóz+"""Ò<•*™ ?_u ÈÕµrrr¥´¹¹âãcUÊÔ¬Yyyùê °lmí˜XÝÉd2X[WAvö?•ÓÕÕ‰I%)ßÀÀ€=HDDDǼÄ2mmèéýsw¡©©Y‰ë²´µµ ££]ê6K\ƒ¥,T"-6­DÁ‚œ¦jÐÑцR©€BñϵTff¦*·5Ö¨QÑÑÑ*뇠Aƒºÿi#¶jÕ =zôÀ”)S¸G½ãlll‘““‹¬¬Œy ‰¨Rŵj9!;;ii%ã£ää”RG±JXÖÊ*¨e‡‚‚BDG% FM¡@-{;èþ=O„®®LMM‘šúÏiÁ¢+ëÿ‹ŽŽBpp°Ê¶«W¯ñŸ7dbb"233¹G233Rjð::ºHIIAzz*RSSŸSFûÅ–ƒ±º6턜œ\ÜP<@ûf- PªFf º 44¨ÄÆŒzõœ‘žž GG{•|KËÊìI"""ÒFFFh×®=„(9ÃA^^>òó `jjŠvíÚB©,Y&?¿•*Uzq€õ2bccðèQH©yÕªUcoÑ[AGG¹¹ÈÍÍ)‘x5k:COOQQ*g OŸ>ìË`EFFÂÞÞ¶Ôì922óçÏÇÌ™3Xj™I“&aÇŽìE"""Ò(:šZ±[·n¡zõêpssÃï¿ÿ77·eLLLJ]7-- ƒ.5/66ÀÝ»w5êý®^½öööe–‘ÉdÜc‰ˆˆ`½^-Z´@BBB‰åfffðõõ-u'''ôîÝ?þø£F½—Ñ£G#**ªÌ2Ÿ}öÙsƒJpuuEíÚµ¹W1Àz9qqq˜2e ¾ÿþ{8;;W¸ŽX½zõ ËÑ»`uêÔ «W¯ÆÞ½{ñÓO?!11ÁÁÁÈÍýgÚú 6@©T¢OŸ>055­ðÕ«W¯2ó³³³UÚ§4;wîĪU«¤ô{g:Hi ¸¸¸ð“ADDT,]]]L˜0AJ;88àüùó*eŽ;Æ|Š‘‘ŒŒŒÊ,3fÌŒ3FJ߸q§OŸ–Òyyyðññ)s .|îÓɈˆè-¿‹Êï½÷ÞÃ{ï½'¥³³³UqTšÞ½{«L¶fee¥ @Æ Ù¸DDÄ‹(srr*³Ì¡C‡TÒ‰‰‰Xºt©Ê²g/Æ1b*WæLþDDÄ‹è¥XYYá§Ÿ~RYö矪¤¿ýö[$''KéQ£FÁÕÕU% 366fc,¢çiÙ²e™é5kÖààÁƒRÚÞÞÖÖÖ*eÜÝÝáèèÈÆ$""XD/cÔ¨Q*éû÷ï#<<\eÙÂ… !¥¿üòKtéÒEJkkkC[[›IDD °Þ´¨¨(\¾|YJgee±×5PýúõQ¿~}•eOS°eËôïß_JשSMš4yî6Klƒˆˆˆ–(•J•¹¡„ìõ·Ô—_~‰/¿üRJ?|øÏ-Ÿ’’‚ª,óññá¨1À*/GGG 0@JÏš5‹½^AÔ­[uëÖ-3¸þüóÏU–õíÛ …BJ›››cРA*ežžx•ˆˆˆÑS´´´JLñô…õššŠmÛ¶©,;räH™Û>|8çù"ÒPgÏžÅáÇߙ÷»|ùrÈd2v<,"ÍbnnޱcǪ,{üøq™ëlܸwïÞ•Ò;wF›6mTÊÔ¬Yóx|½›òòòðàÁƒrogÙ²eHMMUkÝ>üðCLœ8ñ鋞={–kýfÍš¡[·n¯´Ž‰‰ jÕªÅ,¢WS½zõ2óüñG•´¿¿‰ÉWµ´´ÊüUÙ¼ys^€O!88»víz¥u„*Os(O€eaaÁN(__ßr­íÚµß_/"“É^ø¸´~øá¿Þ•Q9uîÜ;w.qÐJOOî:ËåÏͯ\¹2fÏž]ö‡WG¶¶¶ì€ ,&&………¯´Îš5k^itÉÉÉ žžž¯ôhР;¨hÖ¬š5köJ뤧§#88¸Ì2Ï^ïZš•+W–ùCÔÊÊ ††† °ˆHõ U–&Mš`ĈÏÍONNÆÌ™3Ë܆®®î ‡éû÷ïÏ‚ÿ@ZZ¶oß^î턆†¢  à•Ö5jêÕ«ÇN ×ÆÔÔ´Ì)r€’×»–fìØ±eÞÙoooJ•*Ié¶mÛª<;—½²Ê•+cÕªUe–ÉÉÉÁ¥K—Ê,3qâD¤¤¤”«.|çNgþôÓO¸sçο^ßÌ̬Ä!ÿÆ!CÞê_ðDeY¹re™ù7oÞDbb¢”>räÈ GöŸþ¾200xá©LXDT‚¡¡!>þøã2˼(ÿelß¾C‡}§ÚvêÔ©pqqáNFôjܸñ+Ÿ=ý}5oÞ¼ÿôb|XDôÂ_„ê!"z—¾¯*d€•ŸŸ3gΔš—Í=ˆˆˆ`½*…BÐÐÐRó^õŽ""""X(º6ÅË˫Լ%K–°×‰ˆˆèµÒb1À""""b€EDDDÄ‹ˆˆˆˆ`1À""""b€EDDDD °ˆˆˆˆþþY„W®\···”Že¯¬òhÕª|}}¥´““{ˆˆˆ^+ž"$"""b€EDDDÄ‹ˆˆˆˆ1À""""b€EDDDÄ‹ˆˆˆˆÞî+993fÌ€——"""J-³dÉìØ±ƒ½HDDDEc'½rå еkWìØ±S¦L)QæÞ½{077/±<333gÎ,u»IIIìu"""ªøV\\FŒ!¥'OžüRëõèÑ %–ÂËË«Ôu8À^'""¢Š`U­ZUåq6ðûï¿«¤SRR°nÝ: 8ŽŽŽenO[[û¹ÄÑÕÕe¯Ñk¥±×`µiÓ111غu+ŒÔÔT¬^½ÑÑÑR™¥K—â—_~Azz:{’ˆˆˆ4†Æ^ƒenn^â:ª§ƒ+8{ö,{ˆˆˆ4§i """b€EDDD¤ÙtÞÅ7}ôèQ<~ü˜½ODDTAÍ;5kÖd€õ¦´iÓÑÑш-5ÿÑ£Gptt„¡¡a¹_ëÖ­[hÔ¨Q¹·“ššŠôôtT«VM-m ®z¥¥¥!%%5jÔ(÷¶ÔÙîéééHJJRË+88¶¶¶066Ö˜v€T­Z•*UÒ˜zedd !!µjÕÒ¨ý433qqq¨]»v¹· kkkµ´{VVbbbž{Çó« ƒ¥¥%LMM5j? ‡……ÌÌÌ4¦^ÙÙÙˆŠŠB:u4j?ÍÉÉADDœË½­ÇÃÜÜ\-íž››‹Ç£nݺåÞÖ“'O`bb ‹7Òîÿi¼ñÎXÛ¶m+3ܸq˜0a‚Z‚¹\^bú‰ãÂ… ¸zõ*¾ùæµ´ºêuåÊœ={ßÿ}¹·5qâDŒ=Z-çk×®ÁÏÏÓ§O/÷¶¾ûî;|õÕWjùrQW»À?üOOO4lØPcêuãÆ =zô¹“üþWõº}û6öîÝ‹yóæ•{[3fÌ@ïÞ½Õr@}ðà|||àíí]îmÍ™3]»vEÓ¦M5j??>:t耖-[jL½=z„Ÿþ‹-Ò¨ý4,, +W®Ä²eËʽ­  }ûöhÓ¦M¹· ooo¬^½ºÜÛZºt)š5k†÷ß_£öÓ×…×`©™›@Õ'Ÿ|Rêãwþ |ꪗƒƒÚµk§–muîÜY-ÃÆ`gg§–_HðñÇÃÊÊJãö‡: J•*U/|ðÁ·¿W­Z:tP˶>üðCT­ZU-Û²²²ÂǬ–m}ðÁ°³³Ó¸ý´]»v°··×¨zYZZ¢S§N÷}ªNmÛ¶}á„Ü/ËÔÔîîîjÙVëÖ­5r?}]dÉÉáâé•*UAffrrrqã¯hß¾Ê|)Û¶Ý {}}½R7hm]t]ˆ™™1ôõõUòªT©Š êB&SÂȨ2ôõMѽuŸ"$z¼ §ˆÔE§é奤$ÃÏï(7nˆÜÜœù·Q³¦3Î;{{¤¦¦”(‚>}ú iSÕK6xŠˆˆˆHÍxŠð-àêꪶ;‰Þ³gÏf#Ð;ÃÆÆ^^^lˆ DsF°>ví._þgÙÕ«@nnÑÿEù¼sdnnŽêÕ«so¥wŠ››Þ†††j™¢`•äçWdiý]%OÏ¢¿ÔÔ¢´Lèèðüô®]»0a„çæ2ÒÜ]©©©ðððÀ7ðçŸÂÃÃCú‹ç^MD¤aŽ?ŽAƒ=7òäÉðððÀÝ»w¥ežžž8yò$‚‚‚T¾çü(ž/eË–¢t±J•€¾}5Ý9¥)®\¹‚ˆˆ 2?üðC‰ü•+Wbá…ضmF :t(¶mÛ†yóæ¡y󿨶m–-[†êÕ«C©Tr¯&úÛƒ]f™û÷ïãÿûŸÊ²7n°ñHm"""ðûï¿cÅŠ÷© Å’’’JLJÇÆ#µB@OO¯ÔÙÅ===áììŒK—.IS@__J¥5jÔ@ëÖ­£G"44” Ê‹^Uaa!Z|jÀ‘#G™™ OOÏåSRR””„åË—#22Ož>ÒŸR©D»ví`bòÏ”1ÇŽSMîÕ«æÎ ///DGGãÒ¥KËåððð@hh(‚ƒƒñÙgŸA.—còäÉì8z)ׯ_W¹¤ãÒ¥K¸sçFŒQ¢¬±±1är9¼¼¼`dd„˜˜6 ,z‘jÕª!'';wîDçΑššŠ-Zàüùó€C‡aòäÉxôèÖ®] èÑ£¦M›†æÍ›#..+W®ÄêÕ«abb¢–g‘i‚'OžàÉ“'ðõõEõêÕqîÜ9<|øŸ}ö&OžŒððpèëëÃÅÅÖÖÖøé§Ÿ––___øúúJìÙ°a|}}±aÃDDDàĉÒ_i£Æ]»vU™¤1((îîî2d6oÞŒ©S§ÂÅÅÎÎθsçÑ A¸¸¸H§wˆžfff+++x{{£oß¾Š&a=ð÷M[§NÂW_}…øøxé>ýúõÃìÙ³agg…B 6`Ú´iÈÈÈàMOo ͦ!4HO? 5Í®®i0räH¤§§ÃÙÙ …·oß–¦ehÑ¢<ÒÄ­ăP½zu˜˜˜`ذaHMM…­­­Úf¡'ú¯éêêB[[¡¡¡HHH€¥¥%œ¥» 1uêT´lÙiii¸xñ"„Òé“ÒfºoÚ´i‰çõ%&&"++ )))°°°@ZZ²²²kkkÔªU M›6ŵkפEÍ›7‡®®.ÜÝÝ]]]!°hÑ"N/A%˜ššbôèш•žzíÚ5ØÚÚ\\\¤ïy­¿oôêÕ«êÖ­ ;;;T®\^^^HHH€••/a€UNëÖ¶¶ÀÞ½@×®@ÇŽ¶lll¤Œ¶¶6\\\T0ÕNÓÑya¢·]Íš5ѹsg¬^½wïÞE½zõ¤ë‹7 ,PôX£;vH¥]µjüýýaff%Ö-vḺºâêÕ«èܹ3nß¾ WWWœ8q Ö«Zµ*Zµj…Q£FaÞ¼y000€»»;Ž?.ŽdpEÏcii KKK)ýôƒÚ«V­Zê#˜žþž^b€õr23ìlÀÈxöIçJeшV)CúDT1¥¥¥!44Íš5C»víTPÅ¥K—Jé#Gލ¤{ôè!ýÿÕW_•ú={öDÏž=¥t»víTž±Y¼ž£££têðé×(í®0""Í °4(šH4&>¼d~BðÝwÏ=½3Š/XY;wîd£,ÿ÷EÏSµ*àãÃ#"""Ç»‰ˆˆˆ`1À""""b€EDDDD °ˆˆˆˆ4†›€ˆˆˆ¨l±±qˆ-ùÈ´´tXDDDD¯*"â ÌÌLÈJäYYYBOOÖ¾}ûP«V-4kÖŒ{ ½Pnn,-- £cTj¾LV2ðzç®Áš:u*>̽…ˆˆˆ^^äNDDDÄ‹ˆˆˆˆ,M±ÿ~¬X±â¹ùwïÞÅŸþÉ^$"""¢±wž={±±±prrºuëàååU¢ÌСC1tèP´lÙReyaa!|8âââššŠ*UªŽ;†ÈÈH©ÃOž<‰Þ½{#==ݺuCÆ ‘——‡³gÏ¢sçÎlt""¢R9r=zôÃÓÓ_ý5¾øâ ,Y²S§N… bbb T*±ÿ~¤¦¦âÉ“'€eË–ÁÞÞfff °Ô--- ƒ.5O]Ê™>}ºJzÔ¨Qhܸ1@WWÕ«W‡••´µµ¡¥¥…¼¼<Œ3GÅþýûѾ}{dggcÖ¬Y˜3g ™™™¨T©?aDDTá!““###P9êêêbëÖ­˜|ˆI“&¡ÿþÀ/¿ü‚/¾øÎÎΰ°°‚'mmmüòË/¸wïÌÍͶ¶¶X²dÉþ^+d€eff¦òxœ§½®Gåhkkãý÷ß—ÒuêÔAHHˆ”ö÷÷ÇÑ£G‡ÄÄDDDD`À€8þ<,--ñÝwßáÎ;4hV­Z…¶mÛò“HDDoµÓ§O£C‡RúðáÃX¶lvîÜ ™L¦rqâ„ÉdÉd˜5k¶nÝ 777E§3ˆS§NAOO'NDPP „ 6 Q£FlT""úO¤¥¥!..ÎÎΊF«æÍ›‡;v 66 ,@LL =zèÖ­†Š»wïÂÆÆ666*ÇA èìO:u*Dû0ÀúVÅžúÌËËCNN„B ::žžž¸víÖ¬Yƒ 6(šFÂÓÓ†††lT""z#&L˜€ÀÀ@øúúâÑ£G4h¢££qéÒ%ôéÓ;vìÀƒдiSé˜7þü2ƒ , V½zuøùù!//ÆÆÆÐÓÓÃ!C §§‡ÚµkC%K–`Ú´iøõ×_¥ëÎ"""`aaÁ‹å‰ˆè_{úX¢T*±hÑ"À¤I“°iÓ&ìÙ³999HNNF›6mн{wܺu VVV€¶mÛ¾Ó×3ÀÒp&&&011‘Ò#GŽÄÈ‘#Í0ˆ¼¼<¤§§bbbàé鉯cÕªU€ÀÀ@!¤»‰ˆˆÊR|,iÒ¤ V¬X7âûᅩ;LJB¡@FFlmmahhˆuëÖ±á`U ZZZX»v-¦M›&Ýò:aÂ\¼xaaaXµjBBBàîî!BBB¤Óˆ‰‰‰¨T©’4=½;’’’`ll !°eË`ذaÐÒÒÂøñãqñâE„‡‡cÅŠèÔ©êÕ«Ò)=///6$¬ŠËÄÄDº}–/_Ž5jÀÔÔpêÔ)陉Å3áÆÅÅaÀ€hݺ5æÌ™ÃF$"z‡$&&bÀ€hܸ1¼½½±wï^ 2àéé ,_¾5k֔曪]»6îß¿ÏÆc€õî²±±Q™ÖaèСpuuiôjôèÑ8yò$‚‚‚0gÎ!pðàAhkkC.—C&“¡°°ùùùÒȽòòò0wî\Œ97nüýýqëÖ-x{{£aÆÒSIŠG§lmm9E¬²…‡‡ãäÉ“RºøZ¥w…––Z·n­²lÉ’%077‡¥¥%À××}úôäææB__ .D@@6oތʕ+ó“BDôùã?ЩS'!0qâD¬]».\À¹sç°hÑ"I£S®®®ˆg£©ûø[Ñß 4߆ tt8hW­Z5üüóÏÒ¯ hkkC[[@ÑäpsçÎ…¯¯/¢¢¢Xºt)„ÒvŠO9ÑG©TbîܹÒ÷óþýû1pà@éF§g¿ãíììðóÏ?cñâÅl¼×¨ÂG666øôÓO¥4Oy•ôᇢ°°PJ9×®]CJJ ÌÌÌ ¹\Ž»wï¢Føì³ÏpãÆ Œ1;vì&™#"¢×ïòåËÒ™‰˜˜iBj}}}ôïßsæÌA\\nݺ™L†yóæaÞ¼yl¸7ŒÊ¡RmÚ´ DµjÕŸŸ…B!åÂÃÃ8tè´<33›7ofã©ÑŠ+¤ÿýüüàááM›6 QPP åÛÛÛc÷îÝØºu+¾úê+6ÞˆçËè…4h€€€ÂØØðÅ_àĉ¨V­€¢ éúöí‹¿þú ¶¶¶pwwÇÇ1vìXlÚ´ ŽŽŽ€;wîÀÅÅ…JDTŠË—/cá…ظq#´µµáåå…ÇC¡P _¿~˜4i"""péÒ% :ŽŽŽðóóC~~¾t#“‹‹ ¿g5G°è¥TªT æææÐÕÕ…®®.¦NгgÏÂÓÓ¸¸8äç磠 wîÜA¯^½pâÄ ìÝ»@Ñ”r¹ûöícƒýýãô?þœ?ðõõÅùóç‘––†ˆˆ //¶¶¶Øºu+–.]Š~ýúIÛ022‚¹¹9ôõõÙ „#X¤M›6ÅÅ‹‘››‹ªU«:uê---XYY!22cÇŽEHHNž<‰¾}û"=='NÄøñã¥_[ñññ011ás‰è­—››‹ôôtX[[(º}ýúõÉd9r$bbbðé§Ÿ"""ÿûßÿàææ†víÚáÎ;055EÍš5qôèQ¤§§Kws7mÚTz¶1À¢w„JzÙ²e*éuëÖá?þ@³fÍ T*1räHìÞ½ÁÁÁ8{ö,âããÑ¿¼÷Þ{X¸p¡´ž¯¯/ÜÝÝ¡§§'ýÊsvv† ˆ4ƽ{÷ T*¥ŒsæÌÁ•+W°k×.ØØØ`Û¶m5jàË/¿Äõë׆ŒŒ äççÃÌÌ »víRÙ¦•••ôl?z»ð!½1ï¿ÿ>æÎ‹=z@&“¡uëÖ°³³“¾<Æ“'ObçÎ!öíÛ‡¡C‡bìØ±€+W® _¿~èß¿¿TfÏž=Ø·oŸt‹rAA222¤×B %%…@o…ÔÔT•)PоOKIIQ™2%##CåB眜äääHé—ùLäçç«”Q*•HMM}gÛ’““¥ÿsssñÝwßáÉ“'R›._¾/^ÄÆÆ¢{÷îèÑ£rrrðóÏ?cùòå8sæ bbbMš4ììì “ÉЭ[7\¸pW¯^E:u¸ó3ÀzsÎ;§r—Ú³ÂÃÃ9uÿ[J&“a̘1ˆŠŠÂ‹/†—— P(ؼy3’’’ ðññAtt4‚‚‚‡B¿~ýàáá¼¼<À‚ п$%%öíÛ‡.]º 44Tz}???•úäååáÌ™3*Ëž-ólúôéÓÒkÀ_ýUb²¾S§N©ø®]»†„„),½7HHHÀµk×TŒ§NRÙf||<þúë/•ºŸ>}ú•ê~æÌ•º—VæÔ©S*öëׯ—¨{q?Eßxºî„•º_¿~]å þªuÙ¾y¶îO÷MHHˆJÝ‹û&11Q¥îÏöͳu¶oÊ»_………¡K—.Òu‹ÉÉÉ0`æÏŸ¯R÷O>ùû÷ïPôL9OOOiÔ·°°£GÆèÑ£¥éW.\OOOé3±ÿ~|òÉ'*}3þ| 0@ *öîÝ‹.]º ,,¬ÂïWááápwwÇîÝ»¥e7nÜÀG}„sçÎAqãÆaáÂ…Ò÷ÓòåË1aÂxxxHí‚ÐÐP( 6 'N„———ô#²Q£FˆŠŠBTT”t½”››š7oÎË"*¢ääpñô_~~–HNQQÄo¿úŠ´Ôh•üåËç‹qã¼ÄäÉãJý[¼ø'±~ýJ±{÷fqèЕ¿ þIIODrr¸ÈÍMe¹zõªX´h‘زe‹Ø³gO©eZµj%6mÚTb¹R©999¥þÕªUKL:UÐÛ!&&F?~\!„HOOÇgÏžBqñâEa`` DNNŽX¿~½000D`` 8zô¨°²²Ä„B¡K—.ÖÖÖÒ~UPP F-ìííÅ¥K—„B¡‹-ÖÖÖbß¾}B©TŠ;w kkk±lÙ2!„gΜöööbܸqB!=z$êÔ©#ÜÝÝ¥ºŸ:uJØÙÙ‰o¾ùF!ă„“““èÖ­›BˆŒŒ ѨQ#ѨQ#‘››+òóóŧŸ~*œœœDHHˆ(,,&LvvvâüùóB!òóóE—.]D:uDxx¸(,,cÇŽU©ûâÅ‹…µµµØ»w¯P*•b×®]ÂÚÚZ,]ºT!ÄÙ³g…½½½;v¬ôyÙ±c‡°¶¶+V¬Bqúôiagg'&Nœ(„âáÇÂÉÉI|úé§B!233…›››hÔ¨‘ÈÉÉ¢{÷îÂÉÉI !„HKK5nnn"??_äçç wwwQ§N& Ÿqㄸxñ¢P(bÉ’%*uß½{·°¶¶K–,B¡P(ÄÂ… …µµµØ¿¿JÝ—/_®R÷ &Hu¯S§ŽèÚµ«Bˆ¬¬,•º !Äýû÷…“““èÞ½»´Ÿ×=//Oäçç‹®]» '''* Åøñã…¸pá‚Zö+…B!Z´h!ˆ÷ß_!„§§§ lmm¥m6oÞ\:tBÑ·o_@888!„˜6mš ˆììl±aÃahh(ˆ›7oŠ_ýUúLìÛ·O!ÄÚµk¥ÏÍ;w„¯¯¯°´´Ä¡C‡*ü~UÜîíÚµB!4h ˆaÆ ¥R)fΜ) D§N„Blß¾]ˆš5kJûæñãÇÅñãÇEaa!¿¼ßÉÉIbçÎ-âîÝ«âúõs%þ~ùeµ8sæ„èß¿ÏsãžÉ“ljóçOŠgã)¸+++ ¿ýö›”nÛ¶-`jjŠúõë—ø%RlÊ”)*¿|ž.>|x©ëðqo—âø‹™˜˜ sçÎ*ûÊÓ§BFŒ›7o"%%æææhԨƌƒ{÷îÁÁÁX³f âã㥭ãÇcïÞ½HHH@||>aaaˆ‰‰Á‚ »wïB©TbÚ´iˆŠŠÂ7?þø#‚‚‚™™)"LŸ>ÑÑÑR™yóæ!88¹¹¹€¥K—âÖ­[Òé˜;wâôéÓÈÎÎFFFNœ8;w">>±±±€­[·âÌ™3ÈÍÍEff&Ž?ŽÝ»w#!!qqq¸yó&Ö®]ûܺ !ðÃ?¨Ô=**J¥ŒB¡À´iÓJ­{q[/]ºÒHãîÝ»qòäI©î¥½¿;vàÌ™3ÈÉÉAFFüýý±{÷néÔ›7oªôMll,¼½½¥z÷Mxx8¢££±páB•¾)n÷âQ¾â¾ÉÊÊPtm`qÝ‹GxæÎ‹àà`iôåy}ótÝwíÚ%Õ]û•––V­Z…¥K—¢~ýúooo( ˜››ttt°råJ,_¾ 6”F§d2™tôôéÓ¥ mmm >7oÞDrr2ÌÍÍáææ†±cÇâîÝ»Òô)^^^ Djj*LMMÑ£Gܼy÷ï߇½½}…߯֬YƒÅ‹£nݺüôÓOؽ{7š5k™L†Y³faÖ¬YÒwÍ€0`À€Nii©|7É’“ÃÅÓ *Uª‚ÌÌäääâÆ_о} (”ÿ çnÛ¶aaO ¯¯Wê­­«¢R¥J033.qËh•*UÑ A]ÈdJU†¾¾ €¢ *=*•kß¾=nß¾ÈÈH¸¹¹áôéÓ˜2eJ‰×:zô(¤§€¿ '''xxxàÇdï¿£®^½Šàà`¸¹¹I©“'O">>ï¿ÿ>ðçŸ"$$ï½÷êׯ{÷îáæÍ›prrB‹-‰óçÏÃÚÚü1ÒÒÒpìØ1¢gÏž€'OžàâÅ‹°±±A‡’’???A.—C¡PH§‚<<< ­­ ___dgg£K—.°°°ÀéÓ§‹víÚIsŽ>|999èÚµ+ÌÌÌJÔ½øý5nÜ 4Àýû÷qãÆ Ô®]-[¶,Qw¸{÷.¥÷ . jÕªèØ±#RSSñûï¿—Z÷¾}ûBGGGŽAVV–T÷ÂÂBiJŽÏ?ÿZZZÒûsww‡¹¹9N:…¸¸8´oßŽŽŽ/¬;€öÍ‹ê®T*±gÏ•º÷±±1zôè¡R÷gûæEu/Ï~õ6|n*ê~E璉”døùEãÆ ‘››S"?0ð6jÖtƦM?ÃÞÞî¹ÛùôÓnpqqÒ¼ëyæâ«®®.Z´h777øûû£m۶үδ´4ÌŸ?ººº °ˆˆˆH#,¦¡E‹ÈÊÊBbb"úô郴´4x{{£fÍšR XXX@¡P¼t€EDDDôºiô|ôÑGèÓ§RRR¹\ŽŽ;V¸NHJJ“'Ož›†àà`(:Œììldff"88Xú+.CDDš#-- ¡¡¡Ï͈ˆ@pp°Ê4B!!!HOOGnn®Ê÷|YS ‘æÐ˜¬¤¤$|ÿý÷Òó§OŸŽ­[·ÂÇÇëׯǔ)Sàëë ¹\^¡: ::7nDnn.ÜÝÝKܾêïï“'OBúõëcÈ!ؽ{7nÞ¼ +++¸»»cÛ¶m€3gÎàÀ*Ä&"¢ÿVFFV¬XŒŒ |øá‡èÚµ«Jþ¥K—ð믿¢°°¶¶¶øæ›oð믿âܹs033CÛ¶m1sæLiº‹¯¿þZ-SÚÐ륱×`>|­ZµRÛäšš*<<†††øòË/qìØ±ù5kÖÄüùó1gΜþøcvý+Õ«WGff&/^ŒÙ³g—ÈoÚ´)®_¿X²d ._¾ŒöíÛ³á4œFßE¸nÝ:,^¼¸ÄpjE–žžŽž={" @Z¶hÑ" <U«V-QþòåË8{ö,Ö®]‹¤¤$$$$p¯¦ %##7n„¹¹9îÝ»‡S§Ná믿†¿¿?ÒÓÓ±}ûvÈd2˜››ÃÔÔ ,À¦M› §§sss,X°@ÑÝ¸æææX¼x1.]º„ž={JW¯^…¯¯/ÌÍÍadd„¼¼<¬^½æææ†ŸŸÌÌÌ```SSSÂÛÛæææ077‡±±1;Š^‰‡‡üüü¤ô‚ УGÔ«W¯Ôd£½e4vkݺu¨U«Z´h    {Ëv›6m„+V`Íš5ÈÈÈ€R©„Eó¿®\¹AAAøöÛoáèèˆU«VaË–-Ëå˜6mš5k†åË—cùòåøê«¯xýU8ùùùHNN†\.Ç‘#GðøñcÔ«WS§N…L&ƒ'Ož„„ÐÑÑA¥J•еkW˜™™ÁÇÇÍ›7Ç|€æÍ›ÃÇÇmÛ¶UyŒH`` €¢ÉM###QXXˆØØXÈårøûû#$$_ý5.]º„>ú®®®¨U«ú÷ïøî»ïØQô\ŽŽŽøä“OðÕW_aÏž=ŠnV*þžßµknݺ…Û·oÃÈÈ»víÂþýûÑ»wo >íÛ·ÇöíÛ!—ËÑ£GŽ^1À*ŸE‹á£>š5kкukL™2¥ÂvÂàÁƒ1xð`EÏÑ;r䈔7vìØÙ´°°P™ázüøñ?~<÷fª*Uª''' 2Ožì™ˆˆˆˆ,""""XDDDDÄ‹ˆˆˆˆ,""""b€Uš>úK–,aÏÑkóÚ&N{ò IDATµµu(ñ AMx¦`DD’““ÙóDDDôÚ¼¶¬ªUm`` #ýéêÊp÷î=¶8Ux¯mK%òóó¤taa!RSSÙâDDDTáiô5XÈËË{n¾B¡€B¡`/¬—ƒ3f`„ ¸ÿ~©e¦L™ö"iM­Ø7P³fM¸¹¹Á××õë×/QFQêºééé9rd©yqqqìuz«…„„`úôée–Y¿~=LMMÙXDD °^]ûöí‘Pb¹‰‰ 6mÚTê:®®®ìuÒXéééøóÏ?¥tNNúõë§RF©T"77·ÌíøúúB&“IioooÔ«WOJ7lØvvvlp"¢w=ÀJHHÀìÙ³1aÂÔ®]»Ì²2™ FFFÏÍ#Òׯ_Ç–-[Töó}ûö•{»999*é±cǪ¤;vì¨pÀ·ß~‹5j°Sˆˆ*r€Õ¡C¬Zµ »wïÆœ9s––†Ë—/cÈ!R™µk×B¡P OŸ><Bo…˜˜ÄÄÄà÷ßdž ““ƒ¤¤¤7^S§NáÔ©S*Ëöïß===̘1M›6E5P¹revQE ° 0iÒ$)mjjŠëׯ«”9~ü8{Þ ~~~¸rå Ο?³gÏjdãããÇÈår4jÔŸ|ò Z·nÍN$"ªÑÛ,..999X¶lÎ;‡¨¨($&&¾UïÁ××¾¾¾Ø´iªT©‚¾}ûÂÓÓ&&&°´´d'1À"zýð¿ÿý°aÆçN/ò¶‰ŽŽFtt4ñÃ? ]»vèÝ»7œÑ¥Kv<,"õÉÍÍEAA~ùå=zááá ­ðïûâÅ‹¸xñ"¬­­áââ777Ìž=ZZZñ¼ÑÿgïÎãcºþÇ¿²Ë&$"ÖØ©­Q{i”"h$±·v‚R[UUiKc‹Zb§ Ji¬±%!ÄDYd¬“í÷G~î·Sñiû1­ïçãáaν7'gÎ9™yÏ™sÏB °„x:uŠ'Ož°aÃÞÚzxúô)'OžääÉ“,[¶Œš5kòí·ßbjjJß¾}¥£!$ÀBü¹9sæp÷î]Ο?Oll¬TÈ<|øÁƒcbbB=˜;w®¬;'„«´ŠW»û0++KZ]ü%þþþ¨T*ÆÏ“'OÈÏÏé1ooo|}}éÔ©S¦LÁÚÚšV­ZIå!$À*M/öQQQJ:??_Z]¼ 33“©S§ªóòòúÓÓÅËåççãïï¿¿?Õ«W§GÔ¨QƒY³fIå!$ÀzÓÕªU‹Ñ£G+éüQZ]B^^±±±Œ;–ÂÂBe(¡yQQQ¬_¿<==±±±aýúõèééѲeK© !„XB¼irssùæ›oÔŽyzz’™™)•ó/ËËË#..ޏ¸8Ú¶m‹‘‘Ÿþ9 ,@WWW*I!–ÚP=~ü˜§OŸ2jÔ( ¹sçŽTŒ–¶Õ÷ßÀÁƒâ¯f-,,”kªU«†±±±T–B,!þMwîÜá—_~QÒQQQ¬X±B*æ ðÂdøñãÇS«V-€æÉ !„XBcÒÓÓÿÖdýsçÎáááñ_¯éСƒòU¶Yºt)gÏž}éù§OŸr÷î]é¥ÔêÕ«•ÇÏG¹¶oߎ¹¹¹r¼lÙ²èëËË™B,ñ7ìÚµ‹ÜÜ\%½`Á¯ÀÂ… ¥²…V{¾°kÍš5ÕŽùå—Ô©SGIÛÛÛS·n]©0!„Xo«¡C‡’––ö_¯9räyyyRYB¼Ä?4oÞœêÕ«+éàææ&%„«4ÊËËãèÑ£ôíÛ—ÂÂB©!þ!!!„„„(éƒ2hР·æùÛÛÛ3mÚ´—¿ðëëÓ£Gé(BH€õfŠŒŒdÁ‚J:77—;wJÅ!þQÿuŸL¬v¬V­ZÌ™3G*O °^.//ÀÀÀÏåääŹsç4þ{+V¬Hýúõ aþüùäçç¿ðõß| ½NñÚ…‡‡«¥Í›7Ç××Wz¸¢T¹|ù2ÙÙÙJzõêÕ<|øP*Fh¯¾úŠùóçK€¥i&&&/°nÝ:’’’þvžeË–¥jÕª4kÖŒo¾ù###lmm¥ !ÞãÇWK;;;“““ÃÂ… "66–ÔÔT©(!9XªyóætëÖ ;;;("„ÿßó;5·nÝ €··7W®\`ýúõ¤¤¤H% °D1sssLLLpvvÆÅÅ…J•*½°æŽBˆõïߟþýûÿ7º5}útÂÃÃIMMU[ÏO °ÞÔ«Wggg:wî,"„¯ Y³fÊ. +W®äæÍ›œ:uŠ{÷îI °J3]]]ŒŒŒðööÆÎÎŽªU«JBˆÀĉ åÉ“'lÚ´ ??? eM@!ViÒ¹sgœ5j”ô!„ø—ØÙÙagg§,têííÍž={xðàW¯^• `½Éz÷îͦM›¨P¡‚ô!„xžÏÛº{÷.AAAªmð-Ä›J÷m|ÒMš4‘àJ!´Hƒ éÓ§«óññQ[;qûöíJ¥‰7;ÀJKKcÅŠÄÇÇóÕW_Q©R¥®Y·nåÊ•càÀÒ’B!4ª_¿~ji²²²”ôÏ?ÿÌÎ;•tJJ <ŠÚ`?žJ•*ѽ{w¶lÙ¬Y³^¸æÜ¹s888¼p<33“E‹•˜orr²´ºBˆ¿ÍÒÒKKK%=eʦL™¢¤ÃÂÂðññ‘ŠÒööö¥7ÀJNNáüùµc66•K¼6>>žÑ£G+é?Ó¾Ì'Ÿ|Râ] FFFôï߿ğٺu«ô>^co¼š*Wnn.±±±Ô¬Yó•󊉉ÁÜÜssóWÎK¥RñäÉjÕªõÊyÅÆÆbjjJÙ²eÿ•zÏÎÎ~­ñÆ[`y{{ÿ×ó“&MbÊ”)é䎎Ž/,?ñ¿ ((ˆ©S§j¤4U®K—.qúôifΜùÊy}þùçL˜0Úµk¿r^—/_æèÑ£|õÕW¯œ×Œ31b„F^@5Uï_~ù%®®®4nÜXkÊuõêUüüüøú믵ªŸÞ¸qƒ½{÷¾pÓÌÿbîܹôïßÿ¥ËÀüwîÜaëÖ­üðïœ×üùóéÙ³'-Z´Ðª~úý÷ßÓ¹sgÚ´i£5å gãÆüøãZÕO###ñôôdÙ²e¯œ×¢E‹°··§]»v ÞøáV­ZõÊy-]º”–-[Ò¡C­ê§ÿ™ä.„B!Ö?«sçÎXXXhì“6ÒT¹*W®¬‘O¦«÷J•*ñþûïk$¯:¨m¡-ýÁÞÞ+++­*WÅŠ5ò‰YÓ¬­­ùàƒ4’Wûöí±¶¶ÖH^–––ù$Ю];lll´®Ÿ¶iÓFcS4U.KKK:uê¤u¯§šÔºukL‘077§K—.É«eË–›B ­ï¯¿§“œü°è÷Ì̬ÉÈH ;;‡«!w°·oMA¡J9¿mÛnlmkÿé$w Óæ1Y[ÛШQtt 11±ÄÈÈñç4ý¡o‚7á+!4E“_Š¿.%%™£GýhÖ¬199/ÎÙ ½A­Zõùé§T­úòùƽzý‡&Mꪓ,!„B Ó—*Ð~5ÒÈzB¼IfÏž-• Þ666|úé§R`iÞýû÷¹yó&Õ«W§yóæøùùQTTDùòåéС™™™øûûc``@=ÞªF²²²ÒØ|!Þ­[·–Jo š4i"QŠhÍW„‡âÂ… ddd°fÍINNæÓO?å—_~¡  €äädæÏŸ_êÁÛÛû¿~ZŸ8q"#FŒ >>(Þ“qĈ\¿~Ë—/3bÄåŸ, *„ÚçĉŒ;ö¥ççÎˈ#¸sçŽrläÈ‘œ9s†¨½Î‡‡‡K…J€õ÷|ôÑGtèÐ!C†0bĆÎìÙ³III¡lÙ² >œJ•*•ª&""‚~ýú1oÞ¼Î{zz2}út<<<˜2e ãÆÃÃÃ… òî»ïâááÁœ9s([¶,yyyÒ«Å[/<<œüüü?½îÂ… ÄÄÄ(é°°0åqBBÅ ë™™ù§ùþ>!ž|Hll,ƒ ÂÑÑQÞÅŸº}û¶ØCñAAAŒ7î…kË•+ÇСC™:u*¦¦¦ò:/Ö«éС·nÝbذalܸ±Ô6@µjÕÈÉÉÁÛÛRRRhܸ1§Nà—_~aÊ”)$$$°uëV ø«Ôï¿ÿžfÍšñøñcV¬XÁ¾}û055ÕÈ^dB¼N¡¡¡äææâëëKQQÁÁÁ\¸p!C†0dÈîß¿¹¹9mÚ´ÁÌÌŒeË–‘••…¯¯/ûöícòäÉ@ñ•¯¯/ .äÆìرƒ;v°{÷n=zDdd$gΜÁÚÚ}}}ø·öœœ}šš5kräÈÈ7¨T©?ÿü3îîîÄÄÄ••űcÇèС?ýô“2ZÖ«W/~üñG¦OŸNzz:ï½÷ž4¤Pccc£¶Ñó@ Š¿É(i ™ß/Uòû÷ !ÖßVPP@AAzzz¬Y³Fí\QQùùùÊ=BˆÒ+##ƒ¸¸8ºuëFëÖ­_™­[·.ëÖ­SÒ;vìPK6Lyü²[ãGŒ¡–îÕ«½zõR{üý›`5Ô~G™2eÔÒ‹/–ÆBhW€U¯^=Ö¯_ÏíÛ·™8qâ çããã™8q¢,¸)Ä[`ðàÁ <ø/_ïãã#•&„«$={ö¤gÏž/=ÿ|¨^!„BÛÉfÏB!„` !„BH€%„B!–B!„K!„B,!„B °„B!„X%9tèׯ_—–B!„Xš2eÊöîÝ+-/„B °„B!$ÀB!„K!„B”úËÏÏ 6¼ôü;w¸r労b)ræÌžÃÈÈ[[[nÞ¼‰………<;::rìØ1rrrÇÀÀ€¬¬,6lØÀìÙ³100FB¡V^^>11q%ž{þ5Í«ªZµ*¡¡¡Ó¤I}šôôt „‘‘‘´¦–¹pá'NdÒ¤IÄÄÄ0kÖ,¶lÙBxx8kÖ¬aåÊ•¼óÎ;têÔ©Ä<*V¬HÅŠÕ‚çß_[µjUµ¯GŽÉäÉ“IIIaýúõܾ}›àà`š4iB¿~ý€ây\ÒHB!´'Àº}û™™™/ Œ4ÁÎÎŽÂÂBRSSqpp ##ooo6l¨\óÁPTT„ŽŽŽ´¤xöìÛ¶mcüøñãææÆÃ‡9qâ½{÷VF¨jÕªEóæÍðòòÒx9–/_®<Žˆˆ o߾ܼyvïÞ­«V­ÂÉÉIN!„vX)))”+gQâ9SSSî½÷ÞS¹x>úðœ¼9jàèèÈÍ›7Ù±c+V¤qãÆ4nܘ>}ú¼¶¶ª[·.×®]SFV¯\¹Â'Ÿ|Bll,ÄÒÒ’N:‘——GXXvvvÒ˜B!^O€%Àš5k7nñññ¸ººrãÆ fΜIŸ>}´¦œzzzÊã6mÚ°cÇ寉7n°k×.rss¹té{÷î¥Y³fÒ¸B!$Àÿ¼çK_Ô­[—””ÜÝÝùùçŸÙ²e Í›7ÇÏÏO¹öù¤smeoo¯Ìã+((`Ó¦M|ñŤ§§sìØ1%Àº{÷. 4ÆB!–øg¬Y³† 6ЫW/"""”ùTýúõcæÌ™oìóÒÓÓcÔ¨Q˜ššEQQ‘2ßÇLJŸ~ú‰:HB!–xuÇŽãòåË 0???¾þúk²²²9r$C† aþüùjwø½ÉÜÜÜ”ÇÛ¶mÃÝÝ´´4>LÛ¶m144$&&†*UªHçB!–øknß¾®®. 4à·ß~ã“O>!==ˆˆ¬­­?~<jwr–FC† ÁØØXYÞaéÒ¥èééáååÅ’%KèÞ½»t!„ow€uéÒ%~øá%÷Ö5rnn.€²VX~~>ëÖ­ãý÷ß§E‹ÄÇÇãè舎Ž 4àÁƒR¡B¦OŸ^ꪒ 0€ūϻ¸¸••ÅŽ;pppÀÐÐŒŒ LMMe™!„o_€Õ¶m[|}}•tݺuK}£^»vjÕªQ¡B ˜4iEEE¬^½šàà`~ýõWæÏŸ••‹/æÚµk„‡‡*‹¶þÁó5¼žÏ;óôôÄÒÒ’M›61yòd%B!ÞšëuûãB¨7ýÇcEEE|÷ÝwÌž=[9¶lÙ2e¢vdd$...4lؾùæÖ¯_@LL |ðåË—GGG===*T¨ÀìÙ³éÚµ+€l%óü1ü1P<*Ú®];ŠŠŠÐ××§ÿþüüóÏ4kÖŒúõëK… !Ä¿ô¾úWßKÿmºÒTMtt4ÑÑÑJ:55•»wï*éüü|¦L™ÂôéÓ),,`åÊ• <˜ôôt~ýõWºtéBll,W¯^¥mÛ¶Ü»w€{÷îѶm[®^½ªäBÛ¶m‰ˆˆàÙ³g 2„9sæðÑGáëë«ìí÷|¤nòäÉܹs‡£GâääD¯^½pttÄÑÑooof̘ÁäÉ“),,$>>žÞ½{S©R%z÷îMïÞ½ÑÕ•.ñgÚ¶mË… pttÄÒÒ'''ÌÍÍqvv~aËŸ+W®ŸŸ/•&„Q`` Z:$$•J ¼zzz*çcbbèܹ3¿ýö€²…ÞêÕ«_ëó¬—ðóóÃÎÎŽ5j R©4hÇÇÐÐÉ“'sýúu<È;wðòòbçÎÄÇÇ£««ËÞ½{ÉÎÎ&33“råÊñ믿Ç Aƒ°µµåÂ… „‡‡ãââBÓ¦M¹yó&—/_ÆÙÙ™öíÛpîÜ9"""puu¥uëÖdgg R©HMMU¶,ÊÏÏ'55••+WÒ·o_LLLøä“O8pà€4è?dý¾^===™4i©©© >\9ÀðáÃùòË/¥Ò„¢žžž¸»»pôèQÆŒüyó>|8!!!8;;3hÐ ¾þúk¾øâ vìØ2ñèÑ#NŸ>Í;wøè£HIIáàÁƒœ9sF¹AK¬×$11‘Q£F1cÆ Ú´iþ}û6l•*UÂËË‹½{÷ræÌ xÝ'===Ž?Nvv6C† ¡ÿþ,^¼˜Çàáá¾¾>ÉÉɤ¤¤0oÞû÷ïWÖÒÚ»w/íÚµÃÕÕU*MQê………ѨQ#%}á–.]ʺuëÐÕÕeìØ±8p€ÈÈH:uêÄ—_~ÉãÇùæ›o8xð ±±±DDD°råJ®^½Êøñã £|ùò,]ºTÉ3??Ÿðo7¨ IDAT¦M›²`Á>|Hrr2ÖÖÖ¯õ¹ë$'?,úý33k22ÈÎÎájÈìí[SP¨RÎoÛ¶›ÈÈÇ–˜aÅŠ6˜™™aaaúÂdikk5j€ŽN!&&–™ÿëO¸nݺ8;;S·n]†NAA}ûöåСCØÚÚ2`ÀòóóY±båÊ•cΜ98::*å'Mš„¾¾>6lP†*_w# íΡC‡”ôÂ… III¡ZµjDEEÅ7$²=â—››‹òÒÇLJ3f°~ýzš5kÆ÷ßÏÞ½{‰ŽŽ¦wïÞ4iÒ„'NHÏž=éׯMš4áìÙ³4mÚ”nݺÁÁƒ©V­ÎÎÎ/sJJ2GúѬYcrr²_8zƒZµêóÓO©Zõåë öêõš4©ûöŽ`ÅÅÅ¡R©X»v­òåÊ•yðà7¦iÓ¦Œ3†Ê•+3aÂôõõ©Y³&S§NUËkÔ¨Qò×$þ«úõë«õ›-Z(ýÊÑÑ‘G)óñΞ=Kýúõ9zô(/^döìÙ”)S†ÂÂBbbb¨V­š’Ovv6Ø !^«ß¿%%%ñÙgŸqâÄ 233©P¡Ó¦MãáÇLœ8‘÷ߟY³fÅ­[·0`]ºtaÒ¤I¤§§ceeEùòåhÕª•Ú ÈßßoM€õøñcÜÜÜ”‘€æÍ›³nݺ¯–sÿ®N:qóæM%½qãF%Pß²e æææ,^¼˜´´4ŠŠŠøöÛoñòòÂÓÓ“Ý»wóÎ;ïðõ×_síÚ5vî܉µµ5999øûûÓ«W/%ooooåîÆ’Ò‡¦k×®”)Sæ¥×:tˆnݺɲBˆÍŸ?ŸË—/ãààÀÅ‹9|ø0P<ªOŸ>,_¾œ   >üðCå ½{÷¾OiÙä­ °Ê—/OãÆ¹xñ"ƒfìØ±¥¶QÅ›áÓO?ÅÎ΀zõêqïÞ=vïÞ±±1Õ«WÇÑÑ‘óçÏ“˜˜È!C”mzŽ;FNN&L`ÅŠ̘1ƒ#GްqãFenßš5kxúô©2·oΜ9\»v &péÒ%FÅG}ÄâÅ‹•àjîܹ\¿~qãÆqáÂFM¯^½XµjFFF¬Y³†–-[*KTx{{STTÄ€ÐÑÑ!//ÜÜ\ÌÌ̤q…(ežÿÍØÛÛ³~ýz–.]ŠJ¥bذatíÚ•¯¾úJ °´´ OŸ>om½5–¹¹9ëÖ­Ãßߟ*UªÐºukù‹¯•®®®Z?lݺ57nÜPÒ£FbÙ²eܽ{—Q£FѼysf̘AZZcÇŽeÞ¼yüöÛo$&&²víZ~ýõWΜ9CJJ Û¶mãúõ넆†’’’‚‰‰‰<|ø„„üýý™7oP¼dHJJ ÞÞÞ<}ú”˜˜ÈñãÇY¶l¹¹¹,X°€råÊñÃ?——Çĉ‹_DôõqrrÂÃà .°eË*T¨/=¢««K:u¤Á…xƒùúú*w¦úé§èëë+wLwìØQmƒ(ÅVZZC‡-ñÜÛ¸UŽxsM™2å…c‹-R¯[·ŽáÇ“œœLóæÍ±±±áæÍ›DEEÑ Aj׮̓¸{÷.ÕªU£iÓ¦ÄÇÇ‚¥¥%mÚ´àþýû„‡‡S½zuš4iB\\W¯^ÅÊÊ sssNŸ>¡¡!ÆÆÆØÚÚ¢R©04,¾Ñ%&&GGGåÎÚ0pà@\\\”Ñ­ .`llLXXW¯^ÅÕÕUY0??}}¹¡YmRTTÄŽ;hÙ²%uêÔaÆ ÊßüÊ•+166–Jz, µíq~OæV‰Òæyô\“&MhÒ¤‰’®]»6µk×VÒ666ʪôÏÕ©SGm”©R¥Jj×4lرcǪýÌó=.&L˜ÀرcIJJbñâÅܾ}›aÆ À´iÓèÔ©£G&%%…ŒŒ FÍ‘#GX¼x1;wî¤jÕªÒ˜B¼&ÑÑÑbkk ÀÚµk?~<ÆÆÆôêÕ‹E‹ñî»ïJE½í–âß·víZåqÍš5ùðÕ ­;vTÖ’xòä ƒ ÂßߟøøxqrrŠ·~*iäNñÏÈÏÏÇÕÕ•ÂÂBåÎùçƒVVVìÛ·O*I,!„Ö¼¸èëãææ¦¤ÝÜÜptt¤°°ccc²³³™3g7oÞdóæÍ,]º”ëׯ“MQQŸþ9ׯ_—OÎBhØÃ‡±´´¤lÙ²8;;ï©jff¦|`’íÓ$ÀB¼LMM•Çæææ¬X±BíßÕÕ•‹/âãããG€â%%¾ýö[Yý^ ‰ÅÕÕ[[[lllhÕª;vŠG¬žÏµ` !Jš5krèÐ!222€âÉóýû÷'&&†}ûöѨQ#eÅûÈÈHjÕª%•&Ä_ôøñcªV­ŠžžýúõãâŋܿŸ   *V¬(“Ö%ÀB”fVVVXYYP£F öíÛÇo¿ýÏ 9xð {öìaÓ¦M´k×N*Mˆ?qçÎ\\\øè£(S¦ ݺu£[·n˜™™Q£F © °„o›öíÛÓ¾}{%½nÝ:¦M›Fff&GŽ¡zõê|÷Ýw,\¸PYÜPˆ·]bb"*T °°ž={òàÁtuuÙ¸q#7–$ÀBˆÿ3fÌÌÍ͹téiiiÌš5‹;wPPPÀ† ¤’Ä[/$$„aÆ)[qõèÑ(^¦èù‚ÅB,!„Pãææ¦Ü˜™™‰¹¹9Û·oçÌ™3œ;wŽ÷Þ{+V0zôhåëF!J»ÜÜ\ŒŒŒˆŠŠÂÙÙ™ˆˆŽ9ÂÔ©S™0a‚TXšÍÙ³g•ôó ´Bˆ7Ÿ©©)k×®Un)_¼x1ööö?~œÓ§OpëÖ-*Uª$—(•?~<Ÿþ9™™™´nÝšÖ­[Ó©S'ºté"$Ö?GOOOZZˆ·À_|A||………>|Xî¦ZoݺuŒ3†˜˜Ö­[€½½=[¶l‘Ê‘K!^KKKe£êÌÌL¦L™ÂñãÇâ¹+ÏXÜ»w/íÛ·§oß¾Riâµ)((àñãÇÔªU‹´´4¦L™Âîݻٲe ï¾û.Ož<ÀÄÄD*K,!„ÐÏ'ÅÛÚÚ(7À,Y²„ÔÔTöíÛ§Xׯ_GGG‡¦M›Jʼn͆ X»v-}úô!""‚={öàèèȬY³¤‚$ÀBí¤§§Çœ9sÔŽµhÑ‚ &```€££#±±±ÄÆÆ¢££Cxx8FFFäææ’••Eùòå¥Åÿìùìfffœùä:Ä—_~Iff&Æ cöìÙÌž=€J•*IåI€%„o–?þ˜û÷ï+é•+Wâî§'úúúDEEqçζmÛF… P©TœúH*Pü%yyyŒ;]]]6mÚÄÙ³gqrr"--°°0*T¨ ,ÚµkW=•K!J—qãÆñî»ï*éõë׳wï^ 7n6l`Ö¬Y8p€½{÷Ò±cG xŽ—©©©òsEEEdggË|™R*''妊¼¼<ŠŠŠ044 44”‹/*Ë…|õÕWìØ±€ääd>üðC¬¬¬ÐÑÑaÆŒ4nÜX*µÑÕæÂ]¼x‘#G޼ô|TT÷îÝ“VBh”žž;vTþíÚµ‹‰'2dÈfΜɤI“ðõõ%>>ooo¶mÛÆ¶mÛèС7nÜPòÙ¿?}ô?VŽ:uJíwý1}þüyT*•’¾q㉉‰jל;w޼¼<%JRR’’ŽŒŒ$22RI'%%ª6’rîÜ9µ<ÕÊ®R©8þü-kIeÏÍÍý¯×ü±ìׯ_W+ûÇÕÊžœœ¬VöçÏïáÇje¿~ýºZÙÿøüþ¬ì.\øKeÞ6))) 4ˆ%K–œӧL™Â¤I“ÈÏÏ'((ˆ.]º0vìX̤I“HOOgÈ! 2„ýû÷ãîîÎýû÷III‘àJ¬OHHDGG³ÿþ¯8p Ú*íBñOY¾|9^^^4oÞ///öíÛ‡„‡‡3tèPBBBpqq¡_¿~ôë×1cÆ€³³3EEE¬Y³777|}}âe#ÜÜÜ”•èqsscîܹ<~üåk£ç<]]]™7ož¸¸¸(wJªT*ÈÀ•``ìØ±¸¸¸(AɼyópuuåâÅ‹J¾£FÂÅÅE ç΋››¬]»7778€¯¯/nnn¬Y³€   µ²?0ÝÜÜ”¥.^¼ˆ››_ý5=ÂÅÅ…1cÆ(ewvvÆÙÙY vž—ýyЕ““£\ó¿¿Röüü|~ùåþóŸÿ ««ûBÙÿøü^Vv[[[Þ{ï½ËþǶùcÙg̘Áwß}‡¥¥%›7o&//°gÏLLL(,,,ÉÐÕEGGGþP´PJJ2GúѬYcrr²_8zƒZµêóÓO©ZµÊKóéÕë?4iRWí˜VÌÁ*(( ..NIçääüµá7Ý’à,,,”OˆT·n]éQBÍ~RÕÑa„ /lª»hÑ"µ‘€€îÞ½KëÖ­y÷Ýw %88˜ `ooÏÇñ÷÷§R¥JôêÕ‹””|||066V6¸ŽŒŒäĉT©R…=zœœÌþýû155ÅÅÅ…üü|¶nÝ À°aÃÐ××g÷îÝdffâää„¥¥%GŽ!&&†.]ºP«V-vîÜIvv6ýúõ£|ùò>|˜¸¸8ºvíJÍš5•²·jÕ ;;;®_¿NPPRöGñÛo¿)e¸ví—/_æwÞáƒ>PÊ^¹rezöì©”ÝÄÄWWW ”Å3ÿXö¾}ûbeeE^^^^^ >===víÚEVV–òü~ùåbccÿ´ìõë×§C‡JÙmlløÏþóÿßXKn›çe8tèÒ¾zzzjéçÇ„Œ`½Ö¬’\¼x‘‹/R¥JT*ööö´iÓ???Ú¶m À?þHJJ óçÏG_ÿ¯ÅŠuëÖÅÙÙYF°„Bˆ·\©Á*Éûï¿Ozz:OŸ>eÈ!¤¤¤0uêTªU«¦\STT„……yyy9ÀB!„ø§iuTò|Î@ùòå™1c†ÚùéÓ§K !„BëèJ!„BhÖ[ù½ZVVÖ ëÊ!„¢ô(W®Ük>ôVXË—/gùòåÒû„BˆR*88˜–-[J€õoÙ°a™™™/=¿qãFúôéCÅŠ_ùw-\¸/¿üò•ó¹uë÷îÝÃÑÑQ#u ©rݽ{—7n(kþ¼ŠM›6ѳgOlhÁ•+Wpvv~å¼¶nÝʇ~HÕªUµ¦Þ¶oßNÇŽ±µµÕšr=xð€ÀÀ@\\\´ªŸ>zôˆ€€ ôÊyíܹ“öíÛS³fÍWÎ+::š'N¼t;¿cÏž=´jÕŠ:uêhU?õöö¦iÓ¦4hÐ@kÊñcÇ>|¸VõÓøøx:ÄgŸ}öÊyùøøÐ¸qcÞyçWÎ+11FýÊyùúúR¯^=¬ZÿWêýu/ËôÖX;wþ¯çýýýéÒ¥‹F^@7mÚ¤¬©ò*Ê•+‡FòÒd¹¬­­ÉÏÏ×H^§N¢K—.Ô®]û•óº|ù2)×¹sçpppÐÈ„¦êŠW•îÔ©“F^¨4U®«W¯’ššªuýôÆÄÅÅi$¯àà`:v쨶OáÿêÎ;eʔѪz/(( //Ocå244ÔÈŠÌšªwm-—&ëÀÑÑñ¥;2üÝr©T*ŒµªÞ5Y®œœ ´®Ÿæää ¯¯¯‘‰Æš*Waa!¹¹¹©wM–+22OOO–-[¦Uõ^XXHNN&&&¯œWnn.zzzZÕÞÊ…F_MýÑ«fZù5U.MýkºÞõôô4¶E…¶öm,—&ë]“ôôô4V_šî§šÊOSA­¦û©6–KWW·Ô¿Îk²Þuuu5\/ º”Æ÷Wµº“Jû™˜˜P¡B©ñVÑÄ~!Þ†††¹ÉGhÁz´hÑB#“W…x“xzzJ%ˆ·FÕªU_Ø­D¼Ù´fkÏž=|üñÇjëS¥¥¥)óŽbccqttTv1/Mž={FBBÂKÏÇÇÇK~~>Püxll,¹¹¹äää«ü+((^-„Z&33“¸¸¸—žOHH 66•êÿæ<ÇÆÆ’••E^^žÚëüï¯ÚKkF°âââ˜>}:ʱéÓ§ @åÊ•ñõõÕØZPÚ">>ž5kÖ––ÆÀiÛ¶­ÚùS§NáããCAAíÚµcðàÁx{{sêÔ)êÔ©C—.]ذa.\À××—ZµjIÏB-‘‘‘Áòåˉ¥oß¾tíÚUí|pp0»ví"''‡† âîîÎñãÇñõõ¥jÕª´k׎Y³fñÞ{ï0uêÔ׾ƓøsZ;ëÂ… Ô­[—òåË—ê¸ÿ>&&&Œ;–¼p¾B… ,[¶Œ•+W*wTíÚµ‹µk×rîÜ9Þ{ï=Ö®]ËgŸ}ÆÀå;|ñÆ»sçûöíûK×FEE±eË–Ïݸq£Ä¿)M|\¿~}‰ç†ÊÞ½{ÕÞXå«N‘’’B||<‹/fóæÍ/œ/W®óçÏgÕªUœ9s(^{ÅŠ<~ü˜ŒŒ ²²²ˆ¥E‹Y/Püó´v–‹‹ ›6mâüùóou5mÚ”ÄÄD–/_ÎêÕ«_zÝÊ•+©_¿>………Ò«Åk•••Å/¿ü‚žžNNN\¼x‘5jpþüyzõê…±±1ÇŽ#==N:‘™™Ipp0P<ß055•ƒ¢££Cƒ J\Ô311‘S§NÍÓ§OÉÍÍÅÏÏú÷ïOPPGŽááǘ˜˜Ð½{wüýýIIIAWW—~ýú½ç­[· £nݺ4mڔ˗/ R©èС)))øûûóôéS"""J|îãÆãäÉ“j#ï¿ÿ>P¼‚xnn.ׯ_çwÞ¡Aƒܹs‡7nP«V-Z¶lÉ“'O¸pávvvÔ¯__:Ô[ ^½zdff²hÑ"æÏŸÿÂùV­Zqýúu–,YÂùóç±··—ŠÓrZ9‚µbÅ ¶lÙòÂ0êÛàÙ³g 4ˆ娒%Kpss+qt*((ˆsçαuëVxúô©ôjñZ-]º•JEFFkÖ¬aùòåüðèT*–.] ¯¡¦R©X²d gÏžåüùó¨T*6nÜHZZš²F”ŸŸW®\aРAÊ¿3gΰdÉT*•2/ñy:''‡+VPPP@~~¾ò¿¯¯/ááá¨T*òòò TË311‘ÂÂBT*G%$$Î;ÇÕ«Wñ÷÷W~G^^P¼UÇóŸÿñÇK¬‹´´4Ö¬Yï0àêêJJJ ;wîäÊ•+ìÚµ •J…¿¿?W®\QêN¥RÉ|ÊRnøðáøûû«ýÝtïÞ½ÄÝîß¿ŸŸŸTšŒ`½º´´4<==ñôô$00oooìw§Ú´iCXXË—/gÅŠdggGnn.P|'ÕÕ«W¹}û6Õ«WgåÊ•¬[·GGG¾øâ š7oÎòåËñðð`РAÔ¨QCzµx­._¾Ìœ9sÈÈÈPö/ûöÛo±°° ''‡û÷ï³ÿ~’’’¸yó&sçÎ¥C‡8991jÔ(rrrhÖ¬nnnxxx••źuë”üŒŒX¶lßÿ=·oßfÛ¶m1{ölòóóqvvfÒ¤I¨T*BBBèÙ³'*•Š™3gòàÁiÑ¢…Zž………>|˜ÀÀ@ Õ>Õ¸»»ãîî®ö3•*UR[ázÚ´iL›6Mz³Ð ýúõÃÝÝ]éÿ[ø°L™2$$$`ii‰©©)÷îÝŠ÷;}ú4¶¶¶˜›«ïð ££ó¢‚;wÆÝÝ””ªU«ÆÀqwwGGG‡O?ý(Þèõĉüðü÷Þ{äççckkKbb"úúújy&$$ R©°µµ%55U š~8uïÞwwwÒÓÓ)_¾|‰‹Unܸ‘°°0†N¥J•øé§Ÿ T¾Þ122BGGeôÌÆÆ===öïß­­-ÆÆÆ$%%ÉZ`¥„ŽŽNNN899)ÇŽ9¢á³¶¶V ¸4±}†⟑ÍñãÇQ©T\»v)S¦`ee¥P|ûy^^:::œ:uŠììl>þøc,--100 77—²eË’žžŽ‘‘Ñ ¯%¹¹¹ÄÇÇP¶lYÌÍÍyòä  ¾@iJJвÍGZZÚÿ².18JKKS»&33“ *““C^^FFFÊmöæææ%Þ€Maa!•+WÆÀÀ€øøxrss©P¡:::`ffFjj*¦¦¦dgg“ššŠ™™–––<~üX Älll¤3 ñ{k¶Êñòò"55•¾}ûþ.(+®’““Y¹r%=’!„S©T\½zCCC.\Xâ5•+WVÛÙÙahh¨=¨Ê–-[âϽ0ºSÒhÏïƒ ‹ÿZn µkžaeÊ”QFàþlD©Zµjjé—IåÊ•ÀÀÀ@í9ʈ•¥‡ÖXnnntìØKKËÏ›ššÒ»woµ!V!„ö±°°`Þ¼yùz;;;©4!„Xÿkkkµ¯KúÄú|‘5!„Bm&›= !„BH€%„B!–B!„XB!„B,!„B °„B!$ÀB!„`•¤GxzzJË !„B,M Wö0B!„K!„B,!„B °„B!Di °ž>}ÊÌ™39r$%^3wî\6oÞ,­(D)¬<¾ÿ>íÚµ#44T9J»ví¸ÿ>´k׎ëׯKå !$Àú3—/_¦víÚ|öÙgüüóÏ%^“ššJQQÑ ÇŸ={ÆÈ‘#Kü— ­.„–Ú¶m àèÑ£ÄÇÇãêêÊÅ‹•;¯]»Æ'Ÿ|ÂÅ‹9pà±±±Ê5«V­RòÙ¼y3ÙÙÙR¡Bˆ×FÿM.|×®]K ˜LMMùî»ïJüiu!´DPPK–,aÍš5DFF2wî\=zDhh(ݺuãµD IDAT³Ï>#""‚:uêШQ#œY½z5UªT¡bÅŠŒ1‚û÷ïS§NŠŠŠXºt)sæÌáàÁƒÿüs8pà€rݳgÏäuCñÒÚ¯MMM™5k–’¶²²âöíÛj×üöÛoÒ‚Bh±°°0tuuyçw8~ü8ÎÎΤ§§ãèèHÓ¦MÙ²e îîî|øá‡ûæææ”-[–ªU«°téR¢££±³³   €±cÇRPPÀ¶mÛ000†B¼=–âÍ’ŸŸJ¥ÂÄÄ(þjÎÑÑnÞ¼Iݺu±¶¶¦  }ý不R¥JtïÞnݺ0þ|vîÜ ÀÆ•+++ CCõlB °„â¿Zºt)çÏŸgóæÍXYYáååŽ{÷(,,¤víÚìÞ½›ãÇÓ°aÃ×Vί¾úŠsçÎQXX¨WIIIŒ1‚öíÛ3}útiL!„XBˆ×ãÌ™3Ñ©S'6nÜȼyóÈÎÎ&** +++¦NJBBúúúZõ5œ¾¾>£G&??###ÆŽ‹ŸŸW¯^•K!–âßsçÎlll(_¾<§N¢sçÎddd0räHüýý¹qãJ Ó¼ysôõõÑÕÕî–-ZÄÍ›7iÚ´©r,** ªU«&/„K¡yQQQ¸¸¸Ð´iS¶mÛVâ"ž3gÎÄÏÏZµj½qϯV­Z8;;Ó»worss4hP¼vžL„BH€õ‰‰‰ÜºuKIçääH« Q‚[·nѸqc5jÓ§Oçý÷ßç‹/¾àÚµkʾü1›7o¦  @™Ô^š|ûí·œ={(¾ëÐÀÀ€gÏž‘œœL5¤³!$ÀJMM%$$DIçææJ«‹·ÎæÍ›1b„’Þ³g½{÷V‚£'N0zôh¾ÿþ{œœœ1b‡&--“'O²jÕ*ÒÓÓiÙ²%:::˜˜˜ðÿÚ»ïð(ªõãßM6½wH¡„^"EE‚‚Æ«€Ô H.JAD¥HG¸ˆT© é!@€P„„„„ôžl²»ç÷GddIBàý<Ï>OÎÌÙÙ³g&3ïž9sŽÙlF§Ó=tõ5~üx¢¢¢ÐétÚS…#GŽ$<<œÕ«WS¾|y9¨„7eõ°Áàà`† ¦½®õâA`6›‰‰‰±X¶aÃÆ¯µÆž8q‚¾}ûjgÆÆÆÒ¥K1 Lœ8‘wÞyGWnÞ¼yôëמ={…·ÿÞ~ûm.\¸ÀöíÛ±²²¢S§N¸»»S±bE¼½½yüñǵ[h;^|ñE^zé%ôz=ß~û-ßÿ=ûöíÓZñŠÛ7BñÈXBž5kÖ %%OOO©,!„´` ñOINN¦K—.|òÉ'üôÓO¼ñƼñÆäåå±eËŽ=Jll,999´k׎#FP½zuªV­ @PPK—.eÔ¨QÔ¨Qƒråʱzõj:tè@Û¶mqwwgáÂ…¼ð ¼õÖ[@áHæTªT ¼½½ –r—Ú·oÏ{ï½GõêÕ©R¥ P8.سÏ>kÑçS!–¢”™Íf¦Nªõ4h7ndΜ9øùùacc£ ЩS'>ÿüsºwï®]´ @Ó¦Miذ¡Th3`Àš5kFƒ 8rä={öäøñãlݺUË“’’ÂôéÓ1›ÍRaBH€%„¸§OŸ&%%E ®Þ}÷]FÍ«¯¾ À'Ÿ|BݺuyòÉ'hÑ¢‹/fñâÅ888РA‚ƒƒqqq‘ }€4jÔˆ1cÆ M©M½³~ýz-ïÞ½{¥Â„Kq;bbbèܹ3ƒ Ò–™L&‹ûì3©¹[}¿Û)»Ñh$::ºTË^ûævÊ~'ûÆl6Ó¯_?Μ9æM›ðôô$44”:X¼'((kkk-]¾|y‹©e<<<ðððÐÒŽŽŽ£„[[[™šÅÑÑ??¿›æ¹ÖI¾¤tPP6BùÍò\_öråÊÝ´ìEF8/îûÝkÙo÷û]_v??¿›–ýÚ¾¹Ö®¤²_"ãvË~m(kZµjEëÖ­iذ!,Y²„0mÚ4t:ÿþ÷¿iРÕªUàÝwßeÿþýÚqf4éß¿?‘‘‘Ú²7òÆohClœ:uŠ^x^xAŒvݺuŒ5JûŸ?qâ=zô(õóÕÿÏ¥q¾*î\[ÿó7¦£££µéÒ*{nn.qqq{ÙKã\›––¦õ!½Û}c6›¹téR©kK*ûÕ«WÉÎξãkÉ?.%å’ºþ•ŸŸ­RR.©ØØ3jㆵ*=íŠÅú™3?VC† T#F )öõé§SÔœ9³ÔŠóÕš5K-^{ölSÉÉÑ*%å’ÊËËP—¬¬,5a„b_žžžj̘1ê•W^±xO·nÝTFÆ_eúðÃÕáǵôŠ+ÔŠ+´ôáÇՇ~h±%K–¨U«Vié¨É“'kéÔÔTõïÿÛâ=7–ãÆôíäéÞ½»JOO×Ò'NT‡ÒÒ?üðƒZ¾|¹Å{Ư´ô²eËÔÊ•+µôÁƒÕG}¤¥ÓÒÒT=nZޤ¤$Õ»wï;*{=TZZš–þè£ÔÁƒ-òtéÒEeffjé &¨£GjéåË—«~øAK:tHMœ8QK§§§«îݻߴÉÉɪgÏž%æÙ³gªQ£†Z·nRJ©Ó§O« &¨ï¿ÿ^ ñw¹zõªš0a‚úôÓOµej„ jÑ¢EJ)¥F¥¨”RjÁ‚ P€ÊÉÉQ›6mR®®® PÇŽSû÷ïW•+WV€ÅùjèСªU«VêêÕ«w}¾êÙ³§JNN.ÕóÕÑ£GÕ„ ,¶Qç«Ó½{÷VIII÷t¾Z¹r¥Z¶l™– SãÇ·ØFiœ¯îæ:ñïÿ[¥¦¦jéÉ“'«héU«V©%K–X¼çN¯ƒª[·n7-GiWS¦LQû÷ï¿£ãª$))ÉjÙ²ïUDÄAuäȯE^ ÌV»vý¢ºvíPbÜ3bÄõÛoÛÕñÔC9Ш““ãÇ/vÝ’%K¤ÝRÜ‘˜˜­Õ`Æ ¼üòËÔ¬Y³ÄcLˆÒâëë[ä8«]»¶Å²qãÆÑ©S'm¸k­`×nQÖ¯_Ÿàà`’““±µµÅßߟ:uê`6›qrrà›o¾aΜ9äå员˜ˆ¯¯/ dgg“““óPNè-ÄßMFr¢;vìà?þàèÑ£4lØ/¾ø‚ 6ðøãKåˆ2ÅÁÁÇ{LK[YYY¤‹ôÇÚ°aƒEzàÀ\¹r…ŒŒ <== £cÇŽœ?ž.]ºhC!$Àâ®ôéÓG*F gX±b/^¤^½z\¹r…Î;süøqæÍ›'–` QÔÚµk™;w.ÉÉÉÄÆÆÒ¤I©!nиqc7n €RŠ1cưhÑ"êÖ­ À„ X¼x1QQQìܹS*LH€%U 5Ë–-#<<œ-[¶Ð¦MBCCÑétÄÅÅYtBO§ÓÑ©S':uê¤-»zõ*f³¹ÈXRBüÓbccÙ°aQQQÌ›7ユCFr”#GŽ0vìX.]ºDXX˜¶ü•W^aÀ€TªTI*Iˆ»ðùçŸsåÊ~úé' pÍ#F°uëVFŒ!$þ1ÇçСClٲ徖CZ°Ä#¥Q£F|ýõׄ……ѲeK©!J‰½½½ÅHþÙÙÙ„‡‡“——GzzºTøÛDDDÆÒ¥K4h³fÍ¢~ýú¸¸¸H€õwÚ¿?S§NÕÒ7N¹ niiiôïߟ_~ù…mÛ¶ñüóÏÓ¶m[Ú¶m+•#ÄßÈÛÛ›¥K—’€‡‡J)–.]ʆ °²²báÂ…RIâž™L&zõêÅÉ“'Y½z5ƒ Â××—1cÆÜ÷²=ôVóæÍY»v­––#òrüøq~ÿýwÒÒÒÈÈÈ âäããƒv!üïÿKZZZ‘9K…¸]ÉÉÉìÝ»—ÌÌLš5k†µµ5óæÍcÑ¢Eeîú.·ÅC%''‡Ñ£Gk#P?ýôÓlܸ‘´´4ÓJˆûÈÚÚš pêÔ)ÜÝݵ@ ,`ïÞ½lݺU*IÜÒ!CøùçŸ9zô(S¦L ~ýú̘1£Ì•U,ñPùñÇÙ·o999Úlëõë×—Š¢ ðööæé§ŸÖÒ³fÍâÒ¥K…­\¿þú+f³™: ×Ë%êQÍùóçÙ¹s'¯¿þ:Ÿ|ò 666¸¹¹•ù²ËÑ+hƒÏ>û NÇ«¯¾J÷îÝñññ!//Ož¢Œûì³Ïh×®öööLœ8‘o¾ù€3fH€õˆSJѱcG8€N§ãõ×_Çßߟï¿ÿþ(¿½â’žžNdd$¤AƒLš4‰Ã‡`6›hÓ¦T”WWWBCCµô˜1c´áS®W$22’ôôô¢ÕBÜ›óçÏOxx8!!!|þùç|üñÇÔ©Sçû.`‰ÊðáÃY±b{÷î¥ÿþL˜0Ê•+`cc#$ÄÌÎÎŽõë×kéåË—3|øp²³³1b„ ü‹§K—.:tˆ/¿ü’yóæñøã[` qrrrˆŠŠâôéÓ4iÒ³Ù̧Ÿ~Ê?þHnn.kÖ¬aàÀœ9s___íWî›o¾)•'ÄCèå—_fÕªU$%%áääÀáÇ0`¡¡¡ØÚÚJE=@NŸ>MBBÉÉÉèt:ÌæÍ›ùòË/4h}ûöÅÖÖö¡xâÿ‘É}ãÆ$''Ë^Fœø³ÙLïÞ½‰ˆˆÐ‚¥víÚQ³fMí—‹µµ5ß|ó ‘‘‘2(¡€®]»Idd$¶¶¶Ì™3‡ùóç³gÏIII¡gÏž¬]»–_~ù¥ØóUJJ ™™™ÄÅÅi×›´´4휅ã-effjA[qçÚÄÄÄϵW¯^¥o߾̞=›S§NpîÜ9†ΰaÃ0 ÄÇÇÓ¯_?fÍšEdd¤VöuëÖiÃVܪìqqqy®•ýZžÛ-{\\œv¸ÕuðêÕ«ôë×/¿ü’3gΚšJÏž=Y¿~=[¶láèÑ£ >œóçϳÿ~êÕ«GÓ¦M©Y³&...T­Z•õë×Iß¾}¾ƒ5%å’ºþ•ŸŸ­RR.©ØØ3jㆵ*=íŠÅú™3?V³f}ª,˜SìkÕª¥jΜYjÅŠùjÍš¥¯={¶©ääh•’rIååe¨›Ù´i“úöÛoÕþýûÕ”)SŠÍóú믫yóæYž­¦NZäõÔSO)@{õïß_FÕµkW¨V­Z)¥”7nœT`` RJ©%K–hïÉÉÉQ¿üò‹rssS€:vì˜RJ©… jy ƒÚ²e‹rqqQ€:yò¤:xð ª\¹²Ôš5kÔ©S§THHˆÔÔ©SUBB‚zæ™g Þ|óM¥”R'OžTõêÕS€úôÓOU||¼jÙ²¥T¿~ý”ÉdÒÊþì³Ï*¥”?~¼T@@€RJ©¥K—jåÊÊÊRJ)õþûï+@)¥”Z´h‘–'//OmݺU¹ºº*@?~\}ú(³Ù¬ºwï®õôÓO+¥”úðàʗ/¯”RjÅŠZ¹222në:x}Ù;¦öîÝ«‚‚‚ V­Z¥”RjÍš5jäÈ‘jçÎeöØIIIVË–}¯""ª#G~-òZ°`¶ÚµëÕµk5bÄ_¿ý¶]ÝOÝU¬òåHII,vÝÙ³çðööº£í]½z•þýûkéÛ´{÷î$&-‡ÅX+×<ýôÓtèÐÖ­[Ó¿üüü°²²¢AƒlÛ¶Mü.$$___¼½½¨[·®Öç Gƒ÷÷÷ÇÎÎN{Òåú<:ŽjÕªáïïOjj*ÖÖÖR©R%²³³±³³£V­Züøã$$$P±bE|||X¶lQQQÚvêÔ©ÃO?ýDBBAAAøùù±lÙ2¢££ñóóC§ÓÝQÙu:E//¯bó\û~öööèõz­ìYYYØÙÙáééIõêÕ¹t鎎ŽDNNvvvÔ®]›5kÖhe÷õõµ(ûµÏ½~#!„¸×O‹R®\9~þùg222¨Q£:Îâ|åèèHݺu9|ø°6W]Æ Ù²e 8::R§NŽ=Š‹‹‹v®ýå—_´<7žGëÔ©cq}ùå—ÙµkƒêÕ«Я_?BBB°µµå•W^a×®]äç猣££VöêÕ«ceeeQv­ì®®®xyyQ­Z5¢¢¢prrÒÊ~äÈíû5hЀ­[·ÞvÙoç:xcÙœœøùçŸIOO׾﫯¾Ê«¯¾úÈ—º””KÊòž·YY‰äæævô O=Õ“9ÿºÛr+ˆO R¥JdffÜÐ–Š——7ÎÎÎWÑ.¾mÛ…€?t:3ŽŽžØÙ•<ãÏ?ÿLLL !!!ìܹ“·Þz‹•+WÒ¾}{Ê•+ÀúõëILL¼£NÎÁÁÁtêԉɓ'ËYI!„x„¥¦¦°yóz{¬yy¹EÖ‡‡Ÿ råêÌ›7—€ÿ·Ó®]{êÖµì˜W}°ŒF#999E–ŽÆ[¯TÀÝÝU{¹¸8uûóO5nܘ?þøƒùóçÓ¡C8p çÏŸ×òL:•¯¿þZæ˜B!D™rW· Œèõ6ØØèÉËË [¯rrrÂæÅÓ§O\…‚‚ÂÖ¯„„DÜÝo8__ß"·ŒF£Ezß¾}²…BQæÜõS„11—qw÷ Ÿ.HIIÅÙÙI[o2™ÈÍý«¹---]j[!„`ÝÊÙ³‘888’••‹‹³Å:£±€‚ÖÖölݺ£Ñ$µ-„BˆGÂ=än2™HOÏ &&¶Ø'®’p•š5«—©/½}ûv‹Ö5!„B<\† F… œËÝÝ_¬«=þi2™hÙ²%VV…aÖÖÖüñÇ4x ''ËV-kkk®u‚¿_jÔ¨ÁåË—Ù¾}{±ëãââðöö.•yí¢¢¢ ºçídgg“››«=.[VÊ•““Cvv6>>>÷¼­¸¸8¼¼¼JeÚ‹ÜÜ\233-)¾[ñññxxx`ggWfê ‡6qssÃÞ޾̔«4ë½4Ë•——Gzzº6¼T꠴ʵÿ~vïÞ]*Süç?ÿaðàÁT©Råž·uøða6oÞÌ|pÏÛ9r$½{÷¦Fe¦ÞÞÿ}ºtéR*3Ì—V¹ÂÂÂX¿~½6CBY)׉'X¹r%}ôÑ=okܸq¼þúëÔ¯_ÿž·uæÌ.\X*cÁMœ8‘—^z‰F•©ãôã?¦U«V4k֬̔ëìÙ³Ì;—éÓ§—©ãôâŋ̚5‹Ï?ÿüž·5mÚ4žzê)žxâ‰{ÞVLL S§NeöìÙ÷¼­Ï>ûŒÆ;Nåýù¤vûó^µmÛ¶L~ÇÒ*—ŸŸ 6,•mµhÑB™ø^ùúúÒ¸qãRÙVóæÍµQòËÒñЬY3<==ËT¹¼½½iÒ¤I™;Þ½¼¼J¥ iÓ¦Úè×÷ÊÃÃæÍ›—ʶ7n\*·êKû8mذa©Üš-Ír¹»»—JËNY>Ï7hРÔn:99ñÔSO•ʶBBBJåhY¾¾^ïŽGr/-·É]ü¥´o ñ xnQZJó¡¸}en$w!„BQ2½TAÙW³fÍRkþâAñŸÿüG*A<2|||èÞ½»TÄ£`ÙÛ»¡”¹ØuƒÜÜl,‡9?Ijjµk×À×·h°ÍÙ³g)W®uëÖ%))‰cÇŽ…4ûúú²oß>ôz=Ï<óÌ#÷'–xԔƓFB<(œK­O«x€,¥Ì ™Å®»r%ŽÔÔtêÔ©©-۷áààÀž=û=ºè/Ó5kÖpñâEÚ·oOݺu9xð K–,¡E‹xxxàááÁ™3gX¼x1|¨vºuë8~üx‰Ã Œ9’œœÆ‡¼ÿþû 0€‚‚æÏŸ¯å0aB©uÂBQ:~ûí7Ö­[ÇŒë¢3QQIDAT3Š]ÿñÇsåÊÞyçªU«Ô±cG,Þ7tèPªV­*•ZŠÎœ9GbbB‘åIIÉT®|wƒ¥ÿ#}°""ÎP¿~]úöý7J)Ìæâ[¿BCCiݺ5ß|ó ¤ÿþ4jÔ777\*ƒ•%GŽáÔ©S´jÕŠ)S¦Y?kÖ,z÷î͈#xï½÷´º#F0eÊjÔ¨Áˆ#8p &“ ƒÁ ÿ)â‘qáÂ…Û8ÿDpåÊ•×_¾|™Ó§OkéÄÄD­õüú<Ráâ®\¹r…µk×2`ÀÞ~ûí"ë—/_N«V­1b~ø! `èСüðÜXãÆ¼­|Íš5cøðátéÒ…aÆ=´;Ö`0`ee…··7ééE'Ä~çwغu+M›6 55• *ƒƒ*T _¿~Ô®]û¡ @…¸™áÇßòIÃ+V”8ÐhDDÓ¦Mc×®]@áÓ\}úôáøñãZž'Nàîî^*3<ˆGÉd¢  ’““‹¬ïÒ¥ P8xsݺuÿl9I"00üü|Ê—/Opp0ááá(¥(_¾|©¶/ÀÓÓ›Zµjc4ý¥+Q·n=òòòŠäINNtÿ|€õþû“øõ×ÿáììDDÄiÞz«ïm½oìØ±ôìÙ“ÐÐP\]]ïû÷ÿ³ÙÌåË—ñññѦ9ؽ{7.\(¶rrrPJñöÛo³téRbcc ÿQæedd0qâDΟ?OïÞ½qww'22’ß~ûgžy†=z°iÓ&.\H³fÍ2d­[·Æ××—*Uª0aÂ._¾Lhh(...Ìœ9“ɤÍ3jggG¹råèÔ©+W® 33“)S¦púôiºwïοþõ/Ú´iÜ9s´r5mÚÔbF°°0>þøc7nŒ‹‹ ]ºt!''{{{fÏžRŠþýûc6›ùä“Oغu+[¶lÁÆÆ†¡C‡Ò¸qc¦M›Æ‰'X¼xq©ù&\ÑÑÑxxxhã.ž|8}úôá¿ÿý/ݺu£U«VÌš5‹ºuërîÜ96n܈‹‹ vvv¥2Gšÿ„ùóçÓ¾}{Z¶lÉk¯½F=X¹r%?ýô»wï&%%…Š+ÒªU+öïß϶mÛðõõeíÚµìÝ»—ï¾ûŽ *°víZ=z47&""(|8æÆÛ1K—.¥eË–|üñÇtíÚ•^xggç›–³AƒÔ¯__»E˜““ÃÚµkÉÈÈ`ðàÁäää°råJlll ¥víÚLŸ>ÚµkÊèÑ£qtt¤U«V<÷Üs\=‚œñðð`îܹ´iÓ(œwÆŒ 4ˆýû÷Ó¯_?úôéÃÒ¥K0`/½ô_ý5¾¾¾¤§§óý÷ßãááAvv¶Ü©(e˜LªH€•••Mbb2~~0òptt"##Í"Onn™èt÷¡ën3†Ñ£G³fÍ ôÐîØÊ•+ÓµkWiÞ¼9ìØ±C›ë,00™3ghd0€½{÷‚——666ÄÇÇS­Z5éà.¶¶¶ 2331têÔ Ú·oÏ•+WX³f Mš4áüùóF2331 ÅN Þ¯_¿"ËrssÉÏÏÇd2akkKAA™™™èõzt:ƒ£ÑˆÁ`ÀÎÎŽ‚‚ŒF#yyyØÛÛc4ÉÏÏ×ZÆÌf3™™™deeaooRЬ¬,ôz½6)xvv6™™™ØÚÚÒ°aCL&‰‰‰,Z´ˆ±cÇJõˆñðð _¿~\¸p–-[°yóf­3»¯¯¯vž×ë /˽zõb×®]Ô¨Q‰ŠŠ¢bÅŠÒÁýopõjµjÕ&+믮:çÎÇÛÛ[KGE]¢nÝzÄÆ^Ö–ÅÄÄâééQì6ï*ÀÊÏÏçüù?Š]—ššVdïàà*øùùÞÑg\¹r…Aƒ1{ölÜÜÜê[µjUíÆÆÆ†V­ZiëjÕªE­ZµŠ\˜®ÏS»vmj×®-ÿ!âòÖ[o1yòd–,Y±cǰ<üýýyâ‰'´>T*T <<œAƒQ½zu>øàL&ööö%N‡³råJˆŠŠâÍ7ßdúôé¬ZµŠâääÄ’%Kððð`Ó¦Müë_ÿb÷îÝxxx°`Á ÄéÓ§ÉËËcñâÅLœ8‘ääd „ƒƒß}÷={öÄd2ñÝwß1mÚ4&Mš„››“&Mâ÷ßgîܹôéÓG‚«GT`` Eçô뇪R¥J±Ý?ûì³Å^'Dé3›ÍÄÄ\ÆÛÛ£ÑHRRŠEpuíÞ¥KqvvÆ`È#==£Äà îrª£Qqùrt‰õòòÄÕõæÓàÜ8UÎÌ™3 ±8 Š#Ógñð˜0a´hÑ‚!C†ÛÌ^ÖþÿoU†1cÆÐ­[7ùÑ#Ä 55…ùó¿¦jÕÊØÙÙãíí‰^oMtt &“ +++*1kÖøãèè„‹‹3f³‰„„ÄÂ@J§+vªœ»jÁÒëuT®\ºì*UªÄçŸNxx8C‡-²>..ŽJ#!"cÇŽÅl6k·ëneõêÕ÷½Ì·*äI“°²’YÈ„xÐ yètzΞ=GNN.îEòäädS±bEŽ £ Àˆ‹KÉ}8ËL¬ÐÐPBCCK\_¾|yi¹â!s­¿Éß•ÿ~”¹¸ñp„e—››;ÁÁ5´´¿E‹àÊlVøú–£Q£ÆÚ²zõÃÕõ¯àÊÁÁ¡ÈvïêaiÐé¬në«B!ÄßÁl6ÿù€‹íMóäå´‡XJþqeÙr}ß~*eF)Ù¹B!„¸n\XYYáèèpÇÛ-·333Y¹rM±£$ëtVØÙÙa0ä¡$"BÜkk½ÅyÆl6“Ÿ/ÓK !J’ô6X[[c0ä»> ÀŸÖ­Ÿ)»–ÉdÆÊÊŠ  ŠËÝÝ=±µÕcmmK|ü”2ËÞBܵòåð÷÷ׯÝ:}ú ùù¹R1BˆbUÁÕÕ…¸¸Xm ¾ë5oþDÉÁYYû2VV…}³ªT ¦  P„……cggWd|-!„¸SYYäåå~ŒZµjH¥!J”››…«« ööv€5ññW´i7S¦,wwOìqvv$??GöªB!î;“Éøg'vE5‰‰‰!?ÿæ–™ÁZ<=½)WÎ[[ké!„Bˆ2)++//wRRR0Me?ÀJIIbûö¤¥¥ks~ !„B”%ÉÉ)DEE“——‡^_ò¸wwu‹ðС£äææ•¸>8¸2þþåïx»þÄÇ'àà`O^^5jT“=)„BˆûÎd2qæÌ9@áìì\ìHï÷`]Mʦj“׊,¾Éò¯Æ±xÑ7(e¼«/ààP8Ž-¡zõ`²³so9À—BÜŽôô 22Òdè!Ä-¥¥¥OAûÛž­á®,•;ËA·ÎgìÛ]e"ÀÒëíÑét(UüçÏ_ (Èÿ¶··gÏïìÝû;7àùçŸý笑#G2jÔ(IOOg̘1L›6 gggÒÒÒÈÌ̤B… 7ý£ÑHLL .ä‰'ž (¨pÂDƒÁ@\\œ–·\¹rØÛÛpéÒ%m¹‡‡nnn¤§§sñâE–/_Nƒ pttÄ××÷¦ŸŸ““CBB‚– D¯×“€ƒƒÉÉÉx{{kß-&&£Ñˆµµµœ=„BÜ”‹gy‚êçhØ *UªTfºÇ䕨JuöläX5j“ŸŸÏ¶m»þÙ+&&†ÀÀ@ÜÜÜÈÊʲˆô«¯¾â믿&66ö¦™™ÉÌ™3¹pá3gÎ`úô騨Ø0þ|Ξ=«å bذalÚ´‰íÛ·£”Ò¬·ß~›ððpV®\É©S§˜9s&uëÖ¥OŸ>%~¶RŠ™3gZX!!!ôêÕ‹®]»Ò²eK’’’ðññá½÷Þã÷ßgÆ Fôz=QQQT¯^]Î B!Jôë/k±±±å‰g_äê•ËŒÒìì :÷ $É¿eËÚ´y€C‡ŽR¥J%¼¼<Ù²eUª±sço<ýt j×®ÀÚµ›HIIÅËËGGÇ?#¢Ù²e;¿þº9sàááN§Nÿàôé³üúë^í3{õê†]ñƒg^¾xŽÿíú™×»DocË’9Ÿ0çÓX±ùP‰ßyéÒ•de^õêÕ¡E‹fœ;wkkkªT©dñ=322‰ˆ8MbbW®vïß¿:Ž«Wøé§ÚvCCÛQ®œo©ì—ˆˆ3899²eËö?Yh×î|}}¨^=˜mÛvYÖÅåX6mÚª¥;v|OO‹}u™œœjÕªqçÖ­tíÚ•gžyæ–ù<<<˜9s&—.]Ò¬k6oÞ̲eË´t—.]6l+W®dæÌ™Z“jll,vvv<û쳄„„0|øð"Û*)À gîܹڲ‹ ‡½×ëõtèÐ5 +§{÷î Ö¬YðaèT©ƒ#FÈ™C!D‰~ß½…ËW¢|0}> fOælÄ1¦}ûc‰ïY²äíb½mÛ.^yå%¼¼<ùî»…„„Ô¥U«Â¥+V3|ø`ÜÝݨZµ2æÒ¥(Ê—÷ÀÕÕ…:ujáêêL:µptt(lAKÏ`Ù²U¼ðÂsÚgN›ö9ãÆ,R“ÑÈÄwºrêø!._:G@Å*,üj*¡ûR±ru hÿ¬o¿ýž  ª@xøI<<Ü8yò4vvvZ€uí{&'§0xð{Œ9”:uj0eÊ Þÿ]>ÿük^zémÛsæ,`„Q¥²oöï?Äš5ë5ê?FÑlÚ´Õâónäì줕`ÆŒÙLžüÅ>‹Œ£]»v„„„`gg§W%±³³“Ö+!„7õø3mÀ1€¯¦Žâ?½Û0üÃY´xöÅbƒ“›qp°güø¿‚ 5k6hÐ5zŒýû-[”<==xê©Çñôôä©§×–~’úõëhËNž<]ìgZëõ¼7i6ï~ƒÿ.ú €jµB3õ;l¬\ä=nn®$%%“••UX7¡víš%~@Û¶ÏÓ±ã«Ôµ£ëË~ýߥaøð·µmšL&λpÓü…Ý—þž!<üä]}n‰Ýñû÷ïÏ·ß~ À¨W¯žÖ$ ðã?Ò¯_¿»úÐO>ù€Ê•+³xñbíuíóf̘Á¼yó´åyyyÅÞŠ<|ø0;wîÔÒ±±±tèÐÈÈH ðéŽ]»vY|ÆòåËo»œÉÉÉÌŸ?_ÎB!nª{ÿ÷èÒç?eªLz½5öööÚkÈ%æ­óXS¦|õvö·µí7Þxòåý´mïÚµ‡Ó§#Š}9{öwõfe¥»»ú/9ÒlËæÍ› ¥Y³fŒ9ÒbXø‚‚rssoûƒ–-[Fhh(+V¬`Ú´iÚ2€I“&Q¯^=†JÇŽµ¬.]ºP«V­?£uO:wîLhh(7f̘1Úû•Räää`þsRE+++žx⠋Ϙ={öŸ¿Y”/$$½^ÏgŸ}Æ€HLLÄËË‹ñãÇãíí-g!„%·VXY1dìt<½ý8ô¿ítèñÖMóW¨ õý±²²âÂ…?¨S§æMß³oßAΞ=ÉdÆÕÕÕ"¥JÙ¶mééF^|ñÿ¨W¯öZžfÍßtûµCš2÷ǽŒìÿÚMoo,Z´777œœÿü:L&3åË—ãôéH¶mÛÅï¿"==ý–uW¹rE‹~P{öüÎĉcJmß|úé—Z<G… …ýË/\¸ÈÁƒGˆŽŽaçÎß´Û²F£I«·°°ã¤§gP·n-­œ3f̦k×7ý\hôÈ@£B!®—““Ãá°ó4}òÿ´eûÝJó–…}|ô&t¦Ô"O^¹§]¬{¬>ÉÉ)´jõ´Å…à÷ßòØcõqp°gíÚMZÀ\…-škùÙ¼ynn®„†¶àܹ ìÛw@ËÓ¹óëØÚíä¾mÛnžú¿7´ôñ#û®YG'¬t g}V±×¾ÿþw-99…³›ÔªUƒ¦M .vïÞKTT4Í›7eâÄi,[6—ÌÌ,Μ9K“& µ÷_û® IlÞüËu <ÏãëëSäóll9p`¿ö™7ÊÊÊ¢M›ÖËæÏ_BÅŠ\¹R8bAùòåø¿ÿkÀ±c'?QØÚ¤×ÓµkG-Û¾½pß4hBRR2­Z=M~~+Vü???èÑ£³X` !„(mJ)ŒFS±Ë_yÌeú;äççcgg³o©=Õ+ÿûß~¢£c¨V­p\­5k60eʸR)§N§#77¯Äú´²².ò”äüùK¨\9È"h½[Ó§ÏâÙgŸ ;¹{xxðâ‹ÏK€%–Bñ÷Û´i+gÏv$ïׯ§vñ~?‰»»AAîy[C>_=€*U‚xå•—nÞ`YYéÑétr„Ãl6•ù_"B!„¸ÿôEƒ£ÔŠB!Ä=°’*B!„K!„B,!„BˆGÉÿIº”áÃ{”·IEND®B`‚snd-16.1/pix/odd57.png0000644000076400007640000000537411316666617012611 0ustar bilbil‰PNG  IHDRÑÙð…sRGB®Îé pHYs  šœtIMEÙ  2žš‡ ŽIDATxÚíÝ[“²:…áOËÿÿ—ÝÔ¶Èž÷jjF™Ðé¬^iPï÷û  O!š òŠ|ÝãñX~Ћ€²šûx<>Rûý3àǽ…‘}¿ßÏ È¬¹?"ËçÀebôT?wÓSj(ÒÏýy^,èç@K𠍧¹®¡¥`Oà´Ï]dw!£àæÒ£SÇY^¼œË÷cHmøÿþÔÎ Ê8¶½Ãþ»õ”EŽ0ï¤ PMã³%ï_'·/±½…÷ÿtäÇó˜égô©4 ²åùª·ËŠFàîó5ßðœ*p‹Oodå\{}§…$ƽÚÓäü-ñ§ª]œxä‘罆6ê uNêÆÐ•Ûl5’·cªk6Ù£}xÀçTáø,Ú,)uÁþ0,·çÒå>2f®CyN>îÁèhNÝ3SBŒú•³N¯/?òÈŽJb(ntý“›¯kCÚû°>ï?¬Ï-*»*ÐÎ5}qö94õ|º•cº‡ ãí7!ôês‡Ìª–ö´]QaENoArô'¸(Õµøû:UÛr9i‡wK9§¹àCÁ-ñ¹ ¬v€ÇogØEݮĨ©õÏ1Nø\´[iôòpÙäÎÖÊ»Rh®,€9|î`V‹mÞì(¢SÙØB+úUó¦ÚäZŸ›-,jÆä¼ ­®I àfKn`’6È} <)0üÎýðÅMyµÈÁÄ(ÉÍšKì t¦Jã§<ÝÞÂE“EÓÛ·ºîAž-yº˜nš ‹ f™æÂ>w\.%f†æJt̘É:c4W¢§¾ÝBÓÈ®(p^4—a±&c’|£Å£ù\NíÆäÓ9¦Ó\ ¹Ä/ÛCÀ–ŽæÂRêEú-º-8š 4—§ƒ´Ím­³á Ç9×,˜JÐ\#»éúÏÙ*+ÍåîÔ+<4—tB&€Ï•ú3­@÷÷+…æbc}’? )^,u ¹×7$cìÇû2þË~ßN¥eô€æ¢sŠ^`qõ4wÆ•Q‘3 ¹À,r?O7vÎÖ3Íe´Ð\Ø ›΃æÚÈ ß4 C ¹röLŸ åôp.Í-D™ ÉšÛÚ€ZKsV*®ªÌÑ\4á ¹`v€¶’ŠæÍÅVqØLÐÜqëšK[Ð\z  OzìŠèçv“[“d$06Ùžûkm@=Í 1r z ãp¶ÿPºó÷øúûÝe#³EsûƒÐ‰+ˆæªÿê¿i’6|.hz›‹[¶Aö^4BE‚æö:s-—÷»ÆÆõ³k. P–€ìª’Ë/ó¹Àçb”ª¾yØÅ»š {j9ÅæB-ÁÛ>€R šk0;͵ªðÔ|îŸÛrM3š[IppÓÍ\?ø\À¾ 4èkS¹yy6ñš-ÁÍš øË«ÄAÝl õ4÷§áE‚`Ao™¾> 6ÃGRŸÇ}sg€DÒ\ôg+Ð\¨ÍÕCp~ažE—rdš ņþ‚Ï€*T¾Hs{9œšAŸKX!sp‘~{V4w´@s3«!Á¦ÓSap»3 ‰|.d0TÐ\ U©Ú,u‰*Fdz>4@žÂ#|.¿pµX¡|.Ð\ ¹@ Ú Í='5/¸Ó Ïý½x‚ì€V4×s`½6¯4qË@‹ ¹èR¸Gº|÷]†,K•'‹ÉÍè~h.ð¹ÒüÔÌÆœæ€:As îf‚æ\[aš è’@s4€ G{c ¹è÷Ïzõ#ÍåÈ€žJ—Jl?ç›ëàÏ–Ã×à¡0ÏbÃH"ÀçÀŒÐ\mî`¬÷4}ÙaškïPvšÛpȺ8‘^Ž ÌŸ Ø” ¾jêk7šëª´•6[ðåüK€Ï•U„às™‘N6$;>‡Ùrx(Ѧ¹µ“Û„±½4W`À JLŽÉCè-`œÍøT1„If¡Q͵&Ås¶êBvù\4½b¹Åtåz<”Î&†æ¢ ;üó3m‚š…VžµnU|(Ÿ{Ý.}/IJ¡SS|ïAp—e£ãz y¤ä^ÇÍòs‘jÒÀ5€æbvg7¤MS¶›Mš›ÙŒœ6k#Æßm÷ìÍõlö™è Í%1ÀÌ5©Y¨Y/kûÜ^d7ü8&ë¬:úÐ\XÕÆ3ù„†WücÒÜJ6¹ÇX¯Ç\sŸ5•¬ŒÔýŸ¸ÍWf>n–DÒ`äsù,‘q¾ÓÂC¥¹Î1¿Œ¡3 3ìE:ÐÜ”ÅÐ~[f“—ÃÄ»³O½}°drílžÔSXoŸ’~ÃbBSÐÙäs-T$Mœ™”ÚÚ&î²ß½YsŽz™÷\ã\_É?uäçx™al#©[ÆÞkG‹Ú»V>ãIX¹“:¶\ÿ=ðý™1†îâ2i#Í;;ŒFÂÛÎ0.,‡Ãw}¿ e-Ðܞ؛Îõï}qeÞ·3Œ ¿iäì)_^‰aïkÑé- h7€1–ÃH;9>7iß”>Ç?•9r'uy {oÜÆ'×ßmôý›õN<|ÀÃa¥˜ÿuj}þ|8ì‡/85Œ³“rê”#•(0_‡SÓÂúêÑåÐÜ+S»9ÓñÓXùëCúà÷†±ÖÓõ»Öc>T´ð0Ög¨,Ëoo{ÿ1>7âß>¯˜S>Õ’$@bHO½7Ã@qêq[Is“šMþõž¶Æ?€ùòøóžx–£rÖøç:»kÇ)‘T\‡ÌŠøâDsµ®:k˜4[x"KÎ0ôÀ¤„ÿt!…®>Õ)i?ƒïe Ò\u¢ø ¬ã†¹€;ÔϦ;ýF·Ž ßÙwßB/Pn¾¯YžÒž·…¹HíúVýX•8Âûý^ÎëÚÁÃïº|ý`ý×µ?JOøÜ¶±®/g¯ïØ;Hâ0Îp„ËúQÒ½hDþé𔿯n^«Ù4ŒyŸPµwßµÜX¿>ưÎC¹²Ïrë¾Áý¤Àí]̃ÞÐ\‘ÿ^/ú<{RXIEND®B`‚snd-16.1/pix/fmeq13.png0000644000076400007640000000247511147553267012760 0ustar bilbil‰PNG  IHDR^,h V3PLTEÿÿÿààà°°°   pppðððPPP€€€@@@000ÐÐÐÀÀÀ``` CY¼ pHYs  šœtIME×  :¶ñIDAThÞí[‹rã ä%0üÿמxÄÁ¶HÈÕ—¹Î°3 ië®´B ÖŒý6ÈyÕŒi¥ ¸ sNqÆÄÆý°ñ-æoþ4p/8FÕ¨ sXŽ`ü‹Ú‹e—™ÅéQ~;¼÷Ë›ëÛmÞ‡úk#¿Œ°Ü†ÙûÓIØNü·ž>¿{¦ï±“_áôkª_ù’æ.)úÃêNð—>‰§¬÷îü{Õ.:ÀO *¿ÞšøTó¤8øpfxºq]^jù`º]ÏÄè׋™œà¢ òë ÷܉…ǼJÆÆê]yp쩈)%@½úˆÎu=‘š®ÔYý«j«æ«‚ʯ7&ìËÐA*v|{¶fZ„]ëT"¤qÿy§¥®=¹Ã±ü¾~¸*¨ýzmb~¹L~R8’"‹ Áó`Ò` gPk€Grëf ƒYZ)‰…kSB‚•GÇ¡ÎêTuåºð¾)ªÅ® öëa‚’ÜÐL©å’5¯F;Y×^¼TºØŒÂ½$–Ù4åe ~ÄZáMÒ¸Sw¤‰E`íåj‘»çgÂièËç}ë>Íu Ü3áW1AJnh&Ô‚Ð:0ØÚW£" âj0ë40gcÂa™Ñºž“•,½ÇðŠÉZ+Kz»¤­)¾-–Ñ„©]ª @Yï©Åò ïK¯Ö„_Ù-¹©ù¢V2y|ûêd'É’ñ¹% g½ ¼˜ŠScDͼ—Þ$~©#ð(q6o Kﲇ÷JX“ÚÞ}ÆtÙ¥÷Þ£_É-¹¥ùªØ‚WØ­%(Ûɲt•|Ç›y2ÅTüÞZ°{­U³Øi¥0f–Kx/„5ioxY˜ÌÛÒ»‡÷à—]Ú’[š)µ1ïµk_ídY2¤ÏS)sÙJE*¾bž„ý^ÄY3´Á"Mä¡°œÃ{%¬IÕÒ<‹FX‰Ú+æcé}”Ù£_¥¼’’[š µ)1W ¼uu¤+²V“â±EŸW®ãP3Ó$³\Ùˉ¤Ã[v—kþ^ÍR…÷IÈ¥B Wœ©îÜú,TEž1WœŠ‹º–"<ï…“_y %·4j2iAÙN‘…,\@0[t0Ðú–\Û¤ž6ä‚9¢2Szuu]7L6åJ©Ï,vž4‹o\O³<ЍeãLÙ'©ë;ð;²Ë`y‰Sd7¯b‚–ÜÐL„wñÇXtiAÙÎ+Ο”¶†JBÈ/&u&ng4š#;! ’™¹¬¸¦±VÓ…·±¬q›U ±U»‚óÚ·_MHni¾ªM €7dÑÞ1[8×ü¤·ˆÙ0Ï2*»Ž{òÝÙ‰•°=&^kæý‚:¤sh%áÞñÖþ#Îïl˜ûq\צl9G7ĹeÎéóÖÄO4W‚º¤h`ßDèê8lçIկཉ{4wIaßý;@K°šsƒÖó~ð%ÍßÍËû°8[AêùeûlàÃ.µ¿bü£Ùm°`„e```````à{Ø{¸Œ‡°n@éáBÙêVÿæ4º{· ü©ˆ‡°nAîá^³w<„u ž=ÜsíýßÂúÓi/”åVó3IEND®B`‚snd-16.1/pix/sceq15.png0000644000076400007640000012133111215702607012744 0ustar bilbil‰PNG  IHDR\8©ùƪsRGB®Îé pHYs  šœtIMEÙ *KYîƒ IDATxÚì}|ø/ºª¶¶ööíÛa•AÆOžŸÏf³ …oß¾E œwïÞíÚµëýû÷B¡ÐÃÃc¼ïÈ‘##<ªªª«W¯^½zuÿþýçÏŸG?³X,t}GGG¥”“Ïçoß¾}´kcÁ‚L&StIBBÂíÛ·?ÖÕù»û@$ÑXH Ðf ¥´´T]]Ý‚N§³Ùì5kÖì¿ÕÕÕmmmS§NÕÑÑÑÕÕ­®®ž;w®¹¹ykk+ÚæÒÔÔ¤Óé–––óçÏ—ÜyyyùÛ·oªªªÞ¼y³nÝ:ѤRûƒR‹½hÑ¢ŽŽ´äS¦L²ØÅÅÅ::: ååË—MMMÓ¦MûÓY´hÚò×ÕÕurrš5kÖ»ÆÅ*,,\¼x1ÎÓW"›6m ܱc‡r+V±îD*MMMïß¿?uêÔåË—õôôÞ¾}{áÂì¿=ª­­Ý°aÃüùóÏŸ?Ïf³¯\¹’””„wýöÛoááá---...þþþ555b;ÏÈÈ ‘H{÷îåp8QQQ©©©Ê*¤œþ X±ÑÒ¢%²ØÁÁÁþù'‘H´µµõôôü¸§ƒ³{;¼‹UPP°lÙ2<§¯\ttt:;;•[±0((‡’’{{{&“éââbdddccsýúuì¿ùùù‚Ì™3gÇŽ¦¦¦¶¶¶è¿(Š­­-Ç[½z5‰DZ¾|yAAèžûûûy<ž¹¹9™Lîîî¶±±ùî»ï\]]•UHSSÓ°°0€¯¯¯›››¬b°’Y캺:KKËúúú•+W.\¸pÚ´i ÷tf̘!:¬¨®®¾eË–êê꯾ú {%1ì‹ÕÒÒb``0äéB¡P (±b{ûP__onnŽ È’%K(ŠÔòq8œÞÞÞæææîîntallìîÝ»U;(xzz¾}ûv``àÓO?ÔÔÔ¨««cÿ ܺuë‰'ìííüñG´ó…ý—@ a½3'ºç©S§~ñŶaÃÀÊ•+ÅŽ)Ù¾@§OŸ–_H9ýAÉb‹–\~±¿úê«ÆÆF}}}ô¹]PP`mmçt:;;EYT*õèÑ£Ø?®­­=¼ÓqvvÆs)‡w±8ަ¦æ§?Œ«6$\.Ï}2*AÁÌÌìûï¿?wî\ll¬œ1AZ[[SSS/\¸±k×.<}›üüüðððÄÄĉrss×­[‡~ÎÌÌ}Ü××WTTôúõë‡nß¾½¢¢Bl[<•C¥RÑ6<ÚgýWHHÈÈ )‰d±ÅÊ)¿ØT*{cŸ””äáá!ZrY§£¯¯öìYìëÑ£GE¿Žätp2¼‹¥­­Íf³ñŸ¾BWM>ƒƒƒZZZxî“Ñê>œ>}zÕªUÍÍÍAAAr¦H„yóæWVVZYYåååá9Æœ9s,X0A ÙÙÙhc•Ãá<|øðÛo¿ÅþÇb± ìììø|¾hÕÉúŒ Q©ÔþþþÒÒR´×šžž>…”D²Ø¢%”_l@NNú«@äþýû[¶lÉÊÊúˆ§ƒ“á]¬O?ýTìí©ÔÓù@©-555åV¬-´wîܱ²²JLLŒŽŽÞ¿¿üÍH$RtttTTÔÚµkñ< ×­[×ÞÞÞÐаvíÚQ8U:T*uîܹ #!!áêÕ«úúú¢cZ±±±ëׯïîî¶µµ-..~üø±@ puue³ÙÙÙÙ|>?77—Ëå>þ¼¥¥ÅÆÆë §¦¦ª©©µ´´øùùåççwvv®Y³f4 )u(N´ØùùùhɧM›&¿Ø€¢¢¢ÈÈHôó¢E‹ètú¼yó>âéàdxkÍš5qqq>>>òO$áïÅ‹½½½‘‘‘ÖÖÖ~~~èò®®.¥ß' D)Œ¸¸8€––VEEη¸xVó÷÷g0ûöíãr¹²V»~ýzUUþÈaaa†††rv8rzzzÌÍÍ…BaKK‹äÉ  ÿFfº!Ç …­­­ƒƒƒ£THIFRlôpØçþþ~ô«¢§sìØ1eN†wÖB¡ÐÛÛ[(Ê?}¥“‘‘¡Üû?@ì;šÚlaaÑß߯”…B‡³gÏ~øðAþšÞÞÞ‰‰‰ø÷\VV¶nݺQ­äää½{÷Žó<¥ QHÉŸèD9¸¸¸ììì±<¢@ 8pà€h$cÄ_I^¼xqñâÅ•••‡RÖ«~;;;77·sçÎ566ÊY3>>^¡·¾T*ÕÉÉiôÚP•••êêêÅÅÅã¶w3! ) ™Lž(§ãíí——×ßß?fG¼uëVhhèGìe¤Ž­\¹’Ëå&$$xyy)´;É\´ëׯϙ3ÇÊÊêòåËk׮ݴi¶òÓ===CBBœœœjkk»ººìííÁ˜ç~A&\.—Á`ØÙÙÁ±Þ½{×ÔÔ4ä¶±SÀ@§£ëè舥dˇÉdÒh4¨¨¨W¯^Ý¿?<<íË!Âb±¶òÇïÝ»‡ H{{{PPPccãöíÛþùgAjkk½¼¼‚ƒƒóòò8Îúõë«««%›X†††l6;++«¬¬ÌÚÚº±±ñÁƒ555<ð÷÷/))ñññIIIÝŠÃá”Ë ¢¢B‰=Xdâ¢.5Rìß¿?333))É××—F£‰fìÈ¡¤¤ÄÃÃãàÁƒh.šššÚñãDZ÷I:::bÉ bf\.üo†Y}}ýêÕ«h†ÙÂ… ÅÚ™ %//B¡GDDÌž=»¢¢ÂÜܼ½½ËýÍQ ¼xñBVùMMM§L™"º¤··Wtú2N@3»F÷•¤d>µk×ŠŠŠ‚P(Ĺ/ùùbŒ$Pàp84 ¯‚ö†Ìýš1cöÖõõõr‚ò±Ø·oßXôM©žž^JJŠhšçàÏEa: •J={ö,…Bqvv~ùò%ž¤:ô¤"""dÅÁ#GŽ`ɶ(¶¶¶X†<2IzzzüüünÞ¼9{öl…v'–‹ö×_ÉZ3..îàÁƒh†Ù³gÏJ …ÏŸ?·³³#‘H¨x\VV–™™YOOÏÊ•+Es¿ÄôãôôôÐy5Òë_/ 2¡AäÑ£GÝÝÝd2ÙÃÃV® Àår½½½þùg±™äxÀŸ‹6’tÀÚÚZsss‰°³³ËËË300À™ûù“œ””SSSWW×={öLŸ>ýãª!ŽOÄ_I"²gÏ{{û   E÷ÕÛÛ»zõêêêêÖÖÖ¹sçÊW°b³ÙZZZ­­­Ó¦MSTÖE ôõõ¡#—ƒƒƒ,KOO¬e``@$ÛÚÚôôô ½¨øß°LIIikk355ýâ‹/ÔÔ&ötûÔÔT‡ƒ>ö¦L™rðàA¤´¦D9sæÌáÇq¾º())™è©uªJZZZDDÄÌ™3z©,5!5<<}|âÄ ±œßñÀ«W¯†—5èææ6¼mUžDýøøxƒ!gN«( 999Ø× šZ§ª¸»»‡„„Œ\YN§777OŸ>]MMíäÉ“iii c\)êK (ÑÑÑgΜÁÞpA¤)\ºt)##cÈö!ú Ú¿ÿÓ§O±…—/_†ªbH$:.ÔÕÕ555µµµ»ººÀPÒ•åååõõõ¦¦¦VVVè’²²²¶¶¶¹sçZZZb«‰IEŠn®¬´T©åDß‹™™™1 I•Èß¿ÿ¦¦&??¿S§N1™Ì ÊËËétú“'O®_¿~øða ‹/¿üÒÜÜ|T3( ã¥K—æææ¢£³555¨f™|éʰ°0:¾uëÖÞÞ^T½.,,ŒÅbmÞ¼¹¯¯{û#)‰¢DIB©åÌÊÊ Ý³gà Rû>|X²d‰¢ÆÄÄÀÞ×8GR;|$ƒ ^^^iii‚$&& …Bkk놆A^¿~mii‰®F§ÓW¬X~þã?Ž;F£ÑvìØíÇÏÏJ¥"våÊt„âÉ“'èûúúRSS¡R©_|ñ‚ ÏŸ?GÍd!G-^N9!C¤9“ÉdÑÑœ@%ø‰Ë0tÃÃÃ}}}ÝÝÝÜÔÕÌÌÌ¥K—¢ŸýýýÇGõBPLLL'''*• «QåFAêëë>||åÊöÂLÆ  ªÅîïïÏãñrssÅÖÞ¶m›˜Ô"QÙ ““³aÃ==="‘ØÐаiÓ&1­T>ŸŸžžÞÑÑ‘œœììì,êö @TjLU=!ïÞ½›6mÚD×Ò€@ # `š3AÀ @`P€@ 0(@ X,jK @`P€³$!ÉX,ÖãÇûûûóòòJKKålgIB “"(UTTܸqcõêÕ¢zÛd²õšÿžû°jÕª[·n¡f;¨Ìæ‡âããEWÕÖÖ3q†@T˜'Ož¬X±݃õš80Y‚´iÓPÙÜçÏŸ¯X±‚ÉdšššÂ;"ú¨,))±³³+--:uêòåËUû¤z{{1eêÑë5÷öö–——;::Žö™¾{÷®¨¨žõß݇††sss@]]‰‰ÉÛ·oemÀçóïÝ»‡Î’|ÿþý¤úUP©T‹5iƒ‚Jö1?îIñùü‹/ÚÛÛÁ«££Ãår%õ¤€J5òù|Ô‡G(Š iB”kâ<¡y÷îÝ®]»Þ¿/ =<<Æa ‡á"-yRUUUW¯^½zõêþýûÏŸ?~f±X‚8::*·À‘‘‘¥¥¥cyÇ8p€Ëåí ‰¨²%@€ÖO’ ÎHÿþ÷¿'s%HícŽ«^ºt §gºœ“Z´hêv«««ëää4z>IàÙ³g_ýõXÞ±6løŸÿùŸ;v Ý}€Œ¥¥¥•••:þìÙ3±©ëåååÉÉÉ/^¼À–”••edd”••aKª««Ÿ¿f¥”S*#,üW_}ÕØØ¨¯¯¶ä ¬­­ñœ~j0:&Ô#9q‡ƒzíÊ©a_A9hhhp¹Ü)S¦Èª^u€™™Ù÷ßîܹþþþØØX9‚´¶¶¦¦¦^¸p!""b×®]¢NÁ²Àc<5¡QÈÄy„~ÍòÍš\¿f¥”S*#/<•JÅÞÕ'%%yxxˆ–_ÖI)ä@ FÁ„z$'®­­Íf³E/œœÆ”Åàà Ú8’yÏ`V«V­xyy …Â!_xp8œ€€ÔHjHþøã´´´¶¶¶ÜÜ\<;·|úé§#%ùÍ7ßDEE!Âf³mllÐV%‚ L&“B¡`î‰=*//ß°a¶¡‹‹KiiiXXöÎ8 [¿¬¬,;;»¯¯oæÌ™A;wîŒF9¥2ÂÂ#²k×®¿þú })njjÚ××—””¤èI9rD‰'…‡‘œø¯¿þ'¿FãŽÅ^¬Êª^":B$cbb †ÁŠ+äuuõÏ?ÿüþýû¶¶¶xZ×›6m¼zõª«««²\ýÁéÓ§ýüü¾þúëÑv ÌÎÎNIIÉÈÈàñxoÞ¼A}“‡Ç±cÇ.\8eÊ”¨¨¨£Gbý5]]]ccãèèè™3g/]º”D"=zôˆD"ÅÇÇÛÛÛoܸññãǵµµd2¹²²’L&cõíڵׯ_·¶¶Îž={úôéÅÅÅ«V­‰I‡¬rJe„…G[Ýÿõ_ÿE"‘Ða933³™3gþõ×_ TVV–ü‡¿B'…‡‘œ¸†††h¥ÖÀܹs•{ÇvuumݺUÞ=#BâââZZZxâ'_¡PèààpöìÙ>(ýÑ]VV¶nݺIå×,Õ¬yx~Í#)§T†]xôˆØçþþ~ô«¢'%ÇzTM¨‡wâB¡ÐÛÛk;K­¥“‘‘!ÿžbÛ ó,,,úûû•RˆÆÆÆÃ‡—––ž8q¢¡¡A¹gqêÔ© ’““÷îÝ Ë9J L¬“Š‹‹ËÎγà ‚ Ù…%yñâÅÅ‹WVV:tH)É!bÆSJLwAHÖ¯_¨­­}úôéh¤»(‘‰âƒ|xïÞ=AÚÛÛƒ‚‚Äž¡¡!›ÍÎÊÊ*++³¶¶nllDäÁƒ555<ð÷÷/))ñññIII%-—AEE…r–Ècöùùùcp ‹õâÅ x¯@& D"ÈêWTWWöÙg]]]£”ñ2Ât@`ddÄáp™7o‚ h¦Îtžl`/2Éù;yIŒžž›7oΟ?”2^F˜îRSSSXXÈÏÏ744œ>}º‘‘Î5ÙÀgDl$þÑ£G………õõõ¢3Uüœ%‡C7lØ™™9/ÃNwáóù¨‚ \.·³³s4rx&ÙÙÙ#×Ýâr¹ñññ.\HII{ß4IJJb0‚ìÞ½{?ЉˆšdŒØ·oßöíÛ‡1W„F£988„yóæáÌ;ÖÐÐ066ÕÃ[‚¾¼˜7ožØ4-"‘ˆ=ÿ555õôô°Ayóæ©««CCCèO“ôôôÈÈH//¯ŠP"réÒ%WW×ÐÐÐâââ;vŒ“$ŒÖÖVEûصµµ€… ¢98*xPøé§Ÿôõõƒ‚‚ðlL§Ó±Ï7ãpww ¹Nonnž>}ºššÚÉ“'ÓÒÒ Ƹ:SÔÇ?_~ù%šŒœ››;JÂ'ã¼}ˆg0wïÞų%šG€)ÕXXX\¾|þº&9$‰N§ uuuMMMmmí®®.@ii©ººº……Ng³Ùk֬ͫ+//¯¯¯755µ²²Â–••µµµÍ;›ÌS]]ÝÖÖ6uêTTFQtoß¾upp¨ªªzóæÍºuëðLê—DV9£££Ïœ9cdd4¹Z —.]º~ýúƒm‚Ü¿ßÁÁaË–-ðgeéÒ¥¹¹¹h~JMM Ç[½zµ¢"tà#éÐÉ*'úrÝÆÆf¼µzF·¥ÐÔÔäççÅd2¥FÇb±^½zUQQ‘žž^UUåèèˆ&)A Rï™'NܼySGG'++ËÃÃãàÁƒhª«ššÚñãÇ¿ýö[𿉭EEE€ææfT¹ÍmEcÁš5k¢¢¢ÐÜVD¶]{{;–Êi*DII‰d9---CCCgΜÉçóÅÒçT9(ôõõ¹»»744¸¸¸àßrÏž=ðÖŸ<(*îëë‹ +$B‡>ù•¨C‡_²Mj97nÜXUU5©®µ:€L&çää(º%´‡˜T($v÷î]kkkggg>ŸßÖÖfllŒ_„([‡N!É6¥ëµMÔf‚¢½¹œœ*•ÊãñsssQÁü"t‚Œª|É6¥ëµMDÔá3ÈÎÎ~ñâEooodd¤µµµBÆD©©©qssø{[M ýL¥RçÎË`0®^½ª¯¯u ~ùå—Çïܹ³­­ ø]ºtiPPÐùó眜h4Úž={,--bccׯ_ßÝÝmkk‹e ¤¦¦ª©©µ´´øùùåççwvv®Y³fØõ «œ°¥(“aˆÐ!£¦C'G²môôÚ&Ñ„3œ Ož<ÑÐÐNNNð ’”””´´´k×®‡Â°ÙlYM㪜‘¤$à1hxþüy]]ƒƒCYY™¨h"•ñ–ê*+"À”\Œ´bbbôôôlllÖ®]+5'ìøñã®®®ëÖ­ËÌÌ,,,||åÊ–Uò ÔÕQ-&¡P8r+>2~ƒBSS“››Û¹sçüýýy<^nn®ØÚÛ¶m³°°xûö- §§GlR Q©  fаiÓ¦… Jn°sçÎóçÏ;::9rÖ ¢büß@#›ÍÖÒÒ"ïÞ½›6mšœ¹’l6ûåË—K–,‘ã½@&|P€@  ©¼@`P€@   ¢¼ ÐÔÔƒ)pÕÕÕ%''·´´À*ƒ@TéyÊííí………NNNGݼyóìÙ³555·nÝúìÙ32™<{ölXqˆª"=OáÙ³gk×®p¹\ggçÏ?ÿÓºÌËˉ² ™¨ÝtÖ“¦¦ææÍ›oß¾ÝÞÞŽÆXe‘7nTWWÃz€|„îÃgŸ}–˜˜h``PVVæçççææ¶wï^ww÷ÁÁÁ¯¿þÖÚÇ"==}êÔ©pä#tЖBOOϬY³P©¡PøæÍ==½á¹qA  cƒ“E1ëÄŽŽŽêêê¹sçš››·¶¶ÖÕÕ™˜˜hjjÒétKKËùóç‹íYYöŠ8¦;ä=Ô:< IDAT˜,JZ'²Ùì+W®$%%¡Ÿûí·ððð––1û&eÙ+B`P€Œ)%%%öööL&5/´±±ÁVóóóQ'Ì:ÑÔÔÔÖÖý/…B±µµEí[I$ÒòåËEµó0{E2™ŒÙ+ºººÂ ‡àAP__onnŽ È’%K(ŠÔñ‡ÓÛÛÛÜÜÜÝÝ.ŒÝ½{7¬Á‘ Çd100PÒ:Q´ýO 0gt"‘Èãñ° i¯ ÌÌ̾ÿþûsçÎõ÷÷ÇÆÆÊ1‰D¤µµ555õÂ… »víÂÓMÅi'19‘e^8¤u¢XŒŠ,{EdèîÃéÓ§W­ZÕÜÜ$gè‘@ Ì›7/88¸²²ÒÊÊ*//Ï1ðØILZ²³³mllçáǨA; ..ŽÅbØÙÙñù|4(‹h©ŸåååT*µ¿¿¿´´5eOOO‡U Q ¥ÐÐиs玕•UbbbttôþýûåoF"‘¢£££¢¢ÐÄÇ!ŸWëÖ­koo—c'1i‘e^ÈçóŬóóó?~,\]]Ùlvvv6ŸÏÏÍÍår¹ÏŸ?oii±±±Aã‹rí!“Q¹¸¸8€––ê<$8ýöüýý FEEž}û¸\®¬Õ®_¿^UU…ÓîŽÏ燅…ÊÙá„6Y”eˆEí!QþñöÁÇÇ'00Ãáøøø`ÆÁr ‰x‚j'1þü+W® F2RIOO¯¬¬ÄˈD¢‡‡Ç‚ äìpüC£ÑÐN™Xe’Édt¹œ!ù½þÜÎÎŽD"õõõ²²²ÌÌÌzzzV®\)šÆ·}ûvÑ õôôÂÂÂdÖ…ìv 2©ƒ—ËõööþùçŸÑ–¹BÈÊÏ“D,c¯¸¸gº ¶¶ÖÜÜœD"ìììòòò p¦ñÁ_¾‡¨=zÔÝÝM&“=<<`…¨Ô¥K†ÛµkWtt´róó$IÆŸÏg±Xèg.—ÛÙÙ9Úi|ÙÙÙÃ(§\.7>>þÂ… )))¢/b&(III AÝ»wgffÂA{•}ûðÓO?éëëá (t:]ô«œü`U†ÿë`\ºt)##C4›@VIKKÛ¿ÿÓ§O±…—/_†AV$‰N§ uuuMMMmmí®®. W£P^^^__ojjjee…-,++kkk›;w®¥¥%ºDLÍQô¸ÊJñ”UÎèèè3gÎ`ï!*Àß¿ÿ¦¦&??¿S§N1™Ì ÊËËétú“'O®_¿~øða ‹/¿üÒÜÜÍG€àaéÒ¥¹¹¹è0gMM šš%G£F§Ó·nÝÚÛÛ‹É´………±X¬Í›7÷õõ¡oR$Õ1”¥Ô(«œè[gƒ/±Ju>|ø°dÉE7Œ‰‰™< ª‘wD‡r½¼¼ÒÒÒILL …ÖÖÖ ‚¼~ýÚÒÒ]N§¯X±ýüÇ;v A†F øùùQ©Ô°°°+W® “'Ož`ÿíëëKMME„J¥~ñÅ‚<þœÍf£û µœ™™™‹-Z»víªU«222`«[¥ºd29''GÑ 0ŒB•$22RLIeÆŒ§OŸ–\îëëëîî俀fff.]ºýìïï=ùMLL°]™˜˜¿­­ÍØØXV(‰DÛ\SSMÖBáñxèùj޲R<õõõÏž=‹}=zô¨èW1ðçªBTdL2d'kä;¡ÑhúúúŽŽŽ<¯  àÇ@¶Fã–-[ŠŠŠ°I™™™è[ô50ƒÁðòò’ªæ”­Ô(«œÕl)@äÿ^¼xÑÛÛimm­Ð|*QjjjÜÜÜ0=+555ô³¬P“_~ùåðáÃ;wîlkkC•o—.]tþüy'''¶gÏKKË„„15GtÊUjÄŸ« Q…g F^^ž§§çãoß¾ýí·ßàxÌÈ2tpp°¹¹Y,;Sl¡¬ÜPES<ѱ̑çªBT*£;›Íf0·nÝ‚ñT) ù9 ÆÆÆbÙ™b eå†*šâyòäÉa—¢²c ˜ûÓ§Oeõ¢Édòúõë¡èÈod2yB”2ÚüC£1 44TCC#"""$$DRïÈÛÛ{úôé'''*• «QåF䵨ƒƒƒ¯\¹‚kÁ ‚@&oPÕb÷÷÷çñx¹¹¹bkoÛ¶ ›ž@T<(ääälذAOOH$644lÚ´iáÂ…’ðùüôôôŽŽŽäädggg´7@TpLÍfkii„wïÞM›6mȹ’DŃ˜æ @`P€@ 0(@   d4ƒBSSSLL ¦)TWW—œœÜÒÒ« Qm¤ë)´··:99=ztóæÍ³gÏÖÔÔܺuë³gÏÈd²¢^rd!=OáÙ³gk×®p¹\ggçÏ?ÿSïËËˉV™¨ÝÔ^SSsóæÍ·oßnooGc¬2d2¶8NjjªAYY™»»{OOÏÉ“'ÝÝÝ¿þúk(¦ T*ÕÊÊ Š_C&vP@[ ===³fÍB¥…Bá›7oôôô†ç/49IOOollüñÇ‹‹‹E¥Ù!  ÊÂÌÌ,++ ÈDª9O &Šå$D€ÉK€‰b9 A2F”””ØÛÛ3™L###ìÇÏ`0ÒÓÓwïÞM š››Ñd³ÜÜÜÚÚZÔÐiÍš5 999ùùù‚Ì™3gÇŽØÎûûûy<ž¹¹9™Lîîî¶±±ùî»ï\]]aµOêîC}}½¹¹9‚ K–,¡P(’+ …B‡ÓÛÛÛÜÜÜÝÝ.ŒÝ½{7žcäç燇‡'&&Âê§åǵœ„LÆ `fföý÷ߟ;w®¿¿?66VÎË3AZ[[SSS/\¸±k×.<=O”Ñr2éÀL‡V­ZðòòBMÍåÃápP{ˆ!ùã?ÒÒÒÚÚÚrssñì\ÅøôÓOGncÿÍ7ßDEE!Âf³mllÐŽ‚ L&“B¡`îO=B¤¼¼|Æ ض...¥¥¥aaa˜…T@@¶IYYYvvv__ßÌ™3‚ wîÜ.I“": E$cbb †ÁŠ+†h`¨«þùç÷ïß·µµÅÓHÞ´iÓàààÕ«W]]]•e1$NŸ>íçç÷õ×_OÛ¢ììì”””ŒŒ ÷æÍì-À08vìØÂ… §L™uôèQ¬—§««kll=sæÌââbccc======‰ôèÑ#‰ooo¿qãÆÇ×ÖÖ’ÉäÊÊJ2™Œ]¸k×®½~ýºµµuöìÙÓ§O/..^µjÔì†-…¿‰‹‹hiiUTTà‰(xl…B¡ƒƒÃÙ³g?|ø ôVVV¶nÝ:h99––“Éå%éããÈáp|||0d9ày>‹ÚI466*7¢Q©T'''•ÜãÊr¢òˆ¿’¼xñââÅ‹+++:4ŒÝ•––VVVètú³gϳ“[¿¼¼<99ùŋؒ²²²ŒŒŒ²²2lIuuõ“'O «««%ƒÂúõëµµµOŸ>Ý-FCäåË—999:kZ9B>f÷k““H$@BB‚B­&“I£Ñ<<<¢¢¢^½zuÿþýððp´ÕŠ ‹ÅBDZ0~øá‡ØØX¡PøøñãØØXt ú~öìÙ?ü€ ÈÇïÝ»‡ H{{{PPèæÀÐÐÍfgee•••Y[[766"òàÁƒšššøûû—””øøø¤¤¤ˆ’–Ë ¢¢Z­C`÷AœeË–]¼xØÔÔ„?¾HͱA[­Qƒɬ…RnÐG(…BÉËË£P(Ë–-‹ˆˆ011Á“Š300ðB N‡Lr¤Ï}Ø¿fffRR’¯¯/FÃReä#'ÇFɬ›ãÇãO¹Aû‡F£-^¼`ooð¥â̘1ÃÏÏ;wÞ(8ùæ›oÐf&DÕ‚@¸víZQQ@@ÕVp"+ÇFɬESn¨TêÙ³g)г³óË—/ÅRnä¤âtuuEDDÈ:ñ#GŽhkk‹.ܶm¼QpÇ)UsL¥ººú³Ï>ëêêRJŽÔ±¬…Rn‘‘‡ÃAdÞ¼y‚$%%áOÅáÉv)!0y)L2Rôôôxxxܼysþüù …Y96’HfÝ,]ºÊMMMMaaa@@ ??ßÐÐpúôéFFF8SqÔdŸŠ>T=zTXXX__öã *ØRàp86lÈÌÌTzŽ ž¬œ)7|>ŸÅb¡Ÿ¹\nggç¤âdgg‹cp¹Üøøø .¤¤¤ˆ½Ž™ˆ$%%1 AvïÞ=Œ{2Þ> ²oß¾íÛ·ËÅ96R» bY78SnˆD"öü×ÔÔÔÓÓÃF#'===22ÒËË‹Åb0_ºtÉÕÕ544´¸¸xÇŽã*‡¢µµUÑMˆDbmm-`áÂ…hŠ d¢#~úé'}}ý   <Óétì³jçØ¸»»‡„„Œ\|•N§777OŸ>]MMíäÉ“iii cüœæ¥K—ÝäË/¿ôöö …¹¹¹žžžð¥joâãã ÆÝ»wñl‰æØØØ _-,,._¾ +T>$‰N§ uuuMMMmmí®®. ¸ÚÚÇ’Z“UÎèèè3gÎÁK¬R-…‚‚‚K—.]¿~}ÈÁ6Aîß¿ïàà°eËXƒ ±téÒÜÜ\4}£¦¦†Çã­^½ZQµµ%µ&«œè»g›qÕꌴ¥ÐÔÔäççÅd2¥FÇb±^½zUQQ‘žž^UUåèèˆ&)A†7¸pâĉ›7oêèèdeeyxxœªj¢„‡‡ûúúº»»ÕÖÊû2¿³³³S´UB¥R1@püøqÑ<.©åܸqcUU¼T-(É䜜E·„–GøUÕPîÞ½kmmíììÌçóÛÚÚŒñ«­)WjM__ÿìÙ³Ø×£GŠ~•Æ*db"‘8kÖ,XxÚü#ß FÓ××_»v-Ç+,,œ1c ;;²åp8>ü믿Е·lÙò믿òx<ôÝjff¦§§çÁƒ±½1Œ_~ù%..îàÁƒ†††Ïž=ãóùèúååå===+W®,--E{ éééÛ·ováe•¢‚c ! /^¼èí파´¶¶Vh>•(555nnn˜€ššú™J¥Î;—Á`$$$\½zU__ëüòË/‡Þ¹sg[[Û‚ –.]tþüy'''¶gÏKKË„„„ØØØõë×wwwÛÚÚbÙ©©©jjj---~~~ùùù#t —UNˆª=ý Nmm”¤ÖŽ;¦ÜŒUÈDä^’8 ž>>&&&µµµUUUÆÆÆèòòòòššcc㪪ª—/_Ο?Øî‰Éš=kѪæóù Õóä¬O8¦ ¤Ú ŠMÊÆV–t@d³ÙW®\IJJB?ÿöÛoááá---...þþþb.LB¡°°°ÐÎÎîñãÇ\.744õ¼S¢{âB¾!¥XU+TÏ“³>aPP%%%öööL&µ´±±¹~ýº««ëœ9s:äì쌭œŸŸßÑÑ!ê€hjjjkk‹þ—B¡ØÚÚ¢¬$iùòåbòp••• %//B¡,[¶,""ÂÄÄsO$“ɘ{¢«««Ê_H©5/«ªñ×ó¤­ÏÉŒ: ¾¾ÞÜÜA%K–P(©ã §···¹¹¹»»]»{÷n±5¥Ú b² :::¢+J: жK ænN$y<žèæT*•ÃáÐh´Å‹ìíí÷DUEŽ!¥ÔªÆYÏ“¶>'{P033ûþûïÏ;×ßß+Ç$AÖÖÖÔÔÔ .DDDìÚµK²o‰ßnpHD±{W *•zöìY …âììüòåK1—DYî‰*Œœš—¬jüõ½jÕªæææ   9yaÞ¼yÁÁÁ•••VVVyyy’ëˆÙ ¢–êR‰‹‹c±X¨¢ŸÏÿôk”õm¼<þÜÎÎnîܹ¨ájVV:$F¥RûûûEÝ'ɵ”Só’U³ž's}Nê–@CCãÎ;VVV‰‰‰ÑÑÑû÷ï—¿‰DŠŽŽŽŠŠZ»v­ä#§Ý ŸÏs@ÌÏÏüø±@ puue³ÙÙÙÙ|>?77—Ëå>þ¼¥¥ÅÆÆ½ïkkkÍÍÍI$ÀÎÎ.//ÏÀÀŒ‚{âBNÍ‹Uuqq1ÎzžÌõ9yõ‹‹‹hiiUTTàñœ“4TÈnP–"ÎC³X,ô3—Ëíììž{â$1¤vUOÚúœÌˆÌ,,,úûû‡±»äää½{÷ÂjÅHOO›Áš‡( ñW’/^\¼xqeeå¡C‡mt@»A1˜LæØL6‡5Q"RÒœËËËW®\Éårà|g¬Ož››ûáÇիWÏž=ÐÒÒRWW·hÑ¢îîn@€öÀËËËëëëMMM­¬¬:::—/_¾mÛ6CCCt+Éý´¶¶ÖÕÕ™˜˜hjjÒétKKËùóçà ‡|ü·¢,[¶ìâÅ‹€ÀÀÀ¦¦&•ùä.—Û×ׇÍã”ÜÏ …ÈÇ €ýû÷{xx¼{÷Î××}S¨b ¼ƒÁœ!~ïÞ½ŽŽŽ©S§ººº¢Ã±‹-²±±QSS³´´lkk«¬¬LOOß½{7@hnn®©©Y¶l™±±±™™™½½½¡¡¡¬ý ™¸ Œ1Ò§N„k×®TXååå—.]‡'¹y󿝾úJtÉŒ3üüüðïáéÓ§‰‰‰t:½¡¡}ŠÖªC&“3331?^E÷#'qó—_~©¯¯Ÿ ·—¯¯¯££#ü™©BPtuuéé饤¤àW+X¶ljW=þéêꊈˆ9":Åûýû÷›6múõ×_W¬XÑ×××ÐÐÀårÑŸ4‘HD×!‘Hr´^^¼xaee%g?r > oSÈÇ ===~~~7oÞDÃT===YsÆ¢³zzz+V¬tww#òàÁƒ­[·ŠŽÑnÙ²å×_åñx€ÌÌÌM›6‘H$ô±Ïd2­¬¬ðìºøA>:Rô¸\îÖ­[ÃÂÂV­Z¥Ê£)²[SWW÷Ï?ÿ455mii™2eJZZš™™Ùû÷ïoÞ¼ùêÕ+‰´xñb]]]ccãèèè™3gëééÍš5ëÚµkZZZ&&&R÷Ãf³oܸÁd2MLLêêênß¾ÝÙÙiff†&hB cø+IAöìÙcooôQ $Μ9sõêÕÆÆÆñ£³†ÎÓÕÕ6m›Í&‘HR]¹y<^{{»Ú^ ¼ÿ~Μ9 íG*T*ÕÊÊJÎt5D9ÏK±ï?ýô“¾¾>Έ@§Ó•ßt!=<<,X0®”Ñ™`èì@2™,ë—¬¡¡allŒEÀ”)S°ˆ€?b¤§§GFFzyy±X,xËBÆ4(ÄÇÇ3Œ³gÏâÙ²¡¡!''g4ÊD¥RœœàµÁpww mÈX…‚‚‚K—.]¿~}ÈÇ‚ ÷ïßwppزeË(…õë×jkkŸ>} /’)--­¬¬D[yÏž=“œ(œœüâÅ lIYYYFFFYY™èjÕÕÕOž<),,‰///§Ñh‚¼|ù2''šNì ÐÔÔäççwêÔ)&“)™äW^^N§ÓŸ}Zt‰GÉŒÌãÇ›˜˜`Ûš˜˜›,4iÉÎÎNIIÉÈÈàñxoÞ¼±´´ö®Ž;¶páÂ)S¦DEE=zSô—ÌÈ\ºt)‰Dzôè‰DŠ···G›?®­­%“É•••d2õ¸víÚëׯ[[[gÏž=}úôâââU«V‰)úC&Òó#//ÏÓÓsÈqˆ·oßþöÛo£1Â!Ky2:Ž‚ 677‹ 1J.‘*÷¥UVŽmΜ9è\`9°ÙlƒqëÖ­Qi·‰ØãESSSOOFm%B£ÑЬJl~§(’™’KÈd2ºÑ‘ft‰ºº:@044]2±Ç¨TêºuëÚÛÛŸ>}*«K&“ׯ_¯ú„ê8Bpò9¹¹¹¡¡¡½½½7oÞÔÕÕ•”òööž>}:¬µ‰ˆ……ÅåË—a=@ ‚Ô××?|ø088ÕJÁ^\C ÉšššìììÜÜÜÎ;çïïÏãñrssÅÖÞ¶mR†@&KPÈÉÉÙ°aƒžž‘HlhhØ´iÓÂ… %7àóùéééÉÉÉÎÎΰ7¨ÿ'²Âf³µ´´»wï¦M›†_ü¨fP€@ 0ÞÒœ! ƒAÀ @T8(455ÅÄÄ`:_uuuÉÉÉ---°Ê ÉÚÛÛ œœN:“––Æd2·nÝÚÒÒòæÍ›a&??Õí@ 2(466úøø˜ššÞ¸qã÷߯¨¨pqq!öööuuuÃ8 ¥2®»B¡ ©©¹yóæÛ·o···¸\îðƒG©a‚üÑÈÈHŽ ùä“O>÷D¥‚BOOŸŸßÍ›7gÏž >€üüüÇóù|{{{55µììl>ŸŸ››ËårŸ?ÞÒÒbccccc£ÐÑÁ;w***à]ˆ]]Ý£GÂz¤¼}àr¹ÿñÿqìØ±ÕgΜ¹zõjcc£ K*ݹsç“O>quu…w!d\·Ù·oßöíÛ?âèÀdY …™™™¿ÿþ;¼eN‡éîî&“ɰBÆ ñ䥟~úI__?((ÏÆt:}”ŠE¥RœœT¸Þïß¿ÿùçŸCÛnò’’‚&ƒ¤¦¦feeÁ ù8A!>>žÁ`œ={Ï– 999£¤Š¬©Ì30%%eëÖ­b§¿­­ÍØØXޏöÈÕ´±_»TÕl}}}ёţGÊhÄ/‹1Œüü|<ª*,+**j” $Kdm"œ˜˜ØÙÙ‰~ýõ×_ƒƒƒåôãFx8¦¯¯ïèèÈãñ б˜ììlô‡Ãyøðá·ß~‹­¿eË–¢¢"lÞwff¦§§§hBƒÁðòòŠ‹‹c±X†††vvv|>b¤R©ýýý¥¥¥Ë–-¤§§»ðrÊ ù˜-…9sæ,X°@þl6›Á`ܺuëÀ°úä³`Á‚7^¹råÔ©SL&SGGgÆŒR/^¼èí파´¶¶ÞnMM››¦¬©¦¦†~¦R©sçÎe0 W¯^Õ××mÎüòË/‡Þ¹sg[[Û‚ –.]tþüy'''¶gÏKKË„„„ØØØõë×wwwÛÚÚbš—©©©jjj---~~~ùùùkÖ¬É責rB>æ@ãü‘––ÖÖÖ†ú¯ÉŠptt„ã18ó”æÌ™Ãår:ÔÞÞ>ÆGÇ#®=l5mEU³;6’rB>Î@cnnnhhhooïÍ›7uuu Ä"ˆ··÷ôéÓa$ÅÏÆuuu###ÕÔÔæÌ™3ÆG×–µª-g êú'¹ÑÝY˜“'OޤœÐ}@¤¾¾þáÇÁÁÁW®\`CÓaC BBB:„¦ñ%¢âÚCºûŒ˜¥è8/'äÿô˜LfTT”ŸŸ_BB‚¿¿?ÇËÍÍ[{Û¶mè( ““•J…Õ‡‡¾¾¾k×®}óÍ7°* ¬¥““³aÃ==="‘ØÐаiÓ&© Å|>?==½££#99ÙÙÙö&†D[[FÈ„l)°Ùl---ðîÝ»iÓ¦AC$d²’ÊKAÀ @`P€@ Ê MMM111ØLþºººäää––XeÈd ííí………NNN§NЉ‰IKKc2™[·nmiiyóæ¢Ç@äáÇþù'&”0æhC ‚Bcc£©©é7~ÿý÷ŠŠ `oo_WW§è1$]=š£­Ä³ííí=¯Š!y÷î45Làîê&¢©©¹yóæÛ·o···¸\î0Ž!éêA¥R×­[×ÞÞþôéSYÙSd2yýúõØì}9ܸq£ººzÈÕø|þÅ‹1mh©Ö)àÇ422“$6¢/:::\.WrFÉè1rƒ™Qbä¾58/:d8HPÍf³ãããi4Ú¥K—˜Lfqq±››Û¥K—Ο??ä´y<®þþþ £¢¢bß¾}\.w„ ÞÞÞ‰‰‰C®YZZ:¤uJYYÙºuëF>)]–ÅË䟲RPŠÁÌ(¡ßœ2 €œßpWWvµAGGÇHL‡¢¢¢JJJÐ{ÂÁÁáìÙ³>|@äýû÷WÿÉ;w”®æÂçó·oߎ}-.. EO‡ËåN™2-‚ §NRVýJj4'$$ܾ}{l®®²¢•‹œÊ‡Œk5g55µÙ³g‹~Å©5¤«‡®®®››Û¹sçüýý?ýôÓÀÀ@…Z7¢Þ$ºººÕÕÕsçÎ577omm­««311ÑÔÔ¤Óé–––óçÏG7),,D­ePdY§ MnT+µ¶¶¶««KéV4›6m ܱcúUYf*ˆaøÖˆ¹Ñtttà¹è“°’GeLaxàqõ›£-gàÞ½{èí÷ïßcËżIØlö•+WÐ÷l6û·ß~ oiiqqqñ÷÷Ç^© â¢(R­SБ”ÂÂB;;»Çs¹ÜÐÐP©>z#AGG“rU–™ÊÄBQßI7œ}2WòHP²Ä{II‰‡‡ÇÁƒ]\\ŒŒŒÔÔÔŽ?^ZZZUU%úZ£}èÐ!QEpñ’©«oÙ²eË–-bËóóó ™3gÎŽ;LMMmmmÑP …bkk[__þ—/_^PP€ªB´´´H•Eäĉ7oÞDÅcÆÆÆR( ‡ÃãñÌÍÍÛÛÛ»»»mll¾ûî;ÑÈ5Ƴ°ÊÏÊÊ’¼sPMg±+ÀyÑýýý“¼’‡êëëÍÍÍY²d …B‘zs8œÞÞÞæææîîntallìîÝ»ÅÖÄãêÉraRî (æM"Ú$˜)‘HÄôË9ަ¦¦äÞD­SKE­Y¤¢¡¡Áår‡4SQypúÖH^qœàp¬H fffßÿý¹sçúûûcccuuuå„öÖÖÖÔÔÔ .DDDìÚµK²o6Ú®’Þ$b+Hí.jkk³Ùl±…’Ö)ÿ¿½3kêJÿ K ‚£E@¡¸#­ˆ âêH]-¯‚ŠÖ¡¥íÛŸ£Vlqôu™â S*c(. È&¼‚€„D6 »ì›È&b% YîïóÎÛl„¶p¾%7w9ç¹7Ï}Îsžó< Œ¥………³³see¥Hud„¥YdLÈiiiá'%SQmä¯[3l5i7]dvv yT>…‹/®[·®¹¹Ù××WFÚo×Ïϯ¢¢ÂÚÚšN§‹ï3ÖU=Äk“à,í³¹¹ykk+þ<â¥S„Ba~~¾‘‘(”4úX#‰ÂÔÔÔTSSSn1ù¯>Q݉Õhä¹éˆ²+ÖL/Ÿ‚¦¦æƒ¬­­cccÃÂÂNœ8!û0‰ºqãFq•<¦U=ø|>¾6Iaaaff¦@ رc›ÍÎÊÊâóù4Ëåæçç·´´ØØØØØØlذ!::zÿþýà$K§(·Œ¥´/]]]ÀO¡Üb*r^}20Òº5"w\SS“Á`ÈsÓÇZȪììÁˆŽŽFDKK«¼¼\ÎÉÿñ¯ê!­6ɰ3ÃÉðù|‹>s¹ÜÎÎαhxxxjjªÅTTOŽbw\±Š5 ÁK d`ùòå œ.>>þèÑ£“³«ÑÑÑYYYÛ@pòäÉÑÄ€M8)))cqÚÉüäL7Dãnܸ±téÒŠŠŠo¿ýv¤F¾ªÇ$´‰<<<ètúÀÀÀ¶áîÝ»þþþS7r¦±±q,–ÏOò'gº!!›sYYÙÚµk¹\î£GäYà<…àr¹L&ÓÎÎnB®ÞÛÛÛÔÔ´zõê —÷õõ­_¿Ä­¶´´ÔÖÖZYYuww 0 C]]™™™µµuGGDZcÇV¯^½oß>ccãyóæ‰ŸGžøBÈÔ˜}À³råÊ7n rìØ±¦¦&Uê-‰Dš(€ ˆžžžbËå–K¡¢¢B Œô„W®\±±±qvv>rä»üÛßþL œÁ"ÑÀÀÀ¢¢"ww÷žžžÈÈÈ·oßþáàr¹ýýý`ñó _™’JA'NìÞ½»··÷àÁƒ`2 KÉd*°žÄÏœ9sÇŽÀ»leeecc£¦¦¶jÕª¶¶6"‘Èd2SRR>L š››«««W®\ibb²dÉ{{{PQVü< ¾D.“H$_ïàÔBr˜3@¸sçNAA@¹{UUUDD”é(ñôô´¶¶Æo™={¶üsŠÅÅÅàÿ‰ÇÊÊÊÛÛûúâÅ‹ØØØ¢¢¢úúz0 n:È|BNÓÓÓ± Ã>>>¯%í<Òâ a±XW¯^X kiiÂ'mdJA®®.2™œ 1:X"VVV~¿U’®®®iêûôéÓ:::Økkk"‡¶mÛöüã“O>éïﯯ¯çr¹à/­®®ŽjÉÈ4S\\lnn.í<2<©úúúð!™’JáÝ»w^^^QQQøÕÓ‰‚L&Ëx³‰¯.‘Mjj*™LEß»»»Q}úô©»»»ˆËy×®]ÿøÇ?x<H~•žž¾mÛ6‰Þü555Þ%œŠ¨‹?m\.×ÝÝ=00pݺuP@“Å÷#‘žJ__ÿÞ½{fff---3fÌHNN^²dɇ¢¢¢^¿~M"‘Àb0}}}“°°°9s暘˜Éä¹sçÞ¹sÇÐÐPKKËÚÚZü{ö,//¯®®ŸM2¼àD"À:6Éã+¸\nLLLpppBB‚@ ÀB•˜ï,++K@ºÉ)‘8¿>€xAñ0†††š››ñ€ííí#=Ï„9..ŽÉd¢(zøðáôôt•¤`ðÒåË— |}}åQ(EEE¥ÈnݺµcÇÿÂÂÂ3U]]}÷îÝ‹/–ß"ƒ”””›7oîÝ»wræ>U@>xOÄÂ… ÁbAmmm憦¦¦‰‰ >}îŒ3æÏŸ?ÒóLˆÅ3CFl)DGGïÙ³GN}_WWwýúõÉ–äO¹'mšCK‚8¦BÆg †ŒÌRÈÍͽuëVddä°úEÑ'Ož888ˆ§E°$‚ˆgXtrrB¤¦¦æÅ‹ÓSÑË SRRÌ¢¢¢œœÌ8 »té6K –ÿ snjjÚºukhh¨D‡Š¢<Åb½~ýº¼¼<%%åÕ«W›7o¦P(Þêêêõë×766êéé …B“ºººœœ2™|øðáÇ›™™æüK–,ÉÈÈ‹¤lã/ŸIÛÈÑ ¹©©éõë×7nÜØ¶mÛ§Ÿ~Z\\\SSóßÿýßéééfff cðš5kà^ÞáC__ß²eËFz`xxø„Û9B¡pïÞ½ÉÉÉàkii©££cfffss3Š¢4môë§âðAš|Txø+ ׬YS__¢è›7oV­Z•žžneeµqãÆuëÖåêyÐ."Š©ÉÈÚ6nLH†Å)„ˆ|¦"rÞ2‰)·nÝŠÏ ‘ à¤;wî”kúDeXœºò™Š½ÿ–urÐéƒÚm÷ødXD¦lLžÄ$ˆ“y ;ú“ŒurÐée)LEçÙXgXD&wšCä39›ªD!urÐéÃï’¬0Œ   ØØXÙǰX¬œE?|øðÏßóàÁƒ1R |>ßÓÓsœ RŠW:yôèÑýû÷§b™FyÎvúôé©[çRvãåy¼U¤Œäq…šÚ¼yóð_åL[RR¢¡¡±|ùò¢¢"6›½aÃòðƒê]úúúøÄ æææÇŽ©SVVVWWgfffmm ¶”––¶µµ­Zµ l©ªªjkk›9s¦žžž••‚ yyy N ‚+¸¨¡¡!^”¨©©éêê/*3J¶mÛvìØ±à»óþý{‡W¯^½}ûvÓ¦MA%GàÒÄ.ñ±åí ñûx«@q:%Ç)455}øðá‡~øå—_Èdòû÷ƒ322üýý½½½íì캺ºD7Èü'&&‚Ä >|ÀÿXTTäîîÞÓÓ ¶°X,—þþþÀÀ@Až={VSS³eË–E‹]¿~˜››»råJðyÅŠ4MCCAêêj·~ýzàLÉË˳³³ËÌÌär¹þþþÊ•’žž^gg'ö555•D" =z”Ãᄆ†&%%©ª[N¢Ø%>6£¿ÝJ¯<·Êú”[ÒOdŸÁÁA`=‚åH/QTTôÉ'Ÿ€Ïÿú׿Ξ=K¥R8€íàååE¡Poß¾ .ôüùsðÓ×_Í`0ƹ ¥D“{ãÆ|>EÑþþþ¤¤$E)ÊÎ;QÍÏÏg³Ùª:|(vÍhn·â•Ýxyo>ÔÕÕYZZ¢(ºlÙ2 ‰3§§§§¹¹¹»»lŒˆˆ8|ø°ÈžKú‰O+`/L´Xzz:–<ÒÇÇAsçÎá ›šš>}úô«¯¾rww°··¿páø‰Ãá‰D‘NHAJMMM0¢ž9sæÎ;¡êøQ IDATR©[¶lAdíÚµSë½ÒÙÙ‰±S(”3g΀Ïáܹs:::âGáÅ.ã±ÍíFdXñލñò<Þ*€‚ K–,ùóŸÿ|íÚµˆˆ•cQmmmMJJ  9tèøØl¬Kú‘H$‘ÉB"‘êÄx<ØRPPðæÍ›´´4OOÏòòr ££Ãf³ñÇNTAÊ¡¡!---‘Ù>`÷Š_q’c``põêUìë™3gð_%".viÍhn·<âiã§CÅÊÿó)\¼xqݺuÍÍ;¾¾2r1b~~~ÖÖÖt:]|Ÿ±.é·k×®‚‚‡Ý˜={öa;0™Ì½{÷FGG³X,ccã#GŽØÙÙñù|AÌÍÍ[[[±=ǧ ¥Dyjjj‚„weee e`` ¤¤ø;RRR”;<œlg“XçRÚc3šÛ=â+5°gôÁƒÖÖÖ±±±aaa'NœöuºqãFñø–1-égjjúÓO?:uêóÏ?okk[¼xñŠ+|}}¯_¿îèèH¥R½½½W­ZõèÑ£ˆˆ''§îîn[[[µaÆèèèýû÷#ãRRZ¡Ä®®.ÌNJJRSSkiiñòòb06lPŠ ”[ SYg“VçRÚc3šÛ=â+ñ†èèhA´´´ÊËËåœöÙòîÝ;KKK¡PØÒÒ"þ«jnnÆGR‰lîÌ–––÷ïßã[²£eø|>‹ÅŸ¹\nggçX4><<<55kRKK Ç …­­­ dž0týúu¥ŸùìÙ³#=dØÇF±Û­€xe7~ÜïɼB–/_>00 Àéâãã=:™;••5 'Ožœ a|AAAW®\Qúi§îc#»ñ“ÿñV ¢q 7nÜXºtiEEÅ·ß~;R£cJ”ôóðð ÓéÕ€»wïúûûO†Ø¤1ÊâÍ.MÅÇFFã§OÅJ )ÞËÊÊÖ®]Ëår=z$Ïç)—Ëe2™vvvãéÞÞÞ¦¦¦Õ«WO9ܸqƒÃáœ9s¦µµµ¶¶ÖÔÔ”H$­ZµjÑ¢Edº"¹îÃ/¿üròäI==½ââbüœ0d™´EëÁÊÊJúë˜R¨­­ýþûïÁú_WW×ÐÐP‰õÁ ÓÉ¡'NœHOO‹‹;xð •J•3B,…†2=šššîîîø-ƒƒƒÅÅÅÒö733›1c†Èdf†áää4wî\ñÃ-,,lmmëêê@ ÷êÕ«sssñJ!%%›/€ÈfûöíS½Þª†´—Ï;w ‚ü+Þg̘"½ £Düµ?{öì͉—ù —¹ã ,À®ŽÅLLL”•]Bå™U¥€ HWW™LNHH¿“zzzü1|,Æ‚®®®iÿçÓ§O‹„+`üËð}b«È ÓwøðîÝ;//¯¨¨(üêiÈB&“Ár@ÉwQ¡|¼;IÚgˆßÞÞ^MM-++‹ÏçÓh4.—›ŸŸßÒÒbccây•. ‰7nê’`ff¶cÇooïY³f©Âjñ­‡ ›äñ˜LmjÁb±LLLÊÊÊ&‰4&y:6täÙcbbP½|ùò7T0¢ñÒ¥K§N’óà Ì?5ÉÔ¦QQQëׯ½RP–4&y:6TÑŒlª”£ñw–[LL “ÉvÝ+ ¾¾~¢¥#¸¬^Àß+’LÍÉÉ Aššši>Eš——·víÚIeŸK»q%%% rQQQNNŽˆ_£¬¬,>>?)[ZZšššZZZŠm©ªªzþüy^^^UU•ÈEËÊʨT*Š¢•••ÙÙÙ£qšHkgXXØ¥K—°œ)Í—ÜÜÜ[·nEFFû ¡(úäɇ]»vMT»'0™ÚTÍf·´´L¶$ÕKdžü;±‚ “ÉTGcSS“——Whh¨Ä¿Š¢<Åb½~ýº¼¼<%%åÕ«W›7ož Q (ŠDEEˆ‘ŠŠ :naaabb2m#2÷ìÙ3™YØËÈÈØ½{÷×_½}ûö ¨©©;w¤*`2™)))‚477×ÖÖÒh´šš  6lØšÍ`0 Q?>>#îÀÀdz´´looïîî¶±±ùî»ïža}ùò¥x;W­Zåïï?gÎ>ŸOú4µ•B¿››[}}ýöíÛå?ÒÛÛ{2t`B’©M~ÊÊʬ¬¬”^JG Hu’¤cCF’‘Mb;·nÝúêÕ+Uzh ¢­­­€w`2ÌÒMT2µÉOuuuGGp©444ܿ˖-c7[6R©NžtlÈ3²M‡tlÈÔõ‘fggS(744D£ÑÊËËÁ‚ 8Š¢ .DQ4..n”W177ŸÒ³(ŠZZZ*köA)Ò¿q(Š~óÍ7¡¡¡(вÙl›ŽŽ°scc£……–åÙ³geee[¶lÁζ}ûö’’’ÀÀ@,½Ê‘#G°ýKKK³²²úûûçÌ™R‡ãK )0û ­ª„ÆÔ}NT2µ)DWWWttô»wïîܹãáá1šLd0fqL¯tlSñI¦Q:“'*3#Û4IÇö»ÙGƒ!OV‹: œºº:¶j•H$’Éd2 R© W¸ÄÄššš&&&x¿©Èmmmp¸ˆ« lÔÐÐ ÆÆÆòx^ÏŸ?¯p;Uƒß)…ùóç/^¼Xöl6›ÉdÞ½{>Ê¥0ÙÒœIËÈ6MÓ±…‡‡“Éd›úúú7ÊXKëèèH¡Pà ¨"Ó-þþþ===QQQúúú¹¹¹"{{xxˆ§î€@ ª©P­««KKKóóó»}û6‚ XЙŽJ¡©©ÉÎÎÎÕÕõÚµk>>><F£‰ì½oß¾©žÈ«@É 2™¬®®^__¿mÛ6‰kiø|~JJJGGG||¼³³3M@ *Æl6[KK‹@ ôööêêêNõ|8d´J@‘8J@¥@ R€@ P)@ ¥*…¦¦¦ððp,ÇVmmm|||KK ¢ÚHN²ÒÞÞž——çèèxæÌ—yóæ‰Dww÷œœmmmXKQa$Ç)ääälܸA.—ëììüé§Ÿb©,étú(s×@ )9|è‰D¢‹‹Ëýû÷ÛÛÛŽ€"“…Ba±XãÝß~ûM¼ö ¢üáÃÇkhhXZZêåååêêzôèQ77·¡¡¡/¿üJ OJJJCCÃ…  Ç?ÃuJJÊÌ™3­¬¬à€ŒíðX ïÞ½›;w.Hµ" ß¾}K&“ed^™Î,Y²$##cÚž¨¾¥€ ˆššÞ¡¨¦¦¦š‰k§UUUmmm3gÎÔÓÓ³²²êè訪ª222²´´lmm­­­555%‰EEE«V­Z´h‘Èáeeeïß¿wppxõêÕÛ·o7mÚUÈdC¼\"›Í¾}ûv\\øüóÏ?µ´´lß¾ÝÇÇG¤d“K*B R€L  (=‚•K433³µµ¿ZXXØÚÚ‚z­$iõêÕølzXIEmmm¬¤âŽ; T!’‡uuu–––(Š.[¶ÌÂÂB¢Ãáôôô477wwwƒ‡†7Ž;&^.oÿ¬ººº:ÇÃ~’§¤"ò¥°dÉ’?ÿùÏ×®]ˆˆˆáBGQ´µµ5)))888$$äСC J FPPPll,¦wÚÛÛá-‘ưåEt„Dd”T„@~7|¸xñâºuëš››}}}e¤]e0üüü***¬­­étºÂ©1A§Ó>|8uå8¹j¢££Y,–±±ñ‘#Gìììø|¾Èu¥}F¤¬¬ŒB¡ ”””€Bì)))ðé‡HD=00X›ÎÎÎáááL&ÓÐÐð“O>ÆÀÐÐøôÓOŸ88¸oß>.—+ eùêÕ+9hllÌårU¦ÂŸ´r‰ò @IEÈ´åwq û÷ïÏÈȸsçÎþýûóóóg̘1Œ™1\9½¾¾¾˜˜üOOO‘\.—H$‰DÙg“?zO]]}÷îÝÏŸ?öœSPÎláÂ…  Æ}à3tÜ@†yZDŸk×®}õêÕñãÇAI˜± ±±144ÔËËëÑ£G>>>­­­%%%{öì™={¶´J~#åæÍ›ÝÝݘ—ŒÌш1sæÌ˜˜‰†M ŒtNNKKKLLDQ´½½Ý××·¡¡ÁÓÓóÊ•+(ŠÖÔÔìÝ»×ÏÏN§s8''§ªª*ü±ÀØØ˜Ífgdd”––®Y³¦¡¡EѧOŸVWW?}úÔÇÇçåË—û÷ïOHHÀÈápʤP^^> 2%} 'NœHOO‹‹;xð •JÕÐÐS¿ìÛ·ïÒ¥KÖÖÖ2ÊÉ`æŽ`0†††XˆÞk·Aô^]]ÝúõëÑ{øzVt:ÝÂÂÂÄÄ$$$ÄÔÔ‹êkooÇ¢úÀüÆàà`qq±´f›™™ ëg@¦:ÒüRwîÜ)((  ±‚<WUUõõõ%''s8??¿Ñ´L<€OÎè=0vàp8T*uéÒ¥‚ØÛÛ#òEõÍž=ÛËËKþFþôÓOuuu"¿üòË•+Wæççÿúë¯Óêaúì³Ï\\\àŸJ5•‚ ]]]d29!!A~~MM“““«««RZ&À'®¹¤K¡P®^½jaaáìì\YY)½'#ª¯««+$$Dš¢<}ú´ŽŽ~ã©S§¤µÁÖÖVá dÒ)…wïÞyyyEEE(ãÂ… I$ö5##cëÖ­ ·,::ú믿|999`<ªHüŒ ˆP(ÌÏÏ·³³#‘Hýýý %Ÿ}öYYYÙ»wïÖ®]‹êóôôÄK&“A4—daÉ7Œ‚@TM)p¹\+W®Û[~Ö¯_ÿøñc:N ÚÚÚÖ¬Y3š–ñùüˆˆ''§îîn[[ÛÂÂÂÌÌL@°cÇ6›••Åçói4—ËÍÏÏoii±±±±±±‹¥¥%POvvvt:Dõ%%%©©©µ´´xyy1ŒÎÎN‰É&á?2ÍS@QÔÛÛÛÞÞÞ××W±3¶··kkk>1¨‚ÝÚÚª««;¢³ ‚þþ~àÂb±Xd2ù÷j.CCCuuõ¶¶62™¬©©9z  %$$´µµ™™™íܹsôÕº)Ê_þò—Ï>û쫯¾‚(dü}‚/_¾l`` §F(**ßhhh¨”T…ÚÚÚ o¤gSWWÇ&5ˆD"ÐÈ¿£ú444‚±±±R4Š¢·nÝÚ±c‡¿¿aaáFøàèèèââ2lŽÜÄÄÄ¿üå/𠆌­Rˆ‰‰a2™W¯^•çÈúúúìììi.¾¢¢¢æææY³f©©©?>99™Éd*á®Èan¤¤¤ˆÌ§B Jö)äææÞºu+55uØ'EÑäää'Nà#§'$©¨¨H hhh‰D®®.‘}ÊÊÊêêêÌÌ̬­­Á–ÒÒÒ¶¶6###lI¥HòE°ñÍ›7³-¶´´ôôôdeeyzz¾~ýZ±Õ&Û˜ñQå-…¦¦&//¯~ø¡±±±\Œ²²²¢¢¢çÏŸGFFž:ujùòåüã---ÍÍͧ¹øV¬XA£Ñ€o²ººdCÃïXTTäîîÞÓÓ ¶°X,—þþ~0Ó!ž|AŠŠ iÙjjjÔÕÕ‰DâÐÐb-o˜ümC`ÆG•·úûûÝÜÜêëë·oß.ÿ‘ÞÞÞP|xë) ** Ÿ¤€Éd¦¤¤ ÒÜÜ\[[K£ÑjjjÀÿmÆ ¡¡¡ÙÙÙ"±›àXMMMiñšK—.e2™Û·oAY Þ0Aäo›<±¡©­´µµðŒá“ÉLPPÐÁƒÝÜÜðÓÓÓW¬X>ûøø rîÜ9|mSSÓ§OŸ~õÕWâɱAx¼&‚ YYYƒÄnÞ¼)bVfÏž}ñâE /9Û3>ª¾RPWWŸ;w.”…Â<|øpÍš5ÎÎÎ|>¿­­ÍÄÄó8ˆ˜÷D"ÄSx<Ø"»){|ž}åÊ`åáƒ,åœÅo˜ümÃ7 f|TeŸDa¨TªÁæÍ›y<^nnn__öÓ®]» °÷|zzúž={ðó¸L&sïÞ½âÉeÄk"ÒÕÕE"‘æÎûòåËŽŽÚ,Þ0Aäl3>ª:ê2¢z!ÃR]]½iÓ¦þóŸ/^¼xñbdddPP©¯¯obb6gΜÂÂB“+VH¤gÏž‘H¤˜˜{{û­[·Š$_äóù2²-#"33ÓÌÌŒÅb)f·‹7ŒL&“ÉäaÛVsÀŒªï!àÓé{öìv¹õû÷ïþùg¸ì\N†††š››ñiE¶(|±¿¿¿»»[é “³m0ã£jó»0çÆÆÆ_~ùåÚµk2”›ÍÎÍÍ ÈÉÉ*QqŸ…BÙ´iS{{û‹/¤…ëjkk;99)%FLB~·"F£ùûû÷ôôDEEéëëã‹<<´ƒÏ秤¤tttÄÇÇ;;;ÃÑ¢bügö$5!½½½ººº£O@¦¶R€@ †9C ¨ T *•J¨†Rhjj LJÕÖÖÆÇÇ·´´ÀûL8P"­½½=//ÏÑÑñÌ™3...óæÍ#‰îîî999ÚÚÚ#ª^ @”Î/åäälܸA.—ëììüé§Ÿž9süD§Ó%Öw„@ *>| …‚‰D—û÷ï···ïÇ8óÛo¿UUUÉØB¡lÙ²åæÍ›PVpø0†|üñDZ±±†††¥¥¥^^^®®®GussúòË/á-ORRRfΜ‰¯û$‚££c~~¾l}˜˜XRRòÃ?@yB¥  ZZZ{÷î}÷î½½=@055MNN~ûö-™L†uÇÆ™˜˜˜áÉá–Æ¥¤¤H,BJa$ƒ55¼CQMMÍÀÀÞŒ±F¤*dGGGUU•‘‘‘¥¥ekkkmm­©©)‘H”XÀRbaKeUµ„@Ÿd¯ Éf³oß¾>ÿüóÏAAA XJ+l©”ª–¨ ƒÁèèèÀW…433u±°°°µµrI$(`‰ [Šo_ºt)ŸÏU-/^ … ‡òRWWgii‰¢è²eË,,,Äw …§§§§¹¹¹»»lŒˆˆ8|ø0¼CÊâØ±câU!ñN°`ÁðY¤€¥ŒÂ–ÒªZB RÅ’%Kþüç?_»vm`` ""BFeZE[[[“’’‚ƒƒCBB:¤˜ë‘Á`ÅÆÆâõN{{»±±ñ´½Ó²«BŠëy¶#Ò«ZBàða.^¼¸nݺææf___áRaáÂ…~~~ÖÖÖt:]±ËÍŸ?_Äš¥Óé>œÎwZbUHiE+åùŒ(£ª%dšZ `PúàÁkkëØØØ°°°'NÈÞŸD"…………††‚ØÇ‘‚Uµ©¯¯ß¸qcnnnxx¸••ÕÛ·o§m5ŸÏˆˆprrêîî¶µµÕÔÔd0™™™`ÇŽl6;++‹ÏçÓh4.—›ŸŸßÒÒbccÃáp$n·±±ADGGÇÌÌ,77÷Çü1ü;© z\VV–ü… %Âårcbb‚ƒƒÄ}¢££ÑÒÒ*//—眠þ²øøø0™ÌòòòãÇs¹\>Ÿ¿oß>.—+ •UoÏçs¹Ü)Q PŠ•ãVÕ2¹jI&''744\¸p¡°°ÐÔÔT†úhmmÅQâš%88øèÑ£ººº?þøcMMMtt´Ä¨¯¯ï;w–/_žŸŸ?cƌѨ³¾¾>‘ØOOOE7oÞìæææççF¹\.÷èÑ£wïÞU®>-++ûòË/³³³á«¢‚–ÂâÅ‹eëÓ§OKû©°°Ðßß¼‡¹\îŒ3^¾|)íŲtéRAŽ?>Fz®¡¡áÔ©S%%%õõõ(Šfgg‡„„¼yófppP‰ ùá‡à‹¢b(ÇÑH"‘ŠŠŠ‚ D"QGG§««Kâž3gÎŒ‰‰.üì€ü*¬¸¸855u``@†?_ÕA¡¡!]]ÝŠŠ mmm‘W}|||qq1¶¥´´455µ´´ÛRUUõüùó¼¼<ñ…C ÅÉÉ Aššš/^àOK¥RQ­¬¬ÌÎΆIô!ÓÑRÀSUU5{öl‹%cŸÐÐPAôôô†½(ž®®.___&“Éápþú׿Ê<£(Êb±0ï†ø@úÇŒˆˆ …™™™` øçääüøã(Ц¥¥%&&¢(ÚÞÞæM0±±1›ÍÎÈÈ(--]³fMCCŠ¢OŸ>­®®~úô©ÏË—/÷ïߟ€?Ãá”I¡¼¼\a7 ¢,4”®b¢¢¢d—œo)MMMwwwø¶ž¤S’ÁÁÁxkˆB Î;'¬tðàA777ÙW%wîÜ)((  ·Â°WUUõõõ%''s8??¿Ñt;==«©íãムȹsçð~VSSÓ§OŸ~õÕWâQ€˜48•J.{{{08Ú¹s'‚ T*uË–-‚¬]»VäÒ³gÏöòò’¿©³fÍšV%üäyC@&L)\½zûzæÌüWq>|¸fÍggg>ŸßÖÖfbb"cç®®.2™œ@$åihMM“““²"jI$’È"‘Øßß}åñx`‹´(@ …rõêU ggçÊÊʾ¾>]]]¼Ê‹ŽD¶ƒŽ‡„„HÓ•§OŸQµvvvð1…L€OÁÜÜ|”>…ììl …Âãñ†††h4šìH„îîîO>ù¤²²RþqNNNÎáDZ¯ééé£5566ZXX ¯Ïž=+++Û²e ¶ÃöíÛKJJ1gÄ‘#G°ýÁ‚ 8Š¢ .DQ4..EÑÒÒÒ¬¬¬þþþ9sæwƃįΓÐB&Þ§••U\\ÜÓÓsóæÍ5k֌ȲŨ®®vuu_ÕÔÔ°Ïâp¹\+W®Ã[NÖ¯_ÿøñc:N ÚÚÚÖ¬Y3UhjjúÓO?:uêóÏ?okk[¼xñŠ+|}}¯_¿îèèH¥R½½½W­ZõèÑ#‘(@Ìl±´´$‘HàMN§Ó IJJRSSkiiñòòb0SNŽ…L¡Pþò—¿|öÙg_}õ|ùAFl)ÈÃÙ³gG¯„„Bá¡C‡ÂÂÂ;¼­­M‰yCCCÍÍÍØû_|‹´(@>ŸM¯p¹ÜÎÎN¬w---<O(¶¶¶âÏúè#°}éÒ¥L&dR›¨¶ÉëQM¥ÐßßïææV__¿}ûvùòöö†·uœ•™ÔnÞ¼‰·)0fÏž}ñâE%¶MžX/ˆj*mmmÖ+Ñ¡8¥eœ•™ÔäŸÂ} @F¬D5} êêêsG wìÚµ«  {ɧ§§ïÙ³?/Ãd2÷îÝ;¢lkˆ’2©¦m‚”••Q(”’’0jHIIw|ÂQÃ?ȤE__ßÄÄ$,,lΜ9………&&&+V¬ ‘HÏž=#‘H111ööö[·nÍÌ̬©©ÑÖÖ+Ämmmétúo¿ýÖØØhjjZ[[{ÿþýÎÎÎ%K–€8+™™iffÆb±6Ún8üÎ;oÞ¼imm7oÞ¬Y³ ×­['{)d˜€ªÓàñxíí톆†XìƒÈ6›­¥¥ÕÚÚª««+çÈk``€ÃáÌ™3g¢Ú†¢hkk«¡¡¡ººz[[™LžðÈȸ*ñ´ëa±X<8yò$¼7ˆÊúâi×Åa³ÙL&SéÉ!ÈdT XÚõ/^H3O´µµœœ  L ãçá§Ñhþþþ===QQQúúúø’„Y³fÁ[L ¥€¢h]]]ZZšŸŸßíÛ·Á‚^ ÈtT MMMvvv®®®×®]óññáñx4MdŸ}ûöÁé(dº(‘´ëÛ¶mÂðñðùü”””ŽŽŽøøxggg8š€@ÆŸqš’3Õ¡··WWWwZe"…@ R€@ SøÆ†@ P)@ ¨ T *2vJ¡©©)<<KËU[[ßÒÒE¨6’ƒ—ÚÛÛóòòÏœ9ãââ2oÞ<"‘èîîž““£­­=oÞ<(8dzY û÷ï733ûí·ß~ýõ×òòòíÛ·{{ûÚÚZyÎÛÓÓ£@^Ʊ¦··7##cª´VY}lmm}ûö-|Ö!£>€ ñD"ÑÅÅåþýûííí‚p¹\yNÊçóoܸr‡ =|øðƉ‰‰rV)/!.\¸°`Á|fQ===.—+²ìßÚqh°Ä† …Âb±¤õñèÑ£gÏž…Ï:D^$“c³Ù111T*õÖ­[………®®®·nݺ~ýº<õoÞ¼YRRj+±X,@àáá! (n÷úõkÅ)¥]¢´´tÓ¦M⇜?~üÒ¥KðY‡Œ¶À¬ššÚ¼yó°üüjjjòùËËËÃjÌ“H¤¢¢"@F":::]]]‚ßDeeåÿþïÿöõõ)léH»0ªœœ©©©yñâvȶmÛâââÄ[;> –Ñ0%‚ï#H™bÈh} “››‹UþZ±bFª««y<ÞúõëËËË555ýüüîÝ»§®®nkk»gÏ…/'ñÀ'’——ggg—™™Éårýýý±Šuzzzâ­ŸËh˜Á÷*È+…––PY@Äs¥§§W[[»jÕªºººµk×~ôÑGºººõõõJqŽ`—@¤¢¢Â‚N§[XX¬\¹2$$_ÎL(s@bkÇ´Á²¦D°>B¥‚ÔÕÕYZZ¢(ºlÙ2 ‰‡Ãéééinnîîî#"">,¾3‡Ã!‰"ƒ‚‚<èææ† ÈgŸ}ÖÐÐ````ii ÞÕkÖ¬Ù¿³³388ooŸ9s|&çÎ×9¿8„ÃáP©T0:)£ª©© \[;Ò¨µ²†Œ¤”£l°>Î;wôÅ ÓnöáôéÓ‚,Z´èýû÷2<B¡°¥¥åÖ­[‹/¶±±‘èwüî»ï@¾fŒ˜˜˜ŒŒ PZº¹¹EÑ_ýóÆùûûß»wïÇ£q݉_b÷îÝ åÍ›7K—.EQTäü6l[;úËn­ì†)Ëшïc{{{__ôŸ©6B¡055õîÝ»?VŽ£ñâÅ‹ëÖ­knnöõõ•‘v…@ ,\¸ÐÏϯ¢¢ÂÚÚšN§‹ïcnnÞÚÚŠ}¥R©›7oæñx¹¹¹ÀE—½yóf ’žÿ°°0&“)þÓ† °íÕÕÕ®®®ŽŽŽšššD"qóæÍK–,A¤  `ãÆ`++«¢¢"¬búH‘x‰ššKKK‰„ ˆNÇ;ººº°a<¾µãÐ`Ù S€¬¬¬àààžžž›7oâ‹èàûxãÆððð j'6l¼*éQ­S¢k2z¡®®^SSƒ ÈG}TQQÁb±233ètzII‰"Ã@tt4‚ ZZZåååò˜|>_¢3lÌÏ»wï°Ïø¯9{öìˆì>ŸÏb±Àg.—ÛÙÙ‰ÿ5<<<55UþÖŽ´Á2Z+»aJßGçÏ?ÿ|òäI77·{÷î©qËãñΟ?.—œ8#%22òÕ«Wò? W¯^ÍÈÈ8uê¸\rr2•J‹®Mx/««ëëׯŸ={vãÆŸþY(:thTÁKÇŽCdùòå ‹):::++K‰Ôàà ²N%Nž<‰×“¹µÊê£ ÿô§?u“”äêáá+,Yvv6øŸŸ/1ªU)]› ½ áv½½½‡úðáƒP(ܽ{÷¨”B?ðŠ?~|4>ÿùŸÿéïþqõ<™[«¬>ÊÀÑÑñÑ£GcÚž±r•“ŠŠŠ;v`ÿ«ˆG|*«kÞ‹gÏžÕÖÖ¢(ZTT$ ?ûì3Eóòò._¾ÜÐРxDãÌ™3cbb€Ë`Ø Ñ2ü‘ß}÷]YYÙdsÆôöö®^½ÚÊÊjJ´V‰}”‡ÃÉÍÍÝ´iÓ˜6Iž WAúûûSSSù|>‚ mmmø3TUU=þ}Êd2™L¦‘‘QYYö«ƒƒƒx“8N™ÊËËÅ"]›$½& ›Í†°ì8q$'Y9qâDzzz\\ÜÁƒ©T*û…¨YYYŽŽŽàÝðìÙ³îînmmíÝ»wè¥"r ƒÁ ›™---6l?Ú×׬¯¯_YYÙÙÙ‰=g0†††(ŠÎŸ?ÿÀfff¶¶¶`¿………­­m]]ˆm_½zunn.V|ìåË—FFF:::ýýýCCCË–-ÃO uuu|«‹‹‹¥uÖÌÌlÆŒø-"]›$½“`#@Ð××qD£DûÿÎ;Aþœeee·nÝ‚ÿ´IË7´µµE”‚¿¿?˜å633Û±c‡··÷¬Y³¶nÝ*í$ÏŸ?ÿä“O°Š~âΟ?ñâÅ"ƒÙA® ^AÒÒÒÞÞ^°Z ãØ±cîîîööö.\Ï'þY]°`öOàñxø f3Êd2===ñ¥É°ˆOüµfÏžíåå%¿HEº6Iz1J¤š]]]d29!!Ab°DV®\ *JC&3uuuššš‹-ÌÏÏ0Ëmmm f¹?ùä“—/_ÚÙÙ•””Ìœ9sõêÕø9y|z‘·nÝJ¡P6mÚÔÞÞ^__¿qãF ££Ãf³ñmxøðáš5kœù|~[[›‰‰ x—Θ1ÃÁÁË媫«cöiAAÁ›7oÒÒÒ<==ËËËÅßaÒþ±˜zzôè‘H°ÆÐЖ––øc"íMyúôi‘øzñ®M†^Œ‰Rx÷î——WTTLǨzìÛ·ÏÛÛû믿NJJ²··'“É‚üñ¶(F +((¨¬¬¬©©ùâ‹/¼½½###¥Mä@Ah4š¿¿OOOTT”­­-‘H”äºqãF———Þ®iii===À“ûöí/¾øÛ?::ú믿666>räHNNØã‡!?køŸ={æìì,b¿`ŸxÈdr`` Ô‹Ø8Z¤k“¤ÊW \.×ÃÃãÊ•+"nÕéLkk+‰DR yüøñ”””Ü»wOäµvéÒ¥ Ìš5ëîÝ»`0±«ªª@ê‡ÂÂÂׯ_ëêêý<Ø(ŠÖÕÕ¥¥¥ùùùafㆠ¢££÷ïßü;ftppü¤¦¦688ØÔÔôþý{ssó?þXMMíòåËxû”ÏçGDD899uwwÛÚÚfff ‚;v°Ù쬬,>ŸO£Ñ¸\n~~~KK‹ ‚ NNN/^¼xùòe@@€ˆE mqêˆå ÉÁº6u{1LœÂåË— |}}åQ(EEE*f¨««ïÞ½{ñâÅ"ž̵¦}tppX·nÞìTx–[äÀììì-[¶Éduuu,ë@ؽ{·ŒÕ˜ŸL__æÌ™"¿jkkƒ•x#õ¢#B$ÁøX–¶}ûöÑ ßµ©Û Y–Bttôž={ä G¯««»~ýºê (N·4‡2f¹322°åC¼Ák2OΰÑE|NÚø]åöBr˜3ƒÁ°··—§oB¡0))ÉÐгU‰Ý»wƒ¥ÕÕÕ4 lüþûïùåì48ƒÁ˜ðf°X¬âââ©Þµ±è¸:›šš¶nÝ*-7Çc±X¯_¿.//OIIyõêÕæÍ›)ŠŠ „B¡‰‰I]]]NN™L>|øðãÇÍÌÌ‚ƒƒMLLF“š™*h÷²››[}}ýˆÆ'ÞÞÞª'|E,"Ls™^JA[[[ øK&?Ò(Â4‡é•ž|m²gÏ ‹­[·VVVöõõ ùŽŽñl±ˆê¡E€w(HK ÓB R˜ŽÈH 8IÒB ã=|_ô*‘çÏŸkjj °êVeýýý nwhhˆÅb‰GŒ@ ÓËR_ô*N~~~mm­ƒƒCiiiii©*ÉB]]hDJ 2í”¶èÔG‘x@bb"ðÌ/]º4)) JQ1~· ¿èU__?77Wdo®®.°.@KK Ë®@TP)ˆ/z]±b…„44@.&¡PÓ´A ª¬šššììì\]]¯]»æããÃãñh4šÈÞûöí[¾|9X3÷îÝ;9SC )©D½nÛ¶ K‰çóÏ?¿~ýúæÍ› AYZ¢JügJ’Ífkii„ÞÞ^]]]9žØlveeå²eËD²€B •R ‚ÀˆF•J@¥@ R€@ P)@ ¨ä§©©)<<¼ºº|­­­oiiw‘Ê.^hooÏËËsttøûï¿_¹r¥……‚ |>ÿäÉ“4­««KOOÏÀÀAùóçÿøã–––Ó¡ìdZîß¿_]]}áÂðõýû÷A__¿²²²³³ÓÉÉ ÛóÇŒ‰‰™9s¦ ‹ 2­•ÂÛ·owîÜI¥RAWŒÒÒÒÞÞ^‘ý ÆÕ«WÇ®'uuu–––(Š.[¶ ¼«Å] §§§§¹¹¹»»lŒˆˆ8|øðè¯> (> –ˆP(LMM½{÷îãÇÅýöÛo£¢¢D6ÒéôââbE9Ç9Ûúõë[ZZᤇ[´hÑû÷ïeì& [ZZnݺµxñb¡P(Ïɧ¢@ ªâââ˜L&Š¢‡NOOÇÿÄb±ÌÍ͹\.~cjjêýû÷…B¡P(üûßÿ.ò+Š¢wîÜùÿïÿig†††Ö­[‡ ÈÞ½{åù«s8œ#GŽ€"Ã2(€ÔÙuuõššA>úè£ŠŠ üO±±±[·nÅÛÉMMMïß¿777ÿøã×®]kee%bE#²{÷@0vV¦¦æƒfÍš6ìþ$),,ŒÉdÊå’‚}}}Ø¼ÉøÐÓÓ“=ž]ëííÅŠC†>…ŸþùäÉ“nnn÷îÝ««ëëׯñŠdçÎqqqø-àÃû÷ïûûû¥i ;;»œœœQª1.—œ ÄwˆŽŽFDKK«¼¼\žòù|iã…)!9EÄçóÅm>ŸõêÕŒŒŒS§NI©H”wþüyi—Addä«W¯äÜY¼kÉÉÉT*š#>þéO¾†††¾|ù¿ƒ@ ÐÓÓkmmUàbß|óÍ•+Wdï#òÔ‚‚‚X,–@ ððð8L8vì‚ Ë—/Çþœ 3áQàß(MD¥¥¥›6m’è‹ÉÎÎòóó•Øéá¹yófII‰çôððˆ•ßÍ$Þµ“'OŠkFˆÔá…BÁ&ÏÒÓÓ·nÝjccƒ7°›››166VÀ*Yºté°q;·nÝ’ñkQQQssó¬Y³ÔÔÔΟ?Ÿœœ,Ñø¿qãÆÒ¥K+**¾ýöÛQZR.‘"CD E¼Pxeeeqqñ¦M›À×úúz%6/=< ''gÕªU œ3&&fÏž=òì)­k[¶lyüø1%HãwJÃáäææ!fddøûû{{{ÛÙÙákFÖ××/Z´H±‹™ššÖÖÖŽ¦¹$©¨¨ŒÃ‰D¢ŽŽŽÄz–3gÎŒ‰‰.ƒØØX…/7)++‹/..ÆÏn¦¦¦â+}WUU=þe2™L&ÓÈȨ¬¬Ld‚¦L ååå²=2¤„÷ÂðxýꫯÜÝÝìíí±Øj"¢P(‡J¥»ÝÞÞAêêjð™ÉdzzzŠ” œ={¶———b½ÒËÏϯ­­=qâDHHÈþðàGàp8x¡Íž=ùwô§ˆâرc"ÝÄ/i# ,À„Éãñ°ŸdwMSS“ËåÊÐhÓZ)ÔÕÕijj.Z´hpp0??Œ%ÞHlÈŠ=`ÅŠëÖ‹Àf³Å‡¬øhß3gÎ üûðáÃ5kÖ8;;óùü¶¶6i{vuu‘Éä„„ùÿ·‚ Èüùó/^,ÑÍ!.+++yJrK‰DÑD"±¿¿ûÊãñÀ–‚‚‚7oÞ¤¥¥yzz–——ãÿ-â"¢P(W¯^µ°°pvv®¬¬ìëëÓÕÕåp8X§=z..Ài:÷ôéÓ"*[\zÿûßwìØ¼ªIIIàYÒÑÑa³Ùø ÆŒ3¸\®ºº:fÖ‰wS¼Ò<2º644¤¥¥ÿÿ’ûöíKHH@$))ÉÞÞžL&#’˜˜Þ'àFм:z{{»ØÀÀx'Œ*•j``°yóf—››+c<òîÝ;//¯¨¨¨ed”(ð¦Ý´iS{{;ˆ€;ìÚµ«  S4ééé{öì)**Â/öîÝÍb±Œ9bgg\tÒD$ óóóíì쌌Œ€~1‹Àår=<<®\¹"âå‰A„F£ùûû÷ôôDEEÙÚÚb¦‡4È#‰155ýé§ŸN:õù矷µµ-^¼xÅŠ¾¾¾×¯_wtt¤R©ÞÞÞ«V­zôèQDD„““Sww·­­-–KJ¢ˆjjj,--UbggG§Ó qrrÊÈÈxñâÅË—/$?"#ñňKOCCüÉ…B!vª 6DGGïß¿ù}ô§ššÚåË—ñfŸÏÇw³°°033S ìØ±ƒÍfgeeñù|Æåróóó[ZZlllllldw­«« ?ƒˆÂçó©Tjnn.>”í‹/¾‘v åÛo¿Å{&{zz€Á¬@LÑõë×;&ÛóyöìY¥ð:t(,,Lc% D(:88\½zµ¯¯Od‰‘S&2244ÔÜÜ<44$mËàà XÙ%{õÖ)lš†ËåvvvâÃñ_G‰¸ônÞ¼™œœŒ¢èãÇoß¾ ˆìèÏuS<²Sb×ÂÃÃSSSá,ÃÈDI¼‘"Ä………þþþàÿHØà¿þë¿ÄÏ&þŒ¾W—.]:uê”üó‚ÃîÓÐÐpêÔ©’’’€€€úúúa"§LäÈT§§§'  ¯¯ïìÙ³øùãèè謬¬ño@ 8yò¤œKcaDãøüóÏsssûûû ‡gëÖ­999#)BQ”N§oÙ²E¶å">½7Rbbb˜L¦œ© êëëåY““½eË2™¬®®.ó'.yd"§@¦:³gÏþþûï«««ÏŸ?Ÿ?öðð ÓéãÜž»wïúûûÃ<ÃLøK{cJ|o?þüüãHcŠ*++׬Y3ÖJŽÁ`ØÛÛËXƒ„7ïAºgñ7¿Di€w ŒH Òd2>™Ìp8ƒ1žWd±X$»ÜÙ/IDAT ÃDŠd^ …ÖÖÖÏŸ?Ï2Ö«x{{‹Gœ={vÑ¢E_|ñÅØ)¸¦¦¦­[·†††/šxÛx<‹ÅzýúuyyyJJÊ«W¯6oÞL¡PFy]‘!“q¢LKA6‘‘‘?üðƒøöŸ~úId1àÇ«W¯VŠ¿@}}}"Ñxò®”«Kˆ4™Œƒ@ ñ³À»ÑÅÅ%""ÂÈÈ03gΉ1E ͱÄh\e!Þ¿?Ò£ôõõ–S 2d2@ÆÕRãäƒbìììl …Âãñ†††h4ÞŸ››ëíí­òþ^ÈÉ4D¥¦$å$33300üðaäjjjìÓÜÜ|èСib'c‘!“i%È4>`444˜™™É˜àimm;wîô‰3‡LuFþmnn.{ÊwÁ‚ãù`0{÷îv7‹²-(É&d¼•ÂdCÚZF[Ñß‚¾³ÐéÀ£$°ç ´žF«í×QJŸ=§±sÇÐ=ö:ä3· ¬WÏhmtyu꼯Ø6qÓÀ“Wñjw§x;OCk ¨Ibàá0Ð`€|ް3ƒnD‡ ,Ú „… Ü,˜rs¼úÙ7p«¸ÌSÈÓíï¸PH¼ªÝŸeL²\-˜oæiˆó ¯¼#k ,ÿõ§Ç=1-q5¢:Љø±Q"ŠWÔ¹ÇʶÃÝ6ÞV­\ÅÆ®ÉæŸfNÙx«·¡ Ùx³·¥°ÿÎÉáo’ 6v\k³:sì¿]_®±ÿ{Sj%fû®©EÛ7¥’û¬¥)r2l/] ý¦&Ök—DËk’“nl’º.AÝWŠ_—9ß }×ûé©ñ{(k9ŒÃ$²eÿ$ûþïXù. È+~úÉpCMrH3î ŸpLrLÃ@–‚žœ†##…$'u´ÙÝ$uí½É {Gáΰîy–†¾Õ çÝßÈÌZ6‡ÃDe»yÒ¹¥pœybÏo¬‡FNX]©Z>çÕ?SfCÖcæƒ U8Þ¨„?`:½nEÆýz’>g¿F'ö™5úñ"û÷›‹w"Ö¦£gX?2ïÍ4±Ÿyñng§ì³j¿Êª†Wð¥¬GÄ:’\À Ô‰(ÿœÔæ$ß-õpTàÁßß7¢—ò¬ý£z’_’õiü…«†xº4eµvHU*t#ÝǘγÆôgkÿîóÿËãC¥‡ÃCñÇŠô9z–ªþò8ŠªãX–ã†DSLѲäê^“—&Ë$ŸÒ!G” wnõ “c«|Ò^&AÀTµÛ1äTp…bQlD@‘{"ázÏ‹ˆÃe/Ëô²P?B.\ÙKGy#òòBõÇLÓùÔ–èiŸZYÞçsÏÓ’Z…bóÿžkt™ÚËŠÈž¡0ÊZ\/'zÞ_gRönFV¯ŠÍÜ›OÓ)ý(º¿"ªð)ɯìª]«×©W¨ô‡í ªi½9¡ÎÒ$ç”Tœj-âo×m]~û˜Zóg¦¨+¥ê˜ê-QjÛâŠ.âË’¨¬Æ -ù´Â6¡†®E"?Í©ø‰ïñŸ#wžD§Ë[VV25&]t‡5`²V·9†· è Rj×÷Д:­§„¼4Í3}/xçÉk@nkjÛZí¡¨…ëõ8¥ç\{7TÁt‰)ù ^fòí…ªsk Ÿd í‚NÓœåàS+'`ƒ—<ËÔoYò†]RÅ¡HRýR-;ä›)UÉž¦¤«n³øÈÎQ8ŽÍÜÎÍ2ý#÷ó±ñ7!0ý¸›Œù±IEND®B`‚snd-16.1/pix/sceq2.png0000644000076400007640000000230411147553270012662 0ustar bilbil‰PNG  IHDRË**=_&3PLTEÿÿÿÐÐÐàààÀÀÀ°°°@@@ððð   pppPPP```000€€€ ”ué pHYs  šœtIME× -üf_$IDAThÞÝZ‰–« … ¢ÿÿµÅªà‚µ´gÎc¦Ó*ÂÍz†±/ÎÙ°D$°FO8ø…uzh¬ƒ£çñ\`($ª9çÞßíÕEìƒÀ©¼Çe;'­˜Ö­¡Àpã&ÌvæèZ8Ñx\¡²Y÷öÐĉ6ë˜;Ò1[¡ŠÊŒ„…úâke¶ŸdX™>G¢•]Qo?ð(T¸Ö¾M#}%¬¬X\W‹@ä_ñ/†Ýˆ0 CXDЃ7£Å’Œú2–©b³\ù_èƒÞð½[”œƒ<ÄÂûä*Á‘ r^‚OßÅR}~?<Æ:çå,1½D”=ÖËfá£[Ô1ú9ÜÚA.ÃúOͰ8S sƒ¡„Å­X( =mœ2¼¥GÇ1/BY(ŽFÖe»çÆb+,²fÃÄÐ ;,L{§étU/ñîÅ啌±Ùf7ó®–±&•Kd†%ø 3ÂÏ%}„P¿ˆ°Ò²Žqóc® „6XÀVYT8HÄa@=ùœã˜ô§M]±€f(ç8¦Œ6 ÖPlã¶µmuggûÀjh!Æé ¿„l Ü,ª_ ç;³{Í’ëßábòˆ T†ÀK"‘œiŸ÷ƒdšì=ˆò –-¨Ïº6‘äÍN±„À|+z©wh¯éÒçqTºÍ“¹ðieÏ“£Ù½2€²•ô‚bÜ ™j¤jÁÈÙÃ9µr°\&¤Iʾjҽ͛vÌñàb¾ˆT#ù—¯s¦‚=üË=÷$›m |´î•ø&HT#Öo‚‡¸¿a11»%1Ï™ÙÞÃb›Œ–¢ÒHz·”¨F°Ä¡£KÝ ZºÇR0’/é¥|zº –D5¢»ð!±†…=¾Æ_±1]²ÀXEáËÆh®‘¼áMÞÀ¶ìáÏaáò }ƒöt\ƒgH‘jÄâ!¨wì¡Re¥·± /£êž"b¼òŸ+e¾¼/Tƒæ$ Y@i1¤Ÿ„[XŠ2‘I¬t¢sS]¹ùDÓ`©„‚Ü2’»Ý<†Ý­P#·¦ŽÆ~ÔYâz'¡ŸUu»@ÀO kB~ßf\ËÊɇëñóÞb¢ÝhMÞõb§©s¢VjøÐêŠñyÃOê9ý>1§}à¦qÛot•ÔK“xâp»@Î&N#ß71B0J 1î™›=€›ú4í¡„Ì0çýä¼bßÈ ýša·0®Æ@OLxßÈ ýSuƵ Sˆ†§0½~bcG ~)ôOÛ ýÒ.XžÔ1ÞNY¢å¡˜¾Ì–RÌô* _‚±†ajw*vݶƒ´i%ªÝu5]¾)ËfÁ%úçü-S¿=RlŒ…ÉFG¼W…þ†èKÿÃ٬ᱠ±ð#}ð—nÏôPMOË•ú¥"1f~ð¿ ³WþˆÚ#€¹dˆ¿IEND®B`‚snd-16.1/pix/voxspectrum.png0000644000076400007640000054571411147553271014266 0ustar bilbil‰PNG  IHDRïrE“4QbKGDÿÿÿ ½§“ pHYs  šœtIME×"‡UåM IDATxÚì½y˜eIYîû‹ˆ5¯=äÜUÝtÓtU5M£ ƒ¢(ˆâ¹WAPP@W@å"qB@Q.Êt8 (ƒ qDQI„ˤ MOØóP•U•¹§5DÄùã[{ÈîP{ Þç‰ggeeîÌ\{íX¿x×û}¡ÆãK Ï[x8vbhtLÇ|wõÌp°‚‚‚¼p pt{éMÅ/²Æ©¼÷Q0!÷Sr¦¼æô÷ј˜:Nh☩~€ŸNßÂLe¼döµá x ðà>è ­ß+^§rš!§)S09﹟rJ­ñÊÑhbø §š5f*£‰b^Q}y8˜AAAÞƒ¸¸º-Uîhø…íg³ÎÉ…ë~kà>ÿ8cFKÄsÇ?KÇÌÈ8Õ¬1%§‰bÚ(¢‰bÞ4=/ä   Û\¡ÛLP÷ p^Àÿâ÷ë‚<ùèKqh,‹¡&!¢EãÐ8~1æÊüŒŸ-ŸËõúÏß&U“2#£õi|rPPÐDÁy àôŸP€û;1¸ò( …ïùò×-÷5NpÜ &‹¨LŽŒÌÏ–ŸóSs“Þæ)7¾„‰/8ïªñ¼-Ý <((è6UpÞƒ‚‚‚¾‹ÓÛîû¸ûo¾"øÏÜßu¶€)|óƒÿoÞ)ðPëÙƒŽ»÷<øÒ÷€‚8j¸ôœ£ ¾lƸX“û©8ï~é¼ûÖ£+GÙÊy2.Ãb/èN>çý¯c° “o¿$ŒÛYÁyº]À&(è‹f’}ø—ßòóú›Á88ý§ŸêÊûŸ yÃú¡˜ê´á¦¿½,Ôÿ,¸ÿ¤À ¾ù!ú;ɺ?ÉП&M*²hFÍ(Ô„ÿûš?gCí²7àQÄQ³QÔ2ÊzLÒ‡f¦3{Åëi¢˜&ЉÛ1TŠÅd%mÃøŒñAwÐëöãÁp!R Ò"Ѳ¬3˜ g&ß>À{P÷  »âû-äJ%ãZð¯õÍ–ž!òÐÔ‡ýÇî{·[È›n´œ{¬Dÿ´çøû/÷sõ·ŸJFoBག¯~À?Ð7û¬ùS¼|ô$tãÐÆñ‚3ŸNÍxôÞ³¡wÉÜŒFgà•:î±k•=Æi‰S¢V ßyÙÑFåô8®Žø¤¾µJü‘ðAw köýÄQç`H€s·ø‰.ÈצpTæ!‚Éþã_œs ¾&oðÿù(Äf‚‚‚‚þ£PþçˆCÕ‚ÿúçk>…4{=V)Ò{jÔ³€v».'h8û£îm ênS8@»kÁ5(ß2,{Âæ±{pâ’¡ùŒàþgGÁ4 •€»BP•‚‘¢m"¨áÅÑSi£ˆÚ&hãøÉÓ¿AžM¹1ß!Ó3ÆÓ’±)qhbÝ,FÒÔŒ}ɈW ‡¦jR|ãp‡­kî7š%¼”áµ ºƒ@û#Á¿‚­Á] ù8 8ü,`Ø<´:¢ŽLjIâ_(Tä)>yŒÉŸ„<×#µ&W@ñ˜cÃäuâ¼Ýþ“Ap݃î*€þ> †bÓ}p_ê—‘«Û0jP*_ï¿}å{¿r’”‡ÈC¤0™¦Œ :É¢=á|\u!ÜëR°-ÏÇà4¸l¶eXD O” ¼»!¬oŸ‹vûÅ.Îs çÀZÀñãö‹Ü÷( =8·tÝU÷˜h¾ü‚Ã~kóGiZé ³ßô1ÚÒê« ñ.ÊxÆuÉXwðnbÓ™–¬1¦dL‰ÅàQ8¥ùÝc?Ä?ò;ø±Ã6Š¬Ê•¶sÞ{ÃðÞ º\«ÿû1ø0œjàt'§%°g¡ÿ|èý²Ìo$Pé”*JÑ©#Ij(ÀG e<ú²/Åù—Ïü³r nX™ó,p5p.ß/Oþ,Åô|*¼8Þƒ¸ý¡ý/»™1C±&æmô@ÑýŸÆÝÅmþ}¯ÿ8PîŠãîXå el[!y×€k–}†¥#ÓïóQ9e™¶xø¶…¢¸Çgý[ïŠsÊç•[ÿc ÎÞÞ­§ic^sÖ÷Ѷ OãcöuŸÈ´´&ÂC«#´vŒÍÒytK¬òjгš±+û’VEïht-®»›¼Û¶‹íZC?‚7e÷!:t;]«Ÿy >S£¼‚$ãæ{™Ì3•Q%)•xÏ“)QÑÊ]@£Ÿ*É?ÓÏzØ1ØïþÑtóö€SÀx¥°¹AežüÎgúýà¼p šö;È‚Òø‹C}å•Î9§X8ñÞ{;Âëºc¿Ù½ 9…\ŒÆ@uðù“ßõ0óà»aÞwÎŽØÙTìíAæa:]÷Xÿ؃G;š+Ò±€§mÁ6 ‹k¥§ˆÁ dćy3dSpßÛó˜xãÏø¼Þ·w¸/ß}úÀèƒêyü(È èÁlû?p),.ç{é}hçxõ ¿«ƒwyñ¦?±Mä[¦*çulá¸Ìlƾîëfá¼·:Â8ËX‹ón1‹ÈŒšÉ`b Æ”4*Æ£PGÕ7vâ¼·¼+ÀCo¢³.æîG÷Ó˾ñ Ï&¡/|ÐÁµúÿ;Ÿ{BÀýÄ.ÔâTœ÷ˆ4ì=¿ [P§‰À{æ¨Ò”(k!º•Ý…o Þ‹§ƒãó7—qÈËÈ:xß„&±¹!ÊZ|¡(.?Æä¼§ ðÀýM@î!j…z«¥å*ò~àš¤WསĤç±i­`¤‡÷î÷ÞøÆO㦫 .Óàý¢ÌóÑYèôÙuyñH4ƒå&¶9Á&ÍÃ'¿ö¿/yÕ½8þ RƒÚ )`{rƒ0Š!2`Œ”‹ø‡éoå´i´ˆÍÔiB‘L €ñI¹ó´ù™~èÜ»;Œ8`ÚýàHçð®S‡Ê=þ*EÑ;Æd'|€÷ /ÜJ>¸îAwtpÿ={¨‘«’d)„ÈQP¥r‘©–àN,‡¢3Nu—~O,ìG·€÷(†R{NÍwíl+v¶;›ŠÔ‹ëžz`ïë.C2ÚÛšþв¿7ëòî=†¥cXzÖà† ¿¶/¿þYgeäùì¼·­\€_õª}ÿøþíöÞÿ|à¾üíÚ‡èÔ¢œG[‡n:qäfÊ€=<І˜Y›¡Gãcösïç•ÑØP»4>ÆbpJ2,=FŒ¢•KÙ×}öUŸÄÔ›Ñ=sx§§%#ÓÃzqÞÓ¶¢¨&XeÎ{EŠGaÆ-3RÜØá&Û*ÚV¡¬çз]›iš8ÆÆ›ÐîxPÞw¤´r¾1¢ÇUœMEÚA{†ÁBUœ2Fb]\<‡GO~îVŸç’òò–JW¼­ *å†d”€é>2àføT- V«,¥JSLlÙcnY]<ç˜LšõÊ\7ï\3CºÙ¤Ýü—A›G´yDœ5ƒ),F[ŠÉ1&EøïA܃îÚº+HËMà¿¡ûÜ :pW€oÀ´+à®éfNº½,2™1”лo]é6¨¦+ð¾ÂZƒÃÐ3,b3Åг³©ÙÞTìljf K€wPÍ/bÖwà-8Å_6Ù¸‚ý›vÎ{ÉZ!Îûf—uO/ö­-ØØHðÞwywÏŸQò[¿4bgÇð±ÕÜûÞÉv~˜~¿ß£,c¬…ÉÓ7…2ÔApG¶ã,*ñ¨Â“3¥!¦!¦%Â7 S[žÑûU«ëÈ™2±qÕ×S¦Ã\ž³+Þ×âºïë>©®±™tVÑè˜q±›1 La6Ëhâ˜I[0±Ó8'š64“ˆiTð˜Ç¾¿zÙ½ÎûÆ#vq33ç5maë÷Ýwà=H>v/¢S-Tpü¿m1¢GÉ˜Ó 1Ø…ën[C§T¤Ô$84¯,^Ä&?qàù®ÜªÊ ´/r3ZiK²³©¹Œ ƒ,=]Þ½Œ܃'ÿ¤“J¥YäåïW-?úûPÕKêí†÷çÜa^Ϧq|ô£%ßû½°¹éØØÐ\ü-ëÿþâÌy´‘[ë*ñìÚbfMFÔ¶üÔæ¯“Ra°âŠ;EãbbÛпnŸ¤®¹äÜc̬ûà/ VËÙ˜Yœ1VR°ÚúˆX7D³–ªJ™éLà½÷½hÆ1“wÞG;\×ÞÞè_„©¯"Ù­YûÈ)¸i{l½û8[åq>ôó÷%¢eJ.®{ ¶•»?•I™ ›…y¿mþ'?bÿn¼Û1t º£@iI[:™*ꘌ…¨(•»v‘) “¸ ÊÚEÁêÞëQÂÈö˜øâ€û¾—)mÖ™!f9¦ òDæW< ¾)Þ›"&Ê[\®q…ÆhËŒ,œÞƒ‚‚îŒJ´ïlA¶³1˜ [Üóï!›‰X–…P‰8=êº ȼ0”®õâjlE?Vø9¼ïs 2Ó‹Äš»îMåP óèÌ´›H$â¼—†shï\÷\-]÷ÌC™À^ÕˆÛÎ*À+ÀòOõ}Y[»‚~íÃB7‡²0±‰Èüü³E^1™µ }÷^¦ö¸†j¼îÐ륋cúéOïsâDÅ9çôØÞ¾}.¯}mÍÞ ¹úêãÜãk\ü•¸ª[Ë(¨byM»»"ªö¨™—u›â> x§…¨i‰hÑ8fdhïhmDl“éNiÎûÔåí_Êî|7ûJ¾6 ­Ž ‚j– ¸·â¼·>"ñ5Y5cVeLbqÝ'mÁØ•$“Šf159ÓÞO}ÍÄÓ´q4IŒM ¶€w±Æ§ çµÄf<”o9Êøá¡Í“Nä_OrB‘\ZËœ2›X 'oçû¾øC¼ã©]Dg\«iÛˆI+ð>¦\tVœ÷6ЙÃ;Z±ïúœÊÁY³7‡eE:‚ ÿŒ‚ët[IÝgFÿ«@]xðó—_¾G¹ [Ç`{s96†°9÷ƒ‘¸í£›‰\˜¨oé~Lšn´‹ÇÄ:±¢P¸åsdNÀ½C‰äÞ‹ÎuWS+ϱÏbô¥€Ÿ»îÛÝc¶â¸g òÈŠ+^7òX50uË¡àÔΣØZ7¬­üƆ+þMñê×)†CG¿×vÀ[›ÉŽ+¶¿…ÜJ˜ އ?ü8§NÕ|ò“§ù‹¿¸’Ç=î>ü:~ø‡ÿù—“ÿe¯û;ßÙð¡íqõÕ'Èó†ý‡ï€íþ[Iühæ¡êÆX¡Ç5öpŽBJJ-Ú9TíiëˆY“ñä­—¢qTHœ`jslWИ˜J¥T*e¦2š1ßó‘×ñcüæÂ}éÕ,eVeŒ›R†‘Ü{U¥2f)c[.b3Í$¢Gâ¼×9Óºàªû=7Õ—éÛ:¢©cš:ÆV?QøJá½Â:CãcÔÃ=åÃüúÅ$?V¨«=E5‘yk„tb) ¨~è+ßÅÈ9ÝÏmÉŒŒ â€OmFUÅT£¾Nn8ÆI‡ÉÁde`r0½•QÊc”ì7EL[F<ôUï`šä‹¬{&ìû¾äÝ»ØÌ˜’w—Ǹøipñ¯Ã§þ.ù7àSдØU€¯€]÷ùp©ç=׌\‘ë±ïúá$¹™‚óÀ=èö÷{žÄdšÍµŒÔC~L? »»<`À¡-Éžçë­C¾::î&ÿQ÷ذlŸ`åB·ø÷CwÚnãt+¾…Rô{ýX6Ý,Ô]l¦¿%àÞ$ٲȼOìŠóÞ-€ÁÝÅy/§4~Åu—qêäÒu”°Ê¢Û·Új¦‰@Í«W ¹ç=>”±ÞGœ÷\¥âºë`c¦“–~¿å¦+œóâº{Ýeèè©ô›G¡”bc£ÏΎ擟<Åõ×O¨*KžÎù×=ÉoÿöÇyò“ïͬݦ¯óÓžvo~óiNž´œ<9áÒKÄ¿þëi®ºj—«®Úec£àÚk÷¤`þç iµ9b…R~9‡j=Xð­ 62<)}9 OEJ„8ðÎib×ൿW « V #¥ºØó«Ñ3 ?{ä¹ÕD=íœ÷¤¤ñ1¦²ÌfÓ&_€û¤-p­¢Ç4ã˜i_b3L[\I\&ZFflm°‘Ai ó;¥ñ…¸ïÞ+¼UÐÈFSã ü]]×ÄàØ‹®”ó~>Yh²˜¸hàçuìèÛhÚ&¢m#Æ­,"Ç‘­>¿üq&ö4 Òx鼫´Ë³ðÆ`J+®{›1ÝIë"j•`#CÛ‹˜ÄmIÁjš2u9ÎjF¶Ç=ïÿì:™†»{~ °T€‹!.@ò7´±, è2ø$Ë‚Õ&I³ ›òüû®Ï¾ðà=((èŽîç\ ‰bØËÙ\n˨)‡6akz¼ÏÞoÜPKpŸ´»øµHEV»ÂÁ“ÚF†¶‹.3ƒ¸`+&»~²—¾-GÛ¬„lV÷±…‘!ŠÜ ó¾½âº¯•Šé®¸î½LZ·ß¤ZÕ2«º_r¾BXôRs`4¯ûWñ⟹˜³Ï.ÙÙŒH"¸äRØØ†6§O[z=K¯ß²·ßtžÝvžÞƒúཀbc£`có½­yï{ ø@÷àœçС‚ª²loç|øÃ»D‘æèÑÁçý_vYÅÿñIn¸¡áðᘵ5ÃÖ–çAz/»»c.º¨¤ªÆl|×ý¸â£»Ëvr㜳~ý®yÎŽ¼¶Zb% ûZÙ³x«àî[Ùä%ÖÀ];‰Ìx£0Jœz‡Æb(ôeº¨Q„8ž§à9—ü/ÈžÎl–1.;x7%‹IgU•.À}Ü–Ò»Hè÷¸Ç#¯äâw^À´ÎafñÆ`AGŽ6ŽhãWi”òêóf•JáS…wJÎÛoý(Ÿw6|ÚC3~ÕaÒ¸‹éƒÅøêç]"ÅÙî ¼ÏšŒ¸ìà=c‘ÿž7½ŽßyØc[#{ ´r¾dã)L¬ø 3`ì KÅìˆæÅ¡y×Ò@%Äeƒ)ÛEæ]wõüuÓ¨XÎÙ2bšä¸T£SÇ>}¬7`á^x7z™zç}÷ñÞgY4èt­†tþ Ýœ}ÏáÅ|¸ø²…û® O}:alK÷à¼x ®{ÐÜw.•JP§–)›Cøà7ÇXt¹þ/áú}xÔKÅqÏ×!éÃïš‘ºŒÙ|‡ÓdÅ}oW†Yaá¯ÉáïwÅyWvÙi&–Ìû~‹I½4¤YÀ{ U+ŪÓÎuxŸ»ï†þ¡el&ÓPjø“ªù¥¯NØÙTÄã^hJhGª[RÝRßã,Ü—Éï¸È¾[TÑzöÆž§>ë|þõ½{œ}vÉ?¾Gwï¤Ø³ßoé÷dì®d›D:×}ñ8îà=ccñ±áØÙÑ8·ÆùçC–ªÊRUŽ(Rœ}vÉÆFúy¿Æûû–÷¿L+J0F:áL&†Ý]Ïî®çškF<öeßÄ;Þ}ƒD~lþÊ:‘nq#ÅÖÿ{šã/‚×(,<Ø?S Ðñ­¸Õ;óÕÔ6!2íÞq² ¤q£,8ˆUCn¦ôüHHÃs]'˜J㢚¥Lë|›q%®Ò̪ŒY•Ùvð³:£ŽðµÄbøÆ¯ý{*þ‘ñ%ÿƒáÒ}÷[uŽ»ïÖWJàÝ))4D-ÏßA§šY—÷·”9Ú˜ñ›. È]DþÙ÷, êó%¼7ML¥SŠ|‚)­ü_ï£iIS`³ÈOÚ‚ZCíadádÛÛU‰ÑÐd]î]Ã(JÐ=‡éµò5m7¨›„Z%´i„- “¸@¥:¬7Xo¸ß¹¯çÆî<^eqƒ” iÀæ ûíªƒw=o‘›ÏäÜ7™]8ïM!›•Mg9#Õ[Dg>'>ùçcLøÅÑ™&À{P÷ ÛÌkÀš‡¾‡ÂAaðoѨô£í‰«àQ÷抮¸'pé£VÆþäYðox7)ŽN—]5o52Ó¾u³éí«Ï‚wž-…¡e?aà VœR]´TÉ·õcèÅ]Á*ï»ë>Þ9 ÛÝÏz ÎY:ï¿ñr :‡‹2žöVo÷`þ×wÆ Ja¶ñé–Tµœì°Ù‡ÑYG¨þíSKË-JX_‡µ5…{N=gŸ]rãZÀÝKf2Y‚{¿gIâcbâØ“$Š86ÄqÌ•W~yþÏ pߨplok¶· CÊ©*G][ªÊrøpq›Àûõ׋Û>ßl¶×Ó´­§i⼟< ǯÝãøµ§–Á ÏÆOZ¼WÝG0ø‘)û¿¡èZÈí;˜"ñ’î5oU$0ãbSx¥½8îÊbœDf 3¡ï÷i|,Ð>`këxòÆKyÅUO\dŠÇm‰®Ü"ï®[·ˆÌœî§8˱é÷Žåy½gQýXÊS^üb‰Íh½wïÕÞ¯:pï¢ÌàÔ#€—ÌäÜ®#h­@ü7Ëøo?&š;óµôÇ`ê¶Æd^\zk‘ßÙGmtË Ò,à}°‘ÒïŠUWljݮX5–ÒW½ê:BÏV~ÖcàßþºáßFŽ¿ùˆ’çÖ]6çÁzŠ~Ä“~×ñ;?$—Óç¼ÖBZ@fÙèÇ$ ŒÎ<ŸýÀè‘ÉXëÁæ¨1è1 Ãø&yJ'{9±wJ ½ß·¬¯{Î=7Akö8ŽI’˜éÔrÝuî¸ ¼vv4ëëÙ-:ÍøÛh“ÏÇ“¸{ÛÛmëi[Ïæ¦À»¾Ï½yÇ»o zÑyäºÅOZœÒ8Ì]¤pF‘<¡¦½1’×|ÅyŸ»îºèOhš˜Ú%ÒUÆÄÒ—Ú8Œx×Þ‘ë)-™š12½[Â;šˆVzXÏ]÷n¨§˜M¨ªß*&mÁÎýod‹ã(< ñbÇT`Q4Ë´¥ãE?÷y[È…ã>/¨˜g³  œ‚„–ºi¥È£ƒw&š;óµôe#k¬1#¯à½UÌ|ÆÌdáÝÀ´ÍéÓ:§iÀ_ößœq 3-k<&rí"õ Ç®‡ü¨tÍR]GÙI”P· i¯"ëIŸwÝM›§ë’&–ØŒ/m)™÷8mh|ÌiÝÕÔ·2õªX?ð%¨A÷ÜT.­e4qL%²”N‘™:N°' ÓYÎX—‹Ìûs‹7ò³ÓÇÜê1ÕûÒÎ9êÕ(! IDAT>1.•÷Q3ˆ™­eT>½KGÞƒ‚‚nÝÿþ–™¶µàæÃ‚Óà ‹Ñ[ÓŒbxÆŸ]Å=ï·Iê$o*iªr 2ã[ˆ»mOÛÕÛÝã´‘ö húë^vŪ¥ho{ðŽ?>D>§üäO!qVn«NÿWÇpåiˆs˜UòüÆwyDZ(†%<é‡÷!Xë ë}ˆéê×0ª×ôa½[ë '2ÔŠ6œ€pÓXz}K¿ß²½­iš˜áÐàœ"IæðqÍ5Súý–k®9›¯ûºê@lf}ýÖ›)uÛœ½ž^8ïiªh[ð>)vw=ï»núÁs0‹ÓâNkåðV Æ…dØÜ ÷~_‰óÞåÝ/ºà£TmŠR~麻íe3'c,&²$ª¦uÊyf:cJ¾wë Në…knœ]8î“¶ ®bÕpü¾[”—imDôˆ–>û8§«RöýZ¦Øe­HÁO>íeüƯ=¼Z8îxFeôÍî8u_ÿÈYðãwÐAc)ÅÚ× 8õ®½0éÜÙÀýïŽ-æ5›Zác DQ‹ÎÓ:gÚæT.e– À§eŒözL¢‚ï½úµüæðǨÛ{ TÔ¸jµ1¬LQ—(8r9œùåâÂ+£¥ d›`ËH\÷r™J( V ªô´½ˆ§}ø…<ÿŸÉ“ÏcŸ.yèØÕ ÀÏÁ=ŽäüÕó¡;pO»L£„:O J§ xÙT]l&]v›ù÷rï³ËÄÆL"w‹µ³—>M3¡`æ3*—òâ¹ÿä÷¼×=(à~Àñ‘T²Ë‡[÷ž%³ŒAº³HJÈSØtŠ{3Ë¢ÒÖ‹¥ƒïvE’+BÛÈ®Ú_q6‡‡ ³©´uLLf+ MQu M ­ã@7\ |ÙWÀ?½‹(6 º¼ûªë>ìILÜ9xþOÀëÞ ßÿ+à>ß…uÞ-ć†4“}h*ùDîÏ0/¨kø®o;¹w Kð€¤¤^ü Ç-œw=†sÎi¸òJáÉØ²±î™up¬ 8žÃ{Åìïï3´ìî:>ö±8ë¬cÖÙÞþ¯éÞ¤È9U[9§Ëp=Ãô eé¸ì²38ï¼áb—Ú Û_åÛŽÂ Æß*¯IñçÇäNJ¹4$\¬iMD«¥×ÿ¼ub”È&L³Vœâ*€O‹ k £QqTÒD1“¦àOy"ÓÜýÕ2Î;MŽ»…x®`’vλ‚*×½nÚ^¥Æ”N"3“B6e*Zj•`J‹-%:óŒ­ç1öKpOo¶Þì¦5‰ë d,ཋ#ª¬ûê”:O¨ò•yÙ ­Ë»ÏfzæÄy/—«·ï'¯(Û³‘üà©ÔívOv}ÍLeŒ|µO˜Pð×Å3ù–Éó¼púâº?øÜÊç?}¸¡,NO§ÒNe>:`_ŒzC1Ë-0zpq7áŽ4NÚίZÑ•‡Y ‡6c®½’…û>™oÌD#Ž{ÝÁ»5ïN/÷¹›?mè†~¬ÎûÞ=w×E=ýUKpch&+àÞ,á}íÜtºZ»ç=É5à šŠ/QL>Þ‚)†…g­ôdN-À=÷ç°Þƒ­µ%¸«1 dú}ØÞÖ´í2O^zájKî=b¿e0h ,QäøÐ‡ ƒÁUôûEaøÊ¯¼Ûö|y —•®ÁÃÝÃócéÍ¿™ et6üdܽÂ×r}Ô #î¤ßSrNuÎû½¾âTmJÔ´Ä®¡qQÊóä—✠RÉÏÚG²³SKŸw/À}ïíÂ}Ÿ4ãFà}¾h“H6‡òÈ¢ÁYÙ`‰[ÂûÔçâÊÏ,8…÷x(=Aå?êþf£(.˜ˆûïí^$ôe—^ÿàÂ}–޲Œ¸š1GŽHñª÷÷ûŒ¯E€ûÛÐ?yTú°¯ÆûTGÎS!çòõGÅUoeÁ¹’¨ÂöÄu·Úà-uB‰l66K2¦6·¸ÛÍ´É¥0u_÷™Dm$-"ýÌSg௻/?~¾­E«e½hI]Y*‹¨‹%¼ ˜LOàýtS2ŽKòb*±™ž¢íIѪO¡5’FÔû]-P7­¯¼ÊeÎôÉ»Ïc3ZÎäãI]Påð*÷ŒT6Ûk ѬeZåZEŽüÁ¢ÕköA>Q$¦^¾˜€-e÷⊔Z%Ò‹^•Ì|ÆTåübñ&~qòÈïA܃îÂÐ~ÄIi¤P:üÇ—®­ú{(Öá’W¦T£¾~wÅu¿×-áÝH1èj#˜‰¿xï&ã8Sôci¶g–Ð>Œö0 p¯`âÜ[×uq¹™54iRó.Ð^*Ù`©é-3Ú—|| îeý5¸þŠpïrïFð€›šÞ}+λƒáFÎ —ÅÀZ“Æ‚†áfÄZ!ßW Î{RwŠ&°Öïœ÷‰BO§µk=ÖÛV7fyÚïø(<÷"÷Qwa‹$F¢"èGª‹tÍ·¡ÚïÀýfðÞïE‹ú×ÜÃï¾ùx¯ˆgâ¶ÏáÝ™%¼Û[¨Ûä„I³pÝ+±™ydÆ{¸ôãò=ÚÀpîëâÔËÎ'+¿¶#`ÓÐ4Uw0Äyä9ÃÜãõn8Ú‘ë"3²kª3óÞ€-¥ÄZÑû^°z½e }{[>ŽÕÜÛVîx¯9yR2ñý.¿¿oØÜÜᦛÆ\|ñ ’Ä`Œâþ÷?ó¶;gú´ç¾+ÜmÞWï|X0±ÅlYêË’E‡LWu™÷qÞÝjæå–ëó~þC>%ÎwkÑ8Sù¯O9÷%ìÓ§!žã­Ü=©ɼgâÀU>=›Á³ˆÍD´âºO5ÖKd¦:œ²Á.U›’´5q+űÊK1ªRá½V _ðµ?ÿÞùì|—Â7“ѵ“xÖ xRÈ"˜vî-«{vÕ3†[ ÃÒqÆ–Aßm†»Ú.èpkkÈÃöqþîï.ü‚5_l€¿3=L?Ýçìâ*J=æ>|„gÝEãø¹÷>G^“Ùò¼.ûrÊïOeÞëÁidìu_· .ը̋óÞ¬’H—®ñ¤”…e›Që„*€ŸDÅb÷ßqTòÝú‡è‘Ã:hSh?&Ow§K¬Áeò˜Tï³Ò<¦Îê8¡õ[ Àg=é23‰ fYFœ7ÔQ‚éYÚ^D›K½´›AqÓ²%}«ºí$WÝ÷ÀçR¨Jç¼Ï»Í(-óÿxO´*÷Ôy‚É­áêœ¶Ž°­ÁVFîzÙ[ÆfÞ—?‰üxÌa®“÷ZÓÝí˜vó|qÚPÇ qÖ°OŸ=&ª ö Sr&¤T<©x/Ÿ<(À{Pp݃îÜÊóë0fñL ¸+àuZ&Æ×ß<#–w®v¿ëbgT𯹈j¯÷ÑAk¦·#λ­—\bj´ÒIcô±4¢)º±öÜ÷¯G`=©–ðÞTPgKxŸ­šx¼ïc¿WvP])Xv®ûÞ)øôÅm ´7a°{§åçV+¯¬¸çÃ6šëw+é%o<:V 3Ï ¥e³¦µöÆN\÷ÖJÙ:_,´DL(˜šóí)®öò÷/ViÝõzïà½W*bjêQS/ýüMRÏ–=†¥çŒÍˆ3¶ ×]½×9ï°µµÆáÃ1¿ð WñìgŸý_~M¸+ÁýúÞ9ôÓ}Î?ź>É»$È]–‘ïñô¯x/ø³§pß{ëB´ûS°š%°k–u2»•-ÕNJ›Hæ}ïë’i"Î{£cqݳ”±’ÈÌ<6îìTúÑwIÑè¼Y×â­’Ïäí;‰…¶ç½i¬Šh{[L)]fÆqI•¥$YMÇÄeñ§]¬sÝ‹²Ç—$ùΉÞéà]w±}óØŒ†é^ÎÌdèÜ-àýÐæõ\צ±1ÖüL‰ëÞö­"÷]Ÿ{§¿34{ì$7âkyo«z8C¦ RP™ÇF†$•MÛÆ¾d¢ŠÅ°)9Ú9yç=(€{ÐAÎyÞúÖã¼õ­ÇyÏ{NòÏɃIzpôÊë¹ðÂMNìB¼¯8õ’HÜõ)‹" þøû…ÙG¿';ŠÖºƒ÷nTcûÝ.¨+ðÞ?S`¿ª—†¢NŽnî¼wYbuÀyÏYÂûîÕ-d+Ž{]ì‘{È xïª9W3‘úÅ­8ï}÷7¼E²ïà ö9ÀW';xŸ‡Vá‹øËæ@q}]“?n8Hæ0Ì=:P_+¤…Ú°X~Ÿö]d&Zæí7†’{Ï$­€»µÒ¯ykëà뙦Š4=xJÏh”Ó4çýƒðÞ¹ïºrØÈ0i fi×qÆJdƹÞ}›ñ×jÜLú¿Ÿ¼÷:I[/÷¸mÄqw,wnÙgsBÁØ”¸F£"ù[µuÝ"E-àÝMïL/]<¬b4鎙•-îí¯~Ã?ü(ÃÒqhËphÓpcÀ³½Ýc{J8|8¾C^7î,pßß=³²kØö7¥-1 3JÆL|!‘ Oú¶—óòß~’ÄûR™×¬‚¾ô ôÔ-¬§ºÇù©ñ~p_¦ñ©¢ÕËn3³IÆDËy9³­‰± çý ï%“Sÿ͈8’9kڽݲù[dïQîqߣ¿9ÉM?°-ñ#‘Û“Ž3ãQÉ8*™åIVS§ _óÊwáSGk ¸â1¸n=ÉÊ[RgÒI†Î}g Ylf2–ãW¥):uTyJ”·ÄE# ¹ŒÖF¨™gd{‹ØÌ¾—Üû¯éŸ¦ž&ôüHæwxØ·®¥Õæ¼mpq&îûŒŒ=¦È¦OSr™&†¦‰— ñ¼Ý¡ßôGIo»°Õ9>’ yØ>ø8ißµp×í ¼+ນCAÿÓrÑšu®û|’Þ40Š»L:‹bUq»fÞU,yóñ©Þñ“eèG÷9¼â½@S‹³[¯äÝQ+àÞ c–λ™;új±»êªëþö¿’/Û^÷ ‰²¤ÞKTgB›‘EÆÄ7Zœ[w]fR¹g˜CdåkÖJÈõ223,<‘‡ÝèÎÉ.ªk}h4”‘¸^ÖÊ︵õÙÝ¢„#Gz]&Þ³¹™Ò4ŽºvÜínw¿û€#Gþc[Žâ§ùÄ'NóOÿt?ó3bø¹âz{OKÄTɺ&Y€{Ô´dÕŒÙR~êr&¦X¸îÖé ß¹îÚ:¾çÄëxæìùؾ¡‰ ~ÅuOš«Í¢o;Nþ>¬&¯SEÊÈôðë ¿§äkºÅŒªÅ¥÷F¡iUj+Eæ`<õ‹l[á°t¬•žÍ5Å[óÜûÖV­-ÿ‘Œ¹Ï}Ê;•)tG€ûòÒ£¬O’O§˜3dwŒKÐ8¦^âcJÙeÃcäõ¼þE¥WÊk÷G‡ÏgýÔI)¶ÀÉ•…ë¼’ÔBþûSöž:Àƒ‹ô"23Ö%U”2Mrld¨Ò”iœÓ¨˜A¹Çã.{5n_S#¨ Iº¸}ïÞCÒí^J&]{#'#kej É–ÛX\÷¶4ÔIÂ$.Îû,Ïh³HÚ«æßØ»íöÁóËaÒn¨LŒJ¤»Nÿ`·­a2ç»JÞë<ÁåZ/UÆHõ°­¬Žm¹(XýÀ³ï/…îÅÒ8’m~Má3µ ÞwŸd5{Ñ€(j±Ú0R=Æ”2/T1Í$¢m"±w oÞ>ëÎw(\÷/ííµl®G$=ŒS{ ´÷U¥À©]wÇÁæÁÞ‚2 àÚ-¸ö&ù¿u®»³Nú©bÉ'wðž ô{fŵñ`ºLÇ7+Xíï˜[8ï…‡7¼N‰뮫ƒÅª«®{ÓÅ6|*]gæ+o¼ü|̓¯X8ïÃ>|ìCpê$œ±&[‚û`¦³Îñ÷+ðÞ-hÞþ&ø²_‚­¡xo«®¿»€û ÷$^2ïg2´­gc(}ß× ¹Øf¾»0vm*7ÖÄyw1´½¥ón­8ïm Ñg™½77SœcÔÜ›ÆQw»[N–™Ïù¼ùô§GÜtS…R°½qäHŸ³Î:B’ìð¶·ǹéÊrÌKåí¯P;Ù‹½»°*-1ªùÆD‡²¸»‚P%câ4\õãÛ]€Elæîñ¿ñì'ýÍÔåR$ª$Ö¢ðgŽ¼Ï UójʬʨLÊ´Íàó®]dðsx|ú*ÔÔÓD1vf˜“ÂÔbÓtáº'mM§ï]l&©jld$ËÜ©!fdzô·ö¥Û;ÂW];ÌFröÞ(úÛŠžñT2Q õX]¯Kª Kϰt]tÆ@4aP¤lmÉ¢nk Ž9|X-*wø©¾Ë\{¾€_¾ý(ñ=¾÷A"X˘ƒ¥%bìKƾ¤UÑ¢€™‰ÌkýŠÙ„8j »o0c+‹×ª›7fâJ“H;ÐÖD¸HKdÆ—LLA¥SfI†K´ªª±jˆh±×n8~7þÏ«IºÝR–µ²ê¦N›+|æÅy·ËØL\/Ô¢0Ô¥Z V{Uœ2Ž%63wÞñwo&V ¾– ™ˆÁ&`õ²™Ø¼»‰ºî±8ïjÞmfe“&ë¢Eleî¼×Yï)L«œq,Ýf’ªfäÄyϯ>XHuÂr„Þ›$FgŸ)TîÑÆ-Š£´%N²hF¬ƪd¤zÌÈiÆŠfÑ41m{çÄàïAÜïbŠ/°k†Óï½åÿ Õœïˆl ýÖçð>>Ý@3“^ÒN‹–YÛ…ëîY´A”¦ÖFÑxߟ6ïó‚Õ˜û›] †ƒy÷4†Òx̼÷#%Î{í…‡Ì{ÚMËéºp¿¹ón£%¼w- ñÝ}]ß¹ï]û÷'ÿþ=øðƒGJZ@^q¹8Þe!…UƒÍ%ÀßpµÀ{âÀÔ;SKËK)Ö  4›ʼnë+úk1à ™g˜IùÀZ þlCÛÂp¨¹÷<wÝ9wk;xB¬Öú›Á»ú¬à>×övÊÆF²÷ùãææì^ñ¹ç.]|çàСMz½3yÛÛŽsÍ5'º“@à]kp?šJ‡í»;]®Jƒ_éᯜGµ·®i ‰{ÈþªžŒwé \ç3ù)#'K?âOúUF®GåSwß<ލmÙûKxïVªòTUÊ$)ÞmÁDËØŒÕ<éþ/G5^6}ržX7\þMçñ©íó07|ä•oZºîòÉ”ÖEï‘´ªk£hïNkÒXnŒÇj›™Ã{ïôŒ’ØŒ÷½CoMÀPá;x÷]tFrï½r îOü¡ T%Ûe*#U‚ô¾h®QÿY¸/ÿ(\ÐòÔ _Ì&^ïl6£ñ1“¤x'Â*ƒõ†ozÊßrÍ[¾‰—$÷eSÀíjšZZd™Ö.»¡ÄÐè˜8i …íÿ}×ÿÀ!éŠ2Τ¡.©´tœ!Y–I,‡†o¹ê¯¹úÑ 3{5Q!ÛÄ‘¼½æðÞ ¥"άÀ»[ŽÖDèž“Ü{›@ެ–uœ0ŽK&q·xÈ3bšE“ð³%¼·Nâ2Q*拉»M˜²®ãLîó®3JÃþžt|™úœY–aK•§œ÷±.imD:«›’¿xóÿ%‹÷îÎ-®[¥`#C“Å$Y-Ï‘ƒŠ=*õ‹Ý¢’¬&15±oí"M­i'PO"Ú:¢µÞƒ¸ÿöÞí`×C—ˆìm0ýS;-³0,DEB˜ª¡jo—É€ÐZ¸«$‹ÓÞ6|ŽˆHYôÿ&Zç¡Ä>Úm)ü#poOQs¯{šÃy·Qé`Z{/½´ã5¯PüðO*÷»J–Ó¥ïy‡$P¬dŠb+ ëħ¾±.Yïyæ-3v®¾¯, ÀÇ‘¼ÐÖÎá=IþÇ® cijHSó÷º¾Nœ(°Öù„›ÍÜ··wè-3kk1««Ÿ^®¤W»1>yǀ´C+ù;«ÎÑ­ì’–®¨ÖÓZM@Kl+¦“ "ͨqŒc[PÙxPÞ•xÚš±+˜)ÉrÙ$DuÍ´ÍDqï•÷6üîßñ¬7Q7‘xò­/*ÕR„ºrþ¢i  =¼/€»íäãîxò÷~Žd¡'Þ2ÊÚÞ» t(OU0¥¥›ÉÙïÒ(`éå=uÙŽÐZ¶¶bn¾¥S=8"Ò¶rF¬­<¹õ~“Æspw ö²œßønX]•O Ã9$÷–™ÖBlÅú[ÈCˆ—ýs0\_Ò¬/‹ï}9±¼`›ÉCØÚ2ttØÜ4¬ä°¼ÊνmfTôà.Cûz‚0„ë®»Ÿ(9p es3åÀ”4ýâ,å—^:"M³ÜEuoYY Y]•ÿúG·Pú¤"ã¼êîäºÑà”@|HC·nP‘Oh+œÝ;­ÒĪ‚Y šüÁŸBáØµ#*SÛH È[f‚®¥m¦mÆ8”Ί v–²Jïe+rßò˜·2#ŘNÀ];LØ ©8+ú<÷rCG‡¡©CÞtä;ø¶{ƒ´šá:%)N ÐÞ†ñZYB×ÑŒ!ÏÞk çÇ [k”uëb™) b›éàUÕ2 FئWl3‡6C®¾úy¼ë]%Xγœß®à–m, IDATçà®´˜ éw|.¸ñ5¿IEŒj%ݧN#j¢a£flG2-©ƒˆY– `ûG“š½ñsŸ£”À}ý†3âý^mÌá=–~ÿÐM¼ÿÉOpw9S=·ÍèØ2Q9ß¹üsTJ'x5Ãø™ ðµ±la s„}Áª‡÷¶Žhâ hå=,:¯º‡aC4Lœ:ˆˆ¨ùè릌Z8WsýÁe:•ùÍDà×(ßAU…{m3u#öŸÞ6SÇ:²4©Ä‰©Ô‰òžŠmæ­É·ÀíÌ»s‡{á½÷ÞU"i:µèÈ¢"'E®Œ˜6S›1Ir–€ÙÄÑNÅ6ÓÖM~E^Ëûð¾?öU÷¯€¡"dÜ|¸(µ\t‘{¾†<®*:±ÝíB¼qZZì½êbîHwè½/ž5ð¼³µêáöWf¢¾Û ÀÝzŒ[Pž}¶. ün—Ìš¹ú¾›@ëjPÞ37·Ó‡~Gn`g,ð>ò ”F*ï%´G·8 gvj0>ç½J„€ÃJò̰ު!òþêdK{O œ…[ŠŸ ˼úÝAá-3gOÏU÷(ï:b¥¼zó•´Nj:ߌÍÅHâËHiÂdT¡ÁæY‚HáR7ÀûdœC n¤å]ç–¶0TaL¶AË$Ìùží_àCÿzLnäv=×Áæ¸w±ô£Ð©xåÞ J Yö¶=‚ís¾Á>­'2èØÒ¦*s‰ç}V§¼ë“Ï…SÌ[¸ÂÜ6@™=ðîbE´bJl\2$Ô쪳&E'!–©£°¯¼ï}pß_ØqüRÀÍ|ÁžÏ´"}<’ÕÝÜ×Q. nØ)Ú]E»£¸ç¥ƒÊ÷ß n{¿y8Ÿ/”âSa ÿ·ó’…ÙâÕæÕ÷²•sÝO@`ÏüÕ‚eF£êì0ZòL£çŠù7ýè˜ß~µø‚{õ»ë ÷Êû䔀{f`mM‘$~ãÕûþÕHÓˆõ%ÍSžr4 ØX å}mY±R¼÷êûúºag§âãßáÆ·yÖ³ÞÏwN)Ë–é´a:mxá ñŒg\Ä3žq1««!÷ß?ew·¡ëIb¸÷Þ þç÷¢µâ›¿ùr.»lù z-Þxã7Ý´KUYŽIHSQ›WW#VW#Ø='àN»îfOã-4(ߤHW–¦ η¸Ùª»ÓÌTJ€ÄõÅTÄT¤Ì0tƒ}&t ¡k$‡]iª.æËŸBŸ³è™åÛOü2aÕPU1ºµƒò>kS®*þ’1C”þÀ´â»W’ŒÓ§ãŒØå^RWM-þç»üUüø‡ÿ=¶Ó´]€vEÙ]h°Fð>™D^¯ý¬*…-aˆêž,€{bªj…)Ec%ØãÇW8yRsölÃç`wײ¼l‰ãšªî㼫ÃòþàŸð{l³ÌžŒ@ªx¯LLm"¦Z¬3á´¡™†Ô]DUÆLÒœ’ÝX~ôÀ«1;Ó&£U‡ßzØEúáýÙVkZШPÔáÔ¢‹VV ÝÏ^yÕ‰W2Aþæc'åC¹‚u v7ˆ×žõX[ƒ3gƳfîÖ‚5\|¸ œ¨Üó5…åÃ1ÐîÂõG6܃\ tj¼¤ÑG*O ¾{%øÇ þßn¯ònüQ|ßVÏ/Ô¸·àfõÜ63m` –™Q0·Í¨Ð ûN¢"sŒ;нGy¼òÞ«î¡í¸äñpêdÀ§ wß[ËïrôI$aÃ(˜ò5L·Áµ{€ÕuIoYZš+î=¼×+еU ÐÍ>Yil©õuù6KK¾‹©’ÝSòßëk¿õÛ˼ê•#ªªãÈ‘‚#Gr.ÚˆX[˜rŽA}×ÚqýõšÆrð`BYv,-ÔµàýÆ·ùààMoºW¿ú‘<éIëXë°Vó\vÙ2]çÈóÛnÛ&Ž [[ÿÅ|ä>õ©ólm=Z°µ•³»Ûb-lm¥rùYÇæfLÛ:Š"âgÞ;…#þè@)_¬êUwmàe+BA×–êP p…êy·S«yáãßÁŒ9¼´ƒ9 2Ù{hož;ƒé$ê13SÞxç+ø~û:Ê*Áµj€÷+ŽÞ̘B¼Ë(ÿÌšD—ªEi‡EÓЊÿžŠíz™º‰ä8¾ÉxÖWÿñPØøþ?zÚÜ6’ß®4QWÃØPxà]ƒÕsËÌ"¸‡­E× …O2Ùö§OKK§O·lnêáš:{Và}y¹ãÔéÊ_änN¦®DéßæÞ}_œñÈG®ýƒ\O_Äo‘z9w›eªÕ]WÛhª ¦ ¤hÓÔÍ$¤™H÷ÞzQ§“8'ÌPZ¬2ëÉ¿ññz§ бMÒª¹mF§“vDªæ?ó6~¶ø^Q߬ºÎg9)C²­üý—5Ä©‡w¦•©Â梼“Jœj˜t„ ª:abrŠl,ðî•÷8—´¤ hY)þŠmÿ³Æx»‘!ê~oÔ#Ÿ(xõÝx¶V`cCF$A #‡Z’ÃX{2ÖUä0q'~÷ÔQñ››/†Oø÷‘^LÚãÕe}QuoR÷:Žˆ“ ›jÊ2Zí2b[-3kR" 1ÐLíå½iC.ýµ”Oÿ‹ñ>¼ï}Õ}üýÇ¿únX_ƒºn(ò–ñd6‡÷Àð‡¿ÿòE«ä«sxåSDx3I@÷’9W5b’ì4¼ïƒûþø2¯{½#ÀoW!ˆ•çšùº ’§»Ð#yÚ2åûN{ã% ¶ÿýZYt³òΞ¶t‚v~ò<“²e„sÏ»_#o™yù‹ÿö{EyÇ’O™ém ‘µ¸‡ÖòÎ_;Ãw|sÆ/þÆ!X>v VŠŒõw/PQFsx__°ÍôÐíJÍÆªâ¢sËL×ùþB»spHÓ½ðÞÏþÿ8ñôgü%Óñ (ËŽ••¿9’ñСçÎ9Š"â«Ê2ÖÌf-um©ënˆwœL:ó˜ÜûyìØèï}Ý;Wqÿý3êZòàÎ CÍÉ“c~õWoáå/(GŽ|ã§ßþmÍ;ßyŽŸ•"U×k窻rÞ'â á‚N·hÚ§ ;ž«î“ 'Rõ ºk{¤P;èÚÁÖÒÇKÚN“¨’(”ˆ¸ón…i—š†W>á^û'¯aÖ¦¬>þœ4Ûñ-™zpw(TçФŒôàÞÿ†ø`ÅùO­ ÊûR·Ã¶YÆM”´wŸŠên}¾½Uš®50±Zn»ExXÆDyW$ØgtÝ êFîô⡜ÁãÞrýÓag§óª»Ì ÅÎNI]·þDÍù#±’#GV8yrÂÛÞöi‚@ñ¨G­ÿƒXO¿±{;#Sµ rè(›ÂqS +±p-ÚfjÁTÚvP™˜ªß;!LƒŒý柄‹ÜÓ½d5ž’©®ƒÁ{ecœRƒmæ /ÿn\µÉ fÜ:‹¢hàI©ªXgZ#–[Ÿi« "E #›‚Q¶‹-4dP§Ï»ô-Ô‹Öß¡5ð—YÔÊÙtq€.ZTÊg·«XNP•‚q¤­$äC¾4aÒæ¸UAé’!ã]ÇrÑòC7þ$¶‘ˆÍ8ªä…k™÷ Á¦ïmì÷>/>LÚ:`ZgìÆ#víÞ§MƆE;íh'ŠfÐTá>¼ï}pßÿscé Ä«7!´Ÿ†÷¾þíÛ²jù `M‹xvÃåðØ„~<ÀÿèU!ì0‡w?‹#P;˜VÞ¯: Ï¡j™Î€³BÎÂT²‰}Çõa.­A9ë Q쑉åPC¾ y!ð~þ¤£+ýÂû¯VÀ)þøgk¾æYáày·¾é9Ò’–ŸyCÌÕWÀæzÀ¹»Þó–˜ßÿÕ˜º1’œc4è e2¬rØí[ùáWO½/RN#bcXÎ-ëËspO€6ËÌêÖl3=t«F±±¢XY¨÷´Vj`ëupNyÀž[f¤Û©·Ì¸ùÁÄñãÇGüú¯ßÄòrÌÓŸ~„ƒÿf5üðáçààÁ„ºvÀÏf-UÕûÅZÇáÇgDѦñÎêjÌå—¯àƒ5çÄ ±mmÜyç˜45\ziÎß8ãÆÏr÷=gàÊÊ«î¼Ûçßݼä2¹®ê½¾÷þ¬ÝVZ”wŸ6óøç\Ï8(H™ ð,çsÕ=h[¢®–|w|Qi爂šHׄ]CÙ$Ì‚”©ËuC¨^ù¼kxetÍ º_{é/÷ÞºcèÕ½ø¶ °SMm#Ž=ïNnyûå{á½3˜Í…‘ïÞgHƒ®"õ=éÜñ®ª†òª£{EôÞÿë»unlÀXÖÖàâ‹Ê2%Ï e™qæÌ„3gÆœ=+]׎qì˜Ø Žqî\Å©S367Ó¯¨õò¾û&¬®&Äñß-úôë&ÊJ.¶¨œ¦`Ì;ÜÌò·«ª2F—ÛÎm3­ PSG; h&!uQÏ"¶ÿhy.ZDþOKºPœWð‹ð>+¤83ht8À»ŠÓ&£Si8q9Á9 è*:ƒ`6¿U,P)±´|êàÑß(«³*¥ lnp¹¸ƒHC¤)눩ɘmà 9ÔY„vÒ¿ÎY™¡ÿ^qð „™øßC`šÄE;(ïÊ—³èX¾nê2Òt†Í5“3b—q[0ŠÁ6SQÆ’ñ®c‹I:^õÙ£®¥Ž$¢†Åbý>Sطض‰ÆdÝxW‰#Lê ¤ÜMEyϽm¦WÞë” 1Šfbh¦ÐÌÂAyÿÛg“¹a]è×¢v‰SÍ&Ýg ãŸÞ‡÷ý±?þ!#—θè`Jíá]=ìž_‹ø(½ÚF ¼ïÑð” ¡ÿÚcç²ÌðÞz–/[ÁÞìŸ7i™×xpï<Äw°ûyà=‚SSßUµeñìžm°÷Ó8‡)ÍØ ![?)ùñWÀïÝñÜ£ôêNiÓ×Êí~t«Ž:ê6¡nRî¾[¼èÿ­ý£CqrÛ@7ºnbËEÆráö*ïJ@»WÞ×l3Ö‰ÒXÅÆŠf}냜9ùDQxµä©ÏUwiŒdí¼a’ëÅ…ˆÇãÇcN‹¸æškyò“S×-W_} ››Ùß|™”sxõ½À½WßH¾`àÞõõ˜Ë/_ÆZÇÚZ<(ûIbØÚÊÙÚ*xÇ;*n½õ'OžÃç¡ çEͽß]øÖ+D:lGý9fí=ïÍþþŒƒt@+œ(â=¼;KR—âuŽ'…×J‡SÒaiÓ%Ll.ZŒü"¸/»êIUbC핺Á6ÓÃ{HƒEï÷=ðî"ê8¢²¿6 §¶Õ„mC¡ í‚Ꞹϡ¼û”™Ö«òºYæ>`³ï3ØØÐ9Ó4Îo¨/¾8¡®-çÏÇœ9qæLÌÎNÉáÃ9GŽ8vl4üW¸ßsϘ믿Ÿë¯¿ßo6Ž]âùÏ¿„ xð}ñø3a}¹Îk4–‚1Ë#ø8 ?ƯïþïRÌ\‰m¦‡wÛiwo›©’˜»®?*tköž"•:¡‹ qQÉÂã´³†ñ™‚(ª±‰­š´Õ!S—ÑjéÜú+?ô¬‡öÚB|°kŸ#PùõÌ K¦IEußq¤` -Ê»wiiDfÜ›,¤ÍÁ÷<ù'é¢pß7 ¼èv¢¾‡1Ø( ÉC¢¢FìÐ5U‰û´9“:'Ll¦™ã¶å=˜Ûf:Ìñ®#KZϘÖM¢ZGNöZ2kÿe`riê¤sKì…÷:ާò\Ó:cÜìªÑÙ{ÞEy×¢¼—MÒtsâÌ£2Eä-sµô˜h Ì´Ã4V}i:ïÃû¾ê¾?¾7^òq¶Žà’›t‘$9~"td(Úê—ëÀ²_½« æïÜèåå]ºÀ=_±¢ôŸ2éÁ]7ÐÔò8€»?›œÆ°ì÷$÷…¤ÓÖ®—ces/¸ç9Œ'ïLœ@»óþ”o[‚·ìð¼‡tû ¬~6ýžrôXJÓ¦ÜwŸ¦,K¶¶‚X éwÊtŸ¼CÃlo Àrž²ròžûâÝå%Qß×¢";Ü+ÅÆª¨ïÿé?ÝÁüÀñás€ËŒšûâýDßÕvPW¢¼O&9§NMùÈGîÇÍsžs‚¿()%~ò8þÒµµßØH¸òʪªßDtT•ek+ç†îºë,wß}–»ï>#)ž6ƒÚï~^ôHyó­Êí…wó`x¿äŸal ÓQªýèU÷¨®©š£ðÇCÁu߬)¨åø¾ì¦]F£CQäMÿ³ÿÕ¯~êUò¼•‰%eTnxï0¬?ö ÷}ââÞÕÔa§R4[ÇÅ·ŒÙ~óòï]kèZCa ¹À2“8xók¿ô‡n(X}Ó»B8VËi˜Qspyå=ÿÃøç3îŽ454£®-“IÂÙ³gÎD”¥œ^=ZìQà¿\ÇÍ7o³¾ž°±1·Ç ·Ýv~˜þðýœ9Sòüç_‚Öðüç_Š^ˆÁ½ôžÏ°9ª±üSf¬p~Oó¥€–ï\û/üâÝß=÷¼{ËŒCЍ›iH=‹¸ñÔ#åu?ly@÷´ÞÓdFX4¼ÇcS†3tf÷¬6]È̦T*æM¯y9]Ðd-µuN”ï~韉†DÉÔnû xø·&MN˜5ØÜ‰ç=Ò¸H'c)‚mò6g$iº­WÝ£pÍÞ`—à#E9ñX»Â  +«>9I˜ÌrÊ$¡Mw“ з9ãNÀ}æRZP%1:’¬û¸ª˜Õ)M²œ‘Q_“ä›û‘9¨ÌaSÎ,ž'Î Êû†i•1­2&]ή±ã–Øu#ê&òž÷^yWî¥Xf>¼?< ˆ¨‡z—„’²I¤?Cí0³Ž–€ü½—1yÆm_\†ØÇ¨}pß_Ü‘Á%'6Ù:³~‘¢ áÿ¹eÆÁ ZÃ=߬ø…k̼ò¾÷Ò?õà>~0¼.å}PßW%óWK«®÷—R>—Ýû/ZZE0}è³ëvæ~÷À²RÌ­2ýœqèÞ²Õ¾ISI»±VwÛxxOèƒ|ÿÛ‡–xÙ×9Þû§çY_ Y[³¤¹”w´ü¸‡…ÜsëÞC£Y)샔÷&°åsÏ;zohOj4V«š7¿ù$ÏyÎ:zÔhᾑǶeO§Ó!µs¡3ª1W\‘säÈ ¦Ó†#GFlnfÔõW^£œõõ·r=s¦æäÉ3Ü}÷Nž§?ÚN«³(eˆúޘƄD¶¦í&Q¾§X5([Én·Ù@1ZÛ¡Puqj¬¨ïÜ»™ÅM"ìDSki†SÇÝÄÌá½óð¾èwWï=À" ?ðJWL½ÅÍøÊÄ…û’á×<7?žá8{ەدDuφӓÍÍt8=1F}Y^w§N•|ò“Û\{í­\{íi®½öm» lG@_ærøšrÅxü{ÜpÃi”R<ÿù—¢¬}ú‡ó)]fÐXr7!±%‘K™‘PÐrž•Ayïm3ÑÖ‚O%ù³Í§£Î.$lÝê‰ú*˜é”™J±±¦ŒÂÜ×)ã©€+ÄY5‡÷Ä2-%óüª_ýsl`tÇ$‡¶†â´,í§”BH­Ï'øK Ó(ce¤Ù ›·‹âN¤iM(–™ ”÷#ÿîÓ8ŸæïÈ[‚í}°™$T€Ú"¤ÍBla‹f^°ª¡¶1ÓV ë$Úïã¦`û¤›ÒREñP°úŠêLëŒQ°KÖrÂó:‚ÄOo›!ñ‰3*"#‰¡© ³:å½ñÊ{0WÞ]©ˆpUG;54SM]Î=ï}ð½py’’1%eFÆ”˜Š¦ i\ˆ«­ 0“7SÒ ð·.còÏ¿x¿ïûc|ÆxÜríµ§X[‹ùêï_'ÌÀÄpâDÌÖVÌÖјd~ñ=ç!ˆYNáS_Ï<²±ï(2´¨Þ弄]%ð>¹Þùò^úuo·²Ðyxïm3®ˆ×À¬†ÝT6ƒe¦ðÔ³±—šCG9V{h÷Ÿfpªt˜ÒJ8qo›1jïxéܶ{,3ýžbÞö!G×ÙVpýyy÷úÆÇ{ÕÝï¶ŽÜs‡’BÕα’g,ûî“‹Ê{_€šyß{o› ÛB‹ò~袀k9¯ý¼öµ—qôhú €¿pô0ß?W‘G\}õ &IŠ™NŽ_æÐ¡â+þz¶ÖqãÛ|üãç¹å–êº!ÑŠò?>R)FN Tê+ .‘Ú‡²‡w÷ ¿;Z@tùyÛL‚t˜ `|("õ±I]RÕ1¥MøÚµ÷IûsR¬÷|© ÒA5߻֖PKA[ãBÆÑõ”›ÑNC±Í±ÍÔqÄø{ ’Ÿ.qF”wÛjé êá}âæ¶™ØÁÈÀ7tD]Û¡f¢i;;ÑBQ³|lk«`i)ú²¼ÆêÚòÉOž÷s›O|â÷&ʙ͊Ûަ;t™ìtL-]s—’!ÒS!1 µ‹¨UÄ7~õÛxÇï¾Pà݈e+KÖM=œàÞvþÚ½ún€@ù´„R%¸XQÅ1Y6ÅdmHÂJa"o•ñ9ï­˜†ï¶ ¨mD˜N©-wç*Yâ;¿ü“@2x]ûd IDATÕ=Uór¨soÜeú’ “u¨Âár=Øfj"&Æ+ï‘€ûê›ï#¨¥ÿ^2[ƒ­æÐîàÝÅîÐæm&Ê{4’‚ÕÞó>™æLÂ\ zÓ•I‘lÒ–LÚœÝn4À{lnud‰ëŠ™M‰©ˆt=+î˜×¤ ðžƒIÄ:cÕøæËŒ!/bnšyãB#¥_~÷ŒW¾4`yz$ä¶Ü')3ËEÂraYYPÞópÖq$T{ÛÌ`uqжâyèCsšÆa üÉŸœå…/¼ˆåå¿y‰ìÕ§áT%8p`søï²l1FÙ^£ŸùÌ×]w?++1¤8~޸ɿþëmî¿¿$Ž ÇKëÈ[¿íj¹µlcŸ ]{H´ÝاÍTìµÍøÔõOè£[߀iÏëìí2uQ×ÛÍctÏû“¤‰Ÿ›°öÞ³|öëá"E'”qB>š0ÞËÌ,J Âv´‘xÞëNNžù§*ànêî|§j\TÂCIu‰|}ªçðncÍ$ʉ³Š0oe±öðÞtfPÞUæh³€ ö·žOVJÜv$3à²9¼7^¹·…‘‚ÕB¾¥˜´9Ó&£RïAÖ2UÙïãÎ'ÍØ„Ò%ØH£cˬüÝiƒ¡#W“½ûé •îUßujÅ:£í`›q𩦫âÁ23éò!mf—y9!&Sç•÷@<ïU@×j05Ós §£a€ö”53RÚNŠ[J¤ei‡M45pòo¿ŒÉ/á~Þ÷Á}üOõ5²Êº|Ž]RqñVL˜ ´æUÀ\üý*QßèõwAC+)ì¶3˜å{á=ð D_¸ÖƒûÌI÷Ò)°«Þ=«^y÷ÐÞ+ï±ë¨f=¼wó”<Lk¯¾'Њef)pÏÄ·ì%æ• –3Ç(W¼Ÿ}ÀbÊÞ6cÒ•p7~2†Î,øÝ¥ú+ËcŽYZñΜ…FJãqGb,×üÒ)^÷ï7ŶÒl xà³3¥XÎ+(ïM:o¸X[õQ‘Hêe¯–['~÷å\à½mÆœ>]ÿ­ðþ·$ùò]bx äæ›ÏqóÍç¹îºû¹ùæó<îqxÑ‹ ^pɃ>ÿðᔪ²>lÈñ¦ìq¸‘lC=oî˜Ì؉Euÿ<¶5kQºEyìTÀ$ÉÕàu|ÿ/gVD=íÁ}FJK #-g˜¦›wR RœV„(ï¥Nøö×øýR¢ªÀ}ÚeòD®¦³ÛÍc,Û °® ‘µ4Ó;1ÔÑÜ6ÀTÚcvOñͪ”â;n…_(öªî±Öw!ªDu¯œ˜ãU'™ù:˜Ã; ðÞoæCÈ"8~î¸C>ew·æÖ[ÏsÝu÷qòä.kk d¼à—qäÈ—ßIÐí·ùÄ'ÎsÓMç¹ãŽ]f³Ž'>ñ¡lm=„·¿½‚U-š*€¶ñ~ZNï4lžÈˆþ´f)s„ã†ò@BVOQÖqdýnJ:Œ¯bè*÷*ðÑU„mõ`™qVaÊnî½î…”ÞS¢;Úqîã|øÛ¿Š*ŠE}ϧâw׳0%ˆÚ!×\%ŽY•òµŸxµh\HNùóÿ6çÖxà‰A'9QË“xß- Ó(£ÈƘ¼¯¼w& [€÷8¯¸êº`ë78ocS3yѵh8¶úX”n”WÞÓpPÞUÊÛf&ãœi˜1 sê ¢N"HaÚdÄMµ×ónSJä„ÂD³&%sS&e>_¶S`W5¤ +‹y,ob&ëäõæE«n·£™iÊ*ŠU•÷]7ÂT Ûç=ï^u/C¹ŽtÃôœDT½e•ð1 )3r&,±ÃÄåT.¦Ò1m'±¡½uÆÍ”܇¾Ë¸9ù?½ŒÉ;¿°¿ïûà¾?þG€ýr¤ˆ´ŸP?ìÿ=bþûC1÷)àý¹§sß÷Ÿ4|üеuàбãäÓLºy"Ì…–™†yÊD…ÀñÄzõ}/¼|GÆÞ:ÒCüR §Ïxxg¡XµWòú®¨=¼G¢¼4QŠFÔ÷XrîË,/xÞ·ï–bUSJ³%œžC»±(’§>òýïªn%¼º÷c[±$º\ï]eIÃŽ²qlnx×![GB>}³&Œ-ËÞï¾\8V—©R¸÷–þµU‰‹ì;¢öžõÎÂWä´­ø„ÛÖ±´pèPü¿ôµ|ÿýSÆãkI$öggxÛÛàíoW|Ã7œØóùÄ’‹ïà›ÿ`kÞŒFÃh]6Œ™c†(kØçÊÔ…ðþO§¨î(‡ÓŽÚ„²ëÞÈ+Øai°<ôņ¦i‡ð á<Æ­r¨Ö qŽe’ÐiCX6tá[’·ÂiøÞúg/~™&|Ÿ}ƒÐ‹§3MGçÌxoÏko¤yôW}œ[ÿl…vbè¦!u7·ÍÐxx«á”%÷CRèAuOÜu×\9Å=´ÞRÔÍá]{UwßñŸúš-ÁF  ö®[o=Ç-·œãÖ[Ïóў⦛Îð´§ÆÅ ^pæ_6×âxܲ½]†šC‡2&“–K/=¯ýÕÃùà¹.,C>Ç•\9@ Lm \K¶ØU²Ž§]ü~v1%Û“2ÔÕïeP§Oü¶ò¾_úZ¬ËÌ}Oº˜ñ=kñYYwCÿ}zpwþšÎdMþªßý07}×Ã)#éh:ÖZ½òD-AÖÒš€i—‰eÇFĦ⽿I —NöºÊA€JDyD¨ï±F S Ã,N©³ˆ¸0V]gÛÌË’ÿJW‡€K¤@ÕÕrY9¿Ì)¯éèHÞs\.•½Mº\räU¡Ð…Ci˜ìŠefæt‰‘4˜Ô2±9aÛ –^yŸº [þð×®†M`•y•ÿ;v…XO:°öê»É;Iª1R´ZWÌÍL3«½mæBxgDR–DXé®:õ¶™J VQ˜†Ù¹ÿÁE¨8²nJHÃåæN±)+QéXîÒY# â¦;ÓÐ@`a)·ò…¿göá}ì¿Ë&hKú±ì‰Ø8ù÷QéêH©eqùYxèžyèæPÀ;cøºJÔµÎaÿyí&F(»O—/€÷páxN˜60UóæJÈÂ; /PÞ=¸× œî•wìÜóރŬWÞ%&q ÀçÆ Ö™³•ƒ{+Þónh׳…´ìÜï*ˆ5ëËpúQO¦þ仡1¤™@ûñ­ˆC›¨QófJ»g:ÒÐr®µ|ëËnãÞyy*ÊûÖ‘€¦iÕ}%·,çŽQ¬ËLÿ¸¾ éƒk0qFWÎU÷¦u9ËÌÿÒ×ô•W®âœÃZ™KK9§O[NŸ¶|ß÷}š¼àFœ{þž¯¹ø?Ç0ŠÅ}€wß=W/(ïµ7kdS:Ór½/zÝŸ ׉¢å]·€‘!3“ò‹ú»ÙeD‡ ]c Û†¨ªx¯‰$J²³Äe…kÔç8KS×ßþ²Ü“õ|V‘(j›ƒ…WøÑñ´µüÔîb;Mg *pÔ.ÚSÂÚM¡™ ¼7ÖÛf¢pò>Üc[^þIÃ5Æ;¸ó3»¢º×À{d¥°[[o›±˜¨¡ëXx"ƒt ù 6rXOàÍoþkžúÔ#=ºÄövMU‰ ‡õ;ïÜá=﹓«¯>þ·F˜~±FQ\vÙhè§`Œá‡ùaÐUrB7lZK+!;Ûµ(¥/nto[&ï† “C9ß²ùV ;¦lT 1£ý)MÛïbÖ¤”A‚ ;ª*ÆÖš;¿ñÛ÷,³”ìÈuÒËàýËßúµ½/¤Œe ®bQÞw16{•÷ lI²’¦ yôGo ¶b×¹á—fÄÞíÒ[Zððn=¸«Ä¿tLÄû>ÉÖ›,¤N#IšÉ4D†ÚØNÏ VëˆqS°šžÅ¶^lFÀ}(ÕTཬïBoA…t…¡Ë ]a0£–¶ ™8QÞ§¡ÄUVIL¶LËŒ°kDy·ó‚Õ*Žù³w?]Þwä –XÀœé˜‚¤Å%’:`’n8jЙÅMkjRÏB˜vDSÍÔ¬Ž)†ïÛ§ÍŒÊ]"*Ú‰¥êYH]¸Æ‚Î@#xñì#’®ä%ѯò<À†ÔF舺õobÚR2û[`fÝÌ´°œÀ’µ¼ïûc_uÿ’g¾PR Yf.‹„n^_ê½Çª¡Wš;3önïq<¿»_[ÂÕë’WÞÍ$à·´æ‹–™Þ}BÀ0'ÖûݽºŒ.šƒÔ ¼#‹#Ö˜°–ßÃúa½ï Ìj––"–"þˆúž8[ÛÜ—3Ǫ·ÍL¦b—1¾Í8ã…”™Xì3ŲbmìŠâô¡gž}Ƕ"Ž8v4fy•½ð®a:Õ= ;Tgq­eó´«![‡Cÿø!Ecs#deË…%0zž ãÕ÷ÕÏ£†(Q¤‰¢X×µÖŠ+¯\ÃZG:d¹ãŽ’¿ø‹ÓÜqÇY @©ÿÎïüÎ嬭%|Ý;ŽA¡ä:|²?V/äMõ®îºË_çÀ%þMùkÖ‰£Š(šGaØpï .’ëmí ªŒæà®Ö92ŽŸýµÞû¹29ǬM˜¤SP«åqUQV mìi¤Ôê€ï¯_'÷/ƆJ ¼ÿØÊ«8wÑ*3ÒÞUë$Î+ï1‚÷v íÔÐNÃ!ç}€Í °ëæ'réqP9âÂpïÉ ·~jÕî=À7så}uS3.kºÚí…w%!ïF°žÂ-·<Šóìgç±Ý$4E²»Û°»[³¶&ÙèJ}y¥ÍEÈe—-áü×wkL×H‘½RÃkº\$æÔ½~÷Õ+ïçZ°A厫¯üCIê2Ékw.P4*Tw[il«)ƒDÔ÷0bëûNòžé³Ù¹g‰¦ 9¼|øÜñ›=üéç9ÿ§XHA!€ÇýüGøä¼’ZE¢¼›½Ê»I:Vìy–W·©vbxÝý´ˆ÷@ù¦Ä¾Þ¿MæÊ{¤d_Z:…- ®ÐÔYDE’ñžkl(ÉF½òþ>ì§ß^ ¯`7 &ò’ö‘–¶‚¶”ìxóR½ï½ñM l!ð-“sÒvåLšœ i©Ò˜8­˜îd˜¶›¬•‹yÿ­O›—dôñ§þµí3tO5I‡K.UâqO,Ä0Õ¢¬Ïꔺ ¨fz¦ifÒ{aV¥L±êôà^Ö e•3¡ZšÁó.½)^vã[ˆ¨‰©¤x–ŠY—Q™˜’‹¦% VÑ`©‰¨u$…Ít%B×’†e Á¾ò¾?öÁýK?Þû.`IÔ*_@÷ÿ­½I¹Z7¢.Z-¾ïîsÀ{üú&¼e í ªÊDž³×2³ïúxŸÓN"tU…ðÉ‚òÆÞgd‘9'ò¦Z8Ò÷àάáÔ†'|­‘‚Õ`ÞDf9ƒ• Þ~KÌO?Å+ï9”gçà~Že‚ÃÐÞ¾-ŒFƒÑÒ()—#E» §ÏÇŽÞ̱-±ÍáÜÎÒÿL§êŽ4°2ÃŽéÌòøÇ\Ïw=ž­#!ëk‡(Ë–ªê8ztÄÖVAh×_7««1«« ++ yî_ÈŸc#ß¶†Ï~ö4wÜqŽ;î8ç/X¡¥oú¦[áÅ_/UÀý5²$ /¨­|ýé)Mm/€wÀ>ù×%W_µÌzréºzòä×]w/uÝñØÇnrìØ»»õ0qàÀ—Gƒ&•{1$p~ÝeÀ{Ûzx—]¶ +…ƒ\sêNï­å’ß»œ{o› Oøß>„CÑ9CÓ†t¡u>±ßtÊÃ{-ð> Òa¾“ÊÎt‰zqdíîùË]Ÿbnñˆ¡UAÖʵïá¦A†EÏm3 Ê{`[‚´ÔQÄg_t?»’y)‘™Ãû,ÕèLlEy×¾qRV D»BóõýM>xåÕtY ÝSu$éFæ¥ýÆ·ìÖ#¶–Nâ|C?¿O4ÛМpga³@,¶ h¯¼f(ZœÍ™¸¹m&IKª4¦M)’íÜ`a‡×~èI²v,&&…ó©&‡Æ *ñ›Tê˜é”µÄ¸+˜VUROCLïÎ7hR{m3ìÊšah&šv"Ùýmexõ­?-׊_]BÉ)œŸ)I³ª•´i*DÏvNCcIC{p7°d!Y†o½æ2ÞòÊ/œï}Þ÷Á}ü ãÑ_å}õ‚wÛ8¿ˆ+±­¸ À½j|žy'eû‹àîc°t ¬ƒmgï+”]¹9Ü÷ ƒ¼•³Ìþy.*à¾mùÚ]Yˆ{Õ}Ê{aê[¯;ÓÃ{틽ÜÜï~¡òÞ–8~ï-1O|z(«>9=—µ\[u¤Ë-?òK¿õ÷S¥ã~jÄñË%ú»Œ–)ÇPM ‹ÜW ÐË`—Á®À»ÿûe\óú’Ãó;ç“ñYQݳP ~ÚJ Èñ£àöÛMYJ ^YvdYÀÑ£#n¼ñ4·ÞzŽë¯¿ŸÝÝšÕÕ„'?ù0Ï}î F£hÿ¢¾`Ü{ï”Ûn;7€ûÝwŸgO.áÕÏÛ‹^ØLö:‹þõÀB«÷4`2ªCkK(íP»ë4KÿvÞêPΫ*9©rZÀýûþŸÕ½‡÷E¿û‰a%Ì*÷’åaÕP•1Ω=ÊûTghm L+ùÝf®ÀoØø´º”ÚD˜ÝŽr”ˆê^KüÛ4Ì(›DßF{”÷ζ€ Q¾Xµô¯OŸ¥D}O Á•JšCEŠ[?°·œoz¶üÂÃá_ÞB9_²”9L×@Ýî…wí$ŠÄY66DußXõuxô£ŸIÜÉ‘##Š"¤(æ›Wi,æ¾<À} ñptÞ"¤hÇÊ(¦KàÌ}¾ ³dw²²³2rD¡¦H-ãš–“7@êþ½7 …ÎÓ6õjï~:«Du¯4]g¤€Wß'iN3 IÍŒÕÕs²®þÎÂ:Ü;–Œ¢5D4fNŽ8=¼?â§>Î_üà“?§ç=t 'žù—œr°ãÄ»)?€|o™™•9BÔ‘‡÷°ƒ2ˆ¦Ð° ¾ë¼¥vKzì³w²ÛŒ×:´¨Àv…h8ͽÐì€ò×_í:–ßÙõ9ï&Àzø™NEu_°Íüì½yœf×]Þù=çî÷Ýjë]êVK–¼/,cÂf±ŒM0“Ä!B0`‡„ „‰gÁà C&žf0ƱŒ3,¶1ò‚l$Û²„$KÖÞ­nUwÕûÞýœ“?~çÞûV·È$™€…éûùÜOµåîêꪻ|Ïsžßó¨ÌQ§ m± &8£Du7Snþ…Ï•÷Vo[ Æ/¨‚”:IèÒ& ÓŽ8i°™FeŽFÇì1g9K;¥¬3š*¤)CÂBÓšRgâyGx¯ë–PW‰DEÁ ¼ÿ‹O¼^®AýºqšÒ¦2\kåž/Øî‹-NÅØZ‰muå˜Ç#¼ÏCQÞ' ²¾ækr~í׊+ð~å¸rüEßðÍpö!P­Åiç+ß­‹äP!¾FçÄóNÙHÃ*Ⱦ¨_HƒòN9ü¯ý6Õ’D—ty†Ó’Þ•Žoÿ‚š1ß”XÌ:‚ª?cHå=òÊ»½A¥¸æê„­Qu7^`,+Kõ§a–;ìfÈî®|ù¯zÕ'yç;Ÿ¹%ŽûîÛãÞ{/òÀû<úèŠ[o}Œ®3œ?_Òu†½èZ¶¶Ò+·?.^løøÇ/pǸçž=ööjŽIH’˜8N¸{ûKņ¯IÍ%M.Hd„¿G¤7 Ðè|RJXtØB rŽg>sç¯ÀŸ;WrË-g¨kÃb3Ÿ‹¥(Ï#ò<äøñ ËeG(êÚ TÈoÞù›qìàövnæsëŒî¬4¿vÒ¤z2ºŸ{ÃÓòºïÏR·ñ®à‹ˆºÓõŠ^DĈ¨_þ¦WY¬ÕAèÔï‰üš@ Ÿ¥ß}ûÁ§sâ·ÏqâhÄC¯Þ›Kï[­ìÆíìÀ††mY›lÎY®Xîhî¿Ð‚mI³€ÅÔ±1ulmÞÖ|ÁÅOHêÏ´ZQ› Ûiùùxx76 )j\­° >–mFÕ¤”i†½ 9V±ß̈â–e;%ˆ ÷Ç;H¸‹ÃëÖ@bUîí2|ìUxí㉻IS7(ï«óÞ2Œž÷,+i2‰‹,œ7œýæq×Ù=¼ûÅN$Ô¡ úêÔÒ¦aÚÑ&aÖat@Ñæì©ÞË*£.#š2D•Ód½òî­:M;_…ñ%MšW|ô†Z‹J»ªÚœ•K%›^§”.£R)¶TrŸî;XµP8f3ÙYžiX$07°™Bb 8òs?wˆ×¼æò Ö¢øÿg©¹ïWÀýÓòøüÏßå½7ïACA¥ÙØÌÓ?½4k{yrüáÁ­‚­-0Æññÿ3”;e_nÒÕ¯f˜—·îø|£èAxÏæò„€Ûä IDAT€(µWà<¸)L#¨”œ{7~6¼çQÝ+;*ôYîþ$«‹‚Gõse¡0Ì"}À6Ó4òù]2Âû<…sç¡ãÞ«¿®¼›Êç±[`!ÿ[•Ú;è I&ê‘ST3¨&Ç©_‘M›3ؘ9\¦å½Édvuc"g§Gå½›*~êÇ-?ôã—À;P\Õ}kSKžv¬0Æ1™¤äyÊ£Öüóþ!^ñŠ¿qàçwýõ›ƒ5àê«çƒ'þÔ©9§NÍþÊ{ÛZî¾{—»ï+ѽ÷^d±HxÑ‹Nóå_~-×_¿²Û··êZ:óVŸÓöÜYSÝÓ*3ªîω%êS+œ¿ÆTá0E€)hÅv`µæ<çÿÀ½ß–]Ea%)cÞ5–­åc”uBÙˆm¦¬SŠ,'¨ U• À“ò¼ßOasQ·µÀ= :ya;7Dþ)먭ä}w.¤kCTëèÚU4¡èrºP¾NW*)¤I lº•xÞÛ0^â*‡³Ê< ^Z4ÎyÔtR¯>@A-Ï€›';Üü(/Ⱦ`o¾u$½ïá#ºÀW~Ù[›ð;;®Ÿc$*tc–±1slljV;ŠÕ98¦aãpÊÆÔ±1sÞÖ\ûëu™t˜yèÏ *)TŽí¤ ³‡÷ 5t+)Ú1u€q¢¼Ë‘Ÿf¥&„¶csk—ÅÿtQh:ç2vyp÷¶™ 7Dy 1”@ßóÁ6c#ÍO^õ­<êàœ’ ® %Ø­àÔÔ¼²gªqSJJkâÄ2¨Z¨œÉt…8ߪ:À{åhëH ÌÚ)ËvJþš÷ûdâÂë ´Sù7ªÌŸ^dê}ïmĆn¡¦FTw=¹Ì2S%)u*÷D¡s~©ü:¬ÃtâE©uqËûÜ«D,KUœ¥­ ¬&†0í2Ãj5aÕMFÛL¯¼š¦ÔèBcë|PÞûxJ*åÚð¬z /yíÛ¹!ìhïÞŒàÞC¼“‚·J¥”*£iCÙÛ÷ïû¥ƒ¢eKÇÂ<€‡¹•÷\Ò@v8à🡾ÿ—ðÚð¯Àû•ãÓîøº¯ÛãÞ{‡À+ÖAÌU'&\¼ØÑV­À©Ã·¨ë î.‰Qk;øÃw‹rõo_„ZnÖ¢ äž×Woˆ°ßäàÕ>[¨Ùv€1Pªƒð>›‰2®¸®¨Wv„÷È híQ'~Pç% »Q ø’›ïl˜Åk¶™PÔ îÖÛfæ œ+‰rÚì¾^ì=ŽƒE¶õO¿JÇzËÌ$e‘;Òª¹œ<°qÔ±1+RP{õ½·Ø÷Ê»K¼e¦–8Ç$C›£ßÝZ¨kË$µ>`¨è‹…¦ë`±H™LR&“š3göxùËßÏ›ßü¼×À 7l2›Å¸WU‡ÖŠ“'çåî‡óçK.^lX­:šÆpî\Éìö ø9A hC][^ô5s©rì_óýûgÞ5{E¸äþܩȋ—ä¹;À[hTã°Z”÷Exñ á½¶ ¥ÉØfƒu&À•fx»L:$IØRQm%<~t‹ü…Dä©§Ô¨ºû3ðÂ1ÍØäªá¹êüNðB*“Ò4±À{Rt9«nBh:*“â EÈàZÔ¶RìShš"Æ„k/ê/¯ Œp6àÝ:QÜûXÿîi·û}×Cëà”ƒóŠ4†ye]´Ìh' Å­áM?ÿ0ÿk7ØÞpŸLž|סJï„ì„[â¿h¼á'BMGÂÆ,ecf9¼±Üõ}y¾À}cê¸í[ÞÊ”Šˆ–]6)Èp›’¶R”ñšm÷tY¡ G©2L#Š|f”iF]$\·uÏøÉÛåy=E¾N}à;Òép€÷0ï'.R”•í3àýWŸýr‹ H .ý÷±Ï8$î|ð½f"ƒ¨L5*¶h­ˆRQÝ‹UNANœ5ÞónÛL•¤4û1ªq¤IÅrJúwÞ'ƒ®J^eÆB+Á-˜XT÷>’Lå¾N p7Y@“ʼn¡›„è©|mK=½Ì2S;iW­³„¹¿ýÂ=Tü…ÁÁ;›hÚX¢!ë@”w›è!q¦M"B:V­(û=¼¯Ì„²Î¨KKS)t©iêlð¼÷ «bYáÂp|þðP°Ñ_ºKÀݦb—1™XéT†^–°àö}‰·ÎÌ"õzx_ ¶™l G¾xƒxUrß}×\ó_Ûÿ9À¿ïWT÷O«ãµ¯]òÐCç9sæ¼4\„1‡§œ>•qÇÇ÷Øïê5åÝÁ$¶N½{ 6ž<Èíý9Û!Æõÿã w‘RJ7Â{_–)šJ>M³:h™™…òy|»9õÊo—WNüŸÚŒŠ{Ø‚Ñãéºêî_,[[2´6Øf"yPêuxOäáBÙ@üÍL6:…ýóVò/^¢2%¸Tå#ÛDå[ä ‹& TsE5‡f3Õ}*…¢º×‘¼0Œ…­¹Xµb™Éw¥àM¿ÒñMß4>Ž–K8r$a­eýÐuŽ¢H¼ú^sø0…á;¾ã6~ò'ŸuàZx2•Ð|*£G'Ã÷³YLYv, ÎIî÷7îðÜçâyÏÛçþa> hµ¦é4¦ôׄ»Ä2uâýjjY…~Î!¹ØÛËáeÞWU;\ øÆ/ÿ9æì±à¢5ï1cŸY°Ï<ØãûÌê»Æ¯jº¥> º—MŠ-.VX£8ûÒÃ<›[)m&÷¶r¢ºkI¾w«Â*MHç×$ £Y4Ôu› Gk"VÀCå˜2Àš&й>¿‹;º§yÛŒ¡-×¾x%31Fš†åÝ ¸KÍ/{Z¯¾÷ðÞ9t¨DÍ ¡ø’ç²ÿŽ?-3kðŽØÚô-ÂÛOBpOþ’ °k 7GÇ4‡?Þ[³1Ù˜;6æŽ#‡«óšÕyÅþyÍ$µlL·~÷ï³M1ìÄ<•;‰hù¾…#ZíÓÕšÖ4]*?Ä2­Z(¡ S±Í¸¯ºá­”Yƶ;Ï—ý„3H‚LîÁ6Ÿ‹u`â`°Í˜< ›Ä×*¡°9¥Êxé;߯¿þ¢o—Õ‰ì¾Vè!ýãÕzM'Öp_ÏZ€ÊÕînªQ‘å=2DvÉ©ã„6°SíÓ`4M³ßÌP#S%OyñÍœ{P.³H1|KZ°³ÞUj²ïbÉb‚ØÐNC¢‰ÃNÊÎûÝ×’fêÀÃ{šðµwþ*¦Ÿ{Qfœ“ R¨\ »Ë•J©’¸T¡'Yï /ít€÷ÒdÞó^Ñ–Ž ÔÍšòn¦˜RvøØóßäºãk~ìm ðÞ|ãbIªqk~wo›)ƒŒ2Èp¥Uû¾WeßϧôÊ{»¦¼+XdrùlLa6 8rä¿ÿ6Øx¿îŸ6Ç/þbÁٳ1‹ˆkOe¤QGvÐV£ð“Ç対4JÄö šNgᨼ;ñ+ç·Ïx€Å,ô=ÊE4æã@i§ öÖ™ú7RüÚ'¡³Ò”ÑôðÞÉÇ&öànªîþkÞÞvlo ƒY$ÏÉ8×)M·½ç‹™m¿€| &Û°,,û]'õëi ßèT! †Tò5Qâ|I“c>ñÊû ôqÍlÊðY¦¨b±Ìô%I[›~`5åÝÌTo¡ggçàÝtª9r„¡´%Ë4]ç<ÀL&5“IMÛ&´­åĉ”·½ía^úÒãWn„'8d!s€§›kRoóM‚Y«VOû|ìGÿßËá½5ì’"²'ÃñŽwìò[¿užw¾óÚfâ\ÒÓ„2ʈ¢«µ$MaGÕ½?-C~{›Èç¯UB‹ò®R‡JMÓ«vÂÒð^›„ºNh CSµï~`µ÷»;Ý àQø’ïúá¤;0¡±’JäÁ½Pùe֙ʤ´6UËN"™×•÷UǬ‡÷Ð+ïZ쩳@v¡·ò€,ûï? ~Þ¯€û§Åñþ÷WÜÏqæÌ9-ÙDqí©”Óפ¬–-YÔBW €¼î´(æáÀ{ߌÚà®<çkàî€UÑÉS¸²`FÏûlª$ñÅ¿–Jæ>gs_x¤åA^ûw†M¡¨|¤ªåo [IñÐvw¼úÞ—+y€ÿ@–ñÜØZŒ_gIR¥uðÕÏm)Ú˜#‡ ߆ɶ"ßR˜‡ŒÏS–¶WT 4M)o+ù*MéU“± i&à^Íy HSņøÉL”÷®[N·7E‰HcˆŽ+‰p^ƒ÷ûïwœ<9>äf3µ!¹±¡ýï€Ïó”GÛJ#êtrâDÆînËææ•L÷'ø);;9UÕQ–rVUÇñãS¾÷{ ¦SÅ¡CŠF…´:¤U»d½ûØï2ëIm¯ºwrݯÛKÜO¾è Õç|ÕŸªî´¯ƒ{CLHw ÊþÜDM«W?…Y´—uJ]Ç$®Æu°sÝyw«?{ˆß½Wjg´ïy¨ÄkT€uš²É(› Õ:‹ºØMèŠW(\©$j™ïì±û‰MTâ芮_B²„2ÛÁü`»3_Q3ε¬%PPß{x?ʨ¼'PÄp¡©.ƒ÷Í¿÷·ÿ”÷¼ç†OùuvË-Kn¹eü÷ܳ Áº‰dÃfŠ7ü¹ö 3/xwkø¼ÙƒâkßуmæƒoÜäps–´­h&ã5ÓbØd—«xTßÇÿ^¼Òû¦Œ²ÞÓU…YJ9S‡tMÈí¹ïWŽ¿ôÇînÍÙ³ç<¸ŸçñÝ]‚iµ§¶9}MÆéSwÿé’4ìˆuKó]OàpJd ½6¸Ù+í… {xŸèN×ÀÝì….#owñYðä½Ý—ðí­FUe××Ô|ìcí÷ܳ+)·Ý”í­Cœ¿ÐIFìülÍTTÙtMݾ3ËÆÌ±9€Ý,8¼¨¼Gi‹KúlGÕdáÝÍ1F`ª\ÒÔš¨Ô²hÒ9Ë`Š-ôEñÎäAb†¸Ùup¯H)”,º %¿®º3U°\u^y÷v™~¸¼è˜Gb!íá}‰ò¾áÖþ¼Ž+ð~EuÿK}8ç¸ûî]zèqΜñ^÷ àô©ܧ©! [Ò¨£ùî^ ¬Ä2\ ïOÞ;®ÞgÇ~#uÐúKÙÂ2•÷Þï*æ‘¢õ¶™¨Úq t¢F±§ÒÙþVõ¸GÛÃ{ à>ßTLsÅê1{°r=€ï»â­ÿB ™ƒ0ÿõ»;ò\qì˜,Rò-åÊZšKÓÐRwFàÝù„¶””WHw¶+ œe1™¯Á»øÝƒãú€‚¾9ƒÍM±Ìôàn Ìg¢¾O3èæ#¼#C¼yþÄ?ãÉäò(ÏãÇgtÀ½m-ÛÛW ˜þëw¬:êƒÛ5“ M«öK…Ò2êЬ<À¯ ø~$ßîæ­‘ùŒÖKá=ð?|gI_h8d“H>­‰i¨î=¸÷ªûí46–˜?Uc–ÆŽÖW*l§Ø8½¤«BÊ,²èµ¶ÀÀ*í£'Š„zû—_ýf^ÿñW£ZG­’Áóž–¦d`UÅ4¥¨ïÕ©³@z^T÷"‘û5Õ‡D'u÷*âeßúv~é_½lZ 1¸XÑV28¥(Sx­ìîÊÉýÒƒ{Ÿ6a½¡&¢E!j{ÙdÐB¥E…o‰V†® %*2å½®\hil$ª{mGŸ˜ëwÌ<Ä÷BAô¶™þ£Xö-óäF{x_yp_Å0¿ñë¸÷Ö7@§Ù9š3/GŽD=ú©y­ô£ùÈG.òàƒJÁ_ûük¸êªÓìîFÜö‘³Þ#â 9% ó =_x›¥°ìß÷Æ#üÞ¿^±9s<ïúˆÃËš¸kØ?6|½ÊÑ’RaÑä,™bøÆÏ{ ?òžLf¤Ë ³ dá×Ü—]3^£½^²ò0ŸŸ½¦¾g2±T¾p)êH&5pw±¢0þ")ôùêü÷¬"¨S¸ø'ò© ¿1iiSH$Vf¿]èKfÞ23U÷ÆÆˆò®rG—KîºóÊ»‹ÀÅrj¯¿`®Tì#¼‡Ð蘕™PE©4›f1.x_é •NàIFÛL<áUÑÏpbþËÝ)¦ d–äÒD^‡ìP%Ùf‘äºGb›é•w“°ëP…¡Pïûj6À»2Ž 6$EH×(t%ñ”…ÎYio™yºaãÄ>ÓfI}48pÏW¤b“éáÝûÝ •SšœÊf("&=¼¯:X¶¸}ã‡VGxŸ÷𞬩ì0ÿ—=&-×wÞù8úÐŒ±;6妛Nóž&Žƒ+ð~ܟ܇º¡âîùÏx$;5é4$Î69w6凾{'¦t%Ž#NŸÊ¸öTÆék2î½gÅî>Ó>î°½Í%ôÖ™ðx¾ƒßWd£ÝÅÙ5ÛLÙˆœÞûÞ<-g‡½EEª{$Î1]³Íôœ£xï£àüã¶¶ìÓ=rôXÈc:òÈQ]X³ÎD^Ò±Žk¿JñÛ?lISw¥F•;ÛPäÛŠdáØ;'àž…v4§T}Ô£2´j+°‹<T÷EîØšA·Ónù¸µ¥ØÙVìlwc M.° ‚'oõ§û1Ÿ+ŸB#ãLSÍ… ò¢]·Ì4%ÜvPZ±…h¼R°Ÿ\ï‰\x[/ƒ2Ìè¢. ‰hXegPãPôØÐhØ ÀûJ{c%)¢SáÙVµ,N-éêPì0Jñúû^rŽ(lyíõ¯xW’2ó²½·`Íû&Ï—uêZÛi‹¨€E“ËÌi²Š&¸VmIÚL(ª{SúR¦Â@¼‚2•EðºßÝ!iQÚŽÓƒ—ªî•x'ÿ_PºÜ×V‹jÅzoS¡fÛçº÷ð~äH„1î/´Eõ‘G*ªÊpøpÂéÓSœƒãÇO³*2î¼ó1ên¦NVé.’çe¿Xia±%‹û€mGŽD<õ5ñNKÜ5¬6&t“û¸‡tœâ“„È(ï-†€oý‚Ÿçuïú‰Ví ¼ßrò³Ç ‚ÞçθáÉÞÊó%à§°Ú—hÄÞül35‰”¹ Eœó·óW rÔ |âFµ=ðŸÖÅâwH”ôðűÌxÛŒšˆê®µ¦mÃÞ“¬¦Í#‚©…iÀÑo?CƒM@íKöøRZëÿY‘·ËLðY†£ufð¼‡2»Š&´i„Î,Mc-Eh^y¯tJãbo›‘aî«=0¤¼˜*àÈÆYõ[Ôýü˜oqÕ‰å=³´:Â)E¥ØDCgQEŒ*Œt,´9ËP”÷}fhc‰ëUF˜Fãú˜HË@ø©TÍ´Yd†&މh 0Dþ‡Ý«î=ÀÊ­"_ÙŒ -à>íá}eØ{ËLy©òž ¼?ÑqÿýûÜrË¢H³¹™²¹™`ŒâMoz˜_ù•‡yðÁL§Iò0ÛÛ ­7Ýtíe÷óx¿r‡pÍ2cŒc6“¡ÇÅZœºõQ‘Ñ•§Í“îX,Ήú>YìzÅÝ!ë¹^uÿ÷[½¦“!…ÁÓî^)!¯•Wßrouž>§ J÷0ô;.ÖJQ \§xfò EE:¨î58£å½3!7ý³wñ³?õ ±ÌEWÇèÀâ”⧪¬Ì„(hù÷ÿoDaËWs¬~„ýp†UšgU·qkúlIñÊm_øóâÿáí¼ù/—A¶.'ª[iP-b\¡¨£Qy§ñUé¥ÑÂlT´ IDAT^·Ì8ïùmïVöÒ{µ=ös&Wå6™M˜—íïÁèyw[ò¼8v8Æ3€ûÎ:¤8r$ü w€cÇREê¿¶ãÛtÝŒw¿û¬D¥•òü¯g­`ÈŸÚÊðX °­c‡ ºÞ;ÿ‘>K3[ŽÊ{íËIÛÎŒà^6â{ï,q®˜EŠY¨.SÝç†E@¯¼·¡¦Zç·Ú‹µv(4=z<åˆWÜ p8òÈ—Æ޲W°,òzЖ$T|ÅwÂoüKÉñžNGå=Ê%iæ±ÇFËLŽÖ´­¢iìÚù ŒûpÇ/¸úê ÇŽ¦ÄoÍa–c$qf±8ZËyåxr ­.ì¯Ís8I™iVðcw{Õ.ô–™¸½¤×¼ØÊ~7H.ºàF¹6\ãPº#¬;kÊ#¹V>söaÊ*“ìì0À*=Xg0ÒLÚÃ{ðU“âJØ8¹¢­#mø—‹ïdÊRD&„AG´„AÇáò¬l­« Fhe¹¾» ­Eý;Ï6K¦Ô$$Ô­±×¬ \u4•À{“ˆòîöû ÁN>î¹C@ܚтæÔîÚCú:´÷§Ò£ï½;¸ ? FÏ{¼-Ÿþ ¿ðUÕ±µ•rüxÂáÃZºfŸš­¬ãdzÞ»nλÞõgΜçì™óð™_Jº!ƒ„•C†D=¸ç©Àûl‚d¢à¾ÿ*¬S„UÇþöŒn²Ñ]à•á/°b2B»jî±^­Bù¹×$Ãÿ÷ª/øy~æÝßÈÙgæOÛDu_‚)‚~qeS’Bÿë›—úÝ&,m3aÔ¡r‡K””…¢¼ý{þ»6¹íM ‰ñ¼;ßfšVbI׬3.w ØÏÓ¸‰(ïZk+ó ½ògWÞ®ÿ_îÁúÍŒ¨´˜þ&îS…ûEˆŠ†U×á½WÞ—…ü;Š(G¥Ò’ÝæR¢´dJÙeAN­Ú0àýØäê0Áœ ˜„+³‹ò>j{ÁÕ 5s¸X,3d¢À«ÔaS=XÝ*•â´")¦ˆ 0¬ïÑtˆ‹Œm¥%)#¨¥ ©·Í@ ÏÈ™•SžÎHòzˆ†<ÌYVnB©²Þ{€ïÁ½ Ç•–iÊ`™I:ë3Þüšò®Úް5Ìã`¸WÃ'x×9üà>¿û»¿û»5ü`ŒÔsõ±K¸È=÷ìñò—assÉu×=Åâ×\³àškWl3WÀýIî[wŠÐj0©l1÷É'&@pÃõ![›ÝîéTñÛ›Š­œ{D²À?ïWŽŠòG:=ý<Û×DÞ øä½õAÕw@u?r<à‘‡«ËáÝÊpÙ=5<ßCwàwÁ/” ®je`µjÅ÷Þ9f 5”$õª»À»xïm3^u'K”)<å)é`5é:XìÜCþí/'„)i@” »>ÉC{oбlL3ÒT³½-í’냡A¢È·`¹+à>I‡CŽúAx·ÜûÉ‚ÙTqüx±c)'ON¹úê)ÇŽflÌ•¼Pƒ5æ ¤ÿeµÐƒ:¯Øõ–™oyã¸~EÙu—[fxOFx <[¡‹måtV€©‡÷vñ9›LØTL(­—& htLk#œU”÷VÖ™˜†®ŽPüèS¿‡)KœòÊMuG¤[BÝ‘¶Eê;T$~xeQÊÑK+&Ó!á¦hä÷Ð!mÑV¶ÔRHS&ã0^a¤ ¡tƒßýä߇¾qÜ­|»5x7V@GùOæ##«‰xÞ%ð^æ0Kä~êKØ ?LYvœ:5çÔ©W]5ý”^GÇghñ®wåìÙsüþ=7Âu*ÅF.3¶»ûòmê-+‹ãÞjà•÷b çt@²ªÙ?4Ã&а5üÓä'0¾ê·Ÿ•è‰\K× ¼—±f¿s£j‡ªTwN?ƒ…¾ˆ}\Ó™xÕ\Þœ3Ú&;è’}f¬Ôä òuD“–Ê¥a.¶&\<¿àöŸ{Lb½ÔÏ"wt~Î;R5Úf§é¦ 75¸™: ¼7­XË •S'RÐÔe!v% ] Ñð•’$lF«Š‹eÁÀ%ž÷Ká}Ux{8‘¸ÆLŠšº$xo3Vá„*Hi£ˆ"ʹé3ßÁüâû“¶Ößx˜I¾ëÑàJ…Y’:Ó' yxש…T†Ê­ÓÔ$袡-4®WÞÓÉóÞ{ÞSS‘-/Ò”UkŠZb"]VƒjˆmŽÊ΋HËgðQVNu•K©ÔAõ½WÜ]a`e˜dÁ º•‘¤™Ay·°gaé$«ê˜mÌbÈþŒ°³ø"úÐEÞõ®%ü`œ\ó/`w¸ñµv\uÕ„ãÇ#®»îNžÔll$WàýÊñ$‚öø}õ›wÛokðþå†ãÈ‘Œ­­€|*êû›ª€­9,æpᓎ¶?oöš€Ïyæ”l;áÜã> ±ì•w#G(/Ò“š# =¼·ÞFc­ÜW…Ïf_´Êö ò^tÐ(f¡f¾ïàcçˆåg^·äÿú©DE¡·Ìü£ïªÙØNØ ŸÃWœ¾c]çHòwÞ|‚ü£ph ‚ð :Ëþ'JE7ž‹iÂbò…ë ïÛ‘ð®èpŸOàðáç`sSb×Á½ë,7Üð5Ü{ïorü¸¨{W]•sòä”ãÇó+êú§ÀÏF–1-|é?òàÞç«®¯¹½Ü2ƒ‡÷U«Pþû5!oµ/_ìÉZf‘ɹá•÷Û^Þat@¥º%lj¾{ú6§sb±@‰oÙÐ5!a#½e”±ÊD™7ÄU#‹„ºc;=O·ÒÙ]Ùƒ)(ŽÑÞÔ°d*Ã’LGÏ{,ð®sKQç|ÆÎG™w{L~oÅGÿçŠ8y¤=Àûô—*“ç½ö=Ui ‰–Ä™*JÄ8=3¸©xÞõDƒÒ4õ¨¼·Y$i3yÄ3ÿõǰ „É­) l_†ì5*å=æäbaÂeC«äИ˜¥šRøô˜$­Ñ¹xÞ»4d_ͤ„ªÍ(¢œ&’þƒòõD"S_ö¾·¸v­“á[›hÉmï>‘¿S§Ë,‹UbY‹..©}¡­¡hÆ´™};cÏÍi\ÌæêAšJ¡+MÙHL$y7n2iWheyîÖ˜±Ï”%­•Y–†ø@ÊÌz\¤[:ïkï˜NÄ:£†­UëÁ}Myß·q‡®;æq"íåOpÜ{oÁïý^ÁÛß^sóÍÿæ÷?ˆÈ{¶ša;êöÛæ%/y:ÇŽŽK8qâ‰}8WàýŠêþ~¼àã¶ÛVAhõx¶‘@»Ñàû‰&Ç{ÞSòªW͘Ìàgï‹Ø>‹Ð:ÂÚ•¥C<›ð’)¬ö,ih¨‹5ÛLBèXÑÙÑTÍ%ðú²"ë Jøéoø‚'ð»—½úÞ@–™Y4ÚfRo™¬3}T¤‚W}}!9Ø™ekžÖðÛw?WÙ}´-üô›¯áÈQ˜mxpO䣎@ÅþV%J€Ï’ÎbÍÆÔqh[±»¥8vL é"*v7lÌ >¤qÂpô¬7^ƒwy»=÷¹_Ãþþ‡8q"ãØ±”«¯ž\¹!ÿ÷ܳÏ{ß{–é4âÙÏÞäºëf—ýžÅ 6þž‡™«ªx—Šm/÷5Õ-[øÂÀÀáóèb"Ðî:°J2×­áÙϽU Ýç¹»F¡[+Ðî:;ªï½òÞÒ©VEDMK™dX§%FÐɽjµfHlߥðU-e—±ŠEëÁ=[•¬’ ûÑŒ}fƒ¢ûܯýoˋɊRÀ}%Ê{W…Ôe‚Y”÷É¥L’cäÉŠ 04EŒm5[¯Oxü“[QI7F¾W½@¡#åD\hÂûTËÀj¼=ÎÂn,à†6ŸTט: œß‚báÁ]˜ÛçI,ðÞŸqrÞ‹ à,¨¶C7-ßzúgå[ìáÝHé’ŸSØvï*¦l3Ê8cLp¨?öÌçTF"GMÀìá}ïcñgèYjÊØºÏ°³Rb›é¢pTÞƒ–øu—Pw gÿÎyt‰æ¨óÚT'§ÉŶh³!1‘D‹ò~1Jˆ&5nʘ6“û205Â{ÙæótO<ûб±×¿2ÝÒƒ{zÅÛåæ{x÷ –åù7®‚Éýf,²e;Y(ê{%ÜxÓÇøžÿѱè0¶“Úë³¶9vìÏŽa»ïWÀý/äØÛ3üú¯?ÎïÿþE’D±µï–áÝ9Ù[4þì)M‰¤ö³ï=ÄâlŸmþÅöö!lœ´¥ºá]cqR±‰B,½mF‰]&ßTÙxðþöx·à´‡w •†Â·«*(«W5’63¨ï-³(,3½¯½WÝßöÛ¡<É'¡ ¬_þâ ò䶆i°½‚¨‚7üÆ5|ÖÓźµ^uï•w§ BóÈ–¡¸P ÞÆ4cÑÃû¶âºgÝɹO>•þÑb (§hQÜA¢GxëLÛÚúØÙYxïÝœ$¹ó—í8¾æöÛ/rûí¹ùæÇ¸ë®=¶¶~à>“¯üÊ«Gøz1ãð³ó/yûÃt"ÉwíXl¶ïEïÀµ%<=D—Ú‰eÆt+n|ÁÇpïá]5n€÷Ü;RE©(ï—Àû÷nü0•I±Nþ|bj‰}Tšð÷·'YÙÑ6›†Ø4éç·È{å=XI$Ý2š€÷cúÑ‹Ü}÷.gÎÞ&“ú‹ÍG1Syx—6scn¿ý^ùÊc$‰¾ïWÀýS{¼ï}ûìqvwüoŒŸ³¥Ð¾û#`4;)Á,#˜&Ø$F'0_ˆâ¾Xȯ‹sNà}éÖ< xã{KþúÕŽ,2c1“UD9¸oL´Ý¼ÛÑ2c­|-÷Øß}¼ñ­pnPÝ}T¤ø}òGïTüÑhyŠ$O„N>* .æË¯?/О™Á§¾ÈsIo©Çó#·ÂöŽÀûÖÖh— RùÒ²Psx[qß'ªAy_LS6¦–ÃÛŠÝmÍî¶"߇é$/àС`ð6;'Ÿ»WæÛÖ ª»œ°½­9uêY:T±³“_¹)ÿ’Ö:z¨ i 1OyÊŒ<hË;Þñ0q¬yÑ‹N ¾¨•õux<Áͨº÷IZ–µïE‡ÎÃrNZë[‚Û€Ï}ÉÍ4ÄÀÝn¬Øfl@zõP¼ËV¢";B:òêÅëiˆF‹Æ:‰zLu…UZ’d·ñ;»/”w–|t>NPåhe mG^IÎ>•wk”€û*’aÕb,fjªØ‹ }g‹ÒŽÖF£x ŒìÃÛ ÀÓúç\kÞ+7nl£ÝþtãÖ•w»½½jaâ{žà~ø1Ð[ —Š#ÈChC¦ l䢬Ogkà^€Fxÿ_êxÍo½…ã6žÅ&»Ã°aas+3†±æ^7Và½í¨tJÙˆ­£Œ2\¥Ð•%ÉkZÑØ˜­_~\”“Ü ²8LzjG›Xÿ^z\¬3½mFGv€÷¸k¨»„«žñ'ìíÊçJ²q§*dTÞ«( ö¶—›Yi»AB%$“7Cl33…Ê4uýÄÊû$\öž•|t˜ý|ô”q04ñ×V?´„÷U'» =¼WIJœ4Äi3*ïÅó^†ðó­=³Ýeïoè¢6‰hãb“ktlщ%H ûVrÛ÷ÝŒ¢Í©Š”Öû)bÔbïÍ£mËîºÞÏœ«ßýéÏíï­[MIÄPI0DVôEÀ&F:›1|OÐÀCAPD±A‹‚>›§¨<ÈÈ /H€@0} U!·ªÒTsëæÖ=÷ž³÷êçœïß\kíSUˆ  úrækìª;nsÎ>kíõYßùý}¿y@Õ$¢¼ÛAyg ¬,íÒA¡ MNÆwüÊOʵèÛ#ºÙˆU;¦l½ÂnÖë@¬3¥•ÈKñ¨¤ÊûDÁ²ŒwŽ´·Î8‚Òqîâcæü˹Ÿò(oy˃|Í×Üyï'ë³·ÆãS–k-Î]äÑGk67CŠBÀýïþë voüqkþb V‰åìÙé""˜ÄÓ˜¨åÒÓ£ÚçsH#QÝ{å½[>E‘†K²ÐûÞKmÀÞyíá=@5-AcêÓxx×.u“¤ }fí«î¿÷šú¸ß½l$†&ÖþƒÌqæÔ”‡Yy5Íû]A,Ai¶‚Ða1ÎØœ Ê{TÊ¥>ŸË z{ ‚D^ÅrŸ¤ŠÝ-Í#› õÍšq°˜XæÇûÁ–¢8w|Š& awW,3q¬ÖÒbß{îmë5»».,NNîÿ —ÖŠË—§Xëü3©ãÔ©Œº¶,1yÞ¢¾(‡éH¶½»cLýM~>‚ɲmøë|‚ê¾ï¶à µrhÓ ]ƒ1q`zhïÒ@ µAmPµÀÝÛ#JR*“ˆò®B¾f÷ßÒQجw«4.P(íu‹SÒʺ Öl3E‹n-y+‘~K5A+Ëh•S¯bò±”û¬Ã{¶ZÒäâuoó•;š"¢ªšÜ_Sß ­n£ ‡QAðªu˜&À4Ah0…À½2p1€dC§PåÃ.ú:¼G›Þ2Óõ&¤ò`ÿ{î‚: º‚ òBB#¶G2{å}>à=±"tðntÐ+¦_Èû{p¯l" åáÝ¢1.À¸€¤(išˆ°öð‰/»®ctiù+{¯!|Ä[¿Éæ·ßѳó&{€¯ÚH'åï^}/ë´X]ª qT ¼-I[ñEûo¥h%5R"º(¯Þ~œK›†„k¶/’ã\H'ÔQ‚½mÆN4u4€{ïjä¸Ç¼™Éx) Û‚}¯œ/®òó;ÛŒê¢o"ž4´º<ËLÈÕJ(Ó”(i0£@àÞ‹0ãWôù~†c;.”$¦&‰h’HJ™b)gj“•Hkñ‘xï”÷²Hiéà=!È5¹‹çÝ ¼ÛÜ«Ð+Ë•W¼ˆÛ~èõ<ðÂoæ[~ðµÒáÛ’»£ncÊ6¥j$›¾4)•’¨ËÊɯ¹>úñ¸m¦WÞµX]µ¸eЬîîìîjΟ&7o~”oÿöñ½ßû¬þšx챊XJËî½÷&·nµpùKäæ{«…¤Aõ:x/׬3=¶âõ¯¿‚ÖŠW½êŽx?QÝ?ók{û×¹ë®}î¿ÿ‡‡Jý:àxøá»xî݇Y&G|;À» E1Ïù<.Ï–Ó˜`ñþ÷×lÌT? Ú•÷°f€w¥ü‰´f¡!õÖ™jiØ»-êÁ}o[óø† 6Áã#"µ‡w§ôÃ?½éUw×yÝ‹‚²WÏ.^˜F ˜r€we;Ðf-{mœÌÇÒZÕªWÞ' L¼mf{MyGû/k¬ÙÙõý¡%óɈùر˜ØÞó~°¥ˆ\Ê=÷ÜË›ßüô5€Wìîj¦ÓÁ2cŒ«Mcý Àk {{¡pÚÉúŸô:äöÛg8YÐ4Ã`òWû6Âãwƒ.­¢S(ÕÚùÿý_ pðçÞ÷ÔÊû¥8š Cw¬Â61/ýúÿWàK‹jÚYgTíj ƒç݉õ¤T)¹á¬âgߨ·²–¤¸ûØJ­-Z[\ ÿÿ‡¶~†ôG‰©I‹תA}OÆ(Ѫ¡YÉpê•÷x•³ýêëÜüŽaÞ ±Í4^­ûF —9’6 Qo¯SÞ5pìo¬©ï«Fv;€/ ´!0Í$ §Jð‰¾äåpõ^Ü:^|Eð¿gОv¦î‹r˜¥$¸7„*f{s,Êû6Öà}âEˆÅ¾íûùÃ?€Â ¸8±NÙtPÞM$à®⢤)BLíá=H0=¼¿zÿ‘?>"0†íïº.àÞ)Ïápn×uŒJÝï±Ü¬ÒuÖ«î+ÆØXF-ß|ú52îdÜC%GÔ=ÏF¾LWÃ’›…D#Gƒòe"Ê»„Çl35kð®$mæ?ï'pWöÏH‚ŒÉ˜ë®Í ¸î{èrêc¯¸w¹•£î|ˆÁ\)o›‰Æ”aJ”6ÄiËäÜ>bJÞŠ%éý?÷…ƒMÆ®Á{uËám3}£jlÅB“8–F÷N}/šŒ2à½Î‚\±R#òzÄ2XSÝÀ;KßÿJ¾îýhîyøsÈp{éRQÝ›”2ôÖ¯¾—Øeô²†C;t2Œºz²ç=èm3 wdÙ˜iïðI²àÌ™˜·¼å*_ñû4ーŽ÷Þâþû¸Ï½ž‹v+Ÿ7þý+ž ¾—ìî&œ;7åܹ ׯ—üìÏ~Š/ÿòs'ð~îÿíëƒü4‹EÂÆFÊl&Ïþ/óðÃwݵÏl=Örx˜÷Ô{æÌ{a’6²˜ÕÚ`^u߃¹o€û¥+1_ÿGc>ñ°ãáû+îxFÂÖš]f>‡O_p<ïNäŽÀõÖ™Ÿü…„œÏICÃæT÷½í€›WK¯¾Sµ~0¯“·DyŸ, .¡®åÃê;¾u?ö• «e#9]\8?ãÒÅ”ë×"]ÓÉ^ËLâ}é€}¯º{xO",E7Si%Ý\Ošé¬øÆ*v·»›šGUÅb’²˜Èß#¾wÍÍmÍÖ"¥m÷ï>Äw~çÙþçEŠ(z2‘;SÞ,;!÷ÿÙ×drûíSö÷³~®áŽ/Ía hü`”[÷Ößœ£5p7þc[øë_ßñŸ{ÞÛ žé`©Ñ±÷º›Œý…_¥Y4QH˜( Vqo™ jƒkÔ0¬êŒ $FMpFÚOQ¹çÔ1pWÊ ¼VÔ÷@~ÿ*K.{Ó¶¡(ï­(ï¡i¯V¬QøòfÄa$i3º6ÔEDx$ª{» !x¯LÒ§P¡»·MÑdVéc;J9ܾÂ|,ðIæ8¸WMPkf D ŒÁÔô!óÒÿAîÔ››+V²‘äÒ•ÄmÀÒ7òxå}c+`kË«îcØœJÂI°1 ÞnmÂ7}ø3"÷OGá4×í6…ÉXÙñ“l3ÁªÂ•!U›‰mÆðNc¶ IDATn€¼á*Åÿg?K.RèÀƒÃš6¢Ò :³˜q@0ñ‰(ä7G”(ïK%ê´Šÿà˾2õÑ h‹´WßÁ͇ę*L0YH)¢Ìƒ÷¥I¨“„*Š1ã7…‡ßz†éWa¨Ó5xgÄ,9äô7<ˆKDr+ÿ å‡nÝÄï–EƒúÞYel¨¦#æFT÷£a·‹‰,ƒ”8­)Ó•9JRžõyâ͹‡_ûØ£¬Ú§ìpÿ¶‘î÷:õÝÄÄ'5mÒÔK';\ÀçõˆªHhq4¹¢Ê‚ÜIòM=f™xx?òÿÖÒÂÊòòù&"ÝômºK€Aá(LFa2÷ÖûÛ|î¥NQËZ²Û£Ay?’k´SÞ'}TdK±ÍlwìîþüEf³ΜÉ(KÕ+‡<øàûŸ>Ì?_vB´º•ž Õʽ?i PÇÔ÷ñΛô‘ÌçÎ9wN‹Ÿ(žÀûÉú­+Wnrß}7xï{cµjÙØHxÍkàüù}îºk ƶL§¾ò­“¬CÍäò²±§¹v£À˜L&ìÕ÷ÅXŽpÕ~äŸ-¹ýBÀb SDy_øƒOzå½òž÷Nu×Þ6ˆ45yÈé3ö¸GÆôàt¾w­{»L8öÎ…„±‡÷µãX»ªÕýü9÷sg"V‡9YÜЬj¿—é-3Ý@Zà}>öŠùÈÑ*÷Œ¡•t]y×ñàyµv75»[š;ï±1ƒùIJ˜8cñ½ÛËiï_ßÝyÛÛnñ’—ÌÿËŠšêÀ¾“OÖÿ_Öt1F,pKiØJ J‡;Y;œ‡€î×Ë5˜[‘óVTwìš×=§ÑiÉ]ã&©ºJeÒ<¤ÚV^MP¶i¿óåÕ«ÐêZŬô˜—_|S¯º.“¸Àþi”v½ò®µíãWÁ˜ 0’Én!7#A5&[b™ñàž×#Ž"QÞ'«[ÔyD·ýÀªËM‰OöëüÇÛ¨" |¢œë,¨±Ãî8¼¯|0›jf±ü¦Ülüû]üî÷ß¿âOÿiÅÁÍñ+!„‘È¿S`ªäÝ.í¤ú؆EÆÆ†ac°Ég¸:’b¢Þýÿ So¡2½oyÌŠO™sý°aiSj˰ª ¯0uHA6(ïQFÅüåÙ÷ó¿þ‹’n¬°±–šຉ©tÒ·‰f“BÀ4„Õãâÿþêƒ7ðùæ>ãÝ(h=¼ër(aÂ^GÝ0ìÚ0ò–‡„£R¹„Œ•Á*I¨co›kª$aÌJìAÚ¼Šù“îõœ{ö½¸HJ™ºk¶«P‰R]Tí¬3.R4©ØXš8b:;¢Ð™XWüƒI§¼W‘Øfâ´†r$7ÿ]Gw£­E…nPÝýî… mSÞ›$ê­2÷½ZI$ë‘”÷¼ñ¶Wú´™„0·ä™WÞ#¯ºwkeyþ·¾X×2›‚&Àôª{kC ›QØŒ²I% È&”À{¥²HQ.vçVMï{?¦¼µja’–ÍM׫îÝëÖVÆéÓׯ—<ó%0Û¦±âVm·­=À;­ú—‹= .\˜­û¤ù§Úõ>÷Õý)ׇ?|Ù,f±H˜ÏÅ$xíZΕ+7¹rå&rƒÉ¤!Ž+êº%Øyû1‹=ÅÆžâÆãU‹/(I Ž™.xO¬¢Z(ª9\ùõ’‹·Ç,¦ŽÅÔ±1Sâ›ôv™È¿ªÂɦuआ;6Þ—ÛòKnr×þ!{»æ˜òžWƃ»‘mûÂçmYG–ÁîéÝýkŸ ï?ùSOãŽý‡Ey×%çÎ͸íbÊmS¢¸!Kä8<,½e&ôª»Oìà Øö–™ÅHsAXÊ–rWz´¹ [â—TÁ¼[Øõ¶™,†šÍ¹bî}ïí–b’¦½Š>iNŠ)KKšž„².®×¾ö&ÿößÞâVYÂf ¥÷b× ½]÷ÐB¥hoë+4PkøžçÁ·þ }Îû´¢ºë–sßßRÙ¥q^ÓæmҶë!”÷Z žw%¶™ZÅ<ïò»{polD©Ó^Ý~¢eFi‡EX"þHòÓü§òe¢¼ëAyÏ͈pÕÒäQîu¦%d´¼ES„„AÛg¼wðΩ5Õ]=Á&ƒÔ¿ùÒ«B…[ùí÷òÉêût+dêá}ÁÍØ¿×Åïý9spPó=ߣyì±ëíAv̰uª Mäk¾|þ³a ï{˜…a{+`¾ï“D>¿~â+þ#³8èÕô9Ú˹§x”³ñC¼nõJ “õÖ‹&.*ìJÑ6Eèá=彩#þÒ¿ÿ¡þçâR…M4.RØ@ûùЪ´Í4M ¼§õ+3¦ ¬Õ}AÓ}㫨R_ÚK«©ñ®ãû¹’¢Cp[k±Ä¸‘ÅŒ¢5xÏ›‘$ ¤16 °ã3 |½šÜÅbÖiÌ¿ðq¾MÕuöÿðê´ÂtC·‰\¯]ÂL¤˜$À¥ŠU4& –­xÎ;KPŽ$Ã=‰“š2Iq(rFü­ýM´±8£†¸Î2ceHµMBL"_K¹SGï‰Ø“ª:a©'Ëjå(ëTl3®x/Ln$¶² –¿îø¦GIm‰Ö–š˜ˆ¦ßý²hJ—öÊ{eQÞuz,"r^[Ê¥ÁÙ!if)vœ°2=¸‹m¦%( í‘ak˱µeÙÙÑÇþܹIbÙ~ÖX,I)CÙWÓÊMë£vMã§‹}žÑ@É… S.\˜ƒösç&L&OÝütï'àþ¤õÉOråÊï}ïcÕ, wܱÁ=÷ÜÆí·/È󆦱Xë(Š–é´÷ ql˜Lšþ¨ÔszhߨÓ‰ôöå$>çx1N™{xiQÞ«¨\±˜‰Wrc[^u?:„°rýÀjPY è ½Ï;®£øèõ_ø…å1åý“¯ûaÕ ñðn¦sÅÞéÝS!³O‚÷beyØVYUœ½0ç¶‹)—.¦\º”òøõ†4–ƒÖûÞ­<ï&`”ÍÈ›’ùhÔƒû|ì2ˆjïk5òǶ6D}O'žÖ:™v·/¤4MLÓ8NŸNØZ(Ëèl$*§·¿ìïG'àþ9º^ÿú%ï|ç‘ä g‘(î*u®]ƒw¤$e„V ûüq§ºK)‚¿~7|Ç; ZIÓ°Ólýë„Ê8”v(å­Vb?YSÞÛ6¤Ñ±(ïµ_xçw×-ïø8¶ö‰2VQ…‰Üµ”T¯º£«1!müU!m¨U’ôž÷²IIó’zÓÖaoY2!(Ì ê"’öNŸ8cr)gâùOï]ZL77ïÇ9y}—Å|DÚÚmðYè˜Å0‹E{˜Æ0޽=¶ù½?o~ø‡W¯>ÎÕ«×%‰+ðžŒHkùþMuàae°\½ûé§ùÒŠ­mùlßœ ÿÿà5|¥Àœ[LX`zõ=¤åUããþr`UaVИ:Ši›Â‰eæ¡ûÎ{¨rcI“±±–6Ï@^k'ª{­c\¦úXÄpÜ’_“‡¼&ˆh l–QŠkEu—`DZ๭9ï&  JÞÃQƒ…D=¼ß¨2 Lì(ÀLìXà÷ˆé±D¦¯:ûã¨~WÀEèrÎÙXãÆŠ`be`ÖgÍ»H¤ò “GÒܵ–vø]ÚŒMµ ¬Æ ™+ø®ƒ¿2ŽªNG+_»öþ† ´iˆM4uS% &h’¨·)µËPà=šp Ê{]Ç¢¼ÛCÚ\Så 6oÉ“QÙùÝ7¾þ€Q•“¹‚:=žîPòpïÒc»5e+ƒª¼O"ý¤1Õõ¥KÎ+ïqcÅ2³f› JƒÉ-›—ŸZyßÝ NÇ¡½÷¦‘£m€WÜàaƒÙ ΜóçüþþoîvïŸÃà~ß}3GÌf ³Y‚RpëVÕ«ëW®ðþ÷_ãêÕœ—¿ü6‚@qÏ=—yÆ3¶±¶·3ʲ¥,[N€¿v­b2i8<¼@œeG³±«Yìi6ö47 ÷¶‘IO©Ÿºžó%© ¬ÆÞç)ÍÆÔ±á•÷M¯¼ׇaU]Úv%{…¦w$’Í5þSµåõÿ!„*äÇ&`–q ܃¦…•ecG³w:dï”À{œ=Þ+¸VÕTlLB.\H¹pɃûÅ”sgbV‡E¯¼cJù„3LËtóyDš*xàiÌÇŸèÁ}>vÄJ®ÿÞOèæFÓãàn¼ò>}L];šÆ²XDœ>²µ¡£Ü»ccãä’ÿ\\ïxGÁ{ÞsÈG?z“´PN‰G#’,ÅMAÏA-à–­ÚU ;Ó!Á¬YWÞ}SqïµWÝ¿ÄÀ2#~ýy*[¢”t/(g1KE» hãAy7zQgÇáï*ÀJÀÝù!4RœR¸PõÊŸÖ¶WÚ‡lŽšQ0ë2¦*ò`Ô+ïU•HéÒ*´Á1å}¶:À.•xÞërú´÷2%à<Þ}Övï.S8­zëŒ ÚµïE •ï( ³=÷i,£]WĪ«ìþ>\½ú{sÞüÔOÕ\½zÇ{œ¢:¯;4’à÷2Úa‡ÇÂB ¯¹’ò“Ï…Í ÷ÔÁ?þ§PýØ/&b“»¡“ò¯„ÊkÁ+*iôÞÃlePy²º]BCHÓØ:á#Ÿú¼á\õ%Wˆe%Ñb›ñç‹ 4U#à^é2¨³˜:‹ '-«GǬÌÖ°RcÞüÃ÷Ф/=¸×òO¨AG)Éqw^õ®I’Ñ#‡Iâ 46¦ˆ3ª ¡NÌ8ÄŽE}¯’Ä;Õd7âÜõSÒÉ äPkÓN)l¦Åß>¡‡wËï˃Œ‚Œ ?I×A¿Ø•Pu¶•:¢´!t-ß®¿—ºŠi‹ Kñîœ÷oâ‹eÌ¥Š:åÝ$ÄE&²ƒTÕ e²TŽBñ¼/í„¶ Ø­Xfª<¡­¤ )¯G]wüyËd¹dR/©N'8ÿÎwé2ÚÙ!¿ÝŠúÞ­’R¹„6ŠÙРsÛ'Çpˆ¨ï~6Æ>Ay7eËÖ–õÊ»{’òþûÿ(Ctgÿ o=¸·Ä·k¯Æ°»qê”âüù3Ìç^qŸrþü„³gÿËeˆ'wòÏÑõÈ#K®\9à}ï{ c,³YÂÞÞ˜—¾ô"—//X.ʲ¥m/Öã¸rå&?ÿóŸàe/»HiÊÒP–-EÑb­âÌ™”<_òÑn3YΞ…Ñ\ }cO³ØÕV^y¯åÝ:pš7þÅ÷üÓ…¢š+ê…ÂL&%–™©(ï둪4\»ö¸ßŸöÉ Úù æF>a“ô’%޽í ×´½×6h ‘±ìnìžÙ;¼Ÿ{Pn²ào~º"+þó• ¼ò+n'1—:ËL2Xf²¤!‹[Šf³”Å"b±ˆ™Ïc”R8—píÑCæã­Þ:“ÆC ƒ€Û̦œƒwõ©Ýí M#ð®œ>2Ê¥Çy²>w×4|èC·¸ï¾›<òÈŠS{L Æ‹‡è Pþ¸õ©RîÊ·m Z¹|ðƒÚRðbEuZîZàý¯¼ÞòôÏ}u¹6´© Y•Ø¥å½]ó¼‡Þ×ÞŠúnšàXƒæås÷cKwk5Eœah)¶ÊkâØcj*ÙB'åî/~º÷Y‰¨îE›QU õ*¦^ÅT*9f/°+hŠH€²x'÷6–.]£[ú)î¤ZÊ%—N¡öæ¸G“ˆ’ÒÃ{eú"¦Y"³íÓH@þ†‚ÅìÌáu¯{W¾òÒgõ¼ùßhzpÕ½Ù¸ÉüîB-Š{%‘}¹Qâ”Ò5ü±Ö|ôÿxË›à]ßöAÆYˆ¶VlVGõ±¨¿®ÎÞð·~Ž×?ú'É툨¬0K…Y)Ò´!u“ ;ÕÚCD:(ï.Q2+€m´·¬ˆmFeN ²ˆÜJ«gnF¸P¡¬ã ?ùÕP@Ø“¹H"m-:”ñ·œ0x·#FPÇ¢¼Gã;–ıÌIF媬óÄXo›©‰ùÊ/{Ã0¤éU÷ÞCs#&™J¦&Þ¶áá¾4¯aÖ¢S+ðîF}TãJùG%¯¼‡IKœÖÎp”Oi‹U;¶ÓëÇŸV”$òØXŽ6 1i@ˆç½MÄJC î†bÕŽEy†´™#;ÅÕŠ²HQFQzx§Väõ˜U=’sh ãeÁ¤^Òn„(=DCw EÖi 'x%©xÞ­xÞ»aÕq,@nj»Ö–êÕ÷•ìŒÅ‰íc"{x/ ›»ŽÍMw àwvþÉ¿Rüò;ý{¾n£«½Ï½î”÷µ†ê¦as#àÔ©˜Ó§gÏFœ9“qæ œ=+Cª¿]â ¼ªîËeíËnrÿýð·nU¼ô¥ Åüƒyæ3·±Ö±X¤= _¸0ãÂ…a¨¹téÉC÷ÞÛðž÷ŒØÝ•½wc4qæU÷]M2±„ÎÃ{›÷i+Ò$M|ã/(~èuÕô1ð#?6áû¾«å}õ1p¿Î§?}Ý_9ÞCßâÓ]<¼c½×¯{nFÔUÜ+ï²=/àn—»ò©‡EHã<´çÀ³9®ºÃp¼á9\S µ<¹/RðN#Yø¥…* Æ1O|“j,ò¾³ ‹)lÏàMoºÄ³Ÿ}§?}û³rÞT•ñV÷«W‡$†ÆgSj¡[F"ŒhÄëÞÙ 'Gi{%ü®WiÞýOá{_üq&i€s ׊­h-Ù,š%“¾à SØŒ•3[UØò€„4qȃѥÁÚy€÷Ö‘È5´c±tèÀbµ&ÿôˆR§T‘¨ï:³½òÞ¹‘¤™.v”Â+ßEƒK˜6hF:ð=U;ïU$ð>UØQˆ…¤qKQfä±ÿ²7¶ØIˆTa«^ñcvªþßrþaQÅ R¿³à•w;Ѩ±í#"WÍX²ÙɈӚ0mÉ£K#ªû‘2ìW‘d½'iE§|»ý^ŽŠ)mr!û„ì`w_÷¼›XÏm¬1I >÷@ÒfÚXàÝ5 —‹w¾ªVñ¸÷¥ K™§DFÚUË<ÁÔ!«zDY§rÝS1=:"H Õ,ñÏǶO˜ÁAã¤ÿ¡Sß;å½j%×Ý©¨/^Êk±É¸¥÷¼:Ù)ZâÀõ¿oâVL¢1±©Euwã>Ç>G¬¢1.U„®¥Ö1m²_g¬VòóUÃymÝÏØX¬ImbÝ+ï&p·<¼GïËv¡›õê{T7TE‚j¥ ©Êê:%o¼êA܆duA½#ö¬Àeú|÷ÆE4Nüî…Ëå݉]¦lRÆé`…i*Û·¥º.q¦ôÊûh(hʬ#([žûÜmªÊpöìˆÝÝ WÞ_ürÇêÈŠvØ;^u7­D¦6üÿš÷}ï\ÌînÈÞ^ÈéÓûûŠýýˆÛn›ræLò_užÀûçè:~†skÓiLQˆº~ñ✠æÄqÀŠŸû¹CÞúÖë<ø`AYZÂðAH„Üyçˆéô½€lÙݶyf3wë`cWl3ÅÇ=¼» Úƒû ºO' çÎÅr :BŽš&àËÿðuyx‡O?ØríÚu<Î06$£C󈃛ÕïA¦essÌÆ†egGñ‹o ù}¿/Â9‡s°¹Ò4Žt<øÝQ¼·Þo=^5IP­xÎÝÿ [¼Šº6,—´wïövDÓ8Æc÷Å"Æ9íKcÞð†+\¼˜ñêW?ƒÉää²;hSZ÷ð8¼iCàÌߨub‰§µ$Æ\Õ¢f/5må‡T#iµzL-ꌶËÌ™ÙÃT6!)+œS4*ÂFš¸­û„m,­’˜¸Ü×-3ݰª!èÿ{Ýï^‡1M.Êû*?¥òÞ§¾ñ*çÿìOÒ’3l3Ï=î¢úUûf-ª/kJ|À0;ð¬óðs÷yÛŒavÆ[f¼òîêÁ6“íHIÛölmÁ{Þó(A ÐZqûퟱóæŸ8⣽Ƀrýz‰s-—/mE[DÑ&7n(’Ù˜Îíˉa°Ì„Ò–š4ðø§=¼WÒR8ø#£›lÕ˜y€n-_=yCo”q¨Þç}Äô¼[4/9ÿ6ÞüÁ—ÊÏgMòÓÏ|%snÉŽH8(ÂR_ê˜kC«ZÓÔy=¢gb›QCTddʰ2RVDåQÊlrˆk†µNuWâJ6|ÉD}W ô'€ç@&’X3 ú£v1E’‰m&Ï»[ïy¿«=¾‹­Ù´‚â?¼O4áÜ*—k±çt«*•üôд¢|w¶™5Ï{þZó÷92SÉÞOްF)êdHÕÅÒžjRémèZT]¨¨"XmM€Él®É3QÒ—íä˜òž4ež¶ [$Ôyª•aUJ÷1YB½'×wc#yœS†P·âew!•ˆÂzxÇÛfl‚r¡d·{5}Õ¬â}ïN¨W†xS ª{ixúsª êÚ’$çÎ9s&㛿Sñî_h$Ü¿w¥:ÕݴLJV›†­ÍÀƒ{ÀÞ^Èþ~ÄéÓûûûûÑõuzB Ÿcªûúºpa޵Ž;ïܤ(Š¢¥®-/ι~Ýðþ÷²\¶œ9“Цqh!ab­¢,sn¿ý]¼ë]Ï—û•“:ö.žðk¿öˆ8®øé_Øän]yÏe`ÕÃûbžqÛm¾¼C ]^i)$*–šùoòÓo˜öð~óæ]cDÁ… ŒÇ£QÈÃÑûÞMÈæfÆæ¦c{[±³£8u*ÆZimèDiöN…,6Õ±Áжª„‡Bñ»Ç¡÷íÛ’ïû¾_eÌË^v‰óç³þýMÝ[Y‚ d>O˜L‚nVc‡‡ GG A0â­o}˜0T¼úÕÏømýn'ëdývëÔ)öníìgX•rp \ÓYfþÖë¤VfFœ%ÐVb ½¯V{þà õÝ Æ—ŽhôןÆÕ ÊáÆ.;B†ùä“Û—LîX’©–âŸÈpaI–» |$¤hLDÛ„Ä£š¸®)mJ\ÖâuO3k°Æ—2)ˆÚ ˜?Quï”÷Ìç,vƒ«=¼× Mõž÷|,à^1Î(̪o8E¨ZJZÂ>ŽîËÿýÏò^õœ¾MUá¸öwv™~ã«Õõbùu÷/ÁÍéŠåõRÁ^9‚Öô–™y"ðnãÁ2cŒ4¨îìHÏÃ|ÁËiÛû°Ö}FÏ›„ ¦äy‹µŽÙlBmÉws IDAT¢õœGmÙØÖüRrZÔî.ÿßÏÄcù~ÒnÖ“[ÿçPÿ⣚XÕܺ8g»½.M¹ècͪ´° E .Èzx¿‹òæÕ— –™"d6:|ØfMmwkG“Ã%7/. €âjFÞŒ¨Q½ke u“#ezÛÌ×ÿš‡Îr.ú¤ ¡ªÁ2£[*ù7T¤Ã¬¢–jš`ãPb ýQ4b™)âŒ&‹¨²„h\c'!Uœ ©N‘ÿ‹²µå`ͪ5=ïjä°S›(ÔÈ‘/G¬‚qï:³‰!Fhc‡aUÆË©’„2Nq©¢¸ž±š‰[b–ä(íÐÅe¢¸w ª6ѸXRg\$C«& ho˜ÜbÊ€U0¦j’'Á»©ÚBÑ6Š&O¨r)¤**±Ì¨hÝ$©*–Ó ©-iˆzxÏÝHàÝICéÜ Dy·DÌÖÒcÆ ¢Z”ww¤àÈ⎜ô®¬ qôÊ»+ Ï}î6um©*CUYΞóî÷%üÊÛ[ŒížÖ|µ®µî¶h7í1ëŒØeööBð{{!§NÅ¿ã$¸xÿ÷n]º´xÒ¯…áà äܹëÅñÅ"¤mΩ^yüñŠímŽ÷Þäû¾ï~þê_½ HçÝwß ¤ŒÇcö÷c^õ‡ãÖ­‚?ñ ç½Ý)67F\¾œqÛm#ÂÐç›{Å]Gr›4ª•¦Xjïsï,3"ýllĽ'ßZX,RÒ4塇 ª¶b<ŸZwlo‡TUÂéÓ0}KÓ8¶O…¤ãã©.m ׯ‰×=éàÝ–`*^ûÚ_ãe/»„RŠ—½ì’WÞac#ôð.ÇbEz Þe)êûÞÞumi[Ç›ÞôI^ñ ™?8Y'ë¿e>÷Õ*qã¦À†Üþâ?ôn€÷Ù†’ØB=(ï*‚ƒÂ·F-èõU—¥0°vÇbm¦IšŠPµ„ªÅšV…lþÅ#&,™r„V–_úç/êm3•JhšˆÝâeœBÖijcl@dšÞ.¶­ º‘# Ú^uïŽ)G½ßÒò¼¯}7oü¯¿{ žw?¬jW×(/v4M$ž]î-aoë¸`>Áý겤é[ßvvIׄ“kV=ÍɃF ÜDâ6+™K•c6,3³¦ ØJTw·íKÚ"ØÞõ}{ÒtÁÅ‹óÏè93›Å<íi ¿{è¸ë®E‘ðè£-ÿâýg …é\fR‹.b´¨œo‹òÞXXŒ¼ú^ÉÐjrÔ«šz+ƵŠoØüWd´„Çà=Ë ŽfÓ'Á»!€U‹Y)ÌRñú¯üFæÜOµ•#Ðæ˜µ åßÿ-ñ†«Àõ?ïFGÔ©Øf⬖†\­ ÛÌŸ¹ûÿâê¯í³·x }™KLPAXò3»ÎZ{xwRB\e &,3u’P(±Ìäñ›iª,fäýîû?xÕDZzp<¼wy”ÝNÎLÊõf²=¶¸©’#Q¬ò1EœQ&~`5m‰Ò†<A¢"ÝäXLd™¦üµòï³dÂ^ô.WØPÞ7¥Ñ5±÷ôÀàM*‰36ÖØÈ_·…¦É#‚ÜRWñ`›1OXÕEN[wi31y8–óæå7ˆë-’ª¢ÜI16 Q¢¼ï&פy×ÅT69n±ïÎíÀ$†P£Î6³ÔÞ6ƒØ»rCÜÊ{º•°³5ØXÚÖ†š¿ù݆¼oq y:ðz Û'DD6 {ç’Þ.#ô¿¹ù;Ãñxÿ÷ßjeYpÌú¡5=ØãzxÿØÇ¶·5ÛÛŠ7¿ù^ñŠ]î¸cÂ3ŸùËx››gÏL§rüÌæÜºCð)°Ž1·Ý6âòågÏFý «åPÑ0¼ÙÖÅRóW¾­äù_,Šsç¦}ÁÁövDÛ:Š"%I:€Ï™Íìà]¾îÉ$¢m£þûk[Çdȇô¼›ŽnxÕ=ë V¬3S–ˆ}ì€4 xñ‹ÏséRö„ARG–ÅÃ÷ÒŠò1a¸EUÉ“ýbsî܄ժa6;<=Yÿ}>ÅÜðŠ;o™¡ô'¤óu—Ö2#žTrý©¬r’KŽØfÔ¾K€­W)±= (gÛ¥u çpìjI’Qµ––Ì/úóïç?øiSU!“`)þW›•xݳ”ÀLà”ü;q[“‡#Q›¸^}O¨i‘K<‰DO"”U•È@÷¼¯§Ì¸¥âì?DSGò½„ŠP·´„ÒÞèÄàQ’Ò¸Hv€ä¨F%Ù–ë¶ÑKdk~)o>ëÝIDdâUw¯¼?¬šîøH%IS[›ïgÎì>æó˜»îZ°XLyüqxáŸÉGºÀ]Œ¥w.¬`™ƒóv¢Y óT¾ÕÅj‡Íã7&>: V5wmðÝ›ßÝ«£Iî‹.-Ë™÷a3êá]×–g¿ôîý‘3¼þ«ÿ7fÊ…“+¥üÌ…Al4ìfИ7VÔ¥4ê–¤ÔZZ@+dE˜õ>êÜŒ8¸¹Á§vØÏ®âr/¬*MÐØþÜÇ÷Uuð®BÿÌà@} ê§'ØTÀÝŽBª(!W£Þ6#ùò fpö &¥œ#ÁšênÖì@%ȃ;p#uÌ6c'ZZ„µÀ{‘d*#Ê’´"·#l+ÁK7a¥Çý°j™¦¸‘B[KÓDœž?‚-ä½?V÷pn¢@Ò”Õ縻D¬4&hlD›kê›ÒÓ$Õ!aÜrskAljÑM>/ù‡vÖ{åd(µµaï{okMÖZ&:x×êä¼{h?²p¨ ‘Yº¸ÑŒ•Ïê"0‡šøïþÊ «+÷0É Ÿk†£SÜýë`—«LðÝñ;]'ð~²žrÇçÎe8ÓiHÓØpµÖ¬V–ƒÅö¶bkKqï½¼èEoñÐ.à.í –³gÃÞ§Ó€ÍÍ„?^²³7æòå·Ý–qùrÆb1Р×-3ÂM¹õýgvF’|‚§?}σ»¨îqbŒ£mCÒTà}4û‰ÞwväkŸN{ÌŒñÞKûdx8AÕ8õ=jÎ^ÚæöÛg\º4åâÅ.ÌcÆã'{ל¾¿¶u>q&a§‡÷º6œ=;>÷“õß× ±ð5ïÙ&|é+ñ©!f8ÙaGLñóvÊ{ÞÂÆÐÖ-ü¡ÛÅÿëSDt`q±€;$m%Ck:–üe+þtƒDCæn$9NóìoúVi~þüáMªXü«aÙRr3î,3(ë–Ö„´™DL6&’ÆMo™I)™rÔƒ{EÒ{ß[Bê*pÄóÞûª³óôOËЬ–²!*šDl9ë™Ò¥J™Ø%7Y4­(w…Cc»[œB}äÁýÈÃ{¼è‹à¿6@ûÚÀª‰Å"Ó «;ßó°³#¾÷Éä³xÎl$l>Ý?p¤ƒd4…ùHRW¢J#—d™¨îóLj-#9n\·T´LTM±Ÿñ-·½VZ5ã´÷&w¾÷¸ª‰Ê†²L9J§Çà}¼Z±_Ç,Ï2Ë)32 ù“N‰…fÝ>“ÓG7\©ú‡µBg¢¼wçB‰eÆ{©ÿÔ=?ÎC¿z–ÝÅ5\%àÞ@»nuJKé,‰Øž4`•öTYҧ̘QH§:ëVUæ¨F v°1:†ž;Õ=]³Ìt¯#Äïî=ïjä°é0°j§šÕ-ñ±wð^ë˜:•#¯F´&d©&½úÞ)ïßdþ16Ò4«ˆI¼dzßQþ¶:¤$ÔDD@zÛ ‰@Õ.¦,%gÝäŽ:—¶ÔnÎ 7#÷5õ=ªÂÂÑ–ƒò^è ~ÿ£õEâªæð⌚˜‹Óó,>Ä-;§¶¾ÇÁÆ¢¾»¤·Í´uy- ¬Á»·ÃDµ•R¦#|QP‹@QßtL~ ÷Ê[ßjùÅ_̹rå@À=ˆä‡d#p¥@»õ³vmÝ7«ŽÇþ~ÜCûºefo/ü]í²ŸÀû‰êþ[®ÉDøýýÎR"o­â¡‡Vlo Ÿ:±\¦üæoÞ:öç77c67-[[ö¼W•â™Ï|ׯ¿—Ë—³Þ2j€wuÜ2c-JS,ò#ÍÕGáó?ÿEìî^íU÷³gÇ=·­#MS’$aggF];ö÷S¶·ñÊ»b:}òÓ]Dá,çÆ8¶6NíÅÜ:?"_Í¢HsÛmÜ~û‚‹g\¼8Jp¹„¡I¢üõp7¶ÖQ×–4=ñ»Ÿ¬ÏÀãàO~'’® ýa…§3|ۧ™Ay¼5„ƽä Es<&ÒŽô j÷‹&rMî­ ©(ïñ°[§yá«™G_{JJxŒÆ6šb$^÷ж¸Vò¶“¶¢5R»^›˜¦<î»\cÁM±É˜P<ÍkYá-!à«~ž7¾ñ¢¾¯bh ¯GL¿àˆ¶ {hr¡ê&ˆŽå7D½ú®—5,-®t¨¢ë—ðŸŸcŸ y´ï-p~ÈuïÀ}î_[Ÿ2Ó}æ# ËÛ;¢¼6—z6°½öðáÆ”+ëáÝqä¿LÞ¿…oÌÞý™9Ÿü@Î+¿åu¤”ÔÄØZ‹}$òödWE­U•PV)ËTÔ÷Þ“¼bdsÞöç¾’â0c{têV‚sŠQš£[{,t¬SÆ;Ÿøa5“¹‡F"kÓèHŠ”²h _fÞε»\;Øå®ÅG±×4¥KÈ/|âR¯O‰ê¬à»âYí  {ÛÌH2ÜÍHÎÉ6E…ÎRtf©²„çýç÷°ÈnâJÕþªÔ  ë¶™.Ï}$ð®Ç› ð^éDÔt=¦ˆ2Ê4•k!^Œ¨MÌRðž‡#Vá7RüÙ·þËãÿ¦•‡&¨£˜(j°‘ÆEªx—* %³e‘R·&7¹¡¬RVɘ¼ Ê»šRÖ)«vLV8šÂ+ïE‘ƒÑe’*§Ýù’/ü•Þr·4QÜm$ó,Þë^Û˜ÂeT&#«–XL¢HRfô63Øf”WÞ5I¤ÙÜR–+^ñ¿ü*ÿá?<ÿØõðÐCŽ·¿=çc»Ic+Éu ØD ]yËLÛÍÙÉàªj[öÏ%Çà]ÔwøÉäw—wï'àþ_\]ÙÏ—µ y>¢®[“±4áÁ—kð>asÓ°¹i Àé4d>‹J*žÿü/¥mæòåg΄=¸ãˆ5ËŒµG¢ºß¼¡ØÚ‚ûî»Ê‹^ô4._–Ëù<<ïÓiJ–eÔuB];âXsæLÆînÀÎÎïìI7O{ÚÆ1ýÒ¥UeØßqáÂŒK—6ØÛÿ®ßk­Õ ¸Ÿ¬ÏŒ)ø¿ù£ðþ_ÀKëVÔwëýîqÀ4öÓ͠¼Gƶ†å­Jö”±$°tÑv¡£°«œSu0¨îþpN ´ÊE­³Ai(ô÷¨•aÑÈ4´&¤PYo™©MLc#ÎëO2åH@°R`¤Ý²xC€1®R½u¦YE´u()3µî“l\ zåÝ…’)ߪ°Wß[B 2)ZZ9J‡*%U¥û}Ó3ò¹U.Ÿï à>À×ef Þ»’¶Ïê¹òo¾¥”‰(ÙÉæÊ5R²U5ù¤™¹/ê ÿi/ùqî~‰@»Æ¢ZG[‡”*¥ ¤²¾%D;Kœ×èÊRViŸ8cˆŠ†fñ ÿùшÀy¨rŠ$®$ý«ò_s‹ÌŒ¢5ÌŠC®»m±Í¼×YLe~ŸyU˜píÆ.{‹Çäó`˜¹b€vK½ÅE+oŸQš6 QÇ×>ëõü³G¿; )#ÉŸ¦GËŒ*KЙŌC6²l¡%K>RèÈgµûŽ€cøêîá]Ä`zÛLuk ÞCñ¼W¡€{•%äûUå£"d¼¿’×ñ7Þþ=¢¤wž{ðµŽå9ޱ‘FENvÛbQÞK•Jf|3¦(3š:¢ÍUžbòVúj÷•˫Öf¼tT…d¼—E _3᫾íÿ!¡"¦&À ±äfDÕ&4*¼îxx÷K_À´jˆS%Š»”÷‰‚¸K›9Ò¸#ËÞΈÉdÌînÈÎNÌéÓðÚ×^á[¾eൟÿy÷ûî» z$€’euÊoGÚF†V(ï»»qîÝ!±»û»Gðx?÷ßÕº|yŠs¢¯Ã{Óz¨`<ŽÙT¤œ( ,ã~8Tž>ϰ³“1Ÿ¯{Áýö¾>ï£Ll3׃ímÅ'?yÈ}÷=Ê _øtžñŒ)JuI.ò÷on¦lmÍ©kñ×µõ-fÙïîb U?ȵ¹™øésC][ΟŸpþüää$?YÿC/­ÜCç¨+îjð½Oã ÷_·ˆê^ypß»gƒå§ŠÜ ßDÔ{ìúÅV‡ØP”Ìn(µU’aî•w‹–¿bUSY±ÉdeA9xïüîÚX)x2’‘ý‚Ï{'ÿé/£61—ôƒj4ªr8«¨T"¯Å÷îJ…+•XgBñ¼›6 øAm¤1RëÚ és¤Û@ÊgŒ $‡ÜÄ~Ë]Š^\åP•ëc"³± ÈU†ã¶™VºŽ¶7§x6›`_Ò¶€$ùì#ê¹k°hÖ:ÖT÷ùHv';Õ=óçÖÌÛf”X½óoê ³ºÃÕŠ 6”*¥2Š4£&&É+š<‚ŠA}O&´„ÌV‡´yHÞŽ ½ÑcTUBâQ-Í0(ÕÚ«ã\‡°}ÿu~ýÜ3ŽÛf´XfŠ ãŽöc¨¥ãÓnçÿcï̓¥Íîú¾Ï9çÙz¿Ë{×wÍŒ4´X‚DH2R0`Ù`[«‰Áe¶8IUb*`Rq¹R©TRelÊ N•S ÈUr¢2؈…A¢@b$’˜4š™wÍúî÷¾·»Ÿí<çœüñ{úé¾3F¨Ì¸U§ú]»oß~úöç|Ï÷÷ýqýÖw#?îSû„ÝǯwÚû]w”4y×&¢‰"ôÀ‹ kÅ2³è )wÕ ¼ëꯢBÀÇZˆ,•´Ýßšå¦DÑùËW•w5”ÿ«0Rä7úÌÕ@¼õmÃj•¬(ï¡mXÕmÚLËÌÿùûOžKÃr¸X{’Vè>ÑØ$Æ'š(jäëÁ)ÓMkÍmŸ²Ì¨Ë¼§¸\Þ›¹m‡CµÏ\Þ®4Eh-3)ù;øþŸyow½,쬋©Ù°W´ï“ÎW‡„ÓNMõ¢¼GCCß6¬®(ïj.o*ÏÎ+4gÎ ØØð\¼ØçÌ™œÃßúÔ1o|ã¿ÿû÷ß§?}BD.îŠ5æ¤ZZeT-ðÞ¼÷ÒÐyÜe%§ø—Rkx_×KxÉŠo‡µ MãhG¯6ˆ:Ä2c­îà}w7ââEQݵV§”w'S³»EÞÃxh89ýö¶Xv>ÿù+<üð¯{݃ƒU Ôµ¦ªb¬õÔµ§®ÃaD¿ÿ§W·£Hóu_·Ý{YÊíxEëAIëú»’í›ìîOØÛ5ܺ˜O[ÛLãè÷Å.3NÄÝ´ž÷ãFàýÆÓs°n ï¶'@Ñz^‰ÛËEÊGÜS éÖ4Š*éwÉ! Õ=W¸¹açû®óäo^BùлñŽÐ(Wó 鈽%v–ºŠøÆ ãóúÎváÑx'Íu¼·o}Œ®<¾ÒTu›ó>yìïÄÔN’aV,3 pNÉ©Ab$éBÇX·àaê ó@(¡ Ò ª`8Q¹1¼áä ¼eryiŸiW:Ù«ðÞï}õ®õš9ÄÃ^»>%_÷¨/Šûà“x ïuëœd²1 Ô?ùWd+ÍÂ5 Ê\m:x_(ïEÒCçž:Op•¡¬2QßÓÞkúyη½îƒ'=R*²¬¤®&ýÛ$¾hoc%uõ4ˆ.‡~Ñã°j›±½˜m5 x«¹v²Ëîæ5B£ÈCŸÃ>×lð‹a\ xo½õ-ö°( Ñ# þ‰Š¬¢T®/£ÈÓ>eÛÌ0ž±µu ,0%ÍRu_¬zEéO^ ¼ƒ$ eáFóX”÷<éS§‰lbÊ»ïãffZÛ Cn=µ%ÉŠâžÈó*‘×H%›Ä¸X&ªªD6îózÀÔŒ˜ù¹íS”=ª<Âåš*O%ãÝ´Ê;ïe•-¹kËsñMœ}ßs½öøþõÞS›=EÀ-“R]*$1ªm¾THh¬Y‚û´UÞûɲQuEykO\{ê©g{;°½8~ÀpXqpsî\ÂÙ³gÏf<õ”åÞ{çüážðøsØ<Ûç$Ë5 Z¯»[$Í,•÷½s½xO88Xªï/u°âÞתûK:†¿óÎMãisçZ+êÚ³³£;€?wΰ¹¹TÝ›†CÍþ~ÌxüÅazUu—¬uÍëŠ3gÄÿ¹½ Ÿýìó|úÓ#¶·¾íÛî`w·ß)ŒYfþLl(J-ï{2Y_ÛëúóQãý§¹p~™ÝHlhJqKÁÑ Ú‰êžÀ¨øºõ¼ÇC½®ÏíÜ‚Q îóT@½›é[2tðžöÅÎ…†à> 4NQ¦}\02=U)ÌÜárƒ3†¦Ž$õ£÷ØYþê7ÿ{bg©ªïУ&ÇùÞ3<¥.tðN ¦’‰Ç•J)UF¥R|£Qexom3Ÿ}××ÕM—ßYfŒ€»n<>hwe:ëaÈgž0 øJà=r_##Jßm:¿ ïD‡°¿Ÿ°9Têž.†=)IÚŠÚßîs×ɲˆá0ù’Íð_‘Ÿk¯|8XÂÛàÞ ÑG`kSÖd +K[ÛL½üY½1åý7ßñ¯I1ô(:xoˆ(ë S;¢º9ïi§¼Û*îà}Æ8·]¤'ûÏQ…”QJêª%¼·§NLæNO)mÕ÷¼nV“žX§´¤©™¬£ÃM®=¹Ë^¸J©2ÎÿOËÿ /Pô³|Þç·„¢‰"ÂP‰‹¢ßæ··àÞ)ï*å{ë_ ,3ü@N|LìPq8 ï«*ÿbõ—껵ð>T·RÉ‘Oû]ÚLJ£jÕK)¢¹ïc›¸ƒ÷Ë'wIJOX÷öù”Q&é-º‡‰uœ ’€‹ ql©]¼0SC¦aÈÜDyÏãÓðžöÉ«¾(³€öƒƒ˜ÍÍ—ŽÞkx_ƒûK<†WÜ}÷dÅBØÞN©*Ïpqx˜qæŒâÜ9C]«Sðn lnš?òˆ_¯nN{ŠK—úܺµ\ÓiŸ¼Ž1 cßú­wpæLo}Ñ­k]+µwþa.œŸ°»3‹²›h%K)n]¿ûÂ23N ´ÐOä7ž*ÛA#m£j5‚,,ÕǼ·ànö!µºòà 4 Ÿ‚wç¡H%¿Û”îÍ<¢1U“¢| ò &8Þñ-¿!Ðî4Þk‚“<ïÌzje¨¡H{N§ª ;ºK›©H¥áµ øRó¦¿öq>ôkoåÅNÓ»×ZÀ=ˆâî9!X@»´üËRyŸµÊ{%껪ƒ‘b‰òž9Yy ïñØd†-¼ïï'lô%ãý‹ÕÓOŸðØcGÜwß”R ‡ {{Þþö‹Œ¾rà~þs . èºx7é&{6o‡­kÒ<»PÞ{ýÖ2–§£[ðKo?½Ö*cpd”$Ôœ0îàÝÔŽBõ(€¡³FÀ=qÖP–U•RÔ=Ô<ð»¿Da{ Ìœ~?Çx‡ª¶ŠÅòdåûE^÷IÓŠ¤W/á=‚ʧ¼9ü.ï­¿Ÿ2Ë:ÛÌ`>GÍzî¹~{‡½Í«„›J,: ˆ^úÄŠ þxÏOú$ƒš&Š`nhp}C•¤¸wð¥ØYÌîî5|%>r•iTmïßž(ô_ï+껼å=¿ÚgîÝÔÔ"éa39]¨2¹Èrß§"eêFÜg^OœØå%¬œ"(E$¨T&v¸DRf‘‘yÙgnL#‰}Ì›þ‹á}®Å6S÷™Å’4³xÿ,”w ­­ŠÛ½ŠëðÝ{QÝK—Qٔʧ]ÂŒÕ1)óUÕ}ê¡´$c°Èy_øÝm ®pŒîjû(”µ¨î®õ¸«RnƒØfÆ#ÅáaÊþ~z Þ÷öD©•ç—×ð¾®—^Q¤¸ûî1ÞŒQÝ4²ºöœ;×çüùý¾zIv•E;7ê|öÞΞQ çψ"ÍõëùÞ×µ®Å~·ÿav÷'œoÁ}w?&жÒb¥ˆ•"‹Mg—'0J•D:ÇõMÃOËÀ‘ZÁ´ßF£­€{´b™ÑT¶SoƒS„p^Öb“_&)Y^ÑÌ#ÜÜÐD{o¼ÊÕö°qŒu1¹îCEíÁɇymÜkcëcŽã-‚UèÊŸ†w•â46]*ï¤P6m}À) :Bé€ åÊ…Î2ãµå=5SM«z~a©¼‡ja›ñ 7M§¼÷¼¬¼OvDeOe®LVüâæGG%—/ßj—¼sž·½í"Æ(Þö¶Kªù²t§N$Õæ½Üa °:0ñ2€fUàÏÂk6èRd÷A¼<ýåﺗ~u>wƒ#Æ!yù³ñôF%¶½TÞµóØ<¦Î¥¹¬2Ê2£)"\ßpm°KšÓï\ûÆ IDATç2%µé¡\àŽè‰nÂjèI£pQöð±Fgž(k:kˬ27ƒÙf†³zæ¹½5áÚ­]†ÓjxÕû–,õÀ{QõèŠ%¼¯Ø[ª4E<.2¨a D§šU‰D}/ÒÃü*õÍ„áÁ ¤‰‹NüÒ¾²˜Û{Áfá¾w5’^“¢îQØž€{Û°ZÆ™X]2CÕ“Þ¿ø¦ð+¿÷N~gü6âÊ…æÅ› eèQz÷B‰ò®’@ˆ>Ö4eÄÜDy÷25µ´Y ïW¬(ïq«¼«!MÉãTí&¸¶P(þò¿ü=j$©*Æbpx4µKÜ[õ½‰üÚKCº6†‚ù4œVÞ«†ÄúådÕ6&2©}§¼OZËŒÀ»fgGuͤO?]òÖïC:†íö{(l)˜|«¾×àk"í88èqx˜vïïÝÝ¥ç]½ÄÙ‹y~™Áàî5¼¯U÷¯Lűæî»Çê^×2J¸×3ìïeaúÂÙ(ŒF1EÑtëâÅÉŸùôÁu­ë?äúä'OøàoòÛ¿}ƒ}ì.l°»³Ó‚ûÂ2ã<ôcQÝã¡ßW§>Šàhsã'\*© í†iR<˜Ð·«{bÂÌuŠ;‚vÒÓNvN~Ýû<ÂEð¢”~óßúmª*%*‚Wú®]m4Öh¬–åŒØaL%ª®ÃtžwãfØÆ*#ðR‰ÉTº;)P±Á’„¢—“‚…ef¡¼+½Ìjo<ÂÌuÊ»/=ÔQÃHà}¡¼3xço?„÷~t‹ÿãÍ iúbïkÓx{ì¨]Çݯ÷÷<÷ÜŒ¼ŽÖš·½í";;ý/ûú89±|ä#×¹÷ÞëÜ{ï5>þÉ ^Í8Ûæ¤)!ñ²SÃ%È-š#gðž«ðÓ÷HÃêh$–7ËÌ?}Ó}îíÌÛy–è-ñ²aU·–•’Tµ€{‹¦µÍ˜©ã‡~ž›¯Úfßf çÌÝ ›¨Š—t–…½r)yÜÇŽ9&uÔ$ÌjÉ3Ïë>•N±ZòÿõÌ£æ£Wm2®Oð^óºÜÚr³·óf ð¾êy×0Ÿ ¨Ò”x`%mfpCƒí%”&œRÞó¤ÏÉј{v?4QÒ ’ ð^szBlå×’­|&§FA&Ç^?®ú¼×IB$Ѓ\÷;+ʯÜýNÉÔ÷íäbN?G‡¡t’×^jQßMì0‰Ã'—ÔQ`΀¹t‘“µM¨Ë„:G”÷yŠ+ yÖ§¨zÌâÖ2³°!Í€ÊòÖv«OG²ÆXœ3K›ÌÂ:ãÓe PHË!zð³åÝZ’Fà}¤åý8T [¿ûÙý„^O³µºÙ/;;šÃà ­=¯|GO®ûEÏ´¨v©º;ÛÎɰ2´1Ôìïg¤¤Àˆê>¼4ŸûÜam›YƒûW°ÒÔppÐÿª<Ö¥KêÎùÞC€^o}I¯ë?ÎzòÉ‚¸ÍcñÌ37ISÇî®æÂù%¼/,3Îà SÄ­uÆZƒ1ª³ÌŒP&p㩼mTmUwדIB)P´à~ Þaª:Å}qëc‡ï–§fÁù%¸ç’èÒD”ð¦¿óq¦½ƒã9QÕœ²Ì$ÖS‡Vyײ¬Ñ4UŒ®=¦r8µ„÷·i+\iÞ ê{— ó¢UöF5á”e& υлei›™B%‰3ã‘@¨Uݳv1ƒÉ™eDäÞ”Wø’Þ×%¸/×p˜pÇ›ÜqÇwܱÁ¥KL&²šÏ|æ6yÜå=öèØÓïåÌë33dîä®ß5'³5 äYŸ[Ç[ì_áÛ?÷kr-YFM®ÂûtÀ0›‘ÊÓð>P§ ¶ÓÄzèqC§]ÃìÞßœý.ÖÆì^C•b—©Iˆ=ݨºPÝW•÷•Õ$²Yª\"^wÛ VrÓïâMæº,ýÿ®úL$SO½§T÷€€»Î(œœŽˆòn"ñä7e„*sÓ*ïNཱ¶Œ©ó†&dCVÅä•ôÌ›¼w7…¿ðã7°“¸{“vUâq÷_ÞÛ?KŒU½µÃ” õ}êÁ/á}h–ššJl3wßÝ£iÄ.³½-ž÷À›³J„ ­–Ê,À½i–ðÞ8£¡ê¬1Kx—µ³óÒ{U྆÷5¸ÿ¹/c4ÃaÂp¸žHº®ÿx«(._>æé§oñÌ3²ÇìîΟ_d™ñо¨îƒT"VåƒL|ï£>yÛsýé¹À{m¡HÄ.ãbé[Øe"¿„¿ )¡^,ßx_µÎ`=M/î<ï.2¸Èðºï»ŸY_ƦGUC\ÙS–™~í¨Y‚{m¤!ÒÕ­ò^IwÒB»¬´†¯ãLsCQKž^ì!\ì†ótQ‘®‘Í[ˆÅ÷>¾½a$×Ó_ß|Š¡‘fâàÅ>¥•\ Q×P|ž§y´¾û”ò®œô)tÊ{º„÷¾þó<öª;9Ç3ŒnN¹±y†~•ó]ü[ö˜SÓoó¢Oõ»¬tT˜9±ÌÌÀRg’T¢ÒY…šŽÏo5 ?ü…Ÿ_^Ë£Ã{U¥2ô(KÉÆ§á}öÌ*IIÓŠ¦a74Üiãrï.‚QbÁÂN¯Þ}ˆÞ¨ *Sòº²™w ²!Š’f©¼·Ð^G µNpÞД†<¸ç¶ßÙfФ'ð'Ä=KMÂßwÿµKP6HòOb0J2ÔðÞ¸H^•uÖ¦‚QÜtê;Ç*Å<,‡.é¾ÑøRSç6OÄ6SiŠºG^õ 3uÚ¢3»£Lè6|‹þ•ÒeéN€½³ÎøàUÂv îC© ” Õ}æ!4$Ö ¸·ªûPÁ¼öLRMÿ®^Y·“âàßðŽM îzq‹] d³b›€WÁ²·×ï0‰âžvö¸—Zy~ùÔï×ð¾®u­k]Îë‘GŽyâ ö§Ÿ¾…Ö–Ý]Ãî®áB ïgö¢SÑ«ÕPT÷qÔ5‘ïî&=Å0FT÷§r±ÌÄì@à]º:åÏ¢¿ûë´ƒ7§U÷€#à$Ñ‹úîíÿóôÿFŽû±Ì4QÄ´?Âõ YU×öTÃ*.àjUKËŒ5WÊa*‡®<ލHÑ®À‡µŠªL;ÛÌÂ:%°»e(,” QßEd°Tçq_Xe’ö×5ð5>軜÷PÆÙRyÏV”÷IÅB†/ïJÁÞpÐõx¸ë®-ÒÔðŠWl´êû&ÛÛ_¾ñùçK|ð6>x›[·jÆ“”·¼ñ.âlÈoèD…¼ì†öf¡ºÛn¢îßüéˆGß “!¸>¼zz̆õDyƒ$A( °‰L¢íQHN72óÖ×o1úiïIYÓT!W¢¼#à®§žgÏž¥tÃbF:­˜‡üpýóx¥Q!‚L÷È›>E$S[C¬:pAIʉ‘Ló¿üàß|ü»±:FÏ=˜îøéÿƒeÒÊpEñŽ—°9sC‰]LSûvCWä=æˆm¦JRü@c†70|ÿè½üñÿÚ¥î˜Ò‘5%»g¯q»šà*9y¸{øèr’-àzrEÂà[õ=býi\D(E ï Ï{®úq:‘áJ)Š ý øF3NOº~­üÒÓo{ª…w×£Œ%qÆÄNVéPeÀYÃLIêÌIä$(¡É=u›ÛnkQÞ‹º·<½j×?õ¾¯iˆˆh:p·^&¨Z ´»T,yÂ#óÈ#Ç<úè17nLÙÝMÛ,ÝYg†ãÓñ«oxg€ÍRͯüTIÓ664»»†O=f¹Ñªîõ´‚$ŸÈŠ9­ºG€j»W‘ˆ+¶9<·xl×*ïÚ³ûµ7%&ò¿6Dºa¤§œè±Ä÷UAꪦ³ÌDÍ_¹¥eÆj£q.ÂÉו—ä•’53¯h¬xâ}ÙÂ;)»—&}E8ž‚ªQ¸¦åYZdО¶à±PßW<(ë«ÊûbÙ\Bû¤½ÕcøõÂ_yë;QTÀïîÈsKž[673^ñŠ?QoOUy®\)1Fqñâç¯þºsìîñ¡]çêsG0qðõ¯[‚Õ|à}¡i³Ô4š­MÍæ²ûj&‘%Ž,ù¨Ï°žá•¦1¹éw6ˆ>9}r^Ë1Y¡¤³éPòÒ³Û‰’Ô2ÏEÕ_€½ˆe¦FÌôœ>1KŒ: \Ø} 9nÏ&¸Ú0d¶öÄ‹á]%Aï Ócîï>‚ÒuC^¨¼/à}¦üàô=2(ªQ Ò9ÊœåÝ+±:5>HK€/¢eÚŒ‰æDàÝÖ±ô¡ë\yî§fð–ÿJ/¢‚ùß(¨ƒ€{hÀz9ž(5ÛoI Ÿ…xnI¢š0Tx+ª»Wš<X]ø—5žE×ÀZÖ¢ºã‘ÍV)Ê»ÍcÊDKÞ²÷1žžã®+—Þšqõì?iÿ S5xWM·j÷H1òn*Ç<ÏûŒ¡LÐýN…žÂ÷x÷ïü¼¾}yM}- '½Q±TÞºN˜÷2Ë(ÓŒx,ð>{^îÛ§ºkZ† nh8aÌœ1–„šž/83¸ÁÌiªW^¿yœœwgd©$t‘TÈ}ŸÜË”Xç ª´äª×yÞïyÒÇÆ1ÎFõ”0R”óŒ,*‰•<|å:å]+/¯K”Q„ž(ï*£Œz²Ù‰Á:÷ÆEKËŒ—œ÷ªI&K»Ì`ÅóÞûÔƒq’6cN+ïw\Ê:p—[î¿÷ßxîÿý â‚‘÷APÐTKåÝÕà*ùùÕªï{m~û… ~%e&ú3±Ë¬á}]ëZ׺^µ¿ß—ÐvÚ1(”R<ôÐ1ï~÷Ãx¯xûÛ?Ü + m›OK r<8Íë¾[`úgÿAΧs®?Ë@&·ñ(wÞµ‚œš"ºéƒÃ‡óªµÍˆr¿ñZ«L7ˆ%hÕ¼ªƒ$Í´žwïÄOíj‡¯6‰±Æ`µL>u¥è°ÎLå°QLð¯±Vc눦ŒeÀÏ@ì2{Û† „I?‡v‚ìŠòž®<·dùçþ[îA¿ç³„*0ÉèÖªò>NaÃp°TÝÇ)dØ9ðmHSÃæfö§¾F66âàáλ÷ùýOÜâêsG\yþÞ|O«¨·ž*ZhA1ÙÒܾi[xwPj(5ªÖè÷GlDµ¨î[}[ãÑäÃ>:öd”§À=§OC„"ðªïz˜ß{ß7WWtéq¹ÛL/#äŠgÏets*ªûh‡q?G£#Êuðn”#R ½ªè,3EÜëà$·fZÏ»HT£ïÑ„ˆ_üÃïé +DduLÕ¤Ä=KÔk:ÛÌ춤ՔiÖM,¦T6eDyש'M+Išê4‘©§­ò^ÍS.î~ÆGܶš:âÛ¯ÿÚr(–õ}ÞW³Ý-±€¹ï“ë>ˆÊ‚B¯ØfÒ•Œ÷$&±5ß|òÛ”Û±²Ä©%2 ^--3*J¾‡MµüJ`¾4:ölᘖÒT^Ô=æ‘ÄDΚ!³dHbk’²Fç1UžQå)9’4³ ï±·¨(úd”rÒµ8)rbª]Bã#±Ì¬¨ï¦SÓ­mfHk›™ù¥u&r¢¼¿ÀóÎ ù³ÿ"ðñ{k‚®A{™’¦ x ¶½€vÛZg4žÍ Ó _ÚßO¸p!âðPkÒ¯X,äÞתûºÖµ®—aZ€¥t ðšûï¿ÅOüDì¤e ¢±À' œ¯Ñ®~aΕ'g¸¹c3ec²l“ë׳ÂKÞqÔÞ~£"61v¶ÜEê×8'Ê»­¥iµ"e3†ÝmÍî–áö¬µÌ(øÂó%Ô±Db®*ïÍ @~‘:SC˜«~öL”÷È-Uw硟ö¼Ç_¼¥js3áÒ%xð³s®›;å}±ÜÀ0?H ’¤¦JÓ®Yõ„1%™ü5£0e«¾Å<@ßóÌ/ÊæaÞ‹²‡´4p#Q˜m<ä¢!wîÅã¼!.‘É©_¢a5®-ÑFCí¢´!Ž,M‹~>Hm¤BP’»e-¼·ê{$+Š< %EÙC•ÜIzÌÜKÚÌÔÈšWâ<îl3¹éSWIïÉ›j2[rtÇ&q°(µ ˆ¬œô·,wëbQÛ[Ï»  ƒ(9áJíJÒÌlïˆÕÁ—éü^àÿYsùò1hFT{ü@€Z”÷Pµöwí={{ã•áK1‡‡)gÏjSƒ—6׿÷5¼¯Á}]ëZ×ˤΞòè£7oF|þópï½5Þ®A©—ÆS—´T•P¦v¼onk>øÐÝô³#^ûÚÒt‡,ÛáÖ-EÓxª+[x¢ €IàÖU^l›‰[Ë ¾k¾ÌîÜÇ7,’zÑ~p/”wm=¡ûB}"inã*‡¯ÛéªmÚLã"\)žw«dÀõ’5.ð.ž÷¦ÖTuJ’jF‘(ï=-оPÝëãÖ£ÍÖ›@{$ŸçÒÌ aON§É #ù¼ïyñ»;irÞ'ÉWÞArÞŸ|âˆgž:âÞêMðè™@1óbh\§ºdž­ Céœ*IeÊê ¢ '~túØsGö¹ëã•æ‡>óîenû ¼Ï›!R˜žÃƒ5$à‚aÎ@ž£kŒk iéÉã¥mfÞ½Ò¼ùæïR\ê16â˱ÄôºáY‹eULaz§Vi2 “QÆ[T$D”e&ðú’6ðÔä­† ¼éŠêþfGZWÌ÷„TòþµËN0ªƒ÷E¾{í–i3.$KïúÂï¾255©YzÞ§’œ´j›‰¿¼7 üú¿³\¾|Œu• & ê^ÛÐB»ªJÀÝJÊÌînÊî®éÀ}±ÎK9sæ¥Ûeþ(pŸÏ]ÃûÜ×µ®u½j‘áýÈ#SÊÒsáÂGG†Û·[pO*¨GÐ$ ZÕ=j•wc;xß'lM`§Ÿ‘eîGG ¥$©áú_ïÓ@܃¤'·:‚:‚Ùñi€÷=‡G–ówç«QMh/ƒ4¦Š[å]•a ï®õ¼7Š~íñµ Œ6Ýr¥¬†§Ä÷|«ö‡oÄ6ÓԚʦllKæ¯?>ç¿xEJÙ‚ûõ's(Z ,•÷¸kD%-äs|±òÿùkÿî“K(o›V›B§¿% ÂQ£%ào&©þÕª££šW|ëâD—¦Ø:§xöÊÞ}«ºÃdß°9RlŽàèZ›i]j övŸ8:¦ØïQ$=¢ÐàbƒŽ=&–¦Ã…ef¡º/VC„ÃབœÿVywsi8¾cç n¶Ùºy‹ï|Ë/uxY…”BõDyGu–™~™£­'o– «*–¹:xQÞY¦ÍøHóožùn|Ö~…AK3¨ËŒõòõVI ðË|Þzæ£!* âyÏD‘^¨î…é§–*MI³Š`TÛü™ñ·ýÿÃ/êïaX͘§þËþ‹Ó';m–¸³†Ù|ˆŠý^.¶™6ãÝžÄäôeДï37ñÌ— …?­¼/ÒfR[1èÍ FußÿŠ”€"¥’ Ph:¨/i•öF2ø»)¸&#Á‘`(Ë JºfÕâyŸ†ÁÊûW­*ïÈ”dÞXcžUm¥ÄÖ¢•'6–­ìÓfÔÁ»wËɪ‹¸ÈÉÖWÖÂ6Ûð%”w÷þ—{yï{%b÷òåcP4©ülT D¥LN¥wÕÂ{S“FžÝÝ>»»KÛÌÞÞr½ÔúR>÷¸¯•÷u­k]ëzÔ3Ï\¹R’e†K—L&š£#ÃÑ‘æùç=³¼U”µa4‰™žTîÎiÀ+úý˜Q`k¯=\€»FkpÎóÁqÌn íIâ¾Ü J ªÀæ«‘¾»Ýù&hZµ}a™iá]QÞU„BJEJ¬0U ÇWW;êFì2µÖßÝ•„е"²S|hd5UØZˆE×}™ËÌ´ö\ûB¹i©ÜƒÕKå=FŒµe îU õ-ÀWüÈÒÙÖ2ãh- ªãΟŸC¤äØiÂìÏüÙzc"_wƒÄ|6â»ß+¦½Àɵ¥ò®PLzI¶FŠ£/4’´Q*ê¿ß#×ø‘–DKj ãQÒŒ’à•Döú/‚÷dVwÖ™…òJÅ•‹ûèÚóoÿ§D4ê>õ#I?Q½Ny7J¢ ƒUÌí ó¼ëØË4^ïÑÁ3 #ñ¼3àGžÿ9úïÞFic‰³´^ú" §–Y)à>3CâÌv¶™™v~÷…Ÿ¦U’RÐ&cFl·˜ë?õ™L•¤˜Ø'v™ïûŠèÈ£OH”ØfÈoõ;å}îÌôç ”e™‡å„Õ"éñ¦göš! u÷½/èµ-¢†„šH54A6H%™¨î‘l’ÊV}·¹!˜Ny§D¾+*ÿ¢iU[OT6D-¼×y"‰9ã‘&µ噌0Õý™§ù)s7À7𦑄ï4u“t¶æ Ãa´TÛÍJêìá¸|ùˆÏ~ö6EÑ Ç íNI{:»ŒªÄç®–¶™ÝƒŒÓ)ï«ê{½4£ûg—YÔÞתûºÖµ®?çµ»›2ŸKC"@’ÄiŽ5ŸúÔ”Ù¼‚‚Ý݈ñ=ÅÍë[¶ |€Í½ˆÍQ`s¯yÍÇÇ­åNö‰c66·ØX@{ ñQ*ijU,ëšxÞ%"RÖõ»¾í” EÙ€ª—à®B«”Ö^À½…wÄêWs\-oýÊp¦ÖïÞ”mf…2Ô>¡Ïq×(Û4Ig›E ÿÐÎ:»Ìµ'sæ×k)Ý„"­EÍ€m$÷¹P§á½mÎd§“dFm_ï™ÍåR€oùÏ®IŠK„(Ü^nÕ¤ ÜÞü3»>Ô=íÓraÙxÃÆ \šŽÓ§=¡–¼ïÉvĤ“~`{¤x¢nðM†•]Õ`Ú|÷ M«ÍÁAÚÍÑX€ûÞ^ÌhôÒÒþ8»ÌÞ×ྮu­ëeRI¢¹t©HÓêh¤xî9ÏåË7xüñ#P=ÒL±·Ÿ°·Ÿ$0(’Hqóz`^ˆ÷tc”vÊûc7"^¹'é5!˜fŒdàÐÂ.“ô@'ïe"ð^*(¦à3wÜIïî;¹=e™^·ñÉJŸ†wªh•÷Jà=ERz¥k•wOZËŒ18»¢¼+wkbnÏs{|&o•Ïåvjeiàȳ@¯UÞ›iÃõ/ä{N` éõÈI¡©#÷Ö÷)øÈ™=Þ’]Žû°;ßk-3ïü+WyæÙ\þq`Cç¯Q½‚P~åÁý.'þ䩵ê»ö0éÃFò1ÌÆŠOðÉyù»…ò¾5RÜxÞ ѷ3ªm‡_£ò¥=J{²PĶO0Þ‘ä5&wÒªŠ´‡%&š7¸™á®¿s™ÇÿÙ+d°ÏF3r-)1s$if®¼þÚ}Ä;j†’¬;mX4/N¬l»ÐœÁ2.²É°yÄ0‹Iˆ¨ªŒªÊð%òXõ€Y"i3LA«›ª6m&¯úð5'à2´‘Ó„³ox– ýé)=v‹Ç¿EY5llšÜ÷öœ‡"WÄÑà• lŒdmNÄâ±½-÷ý·þùÓDaŸIo ïIOx¥PËXÔ÷2o£KÛŒÎÂÉÂjÒM¬´bIY´ª*Q¼´óî-¼û ;€÷Îã*¯5šÚèÖïÞ&Í”’E¶²Q°ò9ŒYYà—_{†ž‚ë_ȹöd¹BÿàY Uî“Àí&@íÚ„%i4-¼·änÇ+¶™Q YÛ¨ú£÷&;;š+WJ/' _ù¢9´xó8Á½â+î禠†²»ê+y¹<ŸÉ¦b£“”c˜ŽaŠÇ»ÐYf&}Ø‹µæÆŽ'èà±q€h·G¨¡COý ¦ ¸G¾‘ÁKy,¯–ÁYEÒc8›ágŸ‹ï]•Þ°àþ·ÿ 9ý)ïÚ ¼ÏÍ SÞ’aAU™ÒIòIkñAcB ïÀ, yÇü7è zýBš!}‚rË´#¥.3Ô!(N=qbi¦³HÀ}f†¤YE™eÌÃçLçyï,3iŠòÈ ¼ÿ˜û¿ð‰<#¥6ˆ-Ç£åZŒ DJ6FVÕèH¬Pдž÷Ä&{{{°»«xå+ïbkkίþêÓ¼ë] "þàr|ð6ŸÿüO>9½zØ—òC•ŠeÆ{€_ ^ÚßO8<Ì8<ÌØÛßûWÜ¿»ÌÞתûºÖµ®—Ye™æêÕ‚G9âÑGøÂŽÙß³··à3Ù›{Ui’HViúÜ›£Að[ŠímÅì¡>d|&YXÚfúgm¯_QÞcèƒQ»ÿ8â¯ÚBUƒk»ôT ¯|£Ñ…‘ò>Ú7søÚá*OX¨îÁUÍà[åµï®…w½TßÑ-Œ[˜Ç–kOæ?W»îaCCCõZ(sÄçž·9ç5­úÔ†H °kV2Ü[ˆÿ­{+~ë·*vw5EQ35Ý®–Ðî  ‚öZR.‚âåÛ¿ýIÞñŽ ¼ãçÿôà¾s¦Äy¢àÇJ¬3×[e½]v¬ÞÇ [„Î2³Ñ_(ïÀ»28šÐì8÷P£òJ{Üw¤x+M† p·6¦™G¨"t«FE4>ÂÍ nfð¹¦É#(àG~íç:<î+ð>‹$*r¡¼§eEU¦T&í·H{4>êšUCPLÑd½’C”j}Ü•’•McûT"ië™gƒN}dóÎ2ã¼é’f:ËLRÉ4`ßðƒÑ{ðí “Ã T  UHiB$£Zõ}æ‡]}G¢¼G¸±¢º72§v®Ý0ªÚ'$•øüsZ¿»páÆS¤ƒ99;%Æ" ¯€$ô@—T’uÖšÅf¤Îê"ÁæLGâw¯"ê*¥.µØfj±ñ0• úÈÀô-D÷_¡xÛˆàõÿö¾.Qj±lcËÖ¦dc9 ¢¼7.‚¹[YÍ‹,3C-‡j¥ $öÎhz=ÕÁûÅ‹;ôzpþ|Ÿ“ËíÛŽ”Æþ‡º-Mª*‚ݳP +-ÀSÈ›¿ø‰áìÙ¬À”pp¶+#ËôŸ)¸¿Pu_ÃûÜ×µ®u½Œê¡‡¦Üwßmž~º Н~õˆ4]*î{b™q¬Õ=‰¥Qt2q zN<ï£ÀæD¡`šA29ãÞiÛL”´FßzÞ[ß{²£³ðìÕ®­t´*‡x.¨,•¨ä!W/‚÷ñ>•¾‰t4ítÕ&D]ÒÌÞÍ}Ôíž  ³²vÊ;¡ƒ÷x+ækŸÌám÷@€qI I$GP¨§N&Í.Ôüöv²i§bc_øÝ')\~¸áÊÇÎŽ&¸u«a4²Ï—–™6RDuÇ+ú½”Å/ÿò\½*¯á·|˹?9¸žpWF‡öûl€‰‚Ûý^g›ñ-¸OÇðØÕ&ýî”ea›áx"_w4x?¡"þQƒ·åu“yñ»'óZTõÀ{pJT÷™Ææðý¿ó^QÏ[ËÌê2Ρ\åÝK’JCDj+†ÅŒ²ÌÈ“¶y²û˜Ò ¼{G@ñÖ죤i… 1S5êÀýEð® d bHÀ[¶¾÷2[hšùá‹”÷*•Dëc"ßP‘¢´LHUI{ )U ó…êî¬a :ÛŒ‹ÌRyÏEyŸ7t–“dK—‘µð^è^—4óÚÛpõköQèNu/É0¸¡+Ò. hÑXk•~U§ÔEÒ*ï †Ãí*nÕw-àÞÚf LÃĤÞúš{Úp`p§&í*u•à*IjTkñ²á+%ŠûÌÉš7Ò º¢¾¯NXZÉy?wΠ5ìí™à /žg¿a{;ã¸Éý÷Ÿðè£Ç\¿^ˆMæðUèºÅr©¼SB(IÇÙ³Ξíµ˜$×}{û¥«îœâþ¿_GE®Á}]ëZ×ˤ®\)9:²llÄ\¸ÐÇ{ØÙI±6t྿Ÿt3εð)йc2qü¶yÿG3þÝ/x¶&pá̓ú€DGË ¢+¶ :תî 4#·ªûo¾»UÝ«âv9µ?¥º/Ôð05„Bá«¥efœÂµš<6‰¨õi¿{ÓÚfè·`Ý6îR¶¡VÔ÷E$¢Õ`Ÿí¿‚LA%§Á=Ž! pãZÓÚf À+ƦSÞw¶äU˜Í|îÎyF#ËpØ@ÈO[fðÍÖVÌÖ–ç¾á¯’çŸánEš·¿ýË÷«ä³î![ž4´Qœ¥?Í™ô{l Dy§µÍ3é ÔOú­±âßOŸãîKßÌ£WoB<—oòñ̉ç[ ÚiÞxiFmæ2sîVÅ«:åÝÞI˜ ËÌö í<Êj•0w·Mû-ËŒªL; Gnû2$(±Ìó:x|ÐÄ©% È}ŸJ§§UwÂ)xGƒÍbiÍc÷ i3 p/"É.wÞtžwŸhª4E{Oì,ß1x¿À;¡x‹XfJŸQëD”÷HѳxØÙfB¬º¬úNy·mÚL9”>cPõÈ“ž4³êÖÅô£ž=¸ÈnHSjéq™érí z§â# zݭϵ(ïyB“b"±ÍT)U•1¯cæõ€Üö 3Õ¥)'Ò¬=½öqxõ‡¢"=½!ójpµÀ»Uqרjƒ(ðÌZp_QÞcëh}*ã}1]5­içÏš†Ö‡®Ú[ùs ÷ßÂÃóØcG<öØlþ§0Þ”d¾–º|±òNÁÙ³#ΞíZ)‡‡éKþ¹ý'ñ¹¯ÂüÞ×µ®u­ëePûûΉ;"„@šj¬õÔu`4ËÌx"±…Ή;‰Å6só†ã©£;ˆâš½ÝŒïýÏôÈ‚IEuß_ªî/ˆˆ<ï1¤çDuäá¤ྸõ±Ló\PµB’\œ"œH\ î[¢†ûÒãjiZµ!¡aa™9­¼cX*ÚÅ ¸/à]µª{äk¨œ +ƉB© ¶F[Äñ˜«×œL¦Ñ1h%״ߟÁŽo3éOØèC4VÌÆpu`k®_»É¤Ø*ïÀÑ„›Ù1$KÕ=ú±Ê ÍÌJNQ” ;XE4óˆf&ÑVÅX <QÞÝL^·¿ôã¿E£Ä½ªÐj$æñEðiˆHÊZ,3eÊ<¿ûÜð¥ä„oÈ6KΨ(Ä£Bøâªûâ÷‹k%…P+tíÁÁÔNMW{ñ»7>êÒfLêH“JRF}¼÷Å2¥°IÜ)ï•MÞ•ÂX×mLæÑ"PQ ??YZf\k›ai›)|¢’¬ý<Oü=W?»CrÛƒUĥŎâS 3 {ÒbpÖÚ zØ2&ª³Í¸Ny¨[Ï{^§äµØf(YÂ{´\›¿ö¸Lçœû¬wuõsº{f¹K™´D›’c)RL‚í8 %6lQðC1â6G Û2 $€áüÀ #ô‡Ä‚cDH`È [²aqùðB²L.wùØÕ’^.¹;³;;3ÝÓU·î뜓?ιꙥHî.Eq︨™žîêêªîéÏýÞïïû#,¸çTÊ9ïˆÎ}WŒÀnÀnœ“g­`vÓt®1…qm3(êZµƒª:Ð…rqíî.AÔÞhöí ¹ï´ŸF‚iäMÙ{€U@¦}æÝøÌ»`~µQ…»*E‚(¢uÝ­…7ßt‘™æÈòíndFF°ZÙÛ3ìíY%ŠårÂÍ›“Ç‚ûÅEÍ?ÿç÷ø•_¹GQ>ð9a¸G®øêW-¨-¨Ð-à’ͦѺï/¼p‡?5š3A¤ó>™”ŒÇ¯¾z—qtÌ|øùUþã?ôŸñô¿¹·6` ÔЃ»@Ôþ¤È<Òº9„Bo¶]dƸšL½V˜µdõS÷Z×ýzdF`‘Úûq‘“³ÑcjFyF‘Ç.6“ŒZw:Ì«nÑOä*Kµ-5;àÞ¸î×àÝâ€ZV®/¾É£IL'mÞ½ÖAë¼ÇqA&Ô&àÇfÿ¬…wkÆH*¢¥¢ÝÆÐ­M±¡ÀTUiÖÚ9ïí†ØÐbØöŠB î=ç=3#²Ò|ƈM2f,.øw?ú#œlnçñ¶@O]W¾Ä0"sÕ–¸Aßâ·¤ä6Ádn¸‰Í˜ÌmVuÎ{B‘'d¥«¦,ó¨k^êÁûôo½Âf<&p§ÙÝÒ.cŠ‘[ª2D—ÊeÞ…‹Ì¡KX·q™žó^j&ã`§m¦÷¸‚³3çºkm™Ï¥ïa—¡ùÜç.ùsÿõ$Ç0SJ—uÓ¥k’1¾ËÝ4QDŽ`ËÉÉ’““ÈGfÜqzš2¾=|þVrî} ð>€û Aƒ¾‹tv–Îuoœ÷ª2쭺Ȍ1îv” ~ìO¾ ")XÎ5G‡0Š` F‘`’ˆÖuï·Í4‘¨¥sÞ«‘sÝã×ÀVÆeÜû®»µ€Kã¬ð&ª \¿8Y½òM.V0õC kêJ¡Ð6h›fêÜ9½Hw—AìºË­õíˆþÃZXß»ï¥sàg7$Sï¼KÑ{œ¸1™îÜú²» 1o2ï½+蓉ÀZIU5àîÜ÷ɤæõ×7=×ÝûìíX­,«•i+ènÝÚg6{ü0ÜoüÆCÖëš³³káøxL­xõU¸sçMPÒÃ{&uOBºMº[È£R2E¤îOjÆÞyíµ+^{í >2ºÅÿ—þ8¿ú‰;mÖ]þ±rà.¢4ÎÍ]”á6…Öç¾ËÊPKïµËÝëµ¢úÜ %Œ–ÂÇ+D›1FvÎ{Þm%Zpß–iëºWEˆ2n«®ÖŠ`V·q™¦nò±ànÝŸ­=$† ª‘•¡Ò¡ë`L'.ï^¸¼{eºObLÍ~ŠRFk1V¶Ýñ¡®¨U@QLnl ¨ò ªÛÏ‘#Dàà]g–Œ´Ví;ï…vW¶EJæ3ï{—÷ùÍ¿ø½$s¢¼$Ú–dOº(RDÉ”«ö~šæ™à×Ýl%f+[çÝfªuÞ]Udìžïrìš‹íÀê$€¯ýЫd{Ó¶†R¡Û[Uhl!¹¡,#ç¼[×FT2M µ¶ƒöà×.6³î²Ë¼Ïb)´†º¶¤©àðÐ¹î¿ø‹—ü‰?1ƒH:h¥ûÙÐ…?š6ßç.¼ûnsNnÄ>ßîª!óžrtôöã2oÜxÀ}РAß…:>ÞýåbŒm]û[£áßû4ˆ¤ ‰3ÃÞÂ8paB>‘L&]‹Ê¢_éá] 缇g.á¥ÏAh+(ËÝØLé]÷Êo-B¸ÈŒÒÞŽÒØ+×£>Û§²L"‹¹0T•¤’²ÍË6o* KWÕ¼¿£¸sÜ€·Àúêºón¡´.þâ3ï’.6S{³~ÃYíáfÕ6µô÷¾¦SÁl¦ÙÛs‹±ÎÎb®®FÌfŠ««‚ËËœËË-e©IÓÕÊ´Îûþ¾Ëëîí=ܯ®4''nžÁZE®¸sGpûö›ÕﺛÔýªo.CÄ!Ä Z^xá?úGoR¢÷ñ¸âêê‚W_½Ë÷üðÇùè_ü1îݹ€`ø¯~¶‹p¬ÁÖn;në¾+)%õƹ練Îyǽ®6d?9bV=$©r"]R¶ ݼ´†ùÉ»|ìcwyúé»|ö³Ü}³nÁ#XÎsÃbn0cA:÷½®! óÔçÞ{‘ ká"3‹CøØ'`6‚»øZÈ è†U«ÄpÞ•qð.¬ƒ÷5 ¦§¾z1vq–«­¦ÔŠŠ ×ïî¢3̸ì9xïÆBŠe»öð^Z—]Ÿ:½qÞ1]lÆHÇ'³ÞØê¶ë}~3O­øô«³~ò'?ÏÏýÜ÷¶ÏûÉÉcle CIQhò\sy¹m>Ë*dë¼ïíߺ~n:UœÅþ~ao/â7Ÿþô]ïº×~SdŠ+×/wŸB"ù?ÿÉ)?ý7Ýlkî“IÉdâ¢3çý(ûÄmïÿãtŽ»°XãN~ÚØLðQEЬ mÝ ªm]çè*cTg$UޱÒ9ÕÂvqášbÊ(r[D=¼oô˜¢ ¶ºV­ºÈŒØºÊQ£%Å$¦´Qëºä[‚û¼I·±™\»˜Ì:˜P)÷´q'¥‰ØXß4ÅüÀèÓ$=vn»©ÚÛ@×”ýàn¹ªDUi›1»Îûâ¡Eg‚m’<›©×],©É¼ó“ÀÆ=¿QQò‘ßû jJ¢6Œ$*ë*…»¯Æy¯q³&u8çÝÇfªððîÁ=)=¼›­ìœ ðÿPeT“ÔeÚƒ Ç-`Ó…rMR…pà^†®ï]„,Säqm©‰d£wœ÷ñµØÌÈçÝóîþ¥—,ûoK^üÍÚåèŒð‡½uË—tÙ½øL’hÎϧœŸ9;yˆwÎ{}ûk!x\÷Aƒ½õÙÏ^ð Wl·5«UÄOŒŒ»oîš,æšåܰœ¥E‚i*ÐÚÍr*Ú¶™¦"²Éu×ÂÅf a:‚€j76#tî•ñm+ÞuŒË´;¶sÝ=¼OBËeî¶«êkyw̬uÜ÷—°Zøîyû(ÀOcØ^™Ìûì@1K¸OÃÞ£¨û¸YÂN×{!ºæ¼ÿßÿøþÊ_¹Éþà¤}îOOÇXë®|¥…¦(4ëuÅåå–««‚¢ÐXk¹ysâW¯KÂðëÃÍfgg ÆÀ›o|ö³w¹sço¼qß¹îС»Ä"}dI × lÝ|@ð»¿ßðʋՎó>—üùŸþc|ì·yóõ ê¿ù#> ,Úx‰(üsX;ÇÝJ;IëvcªÞ(¬]d&€ú×Ì×£*ɶ ¨6®"1a tMU‡lƒ©M›eÎhc3²2n9S•’c´äòhNDÙ©Jc¨D¸™i ^ZÓ5Í÷o¦–¨ÒÁ{fG\™)ë`ж"RE`j®ÌÔUD’2?tW¤ÙqÝûð^‰°xYùxŽ6dÞÍÆ°-¶2ÙqÞ7Œ)m„] ê, +Sîþø)j£±J …á'~ÿÿÓ¢¶SVbkÁVúáVÜì€F! ƒÝJç¼oe;°Zgã÷Æu/rw2ÑFfCü_”©¿tU€±Òý@ƒÌ bkÝ@l!¨‹€²Š¨ªÎuŸHµéœ÷õ×wÞ'øO¡Ø™ Y¯áüƒ’}lR¹Ë„Vzp÷1™w®{Ü%ggcîÎ΀³X¼»µß(¸ð>€û Aƒ¾ËeŒe<xßûÆ­S !$Bd¼q·d:YÎ ‹¹f17ŒÓ€QÅT¢µs´œû¾èUDš¼gðóÿ¦cÈ6Õ£±™¦"²xÛDf dï³$pàuP­·šJH´|dFaó=ÔÒAûÁÒü´7H{Þg¼±öM3•€Ê¶'$ÓÐ7Ûh›©zîý,†TX¶YÍl0¹EF‹1]Ï{ìþþÃøÁüv^ƒ³³ q¬( ÓÂ{Q8÷=Ï5y^SšÙ,âÖ­«Uú ½¶óyÀþ~ÈóÏ¿ÉíÛ÷¸}ûMPY縋”wÝëôÈGi*°t*d: xê© Nyø0ãê*ãÞë¼ùúÏþøø_ˆì¼;²ØºËº#-ØÊm—ßDÔ7¤Z‹À !+ATKFÛÌÅ(¬¤¶&iwj"míÚY6£ñ¼³ f´M3TUÎ nUﮘ›Ë6.#­‹âm¾½ïÀKL ïA]CMë¼_‰i›QÆæ¢uÞ•vŽyG|pöE£Aˆ´¦÷È”¦v'#M-¢ÝðnAå&«×zÂZOÈ‚q‘a6–m‘8Øî9ï[›b ÐÅþÌ·àn•à/ÿèÿ¾s‚RaT•kŸÙ ï£vÓh½¦Î#ç¼g› ÊmDÞŠ\¶™÷m‘ºL™‡wõ#š: Ü€n%üN0Aë¾UÈ̸Xïué:Þ÷Æk}Ýyï ¬^˼Goq~û³?[óñoȶ¥›ûMdF¹NwÕ¼ZBE IDATÄdòÝì».9¿5áæÍ”³³çç£÷ýíê[©…à}РAƒÞƒ’RðÄûÛ‡÷†¸2âÄÅe€ß[t‘­E ïË©s››ŠÈÆy¯ü«OÁlìÞ~Ï–„”»±í:黎ÌxxW ¼×,Vq™ñλÉëw/œón‹JLãÞ;â¸ì×~ÃH@¶v®ñ|ѹè³ÈEgLå+"å.¼ÏbØfšùaó1~i Ê»óüÀ”çž»ä¯ýµOówÿîì¼ò²t1ô5ggÓoøµ­*à /\ðïÿý}^}õwîÜ€ŽÀÔ µ[ï^G S“Rˆª)üg¹ððrѾž?þßü>ö‰;ü£'·‹b\“½Â_¹pTÚ¼{X¬!“èt™wëœ_è?~Åt R›Öu/…ë;G²Sikế…ëþ.mD ìFc²ÀÅf¶1uìTDÞ»¹¢°q—~àAлe·"²‰ÐÄu±ïk5i]qiLëºk£PFs¥ó¾/(ªØmTµ–Ê„„¶j6)­Ûì%BT­Ñ•BU«Eïáˆù•ÅdvÇyϤ°F ×)ìF´àþþËŸeÍdÞ5î5°•k¶ÙŠ”må¾$ÂÔ‚x“Qæ‘»¢µU­ón²í÷MµU‘}×]ý;)“ָǑ»=Öï3¨U€Ü×é¿…:÷ï¡ò®»r@^ô3ï¾&²éy¿î¼?N¿ôKšO~r;p2ðÐî¯:ÉÜÅe¬xÝÎ'ܼ9æü<åì,i÷³³ñ;îßJ-äïƒë>hР÷¨‚À¼1ëÞXA ©kî3Ãrf8:LG.2ã Áþ¾[šÔ´Ì4p[árî ü…í²õ’ªl*"ƒG÷>¸+î“İï‡U§½Ì»Îµ[Û“Ø|ÎéñÔ–Gà]¨Ç7Í4Îû,†ìʹÆócÕâ6U‘Ÿwzç+!_Ïjíó¾9€'ðá/(KÃlòÿñWøÓúÖoùÚD‘"ŠÔ·ôº~îs|îs¼újFUYNNF$÷ï´® nS¨SP ÞêuoW¹wãCÆ#ø×ÿúäœðÄûøØ'îð·Þx¦ÎmD7ì[YÐ>6#,$5È ÖÖšz8p× ?l‘áŒ`}m=ÔI¥ÂÖyo—3½ïY8¢²!*ß`³³‰ÛØŒ¨-Y="ÊK´Q\œLÑ&rn»q'Ú­Ö}´ßÝÚGòïºVÞkïL\U¤˜8àö®»1¡-k3áƒÇ_¤¨Ü6ÕZHkZ×½2!JkS·­*µˆ‹‚²ŠP•v¶zÌÚLÈ¢fc0ãj ›ØLäb3UbŒ$ÜTÔYÐÂûŸüsÿ_»p©/EÔ. dkç¼oë”M8¦ &ÙlÑkAYGè­êª"³›Iæi¸›)’„ÇÁýÒ]p1Rº« …«ÚlÎð-½u'"³˜Bb 隢ʀ½™[ìÔùuçÝw½‡¥i!ÿ­Àý7Óð©O­ùÂ.)ŠÊEf´èjLñqS‚-]%¤q?ŸÉ¶ÃýæÍq뾟{k!xÀ}РAïQ…¡ä}ïÓLåù}5Ìç!UeØßYí sÃá”3éY×â0 $ª7Ø×è™ç;x/¶µwë¾* ÷‹¼îMÏ{“won3ÍÞ ËÞÒ2‹»ÅI“Ðb¶t€)&üÁ|?Ì÷÷|df Ëñã³î͉ÆÔGqî¬-Òt :óÔ5ÊÌ"—¹îÞÏýID@ÕºíóÔºªÈ1PÂ÷<5¦6£­rƒŸZóÆ÷º+3¡" F-À2Þuݯ «6êÚeó5(­•m÷+=%0uç¼k…0–µž°²÷(«¸™ ¡ìŽëèšÀøØŒÏ™SÀV§¨J»:Jã>OU)LfÑMlFøÕÈÅfl.0Z:ç}«8ª_çûÿüg(‰X3i7¨öÝ÷ ª1•sß·8ç}¦lƒ”p]`Ö¾²±XݺU‘ æ'ÑNM¤R!«·Ï!<€·Ý¼€•nµ½,×ló­iὉÍèBarI îª;ªÚU–r³»eµ…w Á[ÄežyfÍg>óÏþHÜçG¸ïéºÛÛwë—1éœPÕœžNÚ*È7’6ë~pðîÖB¾Õ¿=ï¸4hwy%O<1\|F8;3”¥A)ÁéiÂáâø¨sÜ›ØLÓÀr]/½êÁÝÿÎ~pÏ{àÞUD»àÞTE^ƒ÷Tö–þX¨¶© ”s>ú¡,$QäßjÙ¹î£h÷Š€¹ðM g¬ Š}\&µm“ÎÔ'{jq-+Ÿ¸½óî‡UçÞy·²sÝ›ãô4}×À½9{ê©i…RÊ­„ð@ò©O=àÎëÈ¥U¶¤)Ü8QÔ%ܽë]y]ªˆ½=Ãþ¾ ËJÞÿ?/¸Ç¼ú!³$dW *Ÿ}—Â5܈ÚÅf|CˆÞÄÞ?¼Ñ“ ìÆ P6‘È.6ã#3V{çf;«ÆfÚÇf Ü†.÷.cL.)ÈzZbò uPŽ"›ù-¶ªö&2Ó8¬CîdPì ¬bà‡V¿FQ¹M¢ÐÚ¹ü‘-wà]Ý:ï²2¨\“1BUšBÇmlFl ´wÞ‹rL&»ªÈÆu·F 6)ÎÿòWÛEK5AûÕ´à^ÖDÛ’ª[ç=«Fl«KôZPo\‹SµvzÞe&™\l¦‰ÌìïwàþoÿÈWj¥pWiLï(Ý ž)$z«P[íê< …)Ó”7}"!Ó†¸6”ëÝ®÷&6“¾…ëþ«¿ºáSŸZóÅ/^ µî= ¶vùöÞñYwáœ÷“Ó§§©?’öö·3ç~诿ïïƒ ôRKŸ‡é4ðËœÜ&V·A0ñ þ­þîƒ;BŸwoœwÊ* •Û–¹\*‹„²4l·–íÖ°ÝŒÐ,O:xß_©¶™Óƒ?þÑ?Š”)÷ïC’:x_ö"3Á×Vµ½ØÌ,vuçó>ëåÞK Fí‚ÿ,†Å–KËoþæëü?8k—4-Æ0?H9;Ivà}6{÷½F‘x÷ZŽxþùŒgŸ}“_¼‘º\;Øšå<âðêRQ—–ÃÞ~àáŽþÜfº¶=pïüì¢^h±mæˆ}dFV°‰¼ó>†X½ ùMŒ0+[€¯dØ9ïŠÈL›ñð.l†ÝÔØ¬Fo@opKš¢¹5\ü®)aµq¹íÀ™¹ØŽíà}BA€¦BQ çõ ÜPk™±µpð^Z®b7°JæˆÉ–‚LÐÚ5é”Uä6‰ Vnë*—y7Õ¼7Î{T–¨B³‘c‚ºfkÓÞÇÛ³ñ™wãc3ÕnÞÝI¸®ˆ~ªÜÙÚ€{_“lí–rÙÄeÞç½NQ›½–TY@E@™G;U‘ÁF25±™˜"Oœë~ró(¸kÿ}Syƒ»‰äøØÌ4q'åSEç¾K¸¬-±¶\mv»ÞçýqzñÅ’_ûµ5/½ô€—^z€û¦óàîO^ÛU<Ä{÷}6~ “‹Ì4Îûéc7³àþ­æÜç}pÝ 4è1ï4X›¸Ç7›ïl†T±P•z'ïPÂF£¬e¹ X.S–Ë”4•T•ððÞxpw±™Õ¾ƒë&‹þWÿêÊx¼àÞ}÷ù¦µk†™6ð¾èû[¸ïMƒÍÞ¢ÈW_ö¢3ÓеA^vÅÜ—KËg>ó·_]ñ‘ÌÚEMàæ ‚@1©oëk™$г³1/¾è ýÅ/xxUùÍ­ˆ€šÅbÊb®ÁHêRR—–«Ëœ½½”½=ÃÿñLè÷Ò÷(v¯G¨Ü²ÞØ.6£=¸·Î»=œ?€ñ6­:×]Eóîá=Ðõ#ð^ï¼gÎy7M]$‰ëùÞ¤ÎVÔ2@î¾ë4 š‰(‹‚±‰@"HJ%ŠÚC»[<%t •kÙÖ©Ü =”VPÔ1Žžm]w«u •z,¼KcZç}œoP¹¦P1e‘‰k=¡.D뺛a+}lÆoXÕ…Âh‰Õ‚‹ŸZ0媅÷ëך« qV`¶’Lvb3FG°®ÑkA•ùEMyä}lÆf‚Ù¸‹ÍÔuÌþ‘sÞÿÕ¿ÆUƒJÛò1ºîµ÷ÚÁ{ã¾›\¢Œ`:q?o“`×yµí5ùaÕù(àgþþËüwÿíÙ#ßÿWW†gŸ½ì{ÚmgÿÓ‡÷ÂçÝsNNæ»MªMæýô4yGN¾ßéœûï¸4è=®$Q$ÉÛÍ$êòó—¸ÞuG†Ã½€å2Ù9„Ô5;ð^‚ÉDº-£KÃþ öWœ?ôÁCö÷¸[T·-väóî³øZÞÇ÷¼Ïb8=u×ÞgiçºÏ½ØlUÝqì“Þ—K·™ôêrÅb<ùŽx-Ÿ}ö!ŸýìC~ã7®øüç·Îm÷ÐŽ¨G®Ç¡%’ºPÔ¥ä^(X­ ÿôù#ˆ|}f!\dæ1?úì¿pÐuy…0”Ö}.éÝ÷Æ5Í+XÝc9{’«„k?1’а÷ÖyïEfL-ÛUj°b×uoºÞ•˜iŽ¢ê\wånm¨ˆC ÍËX¸Ã´ø.Û?eF‘Õ£ÖyjïfÒ{€+/á¦}…BÇíŽÒаÝîj… 4UÛﮌnwjŠUhråÜð³Öì¶n]w³±lc_Y(Êk&””Q¤U‰–ŠJ†” ªöá]`]\& 1[É6I]lÆÃûT Ö× Ô:ïEç¼YŒÈ$³QDYDÎu÷q™€{·sãA+×$³ãº´D”Ž™x_N½ëî~ÛLì÷æ{h*NO#nÜPüÔO}Ž¿ÿ÷¿ï‘ïýçž»äsŸ»äå—/q¦v×uoÏH°#ëÞ\i<9‰8>ŽÛ¿¿q·w²r€÷Aƒ ôŽ+õ3]!±¬YÎ$§7jïèO&¸O§a» 1Ïã¾ÝZªÊ¢Þyß…÷þásî{pÇBš¶³–Äs·Y5ê ™ÚÇ4Í4m3Ó‚S·‘qoæc3=罩ˆìßÏra÷^XñÙϾÁÏüÌËhРAïÀ†l7ãÖ‰ŸÍBÊÒ ¥já=ŠT ïEáÀ=Ï›VËÑ‘Ú÷XÁžŸ»lî·¦…`äb3>Úüh\†Ýž÷ƒ¥@Ïum98;¹÷IèjÒ¯CÜ]tæý¯’ƒƒûû nÝZ°ZÍ©kËOþäçù¹ŸûÞoËsþÕ¯|ò“kžyfMQX>ð _úÒ†º6`3OO!ËÅÌ-àZh¦“ˆº”HbêÚòKŸ¾é!Çûá~Â÷×nS¸[­M»¥YB»çŠ+‹Õ’^d¦7°Ê÷ù=¿ï{yîÓ•#~e1Ò«ªhÇy·JìDfšØLí_×®iÆ»î:ƒªHˆÂבÁšrsŠ¦Ë»Ï ÖmwDH´‡vÙÃwc±lêV;çÝV‚²ðë„{ð‹‚— ¨]E¤Ì4ð^Y_é›fšØL’çy(,¹J(«ˆµœPç%jLæ#3¾&r+²hD]Ø÷UH›ä!Jj”Ð`|—{%©â"ŽÝ\mI³-Õ6Dl­«‘41™!LÈXVèµÄøØLE@Y÷2ïYD˜If㨃÷}¸s _ø gÚÕ½¹›woá¼ûr—Ù¢[¼6 vÁ}¢ ®M뼟FG¾ý%àÆ7nß.ˆ"Á /8hÿÊWîóê«Þu7À‡Kà¾ö¢÷ ¶ NOç½!ÕggÎu»W#ßZÈÞp4hРwMGG‰ïz·Xk¹q#móôó¹ƒwc„‡wKU9x/KI]»JÊÃCÅÁbµ‚ù¼ùÚÝZ :p×ÚíaYŒv+!ߪ*²‰Ì4ð?Ÿ öæ¢]Ô®GÁNæ­[#..F\^N¸ºÚR×R*ö÷푦I{õàg~æUþÒ_:}WŸë<7üú¯?äâ¢æì,ö'5–Ùl/|aËz­ŒétìÁ½f9×:×}:IùåOñæ+˜tà~|(yón©êÞë€Y3õðN“Àº…WWø…PýU eSÉÝ—*ØØÞµR®¥îMÛL㸷ðnBìXc7u뺛 XµEEÎuÃ6ë>[¹×3ðn{ç¾[‚º—z@[Ab[Õ£ÞqÝC(£Îu¨©ƒ ÌÔ:ÀJÑB{ }æÝºÅT¢°E ä*!¯Öá»­°T˜E÷4meJÆÈy4Tž¡„ÆáX‘èJ¡+ñEä5Uº.ø\P‘É[›²P0V¶Îy§É¼›ÈmÝ*ÊmD”Iæ#™™Ïáü­¿–Á,tQ)Ý÷†(gäœ.nî¹9V~†%rwñÖλå`rrù#ôyô€7bŽcžyæ ¾üåÞøÿ><‰Ë9U=÷=ïÎÈ{ŽûhçÏûûïn-ä;îïyxÀ}РAƒÞY5yÑÉ$ðàîbƒ d2 Z×]kKUI¶[<¸;xŸN%‡‡ŠýÕõÿ¯§‰Ëº7ðn-ŒâGAýqU‘Ó¢²ýØ4¥ußùÖ_Óéécl{ܼ9%Ï5iš°¿¿àà`1¢mî9>Žyþù úÐø]{ž_}µ`µ É2ãž—Ôݸ¡H’-_übÎÝ»÷YÌ ÍÒ;ï7n(Lð¯ÞØç•—¶®ûÑ~ÂÑ"Q5².0¥Üqß§QÜÆf,¸È6µkµiÀ]¸!CöïñŸÿøïã—ÿ©_ÇéáÝ¢­ˆ´@D‚À/Á¬¶bà+ã»I5PØ\{×Ý¢3P˨èåæ{Љsܧ{Ý ìºîcáÎÊ*íûn€Ú8ç=¶‚‹:¡Ôn›j ï=€·ZPón…hÁ]× #å#ð.¬EÕU¸Ã‚\%dÚ «Ù}¬¨ÛÕm‘ 羋´@—×VÛ)L îÖŠÖyוë™7µ¤.ª,t™÷BºFš8ekSNeÁX‚̼›LàË]1[‰ÎeQoDë¼ïÀOü©û ǰðq-+º¤Ê¶gr7üßg‡]ôj= î“^æýüTJ.³-RÞñvð>IG,&Ý’+m¸Ox 5Uæ#3Ê7šßóÑ=î~©B_wf¤,àåH(Wí¤$îëØd’b¶¯kÕñWcMݺî&ƒððu6¡–34Šñ²kù«(ãÖ}·$>.{¡™¦½ôÎ{â~mÂ.³ÝwÞ#ªuPÊ%´k¸ñ‘™æh =0.÷.­!. T®Q¹ƒ÷BÅl옺(o‡U{±™¦EOˆ²íN¬ÛXwÖÙ@»©¥ùZuð^¹႘`¤KÁX ïY@e]tFçõ6`9ü‡ÌF÷¹?æ'~ì5î‰uq-Áˆ®a¦YÌÔ8îMÝhîžÃngÃ,|üÀj㼟„Tû{{A ï È¿þzίÿúŸøÄš§Ÿ^ó¥/-¼ã>ñß(ÛžõßôÖ-ÀŸž.|¤öós·Eõ·³r€÷Áu4hРï…¡$ yËúDÑ]d¦øÉDþ–÷­¤;·8 ÿ+û:¼«Ó]x7Æ9ïߨnÝšqëÖ c,E¡Éóšºv ’ªÊ{]»èÌj¾«Ïm’Èà£H´Ÿ»®-Óé’4Ýr~‘ç5ççNŽcö%‡ðò‹^yiCU–¥-¸*~©@Ö¹¯ùs®û|?a9í\S]»Ìû$€÷½/âÅ}dFUþEÍù‘}‚ñ ™‹Ìxh'°¬Î2rÀ®’Þë dJ 6Wàtí%YŒ t›w6ó‘™›ÔaÌh.ºm¹©›¿•Þqy€<¨«^U¤êÁ{ã¼'VP ÇŸ;M3ç@¬Ec”ì€Ýºó”H@MHaBrmÛÆ uÞÅ›•X*¬¨\MdfÚØL¡¤É&Gd¶sÜý¡qÕ”¦î¢3¶ÖØÚ¢f!ºV”ÖUJîMc)Uxç}à÷"#ê€Iê¶ËXðþè‚‹—_qà.%¤LÀÍH^yƒ®²öN{y Þ=KÏVnSñô1Îû4pàîÚf ïJUY¢H´à~|ðÜs—<÷Ü%O?½áK_:ñÐÞ¼8™?šˆLïìš[·fí€j³„éìlÄlööV¿Ù-ªCUäîƒ ô;RJ9X‹cñŽß·ðΫìÝu¼×4ª8˜×šÇ:ü¿•¤¤i@šþöþ MSÉéiÄ|®Z׿®-''ŠÅB“ç+ò¼¦ª O<áN<þß_(xå¥ _ýrÖBû‘÷ÙØ ë¡ ¨lïÃrÖ ¬V¥.·‰7 (B¾òµÊ9ïuÍŸù;Or÷Kw¿TÁV´ð¾w&˜@†؃T *‚Z‚Š»c“ç;®1‰É@M`ʺž‘®º¹…™o’”ØX•HÀöU%µ‡÷¼ç¼§B %”‚Gc3½B«v)Âî@º-½µm„ù–•wÝ]l¦\Kê­wÝ%ÌÝÓå‚ ììú”Ëׂ’$©äæ(^|Q8n®q±™X÷À½ò윹sºf9Zó=4k"3}ç]Á<–ŒžJÚïçããÐÃ{ÈÇ?þ€_ù•-¿ø‹_þò·Œ)ñŸ<ïÁ{Fç¼;x?=óÄcnÝšp~>n!þø8}ûÿ×|ÿDÞ Òß.Ì¿çà}÷Aƒ $„‹ÍüÎÿöèb(cRžzjDž×l·5y^3…|íUÉ‹Ÿ{Èk_+99 P‘ð¯8:”äuÔ². 4 Ò(f>¶®›ÛƒWá]÷7„¿bQŠ;÷*¨4ü¾c~ù2²×µ«ˆ ,Ë‚£I’öàÝ»îB¹ŠyuGÂý{=x×Vht&1ˆöPoŽì1N:hŸ'î1ZÏ”ýªÈ®½ëw[x—ÄF[çL[ [ yc↴‘´;9˜,@…îû¨?ËYûC È… (âÖy×…r=ïÂ`}¬Ã™pðN™¦€®$\ÖA ðu«l…µVÔ­a#Ñ™a«ü°ª)Ðé ®ÜFÓë‘ÝqÞmmhÈU»èŒ ©lÈ^“^Þ]³–Ô•‡÷4g9ŸXNÝóØÁ;ìýnÅÍPüʯz8¿gè­†­êŒîÞRÓTÂbÜsÞã·îyO´åýïOv"`i*yøPóôÓk~áÜ ¶Û"Vã6f V+×ÙÁ“ IDATFóì³­ÝOó眓“…¯›qóæ”[·¦Ü¼9!ŽgÔB¾çá}pÝ 4hÐ{QO?ùa`…µ°X88ÚóÑ™ý=ÁW_nœ÷ÜÁ{0O™O,‹‰e1Ì"ضçºCGÞ#Ž<ûo2Þx©„`vGû’£}År"0ÖÕ{*î*ö#…=ç]ÆúìJ Ù…‡÷Ô ¬Šø÷3 ao£"ß.Ó¡‡÷°7°â\jWE.}ÞݹñuoP5¶‚P¹úò­pŸ5¹w£±÷ÉÂÀ;ï½CH¿£È;îµìདྷp™Ç¨\#Kƒ€­ÀÔXjlmÐç¼gI‚J×2caí—4ƒ¡¿)Öb…h‡T­©AhlfÐEµu®{EÄ,r¹ò±ȬX•Tu€‘TÎÞ¢ öæî}]lÆÍ Üüź–<<÷Юqñª²ï]=dó˜ý‘kÑ™U ±Ä{»XZU–Ÿÿù ž~z׿üÀñÚA"¥dµ²œŸ‡|íkpïÞntfßÕKžœ$¾Ï}ÄÙÙ˜½½ß9µïixÀ}РAƒ½uûvÍáaà;ø!DÛö3YJŽÆgÝ¥ÎPUD2b>±ÌÇÆåÞ§ŠYäæ7d;dWt®»j*KÍnÞݨÎy¯$TZQæÆ-·²V{ç½ÐØd[¸aUL—+?9ëxµïÂUV _)Àzª^ìÆÃ»ˆXz`KÁD ® ›ÑkIMà6ò9z»e1±œÁ2ÁGfÿÛe´Ëͨ½ë^ÈêÞ½ë¾8u‘™y?6“ô2ïAç¼?N_øB΋/^ðÊ+÷yå•ûþ“và«•eß²Z¹¼ü×¾¦xí5ïççSÎÏ]ÆÝÕCÆœ¾¥!õëàþí¬…|ÏÂûàº4hР÷ª¤ìºJN­€*^¿S uެsD]@•3ŸL¼ëîÜ÷åÔe¡—© ®E¯Þ3à}ºÁ'µâ«_()3ËÑ;)8òÇÁR´µ"èÚfš¥ZýØL…`zð^¦0õn{sLRËaoX5õ‘ëá}, ö˜K ï¢uâxoœw©Ü}Ö=x¯RHzà>C¸„þÀª.¿ßÄf÷Ýø× ÷ZB¹­\+Œ­±uíœ÷­îm™RžHà"òm;ÎaoÎLšÈLïME¤@»ØÌÚb×–* ±Qà\î^lf“ T.¨²#kP„:ÏY¹^ÿý‰ƒ÷4ðkž›mï¶6ÞµËe5l(`±pŽû¼qÞ“n`õúvÕÇéêªâå—ï·àþúë—¸³åÍÁààÀÅfV+Ëh”ðµ¯%¼öÚ–½=ÅÙÙØw¹O¸ysÊùù”ÉäíaïogÎý=ï¸4hР÷º”‚£#E’ˆNýºIٶ̸،Zm÷Eã¼Oa1%»ºÍâ_~YóïžÉ1ŽÝ2®ƒýÞg)À»Šºí·•p®»ŠA‡×œ÷1ˆcííÂ{ÔÀ{oX5 ƒ÷Ä«†=P××úÝ-néP» I¹ÇTõà]ŒuÞƒÞ{‘!›ÏÑË»+Ï» ¼û·?ØV>ï^ak×Cn3ƒÉ,ÛÂmUµ—3È}uŽw‹­í¶ªî8ï•Sb…ƒwÖMl&a6îêÛ¶™ÜÕEÖYQaAŽÙnÙ›»“´½™Ë»ÿÅ6f÷Îņ2óŸ‰.:“ æ7œëÞ?æ½ØL³3 |‹¸ÌóÏ_òÜs|þó<|X0›)>l«‡ˆ"ÃÁ[è¶ZÁþ¾%ŠxO˜L"ÎÏGþpîûÉÉÛË|'€ûw=¼à>hРAƒù_ø`µÚÍ(ÔµåÕ×®Ú¬{ñ‹‰ö¹¿]LŒ÷îc…pK²òÜðñçÌç’ÃCK’¸Lýü@rì#3Ѭéà]%î¶Y¤Uã`>9p7dÏyOŽ!šº¨Ìž‡xTç¼7êtè¤~XUúV·kÓEft ùÎ.`¢ºmá]@4øšóŽwøû«Ö¿M÷ª"›m¿Âƒ{%ÝÉÉ<\Þóð^Õ®mf£Ñ˶L°ïWpCá1MÂeÞû‘ÅHé+"½óŽÆ® vm0ÉôFçt·«>6Se°† € @ç¼/çð£ÿS "}Þ'{¦p÷ ›Ù6±Íb´q™ùØ»ïãÝÕiã· Ð^xȃ%£QÀ“ONAš&ܾ]ñÚkÖ:×}ß9ï À:x¢›ä¹æô´qÜÇܼ9yÛ??ßj-äïƒ 4hРwèoÝœ±¾*¸¼ØòàÞ†{w×<|X°¿T,§x€7Œ’ÇßÇsÏUª6Sïšl ˶"Òô¶Ý ÕUD6±™f`5±¼+ïºW30ü{+7¬:›vï× ¬ŽUçºëòî£^¿;@í#3†þû:×Ýö>¾ôM3E&t9üÜG‘‡|Û9ïª÷±ÚîæÝmïþ)lGpù5©*,l\l&¯R7¤šGî¬FØàínd¦w[ËîÀjl ÓHu±%ËÆyØ¢òàžCX`¶[–~ÐôÃáM`¯÷ÀÏoxxϚ،msïó£àQ×ÝÃ{ß}+=ùä¤xYk ‚€é´f:­˜N+nß.ZpoÜ÷ƒÉ“OÆJ!Ô–*Ó°5°ULb·wÞ÷~îÝûú:C£a(½ãîž¿4M˜N+Ò4' sæóùüá?|³·œLÇŠ½½ämÿ||+q™wæ¿+á}÷Aƒ 4è›Ó‡>tHš†dYåš8V<ñÄâ-?f:•Þq·X £‘ððnÑŽ$i/ cýêSvy÷f`5h ß¿o°uðž ïÆvð®â¼{ç]õ†U-Þdïm– AÐÖFú¹K+I…sÞ›ÇÔÀ{0mvwt»­ˆìûo›Ñ¶÷xzÎ{š@1°u«TÖT°Î1¿ŒœåŸG»®;+ä£Î»’X£½ó^#´ic3ó]Þ}æ7ã6±U  KöZ“yw±™$¨aƒuÝÌfîùùzÎ7ß0®ã}[³Ø³ìÍ=¸`1é ¾÷ä Ï(r£QNlÛ«*÷œ4ŽûÑQÀÑ‘"Žq2‡ïèÏÅ·Z 98ïƒ 4hРw]O=µü¦?f6“mÌa¹”m‡¼Ö–ÕDªžón¼ ÕÁ¼ñÎ{SÙ¼oC½=uð®5,ö`¹Üuò›ÕÈ=4DÛ„ŽC_B¶ýî¶…wáÿÞÇæÒE¸Ó±ÿ=ç½ÒÑÀ»í84‹™LïÁø ¼õ'(E #eÈ®|lÆÔØLaž¤sÝ+v\÷ha"È×S[Ïô«@X™hlíÀ=±†ÅØvË|§úH¸ØÌbaY, ÷îM(Š7üÀj·?ò2Ø=Þç¾9fì—c½™iÈAUšÅÔÃûÈ»ï“.63Áô›ØE’›7knŒ;9Ue©*ËÉIÜüb¡Þ•Ÿ‡ï„ZÈ÷¼®û Aƒ ôíÕ|.‰¢nùSïéTì€v3¼Ù€rsÛ´°ôá=,@uà®5ÌV´Ëžš÷ ±™u},]-ä5'Þ¥îd¢÷˜¶êÞÉD8ràžô\w‹ïwï º65“ZºÇѼÍx×]¥î>Ë‘ZÍÞp±tÙW YÄÞµƒöt*/£¥;Ê#Èׂ튀°¡ÂGg*›™/qCÇ£^¯zàÀ]å‚åÒ°\Z–KË; Ê‚_ù—Ç`\-#À{2éj9Ç©`‘BXªÌ°\„,¦–境öeo`u1þ濯¢Hr~ž´ð~xQU†ª²ŒÇŠ““˜ããð]ùžþN©…ü®‡÷Ü 4hРߥ© í4ìɲ›é;äÆvKšLÔƒwa #¹ ï㕃õç=èZd,‘,¶W ©v`Þ½½°‚PuËïrÜ=– uÎ{pÞ—wovÛµÍôßO{xOüc¯RÁb··Þy×vìDfÆ Áxé…`´íá=‚Ü3þÅ}ƒ¦ç¼‡>2sj™,ËI™™(… ï¼7îû‚ª^–){GSÂdDYí>÷ZÃ$éœ÷I¯¢óÍ×5‹sËrj½û.°OºMø-šãq,9?O‰cI][ï¼êÚrãFŒRâ]ù~þN÷ï*xÀ}РAƒ úΓÀUL~=v3á®ënŒÏºÏvá1ž»;ìÃ{º¼{?ö"½.wÿ9¾~76SÉn¹RÓÓ¾õ[UÛÏ‘8ç½qèûÎ{›w·Îmצëw·=x7¾¹ÆX¨F°Hq¹÷ºÂ”¬£òÅbéAH4êÁûRùÙÚ›ÛQ,y啺k› Ö¹îcËbÒ «NY㺠ÃbaÙߌfKö÷I§s.^wãnðsÞûð¾ ‹©e13,§–åBt±™ ŒßæÌhšJnÝJÛ¿7îûhôîÅe¾SÁý» Þ 4hРA¿3%Èk6ê壇G$ÄpTÔsó½/… Éôã1Ö· ï6Í87ºï’ׯmUíGs”ÐìG}¬è–5µðN/2c{C±dïŠA æ#APkêm-a2ù«[ V«„(’¨¨wÉx)‘{±I«ë+gÙ~$Äîg=¼à>ÄCœÉan䣘" ÑH6¸aéù÷ópÆ?jˆ!î,À_Pó[¯¼é-ÀKÿ¤D[ú7Ó ª{[YfÑJÓâ¤$[VcÁ}ï»BYjÖÖzÕ])é€Ù¬ÚdUé÷ ^½e¦qj|™+ò=kŸ©ë¦÷Öó¾êàÝ—vÁÏ;/ì:âî;°JYy=n:p–ÝÜ„uFÃÆzî+xw÷©kÁÖ–bm¬­ ?9»öSùÜÁ*òƒò>ÄC qG~4Á«=Â/ÄYε_·Ã5œ‡Frˆ/ðÀ” ÞÆ7/5\y4ï6ÞCÜ á¸u3^êÅúî†e`_{±ì©o°µèáÝİ>Œ.³ð†kkAÊumˆÆÖïÞZfá½.{xo*éà]QU’Õ¤õ¼÷ð¾˜Û©T ð†J‡;ÖO6ÒôÆv™E~}Ý)ï1ìl)ê5EÓšÆ6NZ_¬­œ}à~Kì2_Í GÁýY ïƒê>ÄCœ‰qÍì<"='T ƒ@¢6¯¸U6üû#.àJs ™XgŠÍäZ„÷7˜'ò]âõÆbˆ3 î£âF• Ýï7ò¶ ÄñIª¸Ì{Ûths3"Ž¥wWÝ%D£€ÖÚçáòß„‘ä{ O¦T•fk+è=ïck›¹z‚óÏ9zŒN…â$ÅÝ=.þmeb'­e¦­é_×°oŸbß>EàŸ]ßí-õ¹ÊûîC 1Ä9W—÷&RŠF(*í#Fá|]qÁ{ÿ+þ 2‘‘,µ:—FC ¿þöп˜ç wˆ!Ît¸_ùE¨Çù¾Í‚òN!¸ì²ªJS–†²Ô¤i„²÷¦å ÔI6–º²MžáÝWÖ6³¶šPU†0”ìì¶AÒÈ&åÞT(k«.É×Yf´>…ò®m½û5Û,+q~÷º¶ÊûÊŠdeEUßÛ™^òœ÷!†bˆ3)ÞÏÉôœHI´°£*}«º{Ѥ֠ÁÁß÷!Ô% /_~éñ,§ÑŠ:ô( º¿?‡ÿÆžórñôac1ÄYBXÕ^›7ÎäÔºïLÛB3ÂVÊéì1N•¯«浆8”ÐDT•qŒ4û÷‡ìß,•ܼIô,À³`™Ñ§PÞãÈùÞ'=B¶ð†gWi™³¡,ä9ïƒê>ÄCœi‘›%J´ÔÆëÔvÑðÀÓ5 ïƒü¸æÙË!€ß{ìB`ðf5… I™qŒµ^}7?/mø!†✠)­ò}S•r ·Ü4õ²¯5ŒÉ8M;p¯*ÃúºÏþýá-úlß³@ÞûÉ֙Ų‘¾o­3Ëw–å-õ¹Ÿ‘ÁÙìSf÷!†bˆ¯-þº~ ‰Ì‰)#¦ŒÄ¿®…A” ¥Æ+küª"¨JR=Cä‘õƒ-ø³»ÿ³0庭}|.¸{¯ÈOgPÀ»ÆæÓÁ…ÃFbˆ!nưï¾/NkÒÞ¥kNu¶ÇÙRò¦â¬Ùü¸1Ä7y~€Ë´`vÇ~þŒa ŠEƒ×ÔOXŽá.zãÕPÃW¾e?±—cJ5_ }ÍÜç?väÏxñÆ/‘1³ íà=˜f4Çvt= ð>ÄCÜ$Œ‚ï |ÿöñœ+uóÞù³-¾ZYÈ3=ÏûC qö^¬ÞÄ.LX€oÃÞu>&à0Ͼý>ÿ÷ŠŸ#‘1ЉF¢ñtÖå5Ü÷ý+Ô@M©Xû§c˜oh#µAú²2Aû’¨˜óKå‹yfù2j¬ïÝ/KôLRâå9;ùu\»¹oøò‡bˆ!¾Fp?[í2g¼ªûC q#p°Líq.pÑH2¯€üöûüçÏ^Lä%`èÀý»_þ:ëK?„-îœ`öZ0­FO0úð”ê¾>ªn¡ª}2/A{ã â2g^D4•"óF³Šf*(•OøÔñ ¹ 1ÄC|­q¶ƒûYï¸1ˆƒù¥»ðúÿ=˜ïXøýw5 0P¸ˆÎ6ƒ€ñšýSYø0¿uú—iFJc¿ò¦Zu½ ´”(H,´S[€Ÿž!=òÆ_Þ£Úç#Í^9&óŒ/À·VšWTOã1å;˜ù)ÉtÏÂ{èS†>M¤}vÆôép` q—cJ0 @åfØCÜâ8ËBžuð>€ûwyh¶Fp â÷öÏ™¿:Åÿ{TC)æo=¶ÁÿÉ&¤EÍG¸k`Ï@¹l›AÀ؇ ïd ž æe§q¡þ§à¿n` ;ÇÜñ`ªGß2ƒ”꫹όÏ«»%¦d~BæYx7ž°ïA^ÄÔHš© ™IJcá=ÍgÜÀ&ÞGêû©á â.W+ÛÖtAª@l ä½é ´¼k€ù!nÜO¥ºßÔsC÷!†âÖAëO8poÜ…Iß¼Ó=ÿd ©0¯ë[Ù‰û45ˆ¸a}ã?ÐP}h9£^ņ&?;jñŠÿD0ñmy4OAq©…x sð¾`›Q¾`ìC!àxk™ŸÆ…zµ°ï9V{p§‚é|„ò"5G%M¯º#¦bDäÍ{€¯j ?$÷br?ŸNyWEC.ct%hfÂ*ïÒïÔ÷ÊóÑ’!î2qÖàè [íÄò9Ì×`$Aä~÷ÂG ØîüÎòCÜ2p¿9H?ùÿ V¿J ªûwYhÿn tà^cæÞ%ÈǺ}ÜŦ…vbÛÁc%U¬O ™€¼»A΂žð  Ö·ò¬&Ÿ†gîvxVÕ6VI¯ øªÓÜ Wü¸UÝ·c_¡q ?ñí`ÞtêMÂ~/ø °B§¼Ï‰˜ª_’û1#9íÔ÷é1 ïÆ(¯Áój”×0'²Ê»Ÿtª»ñá^Á_ŸÌwf*¨3Eé{”OxèÈ*ºÖC q.ƒûŽ`·€¦²óðØÁËñc0ÚB‚™‚H I*lì9tˆ!nÂo)ÊûîC ñÕõ±ôj»Sm¡÷dÅrê<§ów‹?^ àET x +IÌúš±xáccc•}Û0ŸC>ììÏɲ†Ý£;w½_ ”`~ij€È `<¶ð^6VyoGa>ÕÖóÞô¶™ñA«Ôï ›/Z´ÊûmUßßg=é¼kàÀCí™tZ˜ª±Ÿ“ûq§¾YÈŒ”L&HOwÊ{¢J2i-3'+ïÉ<#«“Þ23÷©Â^y§©`Ö ð>Ä9æRÁÞ DiOƒ Ø ¬{îúðol^§JHA ü¡€ŸÔ÷»zœ+>÷ÅÃ×:Ä'äó ø­;þs}?ÄÈFÞă „ 0s£}Ýxþê¥+VÃú;ư~P+l¬ÃÆììƒ};vì샯ûºé³­ÄËÜD$ñÂåu&·à>öa¤à’ÿðñ”×0R0ö°ž÷éâÐL|ÁȃDØAiß{%†Kžñ5,äç\é÷«èµ#Þ¼f*e*Gä~Læ; Oa*¬êž{1s/ê!ȼ¤ó¼·E’Õ y÷–™¹¿4Èj˜Uˆ?.†vˆ[Õçæ_޻ߝg»¬Pq„Í3nyËÀjðŠNÃÀ8xÏ|¨¤÷Dvð®SiÏøŸƒ½ì®î§RÝÏÖ8ã”÷AuâNƒö'€´fx$¿Ù î¸ÏŸ$0 ?N¯¼k{µJ&°±k#(N8`wÊ;Ò½à¶Y}ÅWXIMg›i& ÇPHÛþz}¤ä™ÅÜ^Ü.½ô­<á ûùíß¾ìöÛÆl ýrŸ‡•ÒR¬G5þÅ]mR>ëŽñe6›0™ÀK—þŸoâcômž¶žwk›­ ƤNuO_W%¬îƒÕ[{ƒa×A{…UÆÃ~Ùì ¹Ÿ5ÜíŠÏó‰{^‚ "nÕ÷pÎï~ÜÙe<¯Æ“¥Œo¤¼{%Y“Õ z*if‚2÷eÆÇ+tQ`²f5ƒ?`ˆ¯ŸÔÒcÆÔÊ£::Á jÔ(AÑ0#e— gÐ"›o’Tè‚£vžG€=lʉª A€IUîf$ðÃÊžâáë¿+ǹPòŒ‡÷܇¸S ýë*ØöaÇ@YƒW3<¼&¿ùTxû.÷þgH;f òŒÎ2Ó‚ûÆ x‚¼ êÚÁ£¿òŽ÷ô+â×½˜b tj˜qì©Ì7 ~Á Æ jÔœW²Á‚¢D]H¼ÄÃCqŸ~Ÿʃѹél3ã-ÅØïU÷âÅVS;ù¹¥1-Çø"Ä÷*d -Àëh—îQ÷ãñW¿™·}ãã:x«œ™H™Šs/Âóûj3•ˆ)EÒ©ô­ç=Îrò:&obÄôÔÚfZËÌØƒ½LSÌ*ȆšCœoývnÇ IDATp¸šþÎÜûÁ[«)^RÊOÖx²Æ¯+O±Ç˜=Æ|ˆñ@®8#V£ö u áQ(j˜¹<ñÃ&¨Úž6êªD ï#‰L5:‘ÈD[x¯€Gö™»Zœ‹v™6ÎÛÌîCÜnpþã†ÑóÀÿ7ñܽö ô]fc EÅȇIã ŒŸuû-ßÓ&)ŒH} ð­e&QÚ×Ýu?:ÛÌ|a¸ÿ÷Æ{Žø½ctÖ™}û;;ÂÚfÖagŸ`gììÀ‚[[‚ƒcÎ;/æ#9~z¿ƒŸ1»‘á’L´ƒc¢0v”†q³‡Éz&Ñ3I,%^÷OñÐ×\É%oüBg›»J3­êÞBüjêÆ­w3bªíÈMŒdïÅoG¸ðÛñ¸w¿¼óÃÊËØÚfX°Íø1¾R”"¦qg™Éý˜¹ˆ¨2¿SÞþ±/q¶ÏYf<ƾÀ¯´³ÎÔÃ>Dïp„ûIàZà³À¿¹}³†ÍŸº\Æä*¶2îÀ}— {Œù3~üÎ÷ïó©|ðwAæðW¸Ú€ïAàÙ¤uð÷ ¸Æ&ª.ÚfZï;©; q—÷sÑ.ÓÆ Û qnƒû÷iˆ5“È£Ô0~¶­>Rþ9ˆC‡!Þ´rvQ;)§fúŒð†;:&îÂRìY€ŸùV}GõÐÞ*ïG;xo`–¹#¸µqhz«±¬ÿz\ð3C 4µÌl¬ÖÖmÂjQXÕ½i`eº'++'8xðôÝk?Œ ¨¶l€À šc-BÎ2"ƒð "0x×Ú ‰žÛÇ$x,¼‚=M˜ŠÎßB{‚…öзà~KáýcÕ}‰õ_Wv˜ ­$i<ë· –̪‡K^ý >óä ™Š3‘’{½m&‚R&T2& ¹c|—Õ”Y`»®:€of=wÝUò~¢n,¸ð>DW؃úó^V[ˆ¯ÜscwŒ•pás?Ã'ÿäâN}/ë€=Ï|…χùu^À¯òkwÊjüžøØæÉwzhçø*².6ßsüʪïr¤0©èF“*¼°†t(9þ… ÖÏ?2ì'¸Ÿõªûïƒê>ÄmÄóçÐ4†£Gs¶¿;XCÜ0šÀJd‹’”®!çäÀ=×áîÞ2¼OðB›$å…˜£'Θ¿þôvµüÝ×XÕ]kÈœmf@A°`—ÙXÔƒ=g› 4V©ö<6ô>ùŻëð‡•à—CÓÀdb•÷í}Ö6SU‚ÆV—$M­ú¾µ³½}g+¹¶àÞÁ­]ÀdCpb·w|XÕÇ€>.;«Lï;…ÂCuø!­ê¾*û0ñ Î2#ì¶ó½^yÉëáÙOü*‹,b­:xEOÖ„¢è×¥ÝÖ-Ð/®âa¸ðUŸácßwYo›i+Íél3½òn|A|$§Ê|jé‘×1Y“ÐL%ºR”ï&'‚ Ò¶TdæÿäW&DGåÑ€ð†ÂÞ…k'•­úì»}´€\ÆxªÆ+jæ:bϳÊ{G…OÈ“ýR °7³ à¶«%w!øƒwiÞ+ 8Ag™!12Öû DbÈŠ„]3a}ØUîq®ƒûï¸q«AýÉ*ª€2¨’üÛ¯œà>ß»fë ²a)&”Úº5Jm“Ÿfq‰.„…vïñÈtV™Eå½°›žÞªõŽ^u¯ç0sðž† × õ྾b/ÆaÓ+ï±tÞøÚ[€_<¾RЛð¼dÛǰ¹ ;;6YµiZx7ø¾`sSpÞy§ï³ø©ûžºÍ'Ø< PXḮà]Ô… :“½êîàÝC’x’fAu÷ðŒà‚·Ïà&‹Ê;vx+6ñuud=ï_Í÷þÆú;›„Røº" ¤‘ %5>?Ëðû<÷[¿•‚ë ŒÜ¡ã;@)ÝÏ*AP»ÂO ãÆü·çè³¶#)葳Ïx’ÙÔ&äqîÇ©|î7ög#ж™!Îh¦»]&`]tcþ&'ˆ£DrŸÇ9p—Ú†•HÝHy¯%d#8"K(šÞ'¡ÇÄyÝ[ÕÝ/ ño]²ã-‰IƸ²gSùà/:$#xØ«–m3{SxÃqÃ÷p±€×ŸïzጄèT ϹNðÚ67[[P/¨îëÖ¹µ%Pê4}_Hê®úÛ“uÁÖ:d%Ô?NoA‘ÐH…Öu¼±^÷yïÉŠ ñ$¹ƒvß| %¾–ÄN•^´Í¬ÄЄ }笠yò²æY¬ˆÑ|]áéšHÌ1JXp J6Œ½½¥ÆYKªûõîûˆ„¨¬Œø¢Ï?Ÿlþ;bJ"Gò^¹¤U•7T™O™ä~¼ ¼ *×]uìÛ™½ò^#xó¡­áqÕæ8þÏV= ·‡ZmV޵}.`iŸÍt‚_VLÕh ÞÛa q‡2úS!8á•öF\ì~W€­eFFà×v¢‡w+¤jhR…H "54©¢)ò<&«­òþýX#ß>ì4ç0¸ŸK]TÏXxT÷!N ÿ×ÖŽÜ™}¾ªO‰)SXùdž£óþƳ{¶²{ø• \òÞeå½ö!OGâvõ2¼·Ê»÷ ±Mg)Œ| Ó¼Íëö¯Ÿ…'LáïGàó^² ¯±-¿ÿù;á©_tÊû^üV r%O„°ãñ!æ< ï¦w LhjP>x><åÝ‚«~67@JÙ©î­ï==MwĆ‘›@)×@ A˜Àæº`m,¸ò›°ÝVäòPžÀÌ„…÷|Þ7¬ò^-ªî(ŒZv~÷±ßç¨m¬Ø*’Ð{ÞOå{ω (ÑZZÕ]XÕ°ð. ð¢!‰³¥*?à_AÏ%&¶ILK"ŽBr/&’X *™PJ ð¹ž(¨2ß&¬¦I§¼?ø_äí?x)ÁD2öDo›i•÷A}¿ËÆ'¾t)—üèá¾$âI¥LKç=¼»‰rQ„äEL]xÌ‚´ƒ÷’€„†2xÒìõüíúo×uøK!(ϸC&Z€÷&/²¶™Àƒ`îl3Þç‰ÂŒ,¼ËÔNVt*©¥Ç¬N™Õi79b÷[óÜï¸qkàï›çy ¼Þ’9`Ÿº3}ÍR­óÿ ¶ ‹ç†»"¼ö-Í=ùuVy׊ÄIC~¸UĺSÝ' –™ûú,¬Žn;ÜÝ…¯ÿ°]¶ï؃7lÀ}…®ç÷ȃT–ðÊ^¼ÿé¥À–y¹ ï&ë!'²…ÉŒ»x'©]—ZXxoÇæ&®1§çAž^;Ðh•ÞÖ$ \Àãæ [ë’­uxߥØbÍÙIð. Z…,sðžYx7…w› ÚÛfB$¦øZrÕs ÿ¨ó¼;å]ºŽ´ÚÀÚäÔgžß¼˜"|SQißTDrNcRh€û§÷G¶tÙÊÁÆÉèmísW5fú”qwÕƒ»ç^³ Žþõ“ìgüðë tþ缨@ULBeUw7¼ÂV™i<ï#X; ùªÿ}ãßõ9·>n®2ö •Þµ‚_ü€»ðÎKhJ{e¸…`D4ßÓw.¨n¦/sY™Ü=ö=gNöòèvùîîÿ X]5_ÑÔ¹†OÒßa|IÀýÞm,hìa'Z ·òã‰Í3žf™éÎ÷žD‚DÉ%¯»MV4Z¸ÑyÞ±ëžzÞíàÝ}çUm“Þ#Vuo-3¡,hŒBKÙùÝ¥ÐLW©Ã‹k䇴½ä6iV%H¥!€ÈŸ£Â<˜›ˆ¹ˆl¥‘t¥"+SÔ¡­2“ù´·”Šrî³Ï£SÞýÚ)ïC¹È»^ü˜+ÙöxÑ7‹éîåEL!ÃÞó¾ïצ˜/ òûÄÌü”Y•²§Æ„ÔxÄœ°wÌíï•‚Z@#ì¹Õ3½e¦í9×&®Vî6Z ç½q–™Ò^&N¨3²Û¡µÍÈT£G’ú:Yc•÷)ùб霌¯æs?cð¼qæE]Zwð.´ÆLc ¼å¢$Cï—sÛ°ædxgð·°UÃ_>{ixf¾ Í$Pê>qå!ýÊ^\´±6›µVþ'®¹ôÖOJ^Ȳ ¨r%°La4q¶îÚAü4€z^ºìÎå]«®0ÍX*ÙÞE(µ½ƒ |ð#(o‡šÇe©ùá§JÖס® En¸áý…óéòêïï/ìßöÜs ÊûxÝ&ãúè™èá}$I<±îöQ•–øõ½/zÞ7Vzp×ÖÆ½ò~2¸ÿ~5“ËL@I-<¡@6IUÃƒßøAªÌGù ò2m í[iòyŒôu÷=GÁíI ’“tɪ±ø¤³Ë”Ù‚ê^' ¨º´õÝÇÞIžwg›9ï¼ëøÒ—ö çŽs9~Zô%IÛá Õ–]¡7ŠÈH¨=*öñÇ•=×H˜çs¡ü†¼Œ™Unw™P°F©|ªÜ§Ö§®^Vi!ÄÝ8j{ µÖ|#À‹ÁŒ¬òî§¼kð…½ ÔžOá…È´Á¤=¼›T0ÏBšL);ž2bF:ìGç ¸ßÕT÷;ÞÕ}ˆSî}¯?°µ×¼Ú?âº/Ú¤ÎÜ-3AUaý!°l™i_sî%ý}ZìEnu{Gk&aÄ8d©ÚL˜ôð^¤°6¬} ¾pñ³ôj{å–¿}Ä-“¡ƒ³‘#ÝP6YëÈñÊNlà=NmYËʇãA~•}:¹&S+aï”÷0¶VOwü—_·àn ”…áã/õ-Hì:H_!íº›“á]X˧!j¬ú®gSØDUk›Yô»K›ìëTw_Kžçù¼Ów"ãJîzAy$¾=μÛ4=SQZz4FÑ…Ö&£hxü?½ÙZcêå7$_̇úJ:y“ù ž+‰ahO2×s"b!©dÜÕy/eÜ©î­òž7¶ÃjâKšRuûÅRªSÞÓ°½-‡“ǹOµ5Ü)èK@®bUõExwçÇy‘W1&”q`áÝM2gYÊ<°Ý~ó"f÷žð’€”4ep»ÙfüÂžÓ Ê%+>µ¡° îÀ¤Î6Ó¸R‘¦×@2BJ/À•½òîªÍÔ_ (ꀙI™2êÆçVÜÁý‡÷܇8%à^t…Í•½ê¾:ö’ÆÁ{«¾·v¿²~rW'Q4½ú®ÝUá2k£Èk0•»šš¿ò"Ö¾÷ãÜ«dO\²j-¼kg³qÕJ.»ìßøØÇn™ú.žv¸Ÿ ï~ÿó¸õ¼/Øf´´Šù‘|Ñ6 ˜¬ùLBAéì"¹Sß;ï~óª·Ì4šäôzÜ_ñJøZ˜4yªOn•wzxm@S@6e)a5H`¬ÀÔÖ:³—ÙÄÕ@É“àÝþ 6¹Í{ÐH—¸j<ˆWzpom3k7Q-®MR (‘ZÊ‚ÚXÕ½µÌüÔ•ÿÝNþœ-!+, ‹À„YïY‘1~Põ„€QÂÚfˆ×½òüotÊ{B%bj§ºW™iDgY${{Nu÷Eo›©4̬ò¾¾nØØ0<ëYÇyéKW‡É9æÙ²Mo±ç‰£îüׂû;[m9òyL^ÅÈHSÆéxfá]Âì+)…ây3­GLk[qÆàs”¦ ìþxšm3_¼P¸ò1 [ˆjÞV—h-2> S‰Mä÷"ës÷S{A@é…ÈTc¼ËTÓII;™6½ê¾+†r‘çRœÊ.s.ƒûïC q³€{èVqG8ËŒFáýQç2aFo›ù“öŒïÛ¬D ¼t×^ÕZx€{í ’{a˜×д ÖGŸÁÖ¦ê`·µÎø!è`ÞSÁj*¸ûÝêÚð¬g}ž—¾ôn§\¯øi±HÈg§€÷ÀM4*¸êpŸ{Øî‹¶™8ÂRxSÑK–™I…ƒ÷ãc(w{Õ}XhW¾Mkû<ÇÞv·Ûü½]ñ!xú=YÛ¥q¸œÞÄ*`¼æ²Vyw>ÜÑØN\ªÒ*ïA z&IÖ¬eÆÂ;ú9å=XPÞ#!˜†d¼ îZÃêÔIõ…|–‰èáPüÉ?þM¡¬_ýb:?;Â&¤f~Bà—È@#w5Ñêܪå{.(1¡UݽyE5ò™{Þñé<­ý§Pm¦ªýÎ:“ø%{•·¤¼‡v¶k™Ù¸»…÷­­;F}ßdkn«hùñøŸç±Ûe{k§4w¼h7®Ä¶!Ý¿ ïTäÚî‹^\SÆf$±!ÏbfÆÁ»oá½­Æ2Õ#6eA‚è•÷Ó ï£à˜gÑØSŸ¡¯rk°þ÷@€ŒAúV}ש…w?p]U|7¦Œ §¼›T G6aµ:îQg®›±~÷)£¡Öû9î§RÝÏõ¸Ãà}PÝïøø—¹~ð0û÷'ììØqðàêù«ËNMn-3ú­—ð±ù_ 2 3Ðð7ËŠm Ñ3&Ìÿ(‡÷ÐŽ¡²Ê{›™7¶)•{MWÿü}x軾àà]0ú‘-¼W©Mv”÷©kÃêªâ/þâžþôÍ›]­óv"ŽæÔð®k›”ÛØ¿=»Ì­mFDöó™—K¶åÉîNÁÜ· >ö¡ð–'!žø ¶ð®ÁêiPßµ†‘~ã ÷s›HÜBÆÃÜ™æÍÞ=›[ÜùÞ[¨?ß>—7]s\¦3I²%IT«¼ËÎ6ÓU¥p~÷¶\俆 tõ©m3áMš¨*ŸJغօ ÐBòWïù~L)hB…%þ—+8ÐÃ{V&ä~L(D`ìÀ¶^{îÇè¶ýcÑñ)ó4dDÌ…÷JÆ]Âj€„BuÊ{-<²:!ô‰¯¥g;ÇzVy*MP7Nu×llXxßÞVüíßÎyÒ“n[2²øUJ¸Dð~˜Ÿ³Ï¯¤àÇVmá]ú0þÞš½¿ô Óªºÿ²´§Å8nÏUõ¯þøµexÏ˘<´Ê{qH‡D“9³YÊL§…÷ï9ôZ~cö¼à%1rÉ6sÏ×|†O?åÂÛ¼.G,žµÊiOó‚å6mEà@Âè(È»JA&öõ]c&à¸I(“Ò iFsš‘gk»—Š2SÔ™´w°tÂTŽ:xìü¼=z̰sÃà~®«îw¼à~ÇÇç>·ÇUW瓟<Æ«^õI>ò‘Ã<ùÉ÷äiO»˜G=êÀ™¥,­½ÖÊÂŽxÓÃa£WÚßû³pÑOÚ“zþÇNå]Pl[€˜_wÐŽëÜ9Z»±(œ7PíöÊ;ììx}Âj•X†÷f$Ø·¡ØX‘Ôµ!;;7¯Líû‘8ï‚Mr ªXPüád •×%šþWÁsže}¡ZÙMÓ˜Ãûd#ê–7úçaث‘‘pM¡bX= ¾wõrl‹Å ‹S©[9Í]™E`O0¤o•Œ”…joõÔ¾VúVu){c!rcVô–™Dõ «¡SÝ fIy°ú¼=òß· ›’7VÛÛØ8z„ 5JÔ(êHñ{<Ì¡‰M ,%DàÏlœÊød¾…ô&Pß»ô49Ny’ÎëNõL2߈˜ûÞ¬êî꼨%å½C²&aÕ—$¾„Êsv™Þïî;å}ãÓÁûÖ–¼Íê»øiiíîh-À»âw€Wïr· Ç„#±¤¼ M*-‘-LªM6øñ¿–hþØCÕÆÚüœ[á~ÞŽaOl¿ ü^ÿ=åÇì~˜‡1"6”q@Û’‘³k¼·¶™ºWÞ IÄNT=¼WÍéQß׾ǔ1Tü¬oƒÐÞPmáÝ_°Îx©õ½{Mßyµ˜G”Q@‘”^`¡=UÔ¡Gy"pðî”w™2 ¬m¦­g?ÄÙ_Mq?›.qð>€ûóyñcU¥‰"ÅÖV̽ï½É;ßy‚×¾örÞüæ‡ñÈGîô¦þÏóñ<Ùì~·ÛrU•æò˯㸞ë¯ÏØÙIxî/~ÔÙe\üã·Ú³wíàÝùÓ¯þ-àwé@!Þ'öþÔ2¼=+/¾\*8¾·ïsØ·Ïë~X•¿wmì­Û / ©*C]Û±³ãsìXÍÚÚò¡}ëU\ú€Ä;$Lg àÞÔä²÷á»{Çé‚e&ŒìçGhæó¶&L‚ØM4³…Ef­WÞÇ~o›1n}H`%„û?Hñ•ßùã$hXIÝ{õU½ ¤!ÿ¶šEš‹¾i˜îÙõo[¿ûسö¨±ð>Eg™I<‰qð9¿»Aôžw-ñÜ$àM>ö”ƒ÷wÅ‚Ï9u³&V4¾UÞ[¢ð½Êv>uÃÂÚf|M˜åd# õó ‚Ð&«J4…™›"ÉM >\©ßO)~˜J$6¯ÚÁ{•ùdžmÎtÀ‡$P.Úfl™È ÒìÛð¸k§¼K¶·%ó¹!êаšÃ\ÚgÞÛCô&¬ü›!/Ûf  GpüasöÞ¯º|“Éx±r÷·4Ê7„0U(µPÔ\Òç•LH·~x ”E@&“Nyom3e‰ÄZHLJéø~…TÌNØR‘©‚ØÁûÑÒ§)¬…ëtÀ{þmC! °úÙ^cñÝi>YX%JR ïrÞ}ð{:¦ˆBÊ8¤ðê‘G3òð¯¨Ø=8¦Ì$M&ÉDB&fAo›¬3g¿ê~k÷sæ‡{œç`D‘ââ‹WÑÚX›„6lm­qô¨àèQÁ3žñ¦Ó«;`¿×½b”ò1FÜ®ËuÕUÇ»ñÑæÊ+Á§Ÿy£›î3§²·åÏsÛscáõéš³Z˜-(ïÑιÉI±×Âû¬WÞîð6ï~èŒÍuÅJlA×,À»I!½Ç2¼ooû7w€C;‡öGÌö,¸/Á»n¬_Öà]F07z¼¿èE𼟰ëѸZ哿7”ç½µøL˜:pß\·¯í<ïÜýÖ2c@$‚Õä¶©ïâ—ORÝÁvQ½]öð.|ƒ$a0Bpõ#KV.˜N-,ö÷Êû¢m†ˆ^y÷$Åbs&Lçy÷ÉÈ·ëxKà}õ£Çˆ½šO‹‹–mVÃiAX½h½ïìBÖ$òn|ÑÙfÒ£'È×,Ôσ¨SÝùMT5Î6££ŽXJã£ìZ^_ç=I(uD”„B!*õÙ•Š * ï÷»ßI¢ØØÀAÜüÜDKÊ{çw ¹¶]R³ÀV›iá=Í$s:€(‚ã[KMe’®Üå¢m&ob’@YËLéA©xËNѽÐNƪ†ƒÛ![«>e©9$ímÅÆ†amíæUîïÊÿŽ˜£ìw°ïH É ,­_‹Ún€¶sÎÝ€óݧ­œ”b+±˜Áñ‘àø5»Ÿ3¬Œ=Ö× ëð ßðÞóž‡'æ[(oO™ÍÆDÁÜnûÅ«õWܹ-Z$]÷üd?Ÿ,í‡qœwž÷rtÊ»ô5~Páù5ÓzD©cbªNyoª ÷½ßFx_û˜hÎTØ»j«WÙÓx|¥=7†'­•- ©R»¯yøühL®c»N‰-iýîY™0ÏBª ëyW‰µÍÐÛfx?{ã®îs¿Cà}÷3aG÷¹øâ5Æã’/|aŽræßÑHQUcDîBX ÷}ÁK^r=Ï~ööi_ž{Ýkg¥…È IDATc Z[$¯l-Æ“Uwç3æ:w¡jU?{ßuW.7þ‘übmGCy­=ù•UbO†wãA*`÷$xß·ÏÇón^¹‚@7ýšðÒäÒàÐNØA{ä”÷4Дù¼÷ª„Ì@Ñ@¡]òª{#Ïüζ¬]ÇTæ¶Næd#°ª{ã@tɪ±ƒ÷µ>Uùv²Ò»,a5±õêøÀò¡ÝrëŒøž›wˆ”«ßÙhÛ:1´TZµ]`¡è~þßÿƒNuo÷Ø5™Ò†.Y5êFª{݈%¿û-QÞMJkæû#Œ)T¹í‹ÉõwåèÖ™åi§ºçƒwßà™¶@‘û1óÐ*ï&ÖïnB ð:dîG˜@ CåÙdU­éVó:&kö-øÝ-À{lm)Æž ª4_ÿõ«”¥¦,5“‰ÏÁƒ1û÷ß|ë÷Çì¾“ØøeÐÜE[7µÉí j[¯¤„M¬·Ú%TweÏM®=xÕ½àGfp<…#ØÕ5ëkŠõUØX‡ ]Ìóžw5¿ñ 'æSÄôª1Çw×Ù·~µzô½ >ã¶ý˜ÞFÓÞrÖšY™’Žm¦UÝ=¥Ø5a§¼~‰ïWxAͬNI=Ñ{›°ÚÂ{Ý|í˜0ÿmA¶»N2:J!`õ3•ðïÜ„HY¥=4ËsQÀþ+àÈ£lw¯±ãÄ‘ÄÂ{RÆuàÑŒõH±=¾žÃÓMÊ «¼ÇVy_¬6S ;ÚYªºà~)ïCÜù1ù:$-,cáfß¾ S[ëLÓˆ%÷å—ÏxÈCNeš‹.²vž'ùçÙÒ‡e°œx*éK®X€wUA.`/\ªRޏš~”3ˆ’ ÃÎTÎ’›Øm“V ðãñmóç¶v™Cû#꺷̤>x¢€*ïÁ½. ö-¸MßbpÁk<‰z!{9x7z©ì$„]6לJßÀÚª}näÛª È€ª¬m梋ªÊðìg_ÍK^òÕ¡J<êfwÑ€l,¼kézžkÐŒX÷à…xJÊWTŒÿÂgìõŠ{ÔÐY—l²j_ãÝúÝ…kÐd=ﱄ­òîAüÐÏàÆ2F/?ŽH—ßÿáäMŒ‘vù´”„ª@(scˆW°þwGY/ŽrÅ÷<¨«(ÓªîÉÑ©UÞuÔ{Þð³’&½mÆYgŒ/3M3‰ €yÑ+ïYcýî‰ßQ:€¯<öíS®A˜ÏêýÖ:x/KÍÁƒ ¾óûnUúx¦¦ ¦O,ƒ;ðè¿ú,ïüþóéZå˜V¥U×o Ü:ж¿¯¥p|ÇSA±#X_3ò~ÞÁtyœ7½é0ßþí[gìùR<Ì;OúÛ¶[_a®½ýÀïÄÞ*'N¬Ó4 ?®ºnÐ|¸¶=yÑ{LZ¼ƒwI²*!OmÂê<Š,¼G‚¯8pŸé ï¾…÷Õ[fDíõ¶™Ì*ï“_…Ý_¿õë¤'„~A@pVo€WaO©´•µ" ¬m%™NyÙ¼ioäê¼k¨§;ÖzÛL)šÔ*ïû¶®ãC‡ïO•ÊÒVmj•÷)#2FC›¦³ÜïÊe!ï0xT÷3+’Dqþù¶|\+ªJSU†ªÒH©Ò£®zØÞöNYEå¶Æ}>0†´²ÉB/û¢/úÛÚ_Z+IPA&{xÇ©î«VyZx×°[Yh¹$HoQØ÷,à&û>Ny—5Üë™ð©—}mëµuɸô;€¿ö«¼'VÆp­( Î{p¯ ¨•µÌ#B'ûÖÖ6üÂ÷MW"rì<ïcŸÎ2£5LÆ}Âjõà® x5KðE’×¼æzžò”¯r·%¿)Å]÷à.œâ¾X¢ÇÈ.—b àI„…ïþÞš_çuài›¬f 5Þm²*]²*çwûn71Ö6ssÖ3ƒ·ûÿaÁÝM,Œì‡/+:¥žI*ßël3s?ÂÊ’‰ë[HDáQe¶9“IPø *¥‡(=¶·ÛÛŠ0\ȲÔÁ̓ûe_ù8‰±ð®•Ä4m$R,Ã{íy¬¼bƒ?°Kg›/-¼·ûg¹ïþà€âiŸ¶ï”¼¯¯6ÖŠ8p bw·f29³t#q‰…âÕ}0z´aö>šŽÙm´uÀ¿]—áØîÇwW¹ûúçúFtï§O —Nu_„wÙ«îuêqÉ»>Á›Ÿôxò0¦4µ–Ä1²³ÌäžíìÖóžÕ ©W.«î'Ùf¶6¿pÿ ÅÑ80úoþËå"[›ì{g2©ﵛ‹`Æ®¾{Ú+ï{ÇR2m•÷2 (“€&±ÉªÍHÙfhYD•iò:bV÷ž÷)‰Û|Cœ;à~WTÝoxÀýÌøC‡"67ƒ%x×Z`ŒìT÷º6¤©dgÇç#9Æ»Þuï~÷a>üácäyÃk_ûñˆÍ¯y9Äï7Ü•ó c‡tu¥–ýÇ÷þ k˨Kȼ¾ÚŒó†·UV<Ý'­Æ¦÷QÔ²+§QPkk›ñKW2²€• çݽññáƒ¼ŽºÖlmÅ<åGÞÅ×9»Ì¡ýáR•™ÉÈ& {bn»Á¶à^8hŸ;ÛLáÞ|¡JË<Þø—Î6Aꢀ%å½]ÿhÓæÂ6ÒÖ×ìßk± ï~w;RUý¾°À—¿\pà@xÓ“GYL±XaF î-¼³íÚ}(6§aÑ.£SÙù˜De0µõ`ÿn¬ùS-‰ÝwG Ê»ë®ê£ò' MëwwCߥöFÇÀ¯çõÏþ>æMÔÁx«¼£ÀÔ‚F*|Y¨aŒÝ 7@-Úf”i¨g’ÒÄd:^ª63Îl—Çjâ,3ÆÚfDfPyÃj—¬ªœmFAc+Ì$Î6cÊÞ:cÁýÆv­Sûù_ü"‰qmîÜ ð'Ÿý'¨¥GüÒMò§î¦ìÅÚmƒÅ Mµ ïhÛáø&±b4 /8ïà>6×Ë;ÜÅ·‚y«ûyÓÑ\bwçÕÔæ[7kæW¶µUauMp`ÇCÈbôé¯ÈõsONœX'ðKVWŽÃSÝþfïY¡àÖÆÑÝuþ×˾„ç;]Ðg„gýìQéàÝ|d l,¸ ל)¬ú&MYtÊ{)Ê8 I%uªhF³*¥ÈªLw]ŠgºoÒ´†=· qöÄîw¼à~¦Š4½q‚e íUe–®¹&㪫ö˜ÍjÖÖîq”²4üÑ}š(R<àk·þ¢ùKÜe ²²P"ô2¼·–™ö6}ˆmºT{ð¡ f¦víXµÖ÷VI îþ²ònÇ^ÒreU[å=®êÌVÝ2xÿÒ—¦\}õq®¾ú8—_~-—_~‡®rž³ËÚ‰ðœ]fCSÃt¯°¶™:wŠ{iï"m7Ú‚¼VéÓÚ>ÃJÚ„ÕЪïaàÔöÖóî,3î•÷(ì}ïÚ_†÷@‹Nuoá}{;`ÿþ›¾B?èû`u*€éfèÀ]Ö jk`Õº·Í´·F\jL,ì•\…Áh‰¨- !ø±+ ¿…è,3ÚÀ(°å"­ß½×Š ‚ªõ»/*ï7ï&ƒ¹Œ:2R …e'TÝžFHƒ0¡Ý£«˜ó#oy%/|̯ C´—Qg’y¸àyo"dc¡¾™Iæc§ºëÒ„Ô¼YJVµ¶I]{lú‚Ä· «³ÜyÞ+••[géZùì®wãSê€&P¸ëFb\n‡¡§™UyœÃr õß7ivc®Îø'Å2¸·Çg½|§ìO.ŒøÑ#5M¾/ØX7ï}c¶¶‚;ÜŸ<Ä[±ÝI?¬Zº49¬þœ=ç4ÁõÛšêzûÿÖ&‚ÍuA|àöirתî¯}¾ßº¿ ï¥ Æ¥}.bÉjX{uâ!C¦¬ç½TA§ºXx7}wϯ‰¥¤¬cçy_¨4³PmfkÓÝõ»1}˘¿zî´ë¥Ý ß-²ôÊ{(zp ˆH Æƶ‚Qx¤º—&;–tM—rbL$(3‚fä!BÅl7džT™éê×Ï”wD€Ë}â,RÝp¿ƒ”÷!îÀ ‘ø$mݹ8VdÙÁÁÞÛ©ëÇžz'ðž'ˆNÐEáqÁ©ž ŒFU¥‰cŇ>tŒ0T\zé-ÏÚ?¦{Å]Uö„tÊ»«8ãÑ·Ûs5ڻǸ÷¼ûZ˜Õ¶¼ŠÑ¾¾m|3ï“VWc p­òÞ4}‰H¥÷ÄÁ{ÃJ«·ÀY J ÆcŸ”¯ÿúM”ïY»ÌNÄyû#Nµ>÷zl?ïúk üÎóîªÍQïwŸ7¬¬Nìå %qa1õQ¯ùðÛR&œÀ~I+±ì•÷Ì‚eÆ‚“UÞÛ8ÂÇ¡b}’,Ü1ıDÜ„"õÝÏ•‘«躵ª9ìfNm—.QUjw·dÜß/é;ŽRYÓJß$¦‘]bk\[8iá}ÅUœ±~÷¾9“æº/Ù*ï#Ï0ö ãñìí=€èÿ:ÁŸýásl©FÃ’eFb—½‘ŠF(¤¯©‡ð Â3”T‘º¿òžò¢ïx>u&©gŠÜk•w ñáñœ&“T¹êýî&"{s‰Ê§¼‹Ny÷ÑH¿$ñ%i ÉNxˆ6iõÖœ®‚Ø{e|<]Sª wQidmh|Eíyhi'… ©¥û½0v²<º/t×Á{~Ó𞎠*𯖩ÝÚ’l¬Ù2–ëwâ¹ò¹Ö\è`Ý[P®5v½4|ôW᱿ Íš¸þ¨a2†µ‰v<îyÏËùô§rÚ–íŸ?‚½Ýu&ã]Îûž/ÙÉmàäêx¯ñnÞ‹2´} Òå=Œ)|k™‰d:%o–»«zAM¬$e1Šú„ÕEÛLê¹’´·Þ_ùmÓnná´¹[p—õ¸Gõ²ò>)Ô¨Æ8å=c¢tÆÞõÚÛdU ªÄC¦ ÍHÅá*¡˜[xÏj û-¼ìæàý,÷Áç~Àû ºß1!åû0FÑ··€0”Üë^–:¯½¶äÍo>Â[Þr„÷¾÷0ÍO>ñ`ÕÀŠ»(t‰xVI”BÒÅ7žäõ¯?‰s>ÊmE’ÙÜŒØÚr9òN~ñò-¿p¶·á™×È Ú:™h;‹î¸ª¥iã`€÷.””Ý´D] ºÁ¶16ÔÀÛP£­EމR,ö½ò¾d|ï€l¢Xî­ìyxŸÎ ×î¼omi¶·5“¿&bR_ZÀ¶‚:„o÷ùÎ1 õªû ¼ãàMÏ×<åG-j’¤WÞ‡wv…¼ýí·óÎwîpÝuéCº¾?òùÚÿó ’&㻓úñ/gèÆ…´* ÍÂI3ZÏ<¼çéâ<å½1! Šñ»çØfR£éº˜¦KÉ"24gjCWGØ6pO¼mæ Zz/ô}£º^tò/ɤ¤õÊ»ïÑ[fÎÆ!vzÂå=lIÒq£ònM›ÔÄBjHjâÉ)‹˜vé$Öµ•bU­ÃKÊûß ãÁøÜ?Ü®Ûj2¼_÷‹{ÜtÓ>o~ó7Ý´ÇÝw7+³¨|)¶¶`sîìÅWŒ‰^õk ¨"‰íh¿Eç»{Žê{”*rÁ€öçÿþC‡Jpï}ÒYöàd´ë_A×B±¢ºëFÅÜ-&Û Ñ ¼Ç+l¸ñøÈ_>kNC½ÔŽƒÓø`Æ»Ñ#;*-àž+ØÙhïÏ[´zÍ5ë\qÅì¼'YDkÁ¶ ñœ'î©ÛŒq%]SB+ªûÚÄpå)Û[šÛ?^ïHµikعâ#Üö6QÝ«ª£®;Ö×c¶·“‹rßýò ÚŒð®5,ÏZÓÑ+Ökà6eDYÈÈ2ÉåvÛ«í )Ðí¸-áÏtû>²sð¼ûβY ˆÎQÝ(Eä#"{ëÌ$p\u•tÂ5Fñ¢WÿüX¤ºï=ˆãàï¿ï-£·Ýÿ地iu0ªîÊâJ±ÝŒàž Ê{¯ºïþlUŒ­Cª"ÂØhÐà=ï]’…Œði”÷»oL!|£µúÿ:˜wÞÂdõÝi…©¢VѰ­» F€w±B–<ÕÄTû«ð.]€§ëP,ÀÕá}Iôß±cÆÃ»c:Uloë‡}ÜTTgé–ÝM„9ÄVï3¨Ž xÇ;nçïØáºëÚü÷µ?|£\Ç`ÆXÚ‰X¼j"÷, œŽð^V •$-6רÜñÂú|ðÓ¸dTÓ]>¬6QH6^uOW”÷ƒ¶™õ\’¹¬mæ-F =ÎÔx[ í+ÂPšÎ D½ò®½u¦kš<Âåj Ê{ÞË8!hZ–mFIBá¼m&Qò~ä ±ïÿ°hû‚UXäÞóN>ˆ8=¼?î‡à?q‰/>[U÷s\ò¼_:>k¸ä-op¿÷Þžb‡é h¨]Ä»>Üñ®Û;øáöe›·ø‡SŠ=àmKQÞMËÆ{*FxŸÎr-µ“t„¡~Àéû;¾úßÃ4 mÅ6cZQ\•o½î!uë˜aÿ4tÕ9ÊûêÖ|²"áx\¼¦ï•÷ÚÛfÈ<Äžñ·Â`ôEãm3™‚ݯºû®£kŸ†4E†(2L§ãß•ÕÁˆ¯¼û³kKh “XsÕ)W]‘ÒÙ’0ðð®=…6F¢$[mÆñã ù]ç.Ê}÷‡7ÁÚtdÝÞ2£ýzí”¶$ƲWø]”_<'FhïsÀ'Æ„„òƒ+oHãp¨QyG“9ˆZ¨KQúÎõ¼6¹úÞö]Uí9Êû•WÆ´­ãßú:ŒN‡¸JgG»ŒV×)Tà¨ýò@!7‰Âaµ¦Õð«ð^ïGr &rÙ‰òNéè–šn©)m2XfÒ0ÀÖUcÊÞÍP°«1e&ŒXeš€ÀÖg|ŠÇOý,°ÑÀÒ w–6 (u‚©jL#à®t‹uš®whl¤q­Àû$“g©Z¸±QdŠIEgïá=ó½r×þØiî}å]qÌýÖR\Ìc÷x “=˜,ao ?¦¤è¶`l‚Ö%}Tì9Ê{ÂæL Õ¹Ñó®UÀáC†[Þ³Ï7~˜Ã‡¾äKŽ}fúOÜŽ4£ üµl®À»2ÒÊ"2Äöãá}Q‹’^Ç*w¨ÌÑå†Â¤¨Ô‘8QÞOôžw—ãBE6¤ZQ· u›²n8¯»êZ.cfo›yå›á»žtÿ/åƒ\s}`X·òU)LU^yWÞ=¼GÊ0¢É"ô¤FO¯À—q‚j‹&§pcÆ»KmjH&±“]„e“Qí–ñ¨¼_f`¢Gx_»”ùY î—Òex¿¤º_¼c¿ã¦›öùÀ ²Ì°µ¥¸çžÊ›Ÿ •ëË ®–Á~ò-Èñ—åc3Ú{j™Ðk_ѨÇF4Óp„÷ðû¡ùé ÷& ´õÊ{¯º·BZÜÓ©âðvÈGïró-3Þ Â#º_ê±XuJ³ÒÔ~éI,ÿžùoÍŠBëm3ó&;0™¬(ﱋGKyŠe=øÝû³*kbsåép~ô¶=¢ \ñ¼;°‘\t'ÿ“?ùA~à®~1‡Šæ¯Nû[ÍD`¼G¸k‰é8ñŸf£‘uágèz„w“ˆe©pÐ8hÖ¡;é){H§Q¸'I86Ø:Þ{Ï»:Guw)¬úÝ­ƒ#»͆¡má=e€SJºž"*&´²ïXþÑû~“2J¨•$¡ôê;µÄ'6‘(ï(ß{Ѧ(-Þ[fzå=Z”ƒòn{ÛŒMXÊ:¤."Té¨\ì•÷*Ãöƒâ¾Ú]ucêß¶Oµv®)îЊ›nx&w³Ë‚‡â_üÁ”…³öÊ{›`›ƒ–Û¬À»†Ô:Nï»]Žg>~´ ¡¨¡Ù—Ï~ºÑ+ïŽÜÀtúדÇ÷ô/¶Üs┨î5“{tߺ=Oÿ¸_xŸ‚ÝEÛöö÷<7Ù5\ýûû ¯ým$‰á©O=üà/òùÚO§ý¢¢‡ÉÛ€/`,îîáÝ…´F”÷6 &2(.îË¥YQd-*w´yÀRg¬™’´Õ¤ôžwQÞMرc–dFÓ|2彎XŸHÿà{ÿ$êû îM¦#ê{p S'b 5±(û=¼ŸMBê,$Ê;ô˜‚ö¶×H„¥»«ºDÑe›bo™”÷B³˜ÊŸ#m˜èƒÊû<}øïÍÃÜu@ 蛤UÊþþ{‹Æ}áßnî¹î¼_÷‹{ÜtÓ>Ea9r$Â9Çþ¾bsSqÏ=å8ó˜¾ùz™˜"™ˆ¦Gd ®À@1¨ÎÖÐx#ªaøY¨x/.àîö‹^#ªûþéîxoH½§ûð•Q+yëìsÿ~÷æ;pò›9i¸ñü½`,TÅ+ƒ^yÏ»5£JÛyÕ}gG6#’tô¼Ï/€)2î;!v™ÕÓÔŽ«ªûζæŽO”D¦B»Û'Í´¬(ï†ü7§8~üc<ç9Ç/Ú}wâäJ¡m¿> øbR}z*Ðc£žÞ~àá}šË{¯œlü´ö ÀÛ6¤hyTݧ“hh rfÕ6ã•÷HŸƒE¸ª¼û¯W^™Ð¶Ž ~  %UF)áß¾õÁÁÏ>þEÕñõïmP«ˆÊQö–™ni „.64FþŸÞ2S´)ZY¾îúßç7ßð¬àQí²öžwMÂÁ6“†Ë¥(ïªtç(ï;›}Æ»ÄDªZ’fÖ§cÆÏÿø—_s?ªû ,lÔP5üÉ¿ü‡8)g˜ãP¼ê‹¿‡¢%àG~ïytM†mÎ·ÌØV£*'u#ñ¼ï oøÐW ðêûÉ}ùìûÔ£\Ëù×q|Ç oz±½-`þ1?Vô©½5¦Ÿü"Ñ>ª^}_)%š]ÿîâ';çá]±>Šmfcm‡º¶>œqæL͇>t†«¯ž?Hyqeöí«:Oùëë›b%­u¬­ÅEËÎn¯¼gÜö±½Üब*p½e&®X¡‹†g>ó¼éMЧ>u÷‚ß{Q8ÚfPï_TùX­¨íý×}Æ}òR~&ðI?)Úý×VA¹è —»q…à³@ A)0ÿ.°¿$Ÿã§s¼â5o|c˵¯ùºRLúN)^qê…,LNeãÚ•sèÆ¢CK­#*–™ªF”xXš(xÇR´)¥JÞU;zÞmÊ¡Ðpf©é–Jš7­ILd¤QHW‡Ôe„-%F²ï®º½)€že¶%Õ7­uc-ÂEÌW7üâo½‚”C‡!¤!ò”BüümP4)m°$ãißð&¬ÒüÞ«¿t°ÌØV×ït|Á‰Šô…ž³¹Wؽê^bŸ ̨ȇ Êû_Þ ß±¶²¸\É( BéuVë=¼•à§ÓgWÀÞÁt[ÆÑ8tHƇ<—`€ùܰ¹¾3À{]wlm%$ɧ.à_üø„¼÷^šÖÐÕÐöW¦ÞåWˆÝÊfz€÷Þ6Óå†Å½RŒYÇÒI5ΫÁ6Sw‘WÝǤ™e—Q Ó "3šÌhîô¶)lÕƒß}=w{f‰4ˆ;wíŽkÊ©À{ö‰ƒÃ@퇌^‡I:¯¾§£m&6îmQÆ u®©³;1¸‰FO,zM²\dƒò^hiÐdËqmˆæL{å=fáU÷4Ô¸ðþ0*ï_ÀÍÌØgÊ3Î’PÊbºQòf`K-ðîw^ÔÏûîKà~Iu¿Àðþ¹ îï}ï)šÆräHÆÎNú×z-[Ϧ5³8!Ž=¸kï@ÂÉà ò>;,“èdÅón š jK»<ï³pœp K#}ƒÊñú·{ÕÝÁr¿à=è:겫PÚqø‘‡¶ÖRÍÉæÛŒ·ÌLg°½[pê´L‘…º>ïÏýø‹k½Ò»b·È‹9Þ&ƒWÿ)<÷\Ü{3òŠ{LÅ'ÙcJC(¯á´B-®VïËqGSýp?ö·B/ûÃïŸËà~ûí >ðÓÜtÓ=¼å-wóÑîsûí5IÇ I“$ ynx÷»ŸöÿõH‡¿9"Çà¾í ¡¨/ê`Ö`º–?C ìžx3c8‡“þ>g"èNŒê{_¸™÷~÷@LLcÇ©{-´b›I§ši¤dµ£êî&=ý.ê?þÌlÓðœìVá½¥®$"òðU¢¸Þ j÷ ‘\ð®”Ñ>ËÚ·Ö!3P(H½ú^ŸkQç[fzxŸ§¢´8³RÔ”Þï¾Ú•tsSº’FÁLvå•k:”à^-zTMŸ%ŠfÁ&OxâǤhµ®ëèMºëë3Ò4äŽ;e9¶ ÝÝxò“߯Ÿÿùõàw•±Ë#+ïÓdØ]ùþ¿Ž»%SŸ¯Ÿ®Zfœxç9×6ã4Ó„i ÈVl3ŸîÒù°<õ1èÎòË?A _û‘yé±—1 ÏÊzS9Q×qéiSàœ¢‹ µŠp¾ TÓ„ÔDCœ¤JœDõ-Š6¥Rñ ¼J¬3 ÉB=øÝ%eFl3iF£m¦+\Ke­«öö­¹·ÎÕh™éïësm3…Ké”À½WÝ[BB,šF…MJQ§Ô]ÄRg>á^ο÷OoâýæÑTmŒ¡£Ã`µ¦zu ¥"ü²…xŸ#o›ñê{;“D’¾Û/Ng.õ]ý&îpØß‹oÇ…é.¸Î{ó ÷ ¦;coˆ¸õÖィ± ïÊ÷ŽøLSÿiƒu?®¸Bõ©I ôØ>a[Ì}R¨YØ”(­i±‘¦Íš,d¹Õ}I†Môà{ò–F‡tûæ<¿û²‡w£ÛLÝ¥4^yOÐØÕÝÚƒð¾j›©ŸSN¡k = ‹•¾]K'ï]ï¦ø}ˆî…fG£Pƒé4Ë@š.54Yˆ›\nГ=:ÿzß]µN¤A“K[T$}L¤üj±°òý‘Ux×£òoù»¼‡¸‹ÃÜÉYf4„´´Ð@‡€/ÕX—Ñ÷3ù[¢º_÷‡Iyÿ›¯®ŸáÏþì×\3ãéOßñ7Iˇ>t†{ï-iËd²µ³µ•‘$#¸+eh[Çw~ç{øÿñÚO¢ùîÚI;PéÉŽz•Á=ßÿÌuÌj¨kº>•|tò”ÿ¢ËÀZ†¢töÊ{º1ª_™W݃@ša8¯šZtÐZ0Žé†l34#¼‡Øšf3ïï½î«–™ k%.²h™oGÚ¯û¡í½S Ö²……°|:ÜÀµ"FôàlÙÊ~®þú7üåwª»u…ïÙ9ª»ÚLTÄÕ®¤[0Ÿ] ¨Ð-¸ç’•ÅoÈÕWßAUY¢(âØ±xˆšÔZñö›+îºëŸòÜ'ÅÆFG„aÈw(ööò\qèPÄáÃÿú_ßÊOýÔ…]X«ŸõovŸÍ¾º¾Ì­K}ôË?•Ë_1N–çÂ{‹•Ô!7úݧ"®3d÷èÁm k³£L[_Y©Dþ»ñª¯…‰$ÆÜ½¿ËÒd”vEy·Õ:œSØ@Ó¡(Õ­XfjaDm,6ÒmJÑJ÷ÊÞóÞ[gòРªs2ÞmŒÑ!i@Ê{WšÁ6³½u°3îæº®Yt>¼÷Šè÷î½Ät¡¹_Õ½·Îô _6¢¼MÊ2áI±À¨gÎ(´±tÊH3«JÆ•Y,çtÅónæâ‹žúñÈ6ø¾wõ«Àåþ~\Öý£sxäS¹®®`[ì­ÀûQßÂßo•o:5]ïí„âØ½¡¡ü½‡Þ-OEu·•¦µ5N9 .ÕÓ®>\‡ÿNîøŠ#ØXKÁt¬å½Þå]ÇV|ïIŒÊe‘`÷µWÓ5E7*ïu{ËŒÂÚX¢"»„Ä+ïg‰ˆì£WA,„çÚf‚¨»Ì­Ðöb pÒŠÀ’¡hSôýÀó}–2˜÷ð¾,3–AFG´Ôù¨¼kïy¯Mt^Ldï±k‰Ï{¯¼W˘e‡Fî×sb"s$9ùbZgS¿ŸÝè ;ÜÃÕ|ˆûØÀÝ¢i©“ˆºŠ W*TápK54$ ¿š_øÜ÷K>÷‡Þ?T÷;ï,xï{ÏðÞ÷žå×ýc|ó7/˜ÏC^ùÊ/àškÖ¼ýVF¬Ë/—–÷qß¶Ð4–ííˆ×¾ön¸áȃŸh¾¾ƒ #ð\X™­;{b-ê'5¼Ò¬¤"}­üœ õó×äë“"™`Î`0ÛÕ¯d%i¦ežÆÀ²ß»qÌÂhP˜l'à^†R'¹ùÀûÙõf¥ßz-TEw܃®%¨÷×fðQ‡¾ÚÛf‚Lõ—ùvÙüÁ-ð5— !QpÏ +™ñƒê®@Ãlà %½ç= %fpµ¨±_XĽeÆÃ{×ÁúÚ‚ŠÐªÀU(µ÷Š+Zê:äÈ‘Ž$1D‘àÝ9Åbñ$àÏXÙY_OX_ïØØH ‚à5‡G>søpÄÿüŸ÷ò•_¹ua®ÿ=¸÷yoœïÊÏ€êü³ù>˜üáŠm±ÌômÕ²ÅéV²þ#ô Èi ˆW”÷õOútÛéÏã¨>-”ÀÊõ`Írž±09 “€÷ jÑÎâœÂ9‰„ì0¢Š·1 áHI§%efÙf´:8Oyß 5¶ÐcÆ»K(\Â,¿»­½ç½ˆhÊÐÛf¼eÆß‡ÎÉîOjò•ä¤UÛŒRð­'~™ØÄh#˜:m°èAÕ;×:ÓPÔ©|Ò†% ÖiÒåº%´¼;ã +k`Á º÷¶¼ÞóžÎ= ûñ¨é¤`usª¹þúó¶·]yqÀý?!™è½‡ÝWJƶ"™—¤ßQ˜’É_<‚Æ'K-|}† ä5LBYT¦Nyå}ºëEplvúP{~k—¨¦mZ—¥ˆ·Ê5Û\òÏ]:ÞºBÂPD)6Ñ4a1¢¼†iδ 'Ž«Ay7AGwÚ Ê{ŠâŒÍ)ºŒe—Šûh™ém3ây?Ó¬OÆû D¡ž%2¯ìÿSô’»`û58pk#6·Ù% ñ1à“VîÝ6‘¤PÁ©6ci2ê4¦Ë]`'f(ZmU(ž÷å½ÊÞÓH,3±3(²hÇ´™EšHÉékŸzå=¹ˆÊûÑ7ÝÁ±§íñtþ˜”‚=¦ÔD¤ÃóØa(§ î^±Îô¾÷®0°”z€Éçxý§÷sÿý’ÿÀûg+¸wãæ›ïæ/ÿònÒ4`m-a}=æIO:BpN EYv|üãK¬uìî&ìïO˜ÍBÚÖò›¿ùqn¸á8×\#ô¶¶3SÄqB„C—Ñ(Ò>œp×]‡ÅŸz¢ùâ 6C(ü ÝöðŽŽw bߤáòHbm'òK£|Ô„í Þüw€/„ù÷™ã„3 åÁï•wkf$ÎQ.;‚¨Wé³Hzæ,5؉\ÖÖüÁÕ+V$qŸó„7Ã\sÜm9ùÂ/䃡僓<êÎ2™¤ƒm&l`ÿk€JÜ8–¿û¿€r×_†´~¯šQuW€VÌã„ËžÔqæf3OžŸF¢<ïÇñŹ'ÃÌV©½zî†eÃÉ“—]²»«™NwMÈÖ¼s þðò¼olÌY_·\~yH†„a ïY¨p?rD¾ž>ݲ¶öÐ6ÓÔ·­€{·rùjEeW+0Fw¢|¾õKáñ÷TޕÇþ~#ï‘ÓL·ßdKašQyW9L¿ä.ö~ÿí[ï:{Gõié”Ú_ËJÈ´¾×2ùø>¹ê –A&j··Ì$M‰rn€w ä6MHÕÄ´*@cE}W–®1ƒòÞ)3€ûÔT<ï9¿ÁŸ|øy¸BÊ»oδ»âw·uH[E”eLåb‚n´Ìôö­u±Îæ ên¬é¯{<\÷ú"¤àÖXÚø °÷J|CH@+ÛôG ¸E”÷Ö,ȱhÒŽt…ÂØQy·F ÀûZ”Ù9Ê{B;}TdU‹ò~ùåá Ü^Phÿí[ 5½Ï]×c;‚ ÅLàöëoçdµÁλSL!=Ц;~¬ ¤¾5ñ½7£efuè¡üãGq,YÐ,%î1ûKh@5þ9Ó ¯¼çø¤#ð”I"О@›4wKÍÂQÞ‰²ÞÕÒ¡ K·¯+̪ç½÷º‹e&rÞ¯ý¹ˆ»¿»; ºEÒ¹ü‘%M'ÂÐì£ð'”¾( ±†Ø«ïCT½ófq­TŠ&eiDyoÓ›Y\®åœhÔŠûRmÜÅÍÍßxﻫ¦ŠÍ &b"Eu_6™(ïaΡx¼gWýî䃽Êû·òËÜð´³Ì8Ë„}ö˜²$£"¦ ¥$¡!Ä¡Ä å¤ŽÆ>)i)u]óL®yóz¸ïm—ì2—`þ3€÷ÏfÅýC:Å-·œâ–[NsóÍwsâDÁ“žt„Ó§+¾ê«®:ÐÙ/I W^9%çÇŽ¥4es3æÞ{+66"®¹fG±ªñ–™¡ÑM,“k¹è˜N‚akx**-ŪÆÜ[sMpÕŸÐþÕSøµýÛs@¯Oz°ðÅoŽyUzŠÐul¬iîø'O€Pvtì˜)¿µ ¯áÔSäÿP}ì\äãÄ<ؿ㯜€{yÞƒX3K`z]Ã,5ƒònæÔ‹õ=Ž]6å¶68Uyõ}$àÍÍC‡BÒ¬­)âX^)÷,K¸å–«¹í¶÷{Õݰ¾nÙØè8~<ðð²½Ó4n€wù?tpÿGç|žöœ°ç(Û=´ÆÊ4üâ¼lÞÃUx_ô œÑ23 ľ•z¿l2ÍÙ/"ÿwõ$6)ilH¡S´¶®:ðbÇkýü÷¾›kË÷ðÚGÞ0(ï}V½sJ&Q¥èQÝ«6¦Ã U mˆئX¥ËÌNÐÒ¶b›q…¢õI3ÛL ¼wu8|UÆt&:Ü;+¶™Àï"hí þÏÿøëáÊ×ÝHS‡X¥ÑÆ¢‹1]0ÚgzuÏÐÐŽê»·Í”MÂ2Ìê ·li‹Óv´;£ˆr…­%Õê]ߖ󅪘EjÈyWsxVbVû‚Õ\;ñˆˆ¶u¼ìe'xéK·/ÜC¶ÒûaHÚò1'¦pâ–d½¤iBºÎš‚“ßÕ’}Ç”½½Ñ23 % 3u¢ ÷öŸÙŠêþPù.OØF¾¤!ÌyFú禑_¢Bw—ª{Ù&i˳ÞñFÞøåÏÂ¥ •:QÞ—†E ¶™0nƬ÷=w»o¼f%mÆælEcÒLݦÀOBG‚ýî+;>«ü§¾oƒyØÒÆpËŸu¾-b‹‹ $ÕíÛ‡‡õ1Rn¢ Kh`¯p_š —*\Ö‰êî•÷ÆEeÊY3cÑ®ØfR)XMMKâ-3‹&sÞ—†pà àÞ[grÆœ÷ðÃûKù WÑÏ\A* ,rj"JJ*â!ºµXO¥ÑÔÝW*t)»Åó¦Ò+.Ùe.ÁúC´Í|6ÎAhÒ4`:8uªäÖ[Oóû¿Æh¾â+Þù[[±íƒé4 iÜÕ{ìXÆÑ£ÓéùoIÛºà^×îA’ú¼{á²–ãG¶¸ócEÓ+ï=ÀovUÌæ†³Ëf„öþÄŒFíÞ{Å3ð TïÌÐðÃ}×À~rÞ{Ïê‰EÇ4 Ī*fáèwO'ò³ûsý)Õwõý~$ì }eM-¬M5GF¼Â]U!rS耟Mc&¡DÝzøÆ7Ф‘Gèá=Π¸£…Êÿ"íU÷yÌ,qCA•RŸ^JÉC=¦ó[Yߘqü²)Ð1›tœ9ÓúT{Õ `sÓ±½­9tH±µåËLn[[ W]•pÛm}¡jÎÆFÇúzÇö6„a@šÆ4MDÓ8Ö×޽÷ý¡m%ì~³tG캕ÏpU9=Wu×+÷`ìû¿Ô¿ñ‘6”ç57–+Ê{8Â{ë“fzõosöÉW_¿kŸÍZç°f©2‰µÔ–‰ÚGi7tˆqZTdjTëøú÷¾ŽWþs1U‡n¼e5¨ïmP51UcÑCIg :êVŠ>—mƒòžš%M†ºpCÆ{›‡DAH†¾X5¾,æ[ð¬WÁÛ_‚ûü~”÷H/ mæGx)Á€ãÒ9µq!K2–* ‹{ëLIBM%t¢J¥i•’LýÖùü9ï—b!&xÿl÷¹?úÑXë†í«¯^£(:.¿|†RpÛmg¹üòƒˆ;; ÎÁ‘#é`ƒiËînr¿àŠ 0ŸVÚ€Úü8kÙÚÊXÏ ÷Ú†¢·Ít^¹Ž6`_´ a}¢8{_;B»ëò•w·IxŒ÷>ªoÕ\IÔ¢;GygÑypï·ºJC»’0PÌÕ­ªçu¾*vÅ.ÑÞ ¼?çÝ;pëXo ­¥P±s^y·Ì¢˜Ià»Ã?’…@¿EFÒ`ª‡÷TýmÆÙÁ÷>Kbæ±§;Mû޵‡åþKÓ7³¾1åøñëë!§NuL§gÎP58±ÎlnN=¼+vwîXfúóª«n¹e»îºo÷ Qßçó|XDâðá˜#Gâ»LŸÉ1‰Å qv´œX0Úsà½o¥ØƒûÄ[Vá^ÁOàÅgFÈ5à•÷,‹˜ Ê»,uR<·¤¼w¡ë •Óª¥FwÕ‘™%ÎŽÐn;µÝZ\«ø¦·ÿ fÙñšçˆâîVà½]w­¿ûvPrz‘ ¶•¸¡`5 /X­NZº>m&‹Y÷)3i°WŒÊ{×DÌS¹gûXW .òÕ¯† ¨ë­-„PÝ­Ò¨ÀÑFÁï½efU}OWÖ™eœ1]´¸EKWBWK'Úà'F6÷£ufêŸ59t騼¯yåÝzËLïiªÙÙyèÑ£^ôIT÷Ü‹–d^n$ß¿†ÎÈ=ÒY÷NÖ“Їþ½"­ý¯@ý¡CŸþÃõ§·?•¹Õ\ñ/>"φZyŽzõ=‘_âð™t4î¬xÚunIã‚2N²“wÔw‚¥a9ËYªŒ*ŽÕ=Óš{— º°¼ð±¯ å+)m&Ê{—K¹QƒuæäàyO˜„’³¤”dp?Ãÿ+”^J´îÚƒ{AÜA\xxwPå&R'ùípW£ò¥:ÓÑY9 IDAT¸ CÚÌòL6(ïË6”w›h6‚–,ЃçýT“°l2îüÁ”E°“¨Qu?ÞL3ÿ:âñ¼Ø›`|¤¯ÂÒúë îÞݾOZtPÕ¨:bÃLIªÏ<•"ÛùðœçÃk^õ¹œ—Àýa€÷Ïp¿÷Þ‚²l™Ïc¦ÓûÏ×}ìc7qα½Q–Ãg­ãòËgçû 2î&횟ýì{ùÝß; Ç:™ã²#DÖY+£¯XƒH¶ñÐþDNÓ€ú¯Äè ðÞBmF¤%Ÿá¼‰Ð’Pô¹ÆÅL½…e¶=Â{¯¼;Ê÷~û{JÁ‘žŒð^Ï5›sMÓXÂPŸc­¨d–3ã""_óIêØk‘Y½Z¼«f°ÌZ¹†@2뫪\nȾ8.ô–™ÈOUb™©¹P Ú(f±¢Ìæ1žÿÝï^ð;¿sôG§ùÄ'*.;°±à>_ èÚ‚Ù´#K-Ë…JâX±¹éØØå]ÔwM––™®عꪘ«®Š±V³±áØØ°¬¯ ÄO&!M ðÞ[gòÜ<¤×õ´ËGZ„R#Ý,V`}uAÆ ˜G+ðÞwø]ô3ùøs©OüàÝ8IœQÓù¨ºÏžWÞ£\>Þ™bò¨?eÿØÅ=—µÎP ö•¾ó©ÑÝË®C‹µz8±H÷ÐVÒSLÜñœú5 áWÜ7aÑ#¼{ÛŒ‹ÔàwOƒz(V-š­,jÙ4µMiœtW½o)Ê{™z¿{œ>3­ÎÓ¿Þüv˜¯Á˯zIbt‡CPÝ­Ò(ã$%ƈÚÜ—®®Â{çÌéœË†¶”Ø?ëDuO§<®pg³u5DE²b™±½ò æ—‹e¦mo:¼ôfOÓ«ª{;Ú»òË0*ŠÑ÷YTå$…Çxõ]\«8ùr˜¾æ…ÝÁÆTê`¨Ç øð§OyZYþÎóÞ%cd~ ûz—©»¨*‘¯e“Pt©Øl¼ï=Êj¬¡Yš…aá ë$:¬¦ZQ1ªxýîð“²ÕŒ÷.¡i²@cºOžMøkJqÏÊšÃùïû)©ÍÀÄÞ6‰ò·v2DƒË¼ÃNM³¬3–zxRйÆåb •ál)¶™ÿõögÊ¢™”Ò$¸D‘–,|÷ÄÛfmFUÄb£Œaž¨±`U„÷ä¡ñ÷£$ Ýï ÇÂæÒ´Íྠ—Rª."ÜoDx[X(+e˜Å†™f(´ØL ^ÿÜQÝ/ûßÛLÓtÜzë)n¾ù.î¼s_¬³˜§<åyÌÁTk¯Ýâ±e€÷¢è˜NÇýš¿ýÛOñ¡’L¬¼åø‘mŽI8uoGh-üÌšN+i]+–‚¸û«CL¹F÷ówÊ;>Ôý b+ýÈ[ #›8 ì; öÊh ”ðo…Ÿ<*ï³XT±µ©ö“”Øf:Ͱ]ÚYè¼m&Îÿ3/úžkyÎs®æqÛB=s!áéÀ}¶) }Š{ÆîÃÕXÙw¯êÞ½e&‹Í°_zõ½ $…`êÕ’0ôª{äS jgO{{‘†Ùf4´ïž¥÷ßÂûBwÜQsÓMgY.-GÆ„¡¢mÓiÈú†œŽŽÙT”÷Ù´c¹/3vî››Ž­-ÅÎŽfwW3Ÿ›ª{×)®º*áºëÖyä#'h­8~|ÂÑ£)‡…ln éYë<À;&“‡îÏù÷0M¡.Æø¿ÓgîÞû{ë[€ÿ.÷× ºóªû¹ð® ÍïÞEy_õ»OEçf­_ßmÎ4›3ÍOÿô'øþï?À¿Û‰¡¶(hU€Sj„w¬£†%5ƒê®Z锨–¤)å†ò]c¿©ú¸þËîóØkÒAy'fð»§Á‚ºM€U÷šÖ%´6eêÓfÚ¥¦j£1ß= HÃQu·uÄ|Π¼?ÐѶðèk3®{LÍW:Åß¿é-ÝÑi#ª»y«=¼’>Ó[fZBÉ~w )jQÞi ±0-ºZÑú®Öh&kMºD«ïþpÄ_<Ã’…­Xf¬•ίë3XÏGÕ]NØÝ}h÷è?ø>åð~èmP|,¥ŠbTä˻ШÊÉ®K¨é´¡söìá­Z²ƒÐ«îÛ[>¯><˜4³1UÌ3xîs^ýê7§¼¡øržým.ÏÈ„1Zuul åýpTß ¡(RÊ.!Í )Fc¹˜ÊÒ, Ë.ŠU{å½¥3jY$è¥eIvžß}@j4™VdZû˜È”i$šÊý¿¥§‹Oƒ•Ç{Ór"Ÿëîá=ê YBã=ìjâ`ÒárM‹J¾ ¤éR%˜¬%ȼˆ”b E•RT©XfQ¬ûM©©HWÞW VŸû®Cü·§Ü³âwWçÙf.”Õ])'‹~Ôð} ÐÒeØ|:?ïjßa÷ú\wßœ©ª™­§ï~Á1 d|èÖþæƒæ¥Xȇ Þ?T÷[o=Í_ýÕ)ðwóÞ÷ÞËŸx˜²l1FqÍ5›ç€í_)øâ?…ý{JîüŽéîª% YÝöÉl{ŪúÀcÖ ´"‹í¼«tØŽ-ûÖƒUå ‘«WÞ7gŠyEm3.XâÁj±Í\qYÊÿñí£$½§ò{ü¨æ;îi ¶ä`¤`ÛBÕÉꢭÅFâ=ïÓ­ŒY¤FÛŒWà£UÛLà‹Uc)°N|Šg«fè;K¢Qu÷g¶~ËS‡.Øç[×–ûîk8r$,Zó¹dþGQàá=àÔÉܧӎS'UµÉwìñ”§¼onZ¶·ÛÛšÍMu¼‹×u>ÿ<–ˆ¢h™N#®¸b>€;€ÖŠ8V$1gšú¦_!^}_:¨—ç¨îøNÄ$ü¬ƒ€ÞÇ ²X|¿ L¼àvøåËWà}Ù µ=Þk ËÇûðìL±1S¼õ­·û¸\|é •Ó¨p°Ìh-‘ŽªõqF";;kpV¡[‹*É©rlù˜|_÷ž×ðÊCß5À{ï_ÍtC¨ï¥K0ª¿{°Oã•w)Xí|LdLâ¡}µASWELS¯>€ò~·;DÜUD¶&´-Ê9JPW*…ýåOøB×ò}ÿ™Þµ±¸P `È÷JÑvR´ª]@WxËL!ýºLÓQ›hÈê_zÿò²Wß#ȰñîÖÂl"Rúñ½¿yûA»ÌÑ—ßN³±­Æs¨£ Z`îëè]Z÷Ð`C-ZÈ*¼¯¨î©ƒíM)^-XÕ]žË4}ðêû³¿è òLÄŒù„çÌ´.Vb™É”DËú…p…4ö*º”<[Ðd!e’àb…:ÓR/ Ë%mfµ»ªV”Ë„jã*Å2ÈF¿{—K®»cL›é VÛ„iA{~4Ð*ÅÙPÏøÄ«î]æá½ñÖ;|51t¹!˜XÜÜD ¼/2–¡n•Å„iƒÍ Î-nbˆïy/¥µhǤ™IØ‘òb+ ¿håç¶ºŽ­ 5x݇Æb+ð~!Žà§Wšœõº{ïs—ÝŽŒe'; =¼C€ÛkFx/ì;TU3KRfjTÞçNæ3µ¯{=|ýW]²Ë\:Þ?[|îGN¹çž'N,¹ï¾‚3gjþèî`¹´(¥ÐZsõÕBéaøF¶¶ÖØÙ QêÏpî)ëµn~BËö­/,%-ü?Lr ,’˘ިƒNw¯*7 ®<"Šºöðˆ]†Ö‘Ïr?Ÿ8%ΚjÉØŸº’ïŸùËðß³xL€è:ÙÊî'ªUËŒuÒõns®yÊSSUA ùüBïs׉43šOål*J_ØÆŠúFPïyå½ZQÞ³(â-{ÛL—yõ˸A0úÝmØÃ»âcU#bWUŠæ©bž*fÉ…­V")¼uNÀ]kEÓˆ²èœb}#`6h›‚Ù¤c:éØÞÒìuÜuW ^ûÚ%p’7¾ñúÁ:£µ¼ÆÕãñß¶é:GQ4,—-;;'ð÷e¿!ðÞ5°ìïD²F»÷Þp·ÜK®‚»òÿ~.¼+˜®IçÛÔÊK_°ÔùT¯øÝ¥xzéÆÄ#ka¦Øœ)ÞúÖOðº×íò¶g½–Í™|î­ Zf¬•kñïiÖb™é`ó¶ûhŠÂ¦$a‰‰;«@®µÃ°(réžêm3½g3°ƒ7xÙf*p×µøÝxÞ³ÐàŠ>&2akPÝû¨H±ÍlLa’~råý#\IbÅÆ£œÃØŽZK£õÿñŒ¯á}áci†Üè°jø¡c?ÁËî|):ðj¼R¸`|¤UãBŽ=î|⎠N-¼ê¾T´¼mùll´u¶ûÃÒ¾ëSÅt¶²Ø÷êûô"eRôf¸ý½ÀlÿÞ Ób «¶xw­aK·0Ø…$wôÊ» µÀôžƒ³býéU÷±üØÜG^úÚ ”ƒVÃ~õW;¾á>Éâä‹|Ô__£n¼ê>Ywÿq,Êœ8¯0ÓN~I¿ƒBY%”œM ¼Ç $`Á" q oÅhbiö“iM±ŸHƒ¦JS)©Óœ´ …¿»…!ãQ· ¸HR‚Úñ¥|B)îB^ŽõÀ¹-¯­Ëåý‰Joé»ÖÚ;Q؉ÁåÝé&^yïýîHwÕ*p™#œ4„ʺ€e• éH…ÕºN"² " 4!±3DnlÐt¤íØÙ9˜4ÓÇ›fhiù-ÍÿËNȰ¸ïãd{‹Ìî.ûÌŠmf‡š½}…ÛW2^–Jv"«Væ05Ú®yÿ{°.ñ±SõY—ÀýÁûgSêlqÝu»~‚p$IÌl6áýï?ÃË_þ>>ö±šŸû¹±½½Æc³ÆÖÖ”»î*¹óÎ¥Þ€sÏ~X®óï\Joë>*±‡wíG¿†ƒyZ­lGg¬(ïÞ:c€ä믠üHDdÿÿÑ@Û€÷éfH¦<¸ûçÛ|WÎO"£ú>‹ \)$ÛÝ ØœrßUu5O:B󨫧\q<£,;^øãǤç¹ÑÄ9̦#¸Ï§pßÝïì­l ÷#}ÕŒ¶ÄónÏý¹Ê»šŠm¦WÞ‡÷ØŽÙÃk9è¦ÅV Óµpèü·ª¾=¢yò“ïåÏÿ|ë‚}Îá3:™˜Þ›Æ1›…X'Šû|nÙÝ•¸Ê“'­‡÷‘‚Ÿõ¬·²X<ý)b,QL&“ItQîÛ_úw€¦€¥WÝËnùw0ù6Ø_¬€»òŸoy¸kH({ÛŒá~xxw£u&׎ܸŠû,PL´b雄õ›ÂÛfÞzjÁ¯üÊ-<úk¥Ð­÷UˌƞßR<€£¿ºˆ¤ŒŽ°­¼ñiT +d¢`QåÒé±I(š„ÊÆ+~÷’¦•H½¢M)UB [6‚V¼Ã6¦u ¯¼ý-æâwwñàuO£€HtÞ6³>õúþàý-|![Vl3Ô.Â*IŽ©TŒSŠ’dè ÚÐVK•ñEGÿpÌ¥Çb\Ç«§Ê E m01prÑú˜HI½hkE×(ÖÖ}WJ#ª{ÒûÞ÷a{[=äâè{üÄká·_ÖýhC [¬ÖØJK§ÒRã vÄc*ìˆò^ØÜu¦±ûvPÞ×|Fæk,v6Ç´Ÿõô¶Ö¡› ¼lm}’þl5Æ«Ö~¼ßòÒtïáïûÝ•:’i)Þwo™q¢T¢º×.¢ÉÞ«8&XÖâw_w7f¼×qä•÷˜ªˆiªÐ+ïšbÅïn<-3M—0d\ÕµcòU7³ÿú¿Kµâ ['4£ËG¦¹Lrl&ðh‰ˆŒÕý,)nÒ`'Z¶š§’6S& K2Š@À¶Š"Â4Fåv°Ìì/¥Xuéõ’DüâiLjRï Züî>*2j;vwC¶¶8à/„£òË—oàó²}éL ’Dåc! ÒÞÝŠòÞI“¸MPÕØ=%Êû\©aߢÊF®S3$ÎÌød6ÿ†ZgÈç~鸶™Ï–cm-æqÛ! ³Ù„ÙlÂtšñ¾÷â×~í#Ú'loO˜Ï3ªª`mÍqútƒR¯*^ò’Çrà WpíµçŽþÿì½y´-çYŸù|CÍ{8ó¯î•eKž-Ï&¦08i M!Y ‹!镺:‡N€„!M‡¤ ½˜â IèLšÁØ lËX‘±D,ËHº’î|Îj×øõïWU{K¶%˲-íµŠ+4\ŸsOíÚOýêyïSsGù^a<°ÙzúÞ¬Áû.ðˆºný¶7µ©ÍÔZx7u°Ê+¸á¹‚š\éá½Óf“@õðÞ³ ¼ZxÈò*Í-~ó¯Ú ukËpp`I-¤vlm[ˆ­êS÷çÝZ“’K°mQá&¸O'pøqÑfXOÞƒÞkñô›ÁyŸŒÃ~[c¶æ»GIsº‹­1âPÖzmaH*éûÕÊIôÐ>Y‡¡ÓæqáøI=aÙ h[886à=Š,W¯6loCQXœƒ²¬ÙÞn™LŽŽŠ5÷Äð'þÄû¹í¶—^ß[ãd8+Ÿ¼‡ð+ÈKæÿØI¸nýcÞMpíˆ µòZü³0•¹ŽØ Àÿé¿öçÜ3Ãc”™”¡"²ûY>yÕ«öÙý©‡$_Óeje¥"Rµ¢Ë<ÊÛ=wù>&£Ò•(Mè«øä!w卨á”ê?`¿Áþ ~¤~¥ {N¬¡¬“^›)Tä+"sk¸ÖÆ^Iúä½"eæQ¾{l á’ÈŸ· üû÷ß}üþ,Ï&§qfXä¢BU©‚’Š€Ýæ ˜cðUESrp&¸Ÿ{õôm陼Dÿ•;ô­À+MÕŒ ¨ÎwÏåéK§Ît©ûÈ®Á»OÞ?Wà>næ4_cPÎôCÉ­Ò´K $uϵ4 YMkJ74Ëf)[*;ef4ë3'Ê×Ìñá?¬-b2kð¾ëá=ZKÝ»co~Øm¶Ï|µTÅC 4ÀEÿqÓÁ»¿w(‹Œ(-ˆ'« ί&䑸î•p/ÓU][P- åR4-ý’&×XcI´f¶ŒE)#–AJ‚bÙfÔNª ['7e¢ÌHMdï*Ÿ÷¥zpwk©{³öñÖzp7‰R–ù§¤JŠB mPê3’TF Æ F É{à“÷8¢H+”ïy+Ãl™¯äfyYù%G.Á…©•žúK„j"ëŒñΔ?slÉþ~»ñTvòd /½~Ï×WzU¦øÛÃû ¹1YèlxbÐ$,LÆIV˜BÀ½kÜ\á wв‡÷^› Þ3䦲ªåÉô¸:[TŸIáŸ$¼?]k!··c^øÂ=Œ1(¥.cKQ4ŒÇ{{cööÆä¹ no;®_ï €KÞúÖ?ä­o]§èq¥îrœ{þ“÷_jd³Ge¤­c³n/÷ݵ"tƒª£G%ï^i4h¿ æè5/¤¾·{ÔZA[mÀ»q?H9%–Êå™ÛÐf(¡UÜpà̈«­6Z ºnt£!Y&£ gÏ^âü³âƒäXÀb%­ëÊŒ.ÁJÞõ¼'på:´þg8&aÔ'ï©WfªD3ŽÔ8^ôÂ)MãØÎl¯Ì$N¶ª®/‡©'Šû÷} XSS!m ‡ä][¾ýÁÈ?=ù7†hÓö²ÅûYjIÛ+#à^<¦"Ir醶ò_Û–¼J¨ЪeÛ$vX%¿¬S*xßÝXÍÅ&xocÚ\Ñ,5q6¤îë š¶ÇòýÅ¡°^Kß§R;ËJÅÔÎÊP¬«i”¬VmŸ¾ç$’¼>y·)yé;°ýM‡ÉY “Än®µ5# fÕ9ïCêžÅCêž4¼Gµ˜oû/…KøìžŸÓüˆ$(méGmåh—šfiÐ ©ülWè­–Í ÚŒZ «c+-JÅÀ­’#h“¡ÁwgKTB³ïÎûÚLßÿî¸û£® >‚hêà«<ÀGƒ2³2FÉ&l ¬./¤¬v}ònCÑf²€ï~à»ùõ&ôÒ`†E’Iú®2’('ñ¨—–1E±,Ò!yo²ÜôC«ï> ü=¯uŒG¹îÝÂn…G×viï>yoRyb(¯ÎÈ]B¨QéµÙœª2·©Í´)U$!&­ ô¼/ ï»— …“ ¥ÛÖ ¼[Mˆ%òÉûÒ§ïÓŽ 88¨88Ð=À?7{åeìAÝC{wfvО“PJò®×’÷6%D‹=Uˆ2ÓÌ5í\C—¼¯Ã{—¼ÇïûÒ:|måùt=÷g¼ø'ïO÷>÷­­ˆ[nÙöÚ‚ãÔ©”¢hüuÄÞÞˆ}lÆö¶Àû… EQùÈc8ÀÚ„ºî¶ a*u‡‡ø/zâÐþ“´Ç>7wñîݯùÚÑÅëZàfì­tM—©‘«0x˜³N™q¥€o]÷ð>…òᳮͭ…¸õ Cç^V0= gÏJjÜ%ïm뻥?Á뻿{Îí·Wœ:cHŽ…$¥’Il¦î‹9˜•}Ïw§Ìt‚9ýÍMË82Í Ì´> î´­!J67þuÉ{j[íkIE§OêZ>p÷÷ÍgýÜ4FaŒÌ¸~­xËåË-[[Ž­­– Jªª³FåøîïþðçÞï}dÐeP¯D—ù»cŸ¬ãŸò´wX<Ä/Bߎð(x - (¡š çúÈ·yÐÞ»(3ð’—lS–-{{Çö¢þ\Ž¥o5Í«^uÀoÆÌŠQDSNT–ïy付ëßtñ'±¦Æè†—~jõNfFÖ’WFÀJ4µlUJ\Õà»®é¥IQÆ‘W µ²hZ[‘XüŠúä½V–©Y‘X-Î{%«u›àò—+’-ö8XVõ¾{ëÄ ž®ÁûOó—9×Ô,u*-1Ü]  *MDA«´<=pŽÜ%EE]Yò2a¤¤Á’#3A¯Z̪¡ÐUôÎ{‹&²#zUâmÆÿØ·§MÝcg;°õY~KM&rÞè¦eb°¦æÐM™-Ǩ¥“佯Ý9ï»ÛRêuçð¼ëDàý¨ñð>Spää†Tm×ÖolO%åŒÕC{ÓÄom©Í• k!E.”’0×Â|&üáÛ y ½³±hÞ‹$‚ɰ¤ Ë<’wôÎ{™†”W,zá·«&^›!CG­Ô?úÕU>4¹8‰2c†¦±¯‹¬*©ˆì45gú¹—s%€ÚÈg“]‰y¹Þ> Þuç¼kÑf ¶µ«2Ö·ÍàÕ=r›É{›Ò&š ©°iM„!Äp-7’÷’Ü%œ²«Þ,±3̪E[CÀÁذ¿ß°¿¯ÙJeëëgúzуwrÓÖ…# "¢ ¢ðÿ7¢"ïYδ0RÑ™+IÞ÷º§<>yW3E³P¸\K]dQ´¯¬¦>}O K¾°ÀòÉÔB~*@ì¿À´™õ×ÎNÄÍ7o‘¦’ºEÃjÕ$1apýº€ûÎlo;~X[À˜'RâØ0Ÿ·,ŠåÒõôqpñò—÷½ï%î?Ü ¸¯ ìu8,´Y,ftÊá_5>ùè’÷z-}ï¼k@˜ÈR£v=yç}làqÈ«ïcÞ×´™‰ãk a¨ÃOCüôOçÌçÒG¾uÌ“AÕÃ9Ä‘o™YÓfV—å"oWkÚÌ:¸ÈD½‡÷tj˜DŠq(ƒc‘x'òá‰óÑ>…¯x,¼o§pãùd¸ÈÅCÏ»]ƒ÷­-Í>PñÒ—~ökCãXqü¸¼ò¼dk˱½Ý²½Ý²³ãxä‘îóp$ÉÿKžn+Æ <ëv¸ã…rî” øK÷y¸pH#P]àÞ4¤I̲KÞ—¸Ç#÷²óöp.?sëùŒ,4+¿ÇÁ‹¾Íðo¿rBY¶”eƒs²Ùøôé”ä<ÖNlÈ×çsãõ9µµ4¡¡) Eñ÷¯|'• X¸ «Ü­®ycù ä:!WÉc’wW+,µ@»òÉ»®ûpa3´mù+oø ~äíoò¾û’$0\Ëã¾*²Q†ãê£ûªÈÊŸ¼Âåš$Ô>uü°jˆq¶OÞC;ô¼ÿÊùïäYÍŠe›bMÝ7ÈXUÓ`døÔ1+x _%Ô…Å” yô_˜“ûäÝÄìTW¹/8×{ïvQòÛa.Éû²¢YÊ奩¤Zod½ïÞð>Ž ÃögÞ›Ö¬*Z m$jÌžºÌj'¦¹`zxo+M[k\àÀV¸¦EC»Ð4s¯ÌŒýHí8<ç½óÞSz·?ÍûÖœí.åTkOØ6ÃŽÕ›é ï®uÚpâuW@'òN/~¢ýÅ"cÅ”iHY̸ÁYE~E¶‰®"IÞ+#Ð^¥¡ÑT¹Á, å²ܑ¶™Ü&dáªß˜š/#Še$¾uö5‘ïC1šëy$KµºkkÅ …슼Ý%Öc§ÐDÈ,R2³/ߦ¸ZÎË\%Ta@”m»µ›É{¢“–" ±iETrtª' IDAT"ç÷bpÞ+ “˜RÚr¬&@¶«>ì“÷®&xo ûûšííÏÜŸ<øø%žË5L6 Õ( ²L«ƒ÷./ˆXèLÒ÷&%QŠGT¼Ïµ V/}ò^m&ïS?´úÙÞ]òùÒe>Ý×§öÿ½À¼}º§îQtÎiÊò¹ìíÅìíÉ;´ªZV+ø+WJ¶·aXSU9ׯπ-”Š9w.ãìÙ”¦å²e±0Ìç†Å¢!ŠbNœh9qâñ¿ý÷éÂÚw%µ ›ëä#äñìº6SÁhm,U¼7z@ºÔ«3I"H»ž¼ ¼O¼jÐ;ï l 0c —×à=Ë|ÝÔ—üî7>õê×~­ôjˆÆ9w¢½@  ßã®ýÀêDûXŸºÛÂß°tÊL6ƒl ú曹ö¡{€’I˜ö¾û$T@A¬yí#ùçJ ‘ÃÀªbÛ°=1¦É0¬º¿£Øžˆ2S×Rï¶¿¯?gçj‹ŠtýzËÞžâäÉ€Å"¥(*ŽŽrò¼ÞHßW«’?þÇßÅ»ßýºÏúצþ0öG ·Þï¼îü£ž‰ `›.y7L¦ åJt€>yW0ö~pîáüpæÏó̯Ÿ È%u[¹ñºõÖmïrÄlo‡ŸäÏÓ—+lYS&!M$ðþ}åw`£šE™±ÐYîݯ-ZÖ’«l#yWàÝ|lW›»EG9 ÑšSÖ²ÐfY¥8«Hì‚Ähâ¾*²jÜrÁ(2Ë™’вêR÷vX9¿5‚}Ó󬺠ª–*Ŷ5ª$yÇ+3è>}¨ˆYÉàlÓÒ÷¾,}õ^™Pªíá½"i0 â^›IQSP¯XÔ4¹¡©V ØãnXÕüîT†l· |Ó߆Ÿü§þM?㶤£]5ŽViñ½)дœÕÈ=Ï{Á¯VRé‚R´™ºKÞã>yïúÜãÆ_ŸŽÌœ GkÊŒ‡÷,ýÄzÂ:¸7?m ºâsîΊö×6àî‚òª·Àêf,l&Iz"G2Î!€å)¹IÈÄUÓ¦X-I)s‹^Ln¥ãÔWDê^›Y-$yÏU"àMŠQö±ÚŒÖ\ô‘Ôýׯ\Ë^ÀÈ÷C®»îó=ƒÙp¼ó¨Þç$ä:¡I OÞ]¦!SèÌqé÷÷‡÷œM ÒŠ ©˜ša-ÚLç¼/iœ©\ 5À>uOòڌ߽Êz=foO®ÃûûOÍ€ÆÞì2ÙþbÐΨ1—a[¢Ø;÷½$ç]'¬ê„åú~ùE!¾»š·´s¹çÞ7ž&§_X@ùxàþÙëg’÷§Ù+~½½mn¾y‹ªrlmÝÁõë·®ýsMHÝÞÅ‹GÜwßUî»ï ÷Ýw•ÕJÇ çÏgœ;—±½­iÈsÃb1Z[NR?Þð}ßw?ßñg>á×¾¹@éçÖ‹k‰»ëvHÞ»š:‡ +}h3yï¤ûä]yeÞɲÓfRùj=ym&Y®d•<‰õ×§0{‰‘•¡¡bæ TL÷äÎ}gü©/d÷Ý×0©Ü£L“ Y–þD1ò!çR÷Ú'î¶ðÚŒÖ ÆrÓîC¶çUä¿’kÂ$üåÞw‡b¹ñÚ b;$ïJ оž¼ßrKFUImãÉ“[©@Çzê^×ò{p ?§çm’(ΟÑ4mßN³ZU\»–ð‘\[ƒwùº>ô¡ ¼éMwð#?rëgÚߊ¸µcb1<‘yÙ÷­%î­OÝm¦ZSfZ&,Í|ò®efìÏ÷ÔÉ¡YÂøô ÍèvhœiS¸á†¡iÙ¹Oí¢žÿÝû¸y9§ÖV6e†·ì|/FÉb¢E“1oFðž-”Q(ÉãZò^×UË#ïuç½"¡xTò®¬c¥b¶l>¨1õ¼«cäï¯{åbÞþ?œå…ï¾—Qb6j"—Kï»wð®Þãz…®ZŠ&Â%ðn+,5!eí 2ÄR³â”};Š[© ‹ª\¿5u¤(m(W³jXE1EaG5GLæíB5íªÆ-*ï0Ùöµzv³i&na§ƒ÷@þú)¿ñý/n[¾f,4©¡Jƒ¾9§;žoïâîÅͲ-·ñsƒR´™ª……ïyŸ·¨t€÷h­ç#lj¯÷»›_CÛò„Ý‹ki¸”¿•]n%àŽUhãÜcPZž"ŽÞ:cñ7²ÜË$$™ä8­X®RV6–ÃWCvÚLNF¹´˜¥¡%cáR–.ë[fR­Q%÷=ïw©»s›ÚLW9åï½úëб$ÉB  vpɉ€ù#lEŸì†Vm:À{Sä±$ï*s´kÚŒiÔ¨pï´™:%IrŠ$$rÆk3Vœ÷UJŽÌ’„ÀlïV ˆÑ,ë”ÆELb¹4íí ÀOÁ×;®qÓxNu, fEBÎ>—z]¦;º¨õ~©Ò~£k×1¿*ðÚÌZò¾hQ¦ lk&‰íÁ}=5ÊÏçòõŒÞòGÞ¿ñ/ðŽw\ÃÍ•+ÏåÊ•‚Ûn»Èí·_¤(n¸aÌ·|ˇØßhßßÏšÒ4æäÉÛxè¡ë8÷ýïù [Mï½÷*÷Ýw•ü[[Ç8w.ë Ð~Îî«• pž<pòdËñã–ßøC¾äKûÉt|Ïrá¡…@ôzòÞZ¹ºÕkÊL´ö×/~CþÕ(–EôÚŒ×Bœç½fX²•Á•Ë®|¹‡÷ñ¶í:‚.y×òسöÉÊÈJ댪§vgô©á½ƒöîØ -•Uع|+q8,eéàýêEi™é´™ØA2 =݃d[þ;=—ãÞ»ßÀÑûûäÝÔLÖV­ûä}IƒAï@»¡ç=¹9ëÝýcÇ"NœˆØÊ;c½ïMãˆ"õ9SM§ÏzÖØ?Žo™Ír®]K¸zuÎÅ‹¹ÿÄ—¯ëè¨àÎ;/ð¯þÕ˜¿øŸÚ§`ê[kYÓ×=Ö)ü=CwÿùRà}kð®KIÞMÝ»îË8TÌ4uÉ;^ñÛ(†æŽÅ‚˜Fþç—øÕàQ)Ò§÷øÝÏÉgüû×ÿÙ~@ìƒÅK$‘V5‹:c®GÌõ¨÷Ý­® ¥h3™×fŒ¤îm#[Ve6á]UT*éwmZ”‘M‰‰-H¬!ÒÆ'ïâàîšÂC½îÁ½v1‰Ò$N¶DZZXúÝ»ó\køáçü窚¢ŽÈ[qém[´’¼7Zzcj,%!!2À©p¤,Y±À{)Þ~§Î$ÊQäJ’÷È'ï…@¡4 ET”«–ÃÀêäøÐαï#éD´¹ÝvžÚp·W°­q®jê‘¥JÚX<CCÊ’Œû_q‰ö”xïMƒ *IÞ ÙÞë-íB3ž ×øq>uWâ›åž¸_ý—»Œ£j¨ñÕòvnkp@Eï w ¼+ Å< ¸§!Eá&Šå¥T|w›HúnlZS¥*°äuF™ìÒ°rƒï^D‘÷ݵøî˘U±ŒºaÐGÁ»óÁ‘Q½2ã¨ÚQzxŸÜ¦•Ï•¹ƒZyow{Í¢5u¦óÞmæ»ß,®gä‘À{IM¤Ëd2J=¼ë´?guÒ$!!¦øY§Í˜”I‘‡ÙMx7}ò>‰å{‘Ï2ÅhôÔœ›[\' Šm®qœ‡Eáy¼wÐ^P7–¦Ò0¯ÉBC¦º]]ŠÃBÑÎm†…OÞãRgvlÿÌÂ/,˜|2žû3¯§9¼ÿÞï­ø·ÿöˆ;î8¢m+žýì çψ‹øžï™r×]×ùÍß¼„Ruí{{ûûÆXšÆ1ÇdYAšÆŒF¿À?ù'/âË¿|—˜ñàƒ3~xÁåË Ž÷sç2NŠûÁ£²¤×fªJS×2ÔxêTĉŠãÇCÊÒm8áûošqö¹#ºÏw©õàÞúÔÝÿÚê®L¤9Ò–¯rðËŠéi¹›îR­.y¯=¸;†ÝÔÉmº­jê¦ÚÐfÆ6íá]»aú¿*7$žWŽ`º; rîŒõãÜ1« €×cÓë20ùÔ}í¸çkjW굪Ö'é®Sf I0uÓ¬N&“@q¨½và“÷ñhØFY¸aS¥²Ã98¶2ð–´rãÚ~IØèpÎ;ÿÇ?Õ'Zωîé7†µZ~]™-æäqÒo:,u(‘µ@J·ÔIᙊ’„Š„…•ÆeeKé_þŸŠ¾ûëÖ”™¤o›9m;ÆP· µ¯ŠÌ =¼ìî êÌÎxs±ÑÿrîvΕ5MmX51š– ­ÚŠª ¤} Úª" *^zöüÎïÄUмJX–)$!®j)WZ’÷B’÷bÑÖŠvîhжîÚf*šB.mëØ#ãWÜ7’´·­;cØÁÏÿ |Õ—=@ÿ´-wU9ª8 M5m"àR2fÆ„#Zä DV´KQf’¤&_V([úæQÚyПƒƒ6ÓµÍ<9xqLj ÐØ°À]Cóà ¯Éhp‰¼·µxmåï7‘ad”fHÞ™Àò~Ÿ2[Ñ]V&&LKª4 A““Q--åÂR¸H´—Ýk3ù"ç=äÜï’wãïÍýgÅØ€êRwûß4B% …ÑeH–ò™t¥… ~9UT °'¬yï‚y­$ï¤R(¸Ò¦äYÂJDZ‘º3Òâã¯)3E¤&Xa 1,ó¸ïyÏ£„i ¡O£û ±~`uåZ§~“¸R°»ûÔ\>'¿:ã|2CÝà8Ńœä!%GLzef]›) iJƒ[Êw·¨É¢¨OÝS|ÛÌL¾+œ‡w¥JTQ0‰Ò^ý£¤Ë<óú„÷‹kÞóžwÝu»ï¾Ê©S™ CnÅŒÇ%?ôC—¹xqαc)gÏZNJzpßÙIúug'&MÞ÷÷áío€$1¼öµû´­£mahÈóš­-÷óç3&Ýÿu­X, ËåÐy>kŽ8~\qüx°îÙ×=Â/š Ê U”PUò\ÑùŠÈZ:×åSyŒê¤›¥ v&Š‹—Ö“wÇÄ/µ W HþB\6CÒ®¥î“'¼ŒF ç4éÔƒ»‚`ô£¶)ŽÁ6¸ììˆ*dí鞤ïÊÊcÀ·³Æ7Ê(‚x­]ÄCúöÒOrñÊ|êÞ|];F£Ïÿ³Å~ôßù‹üîï^dw7æøñ”›nšE TM]—¬VPsË-;Ìç%‹…—.]ç=﹟ÑÈbŒâ¯8ñ=ê+!뮦´bs‰ÑÄ'ñ7¾Á€9€à~é?lÐ2ÙÅ)S~k¢¯Ÿ’÷ÅZò¬¥îc KŸ¼OSùÙþµŸÿÆÇùÚÿŸ’÷Íë14òØœúжÕ,tָǫEõ[»áͺeF5§Õšï¾¤R ¥JD›1YŸ¼³ŠøQÊL×6Ûù¼·•“ªÈLËMÌ ~ÚÁe”Ào7Ïs[ÖØªfÕÄ„u)º™‡wÛú¦%¸^PRQPc%áÃ’ ®Tâ»W ÛVÑ–†"·=¼wG»r¸94 E[+̪¦^TÔ%L²a³ã$òW{ß}"_{`¥}'•Jŧäþ²Ñ¸Võêa£M¿3#\–}®I(}Ú•'þ"ú©nÉ—Þy_ÙV9oPE$×Â`xŠuu‘3ÇÖ¾û´nî«:dyy‹q8C¾x8㡽»O$ªÒÊë3FѦšEQkK‘D”IHIÝsö•ÉCQNª4 FsHB¹ä½÷…ËØY÷Ý—«eLžÇ}ªÝ·Ì¬­@Y(½ïîKC1»€dÑ î(áªÿlŠBémŠ!}‘?KR°‰T¼-ÔuÈ¢ÍXÅâÝ›¬¡Ù~X•DRò^™ RÊH¶«¦Z1ÔDÎrB]Ùp#yWDJôšÞw÷Ÿ# xÛà^ú™Ÿ›ãzÆè‹æœæn⿳bÎhXõ(m¦*¤ÎÔ͘×d»øä]ªM¡`!Þ{;—Ì}òe Ïè2ϼ>¯ðþ;¿3çq÷Ý×HSÇÁf_‘$1ãqÅdR±»Û2ÜpCÈ 7Xö÷Sö÷3’Äö=»«•"M ~æ¡W‚Ÿ ÿ’{?B^úÒÚÖqöì„<¯Y­jNž€×Z÷ÝæM#É{Q¨ü¬UXNœØÚ²ÑeŽï[®Ï TY±!°£†Ô½nÁt*)ršÊQåN[Ú"ÿ»t¾{«|‚‰wÛÂîXsñ»ä½a¼ô½Ø«¨ý—ùÕóE=€Óö¦‰cš(¦ñã;ïýk¬¤9¦S x×­´N,—ïA)I‡R¾‘!öÊÌ>¤;Cšn–¼¯¾ú+3®^•ÁܦݬÜúå­UX«ˆcý´y]¾¼âž{¹çžëÜ}÷u~ÿ÷¯ñàƒ3žóœ¯yÍ>Ó©åã¿ÊÇ?~•3g2n¹e‹íí¤‡÷Å¢¢,î¿ÆoýÖ´Ö¼ìeÇž<¸Õu˜n °wಹÄÈ![ y}fémžøê[%*ú±;~8ZæÍdƒ/¸8\KÞ³ÑvfjPf´‡÷­'xþ§¯y#Sûêµ’°Oܪ&`a2æf´™¼/kr¯¶äµ<º_éX†}òî5t¼[CEL¥Rr<Ê:¼¤-ÜãµMeãtاî±1ypo]D¦»ä=”ûmñc’¼[=œß¯<ü0ûUͪp_512=¼'EN¥ õ]Ò2#c¬RcYð¢?þ!~û?½F|w›rÒÌ–"ÑE+©{Q–ºXÑκä]qõ¯!»ý.šR1ÙéRwÕë}oŠ}òn­@ûNúÔxïê;[Øn%ü(Œ$ç¾/=XÉ÷Rï­¨sKÝXª   nG1 ¤~ôʲ’'F‹°OÞÇ!¾{§3Gª[cxã_‡_ø¿žØ×zé#û¤á4ð¤»ý¨cEw]‡w†Ë'J;¶N þ½oç'^ÿWzufµŠY®|ò>öÉ{ËÓ…8 ®ÉvÕ…aaÓ~AÓ)ÝlÖD.ã~pyiS^yò£ü׋ÏÚ€÷Îy Ìþæ.aXòŽþö¸ûš B¡x×a+ |§Î¸1l¿ò¿ ]ïA Ëëþé×f¢¬ ÊÈdë‚>yïž2‘lWÍ”"t¢ÍÌò”ùRnÀs#­b¡o^Yïx°,«”,Tý“Y¥žšÔ:ú¹’ófÆ+ùÆÌˆYÉVصEL%aïeö;˜yTX4Œ”ì§ZOÞM¡(gÐ.±†|Ñ¢²¢ïz¿ÀúÜŸÑe¾€á}µj¼»þ«UÙ3#NŸÎøgÿìc¼ó—Ȳ”Ñ(c:UìqüxÌdR1™”,—ç¿ö®—sñ¢t±ßöÞ¥tÝ_üsêÇnÐ<ò€@ëßýÕ[àW}â‘M$MœJªxÇŸ¸Äñãa¿¯û}òÜöÛ1»DþØ1»±°àÄWßÏ/žp|ÏrxyŽ**é\ïའ6´™x4@{šB’ÂÕKkÓBþñ„·½TZVj¿ãííúH‘éý¶õÀw« ãýP`Ê*ÆVS Évç.Õ¼?¾¹fg¤ÿwÌ?öuûóLâÍæË¬YìVnPÊ«bYììøÿmßv£ÃÁwGCšnóA›9×LÆ ÛÓ/,©ïþû¼÷½—xï{/òÞ÷^$M-oyË yå+wNžÌ¸ùæ-´VÜtÓ”K—füüÏßËl¶äĉ­[NŸÎ8}:ãÅ/>8‹Šå²bµª‰"˹sS¶¶¢'D_ü lí ûÍ#†ek?ÔÑÌ;`_?”¿*XàoÝÊ]5ÜåàK5¤®ÉVÕnXudpߡgM¸gZÞ­{üö„Å_â&i0iƒ<]i[I»Aöm&[,È«„UKò®¤ÁƒTãd +̠ͯJ´™Š¤OÞ™A½²}ÓÌzò> ÔÆ£û+ÞwÏ|+Râà/¼sÌoþÕœ$Ñ;fÑJ­)CÅ*‚ Š:¢h"¬«©Ú€´ýmý€¦¡á­ü½Ç(3¼G½FÒ ªæUBj+f•¥\…¨•ëS÷‘ù\’÷v®hEX—4Ë®"Òƒûš6S4°3n:Œ–aòñgž¼ÿk £îúé Ïä\õÁA¸pOösêÒR•uå¾ ¨Ký—I.„.yŸkœOÞÇÇ×”™ÚÕNê"g°}ÊOðä2ûh,X¾}Í!Q¢£©n S¨¤i Q÷ÈuaiGš&1´™–¶ß8³\Iê¾ÌSòmÕU§+b´,Z"¶«NÜ‘è¡&òÚ2&_Æâ‰Û”ѶâÌÙ`C›éÞ›Þ0$0?ûöVnÐïM$à„îa ‘o²ê±4õ˜DºÞm‹6“aÕXÚf²lA•¸QiÌ,xg-yO"T¸ê“÷ÕeÀl)ìËZ* ƒG9ï‡÷Y÷¾{—¼Obø­ßz€/ú¢ÓOúüüKæ_’±ð{Ss DGZm$ïÀ× Ûû›iA…e-êk«¦€_Í%}ß: ù¼…i +÷?JºÌ'úgÏýÓÞÿ÷¯ùã:úÐUî»oF’ÄŒF)/|á”,K©kÍÝw²µµÅÁ⦛b&“’íí†ïü.ÍÉSûìíAž·ÌŽ*^ý?EçZ8nN[ö4q‰|ÑÑŠ‡Ž®î®v¤þØÏî³ø~!Zƒ÷²´ýÿß©3vcxnúª{¸ñEcŽïYbÕ  ¯Í´¾¦£aøÐ©“‰y ¸§)æÈÔOï ¼6£‘ÝÎwo„Ÿ 2Ô¶°;QÐÕEÖí¸Ëa|Edç3åïæ¸"M×à}¬Ø)î¿ÿˆé4fò8û¢;mÅèMpoœ<¼\H²kå™eò猒w ÿm°xoŽ&ãšñ¸~\xÞõ®Kþ¸Ìm·]Á¹¯ý„ÿîÑQÅ]w]çÞ{gÌçij¹~½äGô#|ë·>—¼d»ŸØßO(Іår— ®sáÂ5|ð:gÎŒ8s&ãÌ™ŒÓ§Sn¹e¿÷<—c?áܹɓÿ¦\Âövĵ+ô­2ýcÿÉgòWBÕm6>ïÀ½Ój ùoþ¿×¯“ßcüÍCêž®)3;Óa(nd‡–™N™iÝã»Æg¸€œ„„¼O»:ï½n-U0kÇÚLTT‹ WfúC%íàQïS[[Ã5•Pùci¥ªÑ.kXÁŽ×f–UØü8¢OÞk¨‹¸WfúªW¯Î(“Éæ¢~ÿIöjþ³ýrWIŠ7MäHe3* Úµ|‹úQ~˜ÿý1ÊÌÜËviÉ—¿ñ}üò/¿t"`㪀"  ÷Ýw­b6ƒvîD›iÔŽ&WfÜ;x×¾"²{*¦lOè?Sx¯W…œu++~œúÊQH§u5†Z¨VuiåhàëÆbqdÚÁÒ¬.,,jT^³=ZVõÚLa%©ûÖØ±ýá}þЈ@Wl}Ûuù!üIï÷ ýðu¬p©ÂÅjøl29ÚDÓŒÌFÛÌr–õÉ{×6“Ç Yº FõÎ{ÙmW‹63 èSwÑfBVKÙ®šÛ„½Ξµ¼øÆÛùoU¿|¸÷‡þÑ ~õGf⯯½í;x/2ÙÁ„ⳇ­¤ëñÚ ¨‰´G™D’÷j ¼GIß6Sg–* 0£ì²utÍy¯’€TiR¥d`Ãlé÷ZzÞOGƒó>åÉAÐùñk¾{wŽN"¸2/yè¡9'N|ú“«›丿i‘ºµÜ;x_ߨڮíÂÐtÇRKdþhxW>yw´s©Û#¨wÆ4…8ïE!!Îpÿdþßk/ûÓÞW«¥ÛÛçÏ)ІcÇœSŒF©OÝS.\Xqxhù7ÿæøçÿü•ìï+Æã˜¿ù­9~“§"ª²åhÒ0;ªpŸ(âÍþ¾e ©<.ŽW ¸³j˜FFþÓ7Áâ:4?C?И¦ŸÚÎ|_4áÄžåľ¥ô¾»*ÖVKÓ§îDZ=‹ 7ÁÝfåÞ×·¯ð?ýuůüß^™ñàî”ãÀÏúä}g¬¸z(Öoï»[Eæ?0¢`ø=l Žçîš‘¤áÝÀêr$¿×[ßú[¼â'xÃnäÌ™ñã|lúî­ƒ| Û[2Óƒ2Ó4òÏ;ß½ƒý¶• =‡Õõšñ¸a<®‰“{XåÏù¼üwÞyÈwråJé_C”ú×@Ãë^·Ë—~éqžýì-^ñŠŽK¸é¦1εš¢hˆcÃïýÞ5‚@óÜçnº_"V W¯N¹paÊõë9ËeÍtqîÜ”n˜~BH/Šcžœ¤^p?Ïÿ“g¸v×kð¾æ»Ûv·†4­ZOß»ªÓ®V²`lí>Õ[Ç$P=¼'kÊL0‘Ÿ÷£“wž ¼ÿG¾†˜Tù7÷„#J"f$´Î;æmÀ¼efn¤*R/ÚO ï:éS÷®nP)'=íÖP‘ø¡Uñkã|E™‡¸BõÉûaSV2´: é}÷Äjª\*"3=žäA IDAT-D ò}?úIÀ•f;o¬ê S7´FøšÜ'IŸ¸tÕ²Ò1s;ê•™—ðAøÆ¢Œë“øÆCÌŽ­{x/Wò=ôÉ»u°ôÉûB’÷¶V49LwÕà»ÇÒô42òþ¦Ãû|b½%*Ý“}Ýðí~¥k#NÝËþÆGi0\mwX9é£o–?‹yCÓIÞWÜIßÇAÃûoLá×;m&€yÃ4ule›ÃªÝуûXnBžÈëÜ·ßWüû fèóÕÀ×Îâ2'É{<8ïà¨Ê@üïÄÐŽtîu¥ûÔ}™ûžw+É{•$•¦%"wÕÂR-­øîdìª÷D+Iݽ6Ó&ÓX¶jZö·ÞÁOþä­œ=;âÕ¯Þ¥¹ÇpÛ··}‹Làßö]úބФ2°„ò@¡»^4M€W¨14 Ä©8ïGsÙ–šG¢ÍT6 ïY…u¦5,\¶ïmªIµ’äÝ 5‘‹\À=¯“ 罫‹ì’wTØûî]ò>a|nëIû·ñص§_š–9#dÉûzú΋ä½YÜ(ë¾*2E*Wm!ßλûr.¾ðëÏó+o+¸ý¶ÙšF¼þõç ý´‡Ç'ë¹?ëOxcÃÍ7OqNz·£ÈôàEY–bmHÛÖY~ìÇîâío-¯~Í]œ¿q“'#NŠx衊é´åè¨áèP4³Ý€ýÝ—x?¬e†í¯:e «tÃ$6RžI¥]ôç øÙ'öýtÐ~|ßr|Ïrÿƒ‹a`µöðîâ>u?ýìˆíT†–ÖÓ÷eî0+‡Z8\×ø¡>­À‘¢hµÜçµ™ØÎO|w¬Ø(®>\2žD}â> 4™ïÚvk[òìš2ÓxXÛÙ}¦ivFš_üÅríÚ coxÜ<ù©/p¶»uÐÊ£ö.iÃÞ›’ˆ&›ÀVïGÜà›ÏÛ‰ÿÈ#+œƒ3gRêÚáÌfK®\qEÍ»Þõïz×ìì„|ÕWÇZÅ‹_¼ç‡£ag'ì >2ŒÇ!¯~õ1ªªÝØ|ùòœåRô˜<¯88qþü'Ž.£èÉ ßªSáù_z†q ù‘<â.ÖÞÓÄî ïE+Iäb±–¼kĪ÷©×ž©WÎ{ð2›úë­L£·­$íc+VI Q:¨“O¢ÍüßDDÚ« ë¯=.qŒ‡ùÝöð¾m&YäT‹€¶Ö²ÀÈ—®tÜ'ï†fC™AGT*¥R)¥mFåâ¼7+C’Hò>(3r£Ú¥îQ¹C0À»êô×_37!¡´ÃècænD®jm)ëgU ªr¬LÌÂf¼Œ÷RRI·y¥hµÆ)Õü—½ñW¸ïÎ?Ib5øä½-4E‘jÅÈ8‚B’w¼óÞ4ޣͦ™I(Oíds¥u’¼?ƒ¾¯ü)Ç¥ûçÔP;nù¶#J¢W-6¬)ÛpÞ£YAÓjg© ¯Ì4–ÑÂFI#—×fܼ†EÍô„“ºÙOà¼ïíÊ ÈÖ¶§ðþ |íë?Åü¿)¸oM=­Á»’÷Ež‘Ž=¼ËÛÅѶ†rŽÊ~iQ§Í4 5øî:<ð$ÚPfr2ößœpùës)Ìtçúä}³*rY¤L|IÁÙ³–ÃCø¿ów>ˆRšw|ì<â¯ëð¾¶(–"óõµ„7¡ x_‘xxï“÷D”™…mfˬJ•É4æ(dá̼{m&ŠjR¥H•À{ä¤&rY «Ó‚µîóÎy0L¢µ¡ÜN›‰`ëܧ?”ñ|?! –º¿‰^"ÃÁ]{Õ:¼/Iq9˜¹îS÷v¡i—7ªÍä½óÝ­_Ô´u^n"·§ðå_ögøð‡ß1­_þåçÑOã©Õg<÷?"ÚL’Xžóœ-ÚŽO)ˆ¢6,K¹v­æèÈrt$“{î¹Æë^÷kœ?¿Ç©S'OEŒ2ÇrÙ0;j9š´Ì+Æ»¶OÜ÷ö5ãT±4ï©…£¹¿•-˜tK:rL"ß| ¼›'à‘=ëYïãpÞöžûñ=ËîDóÀ½¥×f*¨Jùk)=ß?°œ9‘f²¯©‡÷ VW&“;êž4²%5€L© ß½õü:>,w&Z*óбûaÕ±•íª:ؼpÿa@zoO’ˆf¬8u,bgršé4äð°àÎ;/aŒâرìÓúy‡áຯ+3ÝoÉŸùºnբ̌Ç5㑨3—/­Pê·7­÷šÏɉìXü¨Ä»âêÕˆ«WC>úÑh°ÖqæLÆjUóë¿~k5Ï{Þ6ƨÜ»ôýôéŒ$èìˆF":Ÿ:µùç[– áS¼}ã/ßá9/ȘåRe+(æþÙ«;'Üw§på²¾)e0‘/öÐ>w™47-:m¦ì´/EËû¾Iñê À'^Ù¬µ}òÞn*3m+ÉûÝÁ;Pçûx‹ùJ{ ¤E³ž]¶hR–¼Ä|P–5ņ_X½Q1a©™.©¥ 7’÷•xWµÃ(wíá½sÝ»ƒÊR.CÊ<¤*’±Yk›‘Á9…$ï±ÑÔmL½¦Ì¸µ§ú$´¼6áBâ”\WÊQêPZALJ­¬€¶$í«[¨`EÌ74oã#æ–¾™¾-¤"±PDô.|E@j5ÖÙ>y¯ Ëj³ead¶XKÞkQgÚÕ¦.Ók3’éæþ…Ç&"¯Ë÷/ÈsØvœþ~ÃJÇèy‹+äBhlCéBZ§ W%íL·*ðêL-Ÿm7˜Baª†ºXm6’÷õŽ÷¸qìïÈÿÖ¶G¢Í|Òôý«}Nµæ“„kàž¬Ýð*X¹˜t¼Äõð.m6˫ҨbGuŸ¼ç…¿Ï?÷¯Ñ>BŸº÷ šLÜ·Ìtð¾bDNÆ‚‚…ËȬb¨¾&2Ä É{‘rà«è7¯óÍ·X”Ú¢,[þŸ8¿™µ¥Kké»$u·©Ü_… B+)|ØÂÂZÔÔXndjдÊÛ”<m¦2îufÑ¡Á¶ŠE?¦*r[Í$uW¦×fúšH?x>‰Äyïž u5‘fÃwïµ™Bûé]_ßÌÑPõà^cGß§îÆ× ®F³íL Éû\Ó,4këMß½P=Àoû§?[#Ñ ãc†W½êõ8÷Q‚@óÈ#‹'õäàé Ë<óú‚wy„b¹õÖ]Ÿ8ÉcÜsÏ!³YÀbSAJ™ÜOžŠ(Š–é‘h3ÓIKuL3Þש{«ÄwO¬üz´”@;Z~Dº‡w$·¿zŵwlÛ‡>´àñ*·ß>ckË’$­wÃñ}‹*J´÷ÝUYAQÉ”iíHÍ駇rѰ›Îû¥•CûƒÜ_Ë­òð®xÉŸvÜýNÕ Mãû²áòÓfÈ˾²KßSï#öH‘>áÝ-hÆ›ð¾5×*¾ìËÎõm<§O¹á†é§ îCB,¿®ÌtG8òßÓZ¯uÜBî•­+>ð_†KÁz‡¡R¿Ê7NùèG_þ9øù<çêÕ+W"®\Ñ\¿^pæÌ„3g2Ξqöì­JÁK^²C];ʲñß²·÷Ä'žJp?yòöž½Åk¿þòFžˆÄ ‡]òÞÂdö<¸'JÀ=j¡¹ÅCûÂɺÛÀ1Þ2?‹±ìÔŸºSŠ~ѥ﬚éð¤eÛ/ÇIüFÜõäv’l­®ê˜Æv—¦_A.É¥êa fÕCìã_ÀÐðýúïÍT‹€za)£ÞCc™Õm-§˜¥FáØµ¥$êk¾{¥Te)óP¾7V«:fì÷ôÛUlìáA#Jý½ÇEŽ«¥œÀ;ïZ·¢I¸„R‡´ZSö©»ªœ@N-u—…sЦ0´ÀûJÅ´¡–Fž:ôʌŕ–jRE1²Š‘uØÂW}úä½m>¸J¯·A=I£‹[ù -šåýŒÞ¶ƒ kV¦&0ñb…+MkÐiK©B vV ah-Ê ¥ ™nE멊e)1ñ¼f·LS˜föXã}÷“'u­ØÝ€ß™ðɽwÕ…-kÊX7àÑ©3Vþ½² )ê7ö«k«¯—Sª0 ÉLï¼7#Ce-ÍV«ÍŽ÷Ü&ïmï£>}_¸‚…Kû÷Þà»Ç¾*2" ´$Ô1leгgöö¶ùæïx¶°rôž{ò(x€ºKÝ3#ˆŸ¾·P´1µ¶¨ è‰M«6–ò6ÛX­Â!y7mˆq-‡múxOõœL+,–ÈÊ"b–ûMNÎÿÉZÏû4ê´MÓ„LãÍ%~ŠO¿­å›?Á8®=ݺq÷.ëuŸYïjÙÐ̵>y¯—–vá“w·Ù6c ¿J£P^ßB ~£ËÁ!I¦œ;7}Ú‚ûg¢Ë<ózšÂ;€ÖŠ$±$zn\uÝÒ¶àœc?¦ªZvvÜOЏp¡b6‘Ô½Ø×Ä1$IÝéöýAi21¡üº79¯ÊxxW-“ØÃ{;¤îA†hk¯‡.ùÀæ8'OF„¡¦ªkÊ̵£¢÷ÝUQÊð¨’)ÌÓ7†œ>‰.à@IܓڕOÝW³B¼wåSw¯ÍÄSÅͲáÍtµÆlgkÀë`>mæy·l±ÙMç]IáM7¬Ú:÷ãÇÕH;vv{{pâÄçÏŽ6†#o¸aòý¼ãxPtÖe7•™¶•í«‡ãšË— ~ægÁ9Å0Y­]BŽ>go€cÇbªªáêÕ«Wc®]‹9ü jYMŽ|âîåÁ=l…ŸD³ÎoZqŒ­D;ÿ–Y®ü ZtðÞ2¶ºOÞ§±x²ÝÚzò< ÞDZ=Àß:üaLQÙ`Þ×Á}芀jj¤æ­öïñ½‹·P/­8ïzHÝ·Cƒ›äµô¼[jßï>ï“÷Îw¯HQ•¡È%y_µ1ÿçǯðÇÎKên•ÝHÞ¥ã=¦r²œ©»NüÍÌ8€ó|bF¢Jþ·»Y£r'N~¡#Z­¥ó\ÉÚeU9–:eÑdŒÛGz‚+¶¨iZC¡" -G¥Š2b±÷a¨ž«\°*b #Ó22` ÇjîpKßónàô›ÿ“÷üücÁ}íeô“‡v€Õw‚¿AS?1#Cq´œÐƒ^´4sƒ*MkhZÙ`W×Vº°gšFšÀHšÛLS© /EØ(XV8]âaºï˜fNÒ÷‘bl¡]‰2sò¤´—mo«~`õ6Î|­’ô:ÀG }]áyà•™eF™„4#ƒËÀEÃÀê²NhOŒ@üHÓ,Í|HÞûíª6!0†¤Õ$(–Ü%y_± c?À×·v5‘Q¯ÍL³¡¤`;…¼`«¾ô8¶ò¶ Z×ú⥿Ö§î6xJ™ [8lšÐ }ò®F°lŠ6êá}ÅäQB›êÞm`]ËÒÿ;6S˜¸WfVõ5‘Ë•Ÿ¨¦ÑÐ63‰!5š9ŸŠ—ÉškÂõjLAÔ§ïë_‘ÌgÒÜÔ»Oß›¥‘e`ºî}÷üûW1IÀŒäéO§oÖI½àܹsœ=ûôXUŸb-ö3àþ ïŸìuî\Ö;ñÉ¢Xk9y2"Í‹yÃ|«¥( ÎÁÖ–ÆFŠ÷|lÂÎÖíݯ±R<œV²5ÏÃ{’ opšÞc¦Nº¶…«WkNžŒzõckËÈÆÎ©úÝ/IE¤î´™U ­åô¹ˆ3'"Μ™ø¤\™µ–™kÜs9˜û¨ÃÒÖ–f²§øÃûrξ:€*äÂír{¾:KŸ¼¿êU”eÉc‰@| Ö^}úlÀ´b2‘ô]©è3ª ÜLÝ߇R¥ÌƯóù-|øÃ‡¼ç=—xík÷yîs§´Nîÿ“IÆxœqóÍ#@q×]×p®‹våµ·²·§xó›?ÆþàùÏÉ›àô錪jü&Þ–¶uœ??e4 ú†˜³gGœ8‘~Þß°2ƒª=+5~=ã=£ Àÿîãïå‡~ã/ ¼g«åö£Øã»˜ª—†Õ˜fô»gÖЪhô»·*C5–¦Tï>¥R)M‰ê-ôšç½õ ©ÒÄk‰Q¼ÿ˽A"ýÂ{HU5»Vâk?ÐWø¤?¢"Å)SßJÓ(,M΢+XtuœÐ׆¨né¼Á½R©|lRê&Áûh„÷z(*²"۱͔b›Ù:kåá~ÊÞÔŽC«wsVîeËß!ÎÕÆ,ƒ¥ÃæµOˆçÀ{;À»¥óÕx±ÌœjœÖr|DRÐ4ÑÌôФW¤ÞQ-Dyߺ$à.ÖéÔhz8{F,3}¯( ØÛQìÌd•hcûÆ5ãú¬Òt Þ+Z,¿·h I¤ÏbÌ´…D…s&eÑؤ£M"úI÷‰Á-À-£"‡‚¦Ê¦ìãFÛ̵îK_Ž™E’q?øÝËLS'œÙ“‡é­ ¼¿þkÎrÍ…4//™°˜`Ö>ª)èiPÝs‰ެ”4Y§Xö9.g´Í¨‰(ï¥ÏV¶™6£'޶ˆÐ±ÁÔ1Æ9ƒò:’^rêó ¼ÇCAS°Í,ãœxb™=‡çÝpwÒ·”?Á4“¿ËÐÃá ñ¨°)3ëö³¨%¹)(ïÝÒŽ/q‘€éȼm3U°ÌÉýy{°Í„§Yd9sÆbíKsXõù|î÷¶? ðpÿý¼‡ýý”¦q#Àï$T¥c±McB’‡Ü?ùxÄÞ¾\eh×±@j ”3ÏɳýjP51+å(xÞM½…È)v¿â)®?v ­áè(&¬b£µ ­œ;°$¾í2ƒ}†eÏÎžáøœ¨îÇçtÈwF¯l3§Ÿô£ê.‰3ruL·[rÓl]])S·mÏÑ«c®½ÛnÀ{5U¼f´"õL§1.L8w˜‘Þ¦:xÙÞ‹¹ø<õ{œ{ùØÇ~ögoðÖ·žðÉO6Ü|¸÷½üO>õ©’÷¿ÿ„÷¿ÿ„þáòä“sâ8æå/pŸÍ ò<¥ë<0ã}ï»ÔwGI×þ¾âìÙ˜Ÿù™k¼ùÍ{/Òñ9Ã9ÊuÒ0lÚqñâ4ì¿ÿ˘uíùä'[ŽŽ¢ð0 ¯úšÚû´g N¿XÂä h¿`àÛ'Ð-àß>åD‚ïÜíDžÉž¨•m»w¯ œÕ½öP:X8¦ÖyPëÞhÓB (K7F‡Ip*}ËSÿœTÇЀ²ž&ŠGPï1cŠÊðµÑónÚ–nãkÿõŸù?ù©÷ü¹ ¿{×ø>¦ì$.Ò¡‰•[•/‘Ž~÷j%K»)%»¹R)mÑt)³xÞEy_Üf™éû ²y6À}Ø­ê@±ñÕR 8½‚÷Ay_X÷E_Pµ)QÓÒÕ–Nx֙Έò^5)žå½J9´*øÝÁV^€£å}vA®•÷Ý·öÙ]ë^Øþà Û{7É&Õyr»¤$cI>®š,ê‚~.>aß*‰ ê»®¨î§†Þˆm¦ Q¡)´b¢m§ˆ;Eõ¦??ú#äÖà.Ê»¬Í{?ªî}/3;â;ž­5O×?’ ±ªË5»XŽ ª®+ïÁoRu)‹¨ ±ïÙ´“ŒE`yCliRÑÄ1ªðî…¦_@»´¢¼W9e‘ê{JIŠÚXÛL5Zf¦‘"7ë¶™”ƒ=FËÌ,…í\ÑùU ä ºûÛ T*à®'›Ê»µ{(]FÙgØI» ï>‡U×m3qÑÐëDy_¸B ?Ê©t¬ï6•wo¹¹”´™²‘U©ý\ŽÑõ´™ì.Áí×~ò—8<’áÔ!r°Ë i2%µJäup/}J1_àçùØÏ }¹¦¼/Œ5EIç)P(º ¼Ÿ;§pγ¿¼ï[¢¾ïM,“ÉKÜïÙeþÂ;À ðÞ¶Ž(Šy晎®Ókšø£§<ðÈ„80^WÝÑPjXÎ大¹ºJ™Ù€÷dµl£Ø­.ÔëmªE¡Gxï:ÏÙ}KÔöu€OzÅ…³+Õ}KP‚Pެ».A—Á6SŠÚ.à.û'Ÿ­¡-¡ëeo{ö^Ó~<a§™i¾üËÏŒsMÓs|\°õ7X¥dy3Šî>0þê¯Î¹v­ãè(ÂÒYÔî -¶oyËÓ|Û·e4co/æ&lmEtÁ}:-0ÆÒuP3ºnÂOÜZö÷§ìïK‘×Ù³1gÏÆ\¾ÜrxøâØh|p ¥à‘G¶©*wiîÞõÓ²E‘Ú÷½£Œý=ÃiPݛŠÜ½ˆöPYÒ~àÐ~°s‘¨èm¿¦º{¦‡–i¤¨ª¸£„eÊS/ê{©`á¥Å2’~´u‹Ô$ƒÙóŒRü¹þ4–Ú&(+þnZè#Y¶À½Ãް¾®´ä,ÇÏ5‡æÍßó3üÓü«Ü šßGT] =8­9ckRkH­f¾æw1Áó®Ey×¢h7]<ú݇¬ìÔ2c¸,3ƒu­íDuÿ³?òMð>¼ŸX5hí6àýÕÉoñöö«pZ£+GÛFÒÛ)]Á²õ½w’¶5-­ŠÄ6£tlñ}DÝ&¢¼#àN¡Ý°ÌŒ«•Bk5ÂÐW~å1³™D˜Þ-{oÅÖ´B;G×Y´wôÞ01sr½ä”)óÅUøY|«FÛL+šS=VÈ;#àî"Íl*³A…E¯Hz$qfѱµã7á=ÄEöÎ é:ý°Â§ØÝÞT5’Õ«N„aXµ ÊûMàìð¾˜,¢‚ÖD’3-WðJ†LÜÓ&fÒ¯”÷«H&{ š¶Þ;›úš-ï^Tw±Í”£ef)&Z|ïÏ.SÊ¥¨îëÝ?õ¿_¢Ì íÂb£{®&UVÔºò^È °µwpËå,ûŒ¼ð0U¨©GOàáôwx§{½¨î±ÄDVIŠ*|€w…ñ1Ö9`/!ʆ$ñcLäJyÇ‚&c‚EʈEs+<”Ü­ –"_Œ×•Á’7Øe*ÒQ}¯H7Ôw¿T#·€þT¡ïý2(ïKƒ¿$IçÈ1äÀ¼Ù*dhoO³»38Ø3/YP¼îÈá}ØâXÇ«›ò™3+p÷þÒwý.’‡2odw†8j8£ŸÅš“«[¢ZÎ ¾ ðî [gàf­FÛLoWÊ{¡Åï^è0L|ïÝ¢g뼿CyŸ¥¯©îÃ~p °ëw¿ÿI‰§dˆ„Rfbà$¨îƒú¯Á{#ðNMÃTácESE²bbR’¤¦IB\äÄИXüîU>*ïCÒL‰×=óMt›ò^ò`°Ì̬œ×‰ò¾/ùûƒòÞЫ°Ds¹& W3E˜eV=?‘Ò¥(QQþÔŠÆå$“†¾°¨Y‹*$.réóÍ‚¦4Ã:6DX¬÷˜ ¼/|A©SX.H&úNÏû2—Õ.c'—Ú‰†<ÜÛ“»Ä·¯{ú]ì«q@5g9ÚeÕ½%}ï%2@ëU ‹ ¿èqsVK½¡¼ûS¹¯'£ÀŽ«GG:Ø3a6SbßÚâ³. {©Ùeîûx¢gIӔ岥ïWvˆétïú/þ&Øf$q†…#Ž>·»éWýÚ¯P Æ cGp·e'•÷ñ`ª°£Gz}xuÝÿ®qãÇõ½ì2ò¸Ç÷&xÞS©gˆ•Ä<´ å}áÜqA”·4y,‰3±b9õ¸M¢q·“7Ñ”uF¿å}øaXu'R·ÅD®à}]-3#ðžÏû™=¹}X+dßü7õ¼Ç7änï(¿‚w¬@2„ªÐS žwkÅ:S6K“SºŒI1§›Xâ©À»*d`w´Ì€ÏŠ’ …&Æ8ÏÂñ¼“C)±ËqS¬)ïCLä|™ŠÙ.‡“§)LîÒíàeOü.T2ÿBEÁK7–. ?¼JGõ}Ç|Ñá~®Æ•£~¹6´ºÔp«Ç»ž¸÷Q‘âw—c1Mƒ}k&J_ˆv™çú½{@ÿ Þg³'y衜S”¥æààJ(­épî"³™æÂÿÄýœáâqÂÅ Y.$ϦeÆyh“`›Ù‚rKaÍfÙˆïÁf+¸nY²Ú=?Œ)q¤Ç&Í¡”çðP¼ú[»b›9·o7¼¼Î‹ò~=øÜ/K³IÈ;ß^S߯žÔW­Ùf¼;ÚúþäÜ‹z<ùäM>üá|øÃ7xüñË,-¯zÕ>W®”|Ý×=€÷2¦j´u !Ç+—fÉ“ÍL8>gÚÖ‘$) Ã÷Ê®Ô cv)Ë­à1Ÿqñâ„££”4Õ÷ÎÐç:i­âìa„ýÖaß‹‚>1«&È^ ¶fÑJy¬3Q×K‡¯z™æ‹óB}î·ÿ™{0ÿ ïgϾ—‡:`oOTÚ²Ô,—š²”ý¾û>ÊÕëÿû9àÒq,ð~>—â×á}¸‰vÝ`›þ¬ÜÔ‡iôÞËŒ$aå}¦8<ü7\¾ü5ÏûšóÜòàƒSœó¤© ¥<â=?>—¬ò«×òè$]fw±™(úÞ3]SÞoܨ1î6ÛL¿ö$ðyÚÞ÷¾+¼÷½Ï2ÆaO˜Ncžzê„|䯏_¾¼ ïZ‹7öë¿þÈc7f¼W8§Ö`vv4‡‡–ÙìNðT¯uxŸNgYªª£ªzš¦çÒ¥‡‡ù½³óùNÜoàÞ!ÇNÛKUo§GÕ}¶+žô‰‘«AyV©N®·ƒeÆŒƒ4§ 8 ‹X²œå}áÙ>ð¼á[á?øü¯õé§<ñÄMþþlNQ…4‘xîÑ¢¥IbÚ:’ÚxcGxÀ}]u÷(ö¹:ÚSÖ«ÌózI¥d±€»ïcñ½;Cj«µ¤™LRfȈÃCj-]m ¬F*´8®)ïÓ‰ˆ\ƒ÷¥Ïé•yNÕÝyñÖtÊ’ø«º;¾.(¡Œ2úÖÐ÷F<ï}Î%sJÙÅTµ/5^ÔÀI!ɾGå½nh#¶ IõÒfªEPÞr\l…kåÖ]„÷ÄÕ´^wí¤hªÇH޽“ãÒÐc|϶½IM‚ÆñÐ_ÿ0¿ý^Aï ÓÝÐÎÛÁé0 üîÓHš_Å2#О„ý¡WísöLÊî–á½H?»; 2!†¥à>¨îÃ’JÞ¦çÛjŸÈÃU€w“õ4YL%$Y-«&}!yçq4¦Í,ëWë•ò^®2Þ#k)¢n„÷uÕ½Ððôw>ÌìÑgÆrñ¼kª… «öN”uìÊ2cæ2—ŽeLÏñ½¼7ŸÈNz¦ÂªÂ¦l3Ý͘2Y)ïÝÄÒMÞu.2ã°j•¦²g)*¶kÊ»ã–+X8ø¤l mIúDl3Ayw]Ì|™1_ƒ÷í`1wIÇÙr'Ø‹rþY:ö¹:‚ú`‘iˆ7Ô÷®µø¥'ŸÈ%—E‡Ÿ÷¸¹Ej˜+ñ¼‡œwÝjú)žwùsÃÜ…s«(烃—n‹ê õ¹ßƒõ/0x¿q£æ±ÇžE)Æx½3g~‘óç÷yè¡ΟOISQi«jîUeÐÚç1—‚â~é8ao{³ÝOÇ¡Qt­øgPÝc'“ÛŠགྷVmÂõïé+&|Ã7<ÎOþäkž÷=M&–‡šrölF]÷c«æö^L^Ü™¤qzK&÷÷öÜWFŠ|GT÷(ïÐn ÞðꆄÿyØ>ö±[<ùäM>ô¡ë¼ûÝ—‰"Ãt3™ÄL&W®”Þ¯óE_tÀ¥K[Mè{ÏG?zƒnãý&xÉ6럧©zNp,Æ@’¬.X{{ÛÀ6 žþ²ìÈs{ïÌüt+C_G¨5–øýêjD nI;ä4ZÙfÔšmÆ%òõ“ÅɆÔî>øÝ=0(ðîˆ:/7×ÏÂ3Ÿ·<ýôœïˆ5E)0Ûy‹SZʈjiz:ei›ˆ¦‘ÔŽ!Ûý¹Ê›v¹Î’œŠ”;ªî†]9J2v/ý,·n|#¾‹Ä:C4zÝS«Çlwñ»å½1¨ÆRWÜ3³áwJŠ$ï=ýîõúÑÏbºÄ>§UÆ;%+ :¢Sv£ÅqxÝ_qö1ûøWP9±êôÀ{Ýgdfë$·ÝÖ52¬zÆ6ho¡h»ïm‚o"v Q'F11Š®–’¦~®˜­’;f ü?€ÿì•¿Çãò'@1Ú9”÷èÞ¡´Öu8¯Ñ½£ó–I6Çi=z‰;,¾ëã|à{_9ƒÉ`›™‹ên§šY,Ç`¡Wà÷ŠY '_þ üqó(—.͸paÂáÁgöù÷è•"mÀk&À¼^SÜaÕlÔ˜Ï',Œ€û2ÊI³Š&“c·ïÌ8¬:*ïIL›D4·âÞëzÍïnS¶"EneP5Cà^QH÷S¿9¬:1P— {»AûéáÏ¿UÞC_€ZŠ#N©ðþÌÊ:ãøx Þcž*QÞ“•ò¾¼œÉ ªÉhˆïPÞ7Åï¾ôùmª»"Ca}Œõ½€»Ë9½r–-t qדkEª4;ÆDf©¡à>üÝØ¦osßÁµ+v™xòŽt™Au,3}ep¥†…§˜ÈµÑ¶™E,II O·å½[Xövàê)`;âNl3í­Yµ¼pz‰²û½XÈ?$ðî=<ñÄMžxâ&=ö,=ö,‹…Оqt”qþ|¼^žº6”¥c¹4´­(·伞¶ÿhø˜b²Ùì7Xfüzz°Íl†¾÷ìïëñ¦äû1½öý»3Å÷§´­”2ýÀü.ãoÜ÷ü'ü4b:½shòvpwÚ[+pñ´ KdÉDT÷“R,3&|ß…oXûË”}?¾û¢»úƒnšžå²e>o¸y³æ7óʲ£ï=“IÄd³X´\¸0åÒ¥—.MÇø¸!…BmQ¤ž÷Xx¡[i¢(¾wV>¸GA1–!î±ë¥ˆ¬QÐ[à=ÚX5Á¿=K‚¦¦""£U{¯{àý–pzvî Ôlíy¶ ©ø~þàˆGÙ¦ÿX#v ,­ŠPÖC±kphš(á½Í¢ Å}Þ5ŽŒr,Jiˆ7,3I]³Ô5·¡¼“Ž–™4(ï­ÊèIˆ ] ­Eµ†ª’Œ÷­˜Ñï>(ì&xÞpÿÏ÷gIµ¡I6á}xÍÎxGÑúˆÎÛÑ:sû^W³u—ÐuV šŒ”Òø.¦¬3lÓI3™íÀÅxê{Õ¦øÖ²=À{Øçµ$ÎP)f‰ûëÌÏþìeþÌŸ9|ágÛ‡ÖVNaú 8§ÅëßK>ýÁÎ⾡ñ1ŠÇ°Ë…ïþ8ùÏÝ7*ïîT”wiYEŠÃ®†¤[yÞ·sy¯_õÇ/¦†‹§ŸqVÅ=cPê>AkàVÀ7IjQÛëAuXÛO€_„ùëW𾈠ŠlA%4YŒ¿¡Fxï#ОĘÈrZÇÒ’»X ¬‘GÖ‘GzlW=ñƒò>!WRz¶~NO ª»ëå5ö9PÉ€ª ‚~€ö\øœDÞ%RT>Xg6à½ÎYnç”}&3)KWXô|¬å=Ü6°ºïÆEoXøœ¥+(¢jÍ6ãÈ•! ÿxßß *ùïÅݹ~nW7Q¯ñ¼Š÷±Ëubn1ÛH˜©IÆëJ×HQ˜_JºVqn€÷=n~®ðs=*ï©VìL@ÕÜGMü¨º×MJYKÙÖƒ_¿ä±‘¨ÈÒd´6!ê`™Qk«¬2ˆò.M+Ï{üWþ+\ÑRÀ]»ë½Øß¼Ð1Þ*/¾w=•´‚Ρ^¦òú’àwW¢º÷ƒšÂâ$gÙæc»ê0°ªã˜ƒåÝõ¡]5§ˆ{×S/[â¾'×6ÄDZæKÍ<À{ïVªûÖ]€÷ôGk.œ¯øcü:3n1ã·˜±$U‡5 m…Ô…+5~¾ð+ï_h“[÷Àý ¼ÿöoßä‰'Nxì±gùµ_»ÂÉIÃßü›¯âoý­W‡4iQÝÞN¨ëc,GG)GGI²Öh[÷º6¡Pȳµ¥¹páA¶wkvÕFôœs ¢Mwê-ñü ¥Di*±“³¢xõ½ý[xsöÀŽð¾½qþüÝ‹[?ZDäÁDÞ³2ŠbÛó”«1>¼«å±¦ºoo¥œ9“óe_öA~ã7^vWØ<²‹sžÙ,f¹ìÆáÞüüÞþö§PJdžóç'w­™õÞö{X•øºphuk*` dìDð‘¢¢xŸÅf´Í¬+ïݼOX,hì RД2ÕÑêY ÐS òîŸQy‡U4ä`™ÁK1SÒ×8¥iRßAyïhã”Ãâ ë:JŸa]'“µ§´)¥‘!3…ûIÝ7 ËH”÷e“¶™•eÆF†µ*g’•)j,ª1Ô•eº”Þ°‰Rëϱoü÷ÿ–ÌkñÈÖaÏã¸;568õZ‰ú®,1wªï¯þÚßâçùO±$§ñ1‹® 35Ö[\SÕï•N9c;)«qñ¨¾¶™?€¿²åÁ6cƒò~é’e–ªÑ23¨ïéQú‚À]ý7W1¤â h´À{iøª×ÿ;Þþ›o 5–½ãk¤¾¢î”÷ä§KºØJ6z*ÐÔc0§=O¿ò¼Æ'í‚ú>ר\3‹Ö•÷¸²†Ð£Ïî7êê*¡®²¤¤qñxNM²¹üÌ:dx5DBnlŸ‚¹ Êûîy(iRŠ“ º/º‚$®iãˆ&Ž©šl„÷EWŒÊ{•¥ä‘&·š³6°:¿{8ŒÒþþGÏð‹_Y210ÕÀ–¢w°÷ÿªñ=D îÁw ´€¼ŠÀYy(QÞÉAÍ‚úž€Éà´Î(ki:-}&IP…ì>Ó,/ËûÜhWM2öiFëϨ¼;ü"ªÉ”§.å= «b8]¦Ä±ØNœ“¢·AyßSðªK/üúùçÿâ¿dŸ«¤Td”òzCAÚú°ê ¾«…—áÓS/ ð®ÀÏ»° ¼³ÐôKÃVhLÝ.`÷‹ Çñ×ñß~û¯òö·¿á æ>s/ò ¼ô£§Ü¸Ñ ”´¤>üðŒ²ìyï{¯óýßÿ>¾ã;^ž‰û­ »»¢¼ªûà‘.K=Zf¯ô™3†sç&kÀ£ï„÷~WIzExP 4{kåëßÿŠW´­é'­‡‡wL‡²•eF¬BÎÁ²ß´ÌWx÷Ä‘áøÒ6ÇÇ[¤iŒµŸ ûå/ßãå/ߣ,xoY.;ž|òf°½ø5€—Ï¿ê«.ñàƒ;÷Ζߧíàò(æÖÉmKø~í×ìÀ¯ßÕ=7ÌÒ;m3ÆÊÍÛy¡YÏ,qêC’Ehn 1‘vÞÍ à­Ql!Žo?ñËðÞøi¯j;Â{ï ½6زêNì1ÚŒðÞ5š¾VTYªþ5Ë>'r-­ˆ\KßTÕRÛ˜E.ê; –™ªÆ6e,Ê{Ùf£m&µj,gʬáªÊiF¿;¨Ö„ÝRÕ)gƒefÁ§+tt QÖ[¼úM€woVàîd5®U 2Щ+‡K4Fo»ÂSÕ) ]ÐiCn®‹qÁ6cZ÷Ü.‚ò®Gå½nº^"ö¶‹ïkÊûv®™^Š˜Lô†ef–ÂÞÎ ›\ý²?¹Ëo¼ûDžjÅ«þìÇå}V¯}Å¯óžø‹©]"±‘^æú¹¦K%*´ÕUœÒyK>_âæšt"Ê{ÒÁbn˜…©Y€÷BƒmIÇðÙ&–>½¼@]oË\C•’¥%M-ð>+n‰Ò>(î=«\÷Û.Ç_þįñc_ô,¢‚:KÄ2“Çä¬,3Ë.G%+彪ÞÛ.x¯àËiÆ–Õ‘"ÁyM‚V‡•°Ôɾîy·[kwr>‘œyP‘—!¬P¦¬º5Õ=’*ô§ Êûèyƒe¦(_úŸC?±ô;þÞ²ÏïhWÍèžÃó.íªé)Ž›ËïCL¤7ÌË ºéîÖ Þ/Ö™¿Æ?e›KGDKï4Æ>¼—d¸¥FÏ(ïs…[jw5(ïƒmÆÓŸ®Òfv޼OàÌž¢¾¢È²Œ¿ûw?Àßù;¯|Éßg>“]æÞö ï÷ß?]S×Å ^×}€ù„G}–×½îíí$¤²H2 h¶·o/ÉP”å*¼ïÅn!ð¾)sx6W×a<96ƒ“R¾q[œÜš½eoïÅñSO&Š““%GGùÚC‹ç©ªû àégÏoqþüÇÇ[crËßû{Ïð=ßsöóò³Ì’eCa6lm%x/–ïá=ï¹ÌO\#ŽÍ˜ñþÐC÷þÅÞ¦o¼ÂC¯<àò'Ä·ìÂð«H;ãÁtðG·á—NØ:/úô6ÛL”¬Î¡!•)qŽIðºÊ{à=¹My/L&LV);ÓO¯¾_ú1a‡yH˜é1Ô:AµÝIÌc¯ M¼²Ì¨º¢­S¾®þEÊ(Ãt=­‹ˆ|+„eKÝÄ46¢¶1Ë8§ÇPÔ ’ºÆ´ýîË6'úŠ_Aø/X¿¡¾·dxâ°R6€»j Æ[ÅÐ û\Û—ÿü¯“!C¨MÀ½Žiƒ7ù*©ÄC~wZ¨»m:vƒ« Ïk¿þWù™ýfsd2£q]„ëbº6¡i<­IÈlEf ôfCyŸ&¸Û±§ññèsO£J¾© à³*dbðË:'ijVüîë–™FËLé3⤡IbRk¨ë”eÑt1ón²áy/¢–Üj’爉,”ˆXY?Xg¸ïÕýÚríøfð²+lÜðŽ“m¼‡*¨ïÎÒfÞ—·‚¥Ç‡øGŸa'í¨¼/«Q”÷Á2£¢ˆ<€{ŒÅx+1‘Ay¿/ŠÈpP¶2°:*ïŠÓe>UôAyl3/Ä:ó·ù^4Ž3!tv8ÇænÂÒ‡ó35 µO°sÉp|ì~¡ð§+ÛŒ®z|hXusŸR+‚ÆöD ÀO¡ßW|É—¼†(ú8ïxÇÞð†ƒ/Xp¿§º¿á}X&Éó‡>ã7?ðÀtH¼p¡£3.\(€ß©à “ÕCˇ?|ŠR1iš„=ÅÚ#yè˜åò·Gh?~‹ííU‰ÑÁå­o=åMoš~ÞßÓáaÁ—|Éáè‰?~JYvœ??aw7Å}#,ïmϽE_úaþ¢ y¹…ù<À»T÷^v"$Þ¸ÍÓ—áNä&?Ϲï±Xg&VÝ©¼ë0ÌÜåýøØ ¢ºç+¥é¹¶ÂBåá´6tni—¢¸;%ƒªƒêÞ7 ]{ºÆPg ªò˜®Û:#×’-nѸˆÚF46bisZaꞤ®Q-3e“Gši±Vã°j§Òàw×ÒN ¨Æ¢CÚÌ`•þÓ©î-I"Ü›&¦¯¡IÓÑ.ƒƒ^Z"\§IªšJ¥èÞIºZ©îþìr)`2¹Ñ¸6Q6†ÙD""s«Y„aUßÇDÊŒ«-;©ùvA°ÍøÞûÞsx(Þ÷­’88w韢"eÂEºUQVë¤*K§,M£½¼ß>4Rv‰Õ²›E/þâS=‚{Ò_êܧ±DEN´¢é!C‘ä«Y„{|ãŸø ð^oS× M³]ܤ)Þ·Št+ñ–cÉÙz›êZ|êÒåXßž÷F ¼k¨Ö,3ë)3™ÑœÔ eQu)‹®  i3ÆZrÛSD¢¸¯ÇDª{T÷´‡‰![¿¸¶Øck÷S”w9yÝ}¸V”ˆ.Z%O ¼ŽÄ:Óð®(¯ËL’³LrJŸ“‹Qy/?™QV™(ï® JRª$e˨Ñﮉ±Î²tIðÅçq,ð~»òh±¿³‚÷í)£=oš}nÇæ·u?ÀÔ?²µs+@{éDu/õJy¯I`êÔ‹m¦”ò%wªá´§’ΣË¿pÁ6ãq ÍÞùàu/`g";ûŠƒEQH`ÇKy»î_€ðþ™–I†Ü÷>8e6‹Fp¯ëïæ?Ý6LVo–dÜ›ä_°UDkˆãÏ´_½Úò¶·]åmo»ÆSOU<üpÎ#¼s£€¨m7n| ŸúTÉ>p“Ë—+œóìî&¼âš(ŠHÓ”$€÷^Çšûïÿ(õìïÖZÚVà}2Ñœ=k99éÙÚ2Ÿ÷ƒáܹ _ò%‡L&1eÙkMÇÅ‹[\¼8»w¶¼ÈÛ…s1Ž|á"‚yÔv…¨í¦x‘å‚©ágþ|÷Ûž÷~-öpð¼ïNY6(w³¦ºÿÿ‰óa@|wK¶™çRÞßð¯!3"ü%¬|ïÞ+tãVðž¯àD_YN IDAT]Õ}mù£{ï¥ì2T' }äÚ±µsk©èÕ½¶uј”¤ªI*I ”÷®O‰;Ï,[Eº¦º7 ê^à}MyßJƒe&¬\ܾ½òŸÿ6Y@Õ;‚{×(úZSÅù†e¦ó–ÎY¢ª¥«,U”¢;'{äî€÷/}óoò®õ“™S÷`›qmLÙÄÚšÌj2«Y”QˆÕŠFpŸZ ­D¹œZ8:»jFî:Ï™3–ÃCËäº_U¾Gx¯8kžá†Ú“ì²£[ÚÞ·8áV<#Z´¸SC?7t*€»±Ø\ÓŸn*ïƒú¾î£mÆ€êÕF׆Vb±øñÿoyËùç|Í¿4ÿZê^,3³â$Ð41Óâ”ÔU¸'ÀºÈb“nï–{gXV9™)Y)ªã$¨îв+ÉØ®üî™5\n¸_V’â2³šÀ»DEFDèž pw¦…Xg^ˆe&·Ë6f…§ö‰Àû º#¿Ô;Ûö–ø´EÍ=ÌåšÕ/eh•SÉk×U©Ä2ãæÒ›@¥Gc{º4ÒcÅþ>rtä^Òªûç ö÷€þ%ï·ÿnÿA}¶poÌö ~÷/nLÉ;ßy•w¼ã ïxÇUÞö¶×?ï÷>þø-NO{ŽSñâíF#°ðÞ4ž7¾ñßóó?ÿzh6ZŒ’ÄÐ4=}¯Få=Žã04ë9>Îxà—3™ôœ9Sl䦣8<Œ^p¶óç§œ?/4V×=eÙR×ýg5vo»‹R¯ý-~ÕŽÏÅ\¿"àž[Ù—µ[AûðØà'ë%ëý‚æ{ß<ÆP„ËÏ|ë Þ§Á6sñb„Rl´7æk‘¼O¬gwª˜ez´§ ¶™çRÞs m-審‡“ÊÒ¡z?ÚešÎüºÚcêŽÏ]¦™Æ´•|¯îÜh›É«ýRÑšˆ&€olDeR’º&©k\«Å2ÓäL¬Bõ’TVI3Jò݇aUw÷ÌhŠÉæ°ê†Úü¿~ŒÌó¸rÐÔ1ª)éêŒ.6,M>Zf:,¦êé*+¯­(ï½Àû:¸+<3n‘Mn4™Ñt•YùÞی̶£òî×”÷Õê‰(€ ÊeÜ­,3ÃõekKsxøÂ®+]ûÉ®¢éb±¿xK¢k±¹˜dQKæµ²«ä¥Wªû"¨îaŸžƒës-çŠÿñ—oñænFÒ‰ubxV‘&ZJú¶‹µ(a-*“£”O|¢âüù;W€ofÛÔW%†s·¸Nãcâ¸!µI_Ãå=ƒÊ§$iM”µ«Œw$Þ±JRê$å]ô‘‘aU•÷eŸK QClɬ«ÙØœ»¬Å2s6òa`5 ªué7•wݯl3ÑÊþ#òz®-ÜÓi…Ó0QJ¼x÷—@µî)«"* Ä —kª8%›Î%»ý™B,3• «.Id™NæôK<³ïƒmFE…iG¿»"ƆaÕ¥+Xø‚bÝ6V-–Óe<¦Ì 6Ù"ƒ­Ï½ éoñ?ÝvN9´X€|&ª»“_/ÍjpÕ.jé85ïØfÜ\¶]öè²§›ƒ›ƒ›ûp ôlO<;35 g.f8 ÏÍKò>s¯Eõ Þ?×'ª ÷Ÿ-çÅÚ>ð[üÖoð¡ͩ랗¿ü­,— ''mÛñÝßýÊ1 óÁ·8:Jè:±X«¸û5p—ÏûÞó}ß÷Q¾ó;ïý㇇M#+Q‘$)Jé1ñfo/âè(åÁ3âØn” ußTY^ä-I Ibî%/ò¶ó²wòðáÂQÌv®©¸LSXž¶·Á»[©îN±µ­¸5 ju£~ó¿ùï‚ò{f Ø b_ÛÛÒ#üe*„˜ËŒgPÝõ8§²½­ÙÝ€Ú¾Myÿ¦·Ëë­¸'t§i{±·8%à»÷ý׈\‹R^v<(FÕŽQyo}D¼\Ò-u²¦¼Û˜>’$–´ªè#–™8ãŒí¨Úˆi ‰ÔêQy‡8„ˆ¬)ïeg*bÂ:0®on!¹å-—ÜGËO­ébC“&b™QU{ºÊŠêîÖT÷ÎÓÈCÍm¾ÜÜs«9 žw×ÅXe¥ÈLjòNV½Cyð¾]Hôçíðž$Ïß×ðé¶ã‚Éq'±˜Nš`[ÑiI¡DT÷å Þ;eñÆàN„º¥]YfŒejáÚ©’áÀ¹Æµ¢¾ç’ƒÕìÁj`UQö »¦¼« ¼'G)GGw‚û?ó_QïŠef»¸I”·4e̬¸ÅÁ{®´çÞ-T}ŠO&ïÑ©ï”Ë>§Nª4å»ÊÀ7Ïþ9:sô©x½Ë6¨êƒòž¬ÊÁª:xï‹Qy¯mJUäãÀªÄD^£ W)EϽ[ ¬î…EÐkå>Wç²éáoâO*ò+Õ}Ü ×€ux7«k‚‹5®ÐÔQB1㬠£–u&³I>úÝsÔJy×!ã=ËØÖŠ|´Í(4 Æ©1&²õ)E´f›éÛŒD·®«ö²TþsÙþJõC©Á²ÙbÂÌKúSš{ñ¼·ëÊ»§@QW½xÞç¿õ}ûÜJmß™±¡Âï&Š­­{-ª÷¶Þ?Óö…÷ÏzÂk_»Tw7¶³JªN²ögexìܹäE¦½·½´·ìàçGp¿p.!ŠV–™I eî¸\·›–ôîEa%ç»ÓÅJu¬6_óýð«ÿƒ¨îg4ÝŽóf´Î¤vSuV×Äó\qæŒf«ðÄ·­šåáÏ/×x!õP-ôîNiš.F•+p ÞN ‹ÞBφò>]*ú¥¢að¼ÇøÔ¢•‘ô:E·nVÍ윺²ÌQÞÓQyG¿û¨¼7¢¼ï†‘ÙsxÞwÿÎ ±Ë ðž­¼îº)éj#{¬©’|ŒöL«jïVüî÷ï”–ˆ›l³$¡]áI–5Å›>Hþ¡=2£¸ÑÅøï´çV“#Ê»‹Ç‡Œ©]ƒw/j´µê6Ëâ Ûö?xÉ…NÂl/'ó ­Žèœx×Gxgï“hƒªÙ-Vª{o Ô¶jlTu&æÖÃÀj›m†(RIvÒç울™ ¸û^qP\bÕðÀ¿RÀ¶ çHƒ”GÕ)$`“ެ(!‚¦‹Y,‹QyÏý’ETg j•4Óç,úb,gÊŒü¬ªF€xÎdL›É3Maõ™¬e¼ei^ÔÒ ¾ïïÊ{À]Å•z\¥‰l+ð^φù4¼·8œŒV® –6ŽÐ¹£ŠSœ3b—iòàËí©2ú‰ÅĆ̯Á{,@\¦çMC¡oó¼{5¶«N"øË?}È›ìe(ÉyWšˆˆ4<¬Ûf’Ïñ–ø¦ëoãþ]y_à ¸¥SdFx÷2L¼t9¥€Wó6xØýiH™éôIPÞÛÒaÊ•mfš;QÜxŸÊª×vð½l¿tÁ]=O)Ë=8ÿï¿W¸¿è?[¸¿[€ölJ×It£÷¦+üô´áÖ­’““Šºî±Vó ¿ð4Z+yd¥Xw¿¡º_OSÍÑ‘4¸¾üå’ãå½4œ6Ã9µñýmë9wî^ŽúÆíÚµšw½ë ïzמxℯþê³\8—Œà~á(æôd5¬º=ƒÅiOw”õšúî ¸ž45œ;c°´QèljXU½%þµß?÷gáÂ…h„ñéTŸFwÂû™=M¿íÇT'cB§Âdóð·ÿƒ¼Ö¾`”÷<‚årî;ÿøýÂЗfÜžt"õòªó¨Î¹ßB¿Pt¥¡Öƒê‘G–²µ”u:¬.›œDK‰ÑÍ>âWÍ{ùÓñ4&Í,Y•3ù€ðº5XoØ™Êù: 3ëž÷aHu€÷!â²o€¦¥«-mmhcC[–:'®šÜ»ÊræËžÅÒ±$Ç÷ŠÆÄ,É7–øÍ¢'÷K2s<ï®õ]¬SðëMSËhšÛŒóý¯ðmëùÉŸ¼É_zyÄäRKç,¾Wò¦´(ðÞÐê*?])ï=ÁÛ®,{®Oûºò>Ý•„£¤…&Xg\«IÒ¼ïî¬Ô÷¡a•b3 DyŸ¤w®þÃü÷Ô·©o&ì×°E‡W UzIm é+£êîSª8E%›tØ´#ÊZ‹‚e´RÞ[±ˆ È G‘××b")xªûh›1Ř6³À½°ƒç]«Åª&€6 «¦Þ»z%×çû\]ìóʳÀY-¬ÈÇxD¶÷©’FãЪ:$UÕ}B—X¢¢¥Žñð/sµØf8/“ŒÖÆô…•gFe~iÄón¬¥0 …QcÆ»xÞÛŒ/˜FPhO†‡eKÒ;,Ãêg¦õ K>ØË¯ànééW([L­Ê.[)ï^n{cæ5nî`ÌÞû>(ïó6£à´ê%êuáqsØ=ãØßSk¶QÜ;¡y‰.\&Ÿû½í!¼¿À/Ї7¾ö¹Àý Qï³±Pj?aºª:NN2‹fƽp¡ ®MÓñ²—wÀûs}È…w8>—p|³¿mé—¢¼oÏ*¯_íÈ“žòf€wíÀƒ5𳆳†²…6†&†¶”fÅñ)Òyè=oþ©Œ·þåh¥ˆc‰jÝÎÕXpæ}€ÇÇ«2´áá÷öXÖQu÷Ðྦ¼ûRÀw÷Ÿ\õ¶ìÞ×À}²å0Îâ]DÕTçéœÅ.+ú¥¢®ãQu¯mÄ^d¨KCU’ªÆ÷вÍ8«: }Ä,fÌy?QùFÒ ˆç}wºòÛnç›¶™è¯u+¯»—‰D\ª¦Ä7]å]x¥]e¹ÿÁ4 éše2ŸÓch&1)-Kü]O¾Xbu7ZgËŒñ–Ì:2kÈ­~UÐ4‰dhsPÞ󻤼ósþò—Ëðfë"œÓ¸^cTO”´ÌˉøÞµ%:mð·Ô¦òà}báò©¡?ÕkÊ»aÛBÒ*’ª¹PjßÝñ]çĦ5›mÚfrµf™q+xŸ~š¨ú›Ù6µ’2/[tØ¢£¿iøâßzÏ ÞQݽ•ã§L2tâ°i‡IzLÞ‹"çT^”÷*MYDQÖ’Ãj`5ì6îˆÂ1W5uQ6™´²Ïûq¤d~!>A‹ç}Íïî: «îLÁpÝìru¾OCÌÁÙ+ø[ möݼŸŽUÜe*ïK™ð°K‰SÕ¤øT¬AU”²4ùÊ{(^ê2KWróRT÷Á¿P[FQhE®Öm31Ö1Úf¦±´:gÞ«Ñ]9Nÿäå·²{%CÓá|«Hi‰(ɨtº©¾÷Òn;UŠr1Ø`>(ï]oWEM§jŒ‰4UŸƒi=»»NæÖl3ƒu&{‰jr÷b!ïÁû]Ùn÷Ïæà¹Öœ r¬Õ£õe€ï[·ê±`ªidPóÂ…bŒÀŒž§ dø;^ªÃ)÷¶—ÎvåJ…ÖŠóçsªªG)ÅÅ‹YÊ{,3³B–ͻ֑Ç=YÜCà]NqöRÊÙËÞ–ææIPÞ#¸^ªë7öí™áÂ;*ïÎ ¼©Mfðˇ-Ù]º÷Ò«p»Bö=!ðŽ—¹$@û4…2ÀüÞ?¼JÛE8£‰ç }e6l3Å>xo°Þr³KQ§uùò&ÝRQW+po¢˜"2œt–ª²2°ê5Ë6'·â#V½Eu–i²XUDÄ0*ïm«PXf†%ûíµ¡Uý-%ªKÆ!UïmÑÖ}¦îèkl3š·ü±ŸÆúë;j“ð»ÜGMBŠb,Ù¼¤1± 5Æñ˜ž/–´eDk"r£IÔjXu–Šo?Ö™aX5FV[´ZsÝ탬xÓaŠqýØëz=ªîFõlïÜäS—ÏÁü©ÚPÞ;,½2Lfâ_—4C·´´ƒòT÷¤•??Øf|«Få½ÈÅ‚0$'Å â5P4Ÿkû¶÷üõ%±ÌWˆò_)¾ò½ÿ‰¢VÔjT÷R"«8h»í:–Q.Ê»pÿÿÙ{ó(ÉÒ³>óù–»GddDî½w«Å* ‰0ØF`‹„,³ƒ1ˆñ{<Ã0˜ð³Ø€2Æöc6m‰MƘEЛÁH¢µR/êVÓÝUÕUY™w¿÷ûæï.‘U­Vm-ª¥øÎ µTÙ™Ê̈Ê|îï>ïï-ï»ò¸KÞ¼§mBÚ&ÄAæZ:e¦¨:ç]8x§.)SAâ©àÝ’¦Š)¼Ñwu©ûξôë?“'S§Ì× ÷Zß³ïcú~%ÇóÄÓÂýú¬Oö÷£8¬µÌfþ VÝ~‹SfÊÂõ7š-[â %d[cªPìߦØßuØ_IÝ} hÝjÅpŸ,³žÿ ç_g€ŸÍ®ì~µà= ÆÝOkFe&ê**,ÄÿôüîASÒ.myZ›‰=Ki5Ê*ª6¤m~[Ѧ’6”¥7 ªª‰&ö²qZBP–Û€XWx(h=ÄJò.”?TDÒ|S Dí†Uûä}>«"o?ˆxäÏ]sŒE`¬¤²ÎuU†¬>ñï<в-Ú6äm„gk‚:§Q N˜ð´%ÍRàîû¤$,þ²¢Ê|jåñ‰àµ]E¤i|67Ð×Döê“Ns’ŒjÉ8s1D$kÄðPm;À»NŸ™G‡\87Ç'ÐäúTÏûfèd¢k›q©»—¸!i¿vÕfE› CÁþ®»˜ò}ØÚê–=Å×&/¹Ð<•ºÇ›”Q€2-^Xã_¬øÜ~ƒÂ ©„¯+<]ãy®U¦0ÜË @‡Óf‚QZçw{1…rà^†©— àîYEQÇCú®ƒ†H)×4SD£6£Gx¿x®&Öó¡ã=@‘ÛÓ©»ÒnXu{‡ñœÃÃ9'õ”»Î!´%þ÷YwK¯{Lp;ø:x_ÝÎ\Ö… ‘‘ÁÄ6drLݳ }ç~—¼wÊÌjòÞßað|M"{xwàî¡ø¤&$5N™±@ÜÁ»×´ü÷?üK¶!¯xÅ=lm][úüùØœ6^ÝU씸‚‚’€Ïýoº ëj"á¾Mg:‡%p¢FxïÚfL—¼«n`Õ,-‹ÃbaØÚ2ìì(æ63ŸÞ¼¿wžN—YƒûÞÿÊÏ3 ÷7SkÎú<»ÏÁx!wÞéÀ½ª ÉÔç–=Ÿ³O@½1¦Š‡O¶Ä~Cì·Ä~˲lØÙó8ØQãcêþ‡÷u“nö4¼ÏÉ,‚“È ž^ï #Ào>:Â{SºÔ=À¥îm |A†n<Œ–è¶AçÍïý ª¶$¾¡± mÀ/›•×´ý°j¯ÍxSO9xo5Ué¶fVÊg¢E—º{ˆF#Z=À{M|ɰª¥¨óIg­$ï><ïkϱ°ƒ×€-Å Í4Z»Ô½jøä|¿sôEÛÏÖ4Vã¥9•¯%#RwµliRMÕvðîù¤qB•´©¢Î=*åÊbìxo|f¡[¨4ÖDêaXÕXw·d¢o\òNæôŠFéA—éw¤‹……±ˆ©…X`îÒ÷\œÒf&jìmoO$M¦†ŠÈ‰vo jÆÕZ2›Î»TÞ§W9Àøåoþ9çº{û<±â‹Ïü""´.u>§ñ½ŠÆÓx²¦ð;xƒÜuÐ`réRè.y/À"ù½É§ómü17ñð¨<ŸÆ÷º -ÅaåQ”¼=¼ŸãèɆØÛ"Öb„÷Îwï—ôZúåL°xÙWr!Zpþý[ܶÿ(;{ç˜~ã‰[(µú¶ûíuλgA¹ô½,Üç_ʵ´±BMÚA›éïäþ¸¤‰ ÃEJš'CMäzâ+™~4$6³ê»K|ŽmBÖ)3ÖvÉ;†ÿé…;œ?_ð'r¥¯xÅsØÜ¼zÏdÏ?CdòÚ55s.‘ ð^Ò u&·Î/lÄ•û^¯$ïvé }pÞOöDºž÷¼Eå-Ó âKßwv\ú¾Ø¸þ9“gܯDC^Ÿ5¼¯á~}Ö烜[n‰ØÜôpÞsž;Ð6†Øoˆ‚1}÷<ÑyîzðÝ]âþ—G]ênšx´e#d€÷ä!}ëõñ 0–¸Ô}âÿýT÷YTã;po¬N™IGxØØi‰=IZ9p×V“7azBÓÁ{Y5‘ûžÂG!l´ ôBv»th=hÆ­©ãfU;úî•TêÞ¸ã B´à·Pw«ÔT¡¬Rlåj«ÖÇ9€»¶ I µÑÔû÷{u&^f´KåÒ{¯{ø>:mhRMy®3]ùØÆ`Äíà=êª"ëÕ佃÷>yÿýsð7®c»ø9ãj]úJA)±J`e7EÙº?­»ðšÞsBþG>ölÎÐó%â”Ó,Ƕ™þsíߦ §'h!˜E#¼[ Û[n÷ÀÕœ‹‘KÝ}SáWüoÙ CƒiÜ.€Røº¢ÑÚý³ÑÞƒ²eÆk\Ui¯Í4JÉ{ÙFÄÚA­KÝò:3¹‡äñÒi3Y³l&¼? ¦Úf>’œèTòn•™sÑ‚e>áÉt›Ýû6v¾ûܰ9u¸•dpà©Þ¤vïuÊŒ‚¢î.Pd€ŽªØGOÝËmqÊò`„%–ðø Ë”§à½ÆsC«DäÄL$B8x_qÞ͉ƒö¶uoSËÓÉûbÑû¼÷yÕÕ–7 ¸¯S÷5¼DÀý¥@¿†ûõ¹.ð5ñ%Úg]w‰{×ø’§´û-Iز³­0í2“ø.uÿ¡‚›r3Ý£Wfæò¼ŸÜ€_6ï9rnþð¹Z|Ïsq.ôÝn˨='0J"jK»ì:¿+=h3ñ-–Ø“¨Ò»¶ iµKÝSA“Jlë3•Ú'Ö Ùhd3ª3¹ˆuK¬ÅJòî±Ñ-¥’èßÝÑÎ0¬º’¼Ï§ðI_ÿ/üä;8ó0-”©äùo}Çà³+Z¼¶¦lªv\X¤mCÐä˜*¡© ¤"!¬ ÚT9mFŽàÞ„žƒÚTSåN›©•‡©íà»[{:y¿Xû$Z¸‹@¯ ¬^Oú.~¸‚Ð?µ# VZ©Ü7Ù]úÞZš ð~;?•¼ÏWÓõʉ(4Fk&ú4Ø5ä'’Åž{}îuÚL?´z5ç%ÿí÷(ïØ„D3=zŒo•ÿºÏ3/"rQŒà®5^Y¾{8ç] áÅœÆjï~Œñä¼&>å»ÝÃõ»;ß}pÞW4møp\`DÓtÚŒx+Äe!zdà/ïøÒhÎÑrÆÎþ9^ús¿…°v„w1¾CžGX_àM¼¯:ïùqä>âGUä£7ša«jßG߃{DÄ^KdGm&/\SKâ 6<×½¿ê¼»¦ï”2ÓÃ{îEÑç wÞ9ã¶Û®Þ5‰M†Ý,<Æ­àœò¾aÆ;efsò¿ïáy‚¦±ìíºÄý_|sH0ƒ`v¶AŸo1Mïµq©û?Â{èà}º'g®ãâ£wÝ­­¯<ø$FŽ@ÑF SKtÖ)3K…¨Fß=ñ #¸+£‰¤”™6´8p7:e¦KÝE«) I©nE+œóÞh>õßÁß~WK·š¼OCAìŸNÞ?úËÿˆ~òÌÅa ¾çýñ;)Úpwml%¨„?|ö^šÓ¦‚J;x¯MÅxiM³t•á}²#¨:x¯3J:€éƒ ¾£‘ÌB÷ù+ÎûÅbLÝxïª"'×ó“=•îÊKÂ|£4ÖíÆ"AHKðü’ö—„KÞ;xï/&z87KISj&[ý…†@Õ#ܧKÉì.÷úüº×ÁOýƒkû.Æ›T±Ïf¾ä6þ±«m;xo"r/¢á Ìøª¢iõ«e3j3uê‘{Ñ་ÀR!Öó(‹¸kšé´™Îy¯Ÿ°óÝÝvÕ²á}׃ãºÓpñÉb=´%Nƒ»ÁuØ_ ²8æÂ“ ¾÷Ͼ‘­€»wúïZÞFˆÐ’LÓÞÑ-]·y¸ä]Ä–*òI¦éÐ4ST¡ƒóYµôœ»ÞA:¥[êS Ÿ¼‰¸S3I¡.´×ø"I–©Sf2ŸÚó¨}Ê÷Ùôg—šf©‡¶™J9€Wˆ!y÷ÄÚ] ØvôÝ­-GmæZ“wñÍ9Á8»î¬lìm…Ü{÷ÝZ_ö_ Ú\D‚‰v 1^c Üs_KæÔO<0ø]]ä,‚Èýsv%$ÏýÏ÷SÞ±É=³c~löh¤6ÈÖPU>¹×Á;á¼Û\PoHÞx—5u¦É6âA›QaKDÊ6 öhÅyž&ê6úúRS”n`5m¤pÛpé’÷‹çމ½Y7'¢ðÅåúúkž|5ÙsR“°±8F?îô3«·cW½ªöÉý´4±FO¬ïR÷ì0¦Ðá¼ËÈPE>Qœ“ŒÉ{VÆCMdîGÃ×xj`ÕÆlx=¼syònÆä½ß‘(˃žpÏ=S´–L§×¶œpšŸ¼"å¯ñf\WSå´bÒÞë®e¦ ¤.=X‚©$, IB§Í8x·KƒM[Ò´tðn…bsÁ.L!_þ×Ïòµ_0ÿ¤mÊÒpûí ·Ý–t³C7'¸_‹.³†õ5¼X'ïÏäû¯á~}ÀmܘXö÷u·›€.µ²üòÛeyrÂsž;Á}üN©‚åYKzÑ5Î$›’Y§¬j3Íüõ—Àüî5|~jáÛjÜ-ãvVþ¬k’÷ÆÕDÆ3ˆ=‰¶¢óÝÀ' Îg’¦øÒsÚLì)’nXUÎ{0TDFZR5Ñxк-«ú’ḏ¨ ¸tí¼ð“o玃ˆ“óðÄÿóDíÑ( šÞ½¦FT–ƺ昲 œÔ@›BU8hïÞ†ûº›¥Scú¦™Ú÷­µ™Ì]$ÔÊ#ÚCên¬û~»-« Õ%Û†n!“«"¯¹q&•PwߨKá½ÿ§êRøÄiPXÜóh,ì=±Ø&S˜*÷¹ØrJµ­Óe&À+ڌ׃{›×xQy1ÚäöYÊOÍ^GíFE‹Õ‚†äÚi3¹eFZÈMä´™Öi3~ZR§ÙÄ{ê%AI„DH.˜pÐfžèµ™:&ò»jR%»šÈˆ¢ I›d¬ó’÷c-ð‘hÄSÎFs²(æ(ñ“oü{ƒQ®ýHùíðò¬óÔÚ2 PÓÖUG*H›„\EÃÀªŽêÈÃ$’ìɘ´rÞ{^FCMd„D¸Õ² I{xWñ°<«×fVVµõÝ…Ê*¼?ÿó~‰wÿærç“kz~ÿ?ÅË_ÑàS «Íò6žÛŒ¨k˜qs&… ¾·تۖºïÀ= ËÞw³„öÄÍâlîºÙ—DÂÌjl ø¤Ü«ª¥, »»!ûûÑMûûcí¹¯á}}n²‹ƒõPíGÎIÉÁKÜÝV`ÁüÑŒGÞwÈbS²³Å Ì Ã.Až Ò¹ =ãgfû>¡½Ìy×{×· 0P~Ï%àÞ^~ýŸw¾û)x–ij$žDYÐV£¬Æ³N!R÷TPFï6«ÆžB¬$ïÆºŠÈ>y¯Kî¢ñدüë¹ý äöƒˆý­€ÿü¼÷!j[ Z¥0RºÔ§ÌˆÊbŒ¤2¾[d-:-0—$ïu ˜HA½½öÞõ†Â«íï"·Cê>ë–õ^{  ñÊêSPt Þµ«è¼êÔýï¦îj1ä)•™á¡F˜ï=xaí Ñð¿‚ý^1€ûDCµ¤KÞ%a8Þ˜j°¸Ç¼éï×’¼O~&eï9ðÓ÷¾‚‚ (”*=&ï9Ѽ{yM#4™‰Rb\Ud}N»äݺÁË̱¡ ñ}"…‰;°ePfò&açÃEVQ:e¦¨"²Ö xNý.y·N› • ੽ ¥þ„/|÷œ,Žùµ?x¹û?S¸×#=‚»ÅÁûÆ5.i/»~àR÷Uß]]îÝ2£S@oè†,]d,>ÖKííÒ÷ea ~Ó‰R÷‰†²SfvN÷ºx¦Šûk_FF| Ú-µðFx·§±•«O¬|ß%¸aï¾óÝ«Ü'³‘øÎypæ½6#(šdÐf"U M3}ê^TѺox°»­8{.åâ¹c.>yÌÁö첯gcãwyù›Žù…æKàÝ àn•»ëÑZåj }ðEýì"´”a@›(TØ’^p𞇗¬*´ëx¯bêÊ#7ãvÕ-%ˆíè»/óÄ9ñ:æ`Þ• "Ÿå%ÊŒ±®ç=‘–·¼åýlnz|ÞçÝÍlvå-3ýóÙ?wÁÕ†ncªŽÈ”k“©ði[…^6§àãúÝ»¶™¼´¨²‡wWg:™6c7k°@¼„­iÈfTñë¿^ð²—…(%Pê٩ˬÏÞ×ç#îW?æîÿjÎt*™nüÁ,yÿ#‡lL[曆ù¦a²CòÞ»Û¢ì’÷¹ 9¸÷Éû²SfÚÖ=¶¶®íój—­[{‰¸\™éÖ;5°dHÞiacnH<Ù%ïjHÞ ¥±˜\Ц’ªp š6;e&ö'¹B¶npu1(3±–]êî ÞZ¿è!Š×ß ÀÉIÅÛÞv†‡:d: ØØðùÛ¯úm^øÉwt¾{DÝdm f÷V)„²xu(-¢²Ð@m=*ãc¬À¤—j3Š:Ðø5O©ÍL´À«À«¥[ “KjåáO$“ÖmF;퉶ÓX{å@êšpb)!ps°î+);’q0²÷M c\ „ùYl]º® ×+C©“•Ô}ªá¤ûóí…û0× ï‹ÿ·ÞÚPá ·úhQÔxƒ6“™_Wˆ#KYßåÓ.ü¬¢YMÝ;x×aÓé!’²k›±­ïÚfj×ÀÒªFZQä£63hM|ÜÇMØx´æ¡.ò)Ÿü+ÆîÉÄãèȰ¿¿àÞ{·xý/uOôÊ’¥V)Œv¿øÝóâC^¹Ô=÷£ÁÍ/ÀpR ò¹Ž¨ŸRCêžn£jZ&´¥U3?æ6lç»ÓÁ{LV»ž÷^›‰mFࣻMñeðž(K¬,¿÷{¢”D)Áç}ÞÝL&Ü}ÿûü8à†wEºåZ­{äjôÞƒeá~Ît-2¶°´CêžUaQ…¥^2¤ï³=·%uÃbá†òö<¦^Ã©O¬k!×ð¾>¦çƒ Û^oz¿†ûwž÷¼‡¸p¡e¹¬8>þ8~í ïäG>d±3ß4,6 ³mI¸:ê” ²v©ûr.„7$ï¡à]÷ðn\—öÕž;þi…é*)õåÊÌ)x·P©ÒwkñnCìÉn`UÎûD°–ÈZšLPv šúÔ=ñé‰tÙªÞÅØ6ÓxðªµôvçyðÁCÞö¶'xÇ;Î1úÜqq{÷øÆ´FÄ.uï•™þa|‰©¤kÊ©,²2TƧ6Ô mŠÓf*§ËÔf²øµpM3+ðÞmðj×½*éRw¿mÙÕ0”Ú'ï¡’ò4ù ükà ñqçÝj-¡#¬+NûîzÞ%°Õ{áÒw÷ÁÜ?ÿ6ËóqLسnÓD-3=Ä5D‚…{n&£óþ§À'Üq…w§<Ë7~ÆÿANDw Ü%fèú.tè’wã´U´Þ£È%ïÝÕð0w¾{Ÿº´AP!hMHib69½ i:øîÎy?_úeDÓ„LãÞ_òC/áíßüFŠ"¢ªÌïum©*Ã|R|³¤ö<·ÐX7¬ZzˆÈR÷ÕªÈYä ¡OÝ}¡­»˜VáÝZWUWU†4­yç;Ï ©ûw©]Dm‘]òÞêeFi¾S?Ìw—ÈÊ Kƒ¬ µõ¨‡*LïU;*3s-ð+h–š6µ™d[tÚŒW òTckA­\²4-³Þ{@ß!ꮓúšHÛ9ïW îûg¸7òé•í’]t÷¿§ȧ¼·#¸#[hZæ‰?¨1»äýà@Dý°êØó¾³p¯Ac`±9&ïWš¾¿è¿À×}Ù7Qá“’¸M¶´®i¦»²àpHÙƒ¦Ä/*Ê" e&¦ êÌùîmŸº[—DßÂѺ6Óªöð*×4j5 ¬ÎbˆüÓCÅŸø‰ ªÊP–íeð.„âÛ_øeTÚG«_W¸%]ò^É{ÞŽ©{îGA9$ïÕÒ’÷ÞKPE>!’¬KÞ³*Æ”rHÝ'š®þ±ß®¹ä½=¼O” §áýÒԽ߰ú9Ÿsw×ó^s×]3îºkö´àþÊ£ÿÊÆLu׆vxØVÐ4š² ÈXQgÚˆTÆxË »t36¶k‘±¥Àž˜Sλ.,º0ƒ6³˜î=ÀO`¸×åöLÝÔÉûÚs_Ãûú|„ƒûîÿêÎÞòä“ {{î¯gÛBYJŽáäÄr|l)Šv÷ùÜ U‘–±îЂt!wz4EkÁÖLm3õžãíÞ'“«Kß?å»+ª£ÆMQš¬à[¾ð"/zÁÖЀ2 îÜJyÁÿ¹á ¾rimŸ¼kOxm§Í²®"2éúÚ¸ä}™ ÊÂ?î«U‘³îŽƒKÝÅ©åL½V² ï/zÑƸ3)ÿñÛH¥øþÍODÖÙWcYÛÞÿ晚¿ý<{[–ò|0$ïºl¨‡­ &wÊL›‚A «S-ðkI%ͲJõ}v<ÁD D ^-8I5m£P‘ZIÞ/i›ñÆ[ˆ®ÐçZÕÛeíu§Íðð®8Ý%îÛ®ÿÚôÉ{½ ú%Tð³¾Ï÷vêLØ©1ûûîZ¡Xhç»oxß¼Bxÿì¿ýê¡ÏÛ OÁ»¢Å»GÁ˜¼‹¥¥*|Ê*À/o#ªÊ£NÝ£µØÛ¨k™q¾{a"J šò&ÆÚ€ Áw´ìj"C6c»ä©ï¾ûâí¡¹d5}/Ë–y0å;<7¼¬UƒV Rš!uoµrÝå¾{N–Ù„\ŽÉ{æ¼·iµ±Û/ œ.SE>Š“Þ‹2¤)õ¼ïyã°j_™æÝvÕ&á§ß ßÿ|÷\®ÖDJ|ÂKj |ÎçÜujA“Ö’[nyúÖoVÓt©û*À×µGS;xÏeä†V›È ìê„e‰]‚Y…÷B¸ªH±R98ï@.˜ßmXÌFmfsó.yßßÓ„áÍù{cí¹¯á}}Ö྆û¿¢sß}%BÀÞžšešÆÒ4ŠãcËɉåäÄ rîìHæsç½ïnƒ;]¦OÞ#å´™Ä÷ºaÙÝUƒó®÷Fpo[ˆÂ+÷ÞÿÁëá̃…+z·]òþðoòY/~ùÐŒb,ÌCCz’ð§ÿ¤á¾I;ÈË,œ¸V‡xש{ìIª®"r¢ÜûÖËQ&¨Je&^©ŠœuCã‚&V|÷Ká}ào¿}ƒ,«Éó†B`<=$ï¶üÌAíþ¶a?qooÎó]åQYl!¨Œ¶ÁävLÞ•KÝE¢˜tÉ{ï½SBí{L´`â ª´ÓfRMÓj¦û ð¾ê¼û7àŽý#3›Üu×!‘ô)s‰¹T™YÕf:Ÿš—¬@| ñ,{x¯¯(ü *›£óÔZ“·ÌfÚ-’ŠZ[ðÝEg óÙ˜ºÏ® …ï ~ î|i@…OND…? º¢E`/ƒ÷B†d:”eÚ1yoc÷ütÉ{!C§ÎtM4}]¶qç¼ÚLß ÔûîývÕ²ŒØŒ!XXjxñ‹·ºäÝÕÖµ¥,[ªÊðÚþb*ÏGËf€÷PíR÷âñÜ®¥œ¸®óÞpÏìiß]ùTÚ§Ž<šÐ#@r¦pm3ERùF„õ}&º%BžZÐÔ'ï¾VÌÂñNBˆ$D"xê©f³àªT?/ÿ t4^õàÞ¶ŠªñiMUùN…j# é¼÷ÆÅK©Ä¦nžÄæÂUEŠ1yWón–‚że17lmÉû|;SXlÀÆôæþ¿>kx_Ÿ³s3Þ2»Zïþ#¡1gwWaŒj!77t·-,—.uÏs· ) %Û[’ùfËÎ6Ho÷ÖBì Ê=·)p„wÍÞžÓL&A—vvð®µKE¯äœ}°àì%´.cÿê[^ÄÜã¼ï„–¨Õ̶{¼ç@w;;¹Í¾{ìINÊÓÉ{f,¡…&Ь*3cê{‚¨ƒýxuXõÒä=}ÛoÑ<úR0KÁ'}’ÛöX–-›ßZ`=ø®¿uûÞ5£Î|Œ…½Ä²—X²£ˆåaÄW>ÜòÚE®®ÛýGÖŽðî;xŸhÁT ȼ7K—®ë©bâ&NjîྲྀÞx^Ó"ÈTjqþ|Ϋ_myë[O¸å6ªõ(²õXe—€»þÖì=¼O¶]ñIÝBÙ¼d m…‚¬a¢]}ŸºÃÑ ¯~7¨Úß-2-lL`1sj—¸‚¯;zéë†Ô½o–éQýg~í«ùš—¿ærx'¤¶Þ ÌÐ2&ï&B§õ¼gɨÍBžV-Ú˜ø? ß[BÑ)3Æ2øîžÐUHHBÏÍ,ô°;Ѱ·wùÕIÛZÂ×´¼éyvPf´jвá«úüÌÝ_M«ÕñV Ò:a©Fx/‚p€w³\wJÞû­®ýÀjUù®*2ˆÝ…¥Dt 27VE¶1‹.连~»ªàƼX?íÌï£÷¸÷²ŒÄ€…ªñx¯kÒ:u¦OÞg¥¡]ZìIß"Óizyç¼ÓûpÉ{á’÷ùs ‹EËö6£:3q”[›7ïï+Ñe®æ÷çú¬á}}Öç†þ¥w®îŸ é}Ÿ¸[ëº×Û–Þ³ Ž¡®=êÚÒ4†ƒŸí-Áî– À[3|€î”™þãllHööÔuÝúýŽ_5œy° ¿PwÊŒ`zþ7ù¢Ïú¢!!îá=0šYë~±¤?÷ ÉKïéàÝU#ÆÞØ4{+b)W6´W…ºKÝõ໋F³RûÆÑxÄz„ú>yßø'A (.Tî^º !? Ùh}ÜÅÐ^bØK ?îàÝ\Hù¸7\äÏ_¾¶» ÊÚN›±ÔÆ)3[U•À¯Uª±Æ¹îI—¼µÀ«ÍR¯ 2m{Ã^[Mcø‰Ÿh)Kw×&ÙД¼/Aé’ð¬<ëÀý¹çŠŠ±Õ¤KÑ1ä®–ÔõUV`*È4¤5Síî¢5@Ó¸×ôöö%¾»“÷$vóÁT^~od†KÝ{eæð—y@<ë;)ÒŸüg/ø¶_º ÞEáZfÊ"À´rð¸kbÓ1yÏâhh›™tÊL„àĸä½4§‡Uû;@Qï»w©»1à­ÀûªôTJð3_ôÕXO Ê̼ÿóøâ€óÕ¯úGćÿâ{oqK²,Û K9!ñ©Ô½ Ú³vVÕá¼7‘ÒòÞëÒ£,r?b_»×g¿ )Íc–…KÞÁàW“wïû=úÛ÷´¨•n‰GíR÷ÖwCâµG]{N™Q®»?@â•-Í Ø¥»ÛS…ÍÆä½÷ÞUá´™Iâ|÷y—¼omÉû|r}»0žip¿šß}볆÷õYŸéy*õçÃMÍYUf’Džï²¤©Óhz7vw×çàÀ?u;×ZCM-˜%§áÝ÷Ir}Wg,8û@áZf¬€ÇüÁOcîuÚÎ ¼O›‡N¿ó‰u)í‰ ZÑeÜvÕ±"²_KhÝÀjÞ%ïéÊÀªè“wÉT Nj—¼çKE#4{¸'ZpT9mÆäŠdìkÏ›ï¯}‰ï vv$RJî­ÇI*ѾóÒ3÷%°¬ÀÄpÜ×{6Ý?=Óa4P gȤYµÖÃ;5|ñÃûþg÷¼LöÅ©ZÒùƒï¾š¼‡!ln|ð¯çùölâ»aaëqòúœƒ£wsfûSÈN&duBqò¶ÿ[ò-L/ƒ÷ (x¯çj"MDìIÒLwÉ»&[ÄCÛÌ [D{m¦l»nw- »‹Åi@×ñî4Íâ•:Oÿé·àþË‹ßÈíž”™ßy÷ 8nq¾rOÝðøÖo¸šßå‰äsÉ«ˆ¥œ°T—Ã{[ÚRyyò®†ä=+º¦™Ê¥ðy3Ñ Í)e&ízÞ‡}ájò~ã9£Ýœ2S÷ág›ÔGÝxàßyïÆmR-lȶtC¨N›v)0i—¼g»4ƒïÞ;ﺰ,æ–ŰX¸€í-ç½oN nÎ߉ëZÈ5¼¯Ïú<ëRøñ>7#ÜKé~kËžïºÖ”¥R÷º¶Ä±bß¿ì@+ÐJ†7v‰È¿û­š3œyÐ %n׿ÏtSó%ŸSCu?ñ½§àý2ö<J`iYÜ)\êî¯v¼»åL}‹Jh-‘±ˆRœVM:ßÝG¹zÌÞCMͪïÎéäý9ÏùU~äG^ÌgöÞði=ñÞÚ]yx‚Ÿþ¶‚übÈò°ŒiåR÷åaLÜ_8Ƙ 9\Ì!í¨4k1©u=ïZn:pŸ(AY_¹:ÈZû2#º%M¯–x•8•̶Ù÷ûî«Y,$Mã¾'A$)[Ÿ4WèCPžƒö¨…°‚G_Ñ&pÜûª2“8åCõÉ;P7P•¸·¤ÒlKШSÊLÛÂlæÒ÷Å|Ü»äÝ÷¯ìk…EXWøäBî<>áŒÙåp9!+²zBq1*¾'û|þQüæÞÉÜûW…O•ûØV¸¶–6fáY.¦ºKÞ½ÜQu«r÷ÂÄ+¾»±Î(#žKÞ-xjôÝŸ ÞýoÎùÞoµß ª>þ;pf¾ÃùÆûWþÙóùº¿?*ûÅoðï«Xª.y—1¹Š([WÙf–´ŽIÕ¸]µOÞTn«kë‘ç.y·¥ ÷"ÍpW¨ß Ûûîi3ŸrYò~£Î]ñ0ú ÀZv¨…”ãfBªÖwÚ©3¥ (m€§‰0ØÊºÔ=˜´k·ê*#O%ï8ПEnè}>7.}_¶¶%‹ ð7s µ÷5¼¯Ïú¬/nÜ_/à+ånŸxÊ¿²Æ¸ôýZW˜º—œ}° =Wó/~o{ë’w¾ë3N%AOûýy÷C$»w³9…­9+É»@‡B­,k %4®|uPµOÞg+ÊÌjòž6]E$§µ™;n ¨¶=~ög! %Ÿöi;¼äß6¤g›®7N°7±üÙcÛáx'! œï~ÿC1[MÉc¸ÿÉœ|m3h3uá”™Iî.yÃÀêd§Û@Ú¹Ï^§Í„ö4¼gmËWü ¼îµ‹k~ÎÚvvä cY ÓM¬T\8ìj&cˆºäýÍwLwÝëp9:ƒ23Õ@ëR÷zÐg:po+ÈœóNÖÔŠƒƒ>uw¯Ù8Ãp´{­_ÃEnaÖ ¬EŸ ŽNx<¾übHV'duÂ#ÿ×Ñðï³Aƒ¦$ JsÈ’÷Fèa`5Òu&œïÞFƒïžxrVÎy_ÑfzßÝZ—®‡ZRdÿv9 IDATÑîÆ‚–n·¯Ð¼ôüïßú£ßb´äì¯[ž vx×áKxrk›óÕ_÷—ÿýZÊÉ©ä½ÔdË0 ½`Éê˜Ô\ž¼´£ïÞi3¢²äAÄæÊ]¡^›9îà}#CêÞ'ïþ ÝwÿøÞž‡Ô†ÚxHiÂuô[#°­ meœRg é5-"÷׸,W•™±š¶M•ƒwÜ¿Y—¼ß{oH][vw] ÀbnØÞ’×¼¸îC•º¯Á} ïë³>ëó,‚{)Ÿ ìŸÙóË¿ïÀýÌécm&…eq«`1·Ì¦beA“•™NU‰º%MwÝå1N7ÍÐµÌ žý ¼«`ü8ÃÛxÁ 6©*C’(~8ã8óžjPf~þ_kÚeÀs"5¼kat£ùè ?¿ÿs!ç§t…Xúä½ÓfúíªÓܧ}ÛLMªI`ÒÕDN<î^-Ø^ŒÊÌԇæåÂ…óÀµÃ»R°³£ÆY -)j=€;Â)3ßw¾‹"SêS¤#!ëôðÞš‘é+{x7¤]”ŸÖl&Ó°OÝÅU¥ëèÜýøûØ´.yä··¸ãèaš´áL¸KzâR÷¬IpîüÇìy¼<þKL)ñÒ› ÊÜÁ{åûäm„–šØ“Ô©tḚ̂]5b[‹®QRuê}únLp Þ7ºEMO–Á)xW²SˆžB›Ùúú^õ}áYzÃ-ܾ|„³ú£xÒls¾vÉ»ó‘.¹™¥¦î!§2¤ò}JÐ4’6µ¤UBæ¹­¨yèÚfjåðÞ;ïªlÉü˜[5— ¬>ÖÁûbƒ•…oð“_ûi×ÿó%üÍ’dG—¥ðMå÷à[i%ÆHŠ6¤n=Ê6 n>ã3ïa1w­#ýÀªZi™é÷°[Òt÷Ý>Z‹•ŽwE^»Öœ§‚÷@­øîÝcÛc±1£®]§ö­·Füê{jμ·†Òðc?0cošsî\ÄÁ%[‰ey3]|þgœãó?ãÒ'®KÞS×6Sš6ÔÝ&Q÷ðk÷°™d¢ ‰vC«!®iÆ«;‹Ñ‰Þèª"/\¸ÀÏÿBÆ—~I|Íßs­]“@”Œ‰»µ |øÚßÇ ¤6î‘D@Ñ`ÜL2E ÓiwÇ@C]É» à±lÞ³ÀÖ8K»Ç:"w:Å»þðc¹óø­¨ãcΘ]ò3vHÝŸüÎ'/{¿_Ënå¥Å9šTcR9$ïýÒ¦¹'‘¢Î$u¦±6j"W“÷Sàn;pg|ÍM}ˆ”¤¬ÃËá={îû}ñ“¼âµoBø–Ç_ÀVûζ;üá¹/áüb‹óÍîxÿS~/>'{5?*ˆ¥šPÈZy”Ê)3¦×fÄimfªí0¬š­$ï^U£}ÍÄkÝëSïi×4³˜Á$ê’÷6¢óœ*Õâ•5Ù-1ÂX¤èÆT…m«°­À´’ªõ]únœ:SŠ€EÒu·KÈJ;&ïÝvÕ6U˜\!–öTÇûÝw…Šèvaìﻀ›ówÎÚs_Ÿ5¼¯Ïú|ˆÿézöŸ 9Oy_:m¦*ôí—&ï.y¡Þ¥î¿uÉ{ڌߴ¼ýâŸrxáVœy|?ìµÓg´7‚»^õËÝ•R3>¦ûÐÛ¼í6£*Ÿýn¦!¯:ï5¤ ²hxÁ߇û~ìÆ½o}ëC„¡u™ãcÔÑ %wvƒª}ê¾|Ê÷oR7Œ*3ƒ,Œƒ÷ÈÕDÞêµ´¹î’wÊød6F)¤«C ;e¦$ÚÁúêž>yïUûש’®~pªOïÕÚÝRÏg™¹<欿ë\÷f‹3Ïâi¿'½ó^(ï­§h/ZÚÔRTñe«{ª†U‹˜¼ˆ°" /5[IÿÚäÔ†Õezoâ•ä}v–©_0L“³!ÉâØ¥î]â.¥Á–N—i[…1’Êø”m0¸ï–L¤÷‰€‹åŠó¾’¼Ï7áp©†aÕº°CêÞxx7íï“5¸¯ÏÞ×g}>D?lŸî‡êÍ>Tûþ÷×<ïyÉw÷ûž¼þâŸïsØZ¸ZÀØ“øBâ¯4ÍXëR÷»îòOõÔoNÀGâ4¸÷ÉûЉ~‰UôÜçºMŽmëšz~ögkžxO …á·~u‡Ù¤¡¸rëtÔeú_/çýi™þ`Fò*3$ïU¡Ùî }¢‰x]ÛÌîSùî]êÞvm+þ¸¤ÉïÔ™¦¹­¯O.ö<Á|s÷¿þÃ@‹³Kêx÷;xïÁ]ƒõGef¢Ý÷¹o› ˜ú–“¬‚¦î”™†YlÙœÜØ¿O%DÅEî{Û Ù?z;êè„:35YêR÷‹ÿßò¾“jšT#2; ­f&¦0‘Î0¹¦ÎM¦)­ß¥î¢ƒ÷¾ã=¢l# 1Qð²Ÿkø½¿«‡×­ƒw9¦î¼Ká’÷£ómkØßÙyùÜû«ï#>Éxôoc&Fžsfó^Î×[\8^žÞ;罇wmkÚ̺Õ6&ÕÞKP)ŸX¹VüIV„äEÄÖŽCÕÝr«±tàÞoW]ÌÜ×úœjœ¹ÞãU5ž®9Ùšbpà. BZhAµ-¶”m€mÅ Ì”& i;›‹I„p£+e· iE›ÑF2ŸÀÁߨrÚŒ1QlÜ;&ïumÙÚÒH)nÊß%l¦h}Öð¾>ë³>7è\oòW ÷mkÙÚzøù¾ôÚL¯Î²ƒvN;ïwß=Âûd"ÙÛÓL…| 5&¸‚ŸhJ ^÷vÁ™÷TœyoÅ}oÞ¥µ°=±,ê …0º÷ÀÛê ~i¦.y7© ®úä]v©ûøØÛ…i°â»×àUb¨LôVVý¶Ô™ßýÝGø›óN„¸>°ð<˜Ïaÿëm÷$ ð¼Oc§ìLVÀÝhѨÌL•»6ª¶û÷6|8¹P¹2÷¬†¬f6·ÌoàVʃ_~r{Žºxí…u|‚:>áŒÝ#?¯WR÷æƒÂ;)ØBPTn;g¨Í4uªÜÀjä†Uçž’÷^›):mf¢Ü=‘Õô}êƒZi™Y…÷@Þþ燼å-gùŽŸÞäîÆÄ'ÉQÊr—ùñgÛÞøè?äüb‹ô ?øk¯OÞKåà|º¼€ÉܾT&¤^Bfb7¨ª…SËV4[;nÓí„ñ®P¼î½ïnŒëàŸ­¤ï×sâŸOÔ¤·&“MC-=„´a±µ@6Y;ï½n=ãfšZB^2™†Lƒã•»dÐfL*ØÞÍ)ÜrÚÌT=k~¬u™õYÃûú¬ÏGÐÅÁõ Õ>“g1·l-œ:“ø+žú À©»«ËTJ°·§ñ¼ëØ3ïu®û…‡¶:o^×ã­ò"¿†„+m 5 ”Rƒ.ã|w—ºo&0 ]Ýb¿¤©Ví—)óé¨ÍømËÿñ£$‰B)Á§ú×ý½^i 0ŽÀ ­té{—ºO}—dÉ»‚`eXuª_ ÁØmN^Bµ’¼'76y_z;¼$ñxßczwutÌãáíd'.uO¾yÚÑûÍm¡P¦%31ž»TŸ(êÌ£Î4yÐ-gò8•¼_ì”Oj”€X¸‹—¡–Ô-Õàƒ÷/¼ó‡Üÿ1ßôÝw¿PQÿÐ!ÉQÊ{í¹Ìš÷£–Çœõwx²Ùæâ«®ìÂùûŠÏåËä_8x—>qzž6uÎ{tê23W±r¾{Ð9ïy³µoÑr¼°ì;í—y ÂàÝÓî.×HÞëñ+ɧ!²4,0RR Ÿ¶U¨¦EÕ-q5‘Ñ4µ‚¬„¬b¢B§Ítƒ¨Þ%ÚL(-›S÷÷j>…W½ò ¿ò+{ϪŸóìçöS½} ôkx_ŸõYŸ5ÜßÐ__ñåòžûïeká!ËT—1ugHßg³ëKËÞô®–3ï­8óžŠjy˨ÞT×yK:mai`)˜n­8廙÷Ê)3m QÄ©ä}uË(ÀbÓÁ{ж<ÿc¶h[Ë“OfüÅ_œÇ÷Ÿú©·]Ó§(>ÁBd îiÒBc]PÝJD>¦þ—&ïFŽà¯t¼{ÁXÅI^t‘±a36lNà{þ|ËW^ß·w÷‡ßI}çs)õ…utŒ::¦ÊùdEÂá}ÐÓûÉ$ ZKÞFD^EäIÊ\Pw^|¶“hIâYbŰ]µVíwôÉ{¯ÍL/i)‘d÷²½õÖ„å²fo;eoKQ¥$SÎ×[,–ÇÈ“c~éèÕœ{õcWwa£\ò> ¦SfšLŠ˜Ô·«Æª&”.yW’÷í…KÞ9^XöwÒ•ÔÝ·GbszýÉûsÿøeE¶Qv½îÂ`)äïmKÓt=ïM×f”WWLd¯Í8ï]—s2j3Û;–ùÄ-\šOAí*¾ó;/òíß¾ù¬ø~­µ—þ,_ÃüÞ×g}Öç#î{_ÿZ‡j?ØÙêÔ™tç¤ïwïšf\òn!«@Ô®"rߺä=±Ì'×ÿ.½þ—{Î<ìS_ÈPÇ'èãÎØÝ®ÛýÊ"þ:õhRíÚG ‰i%ŸX7ÄZq>§[Ðäºß§+}çÃÀj×63Qî.Ñ¥ÚÌÓ—½ìqΞmØÛ÷¸ÿ_{|ÌÅ”?}ó'°Huƒªí6ŸØž¼ºïO§ÍìräR÷´kš©cÒÚ « ­ˆµÄC iê`¨Š\̼{†a`uuXuÞ•t|½Éûo·Ø»"°-¢UˆÒ-d2±„TÞbÌðm­hZ ™«e%ëà]9‡Ý¥ï¯´ˆlìyß¼g%y߀h_ íKÏp¿ÖZÈ5¬¯á}}Ög}րŠϕ¦÷[[÷#凮5ç½÷7¼åw ^óšÃgà›ÔBjH<Á†ï–3õm3~ óÚÈ%ïRº‹–‰'¨RÁΖûóà›n°ñ•¯ü(ò¼&˲¬f6 88¸zELÛÜ;x·T ÚŒÉ{m™í+6¼ç½Kß½N-š†]òŽKÝmpºa…¼\ò>‹­{$–Íë„÷­ÿ÷m|×·ÜÉ»ÞP_Ȩ/dÝb¦cNÚéIÂÉ[®LƒhRM³Ô4™¦-µñØ–…IÚÌ5ÍuHf#ö;ß=Äi3jXÐÔ·#Å¢ÏÊ)ß¡>À—úÚ×ñÆ7¦ìï+âXà'’££”w¼çùì>yY!OŽ8ëïþÌÕß:QSa£Þ%ïY•y ™“ëˆmÕ+‰>å»÷«þTI×ó1’Ã:bkc¼¸¢ƒ÷ük¤ˆOÿ9°J€mÁ—N™‘–vª°@QXl#0F:h¯Á”ÂÝáJ§ieõ©ä}"À«,º´´©`sÃ2ŸZ³1yßûÌ9ú(ãü’¿8xÖ‚ûÎ×ð¾>ÏâóÁnõoª¿è×ú¶+ù|Ö?Xžý¯«+}oöÆpÐqë-ﻡ­9§>ç¿Ø"™>Áî!{}ò¾R¹»ÛzÛuÇ/ ÉyEíJò>ƒ0€pïúw³O§Æ-¡’+ðnºÔ]7•Û¸‘ùôç½KßÃxôÚ'ÊÁj%@§7غºÈ†‰g˜%ÜoDãLêíP†ì ÅcR—¼“çŠüPpáíW¾0¬×fêÌ£Î=l+Ø÷Ìï®mÆ¥îI¯ëyÆä½ÆUDöð> @U mU3ÛZIÝç_ëÙüšÿÎk~ò£x÷»êóÿ{g#Ùyžçç?[UZ{Ÿ©§‡”(ÇQ4”b¢8 xA –í¢ œÀ‰‘ G0‚,FÄá« Q]pŒJd'„" PÌD²#Z¦Mh(‰R”<&5ä,½Ôv¶?ÿ©¥›Í™îꮞnò}€ƒ°X]]§¦ºžóõû}_¿¬¼»I3·“6ý£]à\ÿÛ»ü¥_sò>VÈL@-èS |jWÎyéÛÚdDäx™V ³gÊLQ^Æbsp^æ…‚.\p·aè¶Ìþ·o¬m?L~¼Ým¼Ým^ÏWæ>O©W%¦G ½rLdâòî½(fX©âÀPÅŸ,h k4<7Q¨ÚrÑ×°ºWÞ‹òZÏkŠÐ/üWع“;y¯úXc°Uãþay``†“XŠÂòq_‰ËJ?q•wŸ‰À‡£éYXjZW}ïàrï-÷½·ü³™7ç.$ïâ-&ö³Ë‚æ½mÞÇâAÈýXðOk>òúº_Ê»ø•¶›:4ÊÈL1­¾¯.»©3‹âÓŸ¶,/²¬ M-?úQA1*ÍË/\lÆ/ãä½áÆ:¶"wŒVý™ ¡y7‡e¬¦˜Æfš‘åîŒöåiÕ}\y¿³3ŸðõÂ5Fw+lF>Ï”‘™ävŸÆÖ»[¶_ú‰#ͬœ¼7švRuC·…3ô­Ïjà•òîšU«xÓåLeÞ=+(ã%3–ö1ͦÇWÿVAýÉÙk+[ ÞÎ6þÎ6ÿå?}fî×{<ÖÑO!ï;¦uúiL?©× ±ï••w›Ù† †1ýRÞÃÄ…“÷ÙÊ{­5}ó™Üû¼|ý«ÈÝÅä† ¦~wŠÔà -Þ°Àk ¤)ìÎÆfÒiÃjYyGf‚‘«¸å¶{^ãÊûJçZ=»óÜç͹ É»x›UG…x;ÊýIòG´Â¯üJÆúzÀ… !!íšO½¾WÜóÂ-§Z¿þë–•°vº|&M-¯ß*œmù´òt:†Nà |»fhFP/#3•ÚTÞëeÃjÌtDäx b«biU`äå´ã‚v½ S/ÿlº˜Å<ü‡Ï5IîTÉo÷Hn÷'™÷þ0àÖK™ëk¦½t’Œ"âåt"ï^æ“÷ŠÏ ˆ¨‡ÞLlÆ›Äf,ѤY5IKy7†wIÓ½/ìx7- óYfyú[†oÄ|çZ€¿û~Yy?NÞ!ï¹ùîyz¹›ñÞ‹b.–â^›dÞ½IÕ}0¬Q÷ »×}©5~§†îyàá&͇_ýpã¹6r¨†Ó«ž¼<úNÞÉ H<ÌÀºª{‘B’Á®ï佟Á {CÃj0p‘™pdiµöÉ{gÚ´ºÔöÎìÏ;Åe„äým†*ÝBrÿæq²ÃÊýq>$Ÿx"àw~Çgc#äÂ…¥¥ÓýÕü¿èÄ (¦âž¦ðòË?šžƒfËÉ»gé4: W!GgØñ¸È±¼—Uùº™ŽˆœÍ´*”Y÷ÎLÃêRã S@…÷ñïò¿¾t™`Ëã™ïº¸Lz»Gz«O~{~ùÊzé($…ÄaA-ô©….2“ò~€…ÔC»/6ã±[Lްëb3Àåˤ6›P«² ¾ÿõ‚õÐÇßgÝ·x=[>Öë^+>/#3yßÒó¦™÷ØO¨†80eæ}Ú°jˆÜÆÑškB].sï‹ø—û¿¿’“%¹³Ç‚©´Å}X9®Yuèas6…Ñ•÷~2ñîA^ŠûCïˆ"C§iYj,µ™äÞ;ͳû³Lq!yBèö|'Y½ÿÔ§v¹q£ÍÆÆéþˆýæ7™ˆ;¸Jšºã+_yeï÷¿ã*½++5'îõqtƸ،^ÍÔ0Üš™2cŸiÃj·k¸xñE^y呾Ùôø™ú|úÝ>ßùùÖI£êSO~êX¯}\~Y9&2ï• š¢˜È¨é$6íYÐTc©YV­cX©–Ë ˆtý½Ï[n<—¹èÖOÕÝÉ3¸“™ã…å=sG‘{nko‘À(ƒÝ`ZyfiFl, ÏÐð _Ff67#ŠÂ²ÜÁUÞ;NÞ;ÍãE~-îŠËÉ»¤Eˆ·ó¾!÷£ÑÉN̹[[”Qƒµk!M-Ibyâ‰oz¿[·|â§«VÞ£Ú^A#7Â2Þ'îãi3ŸøÄ»3²¬`s³Í•+m6Öks=Ÿõ}‡¯ýî&Ë™áO_œŠ{r»ÏÎÍë\e}'ïKÌäÝ=ò¾?©¾7ÂiÞ}lfœw·¨Æ6Ö ynÈó qüé÷ÿÊýô·j|´QÐJ‡dww'ͪÇeœy¿[VÞ³q•÷¤N«ÂDÜ]æÝÛ³ i¹”÷J­Œ•4óoôƵŒ?ÿnFå=#¿¼ò¡÷ž…‘yƒ¼“áªîE Ãv#'ïƒ †)a–e /¤n YZ‘!¾’e°±L¢3KmC\=›?·#îZº$$ïw!Ä–{89¹o·]uÜe« EáU?ûÙÞ÷¾ÿýËwøgÿꢛ Ór‚Þð!Ÿ©¼3•÷p&O1¾í½q™Gi1f Qä³¹ÙžûùüòÏÔ _¥èõùðûïòá÷‡ð™.Ð=ö¹J{!ÕŠG§±WÞÓ€¼ïCP¡1ŽÍ¦”wÈó ½é˜È¸ÈJ·ë¦È„a…ííƒg‡ÿêk}>óÞ€›×"^ÙºC¶ÕÃßÙæV¶tBò¯«îIL¿Ì»_ŽJyŸÄf†£*ƒaL’VYjºÍ¤õš{í½T¦?÷…¢¬ºçŒ~¡îÆQÊyˆcs€¼‡¤i6ÁÌ´™a£ŒÐä„YNà ix°;²ln:qÏs·‘y}ÝŸÈûYþ ?êÏɼä]¼Å}ÿ´—Ù¿Ï{Û½÷°÷Brô‰9‡¡3Ó+™ç–~ôåCÿ³•÷¥¦[{¿¿º^ ÷Š;€gÜñðÃ'×û¡OóO.p%¼ hìMû!++Щ3É»×BÑÀP .^œŽˆl”Õ÷¾ ¦ywœÀ縼{¥ë‘çÐhDlmUxè¡ßå¨aŒÇÝ»9[[9ù¯}Œ/DÃ>ÙV|k—hw‹ï}ëã' ïÓÌ{Ñ·ôÒ:½4&/*®ò¸i3ã쩺ÖUÞ[1Td7®eüÙµ >×rràN^€ùÔÂȰøÔÝÞ\…ÛÛ©‹Íô‹©¼2eDÕŒ0Ë&™÷`d¹r%"Ë,Y•Šq“Ÿ–ή¸Ï›s×ç«ä]œcq¿×øìjûýoôyoÛÿ¸ ¼~°±X¹Ÿýš³rßé¸)3/¾t¤ïïüò«|ó™+ÓòeñØÎÈ{¸ÀÞÛÏþž|ò6ø‡Û|òçÖ¸úî¤7òX;ϼÈ~þ]nÂNâÀ'|n t»†FÃLb3263YÎ4#况\ºdÊJ/¬®ºÊûöv…gŸ½1>žçóžýë˜WRŠ?ø“­]ò­]²­ÕíyNµ26“õØ3ãÝþ43y÷€°œñ>λþõ¿ƒ'þþb^ÛßúbÆç2’^#ÜØšq$&,OdRÊûhFÞ3hváv?qÑ™¾…~êä=Í`”ãÊ»kZínd+NܳÌÅÇ66…’wq~„à8Wî÷»mÞÆ@!Ä›¿ßîõ«EÄì4ìq0|‹òö$±<ùä-ž}¶Àã?½Æ¿øç@ºØÙüzyÌDgò¾G`}º]W±Ë{Ís±™´ˆÜü{;ͼ€n×›Ä4òÜg{;bw·ÊC­“eÏóùêS1µm±[»dw{dw{äwwyñù¿q"Ïgܰš÷,y7ß=Y­˜iæ=p3Þ÷çÝ ­íø?ÏZn\ËxõåœíÜvc Í>O‹iå}\}O¡Þ€VH¹¹7nÊÌ.®‰u”Æ®ò>ÙÚWÝí¤úÞéœÝeL )$ïâÌ]8!ŽöA~œ_“Wî}×˧Ö`;æé§wè÷ .]ª`-üÆoœÎ㎫î“ØL1èv=òÜâyЮ{夨âÌL™gÞ“âî¸òîrïý~…ZmÑ(g4r‹°Þ÷XFõ¶á™zd3•÷“bœyÏʆÕAR§Õy¤áéb3f2ãýö0¢›Éâ¥V¼˜ó|ãZÆ÷¯çüé_óöŠûøO¬÷ÄBR¸ÊûÈ@­%hF¸j»M¡oÊÊ»ïö¤)a–»ØŒ¡|ð}C¥bÎüûÝ£ÏW!yBˆ·ª¸ŸÄõƒnªÝOšZ.\ˆÈ²¢œcq†w ò^‡vÃåûãr\d>ðËÆSCž[VWM9ã¬°Ç QIDATÝÉûAœµ2ëže–“yïYzEFh&s§“fürLd<‰Ì4j'ŽŸ~:ç¹çrVW=¨ÖÜwoŸ¼ç¥¸§Öý£¬¾‡Æ- k†{–þN}ψÜ5NÞóŒ0w±™Øœ¯÷ûim}’w!„瘳ÐT;K.]Š&£-ögwNí\üûù¿õŸ]î½Qq±™Zèsñb¹ ·0¬­šU· éͰø¾;¢hj™Îá$ÉÙ(r–òg=þî/¿´ ¬?~‚ò^fÞËM}/¦UVÝ['Âq0Þ® ƒ™ÈLQ@\…o|>ôž“ù~îܱ\¿^°ºjø§¯y.ò²_ÜƒÜ û¤òŒ\õ½¹bh…å…‡WФÐó¡7Sy/2Â,'ʲs'îŠËÉ»BœcÎÊd¦!÷•Š7‰Ìœ6Fy4Á˂ɸÇñ±²â>dþ²îo¿ìóÉM òúÐâžK ƒØ2ónéUc.–ͪ­Ê¸úîÆDV°TCŸ°UŽ-Üìþ“Ü<úÃ:qÿùÿx.®¹¦ FÜ= ’@ßwÕöÙÊ{bi]p‘™fußòz?~PVÞ '滑™å¿õ ­fÄûÞwáܼß%îBò.„ç˜óò}¯ïó !9ÊÄœn÷ôŸO§îb3ÆxÊ {ä½Ù4¬®/ñ7µÐ¿¾ðç—ÛU³¤¯Ò¬àŽ2:Só=B ‘-öDf Õèä–3¥)¬®wA·]ÅÜŸ‘öqõݦn^{/Ø#ïõØÒª²'6à -VSLÏÒhDt:]~pýYžzêxžÁó W¯nœé÷мc!…¼ !„x !‹ž˜s~êñøþÍw±Ô€VÝ£^‹»¥(8öxÁ?¸ W×OåÜÇ@ÞÃ-hJãI\f™Æf ?¬°Ürªcy¯„î"æ$CX]õ¸ô‹[ÖœixLÞA~#vüitfdh¯¸eQãØLݳÐO\f¾Ÿ±¶f¸xq™VËðÈ#?‰ç½Lž¼öZŸ›7{¬¯×Ïäûã~q™ƒn“Ð É»Bˆç(±ŸEOÌ9*¦;|‚É'âÉt?^mœ^SbŒaسd=K/©Ó¦Íª­òï.6㓹ÊûŒ¼‡«¾Ÿ•¾VŠ{0ÌÌVÞ+‰“÷¡½ÊdÒŒI-íšû­È86ã*ï ô ôR–»–ÍÍívÁ¥Kï|ç_fyy—+W:çVܵEUHÞ…Bœ')§-÷K 'î'Í­ÔNñ5ˆ1ôʼû(¯îiVTÞË%MþÌ7fqçàÚµ»|㯆ô–ÜAàMÅ}Và팼ׄš@»ãªîí¸Œû„P÷ 7"²ïÓŒ VV,ëë>—.­°¶6 Û­ðÎw.ñðÃñ™}Ì›s—¬ É»Bˆ·ô…Âþ¾¹9†“÷7ú\»v—ßüM˵[õRÜý7Ff| HÁK§±™a»UA»‹«¼—±™=•÷¾ÏòºÈ{·²¶VÐíVév«xÞÙÝ¢*9’w!„â”ä~ÌaåþAÌðv™w›ÙSu¦ñ“pAù·oçüÞï øÂàÚ‹U• }wìw¨–Uw?u ™†#؈ŒG»fiÇÄfú)~²²R°²R°¾î±¾îsåÊÝ®¡^?›[Tï—Bò.„BAîÊëÏÊÖQ&æœövÚ½òî45«!• >Ø›J|Y…_O=ÕãK_ñ½ç-K͈܄&äG/¾xðÔ{WJyOʪ ŒÚËUÚ5&ß®•±ÏâRVVìäX^¶llø¬¯û¬®ž]•ÑXH!yB!NP¬¨³ÖT{XyÏzðØc’¤`y9bµÒŠÜ‚¦Ð[Ìã~ýë¾üå!£‘es³Jnª¦Ê|ío~§a:•÷ĸØÌ0¡]«N¤½SŸVßcßR÷÷Šû8:³¾îŸÙ_ŠËÉ»Bq‚Ì+PgQîc UÏç±Ç–H’‚¢°\ºTãÂF…z¸˜ó÷ÒK)_ûÚFÃccç³R!7U~û ?¼÷ó}~›ú_(>†ÍzÎʲq•÷x¦i5„ºWðï_#\Tf,ñëë>ApvsîŠËÉ»Bñ¸(X„ÜטVÝ“¤ M ÖÖ*\º´˜™7Ibùö·66|¬Ï7¦Bn*‡ûÃ2óžX%,_(X[3o¨¼·"¨ûðøãï`8ÌY]­qùrƒ‹+4›Þ™|ýç )„ä]!„x›È½í_çÑG!™È»1Æm\¯¾š³¾îÄÝZ¨7#rSå³çK©†el&µøYÊÒRîâ0Kfoå=‚|ä ‡£QÎp˜qùr‹Ë—›göõ•¸ É»B!¹Ÿ[îg¿æI5ÕΊ»µ°l«|ì'_<üs|u•ú¥›ÚRÜ –—]õ½SŽŠìÄðÁ^p¾?tò¾¨ ’“@9w!yB!Ä$ð~[mçæVî«US ¼%ªüØ»_:úºÊûò¥bFÞ=—}¡]ßÿ˜>ÕêÙnP½×y>è6 ½¼ !„oqî'“ûZͰ¾°¾~}®çÑ»õ>ÖÖ¾9÷¥¥‚ÕUÃêªk\=£;—Ž$ç÷{=ößG2/ƒéõž·: B!„8¬Ìõbá^|ò“ßçêÕ ®^]ç=ïY塇<–—Ï—¹crn„¼ !„âLÊýïÿ~«W7èv½su.4]FHÞ…Bñ¶•û¹©Vâ.$ïB!„Çûý"|–ä^qñ PêB!N•Èí¢'æ…’w!„B¼¥9̤œÃ ðƒ”ûûÅe„X$ŠÍ!„â-y¡p+÷ʹ É»B!Ä9‘{‰»¼ !„Bœs¹?¬ü q\”yB!„¸lïÏëu;êa.$øâ0¨ò.„Bqñ> ±>Hð%ôb?ª¼ !„B<`q—¨‹Ãâé!„B!yB!„8·œfÕ]É»B!Ä1¸ É»B!„Bò.„B!Î&õú£sÍΟ÷~’w!„B!æ÷^ïyz½ç$âóÞOò.„B!Ä1Ä}ÌaE|ÞûIÞ…B!ކ©ˆ‡¼ !„BœqWÄCHÞ…B!Ή¸QÄCHÞ…B!„’w!„B!$ïB!„BÌÁþÑþˆÑìŸç~oG!„Bq/q¿Wï€Ä]ò.„B!NQàï'÷ý?’ö7¢ØŒB!ŠxœU¹{1½ÞóV§A!„b¯œßOÜ÷ß®ˆ‡¼ !„BœA¹— ‹…b3B!„G@â.$ïB!„BÉ»B!„’w!„B!„ä]!„B!yB!„Bò.„B!„X,ÿÊ}-†2}#pIEND®B`‚snd-16.1/pix/fmeq19.png0000644000076400007640000000204311147553267012755 0ustar bilbil‰PNG  IHDRÜÆèŸ·3PLTEÿÿÿààà°°°ÀÀÀÐÐР  €€€```ppp@@@PPPððð000 * ô¼ pHYs  šœtIME×:%G$˜9ƒIDAThÞÕ™‰’ƒ @ —€ýÿ¯].5Tl©3ëLkw-/@-!•ÍròäöH´.}âÿ_ÓÊ›0&Ã&ìg.ô³ûô¥èïMûkšqLÙ»õƒ?¨f[‡¾+2uÙ‹kÚEÚSˆÏE[Mï «Jê;jRz‡x³¡Å¥ò e7hRƒÖ¶å—SÅ5m°ïç–oE1SöÉÉ݉VRßW³Ü&Àó3›)Ö›¸ÛÓ¿;»zŸ>EMeoÑ®š@Â׌°Lx¶-£Ûµ^€©‰ÙZ·æPbiÁ gàjêeÙD+ì€Rˆ;¾¶.úÔ.Úb*wžHÜm}›úšÜ5ŒP7ƒE„³P5i1×Cn6ëêɵ~‰eÂqzî º:Úh›0îD(·“këÔ§6ѦÅg<9oRßIÓWƒ[8˜_«™ŸæG'$eY3¾VÈÃ’Ë©¨Q(, ,]-€Ì[š‘Zi d_n?ɰ#Š¥Ö±Om¢¦‡,Tâ"´Ä©§¾—&”†$Þr_œ–þy­©‹üoKDˆŠB` eÕKÁFÚ þ+`ÅLUj³Ö ÚhzÈB%î™–9ÕÔwÓtãüÅÑ“ë[¹¹Áæë5iHuäÆ%‚ ñ¿–ÐúÉm¤­ 9;÷[ç¬5ˆÞ1ݲP‰{¦å4VSßKSÄy~ß.¬*þ¥üÜçâ‘–whò´äºÉdÈÝ9A` ]¾MË)X#m‰P¹V q¥ÖëJÙ"ÚhzÈB%î™–E«©ï¥)ý׎í‡É¹Ø Óq2•“›îÊæøOZAHM ¥þra…ÊêÕ-ée»™‡|,þ[3¤Öëxk½cZ|ÆãžM3§šú^šRs«9›^’ø7¯ÉZòµ¸AnGGðH^> +ºr^ÜH3*­ð8tRo¸1lƒªêó¥+ZÒËv.ƒ@mعÁ[“ا6Ñ;¦eð¸'Ó•SO}/M‹>§6áFÍÆ{löæö‡n@¢áSºÊãØßÚª·} `ÛåÖ†7£o˜î²€Æ=›òwÁ£¹¿„9΋ççGðÅä ˆÖ„™íáÃp½‹>õ2…Þ¦¿ÑÜmšï~§p·\]ùpU5qBu~´bÕ7?£´éiþ/LД–<¹é'ÂuéÓïMЄGOî3¥ÿô—æÅÉ7¦Ð-5IEND®B`‚snd-16.1/pix/sqrt1.png0000644000076400007640000002220212421562206012711 0ustar bilbil‰PNG  IHDR°âøq¼ôsRGB®Îé pHYs  šœtIMEÞ 6E—6 IDATxÚíÝyxužÇño%éÎÕI ä‚„˜€¬‚I8‚ à £¢ºs,bÜåQGFÝÇ9d„Á‘ÙaæqX—}FWÅ#3Êa¸˜¡ƒáŠIBB’îtÒ÷þˆmÒ •;éz¿ž´ˆEÄl‹p¶p³:h57Z#1´ˆM¶(g3Z Äf›árU-¥ÍâÐKç«)}h47ÙCjê(}h5;B›._¦ô Ñ@Üì ±66PúÐh ¶ºõö&F™€V±MBÜ-fJ Ä® `Ån¡ô Ñ@ìÖ‡¹š(}h4„†éÜ´@«Xo0„*bh5‡DE„5SúÐh Žd·› €qLlH“=ÌÙb¢ Å@l²œîÍMâ„„°F[„³™@ MâáÃÃMÖ(Ú Ä#FLÖ¡t™€Fqdd°Ùf0×]¦ Å@,"f{èå‹5T´ˆmÁ¦K´@«Øâ i®'@«¸Ù©·›¨h4ÛDï°p§:h5Û‚»™ €F±Kà°PÐh V‚Cu.1´ˆBCC1ü1ÇÆÆ*>´Ma $ ŸõÆLkj|Þ‚®-G v¸‚\VK@pÕ€þÒo]&¢£ƒšìaÎF^€&qLŒÞd wZ©h1ÇÅ…4Z#\Íbh2ÇLJš¬‘ÎfºL@“8!!Ìdâ´4PÐb 1Â`²¡… Ä11aÖ!-—©h1‹ˆÙÜP}‰:€V±Mo¹\G@£¸Ù©³šv Z Ä-î`7æ€f±]ѹ¸u3´ˆ‚ìMÔ4ˆÝú`½›@ ­â€à½4SÐh Ö‡ëÄávØ©h1GE)ÍÎ0g M@“xèÐ@“-ÜÉÈkÐf ŽŽ2ÙÂÍbh2ÇÄèͶpW3C@“866¸±%‚.Ðh Žml‰tÒB mâáÃíÑô!€Fñˆ†Fk´‹@ mâøøp“5ÚÞÔ@5@‹XDÌ6½ùRÕb‹#¨¹¡žj€V±3Èf¦Ë´ˆ[Ü:W î@«ØêÖØÌT4ˆAú WÕ€þÔÏË×étn˱¥#;>3á×ÿ£†àÏ8Üà~ɸùý÷gµ{üÌë6*Ž˜0›@¯êç.—ÇÇÏ4ÜGõÀÏqT”b2)7dÌ0ÿc/Õ?ÄC†45v|<4åF{Cµ½¡š€?âèè ‹ÅK?f% Ð06ËL¯ øw މÑ77ë¼>e7“^ðó@lµ{}*bÜLZˆàç8..Änõú”>&EÑ…´œÿ’J€ßâ„„0‡ÃçÝ7"è5ÿÄ#F\.ƒ¯g ã~ˆ““#Ýî0“Éá=Ͷœ>ìvب'øg ½þxAÁ%¯O† Nm9÷wê ~ˆ‡ +ݽ»Ù׳†Œ¦/èF ÿ Ä£F òõlÄx_€_âol:y2Ú׳a£n²Vv6ÕSUðÏ@<~|¤¢XOŸöþ¬¤=Õ\zª€â”””¨¨øœ "c£Àoqrr²¢_#ÆÍ4ˆàÇØlþkQ‘Ï BF|Ëmo±Õ–S[ðÃ@×ÒrðìYihð9!cÄðÏ@,"ÉÉÃ32šòˆÇͤ1ü(;žÿ¥¤¤¤§_<è{$ CÆ si‘Ûå¤Â0qll¬âÕ)jk=§OJJŠ‹;½¿Ïê¢âtQqÍåÇ©0 ‚@\SSãöáÊUUžÓ§¤¤„„”‹Ëåsž†qܲƒ$__uµçÉÉÉuu_ÆÇË?þáó3L_Ðþˆ¿ÙBœœœ\^^>mšìóÝ>&³éT‘¹´ˆ:ÀàÄßl!NII©¨¨ÈÊ’kŒF–¶|[ù–’‰0øñ… žÿ%''WTT̘!׸_ˆÆf¥|™ƒ?³…8"""(((>¾îâE©©!Àïñ7û‹Hrr²ÑX‘™y­^dbøK ¾x±c ®¨¨˜>ý:½&ÈÄðÏ@Üz]]v¶ª@L&À Ä—/·»{sk ñ-·È‘#âpt"õûï7ý+ €Aˆ‡mw÷æÖ¡ˆ£¢$-MŽQ;ÃØ¬´û“qÛ˵;7R—<8>¾ãÝ›+**D$+Km¯‰V¡)7Ž~îÏu·ßzÉírR£$¸ÃÝ›[ñ´i×h¢ÝУŸ}Çv©¢ìwO¸Zš¨T ø@œÐ®…8))Éh4º\®iÓdÿ~µ³Ù³GEECÃG?ýæ¾ü¿‹ïq^Q䥗Äl¦~00q\\»b½^]UU5z´´´He¥ª4¼`ìÞ-n·¸Ýât¾RøÊ¬,Ø•ÿÀÙâãgÏÊ 7È[o‰ÛM-` âáÃÛݽY:Ùk¢5 oß.·ÞúÇcr¿—øàO-[¾ñ“¢mÛä7¿éJ ˆ{Y‡bñ¸®nÚ4Ù·¯+i¸Uä¤;GþËÊÿ°tBtÑòôÓòàƒ²p¡”—SÝ ¸Cbñh!ÎÊ’ƒ»˜†[µÝ¶£éTÑÃËçŸKZšddÈž=Ô8B Ž‹óz³ºòòr¹å9tHn¿]Ö®•“';†Ûebsi‘Á ¯¼"}$ xÉÄn—ƒí€@Ü·:â¶â1™$?_JKeÎ5J–.•÷Þ“>P›†;fb¹õVÙ¾ýëLìv9M'võ‡'/K·œ;¦ MŠ»oGaPED܇„…‰Å"mOççç:t¨ÝKNž”?–?”;e÷nµi¸¹´¨üKS¾¿Á06KDöì‘gž8ó»ÝyáݰÄèìJ î»«G?û?úØT6qŸb·[äèQ‰o{êÂ… 7ÝtÓ…£O´q:=ós§3qâÂWMuu·›Ï·•Ü÷ò3ïMoàRá–Úÿ9zÅŽÀж qŸâI“dóf™4©í)—Ëj2™ôz}/×\ZtvíƒQ7ݽÀ0>ç³ÂÀv½/ªÞ]m)+õÔf%HÇf@ îý@|çòÜsrǞϦ¥¥}úé§iii½±h·Ë¡µýÛþú<·»|Ó¿‰HÊ’_‹¢°e€žUR"ëÖÉ›oJzºŒ}ågìX3FRSEסEÎáÊJ)+»òsîÜ•?Ê˽Ì!1QŒF9uJJKåôé+?gÎHn®ÜsÌ™#~þހÑ(N§—éU®W×xö¡MI‘ÔTIM•Q£®ü‘š*II4èñcÉwÈ¢EžÏΚ5ëg?ûÙ¬Y³úæÍ´fâ?ýIRSåÔ)9ý¥}ì©Ç¾¼z×]w-úfJîíL<{öבfšv~^hÖ?¼{QǪª¨™3½´šm½S[z阧~/Ü©„Ñ¿)Sý>Hýž±GŽy½qÈQÿ®¼.«SÕ:0k¶›1·SÇ<õÝnæ³Yvîl¿eN˜ ë×Ëÿ(‹_?«ß0¼~ rr¤¶V+;íÎ~ ¼êÎ~@}\ã]©œmf¦wwY*߀×O\m­lÜ(ë×KZšäçËüùý¹ñ´ wí¯é¯wÚÝ?}òº'ñZÝK–ÈK/ @ü«_É… òÚkžÏ¾ð ƒá…^èÇ=…­¦ìôkßIzäÕȉw¨)èI“dëVUÛº¯ïªª$9ÙÏ[&ú¾áÜkeyÝ3ú:ÑT_/^—å+eöYö½nÁ^wÏØÍcž×)¯qVÙ•õº¬î·ªß·vêPzí»Å"Ha¡ìÞ-‡KRR_|dzäkÙnFO_ÆÅ‹²zµÏXܶïÝëåÛÍãkg¿,î©s*5ŸÍn8Íá½ÔjÛµv^:©xâ ÉÏ—É“ižЛVÿâ-[ä“OdófÏg7lØpìØ± 6ôo!ZÎ9÷›G“—¬œt§š‚îæ¶î«ÁF}n°Ô4œWVÊÔ©2{¶ääÈ´iÖéͺkÁ«—º"õÒù÷µúƒèôÉkÄìþ9É :l{-ìl9vìJ.)‘É“¯ó‰ÐÂÁ©ÏX¼l™œ8ÑG§ ½±Á{}«}y^ ÀK@í·@üÉ'²füõ¯žÏ~ðÁ6løðÃû½\šË—ýþ±¹ÿ“û½¾íþÉko4!¨ÿ’ȳ=Ì3 Lœ(ªj[ꥯæ{C§¾­2D>ûÌŸ½zyÄ +3ü0÷¸ÖX¼ví ì ݳeú÷š ÄGÊcÉÑ£žÏ=ztÑ¢EÇŽÙåòùsëOŸ:âÁŸ*ýøNºöõY73b7¿­þê+yì±N7œ{†ã}û´rx¸Æ·Õ ðë@|ñ¢Lš$UUžÏÖÕÕ¥§§_¾|y€”Ž«¥é«OŠÈÈïý. $œÍ¥›×3ˆ=±ÓÙñîÍ"qþüùˆˆrÇ8·Ëy~ÛËMgZö_º¡#ØbüL@¿-90P†•ÚÚv'''WTT  3†€Àć_‰Î^pzÍÍåÇÙbüL¿^±/UUíÑINN.//?~ü€*¦˜ÜïécRN¯ž>63rÂm7ÌNHgë w;WW·{,%%e@µ·‰œtç ¯3ŸÜoúâ³ÚÝÿ%"7Ü1~Vø˜L‡¹ÎV]f­>k­.³Õ|e­)³Õ|eȘNt _SBB»‹êdàu™ð9éÎÖÁ‰­UgLŸï®Ý³©ì÷ß×ÇŽ ŽMÕÇŽ ŽKœp›>.5ÈÝtª¸]t6dLæÊ<q›¸¸Ž-ÄÉÉÉŸ}öÙÀ/¸à„ôà„ôkŒRÜ1:—¿ùtĄۢ³Æçôï8nxøp¹p¡c ®¬¬ô§"n‹ÎΦú†#]üø7•ÿýüÌû£³Л@Û8.®Ý9D$%%¥¼¼ÜëäV«588xð–u`øè £g,´V©;¸ýì¯Ö KŒÎ^õOw†a[èý7±ˆ×»7777GGG777·{áñãÇ'Nœøâ‹/®X±Âà÷®u»œæ/ ëno,ù‹nXb[/äà¸4}\ª~X²ØéÓ•Öî'v™Oîçª>€ˆ½Ý½YDbcc?ÿü󸸸¶G¦Núøã?~|ÿþý«V­z衇ZgåÉØé°]ªh7N…ýR¥Ûåì8±ç|­Ñ¹í>Óç{äê|a£þÉrîH»¹ª`€bowo‘›o¾ù7Þ¸ù曯äE·ûHLL\·nˆ-_¾\DÖ®]›••¥©Úò¯;Ä[[³qSiqÐ8ý°dý°¤ÖߺÖßC”€ > €@ÜçØÇÝ›çÏŸ¿dÉ’ùóç·þ»zõê÷Þ{oÏž=z½¾-"oݺuÅŠÓ§O_µjUJJ ©*O»öËU¶K•öK¶K•¶«¿õU¶F{íÈÑ͘nþò€øØéõü=‹HB‚=ÚîfuùùùcÆŒyúé§Ed×®]<òÈáÇ“’’ÚÍÊl6¯ZµjåÊ••••‰‰‰Ôe§çþîÈá²6µÞÅsb¯·AQÿ®ºÖ3ˆ{3Oš$›7ˤIžÓüò—¿¬©©Y³fMeeåÔ©Sÿ÷ÕW³._–?”;%7Wî¹GæÌ‘ŒŒÖ‰üã×ÔÔlܸ‘º°º©ŸçºÓní+:ë¢GtìIc¿|Aå¼êÁîk—€nH‚½¾ŠÛ%08ñwÊsÏÉwxNóÖ[oýåÏÞøðÃ;–-»Íf‹ŠŠ’¼<ÉË“ÌL).–‚)(‘Ö¦L{ÓM{öì7nÕ‰.ðÕ“Ä^w¾;mÌê[¸m5_yMäa‘M¥E*ç ²‘Þk{|÷KÀW·ébø±ÇäŽ;dÑ"ÏiNüö·òó¿LJ:0tè’mÛ¯I÷äIùøãÖfã7^|±à‹/ÞyçªÓuÚw‡w4ÖzÍ£=ÕÄ{ÝÛÝo#WÙnÝ©&ö^š­ú˜Þ©ïhqWñ³ÏÊðáòÌ3_O±gërëêŒcÆ>|8**ê:süùÏ%%£Þ¶m[vv65 øÞhxîTÆUŸž»ßå½ßy=)ê³!h|Õuÿ¾+â¾ Ä¿ú•\¸ ¯½Ö–†eÁçÖ­A·ß~ìØ±o¼ñúsli‘o}«àá‡Wîß¿wï^j@ÿêB—÷þ?÷ð5McnèˆÞhûWsîáëË_ãtSŸUV×FæqÙš-gÿ¯éT±¹ô`ÓéÃfÓêÒÊÚ Ä[¶È'ŸÈæÍmiX¶o—[oýôÓOo¿ývµ3ݾݽråd‡cåªUsçÎ¥R WÓŒÿõïìW=¾½Ì“vs‹ñ­!¸¹â‹Ðäñ†±Ùác2CGNr˜jûñœÄëÞÏ”ê«tCúæ _—÷R‡.µeؽwÕ—ß“ôÒhƒ5ÇÇÇWWW·&×õë×/]º´Ý ÂÂÂ<ï«ÜÒÒÒõ@Üv÷f4Ü•õ¸í¶ã ÷î-)) üæ¨Æ "ž_2„žÚ‚ÃÒnЇöýÉú ºv¦ÔƒW8t*eöF˜SÙ‰”ÜÉïIº™þ{é‹(î®'æ?ï37îäÉ“™™™yyy?ÿùÏ].—Éd2 í±Õj}ê©§Zÿ½é¦›/^Üõ@Üz÷æÿøn¥a9qBn¿}î¨Qßùá—,YÂþh þtÇ7±¢(áááf³YDvìØqï½÷Ι3ç£>jˆív»ÝnïâòÚâ‹%!Abbº•†[=õTUUÕ-‡•––†„„PµP# í/£Ñ("“'OnýwÞ¼y"R\\Üñ5‡CQEQôz}aaa·–#"=†Eä§?MØ·ïþ±cûÛßR¯èt n¶éé__ï©(ŠgwáV7Þxã”)S~øÃNœ8Ñn·ßÚÍ (‡÷@‘aÃäå—a6¯Y³¦¾¾žª€îAâÙfüøãoÚ´éÙgŸ}­mÜ4‰­­­U;Ç)Szlm~ðƒ°7Þøé„ «W¯~õÕW©]Ð7ìv{YYÙ©S§JKKO_uæÌ™ôôôÑW;v̘1©©©:îZóò¸û˜¤¤Hjª¤¦Ê¨QWþHM•¤$ Ô…%eerê””–ÊéÓW~ÊÊÄéíš¼ôt=úÊÏØ±2fŒ$%ÉÅ‹RVvåçܹ+jçš*߬‚¯ûƤ¤¤éÓ§ïÛ·ïÊsŠ}éÒ%_«S[[;{öì]»v©,ö}ˆ{Üž=ÎG0~â‰üüü¶ @ÏóÜauü°%&ŠÑØþÓ~挚e/înúà xKn®ÜsÌ™#×™rÆ ™=[rrdÚ4 »ÖÄ»v‰úˆÊ•u8¤²Ò˾µ¼Üž’Rs>,ì´H‰År°¶ö`yùw²³ï›0aZLL\cãuöãþª¼=.ÎxèPÍ–’åÌ™ð bíöÀÞxª—ko®‹8 ……²{·8 .Wß”t¹H™H™È¹«”‰\™–’’39,l´È‹eHm­ÎW€7gDN_ý)9%R&Òñê¨ ‘$‘Ô«?£®þ‘(ØÓo Vä» ótº¬úzNWŸ•4wnô}÷Õž>]û·¿™Oœpœ>­«¬4ÔÖÆ65Å;Ú¨HªÈ‘±"£¯þ¤ûøhTŠ8ÔÍálNΟ}æ=‹º‹ê<µ¶/_¾üõ×_(XD¾û]Kzúo¢¢Ö¯_Ÿ–––ŸŸ?þü  ®¦DO0›eçN)(‚‘¼<ÉË“œ©­U=»ÌîÞîÆ(’Øa¿ÚÉ={ÇŒxÔhœîtæ‰ä‰ˆHHH±H¦ˆšŠLÉ™-2Y¤Dd·H¡È1‘ìï1«{Ÿ:‘Õ¡¡±£¼¼)!á+îoõõ_étÑYYßš;wÂܹÅÿ{AAAAAˆäååååååääÔÖÖv§¹ÈkƒSYY™³6˜”””ÔÔÔÔÔÔQ£F¥^_YYÙî ËÊ’ÎŽÇ'•Û[ºH¹NWÕ4|¸;==lòäØiÓân¹ÅX]­rM} U_½2ˆäzÛ2o‹»3$$»¥%µ¾þòÈ‘-ÙÙ!wÞ™—WYW§òÝv¬îÄÄD£Ñ¨jÃHJÒymóvªVX^ž¢nÓ2›Í;wîl·¹fff·{pÖ¬YõõõeW;w®õ£ÑØ•U_V×oIíƒæÉÞh õÑ`aÉÎþj„Ã11‡Û6 õŸM¯[Q'¶·^*íAÂ˰kYYYwÝu—ç°k#FŒ¸té’Õj‘ÌÌÌqãÆnÌÚÒÒÒ:ePPPÛ]¯×òÉ'999+w8÷29Ò|üxœÉô¸È¦;úÑÅ‹W¯^½víZ¯Ï¾øâ‹+V¬h7uwOµ½Z°@–,‘»î’kÜT¥¤DÖ­“7ßô~Ô¡Á)þ†.¿÷ž´ôÉZIDATテÙíö¢!CvØí®©ê­eË×7/#KkèÁ@ÜëËë›@ìÕçŸËCÉ”)²~½g'E¯ÍH3gμƹrÛYõ®]»¼®Î½Ü‰¹s§õf³¬Z%+W¶}õÓ÷þ±coºO¨åÙìúÒKrêTûarsÅ£ëmIIɺuë6¿ùæü)Sî?>3>~ŒN§kæ©ko]sÌ/‡ËÕüì³AÅÅ{òò>ŠŒ¢€@ÜkÚºOlÙ"ááèZT$Ë—‹ˆ¬]+íz\w¨Tõ£·xÞ+3SŠ‹ÕŽùõ⋲b…\÷’8±Fq«M›äñǽô ‰‘ÂÂöÑsÌyåÙ¿_V­’‡ê»öKõCV€@Ü»y”fW±æqzµøŠ Sqž2 b€@ ˆ1@ Ä b€@ ˆ1@ ÄÀ@Ô/KU…¢@ÿr»ÝB 14NiÍŃx”¾[–ÅJ±,VŠe±a°,6B–åË¢…šF x0‹õËŠñËõ¢²X/VŠõ¢²X/VŠõ€ë5èû÷¥¾ìÃz±RTëÅz±R¬!ëÕ7è2M#€@ uèsÃJ±^¬ëÅFÈz±^¬”ÿ­}ˆ i´@Óþ–5½hU§IEND®B`‚snd-16.1/pix/frqenvspectrum.png0000644000076400007640000010363611147553267014751 0ustar bilbil‰PNG  IHDRÿßj€÷sRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ 5 Å¢RL IDATxÚì½y”dU™·ûì}¦sά ¨*¨*(fðchD[¼ŸºZ›ÖµúÚ×¶»íµnë¢íîÕÐâçØêmÖös–ëÜέ w)M+ (ˆLÅ U 5PcfäsÄöý㜈8‘…P™û·ÖY™¹ãÄÎ8û9¿÷ÝûÝ¢\žQhiii½Äõå/?ÌÌL€ä”SƹâŠõºc^D ¥”ˆ––ÖK^§œòižxb°›K/=ÿüÏ+´uç¼H’º ´´´^êºõÖíìÚ5×t`ð³ŸdÏž¢î ---­Þºþú_R.{€hÌè{- ---­z衃mî£[o=¨;GDKKK«»>øÁŸS(Ô#·aÄ‹ŸþtFwˆ–––ÖB¹nÀOLÅà_YÑc- ---­íØ‘ã[ßz,Hܘ€ÉƒU¹÷¾‚î( ---­vÝpïh%Îãù °˜•LOº£4@´´´´Z:t¨Èƒ }æU<|et@èaLDKKK+¦ÉÉ_§µh°3ÿá´ˆmµå>Ì!‘‘‘0¤é ZZZ+Gïÿ´‡¯$ ·­r ²¾‡d6tcL„©¥¢¥¥µÌµmÛ!æçã•wMºm[ÛLžŠ&<ÄŒ˜0.aB†D; ­e­}û \zé×9þø›8þø/óè£3ºSV¨îºk7¹\¥‹ûˆí:(£ðUÒl&Î{ [5ècš ZËW‡•xÓ›¾ÃwîfçÎ;w¸òÊŸð®w=H©äëZaÚ»·@ïµf ÒᎵÉ8á+= i€h-Sⵯý:÷Þ»/úè‰h)ó©O=Í=÷h'²Òtã¿¢ç¾Òiå?,Fh[}>b´ç>2Ú}ððÃóÖ·¾•?û³?ã¿þëÈï²¥¢õ‚é¶ÛvðÀ:«>àmo{”mÛʺ£V”Iž7f^ÉdŒžÉó† qtgrÓM7ñÕ¯~•ýèG\~ùå ZËC…BO|âÞŽCÄ>‚.û÷ÏòªW=Ì#xºÃV€ÞûÞŸR¯«.îÕh¹1Ñ–ÿpZ™an] î¸ã.¸à‚äõôŒ7­Dwß½›Ÿþtgô‘ët ð ¹Ü.¿|†‘‘ÆóCtܵÆÇ8ï¼þäOÖuù]z´ÑíùðëÆ)¶nÍêàëªîÃ&ôÉI«¶bŒ‘ֺƑÒá?þã?ؽ{7\}õÕ ZËC¥’Ë 7üªc°mƒ~ 𙚪15ÕxŽ>!Òz¼}û!¾ò•ß. ÑDÂã¸ã’œxbv‰L¼=Õñ}x$ùÈI‡ ³…¿“J™|ê¨ÿLx^ÀÔT%ÖGr¡!r £-yžÌD¡+Z)K_f|ìc£^¯³uëV.»ì2 ­å¡ÜÏÿ÷³´VÇ: Ñ©øó"6Hó<ãÅ~®üΞ=Uöì™íòw‹­ûëÝzëŽ>@Ö B­÷¾jU’×¾vb ˆ.¸Ös×^»…ññßOæ``ÀB† ˜ž®póÍGCç EÌ…ˆD+y>îû1d‡®cšXLáMÀßÿýf2³§&Y»6Åë^7ÆÂÙWŠ å@«mã(k¨}åù¸^ûÀ?øAjµçwžˆÖòÐ3ÏÌòõ¯o‹¾‹ÃÃèÊêæT×;èþgµÄ÷b x¨Ã€ÆóÞïâªÄÀ¿c»q=sýõtùuÂ#< Cò÷/º¸Ñ¸+5À²`0«o­ýhÀcT„Ÿ¤•î>¶m ¯±“O>™Í›7k€h-Ýwß^víšëÆRD-r÷¼Ô ú|\C?wÛ‡ã&û¹ü=¯ógªŒÔóì/uéJ-èû>äó~—›‰8 üð©AB2&χ­ö©»Yí>xà¸í¶Û¸ð ùæ7¿É8ÿüó¹êª«4@´ŽN}á Ð=|eôp°pv¹êò¼:Œo1‡¡z¼v?Ž@=Ÿ÷ãžÇ]uþŽø=O¦CZ X²‹Cj$Ð㟇ø´nü:˜©02 N*`LȶÒ%¶¾ÄøÜç>ÀÐÐïyÏ{X¿~½v ZG¿Ï¡©í÷û:ñç‚.îÃèp¥ xpÈ&-1žŸf|<ÄLèÒ%är9žzê)€lꮈÖW(zè`÷Ѩ¶* ý„_zåÄïØ~|U}:¦nNHõ1ðªçñ¾éÓñ,×^íÆß{?aÂ^Î%þ¿ˆ%ËÛà_\êBµ?¶YóÖŒï{ޱñ!ÆÆ†“:yðÞ÷¾·ùøÊ+¯ÔÑZÚ¾=Ç·¾õxÇÀí.×±DHªsðQ‹ ¶ÝžSKül©ðÓbéçµÅ"Õ"[ì®^õyçÿ|àºØÿB.ÉÒS‰U "vCÑ"¾ »JßO3ºnãóf½ïÇwÞÉ/~ñ þæoþÛ~á3B ZGDŸþôý,,”×Xi,X˜DWKÜù/vg®ú¸îõ7Ý@±˜èu®b‰sïŒý¤T0îg͈zN¥Wx«×{Rô΋Å!¨ŠŠýßX˳¸‰Woc\@R‡¯xöÙg)‹ òÎw¾)_øŒˆÖï]¹\™»îÚÍÂ2ZGt„°Ôw×ýÎê^Z <²‡£x>ƒ~¯<‰:LWu8îápû§W?Kú›þ{¸3¶º:ˆ…¯LÚÚ¹ürOß¿•ÚËv0zŽNž|øÃÀóDXç5Ô" }b1Øô:Ï¥€AŸYª¯º=ÿ|²Xn& \b,³#¤%[Åš‹pè)xÍ—á+ÿ—â¼H‰•—ùä'? À¥—^ÊÅ_ü¢‡ˆÖaË¥BÅ÷yšÿô=n?4Šû¸»€}óP­Ò¾ïG¯… w[-áN– ½ôbZÊé,õûýB©ß×>përýª›ËZÌÅ,æ¶z_ûýØîƒ˜„ëÊ­ŽçL2¾ïaï“pÙ÷ïüCÅÇŽ1VTAů}ík<ûì³¼ë]ïzQÏED«?hLNâæ¿Ì3›&¸ “[å!u“3¨½fÃwß¹ˆûh 6 -€ÇbIbµÄ8wÞK=×/pT°ëö^º ê½\ÍáÂêw ñõÓÿý‚4þ^ü"VLJ‡{ÎC´ÏøŽ <#ùä/ þŠ€Ï¬[9iõmÛ¶¡”âÔSOm&Î5@´^2*Ü~;öÁ]8§V NÌ>ýÿðÌëøõø9<Ê ¿åxžf¹Êj^@9º¨'sP*³pŽãph–énŽÏ ýܽŽcYjÐ?œ×~>ƒm¯dõóT?î§—›é°ý8¾n' ¢¯v—#¤ÕnHâN¤ìÏþZòÃó¦¹muŠ3erY_›àúë¯`Ó¦MsÌ1 Z/ž¼©)ÜŸÿœDĸApïI?‡­5JkmžKËo_vO±™ldÇ‘cŒ"W†qi¢ û!_daé3688±ABt ™Ä§yÎ~?kI‚ÃÊáŠ>ÛX PÏwª2‹¼ï~úçp`JŠEÀeÐʃt‚Ãi,m0eëW ‰Õ[¤ ‚ýOŒò«ÂM£ó¼J¦H-Ó= }ôQ” ûõºë®{ÑÏGd…É/©?òŽç"w<„÷³o"§„ œ ò ' æÆ†xÎ<–lä9Ž%Çó R!‰‹…R"âæâ×Ó}íG I¨8@è.3žDô}ß•HÔa ØK ¦ý¬Wi(8L0. ú e‡áú`·J°„SŒÿ/ƒØaw¹±H„‡´Á4ÂosbѪcâG¡Ói8¸+É[­o<ÈÕ"Ã1 /«k·T*qà 7011A.—ã`ݺu¬^½ZDëÈ9 öï'ÿ™O£nù&¶]€ÍØœlŒŽõPM‘3Ƙa„"ª8!4&.ÂR(G@ xôI¨ºtÏX­ÁADû\+”Jtœ:x=nDD0Qj‘›îÃÉÄÚŽ7¢`ñÄñáëp.6pŽS8’€Zêܺ½·N€t‚#ÚÂVØ`šàˆ&Oš ‰X3Ư*0ó“ƒ|Á’<–z”¿a—î9‰ôúSYKüqn¿ývÞþö·S­VyòÉ'H$ ZG@A@ý¹çØ{é¥LLç6 ˆcãBXpLtLàÒ×°p±¢‹Î À¦ŽCUTIŠ 5ášNüàWàú´Õí³k¢ aï€!!0 ˆØøAu Ú"ˆ$vt\M‰X;¢ÇX¨Ú]C³MzÀ¤ñUtÀ¥WN#îžbá3A¿Øï(qy  ЪÃq½œÙb‰ûç3û-H2vsa‡îÔ6Á’á’„7(©èq¢#ÚeÆN¥ª (³Ü—8…¼!ùí±_ã*^Íz^uÔ_ÊM£ ÜÂÖ4_üá[d™köG?bæê«ß¹“ôˆ ÂÞ¢‹ÒŽùÑ¡ôF•$Ò”HQ&M‰ E*$©’ ŽkYø)?à=¼›î+ÏÍØf¬hÐp¢DªíÆCEƒk,lÌ„ c{Ü ou bm0¨D Xª£Äx£Ýæë@{>&6Ø·µûÚ›äÝÁ'ÔÂ1¶q^K†êºª ‚q D}¨§®˜ZÄ.õ·¢GhϵAD_M ²ùqiHº$‰ȰyU«žMÏmòµâ!^}àóœ{¯ƒ5öW¤^Äu¿‹þû¿ÿ€ .¸à+U¢²ÂåîÚ…¿s'²s&¥O8“¥NC.EGV•Œ,R&EU„žÃÃl.¡Cñ…4f?÷Ý 'ÆÃWQR4a‚°ÀÀPíî`Hbƒ~|Ðî ;‰ŽðV·»ñø@IR]œlª³]Zá³ÆàÜ §@¶Ã á dÐq¾]@²~tôAÞ\ÔX«N7µDȪÛ9Çû¡›KëQ¼v€ÈD –Õ¶Š;tìk:ö}Ü•4æn(ðƒ’JsH¬â N$X£˜ú?~Ã9Sײ¡ô¿°žJ¦3 3pT\Ç?ùÉOxðÁq‡¿û»¿Ã0 ­#/gëV¬O$(—¨ÎîÅ)Ìw\x±É0ÂTX†K2Ya450U3”¥¨ŽAùsÏN±0÷_E±-HàÈ0„%cƒ‘¢wÊ ëcÑ>6³¶|I’$‘ÎðVô±SRI•s ±c°­:µµÕòß³©pyóV\ãUdþïÿõ’¿Ž?þñS©TX³f o|ã_2祲4þÞ÷’ûð‡HMXyf€2 ÙYð£D’£«C¦éaŠ0ynà#Pøø»çØñÝgé]8±ßv i l-BF´© 3JÒQû©ŸIOh"è„J˜,p5 ê¸ãâmtq%ôh{AhJ,|Ÿ¢3tÏ•ÄÂBAÇDðV]r²—{ˆç^:`ÒhÛ—!LâíÊ`! :' tªŠÚ\ýºÃèŒD Éx¤€Lìˆ?Ÿa©æçÔäL’FxŽc±Suê/·Ù¸ù1ï¾µ þç à(ÛFØ6È—NÒ½V«±}ûvÞüæ7¿¤Æ e®ÁË.!ØóÍ n996Dñ±_"¤P»ª-§¦-±H›±ÐTÐ%_ÒS5Ûà+p ð¢ÎH)pŒ…á¨4 “çÉ©.¤‘0†ã“E²ÈP$I‡&‚‹2)f&唑'd^_ÄÜ8Çįþ ñí*ì|;jËé¨uÇ FF/bÎáÞ{ï # ããìÞ½›/~ñ‹¬_¿þEÙ]d*uá…!¨íÞyÚY8/;Æ3TŠÉ竌J0FªEPôó 1«0ç=(€•u˜epbža{Ó÷رÍdòÑZeK:ë^Å’çDèBŸ<#6°= Ñ9è7K/\]@¡Tç]ýbUF:Û –h»ßBÃÝÚh Öj u¶Ûs2UwÖU78µ9®.ç!èÈ{tœ”O8iCFÏ¥:Š!Ùñ}üqÜ‘DŽÃtaÓ‹rÝnß¾oûÛM'rÞyç5÷Éf³Úh½@F$ºƒ²Ö¬aìoÿËu!åàÞÿkª_ÿÿ ›Ñ4¬¥ôÔý$”±F) öD{M!20&rüüó'Ó{ÛÚXòÜ´Cp HŠ¥FÇÀæwh{m'ѱ|cQtè[”¾”ZÊõ¨EÜ@Ð'P–ÔbïýpÚìuŽ °ÞRž­ÿ± T£}ì‘ΙVépD¤LYIBVqÌ)£ÜŽ,²džò 'E¹Þ2ðòINm_†s…ðI%&qžû5Æ¿¼ÿ¢+ñÏ<ûÔS›®þ…ÐM7Ý„RŠl6ËÆ9æ˜c^ôúW +X2‘ÀÙºµù½S÷zÛ_b$m³á¸QŠ÷lÇš¬` ¨:øš.bN“à Ö˜aßã};J6܇“è#á¯I ƒP~xw­¢¸»R%ÄâÛ„Óñt¬W* ý(ÕÇ…¯qBñ…Ôj ¯$²˜ è=Ó¬›“P}¸Ÿ^nn©­DzÁ9ù`‰0ßbÿ§@J–í ²1pd;ÂW©#áã ˜ØV¤¬ Š„¬6CVY ÍuKƒÌÇ\HAò 1Ç óMWbᆟC}|3„k¥ŽÃË£ú6•|‡œ½Šõ<ŽzA’ì³³³ÜqÇ\qÅœ}öÙ/¹ñDd…Ë9á¬w¾©‚püO%ñì¯"Ó#pÂ(œ2BÝÏ¡¸sX Éu¾ùض?=Òá>:“ç‰pžV†à0$`u8(H`zÂW­Á)v(_È(½¶èqW-…ôƒð5¢% *>-YÎu |Õ6X7ë„-¨Î°\?êgÞb°ê—èPô^×$~Ç9Ò zôñP†"@ ÑZØ:# #åc8>î …™ðȈ"¤A:*OJ„ ]GÃu¤ CY¯ 4Ž!æbŽT½Vö­FççEçžÏM¬‚LM‘™)Q|Ãë©]~õWX«VÑk³T*±mÛ6.¿üò—äø¡²ÒC[Žƒ«¡”Ë ýŸ†éÖ`Ô‚‰îƒ÷)³LVÚ€ÑGÅÝGš)U!" ¤ü2v­Î€( P£äC>G˜f:`9áƒíƒÚ¶ýï{ðƒ#v>òÈ#üð‡?àÕ¯~5£££ ZG@„Õ¾—BòÔ3ù×0æÀ˜ÅWþcŽbå ½×~Dð0ì0|¹+å1 ‰d•\jŒR*BÂ9 ?è-ÏÅôF ®Ò$r!èöj8(é-·„} ›pœ 6Cˆ¾j:L_¢Ê|‰€`\bf=TFà™¤(“Ê–©Œ'ÉÔŠ¤¾mµ ªùf¸*#ŠÍpU#ï‘¢L2¨²¢@F1«© Ì 9O*(ä%VÅŬy­ò=óÑ‘=ž 2sà—¡îC ?ŒrYGnÏ‘={ö077Àë_ÿú—ìx¡¢µô‡dãFäúãEÕu¹í—ߤ÷¶µá«Fò|@’² Œˆ&“LÈI A6¬¯e™Í»ó‰R©l¯Ží†G"¿q§«„Ä2IäHj¦CÍr¨Ú *f³énl·ŽåºáWÏmö†ï7©ÍüˆxÂÄ7Œ$¦V ¶œÞð IDATT­uËÆ“&ÂU˜uËu›G$AäJT€ Zá¬ÆûuÐ=5Ún€ª9 Àºß~AË‘„‘)£ ~®aá!¬ÚÂ}1W"\¶ëFŠÕBT-åÉz 7Õs—^ÄpÃ>PÀ ,TI€VÂŵ0|Òf‰üª’~…Acžj2A&Qdܛ¦NVÚÂRƒÌ“ReA•™gPÌ“ ŠÈJ@"¨2dÍ1dÎá (AÊ+“PUDQ¡ "G>r…è(vd‚¨9³‚RM1#ââ‹Y÷ÁÑkîŸÿùŸ0 ƒ{[n¹€Þÿþ÷k€h=ŠÇyòÃ'ùõ9Z¥K⳯bÉs¢•çQþC(FƒFMs‚|$½ 5×Á ,¬ØÚA‰“pu§Ý•c½ØMÊ(Su”k)ê®VùUž2ñTø¸‘àÆiK!íÃö±„‹%ÜfŽD¨pxk Ê üº²©ú jžƒëYx~(ÂßÁ H¶ßª7ìEn'ˆÚ&6àËÈí˜&uaSU êMÝ·ñ‚‚Q•r…¡|¬À]©‚¶5¾0¤l:†º´ÃJÈ2+ÂЙïD¾`‘㉇ù¹s"ìÃü­j'ÂÃLà)3„s¦†K‹»¨NH5&4ιávj–CÕ ÛvM+|¯QJ!öl£êce\Öúû™f´#b†1àš'áVÉE&ÌI‚<ª p¼«3±g¨l‚9IJ•JÎ!Ê wÖ‚|š…Qö¡ ª ¢(`.‰*CÍÓÈbæØ_¦^W,‹ÁK®ÀÚ_¢òônJ ]ûR;vàŒ‘<óÌ#z}éK_bÏž=¬]»–w¼ã/í脵úÕ³ÏÎrË-Û _Å’çI³µò|@0 óŒù9ÆKSŒ™eŽ3žÄ¯ªÙÐ…ø®²pƒð¨{6®gáû¾ŠB%ÑKI;ÀHz˜)+áâ¤&u,Uk‚:O™”ýÕZ‚šëP¯‡ízAª@„IrŒ°]i…€2mC„ 2Tä¢8M$ ŽMÕKP­'Â÷à…l€Da*¤®_0…‡©¼¦ƒ2T”+‰B? x†‰+,jʡrƒ¨íFèÈ §²„2|ËwðYät„RÍp\ dŽ‹Âf5á„{»(;,Ïo(3ÜaÒ"wæÇÜYÞj‚¤ÑDP&ži†€2”5é¤dÃÀ|†Ü9Q#?6ÀêÒAFŒ†3³¬ûIe·Æ*ãc"‡Yñ0*>k³û™p&©ø3ƒržñ)‚¼ v(,FyœR€¨úP·‘yæ/òT jÚ¤ŽÙöÁžAÁ£h$_õrÌ YÔovRÛ}¢4ÿ›B=½gçn|ËBžu©“Oî7åßA_ýêW8á„H§Ó ZËC™š*ÓÚ½'ž<D:mÉs30Ì0L1¦r$XÇ1ÆdÔ~òõ4Õj"FÆ@_­%¨×l<×ÄŒf"W ,EñiŸÌ©Ç’pJ¤Èc“ÇQLjH|%)ùiÊõ•Z’j%l³æ:¸n4 F8ÈÊp°–B:"íaeê$‡MY ªx¡{ˆB4®²¨øI*n’ZÍ¡V|Ï3› i„ׄ¶k:a½&Óv± Sùx­¿Ž“.Õ TÍušðóU,a†Õg¥µ-£PŸŠÜƒ ">©¦;k ø5†øjnøµ ~R Œ¨]º§¨.JAPŠðœ}àn„ªD7Xø˜RI1})kœ‰ìY•Çò\ŽKìaTMãÏŒÙ9ŽÚƒQõ©H0tpŽÕ# ò’ò¾f!|Ÿ†ëcaÁþ:bFA¼:ˆÓ·"¥ {÷Á³Eü²Oa"EêÊÿ æ.ðvão?@Õƒá?ÿ'˜š†ÍÏaì=ˆS«ÁYç#N:ƒT¥B"ªå% Žôô[n¹…ÙÙYÞùÎw¾ôó£zXÔêWüà]܇±Ð}Xflê® áTórŒ9ÆÔ4™k±Ç73 k ªi<7_ó <…ëÔ\‡j%A¥”¤RNR«Dƒ½œJ )¨¦õl@vóÙ$œQR8Ì3¤9H†Y,QÀ Ên’r5E¹” Û¬:! ÜPžoQÈL†[¶û©•õ8ï$N‚„1M’)æHB*ð%å E©ž¦R U­&¨×íоEÈð¼‰{S!ì‘ö12u2Çfpd[°T% ›Eõ¨|ePöSTÜ$Õj‚ZÍ¡î†.Êõ-|e4§c‚´‚Е$}̤‹e×qÌî.J ÊK4Øh·Ž“²?;ˆÀça~¸‚ÛBÇí]ÒHªûÒÀ䪢ð¡oáa¡,°í:ÂW ×gONq{f$kÒ8>û,Ź v¡ÎĪ)†D™˜³ÒñH®"•+á=ã"KUŒsNÂNº°{<•§î)ŒóÎÆZ7ÞÈïÂ{|/¥À‚³ÞãÏÁ±‡P»âÔ]Œ3ÿªÄËÊ$+U,Ï Wš§Óé4/dÅ;vP©Tذagœq†ˆÖòÐü4·ßÞmßFò¼±ïG2f3÷!ÃÌ2îM1áO²JbìçeŒsÏ™‚ä,fP”Uðj$kUðË(·€W˜£6 •|‚j%[ !øù´¤”¡Wc$0Àf‹y,Æ1Èa1ƒ#çɈÊŸÇ«MS/@µhS.¥ÂÁ¾j‡¡-×Â÷ŒpÀGRIA50xöjÇÃb‡!’L“$G†ƒ$EŽ ÈQ÷•ªª”¤R !U«9x®00›k7”nZáe<×nÁ–8b†¤È‘bŠ9lJH¿F%HR¬g¨TB VªÉÐEÕ[y¸‹Âaé™q8u-Ž˜%É4–*âPBDòƒJ Z5:çz Rž2[¹(ÂOZ2é#ÓvÆ%™SU0U½B"tRõÀáä:¸X©v¸GGµš@N‚Ú´CrO… [wQMPy&‰5)Èž¹–Ää.jO DÕ'xÃé˜#ÆC;àר¹ û‚³±7Cy/LïÀ}l7 ^§m±)X7‰8ç ÉZ 6ŸÇžgT°ª5ëõðžHB"ÙüT¿ò}Ÿø‡Â}?¶lÙ¢¢µ<´mÛ!šú¾Ö~„ù+é1æO3æçórL“ îÊ`²Œ $ @¬ $k¨ ¬–˜ÇªÏžŸÃŸÉãÎ+¼¢Â­XÔj62e¢2’Ô¤ErâX$ƒ˜0)b2d!æÁ,‚SD¤JXõV-Oª\d¨’Ç›Ÿ§>'¨•¬ÐéÔ-¼º‰ë›’’ù¬`ÐÀÂÄ`‹aF°G2`Ó,`š’²È°_«ÌSŸT ÕJ‚ZÅ¡^³qëV©ÀÀW’r ʼ| ¦UÃb›Al†±!ÅI¦¦„ïí§^—TËF¾RÕZÍi¯颔DI¨¥ÁÍø œr.¶Èb“!!fÂvEŽ49LÊÔƒ²› TI‡€ŠÁ¯Žó}£¹² ÊRé2>ƒçoÁ³8Ì’`†„ÊcS¤N]Ù”¼4ÕZWYH3 p$%#* fŸäØÁiÔ\…ÊÓ bm9GþÙ21矇5ÁØû$õgü+OÁ\3§n„]Oàþæ) çL8a $¦Qƒ‘§?‡±ùÀÆS`m¶V°ŠeÆ3™)H¤„Ó>^*úЇ>Ô||üñÇよV_úÒ—¦¯Ò% ³U4q@’1 ŒÕCxŒù9V™“dÕñØÁ„1É Upjà×Á¯A² ‰ 8%HÌ#Òs˜3˜faÿAiž ¨; ï[w3pêÅ(ŠÊT0)!Ã9›`TÀ)ƒª„ó4Ea1Ìy g'˜%].ÌæñfÜ<Ô«&VÂÄËØOÉ\p‚!$%l ˜̃ȃQ»„HnÛ/`»ó¤Ky‚J o:O=/©Mܪ‚Ä3™OHDV’­c&ƒ˜Œ`3p!fF i°¬"i#ÏWÁ/ÍSËKj“ZÅiÂÏ­G3Í”¤””2`ï(“=é¸È¡ E€Åb„$9Ò"Ϫâ{©Uµ‚E¥è´Âq øy†ã Õ¸Y<ÿL²XdqÈ’9²$ÃAÌ`Šš'©Õ-\ßÀp*ƇäÕö<½Žôi«)ÿšÜö$lÚ€•^ÅÐôãÔó8çÁÚqä ã°íQ”:Ön„ Ái˜'<‡¹ù"X¿ ÖÔ'UH—+È5kÂ*Ц éŒñ—öõU«ÕxòÉ'xå+_ɪU«šÓwÿàþ€7¼á  ZG§~úÓìÛW û쫎mkÓFkúî€`XÍ6á1æåÉ*Œu'cÔg=8u°\ê¸ááÕ SƒlË0V„uy˜-Âty`ñì$é½ÈNBä$YŽÁ§ÔÔÔ‘TCwcÔÀ©‚¨¬€]…d Ò%,Àp9>ÆÜ3Mbg~u¨@Ù ð¾ó+²\‰¢„ ‚¤‚AI D)T%å(fáä1’óγd sø¹b”²axyïsd_}!‚"’&%,ŠHò Ê!LSeŠª€¡òØþÙÒ~¹‚79O½hP U÷MæddØþIç"Ä`›<sHVƒ˜£ˆ´KÈD«š'S.xe¼ü|¾’E­dS¯…¡>ß5p•A1))  r ’6‡f2¾–ÌaE²¢ªÊd†Õ9ŽuìÀÛ½Û½‚´¹õì³TNÀ›1Öf0÷ q¬;Î=ê[ë^›`؃ e²®¹n]øAµ’<*µð­o}«é>^÷º×ñº×½N;­£_Ÿüä}äóuZ³¯:7ŽŠšVÛÔÝD¢‚ÃÏ1îO1æçH·ÞøVDb$l|AÐYòAøà{áQ¯Cµ¥2äK0›'1;ÇH.ÇàUWa’À$µ/ëëƒáƒôÀtC`¥k­ÁP%l³RbŽÏÃtÍ!÷Í84ÅÀ¾}¤N¹ˆ kP¸ÔÔ¸ˆÆÀF-tP²f5„IªÙ2 a¼«óˆcæ1÷NcîÉá<=‰?9My*OðÃß0ðê·PŽU‹ UQŽUª Ë`–Á.A²™<ÆÀ¡ñ¢§J5«m;ž‡0;?Æ —KÛ,hO5ÛjBÊ«‡+˪5D¹J¢Xdlf†Ô #`$Ûa |0}HxDí¹5¨W¡Z…rŠ%˜+BnÍaOÏ0tð ƒñ—¤Gá£p#ðy¤ê`ÔÁ®‡ ²£_º Ce+Ãê"S„ãóˆM3{g;§Èî?DyòF>à ÇáSªMw&©"D̆C«†0±Ëah1S„¡ŒÍcLÌcœÃÞyvNã, ªEê¨[b`ëEM‡†‹ `Ãü–ªDQX b5©“µvã'„`¸hcl ¿Î=ck „–CYŒ¡ñey}íß¿Ÿÿ÷àoÿöoY³fˆÖòÐ'>q/å²ÇÂÒ%ÉsѾöCfhºF+38 [. ãÒ¿‹b5žA;Ñj«+wRáþ‹#H+µÈ~Ø¢u5 GŒ¯ *~ÔjˆjD¥‚Q*áD³m¢ÍŽE€’*áÆ¯ªTÌ¡•au)Ô\ 6ÍÂÁ9Œ=9’‡¦È:DzídX‹¢†¢Ötg’JV- Zu0La“$‹tȓ簓 ka\¹•¡uÁJÃèƈZר3Ï<Ã#<‚‚ÓN; ñîx¨¢uÄäû¿ýíA Xrö•Ó¾ö#iW[¹?Çh0‡uìË`âÄ£§¤üމPØdécʨè€]P‰°ûÛ¢A(?@ø>ŽçayÆðpô粃p±æ Àˆ n–ÒjÏsC7U«A9 ÷‰| g>ÏÈü<ƒüÇQÛ P¤ dÖA7¼p{áaHb`Xçg™qH¥aóZd[ÁG±"®³Ï|æ3ÑÇMò¶·½í¨:w ­ž:x°ÈM7=Øá>â+Ïc…SQò<+Yù D†bëàdtÇ) †lRIp¸k"àÅ÷*1“ÓÉ…hs‚ÛumÛ» Dóf£#„ûÖ0Fà¬5`˜+ qÕëõæì«·¼å-GÝùK}ÕiõÒu×ý4võôÌÈFåÝpú®™ šIóqŠqŠÔø±pÂźS—“¤D8ÎïæÐLkE‚£¡ï~÷»<üðÜsÎ9GÝùk¢ÕU33v옎ÝgÄ˶w”.I˜mÛÖf¬<ãõ0q>æåUy¬ —ÂÈqºcµ´bºæšk8î¸ãX½zusídž x×»Þ¥¢utjïÞ<¿üå^º'Ïc6dZ+ÏeV1¤æÚèI¶¼Ì„îX-­H;wî¤P(píµ×rÕUWqÕUW]&TÿµºéóŸÿ Kï:˜g/ÅÚI¯mæÕ˜Ÿ#±öD8ölÝ©ZZ1}ûÛßfnnŽT*ŦM›ŽÊ÷ ¢µ@Û¶â?ˆïûa°ø¾­ðՀȷ¹YÂ8áBX£;VK+’çy|ï{ßàå/9—]v™ˆÖòÐsÏͳâÉs»µöcP`d#j¦™û÷§ÈdÃä¹aéŽÕÒŠôãÿ˜ûï¿€~ô£GíûÐÑZ ÷¼'>ûª6Í©»mkÃüGÒ©¶J—D«Ï­çÀê­ºSµ´:aÝ«±±1 ­å¡}ûòLOWº¸ÎÙW Èmá«!æšÓwÇüC¦‡8ñUÔ«¥ÕtøÏ5 'žþùlذá¨}/z–V›n¾ù!öîÍÓ»pblߨì+3å‡+νéf==º6œ RÌ´´Z7iûÈårìÙ³§9u÷¢‹.âôÓO_ðû/廾²µÚôÑÞÝá<â«Ïcû~8±äyV²JŒV[ð f0Nx=ŒnÔª¥)>üápÅWðƒü€d2\æ÷Ýwsûí·k€húùÏwãy½ë^ÅJ—d[+ÏÅ€dTÍ0áO2áO2îM1lzpÊ•`8ºcµ´š×ØÏ¹í¶Û8묳šðh8‹.ºè¨z?:¢ÕÔO~ò4®«hÏt _YNûÚT=œyåÇ×~œëÎXÑe*´´:õàƒ`Û6×]wÝQÿ~´Ñ`n®m[ÛÇڄѪ¼›•dyÆÜÖâÁYFn¹VëŽÕÒŠék_ûξÊd^˜Â¢³³³|þóŸgrr€¿ø‹¿àä“OæÞ{ïåÛßþ6'žx"oûÛ1Íî8øÍo~Ã7¾ñ 6oÞÌÛßþvlÛÖD«]_øÂ8P\Ú}tìûadFü™¶mkÒ)8éò°:¬––wÞy'»víÂ4M®½öÚìuyä.¼ðBn¼ñFÞ÷¾÷ñï|‡Gy„íÛ·sã7rÉ%—póÍ7wýÛ'žx‚‡~˜o¼‘Ë.»Œ/~ñ‹m?×W¸®>ï¾ö£#ynYmSw‰z«tIgÝÉ0±Ewª–VLÿöoÿÆÜÜ6là­o}ë öº¯xÅ+¸øâ‹©T*|âŸàšk®arr’‰‰ N:é¤fIùNår¹æ:•Í›7óÔSOµý\‡°´xðÁ|íkÒ>ó*¾x0Ñ:Òf”<ˆAÁ ˜o–l÷§¶ÄI—AzLw¬–VL¿øÅ/¸ä’K^ðמžžæsŸûï{ßû~¯íj€hñÈ#‡bÎC°èÚXøÊLuNôr¤W­†ã/Òª¥Ó§>õ)fgg(‹|÷»ßmþìU¯zÃÑ®‘GBä{ßûW_}uó¹U«V5ú¿ýíoÙºµU-⡇Â4MN;í4ÆÇÇÙ¾};;vì`Ë–- Z-ÍÎVùßÿû>º'Ï¥Kk?¬0qíý‘6Kaò¼1ûJÍbn|%ŒlЫ¥)žxâ ‚ àì³ÏæÆod×®]ÍŸ[Ö‘­·sçNxàžyæÎ=÷\Þüæ7S©Tx÷»ßÍÖ­[Û¶Ò½ãŽ;H§ÓœvÚilݺ•r¹Ì»ßýn¶lÙŸÿùŸ·µ-”RJÿ‹W®~øÃ'yþE«\I£ÖU::†1£0ž†Mœh!¶˜lHíæœÊýœ[ù5çUîã,k?é7}Îü#ݱZZ1°fMXúæ›o>êö=_L:‰¾Âuë­;X|ßhá _ ìdQºU<ÑŸ"¹j#¬ÿºSµ´bzÿûßß||ÖYg-«÷¦²Âõ³Ÿí¢¯£’ѶµÑêóYh%Ͻ)Æ‚YäÖ+ ;¡;UK+Òìì,=öú§Êgœ¡¢µ<ô•¯<ÂsÏÍwÀ£sßhíG¦•<Y ¦›û~Œù9²ÙA8þåzÛZ-­˜&''¹çž{8ýôÓˬ2ƒÈ ÖG?zWTº¤³öUGòܶZ+Ï$I§VÞm„°‚iìcOƒÕ§èNÕÒŠéÓŸþtóqgz9HÏÂZ¡*—]žyf–Þá«Xé’´Ñ„¢¹mmcÓ¨U€“_‰ݱZZ‘üq¾ÿýïpùå—S­V›eÜ3™ ‰ÄÑïÖ5@V¨>ð;#÷Ñmá`|ÛÚFåÝÖ¶µñÐÕ˜Ÿ#=¶N¸¤¡;VK+ÒØ·o–eqÉ%—ð¥/}©ù³?üÃ?äe/{™ˆÖÑé>~8¾x°Û¾ÑÊsÇjnYË€$m•¯·Vž©y¬õ—Áèñºcµ´búÇüG \çñž÷¼gY¾GYºï¾½Ü~û3ôÞ÷#ž<7šÓwe†Õ\«î•—cж^NóÕÒÒ`ïÞ½ÌÌÌpÍ5×,Û÷©²õ…/<ÈÂÜGc!a¼tI|å¹ÀJzŒ¹ö}?Vo†ãôÚ-­¸¾ò•¯°k×.ÇᤓNÒÑZÚ¹sŽûîÛ×£sßöÙWY£ÐV÷jX”17žCÇèŽÕÒŠéãÿ8Vºýã?þc ­å¡\®Ä³ÏÎÒ}æU—äy|ß5ÛVyw0€-—†NEKK ·­­V«|ä#YÖïUd…éŸþé§ôÞ÷#Ëj[yî$êͼǸÄ>îLX£×~hiuÈÚµk9æ˜åíÎõ,¬¤;îx–_ýê9úZû‘ж­\Șoå>¼C¦Ü| ¤GuÇjiE*•J|æ3Ÿ WÓäñÇon%{É%—ñÊ»Úh1=ýô ¥’K÷Ò%±ºWÍ}?B÷a¦ü°t‰ßZÿ‘€Ô÷ ZZ ö±»iOœ÷¨¼k›!@"ˆ¤¬2cõ£ÞtÓÇ¿Æ6éNÕÒŠ¤”âÃþ0\p—]v###Ëú=k²Btÿýû˜Ÿ¯±p㨎©»Dk?bù5ø7Å„?ɸ?ÅPB Nºœ´îX-­HO<ñDsµùI'´ìᡲ‚ô©OÝÇÜ\ +Ï£ð•i‡¹h×A;é¶å>Ƽ\¸ïDZ/¡?>ZZ =ðÀÍÇúЇVÄ{Ö#À Ñ×¾ö(Kïûá@Âl[û‘1JmðUsÈ-—ÂàÝ©ZZ1}ýë_`ýúõ j€h-}éKæïâ¡«.û~à´ÁCf£A£d{èBS 8ñ20túLK«¡‡zˆ‡~)%W_}5™LFDkyhÛ¶FáÄÅj_%Zû~Dá+Çq›ë>ƼcÁ κ­°úä¨----€Ï}îsLNN’N§¹úê«WÌûÖ·‘Ë\{÷æù×½—VÅ݆ i$Ï£ª»8­mk$b@0`äÃÊ»}?Œbë«õÚ-­Ýu´uò› IDAT×]\xá…\ýõÍçßøÆ7²qãF ­£SøÀÑ£ÅVž; í(tμ2ÒA+÷áç÷§HŽÃæWèNÕÒŠéßøO=õôGÄ•W^ÙüÙèèò¾ÙÒYÆ*êQݫΉ]’çŽÕ¬{EV²Jm…GƒY¬õWÀÈzݱZZ1=ñÄxžÇÆyýë_ÏÄÄÄŠyï:²ŒõØc‡øéOwÒ}åyǾÒ%‘ 1ßHc0a"6½Bo[«¥S>ŸçŸøý×½¢à¡²ÌuË-ÛcÿæE6Ž2:Ö~¤¼¶=ÏǼ©‰õ°ñ|Ý©ZZ1]ýõ”J%Î<óÌ÷þ5@–±î¼sWô/îÌÄf^‘ˆ%ÏÃé»F¾­lû˜šÃØr ýÿì½y˜\Uÿÿ:çnµ÷ž¤³¯d 6!B¢ˆÂ⌣â|gŒ ‚ ŽŽ:ã~ ã3êOœQgqWô' " ˆ²EA¶@ÈB:{Òkº»ººªî½ç÷ǽUu«ºª»Ñ Éy?Ïyªî©ÛÕÝw9ïûù¼?Ë }P54Bäóyžxâ Î?ÿ|ÞúÖ·jÑ82p÷ݯðÌ3{›8XÓ8J†¥KBñS~î¹çµÇAȥॗz¨ß8ª¶ï‡¬ÎýPAÔUh…´˜X¶6(ñ®¡¡ÀþýûÙ»w/ŸøÄ'H$š@4ŽQ|ï{Ï4 :¹á°ÂܲûÊë%6uÌ>I÷ýÐЈàÎ;ïäÙgŸ%Nó‰O|)ÞûC¯ G$¢•w£…#£Ê¥K¤%)3RºÄë¡U cÎ;Zfëé¡ÁW¾òÒéô](QÈQˆ{îÙB}÷•]!q_5IŒ´ ÚÖzÝåÞ¦¸ KÏÃÒUC#Ä“O>Ioo/7ÜpÃQ<4aøÕ¯¶P?|7º[v_á»v¬P%ž·{=8³–Ãôåú€jhDðûßÿ¾L :Œ÷~.( 9Õ¡’¨Éýƒ´*¥Û[L¹ðÍžª¥†F_þò—¸ð Éår\}õÕ,Y²„uëÖiÑxã¢XôéïÏ×€¸€X©°ònZb&|Zý>Ú½ž óÜí!ÕÜó߬Ås ~ô£ÑÕÕÑWk֬Ѫú²8r°{÷?þñ T\X%1ÝFb%y°)èû³FË‘Wn7í^oûѱ@P J)^|ñE|ßgùòå,Y²Dm©ÏQ÷•ŠÈð% ÆÁí@dÚi)Ðᇉƒn7ÍŽ@,>âºt‰†F ===åè«Ù³g3c†®L­ äˆ%£Æ Q@! o#ì v Ÿ»”Ç=‡©–óÿ¾í^ìÇfÁK;8ýôv,HèCªqÔã©§ž*¿¿þúëõÑr$BP_@Wáp+»º>¸à!ð€|ø3}ûyp{°ƒ9s’´¶:€dÉ’&Ö­›WþÎÎ΋'õ!×8â1<<Ì7ÞÀ¥—^ʲeËôAÑräáûß¾”HįٻD*4ØGÐÕU «+øì™göò³Ÿm*“ÔìÙ)N8¡ 0°,‹ú§e埛6-F"aè¢qDà•W^á¾ûî`ñâÅ8Ž£Š&#/¼ÐWC ãÅH¨š÷~k††sÛ·çÙ¾½¯LR·ÝV!— .˜Î¼yÉpÛàê«1kV H R }²4Þ0øùÏ^~¿lÙ2\·bÉ›æÑ½„j9¢-_me«&ñ³µÖˆj°O½ÏEÕû»ïÞ±~ßüf%2lõê©\pAgyûì³§pÒIMúÔi¶xøá‡8óÌ3™5kŸÿüçˆÇã\wÝuG÷Š£”Rú92pÉ%ÿÍí·¿J¥m­¨YÜ£§ÚŸä·NtyˆIÌGõ˜è« “±I&-·X†O~rAùó™3S¼ùÍ:LãÐáÞ{ïåï|'Bn¾ù棶ï‡&£‚@þ‡Ûoï ¤d…Ô#5Ž…ñ§I½}Dò¨G4bÌhi‰qÌ1éòÿòå/‹id´paŠ)S´/ZãàâœsÎáÁ¤££ƒýû÷ëRíÂ:Bð»ßðøã¹p±-‘G½H¬ñ¤4rU©q,Úß5ÞÏ4"A¿Ëã—·W¯ÞYþ¿N>¹•9sR”t–|d‹Û‰„Ik«.©ñ§axx˜-[¶pùå—ë¢ äÈÄÓOû\tÑnöíˇ§´D"b™ˆDƳ8&«•¼‚ŠP#+%À“OîáÉ')“äm·m¦¤«w\ ç7ضŗ¾t¬¾H4^3~øÃ²}ûvV¬X¡H½U@»°ÞØxê9Xsö0ƒ}//EÄÇ"˜¬%2ž«k¼ËÆŸ„¥2r™ÈR¡ÆÊªG8!*Qiíí >ÿùcÊ?÷Þ÷ÎÒ®0º¸ì²Ë¸õÖ[Y¹r%¿ÿýïõÑrdá÷/Á¹ï„-ûAm¶Ré}>÷ÕD1y¨ äOÑT&ó™| dS+êǧ³3Žm—\~&×^»„L&õ?¾‰… u²äш^x7½éMxžÇÏþs-ž7€va½1”‡ÏÜ¿ø ìð@¹‘ÓYëª]ôýIX iþÿø“´8é(rW&ÒZüòöž=Å*kå/ÿ²›’+lþü4Ó§'Éœ9)>ùÉ…å}››mM.G0nºé&<Ï£¹¹™Gy„™3gÐÑÑÁœ9sôÒÈY¿Ù7Þüð °Ëo/°Ø]C Ô!+£qÔ{U,îõ¬5Ž%3²‰.þL4Øk±R¢¯²Š`JcæÌgÕN)ïæË_>Ó ~NJIG‡­/Ø7(8ãŒ3ذaïz×»øþ÷¿Ï=÷ÜÀ¢E‹8ùä“õAÒòÆÂ/|Ÿ¯ýAòÐ=ÀsÞªÀ~üýáÆ^ª]XõõZkd<©·ÈûÁdÃ…_ LÆåö§Jí>r²iz ñ¸ÍUW- ä*û«¿šË¢EÏZÙ±co}ëiÀàŒ3frá…óô ó'`ïÞ½tvvðío›}èCú hycâ.•åK‚ÇŸMà= l]À ×·Ø ì«C µ ="©gÐ`¿ñ\Z“uƒ©q¬‚~"¢°áÉþŒ˜ÀZÏŠ©–%‘2 “SNéà=ï™Y¶nN:©…U«þødÉ-[úxÛÛ~ƦMC€aÄ8á„YÜyç¹tvÆõ ôGàø7ÝtË—/ç׿þ5íííú 4€Ö@3¸äØÎ«4AÚ9Èèý·#¹o7±fåaãÐ|ürËãìnŸÎ&±ˆ±·°•ùt1‡ýLa ®gýŸJ"#\#œpÄõÂ`Pˆ…V䨱8Ô8®¬ZËÄoàÞªG:ãY2,šFÑ]ÍG*L`¡¨IÈDD1Q!JÑ€ðßd]b¥þö‚'ŸÜ>M5ÖGåá!—óùÚC¬]›ÄÐíY&Ć èêêàÚk¯=dOü<ò†a0sæL–.]Ê 7ÜÀ¿ÿû¿óÒK/ñÕ¯~•c=–“N:‰Í›7388H,ãoþæo4 ºç¬;qúv“ê¿É >…¹Øƒ©áÚ~ dg$Ù!g±¹lg6=´3DšqŠXøHªâ¦*=XÆ"˜ñÈ눀¢ *NµÒˆ@ü–‡_‡8m7"˜zäR4Y1“qyùãX²QøFíÿ"Æ!™É–i‰€gÿ?&[ÿ@Ä"‰’Gu+ã_?0ÊßüÇ×¾¤d2Oþ;vì ‘HÏçùîw¿ @[[_|ñëöw¼õ­oeîܹ,]º€óÎ;¯üÙi§†ëº<ðÀ¼ð wÜq‡Ôµ¥ äùmÛð_~ï—wâÞñSœD1Ý#¶XÌ Ç,(N³è“­ ÐL–$y< ‰‰‹MÃððm‰Jˆ€(@ !ÐCJ# d%ŒZP Í)#µ‘EQ…£.4²Pj÷­%¿kk<‚˜hß×B µ¤ÑÈj™È*˜Œ%2ÑgãËDÙñ¯…D¼ðä×ö}©íD©€"?¼Ùå“WÌž®ïÕñpË-·°jÕ*>üáÓÓÓ@,{]ÿŽiÓ¦ñòË/ó‡?üøÃ¼üòËlܸ‘¦¦&ÇaæÌ™ìÙ³‡3Ï<“U«V±uëVM oT¶n¥çÓŸ&þ›ia1Í…YTÆ4  È$à™.& @aàaSÀ!OŒQâäH0BRfJ¤qSf°VäQƾÏY#(Ü8 †Q" À,–JÕ! ¿u2ѶªCBãF¢˜8|¸‘ž2Qøq½}êÑD$1™ÌýÉZ&ãÌDûÕF´³AµæÒ¿»È7ovøòÕú~m„;\®}ݺuL™2…)S¦’¿eõêÕ8ŽÃܹs¸øâ‹éèè`Þ¼yÌš5‹ÎÎN–/_Nkk+Ï<ó ïz×»4¼1òâ‹ìþàI=õM6ˆN %$‹8ÕQ*xp®Â±²H0B’, FH3DŽ8yœ`‡BÌF$Å¢„ïæ ^£c0h²AØAD–á…BEÈ/¯»“%¿ERÏj©G2õ~† ¶'f<^ȱš€@¢ûÈIÏkÑW&["Ÿ ÜYãi"nxÒe‰Z áÿí¸åçŠ÷½[p¼ʪ‹W^y…\.ÇܹsYµjÕ!ÿ{N=õÔòûóÏ?¿ü¾©)èÞ¹dÉ’1ŸiyƒAš&ª»;èý'"÷w1\Üs¥>|hL€sI¥‡!A^:±p1ñ,“Òð„úS-øH”+ð}|i"VH¿ˆc€k‚ }Þ~H"B”ô׊kŒ%âÕ'Õˆ8¨F‹ÿdD{BidÔs™M&zl<XtŸFú üñúJÔÍöZ²íëå±øáyŠZQ"1k\[ ü]Ï{\þm“g®×÷m=üíßþ-ñÁ‚ ôÑrða´¶;õT̹szì·$²` ŒŽŠŒR‡Y †ð°‹Z’ý˜qB!Ê.-‰ÌK²¶S`¨5òPJTHd4$> ¾ føT-D¸ŠŠ!áE Y!%B"Õ:‰ªÑN•ù²eý,J(>ãë(“q}½–ãñd<’h”Û2ž`_ÆsƒMd¥ø²u~&j‘ DȬRE¸š8¢¤¢‚ %ëòü›üç%ðž7é{7Š¿ÿû¿§”ͰvíZ}@4¼NðŸgãÆ¬Y³†N8AM ¯¬iÓ°¦M#û⋤ÞógX­ÍôþòŒî!š†ÀP¨œ(EM‚õQ£;] ­©—”=Œ©\LåbâäpÈcâbiùHÏg$• s0\W™(WºHŽ@{q¢ÉÛˆ@<,ø¾‡ ×@ žŠx´ÔØõ¾D^Í|ÙÛÒ(lx¢¹Úùñd²Dãë0ÐXä¯GBŽå$öi-VÏ¥Vûw•d0ôuHÄdl9ÿˆ+ËW0/= kÿþðéÀÛy´£»»›[o½ô…dR']jyÑü®w!׬ÁhnæÀ=÷Ðêt"Òq˜–"»#Ö`«D_è1¤ˆM%æRP6ecÄ=ÒÉ!b‹À")EfÅÄ(ûRS)¸6~“ä€Ñ„t}<×,>*•@¢­@üÐò‰X@™D][¢B^wWt4š/¯ëµQ^ ´”ZíDE穸ÆJ‹«Ï’iD\0~ÎËDî¯ÉÃxå]&-&Ç±Ž¢zH/c£¯Ì:ˆ9–@Š /ß 7Ÿ8­qàñÑ‚Ûo¿=pGÇs W_=6TmݺuÌŸ?àe|k9‚aÏž]~Ÿùàÿ!žÍ"›“0³•þ+>D›; Yø9:PÀØršSÁhóhn iúF¶[ÀšbÈ0H‚br[ˆ«=-íŒÆbˆ¢bÄO:È@¸Ö˜‘³ZZÛŠ5D2Æ"‰XnÍ\-qxãŠq•´¿¤µ”ôÑTTµ[¬îv”L¨c½Ô#‚ÿ„aÈñÊ»LdÍL¶ÿJ£ýsk$jy” h–„¶Ú×™„(<ôÁoÀˆ]uôÞ·»wïæ{ßûW^y%_úÒ—êî÷ío›þð‡\ýõ‡eM*M G”ëÒú¾÷!] ™4^ëW0Sq˜•BÍÏ0Üõæ ]Ä›@즃9Í%Õ9ŒpFÒ£ÅèÇiÎÓátW9•'m ‘$KÌE%6Ú›q}“bÁB „VD©(¯ˆ¬ynͨ%·™4"™zDâÕPIcñ \dÑ\”ÒkÉZ‰ºÅ¢ºJt^Q I×-6Yýe"á~<‚iôŒ¯·LF‹aœß9þ¬YÇ1#¤aÕ!Ð)“<°>õÿAÞ†O¥¢zWWÏ=÷À¸ÚǺuëô⦠äàC˜&f$ùH‹4}ôcHË€f?i°ï£÷0Ý7íAa+Õœ!¿a±= ¦ƒÕV¤¥µŸv«‡œÇ5°íí™bŒb Gäé¶:(¶ZØù=^;^¿9P–rPdd-…׉WçµvÔ’K=²ñk,?´BJ®±ZýÄ­á¨û¬ô*jþ‡Ié+þÄVˆªW¶e²I‘‘Ëdˆc2QbõFwë£iXuFH&%OY|‘ߟ¿ ü8¼g‘Ç yt‰"_ÿú×Ëïßÿþ÷ëLÈaf‘ø>™÷¿©üà0;‚h]ŠÝÖóÒ° ƒš™bä¦oã$@Ìk¶9c£àBÚ¬^2ƒäÓä!&GIÛCÄìQŠÂ"›J2l¦( ØÃ®aRLZ•`¡Ò¢_‡Hj Åo@,¹ÀªÜ^¢¾x?žÎR«ÃŒù,"*«ÐEVb Ôe-EU‡7œ#¢»4²P&~<IŒ16‘¥S¤ZP@!I&(Ø6ø Š ‘Wˆ¢‚b°ª(ªHAy"¾hLîk°V¹½\êë*ÜcµúJ9”8$¨›¬v\»Mµ¦R;f^M‚X&»ýZʼDGWÉÆ­q]E­ŽZÒ°«‡4Æ6«,…ïggó6ËåÞ¹Så‘¿˜Þu×]<óÌ3477sÕUWéÅJÈ€Pb1Z/¿\|„`èî%}òÛ‹Zaq,l¡ø›ûpžÙ½Ðű%ÞAÌeZj/v&OF âJZÛú1…Š—¦,Å<à"=ŸŒ=HÁ¶)bUÈ ´@”+ÊYí¾¿2<ßÀSÊ-•Z‹¥‘¬ØÀRq'°`Æ#”’uãËH(25š eŒWK5¢ÙùºÆ&««ü1n±zR$È­ç¾2kˆ"š½Ù–Ø¢’ÔZj#*–Ýðìó&så(×ÏÎòiÙvDß‹¥h«T*ÅÊ•+õ⤠ä !À*ÝÅ`Ï™ƒýñCRBJà' F·®'µ§¹b&L™»ùiìþ¦Îß‹Ó铉3/õ*m{ÈŽ$‰9£Œ$ u¤ž"Æ(¾”xdà{Ï _=×7ñ|WU^KÀW2 žbûËxS¼š9·ŽuRl@,n")2¾h_²BJaÈžëòò"[Ìoà.‹K=í¤6³^Õ!‰r†~ ¨ñd2E*Ke€±Iƒµ®«Ò(•Cv…<¢»ÙT"|}‚H¾^Ýãz[±~ê³ü³1™dޏ[°T÷ 8¤…5hüɈ-_ŽX¶,X0„ÂÛ·aLƒ Ž7µÂŒv¼_uß±gz¯?Czó ±E£º{:HÍfØH±¥}ÂS´ú‘øøÈ€<“¢²(úEeQPv°­,ŠX°)Ä·ûB"…ïÉ Y©ÖP¢£†DDQUˆ¡X!‰²EãÑXSiä« ).ïÑT&r‡yT—üªG&ˆê0cB2¢Nø1 ÂŽ ­Ÿ¨[ªL,“ÓU¢dòõs?Ìò(‘FH kÚFÐt,òQ]K¤5ƒ{ãÜXÂPÓ«\!žf;—¤; ñ:—5?Xøå/I__©TŠyóæUå~\yå•Ì›7O/Lš@Þ ‰amg´´Óôׂ´ M•0ñwý72¡ s1b Kúù‡qÚMvLaÎ`­í} úãŠÂ¢ÃíÆñò(%p•IAÙäq%Æ(±rµßQbä…ƒ>B(”øBâIéûiAä²à# ¡ŽRQP‚(U†KÛ*Œ¾R®¨ÒU|?°l”'*ÖF±¾âŽãòª—9YÝ¥QŽ‹"z\Ò[Duèq­¶âSý~Œ®BMô˜ÇÄÙ÷Ñí’i¼è+; 1á{Ãà È#N¥ƒe¼†HlªK߀a(ôÚ<æÌ¢?>ÌKþ-¼·p3bË1pÞÐ÷›RŠŸüä',_¾œk®¹F/Bš@Ž $™D®^]~r}áyÄ”…pêY0« ÿå$6þsÍ18Û%³r;ž=•>+}f+Y7I[[/©X¡|ŠXäˆ1*âŒ`D%ÊeãsÄ);¯.&Eh'ÂTiH…0X¡ðnƒ*„Äà |W¢ì 8*bäˆ3*ÅEò8A5ah,Hqß“ˆ‚BæC]%Cm¥0ÖÕS|/â2ó%¾ Ñ•¬&–ÚȰzn1ï5ºÅ&“ÛR·àdMi—ª.jl¶~áUPýÔÏý°B‘<fH$Ò‚˜ÜVñË#Y³ŠÌ¥"#YC$6#xpq1!A/m¼*æ!ã>Å…X”þ:M?ÿ'F~ÿv2ñ0ýðmÆÔÕÕÅøØÇ>¦×M GŒÎÎÀ£>:Š»pöÜöžF˜ƒtî@íê"·/Π-(Ć8¾t$*%PIJ DJ• ‘RH/èA"-ÃöŽO^:äDœœ :µçuâäüÊU1r*^%ÒT`}”ÜW.A˜°g(!ª]ÿ¡Å£Ì`øvH®¬h)žë™øJ–Ã=ß(¯«ÌÀzòDÝè°ºÛµ$ãN@.‰úãæ±ˆHdÕØŠ)Gïƒr[m׬ˆtÀ CuH"B‰:î«Z7V"B éj21…%+}j‚"ä覃­r>b,¸|3­/݆¸÷)è[j[…»âäüùa ÖC ×uËÅãñ8ÇsŒ^L4Å®-ÛÆZ}Øy ©šèxôœÞ†7XÊ!—˜BT;¢Y!›}D“Âhò™ñ1 Â&/\iR4¬ ¤Ša•5ß’» e=ÅGâŠPñ \;;výêQ¤†\ ?.*«~¬„¾ÛclÙ–Ú°ãâÄRœÀ*©§§4"‘ºÑabâ¬ûîi}%l¡ëʱÀ4!) .*äPÏúHF¶“uF:"© ¶] ÅpP šÑ*")`“%I·h'‘Ìb,÷È´ta<ûÜû~ÀðOæà|ñ;$Îzëaq¿üîw¿ã®»î`ÅŠºï‡&£A$"Þs—"ý6’Ó6"ÒÍ›^ÆÛ܃á0$´øo7‘ÓL¤/–iaX`›à˜ _- ‰&IlÒÄHã“DÆ"…Ú¿ ùâ.dÑFaQ´‚áZ&žmàÙF`E82p“9åDŠ<DcZ„MQZü 'JÁ#ÂJÛ¯yá”JaÈy„”*„»Â à0ÌxLØq!n¾/ç­„C¹a²/*n³0y ©4îÝ·VÝ~,ãX+ö†;×¶­¸¯d '8o ŒtÎQkqÄêF¢bqȤJ ̘‹cçIÈÒ ‘a4C¤®jvæ#)b‘%ɰ“"1sCzX hùÃvø·‹Pß;•е¸+V’<çœÐûúcýúõám#¹ÿþûùÊW¾Âàà ï|ç;yË[Þ¢×M G)2-šàä·Âà1ÿxœ—¶“îëÃp‹ÄØSbÐé@» -4’ÁHŠp„Ñ; $qœÐ).I`‘ Ð½±¡XÑĦâÅ€,¦¢b¢â"K(„RC!- ,ÃaTÆ5X9WEÅȉJ¨ñ¨Šè+‘ü•QbÄÉ$$,Š" ?.„µ¿Jõ¿Jé¥<•b„\Q]ÒÅ­”tñU¤´KmþÊS楞•âÖÑPz6ƒW¤’éWSeWÄ1h–åQ² ¢ä‘Џ±’u>Kç†8¨ŒÀ²‹˜Ž‹é¸¤Äp™8J£´$:+G±("ñW¢eb73ä˜#ˆúÏß0ðoM$ïzfÏ…xüu¿EJ]—.]J2™äÚk¯Õë†& „@yÀ’î±0{§w3›Eæó˜n,?ŒÌQà(°ý`ÎVáß; L…@a``bÃBbabã#ßýƨÀ@˜éH„'¾@`¢°ÈŠ8C4aÑ„I“46M¨=û±ºI³¸`EiQ0m\3p{•sQ¬À]¦¬@xG€2#áÇv%¿¥haÈEߪ U]Ú¥v\ÿ D»"„ª,øÆ–t)Pýym‰WáÇE1Æ)eîã<¹÷SÝ’¶6ú* šC‚h íDø%‘iÄ~F"ã>1c7cbÄ<ÒjÛ,7r$ÉV‘G’lÙ}U"(™43@Hª,v±”C)DV—$Ð tzˆ­Û0»  qÒÉøñ82•:è÷ƶmÛ¤­­sÏ=W/š@4&k™`šÁ˜"E•e¡Â%ß;q˜ Ä‘{<š¤ISˆ`Å iC‹ í4YÐbB³iâ8FЩƒ6)b$Q$C÷XŠâŽ½Ø›{0ŠÈÀ-â9¸îÇ$žcšJè&+… #*ël‰p Ò¦`ØäÍ *¬lÉD^KaÇ£"V¦p±@˜—A¥B ÝÀ¢£ª*üX#zK)Ù£ªú1Aƾ_ E.…«hã3[ þ™:eK„U±>d Z´„ä‘&x_rO5¤!c>^³L¤á¥ ü´$íaÙE Ç íÀl™0R “$[ž+H’lÙ•a0°@¼,Íb€x>‡RÐ T`ɇ$*ýEd žóÑé}ç…¨]Á´ë®;èºÈç>÷9.¹äŽ=öX½.hÑ8HŒ,Z¨š)Å•мbÅ÷ÿFLZ@ZO›©PK)•ÐH”òаáWØXĈá p0C­%»óI¬úHº&¦”ø ‰—¨dàçW‰àU$UUø±0ÒÞÊ Œ@;É©89ʸøñrÈqNÅËù+yå0ªb+$¢«¸ÒÄ“Få D[“Kð-‰²*e]ÊšJMi×3«ÊºŒ ?v»·Œï¾*‘‡cA;ÐŽT@ "£0bn‹‰Lø$äÅ«Š4ü¸$­RHˆ‘2YD­Z)Y )5LÜË‘‘9Øè(æˆ ƒÀé _‡B2¥\îÅ4±¾>†~ó†~˜ôYg´+úŸÿùŸÙ¿?矾¾Å5hj¤O=Ñ"L×Eø¡û+H¯¸ÁJÃôÁôÀTæbx¡H,ŒÐ9fbaác`§÷R?-AÌ‘òTh™ñ…LûA²çc ¦B: #î# Ë Ã4…CÅ!‹Áà¾~b¹aRnŒB˜ YA„WIS)Áð £â* ÃJ$žâa%óeHv§âùFUrQYe¢(¹ÊJå] ÈÎ/ë+;ÀúiX8QÄ*zÚdZà²4âª)°HâF·ÙÄk6H‡±bEò‡Œ;H“:€%ФdžÅ™$¡2U²<’*KÌ%I–&ãI?‹VÄÜ`Nfý€8†Bò(‘È‚*ôý‘1* *Tâ\¿žöéÓÚuª”âÅ_D)ÅÊ•+Y³f¾y5hjMMcÄ”~þ' á$#|Œðs…Iá°h–3}±OrÀhÑ¢9ÊB˜"n ”‰2¬:k…‰ÂÄ%ƒKŸ4Š4’&Ü­Ïaõ‚kã ›¢”uqM³\Öų üØ6ðKáÇ1P†²ó°4~IÈ7Ãr.~z\ÊW)U@Îã%ó•]v—„*=–á-è;†`h”JeÃHáÄRé’Rò`;ÁèHÄŠ±âErq’^;V Û’$U¦Eõ#¥OÂ!í‘ÃnA6 5B“8P& «X$I–³ŸÈœÂõH‹!2Æ þ à s~à¶ d8B áûÁà½êÑÅ!-@®­ 7Ù3ç ]§Åb‘ï|ç;L™2…ýû÷—­‘yóæašzùÓ¢q˜x¿d¨oLÖY¦0ñQ(,Tè’¤³°R3IÅã$šÄT:,h5¡Í Â3áHÉÀu–Ã¥ÃãØ$ñ‰£ˆ‡zK’‘WŸ$¶»«h! × u•˜Š‡¥]â®R ?aø+(ïR¦2ªbA² 5g´TÖ¥ä*ÂpdᔵKÉ ›–(bËEaá»’ìw~‹[Õû#R81*žÇÍ y´ƒÙîb¥‹´«ú[[HúYÚü^|S³Gis{+¢¸È’P#4‹2 ’RÃ9C´Z}¤Ô0jD`ä<2Æ ­±>wÀÄñ0\cØ ÜR%∎aP!‘ˆHÜ,r`ùMŒàÑ—$?øAæ_t²Ú%ù_ÿõ_ÁapÅWpÿý÷—?ûÀ>  DˆÆ˜qÙH¯8ôç?ãûA&' ?v¼ðUU††Œ–B‘MÂðc › ÉQbcáàÇë<‰á{o&íJl3ÐUJÚJ) V¦ü ¹~,| ÓÃp<òÒaD&È©8ä!ÍI†ò6£*ÔW¼ weTÅõceMeŒ®bå(±‘E^ØÒ[¯l %ë#èÍ2 0Û\:2ݧXtäºiµú°bE¦ö’YRb˜˜¥EôÓB?i5„ÌúdÌA:bÝdüAŠÃFΣÅî§#Ñ?$)ôؘ9‹"Æh@jHÝuKÖÆpè’™5 ßƒAðrs!9c bO/¹îz‹Eæ|ý‘/¿BÜ4™ú•¯ ŠÅƒvu ðo|€Ë.»L—n×¢q4 uÚipÊ)σbü"(/¬ )«+Ü`”ÂŽKšKt‹…D °0°1ñq0Òý°¡–"$Í ´‹hRAI—&£ÅG6ƒðR* ¤£žDø&Ã"”ul284#ÚÜ…StHy1Š~ý%*M¥hYUºŠrDà.’¯º<µq„êÚWÑÊ»¡öa[e˃°Z‹LO즴iµûh1ú±)2†i=´Ñ‹‘óH’eZr/Íj€Â™si÷ЙÞÃèPŒÂ~{´€m0ó.^V¢È@ã² rŠbìböÂ…Ÿ 8%uÊÈÜ~غüþAz¤G|Ýû0v÷æmwî„÷}€ÄþýX## ÄA­ÜÛÛÛ[Î>?ñÄõ¥ D㨰KJ- ê¶P­×k¼4Ü0¥~ì£ðÃ_9ºƒÜöQš” ÉÆdXÒ%n"R&¤-H™ÁH†áÇ–Ò@ ‹d~¤rKRX¤Èm{ÿ@õP¤h[¸vMi—Xeಠe¼q*9Õ@<—¡þ‘ªv_¥œafÄvaS ig™ct‘t³ˆ!Å´Ô^f8»p³&•#Ñͬ–ä†âä÷:$Š#Äâ£Ä‹#¸âøû|ä¨Yðó>$Òˆ;³Ðïáå`ЀÖÕg ³ûàÕ½x»0  $¯¼æ  fì@mÞIqß^ÔÚK¡PÄÙ·ŸöD2‰9>¦Rý:ºñÆJ¯’÷½ï}úÆÒ¢¡:»æ 8ewXi#òéè°Oó¹ï aYI3,éê(#,ï!ƒÐ㤨Ԙ²C Ê»ØÄñ‰!qB}%ŽŸYÂÈc¿%æFXÚ%–v)…2')÷ßI…”Aõã\Á »¥• î¹¶ï¹]Ñ>¤-¢¾Ûm½½t¦ö0ÅßÌoßJ›ßËhOŒLï fnÁ1Ù• ^Èo&í “ßå z‚þ+®8K¡öu!¶ Š.x«æcÍœû·ÃžÝ¸»0Ü™¡eÅ…0¥Ú÷¢^ÜA±« µêð\ÄŠn¬ž>¦Åã˜ó L{©$¶–ÎÛAÎû-gž_|ñÅ477ëÛFˆ†ÆŸgÁbW_U,‚*F\_n$ÜØ+,íbz¶b)0ü ¬Ð:00±Âò.~nƆ^2®Ä±J»¤LXÞ%©7YÁC¦|¤ J»˜ŽËþb)]/'©Û¶VØ•äAÇ ˆ#´@Ìhë-ÐYØÃ"µ‰‘} ¦æ÷²¨uý½­ÐV_–é<vÛøû$˜>Þ‚i¤ò>þËû‘=>EÛÁYýÄÌ-°óUÔ«ÛÉwRV=kBˆÃætvuu100ÀòåËËUxN?ýtf̘¡¯yM ¯ »Ô¼–¶ŒÐ¹‘šZi¹âJ‚õ>(ߢÂFO*gJUq‚0ä8üàæ"ƒC06÷£¦tI¬"«Ú´$œWòÈS:èÙ‚ÿÒ(Â{;²-MšÁ§w@|Ìš'Î…=Ï!Z΀™«!1S{‰Üv´f ÅGÌñIx^å—â°°,&ƒ‡zˆW_}•X,Æg?ûYfΜYþ,~ÊÈkÑÐИé·¼qÖYß·ôóPåR¼ÁkIo)k/>»öíÀuwÔw_E“›eEÿh‡d<$æ&¦ì@íhÃÉ,¥iË3H÷X˜2±¬ ñäÃ[³‡A5ýÍL¹èâÀjÈøˆYÉ¢[±$Dqv0ü&~üãAßw¿ûÝúÂÔ¢¡qøcR½¿•h,aYýB¡È=lª±>ÂQn[SºD¶B«Z›š˜k#>c °»eCS,8}1é™ç â³·Y›}¬‰†’`J¤içààÑGÐ £4hha2!ŠžÉ£öTGm×Aƒ”Q%žÛM0EÒ‘™6[.…Ys1.ž‚Ì,‚æf8É#y¢ªDAIyP“÷5üqr¹3fÌ`Þ¼yúzÓ¢¡qäâþá±’ýBÃÐ]Óú~„ˆhƒ&'p_uh“`vÎÈÁâåÄÞ},"¿Ö8jŽåèè(_ýêWX´hË—/ט& #uÁsyå•>ÆF_™€)]bW‰çFK@í¢2ç_€ÕÜ †‰l9:svìØA?W\q…¾À4hh¹Ø¶í·ßþJhuDK—”¬'Ð?2²Jÿˆ§B×UdXíí‡}tÔÁ„çyÜpà œtÒIœuTihÑÐ8ä¸ûîRëÚ’-œ’GÉ}ÕQ±@š-h—Ð!"i‚£š<¶lÙÂ~ô£2™|ãßÀ÷ƒÊgu–îD¨ DCãÈÂý÷wQyU*Û©¼·ÊÂ9`7ÄQÐ;DÐ)øhÇc=!æ»imm-ˆîù¡ DCãˆÂ£îâá‡wP?y0 Ý•4Wgž§c·U‡Ó }8¹í¶ÛX¸p!ÉdR×¾z!õ!ÐÐx}‘ÍÉf]ªµ³ºt‰U]ºD´M£’ÖÖÏ<ó ?þ8RJ®¼òJ2™Œ>(š@44Ž\X–i:ŒíûáT’“Õ¥Kœt…8J$¢Ÿ³á_ÿõ_éééÁq®ºê*}@4hhÙ8ûìYœ{î|ÆöýˆU,ñ<«è%÷•F<h¡\ˆ†ÆÑ„Ú²íaø®ŒA¬Z<—mË£D IM üô§?eÆ š@4hhâDH$V±@ÒF¥ë`;Ä“!yÈŠõaéÈ /¼€çytttpúé§ër ”zkhhTáöÛwpÉ%ô·Í€Ñf;˜m°ÄUÀ*'Açl8Ý„SŒ`œ !u”[ ½½½ÌŸ?ŸÁÁA®½öZÒé4;wî`Á‚:ýu‚ãÕÐ8X¶¬™ Aˆ)Û r?¬óRé’öšÌsûßúÖ·Ä0 N9åÖ®]«Š& £Æø DE¢¯h’Õ¹ñŠëJç~( <ôÐC¼å-oÑäq¡5 C€LÆbÑ¢¦Jß r?jÄó«:ú*£­òù<<ðÔ¾Ò8 ,ÁÁAžy晪Óé4+W®ÔGICãÓ§;œ}ö6uõè$«Ås'3¶p¢­_ûÚט6mëÖ­Óäp o¼‘ïÿû ÓvWknnfÙ²e WýP2™äþáê~áœ9sR6ß}˜1ð0¶µý#ãT'¶í2رc?øÁxÛÛÞÆüùóõut8Èÿý¿ÿ— °lÙ²*«ãW¿ú7nóƒW\q÷Ýwߘù}èCu ˜}úÓŸfúôécæ Ã@m—k}–TÜõë÷ýh5ªK—¤ômÂèêêàâ‹/Öä£*Œ÷—¿ü%^xáŸô…O<ñD¹¸Y]]]ÜrË-cæ/¿ürŽ=öØ1óçœs'žx¢>CG,²#ŠÔ±ÝГ€Ž$œ(‚ðÝS!u,¬t`Uº{šÓ¥.ݾvíZî½÷^n¿ývM"‡Läóyz{{ÇÌ÷õõ•ÝaÛ·o'•JÑÚÚJ&“áî»ï³ÿ™gžY÷¢™>}:gžy¦>£o,yÓèNÀN¦L ³fÂ*3 UN2´²wï^Ö®]˳Ï>˧>õ)Ö®]Ë=÷ÜÀ¥—^ª“ d™ n¾ùfæÏŸÏªU«€J›Z\ýõôõõ™/õˆâ#ù‹/3?þ|¦Nª¯CK «rˆ¬ƒZl” Ä:ŽK‡äZ K¥Ö?þã?þƒ|ä#$ 6nÜÈÌ™3õEtˆqXålÞ¼™óÎ;¯¼}Ê)§ÔÝï®»î3·{÷n}ôÑ1ó{öìá²Ë.3¿råʺ}Î=÷\Þþö·™O$´¶¶ê+Fã Ž#ø³w:Üñû"£íFYÈŠ+þèEzúôé¼ûÝï®ûY½2ÏÅb‘o|ãcæn¹å®¾új²ÙlÕgK–,©K,sæÌÑe¤5þ¸›Ï€Çùü÷«FÛcAßvh3ª 'êÜÀ±oß> øÑÐR¥«W¯~Ý~ŸeY\}õÕUs×\s ÷Ýw¼z_ÿú×Ù¾}{ÕÜÖ­[Y²d ›6mªšO§Ó\wÝuu¿çŠ+®Ð­65°ãEš¦`dJ·ÃÄn H#Ú¶6¦Ï?ÿ<½½½´¶¶Ö ºÑ84ÐÅ#èïï§¥¥å5ÿ\ww7###cæïºë®rÆlžçñì³ÏŽ™ÿìg?Ë´iÓÆÌŸvÚiuç5Þø¸ûéÿÏÃy±iÙIÚÀ©&œê'Ak£sæÌaûöí¼ç=ïáæ›oÖDÈÑ‹={ö°yóæ1óÿøÇ±í±¹Æ¶mcÕÚÚÚøÂ¾0ö„ ¡ÃŸß`¸à?×ópò8FŽK³°=Ù-ȱ†Î>ÿþ÷¿Ïºuëð<{î¹G÷þ8Œ ý(‡tvvVÍår9ÞñŽwpà 7ŒÙÿ7¿ù »wï3ÿ¥/}‰Gyd \tÑE Ùÿ‹_üb] «¹¹¹.qi¼>H4çXع™M©ªJ—è¾k{Æ xžÇñÇÏúõëËy «V­âÏþìÏô¤-ï~÷»œ~úé,[¶ìOþ®'žx‚_ÿú×cæ_xá~úÓŸŽ™ï{ßËìÙ³ÇÌ_zé¥Úšyð-Oò«ô~ž‰]ÀªÐ}uª'>ÊÝW凞óÏ?¿œ÷¡¡-^zé%J-+…îIDATþê¯þêå»V­ZUÎ¥‰Â÷}¾÷½ï™ß¹s'7Üp6l¨*cóï|‡3Î8cÌþçŸ~ÝÚÇs kÖ¬Ñ'ó5âÄéͬgí~Xº=ºïU¡ù_þò—õшF=twwÓÑÑqHÿw¿û]>÷¹ÏUΖ-[êîÿ…/|\.W5—N§yå•W¬šŸ?>ÿøÇÇ.œ'ž8Æ•w4â ï%î¿çÕâZ:içÔ0ypÊQN ƒƒƒ\rÉ%Üÿý\vÙeÜtÓMÚÕª-z8”äòçþçUsRJ-ZTwÿzuÍ pŸÕVo†@}þùç«æ–,YBOOϘ}/¼ðBÎ9çœ1ómmm̘1ãˆ;÷i#F'IrBÅx…v]AP?ïþûï/_+š<4h¦°,‹¹sçþÉßSÏuÔ%„l6Ë­·ÞZÞþÙÏ~V&±sÎ9gLišÅ‹³lÙ²1óK–,©ÛÂ0 2™Ìaì—2Ýt“FÐ D€£/I~ö³Ÿ•ßúÓŸÖDˆ†FÉd’~ðƒåíçž{®¼â[ßúÖ˜¢œù|ž“O>yŒ»­½½}ìcu‰å‹_üâau,2$9ß,ÒåéÒ%Qk¶ô0Q¯ìÆ¡‡Ö@4 üâ¿ ¹¹ù®FËåp]wÌü­·ÞÊúõëÇÌoݺ•'Ÿ|rÌüµ×^[×j¹ð jñÍtѬ:Øé'Xaè'»{ï½— .¸Ïó¸îºë;Â×8ŒD)Åç>÷9®¹æ:::øÝï~Ç-·ÜÂܹsY·n±XŒ'žx‚›o¾™9sæ°nÝ:âñxÝïzúé§ùÉO~¬Y³X·nÉdRŸå7þîïþŽÏþó$‰×å÷õôô°ÿþò¶çyÜxã¬Y³†ÿøÇcöommå¹çž«š›5kÖ˜r8¸Ï>ûì×ô÷Œ’ÇÇd@L×ú«W¯æ¡‡"“ÉðÍo~³Ün{êÔ©|ö³ŸÕHH€b±ÈM7ÝÄc=Æõ×_O?=öý×ͶmÛ¸óÎ;9ï¼óx衇X·n]]]ÜqÇ|âŸó][¶láž{îáŠ+®`ÇŽÜvÛm|êSŸÒgù €—_~™%K–²ßÇw°téÒº¥ÿ!è„WÏ’ótlYkÖ¬aãÆcôšüÇ$[ÝjÞüyÄœ Ý4ª¿¿Ÿ•+W²mÛ6>ó™ÏðOÿ{gÒ:Åñ¿¡—¨ØbÔŠbi£B1~l‚ˆ$88ùA2¹9w/.â¡ ‚“CD;(ø5ԥЊ-Li}ƒx1ïÞ÷5ÿ×ãd߈|~Ïëk3ØÃ/š¡g tÜ¡½P€ÁzÔècº-ÛQYt ¢/s"KG¢|†×£¥jÙY©„óàØÈ<:}Ú4‘– aÍd&6ISå3ž¬5‡¦:—aP¿¥fGñIR'ÓAŸO­¯@OºÑõR—% ³JIîRC´£½ªÖáMë2ÄEèÍ‚%HгJƒ›¼Õæd•pÅNëtq¸.ŠÖDz!¹ ¯‚ñ)|h6ȽAqÁh_牕Ԗ”J¦vÉØáÜ×ò‹;¡ ©=úœ´u ¶ ³6Ñì½õÝ…p„TÛAp Ä Â,ÍÚÝ ˆl|ÿªÁf]Hu)f¤;exoågÓç.p ð¥Å0¤n»¹0{[ЏbX+ò0¤î{€$’¦1–äF«4LBê®ys«ZÚi× '!uWñƲÝÖÖCTuvR÷”“9Ob÷N`Je´/‹ CêŸÞÀ£úŸ†Ô=õ³å ÕtkIEND®B`‚snd-16.1/pix/fmeq38.png0000644000076400007640000000113711147553267012761 0ustar bilbil‰PNG  IHDRg€&‚l3PLTEÿÿÿÐÐÐPPP   €€€ÀÀÀ000```ðððààà@@@°°°ppp bƒº{ pHYs  šœtIME×  ;!ÿoW“¿IDATHǽV‰®„ ,Ðr èÿíãˆ÷ɺ‰ÑIÜÄ=:v¦Sàž¼«¢VÏÓx“¯àç[~ ô†r™ë‡`QðÎ$¼B#¸ççHdªsÄxãÄ¥ÍRµr§s½… ¾CDV3»ÃŠÒ/N›Þ?@0ö·ödb=ae óà;yþ eÃÀó+VŽÒÒóK©f)xù²È|þªÿ&´g ckÌJØF4×<^"ˆ`½ÐÂÇ4çQ »Ód“Yo’µ¯¯yêUò˜uqzÎcX⥩´)¢˜ÜPÏãŽ)µ+ô'Ðížyš=Éê]öóç8ÿ®ÙÓdj<ÕHr¨çhÇŒG~çÙ,¨Z‰ý)ö€XÅàÏ”‡´&Ò ©Uz Ƨp>çÄ☧L á–“i:™7•BºÞCàygTX>¿šîRxFã‰egû€¥$²ñ˜Æ¡ÆxÞ‡­=•¦ˆ?ÈfzÃnäË_gÿ0aj)Jz—¼Ë’ý?ŒEÝGú8Ú“ÿ'˜hé 5¯îãÒᩈ ?öO™€µPE,‚£ÜâÔžœJ*[ý%Ó„;dÇþÚg8V#¿þÙâÁ˜áíÿ¾Lœ—ŒK"ÈD±wB€C³Ófä DSZéð£[‰´É‘—Æ” F~PDƒ#î,­@¼‹öÖW&8È@E˜Äš-#hmfvm}š’u6ð°–ášÉéÚ,¦>]jVÖÆçͲBî×öÖW&N Ý\œ$^RÖªxa¼š¥8kÊŠ1®šÐ¨8tÓ,[´€†m–ùí­ÿ®L¨’©B®RCÜ0j³˜¥ÞVåC-Åóƒü)ÚèÐ.ZºD{ë¿+WG·Ôµu­SZ·•f‘*ª¢)ÏúhÒ¾8LßÑÖ×ÜÚwZ¸D°­í|ŽöÖ_&S,ÖeZL@*º"í7UĦµæ¯J½ Á"³£a–z±Š<ƒñ‚=Æ: S\§Š>o–18KSØÂ½÷ß™ Ô—UøÚ‚û›m%þ°?—ùSN)!¡ÄxWcŒðÎÿ0¹Úùo¶Þ²ïÉÙ°ßÖË9óËã&ù›Ï,I_ˆÆæu/ƒé÷ßj0!4˜öpòèñ!Þãk¾“˜ç çyôú–IEND®B`‚snd-16.1/pix/noidchoices.png0000644000076400007640000006100011257645027014136 0ustar bilbil‰PNG  IHDRèiºñ›sRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ :ò’»5 IDATxÚìÝyP”gžðo7÷}¶Ü‚ÜET¢ oEÅDMbMŒÓ›lMvjvvg¶vkwv+U™™šÙÙJ'1Æh‚‘xx"¢r)‡( rIsÍÙܽ8ýM¿ ÝÐ ÝÍïSe•ôûöÓïûôû¾ýþÞçy~G"‘H@!„B!„YÅ¥* „B!„B´4@¯­­EMM ëÚÛÛ!P__OµGˆ–innFii)ë²ÞÞ^TUUQE¢çîÞ½«pÙãÇqêÔ) RE¢‡ͺlhh§OŸFNNU!º  …Büøã¨®®f}CBBø|>’““©öѲàûLæµÈÈHæÿ2OÈ !úië֭غu«Ìk¿ýío™ÿ¯[·ëÖ­£Š"DÙÚÚÊýÖ»ººâ׿þ5€W½í>L5F__ åzèºÆÆFÌŸ?ƒƒƒz·oRÎÎÎhhh€‹‹Ë¤ë~ýõ×°··ÇîÝ»ahh¨Tù###ÈÎΞ´•¾ªª ,PÛ~Ñ4kzÄÚÚ]]]T„B!„(áóÏ?GJJŠVnÛÍ›7§õþ 6àÖ­[zûÝ`ttT©uGGGáææ†’’¥Ë¯¨¨ÀŸþô§I׫ªª‚¿¿¿Ú†‰R€®'.]º„ßüæ7xöìU!„B!¸\®ÎæÆª¨¨ /p^^^ gc³dÉ<~üXéõ>|ˆ­[·*•<ÝÞÞ “¿‰D”5ŸB!„¿IKKÓÙ!=/_¾Ä;wÐÝÝ=¥÷÷öö"((555zûý†††¢°°pÒõº»»aeesss•¦îíí…­­-†‡‡gt¿(@'„B!„è‰D¢³ÛÞÒÒG_¢¤¦¦2j ´¾Gè„B!„+++Ã_ÿúW­Ú&'''455Ñ—£Cúûûabb2¥÷r8­pC:!„B!DãFFFPTT¤5Iïß¿ÈÈH¥íwß}Wéõt*“=è„B!„ËÍÍEdd$´b{jjj0þüYùle²‰oß¾—/_žÖ縹¹A(Îéã®­­ ŽŽŽ€¸¸8œ?^é÷®_¿·oßžÑí5TgagΜAGGè DˆILLDcc#ªªª¨2™£ºººþþ~ª Bæ ÌÌL#''~~~ùŒÞÞ^Wý7·o߆§§',--®ckk‹ÊÊJ•ËÎÏÏÇÒ¥KÆÆÆj›þKØÛÛ£½½}ÒõŽ;†#GŽÀÐÐP©‹/FAA6nܨ]úþýû ôíÏccc Ly\™›vïÞ `úómBt—µµ5ø|>º»»qöìYªB昨¨(DEE¡­­M£Ÿãîºº9¨755!-- ;vì`]ÞÞÞ>åÖ}‰D‡£·u744CCåÂØºº:¸»»k¼}||pãÆ µìuq×34ކB!„h¥×_< Š˜Dyy9üýý©"Ï\®ral__ÌÍÍujÿ(@'„CÈ!„ÉÕ××ÃÕÕuÖ‚ÈÆÆFÖe÷îÝCdd$}A³ÄÖÖ"‘H-eݾ}ëׯ§B沓'OâÚµkT„BȺ»»amm=+Ÿ=44„+W®°.«®®†§§§Æ>»¹¹óæÍ£@ððpäåå©¥¬ŠŠ øúúR€N!s™ %ô#„B”‰{÷îÍègŠD"üôÓO³²¿ÕÕÕðòò¢/ÔÅB!„B´ŽD"™ÑÏ;þ<âââ.çñxhiiÑøv899¡©©Io¾Ç¶¶6ØÛÛ+½þýû÷±råJ™×,--ÑÓÓ3éñ2[‰ö(@'„d``€‘‘ªB!sJff¦Ú¦ ‰D°µµ•ý055‘ùàÃÂÂðèÑ#½ùþËÊÊ8­2\]]Q__?á:£££J'¢£B‚‚‚PRRBA!dÎhmmÅÅ‹qáµ”'Ínff±XL¬…æbb\ Ð !D‡¤¦¦"::š*‚BÈœü ü—ùttt¨µ\ÔÖÖª}{CCCQXX(÷zOO,,,è UÂçŸ>çz R€N!:¤«« 666T„Bæ,cccµus×$sssôõõɽ>:: …¡¡ÖíOuuõŒ~ÞÇ1<<>ï¼óŽÆ?_(ªœµßÔԔΠBBBP\\L:!„B!ê422;;;twwSeè¨ööv888PE¨AKK x<ÞŒ~fEE“ N:s [Ï ¨õ³ÛÚÚ`oo?kõM:!„B!ã8::¢µµ•*‚¨llkÿø纺:Í5?Užžž¨®®V¸¼ªª ,˜ÑmÊÎÎÆŠ+ü} ºX,–›BÎÌÌ b±˜µŒ©Ní7¾g¢ž B‘a``€‘‘ªB!Z¡¬¬ B¡pÒõ\]]Q__¯5ۆǫ­¼ššxzzoáÖ蘘ܼyS浑‘8ŽJå­_¿·nÝÒúãqìøp6o¼ñ†Væ™Pk€ÞÝÝ ‘HD7Œ³pð©zb2VOOD"†††¨2™Ã¿%"‘]]]TdN«¯¯‡««ëœÛo±X ‘H4­ñÅgϞŽ{÷&]oÕªUÈÊÊR©ìÚÚZÌŸ?Ÿù›Ãá@"‘Ly[Ǩ3ÝB:ÓØˆ ÀÄÄdJå¹¹¹Íø+++ÀµQ]]<<<¨"Ȕݿ)))“N±AÑ_}}}HIIÁõëש2Èœ¿¯Ò¶.È3¡¤¤)))(//ŸrhkkÓÈöUWWÃËËKmzII ‚‚‚è€WBee¥Lw ôööÎè6X[[ãîÝ» ÕèçhÃl9jÌnÛ¶m€o¾ù†ŽdBtHLL àܹsT„ÌQ–––xûí·ÑÝÝo¿ý–*„ü}z.KKK½ß×ððp„‡‡£²²R/÷OÚÕ|ª­Æs™6$Ü[»v­ÜøsuýÚØkŒÆ B!„ÂBß»>k[·am0­¾³!;;Ë—/—yÍØØƒƒƒ¾ÏÐÐP¥¡ŽªÌC¯666Lƒ’²ÆOÍ7ž¶æò¡B!„¢šìæ>ñx<´´´(½þÓ§OåºîbxxxÂ÷¹¹¹)•àOJ›^ùøøàÅ‹zóS€N!:âÅ‹ðöö¦Š „Y&‘HÐÓÓC1ƒõ=[‰»š››QWW7kû>~š6ua›S\þþþÓÊW NVVVèîîVKY“µºS€N!„1<<,ó£´´4ªBQ£ñ ±Øôôôà£>BUUUØßäääÈu­Ö´™CÜÐЀšš½û¾~úé'8p`Ze(Óu^Ûyxx ¶¶–ùûÂ… سgè„BTççç‡çÏŸSEBˆ)“+%%_|ñ222¨Âþfü4hãƒ\µfhh( 4º_Ój)Þ¼y3®^½ÊºÌÝÝ}V[ç§k×®]HLLÔéãÖÎÎ"‘H«¶‰tB!„ÌŠ®®®iM“Dˆ¦-\¸%%%¬A¼‡‡UJ¬5˜™™A,˼V^^ÜŸÞÞ^¹ýQ…½½=:::X—±_š`bb2¥®ò½½½°°°`]æàà@I)@'„Bˆ¾HHH@rr2UÑZÞÞÞvc744ÔÊ,гiùòåÈÉÉ™p}è­kBCCQTTD1NPPž¯¥¥<:$‰è—ñ³e°©­­…‡‡‡Þí{ff&Á¤ÝÓµÉDã»É̈ˆˆÀƒô~?íììäÆÛ?~üK–,QºŒgÏžÍ|€¾ÿ~ðù|di$ì¦;‡!!°{÷nðùüI§•!Úodd+V¬ ¢2kkkðù||ôÑG3òyB¡pÂV&2}/_¾¤JЀ¢¢"„††êÝ~EEEÏçkeëî±cÇpäȹ×ÝÜÜ  §Tf?LMM•Zw.ôNµ°°@__ŸNnûtçŠ?|ø0¾ûî» ×qww—;ÖÆ÷±··G[[›Â2R3?PwBÑ3‡2c­×ÒÒ‚yóæx• x¢›M»ÿ>N:¥òûÎ;§µCJîܹƒS§Né|¯Æ¯¾újÒ®§"‘ÇÇ7ß|ƒ¦¦&¥Ê­®®f}]Ùq«dfibÜv^^ÂÃÃ'\§¶¶VénÒºníÚµ¸sçŽVlKcc#œ•^?,, =šòç`ddYYYX¹rå´î¿&"‘H0::*÷zff¦Ì Ð !D‡­Zµ YYYdǵñx<´´´P­ÔÕÕ+++æïé¶~L‡X,FYYÄb1ë“"W®\ÁŠ+¦5?²&•––âÓO?Õ霙°GÐÐÐ’““qðàA>|™™™“>ìéììÄçŸÎ¤§¥¥!::Z¥íÔ¶ñ«ä•k×®aóæÍ2ß“ªSâݸq7nÔ‹úpvvFcc#€WC9 ÕR®­­­ÚþÍÖ8ýÆÆFõÿñÇñ_ÿõ_¨¨¨`ýܱ³P€N!:ll`300À$7’> +77‰‰‰TidÖeee!22R+¶ååË—ððð€““kë«X,ÆóçÏå^¯­­Åüùó§ÕÅVSúúú`jj XXX¨ÔŠÞ××Çz9îß¿O>ùd–±´´4DEEÁØØ†††ˆ‹‹ÃÏ?ÿnÞ¼‰˜˜µ”koo¯s¡/]º¶¶¶prrÒHù===°³³c}HÔÝÝ kkk ÐuQ}}=Ž?>¥÷Þ¾}÷ïß§J$D‡M÷‰òãÇiL*™’¢¢¢iÍWþå—_Ê´jVUUÉä¼X³fRãò °°•••jÛ·Û·ocýúõصk’’’ä–?xðYYY2A¢H$‚­­-í›ZQQ___¯¦³êêêRú½çÎí[·ÐÝÝ=ázmmm8qâÄŒÌe…ÌÌLÖe/^¼€JåÝ»w«V­šòö455iì&~.Y°`Z’ÓêÊ”mD»­X±ëÖ­›•ÏŸtréÒ%˜ššN)[eYY © ÑaÝÝÝ2Ý‚ÀÈȈyûäÉvîÜ)P 88o¿ý¶\ëÒÈÈqùòeªd¢0 ™?þ”féêêBoo¯ÂK• ···>DzzúŒí{ii)Þÿ}™}¯¯¯gºAj²{~}}=~øáôööªô¾û÷ï3ã(ßxã ¥ëkhhƒƒƒ8rä~úé'…ëeffâÖ­[8pà¾ÿþ{ß°ªš£àÝwßÅ?þ8á1icc£¶mí Ú ´´t±Ôííí°··WjÝÜÜÜIÇêõ¢]‡ŒŽŽÂÎÎNæIxss3“dGÊÜÜ\îÇœÃáÀÑёƤ¢g¼½½™ÖD‰DÂ$(100O+½awttÄàà LëXII æÍ›CCCÖÖŒ+W®Ìù›Ï¹,;;+V¬@XX XÇi+J¸¼ê‚üÎ;ï ±±Q¥1Þl._¾Œ½{÷ÂÄÄD¥Vaukkkƒ££#€W­.ÙÙÙ¬ë=zô'OžœR+sww7NŸ>7Þxׯ_Wé^3w3—ËUºÞ¥ÝöنȌU\\Œ}ûöÁÔÔŽŽŽÌ¸Vu’n ¸ºº¢¾¾^n¶{ 066VªÎÕÕ5ÝÆÆƒƒƒjé®­«ÆþþHï;)Y©ú˜››«%úôbWW—L—ê‰<}úAAA®ÃãñÐÜÜL_”爱±1(@×5ÅÅÅrsPž;w{÷î…Ì8›üü|,]ºTf]gggÖqtÛ¶mÕ+Wd^«¨¨Pº[!!D{ír;™ÈÈHÜ»wùûÞ½{ˆŒŒÄæÍ›qíÚ5™u?~ .—‹Û·oËDb±§OŸfû×ßß?iY¢Ævçe |pùòe…I²êëëáêꊥK—"??ÏŸ?‡ŸŸŸÊÛ1:: ‘H{{{¹cxÕd¢@´¬¬Lån°cç¸ûZ\\ŒIßÿðáC„……) à'RYY‰•+WÂÕÕ­­­J¿o:Ó¯*“k|6íØØX\¾|yÚ_Æ“=˜Û=˜˜˜Lz (?EWpp0ž©^kk+(@×£££ÈÎΖGWYY‰ºº:¹Œ¥½½½°°°À¦M›pãÆ •>ëîÝ»X½z5k2Ž{÷îÁÈÈHn|z}}=²³³UîVG™c»´Ž7¾•i츿‰º¹uuu¡¤¤[¶lÁ[o½…øøxf™P(ıcǰuëVœ;wNæÚ244„?üáHJJBjjª\¹çÎÙ3g亶¶6dgg³&›éêêBMM }Ñ3l``---Ì´SãgèééÁàà ¶lÙÂú]wttÀÎΰlÙ2”——###‹/Vy[ÆŽ«öòòBmm­L+ojj*¾ýö[…­v©©©8}úô„Ÿamm-ó êáLjˆˆ…IäIMMźuë°hÑ"«¼¿YYYXµj 0oÞ<Öd6'NœÀ¡C‡Tþ¼ÎÎN™nߊ¦-JMM•Érn``OOOµæ`Ã63EKK x<ëúèéé™°Le{Œ­ EÙ¯_{í5­I|¨„B!ÜÜÜtvûÕÕ‚=Û½ 8€¿þõ¯L uêÌÅ1þz4Ê>HmÍÍÍr9-(@W£gϞɽVWWÇ:>«¸¸¸xñ¢ÌMjYYe¦Nä“Lõ¦fü¶ÙÛÛcÅŠr7.\€¡¡!Ο?/÷¾ÄÄD”””(µÿ„Íspp@^^¼¼¼d^‰‰ÁÍ›7‘˜˜ˆÝ»wË,“v?LOOÇo¼Á¼Î< <þ<öìÙÃ,óòòbû´´4:t¶¶¶X²d‰ÌC¾óçÏã“O>ÁÁƒÑÙÙ)óÔÿ?þã?°víZøøøàÌ™32\ZZ qûöm™§Ëb±)))xòä ¾úê+™ ééÓ§(((ÙÇÊÊJ|ýõ×r­ÿõõõøê«¯PVVÆ}ÿý÷(**’[–ŸŸ›7o*ý ë²³³enß¾]&W4ï••k‰ÌÌLDEE1oذb±XaP¥Š×^{ ¥¥¥Ìƒ„ÚÚZìÞ½çΓ[·ººšu.ãñSj-]ºTá”^&&&pwwÇÿøG¥ÆÚ–••! €9w&0ÙM¼ª‰ÞÆ `=ÖÇÊÉÉÁ²e˘¿çÏŸÚÚZÖ‡eã»ÆFDDL)?*,--åîžžXZZ²®¿páBÖsòùóçÌ=ÑT²ˆ×ÕÕét 9[TéåE4«§§j-“­W™:µè¨ªªbþõ÷÷#33SnZ‘‘äææÊ]ðÅb1îܹ#×ÍH"‘àòåËxôè‘ÜÎüü|Ö¤'·nÝÂÙ³gåRØ—””ÈuÝ”Þ<ÄÇÇËu…ºxñ"\·²øøxüå/‘»q»qãðõ×_Ëܤddd`Ë–-øóŸÿ,³ßYYYxûí·1þ|Ö̶ãŽh¢›†ôbi``¦úúú`ee…¥K—¢¿¿Ÿy€0::ŠÿþïÿÆÊ•+‘““#ó£vüøq444àüùó2----øÓŸþ„?ÿùÏ2ŸÝÛÛ‹ï¾ûgΜ‘é.9::Ф¤$ÖdUÒLºã¥¤¤àÂ… rãå?~Ì:¶¬¢¢ rÝ4›››qçι› ®®.ܹsG®ëNkk+îܹ£Ó­z2çnoo/:::˜€çĉ2OŒ{zzpìØ1™óixxçÏŸgÞ7vJ"‰D‚K—.),ïÚµkÌÔR}}}øþûï!ä¦üyùò%þüç?#55Uî‰öõë×!X{šddd@ àÅ‹¬ÈÝ»wå^ÂÙ³gYƒ²þþ~;vŒu¬£P(d=^WY¨M{ÔÜܬòxU[[[Ö®`îîîhnn†±±±Üõã£>—_~‰ŽŽ™ÖõeË–¡¶¶999prr’™¢F:öÎ; a>300 z Ð IDAT¸sçàååŴ𯯯âÒ¥K¨ªªBbb">ùäðx<,_¾Û¶m÷ß~‹ªª*dffâõ×_ÇÒ¥K‡””æ¸üÏÿüO¼ùæ›Øºu+âââpïÞ=ˆD"<}úÍÍÍàóùàóùèëëÃ088ˆÂÂB”——ã¿øŽ9‚+W®0׿[·n!''GÅË—/‘œœŒÑÑQˆÅb¤§§ÃÒÒûöíCWW“\SìÃÛÛ[æZ___@ Óãï„B!Sß555@kk+jjj&l(((ÀâÅ‹1oÞ<¥öÞ¼yøôÓO§´ã»ÆÍü.¶Çã±v‰D°³³Ã[o½%“$±££C&h066–¹?®vÆ ø‡ø•çÉ^»v-îܹ£R€>ös}}}§5õ™2Yò+**dêWÑ8t¶Öžñ=¦ëæÍ›Ø°aƒÌkÌàUR2éETغ¹OwŠ¿'OžèD«œ*úûûeŒx6)Ó[b¼ñC5Ô©¤¤dÒ1Û³ÉËË ¯½öšVl‹¢øLŸYXXLÚCY-_kk+JKK™b±ÎÎÎxðàÓ¢Q__'N@"‘ ¨¨ˆ jž>}Š„„ðx<äååáÁƒL¹W®\ÁâÅ‹188ˆ‹/ÊçÃÃÃpvv– Òoݺ///DGGËL•RRR‚ÖÖVÊ™™™°µµÅŽ;””Ä¢/^¼€‰‰ ø|>Ξ=+óã5oÞ<üò—¿Ä£GðôéSæiêÀÀ¢££qèÐ!æÇ¿¹¹&&&prr¡C‡˜ ¶c»›îÙ³‡™“±¿¿Ÿ™Wsì\…SÁÖl>>ˆŽŽFTT3F§¶¶©©©xï½÷°mÛ6ܺu‹ùìË—/c×®] •iy»xñ""""°xñb™ ýÁƒ055…¥¥¥LГ’’‚àà`¬ZµJflÐãÇ!‹ááá!¤§¦¦¢²²1112óA—––âîÝ»àñx¸té³Mmmm¸víx<~úé'ææ ºº©©©àñx(..f øtAGG‡Ì¹ÛÓÓƒû÷ï3ÏpéÒ%\¹r?üðqèÐ!ðù| !!W®\Áùóç±zõjæ}ÕÕÕHJJBss3~þùg„……Ïçcÿþý¸téúúúÐÙÙ‰””€Ïç#??ŸI„$‹qéÒ%ìÛ·|>•••ÌÍé‹/••…C‡ÁÍÍ —.]b½|ùCCCàóù9‡rrr`aa>Ÿôôt™ ø»ï¾ƒ¡¡!ìììä2M'%%!::b±Xî!âõë×±jÕ*$&&Êûì3¹×MMM±eËìÝ»Wn™¡¡!¢££±k×.¹Ä>»wïÆÀÀ¶nÝ*ó333¼þúëàñxr]”/^ ‡˜˜¼þúëÿ‘ár±}ûv”––båÊ•2-§vvvGii)/^Ìt£ær¹Ø¿?s\þþ÷¿gn¤x<V®\‰«W¯¢¹¹k×®eÊ[¹r%LLLpêÔ)twwcÓ¦Màp8LyÉÉÉðòòBll,8Ö¯_åË—ãØ±cHHH€³³3BCCaff†ÈÈHôôô@  ¼¼|>+V¬€¯¯/Ž9”— >Ÿ5kÖèì CMM Sßååå‹ÅHMMÅÛo¿­ð=ÃÃÃàr¹Ìö±­­­Jw¥\»ví„ÙÆkjjX[Á¥×ð‰Zµ¥C@&˶íããÃ\ÏÙ†p¹\™‡VRl9^Æ277—ËU:ˆ¸zõªÌù§¨5[Y“%}kkkƒÌµ@Õ.ýÓÚÆ±FGGå‚§ñSr¥¥¥M8%Ò¢E‹X{ÁŒŸÃ\¦¦¦zN,ËÜ ¨’ó@lÛ¶ )))*½‡­«ùtϳ±ñ[ÏUmÁçóáíí­Û’‘‘¡–©öfÂØ\ÓÁ–ïGîMìçç'óÔõóÏ?‡ŸŸ"""pÿþ}¸ººâðáÃÌù•+W’’‚… âƒ>áÑ£G^u¥óðð€‡‡ššš˜×—.]Š+V0Ÿ'}}Æ Ìvlܸ‘y=((HæÆIúº­­-Óõnûöí8qâ|||044„M›6víÚ@€;v ;;qqq€·Þz ßÿ=|||˜©F¤OßÐÐЀëׯcß¾}^uOëëëÃÐÐrsseº‘ýÑÛ]Úµ¨¨¡¡¡*}'c»mý1Ú½{7kwWWWW!,, Ìô1111ðõõÅ;wÀçó™§oéééEVV<Èü ·µµa``7nÜÀ›o¾ 8::¢¸¸/_¾Ä•+W°víZØÛÛÃÞÞÝÝÝHMMEYYöìÙÃ<™‰Døío www¼þúëL¢žÂÂBæ;ܺu+sözõjæõÅ‹ˌǕ¾ÍÜÄmݺ•y=00ùnƒ‚‚PPP@ìÞ½FFF BZZÒÒÒàåå…·Þz‹Y_WyyyÉt‹þæ›odn MMM‹ææfØÛÛËt%ôöö† z{{akk+ÓåqÆ hhh@FF6nÜÈ´¦š™™açÎøùçŸadd„½{÷2ÉRvî܉/^@ ÀÌÌ ûöícn„cbbð§?ý fffðööÆöíÛaaaxzz"!!b±îîîØ¾};sN_¾|………°°°@kk+bccûöíÙ3gðÞ{ï!;;¡¡¡L¢¡ââb¦[îÐÐD"±qãFœ>}‡”——ÃÂÂAAAèëëC~~>s^—””`Ó¦MpuuEjj*˜º‘&ÌZ¸p!.^¼ˆ;w2Ë:;;¼¼<•ÏyE&šFeáÂ… —í–<>WDѹàââÂ\SÆ“ž×ãq8lÞ¼YayÒkîxaaa2õ=¶¼wß}—õ=®®®8zô(ë²U«V±Î—Ìår–§‹Æ^/»»»ñÅ_0׸ñ¤’ƒƒƒL°êèèˆÖÖVæA‹ôÁ³²Ã³\]]å†)L&** ÿú¯ÿŠ_þò—2ß™tüöD°¥­íã»ÛK÷###CæÐDæÏŸ/ ×ÖÖÂÃÃCfiPéýÅDjkk±mÛ6•¿GEûÍápàææ†ºº:¸»»ãÒ¥K¨««ƒ¶oß®ôXÍÆÆF8;;+|PøÃ?àÃ?TK€®Ž^ƒfffèë냹¹9óÚø–Sé8ô‰>ÏÐЉDí‰ð´…ÌõVÑ0}·iÓ&œ8qGŽÑØg ÃÈÈD7Ï“ñ½K¤ÓpN[oCMïÌÊ•+Y)úáQtsåääćc½öÚk¬Ý4lllX×_°`ëë8räˆÌ˜1é ŸÏÇÅ‹eZÌÌÌðñÇãäɓعs§ÌÓØÕ«WãܹsˆŒŒ”¹y‰ŽŽÆµk×ÐÜÜ,…††¢°°YYY2Û&}’7•§½ãŸJŸŠ+êV1þ|¤¤¤ ±±2Š ª««eºbÓ¦M8vìbbbd2R¾ÿþûøñDZgÏ™»wïÆåË—ññÇËü®X±eeerOÂCBBXoBCCYƒÇúݰvƒ³²²b]_„°"ÑÑÑ*wmÔu¦¦¦¬kWcŸÇgž{ܚ™™)¼˜ùøø(üN~õ«_)¼“>äCºcǤ¤¤€ÇãÉÜh[ZZbáÂ…077—Ùžœ={999xþü9›ššÂÙÙ555prrBff&³lÙ²eL€^TTÄìGww·LÖÖ'Ož`ÅŠ¬Ó!Þ¿Ÿ¹N¢­-Z„¼¼<˜˜˜ÈƒK–,ÁãÇetU*̯HHH>ÿüs¹kÖD-€ÒlÈ<õÆhÅŠ¸wïÚÚÚ£“©¬¬„ÌkÞÞÞxôèrrrPVV±XŒ¸¸8¹‡hЦ?’Îg>6gÄxýýý {,DEEáöíÛX¼x1ŒŒŒÀçóÑÑÑÄÄD,Y²„õ›´W„ô!ËD="Œall<á¸peUWWcË–- —+Û3cÞ¼yhiiQØóBzßùèÑ#„‡‡O8NZz|2¶¶¶èèèÀ™3gÞçÌUööö*ÍË®ˆ‘‘†††fôˆ²Ÿ7QVúÌÌL¹c‚’ıslƶrIàðáÃr?8zô(‚ƒƒå‚ccc¹ eÙ²eÈÍÍð‡HQ4Õƒ—Mpp0.\¸ ×M0..%%%L ³”‡‡Ž=*×MÆØØ‡f=ѶoßÎú”z¢qd„LÇÖ­[Yo<—-[>ŸÏú°`Ïž=àr¹Øµk—ÌÍûš5k™™‰ï¿ÿ^¦ðªõO(ÊÝœŽnÒÐÐWWWÖ¤ZÒ„h3777ˆD"Ë\ÿ=<<ðòåK™@S•irØ’€M…L’Áñ½Æ¤]·«««å+€§§'ÊË˧”i^JQ .—‹ØØX|ðÁ¸yó¦Ü,*ЦS&ÑÛDÃììì°nÝ:TWW3­¥vvv8xð ÂÖóñß騡qlTk¯*iϨ«W¯NÀ½þíúüôéÓ {MÔ󂨟têŹ`õêÕrCèÈ+êʯÍ=z¤°Ç  ÐgئM›ä¦ 066Æo¼ýû÷Ë­{ýúuTWW«í¦]ú4üÔ©Sxï½÷d–EEEaÅŠrLLL°uëÖ)Ï«Jˆ®100@xx¸L·Hi±oß>|ðÁrçÉÚµkqíÚ5<|øPf‹¢±© UvêBfË;ï¼#Ó­œ [2±É¸ºº²N'–-÷PL‘ñóŸŠËßßååå¸~ýºÂ9¿ÿéŸþI&{½2¢¢¢˜D“Ò¡,lÂÃÃaee###ìÛ·O®[¿¢äg“]akk;á{{{¹äkêÄ6†·µµUUU¬Û.‰ðÇ?þ‘É?2Ñà éinŸ©´ÒK§¬ŠeË–áÓO?e†ô‘‰)šÙAÕuæ"±XÌšëBÓïil±ðªUšm*ù„t-áããÃŒÓ{ßÛÛ+÷c»nÝ:ÖùfÇ’fÔeû¡óõõÅÓ§OYîððpú2™€¡¡!ë °­­-BCCááá!3ìÆÀÀNNN …rÁØÌÇL0C:ÑvéF¨(|aa!-Z4¥2ÙÆs¹\ +Ìâ<•›CŒŽŽÊ iQ†§§'“8W$ÁÆÆFåñ×õõõxøð¡\~™éÛ­ûÎ;JÉÛ644„“'OâÙ³g¸té’ܺ·o߯ÁƒáëëËÌ”1YÏ‹˜˜…V4zÃÌåâøƒÎ?3­­­M¦·ç;#øøxª˜)˜¬§ÊD”=OµÁðð0ëµv¢ž@ ­ðá‡âÍ7ß”yMšèåܹs¬c|`ùòåÌ8·ñOâ׬Yƒþç¦$„¨Ù²eËX[¾6mÚ„k×®¡¦¦F¦KðجÄ>”É~NÈ\¤¨Ë«ªIÃx<蟲 Þ~ûmÖ–›éðóóÃóçÏå•ÉlÙ²…é†=Y²6éoûXÈÉÉÁŽ;Ôþ}H毦âSÔ+`¬½{÷2sÑŸ9sGÅ–-[ÐÔÔ$Ókhxxííí˜7o|||˜Vö/^h,vCCƒ\^ÐÐP¥“®ZµJcSsi;±XŒââb…Ë‹ŠŠ¦üm.àp8Ózð>ÙL DÛu_›L–s…t-gmm­°×T±˜˜˜¨mL;!dr¦¦¦ÀÞ½{µúƒuzòä‰ÜPe~ŸØæ®f›vk²½µµåååð÷÷—[nee¥ÒøxeÁÔÔ§N®]»Tºq_¼x1ÒÒÒ  ' ÐÇgnjjBVVbccÕ’õœtu±X,7쇅…$ ™û”±" >>žI¾Ëáp°fÍœ?ÍÍÍj£ÙÆÆ"‘À«iqÇg×711a¦ÝœnR^}–žžŽ´´´iM¬•š7ÞÍÍuøðj|ºtxŒ"6l™®X988LiŠ>¶ìèÓÕÙÙ)7¤x¦HR'"U‹tB™EQQQr‰¥38™ h×®] çI'D›ßu¢qØß²PXX¨ò´ƒÒdeMMM˜7oÞŒíÿÖ­[§4FyåÊ•puu•KÆ:ÞØyÚàÂ… سgF÷iáÂ…¸wï,--•îºÿþûïƒÏçËŒãwrrbz5´µµÁÌÌLfíŒtÎSBˆö›µzl¾ˆñ™ß‰§è D[888 ­­mZeŒÍÍ0::Šììì) ÿ°°°À³gÏTnÅŸ{{û)=”¨ÊŒ}—Žñ~öì™Z[šáp8øõ¯-7ÜNUÆÆÆˆŽŽÆõë×ölxíµ×ÔÞ…\úÀgü|èã÷Q"‘Ð ¬€´î(©›¼+W®àÀ2Îô径°“^+TzEºž›hª´ñšššT΢K™9ÊŽ+;sæŒÜL„h›©Ìe>Þ¾}ûàUÂ0KKË)Ý8pÛ¶mÓØ ÔlÙ¸q#~øá466N8'º:«¥½½½áïïÎÎN•¦šwwwÔÕÕáåË— ,ÌÌÌ ‹éV 99YfºaUfÌfwcM‹‹ krK]´gÏ\¸paF>K“îLèèèKð­HOOJ,jÍaæÌttt ¡¡®fÆårÑ××7át*„(+11LÂ22s/^Œääd%E"DY]]]ˆGÿ”˶î*ÊΫ¬ @ ÀÐЧ¬*##£)·fk3=zTg·ßÛÛ[&YæLX½z5®\¹‚_ýêW¬Ëƒƒƒ‘••¥·A¤²233Q\\Œœœøùù1¯‹D"&ár¹*'àRufƒ™pæÌ8p@¥÷øúúâùóç2u¼ší@ LÚÓÇÓÓôcó7CCCs&auMM ¶nÝÊü=ÙCAµèÒÖé“o¢9aaaHLLœðimm­tWx2·I§æ‘NsCfΊ+`ccƒÀÀ@ª 2«¬­­ÁçóÑÝݳgÏN+HÿòË/Áçó§\ÆæÍ›é !j<áP‡ððpüÛ¿ý¶lÙ2§ë)** QQQ2ÃTàââ¢wû:•acÁÁÁr/Æ›h##£)OŸ¦¬––DFFÎÉãWšÐrýúõZ¿­èííEss3kž”¹= ¼ BPPЄëìß¿_íY !êGÁ9Ñ'‘‘‘èèè ©<‰NùÇüÇM(¨+´¡{º.%ï»~ý:¶mÛÆºlÅŠŸ%@Õ®Ô“Q%—•‘‘Ñ´‡8M‡¿¿?nß¾õë×£²²rÆ{êLÅùóçñ‹_üBîuƒ®£,,,d²Ÿ²100€££#U!„ãëë‹eË–QEBÁ9»ŒŒ ¬Y³fV·a* {{{'½OžLzzºZó<ØØØèÜÐTUfÑ055Ö)©þþ~˜™™M«Œ‡"""B«ëÖÉÉ MMM¬½¡)@'„B!„Ȩ­­…›››Lfý±S)j³Ë—/+lÉVÖÈȈÚgÐvê ²Uåêê ¡P¸{÷®Æ‡h¬[·Žuè„¢…¸\®RÙÝ !„u»u늊Šä‚\OOOÔÔÔPé)eg–™®ñÜ£££‘žž®—u*‹Y{„„„(|A:!„h!}þ±"„¢Ý6lØ0íèÀÀ@”––ReÎ!Ò™<&“““ƒå˗ω:™Êp Ð !„B!jåììŒÆÆF¤¦¦*ìʫ˪ªª°`ÁÀÎ;qñâEôôôÀÒÒRoö±§§G¥àòµ×^ógÏèàŸ& Ð !DLw^iB!d6´··ÃÞÞ^ïöëÁƒÌÜç<ÍÍÍz7n½­­Nqøðaœ8q‚tB!„BÑV†††³:ض@YY™ÊïS¶kül322ÂÐÐЄëØÛÛ£½½tB!„B™*ƒ)Ù\.‡uʬ¹ÄÖÖ"‘hÒõšššàääÄü­®žžžHMM…¯¯¯Æ÷µ¬¬ r¯ãÉ“'Ó*[­ý%Ïœ9ƒŽŽ444ÐYNˆILLDcc#ªªª¨2™£ººº?+SìBf_ff&Š‹‹‘““??¿i—gff±X_#e«µ}ÿþýàóùpqq¡«!:d÷îÝàóù½B´›µµ5ø|>>úè#ª Bæ ¨¨(ðùüI³k/]ºùùù“–·`Áµ<ø¯®®†——ׄë¬[·iii“–åéé‰êêjÔŸ¿¿?BBB4öýlß¾—/_V¸|*ÙÂÙ8::¢µµuÊï766ÆÀÀPÚ BQéþ@B!š`mm®®®û>>¨¯¯×ùD} BˆRG’B!„LÍøi‡#x ÀÄÄDíŸ;:: .wöC´™~0âíí/^LûáÀáÇeƷ϶{÷î!22’tB!„BˆæM4µX}}=6oÞ¬ð½o¿ý6âããµr¿„B!ÜÜÜ4þ9ÆÆÆÔºýŸÈMY{÷îŹsçT~Ÿ Ž?Ž7ß|sZÛ½mÛ6­ªÇúúz¸ººR€N!„BѼcÇŽáÈ‘#¬ËÖ®] [[Û ƒ2Mt—¡¡¡NÔßø–y]gee…îîn•ßgii‰¡¡!X[[ÏùsŠtB!„BˆRlllÐÙÙ©ÔºëׯŸ4³º&tvvÂÆÆFcå+“1~.suuE}}½Jï Á¦M›`llL:B„¢Ý”É`K!„hkð5U---àñxj+ÏÙÙMMMÓ.§¦¦óçϧƒAµk×âÎ;¬Ëº»»&Ó[¿~½^ì?‡ÃÁèè(è„¢¯êêêàîîNA!dN‘H$ÓžŸ||àÔÚÚª–ùÂõ•¿¿?ž?>­2lmmahhÈšu^Ÿºók è„¢¥,,,ÐÛÛKA!„LÀÜÜ}}}J­„Å‹S¥M\‹D¢i—Œ’’ªP Ð !DÌô\³„BˆªÔÝÊ=ª$&‹ˆˆ€³³³ÎÕót»M«ª¨¨!!!S~ÿÂ… ñôéS:A¦@­é /]º„®®.477SÍ¢Cnܸ––¼|ù’*ƒ9ª§§ÉÉÉèïï§Ê dÊÍÍEYY áçç§·û©Ì”W­­­pttÔªí611™ÑéØêêê°cÇŽi•±`ÁTVVÂÛÛ›N0¨µ=::;vì q„è˜ÈÈHìØ±C'Ÿ(BÔÃÜÜ;vìÀ–-[¨2™ƒBBB°cÇÎùº„‘‘‘Ü뎎ŽhmmEMM <==µj›KKKÕöÝ™™™)=d`²ûˬ¬,:¹f3@·´´„µµ5 ¨f Ñ!°¶¶fý1"„Ì‘.ÖÖÖ ³ëBô›©©)¬­­abb2éºÆÆÆjk͵³³C{{»NÔ‘:::  µ.ykEE|}}ÕRÖúõë•:&chhˆááa:¹f3@'„¢~Ú0¾B¨ªÃ¢E‹P\\̺ldd\®rá ‡ÃÑù áMA6“<<VeeeJwÓ×UÕ™áK—.E~~>à B!„Bˆþ±³³c’ûŽŒŒh4«øt…††¢°°¹¹¹X¶l}y B!„BtÉèè(8ŽJï‘H$*¿GQ9Ú.** ™™™±X 333­ßæÆÆFLS§­Äb1ÌÍÍU~%‰#„B!„h…5kÖ ##MMMØ»w¯ÊAýt[’íììPYY9ãûmmmºº:¥×·°°@oo¯N}·ííí°³³›3Çrww7¬¬¬T~µ B!„B´ÂtÆ¡ÐtcZ¬··–––sb_ÃÂÂàéé9¥÷²èÃÃÃd}Ãèè(0<$''+¼?{ö,¶oߎááaií~¡ªªjVæCEppðŒ®³³3¶mÛ¦Ò{¬­­Áåru"k½¯¯/Ö­[7gÎEGGGxyyM齆‰„™—ŽÃáàÙ³gˆˆˆPx___>Ÿ@À¼–““ƒ¼¼<æï††;v t¥$zÏÜÜ~øá¬|¶ô<åp8¨¬¬Ä’%KPSSúnuu5ø|>NŸ>žžØÚÚ¢°°Pæ&½ªª ?üðé‹%DEK–,ATTÔŒîèè(FGG\.X¼x1뺥¥¥ðóóCxx8V­Z8wîZZZ¼j}kllÄ_ÿúWúR QÁ|0¥ñ¦ÓuêÔ)¦×Ì¡C‡°cǜ̸¸8Ô××+ ÐÙ„††"44”ùÛÇÇÕÕÕr?<<O­õXSS‰D¢ÔÓÅ`éÒ¥JÕµ*Û@몶nOOÊÊʰtéRµ–+‘H™™‰Õ«WOº®P(„X,†¯¯ï¤ëæææ"((H© ª"‘5552çÃD7Plç„¡áìä]-..fº«FDD ""=R©Œ±‰˜†††X°Ïöñ×ÜÜŒööv¥ZŠ àíí kkk8ïÞ½«Ôñ___¾¾>¥Žÿ¼¼<,\¸P©ã¶ë`xx999X¹r¥NÿvÌV·è÷Þ{oÒ`·±±žžž055E?zzz˜±À...àóùÌúÈÍÍö½’*ëççç# €Ù&µ•-‘HpïÞ=¥ ªR¶*¿š®Ãööv…B„„„Ìú¶´¶¶¢©©Ié.Þª”]YY ###xxxÌú~VTTÀÜÜ\é!ŠÊ622’½Ÿ°³³ÃÇ̼ðüùs\½zÝÝÝppp@pp0Áår $$$`Þ¼y ?|ÇŽS¾ÈŒŒŒÈlÏt ¯¯O© ¾²¡¡!DDD¨¥ÂÂÂpëÖ-466âÝwß…`dd¤0AÇÆå^»qã|}}áãã£ÖzÌËËÃèè¨ÌÃ=ELMM§T¯U¶ÖUmÝ––ܹsG鬺ʖ+mýUfÝ¢¢"tvv*u£emmM›6)•1V("//;wîœtÝ›7oÂÛÛ[© i&ŒЖ‘‘¼¼<$$$ &&öööøõ¯_ýêWxíµ×pùòe”••!,,Œµ<###Öïb¶¿òòrÔÖÖbýúõ“®›˜˜ˆ×_...Z^IÇÚ*³nqq1D"‘RÇ¿ óýk{ô÷÷ÃÌÌ ‡һߎ™&‰ðÓO?1­â»víB{{;ñÙgŸ!..?ýôÜÜÜXóWÉ­Ø®ªî·*ëŸ;wk×®Uª1`*߇ÃÑÈ÷+ ‘››«tb:MÖamm-ŠŠŠ”î&¯Ém©¬¬Dyy96mÚ¤ö²ïß¿sss…=Åfr?333akk«ôCeË–{Ü?þ|>|˜ùô¶lÙÂ<ܺu+D"lll@Ñ...xë­·˜›àÕT%Ò!,7nD{{;¬­­Ujé‹ŽŽžö”%l”½°ªJzý¢rÕ_®£££R¬ª¸\.>øàµ—»gϹ§ÒêðÆo¨œ¸h&………17 Òäÿ÷‡……¸\.öìÙ±X [[[½=V·mÛ¦‘ šØV‡£T`ªªÝ»wkäø×D˜˜˜àí·ßV{¹ûöíÓH/7M ê`kk+Ó.½?øì³Ï˜kÂT7Mî÷Î;5r¼€Þÿ}Ý{횬KÇš&ËöòòRº…[UË—/×hom¨sC¶‹äøn%Ò›}é”&6¸»»«­,KKKµžìÖÖÖjM®¥Î}Õöò §Us,###899imÝÍccc¹ssüÉTÎ]UÎ!UêQ•›g¥LÖ-nªÛKå¾ $T¹ÙÕÄöZZZ*ýìʶš˜˜({AS7‘êÂ6vìkl¿óºp¬š››+} ›íãT“Ç¿*¿ ºtmQ¶\kkk¦×.\_õ‰ªû­Jªú EÕû6M \.Wc皪ÛmjjªR!M~Ÿ\.W¥ÙšºÔtÛÚÚªt]V¶lŽD"‘ÌäÉýòåK\¹rGUx“UXXˆÐÐP&•¯¯/bbbP[[‹+W®`íÚµX¸p!Q–D"ÁW_}…;vȨ¸qã8‚ƒƒ±zõj$''ÃÕÕU¦ ]QQ-Z4çëñøñãX·nÂÜMMMH$077G||< päÈÀñãÇáââ¢r–RBÔ!==CCCˆ‰‰‘[öí·ßbhh\.GEYY>|ˆƒ2¿U¥¥¥ðööžµ¼Ú¤ªª ·o߯‡~8éoy^^rrrˆèèhTVVâúõëX¿~=üýýéÀ$3bppÇÇž={äð?{ö ééé^%{ŒˆˆÀùóçáëë‹%K–0¿ÅÅÅsþ>`¬œœ…BÄÆÆ*¼Hï®_¿ŽÊÊJDFFbÑ¢EL‚é}ûöÍJ¦vB”uñâE899É qîïïÇwß}‡;;;ìß¿ŸõœþªbFûèuuu!##GÅ×_ͺÎÇñÿ÷€¬¬,ðù|´µµ¡ºº™™™àóùœ•}õÕWøÅ/~ôôttwwË,+((Àš5k…åË—#99Ë—/Çèè(òóóÉÉÉL2Źìøñãxï½÷ŸŸÏd|«¹¹ùË_PSSƒøøxðù|DEEaçÎxùò%Êˡ~øPVV†/¾øb±xÎ×eKK rssñÞ{ïáøñãÿßÞGEužÿÎÀ ²‰4"  ʉ‡£‰Æš‰¸[µÁÄR¨rµ¢F­Ø¸DS·‚b"¨ qor4FÑBDTöeXf˜á÷‡û“bRcŒ±Íûù‡9sï¼÷r×÷¹ï}ßç‰ódff²k×.©Dqq1wïÞåÊ•+‰à\xá÷¯   RSSÑh4¦}óÍ7Lœ8•JÅСCIJJÂÓÓ“úúz®_¿Ž^¯'99Y¤~LVV:Ž7ÞxƒÃ‡?qCÝ©¢¢‚††‚‚‚ÈÌÌäÊ•+èõz‚‚‚Dp.¼ôÁùСC‘Ëå2–Á£«MMMQ©TL˜0«W¯v:'.]ºÄ§Ÿ~ú£—ûBô¦¦&ÌÌÌÉd<©áþâÅ‹(•Ji` ½^OBBÿøÇ?P«Õ\ºt‰;wräÈqÄ?šL&ÃÔÔ´SÛÉÉIxçСCÜ»wž={âêêJqq1))) >ü©Ghü_¦ÕjQ*•tíÚ•úúúÓÊËËÉÌÌÄËË x”"!!ýû÷xŠŠŠâóÏ?—ÒÁ‹’ŸŸOÿþýéÛ·/EEE¦777Kƒ+UUUaccƒ¹¹9jµš‚‚îÞ½û«ÊßúC iš”J%Z­ö‰Áy×®]¥–F­VKBBÔÕÕI÷òãÇ‹)¼pÆÆÆº+º¸¸••%Õ***°³³£W¯^”””œœŒJ¥zêÌ~ nݺEŸ>}°··b榔”<<<èÙ³'&&&”––’@NNÅÅÅ|óÍ7ìܹ“K—.‰)¼´ÊÊÊpppxbÝÁÄÄ„êêjjkkIHH ¸¸¸Ã9qéÒ%d2Ù3e°z¡º\.ïÔoH¯×S]] @]]/^$==ââbæÏŸÏøñã9r$r¹œ#FDYY™8b„g¢×ë¥>1†T‚¯½ö3gÎD¥RQWW‡R©D£ÑÐÒÒB—.]¨««#%%…ôôô_}ë™ááZ[[›Ô'¼ªªŠöövššš(++ãïÿ;999L›6ñãÇ3iÒ$LMMéÙ³'8::þ¢¹U…_'ÃÃ9Ãy Îé?ýéO¨T*LMM¥ ¼N§C.—S[[KAA§OŸ&77W8ÿÚ>íííÒ+|:ŽššàÑ(Ò™™™¤§§SZZÊ‚ ?~<#FŒ@&“¡R© ê”ÒQ^„Ç[C=ÀÃÃ3f R©¨®®F¡P ÕjimmÅÄÄ„šš’’’HOO®cý7311¡¥¥F#uû1¤o3Ôé>Lzz: …Bº°|çw êÔ*)/CLÐÜÜ,ÕêëëÑh4˜™™ŒJ¥B&“I) çD]]ß~û-éééOløÁúö‹îƒžžžNnn.“&MÂÅÅ…êêj"##ùä“O¤yŽ9ÂôéÓÉÎÎ&33“×^{!C†Okk+NNNL:U5ÂS3ôy0`€”žæý÷ß'**Š{÷š*¥mqss#11 ‹iÜ Çå¯YII ÇŽÃÍÍMjM aãÆR®ÝÂÂBt:NNNÄÅÅaii‰¯¯/ÇçöíÛ(•JfÏžýTioáyÑëõÄÆÆÒÞÞŽ¯¯/ …‚C‡Ñ¥K&OžÌ¨­­Å‚¹sçrâÄ n߾ʹiÓ¤·gΜ9È#ı œ={–ÂÂB&OžL¯^½¸wï»víâ/ùK§kfVV/^dÈ!¸»»“€F£¡OŸ>O‚G~ª‚‚Ξ=ËàÁƒ¥¾¤ï¿ÿ>ÑÑÑRšÒöövFމ““‡¢{÷î̘1CÔ¾ÇÁƒihhÀÇLJ®]»’žžÎ­[·:äe7l³“'OróæM&Nœˆ‰‰I‡z×СCÅÆ^J }:#GŽ”ÖÙ¸²²Î;Gee%¶¶¶ÔÖÖ2uêT222hhh`Á‚ìÝ»±³Aág™™ÉСC¥üÛ?—êêjnß¾ÍàÁƒÅFIˆt¡ƒââb>ÿüs±!á'xðàJ¥SSSRSSqvvfΜ9ÌŸ?ŸAƒ1qâD6nÜ€»»;ÁÁÁŒ5ŠÈÈH©œ²²2–,YÂøñã)..æäÉ“„„„`ooÏÎ;¥ùÌÌÌÈÉÉáÎ;ÔÔÔðÏþ –/_ΨQ£ ¡oß¾ 4ˆÞ½{ÖéFÜÞÞ΂ ˜={6ØÚÚ——‡«««´,ccãŸôv€ üZ¨Õj²³³Ÿ[y.\ ©©é¹”UYYÉwß}÷Üÿç’’¾ûî;Z[[¹zõªôýÕ«WE÷AøòóóÑh4?ûrŠŠŠˆŠŠü%b,6Á/§¬¬Œ¨¨(ÌÍÍ©®®fæÌ™¤¥¥ÑÒÒBhh(VVVÄÇÇ“ŸŸO×®] D©T²mÛ6ihh 11‘ÐÐPŒÿW~üñÇôèу¼¼<^ýufÍšEkk+qqqÓ¯_?üüü¸{÷.qqq¨ÕjÆÇøñã¥2t: ØÙÙ1a±³áGhiiÁÈÈ™L€……£FÀÒÒêêêØ´i»w裂 …BAUUðèµóÅ‹Ã!Cضmyyy„‡‡£ÑhèÑ£G%99™±cÇ2eÊÒÒÒ°±±á­·ÞB¡PðàÁF-­WCCJ¥;;»Në,—ËÙ³g/^$22’™3g••ÅÖ­[Ù½{·4Ÿ\.mAx qqqôéÓ‡>—ò¶lÙ¦M›èÝ»÷s)kΜ9¨Õjt:ñññ¼ûî»( ©ÅnëÖ­\¾|NÇØ±c™?¾t]û>466âêêÊ®]»øè£°³³£¸¸˜œœæÎ+ AÄÅUUUÌš5‹ãÇ£V« ÅÆÆ†ªª*ôz=EEE$%%!“ɨ««cÑ¢E¼òÊ+Ê[»v-...äææâáá··7MMMÄÄÄpçÎ^}õUüüü¸uëñññ¨Õj&L˜ÀرcEÝÿ%$ZÐAõõõ$''3}út cΜ9˜››K'¢J¥bÑ¢EØØØ‹¹¹9}ûöeýúõ|øá‡ 6¬CppæÌ´Z-!!!9r„ììl¢££Ñét,^¼˜¢¢"N:…µµ5þþþ,\¸Ý»wKA{{;›6mâîÝ»RP!ÂÓ333£­­ ½^СBûøgC£Ó§OsàÀ-Z$ýF.—ÁŽ;ÈÏÏÇÕÕ•Ñ£GC||<‘‘‘L›6½{÷âëë˘1cøúë¯INNfêÔ©ÈårLLL(//—n¼†å–aÐÖÖF[[2™Œ~ýúQ__<î¯ý+›7oÆÆÆF*G§Óann.v´ ü€¦¦&222øío @xx8ûöícÓ¦MTTTðÑG±lÙ28€^¯§¹¹™eË–±cÇÂÂÂ(**àúõë,[¶Œ­[·JçfKK »ví",,Œ¨¨(4 wîÜaÆ lܸ‘U«V‘ÍúõëY»v-Ö­²²’›7oâîîNmm-{öì!--½{÷ÒÜÜ,ÍçëëËþýû‰‰‰!..®Óƒ¹uëÖKXXÉÉÉ477£V«‘ËåL:•øøxÆŽˉ'hmm‡ð«×ÐÐ@rr2Ó¦M£wïÞ,]º”Y³fÑ­[7øúë¯iii¡ººš””|||°··gïÞ½Ê;qâÆÆÆ„„„°ÿ~ رc]ºtañâÅäæærîÜ9lll˜7oìØ±ƒÚÚZ©>òÉ'ŸPVV&êþ"@H¿~ýåÊ©îìØ1òòòX²d‰¨û¿Ä+î¿°'µ¬þ–––ÒØØH||<ûöíãÂ… ?~gggªªªÈÉÉaÀ€ž¦µµµqãÆ ^yåòòò˜2e ®®®xzz2qâDÚÛÛÑh4Ž»»;£F’ZóÆ‡ƒƒŸ}öÁÁÁnÈ‚ ü0¦L™Â©S§ðöö櫯¾’¦>[ZZ’˜˜@DDD§2>þøcéó¾}ûøðÃðZ²}ûöß3†1cÆtønÛ¶m~kkk+½Âþ¸³gÏvú.55oooq]„ÿÀÐÕE.ÔÒ¥K&Mš„‘‘yyy,_¾œnݺ‘Myy9ÎÎθ¸¸0pà@ºuëF\\Z­–ššFŒ^¯ÇÝÝ€o¿ý–¹sçâàà ]kúõëÇ AƒpuueРA<|øGGGHIII‡u«««ÃÂÂGGG©%ß××·Ó6eee¬X±‚ÈÈH EÇJä¿,--yóÍ7¹víZ‡éÖÖÖTVVHÝ~D÷Aøþàiæ:µ¤·µµQPPÀ!CÈËËcøðáôéÓ‡3fHu|FÃüùóY·n®®®¼õÖ[Òï'L˜@=øì³Ï ÁÈÈHì _hAÿ%ŸŽcii €B¡n–J¥333œœœ055eÞ¼y\¾|+++îß¿OBB6l`Íš5lÙ²¥Óëb&&&=z”9sæ`ll̨Q£ %55???üüüÈÏÏÇËË‹ 6°råJºu놑‘ÆÆÆØØØ°zõjšššøâ‹/ÄŽ„g`¸)þ¯™8q"o¿ý¶ØÁ‚𘛛ÓÖÖ&u/1êð¨åùwÞ‘ú¨···K™gdd„B¡ ²²’úúz)Ðvrr"//öövòòòprrêôûªð²3ê …???äry‡‡o%%%„††²råJ Щ­VKAAz½ž7nàääÔaúƒppp½^/ºÇ¿ÎíÇc€Ç?Î+++äry§é†xáßëþ‰‰‰üáÀÆÆ†7Þxƒ+Vðå—_Juÿ¢¢"|||X³f «W¯ÆÚÚZ*ßÆÆ†5kÖ V«‰ŽŽ;è—~x#Ò¬ýï™2e ÑÑÑAáÅÐh4¼÷Þ{lß¾îÝ»óöÛo“––†\.'??Ÿ¥K—âàà@mm- .dذaøpì?]\IDATùùqèÐ!ÊÊÊX½z5_|ñ‡&66GGG ‰ŽŽF©TNSS]»v%""‚{÷îÍ–-[ÈÈÈàüùó¬ZµŠ£GRZZÊÿøGiÝðóó#))©Ãƒƒ·`Á pqq`Ïž=^=z4Æ £´´WWWÖ¯_OJJ UUU,X°€ÐÚÚʼyóxøð!aaaDGG‹7pá9=z4©©©O Þ  /]»vñî»ïJOÛAAxñÑétÌž=û¥[·Í›73|øpÞ|óÍg.c̘1=zô‰AV«% €íÛ·caaATTöööLžrö9g¯söÞgÝ=¬½–†B¡P UMQ@(,@ x] +11±Èô¬¬,ž?.JNPbŠkK …‚ððpòòòD! ÔWX,Y²¤È¶oßÎï¿ÿÎÅ‹•ž\./ò_ES [P9Ë-,,Œ‰'yîÈ‘#xzzrðàA¥ô7Õ–JBQÊU¡P ¦‚_ÚE%4ˆãÇyCxx83fÌ ((ˆ·Þz €ÐÐPvíÚ¥tÝãÇyöì×®]«ÐøóÏ?Y¾|97oÞµY ™1c=ªP9VVVØÚÚyîâÅ‹8;;cooÏäÉ“¥üwß}§t]ff&¿üò ™™™èêê¾Ñrûæ›opvvVJ»|ù2|ðÁ¢a½ …U˜ÔÔTþüóÏb%Úµk‡£££Rš——«W¯®ðˆŽŽÆÔÔTÔdáØ±c¼ýöÛy^WWW¥-ÅÇÇóË/¿¨\ûÃ?°lÙ2´´´DÁÖô!aDD‘‘‘$''³cÇéÜðáÃ9xð cÇŽ­/B‡DM–’øøxfÍšÅáÇ+|HÁ… ؽ{7/_¾`öìÙØÛÛóù矫•wjjj… ÅHJJ*SQQQ:t¨Ò·…‡òìÙ3é½¹téÏŸ?'007n”IÆÝ»w‰ŽŽVJKOO'00ÀÀ@òòòˆ/RváÑ“fqCƒÒ¤Iš4i©S§¤svvv¬ZµŠ† Н¾ ÄØ±c%åQ‘CƒÒ¯_?<==iÓ¦ -Z´ÀÙÙ™¶mÛVºò¹téÁÁÁeÊ#;;›ØØØJݶmÛÆøñãùí·ßðöö&00õëד””„››<ÀÑÑ‘´´4µd8991zôh¼½½•Ò¯^½ÊáÇùå—_xþü¹ŠìíÛ·óàÁ$Ù¬APíÉd¢JȬY³èÙ³§t¼víZúö틾¾>®®®¬]»–!C†‰Z2-ZD»víTÒ×®]K×®]iÓ¦ ?þø#k×®¥_¿~èéé±mÛ6Ö®]ËСC‰ˆˆæÔ«…ÂêСwïÞ­O€B¡`éÒ¥¢ ª)ÕBauíÚ•ëׯ‹Úª9ÚUùá=ÊøñãE- ª6l`áÂ…•âYnݺŋ/ÐÐÐ 44”… róæMrrr˜6mÉÉÉ\ºt‰&Mšðî»ïª%ãêÕ«$$$JXX7oÞÄßߟ… röìY¢¢¢Xµj:uâÆäææòé§Ÿ’˜˜ÈÅ‹iÚ´)C‡­ú +..kkk²³³ÅW P ???Z·nM³fÍ^›Ì¨¨¨Jóþ™™™|õÕWäää0vìX®\¹‚ ¦¦¦Ìš5‹;wî0{öìbMQ^EFF+V¬ 77—nݺannNûöíÉÍÍògƧ"ûîÝ»J²µE“­yÈåra»ôDDD`ffVcß¿wïÞ*i£F’þnÞ¼9Í›7/“Œª¤YZZªÈ255U:¶²²ÂÊÊJé>±JXùßÿþǤI“DAªåÚÃÊÈÈ`åÊ•µdxyyáèèÈçŸÎÔ©S¥ô{÷î±lÙ2RRR8qâçÎcÏž=$&&J²¯]»Fzz:{÷î-ÿ–¾¾>ÎÎÎ8;;óÙgŸ‰ÖPÉÑÒÒªÔž–,Y‚³³s¹)™ŒŒŒJ]¿þúk¹)ç’rúôi˜0aà§Ÿ~bæÌ™˜šš²k×.~üñG–-[F\\¾¾¾jÉhß¾=*sÍŒ7޾}ûâää$É611ÁÝÝ]ÚzËÉ“'«Ï°víÚdee $¨ÒÄÄļö‰'bccƒ––&&&¼xñÈ7¾•Ž322ÔÞªÔºukêÕ«§’^7äoÃ)‰ìj¡°ÚµkGhh¨hñ µ«2»{ÉÎÎÆËË«R>>tèГ'OJöNuêÔ¡_¿~Ò±……E¹9¸qãûöí“ò:t¨’ì¾}û*ɶ±±„Yƒ@P$—/_fÀ€5â]yöìVVV̘1ƒ]»vQ¿~}úõëGNN›7o¦sçÎj+,''',--¹}û6'OžD__Ÿ—/_2yòdÈËËcĈ´hÑ‚]»vahhH¿~ýX°`?ÿü3]»v•dWi…•žžNݺuÅ×%(w>^FÑ¡C–,YB»víøïÿˈ#رc‰‰‰|öÙgäååñÓO?ѨQ#µø999…——–––¼|ùoooV­ZŲeËHMMåøñãôìÙ777’’’˜6m2™ŒŸ~ú SSSI¶0j0S¦LaÊ”)Ji…ÓŒ3˜1cF™d,Z´HÅëã?PêÔ¼ûî»J²gΜÉÌ™3+vH(…PXA '77///är9111xyyIî\ÂÂÂðòòâüùóe’qùòeÂÃÕÒRRRðòò*•l¡°‚Ž££#cÆŒ!;;›cÇŽñôéSÜÝ݉‰‰aÛ¶mddd°uëVÕÊßÉɉ?üP) 3äóý믿8tèOŸ>åèÑ£J²]]]Ud …%Ô`"##•L26nÜH§NÐÑÑÁÝÝ7Ò«W/"##¥žOi).êÆi׮͚5cÆ lܸ‘Î;£­­‡‡7n¤wïÞDDDHÊN(¬޶¶6µjÕªôÞ8ƒŸŸƒ®2Ï[eÖåË—éÕ«—hqå °ttt^»k^AåàÀ’Âúæ›o*{­ª}âĉ*QÀAeÆÃÃèèhºtéÂÒ¥KéÕ«.\ ##ƒ/¿ü’œœN:E“&M”Bp•†€€bbb¸qã÷ïßçöíÛøúú²bÅ Ž9‹/¤áß… ÈÌÌä‹/¾ ++‹“'OÒ´iSFŽYþ K&“qãÆ =zôÚ{ r¹œ¼¼<45ÅH·:pçβ²²HNN…QA˜™™Ñ°aC±°°`äÈ‘„„„0tèP ˜1cOž<¡W¯^Ô©SG-†††lÚ´ È÷&:pà@:tè@óæÍ¥oÕÜÜœQ£FÂ!C000`æÌ™*²ËUaÉåri?Rttôk-xCCC222ÈÉÉ©ÛN¯&""‚””ÒÒÒDaTð}C½ H(’Â[hÔ¡k×®E*J@IVId—«Âª]»6“'Oò÷ÿœ9sF´Ú >ÈßšóO‹gAÍDŒ‚ÌÝ»wÑÒÒBKK‹¯¾ú &NœÈ;ï¼äÇJœ1cï¿ÿ¾Ú2öíÛG‡رc‡Êذa¼õÖ[dffâííͤI“$Ù¿üò 3gÎT’-V ÃÕÕ•/¾øB„@bâĉ¬_¿žï¿ÿž5kÖðå—_Ò¬Y3¶nÝÊêÕ«Y±bIIIx{{«•¿&&&*¡×Ö¬YäI“°³³cÍš5’lKKK\\\”dûøø”ÿPPùIII)2¨¥ f¢¯¯ÏßÿÍùóçÉÉÉ‘–ÊårRRR¤ãœœÒÓÓÕ’affVä¼ráÀ¬‰‰‰ÅÊÎÎΖd׈–ºkk:¢Üª?õêÕÃÏÏ__ßJ豮 ½½½þøcþ÷¿ÿñìÙ3 £GF¡PP·n]ììì¤cKKKºt颖ŒÂCA…BÁ¥K—ؾ}»”7À˜1c3f …‚zõêagg'7kÖL’]íÖùóçùè£HMM­³zöìÉ•+W”ÒV¯^ͪU«8wî\µÿ³gÏÖØºß½{7÷îÝ# '''¦M›Æ‰'055¥GÌ›7­[·Ò³gOÚ¶m«–Œ 6`mmMhh(§OŸFCCMMMÞÿ}BBBÈÊÊÂÎÎŽiÓ¦qüøqLMMéÞ½;óæÍã×_¥W¯^´iÓ¨æsX±±±Ó¾}{>|ˆ¥¥¥ÐN¥ W¯^|ÿý÷Lœ8±Ú÷¿þúëYÇfff899IÇÖÖÖJÇýúõ£_¿~e’aoo_dÛJ-»Zõ°š7o®äs§Àê}ذaüùçŸB•ŒŒ  …Ú–ÍAEQ­ÖçŸÎöíÛE­–¹\€––:uâÖ­[Uþ’““¥÷(‡««+‡âÚµkÌž=›9sæðçŸ2oÞûŒœœIöܹsüýÂÿ”]® +##{{{ìííÙµkׯ)(†••aaa¢u–’7ÈÁÁ{{{V®\Yæ¼\\\D0‹"ˆŒŒdĈäææ2nÜ8\\\˜0a999øùùáääÄüùó áúõëjÉ8{ö,žžž*ßßîÝ»yë­·077çðáÃlݺ•>ø€¬¬,Iö‚  ‘ö(—«ÂÒ××ÇÙÙggg>ûì³7^ׯ_—ö1™™™½öýU•   úöíûÆŸcÉ’%8;;‹ÈÔÈôéÓiÖ¬™™™( .\¸ u>®]»&ÇÄÄððáCµd|ôÑG4kÖL%½ oÈ_+,;88X:ŽŽŽ–d×hK÷ððpzöì)æ·þÁéÓ§2dˆ(ˆBß¾}‰ŽŽ®Ñ««¤ÂJKKCSS}}ýb¯IMM}¥E÷Å‹™3g—.]ªñ¶N:j[2 ÊŽL&S Òðº¨_¿>uêÔ!---Zù¡---¥ãzõêabbR.ò^¼xÁ;w¤¼Z¶lY¬ìúõëK²«¤Yƒ\.—l9Š#44ô•v#=bΜ9lÞ¼™ääd jìÓ²eKžøàñ¥W¶nÝŠ‡‡ß}÷»wïæÐ¡CdeeáååExx8...4hЀ½{÷ª½ÞÉɉ™3gªìÙ?üð§NbøðáLŸ>WWWZµj…††û÷ïÇÕÕkkk"""Ôvy^\ UWWW,--155ÅÅÅE’ ùáÇ d?{öL’]¡ ëþýûLŸ>½ØòÀEN|\êl¥8p JÊèŸäåå§´LÛ¶m[êiÓ¦±xñbBCCUÞqÇŽ|ýõ×ìÛ·¯È÷vwwgóæÍÅ>ÿÈËË+öÝd2Y‘ç ¹¹¹Ô®][å\“&MˆŒŒäÙ³g*›Ä555%y±±±å¶¼-xóX[[“’’Bdd$;w®ÙsX]ºt)ÖCÂÒ¥KÙ¹sg±NÃV®\©–A§ R³ÂXXXUä}ÚÚÚÔ®]›ŒŒ ¢¢¢°°°Îµk׎ÐÐPéøêÕ«ôèÑccc•-…‡MŠ °BŠ‹‹ÃÔÔ”6mÚ(å ùÛîÞ½K§NŠtíröìYöìÙÃãÇ‹|uëÖqøðár­GBBBj¼ùGuäôéÓôèÑ£J¬ü–ËÞ¿_e¾¦`ÎgîܹlÞ¼YÚÐX€††‹-âîÝ»E†ºuëVVVj=O2ù'M›6åÁƒL˜0A¥w£¥¥…®®.éééœ:uJe;HÁä{·nÝÐÑÑQ2ZµµµåöíÛØÚÚªôP¬­­ ¡iÓ¦\»vîÝ»о}{ššš>| ó‡’òÇÅ_ýE÷îݹ{÷.ÞÞÞ¬Y³777bccqwwçí·ßÆ××—ÔÔTæÍ›'ýø7mÚ”qãÆ•ŸÂjß¾=ÎÎÎJi^^^¬^½šúõ듚šŠB¡@CCCú¨LMMy÷Ýw±··gèСJ÷úøø°hÑ"Éñ|iÙ¶m[±C¯¾úŠ .iWÕ¼ys† ¦M›ÐÑÑQ:gffFhh(Ož<¡E‹Ò»@~8ª;wbkk«´`èСØÛÛK ”ʪ[·n8880fÌéúÛ·oóÉ'ŸH®qÒÒÒ¨[·.¹¹¹hjj¢§§‡¾¾> 4hÐ@¥§¨®W‚þýûëûhܸqìØ±CjH¯ƒó‰øøx\\\„v©ôôôppp|®6ŒöíÛ£­­®®.Ó§OçùóçŒ?žZµj©=ìÜ»w/¦¦¦4oÞœþýûcff&µ'###† †µµµ${ÆŒ*²+¼hddDJJ r¹\êræææJ AOOÌÌL%’””¤4$+-õë×/öœ­­­Š5w“'OÆÄĤÈ^D·nÝØ·oGUržžÎ;w¸qãóçÏW:ß®];iiièèè ««Kçιuë–d ð×_ѧOBCCÕš/PŒEQ¯^=,X ¾ðj†®®®dÞSPÏ;v”ŽË¼ÈÒºuë"õ $«~ýú¯”ýFÌ o®íСwîÜ©48hРbÞ† ŠœªU«£GfàÀX[[«¬Â5jÔˆ—/_²wï^•ùŸwÞyGZ¹xñ¢’%þ¨Q£”B+egg9a^x8hjjʧŸ~Ї‡‡ø¯$//””RRRP(Èd2RRR$—â999¤¤¤”yŸiFF¹¹¹e–ýZÖ?ƒܽ{—:{ý‹/hܸ1Ý»wçÚµkU¢â{ôèABB“&MR97vìX¶lÙ‚¦¦&_~ù¥Êpúþýû@¾9Dá_£.]ºH~€Ö¯_Ï7ß|#¾2A¹±qãF¦NʨQ£ðôôÄ××—¹sçJóUÛ·oç»ï¾ãÓO?U[†««+;wVù á“O>aÔ¨QdeeIÎ doÛ¶U«V)É~- «°­RI–Å£££133£[·nUFa½ www•½Š ìXðÎ;*ŠÜÐаȈ?ï½÷¾¾¾*åVx @ð*N:…™™ àÔ©S,_¾œO>ù„ƳqãF–/_μyóxùòe± 2¯bÊ”)4oÞ\%}ùòåŒ3†þýû³|ùrI¶™™›6m’dÇÆÆrôèÑ73$|úô©ÒêßðáÃk„?ª:uê¨LäÌUÍŸ?{{{¾üòK•Åsss^¼xAjjªÒ“¶¶¶Š½ÕãÇ‹œ/ŠcñâÅìØ±WWW/^Lvv6o³—-Ëår•!]iÚ~Q&yC¾‘yId¿6à bbbTìxêׯÿƬá+ *«¬ÿ$<<¼È_) ,xzz2þ|¢££ñôô¬ôÏûÚ–¡¡!/_¾äĉüüóÏÅ^Wx_qdeeúº:2`Àüýý”\o@þdNNŽÊr³¡¡!IIIJ¦$AQDDD0dÈ444ˆˆˆ`Ò¤I¤¦¦¢««Ëˆ#¸wïÉÉÉXZZJ¡¹JKJJ 2™ŒŒŒ 233¹zõ*ÁÁÁLš4‰ôôt²²²˜œ»wïJ²{öìùz‡„³fÍbäÈ‘*vCÿäöíÛJK›EáèèÈâÅ‹kDƒjݺµ´µçŸÃ½‰'J»ê £¯¯/Œ-%bûöí$&&b``€ƒƒS¦LáöíÛ´oßžŽ;2gÎ|||°³³SÛûÀ 0€ÔÔT®^½J½zõ033cÔ¨Q$&&bhhHŸ>}˜2e ·nÝÂÆÆ†Ž;2wî\)r{ì×j‹ÿþý"—åG…——£G-¨>ÿüóW^ãêêÊ_|! KP꩚o¿ýVé²ðq=ŠÝ9R–ö[z¾°¬6mÚ¼Rv¹*¬ŒŒ )$SQþ“ŠóÚYëìšÀ¿mä. :z[s*º¢<3+óÿkNiÉd¤§§chh(j¦´jÕªJL”ª‹ØšSñ±cDz³³ùᇈ‰‰ÁÃù\ÎŽ;ðôôÄßß===Õ’Ê–-[6l#FŒÒÃÂÂX½z5ÙÙÙ¸»»sýúu<<<ÈËËÃÍÍcÇŽ $»R8ðkÓ¦ >”\£L"›™™©í4¬&P¯^=ÒÒÒ€|©…·ý%aõêÕ 0€–-[²~ýz¶lÙÂäÉ“ÑÐÐÀÇÇGGG.\È£G¸|ù²Z2>|Èùóçyþü¹RúöíÛ8p -Z´`ïÞ½lÞ¼™?üÈwéè舽½=>”dW …U\taaòPr o’Ô%88È_‰¿{÷®t§väôQ£F¹7¸ oÈ÷bRpœ™™©"ûï¿ÿ®< «€•+WŠ(¿¥dÑ¢E899•èÚ+Vðã?ŠBH¸¹¹qåÊÖ­[GŸ>}*ýóV…5eÊ®\¹"ÂG•}}}>\¢=†"<—àŸ’Àœ9søøã±±± víÚ´nÝZ:622*“•„‡‡séÒ%)oÈw‚PÙ•¦õ¶k×Nò™#(9ìß¿_ì!¨ÅŽ;èÑ£|ð,X°²³³yÿý÷‘Éd899I>¬ÔÁÉÉ ™LÆ™3g°´´$33“€€æÎ˪U«ÈÌÌäÛo¿¥cÇŽìÞ½›œœÆOnn.ëׯÇÊÊJòÓVi–®®n¹i𚆺}ÁÂ… •Žû÷ﯤ˜&MšT¤’ÒN[ü3êØ±c”<ÿ0€ü«lMQeÕ“#FpüøqQ‚j…PXՔŽ‚ÃÏÏ«W¯ù¶Q[¶l‘b4ܾ}›-[¶H[À.\¸À–-[JíaÅËËK dR@||<[¶laË–-Èd2Ù·nÝR’-–@PÃÙ¶móçÏçäÉ“ìß¿Ÿ† ráÂ>|ȯ¿þJçÎEϺ7IDATñôôäÑ£G¬_¿ž‘#G²sçNJ$ÃÉɉùóçó×_)¥Ÿ|Hpp0û÷ï§Q£FJ²»té‚§§§yª\–L&ãÊ•+\¹r…‡–Kžÿ “%¨9ܾ}›+W®pöMžž®Ö­*3kÖ,ÉÀîÝ»133C.—sôèQ<<>ž¥K—R§NvíÚ……… .$**ŠM›61lØ0z÷î]"{÷îåï¿ÿÆÏÏ:pïÞ=Ž9‚““ëÖ­#..OOOüüü8|ø0 ,Y²===víÚE“&M¤ŽP•SX¡¬5›””DA”‘þýûK>§êÖ­+ż,pi4mÚ4%‡+W®$55U)òù«›•ƒ}ûö1kÖ¬*õÌC5¹\^%Ë\OOOô˱JXÍÑÓÓ#33³Z†G355-77FAãÆ‰ŽŽP(,AI±µµåÖ­[ÕòÝ.\Ȇ D% …%þɃh×®(¡°^µµ5÷îÝ5&xc„††Ò¶m[QBa•àA55‰¥aÆ¢Ö¡°*?ׯ_§K—.¢Ö¡°Õ‘ZµjqïÞ=ZµjU#Þ7##}}ý2çckkËíÛ·E Kð:;v,nnn˜˜˜Ôˆ÷ýî»ïX½zu™óiÒ¤ ‘‘‘åþ|qqqÕμäuR¤áèÍ›7qww/Ò™˜‡‡¡¡¡L:•öíÛ¿¶2e ãÆã½÷ÞµV…ˆŽŽÆÅÅ…:uê°xñb¥sçÎÃËË‹aÆ1xðàWæåææ†ŽŽÉò£3¹ººJ×ܾ}sss~ûí7ɈàòåËôïߟÇsùòe)=;;›ØØX¥< “½\.WJ¿uë­[·ÆÏÏääd)ýéÓ§¤¥¥©ä†¥¥¥RzLL ÆÆÆøûû+¥˜Þ»wO%ŸšÄèÑ£177/ö¼†B¡P<þœëׯ`ccƒ¡¡!ßÿ=›6mR¹ÁÞÞž3fÄŒ3¸ÿ>;vìPºîÉ“'øúúbiiY®¿NbÒ½ôDDD`ddTnq Tâ*((ˆ˜˜‚‚‚pvvViKÎÎÎÒÿYYY¬X±BéºÌÌL\\\Tònذ!ñññ( •ô¸¸8•ë5jÄË—/•ÒêׯOVV999JéuêÔA¡P¨Xª•GqèèèP§N•¸ŠÅåallLbb"yyy5¶­ž9s†·ß~ûß{XÚÚÚÒVŒŒŒÐÒÒ’~Ÿ††Ç/ñõݺuÃÔÔ´BÞ¿Aƒåþ~ê>K«V­JìmÕÜܼTí»¬ßS™Vu§°2V‡þýû—éƒ*KgÀ€Uºì*Û3ÚÚÚVXÞ†††tëÖ­R¼gi¼ªššš–J‰¿Î6Q%ÍtttÄ 5•¥M•{îZµjѦM›j_?íÛ·—掫3%~Ù†ÿ\b‚JJ¥ïaÅÇÇcoo_¤ß£S§Nñ믿’““Ctt4ööö"*Êÿ‘ššŠ½½=*çΞ=˦M›ˆŠŠÂÞÞ{{{¶oß^iž=--eË–I~ü sñâEÉÌÌ•üÉÊÊÂÉɉï¿ÿžôôtÒÓÓY¹r%÷îÝC.—³gÏ:D^^ÁÁÁüøã*&"2™ wwwŽ;FIûM•^a­]»gggUΓ••U=VIˆÅßß{{{Μ9óÚäþöÛolذA꣥¥ELL ;wîäÂ… ( =zÄæÍ›‹ì1¼id2çÏŸÿWc=AùáààÀŠ+ðõõåüùóìÝ»—ððp²³³Ù¼y3=z”Í›7síÚ5Ο?ÀùóçIOOgóæÍòèÑ#nܸ»»»Ôþ6oÞLll¬tÏÕ«W+¤7Z0‡|äÈ)Žƒ’ïëÈ‘#´k׎óçÏ+³Õ«W'OžÐºukìììèÓ§aaa¯íÙLË–-¥eôäädâããyöìñã?²fÍd2žžž¯íÙ:vìÈÑ£Giݺ5ÁÁÁôíÛW:ghhȽ{÷hܸ12™ŒœœœJåƒßÚÚš'N`eeÅýû÷•Œ 6lÈõë×%»®ªÄ£G8{ö,7oÞä½÷ÞcùòåX[[séÒ%~øád2AAA8p ú÷ŸÔn<==¥ëΞ=ËÙ³gÙ³g666ìØ±ƒC‡1fÌ¥{üüüHOO/÷w‰ŒŒdÁ‚4jÔˆ'OžÐ¶m[ÉÞ®nݺ$''#“ɨU«fff\¼x+++6mÚÄÒ¥K000 ..--­/6hý÷¿ÿýoe®äÎ;“œœÌÈ‘#122¢G4nÜÈ_Uiܸ1}ûö¥Q£Fhjj2räH444^˳իWÌÌÌ077ÇÇÇjÕªELL ¼|ùmmmŒŒŒ=zôkÛøÚ¹sg’’’1b†††ôìÙSÚ£emm±±1]ºtASS“6mÚTªà´666¤§§3lØ0êׯOïÞ½¥!« õêÕ£gÏžUNaÊôéÓ|›´O?ý”:píÚ5455éÞ½;ÆÆÆÒœmtt4r¹œäädÎ;‡••ÚÚÚôîÝ›¼¼<úôéCãÆ¹yó&™™™4iÒ„øøxˆŸŸµjÕ¢wïÞå¾ú˜““C«V­hР&&&tïÞììlÞ}÷]4h€¹¹9]»vÅÄÄtuuéÛ·/têÔ‰ ```€‰‰ ½zõÂÈȨDrÅ*aIJJâܹsŒ3†Ã‡Ó¸qcÚ·oO\\ …‚ÌÌLŒ¹xñ"}úô¡I“&¢Ðj07oÞ”zŒ…ÿÎÍÍ娱c´lÙ’nݺqöìY?~L\\&L &&†:uêжm[¼½½iÓ¦ ÆÆÆèë룧§GTTyyyܺu‹!C†€¯¯o™¶QUF„Â*)™™™Ü¹sG­Þä¹sç8p`µ+“ÿz`*¥Ú|IEND®B`‚snd-16.1/pix/fmeq51.png0000644000076400007640000000077311147553267012761 0ustar bilbil‰PNG  IHDRx UUZ’3PLTEÿÿÿÀÀÀ€€€ÐÐÐ ```PPP   ààà@@@pppððð°°°000^Q(I pHYs  šœtIME×  ý©ëí[IDAT8Ë•”Ñ’Ã EEƒZšÿÿÚLܶScêƒCÌñÊpQç>Mâ w…¬dÁ{?Ö4*^Hägº»DnȆmЭèÌI؄¶‰ªrX(ѹ!‹ñJêœ&Øt5•¯šÊ|ž"wdSl/ÎSêQ¶ EAÛØ<ËÌœeà`Ê.ŸNäËXʺÇÈ99²`4@s¥'¹‡I0™µÊ©[¾Èé Œ!¶’}õ¢ÁU³´ aKŠË’6m­ŠµÆƒëÒâï²êq„yû zwÚ¼;n[6ñúà…ì#¸š°wº?òé…KÖyÓ)€,„*ßT ­'ý‡R[-×²Ñ ©ý.FZ9¡í¢{?xkL(¶©rÉlœìÑët c-KP:Ô3ú,[=®z9g²°s^‘÷æžì‹1ðþúÌ®Ê?7E~”ÍojžJÜr)ûûÎ !µøpûIEND®B`‚snd-16.1/pix/hairy4.png0000644000076400007640000033624411147553267013070 0ustar bilbil‰PNG  IHDR„I½™!sRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ*9ªYYm IDATxÚì½yxÕ™ïÿ©ê}oí[k—,Ùò¾É+ÞÀØ€1 1˜Ì$Ã!a˜™û»ü&ss£2$! Ã$ã ˜ƒmŒ7À6^åE–-Y‹µ¶ö–zïªûGËm7’À€—óy=vU:UýžSUç{–÷•šOW@ Á‡ôíÛ– A(@ W Ú)å³…@ œEQøðÃINNÆ>‘H„þ~³g_%Œ!¸x¡0@ ‚³¡ª*óæÍão¾÷]a Á%^—Ï~\:™îùHÒyä%Á@¿‡ýè!ax„@ .ý–t0àGQàšÌƒY–…½gÃWgÀ`4Añ©´·5a2™q8“QeØ<ººÚ0è è &t:ði%B‡»%&0!@ \ø|~v8FD•% Ñ¡%ÂèÙ$'% C‘H„ŽŽNv‡§Ã1$ÍÖm‘•™I~~ž0Ø@–5DBa†S„Š! ¢šÌ(ŠÂÁÊCÒ$$$#˽Y£¡±þzƒäät?õÇ«É/,%¡Õê„Ñ—® ܳg@@XH —ÅÅÅ$%% C|å j™QŹX,V$IB–%$IF–$¼^/Á€Wé<Åàö;éïï'%9™®înÆCWW7==ÝØíRR’ñôy$EÛcÝÝ=tvub³ÚHMM¡¹¥ EQÈÌÌ#³ç…JD‰ +UU‰ÎUU%‚,IÑÑÄÓ…‚èõú“'àHH¤¾öªªbµÚ©­9LJJF4/àR„©©©üøá à¢gÓÆ÷yoý!¿$Ðë´ô:dIB’edYF’$"áAÑ—|^x<š›[¸zÁ<œN'ªªâv»Ù´y ………ì¯<Ȕɓb黺ºØðÁFŠŠŠ8pàãÆŽ¡öøq¼”–Ž@U…ÓøóE‰œIª¨ƒûUUÅáL"1)5.»½9fkU½Î@Nn1õuÕ4‡Ã¤e¸p&$£ªŠ(Á¥/ F£Ž¾^uõ ”——Ç*¶$IqÏë–A´±¥(˜ÌV$iøÑ ŸoU £ÕÐŒģ§Û^oÀlµŸÑÃÇÓƒN«Åh4í¢Pжäè¿ñÂ<çÃI­pz›ªÝÝÝngÂøqôööâîèˆëèìÂh41~ÜX¼^ÚÛÝdg»Q\, úyÞQjø aNoß*¨ª‚¢„‡ŠÆØ¹*Š椌TU PÔȹ=Η‚ à÷ÑØPKbb ‹Æ†šÁÑÅĸtÁ%-|>½½½¤§§ÓßßOkk+999D"bŽ´àü A´Z &“ ¯×‹,Ë„ÃaL&Z­–P(D  ­µ>OÅÅEx<ŒF:]´Êz½^6nÜ„ŠJ(bÖ¬™¤$'³ió:;;˜V^·¿öøqŽVãºëQWWσ‡¸qÉõøý~B¡Z­vPøhÑ (ŠÂÀÀEQ‘$0›Í±uµFctT£®®žc55,˜?Ÿuë6`·Û™6m*kÖ¬eæŒé$%%âóùe³Ù<(Z£6ÐëuFEÁëõÒÛÛÇ‘#G˜4qO?:–H$‚ÙlF–e|ƒ÷j2™Ði£Ç|>ª ‹™ššZlV+‹9vž×ëEUUÌæè¾@ €$I ´ƒyx½>TTLF#:“É„$ÉìݻΎN ò©:RMZZ*é¢ Î ep ΰZBQb#~ýý½ôövÅŸ«DHHJ>­‡]e`ÀCýñ#¸r ðÐØPCvN‘˜’õ K2==ôõõ v K±%‚ÃnF:4 Ó§—ÓÞÞŽÏ Áé !!ùóæÒÛÛGn^.ÉII€ŠÕjÅáppõ‚ùtuwãÊv‘’œ<8›KŒŽ>$?ýý}CŽ$$¥DG:$ ðzû GŸ9ûôQ]‰®®œ I8œÑÎØ¬ì|Zšê±;„©—— 4 ddd`³Ùèïï§«« “ÉDOw7‡UXRp°~ÃȲŒÝfgÒ¤ lÚ´I–ƒ¸\.ÆÇ'Ÿl§`%¢`¶˜X¿þ¦L™ŒË•mÈ2Zƒ^OŸÇƒnЋ׼¹W±ö½uÃ^?‰ÐÙÙIÿ`gF„ýû+ðzéëó0uÊdÚÝnºººp:ì¼ýÎÒÓÒp&89q¢‰k^ÃÇo'=#‘¥%$&&à­ôÑÙÙ‰N¯§«»›ÞÞ>EÁb1óñ'Ûc#ë%%%d¤§³iÓf Á`iÓ¦ÒÙÙÅ¡ÃUØmVE%óÖÛï‘‘ŽÇãaì˜1Øí6vìÜ…V«A«Õ2{ÖLöì݇ÛíÆh42eòäÁÆõ7n¢°¨UU¨©©$\®,Ì&»ví&-=ñãÆât:éèèäà¡CAô=W͞Ş={±˜Íœ8Ñ„$A}}^¯—žž^ÑÛ)8oTE%ò™†Tì˜zrz•Š—Œ‰;Þ×Û…¢¨q³D]Ùœh¬¡æØ!¡ Y®<Ìf ~_¿0ö׌Á ''Û% qDáÉöÕIIL<5Ó#+++ö§Ó‰ÓyjD\tÒ}~Âá V»«mhÇÅÉoœDÔyLJjưy ôG—J…B“RÛáX™ºr ‡Câ›)¸d8¯yŸŽ‘‘Áí‘JK/#ÁçhHè  ¬¶Së‹\.EEE¸Ýn¡Í-­Lž4‘ÔÔ”ØysæÌ&å´íHD! “’’‚ªF§WWOÇï÷Suä(-­­1ªÓé%™P0HkkÛõ„ ã˜0~f³™ãuuttv’—›KcµZÑh4Ô?NrrV«…cÇŽáp8‡Ã´¶¶1mZ9EEEÔÔÔÒÐØˆ$KÌ_0“ÉDcc äçQZZzêc$I”•"Û•MCc# 'ðz½h4Z:::q»;¨««gò¤IÌŸ7›-Ú)sààA’““(Èϧ¶¶nptSâĉ&‚¡z½žY3gÆ5(´Z-²,ÓÒÒ³£N§Ã••EnNW]5 “ÉÄŒéåbº¨àü! Šö/:ªwÊqÃ4ƒkwœ~x2½Ý‘€wÀƒV«Ãh4Ÿ–—@ œÁ€%ö݉„1zÏõy=g|‡™ÌÑÎê€ß{Æ4ŠÁl&‚KƒsŽžœZvèСa;œ6aIÁ9‘$‰ìÁ`ˆC‡“1Ø™ ×é€QA§×ëiim£§·­6ZE:LiI ))Ƀ‚0›ŠyrŠ)@KK ¡Pˆîîn22ÒcS;¬ 3gL£¶ö8¢¿¿Ÿ£Çj(..¢§·EUOë#ÑÈ2Z­Y–)**`çÎOIMMEz½ž„'uuõÌš9NÇ]6 N‡V«¡¥¥·»«Å‚ÍfÅçóqâÄ ÈÎváõšèêî&‰œæ¹L¡­µîžìv‹½^OFF: N¬V+ƒææf‚Á`L,çdgÓÔÔLn^ntêh8BZz¨*ZN‡$ÁÆ2qâDj§¿€ä¤$ÚÝnѸ\@E¨âéëR§4Úh”ˆ: QU%:…ôôS•AÁ8è DUú=½´µž Ë•O_oÍMuddæˆøoF#Ö­ .Ytºó‹  -ñ%òŠ.Õð £ .}A¨µXÉ7ù,_ K ΋@ ˆÏçcì˜Ñ$&&àÊÎÂáp ª*®¬:Žò©Shii!##­&ZEMFÍ©ˆÕjeòäI´··S6jééiœ8ÑDzz`ŸÏ„»ìl’$a³ÛÈÉÉÆn·3ft¡p˜Â‚l6²FÆ`0 ÓéÈËÏ‹½ì]YY|úé. †ü¦Â‚|´Z-©©)XmVúÈrea6›™1}'°ÛíŒ(.Âh4¤­µ%#ÈÏÏ#=#ê#G1šŒ1g6²¬A”ŒÁ`@UUúz{±Ù¢qö¬™¯«£½½ää$rssÈÎv‘••IkK+Æ£¦ö8¤§¥¡×ëc60™¢ëKKFp¬¦»ÍFqqZ­–‚ü|L&#É)Ihd Z–œl×y}‚Óô MMõƒîÝOa±ØHN95³DQº»;âÒøý>Œ&sLì…Ãaš›ëIÏÈÆb±a¶Xiiª§Ó݆ÁhÆþºÔz-EÄ–ÎF8¦¦¦ôÔTa ÁEôË_þrØ!ŽŽùññ*íþ3èd‰L}DXRpY³yóVü~? Ìû\žC¿¡PˆU«^cáÂk¾´ÇPà›@Q,VO÷p’$ øÑéõX¬|¾þ!^ü´:½=]ØlNÌVýž4íi‚3:«ÀÛ߇Íîdó¦xóõŒ7NÀW@$ Ò}ÏÝw`0ˆDDðyàìßò0U‡kÉÍÎæ'?ý¦Í¸JEpÑrî)£’JªáÌSr4bºŽà `æÌéH’ôµL“ÒétÜ~û­bJ–à’E’$Üm'P”3y¡V1MôõvðûÎüýÑ@‚ö–Ƴ\MLsà+„’Á *gý‹À‚Ë¿­ìgr£ÿU\ïäˆ@p)b¶œË™‚ŠN§;÷zUÖ @ ‚¯Izú{p8-ÂR@ ¸èhll•™/ !\ T<0Äg°XÌh4šXh©Ïb³YcŽð‚ËNJ’Drr’°”@ .JA(.‘H„C‡j)((ƈ‰d£QE£7ß\ƒÙlÂ`0"I~¿“ÉÌܹ³„ \¾‚P @påššNIÉ(aˆA%‚ÇÓŠ¢„£^¸““ÈÊráñôÒÙÙERR2f³±¦Yp©"¼V@ †å…^ˆÛŽD"üË¿ü o¿ýöÎãBßÓptuuñÎ;ï ÙÿÛßþ–pøT¸´£G~îë›L& ‡Xß,¸Âáü”ŠŠ'©¨x’O?ÝÀk¯½M}}C,Ío~ó{ž}öùÏ÷Æ[xì±ÿ?–ÿéì޽ݻ÷ðÌ3Ïá÷ŸŠ…tàÀáóÊÿ¹çþ<äÿ6lbÿþƒ_Ú ÝÝ=<õÔ3TT<ɯý,ûæþì½nÞ¼]»öŠ).[†{÷~–•+WñþÏÂXÁEBss3kÖ¬aùòåøý~4 ÷ß?ííí±4ï¾û.Ë—/gçÎìÚµ‹åË—³zõêX§Ú?†½Î;ï¼ÃòåËÙ½{7¡Pˆ={ö°|ùrÖ®] @]]Ë—/g×®]qù¤¾¾>¶öñÀ„B!jjjX¾|9ëÖ­ ¦¦§Ó‹qúÉ'Ÿð¿þ×ÿbùòåttD㡾úê«,_¾œƒÏÜ&LLL" #Ë2ÉÉIAQQ—4_xʨ˕Éc=Ûîé饥¥fRl߃~?NЭ]»žššãäççqÝuל1ïþþ~îºë¯(++íûðío¼ñMM-ŒUʼy³Ù¾}Ÿ~º§ÓÁw¾s;M¼õÖî½wf³IÔf@pQÓÑÑ5äÿÏ<󪪲`ÁJKGpÇ·Æ}7vìØÅλq8,[v»0¢@ð5SWWÇu×]ǸqãøÃþÀƒ>8$ÍäÉ“ ƒ¼üòË”––²~ýz–-[FWWµµµƒ=+ihhà{ßûü1»wï ##ƒ[n¹…©S§ …xá…(,,ä‰'žà‰'ž ²²’O>ù„-[¶pçwrðàAEaË–-ìß¿€ììl‚Á ãǧººšuëÖqï½÷²oß>þõ_ÿ•;w²wï^FŒÁñãÇ ƒ˜L&JJJ(((`þüùØív^}õU IIIaùò唕• ù­f³Nƒ:èßn·t‰Š"¸2á¾}•TT<ÉìÙÓ™9sv»²²‘9r—+sHúÚÚ:ººz¸ë®o³víª«1bÄ™,?÷Ü ¤¥¥ðãÿ=>ŸŸC‡ª¸ûî;xúé?’——MAA.¡PŸÏ‡Á §¼|2'Žçî»ï8§8ÊÉqÑÐp‚½{+¹ñÆÅh4/¾†M›¶2rd ›6m%--…k¯Ïý×rÆ͆ ›ñùüFÚÛÝg„Ãñ³Ÿý;/¾øš›[xùå×Y²d1Ÿ~º—»ï¾‹Å À-·,aÕª7;¶Œ;wc6›¹ûî;xé¥W;¶ŒÿûÉ‹/þ‘ššã¼ýö»TUåûßÿ.{÷îgÆŒrQ›ÁEMSSsLìõôôò›ß<˲eßF«ÕðÌ3ÏóØc#†œóóŸGß}Ç×ñæ›kXºô:aHàk$77—±cÇàõõT__ÏK/½„$IlÛ¶ûî»FCVVYYY@tZæÀÀ<òN§“‰'2zôh4 ÇŽã•W^A’$6mÚÄý÷ßÏÌ™3ÉÊÊ¢¡¡@ @$!++‹ÌÌLvïÞÍÔ©S?~|´1«Õ²zõjTUÌž=›¬¬,ªªª…B˜ÍfGìxBB‡ƒ¬¬,TUÅëõòòË/c·ÛÏ X£Ñ°}ûNÂáSa¨EE\™‚pܸ1q#„²,c±˜éëÞU±¢(¬Yó>'X°`ÎYóÿÞ÷îŽz½>dYÆf³2yò„ØÃo4bé ƒ›ÍŠß@£Ñœ1ïk®™k”¤¤$`±œ ­GxãÕ|üñÎØµTUå÷2þUŸÛV&ŒÅf³b6›…¢ ’O¿W£Ñ€Õz*fW$A¯×h4¨ªÊôéS±Ù¬˜L&Âá07Þ¸˜ßý.:wôh±ð[ \üdešYRQñ$Á`ˆßÿþ¿§]%žáý9.îÝ'|“øý@L†¸¥!—ãš²¶¶6***˜2e ‘H„ßþö·;vŒ™3gb6›c³µL&†H$;çöÛogôèÑ<üðÃ<óÌ3”••1gÎ †Sm8I’âò$)v\£Ñ ÕjIKK£¢¢I’Ðëõƒí¾SyŒ3†×^{éÓ§³sçNdYF¯×ÇÚq†ÊÊJ¶lÙÂÀÀÿôOÿÀÈ‘#©¨¨`ĈLœ8‘¦¦¨çâ9s†o§Z,V¦L™‚zZ àÎN1B(¸B¡ÝÿÒëêêfåÊU„B!F*%##ßüæ÷ìÙ³Ÿ;vSRRÄ„ c …BŒQHRÒ™{SL&þóK$&&ððÃ×룢âIº»{¸õÖ¥:TŶmÛiksó¿ÿ÷£H’ĤI㩨x’‘#KÎÙ‹œ››CZZÊ  óôÓ¤¡¡‘3Ê)--&'ÇE$aòä ´Z-³gOçãwò­oÝxÆ|]®LÖ­ÛȾ}Ðëu$$$pøð**žD–en¾ùŠŠ ¨¨x’iÓ¦0wî,žzꪪª™;w6ùù¹,_þ>ùd'z½«Õ³·N§Åd2sèБØËH,j—§7ìv;3gNåÝw×£ª*åå“èÂ={ö³fÍ:®»î*+ÆÞŸ·ÞºTQðòÛßþ>Š+55™ñãÇðþû¨ÿƒÿþï§ÏÚ!})òÔSO Ù÷³Ÿý,nû±Ç‹Ûþ‡ø‡¸í‡ŽvÝÿýÃ^£°°pHßûÞ÷˜:u*3gÎ<ë}–””Ä®{RÌ}ç;ß"îV­ZwÞÒ¥KYºôÔ»e¸i¢Ÿ¥¿¿'.a}}#Fˆx¨‚Ké—¿üå°>r;::xäÇ?¤¯¯‹‚Âla©/AEÅ“q£©@ ¸0ïÏ={öãÊÌgó¦xóõŒ7Ní+ ‰ K÷Ü}“HÄ{EÚáW¿úOrsshl<ÁŒåLõ›ÐÝÝÃ[o­áž{î¼äc8¡¡¡ƒI“¦ŠŠ?Èéa'¶lÙANNFœ Ï)-óYã @ðM |ó5ªIpé`³Y3æì‚-11‘—_~™@ @ZZ:ޱcÇ’——Ç<@CC/½ô}ôý×- ;Ìó‰D„!®@E!19å åïnoB¯7`2ÛÐë æ‰D´6×cs$àt&Ç94:Ö–Ìf çT_D @ œ‹ÚÚãdee^v¿kôèqqÞ#O20àE¯7¢Ó `î÷¨®®ö¼‹‰¢¢âs¦‘$‰P(„F£!£×ëÑétFEAUU$IB§Ó¡Ñh…BTTTpøðañ`|¶nûˆÖÖV&ŒOaaÁ¤´µ¶¡ÕjÉÉÉÆl6›¶êH5)ÉI$%%q¸ê}}}”O" åKØ^‰Dø}Ã1!xôÈ~º»ÜCÒ”™<8Ê(Ñ××ñ#•—¡×PU•ÚšC؉ *€å Ýçç„:‘PÈOs³›¬¬4TUùB5íȲТ@ ¿ßÇûï¿‹,ËȲ ¨(ŠŠF£¡¾¾Y–$Y–ˆD"h4n¸a6›Uï"ãdpñˉp8„ßß?d¿ÛÝÕêÄdÚžéë룻»ë¬1—/’;gŠŽŽî½÷^^xá|ðAxàØñ¼¼<þñÿ1¶­( “'O¦¬¬Œ+Vˆ‡ x ü4žhB¯Ó¥%%x<ýÔÖÖÚ2w0ìG#éX­zzz¨«o@#Ëäççã÷ûinnF£Ñ™•IMM-v»€?@JJ -­­dge‘œ’»~SS3;w~ÊÈ‘¥x<Ö­ßÀ¢k²¿òN§¢¢BÂáû÷W’ÀÈÒl6k,®fgghµZ èííÃÝÑ,IF òéî¾Y–)**Äb±ˆÂU!¢DÎ Oj)FKFfnÜñþþ>5Ú邪b4šHLN£æØAróFÐÒ\,kHLJ¥ÓÝò…ïñs©²n¹Ÿn]Ýv­LÈ$ON£¥¹uØôz½>îã Õjq:ètf´Zƒ¨!@ Pèìì"--•¬, h42™™.Þ~û]’““ÈÊrÑÚÚF($+Ë…Ñh†¾î¼óNÖ­[Àßþíßž3½,Ë$&&²~ýzn»í6a@ÀÓçaßþýdefrðà!&MœÀ§»v“ž–Ʊc5´µ»)ÈÏ#‰`6›¢6LHD¯7°yË6\®L|^ŸlßAN¶‹Q^>Y–©ª:¨‘¥œhj¢­½‹Ù®={¸æêƒlÐxâééé”––‡©oh¤³£“ªª#”–ŒÀÓßÏÀ~/'L@§ÕâpرÙl?~œîî²]YlÙº‚‚<ºººéêÚEbR"‡fìØÑìÚ½‡ÔÔT*+qeeSdO‰>E9ã”&.¸§ IDATÑ“ë U5úì$$¦Ä‹I%]_8˜NQSˆ„CTWíÃjµãÊ-B‰DιVñ‚ Â6ÅͶÐv°!hØßÀGþ ?ÿùàpØILL¤¿€`0@jj‹‘ää$rsó©««¥¨¨§Ó!j†@ †`4Ñé4$$Øéîî=õ¡ÒjÑhdŒF=^ï€0”@ð5’‘‘ÁÝwßý¹Î™4i“&MÆ; ¯× €Åb¡°°€Owí& QP¢ªÔÕ×0jÔHdY&))³Ù„ÏçÕåÂï÷³wï>Âá06«•ü¼ÜØTÞÜÜ\ºº{HIIÆfµÒÑÙ'ô:O?Š¢PÝà MfV&]Ý´´¶b4Ðéu8N{ìüp8L("ÛåÂd4Q}ôÎ'v»¼¼<öí«$QR2‚ººjÇd2á°ÛEÁŠ>E=—@VQUeH:Uî?9˜¯ª ápŸo£ÑD($ð£Óë¿Ô=^y›&“‘¤¤D222hnn&Ô’‘‘¢„(**ÂdÒc±˜IOOµB Ãât:QU…„„:;»cû“’’ñù¼FdY# %|¼ôÒKÜyçgMÓÞÞŽÅbSσÏN«v»;„CaBápÜ1NGv¶‹Ý{ö ( 999CfßÌSâÌ€‹Š ùdû>Ü´™P(„Ë•EbbªªräH5O?#Š£$ív;GE§;%Œ&ii©ìütÁ`ˆüü¼èõ¯{’¶¶v‚¡ ¡P˜ðg~Ë•Œ‰P¼zÈ~«Õ[eˆ Œúˆ‘@‚H8Ló‰:$Y&'¯˜žîNꎒ[ô¥¦ì_°…|v»ƒp8„Ýn§­­í´¼H$,^@ 8#z½“É„¢D NEA’dL&#ýƒß›ðÖ'øZðÒÔÔ8d_Ÿ‡ÞÞ~ôú¡^¯ï²ùý lذîînn¸áôz=¯½öÓ¦MC¯×óË_þ’¬¬,æÌ™ÃøñãE¥ù N§“ò©S0 84 ‹]‹ÍfÃát––†$ÕóxÍÕ °X,ȲÌÔ)“éïïG’$¬Vápˆ””ddYF¯×³èÚk°ÙìL:­V‹,kHJJŒMp8Ìs^¯Y–°Z£keY¦¸¨›Í[“]>u ^ŒFiéiDÂtZ-Ó§•Ó?0€,ËØ¬V‚Á .Wz½žk^ÝngĈbü~4Í`ÌJÑ 1lg¦tz„¬ÑÐÑ¿ / £¢¦“…Chuz’RÒ¢u+! Pñû¾>Aòi>z*°f_[ŒFƒÕjÁçó¢Õj?êÒÒÒ9zôŠ¢ éîî&--á¢+«­[·²uëVz{{9räHìE'‚¯‡ÄÄ$ª««?Ó¨’Ÿ_0d($áÅȤIÉÉɽ Ûs Ÿ¹ËI›wG̹§™ÕÕÕ±`Árssyþùç‘e™«¯¾€¿üå/ÜÿýäççSXXˆËåÂpm­6&NÚ<11ÚÖ¡Åhˆ÷«‘àŒ;×é<µ­Ñ0 ¦ÖÍh>§ 0ƒah¹ §Î;Iaa‡»ÝvÖt'ësÂi÷a4ck¹OÞƒÉdÂd2‰×|ô{zILJö¸ßçüÞy0Œ0Œ‹Ÿo$ %& b³;ü§ÊÂd$~ï×#Ë,#ÉÊOâСZÊÊŠP󴲆„„D§Ý˜Óé  áóù((ÈíOOϸ( kÖ¬YÌš5‹£GžsZ„@ .³YwÅ–m^^S¦DìZµ €¢¢¢Áç6„Éd"##ƒœœ’““ÅÃp 1­|ª0ÂWŒ,˃ÞA‡óa4š£SoÏ’&– ÕêÐj‡}1þùÂNÈ:l&+f ›É†ªFƒ¨ªÊÁƒñ±fJJJ±ZmX,ÑO?ÍÍÍ8…¢v.J~õ«_ Š×Á×M àçĉz,–øYoo?UUG0›ã÷×Ö6ÐÕÕû@*™†úã©®¥§§Gô+@UUæ\uÕ9Ó…ÃaE‰y ƒg‰ŠN –.Ëp_'‘ˆ2žE:GºÈçµ<=½F£aêÔ©TTTÄ`ii)¯¿þ:’$ñÈ#Ä­‹Dó£ð®/øêßáPè«„g"##“I“&Æí;9¥'êG=å%G ¸H ƒüðïÿUC â¾é!þë¿þtÎtÛ¶mç•W^ç?ÿó—±}ùËë|ûÛ7+ ßxc5“'O 'çÔTÃöö:;;9²DþÁd2ñïÜΞ=ûÑjµlß¾“[n¹1vnGG'••™7ï*aH@pἌ —SÃgçÞ* ƒ>œO‰?UU(ÍÏ -5EJpYàõzñù¢kÀu:-öÓâFíÝ·Ÿ¤¤D ¨*EE…ôöõaÐëãÃ+ŠBw÷©©š'½è}^<„Ùl&??OÌeBié\®L‚ÁF£‘W_}“‡ºŸíÛ?‰Äôô4¾óÛyê©gX¸p>wß}55ǹîºk„ÏBuu ))IÜyç­üâ¿ ''NG{»›wß]GNŽ‹#GŽòÐC÷óÒKÑõ¯¿þ^¯¹sg # !‚a‘$r²Ò°Úì±µ-²,#IáPo·°‘à²áСÃ446’š’ŠÃé`Ìè2ú<B¡m­mèt:œN¨Ñ‰M›6“ž–FiiIL<ú|>Ö¾÷>éèuz&L×;€Þ` à÷“@0" ’ध§­V‡^¯£§§½^ÓéÄíîÀápÄòìóxÐëô$$8éííCQ"D"Ìf3f³™`0HOOï` e‡¹¿DâSO=ƒÅbá¶Ûn¢¥¥ââá} tw÷ Óé°ZEتsqÒ+äÊ•¯0~ü<ŒË•³ïwÞÊo~ó{ü~?f³iXO”Š7òþûïó‹_üBŽ@ ¡@p êAÀl4`·šãÄ ,Ë„B!|Âi…àòÂl¶“›Ñ`¤¿¿Ÿ?ÜDRR}ž>A›ÝF ¤«»›®®î¸ÑDY–ÉÌÈÀl1£×ëXûÞ6ìv>ŸœœÒRSÙ½{óæÍeÛG3ztGC¯×ãéó0vܘX^lÚ¼«ÕJOwcÆŒ¦¥µw»»ÃN(böì™|ôñ'è´:<cÆŒ&''[æ7̆ ›hmmç•WÞà¶Ûn¢ªªššš:þøÇ?óÈ#Ä•ñþýÈÌLyÆ+,, 7×ÅŽŸòÖ[k¸í¶›…QÏ@aa»víå©§žÁf³`4),,`ïÞJÒÓÓÈÊÊ !!!ÎCaa‹_CSS3»wïgÑ¢缎ÛífÛ¶m,^¼NÇ[o½ÀÔ©SÉÌÌdÓ¦MtwwSPPÀرc™7oÛ·o…$A(\¼z{©~ã¸}a¿ÿ4U(ÅFãþÞð—áóÐÑщÍf% ¢( S&Obý†Þ¸tv› «ÕBnN.yyññæE¡»§¯ÏGÊ çÁ‚‚|z{zéééaÔÈRdYæXM a4iowãt: †‚´µ¶Åòêêî&rõ‚©ìÛ_ICC#:½Žää$ÊÊF±nýtvvÒÞîÆáp …hmm‚ð"`Á‚9,XpÊáHié~þóÿ/¶íóùIOOìhhbÙ²ÛcÇ–,YDã›Ýu×_ cž“ÉÄ=÷Ü·ï¤ ÏÄõ×_ @v¶‹ììó‹¸bÅ -Šæ»sçN:ÄUƒgÿçþ‡™3gÒÛÛKii)«W¯¦¸¸XÄ¢„ ¾~Ú++iøðó¦ÙñÔS1ѧ„BxÝî¸ãÁG9MJÀ0‚P¶\~ôz1 èt:B¡0Çjjñxú‡~4´Z::Ütu¥˜˜Û/Ë2»³ÅŒFý´h5Ú賤Fƒ1gferðà!JJŠq: ÒÓRÑét8œNúûk°Z,„Ãajjjikk''ÛEÿÀ]ÝÝÔ¯ òlÇ`0–š‚Þ`À~ZPfÁÅË7.ÆíîD<ÉK¿ßOiiil{ëÖ­±í7Þx¯×KZZ¥¥¥¬[·.¶6Tp Ÿ×ÇÁƒU—§Ðj9²E‰Äö;V]{.¸àäææbµ^ø—o\*Š‚ªFÝ9žtB‰DbSôNOsò¸ªª(Šç´ ‰Ä¦öí:_ÄÑà›ED†8ü\}ß}T½úê©ò ‡‰œïØÝéùE…^¼ÒëîêÄãé‹ "EÓ)Š‚IÄ\Fddd ÕjéééÁfµRXXÀ´iSñz½Œ?–gBœØš8aMMMx}>NÊANÇÈÒ‚¡ Áž éi©”––àp8Ðëu8NŠ @U)(,À ×sÍÕóihhD£Ñ˜@$7£ÑHBBsç^EkK+#KKÈÏÏã“í;pؘL&fΜŽÃaçêóhhlD#kHJJ…y  ÑhHOO†¸„ÈÌ̌Ŝ2e ååå±íÄÄDrssY¹r%7n$ ¡Ó騏q#›7o&55•ûî»ïŠ·¡Åjeòä)—åoÛµk7²¬„>_ˆ)S¦ &T]Xzzzp»;/OAXQQN§#‰°xñbL&o Nåûîw¿‹Ífã·¿ý-’$1þ|ÆÇŠ+hoo§¤¤„%K–ðþûï³ÿ~÷Þ{‡ßýîwH’ĵ×^ËØ±cE­ºˆ©ZµŠæ;bÛûž_gç°i%Nù=×àÝpQ$ô6#o½•ëŸ>öÓjµ䉂\dee‰]–í:óT²¤¤Ä!âK¯×3~||죲Q#¨ÇÑX£ÈbaܸSï_»ÝÎèÑe±íÓ‡¤$'Ǧžž|.õz=#KKâÏ/+…(|…Ü}÷ÝCöÍ›7/nûŸÿùŸ‡ÿlš+Y’0/Ï f¨ê“e£Q#áÆ`øêêÐ7.¯»î:ÆŽË믿ŽÕjå•W^á±Ç‹‰E nÛçóQXXÈ=÷ÜóÏ>Koo/{öìá±ÇãàÁƒ¬]»–%K–Ä]ãé§ŸŽË㤠ôx¯¿þ67ß¼DS 8ž|òi~øï…!†aíÚõ,Zt5;vì" 1sæ´ó:¯µµßýîy¾ûÝ;cqR¯¾qA8nÜ8^}õU&L˜@aaá×zm·ÛÍŽÓF¢Z[[ÅSt0ï¿`ú£RûÞ{,Ïâ%KÐYÎÏu¹$ËÈ¢[K bœk]ØÔ©“سg?›6mcΜ™qÇ6nÜBRR"ßÿþ½üáÿÍM7Ý@eå!zè~–/ÿ ‡ƒO?ÝÍ{ï} ¡@0 õõ ôôôápØÉËË¡££“ æžv¼‘žž¨°„'99.8D$¢àre^SêýþGŽÅf³²wo%‹]Åb&99)–¦®®ÞÞSvlowÓÖÖŽ,k(++%==¹sgÒÞîŽ ÂÊÊC(JÔŽf³™p8ŒÍf¥½ÝMêe“ú„/¿ü2S§N%??ÚCh·ÛéëëÃï÷“ššŠ^¯§±±‘ÔÔT v»ÆÆFÂá0ÚÓF}ºººbNÜn7===“™™Iss3N§3ÎóUAA±í£G²bÅ ñæ¹0&$0꯾/sz½$±Z N¢žGY~~.o¼±zˆ <~¼ŽI“nB§Ó …èëëÃn®KµXÌx½^JKGPZZ- }òòË/sûí· C  Ù³g?ápø´vƒñ+»^ss+o½õ.EE>|›ÍÊÀÀO=õ Ï?ÿ4ÝÝÝ´´´ñÁ›Y´èjöï?@$¢ ×ëX·n#?ùÉ/ûryé¥WÈÈHÃãé§­­€––6Þ|s ÿôOpâD3ï¼³–ÂÂ|:‚ÝnãïþîÇÜwß]~šššY¸pþ|[ZZ‰D"¬_ÿ! Ì¡µµE‹®æùç_ä±Ç‚ðtE¥³³#nŸÉd=¯s?ùäŽ?ÀÒ¥KY¶l/¾ø"F£‘eË–¡×ëyñÅq»Ý,[¶Œ””º»»©¨¨àÆoÄjµrûí·SQQÁ„ ¸öÚ¨K媪*öíÛGqqq,Ïîînîºë.ñ6œ«éC$f‚A¾êwb^^Ž0òEJmm-[·n¥§§‡k®¹NÇš5k˜4iz½·ÛͱcÇÈÏϧ¬¬ŒÃ‡SSSƒÝn…¨¸\èêê %%9nŸÝîøÊ®—˜ÌØ·ïv» ƒÁ@RR"#FÅÒŒ?–îîÍÜzëRÊË'óôÓ¤££ƒÁ€Çã¹"êi{»›ûî[6Xgë¸úê¹|úé ºþÝ`0ÄÙqÊ”‰\ýBÜîÞzëÝ!y?^ÏÞ½•(ŠÂÞ½•q!u.7´æe .|:YYçêÉ'Ÿ²ïþûïÛ^¶lYÜöœ9s˜3çT¡ÄÖždöìÙÌž=ˆ.nnQ´@ ‚/ÏáÃÕìØ±‹¥K¯`ß¾JV¬x…ÿ÷ŸqóÍKxýõw0™ŒŒ;š‚‚<8̪Uo"Ii¼ùæ*+±jÕ›L™2‘Ü\Sòb¡®®ŽY³f‘——ÇŸþô'4 Ó¦E×d­\¹’ &°uëVn¾ùfÞ}÷]rssyóÍ7¹á†¨««cëÖ­Ìš5Kò âóEÃeåä¸hmm§¯ÏCSS3{÷V²jÕ›ÜzëR^{ím6mÚJyùd"…#Š°Ù¬hµZ¦L™xEØÉåÊ䥗^ÁçóÇF_}õ-öî­äÈ‘£¤¤$#IÒ Ûðx<ìܹ›+^& QX˜OWW7ë×oÂ`00rd ÕÕÇHOOC’$öî­$!ÁɦM[ijj¦££SÂÏ q8ìqû>ëéS ÁåÚËÀåZ‚ÍTZZ£>D×4ÝrË<™™,]zíí¤¥¥ Óé˜2e"“&¢#"‚‹‡¼¼¼˜ {çw=ztÜöÂ… =z47n$‰°yóæXûðÖ[oFü$$8¹é¦ëñz}˜Í&’““ðx¬üû¿ÿ,žíª«f0yò : ;))‘'šPõЉ÷ùíoßBKKF£‘Ûn» €òòÉL™2‘„'6›uˆ§L™ÈUWÍD–%²²2 ƒ|ÿû÷`2™¸öÚ466!IK—^G0dÖ¬éää¸bñT… @ l§Åª0ô ‰§·ÆÄ"D×j»\§<}}}ÝCŽ=ZCZZÊÕáv±PXXt^é>+ü¤óÍ$‰ðM1¬Vååó/ÅÖO;~¿Ÿ-$8“0™Lhµ:z{{Ðjµ¤¦ /P|!-ã&‰µ£’MÞþÊòo_àsàLNG"€Vsù>:*0à‹ÐÞÞ>ìñŽŽ’““Ïx~UUIII¤¤¤ˆ #‚+ŸÏG}}=¹¹ÑØvGŽ!11ñ’üN:NÌfnwûyw⨪J uŽ£×bkB ŸG,©*#¤¥%\Ö¿ñƒÍ{‡=ööÛo³{÷nüña¯^½š`0HOO‹/&=]¬ Á•ßïgÍš5\{íµTUUèééaÑ¢Eddd\2¿Ãh4Åây'&&Ä< ž@ @ooƒÇ3Wüì¡:öîÙرãќ第ښcøý>F•ùÆítøÐôz…EÅ—LÙ ‰.|¬_ÿá%{ï$???öRŽÊÊJn¾ùfn»í6V­ZÛ¿cÇÖ®]÷W__/*„@ \ätvvÆÞÛÁ`EQbÛ­­­tuuQ]]ÍÚµk9|ø0ªªÆ¶?úè#ÚÛÛcç„Ãajkkñù|¬]»·Û}ÙÛP’%l6©©©D"ôz=æ’[7›àääLàŒŒ üþ³ BUUéíí!55 ‡Ã‰Ãá$%%•Ö––sž …¢ëuΓp8ÌÊåþ\¿çÍ×V /l[é@%ûöìaú÷hoo»dÊVŒ _#©©—î4Ê“‹ÆOºÿ<$&&Æ…¢yöÙg9rä?úÑD¥‚‹˜+VÄâ:oß¾êêj&NŒÆ¶[¹r%ãÇgóæÍÜxã¬^½—ËÅ£>Êã?Ncc#}ô;vìˆÅþÓŸþÄܹsyôÑG¹ï¾ûX±b=ôÐemCNÇM7Ý„Õje``€‚‚|>^¯÷’ù F£‰>‡¶¶S"§·¯¤¤Ä3žÓÝÕIbâP¨¹yùÔ¯¥¤t$Á`ž§£ÑÈíw.ÃÝÖÆ Ï?ǨQ£±X­üñÙ§QU•þ~ÆO˜HqI)¯¯z™p8LrJ w}÷¯QRJbÒ©å,¯¾ò?4ÔÕ!IKnºeÈhÝÁÊý¼´üOT©bÁ5 )(,æ·Þ ßÓ‡$IÜy÷w9v´š7¬G–e–Þr+«ß~,ãóù˜6c&ié¼ýÆk(ŠBvN·~ûNúúzÉÍÏgäÈ2Ì +^øoÚÛÚÐh5Üü­Û9x ’®ÎÚZ[™uÕ\jŽUÓÒÜŒÝn')9…›¾u›„ß»víb÷îÝg\3%|^›Ø¿ÿ×_-6l"'Ç…ÇÓÏOü†•+ÿ €uë6²kWtjæ¤Iãq»;¸á†EØí6ž}öy~ðƒû†äû‡?ü‰®®ndYææ›o`åÊW±XÌ„B!¦M›LmmË–ýz½ŽgŸ}žo}k)/¼°’P(„Á`à?¸76ÝãBñÞ{ï1nÜ8ÒÓÓ1 <çu¬¨(ÞqAZZš¨$Áe†Åb¥³³‡––æaÄ&8t† ™ç=5Lp!ùÆs¦ñz½L˜0!¶½mÛ¶Øö{ï½À¢E‹bêEaÖ¬YL˜0I’hmm¥²²26"4räH’““)++c„ äçç_þφقÕ ÑÚÚÊM7Ý„$I444P\|iL+ üôôô ‡cû޳Oû …Ãî34 Âá½½=$§¤àp:±Z¬$Jfü„ID”=ÝÝÜÿǰX­<ùD]]],½åVrróxò‰Ša¯½áýµ”OŸI(bÝÚ5>ß]6f,sæ_Í}óƒØsÐt¢ü(G«àðb4šHLJÂ;0À¦6ÐïéãÁÿ“ÉÌ“OT0yj9v»Y#““›O‡ÛÍË/½À??þ¯èõzÚÛÚxø§ÑÜt‚-›>$¿ %áλ¾Ëú÷ÞÅÝÞÎ_ÿïXùâ ¯­ùÆÊWÂÁ—Snn.µµµ¼ñÆ _%âå%KhÙuÊ…ïwÖ¯'uܸ+Ι™¬\¹Šë¯¿–Ý»÷1wî,4 ãÆŽ¥Y»vC,öÖÚµ(..@Q~ýëgñù|g_0cÆTúú<|ôÑdYâÁ¿N§£¢âI~ô£¿ãw¿{Ž;ï¼ N‡ßï'`0((È;ëtÏÿÇÞyÇGYåûÿ=}2é½WBB„@ˆH“^¥X ¢"–Ų»ÞÝõþֻ岺»èuUì`CÙ¥‰ U‚ôji$$¤g’éóûc’ÉÌd&t„ð¼_¯¼òÌSÎÓÏs>ç|Ë¥8uêëׯ§µµ•¥K—ò /X*Ðòrëíé§ŸæÝwß%%%…Ñ£G /…€À ¦*;›¢­[¯©ŒO?L¥ºÆ#3nìh¤R =ãnËk)–i/œÌ?þñRSSIKK³þöññàóÏ?'++ µZL&cÇŽˆD"ôz=Ó§OgÈ!4660a»‘±ö2º3åÛ~‚ IDAT,Y²„Ç{Œ… ²lÙ2úôéØ1·OZ'³ÙŒL*Ef#ðÄb1zƒë”4*•Š––TõK}}>m9,%b ™ÃGÐ3!£‡qòÄqÒÒÙ‹©w޼‹‰II|ûõWˆÅbžzæ9§ûŽŠŽaÊ´–ãpwïòÜ<@Zú ärnnn¤ôK`å+xø±ÇÙºe3­--mËU6Ï®/§LE&“ñÙ§3hHs|€€.y·=ócÆMàÌéS·ÄýaÛ«R©¨««.ƵT@İahêêðKHÀ/!Õš¶@"3vì(þð‡?3iÒ8$ ƒ½^Ok«77%ÁÁ<ñÄø¹¹±bÅJ²²öuiÏž–Ö¯mî¼þú[v¦˜nnJôzŸ~ú%/¿ü••ÕL›6‰ÈÈ0¾ùæ?TW×|uf«ÉÉÉNs ÍŸß1’©T*­BQ@@À5­FË4õõyï½+*çüáÜýþûk:–æóç‘©TÈ=<ò›ß\]ýo±HN[‡þm*…çÒ>ú(†¶Q¡öï͈#Ú¾uvíÚÅC=DZZb±³Ù̈#xþùç‰DH¥R0Ö2är9O>ùäs ÃÃÂxå•W¬¿»»‰l;žžmµ0T^8O\KG²B©¤±¡žŸ|DXx8£îGÎéSÔ××ññûïò¯ÿ‹ŒÌ»¬eÚN|ðî¿Xüòoùáû ˜LFÖ¬^޳îcÂ䩬øä#¤R)Ͻð²Óã[øÌóüë­1ì.§eßu÷HV|òiáíãC«¦Õî8’û¦ðîÛo¢×é9Ú"î##£ìÊš9œ¥o,ÁÃÃǟZÄùó˜ŒåàŒaxxxòÄÂg8°¯ º’ÉÈ|õU2_}õòE çvï¦`ãFbF"lÐ >>H/ÔåV&5µ/ƒ-¦5§OçàååÅŠ_±pá|æÏˆO?ý €¹sg³`ÁÃ:t”±cG‘““ë´ÌqãFóé§_áî®bÁ‚‡3f„uYûô /,âøñSˆÅbBCƒÙ·ï [·î¤wïÄ«ƒ·šúzŒÍogÐj9°téM=ÖÓ«V¡¾pá¿fR77N~ù%ª€€«„Ž— ‹ˆŠŠê´ÌÙˆÁµÒÒÒŠ››²ËÜw;wþDNn.<<77%ùùlúa33¦O#22Bx\ ‰ì:m…!@Ïž=‘J¥Öy&“‰Q£FÙ­#‹;¥RÜ‘QÑäž9míK$Ä÷L°{>î?‘{ÆO´þîÕ;™^½;: ‡d ³›.ÈÏC"‘`6›Q¶¹ÁŒŸ8™ñ'[×ë—:€~©ºî‹yþ…_;Ý@Zú N£•Žë>û«íæG8ÂÁCœ1´£s ܾ®4$ÃåþA(pG oiáû'ŸäT[càà[o=bÞ11ø%$ÐkæL>>¸ß†£íb %¥))&£þüêW ®o»ž]å”–JZZªÓòÛ§% ýû§XçϘ1Yxغºæfš+,~jç²²8·{7%;wÒP\|Ûž—X&Ãç2ü©’fÏÆ7>þºìÓ¯gO"†]¿FHuõE)))ÁÃÓ_??ª*-þù=zÄQ}ñ"ÿú×{<>Þ\¨¬DݬÆÝÝ‹Ïòñ'xä‘ylùñG¦M¦6óüsÏðÙç_òð¼¹Â‹u•DDDtjd§¥¥ ƆV†¼¼<¢££Q(œ={“ÉtÛø^ ‰„Þ}®o*ˆøž ,~ù·Âƒ%B«¥¡¸˜‡Ϫ  ¼Û’¥ÞL.ž:Ež ŸÍ’;­Ó;÷;>û,cß~û–¸†jµšêjQ·}FÌWæY@àFRyì&½Þiý°ý:Œd]MÝ×kæLüqçvïæÜž=—nÄLœHPJŠËå2wwâÆ»mï—ZÝÂ׫¾!..–ýû2yòDÉɵX<ääæEuu59¹¹øúú T*9Û–‚  à,¿zþÙNå~µòk"##0›Ì466òÓî,žî<„—·7þþ~TUU‘›—‡R©D§Ó²víz""©(?ÏäÉ©©­¥¢â|8R©”¯¿þšûï¿¿[žsLDú¥e /Ðud×¶õ7¬lAÞ! xúiâ§Láà›oÒZ[KþºuvË›**Ø´p!1£G“4ÛuR̬ÿù²?ýÔ©ŸÎšÙ³Q:`÷mÚätûŠØ÷Æœ?x†’ÀÒ»>á½÷n‹ˆ¤fÌx¨dÜ”ýUVVÑÔ¢ÆMá¡7gŸf³™ÜücÂK#€ÙdâÄgŸÙÍ;ñÙg4uÑy¤W«»\nK`Ÿ>¤\"=Iä]w™iß¨ðŠŠºíƒNuGÜÝUÜß2d0î*II½¨ª¬ÂÇ×ÇDäÞÓ8w®ÌêCŒÁ`àÿÞú§Ór|à~;ÂääÞ”–ž£j*n*K@‰±÷Œ¡°°???||¼™6m êf5iX}ç9˜†ÎLE/¯acM#´mÛ6D"ýû÷çœMg΄ HOOgß¾}FvïÞL&ã׿þµpèׯC‡¥µµ•ƒÞ6Ç­ts£gB"f›èÈuuuTUW^r[½^OI±ÅR "2ú²ò_ Ü\Ax‡àæï›¿?“?ý“^OkM µ¬ž>Öš޾ÿ>Ç>úˆ-Ï?Ï´Ï?'ÆI~œ€Þ½‰ÌÌt¸A¯Vw¥îôÊ•ä¬^m7ï¬ ñ(pmlݺ“˜˜(âãã„‹!pIÔUUœ^¹²“ Üú¢%‚š£×lW^´bkŠå¯žS¦3f ½çÌ,>srOOáâw# ìè¼Rž6ùÃÀ2â×£GG½Õe™^^žxyu<'2™Ìnûvââ:ò„C°ýr_‡|w¾w@þ»ëAqq1K—.E,Ó»woŒF#|ð'Oždx›‹‡##GŽdÆŒ¼þúëÜwß}Dÿq n%Ê+*¨¬¬dÔ¨Q´¶¶²dÉ$ Ï<óÌmsb‘‘ÈŒÉÜaêZz®¥²ëüÆ•ÎSW[Kt[À¬s¥ÅáÛfV. B_꥖Ép Á=$ϰ0« 0¨++1êûÈõš5‹Ä{ïeâðõ„ ”îÚe·Ü¤×[Í@ë ­áÌö½ñ' × ­­ìûûßñ—¿ vm};a2™0›A$ê§mjëIs^Ûl6c2™‹Å]†KwÄh4b2™¬9žÚ÷c4­¡œ32!—ËmŽ­}_$1yy;v‚{ïbõ ¸³ø§Ÿ†ö4 fsÇ´ ŸPWá‡ÌõÂÓ“´gž!yî\ü… ß ‰AŒª;âE‹0™L(•–Ô/¶uYÄ}‡›ÈÓO?D"áÅ_D*•òòË/ ʰ˜Œ>ü°%ïðСC:tèqÞF£‘š‹I=vå°tK§Q|eŸ¯DïéL&wÙ¦±Í[iÛ†‘J¥ˆD" f³‰D‚X,¶–Ñžâ¤ý¹ko™Ífk>M©TŠÙlÆh4ZÛ_wz¡x‡3ýë¯;Щè1aB~1R77&ú)¹kÖØ5ül4ˆ$KKÉýÏÐÔÖÚ™8’ýñÇ íµÛZ.[ö ýúõÁ`0âííEjj_: @ß¾½9s&¸¸¼½½Ø¹3‹áÇRZZFYYqqÑ„††\V…¤V·ðÀs÷ÝÃÐëõÌš5;³¨®¾ˆ\.'%%™aÃó§?½NzúfΜÊÚµùùç„„ÓÚÚÊK/=Ëòå_QVf‰6gÎ áe¸¹ë¿ÿ›Â-[¨h3[’9Œä\)^ôyè!»yƒ_|ÑÒK"н¡ÈŒH"4ü»#£FB¡°rkËýÖ©QÙÖ¹Øþ_È5hÁ`0pñâí`åZƒ>y‚”ˆÜ>j'9‘MØÿKÑ__'88„ÖÖÞ^úT*&³™YsîgãúµhÛ:(SRû³sûV|||‹Å’Ü'…í[· ‘HÐét,X¸ˆ÷ßy777Ôêfæ?ñ4kV¯¢µ¥‰DÂÀAƒIê݇/V|@Hh†²s%ˆD"ÜÜT<ÿâmÞ,Â;œ€Þ½ è}uNõ>±± ~é%—˽££™øá‡LüðCN~ñ…ÓÑÁv’z©‹Ìí¢E سg?J¥‚ÔÔ¾äæÐÒÁnãÆ-Ìš5ìì$%%DuõEvíÊ"11;v3}úd<<./@Æ=÷Œà¹çžbÿþCœ;W†7#FdGvö T*?>ãÇOY·Y°àãY²d)nnn<þø<ŽÉföìé7Q4/£¾¾ž={ö0uêTáü…I_¼˜ôÅ‹… ! à”ââb>úè#>úè£;òüzè!—f±W¡C‡¬QY=== Äl6STTtKŸ¿^¯»áûˆ%xxz¢ÕhðÀß?€æ¦&^øõ+,}c žž^VÁ¶ô%ÈdrfÌšCTt KßX‚F£! 0‘£ïáûõk ÂÍÍY÷=€·y¹9Ô×סo³~;t`}RRyüɧùbŧÝ>â« /“¬¬,²²²nËÞ›ÛÇQƒîȺu›HO€V«åر( ’’((è¹ÞÒÒʦM?2mÚ$6lîîöÅÍíò¬úég233(/¯ 22‚šš:ë²~ýúb08}:—¢¢ššš–¡P(¨¯¯gÛ¶]$%%zïÑÂ… Û®C‹ðRÜâTWWóá‡ðÔSOñÅ_ V«;­çííV«E£é^ªÓÒÒ®‹ ´eÁ‚”——#‘HèÕ«›ºq…ˆ¨(Ε£·¿?"÷¤&•;m)&³™Ø¸„GDPŸG^^2¹ŒãÙ «À `ª«ì×øøúRXP@}}f̨T*ÎWT°â“™8Ù¾³Y"•’”܇O>xÑcÇQ[SÃ;¢u:+_„w(™™™dff’ŸŸÏ.Ÿ8Ë¥_¿>477#‘HHMí @aa1¡¡!„††¿¾¢¢’¶¨&“‰êê‹xz^™©Þ AiTVVJzú"##ðòê(Ãd2¡P(èÓ§7:Ž¡C[+ßvóЈˆ0ÒÓÓÐéô7E Üž““ƒ^¯G,s×]wpúôiôz=Ï<ó ¥¥¥ìÝ»—›Ü¢Y»v-………<ðÀœ>}º[Ÿ«/Z­–êå_â÷úÿ §ñ7ÿ…J€R©$66Žò²sDGÇÒ7%•ÀÀ N8ÀC|Œ¸¸˜+®ÿ~Ìf3cÇŽ%''‡ñãÇ“——ÀܹsùôÓO1 èõzÁôî2(,,dîܹüôÓOv©;º#"‘ˆààÔî~ñ5*7ÞˆDõA¯ÞÉôêÜѦ #$4Ìú;&6®Óô°»î¶ÎÓétx{ûp<û>¾¾‡„¢rÈQ«rwgôØñNÓ¶|A ÜÆœþúk²þüçŽJ¨í¯¾¨½ƒybû2ÇiÓeFýºxñ"7弚ð Ч¹©™üæëüÄÄžä矽A~áy¸:4-ÁÁÖß+V¬$6¶R©Ä.ÚdppP§@%×ÊçŸͼy÷ 7áPSScù‹ˆˆ 4ÔbUb0hhh 77—œœœ[Þ'îV`îܹìÞ½»Û‹A[Qèáé‰Ç L1$—Ë™ûðcÂÃ%B›EéO?Q}â9ß}Gm~~ç—ÒÃÌW_%ùÁ/YVþºuoÛFŽM¤RGüzö$iæLëoƒFÃþ7ßì$ð j5šº:ÄN„ŸÌAø\mÜ3‘HL`D Æ."¦^O<@©pÃh @oÐß´ûï¥v+¦¥¥…W_ý3C† Äd2óý÷[X³ækqQË;ï|ȬYÓHKKåÛoÿCYY"øùù’™™AII)#GgóæmôîÝ‹­[wÐÐЈH$b„±rî\­­­ô——ëÖm¢¦¦–{îIrr’p3® àÈ‘#ÖßGŽ!.Î2¢òÃ?PTTÄ„ ?~<ï¼óŽ5x‡€…°ð0^¹gŸ~ú)aaa<ØÖFÚºu+‡ê–ç\{±ŠÓÇ 7ÿ:R_{"CA(ðËÓx{®Ëa¤¬?ýé’‚ðð;ïðãâŘÚrˆœˆ6€Ö²2ÊwìpZ†£ø“ÛLw…0aŸ4û²ÅÌ&/æã)×[­nÁà޾¥7·›ôºš¡ê|£ð° \1nnJ22Òyûí3Ë—¿g—TÀßßéÓ'¡Óé¬õÜܹ³ äÍ7ß%&&Š 63räprsó¹çž‘lß¾›´´~455søðQ{"—Ë3f{öì§ÿ† ÌâÅ‹„›p;v,GµæÊÝ´i“Õ7«µ-zxvv6gÏžµšŽvgÜÝ=ˆˆˆ¶›§Tv®¢¼‚uë-âùïÿ»Ý2Ñ-–çêM¯×¡V7 /ÐuÄpA(€Q§³¦„º¹!‘Ë]®+÷ð uþ|Ž}ü±ë‡ª 3 æŠ v¿öG?øÀNÚ +V|EfæáF\'BCC¹ÿ~‹_fJJ )))wü5Q«›1LH$–VJcc&S×ÂI«³¤äP*•477S[[‹H$"2²#F£A,ÛuŽt4 õxyz¡ts»ÅGFï<Ax‡S²c§W­B$c6™Øùûß³ï7è1qbg!f0pæ›o\–å†ÔÍ “^OõÉ“È=<ðŽ‰±.—(,ÈÎfÅСԶE(Hyì1’x€}ÿ;'V¬‚0 OëtHZS–/¿å®iuõE¨®îÈk`]f{f---455ãííRyuš›Õ¨Õj|}}ËåÖýÚïÓFØ›ÍTUU#—Ë…וää^Öéþý{·Mì¼ |}}˜?¿#7­ŸŸoÇ÷ %ÙétŸ>Iôé“dS§úwÚ·D"¶+W@àFQ[[Gpp ƒžêê‹øûwmÁÓÔØÄêÕ«™9s&~ø!ÁÁÁF?~<­­­¼öÚkÌš5‹v«kU__g6j¹œ+-!"2 ±X|Ýö£ÕjÑé´xzz ¨ ¬/FCÕ6i\¡ôõe²eœýáëh¡¦¾žS_}åt”Nâ0Ïvt®úøq6<ÖåIH˜s Ïðp;Aøó_ÿÊÏý«UŠlÊngÀÂ…ÄOžLü¤I·ì5oõ;}:‡»ïÎdÇŽÝøøxƒV«£ªª¥Ra¬×ÒÒÂùó•èõzÔêÂÃC¯8ê^SS3k×ndàÀþœ>¾¼öêñÀC —+øfå—hµZzÄ÷`ÕÊ/è™H‹Z·/öý̤©Ó1™Lm–ä¦ë‘ÉdÄÄÆ±vÍjêëëè™ÐËZFDd"‘¥RÉšoW±`á"Þ^úwe åÂù ÜÜTH¥RŒFÍÍõlÚ¸žÃ÷ß3±XÂÁýûxôñ'A(pkšžÎ‚cÇX=cõNòuå£g+òl×mèâ8Bh+âÚ»Ð÷ᇩÉÉ¡xûvDmbR„ë”޾€íÓîAA·…ÌÏ/ÀÃä¤D—ëœ>‹Ba9oZZZ9~ü$ÞÞ^WôAqEbbxQÑ1ÖrR ÄÓÓ‹ÞÉ×"™LƤ©Óñõõ£®¶–Ï>ýˆ¡™w°ï{q®´©LFB¯$”J7¼¼½™0i (Jþ“óé) IDATýÝ7œ//§µ¥…ðˆHÜÝ=ˆŒŠF&“³g÷®nuAø  ¾p¼u묿¼ù&F›û€E‹òë_;ÝV[_Ï7ß´úÙÙ=z4aƒÐPRÂ鯾¢±-€‹H,&uÁtMMœZ¹Ò*¶\‰B‘ AèJĵÿ‰Ûþ×°ö¬ÛI]”ÓÔ6B¨ctÐÚü|ôj5²[<Êôé“1V¿¼ÔÔçûÔÔ¼½½hhhDVÑJkk+îîîÖˆyWBPP€¹J``€Czhh0*•Ål×ÛÛbW¯R©P(H¥R<==„ò6äÔW_±nÞ<Ìm ”€¤$A \D" …\!t%íÔ•Eß,¯¨ 99™˜˜V­ZEII cÆŒaàÀDFF"—˯KÇð­„¿55},KŠ‹ˆŠ‰@¯×S[Sƒ¯¯ÍêfÈ9sŠO>X†X,¦o¿TÔêfêjj˜0y ååeü°q=r¹ƒÑÀ‚§áããC~^..{‡i3fY÷%‹ñ :&–åY"܇…‡ãëëÇö­?ffιßîø¼¼¼¨®¬Ä××ÏÚŠDÚýä“ ¬¬,²²²¸xñâMÙ_ÝÙ³lzê)—Ëwþîw„gd™i17<ô¯‘õÚk˜M&LF#Ú†§ÛÕü1Ùmé :™šLä®^ÙdrjÚ.èD6®ýÏq„g²ìSGˆm~‹öerƒ¦.ª×ò}ûx;"‚ˆÌL¢†·ˆš  Ryä–zŽsmµ 0Ûiooo»u”JÅU“œš˜Úî×Ùo‘Hô‹“ùð鯯gïÞ½LžˆÅbLF­–Ýü#­55V¡åt%4=ûøm]ïÆÇwZ¯}Z_ké]‘;ˆ3è•3;A± áh+ÞRŸ~šË—cjmEÚ¶ÄɶF:(B×#íûÔÖ×S°a6Xz肃©+(°ìÿñÇQ"S©à‡1¨8á¦<›êæB£ûP_ßHUåM2ß1s]#Ù2þ|…Ä÷ׂD¡ÀM¡àî?ýéòn©ÉÄ©/¿d÷k¯ÑP\ ÀÀçŸGáåeµF(ˆ¥Â'A@@@@àúV«áD¶%c\|<îîöÖI*•»Õ `hæp¼½;:®Åb1¾¾~vÛØ.oÇã£\Çs‰DbWƬûäƒwߦ¥¥…»îi§¶(J ¥Óór\W„]r.+‹3ß|ƒQ§ãèûïw\x…°0KÏÑàÁÄŽË€… ©+(`ë /³Ë³›6Y…8OÒ~áàAÞj‹ÔäL\ÙŽþ9úŠÊ9AGyå8’'N¼÷ⶇIâ (·3´ C£“²º„„Re%{þügëÿþO=EÜØ±D †{pð R„b¢ÝÜÆ¿DŠÉ/ó5$ˆ½RÛ:/®ÿ¹XF²„üC7—#ï½ÇægŸµ›w`éRv¿ö=&LÀ7>žÁ/½„w›o‹€€3L&--­Â…èƒÞ`Öéuèt:»«ææf«€©««Ãd2áïß=ƒ¼)Júö»ü(ªƒ3†Þðc‰D<õÌóƒ*›ƒ*0д4ö´¥UhÇ- €a¿ÿ=±cÇbÒëÙû·¿Q¾oeYYÔ=k'ØDN’£€³Tffkê)vXÏq¤Îvvq'q(£}[SÛ2iÛŸ û‘A[sP£Í´+QÇß^QQ ýÝï9ôÂh8òÞ{4••¡kn¶Î?úþû}ÿ}dîîôš5‹A‹|Ã8›Í&«r:™‡Þ(›)‚1ëjñò¼9½Qf3”U /ï5òý“OZƒ¾´“ùê«øöèqÓÅ=$¤Ëå¡¡ÔQ_TDê‚Â͸DC×È… õ…裡ó¡¡o¾ù†Y³f¡T*©­­åÑGeݺuäçç³}ûvÄb1C‡%99¹[œyium–iׇÊóçˆ á­ÄŽW^¡&7×nÞ€§Ÿ&nìX»yõEEäþç?ø%$ÐP\Lpÿþôš5 ¿øx<#"ØöòËlØ€É`p*»2×´rbœò9Š,‘C9&‡yíB²}[©ƒ@”aï(±ù³õ4z,#‚f'瀑ÙI •–rzåJ¦~ñ^vËÒŸžò½{Ù÷÷¿ÓÔ8 bÿ~ôj5'V¬ iÖ¬ë.Á”Åßßïæ4¼ š´Üò›¶O³ÙLë©á%¿J6?û,Mååä¯_Ùh”¡¡¸˜Q¯¿n þt¹Ô=Kk›³›¿?¾ññW´}ÔÝwã—`—ÿ³ç”)ôk3á îß_¸lä qq¡Â…è½Þ@ΙB äÌ™3DDD°aÆ @MM áááH¥RjÚ܃ºžÞ>DÆ$të{¼{Û†Þ=þ¦™Q7ß8wA^üío9²lZ?¨š3gð·ãßT^Nm›p”*•ÈÜÝ‘»»#swGSWGDF6Ø™zºƒŽ]\ âDvjôÛBpžf¢};£Hl…íÿåØ"¶—ep"Í"Õää¸GCKwíbͬYÖ£Ñ#GÞ–ì>¸f~÷Ýú%Û·[§ƒRRºí3XSSËáÃÇ;¶s®É¿ýíMâãã˜9sªKÁWZZFtt¤ð2ßßÒBÍ™3Ä`ûó¼ë÷¿gΆ H.‘s²dÇŠ·n¥lß>.ž:…ºÒ2jëL@r2ƒ/&°O|bc]–Q¼u+…?þȹŸ~¢6/´4¿ø"!!xFFâ׳§pÃn"ÿû¿ÿ˘1cÈÊÊ¢´´™L†V«Å`0t ññ(l*ψŒ Òž}ÿÄ_57«©¯o@¡#‘Hðóó¥  ­V‡T*!1±'¹¹ù$&ZÜíÓ99ù zë(c»ŽJ冷·¹¹ùìÝ{€ŒŒAÖmmÉË+àøñSrþ|%µµulßþãÇÁÃÃ_ýj!Ë–}Òуµûg*+«‰‰‰bàÀþ|÷Ý:Ö¯ÿ˜Éøñc¨®¾È®]{˜4iÜ5E=€IŸ|‚ºªŠ¦sç(Þ¾Š(ß·¦²2жnåÓAƒˆºûnbÇŒ¡çTçÂ}õŒN# «++QWVR²};÷®^íR~5f %Û·Û¥%é7>É>(Ü$›L}}= ÌŸ?­V‹J¥B©TrúôiF…L&cÆ dddt³ó®ë4Ï’bÃ]x(n!Ax´÷ªOHK³Î3›LÔ=ër› ‡Quü8yë×sñÔ©N œ›ƒ:N;KÍCmÅ¢‘Ž»öeŽ£†¶~}íæ¡¶"‡ùâ¶õ5Ø6:ûk‰¶¦©'BXäpŽ`Ÿ£Ðñú4ØÍ»pø0=&L¸)‚P¡sæL.™™C(--G"‘PPPHzú´Z-ÇŽ° äÈ‘lÂÂB‘ɤù‚E‹^òkÄ=(÷  BÚêˆâmÛøjÌëòªãÇ©:~œ“_|Á‹.|,æ>l%<½jU§åდxï½?¾EE”ìØAÅþývb ïßÿ&mÑ"á ÜDÊ+*HLL$Ö¦¯²²’   î»ï>¾þúk sçÎíVçm6›imiÁÏ!aA~.É}®ÞŠkó¦ôMI%ÌÁ*ïVàÔ‰ã$÷í8·U+¿ ¹O_úôíÀÎí[1™LŒ3V„Ý‘XìÔüª*;›âíÛ)ظ‘âmÛì_‡i¹‡©OxŽc\ :ú-ÚŽ,Jþ;–k-´=pŒ™®SK8 M±ƒ@5Û”åX¾ÙÉy;ú!Þ¬äÜ2™ ÜÜ܈‰‰D*•âííMNN>z½ot:=«V­Áh41v¬%¤qnn>r¹oo/ KZww±±1ÈdR<<Üñõõí2O`Ïž=ððpgË–œ=[Äwß­ >>®ÓºZ­–Í›·qöl­­”J9=zÄàOLL”E$äå£Ñh¬"Qàú⟘ˆwt4 %ö¾™aéé.·ñíÑß=è5k•ÙÙÔäätt0ôíKøÐŽ(l›Ÿ{Žœo¾À ÕºÌUZúÓOl|üq&µå+¸5i*+ãÌ·ß^ú»ãbޙᆪ6?ÿº“àå—…›# p„‡…‘êÓ`b[{E.—óðÃßçQ\\B£Í÷¥ºªšÈ¨ˆ.·‘H¥R@˜Œ&›vІ£‡qäðAÂÂ"˜>s6y¹9lÝb‰²¿è¹hnjâ³å0}æš›š0ô9tÓÙöãfrsNÔi3~‘ë³å‡ïÙ°ößüß{°üã¸gÜDNŸ:f8¾‚€€@Äb1›¿ßÀ¸‰·N>fAÞ`Œ:Ú†Îee¹ô <˜è‘#‘{z2ø¥—:Ääñã_¾Ü鈠ÙAðÙ %gAflGE˜ØIƒÂÖüÓäÐø°5Smm›eÎ|m÷i›¢Bêp¬íe‚}nD“‹ëÛ>_"—ž‘É`pê»%’HnX޵öŠîðᣤ¤ôA¡PšjI@;sæ4Ë‹&•PZZ†ÙlF«ÕvJok¦¹oßššš% À¿“]²d)MMÍ$%%™9„ÂÂbF¾€¥Kßeß¾CŒu7aa!ÄÅÅ0hÐ<==1´¶jX²d)Ó§O"33ƒÒÒ2»2®/ž,ÌËÃl²’/ç™TúøðÄñã˜lžk±D‚X&³þ¾çŸÿ$bÈ ·láôªU.ëŸ˜âÆ»#﫺áZ¨Ìζ¦ºᦩ«ãˆMú!g뉰XœØF¨¹XÏYG¡è2¶¹œE•¸siiQ#—)ìRgÄÄDc4][½ÚÚÒÊŠO>âÍw–±ï^ìßËî];xb¡%UÒÿ-}ƒgõ=b±^úøýw‰ŠŽáè‘C|÷Í× ÎÊ… ç9_QÁCz„!ÃH0¥R‰¯Ÿ/Ÿ/ÿ­FÃýsoþˆ«——É}SØòÃ÷·å3*Â[ÏÈHËËi©ªÂÍÏ¥Ÿó´ EE˜ŒÆN¾wžHÛrøijkÑÔÖÚ5M:M©“ƃ˜K›mb#(Á>àŒ­¯¡ÁfŸ¸XÇvÔVh¶ÿnßÇñ>êR·ûlìýÛߘõŸÿ0mšð  Üb4ž;‡Q«íhL©Õ|ûm—¢¦âÀªNœp)ÎD¼K–¹Z.ÂuX‘ñçJø¹‚bœûT;Ëë̯ÚUŠWþé¢+WÔ°(‘H~ùæEKk ‰0¶Ù‘Ë<‰~Ùc0›Í´´6#•^ú@êêê¬y—-[†§§'&“‰ØØXbccÙ¼y3 …‚iÓ¦Эî•V£¡É!*¿ÉÁZæè‘C,}c 2™Œû|ˆÑ÷Œç\©ÅÅbÀÀtöîÑ’—›ƒT&#$$ <µˆººZ¾þò3îŸû0%ÅÅè´Zä J¥ò¦Ÿ§Á` ´¤˜ÚÚ ÏEpH¹9g8›ŸÇð£¸p¾‚Ÿ³v#‹H&Â[¬¬,²²²¸Ø–çëVaöÚµÔqáðaz÷& wo§ëå¯_ÏÉ/¾àL›Q;þ VYsæ Z‡à"%±ÍŸ³^d®ƒÈ˜ðpîyóMÀ’¢£¾°Ð®Qbëo(ÂyPG%ó4r:UÚ¶¼RÉÔÏ?ºößrÝPq¾²–²Šê›ò h4Z£{ÓØTÏ… §oÖW¥›J¨® ޱû]_Xè4HŽm]S´m›Õ:•Ès&öD\z´‡Ž¬Ë=]¦`tìR&œâK³ÙEÝkîâ\.UoŠº¶ŽÇq%c©•ê—o^9r†ä>‰ÂKØ Q(äHe¿¬Ø×juä˧wò¥}àôéÓh4/^LQQëÖ­ãСCÌ™3‡úúzTªîõí‰DHe2jjìÛ×áöi¯†fç±OYϺï»åÃ2É–Ù©ü°ðkpšEÏ-þEÏU§Óq"ûÓs"û<8ïQ¾_¿–ø„D{‘Ø+‰ý{÷`2™9úAÞjdff’™™I~~>»víºnåV8€^­¶|ì¥R"ïºëŠËð‰í2ÏXLû'&ÒR]¡µ•ò}û(vHoá¬¡àØ€qÖh»h”8k˜˜M}=Ç>üÐzñ¢ÓHª›}Û–Ñnêè‹h[†_b"aa—uý|ãâHš3§£‰„˜Ñ£¯¡vƒˆëxE®P!—5"i.UÍ@ 7Ðu~"£)„Öõu1ùÔê BÅ àRà9­Ñ56rèÝw ¤¢-[ìæ‰gï¹ ×&®ê0œ23]Gpî*0×¥FÕ›f'ËÍ—Wµ\ÒÇÏñ\TÁÁô;—ãÆaÔéØ÷ϺÜ6ã7¿A$v>æWqð`§ gëUÂã/ pÍôêÕ‹%K–àïo‰P[[Ë¡C‡ðññáË/¿ä ‡à‚·;¡¡]·×<<<;aÒmž*•Ši÷Îê4â{K´ÁÃnÉãáu 6/‹gÎÐRUEv[¿ª'з´XA ñ“&1kíÚr ~ ÌݾƒFCev6%%ìÿÇ?¨8pÀ®1"S©ˆ½ÇÒ+á׳'½fYÞ²Ÿfë‹/Zl®FM.&v¢Q­æÜ–-Öíd#“‹“­9¨ ðŠŠ¢O[Î4Ÿ¸8SR0étxóMšËËíÎ?xÀâÆ# wïšlÛl6£WWàçç{Må´´´rá| q?"ÿíš«´¤î;0¨[ñ÷÷¹æsÌË)º!×oÙ²eÔ×׳gϦºÈ¿'`ó¾éõ|ïÜÁ/>ž€ää+ê j>ïÚ ,4=O›Ž–úÂB«¦-;_yÅ.â©Ø…PjŸ–]Bø‰ºr¸z—k K ÿ¤¤Nå¥.X€*0°KAXyô(gøÁéò€¤$¦OçÀ[oah«çmIyôQƶÎt QèL ŠÄbú<ôËõzN™bíøºR¦Û3ëŠéNê“EÔÝ·_àU«Ö0q¢%ßÖÞ½ÒêÔé°3‹ššZòóÏZ·¸t:ë×obñâER_ßÀ˜1#ìÖ‘H$¸¹¹ñóÏû™={ú =žòŠ âã㉋‹#;;›M›6Ñ»wo¦NJBB‚UNž<¹Û܃üœä9Ù­Ÿ³Ö–fþýÍLj¸9­--MÄF†‚ðV úäI¾9’ÖËð7ñ—¿اÏ/v¬rOO’æÌ±šLêÕjv¼ò {þügkŽ*g>,b' /“CÃÍ·gOäîîœ^µªS︳èvf ®°ue¥5LW>G¬üõë1¶‰”Ðôt§àÌ·ßZówE ÖI¾KSYY§íd*­Ï<ó‹?_GŽÀ–-àïO<«WÃÁƒð7›AÄÇ!-Mx»;C_y…=ý«ëQM -—¨‡Êöìá›É“ѫՂB9ú¬iÊËÑ´¼·¯#çòR¸seQà¸Ü–Ä3ˆ=š„——GJ—mB.póÑë $%uøñíØ±›ýû–ÇÓ§Ûw”^¸PIqq >:— 6sòäivîÜóÏ>F£áË/¿eÆŒÉ|ðÁrúôéZ­fôè»ñòòdùò¯xòÉG… /ÀîÝ{‘J¥”––1vì(V®\MIÉ9F޼‹ÁƒÒ£G,GŽd°yóvvïþw ¹]Äïk%<,ŒЯ_?úõëˆ:žÀ+¯¼Òí®l^$õØ­Ÿ±¯ú˜q“ç “ÉoÊþöîþñ†•-Â+$ woæíÚÅî×^#ç»ïºÌkµ|ð`Bä®?þ‘è‘#oø±™ÍfÎnÜHáæÍ_¾ÜåzÆiBWBÎ6hAû:Ç?øÀ.¯ ‚ŽQÛrì‚ 45¡mjBJG”QÇ¥+󳂭#—KÓ¹sìùË_ìæ9ššZ---rÄ]%%çX¹Ò"NŸyæ ²³OrèÐQ㉎ŽÄÃóg Ù¿ÿ0ýû§0n\×þ‹?þ¿ý-ìÞmù=kt,ë-Ø´ &O†g/‘¢¦¦–?´¤ xøáû©©©%::Š>XÎ]we0xð@þýï äææǬYBÄÕÍñåËij{‡üú×]¦¢ØüÜs®;žD"Db16Éém©:—#G²ÑétlÙ²ƒÄD‹‰õÖ­;<Ø^¬h4fÏžN¿~}ÚžMk2*wÏn}Ž"‘•Ê™\~Ó®© o•›/л73Ú¢äyï=tMMÿÿŠÀädâ'Mº)M]»þð; ìSR©R‰®¾Þ*¼œå®rÕ°³lb:r ʰ÷7Ħ!it˜6»ø³ÎF$r9QÇ[}]±éRk¨z½ZMCi)»þðç÷Q"±3Ð^E ëððPžzê1Þ~û}Äb1O<ñkÖ¬';û$ƒ8vì$¯¼òï¼ó!C‡ÂÓÓyyô(ìÜ R)¼ô’óýýêWóÐg/ŽåË¿²ÛéÓ9 6„Ù³aåÊù׿> ÀƒÁÀ+¯¼@AA!55µøûû /ù "ûãÙõßÿMsE` ¸;náƒwZ÷‘#´ÖÔØ‰9[&,[FêOØåƒr¬§ÌF£Ýöî¡¡ |öYÄm9®öüéOèš›¦p½Oœ9“°Aƒ:­—¾xñ5åW¸=ÈÊÊê&q3 õ IDATþr‹ÅÔÕÕóè£sY±â+D"9uu–ï«|kS¦ŒgÞ¼ûÙ¼y[[£K„Édæ§Ÿö¢T*¬u[YY}ôr¹œÆÆFŽÍn–€…Bއ‡;*•:ޤ¤žxâ||¼1›Í466ÒܬF¯·tQïÝ{€¨¨ˆšW«ÕÒÒÒ‚H$ÂÇÇ£ÑHc[Z///$ݨCÌl6Syá|§€Vr™_'©Ô Ë}hmiÁh4¢T*Qº¹ óÍ›Â%¸6<ý´u:ó¿ÿû¦í× ÑPºk¹ÿþ·¥±ùÑG˜º­L}â úÍŸÏÇýû[…«ÆŸm”¼vñ×.ø$6ó“Ê·oÛ.þ 6¶áÑmËîJ€¶/ëÿ䓌u’ƒÌ‘!¿ùuúÇÅ‹9öÁè[[®–žÎ#{÷ÚÍ»gîÏ>û½^Os³šæf5^^Å^RÒåE%íßFŒ€_¼ôºF£Ezx¸^göìé|óåùP©Ü6lii©H¥R/^ÄÙ³cÂÂB‘É„êàFâBòóÝwè9ðæ›:‘pè ¹j›žzŠò½{‘(ôœ<ÙÎ<]áåEÿ'ŸDS_OÙž=4Ÿ?OÙÞ½x†‡[:[ŒFëûj‹Gh(!iiô´ñe‰>œ€¤$á&Þ¡b,Ѹ:tÅÛϘ1ÙZ-^¼ˆæf5_~iI‘4wîœNëûøx[Gnz÷î…››’©S'Å™3yLž<ŽúúV­ZCxx>ú ={öàÛoÿCBB¼pÃÉdŒmñ¹ŽŽ$$$˜=b­ÏâãÏÃ`0pà€%-Î… éÐÐ`¾ùæßü ¯'ï½÷nnn˜L&©®®¦¾­³^¥R1oÞ¼nu/Ä AAÁvóNds*ìÛ‹D"æó埖>FÃ܇ÅËËû¶<÷æ¦&–ü"‘ˆg~õ"z½žï¾ù“ÉĬû@î¤C5/ç ׯeò´ôLH¤©±OO—À‚ ¼i(.æð{ïÑxîœ}‰‡C^z ¿Ä‹ÖÚZ«Ï›mrfõ… ”ìØá´ñèhö pèí·9ôöÛNS@ˆ/Ñ •ØüIm„`ûŸ­tLÑ.þ9¦»p:,ÑÿóàƒD JÔðá ‡ØXä£míÉçûÍŸo|<û^½Óun?¶u>h'~u—HïáŒÐв³OàîîNxx(nnJ<<<5j8»vYR;wfqìØ <==P*»îé ²ÿ½z5œ> k×´6‹N__øç?-æ¤] Âsçʬ=ñññqmåwDY âüùJ–,YŠ››=ö ²hŽÐ]9úþû”\AºšðŒ jóòhmË êl¤Þ•´}gN,_ný}ôý÷]Œm¦ 7lpº¬ý½1‚{W¯Æ­-º€ ÛÅàÕšêÙ³‡]´Pw«å‚ÓŽw•UØEFZ:/üÛ:ÍR¬¢Ñ¶ŒÂÂb.^¼HUUu'ŸD;‰DBß¾–(̶ÑEmŸ›ÿÏÞy‡GQ®ýÿ3[Ò ¤ABÐ{‘ŽJ‘Ðì(‚"ŽŠÇŠåO{_þŽx,ØÇ‚å€+r@D:HïÒÛ&Ûæ÷ÇÌì>;;Pö¾®¹vwvú<åþÞå{[,Ÿß99¹´iÓúg±áþÑê=z”/¿ü’Ñ£GÓµkW6oÞLmmíE÷®\.‹?ÿŒ‚cù˜L& J|B&/÷0…ÇŸ·€ðƒ¹osÏ}xr -ø”ËGŒD2™X´à¦L½ÍgûÂÂlÛ¶…™ÏbþGïË'ó>â™áïIœ nÙÂþ <ÅÖR‡ ¡çm·˜6×írq|ò¿ù†=~H]‰E§æ8m6Oát€ƒ‹ó®&)„¨0ʧ‰F@Ì(ìS¬èÆ?÷¼Þ@-'Щ®s QÌCÄà“׬­;¬ÒîïÿäŸûMéߟˆÄDŸý²ÕmÅc›`«ÔÊM›¨Vë5j Õ(N³ 7î Æ»Âo}FF;22Ú±zõz®¹f<ƒ8­ãݡӓn¸AYD9©¤G†ÄСƒ|ÖÝyç­>ŠÙƒÞìØ¿vr¯¨ ìÀŠwîlr»S&—uà0ÐЯ7¬ô1ƒW]EÞŠlž3dz¯>7ØÈà¢ò§?Á`PüÀàï]ÒÓÛòøã_ZP~•Œqé99Æ*Ú¼¹R¾Jƒ#G޼èž{Mu5µµ5*úPBF/ ººŠ¨èó#±±±‘í[7{~÷êÓ—‚ü|þõú+ ä)S)ûÕoÙ‚MfS„ߢ7ӂ˜hUí»E['Á§g¡ÍôîÝ“I vžßÔ•”P¸e‹ç·Éb!}̘&÷)Ý·Ê#GüÖ·=Ú“;—1~<–°0¾OîdƒmM 9²®ä._Îɽ{)ۿ߇ITÂØûïæôÊ:%)´7:(,,øÍÞ|™¨”—WPS[ñ›^ƒ–wøsåzµô×þýûÉÉÉaóæÍÔÔÔ0jÔ¨à‹Ug¥ä”VdŽO^îa¶lÞD«ÔÖçÅÕyñþøÀLl6ŸÎÿèw}íA@ø3$$*Šnj¡tb˜™IÏÛn;徇¾üÒo_MÚ_y%ݦLñüÞÿé§løÇ?(ÏÉÁi³5 JS€Pï]4Œr€ÿÄck`Mô:…õ2ŠGµí¨Qlzáʳ³©+,ôÉ?AY¾,¥bª{ï^ê÷à,‹Y=ŽE½Îá?«°ˆ¡¯žVÉþzªÎ^t²†ü‚²_Õ–\n7‰-ÛRQÕ‰ƒnþõ–);tKЦ¬ø$'²~õp{aˬæ,Pò•kj¨Àd21ôÏ沿ÿݳ®*?ŸU>¶v->ÿ[™ÿ»NèÒÅCÎR]P@C…W1Iêуö&P°~=ùk×dðlªOõGQ´¾íªss©ÍÍEÂ[&ÂÈÓ/opìõÿøõ'OÒþÊ+ýH—‚ƒ§+NWÃïâ^:wæ^¨ò{hcV«…ŒŒ6§µíñ'˜={6wÜqEEE,]º”Î;síµ×òÁPTTÄ–-[èÔ©×fÉó¼—•R«ÖÀõ^³è˜¢¢¢™óülZ´lI|B"22sžŸM»ô ®xãyqŸ¡¡¡ â;n¦¦¥ñå¢8NÚwèHJ«TþóR·pìxož~æð!,_µ6mÛ±kÇv~ö1 ‘Ú:nÝ{àr¹Î:ÙPþ ‰lÑ‚kæÏÿEûíW‘“CÞŠ¬{ê)V=ù¤g½­¤‡ Íà |C1ݧwÚ6bx¨Ù@i•E“˜,ÂqÝ`Ð¥‚ž_[ËŠGñÜG¨Ê"€pu‰¢€0u›0U±5I ™ÔER~k‹0É`r$ƒäö†·º· x=— Âõ:u×îr+Ûž;[ÎP×)Ré7 éúCNw:Õ•õ¸\M_¡½ÁEtlÑg̹܆W3")‰’={ ÿës÷ݸ^ oþêÕ,¾á†&kûuž8‘ˆÄDJvï¦@¥á7éúhÙž=”©ç4ÊŸÕ‡u‹^r}ɱo†·lIrß¾ä|÷§\2ØW#ÜöêÇ€üU«È_µŠ¨”Ìj>é?ý‰>wßœ‚`ð´Ål–ˆ‹k| A9kJxxèys½­RR<µ[´háS‡ðöÛo¿`ß“$I´iÛ—Ë7A¡U«Ta¼0sãd_Ãø#?yAÜÿíÓ廉¼“ÉäñrÆÇ' #“˜è%xÞgPyÍõ).*¢EËdBBBÈwnò¢/j@¸k×.–.]êUÏO£Øü¯•ïî¾›,µpºËáÀ©ÖLÒ{¬øçÚé‹Ãc H"–‘(è¶3Z§}Š¥#D`¥Á¶#Grý¢E|=u*¹K–xÀgˆº„©K” #ÔïáÔ‹ f¾É‹€Kö‚¼z °Ë à«SŸMøOÏvª³ÚýVð‡ä&Üò°öœ´ÑÂB¨i\NDHKZµ87^;Y–Y»qïyÛ¯‹¶o'ï{¥xëa¡kÒëÎ;õâ‹„5ó*¬-"ç»ï<`Ð\âALéßßCôd”Ïè»4ªªß^cãµ—–R°fO´Qȵ۠­» Îmµm´Ò 0öþøÄD¶hAÏ;î ®}{:MœÔH/@0(Ë2—^ziða%(A9ƒà=⢽÷¨¨h¢¢|s Tî €,„Ć„„Ò:­Í9¿Ö‹öêÕËÇJ“ÍêŸÁØ”8êëýŠÖg-\ÈÎwßE’eB¦/æˆF$p]§LÁÕÐÀÁ/¾è%(F…ã5À§ßæçø‰Rú÷ç§çŸÇVVÆaÕ‹¡…kŠ`0T½VP«.â}J:eWRoZ,e¡Q‡îw£°Þ®®—,¬áá8ìvœjBñ™ö¸ãꊊ8}s€C…œÆÒØN'DFz×ÕÕAD„âéüyà Ün’$³ÚD²,ãvŸÙeŸdfR°~½RjD¨!Õáê«IîדÅBiÓ‰‰A’$þsé¥/Ÿ,Ëž~iÔo´'_²e %j¢Y´¶ëÂ7ç¶©>¨ïÖ{Åž§©¶–0¼9¸â1D/¿rí$0ïg" ÃdÀ0ë²ÛqÚl8m6*+ùqÖ,$$I¢ß}÷‘ž™IÚðá„4Ew”ß½Øív6oÞÌ#§Só&(A JPNCÜ.7‡ý¾IYVîñUÉ.÷Y;v0dô,Èöý‹uO?M­ŽAHüL§€Š·›€ƒ*ã¦Õ@¹”ñõ h!›V|É\Ð)"ƒ¨`[W€ë2Ÿ{γ¯˜Û'æïi s=^€gWáU£ú]_ûP¯ìzäÐP$YÆ.ß³)$„ˆÄDFÌžM÷©S)Ú¾…×^‹ìvÓPQ£¾žˆ„ò–/Wž­PÇí×ÈÖ­ðÖ[ Åòõ×pÕUM—‰ŠÁ„âtRW\ìouKIñKÞ¾fþ|JöìaãsÏ‘·|9’ÉDTr2EÛ¶Ñ~ÂJvïæÛéÓ=ïÛ¨OêÛ›ø[ßo³åï¹›ØN_×S<‡ÞmÆ?gVÒõw½áÈÅéÇ´Ÿ0±o¾I„®îIáÖ­]µŠŸ^|‘º¢"Ï(˲§”MX³fë×S™›K»ÌL"[(SIaz#:Ö ¥ÙÙ°{7h„–_}¥•?rFŒ€ý9ׯßÄÚµ¸ãŽ©dgçн{WBCCY¿~ÍšÅrèÐaòóÑ©S®»îÊߤÿ¼õÖ[TVV²~ýz®¾úêS‚Á#+Vðé¸q~ÿݹu+–pßšŽ_Ýr‹§ôC«ÁƒÉ;–aû›2h—”P°aƒñ÷¤K§èsR€uÒi€AY÷;Ðö"ðûªI0æèóµ~iÇ¿„„`åSìE‹(=p€ëÕpv€¸ŽI¾ä’/¹„¾3fpè‹/<ÿÜ·ìo¾ð«”óGª««ùüóÏ™>}ú9‹@JP‚r~JHH(­[§ùÌ%0ܾS·Þôê7ì‚~&¿ÿ*7Þ2«Aù³!«øæ¬;ÏÚ§žâä޽؅¢{>úˆÁOwßMŸ{î¡êÈÞh×ΰ–£&ֈϚEê!†ÿ§JêСç¤ÍtèݺA}=ÄÅ)àðÖ[aòd˜=ûÌÂ/¿\Âĉ Àzï½ÿðè£÷ñé§‹±XÌdfŽdݺÄÄD3kÖLfÏžó›õŸ3f¨VµúSnk¯©aíSO‘Ô£‡1ÌÜK.irßã7R¸u+EÛ¶yÖS 3¤&À×ÄÔoç`|iŠ 8Ç_[ÄœV1Tdà5O:íÄ×+hÂ7<˜•Òýûy»[7Ϻô1c°„†b §ÿÃÓ¼CïDà Œ8C” ü6RUUÅW_}ÅäÉ“ > %(MŠËåÄd’°X¼Æ£‚cùÁsHþL‰ëØ‘Û6näû‡¦,+‹êü|J”ÉÏ=g¸Ÿà»NzMŸ€­¬Œ-sæ`+/§d÷n?OŸ‘BTReÀdµ"›L>Ì¢.ݧ[ÀD@hÑKd+tP‚Eð§)¯Z˜¨èÕД^»N‰µãe15zN}”ðøxr—-3 !ôóðHÅ;vØ­¹Ë–Óº5 ]»þ.ÚÕ mÛžÙcºÝn”üÈ›o¾I’0™$dOASq?$¬ysnÛ¸{M …°+Úº•¼+šÞY–É]¾œC_íÍÚ—a×óó1_FžGñ3ë§Èâ«õ³`8Ñ÷ ‘%×/Ñ“$\‹¾Þ¨Œ˜¬‘óȲežuû?ûÌçZ“û÷ç¦%Kˆ0HŽÊù¿ùæ®»î:"ÅdçÓ‡ÝÁ‰ÂÁ” 4  \ÜýTUU“‡,ËÔÖÖb·;0[LMLÅ2ÇÑyМ‡‘JÖýTWU2`Ð_u»wîÀívÓ»o¿` Âs#£_~€ú“'©.(Ài³±åå—9¾iÕÇŽùlß¹3I=z'ç»ï8ðùçPCµôÊk šd"HÁœ (ß·Ïع„}Å0PM5é@£‘ò©…„ZñÍKóÅ‚óÚþšáƒbiSŲ¿ºåÃç§÷thÊ­£®Ž½óæ±wÞ<"˜´d )œõ¶ñãPTsçÂwzCFssaÖ,èÜÙ»­øý×ÈÕWgãÆÍ\zé`6lØÌøñ™„‡‡±nÝ&Îcöì9´oŸ~^õµèhÚ îùÝføp>öXÀí?7ŽzÁ{,cL¢t:m ü=~¦>£>©7œè·1ë )¢ñ§HÖ&O¼a¡úEï}óxÅqÄÀ¨äÖ‰ú9ø–¬Ñž]db"¡Í‚eÎG©©©á«¯¾âºë®#ú†û:N¬–ˆàà JPš«âÛ¶Äír^0÷TSSM³f±˜Í&ŠŠŠ ÁyŠû %)©…Ϻ=»vú¨¨(>™÷ᯄGä±{׬V+‘‘‘tèÔùœ>›êêjÞû÷›rϽ÷³}ÛVŽåÅd2qյדžá_õ“yR\TÄÕ×^Ozû¬Yµ’m[6Óà †]6<ωHLôXÉS‡ ¡®¸Ø'”OGxœoÉ€üÕ«Y2}:®ÆÆ€ùL¢ÒÖT’¡UFrMª– LŽ$–°èM­”„V[Т nA‰u ”‚°ãïìtÍ5Ø**8ºfßùÓÇŽeèŸþDTJ EÛ¶‘»|9»Þ{/à³iJêKKÉZ¸ðœÂ#”E“àŸÿôþ¾öZãï¿F.¿|(—_î ½ôÒÁžï™™#ùâ‹o¸âŠtêtáj^þÏÔÔÔ`«¯cÌø«(=YÂÖÍ?гWoÚ´KgÉ×_â–Ýœ((àù—_ÿU÷ÃÌÇgQR\ÄêW’šÖ†Ã‡s¸á¦)lÝüÇ ŽùÂÅŸÊa—‘Ö¦-¯¼ôO®¹îÊÊJ™ùø,~ö Çòž³A@x†%²E I‰‘þî;òV¬`×ܹ4VUù)^2M{Ê‘R±: €¦¸ˆyI(ŠàKJ£å3…àË*²:ðÍkË@å8Y½w€°Šã7²èúë›|Þí23¹fþ|_ Öñã¼×»w°1 2~ü˜ó.dôgßãÛoS¼s'9ßNºî5}:IIXÃñª ±­¬Œ"b?…‘]Ÿ’u}*XÄhÉÓŽ½Ðh’Ö­€øz› Lº>+²’êKe˜ Æ ·áHûšJ×I“èwÿýìxûm?ã@×›n"ºU«‹®ÕÕÕqäȺ y˜¿'q8Ì;—?üá¿(gÐd2!™,|ñõ7÷Tu4Ÿ¬… úßÇ€Tà¸ú M§rpоk´_pì³%­$uØ/Ïw:í8>ëN–”’ŸÈO›7!™Bп/f³·lìù9y²³ÉB‹-/Êù´¸¸ˆøøfžwߨÐ@uu1±±DES‰wèÔ—ËqÞ­·…[,V’’Z I•UU$§¤ I& Ÿñ³äç3óñYÌy^ÉWŸùø,~Ú¸Þ¯È=@mm Î}‡ò²RzöîCjë4œN'®º†-“Ù²y+–-%Qm³+–/£[žÜ|ëm$$&ñìÓÿwÆ®}õª•=’GMu5£ÇŒcûÖ-ÔÕÕrùˆQ~ÛÖT×­–Â’Ý2‡ƒ«^kµZq8Î]› Â_j%ilDv»1Y,†õ»ôÒX]Íˉ‰¸Nd··1[BCÁ8þºE¯^dŒ‡Ébñ ““Ýn²>ÿœ¯§MóvYIÂ"Lô=§M#:%…M/¼€½¦Æ'|Íl&õD.bX›MÀQ µc\ ÞhÂm¬¬ô´Â=¸ìveih@ÖêÊ ÿ|ä.ý¿ÿÃdñmÆññ<ÑØHÖÂ…Tää(ϱwo2&L8c£Ä¡ÜÛ),~ÎÚZûNm©¯u³ië¡svÎĤ”ó®O†5kF›áÃ}ÂKOK‘/*¢pëV Hù3 #u€Dí»+˜Ôo«ý_Ôé¦b‡ôô¡§by 7Æu Õ)Ç­V¨Þ©Ï3®;~œí¯¿Îö×_Çépxê=Š÷öã¬YH’D‹>}<Ä4Cþô§3«¢¸\¸Ôr3›^|·:iFµlIÏÛoG2›1Ÿ#Ö7€Ñ£G³zõjdYæà…^ðäîþÄétòÚk¯ñÐCýb‹¾Ùlæÿý¿ü®ú|en.óXI•êI0…æÐP\v;ëe™¾êú¡º>f ERßWÛQ£èqë­ïPèò÷ΛGuA_ŸÕ÷ý ï¾Ë’¢"ž".^Lî²eìûøcO{5|¶ÂùO%ƒ‡ãÒÿýåÊkCC56›o™˜;öѽ[Oþñg0[£xô‘™„†…àr“•””qòd…_韋EiÑ"Ö£—44ØÉÉÉG’hò™lÚ´ö¼¾ï°ðp ‹½à¯ÞV£´_˯‡‡§ÓÝn'$$I’hh°©@ÔB§.]yöéÿ%9¹·Þ1Ýoÿ¨¨hn»ó.g"µušg}xDV«•!C/e˦L»ãÊú°0.ø”ÆÆFêëë9°oϯŸ—d·ÛÍ7ÝÌò¥K(**T€aMµt»Ý8NBBB0[Ì>¹¦&I­ͫ²|NûXþBYxýõmÛF¯;ïdø?šž$|òI«ªpÙí„ÆÆÒ}êTâÚ+nãžwÞIhLÌiŸ·¾¤„õÏ>Ku~>/ö6"‹…1o¼AŸ»ïöÚ{ö°kî\d·Û0QÆ?7HÌ'’ì£5]1'Qô º0øs¬¯ ÈîsÏ=´5ŠÄîÝÉ_³††òreà £¯ÊTØŒ+a ¡ÛÍ7Ÿ•wߦM2mÚÄŸÃÖ¶šCZëswÆ“e!M_ŽlÙ’Ñsæ°÷ã©Îϧï½÷ë¯|9ÂþO?ÅVZêãÕ‹‹£¯Ðïv¼ý6åå~ýGß—ô,¼Ðˆj´k2ð%œ 7Ö¨(,‘‘ÈN'¶²2¿¾êŒ2N]×{}Š Ó-ËȪbkÂ?¼T8+Ù½›ª#G‰Š:ã€0wÙ2>¿új¿è‚ÐØXÖ>õécÇrÕœ“öS__ÏêÕ«=–Ü9sæ0aÂFõ»hß6›wß}—‡~øwRÏ„4KOgÌ›oòÕÍ7ÓX]í7ÏÈÀ_|Á÷>ˆ5'»ÁÿS–/'¾S'Ö?ó _Üt¡±±ãcd‹Ô—–"»\C©®Z…»];œ„ª¹™'N¤Íˆôš>?ý„)üõ IDATï:eJ“‘E¿7IJŠ'))ž‹Y™Ï”©Ó Úe BC`ÿƒˆŒð†Æß6ý.æ8€nšÂ”©Óøà½·±76Ò÷’_ŸNT[[Ëûï¼…ËåÂd2ÑoÀ@þöäÿоCG¶oÝÂÈ+2éÕ§/»vlçõW^â½>fêmwòÎ[oP[SÙciß±‡dÎó³éÒ­íÒ3‚€ð÷.7-Yâkݨ«cù«óóç{¬ƒ—?ó —Üÿi£:?gC[^}§JÓßPUå5û¯ÑûŠåÃÙØÈ¦þ“üÕ«9òÃ~ ¥bx©KgM_/ ˜3(zEÏG o‚FFh:GR#ç8ºr%1iiD&&Òïþû‰mÓ†ðøßx’dBÍÏ?^ÀìÞù׋¦/‡ÇÇÓÿá‡éÿðçÜvôË/óÁÀœØ¼Ù³®¡¼œ B “A[º­/D/w_(9„)¨Ó×ÿìu×]ô1ƒŠÃ‡ùlüx·Ð„]BÑxS‹’ÿ‹®?KŒ8§2èÈ(Þ¹Á¸Õuòd.{ꩳòÎ2ƧíWP™—ç÷~2 êVž-9rä;v(¬v¢?~œC‡Ѷm[?v½s)555|öÙgÜ}÷ÝÔ¤ý„ L˜;—ÿÞ{/õºš´&àóñã•í€ù‚Elïó/¿Ü¯·ËÌdø3ÏJI–¯o½{m­Ÿ'^kÿ{çÍcðŸ%KHîÕK1œà;Ïß>]1æ~ðîÛ¿ú^£££yð‘Ç}Ö½ñö\¿íúô»„÷>òÖ2¿kÆ}>ÿ¿òjÆ_yõ9WA@œ8q‚'NŸÿË멘¬VR‡ cåãcS½YF’ýõ×au~>¥û÷³óÝweã‡hPC*Ñ)”úÉ+gÉrÿ«äv4TTpdåJ?fA#vA· <šœk(‚DÑSáÄ—î^wXõ ªá œÜ½›“»w#»ÞŸøÎIÌŽ;hÛ¶-V«•ääd Ô°ÂK/½”ÈÈHöìÙÃ7ß|Crr2:u¢_¿sKƒ^UUÅ—_~É”)S ½ Ç‚Î'Ò¢W/жogÓóÏ{ú¤Ögò€¹êuh žðQÑà!zß³>ÿœ,•ýÛÈ¢ŸãL@7`õöítæÍ“~pÑ"²-R¯ÐPÚ_y¥g›¸Žétýõ´èÕë´RP‚”‹M Æ !g¯Èýí¸û¢ÆA@ˆÂLTYYIuuõiïSò$%»w«³ƒì©?hj‘”ÄU}ä·>ÍŽüð»ßŸêcÇ|”9#šxQñÔ~7TT¿zµÏäd´Mlú04—-ø–¤À`;}(pÈ`è­Ôÿo"e *+‹Ê¬¬€¤;2x&ܨ(Z Ĩ—^ò)ùájldáu×Q£*o>íàÑGÏi»s¹`Ý:hh€a?cœûôS¥¨½&µµàt^}uÉôéT«†›òìlªŽõÛ&kÑ"Â|§ϤĶmKlÛ¶tž8P¼ÛÞxƒ}Ÿ~ê múç?“¦æ3&õèá [÷÷¿³æÿ×ÏË®½í@f^' 1“¬3™t¿õ`Ô¥û_Ûf%­~ÿ/ô¬„©e$2_{øÎ9ôå—,ºád]Xfrÿþ„ÅÆrÍÇ_4uW®\‰ÝngçδoßžŒŒ fÍšåù¿wïÞä©ÞÊž={’””äßóóÉÊÊböìÙ´k׎„„úôéCœŽyúL˼yó˜6mÚ/b=¥yûö4oßž.“&‘·bŸŒíù/o ƒ X®DÄ9V6˜k“zõ¢ÕÀt¾ñFŸsÙkjØøÜsœøé'M°ãˆqNt56rpÑ"Ÿ9lóÏòPa!‘-ÿD-55µÔÔÔ\´:cTT411^+®Ãáä¤Î;}1‰Éd&9¹%²ìk⯫©æDÁ‘ úÞ].'…Çb9G†œúºÚ <›’žžNzz:ÙÙÙ¼ñÆMn[vð ßL›FCEåÙÙ~ƒ¾^1Åúײo_?ñQÂ`Ÿ·|9«ÿúWжo÷ñNé!€P/ÛŸ¨0šñ-¨™¾P½H"cÆ?×) ¿ $õìIóŒ ŽoÚDma¡±…ÑñÐIþD4b9ýöF"™LÄwéB3]xKx8ÓÖ­ã¿ü#‡¿û©º:øà¨©Q¼Ó¦Á’%pô¨Â!tãЮ\r‰wŸ¼<øüsp»¡M˜0>úH|ÑÑpûíðî»°t)”–Âý÷É0>Ü}7ÄÄ@N,Z¤„}¶oݺÁâÅ`6Cl,Üqü‚ÁßDJöìa뫯z /(yiÎ_ ︎¹ú?ÿñ-çГе+cÞxƒK|Ðüÿ³ÏÈ]¶Œ¼ï¿÷ÛÞVZêçµûT ®öKTÓ~øÂ­[©9vŒ½óçS{ì˜O¢Þ¸ãú̘AÙ¡C]¹Ò–Zècaû÷#ïßO6m<Þ¿VƒsÛúõ,è!Nüô“gŸÂ-[ø$3ÓCÜ2ø‰'è$0W°óí·ÉU‹Û‹Òíæ›‰Ió&ýw¼öÚÓJœ·×Öú=ÏŒqã|ˆ´Î4ܽz5»þû_FŽIHHœ>ÝçÚ=ב‘AF†q®GZZiiidff’——ÇÉ“'Y¸p!v»V­Z1nܸ_Äú©—Òýû);xPy¯6—\rÉ/®3x>JEN%{öpä‡8¶v­Ï¼¡ÏÜ mÖŒ×_Ï®¹s=ó¬£C§ÍFb÷îØuàÇ^SƒCMã0*ã20Ø Ó´¹lÌ믓ܿ?ÀoŸqš’›{„ŒŒNH’ÌÅ(yyGéÑ££'°¶¶–ššFRSS.Êç‘•uÔÔÖ~y„e¥%ÔÕ×]Ð÷Þ2¥5ìãVœzeiÙââ 4–-ƒáÕõË–žgÙ2†H½Óh5ØÆhþÞøÜsX#"ès÷Ý”îßd2ÑcÚ´&ŸSáÖ­üôâ‹Ä¤¥‘Ð¥‹ßÿg“TÍó>R’0›/N@˜Ÿï_‹3.®9©©Iåó((0N·Jkמ^ý†”3'«øæ¬;uRWRŠGeëk¯yØò¼ƒöW¡*¯š°ƒÛͶƒªöÑû¯7âˆFÑhãÖQûYªºôÑ]G<(nlÍÀ£­SûåjQé®cû¬YtýûßѲ6Ûi?Ë­¯¿îC¹_•—Çî?¤¡¢¢Éý’zô ÷ ~ë­·8¸|9ù›6qÙ¥—ÒoÄ†ÍšÅÆþ“ܪ*Ž®\é}……ÔR°~=ájÈgÊ€´9€°æÍéqë­ÏÕXYÉŠ™3= %H8|Ø3ö}sð a!!ôGôïµ>œVƒ)m¾ €-¯¼‚Ën÷ÇrÕ16Ùf£ìàA_°"I¼š’âi¶²2ÜB)„µO>‰¬óÔêÇHwðS[R‚ìr±êÉ'‘NW_M|×®~sž9$„î·ÜÂÆþ“]ï½çw,{MamKP¢söÌ›Gîòå yòI? ”ž™Iê!d-\È·wÜá“¢üo”J,#gô ¼bž¼ ãtñ ¶ý ú¸šª­«>¦€‹ZÊ‚$ñã¬Y„5kFFí~÷ÞKí‰D&%qèË/=F'½®r¶áÙ– 6IÏžMóTTTR^^AFF» «Ê¼y HMMaøð  Jþb©ÎÏgóK/ZþÕÕìz÷]/#¦.t­ýرTåçsRõèóåô œl³Qo³ùL0‘IIô¹ç*fßÇû(–ØË]¼ Åb/NfzK§¬›ÀCð/XmUÁY^6Q‹îºE0Ù¨‚µF¼?mÂt ¢I½¾HuiĨß5PhV¯QÚ±µã;ð·wçwàKdãîU’$/Óœ,{hér(›²ðþZ‰Ž†cÇ`åJ%4´C¸òJøðC,Μ©>5í“Nà€×^ƒÆFÈ̄޽aï^ÅÓסhyýûÃܹpï½JÈèæÍ Iž®x_~YÉO=Zñª\&ôêõëÈk΄¼õÖ[TVV²~ýz®¾úÔ,Z¡±±ô½÷^úÜ}7ÎF%Eﵯ·øl…Ê.²,S–•ÅÁ/¾`ãsÏ‚ýþøG*rrÈ[¾Ü06ÑGRXœ¸´¬„AyÕ+®.|ËK¸ Ú·fœ †½\S·[ná²ÿû?¢R‡>Udg“µh‘Òe™õÏ<UUªªâ'#`l2!™LŒ?ž®]»R™›Ë <ýqÅÌ™Á´Qx»&%{ö°eάQQX#"èÿÐCžÿʳ³=Ë18Ænàðþýdý53fÌ ¬¨ˆ¤ÂBê,`צMHê’6l’,sôÇ}Ž1qÑ"VýùϜܵ‹ì¯¾"端OH FAâËË)Û¹Ócd“–—\BÛ+®Ài³±í•W”1×ngwa!µ*€o Ø?ù„ß|âÏBÕcäP€4ŒóÈ%YÆ$„ñÇëæ ŠŠ+ÜÆ?ñyFjí°°óïsÿz™æ°0jsrØüâ‹>IlÏ£GÓR ù®ÌËcÿgŸ $³ï?ÿÁQ[K‹>Š9£çí·•œ¬^{•ÕS?FàË–­=#‹ÎªŸGõ}L¿ˆ@Q3´Úñϩ׃G èxÝuÄwêDÙ¡CR ^’,c+,¤¾°Ô6-¶{ÛÉ“˜BBOH ÍðáT:äÓgÀ˜/à÷,n·Û«}ïÝ»‹Y}í²§Æ›$™0›M¸ÝnÜn7……Å:”Czz[O=7‹ÅbxÌß»h!¨’$y®Y»OI’0›Í†÷åTSŽÌf3’$1qâÕ¼üò›@èr¹‘eï1œN/½ô:ýHkÓ&x‚€ðÔbT;LR'#¹¾>àÃËWYïBN¡ÐÈáà'ž@’$’  `ÃܪåWhH™ D±üƒCXÜ:àª.Va}˜î³à]ЀZ½:Ñi£6éiû… K¸ £Pj³&œnÖ«K¥úÙ >ýd¬W.ÄRÚúië×ס[^y%`Øš¶}·›o&VÍ Z{FI•sÄ#*‹&‰‰ðç?ûn£×oºÉÿØ£F) (!£úc<þ¸ñ5õéóÛ÷­ªÅ»¾¾þç=O³«J£švÙe¤]vz‰ìvzš,áážã‰Ófó„*æ,Yº§Ÿ¦"'ÇoœÀà9p9Mzžõ$Lfà(J§UèïZ?û¤v>=) ª2 1ÈŠlÙ’[ua¨ºw·ôÊ+= çLOi)»„}õ &ˆ‰ïŹu+‡·n”ð]íxm„펨€¯è$ŸZFe;`Ðß¼qm±HêwÉûÛ$ü6I’ŒnÝ"ËÂ,+ïÀ8dpi¿Õmœ² ž8ö⋞0e·Î°çŽÿ=ǾÿÞ‡[Oœ”óÅdñëþö7C‹Œ¯·\ž6:u}פ›ÅðÖÚ5é#§ úþxø‹/8,Œ ”>ä3j) ð0ÇŠÝ?ÿù ›ÍÆ£ÞÏ‹/¾Nxx8EEÅ 6˜>ø˜²2%KºK—ŽìÙ³ŸÿùŸ‡p8Ì™ó&³fÍüÝ?‡~XM³f±tëÖ…ÿ{.3fÜɦM[غu'‡“‰¯â«¯¾ã‘GîÃápðÖ[s騱=û÷+aýqq͸óÎ[ óäeÛl ¼ð«„‡‡ãp8˜ëS³î§^ \µ¶ïÞíC¤bî©W$µu»U¢ }~ d0NˆÇ/G¡­7ëú@ _‹²®í‹-ŠÀ`Œ’Q(÷/Ç¿è<@]QsUÏL—I“Sãš-áá~5K÷î%ûo.CÆØ±>ÏY|^‹Tz}Y0–µRÁ˜öLÀNa?§:Öh×— $ Û·<>ðp\3˜“Ôí¶¨cY"0ËÀ‹"¼}~§$ù—eÀ–IÝF¬/‰¤î'éŽ! íIV×ËÂo@ÒYÁÜ2¬—á ¬”Ñ$Oû]Õãùû$0G€) ¤pùF©/#D°Zt(È¢[ÌGÖM@N5Ù…Å®FpÙ•ÅY®eil€'Ô¹ Î å²2hQ#?1¨F$dF†^É`ît}T» Ñ+¶ ‹8ͽ1‚7N¡7Ë:]Ám°^2xFzÆùXqòûï$-Í[*èÁïæ£>õüž2å.¿|(ï¼ó!6[V«•Ç{€¬¬CdeeS\\â}³g+¥xNž,ã»ï–wÏâ•WþEXX(² åå•8NNœ(äèÑcôêÕ;÷°nÝ&î¹çfÏ~™ðpÅ|–•åŸoߨØÈöí»8ðŠ‹K(++ç¶Ûn¦°°˜Ç{àœÜÏ·ÀKÀËÀ³À“xSª*+yðw1òŠ1ÔÕÖ0þªkø~ÙRBB”r9©­[Âúµ«INIÅjµÎÑ£y8ì¬V+üÏ“lß¶•Ã9ÙÔTWqÝ “HmíKV[[Ëë/¿è©y˜ôë×®¡¢¼ŒÂÂãüÏ“eÞGïÓ¬YU•Lž:-Zr±HêÄARÇŽ^Ågß>܇!I :ÀbÖGÑr¨.’Áe2€"4 ç'2§0ïj@MÆ7oOóâ™ §ÍÛZÈO„º½v>½WשQ÷ G ÕBCµÐPÁJjGaÍtêôƒz\6¨ëLêµj9…ð¬÷†ÄÄxˆeꊋ}À` «‘ÒzºRp¬€£G§P^>ê‚îá€}¿Ùù³.dïüùúòKŸõãÆqÍüùžš~F’»|9»æÎå€j&Þ[BfÎ$VÇ@›ýí·~¥[µ%ù §ŒéCøÄ±CV•y­¡]íšw#¥TD+¡ý‹aÓÚbŒ$®Cåxànlô9g© ª,M(¥±Ô’µ`ϽìxõU¿:ˆz`‰oHºÙKX mœX%Õk%)F$«ú™œ@Ro&[†D9à¸îý0¼t0ËnJ§×ked˜Ó‡ß›$e‘“Ùà¢-:WœQ²¨[7hëb e'È*Øsãýt¹ÁîV¢)œn°ËÊXÙÊà‚âa^­Þª$à¾(âê ªÂ%°˜ÁbQ© ÜÈ’z‰êwí¾-fÅ g5+‹¤% €e¸ðŸ6¡„zÿ7‡(lÇžøe‡: hVAui¬Gu`o»ì.¨w+†ÌzuªÄKBà=¹š»:tF›Î°*²vëû°¤3 »Qrsw¡ä65†¸ º-zô hÏ¿RO`\ÎBoo¨ùù"‘‘‘”——S]]Móæ ¯Âž=û)(8AEE¥á>n·›;÷°råjÒÓÛÎÎ{TRsÌf3kÖ¬¤ó¦gtt[·î 66–²²2\.ÙÙ‡;ö –,Q€mfæH^|ñ5¢££ '55…þý•ªšéém=À°°°ˆÂÂ"¢¢¢¸ì²¡Œ¡ÔGíÐAÑ—Ìf3;wîÁf³1xð€³z_™(a¢wÃ;Àã×dĨÑÜ>ý.6¬[KIquµµÜý¸âEœóülnœ| ÅE…Ü8ùf`ïî]Ü0i ‹(F‡ÃÁñ‚|*ÊË8œsˆò²2?@Ë•W_GMRb®CÇN4‹cé·_3óñYäÎaßžÝtíÖƒÇ hø¹ðA@xJB×®\ùÎ;¬zòI—ÁHá3PõJ†‘âhÒ)JVÝoqR­¡Zè“[7™9…‰@Ëݳà Õ€¡öôlŸâDªMhZ^Ÿ6_שŠj„êEÔt¢0@ºT/‡èQtèKX»ßŸòC‡ür¤êQÂã0ÎCtqqqHee8êë}Æ$£Et$Y Æm\×ocɬ”_‘Ì Ð2™T°'jò‚Þ:gJ†,¼{Â÷}\æ‚þ.p; Ê *¸s’]:¯’áû’•w`‘Áâ‹,&e1 Þ> Téˆ@O‡[¥NY}NÙÿ:´÷ªÐ§T’ë°Š'¹o˜¥6×¢D_„fÌêä¡3Á‚"Dø´˜¼ïJR¿›ÕT«YfH†XÀ¢x&-‘`s¸²#ÆP¹°( IDAT媺[¨ B5°X œT-&%à,„Ò:(V¯³V½~ðiM(R˜ï$µ^79t^>ш«ç0ŠÒ€ÅùS>ŘâÖµ¿ð-0©c‘ãÈ© eNÂ7Üú|©S'JMèf*Ñ^uu —_>›ÍF—.p»•'5vìÄÄDsã×røpW^9–ØØX† ÄÖ­Ê|~ûí7c±XÈÏ/ 11ššÚóâ9 x ‰‰ ¤§·%7÷QQ‘\sÍxŽÉçÆ¯%.N1„Nž| qž{ýáÅ©•½(--eܸÑÔÔÔ’œÜ’ÌÌ‘;V ‚mÞtÓõìßŸÅØ±Wœõû ÞSÛïéÒÜ„††²~í‡P”N»°w÷.ÏÇŽQ]UEee% ¡¤¤€â¢"ŽäåòÓÆõ »l86›];·c«¯§_ÿÔ×Õ1û™§¸î†Ilþi#©­Ó4d»t#>>ž6m/.¢¢ ÔIYV_MJé¾}žAØl`9ÆX7ñI¾= "¡‹Yçõ Ñ—µc5⟼®WdD…NΪ3К ¦˪*kÑêŠ7äÌ¥3à–« I J(h„:éXcoƒàù«WAd£n2Ô?#Ùà8œNܲìùݲ_?F¿ô’,–:De^ùkÖ°üÁýÞã¥ÿû¿tž8‘D¡(½§iìXì55ì|÷]V<òÈ)™FÓÓÛÕ³ÙtQõ»Ýþ›œ·×wúÑú'õìIÈ)Xq’zô`ü;ïþWWR‚«±‘ÊÜ\*ssqÛí,»ÿ~j‹ŠüAEž$)À"*yFŠ›ÛÀXdB £SüdA¹×´õʪ,8Ê Dõ,˜¦mJTël¨Îƒçv·lñä±Y @Ñ]3˜¥ö‰\@J÷¾»¨èh&\u-=zöI¢}‡Žää(!°7N¾»½‘‘Wdzö>ê ¢¢¢¹qò-œ8~œø„FGiéIþøÀÃÄÅ'P_WËSnñðH@×î=Ôï’dâ¦[Vh‹ÙBJJ+.>’òò2Ì¿°O^H pm-e* ¤àŠù7ò"YÓµÉÓ$xä\eqüM:P)ZçCÅᘠ*P«S¯!Zõ8ð†zŠJi¬:·PÏ/*†Þº´ ×­'½A½8(ذÁg]Ѷm,1מ>?߯`0(¡sí23‚AMB¢£é}×]´ËT™wT’#‘eEEDD„_4}Ááp”ôÛÔ¬ˆiÝšUðt$"1‘ˆD…6eïüùžõYŸNñÎT©¥ZÐõQ£Q=ù“þ»Ñ¸ õa ÐÊ}CÈëÔ~¨âñÚQ<|2мCR Àít²ÿ³ÏpÚl”îÙã‰d˽D©€ +JI -4\ŒøÓ¼=ÚKê…ÈêM»Ýàv)-·[í÷²W™¶ €Kô¸¸ðÏû•e/ÈCÝ\xCÇ]ø3‘çhÏp† @aÚÌ `l}û ˆIKÃ^]í׎ò¾ÿžz]mE£|Ã@Jz ða}~§‘ãÓ¡k+Fdd™—ž'Ï$2í9Aà2A§2„¹hºÈºS¸N§Ñ|ª¶JÑ (ƒË §×0&1〠¢ÍÐÜ Ñ‘ fÕié¬ÌC‘vH©Qók•\Äz‡Ò>Mnq‚Ù ’ œ./`D³´KoŠ„Ñût1æ}Q3µßÅÇL0€v#G" lÿ÷¿}Ʊ}I×ý5Ê1LÏÌôŒ{pHeZ=›R\\Beeù9÷µm›†Åb&;;/ÀÜèßÚëëmr— M㉡°°„ÚZvíò²Š&a— W¾yƒ>@Äb!I⊎Q{Lt4ñ ^ ´PŸßññ žï)­#AFûd´ïàYIb’7:,,<œƒ†xÿŠ"QW»¸CÇN\¬„€Án¤¸u-Ð"Z|5À$áÏÞ¦¯w„NÁóôá¦bØ'xÃUDk¯¥8u"¾i0š5¹AÄ´ ³¹Ú‰[¨“¶ßðÕ:¼!IêwÉÀ¡ÁÑ+)I={Òz˜7˜ wÙ2*ûF™‹á»$møpZFñÎïÜIl›6´Ÿ0€]ï½Ç†Ù³¹añbX ‰Šò„š¾iºàgLL4íÛ§rÁ·§ÓÉÖ­;Î[+YѶm|­°–t#Ï^ Ò'Kd$=n»Ü¥K©ÊË3ìÓb{Ö{ÝLf#Õö= ´ 0öxreÕ>&Í:t`òòå4kÛ–ü5k8ðÙg^6IA¹Ö£U(D+š×Cd ¶¢(Ð&Ñe…ê…žèi ¦´ïb$ƒ^¡v¡qqt™<™C_~I݉†aöN û”)ùñGª‹Š Aº¸\òÀï܉}íZbcb ‹–nÛæC•œL§ë®ã’$>@Íʺ’Šwìð}÷ù¯¨ˆƒ‹‹Êpþ”÷ÕñG +K~˜3g’ýõ×lzþyªõórº€<ýq#Z´ óĉÄwêDÇë®;ýqÁfcË+¯»l•‡û1yõ wPª:5C¥6o”á2D9¡¹’lW Ñ¡­x 54)YÍoÂÜ«%Ò×£¸k”φz°ÉÞ¹K3bÖñ}ûR¼}{Àz„’ 4J Ñ)m€"Õ@¡½›“›7srófÏöVQ …@I.7ß©áII[»ÖïÜí¯¼’Kð„Ô?~ÖÇØ¼¼côìÙï‚›û\.'µ44¸Ù½+‹”ädš5kNyE9&I"6¶f“ÿ¼XQQA«VmHNnua鲌ÓYC]]={÷$*2šÐP, µ55˜ÍfÂ#b‚ !/ Y·nëÖ­£´´”¨äd«Åçw¼ý6 åå~t–À@ÅÎ]Öâ€5 1fÎ ôŒgfwC_8×)XÝÝxóþ#U¯¾x½v?ÜsGD2:„cFêî1ßÐ)17Ð ˜"#é>uªe ÝèÑ„'x->ZžØåO?Í%BHèáï¾ãË)Sü&aí8ù«V‘¿j•׊ԩ%{”Dóuÿ;N› ³gsà=ú9nÞr¡‰ÝîÀårÿ¡²’ío½å·~ã³Ïú2=:£‘ÇÄQ_Ͼyóp¨ÉåF@R¯üëëœéA¦þœÇP’îõÊ´Ø®“€ý@' æÈÞWË>8UâÑ8$z$ÕPÓ€’†Uˆ@öd0¾H²¯Â.Ö6t€<·v½ñFšgd°ã½÷¨ÓêªÒXYÉŽyópÔ×{Æ #Ù«²•êÃt;ŒObÏž~Û·:”ÖC‡Ï Çóûÿè?’·|¹çwl»vô9EAûȤ$ÒÇŒ!}Ì¿ÿªóó‰ëØñ´Ûè–×^3¬Y)#9d™]ï½Gb÷îô»ï>**Xý׿š’¨(.¹ÿ~¢[·¦ßÿø‹úܘ7Þ`ßdzú/¡2/_šQšJ€ßøÜsØe™µÝ£„S‡‘Ó1e)A”¤ÔtµX²“›ëv‚£N¨—Ce•ÅÔ‰“ûöá>Åœê="¸‹ö ¤FÆDùX§^SGÒ ·`–sD¡Í›>ï;̧A@ 6ŒaÆ‘ÍêÕ«þ쳸Ââãi(+ó‚‘¥K)Þµ+`Áy}H‰dµb ÷N²LcMMÀ|##ÀiTSJ;—=Àd¾á®úÉÍ)ìÛ`pžjd4V|ËPháaZ¸M¨:ZñÍÕÁ± ØëêØ¡‚AqBÕ ë'»Õý«Gñirr  •<è!ÒdßÇÓX]ÍÈçž#¡kWìµµl{óÍ€…ƃòÛ‰ÓfÃåðN6f«K¸¶ÛP^ÎíÚá°Ùp ÛkL: ¦€úþ£cL²Œ«ºÚÇó.ôy iùÂbˆ¸Þë ž«Å[¿gÂ(¬ÏÈN‡Ã™X,K£åL•ªÿkžÿF¡ÿK§8¯¶´<˜‚=¹ÊzÅ6}Ì:^{-}Õ:“]o½•CªwmãìÙ„DGÓï¾û~öûïÿàƒM’Ž´1‚6#Fœ±6“–ÆpÕàp:b´mÕÑ£~åPŽ®\éãÉÔ¤ßý÷M›áÃi5hCÿò†þå/¿Y¿ìvóÍt»ùæŸµÏæ9J)€3׃³DDðÓ /(u@l(`Nlë!—3´Þ—øH4ÀˆiZ›wéŒC!€ÜØèÉ…|Â4v]¿hþ¥`–W#uý_\¨û ~Vá%ßÐŽ[´cE* ’Dht4¯¹†ø®]é1u*Ñ¿ ØÃ?LË–Š‚:mÚ4RRRxþùç‘$‰Ç 4F2{ölfÍšõ«®ãž{î¡];…¤ÿþŒuf˜À££c°XÌÄÅÅQRrò”Û×ÖÖR­†¡Ïš5‹Ù³gŸrŸ@ÛeffÒ­[7æ¨}ç·ßÖJdD8&“‰ø¸¸ßŒg (A@xö­Cv;›žž#+W’«šG7‰œ*Ñ[[š·kG»+¼É¾öÚZö~ô‘_˜6ÑÉÂK1 95ªA&z%…Vóîiadš÷@Æ[î¡%ô3%'%ÿAS@5&7­äD`e•Jýõ‰±NšvϲbÝ;«8ñF$%M…¶Ô”ˆJ‚öŒû-f—‹æíÚ±wÁêKKO»á™‡ÃAII)II ªWÎEMM-͚ŊËå$,, ›Í†ÕBCƒªªÌf-[*±ñJqÕzÙ…"Y‹±æ¯õ ŽïÔ‰¶£FqÅœ9„ÅÅñhUyË—sø¿ÿõ(œFu]à*$6–Я…[#Ûf ±Ïk¡_";°Å”Jmòr úµ_ï\Š·¤­î:…j÷¼J=‡æ릺 ”T€aû‘-ZüöÎ;<ª2íÿŸ35½‡ ¡÷ŽtY±-ˆ("¨«‚e]ÝwuË·¼[^÷]Vtõµ­Šì® A,€ˆ‚Aj¤C„’@!=“é3ç÷Ç9gòÌ™3]Ų¹¯k®i眙9sžç¹¿wù~9¶f GV¯æä–-QÜL&jdÈz-£O2úô`ô¿éè}-9??â¼|ßÏS[@0œýÝïû»ßqâ£øìÿ—º#GxÇ$¨ýEŸýõ¯Ô——Gíï&4X‡ÂÈrtë‹^JâB’b`²Qƒš­FÑM'²üTÓß­ËUW‘°?.•ñW´Â+¯¤÷ 70pΜoÅÿš––ÆìÙ³©¨¨àÀäææòàƒòä“O†¶Y¶lÇŽ£K—.Üpà ¬_¿ž]»vÏáwTUUqôèQœN'{÷°œœFÅ믿NEEݺuãúë¯géÒ¥œùßFèmK]dj¶+V‡&Ö`0ˆÓ颥ÅIVV&gÏžãšk®`ïÞLz5«W¯aìØQ,_¾’ÜÜlô£OŸžìÙ³ŸwÞyŸGùÝ÷j,¦0pî\>€zíáÃÔ>Œ«¶“Åæ0þú¬ß¥ùKˆ¬&!'‡ø¬,ެ^MÍþýÿðC\ÕÕeŸQÙ„-†ÞwÅO=Ñ›­÷H&¼´Ì/Œ#£ÌXnmUÇ ¾$UËЋN®ö۵ح6Ž}º ¾ä5£OFÿú×tÿá±'%᮫  7²‚I“˜¶d 1iißÙkíÐÒ¥Y½š!÷ÝG§ÑíÌ7m—_NA†gà=÷°ëùçY{ÿý¡luZÏžôTû Oqª¨Èpì¶Õ¶¡­ÐÚ2a4võãÓˆTFÓÕ[P·­6NSPzô5µ½ ÓÙ³t?žŠ¢"Ož wÈ;w&wäHêJK¿Péò×e‡ƒM›6ár¹7nœá6—\r }ûöeõêÕœ9s†]»v1oÞI2áhinsŸ)S¦ð /pâÄ ^}õUvïÞÍñãÇ3f }ûöeÈ!¬[·.t˦M›¨¨¨`Þ¼ylÙ²…Î;³{÷n233¿5ãRе!MÒù'·;RÏÏl6cµÚÚ'»o‘µÂ(Ñ>}ÄS¨€âb`¼új(©/û{èÙõ ƒb¿N@·¸Xð8à÷‡1 jåž"´.x-jºi¥æõI4j¿SÐ{ŽÈZccIèÐæŠŠ0æC›ºèiÔàvjL*½ UR‹€J i¢Õ*°³˜ÀfnM6›ÀniS¶Y”÷mf°h”ªñ„)ƒ1&vA›¬…­Ö‹‹÷í;Ò²ZmÄÅÅrë­7‘œœÄ“O>G—.ùlذ‰ŠŠÓ´´8ÉÍÍ&77›Ó§+±Ùltè ô\Ž1”#¾ÍýÙC‡’Þ«iÝÖ°}¯¼‚£²Ç™3Œ":¯£z;¶fM(+X[RBÝ‘#†"ëÑ…Â@~?Ÿ?õTØ>ú>#=°Ó1&”L{<­eÛF’,b…@)…Ás‰XU öoGÉLˆ66ÎSKu5‡–.åz~ëJKÃæE£@ØñuëxmÂ’ …èE/òµGMOœ`÷¢ETïÙcìÈ$$0uñâ¨ûw0K\Éùùí à·ØLf3ƒæÎUØa>yøajæ3¡ÜNЍ5 kºñ%Ž3Ær!AÝØÛ<ÄñD!‰Š§5ó×_} ²ô\n6¹*0 ~þ9>ÿÜðìzñEv½ø"Ö¸¸0Ð^‚"f¨$"K?5‡íB#Aƒ…ȸ+*B=K1Â-V]1„ Ï#€A­$MÓ´«ïÛußMcÔX=Dji‰zVZ/“ýÜ98wŽnj4Ý ±q9`éæ,:˜p§ÆáŽ‹ÁcÃk³ãµX ˜,00› ˜Ì-&ü6 þ3A»‡ÝŠÃœ€KŠÅƒlÇIìx±áV_÷J6<’ ·)¯ÉŠÏdÅ#ÙñH1xd;Þ€•€Ï¤w>¸¨×Z¯^ÝCeŸ#Ggùò•ÛŒ7ŠW_}ƒY³nT#”ýúõÁétqàÀ!.½t,»víeÍšxøá¿õãkãÆ¸\.ÊÊÊHO?¿¤…5>žî?T(«µûæÓ§©;r„­ýkÄöƒîº+Œœ zÏ*·ogÿk¯Q¾qc‰’Qæ_¦mzy#Y0ÎF+ë.~€±l˜M×)VTÇQŸ Ô2ëÚØö§QËݺùKÿ™Ö¸8:@ù§Ÿâih¸ ¹R;Nõ¾}!ò¦S›7sÇŽ¤^´ëêèûï³ù‘G"^Ï¿ì2,±± ½ÿþ6÷OïÝ›ôÞ½ÛÀív² âÍ©Sògç«äA· Öp£u[<®øº¸NKº9"¸¥Ýb7JɶÅÀÐ>7¥—¸7Pª‚B­P16-Ü#BûÔ;F]i)>§3,{_¹ms÷í#^G£ÿu[\\óçÏ'---öž|òIŽ?ÎîÝ»éÖ­’$qàÀ†NLL ]ºtaþüùØívfϞͰaØ1cÅÅÅlÙ²…ÂÂBâãã™6mEEEäææâ÷û9pà£FÂf³Q¨Î/ñññdeeQVVÊÈMû̹m™Ïë%;+ü|&$$à®sEÝç£>bÚ´iØívÊËËq8466Ò·o_öïßOSS`Þ¼yœ>}šaÆqìØ1¦OŸNZZ6l ¢¢‚ŠŠ ¬Vë·jìY­VzõêI Àëq<^w›ûÅÄÄ”œöÚÉá’‡àtE)©© q Ug*Ù¿w/“&_Ibb×ß0ƒ“'O„ö)Ú´·ËE×îÝéRØ•ûör¦²’ôŒ ÆæO7²øÕ—™>c&']³¥…ØØ8[õŒ7}²¯ÇK^½ÈÈì@åéSœ8vŒÌ¬ 4¤¶›A”CX0dÈÞE0(î«9kF²Á(ލÑb%fµL øâÇQÛNcàÖˆd´a¬õ&Ó*A!’_h=Lš¶`­ýƒAá3̺ÅQ+M:¹fÈH„øn` W*»çRšÜƒ£ön±uçˆÔƒš@:õT\î8üN A‰ ×DÐm"è7!$~3Á€‰ Oy/0#[ÝqkЉX$VüXL~,&v«›Ù‡ÍâU[=X­^âm-ؼ˜L—Uó†®ãÈ‘²P¤têÔ«IHˆ`öìôèÑ»îú™™ È™0a,gΜÅjµ„Äj»wïJzúw£\¯C‡x<Î#0ß–%vìHbÇŽäO˜pÞmÏspéRNmÞCçË$¢•šéǰQÉ·(rÝÖñDzQ»T„éê}¼pjã[#Ð5L}€--ÁwßÍ%K"JЬqqŒüå/C€¨ã˜1TnÛÆQ–Yî¨Q$wîöZÍ¡CT«‹¶f®º:¼™ iðÝwfG2ûöÅô-sªÚíß·ø¸ôÏfë£rR`•– /R”±;w¦ß¬Yœ;p€#«W‡Ê¸Ík¼ÔF H»õ»í¶ˆ^ɧÿùO~|Ç¡çEEœX¿žÒU«ÂÀ«S]—û¡0Žj¤2ñÙÙô¿ýve=˜2OSŽ3gŒïo ›ôS\3=™Ì½*Ù”f7ÝtSØó3”õnèÐðJ—ÜÜÜÐ{÷éXqµ×óòòÈSÛÆ«A­oÒÎ;A³hÑ¢°çeee¬ÀüÎ;©ÏÇÛmè#Zû(›‰‰±ÿ[Çlnjâ“>dì¥h¨¯§òô)V,_Ê¥• øk/ÿƒ[~tg8ð^·³ÅBVN6o¿µŒÛnŸÃ–ÏŠ¸dÔhjkj¨>{–ŒÌ$$&’•¥™-êêjÙ·g7—^v9ï­^Ejj*©ii¬X¾”)Ó¦ó÷§Ÿäö¹w³g×礤¤’_Ð¥þ'?£:“ÁaƸÔDŸí{â40˜—Lj‡¢ÇÔ©‘e[gÏrdÕ*öüóŸ¸Îž +7Õ—è$Z…÷µ¾?·ð¹>á5¯‘Tu~±ÒZº©•jrNšÃ)Ñ*[áÀ­_£é(ôøHI„„n`éô‡ÀH35}S8ß2sWö2€pŽLHÁŒÅð“äk"CªÅëÇD’e$9ˆ„Œ ̦ &)ˆÉÀb`1û1[üXÍ>’h"Vva x‰õº±ûÜÄø<Ø}nÝÍÄz\Ä{œ$º›‰ovëuësïsò‚ÿ΋z­ÅÄØéß¿OØó#›™aø8##ŒŒt]Ä2>$¿íÖ[YYY_ÛgÔ8@ÅæÍl™?gmm˜ðx4êwñqF¯^äézaŽ}ø!'N„æ…ó‘/‹tÀT IDATX…Ò7$öóisŠ6)[ œÑÞÀ‡ê¾a,z…1©•wo†©Çr×Õ±% ÛÏéäÓ?þ±Ísš7n“þö7r† wl>ø€CK—²÷å—C¯uŸ2…Ø‹ÜOh²XÈ4¨}û1³ÝN׫®"¹ € Œž¦&.]À5 À4——³eþ|CýGý8Ö‘ŒJ®KW­ÂdµrÍK/…^+èßs§Nd¨• YƒÑûÆ)]µ*´=Šæ¯ö¹é(ú¤™@ÍÁƒ¬œ9“´îÝ)œ<™ø¬,â¿Æù³Ýþ={ï½÷¾WÌ›fó×âÈÉíÈúµk°X,ôìÕ‡}{wãSÙÃûŒœÛØ»g))©¸œ +qBB"ý´nÛ!+‹ììúöWäŠìv;ݺ÷ ¹Yñ êëêqÉH2;d±~­B"9~ÂDúDù‰x<žÿ¨k·F…šéÉL,—„ž4 ;¾£ªŠ¢G¡H(s õ!ùýxC Ì"ÜÄìØu£}½˜½žeM[ìü(™AUÓ‡º­VŠê£Gƒd%Abº«Þè@ ÈyA›™,ÏYRõ qîÂì `wxˆ¯s[î†r¹ššd|nKP^de¼~€ Œ)怌‘ýà÷Éx=2²Ú|(©Þ²€ ü>ðÁ+C‹ §ƒà‘!(+úkÞÿ:¿¢ÖÙ³ç8uêô÷~ |[4Ý ìQ«¾³g““sÞ}N~ò ku%‚‰;ÒGЯ4²~³g“”—‡%&k||è9¥cÙÌ6ŒÎj†2V;•oÚÄ[×_wúcñùuxˆ¥áûiRÚöâãÕÔ2‚Ô´ê˜F›Ÿ=th˜CËÙ³ìWK®²‡ !âD¬±±ŒþÍo°Ø#£À]¯ºŠÂ+¯ärU6ÀžœFøÓníöuYFïÞ\õâ‹­ó–×ËS¹¹ÈjI›^ïR/ë¤w²Á8 è×gݱ€hc#{þñ|9ÆŸ“C~~>'Ož BPJá/Q³h%Ë—sðäIr„cwE))Ï’òòóÛßÒwÖ,lÿFeE»]ëØ±ã÷ìÉ_û'x½^Nž<ŽÅbÁçóâv»6b$nµWqÒWÒÜÜÌë¯þ‹†úz Dž½¨(?‰Ùl披®&>!Šò“<ýÄcȲÌÌÙ·Ñ!+ “ÙÄÓO<ÆØñ((,dé’×ðz<ôîÓ—>}û±øÕ—1™L˜Íæÿøk·}Õ60 éÉô 0ó,2Ú~Àäó!ÕÖ–ŠŸ)ŠÏC¸Ž È|ê¶~Ýð )Ì­q«¤£ôõ%©·xÂuµ>C'JÉh,J6±£ Òm`KVnÖLŠL:¡tÓ§ªžh#P ò&ªü¤ÕW“îÉ ²¼-àn–&¨t+Žn£¬0´¹ÕÏŒ#bÔ Ö7a.—‹E‹áp8hVרwß}—ýû÷“››ËÍ7ßÌÆ™4iëׯgÒ¤Ix½^/^Lyy97ÜpŸ~ú)×^{-±±±$ Z¹ß< ô‘š’NŠ0L&>¿¯Íµ¸k·óË£˜LfÄø£$™°XÂ’zZýs£,ŸµàåùŽ!:Ûáz„‘Öž<½s$’Ä!±Kûö…€žQy§Fþ¢ÀØieÿE¬ei,bïŸöÜ',DfÂKREfÂ8ZÙFÓPúûÒ%HsG”Ì^*JŠ0–Pbb=ô:½šÔýÀ7ÀŠs¤†ÂdN˜ 8KÍ$bÇCuô ”Pß‚T)+ Ú5 !Y‚^²’Ù -êêï‘ÕóBk¯¢Þ!öé~¿_÷[Ålª…pBÑ)×—õÊ_Švÿýw3þmn“˜˜ÈðáCX³f}ûÀúªœÁÆF:ËÕ/¾ÈÊ6J@cÓÒ¢öÙÔ—•±uÁNoÙFˆb¤S¦'œ9úî»<•›DÒ÷éËÑÄR3·:6%¢Úˆó–%Ô‚@=Pä'Æëæ-Ñœêg`ð=¢CdÀqêÅO=ÅΧž:o¡PïoÄOç È;–Ô®]ÃÞ?ùñÇì{å•óþ§yãÆÑi̘Ðó¤¼<¬ß‚èþ·Õ6?ò ¹¹ìzþù°ó`KLdă’ÒåÛI„ ƒÔ9£‡ÄN.xGU‹/¿œšƒ£ŽYMIº€±Ik„~ì¶%gÐyüx쉉ý~ö½öZ賺Ÿ 0×ìÚŹ]»ÂÏ °°üïÿ’ѧ#|0Ôܰæ…ðoÝu v½úêoô?mjjbíÚµx<&Nœh¸ÍèÑ£8p ï¼ógΜ¡¸¸˜yóæáp88sæ .—‹… "I3gÎäÙgŸ é–””pÉ%—0nÜ8\.Ë–-ãÒK/eåÊ•¼þúë”””°fÍŽ?ÎÊ•+±X,$&&2}úôoä|¬ZµŠk¯½–‚‚fÏž (d9Ý»w§¨¨ˆýû÷³sçN&Mšºoiia̘1Ìš5‹ùóç“••ÅÒ¥KÉÉÉ¡ººúßΞ¶[»µÂ/if@(DÍ@;}¡çVàÓoZFP_rÀŽv¯Irr²xå•7¸úêKjj ï¼ó–|oÆaSy9Žª*JW®¤¶Dù]ååT·¹_|Vã~ÿ{2û÷½VWZÊ™âbJ–/çØÚµøœÎ¨ešb5€¦÷êEJa!eï¿r>H¦ôÚ„ÚþZK¡õlÃFš§ÑÀ¢V&m"’ã$1Ù•¾*šä÷U‰ÛZ¾€½ÿúGŽäGBŸ%@rAõeeT|úi›ÿ×Þý+ ŽK\f&“Ÿ}ö‚zFÿÓìòÇ”>VW­"¾ý‰'ð9¸jjpVWsÝo|+¿»·¹™zõݼê={¸IKb¥+WRsð a5ŽY·ÆŠk­¸fˆÒ,áì¾úV€Áú/G™/޼õVh¼Ùts€Fg´.A©œ‘€Úƒùà®»B¿× ì.‰2œÚ¼™NcÆ`’Á¼–žžÎí·ßN}}=Ë–- +{8~ü8ï¿ÿ>¹¹¹ìܹ“›…@žÍf#99§Ó‰Óé¤ÿþØl‘b凿ã?&++‹buþï/Ìï]ºtaîܹÌB u±-##ƒºº:/^Laa![·neÈH)»Ý‘ ¼óÎ;ÉÊÊúÖü–/cåÇR}öLû¤ýZMu]ò²Ûá×eEEEQSS„—"꣊ڂ£eýÐ1+álŸ"›ÖõZƒbô߯{.ŸÂI“È6Œ’+¨U£Åï&²‘ƨ`0U½ÅK`2«mT¿ʽ÷sC• úÇAG 0üYN'uä½9CˆÁM/JÈá …Þcô­?Hê‰z,»ü°äÍPŽÊp¥TûŽAÂû5ôzkbVUÌôI¹µë΋XЇn1A¨^”Ød=þ"f2™x÷Ý5TWŸcÞ¼).ÞÍž=û±ÛmLŸ>…•+ßcÕª÷˜7¯•‚¼S§\6mÚÌ|È„ ãèÑ£ÙÙðz} <€É“šåæfÏ>»£GÑÐÐÈ„ cÉÍͦ¾¾üü<^~y ×\s={ö`Á‚ÿ£¾¾yóüNÂÊíÛñŒ »žž’·Þ ÛÆˆ-Pt”®Y´ˆ¼1cHÓ‰#ï{å*·mSþ‡Ñ£9ùÉ'È~›RF Ì]_OÐë%­GêKKkó$ÐS˜'ôA 1»-©q&PüìgÄ›Íl{üñ0ç· èƒRv-· \`[+G÷I4ž8abMV+y—^úýgT‡,)/ôž=é|˜K.¹«ÕJAAŒ'33“”””xš:õ›ëÿºì²ËX¼x1‡ììlâããIJJâðáÃôéÓ‡ÄÄDz÷îÍüùóÉÉÉaçÎtîÜ™eË–Q__Ï„ ÈÏÏçµ×^ÃçóÑUWyñ]²ôŒtëÓ2¾BÛóù–¯íØí€;v,cÇŽåÈ‘#,{üñш¬‹éštŸ×ôɺEŨ %`¥OëÕ‹”.](ûàÌ@Åúõœ^¿‰Ö>GÑAÖS¬z³¨ÇqRb›•þ@, Å€Õ6;ÄäÁ l ¥þø¢ü§?ûÙÏ"^ÓëþøÇ?{~³®ÜæÌ™\rÉ%áA£NBïýä'?1ÜGÔ!œpÚ´_·eeeñ N‹ò.!ë Э[·0Ð:L'çðóŸÿü;ï[Ç'&‘Û© d|…väð¾v@x1-¨‹¤Ë„—¥Hg–ÚêSÓGõ@2¨[Ð%%´””„@õ%1iÓ9zúZaóÉàôçTæÝë!QS½ö£ }1{=tvVйºNƒ|š«Á] ¨oQØB~ðûÁëWPé_jQ?_¾(¿žµƒóO”}Œ¢¹FD b{÷{\T´…;ï¼»ÝÎë¯/W£”×––Ê 7LåÍ7WqèÐá®ÀÛo¿Ë¼yFm^>uª’@ ȤIذa‡ƒ½{°uë‚Á G£K—¦L¹ŠÌÌ –/_ùg›ÿügüOXVP³¼±cÉ«H3;ªªÂÊ e ß-·°ÿµ×B×öÿÕ8`"«Tá_9 È” À$ËÔ—”„9jÁúzêvîŒʘ €›èšQÆEªàŠ1;( ΫVJ®Í'b_RÐQóZ™úI`¤úz¬ðº()#ö㶨}gÎ@«ŒE@A¿Ÿº;ÃæB€²5k([³&ÂÁ¥ñ©Ý{yõKˆH'"ÝzóÔ×óù /ÐgÆ ’U WU\Ìñ?Y Ocã–«®W]]TÀö»%‰T]©œ·¹9$ .ü|þüóÊ9³ZCýýo½••¾ÿ-·`²Zÿí1çs:9¸t)'’œŸÿý~ñ º]s »_z)t.Í«²ƒýéO˜ívLf3¹#Fய§Ã€dBZ|ô‹_DÈAh0AÝš­ÝüºqàRÇ€VCki§•p‚7‘7@d÷öꂽÚvz_Awúu¨…dÊ(󨕳&¨Á¤h4OIyytQƒ #z‹.óÞníöMZZÚ.šÍn'¡]Få[eí€Ð bg1‡"¹ƒ¬‹.š„EC[ˆôì—¢œ„EXpÄÇfˆJNc&R‚B‹^jâÔNZ¥"¼ÂbåCÉÕE/¥ü$M\Z5/Ô£"Èu§zr˜CPÛ'P*+¢ÚÚ,²¨Úi͚ʄëZˆÌ„£¹ Õ–$Dÿ[n!.#ƒÊ;x½TîØ@)S8S\LóéÓë—É Šöþûë"?ùdxfjÕ*¥lT³ 6…½ß£GWÜn7±±±ÔL˜^¯——_^õs7oÞÆ¸q£Y´èÕïäXsž;ÖÇ#þ•EEœ.*Š .Ê×­ +ÿF£/ÕmúŠt=šµ÷ßOÉ›o†ŽhÁ ¾cÇH"ý4ÃxÀp»÷æÌáè{ïE=ÎÕ/¾H÷)S¾ô÷èòƒÐiôh޾û.¹Ã‡›™Iz¯^!]Ì~*–$ [b"'¤ êmjbÏ?þê%Ô¯"0CX{Äà‹¶^™„ëÛ/Œ5‹Æ¬: )’œ¹tàP/Ô­Ó©C†?~<'7näì®]a.FKmÎé£Îãts™¶mKuu¨’áèûï3æ7¿‰úß¶[»]L“e¯Ï¦Ã Prè ýúlsß—^xŽ[oŸƒ]ÕÀý¼xC†Wæ¨wV2hÈP:vÊ»àïòÂsOsÏ}íã¢^ ™hÕä3*gÔOøz€!–~Ù‡0AuÐ4²™8õ±M«Ì&õ&IR?_ôdŠÀºK}-ê‚Ô¢ÞhÕ ô šMø.ñ*Ì:˜!! ¤|õ…4u#QB;¨_9–FrîœGQH;¨sx‚(d±a?hÊÅÇzò Ñ ¯¼’«^z I’úýaôàekÖ„Ê´ÄŒ ºèíµŒŒtœÎªÿZ3IØív ¿ûÝ—c³X,ü÷µV«¯÷룕¢ô ÉÖz««C$ Ñ€ NVFŸ>ôPÙÏ<êٳÁë ë[µè3bÂ{Tµk^ŒþÇ ¥vP)É„—­ÅÇõ ÷aœk‹0$¢”™õ7ƒ€&ÔFæ`šde87¢$ÿ°i¤sÐS½¶*@Ÿ›nbàœ9ÿðCün75™Yñÿ°%&2L-ùª?vŒCË–E”ÿýf«$ d™€]¿q«¿‚“óó™±zuT©ŒI?ŽÉbQôÍfä`0¬ÌÓÛÜ ’Äî… ‘L&L svï&EíemùÔ©”oÜHÀç#¨ëŸ”$I;êóÁ÷ÜÃÄ¿þµí¹â+È‚’aý¯ÊJÌv;½•’õ…ýúQ¯+ï x½!qw#[qãŒ~øaÆ©š|_Ô 'OF–eÜy'öÄDUU¸ëë1«„"f‘XD=_¯—ŠO?åØÚµÔ>Qã'¼÷V&œ1\2BjDnZÆa š… Ž ÕÃýêX3î ¶X 3o¿E«V‘±w/5‡!û|H@%wŽ˜¨^P—êË{r2½¦OgÏ?þAÀã Iá|úÇ?^4@ø‹_ü"äìßyçtèÐ `µZ ËIì±Ç‹(3ý¢¶dÉNžõcÇO`ÆÍ³q»ÝïØÎ²%¯3rôFñ¹ŸmbÏî]ø}>~òÓiq8Xõö›;z”›fÝJnÇŽ¼ðìS8NÆŽŸÀ°—°zÕ ÊŽ¡°k7¦L›Îç;w°é“ ÄÄÄpÏO~JõÙ³,yíefÿè:tÈâûbí€ÐÀI¥5Óe"¼¹Ü«‹j ¢ZïžMx,‚ÀDZK¸ÌæÖð¤,©| 2ƒêgÀ„@|A…¥Sd õ`,Iá&\’BŒ$j@0¥U°“ LÙjŠ!‡VÖQ·à9Ö@à,8ÝŠP7‰@•…ð쩘Q5jÀFÉ9‡úÞ.Iç`Zìvªvî䱄„0Ç-´Ÿ×¢ÑÈc.„N<â‘$bc¿:#³ÙôoÏjýꇱ×ëûú#‡„“¦˜ Fÿ1DfƒÿoÍÁƒÔ<AH!fóD@(Îáæ“IïfÂI‘PÇìu›2Z‰ž’ gô cºE¸ ¨“Ò€ÇÉêke@¸%¥ŒÛ++Ÿ]¯@‡:´´–Šš…ï©·âxÖ ß‡„·…ñej#Èæknf‹À–gÄê"ÌINV€ pÏ¡CTqlíÚPYe´ùBœKbRR0Y,dJ—+®Àž”ƒî††¨=}^{ãë×GÍ’%uîÌÍëÖ‘¦+ÕìæuJ&Ï?þ[í¿Ô,¾CúÝrË×>¾<|>ÎîÞͱ>ˆº]óéÓø]®Ðs[b"65'šÏéħ ¾¼^Ê7nüZ„. IDATÂßÉYSƒ·©‰âgŸ¥¹²’ƒÀ†:î÷¿§øÙg#r ËÐkì¡"Ó§UŠŠ=ÿv! £í¯]çNÌi²Hâ#‹4é(1€$Ž+m ù׿ð©ûJ*™•0ŠS£]¿bŶÍ!`›èNs9ð„‚Oâ’Ú¸¶¿jKIIaîܹœ8q‚ââb®ºêª¨:„ݺuãúë¯çã?fÇŽ$$$p×]wáW¿o}}=Äãñ°k×.ºwïNNNÇéöìÙ“©S§²jÕ*>Lrr2sæÌ õ%.\¸iÓ¦}c>¤ÇãaáÂ…8ZÔžxM‡°cÇŽÜ|óÍlÚ´‰‰'²aÃ&NœˆÇãá7Þàĉ̘1§ÓIaa!ÇçÍ7ßüÎÂó™ÛåfWñNš±X¬˜Í&.5†ÍŸnÂãqc·Û™øƒÉìÙ½‹9¯5pðà/çñÄ‚ù†€ðŸ _àéç_B^üû346ÔÓÀ ¦N»'ÌçÁ_ÎãÆ›g#e^xîi:deáv¹¹í޹œª(§¡¡žukÞãî?@C}¯þsÍŽfn»Cé/;z¤~ß¡Þ1”‡Ð-DEI‰xZåüb„(¢Iüð:[AXâ)FõìÐÆ(Ü´?V+ID)Í– #LQ„ SÕkPè ëÀwš› Á ղ҃آûíš3,~®è„ Îëù€_[Ïõ2gذîYÉ[oᮯ9ŸFdÙˆÌò~QPØn_ÎÊËËñù|Ô××ÓgæL&ôﯔž8ÁÁ7ÞˆîFZyF:ºdzX‰˜E E¦`qœ‹Ì¶^ê%fËôcQ,éŒ<«ð;WY„ëZ„L…xl 4ir,q*àŒ£µº 7°è§î÷&0+Û…yÄ'Äž§€B½—¬‰Ïã23éë­¤«Y¥íO<Ò‚ Í?6Iy‘å; eeó€~\‹ÖiÌU­Ç~˜=ÿügD¶J;wGWmmðºéƒè؆µìÚk9µyóZÄù§ñÄ Þ˜<™‚Ë/gÒO`‹Ò 3ðÎ;¿ôXñµ´PôÈ#ô¹é&Îíß`ݧL!£ÂÜ—”—žMSÁÚö'ž`Çÿý_¨‡ñ‹XÁĉ\þøã 8Œ'>[¡8?»kWˆa¶tåÊ0©ƒÆ“'±%&‚,‡ýõG†Ê±ˆ’[#9P2„ÚµÔûÆ÷‡?ÐxâöädB}>è)öþZ…@j¢nŽ©®$\æÂD8û° ¥sC´Sê<­,Þ|çô††V®\‰×ëeòäÉÆ ~Ü8†ʪU«¨¬¬dÇŽ!ÂS§Náv»y饗Ìž=;L‡ðàÁƒ >œË.» —ËÅo¼ÁøñãY¶lK–,¡¤¤„÷ߟ뮻‡ÃÛíŽ(O¼˜ööÛo‡t5:bÄz÷îͧŸ~ʾ}ûؾ};'N Ý;FŽÉÌ™3™?>?ùÉO(**¢ªª*BÆãûj~¿ŸÛ¶2hðPÎ{Í >¢Ííòòó±Úlx½^%x‘šFa×n¡÷·~¶™û÷b±Xؽ«˜_>ü[yoõJêë¹iÖ­œ8vŒ÷V+ü £ÇŽÃbµ†žÇÆÅ1bä¨v@ø}5­•NQ¢ßA]Ô]\8´×´(¦–LR%H·Br"Ø’QX-ÒÕçC©[9 œ‡Nm$­b´‰pÑxñÜÈQÀž¥UÖ°hÙ:©ìPHíÚ• ùKèµý¯¾JJAçZZ”2§(Ç2•ÁöËý¢Ûþýûiii¡ªªŠœÞº•#«WG\bÁdpèYeÅý­Â~fÂ{rEàg!<ÃÐK_”ÀŒÖ7k@bH{Á¹ìOkõ6Ž´¬¿[k jðEVÇp­UÀ ¨cÒ£nXÂnà€nìè\ý-oìX²‡ cþMïÙk\ÙÆQpùåì|ê)¦¼ú*HRÈÙï{óÍ¡·ìÁƒ)¼òJ:O˜@¡šíÐòå_·ŽÃ+V„HZLQ@— !GÚi=zpõÂ… NoÙÂZ…P,Ÿ3²Kÿô'œµµýñœ‹Rî*Eƒ¡¨vCÁ@ JõV{ø0–˜’óó9»{7²,“ܹ3±éé4V,^Ì–ùóÃ2«zP5méÒ2›†²2>ž7Ïð˜I:—™öµ¬Ÿf¥«VQºjù'rÓ{ïa‰‰!kð`²Ñ^3†Â+¯TDÙ_~9ê¹lë×€à¤'ž µkWòÆŽ¥¶´”ä.]¨9p€WÆŽ¥ï¬Y$wé‚->ž¡÷ÝÇiUûÒUWGÓÉ“¡ñ,’ÂèµŬ¢8±ge…®}¦Ü¤ y —A{üãÔ×âhÍ0jsY†úÐT^TD¹@Þ;b„ÌÖ˜ßþ–5÷ÝGõž=8ªÂ{g%IâÎÏ?oó?ï}ãô¾ñFRºtáø‡⪫ÃQUEfŸ>TlÞLÐç#µ{w’:†K«8Μ¡öðá°¹P;ÿõ¥¥¼®j#µ÷ï¾;$?ÒiôhÜqGXö2âÄÙ!”¶YSyyD€Ùn'.3“S["u¡.YÂÁ7ÞÀ–˜È]û÷óöM7QWZÊ5/½DÞøñ¬Sû»2ûõ£Ûµ×²íñÇ úÂË´5Ý̼OÌv;gwíbÝѧEEm–ÀjÖcÚ4z^}èù÷Ü• ² Æ“'I7 â­ã¨QÔ=jXFÚV¿§>pðz)~æ’:wfÓïOå¶mt5Šê={ð9ì^´ˆ™kÖ£Òô_úÈ#Ĥ¦RöÁl}ôQÊ7m" F€y)ÊZ¯Ý¬qqaÙF½4TP˜<£‰UA¢tL@7G”ø+qêX†H9‘¹¸+0XWê€9ê<-¸™ H¢|Ýf³Ù˜?>ÉÉÉܦjˆ>ùä“=z4¤Ch6›)++càÀØívòòòB:„7ß|3C† aÖ¬Y|öÙglÞ¼™Î;ÇøCŠŠŠèСÁ`²²2†ŠÕj¥³úãââBAI’Bß”M˜0Å‹ãõzIKK é–••ѳgOèÙ³'óçÏ'++‹;wÒ±cGÞxã ?~<£GfÙ²e¬^½š›nºé;½æK’D|Bn·;ìõ|•MÀj³qûÅwëÓOÑ~MKÏà©¿‡WŒ3ΰ4tömw~vAA!ÿõP+?C×nÝ#öùéC¿ ÛçnéÌŒ›ÃËûÇŒ»”1ã.ý^úgí€ÐÀét “­H~b”U#ðúH<„—&šˆÔ8Òƒ>ýbiŸØÃ E!ã%°YÀnDUWÐÖx0'ÒÚ𠳄‚õଇf4ù¡VW*2?úu 0FÈ€h‹–dµï«õ<Ù œpŸpŽ=‚cë hÞ¾]–C<¯ ¥¥Ô—–rlíZlIIdöi=m®¬4tÁ8ûÐOÕûüùçq·_þw¡ ²4T"’¡O,‘tãF$~Ÿ[tãÍ«Ÿ~P$\ƒOün"{’DÀ á½H¨ï•Úòᣕ(F?·¤¡”” É»[‡/õ±ŸR³7©Ãiâü=™zÛ÷ê«ì{õü̵]®¸‚Xé­ùÔ)\uut0 ôÚè_ÿšÑ¿þ5çÎa¶ÙØóÒKlY°€‘?ÿ9gŠ‹9·¯UcI#‘‘¢€‹¶~‡³ºšck×plíZö,ZÄÐûïgä/ÃÿS§ÒCÕó»\¬UV§Ñ£IÊËã½9s"€–v=8«ªØöè£l{ôѨß)¹ €}ÄÍ~ˆ£²’ÔÂB¬ññÄedpbÃ,v;ë~úÓ°ßÝ–NžÌ ¹s)œ<™s—žNj÷îýéO=ò?xâ ’òóÙ³pahŸãëׇ²€;Ÿ~šO?}^°“’•ÿ;å7F-‡íúåËA–ùlþ|*UíÅŽ£F…2x ˆ¨×:dÇuÍ¡CÔ:z®CBaƒ}]e"ÕÀ±=)Éð÷ˆA›.@)ëÆ½÷øq’‰lÑÇLöàÁNžÌgý+~Y럗£œO½\E3á}ÈÚz.ëö‘us@0WËkÔ¹"@ôøàEì!|衇"^Ó©Üwß}áüìÙaÏgÍš¥Ì£G‡½Þ¹sçÐ{÷ß¿á>;wCíµoÒ²³³#ÎÉÝB ˆ(5Ò!3©ßuËÌìð|îÌÙ·¶;Zí€ð«†zM1}”]Ï>*–»YtŽ«E—½KÊì:gÓ.8vI{6³r‹±‚É&+˜lÊ-Œé‚5ðß >'¸ÜЀæ eÔÌ&õ^tv´²ÓT5£¡Ý-1v°Å€YMwHjˆÔ¤þ“I!”T(¹AnQo6€¯œ%ÙD+¾E ~¿ð\[êüMM!çÃ$8àÑœ#MÃËGÍž´Û×?ÆDà"v‰üGÒ9}b&9t}Dù¼hŒÁbÀƬ»‰y±R@O7¯õY…ÌèBxQËòi¡ñ(ÜNi´öZ„Œ„Öç§}žE‡p™0‘g¡ÐÒ?íqBNS^{µ/,àó±hÐ l‰‰Âêµ%%œQ%\ŒœøÆãÇÙ÷Ê+ì{å&>ú(Ý®¹†òY5{6>§“ûµÞ2Ø8½e ïÍ™êqûàÞ{Ï;£ h¯õ5‹.?ø¹#F°þ¡‡B@P´ÆòrŠŸ{. ¾yÝu\ù÷¿““£€Èšö,ZÀÈ_þ’ž×_ϩ͛ñ:Q¿ø œÉ zï^VÜp `îž=¡×¯zá\uu$åå᪫ãðŠ”oRdiÜuud6}fÎYæàÒ¥”ò 3×®¥³š!=¸t)ŸþéO Ë?÷“Ÿy†½ÿúgvî$¨2ZêË÷EÀ‘Ñ»7Ù‚SÚwÖ,º^y¥ò¹ž `ôÃG}ÛUSCKuu¾)\o=§MêÏÂü€ä‚>ûË_(Ó‘áè³ô‰;†z/_Ž FDiAÌxamÕÖcYXc´à¤°ñÞ;\µkUªTD4 (-èd"œˆÎƒ’åÛ Wß?£~'m}ë9u*G×­—+,ˈào`0Gj¯'wé°Ÿþ”Â+®ˆÊ¤ÛníöŸd9¹ÛOB; üò&–EŠN¤¾ŒLsúÂÐÀ'bµX¢gúb$°˜”›dÉ¦ÒÆ›…A¤òT›ApÉ˨¬Ïûdu‘Ó±“º„…O,³ÓL͉M¦• 1)’À’¦t²QÈhRÔ[2á©@­¶FkŠªWoU (”¼ õ¶(À´Y¤"iWç`‹¥²¢—×¶%Œ­_Xƒ:`ßnׯÿñüxÎÎîÞͲk¯pº!œ$ȨlSÔ“¢8èÑ@¥H~M/T_ à5*ÈÂü õk•ry­OH;¾Ök”D+‘U­Ä1ÚÜ¢‰i‹„Zö]$šðÅÀXá»äŒÉj¥B OqÕÕ±Z-ëÍïr“œLz¯^¡×N~ü±¡ªýuGŽ„½ÿÎm·aÅïvãRu5Wß~;Óß|S‰ à¬dùò6 OÒ{õ¢çu×1pÎ$“‰çT)£àNù'Ÿ„J£ É[bbèwË-Ô9BZ÷õ½n¸¸­‘ë*•0eØpéÿüf»9BPGhóÞwrlÝ:º_{-yãdzáW¿2 @‰V½o».dÐ]wqlÍ6ÿùÏ4?ú<[b"ST`½gÑ¢0@˜=dỔ&Z_µs'çöï`ë‚È&ý¬¸ñF¼AÇP–E.›**zÏ=HÅ%h,+ãs³§P×ÛÉ?æ´¤ë3c)Âÿ6è®»ˆÍÈÀëp°ÿõ×Ãöë;{6½¦OÇ×ÒÂójyjÀë¥ó¥—ÒgæLÖèúÒ4;»kfU£Löz Û:Ä1o¡•.Nˆ£j`Î¥®GM´²ü:Цï[Ö·ø‰ìsÖÖÙ4õ}-ßZ LÀù™­[‘¼Þ°ùFÔóÕ‚ 9(¤2¹ºñØrö,Û{Œm=†-1‘{„ll»µÛŶºº:N>Íþ=Åí'ã+4¯ÇM—¼ìv@øu™,ËȲL0¨LóbÿZP犋¨Yú´¨¾(:- Λ ï!ЄŸ=2˜` ‚ìÙݺÀøt77­€Ï«‹búgY4*_՜ڀà´j-†ì A\"H*øËRWP­æÆ§<*„PäÌÖêâ!Ø'¸šš²r¯é«‰™?¿ðI‘ÒhΉÞA #E¹~#fON&!'‡S›73ZG‚±õ±Çýþ¨L°úÿ¯÷Œ¤ bâ§·lá䯆ÿ½´´q)’ؘuÀS$‚ )›¢Û*=1Ó_ ܨ:˜~!£:†ZFPË jÃK à¸GUd5ÀVÝœd毳۷‡~oÈ<œ§OG\óA¿ŸÏ<%J¦hãÈçˆ²ëÃ+VðTÇŽýãÙóÏâw¹¢öõÔ•”°eþ|v>ó G2 úhŽtKeeXÆË,̣￟ª½{9¾iŸ=ò;{ ³ÕŠ×éD2™øð¾ûBóŒßíÆì~î9þë_Q¯[¿Ë…8¹f ëׇ1\Hê³áØôóŸãs¹øý¡ï[¤^û[Ô{ŸËb—¨ÿüs6ª}šF Ê&”þqq²ÔÖ†]Óú§^—‡ƒ?ûYñV[@0h°­¸ÿÞ'žËÀ6o²$!ƒ¸[ZÂZ Vß|3ïÅÄ("ÖBFöôæÍ˜M¦¨òCN•ÜA,?{êØ‘Õñ•ª¾–¤Þbí %–ð€Ûõ¾6تݩɶxu*ŒÎMd‘HNc¡Už&Vÿ¡5èìYìD2‹ë¹¬˜6©ÀP7~§“fµ4Xd€ýºíW¿úiiiÌ;—ŒŒ ,X€Ýnç§?ýéãoû›aéé±cÇŽ±l™R3ñÀo r±íB—ÑvÛ·oç“O>áWjÀéí·ßæðáÃtïÞéÓ§ë×÷qãÆ´;9_“™L&‚Ao; ü:lóæÍlÞ¼™šššP¡Q¹X á½z47ÑKMz’"À޹ nÁ(αI—MÈêߟî×\ÃV•´À,d#âÔu0EŽ0¥Ñ’…Ò”¤y·5ÀIÀ] -p6¨”¼4ÐZŽ+\P")æÐŠò^Â…®¥6¢ÏF`ÐÙjÅãpDôKèi2p$Œ¢äí3×¾ñ„‹õãÃDd¦O/,É„->žCË–…O˜º›~ÌÅèœe}FA?ÞÄqgÄö«?­Ù?ísÌ‚c§c´¬ ÑJ¥µòµZ˺5]43áÙ¼~Þ xlН__Ðï“É®k¿A°SRÅ­6nâQŠZ2€t Ä%”¥.~”7¥x0YÀ€D5]Ø©J €ê ¥Zš¡>¨5kUبŽSár3âÜ!f#ý* Ë$œ\J øx…`©[X/õìÇú>ìo¢ý!99™{ï½—ãdzmÛ6®¹æš¨:„Ý»wgÚ´ilܸ‘mÛ¶‘ÀÝwß’hnnfïÞ½ø|>Š‹‹éÑ£¹¹¹ :4¤CØ»wo¦L™Â»ï¾ËHIIaΜ9lÛ¶éÓ§SSSömÛ˜¥¿ùkÏàx½,üÿì½w”å™öý«Ði¦'ôdr–! !$rZ„MÆ›h¢íeÍúhß×ß~»ëµwXÛ ‹m¢M¶&0Ø#$` Hˆ 0Ê£‘4ÍôtÏtªôþQU=OWW´»’€õ<çÔ©îêŠO×Su_w¸®$™L’vô=]‘#GrÙe—±dÉN>ùd-ZÄÉ'ŸL:æ©§žbóæÍ\vÙe$ ’Éd>HÑÖÖ†a,X°€^xµk×2EÈæøb6}ÈÈ9HÍpŠc€z5EQY8–k j¦›‰Æ°{ÎÍÀ¿:¿;÷\ºÖ­#¾aCÁ5{ÓÕEãSdN%7, SàYº”±Ö={3!Ü:è  ¨ A Ø“ræîäÔ@ç—íTy9ho'œïýà>›ÄN.3$£)*95DV ¢Ét%@V ¢Ë*º¬¢ÉrJ]±¿§•€ý›óÝUtIÅe IÁ,IÆdLIÁ”dLIræ2¦ìÎLIÂ’e²„…„%ÉXXØòŸKX’ â IÆÄžtTtT tTrÉD#€aªèº‚i(˜ºœÿlè2–!£k –!c2¦®`8놂® ¬›ßÆ”1 Ó°L{Âræ€dY`9s@ÂB’Lgn¡H&Šd Ë&Šl *ªb *:ªª ær9BááH†`(K0¬!MTK§,ÛOU:Auº‡ªt/ÕÙ8ÃúvËöP“í¦2‘@ÞnÂ.к@Û¹N›[CÊvš¤] e„ƒ „@ B@qîW d 4zuPº Ì°×#à„ïj©;Xrö‹NI@åN¨ÜÃv€Þ ‰.Ø›µ}¦=Ž'C!1[&":`uç{ÅlÚböOÖ9­Œð\pÇf°ø3±a×ÝÝÍ“O>‰¦iœëIýwÛÉ'ŸÌ1ÇÃóÏ?OGGï¿ÿ> , ™L²mÛ6²Ù,¿ùÍoÈd2|ó›ßäž{îÉë~òÉ'Ìš5‹ÓO?L&ÃÂ… ™7oO<ñO=õk×®åü#‡v¯½ö†apñÅnïµçž{ŽsÎ9‡1cÆäB;î8¦M›ÆâÅ‹ùè£Xºt)'Ÿ|r~žL&™3g—^z)---,p²–yj¸‡ÚP;˜múžº°òB«ø›uë­4LŸÎ¦?ÿ™ÏAÞèˆ4Θ‘?Æ”‹."6ÁÇìikcçÐzÇXÖ€Ù{âO~°ٳóß·/YÂæ7Þ`}{{IvF/Ó¢(ºôØRÕÎ詆 J `ô9u|&äLH™Q 1Êç¸ …ºm" ¬›6£n¾™Þ­[Ù¹l[ß|³è|÷§¥;;i_²€¾íÛ‘€-o¼Á–7ÞðRX%æ`×ãG¼ûãÓõé§C„2ŸC“ð¯û³ƒÂÚB`ÖÑÚZÄZèz 5 Øu>§3@Ó‡m8fqWáŒC7ŠhQ=ëfsKa¸×¸ýå—‘´pÓÁË%¨ @Y"ÛH–´T0e!£Ár£®v ³ä‚•Øö˜ IDATµ´éŒ­  +¨`…¬€!Â*e¤ ŒQ0¢ fDÆŒÈèå Y%DV ‘“ƒdå0šÔ4)€¦Ñ$ÕiX“°0]QÐÕºb6]Uíï²J– Y)LF ¡ 'Ñ̦©`6 2tÓK†®`êŠý=gÏMSÆ4%LÃJ–)ašRþ³å%Ór>#ÛsÉ8Ÿ] '»óˆœå~VÀrþ8I²%h)–=É–pãÚû±°Ï,Ý™ç$,Ý™ 'aé€!ë§8KsÖw¶5u K“± ËòÁ2¥ÂÂ8¿‡¼WPWsn",æÉí 5Ã9‚j–H(MYYŠH8K¤,Ce¬Ÿ²Š,åUÊG¥©¶—:}MænFY[Û»…Êõ *×ôRó~šöNHä ^Ñ• 6ƒÚf£ŠU.AÓ@Ž›¶ÞîVسVe!ƒiýФ9ƒÓy÷e${|„Ê \ë”O¸zNvx^톚ݽJÂ^ÍfîNšú½ªðþuÇýìÔÏN ë½RîóI"Œ2p8° ›¨Æ,µ?T­¾¾žo¼‘D"ÁOÈΕ+}¯ÅNÞ¯®(µy3ëïMëMu#²³n¾™ÄŽ|ì¡Ï7uO~÷»ü÷} XµC7æ¼cÂ/mXö8>Ä( äŽ–ç~,¥*¦Y™>UŒˆ¹©hŸˆ ê>ÝíËÃТƒnú¤éŒ9—ÈÂe:ŸEb½’8ÜZ¤P+AcÊë!8‚£Á˜©Òß\Ns9uuìŒ £[­%®V‘4+ÉZ!43€fÈYt+€.©d¥ ºl¬ !úÌ ´\MSy]WÑu•œD7TtSE·T4+€‚a)h’ýÙ4màa÷¯3Q°£N²d¢(²l (&ªªåtA’E•t‚R–°‘!¬gQ- ƒª©6³¨¦FÐÐPLÅ2‘-ÓÁ(Ò@¤O–mЦJH¦¦ 3ÝûAˆö! nÿ"[2Še¢ØW:0I*º=“ TI'€nÇü$ ª¤4‚VŽ23EÈÊÊæPR:JÚ@ÉšÈ9{²ÏÏY–ìD°2f@Æ’%{¢Ž‚±Î€1Ýk’%Ì€Œ”1C6€7Ug? IXš,Í!K•ÈI2RͽG Ýpæf€´!c…H[eôKåôHÕô¥OŠ¢%d»‚d Ù„LO€LR%Ó ·7DOwR ¤eè•!]fË-ˆŽ…h*#0¬ŠŠ±9ê{hž½—ªÓ³”¥3Dsý"F‚V@« - !-"¡õe{#oeLÿf&$Ú½m+g¯KÙ¨j»3í´½8Û²°Ö§£€±2”W‚TJ=È hÄŒ…  Á,T& É Z= ÅÁèµ™µsš /p2v“°qÒÂóE€ ûì’)ÔP•°Kû—ã(d5•ÿ‹ÎÖbDª*---TVVè®_¿žU«V1nÜ8TUeÛ¶mL›6P(ÄðáÃiii!pùå—3sæL®¸â /^Ì’%K1beeeœ{î¹,Y²„ºº:,ËbÛ¶m̘1ƒ@ Àˆ# ÀÔ¼yóxà‡Ã\}õÕŸÛ»ìÄOdáÂ…hšF4%‰PQQÁ¶mÛ˜8q"åååLœ8‘––êëëY¾|9MMM<ñÄ$ æÍ›ÇG}Ä+¯¼B[[wß}7ßýîw=z4---Ì;—±‚†ßµ­\ù@pȸ9ÀM×uFŽI]ݯ„>Þµ §MŒ(ˆ5{y0“¡{Õªüø\0½2²0’=ëz£}"{iÀgòJYH²@ìgÚö„›Šâ2§¥„È…7ÕEd"•KDõ Šë©Üã[€ÖÕÅÞ®.×^™%¢ä1νrR‰ÿEÜg.‘ µ¥¥`a4±ÉCé.Ýö_ˆq‡“À;6”‘?ñ~ƒ#î²aG]À()Þ;Z_Û/.’‰ÅíCž¨ ¨Ãé2ùºN“4ðvªèjljSáLõ€s‰^\Zz—@F¤ªw‰+D‡Û®ƒ§›jDT5Bh"H§‚63@ï„*6ÇÆ²´â>c*˜Èz&Ñ£ÕËÉiA¬´TÌêä—ç-v~Ô2°”!$e KÊ¥~*äeRŠr¥Ÿj¹—¨ÒGTNR«î¥Bî£\é§\î£BIR&¥ˆ&hh6ðÑMdÍDÎÙ`Hɨ}:xµW'Ø­êÈ¢öê¨ý:JÖ@¶L$Ù‰¨¹,]™•ÕÝŽö¦a‘ì`fÀõ˜¹è:cgGä†fWÿU• àuúưì7òë9 Ë>Ž‹ÝÜ »ÖÎù]s&ÃY&Y 9ŸuÓ®§Ëvf†aÔŠˆ‡,œ›"ÙAÇ"§Š{ØûÑ­ÂçuÀÙ>¢@X±¿Ë6wÒô™6!,C¥b¯[°%…œ`å@ͪ²b§f†ˆ¡* eAP+Á¬•ÈÖ„ÈV†ÉÆBôO/'S&S&Ó&×dKn4Ÿ¥¦òVâ>IIê³0¬ÊÀŠ lÒ`{?|¼…$q’dÙäVŸÊe VµäkatÈ¡Mæ@äÄG×-笺?óa¿£<»VCn´·C.AݾÅ' Ï‘õ&¤â‹Cx4ªÐ€ê Æa× ÆœAé p)Áä²ÐiØ‘À„sÛmvÆn#vÊhNp¾jžç–÷Yè>sªÿ¹ªD6Å¡4ýšƒ~Ën¹å–‚ïW^Y¨wÅWäÁ”ØFÍèÑ£›(Æoqï}ï{Ÿû»¬¹¹™ïÿûËnôÈêLš4©à»Ÿá‘‚†+Àܹs™;÷ËCÔ E8þø9CÆÍn===tttEEs‰ JQu{_Ì¢¡ X~BõùÍ›Î&û¾¥€£7µÎµã¼QÓ,Œêåk“¬£UóŸbf™(95€ÊQ£Hwwcöõy1½ºoîöîçòÆFÆœz*_~=™ôeÃ3*hz¢’ÏøðF½iU&Å©Ÿâç óç3áœsyôð$`Ók¯±½­­(ꤰF. ÜÛ^Üäeԭضh†Â:;w „ëqk~ÜD)襰™rö[]ƒ4›T¦ºcA:˜ =GV³­|íŒ`Mô¥NêÙéæ[¨Y`ŸF ¥JeQtÙ4±ca¦ý2MðSí0P,ƒ€¥£šS'¨g‰èiš†œ5QR&rÆDÎ()©_‡Œ•5°út¬¬99g å $ÝFQ–a#ÙFâ'9Âpzâ:ôä O·µK –-ÙìíMË[9ÃÖ[Í [ög›¼e3=»ÏDEp®¹ë˜ÒÑŠ$w¯d{?ˆ’!²ç7‘XÈ=/÷žÎ ÏêaÇÇÎÖÖüø0€fg™bjî[÷qry§Ñ(‡_~9«|€aï#è‰@™¦þ+†M²¢rzàwMèC0(‚‚ÃBÅ(ªš!¤d© ‚ªÚÀ)„²¨ÄˆXˆ¹õe\7á~²ËéQÃÆ ãùìê)´FÒÙ^Çîö;›éí-'Û´Ó<5l4[¡@£B´:K,¶‹†‘]”7öhÒ Öç¨ ïa›8œO¨JöÚá¹íi‡-)û:\²5Ñ¿d V>ätÐuвËB “TR7 iO¹ ôZv¦j øx»¶x¤pœ^ìúü¤!àöaˆB6dÑù©zžwCähCí åè•,Qqh¨Œr#C€p?¢ìóYònÞ¹Ea©ƒDAü´Ó,üSÜLŠÓÝðÙF/a$û±&zçâõ[”¦;×÷îEÎf ÒZ¼ÑÑpÏ_êí¥«µ%“)ˆ¦úBïäíïüu;[[Èöô±Sκé&VÜ{ïÐý†î\ö8U”FµÂüRBÅ{tã‹/²ñÅ Æ–—…´œBÁjwrï~ŠIg¼Ò.î¹u9ö¡ËQ!ê †) N¥c°ØÃ@}¡+#ž„pØÎœ«­ƒÀHÇ`çMt6¡òãSµµLÉ®Ãê—`H{M”]&ÒfƒôN‹Ôˆ'a‡ãý‰0@*lXöy$ °Ðà0Mj–ͲØî€0Õ™L' ¥9Ÿ]páj‹º„îKÇuD)BŸxÁ…(é FO,'Ÿ^¬˜Íán£:×$û8¸¼µ£ùç—UX¿Zäˆò,÷JùK³éŠûlom-È~°€-γÍOŽÇ+Õã]fz_Ë|0ߟbF†âqÌø½£ð¼CðŒ9—!·à]çD:e­˜Ev ºe C˜ 5tU¡*ÇEsf%äÚÒˆ0¹IarÓƒôTVÇÈBŠLPѨ”{iÈ-Eø¥ Ê:R¥…t>X—HdÇé‘b˜Uæñ2rØ$:Ž[nƒC½ ö¦m‡Înl¢Íó,êqîÛ.ªz¡*[m ‹p™Mb㢹²&˜˜ƒ1:,Ôà_àù,0FWÚ7)R¤u@¦„þïé,v¤1å ûVìzB÷w÷>/z­ µÿÅíöÛH]]-¡P›o¾I’ùÑþ™3ä‚ ÎÛ¯}Ü{ïo¸é¦kÿÇçòw÷ø—ù¿D£åôõõñÀ`šW\q MM_ª~„žæÞ¨E)¦Q ÍÁê¡Ä—¾â%ñ«Qô#Jñ ³Ë>Ñ€97ßÌòÄдüºS/ºˆ*G·må½÷’K&÷i¬ûýý†‚áq=ϲÇÈ÷]&[¶PdP| ê¯5³F˜¦IvË–BÑsºæá‡ó†§ØÎúÕ¯x­·whäöÀÇimmͳ_Bq*¨ì1>-Ÿqazî¯Ô‚_”^XÏmÀlàϸ©ß]ù1Úô#.ˆíŽvðY­3Å`Qít?LÛt…ì] 8ÂÝ.uõÒHÆ;?Öcç‹U9K[€WÀüºvî“ –£Ü„€ ¦ak&LØcÚÔ®ÄNˆ‚(—qÔP<Î×Ùä²(ºÑS1cAŒ‚âMbm¥ìyö>-„}‹Ž,¿çŠ7#Á žÜÉOFÄòÙ‡´çÿ`º}þµ±ÅõªÞídŸõäAÞ7f  )û<ÏýR ÅHçį|…îÙ»~}ÁþJ91¥AƪD¡þ®Ÿ¦¬Û×n4¼áaŸ¥‚ë-"d¨–2Äd¨¡RÞF3Ður²í4‰†!y,0Ó7Æá {ªêØ.d㈇ª OÎÐ4qÎÝÈèõ[Q—ë°B‹AÝjóߨLc—VÈ‹ }° j@u jSv °L²#Ѫpï¾ëq2¼ ÿ„@­-á@+k×’«²=Ðß½šzêþUιE}œS‡2etÁ‚TWW#I×_=555üô§?%‰pë­·î×>îºë.þV úï´'Ÿ|’-[¶Ø6Ïœ9Ÿ›ìÄçºüÖ[¾|9‹-âöÛo§§§‡x˲ úù¯µÕÕÕ²`Ám|ðÁ Þ}÷}N=õDn¼ñþò—·óë<úèBvïîdöì£8å”xóÍ·Y±bÆ5rå•—ÑۛȯûþûËI¥Ò´µm¢¡¡žéÓ`̘Qüæ7³wo7Ç?‡Y³f²lÙ –.]Îȑùüò‹øÍo§²²Ë2ûæQn½õÛȲÌ]wÝËí·ç¯6553iÒ„‚eUUv–»®ëX–=W”/~©TŽÏ‘NQòò_ü­¿ß6P²Y MóMWD’8ì éÙ¼™Ž+òûqÌ1L<ï<ôl–%?úÑé\Ž8‚©—]V´<¹c+…(—äcˆ×óÁ}÷a™&HÁòrê§Mã«¿ÿ=ÿô'^¸ì2ô\nP0Å)¤^±{S0ÝšA׈tÓ^B‚ñèÇüè5ò]ÃÔ5νiJ^mG?ÃÇð~v¢‘^Ãåµï|‡ôm· !¶ƒÜ®»î:,Ë"™LòéoéJ#Ñu ”©iôwtä„(Û FÝûL$SrËÆ\ò0ð¤ûâµm/nd –ÇÀ¿Œ€*žópG?NÀ®!¬ BY•]ÖD•c½Éö ¨í¹BY†¡±ªÆtp&$ÇT¯©¦§ºš¤\”ÓÏX¶Pµ»>qBëÁúú6?†â*äôeƹÆnÁáåäxSa5|ÉÂÿàuîD)Nã û8¼`ÅëÐ×õ£ÒwǯLé, ±)‹Í[û,Ͻ®aŽœˆ˜úÅ ¸Þç¡áyŽ9ýtªÇãÃô¸Þën:úhÆž~:[Þz‹ï¿_p\¯°¼H‰û™}Ûm|pç)×~ ­TÆIþwEÉç%M<ï<æ?ñJ €¬ª,þ§¢õ'?ñÙr '¨ä㼓}ª{.ª«cÆu×ß¼™uO=5P[kAÒpÈJ)ÔöËbGº'`Gíä9ÀY9%ÄÛ±“xŽ ø™´çF’JF±(‹¤Ý̳^ç„£–0ãâÕÔ¼Ù͈?È » v÷@§ÃÚ/8JÜÉtæIç<Ø\8a«zÍ÷ á È Ç[Tg*)âÔÿ;€¸¬Çžê÷„½`î„lriøiæYi¦ çü¥\EE·Þz+7nä½÷ÞãÜsÏ-©C8yòd¾úÕ¯²xñbZ[[©¨¨à†n “ÉJ¥Xµjº®³lÙ2¦L™Bss33gÎÌë~øáœ{î¹üéObõêÕÄb1®½öZ¶lÙ‚ Ð4ŸýìgŸ Ôuû￟d2I6k»ü\ÂQ£FqÙe—ñÎ;ïpâ‰'²xñbN<ñDR©T¾¾þõ¯ljÇãè‚Æòüùó™4i>úh#ý_cÛ¸q3--wbY·Ür½ï:^8Ó4øå/ÍQGMçã?åûßÿ»víbëÖmèºÎ}÷=D<ÞË÷¿+?ÿù/¹à‚óX½úcž|òY,¸K/ý¦ir×]÷2uêdyäw<øà/X²ä=Z[—qÍ5WpÏ=¿Î3—Ë ó÷Á—­@¨i9zzöbF>JÇ©­­á£ºòâšÇsÌ—¢SŒl–qgElÂæþßÿ›_¾õ/áÍÛogׇ5$ÒÔ„¥ª€0›J‘ܵ £è:áŸþ‰¥ÿþïh©Tq¿f2¾{é½{}£u¥€¡ešœö󟪬dÆu×å—ÿÊWø~o/­wÜÁ[ŽîÄàu‹Þú-o=¥˜Zc  Î5tŠE{ î5X\Pó€Co”À/J*ã_ÿéõØ[Kés¨4Ù14%Iò­ôF]\#±gëÖ¼±'â_ºÑ VyÎk9°K¸Ç¼Ž`M|®KÀÆ—_Î/ÛðÒKü¼ªŠÆéÓ¹ðùçIuvv©D$RL±–=Î@Å'‚*:ðô®.V:Ä`âvºAtûМ2@ÚT+;˜Z º£5¬g«™Î§ý‡Ó¿­Ü¦ù4 '£gt54€!)”Õ¤8vÌû3YÃvò4:ÇH0 Ã+{œnäÐ%ƒªp@ ë˜9xÁqΔKðT¬ X`öØ/ËyhI!‚ŽìKÐÙa¹}Á² ‘DâP³ª´’+M‡ªíÝ»—Gy]×ùÚ×¾æ»Îi§Æ¼yóxöÙgÙ±c­­­yÂM›6‘Ëåx衇èëëãꫯ.Ð!\³f 3gÎ䬳Î"—ËñÛßþ–ã?ž‡zˆ§Ÿ~šµk×òòË/3aÂZZZPU50?öÌ3Ïäu]=ĹsçrÔQG±hÑ"V¯^Í{ï½Ç‰'ž˜Ÿ÷öö2kÖ,.¹ä’ÂåË—‹ÅˆF£,\¸sÎ9gP‰Š¿†6~üX,¸þþ=ô8ßùN¡ÄÈgŸ­çü3ápˆ·ÞZÌ-·\H(ŠL}}=–e²uëv_üUTUÍÛ'’SôøÑGŸðÆo Y¼ø=n¹åzŽ;nŠâ®cå×u[$!N£(JþÕÂx¼‡1cF‘N§œï½ ^A8aΜ£‹l6—ïôÝLÓdݺu477SUåOź{÷núúú?~ü>÷—hoçáÙ³‰ψ¹s1w.#O8òaØyà ´ÞqñÍ› ^¦F6ËÊ_þ2ÿÒv_r{Ö¬aÏš5ÔMJlÂzÚÚ˜rÑEÔ8:„Î>›­­lúóŸ‹Î£§­åÎ>)ñr÷{ñû–ïZ±YUÙîèù‰m­£—èå/o­¡X7#¦ði‚‘%‚:ÅrVª0÷K5õ’øE¼FJ©ˆ„ÄP;ôM*5ðþ'¦†=@‘CÔôËx€‰ øš<çÑ<âoÃÉ“&¡Hñuë ŒqÙDÃØœ5Î|;pzj\7¬ ØÝ]Ðf‚€©5Pv• LL«àes[ÍêIQF5ts$1Óø)=k‰}Gú½‹¡{³Mˆñ©½PðkùŒS¯^©>Ü4oIØb=žäƦPò¦ Ô SXCè7î,ŸýB!ÛªHÚôÙ‡wÌ‹DYPH$>›üjÀ½ÄAâsH¤úW(Í"Í Î4oÍ«÷y¦{o€Bj¿T{QjŠk³-üåzJ½ºV¯æA§Ä Xâ‚bÆgÙ§ß½Î;ï5„|œx^(1 ê•—I™”­F@¬>Τ1hvÐfN$½7‚¹J¶s»H.çý“Ž%9º¢ÐPµ‡æHY2l®„Æ º¢:„³`ål™¦^çøe¹ÿ‘[ìfx!ÃùNiÚ°í×d¡·k ,Â4º,¤ Øéã‘ ¨Š9´ ;Ý<§Á:ü˜î€Õ82‡ª544pë­·’L&yì±ÇŠE·mÛÆ³Ï>Kmm-‹/.áp˜¦¦&âñ8Ñh”¹sçúê¶µµñÊ+¯P]]Í;ï¼Ã5×\ìY³ Öqõ ãñ8O>ùäâý6f̘|ºç°aÃX´hS§N-Z¯¼¼œ ¶Ør¹Ï>û,§žz*õvCoo/--wRVVÆ7^M.§qÿý³sç.Ž=v6UUH’D__?'Ž' !Ë2--wøú×/fΜY\ý·xúéعs7µµ54660{öQôôĉŪ0M‹¾¾~&Mš€¢(TWÛø¢¬,B à׿~ŒeË>¤»»‡3Î8…ë®»’xÃ0¸âŠKþ:¡aôõõ …ÈdÒ¤ÓidY¡³séôXLS§½½ƒI“¦”‹xúé§ ‡Ã|ðÁÌŸ?ŸX,VðûÖ­[ùË_þByy9Û·oçä“OÔ@u_T½7Ò»q#Ÿ<ö˜/Ø=%¢\P;iz:MO[[kmi)ò°úso)o°ht|æhïY%ÀÏp'mÊ ÊRò&~¤1C×éßµ«¤ÑéÕ‡S:ëŽ>šŽåË ¢ŠÞ}(‚!æG’#QXûãg$J>†0$Nˆ›Áò’‰F˜bb'÷¿s#Æ~Œ¶¦n` Æ»c8Ýõ“'cíÜÉžD‚ ;a1Y¦{Ý:FxÀ{îª'R˜qŒ²Æ{AIPÈ$cÙ†Ýpä Œp¢Ðäe¤ÉvjèF¢š8ìf„µƒºö=D×÷!} ¬Þlt5µŽ‘†á0ñmÛŠH{ük*½,¯*¥õ½$Q^à"F³>ÿ¯HR|À¡Ÿ£G¬¥DdÒò9w/[q)`d”¹âKS¥tݸ.ENÆ ×ì'µ#‚@£D´p0½W(f÷Åh¥QZ? WàõŒ5IxV‹k¥Îͯ¾ÑòüW=š\*EzψVvÛ€jš»`Ú‹P·"KÓœöµ7ó•ͼX1Ÿçý+³Èý%dÓ~®ý*5Lg͸#ytÜUŒýêf®ÞͰìNƘ[iV:fvиe7£Ö&×Ù‡Ò•ÂÜl¢í‚xöfì:¿ˆ54*P‚@¨nÞºÃ@jÅ!›…^Ã>o7ÝZB wr®+­©~;ÐÙîÇŒãØÊrhkmC»…ŠŠ ¾õ­ovMÜÚµkYµjcÇŽEUU:::˜:u*Á+K& IDAT`aÆåu/½ôRf̘Á7¿ùMÞzë-–,YBss3eeeœ}öÙ,Y²$_/×ÑÑÁGªª477ç£2±XŒÍ›7óÔSOQ]]ý¹êžp <ùä“hšF0$‰PYYIGGãǧ¬¬ŒñãÇÓÒÒBmm-Ë—/§®®ŽÇ{Œd2ÉñÇŸ×!\¿~=wß}7\p­­­lu2e®¿þú¿ê(á¿ýÛ?-û—ù?ß¿ÿýÂúÕï|çÛ߯¿Þ¾W/¾ø«Ì›w,ÑüoÞ@wÝÙ³`ÆŒi\wÝ7 ÖùÞ÷nüÒöës$õööÒÜ<œD¢EQ…å ’É$ýýýí"6oÞÌ‚ øä“Oxçw8ï¼B–¡… æCð---y@¸cÇ>ùä“üz;vì c;ò÷;²±?/u€øƒ¯{_ˬý<‡Ád2À?]RÜw›À^·¯¡Ëéìï}ºÃÇÈå°V¯fÕƒú¦?áclÕM›Æ„sΡé„Ж,a㫯ҹzu,e@˜”&K¨=ì0&ÍŸÀ{wÜdYEÆ©åxd‡Ú¡„ºaîç𻇼L´~÷ƒ×ð™3Ÿ†Í7á.ƒ$d™Zì´3å•Wˆ;Û¾çkðÉ<£ž(e…ã•_Œ¶Z åÀÐ@ËØúlÕ2Ä‚ÃÇckRŒÇ÷‹WîÅÄY ¬š@ ¢‚Y·ÜÂÚgŸ¥{Æ"g¢ be³EZ¶nä4‡_«AÓvhx¢=:ã㛸ò¸'˜4r=¿?üÞ©:Ήõd–G`)°¬×`›ÖÄ6©ÉU¬Tìq:Ôq:Õ“âÄ.ï¡vLGÊ1;±ŒÃ“Ÿ0!ÕÆ”{‘ÖYöÁÎÔçœtPxpèP–€ñq›½Ì$X)çA’°å*ÜôÔÝNäÏ•žïà 6§ÔaÂon­ô¡j?øÁŠ–yu½‚.pt›+hÊ)§,;vl^„ý»ßý®ï6¢¡kç}žmøðáE:„7ÝtSÁ÷É“'|ß»ï¾{Èhj_|@X]]ͰaÍ(ŠJuuŒH$BMM ýý dY¡ªªšªªjB¡ÐêâÃá0uuuž®“/ºˆ¸×(²,6lØP$&Z §Óišššö¹îºuëŠ ÿÓuûúúèííeøðá‡ôøÙ±vìXÏIߨŸ}&€MmmÐÖfÿ0q¢=9mëÖ­466ú¦’ìÏy&€Íî¾/¼°äºõ_œï/{óKáu?çJÈ~€Äò€/Haó¯Œq€k@æå%Ö¬)’yKaíÒnàcç8UÀÉÎò;°S6“ÀØ‘: [t<çXÆÃ€1˜°ÃŽPîìØ!÷ öçnËam†ôNèîõYèÓì±"¥j‰ºvnô*µsg ööS©H:ø“½ìËùå½Ëd' ƒKï¾Ì}8Þüds¬7i˼iŒÞãøõ•åxky¤Äù9ÖJõ³¼qãí1ýU)áÔóFae€æÅ^™¯Nh©ÿ@tÐͺùfB••d VÜsOÉ{+›Lò^K‹ïÿ.½6Œ_Ñq(J_ìªthÞc_…Ëtš&îâü/rÚÜ¿°ó°a|zôTÖÏ›Ì'æalMŽ&ÙQI¢½’¾®(éþéL˜\.„••з«tuÖÑõi‡ç£†#yiü|†5u0eÄZŽßÊ)³ÞbòÞõ¨ïê˜ÃGËlfßãÂ=ËñD¹5ÅAu¦±5g:“nƒÐFì=c÷{’Lƒzi×1µ×™»ò.CôñCí‹ÑÊʽ:Ð-÷Å„@€¿ýÛ›|u]× ‡#/\ fµÖ¶mÛ5ÊNÛ´iÌ›7Ã;ŒO?ý´¨Æ°¶¶¶(ì~úé§íWÓ4î¾ûî"¯_[½z5|å+_ÙçºbñðZ·­­U«VåóéõñÆ>üqN=õÔý¹ÿ“ã·FÈP;4Þ¨0þl³bͦ){IAÄÚ2‘MÔ•Ëb“È|;µJõ¬—g-•ãÙ0âÝôå ¶ôáŽÝ¶xÐ1Ô^Îó~,6:¯Âzçs6ã¨ZÇ@]a[ð,éì´ ôm°[·½þg†˜®*^—ê.Ü>pAl)io:Þ` Îý|Øe—q’ÔüÖ‚$;:ØÑÚŠ3ýškòF>> Ä/-Þ+âiþ)˜^å÷% ±?™~R¥j‘Åã•Õ×ç3>þÝïÐÒ颚9?öR<Ž|@t©ˆ›¸~©tR(NŸ÷¦„–JCõ¦•–J'öþäïaGMÃôéL¿öZúwï¦M °ÁçüÜýÔNžL¨ªŠŽ>ð{ï» 0zÏ Ø´ÔN—BÅÃ}Ô„6p\ÍNm‚P“‚QD‹ÈE‚dC´ŠU£ÒßXNWu{«kÙÕÐÈÎÚal“FÑIqµS•é ™•êQ*4ô¨ÊáeŸ S¦Â„n(³oT­ã‘ÙÚ Z8ˆPÑä4”©ÍBþÊÖÂèõP·â=HAB³Ÿ âsrv ²Þ¹Þœð?XmëÖ­¾6Ó—µ~úéüò—¿z9°¦ ƒҧ_P@(IÑ`QåPÐuÜxã´´´pÚi§1}út‰;wîà¼óÎ㥗^âí·ßæšk®ù/ï_–墿R­¾¾~¿Ù…fÏž}Àû¢ººš‰Btí@ÿ`œëþîsêÔ©D£ÑÏí<‡ÚÁiAìtK‘Âò11ê 2Ùº@NÅfù ;“Ëøé.["AWþ?B HÎÁ\r0I8 éLº 9s€¾=í`¶vä!瀽“€žkÊb;ÿGc“I ƒ‰ÔäüP‹]($ ;í·7–,û¼kˆ ¤ýzS5@öÊ¢@º_ú(%@‚w}%`ÃK/ÙŸC!v´¶Ú‘ÆL†•÷ÜS”v(û€Cßó ˜võÕ¬zàßÔ`w~õ|&pìí·#«*_}•Ý«Wûjæ‰×R1|8S/¹„5?Nº«Ë BqÚq©¨¢”(‘µ‡žÿ>bÞ<6¿þz*”®Ñ–®P^_Ïôk•WÜsÙD‚sçRwØaùt}?ˆF9úÖ[Ivt°æ±Çe”ök¥J,`Ø1Ç0âøãHuuññãÝ[“¾úUe¶lº;ß×qFžpG|ã¬ñE´TŠU÷ߟ¾¥À±[£\ ec¡CH‡ª~ˆuCmÔaÒ ¤É™ÐgÚCS– ¶F ‡ŠQ Úœ»骩go}-‰`v ð«†þN¤^{‡û oìHCÕ¨¨i”âB£r„êrP F…‚’°‚ÒËÖ=ä.¨ØÀn°vƒµ¬½`vCª4ݽ£°#…}:Ù MÓ¸æškH$˜¦É¯ýkº»»ùû¿ÿ{úûû¹Gp Ö¾ûÝï”ÈýèG<ôÐClÞ¼UU¹í¶Ûe™çž{Ž 6ìsûÃ…q{ ÚÝwß]”꺿ë­\¹’E‹ñw÷wùeÛ·oçÞ{ïå'?ùÉ1Ô¾x€ð‹Ðª««‹¢B3fÌ`ÆŒyÐ:_ðØþ—ñ¸¢ JD#¶æææ|±ó¾Úi§vÀû¢®®® ö@ÿ`œëþîÓ/¿þPžçP;xŸ0:QªÄMŠÈ8€Èp@^¹3•  /Êw‹;IØBÐM2|Gœ]·ÁžnÙ†bÖ*”™È8sW‹ÐýÍKä Ö«À Øvœ¬êU(«Æ68'obëõ;Àê‚\âý6ILãÔðO±ô¦æAqÔ©ÁšT€H²ÌqNPg'oƉ@È%À¦Qàä¯AÓøè‘G%ÎÂã4÷õþÏ~VòœD›—ªJ¨²2/2xûEÎa°(_ß¶m¼)ôƒ\ÿþô¡÷?ÉìÙÃRG’¡à=ŒF‹HcÄýk}}´z¶õ:ð¹OFwíN¹xoÀ€dÏ®åËÙ½Êtê´Åùâþ°¤#"ßϪŠâ0’[¦‰‘˱úá‡Yóøã̹í6VüêW¾Gn µ—YVœHâìø`\`dgîó§ûYî¥ ¢«¡ée©jTÇÚinhG9 V“Õ )Ž(`'v~ù2жA·i;{À @& Ù€ýYBY™Ayä*°Aªs¼en*€i— tûb*u8³~ŒÍ4šâ`&”ù·¾¾>îºë.&NœÈܹsy饗¸óÎ; „Ö/¹äÆÇÚµkùÃþÀ¼yó˜;w.Éd’ûî»2Ç9 9ú裑e™9sæðÙgŸÑÑÑÁêÕ«ùÆ7¾ÁÈ‘#Y³f ¯¼ò §Ÿ~:³fÍ¢§§‡|K/½”®®.ÅŽ ÜvÛmüÇü¦iòƒü€;î¸ãô‡aÜÿý$ 4ÍvÛ¹:„£Gæ²Ë.ãÝwßeÞ¼y¼óÎ;Ì›7þþ~žyæÚÚÚ¸âŠ+èî«‹œ WÖÞÞÎâÅ‹÷Û9þEkº®û* d³Ù/\9Ù j_èöe:_&@6?ÿæ2tº51¢ø»(1"Òº‡;ÉMžH;žK;ÿ0˜dÀ"c@[/#@?QnƒâT8?°ä’7Ä€ïbƒ¸ p0Õ¢Õ6a§ˆU9'Üå ½.ÐöBgÂ.ÚãLý‚!ëeô2ãZø×¡Y>}\Jž¦´°#8Áh”Õ=„iyýS/ð*Ehå%{ò‚+„k2s¹ýJ_5Xƒ“¸]rëVÞùç.™»â×O¥"nÞ¨Ÿ\b]¿k)u}ƒ‘…É>ÿ³»ío¾É¶7ßôÿ.ÕoÞÏ^íÍ',nWÑÜŒiô9™8–a€aÝw~×ë×Ã9IQuÒIÊË™pöÙ¼ó£±îùç± Ã0ò¬Ü’ç¯Y”S’EíC;õÒ­‰ôꕚÂÙÏãç 6iPÕ ±Nñ Ô† ¼ÂB­ÇÎÛ,sÆzh„XÀ^·»¶XЩÁ.mÀ'ä>G*çVÌ™"*ƒö¤8’X`ê6먮AFÈ"p¯Ç½öCÕêëë¹é¦›e™ßÿþ÷¾ë¼öÚkƒA.ºè"†Îܹsiii¡²²’ &¸ú꫉Åbüú׿榛nâ¾ûîãŠ+®`úôé¬^½šW^y…@ À•W^ÉÒ¥K¹ñƹð ™2e óçÏgáÂ…¥2Т䵱½zq³=ýôÓœ}öÙŒ3† ΂O<‘9sæðÖ[o±jÕª<tçñxœ3fpÑEåKYŽ<òHV®\ @WWO=õW^y%wß}7†aäï¡l`ææÂÒÝ0عsÇ Û¥Ói®¹æ.\X°üwÞáƒ>`ÆŒœzê©€-bá"•ŠŠC\»»»»¬ìóèç/5 Ü´i+ݽé‚eý‰næÎ“÷ìÙc{;†of¨¶žžZ[[9ûì³øøãyùå—9ÿüóóš5ÞTÈwß}—áÇ3fÌ–-[Æ›o¾é8f-þáþás»–/SÊæPzéçì1tš¨u'zóC>F½Ái„+Y!¼µ@pгí #{b„ÏË€é5´ý„Â]ÃRLO Ô*“!†²HµØa¨sAYì¼®]vD0Ûk—[0™À6ì2Öl¹Œ‘~Лrèm)Å„¬¬Dëï·xÏúîþOûÙÏ{ÆÄ&L —LòÙÓO“ضO~÷;²‰©Ý»}Á¤´Ë @¬,ôa“ííèét8™pöÙ48Ì{{ׯgÝsÏ ¦/J¼@F€Zƒ€ñR饥@!%–y£¿b”ÒœzûCöô¡9Ƚ- Üüú«¯½½hüÈ•cÆ`¤Ó$u“ÀpÛŽ÷ß ý½÷xû‡?,ŠÀʪʱƒåºçžcïúõù½!8•‚ÎøSËE\×Adx%øKg¸ÛhÂ3( $,ˆe & { ¶%e¤rç$t VrÖÀqÓÎXw³#ú»9çÖ!¨C0UX5$:ZÜg_›(µÌCÕvïÞÍwÞI4åꫯæ¿(¬Á5j_|1===œzꩼøâ‹ùßR©ÔÔÔJ¥xûí·I¥REÇ?~<óçϧ··—“N:‰Gy„eË– z^ñxœêêjúûûó‘ºCÝ&L˜@<ç¾û¡%K–ø’–——JD ‰Åb¼üòˬ]»–¾¾¾’šÛ³Y¦I0¨€¤M›6ïs»H$’/çÛªU«¸öÚkyàò€ðƒ> ½½üÇ¹á†æúëkØŽÆÖ.\˜¿_¢Ñ(\pÁAÓPÿ_ {)ª'üMþûÛ¯½@oûN>y–e’L&Y¸ðYª«+9ê¨w\C (ïáÅ_¤³³“³Ï>›öövV­ZÅ‚ xøá‡©©©)"ýðÃyá…¸ôÒK3f ³gÏföìÙ$ žx≡Nj_Ц Fì1bEÙ ÑH3#H&Øì¬7ò’^cY$8ñFyTŠ…ÏEpt ¯rì€_T±§šª±‹«±]ýªs’{mÍ1½´>ˆ§lí±¸sí½ D.E97r*Fœ\àìê.ºçåN^r×ØÍ ÀÙM‡ ×ÔËfÁ0|#.ðç›oIbò…2þoþ†Æ3hœ>‰çÇÛÿøl|å•’'^£_ ©Ÿ6 ­¿Ÿ½k×F¨d™ÁXÈÄãhétѾÛ^y…¶W^)4ƒEÓü•¨·?µr~µ•^ðÈ>öà  JÞÇùûé'–ŠìJ>ŽËs¿+¦¿¶ÏÁ˜[KfÓù¯¦O'µg½ííE}ä'3X+8†®ó¾@þ¥zÆŒ ËŒë¸ Žw e„yŠÔlÃÇ™@% ¤²Ç±#ünŠxSj3PÝÁHN™¤²OMcà™c@74ãLºà°ÊP¨ß¨ûüwëv8çh8σCÙ,X@?8̺·ÝvS§NeÆŒlÙ²MÓhhh`ݺuär9vïÞÍ‚ Ðu§žzŠÕ«WóÈ#pÆgpÒI'±k×.R©úÓŸ8ᄈÇ㘦ICCŸ~ú)º®³k×.û¿ÈdˆÇã\~ùåÌ;—3fðÖ[oñàƒrýõ×S^^~H…êçÎËSO=…®Û•œ¡PˆŠŠ :;;;v,eeeŒ;–––b±Ë—/'‹ñðÃÓßßϱÇ›×!\»vm¾¾Ðå¿eùsƒöðÓI$’ÔÔİ,‹t:C:!T÷¹ÝŽ;èéé¡££ƒ?þñüà? ¡¡5kÖظgžy&wÞ9«®êç‘Gj8Tj"»víÂ0Œ|_»üˆ#Ž„û}“ä²üç¿~ŸÉGÌ"‰p÷ÿžß¿øFþ÷l6GMM5çŸÎçæ©ù¢¶l6Ë7¿ùM~þóŸÛÞñd’ 'FFéëë+„ÕÕÕœuÖYEûúÃþÀùçŸ?Ô©CíKÑ\·(nîêŠÇójÖ‰ÆiX‰Íæ9Ú*½,Š~ú†.ørSQÝZÅ2ŠMFSæ¤o)[dZ ƒ$-º,l=iOÉ~èvÒÃâ6>Ì×ù¸²aáø.×LÈ12ÝÚÈd§¹'¯È Ê $CPÕr Ó6<5gJë¶ìãºä8¹-[ˆ ý/ùˆ2¦e±ö™gX÷Ì3ƒF¿ö eY¦¼¦†Œ¢ƒ]gí3Ïä¿7ΜIý´it´¶¢§ÓE b_(^M@? 2X´ªTЧ…ôÐ+ïáw ‘ØGfß©®Þóóësñüü´aóÒ"óà/K"ÖÉ‚T³T½§ÞßϺgžñÕŒ­Õ¯Oäýâ%˜ Î ÖÅÙ&ˆ±¨>â–íévÆ…¹s‡²L1»*øËܸ Ww=Iêú ªê¤D*!b@ƒ2vºgÚ°§¤Cbã‚ÓŒE‡‘Xk*¦ÀŽÞÄ&±‚CAå7ÐüعúÓŸ|÷Æ<üðÃß] ùúë¯,߸q#7ÚÊÐÿùŸÿé»Í–-[زe @QJâ}÷ÝwÈßk#GŽ,Òa¼å–[ ¾ÿwtÝvÕUW}®ïíD"Aee%Š"ÓÑÑA$F7§1²,‹ùóç“Ëåhnn΃¾K.¹„·Þz+¯)é×F†­[íùÁn¯¾új>SàÜsÏå§?ý)S§Ný«H=0qPI²,þí¾¬(üóÓ0l8°Ë)°}˜õë7rÌ1G3qâø!KXh#FŒø/o3vìØüC2mÑ4:;;÷Kša¨ µÏ«½þúëô÷÷³nݺ‚ú7zazŒz¯Á …é”íØü §0鈮$ÛH ¸À ›¤AQl!yEI`»1e0%ÇHÖláhSK#g3ýeMÈÐo@Ê uë]¢ Í9÷$9؆jÊCö¬¥”JcŽ•[. WE°^] ²ßAqgê­²HZ‘É´`»DQÓPÀ¡7Mu"s^Ðbe2ìxýõ|dÓ ÄÿXÏdìtVË4²Tº#ø§Ñzï)?`3˜ˆº\bß~@Xöq~ˆ2&ÅR ¥ozÆ„ø,ŸsQ(jRHÌb”hƒ~JŒ×Á¢ûJÝ-ÒÝã¸Q?Õ1g Å€ Ê«AŠa‡óËÏ€òTí…†nH¦aOÎþنB’!ñ>5„g–äŒ#7ãaó,ŠYv*ie¢ ˆ„@ €p¹íxŠ9!@3 FÖ~~ô2@,•ÄN'Oyœ7~÷V¹àH;T5„#FŒ`éÒ¥ÿkÞO±Xlè%½fG ƒr¹Ü~éCÎ8ã ß~>å”SÝöòË¡¥…ƒ%ìéé!—Ë`\ÙºiÓ¦ ÂýÚI È- l/Ñk/>É„)§( 7Üp5úÓC`Ч­_¿žÖÖVV®\ÉÓO?ÍüùóùðÃyôÑG …By]Å_üâTWWså•W²hÑ"^ýuÊÊÊÈårüñ<üðÃ\}õÕC:Ô¾ÐmܸqhšF]]{M4lÜH¡›Š`à¸).àÛâAó¬$‚@—¤&ìùp"m’^Á’¶BË|™¬MOo:ѶŒ5Õs½öbý¢7-Sd*•„ójrŒ×rÇhl!„ò2P@©Å–¥p­[WCÃÍ{s-{S8XÊÕ{m”¬÷@¶r}Уº}(ÖQYC>@aJÞ¾ê㼟MŸ¹åå"Æžuë^x½Ÿ}Vtß4͞ͱ·ßNÑGÒ»e ¸òJ2]]E„"ÞÉ›ll,l Á¢¤Ã½÷’ëí-Xßbp‚žRÕ=‘ ÈTQb–àÏI¦—÷zÓAÅÿÇʇ ÃÔ4R]]û¥$&{>… $BÿøÉrˆl¡î¸K;SĹ¿Ë]áÎ(vq]­ó@AÎB( ¡n¨é„qê‡Dzr6÷“;^úèa‡Ùµ­‰„oš¯›Ú™f@b4ë¹r Ê ˆ¦ ”tDe 1Yéüc€,KŒ¦ç踩r~pèØÃá0ÇsÌÿªw”aü÷E;LÓømÿÅlO)EU©©©EVºººillB–e:÷ì> G|õÕW‰Çã‡ô*Ÿ|òI.¿üò¢åçœs---C€p›,Y «’øÿÿå_ù›ÓOàÈÉ#( ùû( 3yòD†š¿‡íŒ3ÎàŒ3Î@QB¡]t]]]Ô×ר&óUW]•§IŸ>}z¾0Ù¥kþú׿þ¥¥#j=m¼CR[[K jÐ+@è”éQG9ëº,Eq:hË åжVn "‚;qrkzDÆSÃc‚?‹¦h¨»ç_…ÊVƒŨª©Æ1Vk´v˜a=I;å3•³ KH§u¦Z ²º­ŸÖcØÑÀ>Á¨Õ=ƾ7*ä—F¸¿¦‚_*§hF”ª£+ˆƒÔ~8ë^x¡`ÿ3g2rÞ<&_pU£FñØ 'äAÚ`’ ^ »?ו޳‡÷|RàDæÝ×¾R½çá¾íO_tRñ9¦×¹â×ï~i×~ 4XQžÍbùBw_±qã˜pÎ9¬¼ï>LM´²dûÆJîi×'â¦F* š{¡¶*; Tëèÿ¹!Ä*ì°|È#!4B{!¶†uÙ"ð©,ôëŽü˧ŸRG1«¬Xßç4WêÂU—Ù:¼b‚j?ßüdxĨ½˜qŽ[ŽMRâЦŒþð‡?ÌÛGugžy&ï¾û.ªªæÁâŽ;øío‹,ËÜxãû´U~õ«_qóÍ7#I¿üå/¹õÖ[Ù´ikÖ¬9 e1étšM›6åõW¬XÁŒÓÿ[ûª¯¯£¼\"™Üù¿î½mYö5cÆayíºúòüï»¶ÐãÍž=»àùÖ·àÑGíùÁh¹\Žt:Muuõ_µ}v@áôiSå À¹gÎv‚ nÂOyy9³ôyú= IDATg5d û´²²²<¨s[0,Ò2¬¸wc±XQjÃj_¶¦9Nñ7¯f˜h¨¦?s°=áíÖš ãxÀŸ¹Ó+9±¿†•vÙe¹ëŸ{.Ÿé2‘VbóÍ ³mPª ¸QÀ€ÓÛmËÖJB¦vk6énç'¢ UèoЧæ¯z ƒÜ+]`b¼¸í¦a É2Çÿàdz{Yqï½ûì?d ²ž;ÏõöòÞ\´} ¡¼¡Í¯½Æ²»îBK§}Å`€`Ì)§0bî\>ýýïéikËëç –2zÔM7®ªYFëïg™PÇ4Øq ö«™4‰)\à #›eÙ]w‚3Ó!uÖÚ„}ÁxA—÷¿p÷_¿(d¸ô^sïÖ­¬zè!$YƲ,$EÁ2ͼY ˆûösïIÀ„óΣÞ!r~ì±ìXº”Ž¥KÙüÆEàܽӨ‘ðì4ò]@Ô€Ê$Ä’P· Ê‚6ÙK8 JÔFQ’[¨ëänGC]öÿ±wÞáQUùÿMϤLzH@Bï%CGzGAV±+ ®».[¾»¿uººDTT,HQéH¥&¡†B JB*émf2å÷Çd.SCMh÷õü#>6s´S–.¥ª.õFmM †:gT…·7²º^t‹ka¥øÜ9a4ò±7ßdà?ÿÉ÷Þ³ßÿÒ¥Ô\»€A§ãÈÂ…èëê»5d²>áénîŸ+á®ò÷·øèËÊêýEDŠÑH`TCÿ÷?¢êæÛ¸‘Œ-[8ùÕWvÇÓçOÂÃϳɄ®´”3k×Rrþ<]_|‘€6mˆˆ‹#rà@—ûk5f ¹GŽŸœŒÉ`°«KmÛÒöÉ'- »÷ÞCk0ØÝ+EX8=L Ô‚J ê’ë‘Øjlæãl<%±‰Á•Ô-”HA&y]Ï•üjÁÇl¹oËlž ÖPwë _¿~Ì;—7 Óm pG!Ÿµµµ¬Zµ–àà Fê2ÿajêivïÞËôéSñ÷÷£¸¸„åËW3tèãtêÔ^l¸Àêú]åСCBÝqE¿~ý„ú, »Lee¾XÃEî;Ìf£XYÞ\¹t…Žss²ëw}¨Ë¡WSÃôcǸ°};Iï¿OI]c"ù‹/® ¥’®/¼ 4lÃãâPqiÏžë"É` ôüy»žøÔÕ«ÑWT¸ì©·u7´6ôlç(*m™*,Qi^6ëT-sû´\O*mëj/äÊÙvDÐvôoèÛoc6™(ÎÈàìúõhëÂü\ŒÖw=6Ö%RÊÐ…p°=•¯/jª‹ŠÐWTØ-o÷ÔS üç?¨ÊÍeYŸ>.ÅäFb­Ë<ƒ‚PÚDBLݽ¿èh´¥¥œ]·ŽœÃ‡-¿/¹Î![ÚÒR>ŒŒ$vî\º¼ô™Œv“'ÓnòdZϦ©S]î»×ܹ ~çë=Åu#!Ö×ÙÙ /\ÈÑ:'Åá‹Ñ¥®¹rð`Ê.^D[ZêR[Izÿ}²ò,Zéöò˨ëÄmÆcÝSOQrþ÷‰ˆ ÓóÏ£ôôÄ3$„°^½˜WXHua!‹££…Ž¢³gam›¦ÆJéJ[ç"ÛÞÇ®Â|%€Ô R#ÈŒ ¨µ7«².Z·e}>xqÝ…Ô6-ŒÐ $üßÿ9,9Žèš\\3Ö®a½zqeÿ~§rn׎þ³f¡iDAؤIæÏŸÏwß}Gii)N˧NŠR©$¨®³.==µu΃¦U«V.·ýý÷ß»m¨×7w±]»vìÚµK؇uþ—»ïèõzŒF#z½oo¯Û.‹U«Ö2nÜ( ¯±}û.Ff·<==ƒìì\æÍ›Í‡~Æ+¯LgõêµÌ›7›­[w¢R)E¯ 7ÄÆÂáÖÿ.”är!ˆ(ˆ .rþ|¦CO€šÚZËÍ)"ÒX7»JåAm­A,ŒFÄݼ5ÛÆ8]'¬¬é|}BC)ÉÌdqT”ð}¥+ñ£×“¾d‰Ó~½mÅ]U—,±›sèÐ`´šÕØæ$´ <–”Ö× s]Ã°î æëî¢ÕXæ#Y ^¬"Ð:ÚçÊúßnþ£›†­Øûæ›v£B2‘ îµ;6ð]¥Zpn¶ëh""éÒ…œ£Gáé•+íþ’zDIËQ£èlc=^”žÎ¡ ìF@zΙC›ùCúŠ ¶¾ü29‡S˜šj·í€Ö­éöòËh"#©*( mÕ*®&%qàŸÿä@H½ŠÎœa£ £+çøÁnÄ`÷ï~GæÎx5i‚W“&´5ÊÎ,§ìòeN;Xä_ML䪃cã õ׊ÊÏð¸8$@ENŽ0JîjôÏtƒûÐ |ê`…öa­&“‰ÄwßuZ'¤kW~š7€üädŠÒÓ®·(LN¦09Yèh°=¾36ea[çöýíohš5Â}eJ%ã–-#ö78g“à¼(=£NgW?õÔ·ú\\¥2Á:9 _)PUP@Un®0ÐæÈÓ¦óÇ*ýêž7VÓ›HTÁÑ×€½£¯ík™ÍyXŸO…'NPxâ„Ѐ³=gMr2¾ö1¾¾txúéFyއ„„–_}õÑÑÑ,\¸Ó§O“œœL·nÝðöö¶ >|8………h4·bpäÈ‘œ:uJx¿råJÒÒÒØ±c#GŽö«R©ðõõ¥K—.Ââ°aÃ?~<[·n`àÀ”••¡V«-Â98‰D‚Z­–>úˆ©S§²mÛ6¦O¿þR(Âw¬Xçй¢¤¤„€?üؾ}§“ ÌÉÉ%""Ìr=¥RôúZ¡\š››' B,!ÆZ­Öî³Ö­aß¾»/·mÛÆ¨Q£n¸ÞàÁƒÙ½{7C† aCPTTŒ\®@&“âá៟z}-yyy¨T*DDƒ  BB‚II9'F#bÍfÛ(Ŧ1—¤]±„[ZD5çÎ ë‚AƒÃ)ι]™Í8Î۱݆­ÁƒÜÅ÷…°9I] B³M£Ï|=yu ö®ƒV·@kX› û|q¶ÇkmèéD´Ôáám+$­£†R®2ZÕq$ÄQ€Úšw¸Ë…‡ð¼––FaZšSèç°kœËdÈ=<èðÌ3ö¿çΑ¾v-¦ºÜµûþö7ÒÖ¬A]7Ê`åÚéÓNÛ/ÎÈàÈ¢E„téBÉ… Ÿ;gw’›8>€ó[¶ÜTdž-ºâbÒma›´$ÆÖDFâ[—h«¶ªŠ¼ãÇ]nßöuUNgê”mÅ¿«Ws=Ç.©§ƒÀ6¬ÕÝ9gnÛær›î„çŽÇñuEV–P~™Œ&]»óë_3àí·…u¯ìÝKmu5‰ÿý/&=ùUŸ=kw¶ÇàB‡©S‰>©\.„¿:Rš™IÞ‰¬ê)ÁE¸Ú¦ÓÈzjûÚ6’@…}ÞOëh¿û9À¶¢Ð„뜶ˬ¢1Hmäç¸5‰·íëßÛŒ¤ÄÄÄØ½ÉÆÉ×ݺu£[·nÂûiÓ¦1mÚ4§}EEE`—Cpë 9Õ&"àõ×_·Û¦mÈhPpˆàô.Ôµ¬lñÇ»¹víšSÎòà`(,¼ûûJOOgèС7\¯]»v|óÍ7¢ lHÔj5þ¨TJÀLii)Z­¥R!Þ"†NWãd„ Ò°XÝ7]5JóëZã]:™ƒ˜“»wŽÂÊ•¿+Ñcm¬éqï éhBc4ÙÏ糚ºØ:—:.3Ú4ø\‰)Çý™€ˆÞ½ÉIHp)LmGE¤6ÇhgÖjÌ<ƒ‚8½l™ÓHªíè‘Ñ•`s#B{ô jøpŒ:‡.tZЪÅçÏ»[þ-[2nùršÖ…“ÚòĪUäÌ›'B€ÀvíPÚ­w5!#‹9‰®Š«W©¼zÕ¥hsw§‡tïn7O°>²÷ï·Ì¼’¸Ù§µÜÃzö¤ËŒDË–ÔVU‘ŸœLñùó¤×…¼¹âê¡C.ç>*||ìæâ]Þ³Suu½Â·>±+Ô©”–6 $jlZh®B›öéƒG@=gÏF©Ñ¸upÄåÖ­sejÌF#»Þ|€ºØ$è¶žoK7=ýÕgd¸Ý¯gp0mÚÜðšûEGãYÂk½ÿkm:bô8§Ç‘»x.á òlGå¶çëð¬0¹¸g¤·Ø9#R×Á`/LJKK‘+\—pll ›7o£ºZËøñ–{¥¨¨˜?ýém>û,ž˜˜nìØ±‹ÜÜs\uHp¢íèŠì.,VlMÝúôyŒÌÌK¨ÕjÂÂ,ªÅ×WÃ[oÍ^5Œ«WshÓ¦2™Œ Æ‘q>}ÃÇGt‹¯ØX8rÆŽ½;ÛÛ°aO<ñÄM¯ß¿öïßÏÓŽý@ B©TŽTê¼)ƒAwÃGSQQ!ùøûûÒ¤IˆXãED¬i'¬”` í‚%D´ÜEÃÚ6çœÉ…Øs'º¬5W‰¿oÆæj;®a¾Í›CºMƒºÅ!Œýê+.îÜÉ¥Ÿ¶3Ípµ ©«O´ZÝ ­®ˆ¶s .\mËZvŽ#™:ìs«™n²±jt!¢/lÞl—|Ý\'ÄZŽƒ¼nJ€®¬ŒãŸ|‚ÂËËná­Ò÷/¡×o~CæÎ”Ö S//®&&’_7ï @®V #=`qð<¼p!YX¾7mšfÍ„åÝgÎtr Xç¨çìÁï¾KMq1'–,!cóf*êF'Cºt¹i‘éé[ýþú×®sæûï¹´g¡:0b·^—^@®Vc6…ãð SéôÜsdlÚÄå={„‘RGS–²L‹GÀŽY³ððóçiSbfϦåèÑB˜,Xæ†?ö˜ÝH¯;]’Â÷ãÇ3mÏž›.Û»ÖhR«™°r%5EEÔºHS`ª­%±.ÝA掂htìHh9bR¥’ó[¶¸=×[w ÀTýë_…t={ödèСNysrr„<„¯½öÚ Ód}òÉ'̬»ç/^ÌìÙ³$¡V«åâÅ‹´ooq÷LHH 6¶×m3:º…}}‘ËiÙ2Jx¯Ñø Ñ´µ[Þ¾}[±Ap€M4ý“‘‘ÁøñãozýfÍš±ÎMç£(ëÉ ö@ÏŸÏ$"" |WŽR)¥¦FKzú9t:½€]D¤±Èȸ ݆ü1¦M#ù—_سa¯‡†¢ß“Áà2¹wXL OoÛÆwãÆ Î’Svî$<6–äÏ?g·Ã¨ßXã‰Õ«]†›íùÃ8ñÙg.çÓ96àÊ._¦ì²%AoXÏž´2„VcÆ ‰ŒDî鉦Y3|ÂéÈÉq)²Ü^š\9©ƒ³‹5 Wé ó,ÚÎ?²Mõ!ãºÉÞFš]££ «ÜhŽs ª®^e÷o¸êUdço~ãôñ¬óçëIŸ¶m+¤~¨­®¶ 1=¶x1H$´ZÁ æfWþó»÷?ÿñ.×{éÄ ü¢¢H$h"#1êõœ^µÊN(=Ë IIÈoð[èÈ…íÛ9·q#£RhÜ,—víbã”)˜mžk âÊ~œ=ÛNhü<~]~…›Çd0çy³¡²V·Õ Û·ÓüñÇ…ÏS–.eÇìÙŒ$Àýˆ—Q¯çÐþï~øáž<»ÔNáËVF.^l©UU˜ ¾4ˆüädÌ@³~ýÛéÙg‘«Õä=*¸ãÞŒl>hQ#FS'´ OŸ&£Îh§ Î¼§1ðôôœ@,XÀСCIJJ¢_¿~v ï~ýúáááÑh$!!}ûö yéС‰‰‰têÔI˜Ê‘˜˜ˆ—MŠ™ýû÷sèÐ!—yçÌ™ƒR©ò>ñÄxxxpéÒ%‰‰‰áñÇçßÿþ7§OŸfܸq¼ð ôîÝûŽÒN$$Å××ÿ–¿g0(..äAÄÛ[ƒR)k”}…‡ƒLYY`Ó_w[œ={–Ö­[#“Ýü±Ëår"##ÉÌÌ$::Z„îpœe41›-ÿ9A\\Orsó©©©zPª«kÈË+B&³@‰D‚T*ÃhÔS]]ôP7„% 2™ü¾<6˵{tòDæå¹¬Ã"Îèõz´Z-Æí:(•J·ÆP›o`ï_ÿÊ¡ìl4-ZðÛE‹Pz{#‘Jéÿ÷¿³08}E…“É;vŒBC®×jkø˜õs‰UÝ<„ˆ¸8bû[¾=ZHHnËF7i¬Ûr4î°~frhô¶7Žñß|c· ]y9­ÆŽ%¤KNÕ-“¸ù“º±&‡ý8™Úp}Σuþ£íÜBÛPPëFl¤«ðQ[£ öަ®D¡£h7¹¡îÌQ,'a¢Öf>žõ|ãCBÊåÄýîw²´5k(³†jšÍNefû¾¶¼ü†¡y7#ƒ nB"?mÙÒÙ•Õñ9âðÞPSéo¾FŽlÉܱƒüºÆ¼u[ÉŸ.ìcèÿþG÷W^qʽèÈ¡ øåO²«¿õ 6]y¹ÛmYïIƒNç”÷Î1¤[®R!U(œœW­¼is6Iƻ̘a7'Pµ»w³®.ŠQ¯wŒç·nåßuÈã—/§Ó³Ï^/v£½›DãÖãNûî;JëF1óŽÜa£GŒ zĺڦØrqçNòŽ'}íZ—ódÝ=GÀâ&Û¬N¯ZEÙåË‚¼Q}´Þ—ù…Ë{÷’“”DPûë¹ë$R)F Z§cïÞ½ôéÓ…¢aýòòò˜5kf³YÈC8gÎ>øàbccòúúú²sçNÞxã ²²²X½zu½y­©*¦L™Â;ï¼#Œ¾÷Þ{lܸ‘ôôtáÿþðA<îÝ»—Ù³g–œ…½{÷æôéÓ¼õÖ[,Z´ˆ¾}û2gÎ6nÜÈôzB³o:uj‹Éä,*SSÓéÖ­3F£sB¡£GOЬY"!!á\¼xþ®nsÅŠºq8Ðâ6úä“à`{K¤¤¤Ð£G[þ^ûöí9sæŒ(oW\?žLMM ~— ‚°¦FËåË™Èd2ÔjO¨¬¬¢¤¤ø¡oX‡††Ñ¼yst:í}u\µµΜ¹àòö°£TúˆŠ¯ª««Y¾|9F£‘Ö­[3|øp§uöíÛGJJ f³™3f8…:tˆ!C† ÕjQEEÄýç?ï¿ö¦MCåçgyðNžLJ]rk'ñaÓÀFÑÌf‚;v¤õ¸qd'$p51‘NÏ='¬—±e þþÔ9‹’ºí™ëiþXX¶ýãiÿ«_ÙÍ)TôéƒfìX.}ýµËí:–‡17—꺈ºŠ 26m–mtp­o¤·0!nª¹\¸u«Ý9ÜL]‚úGÐ~r^[ŸØ’Ü@(»»·*}ÞßÎ §é¬Y\KKcã3Ï8E!¶kG›zÌ+¬õÙ]Xºm¹EôéCÏyóêЀË?ÿLÂ;ïP‘mI‡`›aõêÕL:•±wË…ÃV‘÷Ì3ÏðÅ_ðòË/³páBRSS…<„^^^Ny‹ŠŠÐh4nÅàðáÃòž:uJÈChݯJ¥ª™ë$ä!2dãÆcûöí :”’’!§ U´úøøPSSâE‹˜2e %%%´k'Îç»ßiÞæÎ… `óf7lÊoÈŠ+xþæ¬O›6µk×2iÒ¤‡*EÞ]„&“‰‚ûáÝòrK’b¹\N@€?½zõàÈ‘ãŒaŸÃ#2²9ùù¹bÞA‘‡˜œœ®]»æ¢U«I´É5u+\½z•ˆˆ; ³Ñëõ”••lc0r;(ÕÕÕÜѱÜÊùNN†îÝo%%л·ËEÅÅŨÕj§„̷µk×ðññ¹ãçúÕ«W‰Ø»×yA‹–¿Fª'·³Ÿl»wojkk)))jß:ŽŠŠ ¡1,Ô‡¬,–9ÅX÷{ÓçccÆãî{w»\KKKQ*•‚)ÉíP\\Œ§§ç‚ÝêùŒw½:ð5Τ IDAT#G¶»ªÇ.êó ÃlfƒMšÀ2¡ªnR•ñðahÄùð/¿ü²ÓkÇ<„={ö´{ÿŠ«ºê@=ìBúóZ÷e›‡ÐQøvíÚÕå¶Ÿµ -ž3gŽð:<<üŽæŠ4.O>iù¿ilßnylµmk1ŸqGFFº™ÿ{34iÒ„ÈÈHŽ9b7WV„XÜDFû±ˆˆpT*%R©”iÓ~@›6­œ¾{öl:&“ ¹\^ï¼$‘{Kxx89994s˜Í}üøq¢¢¢ð÷÷G¡PP[[Ë•+Wìúö©K- T*Y²d z½•JŇ~xSIŠ]±`Á!œèvÉÎÎæ—_~±k Ü*¤¤¤0©n®Óír7ÎçnlcãÆ´k׎víÚÝö6V¯^MŸ>}hnã"ù —ÉÝØFaa!›7o¾íúpùòe:Ä”)SŠ2Ù¾};ááánî7úuëèÒ¥‹Û‘¦G­®uïÞäºy¨C† ¡÷Mˆ{‘™ @§ƒÄDøþ{K§ŸŸ¥%*Ê"­ìÞ½û®¤èׯñññôìÙ³AC²8A(‘ ä\¹U""š!—Ë0™Ì zè+°ŸŸ?…TUÝ_sM&ÑÑ-ñöözä*……e⓵üq¶oß΂ ˜1c†ðù®]»7nþþþLŸ>E‹Í“Öî;FŽÉÑ£GùüóÏyõÕWéÔ©ÓmÏ–»‰··7M›6½/Žå~)“ÈÈH;G@±L,¡m÷‹ÁýR&¡¡¡øùù‰ercÇŽäÔ9·hÑDóç¯P]ílf¤ÓéIIIsi^'“)ñõ x Ï·!ÄP}¦2ÃkzÙÒR¸xÒÒ,¡¥2øøsútGRRüq‘†ö–‰‰‰áرcômäÔ7÷µ ¼]ì[ç€%Ÿ""÷œ/¾X- 5j£Ò3¼õÖ[Âë   Þ|óÍz·Ñ¹sgÂÃÃïH ·”P¶! #,,ì¾8–û¥Lî§Èû¥L4 Û¤ZËÄ2š%Ö“»{Mš4¡I“&v¼ÿïÿý?AÄÆÆ2xð`§<„¹¹¹¬\¹™LÆ«¯¾zÃ΢Ï>ûŒW_}‰D§Ÿ~ÊÌ™3,á¥K—îZg@›6ѨTÇhÑÍs÷Mtê3•¹Yüü,³*¬˜ŠŠÞ{o o¼1ü|p˜mix8Œsã}ôïߟ÷ßŸØØØwó½ï¡%Ñ<ûSV¯›ãÎÝœDDî±_¢Ñˆ½/ŽÃÇÇGHJ,–‰…V­ZÝñ|ȇ­Lî—ãÐh4÷ÍHÖýR&mÚ´¹oFï—2iL<<<ìò<˜cÇŽ ÓÎ;Gß¾}Q*• ’’’8pàÆå|Â6mÚpøða:tè ä>räˆø€ñãÇ£R©¸|ù2‡¦G 8wß}—S§N1nÜ8ž³q¤¾]”Jf³˜Ïø~äðáCŒÛèhˆŽ¶Ÿ&m6C‘M¦»Ü\gÁh«÷š6kÔé¯ýk>þøcæÍ›÷èBƒÁˆÁ`ö§¶Vœx+òp!¦!l._¾ÌêÕ«yöÙg…ÐÊÁ6Α&“‰Õ«W£R©˜4i’“½xCâëëKLLÌ}QNƒ]¸iÞ îtäöa,“ûå8üýýï›Àû¥L:wîüÈÖ×ììljjjÜΟÌÍÍeÙ²e<ýôÓ‚ñÊÝÆš‡P"‘ð÷¿ÿ°˜Æ|üñÇôìÙÓm¹sç’••Åš5kÉdnóZ;§&MšÄÿû_Á8æÝwßeíÚµœ={–Í›7sæÌ~ûÛßpôèQöïßÏÌ™3øè£xì±ÇHMMå7¿ù ‹/&..ŽW^y…Í›7 sr÷ïßOŸ>w6çÒh4¢××âá¡rû[¦Õêɤ¨Rmm-&“I4Wl ÿûßÿ8p ½zõr¹ŽD¶>]AAàøX©­µ½ïl£ö¢¦ÆŒÑhdìX¹0gQ&ƒ)3…üæ ÔÈùŒl±f‰<Ô8#‰Ü9ùùùìÙ³‡ùóçóùçŸóä“O:9$®^½š ÓéX·nO¹Èu&"ÒPìÚµ‹¡C‡ºh´iQ(Èd2±Dî;rrrX¸p!C‡u)KJJØ´ióçÏgùòå¨T*ÂÃÃïúqXó®ZµŠšš»ð9Wy“““Yºt)`™WÞ¶­ëT«W¯Får¹ÀêÝ»7 …¹\ŽÉdÂl6 ûíÒ¥ »wïöa»Û·o_»c³Þßf³NwGÎÊ`q­þöÛ TWWÕœáÃ;’“SIH8ŒÉdâùç§ Õjùî»H¥¼?íÚµyèêªÉdbãÆDFFÚ9ÎVWWóÉ'Ÿ0sæÌzÈ+**¨ªªºåý®[·Žšš~÷»ß!½Õd…ØŽFE½ïS_t:~ø!ÿ»íÚM¨kS‚^qq^ ä”Õ.·ïííí”·ù¾„r¹Œví›#"ò0óË^©Xw™ââb¡‡×Ïϲ²2'A˜••%8—ZC~DD‹£GÒ¢E ZµjEnn.µµµDFF’@·nÝ0›Í‚¶Éd" À®^QZZJ³fÍÈËËÃÛÛ¥RINNþþþw”ÖDDÄEEE<ÿüó‚Œ#•••øøøLaaaƒBë}0uêT–,Y«¯¾ÊÂ… 9yò¤‡ÐÓÓÓ)aII Æ­:t¨S””!¡u¿J¥ooo:tè ä!|üñÇ3f ?þø#`u,..æ:úûû#‘Hðöö¦ªªŠ>ø€)S¦Ð³gÏ;J;±wïAºwïB§NíY´è3†ä$D~ùe?óæÍ >~1€Ýû‡QS\\̹sçìáW_}ÅË/¿ÌâÅ‹…T%ß}÷™™™òæ›oâååűcÇHMM½åýNš4 Ÿ;rv¾UÌæ,˜i÷Ùtb à:ÅN÷î=lÜ–sèÔéØ ýî‰ ´âáá‹\®DäþÃl6SUuM,‘[ !!¨¨(Ο?OYY ¼úê«ìÛ·¨¨(¾ÿþ{|}}ñòò"++‹ùóç³dÉš4iB~~>±±±˜L&vîÜItt4G%<<ooo¼¼¼(++ã÷¿ÿýCa: rÿйsgNž>>Lœ8‘²aà #FŒ M¤QéÝ»7#GŽ$>>¤R)EEEv#/½ô2™Œ/¿ü’M›6qåÊ»\qÿú׿æòåË Iè›4iBEE…K«y‘;!==¤¤$ŠŠŠìr9N˜0M›6ŒÙlf÷îÝÑ¿±Ð˜ÀÀŠ‹K„6Ùõk•App xx¨©©ÑRTTDÓ¦ òò ðòòFt6|}}‘H$tëÖÌÌLÖ­[ÇÛo¿Í„ X²d‰ méß¿?'NlÐãºí7Öwôzýý-­lÚ´‰3gÎ0räHºuë†V«åÝwßå¯ý«Ëõ—-[ÆôéÓ^ÛRZZÊúõëyñÅoëD 8vì£F"!!ÀÀ@Ú´¹ù¡wwÇu#¾ûî;ÆŽ‹§çÝÊ/^ääÉ“‚µÑhäóÏ?§ººšgžy†ððp6oÞLZZ#FŒ {÷nâÓ¸‘0™~;Ò»Õ~õòòâ‰'žàÌ™3ôîÝ[˜£1tèP!„¨wïÞœ={™LF«V­Ä &Ò¨´iÓ…B!„•µoßžÀÀ@’’’HII¡uëÖÂÜ¥ž={¢T*9sæŒÝ6Z·nN§#,,Œððp”J%‡ÂÛÛ[˜?%"r7ñððFÀlÛûÛß„å“&MâÔ©SÄÆÆÞóùI=zteß¾CÄÇ/æÉ'Ç á¢ûö¤gÏîðôÓO²lÙ*‚‚™4i<ƒ‘µk7Q]]ͯ~õäCY. …Â.lÓÚyѬY3§Ñd+Ï<óÌ#]—îÅùß² ¼xñ"Z­–ùóçóî»ïÒ¡C–/_.L&vEnn®Óë 6PVVF×®]éÞ½;iiivs‹RSSQ($&&ò /ššJçÎÉÏÏpʳ£×ë)ªó-++C­VsîÜ9:„\.çÙgŸ¥¬¬Œ 6–!èÀÀ@Ö¬YCmm-¹¹¹”——“‘‘Ajj*‘‘‘ <˜´´4>ŒJ¥bÊ”)±eËÀ’/¨  “É$sçÎùé§Ÿ¸zõ*ÑÑÑ 0€ÔÔTôz=™™™Lž<Ù­ 5›Íôïߟ–-[röìY;+m½^N§cêÔ©\½z•ððpÒÒÒ˜?>[·na# Õj©®®á»ïÖ?‚ðîhx{{;… EDDؽw7DD¤¡±öÞ:†›uèÐÁi]µZÍúõë9r¤Ýç®z¸Õj5M›6mÔœp"-Z´ E‹.DI»:èÎYñna7h}­V«yê©§„οüü|–.]JJJ ]ºtá׿þµÓHضmÛHII _¿~ôë×½{÷âããcw>ôaÀ€>vŸ½úê Âk?fÎ|ÑF,É™2eÒ#_Ÿ÷ïßORRÏ<óŒàFn­S–2|õ¡>ƒÁÀïÿ{.\h÷yFF6l`ذa ž·õ–aTT?þø# , k×®( ž}öY-Zäö;ÕÕÕÂdß‹/–á`ƒÁÀÒ¥KéÞ½;:uâÿûŸð£|üøqd2#FŒà£>¢²²’Î;“‘‘áRZùðÃ…Øä7òüóÏSSS×_~Iyy¹`/¼lÙ2BCCéÞ½;†ßüæ7äçç³bÅ æÏŸÏž={¸pá[¶laúôé”––²råJòóó™:uª Á’çØ±cÄÅÅ‘––FYY#GŽdÛ¶m´lÙ’­[·CëÖ­Y¿~½Ëáck¨ÜòåËyë­·ˆåã?fРA|òÉ'8p€aÆÃúõë9xð »víb̘14DrP‘ëxxxÙ©ôÑqó2ŠˆØÓ¦M»PÑú¸_Ò™ˆˆ4$iii|ÿý÷ÔÖÖ’‘‘Add¤ÐInm«ÍŸ?Ÿ ¸½wRRR„e»víàäÉ“Bû'77—ÌÌLŽ=J§N2d >|˜€€€»’CÐåååìßÀî³÷<•\¹’õH\w???""ÂîÚö<ȨQ£HMMµ„ÅÅÅDyÊd2—!ÃûöícÆŒ|ùå—÷Ÿ ܽ{7111ôêÕ‹÷ߟ¡C‡Þ0\ÒÓÓÓ.qéÙ³gY¿~=‰„½{÷òÇ?þF#8@Y gРA„……1sæLÞ{ï=Àb_ëÎ>Öb¬R%Œn˜L&BCC©ªª¢ººNGhh(`q«©©!((ˆàà`áÇ»oß¾„††¢V«1 9r³ÙŒÙlføðádee Û áäÉ“ìÙ³‡aÆѧORSSÙºu+çÏŸÇ`0aÆ Ãl6 9“¬Îu2™ŒC‡±oß>Ìf³ 2ìL^xáL&“;fÌNŸ>Í€Ä_¤F@¥Rc4–c4>Z»¸¸”ƒ+€ˆˆˆÈC@` Mšܵ텆† )ZokO?ý´0h`5œyæ™gøþûïéÒ¥ —.]bïÞ½¼ñÆ,_¾œîÝ»³gÏæÌ™CFF[¶l¹)ã‘[ÅÇLJ>f EÅÅäå»6ü(--£iÓ(üü4N˪ªªHdxzz8-Óé´\¸p¹üÁq: ‹î^ª.©TŠÑhD"‘ðõ×_3zôhBBB™ûR"‘ R©0™LäææòË/¿0mÚ4¤R)µµµwœ6£Aá!CX¶l»wï&..‰D‚ HJJbÁ‚L™2…æÍíSTØævQ«ÕÈd2¤R)f³ÆrãìØ±ƒ¤¤$V®\É´iÓP©TBÈårbbbX°`W®\Fèlñõõ%77—¾}û’@LL ÂCfĈäåå ï;tè@TT_~ù%`™  °eË.\¸€D"aРA<þøãTTTàééILL W¯^¶Ñ¥K<<<˜?>ÇŽãóÏ?gâĉ´k׳ÙL×®]ñõõÎ_"‘9­vïÞÍwß}Ç’%Ká'‘H„‚U«V‘””ÄöíÛ5jjµF#Ì»R©Th4qnJ#áï¯Áß_#„ˆˆˆˆˆˆ D¡PpéÒ¥ÛúþÅ‹í æÏŸï”°oß¾¨Õj¡í˜˜˜( "L˜0¡AΫ° ƒ±s݈gYy9µzà ö`6;‚TV–"•*Q«ö55•”••øÀ\sKûüî ™3g Q}«W¯Úÿƒ~$î¡ÚÚZ<<<8sæ ¨T*f̘Á'Ÿ|Ò()($ï½÷žË!k×®ñæoç ‘Ê,«x{ß3—Ñýû÷Á©S§·³#¾[ddd’’¤Ib<·™’’+â/Óðé§ßðò‹/ òPb4U‹"""""òГ|â4:váßÿþ'2…7øýõþž}ñé§Ÿ2sæÌºßÐOQ«Õdee!—ËñõõeÖ¬YÂ2ëzŽüðÃBÎÁ>}ú0`Àþñ‘‘Áþðt:ƒØØXÖ¬YÃÈ‘#Y±bUUUòÊ+¯Üµ²0 TTäb2ÙýÓ!bbzàãc‰ôÊ̼ˆŸŸ?׊ 騱¥VRRŠVkÄ`ÐâëˆFã< XPPˆTª$(È×iYYY9gΜ{ aË–­‹8NI9M=0tÂòÓ§3èÛwˆ`È%rw())&;ûM›º=MN>E§]Y³ú22sœèêCþ BLL ?üðAAA "!TTDä~G§ÓsòdªÐ‹$ÒpDF6ÃßßW,lEž;Áw£ecÇŽeìØ±vŸýßÿýŸËu­î‹sæÌi”ó+..ÆÇÇ‡ŠŠ jkkÅ .òÐrK‚°¦¦ ®òžìèу¨¬,híK$àç§l°í7,¢©Ì£„ÑhÄßßÖ­[Š…Ñ€H$Rd2…]ϧˆˆˆˆÈ£Á` ¸¤„ü¼or2™‚kÅî ª««)--tú¼´´‰DNuu¹Ó²ª*qŠŠÈ&EDDDDDDDDmZ´hFMMéC{~‰„–­š&ä Û<½^^ž(j¼½½œ–¸wÌ €V­TÈåNZ+™L*=j‚Ðl–`/ºÈ#€ÙüàN~þâ‹å¼üòóõ®“––Naá5ì'^l‘‡‚òò ²³Ó4mŽFãÓ ûÌË˧¸ØY µmÛJp¿ë5¹ªN”Øþf™0õ^æAAÁ¤¤œv+ŒvüýíÓvxxx•u™LúH–‡Læìe •JIHØ+> î2&“‰ÈÈf÷@š-d3¢KˆÈýLee%_½’ÒÒ2æÌy NÏ’%K˜8q‘‘Í8rä8Í›GPS£åüùL®\ɦ¦¦†§žšÀ‘#ÇéÕ«‡ðß_~¹‚ŠŠ úö£]»6|ñÅrzõêÁµkE<ñÄ>αcɘLF~ýëWÄ #""Ò £÷î‚ÚÛ¿îÙVMüßf²ìËÿa6»O°mÛN~ùåï¾û¶ðÙâÅ_0{öË7ÜçÕÜ"¼›_·Ã¿xþ Gú†¿ü¹ 5Ÿ_"‘b0hí>KMM£S§öNëVTT²qã\¼xÆâ9mÚ¯º+ÇŠMîðG[1¬V{еkÛGº<çÙ·oß Ñ`´¡ê òœq+÷þ²‡K™ébÉ‹<2D·jSëýôÓÏdeeóÜsSÈËËgÍšu̘1  ‹e´N§G¥jÜÉç™üë_ÿ‡ŸŸ/ññ‹™;w/¾øK–|Íï~7‡éÓ§¿˜Aƒú¡V{°~ýf¦NLQQ1'N¤pð`"½zõþïÞ½—ÔÔÓDEµ`„ÑüêWOb6›ùä“/ ¥iÓpŽ=NÇŽí9uê Ÿ}öü>F£Ï?_Æ+¯L+–ˆˆHƒr*ùÕZ=½ŽdÎs#yöÅÙu‰®-ËkkkYºt%ÕÕÕÄÆö¤OŸXFιsç…mœGVÖUŽ=Á¨QÃîV“³ècWïµëȃ†[A8é©_‰¥#òHQ^^~Ãuôz=;v$¿ü²ŸaçC‡v”””Hyy .楗ž#0Ðße“²²r***Q(ä4iBEE%ÕÕÕÔÖ¥ªªZÈ{TQQ)¼ÎËË'$$XHØjKëÖÑøù]O°mÛOäç ×ë¹r%Ûå¹øújhݺ¥àTºwïaŸC† dÈÂúÇŸäÈ‘ã( Ž=Á³Ï:?#¢£[ T*¨©1ˆJDD¤QØ¿{ ëV~Eë]ˆnݑџò…åëÖmfüøÑ„††’rÚå6ºvíÄÏ?ïÞïÚµ—W^™ÎSOM >~1óæÍ–ikjغvΞB"•2ëwÿ$¬is WXçèÑãDF6E¯×sôèqúõ‹cܸQ˜L&¾þz%:´%!áíÛ·%!á0'Žg×®Ÿyá…i”––òí·ëxî¹gn©LdÞ¼Ù8Hnnåå¬]» ƒÁÀСƒÄŠ"""rë‚PDDÄ™³g3ÈÏ/D£ñaذǖ_½šÃ•+Y$&á±ÇzÒ¬Y„Ýr³ÙÌ’%_ÕœŠŠJzöìÎ_,#.® …¥RIII)ãÇÂÓSÍ7ß|ˬY/0gÎ[|ùå‡h4§ýÚ½ kBFÆy %Í›[âÍ—-[Ezz ‡éÝ;Öî;Í›G¿˜K—®¸<÷  @ôz=555´mÛ ¹\¯¯†Î;RRRЇ‡Šüü>úh f3Œ3\¬0""" ÎëX€§O +>ý/S^œWïºááa7µMOOOüýý\.S{z±àÓµüé×O“rô]bz»\ïÒ¥+hµ–0ϹrÅ’°ýôé3h4""ÂØ°áÂÂBñõÕ››Obâúõë}Ûåƹsøûûòâ‹ÏRYYÅš5눎n!VQŠˆÜ)ÙÙ9”––RUUe7"g¥}û¶tîܧžšàv‡C¡SQQIǎ툊jΔ)O¿˜W_ÁŠkèҥݻw¾÷ý÷ËÜnó¹çžvzÝ£GW»u¦OŸÊôéS]~ÀÃCEïÞ±&—ûˆŒlÊœ9¯Ù}6|ø`»÷ÑÑ-øÍofŠEDD¤ÑP+Œ¼õ—âç%gò3ÓPÈìŸaôaíÚ ""™<ù ¶mÛIfæe6oÞÆøñ£9yò™™—ùä“/™5ë%jkkY³f•••ôíg·=‰šx³ðÓoضn9ÚµF%³ßìß¿ÅÅ%(•JââbiÖ,œ'R0™L³¹wï^üðà <°De\¹’…Z­&*ª¹Ýöjj´Ù§;°ŠM+-Z4'>~1¾¾¾„„„ Õê‰_Œ··7O?=Q¬("""¢ ¹ 2‹/@qq 'O¦ríZ‘‘ÍP©”DD„³k×/hµZÆŽé´ÇëI§Nðöö"66†C‡’ì–{zªñóó%99•Y³^>é¥×‰_ „ÞmzöìÎùó™LžüÄmocòä'ÅJ"""Òh„††¢RÕ “åó÷?ÏÂ*j²±Gãõ×_µûÞèÑÃ=úzC×®X´èá½—[çæ¶­›ãã™O„'´ý›}^Ÿ4ÓÍé{sæØƒF£aêÔÉÂû‰ǹ=OƒÁ9ÝAË–ÑvïŸxbŒX!DDDDA("ÒÐ( »žV•JÉøñ£Ëé‰ÇqæÌ9§pQ°ä6zî¹§),,ÂÃÃbÕ—ñòò¼ëû»ñy* mÒhû3\ȼ$V0‘ˆŠòJQŠˆ4‰„ÀÀ›†—“í·L&sin¥I“š4 ±bN¯ …SHj›6­ìÞK¥ ärñ¢4ðõ6›MbAˆˆ—E¤Ráá‘bEy€(-©¡ˆÈ£„ZíATTSŒFX Œh'.""ò¨!‘€Z- BDäB&¿ýä¢ y ¬%u£W¢X=¤5ÙˆIDATy˜¹r%‹œœ|Ôê;‹‘JåtèÐF˜Þ """" B‘‡½¾N5¹ŸP(¼ñ[Ål†víZÛM#0üôÓÏŒ9NǪUk b̘áH$®G ärŒFØ‘(""" B‘‡™ãÇ“¹t) Wí•JE@@yy9bƒ@ä *ª¥ÛÆmc¡ÓéÈÉÉï‘ziÞ<š‚‚<´Ú—u¥gÏZ¶l~Wöe4šøá‡ùå—Œ9”U«Ö2qâ8 ®±uëNÆŽ!^QŠˆ<(äåå×ëwáÂEL&3­[[ìÅóó ÈÉÉ£{÷.TUU“ž~ŽöíÛàéé @HHRéõ üýýQ«=8}:  @»å""÷+-Z4§ªªìžCZZ:ÁÁA÷\˜ŠÜï‘DDXrÿQSSc·<4ôºsVÖUÊËËéØÑb>–ž~Ž-šßÔ¢Ùlfóæ­ÄÄtçâÅK”••áë«Á×WÃÖ­;Ä‹!""" B‘…ãÇO²lÙ*>øà—ËOœH!;;‰DBYYááa8H“&AlÚ´añuë„…5á‡~dÜ8ûœ‡jµ???T*%f³ £Ñ ºˆˆˆHa0Ô"—K E§ÓSRRJuu•Ý:z}-ëÖm&:º9ååôî‹V«½i7c³ÙÌÁƒI\¾œÅÁƒI<ñÄØF?Ïœœ\Æóàà@”J¥X‘EDA(""R?+V|KQQ …‚'ŸÇÉ“©ÄÅõ¢²²ŠK—®påJz}-eee´nÝ’1c,¡;/¾økÞyçïBž¿òò *+«ˆŠrB´wïæÍ› @|übüýý?~þþ~ÄÇ/æêÕ\¼¼¼èß¿›6m#7×’ÙÓÓ ?”J`Ó&ˆˆˆˆ4"F£¹\JHHµµ~”––Ù:*•’#†PS£%++›Õ«×ñúë¯Ò¬YIIÇÈÉÉåòå+´iÓŠÑ£‡Ûm[*•òÞ{ÿÞ·hI\\/݄֮V«eÒ¤ ~~—/gѺuˇêšI¥rd2…XyEDA(""rc~þy?ƒàÚµk9rœáóqã¨ÕjÆÉÑ£'˜1c~~¾ÄÇ/¾÷öÛÂßßOx¯Ñø0`@ŽO¾ëǨP(P*å€8çIDDDä^a6›Ë¥”——a0%‹ARÒ1 èKÇŽíðóó¥ÿÞ‚X]صëgþüçßñÓO?×»ý^˜@\\/²³¯âááAPPÃçOôôô$,´)J¥ê¡¸Nyùùøùyc6›1™®GÒ”——£P<"±¤¤”ðð0g W£zˆ®£ê¡>Çüü¼}f[„""·@«VQŒ1Du×®¡R©(++C§³¸·]ºt…nÝ:Û}ïàÁ$ÆŒ·wý·Ü‰)˜ÍfzôèJ‹‘\ºt©TJddSš5kJZZ:=ֹܒ¸¾´´TøáòõÕPPPHII1ùùùøûûÖ;?QDDDD¤á(((¤´´ …B\nyöÏžý2tìØÎí÷¬n¢Ã†=^ïöm]G›6hÔs“H¤<$ml²®\ÆÏ¯£ AKõ b r¾Ž’‡ç:f]¡C‡ÖÎçÈÃsŽW².»<Ç»è,!"r Ø—•+¿eëÖ¨TJ²³¯òÄcyöÙ§9u*©TBii)ññ‹>|ˆð½ÊÊJ;ç¹òò âãc0‰_̵kEètz¡§x„1$'§päÈqž|r½zõ@¡Pðé§K™5ëE‚ƒƒ4¨ññ‹2d–›Z*ÅÓSV«ãÌ™säææ‰‰""""€Ùl&?¿sçÎS]]ƒJ¥²3ñ’ÉdôìÙæ›ÍÙ³çÙ²e;UUÕH¥2zõê!¤ˆˆH£"ŽŠˆÜ}ûÆÑ·oœðþ±ÇzZæ‰íÁ‰'4¨?ƒõ·ûÞK/=o÷^£ñæÚ×Sx-‘Hœ bccˆÞGD„»ÜŽõûžžjôúZÎ;FãƒÁ`D¥¯£ÈƒÑh@«½·y5kkE3&‘›©«Fòó )++G¥R¢ró •ËåôêÕ]x߬YSÞ|óu§ç¼‹':Éõáß+§ÜÚÚZV¬ø–‚‚BÚ·oËøñ£nêXòó ¸r%ûÈ;vì"99??_fÌx•Ê>ÔÏ`0ðî»0lØã÷Å9fd\`ݺÍ<ÿüÂÃCÖ¹xñ2ÉÉ©<ùäÍ›UW×àé©®·E«Õ¡V{Ÿ}ùår&O~Æç¾¸–ÕÕÕ¤¤œ&.®.\D&“Ñ¢E¤Ý:ååå,Zô'ާC‡¶¢ y”yíµ÷tÿDDDºM+áéy  @ÑB_äÀl–PSS{O!2²Mš„ˆCäbKFÓ¦ÍhÖÌõ³×bòu{ V{ݱé‰Ùlº'î ‡¦}û6¼øâ³œ9sƒÁ@yy%%¥¨TJš5kêR nÛö‘‘M9rä8;¶C&“£R))-µ¤Ù(**¦´´ š6 §¤¤?aù½þKNNeþü7(--#//Ÿàà rrrˆŠjŽ\.çÅŸeÇŽÝ‚ ÌʺŠN§ÃÏÏ—ÀÀÊÊÊÑëõètzš5kذàuë63þ,X°™3_D£ñ!3óMšãããƒR©¤wï^ÂwŠ‹K(..A¡Pмy3JJJ©ªªB«ÕÕœ²²rþóŸÿñÚk3 m‚··ÙÙ9hµZ|}} äøñ“lßþÓ§O¡Y³¦TUU3p`?ADšL&23/ŠD55Záz[££’š-©©iuóusP*Ÿ_@«VÑh4&LÍÅ‹—éС-•èõ·áÀÀ; QŠˆˆ4(Žs‰ˆ Iä"<CCCÃ÷þüŽòóóÈÏÏ£¢âRŸ ØÄ‰ãÉÏÏ»Ú;Ö^¯céÒ'y챟?¬_79y±±1äçç‘—÷Ð3Âõ=]EE‡)++§¼¼’ööFŒÎâÅ ÉÏÏ£²ò2iic;6üü<âq8Z()9GYY9‡Áçó‘—÷'ŽL¢7”)Sþ=|æâÅŠ@ÜZ[[X°à'äçç]]g¹º½çÎÍÊ•/±hÑ£9rŒ²²rÊÊÊq»½}¾æ‰'ŸŸweI¡B!„¸#¢£-¦¾¾øøah4j:;;),ÜAs³ƒŒŒgøÔjµA=„±±1ìÝ{€áÃm”•]Äç뢦¦Ž´´1uÆ0 w°gÏAž~Ù]?ï®®. wÐÞÞAfæ8Ìæ w˜hÃçó±k×?9vì$?þñ‰‰‰æèÑãTUUãv{P*U}õÇX:«Õ8¾øøàÙU¯­™|ðà—””œãøñb23Ç1uj6©©ÉFî»o*EE_Þ°ßÄD……;èêò1fÌ(t:6[ö*¨Õ¡×î4Û0†tB¨T’m¾£ÃE³½ù¶ÂÎÎ.N>-øB„Ò{þkÖÔ”„P!„BÜ¿ÏGzêx „ƒ„$„Bô»ÝÁþýEäå=ð­¶ollâµ×Ö±hQ>))ÉÀ^¶oßÅC͹áy_.\( 99xqÚŠŠKìܹ›§žzœðpÍÍöí+âá‡ç¢P(¾E¹6ó§?½Á‚óIOO•‚éå׿þ-V«…ðpSPœoEWWN§‹ÈH³ôë.àý~6oþˆŠŠKDEEòä“ »yÏÃÑÂÞ½¿u}·æôéL&#F g×®O™5+µZ}CûôöÛ¬Zõ2fóÝí/½p–O?ùè–Â"DUTV·6¼CB!úAccÛ·ÿƒ)S²Øºu=4‡ººzª«kˆŒŒ$%e4UU5TW÷ÜV8yòD¢£­Ì;‹ººRR’©¯oÀb‰B©TR_ßÀСCù…ÖÙ@xúôY¦MË¡­ÍIuu ññqØl TT\¢®®ž††&¢¢ÌX,Q”••“3™M›þƼysÙ³g?óæÍ¥©ÉÎöí»åôðÃP[[Guu fs©©c¨ªª¡¦¦ŸÏOvvKóæÍ¡¦¦ŽôôT‰Œ4£V«©­­#.nè .'«ÕÂÊ•/qæÌ9öìÙÏŒS9wî“&e¢T*9|ø«@Ân±DqêT .—‹¸¸¡ØlñìÞýEE‡Y¸ðÆŽM“¥.—‹ÆÆ&V®| »½Ç‹Ç㥴ô"ÙÙ“nHøššš¯Ö÷‰lÙRÈüùÒÜÜBll4--­¨T*</V P(ÈΞDUUÏû«µµ ¥RÉd’àƒšš:,–FŒÎÙ³ç™9ó>®\¹LmmF£‘±cÓHNEJJ2³9‚ªªÚÛÛ©¯ïiûûó‹£ÉÌ'ŸIÁ âF޼µqó’ Ñ®}3œ0ŒmÛvR[[Çïÿ*O>ùû÷¡ÕjXµê–/_BW—Ÿ>ÚÁüùí£°p'<2½^ÏæÍñâ‹ÏJ`¯sàÀœ:UÂÔ©Ù¼÷ÞFV¬xŽ­[·1iR&EE‡xðÁSP°‰ ưaÃffÏžÉ+¯¬fíÚÿ¦¢â‡Å}÷M#))‘ÂÂ455ñÛßþgžYÌ™3‡Q©TüîwÿÅÒ¥‹Q(lÙRH~~^ÐqìØ±›9sîÇjµ°aÃ~ùËu¹ìÝ{òòJÒÓSY¼x›ÈÈèIê>ø`3J¥›­g²ƒ¿$.n¥¥‰‹ʆ [xùåçioï ³³“ŽŽ©è7átº8räS¦dñÞ{e„±úþÄ ‚¶ýüó}L›–ͨQ#),܉Ýî`çΛ;ƒòòJ""±ÙâñzÛñù||øáß)/¯dåÊ—8vì$z½ŽœœÉô›x÷Ý |òÉç8ð?ûÙ6nÜJNÎdÊË+éèè +kBÐöëÖ½CFF*±±1|È /,ë·cMIIÁh4J¡ 1ÈHB(D?yýõõ˜Í:t„ÇÏgÖ¬\rs§ãr¹q¹\dfŽãþûsikkãý÷7JÀnC^Þƒ¤§§pèкºº0™ŒäæNG­Vàõ¶“›;€Õ«×àtºxñÅålÞüQà¢líÚ·°X¢8xðK–,yœþðäæN§³³“¶6'ãÇg0{öL¼^/o¼ñ¶ý&~ðƒiüô§yœÆç󑑑ʘ1£Ù¼ù#œNWHNýÿ]KIÍ›o¾ôÜ–Ø›V«ÅnoæÍ7ß§¸ø ÌÇd2^3n\n·›’’ó :$0åsÏýII‰rÚµëS:;;iii%??“'O³~ý»twCFF--­îÀíö0~|£GßÃßÿ¾¯·]*ýU£GÄápðÏîeòä‰[yd‡#:Ú @uu ÷Ý7•Q£Fb4†1sæ Ôj5ƒžÚÚzÞxãmæÌ™ÅˆÃ%¨½h4Ž >Äét7…ðpS ¾›Þçëž}öFÉêÕk0ôTUÕ‘‘Æ‘#ÇX¸ðŠŠm¥­Í‰ßï'))‘7ß|Ÿ'ŠY¼x¡þ©T*rr&m%&&™±cÓ©¬¼Ì¾}±ÛíüâÏáv{øË_Ö£×ëúlÛ„⻦øãÿ(#‡…Z[[yáùåèôZ|~÷×n§Õ1šnmÙƒööv4 J¥·ÛCCC#ûödîÜÙhµ"""X½z Ë–- $8>Ÿæf‘‘fΞ=Å…V«cãÆ-·uËèÞ=EŒºc°ÚÚœÄÅ A£Ñà÷wc·Û®.…ÐJ¥B¥Ráv{ 3àtºðz½ ´Z ~¿Ÿ¶6'ÑÑVü~?--­DEEâv{P©”¨ÕêÀ>ZZZøøãOyøá¹h4Ìæ—Sww7ÑÑÖÊéüùR"" ç­·þ7pËèѣǹ瞤}GGƒþ–—¸V>ŸŸÏ(hmmÀb± P@SÓµr G«Õâp´ÐÕÕ…Á ܾÖÖæÄçóÝÖxªãÇ‹C>‰ · Vû¿q›kõ]­Vi¦½½=¨¾ßØ.u V¿gz?z½í8N J¥‚'N3zôHŽ;IDDøMo-9sð#&SèÞ†fF§SÜæû¦¥RZ­Æãñ ×ëq»Ýx<×—Smmm¶ÿÕWÿ‡^X†×ÛNDDZíí-³ÓÐÐDuU-ÿyýÓÇÏ‘>ŽÿüÏ?e&·Œ 1I¡ýàú…ìàDFšÉÌt‘6cƽAß«Tª ¿§§§òÚkëðùºX±âçƒ>¦J¥¢Ï‹Ük10™n¼½¾,”J%QQ‘A¯¹~>Ÿ¬¬ ·TN©©cxýõõx<ÞA?~ðú¸^KÖûJNzÿÜWÒw;³“6½ë»N§ ªï7¶KÚÊ©÷£^¯C¯ÿ÷>’“ïaýú÷HHˆgöì™ô›¸>™3zbj4ƒ’.N‹NÜÆ˜L&™°G! ¡™ÙÙÜS7mZÎM %+V<'ÁëGáá&ÆÏ¸år’ Ä@umÖXqçܬBI…¸Ë::;8qðDH»B© éØ+•JN*¡»;ôît÷z½!{…BÁÅ‹•øýþ;v‡£%äo­¬¼L]]MHÆ~„ôŽ}C}#—.W†Üq·{Û24F>´…’ ñÝë$-m´„á.0ÃHJJ”@ÜF&s¹‹¬VV«´;w¥Ý1i¤ÍB hJ B!„BHB(„B!„BB!„B!„’ !„B!„„P!„B!„$„B!„B!Bœ,;!D/Ÿ:-B1àuttJ„„Pq=¿ÏOFÚx „B!„„PˆÁ¢øä16m,@!„t.]ºL”u˜BI…¼GÜÃù²+!„ƒN¼íôz½BI…¼l6›A!„B *2˨B!„BHB(„B!„b0ù?üËîbJÕ IEND®B`‚snd-16.1/pix/sceq41.png0000644000076400007640000000071111147553270012745 0ustar bilbil‰PNG  IHDRe„ÓRQ3PLTEÿÿÿÐÐÐÀÀÀààà°°°€€€PPPððð@@@ ```   ppp000ÊèS¨ pHYs  šœtIME×  0RVF)IDATHǵ–nà DÏÆ²„vÿÿµsu[¡§§Ez ña¼1wyä nQ@¡Þª‚”SoLgáÐýX±8î ‘ÀÚáÁÁ“[GÚXs‡Klñ114HšçcùÈXÈÁ‡õáä#i!Z <ÍÇ4®æùhbîןÍ!}~Ž˜]ÛâÝQÙ~6Ê/Ûë®V!cëªí\½¯ñ{ÜoŸÛþRéÿZžòªþ=FŽÙ~ö³ýtö;¶§Ûœ‰ZQ(CrÍgZK΋`áÚ+?J—Ï‚šOèjöÛPš|onÅ_®‚v£Ô»iÔ]–KìͲ2Šø£ØDÖõ»©[áLK¶=Î Ô^©ñN‹YÄ„æ1évtÙÞ3_‰ÑJ\»íãÙß–‰_5íÁ‰¾9†‡¾yIEND®B`‚snd-16.1/pix/randomsins.png0000644000076400007640000012306111147553270014026 0ustar bilbil‰PNG  IHDRô(®*ÞsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ Gùk¢ IDATxÚì½gpוþý 眈@‚ rA ` ‘[´eÊ’ËRI.[+«,¯µ.oðºT²vk%»l­ÊeYÁZ+Å "Pˆ@äœsž L¿øÎü1¹§§{pU, ===·Ó=÷Ü{Îs¬D"eoï @ –‹µ¦¤R©Úíkkkäª(ŠRÛ¬¯¯“‹C ˜Ê ÷÷÷ãÏþ³ÊöÒÒRܸqäÊ9¸zõªÂ6‰D‚¯¿þW¯^Åää$¹HÇØªÛèèèˆÀÀ@•ísssÈÏÏGAARSSÑÝÝ––@[[ž}öYìÚµ‹³ÆŠÅb\¿~### QølttÁÁÁØ»w/vîÜIî¬! QZZ §qŸcÇŽÁÃÃVVVä‚™¡g†ùùy…ínnnHOOGcc#¶mÛ†òòrÌÌÌêêêðûßÿÞâÎW,ÃÞÞž•APvv¶Eœscc#œ³)žY±X ;;;ƒû“·ß~¿üå/ÍÛ {{{C(B$ÁÁÁåååÈÉɵµ5æççáâ∊ŠBTT ··KKKœ4r`` °··Ç… 4Þ„µµ5ܾ}õõõHOOÇŽ;HokæD?fggqéÒ%ùs¥Žüã€Ý»w#66–\<3ÂÊÊ îîî …X__EQ¨­­EZZÄb1FGGåBNNŽü{—/_¶¸s››Ã§Ÿ~м¼Î£GPVVf}ff+++XXX@@@¼¼¼,þ™ýàƒ‹C‡1>Æêê*º»»ÍßCôè|||ÐÝÝÄÄDxxxΜ9ƒªª*œ[[œ9sðõ×_£©© 'Nœ€££#éuÍ‘H„ÒÒR8;;Óº¯ðýïpçÎ<|øgÏž…³3 æ4½ºº˜››ƒ<<<àèèˆÝ»wcqqqqq›â\‡‡‡‘œœŒÅÅEƒáááXZZ’÷¯\½kÝÝÝXYYÁ¾}û`mýx••Ç㡾¾îîîØ½{·Öc´´´ 55àñxoÐÇÇÇ‘œœŒññqƒŽ#‘‘––$%%™¯Aß³gÂß))){{{9rÄ( ëïïGQQ^xáØØØèýý .@"‘àƒ>@jj*ÒÓÓIÏkôöö¢¦¦O>ù$\]]õþþ‰'077‡»wï"..‘‘‘䢚‡®<ÈOLL„„„¨,Y2}}}8sæ Š‹‹ :Îôô4BBB ‰8momm-¾øâ 455¡´´ŽŽŽXZZÂË/¿Œýû÷ƒÏç#99YnèÕ±°°///ìß¿´áæJ[[222 6èååå¸pá‚|ÙÙ°6Ç ^SSƒ¶¶6¼ôÒKŒŒ¹ ;;;¼ôÒKX[[Cmm-‰Ð71---˜˜˜À¥K—s>>>8wîø|>îܹ£6ºš@à GGG…Bƒcgg§wŸtíÚ5¼øâ‹¸též{î9‚œœ¼÷Þ{ ³_~ù%N:…ॗ^ÒjÌ•qrr‚@ ÿ½ººjq÷oyyY~= í;¬¬¬Ìªÿ1;ƒ~ùòeìØ±gÏže혙™™ðññAqq1$ 鑌Ìúú:îܹGGGöööøè£àîîŽææf,--áâÅ‹ ÿ~ñ‹_hüðCƒS\r÷î]$&&ÂÍÍóßòññÁ‘#GPZZJ,æd~~>>>:÷“¥àÀéÓ§qãÆ Ú¿QWW‡½{÷ÜÜܰ²²¢q_@€¸¸8 ²zžöööò¬'''ØÙÙ©õÐ_{í5ùLÁO<îînäççcqqO>ù$ÚÚÚðôÓOC*•"++Kë̇r¿‹üü|ùvWWW“­¥§¦¦¢µµ•ÑÀÉËËK«#477‡gžy·oß¶˜÷ÀÖÔ ¨®®FRR‚‚‚Œö›^^^ˆŒŒÄƒ‘‘a67C ÀÊÊ ~ø!Þxã TVV"77/^TÙ÷óÏ?7ëëáÇصk—QE~|||àããƒ{÷î-ƒ`^888@(jLU•¥ÕÉ<Ëœœ”••élccc’ Û .Èÿ_f´µŽÂÂB•íï½÷žÙÝ;™`˜ƒƒƒÚ„ YÔ½ŒãÇ£¨¨§NÚòÏ¿I úðð0lmmjÌ7z·VVVfgÔ`mmùôá[o½eQÕØØ˜<ÆØ$%%a~~žõ-г³3mí ???ÌÎÎêý;!!!¨­­Õº¿¿?An úúúŸŸWWWôööj4èÓÓÓðóóS¸çÞÞÞÁöíÛuÚ}–ÿlll4Ö51GL6å. ñðáC“æ‡oß¾R©cccfsCÔ©à)¯½ÿþûòϤR)(Š’ÿ×ÔÌÍÍ¡»»[¾¾f ¼½½áëëkv*NU111a´ß£(JåÛèÅ&AAAç:[aaa´ÙØšý˜™™¿¿¿Šƒ6<<¬óØ===z °¬­­·–Agå. Q^^޼¼<“_€ýû÷£¯¯ÓÓÓ&oËÆõ1GGGyŽòúØFý‰'ž@ss3ž{î9Ü¿ߤí___GEE>lòk™””„¾¾>i)ã#‹rŸ››ÃöíÛ122bRƒžÀZ´½9ðÍ7ß°æt988èÜ/**ŠÕÁ³®Y“ÉÉIlÛ¶MeðdÌ!×3ê» žr—E¹ë3½sçN:;;;³¸x(**ÂOŽ&èˆÞ˜Ü  ,,,¨-ÍjjdzÓ£££¤—Õ“ÙÙY¬¬¬ ,,ÌìÚ–˜˜±X̪šÁ¼X[[ƒ­íãÉÆýû÷›|`®ï:-Ûxzz²’߯.+VWW9äèô«[#·TåI£t@€ÊÊJœ8qÂl/ƾ}ûÐÛÛ+¯×L 7R­¨¨0¨ ¡1Œ:[jVóƒnúòò²V]ƒV___ZûŠD"“Ux¬©©Á¾}ûŒoH ûöÛoM’määädvÂ1MMM:+à™Ü ß¿{÷î5«©vuÄÇÇ£½½ô’4¹sçŽY7êâØ±cWÈ"X6ÚRu-ͬ­­±6Å*‘Hä3 žžž¬ª<òù|“xºÊE[L1³ VVVä‚Y{÷î¥%9¬óëäädƒN'Ê}``žžžQG×ÏϨ©©!= fffàââbuÉ===±mÛ6Åܳ1ÊÝ\à*uM“·/Ë£¶±±1j@ž>ýº%¼×Ù¶m&''ò[<τȴØBW`§Ž–{CCÒÒÒ,æÁÆìì,)ö¡‘H„šš¹Œ¦%€‘‘V††Ïüü|ZÓäÆB×”ñàà JŒHpp°Z ‹¾¾>„‡‡[ô=êèè@LLŒÙµ‹n*]4iòß¾}[ïs6¥Â9F5躨¬¬dµd¦±8q⊊ŠHï«c¦´°É¡C‡•Î$ln´V,•Îêò ñ°Ì…‘‘N *™K»víÚ…þþ~•í\f"ÐÅÇÇGïY,N zWW<==i—4'ìíí±mÛ6ZêC[ññqˆD"³Œj§s_ÃÃÃIœ …™ÓÀd9†3ƒÎçó144¤PK×ÒHOOGoo¯Y­õ™©TŠÚÚZ­šÌøh^°]­ËÍÍ ËËËfqn¡¡¡Òøydd$kk÷lˆ³0EWå2}IKKC}}½ÞßãBy077Wël­)«ÍÍ ×ÔÔ --ÍâGy xôèéuÿ‘ššjñç!«ÐD0=ºj‹kãÛo¿U©amm­6˜m¯“Ž~¸.]òÖ´/D"‘|}ÙÃÃq¬ˆºå]ìÛ·qþÿÒÒ’Šz›½½½Ú%G!..ŽÑõ®®®Fff¦ÞíÓ•ÚÆU„?“{ÈI”ûää$ìííáíímñ¿¿?|||ˆG@,c||ܨ%Q¹ÂÝ݉‰‰¨ªª"ÕȰå.‹å5Œ¹F¨@JJ š››}·½½Ý¨3«R©TmQ*u¬­­1ŽO‰D&{V˜œœŒ‡× «‹r¯©©a42WÈícå$KÉ9§K@@¦¦¦ˆ…52lF¹"cβVd…É5eCïœ.¬EÔ§¤¤èm¹¢ªª ü±Q“õ)÷ææf$&&rªsk 8°¥½¹k×®áĉ5ÂÕùð[[ãøñã¸sç±²&„néKu¨Ë—>tèÊÊÊÌâÜÜÝݱ²²¢÷÷Ö©úÍÄØØí ]ØÚÚj¼n‰„Qÿ¥IV“““F”gÕ OMMayyÙ¤:Æ\±mÛ6X[[o‰úÆÊH¥R¬­­m*c.ÃÍÍ ¶¶¶¬ôôX±YsZVuË(k’S°† 6* ™ú™`[O]ÓlŽ£££Ö5r;;;‹\±jÐ=z¤U`ÆÒÉÈÈ@ss³Ö|ÕÍêo,íºÙ8räîÝ»G,ëGW43†‡‡ªñs} ž2ÐñõõÕZS\ýýýصkyXÂÝÝݨ¬ôìììM§ ¤¥¥áÁƒ[懟Ÿß¦ÎIµ²²B||»víÒk`l–禮ÐÛƒ!kkkÆ9ê Ø³gY\+s½‡ÃÃÃ* ÓêoêfdYÝÌèøÛ·o#//O­€+ZîçÏŸ×Zg³“““c6R“†PWW‡={ö0N[Ùlœ¹áÑðÈ0§Üxåõw]ƒEƒ ºX,Fssó–,+ªK›z7T.r«‹îînR|‚fggÑÜÜ ÇÙoìÝ»uuuq=‚ƒƒ166FËÐ胧§'m=ø¡¡!VT!mllX{GüüüX‹_Y]]ÕZÖB8À㘠u²Á†âåå¥5¾ÂÆÆFa`l°AwttÄ‘#GWèÙŒ>|¥¥¥fßÎêêj¤¦¦U§ÚRqvvÆÁƒqçÎr1 $$$GŽát=ÔÛÛóóóq=¢££åêwÊõ²²²PUUE˱2¤XŸÏW¨ãÎC ãF4©¤q¡‘ñîîîò™Y™Ž»¾6V΃t/ìããã___³–¨µµõ¦ÖÂæÂ¨»ººeí‘`ìíí$MošÖÁÕ¡¬0æëë+¯J×ÛÛ«QN´¬¬ ‡Òiô7αi|7;ú¨É)WâTθ0åc;::* zˆA爤¤$ôõõq:­h œ¨4mv²³³ÑÚÚjô4£­†>e5uÑßßO;0KÙ+ÔG(FS‰Vå1¦<|øP¯å1e ÔææfìÞ½[þw\\ÚÛÛ188ÈZºjVV­¢#ú²´´dÔ¶Æš-Ð×{W¸É–x‰A7§N2Ka’û÷ï###ƒµs«±ÿ~ÔÕÕ1.AÐMOOkÒ®=B||<£ïÒIce/ÚtUêÚ±cFFFXM£â*§žŽ$ª¹ O0§££#„B!k¿m°A_[[Ãàà ñX4 ,Ž`jêëë¼)¢‡M…³³39)a¹X^^Æàࠊdz1•jvv¾¾¾›ê¼é , ] ×™1™ššÂ¶mÛX?~ww·Ñôö•Q3&ÃÃÃg< *H£Nlic "+ik³³³œDøm088ˆÕÕU“·eppEqRáh«©TŠ©©)r1ôD(bvvVeý6((H>ý855¥vúš Úª—é‚NÚUdd$­’»«««¬æ‡‡‡\*((ˆc<`ILL4Ùû)«FÖÔÔ¤s©";;[¡ü)ÛØÛÛC,«hµÈû:>§¼%o¬ÙhhZZšÙ í›yyy¨ªª2©QhkkÃÞ½{É a‰ƒ¢¦¦†鉿¿?ÒÒÒTŒ›®¦²¿²²¢5ÝI6cc ‡&66#33à¤}†H÷²‰®”5@¿?&Èfj•+÷ÉS¾7*ù)Ϥh ª‹—§’5t#õÏ?ÿÜ$¢38qâ¹,sâÄ |ýõ×fQXÄÒñññÁüü<æææLº^†þþ~ÚûËÖûúú4F¡ëB×z·)5æ2«£Oz-ÓT±{÷îáÈ‘#?çóù«¡¥¤¤ ¹¹Yëñ§§§áïï¯W›ô0ƒnD~üã›$¹¢¢û÷ï7jpÏVÁÉÉ gϞŃˆ§Îl­Ÿ3MŠˆˆ@oo¯^‘¹¹9½ÎF´ ²húLY¯^œM­«k[ï‚LíNßÀÆíÛ·cttTïß[\\Ô˜ÕpðàA”——k”Èvqq1(«immÍà>št#sìØ1½ª9ÊgŸ}†ääd“¦|l£~ðàAå÷Ö××ÍZãÀ¢¢¢PQQÁÊú¹¡b!lbgg‡ÙÙY­ïauu5233U¶ÇÄĨZ×Ç “£Gâ½÷ÞCLL +ï–±–3lmm!‹5l7774551š…‘ út º VfEúµ¥¥…q­Ø­†§§'ÒÓÓbÔ+++qøða£Ì·ºQGaa!§žúúú:***Œ ÍssshiiQÛQ‡„„ 22RïiIMUEE…QÎÉÚÚZk‘,€M[N»¦ ¹ØØXüñDnn.ãöŽŽrVáKáÛ¾};ãTÁl nc Ý`Ä£GjüðCNŽ/PRR‚¨¨(bÌÈÎ;‘œœÌ™Q___GAAâââ,:SÁÚÚj `x{{ëT<£‹««+Åù9]¸pû÷ï×øyBBžþyŸgff¢ººZãçÿñÿ¡q0@'øÌØåQ/\¸ÀJ;;;ÌÌÌTuO]d¸¦È~ô#Ÿ;::âw¿ûÆÏýüüðèÑ#ƒÑ¼¼<?~\í –Éò'ÝÎÎÑÑÑ›.gÔFýÂ… øàƒê ŸÏǵk×ÍZÚ>!!!8qâîÝ»§Wl:ÆüîÝ»8|ø°ÅßW///DGGk .b“¼¼<½S§ÜÜܰººŠµµ5VK k‹´vvvƳÏ>«Ñ“Ô6«-PËÅÅÅ,Rf aÿþýœEâ³ymmm‘““ƒÔÔTµŸûøø¨õÐuIËžÇååeÑúd ÝÄFý»ßý.î߿ϊHÉØØ>ÿüs\¸p!!!ä›'''äää ¨¨íííoff×®]CNN+SÑ[‰={öèí)ÊÖÞ———9- £Ljj*£4/mò´t"¯Í„„FÁ†vvv‹ÅÑVgggµŸÉ*ÖÖÖbß¾}Ä ›3nnn8qâlllpûömFÞº@ @AA=z„K—.‘hv3ÀÑÑÏ<ó (ŠÂÇ̨ ‹T*Å'Ÿ|‚ööv<ùä“Fñh ÿmÅPÌOOOܺuKm0`X±KÇßßuuuf¿<åâ₺º:ÄÅÅiÝN…Fƒ®."O"‘ ¾¾ž¼é,cmm´´48pµµµ(++£eØŠŠŠpïÞ=äææâøñãĘ›ñññxâ‰'ÐÙÙ‰ââbZµ¢g¸A=ý IDATggQRR‚o¾ù§OŸFNNŽÙŸ'EQjË•NOOë•Óm.äää °°•á\ràÀ­ gt¢«7+©©©¸uëbccͺtåÁéÈ«dkhh@uu5~ö³Ÿ)l¿uëQRR‚£G’Þše\]]qüøqÌÎ΢¶¶ËËËðññ½½½Â~kkk˜™™££#²³³IJš™ãííììl,,,àÚµkX__‡§§§Z{bbB¡§NR(£iîÆüÚµk ( çÏŸWð(jkk±mÛ6¬­­%8-üüüð«_ýÊìÛéèèˆwÞyGë>óóóÈÈÈØr~ýë_[ÄÌÖ¿üË¿hÄwrr¢50“ôêêjŒ#44‰‰‰P;B CCC€Çâû²²€½½½¨««£í!ÎÌÌ(Hà±¹?—Çæz‰D'êœUY²µµ•¯¥þå/EQ´¢8Íí\y<¬¬¬4®)³¸¸³xÆ ÝqqQ%EÆÊÊJütãÆ ­Ç:~ü¸Öˆ\cðÕW_¢(ìÛ·GEqq±Z"22Rm^^^.\XXÀÅ‹Y¿Ö pss£•y#•J1??O;¨WŸv¬®®ÂÆÆ†¶AáªÁ½{÷,ªÍ"‘B¡v WíàòùÐ÷z¬¯¯ãæÍ›j?å•W/»ˆD (Š¢ŠŠŠ¨’’ª¶¶Vå;—/_¦ôËýÍ©-úî?;;K•””ÐÞ¿½½jkk³Èsmmm¥ÚÛÛiï_RRBÍÍÍm‰çÀ’J¥Tqq1õŸÿùŸÔÌÌ %‰¨¿ÿýï”H$¢ ¨›7oR###F{§‹ŠŠ¨ÅÅEZûŠÅbê›o¾á¤MMMTOOÉû8}ömnn¦º»»MÞŽ±±1ªªªÊäí‹ÅÔ•+WÌÂNÑÁJ$âQööŠÒòò²|tíææ†ååe¸»»C*•baaA­ÎrAAòóóiîE"‘^IöúìÏå±¹Þ_*•b}}¶*[“¥›^£oÛ¹¼¯kkk°²²¢Ýv™hݨeK~,ÙÙY€»»;ìììä1„B!ÖÖÖÔN'êólésíd5Åé>'b±XeYËÏ7W}—mæêêÛri¸z>¸èÔt&ô÷÷c×®] l.È}%g‹@î¡eÀØ   ¡¡ ’„½½½hnn†···Öª5ak!‹Ó‰‰‰ABB‚|{EE¦§§‘ÀŠþ7°Uaœ‡ÞÐЀüü|•²‘ÍÍÍÈÏÏW›ÂB ¶.ãããÈÏÏWIÑ™žžF~~>ÚÚÚÈE"LaÐ===±°° ÿ»¯¯O.MgŠšßÁü‰DòõÈÆÆFùv>ŸO;Û@ ¨‡ñ”;EQ())Arr2üüüÐÖÖ†   xyy¡¨¨éééðòò"W˜@ Èvqq1Μ9kkkTTT ;;ËË˨ªªB^^#éS` A'`>á0@ Ä @ @ 1è@ £±zT*U‰8¥( ‰„¶ @Ø:¨ë3Ö××AQ­B)öxøð!„B!RSSåÞ=ÂÌÌ ’““ÕJy6‘‡Þ×ׇ?ÿùÏ*ÛKKKqûömyµ5@€òòr\»vMa›D"Á•+WpýúuLLL‹dºººPSSƒ––œ?kkk¨¨¨À§Ÿ~Š®®.|ç;ßÁää$¹P›ÙCwvv–—qÜÈüü<òóóQPP€={ö(”OmmmųÏ>‹ððp½1::ŠÚÚZ…m‰‰‰ˆŠŠ¢]``~tttàÑ£G ÷9''ÉÉÉ$ßxAQÂÃÃQ__¯âº¹¹!== T(Ÿúí·ßâí·ßÖxܵµ5ƒ=ûºº:ÄÇÇoÑš7nàêÕ«‹Åøä“Oàèè¨qÿ””¤¤¤@(âÆ …ÈÎÎÆ¡C‡<.5[__3gÎpÒ^6îáÄÄ–——M^6&ÝÃÃ|>B¡ŽŽŽ(--ÅáÇaccƒÙÙYy夨¨(DEEx¬á¾¼¼Ìè…[__W©ØÓÚÚŠ?üáx饗´>°óìàKJJ¨r_›››ññÇãìÙ³dªo“ «iÏçó±¶¶¨©©ÁÞ½{!‹1<<Œ   @NNŽü{—/_ÖzÜwÞy¯¿þºAmÂÐÐ^Í@+++|øá‡xã7PYY‰ÜÜ\µuå?ÿüsÀ_|O>ùaaapqq‘;I|>eeeøñÌY{Ù¸‡÷ïßbЙôÎÎN ¯¯ñññðööœ>}ÕÕÕÈËËcåǯ\¹‚Ý»wcçÎ*Ÿ%&&"11ùË_ðÌ3ÏÀÅÅ…Ü-5˜ÛzEQ¸yó&¢££¡ÑcøûßÿŽS§N£¾IpuuuðññÁüü<|||àååGGGìÞ½ËËˈÕû¸½½½X\\„§§'¹ÈHHH€µµ5BBB°¸¸xë­·4îÿôÓOã©§žÂ+¯¼‚ššdffB,ã§?ý)^}õUøûûsÖÖ¹¹9 ,,ŒÜ8SôÔÔT…¿“““öööò©C©««Cjj*BCCµî÷â‹/âÆ8vìñÔÕPQQ[·naçÎøÝï~‡üãضm›ÉÚSRR‚¬¬,ð¥K—påÊœ={–víe‚ùzè'NœP1:Âø¸˜˜˜ ]ÍõVæý÷ßWÙöÖ[oÏçÃÁÁVVV°³³ƒD"ÁÚÚ^{í5>|§Nâ´­iiihhh Ý”kêêêàïï¯Ó˜Ë8sæ 6Í´™6ô]#3æz˜.ÚÛÛH»>~ü8JJJpôèQbÔ f7ë°¶¶;;;ÆÇX[[Cee%>ÌZ»ìííåý£££<ãH“‡~óæM@*•",, @ii) 1;;‹ÂÂB¼úê«Ø·oߦ¼"‘ãîÝ» %‰A߀D"ÁØØöîÝ«×÷:„²²2ÖfÌ}×ÈdÁeÆXÓ†P(D¿^ƒ dee¡¨¨'Ož$V„`6´µµaxx§OŸf|Œû÷ïc||KKKððð`¥]çΓÿÿ /¼ sÿüü|GèØ±cØô÷prr·o߯sÏ=ÇøÝÝݱ˜eƒ :ŸÏÇÍ›7ÑÖÖ¦2í¦ŽÛ·o3ê¼}}}áåå…îîny ÞfEß52c­‡i£²²Ðû{...ˆŒŒDss3RRRˆ%Ùôöö¢¹¹sssFÿí¿þõ¯´½]]]ÿÖÌÌ Î;'¯$G0î=ìíí5¸”wKK ž{î9\¹rÅ" ºÁ¹CÎÎÎÈÏÏ—¯™icjj Œ§@’““ÑÓÓ@°©XMkdÊÿu=L=Bpp0ãµÎˆˆ È#¤ ››ˆˆäççë ˆôññaÕè TWWC*•*lãWWW¬®®’›n ÑÑÑòAV?úúútÞÃÉÉIµé×zIkkPe×ɨÉÀß~û-222 :ÆéÓ§QXX¸i\mkdÊÿ ¬¬ ………(,,ÄÅ‹UòùAGGâââ :ÆñãÇq÷î]Òsä²*zrçÎOùwÞQÙO*•ZŒþEWWצwp”F...àñxòÏ>úè#,,,púû»víB?'ÇžššbMxÉÖ˜ÞÎ; Pç¿oÖ©w}×ÈL½ÖÖÖ†øøxƒãââ??? ªMc$l-$‰<*›K>|¨²meennnŒt5¸€ÇãiLÛ}ðàúúúL6;gŒcff^^^œýF\\Š‹‹±k×.Öïáèè(JJJðË_þÒr>Îøûêfä™­-íAÏää$¾ýö[Fmhll4‹çbaa)))–ospp€X,Öè(˜Ã’Ç{ï½§±KKKz-W*K,Ý ·µµ!22’ï\ÆÆ5‚i˜™™ŸŸ«ÇLKKS‘%l þô§?ô}@€¥¥%•íVVV×@sssQ\\ÌéyÙÛÛC$1öì´ÍÀÙÛÛÓ6èb±z·all Ÿ~ú)­}ßÿ}ƒäëëëri`uÌÎÎ"$$B¡P¾-&&j÷www780ÎPd÷GSçççåâmtø¿ÿû?î :ŸÏGAAÚÚÚ´zq111¬^¤ÄÄD´¶¶’^Є”——+Hy²AHH&''‰—¾É½ï‚‚…€·ÅÅE­}jkkår§2cèâ⢷A`<µ*ccþ³L ‡ ÅÅÅ8vì˜ÚÏ(Š2ÊZÿÈÈâââhÆššƒÞݹ¹9üö·¿•ÿÍT ~llL.7̶¶¶ŒÏkhhˆ¶æŠ¡på>55ÅY*Õ‘#GpïÞ=ÒCš>ŸÏYÁ‹ãÇãÎ;ä"oRÔE¹ÏÏϳ¾ZQQììlFC§û»ººäÚãÁÁÁM¹kšaÐW4¥µµ•V6’!ž.ÛQýãããŒ"ÕÙ”­¯¯Ëu> 1èlrÿþ};vLc $çSî<àL…ÈÛÛ‰ÄäS*[¦%ÝA¢D"á< а¹X[[ƒ½½=Ö××5~¾Q‘Pæýn4–333òÌs€¢(ØØØ(¤Ú1E 0„ONN" €Ö¾‡FYYã6òx<øùùÏçë(@OOÊàK `xxؤØúB7ÎbuuŸN úÔÔ<==9}Aˆ—n|$ D"‘¼êœ8qEEEäbh³´´„;vhNߘ¹²²oooÏ«´´GŽ„……ÑNUÚX&˜íAŠò”3EQX^^6šr¦¡¸úÐÐЀ_|Qcž¬èÆY ei쪪*Ç—׈_ZZ‡~ÈžA×åÞÒÒ‚ÄÄD£Ül+++¸»»«MY!°ËÔÔíõ46 #^ú&C]”;ð8vBæ=û9`жòsjÈà@OOO%´²²2¼ùæ›§wöôô¨]‹Ý¶m¦¦¦ nw[[£ ×!77We-ßÞÞo¾ù¦Á÷ÆÚÚZ>0ãdÊ] ÀÉÉɨ„••²³³ а$°ÛA/`,–——áîî®°m£—ÌEZœ©1Ʋ—Œ¤¤$Îu?$‰ŠA˜˜/Å…B•4=™(ËöíÛ1::Š‘‘„„„pÒ¾ÌÌLTWW›Ý=äÜ ×ÖÖr–ª¦ ___“”dÜ*0BcÃKøð!Ic#h¤±±»wïÖøyGG‡Qg–ÌÅÅEZò¢\'êB—ªP(Ôi¬ÙXª1Feµ¾¾>„‡‡³~\N úÜÜœÎÒˆ\yé‡FII éáX†¢(VÄ˜Š¡¡!r#ZÑ4-úÔSOÉEBô9×U¼ŒÅÊÊ ­õ`Cäœ=zdpÕEmœìß¿_徦§§cll W¯^EzzºÉ=–@DD"""pùòeÖŽ©¯gfHa“ùùytwwë'$´á¢?òññѸÌùÎ;ïàù矧}¬¥¥%xxxÀ××Wk¦Áüü<ÜÜÜŒ¦ Ç·nÝÂÉ“'Í¢-îîîÅÑ*++áççG«À«Sîccc6‹ tàÀyò=×ܼy“““xúé§µ¹¹¹áÕW_E{{»Eihh@ZZšY´eß¾}¨¯¯7J¡„ŠŠ ,.."??_ë"88O?ý4æææP[[K,6Cüýý–¬Drr²ÎvîÝ»W£Œ­­-ÚÚÚP__½{÷ê5Ѧ¾YZZŠÂÂB‹}Ö=z„ÆÆFºÿlÝÙ™Zé—ÑÑÑèîîVûŸÏ§]ϪA7¤šÛ888àÀœÈÍÏÏã›o¾ADDŽ9B{ÄèÐ!ìܹMMMñðKñ.úê3ë‹@ Àµk×£WÜ@ZZœœœäJ\ö¼àqj𦢆¢Oå²™™µ3l±±±Œî}yy9®]»¦²}hhH%[ßÙ2,--É×Zež·¡ÕeíÐ7óD*•bzzÚàûŒ±±1ÆßBll¬ŠôíÙ³gqýúu½7==ßÿþ÷*ÛWVVTÒ)õEŸc°jÐSSSKr——¬¬¬8Ie›ŸŸGqq1rss‰'DGGcee…•‡Û˜žŒ9ššŠ™™ÚÍú  QZZм¼ûì3LNNÊÿ^XX`%v!%%ÍÍ͇i„ôÌÌ ­”2&8;;+-YySYzš.ôþþ~™-ºJ¥ª[Ö¨®®Æƒä¯­­Ége***h§*g è;È×4 aZ&•¢(“•Wݳg|ƈUƒnN^œ .ÄæççñðáC|ç;ß1H ;;f݉ÖÕÕ!==ÝìÚ•‘‘¡Ð1°Á¾üòKäåå$ ³gÏ´µµ™] KG¹PÊ—_~ÉÊ3°}ûvÔ××ÓÀ-,,ÀËËK¡Ûðð0BCCµ~OWå6•ÙY±.g4¥æíܹƒƒƒ SÆ2o¿³³1118r䈼è ]ƒ®|¿úê+yÿ,•J;„ÞÞÞèïïWœèàà ö]LJJBKK  ©©I«ŽðXÙMÛ;¥2mÞÔÔ„””ƒŸQmZö3ôîîn¨Õr7‡²fÌ qèÐ!ÆA5ÊS<ê¦ÛÌ…ááaÎ+æ1eÿþý¬ Öúûûqÿþ}üà?Ð;_Y§OŸÆ7ˆV¢¼¼\Þgè;s¦œcîããÃÚš{]]­5fggg+™‘׆.Ñ+{{{VÊgn„®˜Œ:|||T¢òœœ äõÑ•g$è(„*×v·±±aM0ª¿¿_­X‹&m‚5Èé(ÌÙÚÚj\s¯ªªÂ“O>©ò ¶É:D:XYYq^ⳡ¡öséèè¨68pc@«rp«¦éxå÷ªw2ÖÖÖÔ®‘'&&¢ººZA(::«ò¹··7-q!C–"ôAY¤Gƒ o èîî–ÇØØØ`ddD%MÜz«u —.]ƒPZZª5‚›¢(477£´´§NbÉÎdA¤ajjkkåÓ8–À… 099IkM½··ûÛߟŸoŸììl”——«ÌY>´r'üàÁìÛ·Û·oGcc£Q¤WÇÇÇå•¿´ ؈;Q®›`ee¥wÆIUU<ˆ£Gj4ʺҿ˜””U^[ ÁÈȈʴ´L_>$$}}}œ{ýL ©!TTT ;;[aШïò`yy9:xúé§u_{6N\$±š Ï5§OŸFHH¾þúk477+¤¬¯¯£¥¥ü㱸¸ˆ§žzÊhe £¢¢°´´dS£zy-æ@zz:vî܉‚‚ *ÜW‰D"—]YYÁË/¿l´vùûûcqq‘T‹ÛðމD"ZfPP&&&4~.›53ÆÀ¬³³Sa&@êJ¹j ½¼¼pøða&m©gºP·¼acc£ð§k¾|---il£¹³´´dp®9]§…sƒ.PTT¤QåÆ\‰ŒŒ”ëëׯË#o¯]»GGGüÓ?ý“|ddLvïÞM¦h ((ùùù˜Åûï¿/¿¯ùË_°ººŠüü|é)\ÀEú¤¥2<<Œ¢¢"µ‘ÇLøéOªâ!êr0˜Ôœ`SJº¡¡<Ož–œœÌJ.<ÂÃÃÑ××Çh`ª¬›¡kyƒé=¤³Ô7<<¬·Ó¡" .zzz011!O/ôòò2š^ZZªªªTf5XÑrâ‰',¶¢Xdd¤Î >ÆÄÕÕnnn˜˜˜Oš³ üaòÀ›‹\-øùùA `eennn[Ú ‡……!,, Ÿ~ú)f…Ufgg5æ÷=zøÃ´¦¡qñ~Y[[C"‘Ð2€««+áêêªWl!xzzbeeEïïEEEá‹/¾`M¿½±±{öìQûY`` ŠŠŠ´.¥0y—JKKYsÔd©ÐÑÑÑØ¶m–- 6hгØ:ôê3Zñ“­D^^îܹc–ê{¦D9ðJV DÙÁßßSSS …pttÔx̶¶6$&&õ<´éqkBÝ`¦®®ŽÓÁhXXΟ?Ï軵µµ´ÕÜ4!Óž×UvVW~¿µµ5ç©btèêêR ˜žžžÖ;®ÃÊÊJ/¥ÁŸÿüçÄ [ rÑc"‘H,º‚’¹c°Âf2ä*ÛÕ•À”Iu*K™2E—@‡!hŠ¢VŽŒ×ÔkÒŠØ««@gÀ Ïó«_ýJÁP1Éâ`«ORR­ dÊ(:^½¦rÑiii¨¯¯—ÿ­I*V›ÈަŠ.^:÷t3%++Ë$k®7nÜà$מ𘄄´µµ/uóõMã¡‹X,Ö:0}ñÅ9;/M5¹eée2¥µÄÄDµ’Úž¦¦&­él+++Œ‹–ŒŒŒ(¬IïØ±C%»' @áo&ùât™ššRù½œ;wŽ3‡EÓr€¬¸X,†½½=Ž;¦¶¦ÄúúºÆ2âccc ÒøÛkkkèííetÍ 6èëëë˜Ç#½5ËTQˆI'hcccòzöÄKßÜÌÎÎrõÿ½ï}O딼)éëëCDD¢¢¢ðÌ3Ϩ½>L+¡}öÙgZ󷵡\°$44¹¹¹&»N999 Ø>Ÿ'''¸ººâõ×_W; PxÙØØÐÊ«­­ÅíÛ·McÐ% ÚÚÚ̾j˜%’™™‰úúz£¥;áøñãäÂÁKïèè°¨TO6™ŸŸG[[g¥PÇñ l·Y—^;t¥vÙ¾‡êM™+{î\Ì EFFÒò¼5ÍðÅ ;::âСCj׆sèÐ!”••ÍC7¤ÊA¿—ÛÒRÝ0 IDAT=Ù"88‡BDD„Š#®Ðéùøø¨D›"΃ÍwcnnNo{:ˆD"øúú2Š`gå ^å4¦ef¹@Vg£è¶”9;;;ˆÅbÔ××›U kÀ-¬WbRf``;vì0‹¨Ñ­â¥né¥*ˆÅby9Nà±ÈÈÆk¢NX†N©K¶Ð7PÉÁ¡×ÜÜÜLR—{£Æ½òººL宲²Òày¦H¶–.eÏìââ¢Ú›ÀÀ@­BHÚˆ‹‹C{{»Ê=ÕUÁŽt ÃÒ¡º‚mìsòäIܺukË_}òÐcbbÔFÆsEDDz{{i$±µµe¼D¦I“Ý SB–Ma}صk—^’œœœ/íܹŒ¾«NµÇãé¥TJ ºàéé @À™h@ €ƒƒñÎM€«««AÒ›äz‡ºº:¤§§ëÜOVªY“wGÊ´þ¿>Ç\ƒO:…›7orv|:KFL³ îÁ×ÖÖÐßßo4É»­ì¥sUíîÝ»&fÝÊäåå1ŽhµT–––ÐßßÏØ}ê©§ ±ILL Z[[²B|||4j’§¤¤p&ïêääÄJ~>œõ^:JJJ2Éô»2YYYjE¼~ò“Ÿpö›²,m0­o°A—J¥X\\´Ø©"KòÒœœ¯Ïh‚ÏçÃÖÖ–ÙØë4u “1‘­A2òß·oŸY<¯...èèè@hh¨|[@@€ÖÜé––$%%±Þ–ƒâ¿þë¿WH”iÊ3ÁÆÆFï ·ääd5@S ©¤iNN£ã*šÓÒÒb¡ÁÝÞÞ©©©Zå ì°wï^ÔÕÕ±zÌòòr…ÓxéwîÜÙ2çëçç‡ÔÔT£U14'¬¬¬´ž·¦5Ó˜˜­ùå²é|www„††¢©©I¯4»ééi­‘ÍÀÐÐÂàË›§i@igg'w’˜:Èؾ}»ZÁÎ :ÁxØÛÛ#66V^ÀPdÓdúÆ °»»;–——É…03ت&&ãŸÿùŸ5ʺº¸¸àÖ­[j§¢ãããµÀrppÀ›o¾ àqXOOm£¢œ*¸Yéïïg%½úÌ™3ZK½’Gþúë¯cÛ¶m ÅÐÐ1è›ÈÈHôôô°r¬{÷îYl âÍÆñãÇQTTD.„ôàà`Ô××ëÕy;;;k ˆÊÊÊBcc#ãå¦SØ[=X¯»»[EâV«Ñ´¶Öª¿¼¼Ì¸¸•¡ËÄ [ š9ôauuvvvfiJŒ:Áܱ··ÇÐЫeXß|óMƒã<==ÑÔÔD»ˆ‹%§Ë™Â ëâç?ÿ9+Õ*õ^"0Ø ‹Åb477³¬EÐL``  Šj-++c­.0ÜÝÝaeeÅYÁsavvÍÍÍàñxHJJBKK‹ÂçÊE9&&&Ì"ª] ¬?š +Gjccƒþþ~ÚÆ`×®]èêêһܧŒ ¨¨HA¥½½±±±ò¿¥R©V6c I æÄ‰F»‡ú0<$''“‹hƃµÍõîé鉈ˆ8::ÂÝÝ]aºsÇŽVØ?..ޱ±a‰D¢1ÀÌ\JõÕ7ôrÿôéÓ¬D-Jii)I35`HG‹ßÒQ»0T__ššüìg?SØ~ëÖ-$''£¸¸ÇŽ#O‰™ˆÃÃÃqïÞ=ØØØÈÕ¦`kk‹sçÎmIe.K'&&!!!(((Àêê*ÂÃÃ<ÎtÐ¥m,(ŠBkk+VVVd+WWW177‡””yéÌ––y?ÒÑ3g΋`áDEE¡¦¦†{ƒ^]]ññq„††"11ƒƒƒ*;‹Åb„††ÊåG»»»å)'½½½¨««ÓYEfãˆ^“b’¡ûsyl®÷—H$X]]¥íIËÔÞ6ë••¹†¼½½qíÚ5³;WumׯÂÂ\]]Íâ3ÆþêÎ_V/ûܹsxõÕWMÚ9}õÕW ( ûöíCNNnܸ¡ð¹,UIVC¶oß.XwqqÁÅ‹Y¿vóóópww§¥”&•J1??O;èNŸv¬®®ÂÚÚšö—®c …BrÚ²Ýf¦ûŠD"…BÚB+\µƒíçCV«¾´´Ôàþ`#¯¼ò 233‘ˆG)ÓÜÜLýë¿þ+ÕÑÑAQEýõ¯¥(Š¢îÞ½Kݽ{—ª­­UùÎåË—)}àrsj‹¾ûÏÎÎR%%%´÷ooo§ÚÚÚ,ò\[[[©öövÚû—””Psss[â9°$¤R)õÅ_Po¿ý6566F‰D"ê½÷Þ£¤R)U\\L]¹r…‹ÅF{§‹ŠŠ¨ÅÅEZûŠÅbê›o¾á¤MMMTOOÉû8}ömnn¦º»»MÞŽ±±1ªªªÊäí‹ÅÔ•+WÌÂNÑÁJ$âQööŠ£±••H$888ÀÅÅ«««puu…T*Åòò2<==UFÈÏϧ=¢‹Åzå®ë³?—ÇæzŠ¢°¶¶FÛ •U¬¢µ®oÛ¹¼¯ú¶]–>D7ÅÄ’Ÿƒ­€>Ï–>׎Ëç„Ë盫vpÙf®î¡T*…T*¥­Go.öËvÐA­AgÂÀÀ+Â÷ó‚ÜWy¶äZŒ úÀÀàîîŽãÇË·÷ôôàáÇðööÆ‘#GÈ&€û÷ïcbb111 ’©åå嘙™A||¼‚\(@Ðk¦ÞyCCòóóU"U>|ˆüü|ÌÏÏ“«K äLLL ??_¥®÷ÌÌ òóóµ–%4 :Ó/*Kéõööbii nnn$…@ ¨E$Éu³7Š!ñù|"xD ˆE·„EáÞ½{HNN†¯¯/=z„ÀÀ@xyyáîݻػw/1!rŠ‹‹qúôiX[[£ªª ÀÊÊ *++qòäI³ÔÔ&6½A'`>-w@ ˆA'@ :@ bÐ  ¡Pˆªª*Ô××Ë•à€Ç5IõÌMfÐÅb¾ÚúûûU¶ñù|\¿~R©”\9 G"‘`ddDe{oo/1&„Çãáå—_F]]JKKÊ+ÿîw¿Ãk¯½½É=ôû÷ï«­Á|óæM?~\^ñG"‘€ÇãÉÿCo¦§§I§I0EáêÕ« yå2 «« ^^^xøð!€Ç©k²þBVp³#«°Å×®]Ë/¾ˆK—.á¹çžƒH$ÒºÿíÛ·±gÏ>|?úÑàêê (..Fll,©-`‚{htƒž••¥±¬›ƒƒƒü!EEE***ð³ŸýLþҌ˿ýÛ¿á¿ø¹“`ee…óçÏ«ímmmáëë‹ÙÙY@KK‹¼ÏxòÉ'·Äõùæ›oT¶UUU1:ŸÏ‡½½=>úè#¸»»£¹¹KKK¸xñ¢Â?YÐÖÖ†«W¯âÆxöÙg166>ŸÏ>û ?üáÉÃk‚{È%¶š<ô††„……aÏž=x÷Ýwñꫯ"00r½å°°0¹0ÿÇ! qûöm¬®®Êµÿ~¸»»ÃÍÍM¾m}}+++èîîÆðð°|{LL âãã·¬¸Ä7põêUˆÅb|òÉ'pttÔ9bÏÈÈàT6“Çã¡¡¡ÓÓÓòm))) RP÷¢( KKKAWW—|{hh(RSSiWp"Xž‡þÕW_¡¥¥éééðõõÅ|€^x÷îÝáC‡òï}ôÑG[âúTVVªT$›œœd|¼„„ØØØ +++puuÅ[o½¥°¬Z£­­-Ž;†'žx(..ÆÒÒöîÝ‹¡¡!ðù|Œ#88˜<ÈZ‹ÅxðàÂókÈ=dúøµ4–——Ñßß¡P¸%Î×ÑÑQå\¹ëêê G,3Ë{M½§§‡{ƒîàà€¬¬,„††²~±±±èèèØ2ÈÒÒš››ñ“Ÿü§NR«` ÊËËàØ&-- õõõ[æ¾ …B´¶¶"??ùùù(**ÚÒbÈÊÊR‰·Ù*{íØÃÃKKKfu jjj,öJ¥R£Æp…Btvvroй$>>ííí[¦ó»{÷.rssµ¬«½‹‹‹ðôôÔë˜KKK´cbþô§?éÝæk×®qê$rçççÑØØhÔ{XYY©õzôôô 22R¯cŠD"ÐÚ·££Cï™ØÒÒRµƒ>ƒ ºD"AWWg#JY´ûf§··WíC“––¦¢‘Í%‰D®2Å%þþþ Ês›•ÆÆFµùúÙÙÙ¨¨¨Ø’F{aa]]] …B6@¦¬®®2$QÅÈsmmmU蟔çççáííÍÙ;XYY©ð·P(Ô¹œ522¢qɇI{Ù¼‡kkk J£úÂ$àtii EEEÑÑÑ!WG¥‹>š |>_e¶’NìØ­[·Ø7èEA$qêmxyy±EoNðx<ÓÜvvv¥÷è×ÁpÊØÛÛoêå>Ÿµ)/îîîX^^Þ’]*•âÿkﻃ㺮óÀb,z#z!ˆF °€EìE¤(R ¢h¬‰‹ìK±ìHžÄvÿðLâÄžŒ¬ÛqâLL;V&!Šb ‚$@€D%zï½Xì¢,€}¿?ø{ϯ¿ûÚ6¼oF3ââíîÛ{ï»çÜs¾ó••Öakk«¬Ï.))aý!àʇbË4ã¸sç㚘˜eÐQ›¦>?ëæÍ›¼oll¤ü›Íð(Â#WýÐ×9 Í6‡ƒƒƒ°´´‹‹‹¡':Pɪt[DŽ’’Qëzyyl6›ý º——$%%ñ’”‚N§õãÜ ›6mR=îÈ ÞÝuØl6¤–‹~~~v©`p&BRR…€I'†……©Z––FœôŠ‹‹!77—ø›¨ËÔÔ’òWrr2ôõõ ^çïïO™w."2nܸÁù·çÏŸSþ½¸¸ÈɶF!Z,Áñ§§-ìMð$§a{zz %%…àäÔ××#UàϪÁ` RG…¾/11(c&”f«¬¬äÔläåvÐ@U º=æVyt1(“)<€Ã‡;lÒÓÓ7„xvÌÎÎržqCŵ âEBÊjø)ÜÃÃå[__‡õõu¢ÿ÷úú:+I“ëu.üÓ?ý“]Æ ?H)Ý褽½× ÎÏÏ3ö.®âýû÷àet•ÍIÀké…æÐl6ƒ¿¿?DGG3î­¾¾vîÜIümee¹tÎjµ‚#ú«ÆÒ£ ‹üýýàeGÆ+W®È:к”A?tè[©kMLLˆj‚b4U1ê³³³æ°qp·<º”Æ ¹ûšÉd"6¹¬¬, Û¯ëæâÏxzz“'OCÈx8–nÐéU&l½ ¤¤ºÆÇÇ9•'&&!Â’ù7('J%Q[[ yyy”×`uuN:E)EûÏÿüOxY'NW¶xYé211!(ÔÕÕiii.Z™´¡¡^¼x!JÏÃÃùÀ!•DLèõz¨©©í۷󮊊 JúAé×ÜÜ\d!z¹xýõ×yÉ!ra6›áÊ•+“““¢ëÕDBB‚hYA! A||¼Ã›Ú=Ò×××áæÍ››› ¬e-JE,ˆ~ÚÜ(­d^’™rss‰Ü!ŽîînHMMe}Ïôô4ÌÏϳCÙŒ¹ óöíÛ’I—óóó¡6]öøøxÊsÙ××ùùùŠò}øÊ¹ð9‹êXI=ˆ `>°Ía}}=£Ì³··RRRˆçWÍžlû==£È%j|>VEÊÖBCCyË”„^¯Wu󫪪‚£GB\\ìÚµ Ué$'vÓÇÇZi–ÿúúº¬PŸR@eKÅ7àôéÓ G…©©)U–RÚen4  \wl¬á?þ˜ç>}úvïÞÍy²ÆOíÇŽƒ}ûöI¾_²L)Û3ËzG)cbsîØœ¾¾>(,,d•€öññììlEçH¨ì?Á a||œÑçãþýûD‹TrÿˆôôtJ¹9Ò•””ßøÆ78׉˜²i1é ÔZzú^†z$ómèœIöXÛ^¨a___ʆœ­ÊiެG-Šö|f#9jV0àž=y¼÷ïߊWkk+deeIzïFÍ£ÓOŸxM¶Õj%„BpF8~ü8áŒ8p€“á+Ãy{{'=lݺ•¢õ„t`¡·Ùìíí%Øó¨ðööæ$¨’Þ+W®ŽEaa!rg¯Ƙr91Bùààà`‚'PRR'Nœ`\ÓÝÝ `ÊΜ9C¬yüsØØëAAA077:ŽˆÞÐKxÙ:›¥¤¤PŒjhh(áàñ•—ݸqÎ;G9𠔟’‰äì<}ú”ˆììܹ:¤t¥Oçt’î¥*}J¿u뱨ÅÀš¨ÕU®¸¸˜ò⧚͛7»u·7W½f^}øá‡ŒkÓÒÒ(ü///Îò$©úô÷™3g`÷îÝÒ[;Tüwttt@ZZ¼óÎ;¢ €—‚7¸ÃÂçøao¾ù&á  Ú°¬GGGá÷¿ÿ½¤|:î„rz?øàÖ.ÙÈó…¶é§vÜÈ j"##)œ ¶qššbÔ㯮®‚——\½z.\¸ðÚk¯‰“ÐÐPøÊW¾"xÝÐбÆ===EGlÝÆ GGG‹ê/,fcaT5Êå¤x~l Uš››aëÖ­N3¯jˆçà,ÛX'$$ )f‰Á‹/$…ÜwíÚÕÕÕšu'!)) ùZ½^¯Z饯¯/$%%Q &_t7š)))¢7騨XÁÈÛÞA®‹¹¹9ðõõUœŸ#v@U.ý^jkk)¹E*î $%%‰NIúûû³æÅÅbrrRôçÈ2èÝÝÝpõêU¸zõª];íÛ·OTŸ\TWWC~~>û )œ»–’—Áa4c¦’µÝׯ_‡óçϳþM ±ž¥¥%I)ŒÄÄDÅ gDyy9±gˆ©6à;•}ûÛ߆ÀÀ@ÅóÈ|˜žžfÍ“ÆÆÆ:pq"Ìf3´µµ1NPAAApòäIäÏÿì³ÏX_—#‡¼iÓ&'Tô¸°eËèêêljð²4Lè~bccyÕåøÒ#€ððp8tèÃAí‹ÀµNÚÛÛ!==uæŠôþå_þ%㵨¨(GžÃ¼¼< ‰QŒà>wQQQ¼s¨¨A×étàíí ÞÞÞŠÄÿ…ÎÎNÁÆ{öì§OŸj;² 9j(Ž“Ð¦'UUU°gÏm"yàééIì(Qª˜˜ÂHôöörÖŒãŸE¯‚•ÆœœäTsä"W‰‹â[ïjŸôÉãÇ{`éèè¬ß°{÷nbïÄsÔ|÷DÖÀÇõàÁVî555%J‘“kóòòX\ó$e? •EÖHq€^j„J<BMM ìÚµKòû“’’T-ñr$è³àÄ{EàBÈiÓ>s#€œ‘Sûìê «9r);z{{æM› €5ý088ÈÙ`&((ˆ ý±¥õðJ‚¶¶6Þ"l ïHå¹â‚”Hˆ¯¯/Áár ‹ŠŠÜÏ ÓÕ™ä`ppP°Ó‘Þ“R§†øøxÙ¿½©©I1U#¥çU rŽ¡Ä)}iiI–C\\œ(u1 Ò!GnWI©d”µŽ—7áßyíÚ5V^ÈñãÇaÛ¶m ×ëYÿŽÊ"‡–ñûÃ÷›îîn·P5ôòòbÏŸ?×®]“4‡Bkittþô§?"^\ûozz:œ={˜a\‹ï»\Ö “Ã8r066†LTˆˆˆPEdF,”è=<<Œ\»jOlÞ¼Yu>1ÄCüAÑ`Ø»òÞ½{ew&‚;w*âvwwÃxëááaøàƒ?‹Läb#uqåzqÐ+4üýýáÓO?¥pVVV¾èèhwÉ–Ö~~~¬ÑV)¸~ý:ïéÛl6ÃW¿úU¤C#~( Ïadd$üÏÿü/)Z¶A_\\„¢¢"hnnv›~REeÇ*Qî,„8±2‘®†ÊÊJdu0r¸Ñ‘°‡Ô¤3 »»ŠŠŠ`ffFRã9 K·Ê©6á2¨ˆŒŒ$œr6ùOOOOÂPÚ«y]:<<ªªªQI|ÏÄxJJJTkíìÌ K6¯¬¬€ÃŸgÙÝÏÏ íZ2¢$L&E«YrÅO6B©˜3@LäE ˆaânt¤¦¦Baa!„……ñöÆAîûMvèxKq¥8¾è€£È¼éééÐÙÙÉù÷W_}nݺå4sF˹¹9ÊZGéÁÀæ”xxxvJSCîZ)Ð+*èHLL$ûôõõUT088¨J„T#Å)ü ¯É‚ˆïw5(IŒC…Ü4Fww·h™O¡M@ßOŽt'x÷îÝp÷î]Þ0çÉ“'áÎ;Šn99îJTÅ ùÞ½{‰ç?üÃ?P :Y‰K_ŸÍy2PUUÅ{Œ‹‹ƒÎ0¸N§ãuÚœtÍúºº:E"¤ôquiƒ^PP K`FJÙY¤WålüÏŸ?'Úò9#äæ´¥èäçääpŠL ®%%ºÖ©Q‹ïÌ «s©6¢âãÇáÀ ÓéD)™ñUÃðÖ»K)e+9!\±¢TiiipáÂFCz³²J_™Ÿ’‡ ÁÁAˆ‡´´4QëÇh4ò¦<¨øúS’wµººJÙÛè͵\Ú ã RQUU{÷îuÉß¾yófÉ­Å(9(ZÍ|àS‡ãûNgÈ£ …‰Ý ;wîdí Æ†¯ý늬ۉ‰ Ø´i¤¦¦2Zv¢×g_[[#NŽñññ¼õçRJ^“’’ÆÊËËKTš€Ìj€Dï)o½õ–àw;v JKK‘îçØ±cŠì¹8($$Ž;†ü>Üùˆ‹‹ooo†óÏ&(#û÷ïg(@zyyI.Ý#·fX¸z8Èù©ytg!<ñuÚÈàR‚WOc èØ²e‹`*+55UÑ6ÍRS_x›Ë††âTîçç'é™âj½Štz~úüùó òçæ®ÓÁØØ¥™ Ä:Áô“# Ù7::ZÑg%66–1@AVVøúú½{÷(]âPÇ ÕY d222T㜹,ˇÑY äddd i$³yWJnHRZŽJmÛjoH%ð±MÅD=¤”Ì éhx œåÞÞÞ)))¥Š®¾XèõzXXX`œT鈌Œ¤´I•ƒ´´4hjjb=uåää0Z7ët:¢NYd. JóüäÈu‚äÓ®ˆ—üÜ) TçB‰v¥ü=!ÂÃÃYCþºstG³Üqâ‹XôôôˆnmHÞø¥„»¿øâ ä‡Rº…‰)çr$¤rŠ‹‹%±kU çËI•ªãí ÀYîF£¢££yÛ…ÒûZ+®å±cÇàG?ú9rDp~P5¹é††œNihh€íÛ·ƒÅb‘ÔÐGl4‚Üã ™™™šš Û¶mc•ØŸŸç¬â U‹uÎýüüŸC///΃I}}=R*Ej¤€ülÎÏÏKZ RÁv ôôô$R3–åÞØØèÔÄ05 W½±He5KÍÝÓëwåâôéÓ’œTW™Lª“…ƒÍ8³õY—‚ÐÐPäk333á“O>O>ùÉ@ª±}½•šC± ¤œxÙæðÌ™3¬ WÄ"$$y¿0 °°°¿üå/)Nš=#žBsèò]¯×‹îL&³Èñ”äÔ£; Rûu» äŠpDGGsv`²Ôf~o$°i :òBÏ÷¿ÿû¿#߇Ñh„¹¹9hmmEì{ôè‘"Ì뀀QßK> 677ÃÖ­[Ýrÿíßþ 9 ªÓé`vv©îž %U9·lÙ›>qyƒ.EG‰þ¿™™™ÐÞÞîrãµ¶¶æ9tüASò±¸¸(;t™-Š211!‰H£ôšÞˆ@a7=zTòçß¼ySÑû=þÔÔÔ _çÎ8uꔬïvoiiQåôâ,zÎ C'ÕÚl6s9<<\VšîðáìLø3gÎðžÈ”T³ •¼ 8Pb#d999ªÍ!0êîwíÚ%+ç}øðaÖ謿¿?縊)«“;n.Ïr ê"£ ±±i! ALØ]­îfñññÈÝÉZZZ\J¢W¬†#Z3*u‚b; ´µµ¹¥!ÆYîV«•ý æ<9Ú[.ÙÓÓæææ ¢¢‚òº^¯—]îùꫯ²®s.|ç;ßQtMË1.GŽ!Z{â Kš$''³²ÝÍãsxÿþ} ™ÍžåyÛ¶mƒ˜˜¢œtzzš‘*pW¸AwD‡.1›¿šýŒSRRÃî­­­-=‘ ???¤´†ÍfS4׈Âvgë¦$:>Üp„Î >yò¤ÝïaffFuƒ®dúOMdeeñžÈÙž;“ÉD‰D8bM&ÄÇÇ«:Î^^^ª§1ÅpµÜÆ ët:HMM…®®.Îkz{{9‰ R±ÿ~y†¹µÑB@ »rþ\H\¤´´Tq ›³½!¶lOÃËŒ•••²£~ø!ìÝ»ªªªT»Wµ•dÉËÝOŸ>ítû >‡_ÿú×áðáêv/ †]»v©nÐQ[3»Ë‡A¬®®Žh¬`¯äÜÜœêá&ðððà” µ7KX ‡…o}ÍÏÏ+ž‹"ƱµåTîZ޳ÜÅö!P2¢ÃwâxYe€"AêìàR1<þ<øúú‚ÕjԮ烣S‰|s‘‘‘¢»Ü9#222¯=z”Ámp –;ù^¸@5‰iƒsÑ”––ÊF@™hxxX¶Ž#‘ccc¬êióóó`4U)Wãë„¥V"ééé.)`ÄœåΕ×|ûí·)ÿf+õ²×~òíoÛ-#™™™ªèbàøÒ—¾D‰J:j¾ÿýï»åúûû3*·b¹ët:ÈÈÈ`­ßmnnVÍé8~ü8Ü¿ŸõoJçvù6~®pxÿgWF||<< _|ñ\¿~vìØ¡šŽ„„°Z­D§®™™VT‡YÞÞÞàééIäó;;;aóæÍ.:Ç‘˜˜V«®_¿Ÿ}ö$%%©.ØKKK7£§§BBBìyø³º×‹/à¥Ü¦³uc›˜˜`8´ÕÕÕª¬³Á"øáããƒlGXc•Ïž=cm!YUU/^„«W¯ÂÅ‹ahhˆ`•÷õõAMMÓ{½^ëëëàíí ===vëþ“Ÿü<==!,, Ž9Â8Ý© ƒÁ?þñaii üüüàÌ™3v¿{üÆ€€‡ññq»¬¥Ÿüä'`±XÀÇÇÎ;g÷1ÕétðÝï~üýý!66 f>0 ƒææfXXX ôH0›Í033;vì€ÇÃÁƒ¡¡¡æææ`jjJ•qŒˆˆ€ºº:UKE5¨‹™™X\\t»½KÍClddäŸ ú“'O`tt¡  €“Ý«ÓéýØððpÂܺu+¬­­!7”¨¯¯‡;v ß°˜ëÕül¡ëÉ>b>ßb±ÀÈȲŒéøø8`FéuLĠχ#džŽÑÑQÐétÈ„½ŽŽˆGn‘ªä½“PH™W)×Ó±{÷nʼ“ÕÔ‘‘¨¬¬„½{÷¡C‡ ¸¸˜òw›Í}öäädBÒvÏž=ªì P__t:]__‡––äfMbîcxx||| ""¡{œ˜kGFFÀÛÛ™¦Ö}øúúÂÝ»w‘Å}Ôº›ÍMMMÈŠjÚ)>à%z°²bÁè(//Çþõ_ÿ«©©Á0 Ã>úè# Ã0¬µµ»|ù2622ÂxÏåË—11xøð¡j׫ùÙj_???Õ××#_?00€õõõ©vïjÎk__600€|}}}=f2™6Ä:p%Øl6ìOúöóŸÿÁVVV°_ÿúטÍfÃîß¿}þùç˜Õj•µ¶ÄŒ]MM f6›‘®]]]Å***T¹îînlxxØá{œ˜k{zzDݳZs8==577;|<ÖÖÖT[jì++L¯÷“í!9UPƒ2ÐæUƒ¶¶4hsèeÐ+++!33‚ƒƒauu•`K–——Cnn®ÖªÓ @žW äÀjµByy9Qꃯ­¥¥%xöì:tH$mÐ ’)Ø=‚øøx¢œŸÔÒÒRHMMÕ˜­níaÕ Š‹‹!77nݺEY[·nÝ‚¬¬,())ÑIÛ48 ONNB\\Côbvv6mÚ¤‰ahР›Í¡¡¡ yf›ÍN_«AƒÛômÛ¶ÁçŸN0Ioܸýýý™™ W¯^ÕÂí4h  ,, ®^½J0—ùË_ÀËŽUW¯^u8k_ƒW‡¬úÚÚxzz‚‡‡Q¢âááAy]ƒ È{.Õ‹Ë{bëëë.Ñ\ƒ·5è4hРAƒç€N 4hРA3茾¾>xðàÌÌÌhƒ¡Aƒ ¬V+477Cyy9¬¯¯ÀˮϞ=ƒŠŠ J‡ÈÞÞ^xðàÑŠSƒfÐ5ØÍÍÍðþûïCkk+ÂÊÊŠ6(4h P[[ ¿üå/á»ßý.a¼?ùä())òòrøÚ×¾«««P__ßùÎw µµ.^¼HHõjp-h,'µk×àæÍ›°¸¸ÞÞÞð›ßüôz=çõccc°gÏx÷Ýw¡¤¤–––Tï*§AƒÇáúõëP\\Lçßþö·¼Ï|AAÀÙ³g‰×¾öµ¯Ý»Î;f³†‡‡áÀðî»ïÂíÛ·ayy™wïÑàb't¶îd‹nܸA„n4(‹¥¥%ÐëõpéÒ%ðõõ…¦¦&˜™™·Þz‹òß~ô#xÙüÉ“'pþüyˆŠŠ‚ÀÀ@m58===PYYIy Ã0(++ƒk×®i{†‚{„——üîw¿ƒ¨­­³ÙÌØ#þöoÿ–{ÓÿÿƼ½½ FØ¿?Ü»wΟ?±±±ZÙ±;Ð+** ±±Þ{ï=Êë·nÝ‚sçÎÁÍ›7áܹs`µZ)9·é½M†Ùl¢‰<êC'EE);;<==!22 ((þå_þ…r î‘ÿ×ý|ík_ƒ‹/Â÷¿ÿ}¨ªª‚}ûöi«‹‹‹ ÓéÀ`0 ]§4´(0 ÷ôô4LLLP^_XX€••xå•W ¬¬ Ž;>„©©)âM\<¶mÛžžž àççÇØ#„JGGGá‡?ü!üìg?oooøõ¯ ßúÖ·àµ×^ƒ¿û»¿ƒ§OŸBAA6Øî`Ð÷ïßÏÚßÌðmtt:::àÓO?…÷ß_±vp΂®®.¢‡ó¾}û`ëÖ­¼×¯®®ÂÿøGˆŒŒ„S§N! ôÚ}³Ù ¿ùÍo(¯ÅÇÇ÷¾õ-0™L`4ÁËË |}}aaaA[шèè耞ž°ÙlIiMʆùùyxðà˜L&xûí·ÝÒq• ÈËË#Ú§bKKKàáá†QjÏÉzíõW¥tœ©ååeÆ ßûÞ÷ॆaDÛë™™øÎw¾ÿøÿ©©©`2™ @ÛKÜõ„^[[ ÉÉÉ——¿øÅ/àƒ>€˜˜(**‚ÌÌLxÙ#ï]__ï–ÔÙÙ ¯½öøúúBYYLOOCxx8çõÅÅÅðÎ;§§èNDz½ž8ýùúú‚··73¼oï¼óüýßÿ=\ºt ‚‚‚´æ"ÐÔÔDÌÍÕ«W)F‡ •••püøq0™LPUUû÷ïבdT>ÿüs˜šš‚ÑÑQ‡Ë—/ÃW¾ò†ššxõÕWù®©©)0 °!ÇZ¯×‡ƒÁÞÞÞ”:î@áÑÁ¡¡!x÷Ýw¡££Þ|óMøÝï~¿ÿýï¡§§~þóŸÀËHß7¿ùMøÞ÷¾ÿñÿÁÁÁªï%½½½È½Î7"¬V«4[?t)øéOŠÕÕÕ¹UŸçööv¬±±‘ø÷ÜÜvçÎÎëWVV°«W¯Jî%®Á>˜ÅJJJ8ç­oû³gÏ´yUo¾ù¦è÷TWWc}}}Úàñ¬í{÷î9ý}jÏ:㣕­ œâ¶mÛFü;((t:ÌÍͱ^çÎ8}úôŸÃ^^°¶¶¦ ¤“áþýûpüøqÊ©O—°¡¦¦víÚEIy j©Aƒ§‚fÐEâøñãpïÞ=–HÇ `F!LÊkóóóP[[k×9---u‹9Tã»ÖÖÖ•÷ؾSʘÊ6è>>>PPP “““nïñ€Åb!Né?†‚‚§)e†¸¸8YŸÑÕÕåvý©1 ãmésssDYf]]S•aÎÎÎBHH„††ºÌïÊÊ ˜ÍföövU¾£±±Ñ.›÷ÄÄŒ+‘áãáX­Vhkkc“É$ê{,‹ìµ©¦a·× }—ô÷÷ :­lß)ES_ÑzLLŒCN.ŽÀ‰'àúõëPTT~~~°iÓ&Öëð^ñ®2!Ðßß_öï àÊŸ“qêÔ)øïÿþoøýï6› 6oÞÌz#NÉpàÀ8sæŒ[=O+++°¸¸ˆtíýû÷í¶y«ådØÓØ¢Œá­[·s:QN¬lJ¤Îb€Õ€Ùl–5?¨×h¤8ŽÓ).¸ÀwJã7 °°òòò¸=&Îî}xx˜KeÚÛl6B"òäÉ“p÷î]—Ÿ×ŠŠ Áúq½^ï½÷|å+_üü|ÎëÂÃÃËËi1ŽTyy9ƒØÆFjåsl•Âòò²¤gQ)cKÆåË—6«««Œ¨ÆÆÆ ¥¥…òZ__Ÿ¢N˜}Õñ”3‡(ŽÑµkס|E zBB‚ªå<pùòeÕUŒÚÛÛ ñ¹8zô(+{ZMX­V‚m¿iÓ&ÙQ6 ’‚/¾ø‚³lL)˜L&ÅôîÓÒÒìš×sgpmî%%%²?{~~žáP“™Ã" ªD0Àf³‰:ÉK‰.ñí»jΡÕjeÑââb‚„=11a·–¯‹‹‹ðèÑ#UæPhŒÙÖ6_!Û ãÞÖÔÔEV 477Caa!ܹsGÕIÃÉGJ ((æçç¶YÆÅÅÁÈȈ¬ÏàË;+§OŸÂÑ£GUŸW%áëë«hIÓFåÞÜÜ ccc #ƒ?7000 é{ØœDüsÛÚÚ ¹¹ÙåÇóöíÛ`6›¡¼¼\tî‡PŽ÷ã?æ}>ñq¤>Öëëë’òëóóó¬û®299 ---.OÜÅ˃ïܹKKK‚©AÎ×RaµÃÊííížž®ºq™œœ„ˆˆ—]ããã”|~\\ ;íýNLL@dd$øúúBXX˜lçƒÏñjXáÌPÒÉt4È,wcccðüùs"gÝÛÛKÔü²•¢ ««‹÷}ô0.ì‘nª¬¬„††ÁÙ`cÆ8ÑáF·µµfffÙîBcª}ÐÒÒB/üÿ1 “t°™ŸŸçÝ¿&''‘R_ÕÕÕªŸâ§¦¦àáÇ‚¥Ât§‹þïúúzرc1'bÖŸlƒîíí [·n…¨¨(xɦw]R­­­••êæt'''!22Òm º´µµqÖà«1¯xý^/iãFÝh„ëhÝþ ­V+F]YY¡7.uF©˜ŸŸGŠFUä”ˋŜ½¥¥0 £ì{+++ðÛßþÒÒÒàe¸7¼---°¶¶†”ïíéüPÞ IDATéá$²9 t,,,P´õÉŠlÄ•ŽT®¬¬Àµk×®CJ¶µµI>œ®­­ÁÄÄgÔ‡Ë@_ºt bbbX26ƒ¯ú ŒÈÈHUJ×È$­ÀÀ@É¡%/Ké:Þuʘ™™¡œ|¤ ££Ãn|¿[·nU-ÚÝÝíÒex(DMWDss3E^™ Jäbqlݺ>úè#¤=d×®]P]]äTH1èäõNþ|úw±å¨›››‰òÒ;wî0òè|Ÿ'ÅYä¯'Ož µmVr#"" ªª Yè7¢f³™×°·µµ‰Þ«ésˆÿN”9ƒææfˆŽŽfg³ÙL!R ­AÅ zrr2ôööºì333ÃÛMM*ìeÐ_¼x!!!”×Ä:@dç —ä­tvvRŒ¬Á`p›új¥Ñ××çöÝ©ORçp~~~ö³Ÿ±Ðððp† +þÙ|ßñôéSÙ‘‚õõuÊ:ioo³Ù ýýý¬sˆƒmÇÇÇyï·¦¦†òw¡5¨¸A×ëõг•[[[cóaiiItÿrW€ÑhÅžd3èF£Qt-¥Øp‚ƒƒ¯ï¶Ùlªp/%‘µ4°#88˜‘/%×ÚrÕæ²m”½½½ðé§Ÿ2H<œJßïß¿KKKðèÑ#Ñþ7 ­­ ƒ Q²±±‘Á€ååeJ‰\ii)áÜxxxÈ~ö&&& ©© nݺE/Ôrªºº:JynKK §Ô7ÛØJ™Ã……øÕ¯~Ey­¿¿>ÿüsÞï¹ÿ¾è=¤µµnܸì”ÑB‹ÅCCC088‰‰‰ÄþFžS¥öO¾9”mÐWVVàéÓ§²4ÃQ¼mWjtŽ›e¤bbbs–¨˜œœ$8J‰Ú¥vî%´ÜÍf3Á·Pò乸¸Èج…ÐÜÜ +++œœ ýýý’¿o¦4;; ‹‹‹’s¹•••PPPÀiŒÈãÅ6v###Œ¹9zô¨âŽõõuÂyBÃÕÕU¤(žXñ¡îînEÒ¸¸Tôìì,ò½²¡ººšÒáX¬­­ñΡlƒîéé ÑÑÑŠÕ÷rM¢··7åµÃ‡+^ßÝ××ÉÉÉŠßNNŽ$ Wh^¡4²²²¯ .//'Ö”Dll¬$V>Þ³ñÑ#&® 6–;›aõõõå5¢ï¿ÿ>2·¤¤™p¹°°À[k<77§ŠÞFXX´··sžšoÞ¼‰ô9ËËËŒ± fä_ûúúyÿ/¾ø&''×J)£bsØésüÁ ×u ˆâØpõÁ÷ÕçÏŸ«2‡sssð»ßýNÖ¾¾¼¼Ìp ž>}Êêø§ì]ÂËË  ((È®›‚N§³[^Z.¶lÙ]]]¢˜K—.)*s¹!¤ß.‘‘‘’Ôâþð‡?À­[·ºœºTW gàŋȂGxx˜LÂ$;ÚÅÅÅÄa%tN7 œ1RKD§§§áÈ‘#ÐßßÏéxÈéf@ ùÆÆÆB?#¤dÇ̲²28|ø°`¤UÏammq¿äFIMMM”ù·ç?ríÉÃÃÃ’l >‡|ë@9½{œDLæ28½ÛÏUn¤4s\èD`oTWWÃ[o½Å `HA~~>ÔÔÔ8Õ¼*Q^‡ú=j„Û¥¢µµŽ?†©V¢çªxíµ×¯Õ××Coo¯b„@r·½Í›7Ī¥¥%Î žËÈ-//ƒÙl¦ˆ 5E¢;€044Ïž=ÝHªWqq1§3j6›eu¶{ššš‚Û·o믾*ùssrrX5ÛÃÃÉïêê*§ƒÇ÷›è¢4ñññ¢æpzz*++áÁƒ››k—gåÞ½{Íè´§ŠAOOOW¬©Zap:ÚÚÚˆ:wgÀèè(ÄÆÆÂÎ;‘Å!ȵúd(ET>>¢÷®{àsîq#’’BÉ%÷÷÷S¢š/^¼€¯~õ«„3AŽ °í3t j1sˆzØÂ˜±±1Šì+¸ÓÄ…›7o¹sçˆñ–mÐu:;D%11QVÝ'}a«‰M›6Áøø8Òµccc)@¶’±@íú¶¶¶Æ±W*E*{œ-4ÅÖW ¾¾¾’ú#¼ì{ †L²«B(åe2™ˆjšååe†ØÔÌÌ Å ¢FöÈe ’‘NÇë$ =ÓôÏ“]«¨¨€ýû÷SC.p庅KþþþÃI–ÀæêŽ7€!¿ÄÄDÎ=j6==ÍPå´Z­‚MT, %E@ÇÔÔà HHHP}»»»9yt-¾9LMMå<`Òŋ臧f¹766BNN¯G+×ÀX,0 ª‡f8ååå’Þ›‘‘!›d(ÇðOJtÕ£;,jÀ^%ÑÑÑÈŽ½‰ÅÞ½{¡ªªJ³äˆ ëÙOOOSz.ŒAcc#&Æk±ÉáÖµµ5Ç„.ÞÁ†ƒJ>AÍÏÏÃ'Ÿ|"Ø¿O³Ù F£NŸ>M´Ôd{~¸°cÇ^þ —ã@‰f×*סitt”÷tÉö Z­VJ4„ì€X­Vèéé!Ò$xÓ2¿©±±BCC!66–uëêêX«øˆ±Bsh³Ùà7¿ùàâ‘\†OI’ï³"##9;®(ŽKôBFO-TUUÁÞ½{æ7“<9ì§vë?{ ÷êêjؽ{·ÓývG§3\o¼ññÿ!!!ÄsQQQ/kŒçææ```€pøÙˆ¢o¼ñxxxÈ~öy#_===ðùçŸ÷Ç…‹/FÐÃü¼¼8I“äÏ"¯ñÒÒR8vì`Æ©¶ÈÆ¿—TUÒ©f;(á߇;ø¡Ìd2ASSLLL@QQ<þ"##)'yò _ dU<©¼>»ºº ¿øÅ/ç¿<ò¡ÓéàéÓ§¬×rîž={{ö쀗Â%|wD`` ¯$Eff&#re³ÙÃ0¨¨¨ ¶ÏÑétcÀµùâHKKƒÎÎNÊæ;66&ÈÔFÑûg›c”÷‘Ÿ#òZ2>lß’÷&“á^6m¢‹Š E­È¿õĉŒ½ Ã0xüø1Ò%ñìÙ3Që Ÿs¡ñÂçÂÓÓ“3*,uéëwHš››)©ÖÕÕUÁjY½«« ®\¹W®\!ˆ8D5‘ ²RXp…g\¼L)e=1\90 ’ËJp=e{¸QƵ©© ©M(l®Œ‡BQQ¯¯/cì’’’$óbð2«¦¦&X\\}R‹ŽŽ& þY/YßxˆŸÌíÀ7kz :ù½IIIðÞ{ïÙm|ù ÊbèÓ×;ÛïÞ½[´a¥Ý‹/ ³³SpéϹ§§'¼ûëÂÃÃ)s‡ ‰á¾ƒƒƒàååEü6òzyyÁ?ÿó?PD„”ªÿ‹¿ø ÉŸ!Ë §¦¦Â… àÂ… A“¸¸8U¶àÈÏÏ'ú‹Eoo/¥Îq££¸¸Ξ=Ë{M^^ž]TçįÐÁלÂQàRÆSZñÐÙqèÐ!(,,$´Ü  ¿¿Ÿ²¦::: ==]ð³bccáØªª*gãP„•Bž“¬¬,øÉO~º¤¤¤0ÒGMMMD'°ÐÐPFälzzšað0«\à÷A(â¡Ã0âwKIE‰~Oll,Á(**›Ííí혘ÈPpc½{hh(# ðR&õW¿úñ™8ù·¾¾vìØQQQvþúú:|üñÇ„“@W³Z­Œ’2Ô1ãê§[ä¤ådtÐét Óé7¤H÷µ`6›y™’Ž‚=÷Bs*ž“S’ØÙÙÉ蜧¤AgkÉê à"# g}}½S•Þ©???Ö¦ÍÍͼÝ  ¸¸˜Ûôðð`=Dèt:bŒñõíááÁºN¸Ö?›Ó…§ëèÎ#†aŒü7ùß N n0„dGqôôôPj·ÙîÅ0˜L&Vˆz………ÄÿKIÀ£G %%…0hd†½Ð>%fÙ€tÙäett4åÔ¾¸¸È¢å›Cüµ‘‘ÈÊÊ“ÉD4qÁÇP Ç^µº9D¾V rµ…ÕÂÔÔ«È”/j@~÷l*NôôéSÅN;J‚K i÷îݼ¹[{iÞ;‘‘‘‚M<¸àïï!!!€a˜ 0 ÀË4~!¯ü”øÖ[o±®oº£€ŸÙÙYF*ÅÃÃîÞ½KI9Ò÷B®Ó,Ù°ÔÔÔp>käê:#%Õ°iÓ&HNNædªã¨¨¨™\zþüyIІ/^¼€œœÀ0 """K9ÓÓÓ‰1g;ã s:èòpÍÑÑQÆoLHH€êêjbÞòòòàúõë¢çpbbz{{‰û$sˆtñ®]»(Q*©'u§%Å544ÀöíÛ¯“RJ…â:ÈŒ^.OÛÞï¤@Máü³íÍ$ŒŒ”\O#™â.Ø·ogÞ¥Emdd$455Áòò²äòSütI¯ó%;ŠdÔÔÔ@~~>ô÷÷3´²³³áÈ‘#‚$»ÁÁAˆŠŠ¢„nÉã066ƺ·ét:ðôôäŒD å`u:øùù±Ö:ã=Ýqgç£>B¿;w—¾ô%N'$sLvÆÔ*!¦ÏÇ;wàÔ©SPWWLj‚íÝ»~úÓŸRŒ6ÛZƒÁuuuDÚ™<þ‹…UCÏ×sñž8ÀëÈët:VF¿Ót‹ÅF£Qð:)b'CCCÈ!%gADDoNɵÝJ ¹¹Y9 W¯^… .Øý7‰mê¡éÔÐ7*€—ìeTrm[[,,,À¥K—xû\‹©®`c(‹‘Wæ3è“““ððáCÈÊÊbô$:À\¸p¼¼¼ //ò{P_eF`` ÅÐŽŽBFF!EÍõQQQ¬åûö탘˜Î2:6|÷»ßåý»˜9œœœõlÒ$™Ü·}ûvŠ2©Õj…k×®A`` ôõõ‰’ëþÁ~°{÷n #lêo{õÕWáÖ­[pîÜ9e…e¡¨¨ˆU3ÙÃÃC!¥¡d;F1àBT‚ ¾¾¾Šö*fƒ³5[ïlÚíØk¹³q$RSS¡ººBBBxEK¸pæÌ^•A!l§JÔ2×ÜÜ\ÖˆYdd$ ÀÐРr#¾¹'&&rFÈ¿‡6fR¡¿Æ•驪ŸCBBˆúgÔð;^u#e…æH̶µµ‰RÙÄS)x´‚“‘””£££(èŒ%%% îKIIIDĘ<¾[·neDQvîÜIq(és({÷óóóƒÂÂBV"½nÓàÈþØyyy¼ºÀJtKツ¬ÚQìçûøø —ˆp ˆhp>àZî\'œØ,Øc¥CbBB‚¤Z~²ÐŠ——„†† 5u:¼òÊ+pñâEÖijj*ÔÔÔ õŽÀÜyyyÄsCïóɳE뢣£)ãEé‘ü¦¤Gc+!¿À‰;‡bš|yyyÁîÝ»)5îd‡¢¥¥…—°‰£  ž?999DåWpp0áìñ­ß°°0FÉjDD$&&¹}úºÅqfÏž=‚ù*ååå¼RŽŽ^B¡”jêåå%‰'62²uëVäpä7àܹsN;¯8[:bccY YwœM»œiÚ¾};o˜Ã0ðññaœ>cbbˆÓþ… À`0>?’ ~8†††`mmè&Fù÷Ò;ʾ&FëŽM›6Q”Êp¢§i“í;…ÊšÉ i^Ö‘£ô§Á¦M›ˆ(Ÿ˜t~­Ôñ2›Í099IùN£Ñ‹bcc!&&FFFsœ™™Iq\Øæ4''šššØJg|Å–‰ièH¥ fggyó0iii¬Â¨¹J5W9yò$”””ˆ~ßôô´¨<“˜¦4ŽTTŠD Í+׺Ø}ÐÙ6,¼3ßÉ…/Ã&‘ɵ™{{{Ãââ"deeaÏÚÚZÈË˃ŒŒ HOONGÍS’òüjàÔ©S”“™¡Æµ pxðàAÐëõÄûØ"c¯¼ò ëg±­7üÚÔÔTJ=??Ÿ1Þ_þò—y£qÛ¶mã4J/Ó2t6‡¡‹ŠŠ"Œ~[[dffBjj*=öóóc=ˆp…9r„RÇ8̰ñ1‚‚‚À`0sxòäIN²3Û}«jн¼¼$Õ, ÕŸ²-B”6”lÝ}ìmÐå 00µ¶µ¦…mŠ )5“ÃÃê-$Ã5/8„$Œ¹Ö¹ ˜»‚-ýÅVN.ªŠCŒ¨ÊíÛ·á‡?ü!ñï™™ŠN0‰]’;99I)Gå#×eeeQB©B)BJTT¼þúëÄûÆÆÆ§h®Ï$ÍÉÉIˆˆˆ`-£%FXX#ÝuêÔ)äµË5Wbæ°¹¹Ξ=K8eóóóŒõòóŸÿœUC]L –ìdð)R&&&Â_ÿõ_ÿöóóC"yÓç0$$„Ó©'ß7ÞVÕÝ"33ÚÚÚ$…+ØÄ¸€ê1³•'¸”УÓÇÏÏOu‚žØ“¿#5!1£<=b¼ÎVµQ/ªÔ”n„p"“ ÅDŠè­|…z/¨ÈÈHÈÈÈPeO{_(¯IJ¢ª¦¤¤°öG'ƒl?ÚÛÛE§R`stêêê”1è|,wgƒ#"{@ ñT’‡3‚­C+«$±¥¥Å¡ªjåζÜ4ÞNÕÇLJr"¤÷¥ÎÉÉåÙl60‚ª†\ý¯é†‘,eKØ2N1dQºƒ"vÿËÊÊR”DÌ7‡:ŽÉ¢Sxx8g$Î`0p~'—Ä•âÊÉÉa¨¿qÝ»Ô9ìïï‡äädÉ<$|¿à꺦*Ë] Ôê’E£¹"ÄôÞ r¹†` ¡®/¡:R®6ö„\IÜ!–;Ø¢08Ù°  €ø¼-[¶È&!Ò×+Wú…ÄzèÐ!J¸ßãdÉýèGHc†‹š¼ú꫌^é\¼ÅbAŽL„‡‡CHHåµ€€E›áQƒÁ@g|®Âˆ±;‡¯½öÒu¾¾¾‚)2¡{'Ï!¾NPæà%ÑÒÏÏ5z­×ëYy@ƒÁ7àú½ªï‚!!!ðâÅ äëUqv‚ÑÊÊŠàý)ÅRgJ¯]2ÄvÅjmm…ÌÌLÑ÷ÀûðUTT048(ŠfÔNˆkÌ=*xê’ø†}öìYxíµ×DE ·oß_þò—E4“É~ø!¥ÜËË‹ØkBCC GióæÍŒ0÷‘#GTs€é΃œ9TÚð ŸC±¥Æ~ø!o$-'ïçço½õ£¦Ÿ¼_ã‘$Õ ºXúòò²(ÃBö˜øú}㵀Π©¿[,‚ƒƒE9X\ÈÈÈ`ô¢æÃÈȈ¤|dnn.¯ò×ÄÄ„Ûh“‰†©›D MâRÑ(ÍÈCÔLJJ’|àØ±c±)“ S¨à‹hpq4–——áÇ?þ1%Ý@DT###‰Ò@¼Ó">~iiiŠD5ÅDþ¤Î¡^¯gV£ÑȪ2èëë Ç—ý»ì5‡ßüæ7rgLܶ©nÐSSSíÒTD( –h§> eeeŒ×Q PQQQ²ÂîÞÞÞŠ”®‰Ñ!éOgQ‡Ûºu+´´´0^—šB²Z­nÕ]*ÒÓÓE9ŽäÍ gΜA¾öÂ… `4!==ŒF#rÇFœ<…ÒÇŽCú 555pòäIIã÷Ö[o)"'-E1Tìfee1öO®ŽŸ€¤¤$HIIàà`ð÷÷åt(5‡bÖáÛo¿ôªï„bÑxÓy)à“F™™‘ÍWò„ÌV[ÝÕÕ…$œ@í:Š æ!rÊ–¦J‚^:„£§§™e«øi*33bccaëÖ­ÈQ2 YLÙÁ`àu°srràÕW_EêØh0ˆ\»˜Óý¡C‡àáÇœ) B6Òþþþ¼N%Ý©@™C½^/ºî[êÒßËf˜O:gÏžtž=<<çMÌò¥âä0ä¹ÞëT,÷ŠŠ V b¹xöì™Ó´Ôôôô”uBŽ‹‹£,z}«= jÓƒååe^ªT”——³J3:PÔãÇý{÷6„ËrÇ—ŸŸøøø€¿¿?2†¼ùž>}ZÔ…Á.tß³³³-I!((HPï]Ê=‘ó´¸aÐëõ¢9Fbœ üZÑäX©s²ÉÚ¸˜—$>ïIWŒü»pñ#E º’,w©Lh›7o†žžÆë‹94f“­ÐEtØ•„æËÞÁä–_ùùù±ž~'''¦ËŠ¥¥%¤î\ÁÁÁ”Í»¬¬L”°†+A,ËL)…`©$PÒwaaa¢KóP(D>$ÝáÏå–-[÷‘þþ~Ñõé™™™D{QWšC©Z*(8qâ„"Ÿ“••¥œA—b„Ô–-[ùúµµ5‡I‚¢BŽÃ±²²"êô»k×.¨®®¦¼Æ×åF£‘ÐÔæ®÷,\ýÆÝ¹»Ú‚[j&H›>ùµüü|EÓN'OžûS§N9ôP€º6Ô¸O)‚G[·neÌ#ùßAAAÈÜPçÐ××—wïqäâ¿YiØe7LHH€ÁÁAÞkúúú:'‰…3ö>§×A:Ú0=~üXRªC¨² ººZT»C6äçç3ºÔ-,,HrBÔ„··7…‘-ÕQS[ÀÝàçç§h§½   ‘LîæËè°¶k×.Õù/j 5àéé©è󹹹Ц#½½½ìûàà`ÕÓ¹F£y}ÛÅŠ „-dײ…fkkkeuR‡†H~nn.444j„£BªCrB•ÔÅ Q£©‚DEEÁÄÄñïššQkïäÉ“p÷î]·Are°A¹áј˜ÆçîÚµKõè¡Ra]Wƒž…ƒNçUuòS»wïFvÌìbÐ…QÌf3øúúÊ^Ü:ŒF£$ G¢³³‰áŽ#55º»»¡ªª öîÝ+É&óPó¼lãÍÇtWR’•^–(¤îÄÇÇS"QbO踈NYY™ìœî!Jq¥ X‚ÛAG(,zWN§cäÑÕšÃmÛ¶!ñkÜmíÆr ålyøôéSÅÂä:oµddåowˆ£¯¯OTŸp€äädHMM•¤^E'`©%Âí8¶lÙB´(•š"P±±±™M±N‡‡‡dgg;µ’¢å.T⣄PˆXCÄééé”è ÙUê;œßøÆ7$•{zzò\=‡¸rå9´˯·õ‹/dIu[uIDAT9`µZarrjkk%Z(º‘+î’——ÇÙºORµŒ¹ -—pÐØØ˜báö„„ƒÙÙY˜žžVl½8222D«d¹¤j¹;¼rÿqòÞHVóräææ:=ј BÎ2½¶ÞÃà ]' b¯/ÊÎÎfmhÿþ}Q(8qâÜ»wÏ%ÂUŽçåå$³‡ÊÊEoÛ¶µCQUU•âd‘Ó§OCCCœ8qÂiUÔèyt îÑâHiii² ¹î­±7Ä:Ë^^^²ËGí9‡^öú"½^0;;K„5L&¬­­)~Ú ‚/}éKN½°pÔÊÊŠC‰+rE_t:CwÜd2Éd’”ßçƒÁ`@®¿uð\¿ÓˆiØ8HÃÆžC»ÖJŸW< £A=ÄÆÆªÖõ < à ;;‚‚‚M(,  ؽ{7ÔÕÕÁ±cÇàáÇD;åîînø›¿ù·˜¹¹9X__×ô\===Ší‡öÄ;ï¼ùùù6èOž<ÑÑQHLL„‚‚Î1äÚãÈÈH‚’ßÚÚJ<¤(¨­­…¼¼<äs½šŸ­öõf³†‡‡‘;ñŒ†aÈlrò½à• |s¦æoN‡Üý©½½âãã‘k»]yA¯×;ܠ㽫F#„††{Àúú:´··Crr2¬¯¯Sx3d‚Ñòò2rëÒk×®Áùóç‘®-++ƒ;w"É£®®®BII‰*÷ÑÔÔþþþÈ%©b>[­k›››Á××Y×]­û‡dŠZ÷±¶¶wïÞUe}ˆ¹VDiÜÊŠ££¼¼ûÙÏ~†ÕÔÔ`†a}ô†aÖÚÚŠ]¾|e¼çòå˘¦§§±ùùyU>[­kgff°¹¹9Uö1÷a±X°ññq‡‡šëC̵¨ðXY±`z½ü²©¢¢"—ª×ӠͫǢ¼¼Ü)‚4hsèªeПD~¾ IDATxÚìw\S×ûÇ™F {#(‚ \8©wÕbµjÝV‰R·U«þm­ZgÁ{µâBEˆeÉÞ!!!;ùýq¿MÓáÙ<ï/^7'Ï=÷ÞsÏýäœsÏy·Â·Ù¹Ùv6v::: ­“•“åhçˆÓ’„J% ͦI’üÌýrä9P¾´yG[Ζfk6Tž^}JB ¾œ¯ÙZ¢HÒ:ÍÚR$• IŠÇ—òBIù¹"¿¢"·¢6kn!·²¤2+- Ê€6OeI%§£AñŒm­±íe”ËÚy¨LWVã><{ž Óf°Ñ`(_Úü2¾¹™9ÕÜÞäÛóíÌíhF´¿­*©"[’óQ¾ºŒ"„dº²Ï¤Ï5îöéÓ'“Ú¾h]¤¥¥´ùY^‹â¥~2¶7®Mñ2?f~eÿ’üï#JhÞ^ÛÆ´¬HV(”L"³ºM 2J'ЭHVÊ?S¢)%Ð?þOÒB%%•%•j_]Y{EÃŽOO>-L-Ôö@€‚ÉÊœd^ý+C‚aº8ûK¥Å>Œ­nCªždN2/”*û˜þ2ÝÂË ¨¹Lþüüó¼÷yîÃÜKÒKôŒôʲËÌðáî‡Üw¹ B×Ö_c:3'þ:Q¹WâÄ´'iQ{¢†/þüÂóœ·9®ƒ\í½ìc‚cHº¤A ½¾ò:ýiú¥Cl»Ù*÷zñ÷‹Ï¯>»ôsñDr¹¼,«lЃ>=ú”õ"ëó+z´Ã„hR%¯Jy‘ÂôRol*B)† ¤+ä¸dT¦½~ðZi­),È(P7 …¢ª¢ÊÜÕ\ßD?­0Ͷ›­•‡Õ»ðweŸË¾ÙõÍåÕ—B“Ÿ¬k «º—§ŸgJtÊðÃå2yÌ¡gç'ÇŸLtž(—Ë;ë,â‰zLìÑ¡ËN–ª{ñËù¦v¦Æ6ÆiOÒ,;Yºt}síMiF©ò@ E @!û¾¸ ¸ºŒâ¡Íd¸v…’´–Q¹ÂÁËÁÐÂ0õA*BÈÞ˾0E½3.®“(5Ô:^)Ëî0 Ã¤“R‚q›Æ½ºòŠB£`)÷S: éTü©˜¤K2µ3µìdiîjþöÚ[„}{±@ åÔ›>*M\³âeÆd~5ì«,I¿œÿüüsRv^ö‡$ §Ã·ç§¥Õ¼[E~·ˆ›–2 @[ "¯‚[ÄMK­YÓ¸…ÜŠ¼ŠÚ¾” ʲËÒÒÓ°®Îëª×E’"©BÊ+å¹VÙÐõ jí²ˆ2¹ J€¶fMÓðmai‰ÜC—+åJEÒ·B®"—/çg¦ev¶ŸÒÁÙ @¹ù;KžÅ¯ägådÁ+&€/dd %ËèâÅ+X¬UØ_NNBèîÝû‡PìܹÖ¬ÅÚxçÎýÊl=z¦ú•2ó¥KWçåå+ÓÙìŠ:³½vífQQ±j>R©”ÅZURRú%Å$‰‚‚B°³}öìy6…B¡ü˜””òóÏÛ¡†@K@©*—/_¯Q 6mú•ÅZU¿ÌIu -´[5eĈ!ª׬ù±‡ÿü9G-[%‰‰°ƒw©¦ÿüóöÚvQ’žžÕ½{WÕ|H$R{ÕÉ‹oLMM°|X¬Uýúõ©nóË/»·lYO£ýoF¤‡G§íÛ†ê -¥ª¤§göîí]Ý`ëÖõ(£99yçÎ]D}÷?@ E+Wn¨ªœ<TݘϯڷïP~~BÈÕÕyÙ²€Ú² …X¶Ã‡±°`~ü˜vôèi@`kk- B—.……„œÞ³çWOOw„Ðúõ[=zÊb­êׯ÷ôéSjË60ð‡µk7ïÝûÛæÍ¿mÙ²!tþ|èñãgCBº¸8"„‚ƒ%%¥ „,--~üñ‡-[~ÿã_BÉÉŸ>›?ÿ{œ7a´Ž]ùü*kk«eËŸ:uáÞ½‡\n¥‹‹Óš5?b?nqq/îÞ½†*/gÍÅÅ!„…ÕÕ¥í®M¶ËÊÊ‹‹‹11úý÷}²%‰X¶zzº¡{÷Ιó‡‡{nnþÖ­¿#„üý¿./gËÿ™·õ믛8níJ …¢§§WZZ&•JõôôBÓ§O)..UüãiåÉ“ØÕ«Dýý÷•üü"¡P„Ú½ûà¨QÃÄb-ÖeS(”Í›Ò×§ýþû¾²²rk~VÖgÕÖ¨ê[VV¶­­õæÍ?aY„™LÚ°a•¡¡ÁÁƒGòó‹bc_`…¦PÈŒŒ Ò@Ãbddˆ Ž™™)BèêÕ›óBIIÉǪɨL&c0L·oߨ|`¿TFMMM||zá?ݼ¼‚W¯Þ"„FŽ¢ÁŒL&ט­••‰¤é¬är¹ŽŽŽ†PÏú„†^322ÔׯaÉ`yyvz®®.––æX‘eeeËå ­î ƒa¦TLU …B¡ uînhøïJ‡eË_¼x!$ºtéŒ …¹9œGž"„D"1¦¡AƒúW··³³mÈN½b±$8øXBBâÉ“çæÌ™úë¯+ ‰ûöš3gº¡¡A×®<!4l˜¯†|ªªªöí;„m2°[7ÏÛ·£¢¢r8‡zøðÉýû1éé™óæQ;vtEõèÑuß¾C<oöìé¶¶µúbqttxùòrøòÞ½‡=-++›3g†‹‹ÓÀ>ØéuïÞÅØ˜Þ§OÏmÛvM›69,,|ÈAµåiccó;aì‡+>þÕ®](ŠH$ÂqàÀ~GŽœ”H$¾¾z÷ö>yòV,óÍÍ™EØîöö5Üžk×±³’H$d2*=4*¾¾¸ÜJ„……¹›› BHõE]¹rC ÖöÀªñ×$sí§tu÷P³(..17gª6ÓÓ3±n©££B(;;W$!„íÉdriiöJÝÜœI§×Ú?-((Ä„!dnΠÓéŸ?çˆÅbSS™LfnÎ,))­¨à „,--0’H$YYÙFFFuøT=碢.—‹²²²40Я¬ä!„ŒéL&C&“q8\SSµË¬NaaQe%“TÆb­Z»v™H$211f0Ì”ã/ +÷¬¬Ï‰“] vÊÃUTph4‘HÈÈÈÂÆ ì –@â|âØì CC…B‘••¢R©ÕØ·oß¿~0xpå«–ÛÃ'O9Ý%ÿº&Ñ|l/“É þõilLwuuQµQSkÃL)+µ!‰BÊ“«ª ¤£&L&ƒÉd¨¨ºz‡“HL¦±],,˜ª²khh Ú›&‰¦¦&˜èkȹ¤¤T¡P`'Ìáp9®‘‘aõŸ©œUŪ_©†òpÆÆtlCó¥Po¸ÜJU …¦¦&jOœêK&“õõiøÉ:d4!áýƒOTS&LÝ¥Kç/¼ª‚‚ÂsçBUSzöìîç7ì ³•J¥ÇŸSM±´4Çÿò]aa·ŠŠJTS`2´ž?ùüù+Õ”iÓ&«½VR¥K—ÎZ©\Ýz@C§ƒ|ÿéÔ—•–?y… ²²r2¬YFœé4C(# tÒéø%(?B§à‹ø"jžðD$R ™D".-e[Z2Uý¿á•g‘B1€ò Í ‘d21^•‘@!ËÄežÑX¡PPäD’B‹¦«ŽQOÏÊ€6ƒB!ÓBF+å¼XôF@ ”¦ÈñDvùL*—t÷îýü<ébîìÈd2ƒaJ£ÑH$‘H‰Dd2yôèáD" €öÛ©GUÊ+yr¶- Œ*©d6ϯ¢Ñô,,,‰DbFFº®®®••µX,233e0úúŸ?g9:ºhvÑÐ.d´6™L‰Q5‘Á`æc>J ¹(**âr¹®®®5~›““sûöm„ÐܹsÁ“ÐPhý¦^_ßsL§I$,ÑÒÒJ àÓét(P y5ô矎‹«u Ipp°Ïï¿ÿÅ4zkT*–JeRåö?­N:. Bzzº˜cP]]=‰(‹BVVee厎V u~ééé{öìAI$lj„ÇãMœ8±¬¬¬6.—ÛµkW„Б#G”‰ÉÉÉþù§ª›ÍÞ½{·µµµ†c§<—FÓ'“IXÇH$’H$…)òÓ ÿ焪G¯©Z2&ººGG{,ºö´+´ÍÈHçñ*UÿLMar(ÐRàr¹¹¹¹EEEª ÒñãÇüøÛÖ××OKKKKK333ƒâjuDEEÍš5kÚ´iéééõ΄ÍfÏ›7oáÂ…‡Æåææ~ûí·sæÌ /++›1cÆüùóÏž=‹Ù§¤¤|÷ÝwUUUZ·FkƒÏçþÇw‰®®.6* ÍNvvvNN‘HLNN0`–8|øpe°Õ€€€k×®!„~þ¼n·><øÇ”––þòË/'Nœ¨_&G8pàĉ¿þúëï¿ÿžF£mÛ¶ÅbÙÛÛ/^¼øÉ“'þþþ>>>þþþ3gÎLMM½zõê²eËh4ZƒÉ(´d<=====Õ—.]ªÜvtt\¾|9T+ÅÎÎÎÕÕÕÕÕõܹs_’Ï!CètzÏž=U›ƒ$‰L&oß¾=+++44tÛ¶m¡uëÖ5ŠJ¥jÎd€vͪU«V­Z%—ËGE"‘LMMÝÜÜrss/\¸`ddäââ²`Á‚èèhµŽ¸*àá €ÖL&“J¥b±¸Î’T‰Dr¹\,cÛ®®®çÏŸ}fΜéëëûîÝ;2™¼lÙ²#Füú믦¦¦[·níÝ»w~~þÌ™3çÎ;|øð¸¸8]]Ýf–Q¡PêׯŸ‰‰I6‰‰‰ÕGµ Å’žž~êÔ©Ù³gCQ4;wî,**BÙÙÙÕ;__ßË—/Ëd²õëדÉämÛ¶Éåò;wî`Ò4jÔ(…Bafff``põêU©Tºzõj=== y6E§þСCØFpppõo%ɱcÇ”6Ð*H$•••PM‰®®®ƒƒƒƒƒðEÂekkëàà€Íß055e0ªÍ;{{{„ƒƒCsᛢ5š––†½żB¨Ááp¼½½ß¼y£–~ãÆ§OŸ*?~úô ª-æe0 £zúÈ‘#‡ ¢üþþý{¸aО³gÏÆPÌŸ?åÊ•îîî¡õë×9rðàÁufråÊ•ÐÐЋ/b>|øÓO?YZZvïÞ}üøñ‹/vvv611Yºté‚ \]]E"Ñ©S§(Jsvêë•J5PAóØDã‘““Ó¯_¿¾}û;v *14/©©©?ÆÞÔgggGEEÉår„PAAADD„L&Ó‰³³³ªOä‹/†††ž:uêãÇ¡¡¡ÇŽ;vìXIIÉ;w6oÞ|äÈ*•Êçó›¹5J"‘0?¤Dâÿ\”&''‡„„`~F …X,–Édb±XƒÞ7 ………~~~>|@½yó†N§óÍ7˜ÿš˜äää%K–,X°!”ŸŸ?vìØµk×"„x<Þ×_½páBœùôèÑÃØøßUìÁÞÞ!„:::êëë›››#„œœœ(Šæ ›¢5ºuëÖuëÖ­[·N¹€„D")ç²­[·ŽF£…„„´´ÛvõêULCBb±xÊ”)_¸|€zóèÑ#åkê‡*ßK?xð`Ë–-˜ð5 MÑ¥Óéjî\]]·lÙ‚m[ZZ¶L÷wEEEÕ•ýðáãGÇm’Õ«WWUU}áÔn ñHLL|÷î]||¼¹¹y~~þÓ§O i4ZNNNFF†½½½ê œ-\™LöñãGSSÓ’’CCÃäääN:åååuèÐ!99ÙÎÎ.##£ùe´•rëÖ­·oߪ%>{öìþýûþþþP>m]»v!„d2L¿k™Ý·oߎ;"„nß¾ÓKçÏ?ÿüîÝ;‹µwïÞsçÎÍ™3gáÂ… £_¿~~~~666îîîãÇ £ÓéØü'Q­Y¿~½r{éÒ¥–––¡ßÿ}ýúõ £Ð\¬ZµJ¹=kÖ,åöèÑ£qæ°}ûvåö/¿ü‚ (ST·###[J§¾•v°ÒÞÞÞ˜wBìý˜““Ó¦M› |­ƒ«W¯r8{{û7n¨“1bÄáÇCCC§L™¥MŒT*-++³°°HOOÇ&!éëë“H$‡ƒ¢R©XŸÏçK$Õ×ñª$''K$+++&“‰’Ë剉‰!GGG###6›““£££Ó¥K„D"a³Ùšß_µtO …BöMvPwóæM„мyóÔò˜™™éêêæååA…€&&55uÁ‚X8ÂM›6ÅÆÆ>{ölÓ¦MÛ·oǶúé'ÌrÍš55f¹`Á‚ððð &`NžNž<¹fÍšcÇŽ „ÂÃý¼¼öîÝ‹Ù8p ÎID-½5š™™¹oß>„P/Ë¡PøòåK—©S§Bݪ“žžÞ¡C(‡&¦cÇŽ;vìÀdôüùó¡àààõë×{xx „®\¹‚¹èNLL¬¨¨¨-“·oß^¸pÁÞÞžÍfK¥R …bddtçÎÏŸ?cëšN:uîÜ9ìÙÏÎÎþüù³………æké­Qggç8p›sÛ4`¡{ºwïîææÖ‡{þüù“'Oà!iE¼}û¶[·nPÍNZZšò÷,..®oß¾¡¹sçŽ9&þþþ÷îÝ ÆFê|}}#""~ýõW„ÐÒ¥K•ÑhZqk´YØ¿?B¨Fg×"‘[‘Հ̞=›Íf+#T€‡cÇŽÍœ9‹ðqéÒ¥1cÆÐh´'NlÙ²E*•àÏjذažžž!!!7nܸqcEEÅwß}îïïß±cÇ·oß* ËÁû}­ìر£zâ;wbbb p y)..ÎËËëÑ£B¨ªª*)) ‹­dmmöøñãÚö½uë›Í~öì¶v÷îÝÊÊÊGa) _¿~ #==ýìÙ³ñññšOÐÕl /æææjn¤ Kjjê¾}û„BáñãÇGŒuáB2™¬sçÎØ y?????¿”””ÒÒÒ3YºtéO?ý´nݺ%K–èéé~ýõ×+V¬ P(X¼Øëׯ¿yófÕªUººº}ûö-//øðaó{¿o3œ;w.++ËÆÆ¦ß666/^¼ËåJ‡;@cÓ±cGÕfJø†††j;uêT[&4íÀÊóæÍC>}Z™rôèQU{SSÓI“&i>1èÔ㥪ª*((H$éééÙÚÚBÐ[£ñññ¯_¿®Ó,==û (e4..!Äår>Ü€gÅf³Ayz{{÷êÕ ª)€Œ¶ð¸ [´hѨQ£”)\.wÙ²eØö¶mÛ|||ð¬h4šT*íß¿õ¯šÑ÷ £5`aaQçLZ„NüøñŽ;0‡1"‘è‡~xùò%B¨gÏžãÇÇÜ”4T*•D"a+Ï€f„Ífc«æ (Ñ ))I(b2zêÔ)å´MÃj(Ðr …XP h;2šžžŽ9uÎÌÌl–x÷îݺuë°íŽ;*WÚm 6 „d2¶‚ÚˆŒº¸¸!„®_¿®êg°ixõêÕĉÙl6öñ›o¾qrr‚J€*0á©V&Nœ˜““ƒ}ÔÓÓÃïQ9sF©¡¡!C†ôë׊Ñ:àr¹eeeèO\Ý»w?{ö, £u­–Èb±°Ö £u°råJµ”îÝ»3JѺ9sæ æ³!4jÔ(l0ôîÝ»VVVP8ÔHûš~óæÍ;wîh0ˆ‰‰‘H$ØvjjªX,633Û¼ys£:C+**‰D,«úW£F;v,TSm)Œ7nܸqµ}{íÚµàà`åÇ=zÉäÕ«W{yy5êYÝ¿ŸÍfcÓcm`Š‹‹±x<3} ÉÉÉÕc&›šš6¶†2Ú¸èéé¹»»#„JJJï(ååå6lJ¥jéß~û-TZ·ŒöîÝ!¤U€*m‰ˆˆ¸víÚÊ…D"‰ýõ× Aƒ – xSBJ_¢JÖ¯_?eÊ”‡Báк[£MÀ¾}û”ÎG0ú÷ï¿lÙ²¤¤$ÿøñãØ¶ŽŽÎÒ¥K‹‹‹E"QuÏR!???Õ8Ï€ŒjMEE6:™ðå¹3sy'“É”ï‘BgÏž>|¸ªñãÇ?~œœœ\Ý/IJJŠ‹‹Ëþýû ñ=;;{úôéjëD"‘…BÙ¿?TGmxd2‡ÃAUUU5`¶\.·¸¸Xùqܸqª*—ËOŸ>½xñb‘HTãîÅÅÅ'Ožüüùó²eË4ø:Q"‘H8pæÌ™wïÞ©uç9‚é8ÔEh¥´ôq733³I“&Mš4ÉÇǧ³UÆLÆøí·ßT?ž9sfîܹJ ­ÍUÝýû÷ýýý£¢¢ê<ÜŽ;V­Z¥¦¡€Œ¶V***ÒÓÓ•×®]kjjªüxðàÁE‹©Ú5jäÈ‘S¦LéÒ¥‹ZV"‘h„ j³¦Ô ݺu+T5m;dggß»wÛ611Y¼x±òmxyyùD"“ÉôððpuuE¥§§_¹råâÅ‹ááá>?~¼jn`îܹϟ?¯íp¿ÿþ{oáUïú­‘ÀÀÀ@9í}2ÍÌ™3”ÿþûï´´4ƒðððÄÄÄçÏŸûúúòù|}}}„½½ýàÁƒÏœ9D"ý;¬\VVvèСó¿~ýzbb¢æsèØ±ã•+W .¶::tè––å´wUóƒ‡Eò8~ü8æÏÄĤzGžN§>|X5ñÑ£G5æ+‹5ŸÃ´iÓœ¡.Èhë£OŸ>ª/è·oߎêÙ³çÈ‘#ëÜwÒ¤Iª½{¡P˜››«fSPP œ"ZÓ§Oÿé§Ÿ "Èh«D__ßÈÈHUõBK—.¥ÓéÊÄ9sæˆÅâꃛ&&&'Nœ8p rß¿ÿþ»z»µÿþNÀÈÈhåÊ•T**bKãĉPÈh=ñööVýØ£G3gÎ|øð¡º¥™™™£££†¬h4Z§NjûÖÂÂ"::ºGPæ-„]»vmÛ¶ 딀K?ík1hRRRjjêçÏŸ±%%%W¯^U~›‘‘ºwïžê"Q„B¡ˆŽŽ®ñeBvv¶rûýû÷ª¹a¸»»Ïš5ëôéÓÕ÷={vvv¶jÕéÔ©SçΡš6 ³fÍ’Ëå2™ìÿþïÿ 4€¶#£ééé{öìÚ4¨9 IDATAeff~ynºººt:½k×®cÇŽ '‘Hªýw;;;„PUU•j"Öl400PKÄX¹reLLŒjæÕûõ3gΜ9sf½Oêh“annŽÀß(ÐödÔÅÅ à~ýúõU«V}yn...¡K—.!„LLL†ªüvèС!!!‘‘‘jkœ6oÞܧOŸ®]»Vϰ²²R¹íêꪚí„v:6ŠÍšÎÏÏWkäöïß¿  ëÝ«òäÉÍÖ¨³@›äÁƒ_}õ”Юe”H$:99¥¤¤¼~ýZ5=,,ÌÁÁ!44T5ÑÒÒòúõë5æ£\Œß»wï#F@}j'(Šê~¿Ñv'£k×®%§NRMg0ç΋‰‰ W&N˜0¡C‡Õ3‘ÉdÊvkÞBh´ßv?üðÇNœ8ñäÉÕ æææxrxñâÅÅ‹B:tÀ†\­úúÝ»{ËdR„T*S(ZÍÅïܹ3--m̘17nܵ–‹§R©k×®%‰S§NŒŒär¹µYúúú>|øP5eܸq/_¾$‹-Ú´iÔ$m§ 4(<<¼²²ÒÏÏoÒ¤IÕçÏcXYY)ƒ”––®Zµ*""‚ËåΜ9óСC0» Sß®éׯ_ddäüqíÚµ˜˜˜Î;/[¶L͆Á`(;ò{öì …nnn3fÌX¿~= €Œ¶h*++“““B:Vп//¯¤¤$‹ÅårçΫfààà@$÷ìٓЧOŸ½{÷2 Í êmLFsrr¾<·›7oÞ¹sGƒAÏž= «¯s/))‹Å999d2™Á`œ}ú¤ ^´=víÚ…’Édµ(€FìÔ—””fffeffåää¶Õ’‚Ü4¼ŒVUñ óy¼*¯J"‘ZX˜·É’ÂÞt4|§^&“‰D##Cì#…Biu¥ —ËwïÞMMuuu]¶lYk¼ Z«Œ¶X,–jÜù­[·FEEùøø@ÉÐúÖÎBBBTSø|~pp°X,†Â Õ˨X,.((((((//oŒü+**:T=ŠÙ¹sçØl¶jŠÿO@§¾åRTT„E'Æ–„68"‘(%%¥Zœ;€Ö!£vvv?ÿü3BèúõëñññpÀN} û!‘°èäj˜››“HÿþÆTUUq8&“©š2ŠÌÌÌ-Z¤–¨££³xñbÕEŸ¯_¿¾}ûöÂ… kÔ\@FÛ5½{÷Vu_ommýòåËÿû¿ÿS¦$%%M:•J¥öéÓŠ«‰‰‰BÚB§Š`̘1;vìøý÷ß±AXfkk‹*))IJJB͘1ƒÇã?~¼ÞNöÚ\.W XXXà´ÏÍÍ=}út=" ÈhKdÒ¤IÖÖÖ/^ŒŒŒäñx}ûöµ³³ËÍÍEéêꆄ„LŸ>½]•ÉñãÇçÍ›‡ß>>>¾  `æÌ™8í/]º”——×b/ŸJ¥ŠD"*• Oz\ØÙÙùûû_¾|ùþýû³fÍŠ‹‹»téRllì÷ß¿yóæÐÐÐ3f´ökÔÖéõëׯµ²_»vm[ªcÇŽ ‡G€Ö¨ÖôêÕëèÑ£;wîÄ>·ÌÅõùùùD"!tëÖ­Ñ£Gã4NMM=yòdPPP»ºûàom(JÓ¿Ž/,,´´´ÄoÿâÅ ==½#Fà´ ©ªªÂŸ¿T*w½ …B*•’ÉäuëÁß(Ð6;õjËÞÛÛ¶mkÔüÓÓÓ«/xmF°5¾øw¹té<®Èh}prrÚ»wïÞ½{«=n2’““ËÊÊðÛWUU5ö@á’%KZÔm:qâDcß ‡Âã €ŒÖâ?4`ÓL+ûGiûNY.—ã7Ž¿wïžVù›˜˜hë«ÅÐа²²§qAAÁ€ð”B¡022Ÿ?†™™™V¿O2Ú(”””ܺuK«]öìÙ£íQ´X¼páN/))ÁiÏãñ†zõêUü‡8pàãÇñkºŽŽŽ§§'6 ×®]{üø±Våáá?Œ..ÿ˜ZRRÒñãÇ…B!‰„«›òèÑ£'OžhUøGŽùóÏ?ñÛŸ9s†Á`´ä¨MÐ2ªP(D"‘H$ª­»$•JE"‘X,ÆŸ§D"©StT‘ËågΜÑê´W¬X¡•Ó“K—.8qÛ¶²²*((ÐlŸ’’âãヽ%333“ËåšÛ\2™lúôé—.]‰DL&søðáQQQìÅbqjjjppp~~¾µµ5‘H¬sÔ/888;;ÓÍfëééÕy¥ªðx¼ÒÒRxðQí [·nݺuëNž|hQN¶ ©e´Á …zzzD"1>>ÞËË Ï.|>ßÎÎnïÞ½³gÏÆy6›­UØ5,¸9~{&“©UWOOOÛHsúúúZ]‚©©©Î5BˆL&ëëëckÌq¶^ Æ¢E‹B^^^šÃ8K$ì䃂‚ +Ð2Ñn“P(LKËøïS×ln8 ”˜˜ˆ?Ȱ¡¡¡¶.òƯ•½———Vó~ttt~ùå&“‰—o¿ý–N§ã·wss»råŠVWqêÔ)­ì7oÞŒÓ222räÈ‘žžžžžžx앞U»ví Ï*V!oܸ¡mµZ–Œ&&¾70ÐWM±±±’J%Úµ¨¨èÙ³g'NÔ`séÒ%Õ(fÕçùøøtëÖ ÿA oß¾­««…ƒÔ%K–hõ"«k×®Z=ðaýúõZÝ„ ´²wqqÁS´ |ºÿþüßþÁƒ6l€§®ÞŒ9’ÅbŒ¶n•ÉdT*EMêÜkÞ¼y,KU>þ|ðàALFœœ¢¢¢X,–¹¹9f†áïï¯êœøúõë«V­RË™F£iuþÚ.yjØPzªTTTkÛÐê7 888 ¿=þ—cJ¤R)ΩQ2úExyy©`öîÝ[ùÞƒF£-[¶¬QO@¡Pèèè4ê!¢¢¢†Žß>""bÔ¨QZâãÇ?þø#~{pÙ×–xõê•··7”CˤU¾bJIIéÔ©“jŠ……EQQQm¡Ì÷íÛW£RçææÖC¸´´T&“ÕØÃ­í 5Ž0<{öL«ù°åååïß¿‡z ¨‘žžŽ|­›/^¨M*²··OLL ÃÂsÆ ¿üòË“'O°WÆubll\QQ‘••uûömüâ…BáíÛ·?|ø€ÿÒbbbðGNFåçç¯Y³¿½\.߸qãçÏŸñïòüùóƒâ·/--Õ¶{ñøñc‡O#2Ṳ́¦¦º¹¹ã1ÆZ¯?Æb›ë~þüyGGÇ—/_âÙÅÛÛ;""ÂÐÐ0$$½¾¾>ŸÏ¿zõ*Î…ªD"Q.—ß¾}ûÅ‹B¡g)I$’={öh¥Y{öìÑjVV\\Ü7´ºw&L€682ÚÌtïÞçÔ} 33³F]•ˆg=¨*kÖ¬Ù¹s§‘‘—ËÅcïää”——'‹ýýý/]º„glžæ?üáód´õòòš:u*ÞË&z÷î­Õ ¢õë× üki†«6†«&“©­w6›mbb‚Ó¸G§NÂ?KlΜ9 ,;v,‘HÄã–ÉÀÀ€N§Ÿ9s& 55Ï!ÜÝÝ¿ÿþûC‡ië,¦1¸~ýú¥K—._¾ÜªŸ…µkׂ®ŒÖ“E‹›˜˜àlŽ5ªcÇŽøó·°°˜7oþùO eÓ¦MZMóìÛ·¯VÎüd2þ×ñnnnD"qÖ¬Y8íõôôh4•JEáñ©££Ãd2¥RéäÉ“oÞ¼‰ç“&M:{öìˆ#ž} Ò2ÚtôêÕëÅ‹øí³²²ÚOùX[[ãtæ¢dðàÁøõõõY,Öà­N=VȨ:ééé,‹Åbµ·"õpÚÖµk×wïÞiÕÆLKKkúK+--Åú³8Ñ6ZgAA‘‘‘¾¾>þ]bbb´åöF«ªªÒ`À`0Z‚{CÑ„‹‹KPPPPPæC!ôàÁƒ¯¾úª6û±cdž‡‡«%Êår<‹V•h)O鈽װËòåË÷îÝ«–xúôéÚÆ4I$Rõ…ÿõ˜­­­f9sæûï¿×ª”ˆD¢V7¨Žæx6aaa»wïn Í £-ͱv;uê”’’¢š"‰òòòjÛE___¡P¨ÉÜŽ;~úé'ü§„9.Òê*ž?Þ§OüöÖöìÙ³úTÖòòrSSS¨ßí m är¹æ^R ét7 ~~~wîÜÚ £µ"•Jµý‰ŸqãÆáœÍƒ1lذ{÷òÑÖ½ôŒ3Î;O‹¶°Ùì«W¯jõ³6Þ½{NWAF›”³gÏîÛ·O+¥h¼I×Ú.gBø¢w4%ÎÎÎøíMMM+++µòÉÒ&9zôè_ýÕ ‹å´Zg€Œ6/_¾Ü´iþ€ã—/_.**Òj2ÀÉ“'ß¼yÓHç¯m,9m§m56t:½ªªJ+×Õµ[&eee2™ÌÜÜû¸`ÁÍ>4¼@F›’’‹•˜˜¨y…¥‰‰ ›ÍÆâ gff~þüÙÁÁAsÎr¹¼C‡øã’"„>|øpíÚ5üö?~ÔÊQ<ªÉámLž>^«ÂÇæ¨N=´ršÓ ˜››ãtu´ÓN}ïÞ½5 >["¹dÉ’/^ÄÆÆj¶ïÖ­ÛâÅ‹ 0bĈ;v,Z´hÀ€š[»\.wèСÊCÍs°”Í–Áƒãu\TT4}úô_ýɬX±"**J«Â¼{÷nk-¶Äb±P(twwÏÍÍ…ÒhÛ´ô@:åååÏž=C5êØæ@d„ ƒ ¢Ñhš›]fff666ãÆKOOß¿\\›Í Ô°‹½½=‡Ã0`‹ÅêÒ¥KDDžq[ …¢££#‰$‰¾¾~qPx<^tt4þØ$»víJHH1bN{>fÌ<Y0ÇØ¿üòK»}´D"‘@ Ð6âÖ— ‘Här9•JÕjÐö[£:::X\¹¦YýbbbB¥Rëô”1þ|2™Ü©S§Ó§OÕírìØ±˜{ºâââ%K–ܽ{WóÜx##£¸¸¸1cÆ„¼¼¼´´4kkkÍ%Àáp,--G ’FEE 6LóYq8ww÷¤¤$„—Ë522ÒlŸ››;nÜ8l(P.—+ £Øðk~~>ÇSNChh …oö¿'‰ÌÌÌ ( 5ª®kXóJ,ÿõ×_-íô°#u®ñððÀlpúWž1cFll¬••ÕðáÃOŸ>]\\ܹsg öT*5;;{ݺu2™ìõëס¼¼<[[[ »p¹\ssó1cÆ}š˜˜ˆ-ü­-¼Uã±iÓ&@€½D€¶#£ílY½···\.×ǘB¡èëëËåò .°Ùì:ç*zxxÈd²îÝ»‡„„ÄÅÅá9¥äää%K–<|øpÈ!8¯‚Á`h5kòõë×aaa˜Œ¦¦¦jåöËÁVK¥RmçT £@K„B¡¨mhf̘1ØÆõëשTjÎêçÍ›‡ùp!‰Û·o×ÕÕ7nœænÛ.==ýÎ;u¾èC…‡‡>|øíÛ·¹¹¹š›Æ …B(ZYY5×Tsl0&$ £íÌyr~xm0™Ì9sæ „8€'Û!C†ôë×!D"‘~ýõ×Ñ£G×é‹Ãá0ŒüqÆ ¿ÿþ{‡Ëå999óçÏ¿wïž¿¿?ÜÊÚnDTTøZ%ûöíÚ±óæÍÃceiiI&“ß¼y³bÅ œ±|}}Y,–@ h冹àêÙ³gƒä† "k¶166®¬¬”ÉdøcÞ £@KD%,,Œ@ hÞEmݺ›f`kkûçŸöêÕëÛo¿m½—ÿñãG,|·¯¯ï•+W¾DFÓÒÒ´ŠAÀ`0***¤R)È(È(ÐFÀ9wÒÜÜ|ñâÅ¡uëÖµ„Óž:uêßÿ?ܬ'NœÐ03A…BqöìÙáÇ[YYÕhpöìÙ¥K—Ö™žYk@c®È fÜÜÜ´r³PoÄbñ¬Y³¾<œçÎ;׬Y7dZ_åpýúõÚmmV­Z·¸ÕwêÓÓÓ÷ìÙƒ´qwM‰Oll¬££cm E*•ÖìãÇöööt:]+74MCZZš¥¥å¾}û–-[7º·F«‡´€fDÛðˆ!›²²2¡PXã·•••†††¡îÝ»7 /(œKæ4pçÎ???­vìXÀd25ûÉ-..nç: 2 ´¢££ß½{Çápj‹€Ìáp8ÎÑ£GëÌÍØØX.—«*Q½Ã3™Ì—ç åb0ooïW¯^U·©¨¨ ª3™jÔÇÄÄDOOOÕWW×OŸ>Õ»0•£ £G¾}û¶ËàààÓ§O·gï| £@Û!++ËËËkÒ¤I ¥Æ§º°°pÒ¤I“&MJLL¬37*•ªP(Tßü”––2Œ<áË—/óÍ7šm"##¿úê+œ®eô—ôôôÚÌ>|èáá1cÆŒ;w¶Àx*-QFû÷àãÓOõÏÜÜž^ ““ƒ¹,¨“ÐÐÐ)S¦¨¦ôèÑ£z IJ²2U÷ Ë—/Ç<{©ö—SRR ¤šØ¯_?Ì—¹*ÙÙÙöööª)"2ÅÇLJ††>zô¨¶óÿþ½±±±òbmmmkôá_^^þàÁƒÉ“'3ŒÕ«Wc.²jD*•††††††jŽ’Ëf³CCCñ¼j«±åÞ\h7á)55…N7Tü‹Å4š!‘H¤Ñô•6d2¹‘ÎU,c>†v‘HÔʰÞðx<Õw;ذiZZšL&+))™0a‚j• R«„!""B-¬¬T*UŸ-**š?>ÖMV²hÑ"ÕZ]\\|ðàÁëׯ«ÊÊœ9sªWûôôt___Õÿnݺ©Y>}úTÍ £wïÞŽŽŽïß¿ÇÂíT§K—.óçÏWæfaa1räH&“©fF¡P~üñÇäädì£\.¯ñp!‰4iÒ$ì§BCðpccã#F<{ö¬N%õòòZ¹reƒW† &Œ1ÂÉÉ©Nßíõ—QglLW¹ÇccS]]ÝŽÝÅb!¦tUUåQ";;[môh?0Œ:½ÿÕÈòåË—-[¦!:,›ÍV 3…õLksˆ¿ⱬ1¼•ÚéåË—ã9œV‘²ê4މ‰ùóÏ?ñd…?üWtt43Õ_‘†º^mK&66¶oß¾Õ© …$YÙ6äóù:::••Ü¢¢Ããq²²2ÈäF™Ò?aÂ…FøHHH8|ø0Nã¥K—J¥R<–«V­âóù8³Å¶—/_ŽŽŽÆcyóæÍÛ·o7ø ”””lÚ´ %—Ë]»v-Îl÷ìÙóéÓ'nðhè¼yóîÞ½Ëb±:uê¤ÖÃÅ`±X,KÕ1³]€ ‹/^ºtiƒãÉ“'ããã<[ü–»víÂi¼aÆòòòf<ÛÈÈȰ°°ÏgÕJCQ=V1åå庸t`³Ë ‹ ”C<öùùù@óQ}xNu´ÑÃç»hD•Éd|>Ç«" *£–¢òòм¼|==Ýæºl3ìííõõõqÏ™3§1¢éá?Û>}úà|Këåå…'f§¶'€==½ï¾û§ñ˜1cpNPoÉ4F16R¶æææš´¨³íÚµkcÌíÕªŠ6–Œ:;»˜šbш˜^cc“‚‚<[[„§gW„‘½Y*´··7NKcccüao{ôèѼg‹'ü†µµucœ€•‰DêÚµ+NcÌgk§1б‘²Õ××o¤ØVq¶ô«Um0 /B:ÕÁJ$]uu©Ð°ïÒ¥K›ô’K¥RÝÝÝÛÏ}ÔÑÑiŒˆ¤`ª{÷îQ;wnŒ™ªt¶”­uæ­ðí á ¾œŸŸ¹Ìs>fˆ¢R ¤R±@ÀKNÎèÞ½³B¡õ¬Z"‘bddÕöž1———‡5¦jìAþüY(šššb³CJJJÊË˱_W QÚ[™™™b±˜Á`Ôè¼²²2??_õÂËÊÊJKKmmmñ´@Ølvqq1‰Drqq©Ñ›ùdaa¿4R©›öO¥R±•µjU´¨¨¨¢¢‚F£aó[«WQÍÏf=¨ª*‰x!™Žâ))!K’Å/ç??ÿ¼ßkGPP¶zïíÛ·ÕC\ÄÇÇÇÄÄP©ÔŠŠ ‹efföǘššêêê:´%Ëè£Gâãã)JyyùêÕ««+cPP6“.!!aÊ”)ààÁƒ¦¦¦_ýuë•Q©Tºwï^ƒ!•J===GŒ¡f‘’’B$KKK·nÝ õ¿))..^¹råˆ# †£££Z­¬¬ ¡Óé`Ĉ=zôP«¢j¹ÅÅÅ=~ü{6—.]Ú°=X ªÙÙÙ5®ùðჯ¯o`` Fãr¹XââÅ‹[x(Ç„„„±cÇ*ŠÌ9WRNIDATcÉåää`ŽM¬[³fͦM›kœWÔZÉd</00pêÔ©/^¼¨n7sæÌÀÀ@œNC€†ÅÇÇ'00{)¤VE±`}ûöÅ\¨UQ5’’’†H¥R¿Äc Èh3ààà°zõê7jö‘ƒ‡åöQ,;vŒÅbݺu îrëjâ½{÷®Uœ*…Byóæ ‹ÅÂ?ÿ¹Ð®SÿêUB•P¬š" z÷ö60Ðÿgì@ •J•óI,FÛëׯÃÃÃqÆ%VãÅ‹4ÍÃÃ#88x÷îÝ-äºäryŸ>}.\Èb±ÆŒ7ºµðçŸæä䜼íÈ(§Jaßý_‡4/ŸÝunذ!r¹!”••}áÂe™LÚ«—ט1£ÛI½Œ‹‹ËÉÉñ÷÷¯þ—Ëýðჶ+"Ô8vì˜L&sqq6lØñãÇ{ôè9räÈÈÈÈaÆõêÕ+//ïÌ™3>>>µ-g®7¿ýöÛ‚ jôi4|øðŠŠŠ6yCïܹC$[øs[?îß¿5~üø×¯_GFFº¸¸øùùyzzŽ7N&“aNQ±Úµ|ùòK—.yzzöèÑãèÑ£B¡000pÿþýŒŒŒÄ¢·†……%''wìØQ$eeea;N˜0¡sçÎ_~¶X=ÿ’ž={VPP0yòäÆ.X­;õ©‰o2Ó’BOïßZ5ÿëùËþõž––áíÝmãÆ5E¨2eÊl5á–-[°”¼¼¼ÔÔTlÛßß?22’Åb™››ÛÙÙéëëúô‰Åb…‡‡×;NoïÞ½‡>sæÌ›7oZXXüßÿý“Éœ?¾ƒƒæØbóæÍt:ýĉØkÊú1gΜ .°X,wwwSSSå/„ÒÝÜ7ß|ƒ]ø¶mÛ°EEE,kÆŒ­÷nR(”°X¬ýû÷+#gdd(CÔ­\¹rÇŽ,«úÛ§Öˆ···››ÛÌ™3;¦¯¯_RR²qãF:ñúõëõë×ëéé988dee{{ûøøø“'O‰D¢}ûöéêê:tˆB¡üüóÏqqqG9sfaa¡“““T*ussKIIÑ–J+:vìˆU9lz¿Zuss£R©,+..nìØ±Õ«¨Ú³9uêÔððp‹emmmccÓ°«Ý„§s®íÞsX&Ï Ü¼s½ß×Ó7nÙn¡W*—K9nxø™L>aÂh:ݨ­Nxjz®\¹bbb2dÈ‹5mÚ´œœœiÓ¦±X¬   +VüöÛosçÎ9s&BÈ××WWWJ ÐVs°ÿ¡yóæa©¾}ûnذ!((èîÝ»àÅ‹+W®ÌÉɉ‹Åzzz¶¶¶®®®¯^½²°°_uwÌàÝ»wÇïÝ»w;,F­;õ¾#¿Þ},L¦ßÅËG5½G®ãÆù3ÒË«ÔÎä믿NHH`±X‰äüùóñññwîÜ‘H$=âñx—/_Þ½{wHH‹Åêß¿? k×®I$¬.arùÇ\¼x‘ÅbyzzîÛ·/<<¼OŸ>¡Í›7'$$ôïßÿíÛ·‹/æóù,K$%&&ÆÄÄ\¼xQ"‘tèÐaàÀ,ëÙ³gÎÎηnÝrvv®÷ÌöVvú‡OÞ¸õ‡ºvÁÚΩ«·!UF'–`¯˜âã_Éåò¾}{¡¶»Š Ú6!!!UUU?þø£V{mÙ²…ÏçÿöÛomr=tzíÞÔ{t´·2(A-œ½Ç,Aÿx Gõîí µZ5fffõXn×·o_{{û¶­¡ÐNF™L3©<Š@› õ¡-_83©}É(~ ¹D"€J @›A.—5©ŒÊåR¯Êh~)ååì7oÞAAÐz±´4÷ðpo6­¨à”—³ÿñ™ ùü*‡¥¸»{bQð>ÎæpÊá†ÐŒ0ææææùlö¿rääÔ¡9[£!@$õôô˜Ls)òøø$;å·<^BèÇD{{;¸‹4#d2Y.—2™f¦¦&eee@*•’H¤f–Q2™lccK£é‰ÅB…n-©T‚b2b±„Ç«Ò,\MáoÔȈÎá°Åb!ÜZ2™T¡}ü˜*—ˬ5Z\\*‘HÔ™L…BÖ°Wii‰\nR\\bemhðùU\.—Ë­455Q'ÿ¥­Ñ7ï?åTš(ÿRò‰ÇO\ÐÑ©#@£Ñ ‹?|H‹%ª1ò ¹@ r9tøh~ÄbqzzfQQ±@ ÔÕÕÕ<0ªuk”LÑcØü/Ô5—Ã^»döÒ—Q©TlM}m0™vvÿ[¯¬ä¹»{š›ÿÏ0‰D))á „ÜÝ;››3áÐŒÐh%%%..®ÿio)FF+Ø¥Ìe`h¼hÕÖ-+f‹„ÂCÇ"T 9íç7ÌÎÎ!´yó¯[¶¬ÿ§aÌ ½L¥R•-S;;û‚‚üêƒõ{ûßÄ¥,•J¾ÄA2- K>ŸÇãñ”)C‡úŽ=¬Z£d ƒiuóÒÉä÷/…UüS7âÉ ö•H$’ËåÁÁÇæWU TúìÈÐЀN7"“É4š¾±1Í®044Ð<Ö€++k+++.—Ó”Eœ––ÁdšAU€¶JŸ>½³²Ò)Ýââb  !Ôµk×ëÔë­ûíH%·âaä5{gs+[„þÓ¨ÌÌü¬¨ij€µµŽBUUñ‹ŠŠtttˆDjƒ\0ŸÏãpš4(PQQ‘… >@›E&“J¥R©”gee©P ÌÌ:‚òj=o”D&ïÿy5¯ƒ½"×JF B å|ÏzC"„Ð:à‘Ä¥Žr¦½L"3—Ð I´útêÅb>BˆL&wêäC´¤:²§’8™â/}ʳËI{z9wÕNFÅbqFF”&í²µúï+¥ÜÜ|šXW5ÅÙÙ‘H%k’Q‰lkë¥ @;¤Ê@}Úƒa®&‰$Y¡¹5J èP 4hz² ý×Ï’®.©º$Êþ릤æ±Q"‘B&ë5û% …¸¯4%Ù¯³%²ÿµIä\÷.5Ë(‰DÑÓk~ÿÊ £4%FRÝÅn3T›šTZ=e´yáñxX<¸©Ðª Eb±X-QW—J¡4üÈ¡Ž!õÙ …L«L c}º¶‡®Ã[ݽ{÷8-š„W®\ùò∌ŒŒ…*­·oß¿J­|ý‘§üÛ{ð4×(aÙ("‘¬úWTTªÙ¯ñ–-;:þå‡ÖÔ}øðapppÿþý¾ùæ„Ðõë×ËÊÊBS¦L100ˆOLLD 8ÐÕÕ544ôðáÃÇÅÅeðàÁÕ3¼uëVQQBhòäÉ %%%åÇ"‘ÈÇÇÇÝݽ°°ðöíÛ! …bbbUÚ6n½•+)ïÞXVX`aa!‘ü@ …L*ý@ççç¸Éµºhúé§ë×om\upp°²²òðð°³³C………)Šnݺ!„öîÝ;wîÜèèè#F „¢¢¢\]];wîÌ`0ºuëffVƒWã;wîðx¥=âåË7"‘¨ÿ¾›7ÿJ£ÑJKË\]]¾ÿ~jzzÖ©SçBtºÑ?ÌÑÊ»Å/¿ì66¦gee[[[Í;ƒN7¢R)¿ã'NœKNNE?ºoßž!!§æ—––ݹ=cÆ”zʨ“““µµu×®]­­­Beee‘‘‘L&!TUUE§Óe2Ù‰'°Æ)BÈÓÓ“Édz{{ט[ÇŽ9òèÑ#„ÐÚµkBcÆŒéׯBË„ÍfcûΘ1*´ ²3?>¼sµ(?'éíóß‚C»xù Tªü6,ìÖ´i“mmmBÉÉ© ¹¬Œª¬ä „PròÇàà? ³£GOåää:u~×®m!‡[RRª•Œ¦§gnÚ´öÿÛ»ÛØ&î;à¿»óùÙÆqœ¤ÄI¦ ,0 ¥+¤¤Qioªí•Öníªns^¦²n•¶µTÝ´J¼Y_ VËÖªR7UêÞñ ¢0+¤ BiâÄvžqÇgŸ}O{q…ôBú¤Æß¬ÈþßßçÓOÑWÿ¿ïü¿ººÀ±cí—.]~ôÑæž|ò‡Š¢Ñ¡C¯nÛ¶ypp˜ˆ$I¾uëÖâG£S’Éd$!¢—^ziÓ¦ÛK2§R©Ý»woݺ•ˆÂáðôYüõë×=¾Gmnnƒ¢(¶¶¶êK=…Ãá—_~y¶;q℞Ëðmwð•¿8Ýž¿½ù:­kÚ6cëóÏÿäÈ‘7“ÉI"zðÁ­UUþÏ͉kÊË f·eeî²2÷‚ŽÄë]^W˜mk,çHR‘ˆ†‡‡¿´I=µ¶¶>|˜çùƒ666¾ñÆo½õ–>ïv¹\]]]mmmú¸Rï¿ÿþp8¼nݺgŸ}Vo¹xñâúõëƒÁ` 8räÈàà £‹%¼}ï½P(DDO=õT8&¢;v~-ßFÏøÏ›''Æ|þê›::>ª««]³¦‘ˆ¢ÑØêÕ«R©Ôñã§ßÿƒ'žøþçwµreÝñ㧉H²~¿ûö­ó?ŒX¬¿­í½ªªÊ¡Í›¿CDííýýƒíí--;“ÉTeeEMÍŠáá‘®®›,ËZ­ÖãÇOŸ?ÁívÞ{ÏL§ØyI¼$¨BßžB?-³»ˆÈbqÚíß|%“1ü |{]¹rumS3˲Š"D{jY†,Lvú¹ ³gÿÏ‹D´k×UU;;¯NN¦%IbzüñÝ7n|¶fÍj"ŠÇ¼Þ執©iƒ£Š¢rÛÒ²S?ÚDb¼ºÚÏq¦ÆÆàÕ«×GG••¾“'Ï8Ð:}Ï £3}•¢Â„páÝ Xþ*MMˆ&H%ž¡Uõ夎Íø±%=üðƒSωd{{G¡Pày~ß¾‘ž¡DÜ^Dy÷îG ?Ëí¶nß¾íÞÇ ­ …ÖN½ÔÓó”ŠrìX{.—cYvïÞÇ3©WY_+àkãó•8Ð*Ë2DZV«õËÝù+¯šgŽãöïÿE±(1 c·Û£²,θ àk`±˜-óW´çyöL˜³)ʙȡ7L‘"+^ÑUn.›oŒ”¬eÎ/ÌhÌŽe׎Ô7‡ú|%ø"îd­JYñ>ã_â''SƒƒCD¤q ÕÌ£kaY+Š¥Œ!ãu¡XƤ'¤ÆÎ>­ð{ôëFJ–`.PÑ ½¬ÌQUµœˆF롸qŒQ&“=v¬u€’Ø$£ñd"1‰ô+X³iÖÑ(ŒŒ¾ûÞ¿š[eˆA5 ÔüçÒ…=õl¶6;£=7™Ëçy"ŽãLsÜÒŽˆ¼åå/üòW ƒ€’óç×_õŠÎê‘åCCÃDdæy‡Ãa³Û&'SÕ÷ù½^¯Éd’4yŽ(e^ó²-¡¦kÔED.—{åÊzE‘>ý´›çg¹yÝ<÷ÛÛÓ=0ÐODkÖVø+Qh(åå>E‘ˆhÅŠêH¤Ïpí¹¹/¿Ïf2D”Ëç>üàŸ—?.Ѝ,”«Õf³YôçN§Ãl6¾ÉÜ1ÚööѾÞHhýÆM›wîj© P\(n÷2vZF66®ž˜H.fRÿÜÏÃÿëÛÍ´ ¦PRÒéLgç•é-@ÝbbÔl¶<ù£ÿñðïkµ(+”QÌ64ÔOoñz+3©'"!›µÙì,‹uL£±hß{ï´½øëßNÝl£gN|湟áj|Cs7úô3ÏQ>—Ëå„L:],Ìf 0ßѨc‰Ä™Sí7?½ª,`4ª{lÏÞÇöìE½ t¬\y¿Óé˜Ö ¥ÓÂâG£%7[gU§Š"޸хø†&õ¥&õöFîžæ¯BŒÌWeeu0¸zZƒ&Š&õó%i†‘¦Š"ŽÝBŒÌW&“QuêewwÄår"Fæ«XA¼©YQ,vCŒÌ*™gŽˆâñ~·Ûøþó8Å0+Y–S©Œ$8nÖ´4Ø‹FÿôÚk‘@éùoç•ï=°Nîv{œN‡¢¨‰DÒçó3 Ù펹c´¦fÅë¯ý¥€Ò´ëá÷ß$¢††z«ÕÎqy½Ë¦:¨ªBw2MÑþèõk×e’3‰ "«Õ²iÓF”JœÍf#ÒTU6Ü:ïéé‘ ˲L§Ø9"Hš”I?Rö]F¡Ï>‹ ‚P²êívÛ=:(ŒÖe‰§•´$J§>¿Ûí$Ò/ßÇ–2Žc\.›Û]—JeEYèÛ .¿/+ó ù; P4M‘¤ÂÈÈ­…¾Ñ`4šJ%­VÓèèhmmÀð¤KL&“ÇûM&SEEÅ—£DÄó<Ïó==½v»­®. izTkš† >,¥(©ªrófO±X¼3j\ð ƒu8\^¯Ÿˆô¿cci§Üf³_¾|EÓ0Ó€%¢¾¾¡X”‰DuuÍT£Ýnÿ¢1êv»6lXkµþÿÊË—»jj*‰”-[6 î°ÄÔÖÞ7£EUv–é®UUãŽã$MFq DÍ5­WÕ8F=+<Ûnò&Þðm±‰`]p\G…`É›ˆN‚ãʬ‰—RR1º¬zÙ ‘düžîH·¿ÆSb¨/,yÝ=ÝþzLšW♈(?™dáÞý$Q’ ’P_XòdQ–ò’š#ñò“yÒWx:÷Á¹¼˜Ÿs¿§…ÓÑþ(ê KÃ0í¹öø@|>ÿ, 5™="QIEND®B`‚snd-16.1/pix/intro3.png0000644000076400007640000005000311147553267013070 0ustar bilbil‰PNG  IHDRTÖŽzÒsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ$.À=G> IDATxÚìwxTEÛ‡ïÍf“즓FH„¤H/ÒQD±PT44ù^i/¨ (U:A@.Mª¡÷Bè!!!½×­ß!–ô0ÈÜו vfΜ93g;õyd' VVV äDFFajeeEåÊ¢6à ¹‰¨@ („  T@ ([˜J``QØÛowF&“qûö]"""iݺ¹wÿ~(AÔ¬YêÕ«>sáŽ;ArrŠôÙÃÃzõ|ŒÒDDõë×àÖ­;¨TÊ|%ŸäüùK¬X±¹\€¯ï`Žù­VËÝ»!ØÚÚл÷<|ÉÎ{Y¿~3 …)õêùдéë8pFc”wdd;vü€……¾¾OxøC._ ##“š5kЦM 6nÜJRR2]ºt R¥Šâ+xiÙµk/‘´jÕoo/ ~Ø]»öIé ÇŽ 55•ðð‡¸¸8ѽûÛ%ï¡üï?àë;˜Y³æ?VaSS||¼ùý÷-…þàÁ#DEÅàãã7ë×o6ÆDhè|}ãë;˜3gÎ?âG²k×>)¿+üŒýر¤¤<ÎßÓ³ÎÎNT¯^ oLLŠ6mìéY‰ðð‡¨ÕYddd+ ‰—Wu¶mÛýToz‘T¦J•<˜7o1‘‘ÑìÛ÷7™¤¤¤rúôy®_¿ùL/ÃÈ‘ˆŒŒÆÇÇ•JÉڵ뱴Táãã->>Þ”/ï"¥¯U«Fe],•ÕÕµ< .'<<‚þý‡âæVo.]ºÂ•+¬Y³•J%¥/J› eýûKú1gÎöìÙObb’ô>¯^½ŽÌÌÌ<¯7 8œŒŒL||¼ÉÌÌâÏ?w=[uêÔ¯rõPÍÌ´hÑ„åË×úP11±:tŒû÷C8vÌŸñãG©B<<Üñóûå©nyöðµE‹& Ü_Š{íµ:¸¹¹¥÷ññÆÃÆ ëQ­Z•b5ÈÛowf÷îýèõÞ|³£þúë pvvÌÕ£´°0TF5))©RÜ©Sg /²˜DýúuøôÓ^ܾ}—ßß‚ -Z4ÁÙÙQª—7nˆ£c9£°¨¨h)]llû÷ÿM›6Íùè£iß¾ ×¯ß ))…*U*säÈqéÚ?î!¾©‚—‚ÎÛ1þÌGâzˆ¸¸x¢¢b8~ü$wîÜ{¤G'ÐëõùæÑªU3zôÈ%Ÿ9#çÂ…ËÏ&¨¥AÇŽm¥Å+_ß±³³-µ¼oÞ¼MýúõŠ•¾FjEJûÖ[¤¡öÓÂþ4ŽŽøú~,}¶±±&&&N°¤¤$ìíížùyããˆÃÑÑ!ß4ááØÙÙai©zæûyzV¢B…žÒ4Éœ9 X²äGñm¼´téÒ^ê$úú~ŒR©Ì7mTT IIIØÚM³J$¨IIÉŒ7™S§Î1hÐH~úi*•’cÇN°dÉJîÞ Á‚/¿NãÆ Y¶l 'Nœ gÏ÷ðô¬T¤û„……3hÐH£_‹îÝßF&C 7 ’ Î˜1‡Íðáƒhܸ!]»vfÁ‚_ÈÌÌâÃß-² Ô«W¹Ü¸g9~üéÙÇŒJÍš5èܹ=3gβç%,ø¹\NffJ¥uëúpàÀ!ÚµkS¤ûúú~Ì!c1û¬w¾åˆcÍšõÒÈÀÇÇ[|#/--Z4eùòµ>œ=êú䓞xzV"==ƒQ£&Hß•9sf`mmERR3fÌ!99KKK>ÿü³ó—Ý»`Èïè©N§C&“åªf¯¦?^áÏêêt:4šì•xÌÌ@ö–.»[­P˜J -…¡V«˜är9 …)Z­­V'å—SÆ'Ó+ #!̉Ë)kQÉ·¼{øãï=Uâ<²²²˜6m©©©ù¾w}ûöåï¿ÿ)x&J´VZ¾¼+Éɉ(•ÄÅ=T{ûr¨Õ}´xx¸“‘‘ ØšïÙ³g¹y3ïÞˆZ­æàÁƒLœ8‘ 0mÚ4)î·ß~Ë÷ºþýûS¹rå—¦A’3!¥œ”*äàœŸ×éû÷aÕªâeøÎ;Ð¨Ñ ¯+k[úÿ†?ý·Þÿ7*ÅÎ#>>žýû÷3jÔ¨<ã¿þúkV®\É€èСƒ~ãÆ Ö¯_Ÿç5uêÔ¡G¢¹ƒÙ¹s'o½õV‘œC þC‚j‚ ê™ÄÝ&11{{; =–Yæ˜Ê³“:99¡ÕÛ´±±!55íÑ'™d ² ,;;W(RaÞ~ûmþøãb?D§NhÙÒØ—¶V«¥zõê´oßþ¥Ô”LˆH~ö|Tfjh(̘Q¼ ÝÝÿA͡Ϡ±lY·Ÿ×šP½s#,EwïâêêJãÆ‹}Oú÷ïŸ+|„ ܺu+— Ž;–Ìíf÷îÝtêÔIê«&¨&æt÷~‹¬ª­8zä;uD£1&988ó” Z“˜˜”Ý3R(èÒåM£x{{ûîÿûÍ›7§cÇŽ¦svvΖ—qYÁË‹Re…:+¿¥³x¯Ý äþ²Ž=ÊÁƒùmË*•Ê<Œ­­­óœ>ˆ %µx$&&qþü¥Ü=úõµ±±A£y| $$7·JT¯^¸/÷Õ«W£Õj  nݺ¤§§£VgoI077§wïÞ,Z´ˆÙ³g‹–{Z¶„¬|æ È{:à_î]E<A«Õðãª]XÛojHH±±±¬Y³†Ñ£G£Õj%Ë–-ãóÏ?ÏwJ@Pzœ={–»wïbaaA÷îÝIHH`ÿþý4oÞì½ÇW¯^ÅÓÓ3_ëúƉ'èܹ³Q‡îîÝ»œ={€®]»bmmÍ–-[ÐjµÔ¨Qƒ påÊ®_¿ŽL&£W¯^ÏWP«T©B¥J¹ìéõz©Wøäª¿Á Šf¥ÿþFC¬~øÁ(¾}ûö´oß^¼•ÏŠLù¹„11É?î_@«ÑššÄîÍkèÝoD‘ý‘=IåÊ•æB;tè`4WjjjÊš5kÄ{ñœÑh4¬^½š®]»JžFƒƒƒ9uê;wFñȯOdd$ï¿ÿ>û÷ïÇÓÓ³øÓC}úйsg¢¢¢Ø·ok×®²ý¤õîݛ޽{sãÆ þùç¼½½Ù»w/}ûöå³Ï>ãçŸfôèÑL˜0M›6ÁèÑ£ŸŸ Êå&ܺ•Ûµ@PÐB‡æ‚ÿ&§Žî£ó»?—¼ÿ\ÿ a÷5yž¨è—œ“'O’˜˜ˆ\.—~ЦOŸN§Nh×®ä«íðáÃ888”ø>•+Wfâĉøúú>ѹ3P§NÆŒ#Å]½z•Í›7£R©ˆˆˆ <<œ>}úðñÇÓ»wo P¬{ ã(‚g¦R/Ö-›CFzZ©æIÔÃBLÿ#4lØ &0iÒ$6mÚÀüùóyøð!ƒ&))‰?ÿü“õë×Ó¹sçç00“qþüyþøã¾ýö[ôz=nnnŒ5Š3gΰzõjìííÙ°aÿüóÇÇÝÝ]ªàÅRÁÓæo¼ÉÖuKJ%¿+çO°àûqü¹~FL~©ëæÞ½{œ9sF¼$€••¯½öëׯgñâÅÔ¬Y“Ù³gceeÅž={¸|ù2Ë—/.÷—Ëå¬_¿žû÷ïãïïÏ”)S˜4iµk׿À´iÓ†nݺ±`ÁΜ9ÃÙ³g™QÌÝ0Åòge©‰‹Ë½±>gñHðjRÕË ¥Šic|±³w¤iëN^}Œ §OŸÎ§Ÿ~Z¢ûÔ®]›>úˆ””|}}Ù¸q#<`̘1ôë×7Þxƒ~ýúàççǵk×1bÖÖÖ„‡‡3qâDz÷îÍ›o¾ùü555{Ãîî´Ø´üª2uÔ§Lõi©å7iøÇ…þ¨×ªUKTüKFëÖ­ñ÷÷7 ;|øpži§L™RâûÌ›—ÿœ»ŸŸŸÑç'­ÜÜÜr¥y®‚*<ÉÖ­[_øtO^Ûö‚²€TÁ3Ñ¢E‹Wâ9ýõWøà>øàƒ—Ê6DY"%%…³gÏòÕW_IaŒ5ŠÄÄlcKÑÑÑôèÑ___zöìILL 6làã?fÔ¨QF'Üòãܹsüßÿý_®pƒÁÀܹsyï½÷èС‡&$$„¶mÛòÉ'Ÿ0bÄbcc;v,}ô­ZµâîÝ»BP‚ÒÆÃÃ///¼¼¼°³³RBA=wîRصk×L€îرüüüðööfÇŽìß¿ŸÕ«WÆ­[· ½Ï… Î}øH§Óñ矲hÑ"fÍšÅÏ?ÿÌ?üÀèÑ£Y½z5>䯿þâÎ;¬ZµŠÉ“'{Û”T@ðB¨P¡C‡5rÓ»wo^{í5£t9ÇËsþ á‡~ aÃ†ØØntðàÁùŽ"jÕª…››5’~;t耹¹9­Zµ²m ¨T*£ãɯ¤ †……áë닯¯ožfׂçÉÅ‹%£‚Ò£I“&xzz²aÆ\NñÊÿ©E©Š+J[4 ¿ýö›x/ŒÈÈHiáJPzDEE1{ölbccIJJ*ÓeC~à93aÂfÍšõÊ×CFF7oÞ$99YZì¹ÿ> ܹs‡””lmmùþûï¹yó&3gÎÄÆÆKKKnÞ¼‰V«ÅÜܼÐûܾ}›äädnÞ¼IVV±±±„‡‡#“É8wî;wîdîܹh4\\\øê«¯¸|ù2kÖ¬ÁÆÆ† 6pîÜ9Ƈ‹‹‹T ,Q¥JîÝ»÷Ê×CLL ›7o¦aÃ†ìØ±€ýû÷SµjU8@XX={ö¤W¯^lÞ¼™Þ½{Ó³gO† ÆæÍ›©_¿>5kÖ,ô>[¶l¡aÆlÞ¼™„„®\¹ÂñãÇ‘Ëå¬[·Ž€€233Y´hÓ¦MÃÝÝÝ»wóÃ?н{wæÍ›Çþýû)W®\±Å>T@ðBððð`Ò¤IFaƒ Ê•îéÓKÞÞÞx{{kDð$åË——þ_¯^=êÕ«gÿä6.€víÚÑ®];1ä‚!¨Eeñb¸pAÔƒ@ðŒœ>}:WØŸþIhh¨ô900PrëÊï¿ÿÎï¿ÿNBBB¡ù–>¯ûç„íß¿_ºvãÆBPŸz= ¢‚Œ¯¯/‹-’´Z-«V­B.—K.Pîܹþ}û°¶Î¶`wìØ1BCC±··/’çØ>}úpÿþ}Ξ=kä'L¯×ãëë+YºÊÁßß_šføý÷ß±··ÇÒÒ’_ýUª@ (›Ô¬Y???#¿`~~~T¯^wß}WWWضmãÆ£I“&‡‹±¶¶¦K—.’È„§§'&L`þüùÆbgb‚ŸŸ_®…­“'OJù®]»–.]º T*ùøãâ»õ‚*o¿ýV:4rìØ1Q!¥@LL +V¬`ÕªU 0€„„¶lÙ¡C‡èܹ3§N`ùòåœ9s† &‘‘Qªeøî»ïˆŽŽ¦víÚFá{öì¡k×®BP‚çÁ¤I“ðóóÃÏÏ6mÚˆ )üüüxÿý÷ñóóC¥R±k×.<ÈÊ•+™:uªäõ¸nݺüòË/\¿~›7o–Úýïß¿^¯Ïå`Ïž=4oÞÜÈýtQÛ¦È6r[¨MÏ´4¸v bc ÍïŸþA©TÒ¨Q£|ÓÄÅÅqàÀZ¶lIff&çÏŸÇÜœñjØžóo¤¨.¸ŸF§‡´|©[·nXYYåéàûöå›oƒ pvv/ Tpss²ÏùØÛÛ£R©pvv–æT¨Y³&Mš4)Ò?22’èèè<] ¸¦Äg—UfP»|Þq»víʵÔÔ´Àgœ={6111¹Â[¶lIß¾}lï’EY<¼Z3sæLN:ŰaÃ6lŸ|ò àÎ;¬[·Ž'NðÉ'Ÿɸqã€l*Í›7gèС’¨‚¨S§ü1)))ôíÛ7— ”S§NáëëËìٳټy3ýû÷§OŸ>akkK¹rå„ æEŽ9® .™™I£FJæâ`áBxýu( ×ù4Õ«W/Rº–-[}¶¶w¡Q‡ž[tëÖ-ÿÈ}ûà£üïýQ>qþþþ <8»üÖÖÔ­[333úôé#ÔD -J=É…§¶".[¶,×uAAAźÏܹs œfȋիWÅ?DðÊ ª››U«Vå£>B©TŠ·ú9ѲeKé‡!99™K—.••etò¥jÕªRO6WWWix'¼Ìüçµ^½z…/"üô¤¦œF§ƒ½{ œ_ÀË zôx¥_*£:ïÔ©“ôÿÛ·o³bÅ £ôfffEžÚhÑ¢mÛ¶ß\Ôçżyó¸råŠQ˜^¯/zï¼ZmÁiv5¡0_Bù-ö¨V­šd=((ˆäädBBBP«Õ¬\¹FSàõ§NâØ±cL›6MTæKFrr2cÇŽ%<<œ=z ×ëÙ·o*•Š„„ú÷ïÏ?þ(Í“Êår&MšÄŒ3ÈÊÊÂÉɉ™3g¢R© ¼Ï¢E‹8pà™™™ >\šâ2 œ9s???–.]Jjj*K–,áÚµk„……±zõj&Mš$퓽sçN./­¯„ Ž3&WX±ì¡a¢…œ¡F ñÍ(?üðƒÑÑB€Ê•+cii)}>tèúÿ‡¹té™™™ÌŸ?ŸÁƒ3þ|ºwƒ3fÌ V­Z̘1ƒ7Þxƒ={ö––Fhh¨ôCÛ§Onݺ•˸ÉÓlܸ‘õëד””Ä„ Œõâŋܾ}€ÔÔTºvíÊøñãÙºu+óçϧ_¿~´oßžëׯ³}ûv1äš™3g²zõj:tè mjÚ´)®®®â /% ƒÑËÏñãÇÒ|õÕWxxx…)•J£S3‚ÿ6-[¶¤yóæDEEann.¹> D©TJ>»ÒÒÒ8wî_|ñ...9‡™™œÌ7X´h .,õò¦¥Aæ#ÇŽ* Y)y¦•ÉL0WZ¡×éPg¥Çi €-xŒ5ŠAƒ¯jÊåÒ…ñññL:µÐ2Ëd2ºwï.}®^½:  "0B.—#—Ë9räˆ4®ÓéX»v-ß|ó”.44 ɸó™3g>|8sçÎÅðìi 4ˆ¦M›JygeeqæÌ™½Ã¯ÌfÁŽ;JÿòËŸ!!!Lœ8ñq@¹r°};lÜHÍš5Y»v-Ç/õr*ä`úèüšK¥šèu:bäíéQnj†£[U4™éÄGÝ7ŠÓ «iáåË—³bÅ ã©‘jÕàÑs;88”l‹™@‡F¯×K6Hqww7Ú÷9kÖ,£÷.Ç}÷¼yó¸zõj¡CþâIbb"_}õ?ÿü3S¦Láÿû_‰ò»¯ è¡>i‡… ¡Y3£}¨Fñ¥Dx"D<êYÞ¿~¹‚¶=Fæ™V«ÎäÁí,,­)_©–Q\AûŸä‹/¾0ðõ!¢¹ •Α'&&Šƒ %àÒ¥K×®]cÓ¦MDEE‘œœLLL YYY¸¹¹qóæM’’’¸qã:ŽÑ£G3gΖ,YBÅŠ¹{÷.¶¶¶8::–èÅYþ2L¥Z©X£~þ¿†fTönœKL¥ÏÑ£GÙºu+[·n%$$$Wü_ýÅ›o¾)*ª°¶¶æÏ?ÿ”Žš¶lÙÒÈ¢~¥J•ŒŽl÷ïßWWW8Àœ9sŠäeݺuܹs‡ÔÔT–.]J`` þþþ ¶nÝJãÆÙºu+åË—gôèÑìÞ½›5jðÍ7ß`ccCÛ¶mK¼8*~f‚"ðÙgŸIÿ¿wï©Oí[>z«”T IDATtèP‰ü¸¿JxxxO£‘ûÔ^ýú¹;O»()ŒZµjQ«ÖãNÆ“‚ýôý»téB—.]¤ÏŽŽŽ%@ ”"¢‡ZT¼¼²¦A‰ˆŽŽæàÁƒ@¶A¢ *ð×_‘€››o¼ñ$::šwß}WÚꘕ•Å–-[xë­· 5«Ê?ÿüÀ›o¾i´àuçÎÉÝÉ;#µµ5›6mÂÄÄ„N8^¾|™k×®!“ÉŠmdZôP‹J§NE; òdÍš58::rûömÈÞ½{IIIÁÑÑ‘1cÆpüøqöîÝË”)SøçŸøúë¯ÈÌÌdñâÅ8::Ùʃ¸pá‚Ñ‚—N§£wïÞÄÆÆrâÄ ¾úê+.\ˆ¥¥¥tzJ«Õ²iÓ&LMMK4ô=T@ðBÈ™ õððÀÌÌÌhïÚµkØÚÚbnnΆ ðôô”ŒêÌŸ?Ÿ÷Þ{¯H Rí%ç^Oæ1 Ô­[Wò)åëëKPP®®®üöÛoL:•7n@ƒ ŒlPˆª@ (sL:•iÓ¦IBLݺuñòò¢^½z4iÒOOO–.]Š\.',,Œ5kÖ0cÆ Æ_ê.Púöí˲eËøðÃéÓ§U«VeÖ¬Y,^¼˜%K–Aþ-jÕªÅõë×EE@Ë–-iÚ´)k×®²·Rõë×+W®pùòe Û›Ett4óçÏgúôéÌ;—•+WróæÍRuÙNùvìØÁÀùí·ß°°° N:øùùIe‚*ü xzzrïÞ=QùpäÈjÖ¬I¯^½ð÷÷çîݻܸqCšç¼yó&aaa,[¶ŒqãÆIû}]]]‘ËåFçò âáÇDGG’ËJXXñññܾ}[:ŠH[§RSS¹{÷.–––´jÕªØÏøŸšC5 ’ù·ÂÌÀ ‚Ë… ˜2e r¹œvíÚ¡V«5jµk׿îÝ»¬_¿žàïïÏ7HHH`òäÉ|öÙgÔ«WŒŒ ÉèIAÔ«WO>ù„””úõë'¹@;v,Õ«Wç“O>!&&†Ñ£GãååŰaÃÉd :”ÐÐPúöíK«V­Jt´ü?%¨áááÒÜbÙCž3+V$,,ŒŠ+¾²uðå—_òå—_…=íwmÀ€¹Œ’weΜ9ùÆ-^¼8WXŽû“Ξ=[âgüO ª»»»d ^£Ñäª(àߢnݺ¼Ò‚ú* ¶M E`íÚµ„……ÙF>Šê€Q U |Lú»yóŽph&xe¹|ù²äþiªT©ÂÝ»ws…O˜0‹/æ ŒŒ4rçñ$£F•ý2öPÃÃÃP©T¤¥=Þ6’’’‚N§ÀÜÜŒ7ßìjt½¨iÁ–ÐÐPìíí±¶¶.ò5›6m¢W¯^lÚ´)W\bb"3gÎä?þ0 ?tèíÛ·Ï3¿„„Ñ/c5:::×9ùŒŒLÌÍÍl%YY©Òßýûwˆ‰‰5-øÏ’€J¥’¾EáüùóFÞ=s8u꯽ö*•ªÈy :ÔÈr’à%Ôìi*r¹ÈÞú‘•¥~Bp#±°xü2DDDbi©5-x%5j?ýôS‰¯7 ÈòZ¤(äšfÍšqêÔ)Ñ/§ ¦ Re;ÏŠŠŠÁÌì±묬,1L ÆÁ¡xŽíþúë¯|ãX¾|¹h5A±9tèþùg¾ñsçÎ-•ooo®]»V`Ï4::ÿÛåË—©W¯U«VåÎ;Rø±cÇhÓ¦ o¾ù&{÷î}¢Ã““*TÈ•oHHH¾–— úž JN‰V‹´Z YY™¤¦¦¡V«13³4ŠÏžÏ)î/íêÕ«9tèo½õV®8FêU«x÷ÝwY²d C† ‘âîܹCRRÒSeÔpëÖ­bÍmýÛD§Bl)œj´P@VD .´¶†<DÊÞÞÞXXX9}PP—.]ÂÉɉƒÒ±cG£ø)S¦ðá‡2þ|,X …'%%‰Z±±±9r„:uêÙNäÞyç.^¼ˆF£aëÖ­’gM•JÅÅ‹¹wïK—.%++ KKK’’’èÒ¥ 111R>J¥’¦M›baaAûöí¥w722’ 6`ooO§Npss ==^½záêêÊÏ?ÿ̤I“¤¼*UªDÏž=òÏá­·Þ*¶¿ûW™3g{›Z±µ^½úÒ¶)ss^^5‰§ ƒ77wœœœ¨X±Ò£—Ä2O?~¼ôyòäÉôïߟcÇŽåy_½^Ozz:žžž?~Ü(îêÕ«¹z9ó¼Ÿþ¹x3ŠƒŸ4lX¦‹D­ZµŠœ>##333ìíísYp‡l;ºÞÞÞ¹~”ãããs½k9â–””d”~Þ¼yÌ›7Oúüä"QÃ|ê³C‡y†ç—þI§qOæ?sæLfΜ™+ýÕ«WÙ³gOžy]½zU¼ë…˜˜ø|{¨ôÁÔTA~ON\n‚‰Iá3 ¦¦¦LžÓåþýûܽ{—¶mÛ˜ÎÓÓ3ÏíH×®]cûöí(ŠRýÏ;—÷ß¿Ð÷½¸lܸ‘ *кuëRÍ×ßߟÐÐÐbû®/Œ6oÞlÔá* ´Z-cÆŒ1…„¥¥åóÔÂV1‹"¤9Èd2Ê•+—kÈæÌ¨[·._~ù%}úôaĈ( ¼¼¼øá‡ŠìšàéüózžÂÒäJ[X`ggW¬ëlllHJJ*ö½JR¾’\ct]z:,] ÞÞ0x0ЦJ¥²ØuammMzzú {.ÈÞï¹sçN666¥žo5°·/ý½à®®®¥þ£’ó£Û Aƒ—ršà•>ÂÔ¯_¿b_óþûïûšš5k–égÊ÷º™3ÁÒFŒ€<†·~øa™®—‰çuN¿Y³fÏ%_//¯ç’¯““ݺu{)ÛPÀäOf&|ù%qÎI xÕ‘ÅLJ¤îª©r¹9YY)=rŠŽ:¢ÑïቊÊR©ÄÆ&ÿ-Jr¹66®¢Ö‹Htt4ÎÎÎ/ö¦ÎΓ;lãF(d§(ddd Õj_ª­lOƒ££c±· þ] ±±±ÅZD-Œ””‡hµê’÷PŸ¼Ê‡ò\óþŠZ­Ë•þË/'1eÊ÷¢5K¤mÎe£ ß}W*bšó£û2‹iÎTˆéKØ{”ÉJULKeȯ´.G…ª ŒþvïÜI@@*¸¥3æ¦MûšAƒ|™1cŽhÑ|Ðjµ|ñÅùú¿qãÆ cöìÙ¨ÕêW0KKøí7xÊOzQY²d ¾¾¾L›6-Oãû÷ïÇ××—;w–Ù¶9qâ¾¾¾¬_¿>W\VV–´ë¤¸føEãÂ… F Õ[·nÅ××—C‡¡×ëùñÇ|È­[·>|8³fÍ’,>Éï¿ÿޝ¯/þþþÿž j4j–̞ȟ뗡Ѩټv¿-›C¯~#óH«ÁÂÂgg'zöì.ÞŽ~9e2Y.£39ìØ±ƒÁƒadãáÇFÖŠNŸ>M@@@éÊÌ fφO>öÆš5kÆÚµk±³³ãþýû¹â7lØ€ŸŸ[·n-³m³|ùrüüü8pà@®¸äädbbb8p »wï~©Þ¹ãÇ3hÐ ÒÓÓËt9MMMÜÄìܹ???~ýõW´Z-ÁÁÁL˜0Í›7LÅŠiذ!.\`Ïž=ôïߟøøø\‡6öíÛ‡ŸŸ+V¬(½ò÷‚[ר·m=‘¡\9çÏÞm¿1núBZw|ˆ•Ò­_ÿ7nÜbÅŠµ¼ýv¼¼„óüËåy,ˆÀÀ@6oÞÌÅ‹155åƒ>àüùóÒêè† ¨U«111têÔ‰«W¯røðaš4iB“&M ù™5É>1ŨOS¿~}vìØ‡‡G¾6Aÿ«V­bÙ²eìÞ½¬¬¬ˆŠŠâ½÷Þ#88˜аaCZ´hÁ±cǸrå …‚–-[âääDùòå9pà:ubáÂ…(•JȰ°° ))‰nݺÈ‘#GhÚ´)nnn$&&R»vméÚ¨W¯^±ö·ÿÛ»¤Þu1ë—-”staï¶ßèò^Ÿ<¾Luprr¤qã†ØÙÙˆ7¸ôz=>$<<\æ4jÔHê±:::ŽB¡¬|•/_ž† âááÔcº~ý:Û¶mcÓ¦Mܺu‹={ö0wî\ìììØ»w/1O/:=‰•,\øÌb °nÝ:©Y³&™™™,\¸aÆIñÎÎÎáèèXfÛÆÕÕ•   iç;ï¼ÃöíÛ¥Þ“©©)ááá888¼4ïÛ¯¿þŠ¿¿?×®]ãÃ?dîܹ “Éð÷÷ç»ï¾ÃÎΎÇó÷ßsîÜ9Z´hÁÞ½{ñ÷÷'$$äQ§i=Ó§O—öÎnÚ´‰ï¾ûŽ[·nËž={X³f -Z´àܹsœ9sF²q×J^DDD˜˜(¹ívpp ((d2J¥’œœœP©TdddœœŒµµ5DDD —Ë155eÒ¤ILâ ½½=AAA¸ººþ{‚ à]ïuæ®ÜA9GZu膹ynCÞÞ5)WΞzõê¼ô‹ÏN‡¥¥%ñññ@ö¢G=¤…þýûóàÁzõê%½¼NNNøøøP¡Bi? §§§”§J¥B­VcmmM\\ׯ_çáÇtìØ±à‰ù… á Ã3ÏBLL …‚]»v‘˜˜H:uhÕª•?eÊvíÚÅ7ß|SfÛæÛo¿e×®]Œ7È6*’SÏööö¼ÿþûDEEáëëûÒ¼oŸ}ö-[¶”l¸ºº2xð`ºwïNË–- âáÇ´nÝ;;;ÌÍÍiذ¡Ñဘ˜HHHdffÒ«W/*W®Ì€ptt$..Žôôt6lH5¨V­¡¡¡\¼x‘zõꩬ4oÞœ¨¨( Û›Á®]»˜6m …‚̰aè_¿>5kÖÄÑÑ‘6mÚðé§ŸC÷îÝqpp I“&F6hÇÇ®]»˜1cFéMßwÛԾ×x­Eö°2èÊY¢#Ãy£ó{˜È ¸[%¢V?žã[´h_|1¹ÜäÑÐVl›*M´Z-ëׯ'<<œ‰'òÑGaeeÅŠ+˜={6666T­Z…BAbb"Û¶mã½÷Þ£{w1Ÿýª3{ölé¬ü“ÿسg›7o¦k×®¼÷Þ{¬^½š“'OrþüyΞ=ËÌ™3©U«¡¡¡|ñÅŒ5 ,X åuúôi²²²ˆgûöítìØ‘>úˆ³gÏrúôi† R,ƒÜe•§·M[P££ã¨P¡B>CWz½¶€¹B!¨ÁËŠ¯¯/~~~%¾>88˜íÛ·3~üø—j^ô¹ ê³ U ü—xZP_ðY~z½N´‚@ øO`0~¡‚ªÓiHJz ZA ü'ù׬M "#£D ‚—{{{,,ÌËŽ êt:6oÞ†“Sî=ˆåËW@­V[¤¼LLäT®\E´²@ xfââbQ«³(_Þ{÷n劷´´¢U«æeKP!{¯d… Ù‹T¦¦ ”J ÜÜÜIJŠçìÙ T¬è^´n¶©‚š5k”'Þ@Pb’’R¸w/‰ZµjáææJÅŠåILL"--ŒŒìcºNöäêË– B¶s?G,,˜››“‘‘Š^o@£Ñ{ !¿³ð@Pôz-:öÑÿ h4YXY)±´T¡Óˆˆ(x è_Ý ¦RYâåUKKsär´ZhQ@P¦0 €¹Ü€—WMRRRʦ jµÎ;Kff&z½A´œ@ (³dddrùò%ÉžF^{Èñâ•|ãððp/r^ÙgÍ­¸yó6öööXZª(WÎ^´œ@ (3h4ÂÃ’˜˜„½½*•ªô5,:‹ª¯u4 KJˆcÁ·cØðëb ø÷mmmÑjµ$'§þgçâ[ÊÈÈ ::F´¾@ (1©©m‘¤¤¤ñ€ŒŒLär9ööv…^_lA•›šaaiœñäÑý(ïZ¥ÒÂÈ8JáBjGµj¹='&$$Ò¬Y ¬­­Š”‰‰ 2™ r¹…x#A‰±µµÀݽ2åÊÙ“’’J•*5r¥±°°(=A}~Ÿ™o7¢¼{eFMšËÜ©#¾z‘~C¾2J7bÄW,Xð11qüòË*&O~lÑF¯7ð×_û9~ÜØý€Je‰½½=ááâD•@ðªaee…½}¹zÏŒŒtbcsïywppÀ`€øø¸§4JÅçŸûR½z•Rè¡ÊM1·PrdïVÂïßáfÐe–n:‚Oý¦'))oïš|øÂîg0$‡˜OЉ‰ *•ò±jÉJQPK ºu{‹ ˆ7H ”I||jå-œ¦ò²%¨¦¦rºti'ZL ”)ô2 yލåYчüÙþž²NyTrC¯S‹Ú¯ɦ™\—ÝEg0>FŸu/öîM‹'¨9NôªTñ@§‚*^=îkî£6ë_ÌõÈ¢ ªZ­áܹˢÁ+]uGÈã\QJJ*'NœËóš×_ 33E¶ š™™Ñ¢yKQ“à•'Ñ,•@íõ\áVÖÖùë¤L r†üe‰šòv¿$+‚NÍ¡ÊdrÌÌT/m5 :Ôêtñ>‚g"28’ u†± f¾ÿÞHPår9*ÕË{T§S AÏ„•Öœwí; Ó¯ò[T0/ž  Á«Ž©ÁOg][,'}ãÆ+“®šÇŽ+Þ ”ËÍ07·ÆÌÌ*ןV+G«ý÷4 ¿r™™Y‘ž^t¯ÉDpòäY"#£Kµ|ÅÔ¼¬Z—Êj¹‚—™L†V›‰ZšëïÖ­ \ì_$ƒ!Ïr©Õ©œ;w¶Èù$$$pèÐQöî=Pº½Û¼ÃÃÃùù矉ŠÊ¶"U£F F Àüùó àÝwßåý÷ßgéÒ¥œ>}Èv0lØ0œœœøùçŸyð Û•‰§§'£GÆÖÖ6Ï‚üúë¯:tÈÞÆ5tèPLLL˜7o¦¦¦h4*V¬ÈÈ‘#‰ŠŠbÑ¢EdddàêêJDD„øÿ"'Nœ&**ÛIfݺ>T«æÉùó—hÔ¨>AA7¨\Ù•JÉùó—ÈÊR-íÚµàìÙ }z„¿ÿ) Sœ$ÛÉùÙP..nnå2d Z­Ž]»ö˜>,,œèèØGÅs¥3ä·µµåÞ½{fwcMLP(Ìž=›®]»àää$¥ÏI‰³³3VVVtëÖ6mÚHbêêê*ÝcüøñØØØ0iÒ¤G¿`;èׯÉÉÉœ>}š:äYhîÝ»GZZÁÁÁ\¾,ŽÍ ÿ•+{бãhÚ²ežž•¤xµZMLLñÖ9bbb±³³•t§¤dff_$ [·îD©TÒªU3RSÓØ½ÛX|322¤é€b jÛ¶mINNfÿþýtíÚzö쉇‡{÷îà믿`äÈ‘lÛ¶ {{{ d/åäñúë¯ j«V­07¼¯«Glܸ¥RÉØ±c‰ŽŽ¦uëÖRšÆS®\9ZµjÅŠ+¸té^^^Ìš5K¼ÕÁ¿Ddd4Û·ÿ…ZmLÄÊÊ33ݺ½É”)ß#—Ë -05ª±aÃ\º”½>ci©â‹/<³ ¦¥¥³b…ééÈdн{vgðر¬_¿™ØØ8T*½z½OµjUعó/Μ9™™BÚ·oÿS¦|Ba*Íñæ‡,>>D2ügjj†µµëKÛ°:šää‡â ž¹\Á•+ÄÅåîUjµ:6| ;;ãÅ夤d#AU*•\»Œ³³#r¹œeËÖЧO/*Vt#%%kkëGùiÑh4(•J’“SÈÊÊ1•J…¥eîS›YYzNŸ>™g¹•J%74 2d sæÌ ==ãѨ:{Ú1==´´ìC@æææ’륄„D´Z-fff˜˜È°¶¶æêÕ \\œ155åûïdêÔ XYY½‡*^]t: >>5‹u­­M®°ÄÄD-Z@•*•qpÈöÇ”#¦Ù8SiQ9[Ô ö)gnnB›6E7ä$“™`ii‰¥¥±ªT*TªÜ‚moo—+,""’Å‹WàåU ó¢õPMLLQ*m_ÚA¯×‘‘‘(¾à_á)ÓZÒÒâD­‚WždE&‰²´ü{ò®z;,dfbÈ/¡–é8ªþ'ßøøÈå<]Ÿû7Õ&¥ƒT@ (%L;/jA žÂ±ž ØœæÒ¥ ”-V™¶m×\Ôœ@ ¿Eÿä¨dZUlH¯†˜›[`0è÷¡zÕôÆÖÎNÔ¦@ x¥¹|ñ< M*½j÷#== ®àáᎹ¹9..NèõznÉïàdí`tØØ/y`bá`m…‰9– %¶Jk\\Êce¥D¯×“d—„‰‰ñÎS±U Š€R©ÂÆ&ÛŒ‰‰ *•J²°U$AÍÌÈ@«ÍÛ“`Fz:«–-y¦fff¢Ñî©0>.ŽØ˜é/=ýñùÚeKæz(@ (mÊ•sD¯¬Wnn®’ À" ù¯\¾Dе@ú ü¿\qË–.¢Ë[]K\8­VËÿõÿ”!ÃGѤY‹Óþ²x$¢ÉIITpsc¤i8;»pôÐA:½ÙU´¸@ x.¨T–˜™åîz{{‘””‚••Eá‚Ú¤YsLMMY»j9Ÿ|ÖO²žKJRžžUs]óí´IL…µQùkIDATšöm…KINfÕò¥ÔðªU¤‡™8å$ÄÇã·zÚWŠk×±ßOŸ*U <7,,Tœ:uŽ´´T£pNOõê^Eë¡4|½1šõ¿®¥ï€Ïõ.5ètZÌ-,r¥VháââbyûÝ÷ð?v´È¤ÓjéÿYoªT­Ž³‹‹nkkGR¢°*žññ1T©RpÊW¾üc=*Ò¢”““3±1ѦY¾d!ƒørú¤?ƒø2oöÌ|ÓVö¬BµêÅó¹m"—³bÍz|ûdÁ¼9¢…A™£ÐjDx8Û¶nfèˆ1O„Ê@&Ã`0 “É4d8ƒøòË*¿R-¤N§C.—ãèäDZZªÑ¢”Á ÇÄD&ZR ”mA½|=»vðå„IFá.åËcg_ŽÁAÔ¬UÛ(®E«Ö…Þ4üAGäô©„ÞáÖÍtÿ 'VVy}3sfffR·^})nûÖ-t¿‡hI@P¶ÕÚÆ–ƒ‡ä÷aÏØ¹mK.Aý´ï€BoªT©¨ìY•ÊO,jå8êÊ‹ÿ2‚kW°°° Qã&RÜÛ·è?h°hI@P¶ÕµB…|ãÜ+VdȈÑ%ºi¹r´lݦÈéíË•Ë7ý—¾­(Ê⤔@ ¼hAýý·_Em Á³jjj*sg}Çö?ÿµ%%TFÍêåKéþAìíˉÚ‚’ªF£á§¹³éþAbo‚WÓ‚õÈ¡ƒÜ¹} €Ó'ý9uâšµh%jM Š#¨*•Š¿þ>&}<ÀWˆ©@ ”dÈÿ4^5k‰Ú‚’ôPŸfô¸ ¢¶Á+‰îî•óŒS*-12‹×C‚W %J¥)ææ2£¿ŒŒd®]»Z´!FFF¾.JÒÓÓXùŒ.Pž×®pèà~ñ‚çŽÁ@Ñ5ðÊ%~[»:ϸåKë<þ‹¤¶O]þظA´´@ x¡(¨›6§^ý¬Y¹Ì¨§*¹@©òØZÔý¯\&!!žÀ+—Ñ.ŽàëA¤¥¥'¥nTö¯'Oc挩¢…Á £ÐE©^äe } žpbþØÊŒ©©ßðuâã±/WŽóçÎÐoàÿÅñcG€ì“W¯7n†›»;ׯc¤©ÄÇŲfå2†Ž™™þÇ¢Óë8áœÁCG0vÄPÞ~§;‰‰ X[Ûþ KKKf}û?:v~d2ÒRSø´ï\+¸àææNDx¸ha@P6z¨988:S°2›*:b4ÂB:b4gNÀÚÆ†ê5¼¨^à ¥REÀå‹Tö¬Âÿ ÎßMgͪåŒ;ëGþ®«=J[½†þ„¸Òÿ·wçÁQTyÇ¿3If&“kÈ‘p$H!€ê*¢«…î® b¨ˆâ È*+.¢$$r(¬ܨÈU¸x r(·BÈÁ\Ì$sôLï:Œ“¢U øûTQ5ý^çMOwó«~¯ß‘˜DÆÃc)/+eÐ_þÆ·_Àw÷#3k"c³&Õj•+*„¸tjQa!«W|à?÷©®a ”óÉ›—ƒít ¶Ó5œ®©ÖÒM¦PÜnªWÅ`0°tÉBª*+±ö5 (Ï9Ë6™LÚ,¿¤Ô/›"„—D•ÿð¡ƒ|¼~MÀ$Î-Z4½ÊÍ·ø¿¨ Æf³iåuïq=…'Yºd!SgÌä”ÕÊ‹³f2nÂ$ŒF#v» NGYi µö†µ£ôú zöò©õÁòwF§Óa·Û‰ŽŽÑò&Œý»¯m%„碫¨8¡–””ñÈÄgXòŸw‰²X´ÌÒ’bÂÂ#ˆˆˆhäɵ€5«V9~G&9¥a}ê3ÛVk9G 9¥nE!ÔŠ×ë!&Ö·$kÁÉ|š7oÑdâ«/>GU½´Lh…Ûí&9¥ƒ_Ù‡kyE…>x©©x½^Z¶lEb»v€¯ÛÔÞ=»2ìr……¿Ú²×aÔÛyàû°Ûk9vì$ݺ¥áõúך«ªª).þ™´´ö¨ª÷ÜO¨ñW5½JB«ÖZ0=,Ïvf;.®9qqÍÏyð­Û´Õ>ßÔûæ€ü³Ë6™L´nÓ–¢Âzö Ü?­sWÒ:w•»BqéTù/e×v¿ŽN4…—S@Íyi6ù'Ž3ý¹ç±Xš·ÀwÞ\ÆaéçÌ;ðýþ€QVSgÌ$:&†)ÇáQ|Õ>1•– –QR\DîÜ9~y“Š];¿eÛ–MZZ³è¦ýsæyÏëõòþ»o1xèC~éûöîA¯×Ó¹Ë5Ì}ñ Næky×ߨ“~ñÏiOúýÍðŒÑtéz-¯[Cï[þ¤5¥ÔTW3cjüÏÏ~½^ÏNð+cðЇ¸¡çMr‡ q%TEQX0/›»îéOÛÄDæçÌeðÐa~Õó³y<äf³võÊ€€åt:Y›ÍÖÍ2,©˜ùo_0´Ûíäåæàõzxô‘±L{ö_„„„ðø¤GÈÍ[¬¼¹Ù¬Zñ>C†¥Ó61I+Ãår± 7EQ¸§ßúÞõgNæŸàÃ÷Þ ¢âgòæåðãÑ£Çg-/ãÕÜÊËJýê¾½{˜öÄFgާs—k8tðæÎËk8yÁÁ„„´ãxcÑk¸œ¾A Ÿ¬_ËÌÓøpí'Z@úÄd^x)GÛÿ±IYÌš“ÇãaÖœ¹Zú™žBˆKCaa1N§Ã/­¶¶®áÿj“ݦùÇ“Ú) ³9ŒoêÍöú~¡Yºd!·Ýq'í®nï—îv»YüÚ«ÜÝ-Z„Ù†ÙÆÏ§¬DDEלôDDDjfë¦ÜÓ ÜåÍçÖÛûÐ>Ùמª×ëµ2jíµ¸Ý.Ú&&b0`6‡áõzYºd£2ǰlÉ"LAˆÁð;ßX¼£ýÒ|¿ŸÏ?Û¦ fPU•u«W2i|&“³2ñx¼èt:Ìæ0ŒFo-}´.]éqý lÛº—ÛÅÝýø•;rt¦¶ÿŠ÷—k/μ^/Ùsf3i|&ósæ¢ÖnBüÿUWWRZZFy¹ÕïŸÍf'..ö«üj䨇MŸ—ýý"¥‰ùT³çÌÖº7u¹ÆWM^¿vè ßÀA,Ê›O¯Þ·hÕè_zvúS]¤Ö®Z‰×ëeýꕌõp£ÓVVüLÞüW7a2fs˜–¾g×·|ûõ2³&²võJ-½s×kiÞ"ž¼%ËPU•ÌŒá,X¼€â¢BŽ;JII ‰Ií¸­O_öîÙí÷×\Û½¾éa)í®nOÏ^½q¹œ„šÍ<˜>œ6mÙþÙ6Þ_þ6C.w²—§ÓABB|£yf³é÷¨MÙ¼q‡|˨lÙô)wÜé«’¯_³ŠƒîóÛÝš•èõzú¼WKÛ²éS-0íøòsÖ¯YÅ€ú¿Û¶e3·ßÑ7à{‡ KgȰtÆŒLgDÁ¾²¢‚ov|Å” ãQU•ov|É‘Cùn÷.¾úâsvïÚIaA>fsý"kâ£MþÎÖmÚ2ûåWX¿vßïßKbR»&›R–¿ý&É)´ ƒ‘Ù/¿"w­—¹&ªÑ` ®y Š HhÕš½{vѧ>|±ý¿øa?cÆžó >Ú´Mû\ó±_Î Âß|ý%÷ªmoúôzÝ|+aaaçýñíÚ'³ê£€¯ 8ëá R:¦’Ò1•ác|Oº«W\?âjõЏ÷¯÷û•QSSÃÎovЧï]tÂß{çM“’üº{¹\.6ú‰öD.„¸ÂjˆÁÀ¸ “yyö,Š xüéé~³K••sð¬‰U¾šËî];©ª¬`ÌÈtR:tdÒcþo¿;¦vÒ>{½^¢¢,Z»*@þ‰ãìß·—uõÕìV­Û0uÆsM–qæéîìãºñ¦^Lr öúQV#Gùãô'§P^^®_Ÿ¾wñÀß±N§kt™—¸¸8ôz_@íšÊ˜‘¾Z:`ÖœlÂÂÂ8eµjéS;1f\Û¶nfùÛorº¦šgž~œ   ,^ʱ#GØþÙ6ÞZöF}@7ÆŒ{Å£he$&%‘5é1¹;…¸D FÂÃ#•! /¥Î9RJ!þˆ)uÝuÝPUÿ—ŵµuTVÚˆ·œ¤”B(//Ááè@P. ½Y³8m[Ö”Bˆ PYY…¯±ÏGQNŸ¶ûí#U!.@mm-ŠÒ09Jqqi@€T!„¸n· »Ý¡=–””b4%  !ÄÅ8uª ½>„ãÇó‰ ÈnØÑÊ[Ë^Ç`4ÈYBü¡:p€ë»§hÛF£‰ˆˆ(~úéDD„¯•ÁÐ0RJWQqBu8lذY΢BÔëÑ£­[' ( 6[111Mîëñ¸ÕPåÔ !Äo ¾Y”l6»œ !„¨g2™ ùu]õƒêêêØ°a3ÍšŽ’ŠŽŽÃétj–UD…WŒšš*"#-”——¬àl0éÚ5 ‹%ò×T‹%Ф$ßäÑAAÁFâã¯Âf«aß¾ïéÑ£;^¯K®‚â²wàÀ!Z’œœŒÓ™BUU5v»—Ë @xx$±±q(ŠóâêQQÑ„‡‡jBU=x½œN'ªª¢ª¹BˆËžÃQ‡ÑhDUUôzˆŽŽ"22’ÚZVkéE—«T£ÑÄÕW' @À!„¸’눌 ÅbIáÇO\TZÇ~UUÙ¿n·"gVñ‡¤( GŽÆí¾¸æM- º\NÌæPvíÚCQQ 55§åì !þ<ùùìÞ½NGTTäE•І‹Íf£®®Ž‚‚",–(-rWWWÉ™B\öQQ¾ùL­ÖRª«k•˜˜èßÖlpæCXXññ­v(--£cÇ4E¥´´B®„â²g±ÄÒ¢EKjjìDEÅ`±Äúå 7_WQqBUUEñ\t!Bq¥ñõMýuIƒÁ·žRHH°¼ÙBˆßà>¢(ÄGYeIEND®B`‚snd-16.1/pix/tanh3.png0000644000076400007640000003323411147553271012671 0ustar bilbil‰PNG  IHDR,ªãrbKGDÿÿÿ ½§“ pHYs  šœtIME× hq IDATxÚíy\OÙÿøŸíû"e+»02Ö&[½5–±K„Ê2™¬…0> cÆ2&ƒ±eÂÈ"B“}lÉ2†h˜’’-Úß¿?úu¿ÞSŒLª7çùx¼uï=÷ž×=÷Ü×=çuÎëuTär¹@ PTE¡°@(,@ –@ …%娰~ûí7<<<^›æþýûÈd2¾ûî;222DÉ ÈÏÏgÆ ¬^½úµéŽ;†L&cÇŽäå剂( þ&‰~þùçUB£F"<<œ pþüyºuë&{öì{öìyíùC† ¡jÕª¥>%%…]»v½6““fff•¦À£¢¢8~üø+÷ïßssóJ#ï£G8|ø0æææôïßÿ­®“ÍèÒ¥ËkÓ}ûí·„‡‡3xð`>ûì3ªW¯.»wï¡¡¡¯=„ Òÿ`À€â-ÿÐZXÓ¦MûO™¨©©all\âï?þÀÃÃÇ—êš+V¬`øðáìÝ»÷•×>tèîî°§NŠŸŸß+å eäȑ̟?¿RÈ;{ölFŽIxx8ÆÆÆèëë¿õµtuu”ÉÛ ©©ùʲ;vìX±^À?ü Þð±…õO222ˆÇÂÂMMÍMollŒ‹‹KÉSU•U«V•*ÿÔÔT®_¿Î’%K077§J•*%¦ëÝ»7Ïž=ÃÓÓ“… bll\!…œ––Æ—_~IDDGÅÄĤÄt}úô!--Î;£¥¥ÅìÙ³+DÞŒŒ ¼½½ %$$CCC Ê<Ÿääd’““iРÁ¥¯[·.uëÖ-ñØ­[·8pà€x£E Ž9Âýû÷¹{÷®´Ý°aCnß¾-¥éÙ³'þþþÈårjÕªõN…Þ¶m}úô¡yóæ¯TVFFF4hЀþýû3zôhâãã+¤÷íÛÇíÛ·9tèÐ+•€¡¡!æææ=z”/^S!ò9r„óçÏŒ¹¹y™(«œœNœ8ÁåË—yúô©ÔJnذ!ùùùRºvíÚáïïOýúõÑÑÑo¨ ô-,¾øâ iÛÚښ͛7S»vm…îÃÖ­[éׯÍš5{§6•„„„RÙRš7oNvv6wïÞU°‰”'îîîT«VíÒ6jÔ==="##±°°¨y‡ F:uÊôš-Z´ E‹Ò¶ƒƒuëÖEUõÿ¾›³fÍâ—_~ÁÃÃCCCñ†¾!Ë—/'==?~,ýojjÊwß}€··7Ož<`Þ¼yeþŒ÷ìÙÉ'X¿~}‰Ç===ÉÊÊ’d644dóæÍœ;w€#F`ooÏÕ«WY³fôþN:µðò f÷îÝr@ùFé¯]»&Ÿ}:>¤Q£FãèèXfrèëë޳³ó+ÓŒ1‚ÜÜ\5j„¾¾>dçÎìÛ·zõêQ£F ¾úê+.^¼ˆ»»;¦¦¦4lذ°0V®\ùæ6¬Ê„¿¿?nnn¥>oèСìÞ½»Üå `øðáâÍÊ1Óýsâĉ{ôº¯VyOÂÍÌÌDOOO<8PX‚ÒÈ!CÊ5ÏÏ?ÿQø¡°*Ö­['žºàƒ¨ëE˜˜˜àìì\Ìëã¿Nä}S¾úê+‚ƒƒqwwGKKK!Ú¶m+í4hõë×çóÏ?—ö5iÒ„®]»*ŸÂÊÍÍECCã­ÏwvvþWW@™¸~ý:2™Œk×®ñàÁd2§OŸÆÅÅ…àà`d2ùùùôêÕ‹=z ¡¡L&ãÀ¸ºº–™éééÈd2öíÛ‡ªª*2™Lj©¯^½šsçÎ1pà@âââÉdœ={Z´hAË–-qvvfáÂ…ôèÑ Y·nŸ}ö–––´oßxË™îÅ€”j6ó7øøãÅ[%xg–Ä£GŠí»zõê;‘£h”°$^¶Ã>|ø°ØñÍ›7Ûçàà€ƒƒC±ýêâ‘¿;.\(üÙ‚2¤ÜVll¬Â0BB‚x ‚RsúôiæÎ+mGGG‹B «ì177çĉÒv```™ö¥ß74hÀƒÞØAø¿0vìX6lØ åbkk«P|||X´hÑ[OnݺEJJ µjÕ¢~ýúdffríÚ5´´´°¶¶–º„/^¼ U«Ve:…%))‰?þø( x`eeUb÷0""É&ÍåË—iذ!¦¦¦\¼xQἺuëbaaQ1FwUUU…ŸàÕL™2Ešåû®‘Ë娨¨(E¹¨¨¨(Ô!e‘û]pîÜ9±µµeäȑܽ{—¿þú‹I“&qøða…K£GæðáÃL™2…{÷î•©gÏžeîܹ}¤8pŒ7N:_(¬wDrr2ÿ¹ +¼Ž .Я_?|}}=z´4½ãåPÒÔªU …æ¯ 7ý6¨ªª*ôÔÓÓÃÔÔ€;wî`bbBvv6£FbÕªUƒ±±1¤¤¤Gvv6P8ò[´_(¬wÌÎ;éÖ­ÛGÞ†ªU«R¿~}ÜÜܸyó&¿ýöîîîìØ±ƒ &°aÃŒY¼x1PþzÆ ܼy“;v”™†††¬Y³†mÛ¶¡««K‡$ÆæÍ›3}útnܸÁo¿ý†L& }ïܹƒ““ÿý7uêÔaþüù4lØ¿þú‹ .°eË¡°Å9sæ 6¤fÍš¢0”KKK¶lÙÂõë×BÙV­Z‘ššÊرc¥–JsçÎåùóç|ñÅeÚÂhݺ5ÏŸ? C]±}ûvš5kF=æ\¾Ô²jÕªüôÓOR B555ÜÜÜŠÍ? KŽÂšššŠ8êJHóæÍiÞ¼¹Â>###† V,m¿~ýÞ™%æù&Ãuuuέ]»v‰×³6Ò –@  KP6|ôÑGÔ©S‡Q‚ñóó£iÓ¦Ò/44”¨¨(Z·nL&ã³Ï>“ÒöéÓ™LF›6m$¿¿²âäÉ“X[[#“É5jT‰iÚµk‡L&£eË–<{öŒ/^àåå…­­-666lܸ‘¼¼rìØ1Úµk‡ŸŸÖÖÖ\ºt UUUâââ¸zõ*^^^„„„ðÑG•‰ ¹¹¹;v ggg&OžŒµµ5·oßVX£ôÌ™3¨©©ÎàÁƒ %--ü‘èèhÎ;ǰaÃèÔ©iiihkkcii ¶—{ +??Ÿ¸¸8é÷Ïy%Mfff™,ÐúÑG¡©©)yŒ ”“¬¬,…zTÞË¡U6LLL¨Y³&®®®ØØØ(„ÞIHH`õêÕøùù)¸¥½œæ¿’‘‘!-Ö …Á+÷íÛ§fñâÅR¤(ô-,¢$CCCjÖ¬I—.]8p`Å´°ŒŒŒ˜4i’´ø¯‹M&«W¯žxS4lØP¡ÅÇÇsìØ±²,´´´8uêùùùìÞ½###¥‘ÝÑÑ‘_~ù…5kÖP«V-¼½½¥Jׯ_—Œ=Zذegúô餦¦™™©©©J#{ff&™™™ØÙÙabbBJJ yyyôíÛ—ÔÔTž>}ÊG}D|||Åt AÙÍW_}ÅÝ»wiÔ¨£GV*ùCBB8yò$›7ofúôé¬Y³†;wîðÕW_qúôi´´´X°`”^(,@‰‰Å××—¨¨(nÞ¼ÉêÕ«QUUeݺu››KÍš5ñññaÖ¬YÔ®]›ÜÜ\ Ê4j‰¾¾>K—.%??ŸÜÜ\>ùä¾øâ  0:ìºuëX¶lººº ù`ÌËË#??555)~×Å‹IOOgÚ´i¨©©b¦»@ ÔØÚÚ²}ûv–-[&uxøð!~~~ôìÙ“FѨQ#¬¬¬èÙ³'^^^e&‡ºº:¶¶¶Ì™3‡cǎѹsg)₎Ž4mÚ)ÿÖ­[Ó¥K¤ˆ AAAØÚÚƼyó8räýúõ“\}„”œaÆsc©[·®BÌû"ÞåªÞ:t(1ÏãÇKÿÿúë¯ÅŽÏš5KÁ÷°H—t-Ñ%|Gv…‡boo/ C (C„Âz¤§§“™™©SeBt ¤¦¦òðáCzôè! CɈ‰‰)¶Øƒ££#&&&ÒŠÊFFF’hÓ¦M$%%àææV¦ñÚ¢¢¢Ø¿¿Ô%:t¨Âñ}ûöñàÁ peç&Mš)y¾4kÖŒ¾}ûJéOž¡¦¦&ÍQ £S§N¨««£ªª*­<óòêκºº@á 6e½ˆ±ººº3¾(Ÿ—ÑÕÕEEEMMM444¨[·.ß|ó ÇçæÍ›T­Z''' ÐðåøóBa ïAAA„‡‡+ÜÆÆÆT­Zõ!”»ÂŠÅÅÅEÚ~úô©¨i‚Rsúôi¼½½¥í‡~ÐåáììÌîÝ»•RöO>ù„6mÚ°}ûv¶oßÎÈ‘#_™¶Üîæææ„‡‡K¿ùóç‹·ï_°²²âÁƒ ¡9>tìììêQY•ˆˆ,,,¤eµRRR8sæ ‡’öýþüyž={V¦rP8@]½ìT@NNŽ´ò³††F±–_jjªÔ500@KKK:–’’‚±±±BúŒŒ ´´´d®9“˜˜È˜1c0`C† ÁÅŅdzqãFlll7nmÚ´áòåË\½zkkkÆGûöíY³fM™É‘››Ë¼yóèÒ¥ cÆŒA&“qçÎéøÝ»wéÒ¥ îîîtëÖ9sæÍ_ýÅþýûfÝçää°ÿ~\\\Š-#Ö;`ß¾} 4H„àóÇðôéSصkjjj\¼x‘Õ«W³iÓ&~þùg<==YµjëÖ­ã‹/¾àçŸfÓ¦MÒZeAFF‡bëÖ­ìÛ·N:±gÏéxPPÖÖÖìÝ»Ž?NJJ ééé}šåË—KQ>ÿüs\]])((àüùóH•*U¸rå 'OžÄÁÁ“'O¢§§‡±±1'Ož¤iÓ¦ÄÄÄ!),äÌîÝ»å€<22ò•iìììÊ<ß=zÈ322ÞÉ=½ yœœäOž>ž¡°‚‘Å‹À£GÊôÚ9r„¼¼<…ÁEy._¾œ¬¬,Ž?Î¥K—çìÙ³$%%±~ýz pdPUUUZ™úåªEx@ÉÙ±c7n$..™LÆÂ… ©]»6#GŽ$!!gggúôéâE‹8p 2™ŒgÏž±qãF p”0 @:ùòå´mÛ¶T2²páBfÍšÅâÅ‹111‘±/_¾ÌæÍ›¹|ù2Ý»w'--¹sçòÉ'ŸàééɤI“ÐÑÑ¡qãÆ¸¸¸(ÄÆúõ×_¥ÑLàÃuÍY¼x±üðáÃJ㚣Œ×­HלS§NÉ;vì(|Y„kÎûÁ¬Y³X²d‰ø<¿§,Y²D"¼?”K—ðÁƒ¯\eöéÓ§¯=÷ùóç MD }yfvIáefΜÉÒ¥K™9s¦(0¡°Þœ ^â±ÀÀ@œ_yî€8~ü¸xRìììêÔœ9sX¸p¡Bš5jü§ÙÛʨÄíìì€Â¹L'Nœ 8ýì³Ï %==€O?ýTZŠK.—söìYlmmß:ÿ'OžpáÂÌÌÌèÔ©“Âñ .ðäÉlll¨U«>äÚµkÔ®]›¶mÛ’““Cpp0PKëåå¿„Ñ] PrBCC9räçΓô¬Y³¸víNNN¬\¹’%K– ¦¦ÆŒ3ðòòâÀ:tˆM›6qøðaBCC¹~ýº‚{Oixñâãǧ  ;;;¼¼¼Ø¸q£¤(Ož<ÉèÑ£3f ¿ÿþ;›7ofåÊ•Œ?SSS5jÄìٳٲe ÇŽãçŸÆÄÄ„_~ùEÁ]G(¬2&''GÁEB x×XYYall¬É722’]»vQ·n]5jÄÁƒQQQáÇÄÁÁ'''ie›–-[bjjÊõë×ßZ†ììl’““ ¤zõêèééqáÂIa]ºt ///&NœHbb"Æ #66===V­Z…šššDFFÆþýûÑÒÒÂÑÑQ!1«ŒqrrbïÞ½¢ åFÍš5±¶¶V˜¯túôiTUU áØ±clÚ´ €¦M›P§Ntuu°°°ÀÚÚú?ËaddD5PQQ¡qãÆÅŽ[ZZ¢¦¦FõêÕ©R¥ ¦¦¦T­ZMMM)&Û©S§hÔ¨™™™ ë …%¼Ç<}ú”Ë—/+mpÆõë×Ó¹sg…}¢K(¼§´iÓ†6mÚ¢E‹”JöÓ§OS­Z5&Nœ(ZXÁûÎùóç¹wïYYYüùçŸ@¡m Ãbgdd”ižIIIÄÄÄPPPÀ7¤ýE¶±›7o’ŸŸÏãÇ¥ ‚Ož>žììlîܹè—/_άY³ÐÕÕUXI´°%çìÙ³„……ñ÷ß³páBÉŽzæÌظq#¾¾¾¨««ãååÅÝ»w9|ø°´¬ý©S§8sæ ýõ .ÄÕÕ•úõë—JmmmÌÍÍ3f :tÀßߟ͛70iÒ$¾ýö[ÜÝÝIOOçêÕ«˜˜˜P»vmär9'N¤~ýú9r„-[¶Hs6.\Hnn..\àèÑ£Ba ïEF÷"Ãy•*UX°`gÏž ç¬Éd2 ÐÈ‘‘µµµ´B´¹¹9666ØØØ¼ÕDmmmmV¯^ÍÕ«WèÝ»·$¯¯/666òôéS:uêD«V­¨^½:~~~ÒRǧE‹lذAš+Я_?ÑÂÞ4hP¢a½GÅö•41´qãÆ%Žê•33³ó,R„mÚ´)vÌ …}ÿœpú2†%”¡°PX‚²ÇÜܜǗé5Ç'N('OŸ>åÖ­[ôéÓGa¿¿¿?U«V¥fÍš,Z´ˆÇcmmL&£qãÆøÖŒ3V¨•›J­°þüóO7nŒŠŠÊ;¹~Íš5‰‹‹µ@ P*u—pçÎ :T!Vµ@ (™uëÖ1a©ör€¾¶mÛâììÌÒ¥K%—™©S§R«V- ذaãÇëüoß¾-­pciiÉØ±cŽoÙ²…?þø€#FТE ~ÿýwi „Ö­[ãêêJFF†ÔÔÐÐPˆ–*4@ äìØ±™L†¿¿¿´ïøñã899áääD»ví8~ü8‹-bíÚµ899ñøñc ÆN···gÏž=o-CZZƒ "//¼½½¥~Û·ogÖ¬YôéÓ† BDDÆ ÃÀÀ™LÆ—_~IPPnnnDDDàääÄ‘#GðòòRŽ–²ñðáCÌÍÍQWÅ*(?FŒÁˆ#¤ }€¼ mµáááŒ3†š4iB@@€”~ܸqŒ=šîÝ»¿µ ùùùXZZJFý]»vqîÜ9éx‘«½½=öööDGG“––†½½½äo¸lÙ2ˆ—É={ö¬´™ha•1{÷î¥wïÞJéL,x?Ù·oNNNïÍý”{S 66–áÇKÛE“ׂÒpúôiéË …ÑÅ bÉ’%Ba½-æææœ8qBÚ ,“9 ‚ [[[…zäãã£tKY½k6lØ@ïÞ½©]»ö{sOÒ%TUUUø ¥EEEE¡½«©/ÊJbb"Ož<ÁÊÊJa@@Ph”/Ó<£¢¢¸xñ"ùùù ?úé'öìÙCNN—/_––ôº~ý:7oÞäùóçR@Á/^°ÿ~y+¬…%Ê–Ý»w³}ûvnݺEïÞ½™3gÆÆÆ<~ü˜V­ZIé¼¼¼pppàòåËܾ}›Y³f°uëVöìÙÃõë×éÝ»7‹-R8ïMÐÓÓcÈ!¸¹¹Q·n]âãã¥ëoذœéÛ·/±±± 0+++:vìȰaèZµ*½zõÂÂÂwww6mÚÄ•+WBã…%(9ƒ RX KKK UUUV®\©®yóæÜ¸q¹\€ŽŽÆ cÈ!Rº· †¨¡¡3fÌ u]'$$ÂÃÃÉÏÏ—dTWWÇ××Wr¶VWWGKK‹Úµksÿþ}e(–@ðž ¡¡¡môeÅõOJŠð«©©Y&±²ÔÔÔ”KEб$E¨®®^lŠŠJ‰×1­A©077ÇÒÒ’°°°2¹Þ±cÇhÛ¶-¦¦¦¢pJPXJ„¾¾>&&&U(¬²ÇÜÜ\¡%ˆ³³³xåÌóçÏ144TZùíììêÑœ9sX¸p¡x°ï9†¥„Œ;–õë׋‚…UHHH Zµjå–ŸŸŸãÆSš‡Ö©S'Ξ=+jo0fÌž?. âCé¾ ®®®åjÀ®V­ o}þ‰'Äœ±„øøx1š(–r³dÉ>, B ø»„‚géҥ̜9ó­Î)¬àà`BBB066.÷¼õõõ144äñãÇo|NRR÷îÝ«²²°° GlÙ²¥Tç­^½ªV­*j)‰ÇÔÔô?NÁÁÁ¬\¹RÜû¨°^¼xÁöíÛqww§I“&åž:uhذ!&L 55õι~ý:?¦Q£FVnxã)±±±¤¦¦bee%j~9ÕgA)¬7 rWPPðÖÁð^¼xA||¼‚Ÿayãàà@vv6)))¯½¹\Nnn.^^^ØÙÙQ¯^½ ‘·{÷îèèèàììüÚ²—Ëå0hÐ ÒÒÒhܸq…È[$Ç»¬GÛ·ogèСhiiUX]ÊÎÎ&..ޤ¤$nß¾ý¯é}||DÔÛ7àŒAAA8p€mÛ¶½2Í•+W˜>}:;wÆËË‹*Uª”J¯¿þºÂ£Ô¨Qƒ£GÒ¿²³³™={v‰é6nÜÈüA×®]™?~…ÉkffÆþýûqss£eË–tîÜ''§bé~úé'.]ºDûöíY¶lY…Èš——Ç–-[صkcÆŒÁÕÕµÄt{÷îeíÚµ <˜Ñ£G£©©Yª|ÂÂÂgðàÁ¨ªªCXXØ+Ó'''Kÿ_¾|ùµ±òïß¿O“&MÈÈÈxí5²²²èܹ3999üöÛoÿÚ NJJ¢]»vlÚ´éƒR@5kÖ,UJEþŸ2=zôZ…%“ÉgÁ‚tìØ‘nݺIÇ^9wãÆ öîÝ‹§§'Õ«W¯…˜œœÌòåË_›fôèÑÔ©S§Ò<ø?þøƒ]»v½òøÈ‘#ÿs×µnݺŒ9ò­ÎMIIaäÈ‘þøctuuÿ5}}}…×ËtéÒŸWžÛ£G‚ƒƒßÉ´nݺúÁ_÷MQU-Û1š˜˜bcc±±±AEEåºì5jÔxeW044´\¢¾–çs˜4i|ôÑGï<¯ß~ûððð×¾e…««++V¬‚¼i×_Aa©¨¨”h¨Ü½{7·nÝ"22’-ZpòäI̵k×hÕª•Ô¤õõõE.—S·nÝR½¯3Ž ëU÷û¡]·<ÐÒÒ¢E‹øúúbooÚ,X@^^žô|»t邯¯/M›6EOO¯Tyhjj–Kù”çsPUU-·ûÒÐÐ@MM­\òzÛûz#£{Û¶m±²²’šl:uâàÁƒÔ¯__JãááÁ¡C‡hܸ1–––/£££Ãĉ¹té’Ô ruuÅÚÚZ¡å6uêTÂÃñ¶¶F___œ ô «{÷î Û5kÖ¤_¿~ž:ÿÜWÙ ò–#5jÔP¨#Mš4)6BdddTé둲?‡Wagg÷J¡R)¬÷eû‚‹‡xïT¨«Wz·-­A ( o4«"yöì™Òù½)£ÌÊNZZZZZ¥žhZÙIMMEOOï½sXONNÆÈȨÔ#Ï•^a A¥êîØ±CaÂjI>|˜Q£F)Ì0^¼x±x‚oȲeËøúë¯_›fëÖ­xyyÀ¨Q£¤_TTT¥¹ooïIõ&÷+(ëÖ­cÔ¨QlÞ¼YÚ÷ûï¿3jÔ(bbb¤}ß|ó ßÿ½´ŨQ£ˆŒŒ|嵓’’5j§NªÜ ëðáÃ<{öŒqãÆ1vìØÓ\½z•sçÎáããÃçŸÀܹs+ÝB éééÅ\6*ÃB±k×®¥víÚ´k×î•k÷‘™™ÉÈ‘#™8q"={öÄÇLJ3f ££óZ»òÄÇLJnݺallüÊÐ:or¿Ebb¢R.„±±1>>>äää°oß>ÉåÎÇLJɓ'…ë´mÛ–úõëK•éÓ§ãããÃ’%K^éz4vìX|||8pàÀk?Žª•á%×ÐРN:0yòdöïßϺuëøöÛoؼy3ùùùRšyóæ±yóf¥xìû÷ïÇÃÃü±ÒÝ“\.§^½zdffòàÁñÿ#ûöícàÀøøøðâÅ Ö¬YCTTÒzgÏžÅÃÃoooé¼ àáᇇQQQ¬^½Z:öÃ?…=<<Ø·oŸ´ÿôéÓxxxHŠ# 6nܨpî?ÿßÿ=Ÿ|ò ;wþ0mXšššäçç“’’‚P8z̘1RuuuTUUIJJ’Ò¤§§K¾20~üx:vìHïÞ½qvv ý _nq?~œ‚‚bccùòË/ #"" ð÷÷'²éèè••Eff¦äûikkË‚ ¤4ZZZäåå‘ššŠ¾¾>?þø#ׯ_gèÐ¡äææJ_ЊFOOôôtrrrÐÖÖ&++‹æÍ›³aÆ×ÞoEsåÊüýý™2e ÕªU£}ûö3gÎ<==Ù¶m×®]cûöí¸¸¸Ð¾}{¾ùæ,X@»víðôô$##ƒ¸¸8ß°aÃ444pqq!**ŠÓ§O³bÅ Ž=Ч§'žžž|ø0Õ«W§_¿~RPÉ"û]LL )))èèè`eeE•*UÈÊÊ¢C‡\¸pCCÃB{êÔ)þþûoüüüðóócâĉtíÚ•±cÇâîŸP×næÌ™èèèHõyÅŠ¸»»3gÎôõõ166ÆÒÒRA1E?~ükãc‰i eÈåË— ¢J•*LŸ>;v0{öl|}}qvvF&“áééIbb"lݺ•íÛ·“žžŽ¥¥%ãÇ…ø3oÞ<ìííùôÓOèÓ§»wï–z ÉÉɬ^½š””ÉÀÊñãÇÉËË#,,Œ5kÖpêÔ)133#88˜ï¿ÿž_~ù…ììld2 1Çd2~~~ìÞ½›ŒŒ ttt4hVVVøúú’››Ë˜1c¨U«V¥/C¡°Ê˜¨¨(²³³±²²âÁƒ$%%ajjJ½zõ¸sçÕªU#//¤¤$š6mÊßÿM||<†††ºXP>ÄÆÆbhh()¨{÷îÑ A…–ÆÓ§Oyøð!ššš´hÑ( \˜••ÅòåË™:u*–––Ü»w&MšKÓ¦M¹{÷.ÏŸ?§zõêÔ®]›;wîдiSéÿ¿þú‹ÄÄDªT©BÆ INNföìÙÌ›7š5k*E …%( ëׯ§K—.e eúô镦Ë,–@ xïÓÒðÿXðº˜å)ʘIEND®B`‚snd-16.1/pix/fmeq14.png0000644000076400007640000000074711147553267012761 0ustar bilbil‰PNG  IHDR€7ô3PLTEÿÿÿààà€€€   PPPppp ÀÀÀ@@@```ÐÐÐððð°°°000³¹oJ pHYs  šœtIME×#7/@iGIDAT8Ë¥•[và D2Å< Ýÿj b‰Òò'™sg,K2Àò„ql¨îÓô”Ý+­52™Ž÷¥ZúUc ½Í.ä$HàÃ0r&‘â±òÏÏà˜Î¡˜_ÿüÅ‹åè³(æSUÏùÒ›‡ Ü@«“ßÚ¹.Fö‹9@Õ#½ÚÄ@£ã϶ʆ¬•+Bõ³è”Ìzb ‚½æµ­µÉ`H7÷ê¦vˆJSI‰–Z þA'øPaÏ„ë´fpˆS ´ùí÷V>"F;Î~†Aß ü]¦…NYŸßz?*W%Ït°ÓÝ`ìö\ÍÒÊhÇüÖfM½Êñƒ)@sœôÝ`ì¶Ó2íóëÚZ îaotƒ±Þ‚ûüf»µ Åd¢~ì…=ðŸßïôÛàÿ¿ 7Á¿x– :zÕïCIEND®B`‚snd-16.1/pix/envany.png0000644000076400007640000000541511147553266013160 0ustar bilbil‰PNG  IHDR$G™1sRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØú3©÷ IDATxÚíÝár›º€Q“áý_Yç3Ôl K°%­5Ó¹÷¤®K‘øœÄYRJéÀŸS€ ‚P3H˲¼J_úgAj£”Ò+¥$J@–5÷­ÂRòœ3|…Âv>|5†ñ¤ä ÌŒ+¬m…ɘ12¾?nÙ¸ÿîi«;ö8Ó H^¸†²›N… m'/÷$nËRKÓk«#“vܱ¥B¶²¿ŸÔ£åüyç\”Œ­ áб$ÜI牑±¤.ï &.‚4ߪ¹ÙRw“ÖÄw\¤n‰Ò˜12®‚Ôí]ÔäE°¤§é¸ºÑ’­¡n2ÆUº]™¼V¼‚„•ÆTÜI1¦‚„;*·Çhæ1¤de$HX)‰‘ñ$Ø$F°´çÖñœñ#H¶n¾¹Ì6ž‚4àêH”¬t +%12–‚d›ÈVF‚D“X”Œ£ aû&FÆQLdQ²M$º˜È¢d é„xÿ… -FsŒáõdM“¹Þ9Þbo[b›f…d2»Ë?ã'HœMêôÿw÷¸21J‚4ùR?¥4åji?n¶i‚$Fî¶ÆÍ¸ ónázߢÍ%Ar—b g‹&Hbä®k¼Œ— ™Ü¶pûãžeU4B”IŒŠ¶p½|‘ê¬_èØ{”‰aÂô¢Y_+ê9J«KÍêè×mÜÓçdáyÁºóë,u0‚OO|1Š!oÞ ’UCËóu×ß#J‚Qh\G­ç1ýÌcA£G#õó?×|ö¢¶ݹ|þü÷ðX>í/FLvSˆüå‚$Fˆ’ ‰ˆ’ ‰„ÒôA#D)N”¦ ÒÌ߀ GQЦ)ƒä0áß(EY-M$«"ˆ»…›&H¶h 7üWjûŽpø=Jw];C¯¼V¿…éîmÜp+$oOõÃô¾…ku] $[3h¿k½•ë6HGKH!‚ûâtôÂ÷¯×àãï‡ôËÞT€ ö"¡ô:õm@¾¹$A @A$@ $A @A$@ @A$@ $A @A$@ ˜Í퀖e1* H1¤”D lÙ @A$@ $A @A$@ $A @ $A @A$@ ¤eY^¥/ý3€ 5‰QJé•R% ËšûÀVa)yNaƒþ¤”®éè‚/y²V+D0á ©u|îªì•Ušçóù›çŸ¿Ä_¿Ð ¨¡øEíÜøl¯9µ.00è–íÊ–éSl„¸uË6‚ÞÃéøû(Ç/H€ Ö’¼ò X! H_öŽ…_ñýÄWˆûŠô1ÎCîñ_ýwF9?gÇQúñÚ×äö¸ý¯PA*}«’'ÞÚÄWœŸŸ‡7‡Ö‘¸2ŽWæ×Ùó?©³ã/ýx‹kx{ìöË–ªŸ¼€Zeÿ•rËÖÛªÀy˜ãøKV GÏ¿ÿóOœ¿;WI%Ç´ÿnË6Rå÷“ïèã%wÊ'žÿŽósöÚgÇSúñH+˜}„r.öÒãm¶F¿à£n Þïvûÿ>ûÿ¹¯‰ì'ð¯Ïåø[låŽ.Ìýÿž=þè8¿=äíìl+í£køÓX­Q­$>¥¿ëõ+“®4V5ÿͭ尿?Ë0¦äš|_)î¿F°èomRž³»~î ¦ö…zç;¶Ü Õzþh»ò¾^®á³{ ©°þOL†ÜO£þò†x%G¯+¥£ãÿvÞZ™À¯ãxõøkü{§{ ©§H•Lž+ÛÒÜ`´<þoA8{÷,ŸÂòí…à+ç§—íÔ•ÏŽÂ7×þ°Mˆ|l=¿qþç*÷“wŸÒq¼rüQWG‚4`0G¼kÎvÞJg¤q$ /j‚ H€  H‚€ ‚ H€ ½^×Þ0ÊOYªéêϧºóg§}Ë~ƒ¶Va)yÎߘ`öÿÈŒmà µRú~/#NÖÜsù§°`l‡’ÉZn“ר RÆ ¸8î9W&ï8!ú6¶3Žkñ‹Ú¥?áÁ¡nîí£ni{ךc;ë¸vñ¶½¯Z¿•’qn…DÜIu´£í˜Þ=®‚DWw8[¸~·h¢$HÃn3Eɘ ¡öþ¢dL‰W”Œ© j⊒1$B¥qb4Ø Òà“7ê1 M££ã¤ÿ1u•$H“ÄÈÖ͘ &°SA2yEiŽñ M8yEÉx &1ÆSÜM1ž‚dòº«Oã)HˆÒ¼+£ÞÇS,í§Œ’mš !JKArGÅX ’ ìÎj,¥ !JVF}Ž¥ ™ÄSDÉ6M%12Ž‚d"‹}Z£F@Œ0Žõn,½üXû¿ˆ'ïýVIb4Ç8Ú²™ÈCFÉöI.JbÔï ’É<Ô„6~VHb$JÆÏø &µ%A2¡»ŸÔÆÎ–MŒ%c7Ö*Ièvb‹ÑxQš>H&uŸÛ¸Ù²Aˆ(‰Ñ¸«¤©ƒdb·›Ü-&øþy™’‘¥wÝýx³qWI¶l„^-YÍ¥uÆ“o‚?¥oçýý¢0N]›©ƒÑ®1Š1–¹1c®›õjxbÕDÜñyòÍܦz Éêb›&Hbe«Ø'^àž"Hb}Diø ‰ô%_‡„1t¬Ž ¯UÒ°A#è/JCIŒ Ï( $1‚~£4TÄúŽÒ0A#è?JÝÉÛSÀ³Qª¦n¿¹¶äí,€{¢ôëµØ]„Æ Óãï‡te¹'DÐÇ¢¡ôzî Ú€¸|/ H‚€ ‚ H€  H‚€ ‚ H€ € ‚ H€  H‚€ ‚ H€ 0›5Ú-ËbT@bH)‰ز€ ‚ H€  H‚€ ‚ H€  H‚€  H‚€ ‚ H€  H˲¼J_úgAj£”Ò+¥$J@–5÷­ÂRòœÂýI)] ÒÑ_òd­Vˆ`ÂRëøÜUÙ+«4Ï?æó;7Ï?‰¿¡ PCñ‹Ú¹ñÙ^sj]``Ð-Û•-Ó§Øpë–m½‡Óñ;öQŽ_A$ ¬%yå°B$ ¨5Êl_p™»ƒ,}ý^É»G=þìùÏŽƒXÖè½§»¬UÓ¿ÿ}ö.£G¯7œ=ÏÙ  Ÿþ^¯1ƾ†?Iˆ í'^Îä)}<÷]îø}š¼¹[¾³UŽ9û~¿Ñì¿Fú•L,“.Þk¿®FZ¾>µ_UY5= û,Uï‚G«”š?âÊO¹©¹õä>ËFÕH½¿V{±zž_%“o®eúÕ„H Àÿx $€wÿ´…‘Âܬ,IEND®B`‚snd-16.1/pix/sum5.png0000644000076400007640000002307111147553271012543 0ustar bilbil‰PNG  IHDRJÓ¿[ãûsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEظ)¿ IDATxÚíkrÛ<EÉ”WeMÖš¤5Yß–8?&t $ñFwãœ*×Ìd™"úq/‚ë¶mÛßüâ`”0J%Œ@=>¬|‘u]—eYñ«w/¯à^P+R f”ÕTê(F $èU"®ëŠ9 ‘Gç¿[3¨éú í5`l¬¼G‰Àéc¸ï˜£Ò|Ç0äë(´F £¤è¾!z줹Míêk^ýC÷b”e÷Œ1 S;úÕ<êg[8õŽ$­ö™ûg¥>à 2kC¯ÆëÖê ¿Ð^%0e’HXýuaä̤k̨`V0J0¡IÂ,è7H£8õ¬k0ê&F &5I$-€Îš i†“úh0ê¦:£´Ï<º?%Ã~t›M›¦зÞR7Œ]ì©wëºøèÏS>+ç3´5ýYEã ³hÉKjX¨»=ku³¿$˶m¸_£ Ãì€ÌZ ¥RCÀBÝãF©ÖjÌc’:rê€æFj Á¨™#ø(ü^Ï@èjÔ-ÿnø˜  fŠ5J½ozÌïÂLÉH$,& €ú šø•3ð :”^L-MšÔ_j¦)£„I"Ik%-´Ë}Ë3™4~g”RMÒÑ;’B'ÜaÀæ5rP?¯4j‡Y«u˜z©ŸœÁ?„”AÓö.’´nÒò¼À\y ®·nFº*"A×}`¼êæÒŒùDjõ²%¿¸0–‚ê6¾›u0J`r¶‘0O¾SG€šL­ÔÆ·@_3Æ$´…%câI›pb† /Ï1IÔ@ƒQ+1J4b¶Ú`”`.Å Ày~c’¨#€£Vb” Ѐ1IÀ(A¦BàÛ@Fsa”L6^L0JPQ pô›¤=0I:ê5`”@p’€þ\¦éÖƒIê$F H\&i}L€®º % I A“Çí`Ò€:‰Q@±AÂ$QK£…–+@_î’¿h°ÑЋ0J 8q™ +• j €tï|p t2b @Wã!gÐ`  V”@,̃æfÊ6;j 5R7¬(T4H~ã;õÚ>¬(‘¤¢a–´ä&+HÔÀ( ŒÀdFI½ s™äkŽ0HÔ@ƒmxF ¡QÒ,À"Û¶}OÒç0J@òD›# ÀÜ:0J X¬‘¤ý ygOì0é9ýæƒg”@•À¡hAËfȳG€ÖBkí°¢Ó$¿A€}!ÀªÄöêļ°¢D’ª8¾¸ÈÍ-V£˜#¶×Á_˜t >^ÁÖ;á¢Î Xø—À$/ääùh0ˆ…%0!~Žb„Õ#8‚YS8Õ›åÒÄ, ¡ìÙŒ×Éýºu¼?Ï‹q{üùckwotÀh©3îÁ+Hψ1ýL¼Þ[aœ¼ߟ{Âõ‡jCaÜ1kl0'Zóº¸æ±$¢6ŒÐ_-sâVs™}býïoý- W`”µ„ïãî[¤ ¨UÐûuPÈbþþE!=æµLΨïsý_?ûñ÷Šq)çg¢/ô÷ ÍNló¬Ñ ÏDOŒÈÙÿýg¤Hˆ©‰˜%91Â8ÅÆSBÜAåÚPÑ@u­ g1Š'ÿï‡ Ôg:þ}~wê%ŒRÕïã&PN1.ý÷~‚¿Ê ÓÛgù0P×ggAœj~¬Š®”¸ñïÙ׉±*¸_¢ ’ßÄbE]È´ÜÄ#3õÊ0%³¾GqIþ﹈YŒ’МhýY­ûd;‹9zlíGÂïi^®âø(vŽêñýÀ8Æ]ô}8›tSn 0JZ¿ÏžD5Šoj1÷üU¹ÈÅ4¿°šYŠ5A3 ©ÚMßá‚û/&÷ÏŒ~ ó‘òù#ÍSm”wg¿ÿà³0JrBÚç׬w¦~æ¨ÂïoZ®bÖ•P­í• SÑýH½~ŒF©ø»´,¸Wæë¾þK¼Úæ(³¨|߫ψÂ{%ÆIù±ÑC@xãçþ¯mäÆŠ5¿a¼¶¶¿o¤ùªÔKãν® ÄYRdZþ¾‘=s4æºzlëO1HŸŒEÈ0ÝlCThœ0Jš¾K"ú®A%Îö¤1Kßÿ3ÔÕÈt‡Ûìzá«Æ×º!H0L'b£ÈÖŽ»#±æÄFÉ@L–þþž=Öºa:« Â\õZp¢_Þbâ³aŸ(X]jZkM b”æ3Joߣwa}ž;)ÆBMÐÙ»ÿéÛª‚–"­Á$õjæ¿/;ÏÏLÔV0[÷YÑ´jÂDPÊ}iwþµc–ôÆaÍkXï0Hý¯½ê³ÏgÆ}¯‰ÏNÚÎ7L’ÌÒQŸbœ0JҿLjbêŸ.5²¯'§€}F 3b½fòkäÓÙýêw÷Ÿ[]Ö?Ký›Å I1I9×5ºÞY0KFzmÒvþT³î×¾^&É¿® ³4Dc»÷k aÂ(Iþ½‹è=´§µc"‰ÖÁz9þûwÃ,éhÞYþ®ù}eÐ¥nh5«ßJ¹÷q„hp¿fIN¼õ¼ÆÑõN»Y26ù¦%rtƒoÐC½bôöË ³4Tcî·%LRØ ¹¥öµÔÜå4Á[tóMûµÊ­nãsßiô_fÌj¯½r¦åýÄïÙýµ˜¤q×*¥Þi4KûiPG¦|Ï=ÎüwßZ5·d–š&Œ’ÄïðÕq¦Á19k|¹É²JTØ×{¤ÀÁ0©hÖoù0êšBïµõïQ"¶×*¬w#gÝg¾Þ}cÁ$…&<>7yæD“Y2ºCãTG^é¿W¼6cœq’ÝikFIªQjH~ÒÇ4¾˜„ ÇNo¶Ž6JÆ‹½ö&ýc«Ý¨ks_J–bžrŸé9‘p5¶ƒö¨‹0é̆ÖïÐsK¹%³dx’1ZC†tCL¯<¶‘×&Vg7ž\Ã(Íl’öDO™ŒyIè6nö?Û,Íl˜š¤!Gã»E÷^Y Žš@HÍïž“)cÚÙ0½Õã'“)Éq¤¡Þ½„~©‚ÚøÄb’†¼ŽÜ–z`È,f©a¯À(Ítý!SÒüv±·o ü³ˆ{>ãû>>–¼YôÙ‘“ÔëZ÷[Û$ŧ–æé*Ï{OäŽeÇmy˜%Ã&é¶ÉþN’Dõ$“‰ÑÌ﯈û¢e[eËWt(6L¥Y®ÿl¹ø¨QœÍ‚ Nüb³4‹aÒd’Z]¯/¼{˜¤óÔâÍðŸÛØI‚ZãØx•éÇ3£Ï‰jƒu“¤á»I¨Ï“L FõŸÛîWºAÛA׫NkWè%ë×~¶Šä6ˆÔn-F)§ βº$d “⿥Ȗ&šZ'÷;Ž˜hmv+¦à)¤³™%Ë& ³”¦f5J~}I™pÒzô»5³TØ'0J²ÙÈg«H÷S$\hc–&1I5®ý¨Xj„µŒÓÓyFãaè›-ö¦Ïl–f0I˜¥ùz_lÊ™Lsïö÷c\¿ê\}£$ ›%¿Ø­ë¿c+ï"K‰Yz‹‡Ü&huVM³IÊýgÅQ« Ì5NwçÔ¯žß¹WÜÕÜ›îǨo–¬ J+&)%î0K˜¤³ú÷õßûà4Ÿ˜yr艅S¦SúFÉšIºÞtÿÝÐ5ËfÉZó°`’R¾ËU1´$cŒSì{Ó,Ä]%Ãth–n›Ma9£I’þÝ{äϤ}ç÷ïå¸^¤Æ…;¡òÀ,i7L%KFéîÍvn· 4K?bbv³dÉ$¹ßéê³4óK×oë²þ·œ÷£“dɈÌ’9£äö óFé÷Òõ î]MÒÑÖš³bg}{MŽÈ)½'›‹E“ä·O÷Ï0I—±êÖ“ÜCO´Õ„ÌÕ¥(³¤YxZˉqgÝ,Íj’œpj”j˜$+÷Û5JËfÉã—ÙD¸­6Š÷ºþûÙ‘û#Å$¹ß뵚Nšï{}Wò=-›$× =ÿŠ_LR\c~«#Îýq뱉“·ø(í¡z§­6`’NêJàu³Ôë&éªO Âµî¶ØÍ‰3ýbvë]æ6‹ž<(cO²ºZÎÙü„ ¤&«JššÍà­OÍLÒ-ppÉ “T´Õãèõ†^pCW'Å®*iª ˜$÷(÷{Îú“”kÉ«JR…*[îlÜ·˜ï=“IŠìÕ¶ã׈;å‡CÍp Ã¯e&Jf Ó•âÿ\“ôwFv “$ŒÃU%÷ž•®,i~XSªIÊœ)/Z4Ú”œ­†×:BBŸˆéW³û’j&É1¸ˆ»MR¯>Q+î4ê'îNµFI¹aJi‚©æhwvu›lÆ!¦ˆK¢ÖÖ Eo p¨n’rŸw˜¤>9áÆ]Ì=…†éTh0KL¨Éè=úì,&ÉŸL둵{¬•IV£§áÍi”š`‘1 ß]CÅ;ÉÍOYºœù°`–,˜¤=KŽpÝß÷p3lz¡ØœÅÝÕ³MZ{…ÖÚ`Ñ$¨wÒ ïU¤¤È^ìSrB›Yšåu0S¥Ü&xõ^£‹-&ÝB÷P~äñD ¥¶èU6£U_© ´Jlmè% cÅjÊR{EZ7¢6`’l›%?îzÕ†‘&)Ñ Uë-ãN©YÚþîžZï6û/FÉo‚¡Õ¥ÔU£ÒDŠ bE¶o¾ª4¢è XMªb^•޶¶hÐGÍ׆ZW›^Û{ ¹elÁ›x"ÅÒÌÒþ.¹OÃ÷¼ÖdZ®~êÑc-Ôcf £ä›%ß0µØR7£Išñy¥žEOë–»šoJå„%³$q;M­¸Ó¼EïÌ,I¨ ¬&Ù7KÖ w¥É´ï^õXdç„&³äç ô­©¥"µ÷ïç?g¶â÷’fŽN ø¥ ´¾’$D´FÒ¢yeIƒIª938LÒQNܾ·É¯Í«°w³ýˆçP?ˆ© -ê&i®Ú`q½ædZ¨žI;MïZºmÿ¶ß­«9³4×{”BæÈoÐGI#è.éôS„ææ'¤ÉEÇKí{ÝBðº§Y9×ê]fWã¤Y\I}ÏméOcjö¨øÅvJÜ|=Dç½>Š f²A¯ÈžØ}?5ÎñZ—õÏò~Ô ¹V”rN©«q:^Í$ÐxšV•Üû\kf¤öê’F“T{f0&'´Î´JlŸÛ“ª×’VšJOÇ«Y0Iýs¢fŸ°"žs Rƒ^¡úŨv¥Üxᬠsä7Ú¤-uM0·€Ïd’´‹Ö™Š^͆Ór›åM4¡‘[+›¦ÃÉ·O|.iµ®FmÀ$Ù7KWµAkm5™f!îè†5ÑÈ<›F©å»B«K‰—3š$ÉIݳÖ(z¶W´l|©9¡I#W•Z ÃÇöïèùÛ ‡_G¾-½‡IêwšLR‰p°l–ŒÓææOê¼·û~±ÏÏ ^Lkc¡WmhUï„N¦™xw’B³”}ÈM¬9òQÃqÆ(õBG³†¬&‰1K"Åê³OÑ{3I£·Ùõ̉q7‹IšÍ,¹¦é¨©çˆ…˜>ñ0f–¬¯&å„öUæ‘“i½lÚ¸“VrW•:­ÆÒfÄngšP³€»ÁøHØ{[—å¾`’„-1‡p¸÷¢C3ýþÞ¿—qiÔÄA«¸ Ô†©rp²I `íðE[襌·‚>aa;çL[îöœx-ãjCû}[{!½"º‡[»µ!8G÷{Ç{àƒÛV”jš$ç¹’è$݃ⱰïjæA:µgÐý¸kû Ó,+K¹ß3F ;1„IªsO¶™[žâU¥×Åý ¤êRÍû,&)¶6ŒÎ‰}<>¹Zãj'NLÞqXMšn¸2F>[â.«³ñÒ'0J©&éQ¤5}VÃ4ƒQ*ýŽG1ˆ1§IÌ1c¢ýy¤Q¹eÜ,eçØsýÿih)c⠖ߞؕ£³™¤Øû.Å,I—ˆ{ƒIê£g¯:È­‡ÂÍ[ï*š¤.pÖ¬oÁ«QÀýåôƒ­˜¤Šq‡IÊÇø6¼¬šñ\óê’ÞËÿö:ðåÅ+È #sBúö~¶Üµãꇣít½ŽîÐ'XQº‰Å.x­’|ÆÕ%‹+Kµ¿ÓÉVL’° ”‰sé-XU œnWi|Öõ}…éÏ26ng˜Õ¯õsë¼iiã“p/²W-à=nŸÞŸWÐ Å«}5+JGåºk‰&i/l³ø õe´=fFöøZ‚kb’ !LR8&ŒQ´]«ÖíÇþ¿œ#È÷vg‰1IrjC¯^áëi=“Ô‡ïWìñ·T_5º¬…Wq7pe‰¥#“”Qè~\CoA8Ë “æU%?.j|—³qÿËësÁ$ÕŠ»ç¢ÿýHŠgMö¦³ïßb¬nλLžæ “”gjN Ô΋0z¼¿ûaža’ÂÆè,çMV9º}@¯À(U2I?®adãŸÁ0Y0K©lgŽó÷µ~øÚÅð}ýw"”æ¦+U85K—µ"æ{·³¸<É £´4–Õò"W(:è%˜g˜¤üœn`ü«½ãªs¯`ë5“´Bë[ò4î°,ÿLÒ+³éE¾ßâGaõ0·“$ îL‹U£‡;œÖŠÑyá¿‹í¶þ<bZkÁV=LÒ˜¼ø.¤^&ivctvÃÖð=µ°XÛuî¬(UÚNóýû‹Ñc<ýÕ¥”^±zÿöOG1§D,V¯«=zz˸Ã$É3FtC¶Vh–æ4J•IõþX+¦IƒYŠ=Íå±dIV¶jüÚMÒcSw¦’öXjÙ'zš¥Ãä_Ÿ4±7@ 6ɉÌ^!&î*L†¼å•öZwôüŸ´\)Ô MôzÃ>1—QjqjÕs]Öû¢×(Y2L’ÍÒÕµí÷ÿ¾d5ŽbVSh¶%…_rs¶2»ªÝ,ý½þª½¢×غµÁ?蕹-U‹ ¬ ›õêû2&'jÅ]…œVo’´O Ôz•Žp³4Qªm’Z4>i†I£ib–Þbâ욎 j­íõšMÒcSw¦M’v³ä\wõݽ͒›'¡ÚUr=Í“”U¤£¾<*'Jã®ÒuçÓ×Ò'j›"mƨ’n¨òl÷UlUÌ ûFiÄ&©Iã“jš4&ñ´€ÇšÑ‹f’ô—zu0EÝ×÷8={¦tªÎVlz¥ÊÆ©wS9júg¦H²X­)K>ë¸-Œ‹sT[¸bÆŠÃïçèÕG$Ä]Nmˆ­Ç½kÃU‹Y•%ê{öŠØØ Ý¯/ç¿;‡"}›$´— ‚±•äíË‹¥£­ÁîïðMþÍúŠÒã"ñŸ„ülüVa(o>5ŒTèóCûÓo[ZòI‡11^!'’ÄQJ!,ý÷ “•¸Ób˜bâ<õïK7J©ñÔ#îrs{¯ãN>û«A¯¨Ù‹®LB91T£WÜ#~Ï—÷¿ÿ\DÜ¡¿ ›¥Ðë}JtÃg@ï=¶ä^¬Â(­ …d{Dü¥Zoƒ&Qå©Òæö:ùZEêsñ=­IDATmžUE’%CTbœ0Gcó¢SN ë'¯‹ï?*îjÔ†½B–Hªó91úé^hÒ jÚk£Ô¢6”ÄÝô[ï0J0Aï W€qMãCD¢ôf×Ók­•QŒ"`˜¤Œ‰ %`U à&©©%Œ’>˜Ñ€V°ª€Q¸„Iêy:Y„Q@(€Ç·àf4ì÷ùTS h/¨Ç¶m˺®Ëº®bÆ£€P˜ÞÅÞï}|0MöÁ(À”)Çä¸ÿÓ`¼^lF²ºÕ-K¿`¥§qOÛ ñöÆŸ%À âÆÁÖIpêG óÀ xõûx¯^î&@{F @ŒØ)¸]c†YHÏ)¹ƒQ@,˜2I¾Y‘0†ŒcÚØH£D²˜èÛ{7«Kyy#!g0Jˆõ&É7%Œ¥Þ1F‰d gc–ÈŒb“Äx2Ž%@\‹4K&Œ… ‚°½šCä×>Œ`’0ÁŒ'F‰dµÆmµOÏ:¶è.ž%ƒAmUT³ @¥@ú3f‰q…¹s£€`@L3¾€Q¢Л1KŒ-%Bš1ŒÅÒôeƘñr£ˆh„¡ªï ©Ñôdƹïhɇ_©îÿ”$Kég ô‹hL’ýqfŒA#¿R|Ñ›û““°þgHzY ŠRÍ‚èÃQf Ñ€Ib¬g€"£ îé!aÐôbÆšqíyðQø½‚žÕ&€8á°?ÿ+Y˜"žçkÆ´óqeD$¬$Åü®X3EÒz¬p¦ÏeŒ´æÀGj±ÒœŒ˜$z0B‘ñr †äãÁ xùÂÁ«ˆfÆ›ñhh”RMÒÑ;’B'Üõ0`$- žÍ3Œ÷È1g¼ÁR½[·ÈHÎyŽé,QjïS>û}$-ÌʨÈóHóŽ9ã Vb?Ú(i½1$- úšzï|f‰1‹qÿ‹›`›mÛºlÅs·}Ñ{ǹ?&è-˜)î«Ä¶Õ%’à¸_Öì‘l³Ó¥‘0I@ÌOl”HZ€öBƒ4¯AfìaŠgÍ(‘´m{'"y^ÃÄØÃLfɤQ"qÊLÓôÚ¹L2: fôæO½€r“ŒÆ‚Ù Ó· `^0@0SœŸéç‚9£4ú ä Ÿ_Ü€wL­(I]:^וkãÞq}Ü;îׯ¸rï¸6î×§V”0J%Œ’4Ø#ʽãÞqï¸wÀ}ãÞqï¸w€QÀ(`” ³nl²xƒ%鸮ë÷/Yüªõ9Zu±ûhcÅFi]×·óÿwïÏЪ‹þ Ú8Ì/-Á°»Ý îñ9šu11J¥Â"çÿÀ(À”°Åàÿ0qtÌ·¬6þý?ý}ýgzƒm×c F &!cs$ Üãÿ§kš0K ½>F  fZæDì3J¡¿³™¼u]Ogc?Àï#î€V]|ôw©ma>4Eî ÖúÐI-!€ íº8ôŒÜ«»† ’/BBãìY$&Ú0J°ð%€ü}¤Õ¸;`«IEND®B`‚snd-16.1/pix/pyr32.png0000644000076400007640000001052711147553270012632 0ustar bilbil‰PNG  IHDRÈ0g pHYsaa¨?§itIME× 8 €Û`ÇöIDATxÚíiPgÀ7 p „€‡ME,‚ ˆ(±¢‘Ö±­¶N§UgÔvœNk§ÚéEgjqÔö;£µRìTÄ"*49ƒ4r„„¸„$$„$û~ؾ)…@%²›üŸ6ÙÍîÃìóìsR0 CÀÙxA€Ykhhhòííí*• "8(VEEEmmí„Ý---‚”””@¤€AµmmÞ¼¹´´tÂîîîîüü|©TŠa…BAQôúõëø.E{{{?øàW%]«ÕEEE¹0|÷ïßûí·) ˜4¥XöwS©f³Ùö1$$$??ßnmm-,,t¡Xýýýëׯ_ºt© Ã'‹»ºº–,Y&ÙÏ Q---íèèDäìÙ³|>AÔÔÔï¾ûEQþSŽŽŽÒh4צ!11Q,ƒFvÀ¥¥¥%;;s.\ÀA’A4 ºáqa0:âõXNfÅŠ­­­ËÉ„……A=Ÿûˆ…¢hHHÜ?ËɘÍf*• ÷Är2‰„Íf$1)))wîÜ™W¬¦¦¦ÒÒÒÉí?s‰J¥ #H£££e2Èô¸bq¹Üüüüõë×Cøp¼½½- ÄÞ ‹$ÄÇÇwuuAÈ-–Õjõò"VÊŸxâ‰ÎÎNð žXN†F£ŽŽBÈ-1kG¡ žôbÕ×ׯ]»–h©Z¸paoo/(Y¡“Y´hQOOÄÄš…hzyY­VˆˆådBBBP…8 ÿÙçÝ.MMM2™L*•Bø&Àår¯]»¶iÓ&4é8___£Ñq€¬±þÏ;wRRR›<¨‚'«XÃÃÄMÞ²eËîÞ½ b‘O,FwÄr2ø`"§0!!¡££ÄœLll,ÔÅL,£ÑèççGðDΛ7oll Ä"¤˜ƒÅbÉårkfX,³Ù<~š9C©TFDD?¬Ð íH“N[[[¿KŠ:ŽÁ`?¬‘‘‘·nÝ‚'ÖÌHIIÉÍÍÍÌÌ„rútÿ²ÿžZ ÄœÃÊ•+…B!ˆE†††‚ƒƒÉ’Z/¿“I,½^O§ÓI”`:®×ëA,¢sïÞ½'Ÿ|’D ~úé§«««A,¢£Õj ôbHhhèÇA,Àɤ¥¥Ý¾}Ä".‹…Œ3­yìiÒ ¦0™LóæÍ#cˆ™LæÀÀ“É„'Öà’Á7oÞ\³f CÌår›šš +$(¤«Äú'S R}|| ˆ8¿ïimÒ Ö\¤Õj=jô=9Äâóù«W¯&u ### ˆE,Ü`dNjjª@ ±ˆV ŒEÜ"¼çÔ“@,RŒÌy<ª‡ Ä‹ÅË–-sp{NI‹M:(Šºvág'å!b‘ I‡¼uîS¹ÕßßbNÆCÖ''ºXîWÑàïïo2™Ü~dÑÅ"]?÷GÁF†],©TëfAg±XJ¥Ò½W¢#´X†m1&g±uëÖK—.X®axx؇å¸÷¨CB‹uëÖ­U«V¹kèW­Z寴-–Á`pÆ»hµZëôz=Š¢ÃÃÃðx¸ñPiGÄêééiooŸíÙÌÿú미¸8÷‹N§Ëd2 A$!!!++‹ÃáÌjÊîÞ½ë6mÏÓÀår…B¡ûõZ&nËb±x{{{B†˜œœÜÒÒbNÆ-—f%¨X"‘hùòåžã‡Ãinn±f®®®øøxÏkÁ‚jµÚµQ¬‘‘O˳³³¯^½ bÁû “¡R© ííí Öl!“É¢££=°§P(FFF@,çC®©‘ÎÆ«ªªÜáìÀofu0…§Û'Ããñêêêx<žÇ=±fu0E__ß‚ ŸD/‰„«©©‰Ëå‚=Ó“““såʲ¤ÖõM:ƒA§ÓA-ÃB£Ñ6lØPQQ‘““C‚☣´´´dggcÍ… 0à‘1UUUcccO§‹Å‡&gž[kÖ¬©¬¬T«ÕPÆš±Xœ˜˜ºÌ??¿ÜÜÜŽŽ"»åJ±¤RiLL ´:;ÆÚµkQ%ìä€. EÑÞÞÞ¤¤$PÄa–,YB£Ñ®^½JÀj׈eµZëëë³²²@ŽÇw+55õÏ?ÿ$Ú ò®«µµuÅŠ …SÈËËëíí%Ô²®«§§gÑ¢Eà„IKK[¸páÅ‹»»»=Q,‹ÅR^^ž——*8‹•——‡¢hYY™ËW8w¤æ]¥RŒŒ8©ÕÕÕmܸÑ]gu9 %999))éÊ•+!!!‡J¥º$%ŽÜ`­V«V«5ÍLxõêÕ¬¬,’.FO"¼¼¼6oÞ¼xñâÊÊJ‘HDš'>?öŒž:†•——'''òƒsFdddnnnWW×Å‹縅c.ž“†]¾|yÓ¦M®z,{2ñññqqqb±¸´´4"""==}nj¤gýNòùü-[¶€U.,x-_¾|ùòåJ¥²¬¬ Ã0‡3Ûƒ7g÷f···kµÚmÛ¶ÁÝ%ø½hnnnnnf³Ù‹-š¥•ÕfK¬¡¡¡ÆÆF6› Ž ‡Ãáp8‰„Ïçëõzƒ‘””äÜ.q³"V]]…Báñx¾¾¾p ›Íf³Ù‚ètº¶¶¶††//¯ùóçgddN,‰DÒÑÑÁãñ‚‚‚àΑƒËdµZÕjuii)‚ ¾¾¾t:ݱJG爥P(¤R©R©d³Ùùùùp«HŠ——Wxx8~FcCCƒN§Ã0L.—'''ÇÆÆ2™Ì‹U\\Ü××wøðá ïtµµµF£ñ•W^±ûûŽŽ‰DÓ.¸¾¾¾ÙÙÙ¶R©´±±ÿœ˜˜8Íã¿ÅjiiIOO§Óéƹ߾}{ûöíåååø<0(Š^¿~ß%$ɵkרl¶^¯_Ã+—ËY,Öä‹iµZ …Â`0&ïÒh4T*ÕîÊTgsú®‡úûûÛ-ªÕꀀ»cÔ¦:Š¢~~~S•2§úÕ4ÉV*•óçÏ·;÷½¬R© µ[400n7ÔétøÙÔjõÉ“'m]X7nÜ3~¢ë¿Ïk2™h4𝝝Ñh"³Ù<þÚ!!!¶œîÁƒééé555555.ßßßeW,Aì®7XSÍ黦K¥RÚ˳Mó«i’=00fW,þØiΦP(˜L¦ÝzÔ©ÎvæÌ™Õ«Wÿku|LŠ¢gΜ),,Ä0ìæÍ›‰Ã0¡PX]]}òäÉ®¹|ù²Ýï%Éýû÷íî‹ÅÝÝÝ3:›ci˜fWssóÀÀ€Ý]>œQ„B¡B¡˜i¦Ivmm­Á`pVêêêFFFìîšfÐ4É›À?ÿººº:;;ñm©TІaØ;w솛ö „B÷O67~NŽ˜˜Ûvrr²Ýglhh¨Ë ˜â¤a Ãà p~ÍÅ£jµZ &¬Ì¡V«OŸ>}ìØ1pÔs°X,‡›ðŠó žkvvvŠD¢É9:þ±¾¾ÞV,ÜžšššsçÎŽŽN6áúõëjµº3F­Vß¿_©TNÓ‹xbÅÄÄTVV~ùå—x…ìåË—ëêêIOO?~üxSS‹Àl”‘‘!•JñuÁûúú¾ýö[AV­ZuâÄ ¡P<³Â»Éd²Z­x¥ŸÉd¢P(xvƒÁ@¥R‰Ü™Ýl6wwwŸ?~ç΋/žã«‹D¢¯¿þzdddݺuûöí³Õ=Z,–’’’K—.y{{:tˆÃáe‹Åb0|}}©TªÕjõóóû— R&hooß½{7Þx5Ç—nhhxçwÊËË<ˆ È‘#Gðï-ËöíÛwíÚµÿ~üaôèQ· 8â9å͹Ëd2áÛV«5###!!ÿXVVvüøq|[¡PÄÄİX¬¡¡!÷ˆ6Þgµk×þ]gH¡ÛJ¢2™ìÍ7ßÄ·™Læär9Š¢Wåh4š;w†‡‡¿ð ¶…ºººöíÛ·gÏ.—ûé§ŸÚ.///--ýñÇÿýwÛ—ßÿýû￟““³k×.Ûk‘D"yë­·ôzý„ËÍ›7ÏV¤ëëëëéé9wîþñµ×^$ƒÁ ÄK*e…ï¾û®N§ãóùÑÑÑ6l°X,V«5**êðáÃx6*•zúôi Ã.]º„×õi4|/†aŸþù_|aØØØXRRÒ¦M›, †a?ÿü³··wII‰ÝK›Íæ7nÄÅÅñx<™L6ù«Õº~ýúƒºM´=î‰õÒK/ÑéôôôôÔÔÔTWWS(”Å‹ã]>"##½¼¼„B!‚ ••• …AÀÀÀ¼¼<“Éd4úé§ääd©TÚÛÛ›™™YYYÙÛÛ‹ ÈîÝ»ù|þŽ;ì^Ô`0( .—{ûö휜œÉùH$º{÷î{ï½ç‰M:nÆóÏ?ßQA^}õÕúúúóçÏÛ&1KKK;zôh~~¾H$Z·nO¿F£¹uëVQQQQQ“É,((À׃õññIMMêZ cÇŽÅÅÅÅÅÅb±ø·ß~›pÀÇ\QQáN 5zî ÒÀÀ@Ûöƒ¾ùæ›gŸ}ö¹çž³õœÜ½{÷ðððo¼Q[[{ìØ±½{÷^»vM£Ñ¼øâ‹øàxæ™gV®\‰×+Ú8qâć~èf†yîËjµR(.—+“Éx<Þ¶mÛ233Ç÷¨”Éd¯¿þºH$âp8û÷ﯪªÚºu«Ùlnhh_Bmjjzô‹z{{ûøøØ–RÇ0ìøñã<Ïf•L&±ÈMIIInnnVV–@ èîîÆ‹J‰Äb± b4O:e0ËÊʘL¦J¥ò÷÷g±XŸ|ò >…“^¯?räÞ…EÑ_~ùÅl6O~7’Ëå¶^ …Âb±àÝ»­VëG}¤T*#""är¹\.¿wïÞÙ³gá­d:¾wï^‘HTQQ±mÛ¶¶¶6¼Wt@@‹ÅZ·nÝgŸ}ºzõê³gÏ:t¨  ï[›™™‰wäýõ×_i4ZPPPZZZJJÊ©S§ð“ÿðÂOî‚ HFF†@ ¨ªª*((hmmÅw}õÕW“o‡P(th{VG?™LV^^®Ñh¢££óóóýýýñïëëë·lÙ²lÙ2@ öîÝ+‘Hh4ZGG‡ÙlÎÎÎ Ánmm­ªª¢R©/¿ü²mXºR©üã?öìÙ3¡ÁÔjµVWW·µµ!²uëÖ¥K—ÚvÉårN7!…111î1ô  Œ€Xˆ b €Xˆ€XàLþ¥ømn(œIEND®B`‚snd-16.1/pix/fmeq21.png0000644000076400007640000000240411147553267012747 0ustar bilbil‰PNG  IHDRV, ¿`¢3PLTEÿÿÿààà°°°ÀÀÀÐÐР  €€€```ppp@@@PPPððð000 * ô¼ pHYs  šœtIME×  0OÖWdIDAThÞí[‹Ž¤ äýRÑÿÿÚã¥ØÈxšÉ]B%ëíÎ9EUÓ6лƒÐ¾¬!aC¯Ár„”2!2‚ñ¨¿ø|ß ¼ì¢ÉÌìr–`¼Y[]YElRbRÊéƒMzŒuë1´”:ÿ™ñIN#,±HYXéŒÿϳâoOÞ×£ÙY®¶zƒù^;û×/X¬¸y´Üþ¥$r­‰J©êwd0?4®´gŠ:äw½Þð`ªZ¥ìÍùÀá1UyR™éÆ,«ë ׋ŸíI{¦¨"¯„)ûÒ#—ˆ²(R%¼$Ûº÷ñ!˜ÃÄçk ùrµ¬¬“2«¼ª¦f9kÏUä¥0z9ò¾NF6§i-еH À–÷û ‰u½ÎìÊëEÐõY{®èŠ|¹\ünˆ0Lôƒ e î§[Êý 6w`ÓÜbªj[Fc©@œgÂ’Õtr›HÙ´h³Â¡=W´“Â@¯°KÌQi¦¾Ý “ü0ßi£ˆ¸rƒÍÄã(4LtZ´Ü°êfXƒ1¬ŒûJ€óLX²ê^^()[Od|ÞSò/€¢D ½‚.-B#»µowÃ$?~æ\¡SØ ºËä´ ‘OÅ –Ö2¬d¦”ò” 'D˜³Ò)[ÖÓ*^¦¤+¯¶_Z…%rHXÃ+à’#áß(Û·âà‡J¥qz!\ްúa$cþ”Ö`zÊï…Œ¢'@X°Òî¾Í§]PZ÷°–Š&Ô{…\Z4¹[èÖr9“÷4Ì «›{ì®Y˜v1OÆRùƒ8‚µV¤gÖ-­GX EÇ£p{…]ú§E¨öíž3ú᱕!¥ÈùìÐû“çæŠ5LÆHüä Ö½&²O¨‚hW ¶’¥,­{-%rHìtq¥·n÷ÃD?ÂK­C¾Y\áÝlªCÑàÓq¯œ9!æBCˆ_OvVÑÝÊLÐæmqÉ¡Œ_¥'ú“˜•¢¶0Ø+èR»qØæÎw°“8Lô#4³šÑeÈ_°˜÷ê„m\Ì›£²“£pXq6ÙáqÝ\r•*9Ì™ïeÃÈÐ«ê©Ø 8¸”!¢ (‘ƒÂ@¯`XâÿßUØI&ú±`£Áø×°_ˆkèìÚÎ.Ûh^„HsÄ–´²Æ\ÖÆr…iÜH:Jjíõšv! ö –ºpÁM'…Pk‘þÙ9omžtæÜÉFk†O±äãïœÂ<¥!ô¤½O~íßp»GLÍŠÛ¾ÚtÓº0DôqJ±ª³¹šê¨j€2öt/òG^3'=aÖ,ú%t§#°Õ¡âæ{íò·¼êoh~Û}¿Vd×z¯%$þ^»ý×ß&â ˜ÍÀÅrÙÎø²=,ψõ€aø MÔƧ‰ 5QmÚ«f4>MôG5!ý6O=Bl¢ž³u|šè>MÔº¶þÛŸ&ú“P+d÷[ò&IEND®B`‚snd-16.1/pix/fmeq20.png0000644000076400007640000000162511147553267012752 0ustar bilbil‰PNG  IHDR "g3PLTEÿÿÿààà°°°ÀÀÀÐÐР  €€€```ppp@@@PPPððð000 * ô¼ pHYs  šœtIME×:îG!‚õIDAThÞí˜ë’¤ …‰xiEßÿi‚ض&Óгýck¡jpf€ïÀ‘bÌ÷’w‹i)&Ý£¹ÍhV4+šÍŠfE³¢Yñ׬ðV=ˆÙ"–­¯âÚߦá'#h™Éíý"µÇT&ÒUö¶Ž{¦OÍe*=Y^z–¼yWñ®äžªwÝ'V ca¤&„T*b_jâ­Ú+Xá¢ÆµôËÙ gíõ%7‘õüžé3ER¹1‡-@ j$çÑ ͏dLúÃ[ÜHä „˜‰)yäŸûÅ€O2i‹Öß|ûò·ˆm‚,ÆŒtq÷vQ5oóí3‚Ó‡¼¿-Õš—ùæ^™ y[ýk¡ºnõ)Eè[;…·Í¯?×Ò¯{xyÙºù2Â<‹Ú-}䛊ßáøëPס"xß?WÏ~[¶å”óÓéªz7qÍt ئXššmmïËòâKÅ{\Ÿã A­á%`÷ú«PÉdo>Ñy&ÞuUä—¢UŒÙOîöP3‚T2è„R7 /[Z»ŠRZÚy¡¼øZñwÁñE`¯:ýÜDGëv¨€`Vž{~VŸkC¼Å/V^™^ ¾0Ъ~ ÔÀ”™CX¡ìT•–f5‘µ•.׸+Ž×e”âÁt&Y š½þºª`ŽÌs¾ÂsÔ ñ¿1(™tž‹ø» Ü ­å.Óœ7jŒÖÜŠ©ˆº1dEæPZ²5õn(ÓU\ãúaè¬Õ” üÿwà­¦#0ÑñJÑŸ¼õ§ð ªœNjVÄÙ+Gõ¬8*" tâÕàšù™ wzƒû8qŸ×´tEgp[ˆGÛ&P…±lÎH|b­í3UíÒ2ÃÞV\ãºqE ~×ïK9ù15½–Í– “{ èØ4ù˜€x~ â ,õG'ñ¨Š8ÁhŒ=-6ð¨ŸíÎ#"­«Åµð («‚öéÚ_ʱ…1v1ÓfP…`b‚¸Å*U»o¼~UVºŠ÷¸.GM;|Àq1Ð+¢Í°X‡”„™l¯¬D$¯ýd­1W•Ä)½ØÌ£Dœ YGƒká8PV85"ñÚXZ†Oµ+¯dP…‰Ù$—È]¬Ü'ÍV:G ܆dÑW¼Ãu9†}íÿnÌ.£NùŽò´Vî®Ý² ¼i„ÍÄu•:ëÖWei…‹c!&DÒÑàZøÊ÷ôæHJYŸRíÜèE.)¬A†©À˪³W¥Ê²}ì¹ù :¹%ÂW¹Žâ#®ÇÑ»§]( ]£÷()ráb„¦}1K£Œ{ 䕸å# Òlr¦xÏ+™G3!"éhp-üÈ+ÊG5TwüަvYL’âÒh =b ª0éZÚÈLæ­yµªlÐéòÆÄ¸ûÞ¥£øˆëq¤8IBÊE+4´e·öÑrTܶχ•R!‰4œx •ó™»,6ñh¡!"ë8s-üŒ`È}è Üí¿¿0ž–ã¿îÄTc"ƒ¬Û,zMÏgû¨S¹Ó†´ÀzЏGo‚ôãǬ »3€RPcFk¥z#„j±ør€GP›+ó9í˜aOVåò%¦‚ 6oÍÁ®ÿãï'ÆÇˆÀ¹ËÿÎн‘XŽqˆ N ¾7Ö£%æþZÞTüÇßÏô>þûù‘©5”Y·M±[‹üú£VøÀKò™-Џ·WzÝó·¿JøÏE9X&x|Ðú~ã«Ñ,õã¶a¾ø;û5§<»á†ÂÍcƒ¯÷4i¬ˆÜ v¿zz䃑QÆI¯Ü ¥IcÅ'Vn$eü˜¢gåÏi¯åâ·48p$é¿IEND®B`‚snd-16.1/pix/cosines.png0000644000076400007640000004233411147553266013324 0ustar bilbil‰PNG  IHDR¾nY>bKGDÿÿÿ ½§“ pHYs  šœtIME× Á IDATxÚíÝyXMÛÿðws¤$!*)Ê¡ •)DéR¨ášêF..…kì3d¨HW÷J® ™2K†ŒM†&óÐ,iOÃþýѯýut 9Ñðy=ç±×ÚgŸµ×ÙíÏÞ{íµ–Ã0 !„o$LU@!„!„ „By)++CJJÊ7”çÏŸ£¸¸˜j•4iIII¨¨¨¨uŠŠ <þ>|  #Í7€øùùÁÁÁ¡Öu>~üˆ½{÷bõêÕ8xð ¨]ž4U=‚©©)òòòj]/((«W¯ÆÎ;ñöí[ª8Ò$‰~i…äää/näùóçHJJB@@ôõõ1{ölˆˆˆð˜­[·Öº.]º`Μ9Mº²: ´jÕŠŽ<À°aतôþ333ó«î²×­[‡¨¨(ìÚµ 7oÞ„ššOþÞ½{ñîÝ»Z·±|ùrÈÉÉ ´ü»wïÆ‚ šäñД÷­Ñ_ýáááßõ%-Z´ÀСCkÌŸ1cºwïÞäÈÉ“'1hÐ „ýû÷#$$ä‡}ç°aÃЩS§ïÞ‡ÃAçÎk¼Ð8|ø0æÏŸ/ðòï¿ÿþ´“ìµkד“++«zÙþÏÜ7 _©¢¢©©©‘‘ùêƒ[JJ ¦¦¦µ˜¦nûöí¸xñ"vîÜIGÝ»wï§—áãÇàr¹h×®ÝW¦_¿~5æÝ½{·Qþùùù†””ßü””dddÐAÛ„|± äÖ­[xÿþ=ž? ²±\EEëׯgב——‡¬¬,Î;‡ž={BHHˆjö3())¡ŠW¯^AII 222?ô{ãââðñãGܺu‹M›>}:z÷îͳހpîÜ9BEE¥QÔé“'O““SçÏûøø 00NºùŸ„„˜šš")) šššhÑ¢V­ZCCCvîÝ»ÃÊÊ çÎÃúõë!,Lo“úuêÔ)èëëãæÍ›?ô{0nÜ8¼|ù’M³µµÅ AƒxÖÛ±c6lØ€þýûÃÄĤQÔéž={`oo¾}ûÒö"""pñâEÌž=›½½|ù2ÂÂÂ=zôÀøñãîîîÈÏÏLœ8Ý»wxy¸\.¶lÙƒŸþlÚ´ eee;;;¨««ãÙ³g8vì€Ê'Güñ€ÊÇï±±±}}}Œ5êëî@–-[WWW 6 @åã&WW×j…200€««+Ú·oOGS \\\°e˪ˆFlÔ¨QpuuÅ¢E‹Ø4;;;8;;ó¬'!!WWW˜™™Q¥5a¥¥¥°²²Âœ9s°zõjž—Ž.^¼aaa´nÝGå¹SÓÑÑA||<âââ^¦mÛ¶a„ X½z5.^¼Xãz¾¾¾ÐÑÑAdd$^¿~ l™tttð÷ß³ë?~òòòÁùóçÙtºUøú÷ïû÷ïSEò***ðË/¿4¼G8¢¢Ø¾}{µñÏ?ÿÀØØ#GŽÄ… àåå…3f ??–––èÑ£~ûí7$&& ´LÓ¦MÃÆk]güøñ‡¥¥%444`gg‡ØØXØÛÛCKK –––(**´iÓàíí   Œ1ƒ†ŸŸŽ?N„Ƥ¼¼QQQÍr߆Ajjjƒ+—ÔÕÕѺukžôüü|äææ²ËÈÉÉÁû÷ïQ^^Φ§§§³‘EII ªªªµ®“ššÊÓ_/-- \.ééé<ÇÛû÷ï‘““ƒ‚‚6=77—íE„4j“&M‘#GšÅ¾–””Ðkª¤A¡B5'''ìÙ³‡*‚ „ÒN¬ÂÂ|ø€ñãÇÃÙÙÎÎÎÐÑÑAXX’’’pôèQ¨«« ´L/_¾DRR€Ê¶°°0èèè ..úúúðôôÄ­[· ¥¥…°°0¤¦¦âÒ¥KÐÓÓÃñãÇqá„……¡eË–¸pá 22Ož 8p >|ˆ«W¯bĈìgÌÌÌàëë pýúuÀÞÞ­Zµ‚¯¯/233ѦMØÛÛC[[0|øpøúúBFF:t¨©©AXX¾¾¾l_011Áµk× ##£ÿݹÐ!@HÓ±aöébbbØ·oߌöíÛÃÐÐÿý÷ž}кuëZÏ«óçχŒŒ /^ŒÔÔT,Y²ÇÇêÕ«1aÂ,^¼žžžpvv‡ÃAHHnݺ…ŒŒ ØÚÚÂÌÌ £G¦·°~4eee¤¥¥AYY™*ƒ4*¯_¿n4s›ü(âââðôô„¬¬, eË–àr¹HKKcûb•c^½{÷?—ËeÓcbbþV[[û‹w5QQQ|ˆ¬¬,vê‹æ€!¤Axøð!>Ü(ˆY³faĈرcG³ùÍè!„|‡§OŸâäÉ“puu…±±q³šÒ›iÔ„„„ ##ƒ¼¼<öQ!?JII  „ÂÂBøûû¨œ¾öôéÓ Evv6$$$0fÌÌŸ?sçÎÅ!CžžŽ‚‚ìß¿;vh™rssññãG@aa!ÒÓÓ¡  €¸¸8˜™™aãÆ8sæ LLLžžŽÂÂB@GGÀ³gÏžžŽV­ZáðáÃÀ;w™™‰¬¬,üú믰µµ¥B? ¬[·Ë–-ƒ§§'UÈwºÿ>úôéÓ¬®¢¿÷†Ãá𤩫«CJJ }ûö…——ÀØØ˜½ÀÑÖÖÆ´iÓæææ‘wÏž= …©©)0mÚ4xyy¡E‹ÐÑÑ‚‚Ú´iUUU¶sæÌ˜˜ºwïŽcÇŽaÚ´iÐÒÒ‚¢¢"€ÊÙT×­[øå—_ %%E„ÂËÉÉ ¿ýöDDD¨2¾‚¸¸8.]ºÄ7ÏÁÁ¡Z—¨×2ýùçŸ5æ}ZÖ   jùä»?Ë—/ÇòåË«¥S#:!„:¡B!¤Nè!„|§ÔÔT¼zõ `hh!!!¼~ý)))EEEtïÞ@å+¿U µ´´Ðºuk—§¼¼÷îÝCûöíѹsg¾ëܽ{—íL¨££ƒV­ZáãLjP9T}¿~ýÏž=Ç€g›@êY~~>bccÙ‚Ò´¤¥¥aáÂ…8vìàðáØ~üÈŽ( ÅÅŸ|ù2¢££Ù;ˆÇóçÏ+÷ÿgTzLL JKKÙåO#¤¹INNæ¬.--*¥‘‚¦¦&Ž?Žß~û ?~Dll,ÂÃÛGý_zàÀäææ²ËŸþŸææÎ;¸|ù2»E•ÒÈLœ8………X²d &Mš„Å‹S©/îîî<Ëׯ_§#|•ÂÂB\¹rãÆk2ûdmm kkkvyÍš5xôèýØ@YY/^ ###LŸ>’’’ؼys³Ùj!Jqq1"##ahhH•ADÙ³g.\ˆ   \½z Ã`ôèÑìl~ÀÿÚ%¶mÛ6}ýúõLª6Ïž=ƒ±±1N:…}ûöA\\œÍÛ¹s'455±qãF6­U«Vرc&Ož 6}üøñ077ÿyw „ÒHJJâîÝ»˜1cþüóO”––"""ÒÒÒÐÕÕ…““„„„0xð`¨¨¨@EErrràp8(--ÅöíÛ!)))Ð2¹¸¸àÊ•+ÐÔÔDpp08Ž=ŠÒÒR¤§§£¨¨½zõÃ0àp8àr¹ðññ´´4ôõõ±páBœ>}²²²ÐÖÖôêÕ 666`&L@Û¶m)€BÈ÷0`ž={V-½jšÛÏU½[_¶lÙ‚-[¶ÔxRåñãÇÕò‡Ž˜˜˜jé5ÍqB°!„Ô LVV¶¶¶ðññ¡Ê „4jô냺ºzC@B§ììl C‡€œœ¶“`‹-ØÆóÔÔTv *´hÑBàea)))‘‘œœßuRRRÀ0 €Ê±º$$$P\\ÌNF%,,Ì6ðgff² ¥¥¥ÑªU+º!„Ax÷îlmm¡¢¢Âöð^³f ¬­­1uêTžyA ˜˜˜àâÅ‹/Kdd$Nœ8¬Y³¦Æõtuuáàà€Áƒ³í2—.]°aÃàààÀ3~ß¼yó`ggkkk¬ZµŠM§B!ßéüùóŒ»wï"66ûö탛›ÂÃÃÙ~J@!ä;<{ö ‰‰‰>|8›öèÑ#Ü»w]ŽÅ­[·àççÇ3öU@@²²²Z¬\¹²Öu|||PVVÆ.ÿûï¿HMMÅ‘#GØ´‚‚øùùáöíÛˆŽŽfÓ}ì Š]ºt••ÊËË1jÔ(téÒåç±cDzU€Ê-ªªªt4’fÉËË þþþìrrr2UJ#´wï^ìÝ»—]Þ¾};¶oßÎ÷N >Õ6Ö§/šð›J÷—_~Á/¿üR-ýÓãóS?%€\¸pg¹sçÎtô‘fËÉÉ NNNìòš5kàêêJC}¯^½BLL BBBТE DEEÁÞÞ7nÜàÚDNŸ> www”––²;~îÒ¥Khß¾=¢¢¢0eÊ\½z™™™¸~ý:æÎ‹¨¨(HKKãÚµkˆÅ«W¯pòäI8pqqqxõêB„-Z@II JJJX¿~=BCCyW CPP¶nÝŠœœ6}÷îÝ|߆úNNNØ¿­ë¸ººòt§Ø¼y3Þ½{‡;w²iyyypssÃùóçqÿþ}6ýêÕ«¸yó&š„B¾ÛãÇÙ)bsrr`llÜ,ö›î@H£2nÜ8œ>}š*‚4úúúÈÊÊBVVÌÌÌh,,Bªüü|÷Ü%¤®***„·oߢU«V8þ<„…›Ïi•!„Ô—Ë…••|||ûöíÃ0ÐÓÓÀØõ´µµ1hÐ L›6çÈÖÖòòò?¤¬)))X½z5ÂÂÂ0gΈŠþ¯cÆŒh×®&MšÄ¦IKKcÚ´i022BÏž=Ùô~ýúÃá 6B©3qqqlݺHHH@hh(NŸ> ]]]`ùòå@=`hhCCC,_¾xñâ6nÜÈÎ/.([¶lÁ7T¾–ûêÕ+ìÞ½?~Ä_ýeee8::ÂÙÙˆ‡··7”••amm „‡‡£°°S¦La ƒƒ¸\.ôõõ¡§§GägtÂÂÂ(..†¤¤$U!”°°0,XÀsåÞ¡CÀºuëØWt[´hÁæß»w0SAAAàeš3g;Àc%%%¨¨¨ ))‰ X?Ã0EEEÀ¨Q£ ¯¯Ïî[OOO±w&U(€üÆÆÆxðàNž<ÉÓÁˆÒ8/«‚Ƨäääx†n¯Ò®]»z-OmAéÓr¶oß¾Z¾¤¤$ß}©i›ÔB!¤nw`T„BM),,DAAû¯ê9!Í—Ëåù{  ן²²2ÀÒÒ666€ 6@WWzzzøý÷ßÙuŒŒÀápгgO\¹rEàe)))Á‡Э[7lذ¡ÆõtuuÁáp ££ƒ{÷ƒ¡££‡ƒ²ë.^¼zzzÐÕÕÅ_ýŦÿ”6[[[dee±ËiiiPSS££4K>>>`—¨R‘¼¼<¬]»gÏž…²²2nÞ¼‰ôôt<~ü{öìAûöí1wî\$%%!''999ˆŽŽÆúõëŽAƒ ôeš 6 88ÏŸ?¯q˜”'Ož@HHQQQXºt)ÂÂÂЫW/„‡‡ÃÚÚ«W¯FÏž= 999!@!„ÔªM›6èÝ»7¤¤¤ðôéS „Bê¦k×®èÑ£»¬®®Ž^½zaäÈ‘<½Ò‡ öÃÍÈÈ€¯¯/ž>}Š1cÆ@DD„Í5jZ·n 6MRR¦¦¦èÙ³':wî̦kiiASSõD¯Wžžžptt¤Š ¤‰ÃâÅ‹qõêU,X° pww‡¡¡!FŒ]»vAZZ}ûö…¹¹9ÌÍÍááá  <<K—.E›6mZ&___„……nܸ ÀÅÅ©©©˜5k<==±bÅ ¶·o֭߯[Ñ©S'ÌŸ?›7oFFFÊË˱xñb€Ö¯_¢¢"˜˜˜ÀÈȈH};{ö,üýý©"Hƒ°bÅ ¤¥¥QEˆˆÖ®] KKK€µµ5  ,@JJ €ÿ5GŽ—Ë…µµ5´´´^¦BSS“g<¬V­ZANN¡¡¡èÒ¥ àĉ¨¨¨€µµ5tttT¾ŒRUÖª`íÚµì+ÁŸBä;•””àÝ»wPRRبšïÞ½ã™Ð¾¹ÉËËCii©Àš+--EFFF³]<>>%%%ôG+`²²²ìù§:wîÌóè§ŠA½–§{÷î5æ}ZÎO; Viݺ5ß}éÖ­ºuëV-Ú@¾S\\ºuë&°;«W¯bãÆì-hs +W®Äßÿ-°múøøðô&„ø˜ÁÁÁ^^^ÍrÿSRRpóæMâÅ‹ÙæÖ­[ѳgOvŽBÃÔÔIIIˆ¥Ê---áÍ›7Ùž¼¼<ºwïÎŽ÷Cˆ p¹\Œ5Šçßo¿ý rvª´OǤ²µµeÓoß¾]/å***¨Q£°oß¾×±°°`ËñèÑ#ÀÝ»wÙ4kkkvÝM›6±éŸ^ÜRùN .ÄñãÇQPP€ììlªfìØ±8sæ UÄOöôéSÌŸ?¿ÉíWEE®_¿Ž˜˜ÄÄÄ $$wïÞEaa!"""àèèˆuëÖáþýûÈËËÃÇ ???ôîÝñññ(++h™\\\п\¾|¹Æ>)>|À»wïàçç‡.]ºàÙ³g(--ÅÓ§O¡«« ???ÄÇÇ###yyy¸ÿ>Ö¬Yƒùóç#""………@¾Æ‡pîÜ9ömŠÏåååAVVV ßõäÉôìÙrrrhݺuWà¡¡¡ºNß¾}‹ÄÄÄò]ÙÙÙŸ2”|»²²2äææ6¹ýÁ‚ ””„¤¤$èêêbРA8~ü88€V­Z¡uëÖ8wî<<<`gg‡ÌÌL())AZZsçÎøß–-[¾xg3vìX”••AII RRR°µµELL fÍšiii())!;;S¦LÁÞ½{qöìY(((@^^ÿüó;ø'/xøð!,,,pëÖ­zÿ®={öÀÑÑ;wF¯^½pöìÙjë9rÁÁÁ<£·6&‰‰‰8xð |}}k}¥ÔÄÄ÷ïßg¯tiˆÄÄİuëV`/4wîÜÙlö¿ÙÐÐPXYYáÉ“'ÕòrssqöìYœ+''‡ÂÂÂoš}þ‚ƒƒÚµkYYÙjö‰‰‰(//G×®]áææÆCð©ÌÌLìÞ½:uBLL^Së IDATLµ|www 8}ûöÅÇùÞ)))¡M›6|ƒeaa!„„„ ®®^íóåååxõê455±gÏ899ý°]II ååå|ø€ˆˆ½~ÝX¤¦¦"$$K–,a455ÅøñãqìØ1øúúbðàÁ˜BBUƒ=DEEaÇŽøðáž={†aÆáÌ™3ððð@~~>vìØˆˆlÛ¶ ]»v…««+îÞ½‹;v@XXnnn°µµÅ°aÃðï¿ÿ" ãÆÃèÑ£V‰ÇÿýWc¾ƒƒC­ï4/]º”m̪zsâÄ övÝÕÕ«W¯æùÌáÇÙñ^ømßÛÛ›½%ž:u*:ôÃêÃØØ˜ýÑùÑÓÓƒ˜˜Xm ;w†ªª*BBBØ´ˆˆ´jÕ ]»våû™§OŸ¢¤¤¤ÆÇW‰‰‰HHHÀÀ±`ÁìÞ½›'?++ ááá9rdƒ8¦NŸ>Q£FABB¢Éœ¬ž????o÷Î;èÔ©:vìØ ÷{Íš5øõ×_qàÀW6111Œ7®Úca;;;ôïß=zôà¹hÚ¸q#”””0yòdôíÛWàå‘““CÇŽqèÐ!Ì;JJJ…ºº::„áǨìÛ¡¤¤„Y³fA[[ЧOØÙÙAII 7nd·éèèmmmôë×Ó¦McÓÌXXïß¿GDD&Ož ˆŽŽF||<{Ò8p ÜÜÜàààHJJÂùóç±yóf•Ã"Ϙ1K—.eO=~ü˜ýFuëÖÁÕÕµAþTTT@XX˜½­ìܹ3òóóñþý{tëÖå¬êùj‡ ,,ŒÄÄDèëëƒa0 Ã~^QQ xñ↠V-¿C‡077ç ’ùæ}ZN~_uìØ‘ï¾Ô´ÍsÒ²eKˆ‹‹###@eƒqqq1; ž””äääØç·¥¥¥ÈÎÎf‡Bƒ²²2’’’øn_HHjjjìíu\\Ïxý ¡¡ÁŸñüùsöv”Ÿ7oÞÔø¨¨.öíÛ}}}p8¾ù••…©©)ßü›7o"))‰gÍOÅÆÆ"88˜J\\­ZµbGØ|ÿþ=öìÙƒ¿þú @åqk×®ÅüÁùóçcïÞ½ì6ýüü0}útvyâĉ<ó@Ÿ?æææìò!Cx†ÑÑÑái‡ù<ÿsŸo¿¹yóæ ßÁùùYLáp8hÛ¶-.^¼ˆŠŠ ܹs‡'âuîÜ8rä€Ê·}>}T¢  ¶›ýÙ³gñË/¿üoG……áââÂÞ–Íž=»Ú€}nnnpvv,Y²Û¶mãÉÿ´W3¿gü?£Î^¼xQc­=z ##ã§5,~‰ŸŸ_­WÒæææ8þ¼À¾ÏÀÀ Á>¢„3gÎ`ðàÁ¦3ù!äó€òòràÁƒ5®ãííÍ÷Í«*Û·o¯5¿.–.]Š‘#GbìØ± ¢žÌÌÌpàÀž1k>¿í<|ø0Þ¾}‹cÇŽaÆŒ<ù½{÷Æ“'O£GVkÜÖÐЀ¢¢"îÝ»‡k×®aùòå<ùÊÊÊèÙ³'®^½ŠØØØjîßkÁ‚àp8ÕÊ]WãÆkÒÌ[·nÅž={àææÆ>ç&õïõë×pssc—½¼¼ ,,ŒcÇŽ±m}úôaßuvvf/úìííÑ»wo—©¸¸ .İaÃj­ñ¤akk !!!¸ººV›JTT]»vEJJ ÒÓÓ«µ9•ùÉÉÉHMMEÛ¶m›U'¬Æ$77ÂÂÂHNNþ¦¾K_ëÙ³g|',jè***111hhh@ZZ1118tèöìÙ---èêê"00nnn°°°@VV  ¢¢WWW\¾|¹Öu !!! ]»v숼'N„ŠŠ ›› 333lÛ¶ ÇŽC¯^½Ð£Gxyyáßÿm˜°6mÚ„M›6Õ˜/""Âó¦Ð·æ?ãÇç›'$$UUUØØØ S§NÕNf"""àp8ð÷÷G›6møž0룗-Ã0ÕÞªâî+Wò½c«*smÞ|©¾>}3¬¦üª†v~ˆÌÌL(**BMMïÁ¾zõjHIIañâÅhÑ¢­ Ë—/CZZšïluÍ™ˆˆF…€€HKKããǰµµEEEûædU )//¯v~¨ó…¨¨(ÄÄÄj]‡_9†áIgååå|÷¥j™SüLŸ>}pèÐ!¾Ï%%$$`ccƒ©S§BSSó‡L;;oÞ<== œ:u /^¼€¿¿?´µµáíí£GâÔ©ShÑ¢;lÎ7põêUäææbÚ´i˜8q"z„õS5ÖW¤)S¦àðáÃT¤Á= 8111˜>}:vìØ ²ÛAEE>~üÈö›*§rˆ‰‰––ß7ñÄâÕ«WpuuE¿~ýƒââbtèЮ®®000Ìœ9111èÓ§ÛVXU¦˜˜Ìž=›ÝæÄ‰‘••…òòržÑ%~ÊÈÔ©Sy†"ÿþýi& k¢¥)ðõõÅ©S§ØåçÏŸÓ߈¨¨¨`ÕªUÕÒMMMùv'X´hQ½–§¶7M?-ç烠[·n|÷ÅÊʪZ?°Ÿ@ÜÜÜx^ 8p`³>###ñìÙ3¾I¥‚‚HJJÖúÊqc5~üxžÍöíÛ)ˆFá§ÏÇ¿oŠ'…oÁårQVVÆÓPExmß¾666Mò­*999žv®ªJB(€4CñññhÑ¢…@Gë%_ïÇHHH¨6t !õ!99™§³®³³3„„„ÌN¥Ý­[7öͲ={ö°Ã7®^zàs¹\¸»»£OŸ>5Ž‹¶mÛ6”——¨QBUU/^¼ÀÉ“'-Z´À‚ TN r×#F Ft[°`fÍš)))hhhP…ü©©©xõê ©2H½*--ÅŒ3555ìß¿...*g,**‚¤¤$Ïdy^^^PSSÃÇ+ð2íܹ“&M²eËpîܹ×Û·oÔÔÔpûömö­­ØØXDFFBMMg¼Á#GŽ@BB%%%8{ö,›NDÀ €{÷î}õú’’’(..¦Š«²²2¬­­«Í~X“ÀÀÀ ´òòr£k×®°±±‚‚._¾ŒS§NáàÁƒ6lÌÍÍqéÒ%x{{cöìÙ(((€ tttàääTãFueccóÅ©&lllØ‘5ºwïŽ3f ..óæÍƒŽŽlllP\\Œ™3gÂÇÇçÏŸÇèÑ£abbRiBBB0vìXtéÒ…*ƒQQQ¶#SëÖ­¿¸~§N‘‘Qëd`¤fºººxüø1UÄwÊÍÍåyÓ4//™™™HNNf@JJŠÀû½´k×®Æi««$&&‚av9))‰íhøipLNNFVVòòòØôììl¶"“——‡““S3 ò;A®]»‹/¦Ê«ºº:öîÝ[ã4Ÿ[¹r%V¬XAWÿý7ÏûÿäË¿&L@tt4öìÙÓ`'o«·ý§C@°”””¾úqKÕHÁ£v:::ß4N¿aï ©¯âéé‰sçÎáàÁƒHHHÀÎ;kœ%´©¡;Bù΋FYYYÄÆÆâðáð´´¤;B!µc~~~X²d :uê===ÀôéÓñðáC¼xñÙÙÙ˜8q"–/_ŽåË—£gÏžxøð!RSS(ð×ýß¼yöe|øð>D÷îÝËŽ…u÷î]ôèÑ>Dzz:‚ƒƒÑ»woœ:u —/_ÆÃ‡ѪU+vbª‡">>YYY˜?>;£"B©£²²2ܺu îîî°³³ãÉëׯ‚ƒƒTÎ#^eøðáððð€zÂéÒ¥Kˆˆˆ`OòX»v-1sæLvðVcccxxx@TTíÛ·gËÃåráááÁÓjÈ! žt „RGbbb8pàß¼I“&aÒ¤IÕÒÝÝÝëµL¿ýö[yŸ–ÕÛÛ»Z~ïÞ½ùî½½=ßyN¨ „BHP!„R'ô‹B¾ÓË—/‰#F@AA@eÃsÕ¨Ê;vdG?sæ ;ú„¡¡!TTTžžŽëׯW^Õ ³6ÕUYY¡©©‰Þ½{ó]çĉl§Æ!C† mÛ¶HNNÆíÛ·ìø]÷îÝCBB€Êi¨«ú¹Ñ!„|ljzÙ²e˜7olmmñúõk6ïàÁƒ¸~ý:"""x&Ž[ºt)Þ¾} ___„……âââàáá·oß~w¿°ÿþûÎÎΰµµÅÁƒk\ï?þÀÛ·oáåå…˜˜@xx88€·oßbéҥ캻wïFxx8nܸþùççÞØÚÚòtóOKK£ ¥H³åããÃŽ-Tu5Kaaa :¸rå ›~õêUœ>}~~~hß¾=Œ€˜˜”––ÂÅÅ¥¥¥øë¯¿ «« gggÁÅŇÆï¿ÿŽ]»vÕ©LÚÚÚ’’ªµ±~Ñ¢E••…‹‹ 222°lÙ2`ݺu°´´„‹‹ öïß+V@OO7nÜÀ7‘‘É“'c̘1055ý9ÄÃÃgB©ª) iŽ&Mš„±cDzËnnnؾ};UL# ¦¦¦xõêOzJJ Þ½{Çs‘üæÍDFF‚Ëå²é=Bnn.ÂÃÃadd ²oÉýû÷ë\&]]]vŠÚš ÍÃGã½|ù2¼¼¼pöìÙ×ÉÏχ··7Ž;†¥K—büøñ¢Ú%MNBBV¬XÌÌLìÚµ |× ƒ““† ‚¥K—BQQñ›¿ëáÇHIIa—‹‹‹!##III„……ñý;€?VËOJJB¯^½¹¹¹Õòß½{ÇîKaaaµü—/_‚‚‚ ££___žüøøxöÿÑÑÑ<Ó5T]ˆ~ºîç ê\.—ç»>ÿþªí}øðï¾çææ²²²øæ“/‡žžž`È™3g¾¸‘èèh¼~ý<€¾¾>,--yz¼æää  ÆÏçåå!%%ÞÞÞô+’zeff†Ž;Öùó;wîÄìÙ³¡ªªŠ%K– 00ïzˆŠŠÂ®]»pþüyLŸ>'ÿôéÓxÿþ=ßÏFFF~ùå—jà÷ïßGbb"úõëÇ÷³¸zõ*®^½Z-ODD¯_¿Fxx8ßÏÛÙÙ¡¼¼/^¼à›?nÜ8x{{×øýÇG^^:T-¯}ûöðööFtt4ßéZ¶l ooo„……áôéÓÕ• ãäÉ“8sæLç¤ÀÀ@ܼy³Æº!µSPPÀÆÑ·o_ôéÓçÛÈÑ£Gqýúu6ÃÒÒ¦¦¦øóÏ?áèèXï…þü9èW$õêâÅ‹ß@~&.—ûÅ¿‘ 6Ô˜÷¥· üýýáïï_cþéÓ§ùžÜ«ט—’’RkÙssskͯ¨¨À¦M›ê¼ïäË233áàà€uëÖ}{éß¿?ÔÕÕÙ Aþ‘ÉÉÉÁÞÞ¾Æüþýû£¤¤„oÞæÍ›aaammí:¿««+&MšTãㆯ±råJÌ™3ªªªuÞ†³³3-Z„víÚÕy .ĪU«Ðºuë:oÃÑÑnnn‘‘©ÓçÝÜÜ0zôhôìÙ³ÎeX¿~=&NœˆnݺýÐ?’ý}57n\­'Û¡C‡ÂØØ¸ÁdqüÕ—ÔÔT¸»»ÃÍÍ­Až ½¼¼Ð»wo 0 Á•mþüùظq#Z¶l‰:|õçØ¢ªªÊ÷äøêÕ+äåå!==JJJÈÌÌ„²²2/^ŒÍ›7¤¤¤ !!ØØX´k×î›Û?tuukÌSRR‚¶¶6 ê\9ŠŠŠèÙ³'û ¸.Z·n^½z}× H^^zzzß„äääÀápжmÛ:oCVV}úôœœ\>ß¶m[ôèÑã»~“6mÚ@GG½{÷nTWiÊÊÊHOOÃ0èÔ© "##‘˜˜È®§®®ŽØØX”––¢U«Vßü=šššßU¿õEÇ_}y÷îäååd½UÝÁuëÖ­A–¯eË–àp8PPPø¦Ï}ñ-¬£GBEE·oßPùÖÆÆ†ç¤¯«« ssslÞ¼»ví‚°0½Lš&ggg¼|ùçÎcŸåcìØ±<ë>|›7o†²²rµÅåráéé ‡ƒ‡ÒAA cccp8ìÚµ \.¸pá8Q^^ŽÒÒRìß¿<aõêÕàp8HKK«ñ;rrr0räHÌž=›c­¦?@" †††LAAsäÈfË–-|×ùøñ#cbbÂ0 ÃLž<™‰‹‹câââ---ÆÇÇç‹ßÁ”””ð¤Ý½{·IÖçÈ‘#™ôôtæìÙ³ÌêÕ«ù®STTÄ 0€a†™={6Î8::²ùƒ brssäþõîÝ›a†Y²d ÌwË—/3ÎÎÎ<ë7¥¥¥Ì¥K—˜øøx:±|féÒ¥L~~>Ã0 ³råJæÜ¹sLZZ3jÔ(†afâĉ̋/˜›7o2¿ÿþ;ϱãããÃxzz~ñx²°°`yŽ?~è¤ÐÒÒÂüùó¿jÝ•+W"++‹'-<<œ*ñžžž*Çf266®Sã ù¹8€ëׯãÈ‘#ˆŽŽ¦ ù„››¤¥¥ñìÙ3ˆˆˆ K—.ô‹Ôîþýû°µµÅãÇaoo-[¶vìØGñœ<§L™‚—/_âï¿ÿfÓ§L™[[[œ?¾YÔ×Í›7†ßÿt52ÞÞÞØ¼y3¦L™YYY,[¶ ¯_¿†­­-®\¹HNN†­­-lmmÃ^LU¥Í™3Ož|8³fÍvÙÜÜœqqq©ÖŽaddÄ\¹r…a†‰‰‰aŒŒŒ###æéÓ§µnÔ¨QLZZßgé Ã0S§Ne¢¢¢fß¾}̾}ûfàÀŒ‘‘Шêóóú?~<û\·JUý={–m÷¨ªO###¦   AîÛ›7o###æ¿ÿþc†aRSS###Æ××—g=ÆÈȈy÷î]³ù;úüù<¿çõòòòìoÁ¼}û–7nÏg>}†ûömÆÐÐÙ³g£¡¡Á1¿þú+Ã0 3þ|æöíÛ Ã0lfUÃ0Ì»wŒ fêÔ©Ltt4“””ÄÌŸ?ŸyóæÍ¯'''žã»ª ôþýûŒ‘‘®{ìØ1ÆÈȈyñâ›¶}ûvÆÈȈmKõðð`ŒŒŒ˜œœžï±´´d-ZTkY¨H#³wï^””” K—.°°°ÀÅ‹1wî\ìÞ½–––˜6m-ZÌœ9@åLuUWÆÆÆß<ë!?‡ÃATTTËU“ªÆS³´´„””¶nÝŠöíÛ³˜Îž=‹#GŽ@QQ/_¾Ddd$6n܈ÐÐP´lÙmÚ´­­-œœœ`kk CCC !!ÒÒÒ(--…ˆˆ233aii‰®]»bݺu––†™™úöíÛ¬'‘µk×®¥ÃµñÐ××Ç›7oвeKtéÒ‰‰‰èÝ»7äåå¡¡¡Ö­[CCCêêêèÓ§ÔÔÔ`aaøøxˆ‰‰¡S§N bPHBj£¬¬ÌólÿóeèÛ·/^½zqqqhhh@II HJJ‚¸¸8îܹƒuëÖAQQ>|€½½=ÔÕÕ1bÄ #//-[¶D÷îÝ¡  €.]º@FFRRRPUUŘ1cðúõk cÈ!ÐÓÓ—ËEpp0,--¡¯¯ßì'º!„4‹»A°¶¶ÆÆѵkWª`ÿR»)¢²IEND®B`‚snd-16.1/pix/env.png0000644000076400007640000007055611147553266012460 0ustar bilbil‰PNG  IHDRÓǃsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ- ´õI IDATxÚìy|L×ûÇß³f&ûžKÄRû¾V«Úþ¨Òh•R%vj«ªjK©R”ÒZªªh¾-ZK•¢U{í!"‘Eö=³ýþ¸É$ÓD¬!‰ó~½æ•Ü3ç.óÜsïçªË]xSÕ¹\q÷L&ö¦çGÍ92³%‡C `21êŒd_½IoS ÇÁ„ÒU‹Ú͉;. ™;{{ %&“©Ä¬F£Œ¨TŒŽFÔjŽvÎèõº»ž"35!™• g'LFÓ]÷1tdÜLÁ¨0b2ÿ+ zl6§¡48c0‘ÒY¡ ½^GŒÏ5\z×A¦‹.(–æ6¾ÛɆLB³£-ÒÚØÔf´Û‹|sáW"2™îö*®íe›áövöøk«¥K$*7±Èñ5r5Úªi·tÉDæÞ~d¿¡•“Ü»³èÒ/ì5^F®U‰+(UŒrºÜœ» ˆÁ Çd0`Ôé1ªL zÞò7oÞ¼ã>_|þ9N޶Œ &lÞü ë~øÏæÌ¡zµjæ¼ñññÌþì3ªzWedÐpLƼsé ˆÞˆQ']t‹€º´¬×™L†\&G.—#“ËËåæí¬¬Læÿ»–\Ù=(—àéäžää䟔À‰ÈÎ$ÁªºsAÅÄ`B%Sv ‚K>·ùÔp›‹‡ÎÚ@KíÖ-˜áÑ‹ÕG·°!'•‡Åñ]ÕÖÌðèEZF:Éi)l9¿—0‡4”ÎÖ¦2˜w}éG#IÕDaߨŠðº¥ŠIaÄÆ» ˆ &cÞûÛdÂd2¡ÓéÐét%x-FiO½“Rú¿AƒúØÙÙñéìÙLU½«’››Ëœ¹s¹zõ*ƒ¾-ícÎeá Œ¹’€8;ØR˧’Y,ä …ô7ï£+ÈÈÌ@sFEv®™B!î¸àŽœ¸p†±ßÌÂd«Äh4aò²æY_†xuAm©KDž÷BöÈÔòI‘¬°&8ñ£<^àõ€.tÓµcô¿_“äVð@äR!þuÿï,ض™ƒAO¥gjòKÿ¹˜‰Ü$£’•3ë£öówÚEÆùtÇ[íBÐÉ¥X9Ù°°Æ@nÄF±èæ6^óëDG;ÈØŸzŸã›kZFƒ]jUå.ôvkCMUŒ˜ø'í"?ǦŠÖ•YÕúp2- g…-Z•k#ÿäHÖÜÔ¼åÑ‘úVÞèdv%žâׄãäbDPô¯2&Œ&#&£ñ®b4™¤÷wž€TõöæË… ŠÍ¿eëVé¸&£Ê&ðª\™ÏæÌfÚûÓ™4y Æcã¦MÄÅÅóÉdz¨[§Žä±¥sõ@ôúBÍUrdr¹ôW&“¼y7"“ɤ‹Õ§›šU«óþq`§æZV,[âÒÛ­5ULŽ|¾ö+Ú7k¼™Ô *G†Ve…üvÆÔ,vÄÿË(Ÿnüõï!¶þ“°›°~µ6jGÉ»0éó½æ&L÷rBf­âxê®æÄ ‘«¨”mËòŸ×òΫ}i§¯Îßa‡9ãNC÷ªx]MC;¼Õ.¬Ù¶†æ>žôpjÆÂ5Ë«”Œï÷.‘!ádj ž “ÉD_×ö4ÓÖ`ÎÊETö¬Dÿn½‰‹"B‘ŽF®Â6ÖÈÚ]kÝçzišp:ô<¯4kŽ¿Þƒ¯×CÍê5èû\7Î;ÇE×d oFðQI/u“јç-ÜMq¤÷·)O@d2jUñM­J…œϤ/ð$ŒF#övvL™ôs>›Ë‡3?B­V3kæ‡yâ!‰ŽÉw.ƒ¡°b4{ ’€H"anº’I¾˜˜Œ’‚‰&,A‰ƒÉHöítH0‘INîmêvðærh(;®'Ú[Yîc0¡KËæRJ$q79¨»‚º…F}AY5*¤¿½œ˜TCÚÙpt¾R™<~þ›Cÿ¢‡álZt—8^)„ÿsmJǪÑÊì»Áéð†?ÿ.…šÁ¯öäæäàktåà™¨™w]Fìjpñʶ]:€]Þ’õ¦Ž¢!§ÿ†:ðÏé#ìˆ;N‡ÔÎt®Úõºdª·pÅÕÁ™á¯D¡P`ÐéñI±åxÂe¬k¸bÑÙ(ˆ,¯|ï¡‚.Õåó<£Ô¬e2Þáy,øÎh‚4+ª<ñ‘ÉdØØÚ:V^sY®¡¸NtCÞõÈòÃR4 ‹‡L&Cž"DPWo\cζoÀM2 ' iºLœœ°r¶ÅÝÅ …\^œoŽI/= *¥¥VMgd ¹¹¬šTR!>zá$Ÿÿùrg Ã;]êXÏÒå wÒ SʤMgäFR ¡)7éàßµÚŠ¿ŽþÃ-y édc0Yñó÷ÜÎHÆÎÚ–Ôô4Ôî¶…žlHÕeàæä‚ÆÍŽjÕ|P(¤¦¥¢OÉÀÍÍ+'[Ü]HÏÌ +9ôŒtnY¼š”œ \쾆Î)ƒ—^ DX}¥1Oî,ú!yÏ„ “‰¼¦¬; y^ŠIoÄd0Tô²²ùbÁB¢¢£>l(Û¶ïà³¹ó˜üÞDªVõ–*:yç2Y6aÌ£°rssÈÌÌ´è÷°èQ(ÈÌÌD¯×aÈU SŠÂ/¸3 ë4à‡É_"·Vq6>Œe¡¿±õæ!úVéÄwCfc’ß%m2IÉN'"-†ÀÎÝiÕ¼3N­!Q›Sð>Ï+³/¶íL£F[«ø=üGÒB 0…<¯†/=(:Ž1ÿò\áèõ:vÝ‹ÎUÍžøÓÔ±÷fpÏ~¤è2ÐÈT¬ÚŒÎUeqMëÂvÓÏ«F|J£&<â›÷î@å' hR«>ký>ÂKãÁ/»~#ZŸÌ¶ðƒ ÷ïÁ×ú“aÈAmT0ó·¥Èm³1êôȌ⪧¨ €ŒóçÏóÙ¼ùwn®QfÎ@–ÿ,˜òºò¼å;(H^3WanßNà‹_ÇïOÅ¿^=š7oÆô3™>c&ŸÎúH“ £^ÑÒ1™kuÞ<ÉÅß# š²(ð>Iiz½žxc2½ZôîÈç}OÎ…8óvtB,™šX¶ªr5$eD±™IÔôöáßó§ÉmáÌg¿~É“ÇÀn¥Ýæ³ÃßS9J…<Û@ÌÅóÈŸ÷Fn%½Ôog$3wçJr¯DQ¸xã*ñ~2ææ¬&äÀI°6±ñòŸäˆ$1% ¹AÃ…Äpæì^Eî•ÛœŽ EÙ܃‹é‘Ì:ú~I(²LÄ%ÝæÂ­0\:ø2;x§BÎB5Øyœ‹—/á“b‹>=‡ ‘W¸f¼Mk/vû›K·¯#O×süÊ µ4L¹DìßßR5ÅS¦ž˜äÛ„&†#kæ†É`^¼ÀòŸW»×éõ¤¥¥Ý1_Ff&ù¯_³WމÄÄD¾Y¹²Ø}ÂÃ#¨_ßå•=iÄב£G¹ÁûS'S·nŒ&#öövL~o<Ÿ±Ÿ7ofì˜ÑÅ{ F½c®T›‹õ“c¼‡qôžöÈ Ä@ÁØœ~”\UäÕVp™JCzn‡áèì2ÁÚHˆ>cC y›³O ¯™‹BcMNn.瑜Tdb”ë‘ùÛ£ÌÒ¡Ìë3HÉMcsÖ¿è”™ÿ®r¹ŠÍiÇÑUÍ@ieÇ_ñgÉqÏ@æb‡Úh"+;›m9'Ñ[e"oê†ÒQ‹A§'JžÂ5U F\LÈ<ìЙRØb8…Á”Ör :B•·¹ ¼ÑJ¬– +*GÒ³3ÙŸt¹‹YcÔPÈå6T‘Õ:p¹—#*µÒüà fÑ‘þþõX³ú›;æS(”ÈäyÍJ¹ú• •ëÂåN®T`åfWìqÌé&°r²±Ø_.—£.tmùÇTY[µ•Åq”JJwµe¾ÿ\SdZ,ó¶|ñ3ÿ"s“cålcî7ïc«[es…x†Åx ‰ qdge +!$ˆÑKRb¼4¼Vg 7'‡øØ(LF]‰3•2ÒSÈÍÎÆd0`2‰‹&';€Ô”;ÇDLNÌF–÷ÞÏoú’u|­«©öø8yIÜ9à!0äè0¤å ×(QÚX‰ÑU‚B%S`£°ºçîƒÉHº1¥5ÜG—Bº!•\F¦ä^÷Ò™ôdusõ\Y¸»À1$f’ðÏU²’ÒÅA´N¶¸´õ­èQ)Õœô$_ˆbtó×x©k@tê  “ 6þÌbßÀ«@@22£ 'GÜÜì…€ÀƒÁÀå‹‘9™ç5ÏÊ  ÓJ w¡°^H’$Q ‚D®0ë…ð@@pˆ…€R@ Jô@rKQŠ€n@ ¸ JEA—‡4 Kq÷>¸¸xþþû°^)áááA»víÑh´Âà‰‘››Ñ¨/ÙÉ‹ ­,H¸»€oÁÅÅÅb}tÁÓžžÎèÑ£+´ZGa@ðÄÐësîA@ÿ{ìD÷Ýw±±±V~DÄÆÆ²iÓ&…p‚²OáAW…š°î½ÄÉ­2k1ßða‘Á͘Dâââ„-Aù¹¼h–ò>†ñ*UjRn_ÃÁ^x"CDD$J•ú®ù¶oßN—.]ÌKM–Dtt4ëÖ­£R¥Jôïß_Y ‚)SÀÊJÜW Ü{ Eš°ÊÀD—^zž—^z^Ü¡<|}}ù1¿üòËbÓ›6mÊõë×Kí·\½ F£¸§e½{!) zõ¶ÜÉ‘[6a)ÏùàƒO‹ÝNJJ&0p¯½fÙñ}‹ÀÀæÏŸþUìqf̘]â ^))©ôï?Ì|œàà-F-úšíÛÿ0§¯_ÿƒ+ÖmÞõê¸ví:ééŒ3ŜŊ5ètº'r#SSSILL4oÛÛÛ“šš €N§C.—‹¦IÁ=‘’ýûÃåË ÓA` ”b}BPÞ=‡…õ0899røð1ZµjΩSgÑj5æôà൰È?fÌ‚ƒ×š·йs.] à÷ß÷еës\¾|“ÉtÇIŽ&¼Ï’%Ÿãà`@PÐD:thCxx©©éæs¼÷Þ Z·nA¥JìÝ{€·Þz„„Dnܸ‰F£aáÂ¥ üþìÙ³Ÿèè||¼¹­vïÞMhh(—.]bÅŠ¨Õj† ‚Z-Üš>>¢Ä JäÆ øæX±´yÞxC‘àà»ïÿûï¿ÓµkWaȧ¥¢¸&¬Çä¼úêÿñí·kiܸ!»wï£k×Î%æÏÌÌ´•+WÂ,¾_µj]»>wOç0à]óH¦+WÂÉ$<ø­"y»w‰Þ¥W¯î„…]ÃÆÆšJ•<èß¿sæ, !Aªùwéò,;¶-[U©R•JÅܹs ¹÷iܸqdffZì3jÔ(Nž<‰½½=7¥]pWæÏ‡©S Ä#Ÿ×_—¤W/øï4±ŒŒ Þyçbbb¸páþþþ,Z´ˆ€€aЧ±˜Høøš°ªW÷ÁÞÞŽß~ÛI||7,1¿µµµ…R˜«WéY³:»wï»§s¯]»ÜìÜ ãÆ±páRNŸ>g¾†Û·øôÓpqq`Þ¼Eœ:u–fÍý˺nݺԭ[÷ŽßûùùI³··§cÇŽ¢” î‰}û N¨T©èw¯½?ý?ÿ,y#…ùä“Oظq£y{ÿþý¼ð üúë¯4kÖL¶¢ Há¥ä…Âó>Þx£ÇŸdèÐÏ"¿äìÙ àüù‹yMO£,ú@Nœ8 À´iXµjãÇqíÚu:w„Ùô&ŒdĈ æãìÚõ'Z­¹¼ ÙK«Õ˜mQ³fuär¹…‡âììÄûïl>ŽN§£víZ¢T ÊGÂéÓ0lØóôî [·BNNAšÁ` ;;»HÞ˜˜~ûí7aØŠ. ŠÿÌDW>æy ÕªUeîÜ,Òòû@þKË–M‹MoÔ(€F$wyèзï¡6_›õë¿-’þÙg3-¶gÍšfþßÎΖ©SÇñ –/_(J‘ Üsè´hw{ôGŒ€eË _¿x¶nÝÊõë×ï8šOð4È&Êd2ä2±ˆ@ð´ðùçЦ ´n}ç<¤§§““sŠ5k™1ãC¼½½iÛ¶-½{÷.’_.—›x*.r™ÜÜj#b\O7n@B4jTvðàA®\¹b‘ïðáÃäææâëëËsÏ3nxç 6LKKã÷ß7)R÷ôéÓ…Ÿ"X@RRÒØ½{¿°àC˜„­£H)¸3&dgÃÇCá÷ûÔ©ð ƒìŽ5àç—‹^_ý- M›6ÔªeÙ—·xñb¬òB„„ÀÊ•RD€×^{ WWW222¸~ý:‡â³Ï>7LȽáëßFXïp`ÿaÁÙ²~ùfÌ€Âï÷ùó¥ -ZÜýׯ_çÀæí>ˆ£mÛSìÛC‡Í[̬dêÕ“D¤0ù£ýΟ?O||.BB`Éh×Þ|³øëÉ?þ(Mî½ÏfÅjÕ¤Oá9~rù£Ž àüyKD æ—_~m¼¾}‡e‘n4ÉÊÊbÞ¼EÇ™4é~øa£ù8 . ''NONN.YYY b%¥ÇÅ–-ðê«Å7q"ìÜ .<Ü9/†Q£îD&“šËÖ¬Âc6lØ@ß¾}ùùçŸ •™…Ó¦M06óÕWKP(Õ'¥P|µ×Ñ¿?|ÿ½(g‚Rö@ŒF#2æZ»‡‡»9ì¹Z­6§ggçpòäúöíMÍšÕùçŸÃ´mÛŠ‘#'²nÝ7dddròäÚ´iaöLþøc/Ç~àk«SÇI“Æšƒ&懋¯[ט˜X~ ™LÆÜ¹R¼GGÞ|3Í›·YÇÍÍ•?œbŽ#–œçŸïÄåËWiР.:´¥ì1‘™ ¹¹àèXü÷VV’÷qô(øû?Ø9–/—^¢ÖÖÅ¿k×.rss‰åÂ…] *ªª^ zƒ5kÖH±„òÊLZ|ò ôí 5j”;ûúJ+Lîç©]»6—/_ÆÿA +béNW¥{÷—8{VªîEEÝ"99…¶m[ñý÷ñõ•ž–üŽ7™LF—.ϲ~}099¹tèÐ¥Ri¤¤ó±‡ øpnW Kø*• ó¢T“'-ñ82™L¬øW†ˆ‰‘^ȵJŽüâ‹RhòAƒìþ ï¾K¡²8Ì"2mûöíQ©TT©R…Í›¥Žîÿ…o¿•ú)þ*jÑ"èÖ­üˆHaÞÿ÷?iû|úôéC`` ={öQÈÃsýz$;vì¦aÃ$'+ÈÈÈÄ`0`2™puu`ïÞ¿qvv4{ …œ'N™‰R*•4kÖØœ_¡Ó¶mˇº¶óç/²`ÁWÔ©S€zõꔘ?--ËŽ»i×®å]gÝúøxsåJYüóÏafÏž!J[᫯`äHéïÝE)†“'O𛮆©SpõêÕ.ÜÝE¹RJ4nü ?S$= Àß¼¦8HÍ]š†V­š[ä÷óóÅÏÏ÷‘^[«VÍ‹œÇÍ͵ØÑRNNŽ Ô¯Hz§NíKÜ~ñÅçE { dff2~üxV¯Þ€\žÃܹJzôèÁW_}…c1"ù}!ž **½^Ïš5k,ò4oÞœ… ¢R©¸rEK\L˜y+"?MšHŸòŠ««Ô×”šj) ¾¾¾\½zõ¾ÅU ¤\ñ°}(‚²ÅÍ›7Y±b…y;''‡õë×£T*ùî»ïÌéóçÏ7ŸØ·ÏI“P*•E&æå“?dwòd1ânôïߟï¿ÿžY³f c)™ÜÜ\¢£o•É•„B+U’’’É)¼'P¯^í2qíÙÙÙÈÔ"œûÃrþüùbÓ·oßΗ_~ÉÁƒ˜0aƒ õžgdØ1ožŠ%Kî|ì#G¤ØB<,™1CZ W éò@hí<¹u;±Œþ*G\\=°ÒhI2Úr;»L^¦W5¢£cD)|H¢££‹M×ëõ4kÖŒ±c‹Mgk •*ݹ/äÛo¥]: yþµR?ˆ@ÈamcÖºìÆÿW[iA&ÃÅÕ£ìZ_ÆèèhÆŒcÞ§S9}SvéÒ¥Øôf͚ѦÍ×­Q«¥„óçƒR µ¥Ay˜LRÔÙS§0G¹Ü???T*!!!Ô«WODÈIŒ½‚‹³c™üQ‰‰IÈÔ.ØÙÛ““…MÙl&º|ù*ðdæ‘T®\٢ݿiӦ帻݀ßÌ)Ï>û,ßßCûŠF#Íg˜;bc ÒkÕ’ÄEpg^xví’þæ9Qz½^GHɨT*ÜÝËf|§¬¬L’3s°ìííÊìz gΜçI­R±pdôè™2%¥K—Ò¦MÚ´icŽ{ׇ@)‰Eሕ* «Þ¦Maûö<}ˆh¼‚ ­­-jµ…BAãÆïY<òÑj%ÑÈÿŒ.]ºðÇCy²$%%3uêGeÞ€[·nçêÕpQ’ž óæÁ¤I’’Bvv6Â(kkiyãB‘\hÑ¢GÆòd1$%%—y:88`ee%JÒ$%„7~~Òú#ׯ [<­”ÚDÂK—BÙ½{£F  (hK—âT5 IDAT~Áõë7X´h9:ÄÎÎŽ>šŠ§§;«WÿÀž=ûxé%idÁ``íÚ ìܹ[º`¥’Ù³gP½ú£[===ƒeËVÒ¾}kNž<ÃàÁý±²Rqƒ'Nqƒ FpëV «V­£^½:4j@¥JØÚJý‰‰IlݺƒÄÄ$s~Aérë–hr*kxyy…———0†#7WGrrAݸ¸ÛètzNž<ËÆ«ðôô 22Š… —2qâhBB.¼€U«¾7¿Ü:jNÏÊÊfèÐ1¬[·â‘]ë²e+éÔ©Íš5&++›ììlöí;@³fèÕKŠßµgÏ~4ð'<ü:C‡4 8rä_ìíí9pà0>>Þ Ø€Ã‡áááNÕD)+EV®„wÞv(KŒ1‚eË–ñé§Ÿ cTpžHV«VÍðô,¹ºGÿ{l×Ó¾}kš5k @§Nípp°§J•J|õÕ·lÜø3GŽ',ìNNܺCV¡T±±±dddàáán1\ØÝÝ­È †AEcÜ8iýyð@Ê7þüØÎU4¬I\ÜmF†““4×¥eËf¸º:[ôy8;;£ÕjˆŒŒÆÆF 8Ò €üõL‚ŠŠ‹ $$;yÄԮ틳³“y•¾7ÞèÅÆ?Óºu << BxªTJ<==pww¥Q£sþÀÀT®ì‰-:µ3§+•J¾øâѺÆ7Ф=ûl{""n°wïß} õëûóÍ7k¨SÇF¨W¯66Z¼¼*“˜˜Äš5ëEÈc", ôú‚ä‚'ƒ»»eh÷jÕªamm-f¤ yp¬¬¬ BPPÑXcÇ7ÿïééÁ¤IRH·ßîËÛo÷-’¿oßÞôíÛ»ÔŒp§—}µjU-BÍç{ Ó¦M(6¿³³“¹DPúäæJaGòÂÝ»wóüó"„þãføpøúkøðCi[­V#“É,VjTLÄDBA…aÏž=<÷ÜsÂAy÷@e›„„¾þúkóö­[·„Q„››ô7>¾àIKÏf×î¿ËäÒåæRï!r¹‚«df•MW:#=µõ“‰…ekkËÿý_ÁH· 6”Cggñ?i<<¤¦Ä¸¸AAA,]ºTFÈÓɶm»8tèh¹ˆ ü´qø0´lY°}ìØ1š5k& ó™0¾ø¢`»jժܸqCFHÙeúôOh¿•+¿'%%µÄ<µjÕÀÁÁþžC’äÏD”>»vA×®Ûbˆ@ðøyèy 11±ÜºKåÊ•øé§Í¸¹¹òÆ=8zô_Ž; €““ýú½NJJ*.\¢uëæ¤§§sêÔ9ÚµkÅ™3çùûïCh4V 2€œœ\>Þxzzpùòš6m”÷¢Öâï_לÿæÍhêÔ©u×ótîÜo¿]Ë·ß®å‡6Ý1ßðáƒHJJæâÅPV¬XCrr jµšK—B9xð0QQ·°±±!33Ë, ‰oaëÖæã„‡G°kןyMb6ÄÆÆaoogþÍö5/Ë RÝ/¿ü–÷m +³óRÊ /‚Luò"!¤¤¤ ×ëquuÆ)cøøøp],š.<’2äm<<,£¨U©R™¾}{a®É&(h‘‘7Ík›;880dÈ.] 5{ùtíÚÙb§Â¼ûî þøc/]º<[âuj4L&mÛ¶B­V£PÈyã^œ9sÆ kk­E?ŠZ­¦ÿ>¤¥¥›Ó^~ùΜ9½½ÖÖZ‹œ'¿Ù C‡68::`kk‹J¥ÄÕµlˆ‡ä-¥[l—WbccÉÉÉ¡jÕªâ‰~Âôí +VX6aYYY‘m®˜ „€XP»¶o±é¾¾5ðõ­QìwZ­??ËýªV­BÕªUŠäõòª\âùï&ùä×ü«Tñ²Hæ™úÅæ·³³-vYÚÂù /Žu§ãÝ-ÿ“ ..ŽiÓ¦ò”"ÅÓ xhjÔ€ðpË´O?ý”éÓ§3þ|a ! ‚Š€§§'«W¯6o7mÚ´Ü\»N'uÖ ‚r* ÙYÙ„††•É•€µ£711q$$$•ÉëÌÈÈ@©±°î—Ù³EÞ²L£Fpê”ô¤¥´Z-ñññ¸‰C„€8¸U'=-­Lþ(G7G]ܱR«±²óB—›[&¯³vƒV„] ¥ð!Y·nýúõ†(#¼ö¬][ ...8::&Dˆ„\.+¶àQcmëˆJ•…BsŸ{FP¹Òýíe0¹¡ÓÛ“™–Xê¿M&ðQpéÒ%êÖ­+ !”IOŒÄÃÃ¥T/îæÍ(ru>TòLB«œÜ,Õó%%ÁÍØñxxöD—ƒ““c©žïÌ™ €hÌ¿L&!¼eÊ•A£‘:Ókä¡éÞ½;«W¯¦eᘂ§W@JŽŽ¥zq·nÅ ×凹\,ÕóegCRR<žÒ(±Òþ}¹¹¹B@î“>€?v(ËØÚJ“<“ ±®U«W¯^Æ©`ˆpîà‘óê«°y³°ƒ2Ld$Œðå—RóÀo@µj•e™?.®]7½"ñÉ'Ÿ0}útaˆ2Fݺpé’eÚÂ… 7nœ0޲Á?ÿ@»vÒÎÇ dãF)ý¿œ= ü!nzEÂd2•…YPvÉdæxt‚ŠÁ#HøÃ›Ìq£œœ™0aƒ×_Hóæ©Q£aaט8q4ÖÖZ&NœŽ››+·o' Õjyï½Ñ4hPïÎýã /A¿þ6l€Œ سÞy^xáÞéÒæÏ_l^„ª~ýºŒ;‚ýûD\\<'Nœ¦N?ÆAJJ*_|±„ØX)4¼¯o Æ ÂÝ]ÄkzPΜ­VŠú*(ûÌž Ó¦IB@îJ¿~¯Ó¯ßëyµý üôÓ/ôìÙ^½ºÑ§Ïk¬[·‰iÓ&°jÕ:†}›¬¬l>þø}\]]ˆŽŽaîÜ…,Z4÷žÎõå—ðóÏRg]t4ŒYrþááV- ƒaÃîÿ·mÜø?Æ Âß_ŠàwþüE ¯¼ò2/½ô<)SƱhÑׄ„\æôésö C‡¶\¹n±®ˆàA¼üš¬°Ey@¡(ˆœ,U*pss#44?Q R˜ää-ZÎùó!¤¤¤Ò®]«÷©W¯®®6xÄpr++èÙ³ô 5}ú{Lœ8¨¨[ø3zô»€e·I“†€$R.—súô9‹ýkÕª!JÛ#&=] Ñogg'ŒQ±¶µZåè(->gkkK\\œ Â#ë¹r% ­VCpðZ‚ƒ×š£ì–Äï¿ï6Gë½_ÔjËÏý²n¤¦Þ{þmÛvñÞ{cÌ¿O¡PV´G^©T"/¦-í¯¿rþüÅ2sãoݺÅÀÍŸˆˆˆR;שSP¿>|ûí£=ndd$z½žêÕ«‹'¹ âé vvp劰…ð@îBãÆ 9w.„ÀÀ€f=66[[|}kP«VMf̘ÄíÛ‰øùÕ¤µúh._}%½5;thÃðáƒËÌ÷ðð`ñâÅæí3gJo™Ý7ÀË ¶n…Ñ£ü8…'¦ Ê'#FŒ`À€´mÛVCH …œAƒú1hPјD>>¯çy j*WödàÀ~\»v•JÍܹ=ð9ó…á¿lÜx§k„  ésÿšE‹>+ö»÷ߟX$M¥RñÉ'ewx©\.·hú‘ËËþ€¼ DÅòF×®RÅ!AB•J…N§†© <±·†V«ýA' @>_˜yóæ1iÒ$a! ާ§C‡¾-î€àùí·ßèÖ­›0D9C«Õ’õßY¾‚rÉ7aedøý¥zqƒzÏTÃh2òÏ¡fÄÅy”êùŒF¨Q˹\ÁÕˆNŸ -Õóéõ€¢|œ ¤æ‰'ÉñãÇEM¶ðÑGðá‡Ò_www|}}9tè­[·z¤Z­FT«Õè±\¤Þ š¬}¬†ñoÔþ±œçÀþ=å²àÌœ &ˆHpwll¤A-ùÈår …è yš$êÚ)Ôª²Y}ÎÉÉÁÖ± ®nz¬•?esá«„D%о\˜ÔT8qBÑö8ùôSiV³ üae% µOK+ù8hÐ †N‡„žFQ«øÖô)“?êúõ$§¤àê¦A&Û+“×yð+šò% &äæJ/…ÇIzúý »”<=ÁÅEjöÌ_ÄÚÚšÌÌLaœrŽç.(—ܼy“*UªC”cfÏžÍ4áV ¹æÏ_ÂĉÓÍñòINNaâÄéDDÜwCpϬ\¹’wÞyG¢œÐ¡üõ—eš££#IIIÂ8B@îΛo"“Ɉ‹»m‘nkk˨QèTÉCÜ  ‚Ò´)ÄÆJQ òQ©TX[[“z?1…O§€T®ìYì±+V¬æë¯WgN;|ø8çÎ…0eÊL¦L™ÉÏ?ÿúX®12¦L)ø$$Héë×[æËß^¿^ªUåç¿!œ¨R!*JZcÛÅEØ¢<3a,X`éÔªU‹ãÇ ãy0zôx¥RATT´9íÔ©3Lš4ƒ!C0dÈbbbùûïC¥~-³fÁ!ŸüæY??X¼XŠ*ºd øú拜;W¿<­ÕÍ©S§ÌŸ²<±+&Fê´wrlyÆÃªTÿ¶¨((ŸôxyUÆ¥˜ªå¤Ic¨YSвªÑhˈsç`Íš‚íü(¢ÍšIËã.\;C‹DáuH’“ËÏÏÈÈ`ÇŽæí”””rsí±±±Èd2ÜÝÝÅ\ž^6J)øivvAZóæÍÙµk;wR¾qs“"øæ3dH~m]Z ï™g¤¿Í›KM*¹¹RíØÓ³üýVÞÿ}óöæÍ›Ë͵ÇÇÇçÝ/7QhËýûÃäÉŒ·qãÆÌ™3GFHÉ,[¶’?ÿü‹ÈÈ›¼öZž{®#ß~»–ßßùs!¤¤¤òâ‹Ï?1ctî,-›Ï˜1Òß•+¥ p:ÀßKëZŒ%Í®]±B  ¢2%ãäÿxÕ½{w~ýõWºwï. $¤x^x¡³yy׫>÷\GZ·n‘W+–¹ßx£V…fªõìÙ Uq ¤K—.Â@å1ý!˜?_ØàI°ÿ~:=î`\‚GWkUJ±± üëÕ«?ÿü³0ÎÓâdddpúôÙ2ù£’’Rpö”ÆÚ†…A^Ÿk©pëÖÃ\'¸V…Pðtáê*5;&õ+J­δjÕŠíÛ·óòË/ #Utñð®Ov;àè6¶öŒr´ßã¦Î(“×é^EFÈ…Q K 1œ ¶—-[ƈ#„aÊ9ööðß‘ã={ödܸqB@žÉÍN“¡Ìþ°Œ´x2Ò¬QÈ­Ëä5ÊB@JbÎi–>ÑÑÑbÎ@  „¯¬¬¬ðòò"<<œbDJÅìô8¼*‹øUñc'+aˆ{­´äæ"“ÉP*Åô¥ŠÀäÉ0w®ô7_@êׯω'„€Tt‘Ë娨X >z½^È}‚F£¡f͚€ºuá×_¥rU«Ji½{÷&00ÀÀ@a r@™…e4šˆŽ¾Å­[1¥Z³Ž¾…Á`%¢L †ÔÿQ¹²°EEÄÆFŠ+wæŒeºó.ä‘‘““Ãܹ‹xþù}¬7nrþ|H‘ô¨¨[Ì»ˆÔÔ4Q"ÊiiRì¤ü9¥Ç§Y³fÂ0ˆþýáûï-Ó-ZÄØ±c…qʽ1Ù`0pûv¢yÛÙÙ•J…Ñh$>¾ CÙÉɵZ…V«aÑ¢Ï PäX±±ãsìÑh¤7M\\<&S~º†ÔÔ4Žý—ë×#qssÃÞÞ­V €-Ó¦MÀÞÞÞâø ‰èõ’Wbkk ™(• ’“SójQÖØÚ–¿Ù³ÑÑÑŒÉÕ„‡‡—ù¹üñÁ…g *⦅.ý)xj“&M8xð mÚ´RÀ† ÿãðá‚øÿþ 6ÿýo+ýuМ^§N-FvÇãìØñÛ·ÿaÞ®RÅ‹)SƲgÏ~¶nÝ)OA¼¼*ñÞ{£ùí·üôÓfRRÒ¸ví:¯¿Þ“öí¥àU ,eÇŽ?øí·Mx{{päÈq6mÚLnn.î5Œ¥K¿%55ÌLi³«« AAïàî^¾ûU®\ÙâeÜ´iÓ2w§OCÆâ!­èÔ¯/õ…DFJQär9-Z´àÀB@„€X²{÷>,˜mÞŽŒŒ`Ó¦_øæ›EæôÁƒG–( «W¯gÅŠ……òÂd2±fÍzÖ®ýÚ;ëâÅPär9}ûöÆÃð°k 6ÐâX³gÏ »pŒi`ëÖ½ƒ¯¯4dæÌ9ܺ%½jÔ(€7ß”:ùæÍ[Äõë‘åN@Ê{öHñÉ233±¶ƒ6*"ÖÖàã/„ jѢ˗/'==Ûü t! óç´i³ÌÛMš4¤a䥥Y¤ß)vV>F£Á"¿‡‡2™¬H¾ºuýJ¡ÆTO”œÇÌÇÌ| QA©[Nœ€Â¡°–/_ÎàÁƒùᇄ„€H|÷ÝÌ›Wðâ šÀСoãááa‘ž?DØd2‘šš†N§#%%k”J%vv¶ù­­µÈd2¬­µ¤¤¤¡R)ó<•>|¥RÁ`$%%•õë¢oßÞ88Ø“––FNN®ù¯••ÆŠŒŒLRR ÖkV(Dè0 4hÛ¾ùFŠ•×5‰J¥¢Y³f¢/DHôa„‚…ŒfÍ’þ_²džEúĉ£¨SÇììl&LxWW&LxŸÑ£ß% ÀŸÕ«—2lXÁHwßDÓ¦X¹r Æ5É8°€ŽÛÅ„ ï›Å`æÌ¹äää°`ÁR{ð ùðÃ)L›6‹¸8©£¾{÷—¨Sdž pv.ˆàož^ðh8z´`åGÁÓÁW_I+|®Z%mç÷…üóÏ?B@„€H¸»»±rå’"鎎ŦkµÚbÓ E±é+V|yÇó¿õÖ¼õÖi_|ñI±ygÏžQ$­[·®Û]»>'JQ)°iŒ'ýåÊlll¨,&„Th¬­¥U?†V­¤´–-[òÕW_‘““c±F l ÚdežÔÔT”J¥èD¯èµY%Œ X¦¯]»–U(Ä„˜¹ýä5”Œ^¯ñ¯ž"ƃE‹¤e£år©)«U«V¢/¤" H¶^Ξ}Ç…ÆýSÚ€NØá¿ÄÇKÍùÇüùóŧˆÖ­áêUؾºu™LF‹-„€T‰‰‰aÇÎ]¨Ôa½G@Âí8a„ÿpå ¸¸HÁÓIÇŽðå—’€€Ô²páB  …B¨< ˆ——ÇK^‡AŸ+¬÷°±ÖРAaˆ;púôižyæaˆ§ŒªUÁË Ž–-¥´M›6(¼Ñò( žôéÓçÂËà ¥ÌúõëÅ „O)#GÂàÁкukÑ”UÄd2q…ˆa´Ò J¯ÇºÎEZZ»ví2o—¥ðÙW®@­Z¢L<íXYÁ‹/–-Ð#/w«V­8tè­[·.6ò„ Œ H>>>ÞÈå¢ òQ‡Çã¥e2™ò´*{lÛÁÁpõêUpww…ä)¥m[X²¤@@Z¶l‰ÑhdáÂ…Œ?^¨¼ ˆ££ÖÖÖæP!‚‡Ûdff>öóÚÛÛóÆ*çÏŸ_æl“€F£ÁÆÆF”§˜3&N„ñã¥ÅÅZ·nMpp07oÞ¤J•*ÂHåI@¤—m‘µ3FNŽŒp'vìØÁ믿. ñ”£RIsB,€üzÎøñãY¼x1³gÏs„ž b&º L1a|ñ…ôHHõê‰ÈÇÉqu•"öx{{óé§Ÿ2mÚ4nÞ¼) $D ½^ i±aÃúôé# "03e ìÛ'Ú”<íÚµcïÞ½Â8B@O;‰‰Òìó¬¬$Î;G»ví„Q´l) H~ —^z‰ÄÄDŽ9"Œ#¤(YYÙŒ=Ùü¹pá" ­óqâÄisú©SgX»vƒEŒ®õë2÷3Lžü¡9ÿ‡-γyó6¾øâ+Q"ž çÏC¥J{777ÜÜÄ*KÚ¶… à믥m…BÁرc9zô(ÿüó0Ðc¦Ì÷>?¹s?2oOœ8o¾Yľ}ÈÈÈà“O¦ç¥Àòå ILLäüù‹<óL} ¹ŒÉdÌw±³“–Ç ÞÂ3ÏÔÇÞÞ€ääâão‹ñ‰Œ”f /[¶ŒUù‹B”2ÑÑ VKíë‚òA§N “I"2l˜p1((ˆ¥K—¢R©h!’’ORR23gÎ1oŸ>}Î\ó(¼fº^¯LŒÄÛoà»ï–qâÄiêׯ‹F£á•W^báÂe’wÒ«Ww³x ØW”†'Ì–-ðÚk›èÑ£Çc[ûá÷ßÁÓ^zIØ¿<ѱ#°b J¥’1cưhÑ"t:mÛ¶FVVVLŸ>ɼ}/“O{ôx™-[¶³sçn/ž€››+S¦Œ5O‚œ7ïKêÔñÃÅE ÍAjj ЏTO‚I“`Ú´d6m:Å{ï½—'ê°f° xž}Vò>–/‡!C@¡€#F0fÌêׯ£££0ÒÓ. ½{÷`Μ/ÌÛƒõÃÉ©ä‚ѨQëÖm¤gÏnXY©ˆ‰‰cÕªuæþw‹ŠV­ZDZc'ؽ{‹(O€Œ  ;KåÊ•qÉ Ã›ž.ì"¸»'b0À·ß»ïJ#³z÷îÍúõë zÚ䥗ºÐ¼yóvþ:æ‹ϵÈ÷å—Ÿ!—Kc||¼3æ]lmmÍß·k׊ºuýÌ‹8ÙÚÚ¢Õ„¤Ÿ:u|^3˜àqsð Ô® [·®bÅŠ¯…A÷EçÎ’'S§BÇŽQ*•,[¶Œ¶mÛ Œô´ ˆL&ÃÀ zc IDATÍ­hgáþ‹â¶íììŠìãêzç&lmE¸Œ'En.lÞÌðá/‹ekD§NÒgÁÈɶmÛ¢Ó騹s')))bHx)!æ<¥DGGhþ„‡‡?±k‰‰ù…·Þ2òÚk¯‰#x(‚‚àða8y:uêÄØ±c9uêcÆŒáÖ­[Â@eÁ‰ˆ¸AVV¶°Þ# ##󉜷råÊ ó4mÚô‰Ùà—_6ˆE‚++)èâÂ…°~=ÌšeÅèÑ£‰ŠŠbùòåŒ?a¨') ÑÑ1<ûl{´Z­°àCv“ÄÄcOåoOMMeüøÅ¸¸Ì{¢×qõêýå‡jÕ¤vwAÙdøpˆ‹“<’V­`Ð /ÆŽË„ hÔ¨C† A­V C= ©ÚÆF´W?,ÍÓ+‹/æüùnlß^½Èw¿ýÉÉç:¦N…Ñ£ï=ÿGI“ØDwMY~®¤I©ß}{öÀêÕ0l˜+W®dß¾}|øá‡¼ð tìØQëIÈ9þ"¹¹¹øû×ÅÊJMVV/†¢Ñh¨W¯¶°´À‚ëׯóÝwI|üñ389ý~ß>é ÷îÔ¨qï×`0HÇE‹FÅæ¹ç¤ðÒ2¹þþ¨Y³&¿þú+F£‘zõêáéé) õ<'|ÇŽÝlݺ]»þdÕªïHKKg×®? šxÏÇ9|ø7î9ÿ™3çͱ±å‡ÐÐPÖ®]ËÇϦOŸ;7½õ¬[wïÇ<ùþ®##NŸ±¼vŧCi•Ësç`Ù2°·¯ÊÈ‘#¹|ù2Ë—/gñâÅÂHOÊÙ»÷/F†7'J±©ÜÝݘ:u<'Ož±È›““ËåË¡æm_ßšX[k¹z5œ­[wP»v-š4y†5ª—8´6"â¿ÿ¾µZ…Á` jUo¥ªä¹sÌó=¼½«àääÈÍ›QØÙÙqýº$P^^•ͳÐ¥CJ \¿ÒË:%%•aÃ"prú…©SÇáàðhÕDFÂçŸCÞDv #GB|¼TFš4瞎“ÓmBBB ÄÍÍwß}???40ØãÂÌŸÿÉ]j}lݺümccÃøñAüóÏaÎ áöínތ⭷Þ(Q@Ž;Á‰§Q(¤§gЫ×+8::¼…K—B 5S˜6m3g~†««‹¹ßÆ`0òÞ{£Är©¥ÀùóðÓO’g¡PÀ¥KÒØüèèÅ´kgbòäi¥Ò©ÓÁmSpÜܤ™ëþ 6€^g{‚ƒÛÏòåËÑëõ´oßžÎ; ƒ•¦€ 6–ýûpñâe†}›W^y¹Äü¶¶6ôìÙ½P³Ã Æâí·û’ššNÆ hß¾µùû?žÇÙ³ÌÛ*•Š\IïÞ¯b0°²²¢gÏnæï7oÞÆÚµ_£R©8p¹¹º¼&‘×ñ÷¯ @PÐD222…€<"L& M›$áèÓìì JXºt3k×þHÍšóøàƒêåúwîÛ'­I1u*,Z$î{y¦sg©ùòÚ5ˆ‰Éï#q£gÏçàÁ?X¾|yÞ{n•*UúÿöÎ<<¦ëãŸY’™LöU"v±&¨¢ª-UE-µ UT”¶´ª”Rµ+E˯-ÕÖVµ†ªµÕª­AÔR{ì"d„ì™%óûcä2²MT"‘óy̹çž{î{ï¹ß³¾‡5jˆÙ§S@/þ†±c'I]X…±bÅj¢¢b¤ß·o'òäqíf+UòO¼8}ÚäI×`0 G=“FÆŒÁœ?_‹‘#ƒÙ²¥øò]îÕ#¢¢ bÅâ¹Nj*ØÚš®!(û¨Õ¦÷µ^=ÓJöï¾3uqA d²a4h0ìÞûµ£ñoär92™ ;;;>þøc! Å•pVVáá7IIIåâÅ+T«V•Êš“'Ï0jÔû÷Êa222¤sœHH¸ÍÅ‹Wذa3“'Ü™íà`O|¼)þºu›˜2e^^ž\¾|…Âtk666Èå&¾3f|É»ï RY£P(D úܽksP© gO¨R%™èèh.^„uëÖ¡×ëéÓ§ ú»cÄ kWÓ”ÍÈÈâÁÓ͈÷ÿŽ‹3ÍXºô=¢£áÊ•«dd¤)¬\飣-Ë–M0KÃÑѱTÍêŠŠŠ¢b1ˆÇ" ¯¾ú²ää0‡¤¤;­¥I“g ZËÈ‘ïQ¡‚3gNâÿ[˜Ž?J:gàÀ¾,[HPÐZ† Xèu;w~5k‚ ZK¿~½ÉdÌŸ?“)S¾¼îú–ä_éÍ7{´€¾}{–‰AôË—/LÍš5éÛ·o¡ñ### ÄËË‹ÁƒùòåÄÆÆChh¨Å/›VkêÂ8tº³lݺ½^OVVýúõÃÏÏ0M¯-ÏüõDD˜ÜÓ Ê¦÷'iÕ %æÌyH%(h6«W›&Œ4mª¤Gó "½{÷¦víÚ%šÿ%K–ÀÚµkéׯo¿ýöc¶Ç" ;¶ËæéYY³&ç wuuÉ3<‡¡CéÚo¾éŸ+lÆŒÏòŒëãS£Àk—6bcc ¢gÏž\½z•õë×ãïï/y~˜„„–,YB÷îÝ‰ŽŽæ§Ÿ~bàÀÒxÐÃ,[¶Œ‘#GJ­ÀÈÈHüýýÙºu«äRýÁZLFFÓ¦Áo¿N§åÔ©)œ9~~~tíÚgggªU«öŸïûÔ)ÓÚOOÓ ®¢0h̘ÍšY~ÎŒ0eŠéÿÇMf&üñ‡iúh`é·n ¸ºZ?=&M‚™3-_à˜žnêvÌÃïh¾÷ U«‚RI¹ÆÞfͰf1x°ITöì¹Í?˜f{@ݺ0eJ —.]2KcÆÙÈ ÝàÈ0UΫU3MJ±„ü‘Ñ£G“™ir95qâDvíÚÅ/¿ü’«l—Ê.¬ÒFÇŽí¤½AÊ cÆŒaùòå¨T*7nÌ!CèØ±#yÆŸ9s&Ÿ|ò ÞÞÞ4nܘñãÇsóæMj䳺.66Ö¬ àСCtïÞ×_Ý,|éÒ®^Õ£RÁ¨Q ÕZsà@09.´þø#ÿûÐé sg¸zæÎ-ü¾oÜ€ZµL‹¿öî5}ä,éÂêÐÁ$ýôS³ßþþþ=ßB@J9...¼ôÒKy«Y³f®0{{û|ã?iêZ:=èQ«ÕeqaÏ£¸©T©’xåìy”ô‘Ç…˜Œ'„G ˆ2.DPd~úé'a@”q! ‚Ü ñ÷÷'((Hrõ’ÙÙÙlÚ´ -ZTìýÌàÑ1y‰˜fQÜììl6lØ€¿¿¿äº^ˆ @~þùg\]] ÆÙÙ™Õ«WóæÍèt:‚ƒƒñõõeñâňA)$!!9sæ°wï^‹âoܸ™LFpp0>>>,[¶Lˆ `¶oß.¹'éÒ¥ Û¶m+0þºuëxã7hݺµ4UX ”..\H@@9ž !88Xš‘Õ¶m[þúë¯G¾¶˜…%e˜éÓ§?±k‹ˆ@ „€ò§Aƒœ9s€Ó§OÓ°aC³ã;wîäÄÞ›5kÆÑ£G¸téR™§.”w¶oßÎÉ“'¥ßMš4áø=/¨.\øOë„€”FÅæÍ›ñ÷÷gË–-|ôÑGfÇg̘Á† ¤ß#GŽdïÞ½øûûÈèÑ£…‚RÈ|€¿¿?GÅßߟ1cƘŸ:u*›6m2+Ûþù'þþþ¬^½ú?•íGÉΖ‘-Oï?`4–ܵ˜2eJ¾ÇCCCÍ~«ÕjÆ'’@PÊY´hQÇ?´ç‚F£É忤Ä$##“ŒŒL8„R)öÿ¯¤¥¥ #‚2I‘D£±!>>{{;ÒÓS„õNNŽÂàé55jT{ì#@ð” ˆ^ŸMll¢°X1-Œ ž(ÕÇÙÙ²^‹ÄÅÅ™¶m[ ë ÁSŒÁ ÃhÌ~¼b4f£×g ë ë@@ðˆ”[_XIIwHMShË3îîn¨ÕbRˆ@ ¤ˆ„…]ÄÁÁkk+ñ”Ǧ·ÜªDr B@ž2jÖ¬ŽZ¼åñÅWª1  :aŒrÊի׉ˆ¸UªóX§Ž+z ‚ÒĪUëqp°ÇÕÕ¥TæïÒ¥+ܸq“€€7…€Ai£gÏ.T«V¥Tæmß¾ÂÃ#JµýÄ,,@ ˆˆ@ (}ܾˆV›ÿX“««3ÖÖÖO4ññ èõ†|»¹¹`eõd'ÜÈåJ èÙÙz dg†ÅJè?'±«à—+<==•“o壆a©~œ9sžÕ«7àë[—ß0;¶qãîÞMfÈEÎã¡#§pªØ WxRb<ágC>|ð·£µµm¾‹¹#"náêê€J•¿!“8rä-Z4cΜo¤ðaÃÞ~än=IDY@nܸɒ%+©\¹Æ™Ôy×®¿8pàíÛ¿ÂË/¿$JŽ@ àøá}œ8²ŸwFM%-5…É#ûsõâYVoÜÄçŠÿï¿§Ù¸q r¹œÏ?Ÿ€Z­B­öàᮜK—®¸–ZµjÐ_ _»v#vvv„†š¶g?~öy·BöýÆ•°Ó¼5|&,ì"k4¨-Z4C¡PpâÄ©\òñÇùßÿf‰’$”3’ãùzÁ\®^:Çí¸hn^¿Ìõ+çù|Áê<ãgdd´–±cGÍ?,gøð!ù^£J•ʼÿþP>ûlº™€,Xð#cÇŽäý÷‡0yò,¾ývN®ócn…³è‡ n†_!1!ŽSÇBˆ‹ŽdÎÁy^/--Ãtèð*QQ1ØÙÙ²ÿAºuëLýúuðòò@«Õ2aÂt>ÿ|"ÇŽ }ûWpvvâÚµp._¾ÀÂ…K˜8q¬”öøñSùúëÙÿÙî×®…zTº÷¯¾ú'''~ÿ}77oFJ-·–-[”lVjjÞÞ^(riµƒƒnæÍÀ¸-ZBHÈa¦Nýg>úhxiÿóÏqvìØ€J¥â³ÏÆ ÕjÙ±ãÒÓÓ¹té r¹‚©SÇc4 þ•>}î+ûúõ¿Ð·oOé÷¬YóèØ±Ï>ÛH”f „qvqgÒ—Ë?¬7¿¬^ €ÿ 4oÙÐåÑUc$+K‹·÷ýt‰GNËÄÛÛ ™Ì|bi:µéÕ««ôûîÝä<Ï÷¬TÏæ.eü{=Y³ì¼ýáD<ÛÐæ/ŽIwX¸p1&|,…]¸p™-[v ×HJºƒR©äùç›J—.˜9ó+–-[À‰§X²d…t~llüc±»^oêr˱ã¨Qï³rå:th+µê‚ƒeÇŽ?èܹ}ñ HjjW®\ãîÝ»œ>5 œÞfeeE•*•Ñh4T©RøKc08|øÉÉ]V––ÔÔT^zéyÚµ{NGBÂmd2­Z½È¾}!tïÞ™™3¿âûï盥¹cG°(ÁÁ¦f?¾\ò _MùÃÆøÍ¨^½*3f̽"£iÓÆT­Z…°°‹ÿJXØEf̘ËĉcQ(\¹r5k‚¥ðqã>B­VsçÎ]–- B«5µ"^{íÕóè×øyf/ZÏó&Ñk`þ=%ööv¸¸8søðQz÷îÆêÕèÜù5¬­­ñðp•júŽeØÚjèØ±-ÇŸ¤W¯nRxóæM¥øŸ~:ú±ØÛÍ͹\.ÙQ«ÕIøÃ‡ÿ‘ÂÝÝÝ9ò½’J•*2jÔpNž<èQË|A­VKbâ<==òS»¶ô}àaÙ˜f»v­ùôÓéØÛÛÑªÕ ¹Z9çÏ_ÀËËgg'QŠ‚’îÂrÔPÛÅÔuT»um^܈۽ßr™‘l½ñ!Q2|øÛÄÅ%˜äC&£zõª€i¬cÀ€¾Ò÷!§_±¢—Yx·»R%o†Drr²t~ž[G›ûy|­!¯4^"åQ!3bx(¶¶¶¼÷Þ`T*kÔj5žž¨PÁ€aÆoÊ{… ¤¥¥Kç½þzž{® îRذaƒ‰‰‰»ÿQVZåÓ;“Hh衯<øøTOZ (‡ä÷MB@ài!==_|¾X·à–ÉäXYÙ Õ¦ )i²²²ÈÈȆÊ12™ÌlzoI ÕjY¸p o¼Ñ oo/t:«W³o_­[¿Hÿþ}Šm/! ‰ÿ=Í©Sg±¶.üA¹ºzm )é¶0œà©ÃÃëØ>Xé$&&”ؽ(•VT¨àE\\ :¶Ðøžž騱M‰Ú{Õªõüþûnzôx€5k‚©V­2+W~Ïþý!¬^½ÁÌÁ¤RŠ——g¾®¢ J¥’Ê•«¢Óerôè ªW¯&Œ&xêhذ1©Å’vHÈ¡-7jµ õêù’‹^ŸMBB|BâçWr[µZ«V­Ãϯž™7ݽ{CX¹ò{^~ù%V¬XS~dÛ¶ß¹uËäv¸NZÒ Wvv6‹¯@&“1lØÛ€É}ñ®]™ß¦M+êÔ©eѵþøcíÛ›j¡¡Çø÷ßS€É%ÀƒÞ}7lØÌíÛ‰88ØÓ¿ Zn÷ö1P£Óe ×ë¹s')—çbàiÀh4¢ÕOwnbb¢Ùªï’À`Ð#—ƒµµœš5kOJJ ZmV¡çêõ–.]‰\.ç½÷›}kŒFc¡¾¹ ny¬£vmš7ošë»Wb-´Òü"îÜù'©©©’ö“'Ï`ggKƾ|÷ÝRZ¶lÑÿûß"Þ(NNŽf.Û÷ï?Èùó NGPÐZ¶lùöíÛpùòU 套ž ..žÕ«7зoO6lØŒ““#U«V–>æ…\®ÀÊJI¥JU0õ zôz­øºe˜ŒŒTíÑhÔ [à:’Ù³ÿGûö¯Íܹß0~ü(ÀäJÄhüoû—oÙ²–/_EXØEîÞMfþü’Ýsé‘äàÁ#œ;˜tuëÖ‰øø¢¢bhÔÈï^M!‰ððªW¯Êµká\¿~ƒÄÄ$Ìjó©©i¬YL·nÌVš›jîÎÔªU“Zµj Óé ÅÁÁž°°‹X[[ѼySŒF#‡áÒ¥+4lèKóæM¥óøá'iÛÆ‚ ZG:µpq1¹4NKKG¡PHi?‘íÛçÚµpnܸɛoú˜ž‹‹•Ê:ß-(AÙÄÔ"‘!—ƒ±±q¤¥¥’••»Erõêuš7ÿƒÁ ¹S¿v-œ={P½zU3ï»wï£mÛÖ¬X±NG@À›îL¸uë:éï3æJŽ$›4iĉ§xöÙœÿ‹o+ yQO8sæ<ÇŸÄϯ~~õÐjµlÞ¼öì9ÀÕ«×IOOgñ⸻»LjŸ V«ðó«‡-÷]§¤¤2oÞB"#£s]«yó¦ÔªUƒÌÌ,¾ýöºuëDݺµiܸÏ=×”€€÷yûíhÙò6ô5;wþüï3æƒB[Ë–áçW—^ºß‡¨T*1$$Ü&!á6 ü(KOϸ·ëÙûŒ3ÑÌÓ¦ZmC>89Ù£PÈÐëÅ"Eài&==''<<Üñô¬(µ*r¾Z­–„„Û úõë ˜6Þóó«ÇêÕÌÒŠ‰‰¥_¿!Ô¨Q ?¿z|ùå·çC£Ñ P(2d †ð>!!‡2ä­ÒÓINNæÔ)SW˜öF÷ðpÃÎΖѣßç믿'++‹¡CáîîÊ… —èÖ­¯¿ÞARߟ^/¥çåUK—Žç{=­VË÷ß/¥K—øøÔàÊ•ëìÞ½—•+¿Çh4òùç_áêê"¹|Žˆ¸EzzuëÖ)ð^Žý—C‡Ž —Ë9wîáá78sæ< Ô'"â&sæ| @¿~½9r䨽ÖW(«W/ÅËË“ðð¾újÓ¦} €££11‘¸»‹±  <µHŒÆlÎ;ËsÏ=8 Õê˜3çk.\¸Äœ9_3xp|}ë9Þ›³dI Y:îtíÚ‘—_~QúÎYÊØ±š‰É‡¾W"÷þH]XîînÒÇÜǧ†ä8##“ÌÌLÔj5ÉÉÉ’ÜÌÌ, ƒ¤’Mrr vv¶¹öñÈÊÒòÝw‹éÒ¥#µkß_yöì94¨˜æ]׫W›°°‹’€üûï)4¨‡••yzz½žÔÔ4ÉdøúÖ5›`gg‡³³É‰c§NíéÔÉ´Å㉧¤ñŽví^É×A[LL ‘‘QøùÕG.W —ËD žRôz=11qdee¡ÑØ`ccAÄf»ÊIDAT€Jeͼy3 xŸyóf>RÚo½õF©¿ÿ" H… ¸»»~ãžšºQ©REn³ti ï¾€«« _½ˆW_}kkköïÁË«66j²²´fÝÑÑ14hð¿ÿ¾‰çžkbv­µk7’˜x‡ÐУ„† M›—éÞýu~úég‚‚Öbj1ñ÷ï.·yóiÛƒ„„„Ò³ç®\ùghÕêéøO?ýL¥JÞ’hœ={€¤¤»|ôÑ0bcãËå­•®I“û÷"“ɰ²²ÂÙÙ™sç.àêêro‡2Ñ"ž.á0Gtt,nn®(•ÊB·ëÎ!<<‚rãFAAk0 ¯´mEY£ÈâãSƒ.]:Jž"sÖ=X[[Ó¿\]M·¼óN ·ÉÌÌäµ×^¥qㆤ¥¥cc£æùç›Ié¹¹¹²iÓª£ñÑvR}ä-me29jµ …B8^ümçZ¼ðlqt:-..ÎØÙÙ•{{íÛ÷7Íšl¯ÌÌL¼¼<±²²*×¶JOOçÌ™søùÕ/0žBaF iÞ¼Ell>>Õ ©Ä¨P©„˦ӧÎc£QáîîZ² #gùò¥5e¥R‰µµU¹·W^>uòk©”w{iµJ‹í%Ê" zôºÂ»‘Å·ë^ÅV¯ÃÚðè2 ª,@ "‚r( :Ž¥KÙ¹óÿ”ηßþ@ûö=øõ×¥Úð›7ogÏžýÒï;vñûï»->ÿСX³&8ßãéééÌŸÿ~ø ±±q¹Ž<Ê7ßü@FFÆ#ßþ}Ó«×@ÆŽTªm=`À»øû’þmÝúÛc¿FJJ* ·ËTáß´i«™]Î {ä´¢£c™}ŽfͳxñÊG¾‡Ö­[òóÏK‰/Õ¶ÎÊÊ"88Pú·jÕºÇ~þ9ÎÆ[ÊTá_·n“™].^¼òHéÄÆÆ±dÉ ú÷÷gÉ’ÄÄ”_y¸²–Wå-÷sø‰:uj‘]öõ•¥!+W®¡bEOÚ·oƒÁ``Á‚Å9rŒððRSÓ¤šy£F~|ôÑ0öîý›¸¸xvíÚ@ýúuùøãpttÈ3ý¿ÿ>Lll½{w»'2ãùöÛ¹¥òìÚõׯß`ÏžFj×öaìØQ*•,Xð#'Ožàå—_D©T’––Æ¢EË8zô•*UdâÄ±ØØØ`0ˆŒŒÂÃÃMJÿÊ•k8p Æ RY£P(˜?ÿ;úöíÉ‚?¢Õj‰ŒŒÆÎÎŽY³&£RY3cÆ—X[[J¥bîÜix{WÌ3ÿF£‘Ñ£?ã›of0fÌ$æÎ†Rùä^5½^Ï™3ç¥ß..Î\¼x™I“fJáýúõ¦gÏ.\¿~ƒqã¦Há½zu¥oߞܺÅ'ŸL–µ»víHÿþ}Xº45k‚III㯿ö3dÈ@:th[æ>={v`çÎ?X±bµ>iÒX5jïyS§Îf֬ɸºº0bÄ»Lœø9?þøu®r–óûλ¼óÎH)< àM:w~Í,þ¯¿îÀÑÑW^iY¦lh0ÌÞµ”S%ïÚµpÆŸ*…÷îݾ}{æ›Î¤I3ñõ­Ë/¿l cÇv¼õÖO´•ZIJºCíÚ5P(¨TÖ¤§gpçÎ]Nœ8Epp $4"99…ýûJá6lf×®¿èÓ§Gžé§¥¥q÷n²ô;**¦·LRÙ³çëÖý„\.gÛ¶ßÙ¶í7ÜÜÜðòòdâı >šFpìØ¿h4É¡¡G \˘1#XµjÓ¦ÍáøñýÄÆÆqáÂeÜÜLÓõT*kÜÜ\IH¸N§ãС#¬_¿oïŠDEÅ0wî×Lœ8–ÐÐX¿~%ÕªUáîÝdÆŒ™È²e óè蘺6bòÜK¹$ÉÌÌbóæm¬_¿™¾}{ðé§£¥Bšc7ÿAôìÙ…q㦘…oÚ´£ÑÈ„ Ó üQ²Ý!#èÖ­3ï½7Ÿ\¾|•aÃÞ.sÂqåÊ5V­ZOÍšÕxë­~¬X±:—]üý0·o'âêꀫ« ·o'𕳠6Ó§Oé·““c®ô;w~ͬ\&''£P”½u-:žÍ›·I¿cbL-ñã§šÝsß¾ƒñ÷ïŽ\žw'PLL,ÕªU‘Îùàƒ±¼þúkxx¸ ÉOqs^«W¯3þ¬{/W÷<ã÷îÝý©m÷êÕ5ßëÁû¿|ùj¾ÇÏž=““#sçNgñâDEÅ0bÄ;ÄÅ%ü+çÎ]ºÎžyÆT»lÑ¢yž-‹¦MŸ¥Zµ*eÖžvv¶L™2žÞ½»±}û.©fddàï?ȬÐÌ›7Ó,Üß¿»´èìÍ7‡HÏ&**…¢ìÏCñô¬@Ÿ>=˜ü‘‘Ñx{{™¥uìØ¿„‡GYD.\¸ÄÙ³a¥Æfõë×%--E‹–2nÜGØØØäY³>zô„Yøo¼M¯^]X³f¹ÔÉßßÍK/µÀÎζ̬¯oÝGÃ*U*åjQäpèÐ?øúÖåÏ?÷JaÓ§Ï‘â?~’÷ÞõP-^Ç–-; èÿÔ‹R©(°—_2d ÂpvvD­¾ïÅÑÑÆF*ô9/d£F~ôìÙ…­[wòì³ ¥ðúõë0zô€iÖŽÍÍ›‘L˜ð1/¾ø< ,Æß:µÇÊÊú‰ßs—.™7oAAkðõ­ËèÑpøðQ²³ï/³µÕ`0èiÙòþ=tèð*†¦MsäÈq)ÜÛ»"'ŽÁÖÖ–ÃÌš5ŸÉ“?áÂ…Ëlܸ…gži µôÀ´XÏÍÍôÛǧ_}õíc ¦ÙUÕ«WeÑ¢¥ÒÈœ9¦¾Ü}ûþfáÂ%ܺÅo¼-u»õèñ:þþƒ¨[·6•*U|â¶öòò”þnÖìYV­ZÀçŸO4ûØ?ЦMÓ¤É3fá={vA.—óÅS4h˜42|øÚ´i@óæM9zôþþƒèС-jµªÔÔúõëmvŸ3f|@@@³ðœnSKìûàïO>ÉÁƒ¡Œýë×ÿ»ïÜëmøDJ¿I“ghØÐ×ìyXYYñì³Ê¤Päg‹¹s§›Ùôã? E‹ç¤ Êõë70à>üð]Z·6û¨TÖÒ9;¶“ÆîJ²Ö½;‡.™ÀÍð‚¢]»¶òï³ŽŽŽ%)) ?¿ØÙÚ£PŸ+“Å‹WP³fõ\-Ÿ^½½½Å-k×ÂIII•jì…õé•_6íä•6/ RÙçë +%%''§B}@=)®_¿Á÷ß/端f˜…ÇÅÅ3}ú\-šgQ:F£‘_ÝA¯ßëòJ`àf.I~ûíOž¾YéܾH•*•ËýJôÔÔ4Ž;Qà 6€ÊÚmÙîNÛ¼y=z˜òƒ‚ÖâììL—.ŠøGGÝz;{ÕØ8£R—ÞYOC‡~Èüù³òô¸8vì¶¶6xzz×`00räxìÛÖÁ¾aE–¿7ei~¡ì±±QçÑä¶+Թ܃¸¹¹²fM03g~ÀäÉã˜ce¥ÄÕ5w G¡PH-‹j$2éé÷ǺuëTêfŽJ'µk×’Þ› êÓ­[çrk ww7äòÒïk¥T—ì~ýzçÞ½{Ñ^,{&MúD”ШTÉ[šô ®®.LŸþY‘Òêßߟþýý…QEÂ×·îcí(ËÌž=µLäS¸2AÉ·@"""IHˆ-÷FLKK·(Þõë7ÉdÈd`4"ýo –Æ}8^~çYšK®›3ñáxù]#;Û²q³ .™¥‘×5òÊgQó\šŸ‡V«µ(?†ìlŽþsºÜ—ÅÄÄ$‹ÆÓÒÒ9}úb¹·×Í›QÔ«ÿè›>²€dgëQZ±w°-÷áùÏG£Ñ`0d[ìšûi¦°½-ÉdO|â“F£±ÁÓ³B¡ñôútQ{[‹$;;SØ ¨ï[ §’¹Ü ¥R…““ ''9µÈü{ NNŽÂH–¾˜Je©œ¶XzɦBwa Q(eÂ^£œõWWgœœœÌÖ*rºÄ–µ@H¾X[[ßkê„õ #fa @ˆ@ „€@ˆ@ „€@ D ÿ…\ÓxM+¥Â2@ x@²ókGŽ;ÍŸþn±¯"@ ”¢’iàh“[@ª>S›2°­e'¬$‚\4p²¡j£ÚÄ$Å›$)5™‹WI×e ªâŒªŠð?$‚¼‰IŠ'6ñ62+'Ѷ†›°Š@ ,&íZÿÜ4ÿ…³±ØIEND®B`‚snd-16.1/pix/sceq34.png0000644000076400007640000000355111147553270012754 0ustar bilbil‰PNG  IHDRŸ#|C÷3PLTEÿÿÿ°°°ppp```ððð€€€àààÀÀÀÐÐÐ000@@@PPP    ÀgF pHYs  šœtIME×  !ùfVfÉIDAThÞí[‹–«*  /QËÿíá-/;:ë®Ë:ÓÓ¡âì˜d'¡ÿÇŸXÃéÇD){(`.Ì?ñßyô0p 傞\É’3ãæá|ë d)"©alþÙ!(¥ ˜}'[sc9bXÕ¢bH3Ï”yŸ„Öj'}T‘ùv™82hKøÙ-ó•Gó¹åâ †ñ,«Kž?µI»5øtpCF‰” eðIh͘¦gF‚ô±2Ì»ëÊ•GóF¬Å< /§V-ÐÒjí£ñ h­]*ó‘~—ŸE>¾ô ïhþù±èÝð‘‹V?tBvØl´‚¹}:ØãoeZ·Ð:›ÔAp(=)Æ£SïäÖi-…»jáhþùñJ¶²ˆô?ÖšØßï•y;S¯r#µÛL®+õcRj3¿¼‡“´Öª„K$J<©a!±ë0za¯‚]„£ù¿~”ÈìW:/>)ÆÁ}`V;µºa…P¨°N¹½³Ÿy/ü@µ)V‡2q¸ù¦>Ab×I>›Ð¤ÃJ<õç;¼á¡ðãhB’Ùˆ Q=Ô¦Kýìû§'ļæiµÔ÷“6Ò‰Œ.êuôãQF ó·Î:³ ÂJIûó­%Óïû6C´£ Kˤñaéù‹yB *ýÄ ÷¢7½òìO3ŠxÉ"shÑt¼~2¾é°”Ȥ¯‘¸uÆ) ¯dÂj¹™o¹­¿ð'Ìñ6»"HO>·œÍ2M­TÆyQ©ÙfgÂ\c±L\l„ÓUç,ín¼ÎÇTå”öz௚70¹ 3*ã›kDr…į³M;?fW.Ú긙ßÿ–p#^xÅÆ¢ˆ3/wï (h}$‚àþYH*ÜNÙu áMs“”Áª¾%L+9¤*ñ=džt$Ï Ó þmç›kD™€¼®e+ž 7ŸþVÔ¿ðŠõƒˆ'•Þ¼  r;Q~ŸÁŠ£t^õ åè“,1¨+ÁtÂ’ŒoîXw œ#©e´+MTq¹`=ßpÛxá5«jwO •Š'Aí~U÷©Çˆsô,†þÊñWÔ¢Ôf€5Ž¤ã¨¢Óª4bÍ€(qޤ’±áh¾·Ó©ÁË1Öžf"FYê:­×φ\@³‚nÉûúâ'1ƒ=æÿ¥ã/©Eñ°ý´Ùê¯H:ԉˆå4‹»!èÇuÙÙâµt‹1Ï3ƒ,]Â&çš9A¥ag‹óo<Ð4úÅ’…ÒõSÛ©…ÅCHÀã¦'ltCO|ÄëÍÑ×O…äþm{Èæ-Ü9(ØkG …ÙERy~˜DL²Ô!Û‘Ê aÊ=»2†CýövÚ·zMØ+©E©ŸÙö+ŒÙa²Oú‹WòÉ›t±¾„-Ì`f“&àøá.b’¥ÎS,©4ôL.̳+ i·T9´H6”£Ôd?náL~½@潸BůÌå’)ŸÇ×À áDÏ;_»»]àøÍ©3®šÝ xSõjhU7ó4†Ÿ{åTï¹Þ¹=$³NÎð‚WæŒò42²aS°ëRC¸2evmww¨×Ý6»s+ú‚aZIÇ|zm,öR!x‰wƒ¾2—¼²`”ü˜9ް+WjˆfèR&ËÏÛîîP¯»iv“9¦óDÍëú†³b‡Öåšq±ÞÓ-\äÐNxšHÑ%¯,åwª×¾ÔÍÐW»t§»;Ö뮛݉l…!ßa‡Î6ãb½ç¼3qŠ$ÐDŠ®yeÆ(¿¤ŸPjfèõÃ;Ýݱ^÷o4»õáäyÊ3zh ÐD®yeÆ(Ñ÷NÑ-É cµ¸íîÞìu²#<É·ÔÃF™S ‰]óÊŒQ"ù-õìç/’~ÚîîX¯û¼ÙýîèŸÌŠ-ÃC÷7zû@9ºæ•£Dü{êž~ÊîîÍ^÷GõsP5-ÃÓÿ@7tÉ+sF‰¶/Ñ{Wj¨žjÛõìuŸ7»‘øÜÙg¸IéÊÓ9ìNW¼²éþúð¥†d/Ÿ µ]ß±^÷E³›ëKø{vHG€ŒñJñôq¸¶»;Öë.›ÝéHø–0å úHî4Ç5;ÔùÁÑtw‡+Y³»ùºÀ“ú)Ns< äCYCÓÝ«XÍîêH…!L7Òªšãyt”ÍîæëT<õUê4Çs@þÎø·÷L"tpIEND®B`‚snd-16.1/pix/redsamps.png0000644000076400007640000001476511147553270013501 0ustar bilbil‰PNG  IHDR ë‘·ò‚sBIT|dˆtEXtCREATORgnome-panel-screenshot—7w‚IDATxœíÝÏ«Çðš XÐÉRböäȇ\‚³"ƒ‘ÀÁìa¯ b b÷œ½œàSXöŸ"1Î#Xè?xˆç9„€À–¬¼£mÉE1ä0{0-÷kõï®®®žù|Àøi^Ouuͼ™úvUuoþô§“mHà\!|ÿûÿ¼t=€wóæ{áKWØŒ$#€É @2Œ$snè6›ç·Ý~Q»mõñº²š¶™Ëã¨{îÐcK]]š_ªŽ}Õ½&sÖ5÷öh3¤ا¬ÂÜ}£Á$„þ•êÚ®ø}[˜SÌÆíSÖ˜7CL9w´cþõ}^ÎíRÊ~¹)X@2£F@úˆ5Œ“zZN×þ›ÎÒ÷ý}ìá­íö‹gÎö·M¿jÛoW[Ç¥ªØOÛkÒ·­c¶G×{dé÷0°ßbôEúö{ú@úì8Æ0ÎÜÞ>Ç!ɦc-ÿ~©ŽgW—}5½&Åc}Û:V{tÕg-í ¬SW_;ö:‘>ýå.³®Éݘã¨K~ûh©tnï½±õÉí8€uêš}3÷¾Æ˜m V,:ûÝÊÓ°¦m_S`@€Trëãe@tÔÒÑÖó0 XRn}WÁ(f‚Ì-öÕ´)Õ¾S>oªµ¾ÆU±ú5I®‚Õt÷®mæž¾Òµh¼i¥õ±>ÇZ÷ÜØ÷!i;«£­«û˜:å«®þmûoÚnL[§z,©o_¤Ov±«`ź aÌmƘru/FìýŽÑçªOcŸß´Mê›9ÆÚ.F{4ý~Î6(Äì‹Ä1 HF’4«ï“ܧœ8޼ìÊq¤’ºÿ³6(€ìJÐqäeWŽ •5÷ŸLÁ’@€d Hæ\!ܼùÞÂÕöÁæÑ£O¶KWئ`É @2Œ$#€ÉœkúÅ… —ÂãÇŸþûæoÃ[oý4üíËÏ’T¬É… —Ý?Эœ%ÊŒ€É4Þä/ç¿èUÀ·Ÿ<µB]Œ€@þšF@§`…ÂÉ““ÖBß=ïýä×!„^ýßWê»ßý§^Û½óÎÏ— ä§5€ uùòKÏK€eÍ@ŠÑBÛ(Hyô£`vÏ,¤:úQh©[÷avÏ,¤:úQ¨©ý(¬}d³Ù„Íf³t5 ­—á=~÷xpÅ•¯šÜ¿ÿñ3—ë=<¼=x?Àú4ïýÃ÷žÞd0„nþæ0¼õÖOÃß¾ü¬µÀ¶ðÂW£ Ÿ~úu÷î}xæ^ ÀîŠ:«iíGUßû‚»%êÐCáèhø´­¹ë0¶Ûí ç Ùè5€Ü¹óÁ3ë;–V}C……ã0è# kW„”¡!Dh€nHÉ”iWuÏJà¬ÙVå{w×ÞŽ€Ô-L/ÿl:ķ󤼞C €eí| ¡>xt…aâ³HF’@€d `9ßo,׺•ï×F?9¶™åÖÉÏ™˜Î*ûLv’N>©yÏõ#€É <å,>s@€d`gÊ1`0áKv– ù9·t®\yué*@~6›¶Û¥kÝâ$„NOÔ>~xx;¼ýö/×fgX [dlkÎR %‡ÍfSû]M½ív«Í˜MÔrpp-fqߦ6•O`?g\çâ„›Î*ÐGô““»Û‡7nÄÞ5KZCǾjuf'å<Ú nÄæ*XìŸÍæì(;GÇò%€0]uÊÎ=²6s7ëSX/`ÕŽtÎêœëF·ò{-‡×RXƒ ¾0vÒv«m÷@îÓ±r®ßÔº¥èìŽÝGñ}%€¬…/Ëý"ÑCÎè¹ë6%¥¨Û>¿6]¢_ëèè8v‘@†ÌÅÏCÎ#(Œ“ò5]â2ÚQÈ;„Ë—_ŠY$ì·¢Sà’Á³É½Ÿó}Vºê¶ä s]›Ìês9a` °ŸÖp¥¦¢~kìxæ:}hm¹Ûívõ£!MuÏ}* íÚ^»˜ïÙ"ì¬áï ‡P&€ä¬üE–k§~ß­á5YCaÇåLR@€hVóẖz®M28»Fß÷}>Œ4ä)‡³å»(×÷zª¿C˜l5‡êhBÑaιîûúåŸûëR˜»Ž+xýuP§Ó†Ã5µÙj¾:ä4•kŽz ‰µ~hVë¼ÖãȺ³»Ë“%Û}H»æúþXAPËõó`L½RË}ÍÕYÍ=å\¿jÝŠ5"KÞx2§ö@`aE‡½ø`Èõ˺M±ð.§·F+lßÕkjóÜÃÇß+™Ö¹­ƒ<÷g^×çRß+%Íuéº}çþ={ý–V¼¦C‚á¾µ©B­5žÅ.꼦º—¯šº®$ÓÔΫ!Õ:Ž­óœgŸÛÖR´ísìïbYÃëߤ«}š~ïâ“-Bú>Ÿo{¬+L¶½ÏRn-<‡¾‡çª“ÂÕNå:óå:–ÏÄç^÷œëÖWÓ¨G–!ªèÐO ¹Ly4r¨sãÚ/eÝ«—>²ïTõ¬î'ÃÔ·£WìÜw}>åtreè½,R}öVGïû>§íß) yo.¡®Mç¾/H×k8Çwº’@îáB]'>÷iAÕ:—å^÷ºoÜ´v«;†¡ÍÜφV;ûåŽj.¯MWr«o—¥BHÝcÅë_ß™¶ã˜)+sYzÿS¤¨ûÔ›û¥ Hm Õ×6š•C8ŠII ÜÎ5Œ´ÝÉ4×iA}î ›cé{ÖhL›—ç(ÏuÌ}ËÜöåÎÒ£ }×¹¥¾¼bì;õˆBŸŽoù÷Õp·tG¡ZŸ¾ïÏ>wl»\¦»L‘cGµüÜgÊQê¶î»Ï5¼ÖPÇ.}ßÃ]}ŽØ碖¶ÇºÞ¤ån̰åXÕzµ ëõ]„—úÃxêDy:Ö_$å 4WšÎŒô iCÊ:U¢wˆ*¶)Ê­žõNýº ݨv®—쬔ë]n»º× x<§ÎU][6éYï±#¹µ_õ¯kµŽuïDÇQw% !ÏÛ'CÛ©ÚÏXº½ªu¨{íçü^œbìû4ÅþÊÛæÖnC ‘ YLT=3Üç SëV>[ÒTŸ¾åÄžÚ5×1ÆØ!$Æ\×òk×6”Üõû1Ç]Wß±ïÅÆý7uÜ«g›ÇÛ©,þ_íÌ·YrzKSÀ¨ûwÛëêËlH[5už—Ö<«ïœ: CÞÓŒýÌ­ž¸™Ãز˿X'yÆÖa-bÕwíî1R‡¡TÕ-”nz“ź‚ÇTÕ:÷ ^]ã¾ÛO{:V×±Çnó±û*wß:ÅüRíüàìÚǘ†±꺎qßðQ÷ü!ûú¾2‚ѶMQÆ”°ÖTþ˜rçr1C@¹¬=ë¥R÷™ëŒoÛçQ5P ù®X*ˆ´)·×÷¦öÊ¡³<¤©ëÛõó¼˜RíGYXÝÔ¬ê㹩®iiÛ¦oY)ÅØgŒc"F01š2Ö3Ãîà øêÿ}>cœÍŸ$¦3%fÊÅ”Î~ùyc;ømÁ¥î±©£acë86œÍ=*ÖvL]Ç[}¯e6R3ö„QÊïк)FSåÐybèwPÚ¾OSµ}.m±$$#k{C®­¾1-œ¦~¹ÖºÕm3—3ðsì'F'ªi*ÍÐç÷ý"«î#fG~ès‡oŸcm*¿ºŸ¡ûc¥!†ì»iÛ¶@“ð3)ÖÙô}žNÓWNí³öpÔ§ís;Æ%FgÊûóý'€ÀŠÄšUHÙº€½¡úŽgê5 }ÔuëÎ:‡ÇÙç¢>cÚ2f蛲]];V×ct•¿äˆE_±êYW—ž£*c>;ÆüíçÔ/kEž{]çX]u‹ù}Ðwª[_±Û¬zœSŽ{îïѱeçð]†öXÎN¶Û³ʹÂGy?1Ê ¡¾3<5Å<îjyEû–ƒRñ_îïºK×”¤âÿm#}Ž»®ëÚuHýR2űÁ’WçYºÃ•ÓçiS»©#?G(ê3Ú«ºÑ“¶µ˜]í;ÜíX§r‡1×䦺U§!åXÿj@*:Ñ9µwQ—r(ª®MYZŸ¶ªŽê-ѾÕV­W)D-µÆ¯<…´kéÈmgÃcCÑ :…¶üï> iúwSS-t.ÿÜöºÆ¼èغõÝ>eÝÊb\u35X¯\:Â}T;–9×}Ž€4ÇÕZ´Õu޼±!¦iJVí¦ÓBÈØŽxõysNÍ™2õeÎà\gÀ—=¦8ÜÚ®—+€gU¿ðs !MÚ»÷1W=Ë£ ÕŸ‡”QüÎöl›†–™¦+-y•Å\;]"ÑѯW×.9¾¾±Í9­Q`ÝÊñêÏ9ʵ^…Üë–]kÒ¥îòú9vVs¬SŽÁ­-T渮£üwÑç‚Ký ¹ ¤2ÇÈÒÊõxÑ¥ ç¦«3=fÊQª+!.ìên´ÛÕž);Ó¹„ßê0–KXCç!ã:¦¼gÁXs‰Xbµ]ìÑ€¹/½;ÖÔ›Ç|îœæ@€U˵—»G? 1ë‘ãT©¥Í}…¯.Ö€{e—:’P¨ÍÊõ½.€{#×ãåüš¦ª[ÎmPG€•[SÉb Èááí¥«@‡¥oXÈnX<€Ü»÷a¸zõ奫Ñ NÏ2 :«ì€N9‡£œë–«%ÛL’Y| È®˜ón‘°+Hꆱ„8Ë, HF’@€d HF’@€d HF’@€d HF’@€dÎÅ,ìààZÌâ€5€„ÂÉÉÝÎmŽŽŽÃ7bïºÑf³ !„°Ýn=gÈö@·¨S°îÜù ×v—/¿s·­Š ±ÝnŸ‘>Ïâ‹>òÊ+?j9::>@®\y5v&)KWR`¸èäÎÂóÏ«ñ÷u£§§j·=<¼Þ~ûû¬ c¦O ™vÕg;!Κå*X¯¼ò£ÚÇŽŽŸyìÞ½˹zõå^û+¦X•ÿk³Ù< Ä5KiZ Ò´öã…¾óÌc‡‡·£Ö©ª4 Õc:Ä5Û}@ª£ u£…ºQ¾£]Šõ®jË‹¾¤P] Òuå«bäW¿ú¯B¼BýHFWV ¾ÙH__«zå«:Å(HÌàäeÖrçÎáþý“Þ÷#G³°V±gE ×z=V–Û}@€ùD ·oÿvðsÞyçg!„¿ÇªBvÚÒâ܋╯|å+_ùûWþšë®|å+Ýå1ÛU°ª HFYÈÜsð”¯üœËŸÛÚÛGùÊϱìÖÜöÊW~îåçD’@€d HnŸæ¹Â.ñ· ë•ÓßoÔ;¡Ÿ?ÿÍAÛ?yòyÌÝ™‹@Bè*nÝz?\¿þfãï/^|ñéÏ}2±V@¢.^|ñLè¨þÈ×f³©æÝl6!„g‡€‡>|¥ø®,+oæúÝk MÝañøv» ÛíöÌ6C‡ÂZßk­7§â»²ø¯,çïÞU£°F+öK[àœ{¿©ßk›Í&Êq ÕÀ\–ølk€õXËà»xLÀîXÛ‰¬Ö€”ž?ýÈKuÈ>„¯;èuó‡ËUÏЕËêÓÉïZcT-«®ü¦ú4•ÑUŸºíÛʪk€)ÊŸckølÉ*€aâs€|µ}Ñ5M1*wº«ÿ/Œýâl{^SùMõRŸ¦ú¯¥¬ßZ?o² ÀºÏêb¹S:åqvÏÐ:ÕÐÓ6[Ý~ÛêSÛçMÎß½MÛVŸ3Ô}Ëbw }›FúŒDÌF†Ž¼Ôý`Š5~÷ ŒRw¶¬i¬ëùå2†jZo1æŠS]#)uÓ¸ªÛYK°O¢[·ÞŸ\†õëÐ6Q}¬nŘÎyÛº®ú­ÏLJ¬ØGQÈ“'Ÿ‡ë×ߌY$H\³åµµœž>—.½^xá;QN\ïô+W^ —.½°—Áb*‚ÈÔ™C;@˜ÇÔ ²SDð€4Æ‘ Å: ÓÓá£þÐ{û ÷î}o/] Ø+C/j´3$„¯.Åûðá© 3;<¼><|EÕ¨—á½uëýAÛ_¿þfÌÝ?U‘>úCxã×gÙì£bÄcì­¢ßä•×ßéÜæ—6áË/ÿž<ù<öîÏD Ž©Á£üF„?¸´I½Ë3A¤©[pV¬àQH@ŠðñLJÛÂÿE-»Ï忺¶yûí_Īì„Ø}äYÈÙ qö±6/¾=ú¤÷ã…?ÿùÂüÆàzñܾýÛÎm¢rÐøÁ¥MøãÃí™ÇÊ¡$¦Ë—_jýýÁÁµBwî|0Ëþa Š¿êù|€gõíG÷ígD ÕÀ16|tzôupp-œœÜ ''wÃÑÑqgP]wrrwé*dÉç4;9¹žþ[á•W~4ù„Ý,÷™k”cˆƒƒkáùç¿¥³‘AdʬŠÙnD¸T<`^S‚ȬwB/‡1Ó¯.^|±÷sÈ߬$„aÁ£ÅÚê¿€|üüç?üœè‹Ð_úÇgïïñå— }ïûQ }ÃG±æþýÃk¯ý°×s€´¢ë×ß Ož|³ÈÁ._~)|úég‚̤¸zä˜+HÎ>k)E9::^º*°ŽŽŽÃ§Ÿ~6éÒõ³Ü ='å åÀ`SF<ªv&€t]Ì á+7nÜXº ÀÊÄì?ìD¹}û·KWèag×€ùÙ‰ ž¿œÿ¢×vß~òÜà²7}ÒÿNÀÎûËù/ÂÉ““ÖmŽß=ïýä׃Ë6 HF’9³äæo—ª‰ùÏíµ]ßüðïÿñÆÓŸÏ·Þúé€j»èÃ^ÛõÍûò³§?Ÿkú°§Î÷ÛlL~°HF’i¼á… Ão*Ât÷»é ÌéøÝãYÊm¼¡² €]f Œ$Ó¸¤Îfóõ´¬íÖT¡6›ç´%°×Οÿæ íŸ<ù|¦š¤³Ç\è@ªegbéÛÁ¾uëýpýú›3×&ÔÇ|ñâ‹O~ôè“ÉåÕk V]ØØn¿83"äëÑ£O …AS°ú*‚ɘ’"ìTÃMµ¬ºðÓg„fÌÈMß} ­³$öÍ,dªºP~,f¸S—ºÇÇÔÙ@|å©F…ò™ÿ‹_|f$ úXñïjYuÏkÛW }ëÚ·¬ª¡m×e–25¤ SÔMIS†OSgxh'¹é9åÇbîkªÁ „úÐûx²ÉISH0} `=Æt Çvº—Xg‘ÃÚŽ¾RM÷`šº©HÅãt«k»Øzb ïex§,B­¼@¼­>Muž3h˜~_.Ó¢Ö¦mJYL½G@ªS‘– }¦EUCGŸ2v_c˱ ®±k=–®C®ûìj›1m7h VßN÷”pÒôÜ1‹¾‡S°ªÛ4='ƾRzÅ®âç¶v©{,FÛYÀânÝz?ZY}@×6M¿¯>>%lÄ<æÆS×619„6}²­ûÅ… ¦-áñc#"sŠuÉÚ\¤¬{¶÷€\źiß>ŠÑvF@2c€]Ö8¢# Äö¥+ìHF’@€d Hæÿ %¡é›@IEND®B`‚snd-16.1/pix/fmeq56.png0000644000076400007640000000164411147553267012764 0ustar bilbil‰PNG  IHDRç—u9¸3PLTEÿÿÿÐÐЀ€€ppp@@@ ààà000°°°   ```ðððPPPÀÀÀÄsµº pHYs  šœtIME×  œY@IDATXÃÕWírì ÕøA¢}ÿ§-¢F“è¶ÓëÜÙÆs½Bn›*Cci"„˜a_?ô¦ûô¾Âx8ý½Ž›fÒ¯0þú⣅}—£S+,˜¤›éÀÇß7‡ŸLÀ_ÄÑwØmÇKb†!ˆÓcñ3Qñv¢*l,tΛ‹™Zók’|ÀàÅZûÖ[˜”í ó^§ëJiYйˆ#Ggfæyk‰S^¬µ8Ê«Dý¤lß•ç™j÷0À9ˆœlAP#çug&¶œs<¥µDç„ñA;ÃvQ¢sÌß’çìQˆL8—rJ«˜'6\ˆÉ7†B¬Hœó}r²ˆÈw—ë¾°„÷2]i8øiäYÖ>QB°W¶Ñ_JÔ¡ýÞ{üøˆµ*qʱ‡­ÝAÌY™£ÎŒÀÅ.¾c¤H,Rª^š¹ŸY‰ݵP\ >ò¾S%gK§zúï$}`í8&†6Ë®’â¼ 7,sÿe†7Î ´ÚD@¡• ²3-™¨‘…кY–Y ÷œ;§B 8i*©°n‘“s,Æq(|À™Êfär= ùÉåÉw;AÜÕÏÒ¦ùw£#·žEhQ`¢î›Y‚“×N8§]u¨)aàˆäM¯U½ûí³ÐâB…KgœlzŽNçíê2.O¾ƒ*—BS˜7F™tN0аHr2Ó’Þ¾ðʈ€éÉѦ koJ²aAÛ¦D¨†ßSz…YÙ”‡’òÔí¬!Eã‘Û|Ò[Î)¾ƒ˜;“ÆvˆxFZµhxÇ"j;ÔNeœÜ¬>9³ŽœþÉQåËõÒ”dÃÈÛˆ¦¾R¤Ñàëí3ÁðB0•˃J0±l}{dk]¹ƒ Wª¬1Ð~‘?Y¤®†˜;ðÓÏ&Ñß7WQƒý;ä{3:h›Ö™×[v†­Gì]>Å÷bfËo/\Kàóù³Ð>§X;®°Ã_ï[¿âÐÿaù¿%ÚG8õÿš*˜c+¯½öåÔ}ÈöåãPêM¨]©IEND®B`‚snd-16.1/pix/sin30.png0000644000076400007640000002424211147553270012606 0ustar bilbil‰PNG  IHDRœ¤Ø´öbKGDÿÿÿ ½§“ pHYs  šœtIME×  ! f"Ý IDATxÚí{\ÎwÿøŸ*i!•â™óa,‡ÉæxËÌaˆB]u;”ÉL·Ø01‡/Ê=L ‹Ý²e!³n9…dÂ9Ü(KÔ%OW}~ø]Ÿ¹Ó9z?Kïóõ>¼®÷áõz¿ëH’$!•€–¨@ Œ@ FP{8zô(Û·o/Ñ/77—õë׳páBRSSEeÕRtª*£%K–0lØ0ºuë&jý5áìÙ³Ô­[·D¿›7o’——Çûï¿Ïþýûqvv–ýÖ¬YCbbb‰ñ<==±´´|nžû÷ï§oß¾Ô«WO4€0±qãFZ¶l)ÌkÄG}Ä¡C‡JÏÙÙ•J¥áöðáC:w“Ó ̉'èÞ½»0b‰$¨m¸¸¸ý·á5j„………ƿƋ 3à/‚‚‚¸{÷.iii˜˜˜PTT„Zë¡sçÎ\½z•K—.1wî\QY/É… hß¾=úúúܹs‡ˆˆy¶hjjJpp0999X[[Ó»wox×®]ÀÉÉ©ÌùŸ>}Z#]µ[ll,Œ3†ÔÔT8€­­--[¶äèÑ£$&&bjjÊG}$f0‚ò³|ùrvìØ‰‰ ;vì S§N²ÿøñã…p) ,ÀÙÙ™´´4HJJâܹsxzzâïïÏwß}‡™™“'OæÂ… ܹstuuÙ»w/¾¾¾eÊ_¡PàááQLàMž<333¾ûî;üýýñôôäܹs$%%áààÀÑ£G™;w.fff¬\¹’={öˆŒ@Pv~~¾üwÛ¶m™={¶<øÿ÷¿ÿ±}ûvÌÍÍ™?>ÉÉÉdddàââ¸qã7n …¢Lù‹›œœÌüùó±³³ãwÞaõêÕ±nÝ:¢¢¢HHH`ÅŠ <KKK}91ƒ•†0@ ¶‘˜˜È£Gˆ‹‹###€«W¯j|ªýnݺE~~¾ì^<›¦ú3##ƒ¸¸8=z$ë3=楌««ë ·lÙ"z@PA,\¸ÿþ÷¿Ìœ9“Ó§Ocmm££#ööö 4<<üðC9Í:ϳ¦vqqáûï¿ÇÕÕ•€€€bþ¾¾¾rñâE ÷Ó§OsçÎbá=<r€Û·os÷î] P¦ü;À›o¾I«V­d÷k×®¡T*ÑÕÕ¥OŸ>ù=[N€V­Zñæ›oŠŒ@P“ˆeàÀÌœ9“¬¬, aóæÍÌ›7]»váééI\\#FŒ¯FˆgÔ¨Q\¹r…… òÝwß•:ïï¾ûŽ… råÊFE||<ðäú…#F‡§§'»ví’óûé§ŸpppàðáÄ„„Ç©S§4ôp*|sæÌYýûirssE^€··7Œ=###š7oޝ¯/’$áââ¹sçøå—_hÒ¤ ZZZÜ¿Ÿ:ššŠ³³3Ÿ}ö3fÌàŸÿü'S§N-UÞáááœîÝ»chhX-e,(( ==]>1PãèèÈСCÅ(¯FŒ9|ø0/^dÅŠhiiÉ–Ìêñ£Ö’}ž5óÓZ´¥åeÓnÞ¼9899ѵkWÙïÞ½|üñÇ/w]CYéÒ¥ ]ºt)æ®§§W®t'OžLvv6®®®Œ1¢˜FF .d̘19r¤Ê;ÇÝ»w3f ¶¶¶,^¼˜6mÚ sþüy¶lÙÂW_}Å®]»þ2«B¾ýö[bccK¼ãGP½¨•ë\\\ʬî_ÄÇÇÓ³gO†ÎÇÌÂ… ÉÎÎ&::š)S¦h„}%6y½½½144dãÆ%ÎŽêÕ«ÇÚµk9yò$ßÿ=ÎÎÎèèTÝ׋ŒŒÄÙÙ™™3g>7Œ ]ºtaåÊ•xxxTeåËÍÍeëÖ­ôíÛ÷…e¬J¢££ñññ ''§Ö ˜„„š4i°aÃÐÓÓ#--¬¬,rsså-†û÷ïcnnNBBæææ¤¤¤››KRR*•Š”+ÿÆ“””üðC\]]™?>AAA¼ýöÛ|ÿý÷¤§§ÉìÙ³±³³cìØ±¥Î{ìØ±ØÙÙ1{öl"##±°°`õêÕ˜ššÄüùóquuåÃ?ÄÂÂBþAU¯LV¯^——Wñ„kúu ¡¡¡¥Ž÷øñciÆŒUfjïåå%]»v­Tq¢¢¢4ÌÚ+›éÓ§Kééé5öº¥RY«¯kP×A||¼¤R©$I’¤¬¬,)>>^Š—òóó%I’¤û÷ïKñññRJJŠ$I’”žž.åççK?–ÖuüÇËãH¥RI)))R||¼tÿþ}1/eeeI’$Éåy–¿Dúý÷ß™8qb©â˜˜˜È¯ãUÅz´~ýú´hÑ¢Tñš5kFzz:ééé/53+/âÁøγÚɆ††Åž]‚¨ÛÔÄĤ܇Ï^R¥N¯Aƒ²ÕôÓ~Oç÷¬ÿ+³DЉ‰ÑPúyY&Nœ¨aCQY¤¦¦b``Pjóú ““S%{_ýu±S# *¨Ñ3˜ììì2ß‹¡««K^^^•lžêëë—)î¤I“ضmóæÍ«Ô2•ëøRPùìÝ»—={ö ££CAAnnndffHaa!ÞÞÞX[[3}útŠŠŠh×®^^^²:Dvv6çÏŸ§°°P㨗%++ ggg éÝ»7îîîhkkSPPÀêÕ«¹~ý:ZZZlܸ‘ØØX–,Y‚¶¶6&LÀÎÎŽÅ‹sïÞ=LLLäë4kü fÑ¢E,Y²¤Lqû÷ïÏñãÇ+½Œ~~~̘1£LqÛµkÇõë×ÅèðÆo°zõjxï½÷066fîܹ,^¼˜iÓ¦ñÙgŸ±hÑ":uêD@@Ç—­§>Ìš5k¸wï^™òÿä“O=z4ß~û-;w„ÃÂÂä+#:uêÄ¢E‹øì³Ï˜6m‹/fîܹqïÞ=000ÐØ°¦¯9*• •JUn=$Aå2`Àš4iƒ¸{÷.Ý»w§{÷î´iÓ†дiSœœœ4>ÕŒ9’O>ù¤\eprr¢^½zŒ9²˜ûÓŸþþþtìØ‘˜˜,XÀÀåïñÊ,‘å'%%…”””ÿ5___ûTj"-[¶äرcüñÇ >œœœ¸yó&û÷ï×xñµÆ ˜ëׯӨQ£jÑvDŸÿûWïÞ½™9s&[¶láðáÃò[Ö={ö¬ùK¤‚‚´µµ_ûÍÉ^½zñûï¿‹Ñ%`ÿþý :Tîó¿ÿþ;W¯^%44T¶nö÷÷`ëÖ­„††–yßåY¶nÝJzz:»wï`÷îݤ§§Ëy©ó^¼x1¡¡¡ÄÄÄÈû@;vìààÁƒÅ,^ë%RÏž=‰ŒŒÔ¨Éš5kÊ}üÛªU+nß¾Í{ï½W)eŒŠŠªQÚ»‚çchhH§Nä¿·lÙŠ+$ Z´h‡‡ …‚Ñ£G3hÐ 8@aa!;wîäÀH’Dvv6îîî¥Ê{Û¶m( Ž?ÎôéÓéÔ©—/_æ£>"!!…B¡¡!6làÏ?ÿÄÛÛ›:uê°eË"""¸yó&6l(6!¨p³yóf"""йW•âÛÓ¨£²LaaaŸaýððñÁÃÃCãïþýû;rÞ´i“Æßê—U­¬¬?~|™óÖÑÑ!00PÃM½©û¬ Ì[o½ULÇÌÖÖ¶ät+º’ÜÝÝK”ž‡=H ÁÝ»wùå—_HOOò"N‘ÕÆo¼A¯^½xôèQ­¯?ÿü“ÜÜ\ù²©ôôtÙ’¹eË–èééqûömT*&&&XZZÊq11KKKr4nÜX6z0‚j£~ýú²¾Ç;ï¼S«ëâÔ©SŒ9’àà`† Æ¥K—pvvfÕªUxzz²|ùr<ˆ½½=ÁÁÁØÙÙqûöm”J%#GŽdûöíŒ?ž={ö”:ÿ={ö0~üx¶oßÎÈ‘#Q*•À“kìììÆÞÞžƒ¢T*ùòË/å%Ý/¿üªU«fÆ 7ÚÕX³yófÜÜÜ^ûŽõÁTéµ ‚šÉ™3gX³f ,à‹/¾àÊ•+èèèðí·ßÄÍ›79zô(,X°€I“&+Ï^ȲeË8rä¿þúk©óÿõ×_9räË–-càÀò½2±±±Lš4‰ ÈÑ£Giذ!nnn²ZxÁ‚iŒÛ+`222*Äʸ}ûö7žWjKèg-PK‹¾¾¾¸¯X Ïžþ422B__Ÿúõ룫« @Æ 5>Ÿ^njkks/ 6D[[›7Þx£˜ûÓŸuëÖåÍ7ß”8ÔåýôS,-- !99[[[ºvíJvv6=zôÐÈgñâÅ%¦+Œ@P°´´ÔÐkJ4|ìÚµk±xðä¹Wõs­eåYÁ¤NÏÚÚkkkÙÝÐаXاýÅI T 5RÀ:tˆÁƒ‹ÖÔ*–,Y‚››k×®•ÝÔϳªOB½¼¼ž«¦ö{ZÑ­4¸¹¹áææVLQoÛ¶m¸¹¹ÉÏ’Ü»wO{æÌqûì‰m0—/_¦sçε¦cmݺ•É“'‹V‹Y»v-ñññ|óÍ7„……H`` aaa 2WWWæÍ›‡žžíÛ·/Ö_._¾LRR’üNui™>^Vk¯íÖÔ]»vÅÝÝ777¾ýö[¶mÛ†‰‰ .\`èСŒ=š: P(4hFüÞ½{3vìX ºººÅüÅŒ ÖQ¿~}lll°±±y)cǼ¼<´µµyøðákWä‡~ÀÊÊŠþýûÓ£GΞ=ËÀÙ³g|ëá‘#G4h …B#þ¨Q£èÑ£¨Q÷ÿSFBCC±³³QLLLèÙ³'={ö¤[·nþÿû5ÂÇÇ絬ððpþøãV®\)»íÝ»—ØØXÒÓÓ eãÆ( ¢¢¢ˆ‰‰!""¥RIhh(™™™\ºt‰1cÆ”)ÿàà`233 •ûxVVÁÁÁ²?<ÑÚˆˆ &&†K—.Õn3jÔ(~þùç OWýK"T!!!œ;wŽY³fadd$÷ݺuëâããÃ’%Kˆ‰‰!33…BÁW_}Å£Gˆ'++‹˜˜ù±´gŸyþýïãïï»»;  mÛ¶ÄÄÄгgOÚ¶m‹B¡ ,,Œyóæ±dÉ|||øâ‹/øüóÏ'›¼áááüßÿý!!!%\U{›››¿ô#ö¾¾¾ûzipvv®ðïSÑiVFçÍ›W®ÇЫúáwà…í%ùúúVJ] *±Dz¹wï^¹¯“ÄŒ@ F #BÀ!`0@ðš ˜¼¼<òòò011­#¼âT¸±cnn.*•ª˜»Ú:óïxüø1?®u·áwéÒ…K—.ÕªÈ åKª333Åhæï "22²˜ûëÔnÞ¼IëÖ­+4ÍÆË]ÕnÞ¼ÉúõëÊu¾  \\\йïÝ»·Ú¾äŒ3ðóócÆŒ’^ddd™.VhÒ®];6nÜ@RRÿùÏD¥¼fÔŠM^+++âââjUÃþüóÏŒ5Jôp0!`BÀ0@@ Œ@ #„€BÀTqqqµÎLÀÌÌŒäädÑ#BÀT&©qû*1dÈ<(z¤@˜ÚαcÇ8p ¨àoÐUPz ÑÖÖQN¢££åGÔ„±£0/ýë~ëÖ­bî¢ ž¥cÇŽò3§IIIìÙ³GTŠ0/¦Y³fèééÏHGL–!`ÊIëÖ­K¼+¥nݺÕö%ŒŒ022")) sssÑêAQ+6y166&))©V4ê©S§°µµ½[ Œ âÉÎÎÆÐÐPT„@@ Œ@ #„€BÀT-W®\¡S§Nµ¶1 Ä‘#GD¯S\ºt‰.]ºTJÚ–––$&&–;˜˜Þzë­J)£¡¡¡¢W „€yÕ˜8q"?þøc¹ÓùꫯX´h‘è90µ“   EEªa ôRPPP­¦/‹°¦¦Ô?~\XS ^ aM-L©±´´,ñ®”—±¦ÎÍÍÅÀÀ Ö6†¶¶6ÚÚÚäç磫«+z§@˜giÓ¦ mÚ´)æþ2Söððp¦NZi_¶W¯^œ9s†^½z•)~ll,ÖÖÖ•V¾FѨQ#nܸAçÎEï¼òÔªMÞ>}úpêÔ©2Ç¿}ûv¥Q BÀ0µ—… ²dÉQ!`ž¦¶>Wò,ÚÚÚ¨Tª2ǯíå!`JäìÙ³ôèÑ£RóhР999e>2¿}û6o¿ýv¥–ÑÓÓ“µk׊žY…DFF 5 ±D*?Íš5#==ôôô2Å/Ï TUƒ©©)¦¦¦¢g—‚={ö”¹O^sçÎZ¶l)Zãÿ£>N/-YYYèêê 0OsëÖ-ZµjU%yÍ™3GVO/ >>>Ì™3§JÊXÖãômÛ¶1iÒ$Ñ«BÀ<͹sçèÞ½{•äÕ¸qc>|Xª8 Ѹqã*)c“&MÈÈÈ ##£Tñ=zDƒ D¯£æúõëhiiѶmÛ*ËsܸqÌ›7ï¥ÃGFF2{ölÌÌ̪¤|5ÂÊÊŠóçÏ¿Tø¼¼<¦OŸþÊÂ=|øýû÷³ÿ~>,F£0Gaa!111ìÛ·OOÏ*Í󮮠ÈÈH¾ùæòóóŸ®  €}ûöáççÇ„ ÐÒªºêš4i·oß&,,ì…ÇÖùùù,]º”ÄÄļ«É’-ÿ¼~Téu 'NœtBB………,^¼¸Ê¿´……ÇŽcÊ”)¼óÎ;Ìž=»Äp›6m¢K—.lß¾½Z§wïÞ¬Y³† 0yòäì\¹’áÇóóÏ?¿rÏ‚qãÆO¬©ÝÝÝňæÅlÞ¼™ˆˆˆbîiii˜››Ë›¹ýúõ«v»._¾Ljjj‰þëÖ­£wïÞÕV¾:àïïω'žæ·ß~«Òå¥@P­ÆÝݽÄ_¢C‡Ѷm[úöí[£*àU°Z®iu&¼,ÂI #„€!`I’(**!Œ@Pñ\¹r…ððpΞ=+*CAm&##ƒzõêUxºãÆc÷îÝ¢‚…€Ôf6oÞŒ»»;;v$::ZTˆ0AÅóÎ;ïpñâEQBÀ‚ÚŒx:VPmˆ§ck¹€Q©ThkkS§Ný K|ÅQ x^ç§c‹ŠŠªÔúþ•["|xm¿C‡abbB·nÝ*%:’$IUñe,,,ðõõÅÙÙYŒÌׄuëÖQTTD½zõ˜2eІ_BBþþþÔ­[—Áƒ;,iPZXX0iÒ$yOdÈ!´k×®Le[³fÍ ý ‹)„|ÈØ±cKô÷óóÃÜܼDõþêâÚµk?~¼Ô¦ ÕÁ¾}ûˆˆˆ`Ö¬Y˜™™ñÁÈ69ŽŽŽìÞ½›¬¬,ŒŒŒ;v,?ýô¹¹¹œ\ºt ///>ýôÓ*o»²¶QµÍ`\\\ؾ};mÛ¶¥aÆœ>}šÓ§OkH[…BÁܹsqttÄÇLJQ£FU›pðööæÝwßÅÇLJ֭[Ó·o_,--eGGGnݺŅ 8qâW®\A©TÒ¡C‡J+Ó°aÃGOOÖ­[sáÂŽ;&ûÏ;…B»»;ÿú׿X´h …¢Duýª¢uëÖèééΰaÈ%88XöW—³¤›ê¦S§N´hÑBV“oذ!žžžxzz¢««Ë®]»P*•4kÖŒ?ÿü“·ß~[î/j(((à§Ÿ~B©TòøñcÚ´iƒ±±1|ðÁüñÇܺu ÆG½zõP©T¤¦¦¾”Š~IlÞ¼™»wï]lŒ©Ü-ZÄ¿þõ¯ k#qŠT†™VXXS§N%11‘éÓ§³qãFòòòHJJâðáÃ|úé§ìÝ»•J…··w™;… f‘””ÄêÕ«ñõõИ feeñïÿ›ŒŒ † †••[·n%77—ððpÖ¯_ÏÞ½{100 **ŠÉ“'†±±±,ø8tèIIIÄÅÅ‘––†¡¡!3fÌàÚµk9r„ñãÇ¿2¯ySÆNfjjŠJ¥"##ƒzõê¡££CQQ‘¼ÿbbbBJJ *• 333ñŒèkBQQÙÙÙòåWiii˜˜˜ÈþÙÙÙrŸ044$--ÜÜ\fΜIPP)))PPP€‰‰ IIIhiiaff&§•ŸŸ/ïÛ¥¥¥add„$Ilذ‰'Ò¼yóW¦¾„€ª€ˆˆˆRß¹ò4©©©$&&¾rïý?žŽ9­ x¦ IEND®B`‚snd-16.1/pix/fmeq23.png0000644000076400007640000000040511147553267012750 0ustar bilbil‰PNG  IHDR '°p0PLTEÿÿÿàààððð€€€```ÐÐÐÀÀÀ   000°°° PPPppp@@@mz¸¿ pHYs  šœtIME×ùsàhIDAT×c`€¶‹ÌdTœ Ì , oÌÂ€Ê €¢K˜€Ì l  LI œ4t1tÉ2Hd¨ÞµÇ€ÉA‘ác+ƒ›ƒ"ÔügË€ üa-ÓIEND®B`‚snd-16.1/pix/fmeq54.png0000644000076400007640000000070311147553267012755 0ustar bilbil‰PNG  IHDR\ ãù83PLTEÿÿÿÀÀÀ€€€ÐÐÐ ```PPP   ààà@@@pppððð°°°000^Q(I pHYs  šœtIME×  ! ì¨5#IDAT8Ë•”Éà E‡X ¶ÿÿµ§ªÇ,ê"qx—à°7~èï²1Ÿæ·7ÑXÓÇ>¤‡ð,‘ ÒÀ㌯¨±cêVY}ïspQˆò]ùð^ñu~Ì\[”+>ùâÁÖñ†^#S§º ƒ®xJî˜8Í#‹ ¾¡¯‘Þ%ºÌÉÊšæ-—H­©´(~ûÿÀŒoèdy’UØ¡ò˜‰«bÚFZð Ë{aé*¸²ŸÊƒ7E7ŸFa¦jÐ@_R€^X^¿`c6Æ$ˆêQ;kvÍ–R ¢X-o¼â3ê!ܵ†´°ÊIY9ÊÞhzN™‹¢wñþè9T^ñeŒSa±¦/®·;–Ž·ˆù\˜D.CtðW›ð–K€?ÛÀýãá k,ø IEND®B`‚snd-16.1/pix/fmeq5.png0000644000076400007640000000132711147553267012674 0ustar bilbil‰PNG  IHDRô[ìS3PLTEÿÿÿààà°°°   pppðððPPP€€€@@@000ÐÐÐÀÀÀ``` CY¼ pHYs  šœtIME× %¤5D7IDATXÃÝ—‹Ž„ E)EAåÿ¿v¡<|Q4›Ì&;MF½)m„`M[ñÆÞ©þ‰ió µÄF~ÊëÌÿS梟f|)ü¥e>kjz"Ü}¦kڇŧü6r:óY“ò‰pWô™#´Gÿp¾æÄž?êÕ~Ž RBj,5Ά¿zΑu–spxÅx“}sšÊoaƒ Æ„Dí°¨REa¢ ?*°A†á²K¹ž’3´ÆpÃD‚gó»Í>ƒYMåß?I$§83MX#´S9Efê!$çh¨‹‹c ×#ñ!=0‘^L—§ 0Õ0}Úì˜×Tþ½Æ’ˆÞë"eºR9Efb¼WÒ.n[|ªäôË{É›iw)–=í¸Y”aŸÀMᇠ(–ºžE®¾<»´SYEbšÔãÔ„cȆÁf§a»Íw{¤ÓMÕsšaŸÀEé슕Ò$ÑÕ¥cw{ ²œ’ ·4Ò”c®S7Óà´kšXÔ¿’ƒvOo›+¨É>yMåß3(‰®.©Œ¢0gK¢5^hÌ·!ì&|;Òá¦W¢–BËÚì3¸§Iü{%Ñ-Ž;µ£ &(RSd¼Õ>vƒjl±VNà˜‰Ì¢É'üª¯É>;dF3‰Ü8`†ÏT^Q˜{£Ë>C¥ÂÒ—ű%so±Ûb_À=M{[Àm†*µ«è-ÍÛ—†ß³Ëò/z_dæÝ’ÚëorZÀ»Hÿ?Ç~;]{ÇÿnIEND®B`‚snd-16.1/pix/sceq14.png0000644000076400007640000012135511215702602012744 0ustar bilbil‰PNG  IHDRN,å×òsRGB®Îé pHYs  šœtIMEÙ ":KW5 IDATxÚì½yTS×Þø½C„f[° bpD*B´ ÑúÔ-ú(UT´Z+®.½jm{yV»ÔÞ[- …×UÔB¯"P©È Hd ³@™!È„ çýcß{nš„pa’ýùƒu8ÙgŸ}ö9ß=~†a1½Á0ìöíÛþþþ:::Ó¹œl6[OOÏÞÞ½²iˆª‚éÏ_|±páÂi.營~ú©ªª ½2$êˆ1óàÁ==½­[·Nÿ¢’Éäï¿ÿþܹsƒƒƒèÅM7Hh?éììüàƒ˜L¦žžÞL)s||<‹Åºzõ*z}¨WGåÊ•+Ÿ~úéts>ŸF$åŽ;˜LfSSz}HÔ„èëë‹÷õõò’‡sïÞ=BE騱c7nܘˆæ&--mpp077·¸¸ ‘H222ø|>­ QŸ.DFFVVVOÿðáCOOωëÒ•%g$¨Tª»»»®®.Áœ}||bbb¤R©v«…Íf—••EFFnܸñúõë&“)•Jãââ0 »xñ"úƨO ËËËÇ4éçj\ssó˜$G[˜››[ZZæççk·ZœœœŠŠŠüüü€õë×?~üØÛÛ»²²råÊ•èSÜQþçÏŸÓéôââbCCC´e:bbbˆ'–ÉdL&“àôx$nÞ¼©fyÌÉÉéÞ½{7oÞÄ%§¿¿_¡FFFû÷ï×àÖt:ÉdnÚ´I‹ÕbllÜßßoll\PP°~ýúúúzkkëÎÎÎ ÄÅÅýå/Aߘæ¢Îf³¹\nuuõÉ“'ýýýïÞ½‹ªŒ •••¯^½244455]±bE[[[eeåÂ… mmm›››kjj¬¬¬ôôôŠŠŠÖ®]»dÉ…Ë––– çKKK{{{]\\***:;;]]]I$’f%T)9/oii©­­Å ÐÚÚº`Áüו+Wfddh·Zêêêlmm0Yoo¯µµõüùóËÊÊ¢££ÿøãôÕi>€W2!ˆœœ\]]íáá±dÉ86ááá±±±ð844ôÚµk<oË–-GŽQ^Rª««S–ÿ¤¤$ …244tìØ1¡P– q!•%g¤”‰$>>¾­­íñãǯ_¿´µµ•––fgg'%%vïÞ-‰••UMMv«ÅÚÚ:((pàÀmÛ¶988p¹Ü£Gš™™Y[[¢OsQÇ~6› ~TeD`±Xmmm†ÍŸ?ÿÿ÷ágêèè¥ÑhŽŽŽb±xãÆ ÅÞÞ>//O!‡¶¶¶·ÞzKþÌàà X,¶µµ¥R©]]]çÎóööָʒ3âØoΜ;wVVVîÞ½ÛÄÄ““ãíí ™žžîêê*É[o½ÕÖÖ¦Ýj!“Éúúú‰dff¨¨¨¨¯¯‹‹»|ù2úêÆ5€W9dBµ6*»víúòË/ÿïÿþž”i“H¤E‹á_°X,VÈ¡¿¿ŸJ¥ÊŸ144üàƒL&ÓÃðaÃ…«ÚÛÛøáü_ƒqáÂüŽ—.]222‚ÿ¾~ýZ³…€uëÖmÙ²eÏž=ííí<oýúõðF Sz##£þþ~-V‹H$ V.T*%“ÉQQQ€£G¾ýöÛèóÓDÔåþ¾¾>Ø”"Fe``€Íf·´´<{ölÿþýeeeÊ3jõsl™L6Ò6ƒÁ€£_8à’ÿiÞ¼yòëp.\iYÎÀÀàÃ?ÔàÑ`¯øã?Þÿ}‰„aXVV\ޓ‡µX-ººº£ØÔÔ}{Š:™L&“ÉòC&¢££Ïž=kiiyôèÑœœ‰D¢««+¯ƒ<Ò1…BQèêKKK»»»7lØP\\lggHLLÔlyŽÉ—.]ª|ðäää®®.*•êãã£&‡ÆÆÆU«VÁŸ……Þ@…BÑbµèèèà&^HQQGh†D"¹s玻»{WW—£££®®.‹ÅJKK“J¥ÞÞÞ ##C"‘dee‰D¢‚‚çàà ?[677ïëë“Ï3!!AGG‡Çãùùù±X¬ööv"[Yc%..ÎÚÚÚÛÛÛßßßÄÄÄÓÓs¤”Û¶m‹ŠŠZ»vmpp°òF×àà ¹¹¹Ö«e¬…Dü©Gh¡¡!™LÆãñz{{5ËÅbÑh4ù30C±X,“Éš››‡‡‡GÍäâÅ‹c½o|||LL †a—/_),Ìëׯ[[[}}}srrMééécøq¶8š](•J·mÛÖÔÔ4R‚´´4 ÃŠŠŠ>úè#åׯ_˜Ð*µyþeÄZ[[kkk‹aتU«h4šÊU"¡PØÓÓÓØØØÕÕOÞ¹sçðáÃhd4AØÚÚ>~üxõêÕ“ëŸþÙÑÑQÍö[gggJJŠ¡¡aSSÓ‰'”W:äìì|âĉ),$Bõþüùó€%K–¨\ÁØÍ›7mlld2j/'ˆS§N…‡‡Oþ}“““kjj`­Y2™ÌÆÆf2m 9{ðÃÃÃNNN€½{÷`¡PxôèÑììlm¥»»›Á`La]ðùü”””éónÒÓÓwìØ1É7MIIY±bÅ{ï½çää”””¤Y&\.wݺuÓ¼³z®þòåK¸eòóÏ?¹X"‘„„„¨Os÷îÝŠŠŠQ³‹Å_}õ•D"ÑúJ$’   KKK‘H4jâ'Ož0™Ìiòn¤R©]ggçŒûª.\¸†¤kZ/ËEGGôõõËÊÊ ’ú¾¾¾>5Ÿââb €ÈªLII‰««+ña3‘Far¸{÷î×_=³>©×¯_ÛÛÛk¼"ˆ˜ uà÷íÛ  ÷íÛ7444êT*ب!&&fÏž=êÓH¥Òœœœµk×j°Ö  ¤5’zq GGM“•¸…þêÕ«´úsåÊ•óçÏ+hõ"¦æ.ÁÁÁ+W®,//ÿì³Ï4ȱ²²2===??¿²²²­­Á`TWWš››322êëë[ZZ~ÿýwh¤ ÉÏÏWð+PZZ Ò\.733Ÿ¯Kƒáî®ÎÎδ´´ÈgÛÚÚŠ'öòò‚†VÓâõèè„„„|þùç2™lF|Oùùù­­­ëð!&UÔ cbb(JDDÄÇÇ”‚•"Aż¼<¨é Ñ®©¦L&ËÏϧÓéiii"‘(00°  @¦©©i{{»B&"‘¨lÊËË zVÒŒåË—;vì›o¾™þÇ ÕØ„1q¨VŒµ³³ >uêT@@Àúõë­¬¬fÇb±,X€ýÛJš(ŠD"ðoÅÚÚÚ7 ‰âòåËá'‚ëx⦚­­­¸©¦|C0VÊËËi4Znn.F[¼xñ7x<Þž={~üñÇ-[¶U˜2™ ÚKág†††^¼x1Ò-¬­­ &î%yxxXYYa6ÍEHGG'<<Ú™"f†¨>þøã”””ØØØ0™Ì9siË+[)1Q …¸ƨ¦šÄí4ñB¡ÉdÂ9‚³³3ÌD¦®®®H$’—^sss蟃¸vGCCú¼&Ÿýû÷¿ûÆ ê$éÖ­[l6›D"Ÿ(*[)*g«|•‘‘‘@ Pž`«4Õ$n§‰çsõêU¶yóf.— sSo€9<<¬Ð5uttŒäí˜D"?^¡}9xð D"AŸ×äƒ|ÑŒYÔá÷maaGÜ?±²•"FÀDqéÒ¥¸oSíšjÊd²‚‚:N¡P Ã¬ÔÔÔÝ»w«7ÀÔÕÕUfaaíöUW¢ÒGÁŒ˜¾¢ÞÝÝíçç5&· VŠ………DL7mÚ½oß> mSÍêêj[[[h8M§Ósss¡«C5˜*×&NaÞTà‹[·n™™YUU\dAÌ$FRzõððÐ@KT3+E™Læëë µqÇjª©ÞNS"‘ðù|x,‰ÚÛÛ±Ñ 0oß¾={t- ê2b––––’’rûöm™L¶{÷n¤‘2ãUh ðŸ8qbÿþýXüS©T‰ôÎ;ïŒÉe ‰DòññÉÌÌ„Çï¼óΜ9sH$’¥¥å¨E¾úê+5¿’ÉdÜ ‘žžž…… ##ãàÁƒÆÆÆ­­­ E~Ôüpe~6@<Ü ®0ÓQ!ê—/_ž7oÞñãlj\_TT¤•røúúæææj¬W­,;;»“'OÆÇÇçääܺuKþ§{÷îΞma"ºŒ\aLª‡ˆé;W‰‰áp8¿ýö‘‹ëêê233µb0L"‘Î;ÇápètúD?óÛo¿}àÀåó}}}ööö+V¬xƒß·|Ä33³1E¡@ÁÞœ¹:‹Årvv 2»NHHX°`A]]šÍž={aXkkëñãÇ_¾|¹ÿþ+W®`V]]½wïÞÓ§Oçææ …Bww÷ÊÊJùkËËË9NSSÓáÇQMÎDþÓ«744øùù………©ŒëíLù|~SSSYYYbbbEE…›››J¯£ˆé‰fºŒŠŠ ììl\afà¶oß^WW7¦)Tƒ3Ít!†††iiid2ª­X±½ý)êT*.€ ä~f¡™.#dë֭㌘¢N&“"„!Þ<4Óe”?‰-ÌxQGÌ4ÓeÄ/Gf4¤qz}@Ì ¾¾~ss³±±±“¯„„¡Pèëë{åʃ³gÏ¢*Á¢Îb±®]»6ªGŠôôt]]]©TŠ´)f2™ìþç"""ð5<ÄŒ@Q[nþüù666ê¯)((¨©©qqq))))))A•8«ˆˆˆøöÛo‘œÏxQg0®®®­­­ÐÁ»Êkâãã¡ôÊ•+Çã 1ãHIIñôôtppàp8¨6fŠËrYYY===QQQfffyyy |}};:: »¾¾~GGªÄYBjjj``àܹs% Ü–GÌTQÇ0¬¶¶öÙ³g§OŸ¬Y³FÅ5sæ@¿42™l–[qÏ*<==+**P=¼ ¢ÞÐÐ@§Ó·mÛöÝwß9rD,gee)\ðᇮ^½º··ÐÝÝýf‡ o¦¨gffzxxXXXÉ人:///•ÎF3èììüàƒ˜L&ñP™SN||<‹ÅR'zuÄŸ¸råʧŸ~:äœÏ燅…I¹cÇ&“ÙÔÔ„^u!úúúâãã}}}§¼$€ÃáÜ»wЈ‘D:vìØHqéÇÙܤ¥¥ æææÂõ?‰D’‘‘Áçóh‰úLåáÇžžž×¥+KÎHP©Tww÷QcfâøøøÄÄÄH¥Rí˜Íf—••EFFnܸñúõë&“)•Jãââ`p^ôÍ QŸ‘ÄÇÇOèjœ²äh sssKKËüü|"‰###+++‰¤trr***òóó (–ȱÄtG&“1™L‚Óã‘hnnVã ÎÉÉéÞ½{7oÞÄ%§¿¿?&&F>‘‘Ñþýû5¸5Ng2™ò‘­G"11ÑÐЈccãþþ~ccã‚‚‚õë××××[[[Ã@±qqqȵ©&¢ÎçóŸ?N§Ó‹‹‹ íííQ•M2KKËñdróæM5+á*%' @+å_¹reFF‘” ‹êêêlmm0zloo¯µµ5 ;.Qg³Ù\.·ººúäÉ“þþþwïÞEU6VJKKkkk­­­ß}÷]x¦¤¤äÕ«W .\»v-<# Y¡[«««SŽŒçÜÛÛëââRQQÑÙÙéêêªYdx•’£2¥D"ILLlkk{üøñæÍ›MLL---µµµøÝ[[[,X€_beeUSS£œ•Â#·µµmmm8pà@__Ÿ™™—Ë=zô¨™™™µµµ¡¡!úêÆ´C(“’’‚»Ü=räàÒ¥KVVVòƒÛ§OŸž9sF!²Â²œò6›¡¡á|`2™€ 6È'hooÿá‡ð Æ… à1‰Dºté’‘‘þkjjªO·xñâ­[·îÙ³§½½Çã­_¿ÞHaõŽL&+\«þŒ%4ƒÁPÎSž­[·.^¼}cuåIª2âP(…/ROOO~$‹á…XÈò=…BQøÐ>z8†ƒ/üü¼yóä×á.\¸ fYîĉãyÌ?þøãý÷ß'‘H†eeeÁ•|@@¡P.QÿÈÊ’¯ í®ý¹ºò¤Aœ;w²Ùl\PSRRöìÙSTT$?Âß»wott4ŸÏ‡±étºD"‘ÏÄÜܼ¯¯OyAŽÁ` Ãq{bb¢v aسgÏîß¿çÏêÇÿ«V­‚C? 8‡—Ÿk˜››+\¢ò‘Çz¬…D }õ ÄÊÊêÿøÇçŸ~ðàÁW¯^ÙØØ¬Y³æøñãׯ_ÿË_þÂd2ýýý×®]ûÏþS>²‚.𥥥ò²VBB‚ŽŽÇóóóc±XíííD6®ÇñËÛ¶m‹ŠŠZ»vmpp°òžvKK‹ò–¾Bøg]]]‹5¦Ðc-$`ˆ fxx¸±±qxxx¤3CCC2™ŒÇãõöö*_ÞÓÓÇðò'az±X,“Éš››å3WÉÅ‹ÇZìøøø˜˜ Ã._¾ŒšË‰ÆÖÖöñãÇ«W¯Ö8@ ™ÇþQC,§§§1™L‡óÃ?DFF*$8tè³³ó8—ÆYHÄŸzu§eÉ’%êZØß¼yÓÆÆÆÁÁA&“¡ör¢9uêTxxø”Ü:,,ìùóçjtttÜ¿?...$$D$)-666555S[H†a@~Téä䨻w/ …G…±™JzzúŽ;&ÿ¾ÉÉÉPJ‹ŠŠ4ËËå®[·nšrÖ‰:†a/_¾„˧?ÿü3‘‹%IHHˆKÓÝÝÍ`0¦°:ø|~JJÊt{IR©ÔÎή³³s2oš’’²bÅŠ÷Þ{ÏÉÉ)))I³L.\¸6Í 9Eðèèh€¾¾~YYAi×VQÄbñW_}¥Å å dii©<ÂTæÉ“'L&sº½§»wï~ýõ×3ëÛzýúµ½½ýÐгé(ê†A“¦Õ«WNfQBBBŠ‹‹5»¶©©I}‚’’WWWâsc"Â$wì^^^---3èÛºxñ⃌MT¨Ð¯\¹²¼¼ü³Ï>›´ÕA©Tš““ƒ[z -•ZeÄ͘=<<=z4½TttBBB>ÿüóéï’ŸŸßÚÚª™‰;b’´å cbb(JDDÄÇ5È´´´ôñãÇ/^¼ÀÏ”””$%%•””àg*++ÓÓÓóóó¡ã‘üü|eç!¥¥¥p,Íår333±q8·e0îîî€êêêììl\»C>ÛÖÖVxàåå5 µ¯–/_~ìØ±o¾ùfúU</44444T3£ZÄ$‰:ÀÎÎ.88ÐÐÐ0¦53ÛÌËËS0ÌÒ¢‘¦L&ËÏϧÓéiii"‘(00°¾¾^õ¥©©i{{»r>"‘¨lÊË˵îAMåpã£>¦½?oððpÍvòÄˆŠ±üqJJJllì˜Læœ9„Th56ÛäñxòªÚ5Ò,//§Ñh¹¹¹4mñâÅ7nܰ²²ŠUc})“ɤR)™L–ÏghhH~¨¢€µµµ¼á$ŸÏ/,,œˆwöòåKôáŽÊ²eËä# 0‰Dºuë›Í&‘HÄ燛m …BySMíi2 ¡PÈd2áÁÙÙ ÞúRWWW$)Ø<›››C/DH$½½½è ›*„B!ªB¢èèè°°°ˆ‹‹#î–Xc³M###@ rŽ=~#MƒqõêU¶yóf.—‹g¥Æúrxxšô)TÈH^ÍI$ÒùóçåÛ—·ÞzëÃ?D_bº0ÒÒ|WW×úõë¹\î˜ôëëëi4n}‘œœ\ZZêáá'زeKqqqPP®~{ôèÑáááŸ~ú)::Z~o,##c```îܹR©ð_ýUÍ}ÏŸ?¯f›jÑ¢EB¡ðwÞyÃ°ØØXøÓßþö·_~ùðªª*GGGù«ÜÜÜFÚü‰Y²g#‹ÓÓÓá뫬¬D›X32œE+¯?íÚµ+((ªÊÇÌÌlñâÅsçÎ-,,\¼xñš5k(Jrr2…B‰‰‰qvvöôôLKK«®®¦R©åååT*š1¦¦¦âFˆ·nÝjiiinn~ûí·MLL œœLMMGº¯üµ TUUåçç=zÀb±,--MLL ]•JMJJš7oÞßÿþw;;;///¼÷f³Ù»víR¹à43ºÅŒŒ¤P(*Ø)‘d2YAA½½ý‰'öíÛ‡ú˙ګËd²C‡EDDhÜ~h`¶)“É|}}qÝ{-iJ$>ŸE"Q{{»ü-TZ_Þ¾}{¶iYúúú>|øHʾ¾¾O>ùäÕ«W\.÷‹/¾@½å Ö–ûöÛo?ÿüs‚×kÑ¢(:::##C³k5оLKKsqqÁ0¬¨¨î`áþS§N!‹=5|øá‡†…††&''£Ú˜)(.ËÅÄÄp8œß~ûȈ ®®.33S/á1áëë{åÊ• 6hàÇ[ƒ-\;;»“'OÆÇÇ755ݺu ?ïÞ½ÀÀÀ7[÷c$ìê°CPp…?€g±XÎÎΣ¶2™,!!aÁ‚uuuZlx„B!‹ÅšÂ–Ïç¿xñâÍnÝŸ={aXkkëñãÇ1 {ùòåþýû¯\¹R]]½wïÞÓ§Oçææ …Bwwwå…·òòr‡ÓÔÔtøðaÔUÎÈ^½¡¡ÁÏÏ/,,¬¾¾^e‹ ‹ù|~SSSYYYbbbEE…››ÛÒ¥KµØîP(:>… Ÿ©©é¬JöQ°***ttt²³³Qp…¹¯>00°}ûöºº:¨:Fä£w&¢Þ»zì===ÝÝ݉DOOïÉ“'ð˜¸hÐí‹:•JÍÌÌëÅÈ]ôLdTìjÖ)¨Têÿ÷ËŸQÐFLwQ'“ÉDöToÑÑÑgÏž…>Øsrr$‰®®.nBƒ©uÀN¥R’““»ºº¨TªªÏ&êˆÙƒìÆÆÆ£:`G®×g(¤éo‰Ð.@__¿¹¹ÙØØXƒ)XBB‚P(„;£gÏžEU:#EÅb]»vmTéé麺ºR©”¸kÄ›r½>ãPÔÜž?¾úk jjj\\\JJJäË fß~û-’ó,ê ÃÕÕµµµ:xWyM||<4ü^¹r¥Æža3—””OOO‡ƒjc¦ ¸,—••ØÓÓeff–——§À××·££n¥êëëwtt JœU¤¦¦Î;W"‘(GƒGÌ QÇ0¬¶¶öÙ³g§OŸà.eþtÍœ9Ð/L&#èˆ ñÆàééYQQêaf‹zCCNß¶mÛwß}wäȱXœ••¥pÁ‡~¸zõjèJ©»»{ÅŠ¨ˆ&ê™™™d2¹®®ÎËËKAÿrðàÁëׯ»¹¹ Žbšó§Í6¸ãJ"‘úúúŒÕxV\.wÕªUÈ01óD@¼©è *@ ¨#$ê‰:@¢Ž˜`öË/¿Ì”Ïò°Ùìââbô‘¨#ñÅ_,\¸p&†²pppøé§ŸªªªÐKD¢ŽBX IDAT…èéémݺu&žL&ÿý÷çÎD¯í«#éììüàƒ˜LæŒöÏb±ÔíD½:b¶såÊ•O?ýtâäú¢¿ÿ~llì˜.äóùaaaïØ±ƒÉd655¡ŠD¡‚¾¾¾øøx__߉»E\\ܼyó<˜ššJð*@ÀápîÝ»Gt¼J";vl¤ ÙHÔ³‡zzzNèÐL&WWW–/_^^^ÎçóÓÒÒsssÕ¬œS©Twww]]]â7òññ‰‰‰‘J¥èµþGÔ5SuX…˜d"##+++Ç4ÅèÕ¸;vÀ¨»YYY{öìa³Ùeee‘‘‘7n¼~ýºodnnnii™ŸŸ¯õZš‰ÌÁÇTšyüŇU§NBr5 ILL444$èV@&“1™Ìq6ÜÍÍÍD|ÎáÞéLLLîÝ»wóæMÀÀÀ@LLŒ|J##£ýû÷kV:Îd27mÚ¤ÅZšÙ¢ÇTï¾û.S­_¿þùóçt:½¸¸ØÐÐPM3 †UˆÉDAlÔÓØØ°´´ÏoÞ¼9êº7ôN·lÙ2‡óî»ïö÷÷¬_¿¾««+ @[¿råÊŒŒ íÖÒÌõ;vÀF=+++""‚Ífs¹Üêêê“'Oúûûß½{ÉÌLA> ²™™Œ¦lkkÛÜÜ­ªªzúôé‘#Gž?¾oß¾¸¸¸‘Êpþüù1•Y"‘É»··—ø…­­­OŸ>ýöÛoÿøã Ãêë뜜Ò<þÜÒÒR[µTZZúâÅ //¯{÷îUVVvvvzyy/Ìt º¬fLU__omm­Åab‚P¨ŒGS ¨Üß߯ìVhppP,ÛÚÚ¶¶¶vuu988œ;wÎÎÎN[e&“É0Æ#‰DS´™œœŸü†NOOwuuUHcddÔß߯­Zª©©ÙµkWmmí† lmmE"Q]]ñÂL‹¼fcª‘†Uˆ©B9 ²ü0[}@e8ƒSÞf344üàƒL&ÓÃðaÃùííí?üðþ/ƒÁ¸pá~ÇK—.Éÿš””4þ'=yòäž={ÚÛÛy<ÞúõëaÎÊ«wd2yxxX[µ´{÷î—/_Λ7JG^^ÞºuëàOD 3-D]Áã¯T* 8p ¯¯OM[;gΜ;wîܹ‰Ùt@9 ²Bõl …¢,ÿòR 7Ãàˆ??oÞ<ùu¸ .¨Y–ûË_þ¢Åà_üñÇûï¿O"‘0 ËÊÊ‚Ëøò …¢ÅZb0nnnð866ÖÇǯQ 3µèŒ4¦Ò×××`L…˜Z¢££ù|> ¨L§Ó%ÉHA”UÚ>˜››÷õõ)/È1ŒÁÁÁââb8nOLLœ¸•£1éw466®Zµ ?-,,”•ƒƒƒæææZ¬¥ÌÌL(ê†ýþûï;wîÄþF-Ì´èÕo • a4eooo@0j@eKK˶¶6…<tttx<žŸŸ‹Åjoou›Zcƪ߱mÛ¶¨¨¨µk׫,´´´(oò§–ØlvHH<^±bEQQÑ;ï¼C°0Óh1Ó’Éd<oLKÙ8===p /f(‹e2Yssóðð°úL.^¼¨qùãããcbb0 »|ùrpp°úİ`¯_¿nmmõõõÍÉÉQNsýúõ€€-ÖRww7~<88ˆÿK¤0ÓeP[[kkk‹aتU«h4šr» “É„BaOOOcccWWÿüó™è’ŸŸßÚÚ:ÝTS§øµŽôƒ¡¡aLL œŠ?|øpLµ¼råJ­ÎËË jM)~WNYZZúøñã/^àgJJJ’’’JJJð3•••éééùùùÐ߈Êr–––±4—ËÍÌÌÏ¢ƒÁpwwTWWgggãòÙ¶¶¶*<é4aùòåÇŽûæ›ofâ7ÍãñBCCCCC56³]¢°³³ 444Ì1//O[fO¦¦¦ííí€}ûöy{{ÏŸ?ÿ³Ï>Û¼y³B²   ¢¢¢]»võôô@Óú   >Ÿ¿uë̟֨œœ\]]íáá±dɨȭ\Τ¤$ …244tìØ1¡P– YÉe2Y~~>NOKK‰Dõõõmmm¥¥¥ÙÙÙÐÞ£¡¡a÷îÝ Oª€H$*òòò õšæááñÑGa3Ðw¸ŽŽNxx¸²‰uu|üñÇ>>>}}}H$ÛT-ZäËd2©TJ¥Ra mjjªo„Ãá$&&>|˜D"566VUUeeeUWWCÂM›6ÕÕÕeff²X¬¶¶6ìßv‹ÊåÄM5©T*nªéíí­Y±ËËËi4Znn.F³³³»q㆕•UNNŽ··wvvö[o½”ìá“*ä344ôb8´»œ8–.]:;ÆE‹A „<£èÀ“H¤[·n±Ùl‰Dpæ&  !CBBTFÕ177uˆ¨««+‰p$eRRRÖ¬Y9¸té’••žÀÊÊêéÓ§gΜQ°[T(§ÖM5…B!“É„s¨°¥ÞÎQ哚››ûùù|—mmmp†˜&\¸paúX‹nîÒÑÑaaaGÐa°‘‘‘@ ?sæÌË7<<¬¾…¦P( Ézzzø¿b±žQ°[T.'.¥ã7Õd0W¯^¥Ñh›7oær¹DìU>iGGÇHžÌI$ÒùóçåÛ—ùóç£`& E½»»ÛÏÏ/**êí·ß&>êknnÖ (*§…ºººê#îܹó§Ÿ~‹ÅЕeJJÊž={Ξ=+?ÂÿÇ?þ}öìYh·˜““#‘HÊYZZÚÝݽaÃySMÍ–pe2YAAN§P(°ÑIMM…Ór5vŽ*ŸÔ®5¨~ysf—a"48[·n™™YUU•‚ „zÈj¾$‘H´k×®   ¨*K]]ÝÔÔTâî¥qqqIIIb±¸³³ßëèè`³Ù»víRs­™™ÙâÅ‹#""æÎ[XX¸xñâ5kÖP(”ääd …ãìììéé™––V]]M¥RËËË©Tª£££B9oݺÕÒÒÒÜÜüöÛo›˜˜:99™ššŽt_5ÏXUU•ŸŸôèQ‹Å²´´411¦”T*5))iÞ¼yÿûßíìì¼¼¼F}R‘™m+ƒÁ€Í¨½½ý‰'öíÛ‡xl}éH-‡ŠˆˆëN½L&ƒýÇ¿éûöí¤¤$")‡‡‡åí+Î(Û-*”S‹¦š‰„ÏçÃc‘HÔÞÞ>ª#ñ'Íôõõ}òÉ'¯^½âr¹_|ñªí¨Ð\¾|yÞ¼yÇ'Ò^ÉÏ!}||ƯXÛoè”ÈPbñâÅòîèÎÀ5üwÞy_&Q('üuΜ9$ÉÒÒrTÏöjL5Éd2>ÐÓÓ³°°À/466nmm•·sÓ“ÎfLLL:;;,X0&õ$Ä¿†‡*ÏÆÄÄp8‚klŒ1!ÿéÈÕhË!ZDc½FùLâââ-Z´eË–ï¾ûÎÈÈhéÒ¥¨b BRÖŸ6 k‰D";vl¤Øã|ä´´´ÁÁÁÜÜ\|ý¯ººÆbH$|> ¿^ÐÓÓ£à–“Íf?ù70Ÿ7>{ö ‰:â_<|øÐÓÓs:té€ÃáÜ»wOù§žžžñ$Þö¥¦¦*Ÿ÷ññ‰‰‰‘J¥Ú½›Í.++‹ŒŒÜ¸qãõë×áÉ¡¡!xÀd2¥Ri\\ :R&)))µµµ/^¼(..&“Éðm’H$|º®£q;4=›^ 22²²²’xúøøø ]SÙk©„J¥º»»+ÇÆ”H$ÁÁÁÎÎΓS¦¦¦"‘HÙvÛÜÜÜÒÒ2??_»¯ÀÉÉ©¨¨ÈÏϽeK¥R|Ësýúõ?ööö®¬¬\¹reeeå­[·nݺ•ššûúú6mÚ´}ûöuëÖ-Y²dÛ¶mÐI¬:ÍE]MÓ‹˜$&&–——L,“ɘL¦‚cÖ±ÒÜÜ<Ö^kLüüóÏ{÷î%“ÉÚ-˜¶oßþ믿*Œt:Édj÷÷÷÷³Ùìõë××××Ëïw*ÄŸ]±bE@@@@@€§§çG}MMM ýõWGGG…ûâžct´Øô"¦ 111Ä],666,--ÇsÇ›7oŽ©×êïï¿õg¢££Gº\*•æää¬]»VëS‡‡Ç£GN®\¹’ˆ:͘^A]]­­- ¦¦ÆÊʪ··—D"éëëã ÆŸe±Xo¿ýv__ÞÀa†Û˜Ï‘oz¹\nuuõÉ“'ýýýïÞ½‹dfFPYYùêÕ+CCCSSÓ+V´µµUVV.\¸ÐÖÖ¶¹¹~=zzzEEEk×®]²d‰òw¦|RZZÚÛÛëââRQQÑÙÙéêêªYdh¼×*((€½–µµu@@ÁËóóóñá( ¥¥¥¶¶/ t,­YÕÉd²ÊÊJù®›J¥âŽX¼¼¼âÆYYYÕÔÔ¨ fffczÖÖÖ0Ãúúú «\[[[øh\.÷èÑ£fffÖÖÖ†††ò³ …î644ðý÷ßã⟟ïå奨«³éEL ÉÉÉÕÕÕK–,cc@ƒŸ‚ÐÐÐk×®ñx¼-[¶9rDYå«­­Meô®¤¤$ …244tìØ1¡P¦±k`å^k¤”‰$>>¾­­íñãÇøNR^^ž^ÚÒÒÒìì줤$@CCÃîÝ»5+ÕðððÉ“'¯_¿þÿþßÿûùçŸáßû÷ïËÏØÛÛÛ®zë­·ÚÚÚÔ¿…±¾2™ ûp‰„»Ä>tèГ'Oõõõqqq—/_–¿jóæÍ¦¦¦òg à_ØÊd²ââbÅ^}œM/bJPŽ[jmmíèè(‰4ÍÑѱ¶¶vãÆ{{û¼¼<÷aýýýÊ~„Åb1ìXºººÎ;‡ËÛXQÙk©dΜ9;wîܹs§üI‡\srr|||~üñG,8==ÝÕÕUãVòêÕ«fff‘‘‘þþþ·o߆A#º}©T*¿F`ddÔß߯þ-Œõ¨DOOoçÎ{öìÖ`„Çã}ôÑGø@lŽš¦×ÚÚz¤¦7116½›7o611A"7U(Ç-•f“H$Ü_:™LÆC¦ÉÍÊŸ‘¡¡!tþÍd2a·°aÃùííí?üðþ/ƒÁ¸pá~ÇK—.á¿~òÉ'<šÝ§Ÿ~  …x ÷ìÙÓÞÞÎãñÖ¯_ï»ÿ~Í T²³³i4Z[[›JwLººº"‘ö–x*¯Õ)¿⯠¶¶öÿøÇ„~$[·nݽ{÷m5½ˆ)AMÜRùOMM EYþåEÎ àˆ??oÞ¼«W¯âÿ^¸pAþ_ —q122’×åþã?Þÿ}‰„aXVV–ÂÂÛ˜ ×Ï®]»Æb±TŠúðð°üòS(”QßñW°lÙ²qÖAtÔOÓ•qKå¿Ú‘ŽåWwúúú”ä Æàà`qq1·'&&j·äÄcª.]ºT~Ϭ±±qÕªUpøiaa1žAeGGÇ«W¯`¤ç—/_ªìÕìüÍÍÍG} czQi*zh$-3‰DrçÎww÷®®.GGG]]]‹•––&•J½½½AFF†D"ÉÊʉD<ÏÁÁÁÁÁÏÁÒÒRy)!!AGG‡Çãùùù±X¬öövõÛ<gmmííííïïobbâéé9RÊM›6EGGïÛ·þ»mÛ¶¨¨¨µk×34è­[·¼½½K–,QXô‚ •••ÂÉ––åR o¡°°pL¯`"*Mu;˜¹ Éd2×ÛÛ«Y===p /æ)‹e2Yssóðð°úL.^¼8ÖûÆÇÇÇÄÄ`vùòåàà`5)e2 Ɉìõë×­­­¾¾¾999ã)ŸÏ‡=0†aÊxûöí¤¤$…“ׯ_Ðú[Ðz¥)ƒDÑh´²²²q¶8š](•J·mÛÖÔÔ¤>YtttFF†aiii...†}ôÑGZ°S§NÁöEž>ú(<<|jßÁJSà_~àkkkmmm1 [µjFSîüe2™P(ìééillìêê‚'ïܹsøðá‰ÞL"ì1>ùä“wß}÷ĉ“ëŸþÙÑÑqÔÑ,†aW®\9{öìÐÐPJJŠ¡¡aSSÓ‰'&ÎD'22ÒÑÑQ!Hl“’’–-[6…ï‹`¥8€‡ñ˜–,Y¢~*7oÞ´±±qppPnö´ËË—/ÿú׿¢ŽwBIOOß±cÇäß799¹¦¦vÑ£& …p|àóù/^¼P>Ïår×­[7µ/kL•¦z?<<ìä䨻w/ …G…1Øqº»» Æxª8%%EþÌ/¿üòäÉ“W¯^eeei«Yg!µò%)<æ”íìì:;;'ó¦)))+V¬xï½÷œœœ”§ÄÓ“ .„……MaÆSi@¡ …[?ÿü3‘‹%IHHþ¯X,þꫯðu‚dddÈ#ž½QŒ¤ôêáá1&åMyKÃq¢ÒxPÍÌ•Í!µe§)‘Hø|><‰DíííØh—D¡EÒÒÒRRRnß¾-“ÉvïÞ=Û¨”‡C‡EDDŒ5/ÜÒpœj[*µ…Æ…Ô@#RÅåD?&B™¾¾¾O>ùäÕ«W\.÷‹/¾˜m¯b>|ùòåyóæ?~œÈ  ¨¨?öõõÍÍÍg ê{÷îNÜ~Æÿü› IDAT…Ô`[ÕÎÎîäÉ“ñññ999·nÝšÌÇD(£&eÖ=¿r§·gςڑµµµ×¯_WùÇÒp$ãAí2™æSø˜o$%%%±±±?S\\üôéSy»†ŠŠŠ´´´¼¼¿©©©¬¬,11±¢¢ÂÍÍméÒ¥hdˆ˜8Nbb"›Í466ÖÔÔdeeUWWýÉM›6………eff*ÇÀÀ©¨¨ÐÑÑÉÎÎVö9‹6Û¶oß^WWƒfÄßß}‚ˆÉ!%%eÍš5ð†a¹té’ün¥••ÕÓ§OÏœ9£bhh˜––F&“¡’ÒŠ+fÕ<_sÒ N=r˜4(ŠBXè¿ÿW,Ã3#ÅÀغu넆‘Ÿ‘ûêÄt£¾¾žF£áêÉÉÉ¥¥¥x‚-[¶áªGUP—ÉdIII÷îÝ{ôèÑl«@²5Lbú`ff¶xñ∈ˆ¹sç.^¼xÍš5 %99™B¡ÄÄÄ8;;{zz¦¥¥UWWS©Ôòòr*•ŠÛ;Bâââ-Z´eË–ï¾ûÎÈÈhV­4ýË94AgÌéé麺ºR©t6îO"¦±X £Žã¡ÅÎ}}ýææfcccå fBB‚P(ôõõ½råŠÁÙ³ggOÕ)ªÐÌŸ?߯ÆFý5555...%%%%%%èûCLººº‹/Æå\ù ôqðÎ;ï¨\HÚ±cÔŒÎÊÊÚ³gϬª:EQg0®®®­­­Ðë³Êkâãã¡IöÊ•+Ç㶘"""¾ýö[åÐko6ŠFTYYY===QQQfff¸ÿ__ߎŽhÖª¯¯ßÑÑ>Ä "%%ÅÓÓsÙ²egݺu³TÔ¡®ë³gÏNŸ> c>ã;™ºfÎè¬B&“!‹KÄ "55500pîܹ‰Da×}v‰zCCNß¶mÛwß}wäȱXœ••¥pÁ‡~¸zõêÞÞ^@ww·BP+b:ãééYQQ1;ŸýO¢®àŒÙËËK¥ùþÁƒ¯_¿îææVXX#½!ˆiΟ6ÛàF‰Dêëë366VãòI p¹ÜU«VÍt¹Äluñ¦¢ƒª@¢Ž@ ¨#$ê‰:@¢Ž@ &€QÔZù|þóçÏétzqq±¡¡¡½½=ª²Éú`èêê¢R©>>>¨BÕ«³Ùì²²²ÈÈÈ7†ˆÉ$..nÞ¼yLHHHMME‚˜(Qwrr***‚ÑÔäýx!&2™\]] X¾|yyy9ªÄD‰º±±1 Ìf³×¯_¯Òo4b}úþýûd2ÙÑÑQ~&Ÿ””D¡P†††Ž;& à@õɃÅbµµµÉ‡³¶¶Æ•Óh4GGG±X¼qãF …boo¯ìا¦¦fíÚµµµµ6lX¾|¹±±q]]üippP,ÛÚÚR©Ô®®.‡sçÎÉ7ˆY=€¯­­µµµÅ0lÕªU4M9L& …===]]]ðä;w>Œ*‘ ÊáÄäÇÕ$ _{#“Éb±x¤¬vïÞýòåËyóæÁEÓ¼¼<|ohhøÁ˜L¦‡‡`Æ ¨òÿõeË–ýõ¯ýî»ïïܹ£fZŽaXsssBBÂ?üpãÆC‡¡I AÔ„“—v‚¹1 777xëãã·EåÀi‚ÂyÄlÀóÍ7NNN0*õH@ú§OŸ.//÷ÝwsssQ%$::šÏç[ZZ=z”N§K$ØtÊ7£*U’™™ Eðßÿ}çÎP®´´”Á` ÛÙÙQå#þ#꺺º¿þú«‰‰ÉÇ#""F½’B¡DDDp8m¥§§Gƒh°Ú¢¯¯o¢5O%É;wŠ‹‹ÓÒÒuuuY,VZZZff&‡ÃÉÍÍÍÈÈ`2™YYY©©©Ïž=+**)76›ýÞ{ïÁã+V½óÎ;€„„‹õèÑ#???‹»iÓ&ô¡##±FGGôõõËÊʈ„w”H$êܽ{·¢¢bÔ|ÄbñW_}s‰D111?üðC\\œT*Åodii)‰´›2##Ú‰aØ“'O˜LæÄ…Â’Éd<Oþ¦ÓÝÝâÿÂ[ˆÅb™LÖÜܬŠ1kQt9 °zõêÁÁÁñßÀ××÷áÇ£& )..†_êµk×ø|¾T*ýòË/¡Z(LSRRâêꪕÇ~òäÉ7æÎ[__/þÔ©SZlJˆi-ê0$Û‰'&§‰dÿþý𸰰000Š·H$200xþü9üéÆ_ýµïkcc£ êÿüç? Ä›‡Š}uCCؘ85ú²2•••éééùùù•••mmm Úf577gddÔ××·´´üþûïø%ùùù°qKEEER© §§gdd„‡…c0îîî€êêêìì쉘ÎxyyA…Hii)Òs¹ÜÌÌLäHñ&,ËÉcgg ·‚ˆg§ 6ª6¼*//®Ö¬Y“••CÁUUUA•€L&ËÏϧÓéiii"‘(00p"ÌìLMMÛÛÛáñ¨:g"‘¨lÊËËak…@LFÔÿøãSRRbcc8Àd2 †ad±X ,À 6˜H$ÿÖ«­­…¢ µÁ` (§¼JŒaØ—_~ejj (//§Ñh¹¹¹4mñâÅ7nܰ²²šˆ‘ÉdR©T(B³ÖÖV\ç o CCC/^¼)kkkù3<n°M>&&&o½õúÜ‘¨«€D"ݺu‹Íf“H$w•Ê aD´Á„B!Œâ,ϵk×8°}ûv|ô. ™L&ê;;;+¤ Á‡ ò˜››óÍ7ÄkDWWW$Ñ9377‡N;’=Uî=V­Z¥\c$êÿ¢££ÃÂÂ"..NYGBY!L¹Q¾ÊÈÈH ÈŸùí·ßÖ­[·yóf‰DòêÕ«Å‹3Œ«W¯Òh´Í›7s¹\e °3gÎh¥F†‡‡õõõñÕèœuttܸqc¤†òüùóFFFò'8€>8Ä´õîîn??¿¨¨¨·ß~›xvÑÑÑgÏž… a999pŸ\~L®òxéÒ¥ÍÍÍø¿L&sÞ¼yï½÷žX,ÎÏÏ777—Édt:B¡ÀŽ155u÷îÝã|x•Ëlººº:::¥¥¥ÝÝÝ6l×9Û¿¿|J ‹   kEžGLQ‰D¾¾¾W®\ÁÆ ÂÜÝÝ»ºº ÓÒÒ¤R©···@ ÈÈÈH$YYY"‘¨  €Çã988888lÚ´)::zß¾}€ªªªmÛ¶ Á utt†††ª««mmm) €N§çææ.X°`<‘‘ñâÅ‹žžžuëÖáãðŽŽ¸ ££Ããñ ÎY{{»J3$ψ™‚ /4†ùûû;;;?~|¬ÙÁ°ÍÍÍÍÆÆÆÄ]Y`¶ÿþèè葌=¤RéÀÀ\ŸæóùQwîÜY°`··7´êY°`™L~õê•………®®î¤½•ÈÈHGGÇ+V ¡-Tl¶]¾|yÞ¼yå\AI›J¥B{˜1¹¬!‘H>>>jàÉd2”s€žžÞÉ9œ&lÙ²üÛªgΜ9$ÉÒÒr2ås8‡@ŒKÔcbb8ÎÕ«W‰\\WW§-__ßÜÜÜÁÁÁ)¬‹{÷îN›Ü˜˜ä1ø¼¼¼Ï?ÿ<))ÉÐÐpÔ!÷“'O>þøãììì¥K—j¥("‘ˆÃáÐéô)©ˆ¾¾¾†††) _3’Ã9eosÊ—#7r"ügU©¡¡ÁÏÏ/,,L¥4>ãóùMMMeee‰‰‰nnnÚ’s…B™*9˜ššN‰œ''' …Â;v´µµ}ýõ×PÅÐÞÞ~Ïž=¡¡¡0ºË–-[¶mÛ•Žp’’’–.] Uú>ýôÓ°°0>Ÿ¿sçNôe#T‹úÀÀÀöíÛëêêàL• þþþ¨lj‚~!ø·Ã9‘H¤F¿‚»‘S£Ò‡@üIÔ©Tª³nä.zü¨w8§ÞÛr#‡³¨“Éd¤#=%ŒêpŽÈĹ‘CŒ r=Ũw8§ÞÛr#‡s¯Ž˜*ô q‡sR©ÔØØx$ýBx-A•>(k˱X¬k׮ꑂÏçÿú믧NB58N4Ó/Äûù)TéCÌìüüùómllFý:9ν{÷PõÍô ñiüªô!f¶¨3 WW×ÖÖÖììì‘ü+Q©Twwwôa!3x®ž••ØÓÓeff¦6Ì×××ÄÄU1ƒEðÚÚÚgÏž>}:<<°fÍTGÄ›&ê t:}Û¶mß}÷Ý‘#GÄbqVV–Â~ø!nd†@ f¤¨gffzxxXXXÉ人:///kˆD"ILLlkk{üøñæÍ›Ñx˜þüi³ nüH¤¾¾>ccc¤`ƒ@¼‰¢Ž@ ÞTP¿@ QG HÔuD@L7Qçóùiiiƒƒƒ¹¹¹ÅÅŨ¾ˆ7SÔÙlvYYYdd䯡ŸñŠº““SQQŒs4UQDÄ„‹º±±1tWÆf³×¯_¯Òo4˜ñ¢^WWgkk €±z{{Q•i ƒÁçóGMYYYI$Ãáááß~û-888>>^&“¡Fü L-‰D `&“Éz{{1„6xòäÉ7æÎ[__?jb__߇ŽšL&“]»vÏçK¥Ò/¿üÒ××W&“¡ªFà ø)cÙ²e©©©0Æóøyþüydddpp0‰D677ÏÊÊÂN"Ècìôb¤øm¶¶¶ÍÍÍjB¸Q(”¢¢"©T:gÎ===##£ŽŽ@aa¡©©)Fãr¹ ...¸£xì ÍÕSCrrruuµ‡‡Ç’%KàÖ&Œß CCC¯]»Æãñ¶lÙräÈ‘ªª*üÚ5kÖdeeÍ™3PUU%‹7nÜXVV¦««{úôéû÷ï“ÉdGGG<ÀkRR…BÁÞ„BaXXXBBzHÔ“‹ÅjkkSŽß…!Ü  S(ÂMåâË—_~ejjZSS³víÚÚÚÚ 6,_¾ÜØØ¸®®È{£R©x°7oooô Þü|mm­­­-†a«V­¢ÑhÊéd2™P(ìééillìêê‚'ïܹsøðaT‰ÚB}ü60Z7ȵk×8°}ûvÀîÝ»_þÿíy\SWúÿoŒ@©-–¢bPÑ*0¨,‚Z§uA‘*/«ãø¢Òo§cíLm¥£UüvP vh©3EÑ\P ²H Èö„-l‚‚€AÙïýýq~ßÛ; $ÈrÞ%'çÞœsî}Î=Ëç>OKË‚ À6JQQ‘½½=ƒ½ÍdS_ºtéçŸ~áÂ…¡¡¡¸¸8%>ÉA˜”””K—.EEE8pNð4ŨñÛÑB¸ÝºuËÞÞÞÛÛ["‘tvvZXXÐétðkbbâ®]»ˆqÝ`°·™8€?s挳³s[[Û‘#G”,˃0!!!555vvv,Mÿ8ÂjЬ¬¬ û;ùFV¿ -„[^^Þ‚ <<<ÄbqQQÑàà ‚ ¹¹¹ÀÔ1 »ÿþöíÛ³²²`°·™ûTGDGGçæÍ›vvvwî܉=zô¨ò#)JlllLL̆ 4R‰DyúôiðU$%%%uvvZYY½ÿþûÀÑT*={öìÏ?ÿÜÒÒ¢«««þŸÒét;;;0Š166 … ÃÍÍM«ž““SYYÙßßmootÇˆÒøm›7oæóùJB¸544lݺuxxøÿwá³fÏL&3::$._¾¼¼¼|Ñ¢E0ØÛLDfŸF£!¢§§Çf³UÙ——H$šÚ⎎®ªªUR]]íîî®=˱cÇ„Bák9 £(ÚÞÞ®AµR__þyhh|ÿ"‹Qíèè‰DPa2íA-wøðaAV®\9444aåH$ø×ÒÒÒÐÐP`ÞB¡ÐÀÀ ¬¬ üõõ×_kê­­­eLýöíÛ¿þú+¼3 ÓŒ6Û"##W¬XQSSóé§ŸŽo¤Àb±îÝ»WYY‰§TWW§§§WWWã)õõõ=*..ïâââ+Vg@‚ Q†Üžžž‚p8œüü|s|||À>6±:yyy†ÕÖÖæææB}!dj/ËáÌ™3'!!LÅG¾,OXXXyyùŽ;úûû¯^½ R¸\î–-[x<^XX2’V¤¨¨¬F„ ‚¢hqq±‹‹Kvv¶P( ÕøËvÆÆÆÝÝÝø×Q¥&B¡­€ššÐ[A “hYŽÈ»ï¾yìØ±Ã‡;::ª®Ó®¨¨HMMe2™‚´µµ5662 ‡,|ýúõ111¹¹¹………fffD­H{{ûˆ+CDA‚ 555T*µ  €J¥ZXXDEEiJCNEQ©TJ&“q©IWW.5!vI‚ Ç/2XYYÀû 2IMA£Gfff&&&îÛ·///<`G%33èŒ È—_~I´FKKË´´´ãÇËhEÁˆ+êDA½ ‚¼¼<0Úwuu•ÉM”‹â˜˜˜œ9sFÅFÑÑÑ ªHMLLLð%ôQ©¯¯‹‹“I\¾|yPP‚ áá֪᪼=¾øâ‹q„y‡LmS'‘HW®\a2™$Iõ—Ÿ)ŠH$"¦èêêÝ׈Åb"£144äóù2gQN¥R½½½kkkå…ÇW¿QD"‘žž1E‰Ô¤§§'**JQž|˜œœŒaXWWב#GZZZΟ?a‡ÃÙ½{wHHHAA@ ðôô¬¯¯'›––ÖÐЖ–\VV¶wïÞ¤¤$Øò3ú©þäÉ“ÀÀÀ˜˜˜¥¦†‰Åb.—ûôéS6›ššZWWçáá±dÉØ]Ž»“% • #.^¨„B!ò^¨ššš€px¡Z¶l8PµdfIhx<Þ¶mÛš››}}}U?h¼ ãCF¨yGT*z¡‚Ž¥ ²¦®¯¯?÷/PD9nä…€J2Ë‹ å—9”ÿt,™? Þ|óMØð µañX\\\lbb¢ø·b0~~~ZúS™ªASGš››mll!D^¾| RŒhiê •J?~¼zõjÕoýãÇË{¹ñòòº{÷®ö†xŠÊ{öìÙ… Êÿi}}ý•+W®\¹’••> Œõ¯‰U› ŒâFÒÊÊ*,, A}ûö @oÐZxƒÿþûï5uÂâââ+V¨ŸÃ‡øá‡Ä!^II âYYY3³X¬¦¦&+++;;;R]]ÝÙÙùÎ;ïàÆLŒHµ|ùòË™™™¹iÓ¦¥K—VTTØÙÙÉüéòåËA°­yóæmܸqTOÇŠâX«Ÿê™LÖÓÓC„D"A;ŸBi$Š‹±±qww·*C¼°°°òòò;vô÷÷_½z¤p¹Ü-[¶ðx<ðÀÈÈÈàp8^^^‹/£qùrfee…††¹¸¸ôôô¨>®”H$ÉÉÉàÝj|¹.==B¡ ôÑG &&&%%E¾j𩙪´··kÊ4Š¢R©”L&+âUTT¤¦¦2™LAÚÚÚ ‡Ãùׯ_“››+‘jÄrnÚ´©®®Ž8ÂWô§&&&ÄE¸Ù³goß¾}ûöíxʨq¬ðªAS‡LU®®.þ5::º¡¡A>›‰‰É™3g”ŸJGG‡&“ÉÀ*ä‡x™™™¸o²àà`A¾üòKKKK<ƒ¥¥eZZÚñãÇe"RÉ”A£Gª^ME!ƒß}÷Ý?þxÔ8VxÕf©755ÙØØ`fkkK¥RGìÚA[[[oo/HŒ‹‹;xð ´«Iˆ¡¡!ŸÏÇ¿?~|ܧ‰D`§ …"³š­««K\º‹Å E&"•L9N 5‹¢8VªTmú€Çd=yò$‚ ‹/~ùò¥òpËííí—/_¶¶¶vpp@QT«‘b üüüfHX\kkëÖÖVœê‡~ Ñhc=jÉ’%òðððõÀÖÖV*•*‰À׌Œ ‹ååå…gðõõ­ªª Ãï®C‡‰D¢1•EÑôôôëׯ߽{W•üÕÕÕ999<oþüùR©ð›7o޵jÓ2˜!âáá‘‘‘QSSÓÜܼgÏEÿH$’±±±““ÓÑ£GËÊÊÞ|óMå¡ÕD"‘´´´øøøÌ„n÷ûï¿?xð F–?utt²²²6mÚ¤bþœœœ¤¤¤ôôt±XüâÅ |Á¼§§‡ÉdîØ±CùáóæÍ³°°ˆ?~ii©……ŪU«(JFF…BIHHpu³™ è IDATuÝ´iSvv6‡ÃÑ×ׯ©©Ñ××wrrS9“’’.\èëë{áÂCCÃQ~_¹råÙ³go½õÖܹsKKKq'¨*Vm>Õ1 kii>!üñGUú ‰DMLéëë£Óéãîx¸\nff&1å?ÿùσ:;; †¶G¯‘G]¼xqÞ¼yùË_âããÕ?!Š¢@ˆ¢æy~ùå—ôôt3‹D¢¶¶6üÙ.Ÿ2<< F…ø³}LåLNNNHHÀ0ìܹs‘‘‘ª4B{{»X,FQ´££ƒX°±Vm€È|§Ñh‚èéé±Ùl­ÿ,‹¿úê+bŠ*äää§ <ÈËËÿWTT°Ùì?ýéOB¡Pƒ5—H$aaaæææš=íäF£åää¨s©TzìØ1m÷°c-§T*ݺuëÓ§O'Õ&µ©cvøðaAV®\9444¦sEGGWUU©žÿÁƒQQQóçÏ—™;v ˜Š¢nnnááჃƒÚ¨|uuµ»»û”»f*Þå(Š~ûí·<oÜtõêÕºº:mWg¬åŒ‰‰)++SóO'¦j“ÝÔy<0ýéOÓC2 @#kQ·oßþõ×_Á„âĉUUU§NjnnÖx壢¢¾þúë)wÍNž<©bN@PXX8îÉTeeåÄÔHõrfdd466bV^^®Î}ð‡&''cÖÕÕuäșٚ¹¹9ŸÏÏÊʪ®®¶··oiiÁ0,--­¡¡!---88¸¬¬lïÞ½III2 –ØlöX—*´úT‡@pªåŽ=š™™™˜˜¸oß¾¼¼¼Ù³gO˜W,êëëãݰL†q+1qjjj¨TjAA•Jµ°°ˆŠŠ²´´UJ‰ Èðð0q!ƒ••Õ˜ÔW"‘¨££CVØ4{ö¸·0¹\n?©ÎÛo¿=s ˜D"]¹r…Éd’H$EǪÄÔ”SQ†q+1‰£w@——æÀ5¨RJP~ðN¥*ŒÚ·oß–ùuîܹǎÿvww_ºt‰Xò/¾ø¿L_~ù¥¡¡!qÂ2nÏ33“Ý»w[[[Ï\SSSÓ¤¤$VE‰©m1渕˜¸4ˆN§‡‡‡S©TooïÚÚZɤ")%h–¨¨(EýãÉ“'‰†7j#¼õÖ[@§¨„ „‡‡ã_¿øâ âW\\\Æ=?‡ÌĹzoo¯££cmm­Š3ñ)1±ñŠ1Ç­ÄÄ'ê .†-Z´Ã0°Ð0ª”W(bR­ÀC 8¿ c‰…Â;v„……9;;kI‰©¦sÜJLpxCCCqqñ¡C‡),,477Ÿ;wîÂ… •K)qf)fz籶󔣹¹™ÍfS(”òòr33³ò’©¶!+†aAAA®®®GŽÓè €F£)Ï«N\\œ™™ÙæÍ›GÍ)‹»ººÌÌÌð÷–eR@鎎###¢¶\*•òx<`Ã"‘ˆËåššš‚Zttt€Û«³³ÓÔÔT·„ê#‰’’’:;;­¬¬Þÿ}å]Æßÿþ÷sçνƛfL¥+R©´¶¶öÉ“'"‘ÈÏÏoÄW-!ÀŸ={öĉ*Ž ˆº%õ•˜3S±ˆ¢hDDØP«¨¨÷ ðÀÀÀš5k€“À™˜”J¥ÒÙ³gëêêª#› ¥‡?Iâþ–-[ êëëûûûgÂ6ØDÏÕŸ=xð`XX˜———»»{AAAFFFXXXFF†@ øàƒž?þõ×_ÇÆÆ×_ø|¾¡¡áÀÀ€‰‰ ¼%4¼¯Îãñ¶mÛÖÜÜìëë«úÁAAA°5»nrêÔ©øøø)aç#–VM£@ ŽY¸páLåi×ÔõõõÇ!±‚î¢5KDDľ}û€Oø)ZZ5UŒ(ŠÊ¸~ã7à¡IS'“É£ºÎ‡h•[·nÙÛÛ{{{K$’ÎÎN­ºñÒ^iÕT1ìÙ³Þ ÚÆWŸäåå-X°ÀÃÃC, NÑÒnß¾ÉdŠÅbü!ïççW^^NáïÞ½›F£q¹\ssóC‡¹¸¸H$â¼`ÜA—!J MÝ—±§ ÃÃÃÿ¿÷5kxx˜B¡LÑÒ&''çääìß¿¿³³ÓÚÚzÕªU4­³³sãÆ øðÿúê«ùóç{zzööö655}¿ß»w,ÝNo]àë4õˆˆˆQ=Rp¹Ü›7oß¾‚@ˆ£ôñ©IIIþþþçÏŸ700øä“O`{jeÿöÛoº“©zÌzÈÌDGGÇ‚¨)–IÑ××'‘H‹-’_Ù• º S[¦N§ÓÝÝÝ»ººòóóíUYŒ<è2l M!û¾:ƒÁ íïïŸ7o^QQ‘Là+ÑÄ Ëööö°A4oê@ÖþðáÃ: ß#…@&à+rþüù‰DÆqDc¦þäÉ—­[·^¸p!88X,3 ™öìÙ3%´\)ŠLÐeˆVL]ƳϲeËä‘H$©©© f½··7ÏC “ŸÿÚl[ $i``ÀÈÈhb|ª@ ‰6u2]Ïmš:¦@ ©C hêd²™:—ËÍÎÎ*((¨ªª‚íLOSg2™l6ûÚµkëÖ­1Ì È44uggçòòrx”è6L+S722¡H™L¦££ckk+l2dšzss³ ‚ –––2ÞÛ¼yóŒÀ755ÙØØ`fkkK¥Råó¡(*úûûÛÚÚz{{Ab\\ÜÁƒµ}ù¡_úéŠÌU;|ø°| 7â šD"á>dÉd2C†1’ÜÎ;[ZZ,Xv‘ŠŠŠ€SÊ9sæ¼ÿþû‚äååyyy!²víÚ™2W_ºtéçŸ~áÂ…¡¡¡¸¸8%+í†utt¤¤¤\ºt)**êÀZá(òKÿèÑ#GGGàë ÷KM}2C¼d#^5E܈(¿Ùä#ÉÑétðkbbâ®]»€N¤Ðét0S &Nÿü™3gœÛÚÚŽ9¢dYxê ©©©±³³+(( þÚßß?Žˆ®8YYYÄE~éûûûñ0€ZòK¯f]ÔA¾´‡:Õ”/§’—&ˆ—lÄ«6b 7âEWô0b$¹ÜÜ\`ê†Ý¿ûöíYYY,‹N§ UUU½û¤¦¦Nû®öwS×ÑѹyóæÜ¹sïܹC m¯ …Q§H$’ÈÈHWW×1•€N§s¹\ðÙØØX(ÝÔ2 sssà—~ÄÛXQQ’A¬ËˆÚ ©TúÍ7ß,\¸P&ðè¸QÞZb—Ly9ÕyiB"‘ÄÅÅUUUegg;99éèèfggçææVTTääääåå1Œ¬¬¬’’’‡â¶nݺqãF]]]¥K—‚òlذäY¾|yyyù¢E‹RRR ïÞ½XXX˜˜˜¸~ýúé?¬Âþ† ˆžž›ÍÆT@"‘àŸ£££«ªª0•yðàATTÔüùó[[[‰éÇŽ …†¡(êææ>88~ª««ûùçŸþùç£G^¼x|ær¹†yxx¨ò§þþþwîÜ5^E#""¸\®T*=uêˆ1òTWW»»»cj3j;h1]2UÊ900pàÀW¯^¡(ºk×.å—Læª £(ÚÞÞþòåKMU°¯¯ÿ<44¾‚‹Å(ŠvttˆD"l€È'>|A•+W ©~"‰D0ŽX[[ËÜ:·oßþõ×_1 kii9qâDUUÕ©S§š››eò¼xñ‚˜¢¢©µ.¥¥¥¡¡¡À¼…B¡AYYø)**ê믿ÖÔŸ*i-1¾K¦¼œ(Šîܹðâââsçε´´(¹dš½j匰Ù¹bÅŠšššO?ýTõÑAqqñŠ+42Ððññ[©2~é• ü’““_úW¯^ª¯¯ôèQqq1´?þœN§s8A:::rrrZ[[Ÿ={vÿþý¶¶¶ë‚k3!j3ÀPÖÓÓA‡“ŸŸ¯ñÞ8,+//ðÚÚÚÜÜ\5•ŽšºdÄrªþÒ„’«™ˆ<>4³oß¾­bŸ‘˜˜¨‘§†annnøˆÃ00~&fÈÊÊŠxøðarr2†a]]]`­±¥¥% àüùó†q8œÝ»w‡„„OOÏúúzåu©¯¯711ÿ+•JÍÍÍù|~VVVuuµ½½=ñ ¦Ùv¤¥¥544¤¥¥—••íÝ»7))‰˜Y °Àf³‰S-u.™òrJ$>Ÿï2ãpU.D{Œ,Œ}÷Ýw###;vøðaGGGKKËQ»Œööv ®m (*•Jõõõñå™ ÞÞÞªìÉ›™™ÉK2„B!ò’Œ¦¦¦uëÖ!$ šÍˆu!j3©©©¡R©T*ÕÂÂ"**J•V_;Éd\õÑÕÕ…«>Àê1Îððpee¥¢SYYYhé’á候-[U.Dëûêò=z433311qß¾}yyy@r¨@ ««KL‰ŽŽ&JqLLLΜ9£ül:::`b¬NÝÆ-ɯ òßÚ 0zyyy` ,¿ˆ­NõåÛAÕ‡‰‰ p"¢"2Õ|í×ëòåË,ë5ÃÇ,Ó{ÎS'‘HW®\a2™$I•· ù|>1åøñãã.–H$ÒÓÓS³nã–dÈ×eDmFxx8•Jõöö®­­•×`¨S}%í DõÑÓÓ¥èjž%ÔG£Ñ>ùä Éxüø±D"ÑÑÑQE’!S ÍذaƒX,...611AQ´¤¤ÄÅÅ…B¡?\YYY;wîTsÑDI;°X¬¾¾¾µk×UÄ̦¦¦aaa ¯´Ü¸l|—L{× òzL½¯¯/000>>þ­·ÞRåDëׯ§Ñh{÷îUý¿srr*++ûûû£££íííñÁgOOFæ½@’áééÙÛÛK”dH¥ÒÍ›7óùüœœ‰DÂ`0„BaIII{{»ƒƒƒƒƒ±.@›1<< Î9kÖ¬ááa‡cccV.]\\ ÌÌÌÆ]NUÚ!%%eÖ¬Yííí@õÑÝÝ=â4{Ôy–:—LÛ× òVà——Wff¦êë{(Šå%êðË/¿¤§§«žqK2F­‹D"Á“…Baww·6–L‰í  Õ‡¦.™¦®ŽP(LHH¸téRRR’ÌÎ D“E8;ÖsÑh´œœ5 $•J;¦‘.C4R—ÉßêWSãåT"O„hØÔÏž={âÄ Ç¥cà"}ûí·<O]½zµ®®îµ·‹Fê2ùÛAýjj¼œJä‰Mš:FóóóSqÔÔÔÔtñâE™‘aaá¸KÃår+++'IÓ¨Yu˜ÈvP§šÚ('‹Åruu‹Åà«©©iZZš¼Ä+11±¢¢O©ªªJKK#êùëêê²³³‹ŠŠä{¢êêêÜÜ\Ekjjètú 5ü—©ºººªÒÇ£(š’’bff&#M‡@4Qžˆsúô鸸8E³³³ãââ@ ?~üøôéÓØHBIœQE‡Ó•ßlŸŸ¯§§×ÑÑaddDœfbÖÑÑaffF&“;;;MMM5î}tÒ"ûŠ‚"gÌDp·¾ðžƒ¼ttt,,,ˆV*“¢¯¯\Ë,'ÄÙ³g“H$ssó™cç#˜º"gÌD´äŒhÙ¡ Fhh(pÆ|òÓO?!‚ïaB écêOž·!hêš:¦@ ©C hêd™:—ˉ‰ÍLgS‡/±B SØÔ¹\nvvöÐÐPAAAUU•’càK¬3àzùƉ‰‰p08%MÉd²Ùìk×®­[·x؃@äIJJZ°`ÁþýûSRR²²²à`pªðûë.ÎÎÎׯ_¿|ù2‚ Àçàà`BB1·¡¡¡L _ÈLƒL&s8;;»eË–ÕÔÔ8::–••¹¸¸TUUÍ™3gÍš5p08ÙMÝÈÈ8Ê-))qttlmmµ²²:|ø0l#"×®]srrZ¾|ùŒm>øAE Fll,“ɬ­­åp8þ󟃂‚®^½ o’ÉnêÍÍÍ666‚466ZZZ¾|ùÒÊÊjÄcfòK¬©©©sæÌ™É¦ˆ={öìÂ… çÎ ƒS‚ßßl“J¥b±XOOðÎaŠRZZjllL¥RkkkŸüðC,»§‘$iáÂ…øôG,«brÚ¾¿étº‡‡øœ˜˜¸k×.bB5ÃìÙ³GýBÊ,åÎÄ`‰¯qòäIA/^¬|†¢h{{ûåË—­­­ÀoZäÿþ÷¿mmmAM/]ºð†}÷ÝwgΜŸ?û쳟þ™xø¿ÿýï“'O‚Ï¡¡¡7nÜxõê1ƒ——Wee%†a2éjràÀß~û \)+++—˜˜¨©ð†ÊAQ4==ýúõëwïÞU%ÿL–8ñü¾,wæÌggç¶¶60/U¸dO"-Z´($$¤¦¦ÆÎή  `ºv‚4Ëåš››:tÈÅÅE"‘€ž‘ØKŽø›› ž®†Ý¿ûöí@[Æb±ètúÐÐPUU·§¦¦j°ØL&sÆ àóòåËËËË-ZDŸ÷Ýw'Nœ`2™ÉÉÉfff«V­:räÈÅ‹ËËË###ƒ‚‚V¯^-‘Hââ⪪ª²³³œœTÔ½ŒUH—’’RXXx÷îÝÀÀÀÂÂÂÄÄÄõë×çïD,˵´´€‘Õ?þ¨J?!‘H¢££§k/xêÔ©K—.UVVfee)((ضmÛ–-[ÊËË?~¼uëVŸ¼¼¼ÌÌLWW×Ý»w—••ᇯX±b``<ë¶nÝš——Çd21 ;{öì¹sç®^½úÉ'Ÿäççß½{·­­MƒÅîëëÃ? ¿âˆD¢¶¶6â³Z&exx ߯´Ò–œœœ€aعsç"##U´··‹ÅbE;::T;@Æ‡ì …Ö5©MÃ0 †]¹råÐÐÐøNZ]]íîî®JNÿ;wîhü´×HLL qt™tsuœÈÈÈ+VÔÔÔ|úé§ã^Þ¸q£*9ä5êŸòºÈÌÌÜ´i“ƒƒCEElIª–Ù3gNBB…B‰½sçÎøLÝÓÓA‡“ŸŸ¯H6&ñ™’ÓjIy+2B:Ø “wYNf† ˆ±±qkkëX§jæææ|>?++«ººÚÞÞ¾¥¥eDý™êâ3%§Uy&X `³Ùòk È´D¡ZîèÑ£™™™‰‰‰ûöíËËË›=[U]]MM •J-(( R©QQQ¸KF¦ºøLÑiUQž WVV**­•••ìñ!ÓžÙJöϯ\¹Âd2I$Š¢c½ ‚¼¼¼+V âêêªD¦¢øLÑiUQž™˜˜ª^þüãÏž={]×ÃÜÜü믿&¦DGG744Èç4119sæ 1…Åb—I§4K—.=qâ´Ì‰3uAzzzLMM“’’tuuÇdêáááT*ÕÛÛ»¶¶–(u”—[Ê÷/ã8-¢TYÙÓÓ¥¨;;yò¤¡¡!1QÆÒ^;ÇW1ç»ï¾ûÓO?Á{26Sïëë Œë­·T?Š¢%%%... («³²²vîÜ ~¥ÑhŸ|ò П=~üÌ“‰«#~VrZ‹Õ××·víZ¢òLÆ ‚©©)x1säúÏÖú ?@ÚÛÛ«¯¯¿k×.xÏA&‘© …BÿóçσѲêp8 …‚ ˆ‹‹KAA™™þ+[zzzööö:99•––fggK¥ÒÍ›7óùüœœ‰DÂ`0„BaIII{{»ƒƒƒƒƒƒ’Ó¦¤¤Ìš5«½½û!q IDAT(+»»»GTVN€=+!))ÉÊÊjóæÍAAAsçÎÝ´iÓ´¿«š››Ÿ={fccÃáp\\\Æ4*„h‰â«cäêêzäÈ‘±žN*•òx´µµ%jÈåÕÛ\JJŠ@ ]§Á'Ÿ|2I¬B$%%%uvvZYY½ÿþû³fÍR§š8R©øÀ‰D~~~#¾+ ™häåÏž={âÄ Wð§±.ŠËåZXX°X,þF”‹r8œººº»wïFDDœ?žÃáLXíPˆˆàr¹R©ôÔ©SþþþÊ_RT]×Èår ¾´´nqMj ¼ŸŸx£pTššš.^¼8]›&>>~ݺu£šº:rÑ×h¥¥¥¡¡¡À¼…B¡¦zíÁÁA©TºgωDÒÔÔml2î«]¾|9==]ùXŒeèéé¡Ñh}}}W®\ñ÷÷ÇExãüÈkÒ544lݺuxx|5kþYýjÎ@àäGV-WXX1ªG .—{óæÍcÇŽÍ´ö·àoD” é¦n5'm½f42+ò---Ÿþù¨{Q=Z¿~=ÜÀÐÓÕï"ô'9©Ý¡Óéîîî]]]ùùùŠf›úúúžžžšU›Ïdðư^‰›«3ŒÐÐÐþþþøøøyóæÉdð÷÷‡'D‘Ö ¢ES²ö‡†„„'ÄÅgˆÆ~çÏŸ/‘HˆQa½ Ú]–kmm‰‰ ¼}ûvpp°X,f02ìÙ³Ȫ6nÜH§Óa B S艹››ëååejjJ&“›››}||ˆ‚G‰D’ššúüùó{÷îy{{Ãñ<2Åžê`‹…D" AÝ22=MLWàs¦@ ©C hêš:¦@&‘©s¹\•L[Sçóùׯ_‡Í7>€KÖ7n$&&ÂN2ѦÎår³³³‡†† ªªª”_bU“¤¤¤ ìß¿?%%%++ v² 5u&“Éf³¯]»¶nÝ:À¢%Èd2‡ÃAdÙ²e555°“…L¿¿îâìì|ýúõË—/#&$$sÊ„4†à¨Àðƒ>@EQƒËd2kkk9Οÿüç   «W¯ÂÆ„hÑÔŒŒŒŒJJJ[[[­¬¬> ÛHERSSçÌ™£Š©p'-sçΜ,N·³³›–Þþg´©777ÛØØ "r½|ùÒÊÊjÄcàK¬#"cœÊ!:i±³³›lljjjKKË7ß|SZZ M}zðû›mR©T,ëééa600/pii©±±1•J¡ÂÝÜÜŒŒŒˆÆÀ0++ëøñ㸓kkë+W®„‡‡ß¸qcÖ¬YË–-SäOt²'Ož<þ<±“e±X/_¾tss«««{ñâ…»»»ê‘'”°téÒ¬¬,KKKh'ÓèIsDX,Vee¥Ïõë×ëëë_¼xáãã£fœFEH$>Ÿbž¿|ùr¬EMKKkhhHKK .++Û»woRR’FÁÚÚºµµUýóTWW'&&VTTà)UUUiiiUUUxJ]]]vvvQQQ]]ñX&“ ÂÎ×ÔÔ¤¦¦¾zõŠxÚÜÜ\Ekjjètºòøð¨–™ÆÆÆÕ«W755­]»vÙ²eFFFÍÍÍÄ ………ÏŸ?— `~ Åbñºuë( `¨ä¿Èd²žž‚ $i¬ƒ©¡¡!±Xlcc£¯¯ßÛÛëààðÙgŸmÞ¼yò´dXXXyyùŽ;úûûÁŠcXX—Ëݲe Ç C$##ƒÃáxyy-^¼˜¸ûÃf³uttBBBnܸA&“œœð°™ééé exxø£>111)))ð¾Ui®!²sçΖ–– €õ‹¢¢"·§ê0¤Ñh•••±¢9sæ¼ÿþû‚äååyyy!²víÚÉÓŒ©©©L&A¶¶¶ÆÆFƒÁáp€…¯_¿>&&&77W&ð+±Ãݱcèpmll„B!èpñ®«« ïàÞ}÷]xߎnêMMM666†ÙÚÚR©Tù|(Š ‚þþþ¶¶¶ÞÞ^wðàÁéÚ4t:ÝÃÃ|NLLܵkX<)ê0 Ðør:NÏCb!µDtttCCƒ|º‰‰É™3gdVq§ÃÁÁÁ‚|ùå—ÄÉ¿¥¥eZZÚñãÇeúMåî$ïà&µ©/]ºôóÏ?¿páÂÐÐP\\œ’a$†a)))—.]ŠŠŠ:pà€FV€&!¹¹¹À 1 »ÿþ¹sç222vî܉?™5§Q¾…UmÈb±úúúÖ®][UUk©©©ÚÞ–;~ü¸Š9)ŠH$"¦èêê‚ E€X,)2ý&~S)ïp'²ƒ›êü>W?s挳³s[[Û‘#G”Ü$iÑ¢E!!!555vvvÓµi˜Læ† ÀçåË————/Z´ˆ¸WUU•0ÌÍÍ­¨¨(((ÈÉÉÉËËc0YYY%%%>,//WñÇ$›MII),,¼{÷n```aaabb"IR#K¶jžaûöíL&Ÿ¿dffúùù›¢¢¢b÷îÝ4Ëå‚~ÓÅÅE"‘;\`ê Ãݾ}{VV‹Å¢ÓéCCCijrdýÀÛÙÙ½zõêÇ ü+¢é82Ö«zlC0È233#“ɦ¦¦‘ÍæääTVVþãÿ8tè½½}``à¸O•œœœ““³ÿþÎÎNkkëU«VÑh´ÎÎÎ7‚¨Ï~øáW_}5þ|øµ©©‰xïÙÚÚÍ;ðmÛ¶ýíoÓ××øðá¬Y³ÌÍÍËËË÷ìÙÓÝÝíè與‡(¼WˆÐh4AôôôØl¶*+ø`à*“fnn. 5¾a Õ“ÃØ†ZB$µµµ‰D"E)ÃÃÃ(ж··Ëï5öõõះ††ÀWY,£(ÚÑÑA<3D#ì«ÖÊ•+‡††Æ½êîkõ䓇˜˜˜²²2xƒB´¸¯¹bÅŠšššO?ýtÜ«Á7nÔÞ¸öN>I²Y‡ŠŠ 8ð„hxYgΜ9  %66öÎ;ã³FOOOA8N~~¾ü¢ñ½{÷ˆËÕÕÕéééÕÕÕxJ}}ý£GŠ‹‹ëëëU<9‹ÅÊËËÃ0¬¶¶677wꆲ± ƒ‚‚\\\zzzà= ÑÊ\8€DÄØØx¬ÒH©TjnnÎçó³²²ª««ííí[ZZð_OŸ>‡¢hvvv\\H–ùøñãÓ§OËkNU9ù¨âP@ÀR›Í–_q€@¦ ÕrGÍÌÌLLLÜ·o_^^ÞìÙªêêjjj¨TjAA•Jµ°°ˆŠŠÂ%jj§\íÔðð°š•••þ•Ëå–––NéÜÑÑqÜûEEEÄ­ï)„Ý›o¾ Ÿß#¢Ð€I$Ò•+W˜L&‰DBQtL£w@——·bÅ A\]]‰SPu´SŠN®ŠvÊÄÄD£i€ê7ÈÌ2uAzzzLMM“’’tuuÇdêáááT*ÕÛÛ»¶¶–(cÒˆvJÑÉ¥Ú©žžž¨¨(EÚÉ“' ñ”yóæmÚ´iš]iÕ%n...<…T]Ñü\½··×Ñѱ¶¶v¬õ…   Ã-Z„aXbb"þkkk+•JÅwA322X,–——žÁ××·ªª*,, ß_=tèž_ÑÉ«««srrx<Þüùó¥R)†a7oÞ”/›X1p"÷Áßo=xð`ff&l-Aód„BáŽ;œÇÔq444:tAÂÂBssó¹sçâïxÍ›7ÏÂÂ"66vþüù¥¥¥«V­¢P( %!!ÁÕÕuÓ¦MÙÙÙG__¿¦¦F__9TÑɯ\¹òìÙ³ŽŽŽ·Þzkîܹ¥¥¥ÎÎÎÆÆÆ²› ŠQ§¯‰DwïÞÍÌÌìîî¶±±QþFÀµk×(ŠêóÉææf6›M¡PÊËË$nú=l»»»W®\YWWÇåreÆ3¡&†â«cäêêzäÈ‘±žN*•òx<`f"‘ˆËåšššÊä‹Å]]]fff¸„S&E‘æTÑɵ$UqLtéÒ¥>úÈÈÈèôéÓ‡F£)±ö½{÷úûûã/]jR©øÀ‰D~~~#¾tøyøð¡­­-ñÕ€{7U¼k¢(úÇ?þ1660L‰˜Úø³gÏž8qBÅQÁ Wt•––†††ÿ'B¡ÐÀÀ@ƒ Âår1 ;wî\iié$¬;—˵°°`±Xʳùûûß¹sg|êÀIÞS[-—PQQ®âð277w&w”``)•JÁ£¡¡¡Œè…¨zþü9Nà;::rrrZ[[Ÿ={vÿþý¶¶6ù““ÉdEŸI8“û÷ï›››š-!!aÔQŒ"uà$o©Å™zQQÑåË—¯^½:êôðû÷ﻹ¹mß¾}&7ߪU« 444'Sø¯2~”ø|þO?ý‚7ñùüýë_ííí¾¾¾ÁÁÁò;a_|ñÅo¿ýf``üUNªŠ¯]»Vþ>‘‘9ªÒ»)QNæ˜Â›mOž< Œ‰‰immѶÅb1—Ë}úô)›ÍNMM­««óððX²d lDÐ>§NŠ'.Êh€ÿ9¡PˆüŸÿ¹¦¦&Ð5ÿsË–-#žóÒ¥K|>ÿ½÷ÞX¹råä©,ŸÏooo—_²ÍÈÈ|ðÁóçÏ¿þúëØØXл­Y³æ‹/¾½xß××wëÖ­111Ë–-Û´iS]]݈4i[` ›:ÇÛ¶m[ss³¯¯¯êÁDDDìÛ·oÛ¶mÄDuüÏÕÖÖÞ¿Ÿ˜òþûïÛÚÚN†Ê&''8&——9޵w“AGG¬°š˜˜À{L3¦®¯¯?ŽY7ô¸uë–½½½···D"éììÄ}$¨ãÎÂÂbÏž=Äù½Œ×‹ÅZ¾|ùˆ{ò]Û˜z7*++÷œ€€;;;x¿©eêd2ЇÇp¥²añX\\\L|þ¨ãÎÐÐpΜ9“PFÖÐÐðüùsðNaKK˯¿þêååÄ…JdŽªôn2ØÙÙAÃÖÊ\2¾û~ëÖ­ÃÃÃàë¬Y³ðÏÈÿùŸ~”pÿsR©tóæÍ|>?''G"‘0 ¡PXRRÒÞÞîàà@Œë’””deeµyóæ   ¹sçN­îîÝ»ñÏÑÑÑûöíÃßkïÚttt05¼kBÍ,4õɲeˆ††ýú÷¿ÿh/^ìíí ȃð_ûí7üóˆf b3ÛÙÙØÌ“J–ßÓÓC£Ñúúú®\¹âïï|WÊtm:::………cêÝd˜œÝTEfŸ½  ÀÏÏoÔíø—/_þë_ÿ‚²„ ` 9™Sâ"n|$'''$$Mdd$¼4)¡yûí·­­­•÷|>¿¢¢âúõë°£œðØÌ“¿¨úúúÀw¸¦Ök?øàˆ^E51D²¦N§ÓÝÝÝ»ººòóóͦôõõ==='Lg>“Næ¦Vg7•æê #44´¿¿?>>~Þ¼yòqýýýa@õ‰ÈÈðØÌ3¹³èeÂæAÆIfQÔÃÃcÛ¶m!!!DW #²qãF:[¢ÕÎŽˆ~RE˜ÚOõ'Ož¸¸¸lݺõÂ… ÁÁÁb±˜Á`ȰgÏùWÁ!m D3 QËÔsss½¼¼LMMÉdrss³ÏˆºE‰D’ššúüùó{÷îy{{Ãñ<2ÅðÀ'‰D022RÓ= ™¤¦@¦+ð¹ @S‡@ ÐÔ!4uML'SokkPžG*•Êûf°X,xy )`ê/^¼Pž'''‡L&ƒ@Ë7nÜÞT?†—™&øúúú+V$%%G¢)))YYYðª@ SÒÔ¹\nvvöÐÐPAAAUUž>44¢šw+‚w+ðª@ g"N1™ÌÚÚZ‡óç?ÿ9((èêÕ« ýÁƒüãùàƒbccáU@¦äSÝÙÙ¹¼¼<00Ab4õ/^CÈÔ6u##£ÁÁA###&“éèè¢Çtvvš™™áyÆínðŸþEQEŠ‹‹g² dâL½¹¹ÙÆÆAÆÆFKKË—/_"’ššúÞ{ï J¢vjç'Ož¤R©J^Âsttüá‡ÊËËáņÀ¹ºv±²² Cdß¾}óæÍÃ0L èëëƒ ãö@péÒ¥eË–mܸQI2™µ{÷î«W¯¾õÖ[ð’CàS][Éd===AH$ð%ZUUµfÍ5O[\\\TTtèСQs|÷Ýw‡†oìBàS]óP©Ôû÷ïÏž={ïÞ½2áõH$’«««¢SRRdfòòH$’»wïªhåÊ•K–,IHH€W2™ª®)bcc«ªª~øá<¥´´ÔØØ˜J¥ÖÖÖ>yòÄÍÍÍÈȈxHooï† ª««) ¼ð8€ŸH¥Ò .|öÙgx ›ÍÖÑÑ ¹qã™Lvrr’ðæ›onÚ´éÆðªC ©O ~ûí7KKË%K–à)«W¯njjZ»ví²eËŒŒŒš››å þþûïáU‡À¹º†ijj²±±Á0ÌÖÖ–J¥Êg@QT ô÷÷·µµõöö‚ĸ¸¸ƒ*9í7dbïܹ³¥¥eÁ‚`W¯¨¨hÄðøÃx<^MMÍÊ•+ᵇÌ,´€ñäÉ“‚,^¼XyÈ>ÖïòåËÖÖÖ(Š*Ê) ŒŒžzôhýúõêÿH$rvvFd÷îÝJ G :tDŒ‘üüü… ʧ8pà·ß~½†••ÇKLL”ÏF£Ñ6nÜ//_¾¼¼¼|Ñ¢EòÙŠŠŠ$‰ÆÇGýýý¹¹¹¯q€600 èàÁÁA%Úa­¢ÊMòzK8ƒ–åD"Ñ­[·"##“““ÇÔÜL&“Íf_»vmݺu/^T”ÍÊÊ ùÿüÏÿ¨òŽ*™L>v옢_Y,ÖŠ+äÓóóóAœ‰tçΕ+W:::Êg[²d‰T*:| "‘H"##•ˆÆÍˆWG*•~óÍ7 .‰DxNccc¡P({ ìV”””|ñůŖF½I^{ gŠ©cvùòåÍ›7‡††–––~øá‡ò;탃ƒWþ†(~eMž½{÷>|X ìÝ»wxxXkW²Ôgee%ŸþÆoàŸ ˆ_eμxñâúúzͶã?þ¸{÷n%Å÷JʈW‡L&ïÚµËÚÚZWW—˜Û¶m7oÞ$Úÿ—_~¹nÝ:ooïY³f•••Mü6êMòÚK8SL½¼¼¼­­mîܹ³fÍúꫯþí·ßÇ]Ô¯nêžžž‚p8œüü|üÜEß?ÿùÏ?ü ©/Gû(¿I4^BˆJ›mõõõ&&&\.WÅ5=‰DÂçóÁ¢·ò½4œ˜˜0«lmmÇ*"˜Ë•——«³¹wïÞ¿ýíoòé§OŸŽ‹‹CQ4;;;..¤äææböøñãÓ§Ow—ÉÉɆuuu9r¯ö³X¬ÊÊJŸëׯ××׿xñÂÇÇG#+¨Ä«#•JÍÍÍù|~VVVuuµ½½}KK žÓÍÍ ìe¦¥¥UTTTTT¼óÎ;,Kf³ƒ¥6›-‘H4Ò>Jn’QKÑ ³‰6êÔ©øøxÕç“Éd0;Å_Y•£Gfff&&&îÛ·///oöì±ix€©õ(tuuLbEEEjj*“ÉD¤­­­±±‘Á`p8ðúíúõëcbbrss ÍÌÌ0 {ûí·ñÇQ{{ûúõëÁçÆÆÆ;vÝžP(ÔÈ TæêÔÔÔP©Ô‚‚*•jaaeiiIl%©TZVVöÎ;ïòx¼ÖÖV‘HdkkK<çðð0ñù,¿˜ <ÿ©Ù>Jn’QKÑ ¿ÛLDDľ}û¶mÛ¦Õÿ#‘HW®\a2™$iË­À…š[eR©TÞ•EffæªU«Àçàà`°\D´KKË´´´ãÇïØ±ãÔ©S®®®ß|ó øI àËc*êö¢££äÓMLLΜ9#Ÿ.suètº@ ÈËË™•¡PØÐÐàææ~ª¨¨©µ‰‰ X-SuÚG£–¢yS¿uë–½½½···D"éìì´°°ÐÞ_öôô˜šš&%%ɬ«ØSèéé …Bu Àçó‰Ï+|VL\¸⊱X,)L&óÙ³g> `³Ù$ÉÐÐÏçã9étº‡‡øœ˜˜¸k×.°.E<ùñãÇU/°üÕ¡ÓéáááT*ÕÛÛ»¶¶Væü"‘HOOO X[[ƒ”Û·oÿòË/ò"**JQ;Ÿ‹dRôõõI$Ò¢E‹ˆ‹É$i×®]¸^EÝÞ¸!“Éø.‰®®.Ñ—>Š¢%%%¾¾¾#þª>ãkå»!š-!Dá’öÄüMBBBEEExx¸*™›››•¼7„–JL}Da Nee¥­­íœ9s4[Aÿ‚‚‚¡¡¡×{9¯_¿ª¢¿=Àk˜ÂÂBWWW§Ê ?%%ÅÌ̬¹¹YQžÁÁA …2âøP¹°ðå—_~üñÇÚ¨¦@ (,,|#4.—[> ¦ÐCIDATYY GªQ$4ZâÉ“'111#*äÁ"0—Ë}úô)›ÍNMM­««óðð :“’ÁÐÐÐÃÃ#;;[Þ{œra àáÇ#n\«…Bqqqy½¶±±±ú.·!Ó|_]Kðx¼mÛ¶577ã³GU Rž! àÞ½{ò¦®\X‚ ÈÓ§OÛÛÛ½½½á…‡Ì4´ëZ*•*fDæÍ›§\úÊãñlmmÙl6xAÇÏÏ/44”J¥nÚ´I^X‚ È·ß~;88¨â’MýõóÕW_™˜˜üå/ÁSP]¼x1x;Ê¢½½ýÞ½{;wîÄ3…Âwß}—N§«ù,2™ª’ã¿þõ¯ñññDa¦ra ‚ ¿üò‹ŸŸ´s|ªO(=ÒÑÑ‘J¥Ê·Á•_WWwîÜ9|²ÀãñÀ†³H$âr¹Ä Û¾¾¾÷Þ{/;;›¨ë†@àS]»”””466º¹¹UWW½Œ‰ÀÀÀîînðZ%¢TX‚aاŸ~úý÷ßC;‡@SŸP’““Á"ùŠ+RRRÆ9 !‘¾ÿþûðððÎÎNå9/^¼èëëûzw ™hê===à V===܃Ò8044üùçŸ/^¼¨äÕ÷Ç¿ñƪ¿˜ LKf¿ž='Š¢jº”yã7þùÏ*ɰaÃü=3>Õ'”•+W‚ýö¾¾¾åË—ÃËLOSß¿QQÇ+--Ý»w/¼ ˆ¶ym›m|>¿¶¶ÖÖÖV__^DÛü?©G4õ#"ûIEND®B`‚snd-16.1/pix/fmeq46.png0000644000076400007640000000056411147553267012763 0ustar bilbil‰PNG  IHDRV ÄYIsRGB®Îé3PLTEÿÿÿàààððð€€€```ÐÐÐÀÀÀ   000°°° @@@PPPpppÉ…êü pHYs  šœtIME× #^j/ÇIDAT(Ï•’ ƒ D7`äÛûŸ¶€µÚŠ­î02Ž¾Ý„,"Æ-Üöv¤MZsÏU’¥sZ–L7`³êû‹GàqN+À¶ÅdѰF}…(˜æj6irÚ»h›îq——"Ø­:& èˆ&…K°Ì³‡úZbÂ2ó×ÖV °h2ít¦|ˆ-Õ'ñYü´ÙþPª³N†to¥ ·ûÁ:¡-½dÛ ÓRöd–+¶m´øzQv}õe•!ÙÐ]Û7M1¥üœF(žîiIEND®B`‚snd-16.1/pix/sqsq.png0000644000076400007640000002026611147553271012644 0ustar bilbil‰PNG  IHDR^ÿö/bKGDÿÿÿ ½§“ pHYs  šœtIME×  )~cÀ IDATxÚíÝyXTõþð÷0È€Ê"" bT(q]*ÉÝêªiY™[—„,»ÖEM3Ó+åFf. ‰ŠK¹‰h*‹×43”EÙ÷Åd—™aæüþða~޳d†>¯çéyâ;ç;çÌgÎ|<ç{¾ ‡a„BôƈB@!”x !„/!„=%ÞS§NáôéÓJ_ËÊÊBPP®^½JQ$ïÞ½{X¿~=öîÝ ‰DB!Чîż¼<ðù|¥¯}ûí·G`` F%+ˆˆ@jjªÜ¶R©¦¦¦Ø¹s'EœtŠ‹/b̘1ˆ‹‹Ccc#¬­­)))Ø·oŸÂöB¡«W¯†»»;è7ñŽ5 ÙÙÙ¬Þ0 re±±±˜;w.%^bp|}}áëë«PnnnŽ€€J¼DÿM ¹¹¹ÈÍÍܼy#FŒ½æêêŠääd899Q‰Á³³³CII x<¸\.„nâíÓ§† 0`þóŸÿÈ^ F^^–-[FQ$Ïßß À;#޽{S@H§âècE[SCuu5Eœt æææˆ‹‹Ã˜1c(D¿W¼„B(ñB%^B!”x !„/!ÝEss3Pâ%DŸ>ùä ¡ÄK!] OWoœ••…íÛ·JJJ(Ò„¢ëÄ;dÈ„……øÿ„B¨©B(ñB%^B!”x !„/!„J¼„b¨xÒ“©ZsM,+” èaújB‰—îMÕšk‡R(ûá‡h…bÒ!¨©B(ñBH÷Fs5BHwI¼4W!„(GM „B‰—B(ñB¡ÄKH×±lÙ2 ‘£· ´¶¶bôèÑxï½÷ä¶©©©APPìììäÊÅb1üýýñî»ïÊ•—••aÙ²eàóù ûk{°÷¨àà`466*”cçÎ åü1D"‘\Ùýû÷±qãF 4H®ü—_~Á™3g`jj*Wþ÷ßcÛ¶m0`€\ùO?ý„„„ËÊTÅ"##‘””§1.ŽÔÔTp¹\Y™H$ÂÔ©SñÆoÈm›ŸŸÏ>û 666ZÅ%;;_~ù%úôé#WnnnŽmÛ¶)lÿÁ(ŒøRÇÃÔ©S1}úô.ÿ#{ðàeÒ9‰·wïÞ²dXUU¥ô-‰àííµk×Ê•âÇTzB9+V¬+ Tz W(Wµ½P(TØ~÷îÝJ“wII V¬X¡C‡Ê•‡††*ýáaÍš5puu••©ŠK[r ½½½Æ¸@^^BCCamm-—0ûí7…m›šš0vìX,]ºTë8N˜0Zm/•Jâ¨*.Àår•þÃI55B¡ÄK!”x !„Pâ%„ÎFs5BHw¹âm›«!,, ü1EšŽ=JA ÄKѧK—.Q(ñBé(´ôéÑRRR°ÿ~…rek®B‰—àëë‹‘#G*”Q\ÀÝÝ«V­’‹…X,Æ”)S´Ž‹H$ÂŒ3”~þ¤¤$¤¥¥µ;.ÀÃé.•ž|<žÂöªâ¢+)))Ø·oŸByW[ÉA(‚a•ç¸.|þùç eUçÖ­[xöÙg 2†¿þú«ÒߦÏãååÅ~gŒ\¸p±³³cé*ÌÌ̘¤¤$ÙßiiiÌ®]»˜}ûö1×®]cõ^ÞÞÞÌ´ÞþâÅ‹Lxx8³bÅ ­ë”——3k×®e/^Ìú³N˜0Ù¼y3«:K—.e.\ȪÎ÷ßÏ<ÿüó¬ê\ºt‰yñÅYÕ©¬¬d>ýôSF"‘°ª·`ÁF(²ªó¯ý‹innfsjj „´›7o²®³mÛ6”••±ªsöìY\ºt‰Uœœœvuû£ÄKHV^^{{{ „žQâ%D‡š››annn°Ç—””„^x¾(J¼„tÀ¢E‹ºÕgªªª‚­­í¯éG‰—BX$^>ŸÏ*ñ2 ƒúúzX[[S)ñBôaÂÕÕ•U=Coª¡ÄKévN:õÄ+ZSâ%„ËÌÌİaÃ(ñBˆ¾üôÓOxûí·YÕ‰ŒŒÄ‚ (ñBˆ¾Ü¹s¬êüõ×_íþ¬³uL²²²°}ûvÊçj „Câää„ÒÒR­·ÏÈÈÀë¯¿Ž˜˜´´´°š'CgW¼C† AXXÂÂÂðñÇÓ·JÑÜ¿ŸU???üñǬêp¹\H$0 CM „îã•W^ÁÙ³gYÕùðñk×.ƒýL”x !z3hÐ äå屪ãïïÏzòCG‰—‘H$]b‚qcccH$H¥RVõ¼¼¼pûöíŸD)ñb@†ANNëz?ÿüs»÷9lØ0ÖÉÐÙÙµµµhhh`UÏÊÊ uuuôESâ%¤ë,--Q__OÁ&”x €gžy7nT(Wøû»ï¾ÇÓúÙÕ«W)À„/!ãr¹033S(çp8r·¶¶Ê­ü¬ÈÈHÖÇSSSƒ¾}ûÒÓÍQ/!Dß“µnvÅKs5Ò=µM»X\\LÁ0´+^š«î)>>ãÇgUgË–-X±b«:Ge=½cCC¬¬¬XÕ‰D022bݔԆíä:ÔÔ@Ñ‹üü|<õÔS¬êTTTÀÁÁ½zõ‚••ªªª4ÖINNÆèÑ£<|p*4Ö)//‡™™úôéƒÉ“'ãÂ… Z_nn.ŒåË—cëÖ­”x éIŠ‹‹QXXpqqAQQë÷xþùçqýúuVu<<]i’R5løï¿ÿ†µµµBÂ>|8²³³U&ÄÊÊJôïß_!zzz"##Ce̹\®BOƒÙ³gã—_~Qº½P(TúpKÓê¥K—*”­_¿k×®UY§¾¾r±4h«EF©/éÑRRR°oß>…òG`àÀízÿ¹sç*]á¢#466¢µµ}úôaU/996l@aa¡lrM*++Áçó5öFx\II œœœXÕ9}ú4¾øâ Vu¾üòKÖqÈÏÏǹsç°mÛ6½Ÿw”xIæëë ___…rm&§Ñ†¶É@,+mžÐ…¦¦&XXXàý÷ßGjjªÜk¦¦¦‰D011QZ÷ñ«×'iªQu;___¯tN].—«öÊZY¬ûôé###Ü¿666r¯íß¿“'OV¸chÓÒÒ‚^½zÉ•]¹rEm‘ƒbîܹçö¥¦BÔHHHP9é·²Il†AuuµÊa¿ªú–žjkkeÇ)‰4d2d222dñÈÏÏ— ÝUÅÒÒõõõ²Q€"‘UUUÛ„?Žõë×Ëþ¾víüüüÔÖùã?ðÞ{ïÉ%Ç×_cÆŒQÚÔäããƒÚÚZ444ÈŽïðáØ7ožÆïØÃÃ999”x i¬¬,¸¹¹©lïœ7o¶nÝ*÷4ýÂ… *o¯Û’¡¥¥%6mÚ$ñµgÏ,Y²De¶%iŽ?.»U×Òæ½÷ÞÃþýû‘˜˜ˆææfÃÜÜ|>_««¶¶\'NœÀo¼¡±NFFÞzë-0 #צڶ„2"‘'NDuu5$ ššš´Z3­©© YYY´€gff&k~¹}û6† ¦vûððpŒ=Zvç dÑÕ7nœÂ•²Â?Àôó"D¹ëׯk|âýý÷ßcÓ¦M5jbbbÐÚÚŠ'N¨­3{öl¬[·gΜAtt4|}}aaa¡¶ÎK/½„ÀÀ@455!33æææxúé§µúqqq8wîFŒ¡ñ*ôñ¦”Ý»w£µµÏ>û,ÀÑÑQíÃ#F`Íš5ðóóÀd‰ñµ×^SYÇÝÝ[¶l±±±Ún\mW“™™™øä“OOOO|ðÁZ7ÙÄÇÇ£¶¶'NÔªÎÔ©S±jÕ*¸¸¸ÀηûøøàâÅ‹(..†³³³~¯xÅb1ª««Q]]Íz­$B Á¢E‹4^}9::B(¢¡¡ÁÁÁ“n[ӟχP(ÄôéÓñÊ+¯È’”&˜6m†.[ÔQsæÌAtt4Þzë-­ëxyyá…^@~~>†àáƒ4///•ulmmaooC‡aÚ´i ²×@+++øùùÁÙÙYãÕx@@îÝ»‡§žz ³fÍ´º‚o;¶7ß|»víÒØÛdôèÑðöö–Ý¥lذ¯¿þ:ÌÌÌpþüyµÿÀÌ™3§ÿ+Þ¢¢"ÙDËl:Ò“p¹\Ù\[žžžðôôdUÇÑчÖjÛñãÇcÿþýðôô„··7¶oßÎj_K—.•˜ðÍ7ßhœ¹KUUW½9r$BBBàâₚš$''˵ã*3tèPa„ j·{´ébÆŒàp8pww‡»»;.\¸€Áƒ«­?lØ0µM:»âussCHHBBB°páBú…ÒEL™2¦¦¦øÇ?þaÐÇiff&kO711Ayy¹ÚîamTõRéè:êÐÃ5B:ÛiÛnŸ{î9½Ÿ®§dôôô”= Ó‡ÃQÚtaee%·.^gxõÕWqöìYJ¼„ª÷ß±±±¬šXÍòeèø|>êëëÕö+V–`Ù'~ñŵZúI¹ººÂÃÃCã¨5J¼„t"Öí»lyxxàÎ;¬ë±=.ggg±Þ—Ë•=„Ó•qãÆ!33³Ã†;«3mÚ4¥³ÌQâ%¤ƒ}ôÑG8pà€ÞæZ`cΜ9066Vùÿñù Ú|øá‡¬ö3qâDäææê<‰¶—ª99: %^BžÐÓO? ooo­ûÕê›§§§ÊA ›6mê°ýXYYµ{·ž†PÒEŒ7NåäæD¶nÝJ‰—®JÙä,꨺j%ú¥ÍfM¨©NÂvRñîhÆŒ=òsSâ%„tš©S§Râ}ÜåË—•Îé ¥¥¥ R:©3!† 66Ÿþ9€‡³YmܸÇŽk×⌄t$µm¼ *gvÿïÿ‹ððp"<<\VþÓO?A Èm›ŸŸ¦¦&|öÙgq¢5•}kráÂ455᫯¾üöÛoðõõE\\¦N kkkÀ_ý…cÇŽ)Ô‹Åسgbbb´Úßõë× òünhh@zz:u¾/U1(//GUUîÞ½«Óý_½z%%%JÛ`õñýÔÔÔ °°¥¥¥35j”úÄË0Œlz5###|ÿý÷˜ùùù¨««ƒ³³³ÊÄ FS§N1›7of†aÒÓÓ™)S¦È^ûüóÏ™œœfåÊ•LG)--eÖ¯_ÏèÊâÅ‹uöÞÛ·ognß¾­³÷_»v-S^^®“÷NOOgvìØÑ%ã®Ê7ß|䦦2—/_f˜ß~û9qâ³jÕ*¦¾¾^'Ǭ¯:_}õSPPÀªNTTsîÜ9Vu²²²˜mÛ¶lÚS§=¿£cÇŽ1/^dU'--Ùµk—Ê×Õ¶ñÖÖÖÊFãØØØÈÝö}ùå—ˆŽŽÆŠ+螘œO?ýüñ233({ˆ3sæLXZZR€Hçb ˆ®¯x###êœßIçW{ê´ç»ÒfƬ®‡öÔÑõT—þ¦Ô-*Ê]·nÝ:C9q9,--µ^…t æææ¬Öú¢c6 \.ÖÖÖ*ªì)LLLпYO˜Éu þ&„½Òûȵ¸¸8|òÉ'¨ªªRxM ÈÖi[½z5‚‚‚äi=z)))ô­u1‰‰‰øè£PQQ¡ðZNNöìÙH$8xð ¾ûî;ÔÕÕaæÌ™ ÂòåËuz|7oÞDPP ^+//Ç’%K””D_d7rëÖ-aË–-hllDee%–-[†øøx@LL V®\‰ššÔÕÕ!$$‡†T*íóEï‰÷çŸƪU«°sçN…×ÒÓÓQ\\ ÈÍÍ…‰‰ FŽ ///œ9s±±±¸ÿ~·øâãââäú?~¼Ûžä?þø#6oÞŒ-[¶(ý´ÀGŽ»»;þýïC,£¤¤&&&˜7ožN/,, aaaظq£Âk7nÄ·ß~«õB‘]ÙŸþ‰ 6ôˆÄ[UU…°°0¸»»#)) ;vìÀš5kpòäIÀ™3g°xñbìß¿çϟǘ1c ÐÔÔÔ!ç‹AÍÕàïï/ûÿ#GŽ 44666ˆˆˆ@dd$,,,põêÕ.ÿ¥_ºt ?üðöïßÂÂBÙÀ‹´´4ÄÇÇãÊ•+vÞŽŒŒÔ¸JkWõòË/Ëþ?>>‡ÂÊ•+ÑØØˆääd„††Ê®ˆ‰níÝ»‹-B\\®\¹‚óçÏËî6Ï;‡ÈÈHH$ÔÖÖ"22‘‘‘ÈÎΖ­›Öv·ƻヒ¯¾ú eeeصkª«`XF;7IDAT«±{÷n¬[·NmŸ×îˆ/!¤]bbb0pàÀv¯”ŽY³fÁÎήÇÅŽ/!„èÙÿ{ÌàØå—IEND®B`‚snd-16.1/pix/n3a2.png0000644000076400007640000061357611147553267012441 0ustar bilbil‰PNG  IHDRÂN›gsRGB®Îé pHYs  šœtIMEÙ ++Ì¥À IDATxÚì½w%×u§ùÝôù2Ÿ)_mª½A£ÚÀ5@‚„zŠ„DJœáˆRH;³K±¡Õ®¤8£]mŒ¡bV\qDQ¢h$ …!¼wÝn4ÚÛª®®êòϧϻäËÂk¤1ÔŒ´ª/2næ{UÝ••ùåïüι·„”’¥XŠ¥XŠ ¡,‚¥XŠ¥XÖR,ÅR,Ű–b)–âŸkhK§à'R"DgœDLca‚ùË\:ÆÑ'hÖH\³—½¥2ÄšýúÞøUK±Kñ#B,™î?ùxá1z8ñ}ª—Ùô1N>ÄÈ­<ÿ—ìû5žüKnüY~ðï)#¨”èíç®ÿÌš»—NÛR,Űþ5Ð8bQ?ÅÔóÔ.2ú8[~•ã_£aÈØAVÜ©§Y±›s‡Xqç^%iãMà€6˜ Ã¦›èaÍ'©lÇZ½tš—b)–RŸä“ e¦¾Aí}ãÂèÿ©FÚ¤èpâóØËû.7LÓ»Šx ·L4…["˜âÎßæûÿqJÐaòj/0õ-ÊeƒµŸ£ôNŒ5K ãR,Å’Âúñ 2>¤È9G²€÷2ÑEš/Ò:Oùš'16C…)îcæib ))ï£y¥„Zbü9z¶3úC×sîqFîàÌS¬º•Çþœ›™W¾‚〰À“Î-?Þûs?ƒZ’Êu"ÿI¤` aKñÿNú _¨ÚÒ í>¡’ á/¡*ò<É·‘$1ˆFî€ÎÐóqäÀ(`Y4¤ôQâ#° =EI‘*cÆò_âÜ_Q¾SÁ°0UL-Â4Q#L“õ;q+ô®gþ:ÚµA )4¿Šü*–.ì­‘²[òN÷+”—°µÿhï&IñW’A“-)¬ÿ&À§ø -@ æ!nñw*†äRÌ Ê:w 9¯Šq•]B~EÄ!â2|QDóˆ!Z/bšp’(@]ÇÌ_1ø{\þÜ;ñæI#ìœÿ2#¿Ì•ç‘:/SÞÉäk¬ý Ǿ˺÷ñÚ¬ºç¾Å5·1qŒd–ØPÈu– ….©• l° u <÷(l°¹Ë`¹Fñèi¶Kñö#dBÒ ¹?æÛ*£*ÿ&f:â„ÆÍ)2E³Øgq$!Ð5J?…Õ…ÉJ7À[þobŒTTEEtŽÇVKjUpÙhÑ«bTù®Ã´øaiUBÆu©ëâ·¥þjÒ¦&U!¸edÝ zžÔÇ)SÿK .ÞS(«Q d›B‰/ã5©ÜŒ[bhµsâ–P ÒãÝÿŠ#0t =ýœþ6 !è]RK4ÐÐ4¡«„-þ.ÀhñyØ.*±ß`Å·/‘k)þ{Þk)É Ï/ð„Â%…ç NôðY…>Vʳw¥X3|¯Ì‡%îÖºô(JÞð aaÿÖº 8ôŸç[6n‰eMÎé¨Ã%®™ä¯ ôò8¡!ûøH•/Yö…î´qÖ°|Iy-Å#§^ã¤OýG=Μ­P/Ó,S+3gâØÜ£¶xµÌ'ÚœX(pCŠ6Ï“!I?ï©Ïp4A®â#M&¦8â°f€í3œ ‰æ_Æ®2+'91Ït‚XË®uìígÕÛÖ‹<â¨:ÖA^¬Q+3¸‰k¤…%ÐRÒ®ÒLû¹^ H„D˜ètÒÉ7óëÇ¡ªk #" }üÑ’ø6¬f5Ä>ÈmQ…p?wj¨1þ9^­3U¡r 7¤„5&Æ8¸‰}EJM®\æEA°•ªp–o®æv›âÇŒ®åÓ-Ž´ye˜Kfª|mÿKÌñ€‡Kü´ŠL9c²žÑ¸]å %}~]ø_€ÛñŸ# ññ¨{Á¥yžö bmÊcßÄÞAß»xåsôÜL}’µŸàÌC,Œã'ômåòj nù$/þJ`B)·®ŠùÀûuK+6ÕŒP-Ü6v€ÕÂñ1=ì dm m !fÃÇjb\ÇŽ•ŸgwŠ4P•%l-ÅßãšË$&½ÂüWxhŽÑ~ZEÚ=4ÊÔš½Ì—¨ÙnrWÄ\›ã67 *Wøë^>’@•#Ev )b†½ì+E^áP/[4ÊSœåðµÜmRã /MqùzÞ§`DÄyêv>¼ýMIâ[ë»Ü[¥U¥iaoãZ UšSÌ´)ª ¬fÙ*†³äó —R¤D€2K#錑dUx‘B?îVV¤H â³™U_‡—\TX*JŽ‚Hs„a5Ǹ «È~**¬dØDŸeî"4Dî0ËJ_æ© e¥D©Då$Ï 0àR‰ñæ¹X¡ÇB«2©“©ô±qŠçʃ ³EVÇŒkè*^Ê´ÅŽ”Ô \Ó°4™*bRcµ’ŒÉ¤_Ä“$;‰Ž“iA¿‰`P#II êÇQ7 Bû2õy¸t†ÕwѪ‘èÌc 9üzúsra•ª˜§„ÙÖEZP P «…Ó¦àw€eeÀŠ0[<,Ëë ìVKÅ)Ñ?Hy}©ÜDåÇ;€KñÏPI¤ñ cf[L)L÷â•iT¨º´ÊT{¨¨êÔz¸'ÆipÌeŒhpºÄÞcCQ™ ®´˜_Å{|š“mÒÞÌ{êÌÕ™‘ËÙ.Ð.sfš©^V¬`C £œ®Ó–(Ùº…­ƒ ¿-`=Å >‘‚V£ý ‡uŒëÙfb*¨š@=Æè &êz†7±Lv pÂ@( ¢ëûŠIêÏqF ¤¤ÛX¹…e)é"°2ZÅHLIÒ@ù/¦r#›!Mˆò<—Î3ª ¬fp3kçÒN«„ïånŸvBð/ip=ïð©â‡Ù6̺ï0{#?§ÎòÚ¶ò‘€É)ž\É­ÎóÈJÞ§c{¼ZfOohÔl®I8àrsÌã6;-nM䟚b»’¾Lú?Ñþôÿ2Ê~Z¡ÞÀô)~‚Ö8Òbú1‚O²ú3,œ¢:ÊêŸç©?DèÈ};˜<Ã|•Ý¿ÄÙg¹r7Vv¹Ü×S¬Œ˜Ú"zKºž°3NùXm -œ³ãae&—•½åag‹ÐZ8M,£ˆû!î ¸C)²ÍR³ê?<ŹCý¦ðbÔ¦Q¦]¡Z¤áÒ¬Pu;©_Í¥QÁ³h™ì+pÇÿw?¿.1æyÖå:(Žq/”—ñžˆx†ìRqòe‡Uk¹U¡ð"ßbëZxGy¡•«¹VžÌè.îäCA‰Ÿæ¥÷óžØý¶€õe˜¦! Ø;YŸfÒ'õI"dkXMOWh\¦&³o…huü,dWb(AA¨]+C¤ÈœV2·«$à  H©ÀV¥HIr„ñ6¾ uÑ5ä2z\¬cŒIâŠÃô´ðê,@TÄVI|Bˆ R{€¡QŽ›h6Z‘žιX q„ï`*D1m]!IiY<5¡a"bÏ@…¶)¹×âCšli"TS[&M‰Ûøã$!r+QÆ«¤E‚}1¤%Æ¿ƒBdô(«ÞßÄOXG_†(pìI¶ú´/¡·:ªx5°pÁB:‡Ô-¥Ð¦¥„ÞëÀ2Z¸m ¦‡¿ - F‹Bˆáag9c«…QDzpÖRXч±?·rZ-‘ëÿo¼B<.åi‘Žœ¦àffˆf‘V/Íu—f‰z‰z‘f .2µæzxgÄB‘´8UãäšáIŸ¨Ä¶&“>Ñ 7ø3/±QžÂyïî¬3?ÎYdû§˜˜eFÁZǵ5ª“L7ñûfÙY.†¤Mâµ,ï£w«—3ð¶€õG[D¥Š÷(' ŒÛÙdc‰¢ Ž0u”iv };L;ÀB Þàa½þ½É´ê–Wù©ìh®€øa΄i"îd½‹RgâS½Xï`“¶ñŸåÕ]¬_FEx%¤}×ÐtÔ‡¹ˆþìÔPžá{kX»Š 'yªLe-;_åÞåõìç e„}—ùNÂB[¼0ÂÏLóÅ>nuÙð”˾˜'möµù=—ý*3š|EãÓD_”é"ŠHÚÔ^Æù-ÂQ¼I¤ÅôÔ>Ìø·Yþª'©žgäS<÷¤‚@‚„‚@PL(çƒbWõÐ΋‰S´„ãK»)œŒJMœ°“Úf7K3Í•I­Ã£ÐÆÎˆv¸fyØ!†§:´ÅïšÜ¢q§Ùù¥Š%„ýÓŒT"!„/…|9å%=5´ DÝÁsh:´2åÐriV¨94{X(S+ÒèeÁ¥¡Sïá7=Nl›æûý| gùâ~%†iô²Sàã¾kùX ç9#Ör£‚ñ ßÙÎm%ë ¸•ŸŠHë´ph›Ù$Ð.2q†ËûØ¥c(h‡8{š©Oñ®w°õmë?òÄaŠp°v², 9̉Ã:Ê«)&0Aë uÙq¬„eQXÉa‹ä¾U6FæKR€0;è7QO2_%H‰!Õr5åy‰*Ä ‰z/î(³ ±‰ÜÂÈ,Õ9æ³ÃÐD%Ò¡)$*($ ‘ŠP‰U"©’j„ RCQñ5„B ê$1'-z%W4"—b«„*¦Æ÷Uùn$ÒH-’­Ô¾Cꡬ'Ö˜{s7Ó?„è˹ø2å혃L&5˜Ÿ¢ÖfÅ­Lž!µ)®âäã”é˜YnŽªLg»:Km¤Klª>V 7WXn– ¶:Ê«°XF\Ô\!Föy?eY¤`z² =‰uȨ‰ö^Ö0$$qùÃ,((|šu b‘MiU?’V‹—zö¶Ò  ´‰¿ÃåX ’w²|%¶@*ð2Wβ IwÒw)‰‰ø¯ED›éÝà ¾Êó&r«×Ðïãýç~š;éYΞåÌݼëgÇ8·‡Ý-fÏsôîl1wžç®áz.ñìV~ê,÷ ²ÖB©r` ¿:Ï#&E—¾˜1 %â±^>åóÿ8ìOù¡#?ø‚.ï”Q(â­ƒ¿E8†wúK j ~šÚ)ªgXñ)ÎßÇìYz÷x6 Uxè?‘€±‚—f}í”sTsUåæär‘&¢‰!Z8¾°Z8 ŠF·íwRE»M!“T¹Â2ÛØíŽÛeAÇ33¢Ež´e¨‚1¶ðQ"ðPbŠ ŸYÁºÿjý¼þ‡&x]ç|>ä‹yµÍ×6i´¦¤((JC ZŽhe£$ê%êÚE­ Oejeê\šeª ­!~÷ k±Åf«Oà1n²þ2­àã(_ÛÎ'¢q^b›‚ù2]χb’ãIQ7³ ”‡yìn2pôyú½ÜÌÓzŽS+ÞÁšqŽÙSL¿‹ku4‰ò—N0ÿÜôî·Ù‡õ»¼ØFªh ¶Ñk ¼Àl4ET0SPQ·S, i(2#ÃNÒ§H¤‰b£ýø)?™W•ùbt$`£ÜBÏÞ,‘Bš¶‰b ¶PZu9lâ+¤ IK…?$TI{°Ò?!Ð%ì&5•´€f¢·©ZhZDÃ3dA‡…Ù6³CŒÄÌèQh+&NÄAàP 8å²NÇSIBž©p‹äÍ.•iM—‡Eb‹Ä&ZMë"“t„(EÝNã$É /¢ô1qkz?3Ht&ÆñAuéÙB³Éøy–íáðs” ÅXÝ «Ø1³p‘.Â"±OX-é´„`5;ÕC;–÷ºÂ²ûZÁUð;õD«[‚ùX¾´ˆDàABhðîUø»zXçpÇqÂÚ =öLþ¡ÀšDW9ßà²Ç7ÇÐ žæõÞã28KPKšFàÒpeËM‡¶K#³¨\šeêYX¡Z¢ÙÇ„Kä²9¡ârË ÷W¸«Åx‹ªÄU° ›Ç9”â¬â榧ˆÖàüý Â'ùufI$H”>ôÓ«æª*E†ÿ³V ¤‚Ð*¢ý5 és\¹ƒÊŠ*¤Ž2w?SǘտĪ”¤Fø—Â3ì ˜ˆ§¿ÈÜ'Y-»D³ˆöA6üc:évV¬bù¸¸™á!VápÎÖ¼Àù~Ê:L2·“[šcÜÍugùÞ®pL',34˱vÎóü»Ú<3À§üE‘}-6Ht|Eì×Ô&4 BëÚçQ-ªßGßGã%”„pŠx¼‹4Æ"ÚÀü,×þþ)!DpîenÿyýH!€"HèX’Î@HdŒJêXmEI‘è"ÎίJ(¤ i–°«¤¡§(¡tºLR‘@!TR¤B u]JE’Š×Ÿ3ÙŠ)ЙBôð,D<=!FZÂꟺŽ0âwîúq7ÞR¼MB Ácg9p /åß¿@j‚El’¹­9œOGµ¡(q–´T¯ Ú.Ͳ¬9¢•þŠ42=Uì«ÑÃB .Sý|&&iqÑeßE¾¾’O]ä»eüT‚ÑfÆbÃËÜ7Ì Ã\û ÷ÝÈÇ[xcœa·@’g J»Øyˆm»bä×yfˆÁ]l–ˆ¯ðòµ¬^Ïà4í/st ׳±Mz–êã\|ëtTé“~™1ûÍÀzk…õ¯ymšd[ (¨k1=äsÔ‰Xƒ#t¸;†*É£4ÈZádú÷­/FgJäfÌëqã…H“€<‡gBº}ö4J:‡ß&²˰TÒ˜x‚–F2€å¢¶ñ«4°]´”xй5ôF5j™ÜϦ€f‹z?%Îpj;››ÌÚèœ+œŽ©­bí%¬ekJ­È@À%¸@)àT™µû¹9æ¬M%á Ãþ”,6i7¥-°…–ôC´þ–¸B˜®¢}…Æ$úµ´ðêè×0VVÜ‘*4¡Ð§0;uHAävU)×YÙîbõ°œ›YE„tð5ÓÇjJ·- vÖYšõ=d™Éµ¨°òİ“0fãL‚ùX–/M™¨xt,­n•I-ˆ €0+ZA|¸q/àWîÀX?D_KcͲÖ8{óÏ{ê„àÜ4/]à¹ó¾óüÕ3²ëaq=¢7dl©[õ ´Š²áˆV‰z†§"õ"̱*SwiV˜wYècHÁ´¹¥Ê!M 7¸ÒË­ãGAí¤ôh]Gò<™ïfÓ¶ ˆ˜ øþ ˆxô(*z‚’âj¸¿yaÀše|à¶^2JçùcL.ð凉Z ˜`àAªƒ 6¬#‡”™×Žó5<:Àr¡€jĦðË¢V’uG´Ê¢^ U¦V¡Z¢Qì¼êYè2W¢Tâçë)p[#.··©¶™.sëYŒP+¬àD"dH³È²9æâv>ÊÃì«°ò5N¸ô^ÃÆG8`áîáÚy¼qjûØå‘|‰CËé»5üW^ÛÁòw°±Eúõƒ,ü2}Òñ g‰?˺Ò:ɘ+a¿Xo­°þSQOPm´MX*¢‚6‚öÞyâ!Q6£Pl”!¡e9J ã$(ôP\=#G.ö1„È_£0‡¼Ò)fÓy–0%¤=ˆ½Øu 9F0E¨’®DFWH 9L]#½žŠ ¥Ù$˜£ýn†.S§ÑÆû k^áR}-å1fb¼í,;Ï„Aºš¾)f.pf?;'¢¢´™YÅšQ^1}ô^æÅm¼«ÁÛçL™Õm,çöîïeGÌ‹ƒ*ãM›ÍçT<-ž$ÜLºŠÄ ~ˆt3ÆÍ\ù2QÒe~”VÚ‘¥Í8›xõ{âAíÜjA:”òŠa1WXnÞïäG¬üc©C Xž°Ûy»Cæj5q³F­Ìeoãmœ6…6VˆÕê(,§ule‚+J ÑùO†W[ZA.µÞ,¸Þ0ˆsçcr-B<>|Y:ü‹{04¤dÕ J.@’°aý?Þ§lÔö˜œDQ•ÃÇP5‚ˆo?L3@Óyö(“çs-ÎÄ2Á Œü-=§’•³ÉZ\îQâˆì 'Ñ´(ó§û<³ªŸC³L­‡…""õ }è¶Î.…eU[l›áÅn›áÍfŸÆ<E6—X3Éù «g™Ð驳P£µší-Ú縴†ÍÕ#±p"’1æ.ã¾È¹Azp_aj˜J% åS+è-bÈT—Sv0±Ÿf.D¬ÃuÐ7à~‰+)ê*¬^ÌS¹ém*¬ÇˆZ>«#œCþž@5Ñþ-v Èx¾H¬"$ŠÀîê®zó’/<ý>ÉÄ^t©"³ºaù¤‚t‚t9¬@×á4éeRƒtzc†è^êè:I/Öaj¯YÈO².!iÓªPº›Õs)@¸èç©_« .R›$ĸLíówrû£<݋ً˜`¼÷G-,‡Ò$§·ñÓg¹¿ŸeSœfý GL” ¾»’6ø®F2UáV 'åÙ„ª@J¡ 1K|ŠB§~t’IHš2òÎ߇ §˜8µXUí4¢eÛ̱Z¬Ðµs@d, òÁbjfwÔ–4Qb,Ë×íH±.CC*±Fl($!†J¢Ø:±‡¥«Ä‘O¬„˜ ©Jbª$!¦*Ó¶b‡–™ê*B¢ TPA Tó…qÔ®•Õü]5_9'ɺéó h`äürAòí'!í@ívü»BC™0ÔŒ!…Û–Ÿý¬ Ãìôò7~Cÿïç{ïMææ2H)šÊÓψ'žB3@Å‹hx Tƒùy0º^˜°žÎòFN¨L@-ì^.¹¤Êf›ZPÑŒÈM[xEšÍ"ͬϳB5–K#+–h”©™7X®²ºÊÑ>ÆøªÍÞGª´ ª³Ì¯gE³eöØôŸà…¼ó<¯y¤kcnw\fâ8c»ØÓÙÏÞ&Ñ+L”©8¿Ç©u /gð1F ž%zœé- ­¢X%yˆ©›è_‡['=Šåß°b‚hô?3ׇó1zHf‘o¹ÖÈ[+¬?¢"~@àA€r-ÚšŠBˆÏj‰"žïj–è(2ËË_ïi¼¹MTd¼ IDATѹ;I$‰¯Î‘*H…´ïC¯‘* ’¾L4O"I®E[ éy =ˆ½XòE-¢5h›± x˜©Yü›(õ ¾Êì&œU/3µ–ÂZЇÄZMé4—t¤‹vŠ3ïç†æÆ8¿šáÆÖ³ê ç f85Ì`‘’‰u(*„Õˆs–˪˜ƒ :a²I¤áÒþ$‘E`¦$=Ô/â啵¬Q q®§²rÛâØ‡6´r6µreÅÁrniežE)·3W©ó¬–„‹tTÃvCÛ¢àQhvµ²ÕÀ 1Û8‹[í|OËÇöråQð¥é +Lͼnø&W+#i{X~Wbum»VÔ%µ²ãÙ+ÉsÞl7Íw“üÝ4§åsÃ:µ€fÝ=6Èå®»´8Î{\,:°bt4}þù8?¢ÐIŒÕ|¬ä™0è[tÖ2S;K˜u¤å¯E<鹞Êr= ,°º$•™¯ãXèr¬:sà¥b¤†dM –ôË¢V¢áÒÈúªò.ªVÖüÙÃì–Ái½°²Åe‡}|³—¶™ŒÐKl¿ÈG¸û5¾;ÂþY& ç<§XïÐ{š³Ø~”c:¥-l9ÆÅa†*ô<Ãéå Óß$ªöRn`öV0ïet?+\Œ1¼4nc`ÂYÚÇñwP¨›°?ÏÌ*¬Ø ”Q¾EKEÙ†õ/(Þ‚ù¶–@{ˆd3Aüº Q¾)å¸["H)þ@'eQ?²•ýª=Ñ1³^ !Z ™)¯òä~´„T D“D’&( "F<ŽÄ("T´ŠCŠf }•é Æè52Ó‹} =ÿ•Ó#˜)ê¸Ô‹ªcÝÇé-8ÏÜ;¹aœù³\ÜÆÈ(cƒôŽ2f Oqe-k zRŒ°Î„‚MEÇŒ‰Ô˜ÔãL?Ÿ øž –à§È4EVÿ!‘Å;ñyãyH¯VUox%¹ÄÈnÑ6ÔóT±^N¨ Võ²]á"=„‡å„†šZÐÂiÓ6 ƒ@' 0uBË Ôˆ B _#² B‚o˜:‘AdË”§BCtS‚t‰&ˆA‡0¿³]=_z0ÈS¿8_§0ÉßÍM®Î ìb“‘ƒ,ãO¶›æÎ]šŸ¢T’ RˆUR Rë€+MóëR‚œ™I¿ò•tq·+»ºÙf@ˆ. „@äFžŠ@Y”U  ”.Õ©ç²@éâÔ"ªºµ˜ Z]Kiñï*%¦ÀE؉¡†–â»4³Ô¯@ÛÍÜœêØê½Ì÷°P¢Qa¾ÈL™<.9üz•Ò&UVÏr nS›à¤Ëæ1î³Yq”ÊÓ\¹Ìä®óë¹QÁx•“¶D÷(ÜÄžÃ\#XIá3uÔX§¨ž¤¾‘1üWXØÇŠ)Ò—˜xk8Ox˜ðƒ¬j“>‹w†è.ú‰ò§Ô‹¸7âÔ)Êñö{0Kí­ wo­°î!A¤(âAä%)CÔ½° ¡ä¿ñA!åï¦Â’o}¤]I¡ò†Kbñ1&ðÁòüòpŽô)!5dLrê0H'2I#A>?EÜ ú$$OѼLx®Fú4µ„ðnz4Òo0öFæñŸcòp¥Iãƒl8˜‹bÂ9FGp‡qG¹¸–¡QN÷aÅ´7²ú '·²ç1u¢!VÎs°€ªSá½!g¦ŽÛ¤¡Mhâë2±„¯tkîlÎËu“÷&ÇjQ[eŵÅA«cñÈ6H("l(!‹ˆ¬Ý¦”k«¬­´ 6”ºå]dQ$±_X-áøX é¶„ãc7pCÌÌáÊ:¶šy±—}̬ã4ïØÊæôÌ$Qe ðEç§‹òªÛºòsU\-©Þ °¢OQ—ÎÊÀu5vt+¬¸+qîf}Öö!ónŒE¥µØÙ¼¸óÖ¾…è ‰.-•µ.BJÉg`RºT•Þ¥§26i]’J»Ú¥2®N…•‘ÿMp¥(¤ªš”V™ºM»@Û¥Y¤™u¥—¨W¨fSÿU¦V ^`5lhrÚäý5rùxƒã:ÚÌû„}ÜrŽï¯à=Óœ³Y¦è½ãœaÇ^Zö3\hà_ÛâY.õ3ô,'V±r;ë¾ÃáÙ܃{+C”‹Ø3~+môW¨Õ‘»é{Ú4éTŒ§hT‘q6b?E{ V`^]G>B ¢îÇ*¢£þèÒÿ„õ‹èoCaInúIP$g%WRÅLÙ7*ÌH)¤„’ûê©è£K)t]®àL  €¿ñ©Ê®çV×@UHUZy©I¥G ¹RQ— šÈ ’çCˆIñ ñj q#ˆÏãoE/…"|¹k1×RøÕ˜è¬˜&¾Ÿ™Û茙eX»©|3[(&$—¨¿“qÐÄp)Wiï`Çg·³ç"G%ê!½žwñrJRe²Âµ£)íq¾káDVBµÂÇá5-sÿ¯þnOJ¾I@%Wß~‹÷g’¢®D)€äf ­ŽÈ ø4óÜ0»¾Û`Chv€%\h£:©Sh›… R4[x éùÂ*ÐjS°ð2—Ý£`áûX¾…`šY7©Iõ=d«>Xø¾´BÕðm;´tB"‰%:Íñ^N"#VÔE®øêrgÔõêNÃXiÅÒ®mrµ&í~Iqª’ÅKT¾q랣\ê-ޕܹSó i·O·¸5rŠé¹We^ š9ªì|l_ ,·ã¬+v¢©qAi»4 Â’¬—DÝ¡U¢^¤Q YT%ê™§^¦Vf6ka ëübgRÛS잀vˆæ3µÀd§ù¾ ‚3uZƒÈ³_ÅîC¼PfùqNÔ:³Œ5¬­>ÏñU U‰ûY±Šå?ä|B1F¹‹Fe‚v3DœÃ‡wп@b Dˆ!bl±‹â%kÆVô ä€ZŒÚBü²&uM¨B¾Åºmo­°®MR~SíÜoç$ßP%Hâ”›TnÖº4”|£¸nHþ_/ÿ€àÓ=J×5‘KƒWžH:õ¡âïêlø“Ú +~ !ÿ”xA&û„x7€ü3¼¢?Ä}ÿY¼*ÁïÑó=ê3ø¦¤‘~ƒI‡ôô>ÌäÝ >ËD•ú/±ñ%Æ*¨‚äã?ÅÆ—8±…Á)®$i¹†•5.EÌ`9k"Æ®XD.¦tÒˆçú¹Ûç¯,‹†Íôôð/¾Þ‘äw5…{]ÎT·cÕ~]Iu„U3ßm@€lÈŽ÷Efd  Q„2²€¨äýÍå®e\¨äÍ„%p.›ԾjyÂjRô¤Ýv7›#ÝÌ;³ò¾-'ÄlRðò5s…ÕøØ>fˆá§–Œ”Ž«‚/‰DvÉwÎF˜s*È9µX4Lº>uá»Û½Š»¶Ý¯ôêmÚU¸X¤Uw.~D}®nŒE~)]n•šfO‹ à¢o¥çlÒÞÄ©E1¥çy_G[I\žsÊ”J!ÕÕ0+ùYø‹©_v¤@;›CãÒè¡êÈfET˲Z —¶ÃÞ”$À‘¬HQú|ÎFÈyNðsMÆ Ö.p¶ÄÎ+œèeG‹zƒj‰õ¯òÜ^Þÿ"Oîà¶q.§èC¬|C»¹þ$c-Òml|‰ ,_ z‘Ë{YSÆùg?ȦécÌôáìgèK\Þ@q;•ûYè ÇGù.uØÛ°‹¨Ÿ£q#Öõ˜/“átÔiRHSVk¬Pó¥tÞ°Í¿·˜‹%R¼°Çœ‹Y¥‘‚ª )ܤã Úp_Äf EeÂ2…G$¹Qa£ƒRÞ'âñͰ±@|pqÊŸQ½mÊó4R¢Qº—éÄ 1¿ C%>Çü2´*õÕf™¯ D‹j/F™ÙtŠc½!sÛØ9ÊóE¬„ÖëMb–Ç ‹Ð$°ˆ Ú&‰…oãkøV ¿ólêlßœ.ËË=øVÎ5ÿuNÑD¶QØIàšw8” £ÓÖ D*yC©›3ËÍÍø¼×TZˆIuYZMB”ŶÈRÂb¾4`g6b7¿¼×çô¼ÞhêaGÒð…`ÒŠ]ÆÊUý ‹­¤q~Zâ®F?ÏøÉ]ÆùÖ"ª¢Å0?˜yîtÁë s\”ÉÞ ©Å#JÞk¦tÕ:•<ã]JjѺ2ºPµh¥«ù@Ë­t Kt0š4ôÐPBSøej6^¯DÍ¥åÐti:´² `Ư W6zDµÄB%r”D$Ü“P Xô¤è1¶O-FÔ©—Øêá©TêÔL†k,jùDmâq/C,¬bý<íÍ¡tÙ• _¡å!ú©gn ˤðF(›-0ÑH5ôõ¸gð_%ìÅÆÈã+Y¢žcú6ö>ĉí¬5°^âʇÙþ×ë¥| «áÊñ >MíOÐúƒŒ“„Ïà”žñEZŸ¥"“>Eò;$ÊS¤!o‘Æíøý‘ò1É& _ ™HØS`ÏÛÖ¯Ö˜NPSNäi #XÖ%©TÉtBÐNó¥dxSz(Þdg SAQX¦a*k¬*y¼¦q­Ž­âj (…¯ù¬ÔR)©ô+<%™ìÓ)ªB>Ü/Ò)›"9B¼¹¾HóVÔåð<-øîeæ½”®Ð¢AâáC#ÿ¢zþ~ ¶êSóßüf¡Ñ(tu;L„ =H·Ã¯«&N»¹ss VBÚˆ”Hl‘êj[±=ì¦,¶DÁÇÊ<ø&nfº·__¦¦ÐÆói=Ù[fæÐ‡Òð„`†aj†Ò‰ |¹‚œVQ—àŠ»\ön+ê*F?"L®nfX”WÉÖV‹•ÀÅñ"¤¸:ûSºš2Z‰¼¸XÌT–fªJ“D§ØgƒŠf„†ek'ØxÚÚ6^&£2leãu—VÖHåÈvYTËÔ ²]== uÚ­R}-~(VÁ²€XéÓˆÑb55ÆUúæ8S`§GÓbu›f‚Þ$T)5ñ$–‚}™™l¨á9ô\¦nQˆÑê$}”'ð‹@Ÿ%^†{@ÃèÅž$ñýXÈtå Œ`´:Ì –¡Ç(çaZ‚˜F™B½‘ Ì¢N§ôIÑBÊ“‘PR– ’K~ŠŸsyñö€µþ2dÊ¿ëÃK’c߬¿¾ÌUÆ,!ùýaüô­ ÄoÙØ Há/˜JH@*õF{4~µŒ®b ~gM#Ÿë!ü â…ï5Ù­ñG1( jüš*_€ˆ‡{I!Nã‹´K$7£=O# ü-z>Ïä;)LЮÒÞ‡s™›©eâݬx™ Ë0–c¿Ê‹tË"j0g˜„:¡Žo„žrBÅ&^Æ, ß ´¥o O—‘âËŽcÕîj³Z´¨‚\#½Á±jå ˇ²h“zÿ{on×UžyþÖÚó™î(éjžeMžgÛ²ŒìØÄÂhÀI¨ªNÒÕé"•*ú!S¥S¦É@˜’0ÄÆŒm< X²-ɲ$kÖÕ½ÒÏ´çµú}öѾ’ JúIw’ºë9Ïyö>çèHÚ{w½ß»¾ïýh+|˜.0¬–”mÃHA%‰4 !„›V’ôhÝ›¡Àð ’k[%èÍ1«§PX.8ØTÐeD \´Gh;N[”êÔ²Ä÷ÕðdŸ·k¾œm,&˜]I«E)Æ p#ì×Ç‹µ 'ÄM0£Ô"¤ŠÂFaaEé½K¸Ò™êUTÈièÆ€º@¯ǫ̂ðçÈÄu£Ø sEFäHÔ…'™+å]’å傎ÎðKÚJJeËÐÃ/Ó²t\u›¨B«D;£TZ~…F§ÊºUõ­*^=]¦YJÚfK L¥+ŸâeݯĪX¯JŪ6÷Hn¯s¯ÉM©ÉŠ£|{ÿ~‚+\²›û–ó [ùö—1Ra…O´˜ “4Æ™`á¶näܧÙu 7ìb¬Ì¿—7sÞÓ­Ã%,ú2{~•Gïgìf âþ)Ç>Ê¢{™êÇÛDõÿ¢>±ç¼/JÌ_Çû_tdc3ÖõÚü-4J^7iNy8†”?pˆßy%ůx,<òf—ÿP=Ë´†cްO¼¥Bª04©&R´SDa[ðéi€ ªÌ{ýìâ~\Ïç–d}™~K¢ŽÄ• y)`’›jDÏ *¹»+VYx’§Ç7Ú[ )ØlR1ôw´Z$Ò+Ѻ¤›1¶D$—`¼†?‰9î L½ò Œ¯Æ¦QCÏGîcü:æ½À~‡¤†psÌ!¶IlüEôûŒ ¦m"‡È%°:ºU1¬.`¹„.§}S§™ê4ƒ^µff-4r&ÕÕ­š’”,äÓMDÒN;¢U=ÿH¬ÁÁêš5(5#›HˆúÖ­FÔò¬†£’ØYÂaAÌòrãšrA•¯vbFív&tL:v$^ƒZæBÓ Z05Í8——;Õ8n@)Ärk­Lð ±#œH[¡pÜ3ÑVœšJDbFÉN¢ D‡F WzZH˜Ô+rÚÕ%V"ÿX‘ûëÓ2®äL†% ZUö®“Ø9Te"FX–Æqª£µkÃL 3µdl‰(£Þ.A&K9%ÚeZAƧJVժШÒÌ*–«¢c꥾DFC¡¦ò¬[#Mmý$•›ÝJ„ã¤È&; .IMF›L{œ/(O1cIæ™”Û 1"ÌSaï`ç9\ 4N]¦4Eêàú…!±†‰V/ݰÚ 3BÖ–À˜@T0ÆË¤p å£ i#§1FEcsLK ak-F]B¸Š$%TD)}Z¥ø ZS(þS7—ΰs¾C¬Nøü‰Â•ò©ÅDj† 5_:ÁàuË–|dˆ>#Ï–ü¨Îãõ«Ùån©aH>>šO ÁÏáóMö¨Î+wxÜw&Ó›lÔ( ý[Ÿ%m“|ù'´Ò›1^&h[ıAj$6‰Ed’ZD6‘IbÙÄqΧb—À$q mB›Ø&ÌØV°²g Ó°\B‡ÀKD—Ouåö ’òB¹ÎiWkïVèQ'mjyºh=ÿ‚Åø@yÅŠS:Ûv« òØ×¿ìÚÕÝ./w•wÆ*¢''Vµü=/W»òÚΆ£›Ç™.ºDìš*ÕEµÓ¡G—ca5¨…Tê‰^ŒÕ¤cejWŒà„¸óòqS /Ñf$œ3ÄI°ÒÔÐJèPt\tˆÄIõ*)¤ŒêȲ+ÍÔÔuþ±³!þ]&UÝíB9·§;ù¢v®X™ºôÂÒÒP–ˆf3Ä!ptìŠÀ"ªÐôð3‰³LÛ&¬Ð,ç1`‰¶×qÑk—hÕtÝÃïu/ö _1…n#b(ÍÇ6¨½›ø´;(ÌŸhm¾Ýç~xs‹'C¬Óáöˆ±€vLÃIu7÷T¹ª5Ö¿È?,å†)¦êøsæBÖ<ÍO:ÌÄ•\v[ÞÊ5÷ðÂj‡ÈL}ˆK¾ÇáĘó$S72ÿ>&çS~ s¿ÉÔ0êgÁ2YÂ|'=ûÐ_#ú}j?!ýú.íB|le~ žJõÓ‰0hr_Ìc!(.‘ÜîðŸ§@Ó«ùw*‚ÏMq,†˜?_ÀGúΰ®ÚÍSu.¯à l!šXaÀOtÈö¹=ôš a‹Ÿé&#5æÙÉΜXRåüi$ ´àÕÜÖO©À”|¿ÁEU†L´äÅ„aÅÛ*(ÁvM6û%»$†Á&¡_é1â›Ð[ˆ<âUˆýW"·Ñ\€è%=@k3•'ÙD߯ú &ôiØD™jžUÛe.¡Cwþ…9±Š³Ò&ΖMX¦åèÈ#0âDtAƒ™›€Í‚úÞÊwûZy´Øè¼Ò‰›´tgOp2‡²97Ü AE‘Vꃕ¦Ý›(l[†‹vîtgf&vêÒ, YF×§ˆñÝÔS· rUÁÊ?àB‰Ø1Ó ¤›m#6©d™ …Æ^„Õ¢cúÙ"Øy)fö§Ìì9Ä pSŒ;ÄŽ°³52Ñf’h‘*£îE¢LaA«Š²eqReO~žÊ~ŠÐÞÝòùövw7ÐÊß2µ0´”JšÊ‰!”)‹Ø*¨™Žæ#öð=|›°D»„ŸÉU.Af£îi¿"šeÚeš5ꎊ¼Ô·ÃH0 ´w‰P¦ØGy 2†g)mÀjh÷<-¢Dˆ˜JÈÍyvŠ“¶M)iæ+¬clàÚ$ÆØÏ+‹¹"@)Ì3ÅæD/Cb‚v…m _ƺ'9t)«öÓ{.=Opü2GˆC`·QÖ1ô8jåãâ‹)È!1 Ì ®Çn#w 7jéjÑLô%.'¥¥ØžpžÄVÄ »#ô‚VL§<Óà†*"Å‚ å7çpKíìëÏF8òùQÚi^Þrs?WÕHó̆/0þ#ª²Ê&¿½„HcJ˜âÉÉo-¹²Âmý|j„zÞcGÃÿ:—ÿs¢£zÞ\f\óœÉõûá€æ*‡ç%‘DZ¡,¯BA2Jl’ b—XÛ$&±AêÙDiå™$vG™Š³j§S•’¸Eœíf€euÄuß&*á»ùÊéØi,Ûº#]u1«]@¥™šz'lå ªn#ꨀ¦îPª:8›6õ\wNi:MϼÆ)LBk­‚àðüAé´"·[+b mD©Àå’æ{ 0rf]BdݧËþ¦\J»%ÊN[{¡pº=\ƒ<õ¡M)ÆÊ€)ÁÊ+Åp³×#ì+ÂŽ°SŒ¬)††;ÂÒˆH;)2{K!42ÂÖZ ÑR”2fd/Gg¬3ŠV™8Uˆ ‘` „–¨¬&<›-Ê$¶Dìf…J‘£CS$´ê¨œKX¦e‘”hYÄU/ѪÐr <ÚZ.~U7=åQJD=gÔYHá S¡÷2ô ص÷¡îÅPæ–T86alŠm¦[Œql.Ñ”bÜcüt)¿¼› pá!vŸÃ-/ñh™%£ŒÎgý.ö­`ýNyôö3P¢w.ƒO°çjÖßÍŽ·°~ 'V3(°¾Á‘+˜·‹ Ž\Ie;ÉÇú1퇈~‹Ÿ’þ€dÞ¨IÌÿ€=‰ñEÍí¦ßL Ñ`‰í _õ!á“ôy2`üJ ~‚VÂ%·•1àãÇ ­Xes÷J.ôΰÎ߆+±4–`Ð@k„æñ)Ž·„ÉÅUlâLêgØ*>ñj3ß:¬éá‚ © ­hhZš­ ¼iÏdJñRÈ„Â4ùÅNhžˆˆá|’ÁS)\á`<¡¹Õá°d›ÔWK½•$&º1Fä¢.€RÿEœ˜:c’ M`wp*¬8ÓÑmº1¦3–oÓ‘$ £ú%Ú®e¨u "¾îþ`£¯àç|ªf§ut›ÄïHì“`_{m¢”ŽcÝn‹™÷HœÆΠҘæÐG?zâ+_1 C8 róÍ++ç\R¢„Y³®I¥ÃuJÿ‹j'[—y?jíZFl™¡pᄸí¼p:7tZäêªòT…8ÙA†J FFµbìSaDX)F‚•`dv©1V’[°%˜ ™b™s¤F¨ŽM›Ð…¦'Ýb×Ì_;wdÕe’JRƒT¢LRKÇR¤©ChÚÄÙš—O˜Èîd·´ÂŒzç‚fÍì8S¬: K·Zqd…‰ˆ:Ó@·\Fпc’Á7Ð~ §Mi%vo5FŒ|wµ¶Z©quʸÏ\éór„㚬‰×AñX IDATZœð #L GØ6ÄµÇØSeÍv±vŠv ŽpbK3^cÐÄh”©¥!¢—žW˜ZÃÐ&Ö1X›&I1ÁÞC¸ŽÚh]@¥÷›øo¦la=Cº«ëkZ_/Ì-ŸH™§t*æjîY/X Í7›\mSFÂ+!« ,Í"ƒmmv·8¯DMÒ/±4/¶øè¿1tv€õ]|u €fU™÷Î'U}¾q ÉYlÁˆŽ›Ìªïêh£þöXGÝ4$–dÀá}sÙrÏ$H ƒ{x¼/@P²¹ºÌƒm°([\æòH‚0pL Ž¡CS ÕBÿ A?© $§Lb«#]%]†ÕeRvgyŒí<âË+OÍ+t=ÚÏ/Ñvˆ]Ú%Ú¶ŽJ´ÍXiÑ*¤§w«‘»š¹_Øê›Î‘«ÕÙ¤N”t²&2 <ä}¿ú«æÂ…giÃy²`.ŠŽÿ·ÿ†ahPi*  då —¦D['ßá²ò‡ÂÍýL²BÜ®b'è'Ï„,ƒƒ®tþŽÔ1Ó p|Ü/èà”ÝeX™¶â„81v„bÇXùR!NŠŒ±b,H:$˜Ù+ ™`&˜9N‰C#Ò‚-‰îÜŸŠí&‰Êœ 3;i“Ô h‹Ä$É vòÙÒaå&q¦ØDY‰¸AR¢O•®¦ØDeÚ™€àÄ‘™&ÅÝ]ãLÈN%›˜%?ËàyT2ù-¾ »FüS\^Äv(¿G‹û±úžHéW¼©ÎC&›bd›Vƒý1%—s=)Î^ZÁíÛypdï:nÞÊOj,9ÊèbÖlçðJVï䨕\ðc^YͲLöS'm!×0ø8ogÅßsìÍ,ÜG4‰¸‰Gð·’¼‹Þ¯áßJmæ&ø8å:â‹èyÚú¿“Š Š·ÁçC&Þi²Lð•Çc>ì1Gòûã ø`•#4Њ’æ×Rþf ?%Œ0¿2;çrÙYîžÿ,Ž&R\P%UÍ~Ÿ'GO®àCe¹…Òœbâ•> UÆb¶ò× ôxÜ2 ;Ú G‹;ä|Èc¹GC³#DJnïçåˆW#0˜çpËó ã0ÏFš ®qy\ƒ~“aCC\"–¤±I’1©ì8Sß³ì„"ÃÊ“b§ñEÑÊ!Êâ>—ÐÃÏ–Í2­,$ô²™¦:@øyšB1¯ªU`XÝDõÆÉm¿luUΆ`ÆÃ†>ñ cp­ Tã;ßIާ)0§\ïS³#-«ï#éúhh@ˆÆ¾`€¡”ܵËIS+ÏÁ&ÚE«[©kåöNþz¹`$Ð-±.Z T …rY%%”)cÊ¥ ÛY0èfj}¬íHtbä+ÀcDX!NŠ‘`¦˜IçÀH0FöJæq”¤Hò^s€ÎÌŽrΕ™‘{±e®™ÏªEÒõ\Í Z³"è·Ú'§P”M!åØ:rEGÊt2Ó¡«B+‰ŒTɬÑd†M>"($²Ô!10û&Ž¢!áôóÖ£c5¨­%݉ãÍÅNðæb¦ÚÚ#œ±Ü—ònŸïÆœcpMƒ§#Œ˜ËÆØý ¦#Ükްs1×ä•^Öìb×Z.ßÇáAdlˆ%‡™ZÆ’GÙ}.«Ðp©ØÓèùôneú\æ>ÊÄF^",aà=L°œÒ¥TîÆ¿Ê“¨£ˆ_¢ô÷¨¥Ú\#¬¦–ÇKSZ)ÏÇ\%X ÷ø,ôÁ"øzƒõK%‚oNá)VXœãЈ¹o4çyÔ –Û´S¾5̧×ò`ݹoÂéèd2Þ¦!®ì'U˜‚'ÇyvCœ),3lfVWxË©¦•ò™=y–°AÍâ¢^<>Õ‘6+6½ç”x¸Ë=ìOÀÄ1Б‰k΂ÙOHJ,K‡Rgó,›pfŽP±EbvøT”«\\³Å0ÑOÉZÈRØK´3À*ÑÎøW™–KPÒí’ð8í{êÖ´O.¤LC‚±šÎw¤>uEäêÕ•Ûo‚‡Ž·m“†ÑÙd_ºÔûð‡Åë„„¯é¾}í/}I ÑIHJ’¾ßýÝæ§?­[-Ç¥[ou.½4ùÝßÍ蔑IZv¡dמ™yJ ŠY¨›ëZ8uíz .NÚE¸'K|µ.ÚÚ‰4SÓ±SÌ; 3ncv£Â™éV9f™ © FŠ¡;ž·`‘vPìÌÆÜ™(Ú ÉšndZUfíeÖÒùÎr¶›œØ„Ù‹Ýí“ÄQ‘‘¤2U"k‹ë#‚qEwû%($²øpþ»Øù j6¶ÀÕ”]dˆR)c8)n« ¶‰£p],ãkËŒ¹Æ¯Zü;Ÿuž¶¹a‚­eŸf/·¶‘c Ç¸ËØ¼'‡8o?û×sý“ôÄ‹X¹ƒá,ßÎÈ5œÿ{W³h7Í ^1ŽÞÈœG˜z;‹ïaâ&æ …·Ò÷8áS¨÷Qý[¢[)-Âü=Ò߯¹v*¹,%Tb4f¼MòŸÉ€÷–¸§‰V„1­ñ•)ü•òþ^F"¶4hE”™K˜ò÷Çi¥´C$ܵ€-àòž³¬yaBIÅàÂ*Jc :ÎÞ©BÇñ3EÍn)i—|™üÇ<0†¯8äç»0°®Æe}üp‚ѸCÁ*Ò ®Ààæ^ö§¼ƒÁB›£$¹Œ†E¡€ËÔBªnƒ}jîBœñ)«L‰ÝÙì–Cìàg‹g†SÞIq=¬ ;È’’3À²“ä¤Ç^F ‚¼°¦CX+‡§.M¡§MT“8¢é8É’%R)kãFá8€t]cݺìX€:z4üÆ7?§Ë£8­8J.\èÜq M³Ã³Z-£TÊ>}ï{êÕWe¥"„0Ž5[­N’I¹CÝr“¢ 5Ók´»§fÎt}òòˆ²|𑦋¶îLëm¡ ‘HCK™H#ÁJ„™3‹ûRd^ #ÅH‘ VU‰6´)F×6Réj‰Žç  R©‚Ìù^4,‹Ä ¶H ”E,ujëØÔ‰©¡µ™&")”uk°º†BAÁ©1ïÁqÒ»‚<Þ…¹ 0"< Ç©ô³üvNÜMßjÊsi?Ìœ›°Ëè]8ÆlK»7kñD$úBTÈk ËZœ×dª—ó¢OÓÓLú¤6óGäœÃœdñ‰Ceœp ÑÔØ¯2±‚Eu´Æé¥|”h5ƒ[˜º˜9S_Am/©Ä\@é!¢y8›©|ð&JÏÀQämØÿ %Z\¯„HùqÌ5 O\apäî&1[œoñ·“Ä)o­0ßàîqêeÉ;úi&Ü3 ŠÕRsa¾z˜ÏnäcKΰþx/÷ ³¿I¢™ O­}*ñþ¥3l…N_ýMÁ_îc2,g €¹ó<Þ4—/a"=YMs¾5ÓäÆ^¶´h\Sã•„1Mͦ. å]‰0•i—aåÒUGSÏÔ«,ÌÅõÈ!°s׺ìõ.±r=7¬ì¸„Ÿmñ”uË%4£DdT¿»ØÌ«.T5rþ?´ÑuÄ$ªMSƒ}ÛmæÕW ¥ôð°ˆc@Äqzß}¢^ï\³Å‹å‡>ô³Ö™©–ÖZk}äˆúò—u~›%ˆ¾>y×]Âó„(%¢H×ë"àzâOþ{çs•PŒ~àœä¶'³“Œ‚K”U¨e)ÚovÌ-xBÙáB˜—¨üÎêüoцÀD›’RK¡¥è‚”2ï=ŽF* ucn²Ð@‰N……’Z£1DjèPZ(%•&AĺãÆòWãÜ´Z@ª[æíBÇl%³ ‚`ý›ƒíŸÃ1ðf‹R£yòÊt/”™3S\Iˆ±8b,b(¦OQÓ̇%£<b'¸!–ËŠ2Ëv²Åf¾Ã@Œ³á2C,ŸÂßÇ”³è õk}[™ªR!ê¡ÚÆXOßÚ äÞaD«…‘b_†÷êNJ_Eaüö§a*7!žŽu_*î4ø“6Aµ»#FBnóXfð­i¼¿Æ Á§GIz ><ÀÞ6߃”e®ïáۣĊñ€4˜Ï^ÈÇ–ž`Íÿ!#íŽø1äâJ†.ëëˆVÛ|ïàÏ\ëÍ+rxv’áÅ 7Çw.æ¹iö' ÒL Q°F3 ÅñEœ2gš¥H™¢c[žVWqÈ Ì!0‰Ž©f’¥§[¹ÊîyaF¬²H°›ïçágyÉ9`µe¬D×b¡Öód…zŽ_]Àš‚V‡XéI¢„háBû¶ÛŒU«Ò{îá•Wd_Ÿ¼öZ”Z1wž˜7$² •¤úè¾þµLüùˆÕu|ÊLÏ_ ßý„Ð݈©)ýå/…èíåškÑ*ÿZM©„ë1ßù&ãÇ1ÁLC'‘ë”’ºSìŒTÉ‚u”(Ø ‹üÙ352;C ÈÕ5oÑÑM›ê2;f–+ËÓü­N©(,Öîè™N5 :A¤…rëh¦ÝMžºvƒ~¡2*© ÿÀ­wòÈ—; n&œ÷FÂQ&wQ-¸ŒVû0&©. :ãoÂÿ>N“Ò¬w-F¤Ìï+¹9dÚç€Å/OqŸO¬èkÒ±#¬6µ™ÓÔ'i¯áM/󬤦(­äâçØê1§A)K\z%žä™ 0 l.¬2dóž…\3pv€µøŒø|p)eƒG3ÒN÷Ooò:žÝvOÇ`Q™…/ä ,.s88YQ²‰DXEÌ2 S³øèÌfı̷œ³=A«“ÅÒ¬’L5·rbU¤W„9eZ`u )¼ §²`P†¯h£Û9·jÎ,M®jÿùé´`Š´…¸óNíyâÞ{E«ÉEqË­"M |½Ÿ0ÒàÅØ·WR„þÄ'…Rä™VHâŸÕ¦öäÍÛAkRÕA«ÿãÚóDoïÿ0Ž£"ð9°!f¸*Žà©'0óÒcc]JUÎÅ|ØÐ<­ÌÅ(ØKn’W´p1fîWñ±ûýVÁTݘÙ|L¼þRªf&€tK)ÔT«‚›Ê+-ôU‹r¯ú¢c}ÑIµß§ëÍ |§ø Û00Ÿ5ïàà_aô,@ Ÿl–Óõù³ÁAÙ"2Ä ðbdÌB?¥G²®Ád7¼Ê=)¥”ZJ ÖFOá›ôÄ8Ä—rõcls©M£åãZ6ÜÃ+%ªæ$¢‡òXðSƒ”\Ü-øïdÎ×hùÈ2îqäMxßEÏÇZ‡ù#ŒDË;”¼'Ö(QMiIJ ¦ê1›l¶µ9ð¿ p8ä»Óø¤¼µ‡Ç§i„²¡LÒŠñ;à~× ~xœñßçsókËϰÞó,Uƒ¿Ú‡N êˆ:-Ûçä2 žYŸµ¤Ìm‹øÜ~ \pó<~81s)3»­…Ùižiy7µÊÖ‘!:{‚YRŸÕ)¸ »)ìÙiŽS¡Cà9™VååÅÌY:rž—–h•tÛAY·lɶÖMDP¨§©ç!a½6òÍÁ,]}¼^°ôæÍ¢Ve`€¾^ ©ŸV|ÿ^‹~ÞôVÐ ÎÁõ°LÐ8Ÿü8†qò®kÖs᥼NéŒUdì8=˜÷x„$á÷þßgz’¿ûqˆ€þ~6½•ÎÌ› Ì¥REë÷7ð™šaðн¼¶gÆâQÔ㋼XδÁ…ã¢Ëéÿ…îëváûEªÌ‚ù'3—s&φ$ÿ[ŠùñÝ¢Ÿ®çrXh¸œp–EKÂ8oä|DK…8]d¯ÐÅ«{ÚíîÕÅ5KPª`·±ej$¢R é ™Î¼1ì3 Çy’¾cðÁÇŠçrËv¶u!mC„CGÏAê¨>zèÝ‹#ËïæpSâ‚5‰À;€îÃ;ï9tc öNÄí8_Ö¢&Ì»´üÓDÏIÄ…ðpˆNø÷Ÿ©c*6Y<Ö"ˆyw¯è\ç*Ü5Èÿ8 °Êæ–>¶Öyt6Ü6‡ÕŸz%¿})s ï;K ë‡Ø6všÕ¯èܳÁ2w,9U¿²Ÿ}98tÁ[œ\Q{¦’™Wžf6T ‹‘ œ©øfÎÿ’Ô±™o<瘕UFyc…n:r¦©G.‘G»[Ãìæé3Yé¼CT¢•åÑ”u«$|OûV ÝDd2j=çVõœgu…ª:4`NÀ X{kÏcÉb]rÅÁ:ôÅŽmL³bo¹)ú| •òâsD\‡;½ó{Jc’R09Æè±BÎî™ØnvP*³hٌƴ:@ £skü6{vœü¶N1ÁÁ=Ù˜Yp58ÕÐ Òè¼ë¸!Øò¯í?!fB˜(@˜ÌKaÄLnuFŸâ3&úéB8iÌŒ7ÅLÖVD®3Ö?§3 t·Ð''_q¶‚ü4̉U³€Vw½ƒX“ÀÄ=Ú)&ïÏá©V¾mšuë² «ˆ\n°˜óÔO±O`5°¥²Åb<¤1'd4eƒÉü¸A3¢œ`X–`ŽÁ<…¯ðBBɤ–RYƆ§ÙVfnˆèað&ÊôŒ“\ÆÊG^ÅЋ4=ܲ‰Ùƒ{–PÚ‹¢4εxŸ#ù(¥Ï¢À\¢ÍCJ\˜¦ì‰9G³¾á³Hs™Éšø1žfŽàP ¹Xšgêp~¡Ø6Õ¹¿.¼±—GƈâÎM7àÊ~~m9ï^|v€µôûjî®BJÊ&7ÎcU•}M¾õÚæÖ'/åÏ÷0 tösš=öé€%g::3§àÔÉmuH-™"µg¤­w²óºåNšŸE”åR9… ¯“¹–he¡_úeš.AY·<AÎ§Š¡_¦^MçLjº÷A¶ÍU·òæwqÝæ×åA£ÃüÃ70ä óÛîhQÀg?‰ã οœs/G¥g©a¿¤ÁWþËÍ7AÀÀnzG盋Àg™æ _ƒR$ñŒÈ0àG÷Ðj¡Ak6ÝÆú Nþ!CògÿÏ=¹ I@àO£ÒáÏý òM¯‚Ö¥Q€)ˆÛÄÁŒ]FáËO¹bÉL=«dN?覦 ¢„›ÞÎꤊ”fåjÞøúwöèA¶<Èg~3A7°Ô ªÕ »Í&Ü™‹§öI @e à†¸V€`JVh–Mp @G 'ÇÇ ëy˳<®;ÞÖRàÅ”|°$å«hc€ãc%86Î ä{YòUÆ®fð¢ÃÄ9 àýÕ5ŠÖÕXû•Nµ™Š$…LP1(Ü” Å&—Xüõ(Îs‘)Ûê ¹®J+á¹ÉΪàJ>¸€?ßr[Ï\;ÀC#|î"~mÅÙÖŽÑJfL÷‹ö6˜óL¿™@qq?G|¦ã×­Ñ9½ Å©Ý•Îø8ŵ¶ó¬¥VR¨l[:¯·8ùh£Sl¡%i·»*aä/f]¢Ò,ËÙ줦N„B'ˆ¢ïå)b»— áœK™¿Óêàâ,æõGcŠÑ#ßûZCb@+Vm<Ã{{w äÉXþçîAÓYL“¥kþÑÿž‘ÄÁ뚦ýŒ³lÔúè<íM3>úº—Zü¼ïì¾µlõY_Õ³¸³Ãû~öd§Å)ívN?8ãs~ %JȬ)KèWH…H.+Z §ˆ,C-ÏSÓ`uO%¦‰Û"L5* 1E˜0)dŠœOé(a„01B 52E€H¹ùˆìT 4KáPнp4EkÖ¼cÀàPÜIæ›gp8ÂÔ@§ZÆÈ/¬òì4nÌiÍÚ*#c!—÷±¢rv€5;fÇì˜ÿ‡œ½³cvÌŽYÀš³cvÌŽYÀš³cvÌÖ옳cvÌÖ옳cvÌÖì8Ë‘mÏnÏŽýܽÿá©›TŸdïËìØŠN);Üø.zÎð±Ù1;þ•ŒÙ<¬‹8õÂìÞÊþ ±Ie.ozwÿ5þ(}%*’MïdÓ{Y÷ÆYØš³€5;þ?‡§»À`äŽìd÷³lŒê¶nãÆw29ÅÈϽÈÐç²w}¹¿Õ…˜»€>‚ã±òLgö¢ÎŽYÀšÿlãÙßÇà•û˜9ßû].þ#XÙÏe¿Äßü L%H <êuúgvÁñ *`é¹l¼ƒå·PY4˼fÇ,`ÍŽÿ híAØLíàð÷hŒpøiÜÀ+ߣ²‚×^äâó“/`ôj‚˜Å—³å®º•£‡RÖ^É3³óUÞöú:fJ5o{SÍÛ– æ'ç½›• ²ÃÅ]væÏ옳€5;fàB2ÉØ×ù;üIœu{ê$)©ÃðsL3ÿ øó¯âÁ?C€rhŬ{ ûwqþ­<ú5z–¡Lž~’KoæþvÌž2zUÉ©–—7y.å]p2#öÞ*®Åâ[鹚¾_¨ÍÞœÙñϾ0ÿ¼uñ €¥Ñ‚ÙµôŸù6u/rv¤‚…Cû4ï&<ÁÔ7IÊÈõXK]Á\Ìð#(æXÌßÌλñÆZ\øÚÓ?ˆrÙþ´@A;÷–›†÷|Œ{¾ÂÒ¼ºÙ¢¤:-‹ ŸK9„•óƒnÏÁ¾%Ô®¦ò!ŒA-W Qͬ]fgËìø§LûÌ(ÝE:MóÛ$û±çc˜”ÞÔBœqv™a¥|[¡,¦»¤<®ÙoàŠô³¨ÛIž'>†8Ö½D)ÚB-¢þµw1ö0r“Û4½W»œØÎäD ]eå»x5ÊKñS¢oˆgÈÅ¿Èð!ü”µWó—Ÿéx<µ ÚGkŠŠî„„nN¸J9N¹ÞôòåÌÔ¼*‚ÒJe/Ky7,¶¸qvzÌŽÌo HùŽ¡Ÿí§{4¦ï7mÄK8oÖúqa®A(y¯¿#xÇY…„mÞ­è÷¹_Qvøe…)XPa³ÀÕ(Љ= g?•€˜qqÊTÀ–„—{Oy\/ñ¥~Àï“ѵ^)’A‚§I‘WÐþ I±š‰‡`r©Gj3ö<í6mÅš1ò<ÍGvƒÙK³M(i'ûây3êWòÓçpû>Ñièâå|ª”ãQưª§Vñ´´‡(‘8‚†Æ¿#XTâfIIàY̳¿‚“¿E S|)Õÿ£œâÐ@‡óDi¥«ðÿ ÷\œë᯵ù1Äw”˜Hy§É‡%çòͯ—8zUÄ‹>s{¸k’{Ò7žà×›âWRt‹C6Z $Ä 1Ÿ«LÜYüâ0?´ñ ãAM}o8Î_zÌ‘4÷ñ&AE±2ÅÙæˆ7¦|UZWˆÔDí¤táS?Åžì§õ<ˆ^´IÚ"<Še`Àº_åÕ¿ t¶‹c°î¼ö‰Í‚ aõ&žù¥…l¶=E sjˆ1´&éÜí·Ûd!ÎJàÌ5XºË€H@ahJ6ÂðšúÏCáŒðG)‹æÂÊ2ë¹²Ÿµ³‹Ùÿœ8%ì88Åý6Ç2Êßô²±Ê¥uþÊeŽ`¤å°Qð Çûaê•")½@R…Í´ ˆ-Ê`ä/‰ bp¯"N Øû-øyO„&¨B“á° aáQ÷; ‡£¼e^íƒ@”ÁC×]†U›©jU §ÝýÄîA <|à „Û¢àµ)µ(‡˜ œNµ½œ1·k0°œÂª6‹bÿ–hTD¨HñQž9ÊcÓú±~ 0U#Pãnˆ¬ÿ¹è¥z)îU¤ã^/a aTµøI*.Žô7•0øHăše%>`sÑYÖ(ŸR$SWŽñê ŽØôÎaÍ4cs˜ËÒ 1aR:‡‹RtƒÖ4õµœëâ%¨´³f‹ùÌ™Kÿ¿À›¾Ê> mc‚~•>*=ÔBZûØÚÏ@™Ò«<6Ä’^ú#Æ›Œ,`$˜dç +íqžZÂæ1¾ÓËF—Þ€Ÿ–˜ï  —¾”—]ÖJ¶õ¦hª®ã"½‚àÌÁ߇¸’úã”ÞÁØ}$’é1b°—3y„ùogìMïyìü.ºŒ³Ã¯RouâÁ¬G^y!GvÚ¦G^·Ñ!af‘o"ªè*¢œ– µ2ÀêŠ\ݘ±e´ƒ¨¢Ë(K¶D)ÐnKTZ”Cì×Çmâ6±ƒ&C5•\ƪå,öpf‘ë_û8ÊÈAvŸà`›ý&#)ûiöêFM´ær¢š4ÌV"êà£ÝóEù2ÔxoG?u®–;0 ®LÄ3ŠåJÏñÅ^—;›Ü“"$K«|°ÄÏ °ò;<ÑÇ)é!¾ÝÏuPŽ˜®²Acîૃ\æ1´—'ûX=—þv¶,á†4^晜?ÈbŸàYž²¨^Êe1z+/5 —²lóÂÀ8ÄñœËœu,UXÑÔÝ IDAT ¶…Ìz\ÂÒ9T»Û &ÒøÇl+tLZüM4žæ5Êz—kÒ”D@“æsì4`ˆÞ X­IñOxÚD_Äù5*Ç8x”=ÖÅ\ñ[§¾†_ØÎ#&ú\Ååx4áøz~ñOÅŒ.âúýüå9üJÂñI¾3‡·¶xÀc®fØ"*±>å w)þØÆ¶°¤þ(þ'2I5úê’:´C‰{‘$•}tFoôî£ ýë0zÙþÔɦžaÞ‹¸X´ˆ“N# ÊéåÔ3°º’V-Ow¨2!<¨ KˆÚ#”v[”šº »EɧPjáµ)8mʮӠäcö°h#ç´ÐïäR…6‘V§ƒÐ,û—gD¤ “láÕÃì;ÆÞ­ê5Z5¦{™®Ðì×½LUÒ¦œzÊ¥÷ÒøåX5x’ê&þε<ˆµHq[Ì'ÿ5æ… —Nò) š<3Äïyœ{V€õ*¿m0Ñžfß ×‡LñšI¯Ie’—æ3Ü"Z̆ ŽO3Ýû…œñ9,rñŽ3>M —pÁkJÓ„ W0ŒFЍµI4ÆE,≠B‚…·Ëë4v³7Alæm9ô2»‡X´‘µηù1˜kY±Œ…ê>ž—X=T¯dDš˜Çs&¶Fð~.ŠH5òS[8jä]=4Ì¡|‹@úW‰Ó®xÖgGñk„ÖcÊ^—(½X7²BèQêOsÐ Õ‡½‰uñv´c‚;¸f{2áj–¬gùy$%\΂Å,~‰§ªxçsÙk¿‘ï狱‰°l"ƒÔ&4 ÄEÓÂw¹HêqS¼ ¢qB0ÿ+ÿÿ1D&aJ¤ñ6…0g5/þ±¤­Hrœ BU°ü\ÒÊ‹Ð*/]ÀÇ€¢]A” °uºÈU)Tùx'aK—IM£E©%Êv[¢ìSjãùx¹ÈUа[”}¼7ËÍm\7ÀöqnfÞ\œßf0@w{ÙíÄlúý?˜:±‚t;@ÞG}?þ8þ8RïЮЪÑèaºL«‡zé2­>=Yõ*^=U¥YNZÆ”¢®#JÑs#ñ”.£ýiú~èÏp/FîÒæqm\—èÇ”xsÀpEÈŽ”;[ˆbÇ÷žúÅÀê4Oƒ„DIªÚ9÷9feŒÊ±‘%(£kˆnH˜T7¢’“¯J®j•Ð¥ÕÒ%™V œU/”Úx-*!v›’â´¨8n›²â¸N¯`Oá†X«©TqJØë±nÇ 5 {fáꟊWÇ`/8‡«Ï °~Ä{ØPcÍN¾{·íçÙtoØÍO'˜¼”7G¨m<7I°™·<Àƒ•‹¸ÄÀz„çÄ‹X°†¥²½‰ºŠµô¥¾…ý!â=\œ€Bü˜}'Cx$¨“üC!Z#¬·°ÈÅ òþ…Ãøp,ëJøz$KvZT+¸È÷²<Ó°ÚF~™Ý $Z É]lHÑOrðS&*&¹“‹4j+÷1ZFÜÎE/³‡Môìã&ZÅü¥ÌŽg4í«yÃavspçOr0¥^£§Îþ>ú—sÅ+|á|îÜÍççsQÊhÌžÜ8Í÷m ʬ ù²Mâ²ÁF^ŒàF9ÀeBCíDÂNR‹@—”ø„A¢¸Ëch¦¼ù?9šòËŽà¯B=ßClµRS&žh»~ºKP¦U¥Y¡n÷0]£^¦ÕÃt•f•z/Sš5Ý9püH4` &¡ï0Š:€>N©w=¦ÀrÐ?¢ô{¨ßÄú e<ŸêK#ñYÍÛR¢€ýló’ÅÆ„ Å^— ‡ù¶dnŒiÍå­ ÙÜÚ³dXßàø4“7&'ÅŒIÁQX1Qн˜ \…ˆIL»Bµ‚û' \LP  ‰©0"b…T&†ÆÐȈX#¤ B#BôAZË(e}³4 éa¦…®½¯“ …@[NÐ ¡dGÏRs|3ó3‡•„TƤ£´Jóq%BD»YNÏbªÁ~F{p—Ðr|ƒ&ŒrlŠñ ¬l1yŒƒKYhþ?Ô½w”çyæûû¾Š'ƒ0È ˜ÁœIQ2M™ ¶dke[’u½wuwW–ïÞµ½ÇÒ±¼×qîZÖZ–-/E™¤DJT`ÅL‚‘ˆ &§žî®ø}÷ªê©D ûçòôéSÝhœžê_=ïó>ïÛÜYÅ*ƒHÓ¬På  ÞA§ÏÙl¬±»‹M ãeGrqêE¶ižqh˜h;¾…°ÿv £0SOAî¾™;ð³’0gT¥ÏÔsV |t“PQ‡xY¥X‡Y0§ÒÕ%݈ª`IÌ"TÐeD9#W%K6TrÆ|«ŸèÎså)XVC|ÜY]šå{–R‚¤E·U6ú8 Šv¢È|'ÄJ^àøØM ‘¶šÂõq"eê@ <ð5Øé CÖšl±ˆc˜l- 4‹m–¸?ýƒý¿Ú~êÿðž±ÁhÄ>iЯØâÚ¼B,bDeéu2ãàih¸xmLW¨9øjj%êUf*ÔŠÔ;ôTEÔ*Ô:˜,«ºãùƬbFÑå;ÅÌ>:và了ËÂ,`61€wqVh»*DC[eMRŠD¨(G(…âFDEa)¬"Ê #¦·Ž÷rýeë5þæ4{×r—‡¿——WsµÀÝϾõlo£ç^XÍ¦å¬ ßå'÷s[ÿU7w³}ÿ5NÚna½‹ó"gi.¢í&–IŒâPŒ©1îfi' ùOœöA#‹Øïg‘‘ˆ¦S4Ÿc\"„B€Ž×QÝNù_ÿú¨Ç™%2Óo‰V´þ5úBÔÁw9/Ñmo z#=G™|ÒAÜÏòà g´ˆ¸šÅ5êÇ9ï"7±ð8ý®gÑr¼Á®Et4˜ö™^Æ"I4Êév eŠ —²fˆwV±c„—ªôViŸb·ï›„E eÖüØA9x&Í·™ì²â üxŽSa&£üùœºHRµ«¼žj¤¦URê&aH3™¶ªg7p„pµn}Mº…ìÛÔ †“µ[,ïÇ·*Ä*ØÑ’b ]„Ê–ž‘H*w6më¼”\¥n)¬E‚(²DŽ%Ê+Á–§]O¸¶¯3Ô– ‚ì-Jr°>D!„È‚¢[ò[ËcÐ$¿µþ?õô‡1 üAB„EhƒÚFÀJSrÂT¦•©Y„%Q/ÐtðÛ˜v 4ªÔ\š‰’*3[¦ÖÎŒ‹×ÆT•™2õ&KzÖñ9£D &`ª·Òû~Î|ž…÷QÙŠž$>HaÍoÐñiâ7(ܧå˼VÉ¿Ðâ¿üU̵G üF—  XÓä\‘ÛÎów1íÖŽs¼—‡<¦–IÛ~´_]ÍÝ—¬çø Õ¤©±ºÔC¤KÛ,ÍU¥«ŸaaQê sŒi‰U¢#§¨ ì %=…";)) |/¶ƒ]Á‰‘ï2Õ#—P QG½ÈÄ5´…‰¡ŠèÄ1‘ ¡rÕašÇi&²knÃC¤© éòªh!`–¨A$@½Ítòf:-èšu‚©*æUtLÑô 1²žö•Tƨ 0ѳ’¶\bì6ÖIô9êLoeõ0çСhp¬%eœsì_HbV1ÛCï8ï,eóû,<‹x)·NòÝ®TœŒ¸ÄaáÇà¬XÍãTòñór:«™yUy`%«gª‘#W]GԈôFLV#§°tƦBÆ)7÷Ð8äÖ Ž¶¥Œô •8Íœø´È, Ëˆ‰‹22Œ†(Õ)z¸Im˜«™úî¥+qåCœfêǧÊ+cVаä Ô–/ÜD‹Å±©"I,Ò·+Ô‚ôeoiQ&`ˆémãÊ ±"™»¬˜ÜµSdA°[»±K¡ÿÕ.ÑG³ÆçÌW˜g 4H„ɹ&G'Á3û-$¿˜LvöÛ²ÁÖ†fì¯@ÓÅs´_5‡ H½D£@£Ìl‰z¯L­H£B­ÊL‘F›žiS ¿JQÃs6f¦a â*æB*+ˆNb†´ï€:Þs”×PìC8 XUmL«MÉz,VEœ‰YáÅtÕxÂæ!þˆR ÆËÜ"b"M¥Î¤ÆŽ1"´¤c#ï[|™£9CŒVécLâl¡ï(G›DKY2‰aj«ÙÒÆÂ78vžÚV6ïæ‚‡^Ž»å82E³±•Å8[CÏPÿ4[ÎPßÅLŒi¢~‘…)ü€…±›éϱ¼‰Òˆmtü5$†Fh„GãÚWâ$^•@kÄ*J­_ë™9NXÅø,K¬ô,йXƒr_æ‚ÙåEôYVZˆ=L½Æ”…jG*Ô­,ñˆžâB;¢ˆø›0òäÕ,™¦þ2ýÛé½›ÍOðš‰ÞÀBs' è ¦Ú°V²á4‡J˜ ¦™’x&áç 0I¿FvruÌð(/ØØMNXÔ-LˆZÓTô›Ø‚ ýx´¦aTîgÓ3qöakÝ‚ì Ñ 椙h¢Â”u^®?˜ÐJ‹N±¨ÆÆ’ÿˆÎ}ólj;(’€\‚ËäÃï€Ó`ATÁÉLúL¦jKÒšÑ(+ÃQveªb×iÍRöt¡!ÒÚ°NÉÃõS„3…ådšËñq< v3–O!¦‡›x[á†h+*XqlèX¦oK˜Í!µÈæf’B†b†üyoòwF3"JŽD´Þ¦ä Å¬ü{§s`©ÎÏ{é3fú¼,Hh˜´x<%–lÚÁ\0ÀÑ8"–¥ #¶…ïØÂ/Òpñü ¿"j.^™Y/9HZ~š ¹ÚôtEÔÊÔ«bº7,?3ZLC&a|(Ø´÷±ôç9ó%Ü„:My £_béð_Æ4‰_Àú¿Ðobö ¹K;}^z«'NXÜrDÐ]á?Ͳ·ÈCSì®ræ˜Í Ax†¶qÕ$c&1fƒÆ26ÛYóg+¬—ùög›ÄÚ‡)ÐaŽ2]¦³›ž·9ÖËÂ.º œ“Œ¬b‰BLàÓ\MwŒ1M0„×A©›bŒ<Ä”ÀXH©„íÃëLöຘ+('£ißeb%®B*D'ÖR?óÐBíq K°z0Õük“鸛ÎÎm û‰&ˆ tHüIºË€£4Lx›š&ÞBaeÐǨÕÎ1»ŠÂµ´Ÿ§Ö <ÉÄfÚ\D€ŒÑM´Û蓌‚wë_æ C¼šî õàvRçBÓ„)Încû1^ëcyƒaM­‡ž'Ûéõ8f¢\ü6z"Î:ø¡MàâÙ¡«=[„2ЩÂjŬ¹h襩…¤âó3üx¹ƒ¤l@†JŸhf%aä²eVWJi­e7,íehÉ)7Ûî'LD"½p³“]í¯¾ƒ/Pš«GRÁ•XZÕlSM8i©˜4CË ¤ÓÅOê"q哚±(©Œ_N«˜+yhùéC+yM„åiÇN„àDÚT±T‘$‚H$’*%WœÝ'“•*7GÍ¡jîšÑ¢•žð¯H- " Ý ³¶Ì왤ììI[c 0ÁakmhÃR–"*Òpð|ߥéà'$Jо^‰Ù"Í2õ³še=[3%U¦ 4+ªVЦ‰LÁ,ŒÃd©´¯ÅÖ” f}Š%·bB±—ÉGYp?ú4vâ…mÈaœ%ˆŸhóÎ@‡¢¬PšÍuž—\5Ín“5>Lšlœæl‘+†x«Ê6—å³LÙ,ðñ§™°i?Oÿí|r5W_°¾Ã?ÌP;Ëð-ܹ›ƒ³ø[¹ò4£'¾—ëÇhìæÌ6Ö–)ý#ÓÄ·²f–x/“D¿Îǘ~‹‰&†õQ–ÿ#çÒGÞOO;ö>hFPCo¡r#å3„oÐ1"„1Ô¦ÇK½Eˆ·ðö?KkKT 7QXƒ™„Mê¨ÿ΄šx!fLô1ºlØMíU¦KÐŽXƒ»‰âã F„ÈbÅÝ µc–Ð=8'[E¹ŒqŒA›ø6¼Ì*Æ-lz†—;qb‚æf6Nq.f¦ò g ‡Ø"p],Á´Eèà0%3¾Mhã'g›Mèà[:ÄG´J?/,/Ç©¼¹ÞÌî›™uÕ2ÕgÑ D/¦Í\%8 L)¥ã µâx჎=öXR¶PÕ– Ræ€ÕªJZÀ²³‡föÐÊÌ°Ä Kþ-íভF]A¸PB— @d›¡aÎRöqº0+JVrÖ%t«N1ÄJ4WŒQ§byÁa4(F˜ ÚbmxÂ1|œ+Òf„hGk¡”‘¢*áW¬ DÚQ‹2…]B«8'>/zxi©(s:ËÊŽeVÞ˜Ù ’6P"»\`‚ 2y?µ4bCÄ–-BWx.¾Iè¸4mD³@Ó%(P· Š4ÊÌÚDef\ü"õ*3 ° ºQ³I èÆ¾øÒÓI.ÌÀÌ@v|†“_§g5•¥Ô÷¡†0aýo3ù-*+iü˜Å_ xq SPØ‚9ŒQ×–§k#íùâT„£Y<ˇ;§x«ÂÇÆø^7ŸždÉ¢ÓMê]ÜpˆG+lˆ08±™Ÿ{—×ûØ"V²e 7]°žâ› /aÕ+¼±kÆ>N¯`Y'ßcÏbz:éìgJb/¢½êÛ\0°WÑUÁ}œÓK©® £Œ=A´—™…7SmÂw™ìÅVˆhO®g Þ¤±™‚ÆXÝŽ©âÏ™²‘±³€,„üYC9œ g 'ˆaÕ¿L5B™ðõ)ÂABˆwà^Oi735ÂA¼ú~º ~aE¼kî~F%ñ´á].¬¤Ò‹»Ÿ3EŒ%”ú}´M1¾šÞq·Ô]B“Ø$(À"–LpØ!´ L"ß ² m•œs‰J· 8“±ÍœWÕ–—3×—xU­nàl&¬fÑMÄ,ºN33°X²dìüùUŸý¬ò}¥Ü¥KÍÎN`ä駃CcdÄœ˜°ç+,Lp3 9™»XvdyrÙ™ÿÒYÒt²­5ED¦Ë”%ÓjÈbˆU£`7t¡.ÊIÊ¡A)AX€•¤OC̤LJÅ'À ±}ì3Àñ(DÈG!}œP[‘0C¬3ÄR¡¶´Z  bs´Òæ À¶æ ¥çGÓ\ë<…E†!323ÓSXJ„ÐÒVmÊ(9[,B‹ÐÑ-›À"Èé)Ï&pii$ð*à%&z‘f‘F‘†«›I›¯@³¬ëEÕ°ãÀjFi4o =K ¬„S=WQé¦TäÜ“lø0ã/ ktm {j†‰ÇXüsx/ÐõÞ ”z‘8+1#mI!*ó†H†bà3 Y3ÍÞ"× ò½2×MsÎaU€še|7O3¤qmzúÙ×ÖAÎ@ñn>¼„•—¬'yüýëØ¢_dÿÖ©ìâä:–/¤ó%N.£·ƒò;ŒŒ¼ŸuñëŒ<Èò:ìbª w±°€¹‹ÚÂ!¢›è¸šÊ£L*Äqö©‚4P£Ä,Áz˜R–®¯\@åSW¯DjZÍ…Eú:앉‘ü%¦,´–èň Ø±Ç ŸbJ  —b^OùyÆÎÑpФçr¶÷²ð[+Aã â2£n£×ÑÒc¬ +`Ö$0ltr†™DÉyf$7‹ÈÆ·ˆ<› ÕS„^b78¶D«÷—÷Ô›¹!?kìåV=;˜Mïu ÑD×ñ#¤Àjûõ_ŸÚ»7‚òu×¥’B7˜æÌ«¯6Ž—B ¥„Pµš¥”›ù¹-`Y`ع’°E®ªì¬Tl)/{>°’çeöz#ãš•Ê9m#JiQª+`ÍHšMÜ:¥@Û~ºÂñÒ”i"¬¬&Å&n€dµ’Ú0œaFX>v€‰12Ä °5ÂÇ‘ `+ …ðq´–aÄÚÔ­¡´Ô±˜sJõåøëºe]R!•HÛÓ‘!â䨾DD¡Aœ\á"rñ,B›ÐJO¤0±Ò³K]Xb6)]ü" ¯ÌlI7 ¢Q¢^¤QTM'òeCÉ$€W‡zÑj¾LÃ,l˜CÑÓžÁ Øò«ôÿ# 7SZ„€è<6¬ü“_£íj‚çpâöbboC¾„Ó¥¤ˆÅ]>ÿ¢¹¡ÉÙ_³Òåö ~ XMq¼»ÆØ[fÛ(Ç–zD3Ô{ØržÓk¸åo,ã*‹â^öÝÊ}W]æhÎ_ð—UzÐ_¥º†5'ž$XÍÒ3LˆNÚšècL÷Ð~Ëþ‰ãUœUt­¦í›œë ¸˜ÒRŠßfÌG,Ľîñ2³ƒÄm˜kp—â=Álˆ\Šåb,ÃÚ„Áê_ðZÓ‚K1KÇ™ßeѹZ€&ŽP m¢â/PUè£gÏB¬Q½Èmاð‡ñ@…D·P 9N3 ø5ú^ad”Yÿã¬ø'‹¨+h? üë~Ä‡È r‰ ‰_@÷Ñu–“nîªØb–ƒoe„ò“SÐIYæ»x<[F¤t€hÎO®™!ååÒêõ\*¡•§JÈ”(¬´²}Ãi ј™ J¥Â'?9ö×-¶m“ ÔU33:ºé—CaYÂ4EîÕ gôÏþ¬Õ+,´4“DØ9€¹¡ ó…•{ °œ¬Ì±/90³žH« fdÅȨYD9BY2vSB¬:¥«AÑÓn$Ìd²'³ä­¤HÌ”×ÅÀJ•<£…È+ÀU f„©‘­µTÂÒEIs­ï «´m-Ñ’Ø$’ÌÑÊ"L:øe[„‘ƒo›D6~ë‚g¸ø-ÁIO›”\EÝpDP¤žxU%]wcÏŠCÃ×s@ë$™ežä¶ªÐÙA­Ÿ›þž¡ÚM©ÂØOXÿKŒ<…hÒ¹îëQcL?FïÃxOÓù‹„ÏQèCö#‡(ܨBÄ!_ Â}£‚-1ÑºÜ êŒvñ@?O·qí$ç ¬ PÓŒõ°ã»»Ùt’C½¬fXʲËÖã<ý'¶±ùýh®aI uŽÙÍôõ33E¼ˆŽ>Úö2eancáA¦OÒÜDçJÊÏ21 SèŸcA„x‹Æ!‚å¸wÓ¶‹æ, ¡'Ð 0¢b"„#ÆÑƒh}ãÄ™Âz›hdž-pé,N~Gw"nÀŽ=o¢]ènD Þ‡»›æ;x6ªÚwSü £m` ¶SXŒù,Ãj+¥˜ð3â5O3¹«ûC¡&Á 0à $¡ i˜Äɹ•(¬äªèà'sðU i‘\9ƒÖ¥ÒŒcáçôT󤼜›ÞÌι¹ZÖT&3lIK?üÑpx8ð<½u«·wïäË/—åWjûöy##Å ª>(”j=*U•¦¡âxÛ IDATîÍ5 ÷nïÞBf@%BÊ0sÂ*O.{>°ì\©x°Z 32*Ù? X­™Óh&ÚeÊвbaÔE!Äñ´ë‰Ô’OLwÇO—Ý ¨‘>vŒÑ¤c$õ`„`'—FDX!¦F„X1¦B$£¬ÉŸ&'šBÄ#ß Xr.«¬ b™îÑF†­„P&¡DY©Ùå♩õXs=™(‰P%W8‡ÀÕÍ’h$ ½DÃÑžņ O‹›´‡HåC-;U’ÆI]=41 —PªbF,ºŽá'è¹’æ~¬cÃÒßdöQ*Û‰žÅ]Ž]ÄöµµQ˜¯D²-¢M±³É÷4Ûš 70:øÌÏ Ø¼ÛÅÝÃ(³y„~›žc’É^¶œãì®—=ËØð3gªy‰°š%õÒg²¿²fn…J·~öÇâÂddÛñ5×4^}U¿ï}bÆéGaýzsõjêõ™'Ÿ–%âXäôjñ–[¬+榉iª±±àßp´nJ…3ßoi+;VnŽ\VöÌEÀ²æ{[y‘eäŽÍÜ3É™5׌ì¡A,dˆ ;1¶æLwŒÖÃıŠ0›âôØH4W‹Jáá*’zЊ0’ã‹ Õr'†¾8+寣Ɉ˜Ed&§¨Il™D ¿ b›0s‚LŒ§‚­}W$^U¢ÍGûE¶¬(2¢X4ç¢ÂºhäÜ̹¦³ÓFÑ.k¯Bú¬½Š]ÿ@ßzƒ ¯rŃtöqô«,ÞAí„G['¦GÏMˆ :¯'S‚;|¦#ªWDxÃMñ<êŸb¤…4Dù–ÐPGüQ-Ë®9¿$©{•úVÉCþC¬^ |—ØG( F݆q;Öß0['J …Ć×D‚xNDt‚ºIø!ºc°ˆ„&Ú&„È$rˆ ŸØ¢‘™Zé §Bß né©ä+ë&çŸ*Ñö«=›À ã9sÝ¿d°¦e¥·<›™€Žå,ØÈ;/òþËS_Ç®²`ûö°æJNösÿ‡yüQ,G˜þK/GwßÍæÍ³_ÿºû± Ç‘• BH×þ­ß’®‹ÖBk1?ê8¿û• Ç1„°|ßõ}S€‹v-þR3¾Uš9W>©ÝŒAN¦žZÀJÚùvŽ\Fd§æ"K-©e  4")¶"Lt„N'¤NQc-´EÉ_‰0#ŒCa¨ôo*SU1f¾cÄó݉”PBkQâ©'ü2‰T™D‘¥ÃäØÒ¡D9:‘2T,â,çe„òr“ÍܨV-7¼ÕÈ™ V•Þ5켟gþŠ~“OÓµ„îEÌœeó]Ô.Pí&öð'8øUnÿ{ÿ+›?ÆÌâAÝÂÐ#T»‰ÎãDŠè}¿MãŸ(¬D¼ƒÑĵµ`Üé‹=FÀ¬ÁoÔx"Ä€ ;/ð/ øÌ~Ø Q'\Ã'òX×3\d©ÂàôznÙËÙtŒSÝ,šÄŸ¦ÑÍÒp_½—¬oðü›œ!¸“-¯q΃Í,9JmÿVïgú Þ6zj°‹é_ /‚Ý4NFÓ}šða ëFJ§ˆ'`!P¬ ¢vƒTÈâ“Ø58öï¦Íb¡ÁBhDô³6·Y¨¼»¡4¬5ˆvx¿€JvІ¨ë0÷àÐ’x!2$®&›°L"‹Ø †ÈF%BÝH}Pe¦Š=nX„ °21Ú™ŒoYì-…•tsšQ’B¶ 4<3Tóö{ó…U«ú›„ž ø’Hrî(Û>™=8=Š7^⊛i4°«D’S'i_Ä_gãj†'h(µ|Upüx}vÖØ±ÃX¼˜(R'OŠ8– l›(2î¸ClÚ$”úW§GZG¡ÇÆ8sÆ*¸â«ÿCç¶ÆyÜ\|¡u`ä°eþ´Úð"Ëž*++WËÈ¡J‚…–ˆDsh!26ÉVY§3OJe{Ö=·üC+Œ‹? Ù”EΑÐÙšû©{ÚHýu%‰e²Êá=´/cj–†ÓÎ;§Ø²‰¡QšŠÔÛ{ôíw¢bA³ÎÔ”HV¨G·ÞΆ¹­“—ËP1†mÏûmh0M~ücªE¾þÏ´Cé=òYÎ%MCû=¥y‘ådµ¡1_aåËC™),#§¶Œ4J ZÇé"ڼĜÂÒBÏ[×2—¡I5T:r¡²Œ‚’$E´Fk©ss… !âK?Uî[Ô‚ÜÜukû¢9Ð0›~oU‚~®ôreàu7±i;ííìzš÷±ÿyVnÀ±X¶‘]ßäú‡9ô}­&˜¢v–E)T(”ˆgèÞÀ‘¯²ùÓL¼I±“¶e =ËÒ{ü‹ï…•XaUñ_ENãî ~{-úUÌLp{cs4f›'†, ˆ$·ÍðR€ kM6ó|™[=j!æ:Ù~–ƒ%úf UIe¡%l8͹ ½cÔ%nˆå¡úXv';¶²ú²€õ^`æ0“pÅSœppÖ±ð Æ}䯰þ«œ1°F€3ÀØIû«4BdŒ\EaöÓ4 Ìn¬OSýmfdŒ¡.b+öËÄ ùlºyR"~‡X 42ïøfÓ¢I+PµÒx-1¥P¿Œñ<ÑxX‰­I§äû_S%•ˆ©äÞÈ€%S6%æÈL½ªÐJµU˜tv²h`åüõ„M ÎO½5$èâi˜D%ê¶]Ñt•'óç_#ù•»ƒÅÿ–ý_fËï3ð‘Á™¹ê÷8õCD…½t_Éä(ǹõs<ýǬº•wžç®ÿ“Úý§Ð&Òáìyn}ˆÇÿ‘«Àä™ç¹ïAžú6[·òÀÏÆ0°Ì´Ä±,¾óïìN³×—J, þ8ËVpä ßûvþ·27C×€?ù#žø‡÷â(L=ça¹óÍx;—€·æÇ¬œ‡e䀭ùF»•SXFn„8gÃÏÝÌܤ±ÈžÌ"ë9Å.~jF!©ïZ+n[évlɾ«‘ÖñE´R™\Š.VÝû™žò/ÙÒqÑ®/»°iƒ›ïæªxûYl“ÞE¬½‚ç¾ÆÃô¿ÅàîÿO~ž{þ¯±l;Õ¤ ÿnfú ¦`ù]þ36ÿ;ÆÄ‚ÛðCÝ þ&=`øÿeÉç™úŠWPºc–ð…«tðw¢ðYLCëãíX<‰8æÖ˜u³<ác\bNs,@vó¡~žŽqC¬€b„èæê5Îx‰¥'8r=þ˜g–²ÁCbä&v>Ïž ¬=Âð‡¸ùf¶\°¾Ì÷Ž2±‰e¯2 p—Ðvž ‰XG×n¦ ¬¥T‹8ûh4á6ºöМ„:ò6*cèý`v`-Çy‰ÀÅPÈq=ŽD¡Ä¹‘±'Xð9ó§X›˜:@åV˜铌Ÿcá} ‰’þ1Øtn%†w_æ–ߤ6Eÿ ”‰tè?ÇmⱿ§g5˜¼ø|*‹~÷ð›síVRrd?ß}<ËMÞ龕|ðß ÖÔ‰†fƒGÿ;33é8„ÛïâÚ[‰¢ôûÞà]\æY—ËÊË™_Ú9IeÎYÕƒs‚±%µ`žŠ”9HÉÜ%sƒÍ-93oíÊ¡Jç´U<¿Œ3©ŒS-g*Ìvr…\¼þ¬™K-YwxãÕì}›­›éîfÝF::8µ—w~Àƒ¿Áð.eÉjL““/Qí@7ÙË ŸFhFw#BVÝÁÿ‰›¾ÈÀStn¤² RcXL=Oqm›ù{Š‘ßeáç0]¤@J¯`oÃlƒÇ°¿¬ù÷_Štˆ¿3ùŒ§ß4ÅuŠ¢Ç;çŠ<ÜäœÇ±·]àñ˜’ kšÁ$`+ìv¶ p$İâ\¦$JS&âz®9Ápý)îí£û²€õyTã ãù°žEðÎã/§k†øQëAŒ½„ÂB 0‹W0Õφ[ÙûMV_ƒ?A±@Ǭ'Ÿ`Ñ6 Eó8+>@s€êrš' À;Äâ3öÏtÞ€AŒR¾‘à%ª¿€÷Š×Àrµs‡àr‰2œX?‰øH¨G\£¹¢É¿8üb'¡Ãæú€‰YµqƒsuÎV¹>$gïBnæ¦OØÏÁ*«êÄÓx1VŒÝËú~=ˆp²¡±ð î¼í2KÂÏó­¼ VóVšOIn3Ù=»ƒêú¡ÂÈ:22Æ ]Ò<ºk)¬d_»J+‘ˆ¥þÙ+.¥U UóVfZi1w¬’a# ï…‰i•”„9H%¡Ð$Â%«<’LCªš[b•¥«\š‘Áô>7Å£–Út5y´Ê]ßµYâ²Hñ}—ß“ê¿HýÛ:xBÄíè¨v&ÿÆvâ*öD&Í =J埡ïßqø/麿Îä0ã'¨Ãu_àõ¿¦çbÁáW¹þ3ÌNsö8‘‰°¼À·ø«? †›îágYÐˇ>“ôQ1q˜~V'.ðÄßceâõγúŠ÷Ì5ðÞ›654ëüý—±²«É¶›Ùv3€HƒX¡BÒ˜á;CÌ3¹ÌùõàEÀ²æ›î-1eÍVfÆ#3W¶Èîó¨’ïàPóW¶DVB¥KM«‹€g ‚Kö,¶håå\voþß&«Oÿ&¶Á¡]lÙJФ¯·Èî§Ù°j;Å2ýw–±C,^Ã[_ãƒÿ•ã? ÜÁâ͘6ï|™¿Ï𠘊…W!¿Ae%ÅNâazîeàó¬øfŸÄ]Jq-õoÐö š_¢üïÑaÝŽ #%zc^‡÷Ç"и Yçƒ5‚¾Yžs¹×g´É@™cô O.äaÚ'º¹.F¼Ë7Wóóü>¢9:ÆèFn¹ÀùcÓ}Ôr6dÈC%™ÞâÜqËev ÿÿs˜ NÖn`*d†-3áT”Þ›­KB7™‚ãL[©,(Ü Å¨¬£œ}÷D:Ûœs=Å{ôç)¬<°BeÀÒFZ¦v»@å À¼i•€¡I˜”~Y|!´³Q ;•T¾Mh⹋X<Å‘…,¨P˜æp7Ë] A™>h4ÙçÐi`Ú¤Ý`È¢]R7©t›4Yeè#RuêèˆðG‰¯„儳„¡Çä¨v*÷S$29ÿ<½fè 3X`ïwXt5£çð4•Ù…v°:i*ü£wOÒÕÆ5w°íf¤`b˜W¾‹VMÇ\‡•[èX€8.qˆŽ’½?áÂiÞ+Ý æsê"ëÝv¹çãÄQ¶~Sk¤d¨Ÿó'ЯÁÄ(n‰ÛâÐnFˆŽî›7âsÑ8´“•™YEIÅ|ÕBó¥V¾Ÿ ÿÕøFþçŠç‹¬Öªr%a˜#W˜ó×£¤ò^•ÏÜâùV@!YÎ1 \qmm,êfz˜J™ ›˜ 1…#™fÇ-œÙM¥Bsœ[?λO³x5Á+w²ç«¬Ü‰eÏ2µ‡MŸàøß²x'v‘rçÿ‘eÂ;¡°,ÂÃô|”Úc´è-Üíˆ1Œ6mÆBÅÚ©yL‰å‘˜TZk±¡É[6÷×yV²ÕdÓ ¯hJK Ùè15͉.nõðÇy·ƒm!ÑGqµ¤2È*Ë+,:ÈK. ÛX`R8ËéN÷°èmÞr©Dˆ4æY¦D•¸ör=¬gx÷9Žže6ÆÐØ ÃCj,•kžÈŠ14"yRgà8M 'ñ¼ä2{IbV­o—Hö\ ˜o-·ìvß'“XQí˜ÕY¹§±‘5 s]¦ƒQ2zÚš;Mœ©ÄœjyU•„?m_ ´‰Mš&ñjV]à`•¶M\{Ž]5Î^Ë/åÛ½l0†yy%÷ ñíÅÜVdAƒwÚ¹ºÉsUnќӜ՜28SÒ÷!¾këR7´ºO4þùQfþ?Ì{™}‹â'ižfø ì °wGþ†î{9û >D‚¦¢ ¢@ÝÇå0Ý$„@âA$ñ f|~í?6ùç?Æ1x߯²h%(TDà#àõïpþ(RÇÜôAÖ^‹ŽÓ20ç6¢pÙ:K sŽ_û_`ÿ Ä1ë¯gëíD†‰å ÒDš<õ·4j|àSD†Å[ßçèЗIJZᆼÔ2æGÞó)¬K+A1¿íüÞFû<‹ª…­|ç\ö|1æºAVîE9¯*È™ë §’Nâ~‘f’Ãßýú8å2"æè›¬ÝŒ„înÊíìû.ë¯Åu(µñ£ßeç¯ÒÙ‹aðÚ¹ûKD5‚1j‡Yù‡¾ÄÖßAÍ¢=ÿŠu_dôo)¯Ã®"F)߀tÑ'Qý® úoºøÇBÿߨ_Vâ9MA‰«bZW"QóØosÏUøÅ:šE® iN²§ÌµSìoã…}Œ'6ðqÿ<ïv±QR<ÌË[¸' :ÃÑ.úŠ´{„ç8ÛÆ‚Õs áÌû¹»N°‡ãç˜ún™ÆóP§ý87/£ç²€õ'¼äàöÑf`¼Á…ÂE´MÎÈ:ê,A¢¶z)ž%ÊFL57 *³’0ÕV*}Mš‚¹dëg,ëhYì-‘%‰/ª ³¹­4dœt[“ñ­†`+ZeC`9Ä’À ´ˆVRd¸ ³—’$ZJÏ,S³Ýt„4ëŒö²Dã×8×NwwœCݬ6Qez=޵±" ?àx™‚‘"½šÓ1ç«l6pÚ%¾gP5¢=Ä7œB¯¢þcô2j‡0wb­cüU£Ô§Xø †_DU 4¡‚vœe¼ûM*[§÷³éƒÔg ¶btŠÛ¦ÜAg/n8âõï05Hµ“˱lú6á1L¢Ódßs DJHÁ¢õØîÿ°4Äýû2#k®fÍ5C”I}’ÁDÆ6C IDAT!çŽÜô ´/Äo"Lê3\8ÃøÓc)_\—“{RaU˜Ÿl¸ÈÃÊífκ9`å÷‹ù´—ü z¾¼RóbV)’ÈeAãKZQ®îK¾VR¥zJ‡ˆlîO{à#º:¹÷>\ÉöüÃ_±t“{ä…ÇQ º°~ µ!ÆÎÐÙÉè)vÜÍñç¸æ#z‚ë™þ—1%Ñ>È‘¯Rhãÿg」㼮sïßyëT`Ð @°÷"‘%Êê’›äîDŽKb'vœÜ$7Nl§|I>_‰¯c'’%ÇU‰mÉ’Õ;EQ)R$Å‚ @¢w`f0õ-çÜ? d'Lâo%¹Á^\³€)äâ¼û}Îsž½Ï~Â1"¥Ä_§ùⱂø=T½“¯Qý+äOœ–C·È?Jø:D#‰uƒ’ßÄü”Ëß*nóèñk²7Xá!,æÃƒü0ÄV—t–dŒõ z‹ò8]!ê hjåÙ2–(é¡-Hy oðr J˜wšÓiòM, mç| eE+ôW8ÚL}9Å`ìæT¥e¤pS±õ û°¡½‡Ì^†ÂØ·2?‡Lã!yŠÔo± ƒŒãOÍôŠˆ'‰wáM1,‰.ÐÅåûÁC^âéL3ÜŲߠû rŠy[Øý-ôB 9s”d’U71¯™¶}t§l;>†ò@áçÉ¥È&9üS<?Ͼ†“E›aUS!“Dùÿ:%kªr)F©2¢Ðíi kï÷Æx?ëoÇ bØ Íä©ûØx+šŽ¦³çÇ ÷NËóÌôsÍ…nÎL~KCÕoߢǽ¥&èÏ’®¼Ë ‚¨™Fª‹˜•¿üÑAå3Z•òpؼI·lmÍqh×lãÄŽïåÿŠÝ?£´˜CÏsÛ‡Gðsœ?H} á0…¥œ~’%×òêßpó—Øû%šv¢¹Ô^űÿ—«¾„?‰7F®ªéþ+jÞOî± Ä¿AÍŸ“¼—@ºKp3þ߯Ä!¡%•Ñà‰ïëâ/2ü•É—r¼(©4&x(ÌR¼n±Æ'£ÇfQ’N?Ì’süt!¿šbb”Ž–Ž3ÐÉÉ ÜÝÅi“hŒš1&ZŒÊ~Zé\Çz“àI:C„¨=MÏi†nc½D?ËÐy×±ÈGäPÇòÑ›õu^`}“3Föî3 5­%TMÐB¿Ÿ¾B¬…„-Œj¬Æ·uPUØM@„Ы1tàî&§OoˆØ&âûdônõ•ým Ki—׺ÔÊP‡œ9q†üT/{Fi¢$²\ÞIñkŒÀ@6 #†ÈŒ’]G±§ÁQk,¡¤x'cÅ‹(“êe¸‚HÑã´­ ®€À0CŒ ŠŒÐSOÝ]yƲ¼Ÿ“Å”xq:ªhŽs¬”&É8LÆX0Ê£5Ü’ä™0å2Äb‡ÂÜ¢qL'n2ßTὂ3ŽA¿“øwájÌ¥Œ½@f„\}!Én³ ×C+gôCˆÁX‚‚zz.…ÂjVÝ‚—CHêWƒOb€×ÄüÕDb„bÕ @7ÑÀ ðø—°ó×c¦ïm+LqýϘ(=„6sýíz–`rÔÈôöðô‹(…”¬}Åóñ}Ü<š:ã½äR}`Ù Ô­$—E·é>F:Iû®¾›PB§·\¥HOÒq’[~'ÿމÑix²füÔåÆÙ|ê"xñ‹7ƒêm›AÞê—s™'ÅE¹JÎ:Xã¡\Dþ²: rQ¾ƒ/‘MÍÎð^Vn¯Xn9¢ÕÕ([+—ñ£l»–hƒ/óŽ;9êòô}˜ŠÚ&,#;FïQj:ÍÊ›8÷[;ÁÊ÷Ñ·Ë@NÐp=®BÏŒ‘~Ú{ȵ¢ TÅw2ñW”|&I%ZE`'ò[Êzƒ¾R]ïˆoé|j’o¼3G‡$`²"Å)‹–IÎÌÏ2¢S¦q”¶<^9k;Ø=­9òƒœÑP@Åaö4²j˜Á$ù æ2:Âd J)?ÀéyTÍ£¢Á ~%e%DŸâT ÕAì—èZFE ¡ V©Õ”ì¼Âñ2勉NÜÏS›‚8^β7PØD0œ@Ž!_%»†àf‚ â¨q$hƒø¯â*ÄRÌ[±½™|ÏÃÒq©ÍJü³¾m—š§2sFhÔ 8#ø:R"?@X¢LT úÞÃ$èí„Â`@ÚŒ†‘›—££?È`l¥Ð„*¬ûio"´–¢1²éÝLyóÝuDëˆÆ°žäP å¥NÒQK¬²ã´®¢©‹s“Œ\ŦVÔP£ãqfË{ÙWÏÊ<.cIŽŽBêì ph-ç]|Ž)³¨ÐÕ[ÄMY‡lÆMy ãÓLüN7@^‘Ï#+ ¬ÅÍ3r–‰nr —31Œ “L¦ÐJhÚIOM Ð@y¼ömÞõðñ]Ò£È5ë¨X†ò‘’ÂÚ™÷H”B!tŽþ„þ,¸šX=Åu(‰T 7Ïã_æš_G3ˆ”áKŒg‰a†ˆ–¡Áßþ^ù1ããÓhe½ ¹ø˜õó9«JèÍÚú³TöÜÌ“y”pf+rHéã)òjZj—PøáË'Ÿ´W¯¶‹‹µúù¢²B=òCQV‚ ×ßÄÞgY´ˆ}OP×HY'^â#ÄÓ_¥¦Íc^3Á0îÃLjѸ/IA'þšúëÐ\ÊWÐñ ê߃ÓMA3n¥× n+jð*r÷Sô%Ä" o`mQúSˆ{ì÷JÍ›Gø½1þ¾€Ï'Ø­Q­Q>Ê®BnŠs<Äây‰T„†i›ÏÎ éVö,çöüÐÈz‹‚^ú*˜§°ºè QXHÉ0 ;B¬‹a0æS=Lò:—Q[EQã>Úzæõ’î&SF¸žÂ^²˜È¢ÞAÕuT4½Í2ùçÖ×è³ÐcX_¥3…1ÌJÌúó¤;ñwv•a´C¸{q|´FÌ%¢iºx.N!ŸÀѧ¡‰•Joo×Q¿p<€S½èýøútw‚Òá=X5ˆj™GvãÀ±Q5ˆ»àMàåðw“)BýÅc¸ Üç˜xŸ r÷4Éó¤ ¼›©ôñN1j£-§ðÞVªrd[„ü&ê»J3¹„šQF‡é_Æ‚vÎ42¯˜È^YÆÊ$ýÒ@OÑÑĺsÕ&V?“#D°†â ŒFŠ/ÚÏÈêJìeì,¹¨(%èÁC †ÚÛ®Ptÿ*C/“»€üCJÎà&P¯ãN"n"؈yO öãO m@ߊ!C¨a0(iá¡-C»¦Ž1kˆašþÇ„úçø‹YB»À„B¨šyæUÔA%¥P²±T@5<€›À÷ñW¡5¡™¨…_!!ð—c,À˜y/£r#X™ì#½“˜‰ÊªèFŸüo6ÝB.O8Æ ±õVòžÏѬ»š@„¯ý Ö¯dþz„|ö×yäa.Œ`A9囿D°œ™ÝáÅÒŸ‘k¯Õ*+=p}¿äöÛSÏ=—}øáèºu–aè'OÚ;wšF_Ÿ64  _T–sâók©G$ÈÑi^ÆüfNí¢q e‚νø“T6 °hGîcþ&N)¦n ™ x£L¦án²Ç •0¹—†Ï!㨠ÄÑm¤ÿŽðÐC ~Hà h㈔ÇI)6äÔ+¦x–ý¶¢l‚WJøx?ÿXÁÇGÙ«3O'2È‘6Ð^HsŠŒ†åÂ(ƒlJlåØj®y×±B#ÐÍp=u>ÇКS¸g¹Š…)¼q›@”`™Â[Lé9Ò™h p#¥o’|“Ô6Jë ·’=Hv ‘z[ˆ.!x…VDýHÜB¸­]G{ ·õ>e;BT ,´}¨—P1%nB›Ó¾BƒcЇÕô¡A”Ò•¸U'ö¯ð0¯Iu¡ „@vµYÆP>øÈ$<#|ùô¨bB¨ òißÁûáaäaò§ÉÙÈß  Ž¿›ä8ùí„«Ð{È"¹•¨„1÷nêúIž`øj*ðç–Q\޽sM&IذŽú³œë¥ûÖ¼ÁëKh˜ »†y.ñÝ•T&鬢)ÍÙræ±wwŒñ¸¦ÑSÅ“<ÄPf¾AX¨ŸØb‡îÿXyE";FN KÉÆÉ dˆd?H&;½|§aÑoqèëÈ0ñ49—à$ØòY‚1&xìú"?n,Fè£Çèx »€Æ[ÑM‚¥h&B¡†ÍÔlwåqúÛd‡§™ˆò)]EÙz¤ÿ ®”Îà^âg¦ëƒ "óYô‘IHâ9—ª&Ù”d¼î]¬ø$ÑZ¤çLŸaÏMpø[Îgù‡ð\Ðð=ö#ʺ_A 0ˆ0ÔF¨˜êåx'ÏK_gÛ'° @g¼Ÿþs,¹Ï'›¡õu–mCèä]½Äú(Ô$G÷±r ž{„|×cl‚{¸îv\Ÿ¯ý%ïþ¥•<ôcuÛ»„ä}÷ªkw¨†F÷\» ihp:;•¦™W]åkZì£ýùÕ¥2?øÿÄÕ«ý¯ÝØÚÝïU#ý">Âø;®§ë n–ºZ¯äÈ ´ïç†÷3t–ì ×0),£÷ LˆŸfËo‘íÇŸ$ÓI¦¦»H¡bã{¨¼-G°†ÑVbaøˆý6Ù/؆™QÖí¨/úz£Te¾hÊÓepCœo†øD†vIÐbý0?)áýçù^9wŒrÚ¤2@MœµtÑ4ÈùRš]äCÅÔE)9ÊÑå¬må\1ÂûhÝÀ²0á7驤¸„—è\AM„ÀI&ØQ}䎑ØDe=Ñ3dv¿‹êæ3ÄO㽟’b¬]¤†Q_¥b +¬‘ØÌ¢ý1#Èq8¦H ífôF´ƒ(M‰cJL*6 ®ÖÈIZy‰»<Œ™ƒ6å‚Xø @*Ú%9ÈÈŸ·!¼|Oh Œ™öÐye»‚—bü8 ÞM¸fÚ?ÁwH´#c‡ñÓÄZ¨¾|H|„Ž&.oÎ ‘é¿$´¿õ¾”„k±K/=T ßC¤Â£ùq.üסl=ÂÆ.&2ßEÀwiÿùIÊ7R¶%‘#Â]¢;§»V´ ‡î§r v”h- ›äÜ–ÞŒã LÎî!£f9JðÆÏP‚úuDËÉç9ñ2‹·a…˜LÒqœ†DJíà `G¡õëw€Áspó]x‚±1 ƒ@˜±  URªV®¢¡AI) ´ŠŠ‹À$Ä?WL•Âqxòqö¼(pX±‚C»Y±šx?¸˜£gYµEk8ù"äð'™·„Éóxqê7$Û…Õ«ÈõP±†á')ß2}/Ü@zÁ ò©ü¹ç14ìÁ¸÷ªÐo µ³Úëâw³êGJ”zD-“ˆðÞ{E’È(oVñÞ N·Ð˜Á#ß¼V†»˜\Fmç,©­Ô ’=Kz!%6Æ$R¢-¡ð$™#d o"ú™S¸;ˆ68Hî8r#vúìk®°þŽ‹¡ý6î”Y‰ˆ¡ЇgŸÊ‘¢HaÀ^Ÿ<¤b­`»§+B3`4$ùÛ,ƬŒ Ÿ‰à¨_À³Ä4«z6G«?3bFLo³XgÓ*¦+8©Øí#56éÜ¡« „Òø¾bHWËánˆ#óBý^ïnŒr8„s§õ^ìgÉ _€v#¡—Iœ#S ¿BÉßÓÛ‚u5Ï3$³šÂNÆvP9HòÝïgé3o¡¨‘¢ý¿•uû8,I×SÄH1šf ’²ji§Õ clææ!7Ac¸šíAªs<6ظ#z€õš·ÿ×qºHýŒ¼IVáødÔe®_®NÚÇGG˜§ñ*Ö£ëØa:'ÝÂwcXBð8÷¤.[Lõuè!4 t ¡“8F÷ÐL4EÅ;ˆ4O_=ŒÐ¯¨ë-J–—zµiÿ„‰UFÓ'&¾3Ó÷ pSäÆèø"Ä¢Ob•àåQà¦ØOß>6ý Jà{HAßkt¼ÈÆÏcDP‚Ì8Ç~ˆ2ØôÛ¸9œçv*¥fžÏÙÝ”·P\ç“˲ë>®ÿ Jàz¼ønþ ŽË™ÃHŸE›îçÀsÜ|Ùé4…%8.Ãà ô²y'yºFn¾ó‹+üFÞJ·¦?ØßÃcÿDißüÍ ± 4—5Wsz½‡yÏÿ¤ë …QZŸbí„" ¥~¸ ú¥þF¼aæßÁ™? |%[˜ÜCÙ;˜|â»È™à´"dEOTóΓü¸[{iPcRœd"Je7]U4wÐQGK÷'±´’Šƒ´­aéqºj¨° >ÇÙ,±°2\K¬„ð“ôm¥ÊÀ8ÊdVù䯣´àqœçÈ|Šâú£d#“hý)ò£èZ7}fý_¶ùòË1„8¡ÈÀb°HxÝÇ€AX ƒ®Ð'9ï£A¡ YŸYžgZd.f³ûô_´+ÓúæBƒ²·ÙÒO)ž}’Á ¥B£Q1­/œ”d+4" i8޲ÁƒSÈ,r¢‘Eµâ.Ä(€²§ TŽ·žÈn/™"LV`au‘(À4Ã$—P>Æä$é:J;èm "ÉäÔ© ¡1J(óÈzd‹¨p˜Ì2lbØ„LB9º5ò_G™D5LÅ9ƒ*hÊžƒÔPª )ñ&ñR—õþ˜¥d“xyeÖƒ цU„U€MÇ$~špÁò™þ#¡‘&ÕN¤36«^¦M+PRí¸£ÓÄ*Ü‚æÊoÏ‹Âdê 23=R¸äj¤ é^~ÅÉ3(Ÿâ5È)ázfÊÔèA" Dæãå¦?âfqâ4àåQ ¡‘ì!R…nã¹(Éð)"UD*ñ=}hÕH4º³`3Nסû-[Èçð=âÔաm‡X|ù<Ù]m,Þ€ïQ»àçÀÍ¿3Þò÷œ?ÅØ†ÆX7uWÓu˜ù«i£¢…Ñ6pˆ”£ ç3q’âŤ:°Â˜Q¬(îÎyu—À²¯hFÆ1«a-RiaŰRB‰|&e.# M¢LjÒ´iÎ1jRâ’Ó°ÁÈS1Jw1uc Y„uÌ1&æQ×EO 5 ­Ñ Š'ɇ ø¨^’6ÖDÅB’§h¸‘žŸQ¶Œ¢T_OñUhFfÑÜ—ûŸ‘FùYœQÒçIvÑóÏâ”mçð#—˜”3sÐÚ½°²—íý‚5cî"gÙ.Ìv²ºÜF9x >ûYã… vìH=ô ?ð€±i“©TxÇŽÉp8÷ì³Â÷I§u¥D.ç?õ”ê‘GÅÔðâ pã-<ñ}nz/>DY”‹“BSt¼ÆúÛyý~6ˆÖŸ’¦g€p„–»è{Œ€Mâ(åäÕíTm!ÛJå äÛLt-¥¿1Çúÿ‹…'þBF34Êæo²ü7®ŒaÝ{7Mkk§¼™7¿K¬†¦ké~‰p9‹yã/Yx+Þ8eKhý+>MÿC7C¿Ÿ²$_ hÎ),] Å)|7f9íˆôz…+D—ÍÅR‚¹¬ú7s¨i4¡FP9ŽL’úGœK)eÄ IDATqÆBÆ ©ìôl_wFš"PÞ,·aw–Pu‘[9Ô í²£d}š–Êëoðî»OÝ~{îôimùòä“O†>õ©É—^òMsòÍ75kü¶6zz‚ª¨ÖÖÚccÖÎô'ÂaébT–U+yð;Ä@ÁÕW!Vmáüa.ìcùÕ G&(«!ÓÇ¢¨IlƒÑ×1 —a¸¤©Àé£|#~'EkýD7‘üÑÕ„×`ü ZBW„„(˜K–ÿˆôTb:AQ(¡†AÃë&‚ô.² ?IÆ qð èNòѰáCWưšW!³'àª{È ¢¹4_Ã…Ÿ\϶/1º—Â&d’º-‡ÊmÈô ®DØ6ºÄÔ0 Ñ$Œ‘цRÞ…õ§R¼ X×ø¤5–¬¯[x<©‰¬P¿šü.òc8.ª‚ì ð#hÙiö4ÛÊXÍòÚ“³Œö.’©)ü‡ŠÇâ}wqê$+ÖãJq¡Ó´ é8–i*× :Ž“àº´çy^ðxÐ 3푬мYnÃÎ,WtwF/wg«ÜåŠUv–ñTA0¡Rê× Y,߯ßÿÿc^z)8~œH)ñŸûê™T*íœ8!¾ð…ìw¿+KJ!¬«¯žxî¹À–-ñ¿þë R°!XXh%ÆG>¤B–xs?çZ‰‚DÀ"àÇþí¯0¨¨£õÂ4=!1`ÍÇ9w?!K¡;ƒ6â´c8”lA÷‘g‰®Ç{#¥Ü…ø ög•¸ßw8¼êQà¢\º >%+ÆÇšN…4/·Ã›ƒ³’¦Õ'I{§’÷s¼’ÛÀòñËXc¾Ílê¿!„ýÜÿòmyÆ4ŒQž4H¡& qÁfĤ3LÖÊ çÑÒ‚$*‰¸Ø§—æRY¬¢t-;p6ºFÏ.VŒå¹2À:ò¿p†8ûMVü.vƒOS¼‚P9~ #ˆ.ÀA <4Ý ·]'¸¿÷0‘÷áŸÀýáã߯ìåB·”qX‰/ºêGôÁ†<{› ¶Oð “-yƲ ˜4çÉãYìâ%éÔ¨¨æCìË’ªdû Ç&è5)ªa“D—hf¶X€¥Íhª¡—=ý×^’_Ê›‡ÜÅ÷ûø>î”åC†‰Nöh(mˆýI:bT¤9W@e˜âIäm©"6fÙo’¶pu|“¼‰o±ºò4o†@]dX¹™Ÿs³Ô+w–D5ý¼ ©Øþ;Šewðòlÿžfõ¼ðCJ磇i¹ŠÖ7 i­Ç¨i&Aé=Н©UëÈ8²³ÓM&åÂ…ù³g]ÓLîÝ[ðñO~ûÛv6;G˜úŒuó†i츅x?ºËšít¤ãeV\‹á‘í'7„žÅ6Ðò—ÐmÃpþ[h“˜.Ô¾ç ¦$v=ÞKX l ÓÁ\ŠyA¦Tësâ%Ïd¸ßàWó´;dlnáïUy&%…ÅÜÙÇ£’h×E°Õÿª+ÝÃ@œ$`b\œz1eÞ #ºéaÈB( "ÔÁqa B{9¥á¨f#kÎó²‰*£1Ë$ËYç°SDƒÏ¨d4B‰O¯IÎ@xŽoâX8Ó¿J©œSÏü,äºÈ¤.öUM¡Xoe¨•ÂTla¢›p£ˆÖ($VKW+õkÙÿ4%õ$&—‘H`Òz’Ek!ïÓÓÇâ5*žy×-(ð’IGÓœ¡!ššüLÆñÅÀ ²t„=C¬°x½g¦‰Uìò¥ƒ h\Cºƒp”X)“'þty± ˜`òMŒŸéêÃRXßåUƒ.I2Øœâ Áª0;Fy&Eß<>×Ã>F9·px‚Ž…|²‹Wô…¨­a[?'Féµ(ndK;¯ÇIS[ÏšVŽ2 ö26†)fè$Çu‚ £™…eTN?ÄQ…¦:¶„Á5,Ó0@‘<À v™sâÛ5¿K~ÔrKÊ(ÖáuŽæÈ*|…§¡Rá-fa!Ñ“U¸:2JxÚ8’dr¹±‡cqút|œŽŽk¡ òù)`2pt¤‰gNS*w žL\ßÂ1q åY8ú”“gþmŠÕfåur>¾M&Oí9ÿ$+ÿ„7þŒÊx>v³î÷yéË\û§{”ªÕäÂaê6rzšÍë/sײç§\óa^} ;D{ïý-þú ¬ØŠ°Øx-ö%Õ´TDbî‰Srá¼RÚµ×&ï½—åË]»‚L¿±Úà =ƒJö¬  9ëñ"›‚¡ºUT¯§ó°|ÌÙË[Çô1¡ø, g„¶¢ ·a LÛÓò.!ÍEs‰:(ÛE¸X>º‹eP«Q3ÆQˆäñ<ÌbÖqÚEk掣<ªT±j®,ž‡XÏíoòj𼇶™^ây€‡˜Oc€ðqÎHt‰ÚÄš'xUÇöÑ|Ô©ñM…¢‰ò%ÓÞ›³rí„ák—^ŸŽ<ÞÚr8rÆËEµÒ9@¿Ž§#§’*ˆ «ãpƒ8n¬…cãØä¦R.HöbŽ©\[8¦t…‹r¹Y{ Íî N¥¹dRçêä¡i+-ï`ï—ØöÇh \tl/‚ÅŒîbý½”¬»2À:ýJ‰?FÅ=¤_EQ¸¿ ÷…wÁ¤0ç£ œcß®4O°}z”¡ÍClðò9¦©uRû¤]l…€CŽ‚òÛz†&iSh6Ërd'9]ÈŽ £#œˆ²Ô¦²‡}1V˜ÄŒùÈMR9r}tV±TÞ$ÙOo‹æpûéM’.¤t> Rä$ 1:JB"æQSI…‚$Ðòx] úÓ BC70–Rob¨·f…Ò½Œô2¢!Ê@©P¿‘ ÃB `Ÿ£#CÊBW¸aì*“Œ'×ðÁ©¡v˜ (ò%”¤Ñ‘Nõã´[PFã' òó¸:ÉAH\Ä)ÏÄ1ð¦ÒÅÀ³pM×’Þ´ïðEœÊÍä ¼×Ã×(ÚÎЋ¨0Ù—Ú÷2t-L¤‰sÏÒx;'þ‰šíô…(ãÝDꘜ j9ʤ¯“Ñ>´0ÊBÁD‚`É ô0žÀŠÐ?ˆ@ê C=—O&ÝM›üÑQ'®+÷í Íà’fÏVàrÀ ̨ZqÊžõëºP»žø³Þi)Cö_¯¢wá>2q(k“'öûÔ;˜ƒ‚­iŽšó$” 2ËDãÊ£blâh9×r&E:‚8ƒ."D…‡6AÜG/¦¶ŸAÀC+§¡‡ní¢jiˆ“!®aúPHQEgéè>B¡¹ÈjJ (8ÁЦÐJ!|”‡¸Üý²_gêÔŒÖHqÉñQMýÑñ5ü)?2ñ-¤†šZðt|iá[ø&žŽoàéxSH¤!-\WÇ·p¦Ϛνi.o“·¦ÖHáX8¦ôD~–¶à¼­Œ“Ÿ¬iõJ]@´†Æ-äGQ*Vpþ ª1 R'húU†§p †AÙ TÝqe€Õÿ¿ñ'°Â ý•ŸG¤Éí!r3†Dyè¶òžF#f½ÒxBhJ7<¾'¸]RæqX¡ ÖJÌ4ß ñ1‰ï#'ø~¿æ#FŽ<=®’ °“Õ X˜e°ç VÃmƒ‹sA#fS9FW˜:‹X­´)iaK+oŒ/aÞBÖœäÈ0£`8ÈÜÒOÿQN L‰æ¢näZmt¥[`€&Ð$(D9Åkhž"ðîNåpÞÊå/¢vµ_C;ÏÀiÎð ©!%þ–‡±÷òº  4ü%,ìàÓf¡Î6Þ±ŸÇ-ô(rªû8f‚‰«! ¼‹ð¤áYx&žŽ7ŧŒéìq/–câX¸š§¦«99Eì/ÈÆ x žÇècÄÞE÷W¨ú<}? ä²ã´ŸŠ DZ¥Œ÷±à]¼ù=Ö}Ž=_ãÃÏ>Ǻ3ØA*Eûaîú ‡Ÿ#ëฬ»•ï|…wš¯vØs€Ïý!§O22¯#‘š™yáí3ŸÉ8á¡išØµk ‘ qqKhÏS`†d™³`+0‹F]Ä5ó"±bz3hAéü6Dß4¨Y`@ ”àg_Vž¦»˜¦‡í¡¹ØºƒåczÓE—˜e¼§—§4]¢{X>º‡îcøÂÇ0‰Ú”3ä¡jY2Êx‚IQOSœÉ1â>ºD ®¢ò4 ‰¦QM¹‰ÑÎ@WšziÊV[ÎøkϬ–j6ÝH…Ð.ᔚ²®ÕñÅ´w£È©TÔñ5ÔxM¥ÖÔ“:Ò˜/_ÿ˜rSkáÌêè^¤ó:þ4NáÛä,åZ"o)G÷•Ê#ò³Žš:3õœÙ“†Ò3€•h‚…×Q·•žgh¼‘ý”®$AS°t|;ÈèS® æ¢WȰú~—ü\‡HƒÄˆ!úÆB¼‡1Ê1·*ñŠÔâBÜå«Ç”ˆÀŸËK’BƒMyŽ*4ƒU 3ÉS‚š Ë%Ï»PÌ >*K_’Ž2¶O‘ç$íi&lŠ‹XæâŒrÒGx¨Z6vsDa¤IÐUD}„йnÎU°0@a’DýZšÀÇ8é#æQ£X‚@?J›œöÕV³P!ü™u,AæÃ3¨¤¿@: ñ%þT&•SXC±Bˆ3\pq¬éеЖ°`€ã&ÊÇYLËYNÐu¤$[Gý]®†k€9+ô™¼Ñ‘SI£ÏdÏE†e‘5I›6 ‹¥†Z€÷¸ò¯¾†ŸG[‰XÊäýhu¨"²§ðCÈÁmÓ¾b}š7’¼wœ·4 ›EÒÚ¡ÓÇd˜µHEhg Dù`ˆ„Ø1jÁ™bÆ`id€0Hƒ Q!,gÙy®id­¤Äª'5ĴĪp+ÊUÖ"DU@h ¥× Lðu,ˆô"w£2&ºÓØsZÔòÎP¬ðxÚˆ|-ˆ°T³ØÅÍrÐæŽž$éС£†%oòÃFV7°Óy®ÆÙà¥y»‘{Cô,—óLA´‘M!ÖÇ"´&h3ØƦ¹ÒÈš(©9SÀUDèŠQ+q†è›eZm ½Ö-㌌1V”„Fú¸YLÓä).)l°ö GˆÌ’?Ç€FÚXé¡54‘j£^CœÈ¿ ´pñ z’ÙQfd‘~Ϻ€ÀAvP7˜E(Àà[«LÑ ^ŠÇ]‘Ÿ[%M¡¸Ÿ|A6³2Í> ¯mšqÍt‚$1É\‚†|ÀqÅXœûs³\n`»Æ\äÇËù„O„i®4²Ö †9ãã-bK€Ñˆ gd¿æâk„ œj¦½ž–°TC"úè»Èåûy/ˆ°T["´@àÌÓ!âv6ʼnÅïr _åpXÚR#Axè‡¸ÅÆºÌø úÊG¿3`!0 !Ëi^EçOx3†%Ñ€"šÒ.1åíR½{´$TøE8³ð$E¨0߯OR»šûÙ3Ãé^>m!Îó­-¼×"r¿íæ7$aš_ØÔձÞäÿoäÓ/‡¨ã?y|_q-Êg`¿4Ie6àÿ7ô]°†¹¿'þ×L}‰š?gî5ˆbßÂÈWiü"ÏÜŠoÈ ãô0ð3T'‰¥Øí àÊËDºI.%—¥ÿ$©ÄÛ(¸¸M«yêùØŸrl¾`ÅÍ<þ?YÔ˱Ã%ÿÄ4|éÿá›ßÔ+×úRæ^{M=ú¨ûØc²Œ$UV²ªqªIñ*À²Ë+òü¿ XœŠÌ–± …r±C,Çðl[£<ì2rÙËGØA °¬ 0±,,}ªOÅ….ÝÊÊ P¦ °*k]Xæ_C«*òeŠ2VE0•eÅJ”ÃÀ2l…Ѫxù”(FÆ„e©A[ø6U| ?RI‹ ƒ5®-<ÛøÒ7Â/[«¼²2åVåþ*Í<² #lùmÈd¨ídb/÷pù«¬þwLþ+AjÞEš?ÀàŸ°ø¯È>‡•"±á¢H£÷Ró ¬ÿ:`úk†§Hñ€Ë3[²ËcLÐ$s¼`s›!2Ã[q¶ Zò£QVbCšå…Ë¢,Ïód”M‚¬à¸Å2i„»ŸáÓ"Ìa–àŽ@+Á,õd/c­${ÑD’ŸAG(°[ñ ˆS—QõDšÈ(d 2EÞ%?‡¯Ð‚Ì*ÉþWY»“P1¦¹‡™Y|QªFÔ6?k¶ôŠk#~ ý+ôÉ“ö{ß+ï¹c½{íÕÕ>CÄÊ6÷X•²î”ÓˆÎB ¾¢a9 %-»¼vÊXfUÝ:à`$.N(T°B¬2NÙ>–µXYEx °Cd€¥Kê»ZXV¤”FŸ—±©ø\ñ«üÊ­)ƒ”y—B5·’eVUT©ŠàUA+‹  [ZTIìEaA¢+Y¢hU–Õ‹ «bVœR6Ðà:Æs„ç_…S@T$ªŠ¬^¡T˜´m¦~)훘:Lû6Ò‡hÚL0ŽÎR»‚©—h¾÷"N-"ƒ™#¹™Ç¨ûþ^,»ŽboF¥¼WXŸx Ëà‹OÖx.ß·ù¼ êÌðLø3ìsX)i›b=·i¬)NÚÔGé “œW$kX"ÏñJ/¸ÞIÞØÂû.ưna™(~Öë gòä¶³BËFœçÒ;Ø. l ñ"OÞÊÎ(v„È'ym;p°®rxŒ³›y(Fä?¬£¡‡b§ùöJ±`Œ—’-láqEØÊC9öºéà3ü(Jw„X'Üå˜ øÇ(Ÿ¼$õ6üÃÆ¬aÿ$ê~¦ÿ?ÄÔßáì ¤_ÇÚC–< IDAT´¦ö>òcÔßͱ?£æZï =Hú2:NÃF^úK–ìÄ—`1x‘lÛ>Ã/þ†»8s˜»>Í•óLÏâAhÈܼ‹Ç¿G×*cd°{·úÒ¿:Ôÿå¿`YH!‚@hSôìÎÓ«j†« #å¯qª˜TµènWáW§*¼‰ ,%C,¯XÊ+E‚¶̃”`yØEåãe2UM¯n`X²rkF‚zž^Uü Ò€©zrl•·œ¥\³®Ž«YU•讋Y¿"ɪJ –u5oe˜OV\2N9ŒàÚÆ·…ïà©@ÝU¦Pe³*T¡UEÃÊÀŽÿŒž!ÞÌØ^ÇbòeÖü!þ#K?Oömj7`G)%uùW©½ï ⻓è3DïÅš24 5gxu³àÓFlï&$ÌòÇ>—$;²OP7ÇA›Í]#ü ÉmÝ“†ú:6\æ –ÖÒ;Ì!E²‘^æl„Ú:Ñã¼ÒAo ’Øa^[Φ(I=Àà8Ó½¬-J±¹,qbÄꩳpF˜% ÑC«9Cá0Wë©Iw°ÛI……R¨Ý\(†ˆR58‘Än%Q¡Ü¦èå½Ñ–gnˆþÂòF º3E~š9‰©!²•Å6„¼Qf z˜IMpKšH†i2ãLO0µœöE´äÉM05Á¸ÏÜìºÊŸü#µ$Ö²ñç<2õ4¶Ñ5À™9Ör—Of„Ã9FÖñЧC&jéÖd}†›¹9KŸf0N§ÂÊñRÀ¬a Š€×-¦m¶(ÎISg ©L(B›à‚áQx ±wQKö*Z"!»É]#{`ö2µwbö*s3¤zq¦ÇhXÇ…WI.E&±êÑ—Ѱœ£{¨ëâÄ9bQt;…'°Ùs‚µË˜‡{îÁ÷ ˆÖ6–¯À˜bßD#âï¿J"Âô¹‰yU«avù5^ TµÑ´:iX X•ØÐÂØ!20¶+"aIêVIº*FˆA™a•!LÊh,,Γ ËôªÈ§ÊX×ÃÓôJ,p3˜2ÃÒe3eã‚®,‹ ,Z•’€Å/X(W¹UX‰‹êUÑ]ÁµLà?‚kiß 5ÆET'ݪNÙ³B4ô~œ™£¬ú8—¿Ïâ÷áP¿+Ä› vn?ñE¸'H¬Ç ‚À¶1—‰ÝAá«$~ϘƒBŽçNÌwŒzT ²ù¬dã»Ò°æx¬À…I~ÙÌïñD”õ+&x3Â’Kf¸ !Iož¹®4rÓ,cYfÛX—'{”›XÕÍÆAúFÝÀí>zA‰j¥;„s\fz3â$äëj¡e-=>:‡?N¶‰šâä 4â9Noci'µ>hdÐ%œÅßÏð,j%–ä*"‡ïab˜Üa&‹U€ßbyXz—¼ãGqgD_ãB¤ ^â>ºBŒÀDQAÌëô“i!²‰v‰IbÛˆ(ò¼mcVÓ²„Æ(Vëç¼UKt‹SD£XOòÊ6İ’Äg™:Ìl·Qý\æÒVv&‰¿ÅÓ ¤V²%Nâ0?îånkœãõ,Ž“¸ÊÏ»yƒ3Ë¡8­jÆø~·FH† ¦Ø9ËWêø”f¿Eƒm:øoóólGÏÞŒŸ‡º…ü>D/£ÿ@ýï“~ÝÄätþ[¦Ž0öm¿ÆÌ5òYFNÓy?éA¦Æ±ë©[ƒˆ°ï‡´ÝLO°ãSôŸg*C!À ÈøÜz/¿x‚–%$R,ê.ýîG‡xþi„œÿS(‰€\–âP‰2BU ª:$¬hðñ*>å,¤WÕê{%f´ÀÆØ„Jø&ÌdžÊÇJ$«xkc@¯L¯ª¸•Uªj†UæYB—V1H4¥Êk•›A¾“lZ¤Te³•®&V•EYÕƒUE3­2Ê’Ð*¥µƒ'KvP¯â•±ð#Æu„Á³L |S ýJ®…JC´ëšeWœë·ÿþî;Q"‚¹ý´¾ŸÑ¯Ñõ²¯£B›˜ù Íÿ÷Y¢—iý ÐýE# š:-‚ß³¸Ý#åý1Þ]ñó_°XM.mV¥9¨htX>Ê[q'X<ÎYƒSò ®¢5´M2Z ׯJA|ŒÁ9r,Ïá3§®™–>®iT„x ÍušË´$‰ ì~Ò#¤;ij )Por%K¸”¦&’ ‰ý6ÃCÌ-§ÑÁ©ÅIákC#x DzH…Äj"¢K¬«dG#‚ú.—ÕüÉö+Ï´ÒïÁ'ü K}4%¡Ýx„Å×\Q˜ýŒ[˜Ûim#.1!á…þ5fÆ™ý8½`¦ÈÎ’}Œ«æ&ŒôUÆòÌ=È-ýŒyäúª#~3kûéÏ2SOª‹ö!®Žsu3;|²×81ËÐ-Ü•ƒ9F—°)Ã@–K«yÿ ²œ®eIŒº'Ø–ç "gµÏ‘ ×l¢–á•¿ §xÈÒ' &‚f ÐÏ…rWˆ=ÈÄψlÆ›%²þ'°—’XMÿ‹Àî&ÚÍÀ~ì&|ÃÀq&Æ™…;>ÇÙ7ñÝ›yê1Z–©%oð Úâµ#twM±õ6<&dÍ&lëKPÂïý-)‡©AdažjUM#U†ÒØ «¡nŒ # ´’>–o좤U6‘–ÖEy« OVxƒzU$_¡ËVˆQ~XB¥"fUƒ”.ÏZ¿Î„uZUç+ôJ¢Å8Éø#ݬÉáçðvîÍÌ™$½œ•SÌfðF™ÚÀê)².:‹×I‹†S _dêa6ˆ<áùƒŒ|‚Þ9L3x§I÷1÷YVç0f߃>²WÈÿ–¸hB¤K˜&ˆAÜãd%¢ç#4US*ô0šaD°0viW 0O29‹/A`êQ[H÷PÑ¢‘Ý‚¯ÓçÀzRmD°“XÜ'é[K] î!õ¿8^‡½–‘$Ö5ÆlTÙH2Íì>NÜÎÚÎUú¯qíV64R³›W뉭¥·ÓÆ6sÇý“\\ÉÍ™~ö¬åþC3 ,¾ÆSíl©¡eŽc5,Ës°†u‚tÝ Ö„Ó§cæ#J&f™åÆÿ…5^Ö?ëáÛØ·âŽ3s€° ¹˜äf&âæ>DÎÐr;¢×Ãõ‰-‚¯þ#]7ãÎâ®/på“i´–ÌlÜÉó¿à¶{çëÍm›Ÿ|ǙǩÏ%ÒÓå­x•’«³¬w®=t ðÎÂu1iè€Â%ÌòˆTáTɯKAb‘jÙeË‘Eã‚Fùe{€Uv3T²Õž>Yq0Ta–¼Qލö1¨R‹ÅJÇà6Ö¬IæFɬ¢Ô FÛ¨“ÈZöO8»EV’ˆƒýmNo£#A¤žˆBE±¿Î¥ Ô·­Ç±)PߤßBÝDª;Šª+eú„BÄáL”ûÌ”œŸÛIÔ¼³‹]`ð’·Ê>ó0 µ(YŽ}Â,a† Kø63|žÅ!Ú#œÄ;IzŒ\-ò#t»ä}‚Ý\û k<ÂIæ,8ÀÕ%¤ÚI¹N3ØDd'ËÏ3xŽ+7ѳ„–OqúîÊæJ]àq5N´¶Q.IÜv–žãùf:èá­^>ÒÏ/!ÝÊÍy.F©‰Q“ãp=ÛŽÇXc8¡G2&•&íˆÓR? Œ4~\x§a%þa+Ù7ÑX=Œ=‡êaæÑÍ>:It 'ÿOcjI.eè³nùg÷à ÝÌ/¿IËrœ:‡˜œÄ• å¹sKV–Þž -DcÄâ dC¾ó"yñ ÆûQ.…ib ë¥2~Ù7ÔF‰V•9Þ©riY-E(,ߨ¾(ÊX¶uÃ’ÅH0Àª„!VXbXª RIVÌVÕ–™—ME0Xä)¦Yh¶ªÖ׋ºUQÆR%`ÒnU¬å*uEx*†„®2¡c<჋ñÖ U]*šz!ÚŲûˆÚˆ€é#,}?ÙˣİäŽÐ¼‹ñÇXüï'aÿ0É›q_!y'"cäe}˜à?›È†¢6Ä÷è·øh†o8|Ì圡ÓaÍ?²>DÕrs3¿+À:Ÿb‚ø8gqï,ci&ÛÙ0ÇìyŽmâ=ÓL0ÚÚ,…Ã_Ë:‰s‚¾¬ W!{ k ò .ÞÇz=Fá0#<Èê‹ÌÌàK¬õ4äá¹QÜQüûh9Œ;‡>ÌÜÍÔ­ ^€ ‚YÂcä3°™Äb.€ÁÏaÆÏà‡°†è]D¡ÅêºrU"ð0ÿ‚;´Ù‚e0”áæ gqt7ÖR,Ùí˜~ /2‡ÄÛ±Qy‚'¡×‘L"×QóúR¨^’f 5sf+-qd'‰i²{¹¸‹%m¤Žsù£ÛX2AzŒñe´¶Q{–ó]´4R3Ũ¦`ð'¹ºœ•u4 sªžúqÎ:˹'͉(‘↦ 'éõ¸g‰áB”NIF0,ÈØf "n’Æþ^6‰p¡OúÇØ;ð-ä"¦^!h È1ÓOj'A»“ÑCXÍdsd¦H¬€(ûDë&|Ã…cìø,ýçIÏ¢jP1r!]ËI$™‚³‡H-ˆÈS <ô9‚àWK‹”B*žý.'•ÚÎÔTÕîTÛ ¬ªRžêzéëBÂj—ƒBˆÆ>V`,_ýY–SÄ);,TÉ;Z„­¢¸^N – E%«È§Ìו,s«âH SV×0›ªaE«ª”ã\ç -bVyVçolïaãÛ:¡Á/{©¼*‚[յʭêé˜\J÷.¦Ž²êA2WP>s§é¼›X=ùK£$Ûñ.R·é[ÊÌcÔ=‚ÿñ­ˆËX-ÈŒQcBmBÖj¡4-š3aD[@n†ŸÖð¹ {݆X†“u<”æp”e-Ü[ó.VÏ_e_”vE<ÃtŠ®ff˜ic…Á>ÆÛkØ’Ã?Ä‰ÛØn;Å¥.:’¤žçðÖÙ89ÌiF—ÓROò1޶P·.LJ·™¸™<ÎÌ›¤¢³‘ˆAÎaž`ìC´DQé ^aöùOÑä „BÄ[äâ~‚” Q‹THˆøÏP°Àv"+‘á xÞùd«Þ:„»ñF ï%º[–ö“%Tp÷y Óƒz˜Ú=‰zàÓ´è)<àg ý>KÂ4ÞƧÈþ6+‡Èp2Ô‚³•¶qfre]­$3Ìi‚:¢3Ìœçâ&VÄP8¸”Ž&jrd–±ô/Ù˜U¬OÓ×Éšcý¼ÞΊ}õ,®gñ?kåöY^¨¥·À¡+4'n’UŠÁÁÒ2i‹"Áìaf¹•±—Éûd43ÝGE[Œœ%S`óïpþ5 ‚î­üôï°$¾EÞà|ƒcóÈ\”"YO$‚¥&Å?Åì$?ù›ë%­ë0KkÞóët­ÀH.aÿÓ$l¢à§qô<·ºŽaÅÊÕ…ö eÒÖBü²Ê½·¡’J éc¥P±È³”méuÉA]º] Vó¬²/´Ú5zýyY%W-ð4¨²S¡’¬ª e•Ä^ô…[)”Ëømá•Ê~uÚ\ÕT·â¥“¸†­ŸçüèÚFû&‚)&öÒq;ñzÂ,cÿDûûIm@9E_òˆÔà½Nò}Ƽ-¢÷Á8ªÞH_‹¼ËO$u9£ am>›í†zŸQA[š·clpÉydÚÇ9ÝËoÕ³æ]Ö>¾£y”¡6zÆ›b²ƒYÜK\ÛÌÍÜ‹\ëbQ”äQ.nd¥‡9ÅH ¤Ž2¤°×Ó>w™lÉf’ÓøÇH¯£¾†È(þkL×ãì¢É Ï“ÛO®—Äj<ÄIòç BäûIÚ(Çp¯ §ÐmXõ‘!âž@æà4ÆC|;ŽDÑž,Ž’YðøÅ¥ 9“‚T#1BÌ/ð'Ð} J`š‘=( x–\ ³ˬ–˜b&†^‰“Äl%ùMFj˱—«E=Æ•¤!æãˉµ˜# /%Ñ€3ÁL §'K.O¾[À4SõDFN¢nbÃÛì]D[މãÝôŒs±™–j³ ÕÑæX=‹sœKÒП¤^3XÇVÃEDp1B\2íP¯–AÄx–{.‘›!ð™í#ö ù>è$W`urõI¬Å\¼€Ø L„c?£ažáÊInþ4»¿Iæ|Ví`ÉZê9weáç¹z’bæË„ÜùëÔ4–Ú¥¨*´ h½`#FƒJeB"mÎpèiÆ…š…¥<öÂòéj†U íª…= F*¥Q¾±aidÙP:Ÿ%¬ˆV•ÒœêŠa)-¨t`U[Û¯;&« ›u™Oi±ÀÈ^Ò°ª|¡%¹½Ø¦ªÑB ÂPh#üª´~¥ºîÊWÖd m)©V–ÝÍøZV‘½FMþ ‰6Ì4uë™~–æ;ðúyü“ÔÞ‹>£p#NÙe¤Ö„‘wúây!>àšBÜãs>$m9ÎÛôÎp²–;§9nˆEYÝÏËKøÈWg‰ÓÝÍmmïÒÖð*ßÉ’ocÕA^ÝÀ>æW{Xî–=·³M`Ÿ¢15$Æá›èi§q7W×ÐÚHÍ%f2~=µD^`d ó õ ÆfпN§ÂÄ»€»‰då`"¿ŸÂCÔF‘5Xs˜ï0·…è*ì$R A\Fÿ;ÖMX/)åÂBþÁ¬1é#E´Tå_Ô¼³™¸ºßcv~\V1]h~ŒI£¥0 ó¨v„ÂL`„1–0Oãõ®€ ÑBy†\àw¨ÍÂo1ñÓ`²ø/3=Nþ÷éLãïa¼kõ¼ÿÅÅ^RÛi ~Êé´µÝÏ¥ÅÔ®¤ùEÞ^FÓrZ¯rm‹&9ÏÉ{¹kˆ 6ª“®S¼¼‰;8ù‘iŽ®ãCC¼²˜³nd}£)ÖLðµ:z%sInóøI>£8.MÔæEá < Å"wè§ü¯˜$¹,À¹‰‘C´~„ô%ü(Æâü\°’Ìæ(€‰1žeËÃŒ¡bœÙËm¦¾ aˆ¥Ë.½?-‹g¾ÊÌ(å‚òÒ%Û>F²©JÂ’üò¯°môü´¦ç&nû5t€;Æã_"á`ƒÌÑ p꺼¡µP€¯P­2Ã*!—° X*æ9Wˆ DžŠ–ÒˆEÉÖPQ¬JÁ`µ¡¡ú°¬<©®ÝÕ¼nµ@´ª¦W•  E`™@Z&Å2ƒ&@øåö³•ÖØ•ÎŽ¹*´*†& Æã¾/3z€hŒáרôYð†©×鸃‰gèz„á¯ÓýY¦¾EëgQ;Aî)’;ý¨fœ„ØmÔMˆi.¶xYrwš%øØ'Á‘¬Èp1Å®+|¿“O¦¹ êØ|ŽŸ.áåâõpk#KÞ`çÍk\¹Ìðn9ÄÉ"™:Ë@í5Ôžf –T#u—I+¬%´\`Ê`­¤é4ÓçÈ.¦n5u™Î î£y ½ŸL'ÑÕ$ç0/17‹¸›d ûÐÝ8·É ŽÌÁ%øQNcÆá¬!r;r"@^„!LÞˆkF`𠿯„6p5ŽÀ\Å¥` —ª\z¿2 lÁ"óÙ+ ¶ eñÏ´-Ì*Œ€Þ„h‚£Ÿ¡ƒ^ 1̤Äü·Ó1Ì"ß`&YŒÜDä9fmô"T;Ö!2Š`jÉWiF6c]!Ó„jÀªÃêgª‰È0ÓµXõXÓÌD` Mýô·PS c¡kpÆh"’Sx6R“n 1Ïxu“qjÒ¼ÖÆVA›ÁlŠ50¢´8,¶Ì¨m$Aî/pëÐè ø9Ü t#¡af„Èj†_EvPðpCR9þcš·0z•‚ ÖÁ•ÓD;°S,½™Žå\=Ž›AJÆ.`4hÖÝGãbË&ô1Áüo_€Ñ\;†›]pˆ¬¹‹0`!CÆ„‰´T„Ý´0†B†ñþ’*ŸøUu<ÕV¤ŒS yVéµê2(ŒZ -dQØ*–éT»±ŠBUYqŸ÷ˆV…„ó…8ÕUÍ•_€,ÛÖŠeaÞie´óP%1ÊRk"CSšÉæ—qª2…Ä«jVTñ)·ª¹BÓJRÝdûY{?©6®=G²‘£m+¯a+„GÓ&Üó${˜{öO‘ù%õ;™{’ºGðNìnÄiãÄ„Æù°á¹P®óõÈIÖç8b±Õ‡ÅYÞŽqÛ,§->& Œ²x„C’zA|ˆ¾Üs–·šX–ff-;Wòîúaý”Ç›è”D_eïNn?ÅåZ’¤ÞââV(ìãŒÔSÓDê8“Ëiˆ`ŸdÖÁî Ã9ΜF¬&5IømÆÿ€N‰z•¹=¸ÿ–f‰4È—Éo#*Qò8úçøg‰°¢Èòð7õA$iÃ/5oî„Û… ˆ”ƒ _òšZøŒM´zæ¢)¥ -Q)’|¡D‹rД†C ðà»SÅQ‚ÏYt „`N€0RˆAf•0ŸDjaBôS„§š1hìœ0—Ÿ$üɽÂkäþ„Z ý-¦„¥>‚ù£ÌGhžÃ{’þϲ8 øç»qî¤íE.>Äò³ Ÿg`K3ÌæüØò"o®¦ ¼a.?À}Çx£Ö8xä43sô­à¶k<ÛÁº4owrË,/vñQ3y³™O(¼©ÈEÍKLÉà ô‡ñ‡p/1w•h‡œ‡/(rà+¼¼À‡ŒaýïrðïhÙ…g¸z’éYÜ$½w±ä„Àr ,$Åþï1r¶¤am|öõ bƒµpbˆ ƒëÛÿ*‹ãO1p ®áãÿÀÀѥÜZru/ç^(W¥Éru·åŠ˜¥Êø%Ë­òCUþ.‰±²ÌÂ$Fa–Fj1/ZX`ª„vªëFݪ XZÌ—ÍaæƒA‹@€4ZjSÚ¦e„š_øe„ «ø”·Ð¬0ß\AáŒESÍ‹¨o£{3'¿Gþ2·ý "À²¸ð7ôþ>¸ŸÌk´¼§Ôiêë´þ62ÀNPxœšGMø´ˆÜm”…ˆâo0¿ëŠWa‹2!éÕ˜YJ–X´Ms¸†mã­eó$—“,¤t©yaêÏ­ç}—8UO×nm¥ë]Ö˼vže,u1Çè_LÛÙ:jÓôý §—Ö“¤Gðï£ë & j gÉM j+µ'(¸ˆÍÄ êY²qìÛ‰È( #%š}„YäŒQ¿!,±Æ #F<(D+âŠæ¨!«qCs»Ë$&äŒæ’F&BÐÜ¡U 3š½>¾™ï„6g(èª7…yç–Ùebe jKݰ»l’²t>í1a0‚F…HÅ6iÚ¥øºPFJQ#Í-‚‚¯ƒÐ5F/l1â˜N4£× ÐCx͘»‰"?Ž—Bï$þ Ó hÀdBüVDš FX 9ü€Â|ü)ÒíQh@Í‘O‚$qã„YfˆÏ0ØN» o: ߯h¦£X 7‚­(r1Ržªc§EA0¬8E9fÁÛ­Gw1w¿ ¹’ÌyBEÞ#=Nd ÙÉRC·Ì,3st?À‰§˜Õä`å=to"ÕÄèY¦®aÜŒÏMŸ( U¢ÜwZJ†Ž1;bAÒPû¸³ ÛµEqUܪøešöõÔu•„-¿€Š‚@9üF`ÅpRUúq– ‘äÈ%ÚeWß«ãDUEµŠ—˜G¨ÒüÄ"ÛRˆê>\²ÜýSF#ÊÍÚKM¸~¥å¬ÜƒÁ”ôuA#0Â@„FèbFíøÿŒí Ò&~¿ÏaÝbdA‹EžyAˆÿ#Ï ‚ !J²r–7âìša¿`‘G>ËX’MS\L°rŠþírÂ]ŒwЛÇ(IäÂägØxÜ8þ:šBÔ^&¶Ò<~‚‰{iî&ÒGxï>jãÿœüÇI-¾ˆþ)Þ'‰7£¢¨?Áo7êÿÄKÈ?Õf«B`ŒcÄW}æB>g“2HÐü¸À™€ßŒÑ Æ @$|'KŸWÚÊM°ÖÆ”¿À0¯ü+bAã+]aX†of˜,7îûl’…-P’7|^ô@ñWqr#‘‚Ÿ†æ/-‘¸‚Äÿ2œç IDATL ýz+bˆðÆû¤°ºáÞ³äÈräÞ˜þ2M'ɾÎÌ£4Ôb^`ô!Z™{‰ÁioÂ~Œ·Ò4K¦k+OqàÃl¹ÄU±ŒÖרs7Û.sº“¶Q.×Ss…} 4ÔS“ãÚJîžd¿ËyÉœÛÁ{³<×Âû2|7Šcyœm’i‹XúCƒÂ=†ø"ù·È¼„¼ßÃOÝÂàKñ|†÷1—'®¡n#¦ŽŽ[xù¯Ùø›Åœ-á¥ÿˆöÖŒ¦UUN^±ð÷_´tÒ7 ˆñugÖ}}“Ü.¼ïÏA£ Æ”†CnŠ7þžUï¡o/á8fž[Ù 3†×…„v™pÙe„*¶´~UÇÁJq¼`Þð'ª®ª‰£ÕlŠÝ‘uE§+Oá.6H Êö¿<—; Òt¬´."TX5(×/ÓYp>æ{yÖßÇù_Òû ‡ÿ'mk©ï mý–ÿl‹«_aÅ# P ðµ;ñNP³…ü·¨ým#µP6æ ùhÈ‹!I‹ÏÎòõ¿•a&1ÃÙ>ßÇW[ùDš>‡Å6-£œhdó '›Ù4ÂÕzº èq†šYö&oÞÅ{Ø×IwkYÑEÛ»¬Ÿ±ÿéÙCßZºœ£LuR×AÍ‹Œ4’HbŸ£ ±×8›À¹…š·) a¡æ2á‚EDnÁyÙŽµÅ¨—„™E®E®EŽj³[ _óˆ"¡9š£¡Í‚{mÒ!»=ò41x8F¨y!ÏLcКÕ[¢¥?³ox3ÏÐóUË«*!ó޶ÑÊZ”{úÇ÷ÆH*¤à„Ëq¯ü†’Áº¤à[9…X’[mú5WH¢Ò¬—â¸)Vy™EÂ4Á1Be‚u Až@.Âx˜i¼å(…é#_C(Ñ>a¬TËZŒLÑ ¨ªL76,µêkô5‘ˆüVR/$’®%1Îá6:S4Ø ?Ë¡FVº¼UÏ6_pMr2Še«2o¨ Ž°‡¹7ðÛÉœÆW\ÒÃD73z˜8­Ø=øW÷âôàKb-lüƒH_C$ÄX´ QžC$%o‘.ãTU®L@¼¶ÛJ&9ñ#`ò£ í-!šf^ŠÅw`×€ÀË#m°pÓ\} ­Ñ;ÁÒ;K­ƒ¬$}»ÉN•~ŠÂçÚÞ’™^U½Úex²Ê‹J_Ska³SY¾(ßRîBºð8¼þ_T¡ÿºÔï­„Pay]D.¯üÐ+S-·üÜ/_ÐUvª¢G!Sþ–%«hjæ–27J~œÙK(Ãâ›;ÈÊ0ðŽ@å踓D ƒ?$Ç iý3?Ãq°ljÖž$²y™è=†ç„…Q¹Ýãâ¦mhͲ×á}³ì¶X€Mϯ6ñÐûlº³LpôL2P˲Q†jèœfb54Œ1½œÞÜXÍÚ¦sè°½ƒæwX/pf„üS\þë•Ô¯ i7“ÍD—º‚;‰¾‰Úr™Ô£/ÞN ÿ”¹[‰<@ômÌÆü®pò¨AÜ¡…‹y>à@ ~SÑŽæËyzrÐm¸ðýYþ{ùPƒaVó?&± Ÿ«§Ua Ú àµ9^™)ý½ÿ¨”œß ~g•ý_dXEC`KžLs`®´óîNqG’Ð %B2ð ’ÿÚHA0§ù‡,Yød’¥6Žä—>Ãð™ˆ1B ø³€–y¯Jèÿ`ü/T-úþS¸_Äèo“ù Î6œ?gôâ˰ßfæv¿d4Mî‹,>ÄX3v†Âa®~‚UOptMà^cà6äÈ5ä*ƒœº—÷œa_5Y{Ù5ÊÁçÄh‰R—áÅÞ›æñhqè¹Z|?Êû•î7ÞQa~›d^"_ìæ^®×OnÇuЗ^ž/æ0мŠuŸÄRd8óBÃö?E:U]ËËoÖêwòÌÎý°DR®û¨¤k—³ò×1åÉ„š?“L™  ¼Jÿnbm¬ÿ7%ü0et“1žûc¶~†T7F Á¼<'~ÄøåRÄW­Á«*ªUD¢"á¢üYQf[•×êóO½Ã@®Êž «¨e ÊøU!VEMÊT1,¯üY÷’UTÂ#¿M"Æ•ƒØ’5ÛØýU­ ¡ƒºfòƒcùýœø[¶ü.£ÏÑ}??&¼Lï_0ó"‘8ÙÝ,ú"ȼNâNÂãÄÖó˜p~Ë(¡ðÄ3ðH×yÆ||œÇkyÔ g¹<αn>}’o/æCã\IÐcQ;ÌÅ6Ööq¾“Þ~ÚX”Áa²ƒE/sä!îz–£=tzˆutÝõ.C¿`Oµ…ögØIgÙ+hÂË"vP{w s‰K„W¡•DÅH¬GpŽsVˆ{Pž‘?1,1â=°?ä¸oZëð¼O.ÀÑ|0ÊeŸ× ¤@†¡ž%Ûq°ƒl,÷"K–ÕËHš¦éuï=»¿íyÎ3cËÆ&^_M™kíµ×n³Öì÷½÷õ^÷ýÜÏ}ñ@G’“¯»&[Æò ŽésðEEШ7yW‚ýE¦$3U$L®‰qÂ¥O2 †Æ&‹”bf4Lƒðt2š tQÚ²DE–)•žAP(â¹øµh%œ?.nÍ&è"…V F9ä˰}ò6ÊD §“† F‰[ˆ0ª›W×r†$+ÉNqh9mp–L@ºŽ5^°â4…)7Ñ„Y­±?¤B"h$ÿÊ\Z!WâIÜ~œôQ‚Sý¸ jÈ8Tm"TIóV2 ?ÀŠÐ|)*ÃD3é¾å#ÀŠ£[Iõ9ñyÅáÁì” ëm/'¯%€Ò™“Tœ{1µŸÒÄœšöòx%*×Pµ©ðÐÐBœúü7ï²ö£8ÐÉO1¾§€T¬¾ ))ÞƒSÄ- À0=€›£ÑÐi•,ó´¬ðµáñâ´ÜðMÂJ½©ïê´€TótºÚr絕7Ï_Á|5ÝùLð5Ò<¬ÛÌð–΢¥„4‚"••Ôµ¡K&/Cs  ¼Ž°bjå ¨,uÉ¢j΂iÊ×B’Øz ?ÇŽc„ /Sb§Ð˰BÊØð´¯L_Dau^U>J‘Èr(ÌÙÓìV„ušC´³»‰‹Ù¡mšq…¢zŠÉ*Ú†™¨¢y˜±•a"ãäW±ôyŽm`ù)ýÖ6SþŽë_è¤ôKÆþ„Ž»[Eb9‰ÇÉ5a×`ô”Õaþ3ÎBBlÔJû‰PA›âGñ@|Ê ßSßwÄ•:çêÌ<\ä–0Râèð&é4¸>F1ÀP|e ¾ÙBƧ|y$—Wr^_áJ¼]ðBŠg’ÅÚ87ÕÏ—;@(²Á[Y¡ª·q¨h ièCÌe…GsÜ3:ç’pYëãè¦@×Ð_胛kXBh„u~6Ç«¬S„¯§±L>§ÞäI——%_ŽèÜåЯñ×! Ÿ ƒ4õ}åY"øúÔöàü á‡É ážù2™ˆ7 ^"½øFj1Ð_dà&:çøTgè–ìàÕõ41ØACžÉN–>Ë£«Yªã¶°ø÷†ðË©¬¢2Lb†§šÙ®cøìö9b‘„ðMU Gó%‰»ób¦ï 8D ‹‚‡£“÷_¤ÃÊ‘XŒòÑ@yȇ¾©Ñq±”œËÒÅ,7I4ƒÞâLÌmSi}?Ñe¿×9ôMçNcf/C¿D¤¢éâËæß5æTRs‚gzý÷³á¯.si—¦ç83,¹y®`öÕû(­ t„fÑ÷,V”ÊH…¢ëQŒ]ÏÒ¶–‘ƒszJœVžKy¥öÊk|äŸÆV¯ÝÜÓÃ×ÒÀÙtOγ•?OXE§µPmÙÆ@7~ˆç~ÅåïeߣÄ"${ñg¸ô£ô½ˆ)X¼ £¸“Xa •§ý ò]xƒèõ2q/-ïcüvÊ6©ÅyŠš/Púör û %~¢´ë=qêÃYq·Íûó¼hpIŽ]’hT9W ñP=ïe"<ÅðR®ßÃ/—sÅ(å´k„Fi`ÉIúÚYÚÍh-IJãd›hx”®?`Ëýt­ ®€ØHýå,~G„õ%)ŒN*~ÎøåÔ¥˜B[Nôž±ðNü<ÚYX{Q“J['ôD·Q¥­…ûê!²’»¶Î7yÊáÕ"« Öèü2GZ«-ºJ<™¡I'¤¸ºMñµ!jt œ€««ŠçRìÍ )ª * ¤¤#²(RÑ[౉×ϽT¬ŠÈ7^ÓÔÛÖ­¤ÆKs¶'¦Ž´G¸´ žš&ø0èà) ƒ@ð¡z^É’‘ô¹ #4¶'ÈIò’!‰e°>ĸ$ c’m¦iÓhÓˆèLhLi´êøB ëthhBžÂoFU£Žã´£Rø6A+bg'©«‰ffÆ4ð–adò*O1¹–ª$É6§®%4Âp etmeý0‡M‚Ëh¯¢*K¯ ™Jj=ºLŠ1â6VŒfA—AWˆ&›”Œ w ù=¸àU"›É’KR pÀÞÀø~ô&:þHCãŒm¦l%á&P:(F›Àª Tƒ&~bvÀƒš›‡%“Q|s%ñí8k¶6YJõE¨ƒ’0k·¦£ÉçÀ 0ˆ_$ºŒšóðó ¤÷ãæÈôRñexE´0cÏà9d‡i» #ްÝIªòeÔoÂup‹Öí$ÚÑ,ÆŽ1z”µïÁ—ŒeðU¤à(¤(oƶ8¹ûõ’–Z~V+éó%'}¾²®Í3”š³!x]UÍ\Ìù™y´/á`7KÛ8uŠÍë¨*§<ÊÄ)šš(¦Y½™±CÄ¢X©>Ê«°ÀOQ¿ŠÈ †ÂÖ±tœqê7¢ø§PãÄ;Ð=*.Ä;ŒžÃP¨SÄoTê€0&”1¡¸Ùåˆ%vë\^dŸ¢¡HR§5Ë@@$@EY3ÆÞ2Ö{(“ŠAŽ´rf/‡Êhb$DB':ÅL-M$h<ÎHuc w-­Ñ³Žã¤5¬÷²¤Ø;"¬Ÿ3Úƒûs2Ÿ¦á‡¤×]Dè ¼E˜ Œïá^F¸ínÄ9ëÐî“, Ävð%÷y|Ì`Øç'y’OÅèrøqšk"œbÌãñÞWöÙŸãÙ6„¸¾Š_ëŸo¯ í‘q küM7\]Ϲ•ù€¢»’<7^ÀV“0^/æ¦=4ð$R¾}9_±²tBúÜ,¹t3X@i ð$¶r®d\fñÔ$OLašTZ¼·‰ˆAD§»È]Ä-Þ_OÜàÞiú}®­dY˜>_dñ5¾X˰䟋Ü¥ÙäˆäရBdáÁm®î€wœ%Ô_á¼î§´ UŽÜMásÄ÷“ËÑNQ8›Ø½ô_KÝ#ôl¤ü(#XÅf¢Œ.£6ÅØz–>Ãkè0p›iá`–cat“¼N)†0H¸¤IÞÆ #BLZ„CäLU¥Á6rÍ»›|ŠjÎn ¾«‚ês0cà!@:$wy#Ì’¿B`v§‡,á'™¸|”GÇ·EP(1¿(xGP§oL˜Ÿ©1[RJ?BêY0iù ÒA‹ Œ¹UB-Bêe¦Ÿ éýˆF©P˜ôßEÓ5(…E&ÃORÙ‰™@ê` ‡Ùû :?‚a’#7DÍ:„I÷$š)_B ‡fÉyXe<ô.þ N‰B†ÇÈ{¾D±€çóÈß±æBV]Àw¿Èy—Ó¶šþ޵œy9ßø³úZAÝŸOgçºü·óµïrÍeØRãô㣟àÙ‡¸ø ö=KH§µçîeûUÌŒ2Yu&É“TÔóêOXr&¦"¹— LqˆêeX&ãIzšEÀï£j¦Máb«Éý#±3±Ø« þ^Ùqaœ¡´µ¾ˆ–ø™ÎuY²¹yŠ_&¸)Û3Óв9ÀPèý<×ʧ8 ˆŽ1ÖÉ¥/òÛ5œ7ÈH m }˜d -Gé ­‹Éå4Q˜Ài¦òA†>ȪŸ1ÐIeq6U×ÒøŽëœ´±Ï!q雨x¯„¾ëUd5æVŒ§ PúÙˆ]Ïg½ +`Ä£B±Hð³"kYÌü(Íå!¶„ùm†—³œe¹Å=S„a¥…¦ØšàXŽÇ¦X"¡qA5ºâ¿§Ùfi7àÂ<3É®)4IK„ÆRÒaQ ©0?ÅÐ*{8¶3ú8lâ{LT^ª^¬¥2L4Ç+Mœa $=š +‚ˆq¦äׄ¡Fµ×|1½zŠcä¡ÑË~œø9Ô_Šr» «IlMC7PCß!º„Èrì%B ‡ Y =„fîD³ærx­ ³ãUù·ÌuŠ»æêÞ ¤C~/hHŸÄv¢›‘AÂ@ ü$Î3ÏÛ@ùEx9`Q:Eî¹ãÔ\Õ4× šz•é=”o¤bÊ 8ÅÈä§Xûg¸EfN0ôF7â¹ Y;wOr]9Û¢ô”Ø•¦+í Ø $ÿ8Èê(××3Q"øv7Êç;ëI»L•0ß9†©05n[Bm˜¼G²„{§Ø5Ž®æjåY='”fÃ>ãRôç4Ô[^­Ëm, Àй÷$G’ˆù8í .mÆÐqËàŽ“ qà¿®@Ó‰<8‰<Í1®nÄÐ(qÿ8žÆç7yb†A—k«± ¾5A}ˆë+x0ˈbM”ó"<äPfpaˆ»|b‹LvÀ‡ …ÎO•÷IÁ=”6ÃAo5Ú^òçaì#{æq’͘mèÁaÆcû 3¶‚šãëhcø¾b¦ M>ƒó³ôJ&›8#ÅGcÈ ‘„(XhaSÝ¢•¾?GXN”b~®¬[€øQ¶™êk¡ˆð‘9F¿Ct Uï…ÒœÃqÃë'ó0¢DÍWЬ¹=#¯ù"‘©¹Ë‹üco˜›üÖ“\*>…ræÓC½ ÔÜ*áÜBa }'N?ÖR"Û1ë¥ÀÆeü»Ä/"rZb®“Ëeä.jßCdV.…ø zœº+P:ÊàÄw)ß@Õf$h öþwV~ ÅLðâYýìJ”Áà ¤‡Yv-ǘêaÙ•HAr˜R–Ƶœ:HvŠ%ÛÉÍpê m›˜a¬—•Û1ãÜÿM.þ ®Ç/ÀÍŸ&” “"RÆc÷Ó°˜ågPrñ<Nñ轸’Ï|–¾ƒ}ug¢d9ûÝÛAUš‡áSÓLE#HÅ4¬¥÷ªZ‰TbHŒ€H‰¤ï#Ö¥¼Lü2«ÑúÊÌ s“Ô•â]õ¼/yN(š#Ü”a¿C1Çx-7²;Îê$= ÖL1¥¡ŸcœÛñj–f()Ä!º7±¥—É&šJ¨ MÔar) ‡HŸA}…4²‰Ä¯˜ü(‹~ÂÄzÊRˆ‹ˆßHÕ;"¬/’ìA]Hä;”>¬"ÏÙþne> KQ#9 $Ó ; J0æ‘ò¨Õ¨üÓ ë ÖY˜ðwcÜTNµÎÑ<Ï%¹®š“jƒ;‡ˆÂ’ká¡6•QkQm±$Î_ìC“¬-§9JB§#ðO'Ëá\Õ†S3h£ P̸Ü}”’àÿJCƒèúësâɵKXQAѧ?‹PØ9†£@CÓ¸nn€©óËA4 )¸¦] ON‘—´DÙTŽ®sïšÁq&/æðun¨")y¡ÄÙ1jL.2pvœqŘÆa^‚zƒ Ï N\lÈ—)¹_8— §F¶£Ž‘[ƒy˜™+ˆí"))† ¶SµA“Ší„O2؈•gªŽh !§•Æ1ºŠô òaJ6Ò&&0)Ö²Ò §Õçi›~ /LÑTÞë «0_€ÈZênA7) ³ƒÄ6Â.F§›™_Y‡Õ„QƒVPè6Â"ýup0Û±V#$"‚Þ2ïmÌ…Žf¿£”PÞ0hCéˆÙ9wãIƒØÍè-(ŸÀE˜iÜ>ò/#*©ü²ˆ”(w7I©‹ª÷”?ÃØT߈ÕH t&wP±-N zÊòOáæ(ŒÓw?k>C)Ò߇ôiÜÎĦO²ørœ"™Q^¡ó†öϲäB|ÉØ j—áydSÄkP|ƒ÷|‘‘~º^aódr·’/½BÈâñ~®h%b”p¤5·ÓÃ)²0£è§¶Â8%ô0!“É"«Æœ*±Ì¤]ã±"‹àÅ|TW?ð´Ïâ”Öc·£^ÄX…z–¹Dw“Û@ü’uè´5Äf¸½@ÐI­G¾ƒÆ Sºý Ù¸ô-£eöð\K¦ØkcK2fŽƒ®Ï¾øª›³-ÿó5àÙõ©–â"òèQbKˆw “dþ’ćÐÛˆ4ý4r òøÏáwz?z#¤©þè¬ÞE&Fñg[®:1®ÿ´–9çmÇj̵‡ |ÚÛ ÞwP&2@_¹%‰þ7˜-^Pz¹?C_Cä,â·¡4TÍÆé#wö6¢m”߀, '˜¹c‹>Ž’HÁ̃äŽQÿ'è”s„ɧXñaT·ŸRk?†Ì‘~‘ÉWhxå{«œ—¡C/maÃM(òJš:ñ ¼ò#VÝ€mÑ÷<¡ Êk9ü8×}7CÄfÓy„BìøGnú¹<©!:¯àÞïröÕl9‡T’³ÏB7éC²ç»Æt4S#P Û y’õ·0ø(f .¦…Ðóm±Z‘ÆÏQz L…a#$–« _è)©m,Ñ+TĺÇÁZ‡b€]D×IyèMº&8ÙÎ5)Æs¤¦™ngÛã.a‰í*"êh-@ŒºFê{Ð ïbp 5ý”VQ€ì»XtŒb½…È·˜þwË!ÎÄ Þ¢+ïmÖÇ) .Æü3¥Þ-õ6É ¾Ú¨Ä‹.lsÈåH‘K,R>g¸2ŠðP’÷”ÓªÓWbÂaC]ñÍ>nkÂVÔZü¸T‰?l¡%ÌOº)78£Sqx°Ÿ¨Æ%XíqÜ€û!í÷õµ×Eùàztô§Ñæ[¥B î8@ÈAQòÕíôΠ &J<~ t¤Æm«pŸG)Áõí”Ùôxn_çO—ðl’þµa.©e_žƒE|øP3OÌp´À_,âŽ$y-aL>VÎC¤42dó¨0Ô2<‰ûyÄÓ8‹PG(¬CßËÌ-Ä`r¡.¦¯¤æINU!’¤ÊçÚß —°ü]õØrœ“&ùùÊ"×ÁÖ4/¶±)ËN“”I&D)L1DÉÂP4¥'ЧMžÔ7¸ \ ‹™¿C¹½á£Ç(Ü ÃX—`´¢ÅÁG3•Ð…wjóýÕF IDATÑrnzºÒ,ÐP‡ îGó ¥#.æwúnNã,‚ìiòª ã“à %ÀCzsã¤5rú•÷¼ˆÞŽÌ!]$(5Eé0‰ÜBP$Pþî ¢W"}¤DdŸÂ^е¿„7Iêi´2ª®Ã+‘=Láµ7HrÝ8I*ÏÆ-1öÊ¢ö<<‡‘ç‰u[Œ°ïØüPÈÒó$íçCˆý?£f5uë8ú¡ZZ6Ó·‡b‘ÆNžø17ý5Ã'8¾Ÿõ—ñâ¿°jv‚/aÇP;Ÿ¥¶‚ó¯bä8½»Xµ= ?†Ë9t?5M>3ÇhZ‰;Ίk˜9„%¨^Áè”7*ÃT˜;„ó u·!O`Ì íS¡ „Y§´­ÓS!%ÖçyÄ¥\¤ÁÚ,ÝS¼ªS¯(³iœ¤/Ét k=ô ’9J‹Ù4EÒC·(;ΈA¸ƒEü1JëXtG¯¦ó(é,tQj¢¬çbê{ðŽâ]Då½d.¤¼óy‚¿&z&æ;2Rý˜l´_ùÔIq¶âU-‚”Ï®‰òxƒ® “ñx0Å—ê8X`Ç7VHNæ@²!Ξû¦ù` i—¡‡’|p•ÇR<ÔO[„Kš˜,âú<ÒW/Æ’'ûÉYSÍ»—Ñ—&çàz› ?©p|þü|J>ýé¹Ö•‚‹&Ø7ÌDn~æ’øWZÛj®‹øê•(5ßòÀ²*~ºŸŒ37%þšøŠ¤ÃÎAБ‚ëWà)ò>/ŒàÀE-Äl†Š¼:…iqM+/'shŒ³¡‚#yúnlâÉN¹µ‰ƒ%F|Î,#£8àqu?ÊrAŒaÁ4†˜Ö)ÓUµ%èò%ï¥mpçlÔAŠ ¼Iò·Rþ<“‚RžÂõÔ8¸)ffH™:yÈé¸!J6®I)†Æ3ñ œ¥¹2j &tRaJ!J 6N„¢bÖÅëRôz¼ØK°/@8PÀ߉êÃþ Zá)M 9û¡ ý+ˆ"øJè uaJQè× ±P8³«wbn*‹šßls œ7Zoh²ìóŸ<ÇÃÔßøåÔ¿¾g®Á=àØ8Ïõ͹M 2¹q ‰0€#ùþnL‹†8ׯ¦óõÝ„, ƒtµ¸ë8S.meÜØÁƒCœÈqi3ËÊùõc+9«†¿íaS5WÕòíÃd“‚%¶Æ¹c†ÿRË÷r\ãÜ0·;¼+ÌE¥jMñ²uxKEP‡ìª óR´hŽ ~€f¡Ý†Ð@ILHH> Ûa5ªL kv"¤0|î 8©P×Í*)…¡Í=¯m·ù=–‘Ì ‡m6¬/I è>»%û†Å—8‚@(%„€I M±uDˆo Ò(…tQ9ä“"Áú"A g”»KØ× 5¤‡Ì( »•ÀÇOãN GÑš0ó[bgB‚@2ô·Ô~£–@Òý·,ÿ¸9òCôÞÅšÛÉÒõ=–}'ÏÑ;Øü—ä&8õu›Ð"ŒÕ·à:ßAÕ2*–²û6ÞÂø)F{Xv|Ÿë¿Hrt$LŒ’ÍPßÈD7};Y± # 0̺+éù-•õh¦OU+á8§~FÃFLEé mïÃ?…JbëX½H|;ùÿIâBLWÙgã®6!ù€G—C –ù$|„»«9?K*Mº)²QF¨gy’‚Eä =ëYßÄÑGö\V=ÄÉóXÚO¡’Ä“Œ_ÍâƒäÊO¢&ájªþ雩x•  ÛB›@”aÜ­Ä×…öaõæu˜·N o(R¡Ð$Ø¢£K<ŸOfÉ»lp·†W&éžf*-¸¶ƒIŽOQ*±¡ŽˆEß4})ªlnéÄñ99ÅL®qd@Éå3ðʸ§’ §°uP(ɵëh­àå~ íÍû‰ã½ÁèÙ6д· ,!›¡{rþ]a°¶ Û/÷¡›ÄÃtÖ†Ðy®ݤ³Ž²0}YzÒÔÆè¬EÓ9’³xrWQæ¬zþá$Ûé(ã¾1Úc”‡q©‰ 5ö•ø`=?Msq9'§$+cƒ56‡tΰèÖY¢ùQüa¼¥¥ÐH0Cé(ùNþ•”?Ã`Œ  é‘Q¸!Ša\'Bɵ(FpÂk©qé7(E(†)Z¸³™àlJ%oᆤ£¹ŠØïÅZMð+D+úÙhE%f”D ®S‘è 7à@¦¸N‘`KF&=z$ƒÕ6[JÌÍ.ÓšÏq‰£ Ç¥k¾öhÄx—þ{RBÐ0“ü@`Íïž2mV27–³Q£V#O 4,ð9éñ´ÉV««v!Ê…*iØB¸OjÔ Z5ÊP¦R¿EUU¨%0£F‘è[&îS(•@_N࿟лÐ*tf~EÙ HAnùT¾©‘=Œ;EÙ¹&ÈtQs ÉC䨹)È¢GñÆ÷P³…Pû¾Oûå öþ3ç~–¾G¢ös™ê#Rƒðê켘žý”7“š&ÅËP£¦S"³Ô/%s‚h CbIbå˜6…ý$š0QÊ7 ¥Ð ˜–Ž©ã?Fù{ÑF0¥2Ú|ÑSR%Ä—¤ƒÔ9Ø>šCÑ#”%‘.æƒÊâVÐÚK_+Sä| «’š“LE‰à”Q>‰ßFÕarå„ˉG°_"³’ò‚(ö4Z€>‚2±ËÐ1Öcî@lÄPJ/âou:Å›‡Ø½5a}½ÈO Éñµ2¾—fµA\ñ‹iÞc­Í?Žóþ*¦~2ÄÚˆÀCcœUNÁÿì¢Rã–V8…’\ÓLDãË;YZÆ{:P¶Î_>ÉgÎA‡ÎÞa:Æ—ÎÇ÷)¸üx%Àá‹—„tÊB|úè:ܲ‰ºº MµøÉ‹ôN¼q—ÃüT’åõ\½ž`¾-+PÜ÷2Ù7¶¹ÏÎúWlhçŠ5ørîÅRÀ»˜q¾ä+—ã g¹gÂÀwù«+q$¿8BÏ e|xöp(I ¹¹“ª0ß;À‹iŽóóS8’/làö.¤ÁñÀ$õQnjà¾i,ƒ-eÜ1ÅÇ›ùnšíqziÕa^Q\á·‚Û,~¨K ÏÆ»õ GàüÇȺOŽã™¸6NÇÄå /Dѵq§1”5¯°B8ó„UŒPˆÌ–±üÏPÆùhç °%Ï+^…)UB yÜ¥qµÆ:Káù±ÎZƒµ‚èü~^K¢»ìÍót%à B̯Í{Æh³)žB(ü4?÷™â-Ý͉,‰SÇ_¨9£ÙSç6YxöÌç"Ï£>c!V„¹\PÒ^ÿ@¾Ä‚T˜÷ "ÚÜ š®€ þH£ZC ²BÁ0\Œt…ÿ;ˆË«æ6è¾E䋤"};e,P‹%¨=‹ÑoS±”P-¢}*¾@pöre%ñ²âE{†Ÿ 6Tf8à‘p‰4»auŽÉ~öÛ´™TGi<ÌžÍ\û4Ï4°¸„ˆRù2'¶°¾é•,:L²‰êiœZÊõ0vRø­»)œAÙNœ-Ä#Û°´=¨MØßRâ+èÿ+ë”R¾¸JçO­wVt¿§H‹FƒàÅgÚwð:C,°"DÎçpŽÎ(å:;¦ØV/ÙŸbYŒZ›”ÃÁ$«ËQŠ£I¤ä’Æó™Blk!¤ótJÑœ ½Cðd7º`E µ1Cã‰.tX\Mm˘Ûp³€¼3÷kˆÙ¬jÄ4x»ÚúT–£Ã¯7ai‚3ÚˆÙoñS‚‘4'ÆÐæW Mu­„ ç»ñʬmD×xy€’tÖSåÙ~ÁªjêcœL1R dRb¼HÂfM%§ ¸ žþ'óœWÍ i”`I”a—ˆ´Ù÷Øf—Ë*‹.I™NB§eë¢ i ð-d ¢€W$0ç†Ï(ýu÷§Ùs7ûÒ$ÐNs~£Q°¯+©)kãˆÄ•Jè G1©Ñ<[{; O£Z`Î;iÛ§|†Âl~ã\ÌãžÄZA#€ÄùøE¤‹3F¨ t’»¨<“ÀCèÈ€LeË <²CX Ì2¦S¹ ·H~šŠEœÚMÛY$P¯# `èH bhDʘêMÃMahèá¡ëè è&ºD(¬JŒš‰:¹1%…B- Äq¼Áz‰€À%¢Sâ¹äfž¤A"Ns‰‚ƒS XCK/=­,I“½€×Hm?Sq¢BC§dafÕ„Z¡WÈ×cá7`»Ðй 3æ0D³ÒvÂV¥º¤ð$—”k°€,àß ´…C°€,`°°€,`°°€,Ö°€,Ö°€,ÖþâM‹ÚÙÌÛ¾µ€ÿˆ0Áþ­3ÔkÝt'Ḛ̀çyFG9~Œ‡ø¯gñ2ÖŸMëR"‰7ÿÕþa¡kÿæ©j׃ ÷rª›p9¿ú7}’çž`ÅFÊORa£Duʣ؊[¿ÌÕŸZ8~ „µ€üÀS’é^4‹Áýì}”ݲê2ÆIÏÉÑÚÉÞ4¯``€•›Igéëb¬"{~ëÕÒ&6^κ+‰VPÞLeÇ[H¶,¤„ XÀÿ•tØõuô{~„YÃáÇ9çS ïÁô8ñµË¼4ËÖbXŒRJRYI0z ÌÓLÞÃÔ0/ü˜=?ž›¾R¿„5ïeùÍÄšü‚ÂzûX\¸ -àwéÉKáePŠ©Lìcò£ûXöaöÝIÓ6<ʼôSjÖ²äDî¦å“9BÈ£~ÃÈöcúDB<};õ›°ÀÒ>—˜CÏ£ÙXº!Ñá¥' Ôœ¼ N“ZÁ¼à¬Aéì4a NÞÍàݘPVIØ"RMëç±ëˆ^¼«ÿa–B‰×öÖ« ¸øC`’{Ô/˜ÙOã§1BPÂ0±—(ëz!\DêûÐ-àß/Mã Pò¿Æ›"ó,á­83ˆlfðnjn&u¯D`P{9]wSw¾OÕ9¤‡h»‚Á}4n¡{Âbzœ\‘d’%ÛÈåè>ÂÖ뙞fç–ŸÅΧ‘%â§ + "š˚\æ¼³À ,¨º«žøŸ£U(LAÅë1~zÀ/àß…Â:ýœ DÀý‚ Ü/ÜAJ%²@T¿žØF¬ ôÞ¯±?¢xFø*c“â1ħ¨5¹x!þãAò˜PI¡^&ˆãçp_BlŽŸÄûÈ=ˆÖI¸gÑ(j[G³±Úéý&ÑVpØð F_%b!ó¤QÕ%@6q‹\x+'0 Á/‚G"Š,±eÃŒ›3[æ½3<ÐæŸÊ7ÞŸ~Ss1Má·¸àßE¸Q!e5\£è€:“³Âõ߇’¸ ¤$ïðœÏ_ñíˆÂðæÝ òàÅ©¸­„ÿ ‘ •Ü%ÂÛЫ£BoÄSŠå’FWíÐÄ¥~€£ˆú¨ >†@Ó‰.œ’Ûºé ¿UŸ&™Éñ/:iH v,ô›„4¹\È{‘€óúٺБ{– B`M)MîA”b’Š+Èt3ðvF#±6Žü‚õŸçůS³×%ÔH¸Šß|ú„êi]Ïãwb×rÖ5ì݉V‚Ww 9„ Êܺaè4Íõ&…eÍ+/kþ©õå¥ DGÍÁrð4® q]”K$Aèú¬ â‘ýÿHX³Ç]âMò ¸3<ïÑ£1"§8VAH¸aŠv€È+å ò Vb®!¶•`'öY0€n¢)¥Tb‰dÀŽP—åÅýan-ѧ³Ø'—ãU¨´8ÃaÈ ÅÅI3ÐÊ.EA¸ž- ¡ðoŽ—“Ì$ùmk%§$DÉæ‰Ï+¬Dæy*2¯¹ÌùŽ­×xÊžg¨Ði´eƒ+LÛÅt±Kضá`û˜%lÍ›g1Ú6.,gQ+ëAè˜aüŽWÕBÜþîðp£¤¡²'ʼnEœ[Íòw”¾Àû½aгsÁmå†E!BÁV®æHQDn”ðEhSD¯@öcv íG[%õœT/b¥Ç¤‡£ÓQ 'ĵ%Žh´AÜeJ£1ÃI(Êšaoäšc)ªÙààžbïbÎÏ’Í&QÂw)ÙÄ=D¯œª ª$4PWùFÏ‚…8ø¿4‡é2 Œµ]Õ”›hõÐ*©œàx=‹4T’Ã5,‰Ïp8DØa$Œ­(jäª9/ O'Ðú“À"ª3iª¡DТ¼iáëø£ø‹ñFQµÇ ŠÒ4~Q‹[À)áä1š)ÌÐó‰åDZ)ºä2„ɦ ÌrÆQ!*[Ÿ i2ÌžMÜ1ÃIŸÙ~.œâPžÁåÜx˜o.åî{2,u0£|­…‡Sô+Jõl6œ„A—•šLð a>!õ¥e¸üÿÄ~¥-Øo"ÿ8î5^ft V/jÉ%ùWZn§a‡ÄÄ*°î¿²ãß躒bŽCÛ¸â˜åÉo³äZBÃT–wóìcH—OVõàÃJŸ‹Vs’05ªÜyV ,H`\„ƒ¯¬ÛÃõª Ë®à†Õ'BUp#ìxÙN€bûØvˆí£|ìåa({3}t#™+YBU@ÈÚ@üÆÓõÿU§ñký2£k§™ÁhŒƒú;Œ@¿ÀÞ9?Eàà;„á\ç› n¤â0³Šwr÷yÖ ®±ÌѤ('¨¸ÚWA$ʘRBX·à½@ý›1ÏwG°:×ÂÑb böXâžA¯ÆñÑ6Kgx6ÃmÓ<í°ÌeÙ$Ï5sÕÛ åÐ2Één.ÍSšàD3‹“,áh;KŽp0Ic'ÜÎR¼€U#Läðúè6Xû9j%=G™¥|%%x…iƒ\JK rè4´‘Œf3Íÿ—>ôÿoÜÄ&ðŽQT˜ò΀N!âËó)Ž×#ûiaFã­aa µ‡£8ËèÙËþzÔJ–r¤‘zk„#Ýt*˜á¤Ò”Sè.ÖO°½‰î<ÇR¸6IÍ™zz<ŽÖ³Äc›Kƒ`ÊÆ’”&%DÖ6RjM˜4aNuD%‚4A…Ð%ðˆüI’SÊ&16ž¶ð"D] }’¯Rˆö«¼-ç\©8o`B©<±$ °cVåÕ¨Vp9ñwcò¢büаâAˆ ±¬«Œ Q!V¡Ôjº+iU(´QÒlÇý‹+©û‰^ýuœÒ,O2wôž¥|𬅱‹”F™°ˆêíj+_\<ß!pñj=Ÿ*.~íevoáMçX†±Öá°«}åkÊP† (ȼѸKEø ’ïCþL«[@FÈe ÀBlƒÐŠPwœÿÕÃ{ÇØžd@Ñ8Å‘F.2H ÜÁƒë¹7@r¨“e³ä,Ü4ÍÃŒ˜nº „ÌtÑq†|–Ê2ºäåQ «XhPsü*úA&¿•É7ÐÛLR¢¶‘]B]=®‹ú;†»HÞI‹F‚ÐÈqõý¿)ØñŽÖ¹Ù±ÿ}¹Â³?ù5þó›:Ĉ­ä÷SV‰‰¾Èé«i¸”:M´ì*2.(ôŒ 1ý~VED/qz)-Ôs-R¼‹‹öòÊQNÜËG9v’S›X=ôG~ +·òàbú{èçøbVæg……,šbÏ î8Æ·z¹2b\s&I[™­½|0Ë7ð¶€­I®öøouü7ižµ…-¢Ç„þå¯#î&÷]ì™}³Šô]L|±ŒÑ'Yô1Ný”©—i¼ ¯‚Û‡ÓÎîoÒ±™Â,Gžã²ÿÂô(¿úK®GÃD– w²í—h‡'Ÿ@ÔVbÕš{NÕð(9Ï•wjÄ*Uõ°ª€eWqͶW“„!–GÂà ±=œ°âGˆíW–ããD¨ Xµ—vˆaX*‡Xa5+ã™bÅWSˆÒg/7Y†?d¡A0ÕÞŽÂ@ê­dœÿ·a‰ø4“I˜¸£šD ¦ò0S 7^šß„É&TD‘MÏ8øV¤BEèâÙ?X.žSE./nFçTÛ•{.3í|¦ŽwœÊôbYEŒ‡ÁYF²“äjð®2ê´9-:=³]Š *•¬¬pLqY™}š6EKS6}3oàCÝ,'2¬<ÍÞ…¬çÔ,³ tMr&MG3=/³§‰®FÚŽp|«0¢è;Mö ù ,;ÂÄ þrŽQ>IþrzÄ(å1¼Õ´M¼L>}M ûfA­£¾ »(+I,ÀFï¤ìcÝJ2BˆíøSІu VaiʈK…lCxÕn‡âlïaƒ†kþwn#¶Õ`Ų¶ÖkHb„a»ÐM$1 “ļD0Jhˆ@¯Ç®Gì¢"‰lôÝ4 xŒ² \†;LÅ‚õ4ž¤P l-¥~„B@å"Z3®ñh,â™í§iŒ,TÒ˜À:«ñùk IDATÅàrŸfPáK„¢¼ˆ•Ãìo¢ÁAå9ÞÏ¥gx¦‰^ÍTÄŒ…q(J”CIa,<…´)[hÛøR8vT4‘aH ¨‚õøE¼cáLŠ“XBbãûгãdËtlbì Qš¦•ìz ’,»–#/L’—ŽÑ7@%dá ¼ ‹gŸ Ï5³æWç–ò$^•{87Yj\|éxÆ „íá8D„V<Ûós’Ðlj°jƒ9¨R>n„Œ —FùU“DµAŒ\*DEXñÉ¡"”FƘ¥Q2þV ^ʤÚð1nªözø%Ð#k0)ŒÀHLÜ8.~XèDmÆ"Œ;ÈÙ„ó0+¬=áfÅãù˜5Lñ|ì•ÇÝÈãùS)¾h™÷þçŸ ˆÉŠ'L„p;hü ÁÃ$Öaµ"S‘øKÄÿáñ¨1˵èöxÂâæϸ\=Á£n(“-0\ÏÆ,‡šØtŒ‡xã$¯x„m\´“¬å¾ áIŽtsÁ Nv3Î Ã.©v:ŸaÏe¬ËgòúAý½o`m ½—ɵt ¬ãð»YY†qÂsæ,*@–è0•M4xˆ3è”‚Œ?¡ü&Ò>"@X¨OS¼ç:‡1ßAÿv"øŽaÈð~A+hƒA «]ÁGC”!Ò\®¸Ç"˜ûàââë'ÛêÜó'!ø‡’ ˆÿCቸ%µ‘"&|ú£ÆaÞ0XÂ(ô,æ+ø·¢V!&Sɽ‘„Bkôß2}=îå$z'ùÕ$]Hb¶0±‰L+òAF¼;éÌ ãømôJØÏHé¸/sr5]EòÏór?MëX¼“]X=È¡>zòûxâJîx™ŸuÑ?ÃqI±™Î"‡:Y.ˆÚYwŠêâÞ,ßlbC…';ù“ŸM³Æ¢"™¶Ùfë>BÐŽVäǺéQÿnŠGÉ¡ù=Œ>ÄôKÔ_ƒ_ÁîÃigï7hÛLq–£Ï²á˜áÙï0pLç¸øv¾øß‰àŽwÑ5€Ñ:ÄIð…Põ5V•®)Á_KiÍWˆö9n—±ÁE¸JyÆ­byèz8A §bµTÑÊ­+'Ä ª––bX+À °c «lËŽª KÅx#T<c–©*˜¸Ñ`õF«‡¨^Ô8—yÝnµ®´FÔ@JT*~ ŒªQ*‰¶j¬J¢c0ŠñËÁWh‹Ð"PD1Y„M ãæ¾s0Æ&§Úý7˜ëõ›¢äÏò#Ô…õþóbX oD9¤RÆY'D«ÅÈSFdCqZð–ŠùŽW„$k)Z™Ô|3Kà·müˆÈ˜-¾^!gx§ËR‰‰E”!ÔXð”ÏÓe0ü}3%!ˆt•{Åö’›L¯ X@JT]M«&-…ीï•#¸+Á %I ¤Á_Š·¸ô)#)ÉŒà‹JšwJê%M‚e1÷!\´@ï&Ä•XIôG˜ýÒiÌ!*¿ ÿ.2Èï3é㽑VAôMNüý#”ž`øV.ÀÞÃèZZŸáhÉõtý”íwqñI†‡êgÁ1_Í%Ûy¦ö$Œrh7ej§kš—&ËöÕ¼u˜Ÿpk‘çYŸçÁVîôyÒA[Ô ¶9ŒÚä-}£ K"ÚŒÜ#¸÷S:Bþ¿ËÑ¿&Oà*°äÙÿo´l¦8Ëñí¬ý Ó#ìøwJ@E×Üÿ)‚2–…€ÀGGçЋ¸ø–Ÿâg_% õóâ¯iÃô<†eÕðË='¢ 周ˆj¹0¦T‰›æn¬kî»aÅ~Ví¥š?ÖøTMZ!Ê 5bŽsÅ@Õˆ•žÇª4JW’× W5ƒ#)-Î Àx¬ÅÙvâZT‰ŸåV5`Ò’Ð"œ§ûë,Tùñ³‹Ó+ÏÅwðcÇ*MÑ1~RTaKyED¼fƹY¤í«¸ëΰ¼#öa]¬ù†–¿²+4M(C ,ñ ñ¬Æy¨‰;¦ØeÓ—cTc§èÏq¦‘å§8’`Až—Ö$™ÓŒö±r7{³2Eã F»éf&O°‚žA²6v-?çØeô‚ý"SKij#ýNofAÎ6 ¤ºI~›ì©Vì:¬‡©l$±7 O®ÇiBdú…û±V¡’FnŸš:ÄHD|!¢^s…2(͉ˆG|ÖJZË,Chx¤Ì©:AŸ Ð\•Fkìš+ð¹YÜ¡ =9¯;ûëŠÁªy/|8ÄÝÐ1‚¥7¦ZðxK2f˜Ðɦ‰YØ $‡ IÉ›\„à…ˆœä°àFE§`7fL˜ŠˆþuØ„‡E4LðǸ[©”ÑM˜VÔ$Þ!J÷R7E°›B3zÉmL.ÂíÃÝÅ”M0@úÙu´ ‘Í1»ˆÆ yAÔˆS¦ÐDj†‘vÚf$A=éN¤HhfêIJ¢z2eeèγ-ÃBÅlšÎ<[šX“ %)»¤,†-³Àf«Ô¦ò²ð"®§r€ Ó@îr140¹í0;ÆÔ8·rfaQÇà^"—öµT ¥23.åèsô_TÛLÄŠ«Ñá¹Bâ$ö>B˜£0„ž<§R5%˜šgf¹¯ —ÚDŽ„íãx& Ë«jC§VF¬šñµ ƒ='ƒ*~© æaÅîûœ0¬!ל×ÛXBW ¬¼¤®éÁX$ÎgXâ¬ûkžº®w¬ÍlÕ” VD$Q Rs¦•E¤cÀRD5¨Š¼ø¥3ÏSDZuó)‹ eÊ®¨YìÚ·ÂHV LE}!Â%±§1…{ Éó0Ý ýwFŒWÄ—,>U0_bƒ`•&•eK†7çØ :Nód/ï+D‡C¢L%AÃàfèò0ÉIr'8½Œ•ϰïz6mãÈzVž!?Ayݳ„»ÛDÿ&VÓfPÿÁé·³(ÞÊÌRêÛI>D®ŸÄjÒSNc­%™C¼H؋݃½ý3Ì›°zýCa^Bþ=rÚ0­Ù«Å’@3¥9™¢7X”4Fó·yïKãÍLÄAŸŸÐ!ÿЧ©hBMQ“€ÏL  hÞÝJ¯ƒ4xºúa5ž÷ÙñŸaVm õ ެÞòÊð¥ f4¾àÏÚ !É(„à© ¿,Óbs_)iSäàK%¤âÍ êŠFŒó[¤%JòQm®´¸]ùSãHÈfØO 1«¡@ôò·à¤2s3‰eØ_eä*ÒWÐðŽ=@×·9¾q3 ‡˜ê$5ÍL–â ‡™XIûN^º‚ 'ÖxtïäñvZgê¡[ö°ì0ß_ÂUe†4Ã!£ ÙèÒXæWpÔ&lâ^ÃO¬WæŒ%²2¼†`?¹Ÿ&ñ|ü?C)GÒWâUPØ 8ô]/£”gâ8£§ð@ep;±› %K/¥®™âôÙÚ²yè38¯U4‡©)Äô<ÎeŸkoÙ¿ž,5Ÿ%<ÃSµ†'æê†s¦{€aûg©– «fÅYƒœ\5¨ªbV^‰š™e˜o`Å{<3çaûךlU™T̶,B¢ªûæ¸U̳¢Xªª$¬>æVµh¹xŠ0öÔczUS‚•„©¸ÂOPqgEa•OU0E„sé+©|…æO!+0‰ÜûeÔšóŠ5Dâ÷3lÄe¾`ñÎYŸÙã)®ãõÜXaF±@±Ðcê/Ô³<Â*PYÈš—ÙÞÃÅ“L¹4ØÔ0¶ˆeBŸ¨–_²ûÖoaߺÄ)Jé9…w‚ÂJZÅôzZz©ÿ:£—ÒÜGúäzI.#µŠB­!¹ÀE9¨ÅØ[MT'¬HmÔ/0=ˆ•F8šÏF\fL7¢¤yÐc‰à6exÞçé2×:´I+&¾›ÇØ U²ÜAjÁ'ÇQšëê"ºX$æñˆ ›êk–,I½†œ‡SJðR¾&!%ÀlľB‚ ¡x{ –à©R`${+ —¦¹2M öW’ç}Šûë9£Õ/FÜäâJfᨠ yÅK‚]‚²4ïÑDWbºS镨,~@t9Îa*‡)¼†§ÉŽQÚLý fnfÁqf2Ù%ß‚ÕCzŠé6R!¥$rˆá6.Qމ%ôU˜m$]âŒBO³w%›³¬'ea “†‘$uišl…§y,MŸ"— eƒŠv ¯såâ÷"û˜ø)j3Î&Ÿ'rßKÜ~rcT$Ù"¼ÙIöþ Ù„²òz,ÂнU?yË>»ÃëÝK'^àÔ “%œªÂVr^¾!qnDË‚d ¶Œ¾´=ÜÐØq1DUHÌiø,ç³æ{XsT+úuIhëši£U--$uÍÆ2ÃV ³˜UÂü†Óð‹=~(¢9z%ÏšVQ ¹¢9zeX5†e׬«9»ªÆ§ü˜R9Æw…ïRv’¦ìèÀŽBb*#ŠàÅ „FÈ,õwPù…ÝjìVÁMF> ÎG–xDË ÿÑÀŸ„ø>³Ž'¸ä [;¸w’}„ˆf.>ÉÎ..›f,O©™E»yv·áH‚ÆÑ0ÓsáÓ¼|5—ìf¨…î ²}´Ÿ¤PÄ,§õ»œx˦ wR¸Œæ½”ºH6án§œÀ¾€äa"±g?æ¢kpÛ‘£¨#>ÙÄ¡ˆ½†"¼3ÉÃO e®Sâ9É)©?&ø"¡e»…š |œâ[IŒì¥p5ɧ˜YƒÕ}‚üSŸâô]tìàôrÒ Ì"28¾–žY&#*Š -e¡ %ÆR8õÈÚNñl#¿åö(ˆc |a1ÔÆ›|žHQgÍSn4@t•¯ã/F,fâG„è ùIÉLîw3ø ™õ m#—ÇÔ¡¹à ‘OC–‹⤪v¡²yü¯°Ìcµ¯ XsÇ.Šè¹Œ%73¼“ã[q,UBOž“x˜C.»Š_q cc”…Un€å w.û^³®œåÿz•PÍÙíóŸçëÁø%ˆ¸n8G©âüö¹AaæeæGb>Å<œš/cs}³â: "ŠmõšWÚžm[Äå¿*±²Lh‡¡ô ÄqÎTÀ‡æÉl ܇eÁQÞ‰9‚œAåqo0 †òmú´¸Èæ‹«ÏËtçÆÔ¿há-~„˜e$ÍÊSlïâú“ìhçâQ†º¸ä»±~œ±A3 _`ßF.;ÄP’L# )ê²T¶1r=Ëžg|%íx„ƒs o=­ø>Ó÷Óñ$¥.ÜRÏSYŽëb?OÔ„jEi ÙŠ|ÉHWsâ`ÄS¡y¯B*³Br›Í±€ Ü™d…âˆÏÉ ­Š Š?šát…ZiU Uð#¾1ÊGûqYŸG'(ø\TÏ=DšYŸá2‘æ‰q >•O\X ´xZs¬X%ß¶MrºÇ<_°Ä9˜ ÞÖ‡¯™‹£.®'!« ëkƒÌFøð¶^"°½I\ÅÇŽb[\ÙL§K“CW‚?IJ¹¬EI-þyœ„Ãu–%y¦ÄÞˆ{ëi±ÙRfÈð¶:–Ø|¦ÂmI–Jó5#”2ïU<$LÞD7 ýÁ¥%ÚAùZ¬Õ¨'ȯÁ>La%îi ý8S‹x‹qGɯ n'/¦}'‡WÒ2ÆØZzw±k] ? ?Ãñõ\6̾z¤žå¥FÒ6º•~OP¬ca…fØ s(¹¬µ8 * ýf¼A¼ò§ 2Dõs„’¨…ÙifgðÁ42;Ê÷0~ˆ–eH0šSOâÍb*\öQ¤Œ½X"¥ÎKþÚ±3­±RàØýyò“Õm³Ò5{~¾«eWyã"¬*œmK-D¼Q鋨•Ÿsß«±¬˜|D<Žª9¬ù’PÎ=Ç8ͬxãÑœ<Œm©_“„óýõ8ÄPKZiU‹ƒJ´M(j”*öª$:öªâc[ÔrUÆ·u C-|#bÚ[Æxˆ8 `÷â´’^B¢·•Ê$Û±"’—ü‰»Ãê÷Å×j±(",²»‘O:\v^€uš–™NqÕߨ·é´äȶpq‰\„œäL=}ûÙ³ž›žåÙ~V”Ñ©tf)¤©/ŽSÜOöj–yÈŒo¢ç'Œl¦ã(•nêBÄü É4âü;ù›Èì$èÀY‚óeüÛM¢E¨G iä娑ÖÜdÌS¡˜‰¸]‘øZ‘[,Ö[ìöPÐ}ŠïÏÐkÑ)éµyd†ëëhµHÀ¿Œ²ÐbMŠÎ’O%)¸¥•´¤+4ìšáÇÃD¿»„J@_[ ɇ÷T 07vÒ–¨žÙ– -IB¢ÄùuŽ)•àðl5¬»Z[†™ RïYL£KÖg*@IvͰ7‡mó×+˜˜ Ø_à…Zñée UÈš¦ÉáÞ6J†c[ ¼±™&‹“š­ÞÞ€#Ù±3âiv¶~Û¥ Ù"Ì –Òl%ºC˜4án‘QöðÖ Qºë …åX£º­È“dûIbôzîáÔJ^aè à`Mcœ ÍB'1'رŽÍyN¦P­ôΰ[× %ðmŒÍxšÅD’Ð!tK"­°ÿ eÏÃýcf#Ï¡œ§Eè~€£ß¥")” -.ù=R ªìȲ;ÁsCh€D=· ÔÜÉŽÓŒ•z½cT8…5…hqì?ªrÒªcÕ{°ÓÕªÚì1Nü×&9koYgCUŸËƸ»º; ¶D$d(¬HÄf¼¡c‡"¾;sIwƒˆ‰˜®Æª%BS†sÁ+QÇ¡eùúÑWÉÀj´=Vy1~Yµò_,k nâÌzG¨,Ú–‰l¨HãC%L€¨@©¶˜/™bÑŽB–h?7î¥þZôv¬È¨)‘z·1‹µ>"271Zà ÁÁê×$Ùxž‹Ÿÿ&Â:Ͷ…Üú„3L×Ñ/q§˜˜!×βӜ`Íö­bí …™_Å¢CŒkìÆðVÐù0Cw°ø¥2f M( ¬5‰^Fêyüë©›An'ìÇѨ—Œy›p %#¯GžÐæ‘@ü4ƒ‘8p‡ÅxÈ7 tÀ[’ìñx|–/`G‘™?ä– ûŠŒ{<3Ãíô¸/²;Ç{»ÐšS%¦=gm†óy%Ïx‰½Yz“¼¥cCvOãJBšë»Y× D¡Ôœ¾€cDzÞùuô ˜[ËÎ-ýº:#$«›q–âÑ!vO`u RI_=iþÇ>|Ȱ´Î$})>?HŰ¡•‡5õ|âšiOЖàH‰gŠÜÖÌ—“!û|®¨cHs ä õÑì Ù”‹më\#¤Ø%¸Ô2 "|ÙèBï ´ºÑ'ñWÀ ¼>˜¢ÜHa¦)¶£ ”&™î!ÕŒP„¯0¼ˆt‘†iFºiµ©´ÒtgÒXf$b¼•&)˜Lâ[èv6x<#KcB›S)Gwœ¤\‡¸–ì(a#¢ÑÏñ-x@ž¤ãœ:„àÔ£HCǵ´oÄD˜àì5kÄ0Œ…QB[2*¬Ùívd¬PÄ|jN$žeUVì£ÇÅÄ8Ó0·þf® ÃV OçÊÀx±—™ËXÉZ@4F¨x/µ±m(Í¥@i´Š"€Gì!áS=XñÒãW’Y†mQ|ЦËÑgp¤—CL`…$–»Q¨”–ÿ‚üý€}‘é,ˆÇm.ƒE¥:ù³ôyÖþ¦D>ÃÆWxPS—¢ òsz¹¸ˆ7N¶‰Î¸ŽkeG +ˆ5,ݾëYs’\áØÉÌ},ùW†~‹¾=2$úH=Ae5©âúRÿ“ÒýÔÛF>-Ìc !þY‹¿0ò¨f*4kuš!«¹oåÙhq{’!=nNR'øÐ)~§™.‹CE¾?Æ[ÚX")xhŒ—f‹þ$ÚGo‚»Ú©WÔY®ÅR‹UMlªcíyÖþ9 â@?×De*³Ótœ`¨ž–<Áº†É.cùóº„U“ÁÚÉø,~‰‰ Éqô*šdâ ,ü%³í¤jþ4?AP@.Áy}îÓˆ3¨Fµ8©Åá1߸Zô FCV¸Öa8 pc’“Íð¡6Ëü<Ël…¿èá©äéµ¹¾‰=9¶Ž³<Å­m¼˜%ï±c’¬bªÂKÓÍR XÛÄ5¼4I¶Âl…ÁzÒÜ»/d×~ıirˆ«zØÐ‰1HÁñ,ÇgjüÛà…žDësÏxñ6V\}2\܉”Õ–k“qYÑ‚£Ó<<ˆØkÚH8Ô»,kâGÇ8]dAš¾š’Tž'Tl\€T,LñÄÁEMt§yrŠ´Mg ;fé«cy+R|fŒ+YäÛy¹´¹ì X“䃑,uØYçˆ3’“Ò¬z¯ —‹ð'xW` ái*wã Ðƒ´‹x¯0uÍ'ÈegÉ­¥u’©29CÅ¢´” ¯™ÄötPgNs ƒeM¢°YÀ&ŸÓ¸6FòL’rÒ-•^‰bž2xfKÛE t ïÀSTNÓuvø` À¡r! ÎPFJLÈÂwbeÎ&ñªÃ$Î|ko“Lm¡4T¥ZɬfŒ¦~*š(BºÉÔ³ÌîE¤©[J¢d/FP™D%Ù÷)2=NUyVœ„pAÕÀKÕ ¬†\HŒVlŒK$Z -¤A!æ¯sž ¸Ÿ»ÎYÌÃ)#ή¹‰ÔÙ˜¨V1É2Z¨(‘Á B#B0TA*ã#|ˆj®yL¬|ÈWß@ûÒÍ$êèÜÌøO踞üVœjÑþ»DÇPóKœ‹±%*ÄÊ„òH€ã™3Žx¿Ï™€r–Ž/â÷¹ä¼k'Ÿõˆš¸h/GÔ5Ò#¨ËQéby/7F¾…ö_qän6ŸÝ‹èôÓûŽü+’PÎ6 Ðý9ÆßMdzx p»q>FéCd&‡Œ¸I87æÃ(Ûˆ‡ÖSÔ"ÒtŽÌlv¨D¼TæB›QŸ“6%ÉHþbËë¹³Ûð…aîk£^²3‹±ºž‹½Y~p’úi²éLòGÛèKóæ~ê,,Á¶ä¾¥ô×c ÒƒY¾öõo_MÚ¦ÎÆØ’-‡yêJE\ÑË•ý„5 ¨õÎùfÁ¾¢F93Ørù)ž6L¶Óç±OOÚL' f]<UÇÇì”aQ”Áû/9ó©ªÊð¨zX«?"Ž Dœú"á4­7“^…TÈDíÞ`ªJ¦¤Í©Ïfçß9^ókNEiMÇý¤–£Mu§h£ÏVÛLDPàÌ·ñ¦h½•¦ËÑ¢Á¢ÙɾȒ‚QS»8õ”…Ž@øØ!°@AÄYØBƒ²†nÕdYuʹTÕëWÄ\ 4î'djfŒJ`DP{C¼EIL ˜â·yµg_H‚Ëÿ‚ÁïqÁ½Œ?CÂ%:C8Lß}¶Óq;åghX‹ÉQþ.u›q$é»Lð§$7#E$thnðÄAÁêY¾-Ychµ¹ì ßòI$Yháâ^î:Ï-’?W¤”¥¸œ+°Ï"eÑ 3È™š‹˜ZF(­¤ÿW nbÙa²SD9Ì•t=Ét3i{qu?"ÿFš¢ÜO¢„<€ùR?4Æ5€z.oâû>3¡¹FˆÑRD‹a* ÁÐ&Ø^ Y›`¨‚­é³9Vb¨ÈöðrŽ_MRªð¶¶O2Vbq’&‡áƒ³,­ãúNž%_á•,ÿu-%¶2–ÇXÝÂæn^a²HÉc¢@Ww­¤âóìI¼ñ<Ÿ0äŠ.^Hd08Í¡±³"#ˆ83‹1ç±"GàXtdj§ é’rX×…%q-þñYlE$èÌ`[X7-f8ÏÏ^Á7ô5‘pèoä•,'ó86=¤ÒÛ'X¢>Áh‰$ºÒŒû” }õô×q ÀXÈÒ Ç*(‹®4c “#í „$+X”à¡ÅF+S”b¡ÍÓ"º=%‚z´"èÀüŒÙkqN×D9 wÒ°…áŨáj29rSL7 $EAÀ/1ÚOgÀ”$§ÉºñÖµTâra†´áP­ ³9ÂK™ R•v*/S½‚ü1Jˆh¾=C0†JÐ|ÊA¤ t˜à TˆÆ0-ïAÊÚæ—”S³ Ïw ;TMÕ;O˜eæG‰Haw^‡LU± #) ÷<îÎBRK +ÈzFD0Kæ"2Eˆ4ãOàÏbgÀ`§ü÷*H95þ®øp@Õ VÌ›ç¸ ¿á÷7ó6Y‹Çqß³¹ü`,ôb`Š•Z{´9œòçI¿€ ï!Ê! d:I&!‡žÅµP>ªBª‘Çq¨_‰>€Ö4V“qŒ°Æ±ßˆïQ;*daDXbÚŽHäɵqç0Ï)ê4™UÜ_OïyJÂǰk¼Ä³ë¸ù0GB»„%²m«Æ(·ÒüsN¾K¾ÆÁ«è#¬#õÓïd`7%ØOãÿ>­Cþ¿ÐðQ¿qš„õIc>‚}ÚˆWBî„?¯ð×6F³¥ÌåŠÉÛ°P°¯L9à²Ń%Ö&9Qb¸ÌÕlø«ýljáö6”áËÇøí\ÁöqŒáâ&’’½Süðﻀ&‡f—=N_†w\€-‘°mˆGñÖ YÔˆ8’Á)þ×vêÞ})õNuÒ–lÙϳ¯œ½G½ã2zÏné§jʶ^¶â…;tí ŽÍg~A)n™'0!Ÿ½¢Odˆ ïñO!lµòÎK5|j+¸<°Ž¾”â³/ X·7,A*>ò÷¯b ‘Ãyþý8w÷³²™O‡wЛâãGùðrr†/ŒñÛí<š§Áå=m|·H(¸9Ãçò|¸…O—¹.Å+0d™ñ˜ÐwˆðI‚胔îÅú1³×c‚¥Xßcèƒt¿Ì”Ä;ÌXáe´WÈ;ZQ^N÷Nžï£Á"š`ß*Ö¦¨+p ‰™å…•C9I!MW†›5ŸH™HEZÄ‹™ãŠxEp×Óv&@‚TèãÿHæ*’ë‘êlYC(d‚±ÿV½@íVêß…´kߵι²Åk›Œ†¨Z+œù<á4¬vZþÖ¶›Ž5V„‰˜ú:Þ©Ëi¼bâʱâ•Òû8í„Ú l~„®7‘^…6èˆá‡èù­*ë)Žrä_Ñ!¤R8µÜ5 ùjªøZ–œ™^a­!c<éÍkŽí¿ ­ªTË¢²üFNïÁñYÐÏê;yùë,XÄ‚þ Kn¡u5:Oe?u Iõ’ýM— ò8>õ7!#lŒ~R8ÒXFâKÚü­'¶†X>"¤Ñb©¡I#¦x1ÅÆ!îám#ìòQ}lZú2vžaz–eÞÿ]wÚô>™Ì$™”I =¤“ E@PQ¥©»¾ï±¶UWwñ]E±±²ëº‚)ŠÔIÒ;©“:%Ó2ý™§Ýýz?Ì3ITp9ŽçÃ}Ü3Ç|xî{Îë<ÿçyþþ\õ¾Ök<ªRÔËP=SÒ\M]?Y%E8Ÿi;hS05¬&jÖÓ±Šú$M,µÀ@FÑÑ‹±¦a>‹w3Ñ—Òhq´¬TæHe¯Oa(ÇI±Óávƒ?fÈz,Ö8icI¢‚®ãT¢‚S¤ÏD“– % µ&G“ŒØÜ7wÙÙ‹ïñÁzÞê$ë29NTãÔÉ,,«ec ©ƒ>;Ÿž›[ÉÙ„Må\VÇŽ6:†|l‡ªWMÇvÙz†¡ B’Ê‚D,šÈÄŠüSßqš¡,9ç/Þ)û=—ÕâV¾C˜:Š‚/¹ê,“çØuM#ç£éDPU,ƒ¸AË ¡@¨Ä-•)¥ìíÂWˆ›:))Ðu, ¡tˆ™¨:>ä|,M'å3 ÙÝÏê: ƒW{YQET')‰›¬¡!ÆôŽ‚®ákä b’”é i²H»•`®”®%ˆX'ÉèCd®!º‰Þ)(g˜Ô|i›JBÇÖð-¼aÎN§>KŸ‰]Iy;›#Q<‹L)õÐRB½Í¶(vÇ$ʼnÈ@ q¾64f¢—!G0ë‰.‚,B¢Dp´#ÓˆsúŒ¼&šdšIq ³ä$–Á”$ý2‡,¤q€é¬©çýÑ^æ÷ÃdjhÜÉžE¬8Ì™ZêŽÑ_JÉVÎÞ¼]ôJŒÝ$?Íô‡i½Šêd c ñÇHÞFÉ<}á½2ú°›¤y3ê|ñ5Á3Riñiq¸Nç_™¡ps”—FXaÑãòÛ.¾?ž-I<ŸEq†Ne˜› %Åcg¸¢Œåå|s˪¹º!ùú[|aE:{ºyá(÷Îe\œÃ½<{”˜K‰ETã+/Q_§æ!Cì8ë‡)‹qß2t-}üömr|÷ØîXÇ^ÜÇžÓçËö·‚ÂÍ ˜1.?ø‹ít¥XÖÈ•ÓPUÞna}3_¸‚¢»»yñ8(üà*~z€– SËøDjáHŠï,àÅ.Ndøôvój??¼”üÚÇW&ó½v>[OÌàgƒD ÊL:Nð[—ÏðËuQ^‚« ¹A —Iÿ˜°\ J€×„x–ƒ`z Át¯p|*Ñvº­|ÀʳÒÚª)÷é ämMÈYä ˜É6 'ε–üðGíãÆD«²¯ Fòš”»‡Ì Ü‹^3ÆŠ‘(¡ã¬ÃÝŠ¹ }5øRM‹±†¬|ÖyÙ]^7—c·å›Q ‚f질þ¢<ÿ ¡ÈG4©1ð¯D»ÐËýÙí$>×¹„ÆàKØ]TÞM %¹vr§)^Kè#uN|›ŠˆOG*ý3¾†›ÃËÑýã>€ø´mdü5“7¾ÊÊïáäéc÷£MbÁ§xæ+ÔÏfÚ5¼ùR)VÞÃú_\P²Â1M=»M¯îú/þ˜KR\BÛNìN4˜y¦qÃ'iû3³ï"{š\3Ó>Mß+8û¨X‰jSy=½÷SyÞÌtMª{…^€õ))^õ¹6#Õù\ŽÝ>ª‡á¢ÆXÝ£||ˆS>jœY2’H?Ý &4±´ü}–„oòÚi:40ÓH0]ÔZªp“ÈA-¥½i)±\¨!>°”ø¼YXÇQ ¤Ô¦"Þvù ò)O¬„Í6ã æˆÌ1ÙœbÁ4JÀõE<ÞÃ̦X¡ÊàÄÕ:«ÊÙÛÏéaj-:û{Ð%w_ÂïãzL.dq-/43˜ÁÌ©äD?ƒiLATej%»Ûð=,ò¡9dÖ"çbª(’Æ æNDƒ_oF 1Tè †Ê ñ¼|wïñ·04ø¾ÿžÿ†~a@tô=_9ƒÊ"þ¸ ]C(ø!N€±$³ëé"ãâI²†¢b¨%(¢ )èv*ª†®‚ ††ª"4²!º†ªbƒ®£(¸U#nÒæÐç3»˜Œ ªã)t™'§à(Ä öz¬(`½Ëõ v*ÌÔ8¨1[ã„ðfìÃ^†8AÆ &ÁYJt7çPúI^Fb„”Šcæ—6rµD;i+GKq6Šo‘1p+)×I«dÎZØ&Ù(Y?B.*“áI‘˰"«aÕ@›€>ᢚØÃ(ŠTçe"Â](&áAÂÃ(*”€H–]4Çpž+Þ]·ºp{´Ww¾c(÷@'!H)µ¨K m Gç†ñ·ø„ÑÛ ³„>2Fî &‘•H 'õ 5 } s’ÌÔbâ—ã§Inõ)»©“ídx¥k!Š3ÀÀnÊWÁÐq’§©\Z@×jWâCË«Hú5dh^ÏÜ»èo¡m7“¯Dì~šÅw0p{„êl–²IÔL£íÕô÷rt7‹½Y¹†î#¦¶‘âb ð0ª®ÕÁÅP°Tp±4LÅGh–…êb¨h`H UªHÅó…å8…Ñó»ß.a1k;Ø$)òÑ]biذ€µ“¸ô}¬§y&NéÞYœ2B¬™!µ€D)‰·è-#QA¢ˆèVFRºè%Sˆüûâ/.ƪ _¼êË!ÊðOŒpk„V‡_°ÐàêOðñ"^îguüà÷ObënãŽñ«<|«ÇQeñ›#¬­eq­IÚ’¬­Ãó¹=_¾œ„Á®v^:Èg–PG¼p˜tŽ;`{ø>¾Åìq\Ù„í¢ ¾õg\›Å“¹a>¶‡ ؆w”ÅùâMx>A@"Cü?–TŸ/C6qã2¼àݤ+ŸG^¢wø¢ƒ}ô"ä»pü1d“B,—‹ˆÉÝWRšÈ÷†~¶‰¾ w¯ ¦Uã­S¼~˜ÅÓ¸öRT•ù3s'sÓLt¯¾Ì‹¨.ä‘$=>8¦r¾»ƒÕL.æÑ“¬¬eó %>3•§;9nsßDíbm%;²D LúT®/äwY>_ÌC6˜¨WZl,1ä>éÜ&ä³d œyˆYˆ(á³ô.ÇÜG¯‰ÃÖpM\ {̵ÉÑp"ä¦ÑpŽÃ)ÏÂŽbë¸2QrnŒ¬‰maÇÈDB'Ÿ[…UX÷ hPB‚][0>‡bæAOBA>/Ù‡|)ÂQDBHéKôü<‰"E¨0Gã&þnd4”©ÜðŠ‚ RÁÜ,˜R ž_!F‚ÔëÛ‘µ¨Ÿ”R¡‚”H9„ýc" Ýü TèzˆÄ7¡‚ÔɾF‘Õù­¾ä:â+ uPp‡Ií¢øZ|»Á TÞNâæ>@ñbÐéÜ@´ŽèD:·P>5N×ú›™v'gèÚKÓ­(ë¿Éå_Åu8º‘é×°ãiæÝŒb°#ŵTNá?°ôV†z(«àŹd E%´¼ÅÒã'Iž&bÑ¿•òF¦ÞÈ™ßP<‘Òit>ʸ«)šKúM¬ÎFªþç÷Dç¡¥¤áaÌ“ŒØâ))¯ô„)¸¢Ÿª,;¿JéàÐÚȧ»8袴qf2«|•øÚ¯áC•Ô¼¯€õ/ŒàO¡q3ÇU¢*f E­ØŠA¤žÂ}dC°j±NÖc¥¥sHŠ8z¥Ú¹Ýg²`GŽëuÏ0>¤ÃEø,5ÉœÎ2ÛbG’BI¿ƒçñ±j~ßF…Êü" "}–rj˜Žæ•2l³»‹KK‰jì9K¹É”õ¶)3YXÇîvÎ%)³˜Y‹*Øpˆ¸AT£¦!ØyER[„¡0o=ƒl=FPWŠ"‰[ÌŸŒãñ§-¨×¥ J܈èH(°˜×4Ö7W8ÖÆ¶Ãhê_ÛêªÆRG×xmç…°%r.=C(Z~:Ô— ¸çFPTP¨,DÓèMáD)‰“r²Ù{Š[–0èÐáhYBg[R™À‘d%ÛÛ¸áºZ2¬¬¥Å¦:Ž®ñö q #lN²¢œ6—0 ‰š¸*'|–²Þææ"B™Á•Bãš\¦m¸ãð^+Yp4r+ˆô’ŠáV¢´ÓW1“œŽ?Bow´ôÓÉX¸4ôs(Š!;Šî­£äF ¢dÌÀljNG»ŽI5*ÄJ”@¢!\)ß"ªˆyñ$FˆNÈ$¥RÆ1Q¡A"%®D€"1ÇFÀ•3>Ûø çpñW”¨±c%PhRY0š× Gäs\U $‡ œU™'h`+R]ÊõBÚÈ@¨×ú„xø› ѯ'PÀÄ?…w eÚtSdßÀ\€(EFÉnÆK[4IïÇî¢ä<›ä6rýTÞBÒ÷6Z)…óèz%AáLúö" ÊÒ±;MýÕtí£s?s?KÛ.zŽ0õ†»P#ĪÙýGª¦S:‘ã;˜}{ד!t¨©ÃI¢z“ë&¢aE1BEÈ,~/E5ˆj†ø8&³‘¢)¨ƒÌF )CM£«ÒP%`ºÔd\ %ʵ¼ŒÑY=Lˆ§ )°$YÒ¦ƒ ˆ-añtf¼¯€õ¯ âeàfý™“ÕÛ¨3¨\Gß ª_að*ß"·€Âï1üyÊ·à/#ò;äMͨ§+±Ós?M‹/™ü0ÉGs ;Ü_Â×;¸¯”#)\kй¿™E,Hðß'xh&&ksO#Ï2»„ñžn¦±%U¬;ɶS<°†ã}<¾Ÿ;gR›àN^8ÀÇçÓXÊ÷r¤…ÞÆH†—°ï _½‘dš³ý<õ6÷­a\)é,„<½™–.¦×ññ+Ig‘#{•L._~öF bøÈ|¶Õ3À㯎I2¿ ÿ÷Y}ËWïд ŒDŒß½Æ±v„BàñÍ{ðG _ÿª‰¦qçÊ yìMº“H…å3˜^Ç#›ÿt5Qöw²éŸ^NÊåçÛI$¸gÛ:ØÙÉ7¯äÌOž`Õ^k‹¯/à=,Ÿ@ËI›»'óËÖV±#M…a’¬)áÉ4ÿ·ŒÿÈry‚]!Ë¢Ø*%:” 'ܕȎIx–Œ…“ÆÑ°M O!Áµp,rþLÊÚ9®çµ*{”0yÞš×Ä’±°#زvDæb"£9!ÚjÄåR ñCÔïkâ»!™) %ÒãñŒÁ]P ÈONz\v8ì’¨E|CâŒ!ƒý‹8v‚¿kÊp¾XÑD>±‘áÉ€V ø A(ò“JÀ®€uÿ¢äýZÈÏ#*wB RšKª„XŒÔcd¿Š¨Äø$Ò$Œ0øÏü”"#Œüc6Z#è ½ŠÕ„V qN™Š»0êiû)5·C ©ãç`t…9‹ˆ ¾‡TÈ3ÜFÅÎg¤‹‰W³îë\q?!|… Ë8{”òI„°ñÈ,ADA ˆ˜Õ'"ò§CÜB±±ÕÅ‚ _#û:‘8¢í,‰[aF"P [6û¢Då£YvyX ÓûxÎ`©Gèæq`±GÙ4™ëZ9YÉôCìq0«™E™Ê¤ÅïStÿð"œf°‚Ša€î¢?]Eü$^ ±.XKâ%ü2ôV”:i¶"IUHÑâÊz)vØÜnð«®Ò9ç3b³:Æ“ý|¢ˆW†ˆ$]Τ¹©Œ‡®4×Uòã\gE%ëÚ¨4hM2œen )†³L) ©”?¦©”‰E¼ÓÉ©sÌ­eIŽÒŸdB 'ò“ [4–S§¾Œÿ^Ǽ ÈÉUì=EÏ “ê"t•q¥…uÛ! ¥®Chª'áOop]*K(/ʧ¿{#ü=ÚÌBu°=Ú{Æ' k)Œç)L#6§ºPTü˦Ht#ä|¦Ô±ÊÒDÕ™RaðN#,ŸÆánTYµt¤9ÐKMUE´¦éL³|{û¹¢œä…3Ü9‹—»™Z:ûRÌ/åˆÍìbÚ}jcœƒIi”f—9…HÝ¢PÇÓIáÕo[»@¼u¢x:N„œ‰gù D°5<ƒLgL\¿`!%%s>ò°G/¢dM—âk’í!HWÄ” …?‘Ô &hL qm^pU1“™!žD‚.1@$ù ˜£!Ç¢iôG&Í\¾ûC»øéyô¹t‰¼7>Ý’$„1®Ô¨[€‚æÓÒÙ€6ƒ©: i<Ÿ£‚•ù*Å[%il¬U¨C†ÈNüíBûa(C_øñva~`ˆ0 ÷&ÚT”ñø.ÙMh“Чáû D7‘*Œ#Š“Êa”…ªï Õ£* ´é ©ñ08hr©GA€6F‘V²ä¢LèãœFù¹Bª=´ ®$º’SÿFt×Þõ”ñÑ=¨¡ Cj"e» ÑÁ¨!¶§£«ë-¼ 8оHUB›ú†/æJ÷AF~ IDAT³å•ˆgsÄ=~•eئ/ ýÜSÌWÎp]ÿ|œZ—±c„OU±¹7`~ߨM]„ùÅ|e3³JX<žm§ùü|Î¥hïgy5Q•Í´vñ±é¼y‚æNþñrR6<‡©ð©eø>¿ˆ*ùÈr’)NtòóøÈrÆ—£À[ûÙuEð­»A]Gxs7ºÊ„jnZJ*×㉗hëÃõåøÁ?“Îb;ï6çÂßó›8¯^õô³yûØ…@2³† ¤ bñÍÿÀ*ÍÓ¶o[‰¦qÿOЊ‰DX2™òbúOq¢•ªrÆÏàhÇZ¨*å¶¥<€34T±ñ(]iæ6 %ŽRVÌÍÓxü(wΦ²€ïnç«Ëyp'+9›â¬Çm<ÑÉêjv Q¡Óæœ$%iŠ1¤rÚaÄçk%<Ð 5‰T^Så*L1-Jôyú/#¡av’L“3Ǿ…PC†+ñLÔüæZžf9Š[µ] ¤ôÅíRŠËBF|qN²_gUH>#q]zÓˆ³2Ä Ñn’ñqzø¯VÅ™àK<‰ˆpûyCÉ€ !vφŒ>B¾·5èÚej‚¹!¾‰Ô¹D  dˆtñ„BLÁ8ËâÌ·˜ª 4–J¤‡§R˜eÍŽ8T˜‘0¤Åá‹5>­T!N…âŒjܨȜPu¡lE‹aÞE˜DDñ^ 1Š â8ÿNÑg #xÇÉ>KÕ mÜMT¬BšH‹á 4Ü=ÀÈjW¢–sòûŒÿ$"†3DÙLšÿ›†›Q h[G `CûhZbK­ååûYõ%ZÞ&—¤gºK‡Ë¸Éèj Å'Q‹}–äÌK’„DV`·"ÚÑjQ|ô8ZPwKµÆÒ—ŠÕ’\†ý“Ù_Ä­]¬7™ zh>†C8Hº„²~Δ3®—Ár Ô!’EéïòŒÞ5Ãú [ûñ;p'S¾T …ª¦ =†ÅèF½”h³”ÖIZªº/ëC±Óe4;ÌT(’ìϲÈä\gÝ‹¢ôä(W°ï 1Åâs¬,¡#M[’ETEiî§.‚ãsz€©E¬;IS•QöuPfR_ÈÜq|÷¦•S[ÀÎS”D¹´š’/íe|ãJÉfÙÑŒs'P§s€ÃgˆÌŒ"™=…ï=†¥a¨ÌŸ†eøT”òä+(`çX³U *„5ÔUóŸsÉ÷í7!þ"`&˜7c i) ï§oü,Ç ‘’wN1˜Æ‡k!TÚz9щTÑ5VÍæðY¶ñá%¬?DwŠY ̙ȳû™>Žñålv-2dr=Ϭ£¥ßçŠ%”!C‡[±íüÔ‚ï1{MSƒ÷UŸ~%.t †Ù´%_r¤²äúXs“P4ÞÚŹ!†Ò,¸„9ÓQ4ö5s¼MçCWb<»™ö>¦Obá 6ì£{„®Ä²øón2|ú*žÙÃ`? çГ¡­‡µ 8ÜK.d~zùè,~u˜ŒÇ¸r:²”Ðïq×¥üª•¥ÕìIá((÷Ôóhñi…ÏUñ“ô×iŒK'ÔÀÂ1ón(Θ f.’Çx_×G5õóMÀ¹Ñ ËÂŽ’‹‘6q¢¤L ù¿M»CKœ…!ª ÞÍo‰".×( ñš‡x§Œå&å’P"‘>ö sZÁ*g¾NL'Ž"énçÍP‚‚YA“‚Ê»ÁÎßMtœ°u§¬aau£ýG‘·À‘¦+M«MO„âjVnë©(>i‡îaöÔsWȈ@Jr.=)¶WsdA@ŸÃÒS~HOÀi‹U nHÑY¥  Ù%Å:Ï(¤…ÜE°WˆÿCèâï%e)Þ1ÜVŒ+°âa]‰}Š‘ÍÝIö$}¢êK´?Bý?‘ çU¢ÓN’øº¶Sw#}DÊpN¿A´½ˆ£O3óÜ~œq3I$¢ ¤‰(Cͨ#1…ôÓ”.&6‹ð(–Ž>ªƒ®¼Âm +M_@ÂdQŠVSe\ï4ú¨>F?ƒì¦¿”F¸‡ÑNj|´>r Н¤±‰ò÷•a¨>"DéEéÄ÷ÑtЪ‡"jRh§æÝ91º*)m0Ñ|4ÀEQÁ%éòd—Åyø$ªƒï#„>š"s¨16ž&—F„äÒ|u9¯g×I>5Ÿþ$ûO³°3=l9Ħ#œÒÆ‚GÖñµ[ÉæØs”wŽ€GTÇuð³H©çɌқûn"g£i|ÿ¿ DÈô‰Ô–ẈB°‘6„È©Y2—¡‹§Ÿÿ·bP^4ö.¬}"”×äoÎkbî­)9ÓBk ‘( ¦2:ºÎ"RKUËúüì9â1®˜CÓDþôªÆe“¨(ä¡ÇX²˜é <ò2³¦r× ^â4–Ó8Hs;'r¥Aq€—`nœ’0ÃÀ9Z‡èªbF%S$ÒÆ“ˆÕqÃz%È2$ÿ {ž)ü7)$²ŒeúØc l¦#ô¶²S4°0Îü¢‚Ð&TÑt¬Cáàćح FX¤ Pûx²ˆ:˧ÊH ü@Õ®á ‚_"a^OîAÌ%D–âBKQqÙýˆ>&ÜO÷·©¿Òd^gÜUôoÁšLÉRrýÔ¯DÑè]Ǥ»9ô“î ç Ì¿‹­?dÉt¾€*QA…Ú[pvP¼y–ÜKTüüõ8?ÈJ¢F|Y`‹'`Mˆ`D"!Jˆb‚î¤ÕC³1¢ŒW‰Ïâ’#´\pœUÔÊi†Ö¾ÿÝ3¬osøá6ìIŒ VqÐzP"î$±^†%Âè”kvûâˆCqÀxIQÀ…?3Uc×3u¶pK)¯žãžjÞîc‚AÂþò| u1…Íí|m>ûºñ]šŠùÑîšÍov1£Œ+YwˆÁ$w.fó1ú‡¹n»Nrð w­BH^ÙE{_¸™_¾H:ô:VÌDUøñãL®åÊˈ˜:ß{KãúÕ”ðÒFzðlîþ(º ’¶v6lÎÛ¹ELn¼–h$ÿ:Ÿíàµ×GËCyZäÝ"×_¤TÄè·-%©>¾ð•üP4ÿù5B!d)¯ã“·Ñ7ÈóðBÒ=|嫨6Ó Â÷®ß­*<¿Õ#Â&ãã)ÐÁÑ,#ÅTLâ2\©@ˆo“JÑ9ȉY|< ¾6ƒ=ìøãY­£)¡£—M,,dŠOÜ~^¨ã>H üû Y­8ìT)³˜ àºìVI4B{ÀcßQdRˆõ‚YЬÀ{Y¨ xoâ¡~{ÁÚe ýœâoátÓ÷?ßCòm´ÌKéyµ½ŠÖ?Òt?û¾Åœoqê9¬ÌJŽ¿À%w°ïÛ”VP4ݦj ÿIaô5¨ø(™Ç(YNd®”[„U(Ã#!kÓ¼`cØè.e.JšI©™BÔZLó.jzHNev#Z µ›8é Ъ(_Ÿ«Þg—PE?Bê:ªöá(˜šƒ6ËG$¥"„¦†Šá‹d>U>z!^Ȱ‚僠ÈGBqHÎ%Èñó“̈‘Us’6‘á@ì>ËþfU0”¡D!¥ÖBNc„ĆFP|LI2…ð(TÉæð=LI‘Îà0qUG N¢@±%H§9ÕÞ”Çò‰[2ÀR(4 •DU $ð(¶!H ôž“_ ª‹ñ<ü|³ˆ¿;Ñ . 2€a é¨*+oex ?Íð̳¤úhhÂ0‰Æ˜{†Éÿ/ÇÄÉDbÌ[KK+O?FÓb ™9ß¿D.ÇU+i¨ãÅ­Ä¢L«ç̓üÇÓ¬œKk?ÿù çp¦­‡()åíw(©àî¥üj'Ë8p޽ÁåÓèÌqÅ%¼Þ™çÇx¿j‹I%,,版ü5Àà¾Ï…l @—(BÏËRá˜D•·-8/Ni—ë¼U¼Qkrl-«T4º=}œ(a^1× q¢íeÌ)`B·;¤³y< M"n· r6C²ªÁ8V‡Èºhd` kd@à”0µ„&}tâ“ëæô¨0¯c\ÊLí¢±ñn-ß±Íh)Ífp4½*§*F Âq,ÑÑAæ@DÏrª—ŽF9µ&Mfn×ÀjeßÝuL¯æj M º84ÌéZæÖq¯À¡?Ik‚’rîvñ3œõI[ÄâÜÂ0Û, êB´~~UÀ •ÒÞ6©1x ´Åvƒ%ª¬sÅ ã&EF¯m*Á$ÜGˆ®%(À?@å—ðzw2îK$_£ôr”ñtJ"ÂÁã¼¶™Àåßþ‘=yù5fLåÆ5ø>AÀS¦¿[?He9†ÆŠçB(C_Ü{ñ(H™Nó³G0òpd©(R×åŠbúôó_ÔÿÒ]¸Ñ4ñÖ[òÀE8Ž@àÂw¹õ6&L@7äÏ%r©4a†O~†êNžaÝëdGÐ|óË|ç§„‚\†{oç™õ¤|›5W°í™ÿt?}×cÕBNöÐÑÏÇ×rºŸa›ªR¶œÆ—$ Iy˜QP-ÂQ;Q“^Ê«] û`bE°•1¹q㫚,/æMÿ"gv3´D^´ͰÎ7Ç´ª‹{NŒÌèEœL„œE6ŠéâLà6‰¢ŽÐÕÃ;\¢*XŠR§2DÌfÞ²(ªe†@ @`œ`¿„ñLÕ0A•H¦a½ÎKuõÕÔ¨hºÌ;®ä§umœ=ìu/à þÊdTþ%Ë:”ÈYÌ,¥„ü>ÕèÆp~Š.$pq4Ô]¼=‰iµŒ„!ž‚pÈ qî,ÍÓ˜_BEˆ«‚C&I§†YÉ„;Ä ±‡i©f¶ÀóH{ x¤Ê¹DàŽplˆÕ¬ŽR9ÈÍ |A2’fKŒ™:Q/ÉÏ ù¨†aóDŒ{Tr.›|H“e‚}‚K„oH|dT92?Çü~¢?ËÐsÞÅÀ“ˆ ´qtþ–†9úu¦=Hûóè•D&pâq&ÞNëˤ CT¬!ý,µŸ$õkbq´4QH| ñF %l1èÐ'ø„Í)}˜ÅZ' ÐÆÊ ¨”¤ºé`ºXÀ›Hcˆ5Žª·ép°*(è…¯0} ‰÷°¾AK7²mæÓøÓ°2åÒÔ„Ú(ížX‚Ç€CÊGw¯²w„ý9¦¡Jåè½iæÄiŠÓ—Áóhˆ°µƒ¥•li¡©”d†í-Ü0•½-Ô&  »Ÿ%“x§ß¡¶˜ön&VÕ9x’q¥Xœh¥²ÊbÀ³™\GQ”]9y˜E‹(ˆÐÒFè³xHÚÛ8vœ¾³Ü~'®ÍñãdÓœx‡[oGS9v”\–ÀCUä±cò“Ÿ¶#Ҳؽ;t])ò¯½lm•Ž#ï¼SwœÿÅGUyî¹0“ A*ÕÕBJ‰Ñ¨ÒØ(…ßü3.•š.ÊÊ©«…ß<ŠYÆÌ™Lšˆëóìo™»†‚zhÞËìTWÒÑÇ¡S\±'`Ë–-&ë³ïÓ™ÖÀs[¨¬á\šê2RYÉÄJN P]Aw’ª z= c4”³ÿܘE•FM1}!ž:˜ÎÛ½˜} ˆ ¨~Dœ§,¸V~±fTtÏZ8£*ûùÉõ(Ù) 'ˆNªúz>èt³¯”©: žfW«l‰ÚK{/çªi(¤R §Iµq&‡»ˆå^€È’bh€áfФ ùHÄ0ÉÒ#Ø#d$ÊJf{!ÂÇ3hÊMD¼÷üÜùévB‚Ñ@@CQYrû8®B£”‚ žq! 4Ð:é>K[-•qbÅ”@ !2$Or¨†qV!¥2ÀéàxŒX U:ú §A…T…d»Ø^ÉŒ’ìû‹™nƒ‘A¶—2Ϥ²)6q…¤Ûå`”…:ÑOǸAaØg‡Ád©¡ü©Æ*vØR¬öóPMÃkF[ËðcÄn%׆Ÿ%¶šîG(»³?¦ð¤Ûñ<âséÝAáLNÿ’≨CÄ‹°D±* q‚X FÆlW ]jBj‡y) ÁF±±BªmÜ Ó¤sã¤mÂ_â’,ØÓÂ×ñÝ×ùú ÙMS1×Lâß^áß×ðæ vŸæ—óí'¸ï¢¿ØÀ•3Øг=|d ';Ø{+ɰó ãËøøÕüáeΜáÛŸÇuxêE¢&7\¦ð¯ß¸v ó.%â?F×¹óãT–c™üë7PU©*Üò$HË’ÿú¯2ŠLCVUqコï_XÎð}¾÷½Ü{0ßþB ¹í6câÄ ÎΞÇ~à›¦ð}áû ˆ/Y‰Å”‡&—®G<ð=ö½Ãs댾õuþåŸå+¸f5ÿþ_ØY-&™ãØ)fL§/Eï³/E3Ùs„‰nqùL6ä–ËyfÆQ[ƉAî]ʯC,OÝýL,##8\¤X™©aY,KjŠ{¾ëgâXùq*/B66–[~â¤-œéiƒìxfT0¿›# ÓÆQÞpp'³L'¡ÙÎËsX%ó`í$ÇÇӠ䜚Šþ¯Œ§~SB(ÍÅßʾzjk¨ÐÑÆ¼Fñ£Š@ù[5ôæB&«(£KMþ7¢°Èc„B?o„%”whía¨k%³Â<2&mAxx rG+)JC€;:.›!½wЉÎanˆKî0ûu¼ÿÏÞ{ÇÙuÕçÞßµv?ezÑŒ¦ªW˲dÉE¶åŽ+1Ç`Jòâ@H!!Ò¹¹¹i¼àŠÁ8bŠ»±‘eËê²zµé}æ´]׺œ3’ìØÁï}oîMnæùlíÏÚûÌÌGg~ýüžõ[ëw)×)Ar–#V Ý¥ G8ØÊ*I ÑûšXfb¨Ó<6w*ÆyÂÀïàçÆKì©árA4ÎßÍá74c!/{\¦9’ðH†?A?#…g°R$'Ñ‘PuD;0n$ÿO¸ï#÷º9Ÿ‘hú<§~›ŽÏ1ôCd=Þ2N|‰Îû9óMW1ôþÞŠ_ð)Fÿ”¸P÷»è'q_Uf¯„ L~¹ÈÁˆºˆÔ§ Ú‡9™)á±4ÙFŒ] pÜw©p}Ü<Ö\ꦱZ¨š@~‚yKH¿%Âú“>bÞ~â£cQÔ2QâjØ›P­™ŽYeÒÑP-¨TIŽä©3ÈD }l°ILW†c¬oâÅ^.ªgß‹£Ãܸg1¯ŽŽZ¶ž 1C¾D²n'è寋ÙÛÃÄ4kÑ?©>®[K®ÀάZLC On¬ZBqð*áÖëPŠCGéëö¸zqÄÎ]äshcqõ5:IxõU=>®ÊÖxs3Ë———ä§XÔ¯¼’HùÃq„Ö¼¹ßÎ9jSê¼ o\{­Ç"Ÿ×ûöi D’ˆ«¯¶-9vÃÀhžÃ’ÅìÙ‹R(qÓµì9Àt?䯫xqæupvˆ æÊÕ¼¼óæ28‰mcYLHÀ4‰4–U©) "c£åÌJá¢R>EH„1s²¼É öæù„Ô†ˆËV̙Ԫ™À¸\Õ®œ³n[Dçò×I Ë‹³ŽÓŸ¥^b Ì•c¼Šz…ÖȳôÔÒ˜¡Jƒy’SÍ4Ù8å°ÎÀšdZ@š”>¿x¨1Ää(¹%ÌUçÇþ*ù&&ŸbT£5ÂDvPkük¥Ÿ_sG'( “›)æ­çR[W.õu!¯iÔ  D;M6¦&™©¦%Æ™ª£FBùd‘Â8ãsi3‘ŠÔ0ýªª¨ÖÄÁ8½õ̵p$Œp¢†96ž@Or¼žeŠÀgÐ¥ÁÀ$SìɲÈÀ,q$Í ˆKìrY¨Ék¦–j5& „VZl•ú ¡ ëQg ƒ®G ;O`.$8‰ÕAœ#šÀlar+u72¶¯¹£Ø&¦[O|ÓÂíDLÁ¦‰)µÌ(Ý^B‚ IDAT”ˆbLSJ°âJñW+ÍüIκ4'ÈÅz:§™RˆrA ™!}б …&è FÃ8±ÂhÁYHê-Ö,f1‹Yü;„œ½³˜Å,f k³˜Å,f k³˜Å,aÍb³˜Å,aÍb³˜Å,aÍb³˜%¬YÌb³˜%¬YÌâ?8ÎU™Åÿ!˜³—`³ø×JÌÌd˜ì#,Ò³™º6²Í´\4{yf k³ø÷ÄSB°óoØó SLŽQL(‰šR´vÑÐÉE÷²ø^¤ý7‹ÌNÍ™Å,^K4~J1´‰¾søQê¯Á®aô,Úfø,‘I×ìø NˆsÁò;kÞGÃjš¯ÃiÀÌ`dg)l–°f1‹3¨€±G«™þŸĘu î!»á2ve3Ú‹Îrà<ÓÇ4¤Á¾`_;‡T†T5íŸÄ]ˆ»j–¹f k³øŸRå…+ëîÑ>ñ)rßdòy&÷ «(•(Eľ"ˆ ñQPA‚Î2]`íýßFß«˜1^Œ¤À¤gç)‹¯4Ô¿»‹ÔÏ#›4¶ =³òVeæYÌÖ,fñƈù‰dD$'…:‰¿›d>Á¢Fb“üQÄ"¬.¦ŽÈjFŽ’Z(‹Þ}„‚3gÉ6“÷)N‘†Ì 1¹¦²V”7³OÍ0—énì´²Ú}#b™ÅÛ^Ϥ³øwHX¯»7šXQRAi0¨2H]PÎaöFÎâÿ×3–¡-òϰÓÄ2Ùgé2Ñ:y—ÈãÝø'ñcÜšñxbòCL2•#„È$ÔxÝø’y·°ï‡Xsh]ųO¦LFà@Rœ×\å Ñ;ÏhÚF”ËÏ YÒF$‹÷(Zëùl‰5{ÿ})¬#Óœ0c|Ï`ûu¹B17Ë¥cmå>…zV9TÏÒÖ,þ'xÊg$ÇÑqOÓšç‰45‚‘­&¡¡Ç¡ -Dø Émø¶LD,ǹ˜ÑWˆ\d=Å"fÊbü,C1š(Å žaî•LŒ1pšá\e׺…U–Z©‘ua#UYoíá 7ÔVQØ>¶’KlÁhnä:pæ°nöžþÖ¿¤•˜ˆÊÚØIBp„'ŽòM‡8CÉ#H¦)\Áò×+´"ÝË#sùùý|­“»ú9èÑVÃüe¼­üÇÏÒ˜¥°Y\ø(…90ÊÁ~žÌR›%]Eç04°¨ÄsV Ë"òè¶(˜LÝIñÛ‚÷œ$Œ1odêi&·á\Ïð&üˆÈ!‚ÊPgw£kî¥rš;~‡ý›Y±ü ÈÎH*÷ÍuNa•}®‡K§PR…WÒ^$¬"^ˆà”H·ˆÙnÖx Ø¡A %`¾V…ýçéÿ‹Ö)úÑ$ボv`€ƒ*âLÌp ?M˜%tÉ¥Èyt[´iêr e¸*d*$åL+7ôðRo› /Eû)öÏeå~vÖÑáQŸ¦¶9!jóg»ë,€C‰(ŒÒ—g0`ÀÅ´P:`(¦w.+S±ŒyX‘AMlb¸ú„Œo z¿•Ø"w½ s {02ü<öj†÷P ð–⇸ Øós/¥ï ¢žæ‹xþ‡\q±å ¡çy’¨º@^efüøsƼƒö8(G„ÒöqJÚ „â̬wîø¸V3Àö1J85YÚd+‹Bô .NÐÍ4Vÿ‹µÏÿsÖ¶FŸ+Ey®ñ]¶{ˆ˜dÌ!Lã[„M”®Ôw @VÜÏÖY|7›¿Aîùc’9ó?” oGþ™4ت2nxNj¹è/m!Rà‘Ò—N€`IEX%<7¦¬¼ìò™ËÇ ±Ëv‚`Ø!òN® H<¼,21äå2ß°wüGÔeo@X寱“)bŒÒq¦LTBt˜! ]¢ÐËCè¤I\—Ø#(×}² Ê¥ëÒÊÕ€3<¦]æ´Ç(è²X0É.A dG9”å¢?B2ÒÆ¥1JáN2©½ /gí.Ρmœ¢GU„l¡nŠdš0Mzcë™;‹¨IãĈõTÍzöÿ7ñÔI “„‚ãŒ)Âã O06¯™‚Ýì[É\a>áš$‘Mè‚¢ è5ð6²Î¤dpÚ!2‘ŽîwÅjâ…ßHÒHTEá…>ô<(Œà^NÏÓD»€ñA|“ÑI|¨í aq ž/J’ªaÞuÒ"*Ò·r ¿ˆ½Æw/ðé½Ê0¢Nf l7Ô¶/Ün„] p"ì;Ä)V„à„•"ÇvùLcXEÌs>-ŽB‚µ€z+Ft‘i%¥z Uÿ±^Woª°îaûSå‚(6‘AlÚ„6Q¹¯Mè¸øI¹ ¦‹Ÿ¦`¹øå:šn¥:yVj‹¡®À±av4òÎiKD \æ G![ÍÂý¼P€5Ü|†3²“ùO°ùz®ÝÇ©z³T™XßbϽ\ºƒá,©VꞤï:^bb%µ6Î×ûÍSˆÈ\„3Ûùÿƒâ‹ŒÚ$Ðw+Uyü¦CJU$ I½ »„u°žÅ[x¥‹ÆˆéeÌïå°‹b¯…rñmòËyGž~-+'yØAfh³)” ^ðˆ KB(¾ûr†¿ÉÔÉÊk)Óƒd.¥÷e¦òä`ý'ØûÖ|• /¨ü ÙñJ!¨|TQ^3ÖÕ¹D‡ #Dí Rhá[Ò®¯=_¸f /Äp¼+À.‡Š¶c–ãÇ#À‰1Cœ+ÄL°B¬h¦Q®˜`$˜1f‚qn¯!â7™ë£5RC ÷QÝôoóïbÎ[ ?ÌL–ë5Y„±Eèâ[D6‘C`z”,"’‹®pŠ’ƒŸ"ï9¬–Ô%¤B,IgH¾Èh‚)iK±hˆ&sŒÍÇÙQÃÂÁ8Ź,6ñö²¿¶9Hî"–‘«¡z€B€8Eájæ=ÉÙ…4Ž“ £WP³‹â2‡‰‘nÁ}ÿ ¼—I|ÌK°‹Úx‡0J­ÄårVqý;xs¾6ë{”´êI?ÉÑ|ˆªÐ.¡ yŠøK±%‘‡Š ,bmâûä3È zˆ4Lpêb–N¥Yh޲£Ž¬M”ÐÓÈRß Ï%² Å"ƒoÙúr (’nò‡)öyÄíPËðNÌ• í¦v3v7Ç^!†Å7ñi]‡ÖP1:FJ g&{-¤Í¡‡±\J=Èz²2ž˜IÔ:Ç\¸Ä¶ „aú¸>nˆíã8eòа}\'Áqì+ÀQÈ:«ležŠ1cÌ+ƈ1#,…Œ±ŒYþ±$˜å3YBÆÈC!…œá2¹k>V¥ÞÙ›ô'A¹¬§Ð¨m” h‰’(hƒÄ ±Q6ªÜž) —¸(‹8!øMVÝB×["¬ßã9ÆLbß$± â²’*s“IìQJQ4IŽ/¤Y4“•D&¾$—¥Ú r²–®<Ï»¨,u¾IÉ!´Øá²ÌŠ÷êh•(½J0RK(MAýÛñ©lf«?PÒ8¯§Æ÷0º§Ò>ç ZYìúŠ Ñ þ*©„ŠZ#-¤…„¨5T Ó3Á£v%{+¶dlX!ö9Ú qýaUÖ\!V™¿Âæ*³Òë×¹HðÂ0ÂÒˆæå½F&H¸€°¤N0Ê|Na•YéÜ}7HÊC¢8OOe‘U¡ªsÛlUÙÅ»¹óRÖ¼%Âú6¿0àxøÖŒª*ï8"(+OÇ%É!:Ĥ"1OÓ¦©*²-DDX×(T±q4¹ÌK0':Í‘\?ÄH‚}†³WrûŽ9Ô¦©Ká>Ϋ·pù>4v õ6æS ¶µp'Ы¨û;>Jdzšpñž¤tÙŸ_Žó¨f£0§´¹q‡â'1w b%þ`š_vÙ°LÒ*xfšS$Š-Óô•¸§–OŸdmš»ê‘ }šOtÄ,JsWÛOé³xF¾r ÓÄ4øØQ®obU7ÄÂ, ‰ÉÿÓÈã%.I‘6ù¢ÏMiöƒoê.[ÜaꓨâSD9‚›aÅ«1Bâô3 ßKí1ráET}›5DÕÈ¥d%*br%§8æ‘ rÄ!ñRÄšé4Ñ\–äØÞÍM‚’b¯b‡M”—i›ÄQëDp‚R/EHÿ£ßbê„ù>$.ó~!9ù T•pñ_ B£ÕÌr4¯»1IðÙax¯ù!=³×*B˜&ƒß"<^ÉÛ²/˜Ùã m´-bÃ,'=„'Þ¾À•·cÌ2a•-ù×1W™›fÚ†B”ËbªÌSçdUù†eþ C¿y$(Î%Ú$aT™¶,‰’$e[Dm•‹‡—&±E …›ø¹¥\ó–k ïŽ9ëâ»Ú·EdTK,¥MeËØ#I°;0£VÑìë“¡(AGÀ€É•EF}J%¦5žÍbIÍ(§K„):C„&3Áh ò„²Ÿ± “KpF˜º”•Opx9#Ä%Ä0Á´÷P+Ä8Er 2yÕÇQ{.Æ d'ÆäFm=®Y®DZ³?b±æÉíš»+°Ú`KÉ<ƒïO°ØfCгE޹³Ž“œ*rM JñãAîháÄ4ß;E›Ãí„Í. ªXRG”€Æ5™WûŸN1…ˆ“H‰m2îsd’“yŠšÝã Çø°´Šá„aŵœV,Ï8Ãä¹€n,"ƒ.›‚V‹^‰m’·è—zƒ¡²Z ‰ ŽØ'Á_†á{ÄûoEÌA ü%¤‚a& L˜Ä⃠i4SD LÇô/àâ)öZLg©Øá’¤Ð5t™àÐëbìp“X„.ñb¦_ŇÐ!¬%?ˆyðañ¯ã5£# !0\Ž}i!™E^åÒ¤—`fߨÃzIk½h@?N”C8g)ãèÁ²O¯D9õÔFY"2­Xœ÷°BíD¢?Ze÷}¦Qñ°Ê¦û9mU欤bfI…¡0"Œ2g½.$,?É aͤ7?<÷•i«lWI´$ÊL4sR;,“”D9‰MXè“äVó±n{ÝÅ3ßð‚¶‹³pң䉒©#Id )iaÜMðé{‘}xÊøvÂÍ‚]ˆ« Ò a‘>É€¢Êc…Gú$?ª§®—CM¬?ËKóhÌ1‘¢f.ss:Æj¢m)m‡èMQSCÍQŠrøgXµQwÕ»xšéR&ör#µÊôÇiüa^ Ö³¨kµý"â*-ÿ)o ÇúÕHÜd°¥Ä¯ÚL'|j€U±mе¦æ•1ÞWÙŸ9Ê"‡[øË#|¤‹jÅß Zȧ¶°¢Šß\D1ä϶ps;F=[Ïð݃|îz&‹Lùö^Þµœå¤L>tå[íöÿ!¸IööóÔaLÏÁ|s/Hn\@Æåcϲ¼…›çñÐBÁ¯^̳L,ja|œ³Ót·Ð7ÉHî:þ¬‡_êÉRÉu)šFÛx}m‚>Å'ªø“Pß㈇´ü ›´¡EœA\Ž·‚MbÞMKù˜â(ÉIúÓD ‹i6PŠÜ,:ÃIÓ$4ˆjh=ÃélMA\bÔ£Ë&Hѱ;aTR´ð$Bƒ FžÝ‹‰'Ë=’L+KßGÏŸ!%sî&³  ‹,úPe|0™B'†û'‚~ŒŸ>\~Ÿ]OõêÊ ¨_ް*n5  „’ƒ¿… 6Â<-JW;nh¤Ü’²…Ò—N2“åpnÄ0A– +ÀUˆ3ÄŒ±£óªÊŠ1Êžzˆ¥*1 ¡1Æ9Óêß]$o´´úŒ›®Ê Uõ“h²ˆÎX6QYpÍ+e–å•C Q.M`’ËKyX€Šæ‹ Gø€n#6u<"ª6"ûñ.Öb‡0ë”5'áòH<æ3‹B´O é´Oq8!aȵrû!žÎ²Ð'šÃêúóÄÙ1&Z˜?N)ÁìcjÝg™x4Xгžö³D>r 9ôa|wÑ ·SõEJ·‘Þ mU 9¬D»Û#n|Çgƒ ÑõY(ybŠ«Ö8<6É:—gÇYêÐiñPk³\Yͱ)ú‹,Îðõ\RÅõÍL¼ÔÏ]]çÕ!ÚÓ¬oṌ—XYÏÒz~ÿ9n™OÆde3ßÛÇÁ~n]JG Zñµ—˜[MK–‹ÚI’˜Õ$ŠP•œçˆöFìÿs] >ã3~©@J¤@Nͳ¿C¢ûû1Lvõ±¬•‹æÒŸã©£X—´ÑfÄgûïXÂÙûƹ² Óä©>V4Rë±uŒµ,¨æ±A–ÔÑ™æ…IÞÞ³S (V×p$äš6$’¥ŽinKó@Ìýi^„V›g…¾_ª"š&š"Xð $áA¦šÑÈÓLÜF]žâÎÔ“x$)bŸÑF¬ —’Eä_Ë•gx©…†Ó’I‡I‡Ø¥Á¶Q.ý¾Ã7ÉŠp'ä!‚"!4`.#™ÄJƒÁĈ†É¬…8ót„ht+¹£ÿ"Rzyu>Œg²ŽL´‰ôS8HÒõi”¢2?-£÷Op-dtnrbYva¡-bÃL„Œ„ «8ZK_¸ "ÁŒ*füù`0™±ÛÏņ3 U‰õk,xý›­LO3žm$çI"Á ±Ë––C Ñ6A9<,'K™Ä–ŽM¦=ý%)?ôÓ–Ù£(¹ºþÃbüKd*Më»k¹i€Ýštÿ0Ï-àí§9àlã¥E¬Öä%éˆàc v#µASª}’÷7òò(פ 6 òáNäøì«,ò¸ª‰öð;‹é™ä ÛIKî[Âoÿ˜µÜÔEÎçžá3×10ÅÑa~o Ÿ»ýýLæù£Ç¸{5w-áÈßÜ„pÿ5”BüÏ?Êâ9Üw5…¾„mrïŸElXÊÍk‰cŠ%LÉO^åô BSòùü/ãÏ$!j¼ùƒþ&þÁ9xÞùü !ùÝð,ífÝb, !0MÝÂÞS ¹ö"´’ñØÕÃKG°>p-Zpð /dl’+qÇb¾½«•› br’j‹E>‡'°%S9D-.äò!kËcU³i±„ƒé"74jJ>Ðlä¥ùLpo-_ʳÚƒJñ%CÞ¬å„0–ã¼L)…²Iî¦á %ÿNÚŸæT ún–nåDL)"6°CT'Ý~9$<Î6Eq„ãUŠ`.wó 4‰&ž¹´§!¨è© ‰€‚Úõ‡ˆ÷â,AÄP þðIÆ*áQþ«è)´OÃgg~YAé§„„¯¹¡maº•0÷MÂS¨˜ªw!²¤/¡ñz´FcH‡à£ß"³ö€]1ȤGn}›I¡%ÂÅòbËÆµBm¡ ´-FbÈ#¾ÀÒJ0d„]VRª$V$U9N<'¯fHJhÐHf,ös¾UùPÎèCvÎ%Xy”Zh,™DUÎâ4‰lb¶âˆHËX!ÊpõJW½þB¾É\ÂmK©î"ÚEÝÍœÅ[©“ÂJiã%e\ë‰PHÅÅ»lî™fsˆÔ4Np0ź½YÖpʦ5AŸåx7W 1jRsŒcæÔ1GaôQÐØY²1v…]MU;‡ØÌÔµÌ9JÖJªvåõؽ¾–· ÷/µ~æö„öXJcš`»ÏmNq›ËTÌ©óLæb—[«yl˜ U<ÖÏå5´Z|ùWÕsY‡Ç™hóøÊA®hbc “>»úYR˴ϱÕ±¤?z’‹[XÛJw-Ÿü>?»Š´ÍÂF¾³•}gxï´Õ _~†…Ít5²²“ý<ô®ZF’°¢Ó`ó^žÚ†€ûn I9´7a\‡Oþ=–¬tËäg6ÇœïHÿ:[]pcm‹o=!R¢Ÿþ‚˜ã½(PšÇ·(bÅ—S_E” %ßú Hn¼„ÎFJ;Os|˜w]Ž!8>ÆŽ3t4²a!›z8;Ec5·-çËÛYÐÌeMµ Eð·±®•F"X‰9M´ç0±‰©Ite *®°ÒH]1V¤ÀìdþÇ4ÚÀ<È«1´ÄáI =ÈÈr¢Fk„‚r´î¨^Y î6Äíà÷£ž&9ƒQ‹óˆ @hD‘úϰR€êù+¼±Ôª¬w:Óv¯DÞ>£ì(¢ÁðÐñ¢4î=°€ª«@¡òX6侎¨Ç^Hû¯£5hô8“"êhºm¢ò[˜|žæ_"ñaOjaa8 C*ÛŠ1@1 ˜3’ImP¹l¯%[!ÐB ZŸ;/εD¢+Ÿ–¯gŒ(+V4•yN1:D”Ùʇ@Ì»u€l¾U‹ÓïF÷“½ÿQ\» ;Ðö±x<á¶€g:"fК IDATÜiY¬1Y:Í—õƒì¬bõ{Ú}t€¨géQ¶²â§-ªjši9ÌÀÆÛi-!—Ñö]N,eîáR¾ËèšJˆ2[JÈí¨û¨9‚^‰ýÄÕÚÚœˆK4‡ú]ˆm«}!uPÛsÜžæaÞYEO‰çFø¹LžáÖz¾ßÏÚ*~t–¿»’ÏíäÚVVTsvŠDÑ™áøc9V6bIö0¯š‚Ï?îà²vn]Á“{)…\ÑMc†'øçm|ô&²Oìd×Q>z;õY’˜/>ÆŠN–´“²imà‰—Ù´ Sò wb@c-[÷ñäKšŽ9\·4މeR_CÉço3•›1¹@S=·\óSØJ<ñƒ# ‘¢Rm2VÜpW^ÂðxåÝ78Æ6£~ÌŸý*}ÃC§ya¡æsáì þùeÆ‹¬[ªùŒäylKÚ¹jLJyú·¬f^C¾µ“ß¾™C£<‚»/ÆuùÛ¹|1‹šøú>®èâDž’f}‡rüìþö8Xȶ)LËà¥i~u7ÄúZz5g4Ø|¼‘¿)¡mBƒßLó„AÞTã:tD¤ RøõÄPC´çIz[H®£ñ%zBJ)|˜v\‹ÜZë°úÙi¥(zø¾GÉ!HQ*Ïrõ(¦(:„VS„ÀCÞ€w%Ò&ÿY¤s;²Q W­…BØBèI¿Dº·kQZˆ–J”ס|+Ó)„žñ*ä%`\ëP`?ŒÎ#×`þŒÖ±P¥J¼¥Ô$ÑKÄ=x¿€¨GÅ(‘ûk¨!û‹hI£cò›1›ðÖ‰¦ˆóS{‰Àïeè+H ¦A2Œ·Q„3Pe¤RòÓc4s&™ ¨ˆ <ͧÜN œiG3òÊk 0Še3o# ËþvHv>Fžyÿìú·FX½ïFôãu¡wà˜Úlv”ÈE¾>„¸¨ÄÑ„†'ǰI§dnžáËcq@8L¿E]€1-jÒ4 25‰/H§¨>ÆÈ%,}‘³õT‡˜!æZ_d"ÁXk©‘b5ÎvÔÍd6£ÖàÕ2Ær¹6¶GbA¢c%öù\bÐSb¡äŒO«ÁÁ©˜(¡7Ï­µÏÓn2ppœ»Zyøwµ3V`[?^ÎCùÙ…œâÕdÂ’NŒ`(V438Á®³¼m1gFÙu’ óh®â¡Íl\LG=ûOñê .êä¦U¼¸ŸáqŽæ—îàxÛ’˳¢ƒ‹qfÀgË«¸&ï~ Õl?ˆŠÙw„|Ž$á#÷Eœê#ôIòvïG L‰mqïÛ©­®<…ÇO½¹‡5óôÌï$“¡ç=…aT²Ò)V.!F ÒÓžË&•æÒ‹’¡1œ@ZH“—'ìd^sÈùì:Nk#‹:šf/ÏgpšíÇXÐźü`í ¬›Ï×6qÇzêªøÁQÖµs¦H^qûBç Y3‡g¹z.ÇŠxÚ ;˃ý\×B¯fH1%¸§‰oûtxL›Ü™âA¸ÚÓƒRLËHEø ê4yÀ!²(VJÂF’Iš0d|15œö(Y> l¢…2a•é)E)EÁ&HQLQ´Uhаcú0ÖÇÒ‚}ö#Fµ˜+Ä=_k$­õ14–æ'©…4˜¼S¿¦‹‹7Kj(KÅÖDï.V‚e‚jA‚X.°Ð $BƒN‰zzÑ+mˆZTŒ6QÂÏ£›p~-P ڡ𠜭$1I€¿ÙŒ9RL?шw*!šbè;d¯!I-büyœÎÊù¾!¡v Ã;+žƒÉLCši„`B2ói™°Ê ¥f+† <[TÕQ׆ÎcCÇ•„}X1ÕÝvà¼&ÌmNÕ[ËÃbðÝÈaľO˜>òpb¤Kb ¼¯À3o÷ ‘ë¦Ù;Îé«BŒi u¬(L0.HÇ8LhÜ¥¬#?ŠŠÜe,?Ìè ºw2c‡(¾“ù¯R 0·}€¦¯R|'Õ_Å¿Tgö Þ‰ýeÔjÄzƒÏl„ {J¬1øâ0Ÿnâ/ú¸9KFÜP˧ó±.^dQŠ&‹—‡XSÃ7޲ Í]|j3¿»–ϽLÚàý+šâkÛøô ⇯òž‹©Iñßç·oÃ3ya?ÖÏgûQ6àîõtÔq|€G_à“?‹„º ù‚ûn$esô4ßü!w^Ãü¹¤]\›/ÿƒ\ºŠu+° <‡ê,Ÿùk â[¯ga,!Ȧ‰b¾ôuÆÆÿ…{¥+¿ü°¿Î'A¢5Kñsw“+F36š8á _ÂI‘(®¼”믠 %_û£Ó,™Ï×+ò>ÿÜ4ï¹™†Z6ïgûQª²|àöŸá¹½´5óžkyt+®Ëkyh #E>p [ϰ¥‡?x;?:Äî!nXÂæ³\ÚɆn>û—vQ‚ý#|p5_9ÂÆn^žI[ÆíeC#‘ÁÕÕüÅU)jl:RlŽ©òÈÙh ׌/!YLÔŒ~‚©uŸè(ãï¦öGœE›¨lHY”<¢òz!¥4›È£XÖVi Aù¼C˜¢¢h'‘k°Þ«e32úüÒ¡@cƒ¡èMø’Ô7 ±T#YýšäOWn×pÈ×*"뜄z㠀ʯZl4¸|æ03 âÖE!œ„?—ÉÛk¥ *µ õ2Æg…Vh…JÐyâÃÚ\.t *B•Ð’Ü—Éþ&*Bi ?˜‹µ û^!{;ID\bðËÌù(‰@Eô~ƒÎ_£8ÄØVZî Vúé{†î÷3vˆÐ| uqø;TuÓq-¯ü™6ªÚ8ò ±& 0²§1³ÄPÌ¡mÌ„›‹ØT2ÀR)æ¬äħi¶ ø2ïÅÔ„Gp4µï¥á—Þa ¬Fž"Õܧ]KËyóÒE†Ýqˆ!˜Sd*oÒbÑ. %D‘8Á‰±§I¬,õ'™ÌR7ŽžCÍ$º—èbZNøcÐE¶ÀìÃXŠó*r>v„Y‡ù¢–óM±°´Þˆ&E¯O—d[žN­¸%ÅwÇx[Ç L´[<ÞÏýü ŸN›iŸ½Ã,Èb+´b^–çN "V5³÷,×ÎãÈ Ç¹ÿ2žØOï×/$_â•cܳ–CŒLÐUG}–£½èaÃ2<‹¡QvåWÞÁ–}ŒŒÑ7€PÜÿ.^ÞMïãcÜx¦ÉÈ££œ>Kg+wÞÈÙzû†GÀ±èîà–ë9tŒ±qT‚ï£bzNXæŒ) 8—•£¿ö+?˲øÂ_á:œ_òHTø-Žii¡µåüS¯¡¶š_I¬èip䥈Ú:ÛP‚(áàq ›¸ƒãŒL±¨ Ça¼ÀÙ._ɶc çX1%9>D{%Åé ºšèšÃ擬éf×­5´7ð£C\·Œþ€®êàkÇxÏRvNaÚŒE\?—‡úé®ådÌêZv‡dS,ÉPí0 –´»œ¶˜°h3“A.¥¡Ièá;D&ÅeÃL®À9ÍpŠR™•\¯ñ•Ê`ÓÂòS=J~š‚M¦˜ÒyA½mTä x [bz ks»ª¼)¤ÆIèQŒh’ˆ“àxÜ,¨¡ðgèIh,^“ð¦c¹â|unø_l‰Qà(TIš%¡ÁA" ‰•ð¢æ„Á\É"h“%^¢¿.5ènA½ •FÔÉ¡ª1¯!±ÿФk#4¡ JB+æ2pñO ‘¹–X‘{‘8¦úm ÿd¨ºá1ô4F=uW0ü2IBí:F^%*P{1§˜9ÌŸÖñÌIÄKã,w9™ÃP\œâÙ3|t{€UÕ¸‚ñïÏwŽòönzÆé›dc®Á·vsßJþa+õ6ïXÉÿߺ CóÔ«¬h¥¹ŠÜÄ©>t»ñâv~ççIÛ<¿‹½GyÿÛ¨Íò™À3xÿ¸5>þiÞw/sI9üðY^ÙIÆå7îG'ôñÕ‡•ðîwÐÕŽ¸.‡뇾-¤F+æ4ñŸ'I0 }¡#ëyçï‰aðÉOb˜IÌýKŠ%¡5A8sEåŸmóŸÆ°ÏsÖ¥k¹ñZ´À4ùÇïqô$JsÿûinbÿQ¾û†ƒió»¡òÕfxŠ«ÖpõZ|’Ó¬ZÂ;¯ç¾ÄºK¸jZ€VMÝ/cNÅšÄÀQ‚ËpStí¢üZêI6Pµšì z?àüÔ®@ÄØùß,ý<v†ŒZʺ¯RQÍâÒ² CÃCbÇ(ŸMý“”ÍÁdwRs?ºÄ?…)Éûï“a Þ+µva&#¥<j€ïay˜RR’%ó0Ò„ y’„K`ç| ³ ÁÊñ€ öå‘×*V7‘ŠebvÀ ÑLônT­=Þ‰’–z$ [ %F({<¡LWèóèqñ—"•J!Gû¹­ŒõÍ,,àT?sòèqh`i;Z˜YÈ™nZú©Ë'™… šz¹u¯¦Ìff5‡êHR[DïN†ÊB€Æ6ù›öÓØÆÊYœm¦»×aùlZéî%äþ[رl–öjÊ(.¤€þ~’„>ÞÇ[otu $žÇÇîçà!Ù×+|¶ÖœwAFÇ3{;w]²J™ŒTZ[¥ñÚ›#Ò½!„¢ˆ’ !åeÀòqݵüêWR7†º<ñ|ò PTŽÂu¨¬DÑ(-CÓÉ8ôõ)L‡±ï¶EUÕÕ<÷f1~ ù<ÿW.!çp=5e±å(‹§‘Hp¢Ò|FUp°‰qU¤"Z“\9?æ†9Ô§I†´¤¨*¥ÃcršM:¤%9¥4DãòØáƒUlq©Œ£«Q™£L—M:¦\œg6a7†ÓN:G©ŒË`&çQ°q.1¬¥_Ö‰“²pc¤ct›L‡1}1>’–Äê=šzò¹; %`9œ é }úÌ5#‰B|P@“( ¥Ø!‡2X€A9¢i6’W —Gí.°Hƒb RÁ¶™!à §¨*VÏ+¨1*“iWª˜Ç=Žë”kTiÔ*ˆˆ‹{5Š4nTÈ*2ˆM…k1EÆd´—è‚Pî$”2<*ÂBýV²¿D– jPêH­G™€9“ `p ö´ ´?‰= {6Ý› ¥7Óø3ôQ-§}3ŽGñ´m£|%nЦ]LüG~MÙJfra;cWÑv„}Ï0vQ ,æô3j>þEÊ §Ðó0AõÐ< ?Kì¶÷X™{P[¤±2àIGÂ4Õ%R×Ŧ|nOÒã¢ä³°ƒ#­4øèYŒq\}œÃXÔJ— b^d¬+˜úGg1Ô;¤o¦æ‚j^¤ìñe&ã$ÕmYjJÀÕqþ»…&‡{ùT _;Ê&²½“•%¼Zϱ6>3›ï¿Çµµj#›å›+ù?ëù»…oet>ã‹ùÚó|éÒüt3ã‹ùø ¾·ŽGW“ÎòãW0T¾rŸùO&Žá#«Y¿C§øúCxO½Dc#ßúQÀW¾‚;obÚDZZùÙ¯ˆÙ<ôa óIÄøÂ?‚äškY±”0”1›/ý3Q(ˆ¢}ˆ‰‡°IÓäòå—ÞE òß0<U•Ó*jšâË_ö.³©\ö’¡|íkÂu‡*Æw÷°ñMbÑ•Ü|#~(ëůž•é3¸çƒèÿô¯ ±z5×­à ßý"m=üü÷„_|”󭼸™»×à¬ÛÎ'n§¨€½Á’ika0`v{[Em)ÛNó¯wðõ§¬€Çòµí|vo´r"MçGÁ²XQÎÖ4óKØå2´„F6pë`JM †´p \'‡G9†#{©å—cX1ÒÖˆ;ÃÈå&HY8qd÷I %""èụü³DDC&I£•oVð)0¹<›¢ô6§8­RPÃ=!#|•#øÔ¥›üK‚?N5 ‡ˆ—¾ "ˆÔn¶d9:š‡!Ÿ•„ôñ‚Åä8‹ÁUˆaD§Ç…+Ž‚ˆ€M* T ÊŸªb±Ê"ùº †¼FD ¶ eáP8•³}%‘‰TI¿Ž±òéyŠâ¿#ôéÛˆ9­†Î ”®!T騂UEl瘓î¤ë£næ½ÿàŠ/⹜yŠ9£í(£çÓºcè›;Aù4ü7å I¾EBA††½ (y’ø'ß`e—¢7{jc(®ñÁ¥Ó!î“È0 ³¸‡#PáawÐg’E‡ð0¸‚—¶0˜>–ƒ'‘ŠÄÐñ]¢b˜dÓˆˆÉc š[I ¢ æÌ¤±‰>ܬ4uQ]Ia§OKEÈt à £HNJ&#ÚÛ#a(³Y©(RׇDÛ0dÞÄ$úØDÌ0) ÈýŠu‰âö²´ˆP¢–2S'>lB ‡9”x³ Cu¤†Bdº9¡Š*‚0Ád‹rIV UTŸ¾Žª( J>³5L‰¯aôò††©aǘ+t¬AÖ«¨35ŠU Ÿw%I“E ¶ŠêË41Ce´ ¹Maœ"'"}Â-’B¤ñ·¢,"RpßE¿YLêeôùPÄàÛ30'Óû6jñ¹´}??xb\»ˆƒ ¸’©cØßÌêÙl<Á syã,µ%LªfËE0™YC³C_k'±7Iƒ7¤XåTص•¼˜á¡J΄œ¦ Øê ý»JL"ÿYÔ¹°$ˆðÊ@mMÓ«<ò:]l¼46‹Û9”Ç<=$";È™QLé a;-ø³¨@*˜.ZÍÀ’h¿';Ÿ|“\dµ¢bfQi¤‘ȹ¥=Üé—¼ÞÃu6nˆày(!ÙÜLTH䓤|Ù3"ëbŽG\àxØvP"TI&KBE…ÁùúÐý˜Ê`%$aÎâe)JJz$,<ÇÁÒ°u²žƒ®7é$ôÐâ&«¯åÙg‘‘ÌOH;e2xž”2’RGRF ûû…‘Ò¶/ó)Ï#“AˆKæ…HJb1L)ÿ÷B¨ªPU‘NËt:´ ¨ª8v,Ö¬±ÃPhš"„’NËLFQUe×®àÚkuÛV2‘É(»w3eŠ2y²#‘ÌÊw6‰[Öâúd}¶½ÉÐÕÇÛ{UËì8»°r Û‘H°x/¿ÍÚ8Ñ̉>°”×÷0w&}=åEœoá–å¬ßOõ(L›Y5¬;Á’É´zÄãœèƒXã H ƒ©…¼–„Ø0Ã2ÀdBœPÏÖÐ…k mcÊŒ¬!SU®NŒ“Î)Y¹Ýq’”k)Ô:´—qµ/Q]z9ZÄtƒ²€tÝÊV]ÁlP"®`Ö³4 t³š©QH(A`ˆá°YÅ\ûkÄê~Iü±,¾Œ"|ÔÐdèé¥QEø¤‚b&Æ©”¸*B^ÎøôE¤«¹Fâè胜öé’¤J¸JE„ô¦9 ¥Ü*È Â4{ *MÆ«d3¼£â™ÌÓ)´Dì4ù°ä4ìUIi<ˆÜ"d¯×Ã;ŒöAîNôD >Kâ^ü$[H¬"¹ŸH'±’¾=D‚Ø,šž¥ö~_ 1L/ƒŒû0'~AÅ•4n fàœ¡¨Š°ê%ÈLŸ‚9xoa ì‰IÌÏ`þÃûcXrœ'ÒŸÊðÛ, Á$Å…ºf¶•së9¶ºX %a:˜)ô«¸z7g*¨J!\ô*Ê·-á»ÏPhó‰›yî ŽàÛÿÄÏŸ§±‰GïeÏv¿Ã׿‚€Íïpê=€eòÍÇIØò“¦!øCº»ÃG(J´~}°oŸŸHD_ùŠ•ÉHˆ¢(ú÷O !++ŃÚª  (ìÝë¾öZZˆËž)£| ±x±†ËÝ®ˆ½{×^K‹!G–H)Ö¬‰-Zd†¡Ð4±q£»s§'„ª(J)ßúVÜóÄÓOûçÏGB¨4üE"ŽñªŠ5™«Š|Rr"DÙ£lQ0g°Ì"O"GÆ(¹ Ñ÷1­þ§cÃ)Pr¥ß6ú¤K5†Ù’PEIR ñ IDATU)( ²‘½ý4gyŒB14¸gç·5,ΣR‘¥u3•,©A7ox´Up£A¡†ÙÎ÷+yDàGt'yÖfRWKz|ŽØ¬Tð$¡Æ(U‘ *,¡Cô |œ°‰ô/±¿A©W1¯£ÿWÄoƒ2w“›·îÙFÍ—8óUÆ|PzHƒs/2ö.üУ{+¶ÉÀÛ˜ÓÐ*¯#x‹ÒO¢Iä»èG°þýÑ÷X!«=”;`‘ƒê’ô(÷‰'Èci3û ¸ÂÃHâk@AÏG°»ÉÄ(M†˜>F?Dè6‰ƒ¤-b*ö{¸×QÖyF(õ"¡ýNª+#Åóe‰'Ú#v'Y¨ ±B¶ 0]C°àP³m"Ç£T%íq¢“R•Ñ1š(ÓéMS¡Ó—Eút PbÐÕÏèB^{‡é™TFSÕ…¤RtõQS„çÐÑ͸ |—æv*‹(´9yÚRlÆ ”æsê”·eS“ˆÆ×É0”MMDQ8fŒ4Œ¨©IºnEQE…,(A /\ˆ%ç–'*Q¹®li ¥” ¥”ÅÅJy¹‚Ë€¥ibÇŽL[› bîÜxFþ’wv†ííˆòrsÅ ;¡ëBQD&CSS†" Åñãθqæüù¦Êà ½½twsþ|´x±1nœvö¬ åâE±l™jšJ{»²s§(-óÈTZì|›>ÂÉsì9Ä„ ÌœÆËoRYÂÙì:Æœi´tsêw¯å¹mLŸÀùÉØZ.v0{*‡¨®¦5ØŒ©¤)K¤€ &å… ÑéC|¸$4.ïp:è—2‚¥®xî%Un¶ÆÀÍ푳prÀéaÀrâ¤lœƒ:3ø²GÐÈ«&• êtòv‡B¢r¦)ŠD=Ë“âJ&ëØ‘Àtqê9bc˜C«9#$ºÈq'N2ÎYI…‰ýgÆöËÃ,âϨV}Ir—C×øœ…^…~›ë$G½š\*ÄQÁA•ˆè8Q=bµðꥷE¨WãB›¬%ù{”Zd¯ë ÚKÅ£dšéÞIÑ5t¿‹5‘Ô<ˆ¥{7²˜EÙ"’¯P0èÅ‹÷k fã¨W¿¿ág*}Ö˜! šÁU!ÒG2µmUÜx–]–O~–ŽÄ2X {€t„•Åt0#lÝ'šOE;œD~Šê#„ç‹Ð6#Wªw†JK€ˆ© /ò÷1~ÖÅJ‹7º¹¿˜ß·3YãÝ~Väq ƒÇr2ÅÚÑ—þáˆ}œ 9¬[ýå’P¹ÐPGm £sl«-G²B¤ƒÔÐô=ìIÓWLÙ$¦•¢ä„­‘$u‚Ý“˜— ²ˆ©‘s’mùŒg¥ P[Ø×ÃéYÜ)À#là•|êJX {8¤•peƒ2k0o€,f($ºyÚfŠÍò”xC§Ðà®H—Jƒ®¬T¥'÷„ñQüõR»JÈR’ÿBáWÈî!êÁ^DUwã5’^OÕ½4þ?*£íuÊV“îdð8ãîæô×ðº^À-†>ÿ(ZnGÏÔ+à\ý¾–Ë"‡”äÚA6:;ôÔ8Ø)¼2®k`¿Î(»‘¶&0z€Œ)‰w’) tp˜aõBˆ^FþE|«ˆØ¯HM _C?‹2[Ú‘0ªCq:i_„ÇÓ¬ÐéÎ2[eC/ËLZ²LÒt)4¥­Ip¼Ï!™aE;›YTJË£ãœigLG[Šiêb| '›èé£ÀâäVÏ&ap±…±åœ¸@Lc|ûŽa*Ìϙ󴵱r1ÇO`ÖTÚÛhlW¯¾+›šèï•sæ†Q$÷î Ã0ª©‘uuüò—Δ)Š¢„uuJi)ç΢DʸqJÊ(Š^x!UW§ !ëêôQ£4× s^Ð×^èïÇ7¢hd %B`Û#u÷ËÈxžîІ†,ˆ•+ókjLMBˆ†¿»[:--a‰»ïÎÓ4eÿ~?•âܹફb“&é゙:z禪*§N‰C‡ÄÃkçÎ)[ß& Å­kY·Žü –,âÐI:¹û~¶ µ‡Ê Ú»™8™³Œ®#žÏÉÓ̘ñ `R]CY‡[Gêöåó‚1MáˆáPNž»´RôÊI,45È5sû°Ó*G©†jÀÜlsœTœtŒ”EºˆüZ–Z”xxiSôT2Õ'X8 42 Œ€¨žqŠ+© ˆ@SÐv±­†: £ŒÒ!uLPÎq±ƒ ­’r‰RA‘Š ‹ñ¨hâ¯CÕ_Ì>£¡à`‘k‘dÈö2ôÐÌdZœ8„_EDD´·Ñ\HÞ$¦…x*dI¦èwIbŠ *a;} ©(¤*"5HK?ưÄÀtèêbO1S “äLŠSÔ1£Ÿý:z3‚ÛcLÓI¸ìÒ)·˜ä³CÐgsmÄÁ!;¿UåÍ"ŠÞâAᾂ,@,%»om.É=䯥÷uò>ÀÀ{ˆJ¼nœ ñét¼G4@Ø„:Èè{üyåèÞ‚âV=Ú ˆµï °æ¦iÎZ<ì¦hè£Å!–E ˆ•²b€­”é\%«wÜQlÛª”Âq¢Ÿü¤ÇqÓÔc1- Å¢Eñª*ýé§ûA-,Ô‹‹µµkóŸ}6ÝØwÞ7 å§?u}_µmí¡‡Œü J$´TøCS|ás<õ;R\y%» 7ˆá9VÑ߉¡”¥¢RúÒ,¿‚s½´ ‚Âïà;‡÷ëÃuŸ1§¬~«K–9,ºÛ(f8"b!3ìe²YÅHç‘Ìõ/]Ö1ª˜:ÕÉ…^º§²2BxøGÙ5‡«$†DdÈœæt%ÕUŒò=B—`7{'1±ŽQÔ4N÷ gç0±’‡hX¢dpBä!.fñ—3%ŸØp’”ôù+Rû_n 5×?Aœ¦õÍ*”Q0•6†@BÐ!ÁnŽ„x ˜ac "L´Ml©¤d£, µŸ®ì]È icéè{yu -J3Ga5StÔ.ŽØùÔhxf 7XÝlÍrj 6ˆ²Íf”EU’ßçs•N©Ïf2ƒñ°äõŠhò *nUÂo ÿ2g=Ê\‚¿1‘äKØwÓýSò o;‰%dIŸ'ħã53°nèéÇcØYtI 았ûPþñÑ÷X{$9ë!2Ä"Š"F9ØUõ )Éw°zð5Š&±ð"í>–IÑaÚ§0±™4ØñND„QGá9üA´:¿$;¼eØ/C4O~qÊ%àxlïçö8;ú¹)NC†ú$‡ö3‹ãp´‹ëËùýqUa —§X=™·Ž1º€‰…œifÅÞ=Ë ÓØŽÀcZoîãÆ+Ø~˜ªö¥ Æ«xùMŠâˆˆCûxàÚZys37_ÇØ~ø=ÖÞKÌ`ÝzŠ £©Seee´~}0k'Eáºu~<Þr‹±c‡sò¤WTDuµX°Àذ!J‰„œ7Ï,+SAnÝšìèðãq„7Þ˜2 #]O<ÑÔÖšRJM“†¡€Ô4.Ì·í¿&Ù‘¬ŽïèѬ¹Ç‡ïËÉõž{Ê µ'ܶ¶ “‘--A"¡ßw_QSSxî\pæŒÊêÕyS¦˜Ï>›íêŠ@_½Ú:yR67 EQï½×\·ŽTJyôQõ™ß‰d?‹V°g?HÆOã|=³æ’t1,fNåÅ7xø#ür#s¦rº•~o8ŠÄF%†÷¾˜#¤tóÆ–}yC –4T×ÄiíÙKUÎT• 5lMÛ8%.Q%Ó ©ŽþqöOb¶I"„#, ´–Ñ k˜ç¹ÐG²šÚRŠCÐ1/Ðâư«)É}æa.¶Ñ7‹±>Q!ñFŽsI„†*a7“8¹í2ú8JÅ·G,Âb¤kTA´3ØI*·ªp"e“¨’„hÙKÆÁõð/Òn!æ3ÙF—ø ¢Á:;éZÅb…¢A;é*S%žs‘Ó)º¯ä:‰ÓEK7ç+©«dT7iZ•0*Mk–Ö*æ‚>'¨,`L/{Ò/c¡†–åx>3":³ì*`‘‚ôÙ]ÄÃ>‡TštfEò¦ø0lRÃBÞBØ"½v!V’yë~’¯a­&s’È&ôI7ƒ@# èzkhýkþdäl°kˆ¨Ä@ù1òá?±ñüeÀJ³(C»Êƒ=üÊ¡0 žÄ‹sU?½%,;ÁfŸ¸ƒÝ‡T)@Ô2ÁAë$˜ÆøÝ´–SšD=‡`yh¨qì1äíC<@þ>Ø$µÂPBUó™ ybçó€ÅÏ{¨ù@‚§[™kÒšæúb~x SP¥2!Φ³|f./Ÿ`b!ûêùè,¾¿‰O.æd¶àÝ“|pÏï¤4ƘbúúX>…§6ðð^ÝÁ¨b–LãÇÏQSJº`ÍUtuòܯøò?sìoläÃw"¤üùOÄ?þ#òÍ7½… ™0gžqÃ[oUëêÄ/~‘Q”0• ~8þÞ{Ù³gÝt:¸õÖDi©òæ›É¯»Ûƒè _¨tÝpÓ¦¾>ßq‚¾>7‘Ð?úÑrUEQhnv¶oï‚0Œ7­²Òn Ï“ŸøD•çáºòg?ëô¼07òóµòróšk š›ýçŸï‹ÅŒDB{è¡âwÞqvìÈ‚vÅöêÕñ—^rêëåĉF2)š›EQW¯ÖšSªZÆŽcתêhk‹«V°ç®Ö0<éÃ_ê0EÒFàÔ%MýYÃuâ%œ2G¬qÞħèAŒŒ-²—ŒìqÒ9›BŽm%†jÀlœAL USX ƒÝtŽcªŒP멯¡F ƒšÁ;À©kX˜ÆP|¢>2.n•ˆ$n[9ssT)Q¢›Œ@9Coé8ÆMLQ„ˆa>rG‚@üµ˜X…Ërq4]\ÞS(ÒDQaÍÍôO¥¼ [Cbç(• ‡hl¥o:Ue$,tè8EãdjÊ(ˆ£[¨¯³µ’’©Œ×Q ”£ì¯c\ KG¹Èñ * ŒfÇŠ¨ˆaÆÉ;ʺñ,1Ðëyc,«bõ²Ç"§ºŸm…Ì´(ϰG#cŒÏj BŽÙ\ïó_÷h+rƒ`ª5œr&Þ (kIýýR1ç“ÜEìj¡TàgpšÈîÀ‚ü|Ê>Næû$Àˆ›Žx{_ +Åâ ­iœ€QŠ`J+Ç4^“N–«Ò9üÊcÀÄ©¥b {èë¢£Š±F;=ç¸PÇøJ*úNc¢‚j3°Ö±{"cª(21BÄiÚ˜O‰à ÁÂZÇI:ƒò",=ú« Jšà.jhs(±Ð"¨Ž—¹4Eø¿‡Z+—ç† m8Êë-´h°Œêâan¨Ð#è#{”NoU£)”‚(‰³‹sã(™F5Y÷ç>À‚?I2"8ÈáyL/ ž%ÕJs1”¦è륭œªÍœêãüBîpèîâd53Tüz¶T05Ÿ²NÞ-¤.AIŠcºM$%]:%’s1fgY—ÏZ•´d—Fµ]š8§È›„÷,Ê#ÒY/Ô«qñ{ÉîºôA¢B”Zú÷‘·˜ÔN‚ÃCOß„¼ ´Aì,Êáá÷Xi®ÌЖBzèu^Š K¢ˆåõV¨î%ÆtˆU0±”Ñ'iêE$Úpã”@³€‚q»(oà, ¨å0ê]ÄJ¥Aí¡¢82òDÆ¡0 J¢ú\eð\u’ýÝX0ßæH®áŽ”¨LŽ¡INuÐ1Àòjö^äC3yn?å&m½,ÅÆ½Ü½˜M°UÆ—q¾‰›ðãßñ÷ðÊÛØØ*ï¾Ã>Í6ÐßÇÜi9Ìê.ëÖ1w6 çÉ_ÿ:š3'?^îØáŸ:å-]ª66ú--þ”)ÊW¨Û·g»»ýÁA÷³Ÿ-9s&{à@ºµÕÉËS|°øÀLCC¶¹9Eî?üÃèÎNoÏž)#Ç ::2 o¼±¢®ÎTU±qc·çE¹(ÚÞ^¯¿?óǹ¹ü†5ÔN5*¦i ËÒ–.-´mõw¿ëèîÎMª%%fq±yË-%›6 >œµ®Î¾ñÆ¢ý¨ŒòrÃ4µE‹b/¾˜BÍËÓècÆè ¡¥56* =ö÷âÅõ8FŒ®~P‡I“6Ì¡´£—.sÊq0G,5†%*ë²V5„b6Ä$¦PìP~Lfâ"má$H[86™œ¯Ê&›GÊ"›`p*cã4ÓQDI%µƒ8çišÍT)PÛé?BÓæg‘íôu‘-&QADë#{–‰²˜Ñ.R¢´‘j!sžÔ=ŒÏm²òˆºqO1؃_‚}å¹ò¡ "èÄõÊ6zDù}c‰-#ÿ±ün§¿gä¾™å…CÕb4š¸ŠF…7iëÅ-ŘB^)–†Ð r+Í)²“(œH±†Ôá]¨%¯ŒX ­™î~R%Ī)²Q^gÏ$*K)("þ6;¦1>†¡ s`³‹ÈßÁk唌erŒÄ1^ŸÌR•°“#•L‹‘ŽßŒb•K“BhaIulÃãd+“ºÇÁúå¡Ç»=äƒçðH9ïö0aV‚çNqoúQÞkŸB•›Æñ›}¬Ûû¸coeñ¶ã¶¹lØKMã+زEÙú6÷ÝÂožeútlƒ‡ùìÇøÿ¤¸„y3Ù¾ƒ¹Ó8pw€«®¢«S^¸Œ-'hjòfÌPÖ¬Qþð§¯/X´Híè÷îM—–2eо|¹õøã퉄ºfM¬®N¿xÑ}ùåÞD‚‰k®É7 ñoœQZªUVêkÖ”H‰ÑSOµtue **²r*»”rÒ¤øŠ¥f¹ú ¯z_ŸÿÊ+í9Oiо¾àÒî¼³zìØxCƒóÖ[}©Täyä¢EEòÔ)TŸþtÕSOõJPAS%Š´)SÌ+¬'Ÿt ãÆÍçž‹@ùüçÍï}O1TëåHL—æˆ\ Z 'èýY—š€ÃVl°â[`F–:äºÊ‰S9 {.l/d° ÁBq1g2-FÁYbÄJ(Õ06ðÞf‚jbj˜›9¶”ÉEA{æbâEĘ¥ g;í×R›‚@1ÑÉ…*âÓ)H ª¨ ª‚hÇ•v}9E&j>ª>4M„0PFŠV§qÞ¡ÿY—³š‚qÃv­\=èªÃ«ý\dšÀ!ÜN¯Kx¥ %¡O˜"8F;™5TcD„‚ègé]Ũ l³x89…’yTGíô¿Ç黹2KÆÁ9Oý"¦gI¸í´MaB„³—í«¸Þa0EÏö/aM†î^ÎW2®ƒIÎÌ㾫PÌ8Ÿn—æûl+ä0H±m}ܸØôéyÏ?ßžÓÀgÌÈ[¼8ÿg?ë]åšk ÷ÚÚ"Û6Ö®ÍÛ½Û?w.L$ŒÒR½¾^©­U‹‹#Gä>å”*•þÇð¤Ð°Œ?«­?&V#µ*ã«\%ØÒPܘÌX¶)dâCsË™<’ 'POáhÆøˆºFSé!ÏÓ© £Â…zz»qGS”OÜEî¢ô¥T©h­dûʰ*°]D„¨'sˆd ÖrŠ|„ŠÚOØŽlÖ"âd„¢ ¨ÇõñúˆÄB¬YX!„þPŸPþÆŠ/!U„9ì&Uá0Î^¨u,ºu˜ ""ŒCÞvúKPÇbT` éHA´•î~œ«(-Æ0à‡èšBÞtŠUä:šè»‚Š:ò}üã´a–£âB9ñjŠ,´}žË”·‘úR j¨Ú϶ªòItÓPɘBŠŽñÊXæºt§i,¦F%Pˆ,YN—²¤‡?1-¢3¢Á¤Br&ÁŒc19Kõ ¦.—¾ ¸WºoˆÈÃK£ßGÿÓÈb²KI>M,Â~+â ;s}´ p ™å†±¼q[àd¸n<÷såxžgÉXvãöù¼¹—"‹Ycx}˦±i3÷ÝÎo~ÔiÆx÷]¾ü|ëëÄ‹Yº··2{'Ž“N†K—ÊðØ1¯®E /\pgÍRM3Ú»7“—ÇUW½½ÁîÝɼ<æÍ³¶mKF‘'wß]4}ºýÕ¯žabÆ ëÆK C|õ«§ÃPL!äç>7Îó¢_üªLq| IDAT¢¡­-•Ûý¨ªÄbêÈ2Ð4Å=÷ŒÉÏrójš²}{÷ž==ª:Æd2áD†ñÈ#cG>óL«ç9m$úÒ—&~÷»Ma8„wk×V¼øbþî¾»dãÆLί© ’:ÜäË5„6tOF¨?,s°Œc±²þ¬Ù Œ¨m‰-ˆKKdMá&H_B¨Ü``œLŒt‚ÁÑÄæ2×G´Ð›Æ­£Ö!|ÃS=•Úãtì§ãf¦ÚXuc)ÌÇ-Et„Þy” PÞ¢§ïzÊJ1$BEkÆ»ˆ3“x 5BD(:âîë¤î"¿MEXCÏâÿ³÷æñv•åÝ÷÷¾×¸‡³Ï9Ùkø­ßõ»¯ë¾L„@ˆ'ð6ˆqöé˜Ñ¿Ö¢:ÇI~ƒ_®­IЫqÎ'UN¦/»ï1Ú'qßdx1î•äb… I"Ô£ŒN\Mk'–G£Ö1ÐŽsM1q‰¨‡‰ Ærñ:Oཙé6òŽ 0r Ë=üMìÉ3~«BŠÏ²ã–{ä·òü¥\X"ß˾n¦Ðæeœ;Àˆ:™3:ÁÁ&fN°³%'xh yì֌ճ0dgŽ5¾ÑğƦÉ%kxèa.<‡GAÇꓟäK_ yó›ÅºuA:­?ýiçSŸué¥ÎÀ@´eKéâ‹S«V¹wÜ1Ø×çƒþ«¿êøû¿ï)ç*èC…B|çGË»W^ÙºbEnb"úêW÷Lê"Âg>³À²xòÉ¡'ŸìååúXýšYô$—]ðŠiá*¿ð±¢5wÜq¸XLªµ-Â4Í .h}ä‘áªþ’` !µ– ?ó™©_øBß+e”œD[v•þªA /[W'õÉ1૲ìI¬d¿&_a²WuRóWÞ¥š– ²ºP'ò.A–|9»*ÇD–B ú<xˆ Îgªƒóc¶^È‚4)ç¼x- 8N؇·”fñ…ñ*šcÄQÂ{ù(Ý €™ÂøŸ ½—&H‰¼ŸÒE¤˜H…0‘[H$j@Þ€BÊJòº0áEôÝ$ijÞlBh„+*5R¿«“ûëÎ,„Ž5IµÀP¢ïÉQÔbÄÛ1«‘£’èöß¿ã:œ¸’Ū6à­Çû e·~˜èŒÍ¸’úD 73ºœ\êqh.îE´KÔ]ìùcæ„ÃÖqð=, ðá¥ËXàã=ÍökXààà4:äKlYÅéýôÄøS˜¦) ²¿“ÙCììfáÖÎälCƒ­Ì/òR g ñÝnˆØù„­M|(æG.W›úE!z • ÎÁ&’‘Ä<ŸþÏSw ã_%[UXÎ71ßa)îŒ)•{UGX #ÂL0#Ì#ÁŒ1ªÝ®S!Ë»åòÁ©VÜçñ ¬ã䢴¡Qé\vr©ö\DFØŠ0fI}E7ðt/*A$° ™}ƒ¨3¿•CýD1åã(bù Ž c¦·³ë 3:ÙßÃ’¹¼°‹æêÒì?À…køÍ#\z!Ûw§­M i¥TWQ¤ûû!t(×Õ--²8r$tº»ÍýûËÒBè7¿9÷ÐCc¦©“D/]šÞ½»äy±e ­uG‡ úðá’””ÓAA ÁÅ·ßÿq­µaÓ¯ |#}è_1 C•JÓ¦e(JY™kTkššìLÆž€\·L^'ë÷^»®õ ‰ÔQdr’8;Yîg¾\ñWùTNRlÆ+Üëi¸ÊbiC(SG–ˆ,"“ĪTF6¡A¢ÑYÒí4ŒâáÍ I#û)¶“Qr¿W ODèNR²ÐBÔc „ñ …¥¸D ÏÌÁêÀP±–0‡\„Q&&‰0%ôFÔ|Dó¤jVµûàFtb-.˜œ[õºYí¯÷‘!8 9Lå’h8Uˆ&PèxµYèÇP݈%È£ËS-ï nGÎÄPå6ÏØqöãùŒçªtrÌ@]I¶E· Cœìdê„Åj„UC ÿÑb P1#÷ÒûŸcb„Žk8ô$ýGIÀ™Æxž–S;Lÿ~Ò£2¡prM4u‘®£ëC¤“Zþ_›¹j„UC ÿž J -hí GMà=Ëá÷á%ø ’&Ƈñ@äH¿‰OU¦]ê:%× Ùv'áY‰Æ… Ô]]·žGî¤.ƒÙ¦…%H¿¢=@°j¨¡†…§ª„‘ð ©ŸqHa-Þ^<Ћ˜x‘D.æ 'È)@÷…Xϼ·Ò÷,(f1ûªjk1ƒ¡í‚ÑßRØE šªÓeªó&fç`×)wZL$ø¨¡WK‘«ÖïÑÝPC ¿o÷¤"²5à'š;SD–.ÊÂÙÄŒ=ƒb É,ú×BBðÀ·ˆ4Ëo&Ý‚iƒ`t»~ˆ4 :Ÿî`ÎõHËdÛç+cººdÐ.")" _ˆ@˜1s-ýG¬v9 +ç?Å3õûNX¯=qýl”è 6ú Ö³Zëæ¬sÕðûvÇN°?fb€{=£6…¡dW†Å¶¶d8Di7!¨•Œl"‚"ا2¸¢ªÐ–é²àOÉL… Ð R"-˜ßEyFvT¦4ÐH‰¿—ñÔUÕVB¤Ð´El%ayØžvBÑ r&scd3œ ]Y:?ùë?’°^÷,hP$ 1 1ޱe”ƒƒ<Ÿg»K”%h`i¡vÞÚÇŽÞÔÃú..˜Æétk00D¥Ÿe¿jø÷TRJ£4j;?.²Û$.±q&—OðS /E1ç \Æ!” „x@ |ðÊ3†K¦ßHÓzîbl;ÀôÉNfEañ*[ê¤M¥A" Uäø·±òdvP\)È lá ×N€ëá–t:V×Ç °<콄÷û„S9µ•™ -«O–@Êפpþû¤W0õ(ÒBÁè&¢„@Hü“£+hº«íå#Â~FE †ÅØo+Óðס³2heÉÀ´ËÍFK•¶Xn€â1|RÒñ3L1i‰Y:2´(h ¥•Nn¦±‘ºÇæuë þõ»g"ד>2[9|ˆ ôF¶É[Ä&Qß"rð]B‹ÈÅOá9„¾‹Ÿ¡ä’ WùŒDØ!vkvòÝ©\5‰ÙÄ"­°°7Á‘d§2óa6Îbvd‹NgÖÉÙ¸kÊ«†ÿïï]Ö Ö±«ÀØ Ç±k ÓŽ±+EÑÅsð]ß!r)e(ºX,Ô<è¤)9:”¦xUÓªž Ö4.cb;ó¾ˆò€ªÅ^y^A¼œ¯ ª?Nü ~Ï+þÇÎLºÞJ^¦°“þ!†¾‡%HCZk‘e‹Ð°Ê„å 7Ä´SÞ(Œ°Bì'Ä pd‰T„c8f„atÓ±”¹1(DDòNNOxE“àÿÍÓ'_-_ý¨¾¾Âú‡ D¯üzÒ6 ½•ãVåt*À$–(1ÑAú4±@»ø"rH ’žJ»åM”³ lžCà2œã„=s-NçùˆTŒaG˜ªƒ ð[È–Dàc´2­‰³ˆZÄ‚­ÛG†˜Ý4¦Éfpа„\­jø7À'9@a?£ãöpbŒÁ.RÇ84 wŒ¥.šR„-dx.C”A·3¿ÀÙʽOÚ„ж¥O…°JP„˜Ië;°!Áp¸ î”ÐdÖ`µVvuøÊÖ<á d¥Q†>¡†J{ùÙµ«}D Æ~6‘ÂZ”DºÒ{MÛD–™HÓ®G*Æôu*¦ë‘Ž1Bì'°#¬2‘ŘV€!ý—ÛÖX%¤BFX ˆ£†vr ‘ ²ü4"‚3è.÷ŠÑ«é˜Kà ?Å=Cä_EXeÎ*Ÿ6‰MâjWHíH”DK›P¢ƒÄ qMb“¨¬¡Lb¿¼íXDeUåâÙø%ùóq~ 9+!—ç`#ï:ÆÃ2Ä„ìQ^\Â{ñb‚½—#ó85CS½S˜³…#s™¾žƒ—rêFNHÜíäÛÈÔýø}èý¨kh)a|ŒfcÒ;³Æb5¼î»ý(áƒL<ÉÀ!&|/…o¥ªÊ"ÿÖìä·Ã)¼4¾CÉÅOá—é©|{§)¦ðü %[EaT#Á$tÝ^õù­Æå>>cß#êõÀl}¥{õš<«r êÉòJ‡Œ‹h@´ÿwT%NÆKZ aŒ1ñ-Ü@[†Ê´ËAbYsŘN‚ôHù¤dŒ`%X¶ÂªüchŒ»ÌM!ŽBjH0",…¤Ò›VF˜ªâ‹ !ñû9÷<¾!Âú:_cô5jM$,‰2+–e™Äe³ˆÊŸZD‘M¹wSdêØå0tñmB[—ì$4 Mã)vEäNQ!ID[Lb$d¼ « O0–à†-R¬gÎ8ž‡ú‚”˜Æôý kRÄÓh;BãD0­d 죈"j.Ù $õØËqæåÍZÌ;y}ÿ‹´j¨`£&j'Ñs„þ&&L‚`ÎD ‚CœXHºÈxH^1–#€R F3 7ßJ6‹ôØ•",w®¶ Ó”Òx~Z—¬$Á«ºìÑtDïDÄŒþ ÒÆÌ!©«!A#DùyNðB¿lc‰"óêÖb:BO¼²é¥EúRD]eWyè²Þ°ÀÄ{£3Ô]Ai áQ,[‹A¡ö”ûKj eYVlX¶B”»)'˜>ŽÂpÊ Cì3ÀÖˆG!2ÀUTˆ²àÒõ(C¬ªb DDWsí V¾êê¼~ñóŽ62(*-'ƒÚ@YDeÎÊ»±@—»ÈI”Mlš:vD`”ã>K„¶Ž •ÈXÉ@½FXÖªD!ç…8‚7yüÌCg¸Ðc‡OâÐ5Êúq¶Ø´ÛLgÂCw1û0Ï…Œ¸4·Ñ¾ƒ½xS¨±¶pb%d/ãñ¦Ð˜`ö?Oi2F¬¢îÿ¦`!/%݇xZ—b\ó~Íæ˜ëcŸÏÕÛ? 5éÍt§O¿àSš¿³yJ(›d âIÂëÈæÈî'ŸÁØÀ‰,¾‹ÞÍhš@¾“Uky"âç)8 QEbütÅÃMúdð!Q²< ž@ EÝ[Hh¹"B˜äÿ†@äp?ˆÈ"¢Ê“( îÂWÈ)Cò:v¶^!¸*~u ÑP½”¾N¨»‘BÛ*¢n)œNñ'B rŠuŒH0$Fþ;˜CÚ)a@j4± %d,Œ²Õc&˜¡¶"a…Ø BìrCÒ#Â*“Tˆ­º*¯Ê­N'‡¸1aމ7:J¸•·¯ÕJh ß•¯h“ä¤Î2HLbC'¦H •:1tl$‰‘h©!•¥|b tÃB?SÄŽs<–W$šP˜>y˜á–8¡i qIw@ |DB6ÁÎã¥è(’DŠL3-øâKãŽç¨/"|Œ#C:D ìAT‚•`eqú´¦ÒfNc‰xúŽ’èÒè„‹ nŸà-6iÅ2‡¥.^Âi¹×¿ËkøOJO{=è‰xÊg{ÌAÖâ ä´ › 0bCø&QÏÅ7 ³ø6A:CÐ8Â@ß!4™¨'¬Ú¯aŠRšR9ô«è)JŠAšRš’‹ïª@”säÙ¸W¡Oþ£ ٤󅈑Fa¤@‰ø^„‡˜‚Hi¡³¡¡ª¦»æ•vó$hca ÑúÅrej/ZB+Ö[ÐåUÚ¶ª€dª@|ûä”¶P á³Äc¸gC3ñÖTí=(T?jé9˜>êvÐe¶2–=¥ ÆIªJ0d‚Qf(…‘h‰@WbÆp6ÓÎÛ߀ÂÒÌû4=/D-µ Tœ,­„BÆ ±FA "Uå¦üJKg-­kP›hþ8É&‘ÜEæ|m),Nõ£‰˜! ϰJ’`‡K§"]d¬….ŸábÐÄÔ¸} œÂÂqÆCÌ©tmãð¼@¿Â²q{É/£éŠ2ÀœA¦—¸™ÔQbՆ݌µ_ˆµy½–G#Â@ÿm,þÖá¡"IÌ— 8 ÷Oð‘f~1È.là’ç¸uÅ›fÐìÔžýÿ”‚[÷Ðìòð8Úäá2‡óGˆ"¡>¥¥ïr”Ê‚J×h!О&Só¤â;`j„HºMÞ[JTÕÒ- ÛbîE›' hÉtÁÕ‚bµ@£µÀP6 £oG;Ø7hœ ¡SDw¡{È~-ÁFù¨¿&RïÀ8›¤ˆheôŸtÝ'EQ ¤Ôæø÷pp…3© ¸…B ¡¥Ð†´‘`(!´˜<Žà¹Œ¾Öš{Ý´ĉ™$=å¡T%›óåuµ¿¼®¶¯H§2OÉ:D–8Fhrsp4 ó‰àš¤Ú‰Ÿ'ÝAj–‡…%cIÈPÄâ/ÄQÌðØïaX,)1 $­£ôiZ$™„L 2´õ2hQaŸÀo§õ …&¬"²‰º½xËiëG !zYìVÜ<Ƹ6„9+¥8}ª"a(b‡ÏrÁÑ€6Åb‡Í¼§Ò¦›ì›`eÛ‡ÈÀiM,i c0§¥XØZÓ_¿wØ?Š)Ù>L¤Y?ȃýìáŠÊ@íE•4‰0W“DĨ>¼ Ôý9q¥ñ׎P÷GÄÁKø=D'@÷âtkC a UX¬,‹d•›Ì*ï6~SgnÿªÂÀÎï${…¨Ë1Dˆ2£•eT\aP܇a•]¸#„$ëÒЇîÀ^޳ sH›ç"¿ˆ[‡CñRÂS|8CÑcJ†S]¾ÙËÇÛyª—kºyz€&IEZñÂ=#\?“[Ÿá#KÊÓ?Á%3¹òûüÍy OðöeÌh®1×$¾¶žM}ì£­Ž‡ŽñÑÓùŸÛ0³ÔgøÔr¾}„©†c05ŒÍ}àV]U‰ž „„#²Q&JOrrËJÊ@•…•2&‰©²CbVÖquˆ<–g™d¦"ÖâÏ5…„Ã!_7Yeq®"PH¸Dc*ú5VÄÓ= "˵&Ó4@¬*1`9‹¡Iðþ—õǤ $…ñ©• ®:Ð ñ_X&MK@H” d4½¡þKœg«ábI,µ€ãʸKr•ЂV´Bô#Ÿ‡Ópÿ/T ùÑcdßmhƒÒ­¤ßKz Ô“'s‘ÐiÆ×eIßH~Ñ o&Žðz9ò ý%Ã[è}˜V‘ycûngäE„ƒÝFßNldÖuxCôÌp‘8ÃMƒ åc„X §—±iÌ&1[hÛËÈ ºQH°%î!¢4î!œKnz ©Äóˆ•ØÇµÕ®äº„)¾]d.Ä1gÜ3Æ “½%–X<>ÌE9îëãºfvŒ±8ͶaeÙ?‚KøéKܼ”;¶ð–Y cAïæœil:D©Äå‹H›\¾ פ« Ç¢­áwš)5üÛÐ;‚ÞQŠ!kw³o€½#l=È’` m0èlàÑÃLo£1KA²?. xÊaY=GàÒfî+1%ƒañ¬duše6÷É€\"¯¬¤Rx.Ay·œ-˜¦tÒ´r2”ü¥,Ų ËPrñÊ ËÅOÑ ¹–E< ‰`šÁlE¢‘'b›Ïs).Nˆ : 2IE”õ”,pDŸF9Ì3é>9S²À±éЯIÊhˆJ(œä,ÅˆÏ !‘õÜ AYsˆbŽA)b“A“˵_ƒÐ FüÄ`†ÍÛ%‚QÍ%-’ëÐZhC«Ç„–ˆËP>*Ðþw…û ’<ñ ¼ˆ¹[ðŸ§ð Ö2Òk(¾€ßCÝex=Ä>ãÛi#O”h»œ‰4®`ú{ßÐ(!¶Ãøo˜ñQv~–®ë™úqvßIûù´Ì€%×BŠB3/aÓ7Ùô-æ…1¾ƒ…àÄ/hYÈÈã¤$™z¤bt gâdHÍD?(œ7iëM‰ØŽN aŽq‡Á[C†bìvþô8Ó¸¡Ÿ=if7ÓyˆÚ@–GL5f VŒŠ0%æ>üNˆ°, ³ÓG!Bb*Ä„6aèDZ‰|±ò>ÂD‡ìÑô1³ÈË (agñŠ8MȘŒ ñi¨'ô±$îÇ+°ù(cc„ìäœé…òHKêM.[Î;xá~‰]=¸s;xàÖ,aÍJ%ÎXÂòù5þúç‘#üj}#üàqê¹r5·ýŠËOçîu¤šñ|ZARg¡ ¶ â'H×!ˆÙÖÏšôxÏ,~=@,Šõ£àrû Øôù?Šd IDAT ÁeCÌI»!ÎF<‹:éO(Qñ§”Q1§Ê^UEF•7,bƒ¤œmÚ„ÁÅû4 Sžâ\ÅXB>ÏíiÎqYÀ2‡S}ŽiÌ"Ïôuó±„P)"6—Ù”ížñ€bY0iHïãg¿ã&–ºtèjþ‚ %Íå/R-‚¬Ïî—g¸w€yaÄ›Rüð(ŸšÅßnãôFžíåüVÖ÷rÓ\žï£Í¡ÛåÉ.˜Ê]Ïsí"žÜÍ¢ˆ‰BS<°™åS¸x _¸›wŸÇó»éäò•îcí³\q&£c]­Ìì" X}* çÐÜH’ m­“ãp´Öâ¿(™Múj/ß¾~L ¥ùÆðC !?_Kc#MŒ”¸ø îÝ@Ð1•#tu“É2½Ç÷ó±Køâ6ÑÑDg#ŽÒѧYÒÅÓýà‚=im‚ nÙÇHƒVb ?Càâ¥)Ù„éJ †Wµ¨Â4E›0K!MÉ%(f(¤)•sD3Sê™åòE˜çþˆÑg™t Òu~ës(Ë™’¬AV¡5lIê_;ÇR›N0šZP.rѼœê.EÅÒ*ǃèI1 "†äd(+¥ËZCÀ ‰Lgc†¹õœ Z´D—[ ì:.”|Å`ÄÁ4 BÒ )¶IæZÌ”x/ÑOâ‰+9"ô `úZ¡’½¨"b™Nb>†Î`žCé´‹s!IL~î2È0ö4f¢‘Öë¨?÷)¬9Ÿåðg™{3É0ùǘñVú$³ŒºS8¾7Ç™ÉÞsþçØò̹ÿ(ª+…ÃJ“‰Üé§ù2ü§ýg²m˜–Q¯Ì…Z/RbsŒ“Påv‹+ÆÙ®c¬-b»Ì:Á¡¶¤á9žÔ4*R>N€“àlb¨™VÃG\Áü—(€[άU>"µ–“ 0¥0•6=%2‘&V„FDI""tŒR´±"1¥ˆTÂ÷öQ¯‰|®èdnŽç† <1þa{Ž{˜1›|€ápÆrîÛÀ-×óÕŸðÎ+øÉ:DÇå‚¥<¸ +ápæ\Ö2`àfÈf¸éî8L6Ѩ:èBª*¸œªàr´-êuurÈÏs+ÎT±<üW>^VX)¼,E?C1K!ÅDó¸2ÆKù• ÝÂUCØC<]¢·“ËÀ’¸ À”Ø»øN= 9E‘¸4¨jÑFJ,㛇Ø+*Y—¸Ôwsêë ‰ úúy±Z¦MÌ\dS”"ÕPQ&ø Å~Ö·³&ËT' ¥Q¶–xi…„‚ ä‡ÝÜ"ˆ ¤ &¸»…?‡‚$ŒØ±§Ž$~ÂÅS7ÚÕânƒ›$¡dŒx­W‘xDë´˜%XL|”‰;©ÿ; "ëKÈœOjÍ#¬ñÆÛMi™‹ý5éÕÓ8üeÚßÏø´IÝJýiïe××輚-h(nEp e) Ù9„kášÔ­ÆÒÎ~¬™±1ZdP³:À ‘ô¬™à@@J0m˜cEì–JrNž$C[åCˆb9r‡ñlR1v/¢‹ì½ä›HgHa."½Ù…3©´Ù®ä]>ïì!¤IqÀ'ïc†L5‰#æXüv€…iŽ˜ëòÜqV4s÷Þ»ÃÌɱ»Ÿ9õ¬ÛˬF& Œ±°ƒÖó®ó¹o#‹;ɰ4*ÂóxÓ,£!CÎeÃfu1<Œ—çÜU<õ4i‡¥ ص‹áAÎ_ñ£9Ä›–âyzû6å8ÉòåâØ±¸¯/²,}öÙæOxZ«éÓå´iRkýøãÃÐ Zbd$~á’ œK/ÍÆ±öýdƼaÊ4ù³?ë ÃJ•¼RÚ÷“W¥<—_»óæeV¬xÔþ;ïÊæci²ZLÌ:º çÏÄästeèr©‡ÐÆå…ßÁ©c¾„„‘<;lš2Ì1!=%6Õ±Òaº‰5Îβ˜bâøV†+Lš¡7áy‹%&Sµþ¾äl¡H~¬“Ó„8ƒà«ˆ‹‘‹ÈÿƯà^øÆ«ðÆ¿FúýŒ|‘ìÇÐýߣíÿÎ|D#½÷0û lÿ4K¾DϽdfcw³ë‹ §ÜÄñï’‘4-¦i52 ø.¤$)G™I(OÓ\^àîŸTDN3ÚÌãìíærMzëB7!5™ÇÇñI…8y„I] ÃÇÌÜÀŒ„1vgÉÔ=¥µÆÞÜ(¹§À¹’$bWž|È96Km~;ŽˆYßËŸÏæ§=,ÍòèQn™Ëí;ù‹¥üÍ:Îïæ±½¼m¿~‰ÏÇ#»˜’eV÷nášå|õ×|ðBî}†óQ,bš2Üñ+ÎYLÏ1ŽöòÉ÷ðð:æL¡½‘ø2Ÿ¾…¡!îü×^ɼÙúoÿZ¬\¥Ï>“;îPõõÉûÞ'ŠÅäŽ;Â3Ï”+VP*éüljÏ~6+¥~ê)oݺ’”êsŸk CõÓŸŽ<èÍše_w]Nk½sgé¾ûFMS××˸=Šè0L¾ü壖%Ëõ­­æõ×wHy’°ôÉ\Ê;ò?Ü÷ª´ŸùÌÜ P“ŽÃ[·}tÄ4 @†Éœ9Ùol·,ñùÏ÷ a(E[›ý¾÷µ8Žñ¥/ G¾/ÞùΆSNq>ÿù±8–©”½fMjݺÈ÷å­·fwîÔwß­§M3¯¿Þ¼í6 âƒáöïqÓ{øÙŒñÉ¿àž‡hh`É)üðnþS¾õcÎ;—m‡+ÍgßÍ7×’á3×ð… ˜œ6ƒ]Š ¤©LuÒ«*[WéêîIÂJcÈ(…Ÿ¦dTõTyLÐ/Xåzæ2ae)Tw ib‡(â–i,;ÂK]Ï<+"9Àƒ Ìma^¹¤Œ"cûX×ÂÌVæY¸T¥ÜÙûÙ8Ìq ³95K£SNrrt5Û×\ÂÉuu|Y•ZÏó°=Ÿ5YËy•±"41¶óó…\‘¦"R ¥ýüº›Ó›Y¡„Ü"7…KJSô93Ò¹Š|Dï8?íâ¯`\3^à§Í|Š|Õ¥3Í;$qÈm)>'õ(âQÉņÖ:úŠ0þ;ñ¸*Ä Ü`®|c„U|7LÁ{÷*¼½;p®däûä®§´—(!s&½ß§ã&}ƒ¦73¶‹XÒ°œ½_®\û¦iÈ^œZ¯A=†›!Õ–ÛbqvžmšÓKx>t¤}ü”ÃÂÃlÊ#ëY>~ÜB.’C‡Æn¼q¦ï'¯â,ÃÀ4å«îy­ ÃW¦™¦¸çžžt:=wnVaÛF’°`AVkÖ®?q¢´|y£m›BÈ©SÝÍ›‹==ÞÊ•ŽcL›æþú×…|>9óÌú©S­µkÃbQ.YbÏœiß}w˜ÍZgå<ù¤óÚk­ŸýL¦ëÈ60p”çb:<÷ËW±c/mx a±hÏl·™L=Ãc`1u*±EßD%Äkn¤»™CU½ÌSö$Â*+¬TõHuC¸ÊÁääÏt%;ÁsñS”^)©¼,…,…^ ­m,7h/18ÊV$H0'èæ°E®‹å ¬ †8’ pVHY›ÆòŒŒ0¤3™_GcH¤£œR9Äñ€@#c'Øâàt±J¢Mèg³‰t©Ï1]SekЦ,s 0ÎÓ)ZRÌ·yËq©‰²U±/ÃešŠ—Î2i‰ù_o3õ¨Ð§“th£SïyC„¥“¯‹ð´ø H¶`]ÆØ7ÈÞÂèw0f#ÚèÿÝ·±÷Ìþ Ç…;k&=?fÆûèý-§2~YÈvÊ"÷“B»†H'JþMQÞ!Â#k°j”½EDˆ.bŤfsÕÖ·pŠ&3Dñ£騪°œ†&íUŠ-S²„«± 8o¡þ ÍÛH=.dc„ŒÄºK;‹„!XìÊó'M<<ÌÆA:$§¸ŸàØ]&ó2|ž=B£‰ðžE|õiÎî¤w”kó›í¸’C'8ÜËÛNãÞ§øÄ[ùÇŸqã9<ð MiJyÆÇùðµ<¹Í›øËóÅ/sÑùLëä»ß粋xð~:Úù“÷rç÷õáÃê¶ÛX»6yè¡`Å ÞþvãöÛ½¡¡èƒL=ñ„·e‹—Jqë­ ŸøDèóÎK]pAF©ÿ‡±÷Œ–«<ϿϮ³§Þ¤s¤£Þ%ÔPµIHƒq `C0n$Øy—ã$¶“¼îNl'&ÿ¼qŒù;¶17L1`›fB!!¡ÞOÓÑéuÚž]Ÿ÷ÃÌÍØa­Y³öìÙ:_öÖo®ûz®ç¾Ã¯}í‚¢®NùøÇk£Qå{ßëö¤ ÞÿþšeËâRÊ_ü¢çܹ¬¢H)C)ï~unéþJM_ùʱâV«wdX R†Åõ%Âo{©m‡Š"J=õT¿®«®‚òîw7¬YS‘É„÷ÜÓ­ëªç±iSÕ{ÞSý•¯ôð}ñ‘Ô,\h}éKC |èC•a¨<þ¸ ê?üCÅ=÷ä5Mß²Åxá‚@ûò—µo~S\µYôr¦tÐ@C1 A‹ã*ÑJ>ûa¾ýÄÑ#\³’ç”Ü(³´ü§–0¤•”>©ô+~´JÀ²$¦Ð5Ç,V‚Ùr‹ªàaEÉ%Hv ÆI›8 ÒIlP§Á¤¦ž+|„À8Êã‹yŸOšDË0æcÇ©U¢€êìáé,œÊL‰",ÖzÊQ п…m.¾‚"ŠZL”þ£*åÝü ÷é ‡Æ+’‰`#"Xå"K C‰ÞP… %¤;xöÞ­£vÒF äyC8ŸÕBAx‘y†çq• €0ÏP;;ZÙ”¤VŽqj”c3¸AC¨ˆn~=Û « öð“iÜ%ã±(³â¬UÈäøcœwCÃýI¾ªqù·ŸVÑDø}¡¼Œ\ø¿oÍy³ÊÕøÆdØ,ü7QÞCöŒq.àg071ô•§ÿGX±»É“XËÈ>DžÌU3‘Ç1!%¶½WF†}%“CxOžž<Æ8Ýq>0L›¤&‹`¸’Å´MgS?ÃY4Š6Fj4,ÓÆô0Z©K¡H =n¢9T#¢ý^ª³5í¢8\!épI¸TJBÕã¹>š5–YäTŸ¶QfFÉæ¨Ðxã"+ªÏQ©ñ쬛b©<ó*ïYÁóLM`†œ¹Èœ:jâ86¡KÒâÈIšª>gÛX>‡ÔUIÒ)4.Á2eURœ?+‡‡äÚµáÀ@ðúëþöí"•òÃ0ŒÇ¥ã##îÅ‹þºuúð°kÛÁÈHpÅz:í¿ùfFÓX¾ÜR”p|Ü Ã ¢BBæó~¾:”š7/ÖØhù|Ëy®èºØ³§WUk¯­/0+Q@L§½²û.Ëʈ˕HèšV4­NŸÎž<9 JEElåÊJß55†¢(¯¼2Öߟ}Ë–ú ¶Í¾}c lÚTkšjg§æŒ Ú7Vÿá¹055æ† Ñ_ôòyuûöÈ‘#btT,_n¼ò  oÞ¬îØÁʵâL›OW7‘Jš¦ÐÞÍúõì=|‰bÄËŽ#%Z%%¥—ØT.¬Ì2`•j@ ˆJ,Fe®``Òž`[y#ÅŽ‘‰ŠàT³¸•u~†:“L­fšDíà°uLOPíöÓÃÉá4Ò\Iu€T1‡dØ!¨§®‘†é 4í$§šƒï†0iq¢…P€K 'ufP }H ÉŸ Ü¬4Ð R]ô÷3¬€¢£ $„ó˜ç“WÀ@ë 3ŘŠb¢6ÐXAR /ЖcÜĨ¡¶ŠA8ÂÅzÄ›˜£!:دàUÒTMK–žÎZ¨¬uéMqZ…zÖe9ª`±GŸÃQ“XÛŽ„ôÆØ]"Üèó„*CSlr‘&n~G ËåG>w™ü"uî“ò="/ÚgÉÝ­0…±©ü.~ŽÆ{úÚôtÿ”Æ;éþùSÅ)C…%V|h¨ðËåª T¸& j×l¢.F@] ï?ÃËY"#ä]L+‹²‰­}¤Gñ<"¦ƒþã.#OÄ!â¢ÙX>ºC$/M[ê/ø²ÖšÇî4sà/"Ü7D_r|uϲ¿­5ììfA„s£üe+?<ȶiì<ÇgWrÏs|u;κì9ÂWßÇ×ÁÕKñól^È«'X3‡ùëVNqì0÷|û6\©ðð£|ìV~z? æSSMû9ù©;Äμ´S~ⲫ+øãÏ^ëêò~ؾåÝq‚'žÈ‚ÿïT:d?òÈø§?]Q[«þþ÷c¤¦MÓ?ö±šW^I½øâ(øë×'׬‰ÿ÷wù~ „L$Ä]wµ$“êý÷wutd šöìØ_þå´0” »»s?ùɹ20Iâòáo ,…bžºèj-ZTqóÍÓ„Œ>õT¯ZáÛ÷¼§iÍšªt:üîwÛA6-úñOݵ+õÒKi)Y¿¾rõêÄ}÷ ¹®ò÷ßðì³ùãÇ=P>ó™ª{ïͶe‹uô(©”²r¥¹g ŠBÈW¿É׿Ì?“GžálÂ,6nZ±ÅäÀé}t0ŠþzOFYºjX‘É +Zò°,ˆH¢S‰‹L¡ë^¼Øb!› ]Z´  gäçqµN•À|ÇVóAô‹œO‘šËò!ÐNp¸›žíÜà†( ê N'I6ÒPèýThÕÎÅÓtň¯c¡‚&/Iª‚Ÿ%örjˆT©7Kð¬ K}‡ß6æ~)Žú0¯jh 2Ä_Jë,šBÂÒ5Á%Âö^/c^Õ…6 r€þ#[Î’:j 9qFŽq •Ó™U8s‚½sYi +™aÚ[X*q|Æú9:ƒwvš¶jæ;\p¬a¹ÀëæÿT±:ÁÂQ~iQ_ÍF¹§Š©X?Hò{ùïX£ÜájÉ3 YÙÈýªÜŽÿŒ”׈`e3©û‰~‚±ÑVà“î q-#{UÐŽ¡öaAÅ:”W1!¢ÈØÕžØ™#bS!Y8NgÓ!¦°ÌÆÍ!†I;赬êàb”&ØùqP¨R‰æ1ó˜’H;Þê{‘6f Éx}˜-˜9"ÃsÐ^v•…>)ßeAHËéqÖšT„˜O]`V„:GFXåâ8;Ûyw3®C ž:¶Y8ƒãdR¬h扼{¶C&ÅýÜx ¿{–›6sä4†`~ O>à W±ÿ03šˆ¸.–FG;¹4µìM^wŽã>,[& Ãî9gûvMˆ`ÿþü¼yJ"ïûž'5- Ã`×®Ñk®IjZèûÁÀ€;4ä.Ybéºtÿôél,&Z[M!¤çÙ¬î\féÒ„ª¢ªRQð¼ §Ç>q¢¿¹¹ræÌ¸¢`!¥\R]‚T„žJ‰eieΉäª†a^]]ö©SC 44T¬^]„¡¸xÑ9vl´°ôƇ;Æ|?hm­X° >2ìÛ—Ñuãšk*z{ãGí¥K“ž§œ<ézÍ5‰;=ÐæÎ5ÏœañbóØ1¥¦F«ªQÏqðÁbÚl›xý ”ÄTAOé¥2°XÖÛË,/K1‰!ˆJ]ñ"Â.è©XQa%U”\¬Ø7&— ]E~ 3B‡ šæµ æp Skhð Mº—>k-MÁ<ÌÑm9óóø­›Q²b 5õT:„ *¨y¼Ó\  $±fQ'!DúHU Ê¢PR_£M)kHú`…§‚uÌ E1…懄&ª‚ìaü"cj1DÐæÒ,U°±ÏÑ«VÆÏ„,ÙN.ĉLgš'9©(¸S™‘ÀÊ1ÞG‡‰ÒÌÜ|/',ôf–q>C¯˜Îº.vE‰Ö°0Ï›³lËÓæÒ^ÁJA:Çî*ÞÒæp0Î:%1nxGÀJñÓ€ƒ*ºJBÊ=†Ø.ä4>%‡dÐ"d ¹0ÿƒáÏQñïŒ?‡R‡¶Œ±/¼7ÏÐÄ ?_Kž˜0Нh6‘,qÝÆÊa9Dl¢.ºM$9›óªMÄÁ°‰\Ášœðˆûè9,›H[Õ$ëIx˜»ð¯£ªžÈk„!FcG ÞðG‡ÚÃcOŠ%*ûFÁ‡<äøêLžéãÍ6Wóbs-Îsçþïð Íß]ÅH†^b~u&»ßà+·ðòQ9~ŽÏ¼›¯}Ÿ/}й—µW`g8|€¿ùß¿­›ymW¯¡£“ös|õ‹<ñ„ìhŸüDøox_þ²20üð‡öm·©‹)ÿüÏ£+Vh[·š÷Þ;šÍºŸþtå~0Áu×Å·l‰þóà}ã­BÈ;Fvî‚à;ß™çºþÏÞ}æL ‚Ï|ff}½yøðèãwNüíÛ›7l¨ ùüó÷í(0( ƒR·Ë˜%-ª¹õÖÙ†¡|ñ‹{AçË\i IDAT ,Š¢u±hQõ?8}tԽᄈ®+ABY´¨ê¦›¦|ÿûíãã(ªªÝ}wëáÙݻÇ@Ÿ6-2kV|çΨ˖%»º‚ÑQ¹zu<”ƒ}!t)ЅФ,l׋H´ŒÔ’€2J/­ŒPkZ™³n”¥«Ê½*£äjÆ»ë+ÔR×= »@¨°âd"—jÀ\”l¡<Œ’ñQ籺‚FÐÚ8WM}œŠ­ö>†V³J¢†ˆ4ù>ç2ÓGJ„Šþ$¯ma™‰)‹}5Õc\$s sA ¥†vHD™ÝtIh¥j#S}NʸSfl½u•pRßM *¢ÔÍ\y€#‚p1 ‹i‹Í¥iãîàTÆ»˜¡ŠHåQv7Qy% D±cCÛL¦k "u”Ýìª"¾ˆ¥ôs¡—ó+بŒÐí‘›Â,IþM~µŠÛuà°$7…åiNúŒ7°ZEôñÈÞ ã6‡*Ø4Κy(¼w¬.>¥£¨(’ K^·xìÖX¦Ê´/"¯•ùû…ú ìGðu¤In%önÒG°» 5ò/cŇ&2J ¨yÖ§9]¨øB¥èÏa8è‹úÉä‰Õ²xÇÆ¸@*UOK žÇÌ¢M£úIF" ±T!èÇl"’ÓæÌ@yÃaŽOÖ!p˜Òã°RáHÅ£E°ã"Ó#4kœeiŒá4S,ž>ÉöiP©òðëDTÖ73œ¢ˆõ3xüfL%›cN{vó¾m<ñ;®»š¶NÜW.â7ñÁëym?3›9sš¨Á‚Ù<ý¤¼öZ‘Í{÷:ø€úøãöìÙbölvíÊÍ«46ÒÕå¦RÞ¢EZ2ÉclÞÓuyôh¦§'uÍ55MMê/yÔµkj"¡<úh[2]±"QU¥jšòÈ#]Ç#+WV'ªaMã•Wzz†©S+gÎL UYièºxK÷I„ ½=}ð`È[nYèyáeÀs=/TUu×®žûżþú©B(™L°sgOÁCºöÚÆxÜØµkdtÔ1gNåÂ…‰'ŸuÆŒøÔ©ÖÞ½Ù0T®¼2ÙÖ ÉÙ³­ÁA†ê’%‘½{CPAýýïüö·bÁBuhŒÁ±2T•K/{Ÿ(ýô2%e”ðœ²ÊV­’M•Ä„ªù¹¨°#ÅtB.J.A&B>N:A:FÎb¼-Ad>ëB´NÚ|DSÌst(h³˜áƒž‹5T5RãÁ™Æ@_A‹MÊaº%Š@[Á Jï}"A4‚6—Jð 9T½äŽ1ª"JC"ei& DÄÐæ“*yq˜1·ôãT€” £8…~œÁV¦S´á¥#ØHChãDP–Ñd d7cƒ¤‰·‰\dh€Q—|3US©vqÏÓ•'wó£h£ŒtÓYCE+­8?N_•-Ìèå¼ÍÐB6´ózHª†æ‘ ÑÎ…ŒLáªvêèIfç8\ÉÊË*ÙüŽ€5Äo/ð…F>¬“py5Î5ĸ%ë¢VcªþTÈ{Èå.Üch×3üUâßbðëkqsÄ®£ïû¨Å_3i!bøªš“VND]ŒÑ<‘:‡ÿû:ÂGŽó[¹çi …•4Fyi_ú0/Aƒ#§ùô |ã{üó]|ë^V/!p8¸—¿ù+¾ÿ=¶láõýl\MïEŽáŽÛøÉOü)Sü\üË¿Ø_ú’ñë_ÛçÎåï¸#ò»ßeGGÝ•+uÌÖÔðùÏ×}ñ‹lۖܲ%ùÿØ&¥óµ¯ÍîêÊýâÝ®ëKéþÛ¿-Ù¹sð¹çz¤ô!¸ûîyõõÆÑ£cO>Ù†RJ‚­[§oÜX†òÅ/8PPXÒqü‰Î)òç&nˆâ¾(º®(ŠâºòóŸ_j{÷>ÿüЄP¤ßúÖŠýûGûÛ  zóÍ-ù}ûFAåË_žóÍo¶ƒ¡ªZºa辯„¡¦ijT• úìÙ‘}ÈüÎw¢‹®(h“ͩˀe–I*½$¬&*>ã-zjâ Zº&¦$*TÓ‹àÄÉXä,ìÂ"`;AºÀ¯ RãKYTC“Mp‘ž9Ìó9¼.zæ2ËG¸mô.`º‡ð¡ƒÑ7èº5YÔ_òæ»™_Âõçœ\ËÔ9TøE•¤8È1ÜçéË#ogº…VÐÌᥰ•(`¨\a â>Ï`ùýó ?DS¬Ôq¸´¯P(ÊK/ìizûÉÏ%¶ŠjN)0„ýÚ×Ñ8›¤ø¸pt9Mó©S £hp ms#(:ÊcìœMã2fõÐwŒc«YRGå(ƒ§xó VV‘<Ç3Xd¢öp* ÛÂÜ4F›Yb`´óÄ,® I§8\Ǻ~9ŸÿŠ3çëUˆ1~§!#4Jz¬9¤€†®Ê~U4èò5…•øD¸wr6ö J-ùqôE¤&ñÏ O+=+QBMäD4GÔÁ°‰ÚXyL˜RÕK‡MB£>ƒ6NÇ4™2Ž$ðIäÑT*$ñ$ÉÃ8tHŽˆ‡ÕLT'rÅ!2=Ô8l 8èP᡹OÓ Õ!í—É©aF9ÑÏÒ$®C­J*Ç‘ó̬Á YZÇïñáüêe–4Ó?Ȧ¹<ú uµ°` /ïä½Ûxê÷\³žþF‡Ø²ŽŸÿŒ[?ȞטÖHgËú5ò±ÇÂë¯òù`ÇûÐ<;s¦2gŽØ³';c†RWÇÐ70à,Zdèzøì³ë×W´¶ê»w]¸0ºn]í¢EÑÿø¨+W&kj´†㡇N&“ñ¥K--ÃP~ö³óRÚ–Y²¤Òó‚Å‹+…à•WzÛÚ œbÕª©RJ‘ˆ:}zbRCÇ·çT!™¥?>RÖ±c#ŽShu€hm­Þ°¡ñ•W:;Ó CÐÔT±paÕ‹/€ rñâ]×J¶©.]Zuô¨H˜ï}oÍÏ>zs³Õׇï‹›Z[HÄ8uJ–êA£XªbR¨¿XFÙNæË" æ[KgŠ¢$&ˆ ~Œ¬%Šmö,r…'› m‘‹26›š9,>‰©´TQ3Læ,Ý‹™£b¤Éw2æsÖ¢5`Ÿ)W+âUƒ+i‹ð~·”× § 1 _ÇÞ³ #ôýƒKÀŠêÂQÌ,13‡ec9D²W,‡5¡¼LD3‡ž!2‡é]xýˆta53‡q%u; t+‹–Dz} §°ç ò¥A•>‰€¬ƒæ ¹äl®­fy’—/b¼t–¸N…`Y ™‡ÚI§!Ïÿ{=ߎl?Ç?}o?ˆªÐ”à£Ûø×ûøÂüûY±5`ÿË|ænîýO®ÞÊ¡7X³\‰Cƒ;ï”>èÖ×ûwÞ©~ûÛéú§èo›;}Úþð‡­_Ì ;‹ë†!Lû¾óÉO6>ø`¯ç¹[¶TnÞ\ñÍožÏçs_þò‚ r=vÁu}ÇÉë[WìÞ=°cG¯ã¸àÞu׺ºÈÉ“#Ï<Ó¥ëJ*e°ò©O-¬«‹˜¦öÝï¾!„‚ Èå¼Ë"£"-€D"RøxË-sOŸݽûBÉî ¬YÓ°`AÕœ+t‡L$Ì¿þë9ßýîÉ‚ç¤ëºç~Å•XLÏf {ì EŸjšºëjëªt^/3«ôbÆ[+i¢ÔËL« I™Œ­hY¨—q*ZY±Ò·1©èALd z*^¬ûŠ1«8™JÆ42Si©§¾šZÑA¯N¤‰†vsv+‹m›p7ãx·²Ì&è!7‚s 6a€pG[N•‰æ!Òݸ/3z-µ³ˆº Yd'±û;•½<:›ÇÙ¡Þ$žã… 6¼i2WЧ0`R!8©WX!¼éžþžŽœ‚3„㸋ì.ü]邇EWÓsÄÌ,1›H Xf+GÔÁ´‰NË۱rDm4‡hž¨ƒ™Å¨ YAüU¨‡ž'b£Ç‰úžZç3˜gEȘKg©Jwž]\iÑ>F:ËÌ]cdÆ‹]ç[ãôqm3/œAñÈð‘u¼rŠ®NÖÌ%bdŒ¾.®\ˆçÐÙÍH7UÕŒö’ˆ3s Ý]Ü´•ûÌ_~˜—wƒ/ …³gÂ~´@«`ÁùÒK¹÷¿ßüíoÓB„[·ê‡çœÍ›£Ù¬¿oßØÆ±Å‹Í‡êÏfÝõ냃ù³g‡/®š??úè£VW›õõúÆ5?þñqPZZbѨºukÓ|ÊqìBÑ7mZEM¹jU­ë?|&Ÿ/œ/lÍAÓÔ9s*E1©óVU%Ax^xöìPYゼü… ¯¾ºyïÞ¾7ß,!FVVF/®~啾¢&»óÎù<ÐúÔ©±úzëС,Å”¶^vð§8¥•Η»ìåÚª<`e¼eŸU–\–™ëfq>(D%Q% Ý`ÇD1µ''%[Á¸…]Œ¢M¡©‰¦th˜³hõ$}Q¢T¨¿ãÔ›©h±›žTW=Gö£ó©ZD… 6r'Ã¥•øbB î%Õ»ˆx Z º,2Hý1C*ê,Ì$j€˜‹f”lxE¹4FSxÈHë“7è”{íæ¢]…僂‚RpTƒÃ¸£ý,N–`Æ, átãÚoRHÎÆôzɧðŽ3¶šŠV¢m¤GÈ co¢A#Â>Ïpæ*š.0r†¾ ´õ´ž¢û‹˜¢!NŽ*…L†|ŽMu86-}B"’(|ô þó÷$,Òã°n"`÷›¬ŸÍîýXö8·lãá_ó7Ÿäû÷Ó±3„yT‰²~5/í o¾9üÍo¼––`Îvì°ÁÅD6ëlÝyíµL&cö³µ÷Ý7àºîÕWÇË ån¹¥¾±QûÍoz{{³wßÝò«_]´mÇqòÖâÅɃ‡GFlpV¬¨WUÙÑ‘ÌgΜš›ožõÔSíÝÝéÑÑ\i50ÿ _ØX( ‡‡ó¿ÿý¹0¼LaMr²¢Qã¶ÛæóþO~r,•² >ÔÄe±k®™úÄm¥ó²Œ»ï^ø£O§Ãà `*\ N¨ª·¼%r• 5Á/E-Ö€ê䘕^ûœV´Ì±2's*Z²®¬­b%ë** Å‹ŒUVÙ‚¤JŽ‘0¦ã·Ò²€Ùƒ¤‡°МÂý§¦Ó°Šæ“Œžaì&ææíd^gx;Ó¢è.â0cÓˆÕ i‚‡¸‚äUTäÀGd‘?cdÖv."DŒÆ;Š'Pþ‰äh±›•GºHå ÜT±0T>…á—Àä”⣦‡Z¬‹šË‚/‘7‘ }Âa…HYb # !¿É¸Eø."SQëQupa4ƒ¿žh Z#úëŒwao¢" UhCØgHÍ'žDÆÞE÷*ªçS‘%ÿ §nb^5æQ.$1+Ñzê¦o533¤Ïrv=K²)Ff1=Aì /^ɦ}ün+‡hKqêþµšïXàK Ìbo#WºœWPú5Æt¢q¦h({jxžŸYl€ç Ökr§Î ¼"ü%2ô„ßD ñTì³îkX’8˜È(¶b9¥0UPXeÀŠ–ŠÄ‚+)ñ˲±\Ì1 AÔÆÌcÙDLÌ")t¨tUÜ·) É•b yðK8sŠ£w?±‚û_£Ö`prT'H Ÿ®~üøÌh ý+—26‚ti;ÎÝå¾ï±dNŽ3ùÈGøåý¬Ý(÷¿&6nÛÚüþ~ïúëÅOä/›6)?øÁø§?ûÍoÒ®ëÝtSô¡‡†M3ܸ1zþ|n`À^¸Ðlo·‡‡3š¦lÙRõò˶í'â£váBæÉ';!œ>=þ¡µìÞÝ÷úë=€a¨ æ_üÅŒƒwí:_jmæWUYsæT^yeƒijÿñ{J=Ý(µûÿSõ (íæ×n¾yaMõôÓ©2©%¦O¯\¶¬öùç/æó²äʇ%9¤”h¥–aK+VjY,]{…%tt‰.&Õ€åïfÙòŸ19°nNöÔc%~ÅK£AÄSqâ2…tU&I*J.Nº’\ÿZÖ(íŒH”:*zÈŽãÌ£^'ÒAjgõyäoéÚÄÔZLý ,&ÙBT"žcLC]L¼ ]G=†óö b‹0Dõ ^;Átt‰˜& Š„'w&ˆJ©Ô‰b²A+޽ÃÈð bÄ:)âÿ[¦a^R-™á—1=)Aª‡P•rX0B¨"ŸÁQ¿HÜC ÏáÄ >D¼Ñ—ÃÆ‹£,'â\$¿—±:”ë¨î't¾–†²¤RäÞôcôŸ o Q4[EFÐ2ŒkˆªSŒ¤›NÓNäÛÈÆCìXË–NÞŒ“Œ©fÊ|ÞY{™Gøú4f÷°¯…+.†¸SYÚÅofñþ o€íq¢‚9>‡«¹Ž+(°+ÆÇ%?Ö™"pñ§âƒ«âžÀ« ðq_!YTéž¡æe$'b6‘ lÙDJÞV´àmå°òDJ‚Ë((¬<¦C¤`cÙDm"‘1Ì<†<¬|‰YvQgým¯Œ zÌ2øU2¹ÒD2"#dI-GÚIB@s’¸N\áÀQšk˜Q‹“gÿa¦VÒÝ>5ÌΫ;øÔ'ùÑÿÇícÿëàKÓ Žñ>óqï½öúõbxØ;}:·nñê«Yð-+ ßu½;î¨zâ‰áT*¯ë²ºZéï·Áß¶­æå—óyÂmÛêŸþbaÂǪU5ƒƒùÎÎÑ’€rî¼sÉ‹/v]¸0VºižaèŸûÜŠ}ûzÍ–ž^yYK™·CÕÑ.G[[«::F'ôTá=‹H)r¹ ¦ U¥”ÔeÚJ½­š¬‰ý’Ô* J›-w²¬2»ê²ü§QRRÑ2…-™V1IL(†™˜ÌYÂN2^XL2®“Šâ½—•ì¥s3ó<”!œN2KiHì ÷ffg ð/¿’jщӃ·† ¥÷w¤×_I|˜ð(Þ¸ÿHe‘GŒ };ÑFT1ip^‹º‘‘Š&D'”ÓpHJ1q«(ŽÊ‘¯dOIè•Òûß6‚F¢ @šâÒìúç¤| #—@€œ!…)¤"9(üçðÂ[ÑjP’ÈóxO‘_‡6C4"%=†{=ÑVŒÜ'YŽU‹0ày†®Àš%¿£ó½4MÁ:HŸ…RÑÅÈâ1Ä©©¹TÛØ#ŒÎ¢ñ(Ç“¨WrÅn^\ÎÒ!ºM仸@ SÞ°Ž³·“ƒ–J§§–Ö!^mbYO×2W#¬auš§“,Ió‹ ¡?ƺÿ²ø¸ÆQEêÂë’®*òˆëpGð´%¸÷#ÃUô¬Œç„åÉw0²Ä²Ä\Œ,1+õ'€)”…HD®T-ºè6–¸’¼(*,›¨Ç\…7‡ÀòpMKâ<ÝNÿ(éL‘YxˆÿÕÕüzã£ÅóU1FGŠ-i‘cÕ|ŽÇ—êJFú1uœD£a.ëÕÖ†CCn$Jé;Ž þ† úž=™yó´ÚZöìklTûúl››µÙ³]»ÁûÛ¿ñÃväón2©ÜqGËÿ÷ @¹uk}6ëíÝÛa,¦57[7ÞØrÏ=¯SÜ­&ú{ß;Ó4•ûï?eΣêÂ?݃d‚YjÉö*|~îsk~ølOO¶ÌÕšPRâ-’J} ª´2`i“!¥–PTRXª(bH›,©ô2lYe1+½,NU- *^ÂYBb âÒÔœhi'`Œl’TŒL”ôt”«™ï£½À™5̪ þNle¶Šž!8Aê j㘿¤{ 1ŒNÜݤ?H‚Ú׎?« MG{•|ˆ2½Õ@ûéè[¥© Å’êÏ„×Ø"Õ)ˆ¸P|)âˆ'¥ÜŽJZBJU Uœå¯¡!pƒFP ü†0]y{©\¸£½²Ø„´p'ì é•  ïVX!P<È @C>‚Ì V#o"D¦G‘û¤|Í'ì$Æß‡s‘:ÄE¼§ÈÔÃÍ$†ñü7ɾÊaœ³dÈÞLãqÆ^¥ÿ]T7y†¶ÔY(²9›ª8ÜLlµ½ô-bz=mœ^ÏêA:U”â L]ÆÚw¬ùÏZ*Á‰bdè­¡qŒ“S™Ÿ¡CÇóŒ&©O0eœ´ÀHœù’7-–)ò¨*MöÏÅ_Aî×°/‡l% xNÆq]䔘MÄÆÊ–<øB ˜#Z8(¨<‘,1·¤¼ >}á½T$Åwu1pv©$,¼Ü’“•/;°Ñ%IÉð8—fS{EuÖRÁ…‹Åa‹ úú ’ÚC…;?ÄCÐPÁ`šDºxyª*¡!¯¹9èîöb1ß0BÓôoºIÿáÇ ¨©ÃÃyðfÎ4ÚÚ2TVŠñqGÊàÖ[~ýë΂Vjmµ::R…)“[¶Ô8086V0§üXL¯«3;:ÆJ‰ª`Ö¬ŠÖÖäË/_ð<¯LF…åÑœxÜüð‡©ê%ߣ«+õôÓgK*I–`Tް‰@V9žÄÛ +¥¬?ª `Mì¯)ƒº@—¥(Cyï*½LUY“„–/š%y+VQH ¥ä2]XLŽ“±‰ã®¥e*õ{輚Y)ÂCŒÌ¢ªk/ÃWR«¡Ž¾DzUõ0¹v‚¨hÏ’E¹‰X1;ñþbYD'ò8RCÙ†–—ʘà9d§T¾.”´Ä“¢KÊÃ!gBñ5 „"ÒJ ñG/äJ•-zqRgãä%çÃR(ÑáiçRxô272€M&‘I;¬˜¦¨S <øwS!©°Z#T˜/H* ðXÀY!««Z È?$¸G΂_ãŽ\ƒ²mÿ1²‹Ðª «Pž&µm††|œë©Ð»ZˆµŠŠýôÕ`ú8§i@»Šæ—97›ŠêAήeæiÚfRŸe,À¯'ÚÂÌåïÐt•½‡Ù³„Ňٵ„œª£é"/MgEÀp‚: +Ï™<‡šùˆÃkµO'Ùäò`œ«4<©ªÔ…ó$l&ó[¸’ôn”õ¸{‰"ã ×ÐliÙÂÊËÉË+˜YÙâj`<©B,f÷ôX¹r`ÍKSúê%HåÁ.I§Ë€5aÆOpª[NÙ‡²q./(þÙ›®æÉç ¢xY2JjË$Ÿ ,Ë÷<ÏóüÒ€Y\UUa:íù¾wûí?>œË¹«VYù¼ìXJÓBß/Œ~ ®ºªúøñ±¡!‚ª*mtÔ)僫®jTU±cGg Iáôé‰ÖÖÄK/µƒZ‚”,;À–-­Ó§'ï¿ÿ`¹Èjn®ö<ÙߟìaM`K)ëv^Þó\-;.WU—yUJI:©e¦Õ„¹n”‘KÅ ˆªòM6úd7½ÜS7ÊÒUñÉÀŠ_âTaMÐÔóvR¦"%—$#[ƒ·æAfRWCìANßÈ,ý÷ô¯¡¦žØOéQЮ¥®ó§ €ê Ý8+ˆT y(/àn†.TE*_îZ´-hå˜äQø)ª%VÈßòf!š LIþÎF X§²R#Ô* „¼âò‡<:ø!‰R)ŠíÉ*ô²5ÞˆàÏH,GÓ¢!ŒOl#„®€§ó( šÂ7ã¸xI$†Â:h ·™,TÈ F/†ò˜"> X§ÒìA>Oð)¡4þDzSDøQô;ÉßJ´ç)Òµ„ï%Ù‹}–ÜTfð~M×:’S0;[Nu€÷gneþQºû^Oë#•˜‚ Åè,šÞàõOpG=ýAþÑ IDATµïXÏòÇAà ½-ÔeN`¦é¬¥N’1Q|†B.V³0¤K'p6NƒAEÈ.“&C&t!Õð$^ žÓ W’zü :$ÁDÆp5½ ¬Ì4‰‚ÔÊ/•„QûRIÉ–J­JZ¬€ˆyh6–MÔul‰+ŠŽ»]Æ£üÛI­rBlxÿr`ÿ­,wK òŠçÎäÌ1šüLÆsófñôÓvéºpɵ­-ŸÍº¥±´a鯄Ñ(BøÙ¬[šI[˜¸í/]Zqölʶ çÃæf«»;u©Ó7ÁâÅÕÇIy¤Š¨‚Ûo_øì³mƒƒ&Ç ß©Ë^圓%ÕeåÂjBO•“‹AíR%¨ªÅÕ@½L7““ëåsn¢eÉu³¤Û§ÇGHöç’¿¯Æ Âbàê¨C>,ºëgÒáä ÝŸ‰Ó•n©®0ßD/Ýç •Eª‚—m9Å"qMW°ÁÄTx*ÏÙ€„Æ\*­Ï{¼Ü ‹¤`‘ʯB9¤°R„„!|Lú3…l ¨GùùEð.ôqücä[â%Æ¡/Çz‰Ñéèq8GzúYƪ`)•½Œ«„*® Œ¡ôÐ_O,ËØf®\ÉÂw¬å‡Xº—V±ò/Ï`拹²‹½ Y:}z§0§Ž…ü¨žÅ’Á:®¶yº“,ÙA7eÎä}È]85"ÐȾF0—ÈõŒ<ˆv™„Žb¤I8"’%š!^(³Ä ù¬• ÞVŽX™Ú²&|®ÂbasbNZž0BWÅ‘äÅ$`ye‚kb¹Ð.!iBp9¥õD·tà—X”.öJ8óKï ÂÒQá ¿tQX&¸ü20M±|U•BÔVXöò'UvR–™S—½Ê·7 ¼]1ÑCf2¶&–2Ùº*'”(!I™| O®µÉ.{¹°ÒP•K`ÒË‚ úä\•9y—U–·*HªH X1IBEX¡¥Ùq²1Ò…Ž IRµä¦_Ét ý!ÎÜÌü} 7«%º‹ÑÕTGÑ÷‘aÌÄ:ÿ,öuÄçywÆ4´c„¿'¼³õ1žB½ 1]*Qɾ¨HŠ ÉKí7hÄA„dCþ3Ãâäâì{"Ë«y¢’ÏVâ…XEbøÇ„䃕Ì0$‘B;d‰^êÚ'åÿÞw±[ž$dPÐ/¦Ùo£ª\ç]±â•Yp`TòP†[â,4ð)I^ð@žkMÖ H:ቀ¿6hRÈ(ò»R4ª|LÈyŸðf"?ˆ2€ÿ(v-òÌo3vêv"¿aÔÇû45ßãb b;UGYOå)FÞ¤ÿj¦ÙCÛf¦=ñíÌ>M×â[Y>†w¬{y2‰e¸–xš¡$f@¦šXžáBÅóé‹uVPpªh…~…œ…©âë8}:¯²UñÒx!þB<°šÌœc˜EÝZت•—VVÄ2ÄòD2Ä V–x¡èËËÛcÅíKõ`¤PKªE£ ¸L/0pEOÚÊ-}¼ XnÙî{¹Ôò&Ë-#—_âš7(Yú”Ѫ  l•ó+(]BPS£ézØ×—-áé2BM4]ËhN†”ü³?Äâm£ío)ËQ%ʼ*Q¦§”²\è¶Þ³*?0@GUP¦Ä—BU ‹õÉ’jb˜M¤,N5ªŠ•V∨4 'J6)S1‘‹“®bÔ$[‹y3‹.;ÄøRjtÌŒÌ'9BxàCÔ¿@:‹²™Ä1¼#ø3ˆ,%r?@]¾°å&ÔÊNÉH(îPD*`o@‡/oTE…d—G:@„Ü`ÐïsÖçŒÃbwEž·1$gmfè¼;àHvgP%=nÀ’(«bèà„Í1â…Õ€KÆ/î$”’i¶Õ¾uÕ·ì—¨3Ï #(e7VSh‰ !Ì6™e¿Ý—å@M!¡QcSÙçiÚ|"*S t•wY¼šçpÀ\“•¹ Ã4ët†„Ü)EB‘ÛUq²F„sRìn=þµè`O!ÜŽùãu„Û‰¿FÊ tñF°7’Ìãõ‘®A ÛŒÖG¦-£áÞÈŠE´¼#`íâøÏyþ–¿Ê×°¼3ÍÔg÷®ðÖQ9ÔÊÂQöÍæZ›¶aŸÃSÙbÒp@C“œŽŽq#ì0à BÜ ØàJä©dvMø£AT¸Š‘!QTi…b0CÜÁœìmÅ좶2 ®,q-KÌ+Ê®h^šy"a KÂx¥÷|)–5²‰4–;¹$Ì—LË/±,(CØeÀò@“µUá¢r1u°ÊÉNæ”ÿvœ ʫ·p*| §äŸ¬.×V—½‹·¨*u²Â*÷Ôߪ­&„UjPÐ ‰&.UåQõHÙ†ë-û–£%1UYqHN¤P ?.Ò ™‰Šl%ãme6Pq3àÜ ´Æˆº‹á£ùè>ª‡î¡ûh>š‹üÿì½w”\×u¯ùs󭪎è ¡‰@D HˆI1ˆ"%*ÊA²Æ–%'ÉóƲ߳dkÙzšÑøIOy,9(¼‘%+Xz3 ‚@Dˆœst¬tó=ïªj£ð<³Æ²]{õêuëöít÷­ïþöïì³7z\ýÐ"Ì­ò2A‹1"ôc$hÄ¢Šˆ)8¼âåUeSwÔ]¾#S/듳úUë”}•/S_£Ž;굄Ҕ•¾–!¥ÞP@¥¯ƒ§©¹Ê¯ÙVTü<„ñZÆÖ+Ž_9Ê:ºÕUBH….^¶À¨×¹öõgê ¶´«{ ¯ž¿jß+)S“À"4 j“â#s.­ãD&šŽv™`މö…äÄy¢>LíIü[±b;Éõh&rébdr¯b.d•²•8œÒ]Cå¸É¨"ô!¯j÷èp>â Çm IÊsElÁê ©BS°·È@ÀB—éVõ/£ƒ.(ļ0Qõ°ÞÒIôª¿ª&0~^?þ„Ú7Š«M„öç «g–dés@+b‚ËÇ<2:77UoíÉ”Ý%,[²h %é2Xc@"xÌã!9‘p$å“!دX¥Ñ £R½@ú.Ä9Ô1â›Ñéir~r.ú6ò·Ñtoo%MÏ3¼–¶= ÏÀ–¨a&îeqóÚ¦æ4¢hÄ/^ÈÆ¯ hDXhD#ÑV#ш°шF4¢¬F4¢h«hDXhD#ÑV#шF4€ÕˆF4¢¬F4¢ø… ½ñ+hD#þ]„ªµ Õm5¡c´5€ÕˆF4â&„ õ9ûi®ì í͈ôêövU¢° Ðóqd¶ÖyË¿º©þçí¸~es!ÑmdJÓ[‘™×†æ?ï‡hl~nD#þ­i)”PQNDt‚‰orù/)Cªã.¤åN4éT[m f"M.´€Z߃ÖQ»ÀDæê°ñ N Ò1PW;‰DWÿBC†h)nÍ÷¡ä>ƒH”°ÖÕQM•ÿùÒñ5€5õ=?÷›ÿuüåþ•ÿhÄ?ãnOù±HÏ ÿÛ%&Q‚Hýg º”x€t½ƒÜ; „B  þ!T­å¿š$>õºBK¥˜Ë¯¦k D{Iµ;ª‚x’àÆ4ÄþN®†Ñ¦Œ~%›SÞ¦0Rb‹ûßøýûZ K1.¾d³Þd>J)ÀuÉ£Äú„EZ튧@¨jW=ö8Ÿ—hJ`”Ø!Y߯G%®Än@­ÿf"%PD»¾ª©f@FˆÒTK½™–_B!t¤$¹Lþëèíd>Ò½š² U…Weø›Ð__aAeR⫵©å£ È š~m:J§¼Y™-"ø!NŒEj‘èx 3!gŠføeS­zÅ[óµSB?žhÃÐb SgNJO¢d,ôÃb…B%h ‘tòæÊjc%=U Pm,6jDøc‹ñDÞ‘Ÿd— ÑHh¤§Q#†ˆuRÅI‹&®”†`]‰$wD´z„’®;¦­…[¸>CO[øW“œJ˜˜à‘ˆ’ý&c¢,¾†xP‚2ØïÄž‡æ<šDf0ß‚1¤*ïA(ÔED Úmˆ~„ª¦k¢Ò\¼~êTÝ©jCÉ’ÿŽ’:Q tŒ[!!P¸øß"‰ ѪPÐm¤§â‡ÐH,¤ý—Rû­kI Åÿ›‰cê˜(K(-M5BiÄh!VRéü)*ý?‘Ôú|Fè©’JÈ¢+„B*‘"R´ºv¯S¬V¢ŽÕqåŒ (DS©!ªÇ¾Ø$ÒP¦ "ƒH'¶ b%z*D£­PFK"m½óu(ñB„ ù™Ã‡E#ŠpÆ™œÎ›Vñޔȹñ‹î% ÑY¶ ðdžÝYžE¡èà;”r”¤§ è˱˜ê«„&Ô¢o Ý޾B¯õ—UªrŒNò]80… !æÃûks_¦R_”ªïcLGû$B)HP *“«#”N²™p‹r>+”ŽJQ ©¢ü‘Fd~²$1îýX7þ|`Œ¿ ófâP!…ÿ8J¡Ð3$»I.`’è ÉT#!UÒˆ53E¦ÈDè £¥È-EKªúK¦ˆ ª´Zv™VRdQý™ÐHªB+“P¢$©F"U*IuË$*Õ’T¦) 2TW§:3ÑC¬9J{QØó½(-Ë"Æò,ñ°Š2¬åŒË %¼qŠÐ*Éžá\; Z˜­È\Ïõ3èÒ«óJÊ«¿œgì%ö$Ç9<̾&ÂM”¡”¡èâ»”l|—²”[…¼c©©Hw¡¿Š(A¢deŠí1¥Î Òš5q;h)A-Ÿ« ‘DUÿõ!Å.êŽRUgÄ‚»ÀSóåH Ð:ÊLøoRIÈ•" ‰´ŒÒÀ"}–ô²J3BÛˆpI”Eøî'0ß}MÀRáé8©ƒÿGXŸDåPçÉÿì»0ßD’P| oút:þ&¿Mzæê䔩áO¢:f¥ª,µŸ“…SYiê^ß‹½öY%ˆ¨nÂC¥xï |KÇnG<£Ü_òÉé¡pKìMXhñ¶FÊ1©O’’ñ±B„¢©LœàFh!z€]KlÍÃC;Äð‘!š1öš¦‘íÂYLVÿ·²„Úˆ_L%“þ„óþiÎ22šÅÏe(9øå %§Š§’—¥˜¡dãg™tèÐÕœDܦ(§lI•‹˜¡±"!7agÂ%…®05æëÌNA)4…%Ð|WU‘eÖh%ht8,ù¬“+ûFEm. QD•´I£ÇdMe4¢Dhб]’TàkÌÒ¸AH¤@$<#ÈKºk¤šD¼C¨×`º+|1GS¿)ñ%š`—¬U‰ÊTñcḂT…ÿ уõkeâOa.™÷ãíĽ›D 2ñmR:Æà?Ñ÷GÄ!CÓq§ÿ–ÂÓÖ!]®ì`Ñ'˜<ÍáïW'¼$5–ÅW1/µð7 #àFruDpÓûO§Æƒ±x&¢; 3É N@.@Ø™ÑÌš‹œkg©‡ÐéÈÒ¾Ãôá(c7sCžäi.\GïsŒ%XÖ"ºZˆy#ÍKqnÅm®Füˆªx1ö— Ê:ž—¥d¸”]Ê6~–¢ƒ_!”E¥X¹ G>KɦdÑ"¸NÐ)¸.E(DŠŠ9â³)ÃG¹Š'“BŠòyÁg¯FWï©HUͱÒjrWy)BÎLòÈ«ëÌJ4q¿A_]>(²âZ‰ªþJl 9 Óå]%‘%б2ß‚’ËG5ZH%¤PJ5›âã×”z|K0ž°K©£º˜-Y+ð¸Pc’eB]‡ŠˆÿQiŠTŸ"ÜŠù~R‡àY¢Öí$…GI›hzÅ„ãd70öÞM·2¾‡–[0z9ÿ]œ~°;‚ÖŽ–#‘ö|‰Ywsâ ¦¯cç_¢&èì#cáèØå}dL²íØÚEZÖât ãö+ýya͵¡Z ÇGOY0ÑœÒ` ™v‰ã}cŒF¸“¨Aa¹wæ’ÎO0øŒ>Ü ?Ij£w0~€iw0¸ƒÞ·söqÚ®Ç÷ÜÚz0¥ý8ÐÔkѾâ·qÁ„lö‚Tߪ·{â! }Œ˜>EË0-–û˜)­&3ÎrHgú…;yÒfyE¦›ž­œ‡æ™u‚éâlÃk£)F÷±:ÈLô1"[•‘‰ù©/îUìõ˜ ŵ’ÕXéÒmÒ¬¿Æ]Ûˆ'„J§}^,s^ñdÈæ¸2¹Zá`h¡%B§šñÙx•‡r†²ƒŸ¥P9S–K9KÑÅsÏМáV“Å1ž 7Ê·$]YÖ ²)BäÛ:ÓLf8Ì‘˜ !#¼`ҮѢád™$¤•°RP­Ð†Ø1©ê|÷”Ôk1+­|ÁÀîb½Ä¨¯bN P$yŽ DÀ%…Ÿa^ׯ¡•9›Pò84{u²‚@"|Ž6±±…û® Xƒ|O\ỊboÑi5pFùR+”hŽ$òyÂáv 'e3˜K'Pß“¼Uª•$”šjñAâa´ÄÁó˜·áŸÅ?Nö\üC:> W&w ¥Ë(£‡áÍ´nàèW™ÿINý§{&ÿž&+¬zXóƒÑocGØ1tþ.é˜'”+íã?J¹'ÏÓNHK‘É.>9Â{˜KE¢˜Ö˜\‘d‹-Ú3´ìç|3EÄAòXIîVÎý-=eàQô.ŒLœ¦ëVÿ9M9ŒBu¹0›Å.bTnŽ,vIÙ*”$ün‘ïûäJ$Fo½Èö„f»ˆ¢·²ª™ÙÇ9v… „QFÓi›@-¤ÿ8åèD=ÆøuL ±†·Ðºƒ8BXû0VaÎRÚ?…bQÊãÚSF=ðXg†d¦k<2Àd;a]»¸µƒ‡Ž°~""_âÐe>v—&¸!óÛYßßxûÿëƒðõíl¹ÈîaÆ)·¦¤¦>»5aU9p”´’ ˜*už™š¹ž¡l×R¿LX^†bÅ´Ê1n‘oåæfÖ%$!…‹<1;uZSôÉS<:e]¬Œˆ’ˆà8O´ÒßÇšH!@ ñ&¹r‰CéZÞ–"S’¤²[¡@‘z”J!¼Óˆôõ;}Vj¿SÒeÜ’W|w Í&+H©eJàF8ï’ÉËÄ’ Q8ÅÓÙ.–8´I”†v†‡Wñ­,¸F…õØ8'FÙ5÷‚ïsü1^˜Åûå"G ìjeE–yeökå¦#ŠÓk5Ù.¸œáÁ„ÍB ›â~Ø"Õ.M}R¥{E|Vãó÷âŸ@[DpšÈÇ\ÅØiþcÛh½—±Ý=(“±ƒ´¬âÜ“h‚ÒžêÃʮݙë0ÏcqPν¡8Xf( )¢+d†Î›.ò=ÁÒ;ašIßqv&4“ê´:Ì0iÏÒ¼“ ÝLßÁ•¦]$ˆÈ´Ð< ¶Àº€f‘‰1|¬&e_BóbmF(FBÞ{=ÖJDÂîVÌ‘qÊ>‹LnÈ0ZæRžÛÚøêKüÖ"^¦PâØZ §Éé<ÏÒNÎ\æMý\×ͺyô¶ãšôu¾î›¤ÿ"lžÀ‹-òŸÂuyú ¡¹¦¤ìZaÍÕ"«v‹Vl…%ȤµúÏ«Àrªžz©âU9xÊ9ò.^†byƒülެӛ礰Ӯ IDATÂlaA‚gˆ6ÓmÚ$†$3ÊÉAŽÏdµKk‚’8ã\:Ï®3pr´+TŠ”èæ‹<–B+]mt§(+CVUk·«ªJÇxyUŸÆ•\¯²eEÂ(W4ä.å‘0‹…Ó˜)PŠHƒ ®缋;›5„ É3è3:Ɖ٬›Ç­Ì½&`ý”?ìdžKNžn¦'CkŽž+ìô9ßÉŠ 3‹,±¿‹;mZGy<Ç\‹öIÓ ›¸Ýbf™o¸l0èKx\S]†èMøÏ†ú FDrÞ©üÏ ñ>T;þsh׉Æ1–1ñÎz†¾CË{{ÑŒÖGé,å"Í+(ìÅÛU½3ÜšÌÎTŸf©M M+@†Ì*’–‘!:,(P( Š˜‹yç~¶1M£¤>¶‡~+Ï2™àŒ".Fdši¾‚ð°À¾€v-E´óÆ¥T |1=f"ÄóèQ\.Ï*‹( MÑ­óôe†Š¸Še./žå¹üä¶Á‚VÂʾõ³²Ìn†˜qÇ"6ï'§Ó×ÊÍ xr·-gE?Óš¹ûæ¼þe õ“gb¾ñ#e ø0VŒ•¬:<™S`ª}X5…e×RBC \Uv…—¡ä๔25NU2¾J!¨K¹‰¼K9ˤƒ>{/³c.÷…„>¥³líä†&z’ùK[Ä›2F¥ˆËœ¾Ì¹å¬·ÉF¤ òäC¢““ËXaá&¤•¼¯ŒïQ™§p‰Ë ™.aa'Ó~n™{ý.` .1xŒ“Zµ²:Zβ„$ƒka ” Q`ò ûÑ–ØØY!P®œàÅ…¬Ñ‘Z$J'³˜ ׬Cl+3S>Å ×q»0‘OIÛè ÏçJË|<Žg˜ãÒ^dG–ev™>ÏOãƒ)}ÍñfI’²Õå#¨‹R6¸ õwR}’ø!‚=h$:M8‰¶ÂÃù0ù-dï¢p”4Bt0yˆT¡Í„&NþÍÕÛ¢þñeµ]ž[Biô*Öñ´O& U²`„ >2ËêQŠ£Œ†4Iºl‡îQÂQ’+¨KŸ‡ù¨GÉ/¦½’®§ù 3QvN87Çbnªþº$nH™–ðdž÷XðR+fïaÀlƒ[š*r¥Àü—|êöP(qè"¥IÖÍÂl9‚±¸“‹C4Lo&ô9xœ®&²:—XÜÇ /°r)Ëú¹m-7.£µÛÂÐijjæŸ &%êÈäûKÁØ_ü:è¼x„; ­v›Y`ÔŠ–m0êU¯§ìºòæJ˜©O™ën g™Šû®t#ª¬{.^ŽBEaUrê„Õ¸Ey1wgè)Qg G‡AsLrc£Œ®áî5Â@_Úɜ€Ä#,Ÿ ÐÏ\ž@cL 02BþnÖŨˆT!òx%Ê égÔÅ^Í´„ÓGK˜×Ipè8ƒ®&.\`å"6oå®›yô6ÜŒJ8ô¿ñ+|þÏøä'Õ—¾kZü–·¨çž •J>ô!Ã4Õ¼yòþûmË–%Ë–%ßøÝûo FUW%Vår𦠩R¶ŧ?]Ìå´ŸþT=+AM¢ƒY)ü®TÀ¤×©žVN UFž¦rÀlíåÔ*aFa£±KÉ~§^pð3›™´ñsÕª…¢ËøÈ3zžcÓ˜ÛÆ…v˜íóX¥a*tûY]Ëm ú9ÎåäZÖdiJQñ‹pÈ,ažƒhæØªÐû™>‡“êÎ@)Ñòø[8ƒBؘkèÓѦ %ÀÁxeçO(¾ÂÉÒ¸x…<½Ÿu 1¨”D†Ä1IÒ~N+·²Nƒ”$$¨Í<k³¸~Dx˜·sÛJ®­½Ìnö?Á33i·1gÒsŽ3#\šÅÌ̾̉ Û™ÖË‚ƒÅÍLa—Ck3s†x´‰^w’­-\ç2»È&—®ˆc—Û¾ár§`H2¦Ñ,Õ™þñ—•ºW„C$ âF¼ˆÊ¤Í„“Ä’¦ûü'­ø Ñ^25«¢°2¤º,áXNÛ#`•q¬2®‡b–°}2!†d4]Â/ã´ÓaGØGñÜ–‡±”¶tûzX—B­7¡-ä°Gs„q¡Ä|!“>ÌÑ95Î]í5#bÏK/Î,Y’½Æ·ý¿–8z´tê”WYízì±üÐP<6¦ÎŸW¶­%‰~øpL•LzI:èâeÀ²ê€e¼°œZ2X–[çUMé)çåÀÊ¢iqFT*×ý,‡r¯‰|űj"_QXÓˆf1ŒAÎ/ãö€t”Á2A/ý1â,§‡éc^;ÓRÄaމ®c¾+ÑÏ3tšá^ºú™¢<¢!&O3ÚMëRf¤¨r„â ùA¼ˆô^æWVÃZ_d1éòµ:Òª?@1ªU–Vð¤P³iWiUÙî›öËb‚2‘ŠDCfè<ª;‡å O§YGHÔ“4dmä|f¨'ÙÓŠÝFfÍ«XÚCÇ5ëOø›Üá—(íeßBæöÒP:Á¡vÚg23¦|# ¸^¢.sð/­á휹ÌÎyÜ’Pæ¹ùܧ(86[=ŽØÖLJ/ó•nÞó’ÏÖ~+a‡$±™Ç u‡"ÔÊèY•†"ØGh‘æ×[Äcø&öáÜD"È_ |;|°2à’šÂ¶íã”p˸T…XeÜ2Nˆéá”È$ØE,;À.á˜>¶b$d<ìå´=A”`†ØÒEØf(Ã$À X ã>o±ùî0zÈpåû‘‡¡ˆÊÜÙ͓ǹ³—m§ð}DHZàÓ÷ð…£ \Áš>6í„GcÝB¶îâwßÅÿù7 wÜÄSOqÛÍlÞÌú5˜{wóÛSŸû\úÉO¦_ú’É»ß-¶oÓ4ijJõ.”ïx‡û…/ f2|èC-_ûÚ@o¯þáOûÜçNï}oç訿iÓ%Pø‡ }?BY–hjÒ>ñ‰…Q”J‰e½¬Øö¿À€¥r9¾Ú°WàyIån-—“¿ýÛÓù|2Šø»¿»äyñ]wõ<ñÄ8Pé÷$k’Wñ„Q;°@CèÕ¯LqʬÓY—ëYužz½ÎzÙ"`PUÕ¯°e𥂬(å(Øx9 ••ÁЧž£P)°Ê›d°F`k8»yv7+ä #§9³’USÃ<™Vš3dLìy³ýL×1@j˜':ÊÐzæëºD?Çøs\ˆàý,IB!š‰öMV ÙoazN…Gv¶š"”D¼z‡Rkf7%²TL Jƒg¸4†Ÿ’¬¥g­ªÚÒ@E$Šô#Gü7ÆÄ)IH4JþEŽ7Å¡"i!·‘å׬ç8z™‘Üë¡y]f¨“ÌLºÇe¸§›ŽÓ5P}ô˜(10ƒ¾z8àÉÐr™çÚ™éÐRàp33rLåÉ.î)ðL†ÞóFÃY7‘¡ÚtJ"¨ûð¿Iš!*µ¢úzƆj!XËÙŠ€toU‡›Wï_³‚*žÜnˆUªË)WÅ—[ÂÉÐ5HXÆ*cÌcц½ª3f0m?IˆâX ÖL21Ƥ2»"y2âJ™UŠEð ‚|útҀاMpt„…2&ðXÑÊv²nçFóšyö(Yh·ÉH‚27ôñçyÏz~¸‰ž&._àýwóÓǹïV~ú8}X’—^`Þ"Nbf¯ºx!íèHŠÅÈóâ;ï;vø×_/''£ýû‹K–˜š–8PX¾ÜvÝtûöñùóí¶6ñâ‹c3fXýýæîÝ¥RqíÚö\N{ê©‹.ZÔÞÒ¢‹áÁƒ—!½á†ž8Ž+CöÆ;¢(*Uì×r9JÓtãÆÞþþ–4åUž®%Ä«Ã0ýÞ÷Ž:ÎT5¡”ˆcµsçH奦iû÷€Vk·&ªÐ©òH«ã”^ã”ñ*Nu:º¨¦~Sxª¼´k«¯W°jüzµ¤²^QgS[t0Œ ÞS·)gk¨j"Ÿ¡”cÒ"ßÜ…¬.\àÌþ2–û$Ç9#0° F]`¨@tóÒ Œz$Md{h-Ÿel’Ð#½y>i§÷PWîcN@š"$Ú† $>i+ÎjZSd\ûýŸ¤X¨un 0µ#'ëÉÍ®¦–Wãå”§ÚW°å¢5¡R¨ä2hBG%¤ éS\6­:tbÏ"§HÎ3yšñvÌ&Œù´{{¹h!u’¹¹—¶kÖ§ø±$ÝȼˆøÃÑOGBx€cÓhšKOBxŠc×±Pƒso¢©ƒ¶+œ?Íî%¬Š)Opú:nõåH«Îñ°†¿ˆ÷Ÿä¯gó¶€#6½.­Ežiå¶€§\ÖÁaƒ_²GgLÿB¤¿M2H:o+iÊÄs4†â"Åä!:?ÁàO‰O`ëü°‰L½XV™L€Y&S®¦„7À,ãúØV 'Äö±=œèêy³rY%© 1åHbðÀ‡铆h!x¤1¢B!¨²ìî9óY>÷ŸxÓF‡Õá#ÑG>Âßÿ½ÿGd|éKÅ ˆÒ4ø—~É9z4ع3ïºéÊ•ö¶mýýÆŒú–-#¾÷½ßÿþ¥övýcëýÑ.=:ÙÛküãsÿñÏîÛwÒw¿{öÂ…¹¯}íðÈHYӔꮻzyäT¥×(•|á ¢(ùîw>…,ïåìM,H‘¹ÁcŒm`nYÚ&ÎßÂŒJ M…°Ñ¿Â‘4ßJWŠ Úû[\"x˜!>F¯…¨(Um}%U­x]†x†‰—(Ê—+¬UäV‘{…ÂRWû¦)JÀ9¼MŒè(>Ìì„T‘$¤&âÿáTB²œ–µtÆÄ>Æ©„äæØÈ˜h ½ý´_°6qvü.»hÝ8 jˆ± byJÌڈ9tœá¼$飣H±Ìx7í%ò …iLk¡å2‡šÉæhçx+½yN¹™„BQt±\f…ÒI4")7ÉJJ¦RR†ÒI'ˆk$Š($Ì’DDŠÔ"T„‰¢¼•líù–›Ô&ÔÌ2n‰LER•È„X%2SfV7Ä,“ñ°+†W€]Æñj9ãÔA€å×R RJG.¤'ÁŠ8VàB†JÈ#f¸ÀºfvÐ' †"ú[Ð"Æ&XÝË£[èî #1GŽƒi0·‹£‡X¿’çw1³ çX4‡#»™5‡sÇéîµ8}*¹ãŽdÓ¦pýz¶mó:;ÕêÕâ™g¼;ï47o.LN†ë×[š–>ûìèý÷·^ºäïÙ3¶zu®µU<ñÄÀwv–ËÑsÏ Atë­¥R´{÷¨ÛnëÊdäsÏ Ž!™7¯µ¿?ÇɦM§AÚ¶¼ýö^¥Ò4MühÝúQ¥c™Ø¸qn6k„a’$é‹+Ë2ΟÏîñ†%ÑSŒ»á†éï{ß’¿ú«].ëEVD¢NdMõÛ–5%¥Õ1jgô—'€Säz9¤¦¼v¡c* qµjÁ®+b0ê,ª©",»n?`½iåÖt½{õ‘©›¡‹—#oã73Y¬ ¥ùëY0žƒœppg1'BãÂ4"QIë*é^•A~\•3a•Yxˆ˜ù94ñÜIÆÇ©NMôÁc~g/Áã¾›yòy‚1ˆ¹m›Ÿàþ{xf…¹ãN6=¦fÍ"ŸÆÇ£•+Ù³§òO&­_olÛV¼á}p0,C<{¶yöl)—SúéÓ“-YÒtèÐ8$½½vDÃÃ%Hº»]O/^ÌCºdIˬY™§žº†•§ltß}ó„`Ë–s““^SIGGvÅŠNÃÐòyëÖu¦Òµ!@²aÃügŸ=USLUZI)ßô¦ÞgŸ½\V½cUϦ©ã©°X¯2׫:J ¡a(,qUa™uå V]ý§ñÊËW=õúužl%¸à¤ŽîeUÑ^®æ©73éRÎ2ž%ߊ±‚å£x%¢EÌ¿ÀðÅóFæ>Ï)—ì|ºŽ12J0¦¹LóI÷3fbÜHÇÉN®˜XKi¶1S&Ê`,#«ù3Æ ´Èt`4…ø1šŽ ïÉ FH·(„VQ¹]VMwY–0õøQ¯o@J”YË}”ŽÚG2HR™ã‘J0P·`·#%éÃx:iLš’’wÓ–’î¡8J+â÷Ðuï …ˆðWéÝx«„ï`Ÿ$¹—ö„ôŸ8#- È$ÄßãØMt.£E‘þ»~‰EÊ[9´Ž¹½4ÿˆM÷²F_äòuÌÙÍvp-·œç¥itÙh\è¦ï4O¶Óã1qq&7&L´1ËãÄ4Ö^á«]|°ÀßäX³µ…_ù¢Ãí†ò5<'øc‚­DŠTgr3~ŠŸbr7Éâ¹Ú]e“º¢¨2eáXE²!f‘lE:U²Å°Zè`{WÍxgJaÕ’Á °®fˆQjŠª‡Ôqª^jMÑjJˆE0#Â6ïU…šœrµX6‡ŒÎöÑ5â"ÄÌ™I_'Ï>®—+îf¤T¤ii’ÿñ?:_üâä[ߪïßïŸ>í ‘@2gŽüÀšÿüÏÏ ‘~üãÝ_ýê¹îníc›ù'r’¶6}ÅŠ¦M›.ÝÝæ­·v|ÿû'+ô…@©¸¦¡ÂÏ~ö–?ýÓ­ kg`Þ¼–¥K;~ò“#\]ÌþŸÊ·¤¿ÿûoú‹¿Ø^k¼+ë–ö:ÀÒëtÖ+¼ª©óå ˬ3Õõê²à”’2_Î)³®lÝ©#—SwàÖP•½Zµ€ ®Ò¬Ä¥”ÅšEU¨ÔXµð?Ø{ï(9ÎëÌû÷V®Ž“29ƒQÌQ %’¢$*Y–lË’½^ےÚÞuäO¶?[–“ä$Ùþ$K¤)ÑMJ)f‚ ȑӓ;VuWxßý£»Õ3 Ç»ß:Í=uæT÷ôg¦ªŸ~îsŸ{oѦt«sdO3 2¯LxŠÂbCˆÐw1´–ù£ÔNS]Ïœu˜j7N+D%º‡¡O³´‚ª£îaìc Ö ÝOñtÍà Àw©$žõ>2uˆá ~“ê]8+ÑUs†Œ¶¡#ðu‚FV!.B{ztN!²ý‚Ã_Éæ4d%QïÀXA#ƒT6JChHˆï&«Êõ9&ädb8à >ÇéØ7‡øZ:V’>/ÀºŸ‰!j{© n¦óþ8^•Ú­Ì9Bá“ñzz^åTö|2§)x/bÑkpYRïBæŸàXÉ<®†Œ)çH×Ï’T b&(èh£)z%§SôjL¸:Ç-˜œ64”!uê?ò­DuB…ì ^¦Q| – uâC¤ãFáFÙ!´ÌªrkÂmàT•Lµ Xé é«•3:Iüªµ ¬¥¾Û5\'hà—r5EMœM ý «ÞâYµfx–‹E­oE೨›åý<ül+m š7.[ÃóϵþMÑø)…RN+@6¾f2²«K?^o½ ñʨu4þ•uër;vL4þ-[æüàG®.síÚü‘#åãÇ ðÚ´©÷•WN‚ÞÚü¡ Ú´i0•ÒŸyæ0-À:OÌšz™h4pÐJ0¬d(Ú³?­°ŒvÌ2[¢»5CbO–¦a),Ñ„§¤ÍjŠa¥†u;á\Ÿ‚­L«˜n=Ì"iëÍ  M½qž¦šaR§ø~Þöû]r 8ÎÄþf–`|œZùt£>èñ÷6ÖkJ™â”!oUµÏ y=QŒv5•)í&û JÛðÆÔ_HÞR*MM·®«:v•L™LƒpM‰ñ xj £–]%ÕàV 8›Ò¶|åú•‘N]4åª)ž•Ì ƒϪ·@Êo©ïSbV²’· ¬ñƒaëkÔ‚°œ¡ººÂŸù>ûYÿ~ÁøâK­…BS‹Ïäœýú¯ÏÿÜ炼ùæÎG‘2j­÷ˆ[?Õ\L¤ëÒ4©Õ¦^ GÔjá±j¼ÒuußZÚ–H`Ö9on5­D8ãЖv®ÃhW¯¦fKÆ2®«i˜å4 —™Èíöj 8Ò-†5ÕX“i)VSô*Ó¸»Ž ‹eךêT5%¼ 9Jª&-ªYÙÏàwyî6)ŒcL®caˆúv]Ä¢ù䇨=ÆðGX>‰|€Óïb^ŒÂCŒßI;¨=Bõ=tõbˆç©­ÆéŨ Ľøb]‡å#|Ä+į ?¡,Sh‘„.ÄP/+þ@ˆˆ$„ àŒä¤h”÷bůXäfvâ¼qNØ05XðÙª )ÔZ·C$Ð)0)ÔÏ£l¤®äû…Ö2¿FÍA¾c¢ñe*Ä«[ptÔM¤WcŸ`ÝKõ1¼#x.\†;Dp Ï!ÚDn/Eu5»™<ÅäædrˆÂõÌÛÁP‘Ò iE ΣcºIéDö‘/1ÔMoDA£S”rt åÈ Â,Ý5veXg\:#v¥Y¤QÕ)h°Yl*i‰ƒB.¢þ¼5ü ÔfÄ &¾\ø!ñ$êYpQiD•¢&ìŠÊÔD“a5ØS…L½Y7lr®†Ë¡Ú¹)¡OªXUR!¦OÊWN€­ê¢É°fªïIݽž@¨ÚYÇÖTÝð,´5ž‰“€BÈŠ¥*ãŠmÛ„J‰ hÍC×ã­mÛŠ ×2•XôCôîwÏ¿ï¾C-}j½šl_[4åZ튻JÜÈê} É<‰SçÄ,cFb8°Ìv’5Íi•¬¶ðk* ´P·]\OÖve}ÊT•j™2 W¥Q Ì©RVT#²”:(ôSOÌ¡{9îa(D[Ç¢§8ÒMÞÁ|…ѲoaÞKLTˆ×Ñca=ÂðuôûðC&ºIm&3QYˆsiý¼¬4Ú"Ì©b]„a¡½ˆÜŠZ‡Ñ‹¶QFܧ”©ÄC±ZVØ’ßSXR ).8Š.×ÑÀV(E£àkUõÆ×óœ×VÂÇ,ò­õ8§{%šAQp꿦57½ªT5*Ô!?ƒ¢v)Yñ+„?™†½DÆ ~‹Ü­ÝTÿ ÀÚÄÄ»0ûà7(¬A»§ñû ßDj9ÖCŒ ~’¾àx7ÚÍtoed”ÂGYv?¯¯£SíâØ5,ÌaìåèE,:Âñ¥ ¾ÎîU,¯0âSð™^ÄòvÌeøiR<{oóØ'84ÈmŠqÁ)‹XòL†-[¬Ôbb¸ïŸ(í%õ3T¶Q§|†( s´Q»QD é_wj¸e2 C‚ae<\¯™6«‡ Ñ#bVÉÔ›|ªQ4l8¹ÂÈj®÷›ÊúY†5MÌJ¦„ÑŒ‡õvJ5 °¦N¢Ö·â)Šߘ‚­ Å°¢sí¡•í +¹rjäÔ>È)ÀRÉÊ`Âu%ÿW–Qq.´ín†™A‘À)í\6«) ³5Ád˜àY††VKeO&€v ’¦‰ë©é5g¹• YEV[º†—¦šS¥Œ¨d©d)g)e)YÖ³ªŸÎIêcÔV0¯Š|’£7±â µT72à£îåijd’ø5*o¡ËGücY¬;éòOñé)ÂêÛÔ\ÌŸÀ=ƒ8„ˆË1+ˆª_j.ÚG±ÒÆ•Ú+yDòãšX¦ðe…¯¸/@J>aÓ)±¤¬ˆ$¶àK^“=÷ >ži.>žº˜|•˜‘ܺŒ–H4¶ÂÔøt[C VšÜd5Gù9]:.ü¼©#4õNC jd42‚_’ÊÔ¹]°5€ú#âù.Ä ¤‘.ÚO'Ãúu‚½»¨šôë;¨Sû¯äî§T%¸‘´OtˆòÛèÜNé “+Ét¡½ÄÐ&º%Aé# éDý¤Gî'7ÁðBº†Ò ép°óØŽ»XÃi2P4© ªYr±¢³3Ë…®‰§ƒÆc6ó,LSù"Öñ·^«(þ j ô0º•ô­DŠúnäA2G¹ˆqJÂ.«lE¤)a™l€ÝаZ9£Sm1¬ ™VËN#g<[Fôqeû‘A ðD`ù‰”°žÈÃBùí «Öž‰ 1 XS„KN%}Ét1jÄí€5í$N™L0©¸UÉsA•šq¼¹»]´“¬i|J´kU33Am†ÊžtZéíZÕ4´2Ñu pfB´r5VbL²8¥UÙ-A=}Ö¾ ²Ò6ji*9UI‰jŽRžbšb–r/t“]Êâ éGØ·’>Ñ$Ñ2úÊÈ#TÖÑ{œÚ1ê«é°0Ÿ¥¸Š,èRºˆÜ ÜaÔKÔ/ÃíÅüåKH-ÅèÂ8»”ìúZô'PÏ*ñVD/Ú|ÅIÉ·b6(•C\¤¡Kî ©IVj’͆ÂW|Ý£(Y¥Ó§¡$:½:nãcG1ñÍ 1‰KªˆoÍ©éIþ+5*²]Š„>Û‰¯‚QÉ¡MCF;#ê‚ßÎ Û#BCŠÃÃàn““‚=¨mˆ@SŸÔÄa"Þ+ä Â'•»|Fgë¹ë¨Xò;** ùvÄ"ÄÃø#Ÿ$õþIê7áì¡z€ÊOÒs€²B-Á¼ã·Ó/OQYCîEŽKè8ÀÉ è8ΩµÌ9Ä‘M\Pf´“ÜNž¾%6øœî #fR1a!:éÔ‰kìä-´¨d™o“±Hi•&S¿iÒU²h¶‹VF¢,h7_ Œ&NÙ ƒU²0éÿ´…$`5*€YpAáJÓ S¢šUå¼(æ)f¨ä(ö¦ð®bÝì¿‚µö«œYDïa„XDÇëTЍ‹éý2G7г†üӔ據‹óL.'½×Cü#µ÷“îÁøÁ5ÊZ(ô,úŸ"¯Rú<ÄQ%¾s5\ )Å"\I'¬Ð’¿óÉÃ*…Yx®Æ÷+,3Øh1hÐ!Ðß-óšOJpk†XáZ€B‡§+«wÙ©Jî-ó¹Nœ‰(FŒl-6ND’«:¸±“¨]‚“u&¿hàh̵±µV‰X  îæHH!4kòX:¶Ž­³Ôæ¡"ÛªHu)Ùä æ›¼Pã1Ÿ…6›\˜têüJ‘[R ˜U<P5x<Ëe:çXk „:ï²øÝ˜KMu“&JšúKoAÍSꇢîmDìÆû™x/Sùq²÷3záqªI?ÁÉ·Ò’bL˜GìçÔÒg]N×aoféAö,cÞv/bÐ î$}˜Çräò¤TK <“&²Û¡nÛTR¸&ã65SEŽ(ŠZŠ Mm´™Ž¥>ÉÈ}Õ^â–‘•C¤!E`e‘­+»,²>© éFJX!Ûh–®ñšÏdZ==©D7b£ë0ÕlŠV5 ¯…P^‚IM1¬ú Àª%k*éKº¦¥„ABjoBÓôLV2%œ¢Zñ kr©UÂi)áL¨’ 2õ.èsûD»4™Ši T2ÚnfˆVºvÖk•dRæŒÀäãT[ói³½¦M«ŠM#ÊRš’Õs”2”³SÔ-ÜKY[$ÆßÈÂo±ç6Ví§°ï:æŸ&00ºqîal“û c7ÐÙƒõ8þJÜÌ?À{éÚ?!+ãçÑSh¿+y—b‘âO"•Å ¾ácÆÜn³DcOÈ=enw謴øåaú4¶¤P’Å6;<¾;IVðö̳°;«Ü3‚¡H Þ×O$qvóºðÄ5Í»ÉO¢ æS‹ @6T瑱„âÞX‘*øà ¤š#€&" šÆCãŒÄĂۻ¸<DZ y ~¿Ì¤äŠ,+¤àÕ:/…ÄŸïæ¤äO*\ær£C–|2u~€uå 6+ ¾³PWâØ «~!_Vq â%È7¡'8DýzŒg¨\ó2…ôÕ˜»˜\‚õ §/#w‚É~Œ ªŽß‹©àdöAXâTHUPXÏEãv êUöwÓ#¨”“ئ¢Wç”MÝ&´2ÂAê9ÂÓ¢º˜|ŽJ…âèÆ½ˆýßp ßJ s(‘#võš°J*ç ×#]&ããzdʤ­ŽGºÚÒà½f7µëµ ®IÕ”+c ¯X~Ÿå·#Ô´”°ÖžÖV­]tÕÃkÀ–”ín†z ƒÂD‰0)·OÝIµÔ %K%L êÝ â ¢â\Þý L¡S½F{s+%Ôµ³Qg†ÁÊI–3#õ›2Xe[$+w¶PseZ¯d©dT¹C³@óRTÒ8t/gÑnF/dðNobþõ3„—0ø—þq–¾FyõÛè?L˜ÃÌbþ-åËÈ]Šó‡TßE&­ôG„¼D=è¿?«4Kñx¤.At+¾P#ñn‹9ðe:owÐ_+`KÞŸc@gÏ7Çx_]‹->}˜Aƒwv£$ÛK|g˜¼Æ]ýX‚S°£È·N¢+2:]D(Ñ9Gk2¬ÇGøÁP ˜Þ$Ý×OjM›Õ€ËÇ—  „`<@D°«Ä##:è¬Êqç^Lž(°·Ê‚4èÇWD‚?8…iðc} Z¹¿LÖäÇ:°u¾^å·»ùXþüëç†9,9aê¬pR Ã¥.‡ž®]¼(ÔMºê'zUÈ%Ä/Ì%î#.ÍCÁ_ƒ±ƒÂEØÁ8Þrœ"Õå~l›0À+Q˜OªG’Ô%ƒòBë”uj³YRœ¶ 0ɳN²Ó¦®±ÕAÚ²CÔ Ä«¨ êUJGðÀXIy˜Ê˜rú) ž•meˆ-‹ÍÓÜŠÊTEºQ=ld‚íª|ªaȪiÙ 2>ÎÙ9*å 7ĪG65A=Ѹ“”á“eÄ$`Õãjo`yŸbXIäŠ R‚XµT­x†’5­n˜¬™>,ÙîÃRçÂ,f4åÌ´/L+Ît±ëç2…‰1 ÉÔOGך‚zC¥2Þ`~±˜ýbµÜ nËžmÉêYH)2‚,Xʲë­’¦Ú¡ YQÎRé ¡¤QYÅ‚,ùQ‚¥ îbl>=Ç©Í#wœzŒ>@úIÊw1ø …\BÇ¢¦ƒ¾u'©=ð8êãX[{„qƒG•8‰ŸÒøQ¨Æ¤Øã1ÇBÆ>žæ9Ÿý5ÞŸ¡.Ùá1²%‹ŠÙVåµ2KMÞÞÅ‹%Ê!Û üê"Ê!¯•ˆcv•›ò\ÚɶIjÊÔ"dÌͬÊSÙ:Š’8ã1â7e,z]î\t–L½Yá·epÿÓ]Ø:J*HÁÆ.b0u]–ç¸ïÃu"AŠn ×dE–8:Ýó\4ƒn“Ç ˜:+³ôÙ¼\¥¬X’&­³³ÎÝ}¼¯ãüké>”Æ;©þ¢Êõ.oqùoUÞ•bXã”àƒ–z\ÏhêçP+êïF,G݇÷^¬­T3¨ç)~ˆÜ?2´«YÀ»ŽîʯpjÆÚ²¯²Wà™„+ØdvðˆK`SwP:›È%t¨U‡ªC`SÏpµÎƒŽ|»¨}§)u‡Ps¨ÔÎ&b 9iŠï¨ÃJŸ¥Z‡*C`šžHUÈTTÆnèUÇ.‘«5Ç<${zœr3Ulø³¬*ŸT]Ùžp}•jzJë _Pk—ᓈ™ÓÂNÕ8õFåÂú WƒR¨sjXaËõ~N[ƒJtêL³2È7%V¼lií¶uÑn³çš»œ`e4GkÚÙçœÄ+cÆÆ­äŠ­t"LV3±ÅW¸G¹†—¡’S¥¼(¥©tPÈRÎPɺ¸±áEŽ-fPaíal# ¶3¹ŽG¹†9'©Ÿ!¾‚ž?äôG™#Ñž¤~ ©½È ýËD7`_†ùy S—âQÉõŠÅÝ¿b"WåTßΣK~gœçèüÞ(Ýðî&b¾6„¯ñ©yt[¼VãIÞ×Ç/ôsIúüë¶ýŒÃ\—û&Y›c®Íc›]-Æ Ðè3™ÐÔ€)ÊEÏA~ÿ=ˆ‡ð×ÁT•pªLMV¨õ!ö0Ú‡ZAü‚ÉåäGYFw™STŒÍeN36õ:<ö¥) ß$ÈW¼”a‘àeßF¹Ò×Âwâ§ùæ—3þ!ÔlŒå ïhbV<¨Ö"V-U+J!²E9ø¦S%ã©TY4«L¶‘6VÈ´äùÌ”¢ár¨$zzj8alj O4!ÉK0¬iV=XµvCx.i0ÓèÐà\ŠX)¢©†›iÈ·S*Ù~2Ó~¥ÞÀ/:­´óΧœ¢çh¥7÷ã5 Ÿz‹Cí·ÌʤmÝM «ršzlEZC8±cÕ-d)åU1#ªyŠY JK±æ?ʈC×"SšKß(µr Ý;(-¤ã µåäwá;Xý¸/P—˜½˜£ˆØ»  SC¼¦´µÂ4[#íc…ŒD\¥³?àTÀG]¾ïQ ¹Þ¦Wð"Õ€tñd‘¡AÄ]Ý<]`²Î"‹‹²<1Áñ*‹lnîáÅIFj UqámƒLÔÙWdØ#ŠY×ÁÕý-³{‚Xr¢„);. c²kœazÔäY§ÊgMíÉ­8qÌ5 ¹ †àÙ“ìGÓÚV]"¦NO ®Ùœ=º¤ƒ—NSS k f° 4£%4:ÌÍ`”#ŠŽI‡ƒÐ®#5R˜UÅxH‡Í/Ïã–ódX4Ä«?Áï.äÅß.ó.úm¾Xâæ s-¾q«ÃC‚¹†ZnŠÇˆÿ‡P¿w7æðÒÄ£ÿ-£?GÇ󔺈ÊÔn¤ã åçr¨Û[Xü;/cÎn^w¨„5‡ …1Ÿnƒ¨ÌëE“À¡æP3©»T]ê•—™2Øïªºæ«&Ãj ‚—й}¨¶’²lUÁh¥„¹–ªÕ \ O|™5Í.‰\…t£€è‘©’š¬†Ü^%ÓP嫤êLM tZ¾-§á~#‹ø‰®Ã™Vø©©ðÓº£“)aÈë퀷gˆSîÑxÊý VØ.º«>,ÕzøFQu®šà9[õÕJêëF{ŽÐÑ4t1}¤•˜¶`$Š€I hrs:14•8²ªñ¤á†iQm¤~56 SUžâ|œ.Ò'ñ7³ò0Åyô=Ïq‡l ¹’~±—Ê¥ l£| =÷3y=‡‰îÇ{]½X\ûñ•Ø»÷*ñû)aÆêj%>SãÃ:s\áJƒM>3Ê-.Y|uœS>ŸÉÝG¸4Ëíy øÒ >6€Û |û\ÀR—e¾qB~sB‚â+ûX’áÆA¤Â<{†‡ƒbQ†­B(tðC¾¼‚ >²ž¾Hô–,¥µÛ3 Á7w³s¸Ùä~Û .›×r– TC{h­Q• Kç ÏãÅ È»üô:l¡`÷$÷Åÿs%~ŒüÍA†j\5ÀõƒhOóRO.!mñGGYÓÁûøãÓüÖ">1çüë‹'Ñ5®ÉóÍ »\œâ¹%¸5ÍkÅå6÷‡¼ÓæÉ2]ùBœñUð<ÑZÄ ÂÊFNèÈ%˜ãÔkÔ!º’ž3Ttâ! tã8 )ˆ] ûûMbH'šËŠ_R4 Î1ƒØ$Ò‰ujÒ@*‘:[ Û[S¢ög¦ÞÒZKþ0s‘l0P“H×죎a˜!VˆbEÍ}_#ÄŒ0ß0"Ì;– IDAT©“Hé¡0¥ÒU$ÎZÍ“6O9Ã5%ÛOÎÙHóFŽ™fu¥âì¹z_ÕL¡J+” œR3¤«i„kŠMsº7&‰‹„½A¡‰7K“TLK¸’Þ¬{¼°–º2ˆlj¶ L8ÔM›ºMÝ"Ô`€9%jýt¿Ê±õ,~™¡ÅôT‰MÌT5ÌÜeb ~ùïSîÆZ‹û áÅXGQ1¢ý,C³”øgÉ BˆÅ|è€Çê\ea*¶×I .0xÍǬ°@ñã¼­ƒŒÆë&ô[”Cž`CŽy6–àÙqª!×õ¡ƒ)¸ï+s,Èàj¼^dÏ8Bñ¶Å(…!@1æ³uGãÒ98:–† Š§OP®ŸýRŠÍsérÛ2~S?+i…’Xž5^Múl;…H\ÞHrËl£ùÌ‘;ÆÐ5”`0Í%H(‡üè¦ÎtX xè,ͱ8ãpC¦ÆÖeÉe\œ§ï|ª„Jñ/ÙM÷/åö¿¿Aóÿ§ÿö_é×ùw÷wú÷ô»ÿ_ûügþcÿÞ;‹ÎͰfc6fc6þ †6û'˜Ù˜YÀšÙ˜Ù˜¬Ù˜Ù˜¬Ù˜Ù˜YÀšÙ˜Ù˜¬Ù˜Ù˜¬Ù˜Ù˜YÀšÙ˜Ù˜¬Ù˜Ù˜¬+ñ/ðâ¿Éüo:ûgfc6þõâßIkN\¤ð=¤ ™¨MC³A =ôÖäçæÔÄ:ù÷½Ù¿Vú'Pm-½mƒ3mNþ!XÍ®ãªÛ:&µëÂ&l‰Ùn±Ù˜ÿl€¥P¡TZ°!P!rŒê½Ä±Gäá½Föv¢*¡‡·ƒÌµxGþaÀ‚Ÿãä—0lâzs¹3ÆLMÇœ9ž ISssZ´Æ¸€¨¹ºÎt–ŽõèéÜd~_¡„È&‰Ù›i6þãEóÞVg§5œûÿ+æiŸ@ ”†…Ú‰zu¡’BHY%| 5ˆ¾ Á3¨.ŒMÔ_#8ƒê#}#姉«¤.Ç;Š’Ž›(íÆ;ÄY‡4ÕSŒ<Ç’±û¯Yú^¤äȃxýë9¹è­1œZkªŠã°âNŽÞCG½€ƒ›1Џ9¢WȯƎHo@ý#é9Ò¸Sr£Î‚Ô,lÍÆL¨ÉaÁ—”:®‰k`YLM¡) ±Zgé¿2Ãz£7ž¤Þ°3‘NŠâ˜á ßhã® y$f¿Ë‡ úJà+õ‚±ÎAI(…ü3Bü4±@Yªþ‡ÂúUb`ª†q5áÿ/îØW‡$ûNjÇð‘ßBTçØW˜ûqj&_¡ÿvöþ)Ëþ µ"'ž kzÇŸdÞu~œ7òòß±úý bçýØ–lßZn1çZ*?ÄW§÷‚ÇÎîàLÿZ¨ýNÓǪcfùó ·ƒ&0µæ’ÊYüš—8¥š£Údû~Φh¨—bm¬¾‰ý&¿¨ ¡Ð¶¬[a7PL6ïùt–wj¤Ö›`Eâ&Z›ÆÞ‹ÎͰóå¢h—ylºë|J Ds&ªÒÑš†6Âý:ºIFÃ2H»¬Ö±šÏ+'M²K úu´!;Mú æ,Ñ(DlÕÑ5.×éjìÒâ=È直"Ôb´ÍÔŸ&ö°ÞN}Á!bsåÇ1V ò”žEõ»žÉÇQ9¬¹Œm¥ÿ.Žßƒ9—ô*&¶[¸ó('»Œ¡WY´…}й#ͱ'˜ØÓÜþdÃâë(<Þ_Ùs)Ñ Íçsë0và®PÖ¾@'d½’¬!4tŸ»m.¶¸](%ůê|HWK”ÜGüM¡nƒ *xXF»â}û½'¨í%u+±døèþY‚Åè¼#_fþ§(ìàè7YôI´N†gàŽ>œ·²óoXöcŒ`ò‹n`ÛŸ¡U›ëU’ÓÁ›Ã¤.XB9*ÒÕã/=Œ:¸üìß q=Ò5ì~n9ÀsËxOkY¦PÚ¬ƒd6þí…D*ä‡Gyåuþ²“ KÕÅÏQ¶¨¤ù¬$”ˆ€£U~çg%(„D+p_À™~~1jOÖ}ŽŒñÀ|~1& É¶4Ÿáþo[-:„B›¯ÄÖEs_"ЏËó\x^€u„„T§VLpšmÈÖ€Û8Íü !Ö­Àî€Q ¥÷p£@j¨€3ev ‘e³IºÌóŠI,¦X°?d—t¹Sq$âis—ä)Á)ƒ>+5µ yD¨ ¨š ·‹ØÄø0þÿ‡Ê#æQ{™P#u¥‘XK(¾@îFÂ^Š–gâUTžÀ—Ì*Fw€†ç!²>‘f2¹1Öœ>5&¼±'ªc9Fˆuì…Ò9]ׂ:v̵UŽWð|r+| c‚qG§/"«èTäæ²ìBVXsé›}ŸÌÆ¿¢&ÕˆWØæ1z†ÝclËRí š%ÊPÎ0ž¦×勪|7B³Y«3W¢Ê<%1;¸!&`Œó¨Äȱ^'¯P©~f„tè˳ˆÁTP`Wˆ§ÐR6ål5—K4ŒöŠ}CYЏ(ÏçX÷ó ÃÉg4¤»’;$‘h‘,­¹H:Ú¾j Íãê, R 4¨rä eY0À ‚HC òÏ}ÜfÓ£¡tDïtæ¹"(¼–âjA$‘Œ[,ÕÐcõ]¤ .F}_Çêªöß…þËÄÂí[&…ß'û ß"®“ý §ÿŠÞŸ¢´“ú·²ë3¬ø"Û}.ÎRœ~²ëÙõVü¯?ÈàÔKìýËæ ƒ©œSËÍ­ÖR éŠ@›³±ÈóuR’%V• ´‡ã!–óám|/hî1t±j'C‹Xêa,fáÛXcÍJ]³ñªF(¾Àë‡Ù?Α4/G9E5C¥ƒ‚C=ËdŽÛ#<…i³F"F‰ç\–ëtJ´˜èÑÉU9.VÄM¡âa“®~.“ÍgPh%Žž`«$^ÏGcBu–:i ¥š¼ÇÜ÷£f©þ,(IDDp?½ŒëÏ °vóT€ßâVгÀÔÌ ê;t4 $uI ˆsmc&}•‘Çtˆ)§èéfµ†’xc¼ªðrÝlÖPã<ÛØ5ÚÁfEPcŸ b`ç¹²ÎÞˆÃ&nš#vHvÚl‚PpÀ`‰‚º*klñV¤Pj¥ˆv1ß‹w/úe„g&°¯¢øZÚ“ÏÒ÷qŽ•9aäiD†(düƒ[8ñÊ&Œð|&¶5‰UjÆrs Òä®A|W:"ІG¾ŽícùÍö¦Ã†2þ8…€¬Í¼NŽ…¯±¯FZ'­Ó¥Hž%y²е„|s îì[k6þ“©ãx/rúÃUŠ'9jQÍáå©d)§©f¨¦¨æ)¤ëà2‰åšˆ°Â3ÃêUà•z޵½ ³Ì¡Ç r.æ+ô§&9h’‘èÝ,ˆ‘`j˜‡xB  l SAž,=-%K ôVضÇU"²¶‡ùçX¯ñT€¯šieó!µyÔ@H±™[%¡@iÍR f ^㡈j7 °"]G(‚üê˸]mŒWFxaÔÐt´˜ñ ;Ù¨£)Ê£ÜÓÁ%iV(&'ø«<×e¸ÄㇶÃÚˆgt„¥®Ð…!ù†©Þ¦Qòex+qŠÚ0™Úhˆ5Æÿ˜ÎÏãï¡~ŠÌíþ4óÿŸ¦ï#”Ža pü~Ì…Ø 6!œØÊÆ_âÉ_¢£¥^%Ë>»ë\¹ºå7×y>ŸTDÞââìq}\+ ãc{8úµÜü<†k¸5LÇÇÜÀ\s¹}é÷‘ušéý,óš9N}™‘“Tžåt Ï¢œ§äâg¨¤ð²”G /K)C9‹ÓÉ{Á’è§øûAÞ¯pbⓊÈe~ŒRhC<_bh bt‰ãð)v.áš ý #Ú8'†Ø³Š \ n%Q â$ÎpD¡)`Á¬iø°§y¼$òÖô'`}ƒ¯–)¶èUcÿ˜2°V±I7à)¦.à‡«æÊŒ+‚å\bbj(ˆG9Pö™0ѰÑ&UähBÑ.t³Tⲡá=¤X'"—h7lÂû;¬PøR¡ô4©·P+SÝGçìýuzïâèßÓq#a¾-lÿs–}˜‚UicX™ÄnaR„–^W¶'ÒuL´OªŽíáú¤|ì:Ncjã8¬Ö\.ƒ3„Ì«†SÅî"aŸÆô0kØ!nQ™¶4Ò51?æƒ:—\nÏ"×l´ÝÛB^ˆùmThKMÔ4<?M%C5KÙ¡–£ìàg)ç(¥ðr”ÒT3Tr”°"¦j³ôðV“Á"OñÂ>R‹ùá*ÞU'ˆINá•E\ÔÉ¢8$<È+eJWrgºBDH ÛyÁ&³žÍS›3#â9Ia{ºB,á‚…, É¼”LTÛË—ñ*–Ïeð¼ë^~TÆ›Ú9A±Ú|¨äɬb™†Ò1a™J’Žªã˜t0W³Ö€èÇ"ü"£]t-a „C–ÔÊœ^Âæ ¹3ì (*üÅ\Q­r²ÌñÅ\ãqj‚æ<¶ø*ñBžµé"v°É$ãó´F5Ï5î5p,.Pìu¸ õ¤!è,JŠðlÀߎõ~ª¢õ êcˆ^üabÊQ2WP!w9gž@™L%·‘Ѥ.`üyD±¹ë<ÕJ ÓgSÅØ°«¤ì*)ÔÔªú:އ[Ç®áz¸>n€ÕøZÁõqCÇ%«p3d^$Œ°ƒ³/pV+k<ÖOÖDODW@°BÐ+Ùhqm–¥gß¹ÿé˜Ôñ:žä@ÈWÊŒ¼¤ƒ‹peJ«¦”ŸÕ^ªX)¼,•^Žbª²”Ó”ºqìˆ8Ãê,K%ú0Ûn7+ö~ìc]–»ƒα ‹y6 ý¯36‡et+ þ"O ²ØÀê¦4Q¢¼½³‡^0zé´q@èçô)Î4¬§iRd[àÕö!_͆,A|%— Tw‚±¼ª\•:¤qwò¼ÇØ®2Ñá^žÈ’[ÄZý÷saË"J‡øöëÒtæÑVö°á8ÞÉš K'ø^†Á.näÏ:¹Õ¤ßçËY>ò·&Ku,]=¦©O~^Äˈ{a€x>µ'1®£òÎÍŒßKúŽ‘ÔeDJgè æþ$‡¿I² í²÷æÑv\×™ß«îðF¼‡yž ΤLQ¤(Q¢Lj0%Ë–-ɲâîØÝîŽã8¶âÄN+q/ÇcÏÃ’,Y’)ŠHJ"Åy¦’ ˆyÞ{xxãj®“?êÖŽx Œ¿ÒéDwÕªuêÜ»@uê«oûÛûLµu+¯¹\p‰¤ÑÄ ±Z¸MÜ3ßà>Àò/–Û‰1›¸9luð œ&v3ı|ì:æTvcÄJ÷­é 7¡å·w«7CDŒ1"úà³KXaòñU?a^ÿÿüÉQŽGüË,-ƒÄ¡ž—¸z OH3qEËS Oø.ÍMFΡ\Z%Í µ~f]|—©Q6+Ì!nHQ>ó§ye ïJ "ãÍÕÜ“Npü$¶q›I9"9ÉÁ±… *…IÎäðU\]¡’@¿Ið&‡#²[Ùec'¨ | ¹Ÿã3´²­¬ZËâœO¥¨"&‰HºèÂòMH¯gý:F/ °~Àñ$˜4rzu–ÙAnYXÏÈj†4dFªÈ&˜p”3)Ñ2†¶²ZdÌ@NrÎ@ßÎF‰:ÃÙ˜Ö$g®àÊ ¥ N·˜‰¨mæ:Epˆç ÄFnhq~Œ×<ÌQ®Œ˜J™©².azŽ–ñž˜ñ˜³Ür$àéE|Âç û=nMyØæ%9©©ºx\ç3*}L$-¥ÖˆÖ£hï§ùÄ&š°®cö*ï§~8!I±¯àì ÞÄÌa„ñç/hX¥‚aå€U‡Ô-Ü@X9±Š°šx-Ü«…›G…-œnˆ•ãT ¯…aØ!V6æc…³ï1´;Qf–hø‚|!‚"!€ZàƒÏö!VÛü‡í Ù” –Uø‰òõ_ïçÔ<'êÌÆÉKK³3 5ɱ Ë]†jÌeïjv–”X{yi„•Uw†¹}ì_Äh‰êà mûçi®gÍý!ÑA{޽ -g‘@R‘H=‰v€³Ç˜ÈF¨.¢”ð¤#‡)‰‹Vv5ËW1pY€õïxl’æÕŒzÝÒ{ ÓB7ENöuöZÈ”äzVЇk£búuŽK’›Ù”‘Tqê´~Ä~I|-Wˆ>¼Ý¼Þ`vÛmt‰z—Ê8W°3%|‹§³|›_æë+ØT¥?£Õ`bˆ¥ý<7È::Ï#Ëyï4ßÕ‹¸«É‹‹,2ÆL¼”6[àYÓ†ºY0.Òë‰þ þ þP×Ðzã.æ@ùÓÔwGÄ Ú2N?ȲÏ0ý:± ¼•7¾@JÃÊCÂ|õ¸`ãK+Àná6ñ ÀrBì&nΰº£ÅÃÇÍ£ÅÏÊ+Âò±Ç…+#MtA|°î2˜ 17¹|}ŒÙŸZÆ_ì'j@ %pCŽâ?ÞB­Å/ßüø{ „ _{¯¾ÅiŸ³ ÓI±Æ:ê»wžÀQ–”iØÂïð©2õ¥ÊcÀ*óµ 3®3;É‘!ÖôDoòÔ.î©Q›gî‡nå½>ñ9&px[‡žaþ§ZD;¹ÒÀò ›Ä/sp«6°, £õ Ç"ÔjF·±, Éjê ÆTHú³\“‚ŒÛÍäD‹¸ED;ŽOúio½aDúYvÜΪˬG8Ý$‰IHÔ<±O’ X õç}bA¦‘}„­)©€qjŠLCb¢Šµ“åu†qŠsâZÖ Ô8S­ãœÚÅÖ~ÜóLÍ2Õd~+[ZGØk 7³­ÅÜ)^»–÷ÔŸåˆKØ<Éî„ɵÜ9Ãb¦quÀÁ!vùœhòL…+ú}ž*scÆ&+4|IÝ`Pð¬ÁõR}Gf ø¥Jø{;h>†q“¶µ„LR?IV¦9¹‰D1{„ÅàÈ_áĈU7r9$–ô•ã §A)G¥J®8uËX)Ù.†×R¾,Àú4»' òH0C­£4‚•»Fj×C’lŠàIÆÒ] é P£¸Ú4Í'9~#Ë2Ò!œ&áË—Ä×°ÒEÄ}‰ƒuj;X]Á> EºŒÅ ý§†©¬dÉC/ñø6¹X'x­Beßâ‘!FFX7Ë!JÊl}+ywÌXF£Äh§û¹6f¿Å°0kQNÙíª«•xÌPïé? õ3Äûȶâ?‹¼‘Ö‹·QÛƒ2iž%6Hbä bÅìï 9Áø·©,,å€G,õ¥V;Kè5ðŠü`ŽYn 'h;¶¬&^€^¬ö·9„Ř-\;Vf¤Ì6`E0Ð&\9`G„žb'4šÅ/ð±%–bþăïÜÎé1îÜÁúe”î¾å'àõÿÄçáçyèyÞMmë$ú$óoqòz®cšúAÞåÉ þ)æçˆßÇæ€,EŒSŸÀ?Iã&–.¢¤gi$ˆI‚£Ô²„ù>–)H!BM$‹Ù›Ô(º:-ì³’ý{Ö½‡‘ˬo0Ùh«WHÈæI2P¦ _`V#“¨!Œ»Y¢Á$¤â5ÎOÒź‹ãÔMÄ~&A½ƒ-¢&þœðoe½§™<ÅØµ¬wÐg˜9¡÷q{ƒùcšfìîzçcæ¯d×8Ǧ9´ƒwMs¨Æ±\éàÖ8<¦ã|}ˆµàÇ\ÎGçx¨Ìz,f·M¿Æ)‡[ß¶¸Oò%“_Ùé ªõ˜Ð>Dãûèw3ûOè7“ ä:ÒŒñhDË‘7¾ÀÀ hsc+¼‚¨{…EËCÙøÂn¨R(¬&^“’ßV¦»A)‡ªBÉʃǎïæ”*gX1f‘U´Be©Hæ «J>Ä~Å`ÅÅeØ dI¡|Eܶž§^#‹ ,…&Ôøø‡øÒßrÝ­\·•EÜÿûÉ2J¦ÙcåSJ‰Ÿ€Ù%"»Î?‹Å4›!õ&su¾ø )üõ·IšPé ñÌ„l3ÝŽ™nÙÔOQXJº™#}O5Ê¢ž§ür‰ªB­Ê|™z™Za…¤ÅC\aRy…‡Öq“Ie/láZ‡¾£œb~3W:”ã©«¹Z 'ðoU©lgC O²o5K¨ôSz–ã3øW±ÂÆÀà+¼µ‰áÕô§0ˆ ⇜=K0Œ·ƒ‰VE—hÌ“>ÀÐa]K \4)zÑ@]Ê  n¦º÷²ëcŸ ÎcÀ×b–Ñr†UF®Á%P3Äßg&#݆«ƒ…XŽ=Iø2Óì O-Ãi¿ÀØrœ~¬5”O2ûç®``”ÒÍcL¬e`ç0§"• R>Â1Ep ÛÇ8UçüF6NqÆF˜k15¨ƒ5Îk+Ø4É›}ô²ónGÃÊcÆ^³ç{Ë.TùÜ÷`ú8i¬_`XaÏò ` z+ìäój–@TÌDEt© À6XÒϱ=¬ÙB1:Àð*U¿ò+* ³÷¼G³mñ6êÿoªý9|XíÛÇ䤸ö#Lט˜aÎgvª ‰r•cSg`w«Ú½‘ W\æ’dIà)C‹*¢æ©–+šUæsãB•yf…ù>æ*Ì/eÄÀìc%Øç8»ˆ•ç ÇúGYy„#'9·†µý îçD•¾•,=Êø Á2F©Î¼Â)‰y=«ÏÓòÉNP¿5>É)-ÔÌ}”µrœ`šP ½ÂüGX¦##¨“ÖIXèï¦ßA×-h’žiwÓcÄ“íÌ È›Ì\°B²ßdäú. °¾D­NF°ê¤Iž#ù5‰ÒHG0>È€„9bõMÎûÄ[ñnc I‘œ¥õç×⼋Ñ"{š3ë)o¤?"ü&ûw2²•¡ƒŒïçô=l“0ιœ¾Ž-½Ì6³º„±Ÿ½X=Dß,ãËXy˜çC&wqÏ[‰Blâô_²ø7™þ!¡¤| ‡ÿoÊ%ÊP{¼]ÿ\º 8(\BÃŒ”U¥¥\†ÏIV£7´sØjá5qCl¿C6ú IDATtóȱа,'wHøØQf_°.¢ZQÁ¤Â.m+èaX‚Ĩk>î=¢6w¿€k(TÜ™]¾\Ý{¯‘$éÎÆ=÷8q¬ªUM)%ž§]γý_ã'ËT«•ˆcåûÊuÅoüF½TÒ~8;xP6h…+°h9‡Ê¿Ìg:·xV‘Eèç{~.ƒ£4;-‰º§šeÑȳyX¦ÞÇœK³¹~" å°l;Ns¸Ÿeå=¼|× ô#?ÂØ;¹ÕÄÛÏñ }Cô`ì “w²CÃxŽc§iÝÇ6 cžx?3›ÒÑ›¨op|'‹ÖR5ÑÌ?çè"œ[²Ð%ÒÁø NÛèw0(%4ÔM²¯2Û@ˆ_f ¢‚”H­¤Ô¥£ê¸[Ûýÿþ5Àº™qÒN—>…Z‚æµ}¤Ù0r#f^£øEj™B­E3P;ñ²ï3/Gw`c)Ö™ö‰ÖcéЇ¾‡©E˜}ˆ2æ[œÆXIY‡=œ\Iu§N=$Ä®ÑT„Ì2?ˆ]B?ÇX?î(‹Ï²1#³œfq¬ÏÔ#-Nö1š1gSÒ $Ioös£‰‚Y—e’éŒo:ê*KTEf‹ä4Q•`7¼ƒ$&qH]&¿†¶‘H1w{'õ³ø¡ -ÄjbC… ÈeC åK£®JMáåH”…ÑÁ.ÄøvϬ<«è·‹uœ«@´ øå+We‚–¸@¬¢!a7ŸZHµ:€¤,-æ“"<ìü&í:Gy´’Ò’Þ#ÚºÕJÓTӲ͛MËRQ”~úÓ#Y–ºóÎA)Åe’”ÿ²©ûó­o7M)¥Ø·/xùå–¦Éùyyøp,„>=Íùóª€"ÌöÙè K`_vËìŠ/ ®VkÃë,*…+47±eP* k*ÔËÔrM=·€0³56îy¦7pmƧúYÒ h¯bõ)Æš¤C,bx?'ûè z„ógh¬ad”þ7˜˜$Üɲ2Î+Lœ#¾5çNàO™˜w2r”æ1 ’T×à'9‚?FêÃ:ìk(5Éödˆ¤Ĉ›pÖc*D ÏHP‰8HšûÚ;ÕÎ QAÜ©¼†z†äM’ߥt—¬¿&œ/ q@%å |šT’idÿ#}YŒJH?Nc>FÕ‚tŽø¦ËðAKð,3Çh.ø›a…ú2G·R¾†YšOpj9ö,ià?á«X¼†þyþf6 àœäÌfVäÀ4cïâÖã˜cb»^àÁ[xï«|s«WqÕaXÃM'ùÖ¶7xK',QᮘƒŠIÅiÉ2×Y\£ø’Å°Æ ™}”èk"ÙFó!RA<‚Ó÷ß0û8¡ÄÝÅá?ÃÝ*d¤0sŒô,Žj¿»«n7”ç §‰×±;äba1mµ:—>v!Ø»¹¹¡ãÛ °£\Éʱ©Õ%ºÇ~u3¯°kw1©nU+鬨¢°+fì@X–w.J ÀJ{+o¤{x$ .óVŽ©çéŸþô ÃXµÊûÄ'VeYW«5ij?b,KûWIPg?Æ@Ei翦ëâÁÏîÞ=+¥êÏÿüÅZ A+ðH+fLÐhc’Ñ>„ÄKô€˜ÕúupÊìE(ç‚•¯P¹‰ÁS¸‚’ÂÅÖƒõÍõ<¬2—ëVýÌ–h,Á­28Å´Íðj®zЇ¯ç.…v#KXiá=Å«7q èû8½ˆÁ*å9QÁ[˨Àøã[X¤ÐLŒ—˜ÜÌ ncþ ‡6Ó3Ã1MöE&ne`3žöj‡‰>Åpš@î&x¿ý>Jé"Aèˆoì%NÑ~{²)Q*ª»Õ«ÔßDÔ+îÅÜ‚öô+Ñ.°ïÉ™@¡BUÀ)¬X6êZ´„/F(IÖjb+æó'‰,T,B,B‘–AÖ‡º çiê:‰*Ãô}‡ñ,Åð01½]#k–.ÌÒª¢YdMZ6b#‡86ˆã+¢2f‹¹~ì&µÚ G«”û¨f´l„ q±SÎÙh ^bÔúžöØ¡ì×ÐÕÓZº™è é­$ ¡O¢1ÿjQFí•÷S;J+ $Hú·pêAúŠW.ÎØ(_sZÊiЧ¼F/Ã*ò‰vX¹Þ °ì°MÍÚ¾_¹‘0£Ì"P¢GÊ»8WwHØ-Æw#WpÙ€•b±*`h!ú$BåÕai×ϲbœÀÎÃiš_ª 1€Ê2uûíË“$+¶9êY½ùyv6Ü»wZˆN-™èÚ1IAvðàl>zD²äh•µbÆY ô® &BbôŒòÐÏ(¨Sw`ètq+·×WÕѪÊ`+J‚2ØØ†ï‰¦§U1Ÿ‹ëy Xe¾JÍcÖ¥f 6pë8“+ÙÒÀ?ÁØ•\ýû|ÔrVžc>ÃØÎº—9ìà­añAÎOÐÚÌÒô8*ëxs>bw¥=Ôšp-ýÆi¢×h5à# EÈC'HæáZÜ¥˜Ñ”h³!>Ž› gÉ^%N‘Ó!Ö ÝÜîÉ'^!lw¿ &Jt9·ÙÖ6Äõ‚€cð*Bý/hRò"ë’ Ký™s B¢)J@ð(Ùó"3ÉB²ÿ£ ÙÊ@}Ž–Eö¬HEfÃï2»ã¸)©OúçLþOŒ&¤>Äô­_eYJú(cC·2ð5Ž ²°l7ãG˜ü%®zŠCóÔî`ý &sìC\ÿ]žº‚•‹éÿ/ÞÍOó­Ÿâ®1ö™˜‹YvGL„bv„uÓ<¿†Û§ùÞRnŸå‹ùÈ<ÿ0Àµ™×hœ´Õ5¾¢Ò­¢õ­ QU"[‰K̾xq–›Ëe±Îګ킉F•Á%”VS¹Máµðš…hU§”ãT³´ V h»Osé½Y0¬Üèà+;ÉL…ß¶e]@®Îß*.´­¤W•p®¤˜¹HÀŠ. X²°Òâ2ëdoXE%l›§gż*fT×%½±oÑK|.ÚÍ­ÓiWð$».µ­dÛúÓfRZ/Zé ³³„ަh3°Ÿ²ÚPv°Ü®^ÛÀrºXU© §„—™FThê<ôËM¡ù y—Ær¶±!"=ÃÉ¥l8Âá•lÐpåé;ø©ñ&'×°lŽð1ÞÏǘ}™±ÛØXÅy‚±Aœ­,z™™˜ý%Öi軩ï£u/£úß3©ÐïcÐB³Ñ~—ó÷Ó¿] ò‚ý¤¿N9‰”Èß¡¥#F™«„¦RÀÔ¿¨L"3ÄGëÅÍF~#‹Î 7ìønqS¯„Ÿî‘\sq×™· ï +–„@I!ò`¶ÃzA(• h"³É@Ý ´Dš‘Afé¤w`~ŸH’8(µy„È"uÈRÐH©ÕvK¤©"“d&© ƒÔ"É¿2I™‰’DÊ `l1ýMÎ÷ãIÂS‹=Í6²=¥e’é$qƒ×GØ.©d ž溄½e6$‚7tªO[j‡T§Eèk§Qw¥4Æ™{÷§˜x±˜Ä"ÔH LaÉmœz¢mqè0¬rAìK(—H7[ÊiŠRRÐÆ©RˆÕÀË£Å&^x!flû¶òšž¢|ºMµòù41𡸠µû]2VÇýpQö0ꬓŠz#ĨWƒïf^m€Ê K{cô‹au“¬¬k2íE¨…ƒf]4¦÷|T©^¨ê€ÔE˜¥u¡•,K+ÎúÀêæSÚ…è¡aˆ6*…¦nuiU³‚S™ÝåN°‹ê®R\åB·ò”iD%Q/SwU«*æsÏz?s%ef+œ_ÃrÓbPbŽ3Ö#g™^ÂâÓLûÈ«Ùü"‡18ÂàLX8ÛYúÇQYËÐ+L5ȶ24G|„`•õTf*@¬Á[Šõ ­ñ.*âü2@þ,ÞDçP)2A»})ÚD-E&Jþ¼Ð"ÄSd …Ì©b­âF)R…T< î­JßXªý/žÏ¥¢ýbýœÉ} vÒÑ/ö¿C1ÛÑÄ„Èa®–ñ‡!OKh’ßÓE( ¥þ÷Ç…:'ù ZÞ:ù,é? ý,ŽOöø5â»Ñn¡4Fü j?ƒ·¹ÿiæï£2GüCÎ’Qì!NßLÿ”ÿ/Þ¼›¥£˜?àÐ&´Î0½™E8s3›†)í%XËÆçxúfn:Èž+yÿ¾¹‹;¦yK-g‹Ãà8ßîgU‰Ò??Ǹ¦Æ3 פœ¶ùÝT|Y²Ké-AŒ¼‹Ù/´ŸØþÛ™}‰Õ¿ÍÜhÖ™y¶-ipê Fn"žanÿ¡ZAØnx(RL/’f*•BI²ÂÑçwE#t:ÚJ»ß´$Ë[ôkdyöD#Ë B]%–‰Tt6¶ÌzÛ¬xZs” +Æêl%›{Vü@\¼zz¶žmÓvIjz:`÷B†,þ\@ë¢Z²`R²€0­—[e½•½=`Ñû×—¢W¢&ÙÅ­d[ä2 ÂetiUZ²®It0†ÂÒÐèÒ­¼"!جr‘,uy=r+²a„Q+Ó¨0_¡îŠfsjeýÌzÔ–3¸†{vóÌ•¼sŒ3>Á*¶‡¤§_ņƒœÞÀz0¾Â«÷qý>&žçÐílž"úC^ÿ W½Åü_rüý¬t0ÀôöÍ,~Šúßpæ?°,C¼Œÿ0ÍÒo¡ý)5…öqÊÒDû%šŸÂ¹-Edhß&݇ø]ÜR¤|6ƒŒŸÚ)Ȍݿç[kñqƒ»´Îm¨…»/¤İüR·ýÒ ë£ÓœQÔóÝ0†‰#ùˆÉ)ÇS„$€Y­¡àNM½ž‰@KJ‘ 5"TI1%²9•UDz%òi‹2‹¬ s$©ƒò‘ŽòP-BIVA$D q?zH(‰všéø_ Z]T+zgiÔU5õjXñ†u€½IÃX RõcVŽJIo$˜õ2¬N<ØaXt]ªKƒôªZZïWr`uJvZW({å*½‹Xé±2Û”*_ý&=ĪíÌ.B¤º kºùT©¨, J+u ¿$:î¿Ê|•9¯M¬f£ Yx6C§8³ž«ö±oˆe dÊ¥âQ™Â_ÄÀa¦À¾–ÕOrÂÁ]JÿjU¼í }ƒ3k¨®¥ò³úf*D‡ˆ·SÞ€óeæ]ŒUX#dhïljK´ y?Æ÷PgÀVR w –Àßgå ]©MBl<žr2ƒ”jÞO±Kg‰D(žHK‰2TÖ~¿õ‹vTÈÝÁ9üf™{œË¬?šc^a€¼òµB‚D Þes£ÕîŒe ~»ÐQ‚_w( 4É?§j¿h|ZWË$„øgÒ­*»_ˆÙo­#ûz >Om'ò˜ß¤6Œ¸÷˜d÷Ó÷"3˜ûuV>ÂØ<Í«(¿ÎÄ;yŽ£×3šœgæl|ˆ'?È ðÃm¬Œ¨Ïrú:®–0ÅAxæÎð°ƒn­ä}çù§E\ð’IÓ"2H-j6ÊÄ7ÒXtdìÄ$Hð!Ö4Ìœ{¾ - ‚8o“@Òõò¬ë²TP.ÂE•ð5»¥Ü†(wVW¨Øí5Íó‰n'Ÿa5Šbˆ`E™‰/ˆ¡Ù«aµºš:\Ôݡ۟,ð:tqatˆ»Ä¬¶«A‘ÒBsÖÕxß'xŠèwˆÏ‘¼IöI\ù‡Ä(í3B©!?§™ø€`‡"ÊÄwR&ü¾E˜ddŠWb‹XŸu0 VD<è³7l+ê|¶Âlߨ°Ý2Õ¦û}4Ñ&í÷zì²/°n?Áù ¬3¹ÝEÀcMtI$¨ÃX‚¥ƒäã/Çä°B—Üj2›‘HNB Q–j©uɘÈéfd Ò ‘ì!úz‹d–x"!›&\¦‘MÒF!ßdv­)‘ƒlÒX†Ò¤e´f‡±L/að Gû)y¨sÓ‰G¿ÅI›d×FLZ¨9^fÆ|Â[UÖ˜’ñ»ÛjD§)“Œh%14%^F ðghúø`ocvŒú4äÕÅÍ.ý(§ýÕbPÊETP©©Õ…(§!Ê <§I)ÀntV®¾7»Œ¦-¼3·>ä½ÛEÔ¹×ÁïbXaoö0ì²;D½yÃîìaÔ5-á“.%«M¾± S¨¬‹d-Ìf]ƒnÝ=[@²º¹Uv)¡]]Je½Q¡ì¢W¢—Uu+ëݺU·¬^–ÔÚËT˜¢ _vŸ2 HêÄ€n¯hÕiÖq®—e‹p2Ë má÷1WR Gøj¹Maé ç׳Ô@ްí0¯°æ“^‰ÁãL\Á?â`™¡As¾„§a6 EžÃ·)ÝÀâGëÇÁ;DËÁÞAõkL-Å]…û2Á æFìS¤ûÉ–`®Çü¡@¿sù€ÊL!+ãzÁ×2UR²¤θN¨ÇRq,f)lÕ†¿ )KˆŒwZÔ3ldd›tR…¡X¢±Ù"SÄŠ‡Ìg$i§r•1 1¨]üRJáLLâåþêåiX/óÉc:À!Éw!ßi/M`üΆƟ¶øXC }Н69ò OñrÄ8l2Ä“™ú’J÷JNñ˜â„±”ì5Ä~ÔV´iÒ}„×cid/á`<Âü úûzé¡ñ¯aäkœºž¡£ÌµðG©œÃ?É¡+mRgü:vJ˜âp‰ÜÈmGxÄA7iih N ÆVñÙˆç%ŽÉ¦€¯—xo*JÀ~²ýĹÆ2I¦Ú¼@Bm/æ*F·pô€Òb†7²ïIT@Dàáµ)(£bDˆî¥}^-ÒÄ ² L¢&žF¢“Ä&‘Aâck¤:‰E¨“ê¤!–$Ë£å—*k‰46ÍX7Ñ!Pq!SwÅ=²+ƒßǽ—ù9,Û¨Káɺ‚Ä\ŒŠº"$’Ì$3º YzRzÁ°ŒÞ¼a'˜v©hÝ8•^ ªT/¥ê T<-ÁÉl›6ƒvG— ç ¤E ÐßæVmÍ¢TT½º¨2Â!ueSº-ܦòZÂmâ5(çn¬å37j5=mU+ÄlEÔ¹+"TVSxQfªD£¡"túÏ\T,v‰É—CØ+c¥]—I—Ë!î"U ÄŠTP {º€a¥]©Àît¡êÒÚ³·w3¨KÖñw pJöfµ·1.hH‰–s(….ÚážVèS9N齡ŸµÀªn½M³ª 9¥ÒŒÔ•Í>æò& Uj^ÛN5_$kƒô)¬•\¿W‡X7Æ™ Ëg˜U81"€Õ¬±q1µ–eÏr|+ö23Dešxœx#rŠl÷Uj}8Û¨1×)ý+µ³“e’ŒÖ(ÛÞ®8Ì[›¹uŒI¥Ã,;Àä;¹áQöl`ÕÁQÎ߆ïpäý\ñ,co~˜Ê!æÞËòƒ´æQ[髇º™êƒ4«x·á}VˆûÜÇH÷`þ'ì3ÈgPÛ…f*ñXÆ™DüžÆÙŒ‡BNE|ÞãdB=á_ZÜk±BRÏø»f~¹JU0‘¦üç°Ÿd™ÁxL¦øÇ ÎÈŒ ã×2SOÈ2b…¥ñë0dEç¢ì_+ž’~J+ºl†õ[˜J2BÅ+u¬½yÎÎ2K¬öj9r4"lpØb“JÎe¼àêÜâ`i<qNaHî)ñ\̬ä*ƒ¥:¯À~Á»tViê Rlê&‘}SÅý"%óIoE'x’Æ¿¥üe¦wa4ð‘ƒðãw0´‰”ê4kÌe4ßÍÆ×Ù¿†áSÝÁê×yy['ª¢2rŽWWsÅO˜¤M‡ÐDØÔƒÔfÞcî¾§¥ˆ  '>Tv¿‹RùÅ U€Q.fµ  ”iïiX)ÔÖΠܞW%„‡*‘èzCzuÊ­‚mù8¹ªåãæƒ³N¹Så¶Ë;e‰íÖ€¡²âÌ ÈÛÑtYL£Þ4bØÆ 4¬h Ÿt1¯¸ˆÿ¢^£{[yÏ“‰mÓ ª›R%½ZU¶@ºâmìW¢—X-4^É^ïB\B %R¶§ ÐTÛžÞ)4ºˆU'¼¨¼Æî* ´º|U*´«”¥™™zTóU5GË¥Ye¾Ã°ú™ê'­Â ®;ɾUüÔ9NµˆÏ3[fôÃl•j„Þ"v(½Êä ¯añ—8ùV<Àäfªs°è:ª.Æ÷i]MÙ@{•ôìè? ]‡± í÷ɶ)m©’ÏgŒ¤j½Û$¿ç³v ÖI~§Î» ìŒe’WC~ð‘1¬ñÝ3›,–ê J–›|eŠñˆ%:›lLÐe5Ÿ;†-H#W•H®èy)66/A°¤`o MDŠ_\Î;/aYGáH‚ŒÈÇOÛ)BÍÁ1‹5á·H%JDZ‘ð×ãô[8¶­ˆ#ú$÷z43˜¶¢óS&W*>ŠwêJ]|¹MýJ<'’eˆý¤Çàß3ø§L’ý4\ì€äjeõ78uÓÌ)”`û÷x½±›ãw²ýoö1œÒ‘e·I8Í™a®¨2:ÉÃý\YçY¦0@ ìŒc1{ n¼ˆò{¤•lAFþ"‰9îΣA5¨C æ ´j>ø8ÐB”P.¢Šá&}Þ¼g¶šÂmRnÐ °*.-×Áwi8¡ãÒ² òt¡Mw´#L[…-áší»NâØ[ ì˜Ì.siÒuuõÏŠ{+u¬¢LºGtïr&½²{B!æ3‚TGAªHó°‘K±ª¼¾úÇ'ºÅ‚ÌàEvvÑÞˆN/µ=Âz;(z lô^5ÝìµS9Å·^Q½ÜáV%0e‘wÚÓÜÄÑZ9BÙøU«ˆv%K«ŸÙ¼VÙab÷Ïs6@Ř5²#ì·éw¬SßÊæc¼jR ð-<…`)ôS`G( =Bë§-ƒÇÙŸcõ£Ôæ°%Vu'}âoð¯§2€ù5Ò>lý÷•Z/¬íó)v¦Ý$˜ÈÔòDÜŒÜ@ðIDAT,Ä|Æÿ\g¹â›ÃÿÔä*À« ž¯ó+C*ã±9δ( níc6âD“¿?ƒ–¡2>¸Šñ,#L9Ð௡C=ã¾Å¬u9µÛÇä76LÛJçSçxcŽ…¥ñqÆ'W“f˜²}Ó.—aíø>§Z ±uÞ;‚£É3³œ @¢`µÇM}h{[¼Ú@iüÒ(JðL“£-¸»’ÁC |ɇ+”u¾0¥¸Ýc¯b~Íã‹s·ì”Eú ‘ý-ñrÒaÒÇiýw8ËìÍÓ´– +d¯p~¥}œ@4ï`äy-ÆY„žàOqÖ!À2‰FéŸåDÚ:6à;.¡A蒚̬ág›<¦3¡1ãØ¶ŠlšZÌ…$`«4 bÕ*¾mYÂ|¦QЮœyÕA€G»Ø°Ü%iõÕ"Ÿ˜—hV”KbhMYjáÔU©%¼\ÒêX·‚±aåMs‘Ë/z™EkÓÜ)SE_\³º{–v÷uˆ/•7Œ{VÔUþõBU÷ ÛÛЭ_µkuòmzÙÕ…Å‹·ðE RˆNÉEà„¸¸ÞFMµAª£SÉ^Ó‚qÁ´p¡~ÙìÅ©N­²Q€”×-¨+,AÊ ÍMM-Ì{¨—ÚÕ´»)äµÊæKÔû¨##¦s÷q^¶Y©p®Ëâæ"Ò‚Ul9É™¥¬ÙѬ?Àù¥ ›¸ó$:æ)Z+|•™«9Oò*›yŒ™uTo¤ï‡´Vá¼@t~™ê²§È>¬ì†Šeh“JŒejK*†ÿ›Ïu‚øÏ’«4,ÁßÏs‹ÉrÁɘg8Šw—X«ó•ÎÜZb©AYR’üÁ),Åý‹Š,cµËçaCIrû¦À(EŸÁ3Ó¼>‡,ÞýùÎηR5ôÜÚy©WRr²ÅK3D_¸†_X}y ËŒ±” *‰cd!Ñb¬RrS™0e¼Å3Ó ™‚4åOS6é³Xm³BçÆXêq«Ã¹ˆ/ͲÊåÃ%¾êSÖù¤ÃŸ4Xarµ`ÂMYšüO¨«Ñ]8@öï¨üµOQ}‹f«Ez† DËè‹ï`ô Žè˜ý0ç¯ey“Ù,?ʼn„à$ÇÂá›Ìdë¿Åþ!j7â}8¯ ùB&ï‚™L<©+þØçç úû¬Ã T|i+C "‰ |~c)‡}8Ï”Ï µ˜7Z¼:‹‘ñÛëÙWG*Ò”?8IU‘¥Üµ©ÈRBPÏMóÖ,Nç”±¶ÌWq¼A˜¶ï|øv7Y¢gX12CË.›a}þ5fBl?Ú(@’*Þ1ʶ¾¶kôObêh’O¯ÆÖø‡³Œ%|f9}&}ž¨QKùÜjö‡|§ÁˆÅOWùÇ:³Š_à”âñÿØÇ~Å£ï°x H]%Û!’~’'ÿ{ô?£önŒ4Eð)¿ÄÉ«qk4Ï1ç‘ N²w?'Ê$M›Ì"4‰L"ß*&‘Mû lß"´ñ|›ÐL"L*,4©œaåÂV£P²:Ä*—·j…’U‡Õ€*&i#KÐ*ÈåiD»°Èw!š².ô‘y2’FCxuʹbåã4(çùÁ<«˜›N ÇV»1×¼ŠjDËWN(ì+J­,–D¢èK£Å…6‹iÒUõF‚aWð{QôBV^.­ºh—ê"Viw;†.3à eH‰ÞJA­×Æ¡uÁ“ÑkíÐ+³+tA+ô)*Ådέ…‹æ¤†Ûø^{«÷¼1qÝ¥™w(.µ×ÊÔú –°¼Á>ÉRƒÑcŠqI9@_Í-³ÌÔ çi,góQÎê¸Ó´¦ˆW³âM&¯eÓIjXú(ÇÞͦïrv-ý)ú^ü»YüU¦ßÏ¢W ^&ùÿ’ú/ÑN"®Çú+•,ÆmJQJÅJ}1͘é¼±»Åo–øn“ã÷X¬Õy±É³ ~mCñY5øµQôŒ?8ƒ–rW\¦B¾2†#øéE êX’?<Œ–!2Þ;Ê ·Ý|ïÛg9]oßÍQ‹{–£‰žôÉÉß9UtDþ±ï¤$cE‰®ÂOù™µÜ0ry kªÅlÈ?b]µ½œ,Û`‰É¹gZ ªçÇj© ã”òŸ‹|ìƒe (Q©?cc.D+s¡©Ê˜\X¬X™ª¦¶ºtm|—À•Ý¢ñW¬¨©Ñ)Â?Kÿg«JË¢â²: ãŠvK´]e*C­Ië3c®G’aI4p „WrÞN9fƒØ¤~ˆD£¢%h&Î ¹Ó‰y+#ï’ Q™Fi rÔ(Ua‰\9N*ôT~(„r—Åk1"fiÊÁ3a"!RxÆãÀɜ™ˆwaª7*Ë–)išìÚeFòÄN)¸‹1)µù!Ž$Õ8%x‡:¢œ¯N%WUOu zåK·-ª1†GÅÉ1[Ô ¯\.íõV%:}Îåã$è¡´BaÇèv*µ$7²T•©r„s-Jø‹&¾/¬An•Å­²´’ KÂEf†£íVj‰DrÀª (îG\ Ê@>hßÿ© ôûú ëýÔ*]jz¢©©)"Gø¡‹çXºÓãS¾_£cã— µšÃt+Ôuœ.¯Õù5V†’a7Ø—`(Œ[,ñ‰ô&QÉužì]Áj‘T#аÖ#žÞÝ»ÀÖ-ë噄÷_Â5§'Ãúï5ÉypÅ*Λ¢•ð­×QÒ4ü8wlE*$’ëW²ºÎ×Þ×â¶4R¾÷!£.&xä+ªlœà¾ƒ ²a”§rÁצ¸§É«Œ¨œjòHÎXòAE\¢äÛˆ»Ä™Ba­Ì bIäi¤‘M¾MlX„I!Q™D&‘Il–€Ù%`9øfù`»xŽ ‰˜”?X}œ*€© \mzßoÓ£RtÈ)zW×üáá¥[¶èK–ó2 _}5}þùôþ*^GURìDÔdžzĪVâWÑS/ŽÒEXPG:$ªî)NWT{ê•t‹â1Ä,wÚ%r™Å‹bCO‚”•cŒaÄÒ © 3•Z–+Ä‚2APâTb9„eNV–„‹"‘ãÅ*àSr@Œ—ÿ›œ18‡£ØqJ)y“6 ÓãV²7^c÷ CY`–f¦Šš›"´ L ïnìà9&a‘žnViÈU}6AñªJ§N³ÊÊ€ N„]á 3üÐàÂÙfNc©d¨ÂGvò|•Ø¿† o°YRm‘NpbŽÕÀ?L<¸†±`†ìL–n¦ù‹œò6þ9Lþû¾Ä²‡h¬§£ýñM ?€ÿÛÔž"?½†ú ¸KjßÍX™É+_X+M·YLx¸É½£lñyrž[†RøÑ,»=nžàµ/殕¨9/6xvR¾y÷l§röW/Eܹ EÅ|i#íe×,HTɯ¯a‰ ¾¿ƒ½ó=’µ¢ÎõkÉòÅà4ç;¯0çÃ\s¸õŒ@€L¸üÖ¹ÇXWÿ€fDã.RIžþ€ â“Ë*5 !x|Ÿ\…¸&/Îà\¶‚Š'yfËâÊ¥üÓ>êU>6Âs-RÁÆ)öøÔ["æà¬ ¯§œî²3gʤ£ª¬6Ø¡fLTI}â5ä) Dóø&‘N2D¶{\"Ô"ÔI,‚¾¦nøUœK›°À¯°ŠËÓ”‘+|-Îd„ðJzÕ×û”ª@±vù…NY!¶afaý9²2&?{]¾nzæ™BQŽg‚Œã|ç.eç1¿Å«ÿÁ¿>Ë(L@ FKÙË*§©«=c„¬ œ´å†ÈL%Ôí’š Å=†åDX]ܰçx(í'F/C¬#ÄŒ°BÌ3–F,Œ¸÷J0òLÉ¥š¥*‰8²´"-WTD%õCã’:% ™T¿]ÈQ]ƒQq¬$QuÀª”¼‰…VJI£´#í?¡æÂÈu‘¨jfˆâb Š>Œ#=SDVïH-¿À*QÉ.V±¢ˆÓ«ÐÔ‰U²„ZB]åòˆn‚‘`ÆH‰3Ïû‚$úÄjáw +œœ¡{$àx `¦hîabë]Ú# '.ÆJs;a[ŨcB±Pô6ê0Ê4Ú0ʜԞꕨûSeJÊn&DF5çPŒ™3 û#öÇœ­ÑJùÏ&Ub¶6¸j‚FHœ2¬&Ä ›f¸úDš!^ŒL™rèFøtÖY^E‘LwP`ØD• ûÚˆ$C&zYúù1~Ô³£ÌyìÝÇše,îEÊô_C9Öš^„^æ¾@Þg×O!ãŸoæ3«Ž°z™›+¯/pÃ:Nã‡o±½EãO/áö{gèókX=Ì[AgØáÜ1žž…¯œÁƒïbš\<ÆSó qÏrþb–iz§ðãU\­9g[<“9pU5û2òñ«½Áà¨Lé·ÿŠù•’4R›P'1 m|‹Øì•]Тtð|ƒ¤èï˜Dv Â…L*(ýÚ€UàT§lj£\{ §žÁÆ_ý[êòÎn„Ñ*÷þ>ã¥_¨-¨—Öy§¤]U0bM„Ù¡ZHWmª z±v¬èv©$èEW1ÂŒ1Š¥ÓE¢|‚aÄýWj"õH˜f†aå¨y¦ä™Z,4D–Ë å@n»@®þ«üXþÐcÎ *ÆB ³Ëæ@CP€.….u‘5×HMâB0edˆ¸¸±tâ²/9x‘AT¥Ó?¾ƒ_§m¹ô¶+×dÛÊ# W*ç&B‹ð±”¹O\£¶™îÒ Q‡Y£'X>aƒÙŒZ“Œ½|xŸxšÿþ6ìf_ˆú:Ó×pánæW0ù2r·Ùsg|ŸƒŸå¤Ñü4c÷ÒøM&_ ÎÐÎǾø©ÞMúK˜—I券Ýg™d¼Ðå«v„ü¤Ã ­”'f¹mWòçÙPåS¾²›¬qøö»œ]áÒ1ÒŒ¯¿Ê'&¹b $wn†œ. Nù‡=l?ĸÍó—Ûhúó'—‘fHÉw_a»GŸÇnY_âè ?xƒ7ö•¿ZþaÓpæ®;‹ å3k8wéâïþ|SŒðÖÑÌIEND®B`‚snd-16.1/pix/hairy3.png0000644000076400007640000017544411147553267013072 0ustar bilbil‰PNG  IHDRRèåŸÕ‰sRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEص IDATxÚìw|Tǹ÷¿Û‹vW«^H¢QM/WÜã·ÄŽsc;͹7q^Þ÷ó^r¯¯ýæÚޝí¸×88±‚{0LÇ2UÑ„ê}{ÿ8ba- HÄóý|{æÌ™™9gçüfžyFõ‡?ü!‚ ‚ ‚ ‚ÐmÔR‚ ‚ ‚ "¤AAAz­T ‚p!‰Dðz½R‚ ¹NZ-:®s!µ{÷nZ[[¥–A„sN[[+W\qeôØãñ°{wÓ§ÏÊAú”Æú¾þú.¼¢s!ÕÒÒÂ{KßÅï÷ …Ðjµ¨PušX„DÄO… Bç\üÒ«€ûï¿·CøÌ™3ùþÍ×K£‚ \¬}R$*U—  ¢V«Q©Ô'M' ƒJ…ú$ñÂá*•Šê£å|»u{̹¦}€·ËÁ7…Û˜2e qqq„B¡öÂ/p8ÂçuKk ‚ ôsÔ-F£¹KAÕÒ\^o@¯7 Õº”cÍu FŒ& j¦Ëxõ5˜Íq'-S(¢®¾‰pz³‰øx«4žpÞ …ðz½ÄÅÅár¹0hº|.z޾ÌKzKH%$¤ wþû ©ª<‚5>„ļnW‡8*•¿ß‹ÓÑBœ5‹%ž@ÀN«Páp˜ÖÖÆ tR!¥œN'~¿¯×K8& ‘––ÖeB‚p:íÁngàÀ¬NÏûý~ü~?jµ£ÑˆZ­Ž†i4L&S‡ŽA¯×£Óéðx<¨Õj †Ž/teååxÜòó‡w«œápǃÑhÓ¢cy{<^ââ̧õLŠŠv““MRbâÕݦÍ[È>Œ„„„³jƒ¦æfÊË*5jN§“ººz’’ñùý8Ú ÎÉÁ`4ÈÍ* Õꈄ#Ê(`'ÂÇçq£×éÑjõ4ÔVár¶uˆ•’–‰ÏëAo0¢Óé¨(;LBb2Fc\û³¤êhéñû¼§R@#•u ÖŠès¨R©ˆD"X -Œ¶Y¤ÏÎ)ï?€F­TŒ?½^yQ«¯oàË•_qÇí·²~Ã&&NÝÏ7…ß2jäHl¶ãn·›í;v*ƒÚ¨1b8ñññgôú÷eË™Ù<22Ò¥„ z "à÷uñîRú«ø}^¶o]ß!ŽÑdfPöPÅÂhkmæð¡=ä ŽÙl!S^v­VG\œ½ÁØ}!uìa«¯¯'++ ³ÙLii)N§«Uy°Ã¡°´¢% âñx&“‘H$‚ÏçC­V‰D0›Ááñx‡Ã­ª" 3p`mmm˜ÍqhµÊè˜Ïçã«Uk…‚AÆŒMÞÐ!ìÞ³—ÒÒR¬V æÏ‹ÉÿË•_1rĆ Ëcóæo°X-Lœ0—ÛM8B§Óa2™0M¨UJ™':–P8L$!.ÎL8ŽŽªT*+¿ZŸq— ÕjY³f-³gÍ$‰ðíÖ­\uå•@¯Ï‡V£Ál6G¿ƒÏçG§Ób2™ˆD"¸Ýü~?åå$§$cjgáp½^^¯'ãq»A¥Âl2¡V« x½^T*qqq9r„YY˜L&‚Áqqf<¡PSû5.— F‹J­Âd4FéA45&“ V‡Õf% ±~ÃF¬åÙÞ¶}Ãòò@Þ?…Î:¦2ªÝ4¢ýÈélÅåtÄ^ ŸØÞ±)‚L¥VQrh9¹ÃÑéô”9€F«iÏãÔÆ„jµšü!YÄÇÛQ©³ŒcÿGÂ**ˤфsŽÓ墺º†‰Æ£×ëÑh4457sðà!ôúã ÖãâÌh4ÊÊ+8tè0‡Q#G’––Ú>¸ ¢¼‚ñã °X,FŠŠvƒ ¼/©©©$''³wï>F…ÇãæHi£FŽàÐᜲ5`@Ì‹èáÃ%465o³‘—7”’’#x½^‚Á ñöx†äæÒÖÖÆ¡C‡‰!oèÐ3p‚ÐÓD"aBáP—ç”~DéoS°Xcï[—³-*¶ˆD0™Í¤¤dPzd?Ysil¨%1 k0޶æ.û¥.…”J¥"===úb˜žžN}}=jµš`0ˆÏçÅg’–رsXâ,äN(bóæ-$''ÓÜÜÂüËæ¢Õêøjõj¬ N‡2Ò …B|òéç\6on´ÃP©ÕíĈÃáDßîeÜ%cÛGøš:-ƒÛã¡¥¥•@ (3F›7o!ãv»™9s´´¶’œœÄGBJJ ‰ vª«k˜2e2­m­”––qÙ¼¹h4 öx;uµuè ¨«¯ Áž€ßïgý† ¯ÏÇ„ñØíñ|½vZ­¿?ÀäIA7nÂ×§Œ lÞò N‡^‡^§gúôiìÝ·ššB¡0yC‡=ˆ7ãóùÐjµÌ›7Gùp¹Øµ«ˆœÁ9Ä™Íì*ÚF£&>>ž1£GñÑÇŸ’š’ÂÀAYŒÈÏ' ±cç.œ'.·›Ñ£Fb0(ÚU„ hks †p8ƒAjkk;vŒÜØÂñ—®.„”"Œ¢Ñêôäå}6]ÂápôúH$BRr:‘p„Ò’bÔ-z½Y¹í_wK¥B¥R¡nÿ_Õþ?*Nj;/}I  ¼¢FCrr……[‰‹3£V«£/gGŽ”2$7»=•JEFz:V«å;Ï 2©×ë1›ÍTU×’’’ØUTÄüËæÑØØHUUÍ--üö8HyyYYX¿nW_}U4½²²rvífâÄñí!‰ÐÔÜLKK+yyCرc6«;wb2 ‡#|S¸•¹sf¡ÕŠÓgá\ ©áP¨«³Çû¥p£Ñ„ÍkÅãózˆ„ÃíÃÊ ¶=!™`(HÉ¡½˜Ìqä Í«ËA½“vQ'˜DF222…Bèõz’“¤…˜—)£ÑDRrqí&9Z­Ž©—NA­RÑÜÜBMm D`ö¬™Q“1µZÍÜ9³IH°Ç¤ …°Z,hµBíŠÒétMyy[·m§å˜çIØãã1›Íx<^jkj;ÜߣGdâÄ dd¤säH)••GÉÉÎŽ±OMM¥±±‰šš† J[kÕUÕ$§$SS[ƒÛíaþüy ÈÌdÿ”•W‰Àå æ“`çðá*Ê+°ÛíL™29¦JNNâÒ)Shjn¦®¾ŽÒÒRt:Z­†ÒÒ2*+ÒÒÚÊܹ³¹ì²yÑkwìÜIrJ2ùÇsðÐ!"‘&£‰ªªjÚÔj5cÆŽfD~~4/«ÕŠÉ¬ÌŽUV†gff`6›7îfLŸŠF£aþüyètÒQ Ñ>I±;þ…C'8Rf§:Æ Ÿ0ku¬ bOHTÌgÝN’’R‰DÂÝž‘:fΧ§vAÕ¾–W¥BfT…ó½NGNN6CrsÑh4¸œNÒÒÒÈHOïp£Z-Š9jRRbt û†YY ÉÍÅl6Eû§ô´4‚A¥ŸÌÉÉæHi• œƒÓáÀçóÑÔÔLrJ2>ßqS¨Ö¶6¬ ƒ$Þf£­M™IŽ·‘5`*• §Ë‰Ûí¡Íá  a2£}² œÛn)B8êôïDáiŸ•ê,N䨀\»à †xÜNôz¡`¯×M8ròû]Û¹€›ÍFIIIŒ¯ô_@SSS1uÒ’$11‘ââýx=2d¢Ój•ÿö5 z½ž`0@ss ~ úBUZZ†9εƒ´µ9’›KCc#­­Êz §Ó‰Ïë% àtº°Xb×Päưay¬^ý5G+Rr¤”1£Gqôháp¬9ªZ¥Â`0 R©ÈÍÌW«Ö`4ÈÈȈ‰—””@Ñî"L&3éé ¥¥…É©ñú|„BAš››q:˜Œ&LF#~¿¦æfÜnÉIIètZêëhii% FÓVfÑZP©Tôt:V«»ÝÞ>Õl"ÑÔԌޠ')IÀHOK§ºªšÖ¼VŒí#…™2IJNÂhPÖ”ôzöï?€N§ÃngÏž½ä ŠÁ ïP‚p*Ñôûñû;îá¤Õé•Nã„Èwî¯H$ ‘È Ñ"ƒª*K1™ã°ë“¨¬(!kP.F£©{*(¢˜&ƒ!Ôjáp8*¤"‘H—‹¡¯ ƒTTT¢ÕhILL`@Ööï?5ûþîû•Éd¢h÷ÆŒV‘šš= …¨ª®Æ 7D×ê~w à€ؽgF£1ºæµ©¹³ÉH Äb9>Ë•5 “ÒÒ26lÜDsK ã ÆQZVFSS[·nÇ`Г’œBff---˜LFâÌæNß á\ ðUW– ;œÊ”ío"íæä‘PÇ~Iu ](¤º²Œp8DÎàa´µ6s´â™r8ÙRÛÎ…”ZÃð “ œl”N ¥!¨­«Ãh2‘›;˜˜€J¥&11ƒÑ@zZÕYYì?p€ää$âÚGÛZÛÚ .ŒF#cÆŒ¦¬¬Kœ…!CpàÀAÚÚ¨T*£Ñ@RRZ­·Û^o +k9Ùƒpºœ$&$ ÕéÐëõÑ6JH°cÐëÑj´$%%Ê}¡--ÔÖTvOM3˪˜Ò:câø|Š“‰c÷U$ÕGËP«Õ¤¥g)³Í*•å% ’ß­ûO­Váõ¸ðù<ÑÅãÿDÐé´r çœÔ”fΘ=Öh4Œ/Gcc#£‘üüa¨ÔjæÍCbb‚bÂ=w.—‹¸¸ã}Qœ%Ž9³gÐO˜0~\»·LÓ¦NA¯×c2i˜5sZNGö Ø¬</F£ƒAϼyJ^ƒËæÍÁér1z´‰»Ò²2’“’6,£ÑˆÕja|Á8šššK«å”Ö!‚Ð7:*B0ˆœ>AcqÜ4!‚×릾¡:&N8n§Äõù¼Dˆž9T*löDÂDp8Zˆ‹³v9À§úÃþ•cëׯç·ßÀåvQÐà?‰²h!I+£ÚBÿàðáŠ÷ïg|AAŸy2Zµz 6«‰ÇŸû¤H䄗܈¼€ 1è f\ÎÖvÑòsz^«ÍŽÉl¥¹¹žP0Ð!žÉ‡ÓÑŠ5>¸8+ 5èÛgOáq»0ÇYiki"ÞžÈ#<ÄÄÉ3£çÝn7 vÙGJz‰]»ŠP«5Œ=R*C8o ‡Ãh´:¼]läjïO¬6;jŸÏÛi¼` €Z¥Âd¶ ‡vÒwxÝ.,µ5Gylñï™wÙüè9mW°jUO2ê`ÔˆúIIIL½ôÒØµZ½LÁ¸qQO…çš…“ˆ(á»8-x½®N—.y=nB¡ *•Š–æz]tX.gí~ hl¨% tì´­Íh4²>OÎâdH¸P«Õx=®.@D€8‹•J…×Óõž·½^O8$à÷wÏ`4u¹÷aB*‚EÙ«M¸H°ÛûÞk_Š6A8޹ç?F£©}ÓÉQöˆŠ;»ŽT£A-¢_á¢D«µt+^w×ôéõ'ß7³3Â.…T(ÂåjA׎SAz·ËKRbÊ):=áˆO*KAèU***‰·&u_H‰`O°‘””(µ'‚ ô)ëמRHEˆ‹Ã#A¡wq¹œXâ:·"×+‚ ‚ ‚ §‰)AAA„ÞR ¼ûîûÑ¿ÆÆ&>ýtmmmÑxË–}Ì·ßn?£­]»1šþÊ•kbÎUTTF7g]¾ü3Ün÷i§ïp8)+« ©©™ª*ůüÊ•k¨¯oè‘Ju¹ÜÑïp,¯îPRRÊ–-ßÊ])ÂyO(fïÞýx½><Üi¼5kÖ³bÅ*©0A¡ßqZ>f,! 1}ú€èÆ¥—\2*ºË6Àøñãxã?3qbÁihÅŠUÜ{ï1ingøð<âãmŒñ"õê«osÇ·`2Oš~MM-[·î ;{ GŽ”Q[[Gff#GæcµZz¤R_yåM®¹æ –.ý€ßüæÆ{î¹—yè¡¢Ç))É=VA„Þ$ ðÉ'_0räp_}õ5yyC:ÄËÏÏã|‘Ë/Ÿ×ëe*--ç©§ž¿hÛ$%%…GùƒåÈ *‚p^ÜîÆÞR;wø¹úê… öï?ÈO<Ãc=ÊСƒÈΈæëÿó?/ÑÒÒ ¨X´èJÆŽÕeúN§“5kÖ‘ššÊ5×,äèÑjÞyç¯~**Ž2|xEE{yòÉ?òä“ÿ—ŒŒt¾ùf+|°œòò æÍ›Íœ93ºLðàl>ø`9«W¯å§?}€òòJü)î»ïN&MOYYùËûƒAL&>x/¯¿þgyäAž}öÅèçÎp8œ 2¸½AìÙSÌk¯½MB‚½^ÏÝwßÆçŸ¯dÙ²OhnnáÁï#%%™7ßü --­,^ükþô§×hhPóꫲzõ:T*p:]¤¥¥rÇ·ð⋯áv{ÐjµÜzë œ-O }Baá6^{ímÚÚœ˜LFÖ¬YϺu2d0·ß~3ééi˜ÍÇÅ~ýëÅ$%%˜2eb ¬@ €N§çöÛo¿èÚ¢¾¾žÃ‡£ÑèP«e.A„3A­>½½ŸNû×vÒ¤ Ìš5-ºÎðáy\qÅ‚.wXµj-ßûÞeƒ!¾øbåI…”ÍfãŠ+.G¯Wü¾ïÛ·ŸÙ³§1uêdÞzk)cÆŒä²Ëf †˜S¥ÕjÉȈ5!‘PÐÑ´EC‹‹@ 7¥ }Jii)V«•¤¤¤‹òûŸ¶JJJ 33ý´;Ûn¸8nØ:¶Ëô‹‹œÒ\°°p“&?iœ‚‚Kxï½™0a\—qæÏŸÍˆùÜpõ$%%Êšª;wŸQEïÛwà¬Ê  R©bêO§ÓrÙe³<8‡’’#¬\¹†k®Y(Oµ }‚Íf%33NéJÌfsô·þ–[®ïôšÚÚ:š›[HMMéµr©Ô*¹˜‘pQ´Ã¡C%]Ѝ 6°mÛ6~øáNÏ766òÊ+¯‡¹óÎ;4hÜØ‚ œ’ŠŠ -ZDII †gŸ}–;î¸C„ÔÉÈÈHÃïí˜öï?È®]{سg<òí<óÌ x<^V¬XÅå—Ïã²ËfóÒK¯£Ñhxì±_4ììÑY™ììÜvÛͼù滬\¹†©S'“””@QÑ^:BYY¿úÕÃX,qüô§÷óôÓÏ3nÜØn»¡Ì˜q)sçΠ¼¼’Õ«×£R)¦W]u9¯¼òk×ndìØQ,ZtóæÍ"?EE{OjÖðÀ÷D¿Ã•W^ K–ûìK®¼r3fL¦ó裳nݦhS¦LÄd2QQq”+V‘`çî•'[„>A£ÑD¶L&cÇŽâºë®æ¥—^àÆ‘˜˜À{ï}ˆÇãåí·ßã®»n%33ƒeË>¡®®ž{îé=<•J…V{q˜¸©TªNÃ7oÞLKKËI3½òÊ+üò—¿D­Vóä“OòØcÉÍ-Â))..fûöãŽåî»ï>.½ôR† "Bª+rru"JòX²äw1a?ÿù¿Ä/X0— æv+»îº­CØý÷ßsœžžÆ˜1#cÂŒF¿ýí/»ýp¢9É AYüû¿Çvÿò/?Š9ž>ýR€“®¿:FZZjŒÉÞöí»ÈÍÜa¶hìØÑŒ;:züðÃÄœŸ;wfTì1e>öù¦›ÉÓ,BßwZ-óæÍKƒiÓ'D'þöÜzëÜzëÑcNË|~úx½>žþ~õ«‡.è6?^±tؽ»kKŠ@ uÜ …¢á‡æ/ùKѵqãF²²²ä„‹œµkׯûý~ÂáðÅמNä¥K?àС’"§§ÖæÔÕÕóÒKoÄ„ œÃwÞÒc_øÿø”¢¢=1awÜqKÔ®ÿlq:<ýô 1a©©)üèGwËS'B¿aõêu¬_¿)&ìê«RPpr«€îxõ›72iÒx4 6lfúôKÙ°a3ZíñÇÍÍ-¼øâ±™¶k±X,x½^rss(--G§Ó2`@f‡´ŸþÚÚLœXÀ‚sÙ°a3ë×oàßþíçÑü€èç?þ‚Ý»÷’ššÂøƒ³únz½¿ÿÌÖ‰ 2„ŋD޽ùæ›D"¹ùA`Ö¬Y1Ç#GŽ$11Q„ÔÉ¸í¶›zµ0©©)F3{šë®»Šë®»ª×Ò·X,½þAÎ5ß1ïv§sž™Ûƒ!Ö®ÝÈœ93X½zÓ§+fß'ŠÄ矕ßüæçü×=Íå—Ï£¹¹…ÊÊ*ü~?qqæBê­·–rÕUß#++“矕)S&°dÉÿcùò¥D"ažxâ ƲeË·Œ=‚-[¶2`@&ÍÍ-üú×PWWÏþý‡>|è·µkײjÕ*6n܈J¥â_ÿUé›|ðA¦M›Æ]wÝÅý÷ßÏ’%K¸õÖ[寡›Ìç¾û^¢¤Dq÷Þ{ï]”'ºìÑ"‘ÈE9E'‚ œcúpÒcÆŒKùýïÿ‘H$jº­V«Q«ïWßÔÔÄã?µÀˆD"|ýõz.½tR}h˜çž{™øxƒéÓ§`0è ƒ„ÃafÏžÁÿø Ì™3ƒììX­q<þøSD"‘.vt—Y³fu5xñÅ£ŸÓÓÓ;Ì< ‚ œ÷ßÿ_~YËÈ‘#ill$-íâóÝ©R«ÕTVVv¹S½ ‚ ô}=ª9oÞ,Ö¬Yu†ôå—«Y¿~3O?ý¿øÅ¿0wî,vìØÀ̙Ӱ٬|ùåjfÏžÁºu;uš1~ü8**ŽÊƒ!f6N«Õb0è?~»wï㪫¾Gkk{öìW^QTê˜ýAz¯×˦M›˜0a6›­GÒT«Õ1k,/z!¥R«ÉÎ(w› ‚Ðç„C*Â}Ø'O›6%ê,::Hºæš…œýîw0kÖ´NÓ;vT‡=­Ójµüú×0þæÏŸ@|¼ÿõ¿•@„^aÓ¦M\vÙex<–-[Æu×]wÖé^ýõ,Y²„1cÆ\tuª–ÛJAAú7›7oŽŠ¨cèlÈìÛ·#F(‚â"•:åª_µZƒJ¥¡µµ™pH…-Þ|Æ™ét&t:“ÜÉ‚ ý‡£U«¾D­V£R©P© Ž V«¨­­n«Ñh …‚äçgÒ¤‚+ƒÓéfëÖ]E}7·´t¹—” Â1ŠŠŠz4½#GްhÑ`@ñôYRRB^^ž© ¦IëÀat «pëüh|*ì¡8œNgç‰vâ•Éjµ Õ0¬r' ‚ ôcZ[]´¶¶‘œœDFF&UUUh4`·'PX¸“p8ˆÍÉd¢ªê(†Ù³g÷hÒæ÷¹«nµJJ¥&öi¾9Àê/ÿ)7ž ]âvÄ “xããÛ ÝrKÏm/d2™bf»DHµ"Hap;õÚz% Þ­N¦èÇñúëï ×ëINN¦¥¥•`0@rr Vk‰‰v²³SQQ†ÝžÀ‚sä.A¸ˆÐë  :’’ìTW×Åœ‹·áõzƒ½âT¡¥î06‹¾O¿oiU©éÙ¨CÍèt}çæ½¦¦ŸÏ#7œ ]rûíN àÕW_àã?féÒ¥=6›½hÑ"–,YÂØ±cEHu—øx6› …P© ''›`ÐϰaÃHH°ÑÔTÏ!C«A„‹‹„;‘H«ÕJmm}4Üf³ *³6V«µWF1u:ÉÉ}ëýïpimô{†>Ë·±±I¶+¡K……áOº‡Œ e‰M]]áp8f«‡ÓÅçóa0ÿ­ÓjµƒÁón¿ÀÞä¬MØívü~6›5f‘™Ýý_6BA¸¸Ðëõ˜LÆèqjj ~¿²6*>>ž`ðØg@𢯯O?ý';vR0 ‚ œâ Ûò IDATmmm¼÷Þ{ø|wÇý¨Õê³€Ù½{7£GŽgeeQYYyQÕo·$£×éÅåq„@Z­³ÙŒÇãÆd2âphˆD"Øí‰8Âáf³™ÆÆ&†í]wêÿþè½|ÿW/¢Õä©á¼! ³kýr.™y}¿ú^‰fH8‰ï!»=æææ˜0·ÛÝnÇívãv»£á*•Š`°ï¼=Õ×7D?§¤$PW×€Juüø»ø|~Z[[1ØlÝ_ëÛÔÔL0¤¾¾ää$ÒÒR©¯o ŽÐÔÔĈà ƒää "33£=/­­mÔ×7`2™ÈÍÍ¡´´œÿþïçxðÁ{ÉÍ#R{“ââbÞÿ}€í)ÂùÏk¯½Æý÷ßÏï¾hÑ"–/_ÎÍ7ß|Zé¹Ýt9Ab·Ûiii!u":ô\âÎ'¾Ü@8¨Æž‡-Ç‚§ÞƒÝn'ðGãÚlV‚ÁÁ`ºº†¨7¦œœ!½þEÖ|±ŒËx½QAÎÂá{÷îcà„þ%¤Ì§X~äñxq»]±â+1¯×KssSs¾³1/9¶oßE0Äjµ°yó·Ü~ûMèõz‘H„={Š3f$ñññ|úé?¹âŠÔÖÖátº0ôÑþ®;¼÷Þßq¹\ 2˜¿ÿý~ûÛ_ò ¯’žž†ÝÏáÃ¥,X0‡¿A«Õpï½wrøp)O>ùG®½ö ™2e"mmm444²ÿ! Èì3!•ŸŸÏâÅ‹xóÍ7å„ ˆU«V‘—7 ½ÞÒé³}lätض Ú¯vàšk®aÉ’%Œ7N„Ô14*5ùyXÃF‚5™ ì¬ßÑhbÏž}1ñ R“‘‘Á˜1ùÑ)ú:1GA¸˜HKK'==vv§ªª¯×‹Á  ’ãBªoÒŒeëÖÔÔÔqë­7 ×ëùÛß–‘––J8¦±±‘3.¥²² ‹ÅÂøñcq¹\|üñçŒ3ŠÖÖ6&OŽ;­Y©û¤¤D8D$¢¬Iøñï% R^^‰Á`àŠ+ðå—«Nx!YÈ 7\ÃæÍ…ÔÕÕ³`Á\Ö¬YÏ 7\#7— §dõêÕèõzª«gЕµJ¥ õäö :¿ß^¯¿(êù,MÄ3gÎܘ0£ÑH$Áãqnßš¾©I„” ÂÅD$Æã‰‘jh¨?çåÚ¾}qqfÒÒRùôÓ\sÍBÆ¿£ÑÈš5ëÈÉ„N§ãÈ‘2¶nÝÎM7]‡ÛífáÂùèõzââÌ$&&œVžûÛ2 ƶ;e:þ¢ÕjÉÍÍ!°mÛN.¥¡¡±Ët, ›7ÒÜÜÊWÌ—›L„.E”N§#é\DUVºugýkÊm·uÜû/--ºº:²²²DHòb­–êêØr»ýŒ9BîbAá¼£ `,%%¥øý~ Æ¢×ë:4—’’R¦NuÅ>cÆTêê—íf³™ôô4jjj;̤u‡K/DCC#·ÜrZ­–;î¸å;¢3‚Éddöìé²³³HJJˆ®¡¸ë®[Ù¶m'Ó§O‘†á¤"jÆŒüíoàrÁŸÿ|üü»ïBI üõ¯ð‹_ ¢¼¼œììì3È©¡C“;Rµµµ"¤A¡?’››sÊ0½^GVÖ€èq\œ™!CŸv^d0dHcO’—ž b­;ââ”…áññ¶hXRRb‡x‚ ‰¨wÞ¿ý ápô(ìß:”–ÂÌ™wñÖ[Køßÿ{q•áÊ+¯dÉ’%L˜0A„To³oß>˜9sf§ç·nÝ5 LII¹¨¯ ‚ gŽÏ磲²ªOó ´¯À®­­‹ÎlM˜0޶6'mmÎ^Ë·¹¹E\DD¡Õj™1c ¥ÒREH㣠µ’Û'’þügè…ýÐÑëõÍ:©s&¤víÚÅHNNæÃ?äÆoìÇd2aµZ©¯¯gåÊ•"¤Aè5‚Žæ:RJeô,ö¬ë}AÎÐtLqÚ‚aüá¾Û@15+òª-Òè‚p‘²fÍ´Zm—'ã7àÿüŸÓÏóõ×wó³ŸÝß鹄eû‹´´4R½ÅòåË£.U—,YÒ©9r$K—.åºë®‹†WVV²mÛ¶˜¸®|1 ‚ œ³…oþùg´z#Ó¯ù‘TH¿hÓôÚpŸæéjkC£u¨­FÝgù:.B!éábQ†™3gòê«0jÄÇwÿz“)ƒ’——wZù=ê,žËÎΦ¬¬L„Ôù@]]mmm :4Ç AƒbâõÕ$‚ ô?B¡ Ž–:RIeô—ÎM!+3¥OóÜòí^,ÖRSì}·9üþý-Q‡‚ \œ"  º²²@{o÷7ß|3ï¿ÿ=öX•ë{ßûK–,aòäÉ"¤z‹!C†pøða2220›ÍÑð 60xð`233Åæsîܨŵ $$ĺŸÕô†‘§ ‚pQ³wo1#Gæ÷y¾--­¸\n ÈF¡K•”ÔÑœ¯ª š›;¿Îb‡£÷ʵlL›vñ¬“:gÓ8ßÿþ÷Ù²e úÓŸ¸ÿþã6–………ÔÖÖFõz=Æ “'F„' RSv|Sñª’¢Mí²¤’/pêêÎI¾^¯Go¾í‚pÁ‹¨™3gòá‡Ïoݪ8šè B¡„€Zî]¡ÓÊ¿¶¶–ººÎÍöZZ Pö½s:ý¾-ÎjFÊçóQUUfµÚ»u­F£áöÛoïþóŸÿ<æøú믗'F„^¡l_!%»72劻عn7ÿì=–¾«µQ*ù<ãàÁà ‰ÙlbíÚÌš5矅Q£F Õj˜1c*[¶lÅãñ`µ·ÿohhb÷§§‘ŸŸwÆù?÷ÜËŒ3’ÄÄDÆŒÉÚµ˜5kN§‹>XNnnÆ7g?1N_S^^ÎêÕ«DØ Ây@yy9¥¥¥ÜsÏ=ѰººXqt:„ð|ùé]³wï>öï?ùž±ùùù3mÚ´~Ýg5#uðà"bþRR’å.á‚`×ú޽GÅÁíTÜÎgoü_kJ{$ŸÕï?+•}žàp8 …b×egdΜL:™·àñx˜3g&(žb››[¨©©aΜØí6<|Fyoذ…;ٳgÅW_}M\œ™¸83¯¼òÁ`€‚‚±1‚é˜Ø›5kZTPõ%ÉÉÉÌ;—¹sçb2™ä„sˆËåâóÏ?çæ›o ±ÊËáÐ!Ø»W‰óìt7>ßy饗Ng÷nXµªëó%%ÐÖvüø²Ë.㫯¾ê÷mrV3R¡P0f}€V+k•A8¿)ß¿•AÃ;ß,p÷†O¨.ÝKÅm$¥çœu~^W«TúyŒÍfëó¼l6Z­6:ó4bÄ0ü~ÿyW7f³9êÜI«ÕÊÍ"ç·ÛÍÛo¿ÍÝwß}÷®¨€;•ó›6ÁæÍÊ>Q§K$b£íDÔ ~?x<ÐÕ’§o¾ïîÁ«Óéúý:)ùUá¢cϦϢB*ðsôÐÎNãU—ìÆ`´0bòåRiý„‘#‡³yó·¨Õê.MåÆŒÅš5ë±Z-Lš4ž¸83¡P˜5kÖŸµi߉̞==ÆlÏ`0PWWÏÚµ™6m2 vòó‡SÓ>AÎ=^¯—×_þð‡Ñ™áâbøôSå|a¡"t|¾3Kß`0à;Ó‹O‚ÑhÄëõŠAèo¬\úÿø=Üñu§qB¡ Á€O*«a4™3gFLØ1¢Ñh˜6m @‡8ÉɉÂN—éÓ§t;Qi4,8î¥öØ(A¸xñù|¼ôÒK<øàƒ Ç·Uذá¸púâ ˜4©{éß~¦R©ˆDº¿‰øæÍ›˜:õ×> ]MêûýãÙ¾};³gÏî·í#›/ ‚pQðå»OÄüðy»u][S ÕG¤A„>%ðÜsÏñ“Ÿü$FD¬XqfiΚ-wt:ÊóÏ?ßÍr£¦¾»w+îÖ;³X»vm¿n#™‘ᢠðÇüÿ]*î kè¸áÍuÔ–ï')cp¯”ëpцŒ™. ÔÃø‚6÷ižk"zƒ™]{÷:SZg@8A«ÕI£ B?" ñôÓOóË_þ2f}â‘#°eKÏç‰èÝŠ[^®xûë–ÐÐj ƒýv¥)Aú-_¼ý,¼ëwÝ /+þ–Y×ý¤ÏËx`ë*R½€Á`$==½OóÔÌ ‚”””>ÿ¾GÖH£ B?!‰ð_ÿõ_üö·¿E­VçÜ™»:?éï—¾ûë¤JJºŸ®N§4R‚ Zg‰„Q©Ô'tBJØéP²{#Žá/ëv¾*µXNŸSB.ìÛí8¶|»—¬ACÉH1a4ú,ßýûâ릩ª ç7áp˜Çœßýîwœƒ]» ¹ùôÓýÑàO‚GQŽ¿ÛE únz]ÏâÅ3X²¤{ùNŸ> 60þü~Ù^ÒÓ ‚Ð;¤ë?z™Ö†*@YH»âÏÿEø;ûõ4_¼ý'Z‘á>4ýÎ-Á`×÷›Çã%”{Aå·âÉ'Ÿä·¿ým‡sÕÕðúëPTMM…Ðé?ÿyÇðK/½”M›6õèwš:uj§)Bê,)**bÉ’%1^áXgð øÙòù[´6T±nù‹¸Íg•fCu 5e=³æ¦µ±Š-_¼% uÓÝ}Ÿ^xáUZ[Û:½þÉ'ÿÈK/½~ÒëW®\#•-ÁïÉ3Ï<ã>ÚÁœïøoòÿ—×óe˜8q"[·níV\­¶û&†jµšp8Ü/Ûí‚4í3f cÆŒ‰ [ý×ÿ–§Pà¸g¾®ÐéM§fs]{ú!yf¥TðÄW_}Íœ93ذa ³fMÃçó³yó7¨Tj|>óçÏaݺMÌš5P(Ä–-ß2rd>;vйK~þ0*!;{ MM-äççQQq”×_‡Ù³g0th.YY™1ùú|~^xáUœNgÔñÄW_}ÍÆ[P©Ô<úèCF~ø–.ýPLz>ø`9û÷$))‰ûï¿‹>XΫ¯¾Í¦MßpÏ=·“žžÆk¯½C}}yyC¸å–륑¡ðôÓOó‹_üâ¤k‰6n„Q£z¯ &“ ÇÓ­¸sçªU0vlçç}>e=({»Ýn,K¿k71í¡_QypmM/¼÷{]èqÌ¿ý×ç¤l{·|qR¡V}d4`“™™ACC#³fMcíÚìÙ³#†3aÂ8Ìf3@€‰o^¯iÓ¦°cG“&gÒ¤ñø|~ì¸\nRSS°Ûm7Ý´ˆÅ‹ÿ•Ç÷ù+W®áÇ?¾þðNž~ú…×”—WR_ßÈ|#Gç³Ï¾ä¶ÛnbΜ,^ü¯ ˜ÅŠ«:4—ÿø>Z[Û())•F„ œ¯¿þš©S§vºq­ËÕ1þÂ…‘õõ`8å˜&¨T]Ÿ…” tOÆ_N=öê«Ç×rýâ¿àé§Ÿî—m'Î&AèT•ìÆg£þè!ÜŽfl‰=¶}õÞS̽ùg}Z.ŸÛý\¶¯‘SvÏÙ\OkS5ƒGIcö³fMcÛ¶9R†Z­F¯×¡R©(.>H[›ƒ;‹øÙÏÏÅŰZcGPÓÓÓHOO‹ s8œâH~þ0@q ñ÷¿Ôþ"ÔùÂëo¿ÝŽF£î4ŽÃá`Õªµ:¤¸ÍJII¦¦¦¶×ꬸ¸˜÷ß_ûÍÍr B/ˆ(•JŬY³ÚŸs°ZŸê)X¼8öšI“`çNÈÌTþ6nì^^÷ÜII]ŸÿÃ@¥RfÌfs§q +™2%K®™‘¡_ÐT[޳¥þ¼+ת¿=#s1›MètÇ÷XŠ‹‹£¹¹Ç‹ÇãE§Ó1~ü%Ì™3#*¢ ‡‡Ã]«oëvKK+kÖ¬gÍšõÎM›v)ï¼óK–<nóæÍ¦¾¾ÆÆ& Æâóùyê©çX¿~3Û¶í$))‘Q£ò©¯o@­V““3€±cG³dÉ“¬^½–±cGa³Y©¯o 55¥Órõ$ùùù,^¼˜Å‹“ 7” ô¢ˆx¦“.ã“ObÓÓaâÄž/OK ƒ?àwÞ9«tZ[/ž6”)A.hÜŽfÌÖŠÖ/gúµôHš¡`V/•ÛÈÎs<|øP†zÒk¦NÔ!¬  ãB€ë®»ªË4† Âcý*&졇î96ôüþ÷±CÍ>úp‡´-º’E‹®Œÿæ7¿†„~(¢N$„þSù¼vm¬8‰Wþz¯V¬€[nÑœõ†âÏ>»vê£ !!æææ~7 #3R‚ \ØÑ‡ÏPyhçY¥c‰?nïÐP]BÞ%3i©«Œ†í\û©lA¡WDÔ²e±qþþwغ>ûLqܰ¿"žzk_Û@öî…¤¤$»[^ŒF#ÿ8ÍîpçNøéOÊsÏ=×ïÚRf¤A¸à9fÒW^ü->¯ëŒÒ˜uý¿àliˆ›,v<ÎV쩊-xCU Iƒ¥²/\n…[‹ú4ÏPX‹Z£a÷Þ}D޹«êmΘM§A8Y»v­Òç|g&j÷n¸þ'œEEŠcˆ}û`òd%ìúë'½MW³G;wîä’K.á£óÂÓAu2/"¤AÎëþñ"- G{-AùÈΟH[S-¶Ä´O¿­¹F²‰Š”I+±@¨›9rÉ)ãŒ|^g}߯ի¤ÑáQ‘H„Ù³gP[ iiðùçàtÂòåà÷C»—sÆ´i׳lÙ2î»ï¾M÷ý÷;:Î!%‚Ћ„‚~<®6,ñÉѰú£‡ñ8›ÑÌT•‘™;æÌ~õF>Z}÷ýÇnøèe®¸§ç{‚õ½Âôk~$ ÞC˜µo¢Q¿vÖé¸ÝPYýt#I°õ̺¹’’RrGÌÀÝ|»ýì:=ZÏë‘F„ HD¼ü2  Êæ¶ûöA8¬ìÏ”œ|îÊúæ›zFŽô÷hš‘´¶¦SSSCúéNg‰A83ÍõìûæŸL½Jk©¯ÄãláàŽµh4Zœ­ ÝJGg0á÷yÐŽoÆ«Vk‡OQí·+—2qþm½ö[ê+±§ˆ{Ù³¼s€ÝgJ0G3ædMˆž1™Œ=’fmm]Ÿš ‚pö"ê@b"˜ÍÊÀ Àk¯Á¿ý[ß—ó¶ön-%%…úúŽ^p[[[ÈζŸqúwß}o¾ùßüæ7¿é7m+FÕ‚ œ—4×–w¶éÓ7ð8[º-¢Ô-ánšfŠúÊC=’NÀçéÔeû±ï(œ¿´µ9xî¹—yî¹—ikspàÀ!~ö³ßPVVSSS‹ßÊQЍ³eРžIçæ›aóf:Tq:Q]Ýy¼-[¾aòä)gœJ¥êwƒ>"¤A8/Ùüù[]†}óÏØ=.ÊöKvþémª PkÏí¤|KýQŠ¿])ÝlÙ«WCq±r¼a:¤¸‡¡´JJ”8§N¯¨h/#F gêÔÉTTeذ¡Ìž=§ÓQøÃÿðñÇŸsðàáS¦çóùX½z«W¯£®®§ÓECC#»víaûvÅ#eSSs4α|A8Y·no½föìÙ”–稩Q\ŽWU)뢺ƒÑëlâî»{¦œ990gŽò¹¹YqW~ùå—³bÅŠ.¯¹ë®ÓÏG«Õ ûU_Bªººš/¿ü2毿5Œ \Œ4T•à÷ºÙ¶úýhX[S û¾ùg4^cuiL|w[f[¢r­Ç…Þwʼ"‘ÈY{:;–ÿ©˜8ÿ6¾]¹´[qÞEÅmÙ³™ÚòýrcôZ­ò÷ÅÊz„?ÿ>ø@}}ë-xûmظQ‰sª½([[Û(,ÜÆÖ­;ÈÍÍaÔ¨üqT*jµ­V‹F£9eùÞzk)Z­­VËúõ›P©T<ñÄ39RÊž=Ålß¾‹·ß~/&Ž ç/{÷®Žœœ9QñtŒÍ›Ç55ðñÇŠxé©©ð½ïõMùÓÒÒ¨©éÚ Rvö™¥›MYY™©s‰N§ÃjµÆü¡’‡V.t¶|ñ6[¾x‹p8õÀW¸âÏü^Ê÷o¥øÛ/ñº8škÛϽÛ!¦ÚrÓõIy;Í¿¦”P(֜˞š³'ÕÉðºÚð8[¢ÑçqÊq–ÔÔ(‹·×¬Qþü~È̃¦LÊJÅÍðwÂ̙ʢÑh0›M˜Í¦.ERZZ*yy¹L™2ÜÜœS–qæÌ©¬Y³Ž5kÖ¡Ñhˆ‹3c³YY´è*-º’!Cãp8˜9s*3gNeáÂùÒ°‚pžÒÚÚJaa!óçN7nTö‚eæûèi:™ýè#¸öÚ¾ü¼ñFÏ{“½é¦›øàƒúM[_Î&’““IþŽ;­FüfÂO$BK}U§§~/ÎÖF«pdÏfò'- +oƒ†OäÈžÞŸ~õð¸Úh8z³5‘ÛVS_ÕÑdk×úð{Äìê|âðaÅŰݮìÍrŒÜÜã›[F"ðÊ+J¼SM Y,qŒ5¯×‹Ífmkun£ªª†ììX,qdgäë¯7àr¹¸ãŽ[0ºöYQq”K.Q¼O:;Óiµ*y$$Øùè£ÏÛÅœš«®êý¡éêêj al%¼ ]ÒÖÖÆ²e˸þúë©­§¡šš”Y'§Sq.q&ÔÕ)3RgÂ'ŸÀ—_*ÿw••¾Ž‹ùÑ”Ù÷   @˜:]4 ¡P¨ß´·¨AúŒš²bÒ³ó»ÞÇâLŒfk§qvoü„ÑӮÇ'eŸœÉîŸ;zg _ﺜ®)/ÆÚ {V]lLŸIIÊz„gŸU>?ð€"š@ùüòËpõÕʾ.S§ž:ÍqãÆ‰„£Çf³‘ïÿt:¥k½üòyìÙ³»Ý~R0wîLöìQpÍš5­½\÷ÄĹûîÛ9|øÇçõIÝ™Ífµ¯h×jå•AN†ÃáàÃ?ä†n >>žgŸUo^{íøïÊ_ÿÚùµC‡*ë4{ÃCc£ò»wŒü^}<'éÂ^y®¸b!_|ñ .Ü44˜Ù´ ¬V°Xά,ƒŸÏ×oÚ\œM‚Ðglo_÷´}Í8[:„—uË_Œ~®>²7ú¹`îÍd @îèi 26æZ—£³-á´Ê×ÖTÍÎõÿèV\³•„”,¼nG¯×—pöäçøqž:ÝqÊç‘#•EÜãÆAJ7öñ‹3c9áMÂf³1nÜÆ#šFÁ€§LO§ÓE¯?æ=--vøÙjµDã˜LÆ>©·øøxÆǸqãÐëõr# B8NÞÿ}n¼ñFV¬ˆgíÚ–">ºÂï‡nPfÃ;{Ì 2¤çÊš’êï(­VÙÓê55`·'Ð|Â.·[ù.gK^^ìí.ÃK‚ ô9nGsŒ+ò ¿ÂåwvÜWÂÙ|Ü5øŽ¯?$=gdÌùq³o¤tÏf & :ƒù¬Ë5ýšûÙ»åŸÝŠÛ\WAÎÈ)”mdÈØéLiØó饯G+ºÄØ»·Áì4àø;˜Ü)MMÍä M8g¿®¶¶^¼ðz½TTT——'•!Äàr¹xï½÷øþ÷¿Ï;ïXY±BY¹aCwEØÉgx¬V¸üòÞý&\uU¬é¡ÕjÅÑ®œN4‹>Sv·oíwÅWðÖ[oõ‹gI„” ½Ã¡0ô’èáÑC;c_þÊ‹1[¨-/ÆÕÖÈÑC;9™EƒÑl#9#‡´ì|ò'Îï·áq¶ÓßJ¾d÷Ræ‰:Ï©š|ûY§cL¦TT*=^¯·GÊ6b\.*µš¤ÌQ=²V`ˆ=—ÚÆ¯¥Ñ{‰@ À=÷ÜÃÆq¹\<ðÀüþ÷¿—Šeíà»ï¾Ëm·Ý†Õj¥±Q ÷xÀåRfÀQQÑ}}=ÉCþ5 X,iÔÖ*ÎþñJÆŒ‰uÕ·f2³•“ÓEŸ§ˆÄc,[¦ü¯×ëñw×ç»)A.JÖ#¤v­ÿ(æôþm«ÈÈ ßµAù?è÷²~ùK’³%¦‘3òRåG¸îÍφäÌ\FO»šÚŠý„‚g¶¡êšž•{àb5}ŽÝÜÃââ·]UMjÝÍ=õ§tyîl¬ë±bµ¶¶ø¤Ñ{ ŸÏÇ_þò—èñOͳäð v#©)‰†>Ë×éhíW^°Î7Öž¸Øƒ¸\♳¯yôÑGYºt)‡ƒùóçó׿þ݉Ó=ç@`¿þúëÜ{xÍì³ð IDATfÞ{O™m*9M àÙ³þùÏáì\|t—¹s•™¢äN ,&L8ýô&L˜ÀÖ­[{¼þFÅž={5jÔÞׂ ô{6}ÆŽ¯ÿNÙ¾ohm¨àÉû'ÓÚ ¸8/ÛWØéu~ƒÑB$&¯`ƒFL’ z”W^Qöv9F(/½$õ"Ä2kÖ¬˜c«ÕJ~~¾TLóÁPUU…Ãá`Ù²eüçþç9+‹ßï祗^â¾ûîÃlVÖç~öTW+³NgŠÕÚõ,Nw1¥qå•§Ÿ^BBË—7õhýÂìÙ³ùúë ß$Y„” =NK}%-õo@ëjk$VFÏ÷nù¢ÛiŽš²P*VèQn¾Vž°ÔN£[n‘zb‰‹‹ãÍ7ßdîܹŒ;•ÇÿˆaÃ&G7W=»ÊBÂgóÖ|‘°k×.Z[cgùÏÕ¬`0ä¹çžãà¹ç›¼¶6°Ù:Ÿ•ÕÑœ¯/HN&º^ëlؾ};{÷¾Ä§Ÿ¾ 鑲}ñÆ[wz.Ó¾‹Œš²bl‰i˜­ RB¯Qô0ªªHÉêó¼ž*â ÝÂn•êøñêÕðÌ3°|¹r¼x±²v!R\¤?ð@ÏäûøãO *^+¯¼òrêëÈÈH''gK—~Àœ93y≧ÉÍÍA­VsÇ·“3Hì¡R©¸öÚkq8\uÕÕ¬Zµ–†eæaøð3KsëÖ­,\øÿÙûîø¨ª´ÿïÔL’Iï½WPB =TATDе²®ºî¢?×å}w7‹Šîîë˺¾èª (.Ò‘JB „ôÞÛd&Óç÷ÇÉ”;}’I#÷ûùÌ'¹÷ž{î¹çœ{ÎyÎó<ß' \.¿üò fXÀláÁƒøá‡ ‘H 2\)==l6xã7¼LJ¥ÿó?ÿƒ×^{ \.b1°s'°aàiÂr=&Ë?ü˜3µâS~ë­þ—Õßß4 „µ(--Czú#Ɉ¯ð΋ñÖ[gXÎX,x<óƒ‰,-H2Ô<ÈEhüdZ¢1`(¿{ ŷσ”ÒXŸîîî=>ŒHA*)) Iz£Åù§Gû‡ E·Î!fb*˜LÖ¨x_•R 0€¼K?À/4cpêëpõò”ݹ‚{7Ï fb*îÝ8„äÅ8õõ,ݲR‰µ%ùˆ3}ð ììléø{…Å”€š@bÒ| ÷"på0= ¨*"Ƨ¿ozÈàYšŸ…¨q³)Y§=ýdvØ™¾l nœÚg6 “50Ãà™ýbþ†ßœ/¾ßÐ8úضzçù›ßü˜8q"8Þ~ûm͵ÖVàÀ>E°RトÉÖØ±Õx。VŽ46ªðé§ øùi×IK–,¡Üë8ÐÁŠL@&“¡»»ü1Yx²ÙX¹r%Ö¬Y€EÛ·K—Ó§ׯ¯¾Jð22€ˆI\g'™ |ò òêâB„•ŠüΟ§šæª±fÍͳêëëñá‡B¡P@¥RáÉ'ŸDHH¸\®&½B¡€T*Eff&æÍ›‡k×®¢T*¢€o¾Μ¾úŠúìÊJâ§TÓ˽¤ïSH„+«ì}˜ª’’€Ë—¾†ÝòôôDNNÖ¯"šAõ†“=@ R4hX…\&‹mr÷çþͳˆŸ²Ðàü•Ÿ¾€¨« ç­¨„%¥J ‹ ™¤ &J¥\'ýd¦,|‚ìØÉ¤”úIJY‰Ê{ÙKIä»ÿ{kv—B¡áAîEFŽEuÑ­Á¤Œàô¾÷kÛˆ]Qx©ë_ÐrE&¥€Ãs2zmÉSo㜽7b ˜²å+Í¿L Rƒ¥ PHùûîmr¹\™¬ïÚŠ¨¨DEEP|ÌA.¸RñññšýÞ½{G]?‹Å½f}:›/LŠþ[t$''øÛXÂåËdqàm¨å¯ƒ_$ u.—Xî<õÔÇHJœµï¢‡ÃÁ¯ýkwbÂÙÙ¶@çB¡999ˆˆˆ@`` eŽ—J¥èééÁ®]»Àf³áââ‚×_ߎÂB`Ú4ª_QM pÿ¾é÷5…üøíou6àÆ òWÉ3$hhÐ ¡uÿþý8tè¤R)6mÚ///¼øâ‹øî»ï“&MÂŽ;––©”Ô-@Ø>'M"áÖ¬!þ”ÑÑ@I µŒ„µoÓ&Óï‘b¥Å¶N±­FB‚麡Ùvêö)S¦àæÍ›˜b‹-HÑJÈÙ òú©¯0fÆr¸y~tR1Êï\Eü”…P©TPÈ¥`s̲”IÅàpy#²î›ª‹Q[V€IóÖãóÿz !±Q’—‰×wGÙ«AêÌþ˜±ìY@ù«(Í¿ ©˜êˆ|ïÆi(årTÞËF`äXÜË>9k=hõ£R*¡PÈÁd± —KÁfs‡m½‡ÄL´KøÇÀ+ Üb:.ÏÉ ½h .Z;£¤ÄePŸéé Åå f€\.8.Ýè€óçÏcž®š@HH(.]ªFbbÿ4‹… ؘ?ß´?‹RI´\®al ™Œ\Ó•Ãvî$Ú¤¤$,Z”„G%š]Yðôi`Þ<þõ¯áôi"Ø|ô‘¯½&„BAžåãム6h‹½Â999X°`FKùÙgŸaݺu€Ý»wƒÉdÂÑÑQ#„Ÿ>M4myyD³tý:)'@ý ¶==¶í[-\H4Bpä©·†¢½Z¼˜øSMšD„ÐÓ§É9xòÉ'5ùìÛ·uuu8uJ–ãöíÛ8{ö,ÒÒÒðÁÄíÌàÚ5hÚ?0P+(±XZa °ûÞ`€Ã¡jã¹\@"!¶à?ÿ±ýÙcǎŹsçhAŠÆÈÁ™ï>Äæ?~m÷|¥b!¸<Ûv´Îîÿr™Å·Ï# b ò.ŬG^¤N$ 9”J%ؽ …³û?ÄÒ-Û-–¡ðú)$NKÓüíKùúV"0Y,”\Axb2Jò2‘¨©ðú)L²BËVQxå…× ´£¶4ÏèuKÅxsAs|vÿ‡˜µúETÞˆ»w|CbìöÞ*• r©G4V¡¢ð"ÆLG~æ˜4Ï0\N´fV/yΊ‡/ª‡_(ܼ-Ö‘5¶÷®VTÜ»¡ÍÛ7íMÕpŒp£);ÀÝ…ä)ÑCðäs›8¸O”ËÊJÝ耛7obûöíзjtvv з šO?ý/½ôþõ/ 5U+H:Š€VYI´2O=¥õé“ɈF'3“$j?ýœ¢€«W‰À"ÍÍ»ï¿üB®eg‹sðúë¯C ~õ+`ÏÀÇððž|¨¯oÆž=ßj„µyžׯ_§˜z¾ð hkkƒ³³³–Mmvwì0n)³ºßvuõÎg„&œÁ ‹ú¿ýM+ìXŸO„Aµ uáñCúê+­ppò$‰óIžo,ïM›6¡¨¨ûÛß(ç32H}«T$Ÿ÷ßfÌvïÖ¦IëâãâÈïÖ­áß·œ€æfò—Å"¬€ê&}ê)`ß>à_ÿøwñððÑfô 5JQvç DÝö]>üçG&é‹Í1Hw÷êIŒ™± ‘ KQS’‹€ˆ1Fó­-ÍGgk=ÆÎX®¹§®üxN.ðô ƒD$€ƒ“ $"2¾ÿHS†Ê{ÙHœ–†Ê{Ùèv¢©ªØ¤f/ôtwââ‘1oýk¨y‹Ò|b°­+HUÞË6¾#Äu@ŽPÈeIz TÈÑPq’žn ‹()jJò4u+ìlÁ½ë§ÑTSŒ èñ(¸|¡q“1fÆ24VÉbÃ'(Ê⻨ëU÷±°×OíCêºßàÜþ¨q³ÌæQ|ëܼ­®¿ÞÀÏ_ ) 88ò힯XØž³yaèîÕ“‹Wim.\Ü}ÐÝÞ DÐã“=Àaþ ó¿FÅ»BáÿÑngtvvÂÍÍø·üÆk‘}À}›+zz LÕBΩS@l,9>q‚TáŽê§ò¿%%d!|ò$ñ/R QûöMJv¶V°éî&ˆ@¨ ‰€Eî¿}Û&¼‚^¾¼üò›NPÎEF>‡+¼(2€<ïßÿ\{¾© Ø¿Ÿ”/,ŒhV¯&šžiÓÈ{[‹7Þ0M+®ØÔeR×Õƒ¤lº é==@TT‚‚‚4Ôô€3Vh|¡nÜ ‚…~ȯ©S­+ë²e¤~‡~ó´wëVÓibcµýf 0Òý¤˜ôP9:ÑXyÒží¸¹—Ž¢­¡Òà|UÙÞÈøþ#펕R IJ¥’žn\ù ÐÞ\‹êâ´Ö•¡¾ü.2¾ÿõ…xpûÚª K5ùd|ÿ$=ÝP* GÔ¯Ò7i„»{Ù§ÑÑ\‹’¼Kæ':a§MçàüÁ TÈQxý%°«ù™?j´FF¬Ióqõä»Z¡R*ÑRGl’f®ÐÔƒÉ4ûüª¢[‹hª!T²â^V¼ª¢[hªy€âÛèjk@Á•ŸŒæ£{N]¯=ÂNd|ÿä2 îeŸÁ+Ç5í£TÈ-jBãªT,¤h§zº;‡ô`±9˜»ö×V¥½sù'»>[ý XÓ§Ôé;[ëèkˆ —UU„-­ßm_E×çHÁ®]»ð›ß¼ªÑšPÁFg§¼Où ðx< Á1üô ú+—ö½Û·{7eîååÔk—.zÄÆèêÒúðI¥ÀÿüÑàˆÅ@a!5í­[Ƶ?ý¤›f68íFéêÕ«Q^·ڭ¯³“¤ÿè#jííDÃÖÑ¡õ'âr­‹Åd ¦ØïJJ€(½½Ãº:­Ù]^P]M4f¥¥ÀÁƒñôÓŸ#5õs,[v“'§âøqûô)[éÁ¯½F5+e2­óq2±¿@é#¶`úôé¸ví-HÑ~ Ú‡M9ò³Ž!?ë˜Ñrõ;qíç¯ÐÕÖ€½ÙˆšâœÞtmhk¬„ £ue„*µ³¥ÕE¸ó *ïß„B®³ÏìÇ­s{é(dRC#k…\†Òü,dûUEÔ¾± 5:ñŠ.Ü…º²ä^:ŠÜKGÑÑ\£9¯ÿ^w¯ž„BA&U¥RÚÒ|\8ô¿Ú¼›ªQU| Íu¥FëG]/j¨ xN.M []’žnð](Ï·„ó‡´i»ZÐÙZ¨)ÎÑäS~÷íÄäÔW¥¢"A;N~ùg(rägýˆº²T?ÈÕ´O[c%ò20þðnj\ùI#À…C»†ÍwB´H®&¯7TÞÇAËx% !—Iìö|KmÚZ_‘ cD=99y”ŸX,‹ÅŸÏ7ø 6=½-èé!»ç¶ì’ÀÅ‹†”Å/‚Æ‚DB Ž]»*ú”ç×_M:즬šrz§£²2bFvó¦aššbž¥‹C‡ ´»waåÇÞXå2‰=¥™Œh«Ô8v̰ùù:óŸ‘©¶´øùgói~ù…˜Æef®Áøñ›³O=åˆövò.çÏ“a/?Ÿ|+Ÿnº¼í퀧'!Ãpv¼¼ÈÿÖ’M(Ú Ùl60fŒé´••d¡û6på 9—‘AÕ£G‰yïÞ`l2Yޝ4 ;æÙ wwãÁÌ_|‘ê[¦•ÈÊÊ‘#GÌ~S[·nEtt4žyæ̘1EEE´ EãáAi~&êJó©‚JæQt¶ÖAÔÕ¥R®#Ðéeé“e#Û[`d|ƒc¨SG3Šs. vR*å|]Ùä\< ¾»Oï±vÛëÖ¹ÿ $?Óp’ëhFîÅÃèjkDwG³N^¸tôägþ€’¼L\>±ˆØ|\:ú‰A>Ž|74VA$hGñmbÐÞÖXO¿PPþañh¨¤ŽÞž~aà9×\>öRV½`ÛÄÝÑ‚®¶zJYÛ›jPxý:šk ÊßPuJ3<›ïÀþ9ïFR#Ëû†ÄXdhì¼"ààØ?’ ÿ°ƒ¶1…¢[éiá Tz‚”°³ ·ÎÐóœ]!Rm‡éÆÃËú×ÖÖŠÆÆͯ¼¼Üjªo{ã‡ÈŽøÚµd·´§‡;k׿‡ÞJ‹Q•Фa2ÉnõÙ³„…lûvbŠ5~<°bñßPï’§¤…¢ºK|ñ…öžk×´»õÛ·“œçÎÑóÊPa÷îÝx饗̦Y²d …áÍœ;w³gφƒ:´Žjû>l]þ¡¡Ä|ìý÷ ‰¯d¥¥¥D ‰O“HD¾Š ôw´S>ûL_É}”ü]´˜9“øëŒOøì¹iR[K=÷Ç?mÔ;ÄD2"‚hÕ*ƒMÉfâW¤Æ‚Æ…Msøåë4gC k‚;oÞLw}<öµž,mZ,^¼Ÿ~ú)}ôQlٲŨ0%­ã°UVVf@ B R4†=ºÚûtß­Œs>A{êËïPA©T€Á´­ºzúcÖjê—ùÃn´Ö—Ã+Àp±ßPQˆÙ¼dtá›w‰˜¥Ý>’W}¹emCsm)dR­yWÎ2Ó©”d•4»·Œ2IŤ ¤’p{MÅøî>m’ 1³”J¬þ+noªÖƒÆÚVÐÞ_0L,ÝB÷ݼÐÝÙ6‡…‰ÅoCy!üà ©ËØJŒ¬¡‚‹§ºÚ÷åèñsàâé§9ö ж*6Vk]™Å Â’žnܽþ3å\BòbæR*A, $nª‹oÑÎ `Å ²€**",hêÅRQYx-\hü¾š’ÆÓÓ0Ȧ¾"£¹Ù¼3¼.é6P*•Ù7y<$ëL|/^$ÂHQQââ,Ç‘‹©”à……Ö—}Ý:ÂN×ßø»­­„";øøc"0ÔÖ7ÍÒÅš5Ƶæú»™uPñÁ†>iGŽ÷êìž^{>*ŠÊ¸~=13W÷ë­˜æU*²IcÊïk¸à¥—,Y‡™¾&“7o–£\ÇÑïÈ‘#¸pá‚AZ¡PH‰…6\@ R9jäøõ—}fô|mI>‚¢Æ[•ǵŸ÷@!7¿ûÜÙZO1iÓÝÁˆÇ &T*ÓæB,6|7ïÞzÊA2ýçšC£†Œ|<¾†(bò‚ Ô´•÷àgä̽×äùôZ¥U4Û¶¶í«'4L—ú3W<ð ×{9çÂÕ3@£årä{P´1Ý-šºÕ…»O:škˆ&’Ű~Ïæ:ÀÉŒùcÊÊçq§—0ƒËsÂØ-5•‡_tèâ\<àêágöyÂÎÈå–D…\Š–ÚR“×ëÊ P~÷ªv¡æìf@ÊqÿæY;[m®“Ž–Z ‹$ Í¡.â°÷.@â¦L›FŽ++ðpb~´g1ºŸ0Yyz’4"ùâD­™žz¼x1¹ïÐ!² º|™hœÞ}—\_½Z{OL ñóP aNN†lm4 ð÷÷·8¾FDDP€æP]M4;ú&ƒ 5”)„†5HH°o}Ô×ÿßââLÇŲ–Ó¬]KÙdîGGëͰ8‘|÷ñ–ññ„Î>&Æ|K $fš¶*êùü¾™[SßQQDK©iÓ´Áœ¹dk+°guÄSþþþHÔ‘Ú¼¼¼(¾†Cšþü!‡ £i@'nžýNK=ÿå—ÆÓûúúâüùó8}ú46oÞŒƒÂ×××hZ???DDÄ!-- 3fÌ@þ@8ÓÙˆ©‘*((ÀzAÄ’Ñ1Àôýw¬EcU%þ³«7jh½.oüò5Â’Þ‘(¾•a1O¾›7ÆL_fÓ‘Ës‚ ½¾Á±`s x“—lÒÙyaC©ƒÉb[õþ^6j¡ŒNn^3}î^;‰éK7£ÙŒi×PâÎÕ˜–ö4@©P€ÁdcÚCµ9‹Í›•š'cxö¿¿ÃÝkZiOÿ00XL@6z¾9¾›7º;Z R*eÞ£·4?Ë,5; @{8ŠîÏïÚÝ °XCÜ¢T*!ïeP w‡ ;ààÁƒX¿Þz_Õòò””œ±Šá¬©©>øñG`ž ]3$˜?ŸøYéÆCrw7¤N÷óÓú焇áÀ¢£Y³ú&lØuLæk5\æÌ‡kŽK4w¶h¢ìžž¾ûå3cÆŒÁµk×L QjÌ›W…ÐÐP„††bçÎ7nœEòZÒCRR’ôì!Îø;½rdˆE]uµëàd|!S_¡¤¬‹ã7¯4×–Ø­œºÂ—ç aW«Õ Óii›PZpÙbº©‹žÄÍ3û‘¼d¼#ÑÚ iÙ¸y J›Èdb°¹ý×îÈ$=mœ>Ý1.e••B¤·+«—?؃¤2è ´QlܼhAªà é†%y—0ï±×LúÒèËdÞƒ}_í…¨G iÔ¼w{{"Âí¯ñöññÁ¼ÞU¿cÙ F***°råJ[–ਨ°fãïlÙ²/“¾¾T®]Keï›4‰Ä–ruU/0‰‰–Z‹µi!F žu­Ö\ \\“œ©H áá„HCß_H¡ õÊá:5e>8ÚQS÷/___455Y¦Ô7nòóó1uêTZ¢1zà© ¾Éæp1eá¸qú›ýNî>Áho"{§.ÞˆS_ï°úÞØIIz¬NŸœ¶ Ì^Íš>„-ƹ®Ö¸Zá7%‹Àå9õ»ø¾Ë¤hk¨Dh¯RXüTø…Ä¡ò~ö€·A䨙È8ðLL]gºîo4?Ѻû aêb”ß¹jóó›kJà¨c¾:c9±kP›J%=” ¾4ì‡ÔÔTxxxŒÊ÷w Ái†9Äb1x6r†§¤ÌÄåË—‘¢ë§‡/¿ÌÃ_¼fòº\ìÛg{y§è¸‚z{k…(5~üqx1â©áìLÌgÏ6²Fð&×âæof‹¶ÁÂ::šüÔ1¤La£Î4ñØcD€Ò}ŽBÑ2À@B%`§=ÖgžþóÛëÄ‚ƒIŒ­¾""0gùúå—Ä4QY³f!++ k×®5šþâÅ‹(-«9^ºt)vî܉ñãǃËåI_¦)ƒŽ‰©ëÁ`2¡TÈÁ`0ááb`ng°K;¤ež¹ò9TÝ6J¤ÑïÅŸ“«É˜QF…6ï À ·¥²‚˘¼àq4TÞCw'ñûªy‡àè (-ÈÒ0v¶ÔÁ?¬ÿ4Oá‰É(¼þ ¢ÆÍÔ¶ Ž™€k?ï…“‹ûº½yö;Ì^ý²ŽpMÌM« 4zºIàhs‚åÃ>ŸD¢.ŒF(b¨T2Ðè8€ 6X•¶¸XgLv÷@G‡i{°ÚÚZ¨TÞL›©T¦ñûƒØAž:KK ½w© ö  ò3†I“´ÿgfš û„†×âb<ÛÃĄӅ1!îé§½{Íç™@”ãñ”æÎ%ì€ö¤‚ƒ ã§—–f¿t<ñÝë+y„ŒÍ&¦È’xyµµTAÊZZˆàJUÚ QYxƼ¼¼!ÓJÑ‚Ô(…l€wÇïß< ‰È:NŽƒ#d1œƒž#ßB}úðê¢ÛƒR7.¾´7ÁÅC«Zvó D5nãAÞ%›b=™‚£‹;…>| ! ‘8- ‰cäàÈGOw'’RVö;ï”U/ ðº6 ¥­lr7ÏîÇK;#ç¡>—ÁÁ‘¯nc&¦Â78¦7NÙÀ b Nûþ|· •÷­N«TÈ5¬“£J¥€aa¡mJ¥ …v'‡M¨­­Å }êE“BY°’EsîÝËÀòå˦ÍÌÌÄlcª—AÀ† $ŽÙ` »›˜w­^ üÝŒ·ÅòåD#SWg9O{S¹Ìa)dqhƒE·5“!mHM5ØÖË‹ÊÐØ_ŒK~à Ñè™ÒR¹ºº¢K5#/t))@WWÜܨÏiiiHOO§)ƒ aWœ]½,ÿÃÿümŸ©–ÇÍzWN|ap¾úÁm(ä2„'XGw9}éܸŲ­Dk•Ú<(zä\Dü”…–wkœ] uÙ¤Qï€H„ÆOÖÄ2êۀĄ_h*ïÙ½ýf¯~ɪZúñ•&Î[šâ@ùÝk˜ÿØëIMoguw´€ïîcY°mk„o°v* <YÇ>ƒ«§„­áÖÑÙmÀÍç¸<'L[òô|·9çöY#:Âåp“É‚‡‡;||¼GÕ˜^QQ @@Oný™…B8;;[•64¨ª"ÿ;::¢ÇL¢ÊÊJ„…­}¨ëîñlj¯–5LzÖ ëÖÚãõëï¿'&wö€ëòøÄÆãÇ?{üìÕvkCŸ ( qˆ%áÆHÄÝàöÆé2…ÀHÓÛgSoDö™oÁbs èõKH^ï (páጠ¨qCò=ñ=|FÜ{ñȨï˜L¸\Ψú±Ùô¾hðÝwßáqø´¹\/G””dee]øùùùÁÁÁôcI‹0ܵ 1»RSv«±uëÀ<§½¡1·n%`½Ìì!‡‡¿Á£ZO+>Ôð±ó´÷‰—¥›7oÆ^Kö–´ E£?Ð]°;8ò!éé¶kþy—¨Þˆ<'°ØÔ‰ƒÅáB.—š¼R}…ì.xú!r,5p†³‘8RŒ±3WÀË߼БˆÌw›MS[’7¨mâG¾»Á{b&¤šdêë ‚£,oÅŸ³†rÌ`05ËN|wˆÄçÉÝ'ãg¯ωßg¡w qñðǘ<\ú(`‰ív­{4h؆òòrDFÚc®³“/gggˆD"ƒ4gΜÁâÅ‹Íæ³f l¾~ã À:œáeG£¡PK@ß7“8//LØ\3§¤ .“ ›1-4gàMÍ¡¤„J»o+îÜ!¾n ½=çV÷‘322 —ÏGQ‘á5H¥R£ß -HѰ;øîÞèîl±éžê96?gÞz*C×Á 21éäÁш±¬l]L:òÝàá [3jÜ,„ÅO¡\ã9»™Øg.·Ê)zþc¯›½;™÷'yñS(/4nÄ«Žg7¹ßõQxýõÿCío_7iHžë醶†J#åÑÖEpôxÔÑöé¦3})˜Lôé-µÿ ‹)+áå&‹ G3ýÝ–~"—Ú'˜%´Ô–¢¾âhXÆW_íÇ¢E©X´(‡CUU5Ž9†E‹R!‘H‘›[€ììÛhkkGyy%Š‹KpôèOˆŽŽÄ¢E© …HÈìßÐЄ††FºR‡úCáå´µ\.R½ÞéÓ§Mj£ `rA¨F\œV £]N KP/Μ±½=ú(p÷.ѪL˜`x}ª¹Ÿ£#)«­HN-‘Ÿ¡W7]m£9¸º>–ñÑGÀëVLé¦|[ZZàímÚ÷ÕÅÅW®\Áã?ŽÝ»wÓ‚ Ûq÷êI›ÒsxŽJ Õ –bþ»Ú R)ÑZ_»WO FY`rÅs4®…ˆ›¼E7 ù=¹<'¤¬xWOì1-ÄM_f8 †ÆaìÌåV•iòü 3}™A Þ13– YÛ™±Éi›4¬ny—~Àø9«ÑÝÙbÔ$Òn‹ ¯€ÌXö ¼u‚Ýê×ÅØ˱xã[𠊲X_L!±D0®Z(Í7äàh–¶ßx[Y×OÚ«ááb×ò6VáNï7«{Ù§QWV@¤FP_ߨÑH9:!wΜøûûÏw‚L&ÃŒɸzõ.^ÌÂܹ³°té"de]ž}ŸW³q´hÑ<,^<Ÿ®Ôa„ÆÆFøõÑQ%0PK[®Ž£FMM rsƒš"edX¦•ž1ÃPƒâëKÙª1uªu&~¯¼bY«TTXÿDXòð–ÖôϹº]ƒ™ÀÜ;EFeetÿ·“&&¾ »›EÖ…“`­5^uu5BB¨sba!1û€Ý»wãСC8pà^~ùelܸ‘¤h ,xN®ˆ¨,O*• …×1{_Wk=”JÅ.ºØ.â&/@€²Žƒ#üÂâ v‹žØfüC`²ÁæXgtÍæòÀd²0cÙ3à÷AH;s¹ÉŬÅ–ÍÖ/wåA¥T"$f"8\GÄLœ O¿0Œ›ýØ:›k5ñŒLN4‰Óú7ˆ0Yð ˆ@Pôx3íå.ÏÙ*Ó7‹ƒ¸É Êo®¢Ðzʣƪûð ·ëó•J9äR‰Ñk ™ ¹œ`êÔIàóÁç;cÉã}311 MpqqJJH >߉J%‰ÛöñÇŸáŸÿü”®Ôa‚ÂÂBÄÇǃÙaõömbÊÔèk¥jkkáí¤ñ ùÛßú_^]¶@€P°«iØ·m3}Ÿ““e3;‹ø±,_$&Ú¯Žsr€‰m¿Oÿ}ø|²·êw²ö‰Md~ÚìSYp8ý3óÓ‡1á:)) Ôõ%a¾ 3¸ÿÊ¢=€óçÏk|¬àðáô E£oèl­GkC…UiËî\ÕüæÛ6=§µ®^¦½6'Í[Ûߨ{²Øœ^s0CÄŒŸŽó({ú#±9}ŠÙÂbsªgiÓ—nÁµ“{É3Ù\(äR,zò-œþv'ØDO˜£IÏ`2Áî%úX´ñ-ÍùÒ¼LD74_IH^ló;xFÀÕËD|ÄÌîÝ8 ®ƒ‚bƃÆÈÁªUK±iÓãØ´éq„„aüø$¤¦’ÀÓ³fÍÀ¤I¤=7o~kÖ›«±c±yó“Ø´éq¼úêKàñÈFÍ /lÁ‹/>3bÞýþýûHOOGzz:ÚûJ—6Œ‘M‰?sá‚e“;“cõôé¸víãf}úÖJl6`ËÞER’qÍ< Á 0mšeŠÃ1dàÓGt4!!°—.sz§(m\¥·Þ2Ÿþû¸ºjÍö‚1“HV­q3U—îîÀ /<œc^` °iÓÐ<›ÅbA¡'ýÞ¿ññÚÅF–«û"­Ó‚ cho¬Â5=Ó6ß4U£¥¶>AÑšóŸo_‘€LŽr™m³GcUüB ½,󳎡¾â®†¶º«µ®žÃsÑ=eá¸yö;@PÔ8Ô–æÛœ‡‰Ø¶­)kbTé ^ ¹LOˆãbÁã¿3œxœ\(”ຠwJ¥L& ÷ožµéùÆ7yÁˆ ü?e!¢Æ¥ ʳœÝ¼,¹88ñ‘8Ýæ¼}‚£Ñ\kyå¢orJÃ%“©ÑH±Ùl°XL 1‹ÅÒüÏf³5š pvvŸïL¡¾ær¹àr¹#æÝããã±}ûvlß¾³¤1s!S¸|Ùú`MM ‚ƒƒ- ,¶h¿˜L"|M›Ì·Ò:tÊ-Ã̛g^ŠÖš yCÊáëKÈ$ô‘œLÞKWXœ6˜„ݺEüަLQ }o·ädëï‹#þ\6çÎļòí·M Sºï:œ‘”d[̬áþnÆ6;fÍšNo¡ Ž?>(e‘' ðÃ?PΉ%bz¶×AÑí ,ÿÕŸ5Çþa‰hèu,×]+r¨ ²ë³UJE½ªR©ì¶è~{‘ò^ý^ ±XðŠÄ¤ùáÔW…J©BDât£&h~¡qx>ý|‚ô´p zÜÔ”äÚ¥LÝÍà»û ¶¬S= €ÈuvóÒ›´ ËÈsvChÜd¹ðÄišwR)𠃛O²~´ÍĨòÞ ,öO#î{ˆ48>)æúyÚÓïàìþû•·Ê Ú£â[ˆJJAIÞ¥Q;þ ÝhhÈUïÜÙÙ…²·1l Žeíü”‘¡®k ?ŸºÐ¼t `³«ñ§?•á›oâššŠgŸ}VsM76ÑŽÀsÏQó~çrÐ’2˜"`2ÉϘ £6*ä™L¢ò÷rLijn??R惩×õ9;8rnút૯úßfï¼ìÝKhÊm ÌiØÞyÇÂBù!Ñ6iù¨Þy°·Ý’%KðË/¿`É’%ˆæøÏ~Gãh ³fÍÂ;ïˆz¿¥X4HT‡#²{$%%!I­îÅù•J©ƒi\±X|û‡–ÚR#‹uÊÈŸ÷¦cé–íÓiÒ0”í.ƒaÕä¾tËvœûÏßÉ„Æ0]¾´Í„>³[¿¿Lu"e0ŒO¬ †Qf9ˆ™8׬ åé‰H€À¨q€Áµ¥®ñS‰ˆ ½ .¾prñ@p¯ß‘n}XÓêtµ%ypó„_Hª‹ncé–íË$ð ‰Exâ4”å_†˜u*96á‰ÓÑÙZO¯ÂlÚƒkð ç|CãFe] ÝHHˆ…¿¿ŸUÂçH‹ÅÂ;%(--¢?4ÐÚÚ /3ÁŽÒÓ }hnß¾ý–øuè’<\¼de=¥ò4Š‹ââbÄÆÆ"<üw¸x‘ø©¡+©ßÔÓøk¯‘@¥6˜gâë+RS‰ù¢%?ÿL¦sõ'Dˆ5ÔþCL‡´¹s Ãa¿ÆQ; £••†uÿ0aî\Ûã4 V›lß|ú)ùLÝËd25~¥€õòL&l6(–þþôP:²qêëf¯{F¡¥®¬wðV@¥"3íéwô„® Ê_€h«,¡­±Šbn3cg.Gì¤y€iKž†‡o¨æºB!×°œ1 0u¶‰.ÿ7RV½O¿0$/yJ#¼4×<0jB¨ ¥RAÉK³˜Ì½€˜‰æ¹IuëÂÝ'~!±Ö@,¶QÁªâîuDKAxb2¸Ž„¿ÖÉÅ‘ÆCÔ·Ô•Ã;0~a pó"IŒù3õn^ð ÖšsFŸC8ÃN.FÍ3 E·3 R*¡²f[{„böì¥ppð‡ãmöçèèGG‹é†ë¯²²šþ l„B¡@WW—ÕæŠr9Ñjäæ'N¨­­E™Ü¥K—ôžiKgŽ‘áx 5 ¶²¼Ï›G„D¥’Ä̪7³‡6’47••„¸£/`0Ì¿«¿¿}É:ú‚9Ã|šåàŸÿ4Ÿæüyõ·WŠùóm‹Ìf³!$ò$ZEÈ»tU÷^+Í'Æßjÿ ©X„óÿR±彄®6Ô•@¡Ðuw4×%¶ˆJšeô9 …H]÷*`ñSZÃcŽƒ£Ñ ¤‘cá–Ÿ h0™,“ä7ÏîÇ”…Oœ¯*º…½|¹<'0™,£lun^ðŠBK}¼#à‡–Ú2“»³W¿ '¾;ùp{ý‘ØW+!!±“ÀåYŽê?…0ùÇÀÅÃoÐû†“‹¤b!u âò R©7y¾I­' ‚Ðø)ptq§´%`ÞïÐÑÙ ³y©÷ž¾ù¬)äR³Q%"I¦ÀÒ‚Ë(-ÈBI~æCÛ.K—.Ä„ IÓM™2ÉÉ“éŽ<ŠpøðaøàZ¢ab`‹PšŸE9wïÆi»>ã^6ÉO*éAõƒ\ˆº;p?û4üÂâ‘{ñE²¦Ô8\ž&vÉ{ÇLGô„¹&î7^]Ö:Ý23L )ƒ>Âáá ¯€pø…Æ™¥öVcáÛ¬6™4¬—™CÚ§xή˜½úeDŒ²‚+šó‹7¾iWÖ»¸É¾^#„1R»%1<'×Þ~ªmKk™0ƒc¬gêv ¢ðàÒÑO ÄBMÚÑŠ ’°}û›Ø°a-˜L&&N‡íÛßÄöíoÂÿóçÏ‹ qbár9˜7oyd9Þxã88p5qŸü”d|«966Z“oPP ’“'ã¿ÿûÿ!-m!yd V­Z†wÞù=þøÇ߃ÇãÆÐ¡©© ¾VDyÝi™íâÅËÀf{ÀÃÃS§NÅÊ•Ú-wu€W@ ~õñä“ÀÑ£zó`‰ÃÄã‘ÅÿHÐ8MšDÌ/Ó¦clöÐ)¬^MÔ‡ ±±$8µ½àïïˆu´d9t=‘bcâbó÷[ëSL R£r©5%y”s¶Ä§ KH†³›'å\Ñ­sMSÅ]j~‘õ…F…‡á{—£¿±•F*‚¢Æ¡¹¶¤o´î,6Ø®Y œX<Ý8-mD×Sbr£Lk:¸Ž`ØàËwö;BBá‘ÿ0ó±£$¢nTÝÔ˜éZ›7ßÂö¦Q×§9ÒÓ?‹ÅDdd8îÝ+ƧŸ~‰O?ý¯¾ú"àÝwÿ®ÑHI¥2,X0ååøöÛï±nÝjL›FhƼ¼¼‰ÀÀд}û›Dee•&ßçŸßŒÄÄx|ùå>L: aa¡puuÁ³Ï>…÷ÞûÞÿ#üö·[éÉlˆ ‘H ‰(f}§NõcN– 0}úk˜5« mmm¸qã** ·èM åpˆÉØ‚A ¡§R‘gŠÅÄë÷¿7žnÛ6â[5uª6f•%8;›¾æåe]ᾂÏ'±«âãcĉÉÉÃßôm8!͆é:9Ù~Uy9zƒYß`ÛšLßÇŠ¤hX…B™Ô2{¡_hœf÷ Ú ²;W¬ò‰2†¦ê𠎱ù>ž“ ÝhÃ3—ÿ Ž½æŠ¶ 02 S[å÷–0õ¡®ÃÙ«_Ç “N}¬yùOá˜Ë4ß'À °4^?µÝíÍ6åíÄwG cÔõçììÛ”ã­[ŸÃÚµ«°iÓãÓ+êB[Šüü»hll·ßjc᩵VuuõHOÿ@󫩩ï~õ4Ö®]…ƒ‡‡›Ñ|‹ŠŒ ò‹áŽcÇŽaÕªUzýÄò}J% žÏÏΞÕß»G¶‚ÍÖú_¹º³f l=¨µdß~K4RÖÀZè7LÓ¬»ºZ¯‘™<™øÙ‚wß% ú/¾ ûº=`‹Ðgͺ944Ä£ºú~ï˜l:T€HdÜÔÏç£{¢&Ó‚ÔDÐxDº†Š{¸wýÈ$=FƒÑš‚±8EæpçòOÔÁ¸µnÞ6¿Ç¼Ç^ïw]ŒMYa·zuä»Ñ‹Æ°AhÑ$$/‹Å†o/ JiA–&ö[_Ppåø¨©Ãž1¤½N.B¡2™ííðññ†J´·Áòø&N‡Y³fô.0»(ù\¾| Û·¿‰U«–š|Vkk||¼Áf³ÑÒÒ¡P¹\Ÿ~: J¥QQøã·ß~'Ož¦;ùA7¸§©¯'Nn¬§–à›oXÆ&– IDAT´i8ãš—š ±±etrÒRΜ-"ºÔìà ‘‘ÀC¾Œ† ÁžŠ`g ¸8.-£1|ýµq†Â­[·â“O>ðr³é¦y¸phøî>(ι`ôzI^&…™­¶4å7X~R´ 5B R*Qpå'Œ›EÌdR1Êï\B!ƒXØeöÞŽæZ¸Ø@©TÈÁd± •ˆÀå9¡§»ƒ¢­qä»#zü„Äž´qq˜€»×~ðº?g5ò.Q6³XlÌZý2þŸ}(7/;[éŽIÃn}T®žþpíeoÔMËw÷AwG‹Éûn_8ˆ¬wãÑWþ6ÇÁ*Í•n?ÎË<ŠØ‰”k#™ä/ùZZÚú‹‹3V­Z†ŽŽNœ8qO?ýDŸòIJJ@\\ŒÝßÓÇÇ AÝCû½´··ÃÍÍÍ.±aJJJ0fÌ£×îßײôÙô=÷rݽKè ‡w}2™Àر¤Üù£+n5¢¢¡5¦œ#‹÷í¾W^±o9V¯îËØý\¼ønïÑËhmõ`ñ—ËÕX$ЂÔX$@Áåc˜ºh£Ýó´7¢¾üŽFcWBòäeõ]ËÃw÷1ÚT$ȯB.‹ÍLÚcÀÎçäâÔõ¯¡§»sصC`d’ÙEª=0gÍV»h¯ø>ô‡3 aKÕM+‹ ééÖtý¤T¨+»csY.ý殃û/ýÄêÐÃK–Ø×sßÝÝ 7®ïWãÆQuØÕÕ…êj§j0%úÔïÿ{äää ""»víB:lqïÞ=¬[·•E´M--}^ Ï56Ôp¤ì ÓŒ~>>æcO 6¼¼@c‘”DX«¿&ðö¦¦‘JŽ^^±XŒ+W®è\mÀ'Ÿü›7ŸêC{{Y ¼Ýï º‰û)à´i ¡åR Žþ‹ÊwûüA»<'óGbj"“ô¥—IÅèé¶Ý‘|öê—ú\¦€ðÄÕV Ó¨àØWLœ·¾ßy¨ãd¸zúÑL˜³F|Ú^PjdéçØ0Þø…Ä¢±ªÈpáÜ;¦ç\@wg3Ý£ÝÝÝ(**BQQd2Ù >ûàÁƒøòË/‘““ƒ#GŽ`Á‚P˜²³³999³¾ª*⤮ϢwЊÏè%¡;2Ò6S¾´´þ±įÉߦõë®Ö­3\D¸zî9úê+ü²©UýÍðxÀæÍÔk55$Î@Ìú„B¡]žùôÓOã믿Ð÷¢©~@¥Ráòñ›¼ÞÑ\‹+?}n×g*r£‹³ÖúrÜ¿yÖè=åååAsáþ}ýy×>@s³~ýïÄOœÄŽ'ñì³gÐÕe\¥zìФ±®ŽÄ¨áä䄞žÝ‘‚”L&ƒ@  üK‹rõÄÊñ3ßZ}omYíú­æXØÕIV}yéè'tÞtûü÷h¨¤ZËeR£¦;R±"°„:¹ªøÖ´OôĹðŒðçxø…šþ0MhàhÐv¶ ðú©~çãæ„Îfê·?eÑ“¸yf¿Þ!2jLƒÆpEvv6¸\.ÒÒÒ0{ölÌž=gÏžÅý×áøNœ8÷ß™™™¸qã†Y!êܹs˜Ò«ÂÙ³G»èš0h›ªªl'šxöYÓ×nÜ ì}åå@DÝžý…n]GÛiz÷ö¦©Õm…@´·Û'¯•+¼<`ùr²‘¡‹o¾qCtôR$'/…§g²É¬zñ=0™dËJ¥R¢µ¡Bs½»£|7oÜ8µÏªgó=|Àå7͘–¶ :ñ¡8\zº;À¶* "¡±CÃó:}éfzTÓ³‹’f’¸ZžáG>ønÞCRžÐ¸É`X`Ùš0w-xΣ®­d2 :Zú>°»y‚ÍæbÒ¼õ¸}þ †bÚ’M”t,× Æ›¤§ÝÄ»ÞÑBH4†ÇŽ—ËÅO<-[¶`ß>`“N×f2™X´hQï·$CVV„B!ÒÓÓ‡ððp$''C à7ÞÀ­[·ÐÞÞŽ;v .n&’OO°v-ðòË@` }ß¡¥…8ØD#ÕJ“¼Òè6m^å),4­¹µ!!¦ƒ-—•sçöïYJ%PQ<ÿüZ|ûí·xÅÞt„#Y,Ü¿yþañp÷ °g\ûy/ÖÅ|d¼q¸<È¥bá‡ç䊎æZÈe°¹hm¨Àô¥›qí篨y¯Ð¦ÖÅŒŸk²žþá”c“ ¥R ›©X›£#ÀlÑüïèì'zKÇ88òáân¶>ÝE³zAíï ¨!yOkúÅ@~[C-´gŸùÖjO[5¸I3WÔoK]9b'ÏGK]ZêÊàêégO¤¬|ž¢±n®-Áw¾ˆàè ŠG4† ‘‘‘„„ )DEu¥ëæÄáp0oÞ<@ZZŠŠŠP^^ŽôôtÔÖÖâs;»W^yo¿=%%ÔH·'O:¿ÛÁÁdç=r€ 5||ûäIH,|ˆP62rôôg{ô©ðð‡ó½¬Ab"pó&õ\w·e’•²2Ìzï^í1D94Ù„tw4C¦£!ʹpb‘é˜Mm•fÍÍŒ¡½±{ÿ²mUךkJpý—}PÈ©€ÉbC© ž3öÜìÓÄìpêâ¾Ó±;:»A,ì„‹‡mh®)‡_Ý9ú¯€D&¥ úsg,†®ü>ÂÖïÚ›jàîk hË7êîlTSœ}Z+¸©¿}HH^Œ{Ù§’¤bäR‰Áý‚Ž&páàDVdRi8<4×Ð>S4Gˆ:}ú4¦L™‚úú &È¿µ`M‡´´4lß¾±±±Ôo²½¸˜Áž=ÆÏËd@eeÿÞqãÆ©»iÓìgî¶q#1EL13EÙú,ÝôUCg,L©¡¡ý»¸"4tèž]QAúgPP[K½öÝwÄN=FTõ.«ù|>º»»iAj0ÐT]lpN—u¯«­lޤb‘Ñûï^=‰±3–kŽ;[ê Ìj òÞ Ô–ækžWS’™¤¾!hoªÒ<óæÙïÈN²J€¡ÙÉÕæ®…›W^ØqdÀë†ÍáB.“R1ŒÁÕÃŽÎÚཾ!±ÃºÍݼ1fúÒS^c°–À`¤hh˜GBò"“æšLÓ—nB!ˈ¹s[CºZž8Íp‚*¼?xõj§»Û›áካ'÷ЕNc@qâÄ üðÃX·nbbbÐÒH$ý˳¸˜={6圯¯/šš<gú>5…RI˜ÓÔèî&¾MMÀ™3Ä,IÓ§×®ô‰½1­ÝÜ´æ}Ö`¤<ñ°h‘õ ê'†˜û©¯õºnad4…à~N©Á#dJvq~ìŒ< SÏÕדr>x@%œhЂ”ízue”súìW &WO|‰Ú’<Í9¥BŽæš€ñs× ûô·hk¬Di~&Í{ …èj­‡ ½ |wˆ…Hzºq+ã%ï¸É Pt+-†[qL& *¥RsÌbq¶é\ûù+F’þañh¨¼ÿð„!«Ã°„©3¥É 6 ë6gsàìêeUy¦.‚W€¡×pò’§Àu:–B[)µ#ÆÎ@`dR¿žÉwóÆø9kèAcaŠrÿò±ÏÈøÄ`ÀÕÓR±L[cÞ«‹”U/ ¾â."H¸à˜ ¨)ÉÕ\wprDDví]= ´ÑOc@ÐÜÜÜãÅ6¼GGëQÔôäÝÝÆÙôàÀ`̘1xóÍ7‘˜HèÛ¿ÿþ{ÅÀÉÊáZWRC&#ç{­ 5pu%þ..Àosáá„lB¦h­G•¸§'YÌŽôµ^}|LM6¯¡xx˜öŸ²„ï¿7¤Ö­[‡C‡Ñ‚”µP*”øNÂÎVìzÝr„{±H`TÛÔZ_™„Ð'fþ°‚Ž&ÜÊøY?~ŠY«^„\&Aþåã½ /4V¡øö2&NÃÍsÿAåý›¨+-0é“ÐÖX •J ©Äðù·/‚oðÛ§öiü_\<ý('Î[©DN?õþ‰`²9˜¹‚æþÔ‡#ßl®ƒ¡Páîc‘TaXíä8¹hèéû™ÅæPPf&ñˆ1vËËT蟿ú+”J¹ÁxfŒÐÕÓR±H#üsyN¸wã´fÉÝ'-µtÃÑP´´´àäÉ“˜;w.ŒÉئË~÷nÓ÷©T€z=¤PR5 ©D·prrÂÎ;}o¿}sç?á˜àw¿³\Æ»wûön–©öuHƒF_˜8xÏzÉÄ’BÿÛ4†ÐP ºšüM4»ÍÍZ=kò0ooo´è´ e *tw´èVr4VQÍöD‚v«cBß>¡  r™b8PÝÍàÛH–0WO~ip¾4? J¥Â^6-±H^¯¯ÂÞ¿l„oH ØŒ›³N.3D'9Î¥£Ÿôo¡6÷Q0À0j:Ô_-á¾»ÏCù^^þá_Ÿ¡Æ„¹œË½pSµÛ3º;[úeÊ ééÖlýöÞ;¼ª*]üÿœ~Ò{£„J „¡ "êŠÅ‚ŒG½^¯3rçΗ™ßŒ2êÈØËØ•.Q@¤‡!@!…4’ž“œäôóûcçœä¤'$„²>Ï“'g¯½ÊÞk¯µ÷z×z×û6¤0'µÉ=UAGÙ½{7?ýô÷ß?}úô\ýÈ4ô)Óï×~òª«aåʺðädص«îœ¾ÎÓ .¾¤ž~ºé¼76К×j%!¬5&L€‡÷ïs5lÑ¢Ö7Í7Gs×Û–A®RÙü`Wp}rï½W®¬æŒ”lØÐzÚñã÷›ädÉpDXìÞÝtº%u¾–ð÷÷§´´k´+®KAj÷†w[Sv)»‘O(µ½Ò‚,üCû8ÃM5z z{6¾ËÄÙOñ×EÑM¦oêX¥qãh=/n^¾ 1™’üLŽÿ¶–ÊòBì6ý£o&ãôdr9‰{7!“ÉððòÇTSåÜ<àíJ¿¨ñ¿ ÉsÝÄÙO)ùÍ8wl—²]ݵ÷„Jݼ*…B©"´Oš`Ìä9âÔÍ„õ‹B.—t n¹÷YQ!ÍÐoØx¼ý¯Ü´oÏ1íŠ_SUá²—°#\Ê>GH3ª~ ¯gO½wâÅ´Dn¹÷¹ó.λ€¡V½/åøoªuÞkAGغu+ …‚ÂÂù¸·QÇîóÏ]¡ú8ÌŠ—”ÀÞ½õ&Œ’êH+D—.µ0ñR»¸n2ZÝ|Cè?lC¨®*Ãݳîã+ÍwZXK9±³ÑÀG­qG®P4ºŸ>‘c°ÛmÎU­[þÄ;oòÞµnuÂWyQ®Ógþ…³(Uš+n« ëœÓXg Tiœ+2go%ÿBÒUõBé3dL³ç.gÏNWï÷5m^›|uåuDŸuU~$ô%-¶³†×í˜4q'msY9)'8Ÿ°Û%Ìl24òçàbÚI¬>œ=ô‹KÙFƒ¾‘3ï&óH?…ÖÝ …²N§©áþO£AZãÆöo_ç×o_gïÆ÷yhÉ b!h•_ý•/¿ü’!CµÙ*ŸKÿÓ7¿õóÏ®ÿßzËõ|V–d0Âdjÿ@Ïå½§‘Ô‡.kB¦öÓ0q¢¤"Øj5ÄÄ\ÏÎËKZå<fÍ’ê žŸäö 6å—/Ý|sËæÈ;ò<í£55ÙŽräˆämÛ6HO¯ V2ÎdÒœ¥Œ¾m!Û¿}Óâ(ÈJæÌÁ-]L£ ó¬Ó§ÐÑíß2dÜíxú¸î¢Ó¸yb·Û™6ï]LcÚ¼ØñýJܽüðòA­qÇË?˜Ñô0“¡š€ýè;d,é§öcµºZÙê;tãn_Äá­_»ÔÆÍ¬­o+Ù)Ç0kPiZÿ Ÿ8ÇiþØfµ—q]iû‘—_ãf.êPÉ<{˜¤&,‡uåE¹Ô„ï¯îdhí³ºÖP©µÈå ñ•h‚’‚LNìZç<í‹·óf¹¶ów,æ:ã ?þm.«èbšs²å×ïWÖN‚$ÖoX“ñÏ'ìÆl2ðË+°Ùíœ=¼•̳‡Ñº{3iöSÎx·-|¹Éôý†Mpî…r™É>GMU…3mMUnž¾˜ zBûEWšÏб·‹Æ!h–êêjÞzë-<==Y¶l»w×ÙÊ>v¬ÎH³à`øñGéoÎIUèða\ÒX,’A «ŽmZèIÍ'­?ÒÀ¾}R9?\70{úiÚl½=ÜqGÛâiµ0eÊÕùLÕêëÇøÌ™¢‚$¼´‡¾}%§¸-°;Tù>ÿ]ûªFyy ðÈåØÚ¢#ÜN.»K”••Ò§O_*+sQÔ[M)/¯À`0RRRJXXã™îýû÷³|ùòÚ—hÓâmJJ óæÍ ..޹s%¿5gÏžeË–-.q³‹ìغ…}{÷UXÍÁC‡‘Éd¤߉R©&b¸•ógS1{nÃj1“¯³s±ÌBþ…ÃT2¤÷x~Ù¼ƒ¦'="¨”’qð yŸàå?„ä´ÒsK1ÖTa³ZP©µØlÖÚ½X22NïGúÒO‘] CŸp 7OÉ­rAN yeñ’sÞô‹”æbT…r:9šªr~Xýé¹¥„¤fqà§Ïí;”]&$-q/c&c.–š¹´c‹%õÃÜR’á铊oÂ)rSOr65›SgÏS’ŸÉ¥œódê |g’ÓÈ>‚„SgñðvU=I9±K•rä võ¶tÍÅù°Ûí9Újܦp¤1ÖèÉË8MVAË«r…¹©(•jü÷ïw¦Í>‚„Ä$<¼ý¯è‹ÕQþù„=ä•[ˤœØGqÍÊ+Z¾ÉXCnj9EÕÎ0]Y!•¥—HJ¹à +º˜Ž\®  ¶·ô¬ROîáb™¹BIÊñý·=½®”Ò‚,R.ä¹´³†ý¦)2’¢×ÉøúÃ7¸t‹Ù„Íjæ›Vb19Ÿp›'æZ7%Æ•T–’SÛwuµ~ëÞù˳ä—YˆÛð­so§grºÒKô¸{]D­uG_QBq†Ü}o&~ÿ~öîÞ…ZëÕ"MÁç”É<›À¹ô\ô:I‘<-§“AïTY3™´Di§¾çÙó”™<ùß§fáÔƒêÊrúDŽ!iï<ûMæDbv›¿÷6~U¬Jݨ|ø¡ähÕ§Vs{ÎØ´Iúm0øøãY²d žM˜¦³Z% ]ß~+`ÈÍ•ÜîÙ#­Z<ù$¬^-ÅugصKRÝ3¤ô-m./(€S§`ölxýuið?nœ”端Bt´dpÁ¡>¤ÑÔùŒÒj¥ÙñgkmùX,Òñ˜1°d ÔÔHé›b„¦Ãﻯe￯¼"Ú”àÊ3c†ë„EGyåØÚÁ9s__hIã÷üyÉ[-çsð dáÏá»).\È÷ßÏÂNô}Y‚TŸ>ýÀd21xð”J%þþþ”••àã㇄„„âããÛ©~ðàÁôëׯÑì—±ÖúÈ1ÄÇÇsóÍ73fLÝÓSÿIÕ®ëö C¼ÉDÿÞAôïíj•.<$–ØŠÁŽ|2fÌÀȘ±c3v,ååå\¼x‘¨¨¨&Ö]“““™|û=ø{ɘ³PòßtÓø õò­+#>>¾Þ5Y ¬w>ÌñÛ^†G¨9é&ú„ú€½Ìõ>쮆c¢£ˆÿµö¾*¤¸Ž4õþ{xÉPFDpéÒ%<êåá8ߤ¤$ú÷¯¯óüˆáÑ€ìÒÔá¨Q#Á^VW¯MäÓ0G\空æ IDAT=ÙË2°_“÷VS­ÇKV!é{¶gqq1%%%Îý|¡¾ÎüÆ=}ú4áááøø4¿÷Ë‘æäñæï«>ýzOïogÚæî©¥vØH@+,¤¢¢‚m°Ù›˜˜Hÿþýå1ÀØQ£š|m!55oooBZs®R?_{jð‹âÚ}U„ùö{ƒ{=ü›}V óS{Ov×{r¤Óét\ÊÊ"::Úõ\Ï!%%‚êÙ{ê°¢WÃÈuú9ñûª}5xÔÞS¨#¼oâãã ñ&<ä&z×ë»áîkÁ/¶R«6TrñâÅï3èì˜ËwžKNNfààH˜ö îXÓ¬5Â$úLCU9‡zÝÎ;IHHàùçŸGYoùâÜ9øá¨E¡ @ÔZ?':Z2Óü§?µ­üøxIí§©ðú¯¦½{%áI.—6±’MxõU×t£FIª€¡íÅ%Áhÿ~Éìòر’à¥V7?è»í¶fZÊöÕ%\y¨ÁåÐ’µË+Ñžƒ“'%AêÖ[áïoúšT*f³¹SËî° 5|xÇGM¸þÆŽ¬)—à šÇgÀ€.Òµk×2räHHxx8ÙÙÙ˜L& àŒ£P(éZÿùÏv9^±b…sÅ«5º"nFFäÁl5îÚµk‰‰‰i“QŽî¾¯””Nž<Éüùó[ûÝwß1nÜ8"Ú¬¼ ï+))‰””î¹çžVã~ùå—L™2Åéÿäj¾¯ÄÄD²²²øÝïZ·*÷ÙgŸ1sæLz6TH¾Ìk‹‹£wïÞŒhƒr}w×WNN¿ýö¶aWô?üÀÀ6lØU_8p€‡z¨Õ¸ëÖ­#::šÈÈH1:´‹;w¢V«yá…øûßå.B‘Ý.­$9Ø·&Mª;–ÉÚf™Ï±ïaçNÉDÿþðÏJa11’Z£éîÛ'åY5hË–¦UÔÆ“,þ9ص ¦N•VÌÞyçÊ×e[̬ ÉßþÖö‰Œ†ìÛ×õí95URt™ *•ôû`­Íµ Zž¸'Ë1cÒItx”L&«ý£‰?Y«ég͚ťK—øòË/Y¶¬ióØ<ò»víâÈ‘#í^†sx0ïlÚš¯ŸŸÃÛhægذavÛµ¶'n```›ŽWõvU;9r¤´Êv \khhh›ı±±x·´ ú*ê_WCÝ2„àààkâZýýý‰iãö¨¨¨.y ®?‚´ï`jµš‰'"—˱Z%k{'Nàt}ê”´*e³Ij| ©í8œã:„$»]ŠãH7eJ]üúåjµ’ÏóÏçŸJƒµ)S¤=Rry%°ÌLi¥ê“Oêòo ¼öZÇêfÖ,=Z´Áµ×ŸÛË©Su¦ÈÛBC7õùßÿmºÚíÒªvý@“%Ï,]ZçxÒ$©ß:ðô”,÷9œù:d—ÎÜ+Õ­ygÍšÕHˆš7ož‹Ò#<Â<Ðî¼';j¸“ik¾~~~’zP:th#5š+y­í‰ ©+^×ÚUí`øðá-ªõ]M× ‡.K+Œ1//¯k¢] uÙfAª»¯Õ××·]ï#!H Z£¤þýoسg3fü;^Ã`˜èœ™.,”¬è½õ–døÁ¡Tò·¿ÁŽ0}º4p{òÉ:AêÞ{aãFÉ/ÌÿýŸä?ª¼\ÙíÒ¬÷Ô©Òž¢É“%µ;ö1åäHƒ¦3g¤°?ýIÚS!©ìM™½zµíÞ3Úv»t­WÂÀÂ΢M C‡J*¸õÉΖԀOœhyb£~?ݽ[êóް}ûêúØ‚ xê©Õׇ uµp[sŠÍâZ/‹‘#Gv‰€Ø„„„tÉJ›hÒÀ¼Gk»D¯|}}} M#_Kí@p}ñþû·“IÆ„ büx;vH+GÛ·ÃR¼#G$AÇBF£ôÿÀI rÌ ßv›4ðq¨âyxÔ œF’ö=Œ/Åß°¡n“üßÿÞüuj4®Ç6›«ÅÀ¦xé%)Í÷ß/í—êxm[¼øøî}ž~~bíFű—Èhl]E¯;ÈÍ•&A±ù}‡[‚›o†ÿ÷ÿêÂÔü^}Uš1™¤‰£,9r¹½Ó®ï²)¥R‹Jåæò'—»¾µŒF#ååWW×yÙ³Ùêv[VUIð:‰’’ö;¦­€‹/²bÅ ê¹U?~¼K³ÙÌ/¿üâ<^µj•Ó³ûæÍ›»µA5¼Ö«™!C†´Y®» lóÊÍÕÀµÔ"""Ú¼rÓÝxyy]5µc›ƒcÇŽ±bÅ ?õÛAMMó=µ«ÞHÑf³µÛŸàú¡¦¦†²VônªªªÐµðÝ5™L”••a³Ù¨©©Áh4b·¯äÌعs2¯¿.Å{ãºKB‚$è¼ý¶dÒØÇG€^z Þ|S´§¥Iæ”û2Æ—,ÜõëרÊÝ;ïH³Ì6›$˜íÜ)©ö5¤aXCkx‰‰ufÒÛBSe´•¨(i•íZÀÛ[º^ÁÇ+¯HÖ0åò:çÖ]ó.jE ‘KBBÑx²C©lzeØa)sÔ(×I“úý¶¼NŸ–&_.„ï¾ áܹ=ÄÇÇwŠá‰Ë¤d2fsË_rrÕÕÕÎ8ï½÷)ëÖmbÇŽÝ®‰ÿúWIYº¢Bz³®_/…ïÝ /tŽIݲ²2Þ{ï=kÒ—””°yóf–/_NVV§OŸnòƒñÕW_±mÛ6gزeËX¾|9·ÜrË5#®n, ¦z¦šôíù² ®{Ξ=Ë|@~¾dýäÉ“äçç³|ùrÖ­[G¹cªï¿ÿ>Ë—/çµ×^#¾vzÛf³±iÓ&¾ÿþû«æÞl6ÙÙ9¤¥e8ÿŠ‹‹Û´·VÐ>ôz=ï½÷ß|ó ¿5c/<33“?þ˜ÿüç?œ:uªÉ8K—.ÅßߟÌÌLî¹çþú׿rÓMÏñÒK·àå%™—É$Såv»4ë;kddH+NGÂǃÙ,‚pNPTÔØ—Mv6„‡Kæ”þ~n¿]ú“Ë%aêÌxæé\}Ÿ@/¿\7ðjÍ’Xk(—·Q·wCpåñók¿Ÿ$A×ñ϶|~Àɪç!’IôúÖ,o½U–êSOÔhDûs  í¯zúéRÖ­ÍÞ½Ÿ0qâD~ÿûß»ŒÅ:B—kþZ­Vž|òNžl ´¸¹ÁâÅÒïgŸ­[£Ÿ5«ÓD⌌ ž}öYç ¢²²Ò¹¤_¿~ddd4Ú7PPPÀìÙ³ÉkÂûסC‡xþùçEo\6 33“ùóç#“ɈgÆŒ¡ÕjqssÃl6SVVFHHˆ‹6ÁõOMM ÷Ö›ÊNOOgÈ!xzzRUUÕhR祗^Ân·ÇÝwßí¢† âL{% #<¼·K˜\®Ä`8Î!Ck}ð9¾6ÜÜ´âÁw2o½õ–ÓªãŠ+¸Õ¡S¯¿þÚ%ŽÃH’Ñh¤¤¤Äù¾r””Ä2eJ)&“$8­\ kÖHûŒFiøæ›¥ŽÊJiÞô”ö?=ý´¤žóÛo’g¡C%g›¥¥Ò§ÊJG›† ‘‘RXÿþÒy½^²ÔUZê¥8[·JñÊʤ™ïž=¥Ùê¢"i@VY)¥1ëâºZ«¬çîO&“®¡9ÿO ‡ÅÅ’2#¼²²e'¢õÏëtRyát´­TVB~¾4—ÝÚµ^Kètu÷TY)­´]/÷Öjµ$4VVJ{µÚöß³£_(­·Û†í¿~¿ÉËkÜžt:)lÒ$)¼¦¦.›[ã4ÇŽIn Ö­“öD6̤þûæ›0¾ë;#?_2d±pa]\«UZ%_¸¶lÉåܹsÎü>ûì3æÎËwÞyu Rÿþ÷GÄÇ⦛Æ0iÒ•WEŠ¥Ôñ¶m#áááM†ïÙ³‡›nº MC…k ¤¥¥qòäI¦M›†B¡`óæÍ̘1ƒ?þñôêÕ‹þýû“ÑhdðàÁm2£/¸~ˆå×_mwº¸¸8úôéCLL eee¬[·Ž¡C‡²{÷næÌ™ÓfƒÉdÄn7c¯5ÁdµZ))©Àl6QZZŒÉT燪¤¤´Ö†àj¡¨¨È©™QUUår.+k#qq»Çß|Ó|>kÖHÿ+**ðññ¡¡Vòš5uqê#“IÖö23¥IPOOOçªeXXã4áá’ æàäɺü+**ÈËóq¦IIi{=8®»¹ûj‰/¾¨A©T¢rØhn%†Ç͕ݪªªpsskq®~yõ›Íf,K#73mftm¶ÛƒÁ€L&ëÐXËn·SUUåœ0oË3ªOuu5jµÚÅÿY[±X,F<<<:tß—ó¬M&6› ­VÛî{nªìÿü§õ4 ûuÃðæ®£~ÿ·ÙlTWWóᇞҜ9ãÚŸ›j§>>ÜwŸk}þyó×¼q£ôêlºTzî¹§0ŒÝ"DIç²²²(..&++‹ÀÀ@ ééé$%%1©Ö‰Åùóçùá‡xå•W¨®®&??ŸÒÒRÒÓÓ G¥RqäÈž{î9ñut #GŽ$88üüü uä333ÉÈÈ`Ê”)øùù‰ »ÁÈËË#??NGAA£GæÀh4Ìf3þþ’âíÛ·SVVÆüùóÙ¼y36› OOO.\¸@¿~ý\Tú®¤PY©Ãf“ÄeeÈå2jjjðööD.—c³Ù°Z­ÔÔÔ PÛGŸŸeeeøúúº¨N:V¾½¼¼ððð@¯×£T*]¯½zõâñÇ$ßy/^ÀÛÛ› 6´ÛÐI{ü£5ä_ÿú?þx›­ŠvfÙ—“öÇtNl\é²?ûì3î¸ãŽú9}ú4éééÌ™3§Ceÿãÿॗ^jV€l‰;w¢ÑhÚìð½>z½ž>úˆ;¨¹fÍFŒÑ&Ÿž ÉÌÌdß¾}<üðÃWüY=z”’’fÖ×q½úGII kÖ¬áé§Ÿ¾be_¼x‘!C†PY»Œ5bĈ÷ÏN¤Ìf ®Tkì&ó÷÷kM†>’Ö#GŒÖù;‰ììl’““0`'Nœ`îܹ,X°€ü‘I“&Ñ»·¤vRßRWYY‡bôèÑ:tˆàà`T*3gÎD«ª'‚ΡOŸ>ìܹ«Õʈ#8}ú4¹¹¹0iÒ$öíÛGDDééé.Ψ7ÉÉÉ( )))NßRû÷ïçÀ½Ö Gxx8Aµ›0ú÷ïÏ©S§8tè*•Š~ýú9óëè€èr°X,TVVáãã…Å"©©‡P^^A@€ŸÓQG\‚Öyæ™gx÷Ýw©¨¨pQ]µj£Fbîܹ<öØc|ôÑGX,–f6ýõ×ìß¿ŸM›6ñ_ÿõ_ŒëÀÆ“î´àÚ]e{zzv›‹O‡VV:ÿnÙó(—Ë»mâQ¥RuxîrÑjµ^ »VûVGËîÙ³'Û¶m###Üôj«_„®¤ =%%®ªsÞÞ^./ŽÇ¸¹¯¬´¾>x°dê§NúqUˆ¼ FŽÉÈ‘#]¼¼¼©I;uÇ{öìÙ¤Õ•žÍ\ßøûûóÒK/9×®] àœ™ííÆ¦©½,}úô¡OŸ>.aõ-GGG7Ûnº«=UVêðòò¤¬¬Üe`USSÅâSk΀F£½ ÉdMjR¬X±ÂùÛ××·Õ|GÛËÈÈèUÿÝÖtWÙÓ¦Më¶{¾ï¾ûº­ì%K–tK¹nnn,v콿ÂôìÙ“ž={vKÙÝ9^¸ûõøñã;Õòñe RZ­šþýûv,ñ=÷@zº$HÕ'/O2/‚kF‹F£E§«¢¢¢ __?´Z7”J%îîÒ~—ÊÊj‚‚‘ËåÈdBµïj'$$¤[Ê B.—ßP÷Üe»¹¹ux¿ÎåâååÕm+Ô~~~ݦyt#¶3…Bq]8¿¢ë¾&“‹¥vƒqD˜ôWUèiXéÃp@ \(f¦L™ˆ§gã=-Zç¯ú¨TÂ2åÕĹsçP*•.ªÅ W ºlÕ˜ÖèNc;ݵºÒe0 ÛTÊÇŒÓmõ=cÆ Ñή ¾¾¾Ì›7¯KËÈÏÏ',,¬ÙóÕÕÕœ={–AƒuX5óŠ RV««ÕŒÍf#/¯@|©à:¦¢¢±3v™ ÊÊ\UÂCCCP*… uµ°oß> °X,TTTÛ(ÎÆQ©T$$$pÛm·5kñV iÏdIII·®¼n,²²²Xºt)¿üòK³BÔ†  $))‰9sæth%¶[v"šLf¶nÝA@€4+)—Ëk—s5‹•(A× —Ë4hV«NÇ¥Kù¢R‚+Hß¾ý)//£²Rç4CëëëGHH°¨œ«ˆÝ»w»ø–jJJJJr‰ÓQË]‚ƒŠŠ Ö¯_Ï3/ÊõÈÏÏG¯× ÃJ‚NÃn·³gÏ&L˜Ðlœôôt¼¼¼¸ãŽ;ˆçøñãÚר쮛tww# ÀOO/üü|P(ä9rœÀÀÑ]&HùSYYNjj>~~¾¢R‚+HHH0þþÞØl6**tTVVˆR©좂‚똤¤$^ýu-ZÄáÇIOOgÑ¢ElÙ²…èèhjjjøí·ßP( <˜~ýú‘——‡»»»Ó—Ù„ x÷ÝwñõõE«Õb4Q*•X­Vrss8p ,•}ƒ#“ÉX´h‘‹a.×MzxxÒ»woý{—8ÉÁÕ…ÍfìøùùÒ«W/¬V!@]møúúR^^NQQ‘Ó¼>Hæ÷ J¥‹ÅBff&}ûö•&hooo|ðA~øáòóóÉÌÌdïÞ½Œ1‚’’ÊËËñ÷÷硇¢´´”ÊÊJ>LMäØX©TrñâEL&ëׯ'%%Åés177—åË—“šš**ZÐ,ƒøøx@rOàÐKKK›Ü»{U R&“‘œœl§S,@ Ü8èõz.^ÌÅh4ˆÊ¸ÊX´h_}õ6lpq0úùçŸ;¿Ù‹/fåÊ•ìÛ·¯YÿSA}¾;u:ƒÁ9pMKK#-- |ãùùùqûí·³wï^ÊËË bÒ¤ILš4‰sçÎ1hÐ §¬ˆˆd2V«•+V0dÈQÑìv;+V¬ 77—+VpôèQgÛûüóÏèׯ‘‘‘¬X±FŒÑ¡².Kµïàá“Xå®NÀò³R˜3{&*UËY›Íf¬Vyy—ÐhÔÎýR@ ¸~1 ”””RSc@¡PàïïÖée&òòŠ1l7L½–––vZ^>>>,[¶¬QøgŸ}æüÊ«¯¾*´ ÍmêþûïÇ××—'žx‚ÊÊJ4 nnn”””`±XèÕ«v»´B]\\LXX2™ /¯:럳fÍ"11‘>úÈÙ/]ºÄ§Ÿ~*öé œÈd²&ÛCpp0Ÿ~ú©óxôèÑŒ=ú²Êº,AÊ*÷ 4ò6çñ×­$ÔGŽZ­ÆnoùæááI``p­ähÃh´àááE@@h‚.A.—S\\FNN6jµV´5à c6[¨©1áå勤áééÝÉý\†Á`àÂ…t.\H¿Á«Þ¢‘ ®J”J%ÁÁÒ˜/00ÐÅŸŸ_£øÄn·£V«™×‰‰q9 ëVóႼm_NââÂ<þºb:÷?ò 9RÙ¼úS6þ¼°ðùçß²xñƒ~ÛlVöí;ÀéÓIμüý©©©æøñ×me«Õ‚ƒ¯>ÓŸUU•”——Ýp?!á¤xWF‹——·‹uVww–,Y„§§Çeç¯R)ñôôD¡¸1ûÚl6²³³Ð뢱 ®  çÎmSܲ²Qa‚NøN)ðõm»cæË¤<<}ðñ àÏX„Ùdäãõ{ñõ$QÅÅ%|ýõjæÏ¿—ââºn·K«PJ¥___¼¼¼©ªª¤¢¢ww·ëöáøùù€NW~U]WZZžžî¢÷‚.%00__¼½=Ðé¤ œ°°P4m§äïééÅÈ‘£DE  C(²vÅ¿,AÊÍ݃×ÞøŒ/?ÆÙÄ£„õê×(NII)gÏžkîëëGïÞá˜ÍF †jŒF#&“麤ŒFÕÕÕWÕ5éõz!H ‚+‚Åb¡¦¦­VÃàÁ‘N+p\.ÃÝ]%*Y W„Ë¤Ô ;=Ôüë½9´gzûᡪ3c;‚˜˜a?~’%KuIëááA~~žðå#7 V«…cÇŽ3lX”¨ @ Üx‚ÔÈèþ¨U ‚{ïC¥ÏahbÚ´ÉÌ˜ÑØSðÅ‹¹ø“““‹§§'jµZ< @ ¸(++§ªJ‡‡Û q¿))©TVêoؽ[Ý…§§ö!®NAJ¥R¶j¯9‚‚‚0 ›ÍNee%QQþ¸¹]¿VO**t–«êº† &¬= ‚.ÇËË›ÊÊ*ÂÃû"—Kzèþþ×ý}[,†B­j‡W•Ê ³¹FT„@ ¸:©ŽâîîÆ‹/þÞéPM 7.r¹X©Áu(HÙí6¬V3îînX­²N)T&“ U>@ ¸ÈU—mÏwW—W3F9§¨@ \Ÿ‚”Íf¬xx«n@ èÕöÒÌiÎ㢂"†ø…ß‚ÔÛo¿Ï /<Ýbœ¢¢b¶nÝÁÃ/G ´ ®’ 2…ЫW.+·¬¬œììœFáÁÁÁ„…uU¹\‰BÑXuÚj5c³uívš©œìK”•U‰)‚ËÂikØù”lJÜõ.aQÃú"ãúVû6™L¬\¹ µZÍóÏ/E¯¯æý÷?`Ö¬DEEràÀ—4!,,”uë6±hÑÊËuúàÏÁƒG?~l£rìv;ÿü翘:uQQ‘¼ûî'Œ?–ääž|ò<Â¥KE¤¦¦sß}³éׯh¬Á5Nyy6ßQxú…:Ãþò⣼óú·˜Î`0ðúëÿ¢oß><òÈB@rc·•G} ÕrKJJ‘O@ëQg‘ûå'æ°þ»w{— R‹ÑÅnƒÕjãìÙd¢£[†MMM'9ù<û÷$((€ùóï!<¼Wç R½ÃCè"Z¤@ .‹óª\0»† NOÿÐFqmÖë».>ÆÆßPYYŇþ‡¥Ks®P½õÖ{DEE2{ö,V®\U'ˆZ¬üðC/¿¼Œ7ß|—ú3dÈ üÙ¿ÿãÇå½÷>¡ºZ2®pÓMc˜4i¼3ß7ß|—~ýú8¯ûïŸÃºu›8v,'žXÄœ9w²rå*^~y™h¬Áu@Fj2……û¸õÎûùëˡѺ†ÝR·@˜£T*xþùߣÕjyúé'Ù²e«Ë$ŽÍV' ìßÜÜ®RϤÛîæ•§î¡ï€!hµnX,’U³Ù‰‰Œ‹^¯'55ƒ~ýúðñÇ_p÷ÝwàããMuu }ÉÌÌF©TRSSæM[X¼øA*²7:¶7úå—_9s&™ú#—Ë à…ž&/¯€w¾  “)Ðj½D‹¼F°Ù¬•¢"ÁU…Qg$çt¶ó¸º¼ÙhY—”e³Ù0™L¨Õìvf³¥R‰ÝnG¥Ra±X°X¬€­VÛd>f³«Õ‚L&C£Ñ`±X°ÙìØlV—}¾r¹¼v !C.—aµZ±Ùl¨TM[ék¸z´uëo$'§`·ÛIJ:×ì}9Ò½ôÒ³lÞü3V«{íhá™gžt‰¿wïŽ? ØSCüéß_˜®7~Þð%›Ö~ÃÚ/þÑPÃkvÑp6ëÀüüò2,+'N$2zôÈFùÜu×L—I ~äÅŸ¥wïžMN¾üðÝ'l‹[ÇðØ Øÿï½µ@E½I!3ÇŽÀd22hÐ@N:CLÌ0ž{n ï¼ó!>úññ‡ˆˆèK|ü!¦NÌÆq<ÿüRV­úˆÿþïçÛU—())åå——ñõ׫ñöö¦¨¨˜ÿûcìv;sæÜÙ¡znU’Ëåhµ>¢E^#X­&!H ‚«Žh·¢Ç^™Õ޼¼|~øá'BCCP«Õœ8qwwwär9K—>Æ’%Ï3a‚$˜DEE2mÚ-.y8Ôí´Z V«iÓ&óí·kéÑ#¹\ŽƒE`6[˜4i<¿ü²ƒ~ýÂ:4’ü…ýûñæ›mòúB˜L&C¥R¡ÕJBšL&súÖÚ¼ùgŽ=Á·ß®åÁç¡PÈQ(Î<¢¢"Ù´i r¹œªª¦Uðùxxx8Ë›2ebío%¥¥e¼óÎûX­6úôé-ª@pðÜ«oàáÂwŸ¾ÅìOàáé ”4- ( >¬Mù†„Ó£Gh³çÿøÐzø°yõ§<ôÔ˨š0.g·Û9tèýúõ .n+YYÙØlvRSÓ ÆÓÓ;÷¢V«éÑ#”ìì\>ùäKFŒˆ¾¬º92†ôô ñ OcµZyçyñÅg:_ª“ -|÷Ýw˜Ý IDATÍfyä”J%f³™;vpÇw4™fÏž=ÜtÓMh4¶oßÎŒ3šŒ·yóf"""6lX‡+¥~þ-•Õ–ôí\¬ìÞ½›[o½µK:Â?þñ^~ùeç´¢¢‚U«V1eÊ&Mš„Ífcýúõ²dÉê}gÁe–vrëþ³±†áãÚm|Ç`08W5Ú‹\®@¡ÐÐPmÁl6¶.»ÿæ6ïšLFd²æËµÙlèt•xx¸7»"ÓÕTW×`08|ø8“&çÁç³yóÂÂBÐëõŒÃsÏ=ÀÊ•« R5592NGff<ÿüïi-ZÀÛo¿Ç˜1#IMMãÎ;¥oÈܹw1wî]Í^ŸcVÕÓӃǀ)S&ºÄ™={³gÏrO˜0®Á·ÇÆ}÷ÍÆ×ׇ/¿ü¾ÉrÆŽeìØX—°‡žïüݧOoRS3xñÅgE‡®3ärxaùÈe6æ=ò, ¹Yƒ/‰››Ö¹Ú4}úT"#òÁŸráB±±#‰ŽÊO?måøñ¾új5‹- ¨¨˜wÞù«ÕJdäÀFå*dv–¿ñ ™ÇŸ}…Üõ”T*V«)S&²aÃLŸ>•üü #r¹//I îæ›obõêÜÿln¹åf²²$CM­œ&çê¼ô-rÕ÷òò¢¸¸„•+W¡×W3vl,:V®\…B¡`þü¹ªç6 Rëׯgüøñ¨Õj¾ûî;,XÀ7ß|ÃÉ“'›¤Nœ8All,†Ã‡3cÆ ªªª¨®®®ÕM Äjµ2~üx¼½½›Íf£ºZÒ¥ôõõE¯×ãááÑhD¡P4éÊ‘¿ã÷ôéÓ)**rVž››•••ÔÔÔ T*ñ÷÷Çb±PZZŠZ­æðáÃL™2³ÙŒ^¯G«ÕâííÁ`@§Óˆ\.§¨¨»Ýއ‡*•ŠcÇŽqë­·b³Ù0¨ÕjJJ$©ßÇÇ…BÑèžš¢¤¤«ÕŠ››^^^TWWóØc¹ÌB®ZµŠåË—óæ›o2iÒ$²³³1̘1ƒmÛ¶1kÖíâí!t%Õ-õ§&'²}Ã{Ü|óøv[:}ú,Ú9ã§ÓéHIIc̘Q­¦•ÉX­ÆF…„„SŒ9¼ ?ŠF›wNžl¹Üª*=ï½÷)Æ q®$?ÿ¼Å‹$'ç"ß~»ÎîîîVïû”ÈÅ‹ùh4j—ðºû—1uêdæÎ½ …BŸŸ¯‹z‹ƒqãFóöÛïs×]3]žMZZ÷ß?§Ëîqðà¬[·‰òò ü¡çsÛm·ˆÎ.\gøùù¦5àæVÈ»+& }Gž}vI£´ÿû¿¯¸ßu×L—÷[hhH³+7AAxyU¡V›øüÿ!©b³Ö}3•J¥s2Éñ :t0·Þêú. vƘ7on xf.\ÈÄju½¿=œ¿=<ÜùÃ\­¥Îš5ý²ëºÍ‚ÔäÉ“ùä“OÉd,Z´ˆK—.q×]wqñâÅÓ½þúë¨ÕjöìÙÃòåË9sæ 'Ož¬õô>œQ£FñÑGÁ<@yy9ÿú׿Æd21{ölV¯^ÍòåËÙ²e ƒ&**ªÉ²¶mÛÆm·Ý@\\yyyÎAË’%Kxÿý÷ñ÷÷Ç`0pË-·pêÔ)jjj0›Ídff²{÷nâââˆŠŠ¢¢¢‚Gy„Õ«W;õ烂‚ðõõ%%%¹\Nuu5Ï>û,v»ÌÌL¾ùææÎKRR¥¥¥˜Íf.\è¼'³ÙÌï~÷;Øäõët:JJJxþùçIOOç/ù «W¯F­V£Ó騬¬¤  €—^z «ÕJaa!eeeôîÝ›AƒaµšÄD è, «ÿóCcÆàæîÁ/¹‡·>ø²Pqš=Âä×_w1}úT6mÚBVV6&“™%KÅÛÛ‹]»ö9?ÕÕÕüóŸï’‘‘É”)yâ‰E\¸Åúõ›¸ãŽé 6¤Ý×»}û.O£T*X²d1fúô©”—WššNß¾áÄÇ&55€|p.d'm*ž3ç.ìß®2F[¶l#=ýîîn<öØCx{{qÿýsHNNqÆ[·n™™Ù„……0þ=ìÞ½ŸéÓ§ròä)zöìá´šÔYÌŸqq[éÝ»'=4__üü|yæ™'9>oooFŠaÏžý&–.}¬Qþþ~ 6„¸¸­xyyrß}³™>}ªó¼ã÷„ ãpww':z¨óœ··W—šúuЂÚÈ‘1¢³ ×^^žµß1C§ç]ÿ=ØoÀÖ%å¶„ÍfeðàÝR×m¤¶mÛÆc=†J¥"..Ž'Ÿ|²Mé^yå<=¥j·ÛÉÏϧ¨¨½^R©dòäÉ<ðÀ>|V}4 Ë–-#??™¬í›‘˜6m‰‰‰,_¾€+VPUUEXX‹/æìÙ³$''“íࡇbܸq¬_¿ž²²2âãã>\š}-++ÃÍÍÇܹôh2™Ø¹s'6›×^{ €Ï?ÿi_Ynn®Ë=4yíz½žK—.QUUÅ‘#Gxê©§ˆ‰‰aܸ:uŽóçÏsþüy~ýõW~øa »ví"55•¼¼<"""ÄÛC è$ªõ•ìÙ¾™ÿüûo¨5,~žèQãº>œ™™…‡‡ÁÁœx µZå܈ûüóKùøã/˜:uîîîüþ÷ñÛo{yè¡y|ÿýz-ZPûþø®C‚Tbâi.¼«ÕFVVŽózôújRSÓñóó%1ñ þó+$$œbß¾$$œrn>u*©¦™_ÝżEAÁ%6lø‘‡šß(ÞÔ©“0 N8ÈðÑÚ”.2r juÛö™ÍL&#z}5ûö¬¼éÐõŽ?–}ûb³Ù ­{ï”—×YK><ªÙô1ûÚ–t™™Ùüüó¯øùùpèÐ1úö wž«¨¨è¶çûÔS‹¯XY={ö@­Ö¢PAêJÒÕŽ8 Í‚ÔÌ™3ÙµkƒßýîwäççsèÐ!FÍ¡C‡ j$HÝqÇNµ¸9sæ V«™9s&‡"66777ŒF#yyyQZZЧ§'sæÌi”#MsÜ{ï½ 8sçÎ1gάV+«W¯àþûï'44”Q£FqèÐ!|||¸ë®»;v,¿üò ÁÁÁüá ??Ÿèèh:DDD,X°€Ô~ {²xñbÖ®]‹Ùl&::¥RÉܹs:t(F£‘ììlž|òI6mÚÀĉ›¼'Tcb$µŠÙ³g³yóf233yíµ×ðòò"##ƒ˜˜Ž?Ndd¤³æ1qâDÑ’‚NFúòÖ'køþÓ·3î&T WýëØØ‘lØð#f³__ôz=þþ~ÎóþþÒ¤ÎÛo¿OZZÇŽ%0zôH|}}©¬¬â½÷>æž{~ÇŒÓ8rä¸S jHe¥‹ÅUm×ÞÀAFJJ*¥¥eÈd2ÆŒ…ŸŸ+W®B.—&Y®óôô$knîîîÄÄ sîû‰Á´i“”[…ÕÚp0êZnFF¦s³îܹwQ^^Á7߬¦¢BÇСƒ ðÇf³’››GPPZ­–ÈȬ\¹Š¼¼&O¾ùºoK¾¾>Øíf,b\/ÎÑ£ (•amMÆ Aí2(%ûç?ÿéü*îß¿Ÿ¯¿úœšš*”*iÀ P¨ðöîÑ­ôã?’˜˜ˆ§§'=ö˜Sm®³9pàžžžNU¾k«Õ„N—/z•@p™”—WÔ(Üf37bºT “ÉÉͽˆÑht ÷ööjÂ!aû÷$00€ÒÒ2ÊÊ*œåÚSnvvf³¹Pà‹¿¿d0G¯×óå—«yúéÇÛ•÷öí; ïÅ‘#Ç™:u2½{÷t­c« ›UβeÏ2zì$gxuu5~~¾Ì¿.7 Vkµh¨@pƒÓ”ñ%»ÝNiiþX­VRSÓ Á×·yB¡Pa·Û­fŸ?ŸFHp/*J‹ùãò¿2íÖÛœçZ]‘²ÛíÝnÀàÎ;grç3]„…®`ܸÑ]šÿ•¤Ì¢G €¯¯ÏUñ.°ÛmôìÖîtcÇŽfÛ¶ßpsÓ¶[ˆr”ÛPÀiˆF£eæÌö»~ˆ‰Æ‘#'6lh«e\Ïœ>Dnn^‹õk±˜Y¢: ™L†»»G·”m0šXñ\o¨T*d2™ÓIzSmpäÈá„„wj¹ëÖm¢  gžy‚M›¶ V«9z4»ïžÙ¢0Õ^Z¤l6‹Xá‚k µZÅÝwÏìÒ2”Jýû÷ms|“ÜJ¾¢k/Q½FQk¼CS© §6è†zFÅÅ¥¸¹¹5!@iðóóÃjµ‘››Ûd ³¹QQÑ Wvu·ºº†óçÏ‹¶}гg8*• ½¾†ŠŠòF•F£!((”Îô‹¸qcÆ ¥  ÊÊ*JKËxòÉGÈɹÈÖ­;X°àÞ+'H @ÐØdv¬§ÑÙtt§í,3÷ª¼n£ÑÈ—_~Ï’%6gß¾:tŒ™3o%::Šââ¾ûn=þÌ›7¥RÉ?üDZZ>8=B› ´øùù¢Õj°Ûm”––¡×ëÑhÔ¢ñº ³ÙDMþŠ–YUUIee%Z­F<€;îîÜÝC©®64)Pä}Íš  F.¼oV¯ÞÀ¤IÚ¬™±qcf³™òò òòº~!HR@ ¸®¨¨Ð9ýXEGGa0pwwÇÍMKaa¾¾¾‘Ÿ_€ÕjeìØXär9v»£GO0vll=!ÊĦM[8>½Ùò1™Ì¼üò2¾ývþlØð#O=õ(ÅÅ¥¬]ûžžDEE2wî]N³ø´Z->>¾¸¹ITC'È@pý T5,·fee@dä@RSÓ4h}û†ãí-¹*--C«Õrþ|^^žÜL€d8)##“ª*=&“¥R‰¥ÖÒOQQq§»ÛhR2›Ìœ9s^üS§N";;·ÙòJJ¤ ÍîînTW×`0Ñh4ôìÆÅ‹ù¸»»5rd)“ÉèÙ³J¥° J Ü0•‡‡îîn”•I 555œ8‘Hnn7ß<Ž#¨¨ÐqüøId29ãÆÅb·ÛùË_þÁm·MáС£x{7öCاOoúôéÙl®u«äÁÔ©“Y¹rC‡æÎ;oïzAJ­V1*V8ÜAçQ#7‘jËlò\` ¿ó»cµØ±Z:nñÌ™dtºJÜÜ´0|x«Wo`éÒÇj}Æ0eŠä:Âa^¥R6¢$ýýàà®Û»•¿¿o§n~‚««ÕJii9ÅÅ%Àpd2 ……BL&9Óöññ&:ºÎÿa@€?LŸ>•#¢ñöön6•JÅ=÷H>]##9°KîCÙ´œ(™ø ³°Ëš·>WUUEVV¦¤oWw^;|x”ÓñïM7æÒ¥"NŸ>ËCÍgË–mÜ{ïï8q"‘­[w P(œqÍf3÷Ý·ˆÍ›¿wæe0Ø·ï ééøõ×]ÄÄDHRÒ9¾øâ[V®\Á˜1£øùçí—`2™èÕ«'11ÃøùçíTTTrÏ=wãááÁ† q„„9 tØív 9EEÅN•!P ‚ëú;Pk–¼¸¸¹\î|çiµZbb†áîŸäb£¬¬œãÇO¢R©2d ‹àÔÙ*z*H9ÐW8œÛm¦1@p}`µZèÑχŠÊ JjJŒôv,;2™œËuÓµ`Á½¤§gHù*•h4jfϾ­VÃí·ßŠ\.gÔ¨zö ÃjµrÛmSœqW¬ø“K^r¹‚  –.] à4üзo8O=%…ùøx3kÖ .\ÈdÒ¤ñhµf̘FRÒ9||¼èÕK2ñ>}úTòóó©ø©ÕRžÅÅ%àHÁõBII)EE%(Š& ôíNhhˆóX¥R1uêDçûàá‡\U÷¤lùÃg#¬g_úõO_ ¦ªª«±€ÛÝn&«(‡J]>>>PVVŽ-ÜŠŸŸr¹ ëenòòòdĈ:çŒõM,;ö2 á¢2Òž¥áÇ5rT.y9ððpgÀ€þÎcïFñ¢¢"]ŽCB‚ i^MP¥RÕ6Ê(..qª·]IiiyW´ÌššQñ7˜UXXŒB¡ÀÍMÛl<­V‹V[wÞÓÓ£Ñ{54´±¿)™LŽBqùÖMåre»ýG «}@ ¸"È‘êŒÑÛˆÖ¦¡oï¾øøxÒÃ7¤E«x]ÁìÙwv{}„†Ó«WŸfÏF”J% …B4A— “ɰZmÝ¢RªÑhDÛ¾P©TTWû3hPd3mPŽLvyj‘‘ƒ°Û/ßq¹ÕjÅfkßL^§R¹9Ùxûø¶¸é«5*u:ÊËËéÞb¼³I§uí¸֮·+¸žFXžh[q¼'êªmœ;›Ä È!ÈåÒ³ÙLfF:G¶˜®¸¨›ÝNppˆè× ëéBF:¡¡a¸¹»_Óu©R©ñò’ÔÆÕj5^^žíþ€]ë 2¸Åó^^ZÑWáWÐuhµž­Ä°_fþjl6k·Ü[»vóæ]Ìå§75 _·æ»vy§6™Lœ?—ìVŸÇñ£‡[L÷Û¯Û¨©nûrðǼÛéÖž<3/dpæÔ©våÿá»ïðöÊ´O­Ô‘•y¡Mq·þüÙY™W¤q9ê*08˜Ï?ý¨Å¸:]{wïjWþ_}þ)û¿åíJc6›IiÐöšãÈ¡ƒœ’ÇÆM¸ëïON:ÆŒ¿¼î:¼pž Pt:ÉÇÑ®}‡ZŸ7qè`"gN¢[÷4mÞ‚„Ý»¸˜š‚~DZöjv6r¹«ÕB^^.ÉII4lÔˆ^}ú‘rá<ûöТe+ŒEE,ÿ »ÝN‡èŽ´muÓíÝ´þ[ž|ö…`fFÁ!! 2ŒŒ+élß¶€‡Ç<†‡§'ÏÏx…ÙïÆV;qMæèáCÈå2&O{«ÕÊ×ËâèÚ½!¡a|ñÙ§\¹|™ƒ‡2rô#äçåòý¦ >‚€À 6oüŽ‚ülV M›Ýü*芥_a³Ù‰ŠîH»öQ9t€S'O¢u×òø¸‰R]E”£Óé¸r%䤤ZeŠlØPª+ƒÁ¥JEQa!Þ>>7ýîeKâ˜úÄSÒß{÷ì"5%ooFŽC~^ßoÚP£LSŸxºF]]k'€q'£Ñhª•)šV­Û·höïeèð‘<>~"¦ÒR¾Y»€¾ý)µ“››‘‘· L&-Zµ¢s—n‹ŠX‡ÃádÊô'±Ù¬¬Xz­ºÚ€ Αœ”„··7#Còñcäæä•™Éá# âûëÉÏÏ'²a#z÷íGÛvíéѳ7vûõ+-ž^^‹×¯†È匛8™•Ëã?iêM·÷xÒQš7o››ë‚Gã&M2lD™ÅSΟ#$,LúûÔ‰dŽ>„LS¦?ÅÑÇøð?ÿbÈð‘tíÖf-ZÖúžåñq<ûâËÈd2>Ÿ÷1¯¼öÖM·'íb*£ÇžtË@ª¼¼÷ªá7'Ž'Qf21xè0²³²ÈÌÈ`ÍÊL˜ì:ñýjñBf¾úF­uü°i=S¦?…ÝngÁü¹Ø¬V;^ ²7iJÏ^}8éyœnÝ{JAÞ¸‰“]'¨Ë–Ð!:½Þ@ǘμûéÓ kV.§´Ô5ÏJë6í8yâ8E£Ñ|<‰¦Íš“°g7ã&L¢  €5+Wv1•ví;•EÊùs„6hÀ7kV1ã•×8røÇŽfçömL˜<•KiiäKåPÈå·½íj*-E¯7H'ª)Î3dØŠŠ ¹pþßo\_£Lyý¯µÖq­~>www "•©m»(ú „±¨ˆ>ý\}/nÑ?QZïà!Ã1•ºúÌó?%"2’ë¿!/7W @Š iܤ)AAU}¢’ƒ‰ûøxþUÄ'<÷âË :L ÇMœÌóçòþÿ»\LMaÛ–Ù¼á;¦L’6mÛñõ²%Dwì„N§':¦Û·måRÚE"6º«ß†^¯ÇTÕž7c1[Pkn¨WŸ¾|ùÅgtíÖ€ï7m`Êô'q:ìß»‡6íÚÓ¸I3†‡çÍÇÓWVTJŠš+Í·ü.»Ý.[´€~áææFòñ$š›[²gçÆOšBQa!«V,“Ú¾zWRRÌà¡Ã8vä0Gd÷ŽíÒïéxÒQ:uéFë6méÙ»¯”0'2²kW}ÃaG¡P²`þ\}|œÔNã'MeÁ¼OøGì{¤]LeëO? “ɤ»¸!¡a(•J‚ƒƒÙòÃf„G’v1•ÐP©½.˜ÏO?Ë¢Ïçѹ[wòssi׾͚µ 44Œ¢¢BV­XÊÅÔT ƹ3§9t ‘ƒ†°úëåÌ|õ Ž=‘C騩3Z­¶ÖƒÙ …{µß“‡‡%%%õêàc³™ ©ñš¯¯¿8* ‚ ÷o u5;‹¼Ü\úôpÓ÷{ôêC|Ü—ôìÝ—2“‰åKâP(•˜Í•Èd2ƒððð$ ðú³š4%<²á¯*Ìð‘£¹–7×]§G­ÖÐoà vv›FCPpùùy·âÖà`‚‚Cи¹a·Û±Ûí‡ÂÁÄýLœ<ùsç`·ÛÑétÒ•ãÛiÙº5'’“ˆû¥Jɤ)OpöÌ)©®nuœ¸ooU‘œÄtîÊფÀõÚÿýýðòöÆÏßur)í¢´Þ€À@Ìf3‡HÁë€ÁCqTÝåÐjÝi×>ªF™zöî‹B.'(8™LNyyÙM·¯oÿ‡ ×ë±X,X­V©®vïÜþ‹Ú1((ƒÁƒø¸/Q(<:v|­2ÝLÒ±#Ò›V­iN+:PIDATÛv1•€À ´Z­TWAÁxxxTÕŸ³¥õêõz¬V+î:AÁ!ô0Ð`ôî‡ÍæšWM£qcÓ†oññõ•Ê Ð¹kwBÃàp80™J9˜¸];¶KÛ5nâdzõéGPp…JtLg)Ð1›Í|¿q=Á!¡˜Í• ª:1ÿ£ø"—_ð·S—®RÝ 2 ƒÁ½ÁPãÂÉoaü¤)|6÷cl6îîîôîÛÝ;·c±Xp8R;ÜxQå‡M8î,V«…‰S¦K}¯úoÃÓË‹€À@)ðÓéõ i=e&“ôÙkÃý®µSQQ!ùùyôé;€¨ѨÔjHÄ×Ïáææ†ÍfcÍÊ\ÍΠ¢¢NOûÙòÃfþú÷`·Û‰[´€ÊÊJÊÊLD6l„B¡ÀÇÇMÕ:úöPõ{:ÅbG¨Û]X³X9s木Aáw•›—G`@د¤r®f³}ÛÆN˜,åsu2}Õ‰Jq±‘c8‘|™LÆ€ACPk4Ìûø#zõéG»¨\J»ÈÙ3§1òá[~³æ-8î,Íš· E«V|³f‡ƒŠ ×3~~5¯fZ,f>þp6*µwww \IOgþÜ9X-N±ÑÈü¹s0WVÁP;a†N¯—–©¬¬àDr’ë™0™Œ2“é–ÛûШ‡¥ayyyäç£70WVb6WÒ¥[陀kÁX|Ü—<°Ÿ„Ý;éÙ»/Ý{öBë®C.“Ñà`¬ óçÎqÔ©T<óüKxzy“vñ"ŸÎù!âs×î0dØJJŠùqó&öíÝÃá‰DEwÄÇǷƶLÜ_­L¥¨”JÊÊʘ?w».Ýzàéé媫//oB4¨Uf?æÏƒÍj­qGª°°ß[Ož6íÉgX²x!Óž|“ÉDÆ•tôV‹…òò²ZeX»jìgëß3hèp×¹ª![‡ ãÐý,^ø92™ ›ÍÊÌWßD­VSRR̼O>¢gï¾têÚ•¬ÌL†FÃŽŸ·ráü9Μ:ÉäiOàåí]c[›·lÅwëÖ P*±Z,<÷ÒÌZå1è œ÷0!NDD$ ¢VkˆŠîˆ¿gÏœbçŽmääd3óµ·®§½aµñq_ÞvXW‡Ž1|òÑûôະpùR?lÞˆ¯/¯¾ù6ÞÞ>,ýÊÕ÷öìÚA¯>ý8uòDÕoÙ‰Ñè¦y-àV)•<óÂŒZßóøø‰Ìýï ƒG{Ëí $/7ÿ€@N&'»Ê%“a*-A©PÒ¥[ôîZwºvëAiI +–~EfÆWÝÒ¼e+Ü´ZBÃÂhب1þÒo#"2’#¦E«Ö¬]ý5»ƒç^z™³§O‘¸šO?á¥W^#ªC´´Ì­žó¼ÕÝ·˜Î](6¥€Lo0`µZ¨¨(çø±£”––ð—×ÿÊÜÿ~À‹3_¥¢¢ƒ‡Vëõᔞž^4mÖœ‹UCܾ]·š”” ˜++¥úÛúÓµ‚êü¼\ü«íïæò_^œùêu`S©Ô´lÙZáA„ß•Byá–ïÉ>øàé”,!!¥ñqTT˜Pªì””–ST¦–†Å\»ÚcºÊÇ“ Ã×׫Õй*8ÐéõÈd2L¦Rpº¨kšÍfl6+:+“‡ÃáÀápHÚÍØl6÷%гw_Μ:‰¯/^ÞÞ|üáû¼õNí¤‹§Ó‰ÕbAãæ†J¥¢²²›ÕŠ\!ÇÝ]‡Ýn§¢¼…RB¡D.—#—ËËØlVärv»se%*µ™L†Z­¾i™näp8HؽSº TQQÝfC¡T Õºc³Ù¨¬²ã®Ó!—Ë)++Ãép R«Ñh4X,,f3È@¯w˜_ Þ®•  ²²‡Ã^£LZww ååå8ìvÔ5J¥JÊøVÝe2›ÍX-dr:+£VyYr…¥RåêN' ¥RêN§“ÊŠ ”*%r¹Â5ü1éaáᵂ·êœN'»wn—îtÞªnV&¥J‰››öõ½kepÓjQ*•R;©5jŠ›§¾Y;][¿ÅbA¥RQf2!“ÉP©Õ¨”Jlv;*•Jê뇣Æ2jµú®Ê”¸/QQÑRD‹ÙÌ‘ÃéÖ£×mwSSP*•„GDÞ[ßéâȵþW½ïÝÈ5 ͉Vë~Ëm±Z­LÜG^}ªúž œÎ;ö½›µÓí~O®¶2UMÊêV«L7þž”J%6›­F;ݸO²Ûl “¡P(°ÙlÈåòjû•+•+ T©ÉdRÛ^+“Z£®štÖY£ýÏœ:IVV½z÷“ʰ{çvzöî+•§úþöšÛ·Ñ·ÿÀ:} 2™JqšsÐiU\¾|£±½¾ædï¾¾x{ë±ÛÀa—3sæ b:_ï×åååx{{1îñGÐh5Øíåâ/‚ ü®ÎŸO!0 ŒâÂ|Þ™õOúW)sOT]rí™!Si)/¼üÊMï$ ‚ ÔÙYY˜L¥·LS߉@JA¸ß©{~F*ãJ:{÷ìbÜÄ)\8Žo×®æ©ç^¨q…´ºý{Hؽ“7ÿö?7}ÿûë9y•&<0(ˆiO>CfÆ–ÇEdÆŒ0™” çùfÍ*ž~þE232¤‡ë?›û1¯¼þšª‡é÷%ì¦{ÏÞX,fæ|0p ‹lÔˆóæJß;æ±±¸ëô,[²€‰S¦Vm¸ÚµõÌŸ;Si)3_{77-‰ûسkoþÍu'lÇÏ[9t ½^Ï‹3_åûM8™ìJÄàá#XZõ¼ À¤©O°}ëOdg»foÕ¦ z„ä¤cä\ÍfÐ]\²]T>³½ûJÿAî77ÇÛ»æH‚œœQ1‚ B½!¿×Ò/_&<"pMêÙ¸IS¼½½¥dÕØ¿Î]»#“ÉîøàýžÝ;éÕ§ÙÙ™X,f¿Ë×Ëâq8¼ñöߥÌWO=û" ¥‚EŸÏç“Þçý÷b1WV²wÏ.är™té·ÿŽÓéäÇï71døHé{òòr14iÖœ7Þþ;‡ƒ•Ëã™8e:‡ø¸EŒzxŒt‡Íh4·ˆÙïÆVedÛO—êe’N'••ì©6©laAÏ?5N]»I¯]¾”†R©"4,ŒË—.2çÃÙ|òÑûl¨6¡ªÖÝ]J !‚p?r8ìX­5þËÌÌ#‚ Ôʺ²!ùy¹Ѥi3Ž>HÎÕlþ6ëÿ±sû6<@tL'–-YÌè1áíãÃøª¡…ŸÏû³Å̧s>¤CÇNR‚‡.ݺ³åÇÍ„„„Ò®Ú\O{vº²’ëY«µ«VЫO?BÃÂøyëOœH>NÎÕ«$ìÞÉ3/¼Ä¹³§ùtÁbôz=³ß½ž9­Š»»Žö:òÅgŸÒ²U)òñõå›M?1ûÝXZµn¸îè]{(|ÞqÒ:ªO,+‚p¿+**âÂ…œ¯)šßdÝ6›íž2fÖùµR)M"-‚ Ôã@ªQã&\LM¡Qã&´hÙŠC‰ˆhHII ¾~µŸ‘êݯ?»wn'¦S´î×Ó o\ÿ AtéÖpe¦º–ÝN©PÒ>*cQ•••xxxòåŸ1`Ðråee¤¦¦àíí^oÀa·#“ÉøzÝiý]»÷àÇÍѺ눤¸¸OOOòóó0Vl+–.!*:½Þ€ÉTÊ€AC¤4íÞÞ>´iÛ›Õб¨FC¯¾ýؽk1»H)“c:w¦m»öìMØELç®$ìÞI›¶í«N\Ãö._º„R©$4ÌõÖ®?Ó>Ê5?MõÌåeeèÜu¢w ‚pß2 ðòª™ZÞ×7à7Ywbâ!¼¼¼î‹z’Éä4l»»›è4‚ õ=êÙ»{÷ì¢Qã&DD6Äét²zårÆŽŸ„§gíW‡èŽ=ÌÚÕ_óò_Þ¨vÀôÃàq}||dÃÆ4® nÚwˆ&+3ƒÕ+—Ö€è˜N\¾œÆöm[hÚ¬9ý bÅÒ¯0™LDEÇÔÈÚ7pðPWäãÃñ¤cœ;{NϤ©ÓQ©Tôé}2aöïM`? „5gøC£j­gäèGX½r9ÏÏxFã*Óª¯yùUW™Ž;Jòñ$zöîK«Öm())fåò¥<:v<nnzöîW­Ì¤õNú9’“ŽÝQJm-‚ ÜNGÛ¶mP)ëwða±˜‘+@&“a·[ëP\\¯ïÙív<< ·nåÏP^^ŽÕj«×}V.—c0èëÜÅ•²~ŸSY¬VÀR÷‚¥¹L^oëÕáp`µU"“ýò õ6ý¹ ‚PܘþÜd*«uÂåå凧§öW§??v,™Žc0tÈåõwˆßî݉´oߦÎRå儆×Ûz½t)OϺ5mŠÑXLÆõúw¾oßAZ¶lVÇ)ƒ EýÝ$$¤uëfun»´ZÜÜêo •““ÇÕ«¹„‡‡Þös¿iúsAAøµÂÂ"ðõ­9ŠáêU‘µOA¨?ä¢ A„?Z^^6››ÍŒÍf&;;³ÎÜ=r8—ÜÓ2™™Yäää>píXTd”þm4oûY‹ÅBYÙÍï"fdda±ÔºTRRŠÝn¿ëm±Zm¤¦¦a2•=Pm™™Ejj©©iX­V±sù…L¦2©m¶»bi³Ù)-5‰ ü•ûêÿ®®¢¢’ÔÔ4Ìf³¤A ¬Ì„Årýd%?¿PšðÏ¢Ö­ÛÀÊ•ë0‹ïz¹'NóŸÿÌyàÚñÓO¿N&çÏ_|ÛÏž={mÛvÔz=)é7þÀòåk¤×Š‹KX¹rëÖm¸ë`Êl6óí·›Ø¼yËÕ±±ï“˜x˜ÄÄìX±ö¯'''}û>°û¤/¿Œ—êqÛ¶wµŒÝngݺõ¬\¹Ž’’R±cÿ…ûÿ]]qq _|ñÇŸ¬“eCûA„?EQQþäåå¡T*êÄ6­YóQQ툌lÀÇΓONæÛo7qõj<ñÄ$6løòòrrrr6l11:t ‡•Ö³nÝ}t[¶l§[·Îuîüß³þl6))éÔ)šú°bÅÒÓ3ðöö¢AƒP’’’Ù¸ñG†LYY9aa¡¤¦¦IëY¸p /½ô4™™Ù¬^ý-z½ŽŠŠJλ@ëÖ-1b‹/#??77 O?= oo/FŽFRÒ RSÓ(-5ÕVjû‘‡‡¨(×+Û¶íÂh,æË/ã)/¯ qㆌ7†M›~$9ù ãùçŸÀb±²x±+!V§NÑtëÖ™ÿû#22²8qâÏ=÷Ä·?*))å•W^þ.,,báÂ%X,š5kÂØ±ÔJ²²jÕ7téCPP ,fܸ1dddÑ¥K .¤RQQ‰‡‡¥KW0zô*** !44ä¾î—wÃf³qêÔŒÆÌf3Ë–­&++o¦M›HPPýû÷––ILƒŸÞE‡íÈÌÌâܹλ€N§càÀ¾Œû±±³:tG&±pá'\½šÃÚµëyæ™i5¶¥°°ˆ‚‚B ­Ô÷#“©ŒõëÀjµðÚk3øæ›´nÝ’  @V®\Çðáƒ8qâ4#G   ˆU«Ö1zôââ–3tè@fÌx–3qâãô¾jîÜ/pw×b±Xxê©)øùùòïÿ«Õ†Z­ªñÙsç.ЪU JKMdddQ\\Ê•+™¤§gРA¥¥¥4j)Õý×_¯¥cÇ(<< „†r_÷Ë» ¤ìÒD¤„””4Š‹‹9rÉɧHL<ÄÀ}k,såJ&z½ŽY³ÞbÑ¢xrsó ª›”»Vƒ­si¦8 A~1à¦u„h4jÂÂÂ1 ˜Í7nŠ\.G­Öî3‡“ôôŒªT×s7fwS«Õhµw—Z=;ûêÕÎJ¥’&MÝô=OO*++k½ž°ŸY³ÞäàÁ#øûûáããÉT&µƒÝî¸i;ÜmÖ½ÒRÓ}ý Kpp ï¼óß}·YÊH˜™™Åb¥{÷.èt:úôéAzzN§‹ÅR£Ÿ1¸Æú***0›-µæy{P¼üò³ÄÆÎÆÏÏ÷ŽŸµÛÕöeRý¥¥]ÆÃÀ\.gÉ’4hFqqIáÂ…˜ÍdnnÆŒ Ý™ÊË+ ==//OÚ·osË}IÙçÝ~‡¨À×[L +‚ üv‚‚«%ÕïDYp:þ¼9Š""0j”ëêq~¾+‹`FF±±³ÑjµL™2Ž„„DââVPRRB]X´(ž””‹ÒPV­Z;û¾O@Þ€ØØÙ€Œ‰c×®½Ò{¡¡!úSZj"6v6z½žŽ£èÝ»{Õ2УGWÚ¶mE|üJºvíD~~>……EtëÖ¹F;²eËvòòò s¥*.,,"6v6*•ŠI“ÆRTd$.n%%¥´oßšfÍšðÕW+8sæü}„!44€‡ÁâÅË2¤¿4<ªS§hT*ii—¹|ù '>NëÖ-Y·n=à^y- +*22oÞ"¦L÷Àí—Úµk#õË#†àççÃÂ…K°ÙlÞtøq£F‘5úixxû÷dÂ„ÇØ½{£GG&“±ÿA<==hÞ¼ ={veéÒUètî8ŽúXp­ï^ûwDD!!Á?~‚°°üýýHK»ÌæÍ[P©”„‡‡pàÀaöãç狯¯÷ŸZ†ÛÎ#U\\BEE¥8ê ‚ ¿šF£ÆÛÛ뎟sØeuf©ôô+ìØ‘À´i¤×bcgKCÓneíÚõpàÀažyfÚ/º‚*摺îý÷?aÆŒg¥;ååå|öÙb^}Æ-—ÉʺʡCGñññæØ±ãÌœù< æ‘ú=‰y¤îìÌ™s¤§gàîîÎéÓgïêy41ÔukÖ|GÛ¶­iÑ¢é¯^×ï>ÔéÓçP©®ÄÍM‹Ng ²²ÿ@œÎ;’Aj²Ûíäççáç@AAngl#"Ö»ò0dHÿ¯M™2þŽËõìÙ•3gÎ3jÔ°:wÂ^7F]-(wcìØGn»LHH †SPPÄÔ©D% uBË–Í)-5QVV^ãpwúôé‰^ï^g¶ç¶”B!ÇÛÛ 77-^^^¸»»‘““ƒÙ,# À‡Ã&ZTA”””b6› $(ȇòòJŒÆ"***ðññœõªaw¤4 FÔ˜ ‚P§9ì"›ˆŠA~WáMP«Ôß)A„º,7'‹+éEE‚ ¨’â"H ‚ õ“J¥"!á‡'‰ÊAþp¡¡¡"Aêg 5xðQ‚ B𿵃³›ëœwôIEND®B`‚snd-16.1/pix/s65536.png0000644000076400007640000001017311362374226012524 0ustar bilbil‰PNG  IHDR¨º,Õ÷rsRGB®Îé pHYs  šœtIMEÙ 6zЬ IDATxÚíÝÛ¶ò(Puì÷eûÂþVÔ˜Ã0çUwUmM‡/HÈõ~¿_`t7E€à ‚/ |¯×ëÞO¿þ£ hë¯hê}>9÷ú¿ ¾M3¾bëâOî÷»y_R_“µ à÷R‡¢©÷ç4°Ì @¥à[ÔJ®µ4€@¶3@ðÁ÷Õûf½‹mTõSÓ_à‹¡Åþ>¨Ï¸jÎê5Šjkù† ¾ž«Ð¹£b0Ò¥Ws´bÆ»Äõ76ã{ðÚL»Ík9”núVoƒU'Cu>\MSÇ:=µIª®à;]#|t÷ßþP—Mw· 5[Vþ’ü‡—gâÀoƒR)ßšä¨å)øöZ#õ#SuÐv¹I½gêsæKPçf`†ÎGîwt¨p<©NYE|eÖ^ËgûÎJ’“™Æˆ2ð ›dIbÛ‚:ykwìÏ'¿[hr4|À­°iUx ßú­d©ÞA?d³æ¤&œ™ò\ßul”þ®IX—º>Ö†ÃôyGµèÑC&¿dQÇfÆ×XÕëyλԿã unDÍúo/ù¶K¤\©äý­Hš§ë>|3_s­×Háç–ªõ¾ ßYïýëœcý€•mÖá|ÉDüx{ï¯?(Þe‡g©n?f‹/Q—ìpuªÜi _=’?Ezréˆû„ð–Rª‰‚ïý¿Œ iÏnûØsx” L9?j€J¢Ÿ•ƒGá:­'Ç^™9sÝ;¶7Qµ¯þùk¡k×Ý€uòJôÞ½þ¬c´´ÊWêÌ҈䓾ϒ´[íTÙºU_u “$†™t.õ#¾!`Æà;mUȶÓÊÆ!y×àwx¤|üŒ0v5ÿ©„^®»p9§G7x‰ Õ–KQÏg“µgmê0KðMUE•>I/Sg$Ž=*c9FŽaî¢Gý¥âµše{¨cñ_ƶˆ÷O«ó¢™ÁnóJœ‹;áþ‚oþ=[U©×]Þ†©Ý5Ñc+ÿZ×µExeÔ¡§\sx?1è[)ìaŽ_¶ÅÝrØçýÌüªíÌjßJöõPðÏãù6m0@")½w€òÉp"&0/¨=_G½KÜuj?kBTÛï¢3l»3Òú·gh5±Çøi+Ÿ#øÖèàb¯å·žâç³ÆúýTÕ&ÉHŸçå,^´Ûщ¸ßè%N¹RÃ4á-·¦!÷ÏO8YyÒ–¤à[ªÙô8±7ÉoÇ‹ÓÌvÖ5ƒfø:<£¬&¼·†8æ“u¬÷Žn†&–°'±¶j·aÚƒáv}h麗iPí¨÷ºÅÕcgÞp¤cø¸qìÉ’_üyø>ú*Fì·lY`ò(E†¡mÂ@?ûŒoÔž#{oO×79ÿø¯6~ÅëÃäøÙBaT]*÷Õ¯_º±f¾5ºÂlPì‹ý¶\£×çSOÞ»n9ø¶Áñµòì­½u¶ ÈŸ¿•ê½·ü¤óþTFwGò_™bíÌ“gŒ|·ÇÁI~¬š<*÷³gùJ¶òÏOζî¢Úñ¬”Þ™g{+OCžùº$Ë©¿EwSŸéèJ÷r2Ç™;œOH÷r^­{™ ð/jÆ·N‰¿þò~¾êŸù„®CÒÇÿx¶‡Ê·Ï•ÿ2Âñ›¶?öÂÛxïϵ /nì»îzéi½…±ùåhÕëÖy©Ó UñÛa{¸mÌ!ùg‹M8S>óëÎKüÖ|8ù¶ßœÙÊ…‹zžº\@?_÷¶¬úØUIzyê#pkª×4Öù…°r{:òðÃ>P«cÂ>ö ÛkÚö_J›‚odÃ.q9ÏæÆŠ;Ã6LúÄc[TÀ‰Za¬õ³{ªó=¹7íbAí0¿ÔõÛŸû«×‰†Ò·—÷¼7äüYï]‚µÒÊnÍKá›Ì=i‰n«í)?ßùžp"$maö’ªmš¿{ÝøÔ×ùs)nÔí„SÕêIx½ê"‚xÖ<¶$×(·ì.é·~+‘èN~à­yÇñMÎ{è3_tr»†1&]f˜ó(7¾ 3Õ×íz1óX^­gxßb|ñkÕ0:‹Ò½Vòßû0Fó5Ö£Þ1º‰jY{·Ÿq©CÂaMÖî ÐTVvç©üÕMÞê~` «YK§ÿ =ÉÇò_¿uË®}@«ýBz¿íK÷Þæ¯ÿ†àBIÃÃ~>¾u}Çø¦ÊOögþ|ðà¸/OwÝ_x} Ÿê®P’–Ó]vnýXn1À`[ žßÎ¥èu¦kŠ Ö½TÂVO2•.ÌÀÍþŸÄ=¶[_¡«µ üØ­ûìÔÁ÷@?òëôYÔj½pì3§QÛÃ5œÉ¨Ÿ6vÅYÍíÞÞi²Ã¿åÍ>m7zïh„zý¿ï…V¹$àËÔýETˆ}æ¯Üû®ÞoJ2·½³JµÁ •ä™ê=É;AÛ[¶¥ßû¨ë$-wýÇœš…p`÷’oK.Ï·¸Ûðm&öz„ìÞª£,ºáy§c^Ú(Öör')½›.:ŒVËšåªÆØ7T?WÁeÑš]ì’ý:%¿kùÓùÿ`×)ol†f|!Åp˜§/úB–½9oãâ°jé0ðÑÏçºÆÀBŽý¨×õy=Þû]Ò,¬ y*qךþ´¥}ìw§j§Sè7ó£ ÇÜ[þsˆª.ë{Pü·Çzüú“4'»Þ·>HþÄw§ëîúWybZ]ežü¹ D Jw¹9klå÷"…_iº’)š“’?Ü“-MûÞ“ÇVtߢr­¸h¥-=J½¿Ò"[Å‹ª·Û§$/û·/é›þìŒöö]Mv0¥߯%XôEÛ·µê}N%O»5 ‘íÒ¨‹w‰nžÕæ!j†¡/ȘvEéTyÎWÑö{Jüö‡)'É—?¯B«Û3¾¹¹±{ÿ¨~gqEr>”ù¨ŽÕçB;Fiûcd¸ísÆ}ñÞŒ˜¿>„tw匭ä+Ýר‹‘~þùMEéë€[½+aÂ[”†¯DNXÙJŒd[vî¸9_ê.¼)º_Û–W4ëÉûº‹ µ¦ÈÓÑÝ&9O¬_éZŸ LÇp Ùy§\Î{¿!<³^B7¢/­Ð»º‚ThCô'·ÏÿKuG;yw<ùƒwFn0ªZ¡÷^ö~‡|=G?è z»_š¨h‘9¢l?¶D3¾÷ÿÚÕ_ öäéÀCiì÷ö20«l©rÀö—9§rÚ¶¾ú•¹í{ÂC®Zï=€ŽK'<Ôóà6X¥q3Ý{ýÞûu'[QaÆ®xy¶¶u-NÀ±Ù:G~ø] Õ+¿FöÕK”¸Ùf¸¼MU“’Ü£tWÉÆîïg§GÛA:¤rKïîw¡ØçLß‚ý‹W å¿pQS}]ßžs{Ýõ»:…˜yJÒµV†£öÛÃ_—½Ån_bêÜMk×ï•ã½+Á0lÔ‘zf¬yü÷ë2Ïö”I>'C߯»x#ÕãÒ¡§ÓÌz~_-#bžsl;%l7ÌÓèÜá(½‹_•ЖGRùf¾Â˱RMO|;˜¨ç’ˬfkú@ðåk_ÐãpÔ¶¯:G™Õð9äh˜n|yt8‡yÐT+±û]vºÁœûṂ¯ªéЍЦ¾ÆoT0\D…Yî¤T’W¹Çb©ù0´JÒŇ[ê€V—ô­¡„Ž‚x‰¯é¶ìꕤ`EOͰ‚›¢5f ÿò´É-õ œDÁw‘Šä`ÜÛOuŽ6¢t™ßT,PÕAåTθX3œµ‡ÛTbT?嬜³\ˆg¹”$èN_#`j‚ïú—¾èw@°À_ ‚/R/€à ‚/¾ øždY-€N|@ð€h&€Á©`·¿<‡rþíÐAð]ÜÜËÁ²ÔÁ_| —?E³1<™ñ@ðÁ_|@ðÁ_ø.Ñ ,®×«ëÀøÁwñj9€@–: ø€à ‚/¾ ø€à ‚/¾¾[x•Úõ @[[_Y|,õ>ßBüú¿ ¾M3¾bëâOî÷»y_R_“µ à÷R‡¢©÷ç4°yböú˜`ÿVòe…‰Þ•¯yôW-ãfâŸÎ/Ïhþ NÁ)8§àœ‚Sp N!öÏíã Àb‚ïûf½‹mjÔ(y×®]¥ôéçéé)¥%‚J‰‹‹cÖ¬Y˜™™aoo/ÉuYŸ¬¬,²²²PWW§k×®’|ýúuš5k†½½=†††\¿~]ºgéÒ¥Èd2®x "”F.—KÝmUr]Ô§sçÎtîÜ™‰'räÈI® ŔŰaÃøå—_„.ýû÷§ÿþ¬ZµJ’-ZDzz:ÞÞÞÒøD1æØ²e [¶l!--°°°ŠéA}çðáÃ>|˜o¾ù___† Ƹqã055åðáÃ$$$Há–––XZZЬY3Ο?_¿ZÜÜ\rssÅ›hjjÒ¶mÛ åº¤ORRIIIÒ˜ÃÊÊ +++IHMMeݺu1uêTâââÐÐÐ`ûöí4iÒD)¿zтޮ]»$966–~øA”|=cß¾}œ;wSSS|||X·n´út„ ôéÓ‡;wîàïï/ÝX㺜;wŽ}ûö(é£J_Ře„ JúùúúbbbRizb¢PðR¢¢¢˜?>›7ofÕªURûî»ïpqqAKKKgeeqçÎ\\\8yòd­èsýúu´´´pqqá»ï¾«Pß=zУGæÏŸOTTÇgóæÍlÞ¼™áÇsëÖ-¦M›&¥Wúù„^Ê7ˆ'--ââbòóóINNÆÛÛ›¸¸8077W’ß}÷]ÐÖÖÆÁÁ¡Fõ‰‹‹ÃÛÛsss$¹l·þþýûØØØ`cc#ÉS¦LáÒ¥KãîîN||¼ô<Šôòkëb ê7*ç=JJJ(½ç B~öì™R¼²òßE.—SRRR¡\áááäääMrr2ÇócAÃaýúõ˜˜˜ðé§ŸªìÚÔppp`ýúõåÂþüóOŽ;Æ™3g˜0a‚Òó”öî"¨þþþ¬^½š³gÏòÞ{ïÕi±²²",,ŒÌÌL1b#FŒÀÐЀ€ŠŠŠØ·oß~û-$''ãîîNçΕ&…*¥¨¨ˆ 6ðüùsΜ9ƒššwïÞÅÈÈMMM)žBîСƒÒýeå¿‹¦¦&FFF*å””)OMMMæÎK÷îÝ9xð êêê888P\\Ltt4$%%/ü¯‚‚‚HJJ¢¨¨ a ‚ªQzYõªU«€>q!!!üðć‡sáÂV¬X¥¥%û÷ïÇÇÇGêïËd²ÕÇÒÒ’+VpáÂ455%þÿLù·ß~‹——FFFØÚÚ¢®®À!CXµj“'O– )''RRR˜4i’’q¼”®Y[[°`Á²²²xï½÷¤¯U&&&Œ9’ÜÜ\æÏŸ_kcŒ¢¢"rssY°`t]ñ÷Ó§O9r$...Já+W®D___’]\\øóÏ?yï½÷øüóϱ²²*—W£×}üAll,vvv„„„TÙ;W±OW]ðæµ³³«ñÿu1"^=Ù¸q#Ÿþ¹xË“_~ù…ýû÷Kc E™nܸ‘;wîHäÞ½{sçÎ%çÔÿùŸÿymú¼Š¾ öïßOïÞ½111y{ZÒ› ^ …¯’ššÎÎάX±‚õë׳~ýzV¬X³³3jjjL›6[·n1räHRRRpvvæØ±cxxx¼}^Uß[·nѯ_?æÍ›'-Ë}­-È7˜2eŠ$Öë såÊæÎ[+^ªu‘’’ÆÇÊ•+QSSc×®]\»vÌÌLŽ?NŸ>}èÝ»7¹¹¹äççpàÀ444¸zõjoPžŸŸOß¾}Y³f jjj?~\i’êêÛ½{wŽ?ÎܹsßÌÄ™L&ýÂÃÃëu…ù믿jÜ¿¨.ÓµkWüüüˆeïÞ½üú믬\¹€¦M›¾ø_VM 5µÿ×¾óÎ;Ò\‚"¼ÆÇ¥ò+›Geúž>}x±qCjjª¤¯–––”^½ƒ8p€?þøî¨ñ6“——GVVzzzõRßqãÆáêêJnn.×®]ÃÀÀ Ju©ÞÈ©S§¸ÿ¾07ÄàÁƒðât´Šô½téäìÙ³¬X±BòÏÊÍÍ%""‚Û·osüøqŽ?^?»X‚7ƒ™™Û¶mãÔ©Sdff²iÓ&&Mš$ 333±´´ä³Ï>ÃÌÌŒo¾ù†½{÷’™™Éœ9sj|ª2}þë¿þ«Âð“'OªÔçùóçdffâä䍨T¤>œ¢8¿A&“½ñ³<(s~„ a#ºXÁÛ<9qâ„xË‚W¦ÁA–.]ÊG}$Þt  ­óà?þ`ìØ±¼ÿþûüñÇJëGjã“ð… ¤ ÍÛ¶m«rÝÉÁƒ¹páB¹ð… JÏŸ?_iÚ ô³‰¯X‚j3sæLöìÙ¼pü[¾|9NNNÈår¦OŸNbb"£GæÖ­[899ñÃ?0sæÌÕ!11‘éÓ§#—ËqrrbùòåJΑÑÑÑÌ›7N:• ß°a6l@.—£««+]W<Ï[ׂj†¬¬,iExáM¿~ýèÓ§¹¹¹äååQRRÂhÚ´)qqqÒIO5E^^½{÷fÍš5hhhÍÞ½{•âܽ{WWW¦L™‚………Þ¿d2ººº˜ššJ.1?&55U¥ ‘hA/%99™‰'²zõj¥ëÍš5^LÆ)*[ãÆ%ÿ(ExMS:?Uy˜››³oß>¾þúkèÙ³',Y²„™3gJnï¹¹¹,\¸P:lGˆ Úüûßÿ¦E‹õÆÍG[[[ryÿïÿþoÉkÞ¼y„……Ñ¢E fÏžÍüÁï¿ÿεk×èÕ«×›¤'&&*Ó›——'j\="11‘ÄÄD6mÚT%ߥºÀ¯¿þʻヒ§§'Í›7çÇd̘1Ò²‹M›6áåå%<°{÷î OÁ­u177çСC’|õêÕr›ê.Ïž=“v"„ë{üüü€;¥ÛÚÚòäÉž>>¤¦¦2räH¬¬¬¸yó¦Ò³•]¯$¾b ªÅgŸ}€‡‡Mš4!--Ž;âííM‡ #,,Œ´´4¼¼¼jüLÃ:°}ûvNœ8AZZL:UI·Aƒ±eË~ýõ×ráiiitëÖAƒUølJ4t_¬šöÇBøb _,@ða A%ˆ1ˆ J:tˆK—.`oo³³3dddàì쌽½=J;¾üë_ÿªq].]º$}566®pGxqFbéðŒŒ .^¼ˆ³³s•Ò-ˆ Jœ8q‚µk×rèÐ!,,,`Ù²e <˜§OŸ2}út’’’pvvæ·ß~cðàÁ:tˆÙ³gרIIILŸ>§OŸ2xð`–-[Vnsm³gÏf÷îÝJ²³³s9ï«W¯²víZÖ®][nÂP´ ‚—²{÷nŒ‘ÉdtêÔ 8|ø0¤oß¾<|ø'OžðìÙ3öïß––2™Œ>ø Fuyòä öööüë_ÿ¢I“&>|X:¡¶4<Î )ÝšÅÆÆ*Å¿zõ*?ÿü32™ ccc¥yÑ‚ªÄÓ§O9räC† áòåËÒuàÅ4Mš4^Ì{iii)…×4¥óS•GJJ ...Ò„fi}ËÆÿóÏ?9þ<ãÇWÚ€N´ ‚*£Ø¤áêÕ«Lž<™   :­ï©S§hÞ¼9ÆÆÆ/kllÌ–-[˜1cZZZÌ™3Gˆ êtëÖMú·°°°ÜÎu‰¤¤$’’’Ø´iS¹î’*Z·n-í¼‰···’ˆ.–à¥äååIN¦;vÄÀÀx±î¢lø³gϤAᵩOé<îÞ½+A8jÔ(ììì”|ÇTQZ_¥ó_K òðáCbbb”ú‡‚úÅ·ß~K\\C† áâÅ‹øûû´iÓØ¶m'OžäÖ­[èééѪU+\\\$7“1cÆÔ¨.zzzܺu † ‚‡‡kÖ¬`ĈÈd2nܸ!ÅWøŽÄÄÄËï¿ÿNdd$|ð))),^¼///Nœ8Á‘#G^¯<}ú”ÄÄDIV|7Ô¯1HNN‰‰‰øûûàåå…††‰‰‰´k׎™3gÒ¡CöîÝË®]»HLLdÆŒ,^¼¸FuéС;vìàØ±c$&&²aÃi—DooïrñK_KKK£¤¤„’˜˜HŸ>}066–dÅ!¥J_,á‹%¾XÁ+! D ¨ñ™WP-–.]JÏž=5jAAAÒ˜rÔ¨QôìÙ“ŒŒ ¥y’ʾ ½*—/_æðáÃÀ‹yŒ²î,¥ÃU寘쬊¾¢T™¹sçràÀ:uêĦM›X¼x1}ûö%??WWW’’’7nW®\¡oß¾8p RGÂW!)) WWWé(¶Å‹³iÓ&•áªòW„_¹rà¥ú ¼”üü|/^Ìĉ¹xñ"]»våúõëDFF2tèPÖ®]+­M/,,dÿþý :”‹/òË/¿Ô¨.Ož<ÁÖÖ–µk×2tèP"##•–3dÈÖ®]«2ÿÔÔTîÝ»'É:::’¾QQQüþû%¨<~ü˜ÌÌLŠ‹‹8p €´NÓ¦M•Î+Tì;P[ǵ•ίlÖÖÖÒÑÓeãôéÓ,^¼Xš78~ü8©©©œ³fÍ"::šääd ‘–ÿ*Z ˆ††F…ú Tй¹9;vìàèÑ£\»vuëÖ1cÆ ÔÕÕ¹vímÚ´aÇŽ˜››ÁöíÛ¹víÓ¦MãË/¿|múÌœ9###ɧêÚµkÀ 'ÆÒØÙÙ)}€¨T_á‹%|±Së-ȳgÏÈÊÊ’äÒ¿-µw€ ö¨u¹sçŽÒÑ»?~ë Yq€‹§§§¨qÂ@Ê÷K7Uê ê6wïÞ%$$Déš­­-#FŒ $$DZÑ÷É'Ÿ`ggW.þÊ•+kE¯#GŽúŠðÒú¬X±BŠãåå…‘‘2™Œ~ø###¼¼¼¤8b¢PP)÷îÝcÕªUJ¿£G°mÛ6ìííÉÍÍ%..NŠéÒ%ìí퉈ˆ¨q}nß¾ÍðáÙ;w®êNÿÇÑ£GÑ××G___ÒW1(···çÒ¥K’ËI\\¹¹¹ØÛÛ³mÛ6¥t„*E]]9sæpïÞ=îÝ»‡ºº:-Z´À××—øøxœœœ°¶¶–ä>úSSSœœœÐÕÕ­ñ†ÛµkÇöíÛéׯ_…qöìÙÞ={pttÄÑÑQ’?úè#tuuqrrÂÔÔ”>úˆøøx|}}±¶¶ÆÉÉI’…ª„ ´nÝšÄÄDlllX»v-?æùóçJcËçÏŸK ((+ׄÁ¶nÝZÚ{K………–“Uéöüùs¥qqYYˆ Ê|þùço݇a ‚j! D P¯¯¯ÒTººº¨««—“[¶l©t_Y¹6yðà<@KKK© ¦U馮®®tD`YY¸š^Jzz:×®]“>…øûûCtt4ñññøûûcccÃñãÇY¶lÑÑÑ<~ü™LV£º<~ü˜Ÿþ™ôôt¢££155ÅÆÆFÚ!Q&“ñóÏ?óóÏ?0yòdéשS'¢££IOOçøñãØØØàïïO||<ÑÑÑ’, DPe²³³éÕ«mÚ´)×Ý’Éd´lÙ[[[Ú´iC¯^½ÉdÒé±5IAA2™Œ^½zIùÈårlll”ºÇ—æA†.]Ÿ4i’t¿âylmm¹{÷.2™¬|RøbÕ¾/VHHHµžW öÅzëX´hñññ¢ Ä ] ŠG)ÍêoíäèÑ£ôèÑ£\¿ZPqyÅÆÆÒ¦M<<<€®& wáÇӣGîÝ»§ä®±|ùò×%..NÚ\¡´>Õ ª¤ï[Û‚9r¤Ö¶çohœ8qooo´µµñõõ%((ˆ   |}}éÖ­÷ïßÇÍÍääd\\\8þ<ݺu#,,Œ Ô¨.ÉÉɸ¹¹qÿþ}ºuë&éSÝpÅ×µ—é[ë-È7˜2eŠ$—vÔÒÒÒ˜ýôSŽ;F¯^½ppp¨Q]tuu¹rå ‹-âØ±c’>~ø!©©© 4¨\øúõë‰G&“±téR–.]Š……ÁÁÁØÙÙáààÀ€Êå'|±/eذarùòeÖ¬Y#ugÕÔÔ8wî:::ìܹ“Ž;ràÀ‚‚‚8wîŸ~ú)_}õUêÒ±cGvîÜITTçÎSÒÇÝݽÒpÝ»w—þ¾ÿ> 6Le~Â@UbäÈ‘Œ9R險qŸ‘‘QEYzöìIÏž=Ë]WèSQxéû¼LWÑÅ„¯†èb ^Ê•+W8vì­[·ÆÍÍ €;w’™™)SºwïNff&;wî”î]²dÉkÓ§4ÇŽ“ŽYëÞ½;Æ S©oÙôÊê+Zjàëë«´Úìm 99wwwîܹC—.]X°`[·neëÖ­,X°€.]ºpçÎÜÝÝINNfÒ¤Iœ9s†.]º°sçN¥-tjSŸ²>|˜¥K—²sçNZ·n]¡¾¥ÓS¥¯hAªALL !!!ܾ}[eø'Ÿ|¢´,µ!ðèÑ#,,,X·nÚÚÚhhhHÏÎðáÃùðÃ%_¬ììlNŸ>½{÷æ“O>ymú(ˆˆˆÀÌÌLšàlÓ¦ [·nU©/€™™«W¯fùòååô}«[ .Ôhz¥‡lhF¢¨LiiiÒuÅRÅ!4ðÂËÀÀ@)¼¦)Ÿª<òóó çƒ>x©¾:::ܼy“¯¾úŠk×®ñþûï¿Þ$33“]»vI²â\íºÀœ9sðööMc%´nݹ\Îܹs±··gÓ¦MK}öºH·nÝØµk—/_fìØ±å¶-MóæÍùôÓO)..fÚ´iÒa<¯Í@š4iÂ?þñÿŸ¡ZÃìÕ…„„’’ÒàžËØØ˜-[¶H‹ŒŒ5jT6{{{éßÂÂB%wø²ddd‘‘AHHƒÆ××WW××g zzzŒ3F’;M44âââxøðaƒ|6###tuuñööVrTTlÑùôéSž>} ¼ðÅ*(( Y³fµvÔ…"¿&Mš(åñøñctuu%]š4iB¯^½¸wï*õ--+vfcA•yòä ‹-¢oß¾¬ZµJ:*ÙÒÒ’Ñ£GsòäI-ZÄåË—ÑÑÑ¡iÓ¦Œ?ž“'OÒ³gOzõêU£úèèèpùòe-ZÄÉ“'=z4––– 4€Ý»wKáß}÷7n¬PßÒé©ÒW|ÅTJ^^šššìÚµ‹N:I×çÍ›GãÆ‰‰‰Q ŒŒdóæÍÄÄÄ0fÌÖ¬YS£útêÔ‰]»vñý÷߃ŸŸsæÌ`úôéÒä÷ß'&&†-[¶Tª/ ¥§Jßa §NâÔ©S Q‚ÚŸIÏËËãòåË’¬Øt¬.óäÉžmÚ4ÜÜÜhß¾=íÛ·'==9sæpîÜ9)NÿþýIMMÅÍÍåË—‹Ž­àí¤Ï˜1ƒ¤¤$Ú¶m‹¾¾>ZZZüú믴mÛV©™š={6¹¹¹~¦¬ë4nܘF‰ Ê£z¢©©©TéËÊ Ú¶m«d4õ   ñöEyT¿‹%„U¢‘\.—¿Î ‹ŠŠÈÉÉ©×Ý3QoOy¼vDëÿ8xð ¬4Nvv6ÁÁÁ$$$ˆ·Ñ .÷~&;;[ºöŸÿü‡ààà:WjÍ@ÂÃÃÉÈÈ ##£ÒsÑýüüÐÐÐ`ïÞ½¤¥¥‰Õ€X½z5Jï7--½{÷¢¡¡ŸŸ?ýôçÎCCCƒÕ«WשúSkröìYqttäìÙ³•ÆswwçÁƒ{D&Ô2Ϋ¸™ °žç—»Hé¿ØÃç0©zD&Ô²2&”1Äg?›Á— Ò]*›7ÄExÉô‘tÏsŽ4{£Ñð&¼ö¦± Œð.s»:IqM]ì•|—iþp‡FœgZ0B+“ŸËAppnô3=7"¬È"ýú ÙÿÜi~CXì !‚=@"IEND®B`‚snd-16.1/pix/fmeq59.png0000644000076400007640000000566611147553267012777 0ustar bilbil‰PNG  IHDRq&]Éâ¬sRGB®Îé6PLTEÿÿÿ```pppÀÀÀ@@@ààà   ððð°°°€€€PPP ÐÐÐ000©©©uè pHYs  šœtIMEØ 61¿Ì¤ IDATxÚí]Ù‚£*ÙE÷ÿöN’žÎ„‡™Ž’N-Ô‚f¾íoi\t~ógPù£Ñ¾íÛ~o›h¯Š"þ*4Ú·}Û¯m²sZ¦gPùƒÑ¾íojbÔFQJõ ój­ë‚ñÃä¹·“~Ý¢òB›ðÎÿ¬ôý–Fñ°¬ŠVã ~y! !ŒªQ5(ñ¹x Ã-Ålæ=Tz0‡ŒvWàÓ¸kd»Pü›­aTDÿSÄŒË !cB ðT:‹Cã–A¨äþ'5Œ®pã"lòÇŸR©€0/.e£ÝÔ7ë÷îË w" ÊS…I߇6%ѲLRA“øžIbMà/Dør ÇX)‹3׌‰ïÔ‡¯p Æþ¨%ü©1›áT@˜ûz-î¦E÷³Ñî5 ëõ ç÷;aá§yõJß?Øh„cb™­½Ê™³ò`é¦MWrÿƒ™Á¢:'R; (æþÃ<‹îOâ¬Þ»~ž×·]ï%Øuœ»0ÌQEwÊïš ô±>â<Ï’¾OlãÉ-õ¦“§Û²h¾ÝžAåÆh~ÿ„ 4F®‹pRòO­&Vü«]Y<+w¥y ý«5‡4ˆÝ­æƒ ÍÆgÈ^åÀþZ° 4Î:„J¥K4PW‰Æl‡r/Ê‘î3×sRjXSÛ‘ûvG†­„( )ò9eñdªËžó*••Dƒ•øBs¯üd·-"ó+Ûh—sª7û™«‘™œ©aA>…¡ÛŸÔøvƒV!ã‹3¶Sc¨Z':‚|Û¬<Ò¸+*Cå¾\eiDØ,â)”Ìï1£ l2Ï#·E¸Z__t¢þórµ+‹“4§ lÚu«L£$ ή”Üc:ÙS›uð•JR–-ž\wH)!ÖåêÉî½6φfl¥QÌ ~+äùZn6o4‹d¶´Su¨š¼ár ·È8V×ãÚTŠ&ÜP>Ã߯q¥a³H—=ó͈@OF¾aÞ–¤Ê&L‡‹ÜkQÖ¡’hàɳ‚îdÛ¢µDLWOv›m•žÊð'ãgŠ(ï|<Š®‹J×NËë#!¸±Ãó9VÎV •â„,åüèhÀü†Í"Z\öÌ÷yFP~F¾á¿«…¬C-Ñïÿ\>ü[*,ëOv cÛ¤w~[ðqç@Èö²uÀ·†åÓJ:%ýjáõn,–hå’©EÓR>Áß𭠜߰Y$‹KžùNÖ ˜Û…ôõŠðïjhõ5 DÖ->q3áú“Ý:eØÂjÊ%bxˆ£¾~hÜÞËF±oÕ8U7…+tJúåì' ܋ʢíѱr$;¨ÅŸào0V‚ùÝ1 ¿¸ø™ït­¹¤ïc[¨ºv˜œø±“£¨V¶p›÷±}ã¢!æÈ!äKŠ{/›3z닚xÕcŒ(ó–[Y=È<,·…KàbºäŠJQÙÙþ†ÍP~wÌ"ŠD&¢µBæv-}ÿ`ÓØòF&˜M3·q® ‘k9¼JÛËjÜ{±dµý+y µ±É5^PþX ¸íï ÝÝsß *W ð×­ÎÆ_+©LDk½žÛ·•L¹†¬î5SeÓçF,mõÞAgçzÙ´à›ßä4–9® Ó©_æ)(n'ù/±‚©\PŽà¯6±¾U(ÂZ!sû¶‚J=¶Ö['¨¤f‡0çìÍ]†X¾Ç¹^¶8¿yÅ· èTè—Þ$PÜv™+”ÊåþºÍQoаVÈܾͪI_¤u¼5Ñ•Kw#~¯ý—|Ö‹Óˆo|N¥ ?l–o{æömæÙ†Ò³`»Ééàù£Ïöñ!ÖܲÃL7©@›@_¡þ»¥Hbwøìâ\%û0¬â$gnÙK‰oR¶_ö äï÷u^ÀóKÞÀíTo¸E$ü’-νHãü}†Ûé‚o+o `ÜøùˆË *ðm˜ÿ*û_Gbù}1<8êºqñ3¨@ÛøÛ$÷ûû:ßÖlÝoè,na/{Ïç×]yJûô-20¶Ø IEND®B`‚snd-16.1/pix/tanhsinderiv.png0000755000076400007640000003713011147553271014354 0ustar bilbil‰PNG  IHDRÂ÷ºÃ¸sRGB®Îé pHYs  šœtIMEØ /;Vºbi IDATxÚí}w`TÅöÿ»›Ýlɦ’F( ˆ(U©"¢t”ŽI($Q𠢄¦RD}Jä=;½< ½è£„’„’R6Ù–m÷þþ˜÷ö—o²Ùl¹wv÷æ|þÚrï;3g>sÎÌ™s˲Ü]ÛŽéÕö/°0µÏ’¡ŒŒŒÚnC!„$ Bþ0 c4ÓÒÒL&Sm·M:•eY“É4mÚ4hDPŸ!¶Ã¬4ݾ}û¬¬¬E‹ÕvÛOð¤KÌv¹qãÉzUVV†……Áõò:óSD¶GX–Õh4,ËŠÅb’{¾N ‰Ž9"Ȫ%&&Ž1BUcYÖjµúìaáШZ­Öh4ï¼ó¾Þ·o(לàÔ©S$‹“J¥!bN£ä ’«ör¹|ëÖ­Ä”¤Aƒ‘ܩꩧæÎ[¿h”a˜ÆkµÚß~û ¸ÉðçŸÚüሡ¸¸X°Ö%MnDž?žXq„µÑgŸ}ö³Ï>«G4Z\\|óæÍY³f+ù#BCCÛ´iCl¢¨ÌÌLA¶¤D"ùþûï)D¼(}ûöU*•‰„L@hü!ƒÁíà9~ÿý÷&Mšäåå ¯jJ¥ÒgG:÷4Ê0ÌÁƒñç]»vdûjߥK„^hƒ^žÌîÄ4 ôz=>&< <¸k×®õ…FI®Î8ÇÛo¿-‹333IF ªŠ­R© üÔî‰D.ô PµÁìé¿X»v­B¡€vð›6mr¾%E£„Ç¿ÅbáÛæÅ5š6mšB¡hÔ¨Qii)È·¡}ûö¼†ã©†£G òøF||¼×#xønß¾¿‡ÇÄĆ?‚4ŠÅbnCáýÐfÍšÙ~áÕ¨Á‡ ‚¿Þ¼ydÈÀ0L·nÝ 8äÝoÉ{>8KkèÎk×®óΑH$° ã`Y–eÙÌÌL—6aµ»Q£F.´U«Vz½´Q~û„àXBžþyh@˜3gÎ[o½Ui8Á?üгgOoÒ(¼_†ÉdêÓ§´€Cp¿6Šúúë¯%‰P¥¸•–ÒÒÒ˜˜’…ªTªeË–-\¸ÚP›.è}ñbÔOš4iìØ±¯¾ú*ôÀ±°êt:‹ÅBØQ"‘;vLíÙ¨Q#’%‹7J.%=ÚÚ¨orÔ¦Š¦§§C;p³Ù<`À’%jµZ¡Nð.]/´Ã ·nÝ2@¦žP[yy9áB·nÝ*Ô)lÈåòqãÆA;Ð£Š¢Ö®] Q¦Üž‡JKK/_¾L¸ÜŽ;R°9éŽ?N^{‹Å¶„:@£Àç¡ýû÷cF{ñÅIRÛ–-[Àó×2“+Ш}p~ï·ß~ KJJ"É58>˲½{÷æ›k´Z-ŽðÝwß³|qÞ·… µ>G£ÁÁÁE•••qõÀÛ·o“4áËËËFã„ 0ׄ……uêÔ‰?®1™LÅÅÅqqqEµk׎¤¹@8m'4êΜ9ã§íuåÊ•ª_Y–ÅOÐh4UŸ>}D—ñÏþÓgß—O›7o–J¥pŠ AF§ÅÁÛL&S=ÒFY–6mÚĉ‡b ¨ç Ljß|óMqq±ðÚP*•‘,4==ÝùÜ´¿Ë à³J¥±±±Â&nBV³˜tdd—2hÁÚ(À£5J¾ÐÂÂB’Iô “ɤÑhê5‘€w±~ýz¯l”––Z,hNp÷îÝúH£,Ë~ôÑGC‡…µ€w©Jê„@£UW‚B,Ëž;wº:…¢¢"½^&<u}ôîçЪU«ÀÀ@Â…Ž?Zh”cLž>ûì3…BA¾Üàà`¥R q©AuÂŽ<ÿꫯFA®!à‰íË/¿½‰sÈd2AÖ ÓøÒFiš8p R©”J¥Ð¾bÓ¦Myyy Ãà`€Mš4¡þwĘ!Ú±c~¸Á`àuàZLž<™§ê8€^¯‡ñïy÷åää }ïË]ÆËÚèÞ½{wïÞ-Ô¬$±páBFc ¨:}úôàà`þä)00ЦŠþú민žÎF%$$( òÃãçŸ~üø1H—'(+++//'ÙwÅÅÅ>(ƒú™ —ˉwåÊ^7Ðär¹µ'NœH²%½²×$$$$$?çn0€F A¨k—ÂF³fͶmÛF¬¸‹/úrà5€]ˆD¢O?ýh”–,YRZZ 2ç_ÉdóæÍƒv8€X,^°`Ð(9åÿöíÛ vh´|ÿý÷³fͲë v=­Ë–-Ãn:Б€+0 RßzpjµÚ¥EX Q@¨¬¬„ãgÞ/ž_¹¹¹4Mצ#„ºví*åÿرc8D¬-¼–eE"‘^¯'éVLñv Îëi6›]º…mÔø?ÔvR©LNNöÇ&nÚ´iUÏmš¦-KÓ¦MC^B¨W¯^äË9s¦^¯XcVTTx_mÙ²eäMÓ>ô»ö:th£Fª1&B(??F2Àë†ù¹œ¦ia‡"ò¦6*T( òËO°àðqú&õiˆÅâÖ­[Û¾VVVÂêÀ§`6›¯]»4êÇ@Õ\šaY¶¼¼üƒ>ð÷¾YµjUµxN‹-*(((++ã©D‹ÅÒ±cG N`4/^\j S»Ó(Ã0[¶l©Ù©Faú¤R©]‹ž§øu ÃX,–:×µÎïöΚ5 šhÔ§QVVVRR]ÈΜ9À¡‚–––í4 ¨×`æ?þ‹Åüíqéõú‘#G«‘^¯çwßkgΜmI Q€oHM[­VþB0 S^^Þ¥Kb5*,,|õÕWßk:îæÍ› À@£áC­V󚤤&N:UV"‘´mÛÌ¿iTÀNd¡ŠŠŠj?ºzn `}ûöupìͯÁwrÀú‹ÅÒ­[·zD£4MËåò† ÆÅÅÕvM³fͬV«ßõåÍ›7/_¾\má©ÿþEAF Ѻuk½^Ïkê'o!--M£Ñ@{«ÕšPh”eY½^ÿàÁƒû÷ï×vÁ矮Õjýn!üܹs”=/9š¦Ifš*Ìf3±œ»wï&YµÊÊJX¯týõ—k]ÜÓhö ¾ 33“?K'44Ì(€K$’¹?š_¾cÑ{¥ÜeË–9¹Dé¯[L,ËDDDØýW.—ÇÇÇ Þ»à6d2äM8Frr2ŽYç•b?­!B(44¯TÚ „SºóTGŸMÌíïÏJ€3°m۶ΈŠ¥}žwíÚµz½¾Z/.]º488bê¾14ÏâîÝ»5ç‰)S¦DEE2Þwî÷€ÿoÂ@#œD@@ÀÓO? í4 ø?˜;w.˲ bêÄÉ“'¥R)´Ш;ö‹L&³û¯Wò7pŽ3gÎT;oãRªn@ýÁÕ«WÅbXä“F}D1™LRB(<<ü‹/¾°[»ÊÊJ³Ù,<=®]»v0B¾ŸÝYå~JA­]»600P¡Pðýöµùå²,{ÿþýððpcàã0ûv©Y*•Ž1Bæ°X,Þ½{÷믿cØ_l&£{÷î4í‹4/šùìÙ³ñ‡ñãÇ×vMhh(åAžëU«VEDDÔ¶ÈŸYZZ CËó‘ÀÇ“Ož³­Zµâ)¦dffŽ9²þŒÿ¨¨¨ØØXbŽñÆb±˜Œ±B2r#\£Göµ .ÿ£Ql15ŠX‰AAAuÎ~$ã\ÿüç?7mÚTÛ2… ¾U*•-¹ßøöÛoGŒAfFW*•­[·ö뀾H£`¿p’¡ðÄbñÎ;k#/FCLãØ»woFF†P×ø„š”˜eYUÍÕªÜWž¦éž={ñ±åJžÓñy¡!C†ÔyeãÆ)ŠzôèQTT”'%æåå) ÇÉÛµk§V«u:'éW¥R©ƒ|Ô‡ÆN ¬>ñÄ|Ì»wïÆ{Jà$pŒüü|™LÖ±cG/Ó(EQ™™™U×2¼ˆ¦M›â¤n!´mÛ6gÌÌÖ­[SuþüùAƒyRâþýûëÜŽìÛ·¯N§+**Š÷;Í…¼T¬_¿~ÅŠµ%Îäö•€¬ýpÃÀ›k£§OŸ tIaı©]*E¥R-Z´È:!Dx™Õl6>œXí&Nœ8pà@_ ô×^{-55•[ÖCuéÒåï¿ÿ&™>oúôéÄ¢¨nݺë¦?þ¸C‡œX]üÁ›4Ú©S§ž={º´é†·Âsss'_OüuÜ …ÂÃñóÓO?ÕØ…¢¨AƒÉårÏÇê©S§Ìf³c1íܹ3‡gœ.]º„@ì">>þÇ$Cè¡¿ÿþ›ó'_»vÍl6Wcg¼)Ê9·âZtèÐØ,جY3’yJrrr¼¸/¯Õj™eýÒᩬ¬Ìù–ÅÞ³î‰/BH$9Ø~©Æ¹,ËzC²×ù7b÷RÓ™Í>ø€¿dsÕ0uêT|HF`X¸p!O»g5gn–eû÷ïÏSEBBBª)1J¥’|š2Ê>˲wîÜ)((&ºÔYYYK–,q[|e2™ÑhtævÏGˆK’Á‰GÃ0r¹üøñãŽ/ã6€t@@€V«­í_Ç!`ÜÀ¸qãž{î9» £†§Pï&ËD©T*2¦7˲çÎ³ë¾ÆSqo¼ñÆ´iÓ,@ã"öìÙSßi”“¶v‰DT*•m‡Í·mÞ¼ùœ9sœáÓÆÇÆÆzh“Ò4ýÔSO=óÌ3Ž/8p MÓÎÈSP«Õ.\غukm,]ºôádž+‹ÅµM98pà·”wûöm¹\îÀÊæÃ®·+¢<›DUÕ= ï§áŒ,×®]㉣år¹²ç—4JÒIÍ`0¸dÏöèÑ###ÃíâT*•óG¡4h°gχeË–-95‰Nêä1öÇsE7•••*•ÊñÈäÚŽ9bW>Y–]¿~=î_åóìÙ³Z­¶¦ˆ*•J“ÉÄ9e³,ûèÑ£o¾ù†˜¡]³ûøó…@7ÎnòÁ:ªÆò Š¢Ìfsmÿb-À¥nذ!88ØÕ×6lvÿtõƳgϺú†=zô6l˜eát§Îgël·{‡a˜iÓ¦%&&ºT–{U«*/^tüC‡EGGs(„^{Æ ­[·æª,«Õºyóæœœ»ÿ.]º466–Û!vþüùÚdR܇}Hjþ>kÖ¬^x'©Ö}jµº}ûöüQVµ_RSSŸþù:îò/Ý´i“4ºxñâneÔ¥žp’Ô†éÛ·¯KwµhÑçq£8—˜‘a˜ôêÕËÖÆ™Qê¼k¬×¯_÷²Y–ýꫯ¾üòK«ÕZÛ·nÝ¢(ª¸¸ØÁ5NlEÝ¿ßózÙ0a„Úzð…^X½z5‡ÃÙˆ®X±"**Š[öpОœÌèN÷ñÇ7hÐh”]´hQÓ¦MÝxÿ_ý‹‡êãÿúë/—nYµjUÆ Ýë„ÐöíÛ]zO›¹í†€:ß266 n³›V«Ý¿¿L&s²,‹Å≨WVV5kÖ,==½¶ 2 ƒ÷ÖŒF£çƒ«¸¸xèСýúõ«í‚“'Oâm4=⸿ªA§ÓQuùòe»ÿÒ4}âÄ —Xç¿Eýë_ÿªvÃ0uê7î1l³fÍÒÒÒjÞKQv®U~8$ÍsçÎEGGÇü8¤ ·4Š“eºúbsçÎwo°+…ŽûoïÞ½­Zµrµ¬ýë_2™ÌAs9xIµZíÝX­V¬ºdôá[宲[||üž={ ”o†aJJJöíÛüüÃ¥Qqÿþý˜˜Š¢rssdíû÷ï¯Y³&:::**jÖ¬YÎsýáDZÌcõùÒ¥Ku¾Þ­[·&L˜Ð°aCû¬{Ÿ¢¨©S§ºmsTÉ'œššj÷ß”””Áƒ»mƒÛÅœ9sXó÷»wïR…ÓŸpU÷Ú¨«4ʲì³Ï>K`ÙßxïÞ=—n3fÌsÏ=çvq¿þú+™¥–e›4iòÞ{ï9/&LèСƒÛKH'NìÒ¥‹“×·iÓæ­·Þòp !táÂ…:/£iz÷îÝ–åäTáÌ^™ó%._¾ÜÁÞ°æp)ñ°û&Û¶mkÔ¨çTV[ÕŠ‹‹¹-‹a¬oÕ\Œ‹‹ã…è¼K£}úôyå•W|“F'OžÜ±cG·‹Û¿?O*^M¨TªŒŒ ç‡Ö¶<ìYgH_¯×ã%NGEnn®ãö±Z­X×àJt{ôè1hРÚþýí·ß$‰‡Ë©Ua4)Š*((¨ù×Ê•+ããã=߫ك¶´á\MçШQ£%K–TûqöìÙµàbÀ€ýû÷'S5–e½ï7J&AŘ1c‚‚‚XWüÚŽ?îö Èùóç;!Ô²eË™3g²n¹Ý±,[^^>wî\'é>ÿüóN:¹á¥ÚÙ§ÿûßÎø·®\¹rÈ!zó5iÒkÜÎÄÇÇÛõøs¯I333ñ]lذ!--CÑŇ©ìxôè‘L&ãã\¹J¥ªí`玙³gωDU{/‰ò”kìØ±6ê¬æõɋϩ׵ѡC‡º4c»÷&wîÜqõ^]2]º½}ûöóçÏ÷°©u:3WoܸÑs«{­×ùV®úÔ†Ž;âó]ÊrcÙË=à|à0 SXXXsG…a˜ÔÔTÎ]2k3€,ËÀùÐ×ìÇŸzX³¸Î;=š§²ü)fu§NðоÀâ9êõú¿þúëÏ?ÿôd.\´hQRRR^^žã+³³³ËËË=OåÖ§O–e8Я_¿Ú®ùöÛoe2™ãøÓÎWðüùó¡Õ«WÛ½àÃ?LHHðDÅvP4™ãÛz½¯ÅWû}ݺu¶b‹³«¶÷êÕ«aÆäÏw(ëâ©,: *‰†!ÐèXÂ< >†üðC'¯wu?ª&´Z­D"aË>b49Ѥê|ÈÀ±Sºç}Q§ò;þüëׯsÅ!ƒÁ`wfÂ–ï… üz(6mÚT&“‘,±[·nÓ¦M«Ö’ø¨ߦШw`4/]º´mÛ6OúÏyªBaû×í²Nœ8±gÏ’ËLS¦LQ©TuŠ©Õj%ùVÄʪ-Õ’ÛhÓ¦ É1OÓtxxøÂ… «1ÎÓO?ÍS¿(•ÊGUŒÓ§Oÿúë¯<±çŠ+"""lò°nݺիWó—Hø¥—^ªÊÚ!Qn}‘F³³³oÞ¼YÓøòdH›L&b9‡ñÙgOb°;ϸRºa,X°Àq6³ÙLqºdIýo±UhÖ¬˲ûöí«Éw<‰"˲UR„T*7n1±ç¯7±)Y5äÝÊ•+­V+ Bf̘a[ÚfY6//oÿþýþD£r¹\&“9c¡>|(& %ª¨óJ|:…ŒìnݺU¡PIn“ššÚ¶m[ÇÁ7]Òž^~ùå‘#GÖf¸õìÙ“Û÷¯¬¬$¿R-ø±ÉdÊÌÌüH¶ÞIDATïÈ”ŽñP·æ$›JaµZsrrų̈oÒ¤I£FœÙ`‰D‡"³ù^^^>gÎ2é@0°3ãaà×öumë$¡¶mÛ6iÒ„Ûâ222rrrpP/NÊ2‡| þ±6ʲ¬H$òdÞ+r?uêTgŽúp•ÄëMØr÷:<ߣs Wû¥  `Íš5Ä À/i!uòäI–H:@‰D‚Ãpñ¤¬U½ÀjµV]æ÷5Š]µjU}â'Ÿ|’¦i/¦áúð*™ó$mÚ´‰ŽŽ&3=L™2%88˜Œå¾wïÞ÷ߟòRSSOœ8á ³¬0F£Z­†å Q?WªŸ“Ú¨OÕ=//ïµ×^ãðýúõ+..¶ûÃ0úÞ{ -[¶$¶VÀ²¬V«-//'&68p ШkbšžžÞ¥Kb%:´~.ØÆ3gÎ,_¾Üß&;;›¦i2¼†õÐ?þ˜ŒBʲìÆ‰ùÉ øä¢“+hÊÖê›T cdâ“Z/¿ü² m³Ùì ø‹ç¬ýûï¿W­Ý˜1cø«‹^¯ê’…?Ñ(çÇTìB£Ñ<ñÄ®WÚÍZÎ×<ùä“ùùùBeg†a=ztåÊ/¾Ã•+WÎ;GÆÈÈÊÊR«ÕIIIĪÆ+®^½º°°°ê2‚`l5ÿ ÑíÛ·+•J2ò4þ|…BAFÙyùå—ÇÏŸ²,{èÐ!œõO˜s>Mk4ž´3'Ñ©S§ÊÊJ2^„ÏtèÐGæU!-,,ÄŸµZí»ï¾+ Éä%ÂÓ€”J%‡]ÂÕ5_3+***bcc¹z%ÏÁN½zõ$½šÍæþýûSÿÁãÇùŽâßÚ(Ã0ûöíûþûï·oßîÌÅ¿üòËåË—ÉÔvݺu>äÊÝÝ€O 6Œó'ãh^\ ½zõjEEE‹-€›üeee|êÇ4ê’½CÓ´Ùlnß¾=± ëtºÇ“”˜ÀÀ@_ØrÁ©¹}&˲;wî õ¢Ž‘†v“ƒú±Qïßú9M«Õj®X¦ÎØÆþ®äR¥Ñh@l¾‰ëׯ'&&R5iÒ$ÒF9öRêÔ©™â®\¹rçÎNˆ!䨽!$¼|š6""Æ0ÀëÀÙÉÎ;7tèÐz­"„&MšÄyV¯Ú€Óê’±RÕjµ3+È~§¢üñÇÂK>ðStëÖíÈ‘#õZ­fB z½>;;›sMpÁ‚ÜœwXÔ@PAÍ ø™{öìæ€FùÂ¥K—D"œ#öSî8š¦yJ…õc(Ѝ¨¨zhošL¦W^yÅßk‘I,LB(88xãÆÄ&‰·ß~X hÔeNTY?õÐK—.iµZÇ)ìý"‘ˆØy Š¢$ɱcLj±6Ã0ÿý7S}§QWyjĈ>V$‰^|ñÅ×_Ý»¯Q[x€à5 †R©2d4²ûÑ…Ú²e‹T*u)ÀÇ‘#Gúôéc÷¯Å‹¿ùæ›d¼g&Mš´yófÎËppÜîݻ׫˜ª¡çŸžï"ð‹Å‚£8ó'ù“'OôQ£~êÔ©ãÇw)кƒ#}t&1'øñdžOçÑ A–e½u ç:4›Íd¨|ëÖ­Õò-óŠãÇóL§wïÞÄ–,€FÜ„`$øÜ¹sÞÒ Õj5™Èu8 1LŸ>ïzI¥Ò—^z Æ#Шkð !$“ɪ€ÚЧO™L&¼#0~@£ÅÅÅþMŽeÙ'NÃÄbqƒ „·êë4ªÓénß¾M¦¬»wïªÕêäädnUiŠ¢þøã/¶!Ã0J¥R£Ñ@@€€a!íOðb}ùå—R©T©T:©¯±,;{öì^xÁ»mQQQ!H‘¥i:>>¾¤¤ÄÉøF```ïÞ½FÑâ”)S\Ò×,˺uëÖ®] âÅëò4ÀG_PPF}f¬/£´´ÔG^Òl6Èr£ûÈœY¼F£¾¯”ÆÃ‡û‚­Ý£Ga´*±i‰eÙÊÊJNGL¹6 p* 4jgÀ=zÔ»¯±uëV©T*Œi‰eYƒÁ@†×p÷}ðÁd¨ÍæhK" QßkwšÆÈÄKÛ“&M¤Ê†+•™™ )hÀ/ŠŠŠ >h'éõz QJ¯×Ÿ={L*—¤çÖ­[:šPŸ3²1#|F###)R;Â0ÜBV«5!!¡þ !Óæ;Ns}Ãĉñ‡®]»‚QOÛ·odžçOnݺu½jI’1âââð\K|G \·nw£s jµà#¶/Шddd਋œ?yÞ¼yƒ¡ž,)`o$bë0$ó\iµZUƒ%,¿÷4ꆅ%‹{öì¹páB¡¶²\.—ËåõAžB3gΤH­¤¦¦†„„[:P©TªVZZúðáCà&®ðûï¿óJ•ûà4M÷ë×/((È¥ “4Mß¼ySÀ}éõðqÄt’=ÉHÃ4M1‚¤{,€«Žã}tóñÐà;wîôq ´žÈk\\\DDŒ(Ôî¡ê£Qïû`YvÞ¼yÆ «'2ºf͈í䈊ŠjР´ШïÎðYYYÞ}bQñóóó!ÍŽßáâÅ‹r±´lÙv´€FýU&³ç ð_ìÚµ‹À¶d«V­@ë¶oß^xê0ޱ+_Ð(¿øâ‹/ ¤HxÅþýû¡K£R©,€o@#ܨ' `mà¯4ªÕj½›âÔ©S‰‰‰aaa €z³Ù<þ|h¢Ñüüüû÷ïkµZçuÀóçÏçååy±!¾ÿþ{þüK+¹„W“Åbq‡`,ù5,ˇ~íàC4ªÕju:ó!/ñ†õ™3g„ÚÊÆ #A£Y³f„ð+•ÊÔÔTN~ŠñãÇC;ø¶jÕªeË–QQQо"‘ˆeÙû÷ï+Q¥R-[¶Œd‰EÓ`YG?…l»ÁçhÔ÷F>ÖoNN±²X– dß!„äryll,xÝ€F½‰ äää”””€ø)‚‚‚ @£u€a˜€€€Å‹óWÉõJ Ô组hš3f ¬qbÄáÉtþÃ?@;p‚-ZàÐ× ü jµúâŋĊëÖ­› FM;ïºpfZpƒèèhbe=z”ØvÓŽ;HƇ6 iii|—¢P(`;‹+^¿~!$¤Õm Q/@£ÑôW'éhõÕW_ñš‚±L&ÓØ±c .A\A"‘üñÇ …hà>úõëG,›°ñõ×_C#ø„rÈ'2ƒRÿ[ÈOOO÷J+°,Ë0Ì{ï½G¦8°õo¾ù¦À‚WpO£4MÆÄÄ4lØÐ¥»ÌfóêÕ«½Ò ¡ 6Œ1D £¸©:b>È–eÔ.€ðâ‹/ÖŸl²oj£ dá!´sçN¹\ηxãØ ‚ô  Î!‹‰‰‰‰p”À¯±sçN~c!F‰s€F¹¦~ýú7Ž'êaYöäÉ“ 4 £;³,{õêUš¦‰1©^¯³ÀO!‰¢££yÚh”4***BÇn4M渠ѨÑh„Ž÷_œ:u CèõúŒŒ hÁ0ŒJ¥â;™Ñè¸qãL&“Íçà_€Žã‹eàÀÐ"22²]»v,Ëòº»Ë=zøºçÎ|×"„L&ˆ8À>ùähN´QÛ ã¯îÝÓBîEpñÖNÅK/½D¦ ³Ù|âÄ ð!õãÇß¹s'´‡cÁ·h”¢¨¹sçâo¾ù¦_´Â•+WzõêExz$†U«V1 CÓÂÙNLJJR«Õ0z9±Y–…umŸ3êý½zõ"œØ5j$‰„Ä¡Z­V§Óèz®‡Z­V‰DM4 ¨•••$M6­Vûî»ïB³û:uê @£î@HÁ·}………mÛ¶…vÔµZ½~ýz QáX» 4^z,Ë>xðÚàXÕh4@£ä¬Ñùóçó] ±ÌÃÝ»wß´i $Ñ·o_¥Ô‡ƒ!$“ƒ½÷Þ{eee@£|¡{÷î8xÁ`øÏþÓªU+!µµH$:~ü8pW ìØ±#‚Fe±X„ݘM›6%¬“òe=z´k×®àÅp‰$88F>hôÿˆ)8¥s8'Í;wþüùü„=p÷ïß| D£þH…!Ymx(8pƤßÁb±XŸ0 «/‡AýnèjµÚ9sæÀø***}úÀWBòÓO?½óÎ;B­àŒ3¬V«4‰úë~ϲ¬F£!ႼèhµÚyóæ ²jBEÆ SRR_M!Mº¾E£‘‘‘${ñƒ> %Sbyy9aÑÉÍÍÕëõB嚘˜à\@GÄÖ¤}­ÎIIIƒ¤òûŸÿüçÂ… „UQá‰,F·nݹç‹!‹¥R) ç(**:yòd½3êq0—/_°È2 “™™Iƺ_ºtiyy¹P[R&“‘±išÞºuë3ÏøÀîý8ýç!C~þùgê^`` «¢Ñht#Ç–Åb pu…!d0ÜxÉÊÊJ7\R¬V«Ö“{/IýoûÕUsÁ½4¢ø%e2™‹<î-]UVVºQœ{w¹Ý,î‡2›Íb±˜Œ€ÆÀÀ@7^Òd2¹a]™Íf‰Dâjq&“I*•ºñ’îñ‰“ûß÷ak3)˲ .¬ù#ÆÚµk­V+Ã0 `kG»víX×Ñ¿7îZ¼x1ëbccݸ«mÛ¶nÜõÍ7߸÷’x(ºŠìììÒÒRWïú÷¿ÿíÞKÚ§:QVVvíÚ57n”ËånÜ…WóÝÀ¡C‡Ü¸«aÆîWuô9-[¶¸q—{ã”eÙqãÆ¹qWJJŠw <ؽ—|þùçYÞ€‰‘¶Ëß«V­Ú²eËÉ“'×­[‡&¼›´råJJKK«vM=:uêDQÔ®]»|Á´å,¥ÙlÆÎÉv=]%‰{ÞËBEqqqDD„ÔÞ%$$D$q%Ù%%%øv0,,Œ¦iœÕ‡eÙˆˆn·eM&“V« sõ±–à ñøÍ9íšeY­ÖŠŠ W+â Ô••Ùô!™L†OÍqìÒÛÄî©“ôôtŠ¢^xáìã,£à*4hàÒHðdU}žÔ‡iÓ¦ 6ìÎ;ÁÁÁvÁ½*DDDäçç×|ÔW_}gc«Ë—/;vÔ¨Q®:?9n–eÃÃï]»æR»EDD'$$|úé§µÕ!Ô°aÃÓ§O§¥¥õíÛ—W} !îxWÐ¥>*//ˆˆ(//¿wïÞ½{÷ÊÊÊk¬7>xð ¯xråÍŸœœŒ?L™2Åöã²eËpîªk×®áSF÷ïßOMMeë=\myŠ¢®\¹âêY‘˜˜˜šÏÁê·èÝ»÷ðáÃ-Ëĉk»æ‰'ž=z´«µ¾{÷nÍC#ÔÿöðçÇãÅÅÅ,Ë>zôè“O>aYvùòåF£Ñí^¨Z–=ëøFŠ¢nß¾}èС%K–ð*icÆŒ©³®VÇBæé,X••ŲìÊ•+OŸ>ÛÁLpèÐ!/ƒ…ÏFxÖÁwšÍf»Ùhw·ƒša˜9sæˆD"†alOž1c†í˜8Ö!“Épð¯mš[­Öb±ØLü ¯`[3Þ³gOýôvÂ}/•JËÊÊ^zé%›mXQQñôÓOüñÇX€T*Utt4˲¶l̃A.—ß¼yßÕ¢E‹5kÖàŠÓº!„ Eee¥^¯—Ëå˜Y ƒÕj-**²½ƒÑh”Ë嶈ñ‘‘‘?ÿüsµç¨T*𦣢¢N:UӘŵ ‹Å‘‘‘W¯^¥(ª¨¨Èd2ÆÇ×Vý¢¢"Ô![­V‡……™L¦7nଂÑÑÑ2™L"‘DDDTTTàËZ¶l)•J#""*++ñûàšV•¢¤¤$„P»víBBBB:tÀÛ‰$66W*??¿¨¨hïÞ½¡¡¡xì•••U]΋‰‰‰ŠŠ‹Åø!616›Í8(‘󈉉¡iúÝwß­ÍL.,,ÄfíœbzzzÓ¦M/_¾œššÚµkW„ÐæÍ››7oŽ»W6"""&&&111&&føðáÎŒ#']ëñû<~üŸÊEMž«f b­ªÎ•]ÍÒ _²d ¾rõêÕiiiK—.µ=gîܹ‰‰‰5u%¼3Põ9E}÷ÝwøÃèÑ£ÓÒÒÖ¬YS›lP•™™iË3^Õ¨w\ý:L:µª–„ßyöìÙ¶×(,,´X,˜\lok±XðÒ¾W¡P¬_¿¾j˘L&–e‡ ‚m=<´–-[†wo°F9oÞ¼ôôôE‹ÙÚ¶š%kköÌÌ̪¿0àå—_vèOJJÚ¼y³c£ÞöuÑ¢EÍ›7·«Õ¦§§ãø&xE’¢¨E‹=óÌ3οÒáÇ]2êñÁ|ü¹G¯½öšã{Ÿzê)[ÏÖOˆ))(•Êj!?‚‚‚Ú¶mûá‡R5cÆŒªë娫Á®Ó˲ø¯Å‹S¶`Á‚+VØ~±«EÖ|δiÓðïo¼ñv¨6l)?{öìÚœ+´Z­‡ÚÖ2n߾ݬY³ÊÊʵk×ÚTÔ¨¨(µZm»R­V‡„„Ø~Á1BhÖ¬Y¶J•——‡‡‡/[¶¬M›6+V¬ÈÊÊR(ï¿ÿþâÅ‹u:\.ß·o¾ýâÅ‹üíp}±_·Ç±ä†v2}úô ¼õÖ[NÞR[Ò‡ÊÊÊ   ÛÆþűƒöppU‰®¦ÃÚ”q»[ðxù%..¿9¶ê-`§ž8€ÝÜlgd;¶eËoÚcûŒ¦bîxûí·)Š:zô¨mÖä;½^]…ªZFEᔓ8÷ܺuë¨*ùJoݺe{7„]ÍÉÉ0`B¨yóæ6lp¾ú8B«í±µMuŽð×_¿ƒ­eBíÛ·ÇÆŸ|òIµZUK…BQµú.¹Üá:nܸ±I5nܸÎÜ3¡3fdgg»--#GŽ8p BhÍš5gÏžuþƳgÏÆÆÆþôÓO6ù©zÎÇñ”0qâÄ)S¦H$’æÍ›/\¸¢¨3gÎØD´Ú¶m»zõj†a²²²>ùä“ú<´A%‡ÀÀÀÛ·o§¤¤lݺ5::š¢(™Lvýúu~qÿþý˜"SRRªŽÆeË–=|øð½÷Þûè£t:Ý?þñŠ¢ÄbñìÙ³qB7–eËËË“““SRR ¶I)ŠÚ°aÃÛo¿’’réÒ%Š¢æÍ›§Õjß{ï½3fètºo¿ý–¢(©T:sæÌÄÄD|K\\Ü/¿ü’œœŒºsçŽ]m´yóæ»víJNN~ã7l¯:jÔ(Ǻ˲7nÜHII™>}ºF£Áf5¾]¥ReddP5gÎì—£T*SSS±FŒI?88Ûþ»víš9sfEE…J¥š={öœ9s¬Vëºuë°Kv5• ï‰MŸ>½ê"Æøñã±ÆšœœLQÔ¦M›¦OŸŽoIHHÀn‰—/_5j¾À†ùóçß»w¯W¯^µÕtöìÙ¸C9åಪǦ»wïnS91vïÞýöÛo'''_¼xÿ•œœ¬R©æÎÛ«W¯Æ×ö䯧§§?ùä“¶UN…B‘žžž’’ÒºuëéÓ§ÛU-sssSRR ÅçŸβì­[·pg•••Ù]|D•””¤¤¤Ìœ9Ó`08•“S3.(œ7Õ1ÕÂYÐ(p†ÿÈynñKÍ‚IEND®B`‚snd-16.1/pix/fmeq41.png0000644000076400007640000000101411147553267012745 0ustar bilbil‰PNG  IHDRU¢>sù3PLTEÿÿÿðððÀÀÀ   €€€ÐÐÐàààPPP@@@ppp``` 000°°°s¡Ñc pHYs  šœtIME× & 9<*lIDAT8Ë¥”ºÂ †nÚý_íág­Õ©§S‡ÇV!~È« à©eøÚðåZFe7¹yéo¹ÎKÎ6“]T%:ÜëòV‘t%Öçs-(ÿÍŸ”ßm?Ý6‚¤õ‚øIf÷ˆÅrÊÅë1¿~üÛ“»âç 8›~JªLÕ¸_*ƒÔ5cÛù–S-©o¬ñ2@Š­O*›ðbÇßeID³ûVÂÏ*Àó9¢è Ûviì™+;BcÅë*ÇÚ=.ü®ÊWU;”üˆõ¦ÚBxì«+t†ÿ^•ãÄ“U!dcÇjªRЦwh ¸VÈ[¾Þßö º"Ž iÍ–gÍSã7Ð5®ŠX’2K¢b¼ˆr²;@\:s_£>÷ÓhDcPÚü—RfÙ4 ¦lè^šóºùhR„ŒÇ}=waøu5º·gÐìU[@§ç½Eu~ó±¦=ñ«ÞrŽ_Û«÷À¿ßY?KW 7p6áIEND®B`‚snd-16.1/pix/fmad1.png0000644000076400007640000026515111147553266012655 0ustar bilbil‰PNG  IHDR¬^—~c)sRGB®Îé pHYsaa¨?§itIME×  WDÛ IDATxÚl½Ù\é•'v¾õî±æ¾0™LnEÖ¾—¤–4­Ö´Z3šî™Ø·ûÅÀ¯6üàÃÀü~µðØ~±acÚ3ížžQï‹–R•¤ZTE—d’Ì=c¸Û·û!ÁIAFƽ÷»ßw–ß9çw‘s@`€ @€€§_ÀxzÉùUnþ à,€  §—Ï.ç7tlçpþ€¦¿Ïo«yvgW"à oz¡À€LoB$8 €áÊÓ€€ªKE€>{º6@} @Ÿ-Ø™é7goŒ¦ïK08 ÈÁóoØé÷fû3{: @¸ékÂtÃŒŒ ΀@ž~™M7ÿ|mfº 4]áì“óŸp´ì,ç<ƒÖå©A/Ï©@;æŒÖ‚µN %diˆÂZ ²´Î žìîõNúOï=γ³Ò‡e MVc,-•®ñ“Ô, ªuÉDkœcm4n¹(\h~ãÿä•wÞâêNºy#?; §ÒŒ*àw¶ÿŒ…¦P 7Ý4ÿ6Ý 2oa^uaª¥}HG%PäÜð(N+ëSƒ*çJ+†+–g&ζr꺲 U7é*7A;qŸN/q?5$Uð•->ß2„œ¢ƒ³þÓãS1~”÷Røùã^§ã~¹ßËY"ìÃŽ¬y™ÒH[„ƒ¥„§¬ÐçM(«aF4*KÁl€‡©×”Y²œPêÂ£Šæ:ݼþòk¿ùÞó$ ¸âÙÉ=×u3U*W‘‰3HqªÔôEÎOÏxæPhånÞýŸo¦ª|UmX£áè¬ÓcçB€ç<гͅ©Î¹|®@©ŠO±Ó$w±nŠÒÑô;U%¸DLQ§Ó€èt Ì kˆ ƶHI@dª³ôèæÁîÃ~§ÓÍžvðvëàlxCçÙ ^h»š–Ö@hHUj<Œ/¸ ‡ɅÄp‘ÓBçµ ñ0#y –x̳D‚òÁJæ;1³5mK›^6 Ú­[—ßúÖïý`q­Nè,ô0ó¨yæ}fÖÛL½ ›7ulê|«˜®Š4«M«­xÃ* ™ú,«Áhpe¹ö3äܸ‹pÅ㚊/'/¨/­vU¥ïÜ ˜)àšAb; ?w¢®bɫ؛€³frÚ¤““ƒÓ§‡ŸÒS¿k÷˳¡þz4<8Éð˜*C¬‚°aÄ*oh®˜³;¤D>ÆkU8($€äÖCÅ0dÌi•™BáP(·h¬vº s„;%7F.¨‡ŽzÖ v\JE-ÊŒÅqZ­Û?8½êï\ÿú[ßúÝÿ¤¾DÄ<.s•Å)€7=u:ýOÏUbTU®â ¦Hùùî¹çÁêùUÏ%T„à\ÌHg||p fBà^H):ÅtÞÇÏ>1ó¸UÐÙlAdþðüã 8 à‘©å´xÒ+'ã¡Ê­ƒ“Á“ãnoøá¯î Fwdœ³ITúV«”ºA%eL =ç»Ì¦XûŒÁJÍŽs)¢5ÇÈÒÇ W”`n]ÖgÀEFK-Bc¢' ÛÔæ%¡Ä(!åE(ÌYéžÇ!-¤GÀjatê$-4ãLdäy ž°E©ïüîï¾þ­×8õ Ö=ÛdRQ3[@¬‚1í|àê*¡µ«dÌÜ<œåå¦Gà̳°â<(0àÐqç‹“ãåswpÁgÌl8L-0›Ú1R1ݦrÀ®æ«®ÝTœÂ 0Û9\ã¬㳃Ç{‡=™¥§ýQvv89™ÈI©Ñ@gžGì(Á’À×% +•ò±Ôˆ*cƒ˜–9`L iLgÒ¯{%Fv%CãyˆË,¢9­Ùbø~®&–c„1Hí4eÄ"'½$A)ÕqÐÈ3«9žPŒ?f‚*±£¼BAù ÛÂ’±0@´%Ä"êcO›kkWÞ~õûÿÅ N’•#g4mæÍÌgf±ƒpç¾¼"t Ѫf¸š60 °Œ”9ËNO‘sƒyQRSׂ§(p²ó˜–U,››‚ªÙ8÷èà´ÔNË~§›§'ÓbÒ?úéGŸõ»? "Q2Å'"ÎG[JqD#K””AcdLJ(Aަ\[A™øe,…WÔ 'ˆ8áŒ* ãÛK”–.; {¼¤S*´ íˆQr¢Šp µË©B 'F55Ò¹)½¸aõ(©yg}œæ¥Xõ‡“ˆûÂ!0kDP!Ï-¡Ô™NF¿ôF¬r <ʬ´ãìŸýÞï¿ôÚ›[+( ó¹™GÖî…?+yI7µÖµ0™AÜ|RËÌ ³€´ƒÁj°f˜{MkU—¯§"6 C¡bÌíI!)1ŒJgý!Ŭa ˜‚8V*™ó¨Î%’ÌFFÖ ŽÕr(ÖxTŽ("ã\8’`=m(EÂaB„rVçëÖ÷}kUÜI¦ñˆ#ލW°1*Ç,âQ£1¶f±r1åR+ã¨3Î+|¿m ɸÈE¥!ªs]j­pk£(cÐH–C¸À XçÌ„ Q¸ϧ†\ ”nató7Þûî?^¹v ˜ê=®`j ÎÐi*ÌTПyfÌp•³wó1¼¬œÎÌ0ÌŒ„@`-X£ÁªAÚ9éÕsÝù¸«ÈL½›OsÒyØ‚§vÞ€µôd÷`0<–¦uw?½{’þ”åk ¢€pß(#}%¨¤³Ð÷¹5ûˆ5RSŒ™À(RÜÖqžPHBå¤2EàÕÍÄ:(ÇÌ­FÑ~1Ž´4˜¥+ƒ$s¶ ­f9LcÅ@Ý‹Œ‡†ÃÓ¨$§08Ÿm˜+Y HÁ&%qNSJ‘ ƒÁ¸hZk±H|?GD•%³(îÑÅ).Œ(³„saŽB•ZÎ\½n-°‰ñb’c¬ˆæZ‘p•(eP T7_ÌJa'ƒligçwþóQo3Æ¢SCŒ*‰?óœkð\\€œT­®‘JPP…3895 ΂֠U‘áQO çNçÍzfvœìO“6lêÝmÅoÍ3‰Ñ÷>¾ÿ÷û—ÃãýTÅ1a1·>_p`2‚£X fdIÒˆcT8éy[EI)XZxmñ©u”IÁ½0Àœ#iKæ°§±Á!8®ÈØ3ºéii¬3aÍ,Ò3“ÊÜc.À>õ1(ƒÜE܈XAÆò¾Ù25SCA0²a™íz¢ Ö¤ÜH¿Ãéúv¬d"oÈhy{kÔ?SdÐï Ò‹- 8ŸxË)g˜ä¥ð1‹™¯L¯„ÄYÌ=1ÎGÀpnÙ „ óÔ(ìñÅÍ'_|æ_h ŸGí•s¢ó©Ò*f¬ý•rÀó0»ZsJŠ}É)8@kM9E„Î'ésOÈ|‚ÌKYµ|I@åòßü¯ÿc  y£Ÿ:ç„u¥aAL@9&DP䬿>WÒ÷P)+‘G)â$ð‘Ì&y–ûÄÖ ¨ 2¾¶(@RP·k&ÓV*ŠÕ”#r1§U s!°F"ƒ” ±?Ë ‚ @,pàJÞ³4 X0v¹_Jpó@.5½F¸äÖ^K’|iq)-&zÜ;]”$ Í^Ï­.6OÓÎîW¿rÚ.[-!±Ï´QÚŠ˜äÈ çÅTYÌaçÄU¢¢ZJªA# L9c&b¢ kÓ`§§ûc]–4dxZ8¥•¬Ñ…\Ù…ú$žwÙd>’DóéH˜ü¼ pF"„k:ŸËtóq\IrÁ´TCæÓ3{uÖéuò†ÝÙhûݽ²zÚ+dT’2Ç~Be5J#_—ÇH€˜æˆ-Á'!®jŒpà ¡@©‰‘P.h°ÐYÇv<êÃIHÅH` Qj ¤”[ê#†¨RZ*#ÆÅõÈ¤ÌøB!çqŽó¦&Øã¶ÄÀ‘RB¢=™(Œâˆo› •Ô ä”d#œ@¡ÊQžå©Š©5ПLñ1I&È 5ˆ b) –øZH ¡´¦º,"3Âí=M¢¤AM±Ràväö¤C/o¯Kq–íúúR¯ËZKñH¤ãŽ½Ò J ‹É¢ß;9{ë[ÿ¿&Ýqm½Ôé“ã}NM vÞÜÎÔW?Kº? ôÐ Åâ 5<ô‚+ÁóNÿ¼fkÁ®eA+ü$Wñ+¤’ì›ÂT ý/REŠIŠ¥ÊhÊÀœ¦–+™gÙõëW®†4ïtº“ûq»’ž1óh€T¸3h¾4o*ì´ u ªo*ÑÜR¸sj§VPJi…û€çkE®«àùÄ€ÏY:Ô µF@ÔËrëPÙéõ;'­/ìì°Åe¶ÿF©!± ª…&0¦Fs jÀ`L•ÆRG°a&a-í ÅÇXfR–¢ŸÝu¨Ùýj¸#E‚MÀ+ÕxleÌc* ÂV‚Ð&'˜㔀ó ,çóÂj‚X©B.,µ&/\áQ„¸`ÖÊr5l´0ŒFùþà;GO´QŽxn ¶¶/DÑË{K‹áéññ¥àv²®Œ™ëŽöI3Žz'mÜ?][ZºôŠð‹àúÕäëû_¥¯}]RBj1O8«–/Äu0O¨²fô8=OQD2˜­°ÊàYŽAjpaŸ§{«ùK2_驺7­^M ÄÇeÎj‡€¢!* vRæe¤?}üñ½ŸÝ‹DûÝ×ß¡±U4 ŒÀEù±G áŽ3¢‡Ã¢7éݬ&k—7H${Ó½{>½ûäþñIg<é=>|Ú•C›b¹ÞëŒö,CH¬Õ¤4²Ð²4y†Àb¬±‰@3* ?-¥Û—o5×7xBl: ‹¢4E¦ẻÂhMq­ È„LzH(,RL[!˜ Œ¿º|ý—ýÖÊhèš; ¹R+ËNâÂAÿ ºÁÎÖ5¬‰qÚy", ÛK@NV¶VGìéö¥×¯Z&6—/Çuzð4­ÝH¤=͉B²/0-ð¼ÒW™æriEâù„´­Xw;å4“© @Ò’ÐJ’W\š§VΜ›§r4£Ou0ŒsÄ ‡ŠP¢]Í'‚#Ždî³Vdú_½Áå…•ÚÉQ/$òÉþéÚBóú-—cQŤ0,Ãz•ON3>Ü3º?¸¼´Ù¥™KûI3uÏ(ñÒ‘[Nê'mÑt¸[ä$¥{·n^(*i]R9<-Â<#ÞÎå /ÒM…òbÀé 8ÈÁ¦­lÞ©ØyñT’ü#cÌÙ¤ XB!Yªì)B0µÖÄ áð‘Oî|ºº±º~ëö>ü â»ÄÓ -˜õ8Uª¡(¬!.ð‚X iD¡yz’2E¬ï"=æª;ˆL>ÊO¨£È['ë¯^+ÉãŸþè«âH.þæRß{|åà^™ðp2ñ\X»)»‰WC× Ú »xýÊÉ£C¯N¸Ã¹ÌmàIåÕ!ÁÚŠF¹”2™FÅÆöK•ªÞ ÎùƒN¹të%rpл¼ÑþÛ>ÜZ_Ç,£‚»åߎ—ÃØƒÖ£ƒQá÷¤³9!dig©>¨÷GåÄ9çðƒý{oÃïT"=:ðg^X_,ï Y ­\n_àþÃ|º¯B¹F¬¥b<ÀSºy°@æ‹3:y¡TuN02ð ×Ä«¨ Œ0#´Æœ"cl)…uiÆ<ÝýøC@˪ž8·haÅDÖšM &Ëd_‚%ÚG‚Xé4FÒwà<C2É Ï& ª+Î2(“š2 Í7jËÛë‹¡[„Ïî}ô‹_ìŽ~~ÖôÚ/=»H=¯SX Î>Ë?§ŠTiìRÐìP\…êèP…‡z>J´l Á*12çT.ˆm%—\íp¸¹|†\k+ÏdI}_€Ê¤H…0QDa g½u?è}zâ(QÙ†¾³c‘ÇãNµ&4޵åa‡aR:D¢`­¤¥OQˆ•XúÖw íÕëW·¾ýÝogȉR²ÉåÎÓƒ,iD#¥6=„GÖÓ ñvΰ4qö•¯ó½n3=‰]]÷ɇ?]¬/ÜzãòãÏ~F°J|«ÓÔI0 [5p…Öˆ`DqáüíÓGkÍAÿp«~‹veÎ}ðàK_zõåׂ¤‘Ôk4ÀFgQRœ/¯„`N‰5«ñ•ýýº¤Iš«I”²IJÆ©–µ¨áLU¡ñ¼³wó¶ÝUb}>Ei($çZÍçy£fÞ¨[°À‚ÊÂ/¡/<~ô¡Š|Ù +FÍà.‹Lžï#©Bê¾!%FÆ4® ­q{µÕ'̯9›«¾,l»¾Qkû¦4¦–´vùÕ8q¥pÌW(ÄNYEÛL4 !-¢å$XŽdQ£Va=ÃáÝŸ¾þþ[ýð/.×NDzX{ã­·?:ùѸŸ))O÷³ÝÇ÷Ç?ùIP­µ3´v)>þŸþ«k(l`PªÐx½¿ÿ³×Z‰ÒˆXvkó-}eÿ“?héZÄcˆk%+ʬ0FŒÃ°Õ9ù$©]ud%5*ŠÜÞîÞöjâåà¤V.ZëlîÞXº¬Cot|ÂT„ôåÕ[Ë;0Ô¦„+i)§¥Ë† šë©›‡y–@ÕÇ»y¦2€€y…˜ê*”CW)D¹Š0€XëÀjÀŒrDOþÕ¿úï+MƒUvÛ–£7Õä± òGÿ˵´`Á 1â!C‰E€¥K†5TZ³¸s}ëä`aZã‘'­KmÉñëW·#“ïýò`ÂF8W–WLh8&¥! ä4Ç06†Kêa¨Æc…PRƒîÞQ¯õú¨ÒÇ}!ÝDλlÕ=˜çðÎÑgÜV8àœ€uïNׯÎW©É¯ks„JÚø<ŠU4 S1¬#á0hâÍƪ”Æay!%Ækbë €†D¸]khŸ ^Èã¥Õþ™ \“›€{´Nf¤³Ö`E¬V«¯.¿øçß}ÃÔo¼ù_kõYW¹!zéÒ•WÞûÞ7ÿ€¶Æ®¯o/ã,Y¿üþÊ»­Iù`gãÆb{1¨-l±/ŒÌôÛï¼oúÿÕó_¾òòõ?ùuAn½ôú·›Ãþ‰Ó($V!TH*ò)ˆÌ Rßýr{ù¥²ÕãØïäclÂþáðÕ×®¶¼V~ß®]¾Ä¢º3V”Å“ûOp’ìŸfŨ¾µÎÄÀkxkþÊ‚'4R“h2ò—n¸€6›ë//5ñÀ.Ö·þëùß¾ôêõûOþíÿüç÷îõÿôoøh7Øp«|¤)è˜cɳìku=Ü?ë™H¬.®î~õóR˜Aw8¼´îåÏ’zKxÙ°s²¼š²¬]èx‚êK˳¤½ÔÎz§Ì(6éí—¯z¸§½8h,<¾{$µG+Zw¡€ó§p¡„H_ ¥Í :/OçH‚b€<À ð’\Ó Â?·ÿx¾*U©æ#Rå¬EqBÂ4‡6*m˜ËÌpÂ-µ9$À)«¬¯Á”RP®Æ/µ.#­tšedRì•+¸‰"8‚³Ò÷˜Ó–Š@CBƉҮP%·T¸ÿôïľ¨…ÉÿûÃÿí—_<úö×ÞøÆþ!£‡¿z°þZÓí=I`yõ6»]0ŽÒþ•õ~žžÆÑ(ͼ2‡~çmï¬õ»O¼æöÿðßýKŸÂþxÀÃpÊBÔr¢=yíëïÿåÏþ=è `s@K xhNzgK;Û©º?úî׿óµßü‡Ÿýì§Gdž5ËHséšTÇéÖÀÊâ´Ý¸ÔâîèØo¡‰=T“­„×®_º½yssÐÙo¯®üéÿŸ×jÍ­¥EêÎd"öÊkï[Wkƒ÷þÑïþgÛ·Ú¯ qi¬qŸ–]„Á”ýZ£Æx#¤íÆÒaçn+Þ ‹Q²ÞïuŽÒ^ñôéqýÚNâ•Ö¥Ó§'œc´qË[W³3‡mŒ¼…#V«+îˆ~VLóEfž¹9Ö+í0ßhPípµ/4“áiO<›µs>ž‡ ð<ìqµ]á‚°Ó|“žOMW—8ãÐÔX© £mBYMC DT¦Sv„=)£q/½Ç‘Çy4žáá(µÇÙ’ÑÈJS9¨ç¯m/´¶Ç…Ì žg—ðçÃ(ž[q=Ð9ÆÌj5Æð srð|Õ*ó]låÔQÊ:@Œ{c‰d1ÑY%”Pá[탡ÜXF,1–¡Ìú&= \ðèáõWw^þàp c¤pš:§ d ÚNÌê5d Qœ Gk õöûÿô·¾S 4­‘ds9ëžú£q˜æc+¯¾)ó±Õ,\ïþêgãÕK׌‹±|iñ;ßÿþëããÝR'õöÒ/~ô£â~¹µ_zy'ZY_¯¯+¬²| ¼öËï~ðæíýñÝ?ºcàŠÓ#ksb‚¢ƒ`©+šüª—ªþâ%Þ7_ÅÉš!¦ÓµÍv;ë0Ž)IgË_Ýžd¹Wä°$N?—¯Ýú –pº~èbw Òqvtˆm6ñª¶VÊæ—T\3«tøÿÚÀæY?Õâ²{Ö™ çãÐXŽbìåÀ+®¥JA¦•d"š¦¥p¥¬ðìrîžÇh3Ñš•˜J`ßzáDkSíSÙã{í[×öÎ&©½üò;‡Ÿ‡Åµ›;A //ÜPå"ñë „N¾¼ÓµåÒÕÛ«c 3'ˆlx½r˜#~éRÃça«±sT<ùò“§[—Þœ v^»·;ûñ/›ÉU5¼~å ×xÔÙ/ –Ïz7ðk›·ñ“Çs)÷¾:¹âßô®´iÊI°îÛ£»•Á ö…9UþŽšoAóÍÈæI 9ö¢ƒé4.΀6`‘ ÎÌÜY¹XWÂP[¡ÁóçÅ_ˆîŸ>Ú_ÞÞ–¶Ïœ|ëåÛ;›WÞÿÿìÝï¼5:|¨SuùÕ+§rïðî¯ðˆsŽÞ?Et)i,oÖ–R•v²¾èö?ûñ‡¢—ÄØ±,#ÒQZ'2n<_P¡'Ã/®,¶ðu¸’,©±õˆ'ÇÝ:]H"¿ç­0~tü0 ë—n.°l}|2±ܺÒdÄ9(‡Mxe6ñ›íù ©Œ&©ÎñƒyÀŽæ[ÖÉ”ð+…ÊŒ>4mc=oL PbèÌñ‡/ؘŸút¡h¦¿ÏŸ¤[#ùY8*Ŭl2½ì ¤©ˆ=%ƒÌp9ÄÎSv$lnÄ„–?¿û“³Ç˜ˆèÝ×n‘üphH1,m`R‘ð›4y‡!LÒN+‰[ÍØúÙø|¢ä$ë2´víå·º'ösz4zp|óå7k«œ-àfEQL±]júÖvnÞ,Ëãÿ›?{kó}¿.Ž>?¸´|‹Õj¦ˆÞz÷–¿²â‰±¯ÂìäôÉÝÝb0¶ž·Ü^ݼ¶n›=Gν¬÷øÁS/Ž¢Õ(¦õÍíƒÝGŸ|<î~… xóíoìîjÜìåY_Ö^ýæ›{»ÜØì Ön_]ôVäfk# ƒ/Žîy1%¾* ê ŠZóÝé¿nžÞóY'øb]øyÐ~¡ÔD*õ¤é|kÁX°#¤r\á,_èr­¬ óýŠv. @çÑöJê0`S¸BE®Ä9 ³º¡”ƒó}iK ]ÜZo.,ĵˆÖ†Ã3¡Ë M’´Z e”HÄ-!>‚)ÎNÛï~í·Þÿî›CW^Úz™ì™ñæ¥+hA¢ŽÉÇûw6Û¯n¾³ùø«ŸÛ.½Åz½])VkÄŠºÃ/—·¯ºPNz——¶zyŠ=¿}iÉŽE’Ä8ñzÃÉõ›Ëù(–æµZcµáüWoÿæ­¯½½¾úJ÷á§ežÉ]Ä2µ“_螜Ȟ¬‡_^ßCeäHrwÿÞ½¦ã!uÔâ`Fºã–Bð:Äoº–›œö&£³Mj²þ ‰uþ ŸÛ´_‰îÐ N½:ˆÏÏ ªýÝü„Îs¼?«ñgäÒó[Ó  sŒQìÔDŽ 2‘Ç­²+áR{›=ÝbåºY¾4ÆÓyŸáaÓo~ð4Þ÷'Œ O÷ïˆ\uƒ'Gi6Òã ‡‚ÇÊþé/>}ëê7’U2öÐÁ#EéÂJãRç Û¡Þð´Gµk/,žÜ¿ë%l{~³±°ÒÇ ¤–2ò<Ëíõ˜?'l°{v·7—®&#sºÐXÍÈñD5ÃRŠÖJìô¸óXt»]bâ7߸¢eÙ?ô¬:1Ç€5ʇOŽÌSÙôd‰œbÄDÈi@z*nž€ç¾»]  fÕЊuw€ ÷l¬·PŽPÖªæØðô T¦Qâù˜µÚi7¶×>ý¢O•ÅÎq.±¡F^F}jž¤Ié"ý% ¶I.hꥇŸ<4¬·£r_Œ³‰.zɃôÐ:@ÄÇ d>Ýe¡ì™õ·nLP/y2"¡;Üýjóú¶@ùÇ_6k ÊÑ&ç­åP+§±ÌOûíå—5¨‡»ý/mWâ“ÓÎRœ`%ë]-"VEõVvé%c% ÓÖýŸÿð³/¢œ3$K¯ ¤DXÇ \fzOòë¯Þ°™\_»69~zxtÈRš´Y¿~øä3KÙB?-Ç—·wHY¶’Z6È¿>}­ª¾áì°ÖoýˆÓ/ž úE³%‡†7öM ¢²É$¬v[µÆÅW.á¨Bœ†åµæÅbÿˆ*º.µ¥kÍ7ÏŸlKŠ\!޽üô‰—N¨*¿eÇM¹ê-·Ü¾iÿžI@†¾[°DÙ&eì M–æ¦Na3Ù(– …“ÝÚ¢Ý7:Óíä™×7ÙÏlÚ1zîìYÞô"êÛrÃEnñ¸µ$º]lã$?T,:]M”±íõX£Â¤ïê»Qj”J™°Ó höîk¨³ÄÀ‘ÕQ¬g[„z-ŠÞ™¤\SqÊΛæ‹¿ƒ˜$ (äb¤ÀDØ>¦Ò¶VÂ\¼ÄåÊ%Hn@ž·µJ sþ‰“/©¨á :Q'ˆ„m»N3†˜qÃDØv]}ÓWŽáðÒâܹ-›–ÙYšŒû‡&*y‡Žž‹gøÆ=ûóŽtÚ/>ñJmª}ú䙩óggæOÍœ:ë æ°M°‹AN”D^~Éx¶zfCe¢€ÉÌ…Îübwy©9½ÐnÔà̹ù2Z<}®Ò±ÜxMgv±ƒ 3õ­oªÔQÅBw©Ñ-¹9EQ´¸Äb8¤8˃x)j‹B¡µ“B~ PǘÊkQ¡²ÁsÅÅÚ’ÝdíF®äÚ#¥& œºþ׺6«W™‰%óž2LöË<²^£”F@0Pä ŽµV™É$ÈiˆLݡà +½ eL™%.hn£’N¾Ðà¸0*LǼ%Òµú¬“3óã#%¿Ú˜?ßœl,7GûKC€Õò©´ HÑ!˜/V_nŸ¿¨êÛ$Œ¬ý»¶nß:Ý9<{®ð„Ê…í›7AκþºMÞX_µ9g~þ›KóóÍZrî|09¼…7±ÊÎÁÑèÆaÅÃÇa‘èÛ°iÛèȾ¯ÿºôø©êt·SÅÚµFÑrž»xäÙ“¿òÐ3ùòXvщC³V½X=ÕÛ½úØLÒ Åœ!Ü8T–1ßU÷ë¯zÉêx~Ð=°ówëÄé¹%<_¸øðþÛé 44v}4Ýž¬ 'ˆõ[}CSc¦Öom:ô³jÀJ§Ä=?tÝ4 ˆÒ$W=‡… $Î$©LªUj}€‰)ÁÚtò,B©E Qd)…Q± [ÅAÈ‹%E¥ìÈéFäÂɳŽWÈWb+ÊoŸ¹ØìÎIÈA”K¢˜â´ä\šyå±ÇZn´rýr!žž9W­)êÐKµÙñññ²Sâ9îÈÑ—_ì+Óþ’UpsÛû·ÄAƒ·ÔÆ ãgý¹»ö&œ+—‡ªuþÄé(–ù-A®ëŒ¸NŸ>{ºÑ°(uò‚zû0\‡&ÀqD¹  ËRN­(±#4ä•7"Ê=E0(§¯(d÷!¿’ œ—+£¨6¿ló¼›oº5vÅÖI •o%­.—Š!$ (‰ÐÒ&‘µ ¡-®É>­ñK2ÞèXs‘¦1ñz´P WzEHI%ÖlòUmLü„3ŒË#%L`|ã" GD&MN¤ H1,–d>’ÔqŠ^–®ë40Ù¸g?ä»J{žzøÕgÏoؤƱl”s±\F 1Šãn»„KÞÝG“rá›~Û²œxêü†ÁmoxÝ§Ž¼hÓ|³~ôÕÙSÛ¯Ïyc{n¾ÓéßxøðÌØä¨SV¹ü¦‘‰¾ésí¢jŽ:xpçU•¦ýo8(’ÆÑ§ŸòÊ;}ô0‹(f¤P(‡,íbTàÈq°U‚ªC vÄp•1mL¶Å grìîÙÔ¬.ôØå©åÖRWWáÀν7/6Ïõ [»ûÍñ¡‰®lcŽæ.ž ŽÓʦùÖ+¢Aò%'UÞIvoFLg*7Gi“b¡‰ØÁÌWYS.Ûf"2Óˆ0¬c€WaÓaí¢&Š©Ì ©Ô€qu¡ „ó…(êÂDˆd‰âÞA%Ú´«7F*mäó~ײ‹Æ§ê “£ùcåÒÀH1RÍn€…ˆ“Ê–×½áçßqÝÛ®h•1E…Ýe;гչ‰û¨O ¤¤(/YÜ´c÷¶1ìpâ9¼>s$! êËd>—ÏåÈ“C‰hÌ_ªæs£Eó*eZŠ«3çì’çÁàÏ=ê'hGߘçÚ±ŠcÑŘGȈÃc’$¾›C*òK¨Š<Ð²íæ‹žÃXùùù9Ùpr´>½0ènˆp¬D¶sæÂ”7¸9ˆ}¡ò ’A+·ÈœÄ¡ˆGœrn4˜ZU§Ôg&õ@&Ò iLÊ.kŽ• ÑEupO^.¤õ¢UuºdœÜsÏÿ©6õlªQÖÁt±P&@sÇŸ9»Ð7\B ¨ ¡,I(·*c+ÆhLqèw7ªäBBúŠ…XöU¶ì:òܹJÿÒT£+Øp•«®¢øÐsS2€ ÝU€+ýpø•©˜G·¯íß~-qê¤må ÅÓ§Ow'’J³8 IDATóƒxûؾ!×–ªõn.ª^ªïض§e/#Ÿâ›Ÿ_Š«aÉ!²Ì<ç•g^Ø¿KL›´8̳yÞ&‘‡ºq´ì ÚŽ,KvrÀEPæ~¨*dϨBÌœ\ñìñÙ­[ÑLqtÔÍ9çÏŸÛ¹còì3¯€540±I$Ýþ¡Ò©8î³lOöÛgëM?W;öà¹É e³UzË­7 Œõz1œÓ ­ZæŒ^9JÍÞFjÇôJûž> õŒÎÑÊ4¬¨à”ÂürBŠÑ`¤,ÑT&éG(„ÑðÆ] ‡Ž„2ÉS%98‰M¤%0vQÑ£„qÆ!’Ö ù‚—SƒF§–kG.ÚÈj¼íVp#œÁ¥ðâ±3IèÇ2沋ìܵ¢êÙÓ‹S‹7£NR(NÎ-?ó\kd÷°l7û‡và|[u!Å¥æT1‚£Ã˜¢¾ÜFêq–VŽHah&yá‰{úî»Þ¶e`C¿7ŒxÛ¶AB‡ ˆÚyB¨®Ä"n`[¡P}CýNhÅ¥b¢˜j•Š—ÛÝÂH9Ûù|S{öt˜Ÿp`ÈvìV£á“vC¹%ßb¨è âvõb-bL•š”9Wõ].ièe^È[ ií"ÖâÅÔzÖcÚ@X PÀZÑ¿*Å6 R‘¡EµK2/ BœH”åUJ9h‹„E¡²•àñ0ÇYÕ <l!äWúd}z¹|ŦaopêÔ´“’¹PzåJ©˜³Ú%+Ç•5X½Û•Û‚Z²ÁŠ\´<¯vo™¿1Ý .\¨ÇáòÌ‹ ÅÍWÐMŒ4—Æ&û¦ŽžæM:óê1"íññƒ¡Ï[0ÌÕ––úííÜ“%§èz¥‡žùÖ‘«½ÿƒï´'KVy0év¢@úa+–̳¸W ¤D±ÃlåPVV£`E! –ÏEE7Ù´o+wª‹K¬,œ_éu+Q¾ˆ¬ÉöÔ¥SùmñœÚ¸igÙ»Â)ÐÅù™¥SÝ‘ÝW.ÿ;Û<Öì)Ù¥\¾ÒW1£9u©I ÑÏ3vAÀàxŽö“J ”]!™ PB€ŠÚºU5ÑhI©\"=r1;É^{7¢2<ÆJÃ~da•ãq/¨¥VÍÝ@æ:!ÅX2ÛòJý~d''N*u õ|w¸¯¼/LÚœ»ÃƒJÆçÁ±ç.D,–~±ÀLÐ bIV@cc[†f_|éч ¶ä6 Aâ0Å#;TžOq— DŠsD·ú–Úqiƒ=«Z»6nñ[óêl*µj§l;wvvŠÆy§_øIäI’ìQlj…¢¡Ë8•‡'Ýpy¡»mßþÀòìb4¿t¤5;mÙðê ‡‹ýóÕ½×_÷{¿´±Ó\=ÙµsG±O´æRìt $‚E î4ÚíNktÓàÔÒ™ SÕÙKsÐJìœ59R®+B æÀ…ù²'"1±c§íÈN˜”F6Ú’õ÷Ó¼íø¼º¸Ø<~fªÓh-.øÙ½ÍM5Õc{ëÄF©á‚§,Ì¢¤®ßdý8'Cä5²·¿ÿ}£“£&»<ÅñLeríŽÐY:–#5B¢Ð¦<½"pÑ£Zq7\YH³ª@ÚÁÀÌ(è¬H2¨¢²l±qÃÆgŸz(W.2bží©Äöµ¥PG¡²+J(nø…ò€»qkÇ„ähíäbõÌEÛ.ÛEW÷W‹¢bâR‰lÏÊIÊsÔ?räåba`Ûäî ‡`ÉóJåbQ(ÖjEù¢í7;n‰P9ìg³]_õºh¡sþÕ ±²pÏrba«aɰٮ:È.[ Þ¬‚må·oÜûú«ì¸v—SáÍÖYDú•-Š9cI±¢„²pvôÍ\8^©ŒŸ çžùáãêôÓ^œšaIT«·Jx°´äôYHZI&„´““ 9åIL%U6wâˆ7 î¿ó 7¾îŒõDQÝ~X˜˜Ðœe:Fô€¤YK*÷l¥ET ” ¬Û ©æ£ OÛH€Ö‹O9ó ´íÊ•áÍÉr×ö8¶ÇSµE»¯(̓€„û Ær¥+&7WësÎÏäœöç’ÀOú j9>FDÕ£º´i~°8ÐA|¶ní;°kË–ª:wê„÷]ΖöìÛ)466Ø" 7cÚa0¼ì*æcoñü³3ËÕð¬}ðÚ[gQµ˜p+‰"Hå©¶$Å8`›¯˜ßU.ž;†¶KŽ yÑa€Ë5æ;ÝŠFúZåûƒÉâôøŒ‹^ßàžÍu;ùþm‡ÅFµ`1––RÚè•M—ï¬P¦Â$)‹üv¾44?_],Ä’ñ1¸fìгO ªp¤b»Äï„ §î¹Â†¾œ²<±xúÌë7ï¼ióù¥3Ñ"ËÛᡳǼ„I·kÌÃJõ+#¨­º]BËn­ºtÍö+¯ÿÅ;7ìÞkÙc®e†®5\ÔTû -—d‚Ì•fS¨Ù ¬ægèx3N;Q®†x%ÿD@,,¯¨KVI†ÎÆz/–hSæ×2TU=À’XÃùýûnByâÊ\¹;$æTNª˜«œÝç!/Î;¼l—«Ñ”.O´¡Ñ_É] ay¹mYr¤+Šv7T#{ÛVך£¯¿ú K矦³³¤Xˆ’.í¸Êj$´ˆ’6¦HÚ,Ÿ´}>@BA—fdžFŸ~Üv}âxÂË J¼|l—Çö^uðû§w_»÷åsGwõo¹zßÉK/ôå7/u/=ýÈ1ŽKÏ<÷ݺPÃçªÔb…Ê·æx™×?Ö šÞ¦‡®`—f‡¯Œ)ÀÀ@&¤T³ç‘”Š:ó`Éf1!í#©õV1hŸS¸O=þøWþî3wom%AH•Ãj–*ŒŒï½púx¾Òï‘8ÀÍ(Qˆ•ø¢,ŽÐ„vl•Ã.wrõn§/‘±â1õŸõ¹V„Pˆß×_š÷ •ñùñòÄ–mƒýý+ùŸÚ.Gæv\[VFLÈ3t1ÈcÓs$•‡Š2‡qÊ– ë0ÄM­°ÞëñU~B 8ĉ¿#¥Z樊hÐ45®U3cKgbm‰óÏ­¾ÿý#ý,ï!„¥–ŸÈ9L†–¥‚°“³„»Hl£~I•âB8Åq UÌŽHÌM:¤Œ@Ç.O`jç0PÄ9S‚Ëy6—\$˜w‰ãÈÐQ£< q’·AXàH ‹ÈÎ0 âáü`ñöwÝ…‘mÛ¶“wsyHŸ 2“t³&[s”½Ž_˜'+dHI/{´¿˜¤”;Uª‰ÓÏ|ìGÚÀeÜLzâÙ[…œC˜´›M“fð±že^Š[Æ5(™©^© þÖw½³èäž¼ïßúm+@Œ![%!ç aËW,<ï”räR\-BÎNXȶ$ C"-3Ïn.pžÙ•aIi;q› @2s…d°è8XZ¾ P¡I0ny2?¾Áß6¼s/£t¸Xغc³S,õlæóBëåK¦Fººù;Í8„£õ.–6ú“™ÍªËÇR±h:šG´5iÎú•Cõ^Ta@_MhW=¾!¥H5Ï+”¹PEH晦XJ¼t63¿õÎ¥ŒŽ=þ‹F¹0U\vÃDU¢„÷å’ÀŠ*%w³åÌ%LÚQÍ(+×8Üá.Jl>ëºV±¶£8ážÂ%a‚;Y<¶liyä ]J¶_qåæ][½áQ Äv¡@m´¶v­F#Z¶P*ÞLÙµêeD¢z@5Õ¼Â&2ؼì×èäh½l˜yHà×ð~Ë~`–ÒDbDÏ"Å*X;í±ÖɃy¢ô.AÎA)°lŠ€x•lÎ(¼»Øˆ¨öò–vÚ€9“–ë©`_¤õHÙÏ©ÌÓBßmk'Óv¹0›`ÈäµáLOú×ÖÏü…Ù› ̘¡q«RŒ›ÛSšGš¯er¼ÖAñRîµ~™æ!©äZa:’(¡ ¨€paÀ½Ã@öÊ5) VVĨ&hÒïE”q×WæàL“]]®D2ŸP?$Ö® fÊ­¥i£æU½F-ŠsÄ™ôÝN›sÑ,=+V-Ìš‘Ħ×hê ¤jX‰™j s™ê·Í”ý` ©µ¥ƒ{@¶Ò¤XX1»–àZÔÎÓŒ¹ 6ïpæ‹ó:L~¤wñhámÆc[ã§03•ÖT¦>¹Î`àZj§~7aŸ@ÚÙƒµõA2 )ߨµ­lõ’„HoØ=öHz¡ÐëŸQÆ8åø'3¡:HÍ­¥×¹Ä,Ïõ5D5©‰~Ãö¶UÍ ZÑŸôöñ#ágÃðPÆž­7ºÐMœÉJKù]h$8.U—7¨ÂRH%¥ùùÁ¼dï RÚí›eV!Í×™Ùñ @ñX6R«hA·Í»‘i^VWáѧ¹ð‹Ž^ý´Õþ_TiE]þ'¿÷{Nœ ;Ñ—þâs=Y82+dNÖTI¨ÌÓ^f<¤‘fm‡Mllú z¼Vc²•I^¯Bà *ïæ XóÒÏÚ™bm›Ê¬èÌÄÁTÌãŒÛúê!öüKÏ/žž]þ¿þ×éXµjûž?ü‹³¯žþiíD$ó§_™›ÌMÂ…•Ï—l n¡P[ènÞº³ºÜ¡#B3xÚÁN3d¹žY96çC)…²Ôç`V©Ò ¡S™ªía$¬ÄÝØ.(L @â´}qª¤!B›g@fŽë~ià=Žä“÷?^o\ ÂÖoüê/ˆ,N-\rå¼|èôÈÆmæ¼êòU={âðKŸ»¸ý†7œ÷WOÏ›T*ú¹þLo ù±R처—ƒl—†„×üþ×¾àþôÞ¯œ=õØnZ)î–ækj}åÛ¬-7êË­Ç=Ýí×­àíf4;½`7—–’¢(Ž•Ÿ{üGw¿éÈr’fëηß$ñ+‡^<ùôóI žzü'sÎ\`ÍŸ;qôá‡Oñìw¿ð©¯!޾xï½ŠË Oi]eªKL±SC,lªƒD†±BL5‹6Æ\ ¾Y¨¯^ôÈÁØ”¯ m)“X@´×Nõ£Y2*2]w.û‡Êeñèó]·ñZ‚%X úøwŸÀ£òþo}úóù"óå§ÿßÿÞ©5ïýâCkK~óÞ+÷_ó™Oÿ« ÂðgÿþhÒ\~è¾,:ÖÏ~üæ·Þ64Ò=òä–«ËŸýô?ÖÜó~cæð“Ï<äõm»qèøÑW¼p4 ÃìùcË['~®ÙX~þÉçǯz½BšÎ×ÿöK^NÚ£“/9rü…箺þVä»o}ÏRÌÿÛÿú7g5ê?ÿæ·û>;ò̹«oýÒÒ\|Ü«”w¹“_yຫ¿ðé¿û»ÞáÔY·Taá†ëo?ðïÞÿ[ÿù}˜ºæ,™öDz ]ʺk—l*Ìš˜S›¬ˆkºÕÞ©Œ ¾9D€ïøzáÆ´g¦L[½µ EeÀ¢¡c)X›˜FŒkWÀ:ñøám׿VþæéK3¯><¸mÇwÝæ4v¿tè¡ÅKa Ä]¿p €@Âüÿwyø'ÝŽ¿°Ô©^~nÓ5;·^1êÔ¯Üwýž¥9ƒ IDAT±³Ýñ½·~þsŸ¿æŠ»Æämßù¯¹åæ…Úq𪱱M'_xüøóOÆ!;}ø©®G@·_19ºc¤Ã¦òû—èÂÉCžÒm·¿óºƒ~|߯ÝuðŸþæÄKæ¦êGŸ}d,?0µðäÃ/-õ»…ÓÇ_Aípúì‰éK³ÏÕŽ!ÔýÜç>;€Š­F}Û–hæìÒ4.ºKçÆ·í–; T;æ×«7¥ÜD!×(^Ò¬“x&@šÌ“~¨äe c„ 6µŠerÏ=ªý‚•ác³\'æk«’f„T©ñÁZµÏ\œÿþ½÷~è7ÇιêÕçŽoÙÛ¿qä'_úáïùÀ½÷ù–×ß6Hâ}WÞ @K³§Ž>r|hó¿P;xÓMõg÷lÙ±åù§mÜ:89qôðT9o±åêÍo~ÇÌ¥™sçÕÙyõõ?ö…«sïØrÃ$¶äÞ«¯½òº«¥ ¿ûåÇv8X¬Yxàçî:ôƒû/LÍþÜ›n·Êƒ÷ÿè; Kõ׿嶤VoÕZn¹9ñýnc«¶POÔíoÍ'íñ«o»ñRíÒ®=›w¸Qtê[&wmÛ¿½u±ý¾ß¸{p|tp²4wdö}¿ù»¥BþÚ=û'F¯9pÕox£å¥œ±©û“¯a\‹2Ù¨È4³$JL<0kg„õì0•ÎW •°µÙA*‹•dfV²×ëÇhcYl66)'¦Ëî$èþýG?ž4ºW\¹çwÿbi |èGÿºÏ/<ø“¯_ÿÆ·Œíš\žšyà¾oÝôæ·îØ»ªÙh5»Ç_xix g÷¾øÔ‘ëo»åÅ—^صu[”ˆÿïOÿüƒ¿ò¡ý× ž €^~áðž}{ì\îô©S;wíìí-  “P!@n©´"î—a‚m×ÕR¿ˆÖ13–­Åk{t-oÚíAïB«Øz g–DŠÍpR´Þ½®z/§Çr­<äÚ–ÖáË•÷õÎ}œÀXp¤TÇÜëBkr¨6V ÚJZe®ãzÙyZv:‚1 c¬¤"!J*„‰”c¶zN*ЬÔ( 1ô†àû÷~vxæõ7ÿþÍøIšVŒH#ˆ ³.“fÜ$6«q½c¢0dvÛÊíkk;̃h­µþEe­ËR3‹5.'×lCRV†)x@¿}z %Wíj€ŸbÀü8!ÔÄõRºdNͱփBf>D2ÝžÖlÀ–%Wµ+™ŠXÁJûº!n–&2‘>€¢v}¨嶺°Hbbãõ”k-“™êZh 7ÎĦР‘9«¥¤¦ØuÒÙTÆ„@™ï!5Á&Aka¾„Ê +NÖ€&apàZ„ ¥ÚGQ¬w'¥oê»Ú]€Ö«@NûÉD P`Úíˆz=O@@²Õòu¥±A8CÙ[Á%Þ´MšK9B³CúÔ=´q¹Ê€Öky42£M©-Èz´™ÈŒ˜4“&R¤u]ì…µ;.Å¥[OJ$ñн4HD %’³ #Ö,Ópï”O]êt&_Šd„)µ½¥=©­*žr9é!¬¹¸H®ýŒ•RóÄ=ýž0¡·,ÁKšõ΋½ B­´ÔÔtˆéÍ`’ÜåDZµ²¾‰DJPq,!,A,‘<Šg«O:‰•”Ôô‚Q?jiù\kãY¦]|-§AMuŽ%,Á¢dc’÷rylÎtÌRi*'j‚Á*s'¡Œwªîº¦ÌPТTPo/z77ÀsëOÏ^<~N0¹:üP¼Ýh-ÌVAÑ•‡ôÊcǼÔ'õ¥—ïýòWϾtrõò3ÆÖ+‡ž÷»ê©‡^E.Òj ^åa·uö•CpáÈ3q™sa~ýÌËß{¨§öG?ù—ÂÏ$JY÷}òÏkg—{ôÉÓgÎ?öãûïýܧÿù/þô‹Ÿúd»ê#ÿóK÷ ÉŹêgÿêÏîûÊ<³Ææ·D5«0yJK=³LŒ™š$t¬ÅÙ€  ŠTZÙWXÈtàiKO™í>Êñ­OóÖüøxžòwíÜ´º!б—^˜_žýŸý ÉSß\Ù?xߌ+ð.¸ F8¸ý½¸ïþÞþ+¿t«_ýÔP>·}Û6¯ÔÿâsOò°{ãm·mßµÁW¹ S^}ê'¨¿î?X,ç¸Sî›o,M+ø‘üº­Ç¿|ÏÇ?yß7¿Õ/ŸYþp©øÊá—G®ßþÿý·D©_úåÿ²yïö}î5/¼rèØ™“Çj‹ SGŸÉå®ýÛ{>V)ÞxåÏßpÇÞýÑGÊã³7ßòë?ûÞ·øá—PBÿôãÿ"‚ €¼€g;µïÞ÷µãÓ—n¼ao¥2ðèý¼îWßt-ÀþVcùÔ¡ïý‡ÿ@Kƒµê‰œ$QTw åÞ~åZá‚Ͱ ©Ädt®ô ¶É;ÂæØVš†x+¦ ¸©@)Ër±V ¨LT3^ï¾OÅhJs/Gr÷ýûw{øÁïë¨2uô©Ç~òÓû¹<ÄâøÒÅ©ÐO:-ÿØ«GPµzòÕv§îí8þâçĪpüÒEÖáZÑ Dg©Ñšëî¾rÛÔ™oÇ,ì«ä¯¹éª}õ³*3äôKO<õÃïýä?|péÒ) àPMWOìÞ·Ÿ uññço~Ç{„ÛÆŽ=øÄÞþΉ‰ü|@/ÎxäÜýî_{÷‡ãÉï?È6ï¬Þ¯ÿöoüÉgþø£ŸúË·½óîKÏLyô™wÜý¶?øoùÖ׿öHýËïéÿÿøž?ô’ÆÏ=ñöwüò­wÜá ËD- *€‘¢üÏ¿ÿÛwÜýv”°¹K‡¦Ož~ÓÝw„R—þþãÛ®ÚKò}ó'~$b÷îßôò7§´^ϲY;e-"“f:L}Æ›EeêÇ—§»ƒ\éVr±, gb”RÅš4 z{2Ì\=?ZÎ¥O}ê_ßñÞÓ…êo¿ÿ×ÿöcþWù«d.l7ZO<öX­ºtï×¾²kï~«o÷Ïž|¦]ŸËçn]Þ¶¸æþõ?ðüZ8×7Õš}è?lÖ\‹sç/.]¬'ÍDJA‰Ü¶qûæ½{oºó-Ãã»WÊÛå@|à÷§ÁŸÕFyÿ޾ým>˳'J?¹ïÞ gñp1© ßôó7=ð­¯ÿÓßÿŵ·½ý_¾ý—Ñ…êÊënbC»'ïzËuû®¿áubßÂu·ì;ôô‰úØ_þÒ/¿ïöÁß:9úð±g—‡wþÑdq®+s*}o¾íVlY€l@0~ã¶œ]Þ¹i²¿¯rú'ÇÞý¡ßÂ¥@tæf)"HBaÏ·ÿáSçφ7üÚA³…^Ã?x¯Øâ]e&ãʤ#sI«SФY«Ájr¶$H¤VCœiú™9@=ÎÈNéhýý§ÿÇoð¿ÅD>úß~Ý/ÿÒ3?þ÷›ÞqÇî½ÿî¾×qI×oŸþѓ׼çíB$Gž¸wóäA/É¡‰e,ÇA×÷wíÚ¶ÒL.-Ö‡F%„KU?‰£R±ìåÝŹŅ³¯nܶstËäòr£°q¡ †F)h4:¥RÑ÷[y»¬ˆ¬/7-‹T‹ÝvØiuˆE‡GŠÝ&+T¼Å¹šrl¢ø…Oþ˯üÁ–"hʲÇFsv"|[åý(n5;&údŒ-B¢*ð•M:ˆsEɪ¸àŠ *% 2”Ø%ˆ*$€…¶G„ßNlϳ,0mŒ×UFKOÖ»†VÆkE˜Å¯ž#š+áLØ^ÊÐÅ1¹w±ùU&MevŒÊÔz*SœgyYm$^o+×ãöÈ ¤£Û¬ë&륾È^Õ¦Ì.^Ã4k™ 3d®K㲦*÷µ”LÞ« Yæ´Öè*rå$  0‚° ”%H©nf[d õTAË3twlÖÒh=Ù}ª~Ö3w¤ÉWËZèf½©z“dN2©±Ù`½¦Ö{ór½ß+)”«-VúêÔ?~’êËÌõ!3kTW(‹Œû!5äz}Öººì”£ƒX5¹ 0Y5+ J!¥BÓ•/%7NÑIˆ¹ƒ‰y†¯tYÙ ¬§GÈJ/ sb£ŒV60*üž*i•Iš‚L™–Êz#ëF¦\‰À< ‘†ÉLlZ€ÁݦN/KyÙ­UoIFÓ¡L+¦Á!Âܽu)$€!@0à ÍܬØl£×…ØÀ4|Sæm¢_Ϭwše=°VfÍGdÆÉ›¿(ÍqZïðW¦´î;Má¥e6okÚÞXó4[™rI“,´¡Žž‚Ì—F\‹š[ÅÎ4¼G/ æHLeŽÀ”=ºJ9—))’¢æ(S™`b#ëväÙ+#µŠ…¶,Ö2skâL‹Ÿõ÷Jayëž{kK³ç·(€s†)fQ„@ ŽÃÌ$Jà@E95$ä|KzG‰SHbáúɸ“„*æÝÖòY¹ämˆ»\äˆXHÂm¶ßÈö¹Q_a‘œåæ6 OŽTFF Ï.XÚ½‘Ê£õ®]aÖÔÂ<íxŒ)2}fJÁÿÕãªky:+s ‘ä ×`ÊO¥é‘§2Þ)‹ÈÈí¬Š k+ g~KöD3Yž#2e!kíP¨:AmyviºÝeI¥Ü¹¤†ú;"D$‰ü@ÍÃy°ŠQÈcÂìv—‹aÔmûu«]ÆÈ颀T 6Sˆ‡˜çœ%œî¼eO±X®5f.Ôëõ—žkÅe(†œ2Ìo àYVv¹ø¡ÇÔä¶­íßyÓžëï¸C@HÓ ™N.ktBºÞh`màggºuYê¤ 3éÚ½WW”. Š@€” ÌÞI­G‚F™N¶s•°(Í#Í»3¥Ô')!ôfÁB1žˆ8‚P%ª#Ú¹¶ô=!›íÎRÝ ä—Â|Ëoó HVr±v»Á6êÌ4Úˆ…eÙØ&±Àj;B’匫ÒTJBU°¬"E¬i>¬³0ý¤ˆœÂb×úÀ¯½I²ªJÿÕÇ^>þô“Dä‡l,R‚ A rcBpî*Æ]ohËþnºiëþÝ–…cs¡º§ÝŠ”Y ÷…Œ =˜ÑlÏLØ~…º-8 ’Ab¤”Ÿy6`\:|‹^ F•*ÊÀ,"#ùH¹\éwM‚µë³.zP ýd±»ÜêÎøeX„bÞ"ÞhÿÆÊ¹ê«„çåš8òë(öˆB§Ýi÷]u}®Ymðä .¶¬8nØŽe#E¢\ÜA.évê>î/ÆÛn6²Àm(ëaÐüÞºïÊÑ.ÃØêÏ»€µÑCüqÄpbÔqÊÁøÄ®-¸<`1éô—%íæñ•’퀇 ³BˆÕÒRÝqŠí¨ƒÃ¶*õÖr__¿ŒA”«Q܇A:<êÆ,fmbõcY«NH¼udEË0/ Q…]"€F¡ðlKFœkM·’"Çàå•計R%ÁR¡ ª`çj3¾íwlÞpë»îÎW*–4$Í2ûCb‚¹R“"¥*AÐŒHu?b•ÆuVÓq)@$Àc jå$À™ë  §ýȰ•q¾”™N‰WëÌL™vâÅKS5"/^\®ÏU›[åg’F¹‚‡ó/Ý`޲¢+êXvÁ±mÇ0FÂv‚Âr¥Ò–A RÅñaѲ'y»‘D ¢&Íå"¢†½âÖWlܺepópЬs,jÍånÈh{¹åShûB%1cí¤Ž#œÄvˆYѱ-)›IÜMÄ"΄ʹˆHbL)J)"„ce»Db¥— ‘m"„–¼vËß0¶éð{CãÃ&àÁ4é7Á©[ƒ¼¶J;Uóˆ­&cJI€©iâ‹L²Æÿáë=-Í®3¿µÖNo8éÆª[©cu »I6»ÙÝ ¢H‰¤¨‘†2,xF#[lƆ¿øƒÿ ð?0`Ƀ‘5r˜Q8´fÄ)‰d35Cçnv¨\7œ{Ò›v\þPUÝçÜs{€ ¸88޳߽×^ëy~Ϻšôý?¨¥ê/­M}îößøþw^øûïœÝÝE€³;…QÞanrR# [ä ë@•ÆÈ¦‰"v©ëáμöEšøòáÈÎb\»©K¯¼õæAw8¼>àºc@"†Ž3ôµÎH¬RÛn¨·§p|òq3DçP®]*c7¿æºY­.˜ÒÚk"“ µ®M6Ðmðyч^žÙ w«fÑÖó›ãq;½rc7€Êvúx¼æ1Ñ×¶©‹TžMÅÒB<[šYW“wÃÁT:vmGõ¢fb_Ý.³Ñ¢ÍRX5BmXÌËò–«U^\¿qõ›ÿ÷ÿõ;ÿýÿP/½fr•zd±Ü §/NEñ"HsoK¸:wÀŽÃ2Òèd'òTíºÐöÄínù«Ô‹?yI pg³rõF…ihcÛqJˆ€4D"„ލ\Òɘœ¸5D®áå= 4èÛ”Ê2Bœ¤d;7íŽ)º¶›yÐbŒ­PÉ5z±ÂÆwM›fµ.þêôVOõn††Q…ЊþF[Û~¿l•÷.^̶‘™“±®Mu˜dÎM\9?ògÔîQ^otЙ²^+Ã{‡ãN*¶q[—¬Ÿt"fF˜G-Rëý~k[R[MG–&°áu>Ó±®g"ó!fiâ6†½.Y ¥š m¯¾ó3!®k¦ãêÛ «í åA«Z“¦Õ•”–DJˆ 1€w Ø'À tšhøDËÖÀÆtZ9Êo_}C†º&z{èQÖ]¡G[n\Œt«(Ŷ’LTôXÉ, ƒ&ÆÔ %Kì…èíŒ èKÕ…¶àP§¢ fáºf‘²Œ›ÈÜÀn2ŸoëÙ"$Ž€úý½`ùÌö[—T;ï÷dŠòÜhëÛßÃIQúºŒ k'ýüò£ŸQ??Ï™Êßy«.œ›øëGJOW&¯_½v˜·Çn>í¦4¬ ­XI“ZÛ‘6)%Ì]ÞPu¯ýØG̵Âa‘ô\ƒž+œKÛÔ !!ö”y”7ëy5;ìʵøºíÄò„<3ÞM@:Mª´|Ðß±r0¤„žåibÜõwz½§»Ü) ÷zÝbu/µ%t–In|0 ]}Žëùcï@çÊ~¿v‘a’ULÔ¸vJ-ÍÌ/2Æ`Û”"ÃF í„uw}`ÄaÕÔUL˜ Ó¯ëf¸“g-ýâ¡G.nä£sçÏå½tÁUÕ„)a:¹öÖ‹iŽ7ß)—{T–¹RªÁN¹uñ#´%A0/üBTÉug`0Ûm>µùÙ›'ÒÙhÔõk¯¿ðƒŸUWm[׉·3-²¾¡1SI§Ôbz·drMó¶…éœ{=Ðd'G¬Ëí=ö‰»(ˆ”QŽ8$€p ôñáAôàRᵌ«ÄÕ$’åu<â²å„zå^å~w¦@ 2ɵË­MÆà´Y3ŸŠ{óáDLUp2%…õ-23ñÂVDîÍ+mAE¹qF©¤Q.Ž™‚?ãBvRðl6u¶?íÆŽÉ5·Ò¶Ä%œÛm{üé‡ ÐÖ™QYè~?O¨\5=nÆsëoÝ B]SÉÍ0U“ïÿÙØìyþ±õØ:zë;{åLJýþèò£RêVq[%A³÷YÝIÜo¡eßÕ³Nq¦ÿì?þүκÿô[ß»¶_ÊbU•^Ý1)› IDATt"O¥î€TŒ‹¬/Ä`˜ÅÐ ˜"昺 ¤¦í F‘Q‡ˆ¾ÈÊySû‚•šn¼ýî}—^ÇÇ¥žÊráå—öü°:¶…»¢ò•¦r<ÙÛe¼ò‚ÄüzBA\•—­ëöqæB«ÅT•³ýAáf %DDò±õÞu]wv@o¼óV¿,êL41%œg¥¸9ž…™–ˆ·g6êƒK—÷vÔpóÜÞÅË»Õ|rìëîê¤n¹šLüÁ,ù7Â%C+Ñ8/…LE{nn-^›¼òÎÑS?ùÈÓ£Z-êƒö¡¿´ûè…ÔÌ£ó!6ìò¼«Ò;çÎÍšÉâh¦(ñ`û‚*ºÛ×®ƒËÂ56ÎlgþñïýóW^þßþáÏÍŒº6LcuɳÜ$ÙÀ°˜bT”E N)ÙË^¯¿™ð0ÙØô ÖDÌ8`<(Ùë¥Ú)4ÓÅlõØ•k ÷´jkIKvò´j  ULLZÕ¡ÜQí"°€È@ò´ÁÝ©1ÿÉ ¬ ”ï®'[W›ý§ByA¬dÎI4I8†qÕ)êBËÇHã8VmuþÜÙÝþåÇ?úhÿ|9(ŠT¨@>ÞŸ/æ³—¿s­­œxr}¾YŠFŒÙ7ØósÀŽÃÒíãé;oÞ€F~æÏî^|äVóî¥âƒOŸ³½,675d²Æ·D, Nì|ãm’ðóˆìš9¶–<™Rnž?—ˆoµ NÆ}ôÙs~äÕï~ÿ•W_BÞ=ž¸~ L‰5pðÖµ%)*Áyj­f ª7¨€ ¸îuÈ6²2ŒrÕzðªfZsðj²¯…íªÓ?1‚ §™îüïÄ\ÈÕ˜VéØq­øa¢ò´^‹äpÔØ–ºä F Ì1D£ÊLv³)ÕrhýüsÏ=ù±s{?ºãÈ4ŸÜ®ºf:¾9}çØqNhD¬-§&tPù|¨2Þ:L4´€*·l; CÛ.rY€†BøÉíÃ×Þ:~ð+_~¶rãzÿùçŸ/·´s 6ðèý󣫿x•`INçGû‹‰›W‹4.Ì7©Šñ|»·²—è†çÍãi8„½a$³Õg~ý?-=ÿ¿øf‹ÎBj®äVH¹mb.‚0c‘0Ѹhò <6<%†ˆÉ 2„ k‰¡rõ8¦5URZ£œªG‚5{ˆ\ˆ,¿¥8 ˆB”kž<̓§ég` ç·RÄzehSÀ j‘Z›’Ë•T-/H HR ’ýêþ‰_¾øL+ QJwíhœPõa©­G©1k!•Áf.[EÓ'T(¡¦Ö¡Ø8:`–g7êãkׯüÞ§ž{²if©.>ûÏÇäB„C[¦ˆZTÇñzk=ÕG/MêöðxN=1ªa~PbWOgÚÈŸär‹òÍþYya{ ƒjÐÛò’ºä`Q=¹÷Ôã¿?ÿã?«äñ»mÂ2Ï„ãH4ˆtäÉð$¢ó¨2@¯ÐJȼ'ËZö฽q¡·EäSÝÅ„âÕô»;ô2m9ds™c K­ x5×=¦{T@–kÅ ¬Šáé4•°Zs8U*™n^y;¥ÆXmh4F! 玽…†0™ÌŒš²lüþüøv.Ëá ƒÄdç(‹šMçS¿Ÿ7†{ÉûV éØc½ù@¬ªjqÌ0=]EJ¥°¿˜½ý‹›7~èÙ][ß•\üÜÇØNì=‘‚’éxQ‡×Þ¾Ú5óŒY 7.õ%¢-ê‹ýû ™¶g†;›ïŒ¯6Íx~uþê_>{îÁ=ñ¸PƒÅ|%×M#TNÎ/üÖo~þ{ýÍ[zæh¿v $źg(ÄiW‹ÐÕÖŽ@ÇÄ1t"#ÝëMG¶¤È±ÑfÛr“èÖÁQŒI(µ*(º3pK¯Ü½@Ä5,ê²]×ü¯¸„@Hw%@ $$>Ñ-–kau'Ùxš–OåGÚù1IDM–TNZ$-ºL&£}í¡‹­éÏve“­Ê‹íŽ7ºx8m=gž´÷”ç¢p^J/-ÂãÄyà–#öBçnמ)….ÚÎŽo\Ó¾aw´ÿ^‡pî¹gž÷ሽ—ý¡B¡òÞã[ûW®Äq3B­6Þ–Qçv¶7.lkCHJVUÕ—ý­‡v.žÝ}ìÌG/}ûͼúýM=µÓÏLž÷réÛKô™¯|¹Ö‹Ž§˜;™°±± êb1Q Ú`')zF¯rÈd¿ðÁš0æ±³%èÒñ]-ëŠý„’¡ª¡šƒmïÑ×ð4×Ôº²÷Dã=_"3ÄÈ'@®~õ~«Ñ²°ê¬“kI+ûAÛu}ás¤ÄB)â()€a!¤àS_íÈ0ažÉVrUÈBKgœÛR ¨³ŽÛ( H˜Ç¦š»€¨ŒŒrºVxǪ®-¢w =>̦ٹ.¢2=ð‰/ÿÖWg<²ÜÚ¸¸3ìm÷bµx÷ÝŸ4×eÌK½!}®“Žžu}c|ñÜÎ¥KŸœÈCL-2+% #!YÙ£­­s<úd¡åïýèøÃ¶©(—Ú©0ÿÂÇŸùô3_šÔb~°&Júyoà`£$(ޱ6æm$ Öùˆ*x/•+7+NN2êr¹gãïþ4½z}@ ‡· …µLÌŠí´Äµ[+D¾;P¾“}V°'l'xÚ˜8­æÀp®ØnæU“Lo­ìg΃ #bdJ.‘Š=±Oža f ¨ $&àÄË8µ¡ÓJ¯jýiM‡²bˆÑ—ŠÂ¸fÆÒ»Îb&Aã"¶Éw€ „ Ì\€ïfIhÙPK_U7æNXtmí|ÖÔomÀ cå]77>„sý”'>6ÔË,û‹ÛÓ ÃsƒÝ2=øÉ¯~i2>’TFX“»òêkÝìn3¥2…9e[=‰lk&E×ɳŸNjΆZº$eëSð |P©‰¾–ç/nl[~ù/ÿäß-¦X—‘BdŽ(ˆÿÉ×~w>v)ÈŽ3ç !ª’90— M¿,T–,¦dÌ!$¥ß¶¡µÎ§ô~‰@à°Ä]«ëÞGý½)ór"8Ÿ’ 8xÀÈwÀÁ˜çtš’W£Ûá´hÏHE\‡šº˜¸ë(zŽŒN—ÄÜ’áLšD»®;£ûmaÆóy•IÑÇä âÈ6†D¾I]Wµv>^/æìØHÐ-K[Ò;rûÕôÚþhgx|8þÒï¥îöÁäxçÁ’x×ϯ\9¦ l\x)ª¤`>"ŸE™D_ëÁ´JzCo9³Ø8‘t–EÒ¡ãô-«À6ꃺ§´Øp±ÿÚ׿×OÚÊqâˆì£7û»¿û….̺y°À&œÍÛVuÉ·ÀÞ&Û‘dÜŠè“ .èÁÆT2!  ü ÌBµö‡%„Ô©>Ÿ™'n›%dˆ €Gâˉ«º}^KtƉýý€Ž¬QWî¨ßˈ“”R怂HÑ“óÆÇÔ&¥²AH#ÀƒO yÎd¯³sÉÜÅ@mì*k“‹ ›ORPƒbÓ&›:ÏY &nX>ðé'n„OúÓƒ²FÏ*ëeeI×áö[ßøf¿ùhÁqtÑK_› ›}ÙÍ“N 0–v±_‚ó0`q>7Á2[‹>d©# 1¥–§¤¹—]Þìõ¾¿øù‹/^ŸSôˆRgzæÁlc'!uIýÞ‘gxf:€9&8¶®³.tDRØi}¬0XçW,–[‡aíöNK¯¾?ÍbÅk¢Q €p„Å]„¸”´f¾ù°ˆWZÅ_ÃZ£ûdW±£˜§³³ÆÅ ’LÈR¤\“‘:Ó¨„€1Yd—{ÖµÈì-X„”òÑŽŒæ¹wóiÛFÛ„ªG} Ð´³žMî»üøƒ}Ô5UΤÎrNeüúÏ~vfïÒ”fNw¨B ]¢¡¡ v!hŒâ\©¹µÁ3„,O; Ü!´à"p›ò€©²M¯L:ç¬_þìWßœv±¦”ƒu[£³ùhkÑ6¡óÕÜ ™KàcÛe¹Ïû´“H”ƒbÐý²èç‹2ËH×6żËZþ°¶ãƵü<±t@/càRJ@’wq@2­Qy-Ê›OCðòZEzb« !á¾KB(Ã!1c­ICÌBL.FæN‰^ÿ¼o:Žä”šöÁsÛøhZ-…·À4$4QÖÛ˜ Iï’Y*÷ç‹E5-ÆîìÂäö£Ï·óc#L&UlÛ˜àÕ_|ïl«\¦ƒ¦&£•A©Ø&"æ.6­ qq³¶ƒ®ý±ä#PäÉ+ X$‹AA2‹Ô ÓïbP4 zÚU/¼ð½MÌ2%òb@œG,¿ò•/³™W¡™×„ Y%ÕÓœc .p=“aŽÔK1Ó#m˜¤çmÝ®Ž…–Í$jun'VFb-[gÝŽ½ÜTF@$ pL«¤eÛЉøÅ´†vZgû,W§VÓ§³Mrªu2 …!*““u‘t"}8O×QÍ¢*¨W‰Ç\×I£’Ã)rK.º®…DRY謈Œ,K#Kf£î¦D{ýȌԘEn\r­³YFHAçxAš%yr%Ý‘"ºÆ§¨T´¨’ˆ1 ¢ÀÀ>©(H˜>L”î»Îï]|(—„*u÷Ò7ÇòR£ µ!X¡r‘:—TnªE“‹Þ @EÈÏ·o6‹¬—+í%´A&Ê£TÂ*J˜:f”]Ï ëçfaÛ—ßùŬ¡¦c 2ZWÙãŸøä"€,ýÂ×Ái•gÅ]r(Œ¶¶-óTêžfïD~Á¤¼·¤<^ñ»%t±X½—½Ÿ]V%âª(9‡Õµ» 4 R¤Õ¨+^%ú€áÀš¯”WEmËÛƒ˜Ô­)râà»ÔFAPJ mÅ]W 8¡ŒB¡×4•)eB;Y)t ‹L‘w$ç^ ÌÀ-‰=s¨m¥Äèˆ;$Ü>£Æ²ùèÇ>%­'ÕÓš«éìÝë?}ëAŠhC”Š¥¤8uÖJ¡±Õ¢· ™4¥€Á(Ù©L°Á¾–™Š­îÊû;emꀵáŒnv£”™Qɼ׃ÍL:wnãÆ¿]$ºMm ˆd¹®¦_¸Ô7ªª»¼ˆ¤§µf  RˆÒ9Š~PöHyî§í8 E›g¯dK9°t-T«4 ´dâx¿NÔKX¼Ø µ”­|ÏiGfˆéCH¸*p[4âZ>¯yÂ@”‰cpJcIÔCÓÎRA:Bð $" s­«¹u•$Uè!iÉ®Õ „Q¹¡˜1dl"é­ŠÁ3»¶ÍOÁ)ÈåÕÚm?´ƒ š¾Þùù+yÞæÜ<°ûðÆ}{NE'L¢F*om“é™B‡À= ƒÖ»Íó橇½|öÒ¶p/åF‰œ¢b17$ÀÑ̶Zi!Di‡}Å™¯êÊ÷…(EZz2@  ÓÜÊÔ/;ˆ>Œ¢m8ɪé’ÎHøS©$ KÙoÞ)F—´šžôeÂ(H©­«ãë?Ãæ¬޶GÄWÞxñç/~÷þ‹Ï|ú‹_KqöÚ­·›ý_ÔóÖ«bÓìe|õÊ‹ÅÅí ¹Ùtö¸Ù¿uó 7ù™¡Lq‹0YÅ Ù+0ŒÎ©Z(ŒmH%u|ØÊ„ }ç¢T‚ÔÎhs(ÛÉlÂzˆ%Ic&¨…€bÖÙLû©<«¨mÆ‘fµÙ†n”Cr€wrßp)qÝŸfïTÌqîîÅ RâÓHa¼šÚ–î lïìË¢”å%,áíé4ª'¬!µ>àÆ¤àJ’MWÙèdâ\È$}š{e¹!ÎgnôÜ$©P0MѶ±±½&BŠž.9¦,kÔ¹¶³:0;G¦Ÿ‰þ&ÉÍýä/omè­W±³mÛÎ~ñÂdg8èâm¹ñP?Z#ûíF˜Í_ý£ÿí›ûôgž~zûÉGnN^úæwŸúµç_ýñ÷oM~ö÷ß”±?ö7S²½(¯O§Ü z¦ÉúÐ…E1MÖ€ZtÐJ6ƒ0"é„ÞЦ5ÛS„h$£Âã3;þ¸ÞŒD€ •'E¥ C+(@ÛŒ;iHb¸êZ[èã·ï¼úöƒ½¼jÌklžtïí÷> € ÜŸdªÅµ“šïê €° UT<~ÈM!,ÝP—™Bž¦óé|!AdVhÏ8P£¼G"gt‘d C-Øy#ˆÀ2¶R;5t*¤„¤Zu¬,eÌ%c7ÓY7)]– ?:wc»®©f‹ÉÂÕãé~H¹µLn*J„)±±³ýÀãͯ~ãßþÅßþ??Sý¥ßù'èº'žúxþQÞŸí¿yûÅ[G³woŽmME6$6 Ùº[R’EŠÄ Ú™ 1ÏZGu ]˳`ZERèNyšT‰R{¶÷€KÀ… "Ê$2 Ó.ÖFníˆ>ØÆ/ÆÝdq}<¹¶t0inŒBñÿñ¿üM×p>aiFÖ hxï–Žê´üÆBõ{Ùç„@w”Q.¥ž‰µ”å¸d`8Áà{…¯m úšñ¢(¹v‡ývS®Ë”"ŠDËä5·~0PÍØL.lš$š\rÇí̆½€C1ì<”‚Ÿb²Lœ"VÑæ`¼ÖBàì üÒ¢ZˆÍTÍšÃqVöó ;6þd”kIMåKªƒ){ë¢evv ëºóëÿç¿|ù?ù¯~yÔWÎøîÊ„&ñ±/øÔ’ï\?’4Ä<é])FA³‘açÖr¦‰‚&ÝÏÄ[³…èät>ÑÒI%w Ù ®Æ7ó<ÅÆÖì Ÿdl»ƒÄ£²7QÑÒ°ØØÊáV蕛ʲ”]½>ÿùwþöù_ûêRèÃò˜æÎ@Y/½™¸F¦áÓ_¼ª Ä»{D ±“KŸ^‰ÕŒ­¸ÆÒ<5k€˜S$ÙH£“ƒ˜RÝÂHåNˆ‹ù¥V–¢÷-.œ7†Œƒ¢#çe°If¤ K‘„LSD•qJ&:´]OôiÞÔ­CB,¨ôV&ŽˆIáˆL1H„RÔÕ¬i£’2óò¾ÛHJZ‹dL HP)•˜e‹PÛr{ëüàÁ*þÙâ UŠÐ¥:mªxlOÇT|üá'ß;xe|û8gã;¯4ËL¥˜¤‘Xûä=éeM’¡‹ !OMÁ¾úú›hû.3yIZt8Íæ&y…2ù6$ H{¯ Ôó­»H÷uBnZ£ü8éõÝ„á“4 ^R†@¸—™}_…  ­~ûr”éò—98;qÁÇ€>‹àA$¯-õ%`‹‡Ø!²(…6$&ë’M4‰1m.ÆÕQ3w‰TrU¦•LvŒU¦žÖx“,[FöàûR"’`‘é(EšÙ®é¤€ÂŒ2^C"Ñ&ÏÌ>£]Ã*y?žâ~J>h±`(IW}h}Õ¨²Œ$¨§° 4¶Ìµ®’ìéD‚}kÁ2DPÎ6-aÙ¢ŽØb²QHKš¤Ñ"‚ÎÆ?á[—žú½T~þWå…ÝÍ7¿ùbÝéäóg鉇Ÿ;ûçÿëE=:³óÀcO=ùøsŸ<èn¼ñãwß;V6ªBF„™›#ûógú"7y– í•5ÄÕ d_{‘sÂ\€tØ=º$ƒŸWÑù$8$«ˆ2Õµn@*J@æ6ØÚvÀ×Fz'€Â´&%Å“ ‰»3…ƒþxtNx§x×É%#úº×`ÌMN‚_™,cê¨éB^Rkïq„$ÐâǪe !¢É•R4[$ Ô+óÎ-tRUƒŽ·J-b×SEj‚C£|GÐߊÓña]ؼkx^‡¹im0vz¨YjRˆ„ ³¤‚“-X.(á‡ùžÝª7w†×o|ýÿ¿ú{_(òìùé‰ó—ê¨{Qp^ç;ߨ½p93qìnÿåß¼ôIý`ÚÚûÔgŸyà#éå¾[LDVѹ3Û»;Oذ0˜úiwpûû/“‹Öt=‘±£LiÓÎ<«(’L P™#ì mšLkÀ ã¼h½dmÚÚØ«˜ä㺸´„UÆà i -ÕÅ\_H"ËUjôûÇü²óמ_´<æ’ „•†”>:ªr•‰$dDæ4çRmØA„³è»˜¥è”«…%gI©¸a C¸q\Uû‡ ÌR–F†Ä)Y…JŸßܹÿ¾³×ŽÒø…ù…/*[‘͆Þñ¬µì¥ÆhŒÌPÔÁ¨r+éó”’¶ö®ýôú?ýä}á«VC>8/ÓâÊõ›¿øé{»ZÕ. IiúœËÛnÞ5Í_þÅ«¢ŸüäsâcüöK/æ×Ãæãì<º×.ã8@b“ºÃÛ·4HÍ$BvhÓ® #BO%5–Qš¢×8£Aù 2m¬›†¡ŠœÅ”âù×h®ié±Çµàúe¯X:9>`0ÝE2iÐiÙš®—ܨïŸIþÞ êTfXn”)vD#c4$*ù £2pÞh&å»)]?Þ·×ÚÙb“ç[hcZë<˜¶¶6Ë]s_6À3ýÕOͬ ¾QVM½qa¯߬Ú#’[ÓkÍÃíùb¡µáp¯œ¿13Ò²+‚DUPýÄ­D…¶ÑJ`-(í<²åšê¯^øƒÐ˜J IDATÔhoÇ.`G·ÕÑr`¢)4©3$ûêË?Ú¼Ý׺åôÁ³ç¸©¥ÖDJBŒFí77nUÇE9 º²­í-š¶ñ>-d&©C¡H%©rJ¡ŠS¯ÌK)ÇõÇ÷~’XÐÝ4M×pܧŠFÓ’N % {ëÆ%¹âO[ÁÒк,}¸/}=õ’PyaGîß`ª]—¬Ða˜mÚ®²ˆ =2)lð™ë?ùôÓ³Åͬ+ûCÝh©òì|Vª^4~ýÍ·š¤aÜì7¿H‹­^3½@êÚyìÆï˜LG”’ÂÛ?ül÷Ï .eqþ¡s“ö¾¿ý§çÎnB†Ba²®×ƒEç’*úSæãyC(Ww:‘mŠ`s¤­'­%*o›¶¶ÕI%î¼( ŽÍ¢³[ÅNfЬmÇðÐî§¶Į̂٤C•‘7ÞKõôz/?“0¶`Š¡Uo FÇñ­¢è·ÍT禭cH" °µ`'EÌ VÆ”y´Íjàf·d?J'S.8Þ³"¥ÕÑ®áHáƒ_2 ‚‹¹\ËÜÀ5¬®Äõ<Íòâ3‘·©Ö1·(J)¸Ks`‘DÐJj#xnIŠropþÂ&ßèh³˜·žMâí6™Ò”¦=šy%…ÐZP7R*K¬SÔ*uÝ ,-rìߪµDN]™O{zqæÒ®F®…ÜD‘P w 6 Ë¡I±%L{ #Š*fOV:Ï¢]Èì uªÅ *¸VJÈ3I>dm›X ƒ‹}%7U‘„Òóɱˆ1ˆöå¾ñÌùTL¥D¢®=.n¤ˆºëÇH²©Ç}½ÁÀÂ2$Á@çšãæY7K¸”ÇÅkƯe G„UØàztéû:Tñþ×Ë(×põË[‡\ãµ»×r/b5ÕU*zœ &’—!Å ©ÐzF\u²ÇÄÞÚ Óê™ Œ%S¬Éº)@F¨‚t(³SÕqØ)ÊFTÌá8øKŸ\†å¬ Š@mí½uûÚ£G$Úýwßñ¾zàâæO®¿±µÙs¢Jõ¢©¤ê:¡3Õr0-BÓyÈÉÔªâ‹Íž®ô¤ •îíB;yÏzÆ£GWY‡N/¶†Ã­ÖŽƒGƆ uíúìÊ¥¸„\Òì³Ï<ÿËÏìímØÈ·«7~òê»oþèo­×M=#ÊÄÔ#*#2Íq¶{ƒ@ßÛ·Õj´’Z‚\òiaxwÎh½Úö«M t÷¸¾£Z J´ŸM« U:-±êÄa³~81ô†£Ü ¢ @d¤<&&©rjÈe’(G–)ødÊ>¡ )Yf­R’6*‚_XŸ))Ùv.:Q¶ÕÀ6Qk@¢OY€2 1÷§×dÙÌ(ŒÔ½ÝÝÁÅD¾ë+¶n*Í"'–ÀJ(cZÏheI‰L\ì^öGâü~û·¤àO<ÿ…s_b†ÐøäùÔ§T´Ö™í­roZd BþèÅŸd”Êœr‘={é«ÿèŸþæÖî.J%J>æã¿òÙçí«ÿT‘KÎ 1@pž!Úmå¡‹Ä]m»µ ¬fœpÿ-ô–Eâôp5‡ï•– Dk'ZË„;ÁÄZ_qé3ï/½×“Q5ž¢Âd¶sQ‹¹…8wPu¢T£ÒVÄÐx¹ÅH²>v‰1‘Dç’²G¦£i%L¥›6‘zМù¤RF¸ýÎÑ´íc'Uyf÷¾§¿ú…ŸOn4M‘ `•<%Ùµ­¸|öÙ§žþTx;|îË¿ýðÓ{\~úËÿÙâì…ó<½ýòä…H±¼÷ÂðBwÀÓ†!Qk£`YUó¬¿ù±¯=åãDq"6Š$æá(Œúú‹¢Hµ¦'ïûåÿæ+ZÚ.6·n^;7¿xý»‹·ã“=ûÿÝ{0?Š‚lÄ=CÌŒ#\êæ)õ{ýÕ‡WMé¸ú£ðª"Wåe~Õ½$VªÅ;·ˆA.e˜¬s­ym¬«ÙOt>Ìï=ðPvKi¥ÔÄz­6ÑJŒ£„Ñba:sÐIvBÉyš…lJÖœº:õ EɱYPªÔÉBŠ’ÛÄy¡Ò,IƒXJ-¨íXH=¨Þzíg?ö‰= Ñß;·5<ÿëoßzesóI‚9ˆºA­g¶I]÷å§î8#£$±o¼Šñ˜ÓžÇÃììÃí=v_ÿbµ˜]©r{{6ãž/JÑLF1Ýýü³ÏnJæ’KQ˜D‚¹úþŸÿ«³ý3)‘¿ñ©Ïù㣤éµ7~ûÒoêä·¿sùþ§¿úû»Ýuc§AiÕOF¤"ëæa#)=h)îNø´ðÔSÓÓj/ç}ª\}½—hÊHÒ]¨©@¹ÚŽ~¿G!V3nÞWÂëÓÀ6°z”Üm?÷6Ï8^Ê:Ñq ”¥cÂÐ’(&c En¬wÞeFÛy˜UØ2,¤îd¼BÏ[yh½7œtdNÝ\±tm@5ò ºþÚí6yë @ëo\™Uõèñ`:_{ëÌæP;¼Š 3ÌæO|þÂ3çÎ_™Eï¿ðìäÚáXÌÛ[ÄyP’þý7ÿ¨=: -ä[Ãèò¼W4AÙÌ©nðÔ?½ñØ^¯,¬CAP̳Á¿þ³ïüè§“ó»u»¸ÿò“ýbÐAš¾÷ï½u8­ªg/=õ^÷J'/Ín½ù/þÅgŸùÕ×^yi4Û)¶¢<ìÚàŽë bmaûÒ¥Õ.>-KîüѬ™Ž—:ýw£æ×37Ó= ~ 6f‚Ä ¹vï¤%þQ¸'o’«™_ë8;^³?âÞ}•ý­Ä!dÇ¥N‚Øô ÕJD (ˆmk(‹^ d£¬ ÍtÑÍv‹Âw,…Î}™À(†¼( DYÖMÉWH¢Q0ĶCÉ’åöoüÝï\þÍyu»© Èýè¹>ÿÝùßMB–=¤t$ö˜ ªî­w¿õÓÿy†v~ýÚÏ\ÒΡ!H¾ÓEˆ]êLáKÛëB³ðÝ"Móñöƒ~äÙm¬ƒg *)®îû¯ÿæÂ…ÍjÖœ-ÎŒ6z­mý¿{åç<)Ÿ}â¡_ùÑnØùÌGþÅñµ+·¯Ý|ã°™WnQñ"9j”„ Nöh–vïmã°+x¢[ «“…¥ß›äj<ÐûŒAþ cˆ¸ƒ”bnåi»'r Åió‚´fYIK:”€E^dŠ[3Vy–-š”;‹EÏ; BBð!X«Œ®u°nëÍ\/Ú EAÒ5]hH’³e™ÛéLyQf*ÎåVj£0›çµ6íík“iÓe16\™äëWnþìÕk=v~B­„µqî±âbïoÿô-´::äE\Ô‹›• Ç—2×viAY&:†˜ !œµA‹< "PŒä’ŸüêóŸ¹üÄãÌQ ,øèD ã?ü—ÿz{³‡H¥D”DóKÌñøp²xw¾·9xíÕW‘ûÏýÆ×įܾK‹vvmÿ½kWÝÐæQÆÞPÇh ™;`ϨV7WZz¤§ê…NœËËÍf±¤þu|—XvçG$ )€.Çé¬ÇÝá*¸äý—ðÒ¥ŸÿàFêg*©×+ØQðŽ5 Ò'Çe{ìFy%HÁvRDmg }Ò­‹¶ëëQ[ÿÅü³^©:,ަ¡øñ¾þâ·_,t+Œ€y¡~øߺtékbT"%Å:[[¿ô•¯¼ví[/î÷ŒRÅøùŒlç!ù6 ÒÁúˆ  ÀVJ­=AŒ2ÇrãìC£ÍÑ£›—žx’ÕÌA“S$8ú Ô_þ«oÁÁD¨’aÌCµ¿̓nߺ2oe…Ö=~öÌoÿÝd~ØTm[{;%äuT » ‡€RÑ+o%ú \ ŠÄÓ2ãp-ØuYÎKxŠô:œïí"ˆwÿi !ÈÕ(;^šRȵÒcc•ÖÂ÷–©tÿ¥‹ßÿ‡f¾+TXå(Žl1Ä’YÌRè‰ÔȦM픽4{ÄÐØP@F2úÎ7]¡BbžNžüí_ÿü¯|Á´ Ð]ìœ(6F‰?ûÔ³çößýÁßW¯R®rÉ¡÷ÿþßúƒþŸ7‡)Úη³îÈfYñìÅg÷_|åÅצW*Y¦(˜M¹È8)0kÁˆ¦í «ºùü¡Ç•…‘Šêk-Îfù`›†e°ãHb >$Áÿþ¯þÝ«/¿uacËûFçÂ8$²qò^;¿PžÝr5ìOÝ®”WoÞc>žÏgl(I¯8!r^L5báPÇ*3èléÙ⪘€Ö‚—ÍÄaõ§1„àAè"„äJjoÖ §N|Z¦îÝûÌÙK—Û™NÑFV!aP‚Y†ÄÖv*žµÒ¹ <Ô Í ˜¯\Û¤B€èS Éh}þ“ŸûÂç?¦‡u;ïÒ|~¿i>÷Ëýðç·êlUR(Sî–¦µ‹ƒ–DJ™V[&¿=ëTE¶ˆÐ ¶cNk±Ñ°*÷:·¾®?ÕŠîF Ýõ¦!¤:—kW\Kê[wÒil›´–Î?òÑËçh§ïäb@û.±÷™aD4óPçS!ŠLõuB Ñ(ìb¬TÜšr*Ñ·­€¢÷¹_ÿ5 ¶ íë?ýöþþµëoÎëÈ›ƒþöÏŸøÚýÛ÷ê³{g`vÐéÞÔù‹¥ºzõ¥oý9}é¿übj‰¥tAS®#{ Ù×›»¼.#‹nzp QàÍ­ÝaÙGl(†ÎîϤÅ,Û]¤}ò–ÀE× ,QNnÿù×ÿä½w›á1‡Ðv%Êž’j}nõ.¼ø­>!Ï_¾üT”âõ—Þ)³>3õ³8¯§‹ñ<,"£‘b18WÚiåÂàÿçë½ãì:«sáµÞ¶Ë©S43ê’-[Ø`ËÆ ÛØà¦%B.!ùL½)_7ä!!ðQnnB„r8äRŒCLs¡dƒ«lÉMͶꌦ¶Û[Ö÷Ç9g´÷ÙGñ_²¤9šÙû-k=ë) ‰]qT»‚ EЗŠ:WøE±€“ÃÙPŽýErBŽ¿ÿýïçv?Öus`d^æÂKl–ÁÿúzñK_ñÀ¬FKÒHO0$ÖFîW8X'’–×Õ+Zô÷bVR×c=ߤ± t”.®\ûòë/8g'°øñ“ßö¥}â”wÉå×UwtŽ_ˆG÷þì¡‹¯¼êø‘=Ë+«ÆøˆóC;ÏÚÜ{ìœsÏ®…¡‡\#íx!—^ÕÇzs}]U«~ÎN*)Îp­NÇÆà8TBÔüÌf,í î!ÈðPŠýóüÛ·¾Ø>åq¨qâ%Èãh‰&³:M3ç°·ûØ#Á|c릹]×^¾Úm·WWº+½¥…vœ¢“ÀTµâ+6ÑΓëÖU¦§ç¶üæûþtÃtmB–Xÿ,çP$rLT^ô%á¥Á+Lq `ÆÆÎuüýï_îýñq†3P„—dlxz%qÎ^xéÕ{|¤½| 4GF÷”%2,ráROñã'ÞÛ 3Û¶{1²Œ{J1†\úŒ9HRT!ÎZP‚‘ÑŒKîŒIÓ¤×u,`@ÌJGH3øƒûîùÁÜU7’X À÷€É”ÏÁ€~ÚK8ÉNâÓ¾ ž:ôð±ûy,é,µz”FªJP &‰cׂɿÙbëÎ v¾äš×ÝpÓ/ÎÎM¡° TŽ4À‹–fkóCĆ#D,e×ÐìÖ€ÂÁŸP?+9-^'&7P¦¢ðŠ9Œ¶£9"c‘ø¿òo~òÝ»kµÙÌÁ¤ð¨É)/ö²v{ukcó\£¶œIkYͶ´ô ¯Ç1š¨í;yè÷ÞþŽ©NµÞü·\¹íÂ¥có/¸ê† o¼èÄ#O|f÷¡ýO~åö³Ä÷ÝëKÙŽ‘tZ«“Q23§)îÐÖí›oü…WÎî˜àf†4pÉ%çIÊ€¥Œ ô :°V§©Ó¤hÈ¡dÎ-·O7 _þüj¡[©V]È D» 2d<Ë4’Cf]*R£H/„¶‰O¾  1®ß0‡`ú,e—ÄÜù[檵Ê̺0ša3§@âpj¼–fÄr˜-öP,ÊvÔ#I¹Äd`’Ár®ïržŸRÛÜ ƒ¥×ÉJ¡¸Xä Ò8[“AóúºÿçáOïû±Äjâb.K õ µœu“8äþ‚rU»˜èª³‰\ÖÉÉå¸ó°ºrtõº/‚º×X¤‰¦þñW¿t¤µÚ>yBÊÉØ˜n+£º5IM{`=ŠiL¼ª8¹täsŸýôºí›_õ²—¯?ï, ‰%âB #xÅ*IY-)Î4ã ¥rÒ-]xî¹gïþÚ“);Úä’5&M’¥)XNw6®ŽÅ>gÍy×ûä_½ï‰'nʆL\ ïEqè©Í3MÇ‚vìšÜA58¶xxÓät—óĦ*ÍÎ>ÿŠk_~é#{žø—¿ùâgm>ÿù;–:Kó‡½*´WzÕuuíQïÄ)_VS­8QÊa`‘2™Uã4–2 ‡>ãJ±yëzW\þ¢³6NÍnŸ­pUõn°YÔ¡,J¹Z=±öZ9úÔ¡‡žÙ¿ùÖ2Ï(>) ¤ª1Í«0á7*3SÍÉÚ¶ê&·nÛ TÜL E0=y ÎGkª[âoBÎ~Lçèüy3cS²>%Ò”:¾âÐÈÌ€_d2$ÊJó/¢Ò}ÏK(*Ù`aNù€,îÅŸùØGî}lZ…-\²(KC©fæœùzÙ(ÏMmÒ.NuV¦ŽÏ¯V½øÙõ·ÿéI:ÿow܆O¡Ç\V÷jHj¡§í„\ng”ôj¬êbŠÁ€"W±Ü0•ÊÈe Ax^Ef)¸Äpß«dYæiQ©zT©õ²l6Î9ObœªEé2eØ]4µJ½QË­§ªVjÞyì¤ü‰ÐŸœb¨¼ÉÐã ÄXá“Å…¢œhíuæíxQÛcry—˜KÀ\£êá4F °ž-Ëú4sg@; ܱk5sÉiË1® Œ<}­Èb¿ s|ÎZüÒgÿéÇ·ßÞ¬¬Ga#gBƧ·6\ö–ãj éÉh±›XpÌ‘íéÕtçå—½ù­o<²ÿ‰;oÿV×µ–#>×SÉd³AY&ìÂj‡iòX–v‘‡ UWq¶¨¬P6hˈYK …\„Ÿ'¬’:V«u•˜õe<ñÚÆ0µÁ9çm26W¡Qß09ÎÍ*ßyØoÍ+Ê54Žl%9,²ôú/ÌÎû¡Y‘ŸýPÑŸŠúÚˆY ÉË"q*èD…a?/—H{#‹€•Ô¥yÏ´‘“ÍåjC³r¶,8è'½äñû~òÉÿ}3¬åtÆÎž›ºÒ]éñšÉTj¸P]Ó!‘™´§l9{Ç/½îšæO?vt>êoa X²2¿/w3Êz@66±Ïy±1/%Wk¾W‘ª"›6lªzRÐì¦kfxÏÈꤪքPžòA DžŸèSn¬êJÑñ#,oÌ©ÊGÜœ¨Xk°ĸ$òµEÊã¡HMî¯æ§ öôÛ¤°ë 艒`ä"°EICYËJucØ©”¢dÄÞ÷þõß=åùI”m>{}ÒAÙ#lÚPˆ¥V·^¯´²Ìeiʼn’*Ë¡½¹ÍÙÍÛ'šã+‹‡Ž<Ëz±sŒ‘³Yš0!}çÜæs¦6N5£SrzëleãÖ µz}ó\±Òܔٸ>SÌ;™âì5ÿ³˜¢Qˆ+%ɳq¹aXÔï⸠éÿ€áWžë¥‹Çm~i²RZ^ž¯<Âþâ d€ è´¿F‚M\q鱜ҚÃ"+ËÆfÁä$aî;#¶ç‘GÿöCï`lz¢Ù]Ñ€À+\1šï¶“¢dž¡Ì€•èg1dª—±j¥gÕœ¬ríO4«NOT64Ïfåös.”ʆçÕ=´R\ú}Öž,"¯6WŽX¼¸\ýȦ‡" ‡ŠDP=”üåQ×2éÆäžI:ü¨‘æ°Là+>çEÙ²9M="&Æ€{§¿Ï¾êˆ!€k,$I?+y v9ŽáÈnfãÒ±F -V4Ø,Eìoœûú£Ï|âÂ÷øŠE°ÀS‰|é÷V-çÌMö¨c•˜œ©Oøµé© ƒÚº ³3ëÖ5§æ6ÎZ%ªuEµX?ci Ç‹‡³.’µ±˜nskŠt\;œÈá0zl¬ÑëZ:+ÿóÄ­µ“Fq*^QéK°¤Ñ#X ”AÊÀ )§Š§}È ZHãü"pÅmMÃÞƒçòln?ðóà%͵]Ñ /?é2@ôÄÃ÷ßòÙOù‘ðìZ˜˜™¢6÷æšæÄÎí;7VšÁ†ãSbB¡àª>‹| Š£ (…ýb© qÿ¬øóbñÏŸ´P<;óÍ3×TÓ¸ìR*Vû0.÷È Ÿ9å(‡yðÞW¹+ž=Ã_‚K΃ðlcÖAy4ÙÿÄ @æJV*M˜0×¹C¾ `)cÉÕfáÐcË'CëW§6mߨ¸%‹—œ;ÃÌÚ]_]ÑeM™XX|ÍX '·E4Æ–ô¼cy|ùŸÔoýèˆzsÐo¾Ìä¥zžrßå’³u1 †*%Wº…ñtOˆl`j2 àà,Aš Q'ç¢ÅÔu[¬Y±œa¥nÂå¾?,%a`©ìÈAâ€å“ç,ñÜ7¢ •9[ ?$˽×rzœÉI¾mÎˆŠ tdJ2Âÿ„"f E›y(Ò¿\±É¢RSæJ®4nFœ 9tL±]ª Ø3gÐõ©¼t—ã8¢äV1•¢“i\BA5—ß(vmÒ4n¹P®äÁqt[VÕYñ×X¸ÅO_üùøq“{â¦D¹q—ïÿ+TX©2 q9# oñ~ƈ+Åȓ̕=(êi1 r\;'P”¯±¤512²E# Wj ¨h¦bÎKáÜT‚¤¨„¢`±ebÅ€°±j8–«óGªÂ‘˜÷IºXm•jdÅšŠE%ŽkÇT”›ÆŸ©üµ[VŽCÉªŽ—à„þßñrð2àú;Yh°dYîë]±Ê;%±¢²i,Û¸ÌIÌ{±CÉÒ€JÌ%wHæ-×ËÕ–+Í6ó ŽgºœÇÛY);’Æ¡~P¹bý5¢qgÀ ¡”09R9¹q'±7Î1‚Oµ¶Ó–dIk‘)À,«N»—Éò&#ê#.$®D9,§¥B1Ï7_ÍŽŒ7F*Äü«²¥S•n >¼ÔGÊ.( / ÷àl±ÅÅqm¤+¾ ¯M€L®.㥠鑟šŸá: Ü·çrŽ€¹p†9ṊJ&ý$^"` ŽàŠ3 Ü,kÄÄ|¬ãy9@­¼>F vÆN+ÀYKQϽÚX eË>v8›p¥È`,¥ƒF`œ³i”êÔ£&²âm‹ß|ÿ3£øÄáx¥]~”•™¼XK–çs¶h"äŠG}Vq•+ÕæXò™ë›–õónØ@êh`Y¢*ùiĈ b¹”cÅ£¼¿Y©tÇaÿ†¥, XxæèÊÉS½Å¥ö±•¥gØ»ÿÐþçZË+ógïš¾‹\ëµöÍȇv?òí[o›?z¤HˆÍ—{߈ÖàµÜ¸Á[ùÉ]_}è›ßøæ¿ÞrøÀ±ÜÖ¥¢AÖˆ @åÃùÈ#ì^sfÜóÁ3è¡ØXŽä¬9ÖLƒl©žu¥¢Ä Ñ'*•çk:TBpŽ„à°Ò€¸l˜†%›¤20ÿÔÄ8Ñj3a˜ûí;¾ýäC÷~ù«ÿö§öNÔwÿŸ:û[‡=+E¯ÅT°ÑþÉO~þèãûÎyÞŽïÞòeo¨ŸgêÙçŽ|÷»w ÿ!1XþcL¿,¿å‹ßÜõò×lÚ¹¹·r‚Œ!Ë µ`!éYk(êYç\¯f)È;ïüÑ÷ï¼#KÀDã®\xÙeV[p¦×ÉN-´ˆžš_2æOim;­vÔé¶Z]cÊÃB„ùý&r¯TÎ5üÓ<Ì–^ŒªÊß;âôkB´ `àe,ÿûÿ¼XÙº’ëÀHÒ –±ø_®˜à4`.‘ζM×ϽâÚÛnÿ^g¯üå_{Á®-ë¶œýă?9û‚Kï|nn‹P^µwßóÐìܬ”ýw©îÛ½ûÑûþ¦›nºà¢sIÖvÿ§›·lj-ôºSwÞùÍ}÷ÿ4ê¶ÏÚ²¥|ྟíû齓;™eñ}xl IDAT÷W«=¿Ïà“_û;k"~É«ß0=·î‹}s­9½xàfC3ÿü±›I/ýäžoÄ?sóî>µëøÏ>²aãÎGïÿÆö—}}÷ýÏó'{l÷ž÷]xñ¥ÿðá¿n·ÍÎÒñ•þé;æ6y_üÂÿ™ilþê¿||å±C?¼ïg›¶on4'‡”ŠÝ<W=Œˆ‘ñ †8êÆ úixÝ ÿ"pÄX±-î ì ÛÏ—E¥ó /£Ý@©ð‚Éçê4ŽOþêo¼@s»¨ßÞsüøþO?¹ûþ÷ì}rÿ§ÿöãÇžúþÑÇ~>ü(}ÍÕW=ñäã_¿õËXÛxç_ÿØ'?²ÐŽþê½ÊxûÛç×ã¦gŸþü“=ñ·~ýðcOvÛñsûŸøø_þùÝ_øÇÛ¾õ•……S•VÚÍÒ›Þúùÿkuyéñ{Ü’nÿS‡;íK—Nµ—Ÿxðéù…øÁ§~øøíœ»“Kqª·ð’W¿h±½§½´üô½£å+oxõwï¹õο»è²ç¯ß°sï·ö„ë:™™ÚÖ†·iãú_¹éíû–öŸßØÐ ' ,¿Ó)….7 \{2±h˜kÐ —V@ÃyÄ€ŠáêTh(p89ìwý¼tdÀ”Ë¡Š’ ÆÍ¬þ«ÿ°XØ.-ÚÙÅO.oœ˜<·€ÛÎꑇ¾{õë_#Ì6Óõ¿ó¹'‚qjÇkÿÀúMëÿäOßó¹Ï|¾³¼˜šö¯ÿêþáÿ{ÓÜfoj¦zljóó/âx°qÇŽüÄ'ÏzÁ–M[wžuÖ΋®»^Mnûà?÷ÜC?ùëÿù{{¿ÿCÿ¥×_þ«¿û¢{¾qÛ ®¾ººnúÐÂ÷ºiÜÜzá oø•gö¸öõ/¯µç [>úƒ×]ùÊz æ—ôü{÷þâ›~ó»ßúö_õ+÷þøØYìºå3_¸â oýÚ×oùã?þ³…£­ø©m^³2µí¬å‡»º‘Ö§+¹ãš— %ò6:çcž×éqE†+2Íó¸8/Îr8w?*»ßŒ °` +æX”Qª5fK¹Üá­!ͺTT¯Ý…ºHdÝöRµùT­ÑkÍŸ¿÷ƒ¿óß÷ä‘#½´}Ñå瘥£»ÎÁ•ç\^d}àƒw~³³Ô¾âÅ/Þy¹VVoù³¯fÏúGx𺗽üÐS{_²óœ[?{ó »^Ù˜š =µº¤WzÇD¥qß·¾ò¢ë~ ºô•¯ù?ø÷ë/8÷‡Ÿüêá=«Ô¼âòk "ñžïÜ÷¢×¾î[Ÿÿôå]=䉫.yµéÅOŸ|jÛæ-_ÿÉí»Î:çß¾øÏï~ϧžÝû­›Þð«ŸùÛÿoÝTåú_¾ê¥×\uÏw¾ðº7¿qjª.Ô/¼ù ?ñèìKgý0\]>0±qîú7¼yH çE“•àV쉨Ä.€"ˆ+’ \ɈºˆG¡ ÇÁgÖtî ÉvPìÓÊðÈ ÆA@,è®ÛÝñgŸ¹óK_K––SgλàBkµˆÒ»^øØÃ÷¼õmo÷ª²Ówÿè®\ýêÙ­³ý/9Ñiýà?n_8|h×®7žsÁQtêê7ݰxôÈ—½è¡ûƼàâ‹_xù+oDæ6ÍÍÍ/.¿ê5¿„’B׸솗8Ï÷*µJµÞX2+Ë'N\~Å+ןw. ?úø“׿äÆ-Ï;KÕê×ÞøbÉ*]tñä¤ÿÒW¼Fúú–ÿuû/ÿÉ[.½üšz3Ø|öŽ;.ÜuùÅ^y5îÜžµá…ç_v r¸ôº!³×¼ìºówíBF÷þðöK/»rãÎãŠÜd:º»R†EáðÀF~†f{lrv•ø" }¢©)~YÞ ÆùѸߢîZ<ÏáV˜ç\XãÒD#C CÀ€ëëå8@ÀåÆXåQ^-õ2ΘH –Cg¬±öÿó}oûÃ?Ü~Ά¶aœA&ʉ¾@?´ÿ©}Oònòâ_zâ¢Ç$_û·o>³÷ç¿û ˆåþþéò(iEÿÀ{®zÅ«®~Ù«w¹&¶ì ç†0”È]¶”J˜Ç tÑÊœç4€lÂ6<0ˆ8 VC?.Ý1¼D±ÈägžúÐ8±4–†0NÐhóm Vùp¡p9§.dœÏƒÄ Š<½¨9Gp\&ýàÝ~Îæ\>XøL`‘˜•ùU|Õ_’rȵÿäŽgoÜ0kuP)Âå&–X¿Qû½wÿe}f]‰¹© +úN³QXhÈX¢ì†Éêù¨,üYŽâ–»— †{ ?_¶¢¯@Ї4V$ѲÒËve€o\a˜gLS±aÅ¢ÁšG™ñÊÆ¢üÍ嬛Oß2Î )>ld(‡g˜K4Ã}ÜÆä7ÿ-^ê•(WèÁ8vþQä!ËþhŸrãì5òÎŒ™¼DaÅb¦Ù°2³)00J& зåp¬ØŠP1ú èÛ(lœ'ıUJ¨pTvÎ’ƒÒ²"a—•r5X.N|í4vŒ9dĘ-M1ð WX?ÿ…çrF!×"™Áz¥¾´?N~ƒÖrrùë 3fPÒ9gZ£É Ó[Õ˧²•6%ÚZyä±Gz«=´™}øžÝ}ûíêÒü‚šŸ \†Eî RãF¹ôØ}O9{úD]<~lùäbŸØwxu±WäˆB›ï~ç{·}ùÖùË%}-ÆÑþƒÿ~äà3÷}ìDiHS'~ü¾ŸÀƒß¸•H•&[ê3ÿðÑ=wÿd'g­zÇoþQØY<Öúü‡?e½ù=ÚÿÐÞ/þóç>ù·üí·¼¼Kì_?óÑïÜ}÷_¼ý õ±#'?ÿ©/xÕºeA±´²¹Ý˜£/£7<~ G/³¥£‹öú€lø½@èÑiÖrv†”䵃×y5|œè•ŠûÄOïøæïÿ·ßüè_½À¿ëÁÛì*.­œ8¶ç‰þWµ–ŽïÙ}lÛ‹/&Â{n½£µ° @ K‡vîËdÕ÷îúXtb±ÿFÓ8ýþw¾ú•ÿÓÂ3r'>zß#û|ØÝùÃ#Ï<€FŸ&fit׿~aÅ¿ù£IâtFd£^–e´ûŽ#Š<"ÞZíf©-8ðÀ‘ùýìþ¸ÕùÄ¿|‰Ö©ÕÕÅ íÕ…†Ë¬gŒvÏ>ùD·“°úÎÄÚ9znÿþ½÷ï>vd±9³þ¦w¾ëêW¼âoþíªÏ®¿á¿õ‡œzXЛ?xÞ ¶Þ÷ãŸ2.J$”‘I â†k@ÓXxyP$ #ƒa‹Ø·ª°â ´(ÍCm)×€Šü³²”.-_2uåy/{>~à=áÐHüü{ßø«‹/0_ÿÚ]/~éµÜZËóßøÎWˆU®}ÃËγÜúù+ßökÿþ­Ç¶Ì8gý€mN†ïùЇÿæ>|ի߸¸pìûßþ¦¯Âó/½,&÷ð½w/œ8pÍkIƒ±@>òГýôyÏ¿ä‚˯@$`Ðëjýl:»~êès‡nûç[šåEÛvn¿âêÿù_½Í{vªõü¥s7;ûîÃ_zøá=ò?ü‹änb±ïÁŸ8øø÷¾y­,yê©%Ù¾ý½_ÅÙ[Þô–ïÿlwÒ[9õìC—^ñÚÏþ݇Ÿ|xßrýÝÍŸÞ‚>áÒBëÔÊü¢5ÑuÚ~ü•½ëSˆ¶Ÿµý³Ÿüà×\ œµóŠó®zåÛ?þúÖs+Íma)o‚rg»" 3ˆ·-\TÊÊaÃÒÒž?!§ûi…`‡ 3ë+NxÇ^¨P¬ïÊ“¤ü-`|HźGþé=:Mwø³Ï>òÐÊÁGúñ ­5fϾáÊ×À3‡Ml˜½õ¶oXë’“û_þâÿô‘ýâ+nüÖ×ï;ý™.C­Üý·}q"ÚÒM:{}À8œ\¿%¥…ïîLƒÉâÞwoþÊ#÷Þsû—?Æ:PªAó{_sý¾ÿƒž½ë‚èBÚÓíì;p×˯¸êÿí¦¹…7Ø^x(úÚ‰o<ûŽ÷¼¦ŸZ<¼¯µØY³~ôá'é·nºë‡?ú§ÿû·?¸í›—yª÷š%‘+‚N#áŠn @ ¤A“àXjбT¤”s]냊áÎwbh²î»~û?þ…ôsý$+žr:'¶]ÓÀØÒÙ3X±\ÍL%|Þêo Õ *Èl±ËuEW¾û•%‘.Œ·‡4WÓQ)zJgxîF 6tœ£3‹þdN3éJ‹`d¾lÁp´B°¬C¢Þ¸Œ³<'?â%0§ü\NŒ]pÂ"çV—:ë&J¼lW ür9 (5o-\è2È2 0iߟ “ƒ_òLüÉFEV$”ü(F*[ä°ç¬ô “*U$yEVMGF/®$ŒŽòÖ¤bœ$­Üã&j¶äÓËߎ“ŽäS±¢ÂJk‹Š°±(nÂ2I•å˜#f)МÞ6Dýxl°Œà†6„DQM%vöÈ>€êéÎÀŸÏO/\îZâ¹k¯5vŒ9bÎY¦ñ giÛ?¯‡dE¾ÓÈ—ðÜöÅ’QãH?ÌŠ» Š…+Ý¡T¾•£åÖf¾pz|OÄRâÓKjíž’Ã=lK*¿¢CJ"D† ûë@‚7P ¹âÀÊw°W!Žü®Žô²,·ÊÖ¼P2Ïå¹ÛÆ‘¸Ë3 Wb<˜¢ÂK}óް^”œºqVgÊΠ½a¥Bgä|I¡w%ÂÈÀirH“Ã²ŽŠÑ™|Ù³¼ÂúÌ"äÀ7ã}31‹¨•fiQ»â»q9€J…gþÌp%vBþjc¥ó‰ŠëÏ §‘Îai˜N¥Ä’<Wr¹Ï ,x7(ïQ¹ß$-z # XÅe(9p8(úŸOäD‘ 2rb˼õ\±ŸÁ’›/õQTìRÖ”r¬Ä rcXÈ¡2u³^[jYm®ÌÇH»q¥(/u¼Èç·9þ–Éñ£Ê­ ٢ȥc%‰ˆ+fTŒÐ·¤áJ¶výß!&öI@.GÝc9â¸XcwºEÌ_»ÖôóÎÄ1g¹ý ãæ¢ÔI—C“Ë åü.)›€äÁ¨µîÀ–Ξµ/ñKõãÈO‡%¤+oæÝ¼¡È™¹°E©Eh„J¼ÜþúH‹W$•Ü`Pù# Rp„Áå ˆ³…׉|híà†ooÍø:WÐÚúp4ô:`Ä8_Ôµc !ÛªHEÏ>V,€G›ˢÒ|CeJ#® ¬dâŠöX#šÉ|-œÉO{[|Íâ¿Äl‘V:\ŽÄúÌ]6â‘´§ó¦e`5 ‡”YçÒ$î TÉ:p3pÀÀ¡nÐõÕƒCszdÀÈ‚#`²/#ÌEˆÁéx;ʽ;Пô‡‡Ö ®ƒ~Ãɉº¥‚ËæÎÌ2¨ÂŠ:V¬©„·SbñÈt¹VPæ:.z‚ ùtdÀ@ ܃ňdÎZ@BG„ÌšŒÑ¯Š aá3›Z΀8€2Öhè˜@¦)+bFh ²É¢NÅœM4‚Ôv•˜5½@6Y8)¸ï<îl†ÌK]âÝjË]m );.gívÚlVât•u)“(”M—‘D[~hP#)+-ÚmW©8cé{Þ5×OŸ[¤ Þƒ£­<06×"Þëlˆ`QqëóÜŒ—NWH`³As±FY¶ÒL”®º±ùÙ8 °ŽG €àŒK ô •¶·6Ë¢Hûœ[™N{àô±Ã/é+f¦š:ŽL¬µ@mcžòÔYËÒ”˜oÁrcÛÝÔÑ-3¨Xm™L:Ì8»Úî*鱊ÕFzx∲ˆYAÝï¥Z±U–U›0×óÀhÙØ÷|ÆÛI\ñe¬µu)H—¬Äà'Ðö­¶€Æ8¿—-×j5ë8—FGÎ:íÒÓÞ  óʯ&&õ*ÆYܪ4¨á!«¦ÎÄ:®ÛF…µÊdHi”%Ä'3ç{Šz9[æ ðÓë7¿š…О~òÿAk B`P*ìg§÷+`†¥}j9ö}lû¯Ñö'g·òEΊäF8C¸Ñ‹Žÿû}ˆ¥½út½*½,‰ÑólËxa ™%Ÿ%F[ã5]ãÙu»[m㔳¾´IÊB8!Ä„ñMEeY¯ ¼N^çä)`^ণø˜vµ%IÂãZÆÙ^› FFGi † Q/õâ@FÌ› ·zt¥ø2eq%©xY‘; r™¯§¸ñYœ8§¯S½,d³MOúCOû¾`ÈDËÉD“>:ÍŸŒ{©¢n¼^ •²ºãhljcNrY#ÑÆÏ&·®—.Q³•‚•DŸ_îLÔ0!sò@\]_ÉN®´H@5Fçé8JâÖ¥[Ÿ<˯ ®5ë¸UO«5%ª é ¥-c½Žä´2µÓÆE€x ™’j2Í2fù¶çmbÆÎœ÷|&iX ­híš 5\¿&0¹ñ(6Í»5©qþæ}w~9Z¯.¥Ä,AÆŸµ¦íT»L0OG-¥–ƒv C†‚<fJ'Œ9bVcJŽ2–yÜ8 WIœ1Á¥!—‚WšÍÀ:ã5ë,#Oh5TU’àÈÑe ²© ðU¦{ÊRÚSVq«"n9 ÏÉX‰&×IűçjUÁeàˆk×9G¬š€›hÑ“¾„ …,c²#­NÝffÂKWZš'Õñ:¬¦ÊËÒ´jÑ_Æ6ÆâÀŠ[Ž*N3'¤ÔÜcá‚1!cÚ  S¿Ç"—¹ÕŒ‡@¾I–mÇ¢‘ȇ¹èùzû*?£OïëÔ‰\+/±Ê“C^*þY¥RÓ zÆ $Ò¸Œ€Ær.DªS£]’d\øë76>Í<¥ÄS$Âj¦‰Ì÷”s $Ä>rKžvBpÛŽHr°Î€…Ð ºÌ`Æ9ȺBb wJ»J¢ö8fM ä"€€cl#pÎk¹ ¸_UÌ3Tóº+‹½‰°²¢[UÛ˜¨ÎpÛñTܹšÆDmà{Ò1;UÀ(ÍÈSÕ¡ ª ëMå&À*P"s'eP£n›WªˆSJ3ßgb‚ž9¹ˆæ6.–;+2à˜D±$ŽÜ$V*ÞEëËÒ<¬cŒ‚%J_‚Õ‘ÏY¦ <©|Ë1.õtfÈ8;c{IÚzÍðÅõA†àP9@d€,èt€‘°¢È,Ë 0§€”¥Ü#0žÄÈ&AÍt'€1Eh@ót–9t›ðj'ÓÞùÝUßEŽIše, ÂŽÉ„”Ú$žô-çÖƒÐ2°Èç“K¸ÍI0ÔL€•Jñ”ó€KG‰å86µ•Àd¹qhíÈ:”R;°Œ3g´ó¤ô%S>¡tZAÖ‹LÒ¨ÊâÔÔùÍJ¥Vñ­ó” =¯~%5Të´|bÈdÊ\µ^5+ƒ,Nätm6 8oÆÃnÇxŸœšEÉÉfZn}´"µ>ÏŒ¨pTvˬ¯ôü0Ô¦2 `¥ÕÓj2å„I*+ÔUouC „ãÚ#©bÉ]e«0¶J™ËRkŒœ I˜c¾¯3 :•ž 3€«E•„ôTω>æH@}¿S78öûc¤¾¥±à,KÀ˜(‘ Gi×Yähœ6ÁVŒÕ„ǵËPYÇ34B©5r€½ú¤·²œ¨fZK3³,ôëÙ"ãòP #1$/èiŸ!×QTu.V,ÓÌpM´‘IÄ)W•ÈWS.CæTfXÔNYqQ,+²›dšãDÖ¡@4‘ä!JË9cÀÂF0áOê´U©ÈÄ Ÿ+2ôg[øôlÃ…•qMª ðÀù-¡oºõ©LÙZµÓ‹¸çÙz¦Ú¦ç÷"L|ò•Ï\„S•—b¢rФ:iÄ"ØÔ8œ¡öUÍh©1 $UÒ#'RKœ“瘊9Ë€ Î¥ jUÏU²5³¢B ZŽñÈD™6ÞbGQ7ñÐWÎ2‡„¬Å‘³œK4…ž'ÐSA]zd—cŒ”3‚3_ú Â4q­êBëT×êÔêžÇjú“Հŀ‡LÉ”M"ûn…Ç=®˜B@ÒÁ¤à\HJ³)çÑC\-Ú€g…>2Æ\q˜®M{±k v·ÓV ©Hmt\õªÀìPICù°”GLCà 8”€ŠóXsE>Vžm§ÿbY*ë¶:VÒc‚¸K=“ÆõX’ %PŽ€S W½cë@z.^U«¾tIe®‘©ÔS2e‘ǰÊ—  }$"P&3Y¤mƸWá,ó…MÁ1Ÿw%`•-bÚò+ÒȬ(ŽÖ¦†3L‘Bm$‰€WR0cVT˜Z:3Êê(ËHõJ(kB›$±Âj9Lr7ŸÆVÉšŒ½jµ©=šœA±ï*“Õ‰™ÆÙÏ;ïÒ‰M&§&ç&Å”'BÌÔ˜PO AÕ–y:¬J+¹„W•T([ovÐq,”>ðY<î­‚c™dÌCàQ–Ì¥™ëʼnñ¬W—Z4$)ep=°Èm <²Én{I{²ŠÀ<>! FƒqT+d ³fF ÁTÒ!Q޳Ö8è"8Ï$ö¸Ó©6QlÈ + Yc} R %ý W2­hÝ)M›%“YØËÆ!zˆ‡s6¨WÚɪP¼Ë€yäpnÈ€&!¤Çu¬"Ý® ¥04JÍR+!ÌBÆ5¦Ú—•V<Ò)H.¬o¤A |bYÒf^C;äJYQÉùÎdUá0‰ç5tdýJ½R­2—âdè­60²Ë˜N­›¶h ˆãJcfzêœæDejÇNÉÍêÊI³ÚRÞôb{EH•,vC¿*™õ%n b«!Ú®¶Œ$§t'b ’¥cBáÀ i WBèÄ u=¨V²„„䍿z‰ Tªb*V¹Žtœ;n¥Æ™NS†<óXŕń¼VMŒØ$ÜØ}^ Äa8ŒG6:ëTŒóOƒbýŸ·‡ÇRÚ¡Kï²6¸Ðq"ƒœ1ƒÎ8°@³Yª Ylé´ÕŠ%ÌYäžãYœ0Ã8$ %Ê´íД¤<%$g.%§,jÁÍ*ÓM#ãôqË')Î’Ë6ø<5Ô‹*AµfÂH;Æ D‘‰ !™Ð"ª¡Ž„SRH—r±‡Iœùð•§”£8Žgš¡¸LÀs8=µîTÒ›ä>™“Vo\7·qºÚX·yÚøQk!ÍVŽ-wOÙŠßæi¹I”9NoÞZ ª ó§BžD1ª´¶Ü]•D’3á¡s@·ð8¦,ZE黈™ºƒ˜<ë«,K Ò¢æ huœqÖÅñI¿2£ãEM¥š* gŒ‘Š)Quqª™/H3­Cð)oÝ21ÀûÄTB`Ãq3ñI‰†,#kA“(Õ0ŽP”·Îååd®Ì¸(vh(`ÂIA(¥ÍÈ:ˆŽ3–BÒ5™ñd¥K<$²¼Ò`2r$ Ë"Æeà4c¾¶ŒD$Cøk{Ö…—®öîê-“ÂrÓd3‰'È™È8H‰º‰ ‰ù’sáR ~F> æ3™‹@@5ÐŽ¤ ©‰Îµ:YT§xèÕ=A~Ý[ këÂj…¦Ö³QyZrÑë$‡>ÇðÔÜÆóÂúº©õsÈ=Ú¸]ƒ×‹"Ýk-?øó{O\tþ‹õ™‰¦Øº}bþ`Ö ’nä(¥€Ž8¤¡¢016á­NI‰Ö£ |Dš4ˆ†ÏU,Í4Á=cdˆØÍZ2“)hîX·ÛîV\3–À1—hã„í!ð´­ÝæUG1âƒÃ€Á¨HÃUTvà Ÿ)ŠùeX †‚Rj€*^ ÀøBùJõ?F{Ö P  D°ªÒ±0Õ:Mœp ¤žbJa\§J‰e?ª"@,Õȸð€!tÐ.t{(]}#Lï} ®x cÒêTU8Í™°`3&õ¾\'R©Úº2v†µºžè-ì®´‡Ü: tœr¥Èc‰ÉR`ReBS•¡o*Ó×W§jó§ž[~ö˜§N¡˜žÝÔØµ™VNzs3œ÷ÅÌ¥¾‹uC:6·qfã¶ó^$ >ùè“{“®_i¥5ï²Í~e¢î‹ùä8¯(¾jÓÈx¬nzVŠ€µÀŸLŒ!§Â€GŽ)n—žÐ=Ÿ‘œl±¥- ãÀÕ ²EšÚ|pš||ZY$Šl§|mÈsÃb—“Ïå9ƒ€[k´5 !b€†$2«5#'P§L0N CðÖñ$ö# Ô®íÚëy—j"æ4:i´,Ö±µÌeYŒvYê¨7m¶^uÃyÓ›¦.¿ôšÕUÚ´~³`VÖdÆÈèLhÐY‡’ VÈQs¯RA8¸¸ÄØòÊŠØza½‰Gö™œÅ“Ršt€Š J©§¤r Ñ·Íš™Øzù…š;¸ç1Ye[§ÏonŸ®Î>Ÿ÷9¤ÍÔ-/»°Â<€q" ¢ÀtZ % CSt¦û“Czð8rjËœ4QW„Ä8˜ˆ{ζ¬õc žh’[ âVЭëÕ¸‹µÓIØ­‡ªÃaÜ‹C©!zÂõ AOA$)Î<Ô“~ÍSæ !ÿ>¹´O·DêφìuV0–‚qJ4*7F¨øŽKnÓŒCDgÓÖ"pq/bPŸš ¼ç¶gI,ë`”§,ɺ×lÖ'}â€q–h×1ƒÚH‘™®U k3뛜™\¿üÜBÔúžã¾ßiŸPæêÁgyª–ieáÈ3amÓÒ‰E‡(òÕTÅk--®¸JûD´ëµ¿sÍK®ºíó¿èÏÌpJ„ "f&<ƒuÂ’‡ÌvCÆ• Ò¤ó8ÀyÁI8«&Õó§ÎÛ¸ ä §ÁÀ9ÁŒ– £ ÖF«ÝædÑ ¿nœuiW 2VÝT_Ù{Ò«I›šn7«6‘ êdÝÔ Îž²Ú%ZS›{ëÈ·é‹ô C“Ù«w¸ÑYP¡ÔO±LHgÓ®‰ÎœMR> —hH]à ûw<¥"YfÀ.ì¿pg`o¸¬(é¼À¤©q¸’Æ&Ž˜`òL·xj¤ðl–¶»U±åÙÀ›Õ­¦¶.”‡a,"Ò–IÝISSŸ\—¥­ŠÔ¼I‡.Eo"‰’Ž\L¬7aª';ÇHÔfZ(§–¤ËÓÀÛ<âB¥¶]â5Üx虣œÑ©¸íºbÝz9á‡ùþCOÝwþ%Ï ƒÙÞ©“­¶v,uµQ]TdOU%ÊlOH;üð9õ®&’(Z\xfÓ® Âc  0&Òw1 Õ@fA±ppÎvb^SÈYá È?FtWžhCµ›Ãø„rä<§»’)—ùµ`1s>÷‚x5 üU€“ 4ù>ºLzõŽîq¿ê–P‘/XjÒ“$gÉT÷ƒVLŒ×ÑceŽY„ýº!—„ÇŠÚ­aƒÀûSD8³O”¸È#1¢€q> rÏf=Ș?„n×H†Æ‘#É3™D‘–•:_îu´Ô5p1%2©&Ör*2­¤.ê<È„JR‡Mš^ V “ÔÙÔDÝOdjcí\Ô©øH±‰R]éuWeNÌj‘m«o[Ø\scŸ2×íÞâr´ø\õâ‹uzQ甎"A*Ɉ‚ÁVO{õ,ÇiBS8íRm¸É’äø‘£Ï×NÈÌe±3\ÔB0†)¸"ËÌê‰ãíMTÂÆÜ$hBF‰*¢š€´E/znUd2ŽKÉ2ë¥!  I ™°,…Š  µÐã‰0 œXQ4íÀç<%Ó6FH)ª ”Ó µi†\øHà. ¸g‚€7í4 ·>æ @Ч)3;<*úÔäwosošç´®ùƒÁõñ ÉLhÆCO ¡­E%Iª&<£Ð—%œ”«‹ÿ?]oòëéyÝùóŒïô›ïPU·FÎIQ”¨ÉvÚC» ·Ûn¸Ó޳I·‘ È&HvYYö¢M;vg°c[–<¦,™2%J¤HV±†[u§ßüNÏtN·Š¬bÑÀE¡€ßÝ=ïï¾ç9ç|?ŸvQFÞÔ½Ò(¢PRKmVm6ŒÑՊʘÅÖ›¡í4.T5‹É"u¾pÝ®?{ué Ãè_üꯋ¼ÿÓ¿©on£ïãÌCߟ­îÝ?ÜvÅ2ºv·}ý·ÿëßø‹oýñå|ºÝ±ªùè:Òy$J!Ž „:5™ºÄІÃ*¬8ÊÎÅnËGóf{¹ %„€b« p(Ü;ßý~³ÚNö®?øè£+õ—®\bQMAöç®Èîìl.%3%{B6ÄÈëõÚ»«³{Ô©ëc¡VmÐ:†llhÑP—N­Q£âjǨt ÙnHðù掚SØã®6Å@²ÓIuAvÜ­ëzSÛuËŃÂú¦oÂ&jßï½<ýæ[gßÞ?¼ðõÿìõ¯þÜÏÿÿáßÝ?ýÉÿý¹æ’À`¾‰õÒ“†ôE¤D·û÷þ×ÿù„ ^û…¿ñ•¿è–‡wo~ø“{G§Fè/Šðq‘ˆ]W™ÁÖõÄ”¼d5ݹyyçMÀŠ)®¤° ˆ™\œœÞ}ïî3£/̦ź3?øÛ¿Úßý©[YTàLvn”ܬb©‘VRV¥Õ¤¥ûE³ð÷u¾«¶‡4(%&—RÙu­¨)`†>1ø(³2x ª”©#RÆ“ðµÈm·‰¶U(¨½ºZ«IÞµ]tŠQʇá$äOGøØ6ÑÃ/õy¾CŠÏ[åO SáÉß­Öã*Ï'2YD$uL m‹YÐ!!BHB$µÍëñä;¬o>h7}kICìo/>:¾ùÓo}|ÿÎ|>?¾ÓÜùñÚÒSÈwÆÃÉìúp8¾J·. Ç“‹"Þ}û?þßïß]­O ìqîæ®k·gG÷e“Få¥_ÿÅß|ñŸ·›ZoI€X¶§ÒÛÓ·ɨÁ¬ÓF2/G5¡>&­2bZu ©É1En£ÉÕáAJà „²Böx²^ƬºddHé 6œÖR@‚\×nÛnoþô/WJ:ËK­„.僡,!ø4I;w¤_).Dž Qe•k‚,µwBXá"K-´NÊÅУÓÙÀÜûí°ëÚ¥ÒVøTÚà67å«ÏNï«…ª.Þ¿w^÷+•23Ó,gÏ\>Øß³;³g÷e†Hvm§cß“úí×/ÕÇG÷n¯ÚEº“­_ß—ûí¼ÞvBÎ R7-Ömhƒµ_ÈxÛ”9éMDZÚ&p‚2-¨kêÑTmG9û(ɪ•ZW¥Z¬E™ɳñ$Ô–Š¾èb£ Ú˜¦„ìLñ%qTÀ˜éÓ¿ñBàGÏ $ÜÿHÀO|ÞÎøã´êO~‚6Êä:·cífÓvz Cu™DÁ.¤ªþªðliLU;^®Z]uâØw:`Ÿ¨°…}꨼²7 {„Qo8ÛŒk¿]ö®^l¸k1 ¶õÇó#w|zÈzÓąʆBGo»ÓÃÃ>êÜîWr²Õ¬w•›Ž‡ià*58º­M·#—ïæ|ÍuH†Ë¡è° <ëƒñºk½‹°ìHT†Þýû?üÉ8` fÜlê‹vÐ |åú«×f±[Æ3I÷ù÷¾õöÛ0PΠ9lÚÆ€Ö¶ôuíµ€ØœóMæL×/›-näH‡Íö‚ °D×’fè’gÕAmúÔ²ÄX×Ð_"ÕÞ‰Í|ÛJyH;ì˜+Ûw!J‹[Û]ì èGí~$ºø„³Í€åÃf"Eõ$–áéôàgðüäÕ …qk_íwI3ì’WRˆµ×JÒ`9VÙ‰vÚ>NS(ÖEº8˜É÷oß„MããOÃݦo)5} TjQ/—TëùIùS¥óL‡;뺮ÆÔ´#_öqÃ* ¼va'rÖ^¸²ÓoÇ«M·©?\oõ?ý—Ï_{vÑ|½Ô¾ ±>½µnšû·²~Ÿ{éÕñõ³¿}Ûr ö#íC¿…dwÙéæ$0–i­E 9ey®”[.º=¬6œ®bž~øÝï\}í‹ÓòláÛ(oÀ. Qa e¡kÝÞÅ‹£}ðñ±Ï“ „RÒ »ÚÉÈR›âÆ¡5„J€‡¦Î qU›Mfr’Ri ¥Êôb à7d‡*qGIQêŒÆ)zH2:É‘èŒà Î)<Ôà'Úø|Ï Õ“`|òvð™¨Ôg¼ÉçÅc`i]Èb“Îà‹2ëÑÄ<Ú>Ê΂‹Ê€Ô D$uL|ßË\ÇMsGªR¦páÞ|}¯—"W6½÷ÑÉÙñ]â&—&ÏŠ<ÏLž]žL‡öâs_{îäÞ• ~ðàâõ‹ J4ßвÍgW¦×«ç/WÄz/»1ùâ•⨟®‡â µÿà?gûì’ Ë‹Cí_ûõߺ¸š7õƒÊé~^ås½žs²;ú£wß;¸ø&p)•(ã+Ï]L'g«[?üèæª÷K¡h•v¯ß¨}]8ÛÇ­’|éòÚt|¼–ƒÉzÛùú7/¾P}x÷]›•'Ý-#â`ç`8:k~¬ºæ•*—b¹ét0•d3 yдVìú´î0SJ¤N×a&TB£ð]*M’h*„oÉØ”i—‹S‘•AuÒè£[Ýk_i³ûÜxT 0~˜j:o€Ÿê’YzL%,ž"dâçŸñïÉÈrMn¨J)¡·cÍe¦{VÚ¨yïwU•B¬ ×r¨AæÈúàÚ0ÇãýË_ý'ÿòŸ®nß™¼üµnÛ£tð²OMG…"š Ú6Ù^)žM«Õ½kÏï–ùõk{¦^nº¶]ûe»ÜþÍ_ß ¦?}ðG_þÑk?xë×_¹”ïçÆ¾òů(" „VŸÞ M]TU°Ý¿˜ä—½^ gtp#Uâ:egM]OvÇ_ýçÇ/»øÛ·mÈ.îì·›cB£é —&'ÃÁA?_è)š':ŠRä¾¾qåÚµŸ½ñí?þßöÄàðãeLù^¾;²"žÍ …èN[Uʉ±4ˆKL" rÉ’±Ùë6! ×Å$”J¹ÍV 7RzS €±2O…$fÕyá¬É†Âê>—€Z‚¶½E5zÌ'}«Ï{DÆ^Ï÷Í1ž“Jäç±Ä“¨þGôH ©\)4QôµÄ` ¹Õ^¦À.ôÀÜôÑûTN{XVÑå° †À¤Æ‹Ýåу[?z7jyó'ÐÏtg“M´±«Aõ)”‹’SÓˆó ùùW_äûgG‹ºyïö½ØÕ ÷!ñh¾¬O·«m×·Ë?ºýþúãòÚpß·óù©lÊe·"ÈvL…Øl}püÌ•Ýçv¦b§Ýkìm ÍtA¿ökÿ¦Ý:9ý¾õÿÉ¿¿÷ïÿðÅ/Þ8ºèõD•g¦©¿ý“?½mú1ÿ8‰á@©R€šä²‡0ùŸÿÍÿ¾ºß®îýä'‡_{ó7';-†¸ uYî´qT¥eŒ$eŠÜ¢T ¡°:`k<³&cŸúŽ3›g:ô±’a«¢, èsÝ:[£ç8FANšè çØ^¢Ûë¶ ÀPàcyÅO QyÎoŒˆê©}|”ÿ Q>Ö&z<˜ rãõ”/’k•y"ŽJK„$ÈU.ÐR´IѰI0ø°9R²ðf&¶ËeGívy¯î:·Xú$œ‡Bµƒå®+1„•gÓ]$§M/9v‹ÅáÝm‘-ïv!¤è*T<ÜÙ™”ãgËTe¿66eüÂÁkùPëá^H q®´”µ±–>úá_Þû»C“U­;=ëù•ƒ«œ¶u;¬*ýKo6ó¾ûÁ½ïœÕõj¹~áÚ~49µMŠÁšì(Á`wb¢[ø®;Ü.Wqxuqå¿¿ü{µºúoþíõÁÉßÌo‡Ý ƃ‘,0Œ·ÖÊõa7й€ -°ôÔB!„d×à,hßù¡u‡*.Œ'œ)ò½’ÑÉ(BYØÐÉ®÷ £È„{./íÈþœn$?‹<ï>N»Aà'Måçq7ä“%ŸaY$ª†“ÙkÃÓîi”q…QV™ Ú” ‘"“£4è»0‰áè0…Ô¡½·ìq+;ñÓæ×¿øÜÁ0Óâ‹nqSîŠ=Ì ®œ¨q\Z‰BÌì@‰Ò`Ü9Ù@÷ã™RÍžÿÆÁ¬ÜùJ5Þ-…‚|0þœL"…€b˜CH %<çÿ×”¶Ãaå2úMçÛXŽ©^ºLôï~‹ô7¡‡Ã×ÿú7ëóÿO§¥R‹E»šä°vͼÞ4)æA‡½ýñ‹o ßúî;M|e¿yþÖñ½¿zëw¯¼8>Ø%Ùb–%ì¨Î‚òä´µc¡EuÙˆ•'FXXE(SBa±QšMlW#¦Ä:Æ"y¬’‰ͺ¼(ð,Y\wûÀ6F€ +ƒ"ær£$`|$À§ˆâ¼Y”ŽŽŽF`RO.”>~9O"Úžæ>ü—ˆû†™ -´–œs A÷JD %t ú¦7ëľ躣+£óoðü½ñÜËÿן}çàÚÁÏ~¡ãÖŒ~l¦ ’‰“ Åò‚# "Ö}Ô@.Ôú!ô’!2´ J3t($ 1‚ЀçALB"K°:PŸÙŠ`žil»F@à›-Ýþâ­ÝGse³=ýöŸýþµéh<çãÉÉуo<÷ÿƒwG«bçÒµ : Æ ›ÄÙk_üÊ­~*Ѽtéõÿ ©Z+Z7÷s9¥)u^TëÚ>IiÛ¬]Ý{ºŒ>”F&@Å*õK2I#EÈIn(l³@ÌÞåRÆõ°éR)ØŒ 6çéYÁHãÙÀe( |ŒayGýÄ=‘p˜ÎQ÷üdÅ÷™:숀˜@x)˸AH‚„žïß;ü©|¯q=s ºwµ‹œ.ÊGélruÿ7^ í"&.% ¯\V[÷ìµ×FÑõýÎø‚–j±>X°üÙ7éæñ¡ f08Ý,ÅÆÍFAk)híüºöS™‚t ‚&[­(ˆÒàš[`#@+çY¹Ú‹Vk¢IAiшw ¥*Ñ»^(S Ò)a¦d ! #àc—»Oþ\ö°äC ód;ƒzLNõ4zŸÄvà“Á÷‡ÔB[Ô‹(EVSb@°1±óCX2Ø”DÇ]§m§M<íê·Û¿§oÛõj³¸ÔÌ&·º²$†Âù‡gB B‚&f$&ÀÌ)E!4J ä'"±wN¢ŒBƒè%Ñdª .ˆ˜H˜´Uó x”Q?%A$@¡Û+§§ÃðyAñ¤Ž•R63k)øLHbfðtÂ)èÈ€Œ Õ¥z{:Rƒ{šsPZ˃™œD¡ÿè?üast¿Ú¹úâ«Lw´˜$ L˜bÂØ³)ÐJHëU •dôÞ%Å Š»ÚSEÀ»‹ZÒZR+$n}5œ§¢[Üò*&'ýOÔaZ¸££{²Øýg_þ­·o~§éŒŠ´.DzO™Öš$®"­êj IDATW‘%T£¬ãÐtÒXôJHE)&¢ìep‚K/W¯ÊЂ,ÙD¬½)«Z‹ „U™Îˆ½p1*k-œrCB’РI­x:’Ñl\˜ ±HÚi³ÓuI JÕE=EcËt–bÇf¤ÀnRJ}¢H¢Âà£fÖØyÆQ¡W8Tø°)ô°|´À PŇ ú”½óø£5ñç± §V¡Òr2iæ÷e´®îH `Ry¥È°ÐÖ¢¬ÛöÂÎN±dÍéò؇p°?ÞÙ«ÅæÿýÓïPSݘ^þêW_^¶Îl“Њ³j»%‘¤H¨L ¡n¢‰±Ð¼R°Ñ¬ôÉÑ™*ŠØè.lLªëN­œ[¶ëq®ç‡p*+‹XåÚHI+‘uÌñî-ÚSïÌé·—·;fW†ÀžŒÖq³åÞÀ˜Ø»‚, Užc_M‰k–²a³­V‚2ºÊK‰”F©U¿ÉL‘ÄCV ²z¾ŸCžgzÑBr¥ ΟʖdžP¤¾o#ñ"f[JšÅýu7AÕ¶Kí7Ž'•œZFAh˜ó¼wy1‰£XÆE-á‚uÀðo…ôä<èѾ!'€óñžƒ«èIÁñÓnTü<)ʧ¿ÉÒåZUX„W¹GР1§¦äÐZ¥íÆ46Näñƒ3—6»“ƒôZñŸ/¾yø¿üOÿî`GÝínÎÿö°›>y”ke@*lR°j‹J‰Å&Ë Mf À M2¥VfÛ”d½Ú†È¡ïɨE³LY™ë€È`„k(ªÙ)Ó©õµ˜¿{rtßî]Ÿ–AV³°=‰u*'—÷”°„'bï¼J°‰ädQ–Á&ß"‰‰¬tim¨l©1‰@PÌRʳˆ¥8Ð2º’Ö]3å*dGÒMO›ñ¥Q‹½*Dä•_È©’#qŸó]ŒY:)9‰Ârë’A‚’átI½ì±UTˆç/~Œ€âa,ù 6èáë@?…Ó”Ÿ—EÁ§VÍ® kîÖ>G« *A½.lŠ™$  ˜ï×·òKu_ ɦéhÚÚÖ÷“ûÙ;·ÿãoüÎ/(‘'¦:"ëØ·dG‘\94)5XäRJed’^—²ózÏî8ïEÐFè,Ó1A¬lê¨4ŠIJH)“Òä<æN°IYêø_ùæEkU¦Ë¾û“ï<»¡Èõsœ<×Çqëê¤Jéæ‚B9‚çü­“þÍ+å8h3–ѳñ•Ú/F¢SHž ü ’ÒùmKµ[wÛUÓÈZ™"®{Îb½Ý.NNïÞÑÚ ®7ëL ðpñ Žå=];2dV)J?·*4q%É`ߌmˆã [) œP …Ž"T„ŠÂPF Âb>ØáAÄÏÞóñ±8 Ƈ}~¢0|:„ô8T<96ü,/ZZsØ#všHBB#ʸõTh©™RJB‚ØW•O(ä`8[.ïS=™ŠüÝäöNl¦;V))3r€,ÆCJ’Ìr)C̲rh­Ð™jEã½KNh{V€†mÈ÷òP«Ñã¤j8OQφØÛÂ`Úô4.JaiÝnFqÚ÷+:¹ûCç4ÂP^´ùóÂ,¬±X:PƒñL£–ƒLcçµTfP&§®¿œ_»›Bh”…;ù¨bqëø¡¤öN8ËŽõv7§Í …¯‹Éõ¤h¬²6Éé„Tt=K+íLÀðj‚1„do\ßsͶkDu‰Qyþ™Ÿû׃ yÝΉڦ?[.NÓ&vMÈSß7ÁŸ®%‡ž•'òF˜( @$WÉn¹V™ÐYÓxŒi*Q’‹dëm‹„¹"ŒªdÅØòÚšÂc'“ ïo·­2‚{îÒý?ù«[ H0~ÛRU]þöïüÎÎY¹p ¦¾JlôFwíÜ‘:Õ’—]²JpJ À*gTT,¤Ê´!F79N!QKK/¥è·ëUJÁK@'r+·}ã1-Û¥@´¾; ý9Ù±÷M×å[qôÂŽÆWu¼¿ó£ðr=!HÚÚĺ‡CQ¯ÏNX¯ß:<­r «n¥±á>1“ÃP˜B) ¡K"fRõBÅ6ðP–·»÷¯L¯&Ø-ëÇ·è¿_Õ}¬›î`¶_LvMž¥r¥õ¾NÒîätlé…¹tmèç`K½ûÌ;s @RØûG„cülK 1€6çlc|JÀŸ‡ú‡'+ƒÇ Õ¬XôYÖ‡h³*RûÞ$„ˆ¨,   å…?£zÝփ݌æti — E Bªé,o½—™hXbJíª GõY?ÁK¹¼mûá0lPb“÷®ˆ‘€S‚~í­vs’…0r³9² ¼â.¦¬ÁêL¦1l©2ï\/šc[íd•ZoZ˜d×=.0~pçcEZQÝÕ™ŒÊ'áúØk)Þcþ=²ȪQJc%Aˆ˜HTÉR÷ dn %9–'«Ñ¸:½GÊ,G³ƒw^{í ¿÷wõ¹‹P¡ž‚#|´½ÿÏ¿ù‹ïŸüA²D5PMÖuGH$(‹õÂ9[ì [ïòÊ–ml×Ô.·šS˜<*‹²£©!VR2"zÉ€&,È”ÁDÁ$òLÕ´Q>†Êä¡éÊdBäP&„Ð;…FÛŒ›*LNÊ`RÙr—aHµQ„DDRø0ßHö=FåϺ¨Z–óùñ¥åúÁv9n‹{úSRMRZ¡ÛN/Ú¬ÚyᥫÇ÷o9r4¨þ¡-?t¬ &ˆ (ÕcO>å]ƒ§&ðÙ„pšëŸÆP{õbÍÌ™ŒŒÜRDHÅØz­ÙFé×y~a©T£\9?ñJ•&¥b ì *šä¬’”­µÈØ‹·?~kÇ^ih¾Š4–y‰Ûe~Pɘ©è í,.ÑÇK³Šv÷ÿ‹ÿòë7o®ëU¬PhI`í×^ž©åªrƒXTÖ*ÏÀ'Á5JÉeU³lv‡·ÃP{)ZËEÎ$•B­¢s…ÖìQ‘‚¶8±d "%ÉŒ¹%ErÈœšˆ u"©ÅX… "‚v)p,„fJu*Š !™üÚœŒô~¤X`)ÒÑŒ±I ‚0{ÉlÓù%ÉXFJ.2GÝ™­s&u[™U4=­0éîôø6 ¯ ï¨À‡DJ¢Gփǂóÿ :oÍ ®‚§ÖËø©ÂžBš}B²E58ë·½²I!@Ì4ÚÖ0=(ë¼Nëb^¯fÙÈJW¤ºŽF£aŸHÕû¢Wå¥ñ¢Œ§XY•—]9™ª Ô¢a)”Äè×mUíw»v3Í‚Ú{·÷¦Ï¼ô•Í÷þâ]Îö¦Wf¨Ú¼]ÆWÈÙª¦Àê,gaXuÑ^Èòm³4qkªki1Wy)<(‰( k‚iåÏL¾éûI&£CId|©A¹o•\ZŠFh™PÒ&j­•”@œ´†R+O"ö‘A€5&º:ê:9tÚÚ\`õ6ÏDAˆØY™­-bSè ,RÐeuꊄΚaщrÇJ0!ĘB4É<¾ís¥ o! ˜žŒ‹ÁCò'¸ó‡_çO9†ô¤ ŸRЉ'5ŽŸð ÏFÃæÎ||õRð¥D[V"# .w¾§D’+k!HÛÅØçÖrf‘³ ɹ&ˆ=úžs&ä@ñ¶ŮΌ\ ä|Àe÷Ì êp½ §³‹É@PlœëÒjyçîÛ›wÄ×~ý×®fvµ^ýî·ÿh0ˆ:íùâÈl*¦¼ç®¦sMìƒ2…­FÀà&Zl³²FËŠ‚TÒ•j6ÊžÂ&öÓÜ(¡ å uQ™mIvÞÈJD6¥€B“°RkÙ…äF2 äÆˆÐ+€Ôu,e¯³q޵ ¡…Þd2y às雳3‘ç#]œt­(„$ï•Öm@}ªîb¸¤©*TÛ„ŒC;UÜH·mo»àíh°ê)§˜ÐΞø» ;@|2LŸÂ ÎiÇŸœ#‘zŒIñìÅ?‚²ÂÏsi³,Ë"FQ Ù˾ѺàI%ˆ A2¦˜|ôÒ RP…åLMvò>åÓK]ŽiÔ+®jn³gȶ¢/ Ù/Ý@£W÷OZ)N Ò|óŽÈÆù¥et,O÷6ßýËïÜÓÈq|mXù4 ·Cw9ÒÙ¶Û—À…E»˜¼øÂâl‹ ºÐl%rQf/òçéÅætáÍ!÷;/¼úõ /\ùïÿ›ÿ¡HÁdI0*ÌœûBRH R£bÐÒ!=,‘`&y‹‹hPt!Ic%x£”b6hR2)öEa[ÏÄq±iSd*T’Ú‚`a=MÛ5\‘$CN*Ñ6Š€2F€y\()Ø©$SbTÜ;‡QÚ˜ü¦¥LÚö‘_ üh«ì“ÐÙ'Áó\ºÐêóƒøyšºÏˆwZ¸nÛU/1µÀB3 CŒÄQæZÕ­'Íjï;ÿì̤<ÅAZûÉ}pºÜt}‘ç«Æ§f(ý²6K¦nÖ#Õ@y¹¨÷sf¤`E^Lò|ux÷ÒxHÕD å°“«{RÈÃîøøðîÎ,—whúÒì¹~æû‹·øÖð /Œ[t§é—¦`2±é7ßùÓï–F+n·q;ÊC!ãY¨±¾¸_|ùdÿ÷“›Êát‡'£Ùt86ñH&P1«Z`cµŠA˜B¥®Ìi… ±õC1ìݶÈ')HËñp¬Bâ`¥@Ébr°T1k°0µív«Û%­!%”•R €@0¢Þ4PÍ„Zj }ÌLD’*ùCŸòV}&£ãQ¾Ýö xÛž˜d=nX(€„ 7ÊÁÃÔÑ9«æüø‰€ =éHømzLóð4ÆàüiÈvÇj~K_ØR R@±7åŽsë „ v¹0ì¼h ©ïé0üÚÿì~»¹¤gz§€Õ¬©>üë?»óúË¿Qäd¶ß×g]Ä÷¾ûgùÅ«¿üÆoìög§SeÏèâwÎMžýi‘zîä¥~ý㻃éu× ܨš¬–w‚@”à—MðœjNÐ{ˆR';-üÇÛ³ò—fås'‹Ûã :Lb0Ýëûó‰´RÏ´tåž„ Q[( ᄇæ*–Ùe‘ÙÉÅÙp˜S=O80Ùî›áÕI•%¤B]=xu³æÍb`­+í„~ôÞí÷?ø¾i§ÃÉ€7ÉSh ]´¢­€HéV™5ôãð WЭ²L²dŸöÇ"’nƒµ˜ ]¦(ƒÑð¡Ù¼àF“+:?¯ åÃa?ö?,˜?­þ©'+>ñym|R OyÐXGWc—S°R§½¡ aY“ä (†Ä$©Q`zrÞŒÜ1ššË*øÝŸÞù¹É¯½ùjn­–F5ÍâídƳ.â¾*Ú~2Ë«°É ­Üƒí;ó[?ô/o.œ¬îÕ›“õi}´si¿[tU±ó…×~ûO>òË嬪V[ŸÏv/<[½†ÍÛ¢²H™Î!t5’}P¼ÜÄñH±Žh`‘›,Aì‰rç ˳é}Ó7¤ÁÅÔo;^¸&+ €œ|ôÆæ†/õŽ<¡¾wº ‰ì«WAÂp<¹n‘·Žò0yýåóîäîOýØÀg‰ ­±”å©»‰0kcLPyòv%©Ù÷ k… Š ’…Šh%"$ö"d(ÒlÑl’­Æ>Hckõr”€8<<âóÈ:E)}.®†Ÿô¼ë'ƒßáG»ãM»Œ]‡¤MM¨S: BÚhM®¼ ¶…ÄȾ0}57EÙfûÜÂ*¶êâI·•ÓQ.õ¬ìo?¸kín M¬ÕWŸùBPe–÷þç¿¿7zf;<ºìŸ¿piç€æ§?^,¼S1c/ã¥v5ѳQy0)J=ò~½]ßüáü`òññ®.„ 2Ö!/sÙ»¼m–ÍzÝ^ËÅ«ºm†öª9¶Ê;éCŠëŽâaºs›®½ñú°ó¦îM¦Ó/ø˜_»¸sé• ÅÆÕ0oÇ ÝÃfw¸púÆ—Sê…A¥òÔÍ»E;=˜„~j"[WÂõ<ÂÙ*[ÖGL’ÔõR@‡*Ó™ÅÙ2 Ôl"0Êè“Öy‰œR‘¬üjvš¸ö±o¬xl«èÑù¦sù~ÆvÎOµ¿¦'uŸZª¨¸0ËM)­Ä$bm¡IFDÎ*“¤”¼u·uÝ\›Æµ˜Û,†l/ËfÝ÷¾÷Çÿð÷ï}|²¸u3—×ön\TV{Ú>õÂF¡Zïþà-vòKo¾ùü×_þÒK_ž>·ßç¿ø^ž²/}ù+;³½Ùî*—ï}ü££›íÎàF6ÍÍ0·#M-L«ÐöÏmOë>Û «Ò «LVå`¤â^YÉ PE¡¼*EÖG.…Ébˆ‰ÉELìÑ<¹ÍxqýÕ{Å|vçÃÌt±é|ëûFtbô,Dã*_K(R‰"°£iϬN¬︔E9„ÐSHŒ•J9&` ©ÐV cŒ"H‡›H=k!M*tÌ 9DAº¸#£ÓCJd‰üè°Pã=zÚ®ÈOIä?}F¼„9QÞ³KÍHjŸ¶-ª i›T0¿uΘë:®;Iû(¥WXó´Ûé_¹hP/URãwßúþÙ{Gã½g¾ö¥_håZxXKúèG‡È§óÓk¯¼]£’J²ìYF·™i“•Ћ6.ô`SŒ+%—õm ¼ÒPub6¾ZžôíóK'ºwÈ< ¹‰BŠ9d.Ä! ­2‹†E ¹Í’s"DzPB)Q­çýÞ¿ÊËÝ‹{Ó{V ÚǣΠÉÁjÒ’e|s}oPеPÉw¤S’"2¸.n§v 0³2nÖ6º6Æ)%cfEÓ9S9¿1’"”™’ÜÄÕ\ŒF" •©‚ä¶â¢N$H%ê=è” ±M) ޽zç¶¿ó«xtpçQ$Á@|H…§|gŸ¹4>-œ‹OÖ†!Uû­òK>lŸRŒ>죖ê”:ÜF­óítÐlåì^ð5õ#ö­Û4›ís7®¹¸Xרò"›{ü__sIS¬Wf¤vôÎý¾¯d±¹Ý8~ ËýÅ|±·ÿÜ…‘#ìðW•& ÉªÝ_yãgZyt÷æÃEeÇEhN®]Eå à¥LžHi `S3‰JiQªx¶Í“@“âZA oú¨¬— ‘Œr5A@™NJµuWŽ*€8Jüð±)àCÚê±úŸž:l|2‚Ÿg¤fÝb¦œè™ƒaÈ´ 5(QGU Ý) σ8ÈgXï—©¹ªã0 ´ Û[‘kNïÝ?S ·Z–¶Í¾ôÚ7Ý ýÝ÷76ƒj”5íæ¹«¯þì¯þòY³|ï{o_œ¾"«¹ëa d²ŠàÁÁµËÕ` ´vÍöÖ‡›ËÉ«W¾aò’2Ïcw|œºùòp1°÷u#Q·†D´½w.wž IgÖó™§()‰Ä©£ÑDC ²´Ò*¡‹¶Ðå POƒø‚m¨1dV€*%Dî’—J¡r&Wƒ\äõèL‘B™¢Î1i³81úqÕú¶Â¡0”HD&fJN)9ÄDJ‹¨Sˆy¦ Íºmä’î°Ç±šµÂ È t…‚µ%H׸'jyTh†jþD„Á*õyþzxJ•ŠO%ÕŸX, G½ÒJ)FÕ$ŠŠ ’ìd<Úž1Y°E½iæ»í”i¸ ke¬ÙØ •cÐå Ï~áÎü/}˜îílÜß¹|pøàýÑâÒŽ/Mg9a„z°9ý“oÿé‹WoüÌ/þ²RÐh/Ôï~ðÿÀ˜/]øÚާ†Q@~Üß]¶q<’jO î©Ìü±ï‡0€iµƒ˜[©KíiÝ:F°=—¡¬ŠÙbûÖÕîEïUaÕPš´laºk‹TTy1.RÌOV½o) òÜd¹joQÒ}ØÙR2JÕw.Ë:Âû–^f†ZËŠ ˆ.¦(íÆAÑÈ*oI9€‚ ®—cjkeŸb†vÓ÷C£2ž9\€È{tb!¨«»¨‹FÛ~믌†[¾©Äõ~tdp'ïL¶ +A|ìŠwnX>¥ó£0DõToø3¦Rñ¤¦ô3®Ì‡yßjrMO&’5Vö)E6 "í½ºyöÞ7&¯,Õ“¹\c®¼©[Èé÷þî«ßü•ˆ›*O/ONOWg+««o>;]×e%ºÓÓBénÓlï `ÊU&]"Zè²k6Û$¼ŠÐÇòò¥ŸµiQ¤ã{KœéòîƒÅsϾ`2„£EǨK!¤ Ýr0JŠ\¿.e±¶üâU}÷ƒÖ"tFÛ¢Á„Ù½™‘‰Û:Ƭ/2d¥­Nâ G¡X',E›ŠªGGÛŽë:F¡{èD(Aó ·È$ Øiù£XÙ݈aÝ‚]ŽT¯RÖT`t¢ÿÿéz³I³ì<윻þk¬¹UVUWWoÓÝÓ³r†›¤‡MR´`´( 0@Û²ô@æ ž¿´Ÿ ؆lÃL aÐ2ÀDR¤µÜÉg¦÷ÚsÏØÿå®Ç‘‘ÙL4…¨¨ŒøïrÖï|Ÿ†®¡ÊK#ÀZÉQrä‹Ê³7flD˜¶e™ƒeXä!z»TÀY¢Ë‘­fѯƮé-#0±LÙ­¾ü9@’°"^ÓÜi-:IA¦Â1BFH¸h늢‰Œ˜Â¡ÞÍÇ’$JM{÷´nĈ›6iT šq%{«¨!«zóvΪùÓ¼Óýà½ç÷û÷{ŸJU‘\\žœôŽoêöÓ»Ù›¯-æGG/Nû¢¬Ú6t³NÙ4©.42.÷ó—¸f—gç³£#q ÔL²lܧ*‘{±—Ô—ã„ ¸y¬U"9÷œsÈ¥Ld."CŸzûeðÚ‚îÈ)! xÏ IDATÉDê{“:æ^ð@)K@ñ‘ŒðAB´)_ÔÔ™/Ä4šršyO-BÛ+3¬œœÎÙq‘CKvÁ@Ó6Qr»ÀVk)Zy#½àŽ ãŒÉN¬/r`Î(ÉúkŸËf±(xþÃ"•¤aŒ+ã¿B™À%º|)­z«ÀÝB‹àÆ Ú&F%¬[M›ãJ,/‹Úø¤«v¸¬­Mx¢‚AŽý¤ #n=š$t°vzÓ3d-6#-“"ÏÈæ_zåûŽŸ³ªÝ )«9äLüÀ×¾æÜÉ{ïý‰i)›LN§sÅýÝÁÂ-ºiâ÷]šó´§½mOŽ&eÑ¿ûÚ½T‚³Á[÷üéŸ0¶×û­ØÌ2•¤Ã=W]s§þ¸ɰ¯ ÄA÷ÿâ÷,àüwÿåSÉT yclÍa74-õ´SÝû¯èý¾dÆä*N}0±’–¡‰’LÖ–ƒ½$–<Ë¢ä!ò„³¶ÐÌcC<®'öLY´ÑI4 Ç£pœs¡UÐ<ÈXw{çbp°Ff9ÌFLDwÞ±~¦¹—€9EC¢p!8Å÷+ùŒ7‰Yrá" Z;ŒÁ³E”ÉÏׄ4×àŒ­­<[Û ‚ ™øMró¸–Ȍ۵£¶a«T”8—3¡SÃ5­ÑÎC Œ @8xðZeÛƒa1:áiöôè#Õ°w>ÿU.e5¿„qm}üÑN§ìí‰}–§˜y19á )C,‰î>½³8«fÓIÿp?Ž*Ó\0oнá[âÇ~5ÿ†óPW®§G–vÕh±`¾°Ó)´C®³©dq·+ê{éðÞfóæ+åëÏ^œ¼™&Ÿys4T‚1ƒéYöíhq©ƒœ£–ÞbôÄÉ_SP—Ý{w§³'±B”<ñd£¹÷ˆŽÅ(ÑyEfîB­ck(`äYÄ7®î¨˜Ä!“•2¹GǨƒCa†Î~ä’‡Y‰6èTcðLd³Y}™ò9àÎMRê%ÑU4°üCàŒmèÇž2m«b_ɰ+Õ› ×eÚ(0NÄ•D€+`¸àX2JDPj‚z6rEwqG9Þ05Ÿ–B ϸOŸ<Ñ¥Î{YÝ:QÜIyç­mZSWRá`'‘iÞ-÷öº=æ#Pä-òz =uçÎáîð@6q¶˜NªKëæ§;÷î¿öΧºšž>Ùœ=¹t&dŒ©güÌ3†2ªèÎåþ«ßèõ^Š‹Žh+ÞyJõEŽ‘‘dBš:BÔi)çãQ9¸GöÅbvñÍ÷?8{ï2Án™È™Tæd0j œ%M8"úT¥‰aŽ U˜ ˆbôÀ UmÖT ÙRÊd$HXe 0_`¬]„F´Ú&0&„RaÎ¥L°Gó¹z/… ,)Fç‘’„Y—)&pA¢L’$OL¹QâYO_abÚµ"wšo˜úØb¾Ý<Ü<4ÀêÅB¥ªL¨æ‹¼ÓñÖ*M ‹lVU‚´i$˜û©çwËa£ú2Æ-W z JÈ¥*rèͼô U$8yòQ·èœœîì¼ñÎk.×Ïž?‹3¯Š½Ž³.GÎ]K ‘ J"àEáí|öâ,Ù9<Ø{ U²sHM5:Ÿ<ÿèba_$ebX_ü¿ÿËw^óõxKF¨È–ñ&‘J`€˜“PgmþÅü¯õ/ÏGš÷{½;ùëå³yÖ敊¢ª'É> 5c):OZ;ïš`BÒ‘ªL¢¨¢ ™ÇÈ`œC,XÖ´3R 4a#UV„v®(H#AZîd˜eš{.äã_t¨ ah¼%1œ“É9ö0¶ÂûQâ|R²^'‰…È(ñã À¯50âQ+3Š"Û¸èl7À6@èqà ˆõ›¯Ê¨ŠŽ 2©sV nê¦4ÄÆƒ—A¿ÛYFd˜—’!6UZhe Œý,ÃÎç¾þÉ†Ó‹ã“Æ¸Y¸¨ÚîÁtЍӴerÿî¾ÖðüâÅÉ“ÓÝâÎððåÁîppïÂâòt4›Åþ~/KeR*lc5kù…Ë;ç–xDÎcìåó—©/æ\årØ¿s'ᘣ®úã"ËÇu¬°­«è RL¥Ÿúň^0Áíø¤3>;ιi§BŠ(¶»?OÏH`à`"gœ ªçœž‡ȉ³(¤œKécH`.•KeÉEôº`dÓZ2àhêó5㊉² ’ØI™dÄD¢ÛLz„(`>HjÌÅ"¶S¦ª€íZôhð]Ï!]ÅtÕP© l€ hSº9~׬Æ×ã(!Rw¯Äàû‚9¼pLKÞ¢Gfu bb2óPòiÎs6Nsf´P•¼¦<›œ>ØÙyçG­™«`Éwßý÷¸{pçÞëo;cÞ-êfz6K¥HwRL“í‚§™cóB d¾ö™­Î\‘±bç^U7/ž>’Á×󊳼<¼óà~à»\TmT,«'Á1å{`ÊEZöf/Ð@keý¤ §q,ÕŽJ·²·ß}QŽÛä~¿áßNjÆ<•ó˜pA .³à¹ÈaüÑ4ÍÂ7$BDÆc’+Ùp/—ꌉ4x m´Óä¬c"ëú=AoÚDîÍëË‚´µÑ‘w!Ehd. ³e†dž†Öï£*Éñ9Ëw„âh ¿¦©f+ü1„%¯}â”A܆À6Ü7&V7éÄì<'  ¡ÆHÖ»ˆ ‰91PdT9”ufÈZ®N’v/Éœ£Sꀓu[O:5,D¡£f„Nê\JágÓ&ÆØ4ØN6dе~Ü<_¨¬h&#µ7¸ÿæK¼iÏ^<Ž”Z” {^IrÙÔ¶^dù€ ̋ҹúìüCœ“Ø0Ñ·"My2V —Árçõ„=;z% dPiúæ÷}oªª§_ä/ÿ-úZìäú’ï™ã¶rX›u÷K¬&€¢A’©Öè1O“yz6™ç6O2«j"Š6HÞ' À…h¥ çxmø@åÂÑ 4®>9=ÕX&:%ß L!2gBóÖÎ ÌD5­8Lôáî01Öå )*ùN‡óA{ R֙뇘F •Íc3~·{/Ëv“<:ýÈÕ'ðâµÃ¯º²sœÔñ%ÍIV *€„ñ¼‹R·‹q¨ONÀ*†t‚ÆWrÁÏZÑåŠ48P ŸÌyêÚ<§sN›øŒã°ñdÚJyŠ em[® "*˜òq*CÏ“ ÎèV…NŒ<ÏYék¨ÖYü›¼ä.‰Àت‡ÄD!Öïãkϱ)Œ Œ$p ‚vbŒÁä" Áúijö[_aÈC$™ñÊ€NJ±q&QÓ.oeõØpÙøÓË™ÙÁ—ò½»/ó9KŒ.Ž+Ñ`Ä6Æša`L€Ô‡¬#FyÝÌU’E®ªjÊ x˜»Ú&Ù }¹×.Î?ý¶ä)'¹·{XÊ6ìð&I]Ö–6Lå0ȘPW]¤‰&ĺ¥61m;=¹dqâ$¦X„;ºc<öª4õg5rx4¾ªmcÆE*%¸:¸JG‹ˆ‚ÈZ¡ PNR@ˆ.¶y7¿·#.Û ÊÆBžÙ.GN1F%ežÆX“Kc” …o*Œä‚“º“e) L¡la¦£Bçis¢±+†zÞ¥¶a´KÒǘ¯3PC‹² Q7 ÕWz^ME*ç«Êe1ÉkÖÙ„l S¨tãÌ"“)õ,Žî-!C¸b¢¸ÞÁ5êœÖQBŒâR mSo±Ó-¢óM¯q=½4, ‰KȘg’¼ðÂ#Ÿ2(‚Ë‚MZôuj‰iÖõæQ] ë4øf2癆“§Ï´ŽÖOç÷:ƒƒ~bì´nFÉu„oMmgs™&Å`ŠJÑ-&gGÇ\ öû/ó—ÁÇ£~ºH0S÷yäB±D™ôr/ s·Ž $‹šLCðLƽ;Bp$‘ƒH5éàUE“#X<9C"<äU¦ßMš…pÑU-Eb ¬& ©Ð Èx™“† J9gÄ|Œ¼%/Ó²ðŠŸžžL/&ÏŸ<½Ø4äC*íe\Ì“È: ÒTd§Ñ²ŽHšŽ$#¹¨Á¶-D”œcJ*ß4Æêœºœ¤Bƒ‰–œy-µµ%óñhÄb‡ÈJ'±yÉv[Pp™T®ˆyÚç€{)4]’$¯çŽç.ÎB[-€ŒÌ3f•"ÃL0¤Ìö ×ì"qÍUx5šî·3¸EUwc nùˆ("´6ع—;½’µ ë ‚´òrÉ.q!°DLZŸ$™ÅfLšæÜ_NÞMÝ;¯>LD‹žYã§®©ÃœSº¿»ÇHFA±q__NŽ;ªƒIAõ·X¦Zø¼š’§®XLFŠ‹î—™bŸþžˆ™1œ¬;xøZùƒ?ò¿ý¦ñ‚@ Uëè¤ó:ì›´v°{·{òqò©Ï¼C”Eš¼ì«ÅŒwº÷Ç¬Ž«ªüõ;¶òéykª€Q§|峬j¼i¡ hPh­NOŸ‚zÀÓ˜05›Ï¥Gã%ç8³íe¿Û!äviÙDÌÙCQ˜”rÖ7ÐĈ\Œx+%ƒyîãŒâ™£¹•Ik5Wœ‚#rÒŽÛȲ6’ã°¶Ðl«'°¢8\ iIJ ´"© ¾!‡EÌÇøIsÊתÊ%͘“:16Md”æ>’R„ŽÙ`Úà 5¶½\Ûy3uÒĪ+¢è›x!=Ó|ëæ™rÅtŠáääX£&ᨩ´Ãý=XÄçß_X£Q+òÃütgÇGÑPRCÝÎðÞh<–b°ÿr–tÈ0¯Î?zzᦽçR¹BKÅÔ´%ïXÚ†Çwwî¿Î²o\œ´«€sl‹ýþk‡Ãdg°÷ìòèîþ˱2÷^}0ììAðYä!6!ÕÝÓ(ÑŠ/ôŒÎELù‚Z‘&é  ç `w%H'dº£Åû>ƒ¢‘iç9$iÒá±²\‚t$ Ll@#ƒÝaÇB•ÔÂiÆQ•Ìáaš2Í€‚ÌxS[„2Ò½‹ÞxÊü-ê1¼Ž C`kR{NbÝ`ØŒùöÿóŒ¬I*8tETm0©òJ ÂÔ€«ˆi œcWðÖr‘´kMˆ„i°ÉYßN›2»S-¦Çœf¥p½;¶u{üâ)ʶõ0#–gmG í¥ƒÃÞoœTéé‹ãùˆîÞû”TN':°Øòvqú˜S3èJj‰9ë`žÐPÂ}FYS62³ *ëÝálœÎ/;£ÓñðàÀ5)½–EÞem¨¥¶>œLZÿ|:=¸÷Y;îkó(/§h3ÇZû¦âصY—¬ãŠF8zÅK‘¹"éc¦ÓŽæ é …— zæC¾³ Ib¢`¿ŠŠÈ‰vrT•£R9çT{¼œÃ[²=G©"ð(Ù¼]ÕË)ˆ(=\s/ ±ÚϺ¶»$µæ ¢Æ!,ñEþ6qU¼U&‚mò{܆œ¬NOãÓµTØ+³ö…I´«j&QJCÔ*®²:k´Dr†¶nT©ðÜÆ¤”b ‰XZškZ%ÉÑø¨9çiúé7>'R´fŽIïôãoGOöË×vöE¯tuå9ÖÇmŠÐ6Y¯Cbëg÷::¡ŠVP͸ºØß{p÷õ×jtwöwêÅ ’‰-=Õêƒ< w: J¼ ΂öÖc&{e€A9p‹æpo—kkf‚¢ös®0dM=.Ò "r,ð4,\’MƒU‰â3D’AR`2Ë”­dT&B0¦Ãb6÷ÒMb©&¨ƒ‘’e<Ée¬Lx%çRtM¨ç:˜YhT˜«e·YškòI°’ånŵ!¿ºÌ|)Dk!nY~ZûØf³¢O*]k¡`¡uGUÄ(§‹cLóÖL¢^ƒÌ!æL5f¤UrØÝ‰mÐBçå°È?,"MeA‹ 9O•Œ˜‚p)°MefÛ†kkZ1=MòEû¬=}ôbþåÿô{wy™–(t9ØÙщàB7õ‘)Lƒ?ÊÊݺš3¥&@Æ J…)µ‹Tâ˜ÐÀl˪¶×e•Doy0Z²B4'ŠxUÝ'¼šJÃäüêz#ˆ ŠJÚ>Ç?ßà6¹¡ð¨ ï•Pž—ò¢q&‰m뉥œÙZpV;lz1̧û©H…ŽxL,oïUÛ ‘c UBêÑó§;E_æ=BxúÑ·R\ƦÁrx·Ø/'£ãæøÍß7ÊzѨÁùeÃóÐèä q!<=B”Ÿ~û-.Âdvq˜xn³/¿òV-,‰šq$ÃWXÕV”¾ ,á§Ç tº«ÛéùY%öyndžî1HTŠbqz"2U]æwïø’eROÇ/†¬º·OŸÏæ'“ŸµEÏš«Ñ]eBÜ“d¹Þ¾‡Ù‚ñ7~òK_‰™}>yþÑï~xtt˜KSQæRk%öb®­i>vL U"€B h ¥ ’SŒ¥’€ä.ƒ[*þÛ°ÅkRº%Ùrû×ì$!Æ«ÐNl”‰np³O9Ú@º"Âàb¿Ì5çSC^ò9¹À˜CÝzCíœBK cTÍ…ì°zÁ{VX'tª™«N9ìª~ùä½Gc˜Ñùü[‹˜ô;ÞMŸ}쾕5FkS”¿C³Œx]f¢çÞÙlJÝΗÁû¤;Œq2šÇÙ|Š¡ÆùÅ‹‘ålÑç 9“ `PÍt:ÎôÝÖ´æìTìvcš_RÊ â»  g&™ÞKD‚"w{˜È½ÑÓ'á䃣ÅGÓ£ýi¬&'ï~X7«È£¾Óý­Ñ94¹yPŒÿy³˜ëáKÅËûéÝO©>8ìþðŽ.ö;íbÑ,&ÏÆïéѼ«ï”(¹˜M.¦ùáK/ÛºÐZ ²b“º&?÷êl6šó©ŸOMpƒ"éæ©Qoçèª ¦iú¥W¬WµW_¶õÉèýô(~¨š{ê­ä^8>åeÑÅÌõäÝÑôÙÓ#‘3.lãA)‡ FJ ã£6Ó¶n<$is±ˆ€¶f±)Šárû1úÁOFû±ÝA÷¾Î­§ÚF_˜“UU9- l¥&™”é«_\òÔ·&¶íœbxòíßÿæŸ}899o&ÇÏÎ@ʽJ]9Ü,õ^ñÓ,1†´NëBçņÁ¿AHn‹œÜr\뽩'§T’%¢¼ÿpoÂÉ£³£ÉY¬lZô¤Zh̹ê虩’‹ãg‰,±÷áBõl ´ ,Æ“I{lº»wÁglÌÅ4ÛÙ/™áÄlà…î§LgÁ‚ßIÚIVd*O ™0Ș©~ƒÊøÌq—~‚~¾ ë©á<‰¨_¼09ÈÓÑåä|Ñ¢U MµØÍ >P}ù~]ÎØÜ?­Ÿ²Ñbž€r!`†“%ë†É¬F " M•˜“šŽxéáý¡ºÓÓy‰B É$Ÿä²©éù“?nŽ™Ofå^笺D¦ýÔ@kÚ‰üŸüšÈú¯¼º“ôJ.ÕºC®ï Áêãj1‹I¡~êïüÝ¿ø7¿ù«|ïí¹³™  lˆnUÞ¼îóm1 ÇõØ _ŠOA@¾Ö¼]z´"¥¢W\D¸æ1¼¦²ÂÕ8"#XykN[X·‘ÂFjÁ6"±)x²<TоÏQ“d„œ³8›;åIO‹üîÉîÞðàƒüî›?ù漤‡Ži—_òsÑê2ŽÅþàb:ò £¯N±6ÏÏÇÓj:Z¾ZÎ+ÑÏä 8ȆF烋£Gõ}÷ƒÓÎáó'J xÑI˜zòÈ#ŒÀÙDYfD¤i¼Å´Ê»woªj‡–³F r”ÝðôÅ7ßûïÜ3é“O]í‰1¯àärägóyŠ2VecR‚îA‘}õoþˆJ•Ô%cv5‚`·[ð°ä_‡f´ºQŒÅïýáÏ[‹¿õÿýV3šz°`ü¼™2ÞáRÚå‰Y^hXë^¯äl€C\"E8ÛÈéØzàœ @¶He Я'P €CD@qÉ_x"¹%ÈÖ&·9‹nT ²P!:Œ÷v?~v´pàeÊ!XqÍó1£Éþn˜^ŒOìQÝAkä¬#vÏ[7;==»|¿úXÍ÷H0ù°Óï+•dfd“q«ñèù™¡¡O9w£Tª€z:Š"á2Î{eH<÷ˆ +x§ÌØh6) Û WæZ´€yË“—³r2š– ˜Nj0t>~òô¬|u8wsΊwbÝ¢Ê&r8CžßùÒ÷ Ô w8ÔBe»®´Ç›kZ¨ÕÐFöJ=r[]¡<€•àW~â?ü¿þ÷šJ ¶™a4À$·_äAA$ˆ‚ÝâkÆ!|›D7ìJód}"—EÃsƒÈ€ˆ¸ÜOBocI`;µØ¬#Á”L[SiÈc,¢‘þJƒ}çáaïðþ£ÓGÏŸÍFó´Ó Äçç“ûÚ—{è÷mCÒ‡E{2Ï,¢I[-`ÚÆ«NÈ£¨ÚO[sÙNæÈ.)»{xÀDq·ï£§˜(öIë"x3v^µU›•I3#át`䚪-ó0©½:Ý1afŒ¶•JŒ.æEÓ1j…+òƒnÒ)T­w>Œ:çÁ<|ù ëìÉÝ.Ðò:ˆ% y@ÈÖcK†È¸¾¸Ëw=í¿¢^’Ì¢›7 3 Þú¾/ø_ú§¹œ7ÄXÀ…=!Ëå€è²ðq5%ÂÖà0ºÚ)¹ø¦õ8@¶R¤ ÀÜU…€¯…’C ËbQÜŽüaíøÙ­€‘Ý*!¦gy£äÝ»wÌÄüÔÏþGŸzõ @zþâô_ü³_ùÍ_ûýžpä­…‘žŸ}h÷;SÈ@7®åAv4$ ±£ý¬ridÜ È ;žwºéýÌOˆ´GVäÝ2‘¬fÀЇ ÀCLLtÀ,¡ˆB!´¼iÁ¶1HÛ^:Ö{ÛLšN©L[ëºãö"a< Á eÙ # ¦=­T €–4O±^pÔ,vÅ w剗{AÀa¬‰Õ{h-ULf©N-ót•¬°PÿÔ_ýÑòßÿ·÷Œ·ÑWL¨ã™÷Cµ’$ÀµY\¦´&ÙÄ ± þ¥§O®B2…uÒB„`À3ˆ[‚Ù›¡Í¼ nHð[µd¡„” pÙ*KeR€þÞýÎüóÿÅðàÎÿó+ÿkZôÃ\6&ô9‰¥lµm˜7Ä}”£§I”Bt‹Hw_yéᎠÞ|û ȯ.ÓŠr2`ôrv*Y: , DiúPB` 0áê&!÷À–$Ÿˆ ˆUHÄ ˆ«ù=ÄWm7ܘºYG¶VY¦KKqò«­ÂY.Ûw¸&zãóßûÕŸüßú“?ÊúÙaÿíNÆBÞ}øàÆ–¡û†–%ûàg¤µÑY~ _sš/G‡=DF«`0ú5§ár5$€D±Ú$8½’3¸•nq¶¬“õUÆ%7ÎÅÒi hß~ýµß¬mÚHîµþï”Yi‚¥¶qÆ€‹õ|Xh<+d—5R ¾úãÿž 0B¬ðùùåj®׆xû5Ì>\#ÞP­„W$M…3&WÄ-äòoauD8»^hbk^èe±¯ÕF‰­0¬ñ»¸nбk}å ×aù*\èöø_ÿÙ¿ù#õÇ•VY–ct %p `ÖÃÖ6à¶M\{™ePÂ7&P7ˆ͹3"@±b/[Š¢P€píìã6ªìªÖè6¢œ†Ë=°©ÌÀxkÃÒ»¯töëcK±sxðÌAta.éÂÍÇGÍ æÞN¬4~&­f*Õ…ðÍb¶øèôƒŸþONj¹Jm—;¼8+ªnd7禯E _m0®£¤MNdka\Q¾"»N†cX“~­4áØšú…­ÿÑ:1‚uUgI»Y|ߨ¸¯dhäz 0¸Ë2Uœã0Y`ñÚÚB`aƒbíʸ¾ñ¦DÅòpG‚€øõôA ( †ÛòVq#9¼‘À¶ î2aåo}æõ/ÿàEZèèb]ÜX–;èàððçþÁß¿œ7Üa¯Ua6;;‡¹KÓdû¢$Fs4ò7>÷·þÑ?ஊ$ `7*ìÖw»rU78û¯8ZÂjíâ†# Ñ¯ pÀ°®Òà*4[Eq£URYºm¸¦ù kÞXô+JXsXÓQ\[”õ5 K[ಷ¿N+–ç/"O”Bë´ð†,Ý6 į—eÝf Ö.&®®âÏŽ±m³¸Ñ@ºñÕöÿÙßÿ»+_À^S4Ÿyû³{i{ÚyÓIcÃÜ%ŸòN±f¦¥J ¿oýüûÿýË2r××V&ÂnÁœ®ï°†I²OÐö¾ºÖL [[~¼¦ü^¾®‚/vÓ-#ƒeíeõ[ñ:èC@@XG ÑÛиZ™%kЊi>¬Â…%ê—㪳·‚®` ñ:ààW\"që*"n'¢¸Na6,÷Ul±üÍqy1X³|…mïë&EØ0>¸Oâ·GÀ³Þ’µè.2ܹ³S–5p3k¦§NÕ–f¡ïO#Çñ™ýÖ¿ówþZš.g£–pXv+mÏ…,›7(Þ„ÃoS@ˆ1`rMø¼^#¶ô²´e!Vr´–‘`kW½Þå‹«@a-H¾\+¢­‚n9 `b]éc+Æø*¾[º ÆĦËgë-àëbÀÆZaë쀭³<N 9D€<‡È ²U\±!…|#úÀ[äb}p[ü„]Ûÿ­×WÏÌ8Ûí ëàj‰nz.L[ð0ÉYf‚6aʾñÒÚv!ßþhv+MÝ$Ê`·ð/p‹¿ã ³µF$'À°>01¬ÎÁ•,Äu®´þ>×m\qºáØþ¸ý­ÂÚððëz+ãÀ0~%gõ™Ä•g¼æ‰ W·çA–4Æì“$.—åDˆ  œ/D¬ZË[’ ò»›×1lL¦ÒFz[o•¢\ATlOõôžxYæùØ4i§sqñ^ÎudÙ`è—¹ÊF½êêî.[n£h}[§>I®c]¿2øW±nÌÓ-ãdvUN_Zc\Õ@×þrç6+iÑ€HÂu1~s†{-C†a•©"_#ZÕm–ñ]U|×ÏB°ªU\ûG¿&Œ Û(µ][uB Vù šœ6°UƒyÙr¾Ù4Z›Õ’Ý;XõI©£ØP Õ|šfÁÅ„`u“𪠗Pb³ãËÅ÷ü¥¯®õ«Oä·¢?~ ë†FˆnµC×aù2 ¦«ÇaŒÝƒÁ 7×là×)mÜÔÍòùÚJ!.óˆÍ\”€„åí ×¥{¤U-Ä:ÓA`l•µ² ±º¥)E~KŽà!9nxmÚö€W݇°~–¸ÂñHËÏekóËÖE†Nåê“ÂFY*¬Í_—$o8隀 â?ü‡{ïÎKǧsŒ©Î mùSÚìöÊ·>÷ÚÁŸÿ> fe¯p£H~½b;n½qƒmŸÉt¸.Ú,¿* ÔÆQf€l݈cx b¿N ·yaã‚Æëqõ}0_»-\¯3°õ?õkЭéÀÖËHµÚléÁÆ"ǵMº:Çbõ8«×7ÙË×/r q`„`‰.6*-lcå6·}ظ¦›/ºµk¸:FW”ë¾ÃhT¿øø©8«ò—w—Jq€\ìåä°e7rzvËéÐvÖÊoÑóã­\wsžŽo9`1‹ë„{}Â6ý4]QÅo&SÛˆ€Üp›¬oÛT/ËDñºø·¦Û>ôx«@wu7ø†›¾Š‘ãº^t+«_â‹–uCï "„H Å‹kÄÙµñßdµ¼AtÎ7–˜o0Úñ[JÝ´>Âqã‘4@ „ëÅ'@¶®Ðñ ‚¸mÓØÖµÞ¢Z Û>bsâ†ãF …`K.îªÍ³åïÂuv°¥ˆ·t¯ì³Zµ®#¶¦™§Uª kª˜«°70 ×(’M¬W¼¥|¾‰ó¾ALoÒíöoØ8aÍJ±$² ¢ƒhÅ •×Éñ²ÕxÍ`>iúìF†Æ6ŒÕ'Æh´q ¿þÚ?©5ÛÜXüÖ¬ n‹sÄOò”Û2¿„Û¿>nq¯ ÞÒ‡§›>q0$å6Ûã ©P¿Ó±[¡ëU†yõ· Ûà’Y.>݈?6­cü¤YPü¤±بñܸœvå}"Ì×É`E‰ÏØ-bû¸q•Ã6³ÝÚÜ.é„ôo¼á-×~[Âý*j[F! ¢¶ªGÏÏÁÇ[CQ°®v+½þO(¤ Š À>ïÑÇß}´ ütÔ|ôÍ'Á­y¯I¿ É>üà›ãÇ‹[‘7 õ i¹¸†ݬʈ-åÉ«ºÖµ³àÛZWæðô 涉¨i㬠¾¦3eàam-ÿ…_ø{ë»B›rU½q!ðVÊ·ïnØH,7m&Þ:7pëEvKoœ¿ñÏ~‰×ê÷ÿ÷Ÿ¿ûÁßøÖŸüÑÏÕîáK¿ø ¿øõŸøq@{‹N ô?úÏþwý7EÚü7¿ð_>¸·ÿ+ÿÛ/_Lžþò?ù?ßøôgËB¯«É¿ý£ßþçÿ÷/õGþ]¨NÎÆ¿ôñ/üÅ¿,4Û¨®öéÙùÙ¯ýÿôþ×zwv·³öIl°•¤}BZ7é#q“'–mÜ@¼U¿Ç[Êf„¾c^]Úe!nÙ»Â5ì9 ²UsÙ#¹r“DÛìTl;øÛO¸ùxüÖ3lÎ/°O ñn©Âf¥¯ž<õGÅý·ßùηÿìÿÏÿÃþÌßøÌ§w‡yÿ£ïþéN9XU‚W‹¨Öw‹¨ïùž/'ýl6öoV»vþÚ_ÿ0ÚŸûù¿wç`‘$KPÆãwö¯®uÔþõ…¯èŽb!.-J  ~ãWç­/ÿôƒ/¾³Ž…Ù:&Ç[jâ7öžm¬L¼¥Aˆ7t&׫Bkê¸ßèà¶eeÛÜôqU„XŽžAÜPCÀ%ÁõU•”ÿÿu]yx•Õ™ÿs¾ïÞì ˆ AÔbµB]ªuªµu¡Œ­}Úq¦íØM[癩әªNkµÕÚV°¥nH7QQ в©‘ [BBH „ìÉÍr×ï,óÇwÎwÏw/ó<ü—››ûmç¼ïo{-üájŽ›P†¯™0 (ÊÂv"á° ÎŤùÉgáª>”£Y6iöµ·/¡žøú_2µ}ᜠk9vþÂÚ7Ö=1>˜„tÛŽt¬þËSýÁ]•IN •qÝ¢ºæCó>ÑH÷G̺lrei*<ÑöâšÝm@ñ'»ë¯¼öš±ÑѺ-;Þyõ¥Ýoì]ò[÷7ìèî_¾¹fm<…eÿý¿{_¯¿ýÛ7¸³nÛÆ—w¼µÙêèrEæ$;!lâ¶‹v[¨A³FPiªüGE…simÙêtw!3  <åÓR/ Z5&}i„Ô4¨î``p.ïyغjOÌäÖasë›!os’ÖÜÞünMX]†Þçs#Ålb"v²£kÑW¿ê€8ÎöÝ»«PT¿÷ȾCGvïØ½sÛ«åU©Ø‰ž@ÊÇ””’OL?§ 6Ô*¼ªÕÆÆÆ6,{eÏŽúDkgÅŒ9MÛ®{ÖgGDß ÿxÓœ³®™Z]ÞÝE&M¯„$Dã¾z–úlè/ùfÖÚžsÞ áã÷aþ 7øqûiÕaŽÕ²3-¤îÀ¥„ ( ¢¹ WAgÛIƒ'+ I ¬ý^©ð’Eòþ)-•º^”ì¤ý …Ëæ ƒš‹·Øç ã8º8ZñÈ–.]úƶu•…s\\ˈK ôŸì£ÙNO¶÷Œ|åÚ/E§ÍX|ý?œ½ps8@vìØ/H<ýÌê²²âÑÁ¡¾c}<9vüT«36qª½q,&©—\|ÅY“V?¶ñ¶Ý:Ø×pfïgžW àÃ-ÏŸn-¥\¯«$Ðð óhæàëÈ;LO×K„ð*Ë,P…ájÁ¸ž¥ý‘za¨m<òy¦"Á}äXÅ{ Ã-¡((3Jan;‘ı¶mVpӥݨð¥U–Ÿ5®¢UØà]?ºZ›ÚŽ´W–Vœó®»ùzÈxoSËäs ··Vͽ€¹éøXêØá#µ-,(NÓÞ¹Ö´óR±AêO)¤ËD£n*Å ‹Š\GLŒ'ËÊË¥HÇ'¼¢bÍ”R§ÐM§àeP\Ƥä|‚DËJïúî¿ÿéÉ‘¨4ƒ…•EP‰·4òÀ€}°.š7Š.XýmÅ—D­Z’†™${øÂ(™ÿ_^ k…rô <à‰ÙÑQ^_vIÄ!Ps¿0«£•ar6 IˆŒJ­Þר`õéÿÉ!ò"Ö³8ÙrLÛz¸)|ü¯±Zä€pâ¡jK_5Cü»ºV¢4»4úäRéjíØøÒsNÉ?ßó+ axa¢Å«Ê×#E²7‡†< æ'7‡ÈòÆR«¬1ˆH} ¾$²¼•ÂJ£áЈà©ã„ožpmR@p¡ Ïtš(o”h¨‹+Ìè^ô2P`uDXm À3çX™éDÇ¥øå'u¬âEZ—*§2ÈÉÕ•á†[Zk’¯ä‘†ä%y8«Êë×iî '¿"ÖÔ×ÊÒ¬²HIݹyËâ«®Š–EÌ)ö \_E®qbâXjl3˜Rù’ÆL˜þ` ë’ƒºV!EN‡/ÉðØ•§"á)÷LKfÀ3PT—M)ÌÕ âƒYKƒRY¿„C´„>ûÑ4Ú¬/!,01g–ž]ßÉpJvN ËKÓ§–€B…ûÌ´? ÙrÔËJëš/Àà R H¦!Qr $WÔ( Œ˜XJEͯ•Éz2m~‘P௲U¬ôtAÁ™ôÌ©cyÔ‘í$á ˆ…¬¹¥¢),ü/…LZ[›•€ÇAP©(„г3³¾I"´Z&¤Táö¼è   ¼< AZõ*µ„kJC¹úB²°ª˜hË\h ¬¶% DLl·¾nO«žÈ£lJ>eRž‰®m#É€@¦R*ÅšKB2ãø *!Ö?04r|4_¥RéC»š2ɈQ]8Mûƒ;m­ƒoo|·§c G[:·¾üÚñ¶>€ œ{ûÕ­§Nö NëwxÿÍÃi™[îe›pžPšªÂúý÷Ȍޡ\æ?íŽV HA(d2ˆ®ðm­T+3&×D1K衆zz{7´u@ÈîÆÂcÀÈÈÑ£zS€RJzC1•qÒÓÙqäÓƒ€»¿n+T”ß¼’Cõ¿µé“m]J‰êä±#ÛWÕ56ì?°õ}SŽX~Jýñw¾{ïO~2œéyñÉ¿åAoÒêÅaoc¡GâY9HgGÿ믽YN,§_ª¾áÓÖÖN è™GW€RiI? ¤<ÒTßÒ°(‚¢Pt,®ê6¼“O˜û>òìóK>µâ1Jä¦M/ ¥Þyi‹àòÐk†‡‡Ö?ýWÉcï=ó¸ÊЕ˗u=õÀ£ e0`—*Ó±b«|ÊÊH,9×K£fþOCø÷‡”V”T@xÊ^§‚U«_[¿þ•¦æ¶ÔxrÝcëqÑ~ŠîX³¾¹ ‡Çþùƒ£ý'º»ë¶n–²xÝæ ñØ(„/™rÞywûPÏ‘uÜ=1èeâ%¨Ldü#ä‰d|h0Rä(ÜÞ¡ñ‘¤YQXFxì¶û®«ë­¦ýŸîM‘ζÞÞö~ë‹í­?ÜÛ¢{ê›Z÷WÂI%Qÿáæ-Édºóø‰]ÛvŽ §Zu~òþ'­ŸžHgêÞú`óÆw[š:Ò±sÇÎM6ÆbãFyåÎÑÖîÇûÓØèП֌ Å'¼·_}cÃÊg;Žõôt¿ð·§÷ìÚ5îŠþSýo¯}©¡î O©"ÂíÁˆ/”iãMF‡¼²’‚ÂD¤½¹u8SØ|èdÉÔso¸õ;-GÜ)MÓòÉSj´6:Ëzskqµ›r¬fuÆ,»ƒ(¡´W"Øx…cTƒ’Cxàþ8Éu5'Óú£I(TPûö6íhŸhêéoÚ¿gÛæ—žH 夓2>în롎þ~¯¥ñ# 4’LÚññ‰c­±žTçÑàH® ¤#Sƒ¥Õ3ÉÌ4 wIDATz»»î¿ëîGïËIŒgV>ü×Õ[Þ›lmKžaÓê¶¼ü÷ß.ûã}÷ vÇb±øÈP(im?òäÃo_zõ’îÑ‘Þ=úÕÿ´;²aÕšµk×j;¶jÙÇ7¬{êã÷>>°³aëÖgíÛüÒëCG×­d¸g|ÓªS£J9¯¬|vReñÆ OMàßþŽ«Ô–žõ7F+JñO·×õQw®Td椡³gÓËZzÓ-[_ÙÕðÞöc‡ºX©»Ók4¤“…U5Õ‰dÙ¶º÷ö|´gýó õ·—Ò˜’Ä,Î|¬´¢‡–gŠ0oÑ•‘‚‘'GºÜ…W}&€àç™â7Já oËË]³*‘Çæç„Iä¼h5JB*=[ÿ1˜% ŒÀ!Li“3¤‡”JHD@£–JB×2pï»ÿžÜþ¯ý±Ï^¾xÇÆª’eÓ/ñúÕ­}nÍÿÄSÏ,ìʯÎ^ýìã{sß›÷Ý×ãÞÿ³þü·‚€RB(g% ­Ãs~™óÔÂK¾øµÛn*/9ºs×û“jfþàg?VZ•vJû[ŽîýÍÒ;ïžüåÊÞ=­Û·<±eË ÑÚ³Ï]¾|Õ”I•µÕ•×ßþ£“}ãîÜvëw¿¿äÖ¯íÙ¹<~0}éÕ·°šî`âò«_xéyÝ{XçÈg]:¯v-C‹®¾a°«qfñYSgÖ”—¥R\TO™6÷̳ Axiõôs‹ÏY2Á ­‚š†»jùrt ÆB#$”›mÛŒ¯u&zL®xÚé2=(I)ÇR`nvš&™-((®DQÑDÛÁó§-.Y÷Dy†W?Ù|ùÍ_ç\lÿèåo\³ô‚ë?c- ûʆÏ8sáusç×Íúlíè{ /·Ä…DE4õ­o³uû›3g}¯¡áƒæñªÒY7~þŠUËVÖTwáܹSâ3zJk.¾æþ'–?€«y`Áù³A)`´vÖ\ßæP2³ ,=ÿŒ¹7Þ|Ûü]ÚKüâçw¿]TšžMœqÙ¼5«žŠ’è?ýà‡Ç&Zûüß»{Ú_ǫϫq?û3ŸÛw eãÊ55ÓÈâ©©æ}»ç,¼|ú9ó/LDçMã•»ß|ò —ÿ’12±øªëkæWüæ÷÷Nšvfdñµsç'iz`h亥wF‹hÍ9g 2©zÚT7"z›«¥6¥ð[¿¸»¤2È’RçsÔ^ó•ë#¥Ñÿ¼÷Þ‘áXeõ¤É•Å߻뎾±©5U¥…ßú—ëï®™Q –úÕCÎ8³úÆ;¾O©0}MΨ³ægFÁŠ*M‹ØÓBÁHnúU *ã«ôë•îÖzVæèÉHPœC)¸ 'ªž:@z¨-UR]-Œï¬(™pN‰L¡p¥¬|R)”h?|lÊÔiSJãññÁÑ©sfBŒ±² x)®%ÅPœ––dÆânY”2 VuÕË ˜”¥*&Æ•tœ²"Ka’æ/ž–U) å\£.ØûqsSÓ!Ò·|ó‡eåE@@À ¼±ÄÄsÏýùŽÛ~MKLBÀ>ÜñîeW^¤u $ÒVÃÂM£h`"žq@ŒÇS  p@iøZúe<3R+©,)²Þ¦]˜…u+T·Ä|àpÊ ’Æ É-…œÒÑ•R€sHÿ²¢Iï6ø—O7™u†ºà PÉ!hÉIDïLwVÒ”þñgûlj€Ê49›¨$H€9Æî§³°°€L†å4O H,Åw * LÈð°‰8%%Ñ\“ž‚”H¦dq!3Ö"±a(ÓVSJk•–i}6p\H•ueacjýxNe§ 91,³ô¶+D𦉆3×@k¬¥æ‹ýR@qp `®Ñ¶R%ºŒSÓï âÏÒ&H&@8 N”š%@NPH@0L•Ð §¦/•YWì'bq†2, &atÒû¸A¦sDW$}Gƒba©nØ©âãê$/ÃÑÇþ Ã;öœ9 Ë“iý )'bè_À# ‰•,*KP¤¡·cHÇ|™U{„êA'ϤȤ†¶|5/Ì/¦ w~ÀŠ„c‡B ½æëÃP€”€ƒh!„ pd’€æÀ1iÉ*p_(m›RFàf¦FÉŒ¯;û$ ³Zr ̽Erq:šKäI¬N§YRÄ2ò©<1ªù]Y‹‘Y÷ FŽËÓ™óEVg t'&Æ2fY`’>Ð,B1K°£§•IcÉ,ƒŸY—Í¡µ$-6ì;'É&[Q¿ã3*bÆaJúñ8BIm>H>4W‘.É@:`2ˆ‰GÞ#5Œ/‘=r¸æBùz\›4ó,ž”æ ë ávÈH3ˆ=¼‘X);,,Â!ÆTÃÂù$ÔL+KdQ)ƒIS–'ᢹÖM?Ro©†z%ܼËÏ 1±B C?ZŒiÊŠ PâYVâ°&Ú k9ôÝTÆ,`D;üž_™$2bjL’åÒèt¢5šüÀ³BtÖ™èâwžå`þÂbRR„€¤ÚüLM2JÀåH™½œÄÞÉ2f¡æa!Gͬ²YC»µÊ0’,uIhØ£‚0O-DZ 9O|·aÄ–É(c‰— Êq ok>'øälÌ…Ìó¥ÁRfV¡#Ìe ì‘ìtÒE'´^Rø\B1Æ #¨]oÌ>PH¥àê§™ø ¸•¡`Li’²W© ))¸‚ë„•OA.KNTW¡Ä Ä< Ù¬½Ó²Õ*¬—²!t‹$̆äxE(b(ô™' Fx’‡¹“HžëMåHcTP^>2Ÿ6¬1›%L– ÉK‚òr©sB²ÜºBX®’ï75ö@¢ôâá/]Df±v”&FNL|ÌOÛ¡þu/#{öÞIEND®B`‚snd-16.1/pix/nkcos.png0000644000076400007640000005005311147553270012766 0ustar bilbil‰PNG  IHDRôÁ9B sRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ ©w4© IDATxÚìÝwXGûðñ/ Xh "ETì õcï5hTŒ%jì {ר£1>1X£Ä[TÔ€ÑX±‰¨D,€4A@zyÿàǾž€‰AÀûs]\º»³;³³{Î}vwvF#+++ !„BkšRB!„t!„BH@B!D¡ô„„¸téR¾2xþü9cÆŒA¥R1räHbcc¥Ö…(‚ž={F›6mÈÈÈÈ×z?¦uëÖ¨T*V­ZERR’T¦E5 ÇÆÆâææÆñãÇIOO퇇‡óÍ7ßààà€ŸŸÓ¦Mã›o¾áÑ£GRóB!<`åʕܼy3_ë°xñb¼¼¼ðóóÃÊÊŠ7òâÅ ©T!ŠZ@ÏÈÈÀÕÕ•:uêðÑGåkãgÏžEWW—¦M› R©¨P¡§OŸ–š¢ˆfûöí|úé§Ô¬Y3_ënذO?ý]]]ÌÙ³g‰ˆˆŠ¢•ú·´nÝšN:áíí]`Y¶lÙ¿^|ñÅÔ­[WŽšoQ¹råèÛ·/Mš4)Ð|†Jjjê?¦Ù»w/%²žwîÜIýúõ±±±‘“N¼›€®©©I§N ¼ cÇŽ%111Ïe{öìañâÅL›6Mºo™‰‰ &&&žÏòåËÉÌÌÌsÙ¼yó8pàYYY%6 ÿùçŸT¨PAN8ñîza©\¹ò+—UªTIŽ”ÅÜ?ÝÎ700 â?zk¯­EDDàææÆíÛ·•yµjÕ"55•=zDbb¢\e Q ùúúâææÆ³gÏ”ymÚ´áêÕ«¤¤¤píÚ5j×®¡¡¡T˜Eí ===É“'páÂBCCñððÀÆÆ†‰'*é‚‚‚ppp`ãÆÔ¯_€fÍš‘™™Éúõëyþü9ØÛÛckk+5/Dñ×_±víZBBB˜4iØÛÛÓ­[7%··7sçÎ¥]»vðÉ'ŸpäȦOŸNFFæææŒ?¾Pná ñºž?ζmÛprr²Ûl…‡‡«¥qvv¦lÙ²xzzrøða û®Òœ9sXµj< oß¾ôìÙóµó¿yó&®®®ÙA·T)¾ûî»\iüüüpss L™2¸¸¸ðÓO?qîÜ9%¦Ž7È~•|ãÆLŸ>ýõº¦¦&£GPþ”t•JÅ¥K—¨Q£†Ú|[[[ ‰ÅÐÐzõêÉÙ%Dbff–çg¼jÕªjé†Nûöís}Æ{÷î……éééT®\KKK©TQd899qáÂ*Uª¤ô°aÃ%ͤI“HMMåêÕ«Lœ8‘É“'óá‡Ò§O444ÈÈÈàË/¿äرcœ;wŽ &°k×.Z·ný¯ù?}ú”ТE øôÓO5j[·nUK÷ðáC233;v,ZZZìÛ·™3g²jÕ*tuuqpp@GGΞ=KùòåóÐ[´hñ¯…Ö××e:¹Å.DÑe``ðZŸqsssÌÍÍó\–ójªEÍÚµk W»£|õêUttt˜9s&ß|ó †††ÄÄÄðÙgŸ1gÎ4559|ø0?ÿü3ééé;vŒ¶mÛÒªU+âââ^»“´ÔÔT¬¬¬Ø¼y3¥J•Âßß?WCó‡âææÆÚµk©V­úúúDEE±dÉFŒ††©©©„††²zõj?~̈#Ôãµn!„%•¶¶¶¼säLß¿Ÿ2eʨýP-UªšššÊº_GKKK¹‚~]ššš”*UJm;/+W®*T`È!,]º”„„µòkjj¢¡¡¡”G[[›Ò¥KçÚN)9ÜB!ÞG§OŸÆÌÌLi÷õ®TªT‰Ý»wsþüy&NœHFFÎÎÎùÞŽ\¡ !„xïܽ{—Û·oÓ§OŸ"S¦6mÚ°}ûvŽ;öFëK@BñÞ ###ƒjÕª©Íñâ)))dee©='‰‰!++‹”””Wv‚ö*©©©Êø111¹–gddðüùs »eýËâããIKK###ƒ¸¸¸ÌGn¹ !„(±nܸÁÝ»wyúô)ÞÞÞ4jÔcccfÏžÍÕ«WÕÒVªT‰C‡¡««K³fÍøì³Ï”ÌŽ;¸téGeðàÁ¯•éÒ¥yöìcÆŒa̘1Œ?ž>úˆ°°0nݺE³f͈eذa,]º”C‡±{÷nªT©¢´l/W®‹/ÆÙÙ___î߿ϳgÏðööÆÚÚsss èB!J®ëׯó×_Ñ¡C¼¼¼¨X±"•*Ubذa¹Ò¶lÙwww~ýõWΞ=Ë_|¡ôâ©©Éï¿ÿ€»»ûk½`llÌÎ;Ù¼y3^^^ 4ˆU«Vqåʼ¼¼¨U«†††´jÕ ///&Mš¤\¡÷éÓ‡ÔÔT._¾ d·ØKQòŒ92 ÈÊÈÈ(öû”õóÏ?çš?oÞ¼¬cÇŽÉÁ.D‡ÊrrrÊ*W®\V=”ù_|ñEV•*U²\\\²Úµk—eooŸ•˜˜˜uèС¬=zd¹¸¸dYYYeeeee;w.ËÉÉ)ËÌÌ,«nݺù. ²úôé“díÚµ+Ï4Õ«WÏrqqÉêÙ³gÖ”|Û¶m›åââ’U­Zµ¬ää䬬¬¬¬ùóçgM˜0!kåÊ•Y;wVÛŽW7©;wîÄÔÔ'''š4iÂþýû aáÂ…ØÚÚâä䄎ŽŽŽŽÔ¨Q{{û\’½.;;;Ú´ióÊåNNNhiiáääD‹-X¼x1AAAL™2…Æãää„©©)cÆŒáÔ©SìØ±ƒ>}ú0nÜ8®_¿®6r›t!„%R5h×®ZŸì¯’œœL@@€2‘‘ŸŸ´k×N0%¿Z¶l‰µµõ+—ûùù‘‘‘¡LðâÅ üüüÔÒ]¿~'Ož¢Ì‹åþýûÐ…B¼Ÿ:vìHLL ‡R ˆÅt!„ï•uëÖ1lØ0¶nÝŠ§§'#GޤL™2Ð…Bˆbø45>|8¡¡¡@vÇFy G*]!„(’““‰‹‹#++‹ôôtâââHKKãùóçtìØ‘{÷îñå—_bkk‹¥¥%?üð)))ÄÅÅQ¶lYöîÝKjj*qqqddd™™I\\)))¯]†øøxe0—¤¤$âââøã?¨Q£Û·ogÏž=”+WNÙ®››õë×Ï•·§§'vvvLš4‰ÄÄDâããiÕª .”€.„¢dÛºu+vvvÔ«W””ììì8sæ NNNôèуçÏŸ³`ÁÊ”)C©R¥hР/^ÄÎÎ ,,,8vìvvv”-[333ìììØ»wïk—aèС¸¸¸Ð¶m[¶nÝJ¿~ýÐÑÑÁÒÒ===ÌÍÍ©R¥ vvvœ?ž  ££C½zõ¸sçvvv”+WŽ*Uª ««‹J¥bݺuŒ1[[[µÖ÷Ò—»â+I}¹Ÿ;w޽{÷âêêª6_úrM®Ð…B èB!„( dÍìÙ³qww'((ˆ£GJ@BQ²Õ®]›‰'2{öl  Ì=z´ÚШϟ?çàÁƒÊtjj*;wîÄÆÆ†Ù³gcnnþFepttTËûïvíÚ¥öcáСC<~ü˜;wª¥ûñǹsç—.]RæsúôieºH>Cß´iëׯW¦£££åÌ¢qrrâìÙ³ÊtN]B¼MuêÔ²Ç?‰‰AOO¯Dtñú*Eò }ìØ±øùù)‹/–3SˆdݺujŸñ>}úH¥ˆsðàAœœœpqq¡_¿~%v?¥•»BˆkÏž=øûû³zõjF]¢÷Už¡ !„(‘vìØÁ´iÓ¸}û6ÞÞÞ 2„‹/æ™ÖÄÄ„™3g*ÓeÊ”aéÒ¥R®{÷î1dÈ~ýõW–,YBÙ²e•e3fÌ Zµj¹ò^µj-[¶äã?VæY[[3lØ0 èB!J¶›7oòìÙ3Ž;Æ8pà¡¡¡ØÛÛ3lØ0tttøæ›oP©TdffÒ¾}{6oÞŒJ¥âéÓ§téÒ…½{÷¢R©¸sçááá¨T*6mÚôÚeèÔ©NNNèèè°`Áš7oNll,àþýûtîÜ™ØØXT*7n¤]»v”/_ž®]»²ÿ~T*ôèуªU«Ò¨Q#œœœèر#–––ØØØ(yI_îBˆwNúrâ¿“+t!„BºB!$ ‘#GÊ‘xxxpêÔ)©!„ôâÊÏÏOެàÑ£G¹ºwB¼_ÂÃéV­úúúL™2…„„²²²8|ø0úúúèëë³wï^233ñôô¤jÕª¨T*ªT©d÷ D«V­øàƒòDD¦¦¦¨T*ÌÍÍ Ì•ÆÂÂB)‹¾¾><ÀÇÇKKKT*+V$%%Èîh­gÏžèëëÓ¹sgµneå–»BˆéÏ?ÿdåÊ•4oÞ•JÅúõë9rä^^^lß¾îÝ»cffÆ AƒˆŒŒäܹsŒ5 ??? ùý÷ß¹téóæÍ#00ÄÄÄ|—áäÉ“4mÚ???:t耗—Wžéºwï®üéèèpêÔ)úö틟Ÿ5kÖääÉ“.\¨Ìfß¾}ìÛ·OyëàÉ“'¬^½ZI“œœÌ¢E‹èÞ½;ûöí{£aSµwÛfÍš•+¶¶6 4 Aƒ¬X±-Z”k½çÏŸ+åÙºuk®í”¸žâ6oÞLFF†œÉBñžëÒ¥KžóÇOPP3fÌàæÍ›¬\¹]]ÝwVÎØØXV¬XÀ‰'Ô†t}YÆ X¾|9/^¤I“&j½ßÉ-w!„%ZPPcÇŽeÆŒʸU«V¥K—.„‡‡ãââBRRÒ;+_@@ÁÁÁ,X°??¿½µ?iÒ$ÿüówö¨Ö××—””>üðC¾üòKnß¾ýÊ´?& €ÆsåÊ:tè@LLŒ\¡ !„(ÙÎ;Ç Aƒ°µµÅÜÜggg5jýúõÃÛÛ›FallŒ½{÷VÖÕÖÖfàÀÿ¹ C‡Í5…³³3þþþL:•O?ý€K—.qïÞ=tttrå=tèPNŸ>M§NX°`©©©´jÕJ-M‘¼B?zô(û÷ïW¦ójæ/„(¾r¾Ìrœ?^*E¼u‡&00Ï?ÿ\™gjjÊòåË0`“'O¦T©R|òÉ'T®\™1cưdÉBBBxþü9NNNœ:u îß¿Ojj*£FÂÞÞ;;»×*ÃìÙ³±µµeÔ¨Q\¾|OOOBBB˜>}:®®®ÌŸ?Ÿ#F(­ëÛ·o¥¥%S¦LaܸqŒ5Šû÷ï3{ölÂÃñ³³cÆ DFFÄ?þX´zóæÍ±´´T¦÷ïßZ777êׯO‡^{»Û·o§bÅŠôêÕKÎôdðàÁìÞ½;_ë 4ˆ={öHå½#}úôQûì>{öŒ   ©ñVMŸ>=×rµjÕ(_¾<¾¾¾Ê¼Zµj¡££C‡”9}út7nÌÔ©S™:uª’ÞÜÜüµË`bbÂÑ£G˜:u*Õ«W'33___*W®Œ‰‰ 'OžTnùW¯^}}}lllصk—²žŽŽÕ«WgÆ DEE §§G­ZµŠv@755ÅÔÔT™¾råJ®4‘‘‘XXXäk»?.ö?ˆÜîܹ“ïuä®Ï»U£F µi###©ñÖYXX¼2N¨Tª\ó sͯX±"+V|ã2hkkç™×Ëó7nœk¹®®nžë™››¿òE±Œn!!!üñÇùZ'<<œëׯËþž #--M¹u&„%]± è×®]ãСCùZ' ß·eEñåïïOrr2ׯ_'""B*D!]!„(®æÎK—.]èÒ¥ 7n`̘1ʼœ¿/^Ùƒ:åÌ{ù¹9dwHó&®\¹¢l³Gy¦¹pá‚’æå‹ÿýïÊü/¾øB™?xð`ºté‚»»»2OÞCBQ"}ûí·têÔ‰9sæpáÂ&L˜€‘‘¡¡¡J£ØØØXÉÈÈàøñãÌ™3Z¶lɇ~HéÒ¥100`ß¾}Ê)ùIïÞ½™8q"NNNôë×®]»âíí­¤ ¡ÿþL™2…»wïÒªU+Û¶mCCCƒ„„*T¨ 4ê®[·.ë×¯ÇØØ˜Ù³g+?4ä–»BˆÍÙÙwwwš7oNûöí•ùþþþQµjÕwZ>SSS%˜ïÛ·ØØXš5k†¡¡!ãÇÇÍÍMI¿téRŒyøð!'OžTæËº(ö‚ƒƒùî»ï˜üðC èB!J¶>ú(×ÿüsùd‹"ã“O>Q›¾{÷n¾Z ñ:¶lÙBZZ­[·æúõëLž<™Í›7Ó¦M „®®.S§Neîܹ„„„0yòd&MšÄ€hÚ´)cÇŽ%##ƒÌÌLŽ?΃òП={ưað²²bäÈ‘888Ï·ß~›+è?|ø¡C‡* áŽ=ÊÔ©S™>}:åÊ•cÆŒhjjrëÖ-ÜÜܘ:u*ŽŽŽlܸ‘Î;K£8€çÏŸ3`ÀµÎò‹›óçÏ£§§G||<úúújw7îܹSìѪU«°µµ¥S§Nþk¾L™2 2D>Bsööö”)S†Ò¥KÓ¶m[’’’ˆŽŽ&33“øøxŽ=Jùòå•ï–¨¨(zõêÅ¢E‹(S¦ ZZZxyyñå—_Ò¯_?åJ8?’““ÑÓÓcÓ¦Mpþüù\ òBCCÙ±c«W¯¦råÊ”.]È~~Ê”)Lž<MMM233¹wïýõ^^^Ô«W””€bÜ(®F„‡‡“œœü¯iSSS ¦K—.DGG“ ¶¼oß¾üõ×_ÅþäýþûïqppÈ5ßÊÊŠ§OŸ*ÃGqqq¯u¬ÿ«„„å›PˆÀÐÐÒ¥KsöìYvïÞM5”`šœœLxx¸8333000 lÙ²hhhP±bEÊ—/OåÊ••×Ìò«L™2P©R¥\˵µµ‰¥k×®¬ZµŠ¤¤$eYùòåÑÑÑ¡T©RÙÝÃ6iÒ„/^ðøñc%m± è±±±Ê ù¿þú+‘‘‘¯µÎÞ½{ñööæÚµk%ºέ[·”ç-/^¼`ÿþý 4‚ƒƒå.D!ðõõUkØ+Þ­O>ù„µk×*=­ijjbkk˨Q£X»v-ÄÞÞþ•ÏÌÌ oooÜÜÜ”+õ×=Ï®^½Jƒ Šg@ŽŽæÆtíÚUÎÒÿ³qãF‚ƒƒ©R¥ ¶¶¶üþûïÊUí•+W4hP‰ØÏµk×#\y.\àòåËREÄwß}ÇÂ… 9sæ >>>hiiáì쌣£#•*UBGG‡3f¼órvëÖ7òÓO?ýkÚøøxŽ9Â?ü@³fÍŠg@ß­_¿ž3gΨͻxñ"nnnѺuke~ff&–––ØØØ°zõjæÎ«¶^fff®ÆIEщ'ÐÕÕ%--­@o‡_¿~àà`üýý (Òu’™™É Aƒòl)„È–••Eff& `ذahkkóðáCŒ6lááá,_¾===eœÏÕÛú|½¼Íœ[ûy¥ì–ø/·ƒz¹ /ocäÈ‘L:•>ø@™/½‰åñãÇÂÓÓÈî©(44TYöèÑ#š7ožïwüß…çÏŸ£©©©v’„/^ššJbb¢Ú3¬¢úEµwï^úöí«ö Mñÿ¹¸¸P¾|yNž<É÷ß³³3*T ++ ___\]]©V­Ÿ|ò ZZZ”/_žM›6±víZ.\¸@=¨R¥ !!!øúú’””„¯¯ïk=êÍ¡­­ÍÝ»w3f ¾¾¾4lغu믯/ ÍÑ£GY¹r%£G¦k×®ìÙ³WWWbbb¨U« }¹KãÆcúôé8::âååEݺuߨӘœ×!æÎKçÎ¥b‹‘o¾ùgggyN+Ä¿˜9sf®yZZZlÙ²%Ïô}úô¡OŸ>jóFŒÁˆ#Þ¸ 5Ê•ßßû‡UyòÊ{Ú´iy¦•+ôÿ³råJ,XPdË÷èÑ#–.]ªœpÿåöó±cǰ´´dÅŠ”.]š .°uëV9 Љ/¿ü’•+W2uêTþ÷¿ÿŸŸŸTŒï¹÷> /X°€¹sçÒ¦M›·6˜}A¦U«VyþÚ̯ˆˆÊ–-‹¡¡!U«VÅÅÅEi("Š¾Û·osâÄ ûu—råÊÊ;úBˆ¢í½¿åž˜˜H™2e^Ùa@N ³²²*´2edd("š4i‚••“'O.«0MMMtuu•éôôt¥!J¥¢Zµj…¶ßééé\ºt‰6mÚÉså÷ß§C‡…šç­[·¸{÷.eÊ”Qú ÔîÐH·¾Bü»ÇóôéSåm€ÒÓÓ©Q£†2/00Pé]ÓØØXíûèM¿?~ŒòÛ»wïù„Ÿþ9×|SSSÚµkÇÞ½{_+/¾ø‚)S¦°lÙ²B;÷ìííÑ××gÿþý¬[·Nù2Bä?¨æ¼Ú ¡¡µµµÒš<Ç;w066ÆÙÙ™+V0aÂ<==±°°ÀÚÚúº~' €~øeË–±uëVå-¥—¯àOŸ>››Ë–-cáÂ…\¹r[[[Ö¬YêU«èÖ­çΣZµjÔ¯_?W^E& '&&Ÿçß»x>˜œœÌÊ•+¹wïwîÜáüùó¯,ßù4hÒÒqýúõTªT‰K—.allŒJ¥zeùÚ¶m˹sçÞÊ¾š››£¡¡Axx8gΜ¡ÿþôïߟY³fI||<ééé¬]»//¯©‡øøx~ÿýw6l˜ïG †††TªT‰»wï¾ö:zzzT©R%Ïk¾úê+>ÿüsµ2.\ yóæ\½zµÀöÆ xxx‘‘A\\ééé8::Ò¿ÿ7¢(KJJRÛ÷ÂúÑø¶effù> ÞwIIIŒ5J­á¯††ýû÷çƒ>È•¾~ýúXXXPªT)Ú·o€ ýû÷ã‘<ÍÌÌhذ!@žo%%%±wï^ìííùå—_Ô:Ÿ±±±¡B… èëëckk dHšsKþeEæúüùó_9|b~^â›ÔèèhjÔ¨A•*Uøè£°¶¶FSóíÿ*_¾<·nÝ"&&sssªW¯^$މ‰‰ .\@¥R±`ÁRRR8yò$+V¬xëyݾ}[9á#""ˆŒŒÄÌÌìí÷“'O”釃‰‰ S§N¥~ýúvŒîÞ½Kƒ (S¦ zzz”/_¾D~É.]º”‹/ªíwqôðáCfÍšÅ$rQü1ÚÚÚ˜™™Ù‘'«U«FDD[·ne̘1üðÃoÔ·|‘ è...¯\¶aõAæ Ãþýû• 9s&8::¢££óÖó ÆÉÉIiìPÔÄÆÆrïÞ=š5kF·nÝ $7Ò¿bccyúô)3fÌàÛo¿ÅÔÔôîûÝ»w™|H“&Mpvvfúôé…VŽÎ;£­­Íúõë±´´,uîááA«V­r}¡ Q.\¸@TTT±)¯““Ë–-cüøñôêÕ‹&Mš(ݤ¾Ê¦M›8}ú4IIIÊ…ÆÛ¸S¤‡škyxx8³gÏ`Μ9|ýõ×ʲ•+WÀÇ•Ærr…þ/ttt˜:uªòZB©R…[5vvv¹9TªT‰ÄÄD^¼xñNë¦_¿~¹ºB,hVVVøùù¡¥¥ÅÀìhþúë/%MXXX®Vªo*..Ž%K–pòäIeˆÅú¹péÒ¥W扅…eË–•­ÿ¢J•*T©R€””ÒÒÒ022"==fÍš)Ï6oÞ̹sçèÝ»7¡¡¡L›6 lllX·n_|ñûöí#==•J…££#cÇŽ}­2˜››sðàAœœœØ¸q#\½z•ƒ²lÙ2¶lÙ‚©©)'NœÀÛÛ›¯¿þZ|Ò¤IDFFòé§ŸÙ½„Ι3‡)S¦pîÜ9¥<+V¬ wïÞïw@¿ÿ>zzzTªT)ûv…¦f4z{­[%šE÷f‰††F¡µ—T½œwJJ §N¢S§N,X°€•+W¾•¼Ž?Nff¦ÒŠ5¯¼ {¿ÅûáøñãôìÙS*¢€µiÓFé$¦T©R¯|›ÆÑÑ1×ûæ‹-bÑ¢EoüýÙ±cÇ\wZûõë§Ö'¯;±ššš¬X±"WCdWW×¼ãÈû|€Ïœ9ƒ‰‰‰ZÏA¢h=zô ⇢gÏž¹7.]º´Ð^ hÛñ~)vÝÁÁá?­?{ölÖ¬YCPP7oÞ¤oß¾r#£F²ßBȹ=þwOŸ>åÈ‘#JÚ—y{{Ó¡C% {xxàããCéÒ¥•ÛZBQ«{{}úô¡FìÙ³ç·Ñ¸qcBCCùðÃéÓ§O¡öUþ¦¢££122*ð|ÆŒóÊ YT1eʆަ¦&ÚÚÚ¹Ò¤¤¤BíÚµÿq[eÊ”!!!ààà"ÿ¾·‰‰ 'NdĈ¸¹¹É7—ù”’’Bjjª2ÂËý›)?òHHH²ÛV½üݱ±ñådß‚ÏëuÜ—Ó˜˜˜(ÿâââHLLT¾³r¾«ž«+ôgÏžqúôie‡lllðõõÍ÷v~ûí7¢££‹Í~ÛÙÙ©õ7\Pbcc‹|`ÓÔÔDOOcccöíÛ÷Ÿ—ôêÕ‹ˆˆvïÞ]äßÎD'>>^¾™…xƒ€úÍ7ßðå—_pîÜ9FŽÉÈ‘#iÑ¢ëÖ­#==Çãàà@Ïž=>|8mÛ¶åÖ­[ð믿ұcÇ7Ê{Íš5´jÕŠ‘#GR¯^=.]º¤–&))‰•+WÒ¦MT*»víR–Íš5‹~ýú1räHåÇü7hÒ¤ ½{÷fäÈ‘„‡‡¿€>tèPµgŸK–,ɳomcccjÕªÅåË—سgƒ R–khh0gÎiˆRLU«Võë×Ó¥Kµù§OŸ&88ø•ëùûûçù°ÿþJÅŠBçéé©Ö+¡(¸‹Á—µÝ¸qƒ'NpâÄ \]]Y·n/^¼ÀÇLJ{÷îááá§§'666|÷ÝwrêÔ)µ.Y_Wtt4[·nåûï¿çĉ,X°'''µ4‘‘‘ìÚµ 777Ö¬Y ”rš››³wï^Nœ8¡´·X¼x1Æ c×®]ÄÄÄ(wV‹U@Ÿ4iÒ+{jûõ×_©]»65jÔÀÔÔ”úõëóûï¿Ù¯$Œ3F- ¯^½šO>ùDÎôb¨V­Z¹^ñkÛ¶-™™™1oÞ<µeiii|þùç\¾|™ºuëR§NµåŸ}ö*TŠ…nÏž=DDDHE°Õ«W3wî\ezêÔ©Êÿcbb˜3gåÊ• K—.X[[£££Ã¤I“”ý«W¯~ã7PêÖ­K=råÃÄĄ͛7ÓµkW†®Üæ÷ññáĉÌ;Wm¼ƒ9sæ°lÙ2jÕª…2¿Ø·rß¶mŸ}öTªTI©ˆ^½zñüùs6l˜çcÅÅ’%KhÒ¤I¡üXúûoqR½zu¥·7n¨=gþù矕¡`›7oމ‰I±ÝÏwùj¥}§´8 H3nÜ8>œkó€€6lHTT#GŽÌ³=NaÑÓÓ£mÛ¶JÀÏy¾?dȶnÝÊ;wøøãIOO }ûö”-[–K—.±víZå;¡Ø3XYYáááAPPZ«fCCC233¹uëU«V-¶ûgnn^(ˆ˜˜˜```P"¾p´µµÕŽyIêUmæÌ™ 2D¢Šxg>|øF·žß…ÐÐPRRR¸víZž?ŽuuuÙ·oGŽ!##ã—7<<œÄÄD®_¿d7ÖkР7nÜ **ŠaÆ)iÓÓÓ böìÙÊ|ù©_ ôéÓç‡íË.]ºë Þ¢E üýýs 5ª©©I«V­xúôižc–––Eºê÷ÑÁƒ¥аuëÖQ±bE8À‰'ð÷÷çÞ½{@ö0©W®\áÊ•+¸»»+-Ûß•àà`6n܈ƒƒCž=`þ½;è;wòøñc¦M›öÿ¿ëä}óçÏ/QÞþnÒ¤IÅúvôÀ9vìX®t´µµ2dÁÁÁoÔJµ¨hР D’W£\Qtôë×5jœœLZZdddðå—_*ý¥ïÛ·   eãÇãççGJJ ß~ûí[)Ç­[·8|ø0=ÍßEGGãîîNÏž=±±±QÒœ={VfxëÖ­Ê]h777’’’˜1c§NâÊ•+@}ÝÃà 6(Óÿ4º®®.®®®j}|ç˜8q¢Ò0NQtÌ;·DŒ‡.жV­ZѪU+Nœ8Áï¿ÿN:uèÚµ+;wæÈ‘#Ü¿Ÿùó磫«K›6mhܸ1Ÿ~ú)*T >>žÕ«W³fÍ>LPPmÛ¶eüøñ >üµÊP±bE™M™2eäÌ~O>|8Ï6M›6¥qãÆRAEÄÒ¥KÕ>³“&M*ôQýÄû¥K—.Ê:[[[åÝm€råÊ¡¥¥…±±1ßÿ=)))hiiQ®\9¦L™Âĉ•ô¥K—~í|utt˜6mšZ×Òúúú4lØöíÛS®\9444xðà²\CC€ñãÇóÙgŸ)ëäÈ(&GNŒ+’]GGGíó¿d--­W>c.É£R=yò„ÄÄÄ|µ‚‰‰áÙ³g4lذDÖIΫ'ù9GDáûûçò]¶0ï‡R¥J©½vör€ü§ø“ƒþË…a©R¥rå§­­­vÞçUž¿§ù·¸&ÏЋ±›7oòäÉ“|=¾w﹎ !„(Þ$  !„Ð…B¼®„„„bówIÒ¼ysT**•ŠãÇpñâEêÔ©ƒJ¥¢V­Z„……‘––Æ×_MÆ Q©TôíÛ—¤¤$éÝ»75büøñ$''¿vÞ™™™xzzR¯^=T*õêÕË5&Cff&¤^½zÔ®]›€€eÙüùóiÔ¨*•JéíîÅ‹´hÑ•JEýúõñðð ##CºB–þã[;âíûã?¨_¿>~~~øùùѳgOÒÒÒèÑ£ãÆÃÏÏ>úˆöíÛsìØ1¾ÿþ{ÜÜÜðññ!$$„Y³f1}útÂÃÃ9tè.\àÿûßkçÉgŸ}ÆŒ3ðóóÃÖÖ–Î;«¥ füøñÌ›7Áƒ+QÃÂÂHMMeïÞ½øùù±zõjå<222ÂÏÏeË–1{ölnÞ¼)½¤:xð ýúõ“ŠB¼×fÍšE:u8tèÚüºuë2{öl\\\ÐÓÓ`Ĉ´k׎²eËâêê @çÎ9pà5kÖdÉ’%ù.C‹-?~<›6mʵÜÀÀ€U«V1räHV¬X……‡",, //¯\=ÙålgàÀtïÞ[î%–›››2°€B¼Ï]OOGGG~þùgeþÇÙºu+=xKΘ㯺³R­Z5"##ÕÆ‰x[Œ•ÄÖ¯_¯ŒÀשS'ºwïκuëX¸pá¿n§”n!„%U·nÝèØ±#ÚÚÚL™2}}}ºw³3S§NÅÕÕ•»wïâííMTTÔ?nëùóçhkk3zôè+ï©S§Ø¸q#Ý=mýúõiժ͛7GCCƒ¯¾úê•ëÊz1¥¥¥E5¤"„â_hkkãààÀ´iÓˆ‰‰ACCƒ¡C‡òøñc>LÏž=ÿµoŽ{÷î±hÑ"~ýõWÌÌÌÞzãââX¾|9¹^+®[·.—.]Rë|Fz bhh˜ç³˜<Øššòþ¹â½òÛo¿‘œœLDDiiiXYY)Ëîß¿»»;Ë—/W:vùã? !==]vùòåË8;;³sçNBBB¸yóf¾Ê†¯¯/žžž¹–'$$°iÓ&¬­­éÒ¥‹’&00PéùÂ… Ê«Ýý+ÀíÛ·¹ÿ> ·Üß»«úeË–áîî.•!„x/¬^½šZµjQ¡BºwïNË–-ÉÈÈ`îܹ”+W{{{êÕ«€µµ5IIIL™2+++>̦M›Ø²e ÌŸ?ŸÀÀ@Z¶l‰µµõkåo``€­­-'N¤mÛ¶xxxð¿ÿýË—/óóÏ?ãàà€††nnn|üñÇ\¼x‘={öÊÉ“'ùå—_hܸ1 4`òäÉŒ3†É“'s÷î]®_¿Ž¥¥%Ð…B”쀱±1666@öÝÊ=z`aaAƒ ”´5kÖÄÍÍMbuøðá4kÖ ÂÂÂèÑ£5kÖ|íüõôôXµj•r…Þ«W/:uêDXX=zôÀÈȈҥK«5¶³³³àã?¦nݺ@v¹ýû÷ÇÄÄ„””zôèAÆ 111‘€.„íàÁƒäzÿX¼œ þ2 ºté’gúêÕ«S½zuµy9ÓÞ”±±q®ü*W®¬6îy^å±´´ÄÒÒ2Ïm¾|û=‡”#%D bffFVV–2ýª¡,…Å< ÿýyEll¬ò¢½øwÚÚÚhjÊÓQtýýùßñãÇ9sæŒTŒ%- ‹ÿfåÊ•\»vM*B!Þ#r'„BH@B!„t!„BH@¯fii‰–––T„BH@ÅÙ–-[066–ŠBˆ×àíí-]!„(îfÏž-]!„Ð…BAëÖ­SÆÜ~L™2¥X×Azz:/^¼€.„¢øŠ'))é?ÃgÏžë:¸|ù2sæÌ‘€.„B èB!Þ???öíÛ÷Zi‰ŽŽ–J“€.„¢¨yôè~~~¯•öôéÓ$$$H¥Erp–¨¨("""”éÐÐP9RB” ÷ïß'..N™.îÏZ…€þ W¯^eÿþýÊt`` )!JÇãïï¯LߺuK*E¼S œ:uŠN:I@›ììì°³³S¦7lØ€œqB”Ó¦MS›5jAAAR1âyúô)ëÖ­+Ö]ž¡ !„%€t!„BºB!$  !„BºB%IIIìܹ“1cƼ÷u1sæL9!$  !Dñ”––F@@*•꽯‹ß~û­DìÇŽ;ؽ{·t!„¢8{þü¹Z'HÐ…B!]!„Ð…B www&Mš$!]!DqV¯^=nß¾ýÞìï’%K8~ü¸t!„â]:qâÄZ?==ÌÌL èB!Ä»4oÞ¼¹_Ð…Bˆ HŸºiÓ&Ö¯_¯LGGGË‘¢qrrâìÙ³Êthhh‘/ó³gÏ022zëÛ522ʵí.]ºpòäI9QDñ¿B;v,~~~ÊßâÅ‹åH Q‚¬[·Ní3Þ§OŸ"_æ‚'û·ß~£sçÎjóž>}*'IɃ$  !„øwñññìß¿_*¢:{ö,»ví’€.„âß=þœ­[·JE èB!D^æÌ™Ã½{÷$  !Äûèþýû$''KE”="%%EºB¼,XÀÇ¥"„t!„BH@BQ@îÞ½ËW_}U(y]½z77·b_gãÆãСCúHºB”d[·neÔ¨QR¯P©R%j×®ýNú¶mÛðóó{ã€~òäIzõêõÚë̘1ƒ¬¬¬¢ÐSSS™7o×®]ËWÉÉÉL˜0•JÅØ±cå]N!Š ””,X€J¥¢ÿþ$&&¾öº/^¼ M›6¨T*¾ýö[ÒÒÒJdéééåzö[¥Júõ뇋‹K±Ý¯¤¤$Ž;Æ–-[JÜ1»yófž ×~ùå—\ãhjj¢­­ýÆ1jÖ¬Y|÷ÝwEÿ =>>žõë×ãáᑯ}üø1_~ù%£GÆÏω'²|ùr¢¢¢äTˆ""66gggÚ¶m‹ŸŸk×®eÞ¼y¯5ZPPœ8q???ŒŒŒØ´iIII%®žòDE[[===bccÕæW®\™¸¸8âãã‹ô>effâèèÈêÕ«‰‹‹ûÇ´èêêb``P,Ž×ãÇÑÑÑ!444×L """”iz÷îͰaÃÞ¸ÅÿÓ§OIMM}§ûü¯Ã§fddàîî®üÍS§N¡««K‹-hÖ¬gΜÁËË‹áÇË7©E€ŸŸÌ;€êÕ«Ó¢E vïÞÍìÙ³ÿq]WWWFžž#FŒ`À€tíÚ•Zµjå»,®®®hhh¹:º{÷.QQQ¬[·€ððpeùåË—Y·nrÁÓ¯_?ÆDze˨Zµ*7nÜ ^½zlÞ¼CCCîܹÀ“'O”íæ¬ïãã£6¯ ¼|{øÜ¹shjf_ãмysîÞ½«”áÂ… tèÐkkkÜÜÜÐÑѲ{Ñ S+off¦²^ÎüÄÄDZ·n——W‹}íÚ57nÌîÝ»‰ˆˆ@__@iÑÿò±tuuåÚµküþûï\¹r…uëÖ©çS§N)ÇÖ××—ÚµkÙí(Ê—/ÀíÛ·•m&Ú¶mûz ^½zôîÝ›óçÏX¡Ö¬Y£œÜÀW_}…©©©| ñ’!C†Ð¥K—"_Ή'¾òv|ÎsÖiÓ¦Ùò/]º”àà`¦NªÌ›zôˆ   \?ô–.]JPPZy+T¨À† 8sæ ‡Vî\XXX°}ûv¶oß^àûÖ¼ysÂÃÃñööÎUÞÐÐPµò:::ÉÉ“'9qâ„r,úé'|||سg’¶iÓ¦<~üOOÏ\yÆ1{ÙŒ3Ôº§§'K–,É•påÊ•tëÖÞ½{ÅÜE0“IDATx¡>þøãWŽ7|àÀ.\¸gå ñ¾kܸq±è&LP®ÚþîÉ“'ÊUpQuèС\ó<<àÆ^æÂʧuëÖœŸ|ò «V­¢fÍšš““¤M›6šÏªU«¨Q£,Ð|¶mÛFlllÿ2÷ööæäÉ“¬^½ú}Nÿ ›¼J¼ví*•ªÀËѧOÜÜܨ\¹r¡ìwa}O<þœ¾}ûrúôéBÙ¯pûöm.\XàyýðÃhhh0~üøBÙ·Âú.èС‡~ã¶ /?¢*•3CKKë?êñãÇx{{Ó¢E åÙYµjÕ¸{÷.áááXXXIRR5jÔÈwóS¾·±?E1Ÿ‚Ϋ°òÑÔÔDSSSò)"ù˜šš¢§§Ç½{÷¨Y³&±±±„‡‡Ó Aµt·nÝÂ××;;;åp³fÍøã?hÙ²%:::üùçŸXYY)Ï+ó»…ñy å|øpvïÞÍâÅ‹ÉÌÌDWW—ñãÇK[!Þ èššštëÖ @ù²; x™µµ5^^^¹~Õ·k×}}}ž>}б±1|ðA‰©Ÿþ9žÏäÉ“133+1çA·nÝHOO/ð|š6mJõêÕ lÛeÊ”!<<===Z¶l™+ÍÀ±±±¡Zµjj󌩩)éééÔ¨Q£PnS !Þ0 wíÚõ_7T¡B…W¦û§ggÅÙ‡~X(ùØÚÚJ>Mš4)”|r^ß)) ãGd?g666.°í7l؆ ¾r¹••VVVy.ëØ±£|› ñŽIׯB!D  µtéÒ¥%m§RSS•ÎlÄû+##ƒªU«ÊóÜb ==úõë¿Qcº7É«I“&…ò«°¿²²²hÚ´i¡ä•™™‰±±q=úûgÙÜÜKKËB;­­­)W®\ç•––FÓ¦M)õÿÚ;÷ («7Žå¢$šÁ8`c\ºxy»R4Y“:[6–»J Ñ€b䤯‚Qh¤™â”#CA,E2L0Ñ4…K5³Æ¶îl@æŠ\$¡¸,´ì>¿?ˆ3 ýÏ 3¼ç9ç¼ûžË{ÎsÎyŸG&û×y9ÐÿÓ’¼@ ‚IaÊ/¹Ûl6äççC’$H’dg3ùJ3ºwÞy‡¥“$ €ÕjüüóÏœìñÇŸ±N%f ‹kÖ¬$IHOOgu9]]]\]mG™™™v²¥K—B§Ó‰ŸDm',, ’$aÇŽ:@ØØØÈꥤ¤BÿL6l°ë÷C3Y,¬]»’$!%%…{×X­VLÝÝÝc¦]±bŸˆˆš››)..Žôz½(ôI ¹¹™âãã©¶¶–ˆˆ***H¥RQ{{û˜iÏž=KÏ>û,»NLL¤“'OŠBL:z½žBBBˆˆèÂ… E&“‰ˆˆÔj5eddPgg'™ÍfÊÌ̤>úˆˆˆ:::(,,ŒÎ;GDDµµµ´yóf–ï¶mÛ¨²²rÌû÷ööRNN=z”ˆˆº»»)44”~ûí· =Ç”ÐÍf3qauuuôÌ3ÏŒ™V£ÑPYY»6™L¤R©èôéÓd³Ù(55•‹ôèQzÿý÷EËg½dggÓ÷ßÝî¹k×.*--åÂÂÃÃI«ÕŽ™V¥Rq×_|ñ%%%ÙÅ»xñ"¥¤¤PUU•¨äIâƒ> ¬¬,.ìõ×_§’’’1Ó®Y³†ZZZÆ5û/óÃ?Pvv6dgåÊ•ÔÑÑADDÉÉÉTTTÄÉ£¢¢èôéÓd0hãÆœì믿¦øøx""’$‰l6Û„ÛlCC­_¿ž «ªª¢­[·Nè9fì)÷ûï¿r¹À€û×÷Þ{«W¯FPP8s…„³³3¶nÝ*Ö¢þ¡²²òŠÎx¬Vë¨v¹§IIIìÿ‚‚F. ð ƒO?ýtÚ˜R´Z-JKKaµZÑÕÕ…wß}WÊ),,ĺu뮹iíëì¿Pa/½ôíŒÞF[æÏŸÐÐPѲ‡ Óé˜Å°á¸¹¹!::zÚ=ÓÉ“'a2™gggNæââÂ>^̨ªª‚B¡`î`§33ZikkCDDÞ~ûm»Á¼¯¯999ðððÀ¦M›&å“™@OO$IBZZRRR IÖ¯_ÏÅ‘Ëå Äk¯½Æ…òÉ'¸å–[ I*** I’““ÑÙÙ "BYYwE.—£©©éš?áË/¿ÄO?ý„¸¸¸ 899!88ÁÁÁèììDWW—h ‚i…‡‡ÊËËÉÉÉ(//Ç7ß|Ãú[aa!úûûÑÓÓƒŒŒ ®/ÆÇdzƒ¢555œì«¯¾bž0ãââ ÑhØ=SRR˜L³ÙŒC‡qicccÑÞÞ`À•©Z­f²{î¹&“ À€·½Í›7sisssa±X Ñh8·ºuuuxî¹ç&¥ÌNœ8[o½uƘ#ŸÒº££#$Iâ<UWWÛ™¥¼téÔj5Î;ÇÂL&:„¸¸8øøøØ½àOœ8‹Å‚-[¶\7ƒÿÓÙ³gC«Õb×®]HJJ‚V«µs5X^^ŽÌÌL»S˜ýýýˆ…V«EBB´Z-\]]QZZ ‹Å‚={ö@«Õ²¿¬¬,ÄÄÄŒëw-]ºõõõ0›Í£Ñˆ… bÞ¼y\¼ÊÊJ;7»eee¨¬¬Drr²ÝÄM¯×ãâÅ‹¢â¯K–,AGG._¾ `ÀŸ¶““¼½½¹x?þø#Ôj5w"øá‡æÜzj4a_bÅÅŨ®®†^¯‡Z­FOOÜÜÜ{÷îEbb"Š‹‹YûðÃqéÒ%|÷ÝwhjjâúâŠ+püøq@TT'+..fýîï¿ÿæN|[,v]SSƒ††.íƒ>ˆœœöž6 LVSSÔ…}ûöáÅ_äÒ¶¶¶¢­­ 6› }}}Üû»··÷_—_{{;š››ÀwÜqΟ?Ï&õõõõ¸ñÆáéé‰9sæ`Ñ¢E0 ¬< ³²¹zõjTTTpÚÿ ¯òAl6Ôj5ç‚ÕÝÝ‹/†^¯gïRN7a+«SZ-uqqARRŽ;†Ï?ÿàåå…„„.ÞÙ³g¡T*qìØ1¼ð €S§N1ß½EEE,®B¡À²e˰gÏDFFr{© oŠkDcc#WÞãý6mÚ„üü|¤¥¥ˆàää„ððp;»â*• ƒ.\`a¯¾ú*ž~úiîÞžžžˆG[[ ¸ó>>>×͵æLG.—³Ï|ˆˆ™’nüäÈ‘#8~ü8¬V+s™””„ŒŒ VoÎÎÎØ·oŸ(Ô0hlldåÐÏ®9pàû?<<œî9uê×Μ9ôð‘òM6œêêj._Nǰyóæ!11qÜÏ·cÇàµÉ¤¾¾F£;wîä Ôj5ÒÓÓÙ»fãÆð÷÷DFF"??ŸMd†Žû÷ïGjj**++Y›î¿J¥‘‘‘l²³páBDGG#??Ÿ}ÖéççÇ9@›ö:,Z´¨­­<ñÄvqî¼óN”””`ùòå,lÐ)Ìp,XVCÅ®-îîîvÖDœ´„„„ ¢¢½½½X²dɈg"RSSí–Ë>Œîîn»•ˆÁv2kÖ,´´´0ÙòåËí4HÁÕóä“OÂÃÃðööÑ’ÙË/¿Œ 6ØHŒ‰‰aÏ]wÝ… ˆý‡;wâ³Ï>ƒN§×@9ôœ··7׃‚‚FìOÅËËË.ßÛo¿}J–Ÿ¿¿?bccG”) xzz¢§§‹/ƲeË8 >$$uuupvvf‡¯Ù¾};Ðxà;ks2™ %%%ðõõå £Ñ''§Ǻi? ~Õ‡kbC™?>Ö®]k7¸’–5<¾€ÇÍÍ ½½½¸|ù2L&òòòžžÎ4ë¿þú‹ÉçÎk·m1è^sx³kGGG»%ó±I ÊHsÆrrß}÷‰ ¿ÆŒt¸r(ƒû¦#µCÑW'gggøûûs}ÑÕÕîîî€9sæ°-Ü~µ»»;zzz8y__l6d2üüü¸|]\\pà 7Œù›fÏž ³ÙÌåûÆo !!2™ 2™ŒÉ”J%Ó–ÿ sçν¢Cª+­JÜvÛm£šõðð¸b›uttU€€€€«~&qL0"Ï?ÿ<222 T*áããÃö×€¯ÚÚÚXçÊÎΆŸŸ¼¼¼ØÞ·ß~Ë&c7ß|3\\\™™ ¥RÉÍæóòòDa WÉM7Ý4ª¼{ï½—m_ åÑGEkk+×år9[z.**âdYYY0°¤¼}ûv¤¥¥"""pæÌ¬\¹=ôZZZ¸´«V­ÂîÝ»Ø{tpp`“é7ß|¯¼ò ·E°wï^øúúÂ××MMM,ßÜÜ\¨T*Qù# l¹ `TÌf3{ì1TWWÿ_îßÔÔ½^U«V~ýõWìÞ½………¢r„†.‚i3HÉdÐh4ÈÍÍÌš5 Û¶m#4t@ L›Í†úúúIÙ·¾Zþøãö劫««0ú4 ÿ¼ãæ±±', IEND®B`‚snd-16.1/pix/88.png0000644000076400007640000010442111371053205012077 0ustar bilbil‰PNG  IHDR¹/~õesRGB®Îé pHYs  šœtIMEÚ(QýÄ IDATxÚì}w\ÇûÿÌ^ãè]EAAÄ®»b/‰Š5Œ½w±%ØbŒQb-[¢{EDìEDªˆ H;Êqw»¿?æ—ý^8Ž»Û«óþƒ×±;»;å™gžç™gžR0000 î ̰0000 „aÑš¦Ñ¨œÊ7kÙ 27»"""Ξ={ìØ1£é¬ñãÇWVVB”5jÔðáÃ1aa˜(ŠR<5ôa-[¶ì§Ÿ~2&q£Aƒ¯_¿...®©@JJÊ©S§<¨ç£Ž§  ‰ˆˆP04b±øãÇööö*‚Í /4:ºáóù5‰DjN*á™3gFŽÉårtlEEEJJJÓ¦MMg2ÄÅŵnÝšÇãÕ´VVVNžyòdÿþýb±xÔ¨QƒV,¸Ê>‹¡YMaÍš5kÖ¬QPfåÊ•¦fä2JàA¬E%lÞ¼ù¬Y³:uZºt©Ó9xðàüùó[´háïïO3,á¼yó"##eÙ„ðóçϸÓj-£ØÜƒ¡ñEB(‰˜vc’W {÷î 8|øðôéÓ«ºKp8œÊÊÊŠŠ 9FöË/¿È•d±XÈ ¥®Vf‚ °ÚŽ¡µE4<<<44ÔÂÂB«àöíÛ/^¼Ø¹s' ¢¢"66ÖÏÏÏÊÊ ‘HØl6—Ë­¬¬”cOª  -w;vìpppÈÏÏ7” ?~üXñ✘˜ˆG¶*Zµj•““S¯^==²´ªBÃÂÂV¯^½nݺ={ödee^»v­_¿~€qãÆíß¿Ÿ¢¨+V`ZÑsÑÒÒÒ€8l@@ÀªU«*** ƃ+×o>ìܹóãÇM¤ÉòÖ°aþùæ›ÊÊJ©TÊårÝÜÜbcc½¼¼PïtëÖÍÙÙ¹¢¢¢U«VXÝÐj6 Úúúú†……éÉ2n@+Sqq1Ò~L”aµhÑBN×kÓ¦ìºÝ¼ys£ÔøjuÅ$°š\¿~}Åþ„EUVV²Ùzá‹§${Uf0S3!†e²àóù_}õ•œmNƒ 2”æ$ùäÉÅeŸ28˜››[YY LϘa¿týðáC£Y½•9«¡˜;êׯïéé=tèP“"]e|GÕ¤[egz3,¦T Ê•z¢ájW¯^µ¶¶V@ÀC† 9qℚËù¾}û,XP­?*PRR¢ ¶ fXÀÞÞ¾Öµ–6C«ƒ¬¬¬¨¨¨N:éVÑÀ!ïšúËÔN9a`è!***4ÅA„B¡ÎU HX•+WÞ½{WîhNzz:& ½S W¯^-à‰Ëå®X±bûöí¸‹100ô‹añù|TœœœZõa///Ó‰O†Á8ÃR Û¶m»ÿ~“&Mj*Àår÷ïß/ «eˆj‚¢(eöÔ°&fXÿ&lذ!00PA™¸¸8{ö ÷fXBX«ï"`ÆâââïˆQSpz “cXº ŽûÃÔÜF¤Ã*S ÷–°00t ‡Ó»wo™n%ɉ'úöí‹û 3, ‹W‹/^¼x±‚2üñGvv6î+“V k°Mð*†¡Œ=ÎÈT` KEBÙ¸qã£Gd)† ˆ×¯_ãþÅÀÀÐ;•púôé!!!²W¸\îºuëRRRpc``èêš T í#''G*•*ÐdÍÍÍoCS™cv W`3†nP¿~ý#FˆÅbóvêÔ©ÆÔdŠ¢öíÛgmm­ —Ë>}:³F]!ÿÍ›7è"„{«a†…(ŠÊÎÎÞ»w/EQæææA,[¶lÍš5EEE~~~B‰D’™™I’¤œÿEQ$IæåååçççççÊÊÊÐÝÒÒÒüsòòòòòò¯Lee%ú]µ2.\(*****š5k–¹¹9Š“GQ”âˆ1˜aa˜ŠxuôèÑÌÌÌÏŸ? …Ââââ/^œ>}ðúõë}ûö 8$É>}úDGGË=¸mÛ¶I“&M™268uêé <<|Ô¨Q£GvttLII9{öìĉ'Mš´uëVadd¤““SzzzÕÊ sæÌa±XMš4‰D€—/_~óÍ7x°0ÃÂÀ, Bˆ”>â_€Ó)ݸqƒÅbEFFöíÛWN)#B"‘ܸqC*•N™2…»£(jÅŠ‘‘‘\.÷íÛ·¾¾¾ÁÁÁfff‰½¹S§N—/_®š-‚~›6m(ŠBíÝ»w{÷îýû￱Jh$"=†Ê I2;;{ðàÁè7EQ¡¡¡wîÜA¿åâ+È^D¿ËËËQ¦UtÑÑÑ‘¢(¤÷Õ«WOî "‘=ÈÈȨZŸ¶mÛ¢sæÌyôè‘lT Ù¯c(°„…¡®JH„³³3­‘ÙÚÚòx|øöíÛF36Ý»w—J¥tì’$ïÝ»§ä7Œ:>øàÁƒ¥K—¢ß3fÌ@‘³0ô “'ONII …GmÑ¢³Ó¹@Ë–-†¾&-- Àb±ØlvóæÍ)Š@,=Ý\ºtIý8-*ß5J¸¹¹¡¾=sæŒ@ ¸{÷îüùóq =ŸÏ'IR*•öïßG[³f Cßbãõ¡&>N)Ÿ2eÊèëÖÖÖèÇ©S§N:øã?<==)Šrvv¶··¯u…‘½›’’"‘H¬¬¬ ”••Uµ°D"IHH())z{{›HçgeeI$úJ½zõ‹ÅBÙ¶µY=”U›ÞóÑrç°åz Bxúôéüü|´©, ¯^½Ú£G$~‹Åb.—kff†ê*Vpªf7È¥¢2§IBxýúõ’’’¾}û"—1ƒ¨ÿ¹sçH’´´´¤}¯LÀÎÎ.00P"‘ 6¬ÚîêÞ½;q.—«ýÒS[û„›«3gÎ3fLjjj¯^½ÊÊÊ>~üüìÙ3T`öìÙ7n>|xxx8^ õ“É>|899yÕªUYYY†¢4Q5f̘¤¤¤cÇŽ©`ß1²ÑìÝ»÷ýû÷?~Œ¶h ·©AÞ†µfÍšÕ«W“$I’$ŸÏwwwÏÊÊ¢ˆûûûoß¾]"‘¸¸¸à£sú9óCBBÐÒâïïÒŽCØþoÖ¬ÙÔ©SëT[6›mii‰2BçççÛÚÚÍ8ÊŠ™Š»¢²²R›ã‹ö+e,3¬úõëÿG#ˆ† ÊvíekdÜ Ù­lmm¨åäädnn^^^¾}ûöùóçë9çªÉ©GAù¼¼<ô{À€jP¿ÓD"Q@@ÀǵF`£Fzÿþ½’„TQQQZZZRRÒ AF–É¢Aƒ#FŒ‰Dƒ 2‚æ$ ˆ‰‰Y»v-—Ë%IÒßß¿[·nƧô£f'”••YXXhó£<OÉEBèïï?iÒ¤þùGSÖ Ì°þ¯sÏœ9c( T­ wŽ|||¦OŸ())ùá‡nݺ…ÇZoÅ%Du666u2ÏÑvwæüdg„ò¬B!«–i€°1¡¨¦’J£G5jÔ¨aÆюû8 ž~.™K—.E^)è@˜’O]½z•iwtúBÈb±¬¬¬T÷5U,aù ³X¬§OŸº¸¸|þü¹Aèœ/ÓuÀŽcÈÙ‘• ;;;´ü M9|ùòåéÓ§íÛ·WAA{!9B#d§@×ÅÐØØØ|úôiõêÕû÷ï×)BøøñãÐÐЕ+Wªc5§ƒ”ºð!D!tTóM !}v¥®u[¾|9ÐôBÂBÞ[7oÞ”s¹üòå fz¨$þðÃVVV(†‘Îqîܹ ´nÝúÛo¿UˆÙl///‡3mÚ´Å‹ãQÖ7’[¾|9„P#G_Ø©ÐîÝ»«e«[¶l©UPpE;½ þÇÔÄÒÒRô£²²Rö”•NЮ]».]º¨3‚ׯ_¤§§¯\¹3ý$9Ú~ª–jO}üøñÝ»wèß-ZÐ[ Úä\OŸ>íÔ©“··w×®]MgÅClºmÛ¶F3€áï$\¾|ÙÛÛÛËË ó8f–ÊØ½{wjjª——WRRÒ£GúöíK’d—.]&Ož¬eyuÓ¦MÀd‚Ð3\,ë\¼‚jêð ʃ Ö+ùÊ=ÕâùŸÏŸ={v—.]Äb1Š¥) çÍ›§M†!¤à™Ú^‡ÃA‡®*++Ÿ¥é—㨙™ÙÚµkKJJ&Mš¤Ágýúõ9998ò„N” ÍŽ2EQ´¶Y$ÕÁFQÔ‰'Ðï6mÚhŠ˜!„¿þúë­[· „÷îÝÓ‡)ýQ‡3}úô‰'òù|­±H`Ú†Àãíja€Ž7ÎÜܼI“&ôw55šÝºuãóù½zõ2)‹$sòò™3gvîÜyàÀÄÄÄÎ;ë¼¥Z•°PXU;;;Ýî†`yJnnníÚµCgëþ¼@ èÔ©Ó_ýeâ@I’S¦L‰ˆˆøæ›oðÄÀ0Z†ذaƒœ¨Âår—-[¶mÛ¶šä&Åk`yy9EQ|>¿]»v AÝ»w0`Öe×OOOúì†Ñ2¬j% uükè|ˆš:‚¤¤*‘™™Ïãñ¼½½qo0ŠÄÄÄŠŠ +++CÌà©:Çùo†ÀºÎ> ãÿàëë{íÚµC‡íرùÓBo/X° ¼¼|̘1|-EQ:?q¥ n¡¡¡È„?cÆ wwwÝHXFŠ¢<==Qà½{÷t[ds½uÈ‚þòË/*Ë ÚîááJ¥‘‘‘žžžúÓä={ö|þüBøÇÄÇÇë#Ã’={!—’CßæˆÍ(¦Å·ôôt:ª‰AdfÕTçSõòåKô{îܹ@µ—0D îîîˆI©ì=£ «K—.111ª-wEáÈ¥F‡ãçç‡8sR\l“]uT^P$X@`nnþéÓ'½j 6–X,¦וL)Š?~<’ÑÂÂÂÔq”]7ÌÍͱFd‡Iƒ*Ç£s»´¨hôèÒ¥KXXXEEÅ”)SôJbÐwÖÅ‹KJJØlvXX؇ÔaX¹sç?~PPPpíÚ5L—5¡¼¼ÜÉÉI*•š™™ipŬÄPÀãñ–-[¦‡cÐÓ]#hРÊ‹"7©‰„„„¬¬,ú "öÀªU¥ÒÈ¡ =bXÂ;wî|øðá?ïe³ôPçO„àËAº’^Ïž=kÜáú4Vhä-•••¢*@¶U-l a`óÍËË[»vmQQѱcÇðéF%ìÓ§OÕëïÞ½»víÇ Ä¡+õ–Ïç‹D¢¬¬¬† êI­Z·n‚:S k¢Š˜®™¤¯ÿîUáaÆP’[!"œ0a‚ìVµn«Äb±è㱌’1„ðÓ§O1k¶nÙÙÙfffurÏdk­~ê¿äСC÷îÝóòòúúë¯ñlÔ$Éo¿ý& Y,ÖÂ… UÇÊÊÊ;vðùüòòrèƒEEEú°ÎAOœ8¡x}ûö=vì˜T*MII¡½Iõ;vܹsç;wnß¾““SçUˆ  mQM½-==ýÂ… çÏŸoÞ¼y]Ÿ•J¥èÇ€òóó) ¥qûöí .DFFÚÚÚÒÝXW”””¸ººÞ¼yóêÕ«:iEzzzß¾}õ¤K9EQ$I2úÙ÷·iÓ¦®[YYi§n...uzÖ0ÎRÕ¤I“&Mš$¹bÅ tIziźdº½gÏžè7r.Q5 Ò‰:ˆçÑ£GzÒ«ÈS !Ñ:‹2‰D|>BÈtMÕíB1sd[èââ¢B*'.—‹8´:9ÑL šŠ\Ìápè}Ú_0ÐI’LHHxöì™jÇëÔGqqñ³gÏÞ¼y£ÏÙR)Š ¤% -|ÑÝݽ¸¸ØØ–¬¬´nݺ 6¨0˜éŠë………Í›7O·ÕX¿~ý¾}ûfÍšuþüyTàòåËÓ§Oß·oßúõëõy¼è¼ZXZ(Š:tè’´¦°¼J({p¬ªôNßÕaÈ¡PX§œ:¨ªj¦oÄ (Jå]Ú°°0´bëJ§(jáÂ…€#GŽè°§M›6mÚ4€·¹e³²²2 % 7mÚ”¨*Â@!„§OŸ@+gþ IDAT®Ú§Aøùù™™™Ér+í /Èú«$"‚¶ bQõêÕC„±aƺN6D-:œ¢ô§ujF;Þ †«jÔZ·´´4y +00=Ö±cÇ>}úØÛÛËÞ 9wî\³fÍš6mšššJ÷þóçÏåö&9NZZ­ª_¿þ?ÿüsé񴯯X%{ˆÃkšÊ I%yõêÕŸþ©äSàþýû–––zeµ‘ çm"’ΧOŸîܹ# ­¬¬ô!ªÞ¾}{ãÆ ‡Cïð(ûÌ™3ýõ‹Åª¬¬œ6m ¬×¥K—ªÉÈ,--KKKE"‘œé:##C.y›ÍÎÍÍe‚·lÙòÕ«W@‰˜ñR©tÒ¤Il6»°°3u@ Ô@ùþâÅ‹5kÖŒ9rß¾}ú£ƒ„……]¸p0|øðàà`¦Eº»¬¬¬tB‡l6{Á‚>433[¸p¡¾IX7îÝ»wbbâüùó•ª[AAAJJJjjjJJŠ@ IR"‘ôêÕKÎOý;kÖ¬ØØØòòòvíÚUëU!‹åË—&ý¼Øl¶â•••999iiiØ£J#ˆ‰‰Y¶l™’…£¢¢V¯^­˜H´ŒÒÒÒÔÔÔÔÔÔ[·n?^ _ ³¶¶¶µµüþûïºm>Ç«µLûöíuR7ex€mgg'+.‘$‰A^^ž½½}zzº§§gddd¯^½æææ¥¥¥EEEÖÖÖU z¨-[XX8;;cIƒ …ÅÅʼn„ËåÖš˜VõDó²°° ã‹D¢²²²ŠŠ 6›-KÏšEJJJ\\\“&MôY }ôèQ@@R–‡ªÏä'¯U}ûí·#GŽìÝ»wIIITT”••UÏž=ÑaŠ¢~úé§éÓ§gffÞ¾}[¯ºo»h 4HHH>|¸T*-++{ò䉂¨Óf®–accSPP0tèP‚ RRRÒÓÓ5KEô«¸\®ì$ý¤R©Tºnݺµk×êál …§OŸFg0åEQtffzEº}û6ÝŠ¢P>}h’D"0`€H$²°°¸téRµÚ;ÞÔ,š6m‰~wìØ±Z#ÑÅ‹·oߎNÞŽ9R?âììL7BØ·o_À74h,9rdAAATTÔüùóõÇ„'+üÊîõ …Bý᪲ì%''ç§Ÿ~ ­¬¬ü믿Ø5µ§Ú¦êÕ—‚‚€\ׄ„???´3ضm[Ìe˜@yyyM1Ÿtèú—ÅbÅÄÄh'| CºÒúõëk:=³jÕª+V˜››ÿúë¯{öì©êºÌápf̘1oÞ¼I“&&S™©ÙF‹uøðá'Nv!P@A]A¶£¸\î¾}û$Iff&r£‘­ƒÇ²—/_¾eË–ž={2ê7Èáp¢££åHÇÍÍÍÃÃCŸO™ Øl6m ¢Ñ¦MæöÝt˦ÉEEEÑüZ={ö”H$ZþU§)…Üî;vìˆda‰D¢g9ν{÷D"ÀÏÏÏÕÕ…‡ú¿ Ît<, Éb̽º   ##Cûh5Ò‰çJ·¡} 8Ù)µŒ€€½õ0d-Z´ÐþG ¿ýö[´—Ïçëä»ööö î2Ȱ „uŠt£AžI­9hWKË-//§òšБ{-´¨¨HO¢Ñk Š;™0¾ë*B›®PRR‚ÝÍŒ$IÖd,3V)²™2÷a6›­ý:AÜt\(Šzøð¡I-¿º ­¥exxx\¾|Ù¤è¹8ÔÔ^6sÞµk—ö,çàjô05§ S_SåZÇ—À]¬)˜”M‡¢((ukj0)Õ[?Ý2€¡!|øðÁtËçó£££Mj|cccMj–s1× Ûk100 XÂÂÀÀÀ Ã@»¼¡´´.+¶+/«é@'ûuÙ’$)ûf¬R`†…aŠ@‰¿7nܰaC‚ ÐV4„044Ùzbbb~üñGeì>$Iúûû«yTBøÛo¿]¿~UcãÆBsss‚ Ð_‹5iÒ$¦Óc`†…¡Ü ŽKLLLMM;v,bE988<|ø0)))##ãóçÏrÙI³øøñcRRÒÛ·o¿|ùHNN¾wï*ðöíÛ¤¤¤äääÄÄD@qqñÛ·oß¾}‹î~øðN×$‡¬¬¬9sæ (]±±±ÈG(úøøŒ=úÙ³gR©´W¯^û÷ïÇ< xµÁP½{÷8p`xx8 ""bøðáû÷ïÿßÿþ ÉÎÎþüùsóæÍOŸ>-ûàË—/>Œ²„ôìÙsÔ¨Q'N|üøqRR`ܸq¶¶¶GŽ :wîÜêÕ«KJJ-Z´˜>}zƒ ²³³k"ÚððpAƒÑWÖ¬YÓ°aC{÷î!‹¿ýö[___<| 6î ÕààààääôÕW_¡ýýý!„(n2EQGŽyðàÁ7Ö­['ç¸ìêêšýîÝ;//¯Q£F‘$yôèQÄD(Š:qâijgϜ׭[—™™¹iÓ¦¶mÛVVV">xÿþ}{¤Z”••¡¡/4hÉ’%=zôؼysË–-íììž?žfX&§ZYYÕ¯_¿GHÞAqàüýýiö$‹«†X¢(ÊÑÑ¥xõêÕôéÓ÷îÝ++1•””,Z´9yQ5bÄk½sÔ¨Qñññ5Fj)ú±`Á‚õë×·oßiˆcÇŽussËÈÈÐO÷" ̰0˜4%@hÖ¬‡Ã¡¥§:™C=zôˆ‹‹³··GÑ÷éÿþûï ˜™™yyy]¹rдiS ‹C‡}÷Ýw¾¾¾ŽŽŽM›6-//ÿôéSHHˆ««+‹ÅB!Œ}||jJ ûñãÇß~ûM"‘|øðáÝ»wçλråŠD" ü믿ºwïþáÇ‘#GnÙ²GÍ6`ÂÃ6, •…¬ªYXd/Ò¿«½Hÿ‹ve_Rí'H’¤(¹bµB¶<æV˜aa```hØ­3, ̰0000ÃÂÀÀÀÀ 3, ̰00000ÃÂÀÀÀÐO†Um,7C„âúc·[mö<îm`×®]E½{÷nâĉGçã¾mÛ¶jG ={ö0ôivUùÅüçóùr¡Ñ]¡PH’¤¥¥¥[‚333Çþüù: É臭­mM:‹jF?Ò¸qcô’+VØÙÙ±Ùìš‚¨¡ÝÕÕµ~ýú|>_N§ûQ­ŸŸ½×aÄš  ¼¼œæÑžžžüñGZZšÎ3•½|ù299¹*1£Š¥§§»»»·nÝšŽ÷¯Arß»~ýzïÞ½{÷î½eË–ÊÊJ¹»ééécÆŒ8pàË—/ecHVûj‡c 677·}ûö :T5²PÀ’4Ââ)ŠÚ´iI’Ý»wŸ0aÂÙ³g„¡lȾÿþãÇŸ?VQuàîÝ»‘ŠdÄÜ CÇŒC7BH’dLLLÿþý[µj¥«ŽŽ>uꔹ¹yµÄ !lÒ¤É?þÈb±˜¨»ªpñäÉ@‡f̘aoo/{wÆ ›7oöõõõññAiãPÃÂÂ>|(Û‚ Þ¼ycˆ„²bÅ À´iÓôV„¤íî7oÞÌÏÏ÷òòÚ½{w›6m~þùg{Qµ7mÚ„œ`jÝ …ÎÎÎÆÊ° „qqq­[·þå—_,X ;¦(õÕ«W!„±±±mÛ¶ÕI W¯^íâ⢠@YYÙŒ3ž={ƬÑÖHÿúë¯ðððªf‚Y³fÅÆÆ–——·k×NözAAÁçÿ"??™– Ëd€ìneeed”ÅÅÅ€ÐÐPÃ5Ö|ø }’{øðaM{J²puueÂÔXãhBB™3gPòK‰DòùóggggþM@„œÐnggWõ=·¸½|ù2//ÙP b)X[[#¶eoo–––feeåèèh@ÒEQ©©©›7oöôôT¦pPPÐäɓ߿ߨQ#ãÓKKKƒƒƒ#""ØÆŒsíÚµÌÌLWWW- ÂÁÁÁYYYµRWëÖ­i›£éPÞ†uòäI??¿#FlÚ´©¢¢"==½qãÆwîÜAzõêuùòå]»v;ÖøDñÈÈÈøøx‚ N«‚Z[[K$’;w.^¼ØÉÉ)))É€¸„ðÛo¿UÒF‹Ú5xðà®]»£óÉ‚8p wïÞ_ýuMMC=0dÈÎ;k³ „œ:uj­ÖX’$/^¼¸s玆éPNâºråÊ•+WΜ9sòäI±X\VVvöìÙüü|Zº‹ŒŒ£¡{´1òîÝ»Áƒ·nÝzæÌ™zxU† ˆ×¯_+9 äÏÌÌŒŽŽföðšv{£¬¬ (áØAcáÂ…L7ÕÍÁÁ’IÓ­ Þ»wOÃþ˜øhEQ.../^¼0Ö=räôЬY³õë×ëÛ¡–cÇŽ©C$‰déÒ¥4Ž‘úá‡dÃ~(cË+))éÖ­›ê†)êJ<‘‘‘@£îl€A­[·6ÖÖ¡sTÀÖÖÖÛÛ™iõD$yýúõýû÷U®‹Åòõõ•;’a¸HNN¦]Û•TÄb±vŽ”$$$ÔuË¢¨^½z…„„”––ê‘JX“–Áb± ‚JæÏŸOu¸Dd666±±±cÆŒ¹xñ¢^)PÊÛkª…‡‡ÇÔ©SKKK }/_¾ìííݬY³:=eoo?qâÄßÿѺ‰ÅâÄÄĺªíLX!Ø™;vìxþü¹ÜÑFó€T*ŒŒ¤Œ=ª'EQmÚ´yðàA`` Ò& YâAfc•Õµk×~ýúÍž=ûÈ‘#=@666ªI"¿þú«P(477gNô{þü¹ŸŸŸ Ï–––"ßfÌ/ͨ„ÁÁÁýû÷—­‡ÃÙ´i“A©‡} b´kðéÓ'oo襤$ó褤$@€ü?ÕÏŸ?offfÐ K*•®ZµêÖ­[*°ìfÍš%&&ŠD"æ„0((ºª+Í?~¼cÇŽqqqú"aªEQwMB—6mÚЧÓuU“Þ½{oß¾]#7n’/ Ñ’!üçŸTpì A’ä¹s瘓—;uê¤òãß|óÍåË—5S=í»5 ó}ûö=t貕ŠD¢–-[¶k×nòäÉZÞH®W¯žé„¯”Ňx<Þ¨Q£tx…ËåjðLÒ> ÷8ÎÇU~ÉË—/šË¨zÎÎÎ*OÙ8±8¤e†…jïìì\YY){¥¬¬¬¢¢…ûÑû@_AQ L tÝ…vrrÒì9ǧOŸŽ3Ƈ /jr:™‰¡lܸqƒ ´yQ´ª"%¶GR©”Ž¿ŒEsss.—kkkÛ£G휴@jÿ—/_(ÓË'L çnnn®®®:1½çççkv›%d3,­UeÜPÙ½=åååegg§Ù¡DÕËÊÊBéÕ4µmÛÖÀlXÂÜÜܧOŸæååUÕØI’ÌÏÏwww§3e1M(r³×Ô@’dFF ¿-´Ѐ¢^ééé .ÇqªÊׯ_kÜï BxïÞ=•Íí²ï)))ÑH€<­2¬¢¢¢&MšLŸ>]*•VteçΡ¡¡………LŠWvì ‚¢¨èèh[[Û‚‚J‹a•Ö¯_¯Ž¹Z8884jÔèùóç†5 ‡Ú´i“úC (,,Ü¿¿fùõÒ¥KÏ;§GD«ÍuU"‘ôèÑcÛ¶m5ídSeee…ä/¦çÏ¥K—4xbÀpuC‚ =<<´£‰£O\»v­¨¨Hã/—H$—ú„Åb¡Ã€ê¿êÍ›7ÑÑÑš)‹¤‘ê!®ªî«4hÁ•Êæ ·S°nÝ:å÷˜3———7jÔ…R2q NF!dµc€'…|ÒxCÜÝÝI’4ˆm_¤ÇPÄ(õ‘’’Ò³gO RõÞ½{†R á`ÿþýº?ü !<|øð«W¯äÖ Yf!ܵkAk×®Uì?FßÚ½{÷Ì™3ZÖ~ùå___}8›¢BI’'Nœ8yòä¹sç† Æôy<Þ•+WP–Í6°zõêõëׯ[·Î z~Ó¦M ,ðõõÕÈ srrnݺ5`ÀMI¬—.]Òˆ½……EDD ¢V§iDØ{÷îœÕ‰ÃáìØ±ãèÑ£ˆ/B-,,âãã›6mªÌ SSS[µj…¼´˜°¡îܹ³yóæ}ûöÅ ‹Æ£GfΜËèWòòòœœœþùç&8#¥^üRíÃÒÒ2;;ÛÒÒRS/ܲeK×®]5ò¶£Gr¹Ü:P€S§N;¶°°ÐÖÖV—*¡2~X'N¬ë·!!!LÈáhS&** 냲‰DíÛ·gZ ÊÊÊ6l£º'0œ\öêû7Éa×®]ÚÉQäää.\¸ A…}àÀ999ê 6t¢ÒÒÒØØX¡P¨üº‡\I‘©ÙÕBxçÎÉ“'÷èÑÃ=°kjX²d s1Â!„ÑÑÑêo“× =O„B8xð`;væÌ™mÛ¶e³ÙjÒ6:‡0|øpúÌœFv©T­ÖÐhAº~ýz=ÃR™™™l6Ðø üôéS,RU»åçç3*þ ௿þÒ}Óã§q7kc‚X,¾qã†f÷ÚЫH’T!Ò® ÃÆÆæðáÃzóvûöí¥¥¥šerxøð¡:³†Ãá„„„0Q±µ…`Usø4Þ{è…ÅÅÅ ,PíåšaXÙÙÙ©ÿŇÐa1uuä„MQÔ›7oÔÔ# „ÇŽ»~ýºƒƒæJµ’”££ã¥K—þþûo,„ðÌ™3NNNZc»›7ovssCÁyõ $IVTTh$t‚LOO_¹r¥ ÃG+ïÌ Maaá‡T㧚ѢOœ8!g/ isoß¾U'A z0 `æÌ™èd“:æä¿þúËÆÆs¥ZaggwüøñcÇŽ}óÍ79NÌãñŽ9¢µÕMÔyóæ¹ºº"UBOD-4]oݺµ|ùræjEQTbbâÈ‘#—.]ZW·rä+7aÂ憦¸¸øÁƒŸ?nРlX5é¢(~‹FÞŸ˜˜¸páBu^‚Âñ>|›¨”„@ pssÓˆõ°¼¼ÜÆÆf×®]Úw+ Ö ?èÕ«WFFÓ_ …AAAÏž=SáÙæææ2gþ‹Å&L8wîœnlX5­ê䛓{¿T*ýå—_ÔÙô©¬¬ìСCFiɲ¶¶ö÷÷GñgÔ|›D"ñññaî(»²,++»~ý:Ð0¤¨<@+£ßâóùÍ›7W­†§¢¢‚9™”Ãá´jÕJµlI†® E‹ëÖ­S96EQ¹°b(9Û)Šºpá„033“¹Uip8œ7oÞüúë¯ú ¢ƒÙåååj&»V(y8#„ðÔ©SAAA®®®ŒÖÍÓÓsèСÈÇÕ`ðàÁÓ§OW™PÂÂÂæÎ‹9Q]YÌÏ?ÿìï﯎„B’¤¥¥eII‰®Öµk×8 ~`ˆW(T‹vâ5êèÑ£u匕••LwÅ×_ݱcG33³ºZ÷ ƒaQÕ®];d²Umÿâ§Ÿ~ ¦ðiç:vûÂ… Áž={Tö#%Âßß?**JW­èܹ3—Ë•H$º}áÚµk…B¡ÖÆ®G'Nœ¨ÓSýû÷gÔ£ȸ¼{{{וw³ bæ Ù’——‡~¨°½‚V6|G…nÿþ½››[‹-ºuë¦Ú{RRRuÕ 6›kaa"gê?~œŸŸ¯: Oðù|å÷èÑNE‡æÌ™Ãt%)Šzòä‰ ’&a@“DgQ^‡Ò¹¶1êÚí7ÞºuëíÛ·ë*¡Ð/ uØùˆZ pÿþ}r«sçÎÅÄİX,­Õ$É´´4åmÛÂ[·n¡½2¦+‰Þ?pàÀzõêÕ‰œ@µGêkòW ï*³Õ]Sæg57ªQêSå÷\;öÓO?a7uðîÝ;‹¥‚ÃéÓ§7mÚ¤óúk'Q€â0¾¾¾:ñªAb²’­DGGksPêÂpüøñ„#‚Íf³X¬›7oÊqYt·sçÎNNN(C”N4”Ý»wïØ±CùàòåËØz¥¦ôÞ¬Y3ýÚµk_ýµÎ;QK||üwß}§ýÊA888XXXèÄ«7†E IDAT†¢¨ &Ô:_hqXS)|”tD©Ö/" ýÏ?ÿ$ä^áìì,‘H¤Réúõëå´Cÿ÷¿ÿýþûï_¾|ñõõ•í‚âââ/ÿ…@ `â´„ÐÖÖ¶N;>"‘H;»ÈÆmÉÊÌÌ433«k7jm _¸ºº>|øôéÓZ®I’àÉ“'ÚgÜH0©5N?ÄÜÜÜ\\\´iê¥(êþýûÿûßÿ‰JBGGGöóçÏŸ>}J„T*íÚµknn. ;;ÛÃãj33³ŠŠ ‘H$—Hcûöí<ý*„0))‰¡vFGG/Z´¨Öd$IΞ=% Å|GMžE’¤H$RÞtv/]ºô믿êI+ìììN:1zôhíX¾ÑWìíí'Ož t±ç!DòÇÖ­[—,Y¢ XJJJff&ÒÔ´–M BhiiiaaQXXhgg§ Ø“'O_¾|qqqüñDZcÇŽ9’””„Ë!C†äååUU8gÍš[^^Þ®]»Z愆†‰ùûû×zt,--Ѿ †Fð믿ž>>NNNzuðØÑÑñÓ§Ol6›Íf/[¶ MQ†ª!Œ‹‹6lØÓ§ON]jH’œ9sæèÑ£íì쪭FllìöíÛ_½z¥“Á¢þ œ]í§!„Œ>|8U5¦{Ë–-=<’þP죃¦¤¤0TÏääd’ t¾CºqãÆjGý{üøq”áX'سgâ¹M6h+ i²5áÁƒµ2/tqÕªU(¯¸þtªIvvv¿~ýd¯tïÞ]çÊ;útEE <<\®{­¬¬dÿe¨Ù炃ƒùå{{û7oÞ”––ÚÚÚzyy}ÿý÷6løä “=oaa‘œœÜ¬Y3ggggggêümÛ¶Jç£JBÑùdú­¶ä•+WBBBÐ~?›Í~ýúõË—/«¦Èær¹­[·þý÷ß{ôè¡W€jbmmýþý{áíÛ·mllöîÝ‹ íº­*ú4—ËÍÊÊruuuqqiÔ¨ÇÛ¾}{dd$rº¤«Ç ×ïòåË·lÙª©H~ÕÂÑÑqÍš5²‡àùåäM†Á(ÌÍÍ/]º„dd;?''Çø– ÇçóÑo>Ÿ¿aÆšhÌÙÙyñâÅÈ.¡o ÂÉÉéàÁƒtÒÆ3fØÚÚRúqÄÌÌìÖ­[÷îÝCÿwèÐAÎ}A•pùòåxVc``h’ç2÷ê‚‚†’q+w@Ë`±X:ùn¿~ý–?*‘H:uꤓöe–ôññÑþG?~üˆüòµ”QTû°³³Sp—Y|¦CÖä‡fRkI’U)LC,›Z?ÓìRËýŒÃ"iIÂÒO é ¤¤„±(Œw5B²¦y£ÕÁ6¾›ZnçK—.)88j|øôé“é4¶qãÆÇ7)zþüù³n–NDh€ò1 ¦–ËZ•ì› 6›mR« ~ýúºQ Lª¯M*EQZ˧ ' …&¥z3ÏNœ9‚F1€L.\0Æòx¼Ý»w›Ôø>|ؤ\‘ÑÑ7}ÄöZM1h™Ó¤hÚtÚkš#«‡­ÖÒ.á§OŸ^½zŒ×ç€>äaRlÚtÚkš#«‡­Öú~ýú¶mÛöîÝ‹Ï÷h!ôƒ^d—%å—(u3¹geÓä€ÿ&ßÅ*…AC Ù³Ž92{ölÜãÆ¤5Ñ­[·Î;£œB''§ððp´,ÅÆÆîß¿_™%Š$ɪ³˜Aýüü¼¼¼¼½½===Q΂àà`¤×Ñ«W///¯+Vh?k†1,š¹\.îqcÒ† vòäɳgÏ<˜Åb±Ùì/_¾äääܹsP\\œ™™YU¨©ú/A—/_V\RÖK¦ZŽ“••õîÝ»¤¤$®kíÚµgÏžEõ=zôÁƒß½{×´iÓ£Gb1ß°×I­KÓÕi; &PRR@‡ëÌÈÈ "!!ýëåååêêjoo_¿~}¹ ‚ƒƒýüü¼½½·nÝJQ”§§§¯¯/ºÛ¸qc___@½zõ(ŠÚ°aƒ···Ïëׯ)ŠjÔ¨QMDëëëëéééââ‚"çQÕ¤I¹HO?þøãµk×ðØ.ØÚYŠ9ŽW£AnnîçÏŸ£¢¢F xöìEQwïÞõõõ%I2))ééӧׯ_ •ÛlJKKsuumܸ±««ë‚ H’LNNöññAœèýû÷999›7oÞ¾}{FFÆÏ?ÿ,»²Vý âAÙÙÙ²%×®]Ëf³ÍÌÌ(Šš1cÇCï<{ö,8ÃÞ1ÁP]6—U¬Ú%›7˜. [²êSˆyɾDîUKÖšXö+R©E@®©æ†´Õƒ†¡€À]€fX˜aa````†…fX˜aa```è%ÃR Ä€ ¸þØíVkÝŽ»Ú ¦ÓÃÄ §{FFFZZZ¯^½ zH „¹¹¹ñññUï¶iÓÆÁÁŸó`¨Û?~\RRB_éÓ§îj}CIIÉãÇé¿úê+KKKCeXóçÏß±c‡á.ŒèÀÚ÷ßõêÕ€€¤‰Æ‹/z÷î½wï^ Þñ´ZŸ5©‰Š{ùòåÁƒoÙ²%›‚VVVþøã˜géÕìhß¾½¹¹yPPàæÍ›b±øÞ½{‡Yú`Ë–-ÀP£A $mÚ´133ûüùsEE…\òòòììl‚ W¬X¡N\CŠ¢Þ¾}kiiéPVVVÏŸ?GeP˜SÀÇ>”½øÏ?ÿüðÃ8\þ Aƒþþþ²W6lÈ4¡b†U#úôéƒBÁÕ> ]§Õ–OŸ> ‘HTSÐ%Ù+ ¬¬lÕªU6› Ø»woÕO 4ål6…v’H$ÆΉ$Éââb@DDDÕ»‹-º~ýº ²†²²2@PZZªWµ"B–e06n«Å±cÇâââPhºš"™ ÝÄÒÒSÿþý?}úÄår—,YÂår‡ Vµü‘#G8ÊB*‘HH’ÌÉÉqvv®Võ£(jܸqãÆôìÙ³S§NcÇŽuvvFWŒO9B-ºxñâ¦M›P ?¹víÚÅ 5Å5óŸþùî»ïüýýcbbÎ;7`À.—«Ãæ£Zñùü1cÆ™Œ èÇØ±cœœ¾|ùÂÐ1hÃZ¾|ù–-[ Ά…8TÆ wìØ\§Q”H$´¶¶7nÜ×_-‰dËH$’qãÆI$’òòòyóæ©`䊈ˆÈÉÉ9vìØÚµkÒ½bÅŠÍ›7W˒Е۷o:tèÏ?ÿ¬5$–q‰zöìùáÇիWOš4éÈ‘#{öì‘H$ÏŸ?×mó=ZXX8oÞ¼ªK,„1Ùª 6#6¬ªÑl«½«ŒVb¸*!‡ÃéÛ·¯:oøòåKnäää¨oV£(ª°°púôét߇†ˆZáèè¨@ñ¡•Žo¾ùÆ4ÁfÍš!ù]nnn(=‡ñÝwß½zõª&»sçΜ9s˜ÒCåøWqq1‡Ãáp8¨–ÁµmÛÖÑÑQ"‘Ȳ<“Á¡¸¸ØÍÍ ÙJT~‰£££SЪŸŠÂð¿ýicc³gÏž.]ºXXXtéÒ%//¸›Z™¿ÿþû¢¢" =€¨677׈ݲ¨3hˆÅâ’’꿹Î222Øl¶X,ÖÉ SåâââççWÓoذaxxøƒ˜¨€¼ kΜ9•••€: >ÜÞÞ^öîäÉ“O:ååååéé™’’B“QDDýïÿ/›-ë a@ÓÆÆÆ-æz«q 40111Èdàìì¼bÅŠ7®a B˜——wëÖ-”lBAЭM›6mذ!44Ô(„ðÓ§Oîî¥rtˆ†>++ B˜ššêáá¡ýº:uÊÑÑQAOOÏU«Vq8&¨‘›±GDGG4ÈÚÚZ®´¥¥eYY™H$²µµ•½îâââUrÌÎ eË–-'Nœ2QÆõtõNž<™ÐµkW??¿ßÿÝpMZ-[¶´µµU¦ B¡pýúõ999Æ*d=}útâĉ(7GÕ¡'IråÊ•§OŸÖIÝNž<9þ|ÅefΜÆ5²«ŠÜ%%%?üðCdddµvßj“Ž;V½~÷î]ƒ¯ž={6zôh’S(ŠòõõE9D½¼¼¦M›†’5ç"I²C‡[·nåñxÊ”ïß¿ÿˆ#‰ñmóÍ7ÇŽCþ.Õ.W¯^½ÒÉqppprrRÌ\\\PšH<ÿÎÌÌ´±±9uêÔãÇ¥RiJJ „ðæÍ›è«5JOO‹‹óöö6t[UUlÞ¼9  I“&Ô"ºªÍš5£(jΜ9A¤¥¥!Ö¡ð\‚ |||/^¬¼Q¦]»vh¤ŒÏ˜ß§OŸñãÇ×Ô4Š¢ ôôéÓôôt­5ŸÞD­Um Då5_Y„†††††Îš5kòäÉB¡°  `öìÙiiiôÍæÍ›çÏŸ¯Ìæ”aí"”íÕ 7ÚÖ®];tèPggg´Ýfþñëׯ߿][jii‰R Ð`.\¸Pká .,_¾\›Õ;uê”’3ZÖ‰T³»Ø &Ÿ†jk`¬n ˆPÚ´icè^¨òb±8..®k×®:tÐóÑST…zfddÐû†FƒÞ½{¿yó¦ÖÞåZ[“š5kFSй0mÚ4Ýjóä¼ZH%"·ƒnª<‡ÃiÙ²åÝ»wŸ>}Ú­[7zVëçîA»víÐqÙºö¼››[MV¥CÀ‹/|||jí zLY,–6ˆPÝ „mÚ´©“ê† Ù¤=À@“’’×®]3ƒÚÿ¦(ª¨¨BxôèQ=4÷ úäææŠÅb´WPW´lÙÒ ãÉ YVVVÛ¶më´8¡~czdQ%Y˵’˜““SPP A!3,èÞ½;ŠcL’#ZxããããããCBBV¯^­o< BxíÚµ)S¦•üH(ŠzôèQEE0–8‘sçÎ=xð`Ú²uëVí¸³lݺuåÊ•uú„pÈ!;vìÐ$U›8«BÄ!‹¿ÿþ{£tž¦(ªeË– ,,lÉ’%úƳnß¾NA©ÆïX,Ö¸qãþþûoC_i „÷îÝóóósuuU¾-EM:y2 sss:0‰ò 177×/†eÐGs „Ó§O¿{÷®±@²²²ª¨¨øùçŸ9¢W óöuzÏç/_¾üÝ»wšª [#SâöíÛ™™™ÿy/›]mXa=—Ë …Æ®BÈår)ŠZ·nÝ‘#GBBBôAÇÅÅíÚµkÁ‚êÌó±cÇvëÖ-88Xñy=I’ÁÁÁ7nܨëƒvvvãÇGcÊ3577G§ëD3E}õÕW3fÌPÍ@É JˆöYå`„’––Æb±š7on"úïºuë&Ož¬º!EQÖÖÖ“&MrwwWS~äp8ŽŽŽ†Br5¡eË–*ˆ0È ZVVÆÜj·bÅŠ•+Wª6:999è|®¾HXÈy¤êõÄÄÄ+W®(xªj$íÏ™ââb±X\õÔ¤±ÊY€ŠŠ gff¦Ûé¾}û&''«ÿ* 6›-AÄà‹UZZªš!eòäɋŠ]¨‰Û·oŸ>}Z5j9{ö¬»»{zzº©„5 ƒVõáÇŸþy×®]VVVööö?vpp`Ä—_aÍûôéÃ\tDý‡Ã666žžž'NÔÕ… ¼êÂ… È“ËÇ‘>ò¢N$U6›k¼ùèjPEÖzTO»„ÂC‡¹¹¹çææuéÒ¥I“&‹-¢»F;„J¥À¸¼”ékkkäë +ÅB¸ÿþ™3gjj½œ;wîŸþi ¡uΞ=;kÖ,uèpܸq`$$1„¿ÿþ;ªžÊ‹Åh·G3ó–!T{4‡>R€ÎÐ@=C† ÑæQ’^½zÅÇÇ›`RÔÃIII=zôÐÕyC ¹ƒfè%æææz²ÊÅÅEš3ýAý‘B%‰8ªé·{÷îEEE>>>”Lvh{{{Š¢.^¼8|øp­­“·oßnÙ²%ez)…‘`åååuçÎŽ;j9ø—l‡kd¬ÑK„Báܹs KÈB]¡ÚÉ$¹æ£¿š%fŒEQ~~~,K#UÒ*¥’$¹hÑ¢û÷ïs¹\Påd"bá¯^½’ËÝÀ>þܪU+SÓeéu8ŸÏgnƒ©¦O7oÞ-ÚœZ-B8{öìóçÏ«Yg´/¯q0„ÐÏÏOÍ‘BUjÙ²enn®!1,Š¢***öîÝ›Íçó«© AˆÅâzõꡨ§L#00ðåË—†¾®ÖØEQáááZ‹Ÿ…f&Ç …”ì „………×®]ûðáƒa­@@Í:£žDRŒfùµMii©š#EQÔ‹/úöíkH Bèííݯ_?GGÇšú”ËåÞ¹s'**ŠQßeZ¯¬¬4îTQÊ ŠÏW_}%´#˜@Ož<9cÆ ûg7nÜxäÈ‘Úéþ_{W×ĵýïLÂQÄRÄ•¢âVî"mQ@«<Úªµ.¸¼ÖÚgmëÚ¢­õ¹´XqCÄZ+úTÜ@A@D@M0ìKB2¿?Îk^ B23I`¾ð ÉÌÜsϽsî9çž{NnnnSSÓ¨Q£HyÚü±yóf²ä5̨y®þ ×××›˜˜h…ÀR¾?ÕÕÕ±±±Šw7Ùl¶@ hnn¦ôÙ¾}{dd$øz88އ‡‡““m;†•••VVV¤/l6ÛÉÉ ¶}uA477K¥Rð¨Aƒ‘î¯Éþýûׯ_OŠ ƒŸ$Œ2)¤Ÿÿÿ÷T8Vd’¾g4(pZ§¤¤ìß¿Ÿ:¶@ZuN;+£è„ŽÊÏχ±$>ÙÀÀ@ ¨ÿL€DW#Žãà³S‡<:öÈΟ?ïçç×§OŸ.Íl@ðìÙ³ªª*ßà”§§çÏ?ÿÜãECOO/11ñòåËÅÁÃ÷íÛG)󃂂lmmµÜ ‡j䮚A¬^½zÆ êŸÇ0ìÂ… ¤"ÈcêÔ©à¡Ö¤IØéÑœ~ýú}ÿý÷]½](Λ7ïܹsäR¢¯¯Ï€¢¦¦ÆÖÖ¶¶¶–"«ðÃ?„à/ªO™››k¹ÉïééyâÄ *žÜ·o_RŽ[‘î“!åÇ[¹reWïâr¹£G&]Ãÿí·ß£Ou¸t™››—––¾õÖ[Y…¿ýöÕI`€ò¸¸¸®& §Ù”J¥óæÍ£BÓ,..633SÇ”#ýì”ü£ÔŒ¿£\`a6|øpÕ¸¶víÚ7¶´´2®òé(ðE666’rŠ¢CæÓ#DÀ•£µ|Þ±cÇöíÛõõõ)âF}}½š‚s |ýúµö ,(ê«ÚûIÖÙøøø°°0F6)ƦM›lll©‡<0 »víÈ¡ÿ€¶óF]………‰áÊ(J]ä$=¸W*•feeAP-õa©Ó‰åmáQ“&Mjlld¢:eÔÅ‹I,ƒÏœ9sfUUmÌ ÍÎÎÖ±æóù8ŽŸ?žº&nß¾½páBíLVCdLVmh(¯š£Ž˜—¯c¬¦°‡àÕk×®µ´´0Ñ ŠEÄÈ‘#ÓÒÒÈR²0 ûã?.^¼(‹icþ‘#GÞ}÷]-ëæææY³fÍ™3‡:ÅjìØ±wïÞUy°üýý‹ŠŠ¨ã@]]]XX˜jCCNVXXØÀÿŽŸ~ú‰²¥¥‚æÕ|yš››O:Õ«W/F*u: VVV¤e‰DH =z,MÚ0lØ0»Z…¬¬,J‹žÀ 8°¦¦F5åÃ0ê’Q__¯úM]¤ûçŸN–b‰ºyó¦:O€ìnmÒœ2P€ÌÌÌ•+W …Bõ%‰V®\IsrWªÏK¨êMIR©4###,,L…{ ŒŒŒ^¾|IyEEEÆÆÆ/^¼Ð®HwÝŠ§OŸŽ‹‹Ss…ÏÈÈOsÊ@ñ26dÈÄÄD.—«þVQKKKrr2ÍÉ]eÓrÅŠZbâ8>|øp°¶(% Ò¹¨Vr9--íÃ?¤4òÖÎÎ.444==]3&! puuÝ»worr²ÊO‰DÂ8°”÷dedd€u ¦  …Z„fæÃš|ïÞ=-YÀìׯ Í;¶¥¥åáÇ*ÜÛ¿²2w‹¥2tC`¹¸¸lÙ²Es…¶¶¶—/_fÔ«®j(3gμÿ¾š‚ÆÊÊjúôééBkk+ŸÏß·oŸ6ð377wܸq´µ(‹áP‡ò·H$’‚‚GGGªisrrÊËËSEy§áh)xòäIHHˆšŽ4»hóÚ(Àõë×ûôéS]]­qNŽ3¦®®Ž6>¤¥¥wÕÕëîîNƒ‹ WWW8§­uGsHQ§‡š˜˜¨ÂÎŽão¿ý¶ ;& @±º}ûö§Ÿ~ªâ&4Ž»»»C§¦Œq???www™èÔ'/\¸0þ|zø@İaî^½Ú¥[ ?Õ.6ðlvUD¤d¥íÍ|µ÷8xzzzxx<|ø°CË3882wjå’ëÜ?^V(M™ë³²²ByyyŒCJ”——©p@*$$$==]{œq?üðƒF˜1cÆãÇ5Ò´òD++«øøx:i»|ù²M—œ¡mŠ………D"‘H$“'O®©©ióëš5kîÞ½ËçóßyçNG7oÞL®À’J¥káÀÊIKU™ IDAT;\ÿùÏ2Gý·}øðá]º199yÓ¦MÚӑ‰'Òìþ×xüjUUÕØ±c•!NŒÓF$4Ù»”iÔØØ˜ üõë×ÙÙÙÙÙÙYYYUUUáS*•êëë·χh&###ù2\†-Y²ÄÊÊÊúïØ³géj$Žã÷îÝS&=trâĉ”ƒè!®w‚ þøãeË–-[¶ì×_UF)FJJJHHÈwß}§%Ò høù矿øâ y’d;˜¤×¦ê*bbbBQQQê%wîÜùŸ2¨£ x½{÷¸6=Ô×ׇü°Œ1HçBmŽvóŒŒæÎÛÚÚª+!"33óÉ“'Ož~ü¸¨¨ˆº¯ d>{÷î…(ÒÒÒ^¾|Ù͘O„Äús8œÈÈÈãÇ¿éâ'OžTVV655iaæ5Ç=z©€´³³ÓòlmmÿùÏþùçŸðïæÍ›g̘ñúõë¿q’:‘Á¼Õ 0 fk¨­­MLLtqq¡µ?l¶««kAA: T@¯^½ in×ÀÀ`Ö¬Y¤¹¸†P(œ;wî­[·šššèl×ÜÜ\___$Ñœ/ÈÄÄÄÝÝ=))‰f½©¸¸ø«¯¾ŠŠŠ …4«Ï–––uuu4óÙÜÜÜÆÆæåË—oªƒK¡À’J¥<æB) ÷êëë«Y[5h¤]===KKKKKK:ÇØØØØØ˜~>ëééÑ?¯Øl¶ ÍK p¹\333333šû‹a˜FøŒã¸©©©©©iÇ¿R×°H$ÒH]xš×|Ò62ÆB·A4ëVì hÀ$üì³Ïú÷ïO‡Ï;×£x÷îÝô/¿Ä¥K—zNgmll¶nÝÚ£æ³âñ¥j—Ð\jG8Oël6›ºýPmã³@ ?~¼:uŒtn|]\\²³³58«inÔÐÐP>)‹–Œ/U&¡¦öt¡]´®ûWS|–Îôœñ…hX Îjš1xð`-_&X‰4lܸ±çt–Ãᄆ†ö¨ñ ë9E- ‚HKKS¿†.ùñ×꺩¢ñ^3=eÀ, 0`LBd«mÖ<â¯æÊÜK ojºÃIlš#°èÀµ1sæÌÔÔT(f—žž>sæLø ð;v(c@avöìÙÜÜ\5-µ#GŽ,Y²dݺuPŽÃ°9sæ\½zUf¤Ÿ9s¦ºº𬬬… .Z´®d†RWWH º'''>Ÿ?kÖ¬²²²ÊÊÊ TUUYZZ¯ƒ ê0Tû&b±X$µÿ^>…€,J‡O8}úôÎ;srr׬Y´½zõjÕªUOž}Êáp@M»}û6œÁ0, Çq‹µtéRì/DDD´y A ,X»víàÁƒy<|ËË˃jw"‘¨ººzÍš5aaa õD"Qß¾}ûöí[YYÉ "c2è€Ô}›6m‚çÏŸëÖ­{÷î!„L„‹‹KkkëíÛ·Û˜]Ó¦MKHHˆ…„-...Û¶mƒø&‚ îÝ»·`Á‚³gÏŽ7nß¾}—/_¶µµ…'OŸ>ÝËË«½øoT\\ÜçŸ~ôèQù_-,,x<ÞŽ;ÒÒÒbbbx<ÞäÉ“}|||}}ÛdÅaÀ,ÝÖ‡pìØ1Ç¿þúkÐÒoß¾=eʔѣGË<Ùu³ $I|||yy¹D" ‰Dð4sss¸àÔ©S)))§OŸI©/F255ÕÓÓëЇµÿþºººóçÏ·ù©¦¦&***++«µµµ±±±ººúÌ™3÷ïß¿wïž»»;3”Œ‹AOüÌ)++ƒŠÊòÐ××÷õõmó¥½½½BèäÉ“R©ôéÓ§²Ixç΄žž—Ë]°`A¶¶¶\.÷£>’µ¸nݺö”@- }}}‡…pÀ0ܸq£ìšÙ³gCѽÿûßТX,fQÁÄa1Pe‘ƒ]6ùÌ¢ò¡•²Ïò_*s½ òÃmÿÀolq‡Ä0 : F`1`À€ña1`À€#°0`À, 0` 0‹ŒÀbÀ€F`1`À€#°0`À, 0Ð.PX—P …BšK¨“ 8ÀÑÒÒÒ¾8+Ô=FÌ!ÊØ^__/+D„a˜¹¹9ÃjmCkkkCC|ær¹†††T…GsV®\©»G€õ'Ožüõ×_óóóíííåµµµ6mBèý÷ßWSl)¾·g¶ÈÌÌtuu2eŠX,ær¹ñññÉÉÉ#FŒ`d–V Ó‡~çêêJÄ€öîÝ+˽¡{–¡¡¡®ÇòåËÿýïŸ>}zÚ´i&&&òðùü+W®|ðÁ'Nœð÷÷_ºt©Êr ðW¯^-Z´Çqù·Q*•úûû‡‡‡Ëþ•?<Ü]aXvvöÉ“'?þÁÀ—çÏŸ9räÕ«W'OžÌ -¦™3gÞ¾}»  ¬¨’’’ðððèèhj'*u‰ 6lØ€t3} äáÔaz_Ùçšššœœ™@ySß7¥ þñÇq‡4O[¶l©­­åË¡ººúûï¿Gééé;¶'$‘J¥`;vLÆ+ø{ãÆ „Pnn®bövKž(È1­A’do‡,‡õ¸qã ¨ÍkĬqìØ1 ^É)fffÆårKJJ Û_S\\œŸŸ_QQáééibbbff¦¯¯Ÿ››û¦é(ÿ/øËbbbŠŠŠ´jîRñ|òÉ'vððáÃ]”nÀ©TúêÕ«)S¦˜™™ÙØØðù|±X¬ñîC"Ùö©÷ ‚ppp¨¯¯§nŒÕñk³nÝ:yQ¢ä( ,XŒŠŒŒÜ!‡ÈÈH„ÐâÅ‹ß{ï½ÀÀ@Hºyó¦ìÉÏž=ë–ïmttôêÕ«;ì|Ó¿ÿƒöÅ*""!T\\LDPP¹¹yXX˜Æi ÷ÝwÛò !”‘‘AS¿6‰ÓÞ”VM35""âÛo¿Õ-§;ôËÃÃÇã]»vMeoBB‚@ h“jŽÍfO:UMÇüõëד’’¾úê+‡v¯<ôòí)èѳgÏÞzë-xŸ»±G8SYYieeßÔÖÖöêÕK³ÝÏÉÉqqqyþü¹££c‡ÃtàÀŒŒŒŸþ™r–L'GA¥€ö¿ºººr¹\e–wÕ°LLLÈr:(ÿ“òO†u¬oß¾¡÷Þ{¯Û¨Z¡¡¡™™™v¿¹¹ÙÓÓ³Û†°á ßqY9Ž»ãÆˆˆc”žž¾|ùrŠZg·ñü2dÖ¨Q£Ægaa!ÿkpppLLŒ³³ó Aƒž?.ûéùóçH[>L©¼¼\çV¶úúú¢¢"‰D¢Î ¦@ßQS‚Ûq—J¥ÅÅÅ!·gÏžñãÇ{zzê´¶%‰X,¸êw_OO/++ë›o¾s©[beʦl7~uvvvuu…ª‹ôwqqq¿~ýŒ‘››ÇKJJê°Î™a R©4++ o//¯öq ÆÆÆMMMB¡ÐÌÌLþû[·n=yòDž8‹•­sJxxx8lj¹¹!#¯ªªê÷ß÷òòÚ°aäI“&Mš¤£2ëþýû–––ýû÷ïôJ‹µ¿º+bbb €£ýPJ¥ÒÌÌÌ5kÖ¤¤¤Œ1‚~‡É† JKKO3©TºgÏžwÞy‡ò°Ð3'Mš$‰ÚÿÑG¥¦¦ //¯NÍœ7ê–I˜œœ á$:dk©™™™qqq¡ôôô6{7:‰D2iÒ¤††%¯ …¡¡¡/_¾ì–Æ`CCÃܹs›šš\¿wï^úisss“•õV€¦¦&Ypr·×èX,Öþóø¹  Ã°ÄÄD¦,«µµU,³ÙìNÍœ6E4µeee{÷îµ³³Ó! H2dÈìÙ³ ‚X»v-†a8ŽËµèÄbqii©b{P\.·µµµýy©nàkG …ÂúúzÅq×\.÷ÓO?…è:iËÈÈ€ÝsÅZZZŠÅbÊ5¬©S§úùù¹»»C .Kh®_¿~]šH………Jjdʃ „jnnær¹Ý¦;²P2 Ã\]]—.] ‡Zèž{ñâÄ”©à¼ãñxÝ)R4,,ŒÏç+þ¶‰>Ðà*ݰaÃÉ“'»4ìííKKKɶéé ü`°Y,ŸÏ×¹]e^i‚ ¬­­-,,þüóOz&w—!ë×Õ]öÊÊÊ‘#GÊÆQ§«¦¦æÖ­[•••Jö¥Í9 ª)är¹ÍÍÍ]í”——W~~>‰ËdOX†?~’"tË£A,^¼8))iúôéGŽÑ6™EÄ‘#GT# Çñššš”””ääänp8éÁƒýû÷766îR_¢¢¢vìØAu÷KKK«««½¼¼ºúr­X±âÈ‘#$R¤HF<=z´®/ÑŠmŸ/^,[¶,>>^«ÞmÇ›ššT&©W¯^€hg]‡žžž···A—ÄýŒ3©V²êêêxºt£@ ×ÓBŽ«¬¬¬MP ‡ÃisXG;^.—ÛóXB× póæÍqãÆ=zôÎâi¶Ë°M^]]íëë«Îsz÷î ±¾:­ K$’¥K—æççwi\dQ“Ç ¢Ž¼òòrÔųeAL™2åĉÙÙÙo¿ý¶ ¬3gÎÀ&« , r h¹¹”••…ãøÐ¡C»½" ûqçÏŸ÷òò:{öìüùó5+³0 ;tèúš7ož¯¯ï¢E‹,--uwh $uý´©©©é‰'¨v¿Î˜1C tuÂÈŽ@’¹–µåÙ›7oVðü6wiê4‰Ýš5kˆžà9,-ò)=5==½×¯_«ÿœáÇK$;$wÞyrœ©€šššÀÀ@H›G ¿jð÷÷/--%k¦á¤,•~+Æ›¤$†a»wèï¼óަôy‹µ{÷îâ­–§§g^^^HHÈÍ›75¥a+ÄÜÜÂŽÔ÷Bé¨IÝOJJrvvVA˜››WVV*xÝÔ'O .&&fذaºÖýÏÎÎÆ0lÿþýpª¤¤êÓÐLLZZš‡‡êI€yãèèxöìÙÜÜ\¤¡€X¨***¤R))S¹¥¥¥  @GGÄÁÁÁÛÛ©”}n‹Å$‹¢‘R3èG$‘6Óèt?wîBè·ß~“ÿ255QȯÌÑžVÔ@Öå¬_¿ž~{œŠ õ~øA___GÂÚÚZÍQˆíÒaÌ.‘Çb±Ô|Î?þ¸uëVÝ;šý÷ðð¸ÿ>ÑîdbYYYÿþýé‘ mÊ~ôLÀ6nWÌ“‚?þ˜DæÃh‚Á«sËÏÞ½{OŸ>MV÷IǪU«Ô)rß5œfíw×®]›7o†èd™ z÷îýìÙ³#FÐ܈a˜‹ÅB=fffAܹs‡~Ÿ@rr²X,&k”aÂè\xJYY™ '“Ú[…Ê'çéªRã©IYïNçL­©©Y·nÝ›²Jb&•Jëêê(vÀýªªªÖÖÖnvG…™Äáp¦N*hk´ººº¸¸¸¥¥…ÄQÆ0¬¥¥üî:, ÀŒšÏ‘J¥õõõä¾5@Ukk«H$RÿÉ£F"%)Nçë:gΜáÇ¿i„ æÏŸÿöÛo744PJɵk×{H-eÅ“2''§´´´¼¼œ¶÷<**j„ P>–DØØØôë×öst…ÿÏž=+))Q?¨¦1¹òð۷oO™2E___ýi–””D a8m/B(..îüùóŠwCüýýÁ#K=)))#GŽìáÒ ‚ÃáL›6íM%›¨›Íž3gŽ|ÒZR`llÌãñ*++uhµ0441b”zWwîÜùä“OHÇôôô¡C‡r8õ§YCC,Qj¾×äLšÚÚZع”AOOOv¶›P®äœ îîîÆÆÆJ^¬ }8b€A;wî<}útmm­¹¹9ÕÍ_¹råâÅ‹T nïÞ½'L˜ÐÒÒ¢þ;FÏj1jÔ¨êêj²XaeeUUUE.…d½&8Ž'&&;v,$$Dó+22²MÇŸ>}*ëöƒ.\ˆ”ˆ4!"22ò§Ÿ~ºtéÒôéÓ©˜(ùùùß|ó TQf#²lÙ28ÚJõyÇÁÿJz+A÷Ýw‘¤å†!P©÷É"JÛ#’òO …ÂÒÒR#Eÿ½xñbII Œ£èhΖ-[dÏŸ={vUU•ò[Ή‰‰zzz4ðùü9sæôÌ,#xöìÙ 6PÝPccã„ ¨kâÁƒ3gÎÔ ¶Ï;<;d¡¹¹9"""--”§•••A=z²^“#GŽ=zTâ°®\¹‚‚ZfÊ¿?l6›"™Ò§OFHµç¹P(tuu¥ZŽ«s*­›…×Q8¶}ûö?ÿü“NÖÔÔ@™K1cÆ ÈP¨ÕqX‡²µµí’åÌçó'MšDnL<ŠÒ-HÝ5 ¹\î®]»ÂÃÃ)òîÁcëëë©6o T]]­å ohhptt$Ý4¶´´¬ªªR1 ëÕ«”û#‘<‘H¤æ~+%%ÅÍÍM…™çââRXXHn´ÎÖ¯_ÏH¨áäätìØ±ºº:‚šSi½›:H¥ÒÜÜ\'''¤­Y@Õ¨Q£ž?Nn AË—/ÿòË/Õ< TA4¹ò4((èàÁƒj=““ÐÑÑQ5Õwß¾}W®\!—*ÔSÏ*iO:99QÔ¬®40!ô믿j-«/]º„jnn¦âáööö„ÚçCçÎKºp å )å–¡¡a^^žj¢ÚÈÈˆÄ l˜Ç°áÝó‹ªiOû` ª««™wÅþ 8pá²f-0ßÐаººšÝÖÑÑ1;;²­i‡ëëëóóó===iJÕÞ»K—.566RDÒ7† ¢Iõ¦9N;(&®ò“çÏŸAÕT‹0 ‹‹‹ó÷÷'ëDwH󤤤£G’ebïçç… hÇ›7o‰‰.IÔ}‚xúô©ƒƒuÂ477wòäÉ*/̇¾~ý:u³K5œÉóæÍƒfylÛ¶M^WRíÉ0À<O}µèÕ«W¦¦¦Œz¥ \\\~ÿý÷˜˜²^øŠŠ ###ÚòùñÝwßYYYi•U±WÖÖÖ.@04hPNNŽ:ʇ³³3uL(//Ÿ5k–jÝ'GÊ•J¥’¿ã‹/¾ E’b™WWWÿãÿxë­·a¤¤†}íÚ5R2…766ÓYš¦ÍüùóÉ-Ч>UIII²Z2”¶ehhøÙgŸ©@auu5Ç£hCš‰Dpô]…7šÂ"$¦XÚ¸qã©S§Tc©Tjaa1yòän\0•tøúúž>}šÍf“²Gáëë;nÜ8:™O„¬¼ˆö ú¸qãΜ9CCßcbbT:×®]swwçñxÔ‘geeåì윑‘¡Â­öA“&M‚ò¶*[ÎFFF Ô™€%ynggçíímbb¢¦M„±±q]]Í̇¶Š‹‹'Ož¬ ƒBS__Ö¬Y4$Ô …Û·o—% P¦¦¦à‘×þ¬­­U+¢ ðaÆõêÕKµ`pKKK œ±b„‘’<'âêÕ«@7,³ÐãÇ5Â|¡P¨ Ò Ã0PWi ÞÞÞk×®•¥xR`Ú´i½{÷¦š<•sgêŒZ*•ªæÆ0,66vÙ²eŒz¥‚†òüÃÊÊJe« ð .|øá‡šb>‡ÃÙºuëØ±c»úê’ÎÌW¯^ݽ{ÊÒÓh]]òÍa``0lذ… RM¤‡‡GZZd×é²ì§úhYÉ.€û*œ€™ã8*'?øå—_T¾J]hùuuunnn?ŽóÁ´´´ÐÖâ‹/fϞݥ[¦M›–žžNϼ‚Ô ]=B¤ä„G`—d?†aŸ}ö¸ÿõJ5%+--íÖ­[*(Y†mÞ¼™~ïU›™cjjêèèHÖy ÕÐØØ8}úô‰'Ò– • ˆ<|ø°KïææFƒ‹ !daaÁf³•7 *¼ÃoÛnó Íc.•âââ.ËÊÊÊ^¿~Íx¯TÇ;zôè7T:•••ÅÅÅd>Ì–ØØØ¾}û–••! í>}útüøñÁÁÁ´µƒEó”¸ÊÊJzV‚ nܸ&¡2<‘9Cñ6~"PI>ûì³/^´¡îÙ¿ÿçŸNCéÀ`ݺuÑÑÑJ2ð—/_Z[[ã8ΨW*ÃÞÞþáÇñññ]ñŠŠŠ+W®P]´MÉ™³gÏž¾}û&$$ÐL xÙGŒN³¦)•Jccc¡EeÆ®ÿþYYYôœ´ª6mÚtôèQex‚a؃TÚ˜ˆÃ‡¿ÿþýû÷ÀA(={öDGG'$$,]º´EÚ[·n%×G ÙÚÚ*ïIJJÚ¾};ãRŸí)´K‡ÔÔÔ ÐéµQÜ…?ÿüsúôéô;Ô‘æ’!„>ýôSeø#«üBç XZZ*ïKÍÎÎFòêðü0aœ­—ÇG}”šš*¼¼¼ä¿Ÿ={6mNýÿüç?[·nU¦“b±!ɲ¼ï]½~çÎÚÓ ¨(sæÌšeÈzH+©T*‰<<<:½rÅŠéééôigg§Ìe&L€é‡8pÀÙÙyÈ!NNN§N’ùJ¿øâ ù¢O TJ‚ âââÞ¤aQaýæäät„aØÝ»wW¬XññÇ3,Rx{{{eì Ãîܹ²víZía¾……ÅÇwùJøsIDAT,XpéÒ%|ðü€€€ÔÔTBCU|ÀŸÿÃ?(¸L °Ùl###š‰$"!!Aqý*`cEEÈßÖÌ?þXṼÏççååÁ¿ÁÁÁÏž=#B™¤”ä†5ÈðêÕ+ssóÒÒR«X.ˆI.J€¥›6m‚ÔnJªcZÅ| æöíÛ¡½{÷Ò@ŸÏ_½z5TÔ ®]»æääT[[û&¶Ñm¯_¿^½zõË—/û"""Z[[‰öUs<<<B}úôÁq¼®®îùóç!8\N„H$òööîÓ§"¥_`Á “ÕwQàR¡"Ç+cÞ¼ysýúõÐ| Ìò`»p÷îÝTËw„жmÛ4ÞëÖÖV???ÈÖ!F- 5E^xxøãÇß´xÀ`ÁžO[¥`Á‘wo)¹4Q¤aÜÜÜ×svvfÔ+*°jÕª»wï*àíöíÛµ\·•J¥ååå`qÔÔÔ455)ù(/AZM:UKø”݆øÜØØ8pà@Í.!vvvmFAöSFFÆûï¿/ûoïªPàÅ] Ùj©Tšžž>mÚ´ÌÌÌ6ÎèØðáÃccc ­/ÿ«s bß¾}&LˆoïæWUUA J­e>†a½{÷7ë¬Y³LMMÿý÷èèèèèè””d+ãöÂ0¬ªªJOOoΜ9ñññ*¤ñQ‹ŠŠzûí·!˜NÖ Ã222Œ¡*»Ý£‹/622jÃa ÃÜÜÜ&Mšô?Dë1""âÛo¿%(+r'‘H8NNNÎàÁƒe‚ Çñ‘#GJ$’„„SSSFÄPÄÄD??¿Ÿþyùòå2ÁÌ3fÌ[o½ÙJµ_øå‡’H$†‰Åâ•+WΚ5 ö—Ûìtÿú믊3¦„B¡¥¥åÒ¥K¿ÿþ{­’ÚW®\y÷ÝwOœ8±hÑ"â¯Äíöööÿú׿–,Y¢AR¡é¨¨¨—/_nÙ²…K*aØÕ«W'Ožü?ò¨Sö(5 a1?xð BHÞü¶µµUr£”::|QQBèÔ©Sò?ñx¿´´T ;bffvôèщ'¿K—. ÕR/_¾>>Ú(Ñ-)€c=íôbÏéoÏY•«2‹ ºã.!Ý]ÕÛ|èôJŒÀbÀ@c6H\\ÜÉ“';Í_ŒaXRRÍAØ Å ›ëJJªE ­Ž9RTTTWW·iÓ¦ö%æÚ|¶°°h/פR©|•ªö麘¡aƒž.›1 ãr¹†½zõjÕªU J|||vïÞ ¢ÇÏϯ}ªÅ¢¢"ì/ „îÞ½ëïï¿bÅŠ6¡ƒÄ_E4¡ ÃnÞ¼9tèÐêêj ÃNž<™˜˜Ø§OgggÇq766Æqü»ï¾“í‘ËndÆ‹X z40 stt”H$"ŠÏç755Á÷uuu¥¥¥ †}ùå—{ö쑆Ab~GÏŸ??zô¨½½=†afffmšèÕ«—X,–e¡7n\HHœf³Ù~~~%%%IIIAAAnnnùùùµµµ¥¥¥………æææ2Ú «€Í°€:J¥FFF ,£ìÛo¿500À0¬¾¾žÅb‰D".—Û^ØÉ>4hùòåP²¡*$‘Hjjj.\hhhhccóõ×_ƒÚebb‚jjj:sæ ‹Åjjj244444Ü´iAï¿ÿþ€jkk6;;»mÛ¶1ãÅhX zöÂñÁƒ=|øÐÅÅeàÀÖÖÖŽŽŽC‡­ªªjjj‚d’b±X(¶¹722rðàÁÎÎÎׯ_GUUUUUUµ7ÜX,–··waaajj*FLMMýå—_<==B"‘ˆÏçËDç©S§rrr222 B®®®EEE=rrrb«;hôŒžÌ@MÈR5q8 Ã Š¸žžžX,§Rkk+‹Å"‚ÅbÉÙÓõôôBpY‡ž&±X ×s8¸ŽmêééBQ»‰„Íf=,‹ÅbÉÓ†zÞ™F`1`À€Æðÿb÷ÕïA°Ð‘IEND®B`‚snd-16.1/pix/toolbar.png0000644000076400007640000005740211530220006013300 0ustar bilbil‰PNG  IHDR­y‚ÔùsBITÛáOàtEXtSoftwaregnome-screenshotï¿> IDATxœìw|”EþÇgží=eÓ6½j( „4¡÷.‚¢ˆØÎz¶óÔÓ³€Ü"Š JéB‡ÐB(„ô²é=›íO™ßO²,Éf³,?™÷‹;ŸÌ|Ÿ™-ó|žï÷;ó€Á`0 ƒé˜^ü£»Á`0 ó§ãÜGÊþ}˾ØUwøí ƒÁ`0ÌŸ wj ÿ=Y»þÓO?]µj•»»»ƒ†$•ýïï0 ƒÁü)„»ûÚ$MùCZèPK°S-UVVnÞ¼ùí·ßv\-YÚb0 ƒÁô©|¯žuþ8ôøƒvÒU-u¡¹¹9;;›¢¨ÈÈH›u°ZÂ`0}¥<ø” Çé¥úÖµnú£û‚Á`~_x Õ´9R×LBJã÷oØIjÉ`09rD  0€Ãá|÷Ýw“&MŠŠŠên«% swˆ2 ø¤9™÷GwƒÁü~ b­Ý©], ÇO˜`¿Ñýûí4<°÷&·ÿdÕÐB§Z¢î(5ßÿ}hhhrr2‡ÃLš4iÆ ï½÷ûÒš.m1 ¦wPÇ%YãŒ!hg0Ìï Bä ZÔ¡4nÈÖé©áø öïÛk]ÂÄI¶vbÛ·tâĉaÆ 4È¢BCCu:]EEE`àíÈBÈd2aßó 1ßuÊsž ýiD«Í5û[ÿ³ò?€œþ}ùªOj¾ñá{NvNÕ1†«¿üº~3Àƒ§ü,àDùðJSíê•ÖÖ ]ÔÌbPï•uñô8Ò1ÈfÃ}{öLœ<0aâ¤}{ö°ål `ßž=6‚žÔRzzzPPu Ç›7oÞ®]»–.]*“É¡òòòŒŒ ØÏ¡áb0˜¿¡¢€µÿœºzÖ¬3FG¤ã>Øù‘i"ŸõýÍã‘â¦²ÚÆº ÷€|_=›q&/²rCøêa²!PO}ç÷1—°Š¾aµ„ÁF›ÍB#ïÚ/—„aôUßÚÈ:KĔ⶟<¿²=Ú?ö,Ì÷“pÅ–¿âHó`Ùÿ8‰ƒØ1EÜÑÐ~sÔsC0mÆlö`çö­ìñ´³vnßjãŒtUK±Cc7lØà¸â#OsÌEÔoâO×coÖjê½E^B¢éâÒb¡ÁùÖ¡e6Ë)»™]y}°Oÿ5ïü÷ø­ÓqýG €`ç†#qÌûÛGMŸ9Ç~ÍÛ~@Ø1EXò–zjh9éŽm¿ „vlû…-™6cöŽm¿¬Z誖(™KXbºãc¦…\<Ía0 íGKOÅH#úô£êzqÎÿ¾ZS]_ ƒ$AK5HßÑjÙV z+~Àˆá±«7~úÚ¬åN–šxÁ`4ÉòF„w¦9–åm«áŒYsÙãí¿n±XØþë¶|úÌ9ÛÝÒ½!èž·T¯3U¶{€/J€0˜Ššöº%ûŸã56™€H"Z„pè¶q¼Ÿ @ÏÀ`>dÀ cøëõÀ€`0¿ÎÐððá§á;FÔBC>Ürn*4ÀPÀyKÌ„tìÙ V¼P]ZtO_¶oÝÜåìÛ·nž1{ž†ômM\wš$¾)Ä`8ÄŒA-"(€€0|@+¦‰ 04€$ ÆJ¡±/)/ÀMsÚ`"áÏFbè®ËO0Ì_ÖÍðëÖÍök2 #0ÖP»? m&Ýþ“UC ÷ª–¤<žæ0˜Ò‰N] ! H\n¿4»0–—€”‚¡Ö-¥&ƒy „Ö„wj—ß¿!è®–\„<÷‹ê¨/âáiƒÁ`0Œ£@xùÂñ¾TïT)¿CK `>zñÔ§‡·‚Á`0 ó À«ƒeÿ¾ÞçÝ)1 ƒÁ`(îˆÄÆòŒÂ?²; ƒÁ`04þcB™1·óœ:ÔGe…fsÖÓ/ ƒÁ`0˜?|~lÀ°þ–—j‰ K7ä÷îƒÁ`0ÌŸnè”FìÓM:}KÎ5Û~çža0 ƒÁüy`¥‘}µ„Á`0 óàÂJ#’$VK ƒÁ`0ݱ–F„¥èîSRÒÄU«>ë~ü; •ªNœ8ó›ž÷wÑ=òÿ«· ƒÁüÖÜË•ÑZõA-M›¶B'Ë?ŸH@zú˜èèȻ뇃'‚ÐÉþP­û0jTúÿû…ãçš8qΜ9Kº¾üò?~›ÑõD~~áœ9K”Ê ¡Ð#&&nÍš¯z}>s—Áþž½Å`0 æ÷dÚ´K–ŸxõÕçƒÞq"€··—Ê÷҇ŋç/^üdkk›“SÇëhšÞ¸qëK/={–ûÄÍ›·FŽ›¿mÛWW—“'ϼþú»7oÞúâ‹ÕŽùÝz‹Á`0Ì_kiÔ·Hœ‹‹óÀ1쿨¨г‹¢¨×_×Û;B p><õÂ…¾mãd}¢cÜÜ”€¶6ͬY‹DžÁÁwîÜg©léÃC-;{öüóÏ¿¡“§g˜#'š2e¼P(غu§¥äèÑ“õõ Îî2:›#Ú±coPжÂ?l‚Ðéðác’$%¯sç.:8Þgžy9&&j×®‰‰#££#ŸzêñÍ›×ùåú3gÎbc“^{íqãføúFܵk¿ÍÁZ÷V§Ó?öØ3ÎÎþ‰×ôé ««kÙòØØ¤·ßþpúô…®®~~ý¶oßÖÿôÓ–ÐÐÁ\®««kàüùKì6ƒÁ`0Q6/¦v¸ËH\Ÿxá…7Nœ8³}ûO—§OŸ4~ü¬¦¦æ{´ùøãÏ—ž?Ÿ±sçÆU«>3™Ì]*üôÓW#GŽøÏ>@¨µ¶¶À›B¡pîÜ?þ¸ÉRòã›ÓÓǸ»»92¢Q£F”––WUÕNŸÎtuu9}ú ;ûBhÈŽô¡±±éøñÓO?½Ìz׫ñãÓÂÃCùeûòóÏ¿þ׿ÞP«s׬Y9oÞ£ùù…öûøãÏff^÷ÜröøôésÇÇòù|G:P\\ èׯkÊQttdQQ {<{ö´aÆÆOKJµ~ýOv 666mÙ²}Íš•ÇÇöëñãë²³¯?‰ýëCÍ><°pá.—{ùòÕÆÆfÀ„ cU*ÏÈÈðGYèH·1 ƒù=é¢ Ö­ûŽ-w\uôébj3oÉ!Ç’u:‘JåÙSµÜÜ[$I†‡ÇZVW×8rŠî'„„]½šƒb/󀨨A÷Ë7,$$hÆÍo½õ÷mÛv ‚)SÆw©cgD q§OŸKI]WW¿bÅc~ø³Ù|útfBBü}éKtt”å8&&*77ßNåüüB†aâ↱/}|T¾¾Þ¹¹ùlI` ¿¥¦B!okÓŒ?räðÐÐÁ'ŽKKKž5kªX,ºÇ`0 æÞé¢ ÞU{»ôEuôébj-3ú¦–Øt¢^«±_¶·WI¥GÌ:x"‚ ,ý¼¿¡Ã‡ž÷ã›ßzëï6lž;w†@ èRÁΈâ>úè¿§NeÆÇwuu ºpáòÙ³ž~z™ƒgܼ™×eE[NNî¸q©ì±µ#Ý)«W ì©üŽ? „‚8vlϱc§22Nüë_¿ÿþªììS‰ØÁþc0 ó;ÐE¸ºº°jÉqÕѧ‹©Íý–—Å9BTT—Ë=tèèý2ˆˆEYBŒ……Åfs×¼%‡Côºð¾;‹Í+**Ùºuçñã§/žß½‚%$Äçææïܹoôèxöåºußµ¶¶Y\;½¢Tº&&Ž\³æ+öóf9pàHAAÑœ9ÓÙ—Ö k.\ŽŠ =6<<” ˆóç;šTVV«ÕUýúEØéAcÆ$}øáÛW®œ.))³„í0 ƒù“ã¸ê°y1í kiô›dy;;;­XñØÓO¿¼cÇÞÊÊêììko¾ù^nî-Ç-47·\½šcùWUU£TºNŸ>éõ×ß5™Lf³ù7þm9O|}}23/ÔÖÖ57·8~:ߤ¤QË–=4bÄÐ>( ÀÏÛÛkË–ílè-!!nóæmƒõï“_í³ÏV^¿~sêÔ§NeÞ¼ykíÚoæÍ{tùòGGÁVÈÈ8ñí·ªªj>úè¿YYWØÔ¢ž«TºÎ;ã™g^¾t)ûæÍ[‹/>QQQÃûÔáÅ‹´¶¶uÏïvdD ñ<oذÁì1MÓ q}:{LLÔùóB¡`Ú´ƒ^»ö›÷Þ{síÚO,^|ñé]»ö…„ úòËõ[¶|f°_}õ¿áÃcÇŽ>lX²L&ݽ{³MqÉ"•Jöí;—æç×oÕªÏ~þùë  €>õƒÁ`0˜?U‡Í‹iOXK#˜^ÔÿR Ø5÷g³9‹Ç@Ûo0Ì]›´dÉÇ¡0 ƒÁtÁñ‹©N·Y*]>uËBÀµk9eÿ¾Þ‘åMà§êb0 ƒÁtBÜõš8 ƒÁ`0˜»ßAó‡•uâîƒÁ`0ÿ¿éëÅÔ¦ZºoÛ`0 ƒÁüÇZa߃Á`0LWz‰Äétë~ïa0 ƒÁü™°§–êëŒü:…Á`0 ó§¡ß’·wôïÝ# ƒÁ`0˜?/nެ‰ki)ý=»…Á`0 󧯉Ã`0 ƒ±GÖÄ™I²B]רÔBQ ˆ}â=BˆËåˆE"‰X$“‹Ý•.@öQ*ÿßé˨1˜ß šFþÊaîž?dfC ½ó£’K»ÌFmÿô§cÆ=éH«‹Y×ü|Tžžn=UÈ/(É/(™2iLŸ:s+¿äVA M3ìK‡èŒ"náöEÙoÇÙ—?}ز¼¢ÖÕÅkÈ ‘q‡ó‰¦)’¢ÌfSMmÕÍœ£!þ´TPI®Â!P4–†ªß®÷¢-(Ê{õmDpC_yÖyØà>µudÔ™®øxy*í<­ƒ¹¼¶öüÌä áÑtGî?:½±´¬š €¯·§L&Η_\_ßìé¡ŒŠ  ŽŸBo0—T45·¹¹:…„ø øü{ï¶ÙL–”ªkjÝÝ\¼%¶žóÝ$I©«ê[]eÞ*‘¨Ç±´i´7nq¹DXh€³“ü^:ü‡Ìlç7¾FµU‡ °ãû÷#“sù=~Ä,mmš¼¼"uEõ¬™“¢»W Iêòår¹B]Yãëãåxg.^º:uÊt‰X¾Ôét{öîú¤–B¥å5Í-›uuQøyÚÿàöì=¼wß‘.…B‚ $‰\.ðB’4>xLê(VR?°ôA-ÕÖ5’`4†fXÃ04@€ _ìÝì¦1ë.Z2Dîoëjÿ-qÓüÑ$ìßÓé/f]_“6f´MµúàеD’$„¢H„ƒ„b„Ã0$E2æ«$yTÊËeLù"·ÅnOÀ1·|.t–0„˜&BlÚgww÷û2Èö[…Š1¦KZÍ•ëŒÉLúp+iÔ“¡­­Í]é9°ÿ¹ÌéBÖÕ‘#:²½§Y[\ž¹(*u§Ø9¦¡ø‡ÆÂµžÑÿ¼‡!öÈÎÜÏ}\#>¹òFÍ©N<ôÊèï¼dA½¶jooÿîûÍeåUÆœ41MÚmÞ×ë »÷ºt骯ê‘Åsœv¬8±iúô×{].`6“&“‰Çãòùü.÷»I|[ºÐ¬1~ø}ö°¸!Uêª~¼òîÃúÔœ¢è[êÐp7¥‡ý/*MS õ· ò#Â|íè›ûnP«ÕI¥R†¡›[ÚlVh×êNΚ:y†X,Ñëµáaá[·]uP-éô†‹Y7Ǧ¦‹Db½^¼÷@î}QK5u q#’Fƒ\®˜4aêŽ]¿&*“IiÛÐÐi©¹\.° fu:h:<5]6Eåä\»˜u=iôðžÎ‹*-¯ åQýt:-Eu½Kár¹Qѹù7JËkýíy˜ …D"aýIA@)ŠâóùNN·ýÄÅb±›»ø Çãú –hš1 ƒX{ 9¦ýŒvS+£åðCÊg"×%ºúÏõåÿ%¸›y+ ¡ “ÑhBÝ´.”Éœüü¾ß°¾»ßËå%&$ÆÚÇa"Ä0úk@_?l;£f¿;b‘¨°(İøà væÒåœáCØ÷²R)zìn‘"œ¡›½SÊ®¼û©¥«5Ç&]a‚-ý|âžMùòãc8"˜¾Y¿IÀ7®¤¤øãUk^yé©ôöÜ­ÓéW®Zëæî>n\zqqá·ßmzñùå÷ÞU“ɤ®j‰®Î2€Ïçóÿ„‘M½^ïÈ"—Ë‹{ 1Üï}›Õ¦5?zPPÆð9 чÊêÆð°(7¥;Bˆ¦í BÂÃÝ‹ ˆÊ겿C~÷ݠňMkíZÝÉ“§N™%K´Z —Ë++/óñv("©Ó.\Ì—6A$³m+++½<\iÛ+Î iee…››»V«‘JåÓ¦ÌÚºmÓ˜”8¹\Ök[¹\\S[åâìʶ›6aßþ#ãu¿Ka˜­@3]],}å·˜Ùì ©/i.¿ž2~žÊÓ¦îþéÃÔëiØÔÔHeƒ¸”uuø°k÷Ò…‹×Æ¥% 4êuÍ­­öMÚêdƒÒôõ¹îÕÏ™3ï¹ á<.׺ÂsÏþíV^·¾>I¬P†\9v#µPRRž–:Ñl6B¬0Bì·_‚ˆ‰ðÍús=©%„PYE­P(c¥Rñº¯n¼ü °¾VBýчAË—G…GçÝÊ)«¨ ðëÑÃ$ E"Qg;!4›Í<O,CH°rB à þ‰È÷BŸÔÅ~Ôˆ½ÄŠ´˜[79þÌ—&[êCBäÖï@CóΦ’$!ÝmR4ÝÖÖj6™­ ›Lõ2™Spp(¢i†ý93 ƒh†aH’ÁÁ! õÁG»F¾ïŠ¢ôS`@hAQ¾‹“D*‰ÅB ù(L&“Á`äóùB¡ÀÚMe6“f³™ ˆ.å}±l.¯l°/˜¸\Ž¿Ûo¤–V??ê^škÚu\Ý(Šr$B¨tuÏË¿i§Î}7HuÆå»¿Éííºã§.LŸ2K"éJÕÕUgΞš0>©×SëtúósÆ¥M´H¥ÚºÚ‹—ϧ$öxß'ÂÃOœ<7ÊÓË=³fÎÛ´ùçô±#Š^Œý}Ï_:?dÐP7¥Ûvâø©;woKLˆíâbºóàÞÕ…8‘×JÓ4ûÉY½BAmeû°¡ˆ€0:z@SKs}C‹‡û]ŠËâ ;ÂÄC†¹œ>¸!lÔÍuM!¦—o MÓ!w±ñ˯¾ê©Z¤J€^Ô¯PÍårFʧWX—¯ùtÍÊY^²¾=.—kÉ=ïB¨¬¢N ²R©äëoJÞy7)0O4E±ÿt&ÓÍwÞE?ùddDÌͼœâÒÊà@›‚ BÈúx<EQìq§Ÿ‰­DÞ­“«Vr‚èÿ¼/îñêöׯ†Zê š¢¬Ï¶S6L Wàoh\Ï—ŒÐZlÑ€Öé›vrŶýä4E777éõ@c£¾¡AÓÓ,@„››\©”¤Ùf…ƒ4]V^ÚO ŠÅbvx» ‚Aˆ"I@ÿ~ƒ))Šª®®nkk;’›’<ÜÎ “QwVBàÀ¡ýb‘xtB¢¯·oÝÍ×™zäÕÿ=Èéxf¥RTêÏ"¹/¥;ApÝ[«_| ¦¹ä‡.•ù?‘ó ™WºÜ«-u¹êHVÕáâæ«õZu÷¿žWïE\2Â7¶ÔX¥rz$ñ_ŸìE0õïYZZ^]]!±jõ/¿¸°ê“/|}|ƒCB+++U^ªü‚[ÑÑ÷'ÃŒ$)€‡»—«‹›ºª¼²¦R!I%B©TÂïcn{»¶¦®U à:+¤R©D$êHÐh4–r‰Dl?3À&쌔”ÊÎk êˆ  H°í3™'û”©àÛ·g´µµÛ© PÈfÌè}M+M&“ƒçåñxf³½_œMƒ‹Yd9þá» }2hå[º#±½]{ìä…SgK$RVîTUWed?>QÞ[ÀK§ÓŸ»p-}ì$±ø¶T:}öDrâðîþ›»C*%&Äf;>zT’——Š=óç.øiãÒ“œìfd‹Å‚a±ý2ÏŸçîæÁ¶:yƯ۷¤&°öN14ƒ`¿s÷ØavfCm=^„2ëÛ.Ë@ÓGžÍ©?wyÒ&Js IDATmÒ ÿGçMðõö­®)¹ µ„!·äÂÎq3W@¿²$§¥¹!~Ù³6wVÈÛ4m‡Pºy&&$ž:}nÂø$Ö½”y.{Ò„i½Ž$ÍeåeÁöM14ÍÞäÎ&2™{œR|ÛoæÞÔ’5¿lþ•=˜3o„0mâöåÁÝ;¦Í`_îÙ¶Õþ]GyE@ ‰ŠˆÖé´%ß|[ôÏ·‡º¸ð!dhuº N‡sëw@AË—÷‹Œ¾zýÊ­‚²ÈðÀîYadQHìûÿ–:íùùÂ/ÖŒ\BéÈ O¾˜pzÿ}yOþ_Ó›ZbŸY9B;·P(P$[vkÔÏËý>íü£0íÍ¥ÏQÆ‘÷§6ÜE5Ô×›Í&@Cƒæç 9ÛÝ ijá¢b´3M „ÚÚ´r„B‘I­ÎzþyŽPè?> Bˆ"I¡²]»j¿ûŽË‹9GEåÜÔh´ EÞr;£¶H,¥RIStiiéöíÛF%$ê)žùEb%•Nœ>6&9ŽÃá^¸t]­®Qy¹÷ —JÅíZ]vöM;ÖF£©¸¤²¶®ÉMéâ+ õcn^IUu­—§[¿Èàqi#÷8˜’4F¥R566¸º*-\²þû¯gLçâìdßÚèQCŽž8ž02ÉËÓ«½½M&“Ï=㦠ãÓYïÍ0†¡-!¹»Æòö²Qi’º.‡@¤V(IåNÂãWjªêÛ=]U‘¾^‚ÓÚªaÔ§˜4Õ&¿uVÒBîv®´¶©î¿Cg„+Ü•Ž[ˆŠ ÍË+ª¯otuqKd©É©ÇŽÌš1>ëò…ó55Ö …¢¼ü[ÞÞîI/ÍØî•¢‘Ún—'†a‰’>ɼp!¤PÈ¢#{_c‹Žl¤¯¿úÖªʤ·¿ZÏ=ÿl ¯'{üâË/¬ú¸—ÛE‘×ÿöÂP¥’!MQ§épsӬ˛‡P EÝzãM¯Å‹dR¹™´½^µ‹?©´´tÀ€©©©mmk,²ž}N%iPxx4ýRwµ¾)ìó•wõ>üÕpH-Ðf…¬X` d4 ¤H!—/DT…¾õ˜¡é€Ø5]¤ IB.´íî¦iš¼sÕqÖ•‹6k¦¥Œf’Ãﱟ ƒªkâã<êëë[šš%"KÛG/ð¿q¬ŽaŠ$}‚¥C&y·_h2iÚE¡ˆðˆ»vĉ±›Ûn{Ô,ÚÚƒ‡v=;õá£G*•9; ½$9—ß<¿®¥ìkµä»ºðä|©â+gÏ`ʜà ç ûÓæÛƒA Bz²ý0ä\ ð÷K»Óõ­¹b§(ë*åÍy9µ§_šñÙ ý^Ó*"œ8PÔû=øaudA“¹TÆõ8–¿¡´´äÍ´ ¶ëHÄ/¿´bÕ'_„††ÕÖÖ¨¼¼ AÔÕ×yy© ò+Õê—_\!±µrçî Âh4"†±‘¦–F‘P;d„V«½”uN.“xyºI¥"‘Hh?Û”5e0ªj+ÂÃ#.\ÊlhlQyºÛ,÷QyÈd±¸³¬ev‘­M©Äãò A$y_Öô!6)ülóµÌõ³l2ïµCï¯Ôc¸Äh4hšâpˆ?~ŸËµý}¡(êÍ×ÿÁ ¶IŸ *~…B±jõG}2hå[¢švÝ‘Œ³³fΕJ¥--<_]©>rôÈ”‰ÉNNŠ'/DDôŸ2yö­ü¼ ²ÓÆÜ‘Ô¥ÕΜ͞8~ŠDܼ«©­9~òhZj¼\.;wáZhHÔØ1“‹Š ³¯^=*öòåv¬±«ýýBããR*Ôå·òóŒÌÍ- ŠLM_RRt-çFüˆAÒ“vï9˜’2F¥ò®­«öp÷zdñÒ¯¿]7gÖ$…}k)‰Ã9’8:ÙËÓ«©¹ÑÅY9oÞC?ýüý䉩NNr†a4Ãܧ,o‰Á^r_¥8ÇYzùìQCkOäP„`|üíØ–R©„ƒ€£+ãc6êŽ3thkC/#C³Tº[áz¦©p¦kèv‚ëPPB˜’àЩq©iš¶f_?‰Hrähf܈xŠ"iŠjln.)-ž:¥Ç°ŠÄY£….ìÅÅ¿îØrwj‰MÝXóéç?Ù‘º´þ«/–Ý%Ø §Kœ®W›ì¸ÑÅš`cpµÄÂE DÑ4Í0dÏjÉ:×ÐГ“k6›†)߸Is`KÜÃÁÍÛë ›Zõuõ‰ç¯>ñ<@¹ê“/ø——ª¾¡ž WWeyyiEEùK/>y¥€ÇãF1ÖBB¨Õµ‹Ä¢±iªªÔY—/úúxy«<är{é&<ßh0¸\žÞ “ˆ¥)Iig3O³—ê;Ê›ÏfžVy)}¼=í›e-³jɦTâñø¬œâñîuÃÚFÝëk/ÖkH£¹^„òÚö'><97-dùôh.ׯ÷Ù`0"„ØJ¥Ò7_·½ó½¿ƒ I!d0Ø7ö ¾÷î}5HÓ4›šÃ^ÎÏœÍ ‹ˆ%õ|€ÇãïÙ»{LÊHvÓŠâ’ò©Sæ z/O¯í;Jºè›K—s‚ƒCÅb‰FÓÊåò‚sèÈQqCr ¢¢*}ìƒAïîæ¾ï@ùèQ±ö­±ÔÖ4ŒŠO5ô.Î.'«jŒ¬¨¬MM™h0èÝÜÜgTÅää$9rÈŽ]Û_xî%š¢*«*¼¼|úEõÛ¹ûУKæØ·&—ˆ í¿ÿà¾'{’KÓuõ5J¥{xxäÁC'æÍr;wò–:&Šš[™êëöجk‡Syý(‡' "'<[\Y¯ñRÊ&%„̤£én³.«½êu™,Ä@ñ47.w€#ZÌC¾´ƒR‰ÅÅÅ)aTlÆñ£Æ—Hä111³²‚‚BškÍuö\椉Ɏ„éÙ,ï.…¬ŒÐêÚo{fš¦)š…¡ýBÙ\‘»ƒõ-YÒ㺼d¹3N×»A†Aìp†a/[è¶\ºÃàiŠ¡i²çdAëHœD"‰½zõj@@@knÞ¥§ŸN^àÓz²*ˆ¿#ÛrKsõÅ7GíñâþׯÁH€B›2o‘Љæ,p '˜RˆZw¯£§J[¹=F:Ù™Ñúûaß·€íuņa KGJ­ªªöpw—yx ùùç¬^hi6 »"“&ø2±ö2Êkj*äpBV®EF:ñùù…ƒÉʺ1y²‡mµÔó¨ËwÞýÜ’åë3w.¾¶o$—/•:‡y'ºz©Êy‰à@NÛÅšPž¼17cAø8w_]Ý b· IÿOñÍc¡ñÿ¹ã¼¤®:o]½ú¦Wàsû‘ÓrmËÚ.Ö*š ‡ ‰Ï×ð ÍÏ+ê:mJòcBÞ¿ÃïÏ¿§P‰äÎâÓ _9ñUeee×ÕoMøQ¥pôV‰] ƒnÇÄÐmû‚@ 4Œ Ãt"@†a‚½U~?mü^*‘H$b;þ„F£(„|¡€/àó*•÷´©37nÞеÜË{Ú”™7oI¥öͲ–I’¤iʦTâry‚C’¤@Ðû¶{öyóË‹EÕšÑÉq5{Ž÷©áèÔ‘[Žž»’ßøí›ÉÝÿj4ص¥B‰DBѶƒbì,$I2 c4윮'ƒ\`yé¸AŠ¢@E±—ó‘ñC8áììâå¥ÒjµwÙã=ñÝ÷ß8;Ëüý¼/\<ïëã{öÜ™À@¿.¦bE;y^!wòòô4ô..® ç=¼y˹B꤫TîÙW.«¼¼.e]ôóQì[cQº9åæÝPº*oÜÌñtwxy*¯]¿âéáyùÊeoo@KKëñçŸZþ Ï×ÔUK%²kׯd_¹üЂ™½ZkkÓdžË^òðR.§mj‰Ä¹¹7®_¿:súxp;Ë›¾kâ:&Òy3Xÿw—œ˜˜ÀîDÕ‘v@;¼vÁ¬=ß^õ¦wð†$Ý<Ì&]™¹¦®º!äŽ4/íó–~¾ªÖ(ÍñÓ§ÒǤ]ËÉI|éÒ…À€€Œã'âã÷ºêÅ’·tGWÍf€Él6'‚šš£Ñ€¸§_,Í0……eS&»TUÞд·‹E"ƒB´zué§Ÿî¹~}‚kË=xó¤F¥òZ±Â¤Pƒ¡MÓn&ÉøÃwîÚ1qbŠÍàIO£®/ÚvxïsK–¯×U½?ýö njþ™ï2¸­â?†¦WlcON‘<8jÌÆë‡DŽqu 34¼'÷\×\óA—jžÄ=x~aæ2ŸðéŒþ„l^{KñkMªl*1–Z}ÑÙôE›ßJÿ©‹T\(>¼bð['›>ç’Šòꊜ¦·&9*•´ZݪÕ_øùû{ûøÖÖÖ(]•€¦¦F?“ɼò“ÛÛ ÜD"‘ÑhDˆé.Dø|!‰ò²ÒÓgO ìßÏÇG¡½‰›5EŸ'à ¾¢¨êꪣÇ755Ù,Š íÕ,k™$I¡M©ÄçñYG‹H$½%ÙgÝ«I_åÈÙ¾6¼zéjˆJþÞrÛ>ZƒÑÈ04+”+äßÿø­Íjr…œu’1 m°8³ia˜eKŸ¬ÿþk6(é¸A6+œ¢)ö§§KÓÓGïÞ›‘8:Y奪¬*÷öö[òðÒ¯¿ùrö¬ ÆöÏ<—}øÈÁà ÿQ#c»˜’ÉÄɉÃgœ?ÊÓݳ®®ÆÝÝs6þ0yBòÀ‘Y—sNœ:àï=4¶?À¾5–ðÐÀ›yE³.¨¼Ü££Bý£Ã®\Í;sö´¯×àAýZZZ·n;°ôÑÇ¥RiYY±T*/-/=°ÿ¢‡f¸ºvÍ[êb­µM³ïÀ‰…óIÄâª*µX,®¨(?’qxöÌ ÎÎ `Éò¦ïC–7ûöBwŸ,¨i´·ÜRå&Ÿšz¾Sí‚Y›©©|Ó7ìq>_HÃG ËÄ\T&,)?ÝÜtÐÜC¢L„Á`Üs`ŸF£A }ùÊå¢âÂȈ€ÀGŸO@Ó4ê‰ëTK¦ä”D`çþG bnûðºìqã8ì&¸C-§Ÿ½½¡ÀÓÏ>ýÙÿÖ¬Z½Š}ùüsÏÛ¿¥(Šaö"HQ´ºÅ·¨%‹‡©cÔESTO‘8`•ºäïï¯Óérrrx<@P:tÍg]ÚŸÃñ˜¬**i¿yí¶`R "½þbŸß‘¿ ø– €vncoûY¬>4B‰€+ª·_—õÏÏd2æ:}¨¬¬Èf¨ŸŸÀåóþñÏ@ûÇÄÌš9›ýB¨¢¼Z©TÒ4Í0´ÊÓÓßß¿¾¾¾Òlv~ì±úC‡6nßâ«?J$J¥ÒÛÛ»´¬ÌÓÃC ˆEâÂÂ’ˆˆîî%›£®Ìß|tß Kžüž!eþŸq8b€´4YGˆ¢5µ[êkuzd2ža¶Wt‹äÁ1i¯ZÖ?ÒÃ7µ¶d›³*µÛyÍÍÕ§½ƒ'1däˆtÍ{8<—;oý ”ïœ×|ŠÏçk¨ê˜À×ÔgB§ð¸wÄ€†úÍ*8æêTª.*Ëiz{ê*'¥’~åêµþ¾þþ•••>>>••j„€ŸŸ_Uue@` hÕêµ/½ð”õÆ•÷B‡CÖB„Ïã øÂæ––vøM›2B†¦{™¼:MA>Ÿ/ˆÛÚZwïÝá¦t™6eÂç_|m³œÃ½še-“fBØ“TfR šÍ]=‹}‚Ë…OÏŽIâýÆÚóŽ·ò9 œ—Ú“?ß`0P4MRBhÞìvL!„HŠ¢hÚ`×dÓàÎ=«A%É´É3úd]àCQ¤å¾ÈI!Ÿ<1eÇÎCI‰)*/UYY±¿Ðҥ˾\÷ùü¹SÒÇ%¦KìÉš\&MK?pðĨ‘ žžžUÕj•—ÏÂùÿðã·Ó¦¤%'ŽHNq»²\fß@,=tÈít ‰D^õÙ+/=}¿.aϾc £F{zx•U”úù<¼è‘o×5kÆm!rï4·´þ²ußc.“H¥…E ¹¼¼¼|ÿ¡ýKÍR*]í·mmÕìÙwtá‚Åb±¤¬¢X*•©++222æÎžèb¥:ó–îG$Ž¢!€€]'ó«îx2ëþïXU`2›zÏY̺¬öª¿û†,%MÍúæ‘Ì“ ¸f£žéhÈ@‚Ã0}P¦ºú³£&øøø¤¤¤p¸\aAnnõ‹¯8ÿí"ó|höõ~'„hš.Ï-<=4uÄ‘’ Ó1mæ-±Jˆf˜Ô1)ì~i–ûb«wà^ÔYžÜ̾¶NTBÝù\ghG-‘¤™z‡|ð^Ù;ïùšL–¼_ËüÓ1.*„BïW_†Çd6Ù™”ØQs8vï4–ªªj™¬ 000nåÇ[/^¬ÓhœŠøÉ #w~ü)VKÀß:¿GDÇV|Z„„E•wPAG Í6/fMš8ÕÙÙtìõˆ Bƒ®¾¾Úhԣε—–ÍâAçr''×7o>´p¡Åà+Wo„‡Ç¨Õj…BÁ~ÞldÄ3&!d2™ª««YןÏçr¹\.·°°P,gg__°`š µdkÔQÃÿ6p¶}÷Òôéž&ƒà@H@„i¦Û5dUµY p=ã[×^ª¯Hæ÷NxÜ;]Ê¥N WÁpPÒG&Ä’sñóð‘ÿëR35rÖêcO§û&¶ƒê›¦ÝýÂÆ¹s„@ÊG·µ‹“Øí‰¤·ŸHzÛNOºsàà1•—·o…ºÜ×ׯ¼¬¬B]öÌÓ!Ö|þ à À@u¥ÚÏ×ßl2ÿ¼qÛËlnÕ7 „løŒÇåK%2„ÀÁCûjÓÒRÝ”Îe¢({WÙî¦Îœ=yæì™ô±©cÓ)ÊHQF@Ö­ÜDQö\Ý-wDd Á!8Ááp8Öó;õmð=#àqZZZÅb‘ý•ÄbQCC£›[/k³ Fˆ×ÃR8[ ƒÑ®o©›A¡T*=sî8@*•Bï<]/iŠFyKwÌ.ÎN³gNظyWjjšJ¥Ê/È |êÉgþûé'KYÐ=Èe“B>yBòŽ]‡½<½ŠK ƒC]òøº¯×.˜7 rÝ#­­š-¿ìylér‰TZP˜«;•W”8¸Éâ9½J%¦}÷žŒ‡.–ˆÅ%¥…2™B]Yy4ãðÜ9“]ît–0;0ô}ØA€§%EtÎßÙÀÊÓ„âD¯ó9À¬»Ò¦~É7x‰VSlÖåKä‘!¦½¥R"gŸø‰ äÔåQ³s¿·Ÿ¿Ûða'7n4ë € &Mž\}䈰¸·}×à+ŽlÞ¤¯«çáÑÑA¡¡5[w†üý¹ž‡LÐUe²JˆCÇŽ' ÙM¬!Á>þelú8p?ò–-\ÜḲ±¡X¼èëÊv&w7—K—/ 0Øcþ|šf*Þ{ß×`ì~™a¥’ÛËÏ+g͉DÇO ÙyK}IDAT·R°¬‰ãr¹!§i×´··kµZ±‡[â7_í3Ö¥5€WNqÝzù2? ôº;eÇEç °+»¬Þ¢Æ¸}ïo'Îh6“mšf½NÛ©„:Rý ‚‰%©„¬ž=È«Õj±X`±¦×ë[[Ú||}ü|ý,‹·Ù<Ã0Å.¢d„hŠ2™LZ­Vo0ŒÆæÖ6šAMF£I¯×óù]çÍžFÝijq·ÿ·éÓ=w쨵ÔèÙ`ð\úøZÿnÙ@L +º€&W‰Y'6:ùLwñÙ¥fßøÑ³3O2 @²Ôp¾•SíÎ VA ¢ÏëÚ„.e]IIS__ïííS^^VV^öØ#ó!„¡Ç–.Z÷Õ M54Ö‡8°¯¥¥U$ …÷šÚl4y\žT"Ïξ”yîìøqicÓFS”‰$û hØ!xzz´´4=½b„ŒÙ¬³_Þ'„ÁÚ/>·SÁÁg©:„pèÐHûûܰé>–]Ë{‚Çåêt:¡PÔS~·5\W§ÓÙ—VÝ wG0‹Ëã9n¢)€Pß‹‹‹óü¹S~üiû˜1iÞ*ï¹×£"cfÏžèðñó§Û‹““bÚ”´_¶Häåå•_1uêŒã'Ï̘ÖËrG¸˜uuÑCK¤IÞ­ÎNÎûîtÉ\·Þ¤àʵ›³g͋ŅÅù ¹S¥º2ãØáùs§¸v‹+14¢ï‹o©sfÛyâ–Å·äí®˜‘Ò°k;`§“òQaÏó9b õ‹.nqmmu&M¶\&’¸ ÄÔWg2¤ÔE$£(—/#ÍÍn6[ªÝøk”§÷ù7Œ:{@ìï{@"IóÈ%óÎýUTDj4I·.@’<5$9ntâ•ÍÛí¨%†¡ïp¿ :•‡ÃIOOgï|¢C:€Î+Î]«%öa—lÆ8ì½€ÿ®þŸuGR ÚYQråjÞ¹‹ç† ŠuŸ;‡¦iõ¿?ô5ÞL€ ¡Ðõùg]fÍDÇ“ˆù)IñvúÉŽ—Çãêêëìæ®”Ê$f³Yìï'XñäÙ£G8F~ü›/ÝÝ[ñÃ'Ÿt 1 Ñ–OßòØ@`÷×u)ërRr"Œå±‚l{ÔÕEeí[B ƒnÞÌ]üð"kkƒQ$º)•,]"ä ¹<ŸÇg÷±¤†¢(¡H$¥±D*kjjº•Ÿ_ßÐH’$à š¦!AD6–‰ÚuÿOÒˆØñó±à±—3¥N>¾T ¿ùÖkŽïTÛ3É5˜eð4¡oÍÍ>µNèš6àq’¤º¬’%Ijr¿¥Ígš·ý|(.~H€»à‹I¤܃n1 ¡!EÅE!Á!¥%ÅeåesfM¡iZ¯7ðù<м¹ÓÞ¸ÍL’¡!¡¥%%înʶ6 -²)˜’’æÛz' ˆ[ùy;vnOÿÌSO0 yw‚†¢LË—=Š¢i£uä®§rÇazÉâ…Të]‹8ü¶…B.ð ‚Ø’QôßM9–?-¶bV?MS\.ϲ)pwØ/°·ÊëZεÃãH3iß?Á!8<>ïܹ³Þ*/Ë<îˆÁvmׄ-vöïÕ MÑ]ò–¬quuY´púúï·Œ;N¥ò¾™{].W9ô6:;;Íž‘¾iËîä¤TO/ÏüÂ\©D^R\îHÛ^ÉË+œ=sQî­ ¹¢¢B}àྥÌwD* ʦLš[Xœ/•Ê*++3Ž^0ojw©¬|Kö³¼ùjYf¶iIÖŽ%v¦µt,ƒím>‡„Há·º©l…@éâ9‹›¹\¢F}Š6Ób© œ–ºën>ÓôšÀ3—ugØï$bB|‘ÈÜØd¨¨Ȥíz½ÀM ”.’à Ž'–4œÊT„…|²£ç¢i!h½2ŽUB 2Ž%‚à‚3iâ$‚Ã"»YÞ½¾Ïf³Y¥Rõi÷5š¦-;CvB8h`äŬœÌsg‡ÆUΙE3té;ï¡Î @„ësO¹Ì™)ŽŸ8&•ÒÆ$Ø÷vs8@ Ñh.g_öõõ™3g–Ÿ¿Ÿ@ 4›Mf³‰¤H£›ë’ã{î}OÔ¿ ½^à!{a÷xèÄò1ÝÎÍ·¤R4es=$B(""|Ó¦M17 ÀŸœv$`‡ÇŠ]¯Î~ÅB ëÊξ.•HüÙ»ŸŽžAÈáp¯\¹âääÝ_,kµÚ¦æ&’¢hŠ2S”€/‹Åb©D,14íçëGp8¤™dû󬲯£î?üq€ˆ]?>Íá‰ù|²;jik®«S_n©½nÔÕÀq zÃU5!n÷»I†a àÎðL¤kÜùkkQžRÚêeæû»º¨îÞ·DÓLrÒ¨C‡>rÈÏW5eÒX‘HÈápH$„РPÈÌŸ~8ãäÁC]]R“G²Éõw}ÆNPPP`qñ­gžz‚Ã$©ï¾•œƒ0 É06âô=•;Iêï¥ùÝ!´<'|Ñ„¨cYµPâ"‰ªËJžš3€Ïcçâ^vxB‘$7øëo6 ÆaC‡Éå=F Bælæ™cÇ2–=¾€$).—óíÝwT×âð;;[Y@ª”…¥HG±XA±Fʼn5š¨I|1ÍÄø3íy<>ã3ï%>cž11åʧ‰úbì/jÔ$REE0biR„e—-3¿?F·Œ¬‰ù~ìÌîÜ{gÙ3ûݹ3÷Z¦¥N/°ªªÚÑIž&¯êf•T&©¬¬òôôh}™Ñhª««ohÐ IˆÝ³wÏèQ†…†åž<©PxUW׸¸ôâ½eÛÆA¢þtpø°aÁÁ}Nççy{{Üs[~\ÉÞÞž'R~S(|‹/]:|äÐ艊¢ÚÓ*O× uº¯OÉå’c¿MT ¼u«‘eIÛm¹7ÇÙI^Pp¦¦¶Z&“š½9ö£†åÊHï\ƒJ(r÷µw­Ó¥ñÙDkµUëjÊôö´º¦ZoJ%þ¹‹É¨«¯)ìíïØX_d-d›´B¡P$Ò´P$òìBïÇ’«ŽüÖ/,,÷Éù2W—¾ý\+/÷zf˲îO=ymçþ¾‘‘E«×]¬®îYSSã>Þú5 Ãhµ:±£gYÉyeøíßå„ÂrIˆ"dì¸14-Ò4M ¹{½)B±Eî÷ÜM KKK[¾Âîœ`-´®¤iÚÓÓ“ç3CQT|l¿ôŒÜ”ÔªøÁîÓžpš<éö¤ï-hZ(‰ùå¸\.M7âžQ‰a˜¼¼<™ƒdöœ®®nR‰”a]K¹Éd¬¿UÏs5ÕŸ_Z2Œ¾¾^gÎæÇô³9Iˆ™¢â‹½=ÜF#M›ǹÏÄÈ‘£öï?pü¸}÷H;::͘1ÝdbÚ¦%ggG¯M›>gæxÅñ¶îÜ‘H$—Ë¥R©P(Ôëõ:Žf˜Û}Ó4!„ûYv ´g¯ã‡¿ìã?ÐÙ¹·T*ãßëvòðŽpëf0LÓë &“I(ŠÅb«Ç‰D,»:;;yzŽÒo4MÓb±H$up i©Têææ2errss³Édâ~v8;;999R%•JiZðøäñF£"Šd2‰\.—Hî³ó‘c4ê>7Ÿe£Qg´1)PYó’jöò#,¡6½=¼%*ÝðÜàñq1û÷ïùa×ÎfÞû¢%±L*™4q EQÜPÝ]] ^¯ollòõò8zô°ÑdŠïÓØØÔ«—¾õs¥ÑhšššÆÔ/*,#=õÀý _o•j`SS“H$äw§u[£Ñ¤ÈHO=tèWoA£ï¹-?®äà@ÿŒŒåUÒèˆ> Ã444д =­òóõRg¦V߬‘ˆEA¾F£Ñr[îÍñöò8zìÉÄ„…š½9v¹ç‘­í ïí?²±ÂF§OoýÖT´•0©-Qˆå¡šJ¹Û†è´%Fq(eb(Ê$(ÊÄ0[ó(B\ÇŽ:õÙæýú 6Ì Õ–UU•\)Q$ÆBü¦OÉÙø•˜ebƒÄÑ}ëëóOŸvyfzMM­›Åi9½^_QQ%‹œvR½Mì‡;á„}è[„/O_«   Mî7-ø]»vU¡ðãNѵD·ß.k®—^óðp3M¶2“Ñhêš™uê·”_'J$Rn†o–¹}ZÁh4;zL*OŠ7M¶†îäÆ (++Õu#G'Éd2±XBÛ¬×݈BXÃܺuë¾»>”(BÈlvièÅÞ„Uáo]¿~F¡è[[{™eÙŠŠÊÓ§ ®]/¯ºYk2Û~ÚÚüÏï,PÕ»·{ R­Pø˜}³,«×jkk‹‹/×ÖÖÙÕÊ^½z……»ººŠÅ"ªM‡º^¯¯««onÖßG‰„®®.‰¤í§³Ó÷úÅh4 z–e…B‘eVã†ð0MÅý@üCïìΞ_¿^¥yez¿öoÂ0ŒÑhÒëõZ­N§ÓéõÆÚ´Yîd­D"–H$R‘HlÙoÒéB¸_FC‘Ëå2³¯R–eõz½N×ÜÜÜÌ}H$©TÂ] ÂÿtdÛ®+¹ýÛÞóÍik»èÈÆ0Lc£F«ÕêtÍŒ.CÈ䈨R[É2Âj !”$ŽrYCÓ4wnI,óï‚N§+Ú¸ríÃÕë¬\nìä°h¾oDXŸ>Ab±HSUÿ+³rMuu&ãŒ)¾É£ÃÃCÍgIgY¶¹¹¹¡A£ÓéÌúO¤fUTÞän¼¿ÝÑr>!,ð,Ãú=;–½ïsMM]jzNeeµ]þÀÑQÖ7*,::Üꇧ©©I£ÑjµZ¦)ÿlayy×[Ê+Á2¬‰1± ëã푘+—;Èd2¹\æà`>΋Á`|j Ÿsîå$‰„B!Eµ ¾|÷+–ýfó–ukÿö§ LEEj•jöŠÂB¾Ý²­dM¾Í´DÑë 7n”Û;u9MÓ>>^Výp‡Z£Ñ`ïå#%Š„BÚòØÝ&£ÛMÐzo_¾×Åİ´=ó›’6çÿ[¾ lŽìÒzÙŠ ÍàÝP t.=²±,Û2 "w{ KËÝ£NßîëÒ´ n2õ††½Þààààèè •Þ™ÏÑd2i4Mõõ·££\.ç››µö Á²,ôŒu÷“­ŸRš6ï5n'¦©¼¼‚»ã¬=¯ç⦧§»‡‡;OŽ4MZ­–K¥ƒA¯7p£VB¸ûÚ¸N©T"“Éd2™­÷dï¾C?:~û Þ&9iâ˜öìÂCÉ2-ñõĉÅ"Å}Tcë D"ª=“ûXeùÙíŠs¾×ÅÞ¨Dî:úwN:½@è]zd£(J$ŠD–kí:„‹A¶Ft£iÚÙÙÉòd’­†Y =÷wŠ®=är‡>}‚:½X¡vrrìø½·S&'O™œÜ)Mú³¹Gpéôð‡øq‰ÜÙ´”•µ½ûÛÐ3™§¥cN¹$â´ '2OK&CQÜaž–ŒÄ¾;&:èÈ™#„áþÃ%.’{.t?\ôÞØ~c‡û oç"@73?·$¼÷\(i´rt¢c"i9þð/t?ó£MaèV.'5'IËñ‡ û™§¥ˆ ÷9ÓÀC >~Ö<2¯í+g¶ããížà!`uÔIë×póÄî‰àÃwIHñÔnkÀT²ÛÖS÷¸#÷÷˜¼În @Ïœ?€çYôÄðéhZÊÏ;5 ²Ñصó¥ØUËÄ1#6|´ÖêS#c¿øì“NmÚ=ÐÁg=ñØömßvJ«:±(€?•ަ¥5«V¼øêëB¡Ýcì&úÙ†õm׸˅{ü¡ãµ<:692º¯­Zî¯mÊëËÞ~ÿ½•&ßTÇûvïz|ÂBÈöïþ3ï©é­ëÍö¢=E€¥¥¥«WJŽý|xÚÌÙÕšN©eɲ·›Ü¥Mêz½~pÂBÈñ£Gx^–“­V%$B²33ââÛzY{ŠKö¥¥Õ+—»H©¸˜nñà¾=>âîîÁ-îø~ë èPw¹0È×ý¹gn‡£Ñ¸jÅ»AŠÞÎ’ÑIªœl5!ä/ æff¤½³l‰‹” SzóWÚ¶–{w÷æÖ¿u‹‹”â¾þ ƒ›nòèåþ=?ZVg¹U“Fóê¢ç¼]}ÜäsfL-¿QÖZ”ÕõfêëêæÌ˜êíêÐ?"øû÷r+·nù:16¦·³$È×ýõ—_ÐiµÜú‰±«W.ŸñøD¥—Ë'ëÿE7~âîvò¼?9Yê8U!D™«lk/ÚSXêй¥ÌŒ´ƒáWT”¿¼pÁ›]QP|õÐñÔQŽåÖÿõÍ7RûuëÎOž½8iòÔi“Ç×ÔÜübóÖÁ CÞÿð£:{ñjyûkfg…GF]*.ª¯«[üÆ2wwŠ¢ ΞáiÞåKÅ‘Q–륪žÈ¤(êDfîÁ#¿ E¢ôœüÔ¬¼Ç&Oµµï¶Šö¥¥¢Â ‡:˜òÛ/Üâaù{Ü!§Nælüx]á…óå7ÊvïÚɲl@`‹«ëó/¼´ìõWìÝ]Vzýô©ÜÕ+—_8Žâçï¯ÎL¯¨(¯­©áJ˜6eBzê ËJÛÖBQúø*~üï®ë-aHÒ®Ûc ”;:ZnkYK{´ÝÊÝÝã‰é3—-y57'û¹‚EÏÍë?pPlœÊÖzËÒŽý|xë–¯o”•þ{݇'³ÕsžYà篔H$‡ÿw€òû¥â¯ãiLN¶š»ŒÉŒ¿2 ª²"2ºoXxDYYilœ*(¸2 °õ}°Üw[EõÄM˜8¹¬¬ô¹BˆÜÑñðOÇ OˆQnøhí—ßl &„üýƒuϽðÒ;Ë–Ä„MŸ2áòï—Ü=<!‹—,+¼p>*ØO5àöÙŽÌôÔ›ÕÕüµp‡&‰D¢A±ñÜc“Éd«β–ö0Ûêã_ÄÆ©¦N;rh¼£“Óö]û(ŠâYoæ•×–Ø·g`TÈWŸºy뎰ðW×_l~gÙ’èåKÏÏ_üÆ2[-inn>r賞zÚê³™éi ‰C !êŒ4Ë˶Ìö‚¿(°…"„Ìf—†^ìMYþ–Zý}|ü¬ÚÚË„â©÷œU÷eK(ŠZóßÙ‘ŽëžZz ßoݶeó¾CÇzTQ™àüÅ!» !EEêøøYE­(ü'!äÛ-ÛJÖäwtæ“¥o½[YQÞÕóÄuO-=PÁ™ü¿ýýŸ=­(€?»çw3ãááùÕ–ï:¥)¼–hÕšz`Q*=·ðpCZàƒ´Ài €Ï}¦¥}»w=>a !dûwÿ™÷ÔôÖõÉ#‡~¶a}ç4  ¸Ï´”“­V%$B²33¬NWðp¸ß´”¥ŽS%Bԙ鱪Ûié/ æff¤½³l‰‹” SzwZûÆ[ÊÎÊ|ò±dBHcCÃü93Aí[Ó§L (*E}ê‹Í[¯–”LybÚ‹¯¾Þ5­ènö[Šé?05+oíúQÑé9ùï½ÿa¼*!-ûtjVžÂÏ¿‹šðÙ—–$‰2 ð\Á™±É”ç ÎŽIž  T … ²/â„)½uÍ:mS-~ýå¦&F$ÿû£?øh&·€‡’}iéXªZ«Õë"3·Y§3"1='Ÿ¦iwwîšfY¶ Ú ð`Ø×ç¯ ¨ª¬ˆŒîQVV§ î£ ”;:r/ðó÷Wg¦WT”×ÖÔtAkº›Ý#d¦§%$%„¨3Ò‡&™=»xɲ 磂ýT¢:§”Ý—f/}ë]îÁŠUk,ŸíÓ?3÷lGÐc`ž8>HK|–ø -ðAZàƒ´Ài €ÒûÒÒê•Ë]¤T\LDµ §Á¹%>öÍ|1nüD…Ÿµ §±/-Íœ=wæì¹]Ô€=q|ìKK;¾ß:sê¤7^}±‹ZÐÓØ×WTxáðOCû¨5= zâøØ—––¯\]§c³ó/tQkzœ[àƒ´Ài €Ò¤%>HK|–ø -ðAZàƒ´Ài €Ò¤%>HK|–ø -ðAZàƒ´Ài €Ò¤%>HK|–ø -ðAZàƒ´Ài €Ò¤%>Bþ§ƒótO;z&¾´T²»ÛÚÐ3¡'€•sKYYÛ»¿=“yZŠŸõ@ÚÐ3Ý•–‚÷£(êA5 'Zܯíâ]iéé—ç’—»·9=®òà#$„düõçŒÝøãùí„ïBø¦ˆIEND®B`‚snd-16.1/pix/asyfm1.png0000644000076400007640000001016611147553266013057 0ustar bilbil‰PNG  IHDRä/³¤fbKGDÿÿÿ ½§“ pHYs  šœtIME× %î¾IDATxÚíÝÙŽ¤6ÐéQýÿ/wžJ!Ä+Øàå)Ò¤ h 0×6‹~ÿ¯úk€@2d@ À¤üóóó§vþÚïm)·°X _)Ô¿¿¿~n˜(Œ•[xǧtÆ^´f™™ŽŸ@±•[Ç›rÏFëZ> ÜÂlÜÔ+²@`>Ê-LÈßÂ[Zˆ¿×®\ÿè{RåÖPuSWÍç¹i@Ê-£U¿Ç×¹’x<îRÓžnèÄþvÉ|¹ŠíyŸ¸† À+aü}ÄîøYjÚ“ë™úÛ¹ùJ. ÷‰@^¤¤ëú¹Ú2P_†ŽÁjQÖL{âœZò·sëŸk‡æÈt cÊöÉÇî g½ÕÚmŸh!Ð-tÞ¸<ë>Ètñæµà÷‰@€dº8? ÔbÚˆë\³Ž©ï¹© €æŽo};~vgÚ›ë\3_(tÚƾ'èp­§²Î=¶M—5 @ €@2 ÂM]tSr'rÍ´'×7õ·só]žQ yâƒÜ›ožaD-¸n5C,®0übè’ ô![ÈN|0w+Bat®Øž!*öÔúæþvj¾« ¦Ï¨?žÂót•[BÇÁ޽yçÞÐ>9—]Öt­¨}ßNµS0Ǻ²SU @×ÖñnÃ/»éCÛ«˜d ©·;×Kà±'x°×àüÿßÖB^¤æ`äÚiøÅØ×ßîûc7¾ç¡°`zÖî5Žº¶Z3íÉõMýí’ù®ÜȦË€î!Wúù“|g½Z¬ÿy>-d€@ d„›ºè*t·ñÕá{ÍX»üÜÔ±¯BË×B [×_øæÐŒ5Ëm[IÇ–/èâ<¡i±VèÕi­Ö¹dù©m;¶œkÖ_ @ãž%ÆC€B¹¶%¯… ƒøÊun#ÿHÐó8ë5¢ÌŽÃ6*·”Ó÷Úêù9Þãð‹W¦µP³üÖÛ6d ‡6~§ÂîÄÆŒv/·”=§=¹Î=Ö_—õ ±»´º½dÈ€@€Axu&]å†_l54c«u-Y~n¾Øö~€W‚87üâ9¤f~17_lû ¿À+J†_ MŸeøÅÔ|±í3ü"CõJëŸë’/%xÍÌïFøvÉÇZÁ¡é©Wg d(¬{© ÂM‹ù¼Þ¡sÃ7„Ï׉ÏA}ÞvŒ€^«@¬ðv»Ôù$ÔzŽ][È|礶_ ;@?×¥>}øÅóã\©í -#v®÷bºoèši(Èf~17ßyzìZ²@à¹gk¿×:€ïüí+ÛûŽ.k€@ÌÓvܧ×snÈãÊ1ã¦.Ðâ…î=¹a K‡(uøÅܺ–lƒ2]‚8×-Ÿšž)ªg…¹ÅòSÏ0ŸÿÆ÷³Ïˆ?"0g+έ¾Úc#ö’Øý/-{³j—Ÿ4"÷¼uÈgÔQa‡ùN¾Ê-5á7óM¦5c §¶ÿH—54nY??_#µœ]CàÕÖñJroæ*é ȼʽŠ1¨S7u d¸Q±ÈU6J{2·Ï¥nˆ*™Ö£5{þ,ö(WîYåiï²`½–cî!%-Ï’i½Z½5óïÝÔkA dº´‚[´J{¶ˆk—žvu=cÓtYÀ2d@ À ÜÔ@7%wWŸçysøÅÒu¾³ž±iû>Ö`0ü"4:Áè™¶­è·ájë] OxR×µ{)ÀŸÿ…ÐñÿG~±fù©m8ö~•¾eÙ@îÕÚ¶ý÷Ó•ïú]`Ž–néô·†_¬ýÛ†_ì\óI½YÆ5¿òp̽¡çZ/ÀȦ äÞ5#¡;F¥@ Oε'v]Õcÿ>ö? jy….ª—„…“þsÁ™Úÿ«ôPèij~ñâ‰v´ð~b½î.¿ÅúͰÀ¿eéXvcÓÎÓg~1u¾ˆ-'µ|Ï!³l¥ V´Y+‡çÇ}BC†ÞruuZëuÎ-¿æ™äó²bËÿŒò£­r`{™Ý[Bp¢P%ùxŽ»<¤È@7uÐEÍð‹ÇyV~1öR”ØwþŽøžÿ[Õ(]©ºtQn鯥Ã/– Q8Ëð‹±2Û'õcµ ¡|íà¶*<Ê-o±ûUJFE:75­õ±œZ~É:†¾›Ú'®!+0¶x¼ìíØ`Èm¯kÈt•ë®Þ±òÚ'ZÈ<Ú:ì}-xÖ³@ kK°ä:±}"x8xì“ð>ÈO¸¤JýûδÖë}uøÅ«ûÄM]<̽†/¼«Åð‹±°N½ÜD OÂð}À¬ç®«ÓW~1·îº¬áfí_e hA €@2d@ €@2d@ €@2d f¸ÑžŒ% óQn×þm  ²i ‡~x…ƦÜÂ}º¬ÕTÈ*Ì @ 2 öûûëqÌ(Üñy­c¿+O¶ È  ™‘x”iLîÈ2d@ €@2d —Ïh+äñ˜r»îïú}ìÒ#~rèGWØalÊ-ܧË.„°a…Ö/™†­@… d´¤Û·jì;ÎŽ76­´=d@ CÛV5€@ ÀSf¸†íÎr¼Uì9?uûÌþ2€È  ИëÈd–ªØTC \È€@Öný’§‹Y lJ=ºËgë‚Whȵ;ñççÇŽ‡N~5åpær;ÛÍE©u …lÉvͲý²áÿ>=Ãø{0¹Þ ¨Òrأܾuâ­­„ܯ4j?ùØüŒúÔ—ò,õ=¯ d¤c5õÝQÕ†vd¥åãοG?6—ê²>ïÈïûzÏ'4'ƒºJŠÊË{aæXÝ󨨽ÌízÜVúsµ­oW¶ܽš+í+>¡žǪŠÚŽ¿ÿΕ‘e¹¶{B $¾?ÎûóÊÇÏB½‚¼þX=ïÃóþw¬:NRe1õyª¬†Ž³«7µü^çr<@p”üè±Ï[0;Ĺ ‡¾sîuhU WªäÜÙ³îK7nÝÛo¡ß:ÔrŽ•·T%9×*OµÒ{—ó'ŽñÑÍ!¹f¸s`[Zkï¶¶wØç;«†vì³?s ‰=R±å”þ®­§Ðz„ŽÚÏG?6?#œ¥?ü•¡!žûÝvÜæ]ŽUC;ÎYÞr÷Ü\iÙ¦zËZlO‹25ú±ùqH“ª%¦ºÑjj¸@¿òšêq‰•ïпK+‡¹–¬²±rã]Ö Ÿä Ha|Wg Œµ-dÄ?¡ ¹­˜õIEND®B`‚snd-16.1/pix/errorwave.png0000644000076400007640000000373711147553266013701 0ustar bilbil‰PNG  IHDR-”_³æsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ 2¿¹Cn_IDATxÚíÝÙ–›:@¸ËÿÿËÜ'²£#°ÐPõ’vÇC[`ië̼,Ë2Tî?M-B ´-B ´Ôižçižg[„¡@h„¡@h„¡Z„¡Z„€˜Oôë•—eɾÿöªÌ©Ï-¡À²†ŒíÏ‘ûï—ò<ŸÒ/ (ÛŠ ´h¿·Ð>“&@·¡eß~ëðR:CÁ†Úø^*‹gïGµ(åµqutŒXÖÛ-í£÷cò4ZÖÙ–ÀçüQ¨i)„½Ÿe ”ÐòÐv–˜ÒQݽí "zuHZ¯¶¼Ö¿.'†è)ØPbŸL9³®•ý6µ2ª‚ üš/—ƒ´2¸«B T>PçÖ‘jC+ËD¿XwÚZ`xŽ;‰WYrÚl»L&¸B ѳKNŒŽJ,c•lo@h.|Pi‰ðÐÛ·B ¨ï|\îÙ3µV[JWY„ Þî„7-À`T@¡ +u:íÝ/V­Âp·½Öíª*B t50¦‚«këŒ28>ñ­¶¥ÚËÅAh^âxŽx;XÆ¡T m3ÛZ ¡ÙûÈg‰0ðtèP¡¡ªži—¤¾ Œfþmì3€Ð] h£‡Žž«ëß!¸@û>fG´:¸ž ´­‡uÀ9HµÁÝoPAhùiÇ%Ø ” ‚­¾Vʶuì ´Ïò×àÀXòýÒö>-t>ÈÔ"J$ÊOß° B „gÅ޼w§Í[Ú?Zos@hÁ`}{¦]Û@ªÚRnÛl/ù-<ÀDŽ»!däc~ýÞ[®š©¶€Ð‚`’=¤°½…ž–Ë¢Ûæ­÷þíotÜ - ^„Ûà­m³¿_$B ƒ•È1Èý}[8~#¿Íì› ´0x A{·ÐfÚ„:éØSÖüUQòfø#·Y4hÝ f9íºÿB  *g³ÐÚÎRyê:4-V, ¨å÷@h¡ÒjÀ›UÞ—=žj×’mT{…èîkÚÿaM@îLý‰ÁïÛ ±íüÍ`ï´o¤O†ƒÒ!é‰0üôçF¥ÒB¸óÞwºß:õ³ÿky6úæß~wÀ3`¦oÃÔí|jöÁ[„'W^uèJä¿ßF¥«¤ïãûÿûvæ‘xAháæ`¸Ÿôê,#ÁŶkïó-$Îð|E,<Ô\FkÙwcjFþå@\³»¿:ÆÈ)Ëkç+ܼ70;u»§ƒ˜ß¼’ö¯^ûj»¥lcÞï;÷A4çrÑǧ<öÛÏBËwžo¿íŽY›rPˆ|¸#@dÀï)¸ÔZqèýø¦”³ßrÚj_Iý<óûqe¶¡25@¬ÙOsžë*øœý\ó„â´í—Æ÷öèg¥ÙýLæ[¢>›Åžý.å>‘ߥvd:30õ¹ýÏÕ™ƒ9ýdîí;X¿Ø^aáÏöï%´¤–Y¯nGCÎÙcRBÆÙT]Íš}ç3¨\õ9wú²³€‘Ú·æN>õýïÃ…ÞžCËÏIù)!$Ú ”8¹“¬Ô~2µ*ÿì§B Ч<B €Ð-B €Ð-B €Ð-B €Ð-B ´-w|jþãæy¶…€úC˲,‚ 0M“å!@hZ¡@hZ¡@hZ¡@hZ¡@h„¡@hð‰>`žçiš¦iY–ìû¯¿‹< ´„Ë2¶?Gî¿\Êó|J¿`$ l+2€Ðr~U ¹ª²¤¼®`ƒ†–RK5–…€ˆGΚç9TñX€¨Ð1-ë´ëÏ9÷_o;ƒˆ˜—ÆCôl M¾\Z„@hZ„@hZ„@hZþøôòF"W™Ú±^_P¥hBó•–”«;Ïó\ì*Ð¥^«Ç÷¤ý¼–öóžl+í÷J СZž2/¥µxvÃ\ôP•@hZ€¡8¦h‚J ´<å£ ê°^ð1uµîìþûÓ.$iEôG§Boû ýB §ÊÚA¤|§ÂÙýSŠ«aƒ¾â¨8šð.ÔÆòPG"´VYˆþù}ÔJ¥0ø2-Ëby¡…zf«:!ZÜo·ÿ¯uö»oÇwù,\÷ú jdy¨òNDù›Ñgÿë¿ûôl@Ý–mèYŸc_QÐW@;TZ*é˜#gœÝßAÓ?Ÿ}Åq_ay¡…ðŒ2e&ùÔýaôϘ¾B?A[,ÍxªZb)Ú¤ÒT-g9ôè¶¥è`â₉@ ,Mø?_Š«¨ÛIEND®B`‚snd-16.1/pix/fejer.png0000644000076400007640000003172511147553266012756 0ustar bilbil‰PNG  IHDR@¨‘ð7ñbKGDÿÿÿ ½§“ pHYs  šœtIME× 3}hY IDATxÚíÝy\éÿøñW»TŠHŠd7aô±ïëØ'[–Á±ocgì;Ÿf,ÉÄX"ËÈ6 Ù²$;“,%k¢&´(•´×9ç÷G¿î¯# ©Dçz>9÷r]×}Ÿ«w÷r-J¥R‰ ‚Ò§@ADü?ÉÉÉÄÇÇç¸>&&†—/_г(䛨ØXÒÒÒr\Æëׯʼn >Κ5 77·®‹ŽŽÆÉɉ­[·âëë+ΤgqqqôíÛ—§OŸ~pý;wpvvfýúõDDDˆ&ä™ö¿­lÚ´)ÉÉÉ\…ŽŽmÛ¶åÆ4lØPZ·fÍüüü²íãççÇ’%KèÓ§Ï?Ћ/2fÌ?~¬¶_ö¤I“˜3g–––_eù ¨S§NŽëoß¾M«V­¸sçááᘛ›KëÆŒCRR’Êö©©©Ü½{—“'OR¥JñÛ.ä.š››œëDg̘ñÁå¼yó¦PôÒ¥K©í}åÊŠ/ΦM›X¶lÙWYFJ—.ýYû:;;g[LåÊ•ÿõ–Z·À9 àþýû( RRR033ãòåËÒ_k¹\N`` VVV_ý>zôˆ5j¨ííïïOݺu¿ê2&''óäÉîÞ½ ÀåË—133#%%€òåËóìÙ3RSSÕú™ð… ……¶¶¶(•JtttX³f ÕªUÀÊÊŠîÝ»S¶lYìììÄ™òL.—Ó®]; ¨V­kÖ¬AGG€N:aeeE§N¨Zµª8a…hýúõ :”É“'Ñ|‡Š¿¿¶åû÷ïgèС :”ôôtÒÓÓ¥Ïû÷ïÀÝÝ]Z&=.Q~AåÊ•SnÛ¶MY¨”ËåJ™L¦TG6lPîÙ³G9þ|µ9ægÏž)僔Bþyþü¹²U«VÊŒŒ e¯^½”wîÜ)ð<ïܹ£4hPž8qBe]LLŒ²[·nÊ/^(GŒ¡ôööVz{{+GŒ¡|ñâ…²[·nÊe¯^½”AAAÊñãÇ+Ož<©T*•Jµj¨©©‰B¡P»¿Ö <þœš5kŠK!ÏnܸÁ7ÐÒÒâÍ›7¸ººxž¶¶¶9æ‰'ÐÔÔDCCƒ 6°aÃ444ÐÔÔäĉ\½z•Ç«lóÑ[`¡hÈÈÈ !!’%KŠ“!Ÿú PA@A„ÿ¯FÒãCCC~øá‡B)G\\Ë—/G[[›&MšHË{öìIÏž=¥ÏMš4¡V­Z´hÑBZÖ£GÕMùòåÑÓÓ˱§… |ŠZµjÑ¡Cd2ššštîܹÀóôóóC&“Q¯^=œÙµkIII:tCCCúõëÇ´iÓ¦_¿~ôë×àà`¦M›F¿~ý¨[·. `Μ9³°°ÈÖÿÿÖ­[X[[KõíÅ‹¼xñ€ôôti€‹Ï™«ô5jD@@îîîR™ç̙þ}ûHJJâÇ·À‚ |ûªU«ÆØ±c;v,'NœÀÔÔ4Çm 7oÞ$,,L@A¾}†††lÞ¼™*UªP¯^=éÈ»^¿~Ío¿ýF·nÝØ³g!!!" ‚{oÞ¼‘nAŸ>}JXX+W®$<<œ   æÏŸO×®]éÖ­›4tÕ¼yóò”gË–-³¥÷òåKêÔ©Ãýû÷™={6çÏŸgÔ¨Qhkk‹/HOOÇßߟˆˆÖ­[‡L&ãÂ… ”+WN@uÔ®]»l DÕ;}ûDEȃÈÈH.^¼ÈªU«ˆ‹‹#00zõêQ±bE"##±··ÇÄÄ„Ÿþ™3gÎЩS§‘ËåxxxP¬X1ºvíÊÛ·o9{ö,Ùo·råÊøúúòüùstttòeÚŒK/ €'Ož™#½hiiÂíÛ·©V­š4ÛàéÓ§ILLÄÎÎ.³o|Qÿ¢ hhhˆZ+ùüÖ®]‹L&£oß¾ìÚµ‹gÏžqðàA?~ÌÑ£G‘Ëå888°nÝ:©Ar^òÌ)½àà`ìíí‰eãÆ¬^½šÄÄDd2ƒ ÂÞÞž§OŸ²oß> DÿþýY¾|9 ^‚‚Kþþþ´oßž¤¤$š4iB@@ǧV­Z´nÝšiÓ¦qàÀ8@ïÞ½)V¬ØGkÉÓ§Oç˜^\\Ož<¡xñâX[[ãëë˾}û¸rå Ïž=ãÉ“'<~ü˜%JÍØ±cñõõU[`uçååUhV ES½zõHJJ"##£Ð/U«V~ýú1aŠ+ÆñãÇ¥2ÆÆÆbhhˆ••µk×f„ xxx°eËq¨^½zEÙ²eʼnòUFFC‡¥zõê,\¸°PË’˜˜HDD  téÒ<{ö È|.8pà@öíÛGíÚµ˜5kfffRciµ €ÆÆÆbPAȃøøx&MšDÏž=9r$T¨PAZoaa±±1&&&hiiI ?—‘‘Q¶ôÒÒÒ¸wïÁÁÁ\ºt‰ ШQ#öíÛÇÓ§OYµjóæÍÃÚÚš`kkKDD[¶l‘æžV»Ø­[7Nœ8!j± |&///6oÞŒL&£iÓ¦¬Y³†ß~û3gΰyófæÍ›G·nÝèÚµ+sçÎ%,,Œùóçç)Ï–-[fK/«'HJJ -[¶ä×_åæÍ›ôïߟY³fáêêJÿþý©S§/_¾¤T©RØÛÛóóÏ?Kƒ!ˆá°„"E ‡UðºtéBhh¨ÊÕ™4òSÖô«NNN$%%1qâÄ|É÷ýô*T¨@hh(æææ=z”·oß2sæLÊ—/O»víX·n´oÙ²eiÔ¨ñññXZZ|Ãa _š«àéëë«Üòfy™©©é¿ŽÌ’[ï§§­­-åibb"Ý"CæÔïÓÕÕÍöÂF¼QC“'OÆÉÉIœAí‰f0jHWW7Ï Sõ¥P(pppÀßß6nÜÈ‹/˜3gššš 8.]ºàääÄÍ›7ÑÕÕeëÖ­hiiå)Ϝқ>}:‘‘‘@æÛé]»váääÄ;w˜5k¶¶¶(•JöîÝˉ'4hݺuW€‚ äÞ‘#G8wî®®®XXX0{öl†ÎÀYºt)3gÎdÿþý>|WWWjÔ¨Á”)Sò”ç©S§rL¯F¸ºº²zõj*W®,•oܸqŒ9Èœ³díÚµLž<™™3gJï#Š|»¸¸P¢D óJ¯^½X±biii+VLÜ »<==‰‰‰'âèèèààà@³fÍptt,ôò8::ª4¹ !**Jj ‰ŽŽÛ¶mC[[›äädAȽû÷ï³dÉ ³ÝåË—/‰ŠŠâÂ… „††âããÀ_ý¥ò3¯ÞO/66///ˆ§fÍšRùzõêÅœ9s€Ìç‡Ù€;((Hê*§·À‚ ä¯J•*L&#%%gggž={Æ’%KÐ××g̘1ôèÑ???d2 ¸¸¸ä)϶mÛrá•ôRRRÆÊÊŠêÕ«chh@tt4†††Èd2är9Í›7§}ûötíÚ•Å‹3fÌéÖX@Ar¥xñâ¬]»VeY©R¥8~ü¸Ê²U«Vå[žúúúLoôèÑT¯^]ZÖºuk._¾œmÛ™3g2sæL•ejy ¼fÍf̘!j²ðIâââD})¢Ôò P__Ÿ””ñí ŸLÔ—S(hjf^GÉåòÌ«*MM444P((•J€<5‚~7¯KO©T¢P(ÐÒÒúà¶Y˲ʧ¶W€‚ ä]PP:tÀÙÙ™ `ggǰaæE‹Œ1nܸ‘§¼^¾|ùÑôþ÷¿ÿѲeKž>}J³fÍ1bµk׿֭[¼yó†^½zѶm[† FZZZÁ@¹\NTT”ôO¡PˆZó…ݸqƒF©,«R¥ 111E²ÉGjjªTßD“–‚£T*9wîAAAœ›;w.åÊ•£J•*L™2…BAŸ>}¨P¡ …‚zõê±víZ^¿~ÍÙ³gÙ°aCžò³±±aÑ¢E*é………áâ₽½=S¦L¡yóæŒ===½–O__¿à`rr²ÊÐÔEqôáëN@@â„­[·’ššŠ‰‰ “'OF&“`hhˆ¾¾>çÏŸ'%%…… bjjš§ü¬­­³¥'—Ë™;w.zzz¸»»£««+Miú±òeÝh”Ëå*•PŒøõ0`û÷ïW™J°(HII‘ê\TT”ø¢ Èû#;iiiekSkdd$u9Ëï§§¥¥…@¶¼?¥| 2dˆô9kš:¡ðÕ¯_?ÛÄ6EA¥J•¨T©ùŒNÌå!üµmÓ­[7Nœ8!j€ |¦´´4æÎËÞ½{ ¤oß¾ 0wwwÒÓÓùõ×_‘ÉdÈd2i"òÏ•‘‘ñÑôþþûoΞ=+•ÍÎÎŽ=z°wï^\]]±³³£_¿~$&&ªw´¶¶&$$DÔbAø r¹œÕ«W0pà@ÆÇÈ‘#Y¾|9K–,ÁÍÍ ooo\]]©_¿~¶é(sëÌ™3M¯wïÞ„††™cZYYaccÃÀ‰%((+++&L˜ Ý:‹†ÐEÔõë×iÚ´©8BXºt)7füøñ@fÃèÎ;S¹reZ·n ÀðáÃU~æUN饥¥±bÅ &L˜ -Û±c/^¼ M›6@æ ±#GŽ––¦ÒnSÀ"*66–R¥J‰!ä»GqôèQ.\¸@·nÝðòò*ÔòÜ¿ŸóçÏS»vmiYß¾}Y´h3gÎÄËˋҥK³nÝ: ‘ÉdÒ4§" ‚+<`äÈ‘,[¶Œ;vpêÔ©B-ÏüÁìÙ³‰ˆˆ 44…BAß¾}©_¿¾T¾2eÊЦMV¬X‘‘‘€4nÜ8Ïóµ êéÂ… *?_½z…——!!!\½z@ꆙ_Ý1ßO/&&OOOZ´hÁÝ»wñóóãÑ£G( i›[·naggGdd$^^^DFFR³fÍ/ÓúkW¥Jž>}J•*UÔòøk×®M@@@¶yƒ…O÷Ë/¿ “ÉÔªËe×®]¹yó&2™ …BÁ–-[ aÑ¢Eèêê2}útz÷îÍãÇ‘Éd¤¥¥±mÛ¶<åÙ¾}{|||TÒËê—õLÐÏÏððp´µµyúô)2™Œ &дiSBCCùã?¨U«óæÍû2 ¡ Ó±cÇøñÇÿu›áÇãââ²eËÄo²ðYâããQ*•juÌÅŠcÅŠ*ËêÔ©ÃáÇU–-]º4ßòÔÓÓË–^‰%T^ˆØÚÚbkk À¢E‹T¶µ²²ÊV¾"s üòåKÜÜܸyó¦´Ìßß_š¹êSøûûãææFppð7yΞ=+ˆ *MPý)är9nnn;vLD5Am‰xõêUüýý9þ¼Ô4·vïÞMbb"›6m"--í›:~æÎË¡C‡xþü99?j‹-þu?---©{âªU«Øµk«W¯fçÎâ7CÈQFF Ò¿´´4 …ô9==Èì–˜ 5:ΫœÒûPÞY’““U~Ÿår¹Ê6ßT|ûö-[¶lÁÝÝ=[X¶l¥J•ú¬þŸÑÑÑ/^œ^½zQ§NΟ?/­KJJbË–-DGGçàâÅ‹Rk÷¬òݽ{—Ç3þü\u7lݺ5>>><|ø¤¤$Ž?θwïž´Mdd$[¶lÁÓÓSüæ =z”Þ½{3cÆ ÆϼyóØ´iíÚµC&“1dÈ‚‚‚hݺ53fÌ Aƒ\¹r%Oy†††æ˜ÞÚµkéС `äȑҤç=¢yóæ=zTÚö×_ÅÙÙYúüÅŸÆÄÄHW)+V¬ÀÚÚšJËvîÜÉÇÑÔÔTÌÐÑÑ‘ŒŒ üýý‰ŽŽ¦k×®lݺ•Ù³g™ÝÛ~ûí7ž###5j$M3}út:t耮®.vvvlܸ‘ÿýïXYYQ¡B ³5üöíÛsÕÐËËKjjjjеµ5>>>XXX°`Á*V¬ˆ¡¡!ÇŽ“ž±\¿~£Gϼyó°´´”Ò>|8&L W¯^"ZA­Zµ¢U«V”.]š… 2|øpf̘ÁÁƒ111aذaܸqƒN:ñßÿþ—¿ÿþWW×Þ‘ü›{÷îå˜ÞƒpssCGG‡ñãÇ“‘‘ATTdãÆÒT˜oÞ¼ÁÝÝQ£Fltss“/|WBB.\ &&FZfbbB\\\¶IS\\\Ð××gîܹҲ©S§beeEXXëׯ—ö±±±2[£×®]›§OŸbgg÷ÑrV¨PvíÚqïÞ=&Mš$-oÞ¼9®®®øúú2jÔ(ªT©Â«W¯ptt”ò¬Q£®®®øùùe+{ÿþýs= Ìû4;––-[²jÕ*)­Ž;J_ž¶¶67nÄÚÚšyóæIû5lØM›6±jÕªOÊ·K—.ܼy“víڙËOœ8‘õë×ƺuë(Y²¤سÊÒ´iS\]]9þ<*i6lØ;wîJ¼ÿ¾ôóÝz&äŸÒ¥K™ÏÍŒŒ¨\¹2úúúÒ3ç¬18kÖ¬©ò3¯rJoûöíx{{síÚ5ix¬©S§bkk‹¯¯/Mš4áõë×ôíÛ—™3g[°°Q£F|÷ÝwÙ–;88лwoFŽùÉi}h8k ‹‡¹~7ºжmÛÒ¶m[•eµjÕÊ–¾™™Ùó|÷ÍÓûËóCNÇ9hР.·²²ÊÕåöööØÛÛg[þî„wûûW¶:…ÉÒÒRzûÿòåK©¿ª¿ —.]’ºš6’““yôè111±`ÁV¬XAjj* 4 }ûöXZZªÀyX±bEj×®íŸŽŽŽ¨9B211‘ê[Öܯ…aß¾}Eú<§¥¥áïïÿÕ´!577§[·n\¸pèèhæÍ›GíÚµqpp ""‚åË—óæÍ¶nÝÊ‘#G¤ÑdĤH‚PŽ?΀Šìñ͘1ƒ5kÖHŸutt˜:u*666\»vž={2iÒ$,,,pppà‡~ÈS~¦¦¦LŸ>]%½çÏŸ³oß>BBB000ÀÚÚš;wîðÓO?1mÚ4J•*ÅÊ•+éÑ£³gÏ&==›7orïÞ½¢ßZ„‚Ó§Oi¸yÈœ%îàÁƒ@æ¸{666lÚ´‰   úõëÇàÁƒó”_ãÆ³¥÷öí[Ú·oµµµÔÈyïÞ½Ô¨QGGG‚‚‚|Xꤧ§G³fÍØ¾};ŽŽŽRaµòâÅ ©ß´ðù¶mÛÆÅ‹±··—¦,L'OždĈôîÝȱÆÏφ P¹re-ZÄŸþ‰››oß¾P„Ï£P(T#$''J||¥RÉŽ;D„wEFF¢££“«¹TÔYÖ¨,Y?ÍÌÌøá‡°¶¶¦yóæÀÿZžÓè幕Sz–––888`dd$-377çï¿ÿ¦iÓ¦”-[–­[·òÃ?dF@Aø}}}Ê”)ChhhæãææöMœ\\\X°`ǧsçÎ_]›4i‚©©)ãÆ£N:X[[°aÃ7n,  |*===J—.Í‹/ 4Ÿ#GŽ|ç£fÍšœ9s;;;Z´h‘çÑž ÂñãÇ™?>®®®xyy‘œœ,MjÖ AAø|;vŒùóçÁ©S§¤ÆÈ€ô¬íÝgnyñ~z¯_¿–f|_FF®®®?~€Å‹“””„ ^„ˆž ‚ 䊯¯/^^^ìܹSjT¼iÓ&æÏŸ¶¶6K–,¡{÷îüóÏ?Èd2€<÷騱#þþþ*éÅÇÇóæÍBBBX°`ÉÉÉÈd2vìØ³³3#FŒ D‰lÚ´‰9sæàçç‡Lc™nݺ‰(Bî5lب,«^½z¶g˜ùùFýCoèõõõ¥€èêêª²ÎØØwwwésÖP]ï·À‚ ¨-q(ÂgIIIAKK är9111@f9}}}Þ¾}KJJ ššš˜šš~p›Üx?½,ÒdçFFF+VŒøøxRSS³mûöí[•æ2" ‚k'NœÀÕÕ•Ñ£GÓ®];œœœpss£B… Èår–-[†L&£E‹œ={– 6ðèÑ#vîÜIÕªUILLdÏž=ŸoÚ´Iü† ªråÊR{þü9NNN⤨™Ž;âããƒL&ãîÝ»œ?>Çm 4êèèHQ†¡„‚ü£›5î[ÖÔ‡‚úÕßÿëׯsëÖ-•— ï5D„\»}û6ܸqƒG¡¯¯ÏرcqrrâúõëXXX°dÉ<==éׯ666”,Y’#F°iÓ&Î;‡žžÞ'çW¦L™léýóÏ?,_¾MMM&MšÄš5kð÷÷'**Š®]»rûömÆŽ @BBžžž„……áéé) –+.ÉAȵ„„iƵ¤¤$¤ngûöí£zõêìØ±ƒFMß¾}IHHÀÃÀ½{÷æjä† ~0½ü‘qãÆáéé Àþýû2d?ýô“´VœQ£F#N/  ¹ÖªU«lËÞ¦ªyóæÒÐXY·¦yëCéÕ­[÷ƒy¿ü ³gȇò·À‚ ¨-AP„üÂÎ;óœÎëׯY¿~½8¡" ·áúõëØÚÚòòåË<§•––Æþýû‰ˆˆ'V@AøºX[[g›~óÚµk*ëóêÚµk„‡‡‹“-  |],XÀ²eËĉøF‰f0‚ð={MMMºví*N†€‚ ^ÒÒÒÄI·À‚ Eü 0**ŠiÓ¦IŸ zx"A¸ví7n2»k B¡À2eʨLV’5^˜ ”f͚ѬY3‚ƒƒ¥¾§ßBàΚªQ·À‚ V:„B¡W­" ‚zêß¿¶é&Aø€Y³f‰“   ¨§üèj'  ‚€‚ " ‚ ˆ(‚   ‚€‚ |Iqqq˜˜˜ˆ!  ¨ŸeË–qôèQ|||ÄÉPÔOË–-¹|ù²8" ‚ ä1–P¤ˆá°„¯&Šá°„/í[+?…††òèÑ#:vì(*„¸„¢çôéÓtîÜ™áÇg[÷úõkÄIPŠ&¹\Ž–––˜cD@AADAPÔTDDâDˆ(ŸÏÏÏ[[ÛoªÌ—/_ÆÇLJ¨¨(ñŠ(ŸïÁƒÔªUë›*³5_ž€‚ " ‚ ˆ(_¥R‰†††8_[ çÉ“'9®¿}û6'NœgQÈ7þþþ=z4Çõ§NÂ××÷«?ccc222>i@???ÌÍÍ177à û×Á&MšD—.]¨V­Z¶u¡¡¡?~œŠ+âááA=¤u±±±ì¢#—ˉ'22Rœy5P¶lÙ\mÁ¡C‡¨^½:nnnôíÛWe½§§'áááܾ}›’%KRµjUiÝ«W¯P*•*ÛGGG0räHŠ/ÀÇ;v,[¶l‘FHJJ¢uëÖðÃ?¨”iîܹÄÇÇ3eÊŒU®Ü"##¹|ù²Ê>¡¡¡lܸ‘¸¸8:wîL±bÅTcRR’Êöoß¾¥K—.ÄÆÆâààÀ¾}û¤u/_¾$22’gÏž©ìóúõkF···Êr€ÄÄDŒéß¿?ºººjY÷¦NJ«V­(Q¢Ä§@???¼½½033C&“1~üx‚ƒƒ?¸cbb"ZZZT«V;wswwçáÇÜç—_~á—_~Ñ¡ˆ+V¬ÉÉɹÚ'99¹\ŽTßF¥J•ˆåíÛ·*뜜œ²åÀõë×U–çô†ôýí²Èd²ËœuÕöüùs•å:tÈձ߸qCúÿû¿;9]N˜0A Òïûûï¿Õºþ;wŽ‘#G²mÛ¶O €–––´iÓ@úkùþsŠGaee…Á¿&:jÔ¨.6léééÙþJ»ºº2uêÔO>¸GqóæÍ­˜ï»zõ*ñññtéÒå“÷ñððÀ‚† ~ò>...´k׎J•*}ò>+W®düøñ}ò> ,`Ù²e¹ª_jMͼ?^NLL$44”š5k~ôهʌR©düøñ_ü088oooFŽY(`ݺuÈd2J—.](ùn½ÉϼMMM?ý¸L™2”)SFe¥››ÏŸ?gèСddd`ccùsçh×®eÊ”!==S§Nѽ{÷O*X:u²- ÇÌÌŒzõê}òjhhž«}"""ˆ‹‹ËÕ>wîÜ¡R¥J¹ÚÇÓÓ¾ûî»OÞ§L™2Ô­[7W“ß”,Y2Wåú’û|®’%K¢££ÃáÇéÚµ+>>>´oßžäädŠ+Fýúõ9tèššš”+Wî“Ò477ÿbå—¾¾>=*”¼³îâêÔ©óÉç© ¾ËÂ:öÜäý¯ÏçÍ›' »£¥¥Epp°t9^ºti¦L™BJJJžN²®®.ÖÖÖ¹ÚÇÀÀà‹ ®Z¶lY•g>Ÿ¢|ùòèëëçjŸÊ•+£¥¥•«}ªW¯þE*Ó—ÊÀÄÄ„)S¦””„……)))£§§€­­-æææèêêRªT©¯úL__ŸòåË«í-è—¬7y¡¡|ÿÉquòäIâââ8p ÚVÊAƒ±gϵ9Þàà`\\\ íV¬0͘1ƒéÓ§Úà·RÏE;@AÔ–Ö’%K–¨Ã`ii©Ö“L[XXP¡Bµ9^]]],--sݧ(033£|ùòèèèˆz.nAÔàøùóçÈd²'…9}ú4£G&!!gÏž!“ɘ3gN®Û¬}­ÒÓÓÙ¼y3+V¬ 555Ûú¤¤$¦OŸŽ››÷îÝC&“!“ÉèÓ§Ï7}Üiii8::âèèøÁFø‰‰‰Œ?žãÇ#þæý¿¿Ó§O')))[}NMMeÅŠlÞ¼™ôôt•ú¬P(rŠ\œ3g®®®üöÛo\ÿ矲zõjæÌ™ÃÕ«Wquu¥ÿþ*½òË©S§¤ÿgddàååUàÇïëë‹\.ÇÖÖww÷lë5j>>>˜ššâêêÊ’%K¾¹!ŸÞçååEÙ²e)[¶ìÏóâÅ‹Y¸p!GŽùà†oÅŽ;ð÷÷/²ðÂ… ¸ºº2jÔ(³Õgwwwlmm‘ËåøúúªÔçõ0ûX~~~9ƃ÷‰·ÀhÆ <~ü˜µkײ}ûvœœœ8|ø0ÇŽ£\¹róàÁÆŒÃáÇ‘Ëå¬_¿^œ8áƒ,XÀÈ‘#©T©R¶†ýìÞ½›äädæÏŸÏÓ§O9xð ¼zõŠ!C†pêÔ)ŒIIIáûï¿Ç××—Ê•+3mÚ4©ñðÞ½{Ñ××çþýûDFFbjjÊ”)Sxðà'OždРAØØØ™s*`JOOçíÛ·”,Y’ÄÄDÒÒÒ022B.—£©©‰\.G¡P```@\\ …â«ïâ%žäädôôôÐÔÔ$==¥R©2ÜU||<£¥¥%Õ©I“&áêêJll,†††ddd §§Ç›7oÐÖÖ¦D‰$&&b``@ZZ( Ñ××'==õë×3lØ0,--‹Ô9PЏ«W¯Ò¼yóÏÞ?&&†ÈÈÈ\ ðñ­øŠ×l¿µH¦IEND®B`‚snd-16.1/pix/repenv.png0000644000076400007640000000104211147553270013142 0ustar bilbil‰PNG  IHDR~FñJmËPLTEÿÿÿUÂÓ~bKGDˆH pHYs``zxEtIMEÔ2ŠéÛ®¢IDATxœí–Krƒ0 @8 ‹4ö<‘ÓÒõ­Ó“qŽÀ2‹N]c#ÙÆ$í¢‹NÍ0(’ž>(ƒ¸Ë­Hãocº™GÚë}˜~ð/43{í9¨À€];µ0CIfnLï41ŒMïn,Cæµzè©ïÑÀ~Hê¤Lãa«Ñè€óPÄÑ6p?Tt”j Š‚ÚÐ Î*ŠÎ®¬ ÊŠ aÉ"zxH|š,4’,â0Uh/É"ä`9,bkwW )&YD50 @XDeì¿}çT¦‹*„E8`M€ŠUÔ†Zj²ëˆ3\âE¬'€Т#H¼yxŒÛø ú¶ÞÖ!Ðäì°¤¾b½'ª>kà ¾lŠ=Å€Íì—x°ôp=pZ€»AªÈó†ïÂ(ñ #Qú7ŸoªC­Yª@rÆó¹l¶²ý£ ×ÜäSºÈÝõR2¡ÚV«öÈj¡´÷HçAãÑÁøy–ÉtJl–=ã1åŽà1ï˜:{ä…7#ß<o;“Ñd.IEND®B`‚snd-16.1/pix/intro.png0000644000076400007640000005500211147553267013011 0ustar bilbil‰PNG  IHDRTÕ |sRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ *£K£Fõ©Z5ø+·víŒF£t]¿~]BC«Y¥‰Ž>KÕªÁØÚÚ…èè³¼úêË\ö¹sðÃÁÁ€£GÓ´i#"#O“““K‹Ï?´…£GàîîFÛ¶­î+Ÿ¿þ:ˆ»»+Ï$,ìC®°o_×®]§M›°~ýf+á¿iÓ6«x_z–ß_ŽÁ` $¤ þÔ¨QÝê9ÝÜ\©[·6û÷’Â222ñðp/”‡J¥bäÈ!w-“XÚÝÇÇKú!¨R%>(¾TÁcÁÝò#2ò4»ví%33‹?ÿÜÌùó8p ‚û–˜Çot•–wíÚû`µ"èׯ—´)òùçWX¾¹¹y\º[æôYYÙ¤¦¦š®GýúÏyŠK—âJÝdkÕª9Ç’®]\œ‰ˆ8BFF&ŽŽŽœ>}¶Bž9**š.]:–š¦^½g*¤¼—_n'µWdäiÂ×ÖK|­‚Ç–nÝ:ß5†»»[±ioÜHâæÍ¼¼<Ê”w‰U¡P “ÉŠ(ä&£F}ÃáÃö¡ô+ð矛ùå—ùdddb4”®{õêA£FõùùçÙlذ{{; #`©cX؇R&Mú/úôy—°°qrrdÈenø5ª±iÓ6ú÷ï#…%$\e̘ñ>ü7 eΜŸñõõÁÖVÃ'ŸŒ eË0 ŒîÝ»°hÑ  cóæ4oþ\™Ë®WïéÙ]]2d 'ND‘œœ"…×®]CZ3~饙>ýWfϞǻï¾A½zϰÿ!~þy6/Æ¢V«3æ3^x¡)?ÿ<›•+ÿ°ÊãÞM¶Û×ûöEH õ·ë!<Üݧe2 …B’·¿Õ=^£k×WŠ•z½žœÊÍ›)e’²Ë—£ÌâèéãÁÊ•`kk[êU T wKcÏžýÅPFqqñEÆùûû¡Ñ¨êƒ$'§’••U(ÜÞÞï‡Z¶Á` >þJ‘qþEªfU$7o&“S(<''·Ì£{ài¦¢äGY§ú¥Nùuº/.zGëÿþï=üjƒ9rŒcÇN  ­NÏžo>Ô²óò´Å>û¿ÿÝoo¯‡Z~DÄ«·©S§Ö}+ø O%?~üñûr•+¦ü@PìÙ³_œå‚ŠB™••ÍÅ‹±¢%àÈÊʶLùóóóEkÁ"KK‹3‹f‚G¬¡ ¨@P¹°ÒCU*Õ(6ä°ßQÚ¶mƒÞWa…ÙØØboï!Z] <ääÜÄ`((Z ˜ H—g`Péq©ïÉ5e2&¹“фуNÑh*6s™LVäÙ¹\&Y¦’ÉÄ X <#TƒÙÀIý) ‰àÜÚüÙ覃ømöB.^¼$¥÷òòáæÍ·F·6øùùâììˆR©ÄÇÇôô4 ò©Zµ*mÛ¶­-žZ2™Œ€‹•þ   ´Z-CvvvØÚÚ‚ ggg‚‚‰O@¯×Ó¨QcÑÒà‰ç¾æßwü;™‹œÂ{xxb0è1 ¢…¨%áàà€VkÙ¬òóóáîƒvvöØÛÛa6›ñññ!==£Ìùnß¾I“&—Íĉ=z4IIIâÍ ÊLZZo½õV±ñ‡",,ŒÍ›7‹ÆTð”ß f³¹Tš——kÉ@©ÄÆæŽ9;OO/ ´·â¸¸8“Ÿ_€““¦Ôʤ§§“]d\ll,jµšæÍ›ó×_Y} Ç'--­Ð=F£‘yóæ=ts{Ab&äWЀÞÖ|JHðÓOpâDÙ3tsƒŸ~l;¹N§+ñGxÖ¬Y„‡‡Æ+¯Üq©³{÷n,XP(½Édâµ×^+QHßÍ/¿ü¿ÿýo!mž6ª”)Q^aˆÓrãúMüüü0™ ãÍ-J¾¾¾˜ÍÖ;ý½^X|>míõ´nݲùsjÞ¼9QQQå~ˆÉ“' ‹ˆˆ yóæÌ™3ç±x™ùSP1y9iJ¨{öÀ† eÏ0 ౨>>>„„„”û¾¶mÛÒ¶mÛBáíÛ·'22ÒJ ÉsÏöÊpðàA!PŸFª–©éX§Õš²gÏ!:¼Ô½!WŠW(丹¹“WH &%%àííMõêwÜDëõËT™””233ÑëõØØØÐ±cGÆŽK³fÍP©T rrrpttoîAðô„*UŠZW• Ô÷÷õ}¬7??ŸÜÜ\RSSqwwgÑ¢EDDD0cÆŒ[p7âããqrrºï2rrrX¶lY‘Uð4OùKÀl6sõê5ɧõ½Ë`Ù°ÊÍÍ”ÂÏž=Oƒ±µ-ÝÒüÉ“'quu%++ wwwZ¶l‰»»å¾ÚµkOjj*;woîA˜7¯èðÙ³¡~}hÖì‰zÜÄÄDêÔ©ÃÞ½{yã7$ •ÛŒ?ž‰'òå—_оñ9vì›6m`ذa899ñý÷#Î-[¶¤mÛ¶lÚ´‰cÇŽakkË'Ÿ|Rî2®^½Êüùóx÷Ýw •âbbbX¶lýúõ# €©S§’••Ř1?Sû÷ïg÷n‹ ùÏ?ÿ¼LÞïK Êdrš4iÂ3Ïö¨YP C«Í} ÆîÛ·¯Õõí¼M§ND”›ªU«òÝwßI×­[·¦uëÖÒµU¼àá`2™Ø³gÏ=÷Õ«WÇÎÎŽ˜˜rrr8p ®®®dgg³k×.Þÿ}4Í}•3pà@ºwƒýúõcÿþýR\¿~ý|˜5j0pàýyØõôôdÀ‹wÒ-[¶XÅU«Vž={J#Ñ´´4I»(,,ŒäädÖ®]‹J¥bÔ¨Qå.[œ[[[Ž?NVV½{÷&//ß~û·ß~›wÞy‡S§Nñüóϳ}ûv–/_ÎØ±c+¼iii|òÉ'|ðÁ¼ùæ›\¾|™Úµk3pà@üýý9xð ÑÑÑ|ðÁF!PAåD£Ñ0~üx iiiØØØÐ¾}{&L˜ÀòåË‘Ëåh4-ZÄ‘#G*¼ü¹sçÒ¶m[d2}ô«W¯æ»ï¾cÙ²eüúë¯Èd24 ?ÿü3W®\A§Ó **ƒ;v Óé¨U«Ò”<;;›-Zpýúu"##ÉÎΦeË–÷UÎí<.\¸@l¬µ{'///L&/½ôMš4‘Âëׯ/ÕãÀhµZ7nü°×PÍ\¹r•“'OÎHi#zŒ@p+W®¼/Ýê'U Nœ8‘ºuë2zôh\\\8xð K—.¥W¯^tìØ‘¨¨(¾úê+š5kÆ!CaÆñÕW_¡P(øðÃÙºu+û÷ïçûï¿gðàÁ´k׎7ß´¸’2dãÆ#;;›qãÆ‘——Çwß}G£Føä“OʵÃ_nj4šHHˆÃßß·ˆõ;Ñc‚{HMM%//O4Ä­éþŽ;¬ÂîÕ®¨W¯þùç•Ó¹sçBª•·7Ánë߯ÇLJéÓ§[…mݺõ¾ËS~@ ¨ ”¢ Á£D§ÓYÙ×0 Èd²[ì,ñ·Ãlmm1™L’¦;–îÊWÆY¶‘‚‚iÄ,—ËÑjµ˜Íf”J%*• ½^^¯,:Êb„**ƒÙ³góÚk¯Ia»ví¢ÿþìÝ»€¤¤$^zé%† F“&M8xð S§N¥C‡ôèÑ£LëªK—.套^²: w›Ï>ûŒ×_W^y…‰'räÈž{î9FŽI›6m8þ<=zô ÿþ4mÚ”7Šª@PÑÜmÑìÌ™34k&±”¹\NýúõÙ¾}»DPPtK³fÍøÏþÃÑ£GY¾|9W®\aÕªUh4úôéSj9µk×ÆÃ£hßu/^déÒ¥  D^^Ó¦MãÅ_ä믿æðáø¹¹1kÖ,ùæ›oÊuÔ]T  ÜmѬ}ûö¢AîS 6kÖL²ûP½zuªW¯n•.$$¹\.…gee‹‡‡‰‰‰¥–Ó A¼½½‹Œsqq‘ìƒÜ®ÇírnÿëïïF£¡jÕªÈåå›Ä **5ãÆcâĉdddÜ÷qÔGÅ%P8 Ù?MNN=Q xhÚ´)«W¯æ›o¾‘ÔŸ„@}´hÑ‚æÍ›··Í„ jY ,,L:u#°Æh4²xñbbccY¸p!=zôàĉ8p777\]]ñôôdÊ”)(•J~ûí7†ʆ 8|ø0£F²Z.(Ž?þøƒ .°xñb:uê$-téÒ…ŒŒ >úè#rrrP(4hЀ7Þxƒ!C†ðÝwß±`Á¦L™‚³³3[¶l±Ú@{*§ü2™Lô\A¥¢W¯^,Y²„^½z=Õí “Éð÷÷—Œž( \]]yûí·prr¢ZµjüñÇ\»v~øÖ­[søða P&a #÷£G,ªQ&“ OOOÀr–?22€&Mšàì쌬_¿ž:uê°fÍ.]ºD£FŠôØðT T ²ÂåË—ŸúvËå…6ôêÔ©C:u¬ÂjÕªE­Zµ¤ë矾\å¥q[“ÀÃãPîµLppðý=£èî@PA?¢ Á£dáÂ……¦Nju†ÿøñã|öÙg¥ÞW—/_fðàÁ <˜Ó§O—©ü… Já[¶l‘îæûA¥D§ÓƯ¿þj>eÊZµj%íàŸ8q‚ƒZ˜þâ‹/X¹re™Êéׯ:u¢G…Ü* <˜‰'¦þþþ¼óÎ;hµZŽ9ˆ#øá‡Êí‚^Ô’0  @´ƒ@P¨T*ÂÃéV­š•0­W¯ÕªUC¥RqþüyÖ­[GÏž=%ÓyÑÑÑ8::–ÙÛq•*UèÚµ+mÛ¶-äÿnÆŒ4mÚTº^´hööö4jÔµZMzz:7ndöìÙå¶…*ji= ·¼' ‚ŠåÊ•+,Y²„õë×ÓªU+<ÈòåËÙ·o}úô‘<ž~üñÇ4o޼ܶIK###ƒ… ²yófZ´hÁ¶mÛðóóãðáÃäççóÞ{ïa0„@•Ÿ˜˜ºté”)S˜9s&›6m"**ŠåË—³hÑ"X¼x1Ý»wÇÝÝŒŒ 233+¬ü›7oÊÌ™3Ù¼y3‹/–â&NœˆÙl–¬N **=‡²ú755•˜˜®\¹ÂµkרY³&yyylݺ•k×®qãÆRóLHH ""‚¨¨(Ξ=[bÚ¨¨(´Z­T~ff&[¶l!%%…zõê=\‹ýÁÓŠ°6õàèt: @vv6aaaLš4‰-Z†\.gúôéDGGóßÿþ¹\΄ hÒ¤‰äûI&“Q³fÍRË™4i’U÷º@¹]þèÑ£éÕ«C† !77—  Óéøí·ß¨S§_|ñÅÃö)%¸Éd*÷úJIô–¿ ÉKåÔö@©TŠéJ kSÎíM©»ùòË/­®Ÿ{î9V¬XQäý#GŽ,S9EåQœ ”š5kòá‡Z…­Zµê¾Ÿñ©¨ lÛ¶­ô„99—¿ýV(*##ƒóçÏWXlm@QAÍhm9…shh(n> ÑÑŦkÑ¢µk×ÒA xêåË—Y»v-.\‚‚‚Êfµ&!®_‡»ŽÁÝÆÍÍMÚ…¬Î&ANih9i ¦Wùî9wî)7‚—Üeð÷^Ö­[WH,–ÐmmmðóóC£Ñˆ¯KPˆ¬¬,RRRpssÃÅŰ•V*•V†¦“““¥ó÷:Ž«W¯–súööö%–‘ŸŸ/ÙMõññ)äÆäî¼´Z-ƒARËÊÈÈ -- œœœ„@½›¥K—òÞ{ïQ£FòßYYpŸþÁ'jÕª{ö@H”°>Xœ¯ôüQòîi6›Ëö°°0!Eèõzzõê…J¥"33“µkײsçN¾ûî;Ìf3?ýô5jÔ`îܹÄÄÄH»î&LàСC¸»»c6›Y²dI‰å|óÍ7œ9s;;;ùí®æ¤I“XµjG`çÎ,\¸öíÛÓ§O²²²˜2e ×®]ãúõë¬]»¶\SO¼@=z´4r<<>ýôSéÿׯ_§  €ØØX+Ú A7n,]×­[777ÑxO &“‰&MšðÉ'Ÿðù矓••ÅÙ³gÙ¾};W®\aõêÕ´lÙ’¾}ûòõ×_K÷?ž+V T*ËôÏ’%KËåôë×Ï*®gÏžüý÷ßÒu£FHJJ’öCn›úûùçŸ2dƒAÔ21{6ÜÕ°EâèvvпÉé¼½aüxñÅÜÂ××°Xíi×®~òäIŽ;&]ÿù矤§§K×S¦L)³‰6Áã‡Z­fìØ±$%%qàÀiÀw6‹Ôj5ÁÁÁVf8oÞ¼ÉáÇñööæÌ™3e*çöôýÞÁTPPÕ€««+>>>Ò’‚««+999 0€† >jSw«´Ü½NR"Àûï—œæÈˆŠ‚»Î‰°ÁZ&4h@ƒ ¤k£ÑˆÉdbóæÍdddHnn.Õ«W·:x/Õ«Wg̘1¢AS<Ș1cð÷÷,ûf³™ï¾û®Èô¿ýö_ý5‰‰‰ý½§§§S§Nz÷îÍ믿ÎðáÃË¥:õDÔ»UZnÁæÍ›‹¿I¡°ü•„\n–|äíi"33Sò©~›5kÖHŠÔ¯¼ò ÞÞÞ,[¶ €ÀÀÀB62?f³™õë×#“ÉèС&“‰œœ.\ÈàÁƒÉËË+r†ÂÌ™3™:u*/¾øb©åèõzòòòËåå¶u›Zµj•Û¸ôÓ=å<NžMß¾}™6mÑÑÑüðÃôîÝ›K—.±|ùr222ððð E‹(•J~øá¼¼¼„bá™ýìííËä-188Xr1+€¸¸8RSSKM·oß>Nœ8!Mëïöcîïï/©ÇžnÔjµ´ãÞ¹sg¼½½™0axzzâàà@çÎéܹ3Š[3ÈV­Zѵk×2 S€ñãÇK‚‚‚Ðét¸ººСCi]ßÅÅ…š5k2tèPéÚÙÙ™ÁƒsóæM|}}ÅÑÓ{™3g2™Lò†Zk×®%++ëN€Fj5Üjð{Q©TtïÞåË——š÷O?ýdõrÖ®]ËîÝ»ï䥄zÍ»Pû¹—­î;{d§#6ÜI§±§Û¿ÿc•ÆhгfÆS$&3ènâruuåÛo¿eܸqܼy³äJ:;Cl,,]*ýÒ—E¯M›6|üñÇBbJD.—2§çïï/­¥ÞæÞ4w›û+ vvv…ò¸=PªuN¹^^ÖJÛžžžVzªB ÞƒF£á£>*5]^^žµu™ãÇáÌ(F_¯×³víZ¾ÿþûRó4hÕzN÷îݭ ‡÷n`áxkµÚϽL—÷ï¤ÓåçJ£Pªxcð¥k5Tó°ü?##ƒ°°0¾úê«B§‹A:Ш`Ù!-¯]àiF¬¡Þóku$¶l\9;—¸¤PÖ‘r‰eçCÓÿ¢i‡•˜ÎÖÁ™>_†—˜Æ^s§ÊÎÎÎ…ÎO‹Bayæž÷i%77“Éd™¢Aî“õë׳|ùr:wîLݺu™4iJ¥³ÙL§N8|ø°´ T*™5kß~û-W¯^¥zõêe2XɤI“¤5Ù-ZHq999üú믌1âÎ ÏhdêÔ©Œ1³ÙÌêÕ«ùã?xûí·ËíFZØÃÊÀĉùâ‹/øâ‹/¸té’hû@«Õòå—_2tèP&OžLrr2C‡%<<œ×^{ GGGš4iBxx8cÆŒ!88˜ýû÷3hÐ ÂÃÃ9}ú4k×®-µœ¡C‡2hÐ >ùä† f÷ý÷ß³`Á«°½{÷J†W®]»ÆÉ“'ùþûïùòË/Ñjµb„*T4w/ÏecsÊ”)b¹Ôj5þù'~~~4nܘš5k@ff&ûöícêÔ©RÚ}ûöѺukÚ´iC~~>gÏž¥aÆe²ô,‘¾w-uÒ¤IV6U“““Y·n´‘ªT*Ù°aíÛ·§}ûöV ÄõA ‚rú<$$$X÷!lär‚ƒƒ‰‹‹ãòåË8ßZZZ·nݺu³J»gÏÚ´iXŽžÖ©S— ?ª]õê5P«m¤¸ÔÔ4ärñ«)xrÙ°aÃ}[x¿—9sæ0bÄÂÃÃÑëõeºgáÂ…¼÷Þ{âETʽ†š––Š££õ¯frr *•ÅÉVll 99df¦’‘‘ÂõëW1™Œ¢¥O¾¾¾V~ßKÃÛÛ››7oІ{Z*@BBb×®]üý÷ß888°~ýz>ýôSBCCyã7xÿý÷­Ê<~ü85*Ô»wï–ò¸wÉán»%åpåÊ4M¡6}hРÕZuY¥¥ÅI‡‰•J5 …Š‚‚löì9D‡—Ú£7äJ‰§NÁ`}:99“€½½666ØÚÚ€FcShª^½†89©±±±ÅÁÁâoÛd2Yi ¸¸¸°~ýzŽ9¸qã U422’]»vŠV«å­·Þ’â†^Èxorr2›7o¦K—.Å9§ ¦ ú•T€ƒê>n¬U ÒÒ ’OAgÍš…ŸŸ_™ÓïÚµ‹«W¯›¹·Öm—þ½ÍîÝ»Y°`A¡ü¶mÛVhZÿüóÏãííMVV{ö쑃ƒƒ©W¯çγò"akkK‡HOOgß¾}Vy½øâ‹\¹r…K—.Ia´k׎””(1Mvö †‚û¡6jTŸÚµŸ)6þÆD‚ƒƒ±³³¿'Æ XK‹ÔÔT+Á9uêT5j$¹0)“'O.Wdø¾}ûhÚ´)¦\elß¾:”랣GŠ‹‹ËC/«BîS©àØ1hÕªòÖ°±±y$TÛ¶miÛ¶m¡ðnݺ\ì}õêÕ+\ä”=88˜† zÆ¢ò¸¾I“&EÆ <¸ØeQm>tèÐrµG«{úÅý¾ËÒØ½{7­ZµB©¬XcxåýöŸ}öÙò’–g¾ý—•uÝœ››jNK‹3¯Y³Ìœ•l¾;þAÿ²³“Ì%a8p ¹  Àl6›ÍÍ›77ÿõ×_f³Ùl>wîœyÒ¤Iæ… š·nÝj¾_†nNII)÷}}úô)÷=ãÆ3Ÿ?þ‘”U!÷Íše6«Õfó„ f³NW9ëx:tÈøÀœ——WáùÞï·_YY×­d\¥²‡OõêÕÉÍÍE¥RÑ£GijW³fMš6mJzz:/¿ü²X|XÀèÑ–ÑêÈ‘OÄ#=ÿü󤦦Jÿ7›Í¨Õj)þ›o¾aúôéŒ5J¼ÁQ®5Ôåî5ÔŠììlìíí˽®Z”’uiäææ¢ÑhÊ}zåÞµ¼‡YG«ûfφ?´ªTðÙgðý÷ZÖ£~¶‡Áý>Ã?õŒ[¾ÙÙÙ888 “É*4ß#Fðå—_JƒSWë5Ô§NŸÉÑÑñ¾6©î§ãØÛÛ?Ò£€÷Û¹‹¼O§ƒqã`æL(Âò£n•E˜>ŽÏø¸åëèèXáÂôQ!D+!mÚ´©<•<ÆŽ}2Ÿí)~†§‘^xÁj©çaP®5T£Ñȶa£²+—‘–L“Æõ ”ÂL&W®\C¥²Á××G¼Ñ2òÿ÷•§2òd>ÛSü O#o¿ýv塚Í`VyÜäm«?½]M~›·ŒÐКVé׬ù“eËV³pá2Ž=.Þhèõú¾íÛ·¹sçþsüýwèÛ÷¾n}úðÉ'ŸŠß´i2™Œ¨¨(Ξ=[ißÏwß}GŸ>}øæ›o Å8q‚ØØXrssÙµk×c×÷öíÛGFFF¥­_NNC‡%))é–<ÙEnn.±±±œ8q‚Ÿ~ú‰-Z0kÖ,À¢­Ñ§O¾ûî;¦M›FÇŽ?~|‘?æ>>>lÛ¶ëׯÿsõøá½ }¯#Ÿýû ¢Ždøÿu!0$”†Ï¯ ^µj0¯¿ÞAaXâ‹ÙlÆÍÍ­ØÒÝE§ÓI¿ÎÌôéðŒÞ|óMêׯÏîÝ»éÚµk¡øÜÜ\Q*•ètºJû~222 )t, ó*• {{{òòò«~7oÞ<Ο?ÏôéÓ+mèÕ«—t——‡½½=*•Šüü|ÒÓÓñóóC«Õ––FHHˆô#‘——G@@@‘ßDVVnnn˜ÍæB§Ë„rë¡6x®/§èX6o ÿ~«5F£‘;Ï¢QÉ;ÇÏ>þøsþ›AƒF2zôHü”κuë¨W¯!¥¬[&$$0fÌ8À€˜3gãÇÇÍÍ ðþûïãíí À»ï¾KTTÛ·oÇÇLJaÆtÓÑæÏ‡2ži/í£­V­mÚ´!//uëÖÑ¥Ké|úãÈÒ¥Ki×®Ô¶#III,X°€~ø~ýú1qâD´Z-qqq¼ÿþûèt:~ÿýwœœœÿüsÞÿ}¾úê+¦M›Fjj*Ý»wgÇŽrñâE DLL 7nÄËË‹þýû3mÚ4¦OŸÎ7ß|Àxd?Œ›7oæ7Þx¨Så¡Êer}6ŽnïöÇl{G§"Uƒ¦L™ÈóÏ7aæÌŸ„0-9sæð÷ßsñâEÆŽËÑ£GË™kWWWV­ZEçέî "<<œ-Z0gÎú÷ï/ýÚ jÕªE­ZµX±b³gÏ@¥RtÓÖ¦N…7ß„T[Y½z5Ó§OgÞ¼yÌ™3‡ŒŒ †Nrr2`9ÆxðàAòóóËm€âQÒ»wo¤¨áÇK®Ÿk×®MJJ QQQ<ÿüóMŸS*•¨ÕjI­Ïh4R¯^=ÂÃÃquu•úŠB¡@£ÑAxx8ï½÷&“ £ÑˆN§#''‡}ûö XÔF#/¾ø"'Nä÷ßgãÆ„‡‡3lØ0Ìf32™Œüü|L&S©ê‹999üñÇÌŸ?°ÊˆŠŠ"%%…ÚµkÆøñãyá…ËfaXX½{÷ uëÖ|ñÅ 8k×®1|øpi&ѹsgV­Z…««+Ö¶åRì7ŒlÛwŽM^à?_ü›zMZÐùÍ>Ø(ÌTwNA¯¿3õ4h$3gþ$]WÅþ' &`kkËðáÙ:u*[¶laÅŠ 2„öíÛ–uVwww 5kÖäµ×^ ÷”s÷á„ñãÇóÖ[oQ£F ,X@rr2^^^„……1aÂlll8tè}ûöåøñãØØØ°dÉÂÃÃÙºu+666ôïߟѣGó¿ÿý¼¼<ÆOHHùùùèt:ºvíJ^^Û·o§E‹…ŒÔ<ŽÜ«Ø_.j49}‰ú,¿ÆÚ¼\ =ŽN.Èd 0k1ò¥ô‰‰7ðóóõ¡¾Ðl®\¹B:uˆ%//š5k’””$™g+((ÀÑÑ‘ØØXœ  ÷”sõêUiºœœŒ³³3*•JúÎÏž=‹F£¡zõêdggÏŠ+xå•W¨Zµ*Z­¥RI@@qqqäääP£F RRRðññÁl6“œœŒ‹‹ /^ÄÑÑ‘ÀÀ@~ÿýw‚ƒƒŸ]Þ¨Š¨ÁãË©S§ðôôÄÇçþtÊ ûöí+҂ד"P•¢›‚²p_æìîB©T>Q´Èg|”…:rr’EÏOF£þŸ¨&““)O¼@ F¨Iffë×o*Ò*·Fc‹Á —Ü­< …µZ%Þ´@ (3:•J…V«Å|µ5…BAË–/àçç[yªÁ`Ñ—¼ÛhŠR©ÄÃÕJE\\<á ÊÃËÀÀ è% TnܸI~~5jÔâÊ•x²³³Ñjï̬ÝÜÜñõõç^·Nÿ¨@½;;{°··Lܼ™LRÒ ³P¥Õæ Õ択"J%66WWwòóó°³Sck«Æd‚ôô4rrr*ç”ÿ6UP*å˜LL&ƒx› Òp{º/—ƒ7:;yyÚbÓÿ£¦ÝÝ=IMM‚T Tzôzii)$&&VÜ5'§ø©³Je#¶( ©©ÉÈ嘘HíÚ5Q(Ôeˆ@ ”e”ªÓ鈉‰E£Q—h§\Õ`0²qëAÜ|«Š;°s èOù h4j4511±88أѨ…P•‚ÌÌ,rrrHNNÁÕÕ DWå¡:ºùòì‹Va¿ÿò#§N'00ÈÊ8Ji¨Õ-ù::fÉmŠ»»‡÷ ØÚÚs™¤¤ë¢w‚R)(ÐL|üUÀ„ZmKPPð]2žâ*Àï³ Z­giþâ+lXδ Ÿ1gù«4K—®¢gÏ$&^'&&–6mZHñF£sçbÈÈÈ.²Œ””4â⮈·+9‡ÿ]b¼Ba¦jÕ*.PÿŽØÅ¢y ÉÎÊàÍ÷>dÕÂŒ;•F/´Ò¥tûöEðæ›¯qáÂE@FtôÙ{ª‘´´T”Ê;ûbîî·\Óʸ|ù’x«ÁS@•*ÁT«V½^ÿHÊ3›Í\¸p›7o”˜®aÃÆèõ:nܸAJÊ#ó¾¾~xzzV̵I³vøVoÎ×÷fùüŸx§ßPäŠÂ¾ÛsrrY¶l ï¾ûf1¹ÉP*•Èd2BCk Õæ‘——ÉQÂ(µ@ð” —+HL¼JzzÚ#)Ïh4yŠÀ@ÿRF¡ nÜHÁÉÉgg'’“SÐjóËåÈdòŠ›ò·}å &iV1zð»ÔkÒ¼ØtÆÁÁž””¢ýyxxàíí­­-©©ÂhŠ@ ¨|äæZ”ù===°±Q‘]lÚr T¥ÜŒFi¢]‡NL˜ò6*5¥ ¹õµS§—P*•ôï߇ŋWò¯½U(/W =iiZll„%A@PyIIIæÆdªW¯V1U.—ñl o-£Éÿ{ç¶Õíä[Cé; ú¯½öŠôÿaÃ>(2¿‹cpssE©T`6›ñññoM T:ÒÓ3Ðëõ¥ºZ+§@•ãëëiåæäAQ©,ãL&11—ðññ®P·® ò“‘‘Irrê#)Ël6•9mff&7o&ãèhq'dgg[qµ"‘Éd„„„РA«ð‚‚BCkJþÁ“½½=™™™¸»{>²26lŒ­mÉÂÑÕÕ “ÉDÆÖélmm‹©þcÕÇÇ›aÊÞ$*-õêU/Wz¥õPØ, ‡mm5˜1‹O¹J)ЬB†¥É5lSò>•×S@ xÚɲÉg«a/Z³µ™¾Û¯ñY‡Á¥PF#II)¢%ÁSÉUv…Ãõ‰‰IEÞãííB¡°T³YFA¾L´¤@ xꑊ–…fÅÊI³Yvg„ªTÊ ©ê%ZR ˆ)¿M>aó^¥R–*'ïÙå—!—ËÛ†¸{SM î½VO±àžjéÛMVU©TáèèóØ6‚N—Kn®X ÷ʤÄùœ-6yÖ4ØçÙÒ— îÞåW*ÕB  Á}R®ùýï¿ÿ^)¢²ÖK x<‘¡RÙû§PØüc5S*ÕÅÖËÆÆîñ¨;v쨔¯¿²ÖK x,Åé­l½>¯Ð_JJ'Ožüç–ܦÈzéõyìÙ³»ÌùìÛw°°˜6í׊øEêõz&OžLtt4Ý»w§[·nlÚ´‰åË—0aÂüýýÙ¾};‹- $$„Ñ£G#“ÉŠÌ£8WEåqôèQ²²²X¶l™UYYY :€.]º>Ñ ˜¢¾+³Ù„ÑXxã· @GAeÇÆF‰­­-:…B‰B!Ç`0`6[â´Ú|är:œœ‹Í£¬õ0 oÍkµù(ròó-ù::: “ÉhÕª9~~¾üñÇF«ôyyy ãL•Ê­6[[ ùù¨ÕªbåX‘õ?þ N:|öÙgŒ1‚V­Z¡×ëÉÉÉ!<<€°°0ÂÃÃY´h‘Á¼yópww/2ww÷"+rwqqq=z”ÄÄDÖ¬YÃÒ¥K­ò1b„”vãÆdffŠÞ/üCäææ2cÆo¤¥Y\ ÙÛÛÖ“ ¶Ðºu êÖ­ÍΑŸ¯¥[·ÎôïÿÏ>[‡Œ ËwÛ©S{š6mTdAAT·!C>¡V­¤¦Z¼´nÝœW_}¹Øô‹¯äÒ¥Ëxx¸óñÇ2rä—ÌœùãÆýȈƒqss-»@-Þ~ûí2§Ÿ|\´†@ ÜÏ?ßÈr‚Ê2å—¡PØŠV‚ûÀhÔæÛz¨fŒÆ<Ñ*@ð S~…‹cINjW lÔ­[GG!P‹":úJeÑM¢ÑhpvvA.Wpýú5ÑX1>>~xzz=T+e7n\'%å¦hìÇ{{ªW%&æ:¾HKVžž^¨ÕšÊ5B½té2™™Y4jT¿Ô´7nãÀzö|‹gŸ½s$mâÄÉdee1aÂ7RXBÂUfÏžKݺÏЫWr4da…]ÿ@4ƒŽ={öREô¸Çgd2F£þ¡•qêTÔë? þ9P«m¨^½Zm>:RS­g¯NNN·ÎýßùaþGÕ¦.\¸Ä7ßLàÂ…‹¥¦Ý¼y;`fÔ¨‰ˆ8Btô9éœn¯^=5êcþóŸÿ‘ššÆ¥K—Y·n£F}LP?K–¬,wÝlmípw÷ zõêØØÈ0t¢— Oƒ¶„†ÖÀÉɹX[¨% Ô™3ç2hÐH ÉæÍ;0›Í̘ñƒ䯿0hÐH’’,SšY³æò¿ÿÍ`Р‘Lš4Åjx¼uëNÆŒ_(ÿ›7“Ù´i+}úô,Óƒýùç:w³3ï½÷.óæýÎI˜L&‚‚qvv&$¤ ÑÑçøã¼újœiÙ²û÷*sÊårüýñôôÀÑѽ¾@°ètZ¼¼<ñ÷÷ÇÑѹ|uР÷™9ó'fÎü‰‘žžAtôYfÎü‰eËÖ0sæO|ûí$,XÌk¯½ÂÌ™?Ñ®]k~ÿ}ù]#=[\]] åïååÉÇB£ÑTªF«_¿J%ÈdÂ%µ@ °F¯/Àh4J6Sï¥È5Ôœœ\fÏžKll<'ND•h²ªqã†Å®µnÝ\²äò8páÂY ­&™°¸@INN!55 OOϲPwîÜóÏÖeæÌŸøæ›QÅZV¹MTT4qq EÆ>ü7¿þº Üß´i«W¯—®_x¡ ‡ÿ-Žúê˸¹¹b0ÈÊÊ .. [ÓüΜ9O:5Ë\nnn.ÎÎÎ\¼x™«WIII½H pùr<—/Çc0Šœu;BíØ±=³fÍcݺx{{Ñ­[glll¨U+€ ¾®CC«²bÅZââðãã?”òJJJæìÙ …ʸy3™±c'RP Ãd2ò×_6ìjÖ´ä™p•ìì)}Ïžo±dÉJÂ×ңG7Úµk}ki¢?ãÇÿ—¬¬l&LøgP©l4h$uêÔ¤ÿ°r7ž““#&“‰œœ\®_¿¿¿_±6Á“:"ÍG«Í'..gg'ììJ>QZ!Ö¦*Âæ`e`ݺM8;;—ƒZ­&&æ"ÏGûömxóÍ׸v-‘)Sf‘››Ç§Ÿ-õh©Z­ÁÁÁ'''d23ééi$$Ä zm%'77‹ü|m…ç{út”xÿz}ööªV­JZZ:yyyEÎ,rrrÉËÓZ‰÷ööäý÷û0{ö<ÂÂz¹Iý+YÞ¼™\¦t‰‰×Y¶l ׯß(5íŽ{ÈÌÌbæÌŸxûíîÌ™³€ùóóâ‹-™9ó'\]]X½zÉÉ),^¼’±c¿`æÌŸøã ÄÄÄ›·ŸŸ?¾¾>8:Úc2Ä4_ xÌ0z\]ðññÆÇǯPš¼<-iiéxyYëšzx¸Ñ£G7~ùe~ÙG¨‰‰×ùå—’)»ZµBùàƒ÷9òKjÖ åÌ™s’úÒ¬Ys9uê `1<1p`_T*›"ó8q"’ðð¥€ÅßµV›/•{ýú š4i˾}›©Z5تNÛ¶íføðA :ªÔ¦ï'çjIDAT‹Œ<Íë¯w,Nµ._¶èÈFGŸeðàþ4kö_}õ= ÔC¡PHº¶¾¾>\¿~ƒÐЪwHÕ¸¸¸àããƒV›'¦öÁ€ÉdB&µZIýúˆŒ<.Mó]\\Ðëu·F°z.\juoÍš¡,]ºŠž={”.POžü7çÎŦŠÔW_íÀÂ…Ëøï§Ýu:Q³f(r¹‚:ujJ}NJ Э۫\¿~ƒ5kþ䨱Hi”wï¹ýÐÐjh4jéZ£QÓ±cûJ×Ü©©)œ?žü|-NNŽø‹>(å?~<ww7zõz €U«þ@§+@¯×3sæo´iÓ@Z_hÙò)­-!!Uؽ{]ºtâÙgŸÀÇÇ ;;[üü|ˆŽ>wKÒ%==C*799…=ú°hÑ­…Ö¥K—ÉÏ/ ##“èès¸¹¹àëë#Õwøð/Ø»wï½÷.K—®â¥—^äâÅXºví@Ÿ>ï²xñJ4x–;÷0bÄ<<Üqqqâðá¿qpp )é&]ºt*Ô& …{{{´Ú|¢¢NŒZ­F¥²=R xÌ((°Lç¯]»ŽJ¥*ö@OÕ¤ÿ_½šHll<={¾Yl¾ŠQ£>{o ¯¯119yòqq tèÐŽ*U‚زe=z¼ÎÞ½û‰‹K`Рþ¨T*‚‚Ù½û/ââÈÎΡNš„„T!>þŠ”‡³³3>>Þ4oþ<«W¯#..ÆðÌ3µ¤õR³ÙŒÁ` I“†…F³Û·ïæÌ™s—€B¡ 88£Ñ„R©à¹ç#ÑÁÁAlÞ¼ //OIí! ÀŸììl:Ê+¯t 88¥RA£FõÙ¹s.\ä£þ]èTÄñã‘ÒŽžB¡@£ÑžžV«%++FCRÒÍb_Š r`o­ú¡¨M%$\ï¿’ãêꘈ#++›ÜÜ\ììl­–ñ¼½}°³»óý;99ÝõGêÕ{¦DƒIåRìRŽ˜–—… —Q¿~ÑÌf×®]G£Qãáá!zm%ÆÅÅ•øøø‡â7Ìd2Q£FuÑÈ•_Μ‰ÆÅÅ¥X¡‚³óý›-—@=vì$7xê^ĵk×ñóó/ó‡% R /r9È岇/P¥³wïrss‹×hìP«Õdf¦‹Æª$Èdr\]Ý+<_³ÙLzúÿ·wæáM•éÿeoÒ&ÝBWJ-E È"vD\®Žã êÄaPçÁꯢ×GGAïŒSÆ+f[FF/ˆ((ÊR¤"[)”–ni›4K³Ÿäþ‘öHMe“*ç÷<çyÚ“/o¾“ïœ7ï÷}ï"UÑí^Ó~#mmö¨aÂr¹‚k®@VVúyÉï–¡§¯×‹^¯ïR{—Ë ø‰‹‹;k[³Ù‚Õj#%¥G§<¯55§ðû…NQR‡ººbcua¾g¢#áé¨Õj’’z£¤¬¬ßÅ *+ÛOJŠ4Î݉¼¼¸Ý6\./‹Ÿ¯s­8•JMïÞ¹‚•Jq¶é÷ûñùÜ(?…Z^þ-â׿žÑ¥ö/¼ð ùùC˜6í®3¶3™š()Y‰\.G.—3wî#¢U¹k×^ú÷ï+îò/_þV«`0È”)¿8¯*–*•šøøx BIZ[-$%ÅKww7" \ÜͪÖV z½Núr»×H£T*Ðëµ ½hmµa±´Dˆx”!>ü~w˜„êêS‚1D=ªB=xðKhZš““MFF:•\}õwnÿWTTâñx±Z­èõ¡°3ÉÐë㨬<À°aùh4jL¦&***ЮýéÔÕÕc25síµƒÂ,Ó’’ôïßµŒü ¾Á¼yO¢×ÇQW×À‚dæÌiìÞ]Æã?ŒB¡ ´t»víeÿþ žÏСƒq:]<ÿüË.èò°ÅÄh1â‰A.—‹ÊTBB¢»üˆ $$Ä¡×Çb³Ùq8VG.âV×¾}å|úéçTUÕPUUCié*ÚÚœÔÕ5°fÍ?øàƒbÌûôé÷³mÛªªjعs—XeÔdj “ñê«aÙ²·N;¿€%KÞÏ•”¬èÔŸuë>ä·¿ýŸ¦·ñãÇ’››Ó¥‹µÛèõqík) X,­øý~d2Švû=&FƒÛíÁf³c0„–t:-Ng×§ƒ=ÉÈHG¯×¶/nKËÔÝS©‘Ë!!AOé,/¢B­®®Ád2¡V«P«U|ýõ7x<&LKZZ*EEK‘ËÜvÛM žÏœ9³™1ãò󇈖¦R© “¡R©xöٹ̘q3fÜÃþýhh0‰çæÌ¹¿Szè~¶ný0¬Ÿz½ž»_ö|™LF}}½t·JHüˆØ¼ù£ –uÊo00“E…¦×Ç q8ÚÐëãp:B…BŽÇã +°cÇ.***¹êª^øýþN‹»g«$j·Û¿7µwár¹INN:§‹³ÙìƒâããÛ-MN§N'Z !Ë4(^‹×ëE­V+îֻݞN!²g£¶¶§ÓEKK ÙÙ½Ú‡¥Ô³Ý ŸÏ‡Õj£©©å¢¤_Œø”‡ÖES^²ÇƒJ¥âÃ7AfÍšÁ§Ÿ~Îûïÿ›»ïþ%GŽ£¨è¯(• ü~ Æ¢Óiii1c³Ù„fsë;’••É_þ²€£G+6l¨øZié*V¯^ËçŸoèôžÖÖV–/‡'Nb³Ùil41eÊbØê‹/þ³¹•’’E<ùäñÆC£Qãõúxá…PÖ¡C‡ðúëKËedg÷bÔ¨aŒ5ŒÅ‹ßdË–mø|¾0«ùlt󪩩E¥RC¯^R¾L ‰îBUU5G*Õw3é žFóC­­­Ãáp’b$11††FÒÒRÅ6ÿÌå™gÇét¡Õ~§8:dh4jt:Éɉ455G”a³Ù©¯o ==•@ @BBȲ´XZ±Zmb¨i^¯'N†)æeÖØhBdd¤‰¯›LÍX,­dd¤‰ë©ÇWáóùÉËësše즺úz}\'gâ³Ï¾ gÏŒ¿„~ìv;ýúõeûöRTM7B¡PÒ³g6KÓE•[Vöõyy†H\:rr®Æá°pøpC*Ug%ªR©ÉͽAðpìX55Õ­ÚòÈÈHïºB=®ÔÔh uĈQQ_ewž“_«Ä¥E&“#Aêêj/²\™™éÒÜP*ÕØíV´ÚÈå år9qq±ø|΋k¡ž n·;,™É•Š ]^/u:]]®X !!ñÃogÇ笰/F$ezúôQÑåXþ¦¦fŽ©ˆ˜¥H&“¡TªHIÉÀbiÆhLåbº_Y,fìöViÀ$®(zöÌÁbiÆél# Dx~•$%Åg0Ñžñ+nëùË/wóÍ7™4iBX™•ïÓØØÄúõÿGNN67ÞxýYe¬Zõ.mmN|ðW]î^¯½):ˆ‹3K\\,ûö}^OVVzĨóÁãñP^¾OZß“¸âÈÎÎ"33Ÿ/ˆÕj Ë©¡R©IJJF¼í¡§áåŽìv>Ÿ‹¸¸ð(¸KZ¤Ïf³³xñß/‰ìÿ{ƒXÛª«ìÞ]&z¬_¿ÆFSÔ¶--fV¯~aÆb³Ùøøã-Qex½>JJVÒ«WÆ ¥¨h)Nç¹­ÁÈd24 YYÙ¤¤$#Õ®’¸D¨T2ŒÆD²³¯B«Õ‰=§#^¼Þ¶°£±±–¦¦¦s³PW­zŠŠcÜ|ó$FŽÏçç•W Å6=ö0ƒžuë>Àf³sâÄIzöÌäþûgrðàaÞzk5»w—a25‰2Ö­û€É“oçï›S§jEû÷`ݺÚÍòŒhýx÷Ýu¬YóOŒÆdÒÓSEJüµ×ñÈ#¿ ó[-)Y)nžõë×—yóæ³pá˯¿´t“'ÿœÜ܆LAÁ\nºibD`6[¸îºÐfÔ‘#ìÙó5ãÇéÒàêt±èõz ýE'—ˆ:qG© m:nÚÚ\8Ž ’Q¡nܸN+ú^nÚô ƒ_Ãüù¯òØc‹í,ø#¯¾úóçÿ‘E‹rË-7rðà!V¯^ËäÉ·3{ö½x½^æÌ¹_tQ3f$“&ÝÁ«¯¾Äí·ÿ‡(#/¯øy2â#öãæ›o ¾¾~ýú2dÈ bccÅ>ù|>ÊËâñxCš™Ù‹ÔÔÈå2I™JH\µ  Õª±Xl,+¢Bõx¥ `.ÙÙYüæ7³Î(cÚ´)<ÿü+8.{¬ SšÃ®Ð‘Ábi¥®®žAƒHñÿ——ËÅÑ£•ÄÄhËå]=.WøšªÛí‹°ê@*r©®>Emm=))áÅý:’Ð>\A^^:ކ†º‹ò¹~¿³Ù"¹MI\q¤¥eÑÒÒ@CCcÄdK¡§~¿›šš:#Ï{÷¾ŠÄÄI¡v'›ädffDY× ýjµZAÀë½xmJ¥•J²€%®,d29~¿…"Új§ ¹œóöù–êeÄl¶œ³/­Äå£oß>?© &SG“ö{deõ÷LÎÙP‘¾¾Ë‡Ãц\® GðŠ›jµNGLLv{+ÙÙ½£:úA*+á÷{¤/õ<­õ¼¼Ô××ÐÖÖ†ÇnÄÅéIOÏD¼?™ë¶Zmh4šˆqëM ±±±(•145Õ5œºGtŒF#áÑ‚àøñÊnwOöë7³Ù„ÝîÀåj‹:år¹:ªœ@À1tUÞ].tÑ¢¿×ûœN'O?ý; æâpœÙ)×ïX±b sùüó/Î*£¼ü[ æ²hÑ2¼^ßeœÿD& ”Ëå¨T*RSÓÉÈH#%%™ÊÊ#¸\n‚A?~¿+âáõ¶qèСNr¤£ë‡L&‰dd¤‘––‰J¥ŽÐ.äÒf±´RP0—^øßKúLx½>^{mQ—œ}ô)žxbmmßEéíܹ‹‚‚¹””¬Äï÷wáþS“––IFFFc"‡Àï÷Ÿõ;T(ä‚G¼'ÝnGé†c ññqdd¤Ò³g¯(ã,G&S P(@ØÑÔÔDCCcÄqè6 õÛoÏ}êÛÚj¥¨è¯<ûìã/äõ×—rêTô›Õ«ß£wÒÐ`bëÖíQeìÙ³={öQ\¼ë¯˲eˣʸ( ’’’ÉÉÉÅ`СR)»œdEââ vTÄŒ!77—¤¤¤ˆ»¹‰‰ /¤©©ù’ögÙ²å¬[÷áYÛ544RT´”¼ôÒs-¥¹¹…íÛ¿äĉ“/dàÀþ¼ýöš¨2T*IIIäææ¢×Ç T*~Ò÷Ÿ\.C«U‘›Û£ÑHLŒ6‚* ¾°Ãá°E -8å/+ÛOmm=V«•;v1f̦O¿›“'k(,,Û=ôÐl º†—_.ä¹çžàÀC;vœ‰DZdÉ›œ#ù|>ê{¦O¿û²^cuõqªªzöÌh¦‰»âÆÙíöàt:1››/B=­6”@:6VÇ+¯¼v~üø1<úèÓÔÖÖsç·‹k‚>8‹‰ǵO-T(•J\®ÎS'.›ÿÕW{(/ÿ–>}zãóù:E }ôÑ'|ñÅ—¼ôÒsÞRÊAê눧²òD§¼¥Ë—¿ƒÃÑÆÃ?„¢«6nÜÌøñcY¹òüêWÓ£ÊHKKeÆ™={&û÷`Ô¨áQe\@ƒAO[›‡£ššZú÷ï1˜Ä5 8rä*•A„¹JƒA\.7~¿€ÓéB§Ó"“ɸñÆëyæ™ÇÛï9†ƒœñ³ž~úwÜrË$ñ9éÀçóáóùÅÏËe¹ÏšUÀSO=Jÿþyôéӛ͛·bµÚðù|8môê•Éôéwñî»ë˜9s;wîbÒ¤ × hmµµçù¬%/¯Ïqÿ ‚ÀÉ“5B¯×+ˆ‚â©§þûw‘^°Û 8 Ó¹I“&0oÞ|¶lÙÆ–-Û9r˜8È£GÇãñ2bD¾hqnÛ¶ƒwß}Ÿ-[¶¡ÓiÉÎîq:] ×Iv|¼ŠŠJÖ®]Óéꔤ¹®®³¹•Ñ£G„­?Ž3’?ÿy17~Ì‚óD PYy¹\Æ!!ë6/¯¡´t%·Ýv3C† Œ*#99‰ÔÔþð‡×P«UÜwß´¨2Ϋ5tÇÆêNÛeUrøðQÔj2™³Ù‚FƒÑ˜5UÈmêFc’¤ Ϲ\Nr²‘¶6&Sß~{˜øx2™LtW«5 «ÕÆ‹/þFÍ–-Û˜8q\»‹‘‚%KB•rëëÉÏ‚Ûí&--UtMúþsµwï×äææ„=Ì~¸‰ÒÒ•âg|óÍA1=$Àöí;9rII‰hµ1Œ7š_ü={öìcÞ¼'Ñh4¤¤ô@§Óñ§?½Aưe³ÙÒž)…BÞ^%BÁ‘#ÇP(B;þ &bb4gU°±±z45ß¹M TUU“””Ø­ÆÚhLÁï÷RSSËÑ£•âa‡×±9 466qòäIš›[:MèõqR¤TwÃëõâõzQ*Ãw’}>Mh™E¡P Õj£®±ƒA¬V›TŠæ<‘ÉBÖŸÏçÅét‰y:Y jµú'µÎív»¡Ý=(üÞÔé´¸Ý ÅY³ ©Tªv¥g^6›½ÛÝ“Z­VüQŒÔ·Ž{! âp8¢îæÇÇÐh4’B•¸d³é+ª„„„D·âÿñNåQ…GGIEND®B`‚snd-16.1/pix/fmeq55.png0000644000076400007640000000130311147553267012753 0ustar bilbil‰PNG  IHDR•eÉl3PLTEÿÿÿÐÐЀ€€ppp@@@ ààà000°°°   ```ðððPPPÀÀÀÄsµº pHYs  šœtIME×  +.»m¸#IDATHÇÍVÛ¶« ä"üÿ×î$ ¢Åå9ûe—ÕZ Ã0ä†Jc[sÞ¨¯hθsnùUj5qéôª`Yô(«ÿb„'pž 'äº,šõA’¬òÜ­spÌSÜ%ž¶[ã¯CóÊéL¾RRÔ*°4ˆ¦I«Dàc ÂÜ%ðî5á,ú­I4e¥m•ÎyxØX¥,ÞvȤÕún,á ¡E^'_áù\*–v0¢Š8sœ{Œ=U†ø²g™-)5 4UVÖÉÓ¨èBjTXéñîAvqÀ#ÔÐþeÎp$b¼ç`€x «½LðAHCÍ} Ó ®Ž]AcìgÍ 2û•ŠDýP•ÉÎëŽaê¬["N²dßúê\Q¢wŽê Û½— ¶)lÕQ׊ÏËVHRq)£bƒX³Ú…Âo,Ǫ•Í S“¶Âꉓ"ºÑã½¶#ÎËŠ~É‘}ìOl]`«ÔP$-¯ªðüb£¦:U"ìœýòððï÷`9lX^!·’ÿ~œ›o‹åeqêGI¯ÿ¿μö÷+›ýj>ïž¿yc°×¦¿AÔúr«#ÈÒ?IEND®B`‚snd-16.1/pix/hairy5.png0000644000076400007640000037231511147553267013070 0ustar bilbil‰PNG  IHDRR!¸_sRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ8(¸ L IDATxÚìwxÕÙö3»«]­zo–dYro²-Ë ŒÁ¦šn„’!„ )$á äƒxí—jÀtƒ ƸàŠl¹È¶º\Ô»´Ú>ß[<;;»’cŒ3÷u­´;;sæì™Sžû9Ož|òI 4hРAƒ 4hÐ0`ˆZhРAƒ 4hРAÉA¯5 4œ9°X,X­V­!4hРAƒ†3111 HiРAÙŒmÛ¶ñ½ï]‡ävk¡Aƒ 4|ËØ°~-íífòóó5"¥Aƒ g2ŒF#—]z1Ö¾^­14hРAƒ$@§ M_ì6+:Q§GÕsÜnn—AСӇ)ËnC¯ÓÑÝÙÄžýUªçhDJƒ ÎP46µÐÙmQýΠÉˤ5’ „Ýn§­­´´T›šHLH$"Âð½g{G:ŽØ˜íhÐp `2™1Œ ÇÊ“$‰Žö¢£c‰‰‰§«³Iqž(ŠØl6bbâ1DqØí˜L‘þsl6+‚ Ðei#:&6l}4"¥Aƒ g(º{-Ø]" xþ ‚ ÐÝÑAn¶QÔbiÐàƒÅÒÇú 0è ‚@QÑ$ââ<‚PGGk>_Ë÷®»–ºÚÃD™£p8ìlݺ)SŠ‰ŽŽò—Swø0û÷—¡×ÐëuÌ™=ë¤êSº{QQQMÔŽ §»Mõ¸$¹ýfñn·‹òƒ¥8Ž "–“›’„„DoOÕ•eäæ '**«ÕBUÅ~²²‡àr9û­‹F¤4hРá El´™¼¤A@DQðhÓºÚZ­4hPÀívÑÙÙÅÌsf‹ÙICC#¥{öé×b7·4Sàȧ®®Žú†6lØÈ´iSHHHÀÚgÅn³3}ÚTDQÄf³±æóµÄÇÇÓÛÛˤIiin¡×b¡püx6nü’¡C èì꤮î0f³™I'ÈêåæÀƒ>rƒÁÀ„Âñ4·´p¸î¢N$22’¢Iiiiaßþ2$IbÌèѤ§§iUƒ†¶.·K}G ü;P’$ŸLBbJÀ9íí͸e×Fš£IÏÌ¡¦êiÙ4Ö&5}ÑѱX­ý›ØkªL 4h8c!øw Ž¿÷Ó ACœN_—”°ñËMtww³wï>HKMõ Z8N²³³1 Lš4‘¸¸¸€rzz{ùrÓf6oÙŠ[’hoï =-I‚#GŽ’˜˜ÀÑ£Gill¤µµC„’’]$%&ÒÞÖÎÁƒ‡üeµµµ±¿ì……ã‰2G±kW)}}Vº»»?n,GåèÑcìÚ]ŠNÔ!Š"»v—ât:µªACY’p»\?'ÅK’,I’E‘ˆˆˆ€—(ˆHÞÝ($ò%&&Ž„ÄŽÔU›@||"n·ËÃÌúAÐŽTww7»víÒž” 4| hhh8N£d¦|‚H ‰Òx” ª0è L).&.>Žƒ§Ë‰Éh$222hØ ‡t£Ñd&ÃÜsç Š".·NG||†#¸œ.’’’0è ì.ÝCzF:z·[B¯7—7˜¨èhºººp¹<æFf³£ÉHgW'H:½Ž¨¨(QÄétât:Í:’“µ©AC(2%¹Ô6¤ß‘’$ ·"®gÇJò›ËKn7}}ÚZ›HHH¦££…ØøL&ó€êD¤:::¸å–›™1}ªö¤4hРá4ã™<çït8±X,~s>QÏ{‡Ý¡5– *°;lür:ŽY3Ïaذ¡ìÜYBLlL‚9""³9’Ï?_Ëœ9³HJJò×ÕÕÅÊ•«Ñ œwÞ¹Ç5/DQdðà\¾Ú±“ÂÂqÄÇ'PPOeUƒžñãÆùÏMJJ$++“ÏV¯AÔ‰OžLKk+‡ƒÏÖ¬%*ÊÌ AY ”–î¡­­ìAYˆ¢N{ 4%æ¦Z[‚¾ËÎÍ?>F%Éã¥L%"I;M6ku5夤f—@Tt µÕåää ÈòCxòÉ'æ•ÇsÁùó˜\TÈÁC¤¤¤2hÐ $I *Ðívi!z5hРáâÏþ“|k_/½½½ôõõ©Zèt:½þ4høî¡tÏ^¹àüó´ÆÐ a€0šÌ´¶4Ògé ú..>‘>K/1±ñ˜£b9r¸2ˆHét:¢câp¹\DÇÄcµöbéí!:úxt>‹¥N‡Óá 6.eï,eÏþªÏ#eéµ`‹µÑÙÙ‰ÝnÇn·“™™©ÙækøN ³³‹ÊÊJ&Ê~nVß`0xÌ7\.¿MºÑh 8ßf³¡×ëÑétØívDQD¯’àÀƒ{ü´ÔÕÓét"Iƒ»ÝŽ ˆ zlv;znàI‡ÃAÙƒäæäø#UÚÚÚ8v¬ž‘#GœÐ}•°Ùl8paÆáv»ijj"66·$ÑÕÙEvö """´NÚ¢¢¢ˆŠŠÒBƒ†³™Ä+ü²4hÐ==]H’; \¹_ö°öyL÷ŽöfŒÆü¦S¤›Í‚ÍÚ‡(Xz»Îq9AÿÔÐoÔ¾¶¶6HII¡¾¾ž¶¶6ÿÖ·ÒîPƒ†ÿ46»(b2™°Ùlþ¾h00 ¸Ýnúú¬tvvrðP9'NðŸ''G;v|ÍÑcÇ$‰œœlŠ&M¤²²Šýe€… / ¸÷ÊU«=jù|ñÅz²²25j$V«·$a0ÉdÂ`Ðãp8q8ì‚€$yÌ@L&#V«QÔùó—!žéÓ¦òÉ'+˜2e2éiiXm6Àd2!Š"‡»Ý†(ꈌ4Ð×ׇÍf§²²Šä¤$""<á].7Fcz½—Ë…ÕêIVg2™ü¤Çét¢×èìꦪº†aÆaµZýíå#‘F£‘¾>+‚à±36™L33‡»Ý˜LFA$Òl$¶nÛ†Ûå&''›Ý¥{<8×c¢Aƒ ÿÅHNN’´†Ð á`Ðë1Äô¯€0™"UÉ–ò¨“A¿D*!!ÄÄDÒÓÓ©««#""Aèíé!&Ƭ=U § k×®Ãî°Mqq;v|MgW'¢¨#66†Ó§±¿¬ŒÊÊ*¢££ýו”ì`êÔbÿ1^‡92·äÆàÝY*(ÈGEöíÛ¯®Å°XèèèðïZuvu±cÇNƒ°(2󜔕 77‡¶¶vv~ý5ÉÉÉÄÆÆÒÜÜÂùóæ²nýFŒÎàÜ\’’“8x¨œ¶¶v"""hkm£«« ‡ÃA\l;v¹Ir“78üü<6mÞâ'/“&NÄibÆ/‰ó“Æõ¾Äår"¹%˜R<™Í›·`±Xpº\L.*B¶µƒ^Ojj ñ H’DEE%Õ55̘>’’]ØlV\n‰)S&³k×n, ÉÉÉMšHDDå•;zK_Y™™ 6”’’]D 455c4)¯¨Àn·ÓÜÜ¢Ùý‚(b4Fx" iРAƒ N+ú,}ˆ‚øÍˆ”<Š dggÓÓÓƒ^¯'9%›Uó‘Òp:…Kè¨h’““ü¦gÉIÉdç bçίq8TUU3jÔH" 47·0r䈠²œN'‘æÈ¿þ’›Ö>B[{;=½½þ1MŸÕJ}}ÝÝ[ÃY3Ïà“OVPSS‹Íf'=-ÝN|\’$QU]Mjj -­­TTTÔÖæÜ9³éíí¥´tF“‘®®..¾èBöìÝÇ¡Cå$&&ÔâɬX¹Ê_vFz:™™™¬ß°‘‚‚|êaР,:::©­«ÃårÃÌsfàvKÔ>Loo/{öîå‚óçáp:8zìƒeÑÞÞÁ‘ÃGHKM£¸¸Èoæk21™"±;œÔÔÖ1lØPÏo‹'))‘œAÙddf°rÕjΛ;ƒAKa×o_$¸\v­14hРAƒ†ÓŒýû÷0ftáÉ©¸øxš››±Zm*‹¼G“m6i-­á´¡  ›ÍΞ={ü9?"""Љ:(L“ÉDGGg€ÿRcc£§OËü†:;:‰‹ÅívÓÑÙ xò†tw÷àt¹hoï !!>àþ#†£  ŸU«> ¦º††Æ&rss¨¯oð'‚ó!Â(Šèt:rçR²k7ƒçb2714™LÄÆÆRUUÍ93¦£ÓéØ_v€áÆ¢u ZZ[°ôöa41{É_ss ]D™Í˜"MôõõÑÒÒŠÃq<ïHwO'¿‰Á€ÉhD¯×ûMu££¢èèìäèÑ£455£Óëüõ‰ŽŠâà¡CŒ> ½^Obb"ÉIÉ$$ÄÓÒÚŠÑd¤µµ•ššZ dzkW)))ÉDE™éíÕ”+4hРAƒ†³a‰TÚà|z®Ð'D@K§áô¡½­K_C† !55…®®.L&&“‘Œô4DQdâÄ õDª³«…¨hMÓ Aƒ†Ó·Ô¿ßéüùóÉÌÉGà¿c‡ïÝeKµÎ4hРáŒCX"e2™ÈÈH×ZIƒ N¢¢–›OÝDÎ~ÿ©úú&"ŒfÔÌÈKJJÈÉÉñ'‰WâÈ‘#¼òÊ+,Z´HÕ¶]ƒ 4hø) 4hÐpæ"==í¿‚H©¡´´”§Ÿ~šßüæ7ªDª¹¹™+VððÃóÚk¯a0ÈÉÉÑ: 4hЈ” 4h89´´´òñÇ+¹õÖ¾³¿ÁívsÉ%—„ü¾££ƒøxO¸´´4ýDêé§ŸÆb±ÈÚ£…ë®»ŽâââSV?—ÍÆª»ï8&Èþ ²Ï(Þû y_Ê÷¢JyÊ2$ÅÿPç©ë«›¨RO_=Ü*ÿ'þøÇ¤Oš@cI ;ŸÐyËÒy_ Âûßeïõ²ÿòktʆ”Ž×Ç¥xÙñ$fqÅgßË­¨»[å·âùȯK/*"yôhöüßÿ=µ68÷/aÓ£b?Éœ{cn¸œÙ³û=ïà{ïQ¹reÈßñM ©”'¨ô1IÑn¾c“﹇”Ñ£Ùô?ÿCg]]@9b˜¶'L¹Ê²Oÿðº Ya€u’ãU>ÞåcÀDfï+0ée¢¼'ø„¼Q}Û×Áí@/`É}ôxõ6ÏW8Tê®þî0sÑ@æ0BÌaBˆþ¢Þªÿ¥ý èî»I;VµŸÞ~»ÿ}tF³þð‡oHY,~÷»ÇHLL`Ñ¢+ÉÏÏcñâ×¹ôÒ$'{4ƒO<ñ† +`á‹N¨ü¶¶þò—¿ïI¶zã‹ÈÉäÿþÃ?aá‹Y·îK¢¢ÌLž<€¾¾>\.7ÑÑQa˯¯o¤®îS¦LbÏž}DEE1dÈ`þùÏsë­7b63Ÿ0«ÕÊ믿Mcc3é\ýÕÆ óš›[HIIö®¨¨bÏžý\qÅ%š”§Aƒ†S†ÖÖ6âEÑ?ïX­6fÏžá?§««‹Ã‡0bÄ0ÚÚÚýó“r®ò¡½½ƒcÇê=z$ÍÍ-8ÚÛ;È΄N§CÌæH:::‰ŠŠ¢³³“ÆÆ&DQÇȑþÑï*,,¤¼¼ü¤®½÷Þ{>ß~ûíTTTœR"uàÝwÙõï« ™¢ ! '|»SBÑ™™Xš›±45!ªQEÀp«…¢Š`¢}d$ÝõõªDjØÂ…!‰Ô‘M›hÙ¿€äQ£¾]"e·;2d0?ùÉmÇkg£Gð'+øÅ/~Æc=å'R••Õ´¶¶víëëcôèÜ|óõ vyy%))ÉìÛw€… /ÆlŽ$;{ÿš¥Kߣ··— .˜Ë°a!Ëw8”—W0eÊ$**ª1b(­­mLž<‘ˆƒ_Ó¹cG ùùyF\.qq±´µµc6›ý O•(+;Dff?üáM¼ÿþrªªjˆ‹‹¥¡¡ §ÓIqñ$jkóøãç–[n`èÐ|â±ÛíŒ;JFø8|ø(:ŽI“ 9v¬žÞÞ>ÚÛÛ9r111”–îÃjµ’žž@65hРÁ‡5kÖQT4¼¼\^~ùU~ùËûhllbÉ’7xöÙ¿°xñ ì٭ٽ{55µ<ôн´´´ñò˯ððÃ?*÷å—_eèPßÑþýÙ½{/CHHˆgíÚ Ì˜1•¦¦f,˜Ç;ï|Àå—_ÌË/¿ÊÈ‘Ãq»]X,&M*<éßµÿ~***ƒÁÀàÁƒq:Ü|óͼþúëddd°yóf¶oßNCC“'O>­í^ýÙg!5áA$ô@öìÙLûÕ¯(]¼˜]/¼rwKY®.Äq9ÑryßGy˜[Ž;!ÁÑwn{EǶo÷¬aÛ·û…4‚Lɉ‘ÛK€$/Á‘ßW”iñHâ”;N¡ˆ•ÿQ$½¨ 訪¢¯¥% ½]ÀŒ'ž *=WgÍÂm³íPùÚ°«¶–®ÚÚ-ºñC†`NNòî멯'm¼' ¼!*ŠÖ® Ù‡Öÿæ7ÇŸeDß߸qÀ}°øÞ{)V( oÜÈç<0pq{;m^¥…0À~¡¶kàû—›‹h0Ðzð W¼ý6¯ÏKí_ø…sé‰TLNÑéþsœA3fœÔ˜½úý÷)ÿè#Vÿìgt†x¦Òë`ˆŽ&iT`ÇÞÆFzjkqËú³¯/‹€ËN—§ÓF¸@ïQ¾m!k$_çîó¼$¸œ`—‚û¼|Ç6ûâ‹Ù·dIÁ—ÄI ñ{C‘&µ9Í7…?b¥ƒ’LÞy'é“&±æþûéRQ´:Dk~>I#F}÷ƒ;yÍ»‹?dÈ)ëOÊ´oÕªÏéèèäŠ+.eäÈa¸\.V®\Ctt£Fÿ€††&>ùd5£F gïÞ2Ün7£GYþǯäèÑzÿn×+¯¼ÉèÑ#©¬¬Æbéóh1šZزå+î¹çÜn7‹‹¥Ïÿ}(ää ¢®îˆ—ôäŠ+.¡¡¡‘¥KßeÈÁ$''ñúëï‘áñ=xå•7™1c*]]Ý šÏ¶m;˜8q<÷ÜóK~øÃï£×ëyóÍeLšTˆÍf§««§Ó¡ËbéãÕWßâÏ~€%KÞ`òä‰X­6>þxëÖmbêÔ"âyõÕ·7n G#))‘C‡*¹îº+ÿ«Â!kРa`X´èJ{ì)®ºê2?ñ™4©U«>÷Ÿ³cG ½^3£´´Tº»{X¶ìÃånß¾»Ýì"77³9’[nñ(À{ì)&NÏ?þñ/† +@ %%™ÁƒsØ·¯ ½^Oqñ¤oô»,‹Ÿùòjét:n÷špDGGså•W²mÛ6.¹ä¿™ß©FCI ¶Ž…4 QºdI€VVP¥ÖÖF`€ò> üƒüJÚ%!U„·L&sƒæÎ·›²7ÞPÕÄ« VòßµþW¿ 8®ÜQR"ùn’$úì²ö_/*>Ÿê}V{É…H7  ܰm›GÞ¸ùfö¼òJÐs}gá€ßâ:âàÃŒßÿž±ßÿþI÷­¼óÏ'ïüóOyŸÍž9“[¼¿ 8øî»¼{õÕaë ß÷­°dÊò,`ÑŠŒ»õVj¿øBµˆ0ÞsÅ÷ßJÚfèe—ÑQSÃg÷ÜsRu‘#yìXnVì~õ°æž{<•ãK}ÞÏxvª¢$ˆí¸0  ‹]$D¼ZÉ ’Ü6°Ù=S¾W·ì‚—ƒT,Y‚Q1ô·%6j$Ê-›c”;î¡ú‚š™ž¤¨“¼ß$Idb"ù^HÉ¿þ¬4¼ÿ~*W¬à{«W““é„úüœHÍŸ^ÀŽTbbãÆ ­Í°ZÙ´i+===tuu3mZxó‰K/]°#ÕÛkaÞ¼9þàÜsÏ¡²²Ú£E‹Šbòä‰tuuSX8¶ßúO›VÌ¿þµ˜qã<6´ééiŒq|—¬²²šÃ‡=dË'(¼þúÛ'D |˜0a ÌC’$þò—¿ó½ï]M~~žÿ7M`õêµ²uXbÞ¼9´·w°té»$%%pÍ5—û˜Q£†³sg ••Õ$''i‰N5hÐZ8šÏ²eñë_{v–JJJ9p œ-[¶3mZ1EEÈÏìŸßß{ïcÞ9 qØlVuá¥x#F à’Køçf9¦O/fÉ’7¸ãŽ[EÀ¸q£±ÙììÞ½—¬¬Ì“þMEEEÁ 0[æ;üšA,ÖÜwuë×UÈ ôïŸÔYuÿ%5¿¥P£$q¢ŒL逪×^<DzÔ}¤²ÒÈÉ›õ]%IAnä®=ÞÏ‚· "¥F’ÔÚÍ­8ßwΙéרDª?’ 7}ù%‚7ézBAÁY1äœ{n!ðaÓcQ±|ù —9ïï'þ|ò,Yþ@7xð)ý½#¯½–ÌÜÁ–Ün^9ç"“’¸ö㈈‰ ÙŸ|;±¸»jó’ “¼À$ÉfÛqXQ6†|ʇ^!ómTÙd÷ÑyÇ’uAw?DÊc|<‹>ý€/~õ+êÖ¯ôa$ØÜX)Ëv‡™O>¾é¦°Ïà¼'Ÿ$ÿ¢‹Nûø8%[ M|ùå*+«ÉÍÍ!*Ê̲eRZºC‡*HHˆgòä‰ ”Ejjr¿¶ñÛ¶íÄhôd¯Ÿ;w±±±,]úÝÝÝþ§eË>¢¤d7UU5 2˜¤¤D¶mÛA]Ý.¾x>ii)¡µs>¹? + !’Ê7þLn ÿ 9÷/ñ_óRa!öžVÜq]55ª»ÝjäHY¶»……[eT^3ýᇵhQPŸ:ž|òÉ€º>|˜ ΟÇä¢Blöegþ0·›žž^ÔO™ IDATbcW¶¯¯úúF/A„^¯§ººI’HJJ$..–¦¦fzzz1™Ldf†î N§‹ººÃþÏé¸Ýn›ˆ‰‰F¯×“OUUW Hò×¥¾¾A¸½½ƒ„©GOOMM-~’%IPSSë™SSˆŽŽòŸ/¿.êëéëëÃl6“žžÊc=Åõ×_ƒÛífÈÁÞß餮îii©DE™9z´›ÍFLL4))ÉtttÒÖÖŽ(Š œp_ßûÇâp8ˆ‹‹%))Q“5h8 ðØcãîŸÞ‹ÝnÅ.W`®¨;?»îú)ƒç‘—pÖ·GIÉ6lÚM„ÎÍ¢Eß#11ù”ßãöÛogΜ9\ýõ¾¦«®Žü#•Ÿ|BOCCX"¥|ÊÊ'$D&%1ìòË©üäzLóÔÌú”^9‘òù'É8èP÷MPû¬\§— €‘©©DDGÓÛЀËb 0ëóiÑå~Ròûû|8|~M6ÙoP/7êf?±ÙÙÞv»^~YÕ‡ŸwvbŒ :ÞV^ΖÇ`ö£‘¡MF'‰ >ιPy_ßûìì,m6Ò á¿’$±woÙYÿ;›š[¾•û¶•—SµbÅñuA§cÒ]wù?ÇæäpñK/±ãÙgi«¨ íàAªV­R áÃ5+IŒ>2’´qã8¼~=½„[®<Rš×ÉÉËɘZÙJ“8e]•»SÐ×Ô„¥©É/X…sXeæã«ƒOàSjÓ}õ‰ÏÏgÈÅË%/¾HÍÚµaI@É /0å¿2‡O:”‹_zI›XNNeD´³½ôûÞxƒo¸É«ˆuÝuþ -UŸ~ŠŽãA(”>†jf½r%‡o7J 0žZ`ßKo4’:nG·nÅg‡àìé¡Kf• æ;.ä½Ú¸÷}Ÿ0|8çüþ÷4íÙƒ]aù`kkc¯×ÔX ™S¦œ1ãõ„‰TQÑDÆô‡ŠŒŒòûÞ|3€HÙººˆˆ‰¡è§?=¾&zsE­ò’¬P‘Ç’Ňî#GX}Ï=ABS¨¨{òÏr¥¾ÜMpHæPe+M”/e8ãP>¡Lv|ß©Es+ˆ”ü¿Îdbæï~G¤7óÖ'žÀe³©úª)±ö¡‡(þùÏ4Sx ß2†\pÿ}LNóžy€Ë–qèÓOýDH쇡2¾ÔÒø|• ŸâÃÚÜÌo A/×áÌüäs‚Ád¢£ºšˆèh"¢£É™=›AÓ=.7-û÷³' ‘’·ÝwŽHÿ± FÕ¼K§ ž°åÿÉòMÚì Aƒ†ÿ8:Zi°Ÿ¶ûõôôbˆÊÂim!*òôE­¯o:ímÛ^^Ρ?D$É#&H.ë~˜èÌLÆÿàA×Ô¨„°Vp¦Ó¡“­q“ï½—Ù>гÏãÿûé̾×_"PBˆr}‰h4z|¼ Ã…V«£âšpÑð|åÉÍ’ÔòQéÊG˜|¦‚Ný5”„LÐé訮ÆÒÒâ'Ry¤ßg*êõÝ}7ç=õÔYœIr»qZ­ˆŠ~¥áÌGdr2¿r‡XqõÕüÊíæù!C訩‘MïÆ…¸¬Vp»ƒ;¸¾2r§Üw1T@¥ÒÇ=EÄÀƒÑ@óîÝ4î>ná6ó‘GH+ôl¤Ä Ì÷7làÕY³‚®Ÿ|Ï=Løáï‘êè줩¹Iëí4hÐpš  ÑâzªÐØØD—ÕN¤ÑHzzòi»ï·A¤†,XÀ/z{yaذ §ùžcÇx¢+¥@!• ,àZY”3‡ÅBOCÏfe á‚K( K_—ÍÆÇ7Ü€žÀÐæ¾÷.‚}žäf?r? ¥/…;¹ÐyŸ|&…¨‡>÷í>Ù9îÓ!ßíRû½CæÍ㺕+Oø™Ž¼öZfýñg]„Û#›6ñê¬Y ¿òJ®z÷]mýŽ!T©>ÈÊŸüÄß÷£RSùÑž=þsÞ½òJ`¥Ã7fä DÅܤ¦ÜT(òüjòax®¹P9¦äØø‡?°qf¡_=ó ºˆ¦þâDDG£?…Vq§œHeff ’ÖÓ5hРá4!VÅþ»ŽÒÒ}Ô×70þy!Ïéìì".îÌúí³}[W+î¼ÉåÐu¡"óßwC¼!Ÿ}ØùÜs¬}è!¿°á#ó… þÑÕWÁå>"„‚xùÌé2§L!ièPö¿ö.ÔwÜ Ò¥SŠä/âe}§Œö§4ësCæÏgøUWq`Ù2ª9aò/¼p@BŠvÚ÷ÆD&&rÁ³ÏžUc+aèP.zñÅS\÷œÙ³¹èEYówߥjÕ*žö~P¹beøÂ…\|1{^{#6øÍùäÊ5ßHyà¥"H¹#>æÆi+/çØ¶mþ]i_rçÌa´7p¯Þ¡Ò?¨%%5§Ê±õ‰'ØúÄÌî¹ßÕ3ŽHiРAƒ†ïªªjèë³’Off:--­466£×ë>|(ÍÍ­¤¤xÌ¢|ïËË«°Ûí$''ú“òÍÍ­45–EUU yy¹˜Í‘DFFúóöI’Dss ÍÍ­DDD0tèêêóÔSÿäöÛo¡  ï?jÞ}"é « žœ0’ÛMéâÅT¯YsRå5íÞMocc@Þ¢–²² Ó¥9_¹VÔrE‰„ö{’ï$Y$)ˆ¨©i§å¦|zy’'ÝÕ+™2‘®‹Ð~T"Ðuø0µëÖù#‡ÉQ±|9Ƕo8æöæ{ ”ÃWvÕêÕ|xà žçÍ…*I=O7ö¿õå}öœÿü'Æ ¥£ÓÓ)üÑ´Iï,Dò¨Q$xPxCÇCè] 謩¡vÝ:z ™@ͤW>ç¨í8É(‡Ñ×Ô¤Jĺ¥vÝ:ðŽåpuígŽHù•tK–pD–ƒlÆo~6üü·J¤DQ‡Ûí¢¯ÏFdäÉ/r:Aµ¢Aƒ !æÚo‚Ý»÷òÕW_“’’L{{×^{9mmíTTTaµZ©­=Lee5×]wz½Ž¥KßeÒ¤ñTVVË,硇îE¯Øòpë­wò£Ýâ/[§Ó±~ý&&M*dÓ¦­Ü~û-ÔÖÖ±aÃ&þøÇ_ãt:ùÁîâG?º…®®.šššÑéDÚÚÚ¨¨¨"'gÐC¤äuÝu€'DoSM¥¥Aç˜SRBæ²÷öªúQÉ P¨à½.‰R0A…ɵÎ]55þ\0 ™On (âÔ«ËÃ4«™*£‹9 öÍhÝ¿ŸæýûUÛª?*y°´:DÛ!OÔ^]D︂! |k}ªìí·ÙðÛߪæ\ò!uüxÜÜ Õpvbÿ[oqðý÷Cösåñ¦Ý»iÚ½;`>PŽ?_N&µ°åj‘ù”»E Û·í\ùÞ·•—ûû´Ú|ÔßøUKR õ;vP¿c‡ÿ³)!ùÏ=wf)W„«­ºæfróÒ$£ûÄüÈÈD - ƒ 4¨!"â›EùÌÎÎbݺ/ij*#55½ÞÀ먮®¥·×ÂàÁÙ\tÑ|úéjbb¢9÷Ü™”•¤¤dÉɉÔÕ9¡ûMŸ>…… /¢¹¹…>ø„3¦0qâx.¼ˆêjO>¾yóæ°}ûNÿ5³gŸÃÂ…Q^^É®]{¸æšËY»v žÞ¬ô=ö%%%Ì™3g@×L}ðAF_=ÝtSÐw—\”ûïW½îØöí,™2%H@Q¾•ß)T<)qB\'E¦¤2f G·lÁmµªšÝH¢ç‡2x_Fw¤ä÷—ïB©%u‡ iòúGÄÄQTäžìÝÝAuú!WòvsÙíÔ®_ÿ­)§Í¦J¢Ò 1%xrÄ-|í5P ÿ}è:|˜ª•+U‰‰ZŸÂ8næ+ÛjyåA¦äÇ”þR’JÙjÇÃA9·¥)18Ojݺuþ@@rø%g$‘úÚ½‡Ã eÒ!ºË:™;%K^G¯×c2™p¹\8¢££IHˆÃl6O{{;©©)AaÇ5hРAéEggi˜Í‘”•¢¯¯êêZÆMy¹'Ç]nn6«W¯¥³³‹Ë.»ˆÎÎN&MO\\,W\qÉ€w£6oÞÆòå+±Z­ää†c÷åüâ‹8PNYÙA †¨–Çòå+1 a}©N%öF~ª‘GÆb ↻KA(â. e9™”$J†]Y–È<ç®zï=þßàÁôÔÖªúN¨™þÈw¡ ^BA _”29°œ@Ɇúv¦B‘DßçÄ‚›/.*¢~çNUl ~eû^{sÿüçom¬Ž¹á>V!äç=ù$ƒÏ;O›Ì4PöÖ[”.Y2 sÅ~ȉKå|Ÿo“¨øÜ_Î:icLís¸ùNíš¹ý+y*¡Î7qÙígÄ3ðji“ìt¹»Ž³¾îVlFÝÝ=ÄÆÆššFee¢(’ššN__$''a±ô2x°úâYQQAnn.ƒ€;wÒØØÈEy4“ ¬_¿ž /¼ÐlÙ2FÅ(¯íèÖ­[éîîæüóÏW½‡ÛíæwÞaÒ¤Ih#Sƒ g-òòrq¹\X,}Ž#..–Ûn»‰††&ŠŠ&áI_qã×âtz–Ö3¦’œœ„ÍfH>LŸ>…œœlôz£FÀjµ1hPfÀ9™™é<ðÀÝÄÇÇ£×ë¹å#rNN¶?QûM7]GUU-Æ}st{e¥ß7Âûòô' (µÐj‰9ÃÝÃpxíZO_}½ª_•2ŸïÒË•ÜgÊ¿ö*ˆ“òå#RY³fqÁ³Ïòö%—Щâ7x0—¿õ–ÿóÂ7ßäÀ²e¬S„@E˜B¡§±‘ò?f襗~+ýBEn“…ö+† Ñ&2 Œ½ùf:ª«Ùùÿþ_@ ¹©žÚ|àÛ=ºü­·H1€×fÎÄÑÕD¤•¹@-Ü2ûœs˜ÿÏöû{Vß}7u6øëÛVÜqW½÷ž?,º?رCuG*":úÌ%Raµs1±ØíVÌf3‹Å<11Ir…Ôn–——óàƒ²xñbâããÙ¶mdffòÖ[o1gÎÖ¬YôiÓxçwX´ho¾ù&³gϦ¬¬ I’hiiÁårÏ|Àå—_tŸ^xùóç³k×.$IbèСÚèÔ AÃY å®OjjŠŸ°ø L¤>|øÉÍ‹ãÇñ’O®>O¾¾Ðe§¤x§ËóFGG”s¶`ݯÍÞW_õNNPðW árJ)} BGçpvvÒêõõR3”ïFùˆ’|×Iî%¦ŒÈ'o.'P>áìØŽ,»òJºÔ ÏÑ£¼¥ˆÖ§4íÐGF2ú{ß :ÞQ]Mí_·­ÃÁæÇûÖˆ@ê¸qÚ„¥!$Ì)) ™?[W{e jÝ*s‚š «Ÿÿüçþ|c¶žž€ /jDJmWÛ­2wEÄÆ¨/¿òJ (ÿøc,ÍÍý†O郞æíK.AïÍÑzÓ¦MD¥¥‘2vìóŒN ‘ŠÇjµMOOwQŒA§‘$7éé©ôy“ ÊQWWÇܹs?àÏ?÷›Z|úé§ 4ˆììlòóóÙºu+­­­4773lØ0²²²x饗èííõ_óÙgŸ©©ŽŽòóó1™L¬Y³ÆO¤Þ{ï=Ž=pîäÉ“™:uê)mäÒ%K&ýP6­¡:SwB˜rÔ®í/²‘Ò¼Cm1–Âh)2§L!³¸k{»ð˨ÚB,×pÊ£@É5¡:å—Ž×ÇWß-©«tlv)òp/µ¶VšÈ˜’’QT®\I»Ì=\=ú3MBÁ‚b e/Ç®]kIbïÞ²Ó¶Xtww“œ9’îînöî=žë*77ç?Zææ–ï¤äv8øú…¨ýâ ÕèsýõcŸÐ-Ë/Pòüó¸ÎÏõJÿ5ÕÏM`^(µäžrÁÎ7;DJæ\~§ÅBGe¥rZ÷ÃåpÐîý>tSî»ÙúSÐw _Mé’%4•–R·~½Gø1™(üшJKCƒ†3C/»Œ¼ .ðûÍ)ÑvèÕýDôóë>rÄ?¾Ò'NdÐŒ¸ìvvýë_9çB)mBÉ£55T®XÑoz‚É÷ÜÀ’)S°47‡5Éõ¯=^9=iäH?¡:“0`"•ÐCt¥Ö–.’SâH3ä…$çÆžÏ:ž/¿Üâoò©S§•yÞyçqàÀoíÇ/X°—,Î?ÿùO–/_~J‰Tó¾}¬¹ï>¬þcj!nÕ²×+µƒn•Î+7¥Â2T”'¥æS¹ˆêB,šì0ìû<ëð©C|ÀêŸý AA˜"¼B£0‘Þ—IF¨|æ#JÒ%ÈFH’çþr§°y_¾÷}Þÿ>í¨]eQ—¿Ç'88UÚL~ndz:︂¯Ÿ>d¾å3l()¡ö‹/è/¦ìí·Uë¢fVÕ_}$å„ÜÇÄ Äx_q@gòÀ’Ý&¤ä—˜uÚæË @§7 ¹3p»O_±ŒÁe‡^üÎ ?›ÿüg6<òÈ€S¨ãE?û9³gÛýò˸œÎ&ï’¢‡S Ƀ?¨Et)>+“+M÷ì²µÂb­h;…$RF£*‰ò Œé'²ã¹çüDÊ`6sÁ?þ¡Ié¾ЛL!ûëê»ï¦jÕª  Êy@é7iˆŠ":3—Õ’$ PZ @ËþýìþßÿPž·Îššò@ÇzVq1Ƹ¸3ïÙ ôÄ ™ãŸÍ²ZFö„w­©©###“²²@2d4F2zô(¦O÷»ÝŽšœÕjÅápøÿO™2…­[·’““Cjj*999¬_¿ž¾¾>º»»‰'22’®®.¶oßδiÓhnn¦¤¤„øøxrrrüe?ýôÓüð‡?$&&½^O__%%%L˜0ÁŽÙl¨Édòï¨*Ôõ•ŸD‰!ˆŒ¨"܆²“Ϙ6ë?ûŒò>âCo³pŸb@…2ãp‚N‡¨Óùss D˜•Ÿãv:qzw «×¬ Ò¾«ÙÕK²X¾HËIœNFì| $'=-¨]öÞG¬ädK4™·Ó‰äpÀ.à²÷ß'ïüóyåœshÞµ+¤3§¥¡’çŸW Ý)êõˆCзéRÏ ôšXÝqà1ƒ©’qy´/€íÝKBˆ0ËJŒ½ñFÆÈü3|訮æß'²=.I8­Ö % 9jïõ‘‘LøñqZ­\úÊ+¸l6ÊÞy'h²ÈD+‚·fþîwß{ïIÙË—.¥ø¾ûxmÎ\6[Ð3¨ …ÿ;A@§Ð¢¹Ýnl6›ßÉÞ×ßœ^Â?t´&Òpúœm{zz1Deá´¶yúRÖ×7}焷áJ¢tF#‚:>VLf&wÈ¢N©{[{û“¯ïè""tžýú[¶l!eìXÜN'n‡ƒMú[þüç°Äe ,ÔrJùæ^Ÿí²¹Ü77Ë šè­¯Ëf·[Uë­W˜ŸúΗdçûæ×s~÷»þ•OwÝŤŸüD“Ê5œðeZ…PdJT(ToÜÈáC*e/àZ— I’„ð’A{U–ÖVô‘‘'IýÞGo21ý׿>3Iî7-Àét2eJàN|¼Ç7ª««Ý¿K’ŽŒŒÀ†K—.E’$Þ|óM¦M›ÆyçÇÚµkY½z5·Ýv›G š9“^x›nº‰¸¸8î»ï>ž{î9Š‹‹)öîz¬X±‚pã7úËŽ‹‹Cô.B?ÿùÏùÇ?þÁܹs÷²G¶÷ôø…L¥V2”VOM‹ï#ˆŠ@ý–-<åu¦Ó)ÊU@%¹C,¢òÈJy ñÅ|ö“Ÿ„¬¯; AÛüè£l~ôÑãÂÇMõä/Q6P@¯B tÊê%*‰êDJ¹;&_¼ÕLûîÜ»—„ü|¶<þ8_üò—A¿iÙW’Äþ(•cSxàE†J;–e¾‡' APØòóO¨ÜÖ²2þ5jTH¿Q¥ï…k#g_ODE›“ÃOkk™úÐC”½ó΀ÊPÃø›o梗^úÆcY²¦NeÑòå¼qþù'U—ÅRl,?—íHû K½ÁqlÞ6±Ù8ÒÓOŸYRcc]V;‘F#ééɧí¾ß&‘²¶·ûsøÌf å[(lùë_U_»|9yóæt}úZ[ÙöÔSAǯxûm†-\pì«gžaíƒÍPI/•Ê]%š|'_-*ŸM6«íúÏ{üqÆx×ë÷®ºŠº TI§ÚüôÚìÙçÝ}7óþö·o4jÐð]ÄÒ /Tõý ·Ó+—5Õd©PëzØaå½çÁ÷ß§~ûvâóóÃΙƒçÎõíÿ——GǬrnÞ²…Ä34¾Á7&R11147:ˆ;vŒ‘#Gô{í-·ÜtLî3››Ë}÷Ýpì§?ýiÀç U¶o½õÖã²NTÆ©ÆÚäëçŸÙi!¼Ÿ2Ñb(áM6W­,¹™…Üa8”‰ž²ì#Ÿ|ÂÑO>!‚`?¥þ©ZyálëÝŠ…Ögrgó •6ïyÊ,6Ãs†h7·Êù1y2æþùóY÷ðÚNµÉi õ9¿û1^߆“1/;•‘Á…ÿú—êwÕŸ}ÆeËN¸Ì‘×\Ã0¯_c\NNÈò_$¢S…¤‘#Oª>~÷;z™÷÷¿c0›Ñy£ä©õ'ÁG¦ 8Ý]7oÞÆôéSN/A±ÚØ·¯ŒI“Îì±±dÊþ–™¿ÿ=3Uv™ÂöïE‹,[Ó’GŽüFõù׈XZŽûŒE&'3çORc¶?ýtÀ<.1¦rÍp+qÊÝ(lΖ+ã|Ê*‡âóùO=…!*ŠO︀5÷ÝÇš~ÖäùÏ>«z|Ê0Z¶Ã®kР!p«™Ÿ‡ÊéJâ™rÿý$î¿nÍ`ïîI¬|å-‘¹ÆÌ|äfþþ÷aë<ç±Ç°©ŽQ"6;ûŒmw½Öõ¾aÇu:ùø–[¨ß¾=¨S…#ORA]-{½Òi8!ƒÀˆjöñrrCˆ{‚¤©mû®Í¿ôRF-Zľ7Þ êÓOƒvÌDÔ³ÝC`€7!>}ß¹U4(ò>ëœs˜à]¬—ßz+’ÃÐÖ¾ëgþþ÷äwFoHý´ÂB.{õUì==¬øñSdæä“Ë}–ñŘâãϪ¾nŠgÂí·«~—=s&Ã^v<÷G·nU=ÿâ—^Bo2‘>i’Ÿ™SRB–ÿm &+ë¤ê‘½«‹×\’D¥ŒÃÂ×^ã‹_þ’î#G„ÒSé}ÔÒÒJrr--­¸Ýnt:II‰Øl6:;»Ì›;::±Ûí$%%¢ÓéNê~‡ƒöö"#MÄÄÄÐÓÓƒÅÒG||´¶¶áv»‰‰‰ ¨#@rò™—tô¼'Ÿô J€ÀþÙ½÷bii¡yï^F^{-³þð’†?%ŠºîcÇ‚cLŒj­Û°k{{XÜpþÊRʵG9wK¨ïñ±Ã[¶¨Ž!Lj¿ø‚Z¯?ÀäŸýŒÌââo5ž gf<ü0…?üaÐñ²eË(ÿàƒ°A#ä®—ýßÿ_·Ÿ}–£Û¶QpÉ%äž{®,º½®¡ÌÕpð½÷h«¨`ÜÍ7“"=Ñ(•(›ß5hDê›B’h?t[ggÈ¢?- Çû÷\(QTDgm-–¦¦m PÖG¾C5ÅÕW/!éó×zàeË–Ñêµó—úY4å/—‚ùê)ÆçDÝVßW^[m-.àÀ²e8Uv—|ç™?Ÿ,EP‘Ñ×_­³“Ý^ó°a ú' á‘d„±ìß·´ IDAT .8—¦¦ìv;K™™,_¾Š)SŠüDêØ±¿_ªÝî 33ýÌz–—]t¬¯µ•O¼¦çAm¿z5¯ÉŠ(Š'M¢¶>ñG6oö®ùüó pß±99A»1_üò—´û\¾þšÔ±c1DE7ÆÅq‹âyk89ÌùÓŸ D- \þæ›T|ò ï^y¥'K»(ý0a˜>} £F §·×ÂþýˆfäH_QQɱc ¤§§‘œœÈÆ[ÈÊÊ8á])›ÍÎСC9r8#G§ºº–íÛw’››Í¾}¸ôÒ4†ˆC±Zm:TÁœ9ç°nÝ—g‘R×IôÔ×slÛ¶°çµ”•Ñ}äˆj5´WVÒUWçy&Ÿ|â. Sî¿ßJ؇Ã6pdËUË5"•>i±±Û²·WPRË##_3D•õJÍ'U©¸ˆYt(çvÖáü ˆÎÈ8k•14„[öí£×«\¯X¾œÖ²² ñ"Zaî¿‚w>«ÉK>ìè¦M¡ç@Ùû”1cü„  §¡! >Ð\ZJSi)iãÆyÖ9¹R13ó”ìÚkDêL%Q ¥ÿ÷¬ºë®€ã½ø"Ñ Y°Ñ›l¸øÞ{)¾÷^ÊÞy‡÷¯½V5ò!ˆS(6ïv8x}îÜ QT¹.T"FQå%×H8 3­–D©q”¿”Ñ ÔÂQ‹ý)ùŽ“ü¿2\®Ü М˜ÈÂ×_':#Ã#D|ù%~ï{ì}ýõ~Ÿíª»î"{æLRÏ ¤nþ;Qà5ímjB4™qõÕ߸̊Š*,KPb^º»{8x°œÄDO ŒŒ4ÚÚÚimm%'g?PÏ7ARR"ÅÅ“p:Œ?£ÑHee5ÉÉIääxÈbAÁ**ªüï¿ 0''sÙ+¯ðB?‹¿ÓjåÀ»ï‘5ÕZVÆîÅ‹9øÞ{A߇ŠäÚ²?Ë—ëko˜ÇÃ¥Õp£o¼‘Ä‚–ÿð‡X­VÕ¨¯jÉ9•J6g"ÕI‚ðþ§j&ñ+î¸I’ˆI4cFÈü;¾}Þ¸sj*íååäÍŸOWm- Zõµ4ïÙt|Ë_ÿê¶'—é”AÍDBGo–[ûÈÇr¨”%¡Æï¬Gõ›õ÷Ô׳õ‰'üDJi&¼ñ„?þ1àú!óçSä{4bÄwòÙkD* zƒHÀ§^›ôŸwtÅ´÷埡’¤<ž3kÈœkK/fûÓO ŒþH™<÷G¨kä„$Ü¢¥Ô^¸C*_™¢b€D;¢\ŒGØS³»—ð$–;²y3#®º ðø'ø¶¥Ã!³¸˜‹þýï36Œ†ÿ>ÜðŸNAàßüÊÊËË%*Ê£©OMõh GòýFcùùyŒ;šŽŽL&£?Є(ŠØl6RR’O*²™¯lbccèíµ ÷*œ,˜‡ÛíÆd2úM455Ôõ»€¸Ü\òÎ?_5ѵqŒ Š ß}—µ=vVKYQòâ‹”¼ø¢ª€¤æO«œs À²€bˆó„•B±¦Ìwx"i®ýøcbsrؽx1_ÉÖ?µrVÞy瀞ÕÍ›7“5mš6Éœ¡øìÞ{²`›{ŒûZ[){ûm¦?ü°Ö0@å§Ÿ²R®_>t„ö›WÛV˧ 8!(U¨ä»…·ÝÆ.•¹G6mbûßÿDêÂ)SªV­¢Ê›Lxöÿü3ÎÐç‘:IÄĬ¸ãjÖ¬ úþå ‚ò|ô66,¡|¢b â†uëüŸ f3ѼqÞytÖÖbíèPÕ*ª%Ñ•é¿ý-ƒçÎåsÏõ›b¸Dþ_–Ögî*(„ZT'å.˜/Êž(+Oþ(€r’*”|Q–ßÃ÷9:#ƒïoÜHtú‰™¥rÕûïãµµ?[`íè`qQ ùù\'Ëp®á»äQ£Žø†DJ”ø>ëõz=Úyeèô„„oE^¶111%RR’û­ëéÄc=@II sæÌðuÝõõݲ%ì9EwÝ…9Lråï¾Ë=”gP)4 4Z¨š6Zì‡È(£õ©ŠÐ.YR¬9Ò†áü£äëÚê»îBg0`í膤fš*p“ò~ï]{-z£‘W_͹ù‹jWýô§T­\9 gŸ8|8‹>ùD›´N®þðC f3¥‹³¸¨Èã§ü¿ÿëÿþügž¡àâ‹ÿëÚåàûï³á‘GT#5ËskªwÞÉVÊPÊDÝJŸIåùãn¾™¿ý-¦„Æ|ÿû¼6{6«î¼“µ<€€Ç&\0´ps‚lÿÛß8ôá‡Üªp¯¨[·.¤_jTZ7…1CÔˆÔ· Ñ` !?ŸQ×^ëw¤ßÿæ›þð³ÕÕýjÙÔ—ìY³+éÒÓÓÛ³§&Ås“ø–bî ïv+€ÔÑï¿Gê˜1 •½n²Ö¬½¦Õyyh;bÄ%)zŒ°R$ ‹ßÒ_’ñØM0 4yžÁbAh‹¨½p§–.Uàè9 # }_èd¶¶V1¾|‰½ª {÷6©¿’ô_ð¡9sp~Ǹl6uÇ×é 7›5fz™+V “¾£c,¤œF'ÔŠC÷Uô`çY þå—ªÅS‹pB €’žø®'¸è¤6Y±õä +?yRsq;³l™&3Ÿ7ÅD€'¹›l7¬ukt¸ï¾ëÖ§JOœÀÖ×^Ùßך@ªIþ÷¤²ô<,ÆkW¾·®¶Æ x¸êKpí–Ž¢Ââëò|Ýv;.ìÞí·‚ x˜VuF# /užÀó(eÌic ðyov¼ù&ºMžŒã?þˆÒ'˜!5œ†!KºOýÕSë ]@ÞÇýéÍf@ ]ÛgÌPÙt €GçײB9 Àä ìéôzèL&<[PÅHÛ£^q:±`Ð ä72L¨$#Ûßx=¦NmRW@tz=þ.FåTfg£èÐ!´ý …öß±vïFóîÝa0›eB²F(½à8ÙøÀ1t-´5y4w—”JÏ}Žt —¤ƒ8-â|Å Ö"§a)š\cÌ5¼ ct¤ïÁqqh?n·[aiR×X¾úê+”––bçÎèÞ½»_çô˜:=¦NÅÇqq\.ž½{cœ†wÁQ[‹ÿ9Ø•çµ\¢Z{ýY€5½Yz=,°WWCp84k{°Î—F£ø1£!„ÏÀH<ÔìNÞ’”UVQŽC`3OáN{M Üv;Œj,Ö‚›³aÚwI öWD!ÎÎF&£¿ƒ‚`iöG.X€VÈáh’ÿ ‰‹½v¡œ/£ºÞ³q±Qÿß)GM¶ ?Œ’ãǽih¡ëĉ¸ƒA…`#Œ´ÊòÐ΃¥ÅZR‚÷úo-‚ Nc.(%mçÁöhéûµÖ¥{~ùõååX9a‚Jic…$é©ßKç㲘½­‡,éüÈ#NäÞÈí¸Ý°UT `ÏžFƒ(hク{Ñ¢k>ö¥ûÖc`à_–^Ê=HIù˱¸Ý:kÖi'åÎ;kAb<Ò†jÚhM'=¡‹™D€Ä2È Œ5¶è¹Š%Òt 0åfè“Þô`ÚÈÂÁÃø~P†Ï‹¶£FÉû-*ƒIºŠ2Edáûè£PZÚ¸xüç /oÂ`t-Ö<-d/–::•‡º mxJ ž8u ?ßy'r׬Q,ì: ¢c€(“¤HÅŠÓ•ÜÌNÑB"åE¹¡f¤¯ÁdÂó%žüŒ<‚c?ü zNÞbûYVËô¹sqëÀz]ú_ʈˆlÛe§N)¶~çÜðÌ3M´Iþô²f͸ãµ5~þüEày7&LÐf¯«ªªFXXèõÿ S§¢€È;‚0Ñ%¾$<) w|ù¥üý®]8:ožŠõ”÷bDS(ð÷݇¤!C‡>ÿ¥Gލî‰ÅÀ¥n㢋øë«&}oKFŽTyÄè|Y–%]º_‰tHZ?LÍ›£ëäÉØñöÛŠ°uòú©£G˹Jésç¢pÿ~ù~ú¿þ:’n¹…ù^ÊϞŗiiÞ%‹C?þ˜¹ïz.ÏÌÄ—^™ú¿þº.×$=ù¾o_Ô0#•ÀVd¸mqŠÇ¸¡ô<Ñ^j=Ø Ítž•4G¸¨9…—tmSÁÏßÍbdéÆô1«&OBŠ)Ç#ªcÇ¿ªªªBNŽ’t!))¹i0µx«‰ÝeŸÞÎùXä?€…4˜¬……X9~ïûô²e¨ÌÎfîkÞ£zOŸÞèë¯î9Ô—•iîêØý Û$©)(@mAr6n”ëFÕjF‘ýŸ6N舱HŽA²¤ y.«¾(©³Ñ$`¸2GE¡÷ßþ†ÍDéhk†áIº¾ ŽXº(ipÑQéëlzåXÂÂ|ûí*ÝîÌï¿£ὺî@*//ááÊZJ,ŠÛÿuÉ\±G¾ýV‘×ãm>¬‘¬]Ðø_瀹ª«qR,bË¢<'A¹ðъ·" 5ºÄ…‘¤8'©Îyöº:œX²5š`èäâÅ8I0îÙEê`ZbºwWÅ&»l6U¨Ž$;Þx|PEg­¤í]w5 ’&¹$ÉÍ=‚‚"X,f8NÔ×Û‘›{-ZÄ"=ýFŒ†òò HUUUcïÞƒHLô°eíÝ{=ztÅž=ûѶmÔÖÖ"!!ååò‡¤¾ýö´i“Œ]»KcP’Š^”‹‡w»™L©äߊ³gQqö,³mKDŠUmw;*CÏãáIIhqã UtàŠ`*Eô@éÑ£r;&âÇ HüßD:)¬OòH9\;H˸t«N¢ôÉÝ´‰©”qþ¬Ç‚€¬µka‰Œ¼ä~Ó¥ 4ÎçÝnìÝ‹„~ýämô•ùûï°•—û¥dú£œÖ©Èšô&r‰Ú–’œ]¹Rað–Il-)Qê9:"RRÞºõÿQ’£¶åg΀ÓéäZq’¾Q°w/A@ɱc°WW£äøq8­VFEɹЭ‡ CTûöØÿÑG¨ÊÉAMN³Ö›VŸcÜJ:'Ž;JïgE¼%¢ §x¬ËjÅùe¯’%2n‡.±,„/Ò38¢XåÌaaˆy’n¹7QÑJ.› öÊJ„%%]Ñwݤ®²ämÝŠ¥ãÆÁZ\¬9QûÚÞëùç=58ù®W/ŠÖHÀ]| Ð.vH‡j„…(sSmsˆrR@Š.¶KWÕöçyø’Ñ‹©@„''ã¡Í›‘³iñò÷üúk£ û6I“ü¥uëV8w.:-Zxút`` úõë¼¼| àQÖjjj‘””èQò¨‚¸­Z%6(Qg³ávó Fd¤²`¯ÉdªUëpñ¢'Œ*-­­\Ô·gÏî"pÚ‡Ó§3qäÈqtíÚ }ûöF—.`4qÛmCäë¯Zµ<Ï#66={vGdd8î¾{8,ó5}~e§NaÅ#`ð;ï(æ^ô,ô~é%D¤¤àÜúõòìØ ²àc®£Ã©ó6l@Þ† 0Ûi0¥U|W2~¡ 2Céub•ª =E4Yw vþë_hÖ¡:Þ?¶ŠÊ·¤,"x  ºPö̪”ôÝ%)râ±$˜óf¼_ $ý믑þõ¥Sðø÷¿Û³'sŸËfÃê)S0’È÷->r[þñF]ãrmn‡?ìõ]#ïãôÒ¥8½t):÷ßhÞ­Bâ¯lÙ†Ò'P[T$ç þ¤2;ëž~‹¹›7ËÛŸ+*ÂÏwÞ ÞíF©S‘óÇh=t(ÊNBêèÑè'Ö¶€ªÜ\ô~é%düôNää0KÆÐ¥dXï‚UÚ€UB‡œHff”¡td”’äéINF}y9ª) å­ Œ¹ŠIØyWZ¿-ºcGõz>u壚€ÔU–µÓ¦©@”?ß#;vÀ  Ö‘2jáB,ºývTfg3Ûüî»hC0De¯_Í/¿¬*¨+xR¾>´5ÒM ‰jÓ›‘÷1_ÊÂ2b‚ââ¼ÓâÆ19=]þÕŠÚ$] F—.`*(HÍÖ%…òÀÀýe”IôÆöë×[q¼ÙlÆàÁ7Ë`çâEå<öØcãqþüôìÙ :‘‘ÈÈð¦XÄó¢0}úÓ2›<ùaAO°)=ôÐ8œ9smÚ´Fpp""ÂQ_oW…Œ_m‘€Cé±cøeÄæü䨭Åâ#ÐïÕW±kæLˆÒù˜çYÖÔ.&àÆçŸ÷‘™3qrñbMÆRqtQï€V°x@É—ø|1nûç?}¶±xĈ?åür)…™i9¾`Ž/X9>:=üð½Çôo¾Á©%Kðtnî_bÎî:y2ºNœˆÀ¨(t{üq˜‚‚à²ÛaSÎyY«Wcí“Oª<Í,ƒÀÐçÈEžs æÖûÖÁMÌ”¹‹¡û•PF%Öøå}ô)€)"ã7oFev6~½ç…AIÐÐU¯·4©«(çþøƒYù¦×^C—Gõznxr²×|ªsçäŠí’ô~ñE¹Ú}Pl,LÁÁ¸°g–?ü0µµªdbšÑîÐd2 Ë=+&z ÀIË %èòØcrbêŽ7ßıùó™¿õÁ–˜¨\˜fÌ@ÆO?Éß[Þ|3F|û-L!!Ðûˆg7#¦kצÚ$ÿß íe¢Åb1#ÖêtoíDFF 22B© tí¤4l¤(‰‡¢££T9´Åy©©m¯›Âè‹=U’£_|¡Z)Þ‹¡J’›ÿùO„ÄÇãË`-)a²ÜiÕ_"Û%çXq 2Û%ê‰øX ¬ ¢Íz(©ÏÉß"=3ñ D›a"€’BúÅýÒ:$…ð9Å¿V(=PNÆZ†QE~Ï/¿(B5¿éÞÂjî¯OçØò¦Øù›}«ÕƤôt˜4 ÇçmߎU=†û׭ùuëT,’\LOÇÒ±c5.hVÉË5znüÛßؼ9’o»íŠŽßžÓ¦¡"+ _z ÷þöû^ÝnÌñÁÐØ~ìX $—#ÍÒÒpÏâÅÈß½œN‡;æÌñÌwQQ¸yÆ X"c’\*˜ðÕ鶺>öš¥¦Â`±0Ïq;¸áé§Ñ\4j­…:ƒ! #lL—.H0@u¬µ¤'ò Þ{ow÷ÝeDÐÐÔüÊÖ¿kÙ¿?‚bb` –sÍr7oÆï=DOš¨-*òÚÖþ?§×cà›o^Ö=éM&„$$ ¦K´7NñN¤¾åKÎ,[¦Ê…§£\T¿ä¡'åBC¨¬N£ßºÁ&“溟Jó‘d4§ç–„~ýмGäl܈m3f`×;ï€ë²ò·ՄΪ•_ÅЙÍèñøã°UUáø?ÀU_¯ ûÙ÷ÑG8òÝw€g š€Ôõ”VƒËŸ¦PeÉÉ_~Aev6J22Õ±#¼ù&RG¾ìû8³lÊNŸÆÅôtÔS…øn5 ±x«$µ(ÉÈPtRo‰t\¹g?k1¦­¢4(ãX¢£œNô9ëêଫS$¢ýÀ˜SUËþý‘pÓMèpß}èð' £m’&¹^ˆÐÈøkv½æ #>nÞ}Í®Û 8yæëkr-ÎÏc8?æTAÃ@xŠ¥J!ÛfÏF]AÂE3¢’@Š a£‹š“dIŒP3r¹ˆ¿.Â8F³±˜ùxê÷IÇDð(')Œ/žP>³Ðë9и„r LU¨·‘àŽ¾ÒG玴9QíÛ#¢M„·n#ß~ kI òwí‚ ^K‚HŠ~`LŒ ¤ü o‹ïÓ‰2×m—"7ðí·5ADµoÛ>ù¼zzô& f³ Σ£‘ЯÚŽ©:¶æÂ„%%¡òÜ9œ\¼˜ÙÖ/¼ ØÖíñǯK]-R¿êó·¿y@t‹xu/6ª-§ÕŠÜM›à~ýõ+BBÕ,5õ"QHñ‘#ˆHIQóxØæ,‘‘8³l.ìÙð<ÓàM¿Ð1t˜+9/%è°Z Hé £9ï dlÖCö+y•A€,KXB` „£²ÎÊJE[þR°¶qð”&NH€^ôørY­pY­ìýàô~ñÅ& u½¤ó#0·ï|ûm¸íjvªŒŸ~’QqtçÎ oTc$gÓ&ä,:§–,AéI¥Z§×«¨YÏ,[†¢C‡Psá*ΞUuTÕk)œ†òÀiœÏªˆM‚²ô/¿l4û~ªbâÀ²õ,õž{TìZMÒ$ÿ+RYz£ã²Û©ª¬FHT âšÍŽÛzÙíY­@Yõ 8ë#`á.»½¢Ââ«ö gŠ!<‡F»F‚-òå•ЛL=*3¡‘ùKd“‘RXHF-P€†V¤$(kÌ@ÄI(G$+ùa €C‚?3Â÷$ È:òG¸AhðpÙàñrÕŠ`ªRü.Ý» ʰ#DÑ@*mÌ´7ΣLÕ×c߇*J_øê•{gÍR®³^Ž%ŸIÂM7að»ïŠ;¸ìv”>²Ó§èu:…Ïq—6Ž\õõŠïågÏÊ齞1;kžÁヒsë×3)×M!! ¿õO(a­[#8.®Ñ@ òwíò„–]&xn‡Ùë×£y÷îÈßµ æˆéÕÙILJìõëÙ®6¿ò ³ïÑužh£Ž@_Ž¢L„ñDG'H“þKt¼1=Ó† À¹5kµf ä‘Þ&ú7zK7! 8îúzù9yË»<é ÑÇqЛ¯‘Qº 9òÍ7¨»N1~;{íZìyÿ}¯Çw4IjxvåJ¤ó"柎ý'­¥Æà`èÍf8jj ˆá‚t¥jr¡§+у±ØòP'ëà_øƒ·*Øy[·"o«GÙ ŠET‡MÔåMò?+q±—"ãt8ár:äX{ÙíÙl@yň kޏØfj õªÈ•““ƒÚ˜ 8O)Ôt9 -¯>kn½p!Ü~ðAh1A]¸–V`È;²¼„VÃàˆ<¬%ՈƠ”tçÒ9té ‰@ˆ'îÕˆO”D(!}¤p>N¼yAŒEâ]@½à¹~ø±‰íó€¢^¨õ„f+£A`Å£b#ÙÏ’VQzÁˆÂâ#p‘ •º–⨭…ÛnGáþýXtÇ€íÿú—÷¹ü†‰ìõë5Ù×ÝÄØ” .jìë‰yŠ ñ%kËI¡ÀÒ¼ Ç¢!Ï‘$¤!6Fj®$›ê×ÞòIi½‘‡vé)7Ó[¸)ì²ZñžµÕ¡¦ˆÑZM@ê:Ë“ÙÙx×hïry=n߇úÌ«rÙl¨+)Á©Å‹±QtM³&wž1`«òò”Ûˆp:nÿ7Þ@Ú˜1Xñè£Èß²EE©«ÅEçS‘“ÅÊçÕ–÷±¸‘ƒrÝSOA§×#Yœ¨¼I@d¤Ì‚Ø$>±••Óëa¯®FpóæpÕ׫ŒšäÚJq10w.póÍžÏâÅ@y9 òÙªª€ÿ_^“ ¡Øòð„KéM&œ]¹Ráõ¡­¤õ’» ¦¿š|Ù¡C£½M)Ç£í]w1ŸEc½†Þdý³Ï⨘›Ó¹á¹ç*2Õ@Þ¶mÈX¸Ð+AG>Œ # K$u.Ò(C†ù:(}#öû3~tßéùŒLqCYN„4: öŽ‘cSO;žznÜî‹M@ê2¥Ý¨Q8õë¯^aÅÓ’³q#œÓ˜Ôé =cáBd,\¨Ù‰µhyÉθyútl™>]“®Å! $z“¢jü|Òñ7NŸŽØ=pñÐ!ì5ËkáÄ5¤VçE†Ï‹®“&5uØ?©üñüóMLÄ®™3ñðöí8¿m›¢žF“ø–üüTW× 88‰‰-‘••ƒÀ@ jjj‘’’Œòò ¸Ýn”•U >>aa¡^Û›;xõU૯<@jÜ8€$³:{øôS`Ê Cß÷—™™§Ó…èèfˆŒŒDuu5l¶zÔ××#99 uuuÈÍõ$Á·m› £öÍ«¤Æ\£P—ŸÎ`P±Hy«Á'Psm"sŸ¤82´Ï@]‹4P‘¹¨Ò}avz@IìyF à÷e!€”Êz€$ù…ä}’,â(I%¤ëpâZ`#™“e'ÀŸTvB™Óªi %íë:y2 BÅÙ³*/€¿ZÛYçÇ÷éƒ^Ï=SHˆçÞœNd­^í¨³¶w™0ÝŸxÂëýe,\ÈlŸ6°ú2b^ؽésç¢ÛäÉ™9nû¿þ%§MØE&»ÆˆV=¯ð6mþÕWh;jò¶lAúܹ—t'-ÂÙ•+=¹M^ž½–ž˜rçŠm­?ýÄd«ŒîÔ ÉC‡âÀ‡Ê4äR)@]ↇ%ÇiÀ ç’àE  I|§NABB<š5‹ÀúõñüóOj¶UPäçGŽx€K²³ÒRàÌß@jóæí(,,B``vïÞ‡G¹~ø9’““Àó<***±oßAÄÅyB‘.\(ÄСƒ®ù3dÕa€ò'äˆÅ„G³ñé Ì}"½FdÍN¤Bã$®ÅQJ vGÖ‰2‚M­.í#A”ƒ)"Y[%(0©H»®G*Xä_'ØIêäos3ž%«6”´?$!ÁqqH1íFBÉñã8»jÊNžT Ï‹vºìÔ)8E–4_k˜ô~ªÏŸÇr"ZàyU.³t®%"BÁÞVtð À7üšèN|öÑ¢ƒqüÇýîÓZ9|U¹¹ØùÖ[8»jî^¸PEVu5äÔ’%ˆïÓëžyFޖз/ú¼ü²Ïs‹ÅþÙ³UD[‘o¿1K—ª¶·¾õVÔœ?N=Sp0.9âµü )«ÖR³hiFÊ33}‚Xy~1м»§xyË›oVí¯ÌÎFñ±cªþ'õ=ëÅ‹¸°{· ”¸¡.êMç°“L—¬‚¾$é1"Ùü@KG&qˆÒ3@)zÆoÔQíx#¥ð¦ ðž6Ò¤.Sª««QWW›Íæª-*B¹ |©Ð„5ÚtÖÕ!gãFœY¶Ì+Rö6ãûô‘K*³³Q+†ùq På‹©È[•lN,ùkŽíÙ¦ìÞ-uÐÅ kŽ^Ê@»iy _ÑáÃ(:|Q:  ׫—‚=Çiµ*Þ…/ Eƒƒwà Mƒé%N´¶:û÷#0&çÖ¯‡Ój˜CC‘ЯB©zbf©ÊËxÕùùMLTÕB»’b³ÙpøðQ”––áìÙs¸á†nHHˆGDD† €¹sçÃh4bÒ$O!Ì™3?ðÑP_ï ÝÓ’Ûnî¾Û÷ý¥¦¶ÅÁƒ‡áp8‘˜ØF£‹&<ˆššZØív¬[·Ó¦]?¯1ÇP>8/Ç@È$Í·¤7ÇÀNdIOÎ1,µn8Ñ´ß’‚`¦@Yr(°d Ž'ó)Ü"°‘ÂkÈzN:±­ X‘¿M îÓ u ÝP×”þ‡Á€øþýá²ZQ°oSa IH€ÎhD·)SÐOL<—@Éð¯¿Æ²‡B)‘š˜ˆo¾É$‘úã¹ç³q£ŠíÖ[m¨š Psá‚Ïþ‰žO=…o¼!oûiØ0”:…jqݦÃôY‘’‚ÄAƒPvò¤fh›ÖZ¯£ÖʪÜ\TåæúLO¸lÏãü¶mÈ^·NµÎÖ——£Å7zÞeË–LÖ¿’cdzaÃe(8³|¹bÝŽêÐAfgì2q"O”Q»Q£äc*²²`-)A|Ÿ>pÔÔxÀ/Ùæï¿ÃZRâ׳—æ‹ÐÄD„''Æ{)ãâáðWU!îÆQyîJŽGË›oÆùíÛ€@ÀVR‚ú’fî:«Æ1D×[ Î¥ ÝN ôF"iN‘öñPz×iæMû'I(£¥§‚a<´=RÞT›€Ô–~bÝŒŒ ”–ªk–ÔWV"çNù{Ά Ø÷ÑG—|=·ÝŽs6 *7ë$ K¨Ö$(u„îO<Ž>ˆê¼À&9à@B“ô9O$øÐQmò”ÒCƒ ú’zœ£Ž˜ßép7 ó’á6Rû„DGnÏ“ˆ%,ÄutÄ5¤:S64„ðÙ¡ôöÑF;Öÿ<£Å‚^/½„š pžR¤¤‹€ÈH…ç¢úüyÀÖ×^S€(ÀS›P‹‰wèÇãôÒ¥øuÌÕZr)}‰\{Â’’Тwoœ]µJÞÖëÙgqlÞ<Húâ tyôQ¯u–zL›†Ó¦aÅ#àØ?x5 ^ ¹°{7ô&b{öDU^JŽCdÛ¶ˆl×Îï62—/Ç‘¢œ›ËÛ¶M^KSGf†àïxã ¾dýÀíV¬Ûw/Z䳌ÊÁÏ>Ãñ 0â»ïPqö,þxþy¿«Ö{‰ï݃fÎDDJ \6r6m‚%, :“ +'ND鉘Jéï_³ï9Þt2° U;¡®÷J¯$ ÔäüCÎd§JZt ”^dÚ#ê¦æ Ô…ƒ½â¥çHÚ#ÆL¼†ŽØ¤®¡”Ÿ9ƒÅ#F\Ò¹]Šy}U•×ö3i¯œ8mGŒÀ‰E‹pò—_˜µ@XJy-R àˆA#P–ZÁðåbÂÏ?//Øvi÷+¯1èYnZ\½0rþ|D°@o6cRz:v¾ý6NýòKãçœ,1IC†\ÛR“4Ƚ˖Á%z-Ì‹.&üeî=kõj›?ÿšåyµh‹Q£îDeeþþ÷é E«V‰hÞÜ“?iÒ#øæ›ù:t0JJJѯß>Û¤õ™¨(`út ”H­zì1O ANÆ”.]:Â`ÐÃét¢gÏnò=‘òÈ#÷#;ÛÂھ}ê5gôüH‡ðñ^tP‹?u1]º&9ïi…'7ÔÅ8ÝP3¢Ò¤@¬ZKR^”Š F†ÿ¸ÐÀðW##y¥ÈkI÷ã€'שVSdîšC+z,–¹V& ‚[DŠòÀèhèôz@¤ß?{¶¢ö $ãV¬@HË–=Z’tË-øöÛØú\60!½E‡ùÔ#ªrrP°o“¥[h©ÆÜóƒ6x­k´éÿþ11³d ²V¯ÆÚiÓÐÿõמ5_òë˜1~wú·ßpú·ßõŒ{>õº=þ¸bÛº'ŸDþ®]Wln°–”h¾;_,¤\úÿä/¿ ¦KÜôÚk¨Û–XûJÅ0bh?nâûõƒ! “DÂíÿü'Îüþ»"WÉã2ëtÿºuX:v,ÕÕ^ÏuóÖAçe²hÌék“s\=˜:õhÈ¥çb±Mn¦’h=µÿ믣#]¨¹ H]]Ù0}:N-Yâsà/+¶gOŒ^´T¡HN«óúôñÙñ9ÁÀ’ïn¼vb0pVV–׋g:/ŠÅÞç˜Bêì7ÿû߈ïÓ‹† Sµ£ƒšN]§a±tA›V|ö¼Ö†æÝºáž_~AHB‚ªÀ!ÇqkÕ ç(úQ¤Yj*Æ­\yMâÌÿW¤YZšüÿ€7Þð»üŸA:>ø Z KDºMštMî½U«D´jÕð=0°¡/6o.]:¡E‹8´hçW{´Q¼ukõ1ÑÑž?Ò¡CÕ¾òÄ`tíÚùº¾7º\=Ÿ°BCXó­d­e(zž“@‹ƒ˜ë\„‚á&¬¶ Î'- i-Ös¨Ä¸g?€Px 熊Ú¸%õ‰Ù!^—Ì‹"kи(+³›¸_ƒÆÁ¸kÞ<¸ìv¬ž2…Yè˜e°3‡…¡9ÞAÀÑCb-fÓå7 ôúsXz=ó :ˆu¨žÇ᯿FÚ˜1˜×·/àŽ9stË-ªs¿éÞIôàÍ8Jÿ¾5O< Ó§{ÀßÊ•h–Ê6*Ä÷éƒiT>Kv¼ñ†WÀ•·mó·ÀªI“PxàÚP$$À˜×¯Ÿ¼þÀÒ±cU´ã¯Í©˜éÚ§žòK?ü˜cö}ôŽÎ›'‡U–;ލ/upÎ ýðC4ó”~ã_}…[þû_>Œebå× u6r\él|â µµ âj9I0&PôHù˜z“¼anÆ|é-bŠõ\ir KL Þ¹e'Ob1EìÖaÜ8 |ûmŶÀ˜˜CC›€ÔÕ”ýŒÙß~+¯¯¬ô«Þ F Š„RE×ë‘2|¸ü½îâEœüåU'æýœt£;v”É,.ìÞ‹bü. èiYIèNOZ/ Ô$é'9@o߬Y0ˆ5žHÖ¥`è q!gézNxB~ù¥jrΉLMEë¡Cû÷£`ï^Å„ÝzèPÍwóIË–àN¯l@]}”9I·h¡ÙîÕ–O4ª”áÃqç×_ÿåÇå_ DIʘDß.-„WZA@FÆI¿oÝ:‘y|EE%Z¶‰AY9Ÿwù÷U[ „FÖ:+22.¿TIIé5ygZ×ð2'ë¨ÿõP9ÐF,šæ×M'2oˆ•èM&`“סóŸXs#M.P×¶£>]RÌPÖž!•º§Âç€:\Gmr  Ó§‚àlÐÆ¾¬5k0›"‹¨-,Ôe r6nô+ç*0* QQcÕÀ2êpß}°••á܆ *†Nø˜7 ¾¬ õ"E=ÈÑ’þòKœüùgO›žÃ?ƒbbN¯GH|<ê¨ü<:D޾/iüZsr,ž¤!:eÄ„%%)Ædñ‘#Èß¾]¡Òvé\-ž2ñP &éɵæJ@»N©­¬ ?#ϯÕ!×D/kR”8jkQKY”³ jòó±[ƒNo2á¶O>‘¿WŸ?ðäd_°@3aUê0AÍ›#éÖ[Œ=Æà`„$$È“?«nkÓ²T°:0=HHK!ïåöª*¹XpM2I@JZÜP†¿„ÅÇ«BhÈë›*>²3g” hÂ&óÛÁO?…£®µ^-gÝ&OÆ-ï¿Ï\˜®µþòKÔWVzÞ‚Í„öìÑì‹–ðpŸT»,9¹x±×BÔ¦à`¹‚x“4N.ìÞí÷±щŒ¿ìk6o F‘2óÊ,,†@Ün÷¹¿“g®1€fv`Pù@@ÑÞ'r~ôÊçÐnìX\س5çÏ+æj+Ÿä%¢‰#H w‹¸? äÒ6°;©ßOq]Ôu¥H¶='¦¤¶5U2íͳ—•ye¤e,W}½WàDJ§ñãÑæŽ;de¸Ñk;ÇÉÆ¹Û>ù™Ë—ÀªÜ\œ#Oä~/F9p—Øßh±–”àü¶mpÖÕy ¿“mÙR¶¸çmݪ"G ïÏUWQ{’u/ÉÆZöï–ýû7€´ÐP´¹ã¹Ä ë™x“¨öíÑMŒ!–'`èìÙ²ñ¬ãƒÂ®ð&=Ь5k<:[M Ó"§¾eåzð`ÜöÉ'8µd jòóÕ:?ú¨ýsóϢ®¨±Óoî–-($Œ·, çÀ#}wÙl¨øœNÇ\Ç ‹B¢ÉlŒÔ¸¥ç;e¸‘žW@T”¬Wv4 QQXvÿýÌÚm,Ju©’h†žß@} ”6Ñ9‹:¼ÛºÂBftUå¹sÈÙ¸Qö¸æl܈ÂuEËá4)­C…}€Ûá€Àóš½ô·*'› ö HÑV½É$Çwk…õ¯G÷©S@ª`ï^ÙëÂ*€F'ùIž6,vú÷±b`YùH¼G‹‚^¯W°òѵH¤$g3”¡(€’肾Ÿ=3fÀí\¨‹‡ãâáÃLKÐÉ_~QÄK²ïÃUá,‰ëÕ뺂¨£ßÊìlÀO?õËšVrü¸f_´DD0Áû/¼ òe®XB‘Ž/½„n?Žoo¸ŽŠ ¹ #Ñ?Y4è¬yÚ £3a Å#;v YZ¾LKÃŽ·ÞRôÁ+-M@Š5iÖÕá‹ví0‰r‰»ùÿÖ­CDÛ¶°••á‹”E~“ÎÇ$ªõÜÆ1¬åÇŽá×áÃa¢¶ë¨ï¬{M@2S–I#Ø‰Š ,N¨½_R'ßûî»8·S¿þê [ ªÀ¼¾}U Ê €Ï““ßKŽGîÖ­hÃ]Ï«È X2ì“OäÐ åÖ½ÿñGEˆ¾?s)]&L@ E—ÙnäH<ˆ¤!Cäù¯Ã¸qˆîØQ>&ºS'@°‹˜{ÛŽ)Ï˾Ââh©+)Á§"UèØåËý¢m§‹ÖâbÇ50‰üôSÕ½:$_Çk²v•+!ÅÇŽÉÆÍÇBl÷î—ÜÖgII²'5¤E þϰç½÷Prìóø]ï¼#¿7¾=½¤NFz©ÈÂÛh¨gÇ­ *:jÇ Š•ï%r÷CF4A”Ö¼æËhË8¿}»ÜW.EkRWHaÔùùà³~û œÛ­@άAîOm£^Ï=‡NãÇcí“Oââ‘#ªbŽ4KGYèE9äÂI' ”ĨizÉ…™„:jQ–¼Nä½›«H±(¢¡¨£Ô&MKÆ×º ì h¢‹eöxê)ÅëæW^Aù™3L –·…Ä_f©K9ߟ{ü…m¥¥X=e ú¾ü2ª/\Ð CtÙlø½‘uø[mŒœZº±=z mìØ+:~S†‡ÁbÁ²ÀÝ?ý¤yܺ§ŸFmAæþÈÔT ¾@Óë1jÁƒƒqzéR ½RÑ:¡YZŒAA0‡†¢y·n²AeÙÌ™Wm~+.>ù ±ðÚkž¢»À¾}€—Ô¿eáÂ_îaHÛ¾}7††•+×bàÀ›°víFŒ?'>‰I“AMM .^,F¿~×§ˆõ«b¯œœ¤Þ|3FÜ|3JǶ3|*æ<Ã`C†EócžeÔ¡£ hÏ“Ž2h±,±tûRŽSÝéÓò¼NÛ\„¢¥'Qµ&˜‰u‚ëÓà+ÊbÀ†áMN¤·ZqzéRÔ6jNÙùÖ[ Ï­´TsŽ¥Aç£íSK–0”¿rvõjt|àtzøa4ïÖ Ï#›òÎÐ}Hkíðï#ºsgäïØ½³fa߬YhyÓM0àè÷ß#×.Ü) bQÊÄ®•çÎÁíp@o6£y÷îhN)û!ññˆ#ÀjÅÙ³È\¾\õ|ú¼ü2Ì¡¡ØúÚkL€å²Ù°ê±Çäß±ûwpô»ï·~ø!ÂZµÂÙU«à¦B ÷Ïž­¨Å8C†Ü; ¶9@D»vüî»ØüÊ+¨:s†™«Ík—7>ý4Œ~Ò¡ûZÏê++åß²ùÅa—m?nœ"×kï èÀù}çmߎƒŸ.S©“ÒuÒ$t?ÇøÅ@ŠîÛô¼@z•9BÁ—êÙım&r9Ü<àvN§L•Ã㕪#>6b,Û¤Žƒ¬_U”W ÓFÈg¨'þšó , ”+cÒÆŒÁ©_e†þq~¼?á*©& uÊnef¦*”ΗRNzcPâDëF\¯^X;mŽÍŸ—ÕªrÓ’1ò4­. "¤ö¥øTA\Ü8(É%h+'íºÕSV”nX)ÁØNX0É|'i¶ !a9˜PfNŒ»”…ëÄÁ\#ZF\–ÅC~äû6™rçr-Œ‹éé 2­Õ±£‚é©pÿ~¸¬ÖKò8^ Óµ+ÚÞu—f,]q1ü)Ç£*/©b%yZœV+BâãD–ˆ9©—¶ÆJyY‚—‰ˆ¼×ˆ”„Äûf“súÞ ŽEò°aÐ ²•º®¸Ëá/ù;wÂI0UÑbA‘X|Is Ç!eÄØÊÊÐjð`Íwr­¤sg )©á{b"ðàƒ’wæÊ\ãØ± DEyrPt:âãã–Ö_=¯¼òÎoÝ §ÕŠskÖÈïµh÷n¹?¦Þuj’“‘»~=8—K¡h8€b`°ŒÏ†qØl0 $2fƒAîËtag^ÃÀ\´aƒß!ï‚c] .lÞ¬¡¡!]ðW"”æj²v”›šó¥\2gU2Ú¹(pE3l‘ë ïEiõ¶n6ÆÅòjµY|ì „Ç@lÏžÈÝ´ ?ý„ô¹såçê«–XÆÂ…ò„ûîS„Ë‘%C=§NÅù;.)zM8ðñǨÍÉÁŽ7ÞûÁª(îOƒ)Œœ¤õ) èk12úè®3FXI2/F¦˜+lÒèßë O•Å‹N¥eÌU¬Aì'Nà÷Aƒ ½*ÞHL´t_ ¸¯@ŽKŽÓóæáä¼yŠãiƼìU«¹j•êÚ‡æÌAl·nˆ¤jÅv놞O=…Œ… Q•“£b¼t3îÕŽ† Ò;’ò"õQ) ÿZ<;tN °,P Øì@€bQ«u3#€ó  ˜Ò/I@0€Mj¦‡vž™‡O{’N.X ùÞé±Õ¡z‹Ežàøüù¨ÊËÃÕ œhRÖ­[‡êêj¤§§û¢h«k¯¸É—X•›‹Å¢òGZ#I†%”õ—Hv=z¥“è$w. N”ê†8‰Ž`a,Ìt¹¨’‹6 ¤6—å4äD…Г+¼ˆÄHúÜUâ§TôLÊšSd’µ[Tñ:Þ?ìq»ß{OQãÂ[¡À.ÊD¯ƒo’hÑ»7ÆŠ‹¨$ÛfÌÀŽ7ßlºZ3N«™+VxÝÿû?¯•Ýõ&Æ­Z…ê¼<͸ãóæÉµ»þlƒVƒ㸘|ÚXźüÌE}“Ë‘“‹£ß«¯¢ôÔ)¸ëëeÞ«)Í›/¼HÆé°0Ïw ÷’ °WŠ ö¡‡ÆáÔ)O 7“ÉŽãpï½£`6›qçCÁq@ÿþ}ТEZ·NBûöíþ}eÏûï£þý÷™…!u^”°¢Ã‡±xøpLÉÈh0tpݵ óúõSÍ7€‚íÛQ´}»ÂS¤‡:'ŠW¦©†ûϘ¡ðr®˜0%"ý²P±z‘áÚU\‚ £ ºÜ„²d'¬ÓRÈ›N$£ª°¢ç_^cÞ»qútt~øal{ýu™~™¹sºLœˆ#ß~«8?®W/ÜùÕWømÜ8”gfÊû;pŽº:,8P‘¯Až»bâDÔäå©hîxB±Ò¿ùF•K,µsò矙á™Ò3X/–ƒ€2Œ^º¾õȤ9‚0°#H´ ¿þê.µÆk£xó$øs_4i Çèçôs¢ÙƒI]ƒÅXIוdýoäÃ+¢Åª))ø$‘Y‹‰LC 9.ÜÔ1õçÏcéð᪲/Ù«W#kõjMƒ ¤tP‡ØñP¶Ðˆ%‚))ŽWB`U e®¢+ˆR ÚáSU"¨"ó§ÔïeyÈÜ £ëŠÒõC¥ç$ísiÌ#Zó±ôìr·lA®hXÖÌM@ê JZZÒÓÓqÚIm4òåž(-K¹ÞôÚkH2?¢šLh=å‰R„GPÞ’¶ÔD££@ˆ¤$¶ÉÒ££uí1€I ƒJF¾ â»bI"°Vp^ÉC.Άƒ‰ÂCÖ/¡™¯HËãÁÏ?Ç ±28ÔŠl;¾@”Ö1Þ¬™ šôM›P~ú4"E¦ oºw—zü ”®Gvî”÷ù.Ç’EÆ) èú[ピà-0•*p,ï‹ýÓŽí­¯¿Ž3¿ÿ~]ïÁQSƒo{ö„­¼G¿ÿ.› ‚ ((„å ÙbE£/Uhf|¼çC-Öÿ—#‹ݺuf‰†ÛíF×®4¹^â­@9=þYóÀÏwÞ©dñây&8Ò"’`Q jÆ;R©:4g2ˆ\ÀÚóçUtç&(Cô8¨Cnx(©’¥ùUªå$@—5P‹†ˆ=ñP‡Z»©9šT®éwÁ81>²V¬@ Š=êÇ׫~¾ãTdea¾}ˆˆÀ‘o¾Q­Ç¥Çã·qãd@$Éï÷ߎç™ì`«F†Þb_P€ °Y¾Š~û ‘P{iâ%ñèwMF°ØriÃ*«fëD¨ò·ÉÆu§£P¶ªŽÓ–;Uj_Tj8CÃáˆÅ,&œŽzXÂâ âñR{¢¢Ä1Üãa¬Ä±S Dܪ@ #AB N@°‚ˆ$„z@°‚˜H$ˆØ<ÇI!6‚Ý£çHÆb+D¤R’QÛA^<Þ)WKâÿ3E7º(Ñâ'@sQI“ÜŽõž›ÔUºrÀ˜˜Kfe€«(r{ò¨*DP%åQuž6 G¾øB~u´ñGÇ0Гä$0”tL‡¸ÝIüo§æBhL–îmÀdÑÈtäÛo›€Ô•–V¢¥=::š¹@J8,) ÍRS‘½n*Ñóaõ _øÁO>Á‘¯¾RYaÈI•&†`ÕrÆ·l°¡BÊQ"Û¦óžLÄ}™)k­Ha’÷È!Z)ðgd€1'pN‚¼BPZ7kˆBz¸xê÷²rXù¶òrO ‹…¿Êë;ËÝŸ2|8ÂÄSHN,Z„ /¾ˆºÂB¯uNè~Âqz<ù$Ì¡¡ˆlÛö’ûõ’Ñ£Q°o¬ÅÅà]ì©fÏöê‘’cƒá²îåjÉÒ±c½æMØ++eÚSI"Ú´A2#©üü¶m^}+‡æÌñÔÓâyÄÓõlha+o}F¬=}M¤²ˆMjjj‘‘QzYm%&¶DFÆ)¿Ž-))½&¿k„uŸœçSG†ËnGÖêÕÌdpo9Cã#0À¯DlÅۉÚ´1ÎHÍÇFÂKÅÇJ•ˆHò!²¾”@¨:ѵâ~êP-zwr=ÕŠ>½ÞÈÆÁÒR8JKeZuÀÏ> ½Ù kq1t~9zöêjE<6¬™™òó®á8{z¡P‘ßF£( £Àååš G~÷"0Ðë=!UœNÜ&~tzqQoð#ï׉Lj E:†ãÎ!÷q"ÐáУ#:Gýe&`î3Nã`Ï8¼ŽƒÀé è8ð:Üzx½¼N^¯ƒ[§÷lÓy¶¹ z¸ â~N·Aü«ÓAÿJÇò:Ï~O›žï.ƒ^n›ç<×ò܇8×  œ§ ‚Ážýº@@gôF ¼ÐÙš°Š÷”óÊyƒ£Œ :Ê cdè¶´÷“Ô÷H@F×õ×Ë××cÁ A€Ð¸8à ²7)E’²g´X¥re{+LF¿p=wUxÂúGZÍÄwVÕzV 8ié3SZ$’™°^òŒvI¦&r€Åv¥ó%«¦ó.4X¤"mt!Hòx´ \²€”´/®W/´<n‡C•ó ø©TÁÂ{4äý÷E$7ælÜÈd†óuý„›nÂ0‘VKŠEÖZïÅX‹ÓÓ×gÝev6Ž/X€NãÇÿeÆgÖš52à¹xø°Wö=–ô˜6M.5@Ê™ßǾY³ß§j .)ðP)Ÿ]½ç·m“ïÍ_Záø¾}‘ãçuìî‘RyÍž{£!¼ð<ͮۼUwœ<óõU¿Ž¯òZï.0&FQD’E¡÷¤XF7ÞË<ÏhÑ·/.ìÞ­bÏ#©Ž«¯™0ô³”P랸VXžž&¤!‘źEß/é©1ŠŸ‘òìÐaŒrX”hŒ‘Ž/*’ ɵSv1b2d^oð€½I7¢§CG|ôz)ï¿ëD0¤7ü?öÎ;ÞŽªÜûß53»ïÓOÚIHB „‚(WPÄè}Õ« W…{õúÑW_ 6ŠW±¡(p¥H“Þ - %4ÒËIÎÉéeŸÝ¦¼¬™½×¬=û$ø ¾×Ë|>óÙ{fOÛ3kÖz~Ïïy~Oõ8†¿¡ºAõy¥¨“0±MÇ´(Çb”- Ç´pL“²ib[Žaá†ünY>QæX˜ft¸†`"XÏð?…¨lãFô˜ê:*ŸQý4ü7D€gˆÊ‹â !”!·õ8˜8˜¸8˜”‰Q&†…E‘eb¸®‰ãš” Ç‘ßÇÄq,ÇÀqM¹cV–å6¶cV÷·-œµOQ|õF·õ“9ïr¼Öýq=Ï5p]qxÈO¡86…ç"ðÂÃÀ•³ð0„‹)l,acVÜ!–,7‹ÄŒ2q³LÂ*Šˆ[E±"éxžT"O"VÄ.†í’ÈHæ ¤óy2¹QGGÈäsdÇFiΠМ"Côz°ì~(@iJCr¶Ç X ‹{Ê»“`YH@ÌËðí>,ßûâzà ‚U$R5i/`Jñ |æªè±š7B¶F¡=žtªäFGÉVøs4gŽÚ'E±äѹ¡ºƒÅÐlÃz6[ ¡áyŒí܉2ã–o©qL=Äc`íZÖ®Œ Ž ÃPƒhe&=!8®uüõ%ÔšNŽ<ôÐKóZXƒ»:ëïmÂR––âÅtO¦ÊD^Ì¢FE«1°*]V@T™°*”îñ"@jŬ3MÌXŒé'ŸÌÉßý.¥‘^úÙÏpÊe<Ç ƒeÛÏ…¶íÞTBˆPþȺ'‘ ]ˆPEz§X 1V{“;³kÙ2žøò—ß°¡¨_ÿhWO\y%ýë×sè'>AÃ[ëÔùüóL>ì0žQÄ-ÒííñÙÏîqßÒÈO^uUEÍꯙúÖ­#ßÛKJQd).Ò·v-‹¿üe:Ÿžµ·ß¾×…}_ýÝïظQØ+"Ã Ç 5 „ì{Úil§í©SÂ\Nsò›ÿðýñöí àÔ·¼ÿêÛ£œg/ÿü畾QÔOµÔõdx=~vÅG IDAT/ÃÙ1͹gu I*s¼N¿î*}°K¸.”ÞÏêµdbŠ#Mí×½ˆÿäø}mðŸÕñ(¦á K1JWCyÆò»ë•eÀ‘Ê9ƒk°±(ÇÁ[T“ŒŠÊ _ \ ¥@mènÇh®8ÊÍî^> MsÂ’šÄeHèI‘B{yuCJ¥~‚°œ$ºxáNXúfq€æ¯_NëÌVÚée²èb;˜$º™"v1[ld¦ØÂ„²‹¹ËÅXï"¶y$;]Rb‹›n(”a—]þ©š€¬€Œ€´"íSP)å%òÇÜè*Aç´ ˜Ü©A»€bÙÕdôª±ƒ~un+-]-p ]%Þ*}Jà@×; Å¡¯’cõXì¨0X1žº{aûè ìm õ‡yÔ«tÏ8XD eCJ&á(CóÊAmX[0ÚJ?¢z SÚ ªzÔïºgNeÆ‚óªž=iТZ7DCÊ>z~•Ú¯©`ÉÖ€¡£QÙñ–,è„Féa|F,†™L²ßûÞÇY¿û]e}¼¡Ë{{yà²ËBÍxœƒ.ºˆ3"ªÕ?öÅ/òʯ~Eqpp¯Ø)³½äߨs»2 :Ž:Š>÷\eÝN9…]Ë–Q•Òv>¿Çã˜É$©¶6ì|¾&tˆqA¿^µãÙ±ƒ%ßøsÎ8ãMR…ÁA¶>ù$ <ó¿ÿw%_«u¿ý8Ð×á6ãñŠü°:•ÇÆÞ¾ýÿ D¼ò‹_pÈ%—ø±.2œÎòeUûàtê¢E|IyN±Hit””/¬‡Œ®¼ñF¶>ñÄ^ÝûJå^¶fM¥Àæ{©C.pþáûâ™· HÕ íN¶´` •š8Q*tzÄ“EýP>uð×CøôO0 ,Ë¢”Ë!€Î%KBDj_ŸRÀIR³‹ô±#¯Ø©ªCÚÐú }l‹ò;Hyb‹}K–ÐH5ï5ëÛ|!Á6 ©êjª¡FÑIbzhDFîã¥^Zà5ˆê÷”ÀmÌdäºR“A)+Ž—x-þ¶iAÁJ0L#c¤óÒäI1êe)xIò¤(dÌó'AO$%ÜwÆOØñ¨ Yí8çþÝ•c þïqÊÄ(8IŠNÂ_ŽS$N‘61\ÇÇs•´¹LmŲæuT ‡úò¶Á÷ç®…?ÿLŽ-cçÍ]ðÛ¢s¢Bjú#b£ 'ÿ„nÜ|­zƒjh ©‡Õ¿‹ö(¨sÙ®‚(€‘Nøã· >7BÒW@ìÒè‚›zB’î ¯IÜhP¸[ÿf€Ùås+Žæ¾ÛŸ§oöã¬o>š„Ÿ´$ MÀL³ Ätöæ]ô2û*Z«Xh­`ÖŽÍ$Ÿ([Z"ù¬‹¹†l9t5о/0è·]@³ôˆ²‡ñ`°œ¼$–6ºÒ)Ñ\€T äF%«ïQ¥ :6ÿ¥m¦K–*Ö Ó·Á>=+@¿ »=ôª6ª“#N8¼Vo’º°Ž.b¡‡àªu¬Dk>ž3ùo]Kêm q££ƒëMQ"P›g¤Jƒ« %N¸Rõ¼ˆþÐÖ¼‰jc³'ðÅ´jë‡è’¹hcžjM§Aä "`–$œ, ÕäÉ¢2P—ç?yÔSŒš/xäÒ&pý¬Y‘lѬSNáÐK/eÝ]wU˜‹ –ÐÓ_ÿzMùY§Ÿ ¢ÞqõÕrÉ%ü|Þ¼BŒÓn¼:@F-™É“9û¿þ«">pæ7²öÎ;yôòËxáG?âØ¯~uÜ: >ò|ä#<÷ïðÄ•Wî³úÿ€úû±‹E²S¦à‹äº»±ÒéP­=M£]]ÜxôÑ oÛÆ“Ú5÷¿þ:?ò5㤓8ó·¿­ÙÿÙï|‡—þó?ÿ&ïùGW À÷µ¯U¤Éë2N7ÝÄýŸø—­Yƒ0 ~æ ‰ì p­7M?é$ÞwóÍôá;þnýÞÚµpÓMð¯ÿ o$êax¸ªpÿý0cD”Jùo3¹ß?ò—¿°â—¿dÙò’ªù=zz‰žëåwêöœ¾¼ßgÐqÔQ§VúÖ\_ÕÀ‹.”¨íª„q¸°öæhš²^5ú¨ämµ£Úý\øXÿ<ôíúyQ•ÙV_<ÂC˜†ÿ=XW™…«žÞóÅ\¡ˆ=æÊ+iž=»îïO\uÛž~šËV¯¦ó…øý‰'rÀûßÏ9·ß¾×÷á–ÓN ÈzÓÖ'ŸÜã=Ò§©‹×TŒí`ÓòÈÞèôs%.ê××Q@{óÃóðg?Ë{o¾€8@>Çû·¿y¿¶nç'M‚ÖVع†† –Àç€`¿ý —“@Êó$¸èè²éÛ·Ãè(44À´i°a\=\z)Ì›ŽûîVܺÆÆä1§L¾>èé‘Iòûí÷ÿWß_O´à •«¯çÜG©ï9ul]· ŠŠ8Zÿ§?±þO Ù²q¢CùÔ=Ç6§Iø8%À$6á¨K‹,œbjT•ò'¯\w](t<¸¶&nõñÙvHN1˜Ì‚ÒÄ8ɺR“¶ÉYÆŒ4y#MÁHR6b”ˆ1¸}Ág7`ΜJìèƒ)Ä3HÊ09/C¾Ä.Å(—,ìRŒb>A¹ì/—c”Šqʶ…m[ØvŒR9&so\Kææôm…R¹Vª¶0[Š–RËM…²æä[³JO×Êî꼞¼#šÛ=nÀÿºª>K3^ãÒœà\_ P¤å§Î‚¿*ZöQ¥>ƒ9å3J$(’¤@†iÆ|žN.'(§ägIÙòj¸a’„þÉÐÃ¥•pÁèñM`;‚ÍkßÃèÒUxÒŸ¸€äåó(1Paƒ0CyÎKåñ\–Î Ur˪ÂÖ™pzýyП‡Ëà®nR®2D4¯ûoÀ4…ÞI‚—†\¶'a´ V7ÃÃà͘ʆ¹søýÜ ybæ)d›FÉž9Jë‰}Ä4 í ŠM Ê"F‘F/-Í“Œ&§»Øwîf¶oaÂÁ=\y ÝTµÌ7ƒ» :K°Øå_Ý\`J Œ|05Ñ¿ôV¿ dc¶ÑWmòÓ‚LRyprRD#è?‚f›÷/¡Ï¿µ†Òœ¢Ô?uÇt”‚avút­­ô¼òJ¤XZTí×·Ô›8ŒŸxìÕAÆõ„tA =äCíëÊšƒ¤ÁΣ±HÁ S<1Â9VÁþE¥p|GC£ÿZ»Ê -æ)£ü¯fª ÁÀm*ƒ®šÿ¤Æ³ …Ê'[xñÅL>âüÔ§BLÙxau‰ÆÆ‘„篾š~ð6lˆ|¶3N>y¯ŠÅ&9â3Ÿ U!_{ûípî¹ÜûÑRaÁ°ÿ9çÔ‚Ž¯|…~E*|oX ýÿ½vÓMì|Ꮎ⠦w\ä~ö1(—aÓ&ˆOü»MAï“}çÌ£W\Áð–-¡1AWYÕõD¨z¶mKåúNœ£¾ðûÂjD~ ͶÕS5TòeLÑû™¸oÆ5D´KC‹‚4• º Xá(»à?/þ÷gÓw’[½šÕh  ¡`,æCqv‚µm°µa‰¶2ƒuìO“É3”s1ìÑvÞÂ)™8ëVÒó‰ó)ædßñé™8§]ŽãĤ0AÙÄË‹*ꂞõ’ÍqJ`—ÀÎ]†]OD»»Ó³ –¨õ†&20óªp²šòÊÿëä1ö_ß¼ :¦c&mâ¢DÜ(eb¢DLØX¢L\”Hˆ"qQÂþv¢Œ#‡'p=?ïÈ3p½'¤‚/  ðªâ žìm\Oày× [2‡&†p0…ƒypŒ×6ÏÂ+•‰¥,]ûA¬É·` ˰‰e,a3l,£LÂ,Êÿa”%€Å hJR Ë( »„Yt0ŠÖ˜ƒQv1Ê.Âv¶SRÂ4ðLgIñ 7føâRj0ˆy•—ÉCà}Uàš³p-'ñîÐ2¼¸k*~>óå‚g‹×ÖɘS n‚‚“¤`')»1lÇ¢äÄ);1ŠŽümÌN3Xja¸ÜÀÝD_±žÒÆrY½v§ »÷>[WÊö—ùÞ)còìÍÀ+ÀZ`‡Y\(M„’€ÁÀ«@'^ü4z›ÞOo[Ëš‡¦FâM RÙ"fÊ$Øi ;i⚃ðò¿â®y™ìÌ6R_ûg9rÂRŽ™ð, g¯dî¯Ó¶¦_~2ìÏ¿qŶ lÁR ’»ý•AhRjVÜg¨šýÏœ¤™~H ú€³¼a(åóÎŽÆJ*6ª©=^µf—në jË&¸CC”J¥Pø ˆˆ2x3ÀÔÛ@j/¼ËÑIm^&+JÖ\û ‚­Öâå¾UÅÕûWOz¥– UÖ<›º$% $ —•†X#o®°Q%å%PÙ9¯ ÝþÌ3ô½þzdÁÚzIúÃ;vpë駇Ömæʹ\äse2•0ª½™’ÍÍ¡b—å\ŽýÏ>›•¿ù Åáaf¿ûݡ߃iõ­·†€ÔÞ*õ?ö¬ZEϪU lÜÈŒ“Oæ4M}0˜¢®AŸrJ–¨iõ­·ÖŸ}ëÖ1´u+³ü{ljbú‰'V‹»_}•î+*Ï£gÕ*F:;÷®J$˜yÊ)Ì=óL6øE7çžuݯ¼ÂšÛnÃ)iš1ƒ†iÓØ¡ÔÕ ±XOýmͲQðªzùÊQàGÀ¸O¿¾¤UÇÚKå„Cu<×·1|Éwx~S½ªV”궸ò\^“ÀI›8)'nbÇ¥üº‡ƒ”TwL'fa'-JMqJ qJÍq m û¤°›,Êq‹®Âdº “é-. §x ÛóÓØYì »ØÄÈ@6uÀÆ# ³,i +` ¸Ïÿ³ÏKš ´zú ç<Ÿòi¡k¡Ô—zæ)SªL¤,~VÉzrý+5ÿL×s¯nÉÑnôÒjö3­q»¼¯c>‹¶[ÒB©*ŸÁ†Èwƒ5ÉIJÀTŸjóTc„'?¡<¿’t°)·ÄþçœÃçWù½00@§/Ú1ÚÕ*¸,ö¦Nå÷Þ˶§Ÿfå7¾¡çuðG?ZQå[ôÅ/Ò0m|þóUÃnÇzV®|CN›½•Gÿk¦Ý»% 1 xõU8áX¼X‚ª¶6ù[W¬\)·ùàaîÜjîÓÁKïä¶m2jhN; ÚÛ%غÿ~úwä‘ðä“°z5œzª<öÒ¥rû¾>‡Ðü»M÷ß?Û¶m£( ±åá‡+ïFŒú¡|z^«žû¤‡cÇš›™vÌ1u¶[.³ù‘G(±ó¹çBãHL‹4Hh0Ý›«Úe Å|ͨ‰+×®²RQ!ê:ƒ¥Ž9…—^’@‘a|íI˜8 İ®Vš°aœòÉìšz8«™Ï Íæ°“†ÊÍx»…P+ÖºM>ŠÛö ¼öDíƒlµàWÕ„­ ÃÅ.–é`¦ébZ±x3æ`Å:±â6ñt‘XÜÆJØÄ’eb©VÂÆŒ;Xq›ŒðÃÓ¼21·LÜ-ayeân™„[ åäI9yÒ“ódÛ=Z . ÅU4®¡¡4Bciˆ¤S îIf áxÕbáÊÛÝäcÏÀ¦+ Ÿ³aûùyßß &¾»TãñÔÂW>ƒ•/Àˆ#_å ½PP-UPÖΚ2Ô(’ªŽ{S‹/PwZ©dÄÛ@êMïˆ*¶Åþ׫D®ëÜëE´‰p²èTf0O:òHF»»ò+³›ZˆGEö5‚…Òk@ l¡ ÐÓfT󤪅}U‰ÚÀSYÔ¼ ANTà¨Ç0Atè¤Ç_Ÿ‹4Þtäç>Ç‹/w›¾5kh«“Lƒ›6±ëÅYwÇÓdÆI'qÿ¥—î³Y<íÍí[»–Õ·ÞÊáŸþô¸Ûí\º”­OÇÏ‹×_Ï‹×_¿G#~OoçÒ¥d'Ofæ©Ñ jçÝuf"Áè®]\Óѱ×ÏÆcÓCU¯`Úº•9ïy¼ÿýÃàü?ÿ¹òûŠ_ÿº¤Æ»÷Q÷wæ;ÞAª½ýÏ9'2øEàI§eNÔé§Kq‰yó$ˆ®×Ù ‡"=‡"çdR2aɤ̻Z°@«àlh€|àïßßwøí4“ÉÔ†5"dQ),zy Õ1¦zX'ì·çjíF ü°µ54ŽX{èë -"@t(kvMAqž5)ØBBÙßW;®4ž2Ø„s,eœÈ"#}&“ ˆMoœx5tùïàν{_ú:æÐ¹Ë`÷’§)…Á<ìè•7qöpÒ,y²©Ç@c3¬ú'øÐÉ0$Å„øÒ·àÓ'…+ûEÓpHP$Ë()ò¤È“!G3ƒdÈÑÀM 1‘Ý41DC´0 %†É#Ë( “ ˆi»a±‰’6ðªL@2ïö‚­ ¼Š}0eäaÊJÔIð ,Só|ú ¥èUs×L d ¡Yn¸‰.¢¦xŽä ]©ûªÎZu› µÈŽˆæ©Ô/ó nCÌ«vºFߦV8èGcdF2Q±W‚Õ>Ÿ$+i&!Ó'÷QmU@ÐS[P«¶Á牲1¹Âj²™ÖÖÉ´ ’±iG&uøLÎtÚ¿‘eÉËÊ ÍSc'Ñûr;,ÏÂ+3á¾Ã Wu¿8‰j2†¡p9À`2ˆ‡À»­ºÛ>ó R±1Z`=4 ÈT­ ¼vøu©a>Cù϶¢*è×V‚ý;abˆ ¾D¥p/®ßþ‡»¡«(ó®†ü{˜QšoRaÇ;²¬ØÈByML Léy¨zmQÝŽÔsOßRo1Ò{·ÎzOóLzÊs"ŽYO„FÏ)Z}ÓM•JGåú€jh^I4*3$¸£Œ9ª …^×ô£Æ‚Ôæ{@0O5?3V§á×óŸS-âLEÆàׇV‘3¦uúÇìHmzäüä'+Ë«þÊø$µ=œû§?Ñ~ାåžþÿ÷úö¤–_w¯Ý$]»^|‘óx€u~nÏefõë\~íµìxöY>¾|yÍö ?þqŒ¸ä;Ó&pÀûßYG+jëíåÑË/çÒÕ«ÃNµ§žâÞ~€/ ¡Ú[ÁýÐù›ÑI¾Ñi¿³Ïæ“ óùü÷¿Ï+šBdp_ç¾ç=t,ZÄSÿþïoê5|pxyÆ 9Ss³@ê¤/ÏšU{Ü ä 2§JßgîÜ𲯃iVÁØßs:Ŀබ6rã§(õ…Öjž;w\a–å×\òk® ±?jNmLc}T'])âZT‰s]‚0Ár aÁˆ Õˆ†"á\ÛU¡Š,2òg_&€9™r ¬´ª `Ëò^úòdæm 6¥ƒc›ƒÉVS–lû$R^ž$›Hxk*B&.bŠ‹¹âT¬RN®›¾…¸ù ™{D™„(’y’¢POY'‡Yt‘w1‡]ʇ‘s1F¬>cÔÅq1‡Œa#/CíDQ†ß‰²WµÞÕgÍÈCqLzâ‡p ×†²'ïg)ûŒ½Ž+PÁ•sN±Qã½"$â@¼ 0ä½jÔ££0ŽÛÀóY%êLv´ñס6•@ÅbeÅèö´ö*”cmäc+Vð«… C©.pÖÍ7óü·¾EתU¡Ü]#Cïãu…ËÅW^ɬÓOçæ“NŠdkÕúi% :ȨÑ…iµ5b•©v±l0†Á…Ø.HZ4 iÊïqK~f-hhå˜9Ïqøì—¸`þÈ—aýasXvà‘¼øÁ#xúÂÏ3xM‡"ÆA`^Û„ÔÏùhÙòtX0Մ޳`íç!9YHî7éÓ×q8/2‡ Lañ\YþÑaÙ.wnÎBy¯gxNa³c¾OÀ,Cë.0¤ß@5ÿC‰ÿuí*Ë4êßß¹õͨAQE+VUÛW ×ëBý²¿õô6Š0pê׎2"ÖéûªÒâõŠ÷F ¾žÖqÔS†ÒѹZ©Þ¶õH IDAT¡¶®«<ìÀûTÖyš¦¬x’‚s¤ W™6†Ë&¬x¨u¼PQBC:¸Zü•¯ÐªYaG~îs8Å"Gù2áêtû9çTÄÔgó±/~‘§¾öµÐï~ôQÚçÍcůÍS_ý*n¹Ì1W]U·m¬½ãŽ7TwO ŽG͹wÞIzÂŒXŒôĉo¨­®øõ¯ÉuwsLùó#þå_*Ÿ)ìˆù–_sÍ;™¨°¸ž•+¹fêTfž|2gýþ÷•õÉ––êÿ´,Îøå/yç5×TÖýñ=ï¡ëå—«×ð™ÏT®ûñ/™Õ·ÞÊÆ`ö»ß À†?ÿ™G>÷¹Êö×ï»/‰ÆF.[»–¡-[øí±ÇRèï¯[ÏMï,ÿé—¿¬ÀJ§ß´>$ÑØ’®WïMûüù|ø‘Gª×‘Ja&x®ËÓZûÜ›¾J¹¥ÿ°Sw×[{¾zªÏ: œ¼ˆ~ `pófn\´(ò}Èr ¥‘‘Pøœ ¢ÌƒPïSõèGOTåØõÃÎÅ+­FðÆ‚^&0(Û|5Á‚L;XÓ‘Ís€™°ï”Ú{}öy&‹Ï*“a5Íÿ|èÞÜý‘`XáæéešsãŒñ™ÏTÖßyî¹t½øbÝg$…`ñ ìÓG…0MœR©Rwùu×…Ž­NÏ|󛇆Æm?óÏ?ŸFßÕßóê«l|àºÆZ׋/òsE°Á)•Æ=öTÍkÛ²S¦ÔlóÚM7Ñ8mZ%Wkê¢E,úÒ—*ÛÌ<å<Ç …ûM]¼¸&7^Ø™S.3ºsg¥0² t œðõ¯säç?O²¹9T(`«‚)žÍ’õêö?ûl²4î³Oõ^ë[ò™ù×3ºk£]]ü ¹Ïu)ŒÔ¼hØ®AÃÒÃy2ãĻËð8Rn¿èbq¯:ö¸¾ñjû³gK cøÚ-ƒS–ù;NYæÄ?‡'ø=Ȳ½jÍ5JÏÓœ”e`’?ŽÆ©UÝ54¶P•Žw4ÑÓÆq‡Ú]A[›âŸSwÊ ÅêjàÀŽh«^ľQ9Ë•þ3Çš>‰ºÛD1:X2€±]»*ŒúÛXooÈNÒQÏàe³4LŸ^Y. SFsß÷>b©kn¹¥Ò¦ ͦRßM7Âö žOvŸ}jö‹Šúq©Í}7´û/|öÑ+ÉœÓâ´m†lÉ&½Õ&³.Gã¶ȧ–ÖAf·näˆ ËÙ>qú³­Œ¶e(R8˜˜1‡D¦Àôì6fŽnaòÖ.&nè¡}CñÆ2óg~uó&ö›×†—:¹– éãs ¯AÃ:ð^†b/ ¤*zŽjØ£G8LÔSìò]ÊŒ‚å€(*T²ƒ&LJËÐIÇ'5|%ü›ãºòý-9P,Ãä¢ïÌМ®ò.©åÜJš}«^Ȧ ä·/Ý)ü6z¦n¸ÞÞ^žy榟p'¼ã”r9^øÞ÷BâDx5¢T˜¢ò3ö” ¤ç2ÕKpެÔWƒ âL-Ó uþQ/¼A5»IHÁz5ÏÕ¡¶è¢£,”—¡L8‰°b´$“¦Ysl_y/ʘ_Ï=ŒõôT=Ö+VàÚv$ã<‡¨0Á->ZHÙÅâÛ’3iáBüð‡é~ùe‚~B»~}®mW€YÔõÎ>ã ¦}4¹în^üéOÞ¶‘;h˜6MJ{?ü0Çj Z>…a ùd'v“;,´Ý´c%£0`ÙŽŽÈ|£™§œÂ”#ä¹ï~·.Àzá? ×ݓϳá¾û( àóÎ; 0¸i#;v„îýö¿ü%ÆK&Y{Ûm¬õåÓG6o `®ÆŽ¾â ^¿ë.v¿ür¤“"ʃ)€u·ÞJÏ+¯üUŽ•šs”Ë”üç¶æÖ[é]µª²Ý„ùó™wþù•m·>ù$;–,©¼£¹®.^ùå/9ä’Kd©´}Ž?žS¾û]žÿö·Ç½¦éÓ§³cÇŽºµÃþ§i“˜º‡Úo+&JP?J$°© r# Ö¨ÂîFD?¯†më Ú9õ¼–(±ºŠ1oš•¨Õù¥+þé@*Gµ\Ž@†w¹²Í@£!jIË0&ûï)>5™,ÕÎüð:(?ê_xÌbqß&™S´™W´ =0ØCÃÐå_C ´—¢’D '®ŒOÁÈS­¥Ê'«ÀÅÓØƒ ·ÇÐî‹ $M“>ª9eªQ-¨ }WA-„…çÐÆa§›)L3”_-ê€!ݨJ´¯—+"ŒÍÑÎNžô#0êõýQa®õjêéÛ±n©„ëy5ïÈxaX]˖ѵlY͵PÄã•Èý=Ô¥º÷/_ýjÍ8UþFhíÁ£V ÁUÈÐ^¤øyÓ´@ÓkM@ú~‡TÛN¶íäÈ)Àþ`ϱÊ62šÉ’O¦pb&¦áô L(÷éƒ×€¥à=bàLøàç?éçüD‘#‰,‰} ÇA˜ždz!™‡dÁ¶þû>¦8Ö‹Š-hûý 0àAë(dÇ 1 ‰¸t¨„’®² ² ÐЈá@¼,Y¼lÚ(:2\5üTà =,)ï©ê@°‘Hà­Ð߉·ÔßxºÔ øñLoo/Ç}ík mÝÊó~=‘z@Hí„aW<ðc}hÏq"+6 Ó$žÉP®x ê׳Š*`îÖ鸂Á gÉ’ ä øT¡:˜« “:àšD«Ty Ã¥zTUC#ʰxÎ7÷Vð`ó#°Y Ú[#io’ü·=ý4ùþ~â™L%'Ç-—)ŽŒà9ÎÏóêM7‘ëéaÖ»ÞEë~û1ãÄ#@¢¡Av ##‘íkÆI'qô¾ÀŽgŸåÅŸþ”Woº‰\@,fÇ’%,ùÆ78ä⋉ùŠ* ‚CÛ¶Ñ»j‰††º×ªÆmO?ù:-bá?ÿsH÷¤ÐßÀÒþ'ŸÇ¶=öX嚦O§¡£ƒÝ+V0ÚÙzv<óLHÊ\D0¹¦î…ŒÇ9â3Ÿa`Ý:ú| %"(a„®ÿãßpçéŽÓƒc…RƒmçžuûžvZµ­>ø ;ž}¶²}®»›Wn¸¡"pá*mjJDÑé¨éä“O¤´öòq²,Á›)Ï¡'3ö¨ÐdÇ7Þ<Ç©ô:HR °ë¹ªQ¿ëF¶šX„r9†A¬±‘’ÏÜF‰!Y@·ß÷LTP ´%'Â^U}5PŠ÷Z>xš `¢ - fúài22¡~²Р0¡Ÿ€^ÌÁÏnËk…âö†ÀÝ Þnðz W€ÈŽ^d4Sä„ùøX¬rß ^‰š€jˆzàЋ+`RU3 ˆêóŽGŒ£qMFÔžÆ.¹ mŒdœv¥ö‰;—,©Þs5ÆÃ«¨ÑΫƒ nx4Ôæ}{{Ø×c便ß{óÍÌ<åþpòÉìÞ /_‰ÕSŒå5üc]Гni¡00P˾EØã(/b?#˜©Ž@]Ö;`9sȨ½TZ;¡­Ó?nŒé`̰iÔO[k¿| ÓJÊûï’Ÿð$ößÃvH·ì;7É#Ë›™xÄ ÊÄhoêeßÃ73qfÖ [æý% i%L„W¾ªðC–XVÖ¦5ïBC‹`Áð_D¡zôjqÕ[Q‚D cМdª|ú\èöNQ³+MÅ‘áë~ùKi3Ô±›Ý·Ô›;‡‡Þ¾%ßøF]ÃÞ‹ð®¤'NäcK—’jk#¦ä_Ü0>½kÖD2U-sæðŽïŸÛÎ:+4x×c¡P™¡M›\¿¾&‡5Jq/*OÉŒOºššªÄgµ¶òÞ»ïæwÇz_TÖ?p‚‚Ai$Y”6@Ī–’Y®*öÅ}ðM’ÍÈêºó¨VÚíðšðÿÀˆ4îÆ¶ÂïnƒË<à?a¬Üa0‹RA82O¢_ÚL ù»ŽQMpoVÞãÀˆ îT¡* :“}›§9Í:¬a½¾¡^y”zF›7›£ßzO”Ô¾¨ãHõ"ŽiF02F‡ðuNFÙE:ÔAPð_îQJY˜ãØY"†¨w¯: r0}jûv¾H•ÖÐl=©{%ê°Ùn&1°“ÔÞ>px49h[ÖTkà1ð,ð ðâ`¶@¬Œ`?à`Éby ;Z¦âq$wühY›ÊÒÌ û°ýÚ^çã_¡¥0 Ú&¿n§PÍ7 ¤žF•g–ñ}&AßÒZ‚L©êÐ0çï ÀŠ™«DU äÉS¨»~ƒîƒt7´ Ékë÷û¤œbëâ)º¥j¿ß„±ãíI™–_{-×_{mäK;›1ÚÕÅuÓ§sÎm·qÀ¹çV½Çßù÷]|1%V3ø\·Ž»Î:+䉬¢ê%—Yïz >üáÊ9_ùÕ¯ØþÔS!–)*æ_-ÜĤ¦}oe“2ÀxŠG-ð†æµýl¢k˜ØZcŽª!¥v^Q÷vú 'pÈ%—°þ¾ûBÞ¦¨iîYg±þž{B\¢©‰Ó¯½–úS:Ÿ¾²þ¤o}‹Æ}öá¡Ï~¶ª¥?ß{.ºˆM>9(ÌñÏeP›×æ«ÿë¿jr.T õ  Œx==ÜuüñŬñÊ=ã „¢h'b@㬠õ‚¢F}ôÙÔ®ÑÕ<«Q5%¢³¨ºdãÅóCt¸”.$ wÐ¥ˆ6ïFTQòª7ù†3XÙÞW~iÜg×ÞÞÊäÉ“¤´ñÿ€iÍš×ßôPFÝøqëôY†Òƒ¶·ë¡‡*†PÐ6ãÔæêµÿÌ:çUkðécЮ‹½½üþØckú¦ ¿TÀ“‘ã÷ë­@³ ‰,eäÁ…ø˜ì×7úËt Ã€X2doà žùƹt/n3ʤÉ+3²n».L@òX?+‘¹A]Ï$Õ²ƒ>¢*»®†BtX¥| í9Õk¼:,D‡všuœ6:ƒb¼ˆãêËfD[ÓÇ´¾Ã«\܈~;*´ÏÝ(uŸQ€â˜¯|…öùóyòßþ‘íÛ#…؃ƒ:¸ .¼I òØ¿XlÐþ§70 ÖÍ~÷»e8¡2þéO3õè£é]µŠgý¨ ¡5:3éE€-£Î8H„]@D£: gI@Üö(}‡W–¹D9$Ó»Ï,ØÍsü—¼¼é‚í™}x•¼Ì¡ˆÏäáŸ>Eú ÙdE‰ÙÇÊ@²…" Ž;p ÙRÎjÖ"Xýp«`(¯µµ²ÂF©ïbpÝ)¥ïs‡  e˜6ÓÇ xû³„«{T¥Õ›ª,w²&ŒBã(´—åýÉk,™šJRÇ ö6z Ó½R^Ä òüÕW³ê–[´îØX¤XDTL¾IýØ|=?è<6l`í]wUÎ9¼ukMqà˜æÕéfp(Ÿ®¨ŠW±éAXEIë´ë?'€¤@P½n#[·òú]wÑ÷úë•ÿxèe—1ëïäùïŸÎçŸçÄo~“öùóÉuw³þž{B¡S,²î®»jòt¶=þ8ɦ&(C!¯^s [ﺋ¡—_–ž ±¸¥uëh¤~RºGmÍ/3âùëRôúÀUCÁŒh?Æ8÷3²v—¿¡ŠWšJÍá–ó‹Ö,þgÔþ~aÈJ¡Å ð¢©œÓ/ÄHÌßÖß>Øžÿ‡Õíƒc†Žáßœà8õ¨)Oi€žÒXƒïAáG\¿øcY)Y–…&½²_ ³®^AùîÇy%(»á¼¢ÒÙ«¹„{«'˜ÍfÿCT,{ÓÃuÆX5f¿ï}l¼÷^„º§–Š’,d’Uu;½Xº.V<[1®tVL}ÇMj#ÔÈ™4U¡ @Q¯EHk1Á7\‚®Æ¤aÆ´ŒJ¥ºT´Îó `¡P£³³t6w0’j`ÄlÀÆ"IVú™Â.̱îz ÎÛ2¯Ë kBêNdýë„CäÚªN@4¯sÔ½ÒŸ…G­Ê¬ˆQåK¢"€„¨3vTÃŽt9q·ŽÃ°^¿­_³:n7ΚE¢©©’3jD§¨ü§¨R..`54pêÕWsÿe—EÚA㇯ýàÓlLÎ&ÖQæ°ÌË´4 !íBr=4î†Ic²T >Ø~%¿os[11ÇßNUúsàr¹ÊÀ‘1ª‰øttPOg¬^ÈȹyÊ#`AÑ®–°#œ;©ö¯Ôa5ßRo²g²žE÷¢´ÎK¢¹¹"Á-"’s…ÀÁ ͲTf ‹21Š$ä²ga{e7†íZØžü,»Žgb»1ϔˮ)·wýíý}CËÊ~®'p<Ï3p=×U …¤ÓoÕ..&†Ÿ–°e±Oac‰2qQ"eäI%¢@Ê,5FH™yRfŒ9JCl„´9†å:ˆ¼‡5b--)’()’)Ò>U„'®Œÿj}¥xD_¤ƒ`€“.ñ«ö{Qu{<„Ä«öT%ªYÛ)¨vª‰O u•d^³ MoN1:µ]ÙÉleL¥‹É #k¥¥#¶q-ÇÌ6°‡Çxè–ç̓ÆõHµˆé}¶Lhrå½Ê8 ÒR¼µáµÑ…æõq³mþ|²'Òùä“5l»—,[ÇW·Ÿxøá oÙB±¯/ÐôPbQg}pŽ#¯¸‚í¾ªg ‹úŸª¤·7<ŒC5<܈`;¡~áhÕž1‘"B;žzªâH­ç½WU] ;a‹¿ò»â ú} Uïÿˆq¢&Ü=Ø]ºp”z‚ñs`Õço±é¡‡*b_¹Ý»™xÐAl¾ÿþºÑõ¢„¨äÌ0n*,“W*±Ý NÖqD; Ærþ²ÈÝé²­>ÕÛÞ$A·˜Ä¦±éô OÄÛº¾æ>ôtOäµ¹m¼ÛXËŒ†­˜B:ýœ¼ŸÊ! ãU¯ÙTÚŸ­1öjH»PHî ¼T£¬ÒRXjß HUN ‹Š)7ÅPn^Rë  å$ð .«Žo8ÞÔÄB_5÷m õ&¦Q I—7W_š &O½â¹†ÆXìI^7ª6‰>7ÍžMyÍl_1M%Aâb’°úž^‡J-ʧÖz¡F5„OeaÕ—Jwök_¸¾Cˆê­M)ÇÏèP Õ°±W4Oh,\‚pøb`ø–Ò;%ô™&\ÂïìÂÚåÀßú>ïöÛïℎàø#==}ì¿ÿ\fÎ܇;÷¾÷ŸXºôEÎ=÷½<þøÓwÜbî¸ãnN>ùx^xáEŽ>úpFGsÜwßCÿ-Ôx ã^„ñgjMAcšSHïÓÕ¬pÊ)ëTÆÅ%ºT†¥lj™Š€‰ Ôù’)ßòjVÜÄ’ò/ºY†1˜Î“žØ¶2ƒe»g°­8‹á¶™ И€ê¬\ÍŠý˜b× Ï7¸øÌšS¢ñ9`¶@¾FaԯפŠÙÔæ¢yu˜W»ïêëúÑë IDAT§ã裙røál{òÉгr" m}¬ª·dÔ1l§z*Ѿ¾H†j<Ð`*Ç¿çœsjBº ¦çM{” “Ú­9Ú˜ìD´íñ„)t@ †ŽlÙÂmgœùõBÜô$ý]3ë°€ã9²õm]¢Å‚¢l·|_ën¿]Ë–ñü÷¾WcÃE©ð9àZ:êåK¬Áìg ÂÅ“c€¥jî ð\ßYˆãmÑ„–ùÐ2:åÁ;FZÌ53ØÜŒ…™wa;8Ëeô¢Â«ÿaÌDrÈugPðŽ¡˜N ~óÇQÏ»œ!ÿ? °'­ f Iˆ%ÀH*ž– Q+W ‘rJDå5SÂÕövw7ò“\¸jÕÛ@êÍœ¼q<^õhjá)ŒOõriêWÔ”ÚñíøË_j*Ö' +Kf´ÁÝÔ:RU8ÂVGJó€yuêwÙKŸ2Hù¬ä ù© žµ¯þƒ ±T ë)ìBvìA_=¿7DÕý®.«ÉÖÖGmo+F¢š ëŽã™Ð]Ò.ÑúþÂõÿ“näA̤!dìe¼Šæ´ÉPª™‘T#™i¬j°±ÚlÌ«Õ!ÖQ&¶okªMÓäADË |ö-îó^}u5Å¢ÌAš={_úú8óÌwðÈ#O2}ú4ž~úYV®| Çq˜:u ‡r0<"=ÿ§ŸþÚÛÛøÖ·¾úß>Á œ{%+®ÏºDµáPR›« ¤Ôüƒ2Ñ‚$-ta–H+†K2§P€@ò¾Eh±} 5Ã?Á¾7R¬œÀ•¬cÊ—°Eœi?ø<©ó"ðh`„î;ž£÷å,Û}pÙÇåà-…¡AY/g7á"±õò~£|ú}÷ªÃBh¼uÕ¿ù «ó›šÊzb2Qb0nD(›n/ÿîw+±Z(¹£©ûÖ^Ø õ£ŽM¥>'¨/Zâ|ôQîþà)*…qõðÂ( ¥wȨóÌ£ŽW¯§K}I÷(‡z¥Yˆp ¿þ:wŸw^¥æf”ð‘UV0¦¬OIg*͈g•§Svá" ÝR@Æÿ ƒ1ìÒÜ1H£&Ë(–iCË4øÜRØ6*ßûöV¸ýnœ¦òÚq XmÎçÐæ—in¢4&˹%|ŸJ–ª`CŽªT»§˜M¦âÈi¤šç¨Út•âঔÀ)VkA©9X*«Õ4 _R=~7”>ÌÿßEGvg~=9ªN=L8è+ßf¤Þ"0¥wçÝ}7£;wòà§>UÓ‰G¥ŒDyxt/Æxê`޶ܶ`'~ó›ÜqöÙ5ÉÍj\|JñL¦ *„Údݼï”Ìûû4NôÕÕÆì¶L¥wûìgY~íµ•^ÍPömþËÚlÑÆ4)‡i´ù?ªÉÐÁŸP³.Uú×g|¼Œ`ÌH1*2ô‹VFE–œ‘!'2 ŠfFD#£F†1‘fH41jdÉ‹49‘fØhbL¤$x)FÉRvã¸EC‚˜¼À+ú€ÆxQ,Rˆ@€#ð\ H•ë®ûEÍ6Ç·ˆ[o½ƒ|älÙ²¦&Y§¬««›<€;wñÉO^Á=÷ÜòߢŸ¿Þ$X½z5 ¨M´Ϭ.Þ£ ÷¨¹¤Q¹žºÂU©jk¯î9·ßÎÔE‹*ÇúÅÁSèï¯D¹š³KVLU_(û–†+ º¡o–{7`Ñ H3!6¯DÿŽ1–ý¹§â^÷ÑÿCǺ]¤[ ±á'ÝÏþ]D9+`ǰTþÛôÜhÅL=÷,Šº› $0(6ìF°0bãìÿeïÍÃ媪¼ÿÏjºó”é&7d„Œ "ŽmhAQÁ'y»°[ZÚ·mZÅ¡§fPH ØÊ$$„0%„Ìä&¹ÉMr“;WÝÎôþqΩڵkŸª‹-¶ü~ÔóÔs«êž:u†½×^ßõ]ë»dm¢–ÊV‰JŸ“37da-ÂßPÕD«2AT©gz„Ã.ž‹' xèÃÆ¨èa¦:ç(E»(€¥‚Ú8gmsçÒýàƒeû 0ÛÒ_ª¤åûïE,qQ"ª² ‘y‘ÏI˺É@VÕò% lÊÇÚ—tð: ýд5pŸ‡éí{9aâ ` ›[’îl€©þ—öá7i‹¾s+/x—Ò}êWY[*ç}â.8ç··É‚=`m¤@ó>èÚ Æ| •‘⟡VDÈ>5 w`Ps|ᥴçgýâ9¡`E&8¿0®3Áƒ¶1hÊùiam•íù {ÇÜR½~°¿Œ˜’±ñŸ7€”bòGE2îûð‡ñ\W¹ŒŠ`h #‹Ä@EEÅäI7°u+\z©Rí-&0Ob֑ܯÊ›ï&Ä.g¤ÉN‚5ÍK©'â¤é–[”é/a/“– RÑ\ío ºqÌg’Aº±¡†2Éz²±$y3IÞˆS0غ­›XF Ç0±c&–iRHÄ)ÄãŒiud¨gÔj$o%(X òvœ±B9;IÞNP°ãd­y'AÁ‰Spâd–§àư¼7Žã˜åδ-°¢«”£4¾eSÔ*6a-tŸ£®"§bYT¡9]J²2‰*W2%å4%!füdC-O=RdIj9’äH‘%¡å‰SÀÄÆÄF .˜‡_˦ýÙ˜X^¬,õÐ-R`Š9ë!Ôc™¼X1 Òòbþ_b~Ú¢'¦!ú@›’ŽVˆð…)TX _§5LÂHÒ·ÞCñJúÍ£ØAG/Ô¥¼*áÆ4F’¸#1ÜÆá¿¸ÝûÈG>H6¨µŒÅb|þó¥òðõŒÓù»¿»œDШúâ‹ßG.秩ɯ—™æÂ ™tüñ4LÊ‘-[ØñÀ8ù|Ã%:íQfÀs\ŸP %$’ŒÁ4ϯY0':ž¦³iÍHyJW6ÏÑïžCç¬$ÓØG[Ï\þ¿Šÿ?µÕY;cPpK,MÈ`„ç¥ § 1²Ð¹ŠõKÅθ¨ôª€×08ùK_¢û‘Gè{ñÅ2§\¯d=9õ³V§3UPU+µ€ITª[5æÉUŒcÈ:¤”‡We=WS‚­ö}™Í³GFÈôô(Óæ¼ (JB=<×d{;Ç~ò“lûÍo „¨´P¢×X¦uÅùyÔN/”ǃ6Ž ½ŠUS¹žû‹1×oZÛ´´—Áœé0½n/ó¶1ÓèæàÄ)ä'&|ÔB°¶QõŸÄúîM |æJ^˜x"ù‰ öNÎ$óº3aô0Ó÷Ó1p³ÛÆx:vAjòÃà¤a8_Zö²Áq†-tÚ€º:0â %‚‰šóOBËûÇ?‚ßbÁÌ’(HAì÷ÀpJö$Œ …KrFOyái+²Â^‹&o)súW¾À¶»ï¦oãF??5®è d­–£¢š«½—?;ã+_aõ·¾U2`Žƒ›N—þÅÚ'±ŒGd¡4Ô²éñ`À×K†VŒLÉAÿœ‹·ß37Ÿgö»ÞEa`€Áçž+–uS€Ö:hhóh|9ÝùàÌ5Ø?­“¦p¸a{õéì`½t2l7“Ë%Ég“äóql+†]0)X1lÛÄvL,'FÁŠû@ȉa;1ܬ^:à¼pð•WÎ8Øš(-¢EÑÖ—ÓƒzÊÅÔmLÝÂÔLÃÂÐLÝÁÔmbz˜fŸùâzx…=fËMð\×Õ‹)yšçççi‚uö·÷Ÿ.šDÂŒ4-¨bÒrs˜–iÙÄò¦ecغã ;n1;ÎÓÀÕu<ÝÌpuÇ0üÏ4ÿؽRŽ rò¸hxZé»V,†c8¦îÿ5üš¯b*£\@ÈMiþ²ãXVœB!Ží˜Ø¶c™Ø–‰eûc,_ˆ“Î62–«#“¯g4ÛÀàX+¹t ¯_ƒ>ú ‡ÑnõWœŒå?­t; µ/÷û3*ïAŸ î_^m"‹z¬„`©Úëx? Ø …œÿûz)ÎR–m«›&®ëâ;S¦Âs1d¸¦`›ä¶ÕúṦa&“`šÊVzŠr ‰`pª2SÕÄ·ƒeS).å_@eßÁ(à/;ø*2žë"˜B_…@Ö\uïPæñ4Kö³Ò5bɤ¯ EeŠbÛ¤Ýs‹*ÁnUú¥ t8ˆÌá¾ ÃÀuœ áŠ0¶¢ËÀôÐú˜R¦åöñŽãc¸½™ì”›_DÚkði ü¿‡â;ë–Õl=ó­l=vtœËüiÛYܵ‘EÚ&ÎО¢Î#µ3‹¾Ù¥ùi—–ì·úl?Ë=¬OŠ ¨hÓ æõÅK N³ýÆßžë»d£ÁùÖ U¢˜G¹œ¹˜Ä"&„ */%¡@¥b¢ózí)Ïó(J.®eE²OF¥RÈq‹«W…âÍ¥Ó‘)"Q—ÖFC@òŽDh ‘!¢0Š<éÅ\~¹‡T^H­ UqqÏåÐ …bF=~“‰Ô7³|å¢á,2ÈÎI²#>‡õÏæ°›ìpçpÀB&WCšßf{TbÄ «¬Ä5"VMZ¡“,Kªœâ3 S³}0¤9ÄŒF‚â†EÂÌ‘0 $Ì<©X–ÆÄõñ1êbêâc4ÅF¨cÌgg‚Ê(Óu0Ç9 ³`ûÚ_F[wÂæFÊzº/ ×ýÓr54Çó%¼…¦*E¥>A±¯x \Ð<ÝñÐ]ÝqÑó†ë¢».†í—Ÿá OÇÅ´,LÇF¦ccÚ61ÇÆpmLÇ&æX˜y§dGËï딯”ºœ$êô‹“SÕéÙ æO û®Å+ÞCOˆHƒØkÒ°’&V<ŽQ0c8š‰ƒŽƒ‰­™ØºIÁŒQˆÅÉÔד­K1ÖVG¦©žá¶fru)t†Ó-ô´3”nf(Ó‘‘ í``l2™¡¼Þì…Ã98’ƒY†o—‹õë_Â0Œÿ_Øå#Gúijj|M#L¹S¥8ÕRS5mvªØx™Ä¿ó¶ù¦ŸuÿyòÉlùõ¯ËX’Ñ58a]l8Ô5Êk`ÉA<_ ôh)¿†TkÀWüšØäéÁߣÀ55&´»\ö.H$ñ<³/LgÓ&Ñåô¶øêÀ&`‡f¶“£¼ÎÖÞrãô<ù$Ûî¹§êõ”£ý2À‰bž¼Q¼f¶Íšo|£ŒÅÑ CåGI¤’³«½Š«ᘋ´ŠÍò¤`¦§H`ð"Žj>8–Íd;—+›QlKdpZÁœiã¥(’3ˆ†P8r„§¿ñ"³¡E¥ZbD°¦QO¯FÜUÈÐ4­­2™"Ó¬Kû]øÑòò½÷R*»Ç!“'†ðÝ6ïch“¡sò–¶¬c³±SÈ¥p¶~ÜîˆÏ3t:l\^ñ ÙÄnÖy=ëŽÿÌí—iûX8s3Kæ¼ÄÛÞ·‚㜠ÔïÊ`n²™ð‚ͤ=Ú€–*¾T]¢b%ø©˜wŽ€Ñˆ9bG¯,|Wª\ÊûщŒ½Wø¾¤þ ƒbYCCCþ·,ž½ñÆŠNñ*ðdH“Q•‹]–¥i4N›¦ìå>F{{ÁqxîûßW’bMTBTbÚ\bQ.sž¢ºÈÂó(`) Š D¦`øGV®$å¯Ç~3H¦µ@l.°ÈQîé:ÃKšØh,f‹x†SØÌBö2~«w¿^žôr·b ‹­ð\tÁ‰ÖÝólÓC3\4ÃCyh =î¢Å=ô„‹Þè¢']ô”‹–r1\´¤‡žôÿ&õ,Ir$Èó,R^– /OÒËÑ३÷24¸š¼a&:‡iuh- Ò’¢Ã9B7FÒË× Ä°Ð@¯3,þN—Î×õÀ⽟bAZlPò˜|щÒM.6½5«‘00¼Àƒô„:!¯PÊ5òDÐb—,¸W(mç ÷C³Á-@>^ÖoPëe|Kèût=I¸D+oÌ[Ö¸B^Ílá˜ì0µ¯¥Ó _PDKcaÂô^>¸¶¹àÜu0š=´F ³Þ"–„ºEàé!Lø@%Eo­%ø;ôéÀD°; ˜SØÓq&N¡Wï¤Û˜I·1“£‹þBînÂÆ8…îz Ý­ä·&pºó?V˜Mã²[uu),8†‘‘ôÿ§ísW×TV¯~ŽLfä5ýtÈ=ˆ¢ä¨Ýˆ`™G¥ØDT¬èœÀÊ«¯.:òz#7&Õ)¯ÁZ5JBÃáñx¾º¨…É}ÐØÆT|i?CXDF!e¦Ù÷Hšk.€™“ƒ<œÞ—}ÐÔ‹_oq诼à{†ÜRḪÇÓŠ+¯T6·tÑœ»ã`‡j¥MyãtðEE2· +!îC”†®&Ô ÊH‘ûCއÙ릈{r&¸j©œ|y<wÙe¼ðÃVM[Œbæô*lœ§¦ªþ’µBÕ=ÒÇÁf…¿kUI@Q)•šrxÔª°‰z"ÁG_|‘?^{-›õ«Š´3Øø‹_(Ù@1˜î@Jâ½09 f?h=NûÀÓ4,Î03ÞÍï¿›õúRÆ&Öá­×`[ü:ÆÎðAÀ=ÏÁã„I‹ñæêôÌNÏÜé<4ï¾{Úÿaa|3ÇÍ}‘æ¾ÀY¬d®ó ‰žìö m$ðeò”+<2Jû€*5B©0jˆbÁÓ˜‡‚ àÇÑGÖTÄZmÔbmò˜Ë¿¤þügŸ}–ááa^ š¢™T°^cq*'Y_ÏçöVOݹ©³“ÌÊ~©b‘³èoêø£J"šKâþøª(M‚,/ áñ§‚ýx””sE UMg!@ Å$&뜜ë©þÙí¬ÕOa+óÙÉlº™ÉmäI€éùbMåÌCÅ&[lC8³„2 Ã!_·2BuŒÑÌ0 ¤id”FF™Ä!Z¢™aZ¢~šðÕoêÉÐÄIr˜¶SJÐ/ð˜`†ñs’ûgãpð^”¥1ÅPšðÝ [÷ˆfCMxž6KÖÃËCÎ-ï .ÖÈéP^ëVFsl xËb'âB —ŒÙ”׈yÜ!yX@ÝgÌÿÝ1Ûš¹Ò©©"H²ž†ÜcÆp ~R£å™LáxÎöz(8®8¾SÙÐW"'5iþX”ËN7c¼1Hch2}H³É¡«m]÷ù©RðsZ§Ï.È“ä…cO`=Çó,'³Êz3{6ÏÍus`Ýã¶]ßþö÷¸ùæ_288Tu»öö6úû^YÞÐ_äwd•<·ŠCìE©¨‡ªVÔ5¶ î{'ôä’JQüÂæ›-˜§@äŠ8p40k¦õ€Þ‚ŸwÝ줛÷Cý˜Y<€§ÀÁày„¢qÁö÷f, S’swQKÊk Z^œ ŠqTAJU¡¿ ŠtÅ}ó"ØFy|ȵ1nıР[´_'\~9u&ðä׿ÙkIÕ›J§z­ èD7ç—Õõ?üa…>P5p©R9Ôj€¾¨TBH•ÏGNy‹j ¬bòiÞ£˜‹òX”Ù¾w~ï{$ÛÚ*Îktï^žøÇŒ»N.ǧO¯86Õø“Yµpî;Áœç\9Ï@" FÜå8çE¦.ÝÇL³›Û~„'æ¼…±cëa}ÀD¿´ÖŽO´ÒkÀ‹7F“¾ÓvŒ=3ílbû”cè‰u±XßÈìŽLt»™â&ey>êìE2pÃÚ±gN˜±2œ@o`WA숢ÀÆåL·èÿj ßÀް…7€ÔŸÿñÞ÷¾7p2úy H§Ð¨žÂ51£–ýR÷þêW‘DZoÍž¹ñFòƒƒUëÿÅE4ü]‹J…"YÜM.ˆV)?Ë) bô#I¹P…(á›+ØÓtjÐÞ±ÉÀ àøD-€Ñ)ì×;¦“$9:饑Q,bxšF2‘#Ë÷òĽ1ÏÆðìbÓÔ°qªë×QJ½‹i =OBÏëv¼ ±‚…‘w0 ±Œ…™³ýç˜Mb(G|̳ˆYÄG ˜yËO³+Ø~ÚåVJky(“uíËC&£yÌåø9ÅI ¥ù} tü|á‚ – y»DP…^”7Nx+øyÆà³;y¯äÈXµñš[é\ÈQË(‡*ÅöDÚÝQDòÃ}† þ¬ï~—§¿ým²‡•õÖ9î3ŸapëV<ùdE19uESwøÿéo;'\~9÷øÃds¹2¶6&|7TªtÏLDÉê–ž`ÄeuÌ„ú˜_‡bŒ@âÄãO½0ROùý|âmó§ocÊ´ƒœ6c-^økvÏ<Š­-óÙrÒöþ|ü`§±±}è"~ô£ŸVÝ®££M{}©¿ÔC^å+UjVT/9¥Ë º6CBrÃpC1¯4ÉÁ—× Uw€Ð\”„PC5ôbd$841€ÕOÁçOž^vûý sÎC!n°sJLU/ñ¼à´k®¡ó¤“8ðüó¬ù—)³K:åÅåÕ˜§j@Šq°(§^uÝ+VpxýúªuOrѺVƒm‰:î¨G½Ï?O¬®®ì»^ wàÆS/=ÐxUX<€…÷Aµ3 %°¡ºN®ÂÿB4µL˜Ì‹8Sjªõ¤ÚõðÃ,øÀXüÑ'}ð ¿ „lªWˆº­Ì(÷ ëäRssÄ…I=`®÷ƒÑM£#œqôô©.sb;Ø6g»:f³kÎ,ܗπω†0³‡Á܇ÿC9è{âî„9 ,šÃ®£g±sþlæ¹/À׿Æðš4íŽÇ¿ž K{ ó¬ÍÀq´gÖ»?•¸?ý^ EX6¼Ãltƒ¹Ú¶ùõ–a0V,s÷ˆn–ìRY#¥]søz µ@”¦ˆJVkQSœ€žÇºÿ˜u?þ±2Z™9xC6D2Q¦D˻©êC¥Š¶È UÔK\Åæf¡CåõZš°êÕ®Ak=ÔMfsñ ™g€Û©“mHbcÒÁRd™ÃLlHÓÌ0õ¹ æ~ãˆ1ä¢gôœ‹îzÚ›‡æf»è¶‡f{hVPóãø5?FÁLzÞÁÈ»9-ç•ПPkå ›÷AL.xü> ®ã[;X®\ðÊÇFx“5Á:;n‰ÌÑ”PŽ3!ftÁ—ÉK ¢#×÷ *Šßu$†±8V¼ÊÔ 9US.¾Äœ7½‰Ã¯¼B:`IU:QYËT€u Øp÷Ý Œ”5sô€«W“d,b‘ˆjojbòqÇá^xÞíÛ±n¹…1Ë­cUœPOŠIûÐÉ'œÀàæÍX¹\qJã_óÀµüÔE3«îÝö¿©7Úúi­ïgn#œ0rKS Îlepv+7§4à+ã¶W Ãu×}‰L&Ãí·/§¹¹‰~ðBî¿ÿ!6nÜÌ{ß{==ûÙ¶íš››xÇ;ÞBGG;¦irûíwqî¹gs×]÷pÞyËxâ‰U¤Ó™Šßyÿû/`ΜYô÷pûíËùêW¿Ì¶m/3iÒDî¼ónÎ:ëMÄb&“'OâÙg_à±Çžx]Ù}Yæ81aæÏgßÚµ¸A½§8î;æÏgôÐ!òÑc‘A2$Û-Ûv9m[Ü^dTÍ:Ô=ªÃxNAÈ$ƒ\aéBЂtÚÆJƒcÃ[áoêµ²;ààìwü ó”Ók”èРXk4`÷ÃÓ·~=™Ã¾Äúä“N"–ò»ŽìÙÃðž=‘ÎpÝĉ´Ï›°–ûV­òšd’Γý†Ð¹¡!rCCŒY SO=#gïªUx^ÉmßýØc¤÷í—ã«G€›¨Æ°µÀèœxöÙ 0ÑyÒI˜Á5ñ\—}«W×ÇQ5:zvLfuþd™ÊúµégžÉPw7#ûö)ï'T6ìU ‡èǧ)Ñuq IDAT®¨k ªõ½’ï‡[ìì|ðAŽlÝÊæ;K-¬±1z‚ñèVaTU —£R{Šyä)ÖãÐï>OC¬Ï˜vÌ>Î=îANŸõ4ÃÓ›98cÏL;•ýK§°®ûLv®=L–úE—0vÚX#1Ÿy÷Aÿf2ï~ ¶À”àðßœ€»çEÿÛóÅãxÏØðn_ 4g‚F…ÂÞ:møið &Ži€ã¡g=ŒV]óŠN¦V€D4 @{Þ¯£ÊSªð™{y ©®‘öúßR†bBª Eåîèª(e÷ÃGv=×) ?¨Z÷芈i˜£ƒÐ2{6#;wµÂf½ad=AeQ°%€€¬À:„â"¨Ó5¿‰nsZÐRúÑ€š_,5×FØIÝriõIz9lÇD·\’ù<Ùš³#Ô ŽÁ6ðz ?VƯi1\óüZÇö#£aýæ”ú‚ÆonÜåJ}ßùÅò‹£ÅæpaŒ#9- aæLFöìÁtÝ G–*ûÃæ„«+MÚøW$¼šgÏfxçÎ2ÊÚ”¾kK @A‘>¡ªÍSUÊÒTL“Å×\à ?øƒ(‹åÏ–ÀXx]zŸzJéL :Œë¨óåU ­ÔOÊ)×\ÀCŸûÃ{ö0,ÔmGMKW{V¬(ŽÛ¨.(Ò^Ä(å¢Ë.cðë_Ç>x°‚‘s¤è«+ÙDá1 6å@z2Ãsp’‡³L˜‘¥óè^&ïëxUöjt4Í 7ÜÈ’%‹8í´“yæ™çX¿þ¥"øÙ¸q3ßùÎM\wÝ—áøãå»ßý1S˜6m*³fÍðžéÓ0M“3Ï<3Ï<€A~ò“_°k×nFGÓœvÚIÌœ9‘‘Qš››ùáoáÊ+?G,ãæ›ÁÁƒ}\wÝ—^w@J¬9p€öyó8åškè»ôRrýýkÄÑ\@÷£rp` ŒAkXÅúÕ¤ÄÊ­ÖŠ´à¯WìJË€SžòNfbŸª¥2_©u0UƒÖha~wP~û‹pöèÌáí~°Óv|Â*,å„r†8å©ç²Ã. &…ó¸oýú²m–~ö³4L™À¦;î`(R*§w¢EœrÕUÁÄõX¾j ÐyÊ)œÔ–ômØÀ¡_dËòåüÍwlkcù¹ç²3èc¤‡_|±¬ï£ Œ¨zGQÅISù»Þüf²ƒƒô®];.ßC!Ç ×ı,z$ 5åÄ©›0€½O>‰É(ÓÈ`|ÂcžµlYPŒ }/½DýĉÔOž A÷`p¯¢ömD€#€SþáØðóŸ3V½f) ØÔr„õˆû¦ZW ¬h5˜:Ù1÷€áݻ޽Ý4™ùÎwoh`ö9çbÿÓO œÆ››™vúéÅ÷=Á½Œoš"XSü/‹ß•ÆÄ^0ÇÀ< uG2ÔÏË0õèý̘ÖMKÃ0½ñ)œðæp8v½±) ÆÛŒ?Hf¬ž‘¾fÒà d2uds'±ë±Œn©±þ5dÖ¼Tv\½£t¼Þ½'8ÀVüÔ¾éÀdð&hdbuŒÒˆ‹N¬É¢aRšºö,ÆtÇßn*hÍжÃÑh…ÉY±ËKħhcBIθ2^ƒµãG`£G¤QÈl\OâV‰ÉÆBîRoFDÒeNÌ.s J|ßµd ‡wî,²!bSIY.]LÉ ÖÒá೦`N¤‚¿¡|zJ­ÉŸ$L &Í,  ??¶58 ^ˆ÷Zt¸ýtXý¥¤ú!|5™ÿ¯Ý c»!Ó‡\¿ØÐ£¼?oØÔ;Ü…#±w®D<å¨ì;bQ^Œ+ »iÂýY£™‹q`ß>â®[&ïÛ‹Z ®äH{”wÜŽràÅÉ?qÉ %¦¿È,¢òÆ‘Š$/`eyö…ÿuî¹ãZ¼j©áh5Ò9\EÀB‹0z~_µðØIK—2óì³Ù¹bEYyT/YJ\°ýÜç*YBU®[pª¤†¤ƒ±x¿>·y&<mÏAsÆ&½:›ÕÓ³¿ìý%—|€•+Ÿbúôi$“êîccYúûŠ©~çŸÿnæÍ› ÀªUO³jÕÓÅí>z Î㥗63iÒDµó¢k¤‚Èùëñ!*ÌéÀÁU«ømÈr(îÿs7Ü‚=MR.Ú“‚VI*EAã”çù›r=ìk mÁ6§Û¼ ‚]ÐT§¼EFЬƒÞñ 6jë4~Z6£URm§”‘P/D¾mÊå·Uig²¸†ìȈÛþþ“Ÿ¬Ê4ˆŸï~üqv?þxÙçSO9…3þ韊ï¦Laà•WXò‰OøÌS°ýâK/eçƒVí1TͶE9ƲЈÙÜÌ¢O|‚#[·Ò©(‚¨s•¯‰ü˜õ®w1é¸ãŠ(ÉŒ«WŽÜÓrñÇ?ŽȆ?ÿƒpÒ•WrÌßþ-Û﹇{.¼°â~EÝ'tþ×yçEž«[ƒÙª¥¨WZ@ Ñ©ŒTa£¢¶×ÌX]øÃŠÿÛÿôÓÜzúéUSÊŠ kG§ýÃ?ÐvÌ1ì[½šC6`e2JQ@Dcø¥F=.€¦—¡ãYHµA¢âmY–N]ÇÒ¦%Ái Ô<;4†[šØÕ>‹ý­Ó8pÔd5Ob‹¹€CLb„&,bÔQmobíþWñŽê‚Ô‚ÀqLRêœJÍñH4å±S1,ÓÄÓ5ƨÃl·IÕ9%±0hcLêöŸù´¯ô7Byº_^x_ R´FÕá õ¦wÛBˆŠr|=Å>UŠ9rª‡ÜÑ]%d!æ¾[”§õ©ØÐ˜ìº÷Þ²G)aAmæQ<Ø6œŒq¹ ¥)ˆfNZ“`N½#ˆjNT{œÚ‚‡¨æ þèUZÂס8Coðìó'K~É‘`NêÁï'…]fƒ¯‡ìQ`ŠâSa=L¤bÂyŠ)qó6Y¦d˜@Ïý÷÷/³‚¢Ð‚ fEÆH•®U¸®/ß{¯ÒYÑ#¢‹r}“©‹j„¨UY ½ˆ…Ov:j‡‹Ç{Úµ×rìÇ>ÆŠ«¯æ•ßý®*X‹ŠR"¥~¸À–»îbË]wU8rD[”ÂR”ì®|-tª§ÔÈÌ‚Ø40,MéRèÏŽß^ Û¶½ Pœ8xðçœóNöîÝÇš5ÏpõÕ_¤­­•“O^ʳϮcãÆÍeûY¹r5×]÷%²ÙœòwöìéáŒ3NåœsÞÉSO­ehh˜7³zõZ²Ù7næ¸ãŽåÔSO䃼ÇòugûÃVÕêF5)&2P2p ›J†ŸÕ±@ž_3UMM¢cC*;@E"˜ Ø!×Ïà±ðtc -G ³ô´õ,]ºŽw‘Æú¿=ͦ…ÁŒEš¿v¹î´ÑÏEoIÓ–ó|¿->£ؘiA`} $§æIv桜¸Ž‰Ž‹­M¸éA@þ(`&ÄCë 4w²VQèAJâŽdŸÄ`÷òçÁ¨d”õ"nÓ¬Y´ÏŸÏ®ßÿ^™oRÞ±]åÔÅõT.–uõ/{é%þóä“qr¹ 'X”6STœÓ¢ ôpB9 *ùòˆŠc¹1XwëAŸ ú,`A@×vÏ ”ò³ÁÈî×ÊÝì <ÆAa´Û~Ò°ãËæŽ )$!‹Ô,œ &½ÀiŒ%]p*dgÜ>zŠíU°jEº^K ÜNƒ®X$å¨bÔ‚`D0£ Ô8˜j,“|TLl¸¸møñÙrÛmä+Œ‘ª°W•FB„ƒ%±ûþ‡âáË/gp×®ª@JÕ³FvPdGEÕ¯Å6@?dÂí_D6›eÅŠ•ìÝ»½{ýÔ™^x±l»ï|§Ü1¹ÿþ‡ÊÞÏž=“¡¡at]§P¨Ô4Êçóüò—w”}¶ÿ²ý-^¼;ï¼çukûÓCy»Wb¦c fIî¿©¸z`ìõ•yâ¢:IzX^YõJ`;+0ðb??YÔA—扨ÐÚLÔ ¾´Iþð²Sâp×6øÔ|J¹Í!BËû5¢º6Åbo“ÊtvG±~ºUì”<µ†ak»58÷iؓӀO GÕGQâ<Ÿ†¯Ôâ%-€9 u3Y¯†Mq#€ÖñŸú‰–zŸ}–½+W*PM°™zÚit½éM>è.2¡`ÕÄÇ£_øv>_øDýŽÉÎdøag'Öè¨òØäßì<åf¼ím4NÊ1çŸÏÁuëŠõ¥(¬iÁ5é^±‚ƒëÖUdØÈïËÖÛ&½ä\9ùïÿ=h¾ë¡‡èÛ¸±h¿ke#hÒúëf³döïWÖ %[ZXðþ÷sdóf†vîŒ à†‡) ãGŸ>msýå—_æ•ûîS^O·ÊµV=†víâ§‹•¾Šñãº×M'`_¹ù¦)S¸dåJŽlÙÂêo~³â»nÈ·)¯Cûz†fÈ ü¬¼@„} Â:4æÁ~ Ò´ŒAÇè| R«-bs-˜í³CÍ3‡¡QC‹yhzásÓà¦ßÂU10Ór»°´!êÔPrLµ&Ï—Go ÕzÁ9 ]\0dõþSó}Ø„q¡ÖIÿ7€Ôk ¢d4>›>šÂÈc£2Á×EÄžO"HRž/:ЬT³¬U®øLJ ÓøBªhHB²ô‰” ßkÐG!9ì÷N×ß¾}ÄçáK˜/†Â¼8G¦vi®#oðs\±id”‰ôÑ>6€fy¥°©ãöæ Úš"*å ƒMÊ•à¢z@XTý‹’Ã2Ðk8ßZB F&ʱÇ“£p4T©wQÄ(¹cL“É'ħŸ®H=¢ û$.&²ósêUWñÜM7á5Mqí¢®‹cÖÕ¡†òzéÔ–Â-ŽÓ$QWWf ÔýheÖáçzL¢¤…£˜k¤@Ûah ó[[€Eà¨á.Öq¤g4°Û8Š#t¦F|Z~‡K]ↃÁ¯CÂ¥E¹Œ»#\Ó„0É ÅyŠ×É–®Ü¨R`c<ÔýŠj¥¨zvÈ@ˆÈœèH‡¿—lj"ŸÉ€ãÔlfèEDz”Δì<¸QaÙÊE®n„#¥b”lmeÿÚµì~üq‰%ÕP§{î4àðóÏsøùç+€I»(Ÿ£l0‡vì`UP›>vüþ÷ìyâ Îúæ79óúëêîæÈæÍU ªåS¼VQL Š Mñœ3¼Ba\N£øáŽ;–óùϪêvÏ?¿σSO=ñO¶»wïå׿þ žçqÙe‰x==n#Ö¯_Ï»»²ÇaÚš&BCÐÖb†‹htŠé$ó²H9É®ç†É‘€’ê½*=˜ˆy%®Å®‰X° ¤à9©Ï±ëá§ ôCz³~*Ð`ÂóÒº$ÖGéU€”jÞ¨œÐ„Z™W#U¼û±Ç°ƒÔö|ÀpÁ‚×b¡B›¬Ù¡!<Ï{UÇR«·Uîaµkµï©§è”O©¾ö>ù${Ÿ|2òZÖêU­^V®ËRbªj6! ¶ãw¿cÇï~WPËûØö_ÿymåëîd³Xé4žS²ÆÖØz,Æ[þùŸYùOÿT &Fý^µ^[ª×É–Ð4ÌTŠ3ƒT€íÛéߺշGA @ǸS­7*•g±W–Ny¯:Of‹e£Aà$ÀM¤ûaÒ4€úí ïüÈV!_€Ï7<×M„Æ !\Ö‚C `¸Pb¸”²¤&~–T]ßsÑëìCÇJ²¥áA‚…¬W²™2©`¢®{}H½Æ@JžÔ0ºkWU*ʽÊH8.-¶&åãD¨¼H‰il®Âq?“SùÚ‚AÚ LР¹¿Ž©CRÍÁ`­U¸“p œ6kFŒþ mt3“½Lg?S9ÌlLLl:8ÂLºÑq‰Û´Q!”9žÉ„/aYGIa%œ´!ƒ‹ˆ¸ÊóT5k«¯§®µ•±ýûÁó*Ò¯thR©F-’á6±æf4ÇÁJ§ËŒ‘Á^¨z>xÀywÝÅ£W\ÁHº 7îTC]mÛô?ÿ|Y½hH=é{ªZ™Uy1Hq3k1½@3 >õ’/…ºâª«Øº|yEÿ59Ýr<ÎMÔ<õ$€¨IçèEìW®¡zö»ß%ÑÜÌYßü&®m³èCbó­·VÉ wQ<ù|]‰5pñkÅã}ôöä†n¤µµ•üC8pˆ;ï¼€K/½˜®®©<ùä/^P_6lbÏž …—\òþøÇ'Y¶ì<ùäSœxâRêêRŠß9Àé§ŸÂQGu‹Åxä‘ÇÑ4çž[ǾðiÆÆ²üâ~ÝÆÙg¿Å‹pûíwÑ×w„Y³f°lÙ;hiiþ«²÷×]w]w{þyê…{Ú,1˦ô4¤(§%j1» ¬síz^°sª>„¶4Wúz’­­FG‹`A7MÌxgl¬È†…µ^ÍÁ³ ˜¬Cs~JBä›`¡q Áà=¿bà Àˆåg÷ RÒ*P.ÁîJó¬Vó[•…^%è4q€†ÎNF÷ícë]w‘¢N+€V…%çò÷ÝGëœ9üìØcÉV,Þ8œiù}ý”)E–%?<ŒÔ©Ôåª 7$ÚÛ}À××WÕ¹¯U£Ó0u*£û÷G‚•Z Ò  PŠÝÊdÊ®ÝxÁÿ¤iª>#‚æ<ÀÎ(ÛæÅŸúÍÍ»ì2ž¹ñF<×­Øßx^F#Ÿ ”ö(vU(öK–­iÿ‰‰A? ™hqaÁ Tļ xYÈ[¥@(0¡ ~z¸î:{ûú )½Š!UøLyJQ)o+7F;ÍË€)CecE›Ê椞tÃã Ó" °¥M‰`! ©ÓúàËYa–iÁç“Yà­q8ÙÁnf°cØÉl2™~ÚÉP‹N=&qˆiìc*û™ßIó®xX ÎË`÷@®Fœ’LoòÔ<(i‚£¢)À@e˜uÞy¼ùë_çK–àåóe×(ªáŸªToÂ|ìe—1vè[B4¤Vá­x¼ÿ}î¹h””£Š—݈ñj¡#‚ƒÊÚœ¨èVT½Škï9?êê*~ß@]ßåR^Ë1à(y¯Š#äQ[}v¶ogxÏî|׻ʮ¡®`E‘À›¨Ú¨ª¯2ßu#ŽO•öª¿€o}ëŸØ°a+V¬ä-o9“÷½ï½üâ·sýõ×põÕ_ä†ndÙ²wÐÜÜÄ<ÄW|šƒûؼy+ëÖm`Ù²w°iÓVŽ=v/¼ð"«V­ ­­• .x·ÝvŽãðõ¯_G[[+{öô0{ö ®»îKÜ|ó/éë;ÌûßÿùŸ¿&Î0þ<.»ì®ºê9óÌÓÿê€ ÐkŒƒ5u³)Ûñ) $›'Ú¾(§T®Ë=þÃ望oæ©o}‹•ÿø~ vWSO=•Wî¼CÈ@h-a&:€Xk`Ó[ Ww÷ÃäÜ{"ô…OHƒwÈï§Ôxw”’²©!9F¥}ñª¬¥µîMÔ>>µa©¿÷Ú£W^YT|óv¼XõÖ·*€qln à$ÿæÇÖ®¥iútþxíµ<óíoWõE&p]³¦b›kläÄ/~‘õ·Ü¼¿ýÛ²š¾Z̦§HŠ- éY‚ÍrP—DÕ…Û”§#…ÆlèÚ ©ÃO)¦â9pœ…s°r>PX.—’"´üÏ lÎ! ÞƒæH”üiC:¯°-DxLiá}N T‰6ý>RaVJ':çWÕ÷)ªÑ©è„‹ lØ#6/E--)òç) ™Ì<ˆuYrÓݤZˆòL@¥) ð[Á*<_¯,=Æ:ØÇ4v1‹nfr˜ ŒÒˆIŠ,- ÑÌ0]ô°Í´í„5ÀÀ*9äëM ~ªšóe eÕ3‘”ï×+Ë—³#hÀ¨+X "XWÁLEÕ¿¬»ñÆŠÈCe®tiªòéU¬‘ªÇ™N¥2Ÿ.E‚U Šƒ/AþÊý÷3°iSäþ£¢œQÀ%*r§*öÛ È‹¦']WÕ8Q)V+vW¥*:é4? N“Ê"UuÿQÍ•æ¤QãÚÉÒÏj$6dšÂÇm·ÝÉĉ"Î(¿ÓÒÒLW×4ºº|…©‡òŸƒýȶß÷´²ï|ä#S(XtvN.~¶hÑB>ó™œ1;ë IDATsýõÿ¦M[FªÜíèhÿ«·ûa,ÉU8÷*a+€“STY åï¹í6øøÇý<À*ŽážGå¾ /d`Û¶bÙ€××ÇàêÕE5ÖÆÀ— “ êêÀh²Ú`‹íƒ“µÀîÛ¾wce`Ø+ÕBÉ=©Tó'Ê~Gõls#j-ÂÖÕUçüä'Ä›šŠÿ;öŸ ëÍoæ¹ï}žÕ«k6ѪåQ±JµØ6UÐõÄ+®`úYgá‡^|‘§þùŸxð³Ÿ%Ôñ”ß4j+þ‰Ç¼ößþ #‘¨z­Ç5¸ï’KŠ=¤ÆÛãJuÝú6näÞ ßÔðîÝ‘ †ˆu™°ì0¾^PÚ8X)UØ«€ñÕK{øézáõv.Çö{ï¥02B÷£*ïÍÙ7ÝDCg'÷]|q™"¡ LÅT^“ò²‘8%†8j•Y­ ;+ö` ]ECÜ7å¡áÄÃ#A â|þ; Ë$ÛWQ¦ä“‰¢¡ÊutÉ×’ƒUYEÀÊ‘|ñ7Ä&þ‚QI™å0$ªP-¦äYT6u¥›ï@JyKs¾Àìw¿»xŒùË–Träèx|! Ši5†SsÁHí‡Ì¼âAÚ€%{ 1ç*ãx;n2B´1D 걈‘ Ï3}ÌbGó2ûÒ~ï€Íàmƒþ!?í~/~?(usKU”Ò”œYYp@”’w 3 ˜¸Œ€L‘{D×>‹Œ|ÃûÑ}-¼*ÀΉ؟F¥èIµˆ¤¦øNÏÓïí­¨¢’µ¢pnÄç2;d .¾˜­A¯'Õ5ñ@Ê¡²GšÊqk,zzÖM5æT=rÂs2¤ßQ±k*€•i‰¯öaS¨¯¯£­­•d2É3Ï–,YÌ 7ÜÈ¡C}‘¿ÕÔÔ„e•Äv§L™D<^R?¼è¢¿áw¿{€ /ü::Ú¹ãŽå¬\¹šÞÞƒõ¶?,é4"€”¸p‡Î€­T*; ª _o¼õV\ל§¡½ëîfWww‘y23“AËdh¥\‘µÍ„¦8˜A^·ÝOŒAÚ„¿ŸØÿ°~uò#Ð_ðSm† åIA•º©xŽFCz<Ž30PL0ª€/‚Ùkêêb¤§§ÂÙ_o¾óN¶ÿ÷³ðƒdñG>¤%K˜´d‰¯f§i䇇é{é%%Ðj°SÕÞw,\Hª­Í7‡ÕIåí÷<ñý¯¼âÇ-±°Ü‘Á‡J¢·J“_Pg`¨Îÿ¡©3âE) ëëcÛ=÷TíÉÅ8îC5‡W{•Ûi5˜9yÖê7•hnfâ±ÇúJÃ}}ôoß^8 ÷™`û=÷(¯Û6pvw+Çζßü†x½Ÿ6亮òºÇ$Ÿ4,%2„àž¼QY ®¯n9ŠŽæ)‰Î´ØÐjCsZ2 ‡…¤,ÐàÍg·U©Ñb]³ÄõÃææÉ€¥2ÇqÏTâc6•Š¢rÿ­7€ÔŸñqË-·päÈžzê©2Z•&%3Qâ‚"ËV•þ!/Æ"‚Ÿ­óæ1cÙ2f.[F~d„}kÖDª’i“Á“C®á9 uýF‘$DTâ¡ãúuOH‘ÅÆ¤Ž1HÓI/]ôp{˜”=D¬×ò;éö‚{ÄW}¥Ô+Ç“&† @„×XV7”)k‘uQ±Þ8"Ê]gÅØáÃÙ²%ˆDõr‰.Þu `”#2^0% ETKyðª°Zò1Y·®ÈªD ˜x5¥p#bV‰Vq×Zl£ÎEWÜãðÍ\¶ŒþmÛÚ½[É騅9´*ªÖ¬2ð¢ èûSº®74ÔsÁç0gÎ,æÌ™ÀÛß~VÙv²,ù¥—~ ì}>ŸcéÒ%˜¦©È·hÑü²÷ç·Lúÿ-*gǾøÅÏpë­¿þ«_ B´UÒí*@JùòÜQ5…Ç”¨Ô¨¡0ÛeÄG#TemР)õ¦ßdÓhÁO·i„W\X“†ùMðŽ&J…ÚƒàŒ€†Ñ‚©ÒBT×Q0¥ºtlâµÑ€ÆI“H¶¶280Ptêä6(‚#b-pÈ N;ýt¶._^ÑvK¼V=+ýjÉÖV¦Laæ;ß À›¾úUNúâYwóÍôu›Ð|ÔQtÌ÷Çqÿöí Jm²½é:óLâõõì^±ǪìÔ3ÿ é<õTö®\ÉÓßþ¶’©>¼q#‡7n¬XK¨aS¢œ{} ¯à©õz\lŒ¦1ë]ïòÏqÓ&ÒAߣjÁ<—Ê ZÃYKTÅwˆ‚A´@RøYª½)'„ŒîÛWì¥z4vuqZX[ùØc@ŠðZ‹e•oÿªUe6A¼þºLN‰v@S¢ÛgQl W¸—ëÅûÀšRl¤JR9ß.iasOàýIøi>ØN©~3LñKYaŸŽÀ,yR J¾Ö*ÿ:|ß4cíóæáº.»yDð}HýŸþô§øÞ÷¾Ç£øCqQˆRà’£Óá P¥'8ÑI9ÂîP^`ÞìΓOÆÉfÙ~÷Ý uw³âË_VJj‡Û'(Ï… 'QÞx&˜\cÜõgaÍ™ÀÑÀDpã­ 2ƒÝ´0„ƒA‚øÁ ih¨ÿ³ïÿ¼óΡ©©á¯zÅ/€–~¨l…!«êE¥&ëÒ<Ù]C¸Ä’(Z$Ö߆¶4¬ínê Ђþ+Ûâ0o¢ïUm·à¥!8gLtðó«‡Á‚Ü dõ¬PONƒ{^)Ð\<.ñúX€»s'ù€ ë†Ã§©ØÞ¬¨j¨;—//¦0Ö²M[—û[Þ+4©رƒ'®½¶œIZ°€%Ÿøà7;R)ðkÚçÏç»dûû+þ/+Vsˆ‘î;T¯ùQÙj­r#ö¥ê[¹¢Jà¬xÍ5ã>ùIÀo†;²oŸ2ýi½©vMÄs1P×j `Y͈b¾ä e}g'Çç³ûñÇéÒÜå}Ù´‰å眣´ñZÄùÔb䪩ª˜ËÐ/ TØV©‰’À™!Ø­°–‰¡ cèrïÍ( ,ú«1a_á\6<èÈBÒñuPŸ‚ .@§ãƒ½Qß 1$Í}K0–[@Èê̪¬/ÑF´-\Èâ} §P`ç#Œ«©÷@êø5t‰QEäîŽ(y Á‹pò|øÃ¼é«_å– Ø|Ûml¾í¶âDŠ]sæÈÆ„íÂI”´9ien fà„`õ; ¿Fj0œ„Aœm  ãb#NÒLà03½nêF²° ØìðÙ(À.”&§I¹ø ,þØÇH47óì÷¿¯4ìåÅüª®÷:êÜú¨è“¸hÀc_øB³3Þ(]”ïW1îF§À=ª¶ x8Tv>w#}­ÊbîE»j¿ñ‚L™MÔˆî³õ]£Ê=ï»è¢¢Ók°LQ ƒUÇãÖxªŽ9jQŠÂðþì^KK3Ç¿ä5Û{{ë_½íÏ ¼)•ã%×BýíÝw3ÜÝÍŠ«¯®˜'š°ÐêTOWH )Ò\'§z ½ÁW´Òë@«‡ŸÀwöøÍsß:o™“âpádÐ*”˲ÒÐçùoà ¿QJ©;bDZœ7bϬ:)'Ö&‡.Ny¡xè…uÁ9üž0ÛXÒRÁ3DT©Ò—–? /Yh¿é…‰&\>»Øâ020èú`+ §È ¤ôiK?ÿy6ÿð‡Åßûg…âEM!ë¤þ# ZP8¬ùEš Zp±´`ÂxåeÀóŸi«”>&8T*íˆyyÚ5×pâ¾ÀŠ«¯fëwV ÉN±ÌÞùÖ·¢™&…ÁÁHÚ›¹ï}/Ë‚ö7Ï›G!VÆëÈ…ûùÎwrÌðÐå——¼ZA'Ñv¾ø³Ÿ±%…×k€‚¿ü%/ß}7ù¡¡ ¡9E®šŠêÝUë~ˆ©ÐZ:áŠ+Š½Æ´ˆµLWÌiˆnuR LEµ;Ñ¥±å/ß{/»W¬ÀQвD5Ö{ƒ†s2 ¡‹b3±Ðu-講ÌBÃÔÙåYJV0×\Ûæ•åË‹À(*h-F±Ö=lñ¡Ô£)zη yî/À£~Cò¯µÂçSP—7 VÁÿî %)ô´Tç}8Tbâ1?ôÉOús8˜µ2ƒÞRfFÊ–¢ûªâ{•³ZkrªŒŒŠŠ#¦N“«!1;²C¬*6tƒ(£'ЯcøªG‚˜ãÂÌ?B`Æ)Á 4sÒx˜®™µ}°t xÄ_‰#>VÆ\¿_À˜[’ºÌ£–·Òé c,+ëAe~¬a„£þWMŽ6JÕMÕÈWfå^âvÚ8~_Õ#˦v'Ä37ÝT¶°¨c½ŠS /DQ¿­:VùzløéO+7"ØU"سZ‘H· @5 R–—¦+ `ÔV€©¨ÞQª9?ÿ¢‹hž1C10]ÖÞxcÕ…ù®eËp,ëO6î=öë׿Äĉ|ô£bíÚçØ±câÓŸþ;vìâØc‹ÅX»ö9N=õ$~ÿû‡Ù²e;]]S¹øâ÷±}û~÷»?püñÇ2:š®ø Ë²Øµk7ëÖm`îÜYœþy¼ôÒf~دï¹úê/26–åG?ò{°œþyäóù¢ˆÂ¦M[™1£‹M›¶rê©'cíÚçèë;Âöí¯pñÅkêÿší7¨¬¬æ|‰.«¯¯˜Â,×6‰ÂDb³ö„ô¿Á‰é3!LSO?îG‰Tú­¦Ì)‹iô<ñ½kÖ(íóxmEax˜BØs,ÂËFF‰d˜ˆ°·.•u«šâœk0"®—¸ŽlúéO•½åãõÆX˜ûž÷Ð>oÃ{ö°5hä[‹é“×ê©}ògv:•N+A˜ªÆVVÖ%PUÔéK€Þ$ÌC#ðáÆÀˆArÌ7¯¤â!35:Z‘ÞçE“G¹P„ (ŠL— ƒ `8«³¥íþnN¯ÿì½w˜Tåùÿÿš™mì²KïH¤ˆ ŠŠ@TD$ÊGQƒAå£ùX&–h“آƂQ±TéK‘^¤÷¶”…m³»SÏùýqÊ>ç™çœ™5ó½~û\×\»sæÌ™Sžç¾ï÷]Þ7ôË¿ü¦×_93wâ €»ýÕW툛5+°›k8`\¤~äáWx"Ý<ðn5ºGØ9àáuH^K+Ê$(YÙ»yùU &V6“ÙÅg]ˆE#Xeº*­Scº ö»!r *CPSe¤ˆhæªÔήØVšFŒä&Â"YÃIC‡ÒîÜs —–²ÂLóSë» ÝT=xÒí2Òyç‡9´t©k—vѳ„¥ßCá¥#Øíy 0ÙzÜúoø=ÎO•OîW€wÕ}”ï§ ÎÂaWàBŠíZž>™ÕÏë^¡0H¼rËÁ›%R6”‘¢_©X¢|@ +‹æ}úÐëšk×åVK!~7j/?H•—Wðý÷›¹õÖqlܸ‰¯¿žÍ'Ÿ|ÁCý‘V­ZðôÓ/pÞyƒX¸p ƒŸÃ¢EKiÕª%ÇŽçÖ[ÇQT´Œ%K¾cÁ‚ÅÜsϬY³žp8¢EK}¤Î>û vïÞËÃßÏŒ3Ù´i+=zt£sçŽ<þø3Ü}÷í,_¾€mÛv°`Ábzõ:…ž=»3wîBÎ:ë ûïÔ©Ó¹þú1\|ñPžzj÷ßÿûŸMö‹Ìšª”Ñ IÎÈõ›bãu° èg:"PÊÞgø!0^Áü˨ÝqJµè·™V+k'l®îl‹Ýaòû\˜]U{~gD¡ZÎ¥€tÿ5…1«ÕÔ¯©IÊI·N…Ow‘M"P:±u+‹þúWc»À¾¨+"+^D52y’‹7,Öyœûç?ãóûÙ1cÅ+W¦¡ò¹dxÉN¯û¤"QÊmÑ‚~·ÜÂÆ·Þ² <Ägåw±¡Üô|®¶® ‡ÉBúæ|¼ÛYYss fg§ŒVèÍŸûŽOéöí|ÿÞ{)Ÿ§hÆœ»é¸ÎZhËqÞÈÉ_CŒæq–S#ˆÝ—d–A“#] âµ½s­¥i¥Ôáá ”Ÿ¿X/ê3#ŽL r"°8,I^«†¶æEßš¹aÈ AVBhÛC- ºE”‡ÉE]+™ð°Ë5çq=ú †œL @NÆ„++ÑâqG°ddgû†ÃI“_N \³‘!¥LIAgJ@Ë-oU$äRgÁ°µørj›F=•µŠ£†·ƒ¯¼Úü{âÛáÄQ8®Í‰IƪØWË'…eAÍZ§E"ÄC!âÕÕóòð M«E£Äªª” wà }D¢èf?–œÂBðùÐ5x$BÜ|FYæñ#æ¾¶ÀFц&U“>1ê“á"ÓI)ôª‰Ù¿p!û.t|ž)ÜËÓ(v\WÍãt ÍÈÔUØèi&Y B“HÕgÖ%ÅkÁÇè|h—!8º4#5&®A<5;@Ó 6¬GbÐËüÝ“~QÌY}Y¬V1ɳ,Fʲ…Tc Ð|—k§¦©ßÍÍÿ 02òEe‚³ÂÝ ùÖ˜º¥ÌÔ)GA/ƒhØH “•Ú'¶‰‘LÚ!:´¨ÓèÓI­KU§èE•¾zâDWyè  ¹DLÂ+ÍHªäѪ*|>‰XÌUæfØ=¡â55¶mB}:L‚Jù¯iÄC!4S÷ŠÀѧˆ¨ ˆ"h.©ZU¨œ€éô†ôa”l™:5ýÚ™D‚x(DÂãžâá´Î!#;›X8¬ŒúÉû‹iÄqi=82)¬¢F‘¾Ïoîd¦gÄ  ~ 4ªtgV”e?ŠYb¤Qu_­”[‹™9Wð™D¼(ô4åŒEÝx(­ÌâÉ—J,&4gýd.p®pò¤à€&'ŸbÞÉ÷±>"õVÈz@]ºðë9sølÌ.Z”$LN»õV¢UU¬}åGo£NòËÛ™“Ê6g#µ …Á“èÝ©Ó- KKW‰ÀÉŠ YûX¬KY¦Þk ´ÃÈ¥46•¢¥,X Š!~N˜ êù‘™É”®Käí×INÕƒæó€po‡=ÿ¼Mc»ý‹/˜yë­®Š¬I\ýÕWöûwÏ;Pq1ÙqËŽddeQ}ìëÞxƒ•fnõå~HÛùà Ù;>z<Ž8XT””ÖçVãäO)“g^Û¶èšFèС”`DEë:lÂ:jïûöÀ”ïÛg/« €Ì|£°­æøq55irªLƒ-ðƒ«Ve%èº TµXŒª#G<½o^§QŸ|Âá5k˜û‡?x 4·1õ ‚o¿eFáIS3å‚j¯Æ*ƒ¤l÷n–=õy­Zá ÈkÕ 4Jó¹§ä>ŸýÓ99Ù x‘H„-šÑ©Sò…ï[ÿ>”¢¢e\tÑTV†èׯÑh”öíÛѦM+N:©=>ú4YYYd)|ƒA.\ÂÖ­Û ƒ tùùù9r”ÜÜ\‚Á úö=•G5šTwìØÚsã×Ò¨Q!¯½ö7Þx……<úèÓdgg³jÕZB¡Ï?ÿ2ÑhŒSNéö³ËÙH倘­”œ^V¤)lŒ›0pp›à`*ÀHß³ÍÙ)1Ñè€nF¡â¦p×c Åkë"8O_ º¡XÐ;—e„ˆ×Ð@Pyfp©±š `u÷mmþmd^€U˜‘- HŸàY³ªÏ­‚§ã¦Â8aü¯í8$*!¤›CB´L¤iÓžUiÉÜ #ü)œ¥nüTN¢@f&Á‚ªsKÙ……4ïÓ‡kçÏà£K.aç—_¦ü=ŸK‚,7›À{߯gÍ"ßläºäñÇYý⋎cº5¢õ¹DBRE¸@øØ1–›²/çš’É•d`åF¼¡rº¹1«â÷“×¢¡ââ:eøê#Gìëôj¸ž Hõ7ŽÕ/¾èêùdÖNšDv£F |ðAŽoÞÌ+=z$¿?M%âtÜž£ê7¼{)#Uο*Bs¹ÿn©…nçpÇþýä·5¢B‘òrž.,ô4îtÁSºývþðÐD£a‚™HDûΘñ ݺu!‘HpöÙgþ?í¸zôѧyà»Sî·xñ ªª*8ãŒsiܸù~ãÇ'þê«ôÇÙd7 8·ä¾H"²ùG€G`‹=ÚE8É%ĦÞ~œÄDqɦÊ.ˆâÞXWxjÅó¸yî Mà”G-ÇP#3•]h*ˆÆæ†¦ÔÖheLa'S…F„PX%è% •V‰r(‹à©BÀZaœ²~ …,«ëð»ÈY¯” ëoë8ïÑGyï‚ \?üå—éwóÍT:D´²’ý‹óÕ¸qi±ÌéiÊÐttE*gš/ g–WT^óÃZ XtºÊ¤˜~¸œ§d6lÈÿmÙÂó&ØôÿsÇï¡ ÝšrëóP~V"=-[²±øòCfKð5"Æq˜2©2 7«çÁCXE+ ›®Ø\“bíw¥  IDAT¤-º&É 8µÍtå¶Ô;r–¼&Å«œ-¾l]KŽh¦<ë$§±yÜð´)£ÆŒäI“hР¶ÝG$RIuõ ÇóY»f½zžÆÔ?dæ]tîܹ>"•NDJìÅäÖÏÁ'-x1½CN T@Êþ€ñ Àç7À“ßgÖ+AR‡_]¯õDZú©JRVJ„Ea›®E¦Ë,°ž‚ /c!,2T˜äýVêGžàxô ‹IÇ™~( Ñtî§iåë.ï6M™B^›6 5½w5%%¼Ò½»§g-Ëžî¢`ýÀ@<þ«=z$449å†üýï€ÑÔq…ÉDãu½ncéã³ôñÇ•ßó¥Úöé40¿ÿ¾6ºÑ¶-ç?ñsï½×q}š‹btk†¨ymÛrá³ÏÚï.[Æò§žrœ¿Ó€Ž\Àé·ÜÀ´«®ÂgzûÒ”*eîe4üT#³þÍ7á¡þ!oGù³þþj³uII M¨­ âl|)f LGR5Fׇ S®737ãGy8ÒV€ À˜ð×r [†DD0jâB¤&Ž:5 ïlPáä³ Ö ?dæ ¨Êª·ÐÍ ® –ž«B u‰ù¶qýUC¬ÊM¢‹ ÓómÕlY»ÉÀONÉ’‰™þ4tRü49а}{Î{ì1šõêŨ©Sùöî»)ß»×áÈë~ÕU´ìk°UÎþíoÙ2mš«¼Qe7Ô…b€áqÓS\·›SÑíþh)λÛå—ÓÓ¬]3i»gÍJ"òR±²¦¢¦÷j!ƒ‡sOµÍªçÕWÓýÊ+©.)áë›oVê¤èŒ×óqËd‘ÓÙÅ~˜>Åõ‰)ºÖú‰jÐæ°‘¾g 1'Î ?…E0ÖyF4 AN)D"FÊŸeSÆQ¾„dÆpfY÷¢RXÏHÑ-Q¦ÊÀJÕÃ/&9–ÎÆÉìim/v —¾ÖÉÞ¹s“®ûóë®#`ÕOÆãioÿÝ»wýY¿¸¸˜%K–°{÷n[‘#­ °Ó|¿ÕÜÖÌ”í}M”øfÀýæÿAà SËDF²—¼°QÜ£÷"ý~ÓNbøÄ‰]¿ž¹÷Þk_Ûÿ¼÷{¾ý–u“''/VE¾yþM€&~ÈÌ\Üùæ I˜ÖI¸Ö›+ƒ²ˆ‘–1…¢£‡¡nÔn%Ìú­*½ÖùgÕOTálÄ©*¸WÕ y±·¦Z×n‘H/Úì"¥¥,ýç?íÏkNÔz°¯˜6æ}úÐHðZ÷=ÚR¾4t—hHåó žëðW¿¢Ï 7°rÂv éòê^=âëìûî£ý!Y»–yRä#ëÖ3SÍoÞìJváóp®ºEêPùç<ø m¤xåJ>ôP’>ŠWWóÅ5פE…Ý´gOº]qñš6ô{LYŸnëÍ´Éú¶ÇÕW³Éìß•À@ÉŠüÄއ€Ê¡±–å(Ï‹¦ªÀ2H(²m aHDŒ¿ºÉ¦§ÇW\¯5 -óPì '¾¯Ö·*Ò˜!ÙÔbÀ; Sb}”ØA”¹5Y²C Xúé‘z ¥ˆH‰µ=b*…N-S†(ÄPfHe9>#Þ\.‚+QO˜“ÀŒ8E5ˆéæK˜ˆb®{L:/1’-¢d ü!6±’L­ƒVa„~Ç ^åZm:_b"k‘·4*•PnÙ¯9Í›S}ô(‡W¯N«oõ=-úÖö¬Ù=k–ƒÁ—F$ R7óµ^{çÍ#ºæ—ËQ)MRœ‘ÒRvÏœÉg¿ú%[¶¤Œ¼é@nóæ´ì×NÇ“ݤ {¾ý–Û¶%)TëóZ´ eß¾”ïßϱï¿O¢ôM•ê±û›o\rÛsαë§Ê÷ìáø–-úÛtX‹¬ãÅB!vÏœ©ü‚hÙ¯û/¦l÷î$/  L tà€ÑͼkW Mc& q`ñbO¶.é“=,yì1ûÿ[·*Y÷™u^€R«·?ûØ¿?>ú(›Ì¨L_Ó£ pДm]Mùù? 9VȲnÂ~e¨Ó…QxyE@S'·Ö â>í¦Ãðáø‚A*¢tëVªL65UšPåºí´ŠX-ec¦;è¥/‡ÊJ8š¨­mÊtaPð¼[åð«‘1Ýå&ÏÜÖg£Îiܵ+‰hÔ6v­Ñ ysZôë‡TîÛGɦMiE<ÜÀJ¬²Ò!«äQ¶s§ ¤Ž®_OH¨+ÕI\F¼ÞöƒÌÍ5¼êÛ·;ÒÔ½ŒùF;Ó¨«ÓQ)+ãà²eiO·mr¤®i¯^t>œöC†Ð eKö.X`¬­… ‰UWS¶ke»v%90ëUsK!ÔêàòÄãì›7/-ÚÛ·³KzÖª¦Áþ4ž£ °239éüóè8|85ee†ÜY²Ä οt:”c6Pu𠜤Èa¶nÐû4ÃîÌð›ýÛÂÔÖ5fádhÉþ÷ƒ/2ª!#,,\³`QõX1Íx寥%"ÏŒ.]!R„*‚3Í/ =gQÖy¥ÿªî¹UâYjnûå/IÿþýëÔO…,s% ÚÌ"OVcÂ\œiÙè÷ùAìLz ×tóeFÄœx1º“"8´Î¹ƒ…)'W˜YVØWlƒ]a)ý„Ñı&f8%+©¥Ð­ÁIo®yD T 7ÅÕqØ0ZõïOñÊ•1SoÜ rÅÑvà@®R(þ™“c3õyÕÚøÒThr4«bÏÏHƒ LÉ  àÈš5®ç$ ï‚öí9mÜ8,1¨©[Ÿq† ¤TçQб#§ŽÇîY³8f¦éé¨ûˆxEíP<Û“/»ŒÂNF6òöÏ?çø–-®JÙ­É­/ ¥Xº};mÏ>›}úØÔº^PZõïO÷+® òÀ,^¬ü=hzÊ)4íу#k×ÚFJÛsÎ1ˆ",ãhϯZe‹¹zOˆg¸óðáÍ<ícß%%õ‚ø?4fÏžmÿ¦š2ÍŠ'œ/(IÝ”y*60ù…‹œQÕRÈM¡ÝRnÆ^ùÞ½|xñÅŽm§\uûæÍÃç÷sÚ¸qlxûm*M'„OÐ Vºyf_'‹4""(—ˆ¡´ ˆ† 4aø×˜‘¶RjI*2ãN$FŠIÆì|s[é2Çòë_3äï§êÈžkÙÒñY~»vô7€_ͱM›j. *àâx ·šŽŸÂN¸óÝw)j—ëÔ‘ʦ6|jÑÞZ]•E–£\áÿLáfÆ¥h'K¡ÔH ),)¹÷“˜ ŸpñLÊFº_ºž p¾ùf4Š|s‘X$æÉ”a ¦ˆž€PœÐ Ïcµ vÃNG…ÃÛ€4ÙÝÈ#T‚Ë,SÔúøÒðžUìÛçz º[$Ê 0yõ€Ju.éx¢Tï}¤W|xåJ>¹òÊ” ߺ¿—-Sîï¦SÝwQÌýã=çùòºF?É)>;>ÿœŸžö}ò›?ø€Í¦1£úžx½»uãä‘#‰”—Û@ªõ€´8í4:ÁÁ%KØ6}º ¤Ò-Øv3>äqÑK/QØÑ ðYðàƒ|ýÊ+õ‚ø?4š5kæt<`°A‰ó$FrÁ¸&)sÝEÞù]>…CÉè¤ãС\ô ®†Ù·÷ÜÃŽ3Çœ}ÇIzMŒ@Y }Ö+SLň Är¬•C,\[ˆn5ó,0gí!¹Áx‚dR!M!s:_|1CŸy†ïß{Ï ªkùÎ;´:ã Ƕœ&Mì¿cæÌá}á´xÕª´d ÀÈwߥ•é¥Þ^×^ ÀÆ÷Þcžôx\¹>u9%Ž9wÝEÀ¤ÿUU¥^úÌíwºÅ0³ñ¼8Ê÷íãíÛ¾ºé&üÁ ¿YµŠÜæÍÉiÚ” Ÿy†!û¥;wòî/~áyŽKœ•/¾ÈO>I«¯¦e¿~ܱ¿ýù¦)Søöž{\exºrߟ]}5].¹„K&O¶³ìû¯iŽßž~Ýuv ´?ß²îë׿=‰†BÊMÝCþ¦Û:CüüÜ?ÿ™wßmg \ñé§ìúúk>;Öñ33w;H¿¸áöÌ™ÃUŸn“äµnm÷ùªëhТ7š˜¯ZÅ´Ë.Kê9e™r©‹]z¢CndÕ˜5ý>ÈòA†ÏÙnǾŸ"] ˆn$O¹_wÊÑ“žAhyúé\ùÙgXº”Õ'&¿üÓ¸Èâtœ?EóÝz å2Æôçë¾úÊV<©¼ßº†ä¢?±HXf^FDÆ;Õ$óÞu ÍYg1ú«¯Ø1cŸk~ÿ{Vÿë_ÌÉl¥ñY ¶M€Ü†àkA-K_Ž9[­ªÀRà$NÀ‰¸¢š›-v@MšÜ–3C«REÓü¤Ç*çFWý«/¿´ Óõo¾i$à^Ô«§:0û®»˜{ï½D++•,uéxѼŒéQL“>wÓ”)Ì2çT™ÑGôÈœóÀô¹ñF^îÒÅqÏý Mõ,®ž=›V§ŸÎëýúQ±gORa¼|nÞŸ-Zð›7àvÅ >¸è"G¹›GÐçñ|4êNS륜E¦A¯çùáСĪ«]Ûí¼äôÛÌ4P{[~>NaÇŽ¯XA÷+¯dù¿þeÐsfÔ‹åÿÔ5j'NœàÎ;ï$üöÛ´£¶i$É6ƒ<™²½{ÙüñÇF`Ú4v ©:¹M›r³PÃØóÚki=`Ç·neû_ ÀgÓå[ãÓÑ£Ù={¶ÝdÜ-Ôêq%Öp²a‰¬±Vf‚å˜Î|qÐ+5MÕzm ·E‡,³ºéº˜ »úo×Rî[´ˆƒË—'ûøDM U8ƒ*ùµcútžmÜØðrG"ÄÌß^ΚT2»ëÈ‘41Û>¬›<™piiJgQ:%q4îÚ•S®º*éY[ GVß¾eO=Åù&ÁEVAY239ëž{Ø2me»w+/^SCß›n²AM 3ÓñÛí â,Hi‰„í@êã N2„½ phÅŠ¤ýz_{­í ôß=÷œ#:¯R?í°&dÀŸWúŠž·¸ ˜™F¬÷"…å©¿ù ;fÌp à¨:tˆUÏ?ω͛4‘¥+VØÞF»©"Fà)?²rÀ׈ښ(‹æÜb°0]‰TÅ!¤×]ÄÞW¿P|.ÞHFçSD"¼zÉÛ{]s Ízö$»Q#[9 úË_Ø·p!{çÍKÎét­÷ñª*‡W2>*0ÐîÜs9ÉL‘Š [Ym›>Ý®[:¶n]’qä•Ë-^ËÁ¥Km/lª&Š^có”)(*"R^î xô@×òä®xþy»G—ÈL•³îæ±Ríç¦|½œ!>À­¬ôË>¼S"u ÖHë~ˆãø–-T=Jåþýìš5‹Hi©q¬¦Mëñhø|>5jDVV–-‹ýóO7ÌVgœÁ)¿ú™ùùÌÿÓŸj•$B$±ç…²øá‡s$˜—GFv¶s®$=ü°cž–¬YC¢´Ô&okdö+‘5Ï2bTý ÅÏ,C¦ƒà("¨+úd)+;š@•¾×ï¶ÛøÅ#P²y3»¾ù0˜²Õ„WÔ ŒÔ¹¨rnû ›õìIw3-ê@Q‘Ã8è=v¬]S °ýË/l|ÔAŠ#§iSúßv›ý¾é)§Ø)b€CG4ë^Ucß‚ì™3‡Bd2·ysÎòIŽnܨRí¦Óðáœ#±è‰£õ™gÒúÌ3mÃ<˼Ý.¿œæ}úPºcÍzõ²¿³ôŸÿ$n²ð)õ`,ÆÊ^ A‹Ží† £PŸušY·¶gî\ªŽáÌ»î²Ïœ9(*r­3Nç¹Xÿøãí:±½óæñž™z˜Î³ôgdp†&:tˆµ¯½FÔŒš:@k8ÌŽ3›„‡–/G3÷he%—-c‘Ȭ‘UPÀ™wÞ™ݲ‘û‹Šìû­káÒReÖŠæb‡ˆÑ@\î­H‘dèµr$KJœd+¨u.AS†dYr&G3¯! ï¢n6` $˜—G 3S)'99óòh7hû- ÃùçÓnÐ [÷Ö©ŸpDÍ苨¨Ä!zÞ$7EŒ£Nÿ–ÄcˆÖÔ×4%µ«¸hªöícé_ÿŠŸÚÂÞp|Ñ";Ïj ÕØgPÚfg a)+©ÝQVc2H”BY5”êµ}> ï½Jj’BÍÈÊBDy®é¤è%';›X8¬ìtn#‰°êÅiÖ«½ÇŽ¥Uÿþ´êߟeO=Å‘5kÐuݼ"4é i€Œœ2Ì4-‘ ZY©\ÔñXÌöšŠÞÓï¾ë0üÓ!.P¾½óæÙʸ.ÀIÞ_¤÷§¸vU_%ëÜ£¡‹þúWW£yDŽT€Kº!u ©WmVªbêT5y>ŸìƒøZO$ˆÏ^v $"û~È£òàAÀ °ðóŸKE¨îÏVsqøh@va!ÝF"3/õo¾IèàA6¾ÿ~Òü²›ìVUQô׿º¦Kù µä¯M"¤ÈÄ™vc9ÏDcÈJ7Ï–@T¶Â;,6¶²$ÄæîVJ¤&SÒÅzXYG*û®ÕÔ°ô‘G8´r%{æÍs¥¹NUç’nŸ%Í HõêÅ s .}â‰$ µñw8´|y­çÿèQO@—Ñ `ÐqŒHE…Í ÌÍ¥°cGûw“ÀÑÂ…,øÓŸØoáØß“ŽˆF9ôÝwÌðAÚÏš•tœ[·ªui<î ¢¬q ¨ˆmÓ§;¶íš5ËRºtq\ÆwÞ!,€ÌXu5‰¨3Ž+·å°À`+Kš%ã55 ùÇ?ææ‡“"G©êPqÑËž|’3"¥k²ÛaÛÅbI霹͚q–P \Y\l×§©œ±»ç̱疬ŽmÜh§ˆ;€TÆ„²Áec!2ªÅãF–‚‡£At2j¨³MDB¿ÂyíV.;k²$ÇŒØ'5CÖ¾9Òq¬L¹¥ƒÜDÜ>§@€¬ü|"¡ÃY|pÉÛñ rÔ®5#mÎ:Ëf©Ôb1â¦ýeÕÏשŸhX”㪈”.©êîòZ ¯ºª§Å¦÷ßOšô*Ï£ØÀ,'}mP臆~£±b0#·¯Àü0Çü²ÅÎg6XÔËŒW¤ *ôZ…•®ÇOr! ØŸÇ‘þÌLz^=›^yÅ^x–²—YXD`)Ò©[AØÞ7ÝĪ ’ŒrQ´l:Õð_|1.¸€-[â8ëž{p÷Ý]·Ž×ûö­õVde‘kzýãÕÕD\R8²›4!#;›ê’»•ì5:Ýô6ß¼™÷/¼P©Ü-_îPÒ*ö®TQ]a¤¥[¬ëÅ<ÿtj‹äÿs[´ÀŸ‘A4"f‚U¯ÔB™*VNïAáUKråô<ÕüT)¤ײ¥1£QjŽsýͬF·~=G×­ã£_þÒõÞ¦r¤*ëÇL©€T ä&Óšs×]lùøcÛ8‘Ŧ“¦ì“æ¨\Š`=b“`9ê¶[À)èsÖñ¤‰¨iµºËŠ8Uš>5 @U Ñ'¹V쯥rl‰zkãäɵàÃ@yÉÁT Ê-Ht¦Äª«mƒ="ô³† $¼äÀeï¿OW©yùä~ý(ݵËvÚ |è!Îøío“mŒêjÂ¥¥ìùöÛ$•Ó¸1—}ø!…&¡›¦Laú5×$é‘Tãà²eö5{=sç²ìÉ'ÛuéBÏ1c’ö 6hÀ­ý:)lëÌ>ˆ^Cåðs€¯‰9ý¶ÛÈnÔÈÎðr,¥’©Ö÷Ö½þºc{f~>7mÜHv£Fssmg×÷ï¿ÏŒotì{ýòåŽ{(l/6ZHݤW7ç£uÿ[œvš]‹ÌÍåÄöí61…CÅÅŽlˆºôÛŠ£®Ôý~ò[µòtø„Š‹ k™¦Œ°HÙ¢8£ÝAn囟Ym­D2 ±´Å\­I¯^ŒþòK¦^~9‡W¬H«F[|ÅË–Ùß9°hÌèT3)í´HýÈ£ƒkA¦agž§˜ª—ÀÉܤ+Œ:H¦i€.Ǫ†¿Â{VYçó>ð7ÂRVˆÊŠ@Yt.¡Z•8 5Õ#_)p\P¢V*‡ØÇJ—<ŸAÉ#7=h_y…f$§“d(ö ¿W#üVø~ÂûôešŒh ƒÚvBÛ¶\;oy­[­ªbr¿~Žgܲo_.}ë-À`6²Rsä1â•Wèvż3x°Ç’Çsô"…1îtȪ‘PD|¼ ­Š&ƒ]KqŽpé›oRØ©ë&OféO$—t¢+©~C.V>øªê:eÊZ‘D §qc~mö 9¼f Ÿ]}µ+À Ÿ8Á!ßߟ@j)€\ª¾[õã§"Ø–eµ#¥ìŶmíç”@C@†Të]å’û©È5NAAˆzAW¾€äv6'›ž-f4Ó ¨P­? X‰µ»~…¾òªit«9Ñq¯S­kª¯,5ÉÉ$;Wv~ñ/|ñ…’]¶® òÐ!bÕÕ¶!pãêÕ̽÷^–™µLóï¿¿ßÏÉ—]–ÚTŒ§|‚“N²]¾g-ûö%§qcªMÇNºJº¦9dT]FéŽÊïö¸újG½`Ç×A¤¯öî­t¬¹9¤´kYåÌŠVV2¡m[~ñè£v:ç%K’@À c¢Ûõ¤zþ4õ«†QKeÞcÇré[oÑ[ µó¼iÛhu´7dT¼'YùùÜbÖ'ºçZ´ êèÑ$[-[xå rÊ’‹Y8CcÂ+"9ÐÃR`¢bÝ:&™ó0Óã>â²îqqÔ~dÝQ@û] IDAT¤¤1=s¢B“óP5¨Ò€Óo¿‚“NâÛ?üAémH6 ð˜ûpFžr•-§\ ;¹FcÝŒlðec0Lä _´2bÔ6Ù-3S¼ŠõZV¾ ó¯ÎÇBÞÏjƒ\rÈØOrNm&N–ÃNÃJ ÄÉ=ªä—d6( x÷¼óRzê& ½5ÒIPí›nž¼ÏcA»yÙtRS)ûðîÉd£ý!œqûílûâ 6¼ý¶-lT íäÌ;ïdÇ×_³Þô2ªŒ&ë$ô¯ñª}H‡²É™ jt(§+ø$¯™ Hé/1B\}ì˜c^¤ctûÒBò³izê© zè!ö/^ÌŠçž«Qÿ%@Êš8G‰—T†b»œÚìvQ߈éz’> Ÿ‰½ ý>ã¯ý#B¡nBw6õ€T¹¹­šÚš¨¨dØÈÙ^† Šuç–:¤JÉò’g²g=¨‘|Œt„§+ÛgÞr »vµÉ‚¬±fâDÇû¹÷ÞËÜ{ïM{Îùýï™óûß3fÎ:\pÉÑ Ò6Úù‰åȦ?dÓ‡Öù{Z€*U{ 7uùGáó{­œ0} º‰cþ0ÿþí{÷CfÓIÛ—Gv£FŒ2‰m–<þ8‡W­J™ób*ì:r$½¯»¿”¦ª¿|ýu>¹ê*âá°CËÙYÙ’“G&¯@!‚¼‰K`JÕîG¶TúGÖùQ¤\ Y‘²U,âK¸¸~àÐÂ…ÏÏ·{œÉ)²²´¤¸]œ€ÙyVÃÄÌ œYÆËoåóåˆ%[@+R±ª‡Ëc¨€Ê”ëFcE«?T•題ÝFfÇ”)ŽÃbÓa«W[!íƒ@üæ9ø‚àË&ø3À¿|>ƒáÅ çiÐjÌWØèy`)K¹‹ ±1±Ø?A¬Î?Ÿø[?ù„ufžlºi6²°YúÈ#¬{í5ŽoÜèÙW   C†›yás[¶(‹7})Š,(òZµâ܇bæ­·&.x¢ )ݱƒµ¯¿NÙž=žÊ*”íÚź×_§bïÞ$`ìæÒS(y9’–êúSžSFfó”)®)°*¯¸æruR§=¦£ ý.ÏÙÍSVuð k_ªââ´ ïëÇO?,y,>û<€“ø†ä|“LP§mzB|/þ¦œ%—&³ž0š¿kº}Jèµÿœ5QUÂûo=`€£¦jÚ¨Qµd ¿å«ÃýǺɓíï–îØáy¬Ÿ „ê?‚ü‘Õžo¿eÕ‹/Úå`ÔŒ[¤)…;Rå’~žˆD˜jFBÝî]—_þ’óŸx‚&Ý»§u~].¹ `g_É6˜]lnÏœç~Åõù%`eÉ71Õ/îâD·~_å\ñè~ÜAëÔ암í> H%pÜZû—®_o÷rò»€¥LIéfIF+òôA¦rå7^«1TÉ!!KëUáluª}Ū¡" U <•¸Ê/aaÑ/Yb{Ä4Â|óÿœ È B^dÁ—# >™2* hH! A ¢øù5ð'œý¹DB¥,5É3Q²q#Ë}”Šƒ]sðI#b ÇÖ¬q­E’ÛZôéCçáãpÙb…qcÔÓˆ\ø€Hi)ë_{MÙÝ;]¥:x™çí³þ¯).fOq±2Êã“€îâ€PE†tÉÐJ•Û.mâ1‹—,IòhÉ©T~…åÎ ;w¦Q×®$Âaöš}MRE ­}4… jV@ñxáãÇÙ5sf=pú/–b×ΈtTÀH¥š³"`ðIFŠ5C¤fž¨ŽžÄþƒbm“i²2ÄfðQÉ앾'¦Wû‚Aò[¶$d2tªH^äm»¾úŠf}4hÖŒüÖ­möÒ@ '‹ $¹±-æ4kF‹ÓOŒ:„I‚”®!,þf07—v&žX»bŽ^Hèðaã_£.]lÝ`SÓ8±};e;wrbûö¤ãúî»:¨të0Uó^å€K'².ß»œ&Mè<|¸ãz;N4b÷ìÙiµ Q¥£y]×®™3•÷"'˜žâzüiÞïÂhÚ½;Ç·n¥Ô…Š>x+¤è‘Gè=v,™ùùIû¶4ç´ê$Í9yt>…®õ¥°wêÔO4,àà¶Ðeï\ê” ±8ØzY´â¶l4eøW¦ßxȔ4´ª±fe¤v›x $¨š˜ž,lU%)O ¸d¾ýûiFm¹U!Ð8 ³!7 ü…,€-„RKã””ÕäÀr…VbeeÕ®º,s±™›æbüÊÏÄ GåYšwªY:!¯´qQvêd÷Ú(òª½h×ݼr~AHhá0GV¯v£ÃСdP¶cGLÃ#UÊ¡›`IU¯å÷¤I÷Ëç£Û¨Q]»–2³ Ù4î? O@Íþýd‘ªWm·ç)>»–ýúÑcôhÂ¥¥vƒHÏf @·Ë.#V]Í.³g›§Õk¾~BÁ^?ÒÓÌ5»{÷nN¢6ZUs§JÇS¥ú9@Ž [Ué§òÿnë@w1*5£DN‘›äÊ…ÝÉi4^NÑy‘•E³=¨6”Oáü àL‡¯Ü¾M®Ú·§ý!_·Îqo¼Ü>ÔMéÝd†-о=}MªíâåË ÄAuekmÿ‹_0úË/=÷ï}Ýuô¾î:oïþˆt1‚Í̧¿úUJ½îyv6Œ,…Ñí6vΜI\bª« “­<ò[·¦YïÞDÊËÉ2™ñ®øäÑ(Óäâ(ݵ‹#kÖ(õEÛsÎ!¯U+Çy§j˜\×g{ÒyçÙì~¥¦nu“ëâé—ë–¨³RtܳJü ç«/x®R?ò½ƒº‹2Eò:ÊQ¥ œLJV€&gíP6FÚ› ”²®L¢yRšfx šù´„щ^ï#zm¤©FÀ1@Åqö°ê¡r1ÈþcP©7ÁQ¾æ›f@SHY¬€ … ´r™, W-¸XcÔRE™,ñ*ˆDkS «M°W#ySc8Cºn…ý* n}‹×碰¿{æ»?”— ×%@îEyîwT'wùmÛ²{öl ý§R)_þ÷®×åóqòÈ‘DÊË)5”¦ðHk^G¯FÍ~’#Œ*ᬊjÔ:ÿÄÞUuª1ì¹çêex¹sgJwíúÑ®çè† |rå•Ü´~=Íz÷®+™™Œš:Õó»«'Ndæ-·(¯ýìûï§ë%—Øï_êÜ™²ç]×{xÞcÑzÀV<ÿ<³÷;%’ç͈W^± ÷ºöZz]{­çïXÇþÙ‰&;pü8›òªÒ“U,ØnD4Z2#á!»ê⨭R?1Ò#5bÿ‘­)SQh’)iEÖ= 3F=QRr½ÜhJÃA¨Ç eå·GHN׈á$r°J¥Â#j ©%·°êŸc°§gå‚¿ øZšÀ©1FˆÊjðk¥Z.F¡Ä„ü2 f ‹ð(Pll$jI/,ðW-]O*vÄ —Eé÷̲pûbùRxˆÓõzݶg¾@€y÷ßo÷ò§éñ•©ÀU,ƒòyŒ|çÚÿâl69fƒ?94®ºFU¶(sxœ5ÿû¿®^M¯g¢"Øð+ŒÏT¬€‰:âtÀ<ü€Ú×)w…' €nG§aÃ(ß»—[·ÖG¤~¦ÑÍ$),,´å‹œ4iúoм¹ýŸo¤Û¨Q,òI»™º[ÎgžÉé·ÞÊÀLë<¬c¿Ø¾=º®»ÖùYcå„ Ž9øsŽÿÛº•¥O<ÁÊ ’Ö*T@á€r“^2 ¹hýߤG~ýÍ7|té¥]»Ö‘æïæ°ªR?Á©UMÉÄÞb7ù œ9¡A’Yÿ¬Ò%›º;f:žM‘îs¦fDu'+JD¯ýßGqÔL'2« ¶,`’Qó”iâ †A¦BóÕ ø›Q–jŠ}²j´&8*WÌv«Ê ……0 ²Ž›`ê„Âp\ƒJÝø¸’Ú‚h‘\BÕŸË_ £¥0Œqñ«®¸-3/V®ä`ßñã9ïñÇÉ6ð¹=ÄÆwßuÇEOöÆBj¶ë¸3o¹Åfâ›%º¥ÄøR2¿‡"•kŸtÅý×]î»ß㙸5)V±i.`Ì‹¼â¦yçÜs —•ý ¿ ¨ÄÃ8ÇÞyóÐ4-ézê#R?ϰÊJUó΋QË­ÎÂ-­Ôç1¯õß•=¯^é2ýo¾™£›6±gáB'x9’FBÓÏuo¼AÍñã®Îð®ëT­IM2¦.^iHÍÒ–t›u «'NB¡»ýŠ5åæ_øàƒýíoI)T}ǧË%—ÐðRˆ§gpøpÏ=uúJ07÷G;'xu¹ôRðùX3iÒ¿epV9P§èXf^™yyé·æ—îèÿÛß3²fåç{ÞCë\:_|1ŠŠ(@—¼fCÅÅ=òËÿõ/Îâ N»é¦”Çn}ÖY\ºÔSƒÑf%™ÉÙ÷Ý÷³ËÈü6mè2b¬,åš=±mÛ>ÿ\©¿}’M¡ª«–£Ðº‡ÓZþìÄÖ­¼zê©v2Hn`ÙÂõ@ê'R ¤Š™IIš’¢ DpS(ºÔ0Mw*(Y¦„ÊDfÝÁ£ðd À/SSù@Cdg¿¡ œ,Îõµmï-ª§ ýèr´Nº bUP©™=Kt#0%6´"kªô¹¤ŸÞÄËû‰Â‹«2f|>çÜ?ùmÚ0è/aË´iŽ®åÍzõ¢ûWÐzÀ²5bÑóäÑGí.årÁ¤[ÿí^W,r­•ò2Öe¦2·†½šË_7òI·nô¸újÀhP¼sæÌ$©¤ª@èuR^ט]P`PIº(2k¿ææ³(zì1Ñh½³üŽòqÔ ÷‡ŒÒ;ØøÞ{öû³ÿøG2rrê|œ®—^JûÁƒm ²ñ½÷l&¼Óo»-)2”òxRÓâk¬xþyÂ¥¥ÎߺäO¹ÿU:£ÃС,"jn6C"&kæ³Ïˆ‡Ãô¿ãÏc23]õ·¸Öâá0»fÍú¯R`T¸Y”lÚD‹¾}íëXü ›‘C¿BŽõ½årÍHàE‹Øköq”——ãØ^ç‰DÒœð"Ë©R?ò˜4i%%%Ùéz²P–s¿ÅìµN¯¼¼èü¨ÓT &q¤ˆ”ð"=­¸oÐ|>Îâ "¡‹……ß禛Ðâq6¼ñ†Ã;h•cå™/«ª™rrÀoE ›+ƒÚ:'³›£V¡j¨‰©yh¡C†Ï¼OèšQ»AXƒ*½–ìBliEØÜB¹²çS#½¾ n‹ÎË+ Þ©{ÖwÂeeö½½™ýo¿ŽÃ†ÑõÒKímí‡ a‘@ «òä¦ãéNDááÁñM{ô ÷õ×B­¨ˆÓ§»*y‡¡Cé4l‘ÊJÿýïNÃ(‘°½‰XÌ“üB•6äe°ª¢…/ºˆ\@¸´”%=¦ô€/yä55)™óšõî͹æ³+^³†í¦Ç-ÕóSEÜ”¥}Ï?Ÿeë×× åŸaXòÖK.h€Ïï';/šŠ Ç3ÍÈÌ$˜›kË«HY™ãó˜¦QS]MLÓˆ©~Ãç#» ÀÕ9©¨°‘ך¶æÒÒǧÃСŽÏº]v™ ¢VOœÈ®o¾±½Ö@·×ª–H$ÕJù\Öž†AÏ ‡mÒ1J$ê™3)É0Å™Qa'†³U–\¦~’‘tˆFróïïžy†‹±gΜ¤c6lßžþ·ßþ£Ì»D$‚‡rlë;~<ºt`éO(#†â(Û½›-B RÍñãddg™ŸÏ¹Òñ½FVAM_~díZJwìÀ rÆï~Gã®]öuúÝ¿þÅ¢¿ÿˆ™¦gK–ТOǶæ½{Ó+ñ‡ÛXðÐCĪªì¨Q:  jûƒK–P±?'ä /Xü·¿ …Ø'EнtÈþE‹þŸ¡M{ôpP߯|ùe¢ååÄ#¥îîwÛmĪªØ2u*ñXÌáȵB«$hÊL‡­ …~ÀT¤<ÆøñãxöÙg™ûÕWÊÚ ñ%¦¨¸ìu£Ýͧ ÀLIQ’SôTEô'CuI óMã>§IzŒK"fǬY$ª«‰—–:ê:¬Ú-‹M=Ûoöƒ²Š»ü‰˜‘%JA+…h)”FL½yN9ÂW8S ­ÈS îän´»º‡WÖžÌ996ëN¨¸Ø±àüä¶haÜ·H„š’¥ñ®¥Ä|¦±±ÌÅ“ØqØ0Zöë‡ãÏÈ ZYé`òKWxŠ×šÓ¤ ÙÙÆ©©!,ÐëzW¼'ögšFȤ8G^›6ô4™•âá0Û% ¥áž.ÌË£ÓE1àž{¨:z”uf3ßšãlj‡Ã”îØá¸_?¤1£î±Æäš¨f§žJ1c Y e5ÏLŠÕÔPiÒÇ7íуíŸîÊ–ê9ê.`0¯U+|~?† #óG,þ®é¬Fh›KMI ‰HDY­MN>™Ñ_~ɤ^½H˜ýqº^uÿcÖ?¢ë<êwÎòPq±c Ès!«aCn?p€`ƒÊó{±CÊ÷îõôŒ‹óùðš56YÐ|~?y­ZÌ͵÷Û3gÅ+VàÏÈp8‚±XÒZuÓYò½é}ÓM¬œ0 ’S¢‘’’Ó~Të%€{QyBØÇ­5„õ—©“eãMÔ‡W®äÐÊ•I÷¸eß¾t»üò¤í™ùùd5lè-Oª«žóX(”¤KZ~ºQZýòËösOwˆ=ªr›5£Ï7ºî›™—g3ì艡Çè=v,Û¦O§ã…ÌÍ%\VFvaaÝ—®:|ø¥ä9œá0k^}5 Dìž5‹Ý³f9¶u1‚“Î?ÿ‡¶gžq0¦ÒY✠—•±îõ×i{î¹ Uuä+'L º¤ÄÕ©êf„Š‹ÿíû÷Ÿw9ÂÜ{ïeÙ?ÿi‚AG-Z #ƒ£;v°fÒ$"ååI²eØsÏ9¢_ï \K2âóÑ´{wÆoÚ”:?ûõ¯í÷ÑPˆhy¹«Ã¹HýÃ-~á¯îâ™LÅ$’*âW[²òIHŠHóT¤œß!ÿ»=i¯™;—­Ó¦±ðìÔE‹aÝ"—ÈCF†ùãUÔr‘W‚^‰2¨ˆÍ|÷G0JŸ2©åžÈÀÉ›!F×Äžq ŒºQ?ê•À\|1W˜tÆÏ4mêðâåµjÅÓ³xpÙ2¾øßÿUö3r‹ùÓØf}÷c3aÌœ94l׎5“&±üé§•ŠÝë7Åí#ÞxÃŽpmúðC‡ ðží â’·ÞräÂG**xZòâìž=ÛžC²é–Æc7ÉýÕ¯è:r$'¶m#·ysî8p0Š>w̘áª4TioªTÇTøò1¾{òI–=ù¤kú§ßcýËÊqÛgŸ%QÚŠýÅ4n¤ñ7k×Úku^‹¨ëÇ3.záÆŒÃƱ{öì¤u`=ç£G£Åã´2ÄÑÃ&ZQÁ‰mÛ~ðïGÊËYöä“¶3#in © *Ò -E”ÁZ“Ö°XÔ&õèAÉæÍÊc{5ÒÖkaÝ„ vúž_¡WEfÄ@ÉÍ6å?sÉ‘ÚÇíSÅæ—œC²¬óK×%ÃkÖ$é[0È)κç|:w¶·W5Ó ©ƒìrácÇx¡m[W™Ùëºë8W Jó®ITd_}Å„¶méwóÍvãùtæ³U+Dxwð`®_¾Ü±OÃvíꔂ¸éÃín÷D\;ÌóþwF:½þTkoøK/qÊèÑŽmo}¶D¥r¬jñ8O>™ÍZ­¼V­”½¥ê:Jwî¬M½ËÈ °S§´¾WsâZ,æ?®óOì©Ö¹3¿ž5‹†íÚÙÛ´lIÿÛo§è‘G’¾û¥Ù¶@¹®üì3Êvírœw»Aƒ²nÅsÏ1Û$ÛòýÀ5T¤~kœTq·Fb^Åܽ_áQW-м֭öÜs®ç½eÚ46}ø¡ãœgÝzkÒïŠì‚VÊbêËò 3"f‚¨µUØMyÇDéÌ•„@,å(›¦¸—¶`mßž¡O?ͱYdæ4« ÏÓnº‰NÆ9¶å·icÿÉäÉ|rÕU6ÑBÅþýL4ºR ¾7ÝDGóØ%›7³ðÏNª_Q¥ýÈóå})­&á«gÞy'­ú÷·ß·8~·ÜÂjS¡y¥îš5‹yü#—¾ýv•G:çju“'ÛQ¨a&Øi/çÜw§š w¢pŒ”—;Œ‘¬Â­ÎH|õ¿ë.ÚžsÇ6l`Ñßþ–63£ÊûçæY”^ç#èsà ¬ë-v̘ñƒ‹±ýõ¯4ëÙÓ~Ÿ­¶õãçç>ô­ú÷gÉc9Œik¾,~øa[6‰cû_°ý‹/\Û¨KÎ{ì1<ø Ç·nUî³ÈåØª9N‹‚“ÿçèuíµø]ê1ºEÉ#()ÙÝ MáØ²Öm@±n-=`}7&ì—^nizbÖ†Lœž“ÌèU«J N'¥Ú힯}õUÖ¾ú*9s—àÈûjÜ8v  ;]¸žâw Ïú÷ï¼ÃÆwÞùÑ×Ñ–©S“ aY_·p!í Jû˜«Í,¯ëÿ!=¸ÒYoéÌ‹`n.—š5‡­Ï:+ÙYóâ‹®ý¯–=ù$‡¾ûÎõØÑPȾ—O™Â)Šþcuoœq†ÍkÝšßš™©Æš‰)ß»×&%Iwß²…Ï®¾š±EEö¶ÍìQ¾4ׄ3±[7ò[·æóîH שaXµH> ¥êí!~Þ´GÎê)׉±æ•WØf¦MÉu#^{üÖ­“&Íê‰mCÕͳ ’[ˆd ¢r±(Ø`pHXMw , µ¡#“9CA4Õq[Y¯jó~e ØK¬ÛŠ)¤î<¬máÒRÖMžlG“ÜÖ‰íÛa.âcßÏÜ?üAéÅñ:†›P<°d ¦GÃ-…ÎMX§Ûw©Q—. 3iUå1õ²ËL{{çÏçøÖ­üâ±Çhѧ ÛµcàØª.¹$©vB{æÎeʈt5ŠÓÆ#˜›Ë课r·9¿ÿ}ZÊ'!´úå—9²f ¿|ýuÚ˜ôyvãÆ$̦˜k_}•mŸ~êð»¥wŠàfß¼yœØ²…šãÇS6Yv;F]<‚.ºˆ žzЦ§œ@³ž=9åÊ+ù¬)³½açžË9<àØ¶nòd¶LÊ™wÝEÇ /4”ì€I)—õã¿c´4ˆ&Ý»³iÊG¯_ ^kdrÙûïÿÐöœsÈoÛ–pi)_ŽGèСdÔùpo™`‘ï¾K«þýiâá@šý»ß±wÁ‚$`æ'usK†fäå1ü¥—øbìXe ž&¨¸ä@ÔPG—äc™PÎd¯_ÔÏ^07ºù‹_y…†íÚñéÕW­¨ð¯ªg©¬dʈöûëVyRß»Í'«Éî™wÞÉæ?fÃo¸:hSͽŽN=qÿ¶2ðO¢¡”¢.-eú5×(:p eãûMS¦¤ ¤æÝ?'„/Jøœ}ß}´<˜y÷ßo7Éõz»våÂçžcîþÀ±ï¿OÚן‘Aw¡gY’QñÅ®ŸvêDÕ‘#¯\ÉÂtç›~ ’mäáY IDATÕ„çËqãøåk¯¹~ó”)¬ë-Jwî$.¤5×e”lÞìXû÷»®­tÒækŽwÏË>öÁO¦ê”B Dqï "ó×7éÒ…‚ÎI„Ãì1RÅ,}üqÇw¯úüs;¹lï^bá0ÑPˆ2ƒ”À*2XõÒKlž2…ã[·Rm†ÉݼRAœì€bºØ ØŠBåc¤óÙ=tu%j ÅÑ¡Fƒ°^Û?×êñ$¦Vˆý=Ä—¬Z~:9M›t¡‡qdÃeúE¬²’]fGn¯¢ïCK—òÞ!†Ò*/爋ôò(é pc¥cèšÆ‘µkíÔ„tOºV°A: ®ª›§LI¢á=²v-GÖ®¥A‹\b*Òü¶mí&€.ºˆ’Í›)ß³Gy•sÊd ôgd8~»°Cv™ýö/\H¬¦†ÂNìââx8̾ Òòî•lÚDÙîÝôºæe~za[ÅþýĪ«9ºaƒÃ¨tK1²>;¶v-ÇÖ®u|¦b÷³žy˾}mv ê#G8l~×M!ËÏ÷èºuŽôȼ֭YõÒKJÛ‘µkmÖ³õo¾É!3eÇ—_)+ã—‘úñß1r›5#ËLqSð(äIûÁƒ©JÙ……Ië¼ÍYgñåo~c{‚ëÒôÚ+Š*ŸÓª^pe³ ü5klª`¯ã{95á0k^|1é\’ƒ1Nr?)MÒ֫˰sî\ºîˆ0Éiw²|Ї¨ª½ƒ_±¿Š fí«¯’‘›ë0})ž•ãÅb¶S}×—Æñ¬ó>¶~=KÜ68ÝyªëM†½ž»x?NlÝJ³ž=@*V]Í”#8¸l™Ò&qK«fßð9§×kJ×ÑõÔH~–íÎ=×µî°óðá´2„}óç“ײ%ŠŠàB—õöEÑùâ‹Ù3gû÷©¨p/VUÅ»¦]дgO†+ô„j´ì×/¥óÒ:Ÿ]ß|ÃÁ¥KisöÙINX™¹Nïvùå6Õv~›6ŽhTåÁƒ¶±½óë¯]£K‡W­R ÏÑ_}Åœ»ïæ;³…8òÛ´¡õ€Œ˜4‰œ&M”ÇmrÊ)\-¤Ì¼õVªŽ¡Û¨Qô2½Õ%%|ýÿgï³oÁO&©xM ;¾üÒn€h‚ £ïøñô?žÏ¯»Žï¾KÛiТ>Sh¯\™d(úêpß­1ð¡‡ìâðƒK—òÁ°auböi~ÚiøLò=‘`ë§Ÿ*Ó0ªKJØ=k–Ø5s¦mضD4ÊÖO>QþFב#ñgÔ‹äŸk¯XÁV“éÌrÐø<ŒBÙpÕžcÆÐæì³i~ê©ûþ{Nlݪ|Þ{çÎu0Fªšbk@ƒ-ì¨î®™3I˜lzªè”ÜNáвežë¢A‹v„`çŒhB$ÜËø‰S¼|¹ªç ’ëÄú'¹_`·ë¯gûüù艄ƒõϯ8™ùDggN³f´4ˆ½ß~ëZÏ!gIø1H&ÄTA/]DšÛ½À¹RÍáÃ8|Ø•¬JÜ¿aûö´èߟ²íÛm›Ž‡ß—ÂÉX]R¶éÓé󱚙 *U´ÔížDNœ`÷ìÙ´8í´Z}Ô½»Í,)ŽóœÐáÃlèúÝžµv†M˜àÈòQwßÍþÅ‹)Ù¼™h(¤<ÿœF8é¼óØúÉ'´8mŸ}FTRz"aÛ~::rÄ^ÿùmÛÒúÌ3=Ïã@Q‘í\÷Òwñª*v̘‘Dµoþ|å<÷JÓG¢¦&Év•çB·Q£ÈjØóÿùOvÏžÍÓFª:|˜K–ÔYî¦JÏT1Ü‚A sòe—Ùûúî;*¥:P¿X«R?1rc·w>œ~·ÜÂáÕ«Yÿúë|}Ë-Ê kíÿå 7(CͲ`œsûíIBÉ"Ï (^AjÓö2¨eÌÙø²¤÷b³`‹G"¦N"«žÕ6ÊbØÓHî\íS€+h}æ™”lÜȦ>`©IŠ|Cµ´ž'Õ~â³kxÒI6Åö/¾°I!¬qdíZ6¹âS’Ez:cÔÇã ’¶W:dw O5ŽnØÀÌÛnãÌ»îJŽ„HÌ5bää’7ÞHÉ$:|Ø.°·€š®iFËç#·iSûÞ¼3hû/ö<æòýËnRhöC†Ðç7¿IÚ×òjµ=çÜs š7gÃÛoó…T_•Ž÷^õ\öÍŸïð4fæå¹zUcøK/Ùåx4Ê ³VJeŒì?Ÿ½óç'¹å{ö0ÍìI%“&Èζ ÿëÇv|÷ì³Dž}6)bàOÀ[Ï÷ë›o¦ÓEÑëškØüñÇI5SnF´n³ft3…ý ¯®NÜàÝ÷Ê:öÿÇÞy‡GUåÿÿ5%=™„$¤$ôÞ«TéH±ʪ+ ‹.º®ë6]ݬߟ®®uÝEDEADš4é-ô’BHŸ”IŸöû#3Ù;“ 5ózžy’¹sï¹çžÛÎûœOé0m¦L¡² €‹›6Ù™»ëø44ƒk:£dpRj¢'5“wôŸ]7{¶Ó,›TØÈY38¦Ä0¾áá´Ÿ6œ¨)+s鋌‡B ¡ Ož¼Ìí ¤aóCO„ƒlÝš¤iÓHÛ°üãÇ]ÎV6t,rûüiÑ"—ïgOÞçÒs(ý—÷îµ{&v˜6á/¿Lx—.NûKž>Ý&¤Ì Ü—‘‘ô]´ÈÞUÂlæ„5²¦„¢“'Ùóÿçö=SqéßΘá”ûÐÝyÑž=k;¶˜èåà·îÈÞ×^£PFËÕkOJŠS £Æô§äúM 7}(+3V­² w~ðA[pœ´õëY9qâUõ¹]‰&¹kÜ6x®RÙõI¾½÷^NýµË²Í.BHÝ$Aåªã<{Ç»táèÿËÖ?üÁ&r\E r‡\‚Y¹¼Uj‰p’~|¸2ûäå ¤¤øÔ€BYý+,W’Ñ"ޤ³O¥BJšX/ù8FSâì¨o­÷‘wÞáˆÌ§t3’åî! ÷r1¹y0xšèôì7ß8» û;ðùçéíð`\óÀvæšÝ}”a/½$+¢ ÞlCND zþy»‡nÞ‘#¬š:•ü#GX7gN£FÙ+rsRE'OÊ–Û塇P(œ[oÆêÕ,~NG>üݯ¼Ò`}²¶o'Ë2sëêEÒ~Ê»©f7ç±¡Ž†uý2þhìßog®g:ˇ ³[öà¦MvQ†Ü½œ\™'4Vß ¬·¤aHodÒË;•¬¬,¾øâ Ôj5O>ù$2æ;6làÈ‘#têÔ‰i’ÑKWçQíæÜ*]<_g_26n$Ãb*ÛØÎŒã3µøÄ ¾—Ü—*‡õŠ>éiSêgTxâëæÌá‰S§ÈÞ¹“:N68ƒ¢ëV:øÞ¥ ÷¯_Ï7³f‘»oŸl(sigÍ1ñºµÞ½.äà»ïÊv²äžrÉU@é©SvíçɳÂqÄÜÈA4•óeÌ£¾™5ËfyÐPdXeû39\'¶QùÝ»¹lyÿ(qo©aöàùݯŸ-ºãŠ»î¢$-Mö]­pñ‘».Í8G=•¶õ¹5kˆ0@VH5†Ë»5Nbjg6™\¾?åêÜØû×Q0J¿çìÝKŽÃ,±'ï…‡ëºÚÆÕ:fˤuwÌ­æŽø‘# ïÜÙÉwÌ[£á sBG>êÙÓÎ/Þ•?³-‘ï¯miàî÷ß§º¸˜ KR_¹ûÆxƒàBH]ŽPiÞ ëgÕäɨT* 55¶Ù"©ðQálzç*ñ¨Ü¶Ž3NV!ä%LÖÿ}¾{[“$l‘BzéÁdº2ÃTΓ½r L"¤j$#… Ò…øttv—GGqçHnfÏä0"«tèìhOâßaaõ/캺« )ݯop°Sûþ 8ÿý÷|g¥9õÅ´HH`ˆƒóhþ±c¬9ÒÒXÊ€gŸeÈßþfK¨õáN[f›v÷D¨[Ûú“þý] 9Û N¦o†‡;-‹8{Bš{’[Déaû®œ8•Z©¶ÖeGÖ䘒{©K×ýrìXúüö·6ûüʼ<¾’$Q¶²zæLûö³Øé{òÂjè7žç1ØóÅ_ðì³Ïb0xçwxöÙgí~OKK£¼¼œ^xÁ&¨zöìéö5¦ã¤tèh¸èqu¿*]\Çîîo¥ov¨›Â¡Ãm’YwÙÀõ9ï®òyh¢£yüøqj5> lÚÄòaÃl~Œr &œƒRÌ;xmÚ öócØK/QSZÊ{‰‰ :;Š+¥‹w­}}|xÊâ“©½peýûËšË%7SW¬ Q’߯¾2 |CBœ?¸i&½žS_}Åó绌(¨t!‘Orïl×Ò‡4¹øÞжWSOž[J7û2¹¤”»ïö½ñý%×€­_èëëtÀsÏ1èùçeï)ó/\à˜ô’ww‚çø²eŒu€ö sJðŸþDKP­.} !u…n^†‹‰€£ß’ÕOIé°Ìq¦JÙ€ˆRË)•ƒ’ +5 RX>޹/^“¹Þ$Ï*¬³PVádýTpÅ|Ï:ûäXW…‹ÑÝˆŠ«œ@ÈþÑwi÷n2¶l‘éÒïµ¥¥ìNIaÏÿû¶—¬Ô´É]û)ܼxû¼†ÍTÎFT**•Š:“4“É„ÒâצV«1H‚¸üûßÿ¦ÊâopôèQRÕj¾¹õ’î·I•e6£”™]Æ޹þyNõ*,äÝLz=fÊ”–•2l˜ÍlÈvžS/WÇè¼S^¶Ö×l–݇»¶ÿÇcÙ|&-ÖK½Ì&¦kð…¼^ׄÉlF¡PÒ»·S›»<£Q¶îfK;*×ç f*.æOÎûidÛ™ŒF’¨‹½Îoè1^§óh¶˜ß_ZyrŒÿøóŸQüíoòÏd½ÞÖ¾&“ ÕÛo£tDãòy.Ù¶Ác4ø»Œ8s÷ÌQþë_(þýoâââØèF_©ëŒ5×’chs…Œ@R:ˆµä#ýÝÑLO B…s¶w¥C™Òß½dö/Mph0[n‹x2šíâZ…”uFªB"¬j¸âô+íô*Ütå’çÊu4GÍ@ÌС´›8‘mÏ?/+bJXìjÄÎQÉ™G\‡N›1cˆ‘ÉÑëÉ' Žç¤%ì±ÙhĬP0Â!á\éÅ‹Ny1¬ŒFÎ~ó e™™ä<ˆ±¶öªBw^˨šËö4™0IÌúäð c $éäÁ%K(ÏÊjð<4dsîJÜkj0ÔÔØ¦îÊR8v $"Pq mw=Ìn¤Cìí†J¥Âh4b4ñ–Œ„–——£ÑhP*•˜,[¬¢ËÊÓ–vnr¸4†””^p«Ë*))áË/¿d¾Å—÷v<ÆŠŠ –.]Ê"_ž[Y¯Ã‡SPPÀÝ®f°AMM ï½÷‹ÒU\ _~ù%ýúõ£­‡IXÝqüøq222˜,3£5$¯¿þ:¸3R«W¯¦K—.$¹Ià)§OŸæÌ™3Üc ZÔT®¯µk×Ò¶m[º\£)$À… 8|ø0÷^‡U¯¿þ:‹-²{6_-ëׯ'::š’ $M !¤d:2j‘àè·$7{äJH9Š%ÇÇÔôAï djpŽd–ô2x¥þMu’õ»Uþ˜:ÎV{-ÑË>5Ê–ìXCUå.9úµl‰¯$‰­.'Çe–øÆˆ)éù ˆŒ´EçÓWUÙ©6$¦‚bbH?ž ÿý/g¿ýÖ6Ëêî8+Ü´ƒ aâããF­½¼¼8%‰`9aÂ&4¬ñzóÛßþ¶ÉµUpp0s¤æNo¯¦Z/~-ICÑTèØ±#-ÉÊ›7ûÞoî×WBB M®^#eòQ !ÕÄøðÃ)**b÷îÝNÈ]T=¹ VcÝV®C,ç@望*çkDÞ¬N.†U ™¶•ûnv(‰è‘:„:ÎþX fN~ð]ð GSFdê'ý®ÏÎfÝäÉø:loÅhYfr±=8ò° ×Êìl>”Lï»s oˆî>êVD5–¶cÇÒ¢m[ŠÏœqê _Í Ó¸wß%iút×ÿzòdÎÿ½GaH=¡ª°’’˜öå—tºï>»ß´Ì°¹"kÇ>>\öØûÿþ÷væ‚_MžÌ‡ r"§1Çp×?ÿI7KhóŒÍ›ù|Ìû«.ʸt)mÇŽês†%5`þqqóf¾°äðæ|·žHËlµ¨Wó­—R©$\&8έÆßßMQSo!!!×ÅìêN¹¾|}} ¶ ²5%4M“œEŠˆˆ¸nþdM!¤€',a‡ÿýïóÓúõe:âÒ¼r¡?Áµ¿Ž\Ð \ˆ,p)kv!@ËV6 TÌ2bÆÿ¡†L¯…¡ã côB³Ìq:î_)Ó¡—&ûµÎ¢}{ÇHmj‡N°\à 3ÐqÖ,º=ú(u:ß:tþ[õîÍð—_¶}oÑDFl¦®X! §•›Èdr yñE»Pëé7rà­·<ºÜ…Þóê«_¶ŒÈ=álÃá]ºpßúõ²¿…9عýÛßœÂÏ7Ä–ßÿž"IxÖ{V®´›½‹èÚõÊ˼Gî[¿ž¬Ÿ¶¤pu¼Ûÿüg.íÞͰ—^ò¨­,eÿ8>e.ò• n yyy\¸pAƒÙœ½åÛ,55ooo’““oi]%“s­)ÐëåïïÏ<Ðäêu«¯!WŒ7®IÖK¥RñÈ#4¹zµiÓ†6mÚ4¹z1¢IžÇ[=^XXHPPK“ÓŠŠ Ž=J·nÝ®y C)ŒÔû ¹J0ç‰ .:ëN™™qÜÐìBp8ÎN.ý‰Ì@tŸ>˜L&.>lW¿Ðvíh‘˜hûžô(ùù²bÉ,ó]áB8ʉ0«Rã:$µ«r¤âOj~¨tÑvÒEiðBÇhŽD.ïÝKU~>&Id/«ˆJ7ŽÄñãoèu×zð`‚ããµMâøñ †õ„¨Þ½íÛP©¤øÌ2¶l±µÇÕÌLå=JþÑ£ÅÆz¼_h¨ÇmÕ§O£ë”±y3I}'LÀ[&:Ô›&ŽÚÏ ?ü@áÉ“²×ª™ú|]¥iidYñv˜6M6q²cÙݺQ–™)¢öÝ$rssÙ²e qqq,_¾œ¹ Ÿ¶mÛFee%uuuTVVÒÛáþš2ééé×%€ÄÑ£G‰¥¥Èk'hfðÜsÏñâ‹/Êš*VTTðÍ7ßÀwß}Ç´iÓ®ÉgM)cp!r<ɺìj™-¡ZMû)SÈ;|˜òŒ §}¸š¥q7‹#|ÂúéøÈ#D÷ïÏç£GSk ãÚ¡Ã^~™Ž–È,u|1v¬“j{÷ÝxûûS|æ E§NÙü”nŽßÑJ*¤¤9±¤A:¤¦’ŽåJÍ­Á0¬³Qu8›.š]œ;¹>é6UÙÙTdg;çvãÇÓö:D[jˆ ÿûß5—¡¯®&}ÃÛ÷¸áÃñ“æÐð¶ãÆÑvÜ8¾{è! 55¤¦RráPŸ=P’)ÞúÞ [ðœ={¨È͵[Ò®ݺ¹ÜfÔ¿þÕèýÄAâøñv‰åOµVK–%Ï—ÚÏàøx:L›æ6LrdÏžœ·ø n<[·neÈ!$$$°k×.ÙuöìÙc‹¦•’’"„” Yñå—_ÊFƒ+(( ¬¬ŒöíÛ7<à”‘ÁÁƒÉÍÍeü D®7dèС.ÏÊÊB£Ñ0lØ0Ö¯_OZZÚ5EBÊéŒÈÏœHg‚Lțřd„ÔO[·™6²âb %BJº§ÉÛp#à¬ÿzï=|4|4›Jš6Í&¢.ïÛGÖŽäìÙ#Û¡ö ãÜwßQxꔓps œáØj, ‚¹23¤’,÷Æ>ª¡Ü̜ԜÏ*À¬"Jéð» ÷ÑÝä|Ù¤õ·“tk×+¯pníZ8$û„úd…î¿ÿº]{g¿ùÆ.xBTß¾„YÌB2·m³>pEuq1›$³ ƒÿügÂ:t°}ïxï½ò횺b›Ÿy†ýo¼À€ßÿ¾QþW7Šì;ùiÑ"ò- ?m×ìØ±tyøa»e>ÁÁ´Ÿ2åªö“¶aÕEE¤.[æRDÉ%L߸‘ô™´t)j'_±‹›6Q™—DZ¥K]ÞË@ÐXÎ;Ç«¯¾ÊÝwßMII û÷ïgÆŒìÚµ‹øøxŠ‹‹ùñÇiÑ¢!!!Lœ8‘o¿ý–Þ½{sòäI0™L?~œ &ð·¿ý   úöíKff&—.]büøñìÞ½›üü|zôèÁŒ3Dà š &LàsKú™›R2n£!%5©{âäIþ×½»9XxçÎÜ'™ø|Ô(´çÏÛ¾jkY+±•s†ôÀü]8[®›;—ÌmÛœê&‡(:uÊnޤ.[Æá÷ß—ým³¤S.^\³ß•èµp!ß}×&L¤y©¬‘¥QÕØûE¹  BÖ@˜zI½ 8gNwfJìhÈ«p„E©©²mèt]…Ô¦§Ÿ¦Ü2+0öí·mBjÿ›o6zæb÷+¯Ø}Oœ8¿«’ÑgáBö¿ñ!íÚÝpGGœ–,qQé?ýDúO?Ù-kÙ±ãU ©/¾ÈeI~!e÷›ãuûý¼yø; ©_þùOÛ},'ø7†öíÛsþüy'síÛ·Mûö퉌Œ$//ÊÊJ%æÏAs ::šçž{ŽþóŸøûûSVVÆŽ;èÛ·/˜Íf Ä!Cøì³Ï0 lÞ¼™™3gŽJ¥âÒ¥KtîÜ™ÐÐPÌf3‹-¢¦¦†wÞy‡^½z‘••Eee% ,`½ ŸV )a0X±bsçÎ%$$„KŠ’¢¢"º¹±bBê*è¿x1OÿéOüü ùÏœ:OÖwÇ#¬cGú-^Ì^‹#:€ÒÛMëÖW¾_EƒS+W2òµ×äO˜ÅqNÎìÐq&K®c÷Ä©Sv¾8£^{᯼Â÷²Í6ÉEì³Î YE5ü»\®(éÇêeý+Î]:»äèßæØéUJê¥pYŽæŠr躊 Þ”1k{÷ݶÙW;Æ ‡ž5¥¥vß·=ÿ<;_|±~_:ÝoW“ýƒví\f°o=l3¿ýÖnÙ»ññè+*곊SŸ@øØXb ²…3o,K{õâþñ¿†èZ¥/rΡ®®îS€âsçdÏ“'Ô–—{4h 4à¹çä }Íí¬Lpcéׯ{öì!%%…… ^¹ lÇsæÌaùòå0sæLÑh‚fE`` J¥³ÙLyy¹-õ¾}ûÈÈÈ`äÈ‘h4üýý™;w.ï¿ÿ>mÛ¶E£Ñbñ¹-//§eË–øúúâëë‹··7ÞÞÞ 4³ÙLHHÝË}´ IDATºuã­·ÞòÈTP ¸™|òÉ'dddžžNÿþý3f &“‰ôôt¢¢¢>|8)))Ìš5‹ØFøq !åIƒøùáJ‡©SQûøpàí·‚:¤~ü1Ç—/Ç,I. Ppô(ÿ'‰brÈ ¤òöfàóÏsaÝ:òŽ‘­Ã¾7ßäÀ;ïÈþfÒë–5Q-´}{:Y¢ibcñò÷·­ã€W@ £F9ÍxÈE#tQr3:uÕÕv(½¤£[Ç•ÐéŽf|rfz޹·¬&~V1U+BJ!çJx8ï;&W(ÌfjéšS_~əիX˜™I€evqëþp%žÙŒ±®Î­™˜¡ª CU•Û¨ày€‚Ú’—³Ö®µ»nŒµµöÇf4R­ÕRgžpyß>–~¥Ìº:Þ‰µtãÞ}—=æq™¿üóŸv9·äŽßn™¥ÞW‹œ¯]ƒö§ŸÆ[£!~ħ€ í&M"Tbr)%sÛ6öŸ>Ý`ù•”•U°êñ\.,,Äßÿú¤8p ´[6kÖ¬+ÏD//æÍ›'^†‚f‰5·ÚÿøGÛ ˜B¡Àd2a6›íÔž9s†ªª*üýým,’’’è`yFIsµ=õÔS |,– ={ödƒÄG h ÈE}ôööæ%ITݶmÛÊú !uI?žØAƒÈÚ±Ã΄H!霙,"ÊnvÆlvê€ ùë_ñ@éåE¿ßýŽØ)HM%uÙ2Š$ $­V£ƒ@Ã…˜‘›™’ΦôxüqÚŽG²æÓ_}E¾EÔ)d>J›™zŸœ}¯¿Ž©¦Æ¥O’A"`¤u—†4—&FF 9Î\I;·r>[r‘‘ƒŽÑ;ÏžMx—.ùàJ/^tæÞ®sm2aª­­÷±zùe¼,™è³¶mÃ$¹6”4œèÕúWGŸ (:uŠãþ:ž )…;`©³»õý#"ðÌ3If\­ì|é%ôUUNÛW\¾lW®B2¸`-ûâæÍ ©sß}Çå½{’Ƀ•0z4mÇŒáÜwßqé—_Üž3õ¾q#^y…3ß|Ãå}ûd×íÿÌ3.£vyè!—ûÈ=šýo¾é¶¾AATW×àí­¦°0ïŽx{{« ð/& ¬3PÖ¿ŽË¥tïÞîÝ»;?? [ év*•Êî{«V­xÔ’wO ¸SBÊ >ÁÁ´ìØQÖÃUÎ ø……99õ÷}ê)üBC¯¨á»ï¦"/Cuu£ë¥pÓ‰vìüV¹m›¬?†•ŒÍ›)>{Ö¥hÃÃÎzEN&“ÉN X£ š%‚IšWJj¶çh¦ز%Uee ×ÛÍ09špÉ )éoàlîç*w—´¼êÂBʲ²ÐË W¢ÇQ\Z²Ä¥èiHIÏ£±®Ž²¬,ªŠŠœ¢4Ê­oF>â¤ÂƒëÊULz=mÆ#ÒáÅ»Ý"  2í¤ð Ü´õëÙýÊ+ þóŸ¼Ær $-ÍmE(Ô‡UW¹È'‘8nýŸ}–ÚòrJ32¨))±»/ئuk<÷UÅŤ¦ÊÞÃÛÿüg¼,aÕÕ~~ŒraªëHë¡C‰Ú¹Óí:¾¾~Ô9Ìtß hµe¤¦ÅÇÇ@ ®'!!DF†Þ|!•˜ØŽÈÈ»eAAÀŒÎâ×QUU¿¿¦Y4dµVkÂê›bí¼+]tÚ¤3w½ú*‰ãÇCNGE^ÕÅÅTÛuÏ®^MéÅ‹.˵Š¥ZM K"8ÝåË*+]ÎJI}|”Àùï¾s;*o-;Ôb笻t £CÇPÎÏH*¬¢èÄLja79,sô›rRÖ©aï½Çοü…Ò³gm¡×üZëeYަz&@¡R¡iÛ–ª¼<ô:Û¾´=ÓüÑ)g–ÒÍ6ŽíÜP`OËTÕyy¶ˆ2UÂGåãCP\†ª**rrœÖu5[£h`YMI —ví²3 8öÑGjk3ãFìIÅoNGê'ŸÐQÁ;0À¨(§ãþÊ+jjØg cnn@LY¯ïqK–ÐfÌ·÷þÐ_¤ëܹlzúiÒÜ8Pß¿aÚóçéñØchÏœáÜÚµNëH£üyÑÓ’ô[íãƒ&.îšžQƒ ¸c2Æ @p30™Œ˜L†›/¤ÊËËP©°™¢éõz4š‚‚¨ªª°­›Ð,òðûïó$Š´Ó.çk#Vsµõ?NÌÀÜýÞ{¤­_ÏÏú“³€qøë(†¤ø……qÏW_°qáBrvïvÙYw7[ƒÌwkÙÁ ¨¼¼X>lù‡7ØN®fDäßZ#ô%BÈ±ŽŽþQßYB´;–¯Â>òž»ã6^-Z0í«¯Øöüó\ܸѭϔ'"ç©¡åÒólv#.[¦ãïÁmÛ2õóϹ´{7.´ kwæn®üÑÙ(qÐwu¸3=u•'­,-$~C £G3ñ£–½ž|Ò&¤\‰)kÙþááÌZ»ÖýÐJÑéÓN&¸U……|1v¬¬Ø•òaR’iª²óR§ÓÙŽ-´CîY¹Òí¹¬*,tû»ÑxçÍF @йf!UZZJDD8Fcý,FII)-[FàããK×®¨««³9=ÞÎ;Guuµ¬­/Ôû-ýòË/´mÛ–(™QnÇN¡J¦ã‹Œpp%.r÷ìáãž=e·qe’çêÿªü|[YŽâË]”.:­ÒÎfe~>õìÉôU«ˆŒ$ïðáë‡‹Ž±uHéåŬ5k8¸d ië×ÛfŠT¸ž‘’›°–×é¾û8%étš„“ܹ‘›5«+.擞=í¶7y  \™Í™<7?úˆÀV­ì–YÛı¾f\GK”žKWbGºöôi»kÏÝì›'Çâ£Ñ0í‹/ØýØùÉ"Q6p»š©” ½ŒÍ›Ùñ—¿0Y2³s5Täæ²zútžpðC\uÏ=heÌYåî+¹¶Sy°o³Ì5¤=wŽ$÷²'Z¶„—þÚ¬^$ùùâmzq´A3Rz½žššÔj5••Uèõ %yèõ‰²³shß>é†À‘#GHKKÃÏÏââbF:„”X¾|9ñññlÙ²…‘#GíV ©\,oȘF.l¶\gÓ]Ùf;l®FÿA~–Ì1鬣@Øñ׿¢òönTð¹Ný}ë×ãHë¡CiѾ=&£‘Œe;Ï 8bxJ ±ƒ¡‰‹£×üù¬ž>:­Ö®]]™¡9vêåÚÁºýÔÏ?'Ðr=|>r$f“É­œôoÏ'ž óƒºl“èþýmáê­„´oÏÀçžC{îëŸxÂ¥/“²!ë8û×hnHD~óMZ¹èà+½¼ˆ4€àøx2¶nå§E‹Ü%iÈtÒÑUîšL߸‘ªÂÂk •P–™Ég#FØ-Óeeyt+¯a¿®ÒÜŽy¢ÎK£]»¶âz3^ÚjÑ@p»)¨Ÿ•ŠŠŠ¢¬,//µdy9¥¥eTVVÞ°ذaƒ-„aJJЬºtésæÌ!''‡M›61wî\vîÜIQQ‘m½ÔÔT .:EîDÈ›ÑyR†»¼Lx ¤\uú]ÕM¶Ž–{Ç‘†8i8¤ÕâUSÃAKžŸÔÚZ²D㌔õ¯u6J£Ó‘¯Õ‚$dõI³™:ÉöŽ~RŽÇ#f®Žß Ä––h;'Ý_³LYŠª*§ðçR¹ [RVÆ)Á×ßnêÓ˜ëDZÂÊˉps,$y›ŠÊË9%ÓFÊF :ÈÕÙéúÌÏ'|ÍüZ¶´Û¶"7—SMUUÛ¾Ýcñãé}ߘ6võ]Žâfø" $**R¼Qo^^~èõÕ¢!àvRDFF ¢¢¢ðññ!44„’3jµ-[¶´$vkz‘–âââh)é¤ét:ôz=ÇNœ K—.•a2™8sæ :uò¨SuB¦lw«.ê"·Á`àÂ… $;øƒ¸¢®®ŽŒŒ [¾§có°.ÒNçºt^ÿá‡m~P®¨©©!''‡ÄÄDöfgCv¶ý 'ÚŽÛTUU‘ŸŸOKކ«»øIîÚ2»döðXO'¿ùÆ£¶‘R^^NYY­~ض?c•••ÄÄÄ\õ±ºãä‰(ΟIWhµZjkk‰²Ô]z-ÊCQQF£ÑòŒh|Ý7ìØ!ßþ–ý»:V9TPP€B¡ Üî¼¼<¼¼¼ó0™¯'í®ð`}Ef¦x3 @p» ©ØØ~ýëGíf¡¬F[Ò¶†åÂÕÓ®];.\¸€F£!"âŠÝø_|ÁÔ©Sñ—D;{ö,IIWL ãããíÊêØ±#³gÏæÕW_åü£Çbäí·ßæÙgŸõhý”””F%kÌú,]º”E‹y´¾V«eåʕ̷˜ÏÝʺçççóý÷ßó«_ýÊ£õ³³³ùù矙={ö-¯{c×?sæ §Nbúôé­üøq222˜}úx¼~ÿþýoX[xyyѳGv)¾¾¾.tÜìºûûû7j%((È£YÀ›Q÷Æ–J{K¸yOhÙ²¥l2Å[Q÷ÈÈH-ù‘ÈnÙ¹ã{™óÐ4|}]¿×6nÜBEE%3fL±-[¾üKfÎœŠŸŸûÁªÌÌlÎ_ªBíuÅ7üÔ±}Ü?c¡¡Á7ä8 %^^þ˜Íö61ùùù„†:§]Òé*ÈÍÍ#-í"ééÄÇÇ1iÒ¸kªC³OÈ«T*¹×!L6ÀóÏ?oû?00°Q#Å£Fj”áàÈ~½Ên,>>> :´Qâe%ˆÀ­®{PPP£:–-Z´ wïÞM¢î-?""Ânö´!¢¢¢Œ6y³êÛ¨²g}oeÝÛ¶m\0„ƈÝ]wWF”J% …“Ʉ٠*•’[Iq±–7Þ¨Ïy–Çôé“ùøã”””b6›xúéìÞ½—O>YÁÒ¥õë}ûí:ÒÓ3Q($%µ£´´Œ»ïMXX(o½õO=õ¤-ņõ¹o2™1 k˜?aûö](Jü¹÷Þ{Xºô3 f³™‡šÅ† ›)))Àl6ñÌ3¿=.@pÛaBAtÒÛàá'KþI°Ÿÿ»\IÖçªõ=2räpÞzëJ ³ÙÌÌ™Sñµø’›LõÍf³Ù¶mŸ&á ½ð E©Trà—­lÙº‹Eóç`0ÔØÊ«@õÏeë_“ÉdëS›Lf”J…mJ¥ÂVO…BRiÿŽ3™ô öéL²²2 íjW7³ÙŒV[±c'ÈÊÊfáÂ'ÈÈÈbݺ™<ùî;WHÝîÜu×]¢î¢î¢î¢îNlß¾›£G£V«X°àq6nÜÂúõ›xçÿg[gçÎ= :ð¦Ö+,,”Å‹ðÆKÐë ¶—äÞ½1™Œ 6ˆƒض‰‰‰&<<œ!CpàÀaŠ‹µ¶®Ñh¤ººš?¼ ÿž{&±oßAöî=À–-Û3æ.úôéÉŽ¿°xñ8ŒV[™3çèØ1‰ììòó )))µ«›@ ÜŽÔÖTóÔ´´íÐ™Ö íÙðíg,ûÚ>Ö/¿ìãÀúç°¿¿?>//µP9w.””ñúë¯Æë¯¿··7 …¶”W_x’ŒôtÿÝ‹üõ©‡xÿ‹Ív¿8p˜ºº:úöíͺuèׯZm)Û·ïÌôï߇óä“óP*•¼ûî‡L˜0–uë~D¥RQ[[Ë¢E¿¶ ;Oyíµ·ñõõ¥¤¤”ΓÉÏ/dÉ’ÿa4™3çþkjëkRgÎ^ ²Ê>AdM•ŽûÚNFyy9uuzZ¶ W·ƒÁÀ?üÀÔ©S¨®®æ£>"&&†iÓ¦¡P(8оTWWÇÆmþ2K–,¡¬¬ €>}ú0V’PôVãX÷愨»¨{S¯û¡CGY¼xG`üø1œ>}Îöû²e_°víz8Ìoû^^^vÛëõzV­úŽÜÜ|ââb™6m?þ¸™ŒŒz³èÇ„}û2rä0¶nÝaûÿ_ÿz—yó&$¤Eƒõܺu;Ý»w!66šC‡Žõæ;½úöíEFFEEZŽ«¡êççÇSO=i·^\\,ÙÙ9Œã,`ûöíEff£G`øðÁøøøÒ‚ŸÞI^^>gÏž¿¡&§@p+ññõãÑ…âÏ¿}€ÚšjÞ^¾‘ˆ¨X ϶ÎáÃǘ?ÞÞÞ.ËIJjÇèÑïˆµš§Ÿ®÷«—Œzð±ßñû'ïçÙǦòØÓ£K~€sžÁ%KþK\\¬í}`4Ñëõ9rœ3¦°zõZâmïƒüü"##8>º:}£…”——O=õ$YY—Ø·ï ­ZE²xñ²³sرãfÍšvÕm}Í6 ¥&‚Û·}ޤÕpøèy”J•­>úè3Ö¬ùÔÔ“âê¶ëĬbƒ$Döÿþ÷?æÌ™Crr2ßJÂMÛFjkùꫯشi“mÙ‚ xá…èÚµ+­’¿  ]ƒ:Îö]ë&ü¹ iqðàvïÞË’%ÿ¥G®²ëÌûƒ`ñâN" àĉӘÍf¦M›ˆV[Bff?ü°‘'žx” ž`éÒåøúú°wïA.]ºLQÑ•ÀìÉÉðöö’ݯÔ÷iܸ‘Œ7ŠÜÜ|¶nÝÁsÏ=…J¥âÂ…tÚµkËž=hÓ&öí%Ûâøñ“ ¾9úYI¿ÇÇÇÍÖ­;8z4€©S'²uë‚‚eÛD n†ÊßßúŒÄ¤.$&uvú=88˜ŒŒ,ÒÓ3Ø´iùù…hµ%äæÖ ®ŠŠJ ‹ÉÌ̲™SoÚ´ôô Ôj繘øÄdÞ]±‰ˆ¨X†Žšäô»¯¯/çÎ] 00€üüÔj/<´iIJj@tteeå}zrñb&QQ­(--£mÛ.]ºLÝP«Õ´jIjêI¦O·JÞÞÞÄjjIŠŽeíºïhݦ*e%fó•d:ݺuÆ×ׇÚqîÜ¢£[1eÊxRSO’”Ôž®]ëëñàƒ³¨¨¨`ðàlÛ¶“ÔÔ“´iï$|23³),Ì·[æXj„±¤¦ždàÀ¾ךÔÔ“´jÁ]w ½¦¶¾f!¥×ב~þ$ë¿]NMU%¯ýw AÁ!@.z½ž>XÊÙ³èׯÉÉÄÕm½ÈhÔ6-ZțѬY³†iÓ¦‰F4 NGII 555(•J~þùg&L˜ÀÛo¿Mtt4‰‰‰lÛ¶ÐÐPFŒÁøñãE£5!¢£íg ¿ÿ~#/f²zõZ[Ä¥víÚòÆK˜4iœ“JLlCxxKÒÓ3èÐ!‘ÀÀ[™ …‚¨¨Vøúú2`@_ ‹ˆŒ¼ å_ÿz——^ú£Ý²ëIBBœ“)ßõföìûÄE$nK’“±¦wOn^ÿ¿Ñ9?è”)öïõ¾}{Ñ·ï•ï±±ÑÄÆFÛ½wºvíD×®ÎQ“cb¢=PL‡¶a@ ˜Áèd²C‡vvÛ˜hŸ4((  +‚]‰³ÙDLL11îßE;&ѱc’ä¸b®[[_³Ò‡ð÷·Vð×§âÜÉ£$&]¹öòòâÉ'ç±~ý&!¢¨®®fçΜ?žŸ~ú‰~ýúÑ«W/Ö­[GYY³fͲuvçÍ›Ç×_N§cÏž=¶mL@@gΜaÊ”)¢Q¢]»v¶d¿mÚ´± õÖ­[‘‘À˜1cÐh4¢Áš÷ß?Ãîû¤Iãœfo_’vÏnMO<ñˆl™jµŠ™3ë}7{õrN‘ðÁoŠ wø{Gp„”Ji¦uDoÿçSvmùž61aøª¶RÞÞÞ6‡2Á”J%¡¡¡,X°ÀÒqQs÷Ýwsüøq‚ƒƒ‰‹«7?ñóóã/ùK}[«TvÛXs Í;×)¤@б±±lß¾ììl ¹¹¹’””Ä Aƒøå—_hÛ¶-GŽá‘G &pIhh^^"!îÍ@¡Ïz@ ¸m„T·N øùæé í5"ˆÉb‡©Ñ1bÄÑÒøøøÈ&òíÚÕÞq\­VÓ­[½/¿¿¿ì672Çàö¾çÍ›gûþÎ;ï0cÆ »¿ACÄÅE£×W‹†ÁM£°°ˆ²²òëRVBBœl.¤|||0™Œâl @ ‚›Â¥K—í"¾^-jµ7jµ6sº›)¤Kee¡8ó@à‚ÚZÝmqåå:N:#N¨@ \Ò»w«NG¡P( ´Üvñb&Ÿþ5úÓ³¤¦ž`óæíøúúò›ßüÊòÁhÔÛÁ7i!e ƒXXXÌ™3çÄºŽ¸°̓+!6Íâº\rr.ßÇQRRJ~~AAŽ9?HNNW3(4WºtéÞä®ùÂÂBòósÅÉ\wâãÛ`2ÐjK¨¬¬pú=22Ê2t}ÈÈÈâèÑãøúú°yóv/^€NWÁÿ»ŒÇŸ{ÝQ}+oÜŠŠJüü|Q*•h4Á’™™ˆ› h¨T*ºwïE]] ™ète¢Q׌Étó;YƒÝ»÷1|ø`u2ñÍ7ë0Ìœ9•JÅ¡CGÙ¾}7¿þõ#PZZÆÒ¥Ÿ1jÔpºwïbhPÚá( 4š`Z´LTUUSXXxÃB¨ Móþ6R]Ý´f/^L# À)÷Ž@p­(•õï€V­Â1ÂÐjµTUUÙf~T*•m¥²²Šÿüçc† DŸ>=ÉÏ/`ûöÝÜ{ï=í+;;‡íÛw3}údÞ}÷&“É®¿f4Þ7$å­nàààÄÆÆˆÁPG~~ž¸ò͆šš*ÊËKÈȸ(CpSÉÏ/ /¯€ªªjŒF#55µ@}²o½^Oee}Fú¼¼ÛKËd2QXXlWNmm_~¹š­[w¸Ü×êÕkéׯ7C† `Õªï8z4•²²r/^Àþó uuz>ûl%‹/ //Ÿ“'OÛ=ç5š`Z·nMHˆçL&@ ¸½L(•NLL þþÎÂý?ÿù˜Å‹pèÐQ >ÃèÑ#l¿WVVRUUmy§9ïÃÛÛ‹ººú÷Ùñã'©¬¬B¡P`6›©ªªÂßÿÆD–UßʆŒlEpp´C ÁÁæÍ{¸i )…B)›×Âd24¸íÅ‹éŽF$®0@ ð€Ó§ÏR]]ƒJ¥"''—  @FÁÿ»ŒûïŸNXX(Éɘ=û~Þxc 'Ž%$¤…ˆˆŽ¾q骪ª)--!88•JØl jjªÑjKP©ê}™ -Ö gˆo À°aƒ8xðˆm???ÆCTT+λà¶|«hJJjORRûz,×,¤Ôj_'Ñ”™™ETTDƒ/N___¼¼¼ÈÍÍ£  âê4+***),,¢¶¶V4†à¦ÑªU$ÑÑQ¨Õ*âã㨩©eûöÝ̘1…½{Ò²egΜcÇŽ_ðõõ¡U«z?¤òr/¼ðwÞ}÷5[Y¥¥eœ;wK—rØ¿ÿ½{÷@¥R±bÅW„‡·dìØ‘ <€ÜŒR©dàÀ¾$$ijk×òòòiÕÀ=Ì IDAT*o4 û÷"33›áÃS]]ƒÁ §¸XKq±–°°PBBZ? @ ¸CÑëõ”””R^®C©T@‡íèÔ)™ ®Ì2?ŸÆ¥K9œ={¤¤vvåtèЮÉÓu0í3c4ÖÙ-)--¡U«–frs󈡲²ŠêêjZ¶¬o4ƒÁˆÙ¬ÔøúPTTFXX·ØâP ð“IÁÅ‹Yèt:4šqÝ ® ÏÜÌœ9•_~Ù‡^¯·˜Ì™9r-[†Ñ²e&“™ääøûûQ[[Ë}÷Õ'Wöóóå‘G´‚›Íèõzf̘‚^%üëàÁðñ©-ìß¿7§NÁl6Ó¹sG ~´ðÂ…tî»o*•’Y³¦²ÿ!FŒBxxK23³ðöö ¸XKQQ1áá-Å ™@ ÜA F´Z-eeå(•JÙpç÷Þ;Íi›3¦`4ÖOÖŒ5ܬ¨iqC{~µµµ|ÿýFFÁ` ==ƒ ÆõÑ9vìØa{Ɇ„„JzzÚ{¡õèÑóªbØßLŒF#ii¨®®OàåÑzƒõ·ûîçç `{Ñ´k×–>}zÚ­ãååå´,$¤ƒp*?!!Îî{§NÉvß###ì"îyyyÉ–cÅú¬/**¦°°ø†9þ M™ÊÊ*KØÿ¦Cii9âä®;&“‰¢¢BJKËP©T¶÷€±±1vß;vì`÷=""\f+*•÷5×S©Tc4ꛞ²²ví»é:é‹?** FC]]-gΜ½£}¥üýýÈÉÉnÒu¬®®¦´´TŒ( 7kІkeÊ”ñ·ô8üéÕ«-ZÈ?+êêêèÚµÛu;^ 9 P( jZ¢%9¹#þþþâänÈû,44//õ yß%'·Çl¾ö°æõVrWQV}£°¼\G×®øé§mŒ9Ôî÷λPQ¡“MÒ%‚æ‹ÕŒÛ5>¢‘w$Þ¢w ¾¾7°lL&ã-=¾kR:]9gΜ±[f4Q*•¨Õj~ûÛ_ãççˈ56Ó+gÏžÁd2áïïß$í@ à†)__/zôèêòw«xrQVÁåããƒ^¯çòå\ÊËukîØ“QYYÅÅ‹™MºŽz½…B!"o 7qo @p‡©«%>>–ÇŸ‡ŸŸp8–2jÔ0ÑÁÌ, Áí$¤¬NX×Ë1øF&‚æŠÏ•°°/f£Õ‹Fà&£Õ–]?!U[[Ÿ<«CRkѲ@ph—Øc›xÑ@ Üd:|íBJ«-#;+W´¦@ ÜŠ µ¶ÿ&½SÂs@ 7OB«7(¤ÂÂBo.ZS nÛ~Þ!A ‚f@ƒBÊl6a4סVû"‚I5mŒF&“A4„@ÐŒ¹É@ 4!e%00…B)Z¬ S]]JMM™h@ àÓhetäȾýö[»e'Nœp¹¾ô7wë­\¹òšÄÓýx²ýÍØÎÛD«Õ²bÅ lËÖ¬YáC‡Ä•,@ ÜDËüàÁƒÒ±cG–-[ÆÜ¹sY·nßÿ=ÿùÏd·Y»v-]ºtqúß‘^ÓxºO¶¿Ûy‚c›,[¶ŒéÓ§³|ùržyæ¾ýö[bbbغu+;wW³@p‡ Õ–PPPx[KLLAAA⤠àöRÉÉÉlÛ¶Ó§O3xð`òóóIHH >ÞuxÞªª*Þ|óMÒÒÒøôÓO¹té*•Š pâÄ ^{í5V¯^ À?üÀ™3g¨­­¥C‡øûû“˜˜HRRo¾ù&¿ûÝïd÷•J¥àäÉ“¬]»³ÙŒ .ä­·ÞÂ`0 T*¹ï¾ûØ·oééé¨T*ÊËËùàƒÐjë#fóðÃóÁ`4Q*•Ì™3‡M›6‘““ÀСCmûÞºu+éééL™2…?þ£ÑˆJ¥âñÇ端¾B§Ó¡×ë=z4ýúõsªû²eËÈÉÉA¥R±páBRSSyýõ×mmP]]M||<óçÏ ²²’V­Z±páB|||¨©©W´@ppéÒeÚµk‹Rټͭ•J%ÞÞ¾€ð Ám.¤>Ì€HNNfÕªUôïߟÈÈHÖ­[çr???ž|òI^ýuÌf3f³€P^^΀èÝ»·m›öíÛS^^Î<ÀöíÛ)))Áh4ÚÄ„+ÒÒÒðöö¶•=wî\¢££III¡ªªŠÀÀ@~ó›ßpäÈNŸ>Mzz:/¼ðF£‘W_}•šš.\ˆF£!%%­VËáÇéÞ½;iiidff’““à /¼€Á`àçŸæÿø£FâÑG%55•Ó§OÓ¡CNœ8A~~>J¥’Ù³gÉÎ;êmm€ýû÷S^^ÎÀíÚdݺuüüóÏ´nÝšÙ³gsöìYÖ®]Kjj*/½ô  D ¸£ðõõ!(°%J¥¹YÖ?;;‡P”J•íù~»QZZ†¯¯O³¬{]]uuzZ¶ »mï!ƒÁˆN§ÃÏÏ·YÖ¿  ˆ¸¸ØÛú9ç툷W³¬»NWIEe~·íùQ*ÕøûiP(šç{(#3‹°°k³ˆP7®Á”FÛ¬ŽÉd¢²²’ÚÚZt:N#¤ …?¿ú‹H¥R±k×.âââ˜>}ºmf©®®ŽÚÚZ*** ¬¯˜º¾jÇçûï¿§ººš={öPUU%[7•Je›åR«ÕxyyQUU…N§³ÕÃd2¡Ó騩©A­V£R©Ðétœ={–òòrعs'Æ ³ï¤I“˜6m*• ¶oßn+355•JÅÀÙ¶mjµoooî¹çFމZ­ÆÏÏ;w¢V«Q(¶²µZ-Ÿ~ú)O?ý4;wî´µÉÓO?-Û&“'OæøñãÌž=€¤¤$¦L™Â°aÃlí+î,”*P«›ç ìrn!¡É·õùQ(DEµj¦À ÒÓ3nó;ÈLp°†°°ÐfYûœœÛ?ǧBj¯æùŒ«ª.§¼üöR*µ¹Ùè]¾œCXص½‡TcÇŽ}Qº ¼¼œÄĶÄD·B©2ÛBžûúONNûöíã±Ç£¸¸˜Ï>û Ž=J‡œ:õ~~~DGGÛþ8p ‡b×®]Lš4‰øøxNŸ>Mqq1§OŸ¦wïÞ¨T*‚ƒƒ ­¸ÅÅűmÛ6ÈÏÏ·3©³Ò¾}{Z·nMLL ýû÷gÀ€¬Y³†0lØ0©ªªâ§Ÿ~B¯×3uêTâââX¹r%ôéÓ‡¬¬,ظq#cÆŒ!))‰¼¼<¶lÙbó ‹ŒŒdÕªU=z”)S¦ÈàÁƒ:t(—/_¦gÏžœ?žŸþ™²²2Ú·o‘‘‘xy]UÑëõäääеkWâããíÚ$..ÎÖ&gΜ±ÍLIÛÀÇLJˆˆ|||,£k5 µ¢w)4cöî=ÈàAC0 ¨TòáÐóó ‰ˆÇ×׿ÏH]&"¢% …ò¶ ù^[[K‹ÁͲîuuu”””¬¹mï5“É„B¡Àß¿yvt/_Î#44ä¶~ªÕÞxy5Of®‚šš‚‚oc¡«ÄÇǧ٦GÊ̼DddK—¿çåÑŠS§NPPXbÓ%vmðú믛í_nÙŒ3š¾}z ò2Ù¦ëZ´h}ËŸgff²råJ wÝu×5¦pÅÇÌ<€¯oóœæáÏ‚æÏ›o¾ÏïŸýuu5xyƒÑXç´NjêIºtéHppKÔjS£÷qþ|Zm ýû÷ñhýüüB–,ù/>8‹ääö×å8wï>@çÎÉÓ¾ºÛò\–••“À?ldâÄqNÿË‘•u‰²²2ºvµ"TZZƇ~ÂãÏ%$¤…Mðlܸ•Ñ£‡{l°rå7hµ%ÌŸÿ+·ÀôôŒÛÚtÌj]ÓØ©?ü„¢¢bf̘BRÒÕÝ%%¥¶óx5ù€‘#‡1`@_Ê>{ö<åå:úöíuCêž““Gii)ÑÑ­nÛó£Tª ºê½;~¡gÏ®¹|.¦¥]䣖óÔSOq]ë¿cÇ^ºvu=#uôÈqºtîÁª¯¿äø©tž§;3õ·Ì'66ŠgžyZR—óÒ3ç¡ZþF$òžˆ¨£GÂÞ½éÜ9‰ÊÊ* %&&šüüòó P«½èÔ)‰ÈÈpî¾{yyù$'·§´´ ?¼½½)(¨Ÿ¸çر¶N±c'8°?uuµAdd99—).Ö¢Õ–RUUMBB</fœœÄ'Ÿ¬`Á‚ÇyûíøãSWWÇêÕkéÒ¥«V}ÇŒS¨¨¨D«-¥®®–Î;R\¬Åh4RXXDëÖ±„„´à¾û¦“’ò/[ݬçPœKÏ(**æ…ž %å_¼ðÂ3œ:uƒAOdd$‘‘á¶séççGûö‰èt¶sÙ±c¥¥å¼üòÿñØcsˆŽŽº­}Ñn4Ÿ|ò¹í|œ:uÖÖù®¬¬$$¤­[ÇÊŠ¨'N£Ñ±ÿa’“Ûãíí…¯¯/EEÅ„††PPPDAA^^^tì˜d»?tº ‹ë†¯hükäܹ $'·'((ÈöŒ¼té2Zí•{'1± ={v£¬LGdd……EF ‰‰‰¾å¦¹ ).Oœq@ hæ|ýõ»N V«å—_ö3`@_6lØÌ‚óè£ øÍo£ªªŠË—s=z„]ë×ÿÄ AýIHˆãÿûÔVžÀsÖ®ý¢"-ÉÉX»öGž~z>Ÿ}ö;wdïÞ ÔŸO?ý’øøÖ9’ÊÔ©yøáÇyíµ—¹té2z½€®];QTṮc'xï½ÿqÏ=“ñööæÄ‰Ó¤¥]$66†ðð–l޼ŋ8ÕÅzŹôŒœœ\þð‡¿¡T*™<ùn6mÚFIIýàºu?²hÑ“¬Xñ5:%S]]R©âÇ7g9—Ç:t ¥¥ådeå Ñh„ºNƒDƒ“'O³gÏZµŠdóæíÌ™s¿Sû®^½Öî9˜——OÛ¶ñ´hÑ‚o¾YǼyQVVFVVäå°gÏ~^xávíÚK«VáôìÙ]4úuà­·Þ' €Ý»÷QVVÎ_¬¢cÇ$ ‹¨¨¨¤gÏnvë/[ö9†èè(~üq Ï=÷TóR@ hþ”••Ûf#.^̤G®Ìœ9•=º’••Á``ÈLš4ŽË—sùé§m¢Ñn>8‹èèV¤¦ž@¯×ĤI㈉‰"77Ÿ²²2&MzÌÖÙ;tè(óç?Æ®]{ ¤wï¬Yó/f’žžÁ¯~5›Ž“˜>}²m•JÅ£>dù~B4úu &&ŠùóÅ÷ßÿH·nùê«5œ?ŸFPP —/çâëëKXX(©©'ðgäÈa9’JYY9¡¡¡´m›@rr{&M'ô:a0øøãÜsÏ$’“Û3dÈ@>ý´D65LII©í9˜‘‘E—.øôÓ/lAÏöì9Àå˹”––Ñ­›ÈÕy£xê©ùDD„“’ò/êêôüòË>ôz=:]…Ëv䑇ðöö"5õÖ?Ó„‚;ˆà`ÝH,ÔÏRedd¡ÓUàå¥f×®½¬YóÕÕÕÄÅÅRVVÎŽ{0 tïÞ…ØØvíÚËÖ­;l³"÷„‡·dÍšdíü½½½Ðét¬Yófðà´hlÛ&66ot:>>>ÔÖÖš6m"<0“mÛêSkœ>}–¯¾úoooÚ´‰çÂ…t>úh9aa¡6ÿß={pêÔYöï?D¿~½ñööfÍšرã1#å!!!-˜ýyÊË+èÙ3 {{{ ŠP©Øqï~ cÆŒ0Ÿ‡¦M›‚‹‹3“&§ººÚ|ãG­V1eÊ3ugøðǸzõ*}úôü}'RCîÛA¶„â~´gÏ/Ûñm¼¼< ÄÕÕ•  óçññ1tî|½'#{‹{{{ñùç[Ñh4$âÖ¬bzó>ñ÷÷Åßßò¢úÆy"##,æquµ3_lÄÅEÓ¡C{óôqqÑæÎ,®¹¹'¾¦&7n‘×—î±DDt°˜ÆßßÏb 1''µÕ¾lmÿŠ»§P(¬âx­·Ì»Ù‡7ÿßÇÇÛ¢ó'''Ö¯ßDÛ¶þté)ÿÜØk嵸·mëgÑÓ¡“““ÅþŽîŠŸŸþ¿‹m¸m"ÕÜl$‘Bˆ_Ksó¯{νÖ6àF=6è¶ó¨Õ*fÏ~YvÖïÐÍûîÇö%@¿~˜ŸV !ZשS¸¼úú;0xpÿßÕúÜQ©o²rððô‘½'„¿°Šê;úü¹‹””\¾/·³äJ)]º<Øw㛚š8~üûûrÝu:ýCѽó¹s8þâ}¹îÕÕþ¸‘Zm=ßÈ»/×½¦¶ŽÀ@ÿ~egçS[s‹µµu¿N"åáéEtlƉ¸ÍP›6„†¶»o×ÿÇ^_{(:EvƒõwÊhl" ÀÞñç¤×>!„¸Ïøcgçð@$"ƒôú'„â!I¤ŒF#uuµ¸¸¸Z|~äðABCÃðôò²š§©©‰ çÏáëë‡J­þM7¸±±‘ÒÒïyÕÕU¸¹Ý¾Ax}½–Úš||ý~ÒúVVT ÑÔ|ïw;Úý%½z÷E©TÊ/ÄÀÓÓƒA'B!~C¶w;ƒÁ``㺵TWU™?«««ã衃­&QzŽ-›6òÕž]¿ømÞ´ñ¶ßëÈËÎþIe|úÏtšššÎý¤ršššH]ô1û¾þŠýß~sÏËQ*í9väíB!„BüLîú‰”ã&LdýšÏúÄ0<<<9|0‹nݯ?±ùó äåæ P(˜0i2¾~þ <”¢¢BÀôDç³åÔÕÕÑ6 €q&q0k?Y™û°··ç鉓ٱm3z½žÊŠ úL\B¢ÅzV¯\Î¥‹Q«ÕŒŸø,»wî`yúòr²™:í~8{†úz-Yû¿¥C‡FŒ÷ûöòÝñãôd{#uÑ'èt:´ OŽy GGGV.K7 fØ>Œa#GYÅ ¼¬”Þ]€^§cü3ÏâåíÍÂ÷Þ ¡[2ýú`ïž]TUTнg/>ß°–¦FÓ“¹ “&³?s£ÆŒ£° Ÿúz-QѱVåìýÔÓTV”óÕ®/1 |wüý&¸];V-Ï ¡¡àv!Œ~j/7‡”9s1 \).¶úþPÖ~”öö$DvfëæM<>|$mHè–DEE9;·o¥° €™o¤àááÉ‚ùópptd럛`3fýâË—Iè–dJ: FÆŽŸÀ¹Î’2g.±î ¼ñÚ˼ýÁǬ[½€¡çôÉ“æu)ÌÏãßÿû¯¨TjÌŸ@Êœ¹”•–²m˦V·ß`00ýÕ×P*íY0³Sþh^í[6ѯÿÆO˜d^À¥ 8d(OŒÉ®Û9ShJ*¯VWS[[Ù¢B6¬]mžþµ×Søà·8•IŸ¾ý‰‰‹§¼¬Œ#‡’2g.k?[AA~.>¾~xûø°ö³•<>lÕÕդ̙ˎm[(-)‘#\!„BˆßK"uâøQ4u €—·7Å—[ï‚·Qßú{üjµÎ..ŒfNNÎ,úx!Dö©“¸¹{àä䄇ÇõÓ";w!²s‹d&1)•ZMIq1¹9Ùôê}=©+,ȧCxAÁØØØ0vü3­®‡§—7*Õõv[É=z²`þ<”J%&=×ê<¾~þ(•×S\‘‘F—¨h4uu”——Ý2nAÁ!8882lä(òrsÌëéëçGû°æðšYxû쉉‹¿a¦¶RcÇ?Ãê•Ëpr2Åñ…—¦[Ì«×éP´Œ]Zr_9]!„Bˆß,‘Òé¨(/7'QQѱØŸIÍÕ«¸¸ºË‚ùóP´Q0ùù©¹z•õkWÓ¨×Ó5*šž½û°rY:{wï"6>…BAÇÈHöîÞEHh(þmpss³H¢nfccCYi gÏœÁÙÙ™ÞýLtõéןóç1rôØVçݾõ *ÊËXµ<§'N¶øþÆ¿õz={vídÜ„‰Ve߃†X•³iã: òòèÁÈÑcùîÄ1¶mþ‚û÷?Ó¨×óþ;o¦ž0ˆÁ=a±Œææf¾÷6:޾ö'1©{«qûÓ3™ò'ƒ8°?“Ì}_›sš”9syÿíÖÁ”¨M~áE¼½},毯¯ç£k1yr4;Y•±ðýwh¨¯àуˆOìÀǼK×èXz÷íGnN6«W,ã?ÿ2¯Õõ,¹R̲´%¦ãä¹çñóó·šFSWÇë¯MgÑÒåœ?÷kV­`êôW8[TÄž];øîÄ1ÒW®µZF~^._l\À«³^ÇÑQeñ}yY)i©‹(*,`æoÒÔÔÈÎm[xãÿÆ?þ÷¯´ii·æëçǤç^°*çÈ¡ƒ|ýÕn”öJ^›ÒjÝÉÍ>ÍêUËùÏÿ1Åäí¿Ï£¹å¹òcO §s×(Þ[ðwº÷|„ä=[Ûî/wpâØQ¼½}˜ü‹Vß?zÄ"&þ3•Ehþþé‰Ï¢ÑhÌ1™1û ­–³aíjÎÖ!œ'ÇzäÑ1q=rˆî=zqõêU._ºˆ›»;zƒÁ€“³3>>×Û–ÖiêP+ \.¾‚ãMÛàîá ÍŒF[ÊËJ8xø8AAAr%"„÷±ææfânè¯à''R=z>‚»‡;u6%4»¿¤oÿæö;{÷ì"eÎ\´ Ÿ,|ŸW^›m1ÿÎm[ˆKèFTt ‹?YÈÕ«Õde~KÊœ¹_¾ÄŠŒ4Š/_2w¾°`þ<«Ž4 y¹Ù¤Ì™KNöi¶~ñ9i1͉cGÑ54`4M?„µµ\¾t‘é3f±mó&.^8Ϧ ën[NNöi”vJsOx§¾ÿŽ®Ñ1V ÁËèÕ»1qñT”—Þ±#ÎÎ.ìݳ›—gÌâV¿î;¶n&>±]£bXôñ‡tKîn5豟Ÿ?#žCA^.99§É9}вÒRóë”vJÓz––”°~Í*«$ `ñ' ™üÂK¸¸¸°`þ¼V©åéK ë@sËÕy÷ž½Hîѓ͛6ÐÐ`ŒÆf¢cãÑÔÕÑ.$OOëñÃ>º)&7Ç [R2IÝ{²g×Nllm0|±q=^^ÎPT˜ÚÉé–Çâ²´%·-G¯×“‘–J§ÈëíÚÖ¬ZÁ«³^Ç`0¢R©ˆKH$.!‘ÚÚZVf,mµœ/6®¿m9^Þ>¤Ì™K^nÇ!²s‹éÌŸ‡B¡ s×(²O$.¡[«å|ýÕnRæÌ¥¶¶†EÈ´WgZ|_TX@QQ!jµÓ ÜÔÓäÙ¢BÌ¢°0o_ŒFC«eÔÖÖPTX@Êœ¹œ>õ=Û·nfèãÃ,¦¹“۶Ыw_j®VÌøg&±wÏ.Ο;Çþo¿á•™¯c4±··¾¨<}ò{U*RæÌeÛæMdŸ>Eç.]-¦Q©Mß_).f÷—Û¹xá<'ޱx²”ܤî=ÙýåŽVË­›7‘”܃È.]ùdáû$wïiuÌÖ~¶Š¶mi6Y¹,a#GÑ6 °¥$3`ðP¢câØ´q´RÎ??ú€©Ó^F­vbÁüy­&R##yöù©>x€úz­9iµ·w ®¶°aÔØq´ eEFZ«§ƒÂü|2>ÛpÛºÓØ¨çãßcvÊó¹Éß¿-j''N;‚££ŠÚºZ.ž?OTL,ƒ†úÀ*q¹[y¹_¾Ä•bë^,{õîC»PRæÌeû–/îiùaÂyâ¦öö¦nø—g¤0âÉ1„„†þ,ÇògÏp +7ww®\)fÁüyæA¯ òsIK]Äò´T¶oÝ|ÏÇÀ•âËìþr;'?O`P0£ÆŽ·šf÷—;ðôô"6>ážÊY¹,°ðpÔNj4Õ÷öööDÇıùó DEÇZ<¹Ûí¹–Dõéן];·c0 B«ÑàíãCPp;Ö¬ZÎÇžÀó6OŒnçïóþʸ§'¢©«£^«¥kT4û¾þŠÛ¶Ð%*†Î]£ðòò&eÎ\ΠÕjïº {{{¢bbM1‰‰%´}]£bضå 2÷}Mרh:Ev!7'›UË3è}OÛÒ¶m>¾¦ó¥ƒƒùy9VÓhµZ}²åi©¤/Yü“Žé3Eœ8~ ½^R©dÁüy¬\–&WB!~DêfŽŽŽÔkëÍÿ¶±µ¡¹¹™šš«æ§*z=—[:qpT©¨×š.fŒF#¶¶×{³«­­ÅÙÙ¹e-õõõ8:Z¿2dkkƒ±å‰‰V«A¥V›p¯½Zs³ò²2j®V3}Æ,Úòýw'°SÚÑØ¨§¶¶gë q;;ô-môzJ{%555TUVàìâBmM ØÙÙáæîaõj^Bb/ϘÅäç§ròûï¬c¨RSßr±cl6šŸîUVVP[S˜^/ËÍÉfÄ“£[Ý>£ÑHMÍUú>:€ƒ‡òÃÙ³VÓ8»¸R[s•ææf‹;Ô¥%%æòoV]]…ÓgÌ¢^«ÅÉÙ™!?qÛcâæ˜\sùÒEÓzO/ââM¯jù·  ¨0ŸYû9Û2xó{*õõZêëµ8ª-’¥kOÔnÜ.„Wg¾Îô³(*(LãyÝ®­šÔÖ\?NŒF#Οk96ôhµZ†E§Î]¨¬¨@¡P`0ÌËŽìÒÕê‰ÌÍll®ÕsÛ6½^oî¥5¯½žBÊœ¹Œ?áŽÚõÙÚØb4šžÒj5ZT*•¹î”µÔšš«F¦½:CSNNÎÌþÃI™3—LJÀÁÁðˆN¼òÚl¦Ï˜Eö©“­&±z½Þ¼ J¥Ò¼ìªÊJ€–$j''?Ëõݽs;ž^·N¢T*Ú–óI³ÑˆÍµºSQAm­©î“}ê$GæLQ!NÎN-Oˆ®×Í›6Ð%*š°›^黯ÅÅ•š«­Õ+Ô·¼¢zø`–9‰ðññ¥äJ1{÷ìæLQ!z½ž ëVÓoÀ [IàìâBmm zì”­×á|¹cù¹œ?Ž/6®gʋӘúÒËìÚ¹__úÜpé–çíúzêµZU*«ºc4Ùü¹eLv¹ƒ©Ó^aÊÔi|¾aÖ®fÔØqLu&‡øÑºãÒJÝqvqeÈPËóɵºS]]…››*•Š×fÿé3f™ÛÖ–rn¬;Z†F½žgžbz²©‰™o¼IÊœ¹Œ7'''sL´ÚëõB!„¸ÅàÁƒÿëÆjjj kO@[?lÍØØ@i…_¿¶·\H`P0›6®%&.ž6mÚàíãKzê"Š/_æÙ)/˜œÿç?þ#F¡]H(GbóçéùHBBÛãæîFú’OÑjêýÔÓ„wìȲ¥©?v„ “ž³J¦ìììhÓ¦ +2–¢P(úÄpó…Ìòô¥ô8˜Ç޲<})y¹Ùœ?÷„V«eõŠe¸{xЧ_‚‚Û‘±äSr²OóÜ /Y½2âáéÉ•âbÖ­^E»v¡$&™^çÙüùìϤ[r¢cbY––JVæ·Œ÷4ÍÆf2–.fßÞ¯0 tïõ—.^`çö­;r˜Çžnõħ]H(Gbó¦ë1øô_S^VFdç.¤.þ„ÊŠ ²2÷Q^VŠÑh$}Ébòr³)ÈÏ#©{O–¥-aïî]œûá, ÆÙÙ29ìÃçëײûË r”ùµ¼yù3®nn³,m ³2ÉÏÍ¥¹ÙÍ–º˜¬Ì}´ ¥]H(i©|óÕ4uµôêÓתÝCTKLì7ÅäZB={Æt»áææÎ» æ›·ÇÑÑ‘nÉ݉‰ÇËÛ_?êëI]ôOòr³ÉÏË%1) …Ârÿ„Gt$ci*'Žå™ISph9N&ŒÁ¸§'b0y÷­ùæeøúù¡T*Ù¸n Y™ûx¤O_ƒ‚YûÙ &?ÿb«¯Ž·#}Ébrs²™2u …‚z­–ç'ç™gŸ£®®ŽeiŸšb¢©£Wï~„„†’¾d1…ùLö y¹Ù,O_JVæ>:vŠ$¢•ž½¼}HK]DiÉsrñÃÙ3üõ¿þƒáOަ¨°€%1IæÀþLÖ¬ZNC}=£ÆŽcÓ†uìÞµ“üÜ4Z­UJ¥[[Vd¤a§´cHË+ ³2Yµ<ƒG ââùó¤/YÌþo¿ÁÏ¿-Ñ1±lÛ¼‰MÖáååÅ#}ûQQQÆæÏ7•¹ƒ‡âçoÙ>ÍÓˋ˗.²~Íg„†…™ÛÀmÚ°žÃ‡²HLêÎòô%TVšŽ3E…xxz²è“…æí‹Š‰å£Þ¡²¢Òtœ¨ñ¿©½dHh{<À–My¤o?‚Û…°èŸ ©ª¨¤SdgBBÛ““Â#èÙ«7»vî`ÇÖÍ<öÄpÔj'>þà=JK®•¹?Ü=<¬Žé kW³g×NF<9–ºó×ÿþ<<< âãÞ¥²Ò´®z’{ô$&6žö: P´ÁÎÎŽMÖq¶¨ˆ¬Ì}Dtêd1ŽÝµ:º,m ÷g2vÜsâ>ó•IJî««]£¢‰‰§®¶–ƒ†Ð©s–¥-áè჌fZ­–Œ%Ÿòí7{qT©HLJ¶:Á”Œu$#íS¾;~Œgž}ÎÜÆmü¨aL˜8™ú†z>Yø%W®Ç$.!‘Œ%Ÿrúä÷Lž2•„nI¬_û_íÚɈ'ÇX×®ý>¤/YL^N6S^4ÕM]/>÷ &M¦®¶–Œ¥ŸòÍÞ=hµZzõîCp»Ò—,¦¨ €©Ó_ÅÑÑ‘¦ºÓ)²s«oCxzy“žº˜ò²Ró€gŠ ùß¿üÃFŽ¢¬¬ŒŒ¥×cÒ-)™ýß~ÚU+ÐëtŒ=Ö“¥×b2Å⼦©«CmßÒFêrq«7øL¯¤1Lm¤²¥]»vr¥!„¨Ÿ­ûó’’+¨Õê_´§;!„â·p/m¤¼÷/i#%„°{îþ¼ªª’÷ßþzŽ—_{ à`‰¦B!„â¡p×m¤tºÖ­^…»»£Çާoÿ’D !„B!$‘º{{º%±nõJ‰žB!„B©;ÚžˆŽ‘ìܾU"(„B!„xèÜS)¦Ž#‡Ò÷ÑT¶t.„B<  ^^¾­~n04J€„â!qOm¤2–¦òìóS±··— !„x¨´ic‡§§;®®jóe÷4ð±Bˆûø÷àng°·wàå³0Ô×kih¨Ç`0 P($šB! MMMæ’‹¿…BH"u[µ55;z€’+Wh ÑBñP$Q§OçP]]eñyxx`” !„$R·çêæÆË3fI…B>ž47Ëh!B!,ÝÑ©³g‹¨¨p&00•ÊQ¢&„â¡ÐÐÐÀ¥KÅæ1£„Bˆ»J¤T* …‚ÂÂ38::àææ €F£A«ÕHÅCM£‘: ăW¯µ\¾| ­¶•Ê''µE!ÄÝ%RŽŽö¸¹`oooqáØ¹sgôz ÒÙ„x¸)t탽½R‚!ăðÃØÆFCPPˆÅçÍÍÒ@J!Ä]$RAAVŸ)•Næ¿]\$ŠB! M8;[ŸØÔ$=ö !„¸ÃDÊØdH—ÎB!„Bñ£‰TyùJKd^!„â^h4u!„xØ)µZÍŠ•«Y»v£DG!„¸ÍÍÍI „âaJ¤<<<4hˆDF!„B!nAFB!„Bˆ»ôìðzX&¸ÐèIEND®B`‚snd-16.1/pix/formant.png0000644000076400007640000055514411147553267013340 0ustar bilbil‰PNG  IHDR(§\sÕsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ @žV IDATxÚì½W“$Ù™%v\ë­R–ìêj4€°³;³c³$—|àÿf| ø@£-¹4¬Á8 Ðh]*eDdhpí·+*2+Uu7zº{î1+«ªÈ÷^üÎý¾s>©,Ë?ÈbAE@@@@@@@@@@@AP~–E’$¼ïûß÷3‚ üUÈIY–(ËR{A½ïÿZDã}Ž)Z¶üØÀ~‰ßQ?0Aùká>_è"# ð¯B$/ ðó!(B/ ð}áÞ%^Œ„0ñû]ØÖ¬ˆº\ÝØÞȺú;á¦ßß×ëw]“ø% ð%(7}ßöÅ.¾ô®nlmÿÿ¯ýïû\Ó}7Þ~dE@@@@@àÛà§ü‹fAP~Æø©e+„Ó¤€€€Àáâ% ȉ€€€€€ (‚œüçï¦é¼÷g4Íxÿïîò'°%œV~Úää*®Šæ¯ûŽÿ>^¿í÷Ç÷õ»EüŽø9ö+Øl–?è9EE@@@@ொ²,ßùsÝÏoúÜwyý¦÷Þõ3Ÿ[íý`ç’¤ï/¼–åùPýÛI’yæD×MAP®ŒÿºK“$þÏövãCQÔ{ÏÍu¥Pwí¡È²ò­ÉÒ÷±&Ø1TUãK’Œ²,¦d̳,yïó ‚" ð3Ç=[hYß-ÃqWðË‚äm4ý¿úX«ª~í{¶ÉÈmss5ƒr5Qù­d„½ÿêÏ4͸sMÜE~ùÒuyžñÏ”eñÎýÝç|‚ üÀv%~zssWp÷þçÓ¿õgÿZeBßg)S®¾)¹oð»=o“Éé½ÈÍMÇaǺíóq¼¹vʲàc(ITUç‡m°ÀŸ!I¢Û¨Ñ;×ÂÎß2«í9Ý&?¶]A«µs-ÉÑ4óñß¾—jµM{¿õ+Š€€€€€ÀY–^ûú}ÊFÞ'¸û.ïù©¨ï»Ä馹¹.¸û~Ηð ð}`Y.Š¢à÷oÖµïsÝÚ{_ ²¿ñþ6:…«¿¢¨ð¼›ïÃ4>oŽã_"W åö8_Gð²,…ªê0 eY^û\}Nm»rÍúy«…»Î!KÓ ¨ªöN†éª¦F’¤KY vîJ¥EQÇþUÕ.]3›+ÇñQ–LÓ$Ih4ú—ÈÓz½|gm9ŽõzÏ«_"P¶]$Ið¼’$¼ƒX ‚" ð£Á·Ýe¿º«úmp’sŸ]é»õTU¿ÆõM¾4߆hÝ÷3Ûc}µfÿnbu9T»n—ý¦àÂ0€¢¨üþã8|ï¹¾;[$¿×ñ¶ÇÃ0lˆë—~ÆÂvPÓ9Š¢¸õ¹`ÇŒ¢5ÏD­×s~Ž4ß!”E‘ó¹bÇßžCËrQ–â8„¦ü9`÷su®E½$6gd]C–%ˆ¢õ;ä.McdYŠ0\qr©ªâ8äçb„ƒ‘Ëò8¡Y.'”hÈÀi–%0 çÒ¯×sH’Œ¢ÈQ¯÷°\NP­¶e Ò4Fž§œ’{N ( LÓá0vÞ²,àûmDѲ¬BQÔ[çòGOP˜gýöŸ®þNû¾wÙh’ó]ÇBÓ X–{)P»O°Slp•t±€îúúrPû6À´î}=Ûäì¶ þºR¤û»íR Ûî—·7Íõ]%bëõü¶Ùº•ØnðÛD‰¥ëÖ.eH¶×+AZ¯—PU“vö÷û8H‘lƒ~íF›Ÿ<Ïø=°çO–þše¹°,yžÁóê<+cY.|¿Íç°(rȲ‚J¥y)“´]Ò¥(Ÿë<Ï i&²$Ù 6¯Û"ó²,a64Í€ï·Ñhô9)!÷I4²¬À0,äy~e]&H’·Dt4zÃ3=—×k ðøÚÑužWC–%Ð4ƒ“áí¹KÓ„Ùj5Ãr9,R£ª:¢(€çÕQ–%ò<çÿŽãyžÞ»,ðGGPî²£ø©âÇô;í>;æß¦ÁÚMǺ.hLÓ˜ïêÞ”¸èçyvãµo¾’$ó€îjyÉ6aÐuŽSÙ 0CzÝú;Dˆ9ÝDVn¯o“eb¤Šóºrªíq`ïc;Øï–L•wfBn²âݘçyÆwî]·v)cpõ½l,ƒ`vin"˜¶]áë€ÝïÍ%iþ;ÇɲªªÃqªü5Ëòx‚…¯EQáº>\ׇãøÐ4ƒgغQA°@š&$ õzày „a€$ y&b{Ì>âxÇñ!I2%›­ñ±\NP9,ËãsÉæ1Ž7ð¼:æóʲäëË0l„á ®ë# W(Ë’t™„³çäêØx^ †aññP‡ Žã#M$I„²¼LUUƒãTP­¶8™q]R"W¯w±Ù¬ Ë*²,¡ä-ƒe¹<«’¦$IFš&·–þ¨ Š€€€€€ÀÏWº,€­Tš7í,Xºi¸ 7ç×ep¶w¿¯I’ÞËuh;º¬o'I".T¾J®ž/ËÒKǽú™ÛÆk{§üêçXÙÌöë,+ÁŽy}æ"çk*Mc:FÅ%RÆH‡¢hpœ*Ï0mÃ6Þ’³·¯_=¯ëú—ííŒÁÕù¾.›Q«uø3puÈn<™C¢ƒ $³ÕÚ}gƒ`~éól¾Æã£Kkû]2$ñqI’›Í’k4òQ¢ê¾3ÏŒ±Ïš¦CËÃ4*·ß)K¼n>|¿ Ûö`Y$³@s¶í!æˆã êõÞµóÅÄÖ,ƒãñ'.Û:†íÒ2YVùµl¯<ÏP­6yé[c¦éò1.Š®ë£( ®=aÇ ‚æó<¯†¢(8 Ã<¯×õáûm>fëõ‚Zí–ˆã ʲÀz½„,+ð¼tݼôýP94Íà¤AQÞºƒY–G‰™§VkŽãÓyIs(І†a M‰°=fð¼:>*•âxð IÒ%W«åòyžq’U­6!Ë2 Âïwøº aÏ@Ôë=ȲŒõzUÕ(QZ@×­K„i8|… ˜¡Û=¤¥V4M§DŠhKºÝCH’Œ<Ïáº5Ôj$IYVǤì,ŠÖ¨Õ:|.dYÁÎÎSl6K„á ŽS¥Úœ:Ž¿¤ï½€m{ˆ¢56›¦Ó3hš ˜ãôô+:ží¿CAø–¸¯‘ËU åf³¢V¦ò¥`ùjà©iÆ¥Àš9ål …¯Ëd§Ò¿1¨ÞuxrŸ–+]Ÿm!\ùRÉR’„ˆ¢ËÄè­‹Ð[—¬Ífq)°4 û’Hù*QUíR)ÊuÁ÷öq4MçÁuÌ`Yî¥c³ñ¹Î-‹Ùµ²ó°9da£Ñ‡mW`Y.V«é¥ñ$¤Hæ%.l^·ÇÌ4~#I¢KcÁ‚ñ«÷¹=Îóù¾ß¡Aúºn¾Sru•˜¦ÃIkžgÐuƒ®3õ’‡ËD·ðVc (*_ƒìZHÙXri Xyàz½Äf³B‡œ\y^èÙl„ ˜# ž³,—iºP…ÿ»ÕÚ$‘LáÛÆ‚Òémð5b²,£dĆãTø¸–%É€°ëJ¬VSÁIqb+I‚`I’!Ë2¯«ªÓt¦ ò-©ªÂ¶«t¬I 9ž„8áûmÌç£KÁ8ÓÇôz1› áº>ý)­:;û†ac³YB’$NRTÕÀjEÜ´H†EE¯áû,—h·÷ù†€mWà8UœŸ¿Äl6äóU­¶i [†óó—ÐuQ´Fžgˆã |¿Z­ƒõzz½ËíŠUU§%_d3£Ñè£Vë@QTDцa£ÑèÃ0ôû`YZ­]ø~ ‡‡¿ $›[–Ìfç÷Öµ ‚" pOÜ×ÈåÝÚþ uº)èÿÃKeZlÇ5Mcèºu)peçÐu¶]y§Ä&McÁüëdÁ,;þÕŸ³àéº{e™kØ1dYã2lך—í”+ŠÊ«m»ØÍfq£%ËR~ýis2e6$IâD!Mc¨ªþŽMnÈ2âĬ\ ÃâY,ßoÓ|2öE‘ócê:q6Úl–°,“É)Ø·Bà4©UoAϙԱL ³±]¯[Z…·s1Ÿ`6·«ë„]óÛr¤œg8§BK¬ ^vÅŽËvºÙý±2£ÕjúŽÅ±,+˜NÏPì£h$‰(¨ñ{f„F’$Z^&óµÀÎíº5:O3žh·÷µ,+X,Æ—1ê:)’e‹Åyž#ÏSJœ$†…J¥Awö‰Àœ”IÉÈó yžrÂEkž!åZ9ïw¢ª:Úí=´Û{H’®ëÓ5š ÕÚ…¦é|]ø~› ѱL’iš`6;§×°@­!IºÝChšŽ0\q‘9±†…^ïÒ4ãTQ­6±ZM†F£7èvyY!ɸµBto³R«ÕY– Ïs„a€ ˜Qa"ŠÔj]äyŠ¢((Q×ùœ©ª†4çŠ"G–%Ðu““EQ±\Žáû®Ãêvù4dYŒù|E!kI’dÌfCJØ5,—‚9 Äi×±ñøˆjoRø~›—–e²,±\NAø¡ÁvYÉv¯ê¶I &”¦—‚WF$’$Âj5å/+/²,žW£eVä×:˰]qF†§Ëòx© P¾(³lëíÀޱmU›eÉ%ëØ("N\Õj‹ßcQä0 Q¼cƒÊ²Ìv» Šh(,îÖµÝÄŽé+®Ãj5¥ŽIø˜ê[â¥\*2 ‹ï³Ìªj×6•s]ªªÑ`””è°a¢](øØ°r&¦á`ãGìc-$IÌÉ™$‘i2—l»‚ÓÓ¯¹p[’$êt&óŒ ›ÓNç¦éð1©T|¼Ø5EÎw±ëõÞÖ¶„Ùlˆfs‡g±V«)·‰-Šœé…‘òl #Éd‡ž”L½ÍÒIü}q¼¡Y¥ŽSA½Þ夒|¾B­|ȲÊíh«Õ¿ßï ( ˜¦ I’9IHÓ†a!ŽCž‘$.Q%‹1µÕ%d.I"躉ÅbÌKÏXI[;a ÙÜAÌP–§ŠJ¥££ÏaÛØv¾ßF½ÞEšÆ_!ŽCt:Øl–|L$‰dÁˆö¥…FcÀ3¨Ì Z­EŽZ­Ë³3$aÁ¶«¨Õ:pÝêõ.¿6·µZ‡—o±òÊ0 ¸Er«µƒ§°,"Î?;{Á ëú˜ÍÎéúù} ‡¯P9–Ë vw? „®†ÍfE]ºd®Ë2M—~h6wE ‡¯yvF×M$Iˆ‹‹hšŽóóW(ŠÍæàÞߣ‚ |`n­Ñhô·ÄÝ—»6_%5E‘ónM3.¶,˜Èn}¥ÒÄfC·-—¼ÞܶÝKý˜ð–Õǯ×K¾“MìDËK§aØ(ËŽSÅf³|'ëAvÈßÚØ¦ir©,m³YÂóê<Èd;Ýš¦Ã²<¸®ÛöxÀEš¿eïXúÆqˆ²,.'øW*õK×dÛ /—œêº‰¢Èivê­kT³¹]7¹¾ Ï3T* ~_†A„ÄÕêåþëõ‚ –Aa¥pıi[ø\ ×{€$ ¡ª:/S“$ Ëå„7%$ÙišpM#GÆeYRâU…m{œx^ꊢ]–×jÌ’NßU.¦žLN¹‹—®›ètöQÏb¹®O›4ˆÞ…ã¡3OF€]×G’„|Wœ­%Ç©`±C×ML§çX.'tÞ«˜NÏéz7y¦¡(r* 6ø¸0M;Y‡Š"G¥B„抢²\T* x^ƒÁc*dÏié– M31™œb>Q[]Ò,p³Yb6Â0lt»‡Ðuyžb³YpÒÁ²Œ èºÁË¿|¿ ðà8þ¥æˆ’DœÄLÓÁdrJ¿&0M›’–å"ŠÖX,.EV«)Ÿë¼LÐ4I9ãz½ÀùùK<|økX)-|óæ3L§çôÙŸ¢( Ôë]ìî~M3P©4x žmW±»û×™R¾õzƒÁx^ yN·|¿…0\¡ÕÚAžg¸¸8†ªj0 ¶]A³¹ƒ,K±»û”o®dYŒÍfõzUÕðàÁ/Ñë= Ù1;;O¸hž­¡AøÙ—nìîÍÀjÄÙß,ð%šß–æ°`“•Ÿ%ÿ’`Œ•e¬×Kš=xÛa[Q4ŒÇG—¬1°rf˪(*µ]Ò\ïq dƒìà“²š’î–Fœ”‘ž: ‰. @ôzÔ+îKdWw;‹¢ë&\·Æ³’$ñ2M{K.)bý&Hô¶HY’ëÛî¢ÎÜ˶ËMX„=ÉeX¯—´´ŽÌÏb1†$ÉX­&ð¼:–Ë ½G²óÏæÌ÷ÛØlV¼«,Kt:—œÜXÙѶX{;KÁ²R­Ö¢›ˆ¢5ÍJÀ< W‚)ÏtEÁ‰g¥Ò@­áºµK„—ØÞV.Y¢Ã0x©¹Ë(ŠŒjR4}˜¦‹Áà1²,,«HÓxëÜ9Úí=„ášfÒ¬ƒÇÉt’»`Ëò ( ×2ŒÇGÔ¸ÀEÌQ¯÷¸¸œ­QšÆÐ4«Õ Æ€b™Ûë=ÄdrJ窊²,¨u¯BIMµZ‡¯1– de„L“Ez¼¬Z<GH±„³³0MšfRò8¡f >²ž–Ë â8„e¹X,ÆToÂô9¤LP–eø~«Õ –å! Wôï€?‡„xÖ Ë F£×\Óh IoI¹§§_Ó²¼:¤åHÓˆn˜”°mq¼áŽalý°5jÛ®3RÕj‹—#꺉,KQ«u0¡Ù ®¿iµöÐlî²\Þƒ…¬%dYÅÁÁs4›Dgt_›uAPþ (ËòX,.x ºõ.¨ªŽ ˜ñ`›í3‡¥4áº>–Ë ?“ë‚׌¼0°~×õ±Ù,Ðjíò.ݬükÛ•‹""Еi`Ò ]âw’D\ïÀ–Y D§,‹ùu’’"“ïÄ:Nq^ú›¦‹ÙlÈ_÷¼šÍÚ—¡Äz½„mW”t\ >–„dùt$ºÃÃq|îx”$/›óý6¿?FNH}~ÊS–Ò4Æz=§Á(ѯ°ò5"ÂÖ°^ÏyÉŽë’Œë)1Ÿh™‘J¥Nµ¤ÇF³9€ëÖ±^/a/Ïcµú–åR}Àíö>ÎÏ_À¶=\\Óq·¸îˆh% Úƒ¢Š4ÇضÇwúƒ`†( †§ŠÉäQ@Q4:ç$HMÓµZ–åÑÝv Q´AQÃgg/xsAbé«B×-èºÅ3o̹̲\¬× îø¥i:·Ï•e‰“õzF£ÏkÀ0,´Ûûð¼Â0@¥Ò€e¹^ó~–)É2¢ :>þ‹Å>ÿü¿À4l6+¬×sT* hšÁ×I­Ö¦ ×X¯ÈóìR?–ùü­®Â0Jb%èºÅŸ‰åò‚f§RÁŒÚôZt#Â¥NhšÍ~nßoòIcÃZ­Çƒÿv{º[µ`&âxC7ºˆã âxC³°ʲ€i:(ËQ´¡¿M®_óý6LÓÅpøºn@–UT«„d AQ4¬Väy†Fcpi3@ÓLÌç#èºÇ©" Ç÷Ekx^›>1@8=ýŠo2|üñÀj5…,+<óG\Ø ®A³í /ñlµvÑéì ‚" ð/•9aeWÌ-‡éHH€¨ÓìCFýþ#Úû á®ãø¼Ô§ÑèÓ~%jµNTUÃtzÆËÄ‹ ZîbpBA‚&LvÇ!6›Â0@«µY–éN·Á ³m·÷9ÉØÖd°”ôj°sX–˃`ÒgÁçY¤ÕjŠÙìIa¹œðÎð†a#I"䨶w©WD³9àg¬Éi€—ó]{R{ߤé4¸n –å\j`H²,$˜^sשVk‡’·Œ—ŸmÏU8:úŒ“ÖpÎóêØlH­?kn7½êJ•q‹hv\F„âxÛðù~eY"ËbDÑyžS+ÝËå,Ë…aØ<ÛÁô&ŽSAž§¤årÊËüf³!TÕÀ|>ÂÅÅ1µ³ui#¾‡PëõËå׆ Ót°»ûªªó`šõNi4ú\A²9'ÃÎÏ_B’d^NF4%^3t:ûÜÖ—‘Û® ×;„i:¨Õ:4ãEÈi«µ»eQ¥z(Ÿº§mø˜ÏÇü9 c0xŒ$‰Ç!NO¿á:f¡K2#NÒLÓA§sÀm‰Ù:‚f³!êõjµÊØßΛ²µÍ¬}Ùø“ñœ" ×|¼ëõ.Š"£%*vvžnmØlZNfb¹œÐlÛ&vÌ„TFÔ¹«Ç»ÙÏfC8Nãñ‚`†Z­ÃÊØ± ±0¨ yŽÓ4A–%˜Nϸ3ëë²·÷ a¸B’Dh6T#3F§sI’0<æY!&·mÒc§Vë ŠÖ\‡D„õK¬×Khš‰çÏÿ¶]Áx|t­ù„ (?Ñ`]¢‰…iI’ÑéPkR&Lw Ë ‚€”Y–ÇŠH™SVkºn!оÛ=› 3ºK©ñ†ml¹h±l ëåÀ´LKBJO"dYÆ{50²ÂCÒܮƛ.2W#F¤ˆHŸX¡2+\B Hù̶}-yA ʼüŠ™ 0§-Ï«s] ±í%å.õz—7}›ÍΩ¾&âµ÷¬AëãÀˆ±;^òŒ ;';6ËZɲ̵Ä.5m“º^ï¡(r¤iŒÕjʯ‘\s® å IDAT@›,*ܽ+æX¯Ô+àUÕ3˜&éÌ^¯÷Ðh ày5ª ¿¾0\ñëcD/ËRꬤr‡ªF£ÏÇé[öö>„¢hÐ4E‘áÕ«?#I"ôû¨u1ÑN°õ±ZÍ0<¡ÝÇ#Zâ¦ó¬Î“'¿ ¡ÝÞƒi:|Ó4¡;õ&‚`†fsýþ#înV–%4Í„ãTÑhô1½í ÏÊ‹ò<ÛÒr\ðLU»½Ç5 ÇØl–ÐuqB× „aEQÐhôi‰–Eø6%Õ%Ý Ðx0Í\ÂH9Æ sQ”<º˜Ï‡ˆ¢5ï÷‘çdÞÙ{Èú"óÈ2ËåÖ뢡i4v¸h¾,Kø>éeB²1ªÕ&EÅîîÜ ˜d‰®¨RiÂqª˜Ï‡tîIÙßdrÆõ'a (rÁ³±&¾ŒÿüääK®³j·÷ ª'Æ_~ùDцfWÌf#nGLLº|²2Ç$!öÃÑLc@u?]o:âx Ëry™*»ïí,¬ (ß3njÎ& ÀÀlM‰%jÃp`Y.f³s8ŽO«:¦Ó3Þgä$ã–ëÈ0›S±jÆûx˜¦Ã…Ú$0b_Êóªªñ®ÜWí ëõIb0xÌË:˜ã±$NyÿV&Bú3]qñÑ©8·àÂxÓ´Ñnï£,IçkËrÑë=L§çP ’$SâDv§ƒ`ϫњ~¾ßBµÚ¢¥M¤Ïk`IJÕšÔ–µKûÍ(¼Ñm“Ý^ÃpxÃÀù|„NgÎ'o šf Û}€<'‚`ÛöèN±BÀ2 Ј^†‰º‰¹€UÕ ë&6›ïáyuڰؼîî>ƒ®[è÷Áót‡]ã„X“ów»‡\Ð^«u i·¹eÄ«ÑèÑr@2ÿ•Jƒ’BÒ4âÿgY/&LgÍ ù)EkJøbÚÜ/D¯÷yžÁ÷ÛP…Þ£…õzJ¥Éµ%yžÂukÜyŠˆÂÞÿBU5œ½à$˜YA{^Ýîá¥>)E‘CUuŒÇǘÏGØl–h·°³ó”ÚÜ:Ô¡-ÄtzIRç:4›;eçç/áûmN¦ßj[H÷öù|ÄKÄZ­]T* Ôjmìï?çÂû½½g”L[˜NÏP­¶±^ÏÑíb³Y Ý>Àx|Ìí”I6cq¼ÆÙÙ T*uª iÇzbÝÜnïÑ’½*ÏjÖë]4›;p®[£ï±°¿ÿûûA×-šíT (*>üðo†ºÝœž~J¥NgŽSã¥[õzýþcüæ7ÿ<¯Ž““¯°ZÍxÙ×tz†~ÿ1u=Sà8>t*ÌfçØßÿšÔÐí> ›šÍ>×g…!)û裿GµÚ¤ÏÁÉ kfÙjíÒò@ÿçOP¶ƒÄ›þ}×gî{Œ»þ×ù®ë8|Ók·]ÛÕîÅWÿ}ÛuÜv¯7ÿê{î3¶÷¹¯û\÷]ãuÓ±®;Þ}^»ëºßg-Ý6W7Íëmß¶oË›Æë¦k¼mnn›£ÛÖÅ}Ÿ·»ž¡›Æÿ®ù¹î>îz–îº÷»æñ¾sv×|—ïÁ÷ù.¤ûûÓ°Úl]7ÇâxÃ2;UË"Ö±’$c:=ãE…ãTx¹R¿ÿˆfT¸nÎÚí=®õ¨×{¼ïð’NÚ,dâ{â(õ¶?¹^²«Ùlî`8| Ç©ÐÝqÒ‹¤Ù Û}@Ý¡ ¾kÇ!'Zl‡›Øó¶¸v:=Ãpø Š¢ñ¬ ) jòL ’“]Õn÷'^Ó)sŸ½ ŽL*/3be@–Eô’$áììnÇˬ‹W«)Ò4ÁÅÅ RëH’ÇÇ_b¹¼àçe†ù|Û&Ö¼DϲÂj5¥bþsÔj4›;(ËýþCž!Ñu'¨TšX­f±Ù¬¦ ÖëV«)Z­]œœ|Imrœœ|É]”‹1¦Ó3L&§$†Í-²Žííö¢hÃ{Õ0‚aÛ ÃF¯÷€koHé\ÈK·*•$ èõÐNêsx^õzf Æ4 Õåó©( ‚`†$!ät8|8±^ÏQ9æó!æóÍÚìó±$å‡D÷Ç!vvžÒ B€Ä3EŒO&'¨VÛ˜LN©kVëõ«Õ“É ÃÆÑÑg8:úÝî!b$±^/Ðï?‚®h·÷¸ž‰ÙI“ )?"K ÓéÂpÅãû-ڿâï%ÂúVk«ÕÇÇ_ (rìì<áz6öš¦coïßl`eŽ“ÉúýG¼ä϶+˜NOáy ,—X­¦Ðu‹gãH©å./£dÆšfÀu}Ú¼’èŸÎÏ_@×ICDÏ«#Ïsìï?§k-ææšfàââ’œ}C–’Æ’Ë%±8~òäwÔ5Žô²!Ï£C3z}}ð°ZMøùÈHÎ×()ó0½F¿ÿÃá+hiI´VÄ4ãøø Ôë]Ôj{eQ~RåjÅ:ŽÞöï»>sßcÜõÿ»Îwõ\·½vÛµmw/¾ú¾»îû¶{½éøWßsŸ±½Ï}Ýçºï¯›ŽuÝñîóÚ]×}Ÿk¹mÌ®ëǿéïÛÖàMcù¾×xÛÜÜ6G·­‹û>ow=C7Íßm×wÓ}Üõ,ÝuïwÍã}çì®ù¾ïŸÛÖÓû|wm¿.ðÝ@ˆB’$Ãq|êºA³$:oT”\¨íûm\\Óã–¸¤ôäââ˜[$à>,+´çÈšî^û\ܞ礼* hšÎvßoÁq|´Û{Üah³YQ!‹î¼Öi©†ŠÕj†4MhC¹Öëí—QãV®¤‰_Ï«ñ®æa¸â æt$Ë2&“Sœž~ÍÉ‘ëÖhIЀfâKvÁI¡ÕÚE¿ÿÍæNO¿¦Vµ.–Ë /¡3 | YVhS×ê0‘8Ñl²6Ò‘ìh³o@¢bsB0d™4$Y2‹÷!bu"âöý6ž£ÕÚEšF¼·L¯)²p~þŠ¿Î4JµZ’$CQˆøš¹’±sI’ ÛvÑéröW_ý¿¨×{¼Ûýtz†ãã/ÀloÃp¢(±Ù,`š.²,E½ÞC«µ‹ù|ˆ££Ïa6\×G½ÞCèt°XŒaÛZV×ÃxüE‘c:=C³¹ÃËYo‘4MSîÀeš$ ®THPNܰHG¶»ÎʯÆãcDQ€Ç‹n÷4ͤäÞ€ç5àû-.Zg=ÈZ%6ÄIb<>B«µ‹óó—´¼ŽX“òHÇÇ_ ÏSL§gtø~›7b<9ùŠ:k‘ìËŠµZ»Ü´€i6›%>ü5µqö¹Céq²ÁÁÁsª‡Òùü!uÕj‹7UdÒM~C‰ù9ʲÄtzÆ5WãñïFc€F£Ï3CQPMT aHJ×ëF£7ü{]–U ‡/Ñí>ÀãÇ¿ÅþþsžÑ€Ï>û=f³sÚUžd]IV‰_°,™m{ToÒ¬êûûÂqªh6w†ž>ý]G+Úô²D’DØßÿI#ÏSèºõó"(W¨í×nú÷]Ÿ¹ï1îúÿ]ç»înzí¶k»:Wÿ}ÛuÜv¯7ÿê{î3¶÷¹¯û\÷]ãuÓ±îZ+÷=þÕë¾ÏµÜ6f×áÕãßô÷mkð¦±|ßk¼mnn›£ÛÖÅ}Ÿ·»ž¡›æï¶ë»é>îz–îº÷»æñ¾sv×|ß÷Ïmëé}¾»¶_D廃†aáõë¿Ð GÎõ dG7C¥ÒÄ|>ÂÞÞÈóƒÁH’LK|º\7Av!MZZ•Â0,L&§|g˜ÍɼTy A¬I]˜&)‹"âø% %( Éò}NBšâxƒåòFŸë òÏS¾SM‚äÝî!ªÕ&êõ>>ü5d™ômQÚ‡[åy ªÉ©v(G»½ÏEëÌÒx½&kF×-ZÆGúòNáµ&v¼D÷B2xQ´ëÖ¸€¿ÕÚE–%œ8†…áðúýGxðà—˜ÍαXŒP¤\Ë÷;ÜÉÌ0lìì|ÀI=s“2 ‹Å%BÞX±,Á©Z­³:f½9HIiÄ÷æÍgßФK9Ñ‘à^×-”eÛ® Zmr›dE!çó‚`† ˜ãääKÄqÛöxO˜~ÿêõµ«ÇT«m<{öoQ«uh·w›¦Íf…££/ i:ÏT°’¼,K±ZMq~þëõ‚èA0ç½ÂpÍ3ÑìNºnp›â0 àº58N•v¶¯Q÷:‹Î£ ×­ñ¾-Œ¤Ú¶ÇÝØÞjtî–•¦1NO¿†mW°³ó„f'«‚ul›Sƒ 5&H0žÃ4Ìç#žÕëõÐÞ3>/»ÛÝ}†fs€<ÏÐë=€¢h8:úŒ:e=A½N2#l\6’!®}=®#vÙ &“Sª×Òá85ôûÑn¿µòÍó ’$¡RiP@EQpÃVB¶ZMyGœÄ+ ùûÕ«?ãàà#Jêk¨Õ:Ô4¢ÏŸãõzI"YQæÊÇ, m‡”|¶Û{øøã f ?r‚ò>;¨·iîóúmuâ·Õðß§fý>uü÷9ÆMï¿«–ü>÷}ÝñîªU_ÝÂ]÷zA½ï<^w7½vŸ5q×ñë³wíuÇ_ÝÄucùm®ñ¶¹¹kŽî3îï³)q×¼Ügíß6.ï«Ë¸ï³pÓ³ùmæû>ßa·é¾íwÕv©šÀû#McœŸ¿D­Ö¡¿ã ZãMƵÕÚå¥Iÿ†‹¢‹16›ÎξÁùùK¤iÇ©ðÆz²¬ðN϶ía<>B§s€¢È!Ë2 þ#†ÅEÅŒ¤0RAì}/Ðë=Àz=Ç`ðE‘aoïC^ž$Ë ×Ïø~ãñ wèÒ4iš ÙÜE»½‡Åb Y–©sM“å k$N,Ø:KÓ£Ñ<{öï°ZÍÐnïQƒÄ»Í—%èýØÔ.÷žW‡ãTáy5ض]7ÑjírG¦Éä”÷Žñ¼Š"§6ÀH'v™®sÒÅ0lœ}˜Íˆ`?Ž×<˜'Bð9¢hÑè Íø\Èvö5ÎÏ_àåË?¡ÕÚÁhôšf_F´\Îâ¶Ð¬ó8Óì¸n ªªm¹%ÔHŒßññ0MŠBœ®6›%×;„!ÉTÔë]ìî~€Ùlˆ~‰v{ªª£Vë¢ß'ÂvÒƒ„dZêõ&“SœŸ¿DY–´§Ì)í}ÑÃîîèõÀu}NzF£7Øl–^ãõëO±·÷ ýþ#œŸ¿„ªª˜Í†ÜšdìÈü&IˆF£YV©VdN‰ÇŠï¤w»‡˜ÏG´¿éÙ±\^À0,ê F²,IB–¾NUUC½Þ…ï·1›Ñ Z¢blÌŸ}ƒVk7>dg„ <Ÿù؆…~ÿ1â8¤º«>oQ´A¥ÒDµÚħŸþgèºÁõ;yžÁójˆ¢5͆ x÷õ$!ÎU¤›ü¢ˆ”¾—¶’Ûm?~ü[ºiáA–¸n–„’ž'yž!IB$IßosënbA2—¤doE‘SòKÎÑë=äÝI¹ !š¦Ã¶«ôzt:ûÔð@Åéé×ètaÛ?×'ŸüGÌfC4Z]^šiÛœŸ¿àÎfŽSE½×Àƒ‡¿P¢»×GY–øäïÿ~ÛÇÁ£¦1/­¼ êO­ÄëjppÝ/Ñ›^¿ú3öe¹ý–&¿z¾«Ç¼í×ï>ǼíýW_g?Û~ß]÷}Ýñ®þìêñ¯ ¸îºïÛîõj€wÛu_7æWïáê5]wî»Æú¾×}ÓõßöÙëæê¦y½íïÛÖàukà¾csI¹é:ïzÞÞ'ËzÓ±o[C·ËmÏÒ]ëó¶gáºãßµžî3Îw­Û›ÖÓ·ù®øî ÝÓ H’B­< $ILûæŠõzóùˆ7˜cÍÚ,˃ªêh6TÚE;£Á!!ŽSÁz½äRÕjaðÒ1RÖdór4 Ë2šÍÞI}6¢Ñèc<>‚¦™˜Í†<0* ÒÇò\\Ìéî+Éqy“7Ñk6wprò%šÍ]Äñºn@’@Ë?úxýúSt»°Ù,P–&“3H’ŒóóètöéýîÀ²\}Î3O›Í’ÛófY‚Áà1–Ë ~ÅbDÝ¿$N^ƒÇ˜ÏG´~§§_ñ±Ì²ýþCìí}HIÄÎF£7¨×{܉Ø=φwªêõ¢Û=Äz=çîOÍæ€H¯^ý­ÖŽ¿@Y–¨×»Ã&“3x^–£%(Š ¯_Ч4Hw¸•/Ëõ»»À0lŒÇÇ ÓlÑ1¥iBݲ–hµvày5¤i‚NgŸéic¹œ Û=D³¹ƒO?ýÏ ãððPUggßðÃákìì<Åpø ½ÞCjPá¥>Y6C·{ÈKÌX/f›e!ÍM)@UuL§CÞ¬¯, ŒF¯qpð ,—(Ë}BÉ—ÁK˲@µÚÆf³D– jR"–a¹œÐl)W#Ð-n×kÛUl6+j¬ðŒÌ›7¦™t\I™PòÒ1æ¶Çô'iÓïð’©<ÏððᯱZMáû,ÄÝNÓ |üñ?ðÒ¦ ˜coï·¸fš/þÈËêjµ‚`ŽNGÇ«W‚¢}G.áºužÝ"çjö=T* Ìf#EËr‘$ï±ÃtXé$Iz½‡4ó¶‡,Ëhv'ƒiºðý6š­4CÃèìÎ&“Sì<¥eŽÄ–zÿÁSÄQŒ4N‘¦ÎO_ãÙ'¿õÏýo°YnPäò,GY”p|] ,Küî¿ù;„AÝÔÑ9èÀõ]t;ø7ê¿ýy”»Ë}èûԡߥoxŸ ë}ŽyÛûßG‡rŸ1¹ésßfL¿Ë}½Ï9ï3ïsýïs¼Û®ÿ¯qü÷ÑMÜ¥·ø6ãuŸã½ï¸|Ûà÷Ûû»êP¾Í³ßkºÏ|—gùÛŒ» '·ä÷ãT‘¦„0íqá!.A›Í íöùjš‰³³oÐhì W8<üµö͸êäÑRÒt±R©#ŠÔj]$Ékø~‡‹îeYEQD´ìgCAêX,ÆÔ’¸ä.U¶í¡Zmñ¦,<0 {{RW®9ªÕ6–Ë1TUCQ‚-9Z¡Zm"McêB¦qÇ,Ö]úøø íö>-)™ñ‹ÇÇ_ ×{È{.¤™!¯‘$>üðoÇ!ul2i9ÍxKX.ñpBn±X¯|š‰ýIY ø4MçÆ¬GCÌÑï?Âf³¢Ù&b§›e oüGúZ~̪¶ß„/¾ø²,…ï·P«uÇ!×Ý0§16.ÄžµGƒ{öI©=³ƒáðï3Q©4(9u¨vÃæå8d¿N­vS%Â0ÀÇ¿Âj5Ežgxþüßò\*À&º¤4%åaµZºnð ˜ öûý‡Øl–ðý¦Ó3JtcZBå!IbȲŒZ­Ç5-eYb½^ Mc>šfP‡5ŸgýˆŽaÃ{Ú°¬ÕË—ÿL³b:ûf‚eU¸þ‚­É8¹žJÓtÌç#ø~E‘Ѭ)-\./Ðjíb:=Çr9¡½Rt¾ö%IÂbqÝÝg´¿Š‰7o>C½ÞC³¹ƒÅbLŸ¹ü;N£Ñk<|øk.þg¨THyÛ®àøø t:ûˆã ÍÐøÝs¬¦+ì?ßG³ßDÿqóËgøf4BÍ!]ﮋúâvm¸&éµ´Š"ÄiŠA½Ž0ŽñÇO¿þy‰°ÛHÌÑÑç8<ü˜÷ÊX,.x:žóz|Ót‘ç)‹-•ZA’ˆà•‰ÏY—vâÊD¬\™pµÚâŽ8̵(IB*η¡( µa}Vâ¤ë&V«)*•&íB:Åo6 ^–"Ë šÍ-µ*$!,Ë£ú˜vIO†+š…x…ýýç(Š‚;8±²¶Ùlˆõz$‰áyu,¤„§ÝÞEaÛî¦ÄÔÄ iÍ#ÎfChšÎ] ÎÎ^ààà#DÑš÷`±,7o´mŽãs ×Ýݧ¼¡ÑyäxõêSt»‡‚9vwŸâèè T* ªñ±0™œÀ¶«\oR­¶1Ÿ¹îæÕ«Oy¦c29¡l²Mô ]ÌfCÚ‘=@Y–h4ÜѬVë`4zÍu/ÌéÉ0làwøkÌõm»a_£1Àz½ 6ÃÄ1qx[.§\,mYÂtŸ7 Š2…m×éy=¤iBˉaÂ|N´DL›áy 躅ÅbŒVkŠ¢áÕ«?£ßHõD›!Ë*ÕoDÚ͋ žÅk4úX,.Ðëb8|,KÐlîðùÐ4[*3݃ªjÔ®XÁùù ìï?‡i:h4_¢ÓÙÃ7ßü''_a0xŒ““¯hùx¯8>þÍæŽ¿ %]„èM§gT?uŽn÷êºJšM8ávɤœM§ã>ÃÞÑ‘èº €8нÑò<ÅhôªªrRIúÇGã1±»_s­Ì`ð˜[HŸž~Ã59¤J§†âxݧH‰bµQÃÙÑ4Z] ÏÞ@–eôb6œ¢wÐÅb¼€Su0Ûä½½çˆã êíÆg§XÎæð[u´wz0,õv ¿ú¯~…ÑÑ?yŒá«!öŸï㣃=T, ::‚¡iPe5ÇÁ«ñÏú}<éõ ) вÄb³¤IН¿9ÂþAÿ×ÿö{8U‹‹^þóKúŒ'øÿ‡ÿ^L7`ÛUPޏ½®ë>ƒçÕ0› ¹CÔb1¦;»=*敹èÛ4]ÞÓ£^ïra¼ãTñæÍ_°»KjºYSµ<Ïppð¾ßÆîî\ପ’„Ô‰ ØG·{€årJ5+†…Áà ¾þúa..NQ«µ©v$£]®SžEÐu †ƒãã/©.CáÂÖÅ~<~CKM`:=…ãøX¯ØÛû€ö™q1øz½à&=¯Æ­p‹¢àBè4MhF E¯÷›ÍŠöŒØÁdr €h5úý‡<»Ât çç/¹}oš&PQp2Bš×ËåÍf‰VkŽãó, ´Uîbež>ý†ÃW¨V[\(e LCdY4‹äa>¡Ñè#ÏIG÷F£Ï¾1k6½ Ó+X–‡‹‹cÔj]¬×shšI³'D‡°ZRR«½µŽ–e£ÑkDÑz´|h'€­Ö/e+Š ýþc(ŠŠÙlÄ3)–åâøø 4}ZRØ…mWx–Žt9Á²LÞ´Rir½ )[Za±¸€¢(Üùª,K¸®/¾ø6›%L“¸§}ôÑßs[h&²feZDãdðž qbw÷)f3’a}nX3Áñøˆ û‡ð¼:ö÷Ÿc:=EµÚB¯÷€»®U«MŒÇoÐë=‚,Ë\¿”çÎÏ_ÒËœ:b‘Žê„´»¼gQ­Ö¥ãàPÀõz«ÕÓ)ix˜¦1ööža½^rÛj·RiÙ¸£Þ!–¾íA/¾˜BÓ T5(ªcfAVdÌgcôv÷mT¨šJ{ÛHD⸄ht°\ nÍÅéW§0L ;OvÐÚk¡Þ«£Þ®ar>…åZxº7Àa«…ÿó³Ï°×lâÿøüö¿ý žõûø´îÁÔ4غKÓ`¨*ò<ÇÅl¯N0z= ûþ§ ÄðånÝE­SÃøÍgHƒš IDAT§ètñûÿå÷¨4+xñǨ4*´'’Ê›t ‚" ð€‰Ö™Uï`ð/^ü¶]¥:” V«Õü7-8µÛ{˜Í†0 ›ÿœ ë5)#!ý64® nK¤qÆ‘áûm¤iDšJT*Mt»¸¸8¡Á/¸{qB"‚ñ,K±³óQ´AšF<;Ôhô1žóìŒ$I(Іa"Ž788øŸþ{ÚÁ[¡ú‡)Ò4ÂÁÁG\@º‘wP–%dYÆîîÔIËå®Eq¼æâúÑè5šÍ]šUz…NçÇ\øë8Uê„e`w÷ò<£Ýê=„a€4¸Æã7èv‘ç9w~ò¼€‹ÅÅ–0Úà eY…®›Ôˆà¾OJ}6Òõ¼Ó9àšÒHOÇ7ßüz½¼á ëÁb6òýhšÁ)z^gÚí=¬V3DÑE‘ÃukœàÇÇØ;ø_ùGT* ª/«¢Ria³!dŠ™T˜¶)”°ZMQšÝ´‰×w¡h PÑ:Âã>Âf¹Á³_}§ê K3¬kH²Ó51¨À«{p3õ^¿ü¯‰Åx_þíGh¸.ÃÀþüº½&þîÉüß_~‰gý>\Ã@E.—p ži"/ È’„u#M3¼8úò«Y€ùxŽW~…ÿǵ0|5D½å­K¸ ± T5¨ºŠä4Áø ªJÊÏÞ¼!Ïà¹@B…Ȳ“É × ‚" ð€4Ü¡»ØKîVDHƶ]A·{MÓé.kYF2LBÄñ-˨ÕìV«Õj„H’”‹Ý‰-oNË Öë9ï‚-I2%.%‚`FKsÖøÓŸþö÷?Äx|„ÃÃ_P‡£sZÖÒÆr9A;á$‰3Þ‚9rM§§ØÝý€­i@Hú¬ýÉÉ—8<üq¼y›”Ä$H’˜7…ó¼:µ3v Ë2Þ¼ù ƒÁcÁ QPWªƒÁcnÙìû\\Ãóê¨TP’‘b½*æó1u—j ËR^6S«uyƒºÍf‰0\£ßŒ( x/²Óoa½¾à$W«vvžðr«$‰0™œ ÙÜ¡ú’1i6wp~þŽãó!µZŠ¢àèèsÞg„4»cN[&$I¢}?˜¦ƒÕjʳ)P«u±Ù,¨Þ(¢Ú˜dYÆ£GŸÐÞ# Æã7PR¥(*Ò4¡%p‚`N縋¯¿þGj7œCÓtê|µKû.5.ð¨Ë– ×­ñæÝ¿„¦éÔr·Š‹‹c¤iÌÅپߡã®áää+ôzxéžëú‚ׄ°Ì𦙍V[H’¦ióµçº>ªÕ&' ¦é"ЬV3G³ÝÇzµ$vÁiŽÁà‚`ŽÃÇb2$n¶ã"Mž]Q5E®Ã0dYŒÕl‰½obÔ:5$Q‚xヿù/þù>ú÷¡Ñ­Ã·mÄiŠßâÏÇ$K¨«**–…(Mñ¬ßÇÿþ§?ái¯Y’fò,‡¦(.X,ü§ÑŸqöÍN¿9ÅÁG8yŽp¢Ò¨àÍgo`y&gÄ$ ··¿åãý/ÿ3š­Ò$áã4ž‘>,óùÕj‹ôØ™-i©å‚7m=?‰z½³³oÐíB×MŒÇG˜Ï‡p]“É© (?$HiÍÔj$@[¯¨×{´™qšLˆ½+ëcáûm¸Íçc¨ªY–Q­2²ÆË½H…‡‚æóÞ/Ñíðòr. ŽSÅññç¨×ûèvIß…²,©Å0éxî8UDÑš›8…‘†umRÇvü«(K@QT ‡¯ iÄÕ‹}ûüœºnцƒ>Ò4á8éÎÞâ.Y–åò¦Š„X-¨#UŠn÷ÇÔ‘HF–e\®(Z¿ÍîEÏkàáÃ_¡ÙÜE0¦í ®Y6‹ 4”e‰““/qpðí Aô9ªªc6rËW|G˜u–g¥>’$Á4]jÜÁùù xÌ·Z{H’Iñ&‚yžaÿ9$‰5¢Ôà85ŒFo`ÛU„aI’¹¾a0xL›*’Þ2L{T¯w L§g¼‰'³¦•e‡‡Ó^&knoœ¦1‚`†Áà1þéŸþw …b ¦941ŒŽ3Àq†ª¹k<îab [.Ï%›­¨EÉóXVI-\¾ïÉŒÊL…֗˹´ßi†qÝ1Á`ˆÑ¨«ÊÖ•¾ƒA“lv‹Jåˆ7o~L2™e±˜1NdEsѨ«MÓ ‡ãª™mݨ¶XL ʉ2´%±<ˆç-h4.©VOåb2—Š—È…B1âq‹‹‹ÏH&Eh¾Ù¼"ŠbYE:{f3GYÊÖm^š¦ÓëÕ†D> ðàšÈ,ÌX.„+™ ŠÉßITÙׯS±ä,È媴۷˜fXYÑ4Í`2ªZæL¾À§Ÿü!ï0:ªVX¨R¢¶9•KÓ®5‰DcdËY&ã ¡Hˆ^£G,Ã*[Ø}›êI•ùtÎjµÂ ›Ä­8Ž"Ÿ]ÝÊò«ß|—7»9A–¿l·ÉÄãTÒin»]vs9±Øƒ’I~ty‰¿ZÑ 8*©\žÝ±˜-°6îØ¥×èáŽ\¬²Eç®CÜŠOÅùü£O0 aa‹¥c4ïîEy2Á Û%€d:Ãr¾dÅ 3d2ì÷¤oA(ãúú[[ÇJñ[«¾"°¦.‹)©TA2TB˜fXò]š”Jû,s\wL¯WWŠÚ`ТXÜSÊìxܧպVt:÷,³‚²™Ílf3›ÙÌ/b\wÌlæ+©>L©VO$µÚ”¬¾ïñå—ß#•ʉĉÅÒ€=ÓéDÁéaAêõêò ºÎ”x$“9`¥n‘-«D2™!IP«‰ÄX¯Ó¹'•Ê †Èdʲ6Yгon^(j´È#ÄÈ1Ðð}ÃÃw¹»{Åb!ìD…®¬ŽÇe Z䘯Œã ýÝq†ÄãÎùü6ºÄq†èºëÚò†Ý!›­Èúد_B:]Ä÷—4›WR‰ªÈºXnJ¥}tϱZùŒFeáZsh ._ÿü[['Ìç.÷÷o¨VÐëÕ•Âãyž¢u¿|ù1éttºÀlæ*fŠ®ë4WªÒx­mS¢A,"¼^,î¡ë†üyd­Ü¬a«¦Vö²|~‡^OÀ:c±´´OŘÍ\²Ù “ÉRiŸÉd(°½^ÃÃw¥Š²¢×«±¿ÿŽ$—g:ReMS…ÂÝn ]7Y|½p2ä> K©4ßd{‘ÙÛîcYE‹º®«hš.íg ≺¡ã-=Uý»®f¾¾~Î{ü ÃÎP$„nè|ë»ÿˆÉh–µ‹fhx d.‰·ô¸sO4¥Ý!n‰Å¶ú Jõ´Š·ð0Lƒãj…‹F“ÿú½wéÙ6/j5¾¶·Ç~ñŒRÖâk{{ü8Ÿå¦Ö$£kãé- SëòÙëÏ9~ÿ˜û³{þÃyß÷É”2ô=̰øLð=Ÿñüœwõkܼ¸áöòL½ Ô, QWþúéÒÖ˜ãöö…*C(•÷™86íFTJ,HÎxL»}Ëöν.Ž3 XÚ¥vŽ®‹¼R·[SÊY*•£Û­Ñï7é÷›$“9µHt»5*•C./¿ K1‰vÂFã’P(Âr¹ K¡iºÌ_åh4.•Íp:u°¬¢·n”Ílf3›ÙÌf~AßQëƒA±¸'ƒµ>ý~LF46­«ÕŠ~¿N.·ÍpØ"›ÝRvˆT*G½~A  &©Tޏºú‚~¿ÉÑÑ{ê0·fGèºðø ;Äã××_R,î‰$xùò‡”Ë$“9:{úý&{{oq~þR©œ¢Ó;ÎHÙ Öê…ÛÏäc†mð¼¹Ü6£QG-åòžçá8}–Ë¥¼ÕïP©sw'ª{3™² ØkÌç9:’.nËm‡D"ËÍÍs>øàá8#º]aäm—`0Œi†éõjˆ)¼í‘H ÇQ.Ðï7X­ .(àpØæàà WW_`Y%Åú˜ÏZ&`ša•Ÿi6¯ÛT*G8Îf󊃃'jÙ¸¹yA6»Åb1%‘ÈÒl^ªELÓtY_ÛD× ‰Œ´i­h·o•ë§e‹9¦âúú9‡‡ïQ«½¡PØeµòÑ4P(ÊííK<ø€Á E¿/˜2½^]ʼm÷ …¢j˜"Šruõï¾ûpœ¡´Í …¢*¾\Î¥RáÆÉçw:R‰Iª€½àq*y"a©Êêù|ªmppð„ù|*«²#œŸF,–$·Èd*Üß¿!ŸßÆqŠ “²²,f Ð {w)”ªhºÆr±d:q‰§ {=¢±†i q†Û¶iß¶Iæ’Œ{cBÑéBšT>…·ð0Ã&»oí2wç̧st]çñÑ.=Ç!‹1÷Díña±Hg¿­ÔœµUÍ÷=Õ†5¶ Cèºm8=ýPÖ– šŒÇ=Õž‰Äû ÛØ¶¦Ry&“Ãa[.Iux^,~ªšt»÷ŒÇ}R©<étžvûŽRiOR»ƒ„BF£.“ɈxÜBÓt ÃT¶¨ÕÊW0=Dz\.Øß›zý‚xÜRÄïh4I«u#Ó¤RyV«Ó©`Ɉ?ÓE×uµ\žž~ˆëж¨5/¦ßoÊ ¹%[°ó¦Ñ¸àðð=:{y{]’¯;ƒ`0,­PqÙà6W€ËåRT/»îÃ0Éf·[ø¾ÇVõ˜û»7*;²®-v][.gš`ÇÊ¸Ž°ò­¦! 2s§„"atCg<2´Èç«XÅ sw.ª¥ÓqæÓ9¡Xˆ•¿bæÎØ>ÝfØ¢éÉL’Ak@é „U´¸~vÍwë—ÄM¿móhk‹»^Ý\޾ã`Ë" 1Ïùäò’D8Œ3›‘K$xsW£’Ïòêåõ‹:©|Šn­‹Ý· EBÌgs:wR¹ƒö×qD~cì̤vdJYì¾M2—d1]`m|Ï#2;ÄRqºÍ&ÑhB)«•iFd)E_©ABÕ‹ Eû´Û·”J{r)•˽^M–@F‘ï{\_?Ã0‚ìî¾…ï/¹»{M0¢Ó¹ãää´Z×Ê^*J!DãàpØ!*b¹|Èd2äîî5š¦spð„VëZ5݉¼!ËΔ½„³Û ¢x Ù躡²uÓ©C¯WS-xÿ¹ÙX¼6³™Ílf3›ù;ÓŒH.¨ú]­D¨øáÃoR¯_‹¥¤G;Ìb1•l‰!Ëå\qÖü‡DBãqaýZWG")–˹¼Ýlªvõͧ Ø x^·{/í"|{ûR-±XŠx<Ílæ0u m,«H¹|¨ˆã½^]zÈs$“9z½:³Ù„jõ”VëšííS©èÒgÞ“v¤&ñ¸E¡°#9-MUœNÈf+ÒŠµ$ŽR(ìǰí>Á øÙ†ÃOž|—ËË/˜Í&ªL`±0ÉZíŒp8F¿ßd±˜±½ýP‚²J÷«Y”6®;&.Èp»ÈUÜ߿ƶªum±H§ º]Qý\*í1÷…¢$“9\wL&SAÓt‰,Ž3  3Ÿ»ê€i&ÇÇ_ãÙ³..žR,î¢ëAúý…®´fYôz 4MS<Ï„xÇÊâ‹JåÃ0‰Ç-–˹Z\×–Å3b±ÝnL¦D*U\’¦’Y…4íö-¹\]×ÙÚ:áââsööޢѸIJJ »ÜܼÀ÷—²AK('ëºdwâP*íÓíÖ°¬±˜8TÇ’qZÝЩßÜ éÑDMÓ9|ôùT(©\Šæuƒl%Ër¾Ä*Zdú9R…swN"“`ëd‹­ã-fî oáae’¼yzÁ?þ'ÿ€|2IP×¹ívùèÏ¿àŸüê/ñ¿ž×È%“Ì ÚÃ+ Ñèâ¯V<ýásìMÐ ’.¦¹}yK0dîα6µ«[aOÜå 3gFç®Cû®…¦ëÌgSIƒr}ù‚H$ÎîÑ Ï>ûsßÁ9t:wâµmåùñGL0¢XÜSõÛ¢rü„zý‚vûÏ[°³óííSîîÞ ë:¦F× ÚíKf³ GGïsqñ9«ÕŠVë†d2‹m÷•2hÒöTêf*•Ã÷}]³ltÝ`<îÉlUÏ[ªæ³µ¥Ôó–d³|ß'кåò!Ó©M(”bµò¹¾~N>¿ë޹¹yÁÉÉ×évë8Žhÿ[,¢²!.E³yM§s'´ãŸëót£ lf3›ÙÌf6ów¤ D"â€%Z»4Î~ì YÁºd2ËF-Ÿ`0„ï{ärUƒƒA“ÉdÌl6áÉ“ï2vTkÎú`&™Ï§êõsÙÊå©¶©ûû7Äã–¢U·ÛפÓE&“†a2´dîD,T··/H§‹˜f˜½½·©ÕÞ¨ ëjµb4êLæ‰DDî PØÆ÷= j´$%^n„ËŲJØvÕJ0HªÕ‹{ -®/•ö¨×/ØÞ>e0hIVŠP-Öªµ KÓt|ßÇó„×]þš´réJé,“¼´¨lcÛù;0Y.—2󳋦i*K"ÔÑ\•Ïosw÷šRifSPà×¶/Ï[âº6†!‚Ø¢5¬%Ÿ‡Ž3 MIåA¨+Åâét››ª‚w>wÉdʸî˜@@g<pCuÿïr9'•ʓɔÛê|´X̸½}Åþþ[Š[âûK‹9Û»'¼yõ …m<Ï#“+ÒjÜ©¶5ß÷ˆFEcS¶PY–ˆÉù‹ç„BQ¶÷yñù§‹{”öKtï»ÄÒ1̉= @8&x$ÞÂà ;C »Fáx˜“¯Ÿ :Gvyõå™r†úEþÏ~ Ï÷¹.ÉH„]^ò­ãc~r}-¬“Ñ(¿û»?à7ó[šÆx6ãÇ?~Nã²4˜MfhºF¿Ù6®G»|öGŸa-®^œóÖ·žpõÅfØÄÙªvÚ÷—8Î+S vÎÞÑC~òɱ¿ÿ„^¯Fe4ê0÷‡c’Ù³¯8(BÝÊHX¼~ý#¹h ºT«'\]}ÉööB¡Ë圛›¤ÓµÐ¯)óÙl™Á …a˜’^¿K­v® úýÛÛ§ŒÇ}¥|®9;™LÇ©ÜO«u#œÂŠ%*® nn^Ëm‰Ä¥uÏ!™ÌªjàX,M8òŠL§Ëå\Õg‹…$¤jÓ]ׯ÷E~ËuQí=÷7 Êf6³™Ílf3¿¨ï¨d2Ëöö©Z:ºÝš"}¯ë`…­k¬À~"T¬IbyLB ·®×kP,j:]àêêK …]¹Tb¡P„Fã’ííS–Ë…<¨šƒaò[Eƽ1‹ùÏ[’̤±câéÎÐ&‹¢:ÁpP²;|±0Íë&ÙJ–h"J·Þeëx »o³Z­Ø>Ýæà­} Mã—ON¸l·™-—|mo‘ë²ô}¾¸½¥˜JqÛíbè:GÅ"ôÉçÄÒ1&£ ¿õ­opÛí2],èÚ6õ›&SgJç®ÃÔ™²œ/ h|Ï' Ò¹ïàŽ'”öËôê=Ù4ƒ€v½.”ÃÀ[.%c'ªìuÂŽXÀ¶{d2f3‡á°Ãöî Íú ¾ïcÛ=@KÀ¨¯”<ß ùü¶\&òø¾G¿ßTí|ëßñš›óúõ' †‹¥øôÓßçë_ÿ¯$?fN2™a4ê‹%Uü§ïY])ápL}¦´Û·Êº‹%Ñ4ƒ@  –¨ÉdD&S¡Ý¾U•ÔÙ¬(.ûŠ'T«Iõ0L2™“ËW’Á …¦éÊŽfÛ&“–Ud8lc¦jrÓ4MYDwwß’|&QU=uqœ!š¦1›M6¯Ílf3›ÙÌf~‘³ÇÇb)®¯‰;ŽQ¯‹Ã¥P%šL§‰DFÖs áš-’ÍVT°z±˜rtôww¯‰Å„µb2cYEuXŠÇÓ4W¤R9™ ÉNä {‰bQ4{­yD¶ÃW‡Ÿh4¡=ëu*•c:uètDå°ç-è÷›¬V>ÕêÝnM›Í+ÂaQ;ë8C ¸-vÉf+ôû-‚AS†z]‰ 77Ï)÷d(WäWÖÊH6[Q5µõú…²¯-s4MÇq†ôûM¾ùÍÿVÕß®­[³ÙDVÕF:Ìf.š¦«`ñtj Һ뎱¬–UFÓ€ÆÝÝkvv&éõê2Ì/29†a’ÏoÓl^+oýé釨öß÷¾ò»†¦‰rn÷žd2§šÚÖÕ»'?# IDATÓ©­n¤}ÉÎÎ#UÓ*”¤‚$ÔÇÐua¡[³g|OØÈÖ4úTF¼–ÖÿþäÑ{8C‡ÜVžÔ4Míæ+—$šŒ2êŽHfSèºN»Öd÷tŸ©3eçá†i`†MÎ?;ç­ï¼E@ нïòÎwßáÁáÛ™ ?xñŠï<:åºÛeáyœ”Jô‡lúœìV–7?~CóªÉd4¡tP¢}Û&•Ka˜FРsß!@€¸çöõ5ÑxœñpH¾R¤ßêa†B̦BÍÓ4|©L$áâÅ+²ù[4¼Ífâ ‹^·.3>AE¶_+‹kÐ)Àr¹PÀÉ»»W½‡a„¨ÕÎH$2L&#e“¡t¡Ìf‚/ssó‚L¦Äj%ls¢âxͽ)Ëü”'ï+uAN¹»{© ©Ýnƒƒ'\\|®^Ÿâu–jh×Ójݰ½}J£qA&SÁ0‚êçÍ~yÅÏY·w-syáñx†ÅbF»}Kµz‚®¹¾þ’d2Ï|îª jÁ p{û’jõ|=‹ ƒP(ÌpØQ…ëŠàrùPÞ×—&±Xšår.ór–ÊÒ »gV}–ÝÜ<—KÁhÔýë}®n,^›ÙÌf6³™Íüí¿£ÖTñRiŸL¦,ÉÓ>íö­< ™Ôëç˜f„x\4r­}ââpä’L ¾ÁùùOˆF“d2t]WËÆú±;†iFpœ‘Hœzý’p8ªèؽ^‡L&c&“•Ê!žçÑl^±½}*íIOÕ¡_׃T«8;û”T*G.WÅ÷—†©Ûkõ&‘ȨÛaMÓÕAq}Û¼¦O‡ÃQJ¥z½:Ùì­Öµ¼ š¤RyyÃ<§ßo`Y%Úí[ ‹­­^½úsr¹*€¼a6dùÀ\‚'E6`:uˆDâÒþµ Ý¾#‘°dÛÕ”ñ¸¯ÂîkI*•§ßoN¤¢ó€`Ð$I°XÌH&³êw, “ÑhRÞ¨ûê5 ÀŒŠÅ= @»}«ÔVtØÝ}L·{Oeë€Àu¬|VÁ—ÞÒ#‘IЩ7 …¢Ä’1ÙËÅ’Ålnè"L1éÜwˆ¥b”öK ÛC’Ù$VÉâèñ>¯>;ãŸþ7ßÅÏqçsb¡—í6óå’···qçsœÙŒ‹V‹öÍoòo~ø1SgÊ;G{<»¾¥yÝÄîÛ ZÒ…4®íb úÍ>swN0Ä[ FI¯ÞÃó–Ìf.¡P˜p4J$!h±6º¡sùæ¹bìˆÊâ¾È}XEl»/‹<*•CâÉ­Æ-77/¨TŽT–a¹œ“Hd‰F<þR©–Uäþþ ™L™»»W*§“ÍnIh ¨ì:èzP-‘HBRÑ ¢ÑàcÛC•©VàûBó¼%OŸþ [Á"Q &Ô_Tu8:zŸÉd¬¬ˆ¢eOTL÷z ªÕ>ûìyûí_‘ {‡ ‡"SÒh\‘HX øÚjÝ(»Ÿe š@€éÔþJ®iˆeI¥òʾ¹^hÖŸ- ãKòùªª•‡ãrqÑÔû\, kX§+™I5€â™¸®M>_e<î«|–¨ÃÖˆÇ-Òé½^d2ËÝÝk©,ïr}ýœh4ñs‡ä7¯Ílf3›ÙÌfþjÉ_‘¯H²\ΙLFD£ úý&ûûocÛ’É áp Ï[ây æó™ 1û²æÕ‡½‰ò· HM3ÈfËÊ®˜N'4›WŠÔ~ròu†ÃÃa‹@@ãðð]K@X­ #„®{ê1l»O±¸'Û{:D"q‚A“L¦¤¸®ëàûCR©‚â`ØÞ„fóšx\0NO?¤Ó¹W!âѨC*•Ã4EP{mëÈf+Øö@Ö‘ÖÛ¤Óãqh4‰®%Ò%ÎËšà!ÙlEܺ­\–lõõµï§A}D:E¯ÝRãL¾ÈÕù v÷·â¢š6$Ô.+S  HX jW7œ¼õ„`(Ȩ;"SÌ1h÷9xçÚYÃw¹úòŠí“=²å,£îˆÓO1Lƒßüð}Ã!÷ý>wÊa¹Ä^.‡¿ZÁjÅ?ÁA©ÈQ¡Àd6ÃÐ4L]gìû,<‘ëâ ~ûüž©3åÍÞ éð¿ýq+Ža<ûèW_\‘ÝÊ2wç,çKêçu ;F½w—”*;‚!2>Ñ$#4 …#8ãÑd”ùtN³vK:-ÚÄ_ÇÅ÷}:¾ïIžMCÙ øÃÿ ©óIb±”ârÔjgäóÛxÞBþÎÎ>åí·EeoDë]ß÷Ñõ&‹Åœh4Îb1Åó<–ËåòƒASZ+gJ՜ϧ2Ð=&“)suõ%íö-KVò3u˜Ï…5,.`Û}M|ý#Þ{ï×¹¾~®Ê) …R©Æº.¬fkEr>ŸòàÁ˜f˜rùvûVÁD5MÃqF²}Î'Š EÑuqTO&s\_?#“©H€©)‹#¿­>Ç`…ã TkÜú=*2;sæs¡®ˆüZ\6ó%”¼†0®­_BQµUæg³ lf3›ÙÌf6ó Ã0yðàjµ3eK ‡×·¸Kâq‹ÕÊ—_삨½XˆºÛNç^²Fòš Å/—sî E˜Nysì ‰6"¡@,e¦Ewévk,— TŸ+›àO~ò¼õÖwD¼&Z$“BY4—ÄbI”oQ(ì²\Š?g{û!µÚ¶-–Q¡x\2›9òõ¾b>Ÿ2›9xÞÓŒ‹¥xóæÇììŸÒnß’É”]2™’Nî(ˤã 1Í0Ó©#›ó&ôû ©Œ -‚Á0/^üÑh’|~›VëšL¦¬J(Öïßuþɲ ²ÙO°"‘8­Öµ|Ÿf1~¹œ«¿#ˆM8£TÚ#K‘HdT+](e6›(5'•ÊÓë5d›WG©¸‰DF-áp\^ÎèòbcE>¿Íl6¡PØa<îašaYìáI5Ö–KÖÏ©Vo2(›ÙÌf6³™Íüí¿£R©<Åâ.£Q—££÷LQ´óŒdxeÍð<]í?ûûïH¦B—ù|Êjå+Zw·[ãøø}Z­©F,tE +e¹œ+»–ï{T*Ç MiËr¨qM_/N°BÓD#P4šd2cAÂá¨:¸˜f„››XV‰dRØ‹© +w(•ö9;û”ÝÝÇFP±CÖ·í³ÙDò&d2"oR(îðêå'”ˇƒ&¹r‘Æí-‹ÅÃR(o±˜/˜Oçêï½þúý‰„…•+°œ/±ÇCf³ ;‡G\Ÿ½a÷è˜^³C8 ‚;§´_âúù5‘x3lb•,jg5Z€‡;Ø›\EÀo_ÞòîwŸ°ÍRµ,þÝï}¯¿ÿãR‰O..xýì’_ûÎ×h‡”R)îû}V*L ¦‹ÎlFs8¤JQï÷q'S.>¿`æˆÜ‰k»hºF àêùÕ£FÝ‹™¬göÈ—ËÔn®°2E&ÎH¶3¡ápœÙÌ‘ê”È㤭<žç1qF@@*HAi·ŠÈV5QØ à•¡P”ZíL¾F|\wL.·…a˜²RZ0wÖjÔ:à½Î‘är[êu6ŸOåaYcµ‚W¯>æôôCz½étžzý‚H$¦éŠ` E$|Ð ‰Çét«e}\g¶L3¬J#+<ø/_~L¥rÈr¹”Y¢8Á`˜^¯Æºêz4ꨥ¾ßoÒnß²·÷˜ù|¦2Á ©Ú¶"Ñr+z½:ÑhJV9_`YÂ&‰Ä%÷¦M0RµÆÕê ½^]±K‹[[Ç ‡âñ4ÃaÇ&UfòŠÒÎ%ªÄ ÃÊ×{ß_ š˜f˜Nç^ª:KY§}È|>e<îÊ,HCNm»OµzÂÝÝk–ËÉd޵cuý~÷}_]Çã>ºn€ãŒ(•öi·o 4‚Á†a`ÛY>± OcÛœ]/vÃa[Õoÿ¼êÉFAÙÌf6³™ÍlæïhB¡ápœX,M£qÉþþÛÊ&¥ë† Îg³®¯ŸÉ†,‡T*¯2k›Õr9—¬¾ïÉ¥Æ Ka¦´$íÇh·o‰ÇÓê¦;™Ì1ÚŒÇ}l»‡ã ¥%KÔžŠJà8ù|MÓ0;ïñÑGÿ}›ÅbÊÖ–¨LÆ »¤Ry:;ŽßW‡”ÅbF¡°«Úµ&“‘¾±\~Fƒ!IyŸËÃ^@Zfò¤ò)N YLô[î˜JåH,|Ï'šŠâ Æý¾ï‘ÊXô±DM×(”qÇ.ZC#+“ÛÊ ‰CÝÎé‘x#hKÇšAÙÇOÆílñý}†®ËÓ›ÆÓ)¦aP±,VþŠˆiRI§ ƒ´®[ŒpÕépsUg1[ð¯ÿåïua2c1_ðïú6Ëå’å|In+‡;v‰&£tk]V«·Wo¨îaG¬V+*UîÏoÄv¶`1[P¯]2:lo?àæâ5Á`{< Õº–PNljĹºú‚@ €eñáÑ£oIÄ£Û½'•Ê+Eœ‹ÈJÕð îL—H$Žç-e®#)­sã¯ðUB$“Y•ñ …¢2^'K Å(—1͈ÌòI&³*'±^jºÝ£Q—Ç¿-í)‹«•/”°Â.«ÕŠZíL© ­Ö5šf`YEîî^«EÚuÛ†A»}Çöö)š¦Óï7e•·É`Ð&™ö®½½Ç,—Kù> ÒíÞ“N‰F’¦`0hJ‹aŽÙÌQmv€²Ýß¿Á4#òy˜&yõêÏå" ›Ý¢Ý¾¡Ñ¸`±˜+°©e奄+s2-âñ4ñ¸P,ÖÐÓn·¦ª´=o)3_Åâçç‚8/Zñæø¾ï{d³õÔõ WWÏ䥊F.Wa0h&T;X0"‘°H1™Ìª Œ`‰ÅmÍúêØöò\Šå:‘°ÔÅÚú×R¤7_)›ÙÌf6³™ÍüíGÀÕ4ƒÖ€N­E:—aØ4ƒÄ’q¬¢ÅÌ1›Ì¨>¨Ž…IåS´®[üÊÿð+„ƒA:í>ûßÀq©Äï}ï~ã—¿Îd>çéÙ%º¡óKÇÇ\I¨àt¹dæÕ—Ÿ‘Lft&c›/¿ü>ï½÷ëØöX,)í9+âñŒ_ÞcÂv¶¾QMg ZàÖ7ãáp\À #ÈååSL3L:]Ríf÷÷o°¬ÃaG–(xT*Gœý˜L¦,Ûà4eóë÷[Ìf˜9£Ri_5<½yó)[[ÇŒÇ=2™2š¦1ŸéõjxžG©´‡mÈç·{ŒF"‘†aÒë5ˆF…RòæÍñ}››ƒ"Ó"x!4M(8ûûo«à|(ÓkôuGÄÓqóîXÔìN[؆âQ–ó%Ž=f0hrpügä é­æ­Ê¬U‚Fã‚P(¦šÙDÕ´ðç ÈŸ.kc{’3¦PØ–P¾€:ø ‡mYñº­¬3¦)²5©TŽ‹‹Ï)•/c} >›M0ͱXÓ Ól^S(ìàûž¢Ï/— #H§sG>/Z¨:;ñ<ÉåwmýZ߈{ž88‹ûÀŠP(ª âF½O¥rÄpØV~  Éx„Ba‡fóŠéÔ¡\>äêêKŠÅ=Úí²Ù-õ¸¢ÆºE4*`ƒ÷÷oI}gç!νR“ɶ= γZ­¸¿£”™ŒI§ ÌçBZ/ë«•‡ãŒÔáÝq†d2ez½:¥Ò>®k‰ÄŸh]¾žDÂ"ŠÑï7H&³ôûM©J‰Œ ÚòÖkUk¼_ZD" ²Ù277/•ʺ^R Ý¾SŸëìH$®²ck )7HdRêÿÅÏÁõãþUÿ|mÍÜ((›ÙÌf6³™Íü‚'·ô¬ßoP.H‹ÊŠûû×lmssó‚­­\wŒiF8>>àææ%‘HÑœã‹Å4ucnÛ=r¹ª:ä™f˜PÈb4êªê[]ÄìéÔ–!ö)ùüŽ>xð &“!ùr…È<ª l[[Ç p§:Ýn`0L&S¢\Ý¥v{‰aH%eâP(U!¾ç“/—)U«¦3rØ}´Ë«?'›/³u¼ÅÅçJU"‰vßæèý#­O(”˜ÚS¾ûÁ.Ûm¾}r¿úÌ?ÿÿ1óå’T4Êl±À4 ¾ÿú5•´¸ žMf,=ÖhÄÙOÎèÖºôj=:ÕŸüÎ'¦nèD“Q®Ÿ]3wç”˼þä5÷7êÀ¶.H¥rL&6­ú½¼q`†M>ú“ߦ\>DÓ4u`´¬½³:áp”Jå˜~¿Iã>©À€oÞüˆíí‡\\|Îé釘f˜@@ÔB¯ë¥W«•º½_/Ÿ¶Ýc<î³X{ÎxÜçéÓ?Á4Clo?”¿‘©ètîX.çxž§2MëÕórŽ0wÉåª,S¦Ó‰:<Šà¶a„äüJµMézÇ0¶ˆÅRÌç3eß;ärUºÝÉd–‹‹Ï¥ rN,& ‰kk‘8òòåÇ‹{R•ÓeEnfóZ.ƒ&Ëå\UÏç"/µ®ãäüü3ÊåUyÛh\á8ɦñ™NEÕîÝÝkö÷ß‘-tiB¡@@æKBL§Žj[—'õÚX¸<JÉxÜcµZ©bufƶÅ"Øl^ýÌÿ+,s?û1N˜NEøz)L&¶ÊÔ¬ uNm=ë²€Åb®”Š¿¸¬šõR»þýÔ뀰¢®U'üLõ¯ë:?£t$–lü þ¥ÇŒÇ-õ³¯ÿ«—6ëÇý«––‚²™Ílf3›ÙÌ/è;*“¸ã㯠†ˆF²Éf:u40Ðèv…­§TÚWVÓ ãû>“ÉÛîËÌŠK8e>ŸbA^¼ø˜½½ÇƒaEp^ûæ··OºÒ–±TôèT6ÃÔžâº6…­²€5Þ‰ÛñÊÎ.ÓÉE†’ IDAT×q0Ca¶Ž·hß¶™Mfdʺµ®‚¶oÚ”ËAƒagˆ=°IçÓŒ{cößÙ9Ç%a%Ø*æ8)•xQ« …0udDŒr‰º¦ñ;Ÿ~Æoç£ï†1¹|zɸ'Q™r†Öu {8¦¼_Á[zŒûcâé8ýfMט¹S†Ã6Éd–ÉdL6_Â,KînÞ¨·¨vžà8Cà®×#ŸL²—ËñìþžÃ|žD$Âu§Ã«zT4ÊQ±Èç77hµN€ÀîÛAƒ?ý·Êr±$_Í£ÎÀ! Ѿm‹ÏÒ#–бZ­°Âúb†M&c#ıGªŽvkwŸA§' ŠVŠû닟¡…‹Ûï¾ZØ\×V6šd2ÇË—?Ä4#<|øMÚí[‚AS6¢-Tt½~ÎãÇßæææ… ukšN(áÍ›Q(ì*‚öxÜ£Z}@»}K"‘!·è÷òpœ Ñ¸Q»+ò¾²- Ï~@.5âðjÛñó%2˜¦hJ&sŒÇ=²YÀÛ”JûÊ &ÚäÞÃ4#´Û7,— Òéõú–UD׃JÙsœ!ý~“BaWZÍD‘Å¥Û­‰$°¬"ý~ÛP*ícAno_J‡(M‡ö°ª¸M$,&“±â}ˆ Ô\5ŠÍf®l슩Œ“®‹çª×kÈÚ윂p~õ°_,î1™Œ{RˆþL>%OaÛß9<¯s_]&L3Œ¦éjÑ— &£QWý>B¡(¡P„Á õ—–‘õ¡}MŸÿj.ãgÿb9ùËŸ!ª8b8lÿ—”P(Šï{ÿÉeç¯Z@¾ú¼}uþs ×Wgm'Û,(›ÙÌf6³™Íü=ûŽ:9ù:;;þ_öÞ£I’3Oó{\ëÐ2eI  h…a3»\î¬à˜‘fä…ç= /<ñCðëp/äei4õ%gØÓô(t¥2+3CGxD¸<¼îoEf¥ˆ,®þ?3*C¸¿.Âý}ü/ž¢m/K±èìõØÄzá!I¼xúúý{…ót‡À[zˆ|æÏÐîì!Ž"tºxñ»'¨Ô0kw ES Š"ÌŠ »fãïÿæoqpïØ5““ jA€Ópð䟾ÁƒŸ>„(‰XŒH“º¥cïÓ=øKÕvý{}œ|}‚ŸÝÁ÷ö0t]Ô, ÈsqŒ_>y†û;=ˆ¢ˆg£¶ ×÷ñÙî.žFÈòš,ã7¿úËéqãÙ—Ï`8â0F³TŸÎ†ÏXÔƒÕ,"Ž#ÖÙ¨×ÁW¿úGÜ{øCÖ¶t±Džçìɵ¢`µœc2y‰$‰ÑjíònRë5+ÊvÝ ¦ÓSÔë]ȲŠù|ˆ³³§øâ‹çÏÝ݇øíoÿo|ñÅ¿Æpø''ß ÙÜÁÞÞ§8>þªèøäÂ4™_Fñ²í^¼`Oé«Õ6AÀj5Ç|ÎüQ Vkc8|Éä´pþ6Q«uðìÙ¯ð“ŸüK¸î˜{{¸î’¤pŒýýGÙ~8|NçÏŸÿ÷îý„§Ü”†Ã܇uƒÚÁr9å­¨—Ë:C ‡¬¶d4:B»}€õšì¹î²,Q ‹Å¸ˆ¤0ÃLQd­d£(DȲŒ§E™¦ƒ Xc<~ Ü{¤œd7›;ðýeÑKæu,U-åOßÓ4A­Æü5JѲ\Î / O¨KC¿r¾·9ñ•eI1O—B@–Ë/'ã—¥"±cÕáÂb› 6«7É.]ÖægÊõžF¯ÄƒeÕ°^3ÓÂm»Y]& ¾—×U(Añö÷¨û÷Šû÷¿@«ÛG§ŽÐjí¢µßâ…ÖQÀ&æ«ù íý6B?„¬ÈXN—˜ŒÎÐl÷:Äa «j!Yª‰Sw°v×ÐM×Y<ùå|ñ¯¾ÀÓ_=…Swp÷Çwa:&úÝ&*†nµŠ_>Ž?¹óõ²$a²Zá°ÙDÇøÅ³gxØë¡í8x|zІeaàº8=c6˜a1Z K3|ùYäè‹èÝéc>œ£¹ÓD°ú!þ µZ‚ ÀuÇØÝýggO0¾@¿­+¤^.§<êää8NQäÃ4«ÅäÑÀññï 3ÊÚm6‰wÝ1=ús¬× ‡ÏaÛuî`vö Qäãàà3hš‰³³'¼ƒTž3Wó»w„““oÐjíâÙ³_qcÍZ­ƒ§O¿Ä§Ÿþ)O×ëtprò :CýšfBQTH’ ×ðV¯ºn!Žƒ¢8ßG¥ÒäéI¢(#ËRȲRL‹`îë*:”шÍó¹œ|³f~ñº˪bµšqSO_œ|—b@!þ¼+ŸÄK’ ÓtxšÔÅ÷.û^¹>ÖE+zçú÷‘²DÜ*’'‚ ˆw@»½Ïê?’½{=$q‚Ö~ ËÉÍÝ&æÃ9DI„]·ú!š;Mœ>9…é˜@ì~²‹Ð ‘g,‚ÐÚkAE<úóGXÍV8ýæÿî¯ÿkM§?ÞßÇÿþå¯ð“;‡øíïÂTUTLަÁc$Y†4eiMÓÕ O†Cüö¿r@’%^Y‘ñ?ýÍ¿G¨6ëhôpÇ.ü•,Í J"æÓ1k=»sˆ(`í}Ó8Åoþá‘$AD–¥ÅSqVç ë6òœyHŒF/ÐïßÃÉÉ70 VgQ¶ÄýÅ/þ7i/»PM§Ì½³¿ý?~ŽÞ½ý¿ú¿~ÝÒ1~9†Uµ0>³\vpôøEaÔ–CQ4<þküð§ÿ ëÅ ëõ®ËZÖNÒggOP­¶!Š&“—Ü8¦Ó3ÔjíbBÏŠÀþóÿ€Ÿüä/ñøñÿƒû÷ŠÁàZ­=Ìfn4ÇÒ‹^Ÿ`Yµ¢ SŽÓÀpø£Ñ?Ãr9ã&”‹ÅY–Â4+ðý%&“ØvÝî!ƒç0 QÄ:r•ÅÔ½Þ]œ=-ܯù¹Ô VkóùOàYQ7s_,Æ[ϲž`sγùïJ¥É[ÎÞ†m„A·(orá¿ì‡M… ‚xâä6÷œ÷qúëÿþÄ¿ûþ[¬£:øqŒ¯NOqÐlâþ÷ƒ;?¼ÍÔðøïû8þý ôïíbø|ˆÅb„z£‹Éø¦YAš&h÷{˜§H’OŸ~‰n÷ ‰Éäýƒç°¬ 4ÍÄo~óŸàºt»‡Ð4óùÎ~áŸ¢âø˜è}Ç©Ã0l,—3ÞmIUuØv½Þ]|óÍÿ‡fs''_s#:Çið¦e:OivÇ<$IÌ  7'åå>.ëdY=—úCñFå¶ñm/þå… ‚ø°ø˜ ½/B÷(‚ ˆoÿ¾"ßt!~ß7¨m–O7‚ âC½™Ò=Š âÝ"›bäÛP\ï›·M ±ÐXh,4–e,ÄÇsúÎöá]ÝWÄw±2º‘A"t"‚øøØÚ¥¼Ào«ÀÊb¸òßAñ¾¸í=‡îQAßrÕüº ;]ô ‚ ˆoS¤Ð=Š âãç£1j¤ A]wi_A|÷¯•"í.‚ ‚ ‚ >H AAA… ‚ ‚ â"E AAAß(‚BAA ‚ ‚ ‚ ˆV ÜÖí—Ü ‚ .¿6ÞæšI×^ºGA|h÷ñCÙð<ÏÏ9û¾ËÏA|ßo"—]3éÚK÷(‚ ˆñ¾B)^ØIð!Ý̾«7ÖïÛ“Í?Ôö~O\>¤q¾«íz¨ç AÐ}ø]¬çCÛ——Û¾N|\÷™vý‡ó,Or%¦ýü±oïMO\¶ý÷Ç2Îm»‚ ûÃwáaÇÅãPþ}Û׉(ø…asuñÂY¾·ùzù÷e?ÒÛ.çâ2/ûû¶À›. —óºñ¿Íõ¦ý°íxÞt»n»Þ·½ð¾Íz¯ÚÆëÖõ¾ž^ms~n{>P AÛ}øº‰üÛÜÇ®[ß¶÷··™/ÄG#P¾/'w¹7M@·y2»yQ¼øú¶ËyWOnûý7y"r› ûUûùªýp›ñ¼ÉvÝv½ïê¼z“õ^u^ý!'·ù½tí¥ýD|×ïÃ×ç6÷±Û<¸yß×Ù«ÆrÛ׉ïzùA”«Tÿ»úüÇð¤æMŸ†o»®úÁ¾iÔáM.,×M’oó¤çMùuûùªýù.Ö{Ýr¶=ß¿­í%¾›“¬«®™ß÷k/Ý£ˆñ>|Ûñ¼Ï ûu÷ù÷±]·#Xùxï+ò‡tq¸Í–.ú·;¹ÞÕö¶7ÝÛ>Ѿêý?Ôñ~Óõ¾múÙeÇïCŠbî$ë]ü¶èÚKû‰øpïÃèõ^w»,õë¶)áW}þªûÞm_'>Žû Õ |à'Å»Œ¼Í÷Þ&Åèâø¯ _¶½×í‡wá¸Íþß&´|Õ¿·çMO¤Þ×E÷]o߯—˾ó&ãWã|—ÛE݇ßÕ5äMR¡.».^uO{—ãn+\nû:ñ‘‰úœŽ ñ±ž¼ÈÓ‘o»ëýd ‚ ‚ø.C>(A‚Œ ‚ âÙóP… ‚ ‚ ˆŠ AAA… ‚ ‚ ‚ AAA$P‚ ‚ ‚ H AAA… ‚ ‚ ‚ AAA$P‚ ‚ ‚ H AAA… ‚ ‚ â*PAÀm?ÛïAAA彈“<Ï‘ç9‰‚ ‚ ‚ Þ­@Éóü½  Œ²lóAA|hÐ=Šø®¢iæ5ïïw‚*J×¾/Ë*,«zî5ÓtÎý-Iò¹ß)4}hš Aù몪_»½ºnA’d¾ QÏ-³\—eUÑnïCÓLt:ü½z½{î{WíãF£^ï.$I†®[h4úpœtÝB»½_l·UÕaÛu¨ªÓ¬ðï[Vo‹®[üóíö,«†F£_Œ[ÄîîC>þò;‚ ¢Vëð17}†Z­Û®¡Ó9„ ˆ¨×»°í4ÍÄÎÎÔë]Ôj˜f–Uã4øºšÍ~Žn÷dYÝþºšßBy”Q‘Û~ö6ß»jYïS$AÝ£ˆï¢("˲·>ÿ7ÏýÍ¿5Í@úü=EÑÇá;¿$ÉHÓäÒu;Nq!I"dY A‘e)_–$I|ér7ÇÙlî`29 ˆÈól«9q9.Û®aµšCUuDQÀßwœ–Ë)dY,«ˆãišÀ0dYM3áº躅<ÏE$IF–ePaèÃq$Ë劢!IbXV‹Å¸+U„¡‡$‰Q­¶®;F»½Åb M3°\N‘ç9LÓç-Q­¶‘$!$Iªð<aèÁ0Ȳ‚(ò‘$1²,C»½‡Åb„,Ë ªlY’$!Ib(І<Ï$1jµ‚`F£_ìGA°¾ùܤŸ'AAÄ÷·'LäœtlNÚ7Å ÄqøZ”cÊ(Áf´Á4+\œ”Ñ‚rÝ’$c½^ Ö|B¦É¹±%I ø|,›"j29áb®Ä0½i·÷^{¿2«Õ‚ œ'›ûM×m¤i‚4M (|‰8Žø¸’$Bú0Miš Ó9@úE‚ `µš¡Ril»†$‰ (Z­=’$†ªê$žç¶k‚5TUƒëNP¯÷ ª:¾«×·‰âc`sòÿ.›×M·Ã½šL¿ú¼aX·Ü>öÝÍÎec³¬W‘‘2êQ¦[mFgÊåÄqx.Ç!V«Ÿ0¿Z¯VÔ会웦×S©´Î‰×¿& “$.Dë1I’ÏE Ʀ\´4›»°í:Ök¾¿„,+EŽS‡®[¨"ñBÐoóÍHÓôµeñ¸(J|â\¦A•¢ Œ¼”OîK’$æùr첬B’ä׺C±ÏÍùߛј’²ž-Câõ2›íž·äâFÓ Ôë]Ìf>žÍÂyß_ñm(…U¥Ò,Ò£^5$0 aÈ"Ky ‚5$I†$ÉH’q¢^ïBQ4>vÓ¬Àqê°¬ ¼”"ä²ãY­¶0^y,.ƒŠä ‚ ˆouÂÿ1 –ÍÈÏUÿÄwͺ‹\U³Âбõ ò«§ÍßMç¢å„ûb ¬V3þoÖ…+Bš&ü;å2$I.¢£â¹º•ÍZ4eâDzªHÓ”¿W.£l·[N¨G£#.N^uîËøò’$z­£_š&¨Õ:纥yž‹8Žø>MÓ„o‡¢¨Eûä|…áðâ8‚ªêX­fÈs–ÂUFŽ¢ÈG»½Ï×·^/x‚<ÏÑíb*‚eU!,M® ²¬ Mc˜fÓé鹦 ÃáóBÄE¼KXžçEzœZ+Ÿc˪¢Ri¢ÙÜE¬+¬×s†Sˆ4Ö-ì[+’'‚ ˆï¢8!¢˜,ŠWO/ëPµùžªê¯µó½˜®&ËÊkOÖ7#%׉£Í®`å2æóañ!»…‰¸(x•:ÅBùÞf!|‰m×.ìéÂøUÔjÕ)×¹^/°\ÎøÄ_ÔjDQ°±ß^mŸ$)ˆãëõü\„¤l‰E>L³Â£-¶]G–ehµvQ«u`YUxÞ;;ç9|Çiðz™r›—Ë)<Ï城ppðL³UÕqçα³ó®;.|b T*-„¡Ó¬ LÄqˆårËbßKÓ´èžæA%4=ÌçCT*­B IÛß/òànA=æ ‚ ¾›âä*ϬwùïËîäÕE|׸è ò1\Xä!>—Vu›ß£aØeËå–UAç„FžççÒÉXúØå‘OÓ¬Àó\Ȳ Ót ŠæóákÞ-¥ñ<Š¢ž«{X´)McèºÍ…ëN ª:/¾÷<õz‚ B’ؤ}4:†,+ÈóŠ¢AÓL,#Ôë]DQ€õzEÑ ë&†ac½žC’H’Œ ðŠöÊsäyð¡ëV!¶b„¡4M ªz!&Á¦éÀ²jü{Q Ñèc±q–çâ.…,+…ø&ï@VF²,A­ÖÅlv]·‘ç¬Ís‡ðýÕv¢˜~ÒAÄûžˆ”ÿ¿Ø9몎ïêõ« N“Äwmsû¯bÛîJ·L7QF¢(xÍËdÂÐçјõÚ…ãÔωà|´C’¤×–_¦Z)Š M3aÛ5¸î¤=µsâ¤Ñèa¹œb±µ¬É€¢h|ÿÅqÇi­Žm^TÎÆ¸Øp¡†–Ë,”û#ŽCžÆUÖº0q`¹du"ãñK¬×.¢(€ï¯xkæ<ÏQ¯w‹N`¦Ó3,—3Ȳ Ç©£RiB’d~ý“$™‹ @€¦¼EÓ Á•J³èÆ¥B–~ oµvyPz°íZñžß_qÿš(ò qµ}ã(AÄ{妺«j9ÞÅëÔi’ø>ýÎ.@°ÝTï*WõÛ?Ï=¸Š‹µ+Û8Ì_QŠ¢rÀ ¹¼Up¹=åDw÷!²,-LÅ×Ö»\ÎxÁºã4¦ ¢È?'´²,ãŽ(òáy.Aåþg~-&ÂÐC…Ax\¼´Ûû|;6Óó^µb1›!Ë2ÞšYèºÅÓÄâ8Âx|Œ,K¡(^Ñ@áâQU5˜fqA–U.x*•¦ÓSÞñL–U¨*s_ Š|4}dY†J¥‰8Ç!$IÆÙÙS^PŸ¦)4ÍD’ÄpœoLP«u1>ç®ö­ÖNN¾&BAñ]a›šŽ÷ñÝëPõµ×6£—Áj*„Ä 79Üç6œÒ¡œ¥,Í !æoãœJš&¨V[…Cº‰ÓÓ¯!Šò¹t3ß_¶ëç":yžc±CDȲ‚ Xök¨Õ:$ŽÓ€,«…|‚0\óÃéé.æ6#7¥@«V[Üñìì)O›NÏ`š•¢Î†¥•yÞ§§O°\N gx¶]çNïI£Ñè)V5¸î§§O¦ êõ.â8„ç¹EÝ +´¢‹/&b.¼â8„i:˜LNP«uÑïßßHe‹âüOï* ‚5| Ó¬n¤Á‰°í: ‚ ‚ ˆï å„ùb‹Û›Ðu«ˆŤýrßÇ©oeLº)"¢(xMüÜ”"–$ïÞU –0ô`Y•s‘„Ͱ<Ï/wéeR¶¶¬Úí=þ>3b|™1M‹s€¯TšEg«’¤À¶_m¿ç¹¨Õ:Ðu ¦épWu py;_YVà8 dY˪"Ï3MXM‰,+|Û6·i29áå®;t:òÂEá®ôFÕj•J‹SۮòjE»`–º¦ª:<ÏE¬¡i²,ÅÎÎXV''_òj0Í*Úí½BH X.§È² A°† 0qÑëÝE£ÑG£Ñƒ$)h·÷¹¸1Í *•fáo£Zmc2y‰Vkyža<>F°¬4MG¿¶]¿¶5 ‚ ‚ ˆ˜«ºu]tS/ ‚5DQäO¾¯š(fÙÕM#6'ùkE6SŠ˜@¹8à“Í ¢j³õ¯eÕŠu°¼eŠV):JÃÄrÜåºdYåÄ÷WEé\´¤œ ‹¢Ãp iæóOŽà8 ˆ¢„ÕjÆ;g•µqAEøþËåeôƒµ Î`Û5ÄqT¸À«H’QœóeqÝIýÐá8 XV•¿×jí@×íBà æGRŠÉ2¢äû+¬× ÌfgPUÖ-Œµef&‰šfp#Eß_]·ZÜ f6 ÙÜAµÚâ 4ÍÂjµ€ãÔ‘ç,« ]·E›äõz‹ÅŽS‡ëNàûKDQ€<ϱ\NQ©4ǬÆÄ¶ëX¯ÈóÆLÓA’Ä°íÆ¹.fÕjëÜ>ø¨ÊfÊ›:@AA×§V±âðëçS›“ûk'Ž—Dp6‹×7ÛËbnÛ®k1»)’Êõ.#î§Áæƒìÿ¥ëùÅu¥i\¸°³‚ð,KaYl;ËT¯,Ë I/4/;SmŠ€²}n¬‹‚ïW 3žb<~‰J¥‰,Ë0ž"ËRxÞõz•Jíö>4ÍâŸEIaµš#Ib,—S‚˪BU5¾¬Mo\DnDþÿ²=±a0¿‘2¢Ónïök¼¹œBE^ R«u ÿ–Ò¶^»pœæó!¯Ã™Íðý%A€¢èX,†0Í >aµšA’”‹¥ Ïsy74EQÑéÀó\†Q”P«u Ë2jµ6f³‹ ÃA¥Âjn’$BµÚâil[‹vº,AA|l¦-mk–xUáMÇôÍ«ò ÿæw7kKÊ÷‹Ñ–$‰ETUçŽí—Õ¤”¯—u$›b(M“ÂPp¼3U¹œ²ËVÜÃ`iY¥)¿£i&ß_å˜ ÃÁpø‚“[ó>)Ç$1ªÕßþ0ô0Ÿ1«ù`Ē䕉$ÛV˜^¯w‹×Y=‹ª²ˆaب׻<’"Š"²Œy‹¨ªŽù| ÇtzŠÁà–Ë)vw Ïsxž EaÂÆ²*ˆ¢wîüˆ·fæÌçC¡ žÁó\t»w0ŸЦ"vw?Áj5‡ï¯P­¶¹ËýÑÑcT«BÄ11äy.Æã—$ËåÇÇ_A€jµÍM)I AÄ;‚¹o{þ\'(Ê t)L¶1K,'ê›¼Š€¼›©5yžž3$áÒî` ïËåFQP‹§<¢²9×Ã÷WðýW¢BUu^“"I2O†a¡Ñèqo”óu%9Tå¤^Ó Þ^XÓ ˜f…wúʲ”¯—/c¸îA°†,«|»‹1D‘ùš¼",M*ŽC$IŒ8qÿþ¨VÛe… Ó¬ ˘wˆ¢h0 »èô% ×EëÝ>NVÌAQTôzw1Ž<Ï‹:æZßhì°4Ôë=.{½»HÓ¤q§NçšfÀ0´Z{°¬:E2A·^/ày DQäb¤þkL&§P®;Fžgh6û¸wïÇ$–†¶^ϹëûþþP¯w†ÌÛ$I"4}ìì0‡w‘Š #Ç9ºÝ;H ˆ¢UÕ¡ëvQ ±·÷ –E‘år†ÕjI’ñðá£×»‹$‰!Švw?Áb1*¼U‚ðZs(AA|ï¹)½êM¹Xr±ýîEatSG£2½é•3¹ðšøaÆy9‚Àãï•OÚ˨J)HJÑQF7TU+Úðf×쫨xz£ZmCQ44}¤iÂEÂævV*Mxž Qy—'M3†ÂÐょub…Öóù»¸‡¡_DYD‘ÏÝËA°ZÍx¡užgEýþ=L&'Pí\Ê™(ŠE1x õz·hUœs!Æ„`ÛUnúÈá/Ï…ããß!ŽC„¡ÇEUzˆ¢Y–Â0lnä(Š2§É£3qK„aØÕjggOàûK¨ªŽ8Q«u1¾@³¹S¼nÀ0l´Z»hµvÏ5"X´K’d|†Ý݇„ר‘ ‚ â}ñ¦uC75D(Ÿ*ß$ŒÊå°bîë§aªªÃó–PíÜò/Ï_VLŸç9dYÁj5/&Úësãd­d• µ!çEÔ¦ðY,FH’ˆOÊK²ùÍ', ýXdA’$žfTF^Öë9l»Îýêõ.l»ß_ÂqšÐuƒÁ3hš EÑá8Môû÷ùöŽFGX.gøúë_@Ó xž‹ XÃ4+Ü·`Žíªj ½¢8<.ÒÎØä~6òmÑ4ƒwSUƒú/£ÂO$Ær9$IPUÕÒuŠ¢Â0,´Z»P óùÕj¦YAµÚF’Dˆ¢õzÕjºn¢ÓÙ‡(Š…xÒ¸`ÐuA°Búh4úÈóY–m6¯p±gƉªª£Vë@×Mœ=…¢è¼ðr9EµÊ¶ÿððsH’ ×#M4›}¨ªÎ#iŠ¢a6pGùn÷>üã"" †]´Ofž-¢(ò}9½àÝÁ,«YV1c¹œ¢ÙÜEù|’@!‚ ‚x 4ÍØJØ\1¬ÞAá‚€ýÿU½ÉEóÁR”””ŸÝ ,ŠE_Êš’‹ßQ ÍæÎµQYVyëÞ‹­†Ë¿7Û +ŠA` Ód­{Ûíýs)h®;.&Ú.¯O™Ï‡¼Vb:=Eš&¨TšpÝ ï”5±Ilé£Ñé`:=i²”-&r˜wI5qœú¹6Ìëµ ]·yz«Å¸M3¹k4úØßÿl§§ß@%T*Í¢ÛóK‰"Q@’$躅Ùì¬ðv1á8 xÞ’×Έ¢Û®âK*Ìkpœ:Ò4m×qtô’$æ)bóù–UÃj5/RèXcgçÖëE…¢èEDz’$a6;+¢;:öö>ãÔy‡­$a-YV¹¨Ò4IÁ4¢Ýr’$óöÇ£Ñ ¨*KS ‚5šÍ>dYA³¹ƒ XÃq˜P,›$IŒããßÁ0„¡‡ýè/ຓbýì8êº Y~UäÏZ2³Ndíö:C.þH AA¼Ût³^ÎäyVt“’y*Õfg­Ë¢.›2Íh“Í¢ðò©÷EŸ‘r¼é}íöÿ÷b1âc*ë[Ê‚ùÒT¯ü~9©-ý¢VëòÖÅ “C³h½+£Û=D’”µm¬Vs,ck:`6jµ.Ò4.¢G2vw"Ë’¢û_ß_m•U¸î˜OÜËý+I¢(Àz=çQ—$‰1Ÿ`YUŒFGX­æ¨Õ:èv Wyyžñ–ÊL,(žcÎî“É)LÓ¢hHÓªªcÿÆ»i¼wñÿo²Þm?{ÝçÞd}dHØkQ–eç^/#+Y–ñIži²Öµ¥°¬ A87y+ Ü7aјÒO%F½Þ寉%e­Õj^Dq"¨ª¶ñþŒ»Â¿ú\EÑ0!ËRT*¬¾¡ß¿Ç‹ä%‰o«ª†4M¸iŸ,«H’˜‹ ×FäÛ/ËÌ=žÕ.¨¼¾Åqèõî¢×»sNÐ1Au„ù|À»K•é[šf&ƒ¬‹kI£Û½ƒfs‚ `0xŽZ­S´¶aÛ¬eoY¨?ŸP©4‘¦ :8Nõz{{Ÿ@–ôzw±¿ÿ¨¨ý00ž¢Vë`µš£Û=Äz½@§sˆÑèA°†¦Y¨VÛh·÷kœ=å©caÈ¢?iš"ÖE;a“ D]·P¯÷ÐjíÀ4«°í::¨ªŽƒƒG8<üªjpñ(I2=úsøþ Ý|J¥…Nç–U+êJêh6ûØÝ}ˆŸýìßÀqxùòwX.g<ík29ÁÎÎC‚Q”`YU(І$I0žáàà3D‘˪¢ß¿‹jµ…<èºUÕ+4›}|þùVÔ¢01\­¶ø9ÊÆ~P¤¼Õ¶jT!~/ÛÞ쯚x¼é$å¦õÞf?ñõ›ÆzÙº®ÚöË–wÕ÷¯ÚÆ«–wÝòošLm³ ×-ë¦sâ¦å_µßËV‡Ûló6ÿ]w\¯s­¾nû¯ûüUß/·é6ã¸îµm÷ÃMçØUß»j¼7íŸëÆVïm.ÿâz.þ}Ý2¯úì6Ÿ+—·y®m»œ›¶›ãAÄÅ{Æ«)SYóQ-_Æe¯ëº…ÅbTDO$¬×‹b—`>ñhîö½1M½ÞÝH ó¢(}DÊ´›ò‰=«£ÑlîðÖÃe]I’Dpœz1‰·xZNÙ¶t{_.gˆ"ŸOúÃÐçãžÍˆãyžñ”)֎׀(Ê<5noï“b…ðªCU ^#3c29ÅdòQäÃqšX­æX.§pÝ 4ÍÄÑÑc ‡ÏÑíÞåÛQz—(ІNç«ÕlÃõ¼ X#ÖpÝ ÷Q™NOày.úý{ÈóµZggO¡i|…Å‚µîm·÷±\Nq|üÒ4ÁîîCP­¶ (â8€¢¨ØßÿÂЇ¢¨X­f0 ãñKôû÷0¾(Žóqœ‹–ËiÑb9Cð¼%Úí}øþyž£ÑèÃqE+è:ïÖ%Ë ÎΞðöÉŽSG–%88øŒ§ÝU*Í¢h_ã³ÓÓoP«u ˬ>h±Ã÷—øôÓ?-Œ*38Ny΢=ÍfÍæŽŽ~ M3°\N1ÃqpœFqŽ PU“É ÃÁpø;;0<ƒ¢h…9fÀ£{ÇÇÑhôP¯÷x¶ïŒ@ÙöݤàºÏmNHÞd’rÓzo³Œ‹Ÿ¿øúMc½l]WmûeË»êûWmãUË»nùWíÛëŽÏe˽jY77-ÿªý^Þt¶Ùæmþ»î¸^õù›¶ÿºÏ_õýr›n3Žë^Ûv?ÜtŽ]õ½«Æ{Óþ¹nl'—­çâß×-óªÏnó¹ry›çÚ6Ë¹Íø®úA|Ø!/Ÿºlã¸~™—È6Øv½hÝ+rqQ.ïªßÌfyIYÓ±Ù]«;Ç_Öj”bC%‚ˆÁàšÍŽÐhì Ïó¢à:y­N%Ïs„¡W<ašl»ŽÙl€ù|M³¸A`¬Q«u0Ÿ3ÿŠfsFŸGVÂÐC³¹ <dYUÄq„år UÕŠI²ÉS®˜¢[T3‘²^"ËR,—3ÁŠûh¨ªŽ4y}Mu*®pÈó Š¢¾'ÂÐÇhtŒv{ggO‘eÌÓ$Ž#´ÛûPU ƒÁ³¢sšÄ÷e­ÖÁ‹¿…iVp|ü;hš‰NçÝîÝ"2¤ ÕÚãÿ^.gÜ=þþý/kž¶E ÃF¬qçα^»‚¡A|g&ƒtÍ¥ýõ!RæÒo{lÞô¸˜f…×\v|§Î§Á='6£%›Eê¦é MÓŸCâæ¬°¸Îë ð.W¶Í:=YV ëõªªÜï4U.æyÎë1˜{¢(c<>æë) ÂEƒ$)ÐuÖUJ’¤)Kù*ö¦Ó3^(>Ÿ3SÃ( ¹Ñ‹v<’¤(,Í«ÑèóBô££Ç<*ËRÔë=ŒFG|Ò¿^Ï1ž¢^ï¡Ó9€ëN0›±Ô+æFîa½^ Vëàääkôû÷!I2|˪`29…ã4àºã¢EÅr9…iV0£Û½]·¦1ÂЇ®[CA°â-zeYá EEGØÝ}ˆ³³gX,†èõîb8d¯z½»X­fÐu ®;† ˆ$…×èº$‰¡ª–˺ÝC ‡/e)÷|i4úètptôZ­Ý"â#à÷¿ÿ‡B8ÄEg-‚nȨª¦# IDAT/@¯×{Å1náìì ?–Ë,«ŠƒƒG8=ý¦(’—xôŒ¥‡IÐ4 aè!I¢¢žÇG½ÞåÞ&‹Å½Þ]ŒÇǨ×{˜LNe)Úí}(ІÁà9Ò4ã4¸×J­ÞÆoówØÛû¶S…·váûkT«-¤i‚Éä/_þaèãääë;‚B)AAl˶âdÑxÕC’dnšgYÕ× Ø™#7{Â_©4ù¤OÉ*ý8ØzÄ¢K›$—ÛÇ!wÝ.©×»ˆãšfbµš£ÕÚ+ŒöDQPŠ»\”5e!uÙ©ªt÷À…a8pœ&L³‚<Ïx=Ëb1Âj5Gúxùò÷ˆ"†aóú•h4v°^ÏE>ÂÐCµÚÆÁÁ#T*MØvשè:K;:z\˜J…Ð`l¿ZÍ0<Åj5G³¹ YVyŒeU+H’‚Õj†;w~Û®£^ïAU5¬× dYÏ[¶k°íL³Û®c29á‘ YV¸xE™ü›¦Ã}XXT R¤ÓÍÐhì I"¼|ù{˜¦ƒ½½O‘$q!gET`Σ7Íæ.’$Âtz]g…õYÆ:«õû÷ !UåòûûÐlî"Môû÷ Ë*Ž`ipÍæÆ­ÖnÑP«uÑhôàû¬˜½¬i™L^¶ëe¶]ÇÎÎ}t:\—µ•JÍæNÑEÚJájY5,—Ó"ÂÆ¢y²¬ ÏsÞûéÓÂ;?dbØ©¡ÑèA×-4[;ˆã‚¬× ‚Ç©#Š|$qŒ4M! Û,jvðãÿçxøðn~ñ‡¾Ðl›þp™˜¹Jà\'|6ß»¸Ü«þ½M^ÿMë»ìó×mÓeÐëjX¶Ùîë¶õªåo[pÙò®ãuïßfŸß´¬ëŽç¶ÇôºØMçÒ¶O]oúÿMëÜæq¦hñ¾Ù&%ë}°YÓq~Ž!nü^¹Ç'|eZUš&ðýâ8„ëNŠ(ËŽò:tѧÄ4«üI~ ó«xÕz8ÖE Í…‹ï/¡(*§^¤'±ŽKeÝóŽPõzŽÓD–¥X,F<­‹¥-áºcäyŽn÷&“SȲŠz½‡ýý ÕÚƒeÕǦÓS ‡Ïáy.ƒçxþüרÙy€˜NO!Ë f³Ò4å…è@λŠ5›;$ ¦Y)œÒ+E—'±ˆFÜ+ÜåÜïÃu'PU£è"¢ÝÞçŽðx7²z½‡z½[xƒ¨Ü1^Ó Ôj]œ=A»}Pˆµ Íæâ8,Lu^$oš•ÂÅÞÀîîÃ"ª£ÕÚóèBµÚFµÚÆãÇUÕ±^/ŠZŒŽSG¬¡ëVá¦ÎÒ¼˜/«9šNEW®&÷Ô‰"®;ÁÇT8Ï;E ¶]«ïСi&Ò4åµµZ–Uå]ÖL³Çi ÑØáB6ЍªŽ<ÏÑïßÀèºUœ›€¢°®mŽÓ€®›èvQ©´ INN¾F·{·}ÌÉþg?û·˜Íh´;–U…i98;}Š$‰e9L³‚ÆNw°Î^ÝÃò<ÇÏþâÏPëÔpç“OÇ!E½ÑÔäébvñ†yUèöºîæ{öß»(Ž.þ½íәͼîë–yÙçËï\÷úÅÏ\79¹j[/.ï²±^÷Dê²å]5Æ‹Çôª}yÓ>¿iY×Ïméeûýªå_7¶«ÎçËꜮ:Þ÷ÿucºìx]u\nßMã¾éÜ´¾«ÆwÓ~¼îw²íùqÝX¶ùÝm{Œ·Ý§Ûœ'×}çºý¶í¸I˜ßÛtòyñsÙò7ëWD‘yv°‰î€{‚\ü 0/ ±0”øwóœuÙZ.§hµváyKxž{®p¾ô)'dëõ¼˜ˆŠ…p`©X,ÍJæ³Ê¨MéÄÎ:&éPUë53A ‚5~!Š¢b¬)E‡ DH’˜w‘:>þ ¶]G¯w²¬b½žÃ÷—°,Ö¶Ó9Ä`ð ýþ,C˜f¥h5[):hbµš¡ÝÞƒm7 ‘Ð(м€¾,è.ʼn¢¨˜Í¼3Tžg_àîÝa±#ËRìí} Ï[@QtdYŠû¼pÝó–¼°E«R¸î¦É¢#q¡ÙÜ…¦™ÅäZæ"hӷŲ*xñâ·¼#–ªEÍNÆ ‹QÑ]ë½ÞÝb"/"Ïsôzw±XŒ¦1îÞý–Ë)êõ.‹qÑMÇü89ùš§˜~Æ”ž#Ožü’›TÖë]¬VsȲŠgÏ~UÔª8ðý%¯w’$Ëå´hb`£Zma6 Ër†Å‹ë%Iá A€m× úýûȲÝî’$)¢;)óh©wÐêì@ÕTŒÎN ±z‚ƒ»Ÿ@ÓØ¹–e)|‚БD â(Âàäþè'€£¯^àóŸý1¼¥‡4I‘¥ò,‡]³Ñk˜ð'ÿæÏ¬¶û;hôPtô_üñwK l{#½î{Y!ìmß»ÍMüb±íM˸êó7½~›í¾î{o²Oßf¿ÞfÛƒÛl×m–w“¸yWçÇUÿßö˜Üæ|ÛfŒ7›·=·9žÛ<ˆ¸Í1¿Jh_%·yrÓßö¡ÊmpÜvo¹"Þ/ë9¶?—Õª”"‡=ÍÞ4a,ë6_g-rYªKé`iZ¬æÂäbDUuH’ÌM™÷…ß_ÁqˆãA°F½ÞãQ4MyA»®[˜LNP©´Š±²<]· SC«héªÂgQ´oe5&A°B¿û¯ìïÿ¦YÁlvV,ßF³ÖÄ–UA½Þ/Rzä¹\ÆÎÎ}xÞ Ÿ~ú'…‰ÄkCL“¥›‰¢ÄÓ¢JAXv“ªVۨ׻P §§O`Û5t»‡…è†~áÓ"ð¨ÂÓ§_¢Ó9€¢´…‹|…©9w†CžçB–µÂ\±Ã'হI’±XŒ Wú3¸î˜ ' 瑨ÅbŒƒƒGð<ªªãŋߢÕÚA³¹‹Åb ÓtP¯wyʘeÕ0<Ã?ãݰ RÇ©Ã0¼|ù{t»‡ªj`gç!€«ÕŒ›;9²,A¯÷I!V+e΢ÈÇ_ü+H’‚ñø¸H—Ñhô°\ÎP­¶°^/0îï+Ôj]ž¾¬èÞrÄQŒÙìªj0o”õí~’"AU ì}²ä71â(FwwÕv¡¢Ño@E¼xüª®âúË釟¢Ò¬`çÁ~öãOq:ŸÃÒ4Xš?Š%ÿ?{oöãJšžùýÈFdpßs?™yÖÚ««ZÕ£ ²Xòž[û† ßøÂ€ÿ÷lß Œ·ŒQ{´X­µ¥®®åÔrö\ÉLî{#È`}ñ£Oµº[-YƒéÑð¹:+sc2¿÷{Ÿç÷ˆÎŸ“r™?yü5>8%‰0ž‹ï—¯^\üÃP¶Úêm8Þêßí¯ÁÏ"yý]ÞîÏûÿ¶ƒèße@ÝêßÜól;Äüÿ×ûЬày.ëõú''?i}°øñ>DZð†Qn¡³áÿM$R!ùi3ðlÞ'UM„‡ú/“1‰Ç“L&}E ó"²#ŸÁhQ83$‹“,+¸î‚T*Ëz½f>Ÿ‘Je‘$a©ŠD`:íS(ì|#'³XØA‰ï z“ r‰¡hƒþÕõ4ý~MÓY­–!Vxc{šNärU‰©T. M‹;HRŒË˯¨×±mÑšnY¢Q)$Y‰^Œzøùsé´Î=oE±¸R¤b15ìNÖ¿HhWÛ¨…6ªNç’rù€³³Ï¸¹yÁÎÎiHáŠD¢8Î<ÀG¸¹yA¡°K³ùœD (ƒ[t=ÍhÔ¦Z= sF›px*•#›-Ón_„–)Ó±·÷€|¾þûõÚÇ4G”ˬV.ýþ ²¬`¹Ð–%Ë Š¢Ñí^£ëiºÝ+%N"aP¯‹á¤XÜåööŒbq'|ÄbëµO"a°XÌÙÝ»<Ÿ³d Yn¯¯(”«tnD£µƒ}FÅÝ “Þ=­3êˆNœýý‡b(,èÞ¶˜'dJYJ»Ô¸J®Tà­_‹þMŸý‡ûH²„92ùÖ{(ðýOy÷SZã1ùTŠ——M¾õà”‡õ:/Ûm\ÏÃõ_c2é’Je98xÄpxK&S¦R9b4ꙕ"½^ƒjõÑh4 }|ß§Ó¹Ä0rxž(®tÝ%¶= 7O›šl¶ÌxÜ%O¡ëi_ÚÝEáájµdÿaðq¨ÌfCRé4ñ¸N¿C®\`6Rª×8>"ÓH2È1u'*E™ŒúTöv‘ç2²"“ÎÂ`z\×Q*ùjžD*A*›âæå j\cçt£`°sw-¡1éOb¿öΤ þåŸÿÿèÿ“©ÉÞÝ]ŽŠERšÆãFƒ¸¢ «*©\ ×ó°æÍËÝ«.Ãö13¼’ʧȖ³t¯» nT+|ò¯?!]HÓmtIåR4¯Î¤Ë¥ý7¾Nl”­¶Új«­¶Úêï¬M>ã§é§åA~|°øYÚ³^×&Ã!ð«ÙpÛ’H¤‚Á`ÞÈ¿ŽÿݼO‘HÃ(+’É,Ѩï¿¢ˆPõt*ì>›¬¼®ªÆY. E|',´…ƒ9 #ÇdÒ'‰NC جKbST,îbš"£ây+Ls„aäq“D"ªŽÂpµ8äûD£Q2™Z@¥T.×u‚NŒÇÇïbYcT5eÉfËÄã"ÓR,Àz*•c4ê0›¨ÕŽñ}fó÷î}Èba¿öyò¨Ti4žòÆ¿ÊjåR*í…YÏ‹³^ûÄã)^¾ü„““÷‚æõšÍေ\: ‡-r¹JH[HRŒhTÆqLz½kl{F¥rH<ž ˧Ӿï'C|±ªÆñ}YVä­"‰“É,¾ïÖºªš Ý¾àôô[L§}îÞý0hU¿ ?N1Læ)•ö1Í!Žcáû>©TÃX¯×`ÿð>g/c…}œNB»Øk×,l1 ù¾G¾Rƒn6‰$KÅ|ÁɘOæÜç]’é$«Õ kl•¢Ä“q’™R¹+wEù ŒçzD¥(FÞà½wî¡Æb|ÿ‡_ñÖ›§¼xÈ¿øÁÇüÆ0‡õzÍÊ÷q=»Tä²ß'b-¬ý5ƒþ"кlcÏF×O®ù,¡Ò½ê²°D¢F‚µ¿Æ6mæÓ9™RY‘ÞyþƒçÈ1oåѾêA+DXÌ!jøu(Äv@Ùj«­¶Új«­þÞõ³†1ˆH?ö{qôØ '›Æò×7&ðÍÜÉæ@þÍ¡e6𦋩%J ß ƒå¯Û³„íHlC6´,Ñ´¾ ÙÓébP 8ÄóVèz: ;Õ‘$YV‚FõqØó±ÂÄÖ`Ç5,kŠaäÉdJah<™Ì (q<Ïe2é¡(jhûŠF%âñ$–5 )`°&—«0ŸOÉå„•jó¸b£ #I’$Óí^‡¤+1°,ƒÂÃd(Ï×xõê3‰TøyjµÎ(•ö­L>_cÿ!étxšdRX©R©\˜Ë8;{L¹¼O¹¼ÏréH¤°Aœfó;;!ýR`©k“Lf(•öY,lšÍçK;˜3ö\±y²¬1‡'v»hšNBO±rÝÀÞVEVÎ9¾“929xp„c9ä*9Ü…Ëb¾àÞ÷h¾hrïÃ{d‹ É$Ýé”ïÜáþ§ÿ7?zÀÜ´yïôþzMBQxz{˨e³Ìßó‰IýÙŒÕrÅ?{Æ×þ5“Þ„½{t.;,æ R¹¿û?ü.ñTœþMŸÅbNe¯Nº”æ«ÿñ3 å*îÂÅ].‰ë ½ŽèŠé)ŒÇ=Ò邨Рg8sËšÎX-W´Û¢L´Õ:#;BQ4ú½F£©TŽÁàf; lµÕV[mµÕVÿö事ð׉Dê¯ "›Û÷×ë¹aïòƒ¥Ø^lP¾¯çAE£XÜ ‹Åÿó¾a÷ýkÆã.Åâ³™°Ó¨j<8,‹LE*•ûÆÛß<~<žÂu¢ÑH0T”ÈåªL&=Öë5¾ï¡ëb15è9Y†P¡Pz8–áí~¿ó™@„RiEѨV‚mЏmÔ§¹\Ëš0¶™Ïg¡­*UY¯×½ÅÍÍËpS°\:˜æ˜Sž>ýKvwﱿÿ€VëœõÚ§ßo²·w?ÄoBï’• p‰MÖt: ‰c"›²K¿ß$OaYM"èõšÖÖÁqæÜ½û¾ï£ª«Õ MK¢i‰°3•òÈ\®Ât:`¹tØÙ¹‹¦%éõá€JxÞŠåÒ¦R9$‰Òj±·÷€vû‚ƒƒGœŸ?¦Z½ƒe™Lz”Jû¿ËréP(ìÙ5è™ÑQ"@’$ˆ\©T×]„ý2Él’åb×Hf’4ÎΩìì•£" Ÿhàûß¾96©ŸÔyþƒç”ß,S9¬ Çdöw+Ü«Õh ‡¤ãq¾¾¹áwÞ~›ÁlÆícNÊeb²Œò¼ÝF‘ÅVÂuWLSžµZ|ú‡Ÿ‘.¥¹üò€?6,æq}þøœé`J¶œ…ܾ¼¥¸[äûÿòûäkyšgWèI#o`M,$Y"“ÊãX·?h„´»Ñ°#nkŽi‘¤Åâžç2› 1ÍQPºe±˜Ón]›-—ù|J"a0¶ˆÇ“a®F<ßþæeÛ$¿ÕV[mµÕVÛŸQ?—6”«Ÿ÷ó²^¯Ã¼ÀOÿwß´ˆml1ªÿkMì¢ qE"‘ Êñáæ$O1› Ð4ÑÇ¡ëiáé/íssó’L¦ÄpØ¢^?a61öQŒ¸y{ l[ãq—XL J}T5¦%˜Í†È²Ìçóª*°µãqÏ[…-ß“ë’É”q]‡H$þ7‰ŠÇqÌ $Þ'—«†áúM)c±¸K­v‡—/?Á0 A'†M¹|€,ǘLúáf"†›§ÍÛúQàZE–|ÅxÜ#•Êy—Nç’S\wÉjµd±°‰F#èzMKJå8?ÿáùNçU“ÍV nY,,,kÂÉÉ{ø¾‡ï $óhÔ¢XÜ%O¡(ql{†ª&«“ÏzíS.ï¸\9È~xaÓ¹¦éaÄ4G€Ø¦¹î‚bq/(T0Œ"‹…E4*cÛÓ0,Ÿ/VøäãßçèèmÇB’ä°€rÓ5’Îgè·»hñùZ{j£ÄFzZ'[ÀsdR?­ã:.ÞÊC’%Ò¥4•ƒ ×O¯Qâ }çml×¥J1³m>ÿü9¿úÑ;D€›ÑˆÓJ…©ãPÏfÉê:Ÿ_]!E£<¹jð«pÑëñÉŸ &TFí¶i3éM˜Ïæä*9ú7}’™$zFç‹?ûTÅÒô´N§q+쎙$ãþPX³Vî " +2³á4ÜVjñW—O¨ÕŽét.I&³¡5­TÙå¶yf¿V«%ét‘HDà±Ue20µ¨TŽX­–ضÉpØ"SI$ &“åòÃaÃÈcšCºÝ°f0¸ ûƒ~êkÍöGËV[mµÕV[mõÓô:…jÓzþÓÚÜ #Ï|> Îb`sÝE¸ùØ -étÉD ’$¶³Ù0ô^X"‘Hø>lBðƒè‹Øä4d9Ãc8Ž-Fƒ63¶˜Lúáa7.„ƒÃtÚILï»f6Ù)ØŽøÔjÇØö,,ïÛÜÊ·ÛçììÜe8l½†9öÂų³ÏÑõ Ùl‰ÅÂf½‚² :Hް¬ ‰Dß÷BÚˆ Îd"Ñe šâÅÀ¨(ñ1J¨jEјÏ'¤Ó%†ÃÛE¼\:A°~aÛT¥rˆm›Èr UM0u8>~'Üv ‡-ß`8l…Û©x<ï•Ë{ôû·õmN$a6’ËÕˆD¢èºhbO&³¸î‚d2t¼D"ÂVgš#²YacÛ p›6¡~ÏsÑõ RLÂs½`“#¾VñxŠ««¯yçƒ_e:˜¢h Q)Êw~ý3ŸÎ©g™Ê[y¤ i¼•ÇÍËôŒŽ¦ï¡guXÃîÝ]*G–ö’L)Ãn!Oo:å´Z%¥i\ôz—Ë|ÿÕ+rºÎÛûûüë¸Âí«[Rñ8+ßgfÛØ®Ë|:çÿâ32¥ íó6¿ûü÷‰JQ²•,£öES` þÚçŸÿ÷ÿ'oÿú;4ž5hœc¤ó¬ý515†3·ñV¢•ýåOH¥r¤3y×Ï‘åÝv“J}ùÌbÐébdÄæd>›Óë5Ø=8a:˜ˆN›Ú.·N`ÿ[0¶ë\†tºÈ`pËdÔg2é‘JåÂçÀ`pK­vÌååWèz: ½Uèt®‚|’‹®§ÃÇM§ t:—AÍ ±Ò¶mþ\%­Û ÊV[mµÕV[mFý­>Þ× ZDî&ƒ±`6ÈßH$4¨‹~×]„6 êÇU*ícÛ3f³a¸ÙØ4d+ŠÆl6 ¸ƒÁm8À”J{aé¢8ìŠöé´ÏÑÑ[\^~ªD¯Ç&H/±8–5!“)Òí^ã8ù|ù|†¢¨(м²4›ÏÉåª,—†‘§Û½ lK:‘H”d2ÍhÔ ­P›­ßoÖ´(²£R9b:°Z‰œÈÕÕ׿ËÍÍK*•Öëu0p$h4žqïÞ‡ŒÇ†Ã6•Ê!ƒÁmøyÞÛ»æ2T5­ÒhšÎÅÅ—¼óÎo`Y–K›Õj‰ªêD£QÇbµrC]<ž¢\Þg:í3ŸÏH$ÒXÖ˜\®ÊhÔ[É7Ce&Sd±°q+ÌÏ ·Ü¹ó6Ë¥ P_ ët=M¡PçææÅâ¦)r<É[ ž$IƲÆ,6¥Ê.’$±rW,ÝH1Iè)ä˜LL‹1ŸÎÙ½»K÷ºKºf6œ¡&T²å,™r&<à?üà“±Iãyƒ{ߺË^>µXPÍd0‡¾ir¿V£3™`ă~–^j&ƒ®iœw»H‘Ÿÿð)“Þ„L)CãYƒd&‰96q.Ц0ÎñÜJ¤L‡Sì™M¶œÅžÙøžO«yM¾XáÉWÉo‡nëMK–<ñÏäŠ" â.¼@)›!en³!%žJˆ¿¾¹yç­H¥rD£2Ói/€øÁÀq'|+ás4OÑï7QѨ® Dw»}B–K›bq—n÷:èæÉà8f¸K$ŒÀæ5Ã4Ç"‡# ÈÅùùcl{F¯×Ø([mµÕV[mõïûϨ×7?oáèÏ*ÂcƒÑö'Ñ€.Ë Óé <@¿þö7¶¯Í€³9èo´XØAÑ¡Çr)(R“IXLE’ĶäîÝ öxÜaµrƒ€µxf³!åò–5f¹7º¶=c2釭ã"[Çu—áÛ n(•oI§‚¶R9 ѽªg:Mì™Í«„[€\®ŠeM˜Ï'¸î‚ÃÃ7iµÎI¥²¨ªN$‰„qo´L¦ìF.ø¼ØaQßxÜáîÝCª×æã»AV"G4*…„²Vëœããw n¿Ñ:/Þ_•ù|J<®atqÀÏ'¬V+EÃq,dY¡P¨‡-ä;;§Ü޾²¦a?•Ê…Ö­h4J"‘¦P¬ãسÙËS,Zbv:)&1›Œ» uò•"Î\lê’™$K{‰–ÔXûkó»÷w™ö§D¢Œ¼Á¨3¢|P&‘JнîòkÿÑG,W"Ït§Tâþì>úà "€çûR)tUEÅø“gÏ0‡Ý|žÐ7M*é4Oί9ÿâœ\%G÷º‹mÚ(ªÂr±¤ßìc ¦ý)ó™…‘K3ŸÍ1òâÏrճьt1븘cßó‰§âÌ's’Ù$ýV—„žd8h§Â\Ît: € …`ÐešªÇ2Çt»`Ëõ£qƒ¢ŽÇS!ìàúú)²coïAHbS•~ÿ†ÓÓ÷ÚzýDZÂ×®M!åt: Z=d>ŸÑh´ƒM§Žß¡Z½l%â¤ÓEæó)…“‰¸Þ`|]wa[—Êééû|õÕŸ./¿¢TÚG–cŒÇJ¥ýàßç ZH’æZ|_4†ÏçSgN*•¥^?%S1Œ<¾ïá8bt+Àç.ÃÀ}.W!›-Û‹Š"Âÿ©TŽ^¯A¡P'•)jœ}N>_ãööŒ|¾F¹|ÀõõS–ËuHÐ*wª•„ãÌ©TŽ nÉåª!,‘L‰Fc2·×WÈ1]6$™“‡XÚKÜ¥Kº¦sÝ&_Ïã¹ÙJ–ü¤D¦˜ai/1 ¾ç³ÿpŸ“:¶å0θsºÇ§ñ%ÿÍûŸ’Ò4<ß§9ÒùÖÑ¿÷ƒÏ(Ûfb‹­]ÿ¶Ïu¿Ïåóý›>’,‘-giæøî›Ø¦Í`p‹eMÉ |úçŠ,+”Ë<þƒ ÀÒfg}—vû‚~¿‰ï¯ØÙ¹ÇÞÁ]š×¯$)ØzHôû gÎññ»\^|‰ï¯é÷d2%LsÌl6 ­T³ÙXL šæW¤Ó… ôß pËâ¢@–Lsb©'“.¦9-ˆ¢ÄÔe2ƒèf˜D¢ÌfŠP«ã8fPDêÓh<£XÜŶM眞~‹Ñ¨eC‹âæ ×kÐë5B‹×ÏsA²P¶Új«­¶Úê°~ÞmÉf0žþo¶²ÿè±D ]Ó’d2¥Ð‚þ¨ëdSP¸A¾nniU5ÁÁÁCF£‰D:TæóµÚ1“I/ì#‘$™bq—åÒ ÂÜû²ªÕ£ð׫ՒT*¶‘oMûû‚ÌŒ(†Ó4= ËoÚÕÓéb@©6µ^¯I¥r@4*Q*íáû^°YYãºË m½K¥rÄriã8 ñx’x<‰ª&‚Á!ô¦ ÈdŠd³,kŒeMд;;w™Í†aöãÑ£;4ÏX¯ýÐj%Ä+ CÜ®/—6étÛ6Y­–Á ˜%›­Ù™ý $rF㪧\ÞºAä ¹}—ñ¸‹ªê!•¬XÜc½^S,îâû~x ž+TˆD"¨q•WϾ$OR?8àé?¤TÚçÑ{ߢÓgïÎ 1%†5±%5¡rp÷„Õr%ìMkˆ§â¸ —t1Íéû§Üûö=î>8äâü5¡ÒoöùOþÉoÃ!õl–ëÁ€w÷÷ù˳3:q•\Žÿ·;Æõ<¦I6ã“OŸrûê–¿Š~Ìj¹âå§/E®#®ðòÁ>/µG\=½àÑGoröÙ™°‚Mæ!þØ÷=<ÏEÓ³<ùä3Nîòé_}££· nÜ“ ãäóu&“Ãö@ ’ÇÓÀòä0Ü2¶èv¯(—é÷Ôë'Á'¾W‹y€%žÐj#I2××_³³sMÓ±m± n¹ºú:°–xóÍ_ ‡ÈɤËri㺠ÊåZ­s"·n·/ØÙ¹‡i™ÍFAI€Ä÷®È„m¶–’$ã8¶=CQâäó5®¯Ÿ²Z¹À0 Aä‚l¶Âba“HŒÇF£v`›·â²ãòòKÊå #®‹útÚ§Ó¹¤R9B× ûá„6ß_“Éi6_ Ë ù|•NçE‰‡å’›¬Ž¸Ñ®ÑnŸS¯Ÿà8Õê¦9¦Ý¾ Z½Ãjµ¤×kÏ×QÕ­ÖY0 -™ÍFAø=N±Zc:œ„CN:›ÇšÍHæt‚ž4ˆD#(šBLá¹q#N÷ªC¶œCÏè o‡ÔOë˜#ß÷9~瘽Ó¢‘ÓL°–KÞ;8àf4"‹ññÅûù<}Ódæ8<ÚÙá¾ÿ)zFgµ\ñëï¼A{2adYØ®K¿5`1_йê`›6«åЍÅ[y(šÂàv Êg6Õ;UñûõZ„ÎÞm[ m™•»b:ˆ¶z-N$¡×m†‰\¡Ì¶™LúìÓmÝày¦9 ;u²Ùr0¤ˆ¼ŽÈ‚Ä)–ê\_=#“)ây£Q‡ÝÝ»ÜÞžáû^°y’‰F£¼xñCømz½«•K*• ‹:7yEQY­\$IƶÍ0#$,Œ#úýét‰ù\tÅD£âmmls–5!—«Ñï7±,ñuÏf+!Ä`½^“Í–¸¹yE:]zh L§ƒÄFÃ>žÙlÄ|>#—«0w‘åX@r»!ây¶=ãààQxY‰ ™mÏDYäjI«uþ7¾~m7([mµÕV[mõP™L €d2ƒiŽ<ë28H¬Âá$SC:ˆÖL¦D$E’bÁ#ÆxÜ%‰Û‚8–5 ÿÿæ0-BåÓ«[©áy+2™†Q ›-#I2étFã9åò‹…Åh$P¤Éd–õÚ§XÜ Šò:t:!1jƒèµ¬)ét;wÞæüü1†‘s%"î¢i †Ã6‹Å<Üj8Ž…ãX$“Y Û6Éç£äóµ&Õl>gÿ!Éd6°ÊØÄã)z½fÐZŸ¡Û½&•I&3Ü»÷íÀÖâ³\Úèz†FãYøy˜ÕɤÀÕN&}òùz€½•0Œ¾ï³¿ÿˆá°Úâ6Í皦J¤ÓÅŸ+¬9Z@‹’ËWBß?øÜøÖlF©^#mçiß\‘2r$³IÌñŒt.‡“´;ìž²°ì?Ü'¦Äˆi1Î>?ãÁGH"W¢&T*ÅëuÌÅ‚Ç××Ü«V™Ú6Š,SN§™ÌçS)¦¶Íh>g<Ÿ34MÖÀųkžÍ_2¸•£üáèPâ g_²wï€ÿí¿û_8yóƒÛ¹jŽçŸI6W&[ÎrýòŒÅÂæÞÛoѾl±^¯IfRøžãXüÙï}—|¾N6W±ìжäû¶µ¹Šfã ýÞM°Aˆaš#%Îj¹ 3O£~Ÿfóét‘XL  ‚båû>ž·ÂqÌ€L–æòâkz½F8ØÛöŒn÷šÁà†tZÐÚb1%„1ŠÙ2èeÙ 7m¦9¿‡6[ ]YAx»ƒ, BÝriÓh<#™];¦9"‘0xùò²Ù*…Bn÷ UM°^û¼xñ1Éd6€5ˆïŸÉD-.— $I!“)¨à£QI’Â Óæ{§Õ:'•ˆÅt=|HA8>N«uÎÝ»Ðë5ð<~¿Ál6¢Z=b<îë´Û— õŸk«û ·AùIeMm7([mµÕV[ý¢éqƒòúöD×3XÖ8@åúæ·H<ž¤Ý¾6ly†ÃvhYŠÇ“ÌçÓ;› «‘(4ÔÄnÔf½^“Ï×é÷›ììœ2÷ð<7´mJî6An»‡õ|¾Üþ7ƒà¸Á|>EÓô ß1Ŷgäóõ eç Û•Àþ®˜NIjshŒD"ŒÇ]nn^‹)¤ÓEt=fdDcú~h¹ÚlŒDÄe<î²»{ß÷pÝ%ª'‘0Âm’°[øôÓß§PØ%‰ðàÁG 7Èr Ã(²Z-»¢i{6`µr©×Oèõ¤ÓŰÅ|Sžèû>«Õ2€ Ìèõš‹»á¦J’dž>ýKÞÿð7±Í9Žc¡i:··gììœbä ú­®ÈŒ”ëâÖ;§z§ÊËO^bä rÕzZg>›óð;‰D"üÎ{ïð?ýß%žŒóÛ¿òÓä¢×c¹tɧ 4YÆ\,HiR4J5“áªßçë¯Î™îu—îu—IoBù ,‚äyY‘‘™á­@G'³I®Ÿ]¡I¬©I¾Z`Ü£h ÎÜf±˜ [_­‚¦k\<}A¾\Áš˜á¡=i¤ö;áç#ed™Œûá°mÛfø¼ò<Ñ•³\:Üܼäää]$)F»}<§áæoƒ6Í‹…è—i4ž›pÝ¥h÷\ºÝù|Û6ñ¼’$ðÓÎ%†Q$›-Óh< ƒáý~ƒ;wÞáââ‹ g” ›ëAlfæsS €wïÒj‡èéõz繌FÒéR8\ÌçÓ Wµ`¹tˆF¥ßÜïßP«Ý!S¹¼üŠtº öîkå£kgìî êÛb1'•Ê…ðYޱXØ\_?!OQ©†Ý:›K‚D"lá–FÓáyn0ÂnŸ««'b"+Áð-.:~®×Õ­Åk«­¶Új«­~±Fý4»–èXýµ¿ßP²69Ã(·–>Óéàµþ«o<^.W ûB6í粬0ŸOÂ<Ê1»\ÚȲŠ$ÉL§¢XðõÆwQž˜¤Z½Ã`pbI7Ä/Q°W6 +F£6Ùl…^¯A2™ew÷ÏŸÿ€bq‡õz´¯KD"Q–K›D"Ízí‡Ä)]O‹iø¾G¿ß$•Ê¡ë‚v%èDw˜Nû¸î’õÚ'.2µÉ媤R9®®¾&‰‹©ÁÆF”ÓÁˆ°\ÚawÇë]-‘ˆ@'›æ˜jõ½žÀ¯Š¬À’ÅbÎþþÃð¹¹yÎäŠ,l'ÈBx¤2iúš¦“H&1ò«åŠÕJ†%Y -N #AõN•ÙpF*›"_ÏS?©óøó_þÿ13ÛÆZ,ȧR<½½eẼwp@o6c L“ÿðÍ7ùgòçX‹Þ}È‹v›Ë'W̧sz…ŽéÓb o‡¸ Y•ñWâc¶‡x+/°îÅÑt„‘@Vd¬‘ETŠrñòY8$’IÌ©° ærU¦ÓAPÚèQ«“̤èµZ4ϨÕî0›‰þæ œHé<ùò/ÃmÜíí+r¹*××OáZl§Lƒ[2™Rxèîv¯Èf«Aç€hT zX"˜æMÓév¯¨×Oñ}MY/¾øc>üˆÕÊÅ4E+}>_C×ÓÌçS–ËEø''ïbÛ&Óé€XLØÍ6Ŧ£Q›zý”?þ.ï½÷[´ZgÔjÇŒÇ=b1…vû" ÄÖS íâù˜Í–ýãXÝrôÜÉdŠøþšh4l# XÖ˜XLX.“ÉL°½ØÁ¶gaÇÎ&C¶¡¸yžû²Îbq—~¿I4 rf¢A¾R9²ƤRyÆãNðÁ0òFñ¸C*•£Ù|A4¥TÚã³Ïþzý„n÷ú'¢Å\[‹×V[mµÕV[ý-‡‘“ÿ“ GP³$¢Ñh¨Þü}>_c:ຠE#•ʾr_£(Zøx®»`2é‘Í–qÝ%¦9"Ob…pØÙ ~mÛ$›-£i‰ 8,†“á°®§±í÷î}›~ÿÃÈ3™ô‚·jpèñB»Y¡°ƒiŽ¨ÕŽé÷o^;€º!¾ôôôý*”Í–1Œ"“I—ÅbŽaäÉfˬ×Ðh< »P%Žï{Ìç¢ù}:íszú-f3á¥64' ÿn0ÁÅâ.©T.Ê Ò•iŽC,êÆ²µZ-Q ß÷ÉdJôû7A+» ]^~É;o¡§“XëµÃrMÜpgRÜ\]pÿ÷‘c2³ÑŒl²„9™røð7¯n8y÷óÇçìŸSÜ+2îŽyðKˆ'ã|ç­ôg3X¯y~Ñäí{w(¦¦våû|~}Íi¥B^×q,‡˜$¡È2ÛÆõEÿJ‰ù\lê§ôzMîßÿ%<ÏegçÓ‡™£\® Ø*ggŸóÎ;ÿAЯS¦Õ:§TÚ J¬VK2™b0°:¼ù毰»{n÷šBaˇT¶D"”‡¦ˆÅ4d9DÈdÊ\^~I>_ p×Ë¥øþ^.8Îf«ÃuÌç3¢Ñ9‹ÅE‰ëÀÖ&pÏ"Ì Ž!eËóV,—ét1´ŠišÎõõJ¥=jµT5毎ŽÞÆ²ÆØ¶lgž’ËU9;ûŒrùɤG³ù‚ÓÓ÷±¬É7^‡¶ÊV[mµÕV[ý=è' ŸCËæñ7ÃÈFâ6× ‡‘‰T°Yƒ ‚à×"4Óãñ$ÎÙl ¼UÖõ4«•K>_Ã÷}¢QAÊ:<|€XL#•ÒÞ…årÁ|>!SI§ èzšýý‡Á!H¥Ù|Îééû!¨Z=âòò«à ä!I± \Πó‚À¥ËUƒ®Ñ¿!I2¥ÒA×3L&ýp8Y¯E£»ld …:Íæ b1H$ÂÞÞ"‘Hp¨T‚#¾ù| €~¿I2™a0hQ.„Ý›-O.Wåöö‡‡oâyn€?Þ´µkèÉ ÞjÅ;þ {·ò¨V8xt†¼Ó…4 #A*›âî‡wHÓD£QMáwÞ~›ï>~Ì£òÉ$ÿü{Á·ßºÏĶI( ®ç‘ŽÇY¸.žï£&TÚã1Á€ÛëÃösdòu2θ7Æ1žÿà9³áŒþM5®b›¢ pé,q,‡ñpÀÞé!­«©Q5¡Òj\‘Îi_¶P49&3 ™MÆâ8Ǹ?d8l'C¬í`Ðb2éqrò–5åüO¿àÁŠ!×ó)•öBkÛpØ Âæs&“†‘³?''ï‹iôz ÖkŸBaI’òÏù|<'U=úåÀ¶(#Ë1"‘HH‚[,æL§ƒ lR`x}ߣ۽Â0òXÖÏ[Ñj‘LŠÅ«WŸr|ü.WW_‹iÁæEØÇ„½Q¼D×Ì:ÀYû¼eƒaBåææ%ñx I’B\u:]äööŒ\®Êx,,jË¥Ãîî½ðýtœyØÊ.,`‰p»#67C’É\Ú_­D b:]`±°Qñ1žŸ?æèè-t=ÃpØboï>/_~B«uF.'ÛggŸ­ñºÝk,kÌz µšØþ WÛž1ŸOñ}±ÛÈ%ž7d8t(vÈçka·¸¬0Y­\l{†m›Øö,x2„M/™áööÕv@Ùj«­¶Új«—´(^N@Ø:âñT8¬l™ÅbN"‘bµr n‰ÇS¬×‚eÛf@®J±^CµzÏó(•1KlÜ5ºAîîï?d:틱m†yE·¦Åâ^€(•h6_ppðž· ­L‘H”££·0Mq«zxø½^ƒjõ£Q‡ƒƒG¡µlc‰|žÑ¨Ü`‡3ÊW” ŽÇÝ`C”c>Ÿ‘ðð#pkV«Uˆ®VPÕ–5è\5A§sÉÁÁ#t=ÍriS*í!I2™bŽÊ^n³M¡P§¼[c6²sw‡‹¯ÎØ?>EOëä«yæ³9õ“:ÞJôy,æ Œ‚Ááý}Jé4¬…åf¾XpP(K&‰+ ÿÏ_ðîÁÉ„˜,#G£øë5Öbëy<þ£Ç(ªÂËO_R;®qûê–O¿÷W¼õÞgÜaüA«Gi·‚c9D¥(ÖØBÕU:7 òÅ*—ÏÎ02YFƒ.’$¡(q-Ÿ•ë"I"ÓÑ|%nÇ—‹DÄçºÛ¹&Sqº&õæó ѨL"AHƒuØår{{†ç do$ žW¬a6N‹‚ÍÍ×r:LfˆD"8ŽÆ—KEQQU/øú-ÃòMIŠáy+†Ãù|Çÿˆ7ÞøåÀÆ4 Ë*7wEù¨^¯‰®§ÃüS±¸‹çyL§}vwïÓl¾`>Ÿ ªq2™Ýîu¸9Ø|Ol¬Hªª¡ëYÎÎ>egç.Ë¥(Ìå*ÕªÆtÚ§Z½lmdl{F<žd¹´@…Ãd"Т—Dl-Ÿ?ÿ]OS.ï3ÜR(Ô@D+Ü>n@¢Ÿdït=M¯×pÜ9J¥=,k\&ôñ&ˆ‹©T*GAÂdÒ£R9$•0Í77/ØÙ¹G<ž >¶*š– ²f2™R0¨EH$ŒàrF zM¢¤R9Ç Ã¥Òš¦†Ãªª‘N—ð}ÿçz-ÜfP¶Új«­¶Úêàg”aäqÝexë¸9´o¶&›°{.W =ãâ–ô³ÙÏ"ü-P»õº°µ$éol`6ˆá Þtc¯šN‡$©0´¬ª:ý~“|¾†ª&¸¹yI.Wú!ÆA¯AŽÉ¤G¹|À«WŸqtô&²c:>ÿÍû²$2™®» Ÿ¯Ñé\Q©òôé÷©×OˆÅÔ «rÅr)hKåòA`Zâû«p;´^û ·Fž|¾"u—K›ýÃû4®ž³³wÊd$lD›¦òêa•«'W¨ •x2N®šãöìVl^îïaŽMŠ;EŒ‚Aû¼Í½oßã¨Va'›åÿÝïqòèˆ÷øã'OwÇ|çý7h ” ƒÅjE5“Árl×Å^.™9éxœea™s.¾¸ѹŽåˆ¾àòësöî0LYÌE®a6™P¬•i7drE¬™è´X³Æž›¢ÃCK†¤²M˜9Ëá{>¶5Ÿ/‹ÅœXLe2éh‡tZä“T-ÁíÍ«°oÆq¬`pB$ÎUØ£‘Í–q‹é´iŽ(vH&³ŠwI2™#Ïá'Oþ‚{÷¾­Öy€¢–e%|ÎÚVDZèv¯99y/>:rü c’BÓtz½‘HUM`šC Cdb†Ã××Oxð࣠sT3!‹…ï¯BX„ø÷íà1“ÜÞ¾"›-cš#’Élðyí½öñ$¨×OÛŒFí¢W«Ý µá°fÅÒé"­Ö†Q “)q~þ˜jõ(Üù¾ÏhÔ`4êP«Ól>§R9dµZ†}BË¥Ít: ›­…£}jµcLsDµzÌÍÍ Æã»»÷ñ}/¤I’^J”J{L§C‘{’bôz ŽŽÞ¢Û½B’bÄbJP9B’dLsvÄlˆz«•K<ž¤Û½"—«²XØŒÇÝp`ÝnP¶Új«­¶ÚêHšÔKSçáïãñä7ì\š– SÉçk ‡-J¥½ðP*èUQd9ÆÎÎݰSa>V‹M±âbaÓé\’H”ËûAׂ(¼¹xÕM™œÈ`8ÔjwÂÜÅÝ»ïÓíŠ[öõÚ§R9@’”0T»ikïõ®)•ö‰D„U$QÃíF*•c±˜³^¯)êä e=úe4M´±ÏfC"‘(¹\…L®ÈÚ_“Ȩ̂ó P-°Å’,…áÿúñÖÔ"ÖU‰ë ;´„ÈŒ”NÐ’RL"]‘o•ßâä½ö‚r>Ë·™Ìç|ÿÕ+–Î]SI§yžùŒZ&C\QµGL÷-š£ýfŸ¥½äŸýÓ%¬8ËÞÊcÚŸâ­„½)WË1ŸÎI FkMãâ;ûw°¦¢À®¼_áö¼‰,+¸Ž‹»pôZXÖ„Ýý»4ÎÏD‰ŸeÑë5¨ÕŽÃÒ?MKÒl> Ij‚Hå1èv nÙÙ¹‹mOyùòSîßÿ¥àÐíÜb8¼,—Nؽ!r ?ê©v./Èuˆ¼Žã˜ÌçSb1UÕ‘e%ìd4AxK&3¨j‚ýý‡$ý~Slª2%‹9óù,°.iµ:XÖ˜> ˆr…°ès:R­ây«°°P’dºÝ+dY¡P¨Ón‹ü‡èïè£(£Q‡ST5Îpئ۽FÓL§Ã`3èóèѯ„„,±¹h“NH$ÒØöIŠ1ƒ?/²Z¹XÖ˜x¾ç3îŽû¤Œ¬h*‰þ”L9ÃÒ^b›6ûÐébšÎU‡ßúÏ €ÙpFë¬Å[ßyÄn>Ï_}þ„ï¼+Êã¾ÿùbJŒïœœÐš&Žë2µmz/~ø‚Ò^‰fÁ ßèÓ¾ló§±?Å÷|"‘÷cþÔrPþÙõ IDAT*Ý«.j\%`ŽMðòÉ—¤Ó6àÌþ=Þ}ÿ7˜›&IÃ`:íÓjÊí×è5z¨Zœ^·‰iŽú’Xg" ·Ôë'¬V.ºžf4j‡}Íæs$I¦PØÅ÷=ÖkŸÛÛWäóul{ÆgŸý°¦V;æêêk²Ù ÎeˆLVÕ8íöË¥Úí\wA¡PÇuEnçêê •Ê!óù4èQ»RårAµzÄpئTÚÃ4‡áãªjœÙl‚..³Z¹Üܼ@UE®©Ó¹DÓtb1]OS©Òn_„À‚ÙlD«uν{2¶q݆‘g¹ta‰ÜPÝ|ßc±°I&EFÖt»×ø¾Â‰T0à·I$  =E®–#•KÑ|ÞäΛ§È²Ìå×—(š‚5µxãWß •M1îyôÑC’šÆÿô1ÿõöOøúæ†óF‹ßx÷M>¿ºb2³øÍßü6Ñh”ÁlÆI¥Âg¬<îTX¦Î»]º­7/op.Oþâ æÄ$*Eù_GåÃ2£ökbѽêbä Î{jÓbaÞ#a$ð\Q{Ä`pËáé=œ¹ƒ¦k|ùýO0 Ñõ’É”˜NEìòüëÀ’¤§‚n›ÛÛ—D"RhQhT"›-‹¶ðɈzý„ÅÂf6°XØ ;(ŠÊxÜ#—«`YS|ßãââ ªÕ;hZÇ1ÃCçba1›0Œ<™ Ùl…õz’›\Wܲ÷û7T*‡! m½^õUˆ®ö}qÀóUˆxv]Ëšù9–5¡Z=b2é±Z‰œJ"a„2ÃÈ‘Jå‚<ËA°ÝЃܓp+ŠÆÉÉ{ŒÇ]t=ah·/д¦9fw÷ƒÁMhûÓ4Nç’tºˆçA4 Ü‹…M&Sd:"˜ïFƒ¡Fe6’H(JËš„Íë¾/r+bp›#ËšP«Óé\R.puõ„»¨ªøúŽÇ@´µ/6½^“x<v¡ˆðû2¼\(—E/x¿¢ÁŸ»xž(ß¼½}I.WEQâÄb Ž3gµZrtô&××Ïð<—ÕjI³ù"d2%z½F¸±œLz¤R9R©,Ãa‹zýÛ¶¸¼ü’Zí8„CT«ÇÈrŒÙlÈjåŦs"¬øß÷ xNÕë' -b15´u:WÁ¦IA×3´ZgT*‡Ûe«­¶Új«­~ß÷é¸Eýõú)Íæó (Md|a¯Y1öqœ9¥Ò.Ë¥C½~ÊdÒÛÎçó)åòA8n£ª Ì ²,¦7xÜl¶B«ulgxÞŠzýXãy+ŠÅ]‘Qc z‡÷ÿ?öÞäW’+ËÓûlž}ßü^LdÌLæÀ¬VUõ¨nt7 Ú´õJ‹–V‚í´ÐBôh£–Ú  EC­n@R««³²2+YÉâÁ˜#ÞüžÏ³›Û¤…™[£"Èf̼@ð…?îææf÷Þß=çüÎ5îz‹R©ÁÁ{WyøIÚDÐ+˜§ÜøàãÞ˜Bõ-¶nl1Íø£¿ÇùhÄ÷÷ù—¿øÿâ¿üOÒ~ –Å2Ð…?ýü[• ÓåÝH]­:“ ?{Ìÿv9dÜKSªz§=~ùþ2hx;¿¼Ãj±¢}¥Í_ÞáüñY¾ƒ«ëfÚG¢\c6™0èv±I–0lƒ¿øÙÿC«µ‡,«ôOˆã˜z}›Ã'·±mÖÆ“IŸÞy‡ ðñ ež<¹•E+>åÆ2‹V;³y%ïY³î¿v[,Æyz[’$,3>ùäÿCU5vvÞ¦×;EÓLlÛc4º$ ìQž—u;O­r×ýUÖ ]’$Î Ô×&A°DÓLdYF’d¦Ó>ŽSÂ4æó1Óé03_Xe;þƒsjµ-V«%®[âÉ“[ØvNç8wyKwÏÓëÞÞ;ܺõs&“W¯þ0kN(å»ô½Þi^“4Ÿ$™Ùl”7fÔ4ƒn÷„FcËr1M‡~ÍÞÞ{üêWÿ7oþ-z½úý4%+Žã,²"qïÞ¯øþ÷ÿ~*3+\ðX,¦™S]œ9É¥M=§Ó†açÇ¥i:÷î}Èþþ÷òzM‹23†2³Ù(ë§ÒgµZæ‹õÕj,_䆩éÅ"†a˜[ýFQ”5ö¬rqñ8žiZZ’$ 5=ú+J¥››×s7²´¹âŒÁàœ~ÿ YV²M‰¶]`0¸`0¸ÀuË”Jõ¼Øß²<‹ år‹Õ*µ}/0 ;/”_ EQxøð#êõ†ÃËÜÙ+IÈ]ÙÝ}—Ï?ÿEf`‘НuZªm²cK‚`•G…×nlB @ð[ ÍÏ·óBwÓ´)ªYýÆ(«I£…BÓtI’ˆù|ÂxÜ£^ß"ü¼7-ð°½ýªªe…¬½ÌNwÁîî;™mo…( rW¬R©ž§¡¬í{77¯Ç©ÈX­Ìçc–Ë9øwÿ„Ë“³´\%ÍÑ/+”š%ºÇ]6¯m¢¨ £ÎˆÙhF¡–Ö†üôÿ!íƒ67>¸StØÝnqí¿úç|txHѲ°t’mÅ1eÇAWUþÕ‡¿¦æyÌ|Ÿ0Ž‘d‰þtŠ,IœFüÙÏ>B7tú˜ÿ{œÖ¬”š%þÛÿæd6šÑÜkrùä’e–nuïÃ{h†Æt0Mêu<|I¹^åâñá*d6e–È&–í ª‹“Ü„ ÛI‹å×Õ•z“'og Æj&΂tÁÞ³ó®,+È{µÌf£,Âð6Š¢æÅÒëæƒiSÀ2–å1hµ¸{÷/h6÷ñý¾¿`±˜äÎLžWÎÓ¤Ò4²‹5&“>år3O;¸sç—¼÷ÞßÎ,¥½¼Æ"ö ó”,YN‹²ïßÿ5ÆÍæ.çç²T±!Ož|Æ;ïü!²¬dõ&‡Y„P¥ÙÜÍ;¤W«,—S–Ë®[b±˜ iƒÁEžþ¶\NóÈ`*òºH’D©ÔÈ;§7»t»Çykgç&ggi·òÌJ¥E¯wš7-kÙ»ÂÅÅcvvÞÆ÷_p,pÝrÞ¼T–eÎϳ¹y ×-ÇQn<Ðíž0uØØ¸Êåå®\yŸû÷ÿ’R©™»ôY–ƒmó(E¹ÜÀ²¼Üñ¬Tjdâi QÏ+†!¦§EQz/Ôj[œžÞ§VÛD–•¼¡êhÔ!I¾Ïpx‰m2³„€0 °í"B¡P¥Ó9dcã*‡‡·òÔ Hë•l»ÀÉÉ=Úí+Ìf#Êå6Ëå\@ ~Ç)âºiÍH’$8N EQÑ4ÓtòƇºnd)<ó|P­n°»[âââ {{ïÑí³½ýÃá%|ðOÙݽ‰ã”X.§ùÎl½¾CGloßÈ šÃpEµº‘7Aô¼2õÍÃËõú6ºn±q%-¬¾<¼ÄöltSÇ-Ùç*Á2àýø>nÉ%XT7«ÄQÌOo\ã|4¢lÛ\i4øèðƒFƒ¢eñ¸ÛåÖÉ ®ib²$Æ1÷OÎPu•þiÍÔøÙÿþ3¢0â£Òã9†mðoŽÿMÚ¬2NpŠ’œþ.ŽcLÇäøÎ1Š¢!çÏY,f´÷6éôР˵è]\ລ¼×Ël4Ë›Ø%IêîT(T9?{Œç•99¹‹¦T*i-ͺŠa¤S'³67¯ñäÉ­|WzÆuëÖÏiµöØÚºÁpxÁhÔÍ™âºå,åjF’$†•Y¿Çl6ÊìšU¢(ÊS÷Ö6¬qe»îë4£´gÆÚ&9M%º¤\n±½}ƒÑ¨›õIkÚpï¯ÓÆ\·œ‹œ«(ŠÊéišN¸¶ØM]àÆØvjiv /Óí§Üm/[LkT«›YJâ½¼_I«µÏÍ›ÿI’pçÎ/‰ãËòˆ¢]·òÚ‘8ŽètލÕ6sk`Hì|Že¹´Ûi'ùõu¬(*²¬ðñÇÿ–+WÞçñãÏCŸë×ÂxÜÈŽ{T«›x^%ëç1AUu’$¶=æó …B5³9vP-7HSšJ¹»Uêz'¡iZ.КÍ=?þUÕ‘eÇ)ebGG×M..g½…"*•VÞûIJFUÓ Û.`Y³ÙµI†(@ |ˤi; ±»û®[Êr÷ã¼Ëò`pAµºI«uÀr9RëÐv{?O%J»W/ØÛ{—ѨC»}]7°¬…j_þìß°½ý¥rÎå1æ6’$Q¬ypë6ïýädEfp1 ŽbÜ’Ëî;»,gKJ͵̓‹û7v¸¹±ÁùxLÕqˆ’„¹ïsïäŒfÚå貋møaÈÌ÷™,tÆcŽû}n}|ŸÝÇwŽqJ«åŠÕr ´ö[\<¹`µ\q~rH½¹I¦“ùd΃Ïn³{ía¢ê*Á25Xù+ƽ£Q‡årÆÆæUüåœ(Š˜NûÔë;$IÄG¿ø÷”Ë-4MçуÏèõNùþþ.½Þ);;osûöÏyÿdzãÇœŸ?¢RicXf^<\«må©1I3ŸOqÝ2‡‡·²ÚžÛÛoq~þˆårÊjåe»ïMNNîæ½(Æã^Þe\–Óº’u'ñ´öfmfîÆÇ= ÃäòòˆjµÍ½{²»{“ HÅêz±;÷²ÞóÌÖ9µ…žLzéwst‡Zm“étÀhÔ¥×;ÍRÓ¦Óaæ˜g"bŽaØ,é‚=-vž IP©´:Y-†‡aØ\^>Á²<ÎϳZùœž> \n¢ëfî"•Fþ’<±6tÐ48N]Åâ8"ŠBæóQÞÅ}í‚U«m0qݳÙ(‹"v³üN–~ä1Ÿ¹~ý',—iß›u–ï/¨×·³ô,#·^öý9ƒÁï¾ûG<~ü)šfæMSkf#·åõ¼r¾Ápqñ„Fc‡áðM3×—‡YªSŸju#OÙÔ4ÓtrG«( ó‚ö4ú9d4êd +³ „UÕó1c¹L£~ŽSIJœ¬OÌ‚R©Á`ð€år– ߟóäÉy&Lb–ËYf eÂEÞ¨×;¡ÑØ¥Ó9¢^ßF–>ÿüìì¼Íùù#ƒsÊå&‡‡Ÿ †‘ ‰Ô«ãhy*œm¨Õ63ûp9ÇÎi6÷¸{÷WØvÚ¼³ZmsvöËËÃô^3¬|“d<îå=k¾r£GôAàõÍQ­Ö>’$3^R­nd»âQ¶K,¥ÍûæZ­=æó1¦é²XLèvOh6÷²ú‘k¬V Š• þÜ'ŽcJ ›éÂÆ):<úì>?þ‡?åî¯îRß®³{s§äÐj×pM“R‰ŽøÉÁƒÙ MQÌflW«Ì}Ÿ?áúF›ªërç쌊ër6rqÚeÒŸ0êŒH’„ÏþìStÓ@Qš{Mz'=Êí´9¡¿ðY-VȲÌÙñ’$ac{ùdŽWñ˜§ØžÍt8e±˜RªT™ŽGy1ôús&q‚nê\žž¢ëiapµº‘÷giµ÷8;}˜7»«T[,óÜ®5uJ:Ëÿy^…8ŽpÝGGŸg ÀÍæ——G,—S®_ÿ1“É€Nç×-£ë&IÓï§6¿»»ï`ši/ߟg)Os¦Óûûߣß?¥X¬sxx Ëò²Ýô"GGw88ø~¶ØÓl¦M ëõm=ú+Z­ƒ¼÷Ìú9Åbårž¥?¥Êóùˆ³³‡yôB–•<š‘ žËr ‚š¦³XL(•š_ˆž¤MÓš‡uqvj§{¦é 5Æã4åÉ÷8N1¯×pœ£Q‡ËË'ìí½Ët:DU5ŠÅ–åqrrI’qÝR^PÇår‹ XrûöŸóÁÿ4ïï£ë&ÝîIÖÀ0¦¬k/ºÝãÜV{m‡Ün†iøjµd>ãºeêõíLl¦õ‡‡·ÙÛ{—;wþ‚0\eµViŽ0 Ñu#o(è8EŽïbšvV¬_Íì«£¼¿K’Ä,S‚Àçìì!;;oçbÈ0ì<ú‘ÖÉÌçc¶·ßf6qqñÏ«æî_®›F, …jÞhÑ0Rkð$I¸¸xœõ{yÂÎÎÍl±ïeNfU‹ †aS.79>¾ $,ÓÜ®W×Í,Ím–Û”«ªŽaØÌçã,í³L¹Ü¤ß?G–å¼GÍjå†i}Èb‘Z>÷z§T*­¬~ÊÍŒ&¹¥ršZ·Â¶ ¹uðt:È›[*ŠJ¥Òæää.{{ïryy„¢(ôûç_°QE ‚oiŽrݶ]àÊ•0\Ðlî1›hµö³t2…BÁàœïþ€þE—B¹Ä°×§¹ÝÎ÷MS*Hàþ£?`1YpxûöÏÿ'ƒI’ðý=þýçw¸¾ÑæþÅ–®S´, Mc†øaÈf¹Ì­“®4›<¼¼äî_ÞKw»u•Õb…fhÜÿËû /jEš»M†Cü…ŸG3ÓaPnVXΗkEÓýón¶à±,USé÷ÒFr•j‹( )ÖJtN/ðJE:ç§èº‘¥ÛhøþÎkÆã.«Õ2s©2óFGGŸ³±q•[·þŒë×’ŸKEQ99¹›5Ígoï½|1=Ÿ³"~‰ X’$P,Ö{(Šš§Ó¥Eç*¦™¦ö¥éV›DQ ;EQ°íTÈ ‡—¹Ãžç¥Z†ag½R¼LT•Ã4uëñãO2»_9LÓÉ{Û¤}ffÙu²À²\z½3¦Ó~ÖÒäì,í³¾–Ó´@)skeM˜LúL§Ãì|M²ë® $¬V>ÝnYY×ͬ£1©Ûœ‹iºôz'躕h¤©z ºÝÔ™L’ä\úþœ~ÿ ËJë|vwß¡Û=Îí•g³!“É@@ ¾­9*í•ñÞ{×-á¸E‚UÚ4Í+¹ñÓœÜ;aûÆ6·~›?½AÅü“úGT\—ý³_ñïßäן?àí+;´K%~ýä íR MQøù‡Ÿò?|‡'Ý.—']¾wó ÷OÎwÇ .Ý>"Xl\Ù {Ò% BöÞÙãðö!ÃË!íƒ6£åfÖ[DWQu•ó'§È²ŒaZ覎nêDaİÛÇ0-dE& B:—GùîýjµÌRZÒ(Åáá-Úí+„aïî†E±R¦wy‘;,¥vËz¾`[ïȮݑZ­=>úèÿeÿ=¦Óaž"²µ}Aÿ’^ïH°,/ï³áº%â8ÎAÚm~>ŸP,Ö²E|):œŸ?dµZR«meýÒ~ëT¬õâ2µ°=¥Û=É›æEQ˜[Â꺅¢¨,©+Ñññ]J¥:Š¢åŽHq¼ÎÁOr©[•” ‡2£Q7O}I#6Š¢ä6¿ºn±¹y•»w?ÌÓŸTUçììíö•¬×È€0ôiµ²>9©#“ã”2÷°„Åb‚ëVèt³¿³ù쳟Ñnä}i=ú˜k×~œ/æ×Ýé“$FU &“ŽSb08ÏwÖ×µ ®[ÆuKœžÞÏÒÚ‚,¥é0«³p„Û·ÿœýèåQ”££Ï‰ãEQÐu“fs/E‹)çç)ëL&}<¯œõÔHÓ´Rç°UÕ$Ï«ðñÇÿ–z}Û.d¥i–êõ×µ8“IŸFc‡»w•õ~IòZ'O>Ë› ŽF—4›{Y½O!«ï(Ð(¦i3›ó¨@\¹ò>——O(—[ŒF†Ã¶í‘$1µÚ6——ûll\A×Íì^‘™Í†Øv!·©ÈT…Å"­ŸJSFLÓÍŒttÝ¢ß?# 66®`YnÖ»$µ~^÷n™NYMζ]àþý¿Ä²Éz꤆ëþ>/IQ_u~‘ „…@ ÞÔͬ×=Gmn^ãŸýçÿ‚J»ÂîÕ-TY¦ÓòÞ•=>yø˜ý•?ù;üËõïù¯ÿûÁŸøVÁ¢ê¦“¾¢)Œ Î ·â'ÄQÌÏþåϱ‹‹ÇÞ:d>ž³œ-9¹wÂÑçG覎aÈŠÌé“'x•´FŸù<øèA*B4¯ìÑ;íåu)aâ¦Ã)ÅJ™‹Ócœ‚‡¬ÊL4Cãìì;;7yüè3¶·od]§•<_>\L¹¸xÌÆÆÕl'6Èìc›(ŠÆ£û·²4 r¾øLϹÏbáã8‚`E§s”7¾ÛÞ~+O_Z.g†ÅÝ;R¯og‘'ï ²XLX.ç¹Õn¿ß% Ó(H±XË ¢k|òÉ¿ckëFf©¼`±˜R,ÖÑu“óó‡Ù¢ÖÈ:¡+DQ”»p™¦“YÌ®Ítƒ´3ùÖÖ â8¢ÑØf6KÝÙÖõ“É k8Ïk.‚ÀÇó*¬VKšÍ=NNî¡iÓiêºÔlîszzUÕ3‹ßtG>À¥=R4MÏ;|×j›¹ Lš …ËåŒù|‚ë–rã„b±Ît:È„SÚ—f‘Ùܼ$|úéŸR*Õ©T6è÷O³ù~–:—¦^¥bAÉÓœNNîæØ§52œÒ³“F~ŠÅZVSqç•9:ºCµºï/õÚ&‹Å”$‰1 ›$‰ØÝ}‡ËËCŠÅ†astt‡Fc‡z}›‹‹Ç¹©ÄpØÁ÷g”Ë- …*ƒÁªªaY.ƒAêF–~‡éµ´v’ ÃU~£(dcãjž¶•ZA+Y?"Û.°Z-$9ïõ‘Ö¸”Ë-úý3./óhÄùù#J¥FÞ÷(­#»ŠãtÐõ´‹{jŽã8©©Ãb1Íì‚=ŽŽ>ÏS¯–Ë[[×1 '/N_,&Y]š‰ïϳš‘Ô*z}­F§”ÏTÌmo¿•Gœ‹)Õêo¿ý™ÛÜ*¯¡[.g\\<΢?i—úôúfŽv$©ï/²(Tjvž-*®SØÒš§ñK§ê«ü_G̼ª°à›œs¾‰9êG?ýûü­¿÷Cf¾ÏV‹ ŠX¬VÌ}ŸãÏ W!†eÇ1ÿËÿü Iͽ&ÿÃÿú?á”,×âÎ/ï®Bâ(F–eNî¥Mè}üB¥Èl4c1YÓá4/D—$‰û·>Kwˆ{–³%aâ/–H’Œnê z]lÛEQUüå"uÛ™Î99N]˜§Èb:§X-1ŸM0B;se=f™Uê$s?²³Z… •J›(ŠpœbM˜ÏÇȲÂÉÉ=ööÞe2éå©Eªjäõ"©µiºc[.7yð࣬ë}!·VMû½¤‚©\n1Ÿ©Õ¶/ò&rår3ïÊmÛÂ0ÎQÖ pI‚ù|ŒçU°,/oˆ·.ZNk‡:™“R˜÷¢/Y.§X–K¿Ž®›”Ë­¬x¹M§sÌ`pA¿ÆÖÖ ’$¦Û=ÉÒjT«t»'ض—í4Gܹó ~úÓ?ɇÁùùCdY!ŽCâ8¦ZÝÌÓÛæó W¯¾O¬8<¼•5á{ÌÕ«?Ìë5ž0ËåŒNç8oäiiŠN¥Òb¹œcVÞ£Ãó*YT §H»}»U­¿¯4ò•àºe<¯š;[AZ{Ôhìp~þ8K‹ s×­^ï”B¡N§sœ[7;™ËSj0›2·­i¶øöû¸n‰óóG U†ÃK&“Íæ.£Q—³³8N‘J¥Ít:Ì…WšJºnÐïŸgîZu–ËyÞlQ–•,ptò– IDATò“v«ßÞ~‹å2­‡:9¹—G»ÖÝÅb*2>ùäßQ(TóZ MÓqÝ4 ¶îý¢ªzæÈ§²»ûNnŒ°.n¿sçT*í<=,­9Zei_©Ð,ëYÆïgÆ -îßÿ5£Q—v»Èj•º¥M&ýÜY®RiçMAÊÍ LÓÍ"ƒq.žSai£WI’xüøS66®2Ÿ‰¢ *¦é;Ìç“<-M]ss?™ òfÃáÃá%Æ®[FUµ¬†ÆÊí˜//_nL•¯WÄ_vðUá#‚o‡ïÒÆÒ7%PÄ%ßþ¼¢~Õ@üMOP/óúb‚Á›:™Š9J ^/ê·)F¾ ÅõMó&¥«‰cÇ"ŽEË7y,‚ïÎõ&\;âÄ1ˆs!ŽáuÍ+òëx31‘ àMDÌQ@ðÝã•‹ä_V­»¦®à›âUç1G Áï€@yÑþe»ô@ðmŠ1G ÁwŸïL£F1‘wŹ‚ßý±R§K @ ¼)"@ „@@ ‚gùNÔ @ ‚ßDE @ "@ o¬@yÕn¿¢;°@ <l|•1SŒ½bŽ‚7m^‘ß”ž$É:û¾Îç Áïû$ò¼1SŒ½bŽ‚7q^)^oØEð"%ú&]”¿«çù÷íºúmj¯kÇåM:Î×õ¹~„ç‰@ æá×ñ>oÒ¹þNžwŒ¯ò¸à»5¯¨âÔ¿97àú"x¶Ó¦Xt|;çY|ÞoGœ<ïx¾ëÇù¦}.@ æáß…ÍŽg¿‡õ¿_õqÁw!PÞða½€zÑøôïžþ÷ónÒg_ÿ«^çyïÿ¼ãy•àW Ï;Î/;þßd@ýªóð²Çóu?׫¾ïo:ðþ&ïû¢ÏøeïõMí^½Ìõù²×ƒHÁßµyøËò¿É<ö2Ÿ÷«æ·ßd½ |gÊïËŽþœÏ[ü½hõ¢ž§Ågÿª¿}:ðuì<¼êß‘WY°Ùy~Þyx•ãù:ŸëUß÷u^W¯ú¾/º®~› ‡¯:ObçLŒ½â< ~Ÿæá/;žW™Ç^eãæ›g_t,¯ú¸à»7^¾åEªÿu=ÿ»°SóuwÃ_ö¼è†ýºQ‡¯3°|Ù"ùUvz¾îwþeçùEçóu¼ï—½ÎË^ïßÖçün.²^4fþ¾½bŽ|çáW=žorÁþeóü7ñ¹^u ÄÊww^QߤÁáUnZ1è¿ÚÅõºnØWt_uGûE¿ÿm}ß_÷}Óô³ç}oRCðæ.²^ǽ%Æ^qžoî<üÛ~ß/›ßž—úõª)á/zþ‹æ½W}\ðݘWD ÊwT¹þ&;_çï~“£g/À/ ?oäËvh^W„ãeÎÛ‹ŽçEçëy?¿Ìq~ÕŽÔ75è¾êqþ6w\ž÷7_çø_×q¾ÎÏ%Ä<üºÆ¯“ õ¼Ïû¢9íunƽªpyÕÇß±û.ß à;(d@ oΚGDP@ Á›‚ˆ @ !P@ @@ @ Š@ @ "@ „@@ !P@ (@ @ Š@ @ E @ „@@ B @ Á7ú]8HI’H’I’H’$|ý³@ ¿í9ªZÝà‡?ü‡t:GO§sD»}UÕe…áð’b±ÆÃ‡³»{YVI’˜ÃÃ[ìí½Ë`pÉb1¡^߯²\†ÃKf³¶]`<îP.·ˆ¢~ÿ Y–i4v»ÌfcnÜø ·oÿœÝÝwév™LúDQH£±ÃxÜ%ŠBLÓ¥VÛ$ ƒì5%Ea<îQ«mñèÑ'X–K¹Ü$ ..P­nQ ª­Ö£Q‡^ï”ɤ€eyX–C’$ hšA±X# F£.I³»{“á°ÃhÔÁ4’$¦P¨ÑížP©´èõN±mù|ò׋UËÎA/ÿ·¦,Ó¿±°,( $ߟ#Ë2qç¯U.7Y­–Ìf#ŠÅ£Q÷»>E%ŠBq£¯2®&ßþ— ”õã@ ü6ç¨ýý÷h·¯`ÛÂ0`:íÓj°\ÎPNçFcðq Óј'O>cÿ{ܺõgìì¼Ír9cµZE!Åb Ëò89¹ÇææUNNîãº%ƒs$If¹œQ,Ö(jœœÜ£ÙÜcµZP©lpyù„ÕjÉdÒG×Mz½LÓEUuŠÅκn>¥Rƒ'On!Ë A°DUuEe8¼¤ÙÜÃ÷çDQDø´Z{,—3¢(d±˜µÚ——‡\^>agçm./)똦ƒaXt»'”JuÎÏá8E†ÃKdY¡Ý> Ó9ÆóÊÁ Ç)2÷ .Øß££Ïñ¼ A°D–UtÝÄóÊȲÂáám Ãf8¼ÄuK¨ªN§sÄÞÞ; ‡|iÚ˜¦Ãùù#Z­}z½ÓüÛvãã»´Û¬Véç ÎY­–4›»Á UÕðýI’`š‹Åð˜L„á ]·‚%†a1›©TÚôûg¸n™årF¡PÉ…æ`p@©Ô`8¼üדi:,—³Ll¹ù1­Véû«ªFùó§H¬VK’$~á5ú¼µÒ³âM øN ”WX¼.ñ¬@yÞÏ@ ü6Êõë?¡ÕÚg<î±¹y×+¡¨ ²*3ŒÃ4ò`».’$¡›:ŸýÕ/ØÜ¼†¢¨€„]°¹89&IbJåÁÊg2P,ÖQ5•å"¸¥ï߯uKx… ’$1EÑðý†aEËåEQY,¦ln]åôäÝî1»»ïpyyH½¾®›t:G,—3¶¶®sqqHúT«›,â8f±˜P­n0›9>¾ÃÞÞ;ùb[×-§ÈññªÕ $IÂ4]|–Gf€\àÌfÃ\\Íf#â8F’ÀóªL&©8™ÏÇx^ß_0Ÿi6wétŽˆ¢EÑò(Óƒå¿sœ"®[Æ÷çÁŠ ð‰ãÏ+s||$‰i·ò…ýåe*?ùäO)k†,+(ŠšE€t’$Áó*(ŠÂ|>AUuNNî år“R©I·{ HÌçcÚí†Ã dYEQTÊ嚦Óë2Y,&x^ÓtÐ4“ÓÓûùújkë¾?' W,—3l»Àl6Âó*ŒÇ=%=¾$IÃYN³õ—Ëšfâûsl»À|>@UuÂp…ç•™L8Nðé÷ÏPU$I0 ‹ù|‚$I(Šš  gÅÐó®}UÕ M3ÿK׋ÏFÇ^…嵉יŠõç«Þ_¤Š à7£¾ÿý¿G»}/¨·¶n°ym“óGçØžÍùñ1ÛW÷Y-W–Ár¶$Žc4CãøáC æ½·Ål4C–eü¹St¸<=£X® +2«åŠ^÷”­ý+,Æ 4C#Žc’8ÃR£ÐïŸS©´(ÕË„AÈbº`å/ºÁ’b±F¬8?ÄÖÖu4Í`>Ÿ0u8¸ò=FãQ×-eQ‡G>æ­·~ÊùùcdYb±˜¢ëVž"U.7±,—0 P•ñ¸‹¦™ŒÇ=êõ-æó1“II’©Õ6é÷Ï(•šÏ|>&IbŠÅFö Ër‰ã˜é´,+H’Ì|>ÁqŠÙ=F–•£i:q£ë·oÿ9››×‰ ðsa¤ëFá2 EÑP•ÕjÁd2@×ÍLL(ŠJGùçPõ©ÈÙ}â8ÌŽ¿„ã”rAèû³Ld•X.§„a€e¹,—s\·ÄxÜÃqŠŒF]\·”Ëå Ëòh4v89¹‡iºL§,ËÃ0Lƒ ¶·ßæðð’$£ë†a³Z- Úff³¿Æ4¢($|<¯Â|>F–\·Äj•ŠQðñýù߸w,Ëc¹œþ5X*ØÉEÉZ †…ï/òç=+ ÖbLðÝ祋俩¼$I_ùßËÛ³Ï}öx_öµž}ÎËü@ ^~¬Ñᄅǿê˜^{{ïRk¶qÝ2?ùÛ¯âPÛ¬1ê ©6šÈ²ÌåÉ á*Ä.Øœ=AÓ5Ê•&µVÝÐQu•^ï”ÅlÁÆÞ6vÁf:G1WnÞd9]²XÌ@±DÑ¢(" WœœÜ£µ±‹í9L‡Sâ(f>›`».õÆÆ. cÛö÷ßC’dLÓ¡X¬²"#I››WY­–ÄqˆaØT*-vwo²Zù´Zû4›{Ô›[¨ªÆjµD×-l»Àl6ÂqÊÙb@b:Ðjíç UUÕÑ4'On+<¯Ê`pÎ|>&V†ÃjµÀ¶‹ÔjÛYTÆÁ¶=4Í WØvßOŸóÇü†!–å"IE››×)ªH’Äõë?ÀuÓô°0 °ííö“IŸ$Ih4¶³ŠaØŒÇ= …*¦é ( ¶]À¶=f³1o½õS’$AÓ tÝÌêbtæó ®[Æuˆ¦Ùù(e‚b†i:x^%‹fXÄq„iº U<¯J¬ØÜ¼ÆÖÖ ¦Ó áºeÂÐG’ XlP*¥5B­ÖAžVX*5ðýÆËå ×-¡ë&²¬°Z-qœ"ŽS"Ž#TU’<³XÌÐu3_à'IŒi:8N1øX–ƒç•iµö1 I’e™vû€J¥G°TUÏαO¡P#Ž# ÃÆ¶ †• êåŒ$I°,ËJïM3ˆ¢M3ò{+ŠB§øq’ë³Ñ—[«®àw@ |S$Iò•ÿ==™<ïñ§_çéhÈÓÿ~ú÷ÏNPÏ>.DŠ@ ¼^qò¢qøéß}¿Ì1½®1~4ê"I•fp¢›:«å ·â²}cÝÔ™çÜøá»è–Τ?៼né覎a§ 2UWQT…ÍÝ,ÇbÒŸø;oíQi¥é\ÅZ‘öî&QaX&²"ã/çxÅ2üOþqžB¦j*’,aÛÃ~'}}MÃ4m[-’ªÍTY®ÅÖÖuìBšæä”\*•6…BÇóxëEQú𒄦™˜¦fh躅i:„á Y‘i4·)–+†ÃÞþ»Ç)eQUÕÑõTøÄqÌéé}ªÕMÚí+H’D…èºÅÖÖ Þ~ûo±µuZm“z}‡ù|Œã¨TÚ¨jšâ¶Žø,SLÓ¥×;E×MÊåfÁKâ8"ŠB’$M\1¤"HÉRÇVÙý&å" Vhš@¥ÒB’$–Ë•J]7ó{V–jµ­|s¡X¬eÓ Ss„unÍúúzZð|Õõ³<û‚ßqòMž¯úý‹vòž—*ölA¾@ ^ï¸ü¦‹«—ò¯ Ž£0¢¹×dÒŸ ¨ nÉ¥P+`l¢0ÂtLV˪žîâÆQÌæõMì‚[vQu•ùxŽaXžE¥]¡Ü,³˜,VAºkojx»`Sn•©nT1L;7šB¡Z@34$YB–d¼ŠÇæþûïîã•=;Mü¹a˜”ê¥tq„©Ø‘e$ dI¦P.’$Ä Š¦°sm˵h6÷²Å¦L° h4v¨5Òít2° º—§(ŠÊhØåþÁŸP*5PT…·Ó:7݉OâÇ)æµ q!I2š¦S©´òHÄÓbcÊ3Ñ4×-瑌ÝÝwÐ4ƒ'O># WÄqD§sD’ÄÌçcÂ0 ŠÂl‘nä‹öµ ‰ãˆÕjA躑¥t¥‚a6â8%ªÕ6årÃpÐ4Ërq݆a¢ißàÊ•P(T²z 0¯ùÞ÷þ[[7Ð4ƒ­­”ËM–Ë´^'IV«AàS©´ÙÙy]7‰¢årFGlmÝÀ0,dY¡RÙÀuË”ËMT5‹ÃáÛÛo±¿ÿ=dYfÿ½ìsùY½H‘Y­–Y­Š„ïÏÓ”°ÝÝwX.gey‹ ŠÅår‹ù|B¡P% C‹år“££Ï‰ãT8êºI½¾EE8N ð©×·i·¯°½ýVž2æ8EÚí+ìî¾ÃÆÆU@¢P¨æÏ—$‰0\†A–.¶¤Ý> ß?Ų¼,š’þÍÓ‚#Ib]dYÍïËõïeYÉŸ—~§2Š¢¢iF>N½Hˆ†óÑ#xÃÊë‘[㳑˜/›@ŸÝe{öÿ@ xù9ã»$X^%ʯ(“á·ä’píG×0,ƒ8Šœd‰+ï_!Iœ¢ƒí¥‚E–e¢0bµLw— ÛàÆ7pË.nÉe>™3ì Ù¼¾É¤?ư 4Cc>žSn–±ÝT˜HH8E‡Ïy+º¬–+dUFQ’8aÜÇqZh­*”›n}økªU? ŽbŠ"›»„aˆ¢+466Ð ÅtéšÄIŒm{ì^¿J}»ÎhØC34,Ï¢Ü,So·˜ Ç 5T]E–ü™Ÿ¦:MÇ8R¥ž»bi†Æ•·orå­wRÁøèºAL&dYÉ£(Q`ÛŽSàààû¨ªÆÅÅÂp…ã”r·¬VkŸ H‹ÍwvniÑ¿ï/òºŒfsÙl”9™­²Ô.++z‡ ð Îñ¼2¥RÇ)R.7‘e%‹ª¤Ž[²¬°\Nó´­0\¥‚LQ(jhšÎææuLÓÎÓšºÝc‹ «ÕEÑÒt¹ú6ÅbVë 7/XÛ0Cj1=™ 8;{ˆ¦™‹uf³år“ét€aXŒF—ln^G–•ÜV:Š"¢( \nP.7³ˆK‘ÅbBEÌçãJ¥I’Ðlîæµ$–•¦¢¥Q–õú7n|™TQU=«³±q%ÿ¾Æã.¾?ÇqŠY$,Ä÷ç,|†®XVZ@Ç1år‹0\Q«m}ÁÝMQ4æó1­Ö>³Ùñ¸÷”w LÍ âÜím}Ÿºn M3pœBfç‘"Ótr!©ËÚÓÌfÃÜÖúÕÆ<Ñrð(¯º(:Rñ¦MF_&Zž>ö¯*¬ÞÏ/zìY!'Ä@ âäw‹F{“ÆV‹ËÃKãE.œ¢ƒ$KY:–aè†Îl8ëx,gK¢ Â):Þ>D’$ÎãU<ü…åZ˜ŽIÅTÚUHÒ¨‹$KH²Äåá%¦mÒ¾Òf9]²}}7­a9ï`{vú<)­-ñ>…jùdÎt4Å_ø©C˜¡"IPݨ²œ.Iâ„Õb…?÷ó¨P¹YFVdLÛDQUtSÏ¿[USqJH°Z-ˆ¢ÝЩ6šÌÆSªí:IøAz. EQ™M&DaR* …J–æ‘“~ÿœ«X–G§sÄh”à˲Lsc›VkUÕ˜ÍF¨jzL­Ö>õúÛ;7ÃU™X²¹y-[”O²„­ëL§ƒl‡=M_ó¼j–u€$É™5sZã‘Öë¤u4©KWšž7ŸO0MÓt ÃU^<¾.ÈO]¯T<øÏ«`Y.Š¢bۆË\48N1+²·ñ¼*Æ­ÖwïþEQ±¸¸xL’ÄÄqÌýû¿f±˜æÇãû f³!A°DQÒ‚õ8ŽQUѨ‹ªj†E­¶E¥Ò¢VÛzªh?uI³¬Š¢¢(J^S¢i:®[d>ŸäÎl¾?Ë¢^i„)IÒ÷ñý9ggqÝr&²ª„aÀpx‰m§Á²\‹)žW%I’Ì –Ëi&ÎÒZ"]7;Y½Š—ßs­Ö;;7ñ¼ ºÄ¥bb„$AG 5\·Œm{„a@’Ä™]szÄq”»¦¥×rEy:*ãºå/_LË ŽSxÁÚò‹6Îk!$øŠùâ»ÔåËÄÅ·5‘>]³ò¼ÜåõhyÞß}Ùë Áïƒ8y‘ããëüùysÇ7á4ùŸþgÿá*¤¹×D7ôÜ]K·t¼ŠÇÉÝj[5$YbÒ›PÛ®úiÚÏr¶¤P+pç—w¨m¥5,ª¦2ͨnV^ ñ*£Îˆ(Ѝ´*¬+L×$\…(šÂ¸;&ðì¢MÆ,çKLÛ¤wÚ£X/2L)Ô ¬+¢0"IÊÍ2gΰ<‹ÞiÆNƒ(ŒXL8E‡8Jʼn¿ð‰ÃUW ƒ~ç‚b©Æb>£¹ÝF’ÓÈÏèrÄd8Æ)¸t/ÎÙ:ØcÔ!ÉÃA]7inoððóÛì]»åZôÎz„«€ÕÊDzÆ£>šfPmÖYΗŒ=š››(šÂ¨3âôô>›W!>â{?úCf£$ +2½î…Bߟcš.qK|A­±Ád4@ÓLl×I£V²D¥NZ’,q~öH°k7°ñ¸—;}ɲÂ`pïÏñ¼jE™ã8%¦ÓA^+‘îî÷qœ"µÚŠ¢srr7 A¦[5;L§CÆãníHë`Ö‹Û´˜ßËÍtݤX¬±\¦Žai͈J¥Ípx™÷C™Í†DQD¡F5f³Ëå_‹˜0ô™N‡$I’ÓÏfãÓhìpqñ×-cYi Œª¦Q']7yðà#¶·ßÆ÷gt:ÇØ¶—÷©±m/‹Ze9DQzì¾?ÏjŠ´¼˜6¢ª¦é Ipyy„e9_°E®TÚ$Iœ§®íœŸEÓ â8Êk–žkR–dÂLΟ#ÈDŸ8¼@ñ~u”åéÇžN{¶øòEµ-ßdzœˆÐ‚7m“éyu/'_×ã_6Æ¿î(ÿ§¿þ9•V…Ådª«ªJ^ÅãìÁ• gÎ$‰æ^“áÅÙhÆj±B·t}üˆb½ ØžSt¨mÕP5Ã6P4ÍÔP5•'·žäÇ=éOW!¥f‰IB¥•ZÏÇó´‡GÅC’$ܲ˸;΋ñGãÞ»hÓØiÐ>hclƽ1µÍv!¾xB¥@u³Šfh,g *õ&¥F Ó²uGLúdEFÑ*­*ÕÍ*ö†màU¾?£ZÝ WŒF—ùïJ¥£Q]O#Zªjd¶¾GGwòã=;»,ËyíÏú;<=}@¿Ž¢¨¸nú9dY΄LÌjµ@Uµü¸&“~½HX,&¹`¹zõ‡x^™Åbš‹¢B¡š§kµÛWpÝRrÝ2Î1I’P©´xòäÓ<-+Ð(Š‚®§=^tÝ@Uõü=× 1-+MÓuÓt³÷è0©VÛy˜uTn>3\ày•\p¥ýsä/D\ÖoO µIÇC9‹®­¾P³æ÷½(_”o@È2uP4…j³,+ÈŠÌd0¡R¯³y°KFŒ:#tSOm“çEe:Òhm³\ÎÒ£É8«)†—ǧX®$YãÈ9ÅbJ³Ž¦kDQZ4±í÷îý%¾?§P¨Òíqqñ˜0\Q(¥5+wîüq3uÑu+[Œ–X­´^¼&IÂææµ¼ÏË:ÝëüüQ&H$..gu-iÉ´Ž#àââ1…BѨƒãòh…m¨VÛXVêœV«m±\ÎX,¦È²B±XÃ4Ó…u³¹Ç;¿¶ „z IDATDUÓþ2¾?Ïêf®R­ndév¶] P¨Q¯o>år‹z}“z}›³³i#R»¤k•R©ŽeyÌf#jµM†ÃËLiX–‡®›Ø¶‡,§‹õѨ›9~)¨ªJøþÃp˜ÏGX–‹¦éT«›¬V ÃÄ÷ȲÊÁÁ²&©×²ˆÑ0+Ô/ÒhìæÆëú¡ÅbJ±Xg¹L]Ô‹)ƒÁ9QP©´™ÍF¬V~Vÿó×®c’´¶|^1›r‡²uÔK–•,lõ…>.k!º&­ÇIê:½ìéµÛÚBùÙ”°ß—µ(ßRä嫞ÿ¼]¼g#1ϳé|Ù~1¢F ¾Yâ(¦±ÓÈvÊ“t7žŠ€uj”nê$qBe£‚[v)T Øž/âí‚MàÈŠL'Ô·Ó]êÞi/uù*¹”[e®ÿä:^5µÜݸ²‘»…Õ·ë ;C*í4’c:&H°ûî.“þ„ýïí§‘Y¦µ×ÆŸû„Aˆ[r ƒM×W!£îˆé`ŠSpð>ͽ&ŠªPiWÐ ``{6•vI–ÐLÅda¬+,×âཫ~@÷¤‹¢)ÄqLc+³ƒ BüEZ8_(—Rw¨é4u“Ò8US™Ž&ÄQŒ¬È©ðQe’$a÷ÚUJå:ÅJUWÙÜÛÃ_.(U«Ô7ZH²„iÚ´w·Ñ-ÛñØÜÙ§\OT*ªB° Pµ´kz©VÞÿïóö;P­ndîX%LÓe< ( ï½÷Ç”J … …B…îÅyÖ¤²•-D*•vn‡Üï^àº%$IÉlxƒÜÉêââq¶‹?ÏœÓdºÝãÌfØBUuªÕ ÃB×Mâ8¢Û=ÎÒ‹$IŒëVˆã8ë]"†éâúÞ½Y.g UÆã.‹Å”z}›ùÿÏÞ›5É‘žWšOø¾…Ǿ枉Dµ‘EŠ”ÚÔ=£››¿:—s5s5£žî–Ú¤–H–ªŠU…-¹Å¾ø¾Ä\|.ŠU’HQR¼f0 @fddfÄwü=ç<Á ËrËœÊb1.²8!§§#Ë*†aã8 NO?&ŽE¥Vk㺂ÏRœ^Êû§i&• Äz=/éòëõŒ –1tåµZÏ›—µÄíöãñë²¹-ËRƒ dY-î«h'{SøÇ×Ôj]$IÁqv–3ŸårÂlvK–¥eõó.W# ‘Ëòýí67¢ýMlTvÁj5)r9I!I—¥$¹Üzì@’$Óé°¿?Ûu:‚­S­6Šïƒ¿Ï¤øþª¹B¸Ôjòÿªªþíbï;g¾¹¹Ù ”ýü³Š™ïsÕï»®¾m'{ŸÅì}˜w ˜½ˆÙÏ~ö³Ÿ6qú!þÒG7uêÝ:«éŠF¿ª«¼üü¥hÊj×Dî¤å–öG?y„$I´ÚdIF° 8ûäŒZ»Fû Íí³[ÜŽ‹Swðæ£yš¬põånå£h ›pÃ6ßyQi3lƒ`Ð4\ XÏÖÔº¢Ër-²$ãàò€8ˆI6 Ýã.Þ£}Ø.mcª¦þÂGÕÄÆ¤Ñoˆf°AƒM,BéÓ»1µ¶xߪ¦’D‰Sö4MìšM­SCÓ ,ÇAVdÜf ÕB¥ÑvµÝæG34fÖó5vÝÆ_­ ×!yžSï4 ½Pظª­*7/^áÍ=LÇDÑÅãQ­6ÑM( xþë/Q5aÏJ’ a(в,c> Ùî«UÑ:–c»6«Õ Š0÷àðÃ29=ý˜0ôpjUêõ.ºn•ÍSY–àûKjµªªãys:#dYf±x`±³^Ï9=ý¸|­žL^—V¤,Ë88x̧Ÿþíö¦Y-íS†a€ÌjñZŸ—ÕÄ"³bÒn0Ÿß6.Ø–[MÓ‘$¥1:E½oBùhšY@C–ËqA‘ßòí·ó¥FzT*‚a¢ëõz‡ X±ÙD†(UÉíöƒÁ9‹Å¸7>ùä?•í_;¨c»}ÈÕÕ—èºUZº‹®Û.Ú¢²†Øu[4}|A¯wF–¥,—l»ÆhtEžçŒF¯ ÎËÖµjµÉÏ~ö¿¡ëºn±^OY.ÇT*dY%Ï3¦Ó[@p„Öë¦YEU5ò<+û•"+´a<~M®H’¸|lv ž·,!¥­Öðó\V ¿7Ï`»êí7çíªã7Ï^ ìç÷"\þ1·ù>–³·þï4ßgöf?ûÙÏ~Þ888Âò£›âª§Y5ùåÿûKŽŸ³ÝnI¢§áPmU ½ÍÐÈÒŒÕlEÄÜ|}ƒ¿ô_I7)nÛÅi8Œ®FD~ÄzºæîÙÁ:@·ô²Ìp –aʲ écXbs²c«D~Tã »`z,ý²ÖØm‰ðüøõ»f“Ä Õ¦°©m·[Uaz3Åm»¢:9ÏQu•‡«‚U@° d©¬MŽƒ˜×¿¾¦:dË–W_‹]³Ù²¥Þ«£é"iØyžGý³>y&[ËÉUW©¶ªl íƒ6’"Ž,'OÏH7¢\ 2WÁ5•,É0Sh‹Ñ‚õzFx¥E¬RÍgÓ›)²¬pöø Õf•¼`¤H’R„Ô…­j:¾§ê6¨V›ôŽ0 I–89LsЭUù–Ñýk4]çàôŒ›«ç\]}Uf'tÝd³‰ètŽHSQeüøéOH’Û®S«uX¯gÔjí—V;{i:?" =îî¾¥Ñè•Ûn÷„Ùì–8Ð4×mÿÄÐ4ºÝ“"ôßâàà1ªª³ZM9:zÂz=Ç÷‹Ç*ô¸»{l™ÍîËr’lè÷Ï9?ÿºnññÇÿ ]pNEQ±í:ãñkf³{ÖëY––v°4ݠ땊D»}Àv+ø(ƒÁ9²¬tœìv©V¬×¢2¹×;-mQ­ÖP|ÿ6‹ÅC wŒ"Ÿ X³^Ï8:z‚çÍKñ"õN!®<²,£×;e³‰pÝ6wwÏËûàyK6Q¦Ðhô˜Íî¨VEÃWÀtz[TFëåŸ[­!²¬Ðn²Ýn©ÕÚeNiW£|ÿ›–7·»³™l ËÝö Âþ·cÁ¼9ÿ˜ªã½@ù8¸ï…Í{ÌÞ—‘y—ˆyWö廬c{³ŸýìçßÓh†Vr= +2íƒ6Û|Ëz¶¦ÞÇ©;°…«/¯°k6‘Ñ>hsòÑ ãnÛ¿:b³róÍ qSëÖJq é?¾`‰ƒ‹Óphöšœÿèœ`ˆ­Év‹íÚØ5Ã6èôøä?}‚¿ôENÄP9ùðÕy—ÙÝ Y•1lÝÖ™ÞNœ>y²*ê¦còüÏl2ÿâ³ ê½:“› I¼vxsÇôíƒ6¦còñŸ|Fš¤äYNè…¨ºÊøjŒåZl ŸüÇãÍ="?Â[¬éôXŒ‚ùb¨Ü>¿¡9h’g9þRl‡Ü¦Ëõ·/žœˆÍO–á-×(šB÷`@žg´ZCêí†mpøøÕPiteð{g§ ×!®Ûæøò Ý0i :$IL–¥¨º¨œÁD™>ŒXLgÜ>¿æððòLT誺Ø9N“Ó§e¡Õí£ªB\]})hñY^®%I¢^ï²Ù„ŒFW4›}šÍ>­Ö°¬þµ,—‡»k4Mçɇ?§R‘8=ýx÷ÊeÕÈ2Q¬ªaè‘çBÕêí2žç9õz—ñøEQ¹¾þŠF£Ï|þÀùùpÝ6í¶`Å´ZBü­×ó‚Õ"s}ýeY¬(_}õ—XV ×mÒlèvËæ¯~ÿ¬È›hıO‹@ÿÃë¢FZd,Ħâ†vû °}eèºÅÕÕ—Åí²¢‘ÍÆu[h𦙴ZCƒ f³;:C‹µZ‡““ÈsQc¦ ¦)˜+õz—jµÁýý ‚`] ‚]åðùùŠ¿L¬¸¸øŒZ­[6…‰ÇEp[ƒ‹Âþ¦Q¯wÉóL@G·" ¿Ù„¥øÐ4³,ØåJæóû¢ñMÂ÷€hÛ-ìÎdº.ʪÕf™eÊ‚…ß8Ô¿#l¿ÛàìÊ~þà…Ü÷…S¾)4Þ%\ÞæÆ¼«zù»ÄÌ?vöÂg?ûÙÏâdI†,˨ºhÚŠƒ˜F¿AÄÄALä KW²I8ûäLd5ª&þÂ'ò„Ï}ggмHðRL Ã1„j—Ã%žý⪦bØš¡±š­½j³ŠÓV©ŠT!MR`ÌsÒ4Å®Ù(šB³ßÄ[x¬&+¶ù–,ÉÊp»¢)t»T*®¾¸b9Y²-1QYÜ;í¡¨ ª®b9/?I° h ZäYެÈT›UtK'Ù$eÇ_úXU‹Ÿ? {"—£9³»^ƒZ§F–eT¤ õn«/®°\‹jÝ%\‡¬gk¶ù–F¿Áì~†eU±ª–¨c¶œK8¦S¯Rk5H¢D¼ß4CQÆ7¢Š÷èƒcUa5Ya»6Ÿ<&ÏsjiœÒlè“g9ƒÓCQ!=8Æm4Ð “ÛÛgtú„Û¨¡¨ ç± TK’Lz\¿ü†þÑÕºË'?úXU‹(5Ί¢¡ë–Ø6ÔïÄ0l¦Ó»òZuÌç÷,#‹1óé˜Z­Í‹¿zƒÝQáìâã‚I²E–U*‰årÌlzm× ë’L¬9>þÛ®Ón+:#¶ÛmiËêvQUãã©T*?E’dÚíCž?ÿ%³ÙŽS/·Bªj ii*˜%²¬p{û-Ûí–/~I½Þ£Ù2Þ•L©ÕÚ8N½d­ôûg„áŠÇÿIªÿmi› Åšf0Ÿ?pròaèÑïŸñüù/¨V›Ôë=–Ë1ªªñá‡ÿ¡Ü¤Ôjjµ6ß|ó× ç%?'ÏwG F.Ć8išYlƒ*ESWVðjL’$.÷;8ãj5E’¤b³Õ"M7å¿íÄÜN„n61³Ù]qŽ’Ê¯«¨‡öY¯g¥pí`aùöî\´³Ç)ŠŠ¦€` ½Îÿ×rŽÚ ”ýüà Ëû~ÿ.Qó]6²÷maþ%€ö"h?ûÙÏÝÒ¹úêŠd#ˆì𩱠7„~Hÿ¬OcÐÀr-UAÑjÝ«éŠ-[¼…‡fhŠ•eB`aqÓM`Ó[qØÙD"„¾5†^XZ¹‚U€aØ® ÕçYÎz¾ft5âîÙ–k1¿Ÿ ¾I‘s©T*4‡M¶¹°%Q‚¢)Œ®G4ú ‘;)¼ñ’,²&ã×c&7ܶ‹aDAD­SCVd‚U€¢*„^ÈzºF·t!ÎÚ.QñáŸ|Ìèj„né4ú ~ò¿ü”8Œ±ëhÙ?”%›(&‰:ÇLǤ}Ц{Ò¥Ú¨R‘*b«déD~Äݳ;lW¼Z·†$KôÏú¸mI–‹e2G7 Z½‹Ñ‚-¢†y=_áͽò±¬HNžž!Ë2Iœ¬tSgmˆüMñÉOþIœ†kÒ4E5T6›¸´ñ˜¶]6TI’Tærü•Ïv›3¾»G’dt]Ðå%Y*·¶]|œÈcÇèºÅ£Ë#I²,š¶úýsÃsò<§Ùìõzß_`YÕb+#j‰wü’gÅ÷—èº8„ ë‘\6X %l];Û’¾‹Û]^þ„4M$¥„ÆqÀfbš†aÓn–÷ëòò§% ¾Ñè•ùårŒ®›¼zõ%qruõ%¦é”ÂNd_"f³;*©¨¢¶É2qŸóË2TU+sKY–âº-,Ë¥Ó9¢×;)¾O‚R ¤iR èÿ$™¦ÉoÔ¯×ót!ûá´(ûù‹šwý0ü6fÌ»,fo Ÿj%Û Žýìg?¿ë©¶ªT›UÒMÊë‡òàoدðæÃGC6цÕtEµYÅtÌ’¯jªØ²Ä‰8˜u¨6«„ëóOÏËdµšàysâ8,ƒð¯^}l ‚e ›lµ˜Íî0Í*icšš¦cšU¾üò¿•bPÁu[l·9³Ù-Q°XŒ ÛT» Œ†Ãb1*™4§§!ËZY{<]ë2 /ÄXŠ$É8NÇ©cÛ5\·U¶©)ŠVXÛTZ­ƒBT8=ý˜$Ùàº-¦ÓÛ¢YÔëšMÑT÷øñ±Ù„Åcj–¼Û®1Ÿ ÞÎdrSX%q^|óÚ,·*¢úYÇ4¼Ò¶ë€2ÿ9•÷y~ÈYè]v±×åÍ&ªß%Èp?¿_Áò®·¿‹ó>°å»¾_¾O;Ù)ø®·Ÿýìg?ï›Éõ„ÎaG°IUÁËñ’þiŸ``×í¬š½fIŒVËÉY‘‰üˆÈ0«&VÕ"ôBZÓ› †mÀĈ$JÊÜŠ]³¹{vW ‡j³ŠÛr©T*–ÁÅ/–h;¹»n‹Záñ’ÎQÃ1DÐ|»Åi8lâMù\è4ò¿Í¶l3žüHpN¶ )vÍ&MRa[“%~ñÿü‚ȸúòŠéÝ„£§G¤IŠ·ðÖÁoˆ¦áÅÞiÕPËM†á4Mšƒ&Ëñ»nóÁg3¼R©TÖÉ&ÛŸ8)y.Á:`1ž1¾yàèÉ¡ ãýÛ|+(ò• ‹Ñ‚ŠT¡9h"I’¨fÞŠúÖ,Ö7é³-ðæÛmN–e(ªB£Ý&ÏrŽŽ>`5Ý58Éø+ÕjŠ¿WÜÝfj½F£Ó¢Zw^£i›8棟ü¬¬yö¢œ‡»+tÃd1àÖ[„¡‡,Ë8NÇipsó Ûí–?úùÿÊb!ÈïÛ|K»=ä‹/þ+ªªSudYÂz=Ãv«ž<¢^ïÒj ±íÎ1µš;Îf·¤i‚m7ð¼õz—fsÈÑÑS–Ë1íöõz——/ÿ®´L !“Q©H„¡Çr9Áq‡¦Zmrvöq±‘‰Ñu“ÃÃdžͣGŸÐíž°ÝnqÝ77ßðøñÏe™ñø5½Þ)A°âñãŸqyùÓ‚cÓ!Ï3¾ýö”–)I’8:zBÜÝ=+Â쾿,ÄNZ°U´Âê¦ÍfÁšûûÄqPÀ/=\·Ežg\]}YŠ¡8X­¦E¥°TRâ=o^ ÀÍÍ78Nƒ~ÿŒÍ&¢Ñè‘eIÁoÑi4úȲBù,—cÒtƒaØÌçH’BžgÅvHXµD–(+ëˆ7›°€XÚ8NVkXT‹ÍZ¥²tÛÒ:öC7';@äŽá²(oRßôÚÏ¿ïmÌÛ¹—·…ÌÛ›•·EÏoÛ¾üsÃ/÷"g?ûù÷3»ºÏÿôCžüô1ÉF°{'=ü¥Oû Íýó{^|þBÐãu ÝÖyýõkÎ?=§Ö9ÍÐhôÂ&µò§ÿá)Á*ÀªZ˜U“ÃÉÒ ÝÒÙæ[dEf|5¦wÒcv7+›ºÁüˆÒMJ²I_YN–¼üü% š¾ÎtNš¤¥Åéáå›hÃ&Ü”b)K2tSçù/žã¶]q ÖUìºMï´G½W'ò¢r3´ÝnYMV\þä’ív‹¬Ê<úì’<ÍYÏÖ/Šláû+f'v¹˜J¥B䋃aÿ¬/ˆÅfEÕT²MÆr²$ݤŒ¯Çåí Ó¢=è2¿Ÿc¹š©ñôgzai½’$‰WŸ¿b KÓÃõÕVU;Û`=[£¡ï çãÔªäYÎøæI–0,ƒz·^¾Ö¨º†S«AmA ÷—>‘±˜Ìز÷vCˆT°=*RI’¹½ýM3PT·.F–f]ây TU#M7Ôjm|Ét|®[<{ö·xëišòÑGJ’DÄQD¥"!Ë*W/~Ííõ‹’’¦)³Ùm!2rEØ…4M'Ï3ò<çîîy‘GùˆZ­Kž§t»Ç(ŠN8NI’‰cŸvûz½K½Þ¥Vë`š6‹…ÈììJž7ç׿þït»'„¡GyȲÂz=/Ãà’$ÓíãºÍâ>À0l$Iâþþ9’$³Ýæøþ’,Ë >Œø·]À_lß²,ÅqÄ6ÍqêEå³S”#T ±bîÇi”V7Ï[ Ë¢"»R‘h4úeöDQÔ 2~[`^–•ßòïÊ~öóOØÄ¼-lß&ïooVÞ%hÞµÉ{—íì·qdöŒ™ýìçßþì2 wÏîˆ"a³R4I–øä'°/©ujtŽ:´ZŽÁ³¿y&8!Âöfj¬&«²b×° dU.³'‡RmVYMVX®%r)²„¦k¨†`“tŽ:ló-yžcVM¼…'Â÷yNµYŮ٢]¬húŠüˆÑÕáã/Dbp.l*ÕF»nÓ:hÑ>lã¶Ýº¸ƒOV¨ ¨J r܉§á ê*£«gŸœÑ=ê"IóÑœþY«*¼dU†  pä®9XŒ¯Æè–hST…z·.ð ‡õ|Í“?5Á[¶<ùùTMåüG"—Ñ=îRm Û¬ˆ²Z»FºIiš˜U“È>}ÍИ݉ÇÒ®V¹ùúFä{Ö!Y"BûP!‰šý’"2-ÇONɲ Í,²aDïhH÷¸‹¿ò88?áðü´h£Ñ•Š„SY‹ëÏDÁFX©TM¥}ØæôüCjõ6µv,ÉÄÕõ,Ã÷Vض[dU2îï_â8 ‡ÇØÕ*š¦cÙ.’Ta³‰èO ‰hóêtŽ$™áÑ)Fߟsrò1µZ›ÁàÏ"áþþ%Õjƒáá9–å²\މcŸÍ&,¬a-l[@EÀ;DûTùÅVC.…C»}P–+D‘ÏÉɇÌç÷†ÍÑÑS‹õzß_0ÞP¯wY­&¢6Û_¦ ÓéMi§Ûqf¶Ûm‘»YÌqˆ¯ËšâårL–%†Ív iºáââÇ$ITn}úýS¾üò/ØnAÓ Ãàðð1µZ‡8®ð¼yÉa‘$¹¨ öñ¼ŽÓàòòJ £Èµ(ŒF¯Ä…€¢ZlT„ð¨ÕÚEˆÞ¤Ñè•Í\p)86–åÒlPÏäú<Ïð¼šf”µÃiºa6»c½žS¯wߺ€+aÛ¢]m÷±w÷éÍù—ÞšìÊ~þ] ™÷meÞÞ¬ü6滀—oþÝw±e¾¯Hù¡{¡³Ÿýü~ç»lÈ^ƒz¯ÎÁåÓÛ)y–3½™ U jbÛððò¡ R«†"y&¸"²"3x4(ëGw¶¥ùÃESüðvŠª‹/»&l~ƒÛon…¥«hï2,q~»Ý¢™Úol'œºƒÛv¡—¸-·åröÉy&¿ý¯ˆý¸8|Ǹm—Áùo!@‘vÍ&ôBM´aåYŽ¿ò,q¼døhH½[â SÜKl%̪)x*šŠÛtYŽ„}ˬšüú¯¾V6CäY,×ArMÅ_ú¤IÊäf‚]³>лëo_–ÖºJ¥"hñº‚·‡8US™ÝÍJb}ûPÔ .tŽºôNz<>`x9d=] ভS©T^ [:ÕFÓ6É’ŒÕT0lvV³þÙ€,-š”T•M¸!K3Ò4aüpÃððI’P Ã2i4{l·[“ggŸ f̯ŸÑè5ÈÒ”8ŒI’ ÕZ I’ ºªihšÉÙÙ'D‘‡në,f‚hŸ¥íþ  ÞÁ€d#j’Y=G’dLÓe±!Ëâj» ÛûȲL¯w&¾ Ñ6&Ë*¦Y%–¬×3æó‡r"6'hšIµÚd±ñå—ÿ0ôèvȶë¬Vc¦Ó[LÓ)›¾LÓáÉ“?A’$ƒ ,Ë-Ë*0ÍêoÅuÝ"ËR:#úýSl»ÆññSdY.mZ;a´Ýæ8NƒÑ誀FÚŦ³Âb1*ÞŸÉv›cV ÆLÓ„l ˆb$ìZi’ŠºÓb›0x4`ñ°`9^’g¹`(Xº¸/‹C{'%°qG±ß„dEÆ[xlbñgY–QTÝÔiš¥`òf›pCÿ´/²P~ž›hS2T Ë }Ø&Ù$X5 oá•"ÁtDX~›oKBü®l|=¦Ú¬òô?BÕTz'½²Z8‰T]e9Y2y-²8i’róí€0J>üãOøü¿üŠz·ND´-݃‹y&Ø'ÃGCVÓÞÒC7un¾}]æƒ^=0y=AQ¼¥ÇÁå¦c¬a•Û$ÄaÌì~&¶Hª"¸2ºJš¤øsaKó—>¦c²š-‹<€ÆÉ£K4]£ÑkŠ2€é˵HÓ ÷÷/-Þ|-¬E¶TȲŒÎaWXéj6NMÞ7q„¦ëŒÇ×Ôë]–ã%ºnù…TT:[.óÉ]·ñýA°ÆqèºÉõËo™Lnhu{¤é†—/?g:½¡Û;¦Vkk’$f‹C²a;Ôr9ƶ…`tøz½W´gL&¯‹šbA‹ße.^K$I)ò!wwÏ9<ü€Åb\ä,–åk_§sD­Öa³‰0M§¨^!ËjiÝY‰ aèñüù/°,· †áp{û-Š¢Ñíszú1qâ8õB€lè÷ÏPUõzNžo hå¬à¶„¡O‹ÌÇtz‹,«xÞ‚éô–JE4o)ŠJ®HSÁ¿QUM3Ñ4“~ÿðÑlX­&ÁŠÑèš³³O¹¿Qfo¢H@6Ÿ?ÿ…°ö9”ÕjJš O e£Ñ+Y7„™”›¬]]ñÛ“çYiÛm Šg´7ªŠ%tÝ*ÿÏ¿4±~/Pö³ŸÆ-Í»²1ßUð.¶Ìû,fo‹œ÷U7ËÙ~ö³Ÿþ9úàˆz·Îà´/®fê¢ Õ° ¶ÙV4AU-LÇd=[³š¬ÞÒéuI7©¸Ú^4j–Áéǧ8u˵]˜ÝÏÐMESèô˜?Ìñ—>nË¥sØap1 ÑkЈÚÑ$ôzÃ6dIØ´Z.£«Y’ÁVlFvÝÔ1aMSuÓ±õlM¸i´ØÄ~õç¿*IóŠ&‚òVÕ¢Þ©—,”K3´r›”%Yša¹Vùkê¯HT]-³6v]íïžß•yÈuÆvÍF34dYX·4Cc1ZàÔÎ?¹`z+6W’$±ž­©P!Ïr$YâůD(ݤh¦ÆÉ‡§l"ñöÃÕnË%c*;žIr¬6DsÙjºÂtLò,Y¡b³Uk×ð–k’XˆÎ4Ié÷YM—¨šÆjº"ßæ‚'4ZâkÞêöøùŸýišPï4X¯g|þ—ƒnêĨ-^Í„[Îf¥ØÐ-O~þó2óÝni÷o¼†‘šçÇçžœÐìuPÕjBžç¼|ö'çpxø˜Áà‚ÕrJù\\üˆ8ˆ"Ÿ×¯M­&ˆðÕj£ ËǬ׳ò[­61M×mQ¯wIÓ„í6£áÊ(¹+b @’–U-΢Î7/ Š$I&ŠêõÛ­€Nî¸ ¯_Íf¡ë&«Õ„VkH‡,#ò\4~<.À)›M„¦,—cñ=#+eó• É[„áº$ÑÇqH½ÞÅu›\] 8¥e¹Ôë]?`³‰Ëà|¯wÊtzËxüºx­…Åâ¡d¼ìX3ªªÑlö¡¨ì>=ýˆ,Ki4zH’DµÚd0¸@×ML³J»}ˆãÔË ¼xL·…Àè‘碚¸R©0ŸÈ²´¨y¶°íz¹íÁcÙQêEc±‰-Ÿ¢—,–8Êp¾ã4~£¦ø_böe?ûù=‰—Ìíßg?{ßß½Ïrööæ},šï1ÿµ…{Á´ŸË“ç9³û/¬‘ñÙOŸ2½’eÝNƒÐ ©T*% ¾uÐ*æi’Ò>h3˜søø4IÙæÂže¹£’$á4êÝ:ëùšÓOÑt ¶¬̪‰ÓpÊ·M¡9h²š¬8ùð„åxÉb´À_ø„^ÈøzŒSwØæÛÒ6z"xýå5š®aXÕf•ñë1YšqöÉ£º©£j*^ÍÐP4åsòá ëùšz§.šŠj¨<úé#}!žFW#"?"b²4£ÖmY[ñܰž‰ ³Y5ËÏåæ›FW#Ü–‹ÓpH7)yž3¸PmVEÐüzŒ¢‰ÍÓpÈ·‚\¯[:’,A>ùŸ>¡Úªòè3Á¢È³œÖ°…Uµ¨5¶Áý‹{†—Ãb™lü¥Sw°k6Ëé¢ êïòAÏ¿ü öµÅxÎ6߇1õnƒÎQGl¡*’ØÐÙ¤ålŠfh$q‚Û¨‹üÏ¡¨„n´}ŸÕtE½#:õV U5Ÿ0OˆüY‘¹¿¹&ËD t£Û"ÏSâ8À­µ°é!+2Óûn“JEbppÊãL–f„¡WÔÚ6øó?ÿ?ÊCq§?äÉ“?.éY–Q©T¨V›EkVÈ|~ÏhtU4›¥Øv­Ø´Ô^²XŒÊßÑèJÀLU££'躨UÞn3a]SuV« ›Mˆ, ‹–ÈNlØU»n‹áð¢Øì8t:ÇT«M..~L¯wÊv›!Ëj¹á™No™L®I’¸B.A°b2¹Å0lŽ?DQ´"<¿ V~€ªje—¢&8M7ÔëtÝĶëŸÅâàà’J¥BžoÑu›éô†4MX­&% ^Q4 Ã!Ž}‹qù¸Ë²RnMt}ƒ”ð¼…x¾¸øQœõê f³;4Í`µš’çõz§(.P‹ Ø’ XcY.—¨ª^ä]d²,¡VkcYUâØ'IâÒ"¶(;a÷æìò?o7ƒíÊ~ö³6ï½Ý»ê™ßÞ¼˚ò®û.ý»¶4ß·Ây/Höóo}n¾¾!\‡Ìïçø añ©Í~³YC龜­EÆ»‹©¸–Iš¤P?·é&EQc¬TزÅr, Ç@Vd.¶’,‘&)Õ–ÏOn&°E¼¿-emq‹¬é˜ŽÁäfÂé'§¤›·íb:&²"‹°ÿ:`x9ĬšH²D'Ô»uQƒkjÈŠÌü~Îèz„fjÄAÌ&Úà/|*RÛµ™Ýϳ%ÏÙæ[ÂuHž‹íŠÛrÙÄ"Ÿ!ÉR¹i™æx ¯ä½diÆÅgÔ:5ºÇ]ŽŸ£ÍAÝÒ™¼žðú«×¼üü%Í~S@©"²-ºJºIÅ«xn|xùÀj²*Ÿç÷"7°Ûøh¦FºI韉,Çj&ʲÝn½‰|ÆqŸáåû—÷Ln&ló-çOŸ`¹‘qüô„Îq‡Ð ËLÊÙ'g趈ƒ˜þi·Þ,ƒú¡’&¢iMUõÚ™°‰âò96X +á´û=ÂuÈz¾æèâYVËúäÍ&¢Õ”ûj³Š¢ªäiÎtzC²I8¿øÝÒÉ ö† ¤›xÞ’>úS*• ¦é”â%ËĦÇ4ŽÏIÓ¤hŠÊÜJ–eÈÐ+².®Û¦Ñè EÁF±mÑXU¯w û×K’DÔí.—cÎÏ$~FâjµÉv»åþþ9I£(ëõŒfsX›-²¬0œ3Þ¢i–U#M7ÁŠJEäRͦh¸Ún·ÌÑ/·2ŽSg³‰Š-Dµ´Píî‡ë¶ÊœÈ® zµš¼A•ÏY.',—#âØ/Ù,Óé-¶]+ê€å’ïR¯wX¯§†ƒç-Š|ÏŠí–2o´û¯P]·Ê°]Ýñ΢5]‘$›bëÔ-Eêf‘çëõ¬| eY¥ZmY›Ý÷€QæwÞõr$1ªª—”û½@ÙÏ~öóO>ßeI{ßvæ» ÞW4ð.ó>ó®Û_!³;ûùCœÞYþYŸöA[@ð0ò Vë`ÛõÂ"—”™Z­®Ût:ÇH’TäJtÂp]dhl¢Èc³ K1–çyÑ\–ÇØ¦:2¿bYUtÝâþþšf IR¤¯Õ:hšÉÁÁ%’$Íf)¶]GUµRœˆªåEÑËJâÝÆDØÃÔ…ü]mUöe?ûÙÏÚÚü6KÚ»¶5ïj5{Sl¼+ó.Qó>q³Ÿýü!Œ¿ôYN–åF@ÕUþóû[6ÑÍÔÐ-Z»&Åñ˵P…M´ar3!MR?8¤Þg9^ù׿¾&X¬f+>üÓËÃz° XŒ˜U“îI·l†:¸< 9hòÍÿøÝÔyù«—¥àIâ„,ÉxýÍkšƒ&gŸœá-<±Qe4S–¦4ãþÅ=š©á-<"?bnh´©ukl¢ «Ùª¼òß;ëaØÍa“ÉÍDÐæ>ç?:gt5bòz‚¿ðËœ @³/À‹vÍÆ›yB\œôÐmÕlÅb´Àm¹Ü|}#jx“”³Ïˆüˆùûf3¸ppy€U³U™õTY• Öƒ‹³»nË¥Ú¨R‘*ÄaÌ‹_½Ài8~pˆ]tI9“<ËÉ’ŒÉýˆÑÕˆùÃY•éžt¹þê·åRk×°\üOã”îIÓ1‰ƒES0lƒþYŸÁù€Z§†á‹œ¢)´ÛȪ(ØDâ ·ž­YŒè–N𦴄•O·tdEƪÚ<¼¼G7õ²$AÓ5^qxyŒ¦eŽÇ0,ªMÁpéŸõQ5•õrYÒíó,/[§î^]ûb;Óœ Âü|JeèÚ® £¦ét:GȲ°!Ù¶K–¥ôŠMFŽm×X¯g¨šÆr9Á0lâ8`>€D^1Þ’e)ëõ”››¯I’˜ñøšÕjÊÃÃK–Ë1Ýî1³Ù¶]#ϳ²WÓDãV¥"áº-ªÕ&›MDµÚÀ÷—…eëiì?=ýˆûû—$‰ø^m·8>~ @yÜÜ|ƒ,Ëôû§¿¥WXŸBâ8]çööªÕFÁikǾõâsü{¦Šë¶È2ž¿¾þ5iš ëI³XŒ°íž7çåËÏɲ”$‰ .ðý%ªª¡(za«ÛªÅb„ªj¨ªÎpøÇiÐhôJÁW©H(Š}Ššb“Í&Æ4BÀ¸EÞÆ¦R‘˜LnD-µå©O¬P•(òpÁõÙëÓ4! ½ògøÍ@ýx/Pö³ŸýüÎÄÌûÎÛ›—·o÷¶ýìíßßµQù®_ïÚÒü¶Û}—Ú‹£ý¼kçLGXµUA35~òÙœº#®ÆW-‚U ®lwêhšÊý«œšÍ“ÎyòèU¶¤Ý÷øé1fÕ$ݤtû-úç}ò,çÑ/èôʶ­ÑÕ×äõÏÿóç4ú"röé²"Ó´J»Uÿ´Ïr²Ä_ùLo§t»T*‚¤~üá±Úš®Ñ=érôô˵ým¾%ò#úgýÒþµx‡kîSëÔJ€cžæÔ»uŽžá/|V“ó‡9‘±š­ÄÏs¾Åp V“i’ 1U³É³˵èžt¹üé%š©‘lf÷3ü¹O° ]Šº\Á©uk+Qç\mT… ê å ^Fž ;Ü“?~ÂèjÄj²•¼‡m6ц<Ë1“$NøìÏ~ŠÛr‘™Ð ¹þêº ¾ç¹°‚õOû‚V_ÐåUááÅþÒUÍIJºI ×!Š*ª}+• á*$clW|ž^£„hÆAL–d‚Ë2÷Q”+ˆíÎr:§Ú‹“‹È’Lä‘fkÒD°>¦÷cTMe1Z0¹Q­Õ0mÃuÊ’$[„Œ,ËDîÁÔpðÑY 4 ›Øiµ Ï‘dß_ qs÷Œ0ô¸»¾*3)QP©ˆ¶8€õzΣGŸ• py.ª†›ÍýÁ)ºnsvö)IcÛ5tÝ¢Ó9*Ÿã…Ýi‹eÕØns¢È'I"Öë9Ë¥y[–ËÑцÃKâ8 ŽCno¿Å0ì’Éòé§ÿs ã°ÈyØ%(RTWHÓ ¾¿`>¿§ÙìÑh;æÉɇ4›tÝ"Ï“¦×;!Iâ–ÙÁóæ¬VÂÐ+ÛÄ^ù¾eYáààyž–Åa¸FÓ ./Êb1b¹¢=+VȲÌfây >ŽÓ Mæóû2Ïãy j5‘?étŽŠ×Ïœ0ôeU›«0ôH’˜8Y.ǘ¦€JŠêcƒáðA°"Ï3šÍA‘-z(_ãDݱRüY+ïçîß~³(ûÙÏ~þ`…ÎÛÙš·ÅÌû²5?Ä¢ö¾Û½-ŒÞ•»y׿½-`þ±g/~þõÍÎu÷ìUU˜ÝÍHó]S9=’ðÂÇçG¬çYÑråâ þÔmYŽmòê‹W´†-–cÁ°8>bé:¡ŠÆ«J…Ñ«ëùš‡Wè–Îr-ƵNjS°U Û Ù$˜šF­S+›ÅTME34AaO³²~x—}Ùm€¶ù–8Z·é²š®8¸<ÀvmAf74q`ÞŠÚUécU-‘;)~^çsŽž î Â’–g¹°~)²ø¸EöÞhÍjVqê~é/|â fx1¤{"jwýäóû9ãëq¹‘h´Êf±m¾EÑ’8)3:þÒÇ®ÙH²Äj¶"XËoî±/]P oáá/D;Z𤨮M­S£5hyQɦ©6«8 I–˜ÜLhš¸-Ã6féã/E>#ò""?" "Ua=[‹ÛPÉÖA‹jS4…mÙRu$qBè…ø+ÑÍÿÝÜ‘&)Á*@RD@_34ZƒvVïœtˆÃ˜ã'§b;fhdiÆË/ž‰†«³úGG8õâ©)ÔÚ Ö³5çÇ(ŠˆO§wž¥ÈT*ú1©ÂÁáeÉ©T$Òtƒm»hšçÍi·\”Û•<ÏÑ4Û®Ñj =\—Wæw¶¢<Ïpœ:Ûí–årB¯w†å8t:GdYJ»}Àx|]4béÄqˆ¢ˆ¬ˆ€A–­]Ð< =¶Ûm™­¨×»E=o«x»ƒ¢¨¥8Ȳ”(ùÁyYE>š&Âü;EÛmŽ,+xÞ¬Øxh<<¼Ä÷"TäEke‹ë¶‹°y¥Ì¶È²ÂÉɇåeg1 Cjµ…eU™Ï˘vûéôVlMU½Ì­×3f³; ‚iVIÓ šfàû«âóÛún‘Ai‘çWW_†k*aÕÚ ±-jR«uHÓälIÄFGÿÝ=Ÿî_Rö³Ÿýü[ÚÖü¶Ûý6‹Ú»Þ~÷â][¡÷ÕF_ó¦¨ù®ŒÎ÷)%ØÏïžýí3¶Û-‡è´¹_,‚ˆp³Á2t,Ûäv>§Ñr ýUWyñì5Ó9š,sz:dµòéŸõ ×!Íž¨±ýâ|ÍýDT ·Û¬fkdUÆtLZÃó»9Á* ‰.È’ oá‡1fÕÄ/ì=š¡‘D‚åùŠ&®ŠNo§l ‡—D~„ª ;–Y5ËíFÆ$q‚¤HŽ!j‘“Œj«Š·ôPuUPì·ÛÒ.eؽ“Û|[Š—Ÿÿï?'X\}y…¬È¥)K²Òªå¶Ý²æ¸Ö©QïÕ™ÜLPuÝíai’¢›zY;Üì7ËZ^I’Ê:ãƒËƒZ ðòó—ôŽ{|ð³a“U¹´Eíò—t‰UUȲ*cVE ZÕUæ÷sT]™f¿‰¬ÈÔ»uQÏlˆªäz·Ž¬ÊT›U"/*›»ŽŸ£›:—Ln&H’T¶+ò.Ц¥ÍASlª˵98?F7 ÎIâe ­A‹,ÍÖØ„u:¬§ëò{ ‰ÖóY* ‹¶]c|ó@ºIÙ„EÃ_úC„Œ_H’˜Z«A»3dx.åêÑ2&+ÂKÜF£Ì–¤i‚íVñ¼··ß_[ù0»ÊË—¿*ÂÖ‚5PuëôŽ ‚Õî•,KQUñà ‹ÅÏ[ÐížpxøAÑ„e‹MÈdòIª¦ ½Þ)­ÖJEâþþ9õz˪bšŽÓ ×e›Õ|þPÅô±ZÉ''!I2ƒÁGGO qe0ÞÑhôð¼9½Þ ¾¿¤Ó9b4º& 9¾ß?£Ó9"ŠüÂÖÄuÅv)Iâbs"à•ºn•Tw]·¨×{´ZXVÇ5Áªªqtô„££§¨ªN»}P »'Oþ„ XÑéqsó5Õj‹NçÛV.Ç©Óhô θ¸ø1¶]g<¾f½žav!^–¸n»Øêl1 G€N·[¢ÈÇ46›UÕË¢€4Ý ª:Š¢ý†@qœÆw>?þÐ׬½@ÙÏ~ö³ŸF‘ôÛÌ»¶BïÚà¼kKô}׾˾ö]g/xþésôäˆ$NU™ÉݹÈ5è†F´Iã Óû5ËÂЄM¢j™´-*• 7¯G¨²hÜRuA˜W·^å§ò1•JE„›£Ã‡§‚u@³×àô“S¼…ÇðÑéíYÖ¯ÝjwxÍÒŒM´)mTYš!+2½“£¯Fe.C·…hh¶œ˜?ÌK‘³Ë¥¬çkf/ìSI”PëÔhš|ù_2½rýÕ5²*‹Í’¡R‘,q×F¦[:£É&ap.>'Ã6˜Ý͈¼ˆ¿þ¿ÿšpÒè5$ é³-êÏ,×bþ0§"Uø»ÿòw,ÇKìš->oMÖ§MÊøõ˵p[.¶kówÿõïXN–4zâPUïÖñžØD–bóQ4’…ë°dŸÌæ%¸2Ù$ /†ÂÒU´†ýú¯¾¤Ö®±ž­¿³/I7)þÂÇ›{tŽ:Ü|sƒfhT¤Š`Ääy ŸÝϘÞN“ÆÒYÏÖ(šÂb"¸.Ý“.QBIcmP4«j¡›:O?û¬®º­‹B[çðñn«&ûÓQa»\á4šý&†m°˜Î°×EF’%¼¹Ç&Ž £«›(Æ_zŒÇ¯™OÆÜÜ|]rÁÿqÝ­ÖI–JÛÕáÙ°¥ÛÛqPüŒïï¨Õ:L&·åfAئ¦L§·†Å_üW^¼ø%ýþ)Û-XV Ï[¢E§Û=*hîEΩ9,H÷>«Õ´ØT˜Ln ÃUñ~¶Ôjmîiaè•Û†vûõzÆë×_‘çÃáE¹¦°q” c¦Ye<¾f0¸(œ`šU&“l»Îb1bµš ªZx‚5­Ö°°Yå…¥K€m».¾ÞEƒÖíí·¨ªÎhtUdtRŽŽž–üÇi`š²¬2_“ç[nn¾¡^ï”[¢Åb„ï/88¸$Ë6ol¯2tÝ*?¶€c*$IÌj5ý×.“¦ •JÏ›—âéŸrAq/Pö³Ÿýìç_ÁFè»¶?ßÇÞö}+¥ßU`°Ÿ6Õf•á£!ó‡9GH• Nƒ¨€¦©ØuMQPeUÞmÛàÅÁA‡×Úƒ–c² 7,æ"«ñú~üÿ³÷žÍ‘išÞu¼7é-\(CÓ$›Ý»3ë&fV±+}Ñ¿ÓßÐ7Eè‹v#6v5RÌniC²IVª .ôyòäñúð&Ns)’mb¤qx"D¡™ Èzïs?÷}1½œ vHžs=™¢Ê2~Óg –Hç ÃÕWW(šRÓâwᆔ¹ ž‡ÝF¯Aï¨G£× hÄ›˜f'Ä0utK¬lÅÁ¡ˆ–‘à%ã§cL×$ZD¸ WTwCÂN(V¨šžÈIÜ-™]Ïxò£'¢¬éÖ÷ÙõŒË//)ò=O£áñåý’åÝEQÈ’Œþt)Ë2Ó«)ÿÙÇ Ï†t:üÅÿþtE(}=]‹«Û†( øôßÊøé¸Î¡di†ª©¬f+Uáêë+hß7žé¦¨G^L¨ºÊðlH `äá{‡øm_üYBb=[Ó9èˆÚæíEQo%t™]ÏÐtÑ©ÈP„½ã÷HwBÈ9¡S è–¾_Ñ[ᎊšR‹0Y.éšd» I’Ñ-Y–±\‹ÞI¯é‘§9ñþ3ÍA“,ÍĪÆïaÍ IDATÙõ„w¿™™Õ|În³£ªªºÍ­È ½&QÅí‚‹/¿ kÏ`|D¼‰éŽ,îæXžEsФÙks÷nBYÜݽ£5h3žaÛ¾ßÆö],Å UØ®•ªãyMVÓ%Q´ª×Á‚v(ò*•g··¯¹¹yÅùûì ïÆž½bì]ˆ6ºnî[¬ª=7ŨCôiºãîî-íΈ››—EN-Èó¤nÕzùò¯Éó„Ùì I’‘$ÑrõöíçX–Ë»w_`ÎÝî²,Èì­Ööd*~/¢Ož|DG8Ž¿Ïml1M‡ívÅññûuàüaÝj³™ï9.M¶Û–å’e Ûí× ÷··™Í®ëæ´ÕjÊn·a2yS·£…a0ìÖl•á8>ÛírÏV¹çææÕî(j®ß½û5FáðŒÑè)iše)Y–î…à%ž×ªWæQ´¨Íà¡­L«]–(+¨šf (jÍ‹ùÛXýz(ó8ó8ÿDÄÏ œo:6+dجgk&o&"è\–DñÛ0ø¯¿ú’ƒf“¢(0 MQ˜,–$qB×÷¹z7á£ÃC²¢àÙáE’Èó‚^»nèDë-YšÑè7°<‹4«M77SV³e^Ö?;¿åt\ß©ƒö¶kaئ®‘Æ)Ñ*¢Š61Y•)²‚¯ùª^£œŽÕtEkØB·ô:ø=:á·}6³ ¶oÓ6Ù®·µ;ñ°ê¤Ý£.¦cŠšÞª¢5jÑ4±<‹"/ðÛ>ЦpøÞ!Ó«)ƒÓ7¯nd‰<ÍQ4…“O°\‹¿úEUŠõ9I’˜]ÍHwiínTEÅí«[6‹ ~C°D MÐìCWÐÖ“ÙÕ ÍÐDƒš¡Õ9—ÙÕ 'p0lCðXnæ4öëuý“>­a‹ÍbÃüv^SãÏrÎWùeQòþ¿|ŸÅd!ê•ï–YA‘‹+Ó1iÛø-ÿ7ɲ üV@Y”´Çm®¿¾®0ýã>Óë)š¡¡O?yÎònI–d5Ïæ!?ôôÃÉ’Œö¨-Vüž·¤5lqöÑ3dE®ÎÒ]J'i!Öóšã“ʢİ м {ØÅ ,G¸2Y" •~+@3tÚíñÞpyýúâJûjÍv!I‡OÎEfE–Øí"\·A–¥hšN§?`À]F»×Ç0,no_3?ã“öo˜ßÎX,½×;" {ߨÿµŸRUºná8I²E×-–ˉBËéžRÔNÄnÑn9?ÿ1Íæñø’$¾¶ívE«5$Ú ‡¢vXäLJ‹[æó[šÍ»Ý†ÍfÎÁh3 ›ÅâUÕêL °¿.ÑŸEU5ºÝ#>ûìÿD–UNO?áòò+4ͤÕ¢ª:¯_ÿbßXæíÅ€½‡J®ÉsÑÒõtTU]7öëY%77¯öŸ—S9ggŸây 4Í ËD=³®[¨ªF–íHÓxŸÇ0GËòèõމ¢Ž°Ý®eEQñ¼ß¬n‰ÿ7Ñ襪UUâûm€º,á¡<à›"å©!þ;(¿ÏjÂã<Îã<Îã<Îßgxp6âÿÙ‡lv;‘ÁPU:½&Ë8¦¬*\ÓdÇx¶…i›üÍ/yïé1÷ë5½ À1 |Ë¢üÕÿý+²4£ßnp|0@QËÙ Ó~òþS’ÖEøÝ ,Ûäí¯ßayª®’ìRÚ¡ÏäzФH”EIš‹µ'€t—´T]%l¬çk Û@’%^ýüëéÝÒëÃm´ˆÈ÷ÿ4ëb÷ïîëV¬ª¬ÐMÍ|ƒíÙ¨ºJžæ¬îWd»Œf_Ô 'Q‚$KÈŠL{Ô+V–Qƒ'«²ärYâé§O‰£ES¸øåAƒ4NɳœF¿AžåX¾…íÛH’Äý»{tS'ì†5 ²*+~ù_~‰nêäYÎôrŠåY¸ —ÞqUS±}ñõöû,&¢Ì Aû¡ sÐ!OsFOG„Ý/þâ Îr^ÿÝC¾w$î7h,& Ò8ÅÚ»cš¡aXF›iÛuÍs–dµ(êvDþ¨Ë›/^cØF]3½^.H“”7Ÿ½ar1ùŸHˆ¶hùÖ‰né¢k/$m_(šX³›Oæ¬çk¢õšË__’Æ)¦+ †Y’1<Ò´XÌå}·Ý´B~ò/ÿ”°ÑÁñ<²,%h6D£ÛjÃÛ¯_¢ªÂõ ÛM!j\K\±_,¸¹-T‮‰Õ½ªÂ¶}q_QX¯gŸ=Ãñ¼=ÛDä&Š"'Ž×8Nˆm{ضã„L§Wu²,+¸nƒåòY–0ŒýÏÑöHÓ„¢(j²¼¢h¬VSšÍY¶ãòò×X–ÇpxFQdضÇj5%Ž×¬VSTUö=šÍiºÛ“Ý ‹;ʲ@UEÓ—0 ¼aØ §4}ÒtG¯w„ªj¼yó+ªª¤×;&º†Ãz=# {ÄñY•ÊAÐ!Š–TUÉv»$ME=³eyȲ‚ã„t»‡´Û#6›9E‘“ç)Y¶Ã¶½½`1ɲ”yY"É‹û%Ù.Ã6 wK‚N@‘8¾#VÅ¢-Ûõ–ûw÷ŒÏFÌ¢ˆ£³1eQòô骮bXŠ,“§9²"Óì‹vUUµèÈӜθM÷¨Ëê~…,Ëì¢N €º©“Ä Gï‹û|Èp(ªòpÎ!Os&~ôo>d3ßÐ=ê‚$žq×ÊÅdé˜,ï–L¯¦øM‘ñš¶gÓ·ét;"Œ>½œòÕϾb»ÞÒ¶(‹’íz+èò’$*™u$‘91]“ë—×HHÌo稚J²MÐ-²*ÅA{ßöàŒ¹ EUXÏ×\}ÍÍË^ýâýã>“‹I ¸4l²´<ÑÞôÀ˜qB‡$Nðª¦îð6y&뺩“D ¿ºMEìô?¬­üŒx#Ë2ÍA“óŸ3½¾ãÉGOè aÔè5œ(òB¸:†¨®nö›Ìn¦Ü\\‰õ¿hÇìj†ª«´-žÐ?â6\²$ãÍW_q{q#*/&¼þå+ÏŸ08sóî Š¦ìsI$iÙ.š%HØêôQE°nQŸ»€A]7é DP= 0L“,MY.ïÑ4Y–ÉÒ”NgL !{xz†ªi¨ªF£ÑÃ÷ÛÌfWhû<×ÃUû0ìpuõuV/Šœf§GšŠê\EÑ€ŠÙìzω1 ‹áðœÝ."MšÍE‘×pGÏkáû-þê¯þ#ªª³ZMqœ°®HÞnWû {UÕëûÑu“Åâ–»»·Äñz¿ªfì›À"‹[ž<ùˆív]‹*Çñ÷pWQ> Ę€6:N€i:T{Z½½_³kÒhôê•1EQ)ŠœVkDQˆö±!òÍ×wËòÐ4Çñ÷y…ÅbR»dªª“e¢Åïþþ¾ß¢ªª}v¨¬‹~g2Eß|ÿ›Ì?(ò8ó8ó8ÿo1ñí÷›Àømoß—;ùvÿqþð™¼l†³“1²,£È2ƒ  ëûT@àØ,¶[\ÏaÔhp³X È2‹íU–)Ë’ålåZ8†AY”T@xäeY¯eyNÐ øüóW¼ÍØE;:½&†m°X¬)ŠB¸–‰:4ZâÀ£›:‡Ï(Ë×4ù›?ÿ%Ý~‹ËÛ{A³ŸÌ¹y7ùgqóêE-V†e°š¯Ñu­®"õQ4…ÞqO´b"¯ê*½ãžÚÚ4º L×dv3CVd®_ÝÐ;îaX݃.ÝÁc±\ ¿å“l“š»²Yl@‚W?EØ ÉÒ IÏãéõY–?Ó4)‹’ÎAGp_Š’ÎXäF§~ú?ýÃPÃÞQM×h›dIÆjºBVd¢EÄÝ›;A“_nȳœþI7 G‹»nèÒ¶8ùð€îQWpE2ѾUä÷ïîÉvâ~ç7sò4çâ—˜¶)šÐ$0шfy‚S²Y®9ùðY‘¹{wÇv¹ÅtM‘…Ùó`T]%ZEhºFÐnðöó·âJu.*ª¦²š®ÐLþIŸÛwWäYÎñû'œÿøY è´›ÉÛMáöõ-nCä…œÀ¡Ùê“ç)ëåÛ·EU’¡›:¶í“'y Ð 7µÅ­Þ^™Äؾ]7­Íî&?}*¸(EÉÙùÇÌïïIv;²,e0>ÂözcQ\yÍŸ)Š‚åâð‘¥>€k††ç5ÑuËòˆã ¦)œ´²,1M—×_ÀhtŽãú4ýºíK¬ŠÅ,—TU£×;®åeYÐé²Ý®IÓggŸ°XL0MwvŸ’ç)ï¿ÿ¯ØlTUÉf3' »¸nˆç59:zŸO>ù¨ªŠ41M‡Nç€0ì2?g:½$I¶ûPúbÿ=Möbá–ªªpœ€F£·o×Úîöóù„Ý.BQ4TU%Mw{*|A£Ñ߆†³I´ÎÏ?% »ìv[‚ Ëbq[·žI’DQä ‡§8N€ã„†Ååå—¸nˆë†{áÖüïx)«•ø]D¹ÿ–åqçqçïRL|[P|Ÿø.áñ]õßVYüû„äæû’GqòÃÎÓﲆ<<ŠzXÇA–$BÛæ~³!+D Ü1 Ö»ËéŠ(IP…››)=ß'ÉsaÈñAŸOO(÷®Å 0T X-7hšÊ¸ÙdÐl ¨ ]ß'소›MTMeÔï`9’,¡)Šà‘ 2%‡'CBÛ&M2îîç¢IK–‰71º¡vBÚá<<*LÛäÇú1¶+`‘žï !¡«ª`Œ¤¶®³¸]°š®ØÌ65ûÃoùdI&„©3»™¡›:n(ö²"£é—_^â„¢y«9h ªû&æô“Sq5~—òé¿û”,ÉøÑŸüˆªªÄšÔž}Òì7k—À°Dá@´Œž E)Á¾1+Ï÷àÄMŒ'fôtÄÝÛ;‚v€¬Èø-USž±»nézX;K¶‰Z¶ ·'q‚ßò)‹’áÙPˆ‘Û9¦cÒè5Hâ„Ö E£ß s(„’×ô—¤(h [ÂIñ,4CUËŠŠaܾ¾åøƒc@0h$YÂtL:ãnÃ%ì„ A™—xM¯®Vøê¯¿àô£Sª¢¢È >øayó›9·¯o…8ª K2ÂN³fÞ(ªBž mp: 8âùOÞ£( 4M'K2 ËÀ²ÒD 4º­4Y–%›Å†ÕlI‘4š]T]åþjÂn»£;¿#’,±ÛƸ¡‹ãú8¾‹¼üòl–+(óZõà2‰,S‰n˜¤ÉŽívÅf3GÓ5æó[ò<#Ï3E£ÕaY.I²¥Ùê£ë&ëµh¡’y¿r$^O—Ë{Fã3Z­!º.21,Û¡i:ͦ¦w: ‡§\]}I»=Ü?FLUEŽiºôzÇX–ÇÕÕ×{úºÈæt»‡Ìf7{¤¢(½ß?Ím† È´Û#Öë|ð¯i6TUIžgdÙŽ è°^Ï1MAr¿¼üŠÅbÂbqGtÐ4¨öAäutÝ`¹¼ß3 &“‹Ú‘$árèºY;Bºnâº!Y–¢(*IÕ™Ífï·Ds¦ã8!ºníy5YýÚQ9AÐ&Š–uõñ£@yœÇyœ’âà÷q$~ÛíWòü·ÿþ»'ß„ü>‘ñmÑð»ŒÇùÿf~ñ—Æ)‹Ûÿ×_†oY˜š†®ªLK,MÃ5M¶iÊpØa—e¨ŠÂ‹ÓCn–KYfÇÈ’Ä×··„¶aêdEcüåûŒxã™&Ó(¢¬*Zý&oïî1L4ÏÙ,6\O¦Ä›X÷-\mã7<YÆÖu‘1±D¶"Jã.É.%ZFÜ]ÞSU½A?pyýó×ì’S×±=›tORÏË’ÝfÇáAŸw×w<ýéSÊ¢$ŽblÏ&OÅÕõÅdA´ŠH’¯é±º_¡½£Yš1½šâøŸýùg$qBžæì¢8üoZÃa'd~+¸#²"Bý/ÿú%ý“>º©³]oëºÝ°²]më5µ<ÍYMWôûuFÕäͯ}»Ú2z:ªƒû–+œ¢xSU•hîRDø?ZEL¯§Tˆ<‹$I˜¶ÉôrЄĸù¸ª~ƒxcػ͎íjK{ܹY¦Ñkp÷öN|öUÍóÉœáù<Ùš²þxƒD]õ¼š®p.EVÔÙ™ÝvG–f¬gk†'Bиf½âfØF-–÷K$I”x ¯>¸/n,ïE%OE3›né,&sÚCኼúÅKZæcÒ4©Š $jK¼Ýà·÷3‘YPZýI¼#ì†ì¢YšÒìù…¨hŽ£-Š¢"ËJ}»f¿ª«LÞ]£›‚Òˆ@z§?¤,KÞ¾úšáø óù;]ª`»]a».ž×äíÑÒ5ŸßÖmc†a±Ù,€Šéô’,MÑu‹çüüSE8Iºn0›ÝˆjeYæúú%Ëå]ݪ%šÆJLÓ!Ž7hšÎÅÅ/)ËUÕi·Øl¸nƒõz†¢({1’ˆ–³Bˆ®ûûw´ÛèºI³9 ß?Ŷ}ÎÎ>Á0l’d»/(÷Ty Ót¹¾þŠ»»·´Z4M4«%IÌÛ·ŸE¢] $Š¢ÀqBV«ÙàøYí1 ‹fsXÃ)_¾üEÝ·¡I$É–4ϰ,F£G£Ñ#Ib¶Ûõ#åqçqþñ ï¿+ 仉ßvû?„<ÿ}Œ“ï:ôþ6×âQ€üÛÞI“燌zÌöÎÉë»;dYæÝ½¨îxë8Æ5M Ue¶Ù0™-m›»ÕŠ»õK‚÷,ÛFWUÎ?xÂÙéH ÛæíÕ„q³I¿âÛ6W‹Ëû%'£>ÍA“ç'x†Ažæ˜ªÊn—0[­Q7t9ôq ÑÚ4›.‘d‰óäÓ »[q¸|úÉY½*“gB<$q‚­ë ûm^½¼DQ4U¸^C´ˆ….woïwãTÔ Ûž-Ø!‡½š±²Ûì°<‹þô#¶K!4LǤÌKqø­*܆‹×ôÄÊPœ-#N?>eq» ^Çt:âª<ñ&ft>ª™1†eà5=n^ݰž­I¢D„Ò™8Š©JÁaÙ,D+Y¼ŽÙnD+™ÛpqC—]´CÑLÇD7u†gC ËàÓ÷)7¯nȳœ<Ëùåù%Ñ"B·DíñÃ×”&©h_Û¥u6èõ/^³š®0˱ÈRÑÄ•D ÛõUUk§ÇömÖÓ5¶gSEÖ(ØÌ7ì6;Ý~˕ĊÌäÍ„«¯/Eé@Q±Yl¦¬èvhôè–^;€ÍASãQUm¹o?K{Øa·Ù‰\k‹Z↋×ðêzã8ŠI¶ ^B nàã5=¶«-Ëû²,³º_¡ê*º!꙯.Þp}ýRäo ƒ÷~ü)–cƒYšRYšašëùUÕ@à uÃáeY°˜Ýcš.aØ¥;1>~Âb6Å ‘ëp^pwsôG‡T•®Ûàúúå>[¡áº <¯I’Ä\^~‰eyèºëŠV¬h³b·‹$‘{)KÑd•$[ò<Ã4m¶ÛÕ>›QpÿÓ´Ñ4ƒNçYVëÜŠi:t»TUYçW' Mc²l‡eyûœˆAv¹»{ƒm{èºIž'5¡þÁ±HÑL¶ÛEèºÉ|~ƒ®[{vIªj´ZCÆã§{ÞIƒƒƒçÌç·Äñš²Ìqœ€Áà”óóO¹ºújßʕ׼–‡ÛE¾_çªh6ȲR×HGÑ’<ÏÙí"šÍ’$ÿ #åQ <Îã<Îß¹«ñ]ÎÄ÷¹ß'ü}¯r[,|×û¿ÍÅxóÛ¦ÌK±šUU”UE”$¼?‹+óŽMœ¦–…¡iÈ’DYU¤EÁNŽˆ³Œ'Ý.ºªâš¢Ê³,ËÚiYo¶lÓ”ÉtÎz·ãxÜçv¹äz6'ËsŽÃŸü«#Iƒ0d—e”• _ÜÝó¤ßCQ.îï‘$ [×Ù& ñFd|Ç&Ésž<=Ä 4S£dIâ°Ó&ÍsÒ¨(~` ªJºK9t¹øü Š¢ˆ«¿iÎânAºKè´Bqµ¿®ÆÉñ‹CüŽåYlW[:‡¼¦‡ª«(šÂÝÛ;¨@’%&o&h†ÆôjŠíÛÈŠŒÛpi›è†ÎÑ{GxM*ÄJ™cÔëe¶ocy«é ÝÒµ=p?×â'ZD‚ü®*¢føVÔ [žU»*IœÐ4±=›x³]oéŸô Ú~ÛçÅ¿ Òçå_¿DQÓÅoûø-Ÿõli‹¶xÓ¶p|7tkзI¶ ãçâ9³ž‹ö4ES°}Ã6(˲fµ”…(HhÛDˈְ…a¤IŠºlW[Î|Îñ'hºF¼‰i ZÈŠŒí‹õ I–ÐtÎh [Ï× Ï†è–λ¯.H“TTZ-®úÇ}.~uA{ÔF3Åm-ǪW±œÀÁkyÜÝ\ ÷(ÚÑw‰ãUÅE^pyOØhÓï‹Ï‹·u=ñvq{ûšË‹×¢Ù™¬ Ý`q» ÏDFVÄXU5t]ät²]F¼‰éôû˜Ž)‚ðÉ®¦¶Ë²Ì»‹¯9>þ ¿Ýƒ«ýÚXßo×Mci*Ø9¢‰lŽë†¬V÷¢m-Zây ‚ Ã|>A×-ªªD–îîÞÖ”úÕJðSf³kʲø½›¼Êã<Σ øAñ»ŠŽßÕÕø®ìÃ÷¹ß%¾è~ ó÷e¦×S._^ÓpÛFS,MãɠǸÙäó7ïPd™§ý>ƒ0DWUšM’_QîýËí–(Ið-‹¢,¹šÏ9ì‰äùx@’ç(²Œc™(²¼¯L•I²ŒÛåo_g¬›:O‡dIb³ØÐö÷ÂJ7uÚý–+j˜X.º)šÉú'}®_^3¿™#Év`-#6‹ ^KˆÌ l žªðîë zCLGT;¡Ãv-€ŸíqG8kOÆhº`Óx ŸƒÃg8ŽÏâ^dG¼†S ¨¤G',æOžÑ;î]3•õrÁ|vKEÅÕŦicZ6®0^"ÉaØ%ÏE¾b1鯿þKæ³[Þ]|YÃçó[ª ºÝC\·Áííë=Y=Åqäy¶Ñ/éõŽöîÅÓtX,&¬×³úq’$b³Y¢i‹…à¶H’8†Çñº†G>dW\ßoÑï3ŸßÖŽ‘i:X–·¯ù]ÕyVKT †ÃÍÍ+LÓÁ4ò<£Õ’ç)²¬°ZÝóñǶw=”:ì/ÀŽ%oÞüŠ,Û1^a6ž×D–U4Í@U5®¯_R–9¾ßÚsjt‹ aØ©EL£ÑÏuWTA? ”ÇyœÂ"㻄Ä÷}ì»2ß%~ŸÆ÷e%¾øÛÜGçâqþ!åYXž…"Ë|=™`hYQ0"Yæ°ßE‘edIâÍtÊr»eÇÌ¢ˆn»Áf·£éºdE!>O–5„Žƒ®(ø–E^äEÁóÁ€~ È2Q’pysOö‘÷îˆ"Ëš ×ÿêâ-«8æøp€®ª Iœ>SÍa“8M‰â“7ò²¬EQ8÷1T•^¿E÷H´liŠÂÕõ=y–³Þlùëÿö9i’Šà»$aX‚Ó!IY’1™-ÐM¿ís<ê³M’8Ù„aKä_Ö[!,J±¶4:ÕhYOIœt‚®p,$Y¢sÐ!ZE,ï–¤IÊù§çôGšƒ&¦-V²ò †m°ž®ÅZ•k1»žá6\lÏFRDFã!?ã²"ŽHš!€ˆa7$Óš ò@zW4…F¿Áz*reQÒ=ì¢Y’±¼_¢éÇcùeQ¢¨ A'ÕÆ¦N¼‰ Æ6ÐLÑùÛ않ŠÍ|#ê…ûͺ x»Þ2¿×K'?:ësÑ®Iiœ2¿™Ó9èðWÿñg,'Kß;¬owÿçdI†íÛµØ/¸ÔÏ<ÍE~E“nJ™ IDAT–;¡p‰Z>›ùÓ6I¶;$$&tS¯ØÎ?zŽã;¢zZ’p|‡f¿E´ŒÈvYýýØmw@´–É£³žþøE½føðúŸ¥Ûí’No„¬È\¾º`p4Æñªªdüä /ýËZ̦·(šÂxüŒh½Â }ÖëeY‘¦;¦“[¦éàû:²XLPU•(Z1›]“ç™Xß+r²l·17H’Œ¦™”e‰aØDÑ‚ÃôZ#~òÓÏj5ÅóZ ‡§¨ªNv1Mg/ 2tÝÄ÷›8N@¯wDšÆ4]! ·H’L·{@-‚ö¾µÌÀqB‚ Íáá{„aûûK\7Ü‹ŠispðMÓ99ùÛÛׄa—F£Ïb!ÜY–qݳ³O„°_Þ¡ª:¦éÖÿ¶§éŽ,Û±ÛEõ×®(Bˆèº‰aX˜¦Íf3'M Ã&Mclۯݟ߷nøQ <Îãüt9~‘òmWâÛû¾õ©ï fŸèøæ}< ˆÇù§<¶g3vð-‹y=¹ÐÀÙ’Ÿ_¼©…ÃõbA^–¶ZÈ’Är»­×º[-6[,UeK×ÑCU‘%‰·÷S¶OÛ-M×å¤ÓáÙñ˜ÛÕ Y’ð-A›WeY´wõ:lÓY’Ø¥â€=Y,É‹‚g£!ºªº~Ëg›$üìÏ’„çÚÌ£ˆ¦ëbé:T0CYf<ê Q¶¯ìvZ¬î… ä96½¡à»=?D34ü†‡¦(L7vqRÃUMEß7p=dÚ=r|úé9^Ó#h,ï—좚ªâøÃý㛎ÉÑ‹#áHXYš±X¡08 j*Ýžà4¾8Äp .¿¼¤¬Díòäͤ^1C‚<Ï?£›º¨yÞ†«JdU¢eÄâVTÁyÁzºf»ÚÖ5ÌY’vÃÚ©ÊŠãpR-\lªõ¹½ã^½rÕ4kÒ}ž‰€¿íÛ"SŠF«åý’írËá‹CO„Ý't(‹²n³}7tQ4…ÎA7t9x~€aüøßþ¤þzž`Ø÷—÷¶ßö¡ŽßöÙE;§šý&W_‹•-Û·YMWÌnf€7¿zÃìzÆÕ«·®ï×døf³OÐhÑêvi4züäŸÿ[6Ëq¼b½9­vû7aAЮ’»Ý–ªeFO”F,îp‘‹yûös:4MŒ˜íÓ¶0M‡óóŸ°\Þ׫S¿iã²X­fìv[â8ªCøÂ…Yáyš¯òÀ5Y¯g ‡çÄqÄ`pZ‹…VkÈÕÕ—¨ªÆv»Ú¯ -‘$™'O~Äv»¢Õ‘¦1yžqtôç矢ª:/^ü1FYV0MUÕpœY–"Ë2š¦“ç"Ï" Ž6ÛíúQ <ÎãücqA~[˜ûÛÎÅ·sßåXüøCݨy1ómª²bmÙìvl’„ƒV“(Ixïø€<Ëy9™p»Zaë:¶®óüÍ/Øe¾eѰmzA@œ¦üäìTÔÿî×µÎz=Ûæ³/^ót8 Ò}»W”$”UÅËë[îV+aÈd½¦,㘓ƒÛ4ÅÚ‹#Y–yÒéÔ™“(Iö¿a[82Gïq;cé:­mÏcEŽÍír‰kš,¢ˆ^«AÃqž …sâ¼YG[&×S²89âÇ''ôƒMQ04 ϵ„!²$¡È2¡m3Y­0T•]–' Iž£) ¯îîÄz“mÓß Û0èx–.2+_eY2"Þxs=Á³,[-vYÆåDìÛßÝÏ)Š‚¬(ÐU•8MÑ…À¶±Lƒv# ëy"C‘$ô‚€$ËXïv”U…©ë8†ÁÕýŒ÷NÑU•V+ä×77¸¶…fj„¶Í|ºdÇ(’„gXšFà»L7L×ÄwmÒ4c²XŠF-Ëà/ÿÓßðÞéíf œ Ó‰ú*¼³g²H’ÄáÙˆåýR¬€mÚ݆țX:Q›xSäÉ6áOþÇ?° †§CFOG¾wX%A„Ôw‹røîów´GmÊ¢dr1ÁtLFOG8C²M(ŠÃuÈ·¯oé W§5lñä£'ømŸþ±Ñ«šÊûÿòýzýí9òP›vBò,çæÕ Y’±™ohšt:8C– gæì“3Ьàúå5–g1»š¡[:÷—÷4ûMLGY‘™¾› (eœ2¹˜pøÞa½Þ¦¨ ~Óù”¼ ÛeTT$[(üð_H–fužGT &Íõ×ר×ô(‹’þq¿vCvÛº¡-"žþô)~ËÇlÊ¢äíçoyóÙ›zlq· MR¦WS!°!zLW0Zœ@äiÖ3Qà6\LÛd»4ú»·w•Ù?¶¢*¼÷ɧlW[LÇäþzÂânA´ŒhÚ Áz¶æþöFüüò‚,Kp›.~ÓG7šEó šÒŒƒƒ#tSg½š3¹ºdzÅÍÍë}(Üf4zZsLtÓÀ÷›Ø¶ÏÑÑ{?ëŒ~ €ÿÿ&Ïf×üüçÿ‰§OÊŸýWâxC´Y.ïêJaËrkÈb§3$tÝâàà9eY0Â=ʲË«nki‹Å]M’ŸÍnh4úÜÞ¾f08CQ4NN>¬ÛÃß#MwôûOHÓ]3¹»{Ën·¥ÙìSU‡‡/öàI—v{ŒeyôzG¢)Ðmày¢õLð^rúýZ­Ñ£@yœÇùÛ¿Ëm¿òýÍ÷¨žöû\ßemê‡\ÇyœÇùÿoZí›»ÞžwÒñ}¾¼¾©EÉÛéMQˆ’„m’0 CL]§éºÜ.—⪯eñùÕ]ßçI·ËýzͯonÈ‹‚§Ã«8ÆÔ4VqŒ¦(hŠBV¶º_¡êw«’$Ñï4ï©õðâpÌ.Ïù³O~D`Û\M¦´=q³I/j§ÅÖun–Kl]g '#/KªR¼¶D»Qš²Û¿ÇÞW#÷ƒ€¼,yïäÇ4Q5•ª¬x3’—%W·SÖ›-†&2yQàÛ"þìé½fÈ¿úwÿŒÉjEV„-q>°m$Y¼&fyfh¼7‘ñ¸Òœ%»T¼ÕlM¿û›Öªuã·}f736ó¸2_VHH‚'¢«4z ¦WS¶ëm->úÓ¹v7lßf~; ¶«-^Cð ¶ ñ:®ƒçÛõ–·_¼Å° “a7¤Ò§{Ôåàųëq“g9†mpöéÉ6©Žéšâ±n椻´Îä½'‚/D›•,×Y”‡Ãún»#ì…‚…ӘߊûP5• ÔõÀÍA“Æ Aï¸GÐ V›¹`¯hºFÐ ðñ:æüÓsLÇnˈh%ÞÖ³µ\²Œfj<ÿ£çdIF–f̯çdIÆéǧ½w„åZ¨šÊàÉ*ˆ7±Èñôè¦^ƒ+-WdºžP•^Ã#Ý¥øm'%Í^“x-8/^ÓÃo 8h¼‰q<"+DKšeQöBší.²"ø£ÃâuÌ׿úÃ6$ ÝÔ0T‘…p² V³qÑð¼†p=ÏéõE{\ž§͆p—lÃ6i´Ûìv[‘—Ùljw¤(Dý®i:A‡VkÈññ‡l·KŽ?¨]¨££èõŽÈó”««¯ðý6yžíƒíËå„Éä Š¢í4Ýñ›£‡„¦t»‡¬V÷†Mødv89ù²,ÓïEKEß7Ž¥4›îîÞ욃Áé~Íc8<­÷iºãææåþÜ!QU°Ù,H’xÏyÓhôØnWÜݽ}(ó8ß'B¾/PþCð½oì»Ü‹ï –ÿ.ÔîÊ}üÐ< ‘Çyœ¿?cë:͆Ïr»ÅÖu¨*¢UD/¸šÏqM“‹û{ MTøŽ›MŠ¢Í[«U}(ÏŠ‚–+\†–+‚ªý0¤¬ª:_bé:׋Q’ðr2a³Û±M6I‚¥ël’„‹û{kLŽÚm~ñîóí–ÙfC’ç´=Fèq¿^% ¯'wEÁû#q•³¬*® Þ\Ý2Ýl†!qšòáhïzöäᾑlÔh0Ýl¨ªŠÛÕŠ8I8tiynÖ~¸ºÚé`ìƒãºªr2êã[b¥ÊÒ4¢xÇ»Wל÷Ð1Í…˜è„–!8¿¾¾Æ5MfsѸuúüÇ4P4]U±›ªªh>ª.\©a§E{ÜfxØãÉÁY‘Ù®·(šB‹ïåZ4Mæ·s,Ë`x6$ZDh†F§Û {Ø%h„°&¼Ëª8ì‡ÝÍÐøøÃsáæ:o>{CØ k¡¢›:Ù.#èHf‹éšhº†fj5@2ZFyÁðlH÷°+'{8%ì6;¼¦Wƒ77‹ ª®Òµê ˆfhØ]¯±¶ø O‡,& LÇ9E¬­%qÂz¾&Ù&,& !z|¿í-"ºGÝ:Ó4 ;!Ï~úŒƒ¾Áû4NëÚé³OÏD¶EÃ6XÞ/±\Ñ„fûvËQuá\UUEUV”U‰éН­9h²‹vÂ!ZÇlæ®pzG=N· îÞÞ±Y®ùèO?¢,J§¢E$`›ª‚Äo€•–+œ¾8ŠèFuÅtY”uFF’['˼FÀõ›7H²ÌÑó®/_Ñ;îí¿~•íf‹8¼üâWÜ\¾AUUÖë)y&*†ÃnÈf3ãââW,—wÌf× Ž1^€5¤2Š„í&wwoY.ïe]7ö Y+4ÍÀ÷Û¸nÇñɲ”,KÃ.­ÖIR¨ªÏkb6¾ßF’d‚ ÍÁÁs@b>¿Ý»+“oœ_J¢h‰,Ëø~‹0ìR9FŸãã(Ë×m Ë Q´d4:Ã4mÁ´ÝØøÍÚg× Y¯ç¬VS Ã~(óè||[Œ|Áû»*m¿Ox|WEî¹´ïÇyœZ³I\ÓÄÔ4Šª"Î2:Ý&w«χC–Û-£FƒÀ¶±u»õš¬(h{ïFœ÷û˜š†oYüåÅ_ßÜòt0À1 Vq\¿ úA€gšÈ’Äã1¡ãÐr]ñ–Esÿ~Ûó¸œÏ9ëõh¹.‡­o§S.çsaˆoY\ÞMi¸’$Ñõ},]ç¼×ÃÒuŽG}’4#- Îz=Y&°m>™GHêÞɱuж‘Ë0Hóœ¢ëWŽað?ÿÉq6è“:ZˆÍ¢ˆ¬(pM]×øé'/˜E½NCÓöÛä…88ži8Š,³™oð[>YQpw?§å{\|õŽa£±¿Ž Ù.C‘e^¾¾DSU¶»U–i´zã­VˆãÚÜ^Ý3u9<0<2¿_>\Œ¦ÌK4Eay·ÎU’±‹vØžíXtÆ©ê*š¦r·^Óè7xñéS_RdÂù9x~@'ÌnfXžÅ§ü^Ó£*+Š\Ô?8 A;`³Ø°˜,ðÛ>Ûµ¸"Ÿ§9†e08átØA34Ú£6—_^²]më&17t±<‹ÎAUWë&-Ã1ê NÐ È’ I’hšœ~|Ê‹?zÁ§ÿþS¢eD¼‰iôܼº!Sžüè‰xÜq‡æ°Éf±A–äºjZ34TC­WÙ6ó E*V§šý&š© Mèt**æ·¢e ¨[ØÒ8År-V÷+âMŒÛp9ýä”"/p®È³ìõeY’§9Oò¬n]+Ë’ö¸-2DeEQ(ªÆ›X@›!½£žÈ$õL®®QTÁó1m±nÖhu ‚Ÿþ¨¾Ÿ“óè–.À¥¾Ãj9ey·D«OÅ<ûÑG˜¶ÅѳSÁè±<>üä_pvö Y–°š®Èó ËrñZBhŸ¡(*³É„²,évøôÿ”ÝnËøèTä;-ò<£×?$ËŠ"GUu6›9Ž$³Ù e)~_|¿‰eyµË¡ë&¦éÔ`JU¢x4:g>¿!Ï3ÆãgèºE’lñ¼æÞÙ²ÙÌ©ª’§O‚®[ôûO88xaþÉhtŽmût:ôzÇìv® Þaáºáïv¾«þž ~èÀùxØû§'>¾kÕé›Ï“oÿýw}ü»nÿ»<Ÿoó8óû¼fü/ÿëÿFÿ ËG‡‡ªJYU¼¾¿‡ï͆(MiØ6¡m³ŒcÃ@WÒ¢@Ö»¾eq¿ÙpÜn³Ùç=ÞN§œv»$yNYUôƒ€Ÿ]\pÖí’æ9ͽË2Y­°48˸[¯y4âg¯_ã™&žibî×°ÖÌÖ»¦¦¡Ê2óíCUéú¾è§)¶.V‡~öú5/†CaÈÝzÍ_¾zÍi¿W¿N®â˜ÃVK<þþ1lÃ@S¶IÂå|@`ÛÌ¢ˆŽç!Oº]® ÞÎfœ´Û\/—eÉy¯Ç¯onh{‹í–Ón—/®¯9lµ¸[¯±t]–¡+ ³(¢é8DIB?¸˜Nq ƒ¼,Q$‰8ËX­#ž D‹RÓuùìòR4ji›ÝN0j.Þ‰,HËGSâ4eÜlÖ?“«Å‚É»;†‡=Vëˆa§Åf·ÃÐ4>ÿù×tº´}À¶EÖg:ãæÕ ƒ'\Ëd±+eC±¶WUÝ à×_^ ¨ ~‹ë7·¨º*VÉd™$NøØ{“&IÒ3¿ïçkxì[FfäZKVUw5ºÑ؆3$‡&ÒÆŒI}d¦/!ÓU7¨‹>€d2-Šj8  »ÑêZ³r}óðß×ÐárÀÚ@ŒÍˆù˜•YUVV¤‡gVÄóÿ›,ËywËð|ÈÁ£¼µÇÉq—…m3ºÑ}Ð% "&7Zݺ¡3¾sðø V5EUØ9h³6m¢ ÌH½$ÀÏ6*X’%´‚&ÀA¡h¢Q~t1úeíQÛþEQ˜ætv_©Ô+”eÃåºhu[øŽÏb¸Èý/ÖÔbÿtŸ×?}Í£ï‰À­ Q¬™ÜLHã”j«JÆ„~Èr¼ääƒÃl Ú=(‹Á‚ý‡ûÌz3Ñ¥rz@šŠëmí·Pu•Õt…¢)‚åÚ•Éõ„ÚN4Iéw°M›áùã÷ñmÛ´‰£8O[3Ê¢ds5[‰ÒÈ$Ë»lÆWcjmñX“ë O~ð„ñÕ‰e²*ã­=.Ÿ¿àøñ}JµŸýÕßðOÿó?cp6 ‰ñ½—eâ­L1bJuQ J&(…È(×ËdY†·ò˜ŒoÙÙ9dµšS.o &«%7—Ý;ų=ê;uÌÉ‚årŒªê”J¨,—TUËK"߉NçˆÅbHµÚ²¦H’œ'qÍç}â8¤ÙÜòfD‘Ÿw±DQH©TÁ4ǽG‡dYЦÏ‘$Û^ ëEz½×¿õuUýûöBÿuKáÿÀÝüýß|p|ùM€å«Ÿó»;`r7ws7¿ÏdiÆéîn¾°zuÅ^½Ž¡iŒW+žЪTY–çÑ(‰$­•çñþÁv «*'­;• aãÇ1ôð!Ïû}šå2ÙfÃÊóèÖj8A€Ç´*ÎÆcvk5ÞN&tªUvk5ºõ:ÝzÇÝ./:µ^¡Ê2i–al{ZjÅ"Õb‘z±ÈÊ÷ñ£ˆÝZup5òƒˆ’„ÁrI¶ÙðáÉ1p»X KÍr™ËÙŒJ¡ÀA³ÉÒuñ£ xÒír²³Ãd%X‡F©„†ìÕj<ï÷y´·‡Ü,4´*’,ãÑž#Ëâl<¦^*áÇ1þöúMÇÁ𝸝þÙŸð“‹ vk5 š–ßÓ`ëšZ+¢@€-EQ°}/éÔkDIBÅÈ’ÄáÞ²$!K¯Þ\ ?L½Î̶ â˜J…¹² ± )8ëQ5U–ùÁ>`麤› ÙfC»Ráüz·Ÿ/-›Z­Œ±õݸ–Ëî^K€Å‚F{§<}ÿýé<_¢+õ2q”`:’$QïÔ)EªW¶Ù`h‚‘e™v«žË¹6› ¿sŠm»ìí¶¨6*ôÎúT[UtU%Ž„I=ôCz¯z<øøÞÊãáÓ{d› q’0íÍЋ:i’ù;G;4wÅÉ·^…—•f…ÕtE¹^Î}8ÞÚ#K3öîí‰Þ™¥ûx:ÇtC<æÞý=†çC}÷ͽ&¯úšÃLJDAÄéǧ|þï?§}؉ZªlÅŠèy—TöŽšÞLsŸLè úƒo?ÀwDQi\Ù½' ®ž]!IÈÒLDkÛ½†øÕ"“ë q­«ùŠb¹Hû°Mà9ÐKâ„ÆnƒÉõD°Y%–Ð:ÒÀÀ Ø»¿‡¬ ¡R±RäàˆtN¢„À xðä)ª&¤ˆ‹o¡²w²Gàìžìâ,ìЦsÜÁ±4]|×ó5Õf•ûßÀz÷o_>æç××ÜßÙ!L®g3¾ÿàUÃàY¯ÇÊór¹V«RáídÂ~½Ni›ºeE]g¶^Ä1MCWÅr~3Ÿ‹^”V‹/û}þøô”Ïon¨‹¤[ a~1^­Ø­VZÝz$‰n­F”¦\Íf‚e)±¶½0ÍR‰å¶Ìò°ÙD–eüm¬r³\f¤iÊв8h6‘%‰F©D¶ÙÐ7MÎÆctUe·Z¥Z,Rئ•½¹ßé¯P¡€"I¸[y^˜$L¬ïì$"ÞV•å\Nfº.^²S­òoÿú! JSþ죹˜NÑ…j•0Iè›&š¢0ZZÄQÌÓ“#Ά#v"…­U.Ó[˜|p$Ìþ~S5 ,Ïãj8æpwU–óŸ¯O~öœþϾÏÂqXº.µb‘›«!G÷º4Êez³9¶iÓÙUe§ZåÍí@H»T…'Ý.Ï®n¨VËXË5FÉ ŽbÖ‹5c®lª•MãövÄÉÉ>~åÀåâ‹ >úãH³ 04ÛÛ1²*S©Wp×.¡R(¨µªâù¸e£ÀíåîÉ.Žíúâs’H0ÖÔ¢}Ðæd¯Ãdµbx9¢±×`9ZŠòSM¡Þªqû¦‡ª©4öTªeΟ]ppz€³t˜õfÔÚ5áë‘$/Àµ„‰ÿÑwá®\¢ ¢P,0º À·M sW®ðü¬]ï1¯~òŠÖ~‹J£"Â: Xf+ô¢N–eL¯§ìÞßÅ[y$±øY9zrÄË¿ÌûêÙGï18`”¸´M›j«Šª ¯Ðj¶"c* 7/oØ?ÝqÌ~„³tp–íÃ6¾-×|0gÿtßö1G&­ýµšèç‘EàCû°Í›Ÿ½¡¹×D-¨„^˜(8–Ãb8çô;°¦ëÅZHäþ¡(ˆXŒgȲŒ,«ì¡éI’(VJ¸k‡ pÙ?9fÒb"Á¬sÜa1\PmV9ñ’(ò‘eÓÑhìr}ýM+pqñÅ@¹›ßÙø&ÿ›<_J~Ãñ»€;pr7ws7_ߣþç¿ü+Uá½ÃŽZ¢%JnæsþäÑ#Yæj6C•eöê"Bwáº`g IDATªÊÂuE“|¹Ì~£Á'——T ƒ{;¢[¢R(0X.‘eq"Dµb‘R¡€åºT ƒóÉ„r¡€¡iDiÊ͈XžÇÊóxÜí’eçÓ)Ÿœ Ê2Ÿ^]±Þ¦tT•ŽŽøäâ‚ÖÖ«PÐ4æ¶ÍÚ÷±<“v›v¥‚ETág.—„I‚ÂWS©à„!ºªòþþ>}Óä¸Ýæ|2¡]©0³m ªÊA³‰¦(Û8æÃf“›ùœV¹Ì‡‡üøí[ŽZ-ä-ˆÐ…$Ë“„šafYúJºN­X$L®f3¥Ír?ŠX8öö˜¬×¬<E–Ù«Õè™&r™WÃ!Y–¡«*Õb? iU*d[â„!Y– 6'Šj~ˆÓ” Ž1]—ãV UQ¸žÍòžš8M™,–|çô}ÓäI·KšeØAÀ~£„qLšeÔŠEF–èv) ìÖj[É^­XÄ Cê¥=Ó¤¤ëtëuì Àò¼´$iÊI»†šÆa«ÅÙhD­Tâf>ç¨ÙdfÛ$YF’¦6›ù{ë³›[:õíJ…ÛÅ‚j±È£Ý]å2ÿçg?çt¿‹¹ Bx¸»ËÜq˜®×l½LåBz©DµPàj6ãíd" t/½&ú¶tô°ÙäÓ«+ª†A8åôÞ!›Í†r¡@ß4ùøä„ëùœn½ÎíbÁ<@S>¿¹áz0æ¿üãðüÇOèîµ9}ÃGß~œ?~­XäË›[¾úƒ;~üés>úðÇ­?|ñŠÓÃ}Zå2ƒ¥XºmßÇq}Ê%ƒ ¸×nÓ(•øéÛsN:;ÔŠE®çsƃG»ÔŠEzÛØnI–8ÙíЛÍùþÃ,‡³ÛY"Ê3ß{t’³¨?þüðˆ¿þ«Ïhv›<~xŒåyyúŸ*Ë\¼¹¡¶Ç?ýGßfºZ vïÅ%{÷÷¸øâ‚§?x8MùäÏ?áàѵvB©€92Ù»¿Ç£½=þâ/~ŠQ1øþ÷„Ÿësºö}¨ ©u;Ü' ßþRBøíóöº/ÊHMÁà|úo>åÉžÿO£Bè‡ìïâ¹¾ð]©*q’°/…lq¿„9 s–WÏ®¨4+˜#“ÿá¿ûoãëêIþ?qpòMLæ_×Ýñu¦òß$Ãúmfó¯²1Û¥€ws7ws7[¯_W˜ ä'¡+ßgº^£mY‘™®×$Y†,IDiŠ,=7Xù>ö¶+$É2ÜPH3ö›M‘¤µ\r5›±[«a¨*ÕmÿI¶Ùp6q=Ÿ³ò<¾{ïUÃÀ CÂ8æOO9ŸL˜Û6û†IA³t]ž÷û6›<èt¨µRI4Ñ—J¤YF¶Ù°p®¦S MãÑÞGÍ&MÃt]¾ìõ8ŸLø²×ãƒÃCZå2ß½wQšR*h–JDIBŧÇû^åà§ošyr™*˨²ÌGGG¹Ï¤Y.Sß&— - ;h–JÜk·¹],XlÉÞ}oÆ«Óõš«É”“v;_x šÆÈ²˜®V´·ò¹Ár™{nYÆÛ.ô–ç‰òm²š¡i¬|Ÿ•çál‹-Ó,#JÆ[éZÏ4Ù¯×óçeŠ,ӭש üËï~Œ OIQ×±ƒ€V¥Â_¿~ÍÒu‰’UQð¢ˆjMU™Û67‹ãÕŠÃf“0Ž) ÄÛä·l³ÿN%’ß>>¦S­æß»z©„,Ëùýßl6t¶ìŽ*ËšF°í¶© ¢W§^ã°Ù¤T(p¿Ó¡ ª” Æ–E­,Ât:¼p€Ç„qÌý4E¡¤ë„ÛrÎ$˰Ão‹å[–eVžÇA£‘§ÐÛç ©*'‡{ôÆ3ÆK‹éz,I¤Y–w4ùÏIº5Ã'iJ½UÃNáGQ~–®‹aHÒ”0Œ°ƒ€§OÄBÒ'I’H‹ EXB§Zådg‡J¹Èùó+&½)AÄ1G;má“$ñÿ¤]CSU®‡n^Þp¿»K³ZÁPE8 ^š¤´; ª­*š¢ Kš¢PiT(¨"Ò:c ªŠë Ã~ºßš¡±^¬Ñ MQ“„$Ëhî5 ½iLQ+9ýÎ)§TQ|ªŠëªJ¹^F7tÜ(Ê%†¦ ŸÖ6 Ûl Ò=­ ‡1Ê6ny5¾J¥Ds¯‰Q1Ð ]EüÕ ¢óéÝa…ª«")N–1ŒBþSÓ5MD$ËÊo‡ÿ ”»õoŸúM2«ß–XuÇjÜÍÝÜÍÝüòuõúó¿@R$þäƒ÷X8ÙfƒE¼¿¿/ÌÔÃ!Çí6?|ö‚ï½÷;8ÝÝ峫«¼H±\(äž”(I˜ð<ŽšMæ¶ÍíbÁxjòñc±luëu¼(B–$¶1¿ïD 0]—ÙzÍ÷îßç/_¼äOßÿù3vwš” t:IBœ$ùÒüìö–?yôˆ‘eÄ1%]§Y.“f™(Œ,•Pe™¹mÓ,—s–aaÛ¬|Ÿoó³ËKîíìpÐhðÅí­—Å"%jåyÔŠE¦ë5ãÅ’û{èªJÇœîím¯§^*§)~‘doÇcÞ?8 ¸H›­ç#LŽ[-Ë%¦ãP+1]—ޏœNÑ…â¶Ï¥\(ˆ%*0š™üé‡OùÙÅíj•{;;¼ Ø«×sÆfh.ùþÃøQÄÛÉ„Ãf“¡e†ÕR‘ýFƒ )aUÃÈýDNàåB¥ër¿ÓÁt]ª†ÁËË[Þ»„,I¼Œ8=è% K×åÞÎ/{}Ú-Žƒ½røèô>†¦¡È2oF#ŠºNo0á>xÂÙxL{Û§SÐ4Ž[-V¾ÏípBµ^! "öZü~.+ž><áíír­DÅ0èõÆ´÷ZdÛSöV¥ÂåpLµRÂÐ4ÜmpÂp4CÓ5Ñ/S2°×.‹á‚{ïŸà¹>‹Á‚÷?|Èl¹¢Z)¡«*ÓÙES„lÉ ª¦Òì6E e½Êl"RÍz¯{”kevïíúanÐO·ý7ï–pw%ädY–QïÔÉÒ ßöE™£ãå h¡ŠâÆþœJ£Bc¯Áèr„oûtt1G&“› ßÿ—ßçâó * ³Þ UW1Êš!¼CÖÄâð‰ˆàN¢„r]„´Úܼ¼áèÉÓÛ)åF™V·Åb¸`r=¡¹×d5[Ñ:h‰Ð‚ÙJDmç”—ÿñ%Oÿä)×ϯ1Ê‹á‚,Éh¶Qu5Ot‹üˆR­ÄÛŸ¿¥ÑiPiVp,QÜ(ÉpÅALïÍ->|H©VâúÅ5÷?¼ÏË¿‘ÎÕ’"±,ÈÒŒr£Œ¬Èø¶/"–‹:ÝËñRìHLCZáÇYŒgDQ€ªjÅ2õ:WoÞpòð£^B¡˜G$¿“tu»˜Noi·IÓÏ[³^/¸¼ü×]ß”ÿÔÀƯ»gß`ÜŽ»¹›»¹›ß üñ‡ïñj8ä¤Ý§¨YFI&çw¿¿žÏyÐéЪTˆ’„ÉjÅ`¹¤[¯ ±]ôkÅ"Aç§ÓšªòÅÍ % Š,³ÜÊ»IÂCš¥¥Br¡ÀÚóXù>›í¿[«1Y¯) ؾ*ËìÖjȲÌxµ¢¬ëd›HŠc‘6ÜßÙþ8æídÂi§ƒÇdYÆåhÂñƒïq»Xàg×}þÅw? CLÇ¡Ûh¦)3Ûæ¤Ýf²^sÒnóz8$ÛlÐU5¿/E]§b¼ 04 cÛS/øüü’üô=n¬®È2‹mÞI»Í‹Á€òö^qÌéî.Ÿœóøè€l³afÛìÖjÄIÂ`aòh¿Ët½fíz” !M*ÄÉïåtŠ¢(<ØÙáËËîíïòüåû÷º6›˜ŽÃÊõÐ5•(IØý•0„ša°S­òò¶$‹>“bµH§!@OY×™Y¢»åho€Þd–—Zº+—BQt•ìµÅ×:ûôŒÇß{œ?Ö|0gçp‡ÈЋ:îÊ¥T+1¹žÐ>l㘵ˉJŠ•"Q(úIVóFÉ'ݪBÁÐ]ɲ EQðŸ“N]Œ0ÊFÞÿ®å>ôBvOv1G&›Í†(ˆxúÞçüÙªªòôãG¼}uÍÑ£CF×cB?¤½ß¦¿5ë¿ëkÙ¤ŒŠïˆ²ÅZ»Æj¶ÊÓ§B?DÕDtñb° û°Ëÿ·óñ?ÿ˜r£Ìr¼²¦¡Iû°mÚeƒYo&–ðzESò´Èe—݇]æý¹ˆCÖUÖó5²"³^¬iï·YN–è†Îz±FÑ”¼kæõO_ñè»óD¯J³"¢Œw˜õf‚M¨–UñXöB\O๡¿}ØÎ‚×óµÐ nàô»§¼þÉká¡‘%B7Äw}š»Äm²Í¶•=Å_‹>¡Îq‡ÞÙ £(îÝ|E¡X@’%¬¹I©\Á\ŒY.§t»èž0éeÓ³×½‡ë¬X.'F™Fc—ƒ_üìG´Zû$ID–¥”J5’$&MÇ¢X,Ój`Û&Q°ZÍh·—jµ‰ç­Y.§4¢(`2¹¡\®¡ëEÎÎ>Áq¬;åú›Þ7ñi|ÿǹünîænîæûõ?þ¯ÿ'{˜óúñDIÂܶ©š¢ä½#qšbhIš²TYf°\òƒH³Œ¹ã`:qšÒ©VYû>7“ÿøý'yÜ®ª(QÄõ|Οž2^­„&I¯×T•ÍfLJ,¶¬BEdÛkv‚€ Ëêî6¬¤ë -‹ýFƒ¾iæž‚‹É„û•BOß^p²×¡^*±ö}LÇì€çñ­ÃC>}}ÎÃã}IbhY” öêuÛû0Z­x¯ÛÍïËz ÄΆ#Ž;;T Ú• ?¿¾¦ i(’Ä^½ÎÚ÷q£(7Ñ/m‡F¥ÌÊõ(èZÎ,xaȸ?ãè^—«³ßúè–ë²2mJõ’$ñ^·ËëÑH¤t­Å)n ™Xu+cŠ’„ùrE±d È2UÃ`nÛìT«˜®‹,I˜“%;Ý–¹¦\+cÍ,ô‚.–K?d|5æãú!ãÁŒZ«ÆðbÈáãCU[.ˆå8~|Dœ$ܼ¸áÑǧؖƒc9(ª(l´™ÞLiî5±—6Ūl¾í“&)ŪHzú¡èÉ6¢ÐHcÑϸ(‹œXJ<[¤oÉŠŒQ2^ ó&sßöi´Q4Ñ/É£ËqçFõwærÇrØ9ÜÁ¨Ä臩µkB2Å\ýâŠ'ôsdRn”]Œ¨¶ªH’„¢)N *‘0ǦXôk%a ŸXy¬°ª‰foí¡º`‚ˆÞëýgñú'¯é>èŠç[P)ÕJ°õ|M– ÀbŽLvŽwœ@ø"^½å½ï} ßö©íÔX/Ö”ª%Ü•K óº¦kH²$Œø;5Ua1XÐì6±MU.ëùUWY hºÆÉÓæƒ9ÞÚ×í8Ü{ú€Õl…Q6p×.‹É„æN‡RµDïâŠöî•F…áUZ³‰^ÐÙlDŸÌl8A’$æó>Ç'ï1^ÒlvÃcMéîß' CgI¥Òd¹œ°ZÍèvïÇ÷Ñ»>Ç4Gììa%|ß!ŠdY!M²,¥Zm†>oÞü”{÷>d½žqtô‹Åˆ,KQÕíA@à®k±·wËšR.7€Œ$5ÞÒlî†ÈÌçýoöºzPþnÁÅïòù_ðëÀÆoòÜ… ÜÍÝÜÍÝüáߣþÕ¿þwî¢H¦ãòí“c^ ‡ya`¹P`±í8ùìúšÚV ´»•6›ø[­¸³íõè-ÌæK¾óø! Çá°Ùäb:åtw—·“ EMc·^'Ùú8’,Ë¢\îôNÚtÐhà„!WÓ©ˆ3n·óå{üß?ü„ÇïßGB´Ü÷LËuéÔj4K%&ë5Ã`º^S-˜­ÖÜßñ­ÃåR¤zõùgÿä; —KJÛ¢FsmÓ¬ ¶Èõö[M¬miåÊóØß2a“nýŠï Õ{µn²·5J[–M¡$ükÛű:ûí<«=Â(Ü?îÒ›Ì(•‹¸¶G¡Xà°Ýâ²7¢ÞQÆË©…ª ÿÃj› §)Ö|•—:–Ãý‡‡¼þòM×@‚RµDà(ªB£ÓÀw|¦½)û÷Ñ :ý³>ŠªˆáÃ6ëùšr½Œ»rI¢„Þ›Çïª.’&7a,>ê`/mƒŽåpï[÷X UW™ÝÎØ?ÝÄÒ]¬]Œh´( °,ËX ¿Œ·ö8ûôŒÿôCÜ•‹VОˆÙl(VŠ$q‚¦k¢2ŒQT%¿æb¥Hš¤$QB¶-ØômESÐtÐ Qiœ¢hB*‡âÄ¿X)R¬±¦»'»ô^÷ظ5³ðmŸ8‘ÇîÊÅ]¹,§ ¾õO>Â]¹ÔÚ5²T<4IÙ9ÜA’%Æ—cê»õüh-O«¶ª¬çk ¥‚`‚žž0¹™`M,â0 dY¦T+‘Æ)¥z‰M&öªÚNóŸŸSïÔEk½ã£tËÁœM©5Z(ª‚¢*"¾ºZb5_ÑØmðÉßü{?þ>iš†.V‡åbJkgµµdÿþ£ë>’$†^þúÑhvX𢓤ÕÙÜMé±ÏȲ”ÅbÈÉý÷™ŒnQ•B¡H’Äôz¯¹wï:ûœ¿~Ft:G‚añmZ-ñs2žS*Õ€ ¦9΋÷öî3Ÿ÷·`ÄÃ4ÇȲLµÚfµ_»ÕÚGUu®¯ŸóèÑw1ÍIS(”HÓÇY¢i¶m¢ª*šf°^/e™Vë]7X­f¸îŠÉäšÝÝ{,—câ8ü­¯«w&ù¿CpõÕ?]Ëù¯þúUcùo=¿®ÍüÝŸïÀÉÝÜÍÝÜÍv£…0¢& å­ìY–1³mÞŒFtªÕÜ@½dIâfëõ‚(òñ}‡Áà,¿7’$Úë§Ó›oNîÊßàøº}Xü*èø*Hùº´«¯~ì«_ãpÜÍÝÜÍÝüý{XÌ-V¶ËÂqp·Ú¶|ÑÐ4œ0äf>§¬ë"†Ö (:ƒå’¡eaY6£Å]U±ƒ /UüÇö}Â8&‰<8Äø•~’f¹L”$H’ÄÎnU–évZئ"IÜ.ôδ+ ]§Ù¬z!“ÕŠç7¹Ïå;>&ØvqxQÄÚr(– Má|0 W‹5‘ay³õgé$ ÕV•ëÙ 7 q×®xœJ‰7/.ÙÅjY‘™™¯op-7I7ƒ1;ûmÒ,ãõ‹ËœÉ¸}y‹k¹ô¯GèE=7ïÆ¡¸Pª1G&ÓÅ2+ïN¸Wó ûÆnoía” gB?$cÌ‘‰ïúLo¦LÇ‹\*µœˆÕ]¹Ø¦Í† ®åâÛ¿,—³M[x@ :Šª`T ^ÿì {öÄÇ·†únþYŸõbMÆ«E’(!ôC.¾¸àöÕ-¶iú!„¨±×`ïþ«ÙŠîÃ.¡2ë͘ÞNó¶÷ÕlEs_DgiÆÛÏÞbM-tCÇ·…G¡T+¡«ù*oE½j«J±\dÖ›a” *ÍŠt—# Å‚hE¿™à®E±ß;IÕj*@Mè‡Tœ¥ƒ»rQuѵ±œ,É’ Û´éŸõ©4+ئͼ?Ï÷˜õBüÜl6Œ’ð‹e#¿çïîqïMEU8y|ÊørLäGÔ;u¦·¼µÇèz@m§FàBf¶ƒ½W=Ò8Å[{H’L§ÌsB? T-1¹™à»"©í—DR$¬™I±(€ÙzmbM,Ï#ŽC¦ƒ…B ÛZq}ñ ËšR­6¹zû’B¡ÄùËçÛ=OF7 Ì'#¬ÅœÑè‚õzÁÍÍ Ç$ =dYÁq,â8Äól|ߦVk±\ŽIÓ„õzŽë®¶ç¦ “É5ž·&Mã­%!ŽCºÝÜܼ`½^`YSÞ¼ùEѶR¬ŒÁ@€³õÚd<¾Æ÷tÝ`4º¤Ó9Î÷É/þ† pQUù¼Ïîî •JI’˜R©N𯄡G˜æˆõzÁ`p†ë®·íò]\×"Ž#EÅq,Æã+‚À%McTU„ èºñ^OÕ»·”ß­ïã« å×õ|ü& ñëü ¿ tÜ’»¹›»¹›¿¿SiTXN–´ö[ôç öš¼Wã7=Nº»¼¼¸á`¿C˜$l€÷Žx;E1†Q`½X »,coû:.'SZMì@,bvA§^*1š›¹_ÂÛ2îÊe³×ÊOÿñâœÆ^ƒãÇ¢$°Ó%v£K±ôoØ0‹Óüv¥BïrHà4÷š4Úu®^^ÓÚk…g !›)” ¬}aj.V‹,Vk¢ ¢Öiqöò €É|‰ïˆt «W7+Eêõ ~qúþ=‹Iœ •„QØ[{ âT”ó¹.q,Ø£d0íMa¾ãsÿ[÷±¦ƒ·N¿s Ö@ÕT|ÇçüsqÚnM-:Ç<[hÿ“(ŒÃË›Ü]mV™õfÂG°´EÚSÅ'à{MžýÕ3öîí¡h ·/oóô‹/.(ÕJttñlåtI&TÛUúoúì?Úçæ…xÎFÙ P, ´üZ%I¢TÞUUIâwå8Yš ‰ÛÊãÙ_=CÓ5ŽŸcŽ„/£X)²,Hâ„4Ió–vßñ©4+¤qŠk¹èE{a³s´“{BÒ$ ¢¡¸HâÚFÏûsê;uUÁ±–Óe^bù®å²^¬Ù9Úa>˜SÛ©qñì-•ZÁÛÕf•ÕlE–eâ9dºº<ÿ_àûߊ$Ky »Q6]Œp,‡úNÅpAº˜#“4às“m¸}{ÉîþŠ&ئ×?ÿ’Ãû÷ùâ“òøÉ÷ž1ÍÍ¦èø Ü€8ŠxùÅg|ôGÿ€«ó]P,V¼e)¾/ÒÁúý7ÔëT•0”ˆ¢€b±‚m/89ù€³³O)+H’Œ¢H¡( ²,â„MSȋоïä Ðÿï”oÒÛñ›ØŽß÷s¿ R~ËñUàñ›Åï 6îÀÉÝÜÍÝÜÍßï¹zvEਚJ¡ ç]N tÖ¾O±*ÊöfÓ%Ëåš¹#–£ #K§ON„tèªÏÚõMæ ‰Hܹm3¾ãyƒÉœr¹È|¹I`ד|t½× Hã”j«J»R!Šbæý¹è-P!I™tvš¨šJ–f<{sÉ“÷ï³{²‹¢(x®,Ë8+'7<«ªŠ¦k˜3‹éíE‰O‘17W¯§ìwZnÀz!LÃksÍba¸ç/¯YN„4åæ¼/ŒÒª‚¬È8KU–E’U©@’ˆ8W£dPkÕ°—6ЦÐ>l£4Æ7tC°+óÁœý‡û¨ª+£Ë«é*¤Mâ$_¸4C£X Lä iÎr²ÄšZL®'%ƒöakbÁ»dئÍr¼Dü¬çx|ñÿ|A÷a×ryòGOØl6 ß1Êi’"Ë2ËñUW™\MPu$ÈÒ oíQª•^ ™÷猯Çtv©í^F¼ü IDATÔèÜl(ÕJŒ.F¨ºJ±RDÓ5µœd<ÿÑsâ0F+hDaÄz±f5_åfó4N™ÞNYÍV¸–ËÙ§o¸yyÆ ‹Á‚Ý{»ôÏúȲŒ5³0G&÷CB?ÄšZ¨šJ±Z$K2¢ âúÅ%Õzµe¢jªè%‰’(áùç?ARÄ÷TÓ ìî3LH¢„Éõ8÷ö¤IJz¼}ù%®åRo¶Yšʵ ÖÌäóOþÖNή¤i" ú]â(Â÷m*•&¶m²Z͈‚×]‘$‘øùTJ¥ælJ–¥ÀEQñ¼5ÖrЦH’ˆÕjFµÚÜJ’„Ïfÿ”ÛÛWâkªªªÑlv±mÁ„è…Õj ]7PUñø*—pm6›-ˆÑsÏF¥Ò Ñï¿a³Ù ªº¸kFš&ôûo¶ž‘:ãñ5ûû/¶Ài€m›xžM©T)`ë…ˆ…6Ê$I„¢hèºÁÑÑ{Øö‚åRÜoM+àë­X,DQÀpxN½¾ƒiލTšÈ²Êd"€çmCÊ &“+@Ú²6B^&Ë oÞü M+ ª:Åb…››¨ªŽë®p ]/R.×¾±¬ë÷(¿ËÂÿîó×ó‡`G¾zí_çõøêõ~KòM@¸›»¹›»ùOsŠÕ"Y*´ôåB'˜®ÖL­% º&NÒ7l°¦a³S«„º¢ÐïMP%—`›6²,88=ñ´Ýš"z%â8¡±× ‰’Ü™i1›š´ªÚµ*FI4y_>¿Âu}úoú„^Hœ¦ŒK²4ãò¬‡Q1˜ög(ŠÌj¾¢?[ˆ~Œè‹Ü­ ±°m>ÿÑ—d™0;K'%qã;>¾#bhã0&K³œ ÜI‹³,Ë‚Õøù9Ц0Ι\Or&H–«qóòwåòê“7„¾ðiD~„£›7 =6Ù=Ùýey\çeEQ¼`ŽL %&$Ibz3¥ÒˆÃ‘”U+¡j"bvr=áöÕ­ð»xží1ÌI“”4Iyöža/m¬™Å³ÿðŒ³OÏ„,ÊÐxñ£4: ¢ bp6 Žb F!—µÛtvEwF–á˜Ц0¾sýå5Y–qðø€þ›>¶iãÙ^^t·,PT®¿¼F’%–S3O‰zw²,¼µ'Â$ kfå,K%|ùÃgH²„oûxkaX—0‡&Ž%¼ï|!’$ Y”òæ³WD~„9›²š®˜ôF+E*µ:ÖÌâüóóüñì¥3@¾íS*WXÍV$QBµÚd>œ2Ÿ Ë´QïV€Ü›— {Wüâ'?Á¶Äzöå3Áü”ª8«5I³š¯õ¯™c‘$!ïẤOÇ=泪¦ ù£nP«µ‰¢é¸,+Ëz½`± (*²¬°4'¹Lêøø}¢(Ì£QÁ÷mÇ¢TªÑë½& =Ò4ÁuW o/èvàûkÂÐg2¹FQ4Öëiš°X ˜Ï‡¸®Åf#ùáðÏ[aYSg‰m›œýŒ^ï5£ÑÅvG”q] EQÑuƒ(òñ<›$‰1Œ Q¯ïAàagIú¬Vsâ8Ü.ð\wÍ`ð– ðPUßw$‰p“Ù¬‡ªjËlÖãììÒT˜×…Þͽ*Ãá9ýþlÛd2¹&Ž#®¯ŸçFùׯÊîî qrsóI’¸¾~Žm/Ùl2¦S¼ÇaøÂP°©¥R ßÞ˜wì,«ôûor¦¤Rilüö/_“øPþP‹úWÙŒ¯ûõMþݯK»úª4뛀Ž;Pr7ws7ws7¿ë,'Kæý9¶i³š­è½îqs;bH²D’¤TÂpÜØmÐ9é$)›l#ÒŽ†sæýùv¡féåt™/¹ª¦¢uDd™j«Êó>Ç]¹¬æ+Ò$e³ÙD æÈ¤T+¸ËÉ’À ˜ÞNY XS k*ŠÒ¢ b>˜#ÉRîåP5•7?{ƒ92I"Ñb/…‰;‰EjÒr¼ÌÓœ6lè>] ‹á‚×?}M–f$±0§¯ÆHH^€Q6P5a¨^ ¬Elè…9û8/~ô"ïíáXŽ—\}y…ª«(ª’—ø¹– ˆÃ˜ƒÓz¯{4: Öó5§ß=åÅ_pû꽨Sª•xõÓWŒÎE ¡nèŒÎGBªDÂsòâ–À (7ÊhºÆìvÆr,|¾ã3ëÍH¢„(ˆ¸÷­{ÈŠœ×ï}pŸÏÿò³œ9é½ê¡:“+Ña1¹ Àg¹diF¡T`|9fç Ãàl ¤XsáÑ™ÞLö® <6%$^}úŒåÔ$bܵC©Ra1šS®Ôß©6êØK±nß§$JrF z—8¶E'˜s±ˆû¾C©$Ø's*dOýëK²,¥Riæ‹xµÖàäᆷ7,—TUÇ4Ç n.‰"±ÌªªÎ§ŸþTU§Ri0¶K­ÍlÚ'I"†Ã ¢(À0JD‘ÏtzÃz½`µ’§4M$9g\×Âq–(Š`"wwIÓß·‘eÛ6¯¨ÕÚ8Ž…,ËèºÁåå3\w/ÖóyËšr{ûè ( ýþ[nn^æFöÛÛWl6/^ü –5£\nΓÉ5ëõœ( °í/_þ˜jµ‰ã,yþüGÌf=ž=ûK./¿ ^¼ø¿øÅ_âûNΊT«-ªÕ&³YÇ1±¬ iÓïŸq{û ×µr¯ˆ,+9@Á¸Y–`ÑV«9aeiÎÔé[#Oä©e £Ñ%›MFzT* …–5% =‚ÀÁ4Ç €®·ì’žËÇ~59I¢œ5ùÕù&%ŒßüjÊ×ß·aü7õrü¾ìÈïÚˆ~7ws7ws7wó‡žwïQÿõóßsú½SÊõ2•z…óÏÏÙ9ÚÁ6mºº˜C“JSR'7N>8ar=¡Ö®á­<O”ÛùŽO}§N–e”j%~ô¿üˆ“§'TÛUê;uaFÞ.¶I”PiV˜õf(ªB©V¢Ö§X.Ò}ØÍ±+ ×ϯ)ÕJ4÷š"áH–r`9YR(xðíXS‹È( ^ˬÚmQ¸mø^ b¡WtC§P*0Ì…áþ -J§ÁðbHû°Íôzš—*ŠBFܾ¾æÁ‡§=9bz;Å[{”ëeÖ‹5ã¾³Mtz%Šø.>¿ SšûMʵ2£Ëͽf.çÒ‹:¶)–sEU0Êíƒ6ˆÔ­­tKÕ…—¦P*ð‹¿úœ8Žxðôª®ÎÒÉepŠ*â]½µG³Û̆,år°4MñVzQGÓ5’8aµX’¦ ƒ.¡‚„`„æ&ínÇrØ»¿Çôfн6éìär7ÝЙ &ÔÛMÖ¦…$ɘ戟2ê݆>Õj“,ˈãM+ (*•Z s>aïèˆ,ÉpV6q¢ëF¾¬¿ó*H’Œ¦¸¾~ÎýûòùçÁÓ§ÿ„b±B–%ŠEz7oØßÈ|>ÌËûLsÄf“ÑhìbÛ&º^Ì áªªå£w^M+Ç!Ž)‹U&“+,kÊþþ)“É ªªÑhìæËoGÔë;XÖM30Œ…B‰éô†,Ëþ_öÞ¬GŽ,MÓ{l7s3ßר¹&“™UÙ]ÝÕÓê–3€`n4è'èR7úKú aÐÐ 0=ÝU]U3¹$#‚±ù¾™¹í¦‹ãaÅb“L²Š™ÅÌ:@ôp·077?ç¼çûÞï£ZmÑj X,ÆøþPh4º$I´MkieWWOé÷ˆ¢nwù|„ªª¨ªF¬ÊT®áðÛvËh¦éÛsõ˜LΉ¢ íö. Þ×lvEžgXVËr¶ òb{¼“ɦé†>¦iEÁ6ÝKè/.ãy TUcÿ–ËI Ò4ÍfE,qÝ&º.<%£Ñ ¾¿ÄóhšÎb1Æ4m ÃÄ4EãÎ<ÏËÔ2ß_°·w—ùü ß_Òlö˸Z­½åøþ˪¦1Y–þθvýþ–ËÉg\}›Fï‹@‘H$‰ä}(ÿé?ýŸôoô9¸'Êw^§Bù ŸþQŸ4I…©9Ï9ùâ„Û~[x'*Ñ&´Mž~ö”þ>Y"< ^Óc|:¦Ú®’Æ¢úQ%œ=<ãÎ_Ü!R’8Á_øDá#¹ñ“LÎ'yÁÑÇGœ<8AÓ4æ£9ûì3~6¦9hâ/ürÿì«gÂ+âÙPP¦'-ÇK±XÛzb®Ž¯h Zåû»nX×ì7yúÙSvoï’¦iY­ªÈEteülÌr²¥içë2R‡1a *J¹u·ì)òõ¯ÐÛ@š¡‘Æ)Gñì«g«€"/0“éÕÛv©uj$q‚]±Q5•<ËYÏÖX®UþžþQŸÑéˆÑù%Q´a°w@–eÄaŒã9Bl隨vUÀÎí&çf£1·J…¬×sû‡yíÚ¢Tmœ¬¦“ tÝÜ/ÑuÞ„z§I°ðý%•J•(ÚàV«,fc,Ëe4:¥Ñè• è¢(˜LÎi6´º>ø F—årŠe9\\<¡Õ`Yâ8$IbšÍA ¹¾¿ R©âºuEÛF„9¼ß?¢( <øïôû7¶ž†‚ÓÓ¯øä“‹ãxÂp‡˜¦Ãz=Ã4m6›ŽSe¹œlM×ù6º²»{‡J¥Æ7ß|Šãx„¡O¯wÄpxŒªj¸n¢ÈùòË¿çÏÿüf29ö]Ž?'Ï3 Ã*{{SºI–¥œž>Ø.´‡X–ƒãT·Q‹)Žãqrò%‡‡Q­6qÝ:¿üåÿC¥R£ÛÝßVÊšnwùçØ¶KúÛ†† +š®qòå ÷ÿæ¾h2·ˆ‚ˆF¯!ƒª0~&ÄŽªªÌ¯æe MÓ˜^Liî4˽nêüêÿû{>ù›¿âë_}Á­?`ôlDg¯Ã|8§Ö©19›Ä1ªªQïÖKSõrº¤ÚªRk׌]st÷þBüÜ´M–Ó%Y"Jå†~ȳãÇt{ûôú O†8UGô*]Q©ÔY­¦Þ¹ÍÕé9·Êl:¤ÓÛa:¾"VX–ÃÁ­ÛÌG3&“s²,åÎýŸr~ü”ý#~õ‹¿c0¸%>—ín}µÚB× f³KÖë»»·q½‹ùÇñøê«¤ÓÙ¥ÕÚ%–ضK£Ýb5_r|üE!vô§J–%ÄqˆïÏñ¼¶]a8<¡ß?" :=V+‘²—ç¦i“e Ëå„ÍÆGU5Ç£^ïn+'AQÀÞÞÎξæììõz—ÝÝÛ,cTU-wòÃ0 Ñè2žpyù Íf¿\ 6›}–Ë Ýî>“É9–U¡ÕÚáääKšÍ>——Oèv©×{NµÚ¢ÛÝgµšn}kâ8D× &“sêõŠ"īՔÍf…ëÖñ¼——O¨VÛ ‡OÙÙ¹S ŠããÏ9:ú×­—Ñ– X¢i½ÞQY’×óšl6"Êq~þ¨——ßpãÆOQa6ŸÍ®¸qã',clÛåââ ƒÁ ..žÐnï–^‘®d¡ªšðÃlÓ˜ Ã*ï…ÕjZF`4Mg0¸Éùù£ò3e‚…w¨Vë°\Š"•J• X•£Vk‡éô¢<æõ8!>+]7ÞØ—ñ¼Èø6Þæ¸?ò²ªVß6À¿ëÁ_ ‰D"‘|ÛÚ›lŠ}›hûû÷88ø~ÿOìê›¶Éä|RV¢ªT+¨šÊl4a³Y±ó§OcfYõÇ­V‰6!÷™]ÎPT…gOÓíï£é³±X˜ýôçÍèÙ^½†íÚ|ù›Â÷çt»‡x^ƒÅbDop@–fÂgñì)ƒ½#ÎNS­¶p½ëÕ‚ÇãxÛœø;GûqbY¿Íkÿì³ÿÂÁÁ‡eëår\VrÝA R]jµ z)<~ükööîâºuWWO©Tje…'Ïkòðá/·éCß”ùûyžÑéìÓïßàñã_“e ½ÞQ¹Ûzú€^ïË˧´ZtÝäæÍOxðàï)Š‚F£Çr9¦ÕÚEUUF£S\·Îo~ówüíßþ¯øþ‚ÓÓ¬×sîÜùšf0ŸI’(ÚpóæO·©>už>ý ÏkðÍ7ŸòoþÍÿÆÙÙ×Ûàç@ÁÞÞ,£R|ˆÔ‘fÇÇÇŸqppŸñøŒ^ï ¬B5›]K,ËÙ¦:‰ííöî6Mè”›7?áìì!;;·yüøWÛªNuò|[E¬!J­Ö¦Vël{Œô™LÎQe[½)cw÷‹…èã‘$Š¢–Þ( Êž׋åëè…iŠbÎOpœêVˆ(e'ó X–MýÒ4)Ý׋ÿoû.^‹ÉŸˆ@yvÅ$‰DòýñCÚú®Šœ$‰äûŸWd'y‰D"‘Hþ€ÉTЉD"y·ü`Êû²“÷>U “ç"ÏEž‹<—ïò\$?œ9ê}¸wä9Ès×BžÃ»šWT$‰D"ù‘òº~Z‰D"y?‘)^‰D"ùÁó|³Þ7Ù%|ÛçK$‰D ‰D"‘HÞZ¤¼Écoò3‰D"‘üñøÁTñ’‰D"‘ÈqW^+‰D"ùñ•Òƒ"‘H$‰D"‘HÞ¤@‘H$‰D"‘H$R H$‰D"‘H$É‹ü <(‰D"‘H$‰äOA‘H$‰D"‘H$R H$‰D"‘H$É{+PÞ¶Û¯ì,‘H$/ßfÌ”c¯œ£$‰ä}›WÔ÷åEñ;}ßåó%‰äO}yÙ˜)Ç^9GI$Éû8¯È¯Ñ ô>M„rR~ýõø®¯Ïûx?¼ínÊw}./ûLÞæñ÷YóD"ùñΓêQ¹çÇâ×ÕozÝd”óýžWtyé_ÚëHv4–_ø÷í~xŸîÉÏåúÿoû¸D"‘ó¤<ÿ÷gî|ÕõyÛKÞ¤@ùyŸßxñ‹xý³ç¿þÿËeo{œù²ÿ¿É€üâ{{Ý‚ñeçùºóÁðª÷û¦¿÷eïëu ßW½¯·7ßöy}ÛõyÙ5ÿ.ÅÉ›Ü?̉D"çÉïržü.Çõw5¯þ>óÉ·ÿ÷YÈy@ ”?ꎼ ßì}ÛNï›ì Û·ÝÛñ×]·7ù½/Nßåÿe¯{ÙùÛõyÕó~Ÿ{ôM¾Ëo2¡ý!÷׫®ýÛ>þ§2®È±W^'9OþñçÉw5®¿n^z›yõ÷™OÞµ°ü.Ž/y¿ÆË÷B ¼J‰¿«çÿØw‚ÞöKúüsßfpü¶Áâm—·YH¾ÉÀô6”?tp|›Aþ]}7Þtÿªûám?÷ïbRy&”·Ýeü¾>ëïr!öª1S޽rŽ’óäû5O¾«qý]Í{¯:Λ~Þåº@ò§5¯èïÓò67®¼©¿¿ó]-ÐÞvÂ~Û…í«~þ}ù=ÞÕöu)]ïóŽÑû¶ û¶óyÕµ|ÛÇß·…Ø»ø~ȱW^'Éwø.Ç‚ßwþù}¯Ëë¢ño3oȈɟּ"=(?âê]ì ü¾).èâ«É×…×_ö~_w¾Ëëóºëö²Ýˆ¯×óÏù.=ïê>y×Çñz¼Ëó|Õ}ù¶K$9Oþ1çÉ·}_o2_½êßorޝ{þš*ü¦ÇÿC—¼G¿ŸŒäOñÆ—;1‰D"‘ó œs%ï%²ŠD"‘H$‰DŠÉûsßÈŠD"‘H$‰D"y_‰D"‘H$‰D"ŠD"‘H$‰D"‘H"‘H$‰D"‘H¤@‘H$‰D"‘H$)P$‰D"‘H$‰(‰D"‘H$‰D"ŠD"‘H$‰D"‘E"‘H$‰D"‘H¤@‘H$‰D"‘H$R H$‰D"‘H$ÉU (ŠÂÛ>ÿm_#‘H$‰D"‘H¤@ùNÄIQE!EŠD"‘H$‰D"y#ô7}âw%4Þæ˜EQÈOL"‘H$ï×óØøÿ;û·øà¯>À_ø¤qŠa$Q‚aXŽÅùãsÏaülLÿF«bú!I˜`U,TMåò›Kö>Ø#Osü…×ô°]›³‡g˜Ž‰¢(8žCD¬f+º]–ã%¶kÓè7¸x|A­]ãò›K,Ç"‰*Õ yž³Ym¸ùÓ›ÄQŒã:¬f+6« †e`X›Õ†³Gg nHã”(ˆXÏ×è¦NµU¥È B?äÖŸÝ"SæÃ9º©3~6¦½×fz1¥Úª²-ðç>¶gS©UP…Î^Gü¼]e5]1:ÑÚi±œ,©wê¬kZƒI”°ž¯YÍ–Ü;Äñüã4:-½O>{Èþ#£†ipñì„þÞ>óñÇq©uj¨š œ>~‚ë6ÈóŒÍf…®[ wÉÒŒÐ1,ÍЈ71óɯV'ÏrVË)Ív4N©Ô+œ£i:û·n‡1‹ÉŒÙ슽ƒÛ̧#§FoÈóŒ<Ïɲ„þîI”°\Ìè\?Ã0,>ü%7nü”ÕjÂÑÍûœ<ýŠJ¥JQÌf—~D˜¦M’DxÕIsvöZ­C–¥ÌçWܼù óùÓ´PU8Y,†˜¦C¿ƒ““/pœ*š¦³ZM°m]7Ȳ ÏkE>¦i“¦ ãñ•J•³³‡ìïßÃ÷ç}ÌþÏÿ~ø×$IŒ¦i$IL«5Àqj\\<&ϳò»P«µ9=ýÓtX¯çܺõ iš²X ©×»,—f³Kjµ‹Åˆ^ï<ω¢€¢(O8:úˆõzN§³Ër9%Ž78އ¦|ùåßsçÎÏÈó ×m`š“É9iš ë&š¦1^bÛ.¶í¢ë¾¿ M*•*«ÕUÕ©×;ÄqÈññçÜC×MæóF—áðÛöÈó ߟã8µZ—8ÞeÉv=¬Ç4Í`6»DQ–U¡R©±XŒ©ÕÚœœ|A‡ìïßãòò Š¢’$ºn¦ ¦io¯Õ €n÷]7N0 Çñˆ¢$ ñ¼&ÓéEy­ Ã"I"E¥(ò×/ö·¿ïw3IÓø½Wÿè”ë(ËëþH$‰Dò¾ãUëT›Uò,'S†ÇCTM%‰¢ bt:­»tºüìßý §ê09ŸPmUYÍVB|¨ ~ƒÕt…ã9Ô:5æÃ9Ñ&´M4M#XL/¦¨ªŠªªx éÅE?wª½ÃŠª%ªªR©VPU•ùhN‘«€ÅhA–flÖl×&K3LËdx2DQœªC%T[UE!ÞÄyA´‰È²Œ¢(„ªXP€i›œ?:§9h¢›z)NLÛäø‹ctSg>¿?Ibü¥O{·MA¦ilÖÒ$¥(Šrá{üù1ݽ>–c±-èîÐ ƒˆ6f—ÐQ·á²š®ýéã8U܆‹[óh÷dY‚nè$QÂ9X°? IDATÕÅ)EQ`9£Ësz{;hº†ª©¨ªÎz¹(¦¿ðiw¸nÕtEš¤TuÇcµX (yžQ­7ØlÖÔmŠ¢`5_ ¨ µF“ñÕQ´a½žÓhô©Tª¬×s¦ã!õz]·P…n÷$‰À8 ‚y–3ŸX.ÇÛ×M±¬ ³Ù%•J•áð„( ¶‹ÜCÖë9¿øÅÿÍùù#±ØS5,«Âx|ÆÓ§Ÿcš6óùÕj‹<‹[Ïk¦1¢ª* 0™œ³³s›8™Í.¹¸x‚ï/˜Í®˜Ï¯pÝ:εZ›Z­M‡´Z»¨ªÆÁÁ‡Ø¶G¨ªF¬èvØÝ½CµÚDQTÇ# }Š¢`29ÃuëÄqHQäL&çøþÓ´9;{Èz=ãÞ½E–¥¬VS‚`Éf³fµšbÛ.I¡ªš¦cš6õzðÉóÏk iÕj‹Ùì’Ǧé†Ež,—S,Ëáôô«R\jš†aØìí}ÀÅÅcŠ"g6ŸaèºÁj5¥^ïâºu’$bµšòðá/IÓ˜ÓÓ†…ëÖñý9i𔂠Ù`š6ºn¢ª*–%Dðf³f6»Äuël6k‚`EoÊë/>KµÜ±m—¢È1M»"/ãyq¢(êö±ø½O¥IþØ-“H$‰äù¹a½XóÕ?|E§ìßÛ§È ê:¦m¢j*Žçà/|V“nÍ%‰ò,gïîÞïDF’X,¦-Ç®ØÔ»uLÇâã¨G¥V¡Þ©£j*¶gÓ?ê³/qªñ&ÆtLª­*ÕV€,͸ùÉMü…ÏñçǨšÊj¶Â° ¼¦ÇølÌz¾æàþŽ'Ž¡ûì—¢¨Ö©áT¾ú‡¯ðg>³«¦m’Æ)ª¦²/©¶ªD~D÷ [ŠÛµËsU5•ÍzÃÑýì° è†Ng¿Cg¯C­]îØhšN° Èóœ` ¨ I”0NYŽ—Ì®fôŽzyAµY¥âz„~H½SÇñ,ÇBU5–“ªªâ/×€ÂrºDUUn}ø!q£éaè3͈‚M×ðªuV«þjÅb:¡âUÐt¢(ÐM'?ãøÉWèºW«Q" pþì ­Ö¿*…Áµ@±ë½Ù¬¨Tª¨ªÆ;?ãêê)ëõŒ««§tz»"Z’DdYŠeUpõzN­Öfw÷.Ožü†VkÛvÉs!ã8 оþúi·w nÑëm•ຠÚíîÞý §J–%ÁŠ0\“ç9iš°\NC]×Y¯çx^×­ ž'Ž‘¦1£Ñ)P°Z‰(Çr9Á0,Š"§ÓÙãË/ÿÃá‰Ð^"¤Ñè³ZM‚õZ|6¦isppMÓIÓMÓ©VÛÌçCTUç'?ù׸nóóÇDцF£K’Ĩª†ëÖQ•G~…¢(XV…õzNˆãÇgøþœ(ÚÐí°·w—‡ÉÍ›Ÿ°^OI’UÕ¨Tªx^EQñýŠÿš4QÓtÃ5õz×mEÝîq¢iA°Ä²*EN’De„c6»*7å¯Ñ4ÇñHÓ„( p X’¦1•JMŒÛc!RÐnï–‚RQÂÐǶ]TUÃ0¬Rˆ\ ž—­[¿-Úò£(Ò/ŒD"‘H`µœ‘§9ñ&æäË&眪Ãz¾`9^¢:†i h «ÙŠþ>ª¦2<2½˜bÚ&µv ·îobUa³Þ°œ,E:’®1»š¡ª*nÝ-ÐM,ÍÐtñ³1ëÙšF·Ak§E¥&,§NÉӜ֠Åb¼ ‰UAA!S‚¥Ø…¯Ô*øKUQ‰CqÇϰ]›$Jðß\  `»b÷v³Þ°wwÞa¯å¡¨ •jÍÐÐt ÍÐXŒl–šƒ&Ñ&‹wË;ègŠB¤iºÆÞ}lצڬâÖ]Ò8E7u:»]jšˆé•zUSùæÉgyÁÆß‡b‡Ø­yØžïϩ՛¦Q %UUù拇ôú‡¦Étzã9diÆÁ;T›uqNAÈr6©bë G7ï³\ŽEZU(¥iÚ8ŽG–¥†Uîj+ªXT*U’$¢ÕÚÁ0,V«)Y–²³s ×mày ¦ã!áÆ§Vo£ª*Óé%išP9š¦¡ë&ýþmºšç5Y.Ç´Û»hšAQäܹó—¤iB³ÙÇq<†a†>¾/¢ªª’e)A°d½^†klÛÅ0L:=®®ž ¦iá8.Y–Òj ¨×{¬V³R8M&çÛuÊz=Ã4m¢(`³ñùÙÏþõz‡ù|ÈãǿĂz±‘e¶íQ­¶h4zèºA’D[! ÐlX.Çx^“$‰(Š‚F£eUØÙ¹‰ªjŒF§„¡O¥Rãôô+LÓâ“Oþ »»w‰¢€JE¤ ™¦M»½Ë|>âôôAùøþþ=¦Óó2ͶÝm ÚE‘S¯w±,—NgÏkà8®[£Ñè‘$B u:{œ}M¥R#–t»Øv¥Sž×$McÞVt5˜Ï‡èº®X–³½tÝ@U5..ž`Vå C+Xâ­ðU‰¢M¹ÞÌóŒ$‰^)B~ˆÙHom’ÓÅ÷µgåÚ,ÿC /¾îù÷óüÏ^v|)R$‰ä_ŽŸ¯/¿ËÇ¿¯ ¶ÃnQkרÔ*|ô·aU,Š¢Àñ¦—Sê½:i’òͧß߇ipüù1á:Ä´MÏa9YRiœòìëgŒŸéìw°]›‹ÇDADk§Åä|B臤IÊðdÈz¶Æ_ø,ÇKþò!ÕVUx]ÎÆdiÆìj&|0®%¼&ë Y’Ñì7Ù¬6„Aˆfh$QRþþÁ‹ñ‚õlMžå4;‚U@­]c=[ã5<ê½:µv`”—<ËYMWdIF–fDAD°)iµvùxøsŸ0ùôïÿ‰ùpŽé˜|óé7 ‡lÖLÇ$ "U¤nåyNžçhºF´ÇL¢„éÕ€¿øÛÍtrIŠ”¬,ÍÜ`Úâ8û·nGy–£j*£gC±ðmuX-§¬Ws:=‚e €›ˆ«³g˜¦åXäy†ãŠÅçl2äæÍOÊ]ù( Ð4M3˜Ï¯0LUÂ1 "†çgeÅ÷å®xš&(ŠJ,ɲ„,K°,‡$Ž©V[´ZNO nÝc±ÇLÓ¦( Öë9­Ö.ëõÏk°X ©T<&“ E% }Ee4:ÝÞóê6íJ§(rÒ4Þ¦’-·ç·DU5æó!šf`Y•RlÙvÏkP¯wÑ4ðP•z½K¯wDQäx^ MÓQ•Íf½æÜd29£Vë (*®[ߦw­™LÎÑuÏkÒjí`Û§§ÊEvš&<}úªªr~þx›®æàyM4Mçòò –ål½"JcWWOiµv·>žÃ0ËȽ{ÿ ÛÂ˶]ºÝ²,áèècƒÛÜéô¼oÂ'¢Ëm”Â!ŽÃRlv»Û´µ*ŽSe³Y†>Žã¡ªZ™æ«£ª*WWÇ„aP®›MÓ!ËR*•Z)8®¯ƒaX,—ã­ø©ãº5ñ]Mã‘®uQÓuñý7ÓßX ¼Êò:ŸÈûæ!ù6Qñâ$ú. ¼­°“BG"‘üÅÉósÈ‹cñwùø›œÓ»gÇgcPÀkyÄ›Ã2XŽ–è–Nk§E‘̯æÞ?$K3.Ÿ^ró§71‘"e:"’%" ÒÞmcXÓ‹)‹Ñ‚ÞQË>«bQ©UXÏÅnx‘,Æ *õ ñ¿üa–^Žká0<’%º©ƒÍA“"/°*q(Ló݃ny<Ýб*º)ÒÌï²YmÐMÀ_‹è¦¡¢ÞN%lVPDÆkzäyNï¨Ç—¿øg²4+£ ëÙESøò?åÏþÇŸ—im­½£¶k“g9Á* K26«øÝ†Nš¤Ä›˜j«Ê|8§Öl¢( Á"`ÿÖ-’8Ár,ܺH¡Ó USqk.í!ö6ë µvÝÐñW+Í.ƒÃ}–Ë yžSïÖÑMZ­M{§K'hšÈïW5•årLú¸nZ£I»½ (TÜ*Õj›Ë‹ctÝäââ Ëå×m0ž`Yíö.aèsvö§â±X ±¬ ýþ E%˲mjÂééƒrqüÍÃ/èvpÝF¹ãŸe)Q$¼*¦é”)OšfbšÖÖ°ŸñèÑ?Q«uØÙ¹EšÆDQ@–¥t:ûܺõgt»‡8ŽÇpxÂxü Ç©ÒhôI’˜ X–âe:½DÓtÎÎ’ç¦i†>Q´Ù¦5ÅEÆÓ§Ÿá8⼋¢@UÅÂ=–Äñ†¢(ØlÖL§—[¡5ãÙ³ÁŠZ­M£Ñ#ÖÜǶ+øþPÐu£Lo+Š‚Z­aØ â}M§åÏZ­ò<ã믉eÙhšA¿ƒããϹºzJ’„EA,Qð·æ÷Ër¸¸xÌÑÑÇ8NµôšL&gضÇùù#LÓÆ0,‚`U ¤4×+I¢­ÿ%C×Eê—®Ûèˆ]§e%IH³Ùg¹³^ÏÐ4UU©V›[£¿YFI®E‡ð¦DeôêúÞ´m÷wƤ4MȲô•kô…@ù¡íν,úñm"åÅIôU?{Y„èùã¿jÒ{Ý9I!"‘H~¬ü‹+EÙ_ÿûÿ ·î¢i;·D½W÷h¶»äyŽ[sYÏ×Ä›XÞUqmíŠ-Þ›ªÄ"ý'K3 ¢ b:–$ŽD•©½»{äYΣ/>'X„AÈÙÓ§äY.ª‹-}‚õš`!Þc£Û"Ž"tC§Ý°ñýmÔÇGUU’8Á´L’$f> éÕj›J¥†®›äYŽfh8žƒ¦käyÊÞá-¢ÈçðèC<¯AQä,—Š"' }î}ü3úýdiJ·{€ãx,cÆãg„¡O,Y.'Ôjmúý£múS‚ïÏÉ2ñÇ©n}"¢Z™H:¡ÝÞ£ß?"ŽCööî’çëõŒõzÆfãcfù{âxƒï/©V[˜¦Íáá}‚`¹­bUŶ]LÓ¦Vk—â(ŠÂÐÇ4>ü›Íš(ÚeûûeY¹¸®Õ:ôûGt»etƲvvn±·w—^ïNgŸZ­…¢¯‹çýÖ\~pð!óùΗ—±m««§ÌfWÞ/…Áññç*ñ9T*u²,-#,×>•ÇÚk±ò|•µk^ô¨HòDA~×øó[að²³ë¿_&"^•ŠöºÝµ—‰˜7yý›îú½ø>^—"!#2‰ä‡Mù!‰«7­4©i³ËY ÙÿPÀó,gt2"‰>eg5MC7uÖ³5(à/|‚E ®O^pûg·E”¤^a9YrõôŠÖN‹Ù¥(Gj˜óÑœz·ŽaeîØüêÿý‹Ñ‚ÈXŽ—yA–eD›ˆådIÅ¢ /à5<>û/ŸQ©VXÏÖdiF½Sgps Ò«…Ö Ežå,'K4]”äuªƒ›êÝ:ã³±X¤›nÝÅm¸¥ÿæ:‚ú!Y’19Ÿ`»¢ôðjº*¯áþ½}öîî‘Æ)þÂ'OsB?d5³tCg³ñËÒÀ¦e‡1;‡diÆðô’ïcX³«•z…F£Ëz¾d5[²wóËé¯å±šÏ±l‡<)nó‘¨~æ/|мÀ4mÎOŸÇ!›ÍšÑù9š) Ôº®ã5<4M LËÂ_/ÉÒŒål†]±EêV,ÒtÒ$Áñ*èºÁÎÎ-=ZÏÉ‹œáð„ÍfÅz=GQT:Ý]ªÕŽãÑjíÐlöË´6×mlÍõ5&“3NOlMÝ5æó+*•Z™þ3žÐn‹JZiš`&Y–†k*•ú6=KTõº®”KªÕ&–UÁóš,ãí.~‹0ôi6[c»øNT«-tÝÀ¶Ý­ñþ/ Ã5–eo# óù~ÿUU1 “ù|HÛ”1‹,KÙlVÁ²LsÒ4ÍF˜ö¯üÕj‹ÍF¤YÇÏ…óó‡ìíÝ%ËR†Ã“­aîßÿ:½múZA¯w„®ë<}ú†acYlÛeÿyž+\·ÎÕÕSLÓ*+…aÀþþhš†ï/¨V[<{öÏž=Øzq:D‘O’ÄX–ƒëÖÊq –Û¨‘Ær9¦^ïR­6ËhÒó!hRÂÐ'ŽCtÝ,ÓÝ6›5£Ñ)InËD϶Ç_” Zmýv“d[ÉM|Nyéoy‘ëç½ÏkBõ‡:Á½¸°~’x•ÐxÙÏ^öú·Ù|þ¸/NV/þûe"äÅç¼J0½8!¾}yÕÿ¥0‘H$Rœ|?Ô; Z»-†ÇCa_mجE‘"/Ê(ãôr"*n-'KÒ$Ű ýòªªròÅ nÃe=[£ë:†e¥µN4NÙ¬7$qB–dœ?:E¤G­çk·äyÎÅ“ LÇ$ÏsЬ@QÖó5–c±œ,YN—«ÛµKƒ½ÛpYÍVäyÎj¶"X‰(IDeÉ`ÝÔ¡@ˆ1Û$ÞÄÛÅ¥Všñ×óµ¦N£ß`>œÓÞm“Ä Á2( $Q"ÄÔV …Aˆ[wQu•Ð…™;ÉŽØ9¦ù«“ ãE.ÞSk§E½Ý=/>Â÷Ñ;ÐÝë3¸±C¸ɳœÈع±O¸ ‚µ(@°œ°{{ùdPšÒ]¯F­Ñ¤Ùé•ïÛ­Öˆ71•J½ô)¸Õ†)LÞÁ*@ßšð“$‹O_ø;V«é6å&áËþŽã¢(Ú6ÕÇd2¾Øš­W8U‡Õj†m‹u»³C·{ÀƒÿÁà&ªªòìÙW¤iD‡-ÓÓ4M”ê5MQ¸( ’$b¹cVÙDU5†Ã“²wÈõ8ÒéìqppJ¥Z¦­ÍçCæó!q¼!MlÛãèèã²úX–¥¤i„¦é$I$ÊCW[¬V³2ªÑj HÓ˜¢ |ßš&DÏtz‰ªjض·5«‡èºUúxÄk“m•´%ëõŒÕjF¥RCÓtêõî¶òYx½Â+ß®DQÀz=# },«‚a˜eùà8ޔǶe’…˜»Ž¸x^Pˆ¢Í¯m¯ù¾¬åuBàuÏ{Õó_qò‡œûÛLÔ¯‹ì¼(Z^üÿË¢5ÒÔ/‘HþTÄÉ÷™B«é¢ïàÖ@’XìüOÎ&ônˆr¸a–"åî_ÞÅkxì°nè4z2ɪX‹€4Niî41m“Íjƒ¦iÄaŒ×ðp<Ã6èßìSäbÜ7-a¶ot nhtD~„fj„ë°¬†¥i^Ó£»ß-Íù ¢jØz¶¦Ö©a:¢l$É>(ß“ z›ç¾éDþmBëeÂåU“÷Ë §¯K+“‰Dò6"áÅqåÅ1ïeQãwñø·µïR8ýÓßÿÕfUÀUÑÓÄ­»ØžÍÉ'T[Už}õŒ,Íhï¶?³‹èa|óÏßPmUI¢DˆË Ñk” ÍMUáñoSäâ¼W“Ñ&ÂkzÌ®fxMQâw1^Pn]䢻u‘z%ù)ãÓ1Ëñ«bÑ;ìÑÞ¦üÙåŒF¯åXy×ô¨µkT[UTMe1^à5=½Ц0»œ1»œ•óL­]£ÑkÐ=è’D ª¦R©UèßèãÖ]æÃ9nÝ#‰ýÓ#м`=×l5}YÚ{ml×M‹á£iyžóÁÏî³Ym˜œO¸}ÿcž|úˆÍzCž‹ê\þZT3lƒz·^¦¸-¢òÙt4"‰ÒH&ȳÓ1¹<>gz1ͧ4{-P`z5¢âyD›HXt<¯Aï°'Þ£ªný'¢ÀA¬¨7Ûôú‡4[=âP¤Õ‰&„Pà8Õ²:–å8@A§?ØvI¯£ëFÙÌo¹œ`Yaè— É$‰¶Õ¸Ôm°ŒÕjF®©VEyÛ$ ±,‡éôœõzNµÚ"IbÆã3ÂpiÚT«-&“s,ËÞîÊ›hšNmxúôS²LDÈŽ?ß.ˆ…ðñ¼&qr~þˆáðxÛ×£º–U!Ï3¢ÈßF¦¢²,²(‰\°\ЍÕlvÅÑÑÇX–Ëz=g³YÑl¶iuyž1ÜÀ¶Ý2T©TËŠÍfŸ‡Qö[1 QE­(rÑœt>BÓ´m©f P°,g+¸Ì²—ãxx^^ïˆÕjJ«µÃhtJžçT«-î³\NNqœê¶Y¢·M%3Ȳ„ÍÆßŠÑgÆ÷çe%-Ñ×åºÑ¢¨¦æûóR€ã»B‡ezV–Åå˜)Š(Š :dÛû@ˆ¿ëc_W {ÙÚïú9¿;F¿^¼ì5R ü Š–ïZ¹¾81?ÿû^|üU•w~_‘ò.|4‰ä‡7޽ʷñüÏ_õº?äñï³Òä½û…¢*eD!Ë2ÑS#ÉÊÅýÍŸÞd=[súàMÓuSg|6‘ÇB34UÁ0 ¾þǯñ>NÕ!Ïò² p° ž ‰‚ˆõlÍô|Êô|Jg¿C–eË€½»{$Q‚åZ\<ºÀªXdIV– ƒU]èþò!õNEUètI“´œ B?d>œ—M%>>¢wØÃ° º¢'I{·ýÛ40U¼nr>A34Z;-ÒD,ªã…(OÜÞ™ëf‘³ÉMרµk¢Ú—¢°-¨µkìÜÞ!K3¦—SLK )ÒŠ–ã%í.ëù XN–TkMœªhxùì«g˜ŽI–d†¿ð©¸UjQ¢õºÀìjFÅóøê«ØVçjpyzÊÙÓ§$IŒ×ô(ò‚Ï>ý¯¤iÂèò²,#lUDiÞG>E×MáIÉR’8¡Ñm”ü«³gÔë]F£Ó2½g³Y‹hKœÐ±^,qÙì ˪pzú€<јËËo¨Õ:L§—X–C¬xöì«m•K\W˜½EŠ–èr] ªÑè†>ëõ UÕ¶}>Dõ©v{—Ï>û¯(ŠB…e)Ý~ÿ&F¿L7²m·ìÇ!õz—F£G«µÃéé—Û°y.>C×m ë&‹ÅZ­ÃdrFžçÛˆó\7w±ÐžN/ÊÊc×iea¸.»¶_¿›ÍA°Â0LÖkQŒâöíŸñë_ÿgz=á{%™C,«B»½ËÑÑOÊß­ëO¨×{å{[¯§ ‡§„a@³Ùg:½ Š6´Û»e5¬kÃùuÇ{Ñ€±(½*Q`&¦é°Ù¬ñ¼ËåÏk$ñ6²“ç‹ÅÛöX.'œŸ?ÚŠ®®[/½5ªªR©ˆ®ò"úÔ¦Vk//•çy) _fŽ¿~ο _ß¼ñe¯‘å…Åí9ùûC¯›È_7™¿Ìÿóüçòbµ´—UOû}>C)h$ÉûN–ˆÈȵÑ„㺙âf½}BòœÎž(w[ñDu¯F¯!")¶A¸i`i’ÒÚØáñPtG¯XÔ;uîüì•j…xÓ=ì`{6ÍA“éù”F¯Áj¶ÂªXäYÎþ½}æÃ9÷ÊsëîwÙ¬7¤IJ¥V!‰DêЙ]ÎXN–XŽUþŽ¢(Dš•&ú¥Ø›Ö@T]Ò Åx!º²û!¶ksã'7ˆ71Ó!¢qâµX‰‚ˆõ|nŠŠcµZ‹Õd…i‹”²éÅqý²4½Ñϵ IDATKTQÎxïÎ>µvZGø?7wV^Ó£µ#®™i™ n Ê2Ƀ£]ê:á&€’8)TV›U²$㣟ü w?ú)f‡F«‹ç5„Á{8GÕU>úøo©·šÔêM¼z•áÉÙxL½ÙÍuj]¼&ŽB&ã²wJ’ĤiÂÞÞèºÉùù£m%­U¹ƒ}uõ”,ËÐ4ÝÔi·w1 ÃašŽX,†dYFµÚ$Ïóò؛͚fsÀ—_þ7ÂpãÔ˜N/X¯gtû{ÛE±KµÚ"VL&¥âààC4M/}/GG†kE¡Vkãymõ©¤œÿ…á^xöö>`>R9E³Ù%¾¿À0lZ­Ým”B¤6ÍçC¢($MZ­]†ÃcÒ4ÙF!Rƒ[@Ži:¸nck8Ÿl}!9——O¶ uÑSåºr­Öa:½ Ž#z½ÃÒ¯‘çÙ6ê0ÞšÊ ÓéŶL¯Že¹}„¢(A·{ˆªª[1Yppð!¾¿(»µ+ŠBšÆÛþ&K<¯Áþþ‡Ôë"Å캩â?a>Q«µ·¥Ó²{üÅÅã­¼±½ž²Ôp½Þ¥^ïþÎ#úå¤eäÍ0,jµöï”~Þ(üŽ¡þ‡„Œ H~¯Ð—‰WUF{ñïo‹¨¼®G3‰ä}Å÷…ÙÝŸû,Æ K¤M/§Ô;¢¯Æã_?&c*µ ¡â6ÅÂ" îþü.ª¦ÒÚm¢âÖÁ‡¸u—ÖN‹³‡gÔ»ua ž®èìwHã”õLã¿ùô( Úª ±  OL‹Æ…×ftÃfòæ Iÿ¨Ï|8§Ú¬’gyÙE}psÀz¾&ôCš}áií´XM…E”%^ME©Õ<Ïit" Ò©ú!yžsu|EµYEQ‘â´¥€ë:nÛµE›©c{Âü\©VÐM<Ë©µje`%Ò™ÆÏƬ¦+*UQ l5]‘„ Õ–H¯ ýéÕ·árúÕ1ëé«b¡jÂxïV«X‹õlÍãÏ ¨B`EQ@ˆ²ÄYš1]Ro7D#¾å”¿­òå˜L'Wd™(ÛÛßßŪXÝc½ZàÖ]6–å`96óéˆ8ŠÄNzµŽa,#šÍŠ¢2Ÿ2™œ³\L8<º_¦H]]œlÎ’$f0¸ÅG?ù¶¢ÅÚ–Ö]mûfh8N•¢€4ÙÛû ìËaš6ÍfŸÑÕ†aoçj±Ó¾ZMKó·i:ÛŠ_"bãû‹2+ }¦ÓK6›5EQððá/·?×·~Qaª^ï¢ë&µZ›ÕjÆf³*Ó­TU#I":}úýÌf—åâùþý¿A×MŠ"'ŽCò<£ÕÚåéÓOË(¨X6ÂuE –è¿â†>ž× Vë°XŒètöȲ„ÙlˆmW8?D’Ä\^>¦×;Úö=Âæç?ÿ÷eùßÙì’ÉäEQh4º¤iÌÓ§Ÿ•~–<ϘυÀ»6Ø ‘ð´,—..±^ω¢@|þV]7QUuëà Êkµ³s{»fQɲ´©×"MUUf³«ú˜([?޲½â¾Ê²tÛ•¾ò/ÖC¦i½tmô£iÔ(‘¼N´¼Nȼ¬‚ÚóBæeј+“½¡ù¶/×ë"8‰Dò]à8Bl\Wí²+6ÿüwÿÌþ½}ò,'\‡¢aÃÑ]#Osã›õ†“/NXMW\=½"E#B¯á1<Õg—3ξ>þŠmiaÝÔ±]›Ùå¬ì²š®¶Ï…à¨T+ø ¿L³²*¢·‰¿ÞÝЩuD7ø«ã«²q£[wQ5µL‹ñšž¨(¶m&yþøœõ\t±W4…$~Œë÷Ó;ì‘&)O>ÿ ·& úµN Ã6ÐMQ,MRÂ`Cï W¦‘͇stCÇ©‰T­ë¨Àþ‡ûD›ˆ4NétY̦–!¢:ž½í#¢‹ÅˆålNš¦¥Ÿåú½hºÆáÝÛ¸5—$NÊT¡(ˆ@sÓðüÇ«P©Ôéîõ1,EU8¼s›ÖN«lìxyú ÝÔÙ9ÚçäÑc¾yøEÙSF×MÂЧÝÞ%Ž"Š¢àîýOˆã°4C_7s 7Ás>“ðɲ ËrØ=:bãûœ}½­5Á²*t»L&g ×eg«ÕÖvájÑí ë®[ggçšf°\Ž88øÕjÊj5aµš°Ùø\^>!MÆãg¥$Ž7t»~„aXÜ»÷¯¶‚Æ*ˇÇL&gÌçÃm×mlËçÛ…4Mpœ*ýþP`Yޏg6+Úí=<¯Áb1Â4mº]¹ö™ˆò¼Ö¶d±è-òÛ¾1cï³XŒ À$Í+-KøVV«Y–ÐëEž×äüüš¦aš6ëõœ$ Ëf‘gg_ÓéìÇ¢(`4:ÅóêèºÎéé\·±-6 —… êõî¶y¦¿-Ÿ¼æììásk™ü¹uøw«5@Q:=ÎÏ¡(*–Ua6»ÂqªeD亷ÊtzAú躱–vÕÊ2…ºN?eWe´ååû\KI"ù^Ë›<÷EQó¢ïåUÝ£_4ྋ4@)h$É[O¨š&*w™:ƒ›bÑÑè7Ê÷µI<Ïrž~úÇsð>^ƒý{û´wÛx OüÙvaöÕ3‚E@µU¥Úª¢š®qã§7ˆÃpªõn[v‹õL”Îͳ\ôäðl¬ŠEÿFŸþæ#£EÙ~ï¢›:Ó¡è¦m˜¶ÉðxHÿ¨ÏàÆ@Ô·¿×vmþòaÙl²( nüôõnÑÉH”‰Ý–¾õg·hö›Ø›û?ÿ„8ŠÉóœ`)"!O.¨Ô*lV>þÛŸ°œ. ×!ËéR¤ª]L±ù8tF£× ‰V“Š¢PmU9ýú˜þþniv_O×hºFg·KF´Z»Ô;ÿ?{oÖIz^i>áûûŽȬÌÚX,‘eš¶é™¶¾˜ù«s;736fÓ«Ij-¤ÈZXY• 2±#öpß}.>‡³X“YÅ–Q-JŠ×,/€ @ ðÏ9O USŽ„«í ØcQmE½±¿ô±íãÓ}4C£ÕoUŒ E¡(ˆ˜Mn˜\Þ³¸[pùõãñI”àº-E)+ˆëžý9q(r Y’¡êju@ÌóÓ¶Ê*Z©‚Ry·ðȲ„ÉÕmyXÔ¿¬Á¶ËrIÓ„¿&cTUãôìcj5q¨ÌóŒ^ïÁð˜®Ûf½ì“ <†‡i:hšAGU½î,Q–fÓ›ªù¡Î¶(Šª5JlM$ÎÎ>%M“ŠA’ç9a(² šf¢iíöˆ,K©×»<~ü¢(À¶ë´ZÚíaÉ_¹CÓ ^¿þ‚0Üp~þ9ºnU¡sAtß”¹ˆ¢-ºn’¦b㑦 q‘¦Q•û8=ý(õ½b»‘•Eˆjݬëi*šµEäP6›5GGà8m6›ŽÓIJêU0}4:Ã÷—äy^ ×m“çE•Ù¹¸ø aeªªE[|A’D@Q ¾§Bh7ûäyVZ³4tÝ.[¼Z­–%,yýþ!¦iWm^šfT[añŠç ôíêa5Îß>§<äZ¾¯½ëaÓ³(ß¹bþCR»ÙÍï+bÞ•}ùöÕw=çÞ&RÞÕLö.ŽÌ?æFf'Œv³›?ž±›6NË!c®_\C±àyÜž‹Ãètp»Ù²ž­±6º©ã¶]¶›mPŒ¶ñ6®ã›Õ†ãŽ«C~–e„›Plâoæ «cˆ-Ç`z9e=v©ã+Ñè6XMV$q‚n阤¬çkA˜Ÿ­q;.²"Óì59ûäŒîA—0E0~áá´M©à«é ‘Áù¶­=jS“j¶ª«\~}YA7« wçwEÁò~ÉÖÛ2¿ã4TCex<" îÎïÈAºù«—üâ?ý•°VµÝJ ™®Åf½Á›{DADkØâöå-YšñúË×Õk»ª«8M§nÛåø£¶ÞÍÔ¸s¢‰|é˜ØMñ3²6½ý>­a« –giVѼõ×ÉþÙ‰`ˆl·H²„$Éô‡Ìn¦lý€À÷«ƒ­íÔ ôH’4I«x³ÙÇm4EHÞÒi6¬W dY¨§ÓK’$·ªóùçÿM×)ŠœÑÞ1Aà¡éθ:ÄEQ‚#–Ëû²þ¶%>â€=£(Z ŽŒI’˜õzÎó翨>. 7œ}‚çÍOJ€bN·»ÏryçÍ+ãjuÏùùg…€ŠƒzL»=d6»ª`ŠÁsÃpøòË¿¨€•ŽÓ$Ë2&“ ¶[ŸùüU5h4º˜¦C–e†ÅlvEšÆ¨ªÎÁÁûeø]Á²êÜݳ٬‚5E!ìUq–V©ŽÓÂ4êuÑJ'lhZiŸªUúZ­ÆÑÑÕæg:½$ TU/µº´Z‚eóÞ{?­M3ÊJeÛ®W9’éô’,Ëhµ†eP^Ø·²,e¹¼Ç¶ëL&—U–DÜ_{tÝv)–²·ž~7\/Þ÷ðœWñN ü\qßÍnÞ•wù!±ü6.Ì»Dλ23¿ï–å»yšßwƒ³›ÝìæŸ~&W·tÆ&o&Õï僅©ØÇ_ú˜®)¶u áWuo­éªºj¿õ·X®…nêë€ö°ÍäÍÍÐeQ[œ„ nƒz§ŽÕ°¸þæZäC‚»a ñPˆæ©ãñnÛ¥=jsøþ!¦c’„ ‹ÛQÝÒ…h)‰ïq$‰5jØu»ÚÞ¤qJžå(šRm}²D°/ Ç ‰‚u@Mªñ÷ÿá„~Èë/^3½¹eÿÉ>iœ²ž­ñ—⊰ÛqYO× O‡ôö{¨ºŠéPÝCÓW£×`y·Äª[<þøCF§#6« ñ6FÓÅö§5h‰÷/7Ìîï™\ß²ÿÞ>›ÕÝ0¹¿¹"Ïr¢@dhæ·sjRf¯ •åëzš¤hºFQxsÅÝoî ÎI hlv:dIÆþþ{¬§k¢hK­&±Y{¬×S6Þš,Kpš.vÝ¥Ñna:·7¯Ñ48 ùðO~F ˜ãƒUêúò¥h—šNÉó ·.j~k5*[ÔÅÅ3Š¢àO~òï™Ïn1 ›"/ètÆ|ñùEQTWë—Ë;LÛb|pB½Þ©@ˆýþFŸ¢È™L.HÓÓtY­¦4]Úí!ûû¢B¸ÕR¯wyõês4Í(Y#[ÒT†ÃÐg±¸«¶¶Ýäøø£ªKÓ Æã3tÝ*-\9ýþQ¹misqñÎÎ>E’$&“KúýC6›ÿ„³³³ÝúÔëÒ4æÙ³¿)kñ»vpð” ð¸¾þ×"Ò÷—E^µb‰Ö0Á-év÷˜Í® ‚577/¯ªj4ú˜×¯¿@× \·Ãv+¾·8ÞV‡üZ­†ç͸ºúš¢È¹¼|†m×O*NLš&•TzÁLY,n«¼Í|~S¶œÅȲZÖ)l6â¹óPà û[tݲÜR€ÖJ¢½RUBç¹Îv²‡ù}x&9±ñÙ ”ÝìæŸÐý¡|Ì»ÄλšÊ¾+8Þf3û®0Ù‰öÝìæg²L\•üàÏ?àñO‹»½ƒ^UÓ{ýüš—¿zID‚Ïaé\>»äøã㪎WÕTê:’$U•§?*ضÈ\<ò]!Ë2jRÛ—·ô{Ì®fè¦.^#(ªzß4NIã”É› «éŠóÏβ?ùÑI•}1“›—7„AHè ¡´YoHâUWyñËÔ;uñõUÓ5éõiö›U±Ý>ýåý’³O Ë–"súÑ{di†7‡ýî^ÝÔÑM½jæRuUÞKNÊÃëaˆ@ûàp <úiÆÍËdE&‰–“%qs÷ZldÂ@ˆÛ½³›†m h ïÿäGžÈüH5‰W¿~YYón/.«fˆ60ESØøk¬†…¿^a9y–3¹¾­²@õN<‡aYQ°\‘“V›ÞbÍÖXL§Õf Þn fF˜0™\P“Äß…««oE^Upë"ë¥)ãñž·¨àÂÒ5c6½AÓLž?ÿ%«¥Èw<}úgDÑ–(jYVyýê7\½ÂÇóæ$IÄdrQfWrE«÷Âz”ruõ5²¬rpð>Íf¯ „ï£(A°Æ²D{»õh·G4›=êõ.ŽÓªÚ¨dYÅ0:1ëõœ¯¾úot»G¬‘e¥ªðuÝE!D–ã´„X»þæ[ðn™¹ˆÑ4 ðª«ý¦éày Š"/3.[²,åèèƒÊn—$1¾¿DÓŒêãV« Ž#Š@Šºn¢i&/_þš»»WÔ늢àîî5÷÷¯yþü—´Û#êõ‡‡ïWõ¿WWÏ«B‚k×z=+Á• TU™Ÿ2PŸ$1¶-2Bùau“°,·â­t:{Øv]·ª,O­&ÇÛª%í!_ò°‰y›øø¾­ÉCNåŸzve7»ùšïïÊǼk“ó6NÌÛx1ßÝÜìf7»ùãÛ®ã-<®_\‡1¦cVù'ú„õdÛvéîwiÛ¶Áó_>Çi9Õï½fh,'K4CÃi9è–.­R8ŒÙo»i³¼_b8³«™8xhŠÈbø!½y–“&)†màÏ}¨‰m€]·1]“ö¨-r®)¨ô¯ïñžÈ¤H5†'CмÀnÚXu‹Î¸CgÜy޲…JR¤ vøð}¶†-N>>!Å×’U™»ó;Ž>:¢³' –‹›ý£>–c‡bkP«‰¯¹õ·b#“Š|ÌäÍÝÔ™^M©I5ÝY&Âþ«éŠ÷~úNS4ž=ùÙT]åôG§diFo¿‡Ûªc7íª¼Àm»$QRå¶ÞVÌU•éG[–ËÅ3!„.­^ƒãmL»ß£&‰·“%š©•„ ƒ½=z=üÕšñÑû''åU{…»»sŠ‘•©I¼yù Y–‘Äâ°ùÐ@vtü®Û÷7Ö"q°^ašn•Á¸¹yã´èö±,Ñõ â8¤? T@¿nw€áÞÍfÏ›stôõz—Áàß´ö››—Øv“ÑøÓ¬³\Þ†>Q´eµš–—VkP¹Åãø$©bŸÔj¿µHA0Üppð”ùü]7ÙßÂ|~C«5Ä÷L§—´ZCÖë)Y––ö˜Éä]·ÊìFM3ɲŒf³‡ï/™Í®è÷¹»{¦™ôz‡eSW*¶Ke“Öéé'¥}KÀûýC¾úê/)ŠUÕÊÛÂÞÞ#êõ.Û­Ïýý› ôØïV6´ ðð¼9¶ÝàììSööëR°ÈL&âwÍtY.ïIÓ¸úÕëj5aÓ™·{~„×u‹f³O­Vc³Y–ÏŬY&a¸)ïKÂbq‡çͩ׻ÿ¿s„aØÕ6çÛïûÝ KöGózº(»ÙÍ?‘Øy'æ]™™w}®·…ü¿/;ó}³>»ÙÍÿ޼ëw­ÙoÒê·Ž˜^NìïjF¼Eµ®,á´n_‰«îE^ü¶ö¶ YK’ÄètTý~ë¦N%Ìoæ‚I’åL/§ÝtÍêk_>»B’ª|‰,ËU`ÿÛÛ ».ò2E^°÷ÞNÓÁm¹~pH–f¤qJkÐâöÕ-[_\Ã·å ˆã§»×UÉë ²"‹F°$#X„›ÕtÅètD£×@’%ê:º©£™ëéÃ1HcѬe7mV“Vݰ ¾úÅgâþ—ÿ7<н$ÄP° Hã”éå»a3:‘ç9¯¿ù¦b˜E!溊¿ð)òUS™^M«†‚ÎXØÚFg#ºã>݃.{÷ŸYݯðæš.®HŽD±Ý°+ åò~Il…gµap0&‰“êjôÃV(Ibîïß0UuκnÒlö(ŠŒÅtÂÉÉÇEÁ«gÏhö›‚§±H’Çi•µ*ï i''‹Ã°©³XÜÑlö ±?b»õeQ9,Bï[‹[dY¦È‹ò€ê°\Þ#I2Y– if 2ý4IÐuYVªŒÈf³d½ž2Ÿßë*Ð>¡ª:¶Ý`>¿áË/ÿ‚ XÓë‰Ã¼m7X.ï™L.0MIR¸ºúÓtxúôçb;68)«tEó˜¦M·»G¯'Îr:øx„eÕ98xJ­V+I÷qem*ŠÛnp{ûŠ0Ü”ÀÅTdž–÷hšxE Ý@Q44Í I"²LÐà=ú”ÃÃ0 ›^ï ´T¹¸n«²­éºçÍ©Õjl·óù5Y—ÛÕ„4Qáð”ËËgôzèºÅz=§(r^½Pʇ ™ÈȨH’RÚí„(“e¥²ºm6K^õ:$€ëõôwˆò®Û®Bó¢8áaëûÛ Ëwí`;²›ÝìæEÍwÅÈ»68ßÍÉ|ÛRö}¶²ï{û‡¶6»­Înþ5þ>¾­Tãúü «éŠÕdEï G–fU=°¿|’ëç×t÷»œ~Nÿ°O 0áõ‹kìº-Z© q5^’%žýõ³*ŸÒw°êI”»V’R£†U·XÏÖŒNGÌoç,îdIFžåh¦&nW«‘ç9q“e™¨Óm¹Â µ ‘d oá‰\EyŸ%YB35ZƒE.^?¼… ÷ûè–8¸y!HìA„nëL.'UãV¥˜®¨öæeß6*nI– ¾ÈôrŠÝ´¹}Ûvyú'£¨ ýþø¸\l/Ma5YqÿæÃY—˯/YÞ/‘$‰÷ò ŸýÅ/¨w;5hQïÔžÉ2Á>ŸYMVaþúÕ6Ë vÃfòfÂäb‚$ {Ýø‘ Ä?°`’8<”› Yš¢j*–k£j*i’T–<ácÚ«ùœ<Ï‘e…Ó÷DÅs¯Cè‡Ìç7XŽCGÜr…= IDATÞž“çëÅð[^§tG!Ôê.ŽÛ,™Š¢qA£Ñeq?¯*gó<Å[­0M‡éäM3K–ÉËj i&¯_ý†éô’noL‡œŸÆdrA¯w@£!6I†AI³·‘$™Åâ˪WÍ_Š¢ÑhtÑu“ÕjÊdrI Ê`p\f.jÜÞ¾Â÷ÅϨ^ï (77/ØßÅâŽ4Mð}aÍ* ªû!ô‚»ò@®O!Úêyƒ`Í‹¿Ä²êhšIžg%Aþ$I¡×;àèèòILØ£xòU5JØf™!ZOQU½‚?ŠÇ!®2"ëõŒéôª6±ÍfEš ª¼x¬LtÝd08FÓLúýCZ­!Ëå=›Í’»»sŽ?d2¹ êõviS“8?ÿUœ—¢(X­&¢@! ‚5ž7§Ñè•"ÅöEÖç"Iòï´w}{3â8êmÇiVï&µZíwDÊì¸(»ÙÍ¿Ò-Ì÷½ÿm¨ïÿ¿ö[Næ]bå»·{[“Ùï#€v³›)³vL£Û`p<¨Ú¬²4T÷LPÝMÇÄ´M¼™WY¹TC¥»×%Žâj{áÍ<4CãèÃ#¬º…é˜Ü½¾cv=›Y¢Øg~;g³ÜPïÔéìuŽhöš"(^@¼DxÃlŠÎ^·årÿæ^À ó¢Ê膧+ªRÕý…Ïz¾f³Üж‰Ã˜_ÿ§_ã¶\¨!6žÈ®4º Q“,KwEÓ…Hš^MIâ„,Í0‘|+ñ6F’¤êpo8F%Æ®Ÿ ëŽalý-n»nWƒ,˨ºÊâvݰ9ýà ó›y%¶¼…Wö%YâåçÏÅf#™šƒÇ'bS&\ŸW-j¯’$±õ·Ø ÍÐXMW–E–¥4ú¢ä ÏrÜvoµ$ Ep'ô÷F¬æâŠøz±¢ÑЈ£Xl;¢„NgÄOÿ§ÿE@Û-V«)Ÿÿõ߉ƒr ²ëå€åbŠï/‚ºiðÑŸü)†iaX&yžÓí+›Nž•õçèø}F{Ç´»}q_Ö3²,åå‹_sxô”ñø£ÑëõŒ0 8>þ¨¬ö¹¼|F½Þ.›«šeŽ#bµšT!×mWù‘F£K’DäyVm-TUöt:{H’Ìvë•BÂÁqšÈ²ŒiºEÎvëQ¯wK‰ØFäy†¦‰ç°ï/¸¸øMµ½X­¦´Û#Â0`µº'M¦Óköö“çiIvßVzÁ Aô‡º®›l6kö÷Ÿ°^‹²f³ë¶xýús ÃÁ²DMòÞÞ{DQ@½Þ!Šúý#&“KîïßTgçóò<£^ïÒéì±Ù¬J×°a{{IÓ„F£O­&á8mz½}4ͬ5ŽÓ¢ÕçYõ˜‚¨'NÓEBVðVÀ4m4ͬlaóÀËy˜‡ÐýCæHä\’*Doö.$¿›ÝìæO´üÐí¿/Ôÿ¶Û¾­ÕìmŸï]pÌ·½½,»ùó{˜Ìnfl}aùÙz[žþü)³«i’Ò4±'Ÿœíq[´ i.ض˜ßÎ?“Æ)E^+—cÒ;è ›XÓ¡ÙoâÍ=Ž>8BÑÙ+îvS4wù+2o [¬&+ß?du¿ªš¨‚uÀäbRÚU© ‚VÝâõ—¯Q5ÍÔpš“‹ i’rüñ1½ýš©¡j*Í~UPÉÍjÃᇬ§k!VR€T5•GŸ>¢=lÓ´˜¼™¢J9K2X,¿šTµÉ¹Ø¶€hêºüú’»ó;œ–ƒÕ°ªPûðtˆÛtøÉÅI§Ý°ÉÒŒ` vYýùp[.§?:ƒ²4uÐŽ¨®5lƒë——Œ…`LÝÜ_øØ ‘ÉYΧ"¨Ÿˆ‚‚hñâ+Ñl•¥óɽh ÛF4;mz{^V§×÷(Š‚$É,—¢Ò8‰ÜzI–ODH|Ü!L³Ñj ØìÇÞ ³ÉMµýº¹:0Ã0¤Õé“eÚW¯w°íÞz‰¢*Lï¯i´ÛŒFg<~ò)i’–„ô)¶Ýä?ÿçÿƒíÖ'ËRº½=ž<ùYE¥8ä:N‹ƒƒ§DÑ–ùü–»»×ENš&X–[Vä6¸»;/[½XVûû×XpoïqYÑ,Âøªª!Ë*‹ÅQ IyžbY.I"ò+išàºF£3$IÆ0,z½}§ÉééèõÉó¼âž¨ªÎtzÉdrA’DH’„i:l6k¦ÓKtݪ*‰³,e³Y²Ù,ÙÛ{¯‚$ –œ‹$‰i4ºhš‰e5ˆ¢ ºn2ŸU[ ð™L.IÓ˜Õj‚¦¢ô@Ñ0 ‡íÖg¹¼g»õDöH¢)Ë²ÊÆ”›/““•PG…óó/˜Í®QUõzJQd8N“Vk€$)Õæi»õÐ4ƒ~ÿ°Ú®<ŒeÕQ•( H’ð[Ã…@ùn¸þÇ[Àve7»Ù‰›ßKœü÷ˆ¡w¼íí· š+;1³›?ÆyóüÁ*`v5Ã[xŽ!ƒfõœíõ¡€(ˆˆ¶Taõ$Ù…,¡iY‘¡|ªçEŽaU¾( ê]Ñ%I’8à¶\VÓÓ˩ɕUÀ²"nBâ0f»Ùb؆e0¹œpôáI”Po×1I’°›6Á:`ï‘ ŸK²$êŒ{ M©6³ë÷¯ïÑ JŒ·1ÞÂmE ›ÙÍŒÐU=Ë ¼ ²½¹m—(ˆH“jà´4C«Ä“Órü€4I9ýä”F·Ao¿ÇÁÓ4C£=j£[:“ë[.Ÿ]òêó—4ûBJ’TåMÒ8E·ÅUæ"/¸{uÇz¶®.°Ìoæâ5Eª‰¬Ž¡’D ã1Y’áÍ=Ñšv&y÷¯ïÅöjišÐéŽ1 ›ñÞi*6^!îíVT/ïí=&<EòêÔëšÍÛ­O ÇX–‹$É4=EåööI¡i‚â~vöc@€]·MQ\]}CoQÏ›Ónɲ´#£Ñ³Ù5š¦—˘ÍfYÂZ­ÍæEÑJˆ\nwÌRp5‰¢MY±ì ªZIÏ ÃÇiQ9ß|ówèºQ¶œ¥¬V Vþ¿ÈµááW f³Ù¶]/ ¨¹êõ.«Õ]7ñ}a휖œZMB–U,«Žç͹¿¢¨%s(òUeÈ_lQòÒ*†>¶Ý(A–au»o I’qÝv)F~¿`üÛDËN ìf7»ùg)x~¨àm›˜·eh¾›ù®ýì]·û}ÄÌNììæ5ƒý}†§Cºû]¢ "܄Ȓ¶K²ÄÍËV“abX†°*5m4]ßû¨†ÊË_½$K³Š_bÕ-¢ Âi8üÕÿùWhºVµnyAAÁå×—Ž€ ^}}…U·pš½ƒNËÁ_Ь…¬Èâk–`E»iWMcIœD ¯>{E­V«êu—÷K‘siXPÂjy·D354C£5lñúË×8-Ã6hÛ$‘°N­'kú‡}T]lW ËÀjˆïG5TU! LÇdq»`z9åàýÆÆt÷ºD›Häsž_cÕ-f73±ÉDù€¿ôïsðô€ÁÑšTcp<`ëoiÚœqŽfj¼ùêœ4Ü’ãŽE«¥óú‹×Páÿ4N±6Šªg9ëéoîaÕ-M!Ïs]áá÷æë*¨¿÷xEQs¦eSïÔ‘e…û7÷\ÛhϺ¿» }dE€4ƒÀÇ÷„¡°SF§eÀ^a»Ýç’øæõ—ÄqÈz5+û2šf¢ª:ƒÁquð×4ðñý‹Å}™Y‘+k•h$v%Ï[Ðéìá8íŠÔî8M¶[×m£ë6wwçŒFgU­òx|F’ÈâÅÅW¬VSþöoÿ/4Íd³Y±ZMh6û(ŠÆlv¢¨eÀ\' Å÷še ÃáiÄ¿¾~^‰M3Kášf²^‹ZèÕjÂx|VÖûΑ$¥`†¢¨†M§³‡ªê,·4]l»A½Þ#Mãr#3¤^ï ëVº—ªzà0ÜT˜íÖ#Ž·4›b#&lnÂÊgÛ⢇㴈¢  ÏkšÉdrYÚáDÞG´®5ÙlVÕ×AZ.hÕk˜¦¥èÑÞú÷?r‹²(»ÙÍnþh…ÎÛ™oÛļëvoÛ̼mKó}ÿÿ6³+ØÍÛf³Üˆ½TÃnÚ(šÂßÿ‡_š¡¡›:õŽà|»†8ÚFL.'ö÷Þ>Ãã!Ë»%[ËÅW^Àz¾æý?{Ÿ«çB€ë€ÅíÓ1*›ØøÑ˜Ö°Å7û º¥óòW/Iã´Ês<„ÊÛÃ6'à-<4SC’¥*3“¥7¯nÐ ÍjC¸ ‰¶q‡F·AƬgk¸2;8q2j3½œn„êä“îÞÜ1¹œà/Dx\ª‰cǃÕËjˆ€?50,ƒõtÍò~‰Ûq¹üZT´&±á&dq»Ài:ŒÏÆŒ±ê²"³ž á ¨ 0<2¿™ã4ê8M§²b½üâkœ†ÃÁÓì†]1c6§9¹ÓON[c¯ËÖ¬ŠÁÑ€åý’ÍjÃìjFï@Ô”¶‡mÞ5ª†% †½ƒûO÷EÞɳœp#ìI¦#ì_‹»š©á/|½FtÌÓœf¯YQÜW“•°}mÂJ”<”¬&«ÒÞ”`Õ-Ò4År-ú}úHÐ룔ùÍáã/ýj‹ô ®ÝFÕ¶e7l ÇÍg®EžçU^äÉO>äîõ«‰¨Eîîw‰¶‘ïÛqóé¿ù3ê ‘ Ùz[ÞüæM|ÏÒ ÍÐ ¼@ØÒЦpóòF㓬;Á:¨‚ôµZ­ªa6“<Q’Ä$aB´ «Ï?Ÿß°š®0A —™åb‚Ûäðè}²4£Ñi±^,IÓ]·˜MnQU±›ÜŠC¾i:žu|€$ÉÕ!ϳ*€Þht98~Tò7B!0€v{ÄpxR}œi:ÜÜ<öë—eÀ»Em¨Õ¤2^àysÎÎ>‡MIª*ÛíƒÁ šfrzú#’$IJåFa¿²m6+ò<òêUà>I"÷÷¯É²”þQŸ(ÜrøèLØ–tpõì³Ù5{‡§ G'Øu±™Pu•f«‡·\1>ãñyžQ9yž¡(M^cîïß”Uº`ÛM²,!Ël»IQä¬VSƒ,«N¯w ûÝ=&“ ‚`ªêDÑEÑØnI¾ÓÙ+¹¬*”@%,Z­AÉi#Ë"P®(‹ÅPeaèc‹Å-Aà±Ýúeæ$#ж•Xzhó¼9Š¢¢(wwçøþ(H’ˆv{\ãÅÏ´ƒaX•O’dÆãGUfÄ0lV« AàQ¯wÊûrW>.:½ Jù` ˲ŒõzÎlvP±\4Mg³YU0Ç<Ï0M§Ú0åyÆÝÝyõ8‰ÍÊ´ú»“e®ÛzëëÝvëíÊnv³›ÝüsÝ꼋›ñC¹›· žßg[ó®lÎnCó?ÏýEQ°÷x€ÞA¯²jÅÛX„ÓmƒÅí‚F¯A¸ Ñt‹¯.˜ßÌ‘U™ñ£1þÒY oK³ßDVežýÍ3æ·s4S£³×a=]‹\‡mз™ÝÌØ¬6$QÂÞ£=Ò$Å_úDÛÃ1ˆ‚¨â¢ÄÛ˜h±ÝlQ5€éÕ”x³÷x¯:@פ†c°š®H“'ȲøºI”%nÛÅ_ŠÆ°î XoÖÑÂe ޹Z®ÅÏþ÷Ÿx¯¿x¬ ‹ŒfjÚ¨Èxsz§^Õ7º š½&“ˉZºh=KRtKØæ,×¢5l!5©FMª‘¥"»±÷Þ^},ò‚óÏÎéõyò³'ÕöEVñ|x´ÇèdD–f<þñSQ í «•éšP£ª4VuéÓ¶d‰f¯U•ë€fOüìܶKèÿö1=x_ýÇÆL®î¨I5ÁSiˆ¼‹¢ ÑØêw Ò±°¬:{‡§èºÍÞá I$ìai’ ÞLšxbƒÑnYÏÖ¤i"žI„·ž“¦1†a‹6­›+’8lEÅ_¯)ò‚0Ü0¹¹!Ž#ê AžŠ:Üv»¬uÙ‹ÍfE£Ñ-™(*iš`Û 6›WW_#Ë ’$UBU–U^½úuyÕ^+ŽÓb08®ÉE!¬DŠ¢2™\°\Þãû úýCÆãÇÈ²Š®[UÀdr…høŠ ŽétÆÔj5nn^Òlö1 ±=rœ&A°.éí‹Å®Û&Ëz½ƒ*Ðtô!²,3œppð”¢ÈÑ4ƒÙìšf³ï/èõ«LÇdò¦ ÜÇÕfæêê\·…ë¶ÊíOHžgG¯wˆ®›¿DÔètö0MÛnÐë (*O8<|Š¢ht:ã’ÿOžü)›ÍŠnwŸË˯¨×EM±e‰@þCEñpxÊÞÞc§Éz=«üö1]7K™£(êïüí2 »âª*¾480<²õ¶´-N>>a³Ú0>3»žUè40Á`T,8Œ±êyšW­Zƒ£Ýý.w¯ï*š»nŠLDw¿ËðxÈâvA–f(ºRåRÖóuÕÆõí¶¯ö¨Íoþò7Ìnf\|u¬È\?¿F5TjRÑÙY•És±åéôHâ„Ñéˆ``سëaò‹ÿçï¼€öP†i±\Þ³^Ïhuzd™‹›½8ÞB î.¯‰ã-›ÍŠéô’ùü–ËËgEN(,F®Û¡ÓWÐÀ0ôÙ;x G%0Ѩ²)Óé%õz—ÙìŠ( pÝve›uÀ6_~ù¼zõkƒc@”øþ’½=aKë÷+@§3b»õ à ëõ´ÌOÔ˜N¯Áà˜<ϩ׻ÜÞ¾DUu¶[år"˜2Ý=ù_,š½ö»üíÿý7ôz˜Ž€]>ØÕtSç§ÿÛOÙ{o`ˆ†°("eæUip8ÀtMÈÔU¢ bq·@Qöí‹êç¾H£× ÚFÔ­fÞÜ,I" D·tœ¦Ãüf&J ŽŽhš}tT}NßÉЇ<ÝÒ¹=¿Å÷—¯EVdZ}ÁÅ‘d I’0‘‰‘$© óŽÁðdˆÛl& ýÿ#íQ›$Š‘d‰éý5—/^—$òiiGÊÙxkLÓ!K2ÚݽÁ˜ådÎë—ÏÄ÷á´O ƒ-ýá>«ÅÓ¶éŒ:´»&7×äyÊtzI§?`4:Ã4]êõŽh‹Eð]X¨ºè¦,«4]ÖËy™q ^f¨‰lP–rwwÎííK=ù„áð¤d®öŠëvJQ` ëPTiÛnT‡üÉä‚~ÿ››dY†ï/I’ˆ^oEÑyùòW$IÄlv]¶‰ö¬7o~ƒiº\^~]5k GȲ‚,+t»ûÔjµ p)I¢xàôô¢hƒe5hµ†%õÞf»õ9:ú X!Ë*†áǾ¿ Ï3\WðmLSð]‚`ã4 CññÓéP0›]•??Ÿûû×%ÀѦÕÐhôÐu«ª&VÛ®Wv.ÁOY‘$qµÁº¼üÓth·G%Ä2'I"²Lp~ü”$Jèîõˆ£˜ñÁ1õf‹Î¸Ë£> V“ðæ^ŒÂ-iœ’¥n«Áþᣒp/ ‰½ƒ¾h7ÓmtK'c6žG½!DB§#,Œ¦éðúõ稪Žï/Ùøk ÆáÑSdY¦&Õà ¶ÝªÂؽÞi‘Ä1Ýî>ºnrw÷Šýý'|ú“Çb:a¹¼'Ï3úý#šÍA1Ôu“ýý'äy^BëUÅîj5ÁqZeÅð  £gUæ¤ÛÝãÑ£ŸÐéŒ98xZRê}¶[nwŸF£Ëht†¦ıș,w,w´ÛÃòпàððý2do±ZÝ#Ëj ÄÛ‰Ñè EÑÊ à&£Ñ óù ªªÑïñå—‰,+œžþ˜ëk± étÆ(ŠÆùùgd™(( aû²íA ìza{YyEÑh4ºäyÎÍÍK‚À+·!)ýIÕz–¦1õzM3QU<¢-ŽÓb»õ1 ›ZM¢Õ”Mhv µ”Kh¤U½Æ‰×ïþmø¶õëióú'(ïª÷Üý‘ÜÍnv³›Ýüs{{÷øøß~Lè‹­†ª©´†-¶Þ¶"£‡~ˆé ÑðòW/9þè˜ÅÒÂB×0]“z·Î—ù¥&ö°D)r¾Ö-5žüä=¢mT‰·åbØW__aÚ¦%aL½Sgz%èçi’V[˜¢(H„z·Ž¢Š ½¿Ü”Z­Æùgç¬gk‘] c¢ b³ðÁ¾‡Ót˜^M«¬Jžç‚í²ô« à4NYOÖÄÛ˜ö°]·‰‚H\É–%º{]ü…_UgIV¶ †ÌãŸ<&ôCdEæüósÚ£¶°–Å)íA›4N1ë&vݦV«1½š¢›:Í~³²±QÀõ«*ï2½šbÖMœ¦Ãàd€¢*Øu»%«ûš©á4ŠI£âðÙÝï’&){ïíÑì7ùúo¾æñOÐ?ì#«2ÞÌ£Ôk¯ÁânQe‚â0ÕÓ–^Ñà;£E.‚Úiœ Q´ôéô)ò‚Ááˆ7/ž£[:[oËrºÀóæÄaÌ›¯_qq'r$AÈz)ÚÎdEî5SX©,Ç¡Þjb5D‘, ›Ýr6Ã_ ŠúÕ‹7ÄÛÓ¶ªæ²ñé>Q‡åò^ض6!f—ŸþüßÓlpœ&i*ë†e°Ù¬¹8ÿUÕĦ¢Õ¢Æ1IÓ¤¬~‰ï/Êp{™ƒ)9/"ø.èGÇ`Û²IKÀ$³,e»õpœ¶]Dzê8N³„5˜¦‹,«¸®-ÔyÑüå–yy´,qÛõzJ»="ŽC./¿Æ²Ü2¼žbšnEu_¯g(Š€(¶ÛCâ8,ÉîF%®E¥ß?f³YavUï;ŸÑnI’ˆÁàEÑxóæ+Š"g08)336¾?§Ù°ÝzÔjªØhôØlVE^òob&“‹²>XÂqšôû‡´Ûã²¥-#Mc’$Ä4]\·U5¥i\ÕOëºEQäøþòw^ϲ,­ò'ÿ{ïÕäJž¦÷ýÞ!‘ð®P¾ê¸îžÓff Í.wEQ 2ô©t­Ké ðZ!‰ºaˆ"E-—3\Ã1í-ï3‘ºø£rzšÝ=½»$cf·ÞˆŽèS…2²€|òyŸçç8",ŸQÓt~ÅEù/yÎ.ý&¼ ÿºÿæaæaæ¿Ì¡ïúØ×³+óW«h±YmxõÓWTÚì²ç>îÛV§ž»ÏžŸQÛ«¡h óáœ`pýFÑãà~Ø%[è‘=¹§´ß¾¼¥yØ$MÅÉ÷|8'ÚDè–ÈP”ê%q5¶hëÅá3º±w¾' ƒç]¶Ù–ƒg¨ššSêã(F’%Ê­2­£VNaWuA#¯ïÕi4™æyFÃ*Y¬çë<„øî¡… lVáÌìµ8мðî?|—õlMã ‘_ VBÈm·[æÃ9†eˆ•±› nÍÅvmÜŠÅ×öjÔ{uJ áÄŒ®F|ùç_,ª*išŠJßÕ†"8Ÿyðš†mp÷ê€Y†¬ &fjl³-º¥³ž¯ ýáåб=Ѷš­¸yyÃÝ«;^ÿâ5ÍÃ&ƒ·ƒÜAÑMÍÔ°Šâê³jˆu>Û³óµ7EU0»d ä&F356ë o?•×8oÙŠµ5MáìÝgË@ÔB7«œ½óãáÇÏΨï5„ n–éî“¥³Á UÓÄZW³ÆdÔçöê2‚5ãþUS©6ôÎŽhííc]¢0ââÍçô¯¯ñ—k}Þ|þ‚ýãs:û‡ÜݽBVd¦£Y–`:¦)„\ á}Åv\VË9¦é¬|  U5hµŽò º®›¤iÄb1Ê!ƒIQ¯ï…bå¨wp¾sÔ|Íi<¾FQÄUû$+až×àææõz/g¿T«mÂ0Ø1YÄŠÒdr“3O4Í Ó9Í«Œ«UAª×4cçˆ5³Ÿþô_£ª:Ëåd'ÊD1@,1 ‹r¹¹Ë²ˆZß{Ñ2]ïVߪ»ÜQÂf³f6ptô.¾¿ÜµkÉØ¶K–e»š`5¿mض‡aØŽËzWzPÄukx^“8 ‚Õ®´ ¢Zí’e)Q ëA°ú•×wÁHÑe%ç¤l6ë\ŒØv)Ï–ÜWo·¿|¯‚Uôÿ¥Ãò«ó×uUV¼æaæaþŽï—üê ×7}ìA”üÍfp1€"R( Ë2ÕŠ ‰X®Åråc¹åf™átŽ$I9»c›mYŒŽ¨ß¯+EPLSB_ð:Jõo~ñ†IÊfµ¡Ò® [:ËÉ’,ÍPT”¶=›R£”Wï=œ ÝÒùøO>¦Ú©2¼íX³ÁŒÁ…8ÉÞ¦[Ñ‚U4Ex_‘sa1Y h Žç ­ãŠªÐ:l‰à·.NU]¥uÔ"‰jÝ^ÃAóþI‘¸{}Gó°)Bòûõ<ßa8nÍe³Þ°ÝnÙ¬6,§"‹óúç¯ñš"óRÄq;¹ É{öraRïÕsת֫!+2ݳ.?ü'¿“seš‡MT]¥Ú©æðIIâcp1`>š³ž ·¨uÔ©ˆÈÙp†Sr¨¶«½w$\“ƒF¹¬vª¤IÊèjDÆ,Æ f}–¿øøÃ1ò&4 `8i,ëÎI‡õzÆÑÓS$Yb|;¥ލóÕL$ŽQ4…õb×_}y!®z')ª¡¢h ‹ùXôCʲ‘–Nè‹Q–ftϺ,Æ ¦ý)†cPn• 7!ÕN•r«L£×@R$ŠeÁ:IS!fEÁpŒÜ¡’$!.ûoú>=À­º¢öÙ2¨ï5pÊ^ÃËóJŽç"Ë2i*޵/þ1'ï<!ô$å}ˆY-dƒ· [ÐÄã0Æ+×…(Ýn‘9ì·÷hu÷yôü]!z8Ï÷ýj$ITªMñØ&‘¨˜^.X.'¤I*ƒšÊhpK¸ÙÐlíïþ$6›Žëbۥ݉p™×¯¶;Ñÿåk“aYXŽ“gŠDNdC,X­f(šÊtÚ'Mc’$BQ4jµ=LÓ! hRÓL–Ë …H’œŸ4 ‹Ýî9ÕjM3è÷ßÇÊåæÎÑ)—[x^“z}ŸNç”ëë/©V»†C;•`š­Ö¦Yäææå.d.Dh0+0›õ1 ;^›ÍŠfóP¼Fì„Õ}ƒØ»ïþCªÕY¶%Ibâ8Âuë¬VÓ“··/™ÍÌf<¯Žªj»×tqCÓLTUÏ_¯ûäbǺk–ÅbE<¿qˆm—v¤z½'ÝK’´[?›ãºÕc¢æâåþc_]·D#ÜWÚ¾ÊÃ<ÌÃ<Ìcãë‚âÛNr¿Mx|S-ðwÕW-ñ¯[•}$ßoþ*kÈÑ&bÚŸòéŸ~Šc›9q>š£êª ”‘¨Ô EüàÙ“ÁI–ðWbuçîj€UnE’$–Ág?þŒ``Ú&ËÙ ¶PiWߌÑ-x]–AÎñç±)–Åžºné¬f"cb{6aÒùÓOrÎJè‡è¦8ù¯´+xuOÐêu-盼úé+šGM4C#XÄ‘pÊ­2þÒ÷_–‰£˜ÅhAó°‰UÁxEUd‰·¿Ík‹÷Î÷òà¾åˆ°|°'žõ^Y–)7Ëø ŸÉí¶ðÉŸ~œ Ïñ¨·í=îÑ9é°M·TZ‚e€nŠœ‰¿ô©÷ê$‘»)7Ë /‡¬ëœS3ÌØ;9 ŽD)B–f¬¦+‚ݱ1ÌHÓ”ådI±,œ5US±]›¿!c–ã%݃#(€åXøK_ÔïVøŠÕ"‹©¨fN’(wø$I4°Í¦CÑÞ¶Ëé¦Î|:¦Þì`:&¯?ý’j»ŽiÛTš5²4+g­i’+J^ùLK²"S­·Ã5^Ócãbý¨ÑÊO¤U]% ×H’hÎÜ…Z£¢* î®Ð ð©6ÔëûdYÆÕÅ—t:§L§wȲB–eøþËr)«\^~†i:ÌfLÓ%I"4ÍÌ3ãñõj(ò1Õj—ÙlH”Juƒ‹<[²\NèvÏ8?ÿhW,Næ§Ó>µZ—BAâîî5óùhÇ„Y`Û¥œ)KEçââSQM½+X¯g‹e–ËIîÅq(*¨Áª®©×{èºI¹Ü¦Ý>Á¶]NO?À0,Â0ÀódYF½Þ£P0M‡ÛÛ— ‡W;~‰ª„¡ÏÅÅg¬×s|A¡Y–à8å¼ml0¸Ø‰Ç2²¬P­vóçåææE~Ì BJ„a@­ÖE’$,ËŶ]QOÍ_/›ò Pæaæo8ø¯ùýôð»(ñß&.~]æã×Õ?ÌoÖ´ŽZ<= yØd±­W£KQ<¾#KR^ lغª ‚ùpŽíÚ,ÇK×5’8Á,š8EQK|ôîûOö¡Nɦÿ¶O¥UùåÚÔ`Êb´ u$ˆäû{b•)Šó ürºDÞ­ïtZè–àœÌGs …½G=ì×U&w¶Ù6~o3‘¥Ù¬7„¾ÈiÔöj\!ÖƒîA†^Ó£T/ᔆ—C RÎI‡ÉÝ$wašGMöS6« VÑâù=B#ŒÅçÒ”JGp;œŠƒ[uE¸<ˆðç>'ÏO˜çlÖê½:i,®ˆ«€½ó]-ìnÍ­X-ÒÓg9YæüE,—{˜äz¾Ær-‚U€¿òóV2Çs¸RßK3`Q·t>üÇÑÓ«]qÊ'úIžÃÑL-?q£X8>a,Ü–$ãÍ/Þˆ&4ÇÌs*¢‰«ÆÆß,ƒóé˜BAÞ TM\¡÷n®^sw÷Šh#òï<ÿ]«T8ŽrÈ4VÓª*î·®‹•³n÷”,KwâáTªÓlí³×;c>R,VrháþþF£+ @«u˜ Ç©pw÷Ø¢(Åb×­Enn^`YÅ]Ýq%T È$;×(Ãu«9Ñý¾ú×u+l·ÙŽãbå¬YVòv®ûu¯íá6©¶í†BÄ™fÓtÑ4ƒr¹Ápx‰e¹èºI’D躽{/(e"ÔKÂ0@×M&“[4Í X,“e)ªªíšÌaÅb…^ï1Óé ¯|¶¬ÝîûûO¸¹y±Jbµì¾Jù>WR(H»4YV(¤\ &I’.Iâò0ó0·Éw}ì»Ö£¾ëß_ßæn|“øø&ã¯"<Èoï¤Iš¼·[±Vup¶—¯}EQLѱP5UìàoEÎãøÙ¡€ðˆö§û¼[ˆ¢U–ñ—>a2Ìü íã¶È6 f$q‚ã9üð¿û@ì—7<â»$E¢uÐDVd†×hé:Q‰€»ka{"¨Ý{ÒÃöì6¼î®ÒJ /‡h¦&@—®;ž#jMƒg¸UW¬9¦p«B±^f»6fÑd1 FES°\‹½G{8e‡bµ(ˆðÍ2²*£›:ÓÁ”r³ŒåZ”j¥œKSiW~)d–>­ã¥Z ·æòô÷žÒ:jñê§"@~/HܪËj"\«,ÍðW>µn »dã”Eާ hì7ƒýÇû¹s¢™²*c•, ËÈ«‚T KEÃYµ[Å_®©ukâ~o"lÏ&Xœ}xÎÑ“3¾_m¨6"Od»ùc«*Ѷœ,é Òýå«—Äa,B了W/“¦)̓—_¾¡Ú­¢ê*õ½†cAí98¥"nÕe8¼Ê[ë›ÍUS1“,Kߌ)—´ZÇ–Éf#V%IÂ_/ ÞpsõRä§t‹,Ëð*uæ£)I£if¾~¤ªšfR(HDaÈ&ð©7öD ]"ŠD“ˆªëë/9:z8Ž8?ÿ““çDÑUE–eL³H¯÷äWò,ºn¡ë®[e>Òhe†aï…M§sŠã”PM3v,ሬ×sæó¶]Ú­=mÑ4Ë+aÎq¼¡Ù<äää9qE«ÕlWû«ç™ù|D¿ÿ† Xå[Y–Òë=!Š„Pl6wuÃ&A°äððÝØr)ŽC<¯Ža؆M§s’¯­5›‡¬VSG¸;’$ãûsŠÅ ¦é°\Nò0I’wbÌÜ,}ÖëÙ_ëõôA <ÌÃ<Ìo¬ùuôóû“øo»Ý÷]ú¦Û|—Èxhºz˜ošéÝ”ÛW·8žƒ]´P[×i·©¶+\}q…,IôÛ4*º¢PiWˆ’„ÅXT¬*š‚¿bÄ,šdYÆd8£Þ´Óޏr‹¸a9˜Q’¤Ü±-ƒ¿A34ºGmä]øÛ­º¶Á_üé/r c±\„­h²’d‰JK°J‚eÀänÂèvÌb²`5]Ñ=íÒ=¬–éÝ”ý'"SÐ9é®H¥H'x £÷ޏ}yKA*m¢ü„ú¾Fx9]G1š®Qª‹‡éŠÕ¸Á›^ÃË9'ÍÃ&ÛLÔ8‡ë飣ëQ“Ô ÅhÁz±†,F‹|=MÓ5tSÏù2š.Öï‚U@DÂ=J… #+2‹ñ‚4M™ fܼ¼Éë•í’Ÿˆßÿ¼ûHšˆzàÆ~ƒÁÛq ×b¾¦Ú©â5<®>¿¢@Çsòçn>šç-cå¦ÈŽAÆ /‡D›¶Pn•Ùf[*í …BAä|*.’$qþá#lÏÆñâ0&…”eÁ¹É’ ü ·æröáÃË¡ø\š¡j*·¯nU9,ëÍ.VÑ¢è•0ƒz¯ž¯úµö»Ü½¾ÇÌΕ[Ï׬fK‘ãQ<¯!VïT…«7¯hu÷Åï°»èâûKÏ¥Ön‡1{GG¨šJ±ââzez½'Øv™ÙTÕûc˰,Š®GÌfCŸÑìörˆàj5ËÃå7—¯óoQC|3?îW§f3ñý_¾üOL§}®®>Dz\Ò4f:-oÆÅb…Áà-Š"úÅb…$‰h4öY¯ç4›G¬× ÂÐÇ4‹ÌçCV«i#Ë ›ÍzUԘχ»ÌÆ/Û°$I¢P(p{ûš4¹½}°c´3› ètÎØnSL³ˆewœ—%išP*Õ©V»øþð¸»{i1 ›4«kâ>+,#~ðƒ„,+H’Ìb1&Iâ])AÆÅŧ$IÄx|ƒaع¥i¾9™Ü’eÙnýKÞü§x^YVó, ð+dúò0ó0¿‘.Ç÷q1¾*>¾Oåøw ‹os"¾Àþ0ó7˵rîGÿb€j¨DIÂz±F‘eZ‡-IB–$n‡c–A@臬¦+Ê­²X)óù‚T [Wìµ\0K3²$ã¤×¡Ò(#Éa2¼R¶í<!I’È&x6o¿¸d½èœtDà^*Ð{ÜDŽåžo2¸%Ñ&Â*ŠûÑ>n£h õ½º¨–Üqt5"‰ü…Ïg?þ,?¿Ï:ø qõ4cæÃ9º©Sª—hµÄÏ B‘MèT‰B\ô¾à€Ä)Ýó.ý·}â¨<βŒ(ˆò²R­DA*PïÕñBÄÄaÌÙ‡g4z ª*¦#ÄΖ­pF,ÅxéˆåävB±\Är- ²{¶k“D vÉÎy÷jåfYæUÉ÷E²*SmWYN—И¦4¨†*20ãEîH¾{ˆåZy Ýkx„~ˆj¨lü ëùZð îyÛµÑM °š ®I¥U¡X)‡1þÒgÚŸGqîÞÿà˜$NrNÌv»%ÚDÌú3‡ ~úïþœÙ`Æþ³}’8a›m]è=ÚÏWƲ4#‰’üØV5Q“œÄ‰zÊ^C´©•ê%V3¤ C‘•^ Ðu ]/—œ½û »dç R»dSiÔñëüØ‘Qó|¿¶(I{Çœ?FA*°Í~ù:Ä A°¢ÑØG’%n.^Óîà¸.ÛmFïðŒ×¯~ëV)¤]½°F¯÷˜õzN±$²Ûí–8™Ln©TZXV‘R©Îv›!Ë*óùEÑðý“ÉI£Y–æöé´$Ihš‘C×뇇Ϩպ|ôÑÿÀb1Æu«´Û'¨ªA¹ÜÂ0œ¯D´a¹nÇ)ç-bž×DQf³p2¬×sJ¥:ÅbM3°í¥RÃÃw¨TZŒÇ×»*b‡b±Bìï?AU ŽŽÞ£ßK©Ô Ré0ŸÑuY+p§§ïS(Àb1FÓDB¡P@’d¢h³si|Êå’$£( ¾?G×Í|…mµšåÂO8R:Q´A–Õ_>>”‡y˜‡ù;Uòu—ãëûªkñõ½]êÛÉC%îÃü¦ ”Æ~Û6yôøáå¹P`1Zðæ³ ЖeFÓ9Yš±_« NÈzƒi› ö«U6kÁíPdCÓÐ4MQr¡áøQÄj¹¦X.ÒÞk°ÿ¨Çp±'ÍŽI’¦ù _c¿AÆy[^ÏÒŒƒã.Цˆ:âZ‰hññÿ'ÂßVÉWéËÅü»^ñ™æaSd,]d'öjÂÊÐðžïÒ{ÒËY‘YÍD üF(+²(ˆ‚U€néTÚœ²Ã£>­º”j%ã›õ&¯;¾g§˜ŽÉÁ³œ²ƒné$qÂr²$‰Ú'í¼F8Ë2öŸîc:&×_^ Ή©3¼b-‚E;!½'½_Ö€ÌR̓lVB¸¯f+’8γ=gg„¡O'ìŸú!DÝqD´ÛÇÝãÑ IDAT‚ý2¹¡\n2›õ‘e]7™MF9S¤Ý=" ªÕ¶íQ,–q]ñ·Y­v)y5jõår“~ôß³^Íð}ÑTP«u±,/•ê¢ÌñØlü)˜0 ‹Å˜b±Œ$É\_A£±¦™»zdÁ1 ›óóX,F»Pºš7|éºÅb1a³ñwy“UÎ,ñý%®[c³Y3Ÿ°,I’Y­¦t»g„ášn÷ EQ)+T«®¯_ Ë*A°$I"Öë’$stô|I½Þ# }²,áàà)gg¢ªOŸþ>år{Àtv«qe‘G’E#ËRÇ;»ÌЃ@y˜‡y˜ïår|;ãëµµßÔTõMu·_ _ýßǹø>¹ŒÇãa~“g»Ý¬‚MÈ* ©ïÕñ£(gŒ®F  tCôMþãü˜8Š'¢hS«”ØÄ1OÞ9AVd¢(f¸XpÚlR¶mÞ~ü–ÞI—â$ÁÜ­qm»7}æ³%íJ™ÕtE«T"X ×$ ¢¼j· èvX%ÑÈåGQžw)ÕKH²ÄÁ;LÓÝšO…ªãà/}ì’Íx¶ høK_ Ï¡sÚA*0m““Ã.Á2`|=ÎOBí’·kSt!´??ÎÈÎ-j·)7Ëb qRºYo š¡QëÔòšÜ$J]p<‡YFª®¬~÷EcÖäVÀ7+QJðâ/^`E>ex9Ì31÷EéçBªTÙ˜ívKó ™çn’$¡Þ«ç®ÒÞã=Î?:ÇñB?¤uØb5[á/|$I‚LüþÕN•ÁÛ'îJ ¢M„[uq«.óáœÖa+owË2á`˜Ž™ †ù`.ÖźUzOzùc•ÄI†¼žuSG5TÂ@À%³,c=_çÎÊ=ÍÞr-ñøµñç~À_Ï×´ŽZ¶È½Œoƾ{[r1hE.GÑzö©Ö[,™‰÷ÉݯQ«{Ž)„¸#Š ËÀr-ªÝj¾š8ЬBš¦"µ»i"Vïܪ‹[.QiUòu3YV0‹&ÑFT¿üâçìŸS ¸e‚Tà½ÿ°¥w|J­ÝÂv\ºG´ööDð;ØÐéž`Žp¬,YV(WÔ{H’ÄíÍkLÓaã¸^•Vë˜^ï1¦é iãñ5ºnïj†‘$™årL\_‰ãxH’D­Ö¥Ù9àÑÓ#:å2ª,£© VÉ¢ÞÜY’¨8ãÕ S<Œ8Љ’MQ¸è VGÙ²hyBÈ8†AÅs±4ÑU©”Pd|œ¬×œõ\ °]‹½z•8Œ™ÜND]m–_q¿ç™Ü‡ÇuKÇ«{ÔK"H½‰cÊÕ’¨BÒíM×0 Éí„“ó}TEÁkx¼¹ºɦFѱXŒ¢‘j&ÔtÁAY,×"À^+U÷Ã6øÙ¿ù§(ÕÅÕ|ÝÜÜè*nÍÅr-Ò$Íጋɂ,ÍòZâû¼I½W'\ °eDüþ?ÿ]tK§sÖ¡{ÞåàÙX…»w‡öê̇sUa1YpýÅ5µ½iš2¸`Ø{ç{8žCD¤i*Ø6ë ý·}û (ˆŠæ“÷Opk®Ñ×K(šÂ³¿ÿ ÝÔñ—BÜ×§IŠ×ðH“”»×wÄQÌjº¢¶W£qÐQ‚×ô8ûðŒ$J¸{u‡íÚLn'–ÁøfLµSÅpŒÜiߌ1,Ñ|6¼rðìÃ10EUD¦#ù”8.Ñý Û{ð^¾ÂW(ˆ Ñý1yûòÛµq+Âi¶°KvÞ𶞯yô£G”j%ì’M–f\}yÁåg—B•,æ£9I”0¹ "<Ÿ·šÈר–“%º¥ ad‹õÁ{†[,˜ûÕÊw>øÁ"ÀtLƃ¾¨¹^úÔ: $Yb9Y2ÝŠç/IW¤,VuÃD5Ô\%qL ç±Û;AÕtÖë9ƒ»K&“[úý·ŒF׆C·{.ŽqÃÆ0-J¥¶íqpðŒƒÃ'(ªJµÖ!I¢]CY¸{–˜LnùÅ/þÿ_|ñg„¡çÕ™ÏGèºEµÚÁ4‹9±^ï Ãbÿ)Y–²·÷H˪FGXVØ2Þ‘¦ ‹ÅÃp‚³YŸjµÃ`pA§sŠªjÿÛöˆ¢ ÏH’ˆvû„8qÝ*², ‘Q´¡R9¸^ï q¼Á4¦Y¤Ùª¦ækR–k‡1ÇÏ©4Êüî?ÿƳEÎ%IÓ«$š”î3*š¡q¶ß!Iš"@Gܨ[:åf™ådIµ]AVE]¯ïop«.ÓÛ)«éŠ4NɲL°Ub!Ô*í “Û‰¨/Þ¯ 0e¡Àó?zŽ¢*9ÈÐr­|Õ+X”[»<¬²4Œ–UÀåg—–Á|8§Ü,Ó:jÑ:j±ÿtŸéÝT¬¼%)†mpþÑ9Ñ&âøù1nÕÍWª¦ý)Ñ&ú~ެÈì?ÝG·t ’`¤$‘È(ªB¸fáSª•ÄçÃUSÅ㚤"?Ó­RiWh·r0èj¶ÊK¼¦'„÷*àü£óœs¬‚¥h3[ÍVBhËbeïÉï=ÉÍ´?%‰N~pÆá;‡Ø%EU/f»5ΪB¥Uì Uåû2‚ý'ûl·[ܪK'”%»Ü9SÁ*@’%Üš‹[·ÙøÇÍ[–¸÷lšj­¬ÈHŠDwÿ˜`ðê³O±+wŸê{ ’„¦ë¶Ár>#Ü4ÚÝÜ!èí?¢Õ:­”HÓ·\Æv‹è–ŽaZ”« Â0 Ž"•¯iÝg9,ËÅóÔj{½K¬8>~O4üeGGïÒl$ ··/ñ¼z=”e…ù|Ä`pªê†³-FȲüKЪnÑlíÚ¶Ì]9@ŒçÕ9>þ’$Ñnãû TU#I ¦Ãpx…ªêT*mD5óšfbÛ.ÎI!Ë"kr{ûŠBAÚ1Q øþœ0Ü i&Æ>årß_îjžÊÃ<Ìo¼ù.2øWÿÿی諸ý6ñ×Bäaæ»G34z^‡¸¦ Û-›Õ†¦ë2Í0mƒëéK'”U‘+¸oñ-—ÄiJ'ÔŠE&«nÉ YñØn·Tl±®£ê*Ãù‚ ޹½²YoØÄ1Aáâªùåd‚¢*QÄa­Æ§×7ÌWkæ‹QšRu|¼Z±‰c¤YÆãý=¤ÝkK2£ÿ¦ÏjéS­‰}ò0Ix|"ªpÏ{ÔetU¥Q¯°X >Äx¶`Çtö›”ªn¸¾¿ºÚj 碪ªÐ=hášb¥ÊPUB?äîÕGÝI”ˆ«Ú¨Ô=t[ˆ¨—7wØŽÅl8¿Ë;‡"\­HB”x6Ùv‹WqE;UœÐlר÷ê´Ž[uÄã³ Pt…h¡êâJ~¥UÉÃýݳ.ëùUW©´+P€æa¯îQn–óÜÏ}åo¹YF34Þ}~Žª©è–ÎÅgx OõG"4‡±p‰ ¢²Ù°… ÓMQrà/|Öó5Yš±w¾Gó )®ôï\ âñ,VжSvð>š.5åV™$\Ų`ºø+_ü]¡sÚa6˜å5ϲ, ˆè&f½Ë ͳ©^+ëùZä¬J6•N…J»B¹UæÑqð쀃w„3Šö.EU8ÿè·ææ Ðåd™W[;e³h¢j*²&³œ,¡ „0[Ðm̼"º©,Öó5•V…$JhŠU(ÝÔ_ñW+žÿÑs²,£{ºÇz¶¦qÐ@Ñ„c¥[‚ób-Ñ Ö4ÛûyÅô½³X(ˆBˆÐ…“Pöèß\"Ë2޹»}Mû¸Y4QÐßàx¯¿ü„þݪ¦æÐÃ8Ù¤årÂÅŧ,&“[Ú{¬VStݦZmïò&¾¿À«Ö®Y,†È²Š¦™(Šº:¥R×­bÛiš$Q.xE|×­æ|EQñ¼:½Þcåœõw ™û:oA{‚%’$ãyu*•6Y–R­v8<|‡4Mòæ®ÍfÅÞÞù®±l„e‰¢`Ž70 +§Ô¯×3V«)†a?”‡y˜ÿÖnÇ÷%Šõÿ¿Éåøªøø6·â¯ã`<Œ‡y˜ÿº…†%`~i–‘dÕN•ézÍùAÐ-—©Ø6¶®3^­H²Œf©ÄÙé>;І]²ùüÍý›O:\ÀB²ÜlX…!µíJ×4QT…'§x–EµX¤[.c•,ªŽÃ^­J­Xäf6ã¤Õ¤î•ØoÖ¹žLèOg4+eÛfx=Â);(’D³TÂ1 N;-LS§{Ò!ŽbÒ,ã 'šÈJ–ÅÓƒ«u€T( Ê2q’`˜:önÝÆÒÄŠ[ºkàr,“úÇ¿Ëá~›$Ë ½få|E½Xdîû¤Y†kš¨ºÊû?zÊÌYMSitjÄ»*à£ã.^©ˆ,I¬çkÜšK–»W-qýÅ5ZY’ P ‰$Yââ¥K†~(îG½D½W§Ü(c-Æ×cÚMº':§æÃùîäMäe4Ea1°Ã(Œò@ºa4öye¯ª«ŒK* øˆƒ'¹«Ò{Ü# "¦ý)vÉæý¿÷.nE¬ÓÝŸë–ŽfhyCÖl8£T¹¢$NrÇ¥sÒA5TšBðÕ{un^Þà/| ±RW" Þ«‹ßÍP‘ †mPiWØf[ÊM!f* §œòô÷ŸòÑ?ýˆÕLì+­ ý7}¢MÄÉó4]£±ß Ú®²ž­EÆH«cª.ƒíV4¨­g\Z âùÜåeÏ¡T/±eËb(ê¤%IÊ[ØâMœD›·ærúáiN¹OâÝ q…Ýó|þácÒ$¥ÒÀÈÆXïÚî¸CŠªäby›m)U+4›dYF¥SaÔ¿EѲ4Í38•Z“‚Tàɇ? Ë2²,ãøüº%ù¶ë°XLvõÔ Õj‡ÍzÃã<Ç0-ŽžœåÐÂ|ð8;û$ëkY–bÛ.nµ„nêôŽÎPéH‡Vë˜~ÿÀÞá®[¥\m¦1Íæi“e)šfàû §Ìfã婢S`K©Tò\¶[±V¦i&¦éäÙEÑ(`oïÓiÇSyŒ¦™DÑ×­âûKâxÃz-þ&ÎÏ„¦™t:'<Ã4‹èºE¯÷Û.ÑhÐj³Ùø8N™vûð±mïûgm ÎZ¾éDíaæor<}ßcéÛ˜ß&$¾éÿ¿I$|Û1ýu¶ÇÃ1ÿ0óÛsÁâú_ÿ­ÃçÇ=‘#É2.ÇcʶÍh!˜žëP4 › ¶®£+ Q’  ,7Ã`îûÔj¬6’,ãf4á¸Ý$ØÚÛžÇ_¾yÃa½N’¦ÔŠEÒ,c¸\b¨*A1\.y¯×ãÏ_¼Â±MЦ‰¡($Y†"ˬC!vlM£P(°4E¡áºH…~ai²$ñ‹Wo9ÛïÒ*•-—üüË×쉫Öì¾¶W©ä??NS,MC‘e‚(ân<À-ÚÌ+ióÙ?ãôƒS RM×0ƒÁÛi’Š Jú!“Û ‡ïŠò…,í¹DAÄøzLë¨%x1aD÷¬K–fܼ¸¡Ú©¢h ³þ,w¨î+«ûoúùš[½Wg9Yrýå5½Ç=6« ‹É‚$Ô,Ë0lƒ,ɘö§ŽA–f9d³ÿ¦O±"êÁûoúœÿðœ»WwP@¬Ì)beîõÇ_R(HôαŠöoÿ„¿ÿÏþ˜«/®Äº,ÖÎâM,„Ï&á2ÅrÐÅ҃Aÿ’jµÃ|>ÚñEËÝÕ›—ôOñ—>¥z‰ÉݘéôUÕ1Í"Y–1Þ¡(–åpsó’fó XQ¯÷¯qÝ*³ÙBA¸+¦é0^‘$Ñ®mÀf³Þ±XVDQ€e¹L&wìíç5Ìšfr}ýÅn-mˆaؼ}ûɯ}]UÞZæï¢0ùºø¦êÚï'ß%"~Ý×|—£ñíx˜‡ùíž^·Áj³¡lYüìí O¸o.o9=èR¶mnf3Ö› õbQ¬wO»]^ôûXšFɲ¨».Q’Å1¿û茟_^RqÒ,cæûtÊe‚(bÇT‡WÃ!M×åõpH­Xd¯R¡ãyÜÕ«œ·Z||uEÅóâi÷úgiÂé)š&žeáY3ßgÇì•Ë,ËшÎOØÄ17Ó)…B§'È’ÄÅx,®.;WÓ)¦ªrP«1Y­ð£¶[žt:7ÜÍf(²LÕ¶Yn64\—O¯¯9i6 ã˜ëé”f©DuwOš dYf8ó¢ßÇsl‘݉cIb±\3Íùÿð÷øñË—Ô‹E,M£â8âv›†Wb6|[×sm"*•q’Ä ’$Ñj×w ¼/>yÍÙ“Cš®Ëx¹d¼ZQ-¹LûS*¶MÛóxyyƒ¢((E™÷ø”ÉjEšedÛ-õb‘7onÐm¶°˜,q<‘XÏ×ÔZÂ8Î]’ðøé×w#$EmYž#@–†‘¥F Ó°Å4ËÐt§ì I•º—ß–-œ}pÊzéÓhVq<‡«/®„s¡*9ç% B.?»äø½cÖ‹5'Oɶ[âD”h¦F– ÷ë~eŒ;QZÄ NÙa>œã”ÄjY¹)ò.Y–Ñß{?_¹¬Ô›ôo.ñ¼aèï —ºnR©¶™›«W¸n€f{Ÿ4Mòл¢¨ «]C™NµÚáË/ÿ‚,Kpñ½D%±¢h»Ðÿò·ËAùu E'mó×&ß&J¾IXüMŒ÷ãaæïžƒò?ÿ‹ÿr«L«Qån—·ã1«Í† ŠØ«T­VXšÆÜ÷yÒéðùí-µÝj“$Iùù²-ö´úéKþþûÏ$IdW4 ]U ÂUQPe™«ÉMQLfœtZ„I"ëY†¥iÜÎç¼ÓíòŸ..دVI³Œý>¿srBÑ0øÙå%“ÕŠw{=f¾OÕqø²ß§Q,bé:Ž®3D+Ù`±À"LUEWUTYær<&É2j5~~qÉNOøË·o©Ú6évËáÎ ò£ˆþ|NÝu-—Ô‹E¶Û-ÝJ…0IxÙïS(ð,‹¹ïcë:®i2ó}AÀ~µJ¡P Œcâk”m·lâ˜ñJÔ*o·[!p¶[®'^ÜÜ!«2ÍR)w«â4å“7—ì·êL}G×óÇÞÑu6qÌd¾äq¯Ë:MKÊ®aM’$&«ë0¤áºü«óû ¶Ù–?|ï/ú}Ô Æ17³Š$q7!ñ³^‡—7w4ªeü0ij,nÇSžôºÄiÊ&Ž)“õš‹›>ÝVY’ò÷¦?ÿñ/øƒ?øˆÑrÉbíc›/¯Ù;îP¶,.#Q ЩRtU¥V,òÅÛ+‘ñPeÎZ->~}å˜ÌÇ ÛÆ£9Gg=f‹¶m¢+ W—}özM6ÉöżþÙkžþðév‹\( «*o_ߠꪠÉ/DvE·tÜr‘¢i2[¯q ƒ·/¯iî7ðWA~›$JU™ùpNµSe¿Y§?Ÿsóê¯é1½ŠŒ‡¦à–‹\~q•.¢ÅËŸ¿¦}Òf5]1¼æAyIÔ}åó駬g ©™7/nð^.Ôîó>þÂçüÃs>ù÷ŸPí q·Yoðšš¡1ÌÐ-=wKš‡MÖó5iœ²ÝnÙ{´ÇÇò±øÞ®Í럿fïÑ×_^cØÆN°.p+.Š®PëÔ˜ gÄaŒã9¼ýä-Óº©⺞¯©vª"_dhŒ®GÂÍZy{›[u™¦H’`Õöj|þ“Ï)7Ë(º"ŠâÓ1YN—¢}ïù Óþ”ådIû¸ H¢DT`“»qj¬íÕH¢„iJA­i«éŠ0ôiíw\Ý¡ŒÚØo0¾S¬yñóOó bÁ£iñúõÏÑ4ƒÏ?ÿÉo—@ùu¢åá¤ïï®ãñuwãÛ„ë·Ýö»\’o:Þ޵‡y˜‡ù«¼Gý/ÿûÿ…¢*ôZôªUÖaHše¼ø½ÓS4EáË»; U¥Z,RFË%¦¦1Y¯Y‡!õb‘f©Ä_¾¤dšì×j(’„­ëÜÌf€¥)¶®ciSßÇ5 ¾¸»Ã1 U%Ûn¹y¾¿Ï<˜ù>Ûm!Pžu»¨²Ì|ýš0ŽIÒMQxÚíò“/ix%kµüãã݉ù"h{UÇ‚JU‘ îæóÜáˆÓ”Šm³LMãQ»ÍÕdÂ~µÊËÁ º¢PÛ9›8æj:¥[.óz8¤lÛ¼»·Ç¿ýì3ŽêuÒ,#ˆ"$IBÞ9!že±tEÉÿ­«*i–ñz8¤bÛÂQ‰"®§Sžv»\O§lb‘§iº.“ Õ*eÛæg——°Ý¢È2¶®“¤)G\ýOÒ” Šˆv÷-É2Áë(c$Š.œ·ZH…ŸßÞâF^\0™/y~rÄ›áGí6ãÕŠn¹œ¯òÅiŠkÜÍÅŽ¿¥ë4]7_Ç3T•åfCŶ¹Ø­²íW«ŒV+Ö;!¬È2[à`wü Žêu^ôû¸¦ÉË~Ÿv¹Ìp±@–$6qL¯R!Û½?þ§×o¨–\:žÇÍt …Ï÷÷1U•ùgÁa«Át½ÆPU:å2ƒÅ‚¹ïÓ-—ñ, E–©‹8†ÁË~ŸËÉD¸=Š(k°w"°h4K%þ˪Êx8ãp¿M05ÁbÁ»½ד ®iÒŸÏùðèU–ù³×¯¹ìùg}ÀÿñïB³YåÅ'oxÿƒÇ$»ŸåY?ùøsþáówøäúšn¹Ìÿû'É{ï?âq»Í¿þé/xzØ?{µB‘eáä Ç‹t»å´ÑÀÖu>¾¾ù.Çáå`ÀõÛ;ÎÏ0T•W7wH’„môªU^ôûüðø˜EðÉÅqG1OÏ,|ppÀÿùÿü)ð»ÏùWÿæ'xu''ûÜÎç”L“4ËxýúÍnØï<{ÄõT¬I~öÉ+û >ýŸòþñˆ’„û/ÿ=ÕÿŸ½÷Z’$MÏôžpíá¡#2RVféV#0 ‹fX£qy¸Â{à ðhÆ› í¸$Ͱ ÄÈžž¥«Rg†–®µóàŠÅ6[bg€ž¿'Õe™Yé‘‘íÿ÷ú÷Šƒ.¾×ñ™ÞLyçûxÐïóÿ§_Óì7ytrÄĶ©mËbéy¬–6­vƒn­ÆÅ`ÌðlÈÁ!ã{ÿñ]ž¾<§Öém½~›—¿{CµQ%Žbºû]м`w·ƒ†È’„¹ñœ­—²*ÓjÔ*ƒ©Øê¤¿ù¿~Ãþƒ}æ·sþ×ÿåþÊûji’/ñ?¸¿IoÇ‘Ž/Û€ü]RòeºŸo6ÿ²À/#!%9)Q¢ÄWÝÓ¾(Ï]º¢É;MYz–®ã„!?>9ÙâMM#Ísâ4e$Y†E„OÅÛ¿ëŠÂÝ4Yf¼^s9›¡ÇÒù IDATqÐjÑ0MZ–Å^³‰T©p:™0Y¯ ’„ùø1»›§÷Išòr9Ÿ³î÷û›ÍG’eøqÌédÂ;{{<ÚÝ¥[«±ßj‰Á³ÓÞ0d´^Ó¶,Þ?<ä¨Ó¡mYxQÄÙtÊpµâåpÈNNØo6ùé½{Üï÷‰³LÄ7[ŸL¥Rá¸Û%/ íîR©TþkrY–¡Ê2Š$ñÏ< _¯& û­½z€u Ê2í6ï2±ííÏ­mYH• kßgíû\Ïç¼{ úê¦É~«ÅÚ÷‰’„ÝfSøW‚€û;;ÔME’ÈòœN­FÇ4«Õ-±{Kø U¥Y­’e"åÉ‹"Ú–ÅÂuùàèˆ{;;bë"Ë4L“{;;œôzüÛ?ÿ)~±Ûl²S¯oƒ>¹ºB‘eâ4›—4å¤×ÛúŠfŽƒ·ÙÀéªÊ½Z–EÝ4i[qšrØa ?»ŸÇûûhŠ(ÃÜ©×iš&I–Q7„Ùû݃Ô͵ªŠ¡ªxQÄA»ÍN½ÎÃý=ÞÛßg§^烣#Ûm,]glÛ<:ÜçþÎ?¹w£Hª,óƒãc:µÍj©RAÙÄäºQÄOïÝcf;ôj5TYæþæçÓ¬V·‰s½z?{÷+ÏÃÝl­j†A¾!Wó9÷öDàBQå¹Jå9ŽÐ…Ÿüô}‚8ÆPU,M#Œcß="Ës! þÇ¿üI–!I­V¶e±DÈÃN‡ãn—»{}n/GÄq²%wº]ü8]E–Åñ½±ÉŒcœ…ÃÜã°ÓÁÔ4Nz=‘€äyÎÑþÇwö07~.MQØ¿»'RïŽû(º‚¡iD‘(š¬ Rý4S#ò"Ѥ(H"Ü;ìA!âÃuE¡f¼ÿ/Þç{?yGx¯²Œ½»{Ô CÓD¡¥®áEQÅ UM£fYA³ZÝÎ;’,¡šðÃHâ¿ãHÄv·,‹j£*z’ŒÿZ¶¨* sãqSU*€j¨T-U–©êúÆ«ª¦Ÿ$!+ò×ßkË J‰¿ÏFãÛ¾wßdkñU&ó¯ós|¤D‰%þÐgÔÿöïþ=’,ñÓï½ÃÜq(Š?Žy÷à€ª¦ñb0àN·Ë/ž¼à{ï% ú}~{qÁa§#ãÍváÝý}Â4%Jœ0ä Õbåû\ÌfÜ &üøÝ‡$iÊn³)6 • ýf“…ë¢+ QšRN0u~x|Ìzþœ¿xøÿü但ªn= Q’°ò}v›M~wyÉ¿|ôˆÁjEœ¦XºNÛ²H³ŒW£ÍjMQXyÍj•Ýf“$ËXzãõšŸÝ»ÇoÎÏ9l·9îvùèò’û;;Û.;Ð……çq³XðÎþ>ª,‹”°^?%ˆÍðôvsñr8äƒÃCtEaå |’‰.“ãn—Ëù;¶²´9LÄàT©&‹¢HR¥ÂÜu9›Nù×ï¾ËÇWWôj5ÚmžÞÞ²×lâEŠ,3Z¯ùéÝ»øqÌÙdÂn³ÉpµÚJ½:µyQç9²$Ñ0Mœ0DWÖA°•­|Ÿãn—•ïoåuß;:àåpȃ~Ÿ,ÏYnBžÜÜpÔn3w]æ®ËOîÞÝn¬^F˜šÆÙdÂ?ôˆ7£ZÁr‰¥ëu:¬ƒ€×£½z?ŠØo·‰7¿Sãõšóôö–ŽeQ3 ^F´Û䛨çn­ÆËáŽe¡oˆLUÓ8L05 u³iZ£Á”Ç÷ïB;œñgï>`lÛâwE–¹Y.Ñ6á ÞJDQ+šÂn¯M$ìÔë\Ïç4L“³××XM‹;}ü8æú|ÀñýCÒ,Û†0¨²ÌÊr²<Ïét›¤yŽï–!ºi: Ö¶Kä‹Az=¥Ö®Ñé·œ ¼€Ý“]–£%ã‹1?ù7?æÍǧÔÚ5¦WSAª†ðõËñ’ÃG‡PAøšš¢(³{Ðåòé%Gï1¹œ`µ,:{æƒ9ã‹1í½6«ÉŠî(K]ÏÖȲÌýÞçù/Ÿóî_¼ËÅ“ LËdv;#K3zG=U©pº*Ê-UÞ|ô†f¯I­]Ã]‰n•ŠTA’$â0æêù÷¾«iqñä‚{ß¿ÇÓ¿}*b›©ÂìzFA±ý{à(ª"ÒÐzMÛŠ”½ÉÕDÄf›‹Á‚$Ž‘e8Ðè5¸|qÎÑÃcFC4]Ç^¢(óù-{{÷™Í®étöIÓß_cÛ3ÎÎ>e>”¥Äï÷}ø²ܯ"&_çù¢Ïû2IÖ7ý=(ÉI‰%þ!ïÿû_ý?ü³ï¿ËóÁ€»½iž£+ Š,“f¦¦q9›qog‡n­F”¦,\—ëÅ‚ÝFƒã^©m3w]Ú–0†+²LM×1T•ÏÏùáñ1I–!W*Œm[ø1ò; éZ¦¦Ñ0Mì À Có›eì5Lgqüv•$‰É&ëíSQ' ±ƒ€(I¸·³ƒ®ªäyÎËшý>a’PÏþíÌíbÁ:xzsÃÿôýï% 3×¥WQÀƒå’û;"©ëÁî./‡Câ4¥ªiäE¦(¢´²Zå“««­ß¦²Ù€T*~{~οzü˜ëÅ‚¦i¢* sÇ!+ Nº]^ ‡ªŠ²‘.ÝÛÙá—§§¼p@VLl›~£A–e\Îç¼»¿Ïx#Qªé:ÍjUYæl2A–$îözüîò’‡»»üæÕìq°! +ßGÛøZvêu!MZ¯·[Ï®¯Qd™å["×hàn†ü±m“eÇ›'îçÓ)ª,“+×£jèb[Ôj1÷<>ûä|ÿ!+ß§Y­2Í8ØëáGÑöýlY77cú{]Ö¶K§Yg:[m»?ê†A° X,ÖUƒª![U×¹¸‘g9²"xp~5@7uuÑ)n¶‘±{Üg>\Jó£½Ë³çÈŠÌß{À“7<<9äb0& "º»®_ßPo×ñÖÞ6!̬™N@E®PïÔ±§6¾ëÓ芤.EU¨µkÌngìÝÛãÿîüà_ÿ€Z«Æb´À° ƒƒÎÜÁ¨ÌnfyAµ!ÊGg#öì E³ŸéÍUSQ4-Éöܦ{Ðe=]#«¢—EÑ„‘ݨ¼øÕ üèiœ²ž­itä›8ñÙí ES0k&²,cÏmÜ•+ºVü³f2¹œÐ=èRP IöÌ&ßȺþè!/~õ‚f¿‰$‹œ8ˆimòLH }[øÖvîìpýâZx~º ѱc¨Èм±^Œæ¬Vv÷Ù=Ùer5A’%–³)»‡‡8K‡Õj"Š{;tº|ò‹_ÓíîÇ!yžcšµmŸK8†E{§‡³\Ƕ=ÑÊ¡G­ÖÆói6{ÄqÈx|i60Œ*/_þ†årD’D_y_-%^%þ$ð›ûŸßr|S)×I°¾ -{?J”(ñ]Džå\Íç„~H§V£µÙ:È’„,I8a(Œ´•J…‰m³ô<4E¡¦ë¼¿ñ…héFÇ´7r¢O®®P$‰^½Ž®(T5 u³)¹³‘ÿ´-‹ Ix1òôö–ËÙŒÝfE–Ùk6 ’„ºi`éú6š8Ësꆩib3¸aHs#Q:ŸN·þ7 ·}–çô žÝÞr6Òo404©ãàÇ1ë `°\n6˜“Ä ª¡ºbð§öÜ`x>d=[ã¯}м`1\ ê*QmIÌb´`=Y3º¾A’%>ûùÇÈŠL%œ=y-¶-AÌäjŒQ5˜ &,Cv÷Žñ]ñ~yŽÍåÙsL³†ïø›(`JEb>óìÃéõ‰¢€gÏ~NšÆ\]=„ÊžÇ!¾o3¼¾d:½f½žà8 |ßf¹±X ˆ"YVpÝ××/°¬iqsó’ÕjLšÆ_{?ý£"(_Ö-QâÛ‘/*üüß?ßfþM·_¶íú¢mÈWµš[ÏH‰%JücC35,]çÁá>Oon0U•(Ix{W¼Óél=×óùÖß‘l6+o%RoãƒûÇ!ؘºÓ<ß>ῚÏÑ]Qx9 b#Ët,‹G»»4M“,—LlÑRß0M*ÀÅlÆ:è7›ì5›´ªUzµýñghŠÂÒóxgc¨¿šÏÙÛ¤` W+¾çŽ )AÀh½Þú4Yær6ÆÛM\q¿^ÇPU.f3Š¢`åûD›Xe?ŽIóœ  ~#oš;Ïno·[Ÿ†i2±mê†A”$¼p‚€ºi²Ö©—¹ÙÄ\ÍçÔM“ša°»Óaåû¸›Ä¬ƒV / 9ŸNÑU•'77¬ƒ€n½N«Z¥_¯“æ9§“ ãQýv±ÀTU~ûâ ƒÙ‚O..Y—Ó²$‘Š$ñæü†n½N¿Ñ`6Yú!;wvHóIg_«×d´\qýòרT*¢>I¸N¨µjDI"ŒõNÀðlH£Uãâb€j¨aÄjºÚƧIŠnê O‡L®'ÄaŒçdIÆp2çÙ§oðÝ€ç¿xN’¤„^(:Is7 Ïs¢ žÛL§Kм b²4£{ÐÅžÛbÀ^¹,G¢¤Ö®b°®PAVe¬–èO4¾.ª·$%J”ø§g!|'qšòã»wE÷C³‰,Ë̇³É„~£[c´®(ÛMG^Ì\1ÐYºŽ,IT5{;;ŒÎFhŠ‚Eü§gωӔùÆoÄñ¶¿äÃósœ0äf±€¢ füäî]¼(b¼^SÀv®YQ0\­x=£WEän¶‰ïM²Œ$˶$J‘e¦¶³ép¹·³ÃédBQ,<‡»»üù{ùÍÙÝZ±m#m¢ƒ?9»`áº[ÏÌÊ÷™Ø6qš2µí­JS U¥ašøQÄëш4ËøÏŸ“æ9Ó•M”¦¼ ·­óiž‹mÐ&E+ØD‡qÌÅdÊÒŽW£ÑÖ5›x¢¯æõh„ÇäÀÅtÊb.¾ö-ñy5¡™†):9¢$OåuOž¼¨NÉb…$IŒÎGÛ¡t°\ò«¿ú53ÇÁ]{X¦A–d[)NÕЙ9õ†…·ö8½póæ–,ÍDQ¢$±¯ €,Ͱšö̺Êí«[м ܇Í;x3 c'ࣿþ/~õ‚þIŸóÏÎIã”ë×T*Ü¥K%ŒÎF Þ H¢dKXZý²"söÉq(ÈÄÛ"GY‘YŽ– N…,ò#Ñç"U6mêbƒ±-YO×¼þík|ÛçêÙÞÚì™,F‚ÐT¤ º©sïû÷¸yu³%OóÁœë—×Ô;u££ó‘„¹lg‹(1ºo=)ª®RP0x3àì“3¤M\³¬Èô…¿C5„l1ôB¢ "b~õþ‚¢(ÄkH3B/d|9Þv¼-Òœ振FÄ‘Œ|ïg?Æ~]£ÒG5Tê:Ë[$Eb|>ư TCE’%ZýA ¶9ëõ US¹}sM%¼úø9öB—jšÉé³çH’Œ$ ²…÷}ϱé =*a>_¯f@…ép€»Ä" ]  ÝÞCU jµ/ŸˆïÛD‘Gš&T« ªÕ:ªª±Z)ŠŒáðYVȲ„ÓÓ‰"Ÿùü–$².U5X.GD‘h®wœ%iÇ!Ãáٖ̈î‹Ùìfs­_ÿà»$(ßáMÇ7ùøçÉÁÉ®>O@¾Œ\|~«ñmLæß–|”d¥D‰jÐM}›,åEÑ6™ªU­òÎÞž0šç9s×e§^§¾‰¡íÕëLl›©ãàE Ï£išÂ£±IÁù7ù3Ò,#NS~xrLÛ²ˆ’„¶e±ÛOfuUݦuÝÛÙaáy(’ÄÍrɛۡ`©*ǽYž³ö}>½ºÚáÿ‡÷ߨþÛvЪViV«\Îf¢Ã%ˆ6 d“W&ËsÚmn ü("ˆcÒ,£mY|ruEtZ j†ÁÌqxvs‹†äE!¼Ó)÷û}Iâ“Ë«mšÙ›ó¼(âb6£cYL_šfÙ–ö n &¶M·VÃctU©…ðdiÆÝ^OHæ,‹óÑ„0ˆÈ6ä+Lnç †Ë%q‹Áy¾ÑÂQŒgû⩼º¡H!’$ñÒc“ŠT³L>~òš£wHâ³f Oáh‰÷lOªnC(áôÙ·o8¶GDȪŒ^Õéîw8|tˆíx½sD§Ìs–£åÖÐì,Úûm1h§9gŸžaÏmŒš!®S–höšèUwéÒè6¶ço«ß¢Ö®±š¬°ZnƒÀ ˜\N¨Ö«äYÎj¼Íåíšh77uÑsDäY¾ÝšN€Y3‰ƒx»1 ì€ñù˜Z»†³½©‚fjø¶Oè…T¤Ê¶¤°Z¯²/Iâ„Ð Qu•áÙYfòùí\ünî¶Eb1»™Ñê·¶Ýo~ƒ×ƒmÁ¤$K‚4-l"?¢Ú¨².ˆÃXȦ ðVž/-lªµŠªà;>ÎÜ!cÒ$e1\PkÕðVƒ7Ö‹%íÝ7¯„¡ÿìÓS$Y拾.XMVŒ¯†xÞšÁå%ÎJ\Ã[IVÅÛa¾ÓÛe5_¦)Aà$!Q䇒$3Ÿß’¦"f[’%ò\l–Žžp{vEzø¾ÍÙë'(ŠÊz=EQ4F£sTU'Š|f³â8À4kL&WìïßCU5Š^¿þ8QõzÆÞÞ=šÍE!Mc,«µÙž$¤iÊb1" =F£3ÂÐ'IbööîEPAÓL‚Àa<¾ ŽC*Ðõ*Ëå˜F£û§½Aù¦¤/úØ×}Ý·•‘}•ã¿çc_ôñ/Ú||U—Ç—‘ÿžÆò¯“]•ä£D‰ÿQk‰Fí¼(¸^,H³LÈqòœO6MðŸ^_S3 wZ©ð£“â4%ËsŠ¢ÀÝt È’„ÇT€›Å‚fµJ²!(Éfø7I]iž& ÃÕJ„8Æ‹c:µ]^bû>?~xŸóé”<Ï1T•›Û ^Q7M¦Žƒ½‰ð}5ñ«7o¶Ò®×ÃKÏcéy<¹¹A“ez›(^SUÙoµXzÞVvu:™-þ&ê×PÕ­ÿc·Ù¤Y­ò³÷ÙÝø:*ÀÂó8›Løøò’“qš s|§N§VcµrLæ ®Çv:ØAÀàÍ€,Ï·gÝÛä¬O>{Íl¶äùÕ ÷ïìcjfÕ ÞÈèNo†Øsgá ‹±è—pW.ó¥^ÕQ™ƒý>ûÍ |Û§"W¼0:ÅÏ/YŒ—hŠBD,l‡Ù|…"ËL®&økŸÁëÁÖ³PkÕ„qZIeo‹5CCÓ5Š¢ ôBò,ÇY8¤QJÆ<ù›'<ýÛ§8 ‡Û7·DA„Y7YÏÖŒ/ƸKQBX©THâ„V¿…$Kn°5RW›Õmt¬=·YŒ覾}ê/I•J{f“Æ)zUÇ[‹!¼"U„);ɰ6—Ï.ñ×>ã‹1i’n[ÙÇ—cÜ•(JLã”4NIâ„;ïÞáõ‡¯9ýøtKªT]lMav3Ãw|êºØ>æÎÜ DžäG£íu–Á›ß¾¡wØãŇŸmÓ¶f7"ùª(„<-Ïs^þæ†e ›:çŸQ©Twé’ç¹Ã­{f£š +²J­Ù`:¾Å0«´ºŠò<Ã4뜞~Â|>`o‘& çã8K®¯^òò“O CI’év8:zLš&ÌçÒ4¡^ï†.q¡i®»D׫ÄqÄlvËt*6jëõ”(òqÝ%AàòìÙÏ ÙìÓ¬£(Y–R¯· C—ƒƒ‡„¡Ï|>@×M$IAÓ dYF×MtÝĶgÌf7ŒFø¾C½Þa8<ûF÷Ó?:‚òwò/kÿ¢Aþ›ôq|DêÛl6>O ¾Žˆ|^^õE’«o*ú¢mÉß—L”d£D‰%¾†gC"?¢]­ŠôªM?Gœ¦t,K­7>”‰m³Øô>Xº¾mNÿÑÉ µMébžçLl›ª®3µmì àöv‚†\/´ªU®Kœ¦\Íç4M“ºandLY–±ßl²ßj¥)3ÇA‘etE¡Ók2Z¯9j··qŸ^_ó/=âáî.Š,¦)º¦§)÷vv°tMQ¨›& ×åf¹DßÈÎÒ͵¾í,9îvIóÛñyðF«Q’ðñՃͿ°tša`ê: ×E–$žGËÉQ;Ý­Vî^‡™ãP3 Ð0M.6&öájÅxµæÁ£;[ïÂÅ`ÌÚvQ7ñ¶Yž“g‚j††eXM‹åt#¥14Ü¥Ëj¶f¿EQ4f³[OV¾Œˆ|øüÇ˰€%J”øî¡Ú¨¢ê*uÓ¤WFâñzÍÊ÷)€$Ë0]U©nJ“,ã°ÝÞ6`V+j†Áq·K”¦|pxÈÜuÑ…ázÍß}@UÓxÿàkÓ; H6åˆÖ&ŽxTu‘>t³\²p]Ž{=–žÇÕ|.Zè7š¢m$SWó9n±ö}æŽC¥RÙ&ŠyQÄQ§#†Ý  ¹ÙZ Kœ àl4e‰s›_žâúb°íÕë´j׳¹ˆSn6q–.gWjBõVö6Ïy92±í­”ëíºS¯“o¶LŠ"ã„!^ úFÂ$¡[¯Ño6ɳœn·)v]ÛúSV¶K‘˜u“ýƒ&£9©²%5Ó@Ñ4C#MR ËÀö}¬¦…·òèî´˜\Mèîw±¡ÒÞksúñ)ÎÂáλwˆ|a8/Š‚á›!¹‚Õ°(6¦v€Éå„Ý“]<×'SdE¦È È¡ÒßnBмØzò,Ç]¸ìÞÝ×5³)òB˜µ£wdyŒÕÜIDATŽðVqS‘*[iRäG(ª‚$I¢d¿ƒoû<8 ½Ûf>˜#+2“ËÉ6•Ê[{Û¨Zo剈ߛ²"cÔ a&We:ýøÑvûú!­~‹÷þù{EÁ‹_¾Ø^O–d¨B&+2EQ9Y³J­UÛ¦…Õ;uB/Ĩìá,Æ—cÒ8Ýn3>þ±s´ÃðlÈàü½ª‹ÍI–“Æâúm{Nè…XM ESðlÐ ñ]‘幪®â.]AøªU’Xt›TUzG=½U«!Hm^lÁм`gï€óÏÄû¾-E/H£‹¢)TU‚À¥Ýë!)­VŸ<ÏýP„"¾ðmMǾKEÜ9y‡,Íh¶zXV‹<Ïh6û¤iÂÁÁ#E¥Vk.Aࢪ:išlˆ´•]-çSŠdYa½žm6%’$£i¦Y§Û=`½žmäX­Öûûe•n÷<Ï—½½{[¢1Ÿß2Ÿ¸ºzNQä¤iL–¥èºÉ½{?@U54Í Š* ßÿ¤iŒ¦èºI–‰¨äjµñ§KP¾lˆÿ²ÿï+gúºöòϧP}Yá·ÙZü÷|n¹ý(Q¢D‰b¹v¶r+³n2¿s}: È N>8ax3!‰Ò$E’%z{f73š½&Ó›)O.$i#Ý‘éÝéQ­‹ÁwûÐ4/6Ò  ÎÜA35–cá+yýÑk$Y"‰Äç+š( Ü€$JðÖ«é o-6:ÎÂ!K3®_\SäîÒÅžÙÌoæÔZ5z‡=Ü•+6{AD‘D^„fj[É’Õ´ðmŸ,ÍèìwXWÛØ[ÍÔXO×T*Fç#¦7S^üò¾ë£ê*gŸá;¾ð¬ä9²,RºÆçcÖÓ5Ц h¢l0MR²4Ã[y¬gkŒš^ÕÑtîaUWqfÝŸg{¬§kݲ"úHôªN§<üÑc’8Db¿O‘„~Hs§¹%Rº^ݦ• /n8z|´%R«É «VR¸Tlˆ–ó Y’m8_ŒI¢„Õr²d¾~sÎär²1¡ƒnšdYŠª«èUÓ "Ì Ùî IýÕz•,Kiõ[øŽG–%Ò lç´Àó˜Ï†Da€aXäyFù[YÖ|>@QÄ6Æ÷m..>CÓŒ-™xöìç"Ú™3›Ý0žS9³™ˆ?ÎÉ2‘Âõòå¯ÙßÀtzƒ¦™\]=ÇóÖEÎz=£Zm$•ŠD É aXœœ|@¤iL»½Ëj5A–ž?ÿ%Y–’¦­VŸ8ŽÏ(Š]7IS:±Z‰HâRåÛ’™/’R}Ùø¶&ñ/ŠÏ-}%J”(ñ§À±·iž% çÓ)—ó9@–$Yæ~¿O^ïîðÁá¡èùPU–¾è·XxžhGÑ£²i'W6f{SÓ°ƒ©RáñÑ¿}öZ´sGÙ&µ Àñ|ö[­íæC•e® ®»%>`( Û)JªØþtk5#&›.@ ÖšˆQnU«L7R+SÓÐ…w>¸/šÓç6Ožbi†ªòÞÉ“õšºaà†!í Ó±£cÛ¦V¯nÏ`]U‰Ò' ùìù)R¥B£U§Z¯"UDBÔè|„Õ²¶1nCø34 ³frçÝ;\ßN8¸¿üøÏ?à³ç§ÌoçÔ:5vö»<{qÎzº¦ßjb5-æƒ9i"†M³n2»™m øZmá‘ÝÞa(ˆXŽ–¢ÙÜ2¸û½»ÔÛua~Ï2î}ÿ¯?z¢*D~ÄärB½Sg5ò¦ÙíŒéfγ\´œßLÙ»·Çz¶Æ]¹‚|$³Û£óI,$E*\>½$b¨@žç´v[nÀÎñÞÚãàÑlŸøËŠ(©ººM¸R4…åxIÆ–!¶'qJš¤ô{[R°sg‡åh‰¦kôÅV¡B…f¯Éã?Ìb¸ ð‚m_Çøb¼Ý"è¦Î§¿ú5õNþqëßH¢„ÕxE–Š×'IFÍØ’‡$N¶$„·KÑáïÊrÜ¥Kk§…Q5ع³CžçäY†Y7qì“á ­n‡8%­n—ñå€<¯½šáÙ«éÓ21Íãëóál»mZ ÔjmÎÞ|F'´»;H²Äþñ1ží‡Y–â».gÏ_ÐîwðÖ篟c¯¼yù —/N ý—/ͳßý–,¾”ƒƒ‡t÷útû}\Wü^ƒYµϘÍDRVùèz•jµ‰Q­nfÇb»¥0 ‹ pùÞ÷þÕfK‘E>²,Ólöi6ûL§×hš$É,—#êõE‘³³s‡Z­…ï;èºAQä‹mϨT*ôzG4]êõ²,cE‘cÕíÃû$‰ˆãˆZ­ªêÇx|A¯w@–¥T« Ò4f½ž²XˆÀ€oüÀ§º¼$J®çsò¢MíA€®(<q6僽zKÓ„ÃuE³ºiòïÿÃ/¹šÏ¹Y.iU«DIÂÙ¦yü_ýÙ´-‹ša l’¥^F4¬*kßG–¤m³¹ª(I£Ý]Ûmœ0$JSvêuôªÎ«ÁƒV‹fµÊ{ïßg¯Ñ ái7é7¨›xä£N‡ÑzÍÍdÆp±DÙ˜­«ª(³K„œCWU¨Tˆ7Š,s=š¥)Š¢ðê³S|?¤ W+^ÜÜ’$)“Ñœ‡î * qœ0»Ñ¶,ò,G¯êP ┯FT¤ †e°\Úè–.Ö<ÇY»âx¥Â½{‡Üûà.š¡±ZØ4º î<:$LÞüîͶ{"ã­\èíP}s>D34¨ˆ³WÕTöîíá9>yžo[Ћ¼¤$ˆ$‰Áé`KzV“µVñ嘃‡$Q‚Q3XOÖ„nH³×ÜšºwOv)òBÄüÊ2Gˆƒ˜z§Žïøh†}¥QJè ¿H§˜–¹–U!£ò×>fÍÜn.â0ÄE’èìuXOÖ¤IÊÅ“ T]åðñ!ͦèd „Q=MRvNv¶ªÀ ðÖ£ó‘ø^Ìþƒ}*R³nâÛ>Qñgÿâ/„Ñ=IÑ A [;-œ¥C÷ + &og‚ð%BÆ¥¨ ýã>õvgé +2µVÀ0ë&’$‘ç9µNåh‰·òxøãGPÀÁÝ;ô÷¨T* o/ÈsѼ®(Ê&ý*Ç]¹XVI’iítp׊¢Qo¶P5M˜ÞÃdc†Oéõ1k‚,)ªÂl8ÞÄ ë4»mò<§ÙÜáw¿þ/è¦N¯wH­Ñ¢×;¢Zmà¹k~ðƒ¿dgç——ÏX,†ÜœŸ )¡a¡j:ñ=‡ƒƒ‡T«u:}Š¢ ÓÙ#^¿üIÚl‡Bñ»Ýhôh4ºÄqˆ$)Äqˆe5I’ˆF£CµZ§ÑèÒnïáû’¤Ðéì£(«ÕdÓ_ Ë*¶=Ã4ëäy&VI€ç­¶é^AàP©È@…ëëT*³Ù5®»Ä0,LÓÂqL&×[9ZúT*­Ö.šf”¥øK”(Q¢Ä?ô92˜Î14™ãl;OÞJ­ìîÒ¬V©YžãDûÍ&5Ã`¯Ñà¤×ã|:ÅÒuÒ<ÇE¬èôýzkÓxÂÛ²ßj§)+ßG‘$‚8æãËK~trÂ^³ÉÂó8îv‘*•mÓú^³É‹áPlf*•­÷¥nšÔLƒ—Ã!R¥²mž·ƒsÛëÇ1£ù’ñzÍĶ‘%‰FÝ¢jâ{\ éÔk´51æ93ÇdhCȲ<§V?ƒf«ÆÉ»Ç(ªÂó‹k MѩݎhÌ–ó5yž³{²+b…zH’„»rYo<%³›ÙV¥¨ Šª`ÖL’(AªT¸ÌXn¢›«*‹Ñ‚«W,¦+¦³%݃.(ŠBüš‚fjÜ9ÚŨÛNY–q®ˆÝ$IÄøfY&âoGK' E¼­¦ )•¢*XM ³fRk×¶Fý4N‘5a$_Ž—Ûž‘8Šiô¬§kò"gÿÁ>zUÇw„DϨŒ/Ŧ¢³'À²„Üs<¾àüüSâ8@–ŽŽãº+¢(À¶"ˆ Ë8?ÿ”4°¬ü8?ÿ EQIÓ„‹‹'¼yóIÑnï2™\Ç!yž1Ÿ˜Ín0Í–ÕBÓ ÂP4Å;Îß·ÙÛ»‡mÏñ}UäGUuNO?FQT\w…ã,$ùCPþ>ñ»¥™»D‰%JüCàÛž9¿ï3êm_ÂËá0%{û­÷û}œ0$ÏsÆë5Iš¢È2~áÇ1¯F#–¾ÏéD •g“ ÕÍ&eÛ…¬}ŸxóµÚf 3wÅ“ÔzfUèî×A€¼!,Wó9R¥ÂI¯G¯VÃ"Ú–…†¤yNše¬}Ÿ½f7 iYÖ¶Õ^•e–³5YQðúüE’h5j(²LÇÔtº!ÈÉp±äñý;Û®–…ãR3 TEᓳ l?ÀÔutE¡[«ajƦý½iUi6kLGsáINÞ?!IS¬¦%ž¾›Ÿ>?¥h†F³×fåí~‹,¥zš, “ôÜf9ZR©TÝJ¥Âoõ’¡Z³&ZÍeÍÔðmaZ§Â6x|1F7EÄ-°ZÊf_Ž—<ûù3ÒX˜ÑwŽw„ß$/èv1,![ÊRQ X©TDÊVQPïÖI㔽»{$a²5l;KÃ2XWâ‰&žøëU{*Œñí~›ã÷Ž…™?’¬ýûûäyÎr´dr5AV…d5^‘%ÙvûÑê·pP­W)òbûšQOþæ óH [OׂlÌäq“%µV «em·97/oxóÛ7DžxËђ˧—ܼˆéõ”$Jhu;,ÇKêí:£³½õN}+× Ü`kðϳœ“÷OˆCAØÌº)ʃ˜£Ü¥Ëîþ1’,±ž­™]Ïhwû4º ì¹=·‘ßu1kUêí:²"£iææ½WHb!£²š°pŸJEÜj Q²še‚ø¾%¦ocƒeYFQT £ÆÁñ]jµ“›á¦]=c8£Õ ©RáÍxLQH• ù¦A]SÂ8Æcžœ_¢j*I–álúT–ž‡½!2·Ë%~!oZµÂ$ár0æùÕ U]ß+/Ž ’³nâ†" )ØCqŒçdyŽ®(¸~ÀA·CVtëuö[-á3ð}Vž'âl™…íà!+ß'Î2Æ“E^0šÌ©õv{‡{¼|qÁôjŠ¿ö¹|z‰3w°g6Цp{1° |Û§ßkx!­V*ÐÙëà8>îÒ¥"UHc!_Kâ„ÕdEÿ¸/´þN@µQ¥³ßÍà’´•bU¤ öÔ&p’L”)Ö:¢Ð0p$Ib1^’g9íÝ6nƒÎ¾Øb¬&+Fç#²,›ti9^’ç9³›ÙöZܥ˧ÿùSÒ8¥½×fÿÞþ6ò6Ï„D­wØ£ÑipýâšÙÍŒƒ‡t»\>¿$ÏrFç£mécÅ, aÎ?ì‘g9“ˉ ÃûjºBQ…1[7u4SÛvµüÝ×·wo«e‰d± ÿÍŸõNÃG‡¢?… I$¤|ý“¾(§¬›dYFç@¢(hô„^H'tºìžìnehª®’ÆéV¾–¥FÕÀž‹ Îè|´-HœÝÎèﲞ­yõÑsÒ$¥½ÛÆ]¹4z ’HD5³!±«™H(kõ:$QÂøzˆ$KH’$^¿fe)wÝ Ñk…ŠªŠâÆÕ‚«7g4[=’(áÓÿ–áÍ…h_MY-fhºAùPˆ¹RQ•e™““÷iµú´Z},«Ižç¼xú¡Ø†¨ šfnÊcÎÎ>ÙʪšÍi’pÿá÷hµv88xHQ¬×SdY!ŽšÍÒ4a§Äj5¥Zm°^Ïð¼õöÞ–çÂØž¦ yžáykgÉùù§›ù€V«O¥"qyùI’7†ø„ p)ŠU5X­¦ŒÇ„¡0ø{ÞJÄOFÓ¬†¦YÃ÷mƒ7C­Öbg犢¢ëB"W¯w¾ù=½ø“ú7mÿüç~Õו–%J”ønâéAÎ7=sÊ3ªD‰%¾ûçŠòu7â?ôõMþýò€(Q¢D‰ßÕô<£J”(Qâ÷ å’ŒüC0®?4¾Í©¼–òZÊk)¯åùZJüñœQß…ßòÊk(å5ü¾Îé÷ñÍʃ¬D‰%J|QžQ%J”(ñÇåÛ²žoÊÀþ®ñ°4¤—(Q¢D‰?$¾í™SžQ%J”(ñ'@P¾ìþU7öò¦_¢D‰%þ!IJyF•(Q¢Ä?¾UŠ×?ÚE~‡tÙ%J”(ñOâp(ï»åϪD‰%þ‘î•e“|‰%J”(Q¢D‰%¾3( J‰%J”(Q¢D‰%J‚R¢D‰%J”(Q¢D‰ŸÇ…¥D‰%J”(Q¢D‰ÿ4PnPJ”(Q¢D‰%J”(Q”%J”(Q¢D‰%J”øÎ”oÛö[¶—(Q¢Äß¿Í=³¼÷–gT‰%J|×Îé»ò‹¢øoš}ŸŸÿÿµw;ƒ0½ôÿ¹=UBÈ6 1‰ÞœZš%ĘÛÐ-œ."g½hTÔŽx½È¼,¶’C³Àï±OµêíJ5e÷X¬9QÚ+‚ÿyÀ{uòô]¹–‹#®VæX¥®®|0ý;íßú_é$`9oÁGþð´VZ+í{µ€NV?ÚéÛG} ê€åÅ‹÷_ð¯ö³ö½”õýú±îogDÈý³E£5ÎhüJÂà=ïì}­çŠ_ï¹T1Í×È>–Íw&'3þCâ x«Nîäõ,]]Ñ“Qÿ+q:@‚òhÅ'œ³‘zçÿ¼ÊAKT}ûl•"«"±تpµ2Ùmæ¾£yÉ ð­¿³Æ?²w݊άåA»â_žíÕöSxîÅNèäó:™Åë‘.)ºº¢'Ù‰åŽþA-¾,‘ x™xÖõo¯©‹TÝÚöHLµ½:Æ(°õˆzT1ºâ/žÝv°#;(þðÔ‘†jG¤Ô*ã]s½3ó8îE£ÐÉZ:™ÅëYºçõ3»2ãp–®|*ˆâ¸8õ}Ž™ ©‚­¶Þçw}ß#+€ŽtU®U ÈFãñl©¶W Ä2ÖÜ‹À³:°“ VõgÕ.Ñn¼¢옜¥+|åÀ¬Wu̲½ZAôH2Ú^·*=ÑDF…iåh5/½½Úkv=êÍ]ý÷öȧç—j;|R'UÞÑ+ïọ̃믞íÿj;(´6¿Ì 8T”p}è š êßA$'  ~ ®µ"nCßòIEND®B`‚snd-16.1/pix/bessel.png0000644000076400007640000017760011147553266013143 0ustar bilbil‰PNG  IHDR¼¬ï+™ pHYsgŸÒRtIME×1²Ä° IDATxÚì]e@UËÚ~ö¦‘PA@AlÅ»E=vww;°ÅnìîEE$ ¤Kº»aovÎ÷c×Zà¹÷øÝsî•ãzÿì=3kͬ™yÖ¬·æC ÕOb3CÀ^†bÀËC xbÀËC xbˆ/C 1àeˆ/C 1àýŸ@ÀŒÞúIüc'ÔC¼(ü¡^.»,¼ñ 0lC=¥Šä¢j xë(O¬`Ö^¼õŽXH¥ap ƒ¼¤z¶Wß4)J2@`VÞzH\/ Ý„_¼,Vý€§•A¹¯+ 0+o=¤swfO3xÌ¡^Ê,¿èLQ¥º: ÀðjÕÀ9þ ˜•·ÞPÉ*·dFl‘ІÁn½$å_´ß\W|ÅnÓõSGÂЯ ^ ‹Þÿ3ìô0à­wtý®ª§²‘:ƒ¼õDJ©Êþ,Ú„ÅÌ?ÞzBä¹×á+Igæ¾~Ÿ­ü+iÄœÌ'#²e©4î«»Ñ ê-©*ÿRª2%4÷B™û•ÙQS¶&1 `؆zBézk•úÏPt³Y£E¦/ƒ[0`À[/¨W°øÖ }ÐmtgYÄ8 xë±ïŸÕö°z *Þ¦dPŸçóWê¬ïõM¡Ùøàú9>2~£,cVÞŸ–f½uÇ'¥ T|ø Cï?y#C xÿëD‡ µê~üÁpyÐ=;Ó–êF†¶áMVöszyôL{8œßrŸ)ƒfå­'mÖÌIU‰âÒõŸ¾hk1`VÞzCšJ+Eùåm§Û0+o}â‚U §iåtaÀ€·’£#3ù ÛP?){«?1ÝAÞúG‰y®'ËòÕ0à­G$e¥ÅÇ'å3`xÞz÷ºêP; hߘAÞzG–K²+ù:2`À[ÿ¨Ð; 0Šr 9 êáêj””0+ïOOÁ[²ïp£N¹9t¨ëÕ5Ž””0+ïÏO6úGH ÊÑh:DB€_f5šlÏ@‚ï_Mä/q÷Œà¨”xã´o¿¶Ø i—öãÙaÃô¢&ÿï'dü×¶áûô—]o?,¥ ¡¨ ˆö6¿õÂØì6@„ÇÛv윸Ý÷;ë—üÿBLÌÊû7’é¹ 9Ê)öý–=®QS€“‹P.É0çé:[‹H0+ïOIüOóûô¿›Zz>%AŽÕú@³v7ý–m¾hþ€\¡Á@¢þÒö_¨³‘gZï“Ù€¶é…ðã:øz»…½~¨ëI^EøçQ z¶áK•:Y\%Udg®µ#>÷ιãI\~óéÛìx[§Üù5»2`ÀûÓõJ°ƒ‡©¢fa›¶ •Xw9|¤-Ú¶½98d ƒ†çý_ë&¾ÓQ0¤<9..õÄ xVàÓ_b^ MÕ.ïdÎÐfVÞŸ“r•î@Ïó'›«ˆ$nn‡”úmµÒ:fsÞŸ‘bçñJ«ÖèPRzö¥ªFRÐþÚ×v€o—Aì]ú3 `Àû’Ó5¡P˜tu%mƒìc*C¥áy•Æ_kÁ€ ‡:21àý ÉpP³7´6ÍШ‰”Gn¬\®‹dKÀEséuŒÀöóÑû–--L#~¨ëéééÉ•ºVN€Îãç0Çh3àýù¨wHðÝO›@نюͺ<’«'l4³c]€íPr^Èà‚ïOFÂÏáº]Ü$ÿãö4[ä6GÁ+Ex/X¬ËcŽYaÀûÓQüÒùóçï«UµóBN¥@Q64ìJ3É¿.:§Ë`0ÛÏEü¬¨À¤ÉT-[׈}Ê^"/lfW,;@{朥×dÔbýBGž“'o·¬šP] @S À…ŠU,¼ŽA2ù­¬÷3s ÛðS½¨ÆöFFF4 *™mdd$‰-WÍßÈ.Ô[95‹ÞŸŠœËÿ¦-{÷Ø_ú¿šö—êe Áð¼?Åy`; ¥÷V=@PÉf@¡pþ¥Ù’ëò·Lõ8€³òþD¤ß«K÷ž][€ªúþÔ÷Ãs¶jjÄ}>K¯;´¾“n aÀÁ¬¼?#,Ù`lû¹4/±¥: ¤&&b: rÛˆ„ ‡;xÐsƒfåý©d6R5y!(mM©ä ±€']¨¤Ü\£Pâdt׮ȚSC¹Ç …ï‘Äßýî ”­©I1²;¢­öK@p»I¥ÃSD)®û'_†µ`Ø€¿ü-×â”xR½dBRZ€Ãàø.³izúÂ0yâ¤F >þé+¯Hô|ÎÿúÊu«äÆ]:’?»VÓ Q@¯€Že¹(cµe‹¯ Ëï[þýc3ªç+ï_²fþW``ë.¬¨ÛÐ3•ªóÄÀ7®%Ì»hvs@¢ó{`òÁïlBf蟵ò²êÍúS~°çlK›Ú¹Í†ezM YÖ–,S€eÍÔOÌ`ðÁl? ‰| _ò…u$®¬dd—讞!@ý xâ§e½b]Ë£ Š€ »¦")¨¹0lÀhôþ\!?1ýJážØÕwoÖ¼Êд¦³<_••ÍTSø’è9ÚùMX­m@#\ÌÄëýg lõçEíy·Pªíí¨¬Þ¥òÝIâñ5ë[“d%&N eÌ^b†mø)Hµ™“““ƒò@ÀÏâWð{RÇéZgñ Z¹‹£³"ˆ0àý)È»a“æ-G^€Ò«@ÀŽj:z9BA¹*ÀÝA³•ái°œøeÕ*ͼ˜øO x j:³s+Ç‹ äqÒÓhAH¡`+}N™(„½jòÄ µoþšÈ`ä^n}îlµM ¿[óYªÀÒe‹¯GìL]Š#a¢b`ÆqZ bÆ›¡ lõZÀË»’Þj¢¨jL;X&¬ .¬Öxmåî›o>l”n¯Û`ãvò¨N9,Æ üѯ´oÆrˆ¶Å쥄ET4-Ê£3TïˆÚz¹¨YÕ{ÆiTc$½'âø¥ïÔ$bÎncxÞÿ.õ¼ó!ráRP6Ñ Õ-5ˆ×¼hø‰%p4&jx PY;KÛ@vEnÁwjb°û3Ð/u&ŒíY¡5¦;íÅ»ËÎÆbÄC癫ªÆ}1‰W{1¶`þ•/2–½Ýy¯™Ýl?‰Y¿x9oîß<âël  p‡ò‰)AŸ{j߈ÓÃõ¥Nøò¸¢¬ËlUýzZw½Ý¡† Z~2±ë½ö£¹-y·d$xl0uWš!@:¶ÚO³Qïô6’WižœWà§6{oË å§Ô3üR²Àå #.É#ú³ì¾x@uÎøV=]Ï|ý³˜TVfõ__RU2Eú7+€¹ M”´ñž h«üÂVçýòQ|Ñç#p~ {*ƒ¼?Åojˆâ9’mwöÍ…ƒøœ 8­-b?žt0¯`‰}{* x¢£Ç*n,ÖûþF7K‹ž¾>žÝ©DPå7ùÞí}Ú@Gu· Tž÷ç¡î­³M@$¬fÌ\ºðae/Éáô5~Úû§+œ¼!m·¶n–NZ›ÎÞÓVŤO×ß²úè¶r+Îx50+ïOBß,6ž‹Í ‘ÙC—â…Ê@êò¹±‡tÙ ¡hZe@Ë6Xt8ßÚ*å+ƒ¼? åäk~ (h¡ÍÖÄ#6b/Ìñ–¹.î´÷˜k~üÆ…ªwL¸2¼? µ]ôh4Œ7P_ =ˤpSV½ß:KÄlH`Õ«RçåñN±Ï{–„1`axÞŸƒ4ì:OÐëÜ >ÇN4Q«)ËèüíÒÔ6ÒbµF7šuÒºÙW’jåœcëÀ …YyRwÖ`XK¨V­/Þ¼^†Oò ŸÊ 8VÉ,kZÓ†f¥Tü­ÏS¼ÄÎÎÎÎήM4J¼ÿ’õ_C  ÉCó•ošÊ2Y6±u`:l,F¯Ú¸—ÿFmYjüˆË'ã‚zÇÅ…ÙÙµx•É “ï‹2JÊ€°Ý 燔°zâ“´Ôþ Ë0ž£ï/þƒÊ„âÿìaârÜÓž­jÚ¬ÞqqóÏMxóVl9€üþwŠ‚Ÿ¼ýÁÊøñÙ†ì_†çÿQ J^X'¿y-k']ŠÅlˆç S‘h«.½¬I©®p8›ð?\•§·€i—Is@· E¼¬Lþ×CÆ?XÚòåcgÖçU±–ɇO÷ªòeé_ÌT}cÔÀÝWÎ^x÷^s{/MŒ3ùÍJ.iê¾°©=ÎEY7Zð?ó ξ-²vŸKhdr¡=Þ‰ô™•÷‡×ÚÚŸìÇJ@ù>o!åJÑÉî‰^Šcˆg7Øõ5¨þ'6vÞÚ¤þ­»–¦<–å®ß:àÎÎÿ¼ïãÚFs¢[û½øP¼øêvÎÓ8Üò8˜—wñ µÚè€>¦W,ô«:X’½þM™{íhÍUg_rO¯HÞ¹·håcœ?Û£D÷vûÎg؆? Þ?Boq¹ Pôʦ±ìB6plÉ(€è5ÌÉ8d{›˜åÃsm›"[a_+&ÞlÚ¼¶ÿçƒÆ«æ5e¥4\?-£¦ºÝ¬;/ØfzpžR¤ÓÀ§L‘ö“DSû „¨É;·^SÀâ}È­ªóÉ«àûå>›Ù|i·eîÎà”«Ýl°ïÀ Ƕ xÿcÑ­¦ y«¶}–¡È¼7^ hX{¦D¾jßk4tï_¼×ZT2u^É1œØ³GWM—RÖlÆññE‚ÿCU–“³ÞÈÊÎήã˜[99”.ªd -XK5PbÛC˜Uçš´ÑðdãÃÙŠuAÛ\[ ègЧ²ö"Qé«jÞ^­Gf× ]g5‹œ—‡µ×kþÇOþË{Oó‚{7Á¢=¡ )€17ÑãXT›Çô–䥥@”^˜añW¶]zsysÙgë²»v¥‰#gs5ø›û/L‰¾˜n¢µ€¶\Œ7q•ŠÝy„ÇÕš¿|h*÷Øú›jÈ]ß#ŽZÍ_ëܳGÅŠÿ¾¹) ù0.áaÜ33333“Fff>Z+ƒô!Þ|öMÐFòÍÎÎï@½àu¤ò }ŸJI¢myŽö†MAÈ^^`4íKÚÚo¥O‘«òÊÛ­¼uê¯Fçê…aÓT€œékK³^­  &=?ûøÛߥãyèµzàq:cB^·<טÑ6üVÒë—Òéëý„ñ°hXÚ@n‰3P•â”ô5×'Ÿ) ·Ê9$®‰¥ÙKù‰,Ÿ^`C]m@lCÓÚRá·Êî´Œ·ñ»hNjÇ^ЊO(XV«V¨ùê¾ê/íõý(»SÒ¿§¦¶3ú˜ú hi¨o}ôhx«¿cÔ/ºäôk¹ V¦gé´@€÷((1û ÙÃ7XÃú ¿Ç9Ü·ƒâóþhøiÞH Aw ´ý>‰Ž}Ð,Y7tWGýÅCdksÔC¥j÷:Ú§“æhÐrîÝOw¤ƒ×oÆ»÷™VeÉ/Ö'[œð^=•_¹= Æ ¸±w“âæw×+×Ò«å4¶ÄÚí¦1D­T³ùÍêôøåE3^®ƒeI¯%Àq?õ)ÒŒf´´°c‰á¼˜ Ârá6j{ÏïØ»×ÍË5þW_ô^õ—~.>F×:Þ䇿_C~mêD¼/öòçÚFHÆ,BHqßBÈ'ûö/¿BHéðò¼G儈׾x£iwÿ]!»6UHï.iñ¡v*ÛªèY{Œ¦eŒÌ ´Ú³W‘Î#„䘭J¯ !d‹¿˜BfÙÛÛÛ›÷k¾†Cx×È/Ng5¸k<½…dÛŠÍßQ²N·, ·Ç|£]öô(GÔýÔÃyÎ=|IÖËæÅÒ›VBÈøJBö48FÉpJ!¤ú芮ó^Ó[YKr›-¢å$M³oÑ–·5´|½½Ÿ$Q¼ìÄ7.)¾úéf'û•ŠkºM³oÝñTHÿVKþôäýâ<ïáÑm .à˜©›€ˆ¼™­¤øY_ d €;≎ñëX€µÃnÙ„k7ŽcsÖÙ7]Omd-c~eo‡ñµ•ú¹)s^)’ÅëÜM‹YWä«_e!4¯y|¡€¼¦ oÛÙõ8uW¬¡üvc¸`²Á)Ù‰ J kªOÒ[PIÿöò¶ÎMJV[–«ZLdR!”ö¾±’*,kDÕ0ÙZ-q*,pÕ€Ô$ÎÞ3šC4]v|F”G?9UB«­&›»pá›M´¼Œl«Ëo-£/Ä~áÃnkóä.˜à¾ØZqÛ nŸ~¹]¦myý±_ÁóÝa‘‡½ ûÈlÿžžûD†9«ÁPOXUñ€~¿ÏÀ½I@ÐÊWV%#sk8³Àã…^—:<Ömú¬U3eêÐ# z±µç–Å1gkù­ŸŒè'O•^wµ)ëõÛP™_•Ç6ˆ³ÛOd8Ÿzm}V\\€.›Ín®Â²ÔÑ>tà¹Á“RZSg ÕZŽIú_Åž1ûh¢h%Cº¶‹Ëe½+üºwˆ<ã†ña¡ÕÎm&–(¿ÝJÊ4 :3ÛöbVó…Ç2°`ÞãBæáZ>½!é+æÍ¤)*Ð{‹Õ°ÚcÚýé6TGº¯Íb‚CÓ£_ld®Ðœ—K;ÜOŠìåmgÕè·7 xÿ­À{iÎöùú@òåf—¶yvX~A¾9²¯¼Ø+cdý3;@Óp”ÜѺãþ{ž}‰6/%U¼;p@£½Z]=´ÔrHð=|>S{I_¥ •ÖT$eÑZ­J$ ;-b…Ô¼+"Âõ+ ?]r…àF'ÓÆ‰IòœÙaCÞåµqìŸCÔT®"$¬SûÕ#\s!•Ǻ\®ùwÃÊúeÛw$àPñ°Yà_äÏÔh²D¬Ôoíª°õ‰vÍÓÀÎ=ÏY«rË®¥W­±<z_Ggœ)"ß“óÅúšÂbû½ª×·+Mû^ÁGpÁ]lâ‹]·—qîñèwSCÉäß±G§ë½éV6 à6 ¸½³œì¾“öˉ%5*Ý.ßÙ¯e[ž{/±>²­T @:ÊüM-6PU¥#ÔøêZ@eµ†KÈ.³u”Á­ zê@…¦2R&øê×ßQ~<¹nƪ ”+8j:J€˜øiZjꈫ SÚÏÒRþÞ»‡ú€€üÁö«’cù±hb‘3ÛjFíqœ‰>ÏSe‰ˆ2€”5‚[ £ñý,“¤+üZK5¦+ü8eæEÝwð6tªãwp5wC]è—•RÁd]Œé:{U„9//|òd›¤nçåicD©{aDR³Ä±jÕ™ågUÎãJzµÞ&,c¾á“ÑA»×–£»tgŽÂ† À­KêBžîÞo«óMø½Ǒק.%¬ëœ?M·Ýle«NzÄÝož,¶c}ø¦ºÞ‡Ô(Áó³†å@ƒ*ç†l\´ÂÍçåb×ùŸvùm®Ñ#å6L[XNUyr©@Ôñ ¼/çøÚz†‘{„mûÆŠÍØ«ÌÃWŽ™¡xœ¿i êx—ÙÀÅ».Ë4Q²*±ïÂÆxuD°¥/à>Úo`Ûo¢efCÁ¢d§¥Í@Þk›6*SîÐî· XÅŠH’ë¥E„¥äßÄ Pn:d,Ã6Ô¦ûvö9?ö0!„ð8„ô MC(”Q|ÀÎr!ÄïÌÒùçÆ¬8ú›é‚"BÈõëu¿mWÜê¶$kó7mù± ²ÒλÛÒ?¶½%¤fq.]MK=ïçGÀ«ÓÂCÏ:YÕǨ)¿5ei3ÇÆPr¸îÔjʽ-r®_,g=¢Î(tÉûÏ^{TpìdJ&ò=KëäE=¬“õ¸õƒÀ ÞÕò‡Ó¸™'^’_qàr…6;z”ÝŒ¥=ïwI$æm´ƒ“åN“@E(>ÃS¦žÏz»Ò²]eí”Cî#þ¾-F£Úöò”Ÿ,çåâ?·ÜK•À¸nê ²Ýò|&ÙüDéf.wáZ ¾ˆfx:;Vϰcëݺ-ÕÉÒ¤h[Eoý—ëZl¬Þ@9U._‰êMVúªì’æÄ“rsð+m…unÝ4~äÎö*®×ùp¨Ôi¶µk­Œ„·ŽéÖW°WæXHSr}K³“õA]G–™v±ÝÓÇ]í»$ö:|÷69z96 !bB&ùÜy~”bëRLˆ\2úz£¤hÜÚ B!æWnmÕK Iü&¬SsìÒ+±_ IDAT—:Y^‡ !„„­K'„R¯q·ea3%ëßáË|Bùf;‹w+©Uÿ ýMâZwå½t«NVå …hå~ ƒrÊsòy¦;M®Ú£{ë+%ùì(}M-ôŸ=.ÌýÖÿc¤C}XZN!¾ ¤ŸK•Ôò‡åÂlÐ}Y¿g„pþ}Íÿ`ðŠÿe!vh7ι³5GˆXLá?é–ê½Y0H1¡[So- îv[:ŸâaÜê-dž˜~ønºxŸA!9K¤u]ê˕߱Ž".Ü)®Chn}Y§îãGë€WpØ£N«e£ä÷ôÿVN)xW-Î^¸ˆ/} fS†£úü:šÖ êXEíê VnnIË 뎀ÿaÚãÎÞTÊ_[N!b¿‘~BB„w½G@øÕ’[‹öWBˆ0¶€?Y'xyf†•W,þ°¯¾¯:sç©p&b±˜ˆK×Ù'¯}A^½—]’;”ÎÎò'¦“0k¶•œq;ÚöÌ(*ÿ™GHIu“³p]S\ý¥øãmyEIÞzC’Ü÷ŒzßÛ§µ4qü„ÐÐ÷§LêrÚ©u²JûÈÖÝ1’e,j7!„øl‘82,Q¬ñ¥¯Tž§µóÐã;ÝÝš¶«å—$ªìqY«¼·*þçÄŽær4JvùÆòz#!–÷ §ZeJ˜ÛPBáÜ~Añ:òC3ûçy Ä¢ºùâ• »òæàÖ2°X„T^½aS•=Jnެ¦ïVû²ÏP•Œkðm “Ý3Ø›<}êÆ@J‰©“e9 €gW 3ÛrÓõ‡a¡ß@ áp‹É’¢ÏNT?‰(}~’^_>|ø| ïq¨–Më´ª& üsR„} oûK%øjä¶Ûó7\ÇÓ¼˜Cn̬SÝ»Û_­UÏ52ìÕP½®¶ª±|7„ ìÜõs*Ê nÍWgÜâTwHò¦èûf€ßÛ@¡êP ‚ü·°±Ä¬ïr­kØjÞî™À—CØâ71;ÛâŶ<5Ä,i²Ø{?¶æj¹Q}Úº~Ýø… ªÇÖØrëúÀº¢å‹gV°ÚÏØ'œ¨ ®€ýÝ¥¶­ªS`JÁ$Z-ÙO¬6iÀù…Kg4§·ªTGª1Dá\©ÃÏó0`ä“c›Uñz¤L:òÿÜdÕ·¯´ 'êìuúúVˆ&Ý—¶®LJwk9Oö¦pbÛÔñbl-³¸ Xöí ¥‰‘Üì·ñú6ñaÀà*öKŒ¼aææ ¤òC³ûO×6üAÿ RzŸ^6x4¬½²Ú¸<À4éÈ7­šPo(.Ÿ<ð¬b·L“Ï]xËZÈ’ï4ùÝ6/–[jÅœ·ÜŽ€ŒñÀá²uÎÓŽâÛ.æ53¢VQ1=c´¤xž›ûÉZÑ’¾Ö=¦“s²®ÊVX±Ì—bTÏU€Xºp¿?Y”Ü„~ï¨ZuE?´Ÿ·©'Ûqùï{]"/,–Ù›]tÿp裵Òô´¹SÅÉÀÞÜÜ é·ãðHªsœ:ÞO¥ ^o°#Þ×Ý€-fÞ€BÒŠÊ5ÄÏ_5jvf{‡ão§ µošSÕJ-•¿ËªÔ¢ƒêo#÷Ó1ÕÐñäj¸?'ô&ÉÖïV¨`½5^ntpu¡Oa»¡Î7ÌÚqÝu-'¯N«Â×®m)3Ë씕¸ŒŸ—?@ª Z}u±ÊÒü‹6í®UUáîÅäö±‰F¥qfK=´©÷æ›7¬ú°t6DÞ¡ ÈW¥ƒ˜¤ödÞØÔA9# Ëöƒ&³_J?ö|ŠÄ9[èqÞü!$ðX>!å+&æBHw!„T®Š#„ˆí—JbÂÄO³míF-ÙKÒ‚R[[û[‰D|êBðq@õÏu©*¯“õ$ôúA…d·õ‘T$ø®Z4ºæÂ)yÑÕsTù/~?!„”$í´u¬„™…b¡@ ðí⑘.¾`¬J5¨Ûuµ ëR¦¥ÈuJYXûBÉé!$„D¾ ÞX¼¬š^SèDª&BôÙ¥ù–†;³…„‡×U­D?!•á}·E2äšy@è±=Úâh¯Eïi?×bòà™L,ýxû‡¦ó×ïUƒ@B!ŸuV>Ï"Dxö>!ÅÛ¶BHì&DuµRrCb\‹xþrØâH"ÚžG!þ»$ZÛ‰#ž‡UQ®…$²vÚŸh÷îô]SÖé¿„)!·=ÉK8'®QïêK¿==Z¢¤àMT(^—Îzùr’!u‡çÛ:­rö¤Húž¡¾aFžç·Tâj3ŸvãΘZš¾ùµÀLFë÷·hwËŸø^¨«mH½åõ‚¢…+½M-]Ë'äj¿Fi„츸/s}@M²¢0òõMç¯1'Ϥ9̘×1ÃøßW{²Ñ4#Ø6UÂöe:«#æÉ i_“ÄîCŒqM­7°SÕMX±0%:{êónÆÊo«†Ôj$&Õ¬n»§‚]BeW©c¡eÐ5 ÖJsñ±™{Bƒšß™bù©n ˆÿ–”åÈhþˆj$"—û0×KS³,±¥ÏP‰=RWóÈÊñK?Ñõ¹h·b Å%þÖMÆKÔ@ìƒÅzÄqÖbkSÛZž§!¹k·{dE)‘%’3¶í´½P­J>Ul:¹°üA®õt)ââsFQ˜pý-ÑOßìVßYàªõG}õôþuCCQK*ÏVV[xc‹ùh‰bäútêa¦49‘¼}'Rl1MâH¬}è«×î…Ð×ÜÁí1Eqí³g‡„\ ñÏOi~óϧ*h¶éþì> ÖëÄòœ.´îAQý˜¶á×/Ç=žeXù¯–‰Oè-v{)pt5S@òÚcû›%m¤;vÊÇ!‡m¤%ƒÝü[tÞ)å—U§ü›f7ùRõP*…ô/9½HþjÅ÷¦ÞÕAkΔÁò=hõéÛÑZ›¤MëpâFÁ" ¸Å÷ §­õÇ2~{AÛŒó¨e9-{;ðê,Uê•R_¨’>ÔûÎ_5˜"ßëßà¡WM—½j€ZW“­‚;l¹œÅဒO¸Ì6ÔÌ>Nß[Ió±S3c«ÚÃf-ÙÅL¨.cüŒ§ýKñ¼ñ#ƒÿ„áóÜA5„ðé'í|¥RÂâ÷ ëŠie¡Ó÷dÊd‘äRÉñ·’¿•Ï: ‹Ö›©…y¿/43Ûcµì¹»on¤$ã¶Ém»"ßn¯K'îâÊ\´ ¨»»•)ÒA'êÕJý×äL2ùœ_U‹çåä·™UY‘¿zqÍÙXJ*kIMÉäDþ£1!Ä-ŒÚ·‡e)nþ¥Îíãæ—S„²ê’â” ¶ïòóËå¹#Ê !DX^\\\\R\\\\IHù\ºQpÍ9㞈RQ4ˆ[¼ã‰ãûæ1Uâ“û6ü9úµVÞ–O 8ëvzØ0w5c6p£¤l$ß§I/ùê⫤æ}j†ÜÄTn%g6—±²ðõtã @xjYÂÒ ¤uûŽQ?÷ãémV^¶HžAY,ród+¯(ìî vzW|n»J”¥Ùƒ(³‘y·«¦ UíXx™"°&,©$˜ãŠæf2]n""¼+ƒÔP3Ƀzù½–”ÔÇAwC·´Àä î}º@,T§p5œRÅ]B!gïœÏ¦CõTÓ„þÎ)ËxyMv«sGüvÞP¢–gl;GÓ¾¦[Pƒ²µ Ùà§\È¿§®¾u)[·¯{õjcÕ_›mþëºç6­÷²MKJj–Ê¡òa¾âǹ­›}ùoL)&ÛÉ·7Þ×l¶Pî=Þ9ï^¯ã+¼š ´P-¢Î¦à¢Þ*G)Ší"û~±g¨ö÷fpØó€2é«;´@¤QÙóï_­õJ|ŠN¯l7ÌîüíÝ)á˜ùìI{‘øT €W7ªÔ%ªi@ÕQצÇ`îåýS]£‡QÄ:¼}uâ>äþþàº?¨5‚é©®3?Þ÷‹Ô¥.:– °ìdW:¢nÌ£¦³;¢òFï÷3n³>Ò,” 5mðBô¯ ‹._l=!êÑn×VïŸ+_¿6Qˆ ‘ÏD{)fRçP*˜ý©M Ü®½r“•öüFè×ï½³_+×ÔÓã‡RÆê•­+má}eLÕS1‡Tµ¦[I’ÛÞÏö¢¦ªÑ/ ^¥&ÿ¢P|6§Zìê£áµÍ;g+uù”BÓu+Ï€¢þá>ëEÓ|­p›9W&;©ìw³ógõz~O¼Q~E>ÕÖµ±ó(¼´¢oŽÉ‘U·kn×UPë¦õû^à”Üu»LŒ¬Ûò3ŒÒ÷Ð;²b‘£d]F>ò¢Ò;Ϩc)õ1oIC;r Áå]dÿ;Ù_-ìOýR´j`ÉÔÆö€cV+LïWkÉ›Ý쬴u½_®ø"×¶æßiÙO‡&PÉΕPyv—}Mäß±Cî€N2Õ¨¦ücÚ†_J`êeéC¼<8$¼í‘«ù”-2“eÿxSÆø¾É?ª(*( ‹_«Rõòz‰*¿íbÝ+Qa Ù§píÝöXHÄ›¨ŽÁc¥v1Áº—¢˜‹2iåì6!é[,3…­Æ}±*÷ §o â nÈ©Úd׸Œ_««¡3ƒiÛuV*Zxâô1ª?ð#Ãû”¶f”ÁöŽ ²[C%XòžºÏèú¿êåº;¹ ÔÎF<•‡PåTê”ïo,óÜD³}ð6÷íE•Þ¦x¿x·òÙÙf}?†‡Gϸs9݃/'}:5#mD¯ ß"YîeŽÆT¦Wøc§ýJà½ñdNÔjõŒ×½“¡j©(žû{óÄŽ^Y©NØ)ª|kùÉÞ2lœBMOûö»’›qñ?/ÓQ—é)¸7 ÆÈ2§€7H2ù•WL‡@P(/0Z•1ÏA¢O(½bÞ eq})mìÞB{žw¨õLn㌞­L¦æÜ}±‚vÅ…Ó²žï*¿6¤L{nȘ]oŸÈR/–Ýõ°’kŒIj ŽaÕ-jéÿ[87ÓnøÀý'6|FíiS˜ý°; ]÷S‹O4EexÕ x¿O—³š˜5É9˜÷²÷yþg…"Š{F¢u(=—6ÙVœÖ¨-:]’‹åëè•\©:ëH‹¥¥¶ºËuå}}²[ú†×r‰zr®á .• ? 1h\Ñœ”ßS,cör%ŽØ‚cfS´èB¹'Z—f­)R;&°Ûhå—›ÞÊÏð„‡ï\Zy°âCòU}eT'*ÏÑ6'^“¦¼~k€©R#ÚV›Û!)­/Ë” —.щ:.=yÖï™ÓJ-|hLåB>¸—]º<žú/]IQ|%ZSMo‚ûƒ:×bý¹ÁF1;üýÏl€Í!þ¼B"ž«Ú«Í7º%Û³½6c} ^‰’#°Éé²þ¡9’]ˆ¼ƒÓc|Íš7ûGáϧ¸2‘#„²îy!„/$„OR7+·šñ¬`¢ÿó…mLš;:ºP}SÇŽ.[aúp¸$uë(!äKÿSRO¬¸=”+÷?B.®© „Õ…”’ãW¾ #„,ð%„2‹R’äNµ µëú:1"""22"""âX÷6’Mü¨}ͦI.¹8ý3}gï !!„ðö-‰¯&D|ùUFê*1ºMùÜç,UäŠù&@q&þÁ0g~1šIò{XY÷ FªZôQ6­*O³ðžªa*.íñï3T<T«Ÿ9%ݧú„â ò½¹§f»E§uq¦]‘&V¾ÀãZË8ï‚hjTÖ$ùæ¤Q&4‹ÄGªZ q!m@tœ(;g‰?–´ñIëºJbŒ×ó?ÝSêÖ Ð |›½¶š¡rgESÁTÏ:qd˜Ä¤©¬Kåy«ÊAðþQÇI\g5êÁ™QcwtmƒWÇt€6ß™ª3îYl–‰ïO‡KE†öyÑ­Ëz©éGŒug±¸»ÈâÍ>¹Dò'*c‡j»Ì~ÎJ™sQ»Ñ×5¥‹\©s^TÐ#îlí,ÝÛÈ1¢¬rÖÛzýtr£8K1£Â×S êEÓåÆŽÏ­ÕÏ-æ]û(cæäДˆmŽKÎo,y”þ:{»BÃñѳT«¡Üñ¼L½ý¬>ßPóéû?Χ–==N³ôvÒAÐEÌÕ†R]st‡»Ê€†yêÜåºã:`ÖNÞÕ– ô«²_ToêY;t{èDš"âô]—š+úªæø7 l¢úÄ ‹â"Ÿ˜® SB.›Kø«‹©ö©ºkå¬VúŠÙßkïHæ4BÈÊ©Ÿ¢$\ëÙ+öO¿Ý?È#$u‡ !„pŸ¨›tÑó¢?Á‚pJâýª‚y/åše(¿ '¥ËßB¢ÇâëÉ¥XôºBÈàÝ’gÎcÞ3{\4dgÞlçBÊB¾v—ÓÀ€@ª`(N«`—$òù²6‡Ô:v€b=fVv@€¼®c’?ÁÇ»{ð%€œ=Ãkø¥‘_k ^\wZø!’°YúçU&Õm3›üZ[nÍ¿~£Ä!Ýöóò†VÒ~·'ƒÏ*.¯`]H‰NvÑC>ê5ž…K+8ëlSdÓYµ†raØBˆÈëwIÈ¢ª‚îkª åjc:Œ&–Ü L£ Êw›±¢yTûí¦‚¼ÁbBÉZõ<”Rrý4!Cóª¤ææW´êÓç<¡Ô_ì·¦ h`‡"(”Ræ‰8úx¢í¹{øQD!Õ[VR>³æüky}Ü5TÌó[.L-U4.xþ@.Tr ÷•‹Üjz½æ»Âsæ:š°'ì*“b÷SUÕŸ³þûàÿÁkvó_—ç´v‰'=2 ‰í% „þUEÒâOkQ·Û^ÿ¨H,½±üá§ŠôF* R×—â¥8‰©të–3ä[l¨{Ú)üéwL>®1YöÙQ=¨¶±¤³»j»Ú·úœ´ÔÓûkz{Ü-ѧÓÏvɾ=ˆjZ«ê þtlW6€<Í–úx&:@¨Š“T $>a¼¥…ôØeMkV¥Ý5/÷]ý]Sª>›ÖÂà}¥‰´½kÕ^6tÖ”kóŸwú…ÌÃ.¹¶ÁŠŒuÈ祊Áoðb|mT‰ÖڥÀÿìò@—Aì;æÔ!!O¾æn×âQíøÁš—Zi Б3Ø(yÕ&C,R:¹ÿÈ93X<ÛD¡ù¹_f³ŠbŽ.¡lÏàæÝQøá¤}]á±R¶x§Ä.ÞÔF¾6•TÓŒÕÛ¶hÔéqƒ€G'æ^WOŒÔç6®½“ü}Oª·wvé0Ùý'Jj½$Q<,ºv}*€¶ÙmÍrè-%}¸Yw°]E~Á5§z¶?ßeWϳæÓnO)Vl„Ö .â=ݾþŠj‚K ?çV‹çÄŠûîý06S|ãPuå¼ã·ø„ˆ6¿çÒjUr%!¾«©²» ·,Å_>$ãÌà J üŒZAžÅžýêÆÜwñ“šc-¬­ðxk;Ä‹ä¼\üÌäòß(ØÇ]ñ¿dºÕw:É$“g¶èRXò¥TŽW<>⻽æ=:8(.19µNYÀ-.5ùí’?8]é97@j®Þ÷@LbÎK®Œ{™KÙB‹:"•Xg¬yÉãlmÍŒm£9ÏNäìîY!·ò‰Þn¢‡úŸ¹¨2¯SE´äM¿Œ¶aªi×ëÕuäÚˆˆXi¦ÿœü%á$b„Wv¿Lñï÷ÄDtmaft„GG‰J†{í"õÎßrebÜ„Ru/Œ PŒ÷›CôV|W‘å¾uåÔ‡-¯òIõî^=š8šïHâ‰áEDD„œ@È­›;{·E5Ó;Qtw|·4BÈÉœ¦Îñ§Ô¶‚fúžZ7¬TqDDDDÄ“»ƒ#>t>SU§¸ú®75Y9©ðð8¹vê©"îîïŸ/BHIܼdBI¡GD_ù±v×yw%ˆ|ïby}ð£s?Æò !$ýØâZ×~¤¸ú“½Ô×€óí—1—Ž8‹Öëj±}O. „×;€Ï¥ —]Q½»®f&RQa!ãáÇëšÝ^Iè¨ñäâøúÀ{ššµÃ!5N˜ùµÌ¶ËÖˆàÁ1,=ÜU­Î—³Á!LÓÜÌ÷6\Ûc;,KÞ `‰æRÆ:?AÆ =ò~+¥0¦BÏ .ìZe aÈåfTmÙ-J¢äÉr ùñ€vVŸêû`øAØÿþƒKW®eŒ Ž£y(¿b-·ÿqÒØ®ÍZÛ÷« IDAT¬YJ<ÒV4€í§hLƒºA-)ǧ,.Bò¯W¯U%Ÿ´Mf>x=¨É€‚¯A굎IæP[1• ¸Ë·þEx^á¦ñ¡í;oYR+Ææ<ýK©&m’žcRñlÿã–³‘—‰R¶fÌqÅõ¦9ðÍPàÀo¿(IlôØ*së½¼’ÞÈW%X©Ö ë„Æ^—fcYåéÇÏAY ã»RÙÒ†²‰ /åj‚ëEc_µ¢0ñ³@¯Åéß ®Å©´¦¼šiÝ©íùZX©^Åêc2%Á¬-.î’4ö$¼löÉm—#¢Û ¥>ï==0΋IzËSáF–Š¢=«S§W­ÖHœq]Tiï@/z¯Ÿ}µU¼G¾Ý²Ì o®[©³T{aªÆÖÚ›¹ƒÔT‡ÀS*óPQPOÏa »0¦÷þ'Ve!É:ôÞ‰õÖ7:ñ—3Uò5ÔQó±k¬E#cNõ`¥;ó;R…õõ=¨³wÊD=T\ú0f"âU8¨ºi#ÑtŽ¢ƒ÷¨…+€¬í¿ó`‚‹Xˆ¢ÝûzP³c¼])à@ç é7ë‘Ác);’ÆÜQ€Ü‹Úܨiy#)²ø¢õT{²£Õ|a7ãJÕÑR¯¤ã}4“än Õ{ŸèÇ”º¶âžU£zRú{%eá ŠsÅ]*¦<®Î›¼·rÔÐ}`¸¥,Äo]…á3“¶M)þy¤òAr¢jVQT.·+ýS7Wï/W¬4˜Îû±­ïõ•ç-=*¡ê´v¿·µ ‘¢¬°‰ý‹ˆÏ€kaVaaaa£l ‹=¶C¼–îŽÔ…¦?ûŠÀnç%§ûð]Ê!â÷û%e³èQŸ[Ù99999©;999u8"÷€ÝáäääÔ­ð¤! í í©‡©æÎ¼K­áµì؆³÷yäÖ^jÑû:û\ZM€Ù@•{|\'º}‰¤ì!}q3]Dª»œ$„ŠË.ŠIqØŒöò+æPd¿<§5aÃò©®»'iôŽoGœnȘàÈ£T©ªÆÇŸ>â_×f½£ö”J»¹a«dÔõxdË4kÇ2ù(]¸UÝÆabÔ?_`;£©§ßÓh9—˯#4Mé™:ãLÕš•¢å !¿7Ù+$„»{={ÑG*ŸK=×Füøh^ªÃœé«p[2?‘9„rúÜž\žݱ©ÉÃj.—Ëå¦Í©är+ÏÚÚÚÞOM ™b;–Ëår‹{[\ä‹=›Ú˜ÆÉ…²b·½´—¬ŸB„þsŸ‹Hæꃬ•Úôª]ìæK)Yÿ‰â »“G}÷D¯¦I_0÷Å—©b"ªùMkxj¯zœížŒÔjR¾ZêöžšµÌv6—˜ê±.ò¤F¤"o+½»Y>=ò¥GÔQþ2G‘ªJMM]mÓ¢M+‡™—ÓSS³äÄìÿ”#×µpåTµ-¦˜vrËVé>åšsçD½žq÷ŒËþ' l„…•é‹…f8Õ-?>i!:…«DXÑ êɪUÀ㔿ºBU6–q¥ªq ³›íý*c0ã¼$[ºß  $êz^'!>÷Œ¥ì†¾}p_`þ| ·IcÕ±Ÿu@Ý—ïiš 9xÛaS—a’H}‘÷46S½c*€§ç (ò ••i†sUoêÔa•”u¥š ëBøÃOK¶Ðz]|}„4( [}èÐýÇV´1Q»û›ïŒþíY7UÞ®+ëÖá©r•7°Ïqš,;dW6 H]e>´Ã c‹‚2Cáoºo—XWu_áf’½š7 8Eã–#*O¶5K»½§³:øE®j§ýî¬Ô}æL·•§G$έú4­¯.Rßæ èI³j^\ÆÞË;@œI I†·ã%}:£;X²<@Á7ût”Ó’˜·Ðd½×7zþFåæ×oŽwê…+›[¨y³Ò¸èŒLouHÄSõ‡Òú¬Z€@™üªùÃ;Ôü°ù¢h(Ä&P¹÷ÉF¾3ˆQñë¥çZj¬XDû’бô;¸FØep­É‰‰˜jOÕ dIìE•ËÐöÕ­õþÉàežºÐÍÐ|ÿòtžò‹ÒåáÙÑÜû¢m’·¿¢bm•Î|¿¨Ä2‡ÚQá§)¦{¯¶21©íË\‹ôøªÇ76ž€K j÷%°€G}ÃgÏï#õØÈ_æÚcµ»ïãûÚì¦æÓh~ðt4¼£Œ7ïö9JQr7eØi=À¹ÑçlŒeUláM»â0C'• áŒ1ýØ lÿòîÁò¥lsxX`íyŽË˜@M^XBõܽ¶¸+½…÷ze±4Ûâ‰{¦©žú6 à|WêÞ‹ÖnðÌ¿4­€‘Óò²çÐÓ/~³A©še¨ ·{/°e‰cÂBÝ´ÀhÖÀñ(!)Ÿ¹pÁËeÉ„¼ÙYHˆ_“ÃIúà¢Z^ï‰]#ÌYÑ9*Ga‹Md/\jæ+û¸LMA,É0î[JDTvtn¯1»KË 7çravÇ3=r”“©?ëC¸{MFÒ¬ƒvb"¢…ÉT²ßYªxªkòI±,8HhÊ9JJ×ùþ‚”*Ís 8ÅjÀƒ¢_ŒRøB޽Z•Nª<·÷%set±ØþŽ˜"­Èd‡Ú£,ɹú$G–—[~Ö‘ë e¯¿©DTêµaÚp5Úš¸“]³,¼HúzÜ«–r«”ˆ6ÈÝÔDDÅß÷}&"ÚÎצKN¿àu¤x{{[MJ±ú³6±Bë¹Üfú ¥p&<ŸDIÕ¸¾ò9C´ô¨r²$\óq‰Šn\f}OóÌ3fÑfyÖ郾ÛÜû{aY¼÷µ‘/ä"jÍöß^fcõ?†¿›Î»Äc¶ÅÚ…ݶÿF7zg{¹. ²Ý.{ì{ùÄ(»%Û–Ä9Ñ/^ó>7¢hé@|ۘɘ/z׸R-¹MÝõF¥¡ž@¡Wú܇§W-¥÷’¿=ëÓ=GWö3ö)ˆ¹¹¡Úøñ!–ÒÁÊTž"«Î«Üë$ ØFÅ,‡ãýÅr'þ™UœX\·7€üLe÷âg ÓŒ{øxö†ÁFOüš´ªÅnÙúnÔÊ­òÅïG­¹íû3ä@w¾WˆÑ+J.W“5Ç?›é ™R±µ*Œl¥Öa³7i 4þZ('ˆqØåžtô¾¤¹u < .* ÓªœáÜ»¦Sú–ÿ©0ü½„×ÝuãÕmë¯HÛð›4U/"Öp©m—´“Ù™càK険œðºÕy¼50¸(€/µXüHøÒ €@¿éõò1Y2A¨TéûÝ<ô!»æ-´4ÿxÅí*€}»|ñÏ<t¹ òUBjgÏ-bÍïZ ðZ–4wËöÉí#™~e¨¾ñàáÞ€ËZgZí¯¯Ú°kžkGC[pön€©³€ÒÉ?®×±8ùË…m¬tu ÇÊð¯!—í¬ëm'uCA<ë ˜uÌq0On d4^§N?&vêÃ_7ß&my ¨$àâ4'BýZ¬5KýÐz\Ý #·üÏåáo¥4DZ^–µöêoÛŸN%"¢N9.Si×q"¢à]ñD¬Úàºoõäåï^¾S˜QGØHÚ¦61WØN?³ƒUÅnŸâYl>S®/ªxÁ¯–ÅQéÍý3kUÞÊ5íã>štø%^dΡÛ7”®}'kù/©Å6"ZAD;ÚAöENÑ ]© 2Úš;«v}ujÙè!} Û¯nö^ëÀ«Áöò´¥{=½ˆˆRΰmio£¥ʈˆ$÷&˜³VrÉ JèÖM ŽØÒ|"Ú¤¼_GÎdÍe•œ‚¹æÿ‹ˆÞ¿‘ðJÄbI@·vS&^ç÷G.h+·7dn{seDD+½Î¯Í!êžODé³2IJÆD2©X,–صk´ú{t‚Ê&nåæÂw†,“Xôý”PxÌ?ý–ºñËaž…(²º[š´êWV†×às2"á%“³>Õ·—+{ÈÄGžr¦Öw360îcäóBéõ±R±´¼*{š& 2û HÇ£¬oA¼O»W&‹Åâ—ûrYøÐ¡n»…yöã]å;%‘ËSùP1¯«¥$?Ü(¿öé*ÿ_HÄßGm(ê­‹n=FxÆÏç#'Š_þ,”§uu±x.€´ôˆkÅtÐ./O›ð"#ˆ-AÎ;€á޶ϸ/˜ëâÌ=i{wî§Êe×[õff+±qNGŽ$~š¶õ[šÿ"’cȧ»7—V­¶éÄa§‡V{Fè4«*HÏ 9¶‡óM—y´c¾ø’õ˜)7¼ã”_SÝe×-¾NtÊ9 øÔ—ëôa9^?òä:¥æé Ÿ¹ˆKËjÃugGA¥Æ ÅxD°¹Uó¡¬×[oªU+»ÖÊÑü­$ )Kxòa‹"ýhj&«a¸j¤³Àò†sUä¾¼ÿ(µ9›®2AÒˆ;QâZWU<‡Ö§dceÌF™ŒKr ®»ñJ¶ì#á•OŸŠ¢ÊmRö_Öh,7w]uóÝ2n'‡Ö’d Kï:Çž}OR“ö ¥o¿÷> ”Ãhqf#€m¼ÖtÞ–Ý|´¿6€O©O»?¨ üÈ]Œ*=¯+mª÷ß8:,œâöºÌs8’•(,j]+<f’ÙOfÖ´1›¿Nœœø¥£F&¦ 8äušqJmW‰ê¨%cýÖ†v骲qn—XÑÛùÒ|;x¸w8Öã˜Ä¶É( DÕ'WËyb:qâ`¶¯T:§Q+¿MÏ4C‡>½«æ~õ€róÌ%Ž|Ûº°\ÜùÓ÷n²gl¾WÑ6þU[>POë÷‰j(§š ó:*˜;úö¨a»Õúg ¯L @¤]•§õݳÏh0À%%ùkkº.ž™kÇU+HÌýà¾äðz¥¢ãlÏɃeÏ)‚®¬çr€[tê¢üÓRñS(b€JÊ”HÜýÜ¡®¯¬ eëwlñªKY9ò%g¨píº‰­TZvk˜Ú-?‡,Û¬ñ\ÂcÔwÌ›ûoÕN„¼0Žôzn¬ƒj0‚¸8¶{+8„þZßÄž€G@Ô+¡~Þ$]ب±"D!“ŠÎ÷àB'_ýpò‡Ÿ‹dëS VÒ–ݾP:h ì 8³w8'vY/©Ãã1V˜$ƒã=W.TÎ‡Ž²NëùÏ^ vÛ¬…§¶9fÄU«ÖÛ1>áøvàiò¶šèô‹~±èp}ç÷ü½£–G´;únO–»Ÿâ3¤¡‰îðCåüZ¯h­»|‘çþÚ»Œ Úˆ¹pJæj ®ìÁ“ªVoG×o5PÑ£kìªf;›wÞh±wäþ Ï•¾]=m>äod+Tú0ÊŒSø™÷ß•è¶ä>[ÔêMµ)…÷7,5TlòT|óö[eA:vïÎ6`"¼û`1þÀ\xÖÀŽTîjÓOß7åý5a'ÌÎ\¹ ðù×i pƒýHe'år3yÕ`4 >,ë]·‡e—*&ŸsÉÔáKÿéj œÜv f­ª|he…2sÕú÷íÙ.äë–ôGÝ£õàµqÒµ£Mø°ü‡E«¸…Û FìD¦8,¿`ÐR©Wœ¶€Z-å.Ú÷#¸Ì²kÞ+õ&mó.CÌù Œ1鯖ð9EÞ¦Òו-öÖ]Øá‰®f°8LÔÁ5›ŠŽ>îÅÜÊ=Æœpü²—•‰£¥Øø_ÏáºóNë5RæCsË^ÂH”V´êº|ÏzËnÝ]¤ `8D­Ë€)9mjvY«zû³·ä݇={bÜB°z±ª£Ïé]²­lÙwnùQÇÊØIc.åô¹W:E0¼>P·öÿ*mÂßÂÑ0£kä¦âL¡ð7 °ìíV…]fÞ`»ü×ì·ãÕ‰’Œ‰Hê8-„÷t­a}ÉçÚím…2•óà„"µÎ§í‘DT¸MÕ·8%iœa3k¡P(¿èI1IK¼ê7oÓ6 1‡uئöé<>dåÛׯñ7½ÞQñ#/q¼wÙÝ3,NÜUåë’¹w˜A²×{î­~ìÄYMXÍ8¯Â6†Vš‹U)%D”4wóð%ÂÒ21‘øŒ+ç+‘Ýã¼p[‰(åñ©RIÝØÎ’×³¹$cÒˆ9»TÏìp gæs‡ƒø>%‘46Pîü˜@ÿtWYNƒvÞŸ¦ÿ¶ý­©Òc9YQ|©dê …o¨\)¼ ïóïõæfˆßÕÜËFJÙ¿îMD—žÉ_³øÃ ã…”~›É†4#’ˆÈgŽQ꜑Kß0oy—e¡kÿ»ò‰èÉœ7l§àµr¿SÁ›ãˆî³îÏPµsØÝ$æv,‘äÂ…R"¢Î;4 KÝ¿ö §Ý›}µŽ¾‘½jÙû‹¦óÑ{¹ÈúqůB‰>Í?(wžy–Mšî§NšEñoœkV1ýSwÐjVxóÞİ×0 ""Ÿ „üdô?ÛUöÃ=ÍÍtýNlü]‡oWx¥MΦr-Ö½±¹ÜÎ’‰”桒‹¹Ã V*4béu½â¸–޲­×+€6aݪG—wøê'Ê)œúÅ®MŠå¨oí·w–z@#»<;g½…JêÔÁ cö=1œŒÙãÔ¬7²³ÂúówØ¥Àï«0eÒa ¾6›u·* ¯“ÏÛ¢Ö@¥‘·ýj7ލ{ùØÅ=e‹µ|:§92Ÿ’EXœµhGåî“â8õcÉÃ’WASÙ4@(üÒŒ-»)zrÿsPü#ù5náÔOÍJ.ñRÅÆå?ÈÏ©^©ªÊ‰Ñè  Ã*i9ƒ­)ðáú’©Š'ýg뼦Mk:º_Ý´é Ùoz|H’_4v‡ç©Ð–>ʧ e^Ç€ùD'*©—ïg­aÁ0:ä¦10…‹>$)aº»¦Ö—ÆÔ=»F…µì¥²]þˆ{1ýžšíùèyªË¼¬S–£ì¿Éö§^’+é–¶eD$ÛÎêï!æl®TZCo¦|ú×äý« ¯Òn*,t¬ÛÀøŒÁ˜÷¿ãï¾Û¥j‘ͼBÅ{Ϙ²ï'¼s®ßV ¿ŒˆÊM¼òòüæšde•YÝe'‡äÉQFÞxÁðSºò•Hæs¯CFåµWò)¨4m£¡•å¯ Ü9ߤ‘[^±ŒHVÞ³GZZZZZ¡Ê:œÂŠ¡ß%ùéãg§—SùÜOjºaþERßR—‰å7rvÁR>#UÙ…é }³ÌSÒëF[ý^ÉËËËËsëx.I“U{‡Ux WvËPkÀ‰ç¿“Ìk“bGù"¢âÐWÓÄD²m¹rfç«Óò›Y=Ð’3³/<1Kÿk„䯪6”SUˆ™:ùŒxã U;@ò«›ýà ÈÈ’}ï»- ó{ßëäšÁ%»Ð ¯uXíÊ@úÓ\XuŠÄø±ê‹ù³?‹¼E=¿ÄøÔ’Ç=¿<œ¡B5ç¢ç´\£®_•†—1Ó¬N+‚š·ç:̸!šÓ|Â, ífßJC­¯Æ:ü]ºÔ˜~î)€ÒT•/«yç>&rÊYð‹ÜóÀ†ï¬ûôèZŽ÷X~³èóDº½¬×ÇI¹°¸ºÖ„”*õÐ/¬âPn³Ts¼n¶ýÄnê¢*·ßÔ(÷ð.ôæ¹…7YáFZÈ!vÓÃM¹$ç\“Õ+mzvà 5J”ÿdŒû©ÞïeEzNÍK~Ÿ7êÀÝÇßýúmös±ôWygcÒÈ‚ªvF‘uÆä>•ÀÒ—ÁÝô #; È%jOKgØ4£I>#ê°§Lž×¨ÂÊšjþ¥Ãƒ1zÓ¼¾ík»²‚ìÆ)‘4‡Ñyã2B¸²›¯äò dzÇx1E|´Z½ JGhÙ h·,sÔ~ ŽQ•ÊÀh¶ñÇñ"¼³<_µÜÌã÷Ʀˆ¢å²›d"ÿº§h°¶6ð¶QS¾^Ý eIbÈHåº@ô9ÅYµU»5€Èä'»â³9Rù©³òÿ¯-ªMn4ÄjA#Sk5àéW›/Àë½²z}Hj®y÷áÇŠ‹ý½'lP}q߇µÚhðÀòlÅäßšMdVªxŸÀ†Ãäþ%s¶ˆN¾îŒ«ûËv[Þ€ãb–î]ÀÅøfm~´Û íÙ™7D8ŒÙz C‡:§Î]ÊÇ¥gÈŒäÞ®ØSºÖ_ƒ¨¦¬jd¥¤äL¯¹þFæˆëy [)ý_¹ï‡×‰ŠîV]¯v±ކÒr5îý8cžñ Íÿ2ùøkûÒzܯ°³øfà³¶ÎDô¶~cCCCCCÃmªÕ7444lР}‡ž# {éX¯ñ°QÆÛÆ®}Ÿã4äc¨Ã‹ÈÈX¥¥.›ÀŸÑ”¯:²Ú“ˆdRçnG£â%äw;ƒBÔÞ€ÀÍùXac¥žl,7–Ê"?ÕÙ!Vm•š%´6šÈ2sU‡¦ìåØãé–s8…×#¨RíŸ=n Púr4 Sè´6\=^„Åž„$æu ¢ Z)î8gÑ-°¹2j Ý[ï® Çv÷A£ oíý'© ¬•ØÜ$×;ÇÔª#>×gÕÂ&%Ûn¬uèV¥!@T1 †½œ ’Q[dU]IcÈêÝy¸¬wÎí0 ù‰³GO)DmÁ@ôÆy²=ßßö4¿ÏT «ýYßµO:tRµ4ð麫~„I“’} P“ R‹h8ïì9ö§H¤²'Ÿ%®Lw1Ò7?¥\Òj¨×Ý ÐЊfE9?Sžx€k×bügl¿ýs>ª°Š·™*¤ˆaJжtª’i·\aÖØUrœVÄóg ÜšÁ¯ê3éiÛQðMÃfÙçÒ¢¢°?”m›ä‘ÇÙ 9‹ú<{ü÷GDD{b¤DD'ÏN|þc°ýòOôn«b¼ z®QšÅéU„Ya¹ÈnöVH¥Â¸Ë겋?UòŒb9Ä+NK}g¸0Ü kƒÎVÎÑá(¢â »ígrØrÃ^®3¾ƒcYD9#ŠˆÊ‹‚E«QVvÝ¢œ$w.瓜üSL¡ptÚs¾%$'gf&''»6‘^"Ú÷ŽMšûž±Ë — SNªò žqÓlW²îÃ÷)_U5ˆ¼Ð >f­ûVª¼² ©9DÂÈ æmj·3lÞÄp0CStK·~e="Ù_å“!kÖB å¬$"Jœ+_;rN§”½¹O”ËÕz]d…÷Çc"©ënÅUDâRÉ?Ø`K‰lܾÒÙCdï­¬Òñª“R :)Qƒ®¤Y·ÇR~!ª  hñzä 7†è ÔpÁ=ñÑpÄlòâˆZ«”Ñ:º¥?ê3@t"Ý,¬¾Ã.½ØÀØe&O“Î[µP¹r—ûpÙØx^î&Ð]wöñ€öS,?ÜœPÚvY]M7ÉÝTêTé;0ðxµêÍ&ͽ«N ™½×ÃA‰V¾2kÞPF« ñ°þ Õ“LáPòÃv®29ˆ@Î ê/î ×hTK— ã[þÜ#x¼Ucxݦ³>cŠ‹ë %Á憀öÐ|ÏÉ Í€òû½Kž$›Z\<[r ['ET ¸½¹¨Ç¡¦ú×Þ2«3GZÿ×ÂëøCUaÆX;˜ññûx5›¡Hþò-º)÷ÔHk$ÛõÕ(xj_y èeRýNƒoéâ««ØÖ JmUB2É©c|ñ„~@vŽ–=Yµe鱨Ñ÷šl‘:ØpâÄÈk jõ y}ÛçmzLïø¦µi—QïrV þR™H ?=‡°Bð±‡Ê)aŸº€UŽNf¦Xô•²‹ê«Jo¿àÕÂ7ÁË;±D ›ž!ãëÏ}ÕâæþЈ²JÑŸ4„÷g&à§JŸ$KvVœ«{±ÓœúˆhÞÿ]±ÀWõA=Ö­ûÀ‹†¨üå„WâáišS®û_ô(|^t ‚Ä¿õÛ¸Lm1gÕ€££'ªöèf¶ ’§?wñ‘ß6ÉËÌ úiki’sÁm:³ˆñÏÇ©ó.‡²m&}=_« ¦+xè–9»¸“Õpø8—©ÃÕ!—?˜Ô•ãMÛ‚_ÛÍ}qs{_™£)Ëí¤œ©Â{íFpÆàk寕Ú,îÂD§}Ÿ~_åÝûiZÿ*CB:¡1;ÝÝæuâ÷tïöΪÝSßéꯇϠ¡Ì¸=‹#§¤Nu`ar&úƒµŠÙ<8òò®j²–է˧ë Y„­A¹eî¾?GXþjêlÁ ƒ!uÎÿ¤v§s+èÀÇ7¤Ðpµ¸{=­`!¨¢#¯Iì ‘ãEü°q¯ç^ïCUJßÛÓ¬ç_æ¼…™"G̶xÏ8èû¥hP §5{ZávýMx¤Ô sÏ\+–O4{É/ƒVsvÒþ{Ê_Gls?doeèOKsÅÏ 3O=acn&iœtò¯âlB>ï „UÙd æ|Û –ïmöJó°ÈNeB¦­ Šl­¼uîq|Þ²[-ȤÁVR—|Æp±_Ïy\1DñV­ŽÈqšÌC7*°Ò˦nÍ£C;ÔVÆl[*[çÍõ9÷’"6QYAAAAáûÁ††#.ìýù“=YÌ:gÖR‰\¨ŠDƒ:Ħ3ÈUÉt Œ¹lÍÝn™ª¢´#í¿Ê”âë#ÜJˆ2|WŠ* ÞFî\¢HžTö´›¨È’eš_3“”^´’Q銀÷+±–, äm¯s¿.¯#ñZé’6±ÔjgrÊ’nîjª|¾Fzç´M†§³U¸úY'õ,khœ¥xŠ\Sn$¬ŸŒÔeŸþ„7o¶^×þ §õýù Ò€ZvoÊ!"J›w¥ÂQ?»ÑLžKÙûÕìu©ô»¯ïêS¾-}}}}½wvéׯßx7"ʲäk0•Ùò<Šþª…0ì«e¿×ŒØ@BÑ͸×ÝGˆ¶¸Uˆ(öõul\羚¯¯o˜„hr;c yö8¯‘ô9v.Çg¯•;Õöï#¢(.¡îÒ ¢Ô¹Þ$ ÜýIr–½é×¹“äøøÛ±¾h°ëææBr©Û¯Ã#¥È§q 3•FúNÍÒ\XOžp€úBë8Äû#®®[þ4qùk鼯¾-Ù»|ÝYô4>ʆïZý¡ éHš4zQ«é ÑÉOmî>øœÝVÕO\ùE±AÔýÏîÐ1tP&x¬Ç±ñ2Ž‹’{5LáJðõ¢Q¾^FËŽßV·ú4Õ@>•ÆE æY´oÓò¼«b ì.ôÖAÝ^2Ü_ÐvÛæÞ–”j}Œcqúµh Ñïm§ÜØšá½&øw¶úºh°øÍ[†v0’= ùt @”%1hZWezæ~Éê ‰|+^ =ެûúÈcHÝ~@¬C7†ôæ[9Áî KŽ-`¡C5˜¸ä!LiÊ—kN=Àøúøçlõuu nnv¯R:ðëÌ“Cõy£¾~ªF[lð4A&ðÎP n™™¶dúé©Þdý›×+:YÞî8°[__^•Ókíªènê‚oO·Öì© ñõŸÏ?Âëã]`üöRVx}^èiXÔõ¸Ì¤YÚó"œ7p~о&зïƒC­Õ¤Úð{³¸$)ÎÛ_]tO× |ô™isj_À’Û§[œnŠ»¬Ã÷gk%FÎpþ"ÁàVY2ݤßԚܙÌô{e¥$e_î5±­C¿~E× ÂrGÔ{1^‘ùÅ ²ÚíºÖc‘óübŽwyŽÉ«Í ov5ÕD±Û˜ê›Ö÷Ÿ/¼É§^Ù¼¸YãŠ-ÃvÖ3È'Ä›7_©ÂKEòøêbsã‘ ì©$Ì–Ö#4Îàë²PƒHû>ñ ¿cëNnÑ|±@À™€‰ý;·àÑ¥‰NÓ×*ásb‚hËÙ`¹åµ[änÿÁŠ¥ªý⣗­Þ”Ö|s»€ÅŽ·”1ÆiæK»ð\àÒþ(XÚ~V—ª°—¥ÄV’/†ÑÖ!u[®êaVW–µ!\U8 ¯ mÚu 0«»U_íƒÿíNF ©ž3ôÃúvך@ÝeAoͤ:ذ?:·+‘.%.Zsœg"†®àM:á©«6Oʈ¬ ŸDÈ­¨× ˆ|N+í±ø­üÙÈu¿BAîÉx#Ör d|_9¸—§eë1ÙD$˾ÑSnU®¥Q´'ûj:Íï®ÄÔf±Öý1}ždï;‡(‚ ¿mbl·Ÿ3;‡'ñè™{‡ëáÇ_R3„ï¶jmhh¸cV?CCÃcAáÌ_:‘óÖÖ*Ûǹy¦2n‰¼lË‹›Šûp>T@¢›hè÷÷2ØdÿÝàæÒ M&ËÌõŸÝëþ»Äç?g<©°/{‚žø´I‘FVœ·}íQº2?G?ËXÃùŒÒ|àÏôx%çøŠx¾rœ§r3鲜Dð@q‘“ø£Ý7¨DÔBXP %ÊžªYå)«÷ùÛ?7¤s?ÃeÞá™´blxøù^ÜYoÆ]5T„Ƭ÷*Çü#‘Èzüg"ï¥K—‡ÈQ•u'ÊÉðq¾©¦‹ÁQQ£u§áweLüÕZÏS¨ø¥Ë/G<ê·cÂnež`ÌÝŒ‘]dW±’¿K—š2ßNò·2ؤÿM…„Ü¢îÛ7\¹2e©b"±¨*ËcœÙ¸ÙšGÅœk®H'o (,!(µÑòŸ_/ú踙¢r6¤µÀ¶ ¯XüL3auØÂ»² ?;•AEå:GÓ¤B}xŸÆ«åYÎW¨à›Jý̯2+®Ïßèiòý\oU¶½»weðN¶¤Õ¨Éwv'µÚÅ©„å!ɸ6r½:Md¸!kX&ú­EŠg¼+€Æ5nÔaRÜßx£0ö´/Ì ÇqÍb¯|NÉœ>½¨ÑŒ­À4"ÑkJ×_§‘ðªÌŽçìÖÕQÌ] 8TIÚM^¿½àdtYâ†J+÷¿}Þ*Ú¯¬üüÇ~µ># oªðvºFó˜$óÛå/O,ÔUH»ðf×Ix[*êjÓ¨\ÊØ’kmø‰i9¨#ŠéRíþã±p±“c®ÃGôðÕ™€ur©qªa× l½®Ÿçâ9cå×·Tw\ ®ãéíн–9™Ø7:Y/ÿ¥/Nwò] Ð1Ωò šëø:x0±ÈäÔyÉ‹¹p ×Þ-M0•«Üþ‹ÈJ­l¥/-¾ÖK[Ô)ÕÆÃ¼—.Kª¸º©Chpÿ¾¿*PcSÄå;õÇnÖâYN:«É< ½§Î¢f ü­„÷¿û'w#Å¢{”öáЂ@ øõ@Í€q¤ìµ Ž´d…U,¶Ç‡¡¨”í–z«Ã ™ª1ïÇl¨yåp[%ƒµx=Æàóm®ý¬"‘RµjYÒJ€íRuÓ©pà£ICÔk©ˆ‡ÏqîÚÏn€wé>ˆ©Ê‘×'wôÙdÜsî|™ùåЙZ‹ o_¼È"÷uŽÖï  ÙÐÔl:æ/ÄbÎÁ£‡+Â:Zµ¿?P½þ=@ºipǹDÞù•ÿ©„ د½8Áï¼à 0½5]àûä|ÅWb]Oíæ¼ƒ™ £æ±§.CA%`›.ï_çäŸ'5{MÚ¯ËÌÈ ™B]èZ±òÆ|·|"¹b¸PN-ÿ"“ÒlOVÓ³=W@2¢c¯Tgܧ™éÕT¹2úlH¿i¾¾i4Wä&UØg[Ux“i.Ñõû {äK¿~ý¼|}×]aCÆd¯*2IIb}=ûõçŠäIl{Ø%í¥ò ™<.þ#%Lþ·n–°f’ÕmÎLz7õ¢ {rp¶>ãGD[ùËMÉG×Kxþb¡æø…?YJ$¶Û”–î6ÚV³õÞ,k³z¥¶WŒ±5¼Ä)À“Ù­àÇeäøgaÂQ„­  ä7f^Òla•?ϨHª’ñ¯ ¥2"*Úä-#¢ILBXá.3ÉèÖzÅ)Ê/oË×0û†¦ÿL]Þ±ûÅ‚‚"¢²|¹àÛgÔNŽ= ôm] Is¦M3\RPP £Ä£þxiÚDó Ò}ëú(Шhm\ÞÐâNô$}µÚÙQ€¢²oWÂ:Ð3š,tÛ7@ù•J}ÙKË¢«r#_üðˆú/oè¿ê´«$xЊ¯üë–xNkáxMá…ÐÊqiŸ·M;³[Cj:Kêyj©£iÍSOñbf¦r?ÇO=’¦Ï^ìài¨½ôf‘øvdü:5þ]–È-¼ZO¬0îŽ×«¬ÔCÛ–âΞè!öò™ZU¶Ÿ@»Ñ4¹¶ã:`÷ùÓÚÈÉù‡ KÄzפ “$Ö¼w­ÿá-›y÷—a®)¿ ±“æÖ:91ß(­VÊë9µŸ–vMÛ7­J×òÂäJ­¡%(Ó)42•¥í_Ò®¸X¦‡ÌYY%ÅYZ%k‹#_ËÃükGd@v×Ê5³ Ýj€VM=Ê´Þ]çF:Óâ:[¢I6å©âE–I–$,¸ûجô9ã(“.8Ê'.+=çX ­r«±¸—þ’{uª ~­k= k)pïXÎÐOÐÖ­4e¸y›Ž:„~«Mwrõ¡ð¡º<J\¹Ø§zz[Æù'”sô|ÓRÃ×|Î7/G]×&¼º’üL,¨ß¶ê”¥vÍ Û›iÚ¥¥Ïºàÿ¨•#€Wö梻*ï šm¦ú°Jêá-ìÇ,¤áØJµÂŒ[ÕH8Ÿ9ìΨêY˜Ô"ý®¿·š¯Žï» ¼4/S=–u/ö¶BÛ6*ójžr ,tµ6ÌTÜ?^mȸt͈¨óËÆÚÓj^·UÐ)ÒÞNêXA¾ÜÇH½%.°<Ê£—uRN5íÎç{ÚˆÈt¬ÁY*eÏŒõ‹ßPµž Ú ¾ÀU•É¿w+âWÕvÒÒ+Já-?$>ˆé3°å½gÎ+ëÀ¾Ü ×,Ò²£”PÖĸÂ×'ÔD€´k²*}vÀÇœé¬";W1o‚Ÿw8¼ù.ó_Z²*k¡ƒ_hemÖ,eù¢è‹æTAú›Ÿ‚¯NFª?ce"8Žè•áø9˜ËÞ*üÜ£PÄ…\ lÒ¢{ÂÝÑ»¼æÿ›­Ì­ÓoÛã&U‹ÓæºU\¢wêñKƒhiŠ‹i1ŸÄYVæº(ĉ?ðãjþå÷”;Jã"³¦·mó”›VŸ×Ë›-­äŸŠó<Œ”2îGdtž<ݵa‹Ö††­ª6êp<222OyZð—½É,¦ŒHvÖ§xR¤ú!“J…Šã Û4 e3O¥OgÉŸÉrw÷H"¢¼áeªˆu‰2W®$òÑà÷áï4¾6MRÙÇWEDD…SRe¦ñ²;A£¿<™±ÝCNxGQ¤Ã2çTÜzÉßOxÿ|ô„>#/5Ûþ;òºïÅ^¦%jK f?iüMw#>!mÔ­íšg+qØú3v¿î®Õèã¨øjмž®žú Ä™§ÅRiæÆy0A ùNNN='MjüMùÚ"óKoÎxKÞS§N½óÒI^fµLé`?ÓBDôΦ$fÊ¡Ÿ¿œ|çr\¸œ©IxÓ‚¨üåqyøÈ‘Rr:­˜ÉûÔö gÓ¯PéxQÝñ‹k¹,pò&"ŠÚE"³aîË5]ãû¸¦n`ª5 <¶ÿ-àÕ×#lsôU¥§æm÷Šf‰Gz{ã]›,/°½MYœtO r‚œŠ«xIÎ×a¬ÏÃÜ\Qmôé'KÝ,u·k>V¢-æh†ž Y«)êÓCàVAŸñZ0H SãÏí¯€BI¶S& IDAT´€ˆw‚<àÉ:QÝù‹1a‚çŠecz¡ñ»#»œ ¨¾Pž‚'ݺ´ú9;»ªàIйrU]øøÍù%- ÎÈVú»yøÿÔ£ïzú·MŸ>®2¨àg¸=¯·æ¾0»qƒ¿vç]â6â=½¤Ï"Vu€–v©Ú&ÿèiʨ}Ħ‡î[½¾VÝUPd{‚k·Z ò,¬Ù< xk\.×jW­NÕ^Ë—›»¿›2+U·nHþ «¹¾-+9õ¶Zm±hÍÊ%Zãu“Ì4H¯™g{Oà É…‡,aS¯¬…•¿ ò —ÎMÌ=ýæRË»ò¢õˆ†@JÄö,?^/¨Wa¨>ˆÂ@3éó«Rwœ<Ùq-€mâ>½5\‹¸^g¦ÒÐçàáf~‹üòMJ>‘JVUþ‡yþ«¿¿ø”N‹¬°+eiÑù…\` }Cýd͹©ID”Æd2òßâÅÊî6imdëã¯ÒÖörÙsÈò:C_œ-¢{wJˆì ¸ïãŸCDtÇVƒJv¸º†É(ûú`ÀÖ=!ò=mG?–½Àlÿ1-˜÷À”?à>É)F‘ /|S]±«µ™ÃˆˆîÜ!"š±G®ºžyÂÝ•«E…<=²‘3l||ˆâ|ZøøøLï=`À€Õë0`Ñû  ãmsX9Ôw®°Ã“Õ~kêï”Ç4Ÿî£ÿé”ÈÌoéJùˆ›)$ÒГrÇTðW¼^(#ÚéÊ&µu5Ë›Ä+Ý©³Šˆ¨¤ô¥ªRIü7 ‘$/=---e_GÃ#›Ùäå3/ºì 4ønkë{°-1­§á¼<ù1bû‹¼X”ž±Î«ðÆÄy^f¦Y¶QÚd†më?KûàCDÒ¼«ã|ó¦4mí8ÍllþËØTeâ÷û[ª4bÇcŠûþ¹[LÂÁb*²!ú}}‘u§È<·k0 ·vÉ/T>vú˜£ÅŃbóòòòòò®7~œVÑÿ³þ­rL­¹20‘S~Ò©ÔÔ`õyõÏÞÐöë‘ L༊LæØµ‰Å_Ö&"ÚÀz Þl&Z!_¤Š·-“¤’Ò%«5ç–E{|pÝ;aĈ'ʉ„·¬øs;OQ «LFT|íç(iU»Ã0¶äŽãz—vi{틪ðQÆ ñVÍð^8¢þ²9Þ¹DDÖß–‘ôÕ¬·>œ{åùèùŒcð‘2Σä¨s§ÌÃÊÉ,¼Æ=Uá2MžqÚ¾ãìŠiv4‹TÞ¶q>ðc^tUíbxdΜ,Èô7/õnÏ¡¢ì˜Ÿ7ÙS‘WÄËÜc²ðza^®©#EÚ¬­P¤/Ï}ö@hȨ¼.AMåÜC-]Ä»ÊZ€•¸h%ÉD>Ûk›-k¿QEɬãy¥37lu†„I÷Co0ÖßÛ¤¬n[¦1wd'ïð·üÞ¬:LvZkh—/f_k`ï3WAëó;o·Z7­5{Î1ûÜ$ î÷¡Âؘ³¸_ÌmŸƒ °碼JÕù¶ ‹ÛY•ö¯´1c¸\°¯†h¼íLË!Fì¶Áq'‹Õ^+?W¾9¹æP‘Š\)½¦~L*«Îæcêw/{Ô~_·óNðð¿NÚQšóÞ²Fņ–ŸcºVðqC[5㺊  I·úóâ|T%*‡@@n€ÂÀôçUkȲ£ÂíTý_ Ý$ÔÖÕRa†H²ÕÇGF·É€»3vˆÄ3¢å§Ã¼w¥ .{¯2ŶC…¹õÍbÛOšjpËnmÔèé˾ÙƳºË|¾¨µW¹óx³ú"„ß\kúÔxº¼‡yÅ¡±-TÇ>J¶é¨¶„¥/Ô„Ê6CÎN¹Õ¼»ù´`³E:ss)·Úsß~FWš¦}'K¢;R¾¡kžð®D°±0|ª6€Ëߙܿ¥ÕTƯûŽ}GÊZÌüUˆð„[¹z%?CºÿCXecê}šÐÑ¡bÃ2íY^ñç!àÉ(ÖŒH ‡òƒûh«ó¹U’ÂûÑu ]™Br»*Ù€Oj€ckëUHËó E)Vè´-ùÑÍÀCé\žÑ€IÇ{pÛüq¤Ý•[V÷Í:[¨U³õ "Û W7m¹ˆ?ßÒUƒÇ[ÆañÚrQ#e°wŠå 'íÔ¨)Zf¦È tÂõ®O®@qp¾tNùö¿˜gm.›Ä¤! û¢ÞÈÙ_:c ¯Ì¿ÏzlV¬VL¥ôK@­åI—n×»ï æ–çÀÈsúØÑp w¦ @ž-“2ÝF¤d†ú¾&[}W¿cMÍûÞY|7_•g 8nðà6”I Z·ªWc^ŦY£sŽÍN¢8ãÜŠG¥)âÉÔúî»™_?m(qÏKr‹ÏTmj”)ì{‰XF¥·^Iíïhp)ÊW|Ó¸ÞØ cINºÉÊ„1††æ‰É¯ó•ÙTƒHþby„o­"s±… n–\ïõžD‰g‚•¶OÞru¤oyâaÃËBÎú‘¾'&" £–´°M’ÚgU×ÝŒY%²nX3‚ˆ6´¯ÑäQÖAö4<%$+–u1ìr?1119oJ‰2¿,34-ªžWô þyMDL’”÷u°+çwPªÓ3ÂèKý6;5õi±4I³¨$¥æøÜ<, óhs¬H’X±1oJ¯¾·(|zÅ–$ã Hyٻߕ¿¯+é$.Ë›ŒT§O˜Í¹(.Z‘øÅ=såìÔHb›¶˜‡›M3#ýß-ì¥L:~ëX}™­:(go`åíQ!²o)lÆÒ»’X9õWt9ƳFy¯^_ýƒ”~¡ùm"I’¿¿Y¿‰žDô};÷71 šSSÓ\eN  ÏçH4€sÖû!ñÿhÚKé’ËÙæË²CžV‡ÆxRÁIVh±,l»ã¡ÂÛ6ˆÂ}/½È õ Î´~æczª|ük×b±´Ng}h“ðÊÔe_‹ û¾:©ÏH&dGUßü¿÷óÒNøì2Ñ-¥²“pœLØË½nŸ覿àªRã½Õ›åèÞCÀí5QÕ*ðá¦W;q©žž¦K/— R°}¾c ½ÞMõ3ý£s5‘þ½N«+ÿyõïޜӡã-¦öU­åïzxzì¯Àßµ™¡ óÀÝi³:S¬"RøÙçóŒ@n¢<™×ž;®ŽÌöÛiøª¤ìy\¥^|×ëÎt‰»÷C\5q/ÃB¶èÙÀÐy Cb8¬˜1M¥ýiÅ{Õ>[ôÝò+&~Âm÷Õmàôè;O>¯bR<=^}€š»OŒã•T^¿»¬H¶SNί•ÛÍŸÑ-nY#ääì“ÏXø;ƶYkÙ#™Œ4æ_}¯^xWði¬œß{$1>ùÝ•Oèy`å–‹®ŸÀûg;«H?£Ý–K %¼5eSqø ­ìBF¯ÖÁÏknïß—þ®Ã÷*HüÅ=5÷=ûdÆì3€cö• .•/i7VhÔhvƒ–éâþ«ja,x°‚‡5c¾-R³¥®/«oѯ|Ž›©y£`¨ÝϺPrafPr|EÛ ÐjPÃ94µN ¢£ ßW1TÑÁ²9ðr—5°è麀-¸˜’É“àÄŽþ¸cNq´ Ïáò‰RpZ{B/‰»  5÷èÔªE[eŸOMa,¨l“zôc>B9v›+:6å\¯ðLi3+ú\öH#­âÑ®{÷i:@gÔVÒðé“I[˜WMÔš…ÕQÆcYœý§Ñ‹ŒfäïÐ;ä×róïzÄoRW,¡nB|…~vkÂYöDôò8“Íh¢\g5JÐ<òS·2’mêßL½ËXãükP°QAa‘9³xÂyÁLEûËÃ"""# žåðª]ºŒôŽŒ þze•Wppp¨i—.=*V9ŠwšCD”wæ ź/«Ð|ú¾\câÎn=;­Èå3æm*ѬD"¢ò{ŒÛvi9òcEÎñ› ãã1þ£º¬ >ìü^¯gÏIÕ»ôßð=:88Fn¿ås/Îê6QØšŒ_¿ÉE‡QÞ—÷s>¯Òºpn¿cTëÛ¦Íõ—IÇß\±%}JL¸ÌzY»½û I]w²ÇNI"¢4#M˜Nì½²­7‘ÇàúÊAÏÞ­‘QK2Y”2ß°§›D,!’¬à]âÉJŸ‡lp>m¥tu¤Eû34¬=R,³n‘…oÖÆ*Üâ‚ /DÇqIÃd?Ú("ò8X@²Ïñ~‰sK BâëÕ¬<õ!"ÊÙÕU(#Ê«8ã5+óN›-”„ËcO-N2ãmÊC+ØÒÙÛ Š%´"šˆ(y¼X,–ˆ³¾IØëeps¡ˆ¿c:Î]ڼ㛟E$ûseëOWâ%ì¾&µq¯sv¥µûÁßtüvõeE[íæy}Mr£uÚ%n_1šÁÍí»«ºd·niš ßï.—/ÑŠllÆN+¹bñhWw4'$)'æÛSŒ°Qy9ÛWáÎñz±-Ì{?ÁÂgä ‰Glg5¬wjŒèâ·Z+Ãèô·lÁñ-55¯1 äe,Mnˆ×kÿÎv•ÖÀg·ï·œ Tý2mVkäþHú¸šµ]C¿Î ?ú7ó®`ª¬7[¼6ÇQQþ0ùÃëÅ»R£¸<?’vi M™³ßÈsP[.Úk@Ö+®&¢>o°ùšÛÿòEffwz<¯¦QµùûÆ þ\ÙúÓ…WY~qÂÓE›Ÿ¼™ÏËî—J È‹—?wA;Í}Öù¤(©ÔØñ;l©¡Wh*u1ÖˆZæwA/Aþb_OVÅš{–¡vÓÓ æ-f2{¾÷æc›ßú¨·M'͈ºcRøø•Ü»`q/ Üqy- t÷"|Û ¼~ï3oL‡×¡ŠðÜ’­˜˜§ö[=ËZ$ë-ÖׄròÌ[²œÐ’O3€’9cÇ@pºÊàïâ°Í/W^ÅÁ½¥ pžó°ä[n«¢ÉtŒŸ8„•+€ÂôÕâºårlÊjnZ¿)ÉúíìÕ®w÷e­ØÿÏ–­ÁV¸eèÒÓó$·¼§qUMüÌÌß,_É>y®®À4M½3·—æ>;ûCƒ5Üf%¶Ù ëJZ‰æuÓ<ôÊ„¡¨™*Mp¬ý)²–Ý\ Ø«Ÿ!øÛåÕÛÔAÍŒqK9mÛ\. HÊ{cØ®’øµuû’ u¬w©8µÔ("»¾¾»í?Þ-Ĥu›MU™ÆuÝõ¥j ‰—]•œ­ž´[Ô™\¡„NìÏ•¿9}.ûÿñ‡bd¦ªnÍøÚZýÕòùZ}ôt 6™»-×öÍ4N|¬¥‰<üWK(E¹¸º¦ÛFÎÌàÜ iyûjÿúewkºévÛÝû{î×ÿg¯èi„î|ÇáâÅXYH\-*>½®*„<ÛQ!§m:j¨¹/ÌõDMïñãê¦|í3¸y«°d;@UAYCUóB"l}ßêö]¨ÓJ1&s²‹—Mù;ðhÁ:¶N+<­¼ªeV ÿ^hÚ* ?ÜÅIó£~î3»ásour¿Ñƒ›<\òüBõÔD`gÆÕN3«4lUñ¨‚[¹’Öf—ÝÏÌ6QŸÒï«öø-»s§€U—×`¾ŒÕ ‚ãgkPKŽÆ*Ì£\(KµU%ÉÓ⤃K¦è Ñ/_õúl»skfx5u)?FnCy 3­ÊUä"WäÙž‹Ô½ŽÜ§ËÑsv¨¶…B8þ¤#óú*ÊTÔù‡ü,ÝÓ7ÖéØáâ&V¤IxëþýVÕµÆJF´»T]q@•ùÓŽ;Žšß¤ ÙØ”»ª—TÓòyó9Ùý⳯®mu…ÄÒÍÚŒz¢×îz—jyëÅ.Õt¤éu`n@¡Ëçå)¿ÞF¥F”Ž–­°WÉ„çtoÊàŽ<{ç7 NvœñàÁØ[; þ k⿘³Îß2ãR­À6šVÂÓS™å]½! Ú[\á¨xýº‚µ~t1,I¡2í´:M#Ó«Ô ¯]·nåXmÝ©¹U‹óôð0ìéw¶þ$Q͉®ñ2½Áÿ½·‹j{ۀ[ì@ÅÄöØGEÅ;°;1±;±1PQE%DTînjf˜Ù{}LíÀï}¯÷{ÏyÇóÍuéŬY»ÖzöZOÜÏý ĬוXTצ]ƒraô+Ìäfta%ŠòÔKhîS•ß4nÇ-Λ{£„MÌd7;çü.ÕN™·~Â/#—11D˜4h[*îˆWñ™ÉXF©×¾+TîÿðÕ£{öÐÈç#;4Qëƒ{vfo»’³EL«+#é°ü ÖÛq­?#Îá;Ø{øyWåÝV¶aBàB/_`Û îd‘æý£çÇ|fÛ¯™ü«ß|5úÏ·Ãg=x¥¼4ÙÎîê ‹¿cCÿËW^y¨`6Ù$®«?‘§é´_ójðîù]Þo±·'u@ j×õ—÷9\9‹ð®xNÝ]PÓA-¦"ünÞ02Káb¥qÍVÉn„×qγ?*XDZ G°w¾s=k@r@U8![#-òêÉX=»°eWsv€í‡È&Ú•ïN`O á€û·#lÔØÜ^WÖ죺¢£ãëÛ_Lmú1Îö<‰‘ñ÷>&ééšyŒÈ`¬”£Þíõ!â¨êM‹R0ÕòÈQû%î »0^­z»}õYËg#ÍCx¹]zØí¹Â[p.(³ÐçΙÐU ÏÞ_/¼•×ÃÎ,:ÒF?v%#ùrÍ|â~^Ë“ÝÔ[ã•«#ÿøñ÷í6Ütä—y‡ýã8 ½§Cw!?ØRz-Ê©1þÓ8:›G'„{ÔúO¶,všÄ_“¤uí6À¹Mu>jI¹>|ÞË>þÊUe©±>C=èE-Öº7uê•ÄðIª…ÙlôâA»Õ;İa÷s"7·W‡ÿÞÅnÕØ îáhBf0ÑðE˜÷züVùˆ"5ÕXÅTÔo˜ªœžÅºµô@ξfLH–3T^ZÄšIµâì÷i=u¹¶ÑOWú³Ý&?÷ß¹ðw…lÿrá5Z||á½­+Çm´á_{¬z鄽XÖˆûKÅ®µÔÎQͺ§¿ª)WÇyP0SXÎÂC«Û½zÂæ£ÝöÇ$ÍßÝÖrt:Ç/ð2iïïY5“­ÇT-ˆØ]!]a,²±W»6¢&ùzpêî4¶_ùëÕ£*ÇVî*á}~Ìžã¹ÅüÒ×'Æ€pÀ.úBšÆy:…¡5N}£MG!¾K•ºÆ‡ýèÚkx³Æ0£Ú9™LìóäM ºü|²ØRß³ˆÏú@Á,têi lÒ‹öghlÛ¸;‹>13ÚõXO¤þä·´~nJË:Îyî´üÑߣvîþ»„÷¯Ž°Y -šÕ 79ÿW¢fòÚdÃy©¨Š'nù„Vć8^FÄkYñÙü¡Ù„ıRªGŸ2°¦)³!•›9á·ðMaìpP輟ÌKI$‹¬lf¦&§ª‚Jô[B*6«q…Ô©KRv(nù+Í ‹ÿT'@¦Kù#P•³¶}…²ï‹‡Ù±ƒ™ÈؼääT×vÍ­›ÔUål:%'çTÚwK+˜1ˆòcc>Ó„…Êz=?1i‹?…ĵó’ää|!D¾ôC¤&ü<>Ÿ¬fò=Åìc!S•T9±s‹)v¸V4ͬ&—!;[׳«ÙŸâà/^­È’ŠNÔì—‘ØùÍ/ûÆMâ7¦;hD]-¬ç7çðú½ÝD)^ý• oTJ!£éáááJBù f©U*Mò<䜪h?§*Jñ.-ôº,*üYËvѬ ´óGBÙú@)Ì åì0¿xÿ3í5ék‘RB ß-úå˜ P¦úoõ¢’FìÎà„]“׌妣.`} Öb”éÐ6ª[GQŒcuÝŠ¿¹wÖ¤òVí}Mγ¨ov1¡Ììò­I»!jÀuhc«ÎÌFö}¬MÈÙÎå>ü/P´jiÉ>“Ù[n."’ú¿ò¢…ݽÃkŒ»¾U¯Píäòë‘«x”/ *ºtôõ¦•µ,мpì>k@ê^ƒi½ õ»eè»u™Ä‰%<ª;íR½ÑN•†øR Ù—‚F.Ÿ÷2Õ±W—Þà¸~@mÈóµcí¡å·›Ail¢rs¹¥çé¿óPg`u”÷OŸ½éÞÏøÓ³õËZÍ`èö©a!Sm9ý½X‘šÂõ¾_Bjè”6ª[¿í<·ü˜T¹²çzþO†‡k½tS¨k·‡5ª O5,,Vœšo*Õšn7,OKªÓûzåXºãç/Ôyéë©ÖÙ[fœ½!ZѲúÙž¥[¸:ò1¿{Êd37(„‡Q;€Vh`§ŸoÊ+)*2&ŒÍ<”c œhÀ®ãhÔóD+ι®R Ø7á%˜ БÓJt;l˜wÖž)»ä¦d  ™èÛPä‚ÝÖ NÞþ†m•¶¤¾`MðC÷VëâÈ¢žIQ{9ÇðÔŸÜðbÀÚèsoì­ýv·Vßâ‰Ña:Î ç²Ü"öªiŒ²åº·ñâkë|Ë´ÓeÝ`¸Û¼†¶D†I'øözT1ñ·¬E'Ö…±.ªw¯?ûŽŒ»'yz3Ó¿‰ð¨YÞH¾Ýé€Ð¼ú%§Š¶ðtþ·—òð»{›ó’q/Oé ÚÂYw¶©œB ‘AÜ}X·´â,²"£«¦r<9-'sÓwÜy@·];`¼>jÛ\—~¨Þ0œ °?áaúy)?w¨9xœºmàúcæÉ´‘ÃÌA0A Þ~wG åÇ>$nµìÖí¼ë“i¶7ÃôkÛ¸'/FŽå,§L…Š½ÑµWƒ˜¯šѺéëJÆRXáh9g0ñSõ¨q@Ñ/š@9ÍÚ¦XÖ˜Eù«âyÕ®¼m½µÕ©Âk 6â7^³õ§Z†•Õö[÷«Ùñn|z«ךq›öמÄëö<ÁI­¤´‘¹å盪þ2'e±Ÿ`õi”{Ú*•Œ­šêíȉŽz F²Î\޳³[k(¨¥^y—°‘ä“.©—ûn à¡u7Ùå[Îpœð’ ‡e·¤™Ê7FШ€ðî4i“€WÎ(^§Ì5—+߆ôI/u¡nP°A·­Zòž=Ï{#Ë1âg¥\Ö‹–7RZĘÉÌ#”öOi]2šé “z=ßÏ«Çuïú,Q'óÀÐ=ÕâÂÎÔ¿Õ惘èí~áÕ¡xS·÷¯ô]¤lôä]=oþ3îðH¥Øs½áôë÷ÔìP‡Îf{iºµ!:Ê:êx>Ùk€iý¹¬eQ’õCYbš.Ëço”¤e DŒi̹ðŠuĦ¶Z=¨×ír§‡udÊr/áMmè@cŽì"äì\݆±9ѵtD»u[zŒŸ}Ô§o( £z·ºÜ{;¹åþ)u€FMLP6 Nµð€ò ö,ù€áB@Z¸z[;@üš‘Én©ÐU?†xÏ‹—~íX Oý^›hadÖ7VmFõjœâ obÞ£³GµâRr$²]÷ÅËñËFâw^ÔÚ½gýÖŸíŽ÷Ä·,ÃAêÍî$¿›àvœ‡ß½êµ•§2¿Óâ'ÕÛ\¬Û%­ˆSD˜ñ†Ïk¬mljt|ñˆ|ÆÊÝ,:&ÍyÀ ÅÏ'Ì»/Ò>,MŸè›­>¼.a3ŠïÞŸQö|>Då^:ö÷“ܾ˜,à¼ÍÔYƒq,?ýìe¸™7@™Û–Åä­ú`þhf; ÞK<¢7¶0Œv? ‚îµ^íÑè&Ñ#n#S)£pÊùj'Ù›ž¤·âuhÊ‹bËßJxÑ•…ÒÊûÝqMÖ–} ¾_ÌÇï^¶çáwÏ­äÛjYŒ˜}‡S IDAT‘H©îS™˜ï¾å[GÀt‡« ¡Ü•S$~Å÷Z¬D¡E³Z…¦4€{sÛ2eAðÌrü™îÃÚm#ë2wm:ܯh™Y#íœç_hÕž}¿žÑÎÀ× kãÏˬ+u–¸+6“uѯ_Úë?™©öÎw%ç;w-¿LÍš†fGƒ>mª¿u²íµY5P×¶>ójßXm)gBirò†­Ûw—7Z¸-b½“†)íèb«NÚ뛊ª7Øä>±ËªÛ¼Ù¿ cÉü[z¿—ð²>ò"2tzÆÉB€„ÎWøò:T¦}âµE7¿ÁkK²d¤TÅõPžÈÒÂDuz¤&g-Ñ@nlXQƒÆz ÇYê=P@HÆÐ7·Ð³páLJ]¶±WÿˆwëY¼€‘7h¤Ç÷¤˜ ½¦£%cOÏÙÈöäúÜÙ\¨ÝîκòZc;)õïô™½•Ëyãy9ÇB4‡ˆf߸ôÞ´yÍëèÙ5<¥ß|†_lCÞöÙ·ßK°›ó‡Ú}ò9‹©ådtDïœ!Âñ=Ìø±XÐ y˜ÌHC)f’Ç“t±Fy»·à ÌNàÎÅ×méæÀ8ÏBà·^Ô~Îx™¢H9ÌÓR{Wnòƒüá7.¡$ý)’U'½`ïIˆ§qÞ„ªs«å;ŽY%3Ÿ"£øÄÆB>ÔÕ…÷¥*ƒZ¡Ð½§=[v³\.›0á@y»¯™ Ò©i:Ý÷4.›Û/b*Ý\íh© cóC¶3#tßúNà0JbÑsª‘D Å _jyêêÔÙYÕ}ê"õTÔv[Ò­oK•{C×¶Ëà+mfÏ0ˆáæ“‹±$èv#AJyOdh4å§–å Â-Ôpp8såLòmôYÙ6F³ œb u¾æ«xûñ.M æÍÚ£¸Ò?Wo@_êwÞœÇ6Ûú¼ .ù¾‡ƒO¸qÉýÀ5¼dß;À¬p oZ+ÑÅ»&Ñ®G”@X¥8?«;P‰ØÝ«•b%*Rˆ@…Êf¨æGG5¯eëÙ×sîÉ–E·¾&@˜Dþæ=îu;½Et™YÊîæY=]V3Ý¿äÜ¥Žª·Í³ó·î-u{É R˜!ìãæÑ¬TÏ`än[`¯6Õtj9;Ÿ˜¬è=:tP yeeB)R.ä…0ßîæ™|)úÝu¡Ä'°´6PP:œaRM&@NDÀÉhF´®²CµXªÖÓŒž@4õŽ?§û2nuÙÀu±ý†Â+œÑd¢üã€Iúž—x?ÆÝZΖ]Z€3QûxöÛÓGØ#•_uwCõžM€PÁ÷kÝûqF4ÄÃA´ýhg.@'eR*ÞlØvHày-P’–Ã[wñÇh“  Kû}DÀÛÿHÅ»;4?ÛgßÉUDðÂŽ hÇUM!Š—ºÍù›]I:ÏK«íÓçú[M(fn…ðz³QÚxÀêÕî7ŠýÊ{ÎÖÐåˆS%hé{±'Sv+ƒ4e|=v=éÃOû¾(¸² ^v`Æ~J)%øÜ †‰†ôŒœK…§ÒÉtÑs°Ñ¾ºY½!H ±ÅÿÍço^‘°p!ð>` ¿{s,{ìp‚Ovï¥pñvÆÁµ&j-.꟬ã(N¿ KsÕÊÂð;å5@ (~>˜ãHý6•}ó,z S Ä£5£Ou)…ÆWÿÆ{?ŒeJ¡oŒ­7òk?ŽÝÅ>ãy‘öëb/È:¨»«:ß÷Ü‚Ûëz«¢1˺ç¿=ºƒq/¶xxoÒA©vµ^c Q,¿FR ’ì5 å–åâæÀèOÇôŒ¡Ìž×•©§è3ÄHÊ r6{TYS;aýu õ„Ù: «Ð¡Úi=süÃÿ•ðþý´þ_6ó)"˦ûòÚN-ã—踬˜Û”Ñ)’™]¹-A#.jÙCÒ¡ ™Åé{%‡Í{òy-“™ÿá¨QzdÔŒ«Zù„"$w~ÊÏ–/ iY0þ ûŒ×¯08K –ç"™t:ûWü¯Þ‡î¨˜FŸ­&U 6j åêÍ«u뢳¬pbö7lÑwå_¹“$ï·³Ð^](BˆìôBhæ#~[ΨEC}zJÉ›¥¬•"ž™Qým—¤ÿ_U‚øÛ…7qFÑ:< ¤£­àÕ¦_î(åÚç%ó(dU3Éwpà²ñ,÷¬ÐÖ˜X¿„¦ˆÜ!‰P,YÍR–¸`¼Sç)™qe²à‘66îñÛöUFÁCúê) !„ÌŒùÙì±lBÅ™£l{4.‚B2™L&“I;Ëd£ž”Èd²_°‰óg%Ëd2™¬üþi9þtêw¹\&“=îe3+‘÷è¤t»LIÎ ¯®b³iˆ¦¢RV§i,®Ñ 1„yÿEńл™xê¨ù Š,éa1!òîÇTd« òöù»iýã×?åµe®»]“k«]”0áöóñáÅ5ÒWU Ý,r»¼6Óøª²­êx¼€åE.Ø5uCµ˜?W Èݾ«iÒ¶ÁŽí«”¿3œ*šÆéPÒÓ½÷¤»…Ðb>)o•³ùÁ¤‰è0èq›R%ýe_ú`pþÊ/;gTkÁúŽ@ízlÍ7¡Ôã²Ëš%ï6˜6é2¶­A°õ}µÓS4ëûÀh­A–évÛO›\QÿÚ fH<ªv wÊæð•É,RbÈpi ë˜eÏí¡VEjâ?íó7 oе|[íÚî¸È¯D;ód÷%?&}ípbEXëƒ÷ ⺩…·àÞÐRƒD¦ðVÞèÊRmÊvZ+°e÷u­?•ÐB<½W{Àð ë/ ïüJ–µäžê¬VRá Û”¬ª,ùï¿Ýî"º Ü­ò@xŸ¨to¬zŒÕ'M»ªmʬ@}ß|èÌu¥n?k»°bœ‹~„Uô½ó(ÆuØ/ÆÒï‘ëû'†#ëQ´ÿ.fb›Q¸Ö^+tÙh|°Uzãê1TkÚˆñ„Â6ºñû:ÆìçïÞ÷~»x\ÉgÆ´åÙe×®ó‚ú÷_]ã6ÅzLoqÙÜ«ÝàÄ–êHZùÅ^ƒ êͲˆ —±Ì.éý/­ºq=–,[Î{x¸EPš¸kš®9NQûâGª³Ü6=½àà8!Vø8Ûê¥÷ îÈà"£Êuî$”T%ÆOn æ¡^…ÉÖú šÝåêéeMl½¾@ŸŒË_Wk½vc‡o¤®OÄãHÃ1u»3ÇÝpæÍZoŽO³†&«` %ÌØw cÆn@ª„'joüÿ«\wýæñìì‚=ƒyĵ—tàÉsúnSÞ­1AŠ´ðÀyÒ @Øð«6$}„9œ#w¯Ÿ2†ãñx’¶ZGå1ËÿæQ^{FƒsûjvcNì¾pØ  èa˜fÃÞà œ³šHJïÐ{›ÖŠoz€Cˆô3ºIãë&HÃzÛ}éÓ²‰ÀÑ~oð®ûl^<]¬ Ñª·oÜö5âÚžÙ{Óµ‘ªï_O·keÿj;z°Q@µ³ ÄwiméSC5B¢„¹›TÖb,.‚L×¶+kà?øó7ê×q «±³GÇðêÙ_ö•×ÍË…çg £R)B&ºup#-·ªÚf+3"C×h»yž,ãU¹h_ aç[Ì'Dòy…m箓^çÿÿY²á ÛªúÙ6^cñ)™ƒU¶ï«"ykTUc[ #s§¨SéŽÌ³Üse”̬è³)Ÿü'þZáuÙYF^QùbRÆò ß’¼1zCYÆYÞ‰ñ0C!’ãÖ,ÀyM;½KúÓ´æ~áÁžœ¨KıÇzÀµ™LPlVÔƒ! 2z—dT}­Å%0XtbU¶ÚÌÔoýx©Þ<“ªÚÇcí¶±NNÊÇÁOór·-;¿aFÔë7 ?t›GæõàY÷fÜ49£Õº0ƒíŠMÎe²½sÕÍ)ýâÌ1it›Î[EC×ÊÞo2;=Š2ÑÍ'aZ”å¬<,ó’–Å6¼Sc¤e–åË?FK³’¯Íȉ+4µõÆÖ.Hë×ýY8&ÌÒÒò±µ™¼Lf)ª43L‘ØF‹ÍˆEÞ‹Ìνz m¾ˆÄ$é|òš(øDÛèÖ´fßÔ;ȤRjP\ªQ‹ãƒ¢ÆäÖïª#P†e××.h-c—08n< ¢Pr’f£Šä-ÖtüB½¸±ài!yýÙCêµË€Nã—Útƒô3EëU¯@›Ë8þ££,ëêÕë÷ék¿Oœµ°ªs—^ºÀ‹€…#Øã\ìÕè„UˆÙ4~ÔÉG)‰K2.4¸^ã䟞#˜.¶"1‡[¥§„¤½–V'Лo+R•Ö‘nû-S» ~{á% úú>8 J¡GQ†ú2Œ´3vÑ!GÚuÎ-²vÑ3î”-ïZØHäÞý¬ ¡bêµÿ£6­;¢ªÒXf&ºj²®@è: Õv>Ú]¢Z?­ÕŒï´šj¤ º‹{D°ÄÁÙ‚0ÄP¼×ßÖ Í‹5§Ð6ˆ§V±y²Ã޲,—,Ϲ*ÈÐåP4¬‡6‘]Y uö»MY'ˆ<:GIv½~½FxSÎôïÃp®’ÜŸ®;^‹ŒÙÂiÔbmIË…oÄz[Å€õF¶oñ…O~Ø#ƒ½êå4ú…ã×p…Ò±âYß|#rê]‰`•¦U0Q¾’v*ÐZÚv½¦o <Ê«»¢kçç¼Án‰u÷ß~å%ŠÜR âÑZžÁL9œl @í°F+À¥|¡!€Ö@{Ð5†^T,± 5Ô m*·íT —y•ê²Õk»k6æmÊžvžn  sýÃ.kÀ¸Ê_ép3žÈÅ8³QñÔÎc,wí<¹;€ðÍL˜k+âxüC:ç´‡íþËÚÚ]…ݪeJµ<.M8ÊÆÌ.’$ί¡UÓ[œWq  #îQs*@õí:àíK çi}÷§ ú³}Î8·cÌä¥5 ŸAYVß¼N-›-¼—nµ\±˜M¼E3S©éd©1­î?_LÝÎÉÍŽØë×ðÖ^«Oã¤ÿ\h©F]^BYž„¤ØWÜÆãÑ‘™Mólµ­Þ¡ŒŠ “••0AB˜Vߥó„Tùž’pâ°Š{=J!DqÍEÃŽtí44PáΦþ©¡¤òÝŸ[è3ÀÆ!57WB!‹–¿}Ùš#$c8¨ ňµŸJøB!„HVI«nÈ Bm¯—«¯u"¬Û¸BÍ¡òÂÂyr‹+ rss‹ý|§N ÍÍÈÉÍÍ‹[É2…Ã/0Ñs„½\“,#òÇ“ùmÉ xxŽÊãëøþ°W«øðˆ9Œ’8ʲVRï©lw“÷EB.oä!!^;”*¥Òc—Ê’®ºuÓ©pÇGŽ›`Φ,}´jÕ»÷¸$B«^è „'uùî œS>[Âøòâ*!¤ÐÅ­üWÃuÉåapè²4¾ÿ®è*"K ûøñVïÞŸªéŸ¶,ŽõjïyÆN÷q ª ÕŽv©„¸y2É”ôÀ儸iå„S„&ýÙNËô©‚νÛÎ/"ÿoƒÊxñ¸Ê ßZÁÕ#ȹèU¼4)¯'x1áÛεµ¹ Ùôû[‹ú™iYœ+eÚ*?_|\L•Þ‚Z™qJƒùA§2NÑõNœt¬ë:ƒ¢„4ø¦#çŽÑ¥¶@SzzîýU(ÀN<å­Ón7Îή/¾Úzò/Çk–¥¨=RTsί™æååb´úX]÷d÷9¬ôêÂä‚ú°êqH¾J09fÚ‚E£ÈbDÒu²dÆøqgŸ1§Ô–™ `EÀé±SœŸmú2ô_a{ÿy)·-åêh~÷Ä‹«¼’Ä÷’÷r›îMjÃàC“䨺³`0ÍVÂ*.–ñö™£ÎÞm˜Ù<žÝ !#vœgÏ>Sˆb‹%@È9 ™õ4E9lJnúåºl7©Ð7߯-dÄß>bùµz~ެ¨ûŸ¿¯ð;¨xÍÞ€p†ëFôµfÆ4[ƒê»çïÊr ‡ÿÁ´-÷Ü„ jÇÖOa3ˆkÒ ™99õ }s¢26ïZÈΑ­Z¶ËÁbzA\‡¶ÿšðpø[~MÖòm3X«©ÒÇ©ýoy²ë‘µ”‹…(\1”E%7°rqO0ñ^@ýkC¸ŒvÙnË4ÃneC õÞfvÍAé¥uVœ÷ld3ÏÝeå;Ð¥¾àEãa¬Qó3è!€Ñ7•Éuu8ïe€-ï]É¥‹?výj¸Ö$ [WÁ¨¼6A£ÛPÜZ ÝúWߟ¾XÈÆ–åü`9dß·Lk­É·ÿ&jˆØüy æ:L 9›ÿè¢'¿[é¾zƒnîv½á¿%<œîÄÇï*^âÛäÔ+žýFûoçÅ“Cϳkb%Ô¼`Þ¡—¦ñeš&;JQìzɵèF¦S긒”¦ ]yܱt±Ídßøø,B ]ÆVù"G>QZ–eJü×åìßé‡{Jä2»ö66666}ÆÛ^һŊÁíÚÚØØØtý,—Ë5¤Ãr¹‹MP|J!„HÒþì-§ñ]D!ò¤ÃC"«#¥¾õds«Ê‡2ÆŒ’/\É€þgïñ%„\ cÞÞLæTx†È‡:WKF+Q^´öÏX:>ë_&$~ ¿-ÓÞƒg«¹Ú~áÛjKy „ô±AêyV¢‹w…ò¦Ô«½7M"m$kò=WfÑ <žÞœ‰…„*šRžsØ´}û¾Ìw#£ùq¶kbÚ6õŸö©„¨þŒ˜jADÄw׺íÛ·ï÷ŠaP]ì«åþÝѹ}ûQ¯~F¤’ý±ƒ«XoaçMD:V,¯˜Þ;‚—ËïØ—Óì¨}^¬µ€!‰´ïJB©ºÆ¼ =)¼/_Œt«>ËÃÍRÏ7^v´iÌ¿Œ|ù1¯-þÊ.–ÒD PÜô?Ó•Ûï•ÏYnSÌ•}í9êŽqäë\t#ü#Ž¥°#˜QWγžuÂãB“×S8–GÅa§Ä'ËCC–Þc8—§­fße3j}Ðé)°Ú^åU® ,EüW„¸±i+®~º8{˜Z¥Ù½ÀÓƒ’†}q«æö¥,ýo_n1ÂÕu[S0º]:³Î¨>,òžäC¥œñ »~Eíß *x5qY/† \é9¤`q÷E—2"å¶ô­v"ÓÈ-'¶Ü1 ÆøÏùü›äSh¨"Ìzï·W—g«ÎVøÀõGμ€ÇOö<öòDT²ÞÆS4SâI LMs$€ÙÀíº@ [TqS—,áuEËÐU£kj“[ýWÀ©R4O/CÍSÙ²K=÷ߨÆé€Ã39ô¬U6öÆìnvlJ©¹–—ºÊßÝ¿ª˜†§Ý“ËoLF¨îÝäÏ‘rgôRWÌòô›É-ï롺÷y6ãÿè[£ä]fú¬’h¨V %ØL¼=ûW€Ë%ÝhùʾÀo-¼Ïˆ—u?°@üõüï‹Gs KO|ÆÛøŸÅ8ñòã§9ò(÷0'AÌmz˜¼Ü(LýC{Ù¤Þ­E^BV¤¯BãcKÈbп‡Š©Ï ±Iö§SìûM=Ûƒ-òq×—±ÁÙçf3œÂþGÍo ÷ ƒjÃ9ÔŠëÎ~¸%€'X*Ñ”åšS¨œ6û£-`ù?Æw°>ú©¹zš †’¶_º‘»­,zÜŠ«i•Ï3’]¾®ÓÂHŒ›ÏøqÉl%N¡‚°PìZx|ÅÊþ«ŠZÿbéþøH+—ÿ,áý_¯€Ùðò€Ó·EAú@ÚP/ç§ÐL¡Ïñ`)Ä"=CN œ.°$ºœ{,4—k Oú2ƒ–z–%‘ÂåWµ, ד%×)­01++*¬ah'ÿ^T.7ѯU¢TòÌi]@P¯mŸ‘ª[ª<–ãb.0¡ìwد•ìjÞVÖË-=_c&sÕ’¹™:ª¿—– |ÞñÐÑ<µü¬Þ"6•LñŠ}M ãè:MŒ¦âØöêQñ3æN©ÏT¶èÊÕáž ‡’aˋ棜µãêŸEëס&WŽ[eaæ0Vfñ¼³õTÕœ‘G†«‰±ófmw˜˜ê—¯ÿ‹™¥ª„ú¿ùÊ«×0ØãT]àëéXÞé§sk¸Vù¼žÌSZ_¿ÛÏ‹MœYÏ Éå?ë`;Ñ”]àùge‘ÓœcÕê`Ì®-\Ö¨²{ÍvnŽf]÷Çá{ýÜ;“½ÒHÝJX0õ:d—ªf}%‚Ñ}é½¹]™¤%ß}×°e7Ýmro4ìü.ÕЗ^kÍð¥¢Säíŋ̚i@¡Éú1ë6Ñì"#LíqôYûH=óVæ’ÜÄ ñgAôH£)„˘ZÅ1g• §_›%ƒêEô±;yÃ'… Ý[6ÀÖrI-:HϬ Ü\z‰e:ìaFå¿ëjL»2ÖŠ­zêï6Ô´˜ù ”|wÀ?åó¿.¼û»:ß-ååùg^å×ù¹îµ™'»÷2y¹–)·&ýÁÅà}|2fÐ,ˆé·pÏ×Z¥RˆâïÛ÷äº1“‹+¿í‘+/ÄS>ƒ—ÖFî'„+NÌüÁ“ÚðÛe”¢hn,ïÐ!„tHÓpß$®Íäô¹=;‘ÃjÔ“ƒèZd4pÈQÿwD×âw„ŽÖÖ:\âÏ9å„qŒ\ÓœÅß!§.gürƒG 8pÌÕïüýýo÷ô÷÷oÛÞÇßßÿ}jõýO®bÃÔn¹0kd~Ú¤Ôª;ï™AŠþÊ`G!„ÜhPÇüs>M"ýèQgHå¸{\.tÅñø½\^SúMØV#N[ùd¥õòÑÁΠ¯Õ*iï¸õZ½¬V„(w¸ÃÅSWíë¥L%h~VMR²{+›˜<ßr¸)[áÝvXíëÈ4ƒTêþ4€¹öz{#mËIê\9²[N[… ­±nó*B¹‹fVoQe·ÏÀ^š¾±Ž¹¡@ArÝ6x¶g͘_ØLŠIN¬a“Ob\Mò£&Z!NaY e3•£d? ¬9ª:Ò|’οl嬦&kæâ{¼˜ðÙ©?xý^ó@¸$i/[þrš*N|~¦6=^ £¥!äÊjŠ„i<|ÅáuùœÐuÆÈõœ@~žÓ%þ}Ó#BhŠ”…~þ¼¥gÏéäûlv 4cE!„Pêj©Qû9+d €×áûÍÿÀï=K!ä„»*4í³²ŒRºç``µ(žöcãú]a~šÈ¤`n!t7Bâ§TT{Ö²=S‚dÿ’•Wb¨4š>y\çý–°³íîkã~ù$ºH‹ IDATK‰$àÙ½PôÅõ¼òϨ,£ïÕmOBÔ‡RD ¿Eyk/)½Bu:½R3éÎ!N%÷[-ÐÞuBXP£ØïRÝg³\Àegú¶aUºd¾ÂŽèEÞ¦ÔYi_*MËè9å9ûš›µâ‚ß_3Þ|V­Öç/%tm  …àÓ0Àtû¥ëñÖÕT™ôö\;ˆ»Éf±DÝž¥ý»$…ç•âǃFÕNhŒ›õ3ë:¿¥ÁFqÙ°i¥ÑôÁ=o,*ïK¦s½’W.îàElÆïã‰ý‰!6ܶī£Ôv¼Ú»•®9T—PW„è ö<ÿNµÅ¯¯óa4<«³œÓéø×+*>•ìæœÍ¿ˆˆ@S†PàRƒÜú.Qa3æºPvÓŒw›q¾kÓ|Ÿ@XO,6iX °psž‰Pšþ–õjÔ¬ÌcMwiöø%Š=/çØÍFGüQÀBÇ£¦´â™½ÓÙ¸Èb1Ìdf_ŠQL‚Òeù¼ZD>žõ‹ÀDà ²ßÓÛÀËÀSJçWßù¸‘Ê­Æ®Üúèzq÷„2—q….Òã¼#U›WhÌv¡ŠzþVÑ í ‰èädšÄËÏö{¹C“[i9 t”x?ŸÌ;ãwLOíþ$1gÓ™ÙÀN… ïS7±”úôKTDØ£½  ~ÛÑ2#kk3@`abe¦àÔ&£šÃYjo¦ nyè´À¢ºl˜²©ãüþôɦèë•RD3#/Ç>d ÓQŸ½œ8qL)ÓI—}Щ çT²9—–TÞù ÚÔ0ýý½ 4!*$`šcÿ×ɹ ^úDs>r‡˜nø–cͱÒê¶Yƒ ¡yâRÆ¥ZÙ/”KÑC‡Œ`"%Ÿ¯£ YÉIÉ¢½Vý¤(Š¢ò§ÚØØt¾38.ŸÈz¡¼Û9Aõ»¬ù3à!”]Žš ŠJŸecÓÙzhllóAè‹g%YãµÙ¦•I±±q;Z·nýžï~(ˆ1¢sfi˜˜²b;üùSD¦N_N§¹£¦o*h°uæØÈ3!ž ›Ìê§tO_ ÑôMæCéß™îI’\œñ©çc•'&a´rH˜œ?c?ƒ'Ii5ëÈÿW«9MÉ^LsG¯hÝgÍÄÐ$k0MêÙfæÙ•ÐßNXóY© äapPÉiIèŒ$t®²¡"+æ§ò³GתmÛ¶mÛ¶ýS•}(ý'‹é‰duàÜÒÓÚ¿¿Î/‘ŽH)ˆúùuEÛNW! \T³ìúQBèwÛÙÏ[púè•îccŠù~³îGŠ]>3Bú´}C!i/ÚŸãöέN¸ÎùÝvuþâfLáMºÂp¦ ýÕ¼®X^ö£þnêí*#Ô/º¨M™”UeþY›ŽŒU¢®ˆD_»¯•í5]©^åjG׫£}˜' ÏKN®%Æ^Úf®ÊrÔtÍ¿1¬'ãæ&ÀûÃah2%ãNZ³tr¡¡‚NJ<ÜY£°—f‰sê¿ÌYyê1PùIJˆJaêüù]ÔF-@ògYºµƒSð"è £^k³æLZ ó$(÷V´^}~¬ôç ž{Ô1@`R™ÃDÝ=K­9Ž%W>M7ÐÎîß*Äëv‡iŸµ¸¡îØöxv,àÎLñ¡# N¾EYþ¬:1âS3’k4°H·+@lôÀjêÖ“ Z®­þ³#lô¡òZ6¢œ*’å „½¿´G$×-0VÐ $&Da”x:jK˜´fÊJ½„ ™17±JyÝ*  mŒE£’JºX—†µ^¦EñîÕ‡(0!:D‰Æ}gþþ=뢺 ’]õ…éÎØœXÍ‹'Ðï²6šcƇˆjQÖ7M6*LðýsŽŠ§´‰C3HŽ´gäF |y¿™ ìôm¾˜mŒíg"Í»< ~¢B„¥ê¸uÞžyÕûÒ÷Õ`Óðí í8»§ý€ÅºuQ^ÒDÓál3Ü»÷â3,kÖEºù„ˆ,]È}r™gg+ñ>b5b%êÊÂ6ëH+Ôž—Ï ôåÁGÞÎ>΃PaÊáCHúóŸèU¿àj>V@³uþÇ[µùOõm©[¯¤aû²’ ãºåÑÝ߇ˆ6XËuJõõDòÂz– ýFçò— X¿–•IM})1Õ¡Q[—xWî7Ò`H¤"BÈ|¸’{1jã!¶OH,lìÞå÷®“½—è Ší¬Ê:£õ‰LV]ë›_1ÛËMúÜ<’³èÅ¿àP̼ÇÆE>éÏHopýQümZgÓÑŒ}Ò‰S8òÖI¿:`<âAŒúÜonwÙ¤ê¶m+|nüXÎB€Ø&Çy£2¬Kl›BBß9‚ùý™ ä—¸%ÆkI¯:u¦@Ñ—aV,jW¤Þõ:R,½4ÑaËÈ1¼‰o¹-HÞ·Çï…mpYÏ÷»´¬üR‰„ÛkåÚ÷È ÍårZd$ëhyÕ±ŸU••À@¡«‹–UF:„›¹´ƒ\(b:ÊžYÏ©ÏÙ¢Èø{Óœ¡p©Ò-´H·êåå7m<•·ìôôôôôØ Ú¶2­ccÓÞ¯¬¬L›èIU”••¥Ïïjcccc1´´¬¬L;tyCd„ôbe¼O%!„”8N—ñ1£Ò½’âçÇU&O"äëZ~{ö"W.?±äĶ“Ⳙ—¿”_Þ+g÷k^ÛîI\·EÌ ¥D¸i™¢ªn þ$Wû-hBhB“P§ljó…*ß‚üýÞ\¯À¬‹œ[µÚÍy]úú¾kg§ª$÷a0! ¯DŰ»ìÄ'n3¾Í{M!Ÿæýjdwòõõõõíhgggg7Á±oÕ§w¿ž‰ðiœ†1 !ݙµ!˜’¾xU!ß{ÆŠ×:Üš\ñ/^BÈgþæí:Ç#äòìáÃë÷x3Í]Ÿ£æi¸Ç4¾²¢^¼C=–Lˆ×¸,•b½ÆGù׳ùêãiÿ%~D¢Ph„"ô÷î”üÅØÁE¨Ò5[¸§ºƒó×q^•3M×O[Á@¶õºIHÐRí÷Ë®ìª\/2¿~ëGy±î—©È3:æ±â¼êëaw ›½í—Ô \"þgë !d0S8#Ý É^¶*Ry%|[±"‘ü«…7p©Wå±*…·2 õãõ{j_ĪªWVEÒ÷©×:ð®yÁ9?!îÛóÖÞ!L<I]uC¥¾ü˜¤>^:ÙŸ½ØÓD²öEHqå+'£ ¡vôârG¼ÝËñà?ëÄØdž+–-çö)/'ÏBˆ¶çíÁœSô—²¾Ê#^ ±¡ù.}øÂM·ÍšÀEÂü,B2î:í¨þ€»’9-S!d(ÓÏq:”o˜GþñŸÿ%áý¾®¾ÎˆÕ<ÙMZò×íÅDkå©¢Ê'-àEæ~æjÊÄcwf¡ý=­HR„”LY£F®ÆÕ@kCT'£5ç¼|¦œšê›«‘û—\­8l+ã”Q„dL=¯R3׆ žèí÷¶Oë­ð˜QD!gÕQ2–GÆ)2Ókwnõƒ:a¤ËÛ)!$âÉlÍ‹îL!ÁŸ«n™^›ÂzÛ ¹p¹’Bl™+ï·ÑdÅÈØ_„œ¨ð¦NáSI]æså?FЬ•“Êgq¬œP¬BªvGK­ iB¤‹?óBÇ®–Ñ% Ý™:i…Ý 2y¾‚B¨¨?¿© -'„…×ÉJBhqP“×(îMàÆµãG²µsù™ÓEb±øXG›½™Ÿ³d²ÍެɖíyGBˆ´³²Y¶ý[ç—ÌV•¢¤bå'§ùÌ ±X\Z)ÕœIA"OXÐ&&Ký(•Q³·æ)!D>à1!„(2Oö â =+Ó'sœzz^¹ ue oÈ­²yS«]ë)ß~­)þeÂûs"¿-oÉ0ž8_îóžg«½räš>ÒKµßk%=ë;µǟm$„Tì=MËhõ Sìc¼Rcü !ŠpÇÏJ‚–I)BWB¨GÛhZ.#„|iNÉ ¡ˆÜsDœÖšSºQúÞP+.”œº2ää ç3lmm—ªöfZ|h·˜ùƒÆ,Q…ç6ÜUF…k% gJ²aT/óu¯·œÑ7nŸß¨†Ý¡3깊ÆäB¹S£–ƒU>çÜwßGNâz»=û TþUƒ9tº_GÚU?©z­óòVÙîòIaû¯± ÿ% ÷ƒÿ^ÎO¶«|¥6G‰Ü½¾žUÃFHáýpn "áXëy†D¡¤'zŽa…ö-º—t„&U"5R8noCgmÐ|@(sal(« @p=o„ D`æ; 2ݼÇSz(Ó¡•O-} 3ñ˜aáE…šˆ;c'`–xÏkÃ5û¬Ò$ùôþÐâWN²ÓÜ')0næ=N–;‘[(Ôjr@ÕÓ,$F…ïª& r«Ô=ºp°ž½K/Uʒɵï//*:M|³j7ƒãÔµ6ª³XèÖt`µ²{¯C»Nõ'˜W”âw^QõÍeW‚Î(“þø,lÄŽzQéR²»1a‡å®ßqíÅ^Ò…äIöІœè]±›Ýps”ë2Mt@‰ X;µ?a€-„€àvñJJH „#2yB Ì?Òinmh 9èRHÝ¿„È£dz:ÀUÉ B„!-8?µuy%¡B¼^¢B„µòéÛº>A“&æB‚Â%‡;°cŒë{+˜oÔ–U}´1ó·ý°²£*›áĺvŸÐk2u ~oÂF{ëÙs4pÏ~"—MÚ`QÊ—ÕŽmlŸ-VoT:}Εþ9µÝ©ÌÕxäD;ŒfUƒO!km'êU7£o\Ö´kïv"ô)ðÛouDzÏÎeWÔ€´“GëpBvÀf‹u˜ú†H ÚÇæÒïâ–h¶]‰Ž2â>aÍ(=ˆ¡@€yKz0PB¯”•&D „eªFÁyóå&êJ½¡>¶ndò €Gá2#(Õ!ÐÐ#¹T¯’Vîõ=¢±÷Çú‚vM™?Ú\YµV0?1€ì{4îÖ€7½œ'êØ€ŽU¥Žèúû-ŒEM.˜viÂõ®æhÁ#Ù•„M«Ü¦sᜟsßß]xK£!Cßøà»ŸÇaZt+}—U,â¹ín¿‡Mxu~b7XÄ%Ä*;Ùi,·ßóõk`šR½|1](@ú«áKŒ¡4®ë@‰êÊ=Ñ£K¹PB(Uv÷Í~l6¢×øài®uí}÷$;•Žøú¹° &ÒŽbYš'†«’ØéM" ðŒvºˆo Y1@ú\½ ØNÝMŽÕ›®4/²=$`Þtcªïp=Àb¦V@»w‡Â÷=€ª'õ*[¥xœd";k*ÏŸyeÐ`šÈ kp•ÞÀ—÷N/ÔÙ¸ÍwüîÂÛÊâ2§8!ì£#OvËϧkñT¦Ó×=Kx²{?s×ÌËÜcó'ÌíH_^ݤ›%K˜zàHZw9I909$•ÓvµœÃú+¨8cËAÂwóiÇ }م݉úTÅ6î¿¡'(\cР-±ž 8Vƒâ7äsÕ%ê‚ÿ—j’¢™øïVv9gÒkö@ÇcõæÖ˜Í£íÖ9@y@¡^Òé~,%G ‰¬‚Ó÷j„m—ÛÁšäÑ”qÅlÃ9?Çl<Ùà²uRB™ø“Bµ‘“ï-ÙðT'±MëM¥ÿ4¸Ãÿ‡[ÚøJ>gÛ,.º®Ê³¿pXʃþt䵕:qUøcw X¥_ÃͦÂ&|%äÅz&äBþÈ…Û­xÎä²3¬ )ô—A§9ñ'ñ .¡ZÖH棋3ÓÍÚØØ$‰Å¥šàª|!_xó\ø°¸Ø1ÿ á%TÞŽºS´ ieâi=2‹ªKí­<Ò=,e$+,?¥’’iÊÐY!Š2Æqò,qåŒzcsfö*ø§sþç¼ ß=áµû•]åœQþòþn^ ±·ÏNq›RW·uã…éÎå塸»ïcÓu‰t´àÒ©ÊCo®ýèö0¡ªz…qMÒ×Ô?gh –3vàÌcWpLª½8”øI_ôT‘—ˆ|ˆü?(Z?är®é~xÇܲ˜×VOñßl¡Nï¹ÖÍgµh B„À±=ÙMîŠ'¶ÕƒÇÅ)¾%xkšÎ£"@úig¥Ýgˆ˜¾†Äî“÷ßÚþjßGšø‡}þÇÂøŒ'k(º\²{Â'æäö{Ì“ÝäC¬á½ W:óô]ï;G9jv-²«Þ®.qqZ?µ…Œzy÷b¹²›µ×ÀÙuß%h½¤ÔÙ!K9wqL6.ï¯@ô2øl,2øsWÎ+Þ`(ø:oa?',ÿ¿'2%é­ð8áx½ºÆ”¨?ùên˜¿ýt'Â| »ã”ºË•Îv†—£¾ ýúØÎÕŸÙlðÇC›×Ÿé„‹ð~ô_Îe_„Ü?m—UìÒå=Ãy¶ZêvnSÚö:‹¸n$²oð(n¿[I˹&"õ¹çV®¯Ô÷þtep‹ÖNâÕbîU‹¶“Ý€©Zá=Ù˜# U’vq˜{Ÿ¶\á› ª° ·.€b9„ª±×J“m@ÕÆ‘ýßo…¸ há¹»é hñéSo wïg)NcÌCÿp@Xq»õJÜFõ«ö¼—"N:¸Ÿå~Lf†‹ðþxâÄ«µJß ÞÜ”s|p˜G ÷8}!7ÆS±ªÖ:žßbþÂ^Ü&¢Å\Þ·b§º¼×èÝŽ“ª%ÎHFˆ2àv£`±@ÆØL)pâtµki ÇkÌ஌¯Î²" ô—ãŸk¼ß߯#ZêýFæÕìô|BÍÎ"pË€Ôª†OÉ’?+µ­« oßY£çMšXÄö€±´ŸØÃå¼J¯yutòú: b‰¢éÇÐm¿Ûx¿‰Ö+[zûé}ü[„7}ßù¼uwã)Rœ¾x…+€äMØ®SK2½é^î‹_µr·ö퓸ʈãЗŒšA>³9¿iß]gÕSeëÚÕhÏl'c0Ý›BùZúºò~;}¡üƒºb<ã•Ìó¨£S ýt&hº u³¥¨Ç·û‘¼!’‰øè—’ȇäM§6xÅ|=8û£ ÓGÞûæ˜#Öúó¶öÚQƒ*—T>ÒÕ§ íF^«¥Ôpè*æ€<‰õ©žýAÆ…áFäz{à÷Þʲºq¥°T AÌ~±ðDø;®L^ó»ËS´ÞTc«Mïy”wºã¼ºU/\¹SŸ¼²ÝÌýly“ø¹ŸÔ,3ÃN*hZôÓpΡâíÁŸTvšÝ%±%²»½[š)¦`ñδ„„r6k”usJ ¸1Ì:Ã]Н74¬¦øµ$¹÷%¿É¤…ÚÈÒm¸ 3šÍjÑw×C%ÏÈÒòyÎè”yñ…ÚH4³nüÍõg¿ ô7t¥?1Ø*lkò; ïÏ[ë–þ°£´e>ß¹Éëy&÷‘6ÜB„ ¯Díé R¥дú:Þþ,Ù¥Äìh¾K=kjñ*¸Ú‹§nx}tå6EŸŸ?VÔœÒ‚Ž‰€z}nƒ–Ú¡®:ÀãïÜ bç <Õ>†BšR:ÀwgõŠ•ÿM.lý†}ÖÐÈ”Bº¼è êñµSþÐÊËø´J¥ÿ=]S_œÍXo'\íÕ¹ï[-€÷Çü¸³õ ‰vå¥B¹[gÿœŒÇœXOß[ffüÖ+¯÷ ½?€âÝ'g^l<ó„`WMæºA€ Y[„†ê?ðˆ;ÈYdñ;¬7˜‚-½ÒS¶£¹—¸rˆ'»w&õ¢K ðXÚ'I àz4÷ÐÜݯ¦&?*×¥Ê ûà¸Z÷§™š•_wF/S‹gôçÆt4a4«f­”R|N¿ÂUÇÝ\MÀÍ &k¦Z¬}ùT¾M)¼ižyh‘;´r°>óÕÑܰûÍÎ=Ï®iv` oªOžš"\6êJ]üÞ Q¹dnöš…Aù¯4þ®lÓkQ‘^£D@Pü£u"÷€NüBlµÅS¹My_;'ð–¨?¯qÛ‚Ú}å)‚y" ‰0õ•¸\éEæWGcàc+n’Ai®y§ÈD´¬™ã6èŠRæ§{ c~ÈÚËœZ‰  è0Þ%<¦–ÍŸŠ€Þ/Æç_ü‰Tj@g{5wo¬ŒÝýÏ‘·ÌoË6 ¼©ºŽ±Þ2@l4S4Ù|(h¼ûâgÀjM°Ç9A—-w¬¿ì–-÷„GLv˜´& #æèÍ)‡éÆVû~ îo€&±—’a}Ç>‚j>x[4.Ö[– §ÎëR/R>•E÷®/ÂR­¯ãÐ÷¦ÆW·†{ a[†™—&¯¡× „µþ±²ûß­€ùÅÁiL/KO …»«½ºö’À’é( hΞʼP÷¶<§ÒÿÓÞ•FQdá¯{î™Lîû„!QPDnDt½ð`ÁÝU<VÀ]Á(Š®« ¨(Š ‚@@€\„$“L’ÉÜÝ]ûcrtwu’!†]!ý~%5]U]Õ_½úÞ«WU‡Ñÿ7•´®33r´ˆòã¯ÔUñx¯—üAœ^?½nò7ÆŸ ÷–ã¶‘`9Åè”–¨‚gF_nŠ.á€Ðè7`‰/qa}Õ<ËQÚ'€íVuÂ=_hÊ`ޝ¨†.Þ]A€ù[ÀZè igkÞ¸²;BRËl@HòÙ*˜R´ùfÇFçyÇã¡I181ã¥î¥U@Wë¬ÆtÕ ²p çBX"sÜmbHž€ýoX&È'‰âÙ«<½ÿ­ŽÌ~ðÉk&¾*5 Ó¾Û²äUvÕˆ »Áj^ŽqO}Ú—&|øân:(Õõ@x Qž,dÈ\š@rI‚|â䎲Jœm†œoËIDAT,]…>:ƒ2kŠH†œ, ¥TV¢­KH½KÌW“Yÿ'éÆ:,,C„ ðÙº á2€€Ê øÅ:O¢.¤î÷n Žß.E€5%%°Æ.38†,`+%@Il\€ØXHL€4æ² àé TIJšÄDÂæt€ÉÀÑ—Šë .ƒÍ"n«ELÅùÀR^íË[>KÒÂ;½ß-¯I¾w³ ‡n|j&X\ôàM›á~¨ó—üðÖ¦ –©ç›¾óKÔ:&oB„[iÂÜæ:Ø3Ȩû.`ðˆÓ0žb=Ž2þ †¸êJ½à35f  “nª2‰YWƒÐé õœÙD3W­«œ&R…r#ð ÕO£ŒÑ4M”y¨zeÇ›© 0<`¸ùûžâ¥¼’ ³ÑR8zcGàâoÒ"Œ¹îZü°õ%–S lL8"Q´úJ…Ú"´`eÝì ìƒÑlý‚Ì^Ž“bp –º)‚þš Ê…ÑiD&عÑ:€‘-¥×x‰B­~ 핀¦–|󠙨Æ‘¤yùwõ,Øõbo k˜ï– Ó^¿cèÄž«c7œjà€k½_ýz_œ¯@ACi; ”&HóÐÏé*¼&™®à«Z{xio”`Õˆ Ëc¤£O] q.Zº4QDRsÁ´Š"Ð@èe²êZØWÓºÆA{ü´~¨*¡Cˆ¤­~±_™x<¹ÿ¥þ²²ðØpè%8 [ôôû÷ ¸®?Ú x‘·ñ™$h«é_øúÆ#{™’GÞ%ÇæËBi]飳†û8­ì9SêIš;½QÁ˜HŸGáW89;H)£, ô]­•p+øy”¶OCF/¤‘—=ãÃõ›;Œ”±›ø\ÍÃß߈vÞÂY˜VP lÔh·‚·2…ZBצTõõ„|Ÿü]y…x©Ñ9¨{5¼%4ŒtŠÖ $‹F–®„nµ=‚ΫpJ‚–~RFÓ"é9“´ÎYEû’›yåø÷.ÄPœaÒ„||ƒ€àTP‹ G«c¢pýœñ …Tc¦bÂ\ô‹&R“¿¯~LéÎ;cÕJÆUÚ–½˜Ooïñ(ð¾–î»üp¥©‚n>+(pñµ’‘\9Ïñzr³ïl gÛx×{aßø~ÀÊš²è.¥ .)Røzô¾U®Pu¤9Má’áé¬F…ׯ:Ja†5¶éf- J·ŸQp8ÒÖY„B­†Î¦µÑ*£™ióDõ£‰¸Ø%(ð¾èæ¿þfz¤’K¦NþBGÔe*\‘ë+¡¾2á`d¡§\GÙIkp+,,­ Úô2óJZ‡é—³047ö曆Spè¸\糸âµù™=vƒú†Ç§wÏHUœ¬bPAC&Ÿ~.½œ‚¾6æ ‚aGsC^K3}š=¸6* ¦M5ï@¯ƒ¦ûÉl¡]AÕà±ÄµàmË´[£H0šw•ð¼G¢ùfÀ«ËP`i †ÝY/…&JÁ×XM‹TiÕË´)Ç ?Í8jÛ² v€B7Õ§-Ì`o¦æù ßÆ?mô ·Ëå&*xQ–µïª{›ã|kèŽR —J´Òf‡=þÞÝé9²ÓéZZó‡Þ>}´r0 >Ù©"B뻬ÂLB¿œÛBß%Üœæ-§q¯P+ØŸÛôEÙäþ¯«RÁ‹µÛu)#–ﻪ¹‰¹;½f\dSм§9Ú)ÁÓà=Mo/¨Š1ȵcnîÏ«e ÙÎYp"ñ·¾  XÞÛéIÝEwwÅ–àojº ű[µJ Bm ¤òýáõŒ|)—óéf§=šÚtã‹»ä-´^tyi§îïIti Åùí47Ö+9ÃþŽÇÃ"R™Ô¹ÙÖ¯Úæ•ƒ7ÿ³•ñLKôP›B;|NvùH8ïú9! >A®óY8i®»c½ —¯×j|¥/¨6r"~[¯º«ËÛ¹Ì7Ô=³È?CC«¥Ù ‰` Q.&¶*l¸é1‹@ñéÒ»lÈ¿¥ÝsÞGV&0ÍëÈ·Z¢Xzû·=RxšhFü*&`uQÊHs¶©šzÕ¯ r€>U× yÁ¤ižÐ¸ò$f £»F)lРߏç7ôhPˆ"Nš˜‰¦Üêÿt¾"~žÇ³í¢÷ô¶h¯ þýûèØ†‚1q¢%LJ1€….C]IÖYÄØÀz ã/ð”ÇPÁˆú—®N€À Áš€±7uRMÃØ£ ¶Ãé)€SP‹LI1u‚ùÏô".o UJX ]ÅéYBåÊè)áfƒŽãâ—¶Yß֦к¥°—n¥MpFò &–eöW™òaaª¤ô !ŧBÎPM2_fl˜€ç‰ßV½M{¥¼J! ¡4Óî[”B©ª¶*Îm’¿"uf,Ú‘´Í*)c¥q Q°¬ÝÕ á%‚lf§¾^Çz ϲ€µ.ÒEtKgóA¸ ì—6:¼Z=˜ºZ¦­z±ˆn–[¼¬™ÖåN…xéâ/=g%K?^þ†Á7 ]IÛh^B‡wÁªpÓ#Uaøeî$Ñžz ^ €e@àbX¹¦Ô˜Å#Á(*r¨ñÃ4>@HD[ö¢>gÏ«£½2!á´s+^ÁÎ+Øzš€çI™Ï¼Ñí »m^M­f•Tâ±®?á9þ|€a@–,A°øy9!` pA4 šm¬‚e½<F¯“5þ­¥šè¥ðx…ÅÄš š6Ø;´Ð#ub¡—Ä£‚C·âºv†ÝÖÐ¥ 4#SZAPF‡_¢¡}@ì´zŠÀ 2–8»[(7á•ÞŸz=hƒÓbâõI×cx!hë <µ£úSVFCÐDè ˜åÁUjSiìan߇ǵ7ì¶Fó*QEŽvä(…øyÆ!.ƒø ˜.ÇRâMNI“rœ~ت0ªe¼Ž¶½ýÑž…$úu|´N=B[ sÁCûƒu‚{dì5.Kíª[ûò|»o+ 6MÜ”\eJº,/Ÿ´T«Î¯bˆ¨ ÂèT¦™¨Â™+„ßß̰ˆ?¨IŒ·i1¯¡Â2MÁzÙ®0tý45á4mèðM—êѤÑQ¢Å1 ”.~}ËùÚñßÝ¿'ªàmÖ-¦…±°AÝ9œ—C@®Ÿ€SâSÎT±È"}HPS!ln?9N…¢Â(½Øi =UÍgÇjƒŽI¦Ýbnv¤×‚….´ëF¡3½ CÍ €ü¾úŠ`HÍ,ÎúZÖ Uó6+:…gÁ¦ð]yZo•[r´*úWõ¹úRäœFÚÝ¢%ǰc]œBP/ϰ:sC„Ô'øYI¼8C˜–ÉAÓRI‡Dšu 5ù{iC¬Laa]¨pз€h€]³Ÿ |ÝØöe¯…âj$EàD]¦ ”XQlCÃ:E|(=\”a*m„ê´[wˆH;€K%W?é×ã]âm  0,Û29hZÎÒ>è³zˆ[ÂiÛÀÓœ&1ºç’LØ8}æp´[a¡xÆ…­Ïa·ÓÈù’zÿõñôHèoU"’Ôàáéó r"M”—eêö75úf{µhÿFý±§:¶~Càþx/¦Ó»ãŠh÷™ã¸Kÿ¦Æ '~sZz,TŸ,\4í¼Á  ‰´Ðt³1ì€ð|ŠgwÖ*ȧ¡ƒk Cň€nz)‡HàF«@¯ëKdDH¤É1«å>Þ;ÄûÐÖ”©mΗPi‰Ô©íˆL ù[EŸQÑÛþæSC˜v Þs伄w`9Ýa§/6[l¬–Ñ Qjqz¼¹‹uQ:¡Êg¨[°Õr@ÞšèµR÷Gaáâz£¯_=v}N *.7› ‡óÓô“N:.8äͬ<±4!˜¬¿i¡Òö8©N³»¨¬¾«©ØÚòc¯P‹¼•5t­¿®¢¸DnõÇÔc%ë–ŒE{æœõNñ×ʼÕd²3ZF+„WyIˆÙíñºp-©ñ빺¥/¾…ªY=ÇA•à%n Tð^@Òè àYF…oû–s^ì6… ¿ƒ56ùJ;qÛl6ê9]^õI›Ü[Dj‹Ë¤®NbÚJ™ªvWô~Mî{ò왞+«²^[öIšËEà“: ›ÓW~¥MZžÝëÙ°p²ØkàµûßʯÄÄÚQÃ=Ÿ)ÍéµÃÿq¯#âÖz*ý•ccã>ÍI¤ÚÇÄË¥Þß*øsnÛìwåÛó‹‰Ï´¯ùöŒ^rŽòcGýÌj*uû¤YÊÉ«úô=*Mò~0 qÉžó¼Ì,——v]DÄBYRþí=ÍNiÒΗ%Çþ"M›Ò#tº4É1+¾‹õWIÒæ$²ÎÐÙô“(I˜ûH•ðÙ#‚ø±Sº™ïÆ_v¿$oúç_ HÖ®¥|’²…8_²L)¥=4ö§>½¬/Hr¾—.|Þ¥W袤ìŽ?¿8 OÄðbQ' ™tvXï> EUgx·%ôŠ»ßߘ2=)apŲˆLëaÒ~åœ5ïs7<¼þ3jñŒ3ÊÆ}?~“y¾Ì¯0ñÕnfù\ÿæ‡Ý䦺OJ”öâ߸g\¨L“_½cžã&Ù‘'k³ãj¤úóðê~£ã§H_„­Þ7på#©m/÷ñ©3Uc˜ÖGK]lü¨—3CÅ‹†8#yum‡q3º¡Øn5ô”j^R±ÅycÔ(qZ”éñÍ£;=+ŠéeÒpÈ>at…øÆÄßðZ¸¾Ñ«fÿnñM{ÊçÎøèúwUÚ¼œ|í_wî;¼=Ån^±Ò~'åÓ,`dwü­šwiÊVÙn=þú9Ò¸j÷¼^±NîçüdÈù±<•ù²˜¬ä¡?¾—à–8Ž‹ü¶¯^ó¬ø Î¢a ²3)tš;-âÇËÚ ÏЈ¢„(ö›%fö¨xl9:mìí ˤíy®ìòW$É‹Â&÷‘¸UÐ%qþ¢8q#´,Ò;½\D$Œš[½sš¥Ã}ÃßQÁ{NRuŒ&Z~ykföÉ¥#åOXû¶ìZÖõŽÏ>(sažyòaË.©GÏùÂRùwªù¾‹lããÉâ©=¦È¢Ö“ç¿õ´I+‰)¸Ö¢±vé¹ …Æà‘ŒJS—¿Lø@º½F(á¯~ômñ©ïeº4Çaì0ͨGÿVð­8g ë³ß´ö®÷e­p%‘ìÄ…Ÿ~yqùiñ¾L Ðeñ ]tý“Ž~;û cÅt«~ÞàåÌØ®«VÉç'¨©–¥­ÿrÞïý¤¥»W½2j—Ì»ó¦«äùke'q왓ǥHO»7¥üþ/¯<üÅIFErâÊuµ·ÉÌΗäî¬ìm¨M¾wÖÒY¢m>×^—än߉^+ë·Œ^Â%\fñ¬EòXÕUGðŽC|ΰ›9ü²‹»DB¶ò]n]üƒOÜl™œô¶ aÿÕýº¿ÀhÅ­%ÌÏÓœUiŽãÊ I3~fÑ=fÛ'ªÁ¼äge­§S÷?+OùatVÖã²4碬Þùƒµî'å]Ó{‘<íÕ¬,yRÁ½û©¹#kB¡,ió€¬3²¤÷’õGß`¡m?DÈ/Ë‹«œ4±Ï¿$)¿²çæwè¨u‹ÿ+YAȤ!²Gž!$÷¶{ðÊ×¹¾ÃHû9%ÿ® ÓõùwŠ–ö Ä–•-ðt¨s`œY’ÿþ-#U¤]@š÷Ï+îÊÈ%{t©Eg^Tþÿ3—þ´ý†À¸p`saÈk zkÎDÀWuàÕK =ÝU¿Þ#ìzHÆŠl¥‰5ŸYBÓ’aOžõ¾ý<5üÃ1u§0L>º%{ê( ßGÎÝQGs2T¨©Ûƒ5†|0äØÇÕ½'¸½ÖÃõùЇ®Pÿ2jjî ÀT À,°ñ‘ý_ O±×Xäç„™:xû0ëß7N‚i„Ñd»Üµí°]°Gà‚ò}åïÛ7³CJ¯"Mo[´Xk·u·wéÑ©pû‚ÇÆœþm_úu¡¹¾üáÄác§ÎV-=½Xw €^vîáÏÃ-wþ6À _sÓ„ TÛyp—ÓØ–w•2áè´jòÍšÜu—.ãsyüY÷¹âä¶1‘*Ò.`ðþ‰¼éŒŽKê»öî;&Lz$íƒþÛúÜúÐËÝ“'ö½c56í,¿¸2&i}Ñ eK„³¥ :uw[zFqÿäÛJñÅÝo„÷`þ6kÂ:nã]oMR a~ïލ¾—óâ ­‡m…+Aøóéøšûqzƒëþ`Í#ÖÕv’ß“^ðË€X(£c]{ü;àöl¾µ—r5{[±dÛÉ6ð¾”E«NùÿxÛoíÞ[ŸØ|êHTª‚—¢ 猪fs›ÊÓþ°»µîˆ‚yßµÉ]±á*veÒÖ®25¶Aê/e·<}ènµ7Îm“žaÕHì6–cW;á^¯F+79 jH*ƒ­UfØŸlg»ÀëÔoÙŽÁ{AËŸù”UT𪢊LT…¥Š Þ‹Y€ýugš?,ù±ü[Ïù¨óðêO|gWçPéGV«[Šê¥u~Þ x½¬v‘±†ÉrýûË3ä){?I(ÒdMö,ÌœÀ³xç Lѯž'}î|D뺲+‡g‡P¡”®][®UaÛN5¯.ò•â+ûwÙ´¡ÚºŠ¾Ñþ·å)EëÂÆŽO^øµ†¿ ´]¥VÂÓó]ÎÇ{^‘ÕQsÉ›ƒÁ½´I’ÞwŠ Ú?¦y/T½+0ŒáþŠÈ±Œø»?ÛF*’»+)ðž™›ÖëúÝq Í ¿TüóWWŒPœ˜ÀµÜDrQ=í 8Ö CÀžêtJkÎbàûd3a0 !, ð,@(a㙆UÍÛBø&8Fk…ó¶i[‰Ÿ­C)M™= ¸r](m¼µgþÈИÕï¯^Êñ2àªJrr΄x@Ž— I~Fç*AQŽ7§ 'g,8 999968fŒoÁ–Ýsš 9999'T>™õ}IuNÎI8r* ätÝÇvÔlvêþ%‡>É\á>3'õÌ8hÌØý†–|¹ànË£˜RA¾ùÂ5¢agÏ®.ïÙ3¥ÿ!Èß·=ɹçË+'û!ÄO8*ƒÀB„¦‹šüMhú!Èו¼¯¿œBøe‹‰g!äë-„ì[ý—UŸÞúUÃFOîVߤú«wNŒ‰ÄÒϑڬ¥äø-×Ôw7ÙòàÚÑ_ð„’yãd¼fϸ÷÷Ýå>øTY?xܸÄ%dw5äù;Éß§’-/U/0^=nT–£lî¢Ê)¾9EØ9êKŽræê;ó®YB~ÞqîÊÎ#çlºí°wdÖû¤&ù'ò÷Ûí+GþHö¦ïãxÿ q^e+™ö>Ÿ@&<jëÄUs:øõ]‡ÚóáÒMÐAÐ6¥¨Ó—ôwN€×D~n¸›½Ù@4¦ErB\– ó47¯h£€a¿ÖVŸóz®ÿõžË^u|ÃÀ9×w°çFˆéZâ¸ê‡Kí ÷/ßTxpÆøg-æ¾øÂ²4þЬڢ©ÓµÆì¬dSw#ú ý÷0/3'whgüˆ±!èx%pçW™¶xÎVótö‚Á§Æ‡Ž,X¶òÚî“G2q3@õ¸)Â¥µèÿØkÏàÝûn)DI…ö…µûóÕÚ~;üÈ í @—‹ã;nÜðq§mù3ã&ý6úÒP•óÒ¸aš'¼²ßM ÀžÃ*­ËÜbU Â7 ‘?Êv<þüˆ$+àál0Ì!N=ÕàÛtÏoU3F^û`þᣦâìñªÍƒIÁž¹î?SuNoM¿xÀëÙãLŽžä2Oñâîë¤ÜˆnÖ®×)•¹¤o¡ îê`Aû]AR$2â¡O„›"" ŸŠØiËGP×­`öó§øªPídâÜ.¸v7ü€PX„|®: àJQê¬a N0Ìè>—xÓ»çƒî©*x)€jšÅ®Ë,ýxuŠ’8&¸SëÎáTrÆ mržÎË÷'\Q×úé+Òf_×ðÛ™w¿ãõ˸¹:ºkˆÉç«!Ó¼Ÿ‘ÛqÏÙ¸uf§_çõGb<üU@j}@© ؉Z LµÐè¾[×Ý’þ²nZ°Ù’`Ô¬ü–^_²Ü˜X¤@w#u@|:ðŸÁ¨j€Ó‰€. ¥nĆ쿔I…NóÄ—™¿÷«Ñ5œïîTð¶LŽ™¦ƒËØ W„æêÕ¶™q©1Fx8mP²c8ùw$P[m 0¬ 5ƒò¢ QÐ.ã‰àž—–~ì—aµ~»þNï.å1æQÝÞŒ5·÷`»ïD¥>>¬4‹ïš7uCÔøÄ½a׃5:Šž ¾¸ô¾{j· Œ×ZjŒÚ³½3>ïžõ1ôoݘEl%6ô^3hW LÎÛúéÂì}kÚxó¼-û7èV—-ÉìX0ê’1#p]˜µØÑeò|ÇÇå¾e«Çd!aÞÓWuǤ£w?º¸½‚·Å؆ÌÖË/§› íª{ˆ´eÂüÏ<|ß~¾çá &Ë>š0mÉ|󈉗¤~z×ãóG}1|–taàÈ?€a[¯™³iµö_)¯þ@ÜÌŒáÀÌëà©}dx×Õ5io¸Ñ}ó48oÖ0‡~{³‹Þ¹÷²é©má ½¯ nȯ9Qæ/=`ÚÀ1~s]é3÷iµsÙç£ûk©\±*gðM'n»Ñ^ð¥Ǿ¾—ðV¿}×(ùËmÌOœlºVÆrùŸ‚ Þ¦\£2}GÁJ\}.žižÑ0ÿë€0Ç,ÿŒðÒ説ïvt>t¤ë°™CÞÚwÆz2'R™6Ü|NuÜÙõéæ~ÞýKÑMýšüuÿ˜Ü¥.@œWÙ9ºªþì²=s=_ºL\Æ7¾~!øÀ,uQ …B …âoT¸TþˆH8¶C@Ü÷ÇëY²x ãÆ«‹£P(J¸(cÂeÔOˆô'ÀqÁqÀv)-ðôÚ±téu …"åqQ(Îè;P]Mz7]ÒÓŸà#{˜Ÿýì5¶ooQ×H¡P(|¨Š‹Bq)»×*r¯êb;éÊ ŽÃòecù¯__ìYUêb) …. Å.“þ‘xZ¨ %^Î=§ŠÚQ<ýôMê‚)гÕ*R(Î$ºMó¾fÝ2ÇöìïàÙç±æò{ÔõR(J¸¨K PœA4¿PÑ’"&éyñs5ICs˜:Õ5S(J¸(Š3„î7çj¾ L¶aM²ï`'·ýàuÍ …. …â ‘'ƒ…J–¨I šÍ¯·°nÝ1uÝ …. …â ]f·ŒüÇҢƫÆì;ØÍÖmjDZ¡Pœ½èê(gò˜l áM ¶|L$¿—B]7…B¡„‹B¡8hèv¶@q > %ŒB¡P(á¢P(N'O¾ÐŠ%„Wu±ÝŒ@±…'\r¡*. …B¡„‹Bq†øÖûH8$[EÉà9Aò{ÐPÂE¡P(á¢P(ÎEŽWmÉj ‰ŒX±Ýì–$«1ÊS¯P(”pQ(§›BÛ›Ê*~snê«H¶Š4Õ*R(J¸(Š3Ajì9UiîàêKj²ÈñU\”pQ(J¸(Š3"\4 Èõ¶¤ ¹ä˜sÉv …B …BqÚ…‹.sFŸÉiåšsU«H¡P(á¢P(ΔpÑ$àó± åmI}ï’ÌqQæ\…B¡„‹B¡8ÝÈTÅŇL¥%š›sÌ «Š‹B¡PÂE¡Pœ Rá&ÅŠ›cÈÍ9Fò˜. …âlþ̧.Bq¦„‹ÈY°øf›¢½ï뜠³µ{ÄOgóæF¢QK=/ …B …B1Ô»/YqIm~+›¢5‡îz…›ëFüt¾õo/óÝï­çî{v©çF¡PüÍ¢ZE Å™"%J²rObÎMî*²d1Á=•ûÿ´Ÿ=û:Yûl•e!âq›OjzŽ ÅßÞg>u Š3(\ÒÍ×&Ò†¨¸h銋xr\6om¦¡u4Žž_ûÆ œ¿âw¼ôÒqõ<) %\гÿù½vIFþ§ü+Y7-»eä;&$ÜQ"ëqÚ»ãlÜÒÄûÞ?¯nl ½=¢ž4…B¡„‹Bq¶‘ö ó­æó¼øÉ¬¯â˜*’bÁ$ˆÙ¬¸è.–ž÷öìiSOœB¡PÂE¡8+)°!(²…Š6Üd‘6hòhÄ¥‹–SíIµ§’ÇŽ5ôóñO<Æÿ»ãuêRÏŸB¡PÂE¡8»„‹†8ùÑ> ¡É‘ßW$ENKJË™f’lßÝÆç¿°–ÏÿÓS44ô©çP¡P(á¢PœUÂ% NnÎÒ°+=‘1Ò%)2xú-,=sžÏ<ŒŽŽ¨z ÅAC+g‚|Û.¶ž\¤èä,Z"öÀrG¼ârïëùÕ󄉓JñMÞ7gùcòœTx¯B¡8C¨Š‹Bq&ÆPSDZvËÆóûaFHÌfÀtWWŒ!ZGÉïwíîÀq\õ<* %\гã—ãeɉõÞ°›‰ÉЇÆ`¿–³Š@Ï>ß›?ù4¦é¨çQ¡PœvT«H¡8#Â%5Q$2 S-1DËH® ÚÈ·Š<á’FéÔ^ák%|ýK5õ™G¡P(á¢Pœ=¤+ÂçaŸKRܸŽ'2FZ4¤„‹&“ÂÉ;ùÕ©cÞ¹+ …. ÅY‚Év‘È‚¡ö¥…L²â¡»±3bÂEdZEޝÂãøŒMö1MbšÁ ¦žK…BqZQ›Š36„ù6+Þ?×°›9&49²ûŠ4 A×3çbhCœ_ömÞ‡Õó¨P(N;ªâ¢Pœ‘ ©œ–äŸSm™´¯„dûH€“ôè¬ä}GH·´wXlÙÉ´ŠR••T¥E’icùÛG)£®B¡P(á¢Pœ Â%•TË`#,®Ïkâd¾w¼w¬AÁpà@Œ_ßÕSÉísnªE•j_ùÏSSÂE¡P(á¢PœEÂ%5r àó•äaý†]°’¢a¤ZEâU\È}|_µÇï{"“ì«P(J¸(gZj³?!WøÆ‘É©Â$͹ˆ‘4çJ’þ–¤pI·„r*.é’ë *UqQ(J¸(g2e¾epFJjšÈñ­¸xBg$͹iá¢yÊDâµ±ÒþšÔ9ùÎÑv3fa…B¡PÂE¡8K„‹”Þ;ÐvsòS|Y.Y&]áUjä !¼Iºô„‘ ÙòsÓÕ‘ù;eÎU(J¸(g“p¾ŠKÎ2Ŭ0ºT«ÆõÞ­šH&çŽÔyÜRô«dµ¬:„Õ*R(J¸(g™pIíýÁ·ÙÍñ¹ ±)Zžèa[EFNÅ7{ŠHˆìUªâ¢P(ÎäOu ŠÓËï\Öv2üRCÍ8—ú>¹Zh!?þòNZNDNýds®‘vw²E‹ªâ¢P(”pQ(Κpèœ$•Ö· Ú,µZœ8ÔK"nÌO€€ÈIîÕ†ÞVmd=~b€›>øÌˆ_Ÿ'ž8Ì­·>O$bª‹B¡„j)§› ! ¿97•™B¶9×ñv4¤@ gä>º|Õ“”§%+Ã%g4o²É•‰htD/Í@Ääõímüäÿ¾Žnh\ºj«VM@Ó„zÝ(Šô-…BqZßuþ–‹¯Âáo jenBJ¤p¸§~.é©¢œêÊP{“ôœÖÑ;Ð*j8æßþ}h’üd3k®x€ÿú¯ê5£P(Ò¨Š‹BqºÞмýCîSDbð*ÛE$è$#YqI™sÝì‘lÇÉÒù »é©"ÂákC2˜tÕéÖÿó"Ûw´qéªñÜpÃLõúQ(”pQ(§[¸ 8ކ%5\¡ev 7ެ»Þø´”‰ÝèDâS.†¯zb»ƒ[TB€t2™.¬º¸É §‘ãæÿñ’·™:%bAÔâÎ_ïà‰' \}õõR(”pQ(§ )]BÄÉs¢ÄÍB3°5G“¸ÂÍŽÝ÷ï ²ÍEh‚ èE0ÕWq1´ä8´ëË”IU]D&½7UqÑ%B×#Ü-Ú²½ò¥÷Òï­4´DøèÇ'/ ±qãÇ™4©D½˜гñg¨º ÅéÅpMòyv”€™ `Æ ˜qtÇò„€&‡ž2Ò5„¦!¤HîXtGæ'@À?9¤åøXr¦Œ ™5á4bËíÛ»qܱl-k»/bÑÚcÑ’ßóÊ+ 9Ò­^P …. …â.î@Z°ÍDFÀØ&^Uehs®ð̹¸#A—;­IO¼deÈÈì‘lß¿#Ø*ºéæM¸CåÆ p’î~“ Vþ‘ÿd³zA)gªU¤Pœ¡Š ¦‹ejHÇA86Âu®ƒÔLMÇ‘Ž”™V‘•¬ÆHîÈœŒàâóÖäølüÇ\7)`œ‘ýè“ÁKžKÚãã3/çz¤úì¥P(á¢P(ÞùŠ‹3€ij˜–æ ÇAºÒq°OÀXšŽ-uìTKF4Û›*BÇ@ÄáçÿÙl% ±é…Š)a ïPr3Û¡ÅHzs5‘©ª¸øV8ÙïŸx’*ßE¡PÂE¡Pœ–ŠKÔ `š:Âvº.Ò/b4¡éØRá"qAŽŒ`0-ØqØ‚¹hnrÚ7Õä¤Ì±ÉêNê˜ëf2hF2ÎßJW|b%µ¯I¸Éê‹P…B …Bq:„K¡Æ1 0M)m4×As4Çö¾º6ší é6šcci:Ât‘Ž"éq9Åv‘+ä3Û‚/±×?QäÏ™I¶ŠtmäÇ¡õ”¿ÆWq‘n¦5$S¢ÊÍT\T¢®B¡„‹B¡8=—¸©“0u¤Lz[;SmIz]„›©¾ÓÛAH#äq±‚I¯Šæ’2çøO·Š’ÇÞ©V‘.²=.ÂɈ&ÿyÈT(ªëçÀ^fÌP£Ñ …. …â.x—3HÀ4Ibç´‰DÊëâÚHi#L×rÑ\gD&Š\vHÍÎ b¨Ô^2Þ’,sî;Ù*Â'\|­";cØ]÷b+O?ÓtZ„‹#t™ªN) %\г¥â’çD $âf m̵“SEÂuÓ¢%%blÍ«¸¸¦‹†32!°ƒ¹­"|S<þ0<|©º$³]ì‘  Ó|.©VQÚãâŸ,rÁ±A$Ïý4t…¦!„`ÿC1óúëÕ Y¡PÂE¡8{„KЊa$³[R­!+96éú̺¶ã L×Ä«¸ŒÐ’ÅŒpñ›s‡˜âñvS­¢ 4-ß(¶ã;7ß±‘>‡“ uïÇåø‹.b ­‚êjõbV(ÎÊ’¯Pœfn‚#H4ã1‚‰¸w3ããq‚fÌûÞô¾˜q ï{͵“Áo§ö Û`åiæô¦o†ï˜–}\ŒtŽKîFjÃ÷ø†Ï¼køþþmV\Ì6üË¿ð¥äÁÕ«éÚ»÷-Ý/¿ªŠ‚êjÚ÷î¥á•WpG½¨ UqQ(Þã3†‘H`˜FötÒ”+SatNæ–ö¸àŒLb­+·â’»àÑað1—Ì8ôˆ{\„¯ââúª>¾M©ó:•Š‹ëÒ}äá®.*—,¡õ•Wøï•+¹ìÞ{)Ÿ;—ÂÑ£ßô?Q5{6æÀŽeÑSWGÅLµ¹Z¡P…â½*\¬8D2æßJdí,2̆O3’+‚É¿×\gÄ¢öí –‰öÏõ×ü±ÿÚ ½Ab¤ý%þ©¢!£ÿý;”|U ·sBP=w.Wüò—¬ùÍo˜ûÏÿŒ ±öÃæÕ¯|…ömÛÞÚsYP€nnÆŒDÔ‹[¡P…â½*\’KÇrôd‘tÅ97ߌ ¾é©O¸ä¬XŒÞãljuwS3¾z¡+J¸(ïáJV\LSÏjÙÉE2çfÙÒrp-ë:m$ƒÈ1ç’Ùä䈿aW'Sù`+.þ*‹ƒoªIäÄþ§ò\œAíªüêjÊÎ9‡­?øôörbÝ:¦]wFAÁÉæå1åšk¨œ3‡7î¾›]ÿñô|ík¹ï>®}á…·öÃ4"¿ª #/Ç4‘†¡^ì Å;€j)g¢âbzãд×3é¦ÚCi³®ÿßä˜s¿½è»§ª[pƒ9†Xmsî Ãnæ>ñ¸Co·5BFfps͹©?g™w%_þjϿР@ ¨ˆ¥_ù WýéO”­XAOg'¨®fÝ 7èí=ùå’ÒÉ“Yöõ¯ó¾$æLš^{?LšÄÎ_þ’D_ß›ÿ/äç“_]4 vþö·Øñ¸zÁ+J¸(ïáÏòµd¼.9Ç­ÁÿFÃAh;;eáBÀ'†ò¶dy_|m¥ä¿yõÅ^~ñ½úª¸ˆÌc½™×ÅÈœSÂؾÁ©iLZ³†þòf~æ3¸ìè!6|þó4¬]‹ÙßòŠºÎ¸•+¹á©§˜uË-˜ŽÃúÏ~–W¿üe:vïÆ±ÞšP›÷ÉOb ` ioW/|…B …â]ú¦³ŒDF¤xfÜF"#TR†\ÃŒ4}&^+îzSÕ2ãWZ¨äV\²„.‚NMirèódÎõýý“EâbVß~;+~øCª.½”½÷ÝÇW^Éöï|ç-0ŠŠXyÛm\ðã3úòËÙwï½<÷ÉO²óg?{ËÿK¡òrJ¸(#Šò¸(§ͱӂ%hjÞŽ¢ä´—žëí,²\ß*©#MlI’‹O­E#p1„I\ d̹x;‹Èö¶àK®uð FX¸$—7¦Í¹¾eÂw,5]ÃŒD !˜yãTÏ›Çîßþ–÷ÞË–ýˆXw7Uóç3ë–[N.ì ƒé×_Oõüù¼qÏ=ìýÕ¯xõk_#ÚÚÊÄn vÙ²7ýß*¨®Vau …ª¸(ïæŠ‹íU\¬de%«E”¼Y¹£Ò©ãÞ84šD§.BÄѤ“Ý.JyJ49Ø×’ª†$oB:o[@u:Äý]Äžßÿ>©èÄIFŸs¿×Þ´â’/RR1kË¿þu®¸ç ,`Ço~æo~“}wÞùæOJʦMcñ—¾ÄåwßMùÒ¥l½ývžÿÄ'8p÷Ýê­P(á¢P¼Ç+.¶ÌpIdRq}¾–”!7`&ÒÞ”A7`%Ðm!\o,ú+.!b„‰È ÚЙ)Ú`“¬.úÒøW?¶kÛ|äZwîäÅÏžûV¬ ¯¹aès0´,3nöqïvࡇè«?¹×&XZÊø‹/æÃ/¼Àœ[o¥ß²xùÖ[¹»ªŠ¦uë¼¾“Ý¿¤„ñ«Vñ'ž`þW¾B4aßþÀºüGúÔ [¡PÂE¡xï #OŠ’ó­OĤbÿ鉣8A+Ža%¸hÂ>Å3ñ„KQta!dŽ@ñO÷hC{M4Å +ý_t š_~™žÃ‡O.š4¥ÿüϼÿÁ)™3‡¶;0£9“DC=¦6„YXòƯÅÍšE˦Mĺ»OZ= –”°òûßçý?LñÂ…ôG£<¶z5'ž~šîݻߴú*+ãÂï~—¾ø"Óo¾™)W_Mß±cê…­Pœ&”ÇE¡8ÝŸ|Û’Éà9×[¦˜¡Ky\¼0:Khh¦ B¢#4NM¸ DŒ¶l©ãèZÆÛ"|~—TFZÈx—L¥bçþ'›þ÷ÿfÌÅ3÷K_bÔE,)VLºì2ŠÇŽåןþ1-?#PRù1é¨ÿÔ÷¾óIå¸èc.»ŒÂ<|ÕU̼é&fâ' “šÆ„K/¥xÂöþáìûýïy쪫¨™5‹‹~û[ªÏ;ïM¯_éäÉ”NžŒcYÈÔvm…BñÎøûö·¿ýmuŠÓG¢iÝ»·Ð×XˆcJO¸Þ¶géºI½ù*]ḠÍu‰ v´‘ßãÒ¯ÿýÛ>¸íp÷Áœ€††ë„pqe2Ê_ÊŒÂ"óÕ•`kȈMÅžœ7¹%kæðúOJûo;vŒÖõë‰8À¨U«Nš>›_UÅýÏÚlÒj°K Ïœ›~¼œÇNß’'fiТhôù|ðÓç’h;Áûï§sÏ´¼<ʦN=i\^y9cÎ?ŸâiÓˆôôбon$‚mšäUU½ip]J€® Õ …BU\Š3VqñFž5¤ë¦“s-ÇA$+.þØ)ìdÅEÃ)\䈘s½ŠKÐà8Ò«öè.¶¦cI W×2ɵþTݬ©¢LÅåÂïŸòsÏeËm·a54»ë.â\òÄ'?C÷J9Z2òß¿vÀŸä+pdfñbò<žzÎä?~z-S–ŸË¾{ïe×/Ɇ/™]¿ûz晓z ™~íµTÍ™CËæÍtïÛ‡ïê"TQá …B¡„‹Bq6â6­Eìþ>†YliÉQhéÚHÇFs2¢Å»ÙØBC3½O÷!<Ë)¶Šîz PA ƒ¸À¶dz4Ûrl¤n`I;5nœŠÝwè¡Édñ##\J'Oæ¼/™QK–°ñ;ß¡kË=õ]ãÇ3ùúë™÷ÃYqIá’šhò %!|±ÿ9ãÑš'v4ݯ˜5‹ó¾ö5F/[Æ+ÿú¯4¿ð÷.ZÄyÿöoLZ³-öz”M™BÉ„ XÑ(Ò0š¦D‹Bñ·øáO]…â4 —XÑÝI îM1 _ì¿Ï Ì92c,o²Hâ¢=¥sé±f"Ç$œü³áø§Ž2ÆX)œAHîý¹òJ>²~=ç~éK¸cÆÐ|âÛþs¶Þz+][¶àäDá;×ðoœÕ†´nÀoÖºLoM2òó™rõÕ|xýzÞz+Ñ®.ž¾ùf6þû¿nn>iò­ÔuEEè¡ëâlßÑ«^´ …. ÅY,\ Â^ŽK*1ן ›Êjñ2\|Ù. /Û%˜LÏÕ„K>-§t.vPrcí¤PÊÁÎΑ1¬šë ¤M »Ž'h†.é.šÆªü€UÿñT¯^MX×Ùvûí<±t)ÿó?³ÿqÀÈu69w¨ÝI¼-;PXÈEßû—ÿîw,ùêW)=šÆW^ÁŒDÞôÚlÚÜîßÂE—¼Ìî©gãk]êÅ«Pü ZE Åé.&Ðï`ÄÍL«Hó&ˆ¤cc&ÛDÂq=¿‹ë Mh6¸®F@H¸Há¾íóØûë_ \E0'èÄ1Ì8–™špÊiUéÉ$_ÝÀÒt\¦‰á&º×¿Dïë³(Y¼xÈÇšvÍ5TÏËÖ_ü‚#=Dßñãl¼õV¢mmTÌ›Çø}ÇÐÁñ] ××Jm©vsü.d‚ðŒa>ƒ Á¸‹/fÔ’%$úú–” åå½éõùýÝì?ápó'·1N1¿¸}¬¨P/b…B …âì.NȨIÀŒgùJlÿ´ãšƒƒ†a‚«yÂÅ.’·'\=ö¯|÷»4ýh5!bDí„7š-]Ç3 û…Kò˜HŠ+ÝLpL„€îM›Øù™m,¼ï> gÌR<”LœÈŠo~“ÉW^ÉË_ÿ:Ý[¶°å¶Û(;W\£×Iz\4é ‰O¼ŒûÇç}!]‰‘úàŠ‹£ à-M<ù—vž^× H;ööñ¹Ïï`ê¤~õËTUOëëÆŒDhn¦sëVZ_z‰xS“®¿ž‰û˜zS)Î:T«H¡8ÍÂÅî-jù)f/VL‡Ðù[EfÜkéXq–‰d°pq]—íï?ÛgÎäÀÌ™tþøÇC¦ÁŽ»ðB>¸núèâ¤Ç%–½fÀŸÜkùý.¾óKÄ1œB â¸4mßÎÆ5kØxá…žyv‚%%LXµŠ<ü0ç~ñ‹„¥¤µ¡ ·ÜBã ë2Aw¹›¡sÛFZn«H‚‘š>uŽœˆs´9ámÎ$ÏÇì9æ‘'Z¸xÕÇ}³ Ý‘ý„ Q8f ¶lýÝï8ðÈ#lüÂøËÌ™ôîÚõ––F*J¸(Š¿žØ]  XÉh/×3âÆ’†]Ÿ)7áKx­+††ƒðµŠ"mmf<–^7>ŸDFȤÒ{‰!Ó.h *ʉUWÓÜÐ@Ó† l8ÿ|ú÷îÅìì RR4f —þøÇüý¦MäÏ›GO4Ê@"–LÌÕ2ÑþC}ŸeÜ•i㮈‘Ò-^†M0)†Â/A™þúÆá~´à#¼ÿÚ´wÄO]Ì:V,†Þl-¤D…˜þÁòñ½{)»øbzâqàñyóxjìX"Ç«÷—â¬@Ð)§ëð~b>€´ ÑÀµDºr"“!t‘ü8Ÿú^:.AÛFâ’¨·5±ä¢s`üvÿæ7ìüÝïH˜&6`áÙBžžÞ;î ΂眓u.Ï×·b ì%nˆöpm‘´Ž$CïÜÌã§Cñ\Ý´ „fœÀÑã¬Z> ?õ~ú;;éil$zâ wÜÙÙIù²ehCµh„ ¨¶–)ï{„B¼–KÝØ8ÉíÐä„ÎAN]òkB‡p¼ˆä–¿/¤¨ðÔ?‹mÚÙÏÚ—»Áp½”`é ¾ó×ÁCa¢¸.Œ—O0ø×=¶cYD;:èÚ·Ï=GúuDÚÚÀ0È«ÞK*+cÂêÕØšFW}=‘þ~ýýt¾ø"¡ÊJ´¼<eeêͦPÂE¡PŒ€p9¸Ÿèƒ Y.fX[dÄ .¸äï«æ8m‰KXH"BRÔÒÀ¢-"&L&°x9ãÆaº.íuuØIáb.}úi„e!b1S§ðòñ†Œpé âZɤ^€”ˆò‹—äyi ‹@8nÅÑ5rþ´rÖÜú *æÎ%ÒßÚJ,¦ûv¬Ž"‡Q¾bÅ×#XRÂø•+y¾%àæKÏy'F¬àK©`Iá·|¨¢‚‘.aÖnèò‚ð4Ÿx’ÉÇ÷ ™={úøóŸ°¹òŠš·%\êÖ®åõŸü„c=ÄѤïÐ!eeÔ‡¶!‹‹³bÅ“'3Ð×Gg]ÑæfÿügbGR¹bÆ0« %\ Å[ÆÜ·Ÿè@$À‰¥âþ3Õ ‘UéÈTa4Û%èØ>á"(lkf~¸v¼F~ËQÆ|àjÞES¦plãFâñxN·É" IDATFÀÄãD^xÄæÍäÍšE`òd^­?Š>ð±xHw(YqqUYdŽˆÑ6þº“@Ô7³´6Ä‚KçSP[˨óΣ`âDºêëéom¥oǬãÇ™ôOÿ4ì5Bðȶnv¹ù¸ùh¾}DþÊ ¾c@z— øÇFH¸ì ³öÕdÅ%%V†Z9à1›·tó­oÌü«Gj¡²2 F¢lÆ b‘­­ôíÝKçæÍL¹ñFÅÅÃß_ש˜5‹QK–`”—süµ×°l›¾èß³‡ÞW_eÔÕW«7â=‡š*R(Fç]‡¼ýáa~ÛpE1Nÿ†m"4Òé¸Ò?ŠœŽû·®ƒëJl×Áš·h3 úþzÄñzä–TÜ÷ ¥Ÿûå³f±é¶Ûhé%LÀ€yð æ'?I~EÆ·¾†æÄÓ ]Gd¦Šœì•"uÌq¦‹a&"­ ï—w’‚ÚZ¦ä#”͜ɿú O> µµ4Ü{/c?úÑa¯™ÐÁÖ@žù65M$]¯ï••š›ÆM{`„᎜ÇEÃó·hId‘<7óUäs2~#+¡ïèQzÇ4M¦ÿÝßôáJ'O¦dÒ$Æ­\IÇÎlùÑh{ùežZ³†ò9sXuÿý'½ùôé,¹õVj-âµï~—®Í›©{î9Z_|Û²Xô›ß¨7¥BU\ Å¿|»ºHÜ|-ÚsAüæ68´Î_Á'hL“ÈÞ½Øõõ•hš† ‡Iq’ i‰‹tñþl9„Íu# A~WVÝr&¸Ý=ðÇ_"×ÞGÙ?}•YŸú4v @G}½ç}1 , ÞÝÕÒBËõk: DÂ!¢ÝA°ÝÌ(tò$Ùç$]-aìO ÉVsçä»Ì½à\Œ ž®ŽËø«®¢rÑ"@á¨QD[Zp„ 8„ÿâ¿÷ô³ËÍÃÍ“`0t{(½šLõ%®CÔ ? Ÿ»6Ÿ¢ü¨¸ì`í¦ž¤ÇÅõµŠü-£ìcB ¾õ¦{¯ÇáÈÚµlÿÅ/ØýóŸ³ãg?#Ú×GÍüùh¡bˆ…ŒB‚ÅÅ”MÊ´n PYIý† ´oÜHï®]T-Y‚ ‡YY ”MŸÎ´k¯Å–’öº:"ýýtïØÁáÛnC8åK—žtá¤B¡„‹Bqaž8AÏÿ¾…øÚ'À-a#샎& ª–ðñz^»é&Ê.$Ò$´’„ˆhišHÛΘr“-#‰·ZÚ!×AâÐ/%a¡žNNØÅTÒ뀴@&lDw'bë´±ãÅ•LùèMÕÕT/^ ¡áÎNñ8áë/%à61ЛG´'–ìk„“2 {âE‹{­"©[$Úzizh;£'Œcê‚Zÿob¤¦Q2e µ+W" )9“¼ÊÊ!7)ÿ÷ì¶C¸ù"Ó*’9­éÛ -“Š&¡C4@AÔås׌pÙ7ÀÚ-½™V‘|‹ÂåÖiiáV³`…ãÆÑUWGÏ¡C´¾ü2݇1æ‚ NÚþA´@€ÚåË©^¼˜Žº:Z6nd÷®KõÒ¥ÃnÚB`0qõjJgÌ ·µ•îúzLÓ¤ãÅÑC!ˆF)Hzœ %\г˜ž‡¤éÇ?À’™.†´AîÛ…øËÁ19r¢‹îÆFJæÌ¡xÖ,´’d0ˆ<ãl<†4-/-×õeqч`²Ò¤OH‚½Ý8Ž €06^·BZ Ù@S#<öGÄìy„V\̘óϧjéRЦN…¼<z{‰]|.A»‘î|O¸Øø¦šÈ2äú=7ZÂ&‰# ‹xÇ…uM,»rSŒöj°¬Ì«ˆ¡û9Œ±Ûↄ'REäz\Èö»$ ˆE]>{uÞ —k_ïÍ6ç¦D“_´ø*BB·¾8-ë¿S6e /»Œh8Ì@[m›6iÒW_OÍ0)Ã~ŠÇgÂe—A0H÷‰Ô?ö˜&‘†*,8é}˧OgÂêÕÄâqúÛÛ‰ôôÐö 4ÿùÏNšDÉܹêM«PÂE¡8«…Ëöí4=þ˜' ’77ùfÜþ*±½Û¨œ8wÙ%ΜI ²Ò-¡"/Ï«¾˜ D4‚pœ¬dÍq ¹6—>é —@Ž#D²¦ˆ¤í aÕß…¼àbDIÒ0È=šâ3ÐKK骈£ÇOÐß™O¬7ŽgÎ%UéÉn"%\,‚Ñ86‘Î(…uMœwÅB¦,û¶¯ßÇãìI ÿ$_¬ Õ>Jè×=áre>…ù§ntÙ´€µÛzßÜœë«Æ!øÖW2‚ÅÅŒ»è"J§O§ûÄ ?òëÖaƒŒ:ÿü7=—@q1Õ RvÎ9Äc1Þ{/ÍëÖ,*¢jéÒ“ß·¨ˆ±\@ÉôéôwwÓ}â¶i2°w/ÅS¦P8mšzã*”pQ(ÎFº÷ìáµ[>O´³;-7)^\ï&-(O„)h£pþ‚kÞVQá –Ô-?iËB l+3íº„\K¿ô #܇# ÜbƒX,–%š„ ‰Æãnü²Ö«†M#PRBwSݲ=Ú@GÑÞ 8dÚS¾Š dŽãºè ‹PÜ.áî…Gš8ïŠE§$\:j²Ç2<ᢻ™ŠŠßÏ’+HV\â:EQ‡ÿyy…y# \FX»½×]ÐüŸ[iÉ>vh_œëßW5è¿§‡B”OŸÎ¸‹/]§aÓ&Z7näØã(-¥<'_gÐé`Ò©S©½à‚ÕÕÔ­[GÛúõ4<öcÆP|’Ö R6mc/ºˆ`M '¶l¡xÒ$J&M¢|Ñ"õæU¼+Qɹ Å)ïë#‹Ö4¬ çÓãêt[ÐmA—Ý&ô˜‰ma‚?û7´KÆ"íÀ˜?céRŒóÎËÜ–,Á˜9ƒ@Q!ÛL&æÆÓ_fÊ£áPX[Ã9ßøúÂ…t´ Aд»Ð‡CX3NŸ³’)ï{EA‡ ÈdzrÉDßTìÈŸÞ›º9^r®tl¤p‡ÝýVqB0ôLÜ¿?×в7C¾øÃK³ÁõÿøW< ëbÅb„ëë9øË_òìÊ•„ëêHtuyU”€–Œû™èÿ€L&éŠìu†`ÇþáÐê:åÓ¦±ò{ßãÆçŸÇ))¡qëVžûøÇ9úÈ#DZ[OzºBJŠÆŽeá¾ÀuÏ=GñÂ…4lÛÆ³7Ü@ãsÏkoþ±5’‰YüÅ/ò?¤öºëDÕXñ®DC+É’ÎNúvíBK~ð.¾ðBDN Øk?ü!µK—2õSŸ¢¸²§¥…ögŸ%¼m+‰H?qÄ]0](p ¿;†1CÜtüö)´ÊÄÂ…ÈÊJìÊJDy9²¬ YQq/ìXX¸1ó\DQ‘çyIÝòòRb¸áâÄãÉV‘DÆc««™þ¿>GÑĉ”{.ÁêjzZZˆ†Ã$ /¿Å9y"e 2¿_j3 5=ŽÖÓHoS!±¾ "ÙÛJyYD²2!Ó^Ϥ«Ç-òì8ŽáÐÓmSPßÊyk2iÁø·}­Ÿ<:ÀÁ¨M¼0”IÎÍõµàÿ>©\,L’ˆCI¸ñ­µŠ¤®SlZvocê§?‹–̩ù1dg½Í…ÄzƒR{EVbnæÏzÌ&ßcé.ÝÝ6ù'ÚYzÙB&-˜ð¶¯÷SuýŒX˜ì€1än A$˜,’‡Š~O\ëÒ_WGÓsÏqôž{(›7}¨]IIT2aW¯¦rÞ< 'O¦ëÄ öicycüž€’>±’5=øœJ±Y_Ë‘‡¢oß>F-_þ¦É·ÕsæP³hy55|ì1Ž=ñ={ö0ê¼óÈ«®>é5RRKéìÙÈ@`ÈO¦Ò0¨ž7Yý(ÁÑ£iÚ³‡h8Œ˜}}ÄŽ¥÷¡‡¨¸þútKî§a£¨ˆÂéÓ)š6 ½¬ŒX_˜þ¦,×Åv|Õ—”…â¢Õó#¤DÈÒRdY"?ŸH_Ç7¬§·½Ó Ó¶ilid×îfã~@Au5åÓ§ª¬Ä‚¾®.:ˆÄât76"C!F/ZDG¤—’¦Gp[;¼ŠK_vÅ%Øë®¸q‹|éU\ºz]‚M,]½€‰ &½íçåùÃ]‰$0ó8R®ÔÆ]x!H9lE y¯gMS¢E¡„‹Bñž-®Ëñgžáé}ˆ¶§Ÿ¦îûß§döl°m‚5ƒ7û MÃ((`ÌòåŒ[½š–ƒéïêJ//4#Ún¿Ç§äòËÑs£ì…@h¡Q£(™=›ÐرÈü¯úÒßi9ØÉ¶‘åBÇKk)¸ä2c<¯ˆcYXŽCÜq8þê«]¿~O<ë…]‹ö7vÑ|葎ºÁ ‡©]º”²)S¨<÷\,Ë¢bî\&¯YCéĉ$Âa"Z‚ŠÎ'°›»“—€—‹“¬º8éqh‰o€ëµŠ ´(–áÐÑ+Èk9Æy—Îaü‚oëyéhè`Ýþ0ó ldÒ>â‚&}Õ‘í/AzûAYØfjœëÞ_ˆ 2zéRª/¦³¾ž®ãÇéxýuöÿûèÁ å‹}/„`s£ÉÚC™VÑpm¢œcUy!n¹¡£ €ÑË—3fåJ:ëêh|þyÞ{/z~>eÓ¦ Ÿ|+%ÂB&^z)¯¸­°ª9s¨š9“övÅÅÊ»¢P(á¢8«pš·nEäçc A¤¯Æûî£ýñÇ –—ƒë=zÈ»ÔÔ0ㆰ… «¹™þŽŽ´gÅlk#¶};RŒÊJ´!| Z(DáäÉäO ¢‚X$J¬/Œá$÷Æ€Š~'”O¸¹™Î7Þ ~Ý:öß?uÏŠ]_OÉêÕž¹vˆ N¨¦†Â)SÈ?Œñ¾>¢½}$l‡„ ÑDœÎî>Ð46ÿô§yòIš·n¥¯¡!í³yyNžLéœ9”ÏŸOÅüùTÎKå¼yŒ½àÆ_r ÁâbòÊËÓ“-yååKJÐ’•†þžc”€Dc˜Þæâá@F¬d™r]_å…dÅÅ¢0#¡A{¿†ÑÚÎ’U‹÷6„KôàA6ßý$ ˱ÆVÈ3°™#š\Dr?‘W}!cÜu$¸’ò°Í¤žwU¶W ˜°j%S§îé¡«¾ž–uëhöYòkj(›?°piŒ³¶.’  ÂÏ2Ô±ªP[Þ_9H°VΞåº4¾þ:Û¶ëê¢pÔ( ǿɖ„JK=Cµjý(J¸(Þ;<~ãüÝïèÚ´‰Žuëènj¢jáB¤>tL‘ R4nÕ‹Q8iÇŽÑ×ÒBìÄ ú·l¡æ²Ë0†Ø` ž÷¥lÊF/[FhÌê6lH‹ˆîÛGtëVÛ¶QrÅCŠ'½¨½¼òòèkn¡óHqÓÄÐöÆnê'ÚÓƒ ’‡é>rÄ‹w“’@y¹79´`esçR:w.%³gS±`£–/gÔÒ¥TÍžMɤIO2Ñí>Dh÷8mQ¯âÒoøöù*.)ñ’-Âõ̹…¡8qÝ¥-¬£µw°ø’EŒ[pÎ_õ¼ÅÛÚØ÷ío³uÝ6ZfÏÅ©-ÃÌ3°L™5’-}fa¤ÀM{8’>WPÞï0¥;Á5W )8˧Ogô²ehEE4íÚE¬§‡Ž×^£óå—É«®¦pòäŒpiJ°öh4gú䩹iárueŽöèùùO˜àe¬äåQ5s&ÂBd(„4Œô¤—B¡xk¨:Å»ž‚ ˆ­ÇÓ{ô(/¾H×}÷±êµ×ÆùÉ«®fÚ‡?LõâÅlùîw9ñè£4lßNôâ‹)™2…óŸ}vØûϼÏ|† —^ÊsŸû¯¼BÂqHñuëèÙ°˜øÓŸÂ†ÌPe%µ—]ÆÆÛo§-‘ à€nyÙjN}=7‚Š3(¬©aÛwÒ´e …£GS6q"åS§R6y2¥“'Sp€h$‚é88ŽƒyäM#Þµµèyy™i•¿¦Ðù:æºGý&íy$Âzº¢’ñ—8Y­#é:×!`YåLjIh‰ ³‡Åsj»h.n4FÇ7¿IÃsÏïhÇêêÂimA{ò1´åç{ç™_@áèÑt>ÌñÍ›i Öž>Q]ˆi°"mö„Sæ{‹–ü*ÍtDMÊ¢.“Ntc|íbj¯¹£¤dèx55Ìûô§‰›&íuu„ÛÚ8ü«_qüW¿¢¥dÿòã=ôÎçkå´ˆrG£“U™ŽÉÞ67^DÝ`ƒ®p\‚nJ¸š#!¬î0‹i`ìñ§ =@¸þ š¢éQïT^ ¸{v![šÑìC\p¢"öt™ëhG/1ˆÉ¶)³*?$ÁécÉ󒎃· š ŠƒI &…Ÿ£móf|DS5«V Y-KU@*gÍ¢vùr‚554íØAG"Ÿ]3/§oVmrú$ɽ2çXÔàœê<>xQþ»6µ6¼g÷ÜCÏÓOÛµ‹¢óÎ˾fR’_YIþ¨Q¥¥8†AwS‰dD€ „7l ÿ‘GÖÔ¯6P+”pQœ-ŒZ¸ÚóϧráBhyõUZž}»§‡Ú+¯<é}ƒÅÅŒ]±‚²™3èë£íàAzví¢óå—!¥fõê“W#òò¨˜=›ò¹sq ƒÎãÇiß°îõ둎CåÊ•ÃÞ7PTDíòåT-X@ɬYF¢`ìXd^aÚ~ ª«É¯ª"PTtêþ‡Âß‚q   <ë¯â¯?Gä¥W ¢‰°‘¬b UeñÐ9\“¢¢á ³{€…f#c òê)-ŽÒoBs¯â!³g7bÃKh‘rÕe¼~¼‹ú–&‚#%\2«$Þd‘tÉjgI×EOX­8"ÉaÉŸ]H"‘ çÄ º¶n%¼g};vP³fͰ—)¯²’ÚeË(9“ŽˆÎc*}3j}‘ÿC·†e¹D<áò¡ ß}cËæÀ›6Qw×]¾ã:Ö®e`Ãb;wâ&Ì›õïC¥¥Œ^¼˜ÑË–Q³t)áÞ^ÚÉ<ߎCä•WˆoÛ†¦ë„fÍR?ÔJ¸(Þ:“ãâ_¨8lŽ žp© q㊼wå{³eçN¶ÿö·ô44xéΉ‘½{‰®_OÁôéäÍœ9è>¡ÒRÊgΤö‚ 0ÊËiÞ»—X$â…*ÆbÄöî%òÒK.X@Ð7¹¥P(á¢xW0ÐÚÊ?L×Þ½toÜH¼³“Âqãȯ®Öx›'­œ?ŸÉ×^Ë@w7M›6Ñôä“òó UU(+²4/¤$PTĘ+˜xÅß¶pGá†Zž|’üšo!]yùð—GŹç2ñškp ƒ„m£ A¨¬ £¼ÜóÜ îiHÃöÿíÂyc+ö]?Â…6ˆþ.xî‡pd̹­ó‘çž!úê^䀈 H/!7eˆM%å& ¼6‘t\‚2AqQ”$M‘ ñî(ã¢ÔH“@ÂEØ^±"Ï€Sá@tGI·llÿŸ½÷ë>ï|?¿s¦bú ƒÞ ‚$X@€¢$ZÅ=Ž,7ÙNòx½Éî½ñÝÍ“»›g¯×›Í&ÙGvV޽¶¬bY¶D«S”H‰)v $Å"VDïm˜^Î9÷€‰â8×¶äà}< ÏpΔÏù¾ß÷ûªÉÊð0×칌•`°@,e@IHécg¦šÒm¡ÌýRgv•̦jbMvJ&%vnÊBo±à]³†¢{îardWCï¾Ëõ¿ý[Ì>_zzhŽö›‚±»>#X;;9wfjîÌÑÌßE3à²áÃ.J4J¬¿ŸÄÈz‡cÎç£$˸—-£ìãGöxV+)M# ‘˜œdü…èÿÎwÈþìgÑß¶üQd^[¶¿};#†‡Idb’¡ã?ÿ9ãÿí¿áyääß&Ä/Õ¸,ÕRýKÊ`µRûùÏ“TUü½½ :DÛŒ³º÷mRô\*F§“¢{îÁèõ¥ýùçi}ôQ+¾ö5âÉ$þ¾>Âãã ¼ñßÿ>9Û¶a)-]èàìv ¶oÇY[‹!'³ÛM"Ioáý†\I"™ %@UAR@¤TÄX _CMÁ仈·"%r$E½3»eJíP3fXÒàb’“ØQ‚È „LÄ1ºGôê£Xä$R ¤ihÒ ªÚÇa,zKq™é¹™WN°$ƒ" JRÌVZfµ®nýNRÓàb‘bèÍnJ&eîi6MŸó,Ÿ¢;3xù2ed[e%‰DóÀÚ3d×%?¡Jß-sî”Ú"±ðÞ¢ˆž:·‰‡šLŠç¦ª„zzèÙ½›ÓôG´~ç;XËÊPC!Ì%%s¾NLN'…[·Rtß}8kk‰ÇãL D@Q˜üå/ɪ­EK&ç[Aåÿ8˜ÍŒvvòû3ç[CQUB/½„¹²2”½ô¦¸TKà²T¿›úà‰'è=p€Éöv, F“Kz=ù6઩! 2ÑßOÏ«¯¢3HNL`¯ªZø k0½bÞµkQ„ ÐÛK÷ / KZ,6+Hl.¤`Ü˖ …˜èï'8v Çòårr ’„%?[i)¯³×û¡ƒõì1üOþ„¤ÐÒà¢e6P+éÈ1ØŠtãmR1"ZFg6:ƒ YUâq„ªÞjÇÌô“hBU1铨Q‚Hô…MDqt¡åÆ f‘D%s¼ ÀÈù£ÂÊXÊ@"‘HoÆÎ€Ko^)±Ò\ Y‰ï0çJólª–45­¸È1d›—¢ Ž{gáêÍf4ÙfCÕëÉY·,ž˜À^Rr‡¨w(Ä®«B¾ô(ô\tsí+š#5~8F5Ea¢­‘> ·¥…Øä$fÿÀH&‘t:L……sÞVg6c+/ÇU_Îé$ì÷' 2þÜsiãîêÕèçX‘¡3›)Ø´ kI ‘p˜Ààà´y759Ià¹çH^½Š¥±ý†õ¥Zª%pYªßX}ì1ÞÿŸÿ“¡cǽ|[i)¶‚‚ùáE§K'™65aÊË£ûÔ)z^±–••‹Â‹¤ÓaÉÏ'gÍlŒwtÐúôÓNŸfü̵µ繚“t:ÜUUä57côùè9wsv6:MCK¥Ð;èðÝLø†lEŸú>þÃÇIr«-£© e(Ad Æl£wh˜‹-à[l2!R)D8„”Rî0è2•b«j˜ ‰4¸h2}aá@]8N.ˆI¤Ò@2L)Ð%ÁhÉ¿ÿcÈ;¿È`k+áÉÉéi£‘¼bÔRú,A8j@MŠÛ¼5Ü9á4CqÉÒÇŽ\|=ÄŒT”ÌVË\••ä®[GöÊ•¸êëq¯\‰»¦f:Ke–â2â—­„ʼs/Yœ/9W"ê\FZ÷á!IX pVW#; \ºDdr’Ôä$ã>wgc#Æyös IÂìõ⪯ÇZ^N2•b¼«‹d"A¢§‡è… „Žǹcǹ-B\ÕÕä67£w»jm%2uÎXG±K—pîØn©u´TKà²T¿íÊml¤ôþû Ðñê« :„½ª Gyù‚c¡&—‹œU«(¾÷^FnÞdðý÷>z”®]»(¼ï> DÖè­VÜË–‘»iñXŒþ“'kiaôw(ýâçƒ>vCe<€>'ƒÇƒ½¨½ÝŽl2Í».àÃ\ZÇuü»÷2qö"I˜V\Ôð¢eàERÀdŠ¢7O {=hy«‘L&„ˆH)›m†2Ī*fc»+Ê„&Ó6œH¡‹ÄÉ!ô¤Ò£ÏSÇÕÒ $KzLwÝOοùKÊx€ÁÖVF;:P€‰¼Bô%^ôfA8lDMIwª>3!f¸(X qTO>¾€dÐ@SÃÏ‹[a!Y998Ç=#ž¿9A¸Ô;#ÇeŽÜ1G )¢§Îiä¡5¿Ùÿd @ç/~Á•¿ùn>ú(Ù›6a\@¹Ð[­xV¬ à®»ëêbôæÍ4< 8tˆ‘矧àÿxúIû¼¬¥¥äl܈¦×èï'<>N¬·—èùóÄOÂûµ¯Í >&·›œ†ò¶ne¼§‡ÑÌä‘Ä»º(xä‘yÁi©–j \–êW®T4JtlŒP_oÿùŸSqÿýéHùyT£Ý޳¬Œ’ûîÃVZÊÀéÓ´þä'|ðâ‹Ô|ö³ÈüY$²^­°òD²Zé:vŒÉövn>ñ•_ù Z*…n²L–×KÁ]wáX¶Œñ®.Ư_§ï¿ ü‘GÐTõŽÔÚ™Ç¶ææ’³z5ÞÕ«±”” w:?šÐ¢(øß~‡®_!Ø?ˆª¦éU5ý¥e¾×¦~VÒð"¥äTé}D^dW" ˆT )A(©´)—ŒaWU1›8=1ªDoÈLpBAã”ãHj2 -ê-ÅGUAÒ0¬iBÞp7–¼j>ûY„ÕJÏÅ‹„²ŠÝèŒSà"f'÷¢Ý2 gŒ¹BË€K,‰Å”@ñ‘;iÄ¥7°~åÂ*ÄBáp=cvu —dƒNܦ¸Ì¡¾Ìüïá ¸4üúcìj$Bjx5DÊÊšó5wñ©§h߷ηß&ØÙIïÓO3üÌ3äá ó‡$êõXóó©øô§ÑL&z/^$™L!ÖÓƒÿ7ð>ø`Z•œ#õVÒé08é\¢ª*bïK"'ÖÙÉð£kkÃy÷Ýw¼Þdƒ[a!UŸûIM£÷üyRªŠl·“º~¼Ïþ7’U´TKà²TÿŠª¿¥…£ÿé?qô[ß"10@xd“ǃmž~øÌ+3ߺuä65`òÂn<÷²Ã%/ozSñœW…YYoÛF^s3ÁÑQF[[¹ü÷ÏXK ¹[·bœgéáô±M&<+V·y3)U%3ÑÒB*Æži ,ôa6ÕþùЇ¥RÄDkoG’$DF^W ““L^»FÏ¡Ct;F<E“õhš„šRç—©ß¡€”ÒŠ‚.u êÀ· a6#d )ELy_2SFYY ¬…&¢)úB&&ƒ r4Aùú•hñ‰pEÕ¦UUÙ˜…Åc‚ü\È«D6(ܲ…Â;èëëGÖÅõ‚pȈ–šù?—a8ó{UCKaÉJ å”à ™ðÈzÖ­øõæî±Ïw‡‰{ÒŠË,eåv ³!&¬'[Ö³µ\Æmþg>T•èÍ›ô?ömŸù þGÅTSƒiÓzÞºué 呪^OJÓvuá?pky9²Ñˆn.µRd£‘‚M›ÈÛ²…ÉÑQüýý$ âýýô<ú(‰¾>œ7Λ2- Ø««ñ65¡w¹˜!ä÷“ŠDŸ;‡ê÷cŸ+e:³âÂU]¥¨ˆ‰¡!T³÷Ê•d77/˜j½TKµ.KµhÙ‹‹)¹ûnT!ð·µÑ»w/‰ÑQL99XˆÝŸ*k~>¥û:»ÑK—¸öÌ3Dq”—§ ­ À£¤„â»îƒw7£çϼqƒäø8öÊÊywM•Ùë¥`Û6ldcÉÍMûV>ÂoŒÉë×yî9F¾ô%”Ÿý ÑÑ4:ŠTSCJU:ž~ö3:'c«ªÂVV†Þj#9F‰'ÉØT¦Û7ÚíÞ—Œ£ _…‚e_‡0›ÓêK2™˜d Y¨X|F}‚x*E_ØÌDPCŠ¥ØôŸ¿…³ªœˆ?@,"OLKïp`]^‡´r=ä•MÿÛlùù„q‚‘uáUófÈÌÊvQUôñkÕWŽ'œ—5õ¿þcÝãñ|_˜H¡gn‹4Ï%@×Ý'c×Kì¨üÕ5•"ÔÙIûÿú_´?ó ±p ïÞMÈUÍ™‰z*+fC€Åç£âŸ ðî»ñ®]Kh|œñË—éúÑHö÷ãÞ¸Ý<^-!IØ‹‹ÉÛ°aµ21´¾±¥Z—¥úÖå'ŸäÒããïè oýúÿ_½ÅBñ¶mØËʈƒ´¿ù&Ã--L\½JéÇ?¾è±t&¾uëp.[†ÒõÆŒœ=ËXw7%Û·/x[ƒÕJÑöíØJJtîÛGÿÞ½„»º(ýìgUEdƒGy9¶²2LyyÎ웢ê÷3ð“ŸÐöïJ&IÊõë°w/R?ƇNgÅètDü~²ŠŠ(¸÷^|[¶`)(M EI‚iP¹Mq™úy ^dEEÊJÁæGÒªKVVúOEAÄ¢ÈJ‚¬MµDBÄ1†¢FüañÿŸ¿ ë&L¾\”¤BxlœD( *<ÙØj–¡÷y!· ·Ú}W.ê8$I„CTEšå¯™+îÊo£K*Xm ”Ü \1 ¡gõòâˆñü@„h¡+ .wq¹³e4¥È„ 4²µ@ÏŽê_]qÑT•޽{¹¾o#7nRÕéôÙ«ûnòWgÿ ×® òóàv;ˆÉåÂYSƒ{åJ$«•‰†%zó&ásçȾ÷Þykt:Éß°w}=Á±1†[[Ñ€àùóŒíÝ‹¤ªxvì˜ÿ5n6c¯¨ÀQ[‹f4 …H&“à÷#Øç‰û×[,ä44઩ÁQU…¥¨( ÈKà²TKà²T3ËßÖÆ©¿û;Z_x‘S§öö’³fÍ‚í!I¸«ª(ؼƒÓIÏáà =Êø`ÎËÃ>GĬÛË2Ž’ò6mœ›KÛîÝ ~ùgÎÀ±cðÀý‚¹^6¦œ<«Va«®&<1AßÁƒøG#ç¾ûæý÷J²Œ£¬ŒÜæfÌùù ^½J$L«/§O£F"dß}÷‚™ÑãA“en²¯Ñ¥Z—¥ú —Ñn§òŸ ôþû™èì¤ëõש޵kLw’”ÞKÒÔDɽ÷Òqø0#§OÓñ  ªä¬]›6³Î—›I¯õ®^Mŧ>E £ƒÎ×_çÚÏ~†d±à­¯Ÿ× +$ “ËE~SŸù ÑX ‹Ï‡ÅëE2™0-ä{ùˆ—‚D0È}û¸±?Á@EÓÒŠKæ+(¨§N!æ1û|ÓS3z— sY†¼ßGúÜ҆˜¼vhg'J0ˆaŽqVƒÕJѶmxW¯Æ?8H,™$“TÕY£¤R¨‡!þþï‘*+‘V®œþp•L&LÅÅ 0x½ÈV+©h‚ÄD˜d,‰š-³HHÒ$,%9 EË6!¹\H.de!,¤‚‚ƒCŒž¾@4™ ¦ qjR¥æ÷“Š„é=~œ¶7ÞàÆ›oÒ÷þûŒânhÀµ|æ¢ V®ææÑcX 8wêûôcÊìaP$“F4EÜ1A45^pËœkRØ< ”ÜJ²T7¾T?Ëóþ¤q] ¼ÿ,€é%x. æsÌð¸0ÛãÂ†Ý ¸HQÛ `{¹` ¥…›o¾Iû$S)’ñ8ÉpÿÏ~†ûÁïLžÍ¼FmEEï܉½ºšŽŽÂ" !iD¢ÐÛÇAu•Àd‹åNõ&oûvË–öûñ··3øÚkÜü»¿Ã½nÖyTI§Ã^RBÍC¡ Œuw =z”®ŸükU’Ý>ç{ŒÈ¼¾ó7mÂV^޵¢‚¬¢"ŒNç´,Õ¸,Õ­êy÷]ÞþÆ7¸ðÝïrý©§ö÷ãmhÀ4Ïîé“n0à[·_c#©XŒ~ð 6±±1œ‹„¿ I¢pófœ55„FGé;|˜ëO>‰£²½Ý¾`ûgêÍ1·±_c#‰xœž7ߤãwÈonF—•…ÎdZT‰ø(¿&#­­´þøÇœûÖ·èúþ÷ 9‚ÞhD¶X0Ìœç(-¥öá‡qÖÕWUƒƒD#‘Ù›—3_Ú+¯ ËÏGGTÜrtêNŒùùrrÒ_²ŽD H2EUÔét]Yg²r9RÕJ(]~ÌÍf$§Éf#1r¢…ñóWˆ¤RD… œQ’*‰‰!úŽ£çÈF._f²·ÕJns3žuëpÔ-'«´9ׇ³fF‡ƒÁö.úŽ¿C©=‚–’ J3ÓêÊüæ\“–Àž“"å«Ä¨åP”ì¡Úù¨g@< ’¤Í¿:¸D¦ÀÅž^²8WØÜ— ÌD H™mù‚í¥[QF¯—‰±1ýýÄc±ôòÁh”ÐÁƒèÌæ´26´ IÂ^µŒ=ky¯ÃŽ"KBhtuÃO üã°qƒ`.Ϻ£²ϪUHV+“££$&&~ñE+WÎ /S:t;†0›ÉY·ŽØà þÌ>ßœëf÷¬,Õ¸,Õœeñùp×Õa¯¨ 40ÀXK «W±äåa/+[T±ãklÄRPÀ¥ýˆ›/½„£´×"+è%OM y6`ôx8žö—_&pý:f§Çbð#ËØŠ‹Émlĵr%öü|”x½Í†Áj]ptù£^j<ŽÿÆ ®¾ü2CW¯’RU’ÃÃŒîÞMìúu\›7£Ÿ£&$ We%ù›6¡ÏÎÆ?0ÀäÈHzÌíð²gâÄ äŠ ¤êê)âC6›1ø|óòÒ "Mf’á(©`5šH/G4[°Ô×¢«^%·Æs„^O"™däüE:ߨËdwÉ”F"íË%•Ò Ü$Ö7H^s39«VQºc÷ßOÙÇ>†oõj¬eeèN„ÞÎö‚¡¶vŽï§ÄF‹Ë„ƒ&T…ÛŒ¸·o‡Ö¦Í¹&âØ})R¾*ôR.űÊM?½µ‰C A±jÑóÓI²k"F2ÛŠfæ^²xÇ”i¢é‘£2Ûs5¶•¤ÕK[a!…Û¶!¬VFÚÛ gv÷$FGñïÞMüÚ5|€µ¹ùŽü”T þf“¦ïS14„¤ñþyÁ@?\¾,غõNÈ7çäàihÀZVF"™d¼£ƒ‘·Þ"18˜N žç}BŸY`ªs8Ðggc¯¬¤`ËœUU¨B`] [ª%pYª9¯þÆVX8o Gg2á®®&¿¹™Üæf‚ƒƒt¼þ:cï½ÇD_9k×.ÞéÞºwÕ*rÖ®e²§‡+O?MÏÛoãY±bÑvŒÙãÁ·f ù›73ÖÚJ÷þýŒœ:E*‘ÀSW·¨zb°ÛñÔÖ⨪Â][‹Éí^0¬î÷âg0`ÉËÃS_³¾žD"Axb‚x4J¬½Ð{ï8tßüÁ¼W³ÞL^M4¥ÿÂ…i`Qgü©úýh§N¡_¾iÆþ&¡Ó¡s:1£ÏÎN›g‘ÐR*DSÈF3–Uõ |`w“P$&::è;q‚Ž={¸þâ‹ \¼H4‘@Q!¡AR5•vûª±–ÂBÖþÙŸQ¸iîêjlùùifVfÖðÍv†ï£ØEË„& Š;#þo_ü˜Ùm’b8rS$}UHºB ½”ñÓ†ÚI§@Êiþt:et”óýmö¬ÙHÊaB5Ë3|,ÌásáV»ˆô8´.&Øž[‹¤Yç,§¡¼ïëc¬³s8c„Ož$qå Ù_øÂìû£À£ÿ;‚f•f>Úô}™úùâ%8yRÁ]wÝé_Ñ™ÍØËËÉijBde1~ãýo¾IøúuÜëÖaÊÍû¹f±à[½šœµkqÕÕᬭÅVV†uity©–Àe©fÖÀéÓ¼ñå/sæoÿ–Ï>‹ìrá]±bÁì)“>[x×]XKKé>|˜C‡höYêþôOÓ1î ùWdkæö&¯—öÝ»i}úi*?ÿùt4úÇ– ¥¥ß}7²ÕJûÁƒ 8Açë¯Só¥/!ét‹Ž/¬Ö´lþ…MQ˜¼vÖÇãýÿð¸ù?þýÿø$ÚÚpïÜyÇc?åÊih äþûqÔÖâïîfbhˆHOÑ+Wˆ^¾LÎ'>sœ;I¯Ç’—Gá¶m˜ è»x‘H8LêvõÅï'µoÆíÛ‘g쎒„d2aÌÏÇTT„ÞíÆœã# ƒ*°ÔÕb®)g £—«oìçÆîÝ´¾ò =‡! ’Ð4@J¤ƒÍŠ-¿gUF‡X €5//Z¸ÀùmkcìØ›™#¨1áICÆk3#|Ž;G¡Óɹ*YrGAŠ”¯ÍPBád¥ñ§o£8@ vt+@ª¾ó¦Rt~ùË\½ÑÎO?„0J(Y:T½ ’4ÿ~¢i)DD>®±úùï³AëðlÙô“ ìÅÅ”ÝwšÉDÇÉ“(¯’ ÄnÜÀÿÓŸ¢öô`Û±!I( |÷‰0š9.Ò x"ýsb””Æ™3ðÄ_Ž ¾þN•ÔèráïîN·ƒA¬yy$‡‡éõ7wï¦t±Ý=B`°ZÉ[¿ž‚mÛôö2~í<ú( બ\py ½Å‚oíZ ¶ogüæMNþå_ÒöË_RöÀn›‚¸C¹q8(Ù±ƒÒ{ïEËä¨DzzHÆã o*:6ÆÕ—^—“ˆµ IDAT¢uï^Î#26F"`¢¥el S~>z— qÛô”$Ëfì‘IþÁA"áË—éú›¿A‹FqÌÑF˜º’Îkj¢ìãgblŒ±¾>b±)¸õ‰{üqlŸþ4ÒmWÖB’Ò£ÎN'c==t8°ÛqV×aªª¢÷âUÎ<ù ÝÝ8JJ(ؼ™ÊOSN‰D:€ÎRVF^Sóô¹/»ï>Jü p”” /Òö»ÑJàè뚣(Q‰ð¤))“™’5 ‘1éÎ6즧Š,º(ÎÂÉœs9>ŠO#¦Ü˳ưb`þ$èo}ªkªŠ‰Ðõè£Üxî9úÜÙ´Ü÷)$½@ÕK 4]Fy‘æIÍÍ(."¢Ç˜Ph8s€Êïü˜jkÓž¬&Ü©„èòO}Š¡7˜&žH hñ@€ÐÉ“ b߸Mgä»Ï†ÑLBbÚ KX„¤e¾ÒŠPJÀÜ{¯`íê¹a1gÕ* ¶n%žLb«®&{õjrjkïëñÐëôÚ(½TKà²T¿¹šho§sï^bX|¾E÷ádù|änØ@ppî}û\¾ ’D–χ~æÁeÍË£ì¾ûívÆZ[騵‹P{;&Ÿ,ŸoQ‰Åç£üãGo·3tæ =o¿d0`öx0,²9ÙšŸOÙÎX É^±gyùGÞ³¢$“iÕjž7o½Å‚§¶–”¢‚h8L4D&OŸfðG?ÂàpàÜ´iÞc˜Ünr›š°UVèï'4>N2™dòÄ d 5>ŽuùÜÉjf‡ÂíÛ1åæ21†³H%‘³Œ¸¥’±>rGž%³ [%#3õ`èòÐNúåËAÔD‚ÞÇiÛ»—þ õåóÁ½ƒ@Ó‹LG(“ç"Kxá6ßKúJQcR¡îÂQª¯&úÒKÄ^|Sc#úÒÒY`ñù(Þ±ÌæôôÎÄjF1 :…H¥HŽŽóø¥R4ƒHC‹¸¥°0}ØŒòrË ÄÎú>Ö®Ó!æ1ÈívJî¾Gu5æü|ìUU8+*–Þ¤—j \–ŠYWu{÷²ÿ›ß¤ÿÈ&úû)] ÑrJZ6{<(ªJ"ãæoÐöòËć‡)Þ¹sQ×¾Îd"¿¹GU‰XŒîýûé}ç"==Ý{ï¢r¯l0¤Í³uuÚÛ¹üøã¤B!FÛÚÈkl\ôßœåõb°Û?²Ð’ŠF vv2|ê/¾ÈÐÛo8{–ìyàCg6“ßÔDéÎØ«ªH¤RŒutRTÀ¿?’¢²bż‡{ùr²W­B5˜$8vŒ±Ý»1y½Ø×­›ž²²È]·÷ŠD‚AƺºH$¨€0™°UWc­­EšaªB¤ÃhDÉ,½³VUáZÕ€µ¢ 9/{eÞúxjj°d YH&‡ƒ‚æfäø8‰#GH=KÖ¶mÈ3FÞ…,㮩!wýzÌô_¾L4B’Bæ­ÿ!O‰;c.L·‡„¸/d™û¶+¬ªN¢jz§sQ“üGúešJ1réÇþú¯éܽ›±³gÜ·ÒÏ}îû0u©–Àå£A.é`¸œÕ«)¹çÆ®_§}÷n:÷ìƒaAcêª8ýzª?÷9,%%ô>Lמ=h‰‹ìýB`t8ð64P°u+ýý´¿öýûö!4 ߯‹ÞÞ`³áª®Æ×ØHÎÊ•X 0Úl‹¶»>Ò§,¨U°i’ÍF``€ÈÈÁ+W˜8v kq1öùàCL.9 ä451ÚÝÍxw7ª¦‘ 9ÂèOŠkûv skÆo䬩Á×Ô„ªÓÑwá‰`ÈÕ«Þ}çÚµ˜çe5:X ŽŒ0ÒÚŠätâY»kEþþ~¢©ÖWþSer:1¹\èÌæÿß ˜Úñg£ŠÂøU<OAñ§@o'Øz…ÈÁñ@dZE·Oe–éESí"4l–0®RDN-Qû |ƒýØ/?•Ô›‘<µ‹I¤@òÂè®Êõ«ðÞQt•ÕèW¬ÆàÉaïËG6Õ€QBщiåçVÞ”ú"Ð$)Ý>4>¥`J¤Pä\6æèÉïdrxxZEI {ã œ_ÿ:â6Ï’Éå·f Ù«W3tãþ¾>R’Ì‘5ÿî–¿e†ª2=Y$ÝÙ>ºÔeåÞ?(¦r]ɇ2N_{g?Ú[o"›þÅ—ÎdÂ^R‚£²’Á+W<{–ÀÕ«øÏœ¡âK_ZúìY—¥šYÁ¾>ž\¾œcÿñ?òÁÌDW…[¶,ØÂ‘õz¬yy,ÿÊWYYô?NÇK/1tá¶’lóšàdƒ!í)ظ‘ª?øLÙÙœ}ôQŽÿÕ_aËøIšÈ‘3“Gµ_ü"²ÃAï‰ô½ý6]o½…»¾>˰ÀÊTª§!³[ä£-JÝçÎ ‡I„ÃÄGFüáñ}êSJ¡›C½’dsNÅ;wâjh`¼·—ÉÑQbCÏö¸Ntu9ª.³¥zÚ¬Þ 0’Y€$aP’˜ Ö€Ž/ï\ËúÍéq÷±înâÉ$IM#0ù䓸~øŽØI¯ÇQZJŃbÈΦëüNÖÿÉô$Ñ4¸Ls3¿—¦¦ŒÒ߇ã_ø¬™â"ý‡Z’W¯0²y#ì߇øûo#êW¦!Î9;»h¢­žwÞ!Ôׇ¬×£3›çn” <µµ,ûüç ŽáïéaôÂFŽ'§© É`@žÃܾTKàò¯® V+yÍÍø;:Ò^ˆ#G°#t:,óä"Ì„€üæfòšš Óèïÿàä56bòxÐσyÛU†&Á‘‚ÝÝ´¿ð¶¢"Á özÚSWóyäoÙ‚ÈÊÂâó‘ÃU[‹åGŸ`s ¥…ó?ü!]‡ѵkíÿôO¸W­B™œÄæÓ±jUqz™¨ÏGÈï'L&Q"â'Obß¶ ÇsÇ{ƒÁnY&%$Þ”›„–nMµ…˜F'f…Ò¥¿ÿÒg åý– %™ µÿuDûµôäœsvª®’H ÄbH:£»vzcïô¹á•]H¯ìB4oBܺè?uŠŽ={8óíoÓþÚkH²LöÊ• ^0éÍfª>ùIìååèy÷]®~ÿû¨Ñ(9ÍÍ¿×-³%pYª_­• öâb ·lAït2|ím/¼ÀÈ™3Ø‹‹ÝÝ#$ {I ù6`p» wwsåé§  ¡·Ù4Õ IÂ^T„oíZd«•ÑÖV®ÿâô8€»ª çqÞS··’¿y3öŠ \Ë—£3‘ôúßëÔZ“Ó‰Ùë%’RUýý$âqúví"pêÊÄFãìSçÜìõ’ÓØˆ¥´”h0ÈX[}¿ø“gϦ·âÎ{|{I Å;v Y­ŒõôòûQ5øà ‘‹q¬YƒqèB`°Û1x<Ó‘ÿŽº: ŠBRÔöTMöo;#'yl‰³'P•ôVëé–ÍTÛ&À=…É ² ”P&å;óZfÀÊÌ:¡âò±—JÄ¼Ë ¹ÖáŠÊH½—0œ{f´‰f¶Šd›ˆÞÉØåà4¸(Ä$=NJבªÎO·Šd3ÛSªvGÛhú{¡¡Ó+˜â ®!;³u”»Áèv㪯ÇRV†"‰XŒèä$f‡£Í†yÍš9/ìEE”Üû1~pÈŸQ[´`2»U„$f什$i¨åFvÔÉè ì¢MN0qïÄ»=7«7 i%2:Jï±cô:ÅÈþýÜüÖ·Ò§#‹hi³8u Q[‹(M‡%:++ñÔ×£ét =ËÍçžKÿ“-–t6Е]WGѶmÄÂa‚ÃÃôîßO*$ÜÙ‰wýú¥¯%pùý*%™äͯ›¯¼Bû+¯ĽlÙ‚2£Éå"¯±‘ì•+ ŒÐwä#--::pUU-ºÁØät’רˆ·¡àÀן{Žá³g‘L&\••‹{ݺôm‡†¹pÑÓ§½t [QѢʬדåõbòxÐY,Ý  p˜¡£G¹ùÌ3´?õŽÚÚyÛ?z³™¼ÆFò6lÀ·~=)!¼|™Øð0£ï¼CèâErî¹ý¹5º¬,œÕÕxQ„ ÐÛKðúu‚çÎ1zìÙ›7£›gdÝ`³‘³z5Þµk ƒ _»†¢iDzz_¸€ÿØ1²ï¹iŽ–£¤×cñù°•”`ÊËØŸOvCF‡Õºè¨úo³´ÁVb¯q‚á“'é~ùeÌ^/ÎEv²-Õ¸ün¯þ…`o/šª.¸»G³¬ŒŠ¤ôþûkmeüüy.ÿøÇ²³q/Ø'59lØ@ñÝw3ÞÑÁð… \úþ÷ñwtP°q#ºE¼+&§“ü)ܶ‘ë×ñŸ;ÇåÇÇ\P€­ `Áû>uìú¯~w}=ŽŠ Œvû¢Çü}(KN¾¦&RÀäè(á¡!"7n0ôúëØ0Úís&ÏNµPr›š(}àüƒƒŒ÷öîï'|ý:--doÙ‚ÐéæT@¦Ô÷òåÜuª^O ·—‰ÖVÚÿá\¸€oçÎy!Ä`³‘×ÜLõþ!Á@€H8Œ»¡†‡îéÁ]S3o{G6Ðge!é3Ìß"´hýuø¿Œx÷¸ëó`º Ì5•TëuB¯¼A|`,ýA•Q=T%.Ê-ˆ™RC„ º0TÊ(7ôM!©ê-µƒ[&]†^§]ÁVn æ®cÒ½[Ò€ÒúÊ;™VQæ8Š^Oû–ÜÜXÏ„ÕÊ1{)î &ý㨱$) ¢f §>ûYœ(¨ U¤?Ug)-ª:Cu¹/’PÑéUŒ€{ÈÄ]n=ÅîÙ ë¬p³òkŸ£WÃjuu8V¬ÀYU…%7÷Žñ]Eƒ·ŒÌ0áÎV[¦SsÅìÅ‹’ЈUšHYeÂp¤d Ä.°ê3A¿¿î¹×4¢##ô·´ÐqàïýÑWQÛ:§ÛrªšQ° ­õüäâ¼_þj¾üe:N"–H©ÉLèÞ”ú¢© Ž¢ýð‘ŽDÚzB–1z½nÙBÉÎô½ÿ>ýrí‡?¤`ûv .׼ʴ$Ìn7%;vPrß}\{óÍtè‹/âY¾<Ý~ý}ŽuX—n œ>Í“õõŒ_½Š«²£Ë5¿Š!DzwO^Õø‡èl6†ßŸ+?ù înÜÕÕ]®yM¬Sþ“ªO|‚D*E »›þ?wެ´¬¿B’°ø|”Þ{/:?¡áa‚7nÐñ½ïA,†»©i^B`òxÈÛºû²eø{z 1qî‰þ~<7¢³ZçcÍΦüÁqÖÖ¢ËÎÆ^U…«¬ŒD,¶h«ñ·ßêEyáYÔ×Ð&Ç—#r‹Áh†¬ô€™ vôþ·Ž“ ܺ²VïlÝ1®¬Î­¢Ë3 ›‘JÞ–á’†½>…«\!«ÌFÂYŤ»“jF½q•ä=¨ eÚSÓ·­†Kÿ×]H¨H¨$ìFºi"Xž‹ùB?êd”¸Þ@çúÍ85Õ P$q P¸½U”i[MM¡¢Ó)„„kÔÂG6w'|ˆLî/“ÿ9ùÇä6wMf_²É”žðš<•ácüøªiÚœ{Ç‚EiFËh¦YWhÄ+M(V$ÐÐ8ØßkZ Þû«ëØþýhmmUEdZYBâ““t¾ý6m{ö0qþ©Dr–‡iºý¦j¨‰$œ9ŠlÐ!£²â?›e_úÖ²2"Ñ(“££$âñéjF•#‘Dëê@üð{ˆÐb]3ÂjÅ^\LÉΤ4@W—{ŒÐÈŽ’’— YÆ^XȲÏ}ŽD2Éh{;מx‚¶'ž Ç,óó—j \~W5üÁ$&&hóMz$:>Nþ† ‹F’K²L~s3®eËHF"ôíßOßÑ£„ÆÆ(ظqÁQCÉDÙ=÷ପ" Òyàm¿ü% ¿ŸümáèL& 7oƽlÂh$1>Ndx£Ãñ¯b;kllŒîwÞá䷿͵gŸ%ÜÛK"M? ¨ › WM Þ5kìv‚ƒƒ c‹úR-Ëï¼Ü••iP1›:žŽ={ˆ bÎÍ]Ô¡à,/Oû\.ú¦íå—IMNb--%kè¬co܈l±0ÞÖFïþý„º»‰ƒä44üJÇ.ܺ•ìúz²ëë1ØíéŽßsp1ØlÝnÑ(ÃçÎѳoƒÇc¯¨À^R²¨‘Øäõb-)!08ÈÄÀ‡1òÖ[È:Þ-[¼­£¤„¼1z½Œwweü½÷çôYY¸7lXðöf¯—¬âbº[ZˆƒH©f»WÎêê…aY§CŸ•õá<¿#ƒDŸ}–ø±3ˆ¤6ûCªãb  ­µ…¡¤Î·0ÒÚJ"™œEF™ /ÌUÖfi…Rþ?öÞ;<®ó¾÷üœ2½Ïƒ2€ ¢ ,`'EÕÈ’cÙŠKl'›xÓþX'Ù›çf÷Þ}®ïÝ8.‰KÙ’)[–¬HVïEJl")ö vÑA›Š©çìS0 Q˜ÛWôò}žy@ æp€yÏ9ï÷ýý¾E4H(ŽFŒˆ±B4ŠLåÀ‹Ö©ÃÒhAÕj<‹¹V" 6ôj£Ed”HŒÄ¨Ÿøb;¡‡¼HbjpQW9˜Ø¶„ˆÃCz¬jŠ”V$…0g“ó“É'g[G‚ЬQÐh$l!KQ`½Š‹„„Q’B ëàI˜8•Yǀ㠞©„é÷‘äîÿµ¿Ÿÿ4GÌ„üjKžä>•ÛT:kkq¯Xd±¤Éß{ñsç(Y¿~N¢º¨Ñànj¢xåJÌåå\ß·ÿ•+46bšÍÒàθ\~ã­/}‰S?ü!í™| û\h9ãdZ²r%%«V1ÔÖF×ûïÓ¿?‰HÏ|,óŒ{láÒ¥”®[ÇäØW~õ+zwï&¡(”Î%±„´r¨¥…Òµkºt‰®;þøcRáð¼Î·Ùꋹ´£ÛÁ庭AK2!22’6±›Gž«³Ù(^±‚‚¥Kñµ·3~ù2¾C‡ˆ•^ܨ IDATû|”Í“õ”­ èÝn†._f¤£ƒd2ÉøÑ£ŒìجÑ`[ºtÎ÷v77S¸|9Á‰‰4©0eâÈd½ך5s¶ûtv;®ÆFd§Ó™›;Édš—¬ýI‰‹yb;¡Þ´¬89ÅYAõúe¸zÿ…Sœ8›6ËËrÔˆ™~À´VÑ Réÿ[Â(‹îk1‚V›®l„É‚ Ú2†5^Ra4• ‰¶ ÈNLfÖ;’Å‚¨7 Ä’DKdÂ÷!¡ ‹)$a:xQˆ6yI-6^BÛ3I*SØoðp¹Q¢-¨iŽ‹¤I¡5HX¢.–i÷â6_F%ŸvF¹‚¹çæ‘¡žî]»Ú·„$Q<òÈXXHñŠxÖ¯Gk·ÅZQ1g+ÿθ\þCÃ^UÅ•7Þ`øäI:ßx½ÃAÁ’%sÉ:¶Š ê¿ðŽk»vÑ·{7}‡a¯®Æ\\<'(´Z,eeT=ø ›Ž·Þ¢×.F/_Æ^Sƒ¡ `Ö6†¤Óañz©}ôQ$³™¡3g ‘`ðèQ n÷¼Îµi $ÜÖñò}ÌåçŸçø7¾Á‰ÿú_ñ9“N¨-,œýsÓj±UVRû裈F#×÷îeðàA®ïØ©¬ kEŬs–Ý.úÔ§høÚ×°ÕÖFé?x¡÷Þòp!úââY¹/¢FƒÅëeá§>…®¨ˆîãljúýøöî¥÷é§±54`¬¨˜ñweKi)%kÖPº~=¶Å‹±-Z”)ü¤Ía,†òÿü=êŸ| aÛ} ÓÁ ­L%`ì…é=ô1¡LYŸLe$ FHIKÔG½ÝODUèO‰) ¢ÑˆuaZ½…T ‚OMU_òio| éŒÿ±°ÁdB4™´Útõe2‚ÆmB(³“œˆ`¨­dÒ½U[ˆI¯Å¶°mI ²Ãd6÷hÔ+©t{G’4b‰™*Œ¨‚S&ºÐQi4˜H¥ çòø,Â4~K†ã"(h4I  CÂÍ yŦ‹9R±B˜ —*k)»Ö‡&š GìH ƒò$ˆ€ôû èö?Çó4Ñ÷@E¦h2ÝÇešŸKÎIwª 3Yc$e‘r?Ïå*å¹îŽÇz*¶TÀe4ô.ñX ?ýçÏ“H&s* P{zPNœ@CniAÐh0ᬩ¡òÁÑ2xù2á`¤ªf¸.SUµì÷JÀ;_GZ¹©|!ÆâbŠ×­Ã^WG`lŒñâÉdú”"s\4NâèaL_úÛêjªzE’èÚ³‡ž7ßd´­²­[ç4Öe«×Ká²e8ëëÑfBDïŒ;Àå72ÌÅÅ4ýéŸRõ{¿ÇD{;gKi)ªª¦AÀ‹¿¬×ãݸïæÍ _¼ÈÐÑ£œyì1 ÐX,èæðð@´ZJÖ¬aÁý÷èë£ç½÷8ú½ïQ¶f :‡cVç[Au:¼6°äË_½Ok+Z› Íö;ýiS-³ÇÃÕ;ð÷ö2vü8~òÜÍÍ=žÙ•ysV¶y3ƒ.0vî—Ÿ|KYº‚tvû¬ÇJ:z»wK ¥[¶  LôôÐùÔSt|ûÛ”>ø †²{rÇkµ”¬ZEåý÷%`,)aôÜ9œË—#êt3ÿî‚€(ËH:]š„)ŠŸ<ÐÝþ8ÿôm?â/G|÷u„†&E°Úˆƒûúèܹ“þ3g˜ ‡Id×\5“ÿ“`ÊZ_YU©t÷‘G øÇqÿÞ#·®ÅXVH$ƃ¤"qÔ¤:Me”.bd«yýƒˆ5+Ìæ4x1Ó„¶y!ñh5šÂØTGÜÝ@RïÆ(  "²Í†ÖãASP@²@eÄp !•q¾Í(¤LõEÊT]$Rˆ’J|±‘ðZ'Æ'c© @!¯U4ÅqÉ.…Á.¢UKYïÀk8‰–húÿVTI¤»´œªÓÓ5Á©IHu‚p¤rÔÝoñ~[-}¿W‘#æ ¢:ˆ+2½…”(" jHÜ­I˜Š§^“=^þªQ©rç¬ÑãÁ±l§“ñÞ^"¡‰ ˆH«R‡£|÷»ˆHË—#È2“ Ϻu¯[‡¯»¿ÏG,˵ò«/jˆ(ÏÿÝÿñŸ4${]Ek×"šÍø::˜ŒFI¤R$2àEаÜ?Ò ×» ŠhÍfLEE¸¸úöÛ»º¸òÊ+è].œ55³Wx3‚ I£¹Zî—ÿ¸¶s'Ý»w3xâ‰HÛ<éÅF·›²õëÑX,œyâ Î?ó uuØçs®¬^/ îº ÙbÁßÕÅùŸýŒñ«W1a›%À.ÿxSq1ž ­VbÃô=ñ±PM†ý>×и—.ÅZQ±°ð¶-J2IÔç#pí‰Hd~Ã=§“ÊûîCÕh»~ØÄ=¯½F*™D–eÌóDXÊʨ¼ï>Dƒñž®<û,þ«W1Øíت«çý}µ èä$ÁÁAú^~Ū:+€ÉžkåÛ¶a®¬DSXHñêÕ(±‚N‡~?‰Oôüõt3úƒï3z5c££ˆÏ?…pýBË‚áÝ»wsáÕWñM$r;áìb&dZAB2/‰Ysß9»bØ~ïQ,ÛÒ•+1ÓÂIL‰Ò5ÏŒ,™6ŠÓ"©ÝˆÛþ Ñæ@0™ôz0m´w·9~5¥b\ÑHʽˆ¤¾D£M!"¡$“D„}Âi&ã=9Ùµ /¨HB*Í}¦·Ž$¤±šîèôVÑ #AI«~4ºF§Œ$”3àÛ@³ù5lÒ`ºÂƒ2tÓPÓh$ω-ûa^å)Ô@/ïŸÜFÿ¶Š)rnžÉÜ4eÑ´R:Ñu}Œ‰eT­{ž¼¶Rö{YMñõòpÉ^'V++V`ôz‰%錬ÉIR™Ö_–7«ìØdµ"ŒŒ f»-' S³Pel`€àèèÔy¢LU^ÔLÅN®ZŒ¼´iÚ=½z5¦Š "¡áá’ BS_fòº©¨W¦²ZÔÒBQs3:««×{Û¶hïŒO8p¹x‘ó¿ü%Ç¿ÿ}Ï…Žiæé9j­V78¸äYÊ ‹`ç‡wÑ¿±|Šãrƒ;.âôÌ¢l›HTdRŒ/w jÄiÆté× ¹ï%R<úÊw°ž<Œî®Ÿ(ËX.ÄÙÔ„hµž˜À?4”SåΕ]»P÷ïG*+Cjhà‘¿×Q°b5÷?ZÃd4ÊXw7ñ àUÔ¼¿5 ÊîݨNÚ<Åž¨Ñ`«®ÆÙ؈ÆåB‘$"~?†ÒRŒN'Z¯ý,Q–Y°u+îæf‹S¸t)Z«õw:‡ípù_8\‹Sºz5Æâb®¼þ:ý}Dׇ²èÁçEË‚(b«¬¤dÍôçñ ®ïØwëV ó(QÄY]Méš5KJ¸úúëô8@ÏÞ½TÜ}÷Ü­#¦r‡JV­¢håJÌ%%è].ŒEEs.À¿ CÒ»Úã=†ïäI|‡3¼?¥›7Ï)ç•´Zœ‹SÚÚŠÉëåÊûï3éóá;|˜;)»ûîtd–!j48-JÏ·ÛÍÕwßeèÀ†öï§xõj sx:dçL_P€d±0xáá±14Z-êä$ަ¦y=p4fsúf¨Õ~bAKìʼnýíß"¯\‰0Ã5ìì¤ë•Wé=|˜É@pÚú™}Ð~ñÄaL‰Åÿå”¶¶RqÏ=8›šëëc¼¯o:xÉ8âŠÉt&^Â!D«é¾G ƒø®_§ûÐ!ƒƒH#›%CM)HIÐ$´ÅEhª"¬øHrš kµ"::=áökŒí=Œd¶al¬C[æ!i*C#*\çMN|ëŸèþðCüÃ]˜Wh1&•4(Ⱥáæb2¸B^õ%[q‰'‘v†3‰Õ™¢E¼äZF ¢  Õ%°º%Tyú°Ž ÚÇqH}韣"å¥LëFbœ½¸ä˜ûïb`cyDÝè×2£kn¦U$ *Ëí¨1W­á† FШIîùÖ_`Øõ. ¿Aq'Ê2†‚œ˜-b2f¼¯/§þÉ'Á Êáðs'Rm-ß?XÊ®cÎŒUá]·–æÖº'æÎ“¬\ZL)èNô?|ó{!›ÍŒ´·3ÚÙ‰­®{c#F·›Îƒ±.\8£¿“ hŒFôN'²Ñx´Ü.ÿÎRt"ÁË÷ÝÇùgŸQ¤°¡aÎ>¿Áé¤dåJæÛÕ”JU ïÞÍà_þ%±Ó§P_y饑¾ðÅÌUŸ>Ï>ó ]û÷3”‘-§2aƒùY2Yuˆtþ,š¡~t~Ca!Žúz¼wßM$ÁwíÑL)?§(Q2’æäÔ“bçU«ÝÚ-Øjj8öÌ3ˆV+Å­­8êë4:â#Há$Uƒ¶Ìƒ¶±A˜€ÒÆÌj&‚NǤÏǵ×Þbôj;¦/¦šôU(¦4‚Bèò%’¾1, P°¬ÕÒƒ1™J·ŠRr­¢¦ÉºŠš«Àˆj°Héê‹&‘€w&óÚBJ¼¨ÓZ?¢  Ó'° ¤4‹ÑG ¬Nü;}°’k ¨hFØŽ’7¶Š¦»NmepcY¿eªÚ2›k.b:dQüËméVQ>AWš"÷" hÕ[Þþ)úÑ!b‡3ùÓŸ¢õzÑÔÖNÝ»Ù`ÀRYIÉ–- Õæ¼W’y­#% ÕÑöø×‹5 û:ú\²±é‘lüÚC µbbp¤¢äZ:·£Ã*Ih—,¹ €è ðlÜH<•«ç²e+*°x½Äb±y7¦wÆàòï—_{þ£Gñ_¾Ìð‰ŠŠ0—”ÌÙBeGUK¾ô%’‰CÇÓ³o¶ÊJôv;ÚY\HsÇK¯—ú/d™¾½{¹ò ¸—/GÔhæ¬Þˆ²Œ}áBê}”d*ÅDg'¾'ð_¿NÉÊ•s2Ô³š(I¿uö_[÷ 'ØÓC端rèïþŽþâ/={÷ŠhÌæ€ Ièl6 êë©ûÂÐ8 _¸@× /0°{7ÎlÕ'Q–±UTPóÈ#(’ÄhWÁþ~º~ñ F¡hýz4s¤g_ôÐC(Z-×.Ñ÷Î;t¿ý6î5kÒs>›rH’rε…ÍÍ**pÔ×c‡kóI“—.Ññ7ƒïüùô¡ôõ#|ë›Hííˆ7ÉDéªUè‹‹émk#ª(LF"i%ˆBÄäÖÑ”‚zæ$Ò÷¾‰ Ó!®X…Îí¦lëV¬µµLø|Lø|¹v@–¼›U `2ŽxxÒÊVäÚF–ýùŸSþàƒèËË1WU é?q%¥ k Ê+ЯhDp»IX*ˆML0~ñ"]o¿Íù_ü‚þ'P ìK—b^°ýâjƒY“ÃŽ«n e›6áZZÍØÕw0$ò€K¬ˆ)5Çwòþ-ªiÕ‘V‰£‹C ›Cm¡ ×Çq–@B_‡.jd…;–Ä ‚¢"‹)4BÀHªB̨'†s[hŠ,”œþØÕ±•Á e9Ž‹˜y-¢¬š(›m )&Z¨Zñfrn^uF«ÄYõú“èƒã$ ~?“/½„¾¶6sò*—‚$¡±X(\µ k}=“Ñ(þ‘‘ôyÃÔŸyážrÿ1ADˆ&àÅeþåÍ"þ¯Ÿþ…£™J]<ÃR]¹¶Sm-RE M¢$!”mÞLɆ 6ÆÊJôeew@Ëàò›õõ4~õ«8kk \»Æ¹íÛ  Q²zõ¬‹Iþ »à®»p,^ÌDGG¿óü]]$¢Ql••éŠÆ\íA tÍ\ øÚÚ8úÿH¨»›Ò5kÐÌ~$­–wÝEÙ† ˜½^\‹“ŒFÑÚlórnnç!Jz‡EUjkcâÚ5çÎ1°?j,†kéÒYs{ -Mô¬]KASÁ‘†Ž§ã¥—H†B¸æ£‘[·â¨­e2ÂwéÁÎNFŽ'‹a_¼xNÇaÙ` bË\K–ñû¤`¡¦GM _þ2¦Š ¢±£Ýݤ’É\`ž¢Nï`¨Î1ÆG‘šp-YBѪU$‰"~ðd¥¬bf[.šÍH|¡¼2Wq3WVâáÚG1ÔÖ–&aZ,X,ÄP_‹PTÄØÅ^.¾û.žžÞƒkoÇ^]MAK æš,UÕè½åZ’ ¢±X1••ap»A2râWèRÊT.R¶â’ QÌ{.? b0GÑySÄö(78å’¶Â'#‹T †8ND è"fš}Û1Ås±" ²Jó\š« g&g丂·0¸± 1ã9ƒ(Lo Mónaš9$¤Ò8M OÌ]*NÓ+O¢ LL+ø„_y…ø«¯¢[±Í BQ«Åºp!®æfd‡ÿСñq’Š’ûSž¯ý:¡ p™æÜ{PGÓ}k(jY‰™&úû±,^Œ}éRtf3ÉTŠ`0ˆÞá˜Qá#j4èŽô5zÜÿ €Kû[oqîé§ àžÃÄ+8ª«ñnÙ‚ÖlæêK/1~éááaŠæ°PÏgu5å[¶  ×?ø€¶ŸÿœØÄú‚¬·è|[±m³™Ž7Þ`´­‘ ðnÚ4ﱦâbÜË–añz±/\x[3Ó•xœÉÑQ">úYäÃÙa.-¥ü®»Ò–Ü==Œ_¸ÀÐÎ$ƒAL‹Ï™Ê `­¨À»y3’ÅÂè… \{õUbCCF㼊/gu5e6 È2ãÝÝŒµµÑ÷Þ{$FG±Ô×ÏûÞY·a}a!ÆâbDAÀàr¥+/óÖOòHôõ1ü7CôÕWáòe4Ë–!ä%‘ pþå—é9~œX&&¿¡Ê™Ó¯½†¤(ˆwÝ…(˸)Û¸ma!}gÏ ‡§ÖQuîËþ=H»ßG(*Ah\†¡°âU«0/\ÈøÐþ¡!©T–s›3“mv´„¥ËA“À‚(‚(’”$É$}}F#Ž%«¡õ”¢‰ª(î"Býýˆ %ëÖáÙ°âÖV\ÍÍ++‘LVDQÌäõLy%C#Œ~mR"çf¸-i¢®:EØU¦»‚fci,AtS‘7sÓä\“9ŠÃ#1inÄ´ÒлClpÚ'f^+&UäK)´'3s\ø ¼…¡ž´Ù0Åq™fý/¦[9ÓÜt3¤Ûð3ŠNB•„©êL†œ›=VŸŠñå=±ö+„óg PÂa‡ÁÀ’Ôg3‘ÍçrÔ×c¯¯'<>Nhl,GØ~mÉ× Ï\‚“ðú^‰ ×u´¬0á*]iiš·R]`0ž˜ÀTZzGš|güzKbr’“?ù W^~™P?Þ ni—ª5›)lj¢¤µ•Þh{ê)Rá0e·à«³Z)]½šâ–Æ;:hã †NQœ×!@c2á^¶Œ’Õ«8z”ž={ÐY,65Í{¬ ŠÈŽÛrÁ‹D½x‘î]»¸òì³\Þ¾®wÞ!–HÌ |Óæ816FôÀbÇcÚ²éÂ}–ûâȨ‰¡ÑQÞ®û+"ú€K^Åg0d¢‹zŽšøÚß.ü cÆfÀ\VvÛØC$''¹¾w/=}„¤Óa,,$16Fç·¿ëÖµ;ã·\ÌÅÅTÝwñPˆ“?þ1×vìÀèvãÊèøçkÁX¼^¼›7£³Û9öOÿÄÅçžÃXT„«®nÎceÛ‚TÝ?¢^Ïå—^bððaâ¡…K—ÎÛz’´Z¬ååx7o¦|ëVÂýýéçõúßiÙ²(Iè¬VF.^ääO0ÖÖFèâEF÷í# áZ¶lÖ¿_Òh°WVRyï½HV+½ÇŽìè`ä㉌Œàljš“s$i4Ø**¨Ø¶ mAW_ßáà ;†eÑ"Ìsø¦H Žª**ï»Éj¥ïôi‚íí„ÚÛ‰ùýX-B7G$}–{£·Ûјͷ-hAUéyî9®þò—9Ùr2Ó6J>ÿ¯u”#àBˆûö#V-B¨¯O'mS¼v-æÊJ/_&0:JJUA«ÅR±s]-µÄÕÓcDYÆVUEɺu(:ÚÒRœK›Ðz½6'’ÑŒÎfÃPPžS£1m6GË@URìøá—(šð¡Iª—éùC9ŽK6')ïgfsm`’à»ò ‹ÓÍè$AÅîaóh Ù—¡;Y|a;ºÉÁœÌ[È8È HŠ …j¿ˆØ©ÎHÐýв™á¥ˆBº%5£Åÿ Á‹ir®,¤H”jÓ¯QÓàF•ÔŒ!]ú`LNÒõ_Ù²•òÌ5ÚwîÜôŠ àK_B;C…[E†h8L8`´£ƒ5_cr&àÂÔ¿û}Ð5áàTOò%;¢N‡ K·ÕQÈ´Ö¯ïÝËGÿé?qåñǹöÄŒî܉ (¸6l¸ÓÒúM—,)3Ôß’JÍK€ÕZ,TÞs‹|«o¾ÉéÇGo·§o*óøh@šÏP²z5Õ<ÂðéÓœüÞ÷°xÉGÿå¿Ð{ð ¶ŠŠyÝ_!ÍYxß}Hz='üc.>ÿ<Κ¬^ï-içõN'å›7£s:9·};gž|wc#Öòòy'ÚävSýÐCˆ:Ý{÷ÒöôÓh-ŒEE·žn÷‘ŒD8vŒŽ·Þ"ÔÛKxhû<Ž¿¥«WSõÐCè‹‹ qñ'?¡óé§)jmÅ<[±ÁåJ«D‘‰Þ^"\þy´N'"`òzç<ÞXPÀ‚{î?WŸ}–±+W0açw×Ùí,ùÃ?ÄQSƒµª Ok+º,Qï6J4ÊÈ D"èfðžÑÙl¸jjôõ ‡ úýLæ¿eI·±cLjÿøÇÈN'Ú5k¦-ì:»²-[Ð#86F<‘˜ÖÈ~^|©µ±ra®ºÚøÕ¯˜˜ 02Bpl,÷z2Õ]AŸ©µ¡°pÚï…ˆøý œ>MJ°ÖÕáXºÃÂ…$‡GE£È&ÓŒ WÒéþã7{U¡ëWßÃ"%Éã¸äUOõ¦vQVºl2…qUN`°ÄðïÓMñZÈø¿d[E¢‚»À¹Ô„ß½m´ŠƒO¢ N±šSy—dZ*8 ákþO"C ÎLîžšMŒ¬/¾¡U”Æ(仿ÞàÑ" i –LZtÖÝ7ó»“©¾ )¡$8ÄçʦªÝ‡º?øbñ8þáá4÷EQ,mmXV­B;ƒšÇXP@õÃc)/ç™±j‚h§W[n ßøýÚ¥pÏêßÞµýhÊ<Œè­@ˆG¡¨$Wá  Ññî»´¿õ‘k׈uu¹x‘T0ˆ~^eVÙš˜ àóöûQ€á7ÞÀTQ`¸ÕŠŸHࢵX(ß²ç¢E 8ÁÙŸý Q’0ÎKäÔÙl”oÚ„µ¼œ`o/'~ô#Ôd͆©¸xþê‹ÉDik+D8ûøãăA´Vë¼Çk-ÊÖ®ÅUWGéêÕ¤&'4l·|n÷¡* “££ 9Âÿößè|÷]´&†[˜3Ù`À½lÍÍ$ß¹s îÜI"D61ÎÑÂÑ”®Yƒ}ñb¢‘cÝÝô½ó£Œ®¨£Ç3gÕKc4¦oH¦Rt½ù&¾Ã‡‘ŒFYÆ8‡s­(I˜ŠŠ0—–¢±Xn[Ð’ŒDð_½JÏk¯qú¯þ ÿ‘#$0VV"Ï`xX¼bU<€±¬Œ¤(æLÀn´ÿHì܉,Š04„œç‰!Ê2®† —/'%ËŒõô0 Ýì–J¡|ðRÕ"¤ÚÚ\u£|Ó&µµDÂaÆz{‰Ç㨲Œ®¸K]Ú»ïF¸aÃuŽF"h ±ÔÔ`©«C¿ 2­ŒÒh$é7ׯSzù]Ê'£9Ï”|òm®E”oJ§L‹9„Õ Ù®2¾Ï0-§( ­äZEÅE˜üH?#‡3väîÕ«ÑÎQõ5ìUU¯ZEAs3‘ÑQ¢ˆ¥¼üw>*!ÐÓÃÅçžãüOŠ¿¿ŸhOc{öik#tè>8#Ø,nn¦dÍtÅÅt=šs"ÍÄ÷îEùøcäÒR4 öìùb*-¥pùrÌ‹áb¬»{Zæ(Á ’FÆðûŸ™v¬£ºš’5k0x)[6pÔÔ0pþ<ï˜ìì$|ú4ñžÜ=4ógn·ãnj¢êSŸ¢ûøqÆûûo’<§‚A’zî9tëÖMó}јL8kj(Ý´)í|ÛÞž³pÏåÏŒŽ¢÷xÐ64ÌøÞ‰h”H Àd8ŒcéR¬õõèN‚ƒƒÄ3¤èoæ§½Ãl0¤9¿ àûÉ?à‰Ær’l…eFItÞs’J[ˆÄ5‰‰½Ú<°’i7e£DoÙ†R;ãE­ˆIî×¶#NS eIºR$ý’RºFöǦŽh,¤´ÒÍ eޝkkážæÿØtŸø'§OA{ÂùÃ&3BÃ*¢ã㌜?O÷på±ÇèýéO‰Ž¦ÕqÙäêÔ çíAüê×ҿшkÉŠ7l 3ÞÝM°«‹Ð¹søwìÀûç>ãZ#ˆ"†‚Š[Z(Y»–ëÇôùˆŠ­ª ÕJ2Áz iÑ·óDÁ@ÿñãœ}ê)áÒLÿÞ½”mÛ†¤Õξ gl¹m RÿÅ/¢( g~òÎlß΢‡º¥93{<,xàl55ô=ÊØ™3 ¼û.%[·"ˆâ¬æo¢$¥û»Ÿþ4¢ÙÌðåË{zè{õU|§NQ¶mÛœŽÃ‚ ¤Íßtvûm”‡ öôP¢Q$ƒaf#­ y¶úá‡iüÚ× ˜&46F*™$|ú4Ýßú¢ªb[µê&7QI£ÁT\LÍç>‡h·Ó{î±XŒDÆJ= $ÂaƒƒÄö3ŒŸûR^ÕT$ô.WÚù¶®Ž±¾>ü##Ä“IR€¨×¿|mu5ºÊâ¢FCÙÆ8ëë™ðù°75aY²sM :‡”ª"Îu®þGx —à“ßÇO¡«ˆÉ,Ÿ%ˆ«Lñ\DEÉ9ëÊB³)ŒÅ6I´GG`·0õ:U™æ¤+‰)*Ë}èKŒ­ET¼Llûßpýâ»O¥AK¶U•qÖh ˆžR.ï`¢EÍ3ÑUáÔC ›§Ð Ó\so ^3a‘ÆD11E$e*¢ ›™dŠãžÆùí)mmEšÁØM”eôv;ŽêjÌ^/«1s?™i3úúÙ0§õf439w¦‡k+ýÜS=’Äί??ùkØüÙ4+\³‚´÷{ÿñ'ž@Œ«¨ ¨±êá]ðÌ?¢]ºš«'ÚÒé½{‰‡Ã¹¸‚i²¹Aýj?üèÛˆ—Ú¶Üh2£w¹ðlÝŠ¥¶–ÀÈáa"ƒƒô~ç;ø¤ðf¨Ë:ö ¨ÿò—Óù+WˆÅbÄFGé~ì1F_{âÏ|éNrõ¯¸dCQ’ð¬]‹{Ù2zöîåôOJ<¢ ¾~Nù± 9÷Ù††NŸæÈ·¿MÄç£pÉ’yƒ IÂVYIqK æ’’Û37¯D™ŠF3ŠqNánjbÑã±ÛI&øÏŸ§ýÅApTWÏÙFQ–ñ¬[GqK œæ …B8-š;í:3g”¬[Çd$ÂÀ‘#œýæ7‰û|¸[[‘g»À2ÀÉ»q#%­­Ä¢Q´ŽE‹ðwu¡±Ù0¸\óWÂncPxhˆž={8úÍorèë_g`÷n4 F·{vÕT¦:Q¶aî–‚~?ÁAb‘©d’‰={ÒŠhcUÕŒ;bïúõ¯YC`lŒ‘în’Ûý¬l:•J}ጛ7#ß¿$étiîËŠÄâqÂ~?‰DCYÅ«Wc¬¯G.+»éÚDÛ‚T?ü0ÖE‹0x>¸‰?tãòåhf8wtV+Ë– ‡ñµ·cª¬ÄÖЀ, ±drF‹„låHk±üÖ¯Qµí(Êw¾Ž™@p{À|3!½çñAÉ}bJEJ©ÈÙª‹z3Ï%«,’„sEEÛê!9(=šÖ*2Õ ƒ.FeŲ§„±âu(Òd$¬?ú.DbS—$µZÎ~ºÅêÄe0#Ô=ĸ/ÆøõžpN5Óÿ©j‹tèȽ¿¨‚,LK‹F)#‡Ö* Œ#“9)´ Üìúk2‡qŠ~>Sþ– rRzá?°x±+ÁyA‡:p™å{APY'âny îL»*'†À¶„Èþñ÷ßBÌ(±„þNìÿ£aèýø—Ÿø ƒÏý )“J.¦2 Ô~‘ª‚ºëEô]gðþñ_âýÊŸb««#82B`ttšËt–$ œ; ¯<—›îJ·K (hnƺx1½½„ÆÆðŸ9ÃÐsÏÁä$λîšñZDGUžµkÍf†®^e2$ÒÕÅÀsÏ‘Áµq㌕›;ã¸@š?RÜÒ‚{éRzöíã¿ýÑ@ϺuóÑHY¦r%Ø×‡ÅãÁàpÜÖ ä–Z©1¿Ÿž}û8ùƒÐõÞ{¨““xnÁYQÖëq54PÐÜŒ*I\yî9†>þ˜”ßOñºuó¯1)^¹wSý‡qù¥—ðwu±`Û¶ùßÛ`ÀY[‹l·“ºß}—Á={0¸\ÜJTCM æ²2tN'Z‹å¶-“ýýô¿óíO ¿PïtRÚÚŠ­¦ÿУ]]¤€ñ3g¨ú£?B7§ñÎøŸpΕ´ZìUUxÖ­CÒj9üÿÀð©S˜=žy}_$ÇÂ…-_NéªU\®´•þ︳ (Ë˜ŠŠp-Y‚l6Ó½o0|ì:·{^kV=T¼j–ÊJz>üÞ÷Þ#Ôݵ¶vÞìžü98öÝï2rö,f¯Ëq×i¼»›È÷CާMÝÔ £U¼~ë‘W¸þÁû´ýì½w”çyæû«ª®Îq¦ãdLÄÄÁ ‘$eÉIY¶%kµ–½²ÎÙÝs-ûj}¼kïݽ޵e¯eIÖJ²$Š’L‘”I1 "‰ b˜ˆÉÓ3Ý=¦SUÝ?ª{ WG¶ ^~çôiœ Õ]_U}O½ïN]%É£@K‘´\\ŠLR^EVæ©nTÝ9×(æ0³fBm5¹;ʹÂÌ ‚¢,ž’LA+’ÃE¶r%i[’f$¨¥ív« P'ã(^™±WˆŠ„BJÒ8&\ ËeG˯Q½ã>"½#ŒÖ€fQg¿Ûü¸‚ù¤âùÜQÒ}\d5‡ÿâø\µEUçÔPÅJ‘=ÃÇ73N“çÞ_ÉÜ<7œ¥7¥€(è<—ÛµŠæýYDeKô÷FÞb>AK’Av‚s=„;!¯@>£Ï'yÝóÆe„2Tí¼ ÁJd*J¶ð©hÓ¿ü\ÛHU瘾‡ñÊqÜ¿ÿغ Ñåbäòe2é49M[p¾ˆ h©¹o 6· 55Ï^ãîæfü›6!X,Œ^¼H&gjÿ~Œv;®µkoÝU(„¿ÚËË18L]¿N´¯DWU?ü¡WVþ«Ðy'¶`úO|Wu5áóç _¾LÙúõú*J.•âÚÞ½ô¾ú*~ðNýíß2=8HÕŽ‹±mÑò›¿ F#“]]\ùéO¹¶{7Áµk±/Á]D“ËEå}÷a˜àÒw¿ËdWžeË5Ž+îßPóàƒÌ„Üþ»¿cìÜ9ìee¸Qm‰’„Ál&´nîúz,~?²ÕzgÊÎóy2SS$ˆ]ºDv|Ë-ÀátRýÀJJ˜ 95ÅõüGú¿û]B;wb^„¿"ˆ"&·›ê;1ù|D¸ö“ŸÂZZŠ}‘J¥ IXý~ê?ùI°X˜`&™$›J1ø£áݶ -¾¥“©ÙíÆ¿bÙ™ò’„¥ª ÷Ê•8šš(ß¼™T4Цi‹æ=ýJ†’‡ !Ÿ§÷—›³¹=“žšâø]ë¦Óh…Îü(k!›¥Òž'§ihLc%;°¬Ü©h€¦aÌ«H*UÅI³ kÈ+uhñREA˜žFÈå JÀÇÚP¦cÈ~/jU 3ÎF$Ì .'¢ÝŽh³!Z­tî­G4é E/**9"ħøë˜8öcΘæqiæW†f[ZóªWS$YE2(ÈJžÐ™‘ÙPÈEÅ,&wI”2¬÷ÿJ¦û…ÁýÉÜlªµ&‰zÛHº}ÅEÒT'¯²yì(Vef®lRTb‰Pº LM0v¤9Q¨ HyTpNöÐjGh\Á¨f#‰ÌÔ5½Å„2¸h fÒhƒÝˆ©(ÖOý7â**‡nྨèÛª¹<46b\×`œK8·øý”mߎ­ºšéÉIâ ïÞ©´ÏíÀ º¹õjÒ‰κ:ì••z¯¦æ£˜€à2[A1™ôÞ¶6|­­ºOÇü€KF#¡uët•͆ÁdbäÀ2Ñ(²Õº¤tÛ`6S¾i%--ÌÄ㌟:EÏ®]XƒÁ%óšŠÛû׮ſnÙl–¡×Êek IDAT^£o×.Sâõ"/!¯“dk €`42òœ8A`n¢`ü3ÛÕl–Ñ£G9ýµ¯qúÏÿœá_ÔA˜¦- `DƒÿêÕøÖ®%›Ï3Ù×Gvzšð›ob0‘dó"­3ÉhÄ·z5¾övòŠÂÀž=ô>õŽeË0ƒ‹«ô$‰@G‡>ߪJld„L<ÎÈÓO“ºv ûŠXnX½šú_û5Œ%%¸[[±VWc®¨À^^þÏZRÓðÅfè?Z\~°ÞÆÙ9EýÑTæµ1ÓSSô½ù&½¯½Æµ§ŸfæÔYÔÂSµZX”ªI Ê­!Èù«HjIƦÉfsú¢'ª.ó€ €¤¨:ÿ¥ * ¬fh«‡ª:Ð*d;¢ ¤gÓi„¼‚÷aæÔŒU•P×JÒ]„•@‰©¤ÉåB°Z¬VÆÖ !Èy$QEÔYð" 1I„ã\bz&†šÊ Û<ó«-7’uÅÀ±3d)¯P~|xÎ1W§(*lç°'(õNáÕ$êLüJ¦{÷õý‰œN.¼4QЪoÁq‘P˜Žºhî¤!}õæÄìÂ{z ßeç†þwEbn™:ŠgËv’cÄDû¬I£Zøw³í#m^ ÉdEZÑŽ,ÇÝØˆ§­ ÁfÓeÏñ8yE™û:$ÄùéÏÜÄ$ OK ž–r@tt”þçžCv»‰ŽRr›örQuT}Ï=XC!\uuz5ûCÎÿüW.Å!Ûlíö;´¨ùìµËg $&§ôè €K1RHP5 ŠòÂÊ&„UADs ‚Á‡`6ëÇQQRIÌšIº€¹©±¡…×2$l”D“ ÑíF*)Áàq3d;ŠF ÝÿÅ *:ï¤`D4fš(6ãµø‚jQÓWêÑóø.¢¦a3Ï`‘ÓHy…²£Ã·Bk³æyvGo Œ[2Qkعè4~}TeUÀ°D1}Ï@Œë‰L“ª=¨zBu±úr‹Š‹/æþW©uÏÍá Q 3Qè9}p™W} ç€;|™ŠMíÿ"c×®‘ŒFJž‹†€…픡 õË‘×lDlÁ Þ5k°VU1“N3ÙßO®àqT<ßf¦c”|â×oº–ŠÕ³ßÏø•+$&'IôôFÕ4£Ëmm%YÆæ÷#Ûl–)àòaÙD‚Οü„³ßúý¯¼ÂôÐUïCýc)-%ÐÞŽwÅ ¦._æÒ?þ#×^xe?¼è“4œŠ×®Å·f Ñë×éýuÆŽcâÒ%ªï½wÉ^§l·SÚÒ‚³®Ž\&CÿÞ½Œ8@² øZtßn7žúz\55¸–-ÃìrÝÑ^*¹dA—\˜N§Q±y3ã×®1Ù×Gjx˜ÈñãD¡æóŸ_ôÆat:ñ­ZEpÓ&âá0ã—/“ zô(c/¿LÕoÿöûš3_Gɉ ú^z‰ñ·ßFt8(iiY|ßþ5kôjƒÑH`Ó&JššFòùü¿Låÿ`LýñocyïÒÊî‚«G`à8¬ùJ6 šÆ•ßÿ}¢?~R£Ãˆ'Žc8z᳟Ã`·ã®©!°z5ÑÑQ&®]›5Û›o‘R´Ó œTrYÓÃÌ*~ï?—Œ^º´¸¨ó±Na1̉0c0¸ÝZ ª Ñ»Ñ^Žh6ë­‹¹*ˆèw“8rËŠfäúFrîeHª£q]*.ÚíLŒ0!îGÓòúwEO––$e´ß5¯‘\Њj•1&çx.…ÖÖ.¾E€à´%±šÒÈÙÁCc ª- €‹¦áp$ð'°©Ôôõèý˜ÛŒ?ÌðóI 3"÷¹nx¥?Â`<­ï§^ÄbõE(T_$aÖ š‚/2Á¶ÞשŠucÈ3›-5‚% rªÀø° ·m˜.EðB¡}dÈg(ÝqeÿæËĦ¦¿z•|·R$ÝÏU…\¦Ž»‚eº÷ŠÕг¾ߺuhF#ážf‰Ùs.ÓÓCÕW¿zËkµH ð­Yƒèp`¯ª"ØÞŽÑá@v¹0{<jkˆ€Ë¯hhš~7ZŒ{S$5–o܈&Šô¼ò Ãû÷ÓóÚk,üñ%Ä¢¤æ¡‡M&º_~™+?þ1u>Šh0,ê\+HîÚZ–=ø ²ËEß[o1~ìý/¿LÓoý–¾ïENôâ“|.ŸgðäIòÙ,fY&98ˆÝ:Ýøn‘ßn0›õ é-J&Ãè‰\ø‡à?üCºþ÷ÿ¦þ³ŸÕoð·~‚$á(/§æ0¸Ýô?N^QHrý‡?$qú4ÁGA¸Íö¢Á€-¤bǬ55L\½ÊÔåË$¯^%zø0e¿þëú}y‘ýÛÊÊ(ß¾Gm-ƒGŽÐÿüóô>ó ¿ó;·=ߊöùåwÝEå}÷a …(]½ky¹î§ò«xf¾òa˜Jè­œ|L\‡÷ˆ_|—î¾$Ww¿ÌÐÓÏO$É óÔ?CCžüâɈŸø$öÊJjwîdÙÇ?ÎàÙ³Äc1ršFNUrV a…³ŠÄT{ÏI–ýç¿Âܶ–î·‘Ï«(ª¶ûRXÓ2¤ÌVW)ÆÆz¨©B°­ÄPRƒTZªóVìvìÛJ¦”ÄÁÓXV·bj¨C)­FÄ,N2ÓaôäIúÞ|“ž}ûê†ç|U / ƒ”×=XÐÛG¢ ¡¹d”€…™–R¤© †HfNù4OŽ-Pø4 ‡%‰Ý’Ä”ÏâÛžGÎ]ÈoU‡#7Æ¡LRqä9Dð¬Ò%JÂÂóèÙÉ8ï&óœL´*ÒaÐTMUAQP“IÞ˜b(™,zl®ú¢‰54ƒ8+™6¨yü‘q6v¿N0Ö£ÏW¤, ɺ€¨#fo!ŽËäf‰Öóß „x ±u žOA¿'»\ô¼óŽNÜ-˜Î©šþÿj (áI¬÷?„±¡qö>( X¼^›7c¯®&ëþJ¢ˆ£®žlo/î{î¹å½Y2±ƒ„6l |ëV\MMxW®Äê÷#ÝÆäï£ñp)"’ãã„ÏŸ'ÒÕE&ÃèpÜ^ÍQp€­Ø²…ÐÆDúú{ç:Ÿx$ OCÃ’ŽÁ‹…ÐúõTÝ{/£gÎpôOþ„Ñwߥòî»m {qlÛFÙæÍD=y’÷¾ým²©¾¶¶E¹+¢,ãkk£ö‘G0—•áinÆ¿f ÙdÁ`X4±ùÃÐþqTVb ™¸|™ð{ïqöÏþŒè… „v츭sm±‚Q¹m•wßMt|œ©f"¦ÏŸ'Ýׇµ¼ÙíF¼Õ9#Èv;Áõë)Û¶èø8±ñq¢\ýË¿$71Aé]wÝÖTJäB·£®ŽÉ®."W¯2ôê«`6㪭½­ZL21:Ø‚A]$I8Ð2så‘ý%™BÌêDZ!W\ˆTLãWñ÷ï%q}¼¯‘‰žÞYBeP=wI¼x©§¡¢ƒß£¶–•¿÷{Ô?þ83Ù,‘ÑQR‰Ä쵂þ-’–‹Ê#mfyïO¨xb7õ=ÎÔðSƒƒdÒM·Ú/ZîÏMÄæ bY¾¡ªAðƒ\Šèp"ùýˆ.JN!zð$ñk}Ø–/Ǻ¼Õ_ƒ(ÚQ§G9úÕÿ‡«»w3pð ã×OØdEç‘k•¹vAP0ˆy$A¯Àèí$A0^‰cO/,ÊBÞ‹„ŠÝšÂcŸÆ i8Î%1Æ3³ÀEÒÔFEÔTœŽ8¾@·ÅÿÎ0Œ¿Ý ÎFp­ÐË!##I³+“a"—EEãhBã x2 \GÞdüØ1R»vÑûÈ#¼¬eÒ_VààêÜ"+’„‹Õ!MÐ ò"c¬¹ü¥“½³E/Eb-90´lÅüÉ/!Z­ÄGÇÉ&gÈç•›À‹–±¢iÃVdO å›7³ìãgjx˜©¡!ÒÙì‚sEÍCl×óx¾ð»Hó«–GqkE¢ÍFrjŠœ¦éD÷ÊJÒ££˜**@où$É2’ɤóèŠ×èG å#à²T¥eäøq.<ù$'¿ö5:øC”\£Û} 'SWu5M?N&'ÚÝÍ•§Ÿ&‹a°ÛqVW/©œ²4|êS²Ìàþý„Ï#—Hફ[Rºì¬ª¢áã'“N3ÝßOï‹/’ž˜@\µµ‹–ÍÁµkqVW㬭ÅâõÞ± EÍåHG"ÌLL`°Z—,¯Zý~jyÉå":8ÈÈÁƒ¤‡‡ÉÇã¸n >ŠÇ¼²’e÷ßO^ˆ“ˆDˆž?ÏõüI’ðnÙ²hÕË Róàƒ˜|>¦ˆ=u 5™$;>Ž{õêÛƒ'»[(D*à ájhÀh2a°Ù°øýHÞ˜ö‹–ßü¹ª’K$H…Ã\ù·Ÿ#Õue–“PÌé‘ò, _úLâé šš$¦ÚÑd™\^AQµ9½ÎNÄ'~ c7oƒsi)¡»îÂ^[Ktt”èÈùZH³Ž«ÅtæHM+°nÞNåöíH'Ñ‘1âaÝv¿PuÉÀ  8Ê*±¶5#”—ÁÔup4€dƒU–™<}ŽÞW^#ŸËãnlÆÜÒÁÑŠŠÐ÷O»18øW­ÂöNÃ̼ˆÆ h¢ ƒûR îªRgq";׺±ê¢ê@ÁaIRêŠÙL<Ä{tpA¢u±U$i*g\ç¸Ãs(2×sÙöJ”¾÷ÈüÙßsf2Å뵕$´\¡¤‘×fL¤äâ#~ðmàâÆ{ˆB ȹÅVQqÿâüÏ=‰;05N[ç›x½ ˆ¦ƒO)_˜;·˃b[· “ÏG&‘$›&7“™k@Oþ½sZV ·®AÀP¾u+Ølz6ØäälõE“$,–¶6(+»éži°X°WT Ê2¢ÝŽuÙ2J×®Õy0‘‚Ų¤(â£ñpy_Cœ••].Œ.Z>ÏÕçž#ré-Ÿÿüûz’¯ÜºwCÙd’k»v1tèÙD‚Š÷‘–-Ê2övJÛÚwvrúß 36FÍ#,=9&U۷㪯'—Í2rô(±în¬~?žÆÆ%·¿Ó+,j>ÏäåËtíÚÅåŸýŒ±#G˜¸z•² –>æE÷Ù\ŽþW_¥÷™gP *zhÑme«•š{îÁQSCzf†‰k×P4ɃQãq²×¯ã^Ä5Ø`6ãooÇÝÔD&Ÿgzd„Ñ·ßfø¥—°ø|”®_ûm YO¾Õ«q75áooÇ "¼T>H#ñÝo þù!F'óY¨ÕÏÇHw7á‹:z”îgž&|èJ2µ@ ¢T@Rn!‘6`ŽSQ) V5bX¹•l6G*#?¯ ¤âáCHñÂõh_‡Áb¡tÅ JW®$«iDÇÆHMOßdF&xBÄ÷Î ý»ÿ€Ñn§bóf<--¤3FÞ;¿`_¦œˆ£ªkc#Re”øÈæKA”™8ž¾W^¡{ï^ÂÝÝ¥+Vb«o@*«DMH¢g Dåöí”oÙBß’¹A¢,ã®­%¸aŽŠ ÞûÁ:p€øà eKgÅB{ªlãFÊ·o×åÎv;ŸO7ûËÎQ$>4Ä¥§Ÿ¦ÿ•W{çf¦¦ð45-ªøDgu5e›6aëìdxß>¢'O23:Šÿ6Ž–ÅQÒÐ@hãFŒ^/c]]ÌLO3ùî»DÃäráY·nq°\Sƒ£¦†™D‚L:M^U ”\Án¿­ªt´-Äèré&@ߨür}½h'Ž œ}©±¡ºMUIqúÛßf`ï^2‘˜Nžd¡ÂU-.Ò¹ym$4JYJ\)äÆ6²öññq²Ùì @8~éÝcˆv¬ëÐ+^¡õëqÔ×353ûïfÁƒªƒœ"pq–L£\—0äL”h¹Þ]¶™¡²J$ƒ¤æ¿42vÝ+6ò^û}(n&53 VæWXnùÒôPHor’ÚSû°Žö-,óÏC¤6ß›18X««±74 Ùìä29#£(¹|Á”´Áa¬÷܃äñ,¨ ÚƒA¼«V'"˜ÍxV­ÂÝÖ†’ÉCQU$Y¾é^ct:±ø|Èv;¢Ñø‘ßÊGÀåý Q–Ùÿ•¯pþ»ßåä×¿Ž½¬ OcãâÉ˲ŒÕçÃÛÖFÍÎ ìßÏ¥'žÀèpà]¹rQrªP°q´·ÓðÉOÒW/=/¿Œ­¼ïûŒ4:øV¬ á±Ç¸¶{7]?ûCGŽà^¾Û"íA0¹Ý8kj(Y¾w}½îjz§’i5M'K+ šª.ú»e›Ò¦&š{ Gé±1zvíÂäpºë.½]·ÈœÕ?Õ>Hdhˆž={˜KfzMÓXù€»©‰àÆuxV­ÄT^ÁdÖ[Z‚° ¸0|ê9äðb±Ê¢ÎUY¸¡u4›b^™ÉŸÊÀh¾ (â—œÖ$^OÉê$9QAõ[Çç¼\fÍèt<§K.öŠ<Él9¶·Ã7ÉE+œn`¨´ƒA™mñˆBñ¥"« ˆ!O•‘Ad%?Çk)(¥¡P…јýLDC5JÒ6ˆ ä¾k¤“©’çâKÊ”íä„ö„êeˆF#&¿[}=&¿Áh"9&K !"©žÇGòùfÛûBÒýÚk¸êë,ò’„{Å \mm¸jk±WVêÀ(¸sª×šöÿ þÌ \I¢öá‡Ñ¡C‡¸øä“ô8@pýú%+0¢$a.)¡öᇱ†B¼÷ïpð+_!¸~=î[„×-8`ðÓú¹Ï¡ ãgÏrå'?aðØ1¼­­KòfŠ¥ÇD8Œ&ILœ9Cßž=LõõZ¿~Q×]AdY¿ Þ¡/5ŸgäØ1Þû»¿ãÈ—¾ÄÉ?ú#BÛ·c_$¯I,<ñAŸÅçãâOpð«_Å]WGikë¢|£bVTãc!9Œœ;GßóÏsî¿þW|íí¸I8—dge%k¿üer¢Èøµk$Âa®¿ðWþû'ôÀVë- Û‚$a)-¥å3Ÿ¡fçNd¯ïÚµøV¯^´âòA“]]ô½ù&Wwíbä…ÈéÉÕJ!¸PI&Q#SˆÏþÃýÃVZJóO[‰xœœ¢²ÙÜM2æ|‘„™)¸à$g^Ãñ»„}ýŒ~?YU%én¦^‚’É MM¡ýøI ÿö‹N§î6Póðø–/gèÂR‰™\Ž4ƒ³(b4×®%?3C6™$‹1Ý߯Wè.\$Éàn]³a9æšeV+>óxW´ã_³FË«®&°ÂÓ¸³ç2¢íc Þºm0uìYäñ¡B›hŽ ;WÑH‹R'І¤)¨Ýy”œÞîšï¤;[­ÑÜœÖ>WƒËIr¢Šš×̪ˆ¤x)—k_ Œ¥L&ÓçÆöÊèÂl„Â\œö·3 é²íBútQ%±°£Dº}õŒ9‚ÔMtÏã·¨³ï @ ¢¨âÎGylçVÚ¾ŸTtšØàð,iZQõ—˜1'`2[‘}j–ÍÙéÄÙÖ†½®ƒÛM>Ÿ'É`««Cìé¡p[u5Z>?7Xµ “Ë…Án§õ _ÀTQ­±k}=ÖÊJlÁàZ4U%51Áà‘#¨Š‚’É|àl>”ÀEÉdHOM‘"9<<›Tºˆ(۰ЦMÌLM1|à—žy†Òæf 6Û’'Ö®%¸~=¹TŠsßü&¶òr²ñø’გÑHÕöíøV®$3rèúS|­­HKì[Ê6nÄÓØˆìvS¾y3Þæfò™Ì’m§؉D:q‚Éž2ñ8ן}WCJ2‰u Ó=Q– ¬[GpÓ&òñ8ç¿ùMÝ€-“Áñ> û‚7nd&‘ 68HÏ“Oâin&‹-jþP¹e þŽâ““$''Qé³gI¥ÓÈN'ò"ç¬ÉéÄUSƒÉí^Tÿ¯Þ‚ݳ­¿©®nÁç±Þ^ú ç™gHt]EcžmúüP2?ùbׄöxïÚLÓg>ƒoÝ:\ $£Qâaò¹ü-ÛGRnŽ‹B-ÃtÿDZÖ×c)+C°XHMO“ŽO“/æÑšÒòäµ ƒK–/'´y39Е$É$Ц!Z,¸[[156—e’ÓÓÄz{?wŽ‘'_¸@tpWs3î¶6Ü-­½AD« Á`Åê à_¹GÁ}X½´1†|У{”Hå ,\ôb‡žFœæ8¯=´àÏ,¬¤ˆ B¹™Ü™ BR¹­ƒ®APqÙxÝQŒ¥.’ãÔ¼z¨S4«êü§ko Œèµ“ï±cÙ=rs_O÷ªV1VD’æ*.R «s^æ»ÅwK.MÝxO!ÔQç²ÜŽë"Š*.%ÆŽ›×Qºf ’ÍNlhdŽ·¢‚˜ƒhÄ\V†ay3bs ”<š¢ŽF1–”0vé£çÏ“Ífq67ãliÁô_¼H>ÆæóÍ $Ìn7¥Ë—cr»õV¼Û}[ ƒ샼 `´Ù;wŽSßú—þsŒ&Ñ pTW/¹–~\~Yà’Í’‰F9õoÐùÄL]¼ˆÁbÁQQ±d ÆQQAhì¡gÏrå©§ˆöö⮫{_éŶPˆòÍ›±UTpú¯ÿšîÝ»ñµ¶âX¶_Üuu”mÚ„µ¬L¯¾üìgD{zpVW/º ‚€=Ò‰¿õõxp××ßÑOj.G.•š«Ýîwƒ”mØ€³¾ky9ù|ž _ÿ:S'OR²b¶%RÆl¡Á‚[ñ¹¿ÿ{ºwïÆ]Sƒk‰Š™ I8«ªø+Ó££\üû¿'üÎ;xZZp,RùDWu5Uwߣ¦ÍhÄQW‡Óç#‰ ;˜\®;ÖXjz×.Â_øù½{ DIB,\Žòr=ÎÃá 2<ÌôÄ„®À)´{nä#h}݈ý݈}×WwਯÇÕÜŒ£®Žœ¢’œœ$›¾ÉÕ½hË.åõEŠcoÁ—þ·ke%¦Pd™Èà‰x,¶²¯¿Ž bš^k0H ££ß¢iØ>'ÓoÃÙ¶³ÍÆÄð0Ã]](™ ù™½¥»jµ>H £o{;ÖêŒ%^Ù¢醧pñÊ·!.Hv/Aö9¢`Þ‰n £gß uø¬±èmTE·x¸@’ "åU2GÓhIu‹¨é¨OP5 ‚‚³\Ì7©±rªqp¶â"ÌS÷H‚ŠË5ǯ¥Ï†éŸ†or«E‹­ŒWúÅùà¤Ø2Ro"ì•KÖä ®ôôMê¢m"Œ: IDAT[ušm!Õ¾RÌ^/ÞÕ«±W×Mg‰ “Ke¬V¬ÕÕ˜R ¤í;Àj›­:d¢Q"==ô¾õš,sÖ´yÕFª[*q67c¯®ž½ÆoT Kx]ýkŽ\"ñ¾À‡·¹™àÚµL^ºÄ™o~“+?úJ2I²¿ß"¼¼€Ë/ûEd³Ûd21ÑÙIçÌøÉ“Œ>MŶm‹''&·›²M›ð45‘çÚóÏ3qæ ÉÉIBë×/¹˜È6¾•+)im%52ÂÕ瞣ïõ×)Û´ 㕳ÇCÙÆ”47“œ˜ ÿµ×˜™˜ 9>Ž·µuÉN¶Zïè¤l€á#GèÛ»—+ßÿ>ýÏ<ƒävã\¶ì¶¿I¶Zñ¶¶R¶y3õëÉåóŒ?ÎøáÃL8€Ë–E½W ÀZ»–ÒÖV¦{zèúÙϸþöÛ”´¶.Ù.49Ö®ÅßÑAbr’ë‡1uò$câ]·“Û}ûýÚíø×¬Á»jÞµkq66â[½“Ë…ôLËÖþü?#lÚù& ÙàéhúúèýÓ?%Ñׇ6=MþÀ´S§×­C,p£Ã¡³uë˜Éf9ež‘×£Ö}Þ9€8؇øÈ£Hf3öª*¼ëÖað”Ÿ`zttAèaQ R O3 üែ,ë\¯—¡ÎN†Îœ!/ÑS)ÇuƒZ0—J‘§|ËLk®àx¤ÃJ ÓjvûVì55Œtv"»ÝTlÞ¬WR**¶·ã®­Å^4ö“$t}Ì-ÆùoC*¼Ä“?\¡ [è~ù»pêެ² í™8.â¼ÐDŠÀƒ–gæH-®ÞTiAÓɼQÁeKâuÆ0•û [WaEq]îŸS€‹APp¹§±9’ð¢X0<3¬sn°Ü¿²b9á¯î)³€ß2^Äy-#AÐPD ! å‘¡9Û¸A&­Îr\œBœ-¡Rª ¡’ÙŒ³®N?_Nd›ƒÕJffF!­Íh™ÇŽX³F3u:ÑgU&¯—“­¿Å¦WóÀ¦¡åÕ˜]az‡Äšd“IFNœ ÿ~úÞ|“LÉðÁƒLìÛÇÄo°ì³Ÿ]²åf …mÞŒ³©‰9p€ñ×^£éË_~_sf¯¨ |Û6Œ]Ï&Ùn×Áç ´Äþü¿þÆ×‘ŽBúìïÜpD$Y&=4Ää¾}\ß·™DbNŠ:6†úúëhO>‰ñK_š­X9**(Û²sy9_}u®ZRЯÎÚ°?뺄øÊóˆáQÄ­÷at»ñ´¶â\¾œl6Glt”LQ2-ÌŠà¥óâoüÖ윹ëê°ÖÔ05õŠélÁ(Æ:P«"HÞrœ%;(]³{;–’ÌÖÒÒY·ë÷õ@qòÛ/¬T¨@þ"(ï‚ÁDøD cçiì9uN94›ò<ßîµQA$K9RG²¨ñ›I¹ZEy½UdŸF®1åXulŠÀÛgæ¥D냘ÇåžÆdÎB¹Ÿì¨™ì³C2 •^(н®Ž©úÒP™ÇiáÖÕQÐ ¸ÎXœ²©áž-:ÇeaõEUìb‚»B>ªJ½ ®Q³×‹ÁnG‘$ÂW® ®¶6,Ëj‘,fÞøæ·˜èìÄìrᬬÄìvãäð¸¾Àµ”§îá!¯\5ñ¹ w–S$L.×^~™“_ÿ:ƒ¯¾Jl`ÿš5‹Ê¯e«•’ÆF–íÜINÓè;xñwÞ¡÷é§qÕ×㼡üpùUôêìvÊ7n¤ú¾û˜êëcäÔ)NÿÕ_¾|™ª;–$°B6Py÷ÝL\¼HøÝwyï{ßC0›õ0ÁEÈVE'SßêÕÔ<ôãçÏóö¿ÿ÷\?xP·†·Xn{#+î»tùr*·o'ÐÞ®·ºîàJŠ’N£¤ÓúMd‘ª•ÁbÁÓÔDÙÖ­D†‡ _¾Lìòe.ÿÅ_À¿cÇíM÷ Ǽ´­Š{î!“Í2zú4gÿôO‰œ•GÊêÒc¡ð{¶Umò­µξâ|²î<Ò®¨i8¢qÊ'†g÷¹ Ò2ë+’¨`7$Yá°Qå Js×Ôà‘#tíÙCõCéÄl£[c#޶6Ìõõ4âت«18³®è‚:!òžZÃ[S÷2•虂·¯Áæ0ˆ`2üë^£J:M.•BSÔx\W‹Ýðp.ˆ"³™ê»ï¦nçNÆÏc`÷nÎÿÍßPó±!·urD³ÇCíP¾};WßxƒX?×~òüH&Æ;IÙøA. ªåå´üæo’™™az`€‘ƒIb°Û±••!-–ý#ØËÊhûüçÉe³L]¼ÈåŸþ”L4Š5ĺ„iñ¦n«¨ 73Cÿ+¯Ç a.<-V®æ½îÔëí¥ÿõ×éÙ½›ØÕ«hš¦ûÇÜÀSUkyÌf¢CCÄÇljœ>’HàݸqIÐiñù¨¾ÿ~¬„»º˜8q‚T_’ш¥¬lQÇaA°ÔêSˆ&£2üöÛÈN'¦’’Û˜‚tyù§?»±Wc#¡ ¬^5Ðϳ;hcäwú‡ïÞµ %WHµUT´sg§§õ§îê zàãš5xZ[™žœ$66F&^P8PÃaòßúô÷cØ´IWïV¿ŸêûîC1‰ ‘ˆFg¹/êÜMC;zyý]ˆuzŒìpàniÁÓÖF^ƒØðéD¥ÐzÒp”•aʤ஭ æZÍçIŒŒ0tú4Ýû÷#X­”¬YCɪUL EL~Î ‚(’¿ˆ–¸TXìuuŽ *ÄyYj@RÈè¼8íò±È Aú<È.0xn03ÇŸÁÜsI. Úüv‹4ÌÛò}‚EƒQazA»H™3¥ [||mÍW¹æª'1"Sv©ç¦Ä碛®,*¸ìq¼ÆRUIW– þ³× ™DRrz¥CÕÅ<&SQÒj+àî5Ä26bzP(¾eaÒî¥÷¡Z2 ¦9Ð!Ì—Dˆ¿ ZG: ±O%MŒÎÍÍVZŠÕŸ‚Œ(ªXM)’ß¡©¦GÉ\«ÖYU…ÅãáüOŸÀÛ–¢îÓˆ)ÀZ[‹!ÄଭÅ ÎVåÕÑçÆ÷p8±•·÷ΦQ÷Eà[‡ ž†U`‘Ô$L]{àŸ¿m«ªÌ„ÃŒ9Cÿk¯qù™gˆœ.¿ €EjvìÀUWG6æÚž=\Ûµ 5¦bûö÷õ´[±y3îÆF²©=/½ÄõýûÉÍÌ,™œ,H®êj$› K0ˆÑf#c//¿³<8~É1uå £gÏrî{ߣû™g>|˜\AÌ#ò ‚ÐXƒR[ÇÈÛ“L¸¶ÀóætËú­ÇHÜR=$ÀËìç…¿Cûd’àØØmÍçæW\,–4¾é0‰ é‰ ÜóˆòöPˆÚ6ã)ý2‚QÅÝ܆±¤ ÁdÒ#£oÙý²‡³[Ø—¿Ĺ$jD81¨ƒ—ÞIX/ž„—þ#d§ÀYf÷?pQâ## ìÛÇ™ï|‡¡7Þ`úí·‰_¸ÀôáÃÙ,¹ëױߠŽ+“ÓI厸H„à ¼ü2‘³gA’°•—/Z]6—”P¹};Öòr’‘ãŒ=ŠšH`r»±øý—_5x)mj¢lÓ&d§“‰ èûÅ/H\¿N:Ç¿rå’ÄÓРm= ÷¿ =9‰ìvã\‚ƒâ©«#´~=ž¦&ü«Vé ÚYC†á(/Ç]_OIs3¶Š &;;س‡ìä$²×‹£¬lÑí]µµ”mÞŒ±´”‰în†^‰ýûI]»†ãžÇC¸UÄ^Q¿£s(ÄôØ»w“êé!50€w ’™ ŠXƒA,Á ©p˜ÄЙHKI J>Çù¨üŸŒ’úzlÁ £ wv’-TOæ«~ 8z±¯)EX©ç(Y¼^JW­Â^[Kjz𨨨B×Z@éì$ÿ曈É$ò,¼N6mBöz ÷÷“ˆDf-þµbEõôY”¾~¬>¶ð¦ìñànnƳb²ÃA*EEÍ˱•—#zÜôw]%‰`fŒ£¬ŒòÍ›qÖÕQ²bÖêjd¯³Ï·´hן‡Ø…›ó~ FÓ"¤¹ÀŒtùä!¤ÉØ<ԤΠäº!sœ; ‹ä³hà"Þ¸Ü^ Ž z~“vƒ2hú¼5jÚŠ [r¾}ƒUµhˆTwwÍ~½â’ÇmMà•fkkÉ'˜&68„¢j8¤\)ŸE•Tò’€ÔT‹Z[ÏõCãŒèZðÂUåäw:pøsÄÜù,·ø\Ð4l)£ã·,ó[G ‰*f[_2LeJ@È«XJK #´ âØÁh9† žyˆ·VªGÿRNã0[Ø'Þ‹P´½…ÙêËÉAØ ýl9÷ÿBï›0u šÙò϶–YKK±—•á\¶ EQ˜%›N£±cÇH<ˆìpà¼ÍC– Š”46X·cI ƒo¿MÿÞ½DÏ£rçÎE©’,XµŠ@{;’ÝΕ_døÍ7‰ž?OùŽ˜æ¹ \~EÃìr\»–šûîcôüyzöìaìÈŒV+¾«|±ar»ñ¯^MíÃ3uõ*×víbüôiÌ^/¥ÍÍ‹(£s„y§‚MQHÓûÜstþ¯ÿEjxßbAÀäpàkk#´q#Õ>HzzšKO>ÉÈ[oÍòJm·œkC›6!ÜÕEä̦ŽÅV]»µuÑýËv;%--”mÝJNÓ¸ðÃ2ùÎ;ºÛqGÇ¢Ûív<õõTnߎ«¶–Š»îÂQ]=ºãgïÿ1Ö– ·R¼¸VîåˉG"Œ^¹B.ŸŸ/Åݼ‚vî,»Ç**[Ûôcn³ájhÀÛÞŽ`µ2zå ™TjÁú«êéÓh{÷"ÎÌ €¤Éé$¸nÞövÂׯîï'¯izÕE0òäί|eáSr"h4îîfª¿Ÿ‘óç].ÝÉtÅ .²×‡µªŠë‡ã™'}›ß¯+»Š1 7TÊ—ÿåò÷1çãsù@…ê†XPç¨Úí©r ûÉBF› hT€ÔE„™ æ:r™øËO %õàDq>x¹±mtC Iôj#BŸŠ0 ^ÄyŠ"QÕèó×p¤esÁƒE%k4q­¹ «;¨¾z…о^½¥iÈb·%…WH#44«¨';bEÙw„Øà‚A¦¤¹AÉeÒ¼òÅ{yã7bãõ)Ôeµ u&8tuî|5A Ú°û“ @J‘ßrK—B¾’eb†ÀÈØ\‹H “4?3IC”TLö,¾L˜ [¢r£®*\ày¤f ç/ Ço”ýÀÏAþÂÍÀåÍÿ†˜Ó8lÚÂ>K¡U$€ Î/‚^ ;1éa·ø 3 ÚÆvCß0þ.4}â}·Ò““Lvv2xð ×^|‘žŸýŒñÿñ?0•”`½ÅÚbv»ñ¯XAÅ–-6mbjp©ë×õÓ$fúwˆ¾ø"–ÊJ,·±x°x½;:ð´´0vþó™€Ë¯ü ØËÊhùÌgÀ``ðÝwéÛ»—óOŠ\ZÊõ“'IG" ½ô]ó7”í܉e¿Q–±úýTÜ}7Ά†O¢÷¹ç¸üïèOçòm¸3’,c))ÁÓØˆkÙ2,¥¥w,hQs9&âÔç>Çð /0þÝï{áJ{ ñ†ß_l£Tï܉¥²’¾“'I§R䊎³Ú\+@I&Q_Ý‹øwƒtïý¡2}{¿ŸÐ¶m”¬ZEdx˜èè(Ù|~.¼PQPÉïÛ‡¡ºC¡‚&Ê2Ϊ*š>ýiL¡ƒï½Grzz^Ö€¥ª ¡¯Ë<å–$ˤÂaº_}[e%‘áaÌÕÕ”¶·c®­ÃTQ‰`µ¢j¥ÍÍK*ýn©k{‘zö`F™sªOŽÕª{T‹Dt½‡T• ûñé…n²JG°[^#;˜`fP—p«E›üb„Á’. åÒÎiˆ—ôý‹ŠvCø¢^uTq¬í.¤‚[nQBºçÌ™Ì pï̽ßûý}Ëh/ƒñþÜN΄™‚ý_EÈhvìà€wNã‚X^$ý~J41"Õð¢üíÑ묘yqò¼ó(‚ê- Êh™ ™þÌ]w!–” ¬^ ’„ È&=ûöqúß`à¹çˆ:Ejxÿ¾}8W­Âàv#-Ü¿æNì<­­´|èCÈ>ã×®‘‡É$¤FF˜}öYÜ›7#Ùl7??·oõ´¶Òú‘  ¾ñCÏ=G¤¯ŠmÛt¡òšDÙl¦tåJÚy„ˆßÏȱcø/\`æÄ êxব¢÷€Ë¿€©ßµ‹Ú]»˜íë#ØÓÃ¥ï|ÏŠhš†­|y¡•d2áëè fçNv[·î¶oSVÒé[æÕ‚@éÚµÔ½ï}„'&˜íí¥çñÇéÿÁ¨Ú³ë­* rɵµ»wžføç?çì£R³k¢Ù¼¤EODƒÊînêàÄÁ‘R¡ƒ?úU÷Þ»|jnîù²ÍFp|œ¬ªâíè pã­·¨Þ¶ Dqiá°(¾«k²ãã$NŸFéëC®­½yg£iD††>xñóç ‘I$ÈŒ?~smíÍ;7A@”eÊׯ§îÞ{™&<3C2‘˜?:Ò@ÉfQR)øÉÈ›·"$¥eˆ’„»µ•ÊíÛQdÿø8Éxœ´¢Ì…¿) RSæÍ›sß¡|=Eew75wÝÅø•+d…d,†èpàlodzf BSª$ÐF‡ƒšíÛQ’IZ~og'ÎövmmH¥¥H.—~&þ¯H6Íö¿ 7Þ@R5(9k°Êü‚Ã"7‚€Êb?)0çØÇZ={N“t™D>ÓFÈ‚¨5`+ .Yˆt¯†AÑ”…vhýþpE-Ç×nε?%àj*ª,“6›yó¾‡h¹xÉ QÃkР­Të¢A;×›œ¡¢»O{‰P„É>&öT‘nt6H´ÈD²“lZ»‡¦=032Bxz­ÊBùûe쥱ùvè[0.‚ –É¥#3Kh[æ.CÙzN*›ðágCû:\Ž›5„ꉿENDæ¯Ë, ŒBæQÇ@ÞÆäßíÆ6:……Ã¥;8PywAÛR/yöE˜eE™Ÿ™>Jgä"«b!•‚¡7Á`"em!ðÏÏ0ýÙÏ¢¥R°oRm-B*…P[‹ ŠTnÚ„oåJf{zŽŒQU”l–©§Ÿfæ»ßÅ{Ï=˜¯ ‚€l±P½};•Û¶éµ"Á .Ïf™úÑðÿøÇxöìÁ¸È ^Þ [w÷ÝøV¯fêÊÆßz‹kO>©7§wv.™Ö-ä4j­=„³© ÿЃ¼~ª;n™aöpùWQŽšêvîÄèóäò÷¿ÿúuÊr}0·I›í]ÙÀûK•L†Øä$þ zå&E$l·ÐŸXJJ¨ÜºÉé$<5Exhˆ©7Þ(|‰–U©çÜ;•[·b.+#é÷sáþÈØ¶Š ìËh†ò‰ÁÕwÜ”KaMN2ñÊ+zn†,/ ž,>µ;wânoÇÞÐ@yw7õ»v¡* ¢Ñx[F[+Á _ûÃ_ü"‘ï}CI –…AÐ5 íí˜**ˆG"Ì ‘U’øŸxuvçŽH‹Ø#mååÔíÙƒh·ã%â÷ëîŸFÍfÑž|)FzèÃscV¯—²M›°75‘ˆÅŒÍӾĎ…tÇ®]7Å¥Û++i~àRÉ$—/#ç .­õõdü~³³˜Üî‚ãLœuuØÊÊôfåòrD“étfûÞ${ýÂÈF,€¢°·"ÝKAÀ›i0ƒ4½yô“»Ø×µcœœ‹¡U,¥ŸC¤”ÈŠ†”ÕÔùt#Uµœìê.èFæ:~ÔÂuÒjãµ?Ê`s›®œ >Dhk#µb-©ò6üg/ NE©Þ±G}Á!&z¯º¯µÑQp ËQÉDªÜÎü˜-d,QJ6ÍbóÆçFEÅ!t ²\¤˜T¬ß€u2Ž%“œ  Ó´›ºŠ¢—7Õ]nC0¸ØU¯[–ça÷Ã"Å#‹áT@9‚-rñ(“rO5’óUk £¡xéfÝ "ì·¼Ÿ¿îÿòÜ{ ¾Atbœ©oþ ɹ Dmß>Ä}û;:ÚÚpÕ×Óøþ÷ ‡ OO …rŽø4¡×_G–$D£qQz |ý½÷‚ÙŒd„X0ˆªid£Q"o¿­ °ív K0Üîæfî»U’˜½x‘Þ'ŸÄ`0 ÚíØoqL(]µŠºÝ»‰Œ=Jh`€ª-[–Í‹y¸üo,&·›šmÛð®XQ8`ËF#²Å‚ÑáøWÝ6ºU%Óû ûïÿþgŸ%pþ<™doGDzc£ÃAew7%k×’ˆÅzë-Æöï'|éåÛ·cº…€Õèpèz†uëˆÍÎÒÿ/ÿẨF#®ææeßÛätR¹i¶ÚZ4£QïW^!92‚àpਯ_r»Éf3žæf\Økj°–—cÊ;€n·ñO*ÅÄÞ½ôÿèGGFtËÁƒhcc‘ÆÎÎùÿ»Å‚»µ_Wª,&‰èºÑø >- IDAT³gÉ ’¼x×®]7½—Áf£|ýz|ëÖ‘Êd˜¸zµÐ÷£.ìJ&‘[Ú›[æ­wWk+%]] Á‰ "~ÁH“¼x‘ª/~±Àº,dê,ååHŠÑˆ³£÷š5XëëÑDQׯ,âˆø·ŒH]=Hêò›º7wÑGEÌK^[R$xUM"ZBÀt6Šþ¼ÅD·¢L œ‚äÄ|'•˜Ë¤C L_…x@ÿ]A-f_ô÷©®áM› ‚Öüx¥ pͱ0VYO_íJN5wsgz šÛÉÈ%Ä.@L jÛvÌ¥¥Œžx‡©¦(ÊÃå.¹0ò‘PcŠ+ €É̶®‡œ1 Ž·±ùb 󼺅ɹ¹û¨Šº§Jb3!®È\Kuþ0x9o]"…ñ0ô`K +¼ö(B"r3sU ³g0µFõ~¥Á5üã¦?Å_æç(Zxh_Œ¤ùë _ž÷æðEÜÍKÁl®‡RˆÇáèQÄžŸ¡¦£ÝNíÎx::ÏÎâ"«ª¤üû÷“¸x÷æÍ—pñʺºðtv’J§™éï'“Éžž&°?É+Wpßq†Å„´¹òqwt ‡¹úÄLŸ>$Š”,£I=¾~÷nJ:;‰NL ©*ÞÖÖw݉ýopÉo0Os3ÝÝTlØ€·½³Ï‡lµÞVI‰¿ê"JF‡WCe7‚,3}ú4㯿Îð«¯ÒñpËç;ëë©Ü¼GK SW¯2sö,3‡1¶?Ÿüä-u3öêj*·lÁÙÔÄð›o2ôÒK îßOû§>µ,hewS®æf®íß`4b--E¢ã㔬[wËq¡ø.×$E¾ÿ}ÔHýW±ÉI.ýøÇŒž>M"Ñ÷“Ù,©“'I;†©¡ãqŸ IXËÊ(Û¸gk+ÑQ9пt‰Ä‰HàÞ½{Qájh rˬ :E"›—~«ÙÙY²G`êÚ€\Ô%J–ÒRJ»ºp¶¶’J&‰ÎÎ’N¥p47cì[·.ú9³•—S¶~=•[·b©®ÆµjÆŠ ¬UU:ëùkã%.$qáÍ‚ºXË«Œ]W"£±.Åviú §“sÝÜÁ2¯cÉ?&™!1 ÁžëÂû",ƾd`èR±8ƒ‡Y—B¾Ó‹AÊÎéVÐ ×ÃLÒc˜ »B£ñ4VoüWr¡BÊoÆ1¡$:[ø¡låó]f >κ×ÀÄ™I8> fI/Ÿý%•ƒHYený-ãÞÚ`°¢žçì!äsÍ„‚áfcT3üõ‘/ߌ$\5àé€P"ÁÜö áäI„Ǒ´ÙdÂ×ÖFÕöíV+Cï¼C&«‹&†‡‰:Dø…(["Y\2™pç\z¦²2ú%“Në'D"òê«”~ìcKŸÜµ¶Rµm²ËÅ•ÿ˜‰cǘ¾pWK˲R 9ÔZ¹q#öÊJL¹Ì¦÷€Ë¯q‘M&,>&§SO¹½MA‹¦ª®^Õ£¬Ýn=Uq™ƒ´ÉéÄÛÖFý÷Òð‰Ç{óMzŸxÑëÅÓÒ²üó].Ê×­£êŽ;ðŽ2~ò$á+Wð?Níý÷ôK²/N'¥kÖP¹};¡¡!&Ž¡÷G?Bôùð.óÞ¢,c++£õÃÆVW‡µ¶V?ÛhkC2›uÖæ6 ñÓÒiüÏ=ÇПü ɧž"òõ¯ãüÜç Ù%Å,ˆ³µ•éÁA&{{É(ÊÜø>!ñòËÄ{ Ûƒ"-Hð•­VÜ+VPyǨ²ÌìÐñX %“!zâÓÿø}>¬«Wßô=0:”­]Ký½÷2;2ÂÌÐUÓ¼hõïÝ‹ë# y½71?¶êjR‰‰XŒL&ƒ½µ«×K|d„„¦é! ¶l6cözõ`?‹A–rÇ_ç<þcÿë/ék¢åH…Û*Hª6¯+HP4PÄÃ;é›Ïöœù YôêyfªZÔß”»Ö}ó™/)è¹ ¡ð‚—ʳ/ªÀPs=¶¬Ö™´JÚÐ(Œ´¹Ûa“ƒ/&Pm>Ž\%Õ=^†ÏžgôÔ2QÌ«m*È¢‚$Í¥áJ(h( 2æµP暢TšÁ$¤çëY°,óò]THÍšqGðEü7‹r at0c.á”oÃNüÚ5â.P±x³ÇCåæÍ4>ð7^ÑcǸúôÓ4Þ{/fgYM¤Áj}W‚–ßJàRÌÀÜÖ# E¡ïç?çü7¾ÁüÇ„z{q·µéíÃK ­ÉdÂVQAãƒâhjbèÀzŸx‚ÈÐÞ•+1:KÒ~‚$a¯ª¢ýcÃàó1{ãGrù+_! Q¶uëòÑû¹ç·>ò‚ÉÄà›oÒÿÔS„nÜÀÝÞ®íùÛóÑÔ7R±i®–¬••ºªý6ÜŽÙh”é'žàú׿N ¿Ÿl2‰’úéO1wwë 4`(ˆ"–’ï»sU3Ãħ§ÉæÜ?™TŠL4JìñDZßu¤Ró@DþùU;wâhogvhˆh @*‘ Ü»WwðhÆ3nQ’°UVÒô —”0;2Bxv¶ðÞª `v{pîÚ…±©iѳBߪUHN'iAÀÖÜŒ¯« Gc#™dU— jüM ¥c=ç˜}éIĬ ã"%w)/¢ª!©j¡‘,hã œÏ"Ä´%‹;pƧ`f2©å“E×(zûµ‚ñi˜äj¼ì`U=ßüÕšÐJŽ­(°#yÆE+røä~fÏdøÓø0š« Y5cĈ(±øJ°•–ãXc%%Fd*²˜E‹âüQD¸*uð¦píÂu|Ìæbþ¤hÉ36űÿ¨š1áŠR™ß ­Í×èL[J9QÙ}ÈÑ,<ïü¡Ó¤T#¾ÔZ~ô–Í­÷ìÍ ²_hâÏG‰¹ì7Ñ<;ôbFƒšæO~þeÄtΖ½y[‹\q ¦È½½–H MN"¼öâªU¢Çƒ½ªŠUŸþ4iMcvpX4JFÓˆ÷÷3ú•¯ NOãÚ¾}Ñý«(ËØ««i¼ÿ~4“‰Ù‘âÑ(YE‹…ò{îÁ¸LþJ¾“mÅÇ>†³®{u5±‰ Ò‘Þœ6çv[~{Ë펻D‘òõë±××zí5úž5•¢¼»û—ÒíøV­¢rûv4`pß>† ›HP¾iÓ²L”(IºöeÍ"Ñ©)&DM&IMLà½ÅGelµµÌ\»F:`öÊ,¥¥8ëë—¯Z¤Û~´êéáòóÏ3zê‰htÎ> üq”žÌÝÝóˆd4êz¡µk ƒ†‡Iç¨aÝ yüq”Ó§1o܈¼€ê ¼TlÙBVŽ…PÀ¾}„~ö3lk×.š !›ÍTmÙBéºuÄ¢Q““$âq³k}=Âè(î|dñÏŠÁ€¯£ƒªmÛ0UT`onÆR_½±ñ¦ð·Ï%Ös‰Ù—ž)Äòkêü‹Z Ëi_Tr @¿qšÐ&@ìÉÎ)7i-²àô‚‚Ssá{Å %ÿ˜”9 5>89ÉìÍ/u9¹²{ Vk"ç&šÓ‡äÁÊbºQÓ°e³üqlÅ[”𓞠šdêÌ&N"=‡\žš×P-j:‘Ee.«¥ V¹H'ÕÚ¥ÂT´,.ØÕGl‰ ŽÁ(Þp`®h±hÔ•¿LÙË9V½uñqNîò¼û“°ÜËÊȪCúvR@T‹Ø—¢ ¡†fž©ü(q‡uH)€—%£šæ^ø2š¦3;ÒÂñ^îó“­®Ç/”FÉÅh kÔarqëV‡£ÝNý]waol$â÷!›cX#§NA4Š29‰} ŠÁf£zûv¼kÖ ‡™¾qƒðÈ Èd³&–’’%ƒÕJņ ”¬ZEÙêÕ”vvÞ¶úÏ÷€ËoŠAÑ4Ò¡Áž&#<6†£ªê–WCµwÝ…d³1}þ<}Ï>K&\Kî­[e%›7c./'pù2×~øC´T ÉãÁ~ ë³³¾žºÝ»‘].fzé%Æ^zI3,¢c(^ÕÕøÚÛ±TVRÞÝMéªU˜Ün9ëàoõ"ˤÒi¦oÜ N#Z­¤R)½«Èöô õõ‘>sË]wÍcÀµµÔÜq’ÛlŒðôô¼Ð·Ìð0ÙË—Q.]ÂÔÕ…¸ÀAd)+£lÓ&,55DÂ33d2Ôd’è¡C˜±­X±ø6«­¥jûvfˆúýh²¬÷­]  ³8Šô. GGöª*Œn7¢Ñø®ÚÆÉ©qz¾þ?H_¿®3.êü$ß<Ó²ð6¹D[Q-)¢œU¯)KÛ›sÀEÌÀà5ÌÌÕÌK..Æ„^d¨~ú?1Þ?L,š÷’ §ƒ¡Ý±Z¶¥ØU”g. ¢×"·‘5£òùD¥¤I¸þô>Î}ï †^™‹1”F±5ȹ–ê¹Ü½wHÕ™Q-©¨H„'kRgõñ’¨.ÞÓ¸$§-ØbxB%­Ð“Ž 7l/¸}–/AÙËÓ&Z"W¨Žœ[Â"âç^[+ÏÕ„ŒÑˆ& óÀJ})Ö¾HsŒË'žù2Ùbqu†y]TšFë,¾¿ø_$Ó"33­Xñ÷•ó熇‘î»Á¤x–¬\IŦMKKŒ"Š”.p½,<˜•¯]«‡¿55ájl¼-?ùE‰Çé{ôQúþçÿdê'?ÁÑÙ‰q‘›ÁbÁ×ÞNÅ–-”twãêè@“eüdUUõô9zmpÛ‡>4{;”wuén¯d’霫 ¿CL’ó Ë—Þ¿ÉbÁ·zõ²4ÉhÄUWGý÷"Y­\á&Þ~›‘·ÞÂ×Ù©«Ä—yQ–±”–R±mΦ&ÆbàÙg ܸoíÚeK#%£G]éD‚x0Hxl ƒÁ@zv–‰ (YµjÙæe)gM¿¾ÿúuúŸžk?øo¿Mìúuü{÷RùñÏEÌ/Xß¶òr@l܈{Õ*TA <5E<—"«ÙK—Hüð‡h¡–; _ ˜KŸ­Û³Ku57Ž+tjdŽÃõñ/úþÖŠ *¶oÇÕÖÆìÐáÉIRÁ þƒ)Ù¾SyùMÏË7>WtwS³kæêjì­­ØÛÛ±ÕÕé‚Úß›’ÍY~…¯b."`æÌn<ý4ÿþïIö cH-. .h‹<–;Ê)ð÷hG4tduà±ÐY$( ¤ÁgŒ£vÝOh*J*)€–<ˆ!×¼lŽA5 þáŸá^»Ž†÷½SE%£ç/ˆFQVR»Wa5'ç2gÈ \ .£ÜH'jòã³"ò« ìmTÔ4b©ª¦ñ¾ûp´ÚH‡ObPŠûšæ‡ðéY79¶EÊéY4 k$J£ÿ¨‚þ;‚ŠlPež@S¬7xÁœÆ…y!W0æ¬âhÃV4Y@“ÄEÙ–b0ã7•pÃÜÆ##ãNÌ„Ðð¨Â G/5<07b44YD3ˆó_O˜Ÿ¦+*ÞÓÓtö>¯'L :xQÑ·›”ѯSXþà¯1WVQ²aÎövR©Ó½½dTužì&35…ûÏÿ|Þ÷M”e|+VÐø¾÷¡Hc.ÊdH¥ÓL?²Liw÷¢z0A±WTPµu+U[·âíè v×.Ê»º å°Âm®ó|¸üº°Šª’‰FILŸ;Gjf†l,†icx±X¨Þº•¶GaôÜ9"££ îÝ‹½²£ÝŽe™è|r ‰µ;wÒþ‰O0ué‡qþ±Ç¨Ü²ƒÝ~˰ Éd¢týzx€øÌ ƒ{÷rúoÿ–Ú={¬V KœM ‚@ÙÚµt|ò“ÇǩضÊ-[¨Ú´‰t<Žm™Èþ߆Åâóa./gèäIcc$“I2Ñ(Ã_ûÁ}û(¹ÿ~äEÀŸ ŠzeAu5e;wb®®&‘Hž™!•N£( Ù@€ô›oêúGw‰b! °bãFZ?ò¦‡†LL,0ÉÞ^Çã¼çž›"ÁóbmWK ¥7¢hÁ±1,ee¤úú¸´?U[·"HÒ<Ñt>ÂÜZZŠ«±sI B.:ü7Zf&áÿýý`Ò¸ê—/™xœñwÞáÆË/såé§é}é%¦ÏœÕEË¡p?/ÌU‹Eº hÙ;’‹ï7%ÀRf`r"aM? Wtð"d(´B iýbH+xþê1¬«7 ljŽO“MeQ %÷~R Œq0[݈C§>ø V+U[·Rs×nƯõNF1ìhÄbNÀJ^4+åïkJa„$is²wH.</¢`Ààöà]Õ‰£®Žl|ŒØ•W1dÕ9¢hó*Ä"g•¨©ÈBIP0…âTOõ¡eE@Ë…ùÉ’‚,åÆGèÀ%9eAÖpÂÔ,Bîo,Œ´4[ ÿuÏÓÝQh"‹²#ùQNñíŸý¿Ï§^")š±GB#(0ähàÕ¦{Uu^Ø ":@’°/’^äT––·.Ð|ãE2ŠZ¨ÇÈ¢ ¨UâU”„ŠÿͧpòÏŒFœ--”nÞŒ©²’@®]=Í’R‰Ñ7Þ ôÿð¦ýƒÉé¤vçNª¶oçÆáÃzh 0zü8“çÎánk[üÄ4÷=µ••áÈ5C‹âoÀ¥÷p¹%™$ÔßÏ¥þwþæo8ÿ•¯0þÚkºÆ ²rÙµ´”Æ{ïE¶Ù qý§?¥ÿÙg)Û¸û-ú–òҺݻ‘ìv"ccœÿæ7 öõ᪭Å^[{Ë¿ÝärQ¹};‡ÄÌ ç¿úUÂSSØ«ª–MX$‰æû溺« {]®¦¦[&2¾ÛÁg*,°·Zgõ{ö :ÆÆˆ¨ªJjr’øÙ³È&ŸÙáX4:Z[q¶·#ØíDb@ZN¿õÑï|SK ÆÍÙf¯—†÷½Ñn'89I4 £(h@¬¯ôÐÎ-[O¢,cöz ON’V,µµ”tuQ³q#Ó}}œN,Kí¯åûÁ߆·žƒšFˆ¡²¡ðãt4J*&uã‘×_'{ñ"Ææf$«gm-J*EhhÁdÂPR‚j± ­VÌnb”dzQËÂǤ “º ¨·O#ÑæÆšþóüAÈê@FÈ‚á÷þ÷wcklD´ØHúƒ$ý!Ô¬>ž1¤t&Çê-ð¢êW@©>z´WV²òSŸ"œ!æb6§Š•çç¸ ÆGùœ”LFe0«qoI"ˆsÅ“‰ñ+Ä/¾‚¬gÖµSŠî‹h¨Ëts6^Ñ å j¼ $&­ Çëpø£8á[4×-qƒ•WÛî-¸ŽòeŒš$äÀ‹°¤…ÙÖç©>Ç©¦-t^=‰'0]ñ ¹x£uÏ\nL‘¨Y€Ú¹4¨1-èpçbCr#17Fd#¢Ý†°ý¬µµ¸;:°”WŠÆILÍ’%‘Ò ©–šj, ét͉ާ/^$›N_ÃlJͯ,t ktw…0Á.ß‚0ßöš¹Lâì/0(j¡þ ¸™º¸ö@\0FЧ$ý&JãáêœFHЋk%ýïJLXH ™(›ÂžŠÎmNã’0Xy¥ý^ýЊþ?ŠØ‘%\@Þ?C– _ ׫WÑ_ÒBóÀeDEáDÇ\¬Z;Ïi%ƒôrGMšÏ¾ci6Œ'ù½ÿó^0™ Žëã]U+hWbÖ0üùN²Èd×­ „ªy ÄÑÔ„»³Ùå"<3Cxf†øÌ Ó§OãX½zÑ“KÉ` * êY±BSݼ™òuëL¦÷€Ë{ÀågáŠB|l ÿÕ«¡Ór‹»±‘êíÛ)ß¼™’õë™8uŠ?û¡³g©{è¡BËR#o[•ÝÝX«ªèýùÏ9p€ÙÓ§©Ø²kYÙ²4¹ Š…Ä`[m-¯¿ÎÐ/~ÁÔñãÔíÙ³,xÉÓ”¶ÊJJÖ¯Gv:ñ®Xlµb))Ñ3_~Ë)G%&é÷óΣ2üÊ+Œ>LÕ¶mËZyEIÂÕÐ@ùÆXª«»px.õ6zñ"ñóçIž;‡·¨ùxá67º\¡ Q¿Ÿx(„¢i(™ ‰£GÝnl6Ütf欯ÇQ_äpÍdˆÎÌàlkÃb·3ÝÛKùÎKn7“Û³¾si)‡Él~×íSGúêW ú) „põêÙ„ .Þþê×™>xD_ŸNãk‰ãÇÉ^¸ÓÓz^`¯¨ÀZZЧ¥…êmÛ(íîÆ»v-§ÁdFMeÉø#(ÉÌœ`·ø`œcTL 0$!{ç'éëŸ$/ìK̵M瀋ËFøøç Œn7Žæf\íí¨dãIl¾RDIÆPZ†sE™¦ZfÒ"F› Éd"›Lê%ž¼ŒÙ”šÇHÜ$ʽI°«w,•j½l· U<‚(¶!:£“¾Lêä~q™×ŠÍ\É£VôXþqMƒŒ€q"Œ72V÷«ÿßZ‘«GÐ42³&âc6JÇgp¤¢…®¢bp’0XtàRôåvÅ\•.æk_4*ª'‘ YDAc¬´ž;¹X·ŽÝÇ_äÐ0a®œ|Ú\òœCKA/äØS(ÅÚA>þÈzJÖ­ÃV_O<e¦§oNïò`%´Û ¬õ0ÁfÁ…O¨žÇL ™l–T:MhrE’0º\$¦§™¸t‰’Õ«-öµ––ânnÆVY‰%—þþhy¸Ür‰Žsåé§¹ðÿÈůÑ—_¦åÑ÷ùŸÒ5k(ëî&“É0üúë þìgÌ9BÃ9…Q€ÛMņ TlÚÄìŒ?Îðþý ¼ø"+qŽ,öüò®.Ê6l`úòeFdpß>⑵˨Óó̯£ƒò ([¿ïŠ˜œÎ[6M¿›—¡¯~• Ÿÿce6ëL¢Ï‡¥© £×‹lw  iˆl$1/J¾¦›ÎŒøþôK4}áÏ™ìíe*šnJ¼U@öx0´7!<ô)È}$³Ku5¥ÝÝ8ëêIøýDgf0VVâ^³¹º‚‘7ßbÿü+$£‘ÊM›8þÔ°;§tà¢ÍÅú‹Æe ;´¦AV T™f‹a?švE|Iú‰‘†¾õa‰„U­à"* ‰ùÒÉE# †É(ÎÐxA ËgV>ëFˆJÄFmxFýØS±›j M#a´òj¸úŒæ[§Å<;"‹…Ñ‘”U©®Å(g 93’ 2\ÞÄ/6<ÄÕÒUøÂ³EO+b^ÔörUwD,Á$kzfùÀv]7âno§êÎ]¤“IfûIÆâ˜>PŠ¡ÝŠˆJVK0F—…w¨Z°â(°œöÊJ.=ó þÁA¼«WS¹u+î–Ì^/J&ƒs‰*a™¦û÷–÷€Ë’òª­[QT•ÁC‡˜8r„çžÃZQ½ºzÙòÀ|zlÓCá^¹’þ˜:r„àÙ³x×®E6›—°‹²Œ§¥…ÎÏ|ÍhdìÔ)fÎcdÿ~±ZEèÅÏw75±ê3ŸÁTRÂø;ï0òê«Ì\ºDù† º³g©ÔÜœð7OIÞ®mÙép˜¡½{¹üýï3uú4ééiüÿò/L|éK¸víÂÔаøzkn¦ý‘G­V&NâÊ?ýR÷Ýú6[b}ˆ²Œ³¶––‡ÆZWÇT?a¿Ÿl&CðȆ¾ô%L^/Žõë]§‚(bt»ñ®_gÝ:d¯—ÐĉH„D_&‡Û"ómQ’ÍfZ>øAï¿ÁáÀ³~=î5kðttਮ~W¥kÉ©_¼Hæÿù3¤ŠJ‡<>ÔL†Äì,3çÏ3ðóŸÓû“xë­‹’C2 „ HÑ(Ö×@Irïÿ+Y——Ðô4‘2ªJ&™$²o¡/} ë¶mä ¢ˆd±`®¯ÇÜЀ©¼ÙíA‰%IOQÒ Z>aWÑu(†8˜Ì þKXþ,-ŸøÆòrÆ®]#‹‘ιHt½ª€¹¬ËÚNÄáë°qÇ0 =~œá“'… ‚úÚ‹?ýb÷’V'Ão¿Í…ü€¾_$xô(ˆ"JVÕÇfó„°b&ŸÕ¡Áô(òd/±dš‰‰i&‡Fæ%˜*šFôÉ'±®Y‘òQ¤ Š<LUUËÊlvD2¡Ù˜®}É&cÌ./†–¸ó#HNU[¶P¾y3Ñp˜ÙÁAÒé4 šÍØë°¶·"ÕÖ’±yQ$ ÉdÂ`µÒ÷ÒKL_»Fhj g[îÕ«qvt`njF(/ÃÕÚ¦³§k×0ºï <¥!LÆô[ hóîšZd‘.f\À“²!{j.éWƒKÅÖ˜EŠhH bÙ¡ç…Šõ.…ÛY§"§ýóGE9ö%?.0ÅR³f” ˆ¥4Q‘ŠºŠF ¯­¸gN˜›gZ„"oñÏУ'ä”Bet {il^ÎL!íWЈX –4`ÌdðFóÚ´¶k€_J¡ãd?»ÝqäbÖR1ù|ˆ[D¨»ŽÉ.ü­së]å‡z©š°âœëZ·G]Ý\Hãm Z"cc$ýþ·tì÷€Ë-{e%->ˆ&Ë„ÆÇxñE"ýýdý~J‰ð7kYÕ;wbôùˆùý <ÿyT¡Àª ‚TªaØ¥ ¸48$Š”¢Ÿ+âLq28—q_TX™0B,)lÈ@¼'…I*$Täs”0Zy­}Ï|áqñµ6W+P\&)¥U¬¯$¨Ø>9Xò-ׂ†„R?ÓöRZÇzõ*m>à+®RÈ31 ÇN±Â|œ’ö; ûL5›%:1ALX~«Ž‹áf®\¡ç…Dç/ád}¸ü†Ùl¦bãFʺºH„à ìßÏøo %]]·Lƒ•L&|”oÞŒ&I\úîw™8p“ÃAɦM·|ïê­[)[¿žd,FÿþýÌœ=K&%“LÞ²$K”$L.’Ét[‚5“!:1ÁøÁƒ\ûö·™÷ÓgΞ¦fÇŽeÿfCÎyäíì$Í230@:ÆÿöÛˆF#ž®®EÁ‡l6㨩ÁQ[«‡VVâëê¹r%e]]’Ñø®Ÿ}kŠBbf†`O'N0øóýŒÿÝß!u©€Âáב{/Qù»DÅ>Hù¦MTìØ¹º†t*ExbŠt*uS09íK>)Õ4ÞGmG=ÎÏþ%±H„éžž‚hVÍßÔéÓdŲqc¡ä²˜¥4x½˜ªª0•—ç>"J$ŽQ0aMÈ/æöVD1]wÀfbv–êmÛ0—”0úÎ;¤³YìmmxV­ÆÜÞŠâpŒ§PT%ÆVV†Ùã¡tÕ*ß²ÛÛU_OEw7Φ&ÆÎŸ'6=M¬§‡À©SÄB!\­­‹n7Gu5¾+p·µa¯­Åàv#ÛlËjmÞmcÖ©óç9õÍorùÇ?fòÕWQã‰BÔ}¾Ô0ç¶E›š€£0ýâ,_ø¿1•”àjkÃÑÒ‚`6™œ&æ°°"HC¿!çÇGWpº Ôý·@t:»x‘d"Q°.g&'Iž;Gò•Wð~þó7[ùÉfÃTY‰¹ºÙåB2[qVU“ŒÆ.lkV"¶5]X<}Äg6süïÿž+Ï?OÛ'>äñ`ª¬ÄÞÞŽ¹¦cu5ž¶8››1{½:S* ºûd©ƒ…ªyæëxJtà2OLª-èjó´#¢¦¡e±«‚—Š~…9ð¢ :“R£!Ö¨pP˜Çº,•é"ª*Ù¬ôŒ ‰8B¼£ËܨÈ).–™J¢d”yàEÓàÛ»þ»s>Ë2¸ˆ ‰iëí÷S¿upž ¼¸±Z×ÅhšJóÀ $U7µ¢ÒÇ<ðÈh4 ÒÐq–€m˜ÉòŒóm6ïB”e2ÁÃñ7¥lÑz_d»änG˜b€«L#4 «oùýMj|îTŠgFj--ö_€d“ÓÉɯƒÿå¿à¬©Á»DÈM'h6›ϰbçðÞyì1Öþóï—wãbt8¨Ø¸‘Îßÿ}FOŸfòìYúÿùŸQÒi\MMºöe9ÅjÅ·r%=Dpd„ÑC‡èòIJÖ¯ÇètbX&ùÖèpà[¹’æûïÇÕÚJÅÆ8ª«õÜ‘ÛMÑ%' "/Q ‚Þ|ÜÞΊßùn:D$ •É IŽáúiJ?ô!PUÄ:A­VJ:;iþЇˆƒLõõ‘ÎdP4ôä$“_ý*ÉS§pßwâ‚ñ› Š˜\.ª·m£åá‡=q‚‘8ó­oáio/œ‰-õ·›\.uuøGG ŽŽânoÇ×ÞŽA–éë-ª¶lY”}râ[Q–ßuL™¦((™ }òIf¶oG²Z‘««uÑ­(⨪¢éýï'6;ËÔõë¤ÒiR™Œ®?)²«9öE P'Çñâž‘ŒF¬Í-ø6nÄTQA*™"<1I:EQµBŠ©(¹±„”ÒPdË'>Kíž{¨Ù½›¡3gˆ¤sÚ—,šž&øè£$ŽÃñþ÷Ïßæ‚€ Ë|>Ìõõ˜Êʘééa¦·km¶+ëj‰_¸ÀÞ¿ø¢HYg'µ;wÒ°{7ãgÎÐøÀ”oÛ†¥®cu ‚Ý¡¯³ùWû®ª ©Ÿý®’F)“KÅ·JÚœ(7ŸH[›j*¤!œpÛhH € ªPèZ*î\_¸Yˆ;ïR”ª«¥$Rãq´p¬ bÎ§èæ“‡¥ Xb`ʨ¨I#ã ÒiUÕ?Цo»×7Q.ΠQçI?^ :È x†‚4oéC”yÝ9Í‹¾Žšúú‘T%7.ʇ(ˆs%5'lÎhÔŒŒ°¢á*‚IC±¦‰mNàˆ)y9ú1S$(Î ƒçéŒæÀQ’²`¤MÜqËÍîO«|·/ÂDRã™Q«,àµï¨šÍ"²ûQ’0ØlÔÝy'žÆFüÅ_pññÇ1û|¸êên=M0°WTÐöðè™ ¯þÙŸ! ¸o)ex¸ü¦Ï(E“ÛMÓý÷#Ú톆ܷžïŸª;1ù|Ëöå£Ü]­­ÈSW®0òÒKL;FÕ®]ÈË’®žüÜìñ  ‹öXÜ EÓ\¾ÌÕo›³ÿù?ãhnFM$0—•-¹Îv;+>þq4«•Ùáab¡YU%0þµ¯‘¾v ׎È‹QÄèpP{÷ÝØêêÍΚž&“Í¢¥Ó$®\!;<Œl·c(+C\FQÄV^®ë$‰ð\ùÞ÷ˆŒc«¬Ô]<Ëœ™´|à”vua,/§¤«‹ÒM›tÐb4ÞlY>a8>5ÅÌ¥K 8@æâEzï÷PÓi2¿øé¯} cw7R[[A‹S×]¬ûÂÀjevt”X8LZQtƤÈF«æµ/ÓSð½¯!Ž nÜ\VŽ{Õ*MMˆ±`x0¬k–´¹%Ǿd''H‡&±Ü÷aÕÕ¬ýìg‰†B§¦ˆæØº,Ídˆ]¿š†ge=›LŸ™!44ÄÐáÃô¿õ‘pwg'Ž–VLµud ffGÈÄbzcoCŸšmÛpTWcöx0ä@\ž]ùÕç¤ ™§þÑ—@@Å€RÐoˆ Xƒ‚0U›Ët!# ¥J#ÓÔE† ã¡Âµ:ÇÀ³Ò>=íVÌ“¼Z,,úøHE©ÑÙ n!Ïçßä_3¯C²Æ5Li1­ÑÛ›!™Öômßæ*\^¿ ÁÈ܈…n"­HG2w› ¸F´o¹V¤oɃ-w;guV5šzú‘e.ˆn¡5:/ ÎhTMŒ³²úÊܨLÔ*=EÀ:Fy`[ø(1;¬´Y:ó€‹~ß&øh’wýÀEáÉÁ ¢ ¡¢ò“! ÜU&Pinù=  1sù2£GŽAI¥n©ÍË;ZW~â:[úØcħ¦þöÞ;¼ü>÷ýÌ z! A‚Ø;)J"UVÚÕö]¯7Nì8DZÇNyÎÉ=÷æ>ÏõÍÍuNNŽ“Ü$n)¶cÇ^·µ·ÛÛ´»Ú]m³´Ú"­*%±ˆ ’èefî€%‘rެýž@>ĘwÞï[°•—c))Y?hTu:ü==TìÙÑ/|@_vŸOËAû%°Ä7€ËÿÂÒ[,TîÝ‹'“¢:ýÞ{Œ'#åˆÖ:Ô<&¥Œ’&.ËoÉÞ¿”V1Ç´Ôa½¬pnP%§°-[…‘í{ô«c°+‹ ¯•LM…Ø´£¯@ßRî2€F•júÇ´Q‘Z8Ròµ³Ú™²À ›JúV›²3Ϊ¨ ¤ŒÐ(Š.cT’«.¦5º™µ·-¢‡*íî÷¥”ÌCc «ûUP‰Ê*o ¥ŠØt¥Æ«—…¾¾ÜçôÜ0ýúë­V<×vLÛ¿[y9ÃÏ>ËГO’N&ñ]ƒ´ð¼º»î"41Á¹‡"84DåîÝ¿ðcÙ àò XŽêjÊwîÄV]ÍøÑ£Œ=ó KgÎ0ùöÛø÷ìY—2+ªªÒ„Í͸ÛÛq55!e’•‹ ŠX}>ŠÛÛ±TV270@àôifŸžÈÀåwÜqõñ‘(⬭¥|ÇlµµŒ½õV.É4Ü×ÇÒóÏ£ƒßsÏÕ»¬ ow7E,ŒŽ²4=ûî]>z”º?ýS„«¸wDIÂÝÔDÙöí8›šœ9ÃÒð0J2‰£¦fÝ¢KQ’46î:cÉQÄärå.ép½ÃA*•"¯êN RÏ?òî»èÛÚràEEìx·oÇä÷#4?Ÿ;Î]ƾô†×žGÿG‚`0bp8°ÕÕáhmE•$" ‹DƒAÍ6.È DbHMMêr¯¹«¡_o/‡ñ“'s ':9IljŠ´Å¢åjˆ":³»Ï‡ÁnÇQY‰Þf÷k—ÖÜÞŽÞS‚`±¡w¹1{/É4rò$¡—^B]X h×®+Ÿ]Øl¸[[)éî&‘L!™Hh´üþðºÏÝävS¶e •ûöQ¾c› «×ûK9û~ß¼ÏJÚÛñõöâ?pÃAhaÐÂéLY¤(óóÈGŽ ?þ8ÆûîCÈô^‹Šðtvâß·¥ÙYf.\ȳ.¯ø²¶iEu¸Ã?’cÜÌ™¤Y½ËE2‘$X ÓœGŠòü¦MíXvê L.ÞÍ›­VA`adsy9— 9aø7´TÓŒNÍî÷SÚÙ©]¶l¡¨¦½Ã¡1yÂ/DûÌ' ¬œ!!’;Ø«j†ÚRUtàE-(]TíÀNRÀ\Æ:ȵ&‹é<‡Q–q‘ ®‰ j#!½¬"]©¿HQeM ²4'Hç¥ 9K´ª€>æ(˜R:$9–JL,€U…Юnq)°?¯MÎ]ã4R5»·e.Ê–íïå@Š”V„<Ç•š¨:7Ž$ËWÎqQóµ3`‹S26OYãì*ó¤¾+VË&þéKš½;£³)°V³:†Š%¬D‹ðÚš¯ºÏÓø >ëo&gËjžMöçKQ•×ÏO üf¥pÅÑÉ墴« _o/5wßÍüéÓ =ö3¯¼‚»­ ûU¢$ò% ¶òrʶoÇ·s'ÇÿáüéO±–•áik»¦g]½½¨ÀáÏ~€òîîÀåýxVꨮ¦á¾û(noG0)òû1;¤S© çu°S&ß~›Ó<ÀàÃsöK_búØ1ªî¸c]I$ì••ÔÜy'¶º:æXèëcåôi¢/Rºw¯VÕ~«£ºšº{îÁXVÆÄéÓÄc1Ré4ѱ1VÞx½Å‚}Û¶«&×Z}>*n¹GK 3.^X 5=Íü±cÄGmíUE²‚(b)-Å^Q³®ƒÝ~Ý2eJ:“ŠDPS©u¢ v;æ’Š·nÅÕÞ®Ý&'‰gÊ"e@^\D#ý裘?ö1Pƒ!ç°«ºõVlõõÌ ZZ"¥ªZ$Hæ@˜;À…CX?þ„ÌóD}Q޶6ŠÚÚ,VVf爯„IË2¢ÙBztsg'†5‘ê’Á@ÙÖ­èìv¦NŸÆ³mžîn<]]xš›IÆãˆz}nä'»]Jëõ¿¸Ïh:/} .¾5[µææü•ˆ³ò×ÿ‹Ê 1Ì)«=Jª¬å¡„4RvD’oÉMIýBýLpøÈZÿ“ 9§‘¢Ä–aáì*{¥Okì‹ ¯ÉqQ4F&aª`% ¢D¨²ºš¯òøÍ IDAT ›D’,bPtXÓzt•4üÅ·ÀSÅä»ï‘N¦P” û²w3:ýZan ²V÷’í0J‚y!ÎÎî·.s‰9¡®vQ’"•§&2—œ@wM @vTdžQ£¬nör‘rÀˆª‚ŒDåÐÅÀ3dÁËZÝ É¤L2â£ÒÔ’®`Ÿ+Ñ(?ø>Ì·ïþ’.ïÿÉd؈Âêÿ7WŒ¨¼¸Í+":ñÊìGQUշߎ"L¾ñzˆÉwߥúÖ[× Õ-ÚÁY_Oíí·³4<̉øfOœ lëVLWç¯ýžð47ãïé¡ïá‡~î9\˜=žÿ¥ÏÒ àò‹/‚€d4RÒÑAÃý÷cÎŒ$œuu×mŒþ5ÿ·»›x,F2aùÌúô#D“ WcãU†YÁ²wÛ6ü7ݤ‰g'' ;Fÿßþ-’^»»ûŠ‰Ã‚  7›ñ÷öâß³‡¥ùyÇÇI¦R¤ÒiÂètâØ¶íÊàGЙLÚxÂ``yvse%ÞövR‹‹LŸ9ƒ­²“ÃqÕ³lADñºŸ‹çÏsé¹çxóÿ˜KO=…µ®N+_íË-cU·×ÖâÙ¶ sE —. ‡I¤R«ã£¥%û·¨§Oc¸é&„ŒxZo±àݶ ß¾}¬,.œž^>Yç‘é•RgNbÿèo2•ÖŒöÄZU…",O áêèÀ¾múªªË€¤(IxZ[Ùôñãhl¤¨¹wG®övŠª«7lUÿ…€Ä3¯‘þËßB:ù<8е„{5Ä+õÍ¿gìÈA"j²€qÉ.Šœy*„4: š$5ÆEDP§W ¶W2–Ùñ‘’„åY˜êWsÉʪ sõ™Z1SÈ(Ê ¢¬ ¯íD¿m©Xšd`%–Ê0fª Ѻ>{öÙ$&Oæ‰T}öŸ¨¹ãN†/±<=K2–À¼SãrY¶P(@Î1.IC0É®î£9÷v½*ÊͲ/3óe¸G±'™¨ÿÂÆèU§‘\ +IjçF)«ÒMOD.Ç&Û˜­‹§(ÑÞ«™÷«„Œ>ër"ãbB%•^yß×þ/°: v+JZ&tþpïÎÇÆ˜~ùe¿÷=Ê÷îE2™6,6{<4Þwöª*†Ÿ{Ž#Ÿÿ<57߬üuFãÙ [y9M÷ÝÇÒÈGþò/©Ú³GËN2ÿë‚ùn—_ò²”–¢·Z¯[Т¤R„§¦X%88ˆ¡¨hC”nñx¨¿ûnê×Kðüy¾ÿ}ÔD£×»¡ÂÝZVFý½÷‚ÉÄòô4‘@€¹W^A§Ó‘˜›ÃÑÞ~ÕmíÔßs)UeenŽ•@˜?tÕJ|~ž¢«”'ZKKñõöb*+ÃÙÚŠµ¶ßÞ½Ú˜O’~åÛ²-¥¥¸ZZHË2ÓGrâ«_%µ´„£±qÝ̃ë³gK ‰d’P @<!­ª«ºÍÁAGXZÒœGkõz©ºùf ^/ cc¬ÌÍŽÎNôŠ‚PTDhq³ÇsÙsÖØ+*°ù|Úxïß)ÆGý¾6®9õ<¼ó#¨j_ òä$³_ÿóg‰J Ia•qÉŽŠ”¼‘ä§ÑÊ9æ% \ÒóqR“áB¶F]M!Ó ¦‚ópé¢ÊZ­­ª²ª}ɸ‹DYE7>í7?±½ 5¥\\FÎU%à43þÇ=œ¿§™d‘ Ú‰®ínleeTíÛ¾ÈÁâØ8æÍ%H:µ`¼#°æç,‹$¬ºÔ¤€n9ÍM[_/)ù¢Üìõc¯˜I±œÞå· Æiùú–\[ttá4uÓ#”UÌæÊ«|­¢åÃØÃ è‚É€Z$Tq=òJÉÅ„³/"˜¬„ϼ͛ÿç_0wèPî1Ž}ü×$y¤¬.¹Û«ã£7—ÚßyžÖ¦ Ä«9Z¢šü{ö Z­ΞåÂw¿K,ÀÕЀiƒÏ¸ ŠÚ˜xçNYæÍ/|àð0Κš u3Ùíý½½4Ü{/¾>PÕu‹`o—ë_\d™øÒýO<Á;_þ2³Ç¦â*º‘µ4¥§³“’ Óqþ˜?q‚d4JÙ*uQ¯Ç»mîövÒÀâØÓ/¼@ॗ0•”à^§.A2©Ü»Gs3² °8>N"gé­·HŒŒ`­­ÅZ[{Õ—§­ OWf¯ke%&ãÏ‘*ù~[©hTõšl‰¢^OÉæÍwv"¨*Ã<Ââ©S„––6tˆ:¶šœmmè‹‹‰,/kÚ—ôjlº¯ô3Ï .,`úÀVA„ÅBÙöí8š›Iª* —.‘ˆÇsÉ·éÀ"w1Ž[ ]r"A|i‰³?ú–Š &Þ{wWÎŽìmm¢H$ÂRVö¾ ïSÂ+„¾øg˜Îô­ºp’iè V&Y:ü £ÏÿŒðâ"1¤ÄU݈š>®0>rÚ%g‡ŽÏ&‰LÄ ¶ÍŠ}³H‡ù¼”×tMa뵨¨èÒ*’¬‰s¥´‚ù3ÿ–žÝ˜|>$“™t$N2°„O#ºÌÄ~³QU™)7v˜ 8ôTPƒ±¨ˆŠÝ{X œC5,#JW°?seÝK>p‘B27oy5ñ¯¬0«—w†w0¬#¬ÚI«z*å‰}K¾«ˆ4èWÒÔÎŽâ-›]Õø¨¬n“0ŠND´¤±ôsã»l‚“zAÖª b’àjìMßËÐw˜ÀÔ"³ rîuîû佈’’Ѷ(9Àvã"hIZþçÿŽëÌ;$†‡qöô\õýgt:©¸é&¬••„&&~üqVΟ'‘HPÒÙ¹!€·z½ÔÞv’Å¥Ç}áÜMM×ä’4Øl¸›š°––þ«¿So—kýƒ‘$ar:±ù|(é4§x€É×^cidD;[-/ßø`æ÷S²möº:&_}•±'Ÿ$:5…­¾~ãôÙšÊvîÄäó1}æ ‘¹9#pø0¦²2lWIΊÃÌó„ìõõxººd™Å±1tvûUKÂQDoµ¾/ ž5wæ #2ðÈ#Ìž8Aqk+úŒPvÝ}VQwÇ,~?—^|‘KÏ‹¢fšzUs© ðLšàx¢À™¤(…`HI&æV..9û¸¢%£€TdEøO klÅ\Q¥¦½TÔrˆå?ÛŒT©Ï`拦'%ËøÓ•‡†X}”e$QÞÐE´V€¬&„ܶùÅU+t^Zn>3ñÖ¥n†t \ëñ§¦ðÉÓÖè,(" º™êù1Ê=3{•±£¯*+ŠÁöÁ…‚¾¦ì… ˜”…xÜ@삈¥eõu—TJÜ2e>XˆÀR&>y'’¤¡ OÍÂA˘Dè8üâÁŸ:v Á€«·wÝñ«©‰òÞ^ŒÃÏ>ËÄ‹/™ÚVèë‡D>«¢®Ñ»(…ÌI˜i0¥Ä´ŠN1ˆ„WR—Ÿìýâ`H 8|9} ÁÉi­[i pQ•LC·d@ô—#Þõ!(¯@40xÌèOŠ`·SÜÚºîçF”$¬^/{÷ÒpÏ=(² ²¬iW®eñ‹Z7€ËÐ>x·ÿæo¸ðøã¸6ôègmÛ›>ö1UeáìYÎ|ûÛÌ9ƒ§£ëURoóQºÑé¤ê¶Û(ª«cyp³_ü"Áñq\MMWÔ!ä³f‡†_û5«•¹¡!bÁ ýßü&UwßM:™¼¢Ê]”$ 6Õ7ßLíw`«©ÁÑÒ‚)«=º‹'Ói’ËË$C¡ ¿ D[Y]¿û»DX8wŽþdq`{UÕ†N7Q§ÃèrQ}÷ÝX+*X:wޝ}p €µªjÝ}žuÿ”ìÜIQSiA`y~žX,FRQ_¼HäâE¼¿þë—]‹gCñh”™þ~ì 8ººp´µQÛm, £fuþsÍ‚A’þ홲xÆ/ÁÞ‡J2I|nŽÈÈ0S_þ éD’t&¯FQ4ð"¦3üiÐ `ÐAU-LÎiOj£%1É09@“‰ò·D@'ËHi•¹ ™ÅEù2°£dÆú8èÃà¸ó7Ùüµï!ØlÌô.‘VÉÕ%¨™zÑ‚±¾ñð«pÏý`6k8V+æêjLå̧bÐ¥VCò2Ìjš”c®!ŽmnI’1ÇbkÊZ‡ÑåzâéÏl€Þ-LÏÍ‹ÿ—PøÙÔV’ ˆ*iQO\4óºn]ñÓ  Øåp.‘W )T.Mà3O­ “×XÃEE!%‹¤R؇æsÕÙ%3çÌ& +i1Ê /ê0O‡s£%%S¡—À»·”íÛò4.y㯼ÛR8EARñ4.3ó¿ÝŒåÐ)‚Š26Åô~„sËP y!‹k¿×uulúß!•N3ùúë ÿû¨é4¶šš Çä’Á€¡¨ˆ’öv¬ee¿tÐr¸ü^Ù‚,Ki)³Çsì¯þ GUˆ"–«¼ÁsÛšÍÔ8€»­h ÀØË/ÓŸa_ v;Æ+Dî¼éŒF<]]”lÛF"gò¹çxôQœuuèŽõÜôz\X+* ¡Š"Á÷Þcqhˆ¢º:D½þêçÒõ¾xøaúücäPˆÔò2¶5¶ß+½æ5àlh 43ÃÄ«¯rö? ´½Sqñ†ã#É` ¤«‹Òînñ8—ž|’s=DIs3Fg}W‚(b«©Á½y3ÆÒR"++¹ÜKe%®žôW±V·¶ÒôáƒÉ„»« k]æêjœÍÍëÝ¥ ú½ßFܶÁ[†ªª$C!¢³³Ì¿û.}ÿøœúìgI¬¬huÚ‰x®¶@”W¯³‡Imõ`µÀô<Ä\^“ ¦Ñª™asTD’$²D‹!Ép UQ 53™Q‘>†mûÑõîÇßÛKÉ–-,ÍÌšäF}EøR$ «½©» aÏ­$“)b¡ÉIfÞy‡±W^FW7¨5(g %§É^›<ÌmòâœYƺÍ‹õ_˸¨N#mT$¯è([™¦{ÿqt‚œ×­æZ¡%Aáµé},§œ¹\!ÃT¤E=‡˜ ’ÆÔ yRbDÅ¿<‰_?™>§–Pª’E’ )lCUТ^g/‹ºbNé:q½3q:rÙxOUàÁßû$i½AÓ¸äýY=Ëj ]žÎEAT)÷Í`v$™øý; lmÂôö Òü 3=ÄÂ3ÏàܾsUÕºŸSßîÝ8››IÆb\|â F^|‘Ò +þ~Z7€Ë¯ÐJE£„ÆÇQÒékF½Îúz|==HF#Ç¿ò¦ŽÅÝÒrM)‡î†|==XËË{ùe.>õÁ¡!\פ·–—S¾{7öÚZ‚gÎÐÿ½ï±4Þ;°ÕÔ°Ò×ÇàHpl «ßÍç[w[Ñ`@ÑéH¥R,Ž£J’IæFF°UV^IÅ­­X}>ô¢ÑøþËÊQUæþâÏH=û4BßÄÑ‹M-ÌôpîÁéüqfß{d2I"×ÀŠZ(~UÐ~ÓÚ8FÈš¸ìx¹4©—9„ò·U„˜¢`JHn'†[? µÝ$—‰ÎΣ(jè ƒ>ú¨qiK7R©Gu5Õ X­Ì<Œ¯t‘èv`])Áb¯EIAÿÛï0òâ‹\xôQ†žzŠ…¾³TÞ)£“ä5}@Z©¡^½Èr…“”U>‘ÂŽ]<·6î? \ÒK:JC³tôžÒlE9—¢›ì_èæ­ÅŠ©¸ä ÌK%Ì eLSN}lC4…oeš aâŠtÙ €¤,’X1 ,®Šs׌‰T¢‘oîýcµÜKÅÑóxÎ_.´V`hk;ŠC‡(*y–îÕq‘p™@7s‘Tüe“XÍDâÕ%¬´V²Ø\…ùäÊÌ<Ëo½Ebj “׋ñ*L©(I¸[ZðïÛ‡­¾žX ÀÐÁƒ8(z—ÀåWi©*áéiÎ|ÿûL;FI{û55tšœNü»vᬫcúí·xä–GGñ÷ôl¨7»ÝøvîÄÕØÈòø8#Ï>ËìñãÈé4Þ­[7<Àè-ŠÛÛqwt…yòI¦%•JQ¶NÊ¢Ñn§´³“â¶6Š;:p57ST[û+oY-±·¸¹™’Í› Ž1sâóï¼ÃÌË/ãíéÁ°AC¹¥¤„òíÛ)éìdqpá§ŸfîwÐY,¸[ZÖ×;‘ •ê줸³“Èü<Ã?ù óGb,)Á™)X\¹™íëcêÔ)luu”twcñù´¶i£UQ6dìÞw;YæÂÿWÿùÚ±jbõèH§O¢ÿØ'……L¥¥x{{qwt¢"š'­(9ÆEÍca5¬gñqÙÀ冡Å"R±ÄꙺZh•ÎêPLQ°$uå^Œwü®;>Š©ÔK2%X"ŽåKלEÂÈ$Æ}ûÑ·mÒöµÍFéæÍ”õôâlhBºCžt „ëW°¸xùÿû{–†‡I¬¬`r»ñt´QÒvIÌ/5$—$›¯{P‘M:–*œ„ÊŠð\ZÀK^±»(_ «&DÒA=%¡9š¶œƒl‚”Ήt%Aá…‰;9mQ¸ ´ »='•Ò¯kfZ(g÷âQ<áy|òRPY1ë’”%b’„‹#̦ 'szbz _¿ïÿ&Rä`´¥…ÊŸÅ>¸ ¸ŒïiEvé‘D¥˜ä sXM×UfÄ2ª\—Ћ)$µ¥÷nb±£×^'1?ÏâoPzóÍmÚ´ág¼tófÊ{z°ù|L½õ»}C3Æ àrcýÜK”$L.Å­­Œ¼ðoüùŸ³õÿðšfý¢$áll¤îŽ;HF£œ}àúŸx‚®ßû½ ·D‘â–jn½Ñ`àâ³Ï2ñÚk ¿ôŸøÄÆÛ 6ŸÁdböÜ9‚ýý„GG œ?Oíëw{ v;’ÉtÕtÛ÷û’“I–††=xóÿò/L¼û.U7Ý´îë&êõ¸©:pÑj¥ÿ'?aéüyÆŸ|’Mÿå¿h¯Ãzsi½wS•û÷£dêµ×¸ðä“lþÌg®iŸÛü~|{÷b¯ªbü¥—yâ _}•ö}ìŠÛ‹’¤ ­7m¢ñþûI¦Ó”nߎ{ËJwìÀRV†Ánߨ–7Úg‹gÏ2öÔSœþâ™z䄤&~ÍelÓ‹ÏáI%¨ýÛ/Q¾};7ÝDÍ=÷àlk#•J±<5M<Ë1.rxQ3 ËRz¼Xlàú³ï²tqŒ•ñ©Ëª²iÃR L°Èt5•;ï@ߨ½±{c‚¤#: ¶¸ IUc\ÐcóU`ýЯ#5h=OŠ,“XZ"±¼L|y]ïyAÖ„©ö±âK•:‹?àrQ¹÷&ªo½½þ œžKH‚\ÐÂ,¬IªÕ ¹„Ù”Õ€ÿÂæ•XÖ%ÓŸŸãI-éñ„æ©í8ŸÓ˜ªŠN’Ñ‹i$N,måb²U®È¶âªØU@eV_Æ”äç¶éƒ¸SHŠ‚>#Ì]ÍrÑÀKR‰‰:Ä`Fâ9}K°dY—”dàõ[ïED!\êæÌ]{yýc÷³çkŒ”ænmB-ÖiÀEXMÎ%TD>£}ÔDQeNðÒ^z“”È%K(DÊ™øè~‚u>нÇÌÑ£T}à˜Üî ?çF‡ƒâ–J6mÂZVö¾)…½\ÞïgsŠ¢}q¬¬ ˆ¢Vз1ÚíÔßy'®†~ò‘™Ÿ§¸¥ƒÅ²îUE v;Uû÷ãßµ‹‘çŸçgŸûá™ʶmÓR¯–+Šjn½ß®]ÌŸ?ÏÌÑ£œúæ7‘Ìf\ë²?‚(âʈ%»g}=ÞÎNÂ33ˆF‡ãWpš=äTоGeøá‡9ýOÿ„˜‰Û^O?br:©¹å*o¾™ÅñqfÏãÄŸÿ9s¯¿Nå]w­;22âÖú»î¢|çN.°pü8§ÿùŸ1•”`÷û×Õ¾dGΖJvì`âØ1採ïÁ1{½UU]1)Yg6c..¦b÷nœ‹‹5à©×¿ÿ@‹,“ºp!FÈKÔÍÏsê;ßaà‰'˜|õUÒ±XN¯’MþM« ,.À™“˜‚‹ØwïÅ\Y…Þá ¨¡ÒÞ^Œåå¬Ì/.‘L¦Hg¶Og·W4HIEIªPüÙ¿¢ö7EX›$¾FN«¹$]E1 ¦0X0al¬uÊÝ>¬UUoÛ†¹ªUˆÍQeŒF¬ÍÍ08HØéäÒ‰ >õý?ÎÀOÊÅgž¡âvIȯPI™Â,l9‰{_ -Û>CIKÑ“ÿ‚Ó>¦±ªR0.Ê–Ü%ó7’ª (*UgDZ„bìL~bn.97.êpD‚T4ök€!sAÖØ½”æx¤›¡t#ˆÚ>?¼-›—’ËIUaÂRIP´póØ“™ ½¢h)¸J6=X%‘‰¦DÔñ8êp|•iÉ u3—”¤çÝ{nË„ÒɤfBenŽ}èNê^|%-  ÅY¹§±D̸ŠV褬vG(êJ‚‚ ª¨’@Tga«÷=ÌRLkÏ“u‚LÚcg©·…ljôÜÛœýÊ?pö¡‡hüàsiïë~Î3z7FE7Ö5-%™äÒ+¯pæ»ßeîôiDIÒØ‰k˜ñ»êëiºÿ~.<ú(“o¾™+7?öÊJ6}üã$––úÉO˜?{CQ6¿ÃQ‚³¶–¶~”ÐÌ Ë##ô=ø ‰åe,%%XËË×}î&—‹Ê›n¢¨ºZGlò¾ß©T˜m´l>-ùˆVxþ<ý?ø±@{Uæ’’uïÃQ]Mý=÷DX™eîäIBCCèôz,eeŠ’] Ôßs±Pˆàà ç¾÷=B““Z¯ˆÛ½nò³d0hÑé4Éh“ÓIxj ½Í¦¥elË×Óè'Y~úiæ@9u co/b&wÈ`³Q¹g–òrdQ$ YZZÕ«ä1(  œ> ÿò5$«q{Hz»W[®öv–'§ˆG¢ÈŠZÀ¼d۳ŔvKgáþôŸRÞÛ‹£¾‘ÈìáÉäĪÝY—ÐZ™­F;¦Öf„ 4î«æÂÒY­Øëê0—•a*-%‰H&)jkþiSccœ~â fŽgitTÔwtPÜ6«è³ ²Ùk &‘’VPÞþ)ûôe=@âÚBU-`aP ²os(v¹ZÍèjŒKzI-²LyÍÀeÂØìüíx|;Õ…Lö «ù'YkP7×ÏÞ¡çQIç-QQÑ)jŽ)JÈ+I=©).ÅQSj¶%«c‘õzÎ|hŸ–5“WO)qñÊþ(óååT9 ܈%R¤ä¬5i¹bAñ",IN¢‚…eog9÷X«Öp…ðŽF’!% Í.\@g6St…jŒ÷óº\Þïgã™7U–éüqÎ?ü0ÉR3Lï IDAT•*÷칦Áf£jÿ~”D‚¾GaöäIªöí»¦7©¨ÓQ±gî–¦ß|“³ßûñ…ü»wo^D½žÚÛoÇQWG2fð©§œ;‡d0PÚѱás7¹\èL¦ëV¯¢* ‘™&aòða&^z ß5ì3Q§ÃßÛ‹£±‘T$Âè³Ï2sì±@ÿM7­»­Þb¡þ®»°VTF>xá‡&µ²BÅí·oÈf¬Vê+ϧÙåŸy†ùS§X§úæ›×ÝVg2áïí¥|çNŠ7mÒ’‹««sA~×Ã~Œ/-±2:Êü‰Œ=û,ã<Âô¾é4éáa”¡!ÔÑQ ]]™ÑdqK ø¶ÚZâÉ$3.¬&¿«¹UòÚËk03…ÐÞ‰h0`«®ÆÙÚŠÞ]Lt1H4þäoŸÓ¾¤!éñPôÛ„d4ânk£të6TU$41ClqI1%Á°9=˜š‘ª*A5@iÉhŒðÌ +ccGG™½p©ãÇ1WVâhoÇÚÔDICÑD{]Õ7ßLý]wQ\FÎ#d˜AAV \7aaˆ9ñ5D9Œwq&¯;)¼hã)?z? FdŠóX"±Ë]EùÀ…̨(hÀ QZ6´ª/É2¼§t3*Öe4.¬Ñ·pÁ.¨‚@Ýä8;û£H‘UWæÿ”d­ß(!K„Rz c²ˆÔr%‘.tÉÐïn¶W]V"™½žjo è-ezS=MÂfq΋øÏ>ÏÕŒšüQ‘J 3) ì*“ÏënRó:œ2àeW3w5ÞAóö½TíÛGQe¥V"zÕÒÜ.×ÃN2ð´¶R¾};j:ÍÛ_ú+ccM¿A=yö RÒѳ¦†@_}?Œ¨Óánlܼd´¾žDŽã_ý*Áwsó†aOK ¾;ñttä[†õ¹áðõ;ãSQÒiæOâ/™ÁG!tñ"ÑÅE¼ëÔ€–wãjhÐR-ÝnÆ^z‰±ƒ‰ÏÏcöz7Èg^sÉngáâE&^y…•"/R¶gÏú©<(ß±Ñdbì•Wyþy¢³³XËÊÖu&üuÖ×kI¶%%l¶ë|*é4¡ñqŽÿýßsáG?béØ1”T*DRCC¤FÆòá¼fÅ--”õô s¹˜¿x‘ÈÊÊe %'Â=úâ[G=ÄÎÍ].­­ZÞ¢jÚ—H4'Ø•ÕÕâÉd2EÊjºUKF5—–âí®žðÔ,¡ÉY¤˜ŒÇãÃPäÄÚÜ„¾¡„4ã#ó\úÙFž{NÿpÑ'âÙFrVäl_PvTÓgÝ„¹FÓ¸ä‰p1¯ï'Ï£ v¡aj­§^ ªÆ òrò3s¤”J(¥'”\Á±yö¦.Q‡Ž“ † ­eæ,|ª]±z€ÈþoùcÜRÉ)Gµ±Ñ«ŒŒ”œ.GTⲉ¤lঊ×ó€Ë*Ë"PøØ½lÁ.]·ß¯7€Ëõ¶ÃŒFŠ*+iùÈGH†Ã¼ýÅ/réµ×(éèØ°u´F\W]µ·ßÎŃ9þµ¯áÈ$¨n`$ƒ[y9÷ßO*ãݯ~•¡§Ÿ¦¬»{ãÔ\QDo± 7›‘ †ë´¤ÂafÞz‹ÑC‡r¬ÊzÂáìþÚüû¿O"gæäIFŸzŠÓßøžÎNuu¦RÚý~š?üaTމŸýŒ‘'ž`þìY\MMëîóüÇN+ S§N1ú쳜úë¿ÆÙÔ„µ¢b]ÖKg2QTQÁæ?øjo¿[y9v¿Ѩ õ®&EN$H®¬8s†K¯¼ÂÅgžÁdµrþ¶ÛðüÆo ­/‹:æâbü½½´ýÎïàîìdqjŠ¥ùy’é´VW ªÈÓÓ$!ñ×ÎëEßÑ’„d0਩aÓ'?‰ät2qú4ÑHDKžUWÁ‡¬‚¢ÌL£<ø= Ÿú=›MK—v¹(Ù¹GkÉdŠàø„ƲȚöEU@*¯Ây×½Hf3ª,#'“¤ãqÒ±+ãL?ÎL?ÎŽNœèË+=^,•$ÑQ½o5·ÝFÝwRwÇTÝr î¦&LÅňF#ˆâeû7~äAÔå©LCtFœ+gn+hé²™ÛB&iQ è+Æ4Á²Á ¤5±nFë²V¸«¤á¢6šG†0ª©†¸Fï¢d€‹HbÕå„°9qlZ»pu2m¯Ê„µi\A¤@›»dÀ ‚@ÕÒ85S'Ç¢Lk#»¼Ôa9Ó¬OJDãIÊîÿmÜ{ï@çr¡³Ù‰Ôb9’ öŸл³@BÎ]‹yÞÙß Dt6úm-”§fð'&sÏUòD»Y@")$R&Riû+_Å¢‹!å‰s¥Œ 8{[‡Ìz±rýæ]Ý.×çé<›ÚÛnÃÓÚÊÄ‘#üìóŸÇ·c¢^¿±'s6_÷Ý‚À›ó7ívôfócó×.½ÕJÍ­·R¾};8w.7JâW*íè b×..<Èì©SXKK±x<×4>rTWSµ?®†DIºîÜ#ÿÚPQe%å==èìvBÃÃô}ç;„¦§±ù|¦Ç:ëê¨Ø³½ÃÁÜ… ô}ûÛL9‚gÓ&Š6Ð+ ¢HQu5¾]»Ð9„'&8÷­ošœÄêõ®Ë-ˆ"®úzªo¹SI ‘`ðØÁD“ »Ï·aìÿõ¸,E••$B!Òñ8ËSS$âq 69IàÁIOMáܳé àOÌ%%x·oÇV[K,aáÒ%Ò²\Ðvxætv;èò´_E••ÔÜ~;˜ÍÌŽ^Z*-*R!úòKx>û'—F£Ë…«­ {}èõÄ¢Á%¬UÕèÜnFNœ ï±Ç˜8r„Àùó$VV0{½øwïÆÓMoÝŠ£½£ß`±ƒÙŠdµ¢·X~.Ö3uâ0é7Cˆ-]¬ä„L–Jv|¤(`\D¿˽`¢ªÙt¥œ½9ÁŸY\¶QÖ?†ÖÐ$d€NpÉŽŠ (aQž\)«Àe¬ªƒ†nSfT”e…­¢zEq.‚€ÙÃé]bj÷fRªÄ’׋ûÌЪnI……4c;µ@2%àºå^¬­]Ú‰Dy9zÓI¤1J¼+‚* Z²¯(çL¾kJZ\$ºÂ§ñ'§VAV~ì?ä£DÂH2iàæÊÃXõÑËÜDk¯›¸7FE7Ö¿ã2¹ÝTïßÕëeâ7èâ ¡Ð5'çZ<ªöíÃ`µ"êtZ ÛÏ1 0:×µHN$˜?}9‘¸fëµÑáÀ·k®–ÂSS <òÓ§FÜMMëZÎÍn7¾žÜ­­D™~óMï¾KppWKˆÏÁètjîŽV&'zì1ï½’„«±qÝL“Ó‰¯§‡Ò-[¨ºåŠ[[qÖÕiº£ë¨ÇI‘eúûI†Ã²„:“I Û½ÏæÍÄâqæsÀ#rö,‰¡!â'Nàºí¶+߇ł³¹™’mÛ%‰ÅK—ˆ…BäeÑ:tˆô±cèkjз´ä¶5Øí”mÛFqg'Ñh”¹ÁAÒ9ÖR@JUP%=Ž5âi9•"4=M<! œœ$™LâÞ¼GU‚ªYYÁ\ZJÙÖ­Ô8@ÝwR}àÞmÛp55a*)AÈŽþ•+ñƒ¿C9ý††–RÈ)äˆUU@5GLÔc_AH*9퉠ªû"dÙ…TRbqÙŠó¤•QÑ JŽ}QQ¢š«HY–P–(bô2qn¨ÜËL}q½)OÌš\X˶hc"E'¢/NáqP˜íí`|÷ÄÅ(®ã9÷ÒØ·ï‚°Œù­ŽÛ>€µ½KÜ’„ÎåÂà÷3Wy„ ¨™×JDɘ5 Kž( ::#gð%§rbb)/î_KÏÍ—˜‰dÂ@o鬺¨vÿ‚¼F¼ ’éeüân45Ò/w]zí5Â33]CÌ àòmz”q6TíÛGbi‰Ó<ÀÀOJç§>umÖgI¢¨ª KI‰–@û+,œ½ÒYµd21ù曼ö'‚«¾»ÏwM鱎º:|»vaóû{ñE&bà¹çèøÔ§6977ãëíÅàv3ðôÓÌ;ÆôáÃ4ý§ÿ´.øÈî/gm-e;w¢w¹}é%Æfèé§éøÝß]wŸ ‚€ÝïÇY[›kˆ¾îØA@Fâðg?‹§µuÃvscQžM›ðïÞÞãaðða2RÂýýDÞ}uq÷UÒšEIÂ\ZJiw7Öš'&NMåú†T@^Z"uä©ÇǸwo.÷E2p54àÛ½£ÏÇÀK/‘VÕœÛ()ˤ£Q*>ýéËöU*ãÂcqê? ¼°€»³×æÍ¸;;)íî¦bÿ~ü7ÝDõ”mÛ†«¾k&…X2~!'ÊËOÃÀIí`™RDEE¸,×…<ᮢDL&,}ÄXº ßE ŠÓe²©¤Äâ’cß ÈJîï”L9£NPÐe,ÁrD"¹d@^Ò£®$I‰Ë…£""U^͵$õÆ<.c£œ(7Ï&-ë%ôžåEÓ¹¿l20ÓÝÆÐ7aÃ6½žÅ‰ ¢á°&Úä•’ããØ>øA µµïcQåÝÝÔÜ{/³/²47G"&­Bx>@dzwF/–Õìvü==”ttðÿ³÷ÞQrd¶ïïœS§rUWêêÜê Vw+gɲ,ÉAÆ#ãCæ=f¸óæÝ5\Ìp‡7kâ;YîcÈ066Ø€mlcÙllK–lY’•c+të¤÷Ç©¨Ôâbj¯UKÝí>]åJg×þö··§£ƒ–k®¡yÍ|Ë–áÄÕÝ«­­¢|¾éÕ…üäGˆÇÞ0Ç5e#n…¨ÔŽÄÒÞwyÃÈÐAQÁ~ ‚U+ZJI¿åßµ ¡)"ѸýÐ ºbT’€u­ºŽ,:² AVD‰Éh1 -›!§¥ê ºhïo&º¤D\ĪÒRë¹T–‹a±ù tºGë|"†ÓJ¦³™S·m&ðâ!·µa±(í.ιNÒ,ö"cGKäˆ;ÆØÎèÂsäó U¼à>2‰D¹[©ÖƒRñ¢äÑVœ¸(1W¬ŒŒtÓœ›¶QÌZYl‹Q4“ƒ «¨šÕB½QWVÚ Û ,¿|,…¡ëšvu©>žŽfà•üGüýý8Ãaó½µA\¨ý4ïëíeÅÿ1¯¾ÊøîÝf„ûU¶Fÿ6@+ÈÇbHvûUîùúûYúÑrê'?áÈCánkÃæñÌ9FJŠÕ¢}A–™Úµ‹ƒ_ù ©ÉIƒƒØšš.KËêÉà]wQÈ牜<ÉÌŽÄÂQ>!]áúÝ­­ Þy'îŽBK–бaî¶6D««Çó[ý;üýýÄGG™=z”×ÿÇÿ`zï^š—/Çêõ^6(Q”$šº»™ÿîw£±±1²‰ª¦QÌåˆ>ý4¶PAÓ°]¢5[EsuzãF¼ƒƒÌž?op‹ETÌñÏìw¾CÇg>ƒpÁm$ w[ó·mCp8?p ,Z„¼ñï` qµ´`q8LEP–ñ÷÷ÓuÝu„—,¡©§kS“IRDñW#*†'^% îæ‹ÿû¾_ûB.gžðË'_½Ö¤[UXÐjÖ¤5Ðuƒ‚& ¿EÈj•­Ÿ I†¡ƒ¡ˆÄ²ãŠQÙàÑk”—²b#åô˜5fAÉfI2Õ¿WúâPˆäªî’âBe¸Öß"^°]„º,boÊÓm;oERS™_c•8öÁ[9ê¦'{·šÁ0TN»8X|žäCopüsæ§?ÅÕ>‹`•1´*áC3õjpŸÙlmŒZoÊ¢ÜaZÕ©‹“s©ÞfIÔÉ'í(™Aá²®TîS4 «EÅ"¨&qÑ5dM!ðŸE{æm‡ÿ*ž&J&Cvf†™ýûß±ƒB,’tå…AÀ ÑÔÛKjlŒó7ŒíÜIó’%8[Zþ·ž» âò[>é{Ç;°y½Œ¾ô’͆»½ýWbºo'S)gÏ’8sÆìRú%Z‡{o¾ÉfãÀ·¿ÍìÁƒ&ùðz¯j|Ô¾a¾ ($œß¾ñ—_&—LÒ±aÕ_ŒV+½7ߌ§»›l"Á™gŸåÀ7¾a®¸ŽÓ:Gp]óâÅ´¯_OSO¾þþ·-i1t%•";=]Q®Ùé¤ïïÀÝÕE&áÜsÏ1±c…xœæeË®èó’Nznº ßÐéxœéãÇ+£ŸèÓOûÞ÷p/\ˆ³Æ³rácæ¦uÝ:4A >9I:‘¨ÇÀM—ÈÜ‹ÃÅéDnjBÓuB«W^³†y×_h·#X,8››/ù{S þ‹ ~ñv8¿ ºV‚¯Þ`®?û<Ê“O –z}¤òˆH«ß$â2Átš.PÐAx#Yí¢F䊙Ö0OìɤƒÈ´=ž«ä¥Ôý[1Ù‹F¢D\xQC/¨Õ¿§¶$@z]7EÙZÓ¶læ´Ôå·Ôl!š£"›«HçKfZ­²‚\ëAQE™qk-¹i¼J Á00$÷8±“§pzƒ„š5IƒÒ¨¨n¬Vn›ÖMÿŠEÔL2R6ѦӢLÕµBב˜Ò:t>aGI[éÕ`ÑÕŠñÊ$0²¨b4l…"]Åþt!q!v Ô4øºA¾Â[]';3ÃÈöí¼ö/ÿ±ûïçà¿ÿ;™3g°‡Ã¸ÛÛ¯øZu†Bôßr —‹ñ;8ôÀ8|>Áà/Ýß .¿íê‹,Z¸öµk±8ؼÞßâbq8p·µ‘žœ$qæ Óû÷Z¸ðªU«ÐÂ…„—.ezÿ~N=õÙéiZË+¯sFÿüùtl܈Õçcôùç9ñðÃèÅ"¶@àê’o¯¹Éå";;ËôþýÄNœÀ V>½\ñE}]Tomæb;q‚#<ÀéÇ'qö,­«WÏyXpx˜öuëÀfcòµ×8ýØcä&&p´µá™ÃXN*].¢££•Þ!UQH½ø"ê¹sXìvì— ßs„ÄW­ÂÙÝM:7G@ŠÂÔÏ~†ºÌíw··ÓµižÞ^Z֮ŷp!¾áa| ˜Ï“߀á]û›»"QˆOÀÄ0s:–݃qö,™¯}•Ø©#äl  ¦š"iæ¥BPŒ‹W¢1LŒn@ÎÐ÷'Lâri1jZ”Ý ›¶1C3ÊéÙzÒBÍ×:Ø –”€•›Ã(ƒfbhÙBEÁÑWÈ]Û‰b±ÖøX¨Ù,2.Ú,2 «£HWñ¼i¨tSyŒ‹L´9ɽ˜g^úlµÂ `C¾¥Ûª‚³3Hé\éÿï‚ûË fÌ:’¤›£E£{v„@!‚$êX$ý¢QÐ-:…˜ %%Ó‘;¤©”“ ­üX¥m.«¦`´GK$/z áÔ“©óŒ’ÍÆk_ü"6Ìù)¾rB i]½Og'{î»é}ûèÚ¸qî¦TAÀæóѼl›7“‹D8òï0þÒKv;-+V\‘ø”“o»·lÁÕÞNÛêÕ8š›q…ÃæØé·xí\,v;6Ÿã?ÌѤ‹Ñ}ãsç …L?ÈòåL:ÄÙgžajçNr±st=Ùý~Úׯ§yÅ fÏ#rö,zI¹KíÚEjçN|ë×c»Œ Øâtâîì»|.G|tÙç#?=Íøž=X<¼—; MóæájmÅæ÷cq¹Ì­´ßÀcœúÊÿ‹å§Û‘òŠù)=6gwÁù°þ#aòË_"žMPK&äÑ4‹fTOÄå #͵˜‚ÛAA¢ÆÓB½ÊRÉv1Ý"aµ*t¥ÏW Ë[=’¨Uü(f£N{zœîÄù q S•*z‹¤ZìĺüÌBÍ ‡kHŸ„Ž¥¨‘Ö<““Ø´‚I^D½ª¾”n¯$éä#”¤LKrQSAªën•DaCŠC%ÿÃêã  ÌB˜Þ…râ%Îw…]»Pwì@öY÷ÜSÿž¸j6вf ññqf÷ï'²k‘]»è~÷»ç|Þy»»i_¿W[§ž|’“?N.¡ëºëÄ¥j‰›+ÆÛÙɱü€B"qÕ¨»ow7ón¸©={Øù÷_éä™3mØfÃÓÙIï-·`ˆ"'}”ó?û³GŽÐ¼t)ŽÒ§™Ëënk£eùrÂË—ãŸ?{ ð¶4Ó†¡i誊¡ªf7ÊNÌ»w{;ý·Ý†’ϳÿË_æôãã*mC]é>°Øíøûú¼ë.TUåÌ3Ï0ùâ‹ÄŽÇ?4„#¼,ñ+'ßοývp:Û¿ŸB> ä#Æ~ô#Úo¿Ûe‰ºs IDATT/Éf#04„Åã!>>N`ñbZV­2 ‹(’‹Åp_®!]~ã„4÷µCÞw©¼×]™“Â«ß ½ó‡ŒL“Éç*Ä¥œA£—Ö¢eE7ýµ‘ÿeE3ÐtÈ"ÙNìM˜'Ë ÈK%íVrшƒÈéDÇ¥6j ^úÔ{øùŸÞÊêo¿Žcx Mö)\ýýÈ>?j&Šü°•hÁG± ›'|É@..W,'æ by«È‚UR˜5U±T&YÙÌ)e±”U—öä]±óˆzMA‰Œ¨™¼ÏA¶ÙMàXQÕ+!*~!ª~¡ÒøHÖTt$ÂÓç‘ yów‹¤UÔIÔ‘,…;JŠæ<¢ª•(Á\™Ókˆ‹ BÞÕ W".µ…”v—BSèV˜‡ÂØ8Ê‘£ûöáx×»ÌçhÉ4îln&´x1ýÛ¶¡‹"§Ÿy†™Ý»I=JxýzÓŸu……Ùé$¼t)Û¶1±gGx€Ñ—^b`Û¶9—Dĥߎ`¶5kÛµ‹ä¹sH²|UiÁ`n£ôlÝJSo/;ÿîïЋE¬%%ëªÈOo/‚ÃAjt”©×^ãЃ2xç…á²c+YF”åÊÆÛqôSˆÅ˜|õU}ó›üÿÀîõ"{Éž/|¡ïq¹÷Åqiàwá%KЊEÆví";3ƒ¿¯ïª¥y_o/×]ǹçŸç¯} GÉ1?WêÝï§yÑ"ì¡þz·nEËçdùMÉ6x+ÆòVÔÌáÃŒ<ñû¿øE233f+ò¼yW>¼”ܵe ’ÝÎþ/™“?nšçÏŸóºóçÓÿÎw¢‰‘Ž~ûÛ¤'&°ù|4ÍQénogþ¶m$#âããäK×Ä®]xz{A¯èŸ?G8Œìr½¥²‘ gÎ0úÉÿ›øÏŸALÿša/¨UÅ š‚0o1‰ÉRܽQm».×T¼/%%¡¼Y¤EDQ »;uIKEIQÍ₦ëß$=1Mf&ЦhuæÜÙ¬!µyA‡\ÐÁžÍ~¢B‚.:q9ü¸úú[’$…W˜‰QŠR%Ý·4B”@”Œ:£®hMБbÑJsjG1W“lÔƒ³® <=CGd¼¢–ˆFýï•Ë$‹Ar¢ˆû\ªBT¨ó™#6t‡˜Ç%eqœ™FÌ)u£5C7#É¢#Iù)JLÆzv½úÀTÚAóxU€œŠAöѪzUûwʃ ¡!HÆ!:eþ¨øÊ+ˆªŠ03ƒ¼téEÏõ;ï$ŸÍ’œ˜`äG?BE”xßððœÏÉÖ+è½ùfb'OrðþûÉÇb’„¯¯¯A\h  WK -Ë–qþÅÉ'hùüœÆ×2Á =7Þˆh³qøÁ‰;†³¹çÄêvÓºr%Í‹Z¸æÅ‹Í°»ßØ}>ÚÖ®ÅÛÛK.‘àÄÃ3¹{7²Ë…§«kÎ<[S6à$zô(¾þu”tkS®ÖÖ9¯»cýz¼ýýäb1N?þ8/¿Œìráî꺢òc±Û ,X€ ˤggi yɲ‘’͆ÝïÇb³½mFxÅÙYNÿýß1þÈ÷ÌÞ¥Ð(Ëê‹V?> ·ƒ`«¦g¨‹¾/_0.ð¾è YC ¨ ùy¨É Zþâ1%â"( ltݲ…yw} MщžAÉå+G]Þ‰6ÔbžäK+Å3B„¸`\˜¦_êGtM1;ûSffýèºP!¦Qµ”–+–ÉKqW]—˜ÕC¸ri‰é¡n ¨âí)@x|†Žx‰¸PKVLL¥ƒ¦I\gÓ—4çŠeS³NK¯-…p"Yµâ-ª»Ï “À(S6´¸ŽÇLâRö¸hõ£"JÄÅP ²WIKEùºà:ÐÁÛ÷Tÿ\aÇŠO<ì÷c½ åÞêvÓ±aMó瓉Å8þàƒŒýä'¸ÚÚ^¡Ñ¾ö}µkÓ&üóçsäÁ9öÃ"‚iºo—¨~"-Z†Áù—_FËçͦì«Q_ÐÂ…„-bzÿ~ö~ùË´,[6çÖPùnõx®X ðv€®(LîÛ‡šÍ^ѯS‘†-‚Ãô®Yƒìõrú©§˜xé%Εÿæ*Kµ-kÖ Ùl¼ñ•¯0ú³ŸÑ¶víœäE²Ùh^¼˜¶µk‘½^NüøÇLîØÁè‹/Ò~Í5—=‰’„³¹™àð0]›7ãîî¦ãºëèÜ´ __Ÿ¹²ýëéR?÷爫×B_+Hœ8Á©ÿøNÞÿ™X¼.õ·œâ«—ÕÄÚ“Ÿ¡0Z!«”È ¨/å”[Ý$/¢f iC¤  ´oû ] 0›@MfªŠ‹^Ís0R º‘¦÷þÒì‰êìfjßrÑšŠ6¤…ÍOHYá˜e–3âñbœðé ’É׈Žhº€hè•ÿÑ2é@/‘É4¹ b•¸ävÚâ“´$¦«ÊIÙƒRó½¨é´ÎNѸ¤ÊR í+‘ϱ$®³™K—zõÅkKÑäHR<œAÏ\¼EmSõŒ’"ꡌ!j$1 dÎ5ræ¨(óø&éK)/( Øs¸J\TÌÊ eçNsÓnýú‹ˆ~phˆ¶õë].Nýô§ÌìØÁô‹/â ‡ñ\BA©…ìr^²„¶µkÉÎÎrê'?aÅÇ?Þ . 4pá‰Éàëí%qö,ï¿ßÜ<ºš¤aAÀÓ¾v-íëÖ9vŒÄ™3,øÝà}¢ˆ½©‰©ýû9ùÔS„—,¹ªulG0Hûºu´¬YÃäÞ½LîØÁ©þO_9I€#¤uÍÂ+Vpþ¿àÀW¾Âè/~ÁàÝwÏ©|8C!ÚÖ­£}ýzÆöìaü•W8ñØc8[Zh^´è²×mõxðtvX°Ow7ö@Ùé|Óbõß,Dþê/É|áó=€ôÚnÄmïaöðaNoßΩíÛ9õä“ÄÇÇQT­âU©ä•Õ¨/%õ¥Xò¾”Nj š[!ž™hÍTâBõE7½/ºfŽŠrºÈÐß|k(„äp¢¦sfâ芙íRö¸ X Eß­w}«ÇChñbzny'‘“g˜=qëʬá a©õ LYf9âÍ‘LËØ&2è%’P9‰ëFÍè¨ôµh JæEWEò³Úb“„ã3¯ŠX"e•ë3ÌñXëì$m‘ɪ"SV[¨A7IŒûXç™ì%Ë*ÅÒÜMСɑ$àŠ‘F÷Ƴå\l6Ü­­4/^ü;CZʪS¹‡§uåJÿà™·e †a̹2.Y­º÷^”b‘™8ô•¯0úÒKtnÚ„ìt^qm]’e|ýý Ýsª¢0òÔSþÖ·èÚ²Q–¯hx._÷ð=÷PÈfÉE£DŽ#5:JûÚµWL£e¹ÇÿVR¾rããäFG‰üàÒûß@‹Ç0@8vÏu›°†šÙÿï€ÍF˦Mt¿ó¸zzIÍDȧ³¨ª^5Ý– L9¥¶h ¡ô‘[Îg܌Ψš^1êªæÂJyÍLÎÍ"¡;>‚oåÜØZZ$™ÌÈ8Z^AWÌÆI¡`^,-}´¼ÿƒ¥Î`ñx°®PqßbEËK•‘MÙ0k~mž}‹ƒh8ˆ^KNAÎk¶žŒClYí(©)¢®‰Çl´F' 'f*&ZQ×ë®SÐÁ¢«´G&h¬˜s«ÄF¯zuYTðKb;™7Õ¬Òíj À‚fšu}®8Ao”™=ÅÔiÃ5#]kÜÀ–Ó‰¿¢¢çL³­ ÕljiBÅt­g ŒœÙi>>B‰,jýv—¡1{€Å½‚fµ2yò$ù\E×Ñ¥P@‰FÉÜ?Î5k°^ðÞWÞÒ[ðÞ÷RTU¦äà¿ý'¾úU–~ò“Wõž|)¶A\hà¼ãÔ|žÜììUo5”+‰mÛyî9â##XJþ«ysê}Ç;ð ‘3GGÏ=‡¦ªæjñu ’ÍF×æÍø™Ú»—=Ÿÿ<™©)ÂË–Í™lq8è¿õVzn¸Ðð0­+V˜fb›íª³~þ3¡d2d§§™}õUö~æ3úìgI8P7öц¯þ¸ÂÍ,»ïÑZê=j߸‘–k®ÁÝÛGf&B.ž ˜/TG>Ԁʣ#A-­&Ï"ß±„ÄLŒB6WµSõã#Q5Õ”Œ.2þê tÿÞa …pvwckoGr:Q’Y”X =« ( ½4ð÷Á0P²Y ñ8²ÝŽaÏ‘ÊT“{ËD¡V Ê¿™¶&"óÛpDÓØb¹j{uYu1ê7zÐÁȉ'LâÒŸ­n•̳¥Ç‹¡á-¤Æ£X Åꨈ“nI x"„NÏ êTŸŠòRÎÂÑÁiKãr¤˜ÚƒI\.ãÔ*0ö”=¯1û²ŽžÇ\…®ÙBŒjŽ‹–50ŠploU=´ê¥¶.€ˆ¢ Ïý]›6\¶ŒT4Êì™3¨šVçÿÍ<ôòúõ8.a˜·z<ôÜx#Þþ~RÑ(-k×Ò{y/—}Í7ˆK \²ÃÑ -¿,y)%+™ ‘ÇÉF"foÒUŒÝt]w:0³?Ç¿ÿ}Šñ8îîn\--sïŸ?Ÿ®-[PóyŽ|ï{DÇæ÷ã›csªG®ÖVlÏÛ‚´”‰K>åà7¿É©gž¡ÉTÈCi"Rõ±¼ô"R1G)ÐtÛ6ì~?öPï‚x,@G =%ŸJ£jfP\™¼”ó[„’÷ÅÐAeŠÞOý®Å눟#91uáÑÊž’"äuÁ¢ó÷M¿‚äraooÇÑÝì÷c¨:…h5•Ã";p„[уA’ñ8¯¾ÊÈ3Ïpìᇙ=µg·P·á#ÖmóP÷33E'ÕîÇš.`ŸM×o*/FND›”i‰NÓœ˜©œÊï—²k Õm¡)žÄ—ˆ_äq©ýÞ!åqÉiŒ£$jû*ÉÁTn›Ý–ÅjÏ0Y".µcœJ¨\‰$Z’`ÉÄö:QJUe©é”ˆ‹^€ÓñV³”ª1[TÍKù‡F‰¸¸þë§D_?mëÖ!úýDFFHÇãòRèêbê…èýÄ'.-ÎJ¡… i]»–…úЯdfo—hàM‡§½G(„^,òÚ—¾DïM7]Õqö@€Žk®!¸p!©ñqN=ö3¯¿Nfv–ί|° `÷ùhYµŠ–U«8÷ ÄNž¬dBü6Ââp˜Ûlíí¸{zˆœ?Obv¶bå¨5Ýj€±k'ÂΗ½^ÄUkÌ“€ÕŠ«« ßжPˆ|:Cjb UU«¾ê7 rðÜó :ßy'þá… E"§ÏR,ë”C7½ª* 6…hÿƒ?®]YÆãìéÁÞÞŽª(ÄÏžÃnÁÝÕEnt”£Û·sì‰'ˆ=J1ÆÙ,âîÐ+&ÖÊh¦’ŸRÚìÑ©!/HèM'g+¿K­é¶VqÉ‹“Z¢Ó„â³Õ­¢Úuè’¢#£à’²´LLÑOÔ‘•J]é{›XÀÙ‘…=À¥¿Ys1ªÛE²-‹ÅžeâõªâR§ºÔ˜šÅ$E]–RÑ“9Œ ã,í»—ÈŽš½½õ-±Ó§OWÉKé÷Ê&]dþO}ªúõûé¸öZ¼$fg™9}XüÅ/Ò~ûíx®øœu†B¿ò^ƒ¸4Ð@¿XÝn\--¸ÛÛ9úðÃÓé«R?,v;þùó™·u+’ÓÉÑïŸéW^!vâáá9;Md§Ó<þúëé,[:ƒÁ·Õ—®iÄOœàü3Ï0òÄè€÷ y7îövZV®¤ï¶ÛÃaF÷ï'ŸËÕ+&¥¯\㕈?ˆ48„0Ï Å³úýø-Â3]”ˆœ¥Í]<6ÂO×ÁÚÙ‡·«‹ÎM›qvt2¶w?Ùd²ªü”ΊbAGò…hûxý'òìÔÑ'˜ßU²ºÎÄ«¯ò“}ŒäȪ¢ðîï~—Þ›o¾úFYÃøôþ¼™Hœ9Ãáï~—“ßÿ>‰pŠ"QÄ\ð ÛeÖ¿ ]'rø0?þÀ(ž<‰-›Å ¸n\å­œ?ÞŽ4:»*÷W~v–3?Ìȃ’Ü»›’Ç!¸,à’À!a‡TЊçÇáÊu'FFx鳟eôé§°dSx.$ì--pݵôýå_;y’Ø©S•M¼äȆ¢¤cåJ:W­ÂÛÕ…ÔÔ„*ŠH^/²q†ÉÝE$D•-(6Ù¼XeT›ÕjA±Ê(öÒϬæï¨6 šUÂ6–"øÂ »„n“Ðìt›ùµn—ÐKC-ÚPO¹˜þ½S#¨6ÕnA±YPí–ÒuÉ( VO ŽwÏ8M£Q¬íØET«lÞÎÒíí*6G¾h`Ñ’y±Kè Í!¢9-6¡-…Ø™àà#¦âbq‚Å’d‡ù½äÑ Ö$XóÐùGOR<3EîÀò’;x-9‹`U’ ]„•§UQÂÐuÆwïæ…Ï|†äîÝ8s9<€HvtPœœ¤gófÖÿô§—}¾šfŽWC¯³†âÒ@ üú?!‰"¡… ‘l6νð™©)üs¥Þb®Uz:;™¿m† ‹Ç9ó³Ÿau»ñõôÌZWú#o»ûËîóÑyíµhšF>ŸGÕ4r©j±Èùûî#ùòËø7nÄz‰ÀDAp†Ã,ùÈG(( ѱ1Ò±X½é¶tÑuýï =þCÄk7!”©-.þ¥Kq÷ô`Xd2‘¹d ­X§•Ö—³ètþŸÿ Éé®\·=`þw€l%ŸÎ "j®€£­ÀòXAŽ¿ò '·ogâÕW™=rÑb¡yɺ·l1MÃëÖÑ4<Œ£§kK ¶`ÙåBKL‘|ùa U¨˜qkÓjë¿×kV“Íïm‘,ÎÑšN JëÇÕ\4!Ò´H82M(©7æÖl‰º]*à³'Îf0f • 7É0°f²neÛHÕò–] Žk¬C׌ºtÐå"ª\dboý¨èR&]=j:?þXÛ»‘ššÝnD— CÑÑb)Œ¼Š B! Z:ÿŸÏU¶ç¼,ùÈGHÅãÄ&&H—ÚѯòI"É$±éiº·m»dM†Pê/úM¾ÎÄ¥øÁÓ²|9§·o]GÉf¯ªÎÞæõÒ{ÓM´®\IûºuxÚÛÍð«·‘yº˜N“#vü83o¼A>ÃÙÜ|Yã² ´­]Kÿm·áF1 fNŸFSr££dAžÆÙßå'Q–ÍÓÁA2É$±‰ ŠÅb_¥â[‰'^Ý…´x b—Ù`-Z,¸º»ñ/Z„-ÜB>•!3¡X(VÖ‹H®k«­¾J&CvfÆôÞ„šÉÅb2\ýý—/ÇÝÛ‹h‚€oÁzn¼‘þw¾“Þ­[éܰ–+ `õù.jÉÖbãä^únµç§67¥f³¨v´SÁoŸÍb?«qªw¥<62ÇZ Ï@óì,ÁX¤ò·/ò¸`—óøqŠ#9Ôiµ’±¢ëf‚E/µ: Œœt.€4+ dó5þ™ªIWÒA• ²Âô+…„VOZŒú‹š- RS€ÀuïÆÒÜŒä÷#º\ˆ.—ùŸU0²EŒP¹dyþyMº·lÁâó1vèáé¿÷^|ओI¼óæ]U/[ƒ¸4Ð@¿•h[³†|,F!™D/¯š€x:;  áéì¼êz†· tU%yö,/ÿýßsè;ßaôg?clÇ‚ÃÃWKîøqÚî¼á›P¢ÅB`ÁÚÖ­ÃÖÚÊÈ+¯P,*¤¥vU›žByýuäå+‘::Lò$Iؼ4 ¡**é™Y²ñ$Šº ³û÷2øÉOW®ÓÐ4¢'O²ëŸþ‰ÓÏ>Krrgw7þ¥Kñ/_Žgx˜àÊ•´mØ@ǵ×Ò¶f Í Ò4oŽ@ÀÌß¹Ô§w½€qàŸ)îß_Í`)yDjý,¥º¡ª*R“­b‹æ°OÔùc¨5ð–î±ÖƒæÙ‚±hÍfPU)o09ä<wŒÌÉ"ùi½®©L6$Ãl•&o ¥,,D/"æŠJI}Ѫä«`QÉYTäž[ÈE ‘øe}.J”¤N¾NχþÑáÀ ƒHn7’ÃärSˆ%ñÝ}‰¢BæÔ)˜æEI¢©·—ðÊ• üÞïáííE²Zé¼îº· ii—hà?‚ àjiÁ b)¥Ïþ2ßB……Wýf+Ë8‚CC¨ù5Å̉è@öøq¢Ïc¾Æ,$¯kG‚ÓI>›Å¾aíÿ8Í·Ü Ÿþ4ÖÎNB ÖÝÍå η²šÙ . 4ÐÀDYþ¥IË[NIÑ4”L5ŸG’å+®zвŒ§£ƒy×_Ïâ|wGc;wrìë_gdûvúÞýnD«õ²C´Xðtu1ï–[ptu1}ò$™D‚Üè(É×^CDð.[fv']@î$YÆÛÕEßm·ÛÍèoP(Q £â[)³O=Eðö;/( $‰B:M6ưZIGc [ñ‘Ÿ˜àÜË/säÑG ÌŸ§³“¦žzn¼‘î-[h[·ŽÀж`мm‹ùÿx!Y)Æ1 ƒ.AL•ÂþfS• ÓÇR%,åÝ‹Óku$CÇ6›E:š¬¤ç–·Ðjr\JÄÅ9«š%Öm,Õ&ኆ,q8“Ìž0HMTWÀˤE×jVÃ3 DäåÛÛìvp8ÀjCPtÄtAÑ4ƒ”¨“u:Þÿg´Þp ¾á…ˆV;™±iŠñ4†fÖè*dÓσ ÛYøÇŸ©>f¢H6'26ÆØÈóæÞ¸[0ÈÐü¡… ß6™E âÒ@ 4ðf©G¢ÈÑü€O„Ø·Áf§»A”ÓY,ŠF¨hÐv÷DZ·uáîé!°|9ŽÖ6 ‘ù™(j¶M8æ¯&£*:Cþ£º´é‘çžcrß>’““ø†‡ÍRYÌÄé·#ii—h 7á%Kðvw³ÿ«_eäé§IŒŒ`óùp…Ãsn[x:;™·u+‚ÃÁÔž=üú×Ñ’I<½½sú jOLš™Á"O?ìr¡ÌÌà¾ä±M==tßx#š$'‹¡a泜yüǶl¡©§§þ„a³Ñ½y3¡%Khêë£eíZZׯǿx1M ÐÔß»­í’Û'sbl¼ö-8üU°y 8¾jp 1½ì·ÿ4IבjBàʤB¼ŒïÅliÖ‘e“Ag²5MÏT$‘²AÖRÐñD,±R"…¤×˜lkRvEtTkžéšâ’—r­˜°ÎXïúCÄÅ+MÅÅf»ÝüºÔ4Ž¢1›NÅ óÇ6çeïÀþE‹ÐŠ*ÙÑ)æ½ëvnzà{ˆV'gþ ]@”$¼Ý¦É:44D÷¦M lÛV!-ow4ˆK 4ÐÀ›G À¼ë¯ÇÞÔıGaä駉Ÿ;G÷æÍs+;´¬Z…oÁôb‘‘ýˆÈ¾}¤&&è˜#1Xv:i]·Ž¦ ( DGGQ fŸ{ŽÄ‹/âèèÀ³xñ%µº\t_=Š®“M&I'(XÂaã㤧¦0 oggêânk#¼t)Þyópuvbõxl¶_-u÷ðâ7LÕcôY˜y <0o»¾ý‹dŸ}É¿¥¸}C«[ƒ®|£N• kQA˜(À™\¥Ã§¶«¨»/ ¼Q=‘DOfÐJJÃ$MR„.jää"Ó'!9ée)©.µäEäاÁzç‘.EðxÀí6•—qì62v;ç²yÒ±$Ýý8¶–¶*Óu°ZÑ ƒ|:ƒ£¥Ž›n¢uí:ìÍ­¸Â-Øšš*Äå· âÒ@ 4ð&Áb·¤ãÚk)&¼ö¯ÿJüÌ‚ â®x¬Xj»n»öZ­­ä&~þsòSS4-Z„ý-¹•c% _o/m×^‹µ¹™±ýû)d2(©‘W^ÁÕÓƒ÷2Ê‹ ñΛGôìYlÍÍ´¬[Ghp‹ÃÕëEv¹°ØíuÄDÅ«3Õ^ Žî‚oþ¤£ÕxÞB ¦wÂØ“\Bá©çÈìÞn@A,8ê%2Q—¯RŽü¯švÌ­[¡ô3…Ê:tmÑaYu‘‹:M±"…d†\*gæÖ&u‹f*0ª ‘°hh Šél}$Ùßb˜ÄÅ9 ¶{>€Ø?V+‚ǃàõš^»]ȃØßó^"ûÑqçÝØÛªÄåüË/säá‡9óüóh¢ÈÚ¿ø l>Ÿ©ü-[Nóâſդɹ 4Ð@—…¡ëDOœ@Éd̽+g/„šÏ3¹gÏ~âä ®ûë¿føÞ{‘l¶9Õ â§NñŸþ)Ó»vau8Øtß}ôÞqÇœÇk…Ñ#Gxñ3Ÿaêç?G*±y½\ÿàƒtÜtÓeÍк¢PL§™zýuÀ×ׇ£¹ÑjE”¤«J:þß‚®ÃÏ~sx)Eü–þu.À@+ä8ÿ9T Xmà°š› ’µ”Tkµ Ø«©¹ŠÕL½5첪=R$·;[IÌÕì–Rj®„nµ [-Ø è˜È3IŠ$pZÀ-ƒS2“ƒ8dí"qÀÙ€Føž¿#“ôsòÛß"q`/IA¶Õn^d¸“ÁóÐöÄ“Øo½µæ‰f@¡€19ÉÌ“O’‰Å˜÷éOsæ±Ç8üùÏÓzï½ Ü~;M󿡿óhù<ºª"HÒïdlCqi ¸Ü';AÀ ‘‹D8õÔS <ííWej-¼ÝÝ Ü~;Åxœ×ï»äØŽ`O)'åJÇ:››é¿ãD‡ƒÙC‡8ñío“Ïdp67ãªù~©c]­­toÝJ^Q+õyäD»ow7¶K¨7‚$aq8ðõõÑÔׇÍïG*“–_±ïŠ8}Ûu(R©A5[¨+ûÚ*PÈ!J*ö%0{2óÇzÉôª—›šuÝô¿”L¹•­¢Ò¦‘=_@/¢œ.TWœËù)åð9ÝÀVÐÄó̤ Ìd‹æM)…õ©¥ëÓLÆAÁ0˜ å¿O÷ûþš‡0 ‘ôèJ&®˜iÃè` v Ë~ܷ݆½¶ŒP(d³$"ξº›\¡HÇÖ­ø.dÁÇ>Æë_úK?úÑÊãk±Û‘Î:nƒ¸4Ð@ 4P+&44ĉÿ]Q0t}ÎÑOV‡înÀ?>gŸy†ÝŸÿ<þþ~œÍÍsVH6mëÖѼr%ùtš<À©GÁ¿`öpøŠ'.ÙéÄcˆ"àÀPU ©¡áaÄòJò2ô¢ª¸úû댴 ÞóžÆ‹°A\h ~9ˆ²Lç† d¦¦ˆŒ0½?Í—1½^t¬$¢uõj$‹…=_ø3‡áliÁÛÕueÕG’ðöôвz5ö–¦÷îåÔ£’K&ñõ÷_vTP6Ѷ¯[GxÅ ZW­¢ç¦›hY¾I–u3후ø½w+Æ)HÕ@M:–`êð‘*i) LdLnû;îÀ·hyõäj·c ‡±µ¶¢ª:‚ÅJß½ïÃÙÝMhãF|ƒƒfS âÒ@ 4ðë†ìráïïÇÕÒ ÿý¿Æîó]d™Àà }·ÞJ>eġïŸ%þ°Ù´{…-Q’ðõõÑuà (ŠÂäž=DާoëÖ9}7¢$½9@oŒÓ§™xè!&^ÙEÑ0P…š ‚šKY}Õzå ^À§_¯ }3ª¾3j¿ÚҜ˽+‘–Þ„àr!ˆd²ÌT‰ "­½ Hœ;õæ[ðßó~æÝx#–&?§žÿšn –FE_€Ð;î$zà·¼›ÀÒõ÷¹ÕJjb‚c?ù …¢ÂÐûÞ‡ìtâíéi–qi øÍB´X°ºÝ lÛÆñÇcæàAÀ%¯BEl^/=[·Z´ˆÑçŸçõ/} Og'žŽŽ+Ö ¢ˆ#¤ÿÖ[ºë.|}}š†Ånë'¡j¡€’NsþÙg9öÈ#ÄÇ'Ð4P¨_õ Ògõ’IWRLónÅ´«A. G” ³5ÄEÓ«†Z ÐuƒDä×ã¸ùýHMMˆ^/¢Ãaú[R„|‹(â{终œ?¸zŽ ‘N:7ndþï!::Nôü…B{[ïxæyíÝDNŽ` Ðu›Çc>V‚€·³“á{ïeè}ïk¼hÄ¥hà­Ö+¬VŽ|ÿûØK Ç–«X{ðõ÷3üþ÷#JJ:d³ánm½*uÄb³ánkÃîó½-âÛuM#rä‡zˆ“Û·3uü8¿ÃjEUtTE­ÄãWú}ôzõEP«þ4ÈNÓղH½fÜd”F;j‰%3`[± Ï­ïG ].D»ÝT_,„\Q7ð}ôˆ‘Édq¯]‡ÅãL“vdž d“)²±ša°ô¿ü)ÁåËÉLOsöç?§˜J^º´ñ¢ø5ÂÒ¸ h ~u„.Ä 1}àç^xÁ;ïÄÝÚzUÇÊ.+ÿäOPóytEyÛßãßûÙDZVÀ÷¾÷a-m29B!<L9¸/¦cÙ2V+éˆïy•tlÕÐÑ4*µæâÐÀ¦¬‚TÒV4¯TlE/ý^Í¿El˜yvªž¢ÙœlikCp8|>¤PK(„ÒÚŠrö,âÊÕˆqæ›_Ã÷Þ» ·W××m>CwßMjlŒÞo¨ü|ðÞ{¼÷ÞÆ ¡¡¸4Ð@ ¼} »\fj©®3ùÚkdgfðõõ]õñ¢Åbnû¼…¼(W -Ÿ'~ô(ç{Œý×L?ú(é^ û ÷};î»ïÆæõ^º”–+èÚ´‰æ+hß²ߢE6;…T†ìÄ4šnÔ«/º¹’\%¡›ª‹ÕÝ‹ó¿ü‘“#¤&§ë6ŒôšQÑtÌüÞ³l=ën1ïo»ÉïG ‘<tI"6>NøŸ  œÛµ›‚ÕFxýúÊøÎb³a÷ûñtu1tϽoËǪ¡¸4Ð@ 4PG>:®¹†ÀÀÅtšc?úƒ¿9…d’ÓÏ=DZûï'yö,LßJ(îØÐo¿öÇAÀ?>`¦ ¢ˆ½¹WO¾Å‹9÷½ï1ûâ hù4ªŠVUP”²¢RRU,ÑQæOì'ôo²ï‹÷qú‘‡ÑòÙÊï)(:$sPÔ P¬¿Ý‚͆ÜÑ*Äe,c¡ÕJóÆëØüð¬Ö‹òrlMMôÜxcãÉÞP\h ~‹Ô§»ÏGphèmÿ©Ü0 tE¹âÖ“ìrѶnö–&Ž#_(ËåLIéR8vŒÄßþ-LOã¸î:„uIEd¯ÿÒ¥x‘}~²±ÙHUÕªÆÛ² ·ô}6¡"u÷úƒÿ‹þmÛð qöÅrÔ¢†Zò¹h2Ñ8Õëi¿ñ–ºÛ?s†O>Éä‘#Äãq~øÃˆ²ŒÍïÇêõ¾%VÇh—h ßÞL;~œñ—_&~ü8™©)Ó€| ó± ‡†Xþ‡ˆ£«‹øô4éXŒb±X ÁÕ ƒü«¯" ù<Ö ê3h{[Þ pvt ë¹hœB2ƒ®õëÒ:¤³ .Áû®÷š×¿p!›·PÌ剟£Î pû޽ŒîØ 6'í›¶Ô©(v¿_o/½ïzKþðOÚqi hàíŠ|4JôÈ}ó›¼þÏÿ̹'ŸD´Xhêï¿lðž Š„—.¥û†Àédúôi2‰Dm~¹;É>ôr(„cݺ‹ìõâîëÃÝׇäöÄÈEãhªVQ[ Y°/!¸í½•ã]mm´®]‡hw’ž‰ž‰°ösMÇõ7RÌðöõ™¡}µŠ‘Ó‰ÔÈVi—h ÞÞ°z<4õôàîê"96ÆìÞ½Äöí#öúë„V®Ä ]öX»ÏGÛš5—-#>9ÉìéÓÔ&øk@áÅÑŽC,°^P¡ Z­8ÚÚð akn¦˜Í‘$(¤³¦qW‡hÜ —ÐvÇ{뎵8hŠÂÌ‘£Äα擟,𵑖ĥh ·0´b‘ÌÄÅT «Ë5§‡C´Xhêé¡ýškÀnçì /8z”ÉŸþ”ù¿÷{W,{”¬VüóçÓ¹y3ÂÿßÞý…D•pÿÎÌƹ3kt-G[óOn ýaÅZš"$_²·‡¥Þ‚ ‚Ë'+„‚(„‚ è¡ Šj#ÐÕ•j#%”$ÛDÖµeGgÆ+ŽãÌÜ}‘%+µXXÚõ÷yÿÁ圗ß=÷ÜsL“—íísËK"ÁtOÓxJKÉ(+›»ú2»÷ÅW\Œ]1n¦#1âc6]½‰5c“v8)¨ÿ';›ÕÕÕ|½?f0¨?€þ'¶mÛ‘¥ÅN§é¹r…þ7ØxèkwíbÙŠ‹æÒ33 ··ÓÕÔDøÑ#<†AÞ–-Ô´¶’9Ï…ogò„Ž“'ëî&3ÇLÀ˜>à øø1™ë×ð™§FGikcäξii!cåJ°m\&u‰ÐŠ‹ˆÈR|ku8’»q#?<ÈЃäTT,¸×Ã1{_RñÞ½Äãq"CC„{{ïíÅ›“CF €áõΛõƒíÙC¶a2ù{õ%™L’L$½u‹ücÇ>øÌ©T +ÅŠÅX ‘á÷ÿ'N ù‡Ü^/¾5kÈ0MþxöŒ¾ë×™ ‡É©¨À=Oùx;[T[‹¯ €‰p˜¡û÷¼väÄy¡®®•ö¸ˆˆÈ{œ.«6l  át¹xtî‘ÁAŒeËX^R²ðñì%ŠkkkI¾¢"ŠêêpÏsҮȧЊ‹ˆˆ,(aY ܾÍ//2ùæ [(­¯'+7÷£²NÃÀÐ9+¢â"""ÿ¦Ñ§Oé¹|™þ›7YU^Îî–VUTh`DÅEDD>C¶M²lk£ëÌf,‹í§O³áÀ¨¸ˆˆˆˆ¼Ë©!QqùÌý—(š¹€wI©IEND®B`‚snd-16.1/pix/noid2.png0000644000076400007640000000270511147553270012665 0ustar bilbil‰PNG  IHDRx‚LãÓmsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ!¹;ûEIDATxÚíÝÑv›:@Ñ ‹ÿÿeúDeW€fÄÞOmâ6±=:ر‡yžçÿèÎè&x@à(7­ÿ2 Ãß?—>¹fù7žŒ4ðÃ0üéíßâ¾\¦äò4|ë8;(¿žâ¶'ÜšÕ ?Ú™k‘Å›n[4d8J4§¼½áý¿Y ÿ¦Û "oN‰ù1û€'ƒkŽ:Í)­æt=©oÑ)òæ”–‘Oxq'Ú,ž}Þœu32F]P ÑÅè‘#/,ˆyq'CäǨ ¢FÞïdÅè&€úÈÛˆyN“›]b€À ð< ðn@àxø¼W^‹Æ«ïtø’iòCà^NÑ<€À ð< ð<€À ð<€À ð<À/¯}g¥a¼@@Ó¯q/y;>~žçâÈ×ÄÝ qàk­Ã}{oº ,ðëp;]Kѳh< |¿D¼d7¾=_o÷8ðG‘®ý8íùE'@àx@à:5Eû†üÆ,ÀuëßO²ƒ°ƒ÷'O/z}6×Ëõr½â_/;x€N <€À ð<€À0ÌÞ– ÀàK†¡êÅÄj/Å=œÞ¼2Ëéþ’×Y¨½<@¦¸×4íj¢!åâ¸ãòµê(ÓQª¸?EàI§vqy6)Oî览 ÎÆÞ®çèåÞåÏÎeýÿw-È£ÿ§æãG_ûq]õ±Iø£Ö]—GøßXx­üÙ¡’?q7)Oöpj½ϾYJ”]ÕÙé‘_·dÇO¾ ÉÝ=tž”‡°¥§Î.¿·+Ú»üÑi›_¾Ÿ’{v:joá_ÙÒùzñZ4ÐæHžæi’üÂîà·[!™¾5˜IEND®B`‚snd-16.1/pix/poussin.png0000644000076400007640000003441011147553270013350 0ustar bilbil‰PNG  IHDR@©Z¬äTbKGDÿÿÿ ½§“ pHYs  šœtIME× Qd¼Ô IDATxÚígTUÇ€?ºÒ±ì;؃½b%*¶«bWŒ%ˆB,ÑØcE4숊5jÅ‚F 6Š vA”ÞÛûÁâ,oÀ<ˆó­ÅºÜ)gŸ™3gß©{+dggg#eEQ@(@@  0‡˜˜233?šñíÛ·ÄÆÆŠñññ¤¥¥}4>**Š÷ïߋНŒˆˆ`ذa¼yó&ßL÷îÝcÇŽX[[óîÝ;Q‹‚B“˜˜ÈرcñõõÍ7>00lllxùò¥¨0A‘ œ_ ¶¶6õë×ÿh& „››T¬XQŠ›2e ©©©réÓÒÒæìÙ³Ô­[÷?/ä¡C‡¨S§½zõ*³zñâŬ_¿¾ÄÞŸššM›6ýh¼ŸŸmÛ¶%**ЧOŸR»vm)ÎÜÜœˆˆ¹ôYYYpðàAÚ¶m["ÊÀ½{÷˜0a‚Ð<%Y–+WŽÊ•+Ö<˜',$$„FåQŒÿ‘‘‘lݺ??¿2û ïܹÃõë×éÑ£GÉlˆÊÊÔ¨Qã³òZ[[ç;œÖÖÖ&11±Ä”1))‰¨¨(¡uJú811‘ÐÐP‚ƒƒ¸rå 4â«W¯ÎóçÏÉÎΦ|ùò¢K8{öìaĈxxx”Ø{LOOçÙ³g<~üêÖ­+ÍùUªT‰ˆˆI± ÅÖLII¡S§NÒ"GÆ Y¸p¡?bÄN:Eß¾}¿È¶ DGG“˜˜HÍš5ËìCŽ‹‹C__Ÿ˜˜˜­›4iBî¶ÔjÕªaii)ýÀöìÙ“””Ê•+G›6mÄ›û…‰ŠŠÂÃÃÁƒ°dÉbcc144dÆŒxzzbooÀ¢E‹ ­'î߿Ϙ?>ß|ó\ü‰'4hÌ;—¬¬,ôôôX³f ëÖ­#44” °`Á‚W€+VdöìÙÒ÷ºuëbff&—fĈ_ŃJLL$%%EnžRPòPWW—ksU«V•û0`ÀQQ%WWWvî܉ƒfùòå$$$°f͆ F… Xºt)ûöí#,, SSSnܸQ(™2™Œ;vÇĉñôô”âÌÍ͹xñ"}úôACCƒjÕª1{öl^½z…½½=666°cǦL™‚ŽŽS§Ný¸‚Ñ·o_5j$Í÷'''óÓO?¡§§‡¹¹9IIItìØ‘nݺðÇZf›6mèÓ§§N’‹³¶¶&##Cú¾téR©W8xð`<==±´´DOO… âãã#¥¡A©#>>žHJøc”¨ªªú¯›lAéa×®]y¦PÊ´´°°`Ë–-¢eÅÀÕ«Wå>ƒƒƒyýú5~~~yöh~OŸ>åùóç&'ëŸ}xúô)3fÌ ))‰™3gZæˆ#˜9s&éééÒFòßÿ^½zannÎßÿͬY³˜7oïß¿§k×®RÞ±cÇ2eÊîÞ½Ktt4û÷ï P |}ûö¥oß¾ra7oÞ”û¾lÙ²"•¹páB¹­x;vìòßÿ!µjÕâòåËe{\VÉ5ZñÏ}S@(ÀROzz:”+WNT†@  @ ø\222X¹r%ýúõcÁ‚$''óâÅ zöì‰L&c̘1DEE±qãF D¯^½8yòd¡åÚØØ0`ÀŒ¥&¯^½¢OŸ>Èd2LLLˆŒŒ 33“µk×ò÷ßàë당¹9¡¡¡r×-¶9@///„Ý@Á£Gصk—Ôó=qqq\½z•}ûö±`Áž?ÎÁƒ155eÒ¤IÌž=WWWNŸ>͉'ˆŽŽÆÂ‚‘#GJîÑ£Gqrr"99™~øAZÙ»w/#GŽdÖ¬Y,X°€K—.1aÂ’’’X¶l™´âïïO@@€Ü†ébU€­Zµ¢aÆ<{öLNk ÅAÆ ùå—_HHHÀÖÖVTJ£§§ÇÅ‹QTT¤R¥JRxî¢Hß¾}IJJ¢I“&Ô®]›ÚµkSµjÕ"y¶¹&ú><׿xñbRRRpqq¡zõêŒ5ŠððpÌÌÌä¶½;6_kPŦÕÔÔPSSr ÅŠŠŠtæ[UUUTH1   €††Ïž=#::ú³M˜êêê$&&òöí[TUUQSSãúõë4jÔ ÿ›_Ì ‚‚½½=¿ÿþ;:::_ü~*W®ÌĉiÔ¨ŽŽŽìÞ½›¶mÛrïÞ=¼¼¼„€¢¢"ÙÙÙ/¨‚ÂÀˆ#èÚµ+ÉÉÉlÙ²UUU¶lÙBbb"666(++ó×_áééÉéÓ§‹Ä…ÁÝ»wqwwçüùó’ÍÈ­[·âì쌥¥%‰‰‰lß¾EEE,,,(W®ÊÊÊ(+ç r“““IOO'99YnPl„.#4kÖ ^¾|I:uD…>{üí·ßâää„““µjÕbíÚµ,Z´sssLLL5júúú’µ˜#GŽZîÑ£G¥9ÝÜõmmmLLLxðàæææ 0€±cÇJyôôô¨^½:›6m"66–­[·2nÜ8É2ºP€à“ÑÐÐ`ïÞ½yÂ7mÚ$÷½S§NtêÔ©Èä¶mÛ6ÜiÓ¦°nݺ|ó|h fùòåb,"z€ @DGGóöí[êׯªª*!!!ddd ©©‰¾¾>±±±’[ݺuëú$R||¼´‰¹víÚ¨««Kq¹›±!Ç_‘‚‚‚d1&7mjj*Ïž=£|ùòrS@¥^ºººÒ·o_ªV­Jjj*111èêêŠV,(Qœ>>¢(>Μ9CÏž=KDOôСCØØØ0vìXÞ½{@bb"´oßžjÕªaaaÁ;wX¼x±tjE(@ ˜Di%))‰ààà|m~ öìÙÃŒ3ptt¤J•*\¼x€ãÇ3dÈÊ—/Ïĉ155寿þBWWWî̵P€Aó矖ڲeffâííÍÂ… qvvfçÎ@ŽÛÉ?ß¼yÃû÷ïyõêqqq…–Add$¡¡¡’“µ‡H "¹Ÿoß¾åáÇôîÝ[ÊߨQ#RSS±¶¶–»®˜ŸŒ––çÎ`Íš5Œ1‚„„LMM騱#~~~899qõêUÆGLL #FŒ(´ÜÆ3vìXRRRèÓ§ëׯÇ‚ &pæÌ|||8vì×®]“žÿùçŸXYYáàà@ƒ „,«¬ZµŠ©S§bgg'*CPh~úé'”””PPPàÁƒdgg£¤¤„ŠŠ ¶¶¶Òiœ¢pQjcc“çz‡FEE…û÷ï“¢¢"ªªªÔ«W)¯±±1½{÷Î÷>„,C(++ËyÄ Ûžrù§É+%%%”””ŠLV~×SQQù¨ìÝç?s€ Ì" @ (gÏžÅØØcccÌÌ̘8q"2™Œ•+W9®(LLL>|8…–éîîÎÈ‘#>|¸Ü>>È9‘2|øpLLL8}ú4ã.÷÷ïßÏóçÏ¥ïÆÆÆ$&&Š!°@ (8¯^½¢bÅŠT«V }}}nÞ¼I\\gΜÁÈȈ1cÆ`ggÇôéÓyôè'Nœø¨[ÊOÅÎÎŽñãÇ…““†††RÜØ±cY°` 6dÀ€ddd@óæÍ+Õ $''KrMt[ÐÝÝ™L†L&cÁ‚_äAýþûïùZ€”N|||¤6W~(ÇÏϺté¹s爕ÂïÝ»ÇÑ£G¥´Ea4õÃküózÕªUcóæÍSµjUÈÌÌÄÃà  É?ñ‹/ððð qãÆÒ¼a±)Ànݺáè舣£#[·ný")""Bn×· t“kËÑÑ‘ˆ )&Ú·oÏÈ‘#ÑÐÐ`öìÙ_ü~¶lÙ‹/˜?>›6mBQQú÷ïÏ£Gظq#UªTaÊ”)4oޜٳgK6JÅX |2(++ciiɼyó˜5kÖ¿§E‹±lÙ2êÔ©ƒ••  Y³fŒ7ŽAƒqêÔ)¢¢¢033CGGGÎl¾XŸL\\íÚµÃ××—ÍàÁƒÑÑÑ E‹´iÓ†1cÆHyŠÂ‡×ÈýëÖ­\¹r…°°0ªV­Š¾¾>oÞ¼ÁÕÕU2Æ|íÚ5 gžðСC„‡‡ ]KôÁ'£««‹[·n%--­[·b``ÀÞ½{‘Édôïߟ&Mš0iÒ$öîÝKFF¿þúk¡åNš4‰íÛ·“••ÅŠ+ ¢J•*888°iÓ&®_¿Ž³³3ƒ ÂÛÛ[R”{öìaìØ±¬X±‚û÷ïcaa¶¶¶P€ `(**2qâD&Nœ(þOýúõ£_¿~E&·{÷îtïÞ].,×çä,x~H®o˜\ZµjÅÙ³gó–G<ÒÒËÄjh1ñüùsV­Z%*â+GôK1¹Ö‚¢';;»Ì{žËÊÊ"++K:b™{WII‰¬¬,233s”Œ²²ÜÙÜÏ%÷zÿ<ê–-ñTRRBQQ‘ÌÌL²²²PPP@YY9ß4¢(>‹‹/2jÔ(,,,øöÛo™>}º´øaooÏ AƒèÒ¥‹ä¢²0ØÛÛÓ¡C‡|W===éÚµ+”¼Ž5ŠéÓ§cddä˜é222bèСìÙ³GôÁçõ|œœØ¶mkÖ¬¡sçÎìÛ·Ê•+søðaêիǵkר¼y3[¶láÑ£GlذS§NJnµjÕ(W®\¾q6l`üøñ4lØKKKôõõñööæÉ“'ôë×pýúuFŽI·nݘ>}:¦¦¦hhhˆ @ øt¢££‘ÉdtéÒ…   RSS &55È9|ðæÍÉX)€¯¯o¡åôPÇ×÷óóãÍ›7DFF9“‚ƒƒåÒÀ2ÆôéÓÙ·oÓ§O•!(0iii\ºtInHܽ{w\]]III¡ZµjtèÐW¯^ñàÁºv튞ž^¡ä†……q÷î]:uêD¥J•äzɹÃâ6mÚ ¯¯äW|üø1ÆÆÆÄÇÇK–a ¨[·®P€e•2„«¨ÈÊÊ*seNHH`ذa(**’¡¡!wïÞeÓ¦ML›6-[¶pìØ1®\¹BHH¡¡¡E2xóæMîܹC||<šššôêÕKŠ›3gjjjT«VuëÖqûömÒÒÒ011!<<œW¯^±hÑ"bcciÚ´)«V­ÂÝÝuuu±"|.ëÖ­ãÑ£GeªÌjjjØÙÙ‘‘‘ÁÊ•+éÒ¥ VVVddd0zôhΟ?““S¦L¡{÷î´nÝš &Zî„ èÒ¥ íÛ·Ïs=222øöÛoñòò";;›[·nÉöðð 33###îÝ»'u„ŸŒ††&L <<gggæÌ™óÅïÉÊÊ {{{V¬XÁÂ… ÉÈÈÀÑёɓ'Ki,--qvvÆÒÒ’~ø 1ŸGrr2C† á›o¾ùâ÷òöí[ºu놎Žœ>}555®_¿NBB·oß&""###jÖ¬Idd$™™™(++—Þ`VViii=@->Ÿ5kÖ «« €žžždvM]] ¹EŠÊ•+ZÞ‡×Èý?,,Œ˜˜>Œ‰‰ ³gÏæÈ‘#¨««ãââÂåË—IHHàæÍ›>|˜!C†`nnΉ'$¿ ¥¶˜˜˜ˆ¿¿?sçέU (Bî޽˓'O$Ï{K–,áâÅ‹¬[·Žž={2tèPbbb8vìlÛ¶­Ð2·mÛÆÉ“'IJJ’®÷Ýwß1|øp†Š««+wïÞeÈ! 2„¡C‡bkkËš5k°²²"11‘ëׯóüùsú÷ï/¹ÅC`@P êׯϾ}ûäÂ8@FFãÇrNiä:!¯_¿~¡eöë×fÍšH[XœÑÖÖFCCƒgÏžP³fMÉøê¨Q£èÙ³'K—.•Î-W¯^] ( D… ¨P¡‚\XãÆå¾ëêêJCä¢@[[;ÏÉ’ HÿçwêDOOOÚ¨¦¦–o± ,Ê,B ‚³qãFÌÌÌà§Ÿ~ÂÌÌL27ïáá™™fff<þ¼Ðòîß¿/]/888ß4xyy°k×.ÌÌÌxüø1³hcffÆæÍ›¿nøòåK._¾ äìJ755¥OŸ>…ºfzz:ÖÖÖ;v Èqþ|þüy9ò% ɹsPP 6dïÞ½…ºæþýûiР@ŽÕÜ’ZþÿšÜ#]‚öîÝË;wèØ±#¦¦¦,[¶ŒÔÔT6lØÀ±cÇpvvÆÔÔ”ñãÇÓ«W¯<.4?‡qãÆ1jÔ(ú÷ïŸg#ttt4+W®D]]6mÚpêÔ)N:E¿~ý˜8q"Û¶m#88˜ 6àááÁþýû¥¼E>˜ýѰ… bffÆ€ä¼D]¿~=Ϥ*Àøñã0`€\˜‹‹ ÁÁÁ>|˜¸¸8ÔÕÕ>|8®®®ôíÛ÷³î9))‰6lˆL&#&&=zÄ¢E‹äÒ&$$0sæÌ<ר±cGžy‘õë×˙ϭ‹]»vå™Y·nþþþyÒÚÚÚJ¶Ë ÇÓýìÙ³‘Éd¬]»___ @ZZZ¡ž[ZZdäȑҴiSÔÔÔò-ÿŒ3òxùjÚ´)Ë–-ûâ/gn[˯~.›7o–Œ,rÚŠšš&LÀÕÕ•ÔÔT-Z„¶¶6?þø#IIItêÔ‰Î;EcÔµm۶҂Ɖ'äâ¶oßΘ1cøæ›oPPP ##†ÊÉ“'éׯ“&MBKK‹–-[Êù.r8uêÔË-ZðäÉ’““£”¯^½Ê×4SË–-yÿþ=+W®$66ö‹¼ R›Ë¯îK§OŸæÉ“'_DöåË—‘Édœ}š7òîÝ;Î;'·þC*UªÄªU«X½z5½zõÂÀÀà£÷P³fMBCC¥z³±±)òçáîîN×®]ó„W¨PÖ­[ãææFvv6žžžtìØñ_ËŸÀÏ?ÿ,ƉÅÌÓ§O‰‹‹ûbò¯\¹Bll¬ÔÓÎý‘Îý âÕ«WøúúQhyOž<áÙ³g&'+×\TT”ÜýÅÇÇ“ššÊƒ8~ü8?æÅ‹Å7þTÆ/mšü7æÎËŠ+044¤K—.…–Û­[7ÜÝÝiÑ¢Å'¥_¸p!«V­âñãÇŸäÛÀÚÚú“ïåS”Y‡ؾ};ÇŽ+6Ë#ÇŽûèÑØ±ci×®¿þú+íÛ·—6£Eù_'#FŒ`úôé\¾|+++š5kƤI“pqq!-- ccc^¼xÁ¬Y³HJJÊc-ús=z4fff¤§§K£µ?þøƒ 0yòdnܸArr2–––(**ròäIæÍ›ÇäÉ“©\¹2‹/æÜ¹sÄÅÅÉ*KüFh]]]ºvíJZZÚgÏñ†† ¢¡¡AóæÍ¿ÈÁo]]]–/_βeËpppø"ÏÀÞÞÖ®]+Þ~Õ«Wçüùóra7nÜû¾xñâ"•inn޹¹y¾ˆ«W¯æ;4þ¸ÊMŸ} >räÈ/*ÿ—_~ùÌ ß܉IDATâu°fÍš_¼x1ëׯgÓ¦ME.»iÓ¦Bù J%e~#´··7­ZµúêËQ£F inD øIüßy­¯‘ÌÌLÑÑÑ‘ ×ÖÖ&))‰ŒŒ ÑúKoß¾%&&櫸׌Œ –/_Î!CèÖ­.\àÙ³gtïÞ™L†‰‰ ‘‘‘¬_¿žAƒѳgÏ<ûö>kkkú÷ïOïÞ½±³³“‹»ÿ>uêÔ¡U«Vܺu‹¨¨(®\¹"m+{ýú5ýû÷G&“1xð`Þ¼y#`i'))‰àà` åÂ[¶lɳgÏHLLàÎ;´oß^TØäÂ… Ü»w﫸׸¸8ÜÝÝÙ·oÖÖÖìܹ“]»v1uêT©Zµ*—/_æÜ¹sìÙ³›|9”ãdz{÷nvìØÁáÇåâ\]]±²²bÍš5téÒ…˜˜üüüxÿþ=GÅØØGGGÚµkÇï¿ÿ^ú`óæÍóœ¤ü?~,·1T øhkk£ªªŠŽŽ***Òö°ÜÏÆS«V- ¨R¥J¡e6hЀzõêѬY3jÔ¨!—»_8×Ì}Æ ™6mš\ccc¹û+u pÖ¬YÒAl@P|ggg¾ÿþû•d—+WŽððpêׯÏÊ•+ ÃÚÚOOO¬­­éÝ»7Íš5ãÞ½{’,U«ÀšššEnY (III¨««—ê2jkk£¯¯/–ë¶"÷SSS“òåË£­­šš€d 87MAÐÐÐ@]]---É©9ÀŒ3ÐÖÖfΜ9Ô¯_Ÿþýû³iÓ&ìíí±³³céÒ¥’è­A—:ø)|ûí·~QkºÅEïÞ½¹~ý:YYYî±_+µjÕbÕªUx{{K‘d2:tàæÍ›Ì›7””d2OŸ>eêÔ©eWÖHIFEE…ôôô•-==]:Ï)|­ït… 022ÂÍÍMê<˜sçÎQ®\9víÚŰaØ;w®Ô#-“ ðC<==122-H (?æüùóøûûãêꊡ¡!Æ ãøñã,Z´ˆ:uêIJe˘}:sºuëÖLœ8Qꆇ‡³yóf7n̪U«xñâEd6iÒDºþ?ç8­­­åœ|åú ±µµeÊ”)xzz²qãF X»v->>>ů¿sXe‘•+W²|ùr¢¢¢JÕBIi3‡•»I]˜ö*8‰‰‰`jjЧ§çGÓ•YsXþþþ4oÞ¼L6ŽJ•*UêÊ%Ìa rqrrbذarÇæò£Ln„Þ¸q#£F*°Iž¯-ZððáCñ”zôèÁ­[·¾º^`XXïÞ½ãŋįÆàçç'÷YÞ¾}KDD¯_¿–Ü]~ì:ááá|ȱcÇ $3×MJJ ýû÷r¬P;::²hÑ"®\¹BTTsçÎååË—ôèÑCÊ;pà@ÆÇ•+WðõõÅÉÉ©ô*ÀC‡¡®®ÎÉ“'ËìK{âĉ2]þ¢ÄÃÃCÌÁýƒ^½zѽ{w€E›6m@II‰öíÛ“™™™£d”•QPPÀÛÛ›ììlPV.˜êÙ¶m›ÜõÉ×ÈúõëY·n$ÛÈÈHº¯ÜQÑýû÷ó•]ê ’’’TQeÿ}vÃÏÏOήš@ð©(**æi_ù)´OIS™JJJŸ|Ý¥)•Cà)S¦P»víM3qâD4hP*è7ä\ÿ凃ƒÉÉÉâm”iJ¥Ü»wïÿM³}ûöRûPÛ·oÿÓˆÖÿ‰ôìÙ“k×®å{˜^ð•÷fEÿNÕªUyûömžp##£ÝcV\$$$””$YG(üçôéÓ‡+W®üçrãââˆçúõëâ!(B P€@  @ (yæ°¥†ÒfKð+À’nKPúæ°b,B P€A™ÁÅÅ…zõêñôéSQB ò„‡‡—êò9::Ò¬Y3üýýóÄEEE‰Å!¡e ‹}cccvïÞ™™™\¼‹‹ ‰‰‰„‡‡ó÷ßK†6HKK“KŸ””€©©)êêêDDD°`ÁvìØÁÎ;¥´™™™òìÙ3š7o.w ™LFJJ ›7ofõêÕR\zz:ÞÞÞx{{Ëå‰gîܹ(++Ó«W/444¤8UUUéÖ­›4¬ÎÎΦqãÆ<|ø#GŽàââ"¥gèС¼ÿCCCÈÈÈÀÈÈ9Ù¡¡¡4mڔݻwóÓO?É=ooo¼¼¼òä)mtìØ‘ùóçÓ²eËOS€‡âÑ£G@ÎéþýûóÝwß}4Óû÷ï©W¯>$55U.ÎÍÍŒŒ ¹°¨¨(† &´C@EE%BúdddžžN­Zµ¸}ûvžø¸¸8tuuÉÈÈ”[.·nÝÊcr-·]>þ\.|É’%¼yóF.<(((ßûZ»víGï¹uëÖù†[ZZ~4··wž°GqæÌé‡àCzõê•ïuþÍ…gn?õ~Kœ8qâ_G°r pÈ!ôíÛ--­|ýýý?i¢ÖÜÜ<߯=oÞ¼<á/^`àÀŸ\¸£GR·n]:uêôÉyvíÚE=hÖ¬Ù'çY·n“&M¢FŸœÇÒÒ’_~ùEêq| sæÌá·ß~+Ð.ÉyŠŠøøxîß¿O§Nþï éŒ3òÍį¿þúŸß{zz:–––X[[‘º;{ö,êêêù_²ÝÌŸ?Ÿ­[·~ò•2@ÅŠå_¿~««+êêê¬X±‚Û·oóý÷ßK=»=zpèÐ!´´´¨V­Úÿ¢¬LÍš5ó„çÊÍ/îcèééQ¹rååÑÑÑ¡jժʣ©©IõêÕ ”G]]š5kHææ)%9Ï碭­žž»víbâĉ°F¸»»K0`ÑÑÑR|‹-X½z5JJJ¨©©}öÍV¯^½Àyj×®GaÍš5£\¹rÊchhøÉŸK›6m |oŸ“çsø¯ä”/_+++ÒÓÓÑÐÐ 33“¸¸8455¨_¿>¿üò ~.ÿ5 ef¸ù¥ÛMaÉW***Ê …•••ó ÒËù;v,pžÜ¡zqcjjúY]ÿ‚baañŸäùþ+9¹¨ªª¢ªª €’’Rž6Wœ’‹ô¥RVfþüùeVþ×í¦0ˆ}€ Ì¢]Ú ùôéS*W®œïOYÁÇǧÀ[S¾f222 ¤E‹eîY¿yó%%%ªT©R&Û¹´eH(@@ ( C`777d2yâÒÓÓÙ»w/K–,!>>žË—/#“ÉØ¸qc©ÙœœœÌæÍ›Ù°aC¾eЉ‰á‡~àøñãÜ¿™L†L&ãûï¿ÿªËššÊo¿ýÆÊ•+ILLÌ‹……vvvyö¨ JqqqXZZ"“Éxøð!×®]C&“Nvv6'OždÖ¬YDGG“žžÎþýûY¼x1ñññy®ÏÒ¥K±µµýè¾ÔR¥<ˆ££c¾{ƒ‚‚x÷îƒ ÂÞÞž÷ïßãè舾¾~‘{ÊÊÊÊ’sBÍÍ›7‹½ü7nÜ jÕªÔ©S'_ç77nÄÒÒwww4h€££#K–,¡}ûö_õs¿ÿ>ß~û-§OŸÎokk‹©©)AAA„††~µå00ggg~þùç"•ûöí[.]ºDhh(W®\¡Y³f¸¸¸CË–-Ù¼y3ªªª¨««Ó A gãyVVÏž=cРAEv/^^^\½z•Å‹ç[~555.\¸ …K >>>œ>}š•+W–š2ÙÚÚ¢¢¢Â±cÇ cذa :”´´4† ƹsçPSS#11‘áÇsþüyTTT¸páß}÷ýû÷ÇÀÀ€Å‹cbbB`` àììL‹-(W®mÚ´!88˜¤¤$222èÓ§Û·oÇÑÑ‘óçÏS¹reú÷ï_låÈð6šíÝBDz[3dÙÅÆßÉï\ÝóIןÝþè²;•áø ñ¯6ÐúXŸÇû(aãöüg‹ot›¿:ÜÚ\ÙE{vß7\ÁQ#Œ¤hV›ÉØ£¾ßúëߤ¿YÐÓµÞêhÓŠŒbJ—eÍï–ÝãŽpEˆ?Šëo;#Œ¤BU»[úÎnš:ßœÕ9é&2V Ø|vÛ6ÚÕ^ÎÅyí¸_Ô0ZWílé {G©gÞ±œ6ŒÍñN<9â=·È.etYƒh×LP”45 q º±–^ïÝb%»®În^/qÎè5æZÙ•a쥴ÐÑÀ³êãQmGÝ£Ôcc²¸'éÅÐ",F’yídž¼U©}»6èÍd;Ⴆà$>'¦H@u®‡áè›Wg9yIÔÙ(i³²+Â8"Ji¡£GÕ‡G³Z;»ç(õŒ Ò-¯QÈ?Óö—X—tLyóµ›­3@FºuÝ4˼Ä(V§¯ˆôì\Q×8Šd/ÈXŠŒÜºvf·;#Ji¡Ñ@µêãY­#»Ç(õŒ5ý‹›=‡¶Íy2ö… šsȱ®Îagß„]ÏçzIÖùòÌòçQJ  Ô^Ò£Qm÷\&æì¸S{n/ÆX'G%Ô8¦ô#(hçiYÀêœã G±®În–—dtÄÔ—]ÆQJ  ¼Üîjÿ:»]CxCçžÐ×HÚ‰‹Uƒ¼›‘É [î`à‚æ<¥¥/Vç|âÛhW×ô¦Ýêä#·Ÿ]>¿å¨(ÃØ#Ji¡£gÕ‡G£ÚN‘cØ4íãßu/ñË#º”±$ÀÝ&¶¬[‡½B \Ð0†å‹ ªÎùÒ£]Ý|\r];ïh|F”ÒBG/·û£ÚIŠ&m¡ýÖ^éVÊ@¶Ü,h.úuXK«NôÀíêšÙQ`#2Œ=¢´"ªÖ«eúK}˜Ôµ"SF Ö>6XóSgæ7 ÚOá¶~LVáqº+è’Òª5¢Ôxp)£W»è÷y¿Uᜩ÷ k~$m—øUò² ¢m0Þ(ÍäfŽ›dA}äQ~¶†‡¢“k‰ÐO£gn«läˆÔõ !éËë^ôÃëа‡Éõ.¯Ý™& êâ– gÙ[ÏÊMîâH¤ñê=5ícJ/¨KY…ˆß Á<ÿ.*vëY㜱¯^]fOÔŸO_ e›ìKê¶è-KåZ§%]—ÙSuÔŽ!KÙÖmªöŸÍT팱Iû=AP—319\C‚yµ‡‡ksάÉì)‚ºHyÓSÙÆË>2×½Ôϳ°A_Å êb¹ÅæÌ3ï zï;–Û›:ÿ÷ú]Sµ™bŠ ~ü7$˜ç`ÞéYÐÒ¸rèÔMÏ&Wm*‹yØA}ÏöÁüAÁ¢í\BÌú+CôÒ4¸ NÚÔù¨ºÁÔ[ðuç¥í[‚ùƒz]çbŽ>°ÇDÂhûåíMÿÛÆáXŒŽÝ0M…Ÿ³øIv7 G ^ÖS*åv‘ÝSã!}+þ‡4 ߤžm‘¡‚s »±¯Íî&áW×9¿›é©ñà£÷zÜnY6©gÝ ly¬öÙÕ„c§¤¶eq=[w~€÷rZ&WøuI=°‚SíGf`§¤L.>?°í½ZN—ÔSœ¬³ ì”dLž=> Kc&Öˆu›Ô³. -Õ\mûìú¿¶'ïIî'«à”´óä;üAàŽñ¥TÜ6‚ˆÉö ²¿óƒp;Ïjĸ%Í7€ÿðG;Æ—rü`p;ÜPL–_È1áþ úö¹¼7ÏjD¸% D¸c|)U nÁ ÇdøÙ߀pgAßF?p‡ Ü©ú Ü 1$ÊVÜ?nd$„; ú6ú€;DàN¯p¸ÇÙÐDT÷o6ÒÙÖ3}‹¾ýÁømT>)î8úv¬¦]<~OàFÚ—QôíhM»xü6*ÀmˆØ‰ôíOÇo£² ÜÈ€pÃôí41ýðÛ¨d7² Ü };ML¯øíü ¢o§‰é1øíÊß~ ҷÅôŠßÎmœéÛibú7ã·³d4èÛIbzAømÿÀCà@šód4‡èÛ(ML/¿ 2šÝî¤9KFó úvñøm„ F³›À‚4çÉh¾Cß.¿@F³‹ÀmBšË`4%}Û—Ý}¡ï"poO…wïåÆhþNú¶’]£ù"pëŒfÒ\Íå=» £Yƒ4WFsÙöÒéæÊhÎÚRÍ&¤¹ Fó·ó™­Õz¤U£ùÛùÌ®Õú=Ë‘Ñ\ùÌ¿7ØçÇh®|æO¶Êgþ`«|æ¶Áh†ÔŽ­-‡IEND®B`‚snd-16.1/pix/fmeq9.png0000644000076400007640000000060711147553267012700 0ustar bilbil‰PNG  IHDR8 ³Ž—3PLTEÿÿÿððð€€€àààÐÐÐÀÀÀ@@@PPP   °°°ppp``` 000l!Mƒ pHYs  šœtIME×$& è"2çIDAT(Ï•R‹ŽÃ030BÞÍÿí ¹IݤÓí%¢Á®ñÁ+Lñe<|R“½ÚYþXÛ‹¦¨™ñuŒ,Õ‹}ÁÏÏ8 æ1·.bÅV6[ËÚVRêérj‘þí,Ÿ¿AéóÎ|†öË¡púJ ü'òÎÙõAûn‰„T¨IEND®B`‚snd-16.1/pix/n3a1.png0000644000076400007640000033774011147553267012434 0ustar bilbil‰PNG  IHDRY9:îçsRGB®Îé pHYs  šœtIMEÙ78ŒdC IDATxÚì½íË-[—Þõó­j­{ïsžÎ“vLi06(äƒ( J̇øIý?ÔAE??Úˆ ¢„DÒ„˜H›øÒ1Ýj÷súœ³÷}¯ªš/ófݳVÕZç<¡5OÇgs³Y{­º×^«jÖ5ǸÆ5®!ªÊOÿüôÏOÿüôÏï†?æï¯ò;޼?…òŸþùݾžÿž[Ãòw3ÂREäwò ãoòWÿ<ÎÓ'él/m¥{¦~ªëüãÿ ÃËOè×ü韟Xˆù½ÐŸ¾âWþâüwøë—üñ?ù“þ"ëû«xã¯ÿY¾ý 0”† ZÁÅñ¿Ê¯üYÞ>Qe= ´î#,ó •w¨Ò¡zäêqÊt*ŠYÃxÁ¹÷W¥½Zl{Æ‚óüÉ‹<­o¸Xå‹ßÏ/üË?E·ÿ¿`Ðÿü_óý`wK´.9wá¿úwøüÛïËx[ðw·» F–èû2îóÉÝ|·° ¾@u÷|¿ŒÍþo+üÂ?Ïþ')éþpáùøâ÷ÿÝ]É?>`}ÏÏñ×ÿmâDÞ®™ãGÿ¿úËÜ>‘„¹þ(¹ ·Ë–Ù½ZôýÉ»+]—Bædqè°äÁ¾ µ6ÀªÄþr¯´€¯WÚàÚ“¶ý`c°àÚ«D.üщŸýÇÐØ½¹ð ÿÆOAí' Œ¾úKüíÿU´­Csá¯ü‡|õ7Q³.Ý÷Ÿ‚(©[̹[Õ¥ Ú²Ìݺ-mõ–=*m+¹t UÏR‡Sä:}p·ž{Ør‚•÷ 뮬Áʺ¶ë"w0~äÿ›äÛû¯Hæ÷ýÓüÜ/ý¿±ŒEU•ûoŒR ‚ˆÖ2·óhI¿Æ·¿Ìò›C‚4ó¿þ»dˆÚßõR-íAê®\ê.d½ËÙƒíÂ÷×µtWº¬»gû‹ªZÉ>þÚ Ét–tOšvï.¶oж^xp¹ÀÀ®=³á]_þ<¿ïOà¬â¿äãŸ$ü4µÏoÁé–ÌŠ—Ǽäé…þ];ßñ¥TYê2nÇϲÞäž·?ÇçÿœÞØô ÿÛ°´ÅÛ*J°tkØ´œö¤-]mï°=¨‹*íó]´•ΖëXåi„ÕoÀr†\fÿŒÙã—Ù?60v8µýÓ·›Åu?¾àÛ3þ?Ň?‚)8°ÿ"ã/¢±}H N×ÇFp®òae^!g~$¨ ‚Uþ¢ò_8 IŽÛÀsã LqIý5ÞŽÙ^MíÕt†V=œVá}‹;†ZÇ ñ.ȺcµN#,a—Ò…Z4lÚ«¾ºV®»Þn‹¢÷{‘4TÚ.§iØä[DæÛeÞ0nl¸¶÷¢½ü£øJ¥L’lø¢L¥(X~¸ƒ³\WÙó™¹)q»n™¯êJ†¿•ùÓ–`µ *Ùóöï¯Ël†¥f^ܼµõTM]ìÓ¯ð ›â°zîb¬ÜÈþ°r¯¼_¨ú°ôÁ,g¤Ç]%gÇ`I‡PG´ÚË4`²méÚ¿, }DÖž m þ!†Vd#Ê?løW”YËï.†a—þ:ÿ^æ×^ùÓ)° ̺nù IÝ®×`C®¥ER±»–±AU½–[äU:Ì*ß…\ù'žþèáòŸ¢ÕiòܦL[UÒ¥„ì“ÿ>„¶í{H ·„QâH»œÒ®¢é.­m¡ÖùöäÐÇ¥½ÃÐŽùudÏb%¢ö¦—EÜGþõq cùû¾à  R0_ðU°ø>þBØ£pãsd©§ÿ¿É 0}Ë_^ø[<1ÀgþcayáÕSÎiô’œb3&‚Y׳.HÞï£S‹€¶Õ;5¬æn÷Í Åî«ßYó°6ŒÓý6¼O‡k=Héžá’îAXºOå,C<2YÏC-{ˆ¶zsÝ‚÷û¶M×vÛ°ë‡ö í¾êˆŽ˜ à þÕ/ùS_òÏÑ"9€Oü…7þRà÷*“²bf1ÄÌbMT«’»]ö_¯t_©é4.=z#w,{yN—C„¥ß…YÇP+ë.%ÔîŠÞáÔ†\[ž˜»WS»œ©;¶b®ÝEÛEMíÉzçÔÛõŽà×ÝB=âq#nÔlÍ`\·fþ“‰ëÄe&¼1þ þÓ™°^¹þ~iÁÜ<_üÐð1Á?Èß/˜Œ¹â–—ÿÏPìômù†ékÞ|Ë7_ñ£(ÓÿÍÿ~ãë@Ðÿ“ÿÎðˆË…è) ÌÞ~¯€aŠ$Gô£&'9¸y°³­×Kš¥éöQ×=Ó#Å‘i»ˆ¥Û’ûÅ»”Ð6Hrm™õ¡–iKÔt€u$gËþ¦\DZüý$¼’3nË<àmoòdû¿ãàÊþŸÚu^¿¸ÃõE‚gP„Ïü™ ¿À`Y\ š±›(c1EM1ÆhV‹˜vxn·\Ÿ Ûvu·À¤æò˜BÒ‘ðóŸò°Ê÷`µîþߞ”ChmößNº<ñŽØrí°ÒñV¹ƒ¤ítÙI`mÛÔ¶;•ÅJ‹¥‡w“‘ˆõÅ ³õ9‹]#æUM’|7^"y!{ÌWü…‰ð™oŒ•¿ø-/oŒˆ? ŸyxùCüìnÂýüÌŸ1ùE†v“¼ïã?sÚüþ¢ò×dùL¶äBúó|5’/,¿Î׿Íë¦W~ëk~ˆ¦Èž%°ŒüðÊuA•E¸)³ ™—DrÄ„õDO˜$A“Ú,ÖÛhÉÆq*ÍÈÑl”ï®Zapûðß¶^ºpÉt¯öñ”kTi>P±©rXwÖ±²ôH¯# Oqç˜@˜Czx‡SwÙ‘c9’Èeò¹´ ‚XÐb%[êO)$5-»V-˜ŒM8A)QDœ%“Ŷ³¼¡•vß¿ÿJ¶;ƒ=lç}ð•ŸRàú€z<¢Õ)réƒ ê¹8û §»“>ˆ°Ê>ÔÚÖè]Œ–´¹=`™.²m—ÞH÷ØÞm#R»[b{R׸ZdÔ!#þ’œKÁFg““˜p^“—ñ‘`Ð?3Œ0gÆ vB¾âoDÂoóƒ‰á/ó·?ñá3—?Ç—‘7®‘áç¹~#תý¥"¿'‘Šþ1'?ïŒúÿGâHX+¿nõ?ƒ?Èôkz›E¯ÜÞ~oùŸ/DK¹p»à~&‘–•‰˜ K&'¢€P|Á&œ#YJÁl8µ<1c¡d±ë49IÎ$'Ùºd¤Hì’ƒÜÈYº$î®jd;ÖBÛu±m.mÙ3NV»¨ÊËìSÂ'¢‡²?LÎ6`ݯa9¤GÀ:Êä)Z³¥GÁG£wynã Æ«ÅJv¤‚¸Uñ´,¡Xr ¯5hÁf²à&+Ùš¢É]hPº$‘}b(ûÈë´NÁY`yz P«<=> »ž3ñ|ï"1‡š‹éÎûQVºU K÷ÅS{iããKû­ÔQT¹+&¦.%´Ý]±½dáÚÒ“eE1YZU$ {ÉÖgë’—8ë0Š3”…aaö$OŒ8GXüÄ(°FfGºp›Gæ83\yµ,Þäúõ‡Éù-BVfùk7þÛ_E¿Å¾òýÀâÈÀG–‘"0Â`VFð¤áúê‡A–À&² Ì ·0æÌmb˜3vdš _°T(žX‘¨S#SÂYr Ž,”‚d¬':rÄ{b?0{RTU‘Àb]¶dcµî j‘Ôvî¤ ÚbÛÔñYì¯à–º–EÚ½ÖAúô c¿˜e¯ÌÊïåÞ{¡CaÝɵŽ*-9+Þ•˜N‹Kr–!šƒ*è9rÝÝËV«&æ¢X)NS#»V{ï+9bÆUÀJ䌔”1#X1Y¬îöÓ`ÓÝÆåAêköy"{ž‹ÇßSàáè)Éwš!î$õg‚x9‹¹äÀÄÛ}m¸‡à¬·JÊÆ[¥®†XÚ9´MôГ]K{2¶­Þu÷Ïr-Ñ€’½äÁÌY­‘²¢'Ñ3'œ¡ŒL af°ä‰qdð,¯¼\¸Lž¸0ŒLNÒÄåª7oãç—óKÈÎ1¢oÜÞ'^opƒ _½‡~\Ûƒ# ‚ ƒ°hÜÛà¢õ³ ƒNqQ• %*_aÉ_0‹%Õ•ÒjÙŸ»ò6a" -þJ¸„ó¤‘Ið !sE=!c“8Gr¤à"V+ÆéJfY4·bâ–˸F±oÈE‡SæPJ{æž.p»ëÄÃí]º2eî0”}ê {Ñé]ÝPög<”yLiɃÊîŸáìïXã²Gºî>• U¤ˆ«¹ˆì `É€¥‚)˜„MXAÖâTÄš"NW¡_êÊ]y>u‘ÔVëƒ2ÙÇbœÁüQÉù¼Á‰Nõ¥'­<™xö-‡w”¼Ù/‘ |S™}ž¸m’›¾ak³Ç¦z97ŠÊ¶E\Q; ?¶3컈¬*r÷LDú‚IjlrCÇ"~‘`IƒÎI¼%×bâÄhЙۋ%–„ÿćŠb“¥Ì¼Í,id¾éøéãÇ)Œ¼ÀgÁÁUy,|†O07íË—†Y3 p… ®¥>¯® fÑp*b´,2#³#Vv5°ÔUY62«^‚K»U*",0M+7€C\PÌ fï–ÁÌVreÑ ¢ž8âG&C™jT5q™ñŽè‰3ë¡LŒ•<ºp{“ëÀòÍðņexáUx£\…+| ß´O5ÃGH0Á¥™Ø8 YÉ’‹Åðê^Ô™ ó*T—0°T¸ ,K$Ì,å#ŸfO,ØIЄ+XÏâIãH%°D| µ2έԘ‹k^<[‚#9""–l´±Þ-Öe3‘5ªRAÊž€·í+ôÂ+saÙ.ž’=›QZ¤ö°JÇaõ „œµòÈáŸrPiɃš¸ì<ÌSŃy àŒ§>ª.îÝ?Õh6b5”«AUÉA3&â%á£%‹³& *µˆëpʵäÜtqÁ]0eö•öy¢Àë/ôûáWyŠ\ª‡Ò=#œ[>Ðír²gèz Ó´³{'×ê+†¹SÉÛ§¤…N¶£äûÇ-Uy¯ŽÛNô»Ò.‹”°þŠñB4áó`çš :Fñ3CÍ¿nŒŽ<1ÏOrä™02[òÌ0 ùÆõÊ›×è$N2¾†ëë—ÊÕp“•Ÿº6qàL0C ^¥ñ ¥*øe½ÃÔ›×Ẹà$1 aÑyyÁbâ-°X‚' êI ¡’îžTwÜ€÷$wä…xá-°€Tö½Æ\5OtÄSï OTÄ‘¬äÄš–Ža²dA±HËß5"´îº2¢îóĨмi¿£—Žä*{Ò]Î(ÚÒÁYX<­z÷¯ž[ò´÷PÎê†wÝi§¼»y\¶Ò32º=dÔ J‹ŸÊ]£ÙXkxå0‰’°oP¡¬È%%i2â­IÖÙ"Ø-¼Òv‘l» fo›§Å…¾ÚZÎb™Ó3{=‰¶~¬&ý®.­ž0Ý1fOºsÖ~¸¡L;›èaSÆÛà\wª]§„(]üÕÖܱ]ÆŽØÒ¦5½f;dµ"¶ ²DÜÄh( !0;âÀ¥Æ/ž81^¸YÒÌPqí•y!XÉó¤—‹Ü\È7Y†P°kÆW9¬7ø ßÀ ß´O“8çÖÛ{P!Iô>—¼[4Ì2¼ð4ÎRÜ^k(h#³lÂyb`©åÂ@¬ KÈØ 7CÙÊ…õKÕL°`taPŒ%9’'YñF³ŠqDG«ö’¤¨xdFËÖ×)!¶â»ÀjÛÊA“u×#½EX¥Ë›Ò^ zþû¦œÅ\˜øSç’'³_Ìæ1ÿuÚ}}ä^¶ÓÂZ(¬ÿ¬á•¶f«Ðm9‹ošÆñÑ ˜¬>Dbp³5 2wÂËk­Í ,î=%,óÌ­Æb ÃÀd% ÌW}µ¶¼]®Ëà“s ÂM¹TJnð[0íq[an=Æc£ÞT°°¨ªa$[÷f_’¯¤»ÏjG™<1áa`¾0EüÌpáV0•‰qDGªÕL™âš'.&ÏdìÈlIŽœ°ŽTkˆŽÄ“œ$GöñA¢÷‹uÙhó>òhl$‰v8eºÀª´Ý›l¢¿äÌ-ë®ý.Ôº¬㤓nqÆcï »ÎYžæ†§”–yÀÓ?’^r¨­éûÅhAÌ `¶¬0\ůŒ]ÈÖ|RJ¦dÉÆe)¨Gb—¹.^È£û$Üth%ûðª×}ž7!C°G½KOhx=œ¸ïjµÚ\0ÚÙÕû.û`Jöì{éú{¶MÛv„½Ù#צƒ ›Rדx'ËÞh¯H‡FdõåÇOq3ƒ#:Í2¿BÒbÉÃB°”*ݪŵ‰10;ÒÈ´HÕ«\^íËÛ‡—[¸0 8å*¼Â­ý¼‚ÂÐÎÃÇ–ÉR²:½J0“ŽÑgb¿èd~áu&Ì t*6 ,†­‘Ô‚,•›ŸÏØoÈ-Lž40-„HÌXÏbÉŠ‰k’U@‰âÎKr­É8Œ/R¥[w­ûvo¦¤‡•»j×U Í›¤#[ØkMuOf±—8é^º%gܼîAêØ‹Æ¡‹ÐVò°ä©Dþ´ƒgß8,ë©"5+q/‰ðû^ŸVâeÞ7'﯊¾'Œ5>Z—­M“ŒƒÎA–J ̆Rñ˜*È3ÃÀXªžKE.Ü.ܾ•h‡|Æ,A¸(7Yk‚oà[ø¼Ê\×{„¡E[¡eŽƒ2 ³äÁ–Q’s³ p¤…¡`7GJøŒ]X©’YžxáV㯄¯1TŸ„¯Hd Å‘*™U°_ù,Kny¢±R„’±Q“oê-,Þ¤*ƒ   BÛ³ckÖ)Ý>]:ׇú'î9¬ÞB‹Ž’ï[ïKö‚øÓœã”Øz$ËâAbø(Ô’§í‡æAîÃ#÷T²Ùõ;V¡4>+[ŒàªøÅR EëKR„b(Öœ¾ëèJ§©KÝ}˜r-Ý«èâä;3{5¹E|Ðh¥,L3S-Â, –üÆuYÕy"ŒÜ\˜œ¤ óM.¯—oö¢£pQ^…[Ö7xkº‡ØDc“k5 ˜T£É$·H0FƒÌž˜ÕF©\û’°UÅŸg†ÀRUò ·uD+¦öúŒLB¨ºÓŠ€Bɘš]˜Ä’‹"¼®6»b`Õ(~t³±YTeÛÜjص¥ê}Y)ïÕ¤wÍÀ}k´|–z\+gÊw=èž’?o TÜöqéðŽÒ’§áÕ±€ø¨€¶ÞDUã.'U®PXòêá·Ê®¾ZUѦ6UÛDÕ7h»sJg¢âš^NöáUî’ö÷0 ìÌ^w„*}ÐÜÃK=}tkAt2òŒÖó’K/Õ¨ÇEÊŠ\Ò]`5­:~Çbº¤Ê>ì:’îvß½iJûŠÇЂ,ÛtO®câµË" èŒdü˜¼KÞE+)â'E4á'†zÏŒ–ÜTZ—ÊÄÏ –20OŒžd™u¼Èôuøòæ/ñêÕ.0+£àá_Ãׂ?7ç<?hÒ­ /`„¨da‘O—Þ A– 1ª²ŒLŽ83fPK™2.ã,1ârgy¢Ã;Bm–ž<©jM9á"ÁcÉà×>D²m1—#e–ŒQK.j*1? ‹h©‘¬´VR:‚rkë¹+Æ`q0°<:YêY„¥‡öÃS&þXC<°xZâô#½·žhµVÞ#‹8‰°6 Y¡Ôƒ,¥µ5¬÷o"IÕJŽš1ê|ÖÒúE·²àv¯÷B$»§±¶&Ä>Oä Þ’[æZŠC+5O‘KwhõNËúà]ïÔ-wÁïû5RLgÌ&èA¥ÉqéÒ@éô [Pf÷ݶ¶S“nvÌ~¯ÃÚÄ־ܗVÞÊÅo.ƒVï:õø—ä†OÑø ‹¥, †X&Æ­-fdr¤—™Á õÕ€L2LVÓ«¼Ì~øö_–‹0 D™eýÀŸá­‰ãûÅsißníô–5ÉT‹Y½f™%8Ò‚{Ñ·YÏêI•MØ@t, ßÜi&K6”Ò‚©… à›è¡šœ(Rå] CÁ8r`ö¤„7䌋XKq¤$ΠV“q$c‹¨[(ˆC,ªíNIÃUö —Ý«÷ºÓ:è^ôÐû}ß™:äï7Aê´šôÄÝáUvï$nèK7i*sÚK(¨EË[mêÒõ¸„«ù ÇÉŠ\ΊSÄšIœ®š”܉HKç¸Rº]º¸@÷ŽÚ…]º'ã;ªX;}'™¥'•Ô;´*0ë‘…Ä“°ú¡Ñ£bòJxIAÌ*êYÛËsWu½‹°d/s+\+u,ïÒR¼MCZÌ›[%~szÈêªËÁ¿“GâÐŒ\C´>[›g‚Õ|“ËÈToïª~¨¤{s L ƒ#z–‰K`±’G¦Y 2…1>{‹&%^à3| oðm÷y–f»Ã[žø:˜å¢óFJÆ©X¯Ë,°–@L¸ŠSUmë¦,€bÒú|.G ĪÛPij8²!g¬#F|íRª9Ç€­a¦#ƒ:YöŽd¤X›-ÖdS½·2šß9‰—vþÍ>7tgŽ4öj•Ç€¥{>«Oì÷PiÉY¿ô£Ñ;òÀªôÔàá‰Vë>Ôª œ¤„¬•ÊŠnŬ?šÖ@:G<+’,®¨ñKR]#S'Þµ]#n/¶]aÙ×ûHê[êƒ>žSÑ–|q|äJ±?b·8k—æq´õHŽw¼(+3 XEÊšJ»´«câ]6]:õÃFÚ}OŸ˜ç®ô±õýlÑÖ] ѵ尵õDðHD2cC?LÁ,É8+eÐy–Á‘\U²öŽdIh5«ÌâM§¢*Ëûâ×Ô:~mW³:o íZonñ}¨ÅžÂè³{æVÊ™5ͱ_úNcÎ:xî‚,YOrÃ3V«èEônسۑ\‚”¶€²J²" gVrRgŒ‹˜p IDATŸ…Ö¯£gnë®SÆÛ}ógß²p—6J§Díá¬<Öjqö¤> »ä,†*ߥ‡çA»´<—ë®Ú€)Hõcªé¡iÍk¦#ÝûráÑÔt[8ôÞÊ=‡U:=jjŒî§+g/ÕˆyÀ¨ŸmÈÆ—Y†™±¶¹, 5ª¤;èÄ81ZŠ'N­9ñÆ¥R]¯ú2Ë0Øù›ë—ËJ08¸ /8þë.I¬ ì¥\†v# ‚‡¢,Â@qr ãâ¼7iT;É80gÜÀ¬ëÖ[±fmçðD_ª“2ñ¯º¶F¯²†ˆ«Xæ‰ÊÔ^uÂ,9µv˪ÿb-9³xYT%‹Mx+Y(ð * Ž5æJêê ©k É>æ.Ô:FXz¦Ò*\•ô1){쟓Šy` /{Køï$ãOSÑý}öžÊÊd‰²‰âÕ@iÞ~ ›V’CÑ ‰â êâŠøÎò¥çƒ{ÀÊmcÔƒšô[Ù½ËìÅÄG­ésy`gZöŸš•~ÏPëûðr¨:¬+6a¤7†kÃ6ߥ„®Ë¥C®´¬ÔòŽkGχv6†«>¹´œ%¬™‹„•Ö€ü5Ú;{¢Õ¼H˜ ¹f‚†rã22WÀÚ$óÈ$èEn7½zINòä†O?.nà nЏ5„­¡Ö­}È­ý°[ß6ÃèY0(a‘\¶±äEC—°–’ñ W[©#¾֕׈7 5C¬ÄVÆ…ÁµZ«„”­¿'°DÔj-²ZžfL,ëqFJÄG’#‹ F‹¡HPSTT¥šØ”Ö•rçHã:½¨íjñùñ¤»üxAËã|á8ÉB{"ËVë‰ÊÁ>µŠßëKÛ©iƉpt Äè«5aª™dÂGŠ‚P*ry$áŒjd¶®ÜWUs§x¸ëJï{¤S÷5îäZº7ÛÊhx³wáàÌËTZ0½ʾ£ë ÏmõŸÈ ‚L§Öª;õš0²[ºåŒ¹“•ö³ðL÷Àv6¹“ËI—9ÞÉJ·-Ý·W—&€ÖîeñkÁË Åø"ë3q!L:ZÉ7. AБéÆÕó̘-ùÂíÆEàÂt“[`všfœ¤o/_LèWƒ… Üd•h¼Â'ø¦Æamí‡Cƒ°jV3Ã$DxQÁËò1§btõÃÒÅKJ¸…9KÕ‘)&0ƒLŒ•b¯Â…ˆwÄêY23T®UYGvÄêx¡e­zX+‰es 4䊃V2ˆ‘l)B±&Wwyk‹($4½·X¿‡Zé°4Äú¤/ì•õÌ^ùX^<°¾³q‡½ˆÒžA˜= × D÷ÿ–½Û¶ëóÁ§Pd£± FÐŒ #‰õW"•é4V²uË ¹óu*­2ÕšîLQ߉Fi–C¶Ë+û’bÜÓ?ñ@{•ïm~xæ?­lï6ªGÅFyl¥uêk;^BºFû"¡ê:LWrv9D;ol³§®ÒÞš&5Yißœ¸µòø=r…¶(|…jjZ@XģРp)¹K v ²XrиH0¨ç20ûU%_e™iârá&èË•P™ø‰‹×è%ÝÌøzy™Í Á0WFáµ…¯0ÃçêEÓ«Ÿ©µõ\Z…1 L Rð&»19ç%VÖßË80mZ3â=I׳›Âꨓ\:Ôžð¼6î,5沫úÁ[²]E©J·"¨~8†ˆ†\E^­¿:;I\5œp.Z²8•¥‰í°z ²‡ xý‹Ü¥w¥F9K{>‹3Yi?Ó€³Ùw§FZ§í;Ç)‡ªgòŽKrÊa½?Üb°FÃkkÒ¬›L©nYµ\(`5EqÎFcTµkªrûž¦¾vë» àºÂG_+){´êI®²·]~„V§LòµµTŸ¦‡åq¯´~WnÈYǡٷëHS5l›–k$×Êz”ÆÍçé¾QWf?(AZ•mè ‹Ã¾SwË }s-ï…EÙ$é Éx—ܘ­-A–ˆ—U‡U)ù85ª«:ǃ\¹M õÉ—AfKžd¸pûzüÁÍ_òb×ÀW]ͺ¯åCXGg °–®ú94Œ„  ’‚OÞk™&†™Õ2ÉÚü¼’îU“U…Pe ¿*[ƒ¯š'6Á„¯Uõ~0k©1·W¡dæÀRÙýúª%±«ÔQ²Ã9ÍFJæuVh‰TZØUö6±+Þ™j™½ÞtÈÕ›|Êa~¤Ó9uâ58Ž£‚ô.ÎzU¬\º_ÏI÷‚éC­>òª‚ÒŒ\Ä-„aÅx!©Kâ­$ã ÕË!vÍtÚÕé·<ÑwÐãºÐ‚®}Át®Oå@{éA!q·Èc¯=¬ŽÏ”³IKDO<âe¯~(]6ÜO´è=¶½-w¿bÁ¶-t›¹ê·ËìÅYw®LnOºoÖKçÿÛ{i¥ÆÄÓ~E×ú¤6­gÑáeò~‰âE˜™.Uô02Õ>Äyf¬÷íÄèI½p«17.½)ŸíÇÛeœJ°¼Êú_ßà ¾†[«J‡M±…]©=¸ÀƒðI12!Ö£ø"vÁ{I\õœpÄjaX ©¨*­V[žY2Îuõð–šn˶HÊP9á-i35­Ž¾õ°„÷D¡Dp8'«ý¼•jL1¶V×Ów¯(:õiŸ–®bØïëùlèãA‡†]ê”ÌÒ³5ý\è ´²û°ËíÀ«nÃE **ªgUBÙ`¬Ã¬áV¾vDÛÕþc•h)XÉNS v×Ä©¾»;]gTº.\mÌ®v$KÜ«Ióƒ =ºçãïŒñ{býî–é'У2«<È ŸµÐ32«ì=ØGXeï¯õÞ´£X°i}­šŽ«­Ãݺ5í:iOŸn;}•еóæ;b+¶_YÚ6cWˇµÛ´ž‚ Å ³ :É0°Ô‘KË XifœAg†vòÂà‰–ôÆõ"7KtždüúòƒWÿR®†QðÊM[zû_Á Ÿ*$u­<—í´ÖqÍWÁ(QRqÉ[cK6v_óD§ÉɈ²ö†ºÎk,6¤Af'ÑiŒâo,–|c˜…2q™˜ªš|^+LÕK¾øq$ïâ›»Fç³u¼Á¨8a„70ð-L­&PCÈJÌ¿4¿:ˆ^ð”AJ°%Ød1EqEÕKT¨4y¬Ú8]»vK-ÿUŸå…àš àö¤]iŒ'YâÀl)ÕŽ9áL£ä¥*ã±®¥“‚ZrÍ:+`9‰†‚â$y‰µ{ר¼Þœ €4µé>½)3w‡r`Á8Úȃ,w…¬»°Ë<õY>5ÿ{T:4­ ¾ÊÛeS(I÷³TmŒ—lÖ…ÕkY+j+Ï:©U““d]¢¨h×|³–îóÄÔÍm Ø—ƒÿ_F¦.Ô²û±nOÎc÷ŒÈ ©¥?ŽéÃsÅCy XO*0f¯Òº¬~u­I€â2&#¹õ¬¥nnk9x.»’¶Üе¤¯gâÓÞ‹n=ŒÝäeÍË$¢QìPlXlÈΤ…Ák¬nYce¸.·žWÑiºq¹p[µ¦2Š×ø&×oý¯?xÉ·ÊJÇ6ç⟚bëµ³ÙÙüÚÆØÆá£ru&óy| v1¢EU¼ÄÀâM{%–«vyœ¥Ô®À’òêïT ÖETT­8#ÅPÉÚªG-wÐëŽu Xz­pÈâ›ÿ=½sÚÄóHŸeUEµ¡•m!Ô ‡U+³]Ú<šˆôN\ª[¥J`KRVoÓ` šÖ–Ÿw-IOf¥nðûŠl?oÕuzòžº²û[H¦ZfŸJuÑ‹¶¯÷$öáûÍèáAQžºÓ<Ä›ZÑYÜj=6/½ÏK˜ŒÖeQí™r3–Û=v'3ïkˆ}`å:œ²ïØ´Znù¦~X`hSüÂÚAí†äÆ„£j/Kmë »Ü0WP¨wà•[E7yyc2Z‚,7¹|úÁÇ48nµÁPy•°FøÜ`뛆b¹iÍBSíëÄÆšƒ¬ƒ0œª5Kâà«Oô$cµ|Ñ×(~aH«—iÊ묰4´*a½#š‘é1åUAšSã/GV fÅJe¸Ùµ"ø‚ÝË’…R¡Ê¬<}²ÑâmÜFÎàTPiƒàkŠ£­Ù~—âSÂS.önßQªw.}GîøNŠUJdmøW¤¨­±UA ¶ìç8¼W &cª_SéÕEkS“ÖÓÍúeë¼ÕTuð5jq„•tS EŠwI|Óïnž=5ØûŽû¦ºVž-ŠÐ=•½™AìpêhpÚ‹zMëV*Ï MËS£žEüþóÃN1«t&ï§Ðš}m±tÝfv_®¦>ºŽå«á±ØuØ×{e;Yƒm´e‚¿î÷„½v-~•!ÚzýR'J ¼f._¼7G¼“d¤,:8Ɇ¸ŒL¡)žZãô¥²E¦ W/i`yÓ‹±úúáe| *\»95˜ªéáç&Ȩã¥ÇvØ­}Z[«ÕÅÄ`T”IÆA—"Æi²RßX­ ‚%E|µ©˜Wª+Vj…’„pwZOj¤{©––ìUô kì¶Ô¹š±õ kEÒ [óP•JX²HÉ8SsI-†bl1&›ÚkW% °ÖYîy:=o}dþ§FNœZÓ˜•±ª,;"EEÅ$1[V,’¼6§Ý–i?ëJM W,k¦½CMÁ̇©¨/hAlkq0¢³F+Ù5! ݵܕe/ˆwN¸}ÞWš>¨tÃÞP÷¬üMmÔb[VÈó­gr¹G*ùG ¥ßO¥õˆÏº³Y-{­éÝ,í²W?ÜušWëÌÕ>°ª¨M«‘›ýL*íü?s§Ãêg‚ºÆp§v5s,ov¡åb êƒóÙ†l]¶&Ï2XMµ†¸„R-C Å'&·vÆÔêìˆW eÔÛ›¿¾ú 7a«kŠg›\«ºk-Íò¡æ†À ®íìÌ-+­€03xƒxUCÄ1N¢g™5‰3ËÈ40+Cj–\­i,éÂ-+úä’bZ5¥©ªOÍê¹ì냂©ÉJ"G\U±¦w¹VޫŸÇ9bÄ x’Yù¯eå.뛋ª‘\ég²±eò°9ÙÙNè“ •÷öÊt Q÷7I¯/5g°eÚÿRsÀʵ‹¬Šdli|T¦f…9,³'ÝkJ(íU)yw|¨UE©ûI³vPA#¡™Ä«•à4ÑàVËš51ûÖ§ÔVìÎQî–uïQs׃¢{ä*Ý;ô™£î lº‹azjë>ä±Öô¹J‹Ã°Ëç£3ù唃©­y7áÉîeX¶;U¦ºAdÄ –õº˜§ÜqR ¬´ƒ³Š\—v¤ïÜ™µUåJGÉgX€‚ HÀ_â‡ñu4³—Tõ¢³Œµónfª7ð•[evnŒsµf®]ÊA– ·‘éG~˜FWFƒåMÖÏó~³µpO]ªk:5Fj͉¡aô j,&¨j<ÅØ×ájM²x‰‹f'1®«jŒµY8ÄŠ¶Õò¡Ik1T¾ðVïŽMÖP¨*ÎjUÂRµò¶å†õ$TýX†œH/Dª¸–Û-YKÕÌ ¾­ ‰l¤TUª1EP±l–ëiïH£¶Q:Ï[yî<ÚÍ>ìjöJ­£ºSc«ü6e³òšÿœDX5c´¼ÉFlm°Õ©´¨[M ·Ÿš–ËêbšŠˆ Ödqqm%Ñ}S4Ý ÐGX[káÒAUo½(âö x·WœêA¿ï6X§c—{?y`/?N„õܶôQï¡<Õ—n[—=xÞT>Ô7`wŠ­Ò­‚¸.²y¬éZp}×Pö*yßÅζ]âÐD—Ö–.­^šœOÆkò$ÃÜäà‡µ0ص¿g|ë«Ê Þ¸ŽÌ*2ùñíÃu1 ÜÀ+NxmÂÑ-Ôú K³|X`½´/5ÀÇŽe¸ÔÓ*ŠÍ&YS‚ÍÖZÉÂñI½—T*•þ« †!ã¼]MY}£äÅ“ª©\ ùwê*×í¿rü– ;À ,õ®o€U\sƒ0x³š>¯T—%gRS€—í­øX'3Ôd¨¦mŠŠ¢*¬c£ä®ƒgßÙ&ådØÂŠMtí®›’SPÙ°])v){ÀjøÅëÁ–é~¬v1W ÁŒ¾;ÁKÂÕQÀ¨ož¥U_jT­Œ:—ðíõÝá©»Yý¾P/ûYFOZ²Ý?ºÄ›ý¨‹>´÷€UCÓß©ôD³õ‰!¸­+Ô’ÝG{Èc;D9óëU wOº„)ëÖ§ŠØ® hÖí~ˆqiÇa/ «Ö4õ}f¯ÖŒLHhF¸˜1;Ïu ©¦E‚i^Z–d(ËÀR‰­cµ™nÜŠÊM.Á.ß¼|9“à«\„´…Z_µé­Ë&"mߥâÚÔV í®zÌ UÃ(Å›ù:W°DuI¼#Ž:y‰Õì¡T“ø:›Š¦ÃªAYVåDË­]£$[qÇáš}Mi¢­Ò¨.µäD4ïfÂZ?a}“š$n:Ji#Lk?L¥ó+øˆY›íDß·oiOO}–«Whí$©²u@eÍÛŠŠÊ ÙàÅæþÔôPN+·ØJw!Y¥´ä³´U7ö½Í[-µJÒraÖ–ÃÚÀ(ŠÁ¹$4 ±‹%|‡\eï4`:S'öϽW¦`Ñé'ì~¤ecñkÄ[Ïy0¬çû ×#éã‘ß©ÒÒ§Ó£3¾Ý‹:úùarHßGµÖ‹-mé´SÆë>þr…COW•.%ÜÔ§[ßõV§ÓΰNñ‹¸’íƒ[¬d'5°Ê81Ö;sbš¸ů-Ê8â…é•«ŠÜô2ÊdLy ×É‹ ˆpUÆ6±êEßZ ñ­}žz.­ì@Ë 7ÚëCÇÓÁ)QÈR‚ÅëâB6ÞÚÅ_ô C©Žh ’ªåi›£dìj©¼ÔÝŸ˜-Ù6ˇš ÆUtZ–¦xÈm0{ ”²ÃWêÊ’|3d¨pfšb¾ªŽìjŒk™cmÏÞ\¤¤÷YkQ °jÀ ˜uÆ©ET.•cÒªFU+W¶QIÈÊ2U¹‹‡º$ÏÜé«ÞS¼fŒïYáÝoj§r(Mý kbèæ5” X-%¬ù¹³¦érõa»<yqœññ¼½ùˆAå1féÓ_ïû ûÖúrfêpT?ؽetéÙk»r嶦)æ4´+•:•ÖÖÁ³½QhÁòV®­lÑÝäM%¿!Z@rs]0E‡ëüb$;ÍQn5%¬î ÄJ5–—äÊÛÈ\îÂÍKüzøÁ2 18T¸4Л`uüÜÕkôwmáXnߨÖÖPsIF”Q@r´o׋±ÅJ®¾}Õ¸&°ÌHó/]MJk„US›ÖWX  ¶z6䕺JÕ¶´âZÕ‹Z43;bÁÆÕ¢TWUÉ'rM)ÍŽ­œ}Â\,G†bÑ a­k¥´}|M 3YÞŸQÖXL·Ã:¾uÕ5®€%²ÉÑ7ÀÒN ÞÉ?iÁÔ [yE.9•5ØŒ)¸&ÈzG®-7Ô˜ZæùŽY¦1Y£6ÀÒulU*­ªz™:ɪ2¸Y¶¡ð¥«åiײÓë§sWÆw]Ob/lË]8a÷Z&íLJµ=è¾›º¥¸wÈzð§1µúsnë‘G ߻索œÔ‹w5DÛ1¤¦;ͽ««t:vÓ™’ùz]×¥ ûpµì#¬¾qG:MfjjRíœbc¸RSE”5ºÑÚ¿íõzyó.MU¯yiàR[£gP÷7f…—ªÌ¬¶ñ^¢Ñr“Ëçˇég/ï:øK7˜§"×WíÃÜZ†h›¦ìÒNSèâ/séZg I[«d)Þo5È¢ÁIJêG™ 9©‹â7J¾0¸ÆRÕ°vS·*á:@¬ú”FB`®$zÆšõø5þª^k„åW¹|±k–£~°´vUf}å× ë-n£ä+m=-Ťcî=µŠMMKE¥óW–}WŸî#¬;Øê²BÓ%pU‡%åŒÃ2wWPì՛街éÄñTP›0M‡e*îºUVJ£áÕŠˆ¨EUŽã•s×r(]&hºÏköf‰¹¯|èVï}\X²WruÑVM}íYûÁk¼”(ß)Ô:}PþŽš¥ïrò¯;ßuÞÙ…åNbª{zÞvꇺ,(ëŒ÷üta­…Áws*’ƒ ­6Ahaå4%Ô–¶Kor+î³Eéi ²ñ\-%\ë5ÞJ;ˆ"x¿¬…†ÜÝ©©ÝvC«úŽÌÚjˆiOÛô\‘í Uö0#ÄvS*s׌B‹ø:&«œ "Ò¬Ö÷µžÔù~‚x9£äû!t™`¯‰¹+–}g_:|Ÿy¤ø„IˆEÍm~ïØw·y/˜+^¥óhÖn²‡q}UÂj¹!_ÇWkó(ÓÄÅhöRe¥´†˜‹"cí¹«ÄVeyF™蛽¾~¼ÎfàU¸Vñ²ú—Vqü'øMˆð©Å†Csa®çnj–k-ßC ·šcýðVP­TW²>g%b¤5ZTê(éÚK88â‚™ :Êêøž–:ÌxhÖ4UäUCŽáªnñbȉ¥’èy-&–ñï´×aÕÿ½Jv‹¶zÀj²ÊR'“WÒ}M6ëT¿õÖjg«e÷aí«ìoaÕ ¯VHï¡ ™ra%lÆ•{¨êÁËlbù½îaÇœÕ=aƒgÿÞ¸³V*Ï…ªH)Î'©&dÛœºvh^ï©ó<ßNN>L‰H],”;nÙtÎ*zVDQ‹’wÑS¯ŽàqÝðøà‰µ–>hñùqÇð 5s ¶LW7|2TÛîÝ.z}nõevóê%φ\}p3ÿcßÁã»`j›sÚUð-ÁôO?¿‡Z&éåz vd§i–YPÛÆ[7.íž+`9Òk¸è[0_|óá‹itªnñÊÿCÙ›6IŽÜÚ‚ð…ŒÈêÖÝÞ¼ùÿnlÞèJêªÊŒ }Á|p‡œdT÷•Éd©Ì¨ÌXè pp–õ릉‡­ÕúÒjô’+@Z°ÆlµNy•Œ+MˆOT‚ÿŠ÷à3Qµ(é$jØSY3¢CrÊuÈ [c]e„„­½¢’PKˆªïiL+äNq¨ uU 6Sy‡ÒöŒš{H5’ÌÒ­¢´‘€WCAe%ÛcPÿ¢W1»%¢*fÝ6¾Â9h‡ÎѾ¹µ„˜æÁÆR¸ê°š—´ZÔïØ&¯9q,[›ÆO,Ü ”eÁžá´7¥a0H¤)}ÌT ¤5«Î¸•eV3Ì“O‡>•I=™@øYH“I|3¸ 6m]âÒI–ð?BâåϬiþ4ÕâRN„Ùž›¯,LëIrXÌž£GåÌÚ=ÔÞŸÆ~·„`æD1Ö€Õw²Ž„‡7ÚçÝxÉW ¼Z-·Ô5>È×@yC„ PÛ&€"ö[ [bc–¶0Á– ™©|Æo°&Ä1O`à|(¹á'@À'ðiD¯O‹6_£ÿJjε›ôì1$6ÇÈ÷5 ‘vR³f’@Ô|–èÞâ¦=r‚ˆÍ ¥‘¹­¡u ¹o¯·Ñ5ukšŒXG¶y¬FÝ"ÓFé±c»Fˆo$ð¦Ö&­M¦`UtE`]Í–M‡Ð«ÑZW±¶l,:/ZÊKøo V†¼Ê×핳5ëÀƒ/¯Q³ë›ã{†'Ȧ¶d–¦ è"!'.:ÄÊW3Û1ª h³Þû~fÖ4îd*/3Ñ3ÅA#°I ²çÙPþéáוë³!~iíp™$v°ô¨³=)f ̲ž³ÓƒmC-Â5Ê™øÊ ¯k»:tÆ{tXÅ”3˜ £˜É1b×XGP dÜÁ‹¬ÏòJH¾ä¾ÐÞ:¬ëw‚D¤6ß©[K@ä[ D¨7yþ¤?î{òŠ'!,¸¾Ô3kÕßP-™ÝVÝ!6áô0hf§q'Ûê“EžÄS^¹Àï.& mNêN­`etÇ£5#>õäŽ}ClCî05Uœ«&Í¿h‘ ÛøF³ =ÿ5*ƒ´É»%uãšÒ¾£h×ÈÑ(ª—“Š6Vâ´±Ò‡],î&z#5¢õ…kÃÈf‡HFcƒòŽ8Zà+¼!• oK•«Ç!‘ !¾×²öndÁ¦„¬‚Þ¾äVM9 $«vNÇáìÐw›i½Im/†“ÉK˜gÆj6ñ2;¶Ø¤-Õ®·³¡] ðl§!WÍÎ¥U<Þç\¼SJÿ©^šÞ$‰Á°pªSΰ´Xy#‡VÍÞï50 œÀí ‰'r<Œ»ƒ]&f“3fh /CË5­ÚÝP…éáx*Z|üöt7,„/ét­ÑaÝT#ýCw³j³¡WÐ}î†ôu6l뮌è¦SGR8ÊÞ9ï-¹ {jÒœÜüævÄ›C& wŸåÒB[I±'¹æáPj:¬NŽìP†d¤¦—nÕ0D‡îˆB¦Ã"íÅÔܹM‚ÍN Ô¿Q¤Ð1¬ ÃÒ’S‡õbÃë`8˜RbV‡õ’éî-áL9+Âf ¢ÿUS·«X¼Å<ûÞT´`ñK ÀQP ©1Öèç1 ÿ¢Y3Y¿‹0#ñ–&L¤B5x¼›½D!C¸þF6Ñ&©N¹58¹ƒ¾«ï dä ý²lÑ›è°zòz¼ÌãñóHXg ™gÃ2“@t‹VA0T½îúCkX ¿Áò°ÎXû¢ƒÿªØ|Q2—â_¤kG‚„%»¥zΕh˜O)ý½%Dì­ÃÚÔ6~Á±9d'å‹îŽê?(wêت)gwUw߀ïÀßø—}ÃÝáHJ‰°ÃpØÚÜÔ²YO]ží eqeY‰%Q¬ÄÙK^¨#q ¶Q§†©i ÈÍafï”ÔœœíUSQ÷~(3J‚o†¨9+_ÆÉò:“!;:ù³êö¬<«S¨_‹¼ø¥‡‚5âl•”ôÿB :¿¡É®¯ VîDv?š±óЧ͗³ä¬ÁÞˆVÑÚŸ\°d×®›r(7Ô&­ðMÜD•Qª0ˆbØXä5¾+4}à¸0ûDkêÀ³Ï fnøæ!~ÙB^µ†//˜åˆ71[S¹P³ÿ9c‹fJþšm)]e_ÒÕ÷’òÂ6ÞÏŽ­‡"™î¬Ëu*ü‡Ön9œ1ÉJzÝFë¥U•ÕUµˆQPçnù 7pª1î»}_°=±‘Ô…¶a›Ð®]Ñë¦ClIb+žž2Ky¸Ûç·]"V `A¤ÎÒb¶øÀOCˆo(ÕÝ,‚–§ óF îMÿ¨»A4sú•$’8<ü¹2•,!ÒP’hkhÔ‚mÇÂÚaµÀŽÁy\<’C·ª)wúB³¨{%k«$ jêfd½`y¤V’šÖZ)Wu²œN‚J:}!ñ¦Ûê–‘NAeÆóÑPIK¹¤5´«¼¤=$“™ß†/Ý›äEƒ°øWûéË 4ë~2”6:Ô¢’%¡Æuw†´¹öUSØLs6³;àCfƒê:€jV„ev‹·ác~îÝ*¤‚¹ÛkX‹Ã…xu[îäN#W\­¿¨þ<È{ºæ\^œ¸¦Ö¡ô@ï²»Ù:{Mû’¯@Qc‘ÐÔv‡èµ¶»V„Ý´]»ù€ªòl,ä[PÀZÝü)1IDŠ’õé5Õô?U8¥Jº._¬ú’³î‹¾º¶ uÚN6—ˆDê8&ˆT™kàOÏ;GG™)ö„!I…Ë|biÑ› fuXV§W§„SÜ\h_P6ÄQ^hSGšµµöl¾£ïÛ‚­m»V<2£®ôü’{eþ\>á–C€'¬‚HÝ$~ÕÒÓz¢ÿOå‡n6«‰FSéÔÔt×2½i9ûÐ<êp gðH¸«Ëê¶ÅÁEǹqÙíE\‹+Î^­™›sAš\q˜j D3êQç¬ê”Áà‘£J£3<é7ÆI§ì‡ö6Ž®JVáNæÔÝ!V½–Ê0u8âÍ^›¸͓ޡ-ÁÓ]ò°:†exñl‘©!Ê)¹ÁÏ;ÄWÏUÀÜZÁzª-lû_}_j[v¶UEë=åÊc"H'gsôm‡Uç¬ 1ðV¹2uÅÜLÁè”à†ÂÜâF¨¼Èe&7ð,Óq ”<æyÒU4Üá?õÏ2Ç~ÆCo’ÆëI,-3˜EWÁšÅòàõàMµʉ֥¿rÕ½Ù!ŽfÖÚÆG3ÚŽ¸šèä ý$PI Œåcó>%ŽLÅIyÒÞt­™bÔn÷vð6Äv¼¿p¿Ñ£‚W<ò·ïÛ]ì^Z$X”NõS['Öâ—ºhµéï®6Õwví¹ðÐútUºèðØ ù86 „$Ø žÊâKAv …½Cö(Av¦F:Ýö6Ó¹nRZƖп¸W¹i[ñr(Mö›±«Fºóà‡yV9¶ÿÛ‰ÜÿÄÐ<‡ƒ‘_lRÂécó8¬ª0ÖˆéâF¿Ä°|Ñ»ÔW£åázað‰ž¥î‰[ëpwóñ£l «™õ0‚—ì¨K©³ú-m=Î7ÞCTQÑN ˜“WNô.?çw“Y;Z]´›{'××@imâa>É"ßù—ÒU‹$¿ôÈUÁ’ÿáêð`É ÃT£«‚Uç.Ï §‹i»ª-Xí=øW:°Õwˆ^ìO=T27Õj“36úµ Pkµ*üRÝúd_™¤ Ë²`L˶LlÊ»'Ö÷%÷…6fù~û-ÅP‚«šj5ÒCPùaþ®t­M¹Q?•8{fþx`XÆrkÕü4žúž°£Ûo­¦Âü˜¹2Õ=< DÅæÂCWó4ì¥×¦gµF¬ñ¹ZÓàS—Fç¶”dzíÇøåªl'öZs°|fN´K×Já‚v(ÍL-öìKÉ „xÛÝíûJá "-íøyäÏvn[¸4CV<¸7S­(»£hÿò÷Ïo;EÜ7Ý]Þ´$ßôÝù¡®Ö¡p€î£g̪µö¦[\M]î)lØÙ:Z-µßr$ŽKàÂR#{.LeGÙ¼Oi1´ßã¦S³œWr|å9¾Ëè®Rêê;9K²ÒDµÃª¶` ñMKî1^•Ž«„F{(±™¼²åixÔ(†U®·„ žàF´—ßd̬…ª™2qß_í•ýâ‰[…ƒÚ¶˜Ì_tuØxq¢\XF ÂDâP…’™¢ wê¼%´Iƒ³ãÌv™NûÁq¦“ñ$3Nlöé‚Ö5†¹×,¾2lpW4‚_xòÌAµüø?•R_FÆýZÊsiæu™Çc­iÜ©`c5^¬Ÿ­x¼iĺqpâ¡°N=`-×a¬ ¿)©Xºèç{S*¹QhQ‚, _³[³ãJ$›¬ž ½rÃÚNmS/ÓeÁ&@@Zš¾OòJÏèÒ?~û÷´,„*¸Ñ«¬Œê³ªyÖ<•búðБð¦-RÛø6ý-ól;b>’Þ’zxíí—"°4 $•»+Áƒ¹<±:*)!IL¥u”êªìÕY4ª‚'„“‘‡éæð~çTAôž—A½ÿz[*Ü!¯ãp.U½TD,8%g BüpIP7ª¢]ãhÁ—#a„Y(ÃÃt ‰T_=×™ô`=K›êµéŸ=Ö¶cÈ žmuØÞ¬öý¦ H…Cœ”JG>&b³1«˜fÀâYÃçO¶ùuÞúÙ‘fÀÈçu]í¢õ±´ E>C™Ówt­sµÂì:AG›ÿ?±©9µâ/#ñtâÍH8ì•m¾+c+ü/-Ê‹>ÿUÛ®ÍØŽØ¡¤5q32 0õ×¹?Ka.na˜Dȵ—¶7Q)zG¹w5) -²¯ì膅iâaò*~ŽØZ•€nØ?t{F*ܱ„,2’ÃÖ@éU÷BÁLlàñ«Â|1îˆ kkDéà5$’BÏ“éœÉÃÅlo«Õé Ò,¯ÆÒÍOƒài±Nͬº‚«°çÂòl¼Ò¸ÎÑ`XÖú=R‚˜‹žæpd1¤-»Ø/æäaéÑzCµ÷¯\&’<ÍäƒÁ½´Î3Y®ª†œ`ø_hMÖŸöY—âõ4 Ûý¦{ÓÄÕ¤“ÙsYLçj#¥=@nHy›µ‹Þ‡'àºËìVZ 75m|1¶ñ¨ Ü Z°ÞpðTÚZª¨*xä Û‚µ‚#öˆ­¬/ÜÛÄô“¾­ò¬žþ¶ÅE@|)×a@òífùð©5hÓVëC[³¡ýú˜›Ö,¯Åz8-âð0!,A¿huÍXà©:W~¬ß4ûK¼£²øV©‚kï ¾ÙÇâ>`os`óÍ~K­iòó*?d+UJ[Y’„H^ÈÐJåäó7®ÓŸås‡•à·æMmp{kÀ\;ƒ†œu$^I·Z¶«ÃF.õŽú²àÙ Öqº>Kw'Ã7Òv®©³¢ê\ñK¦dT„eƇ‡Œ–u:˜—ÝÏÉœ@o×!zš ûÁ¸ “@¬¾ƒ£¥Jf6ôßáãæ¦ ³Öï ›ùëÖ€j§u&=œSÄ]¿áÁÃ0Hë,ñac¤ s7±i¶p—ÀjÎÈPõr"ÜOü’¿¿šA+­ê¾P@€ì Œõãé}JˆÄKŽÔó¯"¶¶ÖÝG$RkÀf±ßéQÄ}Ñý+||þÛ=û€/µCZ©;M®è*îÀÿþP/˜êcA÷1ñ5”*€0(«Ë+Õ+˜  ™:µµéT/RY‘ÊÉ3œ'–DE<¥D¡U¯¤ªÐí•k@ˆH­5 ¦ÃÊC¨•+Ù«¬ ³¡j„›ˆ: #ú¦rYÀ¾Ád2û1 6icl]Ks |B`0tž$Láb‚¦åT°Lˆ$_æ>sónï×Ó«NY|}|'›u0ÔD;hñ*†ôPL#`QS­Zd¹o.Ö…¢Ca©õ¬°€}ÅÚ„;Íé¡YÓ,Ø \ šnñîŸë}§¥Ã"ˆjMsÓ×¶ê+¼ÿ¾t¦ ÀßF€…6V#¶'¨• ×®ÍÛsÕ?Aº—t:KŽ 8œ¹<ºt‹>bN>&bIšÙ)Av ŽZ¼X[ÔÏ䕜ÕV£ÖÏåæWã­ÓÐ÷(-ch. «WÞ)ƒÁtX((L÷¿c1@ ÁИ™ZÛ¶î}†¥ÅjJC64¬€+‚ý…í¶:ÕzN%øˆMÀ鉵 Õ°+B$ž’§TÊåSÁvHf²(Ú[aàaŽæ¸išç™Òß9’΃w³ÏŸÍ?>%dŽL1ˆlªÃa]xö_þ‹ ×;±¡\ad8éŠøÔåYoek’Ug_-šA÷:¿£6¡µK†X‹T÷©¦«öÊ–Ö0ú):„V*OÚ*@‚ìà*ñ¾ûÙU¦ú”=ÒÖ0¬'šùrnlÌæš xÁÖ¤®ôü#þþó?¾ÉÊX*ø¤.ôÊ/eõ¨iïæCÿ+¦]ÚÔ¦fCö©³íý aÝJ "¨K×hÄVà9‚È´›u"ñ´Ç½'G™©×¦¤;Ófßr°<‚:Ò4Ÿåá%*œ®ºCu+íò«CÔël[ÚI®ªf0¬+ÇÑ„°#ðËZ}dò¼¶ŒbfC¹–ÚjÅc]8XZ«{±^¡ÖÃà‚!OlÒË0lmF"ˆ´U*Þe3 ×Ðb®}Ë„cïÇsœýPÍÑ F~"3“Jfª@Dàô*h¶Zž ¦ÜÁˆRäMµâS„—\uFòK~<½áÁË› ñ·z1š{+œ,ämîô!؈qœÝ<3ö‡µ˜9€Fc%æƒðóÍ †OfKhe[ÙHÕTžRçy©ëú¤ ‘Ò&»µ¬°–"³tÛÒÚMtÁó†;£ÉMžŽ2ûúõíž–Ø;¬O}ž7}¿n/^+~À¿ÃZŒ5àM‹ÚÝ-~½ra×:Û":y·‚E}ü„`¡ Œˆ¼€(IRž$yJ¤ÓŸí°é´UF Ü•†{›øæ¥Rçbä‡-¤'›‚U-W¾µWj‰õ'’Q/ VFذðiIUOãH}%‹õÚc‰5À,còg[-×h W½5ŠÖ·Vïâ:ý¬©És¥Ž’»[,D"N ’ŠÙ‹ZC6÷X2 3}ºóa6Œt!HÉ×®¾4:û:°Ém ©àDøç¯ƒó¯‹Ôyl”+<ëR t¶W–«4F:<ÐIž]çœD1žuκu&0ÄV.ŸàšÙƒ˜ÊS}Ä,U’Þ`²qy̳f¾qî #´ƒk½ÝѧH{Uþ¤ë‘YëÐ/Ø Ü‚õÑ·ûò¤Õ¡°Häýo?ÿ×oÝÔ:—u¸¶Á­¬þ<ÕÅô®—â¦CÜPFí’p#ž¾^¯;Gª—W¢ƒ×º6È΄*‚°‹À‘D’H`ªL™[ÏUwÚÑš IDATKuTÕb´æžxX† ½â£Ý(X„â Ãt´ùÕŒ -ëH}Ÿ(’?ðÚ±ÌÃvX‘_Û³a Ú~q^Ö±—!yE¶N_´šõÀº_}¡‚yBÄŠ§Ã:žwc¾Q1[G¤*Iˆ¼‹½Ø«™ÉËœ¯LJf.¹ÌVî—-G9­Ê.éäºPê5Ëöplh î”fz@Ê/ʘIN›OºzŽ—­Ö¹«ªWaet²?`^uÞ!lÂx~Ëe6sfH´? Jn1™$3óÎzÝ™ÖàçRÑÉ«ÌE±ôð’NˆG…[òÇ’+S@Š”K;vo‰Ø?ñQÁÜl­œ}áîPˆjÄöE÷¼øÍGYBð‚•zE_u^Ë ðøøø®ñ®»Ê‚¡•}×Ý0!œ¾À oÙ¦?ZMsëM f VY5ë¬=Gè9®„uç…©FlNŠÑk$ì#£2°kÊaT.®®ûÛ–0W¥‚k b¶Þ§6™Uwˆí:áÉ È¡fÈõH¸aáéºì>5†#ÏÊOíæ#ë¢N¨ÏühØJuÖp¡ƒ9ÎøzD±Ö®:\cÁ^ˆ ØI%'Œê–Üï´Pס¡%Ìó¸W(¿Ä~²¡$T›cµÎô¢­ö„Ñ*p¥×Úbº g D¹’òS×pZºÕS‘²_ê±EW„øzEÑ’+Վ̲G9•°ƒjÒÍ\·AkðsãiGÂbŠ—³ÑÓíàô®àgƒ˜¯Éx¢U³%LúÓÃï:^>Œ°ãã·ÏÈ{D$,5Òî‘ t¤†«F,í˜E•/ØÙ…ø§ÿøúvß{ð¢®jnè6'Ý'à ø¡ÐxÒÆêw_ É{}p«ewý †ë«×¹2ê19FCÄ]Í7¡WRt,v(I•ˆÂ®xvTH¤áYLÍT+9)LÍÞ¯uÈp Œ74ˆ–)Ý´R~¤±jÁêt-Ój½èZí’oè6AÊåH¸#Zнµs €½: Û³‘òKwTŒÆp@ò6ò¾qJ Ü]îk3T ÑÉ߯ÚÉñä‘X—F—§þÊ× ®!¢C> T<«ß™@?¹4+~ꉜ5îÞ¡O…­®»òò­ÉÆ\Ó68îJÆ|Oד[<ÍÆÑgaà/<ΦZïÀø3˜%'~©Í–y¿)sŒ«M9´‘2W1§»Øµ{xe˜;¬±“¡ãQõIrÍî%½ª˜,`–eÝ/Lâ¨lU"ö€½Aò×­¿wO¹‚¢ì+=ÿyÿ÷Í/X Ž@‚›"G^­¢›‚z8þøÞœd"DA%é\öÉ;ý yfÏF°ž { ËS6Ö¬ú¯óiÔ‚ž”{ŸÕ:–º¸ê@’É·’hoªÌf(HÔË©pºå!²æ†Q?ÈbLâ§K—’pJæÒÖ ]ƒî;‹3QˆW Ô&a;B¼qÛzqß康*Æî ¾Y^´:Õˆ í;¶` ¯‰f‹pÅþÄ P톭â%É->‰NYVˆqàP}0(ÅØÀcNÙ9¬jؤc˜aÓæ°¾V[Ö×!Ïl,Òn€çFN°f«âCïóĻ^¹ÅŸ-áå—ÙÔÖó‹Þ°Où´½°ÆÔ‡ž‹gJ ÏÎ<‡´Úé AØ5/²ùÐFÓ«[cÒlØÅ0]³µ¦ËÄ”:ů=húI K%’æ³\Á+¶Ö7¡6¿-´¯òãõo[\*3X]¡†Y¢& ­xÝ”ÆñS°$ØÅ!’òàžðÜTYMÏå”+S|=™,ëj9˜ñlÔBN9NÍpFîȰ6},p$ •ŠÂ.{ÇTÕSöÔû©$¨3Hù¥‘Î#¢µq ¼’N¹[ݶ´ÍUºLì¦jú.’¯F¸iÁåG(ó@Îü)Ë{0v4¤‡Yo8\©Ù¹6£ˆö‘[[¼P³&,mwÔÒX+¨SEˆò\|LÄBÙ !Pt Í@gñF¶WN‘^2Óâë)—F[‚–Ó× ÎËŒ3 Y¾’› ^u®´©àY;ÍW¦ ò×,˜ß‰x“ã9iñàb*§V 6{uQãÓíÃvXn¶ü¼Ñà²UWå—=Àþp2Õ„Z,²±±MC(ÁKq·/ÏÉQ!H”=Ò^à6ìÍpŠPÜZÁŠH¡³´¶/ºAà¨<øöã·ß’‹X‹€¨„Ùx“æ±Cü‹ñ‡à¹ŸO†g¬„@p‚D½Õb-IAAw6Lw¯–Óöu7œ¬ÑU±âeN«>„3ÂÛÞ‘‘r ñ\FvÞqiãs IMôò Ô8Œê•CŸà•%?fÃa¡%6‡^̬šßîV§¡m^õZž-¤­©D• 4ÒC9š:pBZBµÇêÄTßµŽdŽë`T`®e¨;*‘(øâÖܘTÌÐRO.õJ|Xâäÿ„«Y†‰DýY óë¯ø«®§ÎdUœÜµÎÍQ½²0–“BPÞ̃ïXZôÆævŒæ½á¡×;+hÆé 7/ëüž´Î/Rž&3c•e V™£kê¼%<Ô©jÌö” ¹m‘d‰»‹…¹>i÷’„è{P3â. HDŠØ*ÜÛ‚§1òMnäåû·ßÓ±€ŽÄW“ÉZÇ–°n„ÿÇcÏ Y=rDt`Âl‚HãyNŽ€ƒ®u:v&øƒ’š,¢Ý ñ‹“Eï‹1Duúߢ•‹´çòœ ,ʉ£x|£•öÜÝ‡Š°ZZéÐäÀ1V}O+^¥÷×n düO§p™†52lÒIo=φV¸óÚ6<~W™¸×ìÆ¡¡˜ aL¦¶<‰‰-Å+Ðþèé;…ÂÊ‘³áôfͧšsÊ»í°`6ð˜aøÁÏ>6xÏNInvýÅ­AÞ“§Î¡­rÅÒ¢7Œöw™†ò^¢xéÝ|^eÖ+hß]QUmÿåæ±—®~ŠÙM6H'=ÓV+/‡bÚ®jLiÈ̆ÅDÖñª g3\–þ›Ý½|ܾ! ¸A<ž@^[ö*6íq6u}Øœj ûSëK6øzÐáqQDÌΆ¬¥-š­"›0c¯ˆØ Þµ9qÑŸö ˆàP©xG,2¢J‰ÕA+Õ‚•†Ìp€YŒš!ùEõ~¬eë&À•z_r?: Ö0pòØŸVn¨ã!^­–¸BüZ¶ö Ø«8bàÖô=Íu{°´"Ï9×}l$PãØÆ°3êK’„7y[|Å8Œ„nNa.æ´‘™ò<–¹ Šð`NtŸúáâÆö!câÊT©Çøõå “xõž'©Žªîk~Ãà OÀwÛ‡ij"ã¶eGBë0€Î¤"ôÈéÁÒâ a!Ê`î6[Ô ¤/Üû¡5 ¨)ãF Õ2[9¿j ^³—Zê8Ü«B‘±AyÇâ9œÕ,1Ef/-  Î á __ºoΛZ篢0.iSåis¦šY¤èÞ5Yòª¿Èê©8Ò\¼N9N/o¿<#ôlnv<|ÇÊzÆŸ+¼€T:^Þÿ@™),Åü¢zbãS¼êcV㎽n©kÜȃ!¬,Dé ©mº—.œ._ØÚž=bHDÕ#/ò”ûÿz†UV¼Lâ‡=Ö]Q­O ŠàüsÅÿŽòøRØ©="âë.€¨“¥ý€äž^Ô#ñp4b0*Ũ5=ëü±]`–S=éœÈJd%Ó9-pd,ýÈÔ/‹ˆãâx¬]2yb!ïÁˆh´‰A+-"™–`£åPY*hRô 5£AßÛäØ Ö(ƒ¤>~úbi õ‚â", UqÂw ¾ô¯O|hëÖ¿4/׆sdFÔV°š:“õ µeç6G¥Í·DWøz½òâ̦*àMÁâaæSÎ_yñÎaËšRk:ˆlâ/Æç³{ËÉtE†*ó\vè§ÞAZtj—è—þ3¸ªSoš9V8)·\¹r¦ç™Vj‘¬9kê¿qScEÒ$1[¹`¾S ž• Ø›¹òÛª6/’@«,· Qv¦J‚­-c9"mXj{1±5c<‡ºÒV…„ß¿Ü-7¼/S–Ö¢Mƒœ*ágkÄüü/äOàïÀS¹· ¡¬@DöØœ >Ž ‚JèNÚC9#«ð¿•(Ž-!æoŽ;än:¬¤7þ¤Þ®ïäˆø†v¯íaŽ^å¬ËdH@BØCl󒆂P™j¡šàÇÕæÛŵKÜ ÂÔáˆ.*­¡÷où•¢J4ü·D"Ò¦UCJè´,‚ˆº¶ì iß”9lq"z‘!Ò´8TÒ–Ç) 7?Ò&˜h‘µ8Q¯Tb­þÙk Cß6î‚<ˆò–@uˆ+óQN'Aà»5e ¤#yen‹‚uffáw(oÀ7¹ª\6çâ²r ¥e{ˆk@óHˆÇ‰VJ¦Ã:ÓDùʾ{åQ¾½1žïY”¥¯¢»;ͨ¦_.†M*fuÈÆ6Þ*¨×~\©´èCY±Ÿ˜+Q·å¬àˆm"5ÃkÑÓMO·â.D^räoŸëýñ_wü$“ÕZL’Xó\n·þ;áoø¤å OèG'¤Ö€ÊÈÉ#2½¤9«Vw£‘¶pժŅͺp'ØÒLî¹ÓR8æDѶËéïñÆ2mtXlÐ.˜Ìœ/m–¬ÞUí-ˆk³#Wg¿»×ìH$Äý;LcI‡!¿  "D Õˆº0‹~%¯L;wæµß 2û\%!M€&5qÍOº‚jÄV±Wp ü¨p­Lp͈fh} ¦ê9‡%½fCž!ß!3tú¶fŤ.1¬z¢½Dé­A›ÏfàUŽÖ#ÿ˜ç}"ÌÀèæjROŒ­ƒ¦»žê®JͽÒá›ò>Éâ-ͳçaáxÐeÊ•W[BË5³îAàwP @Í nhu&=Ø&6˜Tˆ2Ùp“Š}ˆpK½/xd'¹oX[ A¶¶ûBjM@Z±°£²` ´×·Ç BDêÔªEß‘›æM4ºü?îøþ¿À«c¼SÎÂð¾ E°ÃÊýÂ~I±ùÍ$.¦Š9%X GšEË•ª³»áv¶hñv:›a?xS›ÄLl:,§_T éäh{qÜ‚áû•Õ ædŠÀ‘ôFƒŠÀI7¬GŠÍÂVpÚZ½ú~錰8A((ìARÙ “—\É=-½¢€;ïõ!! ‡0aˆ×þË¡‘“Z(‰£“eZ’0#=»ñœ©ó⽞ V>u;4ó¼9dEÏyîo˜/GmŒïÀ¡µñ¦Q8КøŠzhµèd#olüpª_ï¦Å_³Øô¦üf>=X"Êlm*3ÛCNb=_7Ëôðrz€1ª¦;f™OP— ——)èÛ¬i‚Kž²=¨‡;”ˆUW`)¼¢í¶Á¹â$WâÏðñüý–Éc!ÜEÅÒ^;»öÅBˆ3è†ÏˆÜÞÔOõÜt±€ P"w°ƒ6A" Jwö†éî´`m&ÖœÆÙ@vl I›<6£3:† yý%êr¦ÿòÆÏd\ñ ½0‚àiݱ5Ç >÷r&8BÑ¡‹ÇŒŽ¾.|QIâÙ¤…^WèëV&M#Y=ãmqû¦WéØ3ªuij}dÕ6Ö™GáNšO®E´öÐCÊ«H%&'rk ûbÆ:Ó&X%ãï[O„È?ýì+\N”ˆ:y¶w4Ô×m¾¼YÕ“™ ½wš8$.hrU5οᲢÑûvI—¯'& ŸÜµèj·àNé°nn…ë<ÇW=ÖŠÚ ¼€75’¹Y?Ò1ZS-›PÄÚ&Š·1ÀIåuw¡Q@Þ°«w[b5uÐó±gø€}Áæ)á•¶þ·ï¿ýžƒÇB]6´(¾šãºNÀ„›Ã?þ »þüþ $c¿ö7£fÔFrð‘pœ@èee´'ÚŒ¾gH©×Y»ãgZƒÓ5€7?ÁP·l®™ZF†˜ê I"èe”̃XŽk3àÛ›#½Z':¹üòÉbxx”Ú]Ûï<͆ԯƒEjáÏo÷(é“„¥VC}°‰7CåÎ5%‡‘šHËænjÕ ç‘A]ÄüpÍö/©v§š{1éöy®V˜3î‹g f1ÐQ5A‡&W„4”qWUà,'t§&W<‡§VO¨½é›Î˜ÔÙ¸F~©§«ç€+ñ%N¡dg±7º0w‚äÃ,l²d®Xáw (—ªÎ¦ÉŤˆ [²V1"‡‘(¾(K++y:Ã-åÛÇψô%·Jm$lÖ+ºnÍà¡€ö»GÎänòp”ÅáçÇ·C§5,ú·V=Œ]sC`Á‡ü {Ãç÷ÎÕêþÊw³ºó½íª v -Ø="ÁI°Ñk6dàiLµ¢Y&FcNÿTªš7CßfZ-o(©0xÖ0‰^Ì4ãçñL7‡Ù°îy¦`=æ‚åæŒ“±f$ˆÕ³›ð1@¦ÎÿÛ„D›ìK,ÁeñžrWÈ1J…S—ˆ®Îil‰Í×qúêk%bˆýr‘BÔ…ãaI.Õ‡¿n¿ïHóR|ôMÙØŠËžëEF&Ú¼{MÐ}Z[x¬Æé$Q¦7Ç&{ìÜI<¶ã/Ï‹Ì Ñ/&Dy? ÚÆª˜4Ãõ3ÏÛGŠƒ#˜›û©zÒ':ó*޼é¾=hÚ2ßÔÆéÕù™}Z ‡kè{VÓví*³H  ï2Çê9`)‘ö¶êŠØ}w¹+¼\’G*ðº9©DˆH?ã·Ïÿü@T®ƒ_ú¬‰˜°HªÿøÀWDÝïÀàûlø4ž~Avì+R3¼ÓWà.pÔ›,¯ÿ"êuk·„Ck ×”ÌðïtžuZ­ššMÎ1Ý7?=̬å/]¬/ý¶`Ѭ­8ƒ|ºÀ}‚\ÉCŽè»¹J>©Ü¼xþä!néOé+ËZ^*Ÿ6à=¾po„‰æJÑB+Ô — â©tpö ¾¯V㻆V i ‡p1ÁÑuI'Ks2þÇVHf¿;v`H>÷a7‹xr¶á‡'Ÿbªå^z|ef½Ÿ‰Wô†ÙpfÃÜJe¾†åD¯·¼­³m¡; ¿Åð°,ïí@Áõæc´¦Òth^¢ƒ55–²ÞÕunµÆ^3­‚_R@.W÷oá§£òÄJ-3¥ƒîâQÚàPn]ËáW<µŸ¦ {YùéW¬&ÁBjm$Ê·¶V#,‚ïÿ߯^ë০Kÿc$ÄÜb·€‚l nOJ ÜÌþ5·Rr(Í6>}áΨaÁÖ\ë<òB{÷é?·DBX^ Výs7}§n„› -øñ¨‹¾%ŸÀà¡Â [—Z=@n(7ÀasHްk#Ê žÔë×ÑF­±dÑEû)¯“2Zi4Ý¥k9Ã~HCߣ§ƒÌh„tY°¾LÁâSÁ² ×ËÍÓÁÇ÷lˆ~IÑ9T®òâgø¯åî¸ù±–W….õ2%3=5ƒ*Ø_µxˆ]Àø…€=ºÝSæµ’hÄa5wÑݘðÚ1†N–|š‹³!SÖYlhÏ´®E5–¾¾HðÖhåðOm¡9ôD™9`U +{ä±6Á†Gzà–"ö És®ß܃òàž^-Œèêð¤Æ„`üýw| ?€/ n½iK²›Qíix¥€lØWÀƒ<ƒÉøü <½`õÕ é›VŸ<w¬㨙P åÀÒ²áKùÃ;­O+©¼ÛvXdTtXš+ÎÌ蔦@óÆðòð,S‘Êû?ý‡€½¤H{Óšz”ÏÆ)m½UcL4â(4£j.Fųq#öݪ° /síö»–æžf“R¹K¨ £5âêWóM­Ïòyj¦ÂL(§ó,oå8õÔxoÃp¹:¤S½£“dGþlÛø‹?z^Yʉ‡“ÊW#ðá…[˲r¨bŸ»ŽLÔèÕ•Ñ Ø²H„ÍèAÒ+&——¾mw„:{á`Ö3Ói"£7CÜY#?'õ»ÙðØzÀñÆNÚzr³Ýùê'|ÕþÈW¸‚qy,¦-'”ªè,æÖ•NÖ¢7¹ÆÒªp¨¼ì*Nj¤¤ÍTð\@ò(‚ÖåFljؙ¤ /´ùÇï¿Õ ÑwŽzäÏȹ١åLàß=þõŸ(A¹[›Âðmî}h™¹kvÐDl¨Õªòö) IDATp;d\OªwÄÈt•õÁ‘f7ÆQ.žsZ"›íÓ@¸œaØ'#¼òs‡õÃr³úvÜèÉ̉‡Õ¡Ÿ!Yš¿!Ê•.£­iQBZ +ÚoQ" uA"kÒY#+xdîñÙ¾À9äV¹†ÑMíî]§]ÁB,à*\‰·û5Í¡z4;?¬6):yžÍØÈmÊŒH§¾Bç1ÒdV*ÝB«Îq~£'³ œŸ³ Åø©”“Oƒ=Þ¸Bµè”‚Sß;&ã/x™žžù„éñ\¿ÎD 7¿™×?x“Ê+OìÁÒ »Ú–ŠRLÉtU‡«ê˜3†Ì0»² ñ­¥Õï~Í÷õËQ Ø‹°§fœ› ¼Óœàˆ½Y>4”V‹lLŸþ#¯ °`1Î ^j!8ÁPüøäUc¿þþü³{ÍÍO˜oć»ŸGÂ3ýý@‘®†ùÒfãfQ•’Yšã6Wâ ºãëßuÁVÁ»G®ðÍÅ´¹z5#ùöü û´›Ð 1„„hq;%†Ñ©BYþŸ$yl.îlºªlÂÇÎÌxkð@(ƒ|xRÁü»Ô/'o.œ¤ìú~RÑ–Ñjýš¥õWfÃs ˜m²Æ8gêa jIùÔˆÕS¢Ïðß—6’âA‘Ê3Önû¯|¥¦™ZãÃH¯+™ /Õs*äXj - K7°¬èjžÔ†Ä€ìQ*8ÒÎ" JŸñÛã÷ ”-•”V*€',‚Bðßöh cûñ?€‡Ñ§> ™Mµ­bw-6¥ 8äºÏÀ³©yž:JféòQ Ðf<Ö„k¦Q°Öy€ã¿Òa…“‚fƒÁƒŸ”̬Hžo‹Õp„è4±¼ó-ÇØÍM&ýåî•û@'à¾>Zõ‰oûŽÜ¥1ÝA Ž:ôÎšÎØš©`!T¡J\y‹ëNt*+‡bmÑc6«q}àè°œy-r5ÂÔ8€J§Â£EòÉëÖ€“rsOd!› Ħ/£÷æ|yFÄvƇŒÌ€ý/jÖyXß$FžËNÊm1]þ9™sWh½0£ûí4ùdÌÿ¬šÏåhvq~k`à±®‘W³ KÿÍNŠ¥8(5n`ãÙ(>G¤v¨Í"\€ûˆí ”p“‡»÷éO¨—šbPm¬x |øãÿVæVb¿›£µk*áªk7\ÓÑ b{<$"«>{'ìÜ]³¼2 ‰>žÞ8s ZÌ×l6ÇÿzK8ªÏV˜|šƒ¬®€­tŠÊ»œè$Æ èëEÖD*ì·uÃ˰¹Ö€õb„¶IdM=kN~ÜÊ(bO¢Î¨©³3Ñ7á>sÏá˺1$?¯BŠ!^Å“–ê°E+-ž”hàv8™v“<9Y»ˆñ]Á›f´ÄÜLðœÕjÛ+÷æ.#'ËûKÝÏ9ÌÂvUÕ¼ú:³Lmh¶;ÙÞŸm”e&ÙÖÓåæg/B=•»ùe6AãyïxP:C‰0Xó,%5˜ÿøíÓ£‰GaOyðàH Þ#·$±v•ö8Ú½8Êí-ÿŸ‚H}q9€­(Ô¿Xé¾F0N›ûþ˜åÝP蚌]ÖMÿI6@Ô àËxhEdFvزr9e‘lôÊm“(›þ+è „u™Èt¦ø„_Œ„Ÿ½·[Bš‹ÔôN‹NK,\™€ž]\Æ1ú¦×fû0šO,<ݤ+äD¨’+=(ž±á. û—J=Ï!hæxzh”Yë©Dv®0WæÚ ᬧµ]›æ9JðöWf·¾BÁìY,Ç^BJÇVœt‡eœÌÚ-+»œ¨Iç”0™ú™Z¯ø2g þÚá‰çê<ˆ{pr›¸”(¾‹D³A_˜©~¸Rð4½4'кÀóµ.´c68‹Å°è^æZÈÚÐ(b,·§wéI·L^k5" –V3SÒ Dñ(D˜$øûÏß¿e°¢`§¾ñkרÍ– Ø ß#¾þ†½šðin­2׿ lè‘Óં^î¬ +÷R ‰àyžŒ…ÀÐk9«Rö“QÆ`±>Ë»¡Rí¦}¹À°ìª2œŽ–;aXÛ§«‚ewˆrµÇÉ2WÞÄßô›ø ¬¡äC¡‚•œs÷Ú}ÏhDcD¸æH³â™áZj€Cl½wîfÒ5!4ò„£ÂîÖB aPžóD4@Vw 8¬|ªS4¸jp\}o‰:,".Cê…xÆ% ßë°¤£ÓàЉ¼s©§ÙPf"_ñêþJÍ:ð¶fð8™ÕàÝ \mw0»NÛ?êOb„ÁjE|.ØÕìOäʃM™¬F±¾.xÊ ôk¹ÅGqšÁ¯Gy p@ÈœÕ\+8 GlBÔÆCòøã·ß«w/ƒ‡ -zìW 6Z)á_ÿøwäA:ø—)X4cž6«£ÌÜól§‡²ì°çP"¾ƒ#€:MªP[¸Ž7=T0ýf·¬8›ÿÕwëSÇXš V0ÌÉólèÍõåN,-7÷P—¬w™;~š ‰ŠyKïÊuhÖ]Ø)~†Pï’’{¸ôÐë<µÀ¸Æ„h¦ínæp'õ€f M ”¼äLîæž ¹Ó,0>Až#@y¦ ò2wX–;r&&Y»®¯œ\ꞥi¦§[èÌj³f9åôË8ÂÃ.äÌrSÀ•“į‘x:Ù×ÈI§Ó¨XM™æùåS6-N<µz‚¡ÚœèZz˜aˆÇ9Ìã›s—+§$±6ìg À•òññ(1UU‡Òî©­±ª Ø Eì{» ¯ô$©`|Ýï{’‹ÀS?k?µú6)VA Ô€?þ i™qœr’ffSkÓìñ¥/2w…M«Ã`µ¯€ì€ì@€#ìÜ ô+À¡—qs0¹aÙTž`LâË%†µ+Óݺ¬±éá®çfHÞfžØÓèfÎ:c@xC1Ãv)æ WcUÚ„ažž´R€“ÌT’¤ƒ½f¸ W:kå ©ÅPÜÔΔR¤ØUæyé$©±3ÚÍ]FrXæD<[<è(òl2p03–éÒ’fJVt`1‡fè ÉW“[&óÛ_OúNšyO‡l‹ú&zçL%ý5 W5ëÀÄ÷ãSeÄ,–«ñàu$WM’kIÜ©iâ¹Þb¤ë/w|g>ç’«ˆ÷†ñt…aâl›OðÜYäN>˘Å=r¢Úšsg·ûÎ,-™-LÛsZ̳/WN$Ê>¥V TdY6xòTž’yÍp¯-Õ‚5X4 5`³Ù2ÕEö@)¯þVDb^¨¯,£Š»m©r¸þ~ÃÏÿ‚,ŠUÑl mïb†š1ùáÛ¾1©DfäUxc¥¬¨»x<>—^¹pÍgr*èuf“ò¼ˆà¹ =“ãëLˆ/3{JÕ ]ðXp‘i@áÙ‹ÊBòunìêÕÛ÷Í‘œb¨ñ&9‚Nù]¸ÜПIy¤­ó'xþRò}©ˆ–“¼©^Y¼BÍ@ú³z(J%¦Ã²&ÐÕ8=Ô+êj6ÍmdmŽno»9“ظRàÊ Y·#{KjªÃ„è‘=§ïß~ϰhöÌjÜ©‚>ÕÀ‚JX~ü†íðì…#æþ•çk³ ÏÓÌ»²aáLr½DÒuy&™{ÛÕÔ?,ˆôºøÃ/ Ö§1·¶‡ÍvXÞ|m­j¬^úP°` NnL—Iç55ë]n~x­=4LP(Ýýçr”~â[£/|¢4¦–¹ çPRÏ߬çF¦Í=©¿ •hÅö ©ÄKØ`vÃÒâ“/« y~™6þÔaÊ¢8BØ6MLÄaëñµÝãÙ?KN’óٖ]†“±ÔÁ™ïàäÌàËóæQNô…³UÖ½: iΤÀ×Ôb}n¶0= §/=ÙöY[%3E§]_Ôèuæañ¼]±%ù]Ù–e1UË 39¯n©¿Ý~<èÆ–*D ·Rá¹KG6RÄž£l’xúñí·ÿÎÞu¹qdÇ^È IÉîÞ{fÞÿ ¿Ó»ªl‘Ì ¾H¤L©ºÏ騨PÛ²K¢HXX—€¬ð¶,hVUoyUðˆÕ„'ü7=WL¯ºfÛ%^,u ѹ]Õ(-³˜ª#Ø¡‘Wˆêàkƒ#8BdD ¡@eœt)XŒoÂ¥o=›16Ÿ­%ú\·zi+9ÌæŽìG0‹^…ÎK£ªÐ{nÀµÐðÀÝÜµŠ˜ÇP®±nÞ3Ñ•ˆÀ±<äWàV –Á°ó!¸?§E™3|eÏä–x019Mäp“néÒÖÒHFp“ÿ&›ðNŒ*P˜IFéî³ÊóÎÈo Eëh×|ê$1²Y±ùŸë"<,¯xXÓQLÝ^Ñî/æųuSßG#´N¤V?ý”{cŽK#Ï£QßõÆÅ;ÈF‚/“Ú¬êÍþÒaÕñ¾ÛwqþÙýRDŸiùÈDµ°‹”åëQ—æÝ q¦ðÀé‘–@) ƒÉ¹úkû<þ{mB¿`$nd¬ŒH(Jíq£ °ÓƒôeëûanäšA£´™³àк–L ËÚˆÁÔìnæÐ‰õ $TPŽÇMâ„ã‰)+áÁø25ôÞ 7ÑÐat=½kˆ&ë™|Ý ºÌÝp¶¦¡‰®5KÔúuV§¾ýµIKrâZÝ÷íVœ+ä?øëÕ ^idN”Tñ /zÃŒ@¨U}âééQã´„©Xš©-á ”IÜÙ{¦´Ÿ”†î“ÖO« ˜Êø{²9Ëi’#‹c@>#òuoh¡T6'uôÞ¨¹«¯ªMÜK?¢f£ ”%JÝ£ÙX.8¥ëÈ’¦åŒ<êÂG!ÿcýó KþÙaq Uê(Aó?¯Q«ØS&*ÎÃ3*ûJâ„å%#Zð©^¼"Ò>$•À¢1ùNlmW­p™BD^øÈ·åP¸j’…×Û'7±­±t)cÁ¢ ¹±Ô‡ÞE胢ºJÚ‚i|h„™èU·u)ª4Y'Ï Á:© mpüÌ,}×dñè^nÏñôŠ1×¾¹ç"fù7XÛáj_,Í!ž.:ç¹ÃºLÅYŸVŒ‰¥ÆùI;PF¼ K¤¦L‚Ša ›ôL Ã*biùÀ).ÌJDN!ì÷-¹•à+=ë©7æÕp1íb. kùh•ž l÷$ì=S4’¯Êà»ä{«µëï²TìM´dàÛè³-’¬C&«+UWb94gü¡¤{ÒΈÆ07™šÎ6"˜6Þ–»TT0uï¡£Tâ®èM$ Ä‘ö¸¹PŬ´ùŒûNP˜Y7<t°À¡DœÒo¯ÍG£@kdITÝúp…›ðâ…1¬‡kðx§µð|~…ÓÛ™±õb2•׫¥#,¾´ÈÆÌHÔªX²C ¨@YPûOîJ ØõVÚÏ­¬pèµÕó.N3Æ‘Q‡'U–ö89œ¡U®gD˜Ž¸ý‹~”é8sîÐT°.ÜçØE2i޶bqúG¦wÆFuõûý|*ð+„`Çkkó»ö°ÙÔT…)6„ŠƒZºIÖ!‡œ"Ÿ;݈y ɹBw&g‹S;ÿ Þ™!MÄ…&Æ>«Œ7€lÀ]M¯¾Ëj6–$gÂVIÒeìe¼ô.;Á‹7}yÏØ|IøœÓa/±püY­fB*z/{Fž2¥y”¢užéøåã;Èæ9EÊ9g õNÖÕ7ÞOZÄ‹öÄ"ƒ^iŠha3ø®šV3x¿b—2‘Ä\m#ÊL¨8¥¸&O|¹q3gIjÙ¼gYkµLcšÂeE?Óèu‡H$J/öÿÁËÜD¯Â$gv8O[ELáíV|³Pño×…xcÈuášÖQðúÒpb^Òxß¼t[Ý?†´ÛZJCG˜uY<ë¶ûë[Í;·°—%¼¥A¨Á)õÄÍÂÛýÇE>bµo ;ƒ€pŠM¼L…‡çZœûqûóŒK{sA·„Qm¼¼Ú‘bºî^ιÝb_ÔeRR'%{ŸúÝ“Ú3 ðž+"ÝP3Ààí)îy,÷/Í~øTô¾ƒ‡%m¾œq™§Qñ¼øÝ )>¯°D/|þdÿ8wpÊ~±œekqTôõ:%‘F5º^G¸ºâÊ ~-Ÿ…üÂçúãÏf,#Ö4Q,2BisÕ“;ZÔaÀŠCufnÃñ3»Hž=­ëá< :Jåµ[í¦±˜8kÎ4_É0 êئåW¦LYˆà2B">h_,d<ç+–É)ðâ¥E¯üxÍ^R´ø½°æ÷Aa4«¾‹¿XkÑdR¦—à#ÃòöãûM@Ì-‹‰Mp-ÓaÅh@TGXQš/`‹ºÒJ±!¸rÛÁqô”¿qË_È®ê¼#1¼"ò‰‘Uy._áãëóƒ‹C#ÑÐa-:ÒtÈh¢º\R­kt-7ËŠM±ÁdÙ Y×ý™qPÛ~xºGŸ„Û‰QïÊ{hr1$³O:)ái‹m^zÓøÖü0PŒ 9pd0,©kܾxÑà‹cscˆóΫ’9¤r~< =”wJ(À­5ºBžáˆ9Ò) —I’KJnÁ«^Ô49mµá± døJn…c&v´ÆÓQ!{Ða+¯ä8K¥iqA Š(,—-V•­+j-DœAÂÒâë"¿ŒýE¿Î¯Zšàµü†+__­ðè•Ç^'ïö†ôÊ£ù¥”‡^é´/nñî yÕjêÞ !ûÇŠ&Ç €H†|3;QÌ #ènLÌè.c¾GõËÎ ì\Ya‡& l¦Z"Ü íd‡xò”#-üë_Ÿ¼88BaDjʬ>NZG‘Ëá(cÛuùÛ6VÆlP°°ÆU…} ¨õ_•±QKEè¾ÿÅm'vœÈ+jË?rÓâuèƒsôÓtб{r­æ #aAØš ƒ!È4+@~;hè "¡£Ð3î´˜+l~êŽÒ’ÅZ·Å`JÛRW_aã“÷¨ ‹Ð”»Y“òõ{(ä {"”àw:ÇOhöåÂá"?roç¬8—åèzÒ”‘®ÞB¶ñÕŸhNÒ¦rÚ‚UÆ“³Ž“Q5ðà%·l¶â{g¡Ç­ô÷ý…ñ™þ£­G±Š˜‹û¨0ç³5²»Îô\<É!ŒG`Ë&^é¾xºe Õ5Ö9’UzTœ#N‡R@^zÜ͇ IDATŒáeïó÷Çý,+"™I£½ÏžÉ/3™˜G‹šb\jxô×:MÛµèƒS úb!¬^°þþKç¦C霌BÈ8y˯ÿR´+iñªªé¶8ôJ9}Q}„qC†Ñ;І = ®¨„=‚Š™Ÿå0ÝÔÜ$Ùˆ$š®‚Že+Þg B+¼Ðä®qr£5Á¡nØ3B@–¯|R뿨Â’z«sK<D=×ûôwÌj¸¦qÄAz ØÌÀíÌNÞ™û[oFëÜLS.7'ŠY£“FÂìþDfÝváœXÇÍY½N#âÁÒ4³CÏ}ÿ}ÍÂÈ4˜ãAüôù¥¾4bæ-$Óµ‰ŒË§gKû‚óz±°q]Ë×–—–[gƒ#¦5}„’Ä^Yª¥À¯Òj w' ËV ñ`rÉSùëP¢ÇBÈ GϤŇi3hô|)õ¥ ºš!ù<¹Æ³QFçq$ìZÃ>0msÁúþ4³å©LÔSiø_ò-Â!ÚàŒ¨Ýwý§^p>†LùÓÖô¯Œ(N÷…˜L!TSõŸ…ðÁð„›òࣞ’ÉÀ[ÅÌ6¢QØX‘¸ Å…V®ä+ûBÒ(¹viðoxT5ìÎDUä]bNäP%€G"ÈBDŠœ y&ç—/ÒaKKxîþ=ÁÙ™SÖrD-KËUoæÄ÷ÉCÙh3 ‰oܳղÍE™xð˜tr4¬9mæ]P-~e&ôr7õ›þ‹Þ`Lü #{g[J“q®È0Yny²0íš1bP,†×TÆ9ÑOnYs‡5é'©4$øµ~n¿vΠ6Œd!Ž:‡"‚Ù€‹MÐw'"$÷[‘3TÁCÀ-[¤9e¯{/¾ˆÃË<6êgšÞm‰p¥jÇm.XÀëïêëІ)ë¬{2N¿²ì ç¦sç®ãC9`]âèFH³±=èE0ÝÛ’jJý 0JÆ[“0 åê/àn²ÔòHƒ€¶*?€L>ÇŒ“/ØPèÂÎSË»–ƒäº`×޻ݸ"NÆ'5îPoØO,y£13Q äPÝR]­tš,ƒlîŸ=^8MtË}·ˆûÅLÏMʶ_ª­Ï’çSÑ­ç+;*yðàË-– úNS¹¡‰Z߈¹ñëþ•—ÖÜaÑ+Ø‹ßÈðDãz‰]ø—[BŒJ>É…[hˆh<‡ƒµ}&z¥Ñ ðm4Ý80– mUºX=*˜‰8"W8€êŠ3!:‰†r¨Â’gP¤ì¹dò+¿ÖÏÇ¿6x­Fà—& ^\$/ÿ%Ñh¶p­“•©,éÁîíHȃeé4¦±È†/H~î#ãÖy_À׊´¡T”ÓP"Zü~Ýã1Âû‘P]Gž=MÅ+˜ƒ±€Î?ðW@2·= :EëÓ…P‰HÁ§åv4wö>ØûÑ–ƒ KËúÕ$ƒ^¡òŠVj gíÀ(çdù†ãú¢£ìØ`d¿•ɨ¯NÖI¥ŠÅLо01–\L„¯ ¡”Þè{hºë¿lÇxâ|]^R™ññFƒy©elkŒPàXÇÿËõìÌe^™‡a ‘ÂØßçΠ€P2-ê1<¹E¤îÿÂB ó¢-“í{@öT2‡HgDª÷ÿ9üÚ¶óÕ8 ó4ØÐÄ ­#ˆ@“D‰§ÙŒ„—e"ƒQV Àúr$üà –YçÉS/­M‹K 5<(ṲÉá{ñ¢õ¦³áÜ´òý7Œ4EYô­Ø%5ìk!÷šà@r(â/Fuíš»ë¹r³ Uý¡l̶{ÏYŽpÇI˯õsAJ<‰[Ctm?r3ökVËêóç ]q¨ä)Ž4 ¼¤û®¼òä±lG³X覩ll’œ–t˜ÑïÒau†F~,-ée½acÒÒÆ”” X§€WŒÛ­ í9ù58+¦èUnÅL΂y½xÏäœ=E¯æÁ+àÌüìhX_!Šs˜ã9šÅ¡ÂåÆ=ÚûFµX=~ëÅt=n^6/†ÕEð <—Ûú ǹ²#’Ô>Ϫ M±C$‡š(äÈ¥ÿÏö¯Ý¯mÙÕ©“‡ ÿÊÃnÆêûxÛ2ú®]vˆÖ0Êfôôâ‹‚uׂůâ4«Ç‡^í7½Ìú’PÂ92áÀÀcžà¬àîë®4úoí¿l^#L[?nÔ.ULªéðŸfTøá|ÛØ~Ê)hç´Z.æÔ)*ÐÛËWüÈtÊü3ÑB¨Ÿ@jö“ÈðE‡DÛ‚™‹*¼wàL~ÃFu´Ä“3¼úÿu ÄuŠ nUMUOæäè3&Wx›;wÑRôîR,E›£$½Îrr1:gÁôv4Å.ëÅ2íïÜxÒò´.äWX8ýÖÝ¿mµ.ð79¿"»Úÿ.2&k½™›F¶(j5<¼Ž/ÅO/Å.ôqæÀ7=côÙÅ/OE²ÐUà%+LR;Ã^hÒ9RÎð`Äxÿúã^áPoóé^ì¿ñ^žÎS J“ ccU g$M8Éi@C‡õoƒ{%Ãì²ä®l˜¤›V¡¢Å'»ò9Œ!yd¯ÐÌqê]®/£ú¥ëi ˜ð˜Ùêa7ÉŽ|4ïWdµOVZiÒÈîNÏËzÈ p'í·Õ‡QœAp`TàúºÐ£3¾m‡âå*Héò½þD(ä×pÐ-SõšeugÞ¨7²A~=j{®4ºç1ó‚M~ºÎŒdàc%O—(ð¼5wºôü«1[Ëφqü>£¯X£ï ­ß”-˽º4\ôžëPÇëâÉ“¦85R€|à:\æ©8~qWuMzH͵éIÝê¡aþ^oñQɃ yw±í"×— À¡—³Sø¥ŽjàÄ+ýrˆôt¤9Í&ŒßoÂðF‡YßÜ .;ã<Ú…—‘Y™ÞuXŸÓº1?õh\’ŽzÝDð[jïá ã l È|G©À‡þÌ©b øV®4%NÍÞ4Î<*ÁŸØ=òŠSHô,IÅTîüÐÊ&IAa0¡¸rwxc‡;= ;GuÃ#cñ¨ çP$ ·Ož5Œ§À{ÔŒ8†¹R/Ôèò‹? þu“•Eç~X¿¬ÌR¼êx¬V—}O[žlHh`«ã6h\ÈJÎ\Anª“—gb,In´Ã4:ÐäN3›:Ô Â{”þåÞ0^ò0è:нçø‘6/gUwbÊY¼d²\,ë/[Âú»U#ÕVÝÊ·íAT=Õ€’e‡ªxpq¨Q|–Å4I<5ÒñÇVœG!xÆ ó½ÚØ»÷Èâl³S§Ç0—;BV6Äé×ëOƒŠ•±Õªš²U_Ù4gÕî³”æI@úUkÁ—Ãá€#"ÝÀ|w-~7m»ìÀ˜Æ2ŽTÒÝ RÈÈ"GüoÀ§n&‹!¡ ðåu¶µ: +!4öY¹…Çv¯ÞßèA@BØÚ? ¼¼ã[b/¥ß©4V²FìÌÒŒ(7:™QÈç·pxWšò²‚‚Qÿû‘v] è†ÉÕž&ÒóŒ‚xC}Ó“´sTšbÝÚÈ”© áIå3Û+×) zŽPÄ]!›‹ßlÒñ[Z¼û»>ëeÁºøÖi‡X¦ùl„zv!EÉY˜¸óº½ŸFB“†i”P™•œr\¾­ÕSõœOо…:€ÅüzÉ"›] @…Lôíò÷ýžj€×šES¼&^ó<%øÕIÄ0,2ÆØÖβZ^ÒÎ1ÄØ¶Zݰ˜uãnæ©U Ünh »þ ¤2aCk»vÂ#âŒÈ Ò†ZÀ2ªŠÍ?ôW|ðx6©n¬çÉ\ÊŸøú@ ¸1œQðØMªM*ªªÿ”%£(­˜*ûÇz«Ñ„̾’87ðŠCìeR’¤ŒèPWì’·5Z©à¬ ºPˆ¸²ËÉas;y&ÏT ©ñrS fú¾øcÚÒËž¤ºe¼àêÔÕ×gKß8ñåf?x7®³ªÁ­¦a€Ô.>Ø–~Ä“áÌe¥Èï…‡4Qðÿ–¡ŒòäJP^Qí/v†³‡›Å³Dx-X4B÷ýÂÞ ¿áeL£Uó^X~žë¶îΕÄÑ“)× ñ]Ä#.•%!@ÒDÌTœ/??ÿÌ. ¶ áê€tqߤ©`»iÉ‚Qej»îbŽ£åÁ³áT½è°Ò´nL¦`íf¤LºþìÓæC[ÛíZÝîzÁ];vÆ7¡Éá+âˆÈލñ®ãC®ø9RR/¾¾R5ãûäˆJâ‡Õîª~šþa®Cר‰à•(}.%øL¾²Ïäks@pá†ïŠÀ7<"N•>Ö€OñÏ’ûX×sÉI`ˆ™ˆ ÕQ Kv·ŠC½C/ 3ôÐ*Ö¥`9“Ù3ú±aEôÌS ·à3R’­W77í«ø«‘թò=T™å{j úù‰7§ ¦>µ$YöfQÃhYcþø@‹r$àD%ª¡¸P½cPæP(Ö^Û~и mC}~¡¸ »GOÑ$bJÚ8Ã×H)!Þoß.0k ý`òz´½1_ô®ºPÙò8ýÙäm?:jÁÜ$ §Ôžj>Áñ`FmA÷êf‚Ñ_—ÇM&M~Êu2غ¨yðмþÎŽfÆÎoöðΚ¦Ný.­*¦8XŒJiéU]y y²¿tXÇHECÏG 7–á.ãæŽ˜˜+ Ó=׿?Ç®‘JD®»¦ïA  æJιòµ}œFxD¬nڄѫ٘ÔU…Þ-SôÀsf\ì X×úcÁbÜ›¼LY©Žµ¼jm²=UK`ÝÙ8žÆênhð§"\}Û¸Fvø¾á±!U­Y»V;)„™ñKSŠ¾Ì /Ø•.³Ãψìñ‡AOXµ :ñ—qC±usÁx˜WÚËF‘Wò™ƒ£šò“Áà2‚ü)Ø•èàWœNʼnJ—?º `Á騮؉ٻº¬‡wUîÜÔ㡯ƒY:óØ`ÏlUZ§¹HlœYË‘a‹˜NX™¯!01ÞýÈe¬[ ÿ2,žÃæ¿Oz €gÍ;Ø:9Òð”ÿx©b’/ãÌä’‘ž¯Ìgf¿g7. -ÑtÕ›ÙÍPW½Š ïëmùv®0œãêè9zTQÊlÈ@@f8ŠðÅ#ÿïÇïñ ¦ý÷ÖÌNTÈÀÂõó˜>ºæ½¢—À`¡ÒØÌÒïTôì¿LAª›/hàÆ3 ÇIÔ‘Go³7íȺ÷ßM‡Çdz±N}ÿ4Lˆ‡>mQïÁã›=Žö)ƒeú?ØúPx^Ú±úâÄ{þÏv§¯à+ DdB&|)èn™ªèIf„¾+!>ƒƒ;h«ÑŸ”œ‘S¦àÀ.#†«Í¹¡³´t?ølÇœHêWìâ«•á# HïÖxz—‰˜õ¥ zw cÝ9Ìãb ½‚®æÉñ¢ Éæ f9ÝÛ QËuA4Ó¹™ aî”4qÅ0º«vöüŒÄó+êÃÅó÷x&Të÷„xzѪ“#ØeïY_YAô­ý¢Ë¯†gåWV5Ž'—Të/·ê)1Û÷(9€¨b]öÏ¥6»òÊà ïQ#rVÐá*È£:ÙÎÉÇïÛ=»È;ÁIúŒü¶©ñš% vmâ•Á”uÿ¬ à þ[Ûú”epi¸ûY«ÛOõiƒTýZ±’“$žb².úu»òÕØô0 ÅnX^½œFXz”?èWæŸàŒXA„šá…¥ub)†DZá;3« }úÿn8h,-DJÎUò` ZGÎÑЦ•1I¢˜Uj‰eL¡ð£§ŸŸläââ¨E¤Ñº—±1¡)·Ìþb xÇ›¤~3òÒÿ­C)^ÙK¼d¢¾´¦yÒ3»ÔÃh..€ÎÜ‚˜ˆæ©‡êŸEÜæ°w­aòƒ7Òï.·ž=efbr¢Ø/‚ae¡) ‘Џ>DúH¼xW¾n§_9K2–T+&Q•Ü"I«…˜½­YÔ9]JÊKëØÜºE+‹™š<_)I£±‚‚é°7<>‘œP„މ…â< Ê>H?W…‰ÂNϲƒ†MV5üÒlú¯]1£ÝdôlŠ…­Zéî [úÌ“šÓX~|ÿR‘?P;ŒS>û€/ý0ûáH¨õÙãg@dj _ÖVLæÄÀÍJ_sïP$ßœkøZïÙ‡Œ˜…§CýÀ—àSv æËÝü/!ŠN¢ÀËA Qœ¶b! sÊîá+x%ÄgκC#Œ@¿˜ŒÕj¯YÉ„èÁ˜/ÛAî\ ÂU@¹ñòÅ`Óvû’.ʯ,çÆ—Ì&Þ¸˜^V©x}úâ}HÞ,yRŒÛ,z fåÑJŒŠÑä±ÃºHfß‘).Ô­‹žôC=E ¼®<*9§ùŠº.ôJ$„Æðu ¾eµÖ@¹’gú³’2ªçJTUv(ä»&‹{,ùzGúõHJÛÕªl¯\Z1En$©Oìà¢ôv$Üð¸#$´A%m³—Ñ3Ñ"5/»Ðœ ‚cy L­Òg5ü«Fàœtæª:ýõ±hÁJªÿ Œ“IÄ%A’G#/û^‰™]ñ.‡PÙUx$zvuªºxÔdàO-gÅxÿcØ‹|÷HÔú§È„//‡ñXPÝD~i‡ö¥¸šàׄý5¢nŒJmï–tϦÄuÇf.|°£òé¿q¯Á¨°Ï$½"#lx0¨ ȱ´¯8­8 !Ç{ µÆd‘~-|±%øL§žßÞØ»œ‰÷¦K Æ ±qbQóðtx©1ü쿨(_@± –3{v»L¤W“—óû‰ô€WNÊõÕh†)l‚ÿ®oš‘x÷Œ·ÎtnÂæëø{ªi©Â2Sü©¶ Á”Qײ×"Mã¹ÇÆ °Ž}ôK„‹µ0x^ãáK€…C•Øs‡"<2¡–FqÈ­ÃB-m‡X¾ðQºJT<ÁôY­lÉŠÐ?x9£å $Ѽ!Và›wµE(P4½é³ÃÒ‚ÕísÅÄNê-‡žBE°ÒQd[À´ÓÊD.a)*PVŸ8Vv¨àèž.‚‰Q¨MÕ¬Üyð*Ñ‘çéäµ||kËö茟„B¾<¾î(w¤;ª¸Ùˆ¬úaÑØÁÇ(²:d8ÂÚÊ-Úqèô7Hy UYžþ 8Ò^7Šœ($DI…+º Ìú§ ¸Œ£¶Õ¡˜˜ÿU¸gõ¬ã ùÀù›êêe;g8pËÔ„]?^‹'ùQÖãU÷Ó*a P¶iOSiÜ —@àç…S¦$‹9ð¹ŽÊê˨èFýÙK8©Naˆ³‡ Þ$YðT¹Ü?ßÑÁfrÖᲺËn+ë+(«=iÇÈÙ'Übþ‹JiÙhjy,X£SvrÀа¥{øv\±€îÒUAÇ:m»jÂ"Qçr±Gd‡úÀ­W(o¦Â©ÏbÍHGßB‹˜µ:},àÛ± sÁÚ°ßðÐK¨¹ÒOI$‹@AŽÆ‰(4¢J. Ëó3I=9f2Bñ^"gk%>•UdOÇH&óâ—~fßfØ÷‹6b¾ê¶Zx6Ý6ÞŒLø¹â± ”¸im®Öϧsi¾áç†ìÁŒB¸ÿa½D‹©Y øÐ«ð®rö•yqûÇvÆåĺ Eœ²O¬]aÁ„´%¸»4b+öÚ±]Lµr{šÏð+TØòK<ƒobƒ¿»Mâ(Ó¢>—TÑI:›ù1L†âà¦ÑضVKI9® òÀ‚¬S2F––õ´n¥ób÷*ÀbN¯˜}µ~CÑz‡aÑ߉«/v†s¬F6•¿Ž0œ…áæñ>‡wLài5 ˜¼‚8Þ]3ÅWÃ4;DRü‹˜·ÏÝQu¨™=‹ú^NWi»¤Ê(!>¡uöE®t†óȽNù¡Éj£¢Aµª/èxØ÷‰Üax}¾¢¾“Xž.ˆZ°œ7ŰjÛË’CZŒ}м™Ø¶Û¢9;äݦVÅ\¢ ‚;ðZÉUçŽm-ðÌT“k‰Õ_€Ea¯›eÇ‚Ý2¶€]i¨EÄ„|0~rÀwÀ± ‚ÿ—:'u1õÀã9ª4#nF—ÇÀ“T ÏwØëNÈ\áë‡+Áÿ ?>ðå¸VjL<ù$N, Aæv±-5^¦’Éê”4ß ¶”=ï%&ƒ‰Š÷Ë–Ô‰£dü!G ðÁbÎ)Úe)ZΤxÖÑ|Ì›4—bP-ûö•:È€Ëpµ^Ñ¥‹oì» CšÂ/htѺ8ñ^ú5Lêe~“,ýR,=K¦o½4Pá •w“ˆºšS)T½ ¨ç߀ay…zɈe»kÉ1Üìæ}î“Äœž ŽK"Ïå©(@_¥/®CFÔ$ ª:02ÜŽUêNhíÕ0ö¶KÚ4[¤hijìlHO–Vkñ4²¬¼î°¼a@hÁ’cH}/–u Z4C”áN,R°¤H)ÏÈWø„°Ð)_®:KnÚv}kºëù Ü€Ìx¾¾ÎÒ‚ºëœø£íQQô'~8d׺*Ët¯Šµƒ¾#Ä–úu'TF%¾Ñ÷z/Îo´g‘rDªð&âç|ŸXКÞ(\Ó„˜á*Bt(ð ±4¿ÀÉ38rζu¾ýBnŽO—µþw2aUÙ,-Ü~û-oÆ9gš¯dÐcË MMSZ=¸kä*Q‹Ÿ8;a H{Ä~ïO1÷éPîð¾ÁÈ;=é4¸¹ã™ÐÓ‰Y;¯®þIT>ÃãF™}%—9d A6€ 1c¯ ŒGDg¢§tµIéŠÃ¡z|d„I@Æg¡Æ˜÷TüZKÅܲs²’¢‚Ú/†R§¹Q'c ÜFk\ãM9»$„”§Nˆú*·Ûñ`ajѶK‰UV̼®{uUÛ°¡–ëÝ«ÒP€­KBìMVн¡~¥µ¤“’Q‘Ô¬Ù´ZÔÙª—n©C­¨~¦5¤‡{Z$Š´Ç±îëØœFˆ—~zz–{~ö_¾ÛB)ó[‚°(!&ùU;6¡ÑXÇJ.S8°ž´ç¸Öâ¸6ÂTÆNO`k×:Õ+×—Œ÷Î/Õ€/é¥VÂ|2~„Óã׆ïˆZQà犿V|ºvOû0½¤'M2ÁÊ´?¤h2DàpÖ…6>iɈ$¹.2|OX2¾;×Ô+ë±Õ òXþøBa‘a“üB~YNïÅ^P‹Ž•qT³›>Œ½X2ǤÓüŒ{")ÖÑ­Kæ ˆF=½µ€¨EŠ_7ç‚euynòx©#ÃÌ#df·¹ýñÿ@,Mÿàï¿5Œ¿È§çZVÌëñµ­‡”šd–©ÉÜÎÉÝ››ÀijSÿîCegÝ^ïLÎÕÛºKŽt!G ‡’°ˆùLi´Ò"üåÄr`í²Dó§Ò³lEß$¯\SRA÷E£Sü+ +-8üÕ…U¶Ãê jCbkÇ„(¡¤‡†aÕæo‡ŒÈºj¼ ñE{±Œ öÁþ†=QÌ a¥S:‘/|ÔàbŠ1ßaã&À.À7›õoåÇßÔÝï0WÚtìÊb¶ÖWÀ<ö¨(~H´ ‰½Ì³1š)mÝâ‹ÎªUÁ¬ ølÌÅíî—óÄÆ'Ñ©;®Îu8°È66!Ê= &©I÷¨wgòÝ<À 1sQ)¸Üv.ŠWMȒ<‡±TæîM¢IÉôö§M„­ƒ‘¨pxºnÎ,ep2`“oh ÙX#ئÌk‡r š®#¢Èï ŸüÆ£æeÚ3½)Uô[¢&;¼J½êIlHW_AŠÙ TY'>on6d²E,ÂEf‡Hæ»Kž•5žL$ô#GEòî|Ynº ‹C=°’†¡Í†Å6©”ª¾RìM–kū͉}WH‰¯mÏ8¬§3<®>ê=ði»¥—㦨nåÌvXÂ!‚á:Èw¥`Ù¶+!J/v`“Ÿ’ËU¾%ß=Wœ'bewÒºÓZW.K¾ûV’eBlÀƒE4ÓLÎd$üP»ˆ¨tù›ù7Â7p2¾þ¿æŠR°Å!Ñ3 m3SRGêáÑÛ®“p˜Ó}Á‚_ôIÄ©°wÄ"€ˆÈö_ðâ/§Â†]ªRhî ¨“õ {w°!p¦@¨ ûäʶî•´C¦Ó´"§Ùú¥)n'h1DÏàµÛFŒ²š.ªÆÍ¦s†òìø©€N=™ÆËÎËs g•1n$p^Z-z#âÁ«¶‹Þ'Yü_¥ZüÞ]Ë®/ ^{k WÛQzz-ûq /£©ƒLyTS;#ÏØõŸyn„*Ø<¨–uÙ«#"8pÂwßß ­tóF¨V)O¢à È^+”ÀxAßKG߀ïÿ+̉ÃK “V‹Q^€îiÅi+™3<ÓÕXJf‘!gµ¢êˆè®H¼C[&6ÍKG¸ÄœsÃ!B–Ƀ2µ 0è ÷ WÉX¸v‰â¶äC>m¡ÁI+áFÌÕ³©¿ÕþaÑjÕÝ&]ì!I„Oax12#)I^ÊЧ^zƒº™¬ùS‰½xš”€Ò.¬tTò?¸ÞèAdâ5<®S=j'=”¶UQ<–õŒKeWVϧk¦b1Ø!pA—vy¢‚P_Zξ”íµkpÎc#„°3vµÐº@WÙH£%ç"¦¿ØMÈZfJe)«/Îò qåÃSÍ7Ã;Ô³Q"X*8€ ‡LÖDÜ|B¨.t`…C¥î/ãÇ൚ÃH“E[{eo¶zÉô_i$w[rVÇæÙh3è9 ˳sc>+Ibe4Q°´2y´¿Sò?.Xxïëð·õë7rH›)ËÊÕtLÖ6+Œ1n|2ÍÌŽ¸¿µMxsÍ6,k‚ƒÄ£8Ck;«–‘F×oÜúÐ#[«,‡ü…úÐ+ý"«Ò0¿Æ°"N¯æô4¯A×øÛ­®imÅ«›œVCÎkšªè»bXΚšöÌa“š™'×T;ˆI«K²a<°®jF¼cKX2üŠC.Ý ûUZ­…NáI|Çû×´…Ê !3Ž‘‡µCˆSõÕØu×8Ä»PƒV®ŸÀbRK£ßÍ„‚D¤ob$8{:îkˆåÿÉäÑc¬ÿtŒó†ïÔðRœX ¼´ßÒ”mØÏÖÅ9,.É1{ª. ûµD—q€‹z$eí;$u]à $_Fñ3•¢Uí$S6,×ÁMk¿°Švï†]È™‘RgA¿þü,5 q“F7N7ÎÔ¦èû¦µé[A«‡~·ëõvà§.«r²BøÞøz‰S³d2-„Œ|eqìé&&’Œv‡‘2¢ø¨U%£Å‹E߸E:_½#QÄéQ‚ªXß.|FJXB¦ÔVu-h:ÛÒhVkqÌpƒ!‘f­È}«xšâQÆâåL–a$Éì%…_jâ(Ä(ÊUPèïd*Ñý¹¸•^lêKÀè='þe·õ®ÃKšþÙxá:0Æ4mžÂÅò”;–ÌAN#•¡ûü-ê¬m5ÒYZݹå¼,gõŽ˜…VJàõ¿¾QY½ˆERAvßç'ôêÂ~Pk‡2Úiµ¯0rx5–€ì[SQ¢Ù ‰µk¤»í`«óXçÄîx!=TãWS£‘‚e ¶Üµ>;Åò!&zbn6,I¦ÈËŽMœØO¬nÅ‘(ö­¥xºåkýpÍþáA->C:¬ ²ÒÃM+W–°›[6‘´kûI²¸ëùØõ\‘ˆon¿o9„ŒpR …ÅËr:_A‡á^ly»GEï ÉtU§ÁJØÜ½­—èÅÝúå;#òãÎ^»7Ljw9èsí¨T§† “O±Ÿ4Õl¸b—ðÁúÛ‚õGš Ùà÷:D~ïÞõ¬ž}·Sa6ûˆ:f$S­­<­¨5®y©cï«Ã¨A®ÞüNÄNŒ$ˆèÁ¨Bì Á}0pÝT«§BZÏšeGBäVh–-XB6eë¾lë?yË‚añE‡XM&bg“âÉ~hWV6iТÐ,é¡6҃ĎÙ'æöÀu®)Ã-8ÄÍæÀ&MYà&е¤œ&ŠIbv8ì´>Âý 1/!ÇP7ß\%¸°„I1,[¹%võŒžC ÜõªöPš‡ÿ(ˆð—™¡š©1˜ò2yiK[žQ_fÄ :±ô¢ì ¥|KÕ·ê{ŽÜ9näbÏå žËLÝUÆ;öÓœ÷yäpe•XÏ\‡b¶‡·ræ2Kã…TFèHuoé2ZŠD¨¯@÷:æ°Îí™%gèU2ëK6<ÿ[é;réï§gºÃs0¬c鯯Âyl ó†Û?+?äê:MkÚ«Ø¡¯0€|]ý!ÂU0vªw|+ÔÊÍUø‹DÒ‹–{zcÙ&«¬ì›6õ‹ô²`•€äuì2Î54Bò lõ Ø2!®dàé¥EµEBéÎ \””_Z›hÎ3èDê.̱‘NƒlS[- }÷ŽS¯p©Sî·„E,"œ™â ñ†=q8iy,÷cYs u%^µçZð„ºîÆ,ðTW†½ëøüÐÑïKO©S{“S ¥¬FƒN§Î¨¿„ÆN¡Ü¤`EÏõ EÁ>BûÞW2܉˜Ÿ-öÝ…DDäôïÔPlD¤L¡Âƒ)SˆKŠŸ'8‚ü¨m³\ÓKÁÚÍ Ü†Vx³jpfÄ𦟲«toÖˆ—e¢â2¤ª |Å-Düã/5Ëj#]ë+§*7Ú¾³£ù0ÿ£WkÄ—?ÎS âÓLu.cuäÁÛìnûi쪼ɠ¼°`É \½Ã *V÷ ·Ô5ìdsɲޡ¡`É’;EË+SÁ¡Ð€¯î…‘Ö³çR›‡ö´#aÔ‘®~¦O95™ˆ16 -X0ÀéçMŠp[GOvuX´`uˇ¥ÝA¡.€®‚V vouª_™²Ô’×Uä‡ ñTA¢äýøˆSfÂð gn«Æ#Q<o¼ï´.žÛòXn5;¾n„£›ÿ UkS¢vX«1‡¸©Q×_h~§~œªl¤EÕÌ ¯äUiaƒˆ—LÁ‡,ÎÈmxHý(#&ùâ@Ñ-a 1‚—;MB»™TöMöÿ“öeÛ‘#»v1’©ªn_ûÿ?Ñöéî’’Œ ~ƒ‰àª¾>«W-VJª£ˆ6ö@œ3…ðiM¡Ú½(“¥œÚRG¸vÛP?ZÿZó¸L´£\Ç‘p×›‘ᮡ®º)WDld2 £ñ« ÕÖ?¬6Z»hóe>ŵ^FZÐ=-ž¾+[ïMµpżߧBn›ÅØ‘kFf;z:ígòêÀ˜©û¯ƒFšAv[†8*·L¾Ï[$šÖÝ-KÈÌ݆ÕêP¤…MÓßÇÙ°Ž®ð…n0¬ªÆN ›UMÖî¶¥­ãUÁâ‘ô°ûÉ‹?!k§‡Î ”r&Z[\¢,[çÁwáŽñ¯‘Ðæ>*„ËË=K÷lY¥®‰å–pÁ+¬Üäb˜WàŸXåÅ'æÂn¡MJÁ'R œ 2a¾…6öCî–; ÿÕù¥;Noz#&kDÝ;w®Cê,ù]ëÃÀD¨ &L`cþùñs2‹‡—°¦Žê°C•¢C½ôÏ„ m¬C­0²`ÎNúžË‹sÙ¢³Qgg۱ۢуÿHMc3UN<,£V‡ëë‚ìÆo 6ƒ@ÄyË%`±À£ÞdȃOÌ»×UwÂj½íÚ<”Çñ°j<«k¯ˆ£Å¡˜þ/¥NTLùAع»‚§©Ð‹˜Õ=—y$=¼xð­“ò}hê‹h*E»óK;×Aðc›·þËx„‚•aÄ¡E V§€ éÁwf_6½K.° 1`,ì‰9`­äÂ'¯™üJÓÓÍŹ4ùfB&†gì5O~Ñ@«Ú!~_}“èGm÷ùŠî°]ІjGndŸóœ]iD 4ñZÈŠÒСZ”ˆUÞ×I]#±--°±ÈÛ'mæ®àñ(¢e ”Á(”"%ÏÉÍÅ8–ŠHYe[ÕÀ”†»ˆÇõº³ûîSIQ߯3{…Ä75$6åRж;JJÀ± †Yí§¯ÈMgYÔ=Ž1Bâέ”ÿ}Í:ÌïQê‡Êu™ç¡7£t¶øÄƒ×<’|²÷;DZhnDïæz¸!û˜Épâô"ŽÒ®³Ù+‹é›JÊÙBtìQqfV3ner$õ’»^ì›Ýˆ£¬WŒ½(êñ½`A¬ÍØ”n„.X»#åÍ*ý…pí¶¥=.Q4üVÒ_w5vaÎ/óe/ÿ‚xi5‡¨Ô-^º-a“2hÁ$Ä¥ ëf\3I H"]\=e (û¢Ç Q)ÎÏ0U¶˜Å8‘ ±OŸúì;Äggi 9þŸÞv¥þ‘ŠÊØ`wXϽr¥$%`&4p5yòÕ»b}¦g䥑ÉðA"VilÅ”FlK…’á„QacO<ŒHaCâmÁšÉE¸Â.’ ”]ÌÎZºü°ö)Kxtbîsâ³óK³Ê Ó«ªFI›õ9Uì¬b?Ô‘‚d”÷iÛð¹f ªøäc‹To Ö!hŠÐÆuáo¶ZtC+¥«žëÒ²ærcHgúV;·ªjµÎuÿ0Zµ6)ª™2ý¬5c‡Õ=…ÄÚÌ€}ÈÑ&³y9˜ÛÔÍg¸Â>_ p8$})ô©š“©ƒyÖ‹‘°ç‹‘v'5J‡e”:Qš(CU‘„Îσ+>^FñL™‰¶à±‰—§×xÚ½´’¬žxHÖÁT·å= wA+ú¬ˆB%•;Sb_ÅyJÊ™t^àù0g<3ÜŒìB1lø—û¤G¤¹À¥øŒÓ–ë{Š}Nœ•Á–ï­ÖÔMl>_ÞzôÊõѫۣ¬ýCóèP= /ŸÚ=ý”ÿ [ØUÚ¸µ².ø á’ IDATìnˆ^ºK)g¶Ào¼ÿ­Z=ÅŽyÇæ3ü>…ôPÙ6Z üä–0%b°ïÞLU霋â":5è%ÍÑÒh&¶×eVч:_ªTU…+×ñ΄Ò$b«Y»æ0´× oÔuàC\Ü·1 ãR™ø­#ÍY#Mo\ß\_SãQ®¬š)«0x;ÚÕÓ(åÉj‡¸{Ô¬GÉ¡€YD˜ìÌL›)K爵RC*œàË;†…6¡é œ ‰ïMqå‹9wXµ¡Ú6VGE%fQx@¬V‡#ãE0…-x „ ‹ˆ·"½©ÂaühHžöVKTàLL¢R´2BvºÖV§„þ.…Ï# ÔÕ…;¾vy°ÜŸeß0J½‹Xž˜åû¥e›…Ó$ÌxvŸôá|.Þåæ‹uû! #ÑFˆªâɯ±ôë¬èZwн)°s_E{Ú*žJt_q.FºHo˜…½ôH;)>Ô}±¦—'µkÞUØØE+_à$ÞÂ0YxxV™±‚ ¶w)+~íkÄÚá{HâÞX¹nMÓTUT©ã(ÌØaÕQý¬ ª(ñË7JN9©CÌÃ4Ù”[©;©7™Ò ñÿ>ëßu×dÑÆÏ=f0 ;¬uz“G¦ȥg–ÖNk 'ž^¿´¸*3Ãù:Ù…À8ßV0þïž‘QFƒ­y˶Ý^ÛþO —$ºÅÜf$òÎ’Hs‚qBúÿÀ/Y5Èû›·¼&qéÆŒgB¬[nk–‚‘ä•”eP†eF4«C S†eÊ@Pî]¡Sœ,â›r°(ýl_UÿåT-+ãÄGÊrÚM;ÙlÙ‘kj†¥XwÚ Ã¯èóÄÚhDÃ'lþì Š©:|ÏÒ2ß…!²Öî|øäÄÊ ÌâØ2Š¥Ec¬tUK•}xÌ'¢ƒÙæD"`…5˜ÔÈTvØZ-k6·,Û“€âNR”)&…Çw!áníPµLçº`à"xš›¡f¸˜ú®e_Ð F磪ޛZ,ê®ÕâÅCŹ³Í¾–*Lƒñ$ý×+xf/XRhDr¸'ŒeøSáŠÐ ‰¯°±s¸„ ¾nN[> øŒçIZé¿D’1gò!p^Ì”‚º¹N– áI/¼é ÈG' î×Wo¶Sgo¡w[U]ìÖ€Ô9òªNŒJ‹qƶ «œ+?ñõ¥‡<_ñ#MmÂ’ÐDåeôŽXä³R°úž~, m©q!&ë (l@{͘Ñâ:]£(x«œÜv]´5%¬ )_3.›Zé\Ÿ2xÍlR2ór¿=hŒ«*OEiŠN¸Š’~Cˆ§·:|ÿÖìaŽ…éàaZǶˌDÓ³siQÄQV“£Q+—^¼ØƒJ´k%»Kñ4÷K€­ ¿CIPR?Rì&3û´wU°x£x $ËÕ7ÚëTëBÃIÄ£…;¬#q…NŽÝ?ìå™o62È1¶²@¨’íä,[Ù2QBƒÓÒ"é8„!!“£,\7 ÓìŠUXZ Ñ£È$ùqé¿D¢(ÞSJ…/óxÆ9G_‚«Ñn>ž±ÒfM;‡kêË÷ºöWÇæÓ(“ÞÑ÷ÔE0¹£Z…fÌÄ~M?²ñž23ĬÂðfØ X"ZåÐ }K‘²4­ùœá|@6ºüƉ¼frÑ&dL£ÐÍ0w–Uw‹Wðv´£Ñn {kyP¶þ³ûÐçÆm½ÞèWõ +³-]Qì–CÃFzÞ®›NŸÙƒÓçaygîù¥ôŽ4x;þú:èï8¦©ð<²´—ÈeÆœF ë@zàAMMëö€‹%Ú QŠwé«n­Öþ[ÐwÐ`ô¾±vŠÃåHÈ<ÌE|Nˆ5¦^ªè¬ƒ8φšØVÇ—#õ…¯x)ÊŠéQ+¶ç¡ÙZ¶¶Éú¡Ûhó6Ô¦°Ï$šD#m— ¡kIÁXzEÌXì·`4Ú#í«Ã.¥^#– ÷ÄÔ™¨Î¡$ ~âåIs†_ýôiyv­Y8±ßbÚÈYswdþ¡ûÐ]ç¥$ý­†„ !ZÇx‹ c¦Ví3ÎÙûF¶ÂμZ¡ÿÒ´í©»•Ê\ìwPoÂZû·¬=Dع.Ãj™}&?3™…À²é¥¬6}E±L­èPçsX%ÜÙq–¤¢ÌnXU¾³Q<ø¢>]MEëðˆ×`ôHмé¨E}¹z›“‘±9í¡(™í*ç®`á7h¥æªÿº¶<}uÝÆ¡˜N¾4vô†'UΊ"gYåK£s©Q· CÆp° „ƦëmñV°ºâÂv:'«Â}JÃ[Ê1Yw±½`õIr[n†ªÙ« ªªQÖ=tÉÂ|rNã1|î Ð)(ÎŒm—î¿”€€-Èm ¿µÕ˜ ÀÙÜÈ4c eaB46™Bé¼Ðµ*ì‚ Ô‡°¹0»1t' çí«QjÓi‚ÏðKÄ*™ÕUön‘–ÂîI³7©¿ ~þTÚ¤ÔÏž‹1©âÒÕóŸ}`oå¿ß_ÏØ…;¡Ÿ{¥«êÈ„Ì B¦2ûg¤bl!÷ꇲ©Ù¨³²døÀgFÈxίˆC×@ ±[Z‹Ð`øPÏ¢Z*™=É–Æ†ê© ƒ3H >\w§ùì ~R&ÑèʪÇŒá†nì¡v½=´¦Ün"þ­rë~•ŽÉU‹êmnÆ6P#“‘+;&#>Ëý†œx˹b¿™ÿÁ¬ˆ®óàD¹ÕÃ’­‡ ñ2II×&;ÄL~Æ2cY¢w¹8·úX‚ã§ÙJ’Ø4?{‡%¤‡_z9öV>€üøè«ÃŸ*JÀ™`ÇHTÿ´-Ød“™ù+“Ϻ§žx·§ðõè2r9Ð|…£ÍJOšVaÉ×€l©»tqö”áɹLÈ` Ê}tJmck‡çw[}«HŒFYV5¼d•ŽQGŸ9œB.wæÁ_Æ(}Owr¢òúÄîØ|»é`.=ã¿ei}kû÷[Öï¸/㤓ä«Gªšõ±Žiky4Õ²Š4G/‘¼…E .J2X†¡-Ãaóž<ÎøU¼^Yöô‚´ªUù‡«Ë©¥Z ”{µªª±ª½Õâ1™¤Žßó…߬2,>‰ÛoÝ/¨w°’ C=bÏøj067wS/Ü%á=IÄ#T¸i7FeÜÆ¢à1Ø ·"Ê$‘$é°<²¨#¹XðŒx$„ÄÑS^² Ÿá±ø©V˳A¤Íi+Œ®ÔÙböðw÷ß“Ys§nµÎùjÝ&Б6ZîO°±Ÿáƒ-á(XÔoÑRêªL‹*ÈB‡ä«ˆI¥E•¶tÂbÐ ~F,â›Æ0ž’ç\ÈJÁ'ky† ¹³I›ZÿYÀç‘Ú*ûÓª´Úg¹Ž¬úª”õœØT›v.X»Ú±3õiôNÞ¼Ü _g[ð•güCÁs©.4o$ÓoôÓ¸‰0Óά’hT Ú±N5µÑ&ñZ¸“Æ ±T^A€3y2$VwŽâ S• ˜^]«Á»ÌÿæÄsÁz™ÉlÚæ’I°ä—k¸ŽJ-ý'FZž>éêM6W"+SRv¤ 4 ã¡Ñ)mhy¶¶Z[- †™*ìJS ŽÓØV2i“Ú‚Åc’rº=ËÒýjVĈYýO|H·±.˜ ü‚EæÊ•¢G–ŒŸˆåË<’‰‹)†Í6>VF¦Í§aí²êg×÷HÚÅðKþEÝâ^ÅþfÀo”\.Åýúñ#Pöœ-ÕÀ+ðŸåüì^¦A„Ðf«P®ç²< Ÿ}×By䊵Âø‰ž¾°+ä&»8SÉ6"`3È«ús|(×Bbdª“ûœ>²ñ-™|fŸÈ‹ç_B°û æ:ãßuUÀSº*±:’ƒÚ–Éf¸‡Ó¨ÁnÍRœVr,[š —Ãý¤ª°S¨VQË¿Y¶Žœ†ÎC¼ò\f%ÞÙk]¢ï‡T[<ŽÛeôY6*gŒ”pÇl‘÷ÖÔ`S%K›gÔf>S±ÜUÀΏîfŸÊæøœ4‹Á‚uç¿sÍj÷{CwÅí>ŸWÀ–/^Ôº`„®¢Ž¿n›Î5몱Žò®4llyß[­Ñ¿Ì!²¨ù"¢Ø4GÄk†Kˆ}‡è#’¬ ë„e¥)Á{ΉBBøÇÿ\]L5´`0žÀÊ´,ÓÑ÷g'Çõ?¹£ï’Õ*Ïñ§Šœs„ †£–ìócò6KÑyðg"qÕa_™õ:—Ø ]~ì jÛü¬³ \Îuš[@öä2|à(E·’…±•œA~ôt‡ZÚÞüZ5Yi;š¢Pª½´ín´²kãê°²ÀÚ¨*4Wû"‰XýÑîþ¹Rlݔƙán{x ·úeº›ÀÓ2WZ¾ÊÒ¸œqZ%ÔS²vUË ÍÛAÃr"=”Mf‚‹%š O.ÂÈnºvÿ»CyRëB›È+Ð}›Céf£Û®LÛïÁðíf'̧‘¯rÍä£ÓÆÐލ‰’z kFiõÁD°y¡Ô¬©“_@TÍš(Tr6qÈä¬ï‰[¢zÃõˆIDž‚iEÌX\ïÈžX#æ?a ø¶Ä¶Cäà)/4­.>?æešø‡ÁBÀÂX ®[~ö[twaÖЕ$ý ïK/g 0„ .äÛl`Ñ`Qà\HÀ¬eq×#ßU™ÝK‹Å¬¦ÁbóÒ’š.äø$VÔ’L>³'Q³ÞxÊ´Ýfw›wB|Â=¸[3×ÑÕŒÖïV!INíeôd8`e4ØÒ­íÆ¥”®å« æÔ¢EíÀêFü ºvË€žŠsoenlè;-"®ÆÃÎfÆ©°„ø:òãŠê’ºóèBcËÎ&ª¼ñº{ ) Åa7X—m5¸õnqŒ«-á¶(ì W#¿E²ê êªW†š Ì7Ëá7¤‡Ë¢#@ÌX¹è4꽸}ÏÛüb@–É5ë*ÃÀJ1q¨d¦àÙ@wú:uë£CòKOr-ÃÊýzêðüÔKØZµ˜°øØ¬™h ¼‚H–ƒ„–&,Ù i/­~!fÓR›ÖK†“Ú½ÛÆ >Ô™¼KR9; 6Qíž_YÑGIí¡Ì©±ZÆf¹Žq‡PLH|Á#éTcêh¸ˆk7>ðf¾ŒZ:)whT!Òwuk+yôê°ð¾`§&¾!Èó½™)°]U Þ¡5)ãÁ€žÿ–•£™,n¬©d¹’SÒèí9ì‰Y fwmgµ:ÄzÚ¯^»'þóMŸÕ®¶‡õ¾ðáj‡ˆ«ñð¼C4*Q„Ç8 éÔv\#ñP/«UÀV„Æå€¢+W… _Ѭ v…_9W²‚auwÓ”6~é7§‡ ¶Öö \aV̹à+!XºòŒ%‘œ&Z3¹§}|>>ÖZ1p„'mS¡ïàë,yÛ Ö—¢>­Àcnk¶‘»…‡Y](Ñò.³‹” ÜŒ§T%e°%Ýæ±“!€½±]S)¼6ÙXO°Bû2`ÏÉSn FÖQv¶2xÝQ·÷+)°öù+ýSäOÂ7ž|šŸFBCUP:)‚…Q£P=-²ÛU‡E£Àã jJ¸S ù_p´è}ü޹®Ý¢_—-R#á¥Õ”†ü@Ñ:Ûo.mÔ&WYl¶ÙÅR f­´%(øÖwÓ ^O…ªr½:RÖaKHׯ)Ÿví¦xÆÃzgAýƒ|åêÈ÷´ÒKa¨9u[ft&£t'u8uá_‹Eêä d(ÆêLµ¶“Ûß” _±$„„ØÍ—S†Ÿû~-m^¦KFx"‹JqÁ$ãd†wÈ+âŠi¢uÆsáéAÏ€u±Ó⦧™ùÃà $†£—åÃg?О !r³yôZF]Vý§ô\ŒJðT³]§XœKäg,`N¤fÉ’¡Ád¤!"£ WÂT;Â%$ Iµ„Õ# æÉ$Ï9“”#ë«s…|wwrãÊo÷Y® /j Ôœ¬¢€a«Ö[FI²ÛH+µýEkêÐ:„mİÎÅK'µž –¹Â=ÚÉž†/{oI¥æ†2ïñ8õV<î ›Úlhi´QüÛ3סu3ɰ ‚ 5P"F!+¹æ ®Â¬ú,zåF=×#µ*¹(í†DËãTÈ7è{½ÚžKÕáâ=Këð^ò(ŽxVU8}î;Å…Kýþ ý¥O›]&P[X×LHl)P²T+l#ûÄœ85² ÁwèJÖjB:• £âL–¾aôù‰GÆWÀGĺRX0yÊ bâðWøs Sž}Kfû e¾û`,ôÚ!þþo‡ºtäÉÞT4‰ÀÀ q+–R1.Q j–kÞøMšó¿ì–sQ÷µ^±Zá—J’k… R³ä¥$=™‰¯Ù„àW÷¨{Þ'ÐN1Ý}Äü(ͱŠ._”ø¦Œž3‡³ª)hêÛªÚÏ\bXíªçÒ¶ÊÝgÚ‰Wz˜Tì èq‰{¼‘ð˜«ÜÓCåÂw!®gWƒŸÜâ1nVÍ.š×Û.*ÁØæ¨2>ü–ØàÊ–ðÄ»‹z÷Ý‹×ñWwªÝlŽß¹´ÖW™3zUo¾t>‘έóFã‰×™æäòù^ZõçÞXYuáFÿ_«Â àA  r Ãø¬Æ6£,·úŠè9rrKåš°.Û–0~a›@™¡?’G"Ö/< üæˆuÁœÈ;”'ÏÙø¯øøúŸÚ>_´õ\K÷ôc’këÖÌÿ&¥ÅëÁM„ÊL’‰û?fZ ja‚Ci›4g%4‹±ZäÚÝâû†Ñɧ°vg}y$ô˜¢òr:õ æAd¸réÓÖŠ² ™ÁWPëÏb' OYMs‹ÊXϪájcEcÿµ{Ú¥àáÓFÿÎû]›&i?­þ9çØ›¿“txWn.+sSÔð¶Õ:ü¯) (^£Õ÷DmÁ¼ëv°eŸ˜@Þd®dãÖXQØL¨›ÏPﶬí‰6<›ê‚Õ_=ºÙ†òMM¹ ß ¾%Äã;÷ÿsÁ¢“üP¿‘v³p$ZÀ“²Ð^—~iÏ\0à몵p¾ãÙˆ´XÓxáaõkr–ô)B¦OXä®î,ùUX©3žiÁS$~ú*ì¿èëoÿçêB¡‹`!Þ°ù¹Û?ÌÀ_#^\LcŸ˜æn°5¶',˜³óѬ™<'^òÆíxzdVøˆT„8*p{Üð^fa™(å‘`½ÄX‘z"W $^ƒÞ&gŠq‘4mÄãƒ6†˜e5(Io†©u¯ˆï lñ&9S*™g¹6²²ï_±Ø“ˆ~2‚D •\nþ'Vax­ˆyEH¢ïY)Îü娬Ÿnþüñ‘§Ð ÁžŒL˜»Tâ³{Éu`«öA²u0ëcÏãéw{bLT£û𬷹Á&Š3òi3Õ²!cÙMî…"/‹ÅÚkdK(ײ%,ð S±ÔÚc¨å 8DZ¼ÍÆ4ë*&£4Ï^‘}v_¯â…XѵRÿªU‚Ár*RuLµ°§Sv78-c~NSåì°82'(£Ž®ZtƒÏ¾±¤9ó^ŠrÎÕʼÝ$þN·u¹m#tx1­ªYfÔN÷7Ž 8ÎÕH«4S«púrO/o0´e«|ø‹‚Å;¤É*ˆWçÀ%$ß® õ­Ž‡¯„Óî³wïLµÌ=ÚÙÓ§œèZš¿ë?¼zÄ«¿ïàÉœA° Ï1.l¨ãLÙJ§HâôÅ|yE°(²ns(²n È«8 ¤“|Uú¯'Í-Áñ#Pzú9{ÿeXiN{F"L=nkþüêäì*³ÌÒ1+°x[&æG¨Ñ&ö…ì_+ ø]ÅKk‡ä{:‘g˜“6·øÅ¢Ñß#;”§Ó‚Ú`|FŠX3ù;óÓR5¶…)YÛä0`(T«ôw!©6Ù)ÿ†¢J˜YޏJÜ©§ï0Öm¨W¤­háQ[fÆ>‹F<û}pØ¥½åÝöð[$þM¢ûÉ”ÇòÝFyùaB,cD«&=(7GÙ[Ó¬­Žs#­®²¸GÏØW«eÔ¯C—ÄQÞ9ïçÌ›wYC—`|»Wö´«ju¶ø~uømÁâ“5Ía]xÆã:Ä 6V{ϵ»£$u’ µ×,dÙ¸j§g5k#³RZ9ò+RÀº"F8¿îÎ#'DÑ?1KÁòÈ Oé°d‡8ã)ÝÖƒžiá)“§ÈÅ»2û:ÉïaL´é}ß~vÒÖÔ ?¼t†„ Ý•™„ÈŽÈ2›ªÈz:>jÄÍU|ÀTS…oÐ"’G*[RQXd™áäƒXà˜( 3£;…Å¸Šº}¾¹€Õj™¾IØ VRï‹S~ðedì$UÅœêÊx²–±`µ·¤GÂCk§U•Qm×ûñ¿·=üRuv5½3ÕzÃÇTGJDU/©µ°µZ co²˜Ïì"Â|gfY±9âžûw.XÄ fÒä‡ã2îÒFšïí‚ø-¤uÇÒ:;Ò¼÷:âí•üÐ(+9ñãRãÅÒÒ;D­ÙÙšø#Î÷`÷¸Ñ»¨°ó¦:_‚it|b“âN‰°{3äþq¢4VÛHˆ)Ã[´ ¿`r(Û©DY IDAT‰ü“!^M\M\ìôôÂLˆ}‡€_ÝûáWŸ÷9(öÏÓ£×ë pŒLò×ü?ÓOoòŠè¸JY>F~“ãЄu7†ûº©Á“°""–—<ò6#;xQS›MSf VK¥±id¼ÍÎdë*yP\AAÑZ??’Ji=0B‹j— ´ÓYÍõFÁùÏóüšÔ`àluTìÊÁÒÉ{ä)ÃMXžxä~{K µtX_ &BËðOÌ^ÊËU”‰¿è‡ ?Syö„µ§%N=1v¿‡ÿì.4ÀÔ- b§kEÚ&߉‘©°+“³¦þED^#­b#)*ná—F¤¼[ë'4Ú¸5SÂ5ý´hBzxà«lœxv( ëP<åÊÎSŠ´$òp¾€x³ß=vwßkWål÷VÞ9\ýൠQ¯ ÍØæ[õ³çbA÷CÇAêÞ9¾‡fíÌ:ä¹4Ä}úoàY|Å{ S޶S:̸aÅ€·/…„'›5%pjdÈ#Õî–Uà,êî\-××–Ĉ¼F@3êûÌ©à&üèÛ­âåºð`ò¦ƒ£Zé!ÞâÜB鵯9Ñ©wÝ^eVaó^ñ!¼:{­Ú!Z50º-ˆ-(ìà}v>Wk­âØ)ÄÑ„%Ã?ñÀŠè3B‚—"µ‹f¤`‰_àŠh¨®ˆ+ljéΖ0ÿý_?[±x‘75uælQû§CZ¢à©=&c»&ÌŒBXQ'û?’ !qÈ´D„.!$,ë´]1Õ’ßüü#ؼì°¢tg+!Ø#wn­ÕWØF€C™§޹tYïÛO¯X­sè´Rêw«¸©Fµ];ûÁZ‹áÚGE}—VetWT¬'ZFÓÍÀXàx¼¿ŸçvÿÁ¾ë¶ìÍñŽÕuwGãDŽgevæFÉ´vŒ£Åkí÷Ee8_‹©Ž “tXY )‰Gi°ŒÖ¡w{9 [Ò–>^ÞPþñÝÐÛîí´¼Ó³MmKùdaŠ«"]uXtJåÖïhçZ~èÔLžÅTÓO|—R§~G…á!·aa$úêç«uÕùZØ8O)aÊì"‰èÇ¡”>g„B ‹’9°¡’ó• oi]®+{jo«’fE:Õü†¢zäÒÀ<ŽftlªÛbõ áQ 5EÍçQûRG0 'B¹ï°ÌwÙ;xÛa½33ý <þ G²ŽÑ;zñªáBÛ¯wD¸²§ÜÈ2HІrµø÷TXƒÆ§‚º3Ý·€åJ†ÐèÜm²ªèí÷\Äî@»vßjñM¼¿ei]zÓÒ•Ã##áÁÐŒ&âPã¡f“:ýº+$~Ÿ ÷ñpRz8Pî*E÷(ÎXxåL.b}ò£Ðµ¶x ‹š°dY, †å·*&ålÎpŸxÈWEßóÅ•Â??–0µl ‘O‚>z0â¯^­äô‹*LLêû{±f8âÕ<só†Àj»›Ä?ð”D¦ºù,ƒÖM¶ H±Zö[xšÏnÆ’Ð|Ï,à+,yCÌ>PŠ>‘m¨Ln³ãÚ ‹¤Lj?6ZZ uiöPç -®ncÙÒáï:íõ jÑ6êæ„a½Ä»‹ò¼ãÁã;ù޹aiýŽšçÜ…àÄÉ:k§ÍXâBßP7ŠƒµÕSb¦B¥!Ir¨wK`»U.£a, ºîÁ­m3â9·Zw‡¦†ß¨ îg0þÒ*þ’ôp ì ´ùÆ÷ß^%‰™“—–F¬öÊ¥Côvõ’w y‘¶Ëmó9 l&–pSr®42‰¢§’á&^¥±Âºžs±ƒî3Ù!f8NxJXY@î“cšé¹ð(ºÅM«Ÿj´›ˆÚ2¾hCâÕÊÀ?Ý´vöFí|,!ŽÛçÇlm­d™‰G•{j=åÐ!?Åò¡`ƒ¡Â ³ÀŠá$#c ±pb9/)“ŽJaßÈ“aØÚjL£Ôß[ß5Þ^Mèºæîq­¾*µ·ÆU!ÄMá_õŠVº[Â;¥ ®WVV¼:Ž—K—3{³èŠôpoÝÁðç?yzúîà«^äEQÌ(Ü1'ìu'ÖóX¹êÉc\GžYïm„áé†ôp7èÐ=­Ô\•­ËÖìÛ¬V\Y>ò‡.€mpµ¦.¢×©¥±m”È£ìL÷gÐ L;wX’-ÚÐ*ŒWš]rxÐë™S=6§Ç{™åÙÙý}àE»ÏjÅUjø™ôðž7\or.h´¬#]ËŒ5eÜ!îIëšë ‰ˆ .ÛœÈ ”aÃÕ9>ƒOŒ Sâü'J—É#‰ÿºE[d$ähÆÓ#?ðµ"z” KB ”"¯+M â¦ÿ±Ä©Î–ÁÔ=§ÎÒÚ¡÷O öšµög·?û±2>ˆ“IÁs„3þ‰ ÀÌÏ…¦„¸KshÆjP,Ãx¬Õ€3ÒnÊ*!=ÒšU8€Ø!H~Ð+¬§âP2»LÅQžÝ ã*“SØùnþÔœXÕÐç;øuP#®J\FJë©`ÄÏP¼ ya®¸8&_¼¶rgO«3KëìµL÷vZ4Òé;Åââ¥Ý˜_2Æë¨@° s ¬)ŽŒP®<²dUˆT¾mP;,Û™ FðyKMì†D sêEéJ~|ÙæÜõD‡ ๔oš2¾GïÔ<¸Ò7ðÉê}Õ¤§ VUP—U·ŠéUiï¹v`+v;t8¬l‹EŠ=B9ˆ˜¥:S)üÊÆ‹vÇr+dW¬iE(ðeÁ$Æbñ…‡Û°ù9 E|$„€5ÒúÄœ9j+MO?}þ×ú°›¥çÜEÔb°õ øìa¡Û~Æ‘šWiûêJ™}™¸’õœWš-bõ›4Çd ÖŽðN‰M˜¹Rűd1„°(+pÞ¾ßUXùŒì¸Á¢Àº0%ëš,îËag0¯¡+V á:ÈØ±K"…âÛ‘ð\°tyÒV¹Šf btò;Åêðr§ô;­Ö%$o~ÏÎô’Ž·¨'5N½u d˜ÈÅ!¡: ¡ #°æèÞº–§À˜©0õ,x3ÃpßFšQ›N7òC\í ÛMè#߀ñíÊ{èŽlqéhN±”g§-ÜÑÙœ¤:,RbRŸ{­rë°ëH¼ú‘©×¸L $pÀÁqq®°5™¼¡VÙ.4y” N¼„Äô ³p„д`ž±ønÿà‘ƒ´]41 ±=Á¦Ïù#Ï¡8ÛÃ/ÖÎ*äøÏþ¦¾7` ö·cbB%.à`>ý£ZiuÈ„?&¬K†#ÓîVáFø|œà…:oÐ lÛ €Ì†ÙÃûn+–à{ÎŽJ#|²¾RaigV†Hû$¸* Â> :M¸œ{xõ¾ ÄèWs(XEe…™Ó(PÕWédŠ© ÏöD+5o ñ—– ç½!nèo*Ô¶ñjãUUìö¾Êà“l³O*¶U˜}é¼2 '“oÇ—[ÂkÁ­ŠŠ‡ˆ,¿@÷s2 «;c9ÃMSs§ ¦·"êvSÔÚ•Å ßä^vX³Mæ8Ù˜µòCÆ{óYµq£¾.ÔÎå¶óSvHÞÔ[0Êàc[ «)ÃGNÛ‘­¥}$Lò¤€P*äljBIJ"Lˆ|ÖÍà!ôÉ7Ì­­o  ƒBwgMÈ^ò_¥‹l}± P²¨ra稗œ)ðà"pió?׳5'«*ormoGî»6ÿ+'C]«6†4þ`»é°ì‰_ õm—Ó"®øÒw5‹NÐÍÁCüÒ-îÒ¢›¶îŒÌ`Ì ;Ä[hÁSÏ"1¦y䯯» Öô´y{¸Ë‘Pº/n¨ ¦²md • Ëœùj"Úi-jÔ[û>1íÙù1nßÁðwî4¸×N_®5ÍUÏu~;ÛÕ[îG&½XÜWà]ü9 ŒV Œ¥#_AåV徂,  v ¦rtÉûì#­‰‚å¶RÌp˶ ‚X¯˜&<',i+g9!®ør(OÌuZGgʧùH>¦É7cñE˜Ϙi“õü§Ãð¹ÿ·?±¹DÈ# °þ ×àžÑÂÓJ1Áÿö‰b…ñeá3‚HsD©ŸáÅuG V@.Ûïœ&¬ %#T˜ˆUš²6´ yk»¼£ì¸r³] *Y¶Ô¨gµ²¸_*/Æ&µ*-¡-hªêª4¸nmußý•±`:¬6&ÅCÅSCÝAæäV ¥“ý¥ô]\‹¹—C›ñSm®Ú4œ˜ñïQ-{«Ö†vôtôÝ 9*¹,jØ´¨þê°Ö"ʯ$md˜Hq‘­”XAÓJÏÔÍK­³7+nâáîº-¾·-½»¸›ü1æ»Ñá¿FâI•ï¢çC€’QÔ­Ò-€­úêhœ;*ïúüâ7„KòÇÐÀ&ð4­’R騬™}¤dQ'¸ˆÕãC´>ró'x~VÄ„hQgL f2aM,Ê„eåøôó_ÿõg{< ð`< ˆÀð«sµ*ð*ðHÀÒIbÿò ¬Œ•–?#Ù-2s¦'1WrRw€Ð’§âTEA±¤ïlà¶€[‹ÒMµ„öõ!t­K%bñðȞºy?dP×MÚ¹U¯ÈÀûœ¾3Ýë(¥nª+Š·eFÅïÃ:„Nsÿd•øp°Z®§õÔù¦ þµƒ¹Ç¶ÌH‘?§ï¼ éi'b­ú.§0 ª@†ñl©Z.ž6Q¡d5P»ì° œÝ.,¡56• Q#¿1S_k¯zBµèÊÿ“®ÌpÓÄâ;ºiû½ñð²äá;VËÞÞv¹q6Ä©N¥ˆÖ•˪9Q3tú‹ï»¬'ôâµW.¿q9€ [ÏÖ63ý*ä Ù'fË¥ÐF_ù¡CY°¦Íië±"¬ˆ5!.ø HKB0h3–•³1m™§5LÅ[< _Àà Ì*¤gï&¢2Ø2½ „•ٞЬùå~òžRkL‰¢GŸe1®ßvÆâ¶ üþGäÎҲ„¨pÂòŸñ+¡¸îs%—FÖšâM¶Tãé!ô¤Õ Mù¾—Õñh˜¯¸ª-°Þ!²Òëh3Òƒ«ßê'ó™óqN§YäÁÃLúN`hn¦Â7!—Æ-tÆë%©·;A„ÔØR5Ô šG©({JßÑj§5T¸F™aØX˜JflΉÕt*^ßfñ½€oØ´üÿg[Š+õ9®8…K“ú){Å/=#\Fa|Zڦ堦“Òè\®]ëJ·õ[i£u#s²‡kÅ…Ò y›e¡\ÚXZE +²Å‹üp†w(R°,Ê>âOb^izÚé×ÇušÚ‡Ù!îK«â€Q™ˆ±`?UEÝ:¤½ï«Œš•v*XM©,ÚˆaÕÑB¯UûÎó¿â˜ï´£ñ æÁæ £6}ÿ×Óóä«°#þ ó°;öi»z±Úw^Z—šOs_¹Šâšº«e¢=Q·jÿN?`Zå6§Ù^¬]Sâ”ñ@îsb"Œã’5’ =òÊ1“Œ„©Cò]aQ¤@8™ ž˜-Õ…ç…&oò§ùH.¬.¶`ñ K¿ÔuâWg–æ>ÆþHyY>°79†ìjÂJ!ɈÅ@Y8ú]V €ÐÑ÷„5¨'·Õ§w(;¶õ8” ç‘ĸĉ}%[É8ãš5•*‹Ï ×4¿wL~ÛèZcN“]>ù,ïzì¦>u4ðk§‘°Ž4¨­ôYüï¹$ñœ+¿µ÷»ô¶4÷0ü{º%Ý@=—jê–‚cLs\+³ùÌdw“KÈ S`-œÐ²* ÈpD°LíŠâpɃ7'®Îyï]xð¶óºH·®Ö¥Ïò¹ç¢±Ç•}Ç’¯j¹C'ç,Í5Ýõ˜^Õ&s°¼ŠÑ#¡í_µ½Ø¹>Ñø^ÂÄä?ÂÕj}õ6{[VZ ;OEzìQDÄpbr¨ V±²¿š¾,ÚB_ fÇy¦e¡ø+üüåԇţg^,P&.Ìk7\^{ŒÍÚ¯  µÃ$ DpÈ®f<-Zo›4' ¬.HVØØ¤ÖwYeƒçh &ó⎟QÝÖÁ ± –‹§lMõT¬-d˜Äs·å(#_”|§ŽÒœªÎ{ ‹¢ÑT‹FèêÐaµNÑì {²¦¹3Ýåû‚…{¾äeú޹²·47[ÈK Óól¨©£ƒ ¼%ëj#+îiuKÐ)V5;®ßŒ­L+Œ´Z,@{ÐÁÌߌÉnfäÚÑ)Ê£Ý°ÝøÊøá G´]‘¹.{1¾1';ìb¿UÃø,íj7lG’mQ«C§¢.öŠ”½¬Uw‹|ÛÔ­¤b¬r¯q ð Πr0s›§¯h–bœC‰¼d ~› Ê`PWĈ% a¨HÈñ¢˜Ið_øp”g<Ÿüˆ”­Ï8/~*ÆoÔ†_,ù¿»ßƒÜ“?zÁÒ¾ •¸% Mˆ½Lc›is[­0V5#ˆ©Ã>ŵ¢ÂNX¥ËS‹ú‰B—–ƒˆ«'¬2cäj…­pžR…5̉ª£<…ŹJ½iåjÀSɰvÜ*ª¶«Žãž‹:D«‚³´»V핵9¸¹²W:»;àd¤E÷ÙÃôVÄcÞ¶Z椧ß0¥ÑµRó³ê)RLDÑÌŽŠø/8TF¶p–E#p…# ¢ÉyŠí‘1Ö4Éêy½ u¬Pfô&&Õe`Ÿ³òÒÚ“öeâî´Å½rÅÎçâ ߌkü–Ý`|©•ÖÄÁQöH]/ÝÄsÙ¡x¤oQVai‰ŸX>|áãA_žùƒ>Ùýü³<?Ž03žLÝ6þøê`ÖÎõ»©)¡1ÚfΕ‹ÉøD!pˆ”g|­ˆ+Ö¾O‰D l):n£ËÛÙï¼Ƽ„ÃÀ£8ù)_à&Z ÛL®Á“­©ÖòL²_?8Žî3‹¦Ad%ñÙ'ǬZ°<¬¿Áœ•¯ôC2k•‰•†ædXÛñËû\a0ôµbr[cêæŒðÄdÀ ±cž±,ˆùëž‘õ‰9qø?óÿZc¬«A xàɈ<€/àÿOÅ5ýè†?UæØŸ„•9›úƒÄ¦¦WÉX®â8*šg‘æžÕ`ýæåE¬Ch€TKâ0vV@ÞVBža„U[`+ŒCq¨’å#k)‹fgJœWPíÕª‚iˬ58eG6)Ö…íŠß”ù2ÆÜV÷†mÔEÒ‰¥U¯ªnlxß$YàíÒð=‡¥Zº’,À`Qj}£b¯ –A³¨ Sá š´dv£eÁ6Û ˜¹k YÉ ƒn¬V|ʪá{ê&~Ãüð}µz#“þÒß4}4j¤YaXت'癿ԩƊÆè]§¼ w&WS ê}oF`+ôÊAXÁ¦rœ[D— µ·pr”æ„`PÅ~ÂÓ EÄžyÁsÁ$>3â„Õ¢>ðµR4ܾÌc™§OûÁÞàIxñ‹ð@ß>û=;¿ôG§à …Ñ3ØÒâ¦æM ÛHkÄZ¶œ‹0aIÈqÆREKˆbÀ¾gJ÷-a­[rÚúÀˆ¹ÁÆ ÿr2WÊ>1#Ó' qBdC.ÃÍ´† ’í•Øó—±6å1éKÓßÝIrXN“‘f'é“Õ^å˜Q­qNŸæÓœˆ¿ô.7ì’Ñ~°W>³´Ì[ê<®¨BúÁv% N¿•£ÖÐp=ZÔ†VÁ6Á ¥x¤+°†êÖd¹q‘¡ÝpÌ)´ãäü¢Ü/üÆö”ï7‰ü{•ëÒà ÷-¾Ú³ÜÅ–Ø pÈ›Ô éîeª­i´ÅeîwE·ì©7V­ÛW•ŽvG@ÂßËõjCý˜>‹u‘²C– ‡m™˜,`–E‘D²€äQÄ O‡² ®ˆ–jä”(X_¿þ|”ÇOO›ëÿtbêyˆ»Æxê+:°ÍÌÊ1;/ÀÖÊ!PFê »°®>`ò8lI2$ ûAžQ A]*œx4çí¢H§Öiß 3ÃRõ”£IÆ4ölˆ)œAUí^Umä7%â)ªÕ¢‘ÖPGA"+,Ÿ•¹MSýŸ"!.ù¥<.ãŠQô-Kë®á²7ëÅ7ì‡3Å”Nku{³!A² MÄ^°Ø¢6 [’% €A3Ô*¬1ÍXf Vhê6ã“ã}ÓÏüÌE'ëŽññFáü>Ì•OÆiïÁx¾jtÏ}5]].šRÕ2ÑŽ£Wf[:’Ä*™ôA ×z™ÛŸ¢ú†üj¨lQ¯¶5’·ÙØ(8Ë-RJ=k>Ã?±:ä ë‚(²êQhaA´¨-Ož=¥¿èÏ5ÄÅÍÉzL„0=­ÇwÕô— \û/)WîñbF¢lšc 6Qð(—•¢|&…u% ä¶JVkØ,Xó„%bMh `‡bQèpé!xd·‡€›#¢:”BΣÎŒ|Õ…b¹¡1IøÖNUÑMö‚•û‡-÷ùž|aÆÌd]¹hÜÚ“[ɹ`ỼöÖB ox\U%ûv<Ä÷Ô¡VòUÏhDCÄDlQ%0ïÐC,h IDATb$$4q\³°²%´hâXQ̲T­äÀ­o ½²£=Ð‹ÜØjµ¤ç+Y½í¶ðïGÅß¾ñx¸£·|Ë!ÆØUÙS’˜ëúÌ"1²çVjùáÌ£YZY­w,¬¤¾j4OÓ|ªÆj‘—DqE p÷Y.O¤Aøá‰Y6Œ &ƒ6ayÒ±zÎ ÅOóãï?RŒ› ³¤Šùn§õð«£ZâúðÑ™tAb%ÌŒ•¸Pþéá8°ÁLO+šüžd±ç!¸9bñ,° b†”ª{y‰‰E2ÚNæ È &bž„”B$OòÉps¦8TkеÕÞp–½`eÅr°#=Šô íw`˽Ô6æ —¾³½¼¢ñM¦ÆŒt¾Þ¿UðøYæßƒñçú«þJ Æ6ÑcTº ›CmhlÐ,•I´aÑ5ÔÈ1Õ-Ôbk¯ö£^›+âô¬t·ÙÆNäwˆtSGø»Ì ¼õYæ|—jyæÁÒ:ÚɚƌÒhëTy†VÙ¿ÙQ&½“XYÓTU¤‚ÊÕU,¼YÜQ†š é§—ëÿqö®Ë,IÒ˜GÞªvïì¬>½ÿÛÉL&}»³ç4‰ªÊKèGd$"Qv¯ÌŽašì IÀáá—mÇâÀÒŽ= HWÄO­ÛÕÖó¨¿ðqÇWD‰Tv^VìÊWü8Büú_wl„_zC|(éödàSWÂñ2^G(!0Jä@_ËýðiÁž9Š »LIÒŽã'þ ã ÐÍÏ ‡ìzâ4LÈI²´V<šd-•žWÅ(îQ¢.aõ!P Èž[¤Ór8ndÃd5Bǰši³ ãKg˜É,ºÒÍ×Ó<…“”çå©ÛN)€ç@ÍsËáù\ø.Eëe¼û'ïRú`HÜ@Ôw>ø k ìP=Èuí¨?9"xÔòT {WoS¼ßË¡ÐI›•ñnÞ_ôJ–ê©X ¿+}lßʵø½èá…Zxo?¼,k'ÊÀ–´¹ÓLBV#„ülÐ sëÔ0ôŽÍQ>¶˜‹»ì‰;Ð@ 8z"3„{ k]¼»áá¸Ô=Ò+¶ ‹è¸ ìXwÄ€º`ÛzäֶѺ` \nôØiÁ û²Ô›ÇBðÜ3³"ð|ÿ À¿TÛtI”¯z¡þxp¦œbIáðiã²Ð~ãÇB»Ç"ngSñFUi‰ UÜ…¹â!ƒ•Ð"Ϊ»ì‰„P…¿w¨\à#b@¹ãqÜõ OÕ¹6‹ƒžýìÈa“oKÃØTÈ´y=ÄŒSõÊöOfD8gX¶7r-üNVú[2˽¹ú7âR÷fëüž/fÐ`²ˆ‰ÙSÅ¥5:[yTß @ÁἎZäü&¥!í[Ÿ-¾ö[̳ÁöÅ¿Ì|Elác[ñ-_ßËJçU‘õlñ:Ó½ Õ–oeÁ¼ áÊPÍÛà é^æÌe6<ÍìÚþdë)s]ø¥‹êOª> @}¨'± _ýÒþÿ:8îX"•¯+Eñ¾¬ØÜ<ªfÔð‚íÑS˜Ö{¤ü‰¡º>ýDZ.ŸîÎÉᡤûãNpF®MÏEÒ‹f&àƒ°1¯”ï±Äpð’)þà_‘òÎ  Ž€,ÙI²0jŠáñŸ;HL+v×Å\!!äˆ"ô<÷’’Ö‹Ô‚‘eLó¨ŽXÉjÄá;Tïkp…B dÃ3V#£käÃKͽ7ŸùXuΧ7}ùül…¡“ÂàRðèÁýN8êæ“ßê¶ÎU[íâ5KÄî’Üâ>guMƒDÍdDê?‹èQÁDÔ‚' Lœ•Ì‚‰ì`óC ¦'yΔxuPãäÎ{Qñ^²Zßk ð»Q«]Ôð0k vû.Dû]¢6ÑÓŸI0{æAºÎt™ÉȦbÔé>ÆÕ¨Þ=§£ŠS¡ù`µ½ŽhÀjÔKg!iVPæå¾Çp$wxÔ…ö—@% Xl XÉ£~ávÃCàì†eÃCZ¹6ܵº»¥~¦z÷XEVJø`á®ÊøM ¬U==ð0°©È6p%¾s ø¤æü‚-Pp`÷”µULlPÐUò>"Kþò,T% 3\ÂîQ3Ãy±^z$¢V0œG ì„@ÌÉÑgŠŒÌԞѲܺå`ú ÚþgšEþTÇi=@c&(†møÃf?§„ó©™Å½Ù×܉âpo*Z,9v]ƒÎû ›NƒsNY_OÀr}%ôϲ T„£Ã‘÷Lä¸F* t•æS½M˶Ó2fC_Õ[Xo§6Þ¨HþD÷€?n¡¥Ìo;®Sÿ ûϤúÊ_rɬ2Ÿ Y;¾ CºUæŠÖl^ –® W2*Ç¢€Å¦*qô.ÀN  9-‡KõpÇJGà"©Ê¢*8Dtºcñ¨eGz`s¨ ¶_„vÃöÉHG¢c_–-ܲ¸Â'ðð¿°Dûxiú:Y•:±•n9Ä€œ)î¼.´ÝðȈjFøÀ'ƒiÜ‘+¡ªäKF È©Çoå©Á%„Ø•=$Ô»ô!šô¼ Ã%JÔ„Üà ˆ ‡D9¸Rñµö¥Æ4Hsd^?é*7ÇÆóœQc÷€b¶¿f»œ1îÔS™Œ¾"àÛûxe7£Øe<ü;)é Ü·“rÐ#äÑÜüš³Vÿ²8-´TMäˆcÇ*[Ø(pýÂ}ÃÛ–Gâü õ—ÿñ÷ÏŸy‰üÓõééCç»Oà—VõSo±èCnÃÖ³0å%æh§e•o H§X#ѯ„yDVܰEx‡t hÎ2Ì:)Kb","ËK ¢:vZF1—GuT Bà©,a“WM ™°Ä”³Z†«™÷õ¡„8æ#žM<Þ<#ýI_ÚNCÓ¹ªê·Õ;—YZô>›ôÒ/ý2g3šèwgÊŸ`Vzý°šëWBÙ ›‹ŒPÌÓr7¨"f*ÌDŽ]hÏñÕ›.6»ÀÛ=q U™¥Xíý ѽÿöá\‹ßdN¿·"rÌ×D|;Ý$齿N­Žµæ±éÂèzúäOåÒÎô¶¶™ùz'+ ’=K%ó Éó„ÍPƪ“H°€+(Á/|KŸ!æƒRÂáz„| ¨÷ŒGÀ!|¶¸yŽa“8æDǃo+íÑ•Ïõ¾órüŸKÕJŒ@øVuó<´hZI÷nåYuTÙ€;aF¤íçB3Rƒ/<×LbN*b(rXLˆ¥ Þñ%Oõ¿ H–ƒŽ]冯Õœ(oÞE8¯I 8é–CóÔ3È ÍsmÞ9×\h.4ÒWË[» T±çB?Ë‘†‹ëE±ågG®â•0OXõÔDùÉ,Ýû¨5Þ‚ZA%TùÌäwvúÃFU4”¾ÖåOjxRÆ×yÔü“Ýð ñRV{µ$ ¹þ[ß!¾Õ–þ¶àe÷ ’ŸJQG.v&>ÿŇ8è¼`Òâ›)Ahfés³Ç­ÍÖK"sÕøy:ÏR òà * Èq=þmýïLñ@r\:nˆ©GnV"Q0 èÌ%ó—Ä?Ô=n|#âGº=âíð‰ƒÃ¦£Ö0Nÿ­ µi^Øf07«t+$F¢–üž\ŽqqG¦¸q^¨×ÜïX+ü^n n×ýNr–\@=Ð$¤Ô£˜±«äÐDñ/Á5«Ð´âˆ8d)ðòÑD‡¼å ‰Ä?-ï‹#"+p„ù]¼ê8ˉ0Á¬°.b2žjž­Ñ/â¬KÑNeɸ ÿfÔòï¡Êͳ½=t¶Ló;é°¸ç”Ê>ØôbØ$ØÏaª˜¸”ïJ¼Ú)Ъ´xöx“„Lù8Ê¢ _f…³}³¨*2õR!¶$Ô4ÅÃS[°ï¼ªõ@\°:T™VÚ÷›ÐÕ;–„= ~â~£‡CûÄÇFëßë_é'ïж‚v^Hëëô×Ì$Xt+@ ¬ŒB¡æý¶.1ºƒ–ŒDYÞqG…ȵ$jyï´âð(¬ƒbˆI $áñR9åQ† 1 d„ÁwÂÞ«'×Ô*ˆ•½£–ÈG*ÄÌ ¸æq䪺™2–Ýò.ç/ž5¨¶V ³YºÎƒÕ°ð¦i§$;wõŒ<½ —{/ ×”ñ|A.3ÝGŒ_{þ1o´¥”¦õnÔºQw2ð0÷T&2ÙùÝÅæfãÎØu8+™´r¯Ò-oHwÜfûHVÁD5¸úiGxn>í1ÞUšŽê‚cÇBà«ÐðûçÑ7<<êJ’bì©>øökùñwøÉwà†^NþE]©ÿ©b3SÕ‡ÊJ.Œ („„Ƽ:|¥Ý/ ÇÂÇA‡Ô¬Þñذ½q÷Ú3¬32Ei²•]*-ä?­Pïªz!Å„¼ó¨zq±ì†A^,T*|DÖŒFÎq TCÌ!1£ v^¥,#¶”ÌvbÓЋÇÊ|šÇ¼$¶«¾¨v:¼»!Ò›(w•ÇKW‰îMféàÌߢ‹Wp8`®Ö{»-JXFh¥™5Á15çª\@Éìz£¬ÁRòmîŠæCÅŒµî4PøÓnx–Aü¶_ûb™ù ­.{-ñFŽ÷}ßÒe¾C5Þþgji©.—†ŠMÔÕÎÀ½Ÿ0IÑp&‘&Ïú¸hº©-œ-&¸fÕß²ö§ % W¸Ä·û#†rPŒ”=êÆÇJ `qüy´ˆ¼aÈÂp‰Úà†mÃ*É0º­¼G_¾n·=-Í»ù‘ºúá? €æV]¡KbUõCŠV3ª!1ã¡øuÅãS¾Ð;-Ä;ž¿•â_ö‡½”Z´9ç¢õÜE½½¿þ%¥:Ì8åLÌàæÃ‘̹pQ8{Y –ô£º9R/ Œø‘CʉïêB{FóJBÃׄcǦ+á¶a­p;–«Gñ(w|*žëJ·¯pÿõyMxž_ÔÙ·/ÍŒÿÔP­¤€µ¨ _F™¹Â?€ÌØi¿¥²x*B¥°G.…‚ Vø’äè„`ß­Ñ!õ>Ç,Ú÷Y*ˆuÂ’±«JfœD3Ë Ùô†(ꕞ×TÅƒÉ ¡ä3Šç¨$äB ÇÑå¶j1]Œkûa&¬ú¾¯ÓÍ[g™{; âω4çÔr?'5¿ëH¿£üù }‚­™ááW·¬QMýÃ}Ô’_ãÎÙsE8©óñÜ™,4IÛòÔÈ·¾¾P‰a>ÖŽ¯ÿÔœñÜÛ½yCps¼ý½4¾ñà”Ñ}ÐïäñÇy¥ç ñ²HÜééÄp¹S”V{ d¸ Çj䔨 ËÄ—9¶´š-«5µ”¼=XËn1\Ø¡>Dƒ€´ƒo  ŠKù±þZÜ~PñŽE@JÔäýJˆUœ†Ü¤ˆCTò9P¾ávÃ#úü×ýßò«óH„_@bxÂð øOàSU¯²>ÔÖs¨nöC)TÁ1 Õy ¾8i‘\ÓÀK¢C¬9í½·¢{ °nø$$ !§­"D$²bóÔ³ä½ÌPÞ£DÔòôá΄cžK2m<Õˆ"p 9ç\shÎ7WXœÀ<ɵüUkA50aú¢t·‘ÿ£`x÷møŸ»jf¹d¯ü›\š† 4¶s§!_µv^æÁ¹ßQïîš¶ïZ†þw¿á°º›uCä>[uƒNB^Ú€:42—9®ŽXäïÔæŸjZF¢a‹Ûl u³ÕæÍFð.Úô¥ç€Y§ëûÊ‹ö­Ã Ò¢o‘Ë]½9‘ñA[B…4s‹½]瘚\6`«ÿG9ÉJÍö÷Ljlú‹¬„QÐ >@´ÂÇöññ¹øCb׋J^kß±œpÜä5`‘Aìû O5ð±Óê|ûûãg¹Ç<"áüRÜüÒØø/ƒÑ#ûÁªä“î‰!…q#v.{×V}öTèà”(d‘•.ØVx¶¡5ŒŠ,lú‚#áØÑ¢6YxԢĖGmx8´ŒØ$I”†#ñ‚Ñbà-(qb¸˜Ð*‡@Ù¡_=rß1<í;Mš³z™/ìdDÉ#%T§¬| "| ™O¾œf"Ìd™/ƒ~ö£yµ¼ì‰ç2W{sļÌ_EÁòÉÒt™·Œ7¡5íÛÔÒïaë XíX˜¯+þ4P>ù½ ß”† —Ó‹¡3Ødï‘ÍìwÁŒNYÉÇ¢ÄkLUOÓæçÒ?M˜xqP{4—ö³÷5R>8EÊ X±É•0 ìX½B"ÃQ-¾Þ>\ÜiÄÖIhryÂ++ßãhì7øˆrAR·Êa–¾ˆìÀEK8/y§•–깘ˆœàªðôòS­ä‚çæ©$xIÝô¾’g‡æŠ“ÁåJYûí°õ:aµ+>o~è¿UÃãM½ô7ª:˜DxšEihÜ?¢ázÈÇ­#˜f07‡D#PŒÆ  5l/>WÂŽkIOu+(´À-í¶Åi¸`opàÍõ0E”‚¸bshÂÛ„xßqíð(Ò˜çQ¢hîå_fÀ"T&ß–ˆ\‰þ±pÜeQÕûÐ|(ô¢!ôs Ï¥/ÆiÌ“D8%÷¾äVòŸ vÎ…Ò¸¢´ü„\äå–G ®‘¼ùr0‘]Ï•°„Ÿ:ýguýß%š,UôvÀ:D´Gð¨Ž+{„XyȈìJXŸ&Û§õ„õÅðbà´9ñiž¶`¸°—3ÿ‹SúÅaÀÓ÷—ÚŸê³p²ÚU¨ÃoK-¾‘æ½ð|QNÃx3ëµÌOžá% Ó©5Ý÷PŠþ½²YÑŽ`Ò¢š¬¦M®Í„2VóÂ8L®Ö¦^¿M²LAËíp©%Ú#V0-Ôûx<ªÀAÂ!­bÃAPìÖ@Õ£ÞøñIÿºýã‘îíÁ3Â/ÆJ€êKÿ…guþeÈ,Qi}è%áîèÕMé|Âöq;ÂâQ"烒ˆ"çVÑćgõabÄ9ÔKèÐF  @’UÖPJ—^‹I¨xù¼X"úçTá„”yMFˆ /z®ÀÕSq¾ ®™˜Éñ3k¸¨œ»ž®B–á ³Jë%¾~¯ü[ë,}[ÀsR–2;&Ù_ÝÏ–Ãꆶ¦íÀ¬fN_Ú,9Y°$vƒÀýB­Áù°QcÖ@¨ç^Íé°e<›äÑ¡tŽÜ¯fõ;GÅóLuÑ|å=«uùÂ𽫇¿MÀï„ZB÷«z›ë¥íÅÆ›Þ"6„WP*È©™ÙŸ‚áÇéc ¬l4`27D>ö ÀJ$Ø»â”Vð*ˆ%¤²¸Ý¹¶á¶ò©8´I†‹„,]­2¶8Ô€,±ñy£uáÍSù+ä-Üv,|>3@øî@þ¾Ô»#Ü¢â,ÁÙg*Ë#)à& 1*µäZŠ-ºƒ’çÊD‘² 9‘w)7,+vÒò ‰3ÌÈ@Òê(:¬¾„Ì’½Ò£F"þ²7Dù2a¡yÔŠÝéê/œ½äÁª.²J¬pŒ…¸90“7#6’£wYZíJ”èßì‰n~žM&þ*þ´²ë¡}ìPÙ7’ç¬cxFå3‡%t“ÌY /®¸­Ž€”Þõ& 'Ôà$†k8ÆI%¢„åôØó€Ø€¦Ò×'Ò·ùÁ ü{#=µiü0ŒÌ Ïæ×ùªš.`‹þX÷€?n´x×yøÍˆÍWJ—6Q¿8—‚9&Ê/†ßਠ;ÐhÖ›øÈ_ôs˜µí¤Ô¦¿ŠJŒZ‚è2¸‚„X|üZ°´TÏu§%¢Fä¯nœ®RƒHhBÉËèq`Yhwh ùÁëÞÿ=-íFX5ÂtQÀ=G>ˆ›æ¹ãQV£O"Ü€±P½{$*ˆðˆÔ›¢ûH†Œ¸—ø IDAT°Çšs·IW™˜Ê _v,Ãb)ƒ’†šVê”|ö¨ 1ax²¢‡„   æQ*œW¾XºЏ =Z@!j ªì‰Ø£‘oÑ03üó²66žNÚð¡Õ®‹x¿ò›ê\1²sÚŸPì¢EQej}¶r­ëvü5‡Õ:¤9i·gýßÁj ÝØȤYg|£¢›43Šä›§*ÇÅ‹cjÕ§>Ì22ôж\—Í.äç²Io°ŒçyʽÉ_6¾þ‘)]¡þ¬cŒß†}#ˆ§ÓاßqXmx¨‡çÉŠè´=ÀÆß32—­èÁ§í ÑŽ]ÍT]4©a“1«®RªÀ^©„T’?‚Ëî©Ã*²Ê„µbqhåÀâÐÊ>äö/ŸæÀ…Ÿ»_Ž˜|bëK©«/`Seü0·ZS·ÌƒwÖY”³=¥§tíqÍ!zW#åLÑs=(Ýñ% “Jÿ;¢,}"Ý’„qé”–åW¾‰0•/#y”ŒœÕi8ȬŠPp8µ”xT)c÷hcg$pD)ÈÐı ·ÓnüÒ©krŽEõ»Sú3ûáoëON‡x“Û®´ï/1d#gÆ.› ®ö'«Döº—`N«u(³ëp¬“e~MÒnˆ¥k è´ ,õ¾<|h]éÎe§EH÷!Î’fyÁß°­¸‹,s£…À ïŸtßÒí¿þù︒fÔ|R¥½õ¿´¡'iÏ¢{â<ô-Ó©]14Á†q£F¾%Wb¨Áƒp U„Ä{ r(w¾bOá ›£: c@©Ø$6 @ƒ÷Èâ£Xd®‹KÙ£QÁKb$Âõ…1KÞ|A }al¡”¥[¢P¼• E•$JŠØùÖrF›Ý‰Îvå×yasÏb/·/º0KË)ð©·"ê#•JÚ­|{¿º ÿ2aéäEú’âÒþGŒ+aì+a¬®7!Y=|,,ÁåDSW%GØ0Ym6N7CÞXÆ(ÎYý8ù1sÔ~n¾hª¬¥Îï½´^œ] ïJÿGÈ…?È¥y)c}µÎóµ7÷ gò“a"ê8±2|«p$¾Å0€Áì‰ÉÈ2_Tò°ìé0èynüÆqCTg;ï úhëí‘ü}Ñy¢ìû`Eœ¼ã!éé ©íõ€…ŽO|p¢G¼)²w½SZþ‘w­hýÀ§º&7¥êýÜ ^'uYîèÏnÇØ‰í y. …D‹Æ‹J+#ÞðP ÝM} §¡ÔÐ<(ùñ+QÅ\yÁ!7®òd¸²t/zÔ‚ÃwcïPea€{ü)Ëù•Aò‹K©è³ÇO"+‰ž›VÔ€üSXÿd¬›²ß|²øcv™YJÞ¿.‰.F¿&ááRLLrôsCœÓà|5hó¬ ßàͧ:åà©M»!ìQvIyö4¸„,™,íòïeW„*Y²wÙüývgóí óa±ýz5gÇ6gþñU¨ÖKðƒÍ£÷h?Aê2„™g:ü›ZwÅÒü>qþþr]ö7Ú[¨ýrÛUäŸKb1–›+^êÉÅÌÒ×fJ¾JþxÊJ{äƒL7 ോòýR×åácÙ(/¼{ª¡“îÃ’µhÃ&›`±a% á¸ákåZ¥Ÿÿüh7_Úö¥£ÓøoõôXAüª_Âþl<ëƒØÍºI”óNhÄ‘j¤G¸>*+¶ÄÇNkî Óý=/;Ck-›oF8TÀNÛ׿äu]º­§Ecž–ÒÇÏ"Q‡ZúÂÈ Îõ,".ðú9UKªGÇ‹\=Iþ à¨:n9×FG<½Ü¿ÏjAo7ãïsú}ÊÒ°4“¢Š¬ôä þ(¡«=?ìNãՈí½ÄÃK`ˆ’î4´–…‘™@Tb*DÜ"7¯„l–ÁøF ŒZ¤\ ³ •{…gã4fù»å{ÚuEÈo®?!æÏ±¥..=3˜¶í‰OÌ€3Àj„Î$h‘i2r@d„¢É¢lX-?ãT1ù #£(2(úB©Iw[릹ë¼ñYI[3í¡ƒd>ŒJ ¦Ï.ÌýHnv ²Y³ù‰âr8³óç¤øïeñß(øJ—GW¬üKoØ faî–næ.Ú õg9=kEq•4ráá7°Hø8hKn™Woo¸ö¢'ÂIÃÍ7bçŠñ$ïÊÜÀ)¥;¸Á-¼,»‹-P=°‹š/ÓæQ<Ú£Ÿ k+!¶/ÜÅò²b[isÜw|-÷/«.à!ÏÆõ›¦dþo=Ê•ð‡ªä“~O³™¿Ø Z¤^qaãz _ˇó5pé]aT>@`Þi1! E6G¡ä |ô¥/Ìe™(åJ(ÿɘpH —ëS»Qeþ’Ï4€5F­:"U@%d¥ x]E$!¥°I*O%gËS…ò<%¥ÂNƒ{$ K΋¾7R—RH)•ʧC/e'$t ""Åwž°|C¨ÊÏÿ´ƒÁ&î¿ÿÉdɤÊp;ù×qèP$Ò-2 € )Ħ“ ¬q¼ŒW0/²—å±ÎgAoÜ‹n–XvºÌô|G›æcœ;ñ‰ß#¿iJä7£V{ßxø½ žç©‘f®3dóÄêÉv9ˆ©¨£5¸³ZA‹YìÃj&ËÁR]Õ(!T“ÕÂ)è´y'=@ñ^~,¿ ¼C Tv^<•€º`Yp¨¸\BM›Šã¸/صÛÊþñ÷?ÖD ƒ©‹n€×V±]“î†sIŠÎbBºiâ |›:(™ùF5„º„Ã¥@%piD‘ŠSãŽG}©WH’+aVOÆ._…hSU•vˆ®=#¦>ˆ•Ô* V‹QÅÖR¿& —¼]/"e»J”&C°ë7MG€Ó!kô9Ø Kˆî(Æc ! Ây²¹ñÌ Rxàî“q꣜ŽxãЧD¹À Àª†}zá°d†’ñJÐÊË/VýEý +ïXðPÜ;‡ ± DÄ{KãßÔÈBñh%»škÖè<;ŒßÌ+‡M(ð‹M&÷‰7m¦œòE.¯›£¯“Ùñ]¸2åùψxã|ø“xxwÂ/žs§Dkàù°èˆ­×ÓàÜ]C8@ÐÂÜ,·ñLu>&æyal&]Ë–¤FÔRúGy÷âc¡ÈÊN‹çêˆ$ÕÁË„ÅâàY°K„|RÑÃK¤üµ|<þ¹6x|VÀ1VÂCŸ3R=ýK[Å’~+“þ7\“Î@[41‡ˆ„ q&òÍeNÙÇæ]$©2Ì™S "ù¥Â5·NÉ—Ø;-©˜Ë?G§:Üׂz2ɲÉ¥{qh >+3ÄY*×jÂÙ3(¡‹Z˜/ºèبä€Õk´†éexò¼¾ Ó,}"›iw×Xh`HëhEc·S½³H±Ü`•¾=>ª½²ZþÙñ~ÇŠÞÔ-WB˜  <×%ì¦EU×ͼnÊU¾'N%#¦¦Îö×ßëçíÏ™?ʪÂÙHê‹ìa²^L>¿uMãÛ‚±ïåçµvÒ[XÞ›Q«Í)€6‘óØåO”üûñ N`«©­§Í9~®3wÀgXs5ëdUO1óס7Ä]× hÁòqøT“ÛUÇí $C¹ €õÀ­V¬²0ŠE9P \o´ýåþõÏkw‡…à +ã‹ú¿öCSpÀ¦¹# Ú’î+àÕrMºiî@é–|CDûº¡Iþª§ê¸ ’ï$£&"K‚ ‹ªd~ö½ôL”êUtP¤˜Ç=¥ö@µò曋´H€OF¡ŒàŸ€U`tÏqC”¡L‘ë XÔË•›)–‘ð¥Qp„YqçÙ§¸™êsÇxòä³TéÞ‡¡‹•°"0BS}ƒŽZƒúòíI†)îù7U¸†$·Œ!kau[2ŽJ¾øÐ(ñk©dœÇ†s21™ã NÛ_Ä3ÇãL[²3ÎjzÞÒäŒ:”#Cwß*¾Yÿ¤î¯*—¾±ò¼¤B¾¬´þ¤5µ— «‰›„†pè/Õ|žµ%¼V6§Æ¨Xôž y?+uIR]C¸WkÕ¹ºcIœ5,–3œè$/P&¬nÙSûâ[¤ƒoaÝýÒœÇJøÔõðS»üŸ¦(p×J¾³›ÂSÕÝPÌÕ2ÞŒ†>£W¢kÉy_AüøÀ9RÕ+¡ÄÀPãŽÖ ^,1J––LX 4¢á ZxQÆËMKÝ<ÁñìuoR¼H`¡ùmàݸ9¢fšë;“ ׳kyÜë `¶À‘],ìZ7é:éi°±¤Ó¸RíU^€å¹7¼ Õ˨匸ôù“µé@`™°46$¼QÖ龇Ã'-ÅmóöGs…ýKn^5¹qÐ^2€¢ÙÚ,ˆщ¸þvR/£´h–AáM7ý;Ø2óðÛ…ox\åÓòiʳ Rº*cå9Ÿæ‰ s+k_Ç‘™ý-è©Òò†ºòsli1€UTV5ަ™Y×Ié¸là Zoùçú÷B{¢ì¹*ÂÊ„•C[°ËæèÐVº-ØÁØhýµüüõÏõîq#8†£étxš*ãY7]­ºßϸ^“šó³w¶/‰úVÚî¾-ÕùL)R‰È+?@«v¡$Î0ë†Å¥EAzˆt,Œ‹š …á’…QDòje1E[¥ÄÌ¡ÉÕU'¬,–TƲÈMQÈRq*h*z×:PGï¡ :U êÉã¦Ä# ô%Üx°é­»©M¦f¬Ú.9¬ÒË* œ¡´Æ/’A1zÑMT,º `¨2#h†@%æJÎQsñèQ™U]yvŒûÖ‹Ë W{b5)ÌíäÑ &,çÙÉ=ÚY;ÜœÜu©#½L¬ù-7´ïÈ,¾š¤Î»a›oˆ¶¼ÑŸ2ÿH¿6¿Î¡ÓÞ¤fy 0BPÖ™ŸFmΨr­<«´H/tÃ/]ôÁų́ÖŸïëm}DŸµÈy'Y »$÷Ò0TiH•ÇøZ°ñ'$ÊÛ#ÜŽ”Ø9xÆõ 릤ûßÀßÀ_*×’P­įz#þžáõIº':ýJ=àÅßCˆhÁíaÉ>:·4râï)ð‰0åADiªWÈ(’c‘±/]šÀCÖ0DŽyêPƒfo…Q'¬>”Ed…€Pe7 2C¨IFcïžâ,Y!•Øêé¾CëÓ¾—Æksßû(x«? ÍØEN² Ñ4à¥^^ +¼TBºë­o$Ã{ø¼>V8Uºs$%ádÂrTvŽšsÍûJ•©Î¦hgV¼z !‹3ZClÁóભÞʯ0¥3p¬ÿr%´áZ笺bâq²"^zÛ›Që·úR:í¿¤²!_þIÎlØ4÷ø6£Ûš–G†¯p(€½f˜8£Ãòjp‰Æ#]ÍJsUdƒk‹Ñ@ÄNPÔ¶«q)?o'·ïXÁÔ œè@’•P2dÓ—"+m Žê'ýøŠ÷Ï|Tïñ†'ÜOÕ»¯šK³Y;XÙ S«òY»¦0ßtlªêï¹\ î×íG Q†—H9c_pˆ­²i€rè–æº"ÈéÐôîUÛu•„Oòj´ïA_—¶—ÍÍ",žåIÕÌYzáïMWŸjy?O[Í€*]Ç/' å7¢‡ÿžo*ZÉ\ Û• ÞÞ!h¬øÍoI >wU{Ð8Ú´ëCÓõŠÑÄ…³j8¬ªPuèÏ.<›âzÃè:à[]o[ò™ˆ#—m_¸´a‘—œ0\ê—¾{TV<¤³~åm¥ó¿þùïíîŽq§>a-ʯGàð øþ[‡©MEQ;‚S‹NdÅdŒS£"¡+èÍÕ”È'ïz èŽeåM¼~ïçQn=” ÂÐs$;Èi —|½Eš‹Ã78§Y€E'¬¤*y¥Ï›Â"«‡±¿ZŸž>aqxrXuŒ`Ψqô†¨*-Cr9³ŽÏeE+aâUý@MiÕš’„Q^NX±uÀr'u¼3¬Ö@+¯øõÜ [g²ì?ƒ!W¸Þ ç¨9TÏÕ…JòaÅ&+¶†ÙUxÞÓ ñ 0ÝmCûîO 6¶ÞµžDÖ´Ò€ü| 3í9ꂹç%S¡~‹2ü­J ïc~›ߦ8Õ ¹ì™¡™NoÍvB®ñŽM7Û°õ¸¤AqBɇSlÖ‹Jk܇çáf>ÚæöÔôŒ†«ìbù¸ýŠ.oXg-X"Jè5ˆ‹äR%dÉMßTtºÐÇ ›{ªŸëÇök Ÿ¬Œ•zEXTq<4]+*ÅžÔ¢¸ë´u7¡¦Ñø{¢Nar‚8Hô ‘9QYCõ`J™b¡®É:8IÄUELØ=J5ì{ÅCBþ*b@¢])w}i¤;à I„äFØ;`è¤{ Mƒæ:6± z°§žÂ.¾0ÕkYœšÀ ÏÕåB$Ø4nˆü$¹@Aãç«ÔVÖú(Um=Óí©ãzÊJ-%¯ãU?LŠÀ]ÿë/(F@者 ¼ §êQo.5jà¨Ç«ƒç¿ø^ `[‚ T s¬7ÉþDüm½d_ ˆ oqoÈx;pñÕVHï[yðFñð}85¾rÒIìJ³ÓÐÖ¹ù›0Ëpuy#ì ƒkg¸ž—û £»M‹‡I€lÛ5i«·Š-ˆ(a­Ñ‰0”"‡qlXåu%$À;V%ò†Q È7lÿŠÿøûŸ?y%Ü >1ÉÓì¡ËìÐjíÀ]å¦?uì,ƒkש§­v8»éwöÐO[GˆŒL¼Ù¥ƒ§âQ¥Ãs-’j|¯Ê£¬À{,]ê…à5ëFÆ¡ÒòhEWÂü\Kè⬞YZY§ª ̽L^2ŽÉkVˆ6Á)½!Ž—9sO£—¼ÎæúÂØëMõYׯ„eM~lª$šiÃ!à›•0ž{6–7jÒñêRôàÚë F‘Ÿkíàz*À¡+D 4[w!põÔR8ÀL‰Ÿ2ö®2-—*&›1 ¿îgÿ Œ†ÈŒó3O¯?1§²- Y²øÕ:ÝÝÉ/M Ýú†ÏúmÀ]•ðìL¤yÂâS°­%ÝÙœ7c±•AM³˜aÚX­ä=ž1›w—Q´—é§éë|ˆ4ò‰Äá´ä {:„åá–èÒV‡¶bùÄÑ@¶€âÑlbH (_|÷T¼ouO ³ÃÂøE]¢ñ©ÄÞ Üÿ 8€_Æ ¶¨¸ô˜ÀdÞ2N%}€Ÿò š`€À-¸SÌÁyT&ôMËJ=ÔAâeLEXÄK¨Ö°7[§¡$@0HøuÌQ† Ü‹DÓ4×µ}s”íBð!k(ã¼äªÈpÔEX}»ªË¬„vÄjR ^¤ £€W¹,Iƒ&a]ÍY/‚,g\‡îü_Åbö”þ¥ y¤2sÊ/FäC âÄD¼,G¿Óµ™(z§ƒÇœ“ýÍ+ì%<Á›o^5ïÿlÈ,Ò¹qöùX¦;¡•›WX:MC¶î·Dÿžç!îe »ÌÒr§ÛDî4aUóð’à*<Ò—çM`ìà°†J+\EË–“™a¬„ÍdÔT t±2ïp üø\Ü¨È q!¬*M¨Þp€%‚‡z£-¢8nº}¦¿ÿù³­‹aâÅ8½¨èá/àoµæ Ò}Õ…ñ®ÃÔØŠæ˜x·"ß<–MêÑö Q#Ç…ÂA)PÉH ?ˆ0*ÂÚ QU•;ûž²€BE¨xéÎp€ƒÎS"R¥®ÌjÂÍǧq§Ê qhDI#œ2ñªÒª½ßoŠ‹——ï8&¢h„º¡áÏ4.Ò¯þå+À:©+å/ò°,0Õé€ègûÎ`²EÌ>>:‰6Ï®šw†̲ws½qº+A|;‰³^Z‡ìlø‚\lÔÞ¬zãqhp€ß5<>Í®æ†XÌ•°™xå¯h6*­dÞZ8@ pÀSsËáC#ljòÆ‹'¬UÞüWì±ç¬‹2Ó;ÅQûÄýÆ–Üæ×œbÞ©Ïé«f–Þà?5¦F8¬ꎹ|è*מObvx´W 6+¤?]ãAªš Òº¼åÙ‘õòç+a3E$Öå$"«R/)“Áä@ÂZ~Ü-´'ºÉ °ájfÇ -áØ°KüÆšÚ‚}£¥±ûô?¾ÖÛ—»·èñ)„;ð·†7¬úeª>¾hùÅh™xÚ”žG†ÛÜ­-T—ñ”üŸ¤hñ"N&7Ãh›…mn–«&,‹O(foˆA²ü=8éž8H÷:?3ÔH¤y¬bZ0ާ$•€À”á¹¹e±x*ŽÛB‡„ψŽ\D v¤´•À7l_¸Wò+ö…>\jÿã'/‰@À‘¨«´~qü醸(K•4¯fӧȪÏÛÃè!¢âoÒ4›3-" ñT/€g>¨.¾z_B¨>84ÆZ9D:„Ãy¤Ym:+¶'g±*Hñ²€%Ñ€¤FB“|WB‹ð³e§»©…ƒv¨¾aMEÙwi*cåæY[µ0œ‰³ÄÍÂH/áÆTýó/VB×mÓ°†³!úÖƒhlîòšú!zòÖ¦²¬Kœ~U*¨¥ºó"_zŒ™˜Ù›žzS²|i,¦Sq`5îÖ——û8`3Í™e³7»IñÐ,Ûb£¾8óîþê1“ÙßìwïäZÈÁóUnj; yÖ.¸“PöåBêÌ ¶š¡’ç#‡ZCj}¬Çb†i+a2 | t#=ƒ2Bª·ÛÃù¶c|aÃMˆä¤7D!wd”ذ,ØÜ'ï íŽZðåóããH‰Aø¤®¿_€ÏS¤²`Öߪáú2rY§¢ 8Ý’~ª$u0\ÞpóMÕ§ÝôCˆŒƒТÛn yÀ¡XÊÂG¢}¤5Äù —>ìXVlN£iFãΡö¬s3àQ³ªI³:x§Ž›UGøŒœä›)ؤÐdƒh§Ðy ôŒücó6iõ¥"tŸv»\ cAt ª‘Zx:ê`“¹c™ë¡|¼•;èÿ o¼Á¯39P÷¬Ö”vòO°¸6ñ)ï…‚nO ûdÜy¹Õ±aôýÜ?ÆJñÂÜMgÌrsâN±Ÿçh­v 5ÅiUüætH§Z€—ô&^ù¥¾ä%ÝÁÖ Ùê?ÿù~ž°pê~„A.FˆÏ¢¿ÃRcrˆ³¥´Ò}Ð^«î†‹±(˨¥öÃP«ûx$xªŒZ„¶âøRopyÔn GƒK´ÖƒbÁ IDAT¯Øˆ[$=üûçÜû&ØÔÁ´G i~ÿ7ðP~è¿-*TEÍ$CºË°9¦-¯dV3îq¹!®„„éÕÀðœcÊ.:×2ÅÄQD§båñ¨^"·„íñ=þ4 ÄÕ­YÖ@íRKAÕêàaê%‰}Jrω¬ƒ×=hÌ©¡0²´|Ÿ×†ÚIžN‚Yä:;DC¼©!ìí7¶l°–5ߘÇöD8Š.‚j œ[Ü­grDªx!=ô9"–Þ×g$pé²gÑ÷í¦—}jÃÅO62úX‰ÚG؃O0äL$„›_ÕõŠÆjoÒµ.1‹Þ8 Û›\ÓwrSzCÜáÔÁãçsa›Õ¸öo·‰Xçb3^.ãÍpúÙIR1úÛÉË=‘ç5pè°ªaâY£iVÍ«Z€rï@tÌn)?Ò/òØ‘< 1?èˆ7<<Ò ö;@+öOÜ=Õ€ºò¨øôïpËkD%Ü¿¨ÿуx Å8òÝFæòh®»Îܽ"ZT(” Ū¿eÜe Ôi2¡º> F~KëRàÒ[T×J^ý=Uê#rÒ°š„á2HJaEä!È%Q¨*׊#ËAÃÿdb#a™uðÝ]èÌ;éÔë«Ã§1ô¥²zåæõJØCµ¾Y “›ò´&äbƒYF)êgöІ¸´Ý­À_¸†œg0…|&Dì¸Á³§æ–ÆVõo…NøgZÝ™½’æ¸b˜O£9VÐõ÷:R'·Lžî„n¦Å^˜xÌ}<4§kÑïbjpUüuÙ½ô½²ô%:ÂÍóÏc =zæy{±õ„ù · ×àg"Ãåž?‹ð êßê‘VjkDŠÁ5ë…I‹·gǬˆ 8àoíçÇ_ ¥@ÕS‹\DôàµqzT4W¸„=a—¡à‹îÙqýå~~­÷ÏÿõñL Ôe Pû¡,‰ŸÀÿ <Ì~÷¡"ÒÇìM¨Öª~éC#‚Iãÿ¡Š`?bdjÉÞ“oÁIkó\"•áµÔ<Òžt* ¥†}/Eó”™Ð†•ZBltÅkj‡–¤& à 3| \Ó3z5£Ì„ÅôÔÁÃx¤Ùör]¯„1#¹)ª†LªøÙsڿ¨á_bK‹>ÖÀf˜°ï#B̲ò$}iŒèÊ’6AlªïéKò¹š×hÔWXüv—ŒI0pȃ TàÛ«¬ç»f†ëŒö÷‚_õBM/é»?Ip“Ïdž¥Â'R{áM‘ø­•åî󒚤zÆú×ÿÐ¥U‹€ÿ <ô¿¬[d1Áðò8[žçÎŽSc=Ì}f|ÂYìCýp”/þj†'Ž.¯‰|#âJÞSõT#ráà¨SW£ƒZpJvÀ¡}&+>£ˆ¹¸â ísYÉ¡gδ^}Øiû*:,U“>åWC¯¡˜Uòu„:`"U¯',Y ¾ÜK£Þ¦Ê >¾¾¦;L¼4j{îº ¦ëV+±„ÆÎûR!€ëSØÿ–y~ñ–™“‚Ññ\¦<[sž®!†õš2Ǻ?ŸBþlbºÎ\ÁÌiôO²Lù*ùï†_ZyÎ9ËnžûøÄı9,òŒbÍîlÖÆç"mBÆ38h²P0Ê®2K¼x>f“ñ_T}¾*=´j¨Ö¢yAÒ-»õ3ùc£•˜õ0/ج^vCY¦Dk ð‚ãA· ÿél?–Ã%vŸr%üR–}5ÁðŸÀ¿€OàoÅ©EµWI¿‰› bïãxF˜:“ÀT31(ù‘!›ÀŒL{´è r|¸THü=ÙqtÔ¤nZ¶BHîwÃ1oJªrAt¨r,]ÌÕ„#“; VÑ•žñÊÕ2ëƒÌæj<Í:È=WBûVÍïH÷û×–.‚®è37Ǿ Sí$zp'£’Mô«&>Ãë·¨£“™Ò9€¢Y›É•}g3seÃpØøj¶´vLt…]*ë§suÃê˜5‰/pÒdáÀ-i-󂈣‘KØW¾y×ÜÂt«Îƒ¨SQMcàå%uÓïˆô\È«b ŸÙ’d°ÚLÞ´¯V©ªlý¢‘ó«~¦ÓAÌ•bxââªw5ø‰¬!y®åE£DÕŠXrè%2ÅK¸Â»>Cõ¯Øq쀈C€i„jyÔlމ²¢9 cõOö½ƒÀ"3ôPQ˰ò X˜F-6í^lR’{]É€¿Ð:Èœe«·Eæ.KDnO¦ÿÍ‹KT˜õM¬z3€1^šÑ„aÙû6L&àn˜žL¸ò´$^Ú„lë=ŸBihÎu¡7hõ'eˆg‰Îà~•oÿüú­åOöC›o‘ÎÏó—u ÒÜ$éѳz=ÍØ¨³ö½^ýbR¹À Ý×™°§g=*~…oå~ûJþðÔˆÛBÇ«èœåBïQ7¬šŠw$ì Nj=*QK´ÿúùóð c!T ð#³ÖÕgA}ˆ^()‡%Ï«»á°Š9z=vFصAÙ†Çáõqæ-B8Ï„Huñ‚k™âAɹš GG†ää%þ‡–ºíW:Ø:K‘…›}ÒŸK[ÂxÜÙÌTe;ýÍÝÏÖxÆ5Ôv X‰L&ü9p _cªQ§¾h;mYéCì瀲b« \àVÕOÀ£2V¼ºyˆzû½ÎYtJ„ÂLºŸÛP‹Ê‹£©ê)W÷Kvg1ïü¡+ÛÈÁ·çgù“qÇÏE§V®õ"ª:ó\4W ý x½ôÒžY>ºZÝÕ¡óLêf—…¼w&› ËÊ»ü\Æ*¿’`„”µ ¤˜Ý°Í15Õ W5T kY”®®=IRàŒ 8‹u£-ËAñormç%ÒÁp_Ý#]òŠÕw9R]±WøÛÚ%š¸á]þ¯û)aã‹pS&á—~Gnº¯Éž(A¦7¬ŠK5òQR—âAxsLô†êŠú§ÁÔß% öÎpõÆ‚æ\ƒ«!>É !Áð;Ë͇©@¬®V‘5ˆÝ‡€£‹à[èʬf+|Ը󼪃ú™çè%9Ë\.WÂŒ¸OÖõ0|†±[v`² Z±f“ÑÃðH{­·•ÌŠ€²!¨eñ7 •Ã4üä½O‹,Û–ö[kï™Uçž{Ÿmƒ°»-YFƒ ž42X#!¬Oà‰Mä¯!}‡þ iÚƒc0ÆXöÀØýÚýúÞsNUeFÄÞky°ÿäÚ±#Ï{ü8<òVeVeEF¬Xë·~|ÍÕÏ;Ñ“yæÀQHC§‘zX]z®ÒºûS=6-mB¶Þ¥Þ¸oJoØ5âM2ÄðÐ`Ç,}‰a£I¤³6êmÏó¥x<Ͷl"ÖFëéC‡åÌlLe´IAÁ÷‡  æ4 r èÞèïT×…0ý—ô1ˆµçÊH|IÊ|ÝÝòm¥u¦à€}ÁšG¶,Ëäø÷Žë‚5cÕ7\XŒézwË®Sm¦<ø¥Z>C×z¯¡a tõɲª·ÕµúÕ´¦ìjN¦æfsï ¹Zö­bDeÕ˜k\ êÆqâèÂÎa§À&­f5á½F¦L1}\³®úÁïuÕXý³º‚å ¾YãñCŠ'Mñc:¬ƒ·ò÷0,¿brÕÞœîÜvvjr¥Õ¤‰e)bU*Ò`5óPêì50À„=ï•3-o*LتÒReÈ}mïL´?»V»‘0 îÞoÈ’á:ðÙÝ:½·@e“j•žô¯s½„fz6©a$ZïgÊ&IyN·‡ôœMŠ'h-˜¦'žËΠ<,`¹o<Ûa‰À¤Õ¡¡ ‰VVÕLŠÉX¿“ç¹7#a)p5Ë‹f¨ÂIºÌ·À»OºÝhÉíÃŒµÊ·k¶$nÖ€3VG îßÜëÏŸ’À¸ˆàK%=\ÌÄz©oï øZÑ·¦‘öµ®%c Ø ùÖ.5õ¸¥k…ZÚöÚv͵ÅËU¬¢v&uT^Â*“[ƒƒ³Ñ„²Q´3„UfZ „ì}š V&@d&j½c5|j&¥Þh¤`¨Xj}–q‹7ä,M kCØ0lµ‰§¹9l5Jº>6†S+,‡¼=Hôèã#á´UË=}ø?0«Q,é¡Í†tÏý—ÓÇ>ÑòàÙ(u¥­Úàg;‹ +¼ó™=³P®Œÿ ±(u5Kúø/˜Qâp]†>î0™‚ÅO V$úá: á&kP*=×áÔÇ:ë€(}g{h9¿ÓÞO¿ÛOé™·2 îÔOˆn°ÙÁ`¾l[UôN[Î\JÎôFS¶¸åú~|º·6õVÓHÛk2(Øn˜¨RI;fÚ|ˆž#¬²ÒZ%u1“Üo¸äÚ‚ fÉDë„M”ZßýËû×ä=.Tþ˜6fóåhr+"ð-ÛÔ6ÅN˜ ^!TJRn»nÕ/°i¤sé¹Öói3ÖV»ªT§¿­vXS­k0œûÙD(ì§p„©%öÉ»¼XŒì3‡Ë!‘*QÝs„"Ï”fåžEÔ§Ïm`T®Sõ=eÀÊÌ,ËÒJÏ1¬™>5à:‘YŸ“f£NäV¼rK…ŽYJ&,çVøöݬäÊ=Ô‚53&§Í <9×ÙS]…ýò;R±ú9RC¼¸ÇÚSOkà:JÏ"ãí'ƒÅA2³ôD!ê¯ùê-í3Ôž¼{"fFZá‰Y ­ô÷vŽ×³Nßõ«¡}Ç”G†ŠÀ†·ï_ ¢wK«AŠ»î,GŠm …ÆJzÐaèCÄÛFl®ËµØ;#«¦¥˜j¹E.Ó¼zŠw½8J€Ä;ÖL~ž*áhÆ={OØfl‘ÜEï Ýi’·Ï/iö`)f*[ÂPƒ6²iÆÔ²àÏy' ¸áZ0 ºïÆþÃdPs_’fÓ¾¶l­µ©aX®–¶­Î›9ÖSa‡å™Ô)˜”IÖi)³Ú™$Ï=;©8’¹²´\u}àÒO CöŠa5„ËUÇ÷:?e}Ï‘VZ½k4„Ó³ëã[^k¶ÿ´ñ‡fB´<øã±–0›ÃêäáwÏ6ÂnÃEÀû —L}¨Ô5—5͸ZA¢ì( ñ4í$šßw«§ŠXÙ+ÖIÁJ{Ó`¯lÒéƒ6ô]}ÙDxyØš£7dæÎ„ù$ãëC<Ìt:,Ké»Î3ú]2m FÌËõÑŽî»%ú¶„Ú¯µBøÚö®ñK]] Z6©7xV2FŒjœ¶Ôà_{åÁK½o)°ƒærñÓ‚åzwSšhwˆPL´\n /3–|—ÍÁˆîN÷EïJpNn×åN‹2cÑb¯*Ù"T`«%K3ð%÷Y;v‚0•ÛêUè)Ö ù[­Å¡æe„Úµ9ƒw£æÙ ±kª7๻`´S}ÂLõ>­º˜’çä³€@Ð S¾Šê™JŽt+7®$6Ð]êVQ«ÍÃí@ ©×Hç‚uÊÚVÌî!î+›EµÐ‹ÆêÔa6ÔÎHë‘*9ì½hx‡?nAÙ^&שÜ|ÕøY©üøâèà…ØkT"0´³ê£]н·²µÚÍç*ýxˆz¶×ël\"÷st_”³vŒÒp4éJýåÚ.z¢¦¶¤§Pÿ­Sgwù]Ìø÷w¤‡ö{úÚ!åÐFy¦Q[¬ÅÔ)œ•¶nÕX»tR¨TÒƒ˜¡ÏÊzÂYÿ%ƒ¾gªoq/@˜FP)vï#»Ä¤7]<¥¼CœqÏ×am°à>áEàÞq鮀׸A×/—ÏïþÂ@1Q)”yÖË;ÑL'E ¼ÿ·ƒ®¸%/´ð•ϯ{Fo´„¹æEáÝÌz{-ÿS­bT!üFŽ×ZŸΆlDBlZ-%D´Q¼ËJ âÛÇ]¨ÞÊ»SÉÒÅœ=QÁ,eÈŽ”Á6³ac]ùꘪÚ,º¯XêS3Z$Úk͹Üݘ:Keê#[-!þ 4,%éP¶¬ÉjÙŠ™të°$ÍØR!F¨`G ŠDŽœNÓžŠ´÷+:›7… Ê:,1“™Å9  4÷òê¦Hª•Þ§R‰Ü@¹Ý-TïžÈ›y˜Ô,3Þ&ô8V§I}0va4TëOg±@VE΃Ïý÷O¦’¡Ã“í.'N‡jëLÁCnýÔ\?Íd<šþ³:$ÐÝJz'Íz¹ÜØ‹£8é¦DÖ,‰%è\OÔ\³ž?Còõg]% zó—ä=@•_š#ZCõ\øvÆ·i…~@ ë„ÍÃ16ÂUá©°Éš)¯¬úÆ’o#ÞK=ÜMÍã+„瀞 «¶<Þ¼ëxhw޹xQ ²ÎÎÑ9×Z¡Dû@`VæÉQ±WÎH4@{e)e‹.zÐJµšÏ¨ÀyxØP"ÐtV°¦;¢¯¼x³›#ê\ayJå2è{ëª`c,𣖱 q!z‡~-K·«dG¶œi˜*Âåá\–k&8F"*±Ž.$öB Ý«³e2Å(Õ£ë (Xjš²gQ\É´OÊE¤­e¿ ƒùºbX<#–ÉY¼Å©öðàÌ5RÛŸQLÇ!ô0JÏÛÒ~JuýoáºÁccø'}ä¶ï§¿ÔsÖ$ߤŸ³ÖÄiTZ|4‡6i‹˜×ú@z ^»m¨+Ÿ6A;(aù´zïtIê-¡ì¹0aÏfl6ÍX?pÍ×ËD)˜ä^ß./÷ŸL„‹Bé±%C+¯Š°Þ|0ä ¢àmÆJÍÞµ€â¯õÚM€Øf䊾wz˜ª˜ÑÕ¦¬‘ã©ú5»z¸Û âëW–úÉM•@Ÿ‹fî+v‚ËÌQÙƒ94v(k`ÒlaêV ³Èlb5n65ù±<¡5L+$>‚}ŠŠZû‘Ц‰5„«uXÖóO{ÃV³ †è  ,ÕÒj±Q&ƒÔöÃ)ÿIyÇ,`«â«Ù>C‰Äir”Â9[É»ž ëU²ô¡ÃjÑÓ4HlPO}_ L´ŸâÌ%Nõ"Ëó°åØ{Ó­Äâoñ1<ôA6›W¥¡ÍÑ3f|W‡ˆ3¿@=úY?žsxLÖSs| ¥ æ>2 “¯=RÓBåV‹×Z­¦zìbŧ¢Q&Lo0¬ÉxÔH‘¢d~¹*ü’®ó»8ˆ“îLY`¸æœÍ€°+xÆ–M¦Ò‚5ïÔ‚î·Ÿ_~º‡3!¢Hyr‡u1Zè…‹b!ü<á˵FN;èŽuÁ๻3»jQ82Yau”s†VêpÇ:CÌu6ÌÇ}­­–«ÐXëF]%ÈY8¥åý8z|̾„•)S >9Ÿ­ãš7džKo‘«uéL½Ì–­rÓ6L7ÀUÔ…»5²~¨ÜáØX†¶41Òcåzd[ˆóä¸aÊ÷¨QK˜_•ýÿ2À™®,•¬nÓ±ºdh è4 ñ2ßɱt:‰e´ï’š:: òßgÍÆwŒ¤D|ì.ûØ›0Ë`írPóØÈRê«‘=À†D.=Iã™müÈ{À“gÊð°Ńɫ/-ÛTÊÚ¸÷ölMz<+Ÿ9 ø*3M#îeüXö>˜ç 2m›™dÀû½’"8êËë[ m¢™!PLTÐåë —È.ÌꑦŠÍO´Nºáëüé6]Rt˜ “‘V­Lñ}ž Kμ¸âcBüR—ï@@\ W€páNÅ1?°!=ÉLŽ¡ò*8ÕªØzØZ)¢)rpŽ306ß.[‚‚ Ž¥BŠÉ9fQ d ‹¤:Ò(©zÚ³nq/É`™º•txׂµbºƒ}µDåm¢„óœ[*é±9ª¥C¯JÊX­\,JBNì5¾Ñ˵bóÙmÇ‚ñ™­—»ÏÜdJA5 Þ*×#»zŠüî(ÁƒRÝ™k‡eµièóŸÇ„ôH8õXÑX×à@±´ˆ.06Ér¢§‚5bDâG0^ÏØOÔ7\ôÄ3ë;::£2ÈPÏõL~82ÎhØEðÐÊ–ºVûn¨ãaö é¸j߃ù¼’+Õ@]Îôhmœ(A78'—éî}dRëÃËaõˆy‡˜#K2ã^­×™V‚8M3­¿üøcšjÍŠT1¬º:Ì¿ý…àQ|óøåG¬ÙóáÜ€;RÕ¾9¬ G5?QKÐÎTkš©ÃKí¡63 ú:ßmµ¿u¦úØRÕZ6gv²0ÛFgx?íîäÐ*W#D‘8Âæ9» ©CbR¦…TÊJËjÕdáÐaÍwøPŠ…ñÔ M8ib\ÝøZÁ²úQ§D9âYÀª$`OÑ#²*SRЄ}¯Îvœl~ÏmØdhB”b_¿&p@ Ø’zOûâWÖ„EI ̱Wû½›”LÙ8Xêٹ΢,ÚcÎj¸©¨fõ  Çw´wwxæ=áúÛEÀ,¬ [<Ñ0ésoÒg¨–~WEg¦*|: swˆÚ‡sŸBò _A΄µû^¯Ø†ÄŸ"~i:#=\ ´ Ì‘æwb½cΩt7º8ˆÀerÇ…JåZ2$ï)-zQÏo¯/ûtb$Å…JÁš*Ã`©Ò?%\ïð?`ªœç­"átÁæ0sék6`Vx*¾úU£5,•ᵚq©º­[=möâ¾Î’í™Î4ÿÎ$xÃù UÌØ°Oê¨lËxRbh)d¦mJо‘>¿¡æ[áTæ"ˆ@ïgÚÖRÓĤôb*=žBá°‰²6#¡Jì “Ý…8k¸ª½Ÿ+ÕögXg,¸KµŸ°ß)yDUŠaÚˆ:×BãëÒ7š³žMÁ’úaè“‘{ƒ$3Ö&0ߢ©LÈ^EG‡®êt'O<ëµ]¤3g>íe7ß_ â‰Àp4Û¢'œøP;åÙ‹É:Ø–Jo¶¥Cn·¥a•uu½³iªK6CªŸ~C-wƒ4}Oا AÝA\J×ë»§IA9ÜaðŒy–'’¹ÈËdƵ*g·…®Iãx›¯7¾$qXžJ¸TjU+E ×+>f$~>êŸñ©T‚= ^ÀŽ ù3˜ct7‰j¡žê›GS­{Ÿ<æ áå××:#W féjÿ5ÕsÂ~·H´žrVN ®\/ÆÉ—HÁí4õù{19Q¬®è9SÝ3°_Ñw“‡ªb‡°TöR!ÛlHP@”Ë[jQN…’2ݦ¬Wºm î3¶œSTÝRƒê{ÈŒ´§G0–LÈðˆ Uì`rÏbc¯¼›ËZz?„80ÝÇK?Þ òÄͺ®Ù‹'A|Æ1¬iÐ qV†Æfçà#g9ôÄ C߇3ž×hªE=HXzZ‚õ=šÁ™Ú*oË÷ß-ww…ÛKêoÑKKï!µóM} ÖÆªiíº<å”i…ƒ,ÓÝ…èL[@Là;–ìPÊH.Hž°g$¾Éì7Ü¿ùO¿|þQç:Íy*ÖR}þ˜ €b&|õøù'D|«ÿÒ#ÔP7¤€4!ÎÕ;‘sk±!õUÃè´µl^ëW\æ¹ÝCåžÌæiÞxTr-X®ÞÑ·úŽ^bS/ïâêIŸ/ålxLÐÜ-¶³”U³~UÆÓµ IDAT͇ ºR>Džʳŕ%vT™‚EJ¤¢Ì$©R›ëZã%Ê•ÌSËè™[7%÷1_áÈk|£×„Û÷Ž}Á=§ª-¸7!tó›oþ\x豋>Ñ墢œˆ™“Ÿ"±¥«TO5êgªÔoìGÕÜÁŽ3õ(‹1‡3ðcŸêRBi¯h$3÷iO¶?ôGAù,ÛNÇ’¶ðĖϽ±ÀñÀ/;¼p4zæ3–,÷M[m1MÑsæ¼!ÆM€pR¡C[§RŸM†¾`YÐ= d.ÓÑ^‡ˆáºž¿Þ°°ŠM%SZ³õpÞÙÏÈÑÓðˆ ¶TÔžbò|{¹ì.@)ÓfÖR«C6ðCeBÇ/?aËÃÞ_fbå*Õ]®Àa|õÙ´°+˜ q¡Mj«™ ­¾§­­”Ú÷tùP ÖT?§Xëš5äZãÂ@ØvæRòÆý†žžk!aR8²Z夕ç)ˆÚ3ZV„>¬ùäÊÂîžóCzXzej¨ž dnQ©òÇåx÷ºƒÐ˜î{!.Ä&¨Çè‘D¦`•Î+‹¤D³âN—wï#ÏR Ó@»tgé£ô¤I°Zh aíú´Û!)¾dé<œ“ñ¸òåÑ _„Y&R¿GU:#1ЙÄç;®Ê£¯Ãa÷pÐ?ZPß}—?Ág4ˆÐo,†•jÓðP& ¼€VhMF^ ½[V2M46RÑÐJÕàY\ a2’ª[nµâËôî)©ÒDñ†Ì¦Q $¿yìYÀÇÁÛ¬«§˜È]èþuùtû邉ð®ˆTÀ,Wi¥®î/Lx»âã×®ÆZ_k¿´Õ|±ð-` ¸;\X=iîu¦Û ­4ô$Rg˜YVkÝjS0ÊDê]OC%”lf’·Yž\D20kÁ2aâº#÷¶X¦Nf]o©š—ï³ôþÒwXèQêÇ}3'Dª*ï—ðæ^œÔeì­)æ3Û%ûL·h 3$²>,RΑHAª˜hŸç(é^C⩟þpV¿,ènÿ:鯊¢c.5¢2\@Ê…C=­‚zR½;ÛLJGì\†}¢ö¦˜ÿ<%>«bxÒFÑÙ`xøíÔ»øP¯LB=™ÛPnÙ¤{O+³'‘ï¥Ô/æ½þ„fM£½¨½Ü=/2W‹ºpF‡ˆJKx×e¾§@›Ç’a—÷,yÇK…öKìm™óü¡/Ž£^é>-T ç dµ†Šˆ;Å…ðW|ËV[¿¿Þz{žÙ~ÈÎ5HÞ^À OXµ,ï6`Q= Vîª>êÐ×XZ8Û¢à¹ì™+›$¨ÑS[ÿå{Sm2T/g VåÇ Vfޱ¹h\û>Å'0poð]xFz’å*¼]gø¦pÁ‚{&ãÍX#ü„5gyì>r0·€©È)©ùveK ¤Ó¤LB eÁÅtVqäìoOìr Dq‡—ַ赳„°o!õ¥Ä›KÉrÈÆñMƒèS<û;DzBôÌìAÎ<Úû)þ“â”ôij¢+00©_5ˆ‰¸/U,3B³Ô¾u²Ë×fÆ’Ìݨ-—z¹F3cn•¥5ƒ’¾¼~v9•å-aÉÑ¢R9¶ï2Å4Â/´zD(¾ùOïŸ_Dð®ðTR-Úñ­zW^Ž@¼OH¹*|>êxØlF¥667hDòe<¥&Í!8À+6ꮽ ­}i[»Wo&V6ŠÅhà|׳´œÉ÷ÜÍwi¦ZЊ”-X ¼Œk«]"Ì= =#†:…¾Ãâ³N=ž,=ë²ë¶ªêi•I ‘*)åàhÉÓ\¶¼Gš°f^ì‚{!ñÈÅh WqAP%%šÃÊ$DÃà3º©Ûù*=çaéOáp¹§~6̲’Ÿ|ـǯýo°éXz¶ïÓ]²*eg.ìƒäð`ÿEOˆ¦§2CœÕ5xavfLgþîÙ7‚ o”$ĹÎ~u‹oõE™Ï&Aé'ê@íg˜$1:ÍÆ‘òÛ9–šu8HÉpŒ«Àöv\É'ãj diÀÓ¤ïe ‰âwñã鹎šz“xÛëñ0ùZ?×/ØT"kRÈæ8„ž3áÍ›ô€W„ ”m2K+Öã`á`?h=Ù>Ê™õ ÊH<ƒ6¸‹¼ÌïìÄWüŠ%ódÁ*pûŒÝ#æD‡¤€§´èºûp{¹ìaÒ@¥³sõ÷6|§ _„«b!ü_Ÿ±-µžý°ÖO š(±¹§º{èŽ5`õØ\æ“•+Ô}¥«´»¤žÖ ‚ÍÀز'³%äþŸ-XÁNÑ#\l"O Ö‡YIRßjYaÅ¡`¹3/> œÂó'‹L$¥h âYˆ”X•…øZ¨Í¥«©ìök&4\Àž° ˜‘:}5‘(ƒ4x ØIMͲÞ<|eëiîlKÈC‡@fN¬¾R1Š yÈ¨í¦±E¾z󩬈tfƒE½¢¤g žCËÆ=9Bòô„ƒJƒM ÊmôµI{×°4|Å J7x™`RA DÉ[ä’jqhüƒA!Ç+™›F2Ž4ÆÁ†jð’Ót]>&Þ‰ O)£ï9·"Á9Ä;v-;V aü Ë®á½~Ì×_DÞ§PƒÄSM#àB˜›Ã·+n®X.á ð[`-VÙ!¾3‡ÉäR8ì âfl„;à©”µ¹ò!îu|©ŸA+X­ŒÚþ«Ùí7èê ±n,yÞU¨ÆyÖ¬ý;Ë Â06§Ì8º³ ¶Þ:Ì2 ‰¹.¼³"‘zÄÙßü•X„–5òˆíÉ9¤€-ÁD¸¨ËÕ$±‡G`&¯z‰œ:šæ´ù²Óp›µ—š7—»˜3[‡UõÊô;üô¨ÄÕ (Á§GxŸe9P?±©\Ï€rB«èÆYôÌ,®a«¹giÙú¼`½Š§à†ÄogË=i+Ðû¤Ðúp¯ÃiYŠ“‚hó¾1‚n9ÙÑFïœsî6€„­æ;Fóˆö?aZwø¬—ô”0íœcêàzv•½ £N !:‚{Qû Ä88r——-¡ÚiÈ ƒÚïd fꙜ:¬ÿtˆí±íRÊÓiÍõ=Ï6‰|Ji(²tÒqv/dS…Ç‘Ó Í½SèÙªŒ 6A}ýuÚ“#nÃô§Æ-ë°§h9cû¹/š ‚›e™îêÉ‘„ªJÀî#Ü[>“ÒŠ9ÂÏØ&¬LI”&Ú˜ô——Ï[˜± üÄ¥þ9ßp&*>ËŽ°þü3î-™'“2Åt3„…œÆ“®kolªcº ÍÈWÅÊfK¨%Óp5!Õ­ÐðáãÍéëŒÙ<Ñ×£gËY;9¶g–7¸{0÷'£½}¯A¿ã'ìC}‚ÁKïh,À 囦\xãé}z Ø¡`J™ßÐB°‚/¸5ŠCöÒʹ¾WÁ!7lrG‰€]“2–9OüÚL‘ò&Ýõ„ 5^€07 È”©çsþühr2 âQÑ8Zñ¥ñ¤ÞÏïp9í\ÆIýYÔ …—Θ Ï|¥§;àŒP*ƒ»ÏámsïêG}ãk§s÷$ÓLÛjKA,EÐOѤ0ôÒ:ÐJ¥—Jíõ¯šÍ¡ÅÑH7ðU¯/7ïRÀ&`§q¢=§ÕUcø~~ÉÃV¤ÄS¾ïª¾O/7w8òý»`XSÍ4›%8à¢à·WÜ'èR÷|ÙŸðݰگõ -EoùÑk5sØ ê€ý‚ ‡­š#φD±×"5¦Èd€-®½È¡`9s\L{ä Œ•N·„·¾ÃâÞø†{w5ôÝ¡`ñØ|¸“Ê€ª€¯€#t¢piUb¯q¦MŠ©µWÎ/*=AßqÍ1®·rH¸4cC†2%Uv>‰X”v¨«.%Ë]+úhK*õûo<ÙNð`Ñ«†q.vmZb,ô¥haýØs-¸§‹¹³tf€•L3-½YÂ) EgûAzÞm=§\VôD-»‹æÞ¿š{Znìo‘ã uf¶Ãï|/<¹}éŽrèIº\éZt?Pãét®ýKcé|Y‹‰œ£R†&êz/æ!1 f$^à¦ljJ˜tnÿôºSÀ¥nˆ–J³˜ês(šk¯øâñí3âfˆžY~˜e“of®ÛªW¨×ó¥*¡½ImMC=6‡Íƒa¡Råcvy¯¯ãjÜL†^Èæeiͽƒ ÷„ ß_Y‚µ×½§¼ ¼áópø¡óÕ:еä !Þnz¨×¬Šb¡äümáÄžHT?6Ê<,da~Ps.Š©|‚ÓZ¼² M¦¡ÎXó'VñüĤáà6ãú?è ânç'šçï×,K¹¥31=[>ãÖï&̶{¾ïà¤WmØã“€)[Jµ:ØßX›þ‹LjÆØ_{íιC”à—ô:¿yJ^£§˜àr3…šñ—À¾M\À…! õ'lðôí‡×4û’6>ӣÚjS“=j˜0+‡ßü r1†¿ý*AJz¸ÖÃÙ¬.fËkñ %up±‡šw_]ÞwÀ×Ñ×ú°QäAí{Ð Këw¬µ2ÝÉÔ9Ô¿” ?â°¾ò}~9ú Õ=)XÚó’¢<­M¦˜Ê•eÒ Þ.Ü œÆG mñ'ô©d¯º!…,/o¹3ÌRN`¢²O Sd’ŒÈjul}ÀêÚ+ŸOc‘-õp[§žÑZe2Ÿ™VÛ_€w=Ù:Zê¢ôÌ#ôœ©4ˆy î=.gAz2Kºú.ª%=¯bTöÈ^6‚ýÚ{Z®¿tïù¥$~jvÝܯ€’y^2ìqíICɼédªiÛ!^@Õ<2ÐÎA<ï1)ßéÒ0¬;æ„™ñ\ Á³;¦Gœt9½]^w JŒL9/º¾+_{®€RÎÖ ïkËÕ^€/’ú 5‡oµr´(‹­âY0q=ËC. Äc÷ð¡\ì+!Ð#SZŒ[–3•ën„;S-OÁô@Þ`aç´†6¶Î¨Õ©ÐÛ>ЙùöiÁBŸ¸ðl1.½¡®íõ\É2iTUh½ÌèB7R8’÷b‘Œá'ì{1#)©ˆÔ\ä[xOC¾\>9íw¤)¬Î¥¼ñ±Ó£ ¸¾¯ä>÷jTPºaf9YÜÓn¥8«f5 ExéFêCUнpfÐ×y§X‡Ký`Ac»¡ñ=ÈYeÁó²%"ªOd‰‡BÉ= }7=ærë¥E½ÍŒKp{uWŒÞ¤XjëJµœÙÀ‹ÙœõêrðKâùî]Êè*—ýu X"Bfiå*sÂùŒ=ЀTfÚ¾,Ÿ?肉0b´Ð:^IcŒ*vÂWÂ×+Þÿ*tõf.-ôæ¹b(³+µÍuSUæ>õ^~Y¼ŒÄˆ f0•U+}þ\5¤J kÖÌÎÔ,2ët«@šÿ-:#gÑ0‹iÐídäzŽÍiÁ:Ä:Poe½)Šâ.ÛnÑvÉ’C&•D¨™Ì•c2@¥`yS›ÔðE¹wËjEfzÖa}ïõ'’Y´ñ )ó0–F— 3B<… `؃š'cC-r1kžL Ú/A&§ÌIP™ïRö¢ÉryÔ¼ §`‡«Q‚M¥.°‘¨¢ÙQ˜w&%¶¥¶ãAûß­kØaÚ¯töÚt6ÞR¿‹ÐÞŸ²Xz¯V‹¾o–]?'&æYZiÛ‘‘q‹×å—j°ÀÂw瓨Sư\Àî±D KKâ @ƒnJD¤þúöú’¢GÈ%©V©Ãß\kË€ðó‚÷ ‘jg$æv†ýÑh` hw«¿c©‡ …^×A¨Ã¾»Cpݳœb£‡:r5Ibn ¼oÕšá¼ÃjR WGPyîSÓÆñ³“ã}ü,þFl¦*C.ßÚx®H”^ùcº“* q …NMÕ2Þ ‰pÙ“(‹N’ª©VË%TÉe™´0ÍóÎ$¹dt<îËúáof\‘ÄÖ!=ùPïäX$ˆ‘]­9•ñPÍÍ‚#½d¶ûvˆ6=ì@›ÀYTý!Qž×;zâð÷loø¬fa±ÔS[1xgŒ$wVŽõlû)6Éê-— ­MÂy`\ÍRÐ×_:¯?™°.å Þ³Ña&ÓÃ`‹Ì%ô‚Äó‘ðÃŒ„MÚCõ½Y·®ã%ŸùÞéw ß•¢O™¿_k ’BR8q·ù*ŽUY‰/¸½Atk¡êm.;Ò$¸l\›FGøìîJÿ%$›ÛdéõâWfyXh¹¡øÆžƒÆõ|ðf.p=¿S‡¦Œû>39æ?Áïpzô„¡ý;xØ»€ï[SJï¡„Zçu4 #ûá”ô@ß5h>TÉÃìIO^8&éàn:bP ·h‘ÉS®YÕòÁSÓXÅ:$‰1Á‰ýHxP)V%å¸Lì×ø²¼1¥ {$Ÿ…;džsî°¢/Ùw4c%‘l3¶ýýrÙxÒì³<Ñ#¶y‡f¯ô øJP‡ßþ é¥Z•’Aˆ{z1ëÏØÇGóøn§¯ô0We@T`/õ#-!»Gà‡ù +•Ãx€á›«Ï èÞ2„¨"d¸ÊZÞx3ûXìùpZ¹ž‰³,„pöŒÛLé—~kàžèUwÚ^&ö¥c’ܳü‚›‚ß! ¬˜'l3Ø#¹º£±JÇ© "(“ÓÉíÌ%F¨T.5gêÚ[dæzë×xÑ,k×3böÒSác1),Çj—£z”ÝŒá€c”C<5b?E¦30 g^A2¨¦yH÷ÂqÀ=_8Ž>ñ4¤7âIËvÚ Q_—Ý𣴇ºü°Êœ’ì=E0ÁÜjmÑn&1=ŒI»ßëàs©Ëœªð”^æŒaÝuw´çuøT¥Ñ‘kM ظê¥Ý^ßç×ÛçEcRJÌ—7y‹©ö5¤€ÃÛ7ýè’¸o­ãªE¸i7اžXXð‡(1³&‡5 fl\²6v*ðrö\e³F8?Tî>•c36•þê:dcPoê€~hÑ3.å¸:Ô'<÷Ä1Î|Cî-…øöé²#$0HEY(ó°2>åê™¶à%'ì5;:岕]в6µõ_‰|Î7c粓*FnéwáMYFƒzC{PêK•ômÚAK’¤X|ùýèÍpÜ0Z¡¶¤>\ZÎÔÒ“ ô¼óÒÁ’Ïìnâ5 “Æû¿Å凗’"$ðÊìô »}öGOTÝÍ1ÍÇÚR-à(ó²þà¾Ú½F&ÉnàÙ’¡Ùò€©âÄkÀ.ð^c ¨—Ÿnî‚l¤Åõš—Z°P÷qùN;¾LøFgžÒ£tè¢b\îSçdX(©mrü0 +»&l9Ôw€ ë‚Õƒ€…‘LúæUKSöÔÀo­µm2á<ÎŒu—ø`°ßóKmiü‹†t:ôÀÖf¬‚¥Ïm.¢Ò@»ŸÄ¹ 1R0å é¨CÁ3îM`Á=GLY3”7Œy`Ü2`á Â*D*Ló¼®*x\Ïs#eC"s=‡ËÊŽÉD¹æ:tժ̖d…R³,ü,½:'öÑ0–ó¯Qí™a8£˜Ò@ç3‡, hñûÉõ ª%C0ˆö¤­SR;†u¡ží%¬µ¼ôÉæ¡i=r*Ðm“F7®—¥5hOœ£Þ‘¦öΙY:¿®äÔQbU%vˆY›á'\š*¶ó¼¤ïi÷•ˆf½ûY„á“ÂSaZxÓ‚ zdN„8u›šÜLjýë[¯qZ³têÍœÖ[¿¢)ÌÑ|t» á æÂPÂíR ®­æÝgOT©eË,ÅÐërêÓÄlmB/9dÓXñô¼`¡?_ð$z¸•€ÅUÓ¨!\€oŠ %ïÞ—ëŒ5);J ++Á¥r²”Ø6Í’Ãìôà ïØfxø!(#À$>㤠#¨ßZîu6E$Iôq¹$Ç ŽU_èmÜ…;>ó\|®G NÅßÍ7î{û×™@S¥Dnwï"QÉM)—é:H/ÕVߪõêI½yaì¬ t·ñ§Ù>=*¦ËYí½øBÌÐw¸`ȹ94¸ÔWу„ôø÷(0tÏçÿxz>ÒY­‘A0¤Æ» g‹H\ 1D‹ÀЊ¬&)Ëu¡¥f=*q¬›81R\oÒ{qY=úܯ³UwNQbТ—ù&"©•ÞŠk<â[„û@är÷E¶| ’ ÛŒm¿„ÍOšmJ=àæo†JŒ÷…žÍÉÒ£›/ýXüF5͵hÏIï„DP ¶ÜÍŠY5FàR.­×ùfºP^‡-aqÉi`˜o ÖãÞ‘˜ó7Wÿ&T§)C:õ5Úfï9\¶çÖþô?Ø?¸Ì09™»ùÏký¤³½m­ÊŽ…T…ï—E<©A÷oô)çSÔD©; ŸêÀhéïÙ °©úœ@B8ͼNËF®ÚïBkblöí<øÄsïXn_uX&Ú ÆíPSfÃkçÃýõ9ò<ó¡M}×#g]úöêÐ"É{POÒ“j¢¿‹Z…3ö‹ è~R1ìì_d—q{Ú󱕸Iá÷f©‚‚ÑñŽ\¯ÐßÜU$f±è€TÕ×e“­ËõÆHŽ’*ƒ(Ãð „¢ó qˆúð¨qL´;M…·éõþyuà*‘jJÕü/ïO†ä±—>2íŸ 5—°64섈bsH®¸Eí¹xºÖ{uª8©¶]ëˆåûI?¿€ÌRÅ?ò.$@@ˆáq’¶—£›©Þ•òyÈãÁ§ƒç²=‰ìšÖŽ|Ý6„«ù,f¾\Tm×Y'rWú`¨€s¦4A=¢™‡¥àì™Ï€KÿÅÍÝ!Á+À‚Uˆ(Q˜vGB uUÄcÛ+7¬Ø¯Öâð•½çl‡•ú4z“µPœénGÐŽu?‚J©¿Áë`S•žR?ÜK_ÔtàÏШï˶¿¯+t¦+§ÞCú®Ê,›Ž' ëßÕ85ï(þˆÕ7f6×* ¾ý©Á@]M¢¬¦rq‡xdŸeG2Ï+»R mUÂÒŽ•³õLÞ¥„HíŽR„÷ˆoîõí‡Wq@+¾P9rÁŠ}lm7hos€ŒÕòLÅP”JGµ+”°v†›‡(Ð]ê+¯µÕZ_â£`ýhœô£©ºT÷Žn°ËÊMÅ e3 *@àZ°rå:ºÖ(Œƒyp˜Ò¾­•ßà yíºçSáµ¾ñ+å´_C ,ìD9<0—àh½â}C˜°MXc!á! wZ©Pí^$U_š¤.‘ŸýÝ#•V+k/Î÷j:Í{¿uG°)1#H¯f–DïÖeŽ˜ÂG°v¥òàÍÂ=*¯½@ZžìÑR1KOØÐžñŠŽ;µü>?ë %gVñ®':Ⱦv0zǰ–%°¥×fQdÒ´ö­±öÛCC+½šÚRù^ý“ÊR…“Î˦ˆÔkÌéÂ) F8Ý!  ©ÚÆ{$=ÂMº9J2¹w‘À B¢ÂÉjY«¹è|`ÏÓ"™dé\צ᥸t¦{„WÂ%ÜÙ%bP4óÉhTrÀuöªñ##KlT×»Ðlêïuè"Z3ëLµ[©ëdÁ†Ÿ›†Îà”Ò{ ©[–Öáâå¾¹“f¥gVCßi¯tXzê°—õÕix?‡Ÿo²œ¦cÚ#tTf¿²½ò6ðàµ×.ÚÒž†°¸üÚci[ #šTÁ|]yGIAªð]ÑcH¨¤€%ÂP Vð”œ&%r.}\/;˜«ÙËlvàý‰™Ê©qÚ¡`I/ c^ƒP%Ó¶l¥º-T\Dƺ *ذ Ö4ƒ P…æš•ÇÈ­þ’»Ùì»f£‡ýL€š‘{‡TÛpæÒv1J©ë5it¶Ù‚±ŒÆÍÕiôàë’­ir—%A5ñýÓ²aR"Rr¹îdf–šÊ¥@.OÙé!'ÇU~©8Ä n9s,Sᕈ!ÁEæÄQ°BÏ@oµéa²Ù"µ’½õ‹Eô¢kíüôˆ”QíX)!Ä®Z¥Š™*$Ÿz9¬åçúþª–3»ÂPÖgϸúœâp ožR´ÖzÝ:jªÓ™Å!¯¨¼íœ) c¯LCMÕ~M †ãúïÚèÃÞ#0/%vö’Ç—Œ`äÒcÏ‹ì¬-kÁ<;‚Çî)*Èi ¼½|Út†X©Rµ¦af`H…;ýxÒpO~`<Õ#J]ñÇú ô_Tr“b#$‚oÓ‘8ªøDøÑA°ì T ¯µÉJÀ·zbß{Áìfö`,NÛJ=;Ëð+ïóáá^FÃm”é¢lÕâ]¨$h7†mâõ²`®„ qò4á]™Y’ú¼"#èù_n»ŠÃr \&Ä{DκBD‡À#!;ØPÌòä“\—B8 £%”rÚ{þeê­ iPDPÖˆ™Ì©–uE#ȧ'–Gu¸}R_wÒözà(p/Í‘¾]ÐÁW‹zN)ýÞ£ßï¬Y§;ă^šÏʆd:Û!º³¶ãÉ+k^€œ©%uØkJo_†×žd @*-³ŸÓ2Ý”Éi ´'ø¼;jËŒ„qC¨NJD„ ;±þ|ý1†OˆŠ©RÞ]]¼ ÑÏô'椾`ôˆÚ¬½ÿ¢ö€lÕ•¨tJ¢˜—£4‡ðø©¾f%lâ°yl3T´ò5×*k” ão¦ }«Å½ÅŸù–2ˆïÁãÿ O|CYÈ%E¢rC|©÷®æÌ¿™!ËfÕ8ÅLzÅîüGxQ¦MQáÁG8†dcxSÂ\–õ,ÅiT"^°æ©0` ˆ Éù¬Þlj7ŠUuhCº“iwóE1ÎîÜ»nqO´îPdRØh­Q´rzYEøt8”±Õ–²o‰«i`fÚÓxL¼>…;ô ˜Ö]¡ßµaøŽÙ=Yóa ³žÁâ3”†½ªž]ÅPÐ^íhØLãE~H4;Ûaq¯é‰•ˆž°óòî(:M‘<•-!´=Èq­þ;C²™åDWU¦ézÿaÑÈÅü/]Å–ðs©oêFØ.*’˜ºÖ·îf¼’VD±T]h ?¿ª-ÜDE$¬„•QqÿIèKæ?êœ냛aŽr¥šÉ¸ ÖÈãÎAfÅÇç±Q'ÎßKÝ*4»ØÅ‘ÎFŃ^zL‰í·¨W‚¼·“‚#Hjxø¡j¶¯÷i%)_®KUö¡_šm)4GíR¼NhÏ[ §RyÀÍ÷Îü]WâГƒ€H”EòþÓ+•$ 2‹¸ž&©Cñ:mµl‡¥]ËZ?DS°’±™ÖZ¼š¼'ÕʵŒn /Àô…R V`U(!>€è°;¬Q! :Õî%ßê`5o f$¤¾Hb-|ÿ„ÊùǧHo¯˜Ýc«šLåjÁGk½­ýÓ‘°ÑƒOä²è=‘›°ìŽ‘.ÂsHgú(§BÏä6?æÿ_pφC3­…"OÎó>]6bè‚¡¿£²@l%çÞûPŒÑu2Þ xhýÈE÷r%hÕ¶|’Î+ˆ‡MŸ>I— ^xœúæ=ûáY~î3âÕ©YÕ÷xî}S©g–QÀfÍH-V#ƒƒ$ú´!˜þÕF®ÁœåNáx‡¢Ú]vÜræ¹,ÃÖó îioMÄQ¦yûä¾Ýq!Böñe/$9Þ"Ó2éÔA=A•0ccÈ>‡ÍO„¤`ª^µñ-9OÕUcÕ—>²)õ³aêm¦¥^ɰaHÔ ¼†m×aýXŸºÖQsCqÌÐ<ÝCïŸH?ÕR÷Q_y¯ÿ¯†Tª½;º L›þ{K8«ÚR`E$ÈKIÐ=6ýx­­B6V$©µåPñˆÊÕ­ÓüÆŸ„Øišh[pÏpðm‡g$­ôw´+«÷JýJ¶Ïø=·ÿLÊ31…eãl&è lvè[ db§255ɬ]Üp `ãm‹~uHÅK+ó°eÛ°#_âq_ ATÛ‡$M“¨J/‰‹ª¿ú{ï§¿ûw%Féµ(PýüƒÏûoã¯ÒÿþâOþäÏþå¿dç0ÜKH_¾üïÿìŸÑår4±Øwëuá$B"jüJ𱎻jµµ ‹ªŒypçòͨ ­¯k¿Â,9——;³8$U0Ð=ãÄ’Ïv4>;=dk@aJQ݇»~|ºJr%ú\½<A3o‚ƒááxÛ‘!`ý¢ºY“á$]ꃶx §Ö'à³±¸inkýeK}p§²¤¼(vF¢Ãû $/ïuH¼Õõâjü„ìò¬`Z-î6ëñ…\ð̓ ®ºâl}·õR¹S%ÁïÀRûpÎUXõÊ—Kb¾Ðí›~Jä6mt‰Î)ÐæŒµB].ÁU¼ÕUZ©KUœ(Ä ,ê„yž7âD–VÊf d³ôÔÊ ³ž˜Òë˜ÙDïæÊcƒª‚~ý#íJ N5N¿¾ s™;Eèþhù‡ÿPn7›ºð×þñ?þ7+ªJDEª•ªþúÿø×üÇßyÎðOÿéøÅ?ÿçÿœCxÐxCˆú§Û¿ø,ò°Þw}{WM”¯§øúµt V¡‘U†,8îg«AÑN’×@é2ߘEˆHÅQʈjNêÌ;D‡D€CÌéTÍ—#¯ÑSúöúšÈÃg¹2òÒGó™_âg,|x¢C4+þƒÛŠöuª¹Ô̧Ö ð“Ñ'¦êfÓ®ÿ¥'i)ðAåf¾ !:lk@º ½WVÄ^+öfTŽÒët‚¹|ý`ÅC4«<Ü*¶+¾,x!|¼"Ѓ¹ká­TeÒ÷š÷ñ¥Ö²HY€¾^ñ.“³.zCgÜ3ëý‚[VBdÓ#.X3^A{³(ç\ä¥rhE6äÊq‡Ä€@}h§Múpô†Éàñèé6U¢­Á~¸àúk슨¸þˆŸþmÄ”?YÂýß躓1ù?üÃéïüÿïêÎ_jõoüfTõþÉ?9~õý£ãÓ¶MÿÕ¿Â/¿€ ÄÿÝ‹Ë\lN‚ßýkÐxÁÇŸã K~©`ï^/΃t õ‚O:`žWu‚×”ˆBFÚ é!µ1›ŽD†Fp }Æ&ß__RÉP×’„ÚÀ˃‡÷s¢ôÊ9rn-ûá ®LCº…%gµröÃúÁ¼x¯Eª±¼Þëeßx—ZβŠ2*vÂÝawØ­r#kUi¿U‰ö­’Éšt{‡‡C‡åzi—Ö7 ›@.ˆ &¼(V*çA5¢íòÖ&н‘ï7€¢H´_ƒ.ר>‘Kê„rrü„­šP%WÙz†VJâává-†p1RRçR˜#©·Rkë)rnmu¬Ðþù?üaigÂ_ÿM„ψ‚(øwÿ#üÿ"ˆ‚?ü[øwþÆ)?àúü®zôWªîü,sªJÓDÿïwd‹ÿò¿êžôßÿ nß@"þ—?Åoþ5&‡Éáí7øíÿ†9!ñåÅ‹£Ó*&@VS1¿¬ðp”’zÐc$ …ô@\¼´ `É«ð€è5Fòðzs—=«®¢÷ÁŠÎHt¦`ÀÀëàCt kÙ9ÑvX‹UæŒKjã´%¤JÆÙæfhœ °S þÙ]qgÜç¢Zg£Zk«õ^ëßÍ8ŒÃ˜Ô¸Ø‚ zåÊ<#@×ÒÿÅÂKÃ_ Ë6KQ .Ù*v it>‘KÞ ±('j´RwÁM ¥xwМ$öކLØ#¼CZpß1Ä÷ˆÝâ³K7C¼ÆÄ~žïR>k5f#[•ؽgn¯þýÿ»`Oxù÷ðoý§%ÙúÇ?¯ÿ4ÓU^ð×ÿC<»´ %ìéÆíÿÏõèÿõ¢FÏ>‚ÿÄŒ¢ÿÙñx¼~àÿüŸdÇŸÿOøø ¦€ÿù?€wxÅÇÿˆ_¾`^ë}7“fr( ë|]'!G*ž×\*3dL#{Ô8Ä”e=”"«Ú¿]~ØdBœ"Q‘‹Ð™þßÍrŒÁ8mt¾&]¸éçg«=ãÿiïl^%¹Ê0þ{O}vu÷›¹"q‚&cŒL$$™0‹€1\èJ7‚k]ø¸uïÿ!ˆ …]ɨ$b™È@p11ÁÄx¿º«»ëœófQuꞺ}g˜!CˆI½«ºÅmèÛ÷ôSïÇó>OX›¨×ûú4¡=ÖDVOohÀI×¹j`-,r\†ƒu6!ÃZí›EHÛ–á[ën±=,CÀŠ…8W8e9ŦÒUÃÅ6aqr±’ÖâQ3Yû2ɼc5ÕÎÌ"u _R·]ª ‰cmðŽuJÓ–‡-¾eH´(Ö3ú Y5xŒ–åÊx¥užk"N–‡ó—1_§©9÷“Çp¯œ¯¨§¼ÀäümôgcÖˆGŸH»å¿¬¨xøé“;¼*©†£›¨C”ú߬? Ë9zÅd)yÆñ¯eƒ–í÷Aó²©Ò]ƒ¶nÁ >Á·%¡ ²Ç)VÀñ¿¶k‘ªU#‡Ó›fôŠ4ËhÎÊY†Áºµ.p&'e»™Å°†Ð³6¨Ým« V X›è[T‡$¥Ø#W¹ñ¬"Aˆ6sZ+•à„ŽƒÜ˜­ð³§Ú‘âA¬:âíë°eéÔk:ƒ¨vÏ?•F1,Êé:)Ô ¢$rB¾9ÕX–¡’™l-ŽÊPðÞoqó|¤jÇVI裴)»` ´ † °^õ¡‰Úð½áÂ$är=Š­Cýg%JÙN…:c‘áÁY´ ÉØ$ ×2bE¬"CÙ¬~ZÖSÝ O]ÑHG¶êÉe桇—G]@±á'tšA9³IòÆä"*­kN$Rjº‹4P±±´fÓ5÷½#)ñ»|yÊ•‚<•¦Ò ¹‚XLJYv&%fz§Ø4¢ÒÈTI&$ë‚üþpÿ™à¡js69:Cs~¹Ë¬æø=þª¼¯Ì=Öá„uÊ9G’ÐmP\F£*NL"v‘M—;•Š!Sþ'g ÀNÕ‰Û*ÁfHÞó[]-ÒŽc!²ì™M÷*J̶·{!-ݬ£I\2²Møò¯ÃÍ&t«éÉ)+aÚrã3–)Í m·êaÁ¸†E¸yÞ“É€ëˆgÖŠÖ¬2H± ¬ýYÔt?€*¬<ºÐÕŽMm[Ò†Š :‘¥©$Õ‰Ö‡²cðLC–Ó$d­ ˜‹ F×å\öE~h°sæ—xYOQ ¡ÛŽìê}¹ËÇï#ŠÅ4) 8éŠ  ÷ñ‹öW ‡î¿©±5É_¸ê0×6³@MëV€ÉhDpe²JÊÎJºÑnî)["º ‰É§8kâi#‹G‡Ûäx¹ÏœX\”jÅ­Øó¢Œr“<š!n¢òÐ…©­ ¶B}ÎÕ–ƒe)l Gçps´]úYÅQÈ¿ŠÐ°_‡ÔŽmôn24ƒV G)*ØPö̬v°1%Î…7Ù¢X»)î…Fý4Y˜Y#iAs¨Þ‰1¸ ~FÝPÒŒ£/1}‰¯œ§¸Ì¥d(µ¤Ýâêöáƒ;Ø5cŒ;„0œ«Ó'KÑGù^{ý<ßÖlÞâÆîwÜøˆú€"ãp‰+[›€L×óB׆¥ ßÛ3|ºÉÄ뇜åâ}Š®Õ÷­dÈVë›6ÛS¢Šò´ØÑ{X>$4Dª }Ó½7"kq­ ×EÈΑÌ|Ûájxm”ÜК”:ÃVÿª@½/CÁYÃA€³:ÂÑž¶´àÑŠe/Hƒaƒª?ÑJ5,¬7A#ºWÊ·‚×Ì™ùdR$É"÷‘x6?`ï""4¯òàöɈ‹Œ 4ÆgÙ†çPÑ‚ü)^ä‰öæo¹™}(ò{õÿ’z?áý݉f®:Í,a×t’Q'“0Ùòz”¡Köڿ e¾OÙóF3ÄÆQmÖçìåØSç[üëywÅáã#”ð°F<ÖDÔ}͘Ì pfs›ž!”`•µ°HX'4ÐLhŠù°¡g¶„ýˆÛ*ÁºÚ`’›²4ä)Úòà•F:Ê{œ“µÙôÄg¨t\œ±q|CÈŒò®µ5BÒŸóèžÄ­Ãø'9ðz=F‰ªÞíkî6Þø «Éú¾“s\{‡TN8ø¹áW¤Ù„†ýš þô7=~G:[i¤ñµ ®§Ú‹e$±f{0)Ì $M( ‚)ÜÏ+ßa¾Ë³1óü%ŠŒ$åñ ÷ìcŒ1îqbxç€õIpñNâæq‘ôWbx÷?ì"TýF®½Æ›×IPŸ&Í›o®®_?ì‡cXFMz ƒ;° ÌŸ{nï«L6"?ý‰¨¡œððCäìŽð4Æ#`Ýkh«WZ×Ò©•£«•u]·ÅÂ^½zxãF¦ ¬’Ä^»öÁõëûW®\|òÉŸzjöê«»“‰) Qåüys¨1ÆëS¬¯·ÊbkÕ9íqÇZuΧ©I1FÒTFxcŒ°ÆcŒ1>¥0ãG0ÆcŒ€5ÆcŒ1ÖcŒñEòúýÒûõIEND®B`‚snd-16.1/pix/varyphase.png0000644000076400007640000002775711147553271013673 0ustar bilbil‰PNG  IHDR´ºõzXsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ Kƒ ` IDATxÚíiXWÖÇÿ½Ñ@ƒì  ²ˆ¨(âŽËHKÔ‰»F”èDÁ}L&¾®Y'&jÁm\¢1!‘hPQ£w"Q"* ²ÊÖ4Mw¿z(ºÞèúüž‡TWÕ­:÷Ö=÷ž{î9œÒÒ\‚ BK8 …‚A¡5\AA „ ‚hZ äôéÓÈËËÓè†;vìÀ’%K••EÒ%‚0eröìY,_¾EEE ÞlûöíèÖ­Ö¬YƒƒâÑ£G$a‚ ST çϟdzgÏ0aÂnvåÊ 4ööö5j~ùåÆïR©‰Dí_ee%kBP(H$`ÓŸ@*•²Ú$ är9+eËd2H$Ve_UUÅZùr¹œõ÷g³ýÉårÖÚVëžío_.—C&“5Ž Bhh¨ÁvË–-X¸p!ã/,, æææèÒ¥ kB,((€¹¹9îܹÃÚ3L›6 7oÞd¥ìÒÒR˜››ãƬ”…víÚ±&ûÐÐPÌ›7µò9ÖÊŸ3gÞyçÖÊ?q⢣£Y+?<<§OŸf­|6eóæM„††ê¬ÄøÆ|ØeË–©‹ÅØ»w/ªªªPTT[[[“œ âÈ‘#èÛ·¯ÑËÎÏχƒƒ«ï?þ|lÛ¶ óçÏ'»a4***`ff†½{÷bĈ¬<ƒX,Fii)¬¬¬X)ÿСCˆŒŒ„@ 0ì ¤!þóŸÿ >>^ù¿··7>|¸zõ*  ñ½222A-šV¯^O?ý”ÕgðòòÂãÇY)›Ëå¢mÛ¶HOO§ÆÀIIIHMMemîïï333ÖÞ?>>¿þúk³¬»zg çÏŸÇž={PXXˆ¤¤$ìÚµ B¡píÚ5ðù| <°téRlÚ´ >ÄÂ… YM7G^¼xgggKðx<´k×Ož<»»; ÄÈÜ¿Ÿ„ÐL©W!((¨ÎßwíÚÅøßÚÚkÖ¬!©jIll,Fääd† r÷î]tïÞA4;h#!A°Ì“'OàááA‚0AV®\‰Ï?ÿœHsgìØ±8vì˜É¾¿@ `Õ•š`Ǻ;«)RYYÉêúK‹Q 666€ââbVÊïСÒÒÒL¶!Ï™3»wï¦/ÚD F\\ ‚hž ¤[·nP(‡L!Z×®]CÿþýI„I"‰PVVF D¾üòKjI&Š)ïÿ!ˆAƒáÒ¥K¤@‚ ´aíÚµøøãIÍR `ðàÁŒM±Í>MsçÎ!88˜Aèƒk»¡ ‚-’““õŠCH „ L˜„„ôèуa„‡‡ãÛo¿%ÒQ(ÈÌÌd5-aº4…@š»øúú"))©ù(Ç#44¡¡¡˜3gŽIWž\.GZZ¼½½©%›0Ë—/ǺuëH,ѪU+Öö 5gølêéé‰ï¾ûÀ«PƇ¢š L777JÍ"¸xñ"ÆŒCÂhê3‚ ‚H‹@.—ƒËåbìØ±8~ü8+ÏÀáp€Õ´ºA¤@´dÙ²eظq#ºté¢ób’¾¸¹¹ÁÚÚ)))T!a$RSSÑ©S')‚ОëׯS.æÂ…  $A!íÉÏχ½½= ‚ HÍ>Ÿ@€òòrA!ͱ³³ƒ££#þúë/A!‚ÐŒˆˆ,^¼˜A „ B;,,,PQQA‚ BA4'¼¼¼ðèÑ#R „v”••ÁÊÊŠA&L=@ „ÐŽ3gÎàõ×_'AA „ š#|>())1j¹ÑÑј0aUK³333R AèŽH$BûöíñàÁ£–[ZZJ&L–xôèìììšõFVV¹?~ük×®Èd2jIA4ÑŒê| ß}÷vïÞ­<>}útÊ BA D{|||ššJµB˜ çÎÃСCI)B?fÏž={ö LˆŸ~ú “'Ofý9FØØXª‚Hs¥uëÖÈÎÎ&AFÇÞÞùùù$‚¡K—.ÅæÍ›Iad6oÞŒ%K–!š/VVV(--%A„‘±µµEQQ)æFTT¦NJ-˜ ‚AцØDJ „ Â1DR ñ_\]]ñìÙ3„‘(//‡P(ŸÏ'a4SHÄ Cdd$ ÂH$%%¡mÛ¶°¶¶&a!‚ H„‘ˆŒŒDXX ‚ H„vܼy}ûö%A¬¢kJWS‡•Õ+‰D‚çÏŸ***¨‚`•>}ú`Ë–-$ˆæ @òòò°wï^€T*¥Z ‚ ¢nnnøøãb±_|ñE“†:„ÜÜ\899Që ‚¨Z©™™d2ªªªHA¤@‚Ð???üùçŸ$‚¡=mÚ´T*Enn. Ù9s& lݺ‹-"Ai¾,[¶ 7n$A˜ ™™™pqq!€ËåÂÚÚ/_¾¤†A Ä0”——ãСC-º `ooO-‘0iÌÌÌàããC^`¤@ Gxx8òòòðǰRþÁƒñûï¿S+!¢EñôéSˆÅbøøø´\"—Ë …‚µòׯ_ÏÚûçææbëÖ­ÔÚ ‚0(Õ}*‡Ãi¹ ¤)˜˜Èê ìþýû¬•Ÿ’’BJ ÂðööÆÃ‡›¿qpp@~~~“x–ëׯcüøñÊÈÁ¦FBB~ûí7VGIOŸ>mÔ2ŠŠŠ`kkK=aÒtëÖ ÷îÝkþ dÒ¤IˆŽŽnÏRZZŠU«V!""ÂdÖªU«X+ûûï¿ÇÚµkµŒS§NaäÈ‘MBÖƒ Â¥K—¨7#š ¬Dã}ùò%®^½ àUnB=ðóóÃ7Я_?£—öìY 6Œµ÷?yò$„B!kåçää\\\ŒR^Ïž=±iÓ&jøD³•ˆL&CAA PXX¨öœëׯ# Àä*dĈ ³ŸÏg-gŠD"™™™É~W®\¡A45booéÓ§cúôé˜:uªÚsž>}ŠöíÛÃ××III&S!>>>HII¡–ÙHOOotZ}\ºt .\ Šh¡üùçŸèÖ­)Ædذa8{ö¬IŽ~ dÒÇC÷îÝqçÎVÊ¿}û6zõêÅÚûïÙ³;w¶…Ò”ÖßZ¬©ÍñãÇÓâW^^Lþ#³±±AQQ‘IÎ~Úµk.—½OtÓ¦M&5û'L@>|§OŸf-fNQQ‘Q#ÆN:QQQ&×0/]º„Áƒ›ì‡ùèÑ#xxxè½ÑK¶mÛ†øøxÖÊòä‰r31A Ä`ôïßׯ_g­c{ûí·Vž­­-cþã?bÏž=F+âĉøå—_Œ.çÒÒRˆD"ÖÚØO?ý„)S¦´è?&&o¾ùf¿8—/_fíùÖ­[‡ŠŠ “èˆ9:vìˆÔÔTR -ºìßG޵µ5kχS§N­¼¿ýíoŒQhnnn£oîk \¸p¯½öëÏ1lذF‹ÇvåÊ 0 IÊ¿  666¸{÷.«}€1HÛ¶m‘™™I ¤±ÉdàñxF)kóæÍX¼x±Êq©T ‘Hd²ûWnݺ…sçαV~eee£ÉÞÉÉ  IE`Ë»²²Òè.ܯ¿þ:Μ9HNN†——"##Y“ý?þñò‚kI äÂ…  TYX¼rå bcc¥LKKK…BÆ~•o¾ù .lÑ ãüùó R9þÃ?°¡xÙ²efZ²´´—ËEII‰òØàÁƒ3°gÏžáÁƒ-¾cøðÃñå—_µLOOO<~ü¸ÉÈàÅ‹HOOg­üË—/7ùj‹0aEGGcÿþý(--Õû^áááøöÛo•ÿÛØØÀÒÒÏž=«óš{÷îáÈ‘#þž‰‰‰èܹ3‚ƒƒ¶éüü|TUU´¬ƒbÆŒ¬Õiii)«¦Âj¦M›†ü‘ñQ³¹.——™LFCߎD"ÁÎ;!‹Y{†êH -NtïÞ]Å6:fÌ;vLï{»»»k=êØ¿¿FÂÖ—ââbˆD"8880<Á6lØ óT?)) ]ºtiruƒ±cÇ6¹çúæ›oðôéSÖ:ñuëÖa÷îÝÔöpþüóO|÷Ýw¬>Ô)SÌÅÔdH~~~™úüüü”™Ë’’’кukØÙÙ1ÎÉÈÈ0šöÎÈÈ@rr2ÊËËY“ׯ¿þªÓu<@çÎëüÝÎÎnnnõ†•ŽŽ6J.ó»wïÂËË žžžÈËËSOOO7š·Ž»»;233YQ ÉÉÉpvvfÕµvîܹ¬®=yòÄ(f/¿ü~ø!«}àÚµkññÇì~Ë–-ÓøÜM›6aâĉ nâm² äòåËÊØ£FÂÉ“'ÕžWYY §²¸~àÀƒ ¢¢¢Ô†^ …¨¬¬d$¾ÊÎÎn´u™Ædܸq eÄårÁçóQYYYç5kÖ¬Aqqq£<Ï Aƒ”&£ÊÊJ37÷ìÙƒÏ?ÿÜ(Jzܸq*dz²²púôéFkÿµÛº17¾ýöÛŒ‘ð… pôèQÖÚçÎ;‘››ÛèåbРAHNN6Ø=÷ï߯ñÀãܹs˜3Úÿ÷ß„‡‡cÛ¶mÊãG%íðòåËñóÏ?k-Ossó:ÍQ*áÝŸ?.—‹Ö­[3ŽÇÄÄè”aM[***°oß>ÈårFçPRR¢bÒÔ¦þë#((H9ËËËÃ?ü Qø†Êçp8àp8uŽ’ùåLš4I¥\¿~½Fæâ¯¿þZãw|ˆ7Ö[×ééé o¶†HOOGûöí1räH†ùºsçÎŒA`u̸šktr¹*›ò²³³‘­Qû …*‘¶lÙ‚E‹©œ?cÆ e~£j Þ–——«Ì~$ """Tœx‚ƒƒ î‚|çÎåeTÒ½{w <˜ñ§MÄÙú+YYYÕ;µ‹Åرc‡F ¤¬¬ VVVuþnff†®]»Ö»ÀäììŒÊÊJF’ÒÒR½ìÇšÚ%Õ¡P(êuEÖ•}ûöaÖ¬Y»sçN½Lêxñ✜œ`gg§¬Ûââbdffªì$þõ×_5šŠÅb…Â:7­®^½ZE9Ôäøñã3f ãX||<  u\³š¦QM]«+++ 6¨˜1ês†Ð…K—.aúô騬¬TvÎ/_¾Ä¯¿þÊè¬SRRTLÊ: µ³³c|WŽŽŽ § ¹\Ž%K–0”êW_}¥ñ¢xvv6,--ѪU«Ï=zô(JîܹsHIIQQàêLbÚòî»ïbÇŽŒ¶ºdÉÆÀ(++ ÏŸ?W¶õŠŠ ­7a[ZZB,+­ .\PQÊFU ;vD¯^½={öT9o„ ïAˆW*£úF÷2™ ÔhTßZGõTßÒÒ²N…uåÊ 8P'µmÛyyyjÍ8?ÿü3&Ož¬Ó}«ªª°fͽ¦Ï–––*{3rrrTÌGÕ9—Ëe,Êd2 Œ9²ÎÙKdd$ÂÂÂ0yòd>|XYŽD"¥¥%ãÜÿû¿ÿÓxTííí­r}5 ¹zççç«tŒ/_¾„^ßONNŽÆÙœœŒ²Ø\mvT(ÊïÉ“'1`À€ DHHˆÆåÄÅÅaÈ!7nc 6kÖ,ìÛ·¯Þk322ê\SÔ‡¼¼<8::2ŽaÁ‚*ŽŸ|ò V¯^­WymÚ´iÐ nÕªUŒ²~ü|>Ÿ¡p‹ŠŠ™™ ??¿¦¯@jãêê ±X̨´wß}·Ñ’íDEE1r[YYáÞ½{prr2Z„X[[[Ϋ6—ôìÙ õzyXZZl¯ŠP(DNNÊÊÊàêêŠ>ÿüs¬\¹R©Õ===5ºnË–-*æŽ>ú}ôãYnÞ¼‰{÷îÕ™Ó××W'?vx{{+ÿ_²d‰Z/±XŒÊÊJØÚÚ*Ÿ§>Bûöí,ÛÎÎb±}úô1hÝÍš5 û÷ïW©jâ½Týñòx<ÆG/‘HPVVVç†W]X±bþýï³ú½@$1ÚzYYd2£“J¥(**R«T«¡u™V»‹¯Üá«M“õ±lÙ2ƬÃÛۻѽðär9òòòàååň¡vôèQµû…tÁÝݽNÇôôt¸»»3ŽeggÃÅÅ3fÌÀ÷ßßèm¥Ù„2™|¸Š¦®6sõ» ^»vMçÐÙ®®®˜9s&ãØŒ3”#~u£2kkkŒ9R§Ðï{öìÑ9”¹B¡€T*U‰äª©©±]»v(**´iÓÇKKKëul¨kܘûJKKQPPwwwÌ;»víðj[›†.™ºöê‡333<{ö UUUŒõ®ŠŠ dee¡C‡ŒkÔ9»T»»k‘#G ÖÂPD®¸¸ ÃöíÛQUU…´´4 4<Okó¨6œ8q£GÖ雪9›©o×¢HcqöìY :´Áójoêñ÷÷ÇñãÇ!“Éàáá þÅ^}°°°ÀÌ™3UÌZüñ‡ÚmŸ~ú©^‹uê60999)÷¥4¤4:·.† ¢b«íB9bÄüöÛoõÞgÁ‚*nâ 1pà@óXÏž=Ì Q½&§P(pùòeüíok´6ëààÀð:jLz÷îk×®Õ{^M'u ËÑÑј0aB³ë"""°hÑ"H$H¥RXYYÁÇÇGŵº±ÉÊÊBÛ¶m¼ÚX­Ë&åÆh7ÍV888À××W­­»>4ñbÐT›'$$0Û“×_]ÅT¢.ÜEc¡É¬ÄP tôèьن‹‹‹ŠMüøñ˜6mšÁC»ãúõëprrR0`€JZ{aßlÙ²…ñ¾mÛ¶Å矮â.­ÎÛ«&aaaF˧1|øðëžÃáÀÚÚZ§]ó¹¹¹pvvV~{·nÝB^^^½æÃÅ‹3Öj† Ro.>Ÿ¡P¨ñ:aõ^•ê~%;;[9x‰DðòòBbb"¶nݪvÿH]ìÞ½sæÌ©ó÷€€Ö2²¶Âçó1{öl¯Œš¸»»#''‡aVª½c\>øàÌ›7OãóE"lll”›Àšnnn*f”ÚÓáV­Z5JL,@€ÖÂÂBeâåå…ŒŒ ƒ$_úâ‹/TÜ¥œœ&LmÍc èÓ§Ú·oGÕ{nmwÝ%K–`ÕªU*£ú˜˜üýï¯ó>ººòž?¾Q²1r8ôéÓGãxL5ùñÇ•qèD"ÊÊÊpòäIŒ5Šq^rr²r³±³³3Ã묡öÙªU+¸ººªõ0;vì˜Jtèš3ý9sæ`×®]xþü9Ú´i.— ¡P±XŒœœ¥òÓ„¼¼<ÆF† ¦•ƒHll,Þxã 2aÕgæhݺ5 •Jë]lÖ•#F¨+))AjjªZ7^KKKXYYdikk‹üü|ôèуqüçŸV;*¿{÷.ºwïn°wïÒ¥ Ú·o¯ñÞ’œœx{{ÃÛÛ[§T¡}ûö­w ÌÕÕ999ÈÌÌT‰ fˆzýá‡v}WWWäææÂ××W£{¦¦¦¢K—.pqqip3Y§NërB¡£G®7?Š­­-ÊÊÊ£wÇpçÎ'”ڮѣGƉ'š\žž®4)Wsûömøøøèœ_ÆÉÉ GmT³¤6 11‘­£z@§.†ž:¯Du{ÕjÇ^mþNLLÄŠ+Ô,mQ D$¡¸¸XíŽËº\; MuÌ›Úq¤c4gooÏ('<<›7oV.`{xx ??%%%u†aЇ÷ß¿^w݉'"::Àÿœx<ž2ÞPuÌ-]Ò …BDEE1 ÄÅÅ5ʇ^Ûå200÷ï߯×ÔÀçóµŽäêêŠ#GŽ0f6668~ü8Ë/,, ;wîT†›ñññAff&^¾|©âj©/C† Abb"cs¯™™¶oßÞ`€Bm™\íÎÿ›7oêµ1uüøߣ«cIDATñ*dž ‚!C†0ŽõíÛ{öì©×¬ûÚk¯Õ™»fâĉ UYW[¿~=–,YÂØq¯n="88Ë—/g($‘H¤Qø÷f¥@JKK•S[c¥"e ggçF­ÀÚÔÜ­ÎÚšl Mll¬Š·Ö•+Wп½Â;hª@c6æŽ>}úhpÑÐôë×TYÓR·cº.ÌÍÍ1sæLv÷1‚a}033ÇÃ… ”¦ÍO>ùkÖ¬i”ÜíÚµSYÀ®¨¨Pzd銹¹y½ÑŸ«©~ xµ¦aee¥uü³§OŸ*÷œ¯¢CÔµNÉŠ‹ÅÊ|õEzl Œ3'Nœ@ZZÞ}÷]$%%ýîß¿op´º¨Ýy5‡·ºÎS›]ÐQ¾1©Y¾““är¹AÓ¢6djR'çmÛ¶iœÛÕÕU¯…ùšïïââsssƬĘQŠW!|üýýõjG+7àÚT›5eïÞ½Œ°Q‹-ªÓ)ˆ•5'''Ì›7óæÍSIÔRÑ4TK+Û×××à9(4¥sçÎxùò¥A6Ž6=Ò8>š.ØØØ@¡P06î­_¿ÿú׿@‡êð6l±xñb½½/;tèPç ’OUL´Tªmñ5ÓíVÇ+ÓÄ­ÑPTTT¨™ÿöÛo5fffFõ …Beª\6033Ó*‚öرcUB–냧§§V9|  …ÞëHÕÚ¥»IÌ@ŒI`` F!¬E=êÍdØØôï߿ɄA`ƒj¸±ð÷÷ǨQ£°nÝ:“”÷¢E‹àè託 FÞÿýzÃ—ÔÆËË ÁÁÁ+¿:v–¦tíÚÅÅÅjóÙ‚¡C‡j%“W S¦LÁž={tÞ…jªÃ¯<% Y ±dÉlÞ¼Yùÿ˜1cpüøq£¾ÿ—_~Éð1&áááZ%34AAAuzÝGGGœ8q‚µè¶ÞÞÞg% uÛЄ„„4Ì»I˜°Îž=Û`ÊËÆdåÊ•‰Ñ¤ íÛ·¯3Ÿ€±xò䉯^8†¦f¦>6puuÕ9Œ¿!X¸p!<<<´Ž­d(êZX7UüýýqìØ±:MK­ZµRJ§©báÜœœXû€lmm±·)bcc£wl*}™;w.&MšÄJÙmÚ´All¬ÞùÐõ¡v@‚=r*±¶¶FPPP³y“˜ìÛ·µ †=zô`ìje???½wçêJ×®]qøðáFM°ÔlïÑ4=1A47LbÂöîôÝ»w«õ£®¹6Ò˜œ={^^^¬½ÿ€=¸$Ñ<ðôôÄãÇYŽÏ>ûLm(”–‡Ã“““ÚÍÍ"‘~~~ZyÌq©IAK×á’—˜˜hÐëÚ–OƦ1qiƒ\.gí»P(Ëå¬ ªx<ž2r³:ÆŒƒˆˆïGÃB‚0Aòóóann®užyÂ0²þü¹Ñ¢C¨£®TϵC±Ð „ rrr`aaÁÐG˜ööö8!# ’_ ŒÉ¸qãôŠNL „ X¢:E(A´HÆmp\.#6A¡PˆöíÛ32G²ñ ´XYDÏËËñcÇ´üpîM ‘H‡ââbVìßááá E@@U† c,D•χòòòX{÷}ûöá‹/¾ ˆ>£xxx=ÄEÛ¶mQUU…ììl“üpÀçó›Äû×NJ˜±±±xã7LòÝmllF3]±¶¶V¦ƒ¬+?pcaaa…BÑâ3!6Œµ‘’ šÞÞÞ4!‚ LR A)‚ êÇÖÖîîîHHH0i9ôêÕ‹ƒ P&aBp8p¹\Èd2“•ÁðáõJ3K!ÔÏz¤b‚06lF¦ni Ë„ùñÇ1mÚ4aTÂÂÂPZZ OOO)‚h>XYYA$!''‡„ÁíÛ·‡L&£T·¤@¢ù)KKK<~üB¡]±@õFb‚AhÍo¼ØØXVŸá¯¿þ‚³³3«¹ÊMGGG¼÷Þ{$R ¡==zô0y7R‚ BA!ŒGïÞ½qûöm„ sýúuôïߟµòoݺe°¤B)ˆ 2çÎ#A˜(ÎÎÎ8pàFŒÁJùo½õ²²²0tèPª B/XqAÉÌÌT&u—J¥T „I1þ|xyyaéÒ¥¬)°Ù³gSEÍS¸¸¸`ñâÅ^…sÿú믩&ˆŒ=š„@4O"”y Œ„ ‚0 ´B˜|ð¾úê+Aѯ¿þÿüç?©F¥uëÖ %A¤@š3ÉÉÉðõõ¥V@ tèÐA4{(A°@XX…Q!HÍ“ôôt´nÝB¡„ÁNNN$¢ÙC‹è&HÇŽ˜™™‘@‚ BhÆÔ©SeÚ ŸËÇ£Æ@¤@B;üýý±hÑ"A!š………°³³c­ü•+WR%„ž˜ä"zPPΟ?OµÏ"6l@FFkåwêÔ‰* h¢=ÁÁÁM"nnn®Izãxyy!,,Œ¾>‚ BèÊo¿ý†áÇ›Ü{›™™±j¾"‚AÁ"¬¬<~ük×®Èd2ªdÆŒptt$A)íðôôÄwß}àU8÷C‡QM˜]ºt!!D3‡LXA)‚ ‚H‹¦K—.ÈÍÍE~~>kÏ777ª ‚ t†¢ñ²€@ €\.gÕ z Š ‚f Í‚ BhíÆ&‚AA „0K—.…½½= ‚ ˆf -¢³„««+ š4GÊÊÊлwojA¤@4gñâÅàóùàp8Ô ‚ K$$$ ¸¸X£ž9s{÷îEAAA“~ñÖ­[ÃÇLJZADc)ÔÔTÌž=/^¼hðf'Nœ@NN<<<°sçN”””4Ù÷ññA`` µ‚ á74ó8wî&L˜ ÑÍ¢¢¢”;œ°cǼÿþû$e‚ ˆ–ª@¤R)îÜ¹ÃøÁÛÛ˜7o6nÜhÂÖ­[‡¤¤$ƱêpÓ§O‡¥¥%ÕAD%::¾¾¾LRYY‰7n0N´³³CÇŽ ZøòåËUމÅb¤§§cÚ´i:Ý333ýõ† ¢Óõ·o߆P(D×®]uºþÔ©SèÝ»·Î¹Í :„®ÏÎÎÆŸþ‰×_]§ë¡P(àïï¯ÓõgΜŸŸZ·n­s»8pàfΜ©Óµyyy¸yó&F¥ÓõIII¨¨¨@¯^½tº>..;vDÛ¶mYyÿ¢¢"ÄÇÇcìØ±:]Ÿ’’‚—/_¢_¿~¬<¿¾×—””à÷ßǸqãtº>-- 9998p`³|±XŒ'N`Ò¤IFQ µû9>ˆD",X°@ë›]¼x‘±íâₜœ¸¸¸àáÇðööÖè>ݺuÓ©|àf6]¯ŠŠ‚••F­Óõ˜>}ºÆïZ™L†Û·oëüüIIIˆ‰‰Ñùú£GB¡P`üøñ:]_VV†±cÇ2F%ÚrãÆ Ÿ?-- \.WçëcccQ\\¬óF*•"((={ödåýŸ>} ±X¬óõ¿ÿþ;²²²ÊÊóë{ý‹/PPP óõñññxðàæÎÛ,ß¿¨¨OŸ>Õ«|}¨wýüùó űcÇðá‡"44‰Dùûš5kpôèQåÿ‹-†  …B¡ó¨@«àrõÚËÁçóÁãñt¾ÞÌÌ \®~ÞÐB¡µ÷çñxz½¿@ ÐÛZŸ÷çp8¬îå¬×¿™™™^×óù|ÖžŸíúçñxz·}ß_8Ž^õ¯wù …B‹ÅXºt)¶oß‚06úÎ@B_BCC›mzŠ…EAèë±°ø|¾Î €¡/>>> ³,AM·I4EŒfÂÊÉÉAjj*ÚµkÏ¿|ù2¸\.%]"¢Ù’€’’ôëׯÁµu}dAAîß¿077Gß¾}MO( ¬\¹žžžxþü9æÎ‹6mÚÔyþ ‹!—ËakkKöi‚ šqqq¸{÷.D"Äb1-Z¤uùÑGÁÍÍ ‘HàîîÞ´,6 #ðüC!•J …BQUU¥˜={vç^¾|Y©üóæÍŠ[·n)¢©“­xòä ãØµk×H0&Hqq±bÁ‚ ™L¦P(Šßÿ]±oß>­ûÈo¾ùFyNLLŒâ§Ÿ~jRïi”Et©Tªtäñx¨ªªªW×t‹äp8`ÙQŒ 4âÊ•+8yò$ÊÊÊÊõ©TŠÂÂBH$eûùò% ¨}·Pjöe<OuC›>rþüùP(8~ü8***0yòä&õŽ”PŠ ÄÑ£G‘““ƒV­Zaúôé¸|ù2¾úê+âôéÓØ¾};ú÷ïôêÕ ‡†T*ŰaÃ0fÌ ¡–'N ¼¼S¦LirÏf”ˆ››²²²¼ =Qs;¼\.Çýû÷Q^^°´´T®Èd2TVV‚ZÑä ÁŒ30}útÀСCáââ¢ü}êÔ©ÈÈÈÀÕ«Wqúôi¤¥¥¡  qqq$¼—Ë…P(„X,ÂÖÖVù{~~>ÒÒÒì#?±XÜ$•‡Ñf ÿþ÷¿ñÙgŸ¡¬¬ æææX±b…ò7‰D‚nݺáÒ¥K4hzöì‰/^`ÅŠàp8:t¨Îqª‚ þøãØØØ4ÞfýúõèС¢¢¢Hh- ‘H„|öÙgÉdðóócĻۿ?öíÛ‡ÄÄÄzûÈ?þC‡Åü6l† ÖdÞÓhn¼b±EEE°²²‚µµµò¸B¡@vv6[ò³³³@¯ }aL$ "##Ááp0oÞ<œ9s;wîÄ‚ ЪU+H$ôèÑ;vì@xx8V¯^üü|lذÎÎÎ$ÀH^^¤R)œ!ƒÊÊÊP^^ΰƨë#³³³kdµûO“Q ADËâÿ;ÃYå+kbIEND®B`‚snd-16.1/pix/fmeq25.png0000644000076400007640000002771111147553267012763 0ustar bilbil‰PNG  IHDRÈ­õa0wbKGDÿÿÿ ½§“ pHYs  šœtIME×  (ƒ[å IDATxÚíy\OÙÿøŸmJJ!Ji,)‘õ,c,ÉŒ “J¶±‡c†‰ì;ÙÍX>Œe,3öµHE„²…RDѤ´/÷÷G¿î×[e˜ á<÷ãñ¾çœ{Ϲç}_ï{^ç¼Îë¥"I’„@ (UÑ@ˆ@ðN$&&†„„„<ùäɓܸqCô¢àÓ˜˜¼¼¼x剛7oæÈ‘#lÛ¶ððpÑ“‚õ—´µµ©Zµê?ž¸råJN:ņ  ¥Q£FJùÆ ãñãÇ%žojjÊ¢E‹>˜Žš={6C† ¡R¥Jâ©ù”¤jÕªX[[ÿç O›6ÜÜÜbóœ¹yóæÕQçÏŸgàÀâ‰ùÔ¤8®_¿Î­[·øê«¯ÐÐÐx­ •˜W®\9Ñó‚S¹{÷.‡fÛ¶m<{ö €­[·Ò³gOž?.—2dÓ§OçÁƒ4kÖLô¤àÓ}}}&OžÌ!CÐÔÔ`РA9r¹Ü€èС...ØÚÚŠžüD á×_•OŸ>M§NèÔ©žžžrúðáÃåôãÇ—z;‚ƒƒåë¿jè›››K§NX¹r¥ü,ž@`` œæîî®|é=о}{ÉÚÚZ*KŒ=Z /1ßÑÑQzøð¡ô)Ó³gO©nݺÒ?þ(I’$ÅÄÄH†††Ò²eˤäädÉÊÊJ>|¸4fÌÉÜÜ\JNN–üýý%###éöíÛ¥ÖŽ„„©ZµjÒ¼yó¤ääd©I“&’››[‘r=’z÷î-õéÓGÊÈÈÜÝÝ¥ÆKÉÉÉÒ‚ ¤jÕªI/^” ¥%K–HÉÉÉRƒ $///ùb¡ðÿ“‘‘A^^žèˆW°gÏ.\(çççÓ¾}{†ŽžžÛ·o'##ƒŒŒ ¶oߎžžžžž|ñÅäçç—Z;$I¢E‹Œ7===~ÿýwÒÓÓ•ÊDEE±hÑ"æÍ›ÇŽ;ÐÒÒ¢qãÆ>žÈÈH5j„¡¡a©µ£bÅŠtèÐOOOlmm9vì¿ýöóçÏgÇŽXXXàáá……gÏžeË–-ddd0}út ÇÞÞžÚµkÓºuk<==±±±áøñãlÞ¼Y®Kå}ì(´··çÉ“'\»v­Ìüø^^^ 2„ƛ߳gOV®\IõêÕ?Y¹}û6ÙÙÙòq½zõHOO'66MMMÌÍ͸sç™™™Ô¨Q==½RmKjj*÷ïß—õ îÝ»G­ZµHNNæáÇ@}aíÚµ‹ÜÃgŸ}†®®.)))ÅÞƒxƒ¼#"""033CKK냾‡ðåóâl÷ÌÌÌÞj[tuu‹­·P*UªT¬aé›ÜÃ;]»vqçÎù866–òåË22}útæÏŸÏgŸ}&þ->0Þ‰€ñâHîSÁ‡Í;™Å²³³£wïÞòÇÀÀ@ôüƳgϰ³³ÃÖÖ–™3g’••E^^[¶l¡Aƒ( HII!%%…Î;£P(°±±aãÆ¥j¥ŸŸÏ®]»°¶¶F¡PЦMÙ°¶ŒŒ ?~ÌW_}¥tíÚµÃÖÖ–Ÿ~ú‰¬¬,¥sþþûoºwïþîDðá3dÈ Y·n›7oæØ±cÄÆÆâííÍŒ3F]]1cÆ0qâD²³³ Æ××—©S§* ±ÿ+OžÈ{ÈÏÏ'** 777ºtéBnn.wîÜaÔ¨Q´k×îý(邃={öËĉ_{ëuYã?þàÞ½{Lž< âããY±bU«VeÇŽ$%%qþüy! ‚7cÓ¦MLš4 oooÖ¬YÃóçϹ|ù2'Ož`Á‚rùÂïgΜ‘m¦J“ˆˆYÉ~qÊÒ¥KKtòÛo¿1~üx&MšÀÚµkQSS£_¿~$$$@NN)))ò9b%]ðZ RSS9|ø0}úô‘Ó5j$ÛZ5JN/üÞ¦Mš6mZêm±²²¢cÇŽEê…‚‚ëׯ§eË–|ÿý÷rúÈ‘#™5k)))Œ93336nÜÈ矎——W¿ÑïDiÛ¶­ÒñŠ+xòä‰xâ>0ºv튉‰I©xÿ›èëëËþ¢œœä…-[¶$%%…BAçÎ;v,úúú´nÝ€þýû¡ƒ^‹K—.aeeŶmÛ>˜6_½zCCC8 §U¬X‘àà`¬¬¬Ø²e‹¼'äÆèèèpôèQ! ‚7ÇÏÏMMM¦OŸÎ©S§Øºu+iiie¶½aaaìÞ½›_~ù¥Ø|Ž9ÂßÿMdd$Û·ogÒ¤IEv» ¼“&MâË/¿D¡P`bbB½zõÐÐÐ @ö%õ¢ÉFá÷}ûöqâĉRoOHH[·n-Rï„ ¸uëƒ ¢zõêÉêÕ«™3g}ûöàÿûçÏŸ'11WWW´´´¨]»6±±±J6ebDðZØÚÚÊa.nß¾ fff,\¸Ÿ~ú‰9sæ ¯¯ÏâÅ‹èÛ·/ …‚ŒŒ üüüJÕˉþþþL:•Å‹£¥¥Å–-[¸ÿ>™™™¤¥¥±|ùrÖ­[GNN½zõbÔ¨QôèÑ…BAzz:«V­¢råÊ$''³yófvïÞMnn.:tø¿Ê„-–˜æ”Œb ¯@ˆ@ð „ò·oß.Ñõ¨ `È‹®G­­­yþü9111@¿³ºuëÊ}YÔæ³Ï>+õðÙ)))²óiMMM,--‹”‰‹‹ãéÓ§@Aôfcccnܸ¡äî§\¹rÔ¯_Ÿøøxät“÷TBù?D]]]è ¯ víÚ ¤íÛ·K …Brww—lmmå²Íš5“ÜÝÝ¥V­ZI¿ýö[©·eÿþýRÓ¦M%wwwÉÊʪHþ7¤víÚINNNR÷îÝ¥/¾øBŠŠŠ’ÌÍÍ•îÁÔÔT’$Iš8q¢Rú²eËÄ~Á›¡££ÃêÕ«å㬬,V¯^MïÞ½?~<5jÔ`Ó¦M¨««Khh(K–,aýúõtìØ±Ô<¼§¦¦²lÙ2zôèÁ´iÓ¨S§kÖ¬ÁÃÃC.À™3g¸tééééØÙÙL… ä{X¾|9IIIò9cÇŽ•ßD…»…"xm233Y±b+V¬ÀÜÜœœœ¥¶IIIœ9s†ÀÀ@%S¢“'Oñ|ø_ÈÈÈPrú–’’òÚk-;vìÀÃÃ777LMM•\íÝ»—+V# Ê;yƒDFFò÷ß+ÝàÃÃÖÖ–‡K‡ )³m544ÄÈȈ˗/ËaYGš5kwîÜ‘íÊjÕª…‘‘üòË/T¯^áÇ¿9wî‘‘‘òqbbb©Ç‹¼}vìØÀáÇ:th™nk÷îÝY²d gÏžeñâÅ4iÒ¤ˆ"?{ölªT©ćñòòâñãÇJq×߉€¼œ=,,LXó~`,Y²„ˆˆüýýéܹ3VVVe¾Í}úôáÂ… Ô­[—5kÖФI®\¹ÂŽ;hذ!P`¶²páB¦L™‚µµ5ýúõãùóçB¼>W®\aÏž=<}ú???.\¸€©©)K–,!==§OŸR·n]fÍšÅÏ?ÿŒµµ5OŸ>%==ùóç+ùÈý¯T©R…5kÖ‘‘ÁÓ§O©Q£†ÅÖÅÅ…nݺ‘••ÅøñãÙ¸q#fff²pH’Ä­[·h×®<~ü˜½{÷ÅÅ‹™:uª¼õVÌb ^‹µk×òÝwßÉNŸ÷ïß‘‘¶¶¶øúúD«V­¨V­íÚµ“ËN˜0¡T=1ª©©Ñ°aCvíÚÅ·ß~K“&Mä2SSSÒÒÒ8yò$œ;wNÉ,--uëÖѯ_?*T¨ Ç–-[ƪU«€‚ Xƒ¦P¢Ä:È?¬ƒœ9sF²´´¶XÂKPgΜQr øt"¼¡ƒÞ˜ÈÈH"""èÑ£ ²7t===Ù¯í±cÇ䵯-ZP³fÍRoGDD‘‘‘8::ÙKpñâEîÞ½ D·µµµ%;;›½{÷Êeºw–W¯^•G µjÕ¢yóæâ "x3ÒÒÒ˜0a:tˆ¼¼<‚‚‚øõ×_‰‰‰‘½¦Lž<™˜˜¶lÙRÔ×ÔäùóçL˜0OOOœIMM-¶ÜêÕ«9wî§OŸ–椥¥1eÊbbb˜>}:ÉÉÉlÙ²…ãÇÂòåËÿï"BIÿg%}æÌ™ðÉ+é_ýµ¤P(¤S§NIOŸ>•âãã%+++iîܹ’$I’äçç'ÍŸ?_ÒÓÓ“$I’/^,YZZJ÷ïß/µvdggK§N’(Ò“'OŠ”9pà€T½zuéÒ¥KÒÙ³g¥5jHG•œ¥Î;K’$I=zô¥Ó§OK¦¦¦ÒñãÇ¥ÈÈHÉÐÐPÚ³gPÒß„š5kÊfÝŸ" àĉ,_¾œ*Uª ¡¡Aff¦’…DZZ7oÞäöíÛòBx )MÏŠ´oßþ•öøøxâããå㸸8 S*Fbb"±±±rÚãÇyðàb½ ‹/VrBö¦ì۷ÿììl222X±b `êÔ©J6NbKðŸ˜9sæ:::¬[·GGG/^\âØ_Ìb …ÿ°/ÄàPQQ‘½¾«¨¨[æm“——'×ùrTUU‹x™WSS“Ûýò}¼3¹qã†0wÿÀ±°°àÔ©S‹¥¥%lÛ¶€€‚‚‚¨_¿>kÖ¬ 44”   ¢££Ù´i“lf^äääpáÂâââäºÌḬ̀°°ÀÞÞž””ÂÃà &<<œ¬¬,¾ÿþ{\\\èܹ3]ºt!((ˆ¤¤$‚‚‚022b„ DFFòøñc  [+¿9sæŒ0wÿÀ™1clß¾víÚ…¾¾>œ;wŽíÛ·+9µvvvfûöíÅîÿ/dff²}ûvtuu5j‡¢qãÆXXXЧOY7êСAAA´oß(ؿ޲eK¶oßNÓ¦MÑÖÖ v?~œ¨¨(Ù)6 ¦y_wš÷?þš7oþ¯§y …a“°ÅÄ,Ö[åÚµkeÚ)²àÓ¢ÌÍbÍ™3‡~øzõê‰_§ ±gÏ%=`̘1ÄÄİ{÷n À÷”§§'ëÖ­ãÑ£G8::Ò AƒRmÏíÛ·å-Àúúú >\)ÿòåËüù矨ªª2yòd%ýeþüùòñ¨Q£ÐÑÑ`óæÍ8;;+Ùu‰!–àµØ¾};ÕªUÃÆÆþøãî޽ˀ¸sç666üðÃ,]º”•+Wâíí 111 8P^™. ž={†««+‘‘‘ØØØ0sæLæÍ›'çGGG3hÐ >|Ⱥuë”lÄ222˜2e S¦L!## ‚‚‚pttd̘1JŽñÊäDP6Yµjººº¨©©1þ|¼½½ÑÖÖ¦zõê,]º” *ðûï¿óÛo¿Q®\9¶mÛF§Nppp`àÀ¥:lÎÊÊBWWttt022báÂ…JBжm[üüü˜:u*_ýµœ×·o_‚ƒƒÑÓÓ£V­ZhjjÒ¸qcüýýéÝ»wÙ×Ae}}}ÔÔÔxôèÏŸ?ÇÌÌ UUUÊ—//o]500Ë~¯P¡B‘ 4¥–––<4z±^€úõë³téR´µµ¹råŠRÞƒ7nS¦L‘ÆiiiaddTlìL! ‚7",, I’d'e%E'Nä×_•ƒxþ“¹ŒÁýÿøã%¿Qe™ 0~üxÙyX%×®]âããÿqè'DðÚܹsUUU%>)))²õBo뀼“/))©TÝŽ’ššJbbb‘z£££ÉÈÈ`Ö¬YhkkãììLzzº<£VXVGGsssÔÕ_­† %ý-síÚ5jժťK—>ø{ñòòRr7ª££CFFǧK—.x{{3kÖ,ÔÔÔ6liii=z”ääd*V¬Xªú‡ºº:C† ÁÑёɓ'3uêT\]]Y°`>>> 4ˆòåËsûömÒÒÒX¸p!NNNŒ3†èèhF111œ:uŠøøx¶lÙ‚µµ5mÚ´ò.øë¯¿P(œ>}úƒ¿ooo¥cÖ®]Ë‘#GHKKcñ⟸¸ ­­Mbb"­[·fÚ´i•Z;*V¬ÈºuëøóÏ?IKKcΜ9ò0jìØ±Ô¬YSÞ6›––†±±15 |t={öŒ.]ºÈ±`òòòHKKcĈäåå)Å"xmŠ›577ÇÜܼHú‹†‹oƒš5k2lذ"éNNNÅæôïß¿HZ:uJ,ÿNäæÍ›òæøÂñ£@ð!ðNäÔ©S\»vM>~üø1úúú¢÷B@† ¢t|õêUáÝýdܸqòÌѸqãhÔ¨!!!,[¶ €5jàëë À´iÓˆŽŽ–•ûÖ­[—j[._¾Ì‚ ¨V­š’©I!6làäÉ“tîÜ™þýû“––¦´.²téRôôôرc M›6²M™˜æ¼cÇŽeóæÍøøø §§G·nÝxòä ׯ_ÇÈÈ>LFF™™™üùçŸøøøðÙgŸA~~~©µE’$nß¾¾¾>>>>œ8q¢ˆ×”;w2vìXzõêE—.]9r$ gϞܻwnnnJe’““INN¦V­ZÔ¬Y“¿ÿþ›””¢££ÉÌÌDCC¢££IMM%)) SSSj׮ͳgÏä-âB@¯EÏž=QQQÁÅÅ…€€œåíªƒ âÂ… xxxpûöm ôþuÁ‡‹‹ >>>ܼy“›7oràÀÙH±,Ò±cG:uêÄØ±ceO'P0ý;eÊY76lùùù899ñã?1XoÁk1tèPÒÒÒˆ‹‹cܸq 8P61)‹Ô¬Y“íÛ·3gÎΟ?ϸqãprr¢k×®´oßž¸¸8:vìH×®]166fãÆ,[¶ŒÐÐP<==å7‹xƒ^‹¿ÿþ›üü|LLLÐÕÕåéÓ§hiiÉ^С`…»qãÆ¨««+Mã7mÚT6M/ 455iÕª•|\¡Bš5kÄGÏÉÉ¡C‡DGGãììL³fÍäY®ÄÄDÌÌÌ011¡|ùòò¬\ll,®®®˜˜˜àïï/†X‚7bâããC`` ¤víÚŒ?’’’066fĈ@Á–[.\¸ÀèÑ£166.µ¶èééáããÜ9sÈÌÌDWW—qãÆæí)))¬[·ºvíJ‹-”†XË–-ÃÇLJëׯ3lØ0"""pwwG¡P(•"x#%½jÕªdddСClmmÑÖÖ¦}ûöT®\€=zÈå—/_NJJ :t(õýè-[¶dÚ´itëÖMN_¸p!yyy3wî\ ºººrþˆ#°±± üfµk׎äädf̘AÓ¦M©T©’Á¿ÃÎήHš¡¡¡@óE^þ'.m øâ‹/Фµ€bßZEΫV­Z±×Jº@ð„€Jƒ^½zѲeKZ¶lÉÙ³g8~ü¸œö¢)ùÀåôC‡•z[Ξ=+_ÿE¯%…ìÛ·OÎ/´«‚KòÂô–-[ÊSÕË—/§eË–ò~–w* cÇŽE¡PÈŸ—£üÊ>...<}ú”   L·nÝ ÅÙÙ™áÇÄÍ›7>???ÂÃÃÉÏÏgóæÍEÚuîÜ96l([$Ÿ>}š˜˜¥k‰!–à&ZæÎËÎ;e½pÚÝݺuëÆï¿ÿŽªª*}úô!..ލ¨(Ú·o_ê¶XNNNxzzR¿~}BBBä‰U«VѱcGbbbpss£fÍš\¿~]çççǾ}û°¶¶fذaèêêÒ²eK6oÞŒ««+±±±üþûïB@Ê’âÛ¥K%«Ø²ÈÀéÛ·/&&&rš¶¶63fÌ`ôèÑ@G¡ÿ«³gÏÊ¡ªT©Rª›«455™:uêÿÚTW§zõêìÚµ‹ªU«2wî\Ù9µ¦¦&ÕªUàØ±cäææR±bE9N¦‰‰ 6l 55Ué„€”’““‹Ä¤(‹T©R¥Øtmmíbþâì³J“òåËcjjZ$½P*T¨P솮BAz}}ýb=í”)äüù󘛛qg/¼/Ê”€„††R»víÿÿË|JIDAT­‚OZ@EqwwWò^þ>‰ŽŽfÓ¦MÌž=€œœV®\IݺuåÍF?&!!Ö­[£P(¨W¯K–,!33“-[¶`ff†B¡ÀÚÚšøøøÕ޼¼<6lØ€¹¹9 …‚FÉÞÛ¡ Õ¼yó°´´¤E‹´oßžÄÄD=z„­­- …sssÖ­[Gnn.?ýô•*UÂÐП~úIȇBzzz©ú”ú/,^¼˜M›6‘™™ DkòóócáÂ…S£F |||øñÇ©\¹2ÁÁÁ,Y²„E‹qõêUÆϬY³¦eË–Eo¾.OŸ>eêÔ©Ì;—àà`lll3fŒœóæMüýýY±bAAAhiiáëë˸qã°²²"88˜yóæ1}útžM^^žìq~õêÕŒ9€pùòe À^ìàÁƒ@»¢ÁƒË×+é‚ׯÉɉ›7o’žžÎÁƒÙ¿?ßÿ=C‡¥jÕªdffò×_¡¢¢B÷îÝQ(Tùù矕ÌÝ;uê$G }=zDjjêGÓùÉÉÉhhhlRð ÈËÿnªªÿnd·téRΟ?ÿÑtþÁƒ122ÂÖÖV<‰Bù89þ<†††Ô®][t†ÁËܺu }}}ªV­úÎëÎËË+3ñ …€Ê>>>œ>}ºÄüÛ·o“‘‘!:JȧKïÞ½Ù¹sg±y3gÎ$&&FtÒ§$ “'OþèÖ2þ Æ cùòå¢#„€ðùçŸÿëÈDŸ"_ýµè1Ä”Dll¬è! ¥Ãwß}dž DG„€‡‡‡kÖ¬yçõúùù1qâDñy»Œ3†S§N½—ºŒŒxôèQ‰ùÕªU#11±Ø<;;;Ξ=ûFõ8p€J•*aggWlþúõëiÛ¶-%^£oß¾<{öLHÁ› ÈÍ›7Ù¹s'ééé¯}ú(ý‰µnÝ@Žùý"aaa¸ºº’••Ul0}út¼¼¼ŠÀ¡C‡hÚ´é{±xÛÔ­[÷õÿ¬¤—8~ü¸4qâDI’$©yóæRI´nÝZÊÎΖüýý¥5kÖÉÿæ›o${{ûb?úúúPäcbb"ÙÛÛKmÚ´)6¿víÚ’½½½¤®®^l~½zõ¤ *›W«V-ÉÞÞ^ÒÐÐ(6¿nݺRûöí‹Í«Y³¦doo/µjÕªØ| ÉÞ޾ؼÏ>ûL²··—Z·n]l¾¹¹¹doo/©ªª›oee%ÙÙÙ›W§NÉÞÞ^RSS+6¿~ýú’¶¶v±y€Ô¨Q£ûòcþtîÜYz]Þš5ïÚµkKÜù÷å—_òäÉ“b­z ÇéÖÖÖÅž›˜˜H½zõJ¬·V­Z%æ%&&R·nÝbó>|H^^Þ+ëý§vý—sëׯ_l^\\999¯<×ÒÒ²Ä{~•ennî+ûòUÜ¿“‡pï‹{÷îQ«V­W:H7J¯% aaa„‡‡Ó¿ÿ×Þ˜S¾|ù’UU.\¸€¶¶v™éX///† BãÆËÔþÍ7ß0cÆ ÌÌÌÊT»ºuëÆ† ÊܬmÛ¶;v MMÍ·£¤×«Wmmm† †§§'{öìÁÍÍ´´4¹Üøñã=z4÷ïß/q&E øè”t<==yðà¬\:”ž={R±bE¹œ““5kÖ¤J•*…ç?³Dô×k±ŒŒŒ022’166.R®I“&MG¬\¹R<õoÀþýû?‰û+éà_%¥÷8<66“í¼áS">>444Dg¼æ³U£FRÓ‘Þ‹€bˆEÙŠ¯¯/QQQ¯,·~ýz6nÜ(~OS§Náëë‹¿¿¿Rú¬Y³8tè||ÿþ}|}}¹~ýºœvæÌ|}}_¹ï>??___Ž=Z¶$55•… bmmÍâÅ‹K4|[µj’$‘››û^LÍïóçÏ€µµ5åË—gÑ¢Ex{{S¿~}ÂÃÃ9~ü8YYYøúúbmm¿¿? \¸p“'ObmmͤI“J¬c„ X[[ú¯ `ßš€dggs÷î]‰ŽŽ&++«ØrW®\ÁÖÖ®^½úÉ<aaa( V®\Ybß|ìØÚÚ2f̱°° ::Z~3ôèуŠ+rÿþ}òòò¸q㎎Ž<|øŒŒ =z„ŠŠ ŽŽŽ%ZXCQ¦££#ÚÚÚÄÅŽqEè¢÷„——!!!lذ{÷îñèÑ#jÕªEXXèééÅ•+W(W®ݺu ((H%× A?~L«V­PWWçòåËò¢íÉ“'èØ±#™™™$$$ðüùs’’’dëã³gÏòøñcLMMiÞ¼9§OŸ¦]»v¨¨¨†¹¹¹Òâpi£¥¥@`` »wï–ß e‰w* W¯^eëÖ­xxxP§NOV86lØ@\\ÿûßÿøî»ïäÙÍÍòåËŽ›››7oFKK I’HLL¤fÍšœ;wuuu®]»FTT‡bÿþý¨««³fÍ ÄÞ½{ÑÑÑ Ìñíìì˜2e _}õêêê|˜ÐÐÐRñTóçŸÈŒ3J-lÝ[Š+âä䄃ƒÎÎÎèëësúôifϞ͗_~) ȨQ£˜1cªªªL™2哯£§§§ôðéêêÒ¯_?,--¹páqqq¬_¿ Ê—/ÏÌ™3Ù¿?¶¶¶tïÞ;wr÷îÝb¯¿téRš5kÀðáë^///rss:t( 4 ]»vtêÔ‰G‘““óÎû!00!C†P¹reNž]%K–ààà@‹-èׯß·ñ­Nóæææ’‘‘AùòåQWW—µµµ•̤ w.–%ëÞ·M‹- )ñ8,,Œß~û~ýú¡®®N“&MX¹r%:::4kÖŒ#GŽ••Edd$£G&44”)S¦pàÀ~úé'¦M›@Æ 9{ö,ÇŽcÖ¬YÄÇÇ3tèP>ÿüs iÔ¨AAAhkkÓ£GLÛ¶m100 wïÞou­ªðy(DCCCv¥¦¦*çå呞ž.?K…znVV:::¨¨¨••Evv6ºººE&ŒÊ•+÷¯,|Õ¦OŸ>ýmu€ªª*šššr'¿|übÇ|j a>ÄÞÞ¾ÄãêÕ«£¢¢Âúõ뉈ˆ k×®4oÞœ“'O²sçNΟ?……sçÎeÚ´iÔ¨Qƒ.]ºP¿~}ºtéÂܹs ¥M›6¨««£®®Žµµ5yyy<{öŒQ£FqðàAvïÞ±±1ƒ BCCƒ„„´µµéß¿ÿ[7H,| ?/‹^>.îÙQSSCSSSn§ººz±BðòµÊÌDðö(by{{—Ú5çÏŸO5Šluþ”ò’””DVVÕ«W/µk^¿~KKKaúÿÿÔ C ö'IEND®B`‚snd-16.1/pix/ssbambank.png0000644000076400007640000000605711147553271013620 0ustar bilbil‰PNG  IHDRÈ£ÏkQbKGDÿÿÿ ½§“ pHYs  šœtIME× M_›J ¼IDATxÚí{H]Æ/b³Zc»JåÚHeIVE ÁB](ìF…%Ý(’"©? £È$º VD‰¥A¶ÝébP,Iµ.»ºvÓ\Js7íbóý;¹µêú5³:³Ï–8gÏœ99ïûžyw&H„¯s ¡@¡@¡@éj|ûö µµµüíÛ7Øl6Ô××s&IàäĉÈÈÈèðàóçÏcûöíÈÍÍEMM g“¨ŽPo•/^¼ðéàììl˜Ífdee¡´´©©©ß_¾|‹¥Ý>¦L™‚)S¦tû‰:uêV¯^ÍC Ÿ¬µû}dd$´Z­×OHH233qçÎELÔ‘#G¸ZhA¤¥=ë`6›±cÇ^¢< R]] —Ë…††±.,, K–,ñh…ªª*@xx8g“†@rssŒ’’±næÌ™ÐëõíNŸ>ŒŒ ÄÄÄ`îܹªž(fäÐŹzõªOuZ­Ök=!ª¶ „ ¤St´cG(€†1Bé.¡ËB(º,„ B‹˜„úëDMMMwæ?|øÀÙ'ˆ›§OŸbïÞ½bÙårqö â&)) 7oÞËåååÐét¼„1ˆ‚tn*P „5 äëׯ²Å6ÜÅ¢@üŠ îÊ•+8xð ],„ºX„P „P ЇA:B3 „ „Ið[.Öýû÷±oß>±ÌdEB´büøñÈÏÏË6› ÉÉÉ Ò üz2ctt´Xþüù3gŸ0i fó DE. ], „ЂºX„ЂÐÅ"ŒAhñ],BhA¡@hABˆšð[ªÉÛ·oñðáC±\]]­¨‰¢KHÈŠËå«W¯Ä²ÒžÍK—‘•Ñ£G#33S,›Ífäääð Æ „P ôé ¸>=MpÁÂ$0,¡‹E-!!!!!‚ßr±ŒF#6oÞ,–¿~ýÊÙ'ˆ›Ù³gÃl6‹e³ÙŒ¸¸8^B‹ „ D:øèQBBü?˜‹E(¹,4ÂGcB(B(B¤w’Ç£¢¢B–¾Ïž=Ë`ø-Ëd2áĉb¹¡¡A–óF”••!&&Fò¾8€eË–qÕP Ò3xð`,_¾\,¿zõ —.]RÄ$íÚµ {÷îÅ®]»¸b(yˆŒŒDdd¤XŽˆˆPÌ$Y­V,Z´ˆ«…1ˆÿPâ{Ò™E‰š(X JÌæ¥¡@!], ⠴ „P >àp8ðìÙ3Ì™3‡W•P R__ÊÊJLœ8‘W•(_ Ro™Ê½ËmÞÀÄo©&uuu°Z­b¹õ+¡•D ‚À@‘7oÞàÌ™3bYêl^XBÈF|||àì ÄMxx8†*–{ô衸ÉâV/"Z­‹/Ëåå娾}»b/ÅÁį(ñ>ˆç(**¾}û¸)yÿ"+Õ‚üüù---\‰ˆò-Ý, „t¡ B¢Ö„.ÖoœN'¾|ùBºX­ill„ÃáÀµk×píÚ5Éûðà¢Ô üz×䃰dÉYú_»v-B],BT€ßRMšššðéÓ'±ÌdEB´âéÓ§).—KÒþ¹‹õ7¥¥¥˜A§³;d ÒU¤sÌ¿ûœ>}:túÕq^âp8‘‘’’’vöµZ,HZZòóóiAd ¤¤ãÆÃÀ%ïûôéÓHKKûÿ_Á‹d-Z„•+WâÑ£G˜>}:’’’¼ìk;o¸s±† †aÆýó$¸\. 4………X°`ª««.É¿xñ·oß̘1cÆŒ‘¤_÷˜u:ŠŠŠÐ¿É…{Ì'NĤI“$ëW®1WUUaÿþýHMME¯^½$smm-^¾|‰¬¬,qÌ7oÞôÙüü…N§AöìÙ# mÑQ»M›6 ±±±^?ÇHú 4&yßQQQBTT”,cîÝ»·äýºÇ,G¿r9""BÐh4’÷*h41k4aÍš5BG„þ‹ØQ»C‡µù]yy9’’’0räHÉMê!CdqÊÊÊ$O—›ÆÆFŒ7N1ãõç÷ëׯÃ6¡¾ú™yyy:t(’““%óG“““QXX¨˜‹‡G)J Jsw¯× }Ù²eزe `ìØ±€U«Váøñã¶S3L ¼ñzµ ëׯÇÇ1bÄŒ1BÜe0`@‡íԼؘ\xãõº‹åÌf3²²²åbÕÖÖʲ É1wßñ2«(MJsw/BHwHÿþý±téR^Ò½c"ÏÔ$¤Mü’îÞÜÜŒ_Üék;¢nš››=Ê={öDPPZZZðýûwôèÑ!!!às7|i'»‹e±X˜˜ˆôôtÔÖÖþs;¢~ÅF£ÅbAss3òòò˜˜ˆ¼¼<477û\×–}i'»@æÏŸ“É„™3gâäÉ“ÿÜNM|þüçÎÃóçÏ©ŠV˜L&˜L&äççcåÊ•èÛ·/ìv;nݺ“É„[·nÁn·û\ç _Ûñ…]ÈÁƒ»ÝŽàà`IŸ4©._¾Œ & ::N§³KÆÀmÞ.¤¸¸;wîÄÂ… 7âÝ»w0 (((Û †6ë JKK±qãFñ»‚‚”––z=Ö×s´ÕŸ¿pŸ¯«“Ce· ¡¡¡øñã‡Ç[bSRRÀã EÞÚ©™yóæÁn·cóæÍbÖóíÛ·a³Ù““ƒ‚‚Fäää ;;pñâE±îðáÀÜÜ\ÔÔÔˆ¿W~ýÄ4$$)))Ûú.\Àõë×qôèQ±?÷y½õçOjjjÑÑÑ~?<üÇ÷¥®²²)))HOOdž Úíï/? ×ë…­[·ŠeƒÁ  †Û©ØØØvËî:½^/èõzáØ±cµsÿÇ]çt:…uëÖ‰u9VÁápN§S0 ‚ÕjœN§°gÏÁh4úunŒF£8æÖuz½Þc,¾ÔUVVzÌA{Çþ ïƒt!:Îãéë–`Û¶mˆð+<..Σ®¨¨ ,À“'O÷ïß#??»wïëZÛúYYYˆõhgµZ1{öl$$$`Íš55j´Z-æÏŸ׈1H’žžÞn²³³a³Ù`³ÙP__ßaV«Enn.t:×v­Ï1mÚ´¿ÚM›6 ~åE²8ÞIW}$í×n·cøðá?¿ÿBŠ–^IEND®B`‚snd-16.1/pix/all57.png0000644000076400007640000000450211316666613012577 0ustar bilbil‰PNG  IHDR›Úÿ‰xÒsRGB®Îé pHYs  šœtIMEÙ €â©ÎÔIDATxÚíÝÝ–Â&Ð1Ë÷e{᪵FH Àaï«þÌÄÈÇ8z{<!,šh @¢캧ÿèív{þƒ‡ À؉v»Ý^Aöþσ­:?"ìñx¼ê5€Áí#ÂÔh@Ÿ2²)kík'ªjí£}ü€U*Ð˪Ó>'Ñâ$š'@¨íjOeãìäö̯?/§êé}=ÈÆ1¿þ¯_?Ÿxn'ýÌ/f½ÄÉËù«¹]{¸ Ï_T?²gÕa°ñ3«ÎÇ¿:iʨ&¹ØÃ·Çpí)ÔºšÛÎ&ZÛviØßeË´Ü£õ6Ðs«•ËοÃë;Ú“à¥\È»®RiÐðrâmL·jùE_ºF+kÂXŒæëõð†>½€D.uë5Õ\ÛÞ”òÚaÑô×,ý¡ÅœÑ°;~úœÆÖcõ²‡•j4h6Gš¨v[æâÈ–haÉL›DÓgJ›¯7°=DÔhãÍlݴ溽©7~`éðt£Öä½ÅÙn“vØàJ9ÕÃð5šAìžYV`.D¢'!‰¦Ê°`Ô¿q Û{½v1^ ‰æ» Š—?¶„´VñïUíMð53IŤ0l2ðæM4N£)¥¯¹|‰}…¸þq&ÑPÐ)?®DCšmé-Ñæí{‚u½aÓ8ÑÌÌîRTÜj4½ &B‰v´íT`ÕIØÒ2pÄ›½$ZÝaÔpÕfÁáK0Uãö×ÒäF2j50u¥¿û¢M­®P£ÁôõÍ0*–ðj4ÜJT5@î­^Ø”Â䕈Âj¤D;_ù÷ùlxª›Á·(É#‰ö½óQË“„}´Ï¾0.‰ößœŸ5]>hX,TYk€DK­×”iU[[# tô¿-s×yn-P£Yg=æ<&Z^¢ê‰!ª$ï ’hÙ<èwd/ÔhÓ…¯å H4E¦·€W´È@ ÑÀZ‰†%?¢_¢ 9›öA¢mØBÉâP£ayKžª‰&¹ Ž’×éžTœDÛhVaGnEé.eÒU§%öˆ“h eÑøÄÇ~oKj4µàŒDâÔøËvÕ´U'ÀxëS‰§/ùZ ¡Fhê,@¢‰s ¨Ñ@Î"Ñ€rºzsŒD3h†¬ щ :T KyÎàY„ @¢a1‚D¨±â2ÑnÿgÊ-xɶ`šÜŸC ÑÙî£õÅÞëµìö XuH4 Ð&€D#þh.ÂST52$€D£ÿ’JA‡D'ÑLÚ¤Ûó¨ÑOH4€¦Jm¼J4@Æô“¡+B¢ Ìfô#Ì’hÂÔhâ,þRHí‰DcöH’ƒô9Ø$ F›UøÇjžªj%€D(ªÖ7§(°­õ N¢ù.(Ì@XuR¶]vüÙG;_ŠJRh`îQuJ4 B¢ÊI‰fj‚KB‰Ö×¼gè0O mÜ2‡Oþ‚òsÑÙ@˜i`Ñ4¸UŒ«ÎN†Æ+H40a Ñè²,Õ8NU¢H4‰Fq·ÛÍÚ‰ Ñ$ÅyÖFø3Ñܺ€Í<S o‰&Î ßnH´Ì’AÀÍS*ÖøKÏNþz´ÒÕu"Æ¥YuBÀIeÚË—h¸9'²m%št`Ò8 9$$𨉆aØê,ðˆ(ÑD¼î…¨Ol—Ûºøf VÃÇÙ@«±{}›O{áïƒmè…Ë×»Æ>×età7ߢFeÚÏêÞ¯D³tw!ÑÀ|ƒDhô»ú«x±F¢a‘¨%%´+Ä4Bøz¹`ÔJ4PéÄi‰† ©b÷§°kî® ¢ÆS¤7ĉxÔh hD/@ÀªóH)¡q™§ÈMY¨Æþ*©Nú·Û)Ó¬vÅG›ó±ê® ©ŸH4.ªC›ßž`öÐ,µ_nÑ1¸“ Ój4ëtAKÔA£kaœ/Ñv+Õæqfv'W=a¶UçxÛ`"‘hû­¦€*5Èäx·3èÌ]³ŒÛ©z°ê„ÁjgÓsze#Ñ襲¦øÎÀù_¼ ×Ên-Su¹;ŠÒ?jiVõ6\w1I¼t{µ|ñ.XŒ×xWtå…×ÈmO¸ÔÇ|'~0Ñ„pöÑJ΢ýlâþº .¸Ïª‡ì[ŸCîÙ—àÿºD jÏ ¹àíö¢º:±â'ó¾:ËÝAý|ÊGQ6lÞ²/qÑÛMƒ}—ЧŒÏ°}%½`ÆN´÷Š×}JÚGûˆ0c œh¦Fú”‘M»ûh 7àzï‰tßΣ¯{gïúÛMC€zî‰y´ÞGË]x^¹P½x]ìå\ —k8ZÞÿÕ;l8<"®:ÓCMœ}ºî¯ ä P;[ì£û(•$‡D-Bmoj4‰ Ñ$0‘»&xÚøè‘íO%Ù8àO]:ù ˆÜÓè¤yû9cC4ñ·Ö—ùþ»]s‰¶?Öÿ=Ò‡#u2Ó?úe’ù5ë’Ñ”WYªç±êuZ† †è×ê¬çñ¯Fû«ZKÿ:àǼ·þ4Íõç¼ÿ—õmû€»§±;ɧ¼Öáã×i¼þûîdFn§d]râ ¿Ñ_»]sÙ˜qò–h?ûïkwfõñÆ uZ­ë=õ>þáW^lŸFʲ"ñµÎ,9×§ñëÓû+ý·¶¯+å’³¶7ÀÉ&-5D·cmÆí¤ÃÇ,{2EŽVêk· NûÇŽS££ý‚íÕ汹D¢ßžhxž¼ ¬:‡ÛsÈú_Z ÒÃ¥zCt£bµê”Œ[χ›ÛÃ<*Ùø’³íý»óo=émŒÛÅžu¦©z:Dœ­w¬GùÉ#4oí¯û}Ïë:vðíßJ?æîRq]vÅ»‘Õh SëÇmYck}b‡Oþ#§Þ—¿xìµÞ¿?lý]b¿NcýŠç;å׳ÎôKþÕ_é›ú»¼æCðÏte·ÛÞZÅÔë}‚±êâø‚ŠãRó¬IEND®B`‚snd-16.1/pix/shepard.png0000644000076400007640000017605311147553270013310 0ustar bilbil‰PNG  IHDR  ³ãE[ pHYs:ÊduhtIMEÖðhOà IDATxÚì½y°m×YØù[kï}æyºó›$Ù’,!ϰÁÐ&)\é JNÑÐ! Uî¤éP n0.ÛåŽ!M ¶Ë ƒ…<àI²,Ko~ïÞ{î=ó<ì½×ZýÇ>ç¾ûË’, ëÝõ«SÒ;çì³Ïykïû¾ý­o_š}‰¯Ç¥íK›ë›RJ,‹Åb±XŽ*._8±uâ©æŸ›}.0Á“wúôé×W^Ù\¶+k±X,‹åÈrúñÓΚs9x2ÈŸúýßþÚøÆ’CJ¡žü‹Åb±X,–›e”6úÉ="ßøA¸Ï/þÍÅ„NÜðPÙ—Ó½éþÙ}»²‹Åb±XŽ,îØmöÏÝØ#ŠåcÅ;‹‹#^MèÄ«¿çÕ}Õ¿þ3ÊFåîµ»íÊZ,‹Åb¹¹­¾`u¤G7ðˆžh¬[ëâú·{ƒ•ìÊE.^ë`}Õo¨ÆõŸ9×8wâ– ݰ‹n±Xž Æ!Å7ï´ÒÒ±¥9‹åiÓÞk'nMtTçÑÞ¹“·Ÿl¨†@\£Òö»û9/Çr/Ðj‹Åòw@¯Þ{àÿyà†o~àô×úÔ°9¬?VŠ_ñ‘ÿø(»Ô‹å›Á]ñ»Nx'¢G¡QÀ\{€¼î¹|qüÅ·x·DB§`Ñb±Öãùøçÿèó@ý±úgÞû™Iwòå|ù¿û‰k|¬Óœþìý,pé‹—úÓ‡F­Ñl0ûÌ{?³óå»þ‹åA ^œxñÚxMø×†Û'zr>8=¾pî Zëkp¯?]½S´ñhôçÆéÆß§]b‹ÅòÌxäÃ!.=tiçË;k·¯ùS¿u¾•È$Ž¿ôøößnÖ §^uÊKxÇ7‹…õBí¶Ú¥‡.=ú±G3Õ̧ßýéþ~¿vKíôƒ§KÇJÓþ4¿–?8¾»Ó=ÿÙóß¶ñø_>þ±ÿëc?ü¶þä»>)¥¼ç‡î¹ôÐ%»þ‹åd¿³ÿÀX¿k=]J?­^ÁÒè}öݸ=6ïÙ´‹k±Xž1'_u²°Qˆ\¨—¿éå±TlÒ¤Š©ò‰2.¥_ü^ìÄœƒãÓåtª˜òÞ¨5ʯåO¾òäú]ë·¿îv °VÈT2¹ÕÜ|4F­Q0 R…Ôm¯¹­¿Û_yáʉWœ8ö’cóÑ|:˜Ön«=]mh±X,×`0{f¯zk5‘K<ÝÏÞ(+Ma½=r+9»¾‹åÓ:ß:óÉ3Óþ4UHñtüøK_øÜ…ûãþD.qúÓïzË»Fí«Ju*'*Ÿz÷§*'+ZéÇÿòñd.¹ýðöößnOÓÒ±R·ÿèGþè_ÿу¿ÿ òÕÙOŸm_lφ³è+R…Ôo¸ãÿîÛ»m×ßb±|£>VÚÖ Žë\óz¯Ý;óÉ3ÑcØ qí¢øÒìKŸš~Ê7þþ§÷ï~õÝ7®"ü›s¯ÿŽ×_ÐìB[,–g—óŸ=ò•'ŸÁ÷ŸØÏÖ²‘Se±X,Ï"íO·o{õm7®"üä¹7¼ö çƒó7TJw×înþÔð÷t/í\:súŒB‰hžmžoÜà3½Þpxþüy»è‹å›ác=³Nz»z‹åY'1Iì=¾·Ó¹A¡ÌpØÝéž¿p­5n§‰éù'ÎGõËâ ã/ìø;Úèé¥Ñ=‰xž{Ã/sW©Ð.ºÅb±X,–›)%p}a €Ž”JÝ Ì`0¯™N¬§”úć>á:Ž³Í¶¿wf÷û_÷]¥RÑ®¬Åb±X,ËÓâìÙó{Áö…Øß÷/\º`Z,‹Åb±<ËXËb±X,‹åYÆ}ò·ÇãIÑŸs¹¬”r<žxž‹Åß&“I&“v]÷)~ßl6›ÍæÑŸÐ÷}ÇqGN&ÇqãñØS<¡ïŽ#ÇÑZAÇ|ß‚0~æµE“ÉÄ÷ ŸÏ]_xy óù\)J%­0Y,‹Åò¼c6›%‰Ã¸ÆÊO§³l6ë<ÍÙ¦_çèù/á·û÷¢Çp8>ô¡>öØÑ»?~ú_ý«ÿí¯þêÁ§þ}¿ò+¿úö·¿#:á¥KWºÔ¼ï}ÿíñÇOýèý<òèÁëýèýO~Â÷¿ÿÿ{ì±ÇÝÝú;ÞñÀ£~õÃþ³g¼ÐÛÛ;ÿù?¿=ú…úÐG¯?àoÿöËõúÞÁÓ/~ñáûïÿ„P‹Åb±Xžüò/ÿ.J^[Ï÷Å/>üOþÉÏF.ÊÓâëDžŠÅÂ/ýÒÏ<ÝÙÙÝßoÞ}÷‹¢§wß}çÿø¼ûùÏ?ô©O}ø‘ù¡µ¯uÎ_ø…}P«8™L~ÿ÷ß D¯ìï7··wo½uÑç=ïù¯ï~÷ûŸxâÌë_ÿÝwÝuÇ Ïvûí/xì±'îºëÎ/}éË÷Üs7ðÙÏ~acc=z×÷ƒßýÝ?n»íÔüÀ÷=øàg^ýêW=ô·/|á­©Ô ¢\;;{wÞyûþè?þÍ¿ùå;îxá`0|ðÁÏ$ñúOßò¥/=òë¿þ¯®Öî¹ç®7¿ù6Æ|îsÝyç £Ï‡£w½ë}ÀÝwßñº×}÷ƒ~¦ßïŸ={á;¾ã¯xÅKŸxâìG?úÀ÷}ßëî¸ãV¦-‹ÅbùVãñÇOìc¾ÿû_ûí·}Çw¼òÞ{ßx`åOŸ>ûàƒŸ~ò'<Ÿ²fì_'‚ÕjuÞúÖ_~ë[9Ú(¬TÊwÝuÇßüÍç¯?2 Ã?ù“Ýwß½÷Ýwï;Þñ®'9ç/ü¿ë[yw·üÚ¯ýVô‘?ÿó¿ŠÅü+_ùÒøTtä÷}ßëo»íÔ}÷Ý{âı¯u¶W¾òeŸûÜøä÷|Ïw÷Þû?„”~õW#:£Ñzøá/àžÏýÇ{â/ÿò¯ƒáSYè‡þòþá¿ï¾{_ýêWýöoÿÞ-·œ|ùË_òº×½æõ¯ÿ@qß}÷~ä#üë¿þÛÑ×}ùË_½xñÒù/¿“Édî»ïÞ|à#¾ï¿ûÝÿoôîáÅb±X,–¿Cλ¹:ÿøÀ{ÞóþÈX¿÷½ï¿æÈN§û‹¿ø+Ñ»¿ñ¿óä§ý:¬J¥ô«¿ú+OãñøêêÊÅ‹—oxðý÷"J]’òÉò–þÓú÷¬áp´µµüàþ‹ÅÖÖVŽ\[[Éå²ÑOÂË_þ’÷¾÷ý·ß¾ˆ ml¬œ¿Ñhýæo¾èv»¯zÕË£oüÀ>ìyÞS_úøpkk£Ûí Ãl6S.WVj««µèÝ­­ƒ}ÙÑhýÚXÌ CuòäñÈç3Æc¾ó;_ý˜—¿üÅV -‹ÅbùVàÔ©‘«ó‹¿ø+ÀßüÍ"gf0\ð½÷¾12ôãñør°®a<žœ9snw·Þjµ+•r¯×¿xñ²¢ß¤ÓéïýÞ×F;†'O{’“|å+_rÛß*—K>úUàøð·û˧ÓÙéÓgëõýF£Y«Ul6óè£_}衇â'ÞôµN¸¾¾úàƒŸ¹çž»¢§_ýê­Vûüù‹'OßÚÚø{ïûÈQ+òüà‡ÓéÔh4ùZ‰ù©T¢ßD¿ªZ­ôG’ÉdÆãq¥Ròùüîn}<§R©—¾ôžGýj«Õ¾téò±c[¥R1úàl6»Þ‡ë÷oyË›÷¿ÿßô&+Ò‹Åb±|ËñßùŠ7½éG€(Ù©ÕjïîÖÏœ9wüøð¡}äu¯{ P,žü<Î?ûßÿÙåð²Bοëä+’É«ªáŠÅÂúú•lªN§ûÈ#_Éå²Ùlve¥º³SßÞÞ•RÖj•r¹T­–?ÿù/íîÖÛÌdn<ǾX,<üð—wwë»»õÍÍõ×¾ö5ögßÝ­ÿÄO¼iccm>Ÿþó_*—K©Tjmm¸ãŽ|âŸ|Õ«^Q.—¾ÖßáØ±­D"ÅŠ€?û³onnL§ÓÛn»å•¯|éG?zÿînÝsâı»ï~QµZyã¿7‘ˆßz멞me¥6 ¿ò•¯îîÖægÞòøã§O:qöìùÁ`ø“?ùfà/¸åñÇOO§Ó×¾ö5ƘøÏ?á©S'^ò’oûó?ÿ«ÝÝú=÷Üu×]w¬^±XX[[Ë岟úÔgwwë?ôC?`ºZ,‹Åò­ÀÕÆzõĉãŸþôgwwëÕj¥T*ž={a4O§³cÇ6•RJév»³»[Ë[Þ|Mǃn·×vXW…êÒ/]ö¼÷ñÝ·¾î±†ÿþø?°¹¹þíßþr»‹Åb±e.^¼üÁ~ôgö§oøîÙ³çoŸNŸ] {~òýÖoýÞáWþÅ¿ø™¯›õ$L&Ó÷ïþãáW~üÇä¥/½çùÛþ‡ÿðŽFWöAßð†ï~ã¿÷9áïüÎ;Ï»xðôî»ï´Þ•Åb±X,7%<òè{Þó‡‡_ù·ÿö­¹\ö†?¾õÏÿùO=Å3Û–Åb±X,Ë7Ê5,;*Çb±X,‹åYæÊ¡âÌ™sAÚE±X,‹ÅbyZL§SçE±8X±˜wÛm·Ø²X,‹Åby<æ]f1À»Eh±X,‹Åò,c,‹Åb±X,–g™·iH& ÓiïK_zôe/{‰RþÓsÙ¤q]õüô·½­üÒ/uìU´X,‹Åòw„ð}ç©:X›ó¯Þí<ìœ6BçºñÔ,vùòÎ5‡yž›H$¿rêÔI)…ÏÅ_h:Àsó]‹Åb±X,7ÂÜðÕ;X{jÿ«ÁWqÀGùªôX:Ñõ>þñ<Ï+•JaFo»í‰„›Ïç77={ºZ]¹ÅfÉ[,‹Åb9òbŒmÈgù¥n.Ä|©ñê.khíj8¼0Ë×¼¹ê RŒëî 18🄘H9<´ŸÝ“¹Æ¤‰A ’Æ””*)U><­SÆØ¾¯–'ñÚÃCR§!ð¼]˜Á &H98”Þ{Ó:©;Èh½¦TMëÔAªŠÖië¸[¾¶à©ejÝ¢¶Ýóv`º´³>øŽÓ:¤îXnõÄIBÒÆ”•ª(Uˆ¢Sà‚{óÕÐ<¿ÇiÆb_<ðŸ¤ìKÙ_>b‘B‰i“$)ÁÉH•,Jöyç[ž3mr¨A†㺠!F0… LÁwœærKÅ?dÉ\câ€8¤Œ©S øˆO©¼µd–¯u»xXê§'e¦0Ôã´…èŠE\c†¤ŒY ‚ÍÃêΘ¸R»Â–a–ý£‡ö¼úRÑ-‚OR¥ì,=*uèŽ1¶Ôx cV´.)oE‚Ó:õÔXë[A=âºï‹òyaáCUë’R+Œ"Zç•ÊØ:–¯ÿïÁí1ZÆf0sÝm!º0^*”à u u)ȳ†‘ÈE®|íÞ±å©X5Ï«/ls!¦®»Cè/mÛá|o¹—…šÖU¥*Qöçro¥fsï,_)çŽÓ†1L"Ù“rà8{0:xeÙ¨l‘Hyí†Õ0Ü4& uƤíè¡›ÊÁÒúÅaø¿j Ãò5®—½´–kpœþ2Îtò¹îeB{©Pü«J ²ŒÖ'´.EžSô_¥ª×9îVð,×›±É¡;þ¹sÏ»Áxù8h{xà?Ef¬†ËpTäÍ'ƒ`åê,(+u–ë£ãt©»‰”×݆áRð&‡ºøO‹ÛE¨…áÖR“ ÃÚuñ'+x7¹ƒUò}c¯¢eiÆK'iSÏ» ý¥B ‚å|'g©SRP„5¥VIC*R+Z—•*Ê(·µQ–ë͘ï8Ã¥ÈE1€®ãì.ý§(0b²t¡÷ÄÒ’m„áæÒŒ¥!¥TMëä² Ù1Ƶ–ÌrºI9^–ÏÁwœ=)w`Ã¥ÔÝ18åŒ9©T ’ƒ¬Ö¥rKuUƒÚR†£í`YŽŽ[ÖC‘ó¼Ë0€ÁҚѢӫÉ=ˆòQrZ¿À˜¤!YcŠaX]ºY8Z'¬%³\mÆÆBÌ—‚çCàºç…hÃ0j L=bâkŒBhƒg d /…—!¹…¨*½eLe)uYcÊ‹«î¬ƒe9þÓL,ru£~<Ï;K0XØ0Õº.T›YÈ<$ Ð!„ÈœN 7I,GºJ!«ô d‘Ã) «Jmh]\B\cb61Å"D åèÐ ²±çCw "ç©êI¨!Ó€™O`Bœap"Ž“ÀM^%“4¢ªÍ"“Gæy­«J­‚‡vÑ‘ÔÙÂ(K4Kx|¸c°ãìJ½CÐ%ì£úB÷„iàÏ™…*ÀøH…ÒE&qx +d’Zœ0Ôyd™7¦†ÇÕÇal9Æ:îë`ݤflYÖµE{î%Â!j€ê£{螤!fFSæ3Â9zŽñùÂAƈ%HÄI%M6cDYÄÉãæqóÈbœ‚Ä£1æÊä—£ìòY©S‡ŠÉÍx\gW„û„]tÕ´¤j1õ™ÎñçSÌ£¢Ï#f5pfM1211 ˜NÝ =É1ABd%¥ ^™x‰DD.t7´)Gíz¡¥Y2«P¬àa\·-Eú˜.t1'Üã>ã“!ó!þ€`ÄL194]ÃÄ)AVòÈV‰•H®,)oUÉÚRê"ß=†«‹/·Á€#ì??Ï»(èaúÐÅt¡%ýœ¶ vð‡æ3&ËyŒQ3ü„$©;A2‡·F¬D¼H"¯“•PŸ<$xicrJ-gäÍíú[ug„ð=o3ÀÔ1èÝuf-Æ&#¦æCæ¦!Óe×EÀx‚„àCžÚpcë`=×±(×­/g¸ö ëªsbÒe2`ÚgÖ‘–\± IDATaÞe:b`e¿þ¡¾†‹ uÉ®’®‘ʓΪĊf ŠPŒÚl*µr%el…”E{Þ> a‘%ë9ª)§ ú ¦]æ]ü.ÃÁ¡†š,[C§¢v†‚t†Rd‘tžB%tŽSY ^²a¸z%ñNÛíc ®Û¢ÝHÝIÓtæ Æ&}f=¦ûŒ{‹©BÓåX—h˜PòƒŒG¦ÆF‘TžTÞ¤s¡<PŠŽPjõªŽöŽñÈã8C);Ї´1 'Ü—Ó6“>“ó.ó.³1}C÷Ð<ëƒþÁ™¨ukŽr‘d‘TŽtV'*ÊlB ZÝñ•›u°žEç)*K/òö7ØfÚcXgÖfÞ£=ÅÀ0ÖL5¾Fé+×õÀ*æØÈ‘/RȇñM¨ ʈ²€ÈáærÜi[ŸbÍØôÏQ 9¯/\öY“Ñžè‡ô4CÃD3×(1ˆC£]ó‚dš­<é™ Ù´ŠŸ0bQFùPmâWF•iÇ([ÄpÄÍX4­%ºlHšŽ¿Ë´Ï´Ë¬Ã¼Å¬/ú!MÍP3Õ­¯8îÉÈ9÷(çØÊ“ÉÉètYËuDQE® A¸~0ZZÁ;â±(×m¶³˜¡7?ͨŬüͼ-†3zšfl˜*ü¥º;ì?e=Ê9n©‘ÉK+oÃPC”‘%DA›šÒÕÂg¡OS3ÛËõÔ¯«ãtæhÂÈÕ-é·˜u™w˜7˜ÖEJ/d0 ˜ÌC|ƒº:•‘¤ÓTÓd3ä’¦œÓÞ²‚SÆ-áä½iL"Ê%Ϙä"e3ʨãîKÍXD=Ç=uYÌ¢°S¿Å¬+:cZÀIÀÜ_ä£D÷d±åVI*ÁJ†Lšlš\BgsÆ]Á=5< ͦ6ÙC“…\c≥~DÑŽÓ[¶ÏÃHè7¿À¬Ç¼ß&h‰Ñ^@?d0˜á‹¤quì3›¡š%›&—2¹ŒŽ—q*8œ"^%ЧŒ‰HÄq­º;Âên¾Tw‹¾wNØw‚:³.Ó:ó}æ=Ñ[ÚÙIÀ4À™Ôröl2j­(ÉfXÉÏPÉètÁ¸5d·ŒS4²è¥Ã•½'@`žåÔë`-8TL>‚)Š™ ø]‚A›°Éd$ÛZS†3&Sf3¦êʨMQ<À!•"Ÿf+A!¦ói2b'ˆUðŠÚ«„beyh2š¶q%¾mË£ŽœÔM—R7ÚgxjWø]üA‡°ß¡?—ýƒ9Ý1ã Óù•Í”ƒ`@FIN°‘!7ù´)$‰•p+Ī$V•»¢LáÔÅI³üçoÓ¡ŽØ½¢”QþAÔÂ`ŠÕuÂ:ó&þ.A“ÉXöGôæ fŒgL¦L}F\´$㤓¼p•B\Ò¤²¸U¼ ±±B ¶ŒÈ- ƤŒ‰_ù!VÝ97>Ô*h*ÕØUuüÞÂÎÎöDo(ú#úsF3&3fS&šÙrº»tÜ“©… ÇââºT UÁ«à•‰WØ8dg“W©;óÜi¼£â` eH.JÊcr›°GØAµQ üŽ3hÓ›ÒÓî2ÒSôÚŒF•'£¤IœG)CÉ£âšB–Xä*™5“(lE‰†¤Öù«ólHà(݇¤.€À¥)uÕ@5å¤)ºúúcCÆ#šLU0lb㬥)¹¦”$U$^#Q&YÖñµPl-¥.mLþÚ9Ö…:Z‚§à ƒFàˆ¾c„=Â6ªÉ¼î öéNéŽÎè±¼Yd —»xI&F>ÎF†Í˜É刯¨(“(„Þº6Ѭë"¤´¾n,£ÕxGÉq?dggz¢.TgagÃ}ü®tÅ~ŸÞp!x}}ÅΆ‡Õ í’õ¨d)y¦#›%½Er…DIÅו¨FÆ8ªUª|Õù–‰}ÞVJ6³„9qDÓF_Æ4 Úôp‡Mz†}Æ]ö¦t)µ\Œ8ä ’¢Ë킪C6G¢FªJºL¾à'7‘Ùƒ¬^È„aÙš±£ÊUC¬]Ù–¢…ncšè=F=g0ý>½!ƒ>ãã>MZKó•DÅ )HK ë/r(ÅIVHÖHWHƒÄ–IÅe(C2JU®Üa7SŽz©ñhŒ‰¹1í…à™}F¾ìMes—~ŸaŸI—þŒ‹‰yÓCÁ€¤$YI!ÆŠà.‡jšô© é’IƒØ‰x4åòP ÃÒU¿Å† Ž–º»bg%3WžÃtR7ï ÛôÆ ú´ëŒtÍÂqÃ|iãZª»’dž¤êÍ“¨‘]'W âÇLÊ;dgsÆ”Ê>ÕÝóÛÁ’|!>ûCgؤßcÐeØbÔ ЀÔaÄ"ºÈr/ y8[°"(äÉTÉVÈu¶ªR%ÜUXä‚`ãÚüq[uT­šç]‚´¡‰n‰‘ïö.Òn1h3jÒÐ04¡µL7Ÿp%- µ¼É/Ã1øîÙ™ ¹ù‚ÊÔt<5¨Àjn»±Uµ1Ã.ÝKŒwé ÙÓìZš®a¨‰êP>odÉ*ð"¨f)¯R(Ṗ¹U n±‚¨"ŠÊ¬)•=$x‚ÀÖM3Ö¢ ¨÷cåNrØbÔfÔ`Rçò=MÃÐ1ô5C³AiˆArP€2Ü U‡\|‰BÁ¬®ªbžd±Š¬!*Ú¬„ªr¥‰6è~$1®»èw~‡a›]`ÐfÔb²Ï¨É~Ⱦf×°¯ên~ÈÎ&!Q,âÛ ”&["_¤˜SùSL’ZE¬"*ˆb¨×´N_egŒº{î¬áP¾÷½Ù­­…ÿòéO'\—·½­Ýé8¿ök…S§Â½hþ“?9øÊWbï{_v0÷Ý7ÚÜ ?þñäý÷§Þð†ÉOz2ήSÈRNëRÑ”cä’¸k85¼Z(OjÒQ-^47j‘eì^Þ‘3c0„ôÑcÆÆ›ï‰I‡I‹iƒé—bN3¤˜~ úá•D¨ƒÍ”4 · iryV ¬æT©@Ñ!^Á¦m”sÒˆƒúo‘Õk“QŽB()ÛËzò.³‰˜Þü2“ã&³=Æ-ÑœS¸4§0èF\i…ïFÈ–±Ï[]òyòyÊiSÊêµ<…4în ·¢Jhj‡ê@ãVÝUu×êïudzЙNœÁy&-¦ûL÷èLDcN#¤Ð hôÍBÝéeÐ= Y¨Ám‚B†|~agË9SNÉà®;nÜR`N Ü«ªq¬º{®,Ï3?öc£·¿}ÑQw6‰„ Õë9£‘Êd ÍêáPöû2Ÿ×@2iÚí¯Ù|B½ìÞÙO߉e}ÊÕ{†b´(†¢O0÷Â}1ë0k1Ûg¾Kg*›ê3µ;2½)½mè"hm0จÄbOTà…qŠi*)jI}˜|ík§ó¹øØÇRoxÃä±Çbßû½‹ýÁzÝýìg'ÜÝu‹E;áyoÉ–séF£pDGšÔ9ô£¡ìtiwiõM»C»ËŽ6瘵ð‡„#Ìã#FâJ¼$¢ˆ,8Nʼn•gUšM—ãP)Û¢rLfËAb§ ()òÆ®­ï]«½277æÊ(k£ÐH&;è6zµ+[{¢Ý1­¾i÷ètØŸ²©3ï3ë F˜9ÒG ¤Äsp’Ç©ºÞ­nº*Ùțd#Fn•ì*ùùU•Ü25EÈi]º6þdý§#"*=Ñ #Ò졨:ážèÌd§avÛf¿I»Ë¶a— ½ªÆ‹\r#q<rÈ‚p ®{«“Z‘âv×”JäÖÉÖÈ—Uj]ÇŠ†²ÏŠ1e¥ 7rêìuyþ;Xý¾ó«Vջ߻ãÿïÿýñ}÷ÞùÎük_;yÙËæ€”¼óùüÁñ _¸p›ÞùÎü›ß<\__Ô±Üq‡ÇW<ª'žðìõ{~á8#)÷  ûèºh÷Ýþ6Í.í&{C.q‡Ip€¢çfц,N§ŠW&qœD ±'µ"…5J5VÊAñ8njš²2Å0ܸζÚ¨£§æÜ=!šÐ„:j_v'N«ÎNv“v“K¡ÞfÒfÞÅïö1½èIƒ˜ƒÌ xErwãmÀ ØŒSZ£¸J©b •0[Å[…€’ÖåÄŸ¬Ô9u×—2’º}¨3;Ý®ì4i¶è49¿o.h¿Á¨Ã¼KÐG0Bµèäš™Dæp‹x%r·â­Ãm‚“e kk”ÊAöéb*!%¥Önà¸[Á; V©¤~þ织_©V¯zåÔ©àðÓ{î™ßsÏ FŸoo»ÿã¤‡Š¿ä%v6ú· RN¥lBZÐd:uzgï ½=z»4Ûú²™6˜5Œß4aǨ®ñL !`p p8Y¼ÙMReœ-؈Q©R©ˆZI—Kº”#µŽØ‚š¯7”Î#X¦@ ¶ôè™±¶mè@Õ¦‡7ؽ=z Zç97˜×™6ͼi‚6aǘž™ûÌ ¡ABÌwp2¸ybÒ[¤îÁù6¨•(W©–¨”T©JÑCn Ö[³pS»"râgïMÄëÃ6¦Ád溲·G·A¯N¯nvæ³sŒêKu×3zÄT37hƒcH ÜNŽXžD‘üqâ+p\R˳¾)Ö«ºRÖ¥ ‰"l V•Ipb©îi<ë?YëY¤ZU÷Ý7žx"f¯ßshƺB a]TŸq§u1hѯÓ>mšÃùžž4¿†­@µÝÑÓ Ÿ „GW¸"ƒ›!ž#s«ëˆ5OTÊ¢š—Õ•Š©¹2¸›Än1rm&*8âМ2Ï窀¶mnpó;î#)»PÇt™úb軓K Z ꌶÍþxr1œ×ƒ †­@w‚°Ï(`† ‰ D'ƒ—#¹JæveÄfRn®ˆj^V3ºZ¢ê_ÁÝÀ­â–gb}Yu¨úØî¤!©›KÙ]ômÑ]ú¾7¹Ì Ã Áp‡~3¬«Y#ðáüÒ\µÝÖ““?D‡ˆ˜"æ"3xYâ9Rk¤ó¸ë‚jNTвš—' º–'—Å݈ ç3Ž‹ˆ^GyVÝYë¹%7Ѧa&cÞ³ƒ¡”ÃEM¯31b:ug—˜4™ì2ÙñëóÙåiؘ‡Í™nMu{6™ÑŒÙŒ`†™à8bˆ^ŠxšT‰òkÇÓ²š•ÕŒ[KÉJF®A¶J|ƒÄЉ¯„ñus )H(Z§o0®ÜæWÞÌ‚7“r°hdŽ„ž¿Ã¸ÅxÉŽtý†ž7ü°9 Îu{â÷ÔhÊxÆ|†š#æ8Ž€$NŠXšTšÌqŠ!+)YÉ:›9g£â®@%Ibƒø*‰šŽ­*/g³³ãhº@;H‡¸KÊ¥èQM8Þš«º‰U'±ê%×Ç< 6X=¤·HÅåhŠšÖÅ™Ž[©;2è+uÇ„Æ$!qs:X§No{[ø¥_*Áëì8)·aN3ˆ}å6wØí°ß0ýIsÞiоĴͼÍdB×,¼F© HEíåÙ$…U+¤×Ȭ‘¹%.×6¨lR©…“”=’YX… ”°65Ò*”£{+æn ±u¸Ìpà^hˆÝ{m{a£ÛmÒo2j1m1Ù§ë_é„•DEY£nPÅ2ñc¤VI¯‘[#¶§¼IuËlók<ä Ô †kÚÄope{ŠºëJY‡=Ø&ܧ¡œfWî58}Þ4öGÍ ×bÐbÒbÖfÞ¥§hRw³ÓŠPr©¬‘ú¶¥º[—bµDi‹êª.o©r‰|a©î A°:·^ûFʱã|v0Û Grâì·Øë±×2­Æì ?g^õoNëf7c !¢Á®u†]¹?rZ»4›´wTogÐòuÆ»L.3»LJ{9ªü`ÈAl9Ð¥à‘­Q«©‘«Rª’¨e9u kUU[Ó+qŠ 8ëP ÃÍÙõ†mUÔQ‰ ®» mh ÷è¢5wë³·Cûò¸Ûì3ª3©3ßÇß§?c†Ë¯b9LhaÉ2ln’®’­Q¨’«º²ºÂjÕ²Þª©,±lŠRÇC ¯7cÖ’36pœ…º›öi¯»M£M³®Z—û;ÝÁ“:“:þ>³mM¢ü©u—Z6$OåÙ,s×1 «+ÄkyVÖX­šÕjX-SĎéHÝM¯ß¿³êî9î-)[ÐD¡ŠöÔí\¢Ù ½vwúÍpX§–Ù~“þ|1Òzºœö† /yÕS3èv­ŸC36wœ&ô¡êÐÓ²?u§iïêáåñ¸3ª3Ý gõÐßSA#hLU#d0S!ZÁ²T qâ+¬yA‰b‰r^& Q«È¼¸¥"V“2ŸÅÝÂ]3Îjh6ËTFÉ5ƳUåGFê”ãt`L“ÉŒ.Π%{;twgÝÇFÍ`\7óz0¯«`/˜ôÃVhºŠžÏ4D…s%•ƒtŒø ·¯“+S,RÈ&ÜJU¬åFÞÔJrÕ‘…¼“¸+Z®)òsG \pÁ5Æiïè˜1!zP'lÓײ7vú;tôvæÓa3^PÓ ¿úͰ;W~È8d®P!¢‚º,ä$ñ,Ù"+Eò%6×d¢P’+e±–g¥*VãNÍ!¾Ž»aÜ[C6ôBÝEu ÎbŠš¼#!uC!zЇ&aŽq›{¢·KwO/ƒñ>Óz8¯‡þn8ÚõÊôB†!³@¡ÕâŽ1 yH'ˆ¯²Y⎅"¥¼LæJâe¹§1yÞ-ß·f–”BŸpÌ9š:“† 3ÚŽÎNëÌwUXŸõyؘv‚Ykfú3ú#æ3”O`÷dqHA"N²H©ÆÉå,¥xÚ+絬\-8ñøºçå×IlXQÞ†Žeˆ d"¥MÒÜ0¿ÒÖ§Ü„1€©èbÚLœI[޶Öƒù¥é¸;ÝÕÓ3Ó`Ç÷¦£á´„½Ã“þ N¸Hç% iI,CP*«uLÁ{$WÊ3,(;ðà!{¬àwÆqà©®¿]Ãc4؆wëàõb½Œf;V[¶[;öþùÝ)‘ÜØqâÉ,%‡›xÆ®&ìFÌ®;ñ†o" uR-Ò5+…v‘9-)S*£µ (º¢î¢îøèÂcOtÄÓˆÝ7QÐ;†ý`ìG£mØ?„ƒ­nV˨;?—»;Å<Ð NìÛÂvH$ÈåÈ;”bFÉJÚ'þ2‘r˜Õ$é6é©r¿%n!rS*«µ­Á¿–»q÷„ØÂ}8õYÃßÈcw½ÃzŒvá`õvÑpsœ¸Ó-Ëë-Û5—/ú¬1‹x‚l†vž¢CM:‰|ÒªÇc¸]9 aÞ4H·IWu²ÆÊ˜§>›Ò:©”¾Wíùï¼ëáÓ§õ!„}ahé>Á ƒ‡pµÕã}4X‡ßÍÂûÑbåÏV,l–Vl,` »³tä4Öv$ ›¬E1ÏïÅI¬XÓvšV¢a§ê2^I“¿%_WÕF˜©c¥ 9­óJ%ßó]¯ª”çy”> }¬èôñ{ê8 Æ‘΢þF Váh>œzã)ë%»%‡ ËèuGÞ,uqŽIÚ&ŸàeŽšM¦h%?q-3Ù´“5SæäÛä+Q¦eS˜5·ãå´¶¼kûQ-Dðˆ:|"eª… '#í}Îgz¼úÕ_«Á|?_OV,–¬æ¬Æl]æ°ƒÃÉzv0d ’›bžÏ-Ê «Ûñ¦hš¹¬x=Gî†BCe›aºLÒBOÀ‹¢Rˆ¸²öSŸõÀGXú^‚ö»áj½Þ©×cÕ_ãÅ|íÏ–¬–lVlŽL`s2¼_è>ƒ¤E1ÆÇij¶H­XÃršV¢i§Ò.ç)¾ ö"L7U&yÒ'g!E鿃>û#!XúüK¡1äÆß ûZuõjËÝÃtµßͺAw¾ð·öc¼ Ç%‹%la)é$YIÙâ·%©²t>NK¤š"S±ó²O4E©Zªç¬T¡E ýCcÔ•?=gÔiÐh,£/¡{ÚûJ•î!¾1„“Å,Ï‚éj®wÆxSv{æ°âq:™ !Èò‚¦ÅoÅE¬.b-‘z)r/E6QÊ#_‹Š7Q)KŠ«·ÃúÕõ#,w¦\J1BÐ]íõ(â[et'º·Ü¦S=ZlÝÍ”ÝwÂaÌÔe[p!}^—&X· IDATJP–”,~W(I»)â-‘hŠtƒ\¢”K}!J•0ßRe›2db'÷ 䢨äjëÊŸ~4ÀSçrw/˜<öÙÅþdÈ3F“ð¡7ó‡3¾œéÝ”ýo‚·dqR(ûç£ 1AZ’”,þ£„HÖE¬)œ¶H5E¦ËËN<ÙÔ¥JP{I ³xê³JU"•ø{ï³Ázx0ÿõ¿Nññ?øƒãÿ)†1€ú[Ö.C¬Ùk†S=ìö½ùÜ[ ˜ÿwÈfÉP3làÈ»´'sJ >Ž“¨’»¥|K©,³™²¨6h–¢Z]Õ“”lÄ x Å ¨ž€ö˟ùÍ,0Í1,`Œî1;šÝ±MƒEw¾›/G¬ûìû  yt¦Îü 0 ÈC>¤J$kdêäj4k‰DµI³F³V«ºjá  5¥êQ”ç½ÇWà=ë#åÎ0{¬½-'+cÜÓß³Ùu³`ÕgÛçÐç0fâ3†¬.øÓãìÒP|– Q%U'[§X§”MÚÅ&­ZôÑKUw(Æ¡ (EQ]©×r÷ã;¦9¢ctŸ…'&®90œêñ`{èõ¾ 6}vÜ›'€.γÏðL>žúìiüðyŽÌ ™:ùÚ©ÏV©Õi–U½Õ2ä+È6T•jFQæDÔ¿ÙÀûðV£ý³¶ÆcCî¾²¿þߌe—Ù8ÜtWÞp=Œv=íöB÷!šN‚¡ÒÓˆUÄ6äáiBÐç|”ä ¯b8eÒ%reÚu£œ,šÕ²lçhå©'dÅ’f£…Y ô+ qgsÊuÝæ¢I¹€%L –,´±\ÊáÃûmp¿^î·=öýðØS^/š¹a/Òý€mÄ!‹ތ Ncíáƒd–d™L‰B™J^–â%óã–èu=/›ÂH7˜u-«¡®`W˜`€¼º¢~$Ç0N¹- ô„­Ç kõÀl¢çƒåöõbäî»úÐ ½^´›G£(G,B6›àM¹»Œ3(ÀÏ2%ÒereJE*ÉT2[­¼lgÕMÑlÇ„qƒÑĨê&‘î£ïê>þ‘\#ØÁ†øæÚ\ÍÄlÂllVÇÑz¨w÷jûeè ¢©•žE¬BöÑcŸõÏåÎ9÷Ù |” Q¤Ø¦T¥’3Šñ²l–d+§ëÑ4e)&­1o•¨G1p…&H­ b€Ë‡G°LSçrˆÅô¿ýŸÿü¿û_ÿt{Ä=r 8èÇNvº“l–yA+M²B&O>G%%ëFÎù¤*›YÙLÚ-ìlÚ4n‰7ˆ£caÄ ¶Ö1­MõÞQèõ<«66†, ·l+mí_³š„ûþrw·ëÇ~èw½ ë­7Ç¡ò§ž^Y88¨Ç8(}a-B1F+O*G.G)GÍNä’y³™1:Ió³¬]3m«)ìñJhµµÀ‡¤Ö1­cï/&Wà=¯©çÙz<äà³ÂÚXOYáÃö0=ôØÿòèw=oäÂãØfG6GöG\z#¿³Î#¨b4ókóTRFÍÈÙÕœÙN‰fÁlI»jرODü§ bÃD8`kl­âoÑ'㊺çw”aœ¤ëÇêÓÐ\ß±š†‡î6êí&¾ÛÓ~ßó»þfxxðÝ©ÇòÈ›>ûvìâiUܤIæÈä)äø(ʦsF+c´R²‘¶šÄ2yÃì¯ëD54ë';ÞcŸUq|–}öÃÖ`Íw,väLêIòe*)šIÒÛl¥c/ñO³N!0nd¢IºÆ›*e‘ˆ“¢<©”Ã{s ¯ç6:À6èᯠwÈn®§¶}wº]}üÛ¥ß?LÝí0ÚOözµc³å°åpd®Ï»5Îw²Ø¹“•b|R¢”¤š¢’•v#iu’vlj5D¾œˆFª9(™$Ö©&ÁQ*ÉÕõ#èdRîÎ^¼åöÄaÌnÀîÁ›mÜ^/ z›cçÎGÇ`¾e½c·å¸c±…0‚Ê ª¹"­ ©jÌj§¬v"ÖNÄjÉD¬j[mÒ5•¯†‰ŽHC ¥² Þ<}¥PϬÜíá؉еü>ÛË_Eë¾;TÇž z;ÿÁÝÏw}µ{ÁhÉjÍaËþÈú,ú|zÅ{"î9“fŠBŠjŠzŠt݉ý$g·ã±f"žË9ÆL4tªÄ[¤ ™8¹!qZ¦þã4 Øëÿ³Üÿð_þÇN¬%r•0ÓV9‡<ÄP€¼R­­k5yÖ3€³åsDz{3ìiâÓ ‚A0 £è¯Â‡Íl6éå|-ì–¸ Ü- ÅVz^ëìïu⤊ü®CÝ4›"–,Ùv'k[N›dÍȘÍdò•Fnèœ$c óƒŒÖi¥œã•<=Û£…ðQ‡G ð0Ã¥ôzaøàs,waÕèÏUo;õ–½`9œG›‡%ÇkÿÑ7ó$„:½Ç b6É4åŸÅ¨æ‹D2Þ´ìv,Þ–ÉéL6-oÍt]ç«A±F bÉ cTFÁñZîžm¹‹À‡#x¨à„>Ku…7 ÕмÞ&êBo©º»ýr=R‹‰wX,Ù,ØôÙoYê7êÉ󞄸#“¢£b‰†ˆ•œ˜Ý²â;©IUÍŒÑrbmòå(W‹²irKCÒZg”Šù×r÷<Váya½üÏÅ?þãw;ÙÕõ¼ÆggJZê£)¾&ê£îÕf%GsÝ]«û…êMëåCŸa—͂͘â¤9ßœ…ä's¯Æp!†Ó•;Л§ë‘^}ÍáŽã˜AĈ7Û^¼Øy¯K>‡†$S%õ)©Ù:¥D±B3“¬Ð(…µ MxC´ …(ª*öV»šžõ8ʲF°„1ô8,À/°F÷Þb>ÑÙê/—ÇMŸ}—cé„AÄ”7#¨ð ¼'/^>:”âMœ6Ù[ª­XI6+²nVŠAí–4¡G¶à¥R(Ê\½x?ž#åÑ0N @D¦}D?0Gƒõ|0Яçîl=dßÇíâ XìðHߟFPOC÷8d _@C’*o‘h‘i/ÙÙª¦_‰F%¬iBâhBEëb–ï\i¯ó§-Áº½ þäOÀáP¼~¿«“™æìq)cö³?“Ó!£¡¿z˜ïç˾ÚtÕþ^¹÷êË}ÔWLˈb¯…äê)åÂõÔ%™"Åõõ¢,' f£"nòº]¦™”ÙŒ0^`¼uK‰$H.’Ç_×Nö¼‰ûiè ¦¨)ËÀZE¬¾Ý¸ÝùÔ_?¨í½rÔzªº¡ê+îC6нz3 Pg^ò,I¹=¤HWÈÕ(U¸-;ùjMtŠò&«%Q³¥ÕÄh#+JTCé#}äY=~Ýlýœa¬…˜ÂÆvbæ[‹ÆS=î­ŽÝáwÞúNíï•ÛUC7zPŒóˆb£Þ丞nŒÖÙŽW߇ºAºD¶F¡JµB=H+ò¶¤Ò¡éÈlNȲ®e%ˆHòˆñ¦Üq5 _ Öõ|H·±ƒ§4±%ÁVlk;d¾‡_®ƒîv÷ø]o3 ð‡x“0˜Ø{xGüà1„ìÔk$¤ y¸BŒT\‰bžjN´³¥X»(oR´Šf3Q¶éØ¢*ì¢o6I€-–"vz–Ñ—{ÊÄõ[=³¶%,aÎ.”«½¹î³˜„›þÆï-îƒÍ×x÷ê8ðF^ÐÃkoîë­Çþˆ{à¨ߎÕÅ$ MøH’Ê“)’/PÉSOZ¥dIv²ò‹¢l§ÌRÜ’MÃ,FGÛ&1ˆZÄ41…©uì-´]…PÏê(Ã8Ú¯ñ§bãY›!ó9‹ÑÞ¿[¯×Û>‡{_«‘ÿ€7À›‡áÊ´úG…{Qîžâ  ð‘$W¥P¡\¤–5;¯æåMF´ó²³Ê™¸øÔUìR`ÔˆA LC‹ˆóV¹ÓoÕõ\ ÖõüæÎ„8©J¶x;l÷ŽíLí†{ÿaÝßú]߿߇÷‡ùfßÝÑAÏw¬·ÌW¬ô?Tø¶<yhÙ$KdÓ”ÒÔ’¢m&²ùtüw2V;í´D"“‹™ÒuÒÅ ÖÔ # iˆ_Ê¡Þce¸žu‘'!Ó5g‡åNÄnÆvây½}Ð? ´ßu¿Ø¹Ýý ÜöÝhºc¹c»cw`¥Yž·/´6¬gj?Ø«‡ýbìé » îŽîpÿ•·ìÕ|ÇfÇ~Ë*dÃãЧ,ë¼Ó: uA:E:C«H#%šf2SH[·Ž}“ŒµbNÕJ˜-™yI¶æÇ[$$2q²kÒÚ:AìZî®ëz> 6v„½'ò9bEÜ…ö&¾êzÇq0PÁ7®újæŽ7ƒp98z³Ë9»%û5ÅèBÏ{Jå1Îz”¢ §âSŽÓ´Œ¶á¤jvìÆŽ¿ˆå?53±ªoS¨êl5L—È Ì“ˆ¥E9úWW}Àó8ZÊ'#žKŠ£o»gQÐ?ª®?wƒ^¤»ëè~n~ŒÆkK¶ öKVÇG!ùÓR¼K1JÒ‚dœf’j’º-Ú2VJÇb;Ö‰'nÌTCfÍxæ Å(SS™ ò…Ô)ÿêŠz¦å.Â{ôâ)_KgøcíýðkÏù}uê~>ìf‡U?ÜŒ×z0d7g·a®}3îE–q!¿K™T>‰Stx3^šN¢‹ÝZñN<Ù™|2mtd¶A¡–Ú:kad!{öâ9Wà] Öõ|pG q’‘„¦ì 5#öØO¢.ª{Ô½Yô°îî{÷îj:e=a7f?c0áq#ÞîmgŠyæÉ@Õ lÐ0¹1É—DüÆHÜ鎑«YÍØÏÌBJ1*ÖTÑ&ƒ EÅÓ…ìj}ÆÍìÑ¥#CN¥Üá}«Æ¾ê…ôênëŽæ=&ÃÃ~2azÇaÌjûƈ·;÷§Nv9 ¨üÔà‹›NÛpnÔ­‘mÊ|ºX£P£S * «%È)U>¥ò¼ ¼+êžÏ‰„8¹ð")6¢aŸ Ýûꛃ~˜‡½ÕÔõ£ùdÍ'lÇlF vL~à;¾}:¬à3“ªAÛ¤åúÂL¾4Ò#W‰N2Ù¤R‹·ºdSt0+P<í´ÖÚxºïJ°~£Îë×ÖŸýYø7ÿ&þÿáÕEøî1Œ¹”w0B?°téc–¢; †³¡Ý­Æó¡Úô9ôØèE y\±¹âœ³¤÷Ä¢ ð)4 -(äq:¤nȵ(V̪Õ._Ñ*µ ÈÛÈ&T Eå@%¯v¼êöRžØøïž‘ÇÖ Kw±ÜO†z0Yï—C–ß±ÿ–éž>ï Ñx>i¡*P:y£lœ6‰™6ù†(§²uѱËZùðeM×mœ4OQQTx·]÷\˜9b èãb~=¯þd6T£‘?šY÷Ùõpô·|Ç›êîù‘÷)ÎàÉ}Ü‚´ #Ù&÷ù¥²]Í|¢.ŨÞPõ$5ˆßžÝÇ¥œ«ôÇpoâ¨Têy¬››à_ü‹%àº?FŲ”{)g0…qœ[‹;FS5ì-ûÞ´Ëⵞýµ¾óôkÔ@3Õ¬5{…«ñÎÛ¬õÛì4ø=x“b…bƒZF•t'ÁmM|Z㣪Šß ÑÔ‘?¼AœT¼â€äü›«+êùR¨© XÀÈðÆý7 Æ »î`>é1¿g}§×]ýpÔ¿Dõ4sÅVsÐxúquIÜcgWTªÐ†ÛõTê4«T†xQ7e:y]¯êd]ŠŸ!JŠRϾO>¢NÀÕõ\Q·bþ¸4š˜›žœŽŽÕ¯~1ïÓ.«{½¹×³©þý€kÆŠ­ÂÕøgÖ®ÏÀ;]Oåîpµ …6¯nIvÒ¼¨ŠNIÜd£BSˆ!šˆR¤›‘NÊûuWà=ã>{”òf02¼¾12ž0¨QÝÔòß8ô_eA‰³/(C*NæëºdQ‚´…,AMë|åÞ]-|ÅÞ‡OÙÏ»ðB¥ÞzD° èGî7á8 ˆîÝÅfµééÕÅ4XMz&'¸+¦ê­mŒþÛ¯x6$!'h›TmnlÚ¥¬iuLûÆt:2Ѱ²±J‰›R¼ª˜¤yâ)Jà Ëo_o¯ßíyôÙ1PÊd"¢1ÁŒ ƒp¤‚_Á÷»°¿›‹‰^,6ç>Ûc¶c ‹‹>{iµÎü©e³(™Ô,Ú&µŽmÝšñÃišé|2+ZEéxQ•ÊQ3GÒ6¢Hkò£ô¿×êJ°ÞÓÕLó´›l=ü±9™‹þŠûUømo0 &L‡,lúŒÜÃN Nm,¸¸/=5³Ó[^ JP‡p#yCõ Ê7T+f&Û¤Ù YVÕr”¯` %¥ŠQôhX8¾3‚ºN¡ž×±¬ôa€î‰ÕÞ¹_q·ãánù}WXwYÎ¸× xœ}>”èÂÁ Ïeå¤JiCÚðBR*‘º%סÜáE£hÖ›4«ÔóQ©ªÒh@²aXÓ:Æ· _÷¼ŽiÎ…8ñðþƒ9î‰îšû¥~˜­WÃî"™Xö¸ŸÒ…áÙþ¹ç ê²Ü]f¸tà%| í8©[²7ÛT¢œÍÕ/Ûê¦åŠXe¨žÚXTOOxWGÞ³>Ú²í ô9NéJ~;äWã`4êï6Éž Y ØöèyôàæO=á¹Üé3ꬷ՟-xí ÅŸ»¡Ü¢V¶“ù&Í’®æÂ|ó%” †õSlлÀûÿÆÝ\Ë0R.` ß²;0Ñ a¨Ìé`,'LôgËñ®y÷wúØgÐ;YÊ/‚¡/)Ø'j %¨AÕ®k¨“®PH%_ò²M!•-©vžhA¬:¢í0¼Õ:vx,Pçs5§<—#åÞ0æ°†zÂ~Ëw0@Þ¾?Ñ‹)Ã¥înW‡}÷otøšÅŠÂT¿‘ßy“yÁÚOäéVÎa7‰7HVÉÍ¢Q®Qn™…T£©;7Єl Ù‚*•ªùQÚ¿ÞuÏŠ9M…X=î±§Ìc ¦Ko8f2§·ö¦û‘:vñïtpÏhÅ70…~+Nó) ÿÒ:s U¨Cº@â³s¹K¤+T”êvV×Ü|-U‡”µ®„aåüp|Þ³dNc˜À =f·g Cè#½y¸xàõ\Ým—ÇCïŽà^{z!}èÁT¿QGo‹Nk@ÛP>Q¨ØcŸujëf-^­SjŠB*ŸZ%n  5« ¯ E5¥’oõYýÿ;ðžÁR¦y¢@X¬ŒùT.fLçz6XûƒÅò°î‡»näÞ…ƒ;ïN©~À4`° ØêÇu.ÞÛ*(ó"Ë uJF‘d³d*JÔ ´³f-^0_ŒŸd=o”Ój`Õ±ÊÚ,‡T1N˦Ló”5w½=¯‘§wv€®Ð \×Ú/èöŽ»þ®FÑæ!ÜßGLJpº^+õµÇ<`㳋Þ<£çÙøA'«A:q eòeÊEyÑrR©bAÞfÍÛ”è”íRA˜M¬*VQÉJ$Òˆ“ºÀôµõÆ}wÍÑx>Ä}#åÖ°$Z‰µg®Ì–L'ަןÍVý`w¹÷ánÞ‡A7d°Xx¬Õc¹ .&OÖã˲:”ã¤Ë«Ü6i¥ÍšS”·yã&m´Ò¢šµÒYa¶ˆ¿ÐF5%äéÖioŒxW õ¬æs!NånÀÁ“ëµ±0«ùpí÷‹ãº,ÿ*<Þ…£]p¯Ô `° Øì4Û Ì;™‹IÈÃ)G±!ÉäÉ”)•©h¥ÍJµa½Ìõ²U± £UÇ.aæšÈÇrça¼1¼ÿ}ïÃ#XßoýË™þüÏ?þéÿÿùÿp°nÿè>þ·»ß‡Çoözæ²Þ³;°Vo O¯xââÓ:pÒI¶$Ù4™Å,µ ­„Ñ´3v+mÝ$œc±vΉUe¬A²ŒS Ì61pÀGë¸ÒÆÕõ¼ÚØVˆÃc–Ú°Ó¦;›9«Ùq÷Ýb3Ý¢cÏõ|ïá8:¸a8tï™oØz¬ÏF<ï"•G¾Bvzá/ Ò*U*9)ѱœ\!kÞ&훸ÙÈÄ«–ãÜÈd‡DQÅ+‘™Ã<Á6¶R‰à‡>ò+ð>ä1€alàKôß3+¹±šëõøô7»õæ[ïðýÑím¦î½òúG=qYØØzLß§ç=/~NΟâí㤲ärT²¼L›/»¶n»ãXµ”“KÙf›D…d1J4•™F8‡˜Ö¶Ö±àŠºgu] ¤<9ö°aïYÛë«Ypl‚Ñvº}÷øà»wÇÞd× Â¡ËìÀæÀÎ}Óg÷¾ñvúÝ)3¨$IgÈä(樥i9f=ž‰œ}š²ÙxÅt욈7H”H³‰m"RàœÊÝ{‘ÀûðÖË—ÁŸþéø“?ø—:w IDAT)þïÿã_Nþ—?Û˜ë·Ä(áŧ}r¦$ 9AÒ¡–§” §cÆ*IǺ‰Çoíx3™¬‹Bªe¦ÚäJd³A¼‰c"҂Ģ(ýž‚r­)ìÔSÊ=ø°C»xÊôgÂs˜+w䪞»:¿Ýù¯áýa;ßÝ«í`¯§[–kvkæ{ÆšõÙõ4 àBÏ›8Ï>Ó©$Ù$•Ÿ%eÇL$êŽ}cÇ;1§O—¬´Ù’é:•F˜lëD ëdãKžÖZkm¼ ¼«êfí‡³ãøˆrÙGVpÏ~Áa懃ƒ7=Ž£p°ñŽî/Vƒã¦ïû£-ó ›» ËSäë?NÀ„8d YIÒ!“¤˜¤êвŽá¤>JÆ?Ž9íx²ffâÅX¼E¶B6%+*‘ÃÌ@êñº¨Rúê}>ä)âðhÁã@ÈãÑðG¬‡ê08èž»pýAö7Á½ë÷öƒ`ûÝÞë-Ymح٘ûìéÆè_”;ãÂZ‡²M:I6I9A#Î+eöM›ÈM#Wå¶dÚd ì$ É0,ƒ¸Æ<€á“ eFNñç*ùj.¼h2˜E÷ûåݸ«–£m4]°š³›±[1VÌ`|žüPÌ;;@ËI›¬EɦnÑf+m%?³m#Õ´r5Q°j‰DƒR‰b.ÊUU1(BRZ§¢(ËuIÙ3éaꌔ“*$Ä¢7Ã뺸‹p¤,¢‡½ºß­Ö«‡hùÝ4ZÌÙÌ8̘{ñÖçUÖáÛ“ëÜÉ2‚Ò©ÜÙT-š†¸‘V®hÅnÍDÇ(}j²é¬Ù4òUJU¨E™,I ™?¥+•Q*®¯Ë@ŸOÅó): Ò"ôLÝÅ_ÌÝó&‹hàëþ\=ìýÁ¦ÎûGw²d±`Ùg=g¤½ŸÛ ùe‚†u¾1¦U‹¬M3þXîŽï˜ñŽ‘l[™ºÌg“Åäç”Ësa¦¦³1¬SäKQTÐÚü‘ì´þ° ÖHþ©Å)µDùF”n0ÿà³µÕ&ùO¢è‹(jAFë\¥ßÓÆ®B¨¼¬œ9mȽ!&è•#iü¾g¼Ô½÷Óèçþäç FŒ†Üoù†7~¨íÛ«¬Ÿj ç e'Ÿd¨ :‚O?ɉÆ'TÚ"ù¹¿%éT¨Ö)—‰ÝÁïkÝ„L–N?è@gÊõü î-ì |Ëè£'B~-Å_éÕXVô&|½ÖÉè‡.¯ø&â5ôaÂãàóç ,OÈIH r‚² )ø>¢^¥?ñß|– Þ¢\%S×âã ø ä!E%­å{ÚØõÆøL€§ÑØV½A/ kˆ§û÷º?ãõTÿ_áþ+¾22šòUÄ__”»'©ñ¥ïøie^¯,¸Ü>A¼Jˆb‹Ê­(Þ ãwàó,/?¢Tƾ ‚ßÓºé(ªœÒï®Ðç@°þð¿þÿô¿ÿoÏéù0ª¼u¸þù|Že` +xÀŸ1Ór²3Æ#+w9¨áä¸ß³ü·Ëa@/¤#˜Áöb·«º POm,)ÈCêФ*$›dê4oi¦S QuJEnrªYŒªY*» 7PUªâFù·ÈÓxÏg"囿ðÑ7Ã)ºGs<¦¿ÑÃÅÌÕp6VCv=v_3™ð˜^¤oëQžQd ójáRŠDTƒ\R…z2u›xa´ ´3Q½¤ª1²‰³¸¹CP}ó³^ß?Ÿ£,k|.wSÔ„ÇkÚå~~Fº?=¬cÖ}˜m¸ƒo°@=|;ºåIú™…,¡IòM² ŠU*£aTJñ’hø8vjºlaVÎ}6çí7¦™ð:¤x¾K©ß ‚ÛëW|,8ïÅÛFW†ÁjÎlÌtÀ×GÿK&½pù –=õ7nð•ŽÓˆuÈ>ÄÞx‹DòË;™õ3…jÃKh¦©–i”©6°þSStŠF3/«Y#vCô3a”±òJ#‘CJ0]$ZÅåêŠzGʽ”kØJ91Œ/ñû¬f<|ËÃLý‚õ½^ôÂÕ½šL£/‰îuômȲ=rtqýG=Šw%.¶ ä‘(ÙÄs$sd²3Ô³I¶n§ÍÛ¤ñiÁhXv¸SˆÓ0¬2N.´ZÚNàHDb`…ÚÒ:þÖãªêý/_†qÊ_ÃÏc‹±_ËÍ‚åÒ;ÎVº¿ØNC¼~týð!˜ïü®>U0õï8¸xGöêMŽFx‘Cöd=>µ±dm’e²EòYÊ)Ñ0’-‘I’²ãÈvÊêÄãX\ÖmYñ"N.0šÄ$Ö x …iû-{ùx$m:Ň¹°C-Ù¬±V+½Yl£ÉšÁn»? qu îwì÷C¯Çqìë…ÇæÈÁewd«p ý”çDò,¤!A"M"O*K1ËmÖj‘­ÅÒFÛ‘í¤l¤í:vÁŽËf̾Åɇf[Ûqb`œ„|–ÂŽtì­ü +ð®ëz~cî™ù¸èžæ€é-¤;×»åV}ä»ãjíÝ wöÑWj6¥·e°æõ–áÅcÊeÙ;3íØ9G#‡dšt’B‚ª#Ú2~‹SMÇ;óÊI~bñÒ P%U'Y$^TêEÖÀÑ:ûÔÀ®«Ê>ôy§dzjKèŸ8¼å?ˆý*ð.ãüê0Z_oÃî^}çîèolo{œ"ó7Û«Þq0XÛ… 8 œ$å• ËìˆÄ­é¤±DÛJ6XGŠOR”Z¤*$òZ¶ƒàå)GCëÄI˜Â{wZ_÷•»óF„Lo*K½_ºjzßÃãÄ únðå&üÛp<£¿e´eºc Ÿ_ñ¶?(w⚀üÉSgO‘L’MPIð¶Bºœ':V¢•H¶LãÔ3¤¤«¤ZQô2Š*§lêB0ã½{¹~Ì+Áºž¿çsr¦„€‡ Or#\áHË@Ï}ñ¥¿ü>î£ÞZ=l¢/£ùþŠÑ‚ù‚¿ ò¸¥|wÑÉžTP—»5(€#‰Å($(Ø”-ZÒ|}k[™–™n›¹¦™øm!^f(4ÉUH畼 ÃN9ZgŽêíáÓU˜òa>/ >:ÄE†®´¿Ž¢y B¾ëh¸ ¿š©¯öî·ô L—Œöô4C]ìa ð„÷dŒÊCB³HÄHÙl^ÙòVد„U*šé¶‘iY¹–4>ƒfŽÚ+òâ¥H}EuHœ {—3€ë{ʇZî¼7P|Bð#+üZù Ÿ™o|ºƒp¼‹;Õ]©oÝñ/éÏ/˜-éFô.Xí/XqÁÝOô=Ep l›dŒœMɦnÈa·Ë-+Û±r #þñʦT#W#W$^ ÂßÑ:B]ðNÙµÜ=3‚%¥”RžÿY\ÿB?¨£Î7h­Qbgˆ j­ôB‹¡4þJÏ—ú~¡¿éï¶ÞWz8a8e2b²àµæî.FPÁÛ+¢ž$½OýÌ‘ÄIIAr+i#?Ft2×…–,µÈÜÂç}L¹B.¯­v|9Hk¢Ì[5äÚÉ>`Ô=RMù½V+Å̰þJ†z²Õƒý…þn=û· ¦Œ'̦t]î ÓÇ÷¿Gà©÷yñQ'ˆIAZR”Ô!Ç¥ŠÈ·E±%K-ÌÏ•:å å¶üÞÙXžT*ï«Ø•¸èü錑s¹Ó¥-³Új=U|'åßêùJ7º¿à~®¾ ç]úS^ÏxÁkèò8‚:ñ§'!o{ñžr¡²G’ä$eIq‹üDŠbU4~"+m‘z ŸÆ¨×)W)I•Âè ¥:S*§Tê] ]÷£"X?ýéo§R 5«Õæúú›þ½Í®+XÁØ2ÿO– ¦+F3ãà/“׌ûÌÌGÜù|¶”Ï`ý¶¬’·¯eò"«7ÖTá·á#ƒr‰bƒjzû§ð2G£L£D³éŸ(uEÈ„a]kû-ÞÕ¢òLP·â”i?±¬‡;`¶f²`8á~üROF » ¾a¸â[¨Ï/žð¼·ù?De! 9(Cnà•¤Ñ¢õ‚ZÜ-âs›V™z‰Z\!T¿«õ퉸AÝçñν~´çp,k;XÃÜ0¾’»oèÏOéõ×ÇÍ£“>Ë>wþZ?²öåÛ!øÑÛÀ{'G£(@Úð´Rë”ëܾ ñ;ð2O½B­@9¯c­0üÊÓº†Åw ÇWà] Ö[0 ÖkPJ¿~Ý{õªyý;ý{9R¥\œöÆ/eøšÕšù‚ù˜ÑX}.ûÌûŒ-Æú;¥îQC¢‰b¥ØE^„¯•¼ï4³'UoRç6V‡´“´;TK´Š8#^¦hD#+«)™)éð$%!sZfCU‰ \ „Oj-á:øüP¡a,À…-¬-ëWøC&Æ#¦C^o÷÷̇,ûzÓS‹±þ…о&k½Pl‡?"PƒÏw —m¬™3koÁ¤\ \¦V¢ó ûsS´ ¢™õ´,eµø\è–¤(ŒR ^`ˆã e'Ô!ñÄ»ªÞëùÀÊÝAÊÇͳBÌLãoØ®X,™Oy}}å/Ìû¬zѦ¯{ý=ª‡ê*5Qì#¢N íÊ7×óá•;ß0&¦y†Õ0üèï‚`ýÝŸË]„ÿè¹?‚êIyr¦ì…X[æ—V,gÌz,FêÁßXØõÕ¡ïÏVák|…;QáÒgçãzø¡ÏQ?š[.)^<Ê…Ô !)f(卿èTI~fÈvF6RF-iVÓ¾1õmŒ¢iÂØ²«a䉉Y3ÂÔFìM¦æeG» {?€¶â”꼕rdª×ìÖl¬&,Fîßú›ÛÞüÝ z‚{‚!þT…Ó#[Ï#8âEÞÿ‚B]¶±“—)hCªq y*9Y*EÌ—†ì¤ÍÏKFÕ±²Yƒ-]Q±œ²Š¡‘ÅKœW™ SëÈ÷„¹^Q÷!ÃXžËÝÄ2¾æ°b³b=e5Ò£µ÷ ×#f¿Œ=º ïtØÃã/½ö9ø¸|ï±Ü=¡.úA¹;YÓOÑ-í åÕ­ É[Ä­#›£ž2kI+û‘¥omЦ‘Óv>0jS€–ÆŠ0´SWÔ}ÀåÎ=Þ·–ñ+±±š±ž°G¯ƒíÍPíÞ¡”ÿ«^þ'Ï”`]î"|F_×;Ï¤àšæ½ gl§l†bÿÀtæ ½ýÐsî±wØß«ï×|»f²g~`¢Å(»‹Qï$6_ó¤ éóX»lSJQKòi–F•ø Ûi& Ç©ÅdÛÑéh’®(á+­3ƒ˜ÖŽÖö‡²qózþŸ·{ZŠg£ÿ›½7‰•lÝòú~»ï÷Ž>Nœ“ݽ¯s]ØØU¢«‡€ÅÀ.¹$,Y²°°<+ϬòÜO,l¡‚¢&–…°„ Éà‚ÂïUÕ{÷¾Ìšçñ}’ÜÅéë|½âMÌ}Ä2äMIJ9ê¡¢®êÞqåy‡eƒ #ÃDdh2±¹±xa1œ`~Ks¾ëš3M½Ñšñ´1_a0zè^U¿¨ªY ¡šÆh.yêŸüSwiŒ „Šü¥Pl‰÷ÄÂ¥|QÞ¥Ñmzøa˜¾M¢·õ›€Û˜EÄ:d³„û®ÝåïßÙ}ªm"ÕiÕ¶;›ç7ÖKQaš7†õÂP¾íÔö+ÌæÓ«…ë²¼éb­¦Q.íîg`%G¨ „Šü#¢%Ñ–h%Æ?n»tžGir›¤oãû/›7÷«MÌ¢aÓÍÙÿáPüW?ÙŸxQþtûH§ÂË!W”7Bå“ûd[²é¢^ÉäwTqyÏóäŽxA¸n‚}Zø;â-ÅžÂ',•)ñ{(êt…×R Æ0è© u¦*3‘ƒôB’ž©úwtíJ6\Ûâ¹ÃÄc énãöJ{Èßož¤g7)õ™2E8“øª`Á x‘©Ä3‰W"3çFè=“fß‘ú3QüLctÝ ' x.Æ (Z~e0Üo`—¨×Oói¡îʤ…ƒ$ÞQûT;ê•X!ì—õ2¬æa}»Kw½s¿e±a³a·á!ãæp–íZœñyÏ OzoÐx.3“x!òJ¦7Å}&y×â`&ö¯Dñ{ýæê9Ã!ýŽWÖßkšI+Ç£, ~5] ïkw5Ô’´ÙPû”o…ú­”¾®×QµëûCu·-~oÍÜ/Ù­Ùø¼C…£3/¨“tæ\¼–úiµ$<‘‘ÄLâß—™987¢{#ögâ`*¯fãf8ãúšAm\?׬QUƒgä]ì >%ø~¬Q $qAPí©×T )ü~}T‡úÁ/nw髇VVK^ÜuòÏó Ð÷ÓσŒN°å Œ$&"7/En,¾ç]Ö¿¹G–W‚Ð,áŽüÀ¶a ˜£¬æaÝ7û[–;Ö‡üoH—äKÊÕ‚]Âa2Æëkv=Vc›)Œ`(TòXÿdÐü°€Z–—wš”·JùìCv>ë ëU³XG÷ÕfÕ,_×Û/špÞÜ¥¼i¸oXÕl‚†¢÷¡Îi•§žÒf“9å{peÓ111à] â G¸î‹¯†â3·öƵð9Âa€è!Øyþ DÒcÙœ©ð.›íOi’m †¸•àIÒ)¿e¾f³c½a5/nãíªÙΛý¼9Ü7ËûæËŒ·5ó†Mß<ÁëÅÙòétÎnñ,¸‚^'bxc›ë—ŒGL\ Q_ªÂÍ@¸î W®81›ÞuÅA!ôœ¢|Ö4jûUãw ¯ºìŸ>-쾄»`' ?Ã-»ÛÍëû`^mìæ?oÂÛz»çuÍëš×ìͯ¼+:Î:žÔù¶ :ÃnàFÆÒ1ñrÊä¥ <÷„ëž8ó„‰-Œ­RùÂqŒ8ipŠâ¦-¶ !¹´»OöÅD÷Àv’ôZÊîÙl}6[ÖËf¾Ù¼®oÞ÷M0oî2Þ4Ü6¬jö ›æ¸ò,Ï–Oœ.ž¯ÛÛ9ëÁ>ƒg#›Þ˜ÑˆÉYïZ^¸â¿3®,Ë`^~˜ùÕmÆ]Á¼`S°Ïñëc¸Ȧ•½§W«w;m§ËÚœÂK›^Q©ÇÌe8¤g–|í*3K{åŠc§V>G  PzÈVQÝ4 È ã6¹Œ±O«êNç¨#vWÄ ñßgõÀnÉî!^”þª UôPÄ÷E°¨ÿ¿”»‚Uή`_|%ÿé};M 0;Wž1\ ô-†}^L¹r¹î¡Ý¨Òµ«ÌlùÊR':ƒAcüꥇâ–ͬ®{mɵåÜ4Ê¥ä>ÁI– BÀñÐÊÒ[1_ø[üey¿8<¤þ¼ çe|_Æå2hÞ–<Üg¬²c»‹»ôªòCò…óugëϱ‚×cØcâqåróLП;Òµ£Ì,ej*c½²noPG¨#Ô^Q>o½+<±i4š jÿäVP…(]ˆPkEø‘|ököwå"<¬«Í—epWÄ÷E°¬_Ü, 69~Áºf¶|z?CýTxzÔÙ]à þÙœ½vèOEù™-?wµÏzÊXg0lÔ¨c”>Š×H^Q>oµ m-ÿ4æ¬üé¿×R[I+†ŠEa#ÕsâI´%\àÏ£u/‹d‘§Yö¼}¨î)›˜]Â!cÓíȃ÷®ðGf‡Ž 0º»¼Œ&W=Æ3‹gÖLVg¦63ô©nLUõŨ֟c1úè.š[”¯ÀµÀµ>¼\rË?™§‘¤Ãy0™$Ü‹ù–( ÞsXþòu­Ëx‘'ó,»OÓy¾›Û„/¶1‡„mÅ®»I9qõÕ P·S€¶Ø}(ãZ lž¹|î0ê Úµ®ÎL}¦S]+BÜX׸ÏÐ=t·Ge5mùÁ9JÓè§Œ¼‹¡ë§ƒŸ"A( oן¢¸”Ê%IH| Ú­„à>Û„þë,~ÈÓ‡4Ÿ§þªºMyHY%lcVñq’ëŽßá}¾§ƒîÝõ z6#‹©ÅµÉÔôŸsõ™¡_iúXÓ&Ze½Àœ` Ð=ŒqQ¿jåxj…Ò4FÓtvPùå•~O-Iá1Aˆ¡ÙÉÅ—ÄÑžh#D÷õ~¯‹xYÄ‹<úAÌó‡ˆû”EÂ&a³ÏØÁ‚÷°ûû«ŠÖ‡Lï }¸VX l&×3 {ª(צ63¬ç†õL§7iÌ+Œ!FÃEuËêEÓX F~¬:åqõµÐï>m€%…ÿ·öú®ƒM¾Î³UVÌ“b•÷¡¿)o~¼c°ð#V Û.Ñ¥Ý'|ðÕžX)v·p 'à*x×/ ž© ú¢6S™jM{*ÛcYMšá œ¶‹íÔò¤ª®;§:=­½ÇIvé)Ÿpï$QíJñ-YL~ Û“­Iõö!¹OóeZÌãâ!ÊæÉ"h"–«Öäµ` »N–’|Èгl úݱ̃žˆ«µQ3Ï-z3E¿ÖÌ+Åž*öXÖÇjã]ãŽñÆxƒÆè—õË6–ô­®ÝGÞe%ð T]ýNž,½Š< ;mI—bö&ßdÙ*KßDùÛ ¼wÛê!b²Ù8l Þžµ»wöçíît‘ç‚ÙÚà x žÎHc¢ñLcf`Nã™æ}®ÙÅžÈÂ`„3Áâô°L»¨þH+b=C«*çñ»º`÷Oaÿt®…LWb¹%Ý“¬ÈÖ¤ó&Xe›"_¤ù")æQvÝ-ÊyÄ2`àøñqζDª´“μïãz2ѰÏöî=êŒM&3•~_Ô¯5s¦šWŠ=–í†Ð¿Áç¬e—⋦´*ˆ£ª¼'>®Áœý´Öÿó¿ÿàúßþþ69òy÷gZ¼ììÕò^.^kÕ†–Û®D_b$s%ñ=…Q_0®d{&ºS©7¼±(]zS&SFC\§T_4nj̽¨“¬¾@¨ý4v¤@ ¥"¿¥J¨T>Õ–r%äÍίÖiùå¾¾÷«¹-æ>KŸÍžýŽ`ÏCÌ[ž÷ü©ÔûñdmOqÀ[¤'3˜H\K¼ð¢÷mÙ™IÞDì{¤6£)ýý>žË`Pˆß¯ãhy£WUïñÛºì>?î•çÓª« ’Å¥Ðì)ÖT;ªËã19 IDATµPÞ®«MZ-“zÖ‡ðGÛ…_/¬÷ìöì·>‹š%Ìa÷¸×OéPïp¡Ü»d†òQŽ÷Lbj`M%óJr¯¤Á3qt#J£ý)ý½žS[£JxÞ1©Œ £,‡O()—v÷ÑÏÚR%‰{‘-UHåSí)n…ìm³ ªUR-ãzÔ~¶ŒV~óvËÊýŽ`Ç6=*@wgFÅÓv÷p—Áíæ¬#àHôe^È<—y.áEk&YW’;½‰ÐJÒõ„é ½ž‡kUêMÝ\usÖ(·ªÎô{õ' ýì ~ô£?š¦ñ¼Á×ü·ÿ1ÿ ÃO<…PJÇJ±Ï¸P×ðL ×cø¼)ý1£ÞH'CÆcF}†.W^©½lškŽ=˜i9x²‚ºœÉ>G#IZ¡Ó6­Ä|)í7¬c– ŸÅîðz»Ü±Þ±]ã¯ Öø{na·°}O–rÊŒ=-Î!”Ù)òú0‚Y«Uѱ&8WxWܼd­†ryº‘–Ëò²eAµÑŸbóZ —l–!‹‹}³ØÛt±ãí»5‡%á–EÎ,:ÝqKIyŸNÎS%u\(³óþ nà™ˆ×Ǻ»¢7a8b0D1äêŠqŸ¡Kßjœ^Y à×à¤åðhuÚ}^žO䑤ƒ(®;ÃÖÔ%ºå­ÏâØîŠå~¹oV;6[vkvoÙ쎾-'ü?]A5*¼–#lq¡NR†ïXW8S¼ ƒ Ã!½‘ÌtÄxÈÍ„±GÏ*¤ïtä=¬º1órúä›ùôOŒX€u{û¦ß?ž¡Ÿ?ñ5ÿíûðY'ŒšÂLÀópFxC&#^LöyÚcÖ¦.›‘! ÌRú áô<0óꪮ§²K:Þ'œZYJ{å€/ñVŠæø!ÛNœ²Y†ûh¹a»hÖoˆæÄófq sŽ íCÃî=&ÊW]á™Å ÜÀ5 uì!ÞþQŸIŸÑH•^Ž…+—©ËØFFiÞ L<aVRΞD16P\ a;A:ðt€½XoääÕžåŽÍŽÍºÜmwûj»iü%‡Á-û»æ®â–Í1z!hŽ÷wéW‡ ËjoÇØÑ͵ÕF‰ {8#zC†}Æ}&ÖHçj Ìz¼01éÙ•ô a Cœºqãrú¤Ýe—ªûD¦õ²·‚+vR¾–‚»­ÏzÛܾ ÷ÑvË~ÝøKÂÑ¢ ×ÜUü>,vE ÉS9ÞIŸRç\mun®­y&âöð&L¯õ™öö$ñªÇ´wœ³c£Oëæ3BÁ;«Uå<^ õÏ~áýá¯AÎ^Í×úü—ÿ±õ?þÚgÒĔdž4ÒD×mÔò¥ì¡ô+ÆYíœTQí¬lª‹9ÅGŽœRQô[*åqŒ5RÞÆ!ë5»5þ:Žüý¶ 6u¸ªâe.J^¾I›EŪd[r( KÂúè|È\î4ÆZ=TkgОƆ0†±‹ÛÇóºL\¦^O“&Ž8µåç®|cJ}cŒ¡·Ø½yÌÛ®Ü3/ÍA[x"¶ƒÓc6aä2q˜Z‚:¶Å+WšÚÒÄFš25kõs”1rÙEr¬¬šuå,_ÚݧsPl/Òãq±Ù*å˜CÈဿÃß–Á&8¤ûyµ¿«’e•Ì«tUÎóæ¡dY±)Ùls¢ÎD#;[|~PwܪÝÍ®×µ¨Ý3°=\¾ËÈåyÑP“¦žxeIKëòHã ‘'¨Wm»«…^Q º!+H)]òÔùÔ9Xò/ü§Úóó-1½B.õ²ÙþˆŸVvWœôž4TïÄlC‡D>Ñ–h¦þî.MÖeº*òe‘/²d›=Í"g±ˆñ¢”Cý¨¿K»¯ûN79ç ôÏÀS ËÆµè[¼ò¸2è[Š21å©¡Ntu¢iCEíé¢ýcŠÞCsѬZîWŒAk£‰”¢QŸ\_ ï£`a'»Ë:׌DÈ9½%‰D{Âu‘n“ I¶E².£/Ó|‘ç«l“”óœUÆ&c—¤ì“G²ô©™aýÞ SÞ‰sž„iâÚxC‹±Á•)ŒÆ¦|e(SCkêHÕªl÷}„>š¢;¨V%Žëcè1L=G~T·Ð uáã*¼X¢SÖ'ÄÔ±RÍI"¢E¸m¢ušîÃ]¯Ët]fË"_äÁ"}ˆ«¶ÝíRüŒ0%Ê9tË«ìC!ŒÂSÏjëÜÆ:N×î†&WSCÔ†<5´–6Óµ¡ªõtÁ˜ ÐèšnÍ‹îì©€\"¿{ásiw?««iœº¾º¼Åð͈bU7€rȨr­þ>Ùž|Kº$½­ãïgû8»#KñšâÇT_P¼æmÆ?¥»Åë´ §|ƒâ+.SN¦š­Wï£z"k‹+—*/UÁž¨|®ò¹Êg ?¯63µ±ÇðnZOièUÕ4+žØ…õqï>;%T+†Ji2Mø¡PìȶdÒÙm¿MWqðûäo(^S~Aõ#v[¾lx oáG]zÕùeJ»‚:Ÿ&ÂÓ\aíÌÀ¥–{*=±Îsï¼R¹²%ñ¥Æ·5>Sx)ó\n®ÌÆù žÃu›#Ú4ƒ,ûÖÓŸ§Ëû˜Ÿú¬ðÚ•ÑJõZ*^“mÈV¤÷do‹x/›ì–ü5ÙÿKùCò·Üæ|oà–°…Í™[ÐW©ÝÏQjG¿k=]û"žÎ@c¢3Óx®òJeöL>×ø\á•ÒòÌ롃ô žÃgp^U]çÅèrV¼¬Ëó 4‘3 Tû‹*YØÕ–2¦:Pî)wMµ©â„îÚdÅë ^Åõ2Ìöá:Í×›€]Àá@¸g¿cÓE”<Ùlïé¡N&dN×MLSÆ‘ñd2#‰—2S[RDz1•Œ±hDg(:=Å4¡?ft…ëâØ8f!_ç¢ÓÉñL°êÚªSóòš?ÂGΗD”4µ"ÞS%”!ÅšrG¹©Ê=Á¾ÚfÕ&«VI½ŠëÛýöpXǬCv~@àû„1ˆyw?õ%¯Î²]O…gvaꘖŒ+Ó—ÉL$f"=K2ž+ÖdN${(8}ÉqtÙà ñúô=ú^©]•ŠsR·‹ªòšT½¼å¯êʳvw, ±I%æT1eHåSîšâ®Š¢æ°¯6yµNêeR¯¢jøI|{h–þ±ÝÅ>QÀ¾`ÛŽ~ŽÝß1!;m@-ÐNOÆ“* dÆS‰+EÔ‡’>‘Œ‰dM¤Á3Ééɦéâq{xŽƒcÕF¿oœ“•heÑ»>ÆÖoý–õgÿlÔþú?Pÿæßt~íןÿù øíßÖÿîßµþâ_ô_¾¼,¾¿ÖGQ!ê"\°£^ áN:ìØ¤¬cÖ‹ Yû‡äpV÷룎7Ü‘l9Ä,›£`oyF–ŸNÞâSg¹v³mÁø\»}Š1Æš0¼¡?¦ï –9`0`Чïѳ陕3ª¤Vþé<ÚA•Óô}òÓE‘÷Ñͳ\QÚ¬8Ítê-A) Þ¬#V!ËCîû›,YØúì÷lç„kâ=ëê¸8 ·,¨ò©’ü} ¥CN'ÔK˜ÁT O°ÆØcÜÞ€éÀTzCú—žU;½R!ºíÖ³aMc•÷Ô¥™}d$…’´v-sÖ$±nØ%l–?Þ4+ßÏë°ÞØùv;â-›‹ú(¾ó»èôô¬ã}•ðS; Å;Y·Œ×&ösŠ5>j¶z}z–!ycÆ#¦#ú6žY™£JiožÝSŒmYN>ÃxÙ€þ[°~ó7í¿ñ7Ü`ý‹¡þÎïh¿ñ›¿ý·íº&M…ÕJúߨüÕ¿êþʯ$ßþöÅáç§ÒYºp¨BØÀ†4SÂ9~Ì>f²;°Ù%þj$û=‡-á†xM²$ݰÉxàèõ~¨Kù\|Jв:‹9¯Kw™8Æ€á3¼>½‘-نǴÇÈalsí0² s\Hýn)Þ’Õýª´/oöc~D1“¤Ý™‚¡ÕCí…$”×sö1»ˆí­ßì·A¶Û‡Õ~Çê–hM²"]3¯¤|ý¡l׿=ƒÔ±HÚ}€Ó ÄG0¡Œ1Àà ð\_1réë¦Ôï3v;ŒLFfí¹•}UˆƒÎÔÀ³ize9¸àõþ©;w™{ª@Œ)Ú² YìÙúl÷E¸Ù¦ñ~ÏaO°!\qxMºf]°à˜(¼?ó‚:9ÃÖO© ­ˆA펎ڙmP¿µnplŒög@¯Ç ÇО+MFLÆ6C“^9ƒZójÚHõaÛîªjP——¥û`}èùá•ï}¯øc,kûOþ‰ö ¿âO¤¿õ[Ö~/þå¿ì?÷sù~ ^ÖO˜|Ah¥(ácÉ 9Û ñ æ±^áï²läqè×Ñ®Š6Mº®³uÜU~P-êfU³©ñ+QE\‘ÔD'ÊW1+•.bsxÅx=ÝÅt±]\—¾ÃÀfdˆ}Ý–žõű)ŽMq¨I­q\Q·qˆÜGž"ÙHfYOôDxµQµtiÉÜ’åmGãmeP{ꀤQ²Vø„|ü}œ¬ÖAí«h×$›:]×ÙªÎWµŸVus[±«ð+‚Џ&­H›ã2 ûÐ2@<]íÖÓî,¡à)ØÜŽ‹ç0°ZŒTUw]al‹W–tc‹Mð\Á1D©4@ê!9H²WT³\N"ÐvÙÚ4•xY|£KÞUu`½Žäx-„ALá8ìëhV»àPÖe0¯“M­ë|U§ûjUÕ‹šMͺbSU$i}ä*¼sPäì”(w\ÏáÙ ªCÓÂô0]††=†6#]ô4[ÙÂÈǦ8ÒÅ¡&MMÔ± H’h7¢[ÖãüÝv'4t¹Îû8†ì^uíÖuï£X-fúÍß¼ìþu€TÕ5—&&oÔüVH÷Dþ‚hC¼ÈªEEÉšdI6'»'ý}Ê;öwððÔYÎç1«ü_â Ýmjg²aËç±,, Ϥg12˜š|Ç”ú¦)\\ë\k\«\)ÕÈ£'#Oá3h—.ØEñ¬¨µ§³»ûEsyíßøæ)„3ÉB›%\B^ªñÄ!±O¼'ÚVÑë$_Ä»*Y’.Èæä÷÷”÷̾€EGæõ»5ÀižU_ïzšgjG$wNñ¶cÑ3šLL¦:WªÔ7 ás›o™ÌT®Ôf¢ÖËê¸ä˜€]–7eå¾ûÝV—ªûHžF’|(ÏD  $¤¹šÿ˜$ ˆý6„±Êæq¹YßÕñœlNþ@~GyOºâ¾â^ÃýÓ誴«ºòé;Ï:žÚu<ó)–²tl‹QÅÈ`bp¥3Stedr£s£ó¹Îsµµk!MÚ ìVK N]ŠbòÞiåRxÅ#¥(žkÞˆ©S¥x#¦÷¹ô+µöK5ÀzçëÍF–Ki2©t½™Ï%Ç©}_ô¼ã˜ýGÿHÿ{ïÑØúþCã—9ùY}ÁŠr/аëd%K˜“X#­Þ|‘qŸs—«l^'y³Èؤl–AB’Tüñ¤Û0|ð…§—wN—²ÙšLáÌàŒtäkäç(7¨×è7X¯0ªQFë&ÞfÍ>æDDq@´%(Ó?ã3SÍ¢s4àé$kMðÛa¦Iè2†Œ¥àIx2#™g’8%u +#IIÚ@Ô¢á)VOìÉìc{Ø.¶…maé…rÕ¨rÞñÊ;¯ÔµÛÔ“Ão°Ý=É[„‚¦¢Bï)Sʘ2¢ (U½*ó}yV»¢Þæõ6«×I½I¢(|(â]Â>æFÄ!iH”Ì!èèTéSöÂy»;q=[°c 2†rT»=™‘ÄXº¬Íu$iCQˆf_4<År$KêIæ€áÛÆ¶°ŒRÖºVŠzy”ÑØ-a½®¦Q/çÆoháTÝ»Tݧ¤©Å:“›9eúdβ«ò¨<4Åj[m³z›ws6Ù—á¦,ö1ˇ€(" I’äØîøow|þY¿©‘o»øßØœÿ—_ýÕðW5<ýö/ü…Ã'ÔVÎÈ!O~-’ëÚ¿ ^Ьi644· oštÓÜÓÜQÿ.üˆæKø’æÇ<¤G'ž;x ó36eòÞ&àý]²Ø¡(¹Ëu9n¶\žÀs‘kkðR®uÏásÏþ=oÃ3‘©ˆz /á7Ûeù2ÏŸ7~ðàÒV¾!uVÍã§A–Öªò4>ÍŠæ5Í}Ó¼nª;6EsGsKó¾¤ù'ðÁŠ· ¯á`Ùåü§¬:;(<éngjP¹Sä` 8®À@`,0ø–À÷^ˆ‚9ø\à[ŸÃ+ðBàÚExÕY‘[Q^ž§,_™&|)¼o¬Ý½ÿ‹FbMûM@³¥YÑ,iî›æûM¼lhÞš×ÇvÇ—¬—ü¼éè «§r™°ó•z?GèìÞžÞÉlG /0˜ Ìž ¼xe ú·ÄcÇ{%ðž ܸ.Âwà;0ë\Í{IòGšFÉ¿êàRxËœmYš+Ò—4»®ðÚ9ûº‰öÍ[šß£y?¦ù|Aõ–‡Œ×ð~¯kwïÓÞɱ>gÀýç?ùÀ'÷oüúµü·þ–üã¬ÿâ/¦_Ï*I¾(†Ýzè”Av O PÒ%»„Uˆ³Ù’Ì÷ÿ”ÁÐÇŸ“ìÈvä[²Ûú膲‡ÍxzgŒ½y'wÇ¥–Ì래•ГQ{h}Œ>ÞŽ{äööÑzbÏaà0°˜9ôõÒ4¶Šj! c˜Equ$a]žàQ”ù×?~ꀨÂBŽ—2ö ›€Õ® ‡Æ?”Ñ! ô‰|â=É–ø|K½3Nç°è+ü ›§ÓKén3oè«6ÔEÀ°Q{è}ÌfÛc4``K}ÁSm—¾ËÀ¢oÒ7ð´Â»Â•zÅ£ö³½ÅÓËrÔ$Êå ,ï!ê¨'Ñ£Ø3 PÒ~ŠŸâ'ìCöa–õâÛ]ì“ìHwä[ò=«”eçbpè$Ÿçcì}ÖÝ)ïœüÔ^· †kµÖGïaö°<—žƒgJ#e,õ<†}“IOo\«4{X¸`ص;ŒªÔµIryçÅ#IQÜvZ™ø1²:+ý•àðSvûÿçþ¡ñý¸Úo9¬‰÷$;²=Å–ôp4YÜÀúŒ'óΜ}?öCêÒ«¬îsÒ¹À“Ñþ„õ³ °nnª¿ô—|`½þ7y Љ(º$¸s.É bä|+&>û€}@p ð‹l²²$Úï‰WÄ÷äŠ å ?eÅ#ŠZ½ÝìŒÐ~„§mÅèFšÕ¹9”€¡£9.v~צg10Š–£ØÂÈbl26xn2PKg@O@µj†õ#êƒQ–ÓºÖ¸H3¿ùÍv!IûÎ4ç„¢B꘤!FÉß%1aÄnÓ¶Q½ª]6-xJ·d›#‘<õY׬asæÊBø4[ã|÷)<“Ÿ´ VÇÅíƒ+£9h¦ƒeã8¸6³CU¶â¶Ug2ÒªM߬FžŒ0(&ÞÉW³È_\°ûÇðˆb$ŠÁ“—vž•1a£ä+!b˜ 8ÔÑ>ª7ûdùÄ;Ò-é–|C¾¦ÜîyÝyAnOô»ì=Ň\õN4ãtí®o :–‹íàØô,ú&U™j£Ö8ƒ‘ÎHc¨Ö=§v l©®KF‰†f]»e9ºÞÇ¡ö]Üç9|Ú9+E;)\Ä„!A@xȳ]È*LòØ'˜“¬É6äëcáùÙqÎ.:ûûó9[~E£tfÚbwíÎ>[X&š‹3Ävql\›¾E_¢å(ŽÐsóŸÿ„Õôé,Yn\·Tõ_Ak!…(FÝ [Þ]}Ä4yMŠTìåbNl‰öÄû¼\',Ó8M÷d² Ùù-å’jI²„U·ÖÞÁ¦Ãeç‰.ç,(ñLet¬ïLnUQ–‚f¢›X&}‡ÅÀ` 3’•±`hžÁDçJãZã¹Vœf ÓiX3n7YÚ6óìä—êov’%‚w2¨“ % ,ȳD©îHâ8 Ù×áCR¯Òj—øu¶%[“¯ÉW”+Š7äó£fÛVög(*úŠ]Ô;q.fç¦qÊÖpÀÑut ÓÄ2q <ƒ+›©.Œ£§šL4¦:•‰ÊXiFF}­c˜£ŠQÆ<°êºW×ìþL2¿›2ù™‰FBÙž7R¾$ŽHBâñ¾Î¶i³Ž²m´jÚÂ+V+Êå’bòâ5Ç%èû»¨ììÐHWx'G³êgóÌOƲíÎ6q úC¡&LDÓë9L5&:W ¥õÀ¢–^ñy×îŽ{вœT•w)¼ Ýµ©Aé&%kHQ«;!ÚHbŸx›W›„u§éŽäôþXxÕ’rIEǘîëuÿò]”ÔQeÌ.Óú¾»`ªh&†IßÃ5éôu†íœÅTSWW*c¥šM_Ó†5S¸jÊ÷'¼#þôÖá ~ÿû*ðð Ïf'Y‹büÈ©<¶•rÊš©Š”æ-YD’ùDwu±ÎYæÕºð«|C±¤\R.(¿ º£ZàÇÌ9ún:9ß;¬”s>çûvšF×VN0ÙCA×04l Wcj0Ô+L$é ÍrTf*3™™ÂK¥y¦7#•!˜Lk&зý<U׿åFïm(ñ™Êûßsšœ¼¦@i–R9' Éd>Ù®.V _äqT´ €v†-¨¨ç¤oXTÇž²~êeÐ^QO7 “§(J={[à#¢«:¦Š£ã©x#•—šp%¨CY•&*3…k…™ÌTn&Js£3‘&5W'bJ«µ*ËiY/Øý-¼sn÷ ¾çÔE["jõB±' É|²=Ù¦hVy³È“({  \R>P-¨æTsò-‹š[¸=Ãîa·ÚÊÏ|4š÷lðÄ3ì®vðýxt± LýØîz}•¡ÊX¦(cËŸkÌf2W2S¹ZŒ¡'!]Õ¼ì ϧ®Gyþ ¸HA¿Á» œ|UË®(òãœÍQYˆå–<"Z“íÈvuyœ³ù¶.6+ò×”wT êª9»Œy×îZÛ C§ÖzG¾Pa÷ó9{Ú»··É­î@W04 WgdÒk«Ne"JSA3ÝvÎ*|WåJn&j3Ô‚áÀ´f C˜¶Á Eq]U½½9ûé¬< ˆ"Aþ¾–þ¯ìaWI~Àº`]°ÎYçÕ6ÙÆá–d—×û ?%Lâ„4&òIÓÇ£|¶WÌžfkpÖGäÎNSkQðÙí°s×é+(C¤1òeŒ2DaÝ`ô1dOg$«Ì¦‹é`Zµ=*ä)(2˜Ù£J­i캵†J/?ÝßÀ£ªw‚àwerènÞ6Ô;‚ŠÒÆgS².Ø´…—Uût['«:Y¤µŸqH¢„4&‰ÉÒŒMóx{‡SY~Eîªî|¡ÝòQF0ð\¤1òyŒ:F¡ Ðú=ÉQ&º8Âì M Ã,•«Ju±½Ä( ª ðPšF«këˆæ.Ï×>ÆTõMw²í oÒ˜=ìýPxHYæ¬rVÛ,L“ É®Îw)~Ê&$ˆí.‹ÉcÂúx_|èöùÓ]ûWñQÚD—iG2h/ŽÛ Òõ3”êuˆ6@ïcÚŠÁX‡‚3ÅîaÚ˜6†‘KÏMAôâxw¬y¸ô€Ká}#¦½îî‹£.'msª=‡š=¢Ÿ »„MÁºd™q—~¶­“ É>¯÷)‡” %Œ9ø¤ yLš4 ÷¤ÃëÅ™Øïƒíî<Àª½á™pt²Ÿ@OEusv„yÇÿÅ IDAT>CŸ¡÷Ñ]ÑP\ƒ‘¤õ1û˜.–‹ë•òu¥Z )`djw”¦ÑëÚüiÌÙO`FÕŸûsðÛ¿­oÿÏÿÓÍÿ$„1qD‘¤EH±Ïɼñ™­\Ñ…| vDr£fNG®œÂXBé#õQú¨Ô>z£‡ÕÃu4K¢'ØŽƒma›Øz©Ok×ÂѨ±ó#ÈnyjÓ8UåÀE–òu?в„¨c>µ»g|š=YÖ¶)Ü Ë„MÆ.cŸ²Ó4ñ›ÈoâCVïü€8$‰È"²€""®»B½#ÿ¬ÏBïœÃÔŽ|ÛVÝù0ëɨ-d Ð{è=tÓÅ24‡±®p: ÇÄÖ eÖ˜2†€äätr£S•»u­_Üð¿vðT)ÊCWuqÜ×°£ ÚY$*)ܲ/ØåøM|H›–’wœ³!Y@º#Kð›'s¶»Šþ0]áÜmQ=ã*´ž‹#ŽLWFéu…78ªì –‡¥k6]êa{ØŽ…mâY¹ñS@ô »:&±µ‚QU^Óh_ÿœ•?é¢ù§ÿŒÿåŸ=n¡Ò§’òòCì6¹Óœï±O®ÐžˆÞ‚'ÍCwÑ[n¯ƒm }¡ïI}ÁµqM\OÇÕk»W™Î‘?…W‰éŽPU5¬kã’.üµ–µ¼„èŒ9ÞNœH˶½ÈéNAÊâ@—q†MæùÉw'ÚîÉÊ…Oœµ|AÇçM?4ÉN¯Z|j¤©ž”ä!àÈ]R‘=cŒî¡·ûMÛÆV4Ï’aÐc`ã¸:®VÃÆR±AS`PÐïªî8ÌÊrÜ4Íåùkz$)ÅàijP—XUD!BXËéŠ ÃÏRIs“xp«¨`I@’d>ÉŠò@âׅ׃[Ä“+ãsû1ùé‰Qï–dàŠ¨ö±ð4ÍÅìãö1lCtÇÅUL·Íg0[•9¨- LÑnp‹#—ÜëÚÝè¸t¿TÝמ2IZCÖÅiPÅÄ !â.•¢ AÎ!%Hðã&ˆ’* 8ì³8›¶ðÒY@~ ?PˆC6õàž¼§ÖjKýôæîd?v¡ÚUÅÉEõP=TÝÅp1m<O7\\SvÇÆ3ñÚ9«5–]z}PUðŠc=m+Œ²¸áckwÿ ëOý©ÿ¤®á_„’$Õõ×ýÝÜÝÉ­ŸûïüŽö%ìŸnäŽB~Ê>*MC±Ql¬†abZØ&Ž«¨=lG´¤‘ÃРä ”ÖWÄ[DV Ïäå&èU5¨*ï¸Ö¾‚ˆ¤n™·J¾’(%Lˆb¢°Jü°^ǧEd>ù|O±' ôÉ"öÍ‘}âŸmÎWPïÜŸã'ý,UÃî´s.X²b£Yh6†Ûö° \]tÓÃ24“¾I_gfÑWO¯ìÞÑ[Z3 Wµ Þ B•åä8É.…÷ṵVvWt槪‹©²öwrâ‹ñž0%N[¦8,òC„U~éôp¬º|OÙ~|üðQœ·¶­ü—nNíN?óѰa$ Èªj£[6¦…e0pè©Çv'z&=¾Þ¶»zàÔ} L±^ù(dzÀ®ªqUÙÇMÀeéþSow¹$ùg-Y·|Š "kZ4%¦‰œ/ SöaDÕI4‡?)£$jÒÑŠlOáSœ^P²ƒ>Õɼ<ëxç÷s/ƒsànunøª>DµÐÛ³°º9ëÉÚÏ4lz}ƒFO¥§Vv¯q`XàUÇëèӪ¨k§,‡Ÿ\»ûWXqßß¿=ýöõë7üÿGÊ×î\3VúOGÀïþ®zÿñ‹-ÒQuÕ@7Ñu,“ž£áiôd¹‡ÙtÅÖj ^ 䦧ծu܉ëFK¨¬Žßã•J‘¿lùr û“(ÝuÑÝÔ§ÇŸ÷¼iÛ‹˜§J~K“Æ$í•ð¡¨ü”]Æ.>”نܧØQî)·”[ª-ÕŽÜgQ=ޱÃÓ‹ãø=ïŒSC‘»If€÷t’µjÅ@3PutÃÀ2°tz#]è zÃVt†:C•Ê@a(×WVÓÓðÀ–{0¨Ž›¬v‘j6“ç×ǿąKþS|jI:œU]ÇØmANUˆ™r¹“òiJè“$Aû)»”]VÄù¡ÉdkòÅŽjK¹£ÞR툶qkð¡1vÒÊTgUwÎX°:J¦ÑØ-д²è]ÕÙ:®†§ =Á¸lÅmÛÊPa 0+ÏÅ ˜ úÝ$sÚ/\U£²\ÚÝ×€œD1ìºNÑÕBwb,Êv*±\ÎISÒ„$" ›dW›”mÖ쳸Ê}rÿÖ‹ Å=Õ–jKy`W‰{‡.æÜ ÿÐűøtOav%wj ¶íÎÄq0Ûªk ORú=tÙÕyav…'מÓô”£BF³`VÏŠîié^³º6~öÚݧwE¨ëÍ‹%àºõÿ=\ÁHBlyæ7ð ®á9| ¦0Ó€¸æQ…7·®ÆYöÙñë^”)ßð† Ñ´?è˜;¸…,ážfIXÝNð%¼…¸‡{š9Qv”ÝÝÂâ©TÔ-²§9ÖïCŸ¡¤ÎACívQö©¼5µAÁŸkÁM÷¹î>WíoOE9íŒ9Û¶âTÅçE1¾,Ÿ>‚9WiÚ—¾Ál» ¼Á-qDЕáîa¿·0§Ü²nXÀªÓ{®º ¼SÕ¥]Õò‚:-A¥÷44';ƒáo Ó¶˜ ¾¯àÜÀ f]»¶…÷Ý.]xØ‘Hí"ýÞ1½êÒî¾ÑG’"UýaרüÎss¸' X£Žýá¬ÝÝøÇª[v9µþÙJ:þÓ;º™ú½vw®;VŸ‚ø“AÛ¹&]$è@Fw½îEg}*<½í†W0…—'ùg™·,{ÿvÎÙO›ƒ5úϤWÿõPc ˆ}4ÍAw0Lt£Ö¼B™¡¶/õ´G?ÉUt›F½ü¨ÿTM{sÆçÏ&ÙžfK©L>‚_pÙUlKöwI}Èuî“úTAÎ!'Ή2˜8!ËÈSŠ”¢8~õä=VÊûiŒíž|¦Ri)ý3£¹vžõDäâùi„<@î£ôQz¨ª-ibÏdŠ2:2õt ÝD7*yTÊ:ä‚~vs¨tù¨X¹âiˆ4@½ùÿÙ{ï É®úLø9禾û óNÐH3£,!"I„eÖØ€‘ÍbïçµýÕ»\Håï§bm¼.Øý¼ŸC¹v \Î6`°± "È#-H"H ¬‰šý;¿ó ÏÖ ¬.¬ì»á`ÆÆ ¬3ÉpkÔêÜîFt]úÒ)ñ²|V6=K[¼Óoñ¶ËzàaZBž˜;,!¦ u+ «±a%ÆRŒåË¡„«Vá/FX 0 0 àðø>¡ÐË…ÞÕpT,x¡Dßm¥€A•n(³@€YFwÌ:Cš;{µYØMÃ!3fíÂéÀm¥µfl.0³ @`åß'Q/69o\°|8·,{Ëkko¹¨Gã®Ë¬Ï¼ÆX;=N× œÊM?·¬}ò§íÉ5l HV†Y“б¼Œµ«úVC¬X ¢Àï ¯ÑrŒ ½4x<„¢Â5D>F¢ØÜ–¤ðU×ÌsjäÉó”jŒ.hfFVfî:8-8MÔêFt\tk¤EÜêM´ÛhÔá:Ì™cvS‚$=¡ I¼Äq·9o¤AÝÓpŠcœ#Ó<,—•‘Ò µ¬€’bÞ„‰Æh@ú–B,úX ±ˆA0bIù¸7ˆØÀCÏGà!¥¬‹<Ä"ËbŒá"Ö"¬EX ±ècÙ }¿€Ñ€‡£@ Œ<øFøCD"ÑÌKÛo†Šnpå^±\„—™»$Ñ«Îÿh0š0º°`JÖ¥= -8 R³Ü&æ]Ò#n õê Ô]Ôkpk¡¹)õÅl RêѸ 9±xçRHHÏg–‡y0aèE‘ç!ðà0ZA8D4D,/lˆ L×ÁÕü>,*uö¢J’§«TAeÑ캣³ « ³³™Öö:4´Ôpœz Ò´¬D>#)ZqÐtXm†wêéË9¤ 4ãô¾+Õ ,Æ:ãÈ“6%§&QÒ§tMÖ øJ]œ\eBŸ\ù†¿‚AˆaˆA€A€¡'Fþ€¯0ð¸çùÂWdŸÂ¡l†‚ Á< ùX¯uTZÃXÉe§JßqK®*YóRR¸d¹0š0š0Z°»°»°›iuT­×…K ´ê´m5:h¸hº ëаcg^¸fÚgÔ€¦@3J©Å>Ý8žIË@uCè)3w‡ ñò#ªFcA_>ÇÜG0¼>]]à fú ñâÐa8İzž—/e´uáXA8Δ¦c_!ž^q¡Û½VªûLBì® ££³™š;« §…zNn®mÕѪ£éMâÖÑj ×LÍ3Ëë5Yʘ5 §¾ÙXÆE;Žçµ¹»à¬-[¢ÿò_–„!ÑçïÔ-u+†±o…Jë#“ò’ƒà‹‰q±îaYpØì‚8?N X²q«ÀR^A£PÕ«@Ê’U–R©I*›o7 ô¤tJÇm›€‹e À‚,A™怦 ²NáÍI¹Ÿ6Ðfá–8žK¿½€QÖ Mó@êÄcUV1-!™$!ðàKÀ.I¹ÃH î‡!1ˆÇãªÔÙA£üF5Pk]jdq!eakÊ©LÕ~XX5©ù¼¸Ø,ëQUÄéë€ÀEŠ~hÄþUéî_k¸œik‘ÒeéǯÊQg{S’Å‹5¥2jÆuO‡€ÃˆûèG€}ù9ÖE¶:±{q~l—AFš½S™Çµ¥¡«+~|G*kl6m$«Ú•æ[¤y«[ ]i {²~¯ 4ãàò´í=qÙu¨v°TÓ(Õ§o¸ë>%CYJ¢½8¾„OÕ0—eåû9r, ,r,s,‹`Ä—ÁVÀ!–úCŽLjÃãð9†#ˆñŠh6Ÿ0‡Ñ–±¨ºnЦ$«‚ºh› ³ 3 óÀÈ<ÈÈ,è&Ð9ШաXG1K1 Úƒ9 c´£Æ[™hKˆýì–z!ÂÐŒ9EÓÀ¶w)3¦û²w9­Ç ±$ÒÒ”%e†E†%E#û9_«Œ­€¯‚¯ ¬q 8–†ÖqD 1Gâü —B /éWPZg]à ë:²–¼e¸Hø–]fAæ@g@7€6mJç(æ)æ@fÒ”³Ñ‚ÑÑô«@Iʯˆ¨â¹…x$Kiœ4,k¿i”A¢%);°,¦ßÃ*p$­ 'Ë1–8Ez½Èq˜{kl||5©Íãr 8F}Ÿ!à9"†ˆ§Uä±ÄKs‰’8¶=5˜‘¶.kb°Û 3À<ÈF ó ³ ³ ³ =hË2°â"‚3 mÐh“™ ÚšzjðÕ¦ì¶6wÚÁÒ(Áqv20Hku³Õ‹­¦ËYROydÕÃ*Ç2Ç*à Ç*Ã*kñ2‹Öõr1Œ1dðbx1|/D!ŒňbÅmRûïÊ[Sé'wòûþžt›’5̵Aº 3 =YëS?Éè‚vat@;0]ËÀ¬MéÁlÃlÃjÂlÂtaºß*L' p™àÄಀW^’•Œ ÃÉ™¡yt|°íý”fYÜ¡ŒEf1ÎýÀ ¼0eÝZÒ©ÀÈZˆÃ ‹ ++ k +,òã>â5Ä+<^eÅð2âÅb„É%B#ŠÇ=Pªö}AE3 85JaΆ¬Jƹ´(ŒÐM¸—¸æs  0:)ñŒ5–Y=ƒô`¯ƒÕ‚ÙHˆ'ÌzÀ¶f%~ +².Ù>PḚu'禯ZÖ>iè [D\_‰Æ¬‚¬Ed5JÍÝ!†å«L¬±ˆ×82¬EHÖ…Ê%a]ÈŠ… …¬qa–KCîk²e¡©ôßu€¶#3w=Оä^F挌šc`ÆÄœ‰1:0;°š°º°›0Ý€]* 3£˜0HœîOU[gTSŽ&ÞÉY¼½”.)Ò=ËJw¦lS¬"rµT;Xgcl‰Ò@Ùðp%â§Mµ‚§BrWNÍ„û`#°Ø0Qyb…‰U†eÎVù¬¾¾~|b|bbbX_ÃËÉòªmP~I…ç%R’œ]ÖOn&5a[0 X&,5މš×@ÃDÏB“61Û0;0\ÛD×ÀŒÅœõ†èÙ¢g¤û¸$ŒP·€9`O³xi¸\Àá¶4«‚’ЂÆDˆë¸<Éñøš‹ñx0BöS±æù²Ži¶Ö|5Æ>†î…)ëVÁW!VSú‰Eˆ„{k+ˆ¼t)Lºø²®µ ªr(žW)L1 †Ó„iÀ±àd¬3Q7P7Ð4Ф¤G¬9X-jЖž¼ÌRô¨˜3ż•FÚ@›ÂH!z=`Aªk¦ƒÚ¹¿UùkF{Â! $γNå^ ÁTÖ’Jö!öÀ†`İ5ð5&V8––㕈÷ÁWÁ× ’hçrJ9~b X_CŸ§nX_Î$(]Ÿ*ëâªiŒ–tÏÌiÀ4a0M86\I¼†–&1:ÉÖÐ1i×ÄŒŠžÅŒÁ»zròZ¨%MÌs=‘JCµäÔÇ.Ë…95ñŽ•uQ‰u…K ÁÇ'>!}‰b ±æƒ -ƒ­­ ¾Ê°Â°ÄÙ€õ_½t‰¶ÏÓÖöíÖþaÀ׿î¾îuÞ¹¶99γr‰I¶e‹²zd1ÍùÇ}¬‰´êÌâ-ÉåQ8ˆÐOCX«23”ÍÁž¬£ ó(‘Ì¡¨?Uª´3(U§)Õë³ÍYRKb×_HVBÍ)Ó¤’If›€º 2,s²=ÕìEá–q)e=ÖúÔ›^«=' »=Œe`?’Ú:±ˆQ”¦‘“ðèà0°(Ë¢–åõ2Båæ®\å¸/Ëž‚¼ÏΦª ‰°¡šIQ'YÍ)Y¼–Òf%ß.’äš•×I¹JÓ.’•O ñ:²¦¥ÁÙ|lGzºð銾ï¢ô2.= ³'ÄÚp CI¹…l‡%7—SÓÇ×0ó‚Ž(æÎË÷{úŠlËgUs§váeYãBh¦~·èf¢K6+™–X¼ÍŠÅKÒ~fGÖznåž ëšBô|ïmîN7,ëiîÏI[•UÁKé õ1ö—ˆ·8æ&þXž:©~¸ôÿÅ–_8O¬mÛ¢|dÀ‡>4ûCÜ–™æ™‚ÏZQFyͧ!X”º9ý4RDýѼ£^/DßK¤Nxäù"¹%‚a€`„`„ÈG öû`>˜îy`1â|äIí$Ï3Cš "CPf^Y.q¡jF¤Z­Ã¨ƒ6`ÔaÖaÖaµ`7S_Ût4jh¨ÃªÃuÑj¢æ îÀµ¹ÓdvO¾(@€ÈHZ|åCªšFó¦6Çþ´¬ƒò ‡Šl…'Kº¥X Rfø€Òçˆ1ŠàG)ñü^ÏÇp2߇€ •Û‰|„CDë<°Ì "DÀ (ÌaLÎ1Í»P¶rúŽØ&HÄmÀèÀ¨Ã¨Ãh¤Ä3]Ø.¬:êMj£é QC´Ç…[K/­špë±µ0NÕ8B$YØ ¬³KK‘Ló!Yè'È·'ä°Xe]r!ÑF!¼£„x©²SÈ=##RâE>B±ØG”°|p?½æbÜ7*±ŽI*aA¡ 4±x™.y€¸ .¨ ZMRÁmÅâÕa%’å¶áF=Š:ì:j5¸5ÔjpmÔkp­¨¶×Hm›0QSë*넨i.§Å; mL¨äZ$½’¥–EéæQò‘}Cx1FF!ú>ü~Ïg±ßGp„FCD>¢‘$^ì£öÜåΆÀ±{:Ex" 4²¬Cò—ži¢,ÊBò¥ÔCDÀ8$³#J]yêUHç£Ôë+Û½AIÈ «¬,(£¨³d\̼PJ]Q‡JZTÚ´®Džfd¼iF6I­KB$™µ ,ȧ»À¼Œp5›ÔÀt_Þ© DYÖe|u6,qUvÞ-G Và3ø2R°,9¶¤ÐO¦ëÄaDqú*yñ”`—‹R“)¬Ä:šï0·%ë ½x]I¼$ZKŠY’>§’o³’„½LÅœ&ödH µÑ:3‘wmñûÒÄ;•Ö2¥Ë2lÔ—oU2iØ᥮÷š‘Z¤‘,ÉÃW!Ö±´½‹ò”qÙ•^T!jä•\œ’škV–—ñ¦EAŠO(·N¡ßŒjo$º-Y,ª#‰—ôÝØ»F¥øIh<Åït†rðÏŠ¤Ñ²Œ¾{2ÖÙdˆ$÷ÆÉ£!°˜/WP[݃¼­c ënÐÖ1dëÖl{·ü!«<‹²ëVžH?“SÜè³ôƪ¼,q ú\ŒÄˆóÄ x}_À9BP æˆ"Žˆƒ 01žßRN£Š¯)#Ou¥'¥.û¡š€ås í4GdyéÐõ@¤ ÒiPBgf(z]Ð9h; dW®\–k¹‹FòÍPêurјn5âZíI¥•{”O NÍË ¦s\VVÖÖDʽ¾À@`E`…‡aÂ:> x>‡'0â">&^,À8Xr-)§fÕä]ÒpgçkÉ[Š›ÞFê7‘60Ì€tHè‚tAº@[öCÙ ‚‚I(Úiƒ¶A;  ZÌ×GñBŽYJ”#ùÛGA­öR¼¥þx¾áÆ= 2/Bú «G$åú xB¿(äËà#`Ä1©­ó9PÀãˆ8b‘^sÆÓz?^2wPúÚy¡–Ìaråè…&`ºiá‘-ydètîµA: -»K±@s—Úºh¤Úà˜¢­9NÑ$…G'p/iÕMyÓà8{(]U:´<`Eªc¬Ýt± ?NkJC?ÆšÀ°*°È±*0è ô9÷„Çùb 8>‡/a²¼ D!OÍŸ¼ÎªskR„Ì‘×õ|î¸}Ìÿ¾y¯sœlJ˜ñ*扆A˜ž&ƒH~QÎ7ÝŸõ¥X×Eù¨ºZÒ›<Å«bQ¤ô³F¾tÀÊ÷ýfçÞ†rDYμ«A5­ õPuÑt!:‚”t\u]ùÉBHâ)ã]S>õÇd"ýôÛfÊ@Ø,¨´P¥®ÿ y+yÄ ŸDVßMW!W8ªˆô ?¶L%ž›§ ¡JIpA?*ëGOBS6Q„c cc€‹¸+ÂͺSîÙ+% ¾âß+6›»2ñ²5qMñÀÂ\[N¨ØÓ¬(jRwžÚ Góþr¡RÊ. {iÉOÔ›bî: ñÊ–›SÞ¾6w§ŒX)§QÍÝ ×Š(Ǻò:›˜±n”ë‹JÄ •ZЏÄ:‘ߥAZ<¢( ™ù]efñ¬ ÄÁ2ŒEÇyi’ÔS¬†'=¤!ЇðÆI[/­'£¾—Ê:† È¡ŸÔ©Äð#Å>bŸ#ˆ2øüQŒˆ!ŽÓ Ë.!8ƒÝ “ìH²Õ/LÙTçâÕšX‘6H h€4@š ÉF« Ò‚ÑíÀh$’O0 ×@Û@Û@F V/­#0k°j0˜nÀ·¤9›¬Ã7$ –’E´‹JÂÒæ¡ Û~‰drÏ(_ µŸ³Éw·ÌÉçɈ£?ÀˆaÄ1äðF1F ^Œà ~‰Èð‚“B‰ˆF”ò-f`1D Æ "ðxlkx)6@¥ûläsÇu…x–"òI¤Ò -I¼&hB¹&Ì.hÍ0Ð6Ñ4Ð!¤ 3yÂ…Ý‚U‡Uƒål+LsÜwj  I¶Œ{Ù‡2ʹ™Wv˜mïPTï%‘«Îo„ ýü„Î!ˆ?ĈÁãX‹1`±”už”Í"ODƒÏÆYªbI[F`‹ÁciîX*9 Ç IDAT<ÉmJ$îLE:8[´ê€K`(µå$»´Az ñšÒÜÕAk†…uš&Ú0š0ë0š°\˜.,v]˜­_¤t;fBÄÈëþX×W Òœ! s*j¯:\³Ð!%ò¹ BaPPƒÂ 0, “À¦° ê‚ERsY­Jk ‚.E—¢EЦh´ ZD´¬40“õ¦V]–«´º‰r¹éá®uæ_Yüúø…¸J)åCê…W_ ‘{L”í¦d€ F’x’[¼Ÿ cðEÆÉcHâ%ÿRú úI€;= qý…‡€§dó”(TacA–Œ€¦Ü# ”‚Ò”o&…IaIâÙ5‚EVéë˜ Š&A“¢E0CÑ%htˆhYh“´d¯-ûú\#M<£'¤,>ÐHJW’$6÷¯*ºéäÌ2B¢É¬ù¬„Ê·ä6Ì`» BpbრÖÀG}ˆDB¼5ˆ5áÇb%å[fåâŒoË™îx’b‘®Z2αÐ:æ‹ðÊ‘PI9"m]rmX†d…CàP8.A ´£I¥¹KX×¢‰¡C—`ŽŠ–%‡ê)×Ù”D¨DŠoËXThrÞeÁ¶ŠXÔG¼$X^ ›(Z´ì| Q|F€òÝD !B܃ðRsÇàËýt‘k`žŠÔ.¦ôcÉÚ* ¤ƒ>ÄpÂ0<%Ääµñ36®¤‰’ôÉ>ÅO «–«hBe”fµýÓ‘ñNµ6%)µ²6…fÞ j+ôëbì'µåôPÒ•Ó¬:ŠÕΆ;p>ãûWT|›šxÇJƒZí…rC…u¥¥ê0°>‡A³ëeeP?¿Âf)¢Q+•.Òa‰xL²..‰,B©L(°®©dx²Fô´T­>î*jÙ:Û‘ëì¬bô̺”réÊn­–\d“uÖãa¸±ømž’Ë9.Óðý#ÒÐÐÐÐÐÐ8ëpn×`­|Ï~,iHà"½@€ãT¶9ë)%lIʤr_ÖêʼM’¹É´6œÈ²HÒZ M N‰Õ:$mhiƒ´@äA´¸ ˆ„[¹hùúºˆI¡?%ÁÛ*eÛû c)_zâå+›†J#Þ20@ŒKx³Â»5‡'0ð6ÚO`UÀOúî/iDð¡Ý(1']xò:á^’KÌ6eD€Šôœe{²dü¢û´ ˆ)c.P‡Èâ•õ”>2ïÒUè×L‹à„´I¢«AZ©òÓ¸’Åê (ÞÇs´òQÕZ$Þ…Ù*%ÛîBE7 aÌBÙ“ÜÑûqŽ˜’{dÀÐ%¬<‘äž'0H¸—4݉äÝDŒPÀç%åb`b|I3ØŠò=AJXmƒðÇë©ð‘+)_Pe²ÉB\17…æP•u¤’‘eú¸ù¤s6Ç¥ž¼D¯êŸÕ¢–¨î Y7m©ãUÄ ò½ŸJÎEô(WÙ”œ\ùïFJCŽZé™ù’6x*»·uå½±¹#“Í“7wuE×\.~0IIøÌ)ñÕ¬! ‰w\¬²T4η›—›Ž‡JêŽçXW¶x…>œÂþTýÁ‹µZ…!G¼4¢’lª_\¹Îš¨šáP0w…Æø¬à¡“™;š¨&éµDôÃ'Þ¹í`µ\\Ò†° Â[Šf.¸ µÌµER]I\h Ä!”¸J‹T ´ ÃuaÔ@] †à Øe ²ÍNéA‰¦¶¥¨“8Ç#9zÞ‹ùRØö>eU å¶Â¶,RõÂOçK'Q*©iAÂa„ ÑÕá1ø!G˜ ¸g"†#ˆÓ¾»PY ³Û!8càœsÁÁy:™ „ƒ0p„Ãé,<—‚›„aB˜D ° ìñú" ¡Y#¥\r—Hú´ Z1-’¶†J}Z‡Ù­Ã¨Áp@k’xVÄ60Z/ÒŠQÖÆÌbQä8jä´Ï×h¼¹bš‹y1 _i}*è+~ s<‘^‰<,e] /CÈ$|KˆÇ±´Û3ȳNV °¸‚x‚×.Â"@9åéÊÔ$„aBX’{vjèD-%^Ê:©ÛC\ ™’ ‰•sSúQÔtAÚ uЦ$ž #»4`ØÉ%ëbÑÍy` §" ¦ùY×VÁÐ)‚Vç}ˆ}¥EÓ"Ê÷ò[Aƒ„R*¼ ‰“,’”1JwOLÙr©už&ÏVÉ@YC3èHiºSÚD~7Æ«bjØÉÊøFjR·\u9˜¥–ՕƦFéÒ”mvV2OÖUDõ[²V3KQ'¯ëð`+¯ |êù¯ã­Dé¹%k”gO¦[°nYöÑ@^ånPbÝH^£ªîx²¡PR.ûy¾¯ ìªîøEÖXSÏÔëù8“J¿,ÕÒP‚ɵ¥š»¶ Oe—V6—OD›y4§ÍÝѶ”¾BÈ ±Ókb%1NLDÅ4Aké–Ëtaº2È$YgZ0-X6,[˜µH¬K@™J¤‰ÂP(g)í2–O·hœ;çÑ‚˜æ¢’ÆàJ>#.µ»%çÛS‚B!8SUÒƒr|ˆˆ#f)ý¢aŒ8/[Lj#Äâ@ÞU¼²H¡_œð—ä2cT(C[Š¡ôÖ© Ë’(Âú)çerc –T«Îó~¼–¦QólT¨a¬F_Ùóùß ÊÐdö(€ˆS/<Î¥ï[Kj—˜ä‹SÙº1÷")œ"ŽÓh}4ޝß3PYT“¬½Â‘H[¢xëÄ€a€€ î@˜€ä^ÎÜ9€3fµäzXlfÔIža§×¦ ÓU+OXv$æ¡ZTSzQ Ä3‹gÆy#ÁxŽ;X×:xßœ²ñjŒ+„S}»4G{×L…(]·ýRá§eÞa>ž]ò›­Ì”dïPð¢2ƒäçÞ©û/Vµ{.$üR­“8 6 µ\$+i*!¨š ¨IÉ‚¬,À0ä£-ÙèÛ(;SM|Á›qY~,ÛŠ]¨Á'B"Ó\TâE±±TSjYÜjNW“E©“(j¯A>%¨Æ8eÑ ”T`,GŽ©ÜKøÌò{‘uŠ|Õ¶¡D7|ÞLºì†›—…VŸMe±«Ü®í$œD@lsÊBMY°Sýãtõн««-ÞL<ÙæÅ—*£RQ®0e¬]鈟H!Û(G÷•Ýè(7Ì›;¿äBM²x•¬C>k”vqÒY§Ùl5'‚ÊøÒÊG@U:HMQ×hä§dµói#GðFì_Výí_ZB瞃µoŸùÿPðÄÎ7êø´†††††††v°N33ìÍoö+ŽßêyWOB`|üGib…!ŽÓ~Üd4k¤\âì6O»uc&‰tPpÒ8æ[›â|Ο奃Õ}”³”ì™ÔN§ªHÀ¸kÄ®ºá*EQ`˜™˜H¤=®û%u$ÉÿÙ Í,DF1Ѩ˜&Lù)‘´Šl´jÈÕ9ÚôgW>Mœ¥Q²ˆe¡}!«EÊà¤øàlœDNÃHQ<æXB¿HÀÏáŠ2A6¯U æcm 5·Ãªöý¼TuR$…øU¦FFIY’`ŽTÎâ ¶ yÚTÒ¬.¯ëcÕ â¦Äƒâ€: 6H-fë#µ«\eüÊ ëÆd¥ƒsÕâ™æË:¬©¸*a*åÜR(år¤–Ú‡—”‡#gåŒ0™ˆ®P.ÎH(§U3QjŠJE¼¤Ø¯².+lròr®F~ì¢5Áè%¥Æå¼X4Õ"uÙhS—†®’t=Øc£Gl+ˆ¶ráVÏOO‰G'¬°t²ÊÆ9ÚØöÞ¼­Ë‚ëaž~1FÑâø†óÓÁªÕÄ–-€v› !Îo˜Ò(?¨7*MOÉLL–Xæ qe…$á@¾•·`²Â|Lœï‰)O.PW8^ÒÂ/”òŠüÚ–åVD¾q×ÌRET¬|¡¥“—3· uá€Q˜ë*éã†ÙÚ™ÑÁ&ÁZÕ'ã*ì„„¥¹ä¡Ì¨²Ô6,Iõ²kA6x¬T‘)¨¯( Tɦv©%ⱪ™Õ,/˜Q0@~i@•:FâcÕJk›¥xQ®|Äͳ±!?B”1hN~¨°›ï'wd9ù­›|6.ÚÂây ¥š»Q>+¬Úºaú,éW§*%W-TR~Qé+yä¸äÊg\xU¹À:µ…¡ Yn–£ H;§–—=;ëFŒ%T»— ¾®åÓy5…µ–ð7 Þ¸à‰Ç sc{ÈàE¤X¿à¼`=+¥¡bÈQÊ–Oº j2”r"÷ñ^ˆˆ bˆˆ "ˆ"’azA:1 DÞE ÁR)'&9UÕûy³•FgîŠz;Y„x~ŽJÍ*$¯€ä)J`ÈQRmÀ 0 ,#¡'ï:E„m Ë(¶%ò½7óŪ‰©—‚Y£=ëW ¸ô-‹c¦ß¤qxBýSʽ”x"éGŠ$÷Bˆ!<ˆ"i"·CùWÒ¡òR…>»Pñæã|9—´1…±d)·5ˆª©Âî:k‘ÊF„&”£É¼FƒÀ °),É7õbÔ¨p,a‘±ËeˆG!ʵTuÅ»R‹°ÒÅóì8ÂKÃd7fSÌ@Ø#Òʥ܋Æv/á˜ð"R ]•¹ Jæn’æëÇ ²u–d]¡ºœç½ù2ñŠæ.šLj¤ rr^Â=SÚ:+»!‰gaÂ1RÖYŠjFú ˆ¬#ÏQ¸§ÎrSž-%]ÎfÖÅ„°É”;ª­ÃTîI¡T>@¼‚)ël(ÜËlƒAÃcüÚ´ƒuÂ¥ V{AÙSg®.+íû Ú8Q)ìäݱ²ðôKLjø–pÔ§ ¥Ëä©X¿XäÚ nw¹™.³~¬ª6<Î:V5ÉSñÌ+ªIÇÈÊ Ìe ¾åFL[‰B9Y/^ò‘}¡‰•kËÛ5¥TÜQ\óZ>eÅÑB4)ÌyžÏ4eʸ »牒p)η/d•3òÚ"i0.-©eªO]w.=6?A»J§8£¿ S‹ó'EHH\«m—=lY–"“1,ÇJzCUŒ&k ôšBˆ<™„‰´Á$™‡Ë ÀÙ(à8r–3“ÁÔ\Ï"7.¸0÷®k&¥ ÊÄOv”®5C‰r«2½Fi„:åÂJt£+5W“™/ò"ó|Äìô©D'&ˆb6ˆéùW4§”ÝH¾ï‰Ã­iÕàáÂ#gÅö V{‘µ`-.)2%µÆJenQ՘ż”a.€³”rêu¬ÜåÊhVp>‡Î•¹è*÷„(¦Q uÅß›¹7K5¼ê¥Ü'eåk{­L°<˦(¹db‹äƬsÒ¬a¢‡˜ÒÏ  °¸háÅ”K|£“ûï¦RgOƒžÌÙ‰¼ò)Sh¦’0*·+Ð/ÊÓ/Ê Gb– AedãŠés/oëÔÁÔ<ã›ÌĸT¦ÜP®ãLn82W.u2K£z²V¾CÙ(U2qî8£LÅÜɧ2=jb¦ªz™1,3Š×ÅñL‰/X6ßú¸.…×úáÏ\7ÍeË:TUP``˜7ƒ ëʪ—¨l !ÂÜ KŽe«mv—)«*SLËó /¸"¿ÈòɬƒÌC º^P ”u®Ðá¦.lL)‹Kg7VÒ·q•‚x˜«Ñ2é=i0SÖVQÒçU%“"ß5å|Ó*¯%kßV;Ï ó\Í|ëJ¡Š¥¨×i•&¹ªÃ‰Å09ùÞ?°[?Í ç‰g¯UÉVÆ¥«²Î¶ ê\èµSڸȕóª”XérÊîò¼vF¡(ª@¿)Ë[¥¯KK¾Í×K¥á¦” 7‘kåÀfRv¾"J†¶Ç î¼-Äúó›uHÛ*7Y%hÁ*8ña‰{6–ñ¸.¸lîâ’Ñã Yž«BÚC(ºÁ“ˆ‡ .UÌÍwƒV:ôQûloPÑÀlå»”Ye)ô+ðÐLÐu‚ÌïæŽUyí,ï͇ùžóòF±àÍWÒ/#miô4Ï«ÅÊíì)Q5kM軘dñ¦ìô:E¨¡¡¡¡¡¡¡qª~çô§7ŒïÙöß'û#Bb`¹äGg;éå !ä`qÁ•‹HgÜ'·“ãÏ&¾±PƒNy/8‹6eó¡D¼IUÈ1õ… @!(„L¨¹ý`B(¡bȶ–ä¶1¾ALšÞ &`‚Pù8¡ Ôˆâ«WO·’¤*µCó³ÊÕ¡åj˜ÂÈ¿¢q†uçLs•Ò~•Ê$ÏÇE>€SÙçÆóÛðrÈ1Û1BVª¤™ »:^äWX—< …ŠÈ_§7äçŸÔ’œ(dNÄ[Ì—‘”l"a<¹BI!g·‰ f’?N É=Ô1A åB1£hC…8kzŠHžHFiìQ´ê˜4šq†™YÖAB"¥c­’¬‘e•^T•5x”Ÿz:?šNœ³òc§meZµS%÷kÊgí’Xg(gS•ŸËCÊ(õLs%oÔlYœç¯*XáU%SaÕƒÉÁ¡¢²Z¨»âyA'QŒQOIÏ•«Žê3!O6ä¥\UÑïÜŠ@ò‚…<ŠUb‘•§Ÿ]ÒH0‹I“ôA áÄÞUÕyqnÏ0ú”ú“s´nÎîŽeÍLe­TÓÆv^åEåž"¿ÎãhÅsÏÁÚ³ÇüÌgšÜyõ«u RCCCCCCC§O ì½ïíعS«¤jhhhhhhhëTÀ¶Åºu @½.XÉgï„ü§, žÏá ‚¤ „R"²f®OÍiiŽUâÛJs 1”§’V^ Bw‚ð¢\ úñª{´*{wéÑ#U}ê„sçôÇÙCˆŠ|˜¨ªàU5+¬TÎÂJyµrŠ7é¨ ªÊÔ~>¹d—R&å.Þé±l+ËøJ(_~2&× e YOv™ S¹kVÕÆ™¥!±Dí#5“2)zàoI?‹:¤Z?ãXèGùà²L©!±ãìšPxWΪ D‰3¢ªRJ(DʽšÌN*×ù§*'¼*]7‰x\©uò\£”·#A:H5q0%ߨ,»Tè'̼­3K ¥ Cš»læMˤ`áÅB8ãÿ2.LnÓ:W|\ˆÓ+mà8; 'äÀ*Ux–M0J¬ŠŠ"_ÿà— &+ulVZÑÊÊ-”Ôî c€T‹'ÑÈ“%”uÖ PJ{…ÌÕWÕŒ‡4?¨¡\G”§¬1ýˆb ²š¹8^³Þø_qB¶®ò*Dý¼u°òÈøW¹ªÑüb E¢ˆLÒZ•§5kR)EKMÀYÖ¶\i+5+0jÛráyJÅÁšT<>©ºœM~<.ýyœ7a/jÒÛ‰ P•“¹be ¬CΚ~¥3ŸÒ"êS̼ïn•Ä|Œ’̆ª(E*æÈˆ&'WV|üó‚RBo™„l* DŠKX ^œg;«rÙy^Ÿ`’GU+È1ŠÒ™£[ÇÜüj¥{…ÈÛ„æ}&£¤˜GóRQe£g*6ÍÈÏÃ3òöS µË¹¨WçóÊâ…„xUþŠ(ÕƒŠªÎ6aO—v’q^€MØ‘²©Z”  x©ÄXUËPuEi›¤jÑ¢VPÚ@uÐRYZ1ͼûnä»[²Û…ò;#/Md¦à›8›ÿ¡›;-Ó ¡¡¡¡¡¡¡¡, í`ihhhhhhh\P8×k°n>@ɧ©Ü Ø*eߦT×’cxÿS•‡‘©ozN­¹RR¢#ùR$äëBPU"J…#(BŽ_xB¹.JN(Q¢ªE”´ž’]]škÀ'WA‘ª¤–ªXJ/ÉWÐ|Mž*9ˆü'L‡óyÞ•G+ë>UÄ;ÞcN;g7¥£*i/QUôV&ªnˆR1òÇT–˜þvR›B¹FƒOP3%ñ&}±…𝓠gT™2CU'Q­…²J%íB¡·†3ÖØt?XeTy (É‹Ö#ï諃ôÔ*rÕ#yËRš§Ô•Ud,¢!Dë‚d $£›°W,[ª²^x¥gä½®ÂmTY<1¡„¼ÜÄ€' Ä«ìn+˜ ‚Ä0UÌ]á¥h¾U‹Np° þ}rÝ‚Ë>ýÔÁ¢)„«£V…¯OCCCCCCCCC;Xg1ÎõaçÊ]ª$žÏ9ˆS'Ùq¼Ê3å”v9÷Á«.çø©ò¬˜œŽ©ü—¹’¦IîÒ’ )½É× u0jŠ”¦OªÁ*Lu¥“S„ôœÝ´œ*≪—Çù£&UôCÕÈOž…*ì…¢å#&ì-ËŸM-Á™”›ž2¼–®'¥Q0<)EX&^!EH.l£w2|C)ÛKªL-é©„¡ùwWU} %Yê{‰ãL($Jl!“S„¤j’_AhjR V‘BB ?1r®ÑïdXw¬ÿì¹í`ÅñúÑèæóÊá5Wl{_ÉÐå.J·+k'QõóSסÄ[2¤½HÖ*«ô ,ÿrD©˜€L˜ìŠ8ž1Œ>!QI‡šË㸣w9ggŸa¬*«&PŽTÒM)ª£—-Þ^ÃX+õ%@)ÖDÕ"+†[âxñ¼‹NjhhhhhhhœbhKCCCCCCCC;XÚÁÒÐÐÐÐÐÐÐЖ††††††††Æ‰ÃÔ_ÁYÎÝ(Z'ïMé=.?uTQ’ï+DþOHUgV¡]¹ðî¢tp±ñs—sGJ{«›<[Ógü,A·eW˜¬¦üáÅ;îðN½ƒµuë¶0ô³»‹‹KœsrÆÅñ·m‹>ò‘EúÐìë_?íÿüã?n¿ÿýkSøîwBðò—“øÂê7Ü,,°I?ýÓÖûÞןtÀþýæ÷¿o¿ùÍ£“ùœG=à3Ÿi¾å-£f“O:`0 _übýÇ|0é€^°4o»Í;­ŸóOþ¤õS?Õ§ôÄ_á‰'ÎñŠWLó™æOþdÿ´ž²¯}Íݲ%¾ä’è„_dyÙøú×koûð´~ÎüÇÆM7ùóó'~Êöî5ŸyÆ~Ó›&ž²Çwj5qíµáÉ|ÎO}ªy÷Ý£zŸð+<÷œ½¸Ho½u"ÃzÈݼ9Þºµâ”MçÛ‰;XÛ·¿Øí¶ƒ 5”»víYXXñÅ[»ÝnòH­v¦ƒIwÝ5Íqyè!wú¦ BÄot÷nóõ¯÷·l™øÃàßøÆ´wyáKˆ“ýœG=àÉ';îõz ·²B·o·¦¼Èü¼³c‡uº?ç7¾á¾å-#Ã8ñW°mÁ¹óΉǼô’ùú×{Û¶E§õ9êžG6nd7ß<ñüÔSöí·{ssmÙÚ}î¹igä»ßužþ´Ÿ²G©½å-£)«õž=f¿O§¼ˆë Ï#§ûsžüaHæçÙ-·LÝŸóða㕯 ®¾z¢•ÿÖ·jwÞ9ªÕ&ž²}ûÌååi§¬ÑýþÉž²_´ÞðoÓ¦ø„_áé§íZML9&ŽI·Ën»Í?áÏéyä{ßsN÷)[Z2®».xÙËÂ~‘ŒÃ‡Óý9wì°ÞðoŠï~ÔWxî9Ë0¦­wB ÑÓ·…G}—ï}ϹãŽQ§ÃOøfføÞ½Ó¾Ï•zõÕÑõ×'颿øk¿¸'ÞÃÀü=£[.¾1yÔ²Ü8ö÷í;xÑE›„`^|qÇ /¼¸~ýÆ ð9²hYæºu õºã8ç1cÑ¡CG6lXG ãL$¿úÕú›Þ4íÆÉÿØ…Zss¼ÕâS¾ŠM›NꔪϹ°Àêu1åsnÞ̦ĉû}úÌ3öÍ7§õ”™&6nd¶-Nø(E«Å§x´É)›>ûLl[Lq)N 9Mó(§ìX>§ëòOû:²asœ?e„£ž²ÙY6ý”Ë÷9}½;ju»|vvÚ:2?ÏãðdKrGŒµ}|?‹Ùîoï&ßõ¿û°÷p(Âåoù¥Û~N.Æ=Ï[~ì±ï½úÕ71øâ¿òÍo>6;;ÛívG£á-ËzÙË®¯×í­[·üÅwlÙrée—m¦TX;Ö‡>4›ä 5Nßþ¶³c‡5%‡¨q\øìgÓ#XúÇþþ}æßþmãßÿûUýUhrêïóT!RïikÏ£Ñã¡þËÇÿåød†Ãa¯×[[ë2Íãy£(b;vìP˳Π¦âh/ff8c±þN6oާ4ôý‡×åW^éïA“SŸ§Çá`Íϯ«Õjœ ˲gffm4:£Ñhaa€ëžÑ¬)õ¿Ç‹-[¢)¥fÇ‹W¾RÛ\ýc?KÑëñ)UŒšœúû<ÓÖ«^uí·ÞbY¹ã=Ïk4¶m+ Í Çê`ÍÎΔt]çL:Uµš¨,pŽ"²¸H[-Ñh輌†††††Æ9ß'++Ô0P)ÑïÓá¬[7­iã|p°~èxàú³ÏÚ¾OÞûÞ~¡OGüùŸ·ÖÖèhDî½w™juz ` †žC¨¡q@|üãm!H·ËÊr’ý>ýýßï4bãÆøïœyÑÍ ÅÁZ]¥ßý®sß}˨j1øÒ—ê—\½ñ^’_ÿõ™ûï_ÒÄÕÐШ4èíö¥»víœ.o¡¡¡qðGÔ¾ûîÑ$ÙÂßú­^²ÖÿÙŸµž~Ú>.…Oí`ihhhœ ìßoþÆoô~ÿ÷‚={vv»Ú»ÒÐ8+ð'Ò CbÛâž{ú—_~¾5Z‡ƒõ•¡ÎxøÞÝÛ_õŠ«®ºê²äî³Ï>¿kמÛoãh§MCCã,ÂÿüŸÝϾqÑEñ+^üÚ¯Í~ùË{ÿÇÿèíÜiþ»·vß}sú§>õ©æSOÙ¿û»‡m[Üwß\§Ãû}úÑ™®X«¡¡q’xë[G¯~µÿ Ö׿îžÖqÔ+»»ùºI.ÎÜuô‰¿Ü´éâä©¥¥åú§/7õO~òÏOǧl4ÄÜ{ôÑÚç>×ø‘IŒ?þñöÇ?ÞpÓMþöíÖã;þç­÷¿¿¯)«¡¡¡âG~d¸°Àþó^~ë[GÏŸÒ4Å¿ý·k{÷6°×¾6Ñõ«ýW¿ÚÐëñw¾s°k—õÚ×zZÌICCãX°iSüîw6nŒo¿Ý»ývÏu€;¬v›ïÚe½ë]ƒ»ïÖbQ§ïxÇPìÚeQŠõ¯ÒQÖ÷ÜÓOœ­ë® ¯½6صËúéŸîO4tÖâ8ÒyGîûÚŸýû¿ùÄÌÜÂÅÛ®øÙÿø!`ÀþýÿûÿÝ^xñòË/½óÎ7ž>Õ†ý¯s³Ä¯»n\òÖíòw¾S«½ihhTCÄ1G3N¦)öî5ßþöaãÁ]ý½ihœV”'.gIªd•WúsÇÁÚ¼å²ßû³/uº³;_xúúW¾†È¦É >ðÿøÖ·ÞyçoÔtÑÐÐ8ÛpÉ%±ï“óo>úÑ€t|ÐÝ¿ßøæ7k=æ<üpí›ß¬-/ÓtçwŽ:d¼ãî¾{ãk^£GIjhhœ8ޝ }ãæ­¿û§_ü~é§ßûý²þî444Î lÝ}ó›{8'–%þÓZ±,q÷Ý£}hÙqÄßÿý~Ž#žzj·aˆz]|å+{£ˆX–ÐîgÈÁڼи¬·rY¯÷¹OÿqgÆ<Š(ÑM_·nîž{Þ¥¿M ³õºHª'q›Rçɶ‹7j5íZihhœYëòË.F¼  Ó¶’™žºaN[›8MB£BýÍjhhhhhhhë”s†zÖ—†††††††v°NžþŽ{÷ë¯XCCCCCCã¼ÄË^võÜÜì™v°¶oßiYVrÛ¶n·#u]·ÛíèS¢¡¡¡¡¡¡q2x饽KK‡ÏØÛ5›­mÛ.Ý»÷¥ÅÅ#É#­V§×›tüéH)­ÕÜv»]¯»ôÑoßtÓ̓ÁŠºIGCCCCCCãÄñì³O/,¬;coG)e,êv[33½ÅÅÅ~¿o”R ð3í`B.ºh3¥ ”¡Ç×khhhhhhœÛàœsözÝN§³²²6Í!;­Ÿc×®]£Ñ1í]ihhhhhhœ'ð}ïСƒ+++SŽ9Ž–eÕ DQLtž„†AwïÞkÛÖüü\³ÙЧDCCCCCCãÜEÇö}ŸÒëÍœ @åæ2~ë[ß|ó+§ÿI½î8pà iš‹‹K¾ûÝ'8×5X'Ž••Õ3Yƒ`Ïž½‡t]×4î>‚¬#G——W.¿üR<ò­[o½9y|8ÁØ‘ ‚pÆÍO>ù!Ž¡u²4444444Në×_´¶v憲¯­ù€HùÙ#7\¿~þt9Xû÷|öÙç=Ï¿þúk¿ð…/gÖêêÚK/=Üž™™™™Ù¿ÿÀpØ×œÐÐÐÐÐÐ8˱mÛeëÖ­ãüü¬¢B<ûìskk+ÇõW¯xÅGŽê÷««+‰oó†7Ü2éàSÖEøéOîúë¯-|hvvæXÊÁ44444444Î+~øáG®¹æªSã`µZµI=ƒ/ùË\}õ•êƒBˆÅÅ#”Ò}û8ŽÝl6õ)ÑÐÐÐÐÐÐ8wÁ¹8xð`ëÖÍM?ò4–(¥W^yuvwii鯸¡^¯ëÓ£¡¡¡¡¡q–c~~þ™g–ƒ >_ÿÁo|e«Õ:®?i6[®Û¸öÚë’»Fã‡ã`½ç=ï̆=khhhhhhœ[¸õÖô—PÀ-·¼B½K)9>‹ó@§Ó‚Ÿð‡¨Õ}&4444444Îu4ÞiŒE”ÜõÁ5ÆלæçT;XA0pùå[9õת¡¡¡¡¡¡q!ƒñlüü Ou³ö>¿wóæ÷¸ãq°vï~éàÁÃú«ÔÐÐÐÐÐÐÐHàÌÔqyî‘'žxªS—p-,Ì_|ñEÓ¬-[¶nÛv™þ*54444444Œh°3Þ¯>rã7¬ëŒ‡äpÎ’òª‰çQá Ì(ºFqÄñ´IˆÕ5XÎ&BèÙÿ¯¬ì9«>ϯþê‡[­ž&¢†††††ÆQ±ººøÑ~øœø¨¦ æ“œ¬¤…雨¼{ií(Rù(!ôœp°Î6¸®ûßþÛo}ðƒ|ê©§Þýîw¿ÿýï×߉†††††F%~ù—ÿùòQ-nÜ}íÇõ'Ó¼¨‡zèÞ{ïý«¿ú«cy¡]»vû»×ÁeìØ±ã _øÂYz,ëcûص×^«½+ £‚jÛM˪gJ0<Å"ŽÓRßÂ4]ߟXµ¶ÖôÑo/..Ì;Nt°¾õ­oò‘lß¾ýðá ؾ}ûöíÛ——— ‡Ãän¿ß°}ûöä`ÏóÊ/uðàÁä`Îùp8\YYÙ¾}ûÎ;“gwïÞ¼ËÁƒ5)544444΋ó8ŠFÙeqñàIbÊàœ©oáûý§žzjÒÁA>úè·¿ò•¯Ì;š;wï|þ¹ç¹àA.›¸ÿþ7¸úê«¿øÅ/&ÞsÏ=üàïºë®Â«<ñÄ;wî|஺êª7¾ñŸøÄ'2oéWõWÿàþ D8 >ð|éK_JþÑýÑÍ›7«¯³k×®¿ø‹¿èv»|þóŸ¿é¦›cÛ¶m«ÕjO>ù¤mÛO>ùäÍ7߬)©¡¡¡¡¡qÞã?xæ¯ÿú3Þô¦7¾þõ¯ùüç¿ð¶·½uçÎÝýþàŠ+.ýò—¿öío7ŽãŸù™Ÿºä’ÍŸþôß}ÿûOø¥_ú¿gf޵*úïþîŸÂ0|òɼêU7¼ímoŸŸ}ÃnûÁžIžýÎwžøìg?àïøÑë®»æ«_}è®»Þôä“OµÛÍK.¹X}ÕÛñ<æ†a˜[.Þbl0X¸Ë;ê'øÚת½¹;ï¼óøÅ_üÅäîC=tÅWøçþç|à–e8pÀÛßþv¿ð ¿ðâ‹/f«°,Ë÷ýäàŸýÙŸýÇüÇŸû¹Ÿ»õÖ[WWWï÷~¯ÕjýØýØæÍ›¿ÿýï?þøãšsç=þú¯?óáÀ?ÿó¿xôÑo¿ímo=|øÈÁƒ‡·n½øÿïO|úÓbšæý÷ÿæ=÷¼+Š¢ìà7¾ñµÇø<ðÕŸÿùŸù‰ŸxÇüÁ8phÆõÙn¸þ†®pÿý¿yÍ5W~ûÛß»ë®7íÚµgaa¾à`õz½Ûßx;‹Øƒ‹šöÄ{B.ï8rçÆ[³ƒ¶nÝúÄOÜvÛm=öØ«^õªäÁO}êS7ÝtÓ%—\2é#>ýôÓ6lذaÃ}÷Ýà¾ûî«×ë7Þxã+_ùJþð‡o¼ñÆìà‡~ø5¯y €ï|ç;ËËËwÜq‡išïz×»¶nÝ à¿þ×ÿš½o<òˆmÛšsç=ÞóžwÞÿo˜››-ûL¯}í­¦YѱwìÞ€ÙÙÞõ×_;éÙÿõ¿>±oß~ßÿþÓÓ_ÇãþÎhgè…»÷îž8ìùúë¯gŒÝ{ï½·ß~ûÝwß<øØcmÛ¶­ÒÁºï¾ûî½÷Þ«¯¾ú}ï{ßûÞ÷¾ûï¿À[Þò–7¿ùÍœóäî›Þô¦äà»îºëÞ{ïýñÿñäî®]»öíÛwÇwt:¿ýÛ¿ýä'? àW~åWvïÞÝëõX–uÕUW½ùÍoþíßþíÁ`ðÿ·wÿ0iDqÀßqb£ˆòÏSMŒééÐB]\œ»¸˜MÚ¥£!.:¸tpiœ:v‘Ñ@Ñë?,ž€Æ H„âáÎXÓ"4M*ßÏÄ]~¼wï÷rá—w9Þðð°òî·ÕÕ/7DÙÚÚ%„h4ŸÏ„Ün×/‘Zm[&sæóù !„PããcØE:™Ÿÿh2¡ØÒòàô4„‰#Žêí}˜Ïç9n¨P¸ØÜÜV©hŠ¢|>ÿ‚jj²J›Ôzq}IXËbösúÕè å¬Ngû/þ¦!›=¬«ë™™y7;û> ÍÍÍMOO÷÷÷ãÆ¨èõë—^ïŠRœßœ/•J,k³Z-Êáùyn?F±Ùz¦3^§(’Ëå alìY*uj6wB’Éc«ÕÂóqåí¿ÁÁµZ}Óf*•åùØÍa¹\Öëu}}×[×x½o'''Òé ÃtÚl=¹\>ýF±Z-]]L&sÆóñÖÖV­¶Íbé‡×hšæù8ËZGFÝѶ:±"­Š‚újÂÿC’$íìì,//s‰DhšFNîøÑ !å²Ì²f–5ßÖÑÑ®¬`)öö¢»»Q­¶mbâ9MÓJu¥C„‡ƒu8Øßa=Ãpwua2ív›Ý~ýâ]{»övF£Áh4(ŸeYÞØøšH$ ½Çãª2ºÊ+XÍÍŠ¢ên./¿×ÕõƒK<ŸÀ=PËZ]®Ñû4¢Ú+X¢XÀÄÿ§ó‰Ó‰44:쇀  ¾ý|DHéš¶ÕñŠAB®hèÐ eù€†%œ z½ W®ˆ²$W¡ÀÒ èV¤HÅ/Ä6bîÇn^æ‘YhX±µ˜ç©ç@:¨ÙDQ”Å*A²$Ë%Y,ŠÈ,4,¹$_IWâEµŠH*JDÙì9ø)(IRõéŸà‘YhX*•jñl1žŒ×ŒüIÎf‚b~gIEND®B`‚snd-16.1/pix/editheader.png0000644000076400007640000007226711147553266013767 0ustar bilbil‰PNG  IHDR,1Æ5Ÿ0sRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ/ †Ã+ž IDATxÚìw|O×Çß÷;²·X±…ÆLÖ A)¥¥UT•ú©½j–Ú»öÞÔVT­–jì†hmBì1"SöøÎûûã›Üä)Áý¼^^r¿çžsï=çÜÏ}žç<çy;GÑÓÛ  (È­x˜Kص;hJV|Q/åžá¡Ò+ (È•8sú4Ûÿ7 À=}4‡/+½¢@Á[ ±8åÍùŸ»Þ_ª«Ä :¾2y?wÝ»B»UWøÔ\–B¢Ós×ߤ$ŽTbôÑÂÍ"f£ ÑhF4˜@Ìf‹j•µF™ ärxˆÔw¯„Z­Îvˆ°{ìO¹ˆ•µ@u[Oœœ]Å쑃Édä÷«û1»›(avÁ·`•l×E„»!7¬Œ˜5&D³ùÂ2XËþX F<«mÑl”ÏDžÆ¥@%(3â¢°Ö /kB 1\Öݧ¶½Åy9õ>M‰¹òž+Ú!¿Æ… ©w7Æ)ƒøª¡Q ©ÉIÙ:Ýl6“’’„ÙlBT‹‚€A¯çï¿ÿ&ùm”-[–|ùò`6š,Ü¢A„kW®påêêøÔÁÖÖæqÕïìYRSR©^£:]2fÁ„Y4!šÅÌ„e–$,«8‘B1yÑ ˆ€ –?A@ƒ^ÏÅ«ç1úPY©• ñ’¨iÿÕìKÉ~K0¥°2úÐcçV°+Lw·†ì<{ˆ3iZ³ úûqܾz c1=…]òÓÚµ&·tøÅŸÅ š²¼fŸ|MxhLd_üy"ñäÓ8ÓЩ".j{EîÉÑçklï¯C9~Ü:›û^©¨lµÊ ¿B˜5"beKÈEED“³Éœþ#«V¯âÞ½{O­Û·O5l€(Z¸EÔŠˆˆœ={†EK–põêUz÷ê%«sòäIæ/\ˆÕ«¢Eã3c‚Ì„…Y´¨€ƒ­ ÍêU¡tOT*‚J@%¨P©U¨A¥B¥²üœœÌ´ÝQ„ŒˆŠ€õÒ(¥ÍÇÇŽÞÜ@xt$ Š×í×OËa¥Ö`­ÒbE„´Ô‡'}ê&óòl'rs á¦x4†¬ö;zs4äû.E¡ª”‡T³á±k6r¨È»Áìù{7&o+]óRË®4Æ®ÿ ÷Öïc¥Ö`¥Ò"&ÑŒN4`-_\kA‹FP""zшÁl”Ú·QiÑjŒ¢Yšt)W#x˜I¾êžX Ô‚ 3"z³£hB%¨°WYc͈ˆ¨:³ãHWAv%,sÚëž=²¨X"¢É„h´—9ÍVäààðÄjF£1mìD“ÅÄ$ª-õ|ëùr!(ˆ={÷";‡V«%00™³g£×ë3f4æ´úf£ Q|T%4e¨„˜ìlpu¶G¥R#‚… ²øg­U£Õh0Í (“饿€&Ë nÚ³UþÛ´ ¨œ­q OᛊMiêR•û)QD™Òä]0ë Œñü†´eâß+¹bÅ0–T/S‰Õ%ʰïÞ)EîEãò¸.Ì$ß}H¢“³cá4S€Hrp4v÷ |]ù#ê9•ÇJTóÀË/ü9‘tƒ|Ö.ô*ЄÒÚüX¡Á 9w™¡þ<’ÉoåÊ÷MyÏÚƒ«‰÷°VYe˜>SÍ|äP‘fnUÉ'8’,Øûð»¢N’ÏÖ……¥ºq3%Œc ,º±“VQiUÊDyAˆ‘t*›f$DÌF3fµ…ªD³ˆ££#K-|b½ƒ‡þF§KEED1[¬Í ‚½C‡üÀ´3عkƒªU«2é§Ÿð(X±cFS¼hÑŒº&³E%•©„b†J(š,_KAPYÈJÒþ·?úÏ"¶™0+V0–ePêT­‰Kɨ­H4ëØ@åøØ¥!·o³ÓMê4Då,ït1Õˆén`ã[ˆŒHË>¥“«/—®^ÆPDÏÉÛøëèІÕêÐÀ«"·oò{ê>)_o›¢|¿ ­Þ¯ÁíË7Ïo‘Ð «]Ù°ç ‚¯r-6ý®ØvQæÉ‹–Ù ˆÙV ÓÕBÑdF4¦«„f‹¤õ”6DÑœ¦Nf˜›D³E%L¯×»gOÁoÏüöì¡@ôíÓÏ’%3ÚE ·¨³aeZ%4!Ù©AHS PYÔA9a©ÒXP+‡&x*FGË‹•Ãú m¼÷~ìkœ8†s~Ø¿—Ÿ ¥Ê<Îyz#ºØdNÄ\¥]º„EFð×õвFmoIo@%ÈWuìøÐÓ^‡µÞ;Q‹3ÎÖ”u-†µJKµŠUÐ ¸;»¢Qk(nÍe!C‘bøV¯£­=…Ü `keC;’.‡ñ~ÕbÄÄŲ+`?G.S7¦>5+ð~¾Ò¸hì)Z°0Ÿø|DW7ì­m)o*@ð•ÓPnÝ aí_[ˆ)ªBåªÅFoæ©‚™_i$’]•0]‚7š0§©“bšJøÔ6Ò¤£ÌÜ’¾€—^ÏÆÆšêÕ«qøÈòæu§\¹2R¹F(f“)MÂzD%õi7d²”Œ”ÒlVª4õ0CM,l«7£• ‘# Xóǯ¬>´Á^‹(Š.Öè¢! Ðt@›Ç.}>e)©¥U*•Dz±r¶µØšôòÉvëÞmF-Ƶø{”+^šñíPÔÝ#Ss"÷ÃCIHM&8ô•š˜Q|\¨=Ë6'*2ŠÀ«±³²¥@ž|h̺ˆ‹‹ ØkÑ::¢q´ÎxQ‰‰‹åNØ}n‡Ý%èúenÝ».6ÆBÖ11¸¨±)Û‚.–:z³2Q^f~ ¤ólº²Ø)ESÆ|E‹¤ô´6,eéÿ°ŒY:¥ývöÜ9fÌœE¾¼yqvq&(è"ó,¤S§ŽØÛÛ[ª ¢ÁŒˆL2£»\%ÈJšJS3‘Vú¤STšPi+1^ž¥iæÐ •»:³£Ñ—6F’lÖQ¿jm’j¨€ZP=QŒ7 ¤˜tõ(B“Juyàbäš!ìÉÆ G VïÀ¦¸‚ƒÅÖ§KäJÔmª.OXt$W"‚±ÑZS0O~BLÑÔ°·G#¨¹u÷6'.ŸÅÙÕEjO4™9{“ÖÅêÒ¤z} ëKóžC!é’çî¯K")%™ w®¢7)ìV€k ÷2l]‚V…ÚZc!ál¿j žlD‡ˆðþ=vüéöyAà³ÏšIóRT™,ßÇ4U/Ý|ñD52½\´HI¤­8b9uú sæÎã`Az÷ì—×{Ìœ=—ý"ݺtÆÊÊ AÑ”¥[C†J¨O5Ž‹­£Lš‹D•ù·ääd’“’05ŠJ˜ƒÖGÖ¡Ž©‚FEDüCŽl:Éi÷ìºr„ž>|®ö%<$³s±'JXáI9|?:ù*2¨Ùwüu1€ à+h 8>ñú-V޶¨Ô"L5êùóî1ìÌZ×n@skS“9{ñÇ‚N£)äøX¿(ª`Îͯû÷ï³jõš§ž«V«ùôÓf¡Äl¶,¬‘áOþÔ•FQN’fc†#ú©3gX²t‚JÅ÷}{Sº´Å§[×ïP«UìÛFC÷n]Ábð³pMwkˆP¥²ðƨ® ™´XÒ ñ™~,õ’­ ؘòÊ„zYürc?kV¯Æ–áøi6›Iq0]Пã÷°|Çzô÷â1;¨±µµ!é^ ·¥û¡Äÿy•$måüD%Æ2õä/L ŠÂô N‡ÞÓ{gkTš Ÿ¹Ï·å¡ßU’mLØóàzÌ=zþ6 ÝÙ0 a©1,½·‡å~1‡'c6˜ÐkÌèݵ\}x‡ÿ]ŠùT8úøDWk¦ü¹Œä»1PÔ†{‰‘ ;¾ó…HR#Qç³EkPw? Umþ ?ÉàV<æ$=ÁŒÎ¬cóÒdIOâNÜ!Å]…]¦ù©àe%,­•–üùó?ƒ°Tiò¬F³Å¶”¦QYÛX3|Äè'ÖÕô4ÿìÓ4®,n i‚Y|\j†ñähÑ"’­ËÑёݻ"aaai¡`1+˜Ÿâ8*Øk˸f›~¬ÒWŒÊ|xY$“1x;`ö´–}¦¬ÓÆÈ€ c9GL%mL"Ib;¬Ì"±b †ùÑèM¨¬4˜ŒFŒV"Æ Ž˜=mÀ š4¿˜Ì߯‡V @k0!Xk0ôèÜÀXË [½3¨ÌZ}9GLž6`´Ü—µV…`£A¯0|芨·ìKҪ߳ÅÊ,"šÍè쌕\0§:`FÄ ÐTt@Ì‚ˆ©° ¦<ê´í`"Z• ÁZKœFÀøQA¬Ò&ª"a圄U¾|9–,žÿl– B,î6æ48A;fdömöbÚØ‰"P¿A=ê7¨—åévöv ð}&£»`1ø›³R _â ¦øóåÔ*5jǬw ˜&Ëb‡u–_O­µ•…Ý@OµJÚ^-›´¢Y>`Z+°‘×ÓÈÚ2[®kk¥ÝMc¥«L^ëÖÚL/ˆˆZ£Fíðø3™ »ˆÆZ+Õ‘ÝW¦ç4+VŽHXa¡!¤¦&g»Š>5Ì +1!]j &³1Û×Ä n¹/½>5û×Ö¥X>°FdV Ql ¼õø-ä(»BŽgrºnJƄȀs+1™žO•Ò‰FÌ& ¯ïFómLÀŒùq•P4˜0„%’«Œ¬o!^öÍŽ| ×¶Ëç‚¶€Ã#„e4cJ5¼ó*_×ûTY ä lܹ ‡Þ’Ë&]×ÄhFˆÓóÃ0S”žR @ÁkE``?ÿ²cÆ2‘@%¨ÐjÒ ¥¢“É ô– ^+¢££0h5ZŒ&‹L–%DµZ-íþW @‚ܵZmÙ˜NX*• ZÂW (ÈU4jµ´Z•®jÔJ\v ä2¾4j ª´}³i–€F­Q, ä:hÔT*•\ÂÒªÕ(:¡ r´jµ%&™mXÂW (È]*¡  ÑdHXin i†­l4`2ª•àW (xY2R‰¨5ÏȨQ«å6,A2º+D¤@‚Ü‹ K¦ ¨UJ^A ä>•P­R#Ý5Ï5ô»¨YË—O?ûBö/%%ëm=-[µ•·û¦#sæ.ÈòÜ›·n=×Cõ0˜»wïý§wñâ%FÿÚ.4ôÝ{ôæÓϾ`Öì¹$$¼xv烇þfÁÂ%oÜä5Œ|Õ¶½ò¿cÐjÔØ°ÒGŸC%4MtéÒ‰Îßý/[çëu:Ùñ†_ž¢µ_¿AìÚ¹=ûY¯îÏ ³ÙŒÁðú¶,-X¸˜Þ½zàí]‘Y³çròä)4¨÷Bm™L&ŒÆ7qû•ˆN¯WÞàwQ%L“¦žÛèž]¬Z½–ãÇOðå—_ÈÊ-^Êùó¨U³ß~›ñÅÜñûøùíåæÍ[ôèÙ€)“'áââüÌëÅÅÅÑ£çTÒ xÑÂyRÙÀACHN¶-³··g挩RYÏ^ßK©…ÜÝÝ™8a,:Ž~ýIçuíÚYú;66–‡eD]|ï½Ò ЀiÓg1䇬Y»žÿ=Æûï{Ó³G·gÞÐÅK,X°H:®_¿_µi•å¹M›6ÁÕÅõ™mîÙ»ŸíÛwHÇí۷çv-éxÖì¹\»vÝò|]:Sµje6nÚŒ¿ÿaé¼ïûö¦\¹²¬\µ†'NJeC‡ ¦D‰âϼ—3çpãÆ éxꔟpvvbÃÆ_©^íC¦Ï˜%•Í›; ++K"Šá#FóðáC  ¼½ïšJˆ 3ºg’°žßÓ}ÉÒålßþ;mÛ¶¡ý7_°eëv4 #G “ޝ\½*ÕûªM+Þ÷öfóo[d„U¿~=>¨Z•›·‚¥ºŽŽÙº—q&1gÖ ‹a6Ñ¥kO~^¾˜~Ó³{W)µvBBýþÀœYÓ9b¨”3-,<œQ£Ç2aüXº÷èÍÄ ã¤ö;wéN•*–úû~ƒøiR†zx!(ˆ…‹–лWêÖõÁ§nú}߇‘#†qüø Ö¬]OÇoŸ¬Ê$&&1wî|ƌΠÁ]îfÏÞý4ü¨>áá$%%Ett4e¼¼žÙçÎròä)©Ó¥4‚X»îfLŸB›ÖRœ:}&EŠæô™³ÄÇ'Èê;ùógóçŸaee%+úã~Y¿ú©÷2Á"*V,OÛ¯ZËÆkÖŒ©œ;Ⱥõ¿°|éb©¬[÷Þ¬^µœá#GÓªUKòåÍ ÀOS¦)oð»ÇX2£»ÆbØz1?¬Ý»f©&%%agkKá–´NýûõaÿþRyž#•]½z SZØaWªWûÖ­Z¦µS’ðˆˆ§+:¢™ÄÄ$Ùõ4j ))ÉÄÅÅ3vÜÎ_âÁƒ0jÔ¨&IsOƒN¯Çl6ËÚÔëõ–ˆ‘ßvø†õ3TÊ””Lf)ÉÉhµY½„ÄD³™¤¤$®^½&‘?@ðíÛϼ—B… qÿ~())áqš8.SßN•]/** €‡cÈëî.•Í=ƒÖ_}£¼ÄïšJ¨Ñ<"a ÕÛ­!*ú!vÉ‹:´`Ùò–üŠiÏý0æaöìY&Q‘QìæF¥JÞYž[©Òû/uïnn®,[ºˆá#FÓö«Öx{W|­}Ÿ {öìØ0[~Ñ‚]»v.ý¶xÉrô﫼 ž%`¡Qe©>¿[ƒÑhD÷ˆ1ÝÚÚµZÙl–ÊÖ¬]/S :½SÚ9–¤‰‚ŒQÓëŽ9†Ó§¼ðkµZÚ~Õ ggg© ¬­­$Ïúµ+¥ˆößv’Ô­V+{¶† £råJIÐÅY"½ôþÓjµ/5,jµZv=QQ½„«‰J°äÌÜfzNÉt•°nÊ—/€ZeI «R«EQVO£Ö¤-/«ð­ëC‹æŸeê_+ÙuïÞ½Çw»1h`š4ùØ2þkÖáííM£Fe˜¾îðLÂÒj4–¹’v/C†WÞàw²4j5‚ê£{z¿ì"oÞ¼¬ÿe#{÷î—ý¾~Ý*Úó5óæ/¤Ý7èØ±=m2gΚÃÉ“§‹{ÃÜ93S¿Òë._¶ø™÷âåõ66ò4èÞ-’Ȫ•Ëèø¿.$&&¦ÙÄY½j9[ÛHë6í0§eä˜4i<{÷î`ㆵÒ=Ì™3“€€£¬X¾TVV¾B9Ƶäi³³³£T©RÏÕ—ŽŽ ØOÖfÓ¦Mhž–yÀÓ³¤L{>ü°*÷CïËÚìÙ£¥K—">!ÃdÇï;™ô“ebРþ(ŸÏ[4gùÏ+eõFŽ:|ÃÜy deS&O”’a¦“¢““ÚLYt:vìÀ¨Ñã˜8é²ôÛªË(UÊ{{;Ù½{¿o»ùófÓ£W_"#"¥ñÙ°a“ò¿c"–V£•²œ jUüc67ƒÙÞi.GîC¯²²5G9ÂEÏØšãï”þCGÐiûX._gw¿e鎣•K¹P%T=+m•P r‹Ö`Ùü¬–¾Ÿ&Æ) ¡ ^ªgïN„ôh yºgOÂR©Äl]H rD%TkTŠJ¨@‚7D%Tg¶aYxL r›|%ç&•Ò% (xS – ÂR @…°(PðÎ⥗íìl%§®7¢(’””œ£mªÕjlmm^Ëó o@W5¬­­ÑjßÎÕpQ´„uRëY h4¨Õê7h`sÞ‡L„—ŒÖðâ0›Ÿ¸çù°¼®qzçµ¢*P @An ¬?þØÍ… —þÓ›ÕéôLŸ>ïêà3gùë¯}ÊL{‡±uë\¹rMéˆÜDXA„†>øOoÖd2²oß¡7ªƒïÞ½GPÐål;gÎ"Ž;©ÌÊ׳ÙLDD¤ô/66N*‹‰‰ >>ˆˆHâââ¥2ƒÁ «Ÿ ©i‘üËåË׈ˆˆ”Ⲥ¦êdõ²²­FG?”]ë]GŽ[ wíò“â†7jÔ@ Îæï”˜˜鼦M?–2£8àOBB‚TÖ¢E3i#¶Ÿß~RS-±À«Uû@v­;ý0™,ײ±±¡I“†>üuëÖâÚµ\ºt6¬÷J:4!!ü¤çKÇÇ1>|T:.R¤0U«VÂ`0òçŸ~üóÏ  §dÉx{—àÞ½PNʈ!ïåUš²e½”Ù›ÃØ±ãOÖ­ûU:.X0?}ûv£lY/FšHÆõ8ÎÍ›Á-Z˜>}ºQºtInÞ fذŒ¤$¥J• wï®äÍëN÷î¸|ù §NcíÚM|úic:wî@rr K—®äðá¥zï¿_ž^½º/_^é·jÕP¹²7[¶¬U(§ kùòµT¯^U"›‹1bÄ`vîô#(è’Ìà9oÞR¶„ȽsçÑÑñÔ,XFß¾ÝY·îW<“V!ŽgºÖbcã¤k™Íf"#£èС-wîÜã‡Faoo‡ƒƒF£‘˜˜XZ·þü?ïÐY³I$m6›ù÷ßÔªU=틚ÊÁÒ¹AA—1ŒT®ìÍÁÄÄÄrÿþlmmqrr’ÎKLL”Õ ¢mÛ/ñò*­ÌàÄÌ™ 8ztt|çÎ=îܱ$èíÑ£3]»öåçŸP¾|¶oßÅï¿ÿÉàÁ})Sæ=¶o_/Õ[½zûö¢k׎lß¾ž‘#'аa}êÕó‘ΉŒŒâäɳ²zãÇOãìÙó4nœJzذ2S+Q»vu¾ÿ¾»´jX»vcFŒŒ¿_~Ùœ5>”Îõñi"Öÿþ×NÖŽOúöíÎÎ1gÎd<<,©©Ž?ÍùóAüöÛ¶m[‡}Z6œÐÐ0ú÷ÿ‘ÚÒ¶mKfΜÏï¿o¤hÑÂ\¹r™3¼ÂÚ»÷ 4é £lõÆÃ£ ƒõ‘Ž×®ÝÈùóAÔ¨ñƒ÷%..žúõëРA]Y›eʼ'#§‰§¢VcÂ„áøø4–Ž«TyŸ¹s3rXz{W |ù2øúÖ¦zõªœ?D¯^9,#""ùá‡gg6Ú·ïìzwï†R£†\‹èÒ¥£20ÿa•+çõD‡ž=Êr +V€7n1tè"Òâv[lU¦,Û¨X±¬ìøã[¢Vg˜áêÕ«#ýíääDÑ¢…¥~ùòWo¬×j5”)Sšk×n°aÃo,^¼B6± zz"NÇŠëØ¸qK¦‰}Ÿ?¬¢ÌÞ†»»;ÖÁƒ‡=ú'&Lñعnn®’ªW¯ÁR½””T&NœþÄk„††a•ï¾Q£úlØðóSïéÔ©³88ØS¦Ì{Êý6¬'aÉ’Ù2 +S§ÎaâÄ‘’MfãÆ-Ì›·4Ë6Ö¯ßüÈjÇc r’“Sضm*XˆváŸ%é+&&–=žœÉøôésØÙÙáà`Ç‘#ÿräˆ!!wéÖ­Ÿ2sÿüõ×>üü2Vt #uêÔ|jA¨W¯6Ó¦ÍIûØš9wîÅ‹•ΩS§GãĉS¤¦êøüóO)Z´¥J•êÔªUŸ²ö¿úª“bÃzÕ„Õ©S{æÌYÄäÉéÈ×­[†““#}úteÊ”ÙÒŠL³f%»Ô!ý4h¤”fþ“OIõÇηßv— ünn®¬ZµèµwhïÞ]iÑÂ’󮮠R¥Jfê‡o¤2'''<< Èê~óMkæÌYÌܹ‹)W® }útÃÍÍ•êÕ?êyx$oÞ<ÊÌýðý÷=d«Ðîîy¨U«ZšFP˜^½ºdYoàÀ>ÀÁÁŽöíÛÈz7þGG¢¢R²dqéÖ½{'NŸ”ÎËj\—.ƒ³³“28éˆ µªˆãö,&,>‚å-Çp`ïS³æ< ''GÔj5)))h4™a=..^ê츸x‰\Ò &˜bcã$5ÐÉɉääd©^LL¬”†ËÙÙ‰ä䜜˪[ºH¥Ráêê’åµ3CEÙruް¾F#©»&“Ij_ì1™ÌØÚÚ`4¥%j•J…-¢ˆ,EY||<ƒIzÔéôÒr¸V«E«ÕH}­Óé%BWðtØÙÙI9)ß6üóúuÃßÿ(Åàƒs9q)-=ææœ„ekkûØo™ ãi_ ç'ÖËLBéù¨!+¼®¯’Z­&O·'Û“Ê2ÛÞ…µµÖÖn ã(PTB¥ ¼+Ðëõ’ßÞÛ'a)„•ÍI`@¥2½1l6‹èõ†gž§Õj²•EÈÒ¦NÿZžG§Ógëyr½mB¤H –þÔe£ŽJ¦N? F£ÿ³ &¼fâѨðñyþ•î—&¬?ÿüGG—·ªLÅéÉ IDAT3SRR¨RÅ GÇì­@†‡Gqöì5\\\”™øBÒˆV+P¥ŠÅÇ)""Šuë6bgg/cooN§“ÙA‹/F³fžók¤eËVJ§¿f\¾|ñõHX*•ŠÆ¿Uyçά­ŸOj)Y²$~ø¡2_Hê5såŠ|»¹¹âéY2¬(\¸ÇÇÅ%ÃÆW³¦Òyïšd–“ <˜'N¼±±cÇÜÜ^θݴiSÙWOÇÀiÞ¼ù3>ŠC*E‹z¯ô­BX9„   Ž9òÆv†^ÿòv¨ÿý—ØØØWvÏùóçOÛGù\õŠ-Jll,ññ¯7À×_ýÔr+++J”(I\ÜC\\\ ºLÑ¢E”7÷ÅÀï£>"_¾|ʈ=‚Ï?ÿœO>ùä¹ëuïÞ*Ur~{››[ŽšÜÜ܉‹³lŒoï ¯d¼%Ö‰–-[MDD„2j¹ùòå£M›6ìÙ³'GÚ³³³Ádʰ'ÚØXãììœã!gÍšE@@€t<}út<==˜8q"gÎd„÷Y¸p! ”ÍM€ü‘jÕ,žñ‹/fß>yàÆR¥J1mÚ4"##éÞ½;3fÌ dÉ’Êäy„µwï^~ûí7:v´ì2?}ú4cÆŒ!66–¦M›2|øpéÜ#GŽ0yòdDQdÊ”)Œ9’˜˜lllèܹ3—.]âÊ•+üöÛoxzzR«V-’’’X¹r%+W®Ì•êååźu눈ˆ`Ò¤IŒ1‚Í›7³lÙ2*V¬HÓ¦M7nmÚ´ÁÚÚšuëÖaggGŸ>}döœÅ‹ó믿ÊVÆž¤nÛ¶M’@'NœˆŸŸ®®®Œ?žÊ•+KçþøãÒ‹Y¨P!üýý¥ ë}ûöåìÙ³äÍ›—¹sçR´hÆ~¸N:qýúuF;}û(V¬}úôÁl6óõ×_sÿþ}¦NJ£Fððð €øøxš6múÂ}Y¢„'¢(wA°¶¶Æ`0H1Òr+V¬ Ož<,^¼Xú­cÇŽøùù1{ölÊ•+G×®]e}±{÷n¢¢¢|¸ToøðáŒ?žB… )Œôª ËËË ½^ôõéܹ3³gÏfذaÒïéߦM~þùg–-[Fß¾}Yºt)­Zµ"&&†C‡,ûº|||X¸p!Ë—/çܹs¹ºCÕj5ÿý7ݺuãèÑ£Ô®]›iÓ¦QµjUDQÄÁÁ!“´`ƒ%ÛŽ¯¯/VVV²þéÕ«NNN8;;S·nÝÇ®µaÚ7oΗ_~)IŸGÅÏÏ®]»²ÿ~úö͈1räH‰°:tè@ƒ ¤mQé÷;f̦OŸÎÙ³g¥zéeãÇ'((ˆ%K–àããƒZ­æàÁƒøúú2tèPV­ZÅ?ü@çÎ_ªmmí0ReÑ8ÒáéY‚k×n¤í×^zÌŠ+†££#ùóçàĉ”-[6íZž/^\*  bÅŠAuëÖM*›5kµk׿èQKFGGGüüü¤ëtèЀ~ýú1sæL©Þ‚ hÞ¼ùc™‚W@X÷îÝcÍš5Y–•*UŠ¥K—ÊÈmýzK³ÀÀ@¬¬¬2dlß¾ýˆ   ªW¯.ëŸåË—óðáC\]]±¶~²ƒäòå˳T•÷ìÙC»vídRÎØ±c¥¿§L™òÄP>OC\\ ,,. 3fÌÈñþpqq#<<š»wC², }€oŽLᆠJŸ:uн{÷2bÄécY#Êž…©S§R¿~}Ùñ°aÃÖySlX¡¡¡Ì›7ï±ßÒÅåš5k@³fÍðóó#%%%Ëvll,‰Ÿ¥*½Ixðà+W®ÄÑ1c¯d¿~ý¸wï7oÞäæÍ›O±óØ¡R©¤Mâé¸rå Ë–-“¤8€¹sçÒ¦M›»oQÙ¹sg–e‚ `gg÷Bùò"#ñ¶ÖÈöŽfFú¦ûœÄ­[·X¿~=£F"Oyä„óçϳ{÷n†šå~ÏG1vìXâãã)S¦Œô[íÚµÂzSKEΞ=K±bÅdÒXLL Z­–®]»ÆöíÛ¹xñ"£Fbþüù#þüg„W~øðá3Û»xñ"+V”–³ë_—˜˜HLL M›6ÅÆÆ†Š+J6»çÑh@­Vag÷äÝÙÝ:•œ={–+VH’cfœúÈ’G£Q¢<½š;wî;ß¡PfÕsâÑÅ‚W •J%Í£P«ÕÏ4î?éC÷4"²„ÓÑ*ƒÿ¼c¥t Âzâââ~¢ÿσ~£UËWÈÈH‚ƒƒŸkÛRLLLŽz‹+PðVÖ‘#G5jT–‰Î;ÇäÉ“5j³fÍâÎ;ÊeÛ¶mã‡~x¢&+̘1ã‰Æÿ—A||üÒ®¯…°>ýôSÖ¯_/sLÇæÍ›ùòË/Y¿~=îîî?~\¡l {÷î,\¸0WÜKhh(Ë—/WEÁ‚_ž¸yó¦´ñ,Þ½&LÀÊÊŠóçÏÓ«W/RRR8pàÀSC ·oß­V‹Ùlf×®]Ò.w€o¾ù†nݺ帧sN=ÿW_}… ³fÍbàÀtîÜ™o¿ý–   8ÀÀعs':ŽV­Za2™X²d 7n”Ú6lM›6}aI½^ÏðáÃeϲeË(W®` íëë+©ç6l hÑ¢èt:ºuë&ó®ÿý÷ßÉ“'ãǧ]»vܸqƒ‰'¢R©Ø³g¶¶¶ :”}ûöŠNNNìÞ½û…îÝÝ=?•*}d•Ád2§ÿóm-¸rå²òæ¿f¼è.•',OOOY˜ŽmÛ¶1þ| „··7´hÑBvÃÌÉ“'±¶¶¦F KÜÛ·oó믿ÊÚ\¿~=ÿI<§—Ejj*UªTaÙ²eÒFØ!C†pìØ1AaAnGÚ»w/111²çœœvíÚeÉTÏ6“ÙØØ0zôhRSSiܸ1¾¾¾ïÜä(Uªß~û­l»ÌÒ¥K=z4åË—§|ùòÏÝf­Zµpppy[6ŒŸþ9Çî[¥RÉL ¼Q„•œœŒ««%#s||<›6m’¶+$&&ríÚ5âââ8þ<žžž²ÍÐYÁÊÊ ggg™”ð×_ѨQ#)ºcn…———ìØÁÁ­V+=KBBƒ””9tè,¼°Á`È–SåíÛ·¹~ý:±±±œ9s///ìííùå—_0Rü¦ôñyŠ)BHHˆÌK»téÒÙzf8sæ IIIìÚµ+Ë}xo4øŒƒwæŠ{Y¿~3K–¬ %%•Ó§ýÂzÌœ9“)S¦–f›6m"::ZRW¯^··7;vì zõê2ªY³æcQ=<<øî»ïX½zµôÛ'Ÿ|’kÉ*Ož<Òææô¨¨µkצ`Á‚”,Y’ÈÈHéYªU«†F£!66–5j-{ÎÌÁឆ€€Nœ8A… X½z5  D‰|óÍ7,_¾\ÖfºýªfÍš.\XÖN«V–|}C‡eÚ´i²ýs™7<§Ÿ—Š/Î×_ÍêÕ«±³³{+È xm‰r³6‰´¡}û6Ԯݘw B…ZUÄq{Áò–c8°½>ûzë¡C'hÙ²õ[Õ)éy ­¬²Çç‘‘‰‹3*y _éy ´Ä™ ‹àÌ™ ªV­ôL£»½}ö¿¹vvvOµaEG?¤OŸÁÒqùòe9ò‡´NcÆÎÏ?[‚S~øaìÀÕ«7;6cSݺ>ôìùÉÉÉÌŸ¿ŒâÅ‹²cÇ.š4iDÇŽ_ÍÆ[qp°gï^Ëv®–-›Óºõçìßÿ7+V¬ÍDRmiÖìcÙý֮ݘ£Gå±ó7mÚÊï¿ÿ)÷ïß‹êÕ?ÈD¼:þ÷¿ž´jÕ‚/¿l‘«mXþþGøã(œË‰Klé1e×¥ièÔ©7 f¬¨^¼x™åË×еkG‚ƒosøðQ¦M›ÀáÃGYºtÝ»w¢xñ¢Òï»wïeãÆ-|òI#¦NøqäòÍ›·³k—+–güø©Lž‘¨eñâ Úgg§·¢¯Âz  ×ë1™L¨Õj¬¬·Ñˆ¢(9¨ÚØØHžó:³ÙŒF£QBVVZRRR3IJç ºL×®OvÛE‘“'ÏHÒ×ýû¡Ì›·„ºuk¿ð}¨T–„±;gH_Z­Fò™3 FÌf3))©XYiQ«Õ=zœ«W¯ËêuêÔ‹ä䉰RRRññiL÷îèÖí a)xõ˜={6»wï&Ožø ²ìÜ|ùÜ1‚À‚Ó¥z… dÁ‚F4 •*U”Õ+Z´nnnØØØP¡BYYYÉ’ÅÈ“Ç ÊѤICÙ½tïÞ‰V­,Fò-[~gÅŠu88ØÓ¼y[ìÃ'Ÿ4¤víê\¹rMVoÔ¨!,˜±Ò,àææŠ­­Í9וUÂ,ð&®†‡‡Ó³gÏ, +s®¼ÌË%Xx®\¹òÜ[srË*¡9rã*aŽGk0`€ìøèÑ£lݺ°äÞkܸ±ô/Ý'(11‘Ñ£GËêmß¾#GŽ–˜è™ë­[·.×rHHˆtŸ—.]¢qãÆR\õK—.É"ìß¿_¶9xÍš5²ç|ÞøîٕƲƒ^½zÉî%sʵŽ;J¿gÎy8f̺též={hܸñSýµ(È*azòˆ;wîP @ÂÃù}û6` ÌŸN^›6mbÍš5|ñÅܹs‡ˆˆòåËGrr2ׯ_ÇÁÁÖ¬Y#«7sæL<(9hæ&$&&âááÁüùóiÞ¼9üñ&L H‘"˜Íf®]»&*Ù–öíÛÇÝ»weÏ9yòdÊ–-‹••!!'­P¡ÂS#VDDDðàÁ’““ ¤H‘"Ùr¸4hß~û-*T~ûì³ÏØ¿?`ɪ“îo2™hܸ1{öìaذa´hÑ‚¹sç²páÂMÕ0›Í/”8ö]…Éd~û +#GŽ”mäM2gt>vìuëÖÅÉɉ֭[³bÅ † FPP<`È!ܾ}›Ë—/Ë2µœ3fΜùT dÇŽ„……±lÙ2Úµk'K#ö$èt:¬­­qpp~Ë,amÛ¶øøx‰2ôíììÐh4²º¹©©©\¿~½Þ °Ñë&šbÅùä“'ž»víZ>|H¿~ýru‡Þ¿ŸŽ;Ò±cG®_¿NÇŽ¥ Î7nÜ`Ó¦MÒ¹:tHFÈéu;vì˜e.ÂGqèÐ!:vìHß¾}9}ú4;väÆìÞ½[–mhåÊ•2gЧaôèѲ{Iw`]ºt©,m˜Ùlæ§Ÿ~RÞ$o&aÕªU ooo)× “““j$<<œÄÄDbcc‰ŠŠ¢T©RRú(½^ϬY³$•pÊ”)¤¦¦b2™øí·ßHMMåÿû_®ïÐØØXt:£GfðàÁŒ=š#GŽpúôi"""8}ú´tî­[·¸~ý:þþþ\ºt‰Ñ£GKÿ6oÞLDD©©©„‡‡?öOE®]»FÅŠ騱#óæÍcôèÑ’£nPPwïÞ•®÷ï¿ÿ›­çèÚµ«ì^ғט˜Hjj*ÉÉɈ¢Èž={”7IÁ+AŽ{ºçÍ›—Úµkóí·–¨‡‘‘‘DDD Š"½zõâÚµk8::ròäI™ôuáÂzôè!¥jŸ3g;wîäÃ?dþüùôïߟ?ÿü“ÀÀ@®\¹"EvÈprrÂÓÓ“¨¨(<==1™L¤¦¦>u󳓓¢(ÊRÒ0€|ùòeX˜õë×/_>Š)BBB‚tÝ—EzžÃtd&>€?ÿü“;wîd©º¿i¸yó&DGGsïÞ=¶mÛ†Z­¦E‹ C¼í„õ(2ovÞºu+S§N¥lÙ²4oÞ\v^ÕªUiÙ²åcõÝÜÜhÑ¢…”9,,ŒØØØ·ÎîR¹re’““9v,#À™3g|¸,"CëÖ­³ŒXéêêš«ÉÊÞÞ^²Ë¥GL-Q¢NNNT¬X‘é9›4i‚••ÁÁÁÔ¨Qƒ   YŒ;–"EŠ<õz ÄÚÚšüùó³eËÀªà‡~`øðáRd×ô Íé¡f ÀÙ³g¨_¿>Û¶mÃÝÝùóçÓ¹sgɾ6sæLôzKŠ©µk×Ò»woictïÞ½e  ü§‚²ùùq(›Ÿ_-”ÍÏï”ÍÏ (xë¡– Þ(K! Þ)ˆ¢˜#n ^/šàB!,ïÊ”)Arr´Ò¯ÎÎÖ a½‹øõ×_±¶¶æóÏ?¡úqqq²o3lmm(SÆS™4¹F£ääçó§Të Gll¬,ûÐó¢iÓ¦²LÐo3A…Z­˜msZøüc‘ㄵhÑ"zõêů¿þÊ™3g¨P¡:tàöíÛ²Ä|ð­[·&%%…M›6Ñ©S'©, ggg*V¬øF Bxx¸ä÷Ô«W/-ZDÓ¦Mñõõ%$$„   )ŒÉéÓ§1T¯^€={öpðàA©­víÚIΛÏ´iÓˆŽŽ–®[¬X1üýýÉ›7/åÊ•,; |||ÈŸ??~~~:tˆ† Àˆ#pr²¸Ì;W¶Qz„ ÙÊÄ£@Á‰ÿÜxxxàããCDDÍ›7'99YŠPàææFóæÍ¥¡¡¡ìÚµ‹ÔÔTYÆc€S§NqåÊ•7®C£¢¢¸|ù2Í›7gøðá4oÞœ½{÷ráÂîß¿Ïßÿ-{ñâEiïà±cÇ8~ü¸¬–-[&e§y&NœH™2e¤z#FŒàøñã’ó'€ŸŸŸDjéÛ£2‰ ³fÍÂÃÃCv/}úôy«_„±c'ùZ®ýÝw½ññiŠë^{?:tŸ&\¾|5WŽSŽKXžžžT¨P¾}û¦é©FÙ—:óàˆˆìííeõëիǾ}ûÞèÉ_ @j×®Í!C¨]»6¿ÿþ;ñññÙJÝžùœqãÆáîîÎþýû;vìcç¦GI9r¤loæ!CžybÅŠQ¬X1Ë}ëÖ-òäÉ#»— .¼Õ„uõê ôúìåÊóñiL@@ÎE¨X±b!üÍ‘#ÿ¼’gÝ·ïÿüs‚1c†>VV¿~Žù+[sõ­ ¬G_:___À²œ¼`ÁY€ .P¢D EÎŲI<..NÊe–ýúõ£aÆ4lØð•ÞÏÁƒ¹xñ¢tܦM›·ª¿Žñï¿'¨RE®v8àÏ™3Q3ZµjA‰Å bïރܿÿ€éÓ-q¿ù¦5رcׯßÊ$9µ'O·l¼/O.[¾| ±±quH%0hP_©lÁ‚e¤¤X‚YÚÚÚЧO7©læÌÒ¾Qgg'ºuûkÖläèÑcܾ}‡éÓç‘/_^:vü€ÄÄ$/¶„‚jßþ+ Ì/µý•+×KÇ¥J•ä‹/>`Æßxï½R:dÙŠV¾|š6ýXö›7o'5UÇ·ß¶Í}„•DQ䯿þ’ö×Ý¿ŸÏ>ûLvÎúõëùúë¯9r$ |§ëÌ™3ÄÇÇ3mÚ4é·¶mÛûÌ,×sçÎåßÛß IDATã?¦@O% }ûö1`À€'ž3lØ0&Ož X«¾­‚Ïœ äàA¼½+pâÄþ•Êóæu§tiOÙË?mÚxœ(]Ú©<](X°Á>cÆüÄ‚3^ø>çÌYLž11‘Ù³1`@/Š-LppA)]Úgg§ 2Ш)]Ú“•+×áë[[FXcÆL¦aÃzÒñÝ»÷ؾ}'_|ñýú ¥{÷ïøàË|¹|ùjµšÆ?’Î_¶l511±¹°¬¬¬²ŒS¥R©¤˜íé¶®ï¿ÿ{{{\\\èÝ»7·oߦK—.œ}9r$Ó§O§AƒÔ©Sç±ú3fÌ®¹jÕ*¦L™BÏž=¥+5bßK­Fæ&DDD"*>ÿܲøÑ¸qNž<‰xòck›AD³g/Äh4P¼xQŠ/Êôé󤺙Q¤HaÜÜ\¥ãI“f¼Ô}ž>}Žqã†Q²dqÀâl9{öÂ4›ç)ºwï$Ip¢(Ÿ±ï²\9/éï{÷Bñó; ©|F£Aà±g°±±áóÏ›áïÿøªñÙ³çY°`ºtüÇIv®’%‹óãpp°˜wÖ­ÛDpðYý-[Öʲ¼çÂòòòbܸqY–ùúúJúEæðȵjÕ¢V­ZoäËPªT)&L˜ ……ùᇤò®]»Òµk×,ëöë×ï¹C@·mkùb¥¯Ä>j‹êß¿?E‹•®ý(jÖ¬ùؘ888°nÝ:ÞØÚÚJ’Jpp+V¬ãþý »ëÍ›·ŸÙFPÐ%Ö¬ÙHTT†Sjæ¿ÿk‚ IKýµŸß~ÛžIÂJ’žï?±+i´Y= ..9ãë§øa½Å0›Í,X°@ÊLT¢D‰wNÕΞ½î0'OžISO“?^&N™&%ïáÀÿ'Ö:uC‡ö篿öããSƒ-šIRFV’Ê…¤¤dV­ZOŸ>ݘ2e6ü.!ìÑc‰‰IYÖ»{÷>GŽüC»vÿmÄ•Y³’œœÌÈ‘?(„¥ kx{{Ó·o_$5<»ÁßføøÔäìÙóøø4 AƒºT®ì ¨øä“F̘1_*kÖ¬1*”“-$-X0M*:Ôbüî»öŒó“dŒïС-ÅŠÉÖýtêÔ›sçΓ””ÌþìÝ»;;[¦LKïÞƒ¥½‚ bݺ¥,\8ƒvíº”d!";;;V¬°„_³f1 |&Ý èÍÞ½3i0Õ8s&ŸÆ)RˆÙ³'Ká矷#,,‚ÇR³f5I œ4i”ôÌï¿_‘ñã‡àèèð˜YÈh”ã<|øbcã^š°”xXY@‰‡õê%ÁWËÎÎkkÅù5·@¯7H„›”xX (x£ñÊ kÆ øúú—ey¿~ýðõõeÁ‚•uéÒ___i5KüñÇÏL³Õ¢E %[¶‚·¯Ü†Õ¶m[Ú´i“eV’‘#GòùçŸ3sæLæÏŸÏÖ­[ùòË/KZõ^½záííͤI“Ø¿ÿ+w¦ÌxðàÁ3Ý ¶nÝú܉"’““iÙ²%~~~o‘êiz̶¢àõŽÇk'¬¨¨(Ù’x©R¥$Ñû÷ï³yófzôèñØ‹f6›Q©Th4ªV­* {’¹¬FÏLÎðºÍÚµkøê«¯øõ×_©S§|𡡡ܸqƒºuëpéÒ%L&“´ÁûŸþ‘e{nÚ´)^^^ÙºîÊ•+%©µmÛ¶ÒjàüÁÍ›7)W®gMÓ3mݺU2ÎvíÚ<ÈÉ“' –ò!öéÓG–öëMDjªŽ«WƒÑéô [¼nII£¡dɯŸ°´ZíÿÛ;ï°(®.Œ¿Û€]Ò‹€A,‰ Ñjì&öhlQõ³ Ø>ÅX1¢ÑÔØ»‘(–Ä/j4c$FˆAEBPAÁ¥·ew¿?Ö½0ÒÄ œßóì3wçîÌ™™wî½sÏ9lÞ JRyêÔ) 0ÚÚÚ°³³Ãš5k0vìØ*[꛺"ÊÞxšFJJ Μ9ƒ©S§Âßß½zõÂ/¿ü===<{ö §NbÇvýúu¢uëÖˆˆˆÀùóçѲeKV×Î;±xñârY†^dË–-˜>}:³»¿¿?‹Šaff†‡âÈ‘#»9s!!!ðñña­¯eË–aݺu066†­­-tttXšê[VSîßwwz9R÷=ƒdÍèŠÅbŽKGZZbcc¦¦¦:t(k¨ÉÉÉÁG}„‡âÔ©SèØ±#vïÞͺ<Ÿ~ú)îß¿°°0|øá‡fAÖ$1tèP¬_¿;vìÀ•+W‘‘QåM¯vŽ.k»:ÀÐаZçç±cÇb̘1,¯ :¼  šjbb‚›7o–Û~Ö¬Y2dÛ/õvï½÷š7oŽ}ûö±.yCÇã“ÿªF´vó5C°öïßK—.±åÄÄÄr>ƒ/Ò¤I„„„`Ñ¢EèÓ§s˜Ty÷BBB0}útLš4‰åÜkhtíÚéééajݺ5¦OŸ^­ó³«š`llÜ`ZND#éJ¾é ÷íÛÇ"XfggãÓO?%+¿wïÞ…X,æ´>GމŒŒ H$’*·ýá‡ðÑGÁÌÌì­í_@@Çň „`-[¶Œ9ÓêëëcÀ€̧)** Ó¦MCBBú÷ïςܩÑÖÖ®´¥ ££óJ­ˆÚF 0~µø¨÷½M›6gö騱#„B!ø€S–œœ Ö srrÂýû÷Éh ¥K˜™™‰3gÎ==Õ«K¥R‰àà`ôìÙ—.]BRRœœœXÖãÇs’ŒºººÂÝÝ€*ctXXiζ֭[£uëÖJ¥øí·ß½{÷ƹsçàîîWW×:3hVVK>¡Þ§¶mÛ¢E‹HOOÇ£G˜ûM||<är9œ¨æ©Ý¹s‡Õåéé {{ûjóòåËœ„½{÷†©©*ÓŠ‰‰I¥s¹‚ƒƒ9­à!C†@,ãúõëprrât}þøãôêÕ«AÞ(,,DTT¢¢¢XWpĈ˜1c¾ýö[A("22»ví"åh(-,¹\©TŠ7–ëFDDÀÇÇaaaJ¥8þ<ŸŸM›6A*•²ÏéÓ§@•¨lÙ±cǃÄÄDìØ±R©kÖ¬T*Å¡C‡PgMJJ¶mÛ8ûtäÈ>½zõb.•¡§§‡þýû£wïÞl‡‡fÏž }}}tèЕ988TxoذAãŒûâ>¹¹¹á¯¿þbÇÒ²eK…B$$$ÀÐÐÀÊ•+9-¬ê"0ôë×ëÖ­CPPU6鲩í—-[†àà`ÄÇÇ£wïÞØ½{7ìíí1~üx¬^½š9[8ZZªŒ2>>>X³f f̘CCC|óÍ7,…=AÔ%oÜùY¡P °°- –uV¡P ¤¤„Ýe‘Ëå(***UR¡}¯¤¤ÅŪ°¶|>|><¯\}ÅÅÅ …5Ža^–×q~®èËî“L&ƒL&cǨþûb ŠÄPQìû)**‚\®Š-‰ —ËYĈ²e€* ƒÚ6………l K[[2™ŒmWXXÈ©ãmfÖçg¢vÑçg>Ÿ_iü&>Ÿ_¡X©…­²í„Ba¥7î‹õUVmQÑ1–]‰D•ÆF¯ª¬*^“²uT%4jA*{**{›bUÛ(•J†‡¨;ärEÃÃ"ˆ·›[3JÉuŒ¡¡ AT…X¬ƒwÞiÖ(Ž5++»A Ñhàñø¯5¶IÔ=µ~ö‚ƒƒ1kÖ,äåå‘õßaaa¸víZ¥å{öìÁ¬Y³Ø§²yUœlÜÅÅŘ5ks}"ˆF)X-[¶Äرck<»fÍ–.Œ(åöíÛ¸wï^…eû÷ïŸÏÇØ±cÙgîܹœï(•J:t¾¾¾ÈÍ-};, 1vìX¼ûî»5ÚŸ„„Î|.BÅŒóÑ©So¬[·…Œ¡I]Â7nÀ‚Ͷ633c±…233Ín”²ddd 22’-ÛÚÚÂÅÅ……… ÃåË—allŒ¤¤$8::jln¹¼¼<æ–äáá7nÀÙÙvvvÈÊÊÂÓ§O™³sJJ  ¬¬¬¨&Å–õákÕªÌÍÍ_êw/_¾Œ‚‚ö»ÐÒÒ‚³³3Úµkˆ‰‰)÷fððáÃJ¥èÖ­[¹ó˜““S.âFtt4¬­­qãÆçÝ,Û6** ¸|ù2þüóOˆD"tîÜ™î2›7‹ë×#ô#C“käÈ‘3f JJJTM8>yyyèØ±#²²²páÂüôÓO e ±uëVÎ$µ·¼¥¥%.\¸€ääd\»v ‰‰‰ ±‚•€yóæ¡_¿~ L&Ãßÿ &àÑ£G8~ü8¨f¥bòäɸÿ>8À™3Â&ÏVÅÉ“'áææÆ¡¡¡Xºt)'äodd$Ž?ΙzàÀäççcúôé¸xñ"§Îk×®!,, ÎÎÎ?ÆÕ«WÃÌÌŒ“açÑ£G7nnß¾+W®àÉ“'¸pá$‰Æ Ö_… $ä2[2dZ¶TEùøý÷`\»VšxvÔ¨aprrÄÍ›‘8sætu%øøãÞ8zô¾øâ3ØØXáòå«066ÆéÓ¿#?_•$tÊ”ñ033­v_öìÙ””Ò@óçÏbSa¶lÙÌÌLöpX¼xgÛ[·nã×_ÏbêÔ 055!Áª)‰Æ c)×;†ÐÐPtìØöööX±b ᡦ  W¯^åø &$$@GG†††X±bž={Vo©¶k×+V¬€§§'BCC1þ|$&&Véü ¡PȇÈÈHhiiáâÅ‹Çp5?ÿü3ï °ylžžž'æäädìß¿sæÌa-¶~ø2™ “'O®p¦M›†æÍ›#$$¤\Yûöí1jÔ(ª ¿Ý»wǸqãðÙgŸÁÃÃEEEÝ-¼~=—.…âý÷=غ]»±dÉ<˜™™ÂÎΆÓX»v3Ö­[‰ë×#™™77WlÞ¼ ýû÷Á²e«°wï„„„ãÈ‘Ÿ±d‰/ÄbU+vÉ’•ع³jŒmÛö I=´kWšñÛ××7~ƒ€€M°³³³³#ë•øú.E@@©moÞŒÄÒ¥_cèÐA$X¯‚žž«—ÅÐгgÏf9ð {÷îåÆ[2½zõÂýû÷96˜8q"ÜÜÜЩS'üøcù®„X, ŠVÙ¤Û‡Âßß[·nåt³²²pèÐ!P9L{{{ãäÉ“ÕîkÇŽkÅ&ùùùÈÌ̪°L&+yåzU|8s ~SáÂ… èÛ·ï+Œæ":ú'W`Yx¼W{gäéÙÏžI±mÛ¶ÎÞÞ>>“‘šš†ÀÀCHOÏ`e‰‰I/ٻЩ²]Gžà´ŽúõSùš®Z凥K¿æìKß¾=1hÐÇlùU½#H°^‚ØØX¬\¹7oÞÄôéÓѳgOLš4 <1118|ø0û®† –?ÿüsìÞ½999hÖ¬¦L™¢ñÆ-Û-`ܸqKKK$%%A(âäÉ“‡i— 3­­­ ___6è®î®;wW¯^Å´iÓ8]ö—Éâ¼téR„‡‡#-- <À®]»Ê‰^EXZZÂÅÅãÆƒH$˜1c^ÉvÙÙ™033†³så=‚W¬¨¨»P(ؾ}}™qª‰J¥¸~=ææ¦X±b1à—_ÎàäÉ—›Ú±aÃvtïÞ…ã|þ2,Z4mۖǵsç>̘1ææ¦Ï»ß tëÖ#X—.…aÏžðÍ7ËaeeA‚Uó§ÅQÎrŸ>}XsÚÎÎ_}õ§QŸX---L™2…3GÈÀÀ€s³¾ÿþû°²²Bqq1ŒŒŒ46s‰‹‹ ¾þúëçOCUËB=¾¤££wªI“&àñxÐ×ׇ––fΜÉXÀÜܼҮ^é6 £GFff&{i¡~ë8yòd Æuô­lâäæÍ›9öž2e '˜ zxݺuœ$¢€ó 100ÀôéÓñôéSðùü: ¤XÎÎÍðûïÁðòêSfÌî?°´´@¿~}°nÝV6pàÇèÐÁ<‰ÚÚÚ011fbgbb\¦E<ÇGNŽÊaûÛo—³²3æ#<ürrráåÕÇ„™™)–-[€Y³àáÃDöÝsçN@"cȘ2e6ó}äñøøñÇ}/´ÌŸà?þÂÒ¥c^#¥ª¯JU_»T­áôé³prªÚ惼P“é|‰ÚÚoÇ9> `š7w Aý4¦Rif½¿.*ŠÖ@~ AÐA4&ÆŒþRc| A¼d×SÎÆSß4ê ¢o«~BCëàÁƒHLLDûöíË%^øþûš ///rùxNDD„B!sªŽ°ä¯Â©S§Ð¹sgVX¾aÃàã?®±âÛ¦°°÷îÝGQQ1]8u-}7nÜÐ8Á€øød´oß‘£Žyü8é•¶{ã‚UTTÄɲ¢¯¯Ï&xæççsœ{ Ù+x@åœÛ§OtíÚœ4wîÜa®9>dsŽ4²Çïàà€„„4mÚ&&&(((@vv6KÄ™••…BÁ¦h¤¥¥!==ÕeccS­¡š¸¸8÷ÞÑё͂ôè{Í^ÖÖ€j|Y7oÞB¡)))044dc2‰‰‰°±±aS"d2sbçñxhÑ¢«£wïÞHJªøb¼wïsyQ;f×6<vvv¤uL^^ŽfÖ÷ß›7KG1fÌ´nÝÉÉÉœÙÔffføüóÏñÎ;G=¹²"ÊN„Ô4âââ0lØ0xyyÁÍÍ ÑÑѰ³³cÎeŸùåæüüèÑ#ìÝ»ÉÉɬ.gggøøøp+ââÅ‹¸víKþѲeKÌž=QQQ byÙ<¯ëׯãðáÃÈÎ.LÙ¹sgŒ7+W®ÄĉY vÒ¤Iøù矡§§JpäÈ–ÏÇãaàÀèß¿•ûøë¯¿âäÉ“L°ttt0tèP–fŒ êD°‚‚‚ÊyŠ«ã,¹¸¸`÷îݬlß¾}øûï¿accܼy¸xñ"K –žž___„‡‡#)) ;wƼyó4Ú¨;wÆ®]»8ÎÏqqqUºmܹsB¡cu…+W®T8;}Û¶mT“7W­ZÅ&âzzzböìÙ8{ö,<==1hÐ ª`‡?~ à†§§g• 5&&&ìü¨Ÿ«¬€€üùçŸ,ÑE||<üüüH°Íò··çÜ€‹/fË©©©øòË/!‹±hÑ"¬_¿^^^èÒ¥ ûŽ-Z„åË—cøðáðððh'¢K—.ˆŠŠâ8?Ï;b±nnnX´hQ¹mÔA½¼¼^ʤS§N,ëöëðñÇ¿ò1ªE[&“5ØsIÔcÁzüø1òóóѬY3,Y²„98çææ²›ÏçÃÅÅFFF°±±á$J‰DÌÏÎÎÖÖÖ òDäææbðàÁøòË/Ùº‘#G¢]»v°µµ­RnÞ¼‰¡C‡VÛu¼uëÏz.]ºôJñÈ.]ºÄI%¦)Ÿ²åÓ§OC&“ÁÝݽÜ؉':t€¥¥%[̱÷ÀÙ8`~~>ËòÝ­[·7ò !Áz†ŠùóçsZƒ ÇÃG}ÄÊRSS´q§OŸÎYvpp€žž³zP;%%8|ø0 þ Ê·qeIMMÅÊ•+Yð?u÷ìÃ?ÄÉ“'Y½I“&l`¾oß¾8{ö,Μ9ÃêQ¿=ôõõaaa &pÞ°5oÞ¼Ú®ÞàÁƒñÉ'ŸàÑ£GlÐ]=Åáý÷߇¾¾>s¶vrrÂàÁƒÙ8›‘‘gÐ]J¹gÏž033coÝÜÜØ »ŸŸ,,,pûömªA÷>ø€Ó]ìÝ»w¹›~äÈ‘°··ç ºkýû÷Lj#زºë‡¹sçB àßÿżyóˆ­[·ÂÈȈ=˜bbb0kÖ,ìÙ³çÎìY³8±á¼¼¼0cÆ 6v×½{w&t³gÏæDê jI°$ :uêTa™¾¾~¥eª|ÝܬYýÈ''‘HàääTé8ž••U¹ée¿¦¯ÜÕ"nffVa¹««k…ßW·à*ãÅ9Tꉋ‹ «ˆ÷ß¿Ò:Ë ›¦ñÏ?ÿ`À€ì-ê¬Y³ðé§Ÿ")) ¬¥äââ‚ÿý—=ˆ¼½½ÙùÝ¿?Ö®] صk«ûáÇðóóÃ… þþþ˜0aƒÜ¹s'öïßOj¤ cX¡é¸»»ãäÉ“ bÂìééYaðÈñòòbQZmmmYž²ãcû÷Ÿ'О‡‡Ûîe'ý$XOOOxzzÖx»ÀÀ@Èd2¬Y³€Êë`ñâÅl®a^^Ö¯_™3grZÝpqqa]Éàà`øùùÁßߟN Qßô3IDAT„‹%Õ|‹@ùÚ¿•™™ @Páx¡‰‰ 233¡P(Àçó‘’’ÂÞ¦¥¥q&=[[[³‰¿©©©X°`6nÜXÎ[!99™3ÿÌÖÖ–$XD=ÄÜÜ­ZµAI‰¬Âò'ORñ áÓ+䯏qãgPhÃÛÛß}÷öîÝ ¡PˆØØX6awþüùXµj{©½{÷P…˜vrrb™ÀÔÔ À† °xñböêîݻطoô—€øIf¦Ož$áÙ³´ ? ÷!—+ÞÈoõèÑíÛ·‡B¡`Ÿ²S0æÌ™mmm( L˜0“ÜvÑ¢ElÖJ7n,--9u*¥û»pá ‹ Q)(ȃH¤ @…BÎ)»?%%2ðù¼7ö{ݺu+—ýº,U¹,Mœ8±Ü:///Ž×‹èééU¸A-,¢ž¿\*¯¢¢"hi‰˜#6A‚EÔÒ*â,A*Í"Ã`„æ‘‘ñªTZJ¥·oß…>†‹ 4ââbÄÇ?€@ @VV6lmmÈ(t'4…B‰'OÒðï¿ÿÂÆæõ¢u(•Êït_xÕ7¼¯-XJ¥’¹!PPP33q¶‘J¥ Îu‰‘‘ Z´(õuÌˡÇ¡šÏרÞV­œ!“e“ëüü¾šóûk –——;‚†Õ³40Э4¥{E˜˜ÂÐP¿FÛ\x¼ÒYæææ¦è×¯× Yš+Šâ!¯ñ“±s—PKKÔèÈçóI¬Þ°=ßVJy¢ž_d‚ H°‚ H°‚ Á"‚Ðpj<讣£‘¨áOßR*•ÈÍÍ£+„ jȃ  ¯ö{öövèÒ¥ÓÛ,@À™ Ó+551Hté*$ˆJÐÒâ£cÇ6l977––MŸ—kÃÙ¹9n޼ƒhii£C‡¨iFšé^h½óŽ+ÜÝÝÉQ wïF•[Çã•f211Aqq>Š‹e‹U²ù|ÞóH5›KGcXA¼5tuõ ««‹’ìššöZõ5 ÁŠ‹{€yó–ÐÕCµŒP(€\® s­§§ ;–ð÷•ê{¹~=ÿüÇ–»wï KK @XØUÄÇ?de}út‡©© ¢£cqúúMàæöÂï£ÿ>00ÐÇ­[·q÷n LLŒáà`‹7"ñÉ'ýY3òÌ™? •f²:GŒ¡Pˆ°°+pqq¹sXssÔ¨a€¿þ Áµk7qãÆ-är9ŠŠŠ!‘H^©NþëˆÕٳ瑕•Í>6lGaaþþû2þú+„S¶fÍFÀ©Sgr÷ï?À÷ß!++ª²Ÿ~:Ž7"p÷î=:ô¿çe›?þx 11±œ:×®Ý Ø¶m/æÏ_ÆÖK¥™øî;U¢€üü|äææ¢¸X†¬¬ldgç”;–ß~ûcÆLBV†#ˆ7…•• +5––ËåÉJj·…÷††˜6­4.õƒ ÐÒáîÝØÚZaìØ‘¬ÌÓ³ûÿ£záw\°fÍwøú륜²AƒúA,ÖÁáÃ?Ãß<=ûÀÏïK\º†1c†£uë–eZmC°`ÁÀèÑÃЫ—*&wII zô„9s¦áã{ÃÑÑÉÉO8ûZ–±cG G®055¡«Œ Þ|><^Å!dí‘[û]ÂiÖÌá­aîÜ%hÒ¤4–w›6¥áGœ_=•½™™)ÌÌLé*#ˆ7¦.ÈÊÊAAAÅs£¢¢Ñ¡CǺ¬~ÄðáCÞš¶m[‡÷Þ{½´Þùù8qâ4FÆÖ……]Åï¿Ã×w%7 ˆ7À³gÈÉÉF~~Å‚õª½™W¬nÝ:cýú­èÕk0[7|ø… Л±ÿV6eÊxÎö¶¶V˜7of…u»º6‡·÷κ™3§Àßÿ[¤¥=eëN:Â&¢U… ÜÜ\Ñ«×`ˆÅ:X±‚ûÆ0<üüý×ÀÛ{ A¼ttÄððhWe—ñUàµêä®\þûv¤d§a÷'Ë|ÅÅ•÷/uuuY ,™L†’’ÒW”ZZZ,˜_q±ŒóúR[[ |>%%%àñx¬¬¨¨ÚÚÚÉJ pcK©ËÔÿ+¥3cÕoôŠ‹e‰„l¢šê»Åœ˜Jr¹ÅÅ2ðx('r%%%ÉJ ££ÍêP*•ˆ‰¹‚M%ˆ*¸{7 VVeº{wQT¤€••d²â ·¹páoŒ7AåS.^ Å,ż?7âjt$þ7uãëu E"D¢Šø©D­|YEn=jAªÈGQ]öâÿåëÅí¸àÄbAÅÍL¡°Q¸Dm¢T*¡TVìzS¶¡Sh¦;Aõ†7+”J Eƒ7LeO‚ ê‘`åç( ËQëP— ,‚ ,‚ H°‚ H°‚ H°‚ Á"‚ÐPÈ… ˆ·Â­[QÈÌ̬°¬¨¨ˆ‹ Í ))ÆÆF•†Bvtt$Á"B3°±±C‹®•ºñ• E‚ED’žž†´4}”‰øÄ!66ŽŽö5®—Ý ‚xãdfJ¡§gXaYdäW”I‚EÄ[!&æ.D"n\ºüü˜˜WûŽ‹ ˆ:E&ãê“J3+LµG‚ED¢P( •J!‘4äää"%%ºº’W®“‹ ˆ·FNN6ž>MÇGqq1Œ^«>zKX yyyHOO'CÄ+ T*¡PÉÉOk¬·…Aðùäç?#cD%ŠË­kÚÔÍ›»²e@„nÝš±¬T|¾€ëM#kC,Ö&CD puuBÁÍreiY>³:WóÌ9$XA¼Q´´ÔSÞ|"t'¢Þ@-¬JÉJt¯Òïðx€R‰JÝ¢¾Söú®*ó]«V-оýÛÏN‚Ué‰R //­Z¹•+ÓÓk]]]›!>>îîïC&+"£ ì¡-CBB¬¬¬! ÷d²’réç›4ÑGÛ¶mÈßú>‘`Õ=½&ÐÖÖ‚¹ySäççàÒ¥ H$ÉŠ––L"©©O ++kää<ƒµµòó —+’ò„º„šŒ³ó;(*ʇH$D~~„htA(äC"‘@(´AAA22žÖê>`U@ €#D"äòBðù€\^B†!¹pB(äCOOÖÖï!&&†KÐÖÖAvv&´´‹Åd‚xŽòù|tôm¤§g’`iùùyHJJ‚AdffU8O©4ééÏPPP[[›Zû]š‡U zzºËÐÖÖFTÔ]$'?Fq±Œ C4:är9JJJŽììðù<è×ê>P ë%ÑÒÒ‚––JJä¸råZ·n‰ÜÜ\H$!)‰Þ ‹ÌÌlöjjrrr‘““˘…ÂÚ—¬*‹%ppp*·ÞÁÁ pqqEÓ¦æøàñ´È`DƒÂÈÈvvŽH$àóµáädUéܫމD8°/LMͪøV©˜yz¶'£ ÖÕ|CA‚U—ðx<˜™™âm8pñjР;A$XA$XA`A`A¼!ʽ%T((.*&ËQ§(Šê+%%7#ÈZAÔ)ééÕ –%,,LÉZAÔ).\x™.¡%%ùd-‚ ê¸KX>ö ºQo Á"‚‹ ‚‹ ,‚ ,‚ ˆ7ÅÃj€L:&6jØÛÛaÇŽïèb Á"4„„Dœ=ûs£¶Aß¾CéB Á"ê))iHN~ܨŽÙÚÚ ætòI°ˆúFZÚSðùüç‰2>|¾tâI°ª¿P2 …õ5¶»±±¬¬,Áç ü9DàóÉ êáðÁ9*ÑÁâAGÛ|¢AùÉãT„ H$Úõöx<>t´ À4Ì„¡‰¾6ÄbQ½nŠuôÁã7ÌsôoìXX€ÇãÕ} ‹ÇSB$j˜‚•˜ø†FH,êyw©áž£ØØ¸µtX,©÷çHØ@ÏQTÔ-˜7í àõZ‘4‹ ˆú#êd‚ H°‚ ¢`y{ÏAXØ8p„ÎH-!“É0mÚ\xyõaŸ¤¤×Ÿ³¥P(qìØ);v eÍ® üý× >þ!gÝøñÓ^jÛž=¡cÇøí·?H°ªãñã$'?Áöíß¡S§;v$nܸ¥’.ô·ÍW_}ƒáÇ $äwöY»vÓk×{âįˆˆøø‡8qâW2t-˜˜„ÂÂ"ÎºØØû/µíùó¿`ܸQJ3ëűÖéªÔÔ4(•JX[[²uQQwѶmöúóûïƒÐ¾½; Ѿ½ûK>åØ¿ÿœ›ÁÜÜÍ›;ÓUýlØð ûçÎ}HIIcË Ζ–V•Û>ü32220w®`Ë–]8|øgŒ51nÜ(ðùªg¤Tš‰¿þ Á!ýQ\\ŒÕ«Kýþ,,Ì1eÊxvþ'LË :‚Ï?M'«¬_¿99¹--.üoµÛ|ÿ}zôèŠÀÀC33L›öŸÆÝÂjÛ¶ ÜÝßÅœ9 Ë4e?c5´jåSSXX4eë‚‚~Ä·8u•­ƒÇã¡e˰¶¶„‘‘!]±5dË–ÝÐÕÕżÏ>óæ-©v»Ã‡bôèOÙòèÑŸâðᣀ}ûrZΙ™Y8vì$@ p~KWW[¶ììÝ{ ÌƒHÎn ‚Ëþ3}ú a¹\X¹2ŽŽö̶mÚ´ÂÂ…Ë«­o×®@øû¯aÛá»ï¶5î–šÕ«—±§º‰‰1†‡„„D´léŠôô |ñ…7·cĈO0w¹B,Ö¿ÿ̘1°iÓNØÛÛ¢G®ÈÉÉAnn-òÇîݛ誮„Ÿ~:ŽM›v ''‘‘¡ˆ‰‰ÅĉcѶmöåË¿y©ºnߎ†> ++»\ùæÍ»`kkwßmÅyÀ˜›—fj’J¥ˆ‰‰¥S6oþï¼ã–{÷ˆŒ¼ƒŽÛÃÔÔPPPXîa_[·®…ŽŽàÞ½|‘ 3Ê”)ã±aÃv( ܹsGŽüŒI“>Ç¥Ka‹uàîþ@$aÓ¦5l{?¿/ÙÿïâäÉßв¥+¢£cðøq 6nü†®è*>|†OÏ>¯]×G ­­ò (***W^R"cO5?þx !!ál9==ff”j®&ˆÅbèêVgÛwïÞÁÁÁ×w&[çîþ.är9||æ¡C‡öhÖ̉QНïLøú.Å’%+Ø:uÀ;ÿE˜1c>'`PЮjë411æŒ?òù|˜˜?oEíÃÂ…þX·îkÈå%˜?¾ûn5«ÛË«´u·páqùòU¶Oê2?¿/z…NÞ B$âÞÊêê¶më0~ütdff²VÓùó¿°ïõì9iiéàóùøé§ã8qâÐó.!íÚµe¶·²²ÄöíëëüXy­:¹+—ÿ¾)ÙiØýÉ2„ŸCqqnMª€®ÄZÚòy1„ü}†F°¶®?¾„}ûÅÙ³?#*ê. ôáàà]‰DZõÏOíÏ?/¡{÷.TsÇz÷‚ ¸Ó%Μ†[K›²h jÔø|t%M4Æ—ÐÓ³§Õûº9|={ÕÌ—ðâÅPüwÁRÌûs#®FGâS7R<,B³¹?'OžaGŸÉd”F ¡Ñ|ñÅhDFÞQÉ÷È(µÀÞ½›I°¢¦ˆD"´k×– Q˸º6×Ì®3‚ U—0--—/‡4HI¥™èäÙ¾ÞGBÂ#ܺu³Až£§O3àÖÒ¥ÞGtt,þùç^ƒY‹ ˆ:§é'ïU.XŸy¼ÉHAhh—ðYn‚#B‘WD­*‚ 4“'ªî!O #RêXS:w‚ 4›ÂäLüà} e²Ž9IEND®B`‚snd-16.1/pix/pyr03.png0000644000076400007640000001025611147553270012627 0ustar bilbil‰PNG  IHDRÈ0g pHYsaa¨?§itIME× 6(U\™MIDATxÚímLS×ÿÀïŶP*åY„*ȘŒ‚E×ÂPyhuqS7“qÙââ’-{·øb,sÙã6¶Ûâ–9˜ºl… H J²j©P(¥P…Òöþ^Üß¿ó¥B)}ü~^Ýö´·‡s>Üó½ç领!`iÜ €Mkjjjå'º»»•J%”`¦XwïÞmhhX–üèÑ#AnÞ¼ %¬ ‚á(;;»¢¢bY²T*e³Ù‰Ã0EU*USSž¤R©†††.^¼håëõúŽŽŽ‘‘û,Ðôôt‰„¢¨‡‡ˆµz2 Õj /}}}Ùl6~ÜÕÕU\\l5±ÔjõßÿýäÉ77·¤¤¤äädû,І††¥¥% ÃMKK£ÑhT*ÕÅÂ/E}}}ûöí ¼~ýzxxxjjjrrò÷ßïãモ¨­²866& —––bbbí¼@_yå•eïˆD¢ŽŽŽ™™ …B£Ñbcc]A,Ôì®®>ú¨®®nS•âóùþþþqqqNð?77'“Éúúúð—$)::ú¹çžsŦІÈåòÁÁÁ¬¬,àeM¡P¢£££££ñ—F$UTT$$$„‡‡ƒXÖ§š››ŸþyƒáĉDŠømShhhll¬sDýv'Öää$ŸÏg2™d2ÙEâÜ„„„„„AžŸ¯Óé@¬™ššêëëÃï«óØ»wopppuuõää$ˆõ?ÚÚÚœ{ÄÆ:Ðh´¼¼¼ÞÞ^{sË6b C#h)˜Lfoo¯P(tu±ººº^|ñE²n‰DûqËbI$ç›%bDEE‰Äúúz{XÒg±㎭ڿ[t:½±±Ñö÷­f|g#C:³o6T*•N§×××gdd8Ø‹N§³Ùì•“»Ÿ †a …Âþ‡#//¯;wÚ6Þ²jSØÞÞ¾wï^¨x«Å[6t˪bÉår¸\YÓ-`X»á´bI¥Ò°°0¨ok½eË›¸e=±=z´gϨlë»5>>®R©œS¬……_rnCX,—ËÕëõN(‡ÃÉÊÊ‚:¶ØÔ¥Å6Þ[áéé)œJ¬þþþ¨¨(¨]Û>??oµy§æˆ¥Óé´ZíӻЀXƒÁxðàuFÍK p8œÖÖÖ5~~ii‰H$B½Ú‡ª©©±S±sss׸²T¡P8újqg‚L&ûùùÉd2‡±ø|>N‡µètº@ Ðh4Ž-´ƒ®Ù n®X0ŒcŸ„°°0±Xì¨bÁ0ŽÝßÓÓãbéõz77耵_¢¢¢úûûO,´sââↇ‡gffL,›ÏŽž ƒÁhkks0±t:Ý–-[ òì2™044dùû3¾cñý±òÒK/UTTìܹÓöW¬µ,¦‰D†}§;gÇŽÃÃÃŽÑŠÅbgÝßùHJJêèèp ±4 ‰D‚:s’““y<ž½‹µ¸¸~8!!!–} Ú¦ˆÕÑÑ‘””µåXÐét>Ÿo×bBU94Í‚Ói`ÈØ”ÛCË‹533ãj}„ÛCkˆí 4ˆ›"tBlÆô`9:øƒÀ7øüQ«î8¹¹¹UUUöÕBרs°ñµ‡k~~ÞÓÓ*ÆÑ‰ˆˆxüø±‰õàÁØ³Ï ˆïíí…¦°0(ŠR©Ô©©);ênœƒ”””ööv °0d2Y«Õ.--Ù^¬úúú@•8 ‘‘‘¶ëŸþ¡P(PNCtt´H$2ï»æô®ÎÍÍi4š•ëÑ0 s Ç¬kòÃÜ^xs®XOž<éîîÞ¼E´€ý`öjisÄŠe±X0GZCkÄX</99jÂùP*•6 ºFó:´,&ÖÄÄ„¿¿?TƒóA$ÍèÍ‚RàÙìÞ½{½C‡ ðl‚ƒƒGGGA,ÀÂP(”¹¹9ˆ5<<¼cǨ¸hYX¬ÙÙY///(}'f½{–Zf1Åàà ?;7žžžóóó›{ÅZ¹˜Væ¸>>>kŸúÁ;°V˜Lfss³õÄ‚.‚››ÛÚÓj± r6E,x®‰ëpðàÁÚÚZ+‰5:: …î ¬½§‚wÀ^›BÀ¥Xã>GkãÛ’ŽÅ'+oT,X@ájx{{OOO?ócÒ測[ÞÞÞ¾b==¤Ãáp²²² ¬]еÌûƒàX7ããã `yH$’F£± ãçç799 bæ™ YA,À|}}U*ˆXEMì bfbz!ë†ÄjhhHOO‡"vM²²²8Îj©æô¼+•ÊùùùÑÑQ ÃÜÜàšç¢˜žPjŽX³³³SSSk0\sÄ Ç…MMM…½!¡ÓÁè3¹6Ô‘Édh ]»ß‚À¦Ü‚XÀæ„öPÀFˆíëë± ³Úº{ ØÛ¶mS( `õ«¬¬ìòåËË’ÇÇÇËËËûí7()`5ŒNúû_é£G …B¹ÿþþýû Éííí¯½öZUU¾G¥R555áI<orr²¾¾~å/­¶6zvvEÑ­[·®Lšžž&F»[M¬´¶lÒä䤧§§‡‡Çʤ‰‰ ///£[5­v6•JE&“žÍÄ·Ld[¡Pøûû]ºbÆ«P(üüüŒ.Ý 4ÚCiôl(Š666†„„ÄÇÇ/K£Ñ¸»»{xx,,,<ýeË}}}Ùl6~<88YTT´òçGFFBBBŒŠ… ˆÑDLˆµÚÙ,ždB,¥RI¥RŠeÆÙL|ËD¶ÇÆÆŒŠeÆkâlr¹<((Èèª>?”ššú´X†a†©Tªk×®cvÿþ}‘H„aXgggmmíþólýõ¶ ÕÕÕF߉DF“z{{¥RéºÎf^L$uttŒMjkk›œœ\W:;;årùzó`"Û jµÚRåÐØØ8??o4©¦¦fiii½Ù[b8‹Åýýýø±D"Á Ã0ìáÇF‹ÛÄc5 ö“‡eüÛÌEDDŽwíÚe8Þ³gÑKŸŸŸŸÍÃFȃýäayàebv)X »á™èõúâââ‚‚µZ½ìŽé×_½rå 8ê:ètº .,V*•ÿš°öV³¿¿¿§§ge‹Ž¿är¹†° pzêêêJKKWšÐÔÔ411=ïÀº™˜˜P(&f¯C¬]»vq8œ¯¾ú*##AêêêÆÆFA Æ×_Íçóí0„6ooï}ûöI$ü¹àÃÃÃß}÷‚ {÷îýæ›o:;;}||Ö¼k4½^wúi4E‰D"‚ jµš@ àÇö‰V«•J¥·nÝ:yò¤m·âÕét7nܨ«« ùàƒ‚‚‚ I===ß~ûíüü<‹Åzçwìyã1N§V«=<<‚^¯_\\$“Éÿω º»»OŸ>^Ù0:.''çØ±c‹‹‹åå剉‰###xRKKËÇ\UUuþüyA.]ºäÐޏN¼Y\\ls±š››ýýý w9çÎ{ûí·1 Óh4%%%ø›z½~ÿþý111]Ú¼[•ÂÂÂmÛ¶à/cccËÊÊðùL/¿ü²aL×ÇÇÇÑŸƒìrbMOOŸuêTkk+þõ/¿ürvvöóÏ?¯ªª …'NœÀWs¹ÜÂÂÂêêjÓ=ÌCCCOO‘À¥R©Á<.—›––¶Ú¬Ë~yóÍ7) ƒÁxï½÷êêêjkkQ ç|lß¾ÝÍÍ­³³A‡#—Ë¡R©‡Öh4 ?ýôÓž={$ÉÐГÉäp8CCC‚œ>}ºµµõøñãÉ›Z­–Ëåt:½½½ýСC¦÷ ±ì”×_¿ÃG¤¥¥åÌ™3\.÷Ö­[†ýRRR._¾Ìf³{zzÒÒÒH$ÒÈÈÈôôôƒJJJJJJ‚‚‚ |||ðkOrrò³´uëÖãÇ—–––—— …ÂòòrÇ-^×ÝûŸJ¥Ž =zìØ1Ctúôé™™™÷ß¿¡¡áÊ•+ùùù÷îÝ›žž>qâ„ÑEåÏ.kï[^Fffæ²wrrr’’’zw ×½béõzEétºL&KOO?rä“É|zF¥L&;þ|OOORRÒ»ï¾[SS“——§Õj[ZZ ŸÁ0ŒÏç¯ñQÝ¿ÿíÛ·ŸøüüüVŽX¸¹¹‘H$b97oÞÌÍÍe±X<O*•â¡’H$Òét‚,,,\½zU­VïÞ½»²²2((H©Tzzzúé§øóÜçææ¾øâ | ¿J¥úý÷ßµZíÊjnn.**ÂO{âÄ ™L&‹q³ëëëóóó}}}1 5LËåZ­öèÑ£\¾®ÓAÊãñ(J~~~OOÏÝ»w9"ðYÑ^^^ÁÁÁiii—.]òóóKMM½~ýú…  ð¹µL&ŸÈ{ãÆ wwwooï”””ÄÄÄ«W¯â'ÿá‡)++[ù»DD"‘úiSRR:;;/^¼˜’’‚ŸßZcß¾}ííí555]]]]Ú®5ÑO&“UUUMOOÓh46›mxâp[[—Ë}õÕWãââx<ÇËÏωDîîî}}}Z­6##Ã××ÿpWWWMM @xë­·ñ7 ÅŸþyöìÙ•¦\.·¯¯ïÌ™3†¤‡ÖÕÕ…††>|bÃgš Aòòòbbb½¨a)1b €Xˆ€Xb b€%ù/ò‡Ú»Ç2öìIEND®B`‚snd-16.1/pix/sceq30.png0000644000076400007640000000270611147553270012751 0ustar bilbil‰PNG  IHDRÃ"7B3PLTEÿÿÿððð€€€pppàààPPPÀÀÀ@@@```°°°   ÐÐÐ000 {½£ pHYs  šœtIME× ÞK7ö&IDAThÞíZ –£ ¥!hîÚa5ÅÓY¦3c½×i˰YŸZ>‘EŒãjZ€PÊÉ)Ÿx¤1ã„«Q&ˆY9# ZsÀiî×xõÝ ¨ý[427V,&D†(ëb´ †±ßpi?»¢9è‰âKDKû!hP&ŰaESY¹­ƒMÝÑ9]Œ™)G`¡9Oy@_@ŠÍîSboËQbh41öß̈¿xŽG:žÒ•« *¥&îñ¼Ú4¶Ç¾ (sÃ0\k-”aW)]¦{¤fÉæ8‹WÛ(“2;èĘN¶Ê¤núkE.†ÓÝ?çF*ܶjé$åÕ*­9Zÿû ¥®õÕ4lëÒ!OÁTº;tA.SP,5L€nŒõyoC3³é’‚3ž£Ùñ×¥Ï8•¯õËÂsØÖ¥C“Œéí+Õt#S°É9åI/ë¦òÔIª9~†-㽇^†¯õó¡¹0ªßÖ¥Ã`Z_ß(Ÿªµ¼ŽÅtè7¬Âõ‚÷¬Zš3\.ƒk(4‡ëŠ ´ÀBýˆÙúÆ"Hl+yôÝÎZ³þÀi—ðbóÕm+¦-RCȃKUÄÌÜ•“›2ûü¨ç‹m®WÒ! Úmmp4‡ë(%È uL_ öú(h}ãÀq¤Ûrn£ÔjÆCÌ@Ò¾g¬Uë{Ú•0´a«½ªÈ òCa«ûŠ o,Q9„¼iÙŠ¦­vÐl×ÑÚbÍé#VÇô_³#<åÖ¨6?2ÞGj%cGPãbÍmäԳȩÖG´Ë¦Ã¹éÙ©mhàï­cV̰öu¼ƒB¾¢u«Íá;ZŸ¤¨S©é+¾>T‘ F¥ùÆ ‚†.îY =ûòåµ7˜RÚ:p¸E®Œ˜ÃÔ#lÏÓ. EúªS‡Ò³d‘‹9 8{„cô_c[áB¢-)m ÙÍ×°|)<£W”Í"±/°QåBÀn?Îg‚ìx—%tK¹¤û|E¶Fß{4RxC3%¶%„Cô5§²ÈÊ#ájß]icØ#» ˧‘"2Ã0ÚVï»hg_zr™×ù.\'É™w¶×¬"(ËA9À× Ù^,åŠR´Ó§-!’µ1}ݯ [Ø}“ª¤Ë’݆åÓH9ðC !$öEéþ¹Y²~ÕAƒµÞVøÚG¤ðCM=…ËÉÚ˜¾fì5·ÅZJ'ÖÆkY>ŽXú×·é"ûr-À»'Œ\bIg­BU½¤»| xôwø †mâØ;}{½C_ͬm!ˆ¬6)m {d·eù8RÀïÎÀ¶*^¼¹£Åäh|æv>é¤bZyN$Z{ï_û¸š‡âÁZ‘µ;ôu§™µ-´ Ÿþ»¤T…Ϙì6,GŠÀ½gƒ‚ˆ2w‹Õg·%õøÚÓgˆO`Ù:š¬w63˜œ½vè+àN¹-vV ¤Ýè.Ù­,¿%GzJ  –xÙ/:Nú+‚ì·GÓŒ ²cˆœ½Þ£¯[ÔL¶j4&»GyØë^Iœ8ŒŽ3°ÑKó‰§ÇìС¯½åÿ  ü½4ô¦Ý žÀpY#]产n‰/SrÊûeþaØßÏ¢˜‚Ïæ}bøÑo‰-;ó§…?á[2wbÞæ4ñ»%œ8¼Aó>ßk{·Ä‡7HbÞ×ÓÈß•«CŒó%ï/“_õÛ)G¹¥{¹ Â+!@ȉá:^þrÓ‰á7Jx¹éôÃo–üå¦xjýÏÈN;1^×ÂEIEND®B`‚snd-16.1/pix/mix2.png0000644000076400007640000004544011147553267012542 0ustar bilbil‰PNG  IHDRµæÝ¥Œg pHYs:ÊduhtIMEÖ11·n·Á IDATxÚíw|SUÿÇOöh³šîtïÁ¦)S† EDÅñ (ÈP}ÐÇ•ç'(ˆõQQPÇñŠ È(«”R ”¶ŒnÚ&ÝmÒ$mšfçþþ8z‰Iš¦J)ß·¼|ÝÜ3î͹·Ÿ|Ï9ßó=”"Cr‹¬NN¡PÀ @V+‹‹è1!”Õ•å.Sµ,# Cn‘C›0Hô±Z–”!7»“µc?£BK¸„NUï­Žuap†ÑÂP3²ÕÚ ±„3‰FÂVçZÖ¨£¨ŽúIžý›!zNIó¥A›p a³Ú¨ÅT4ÌUÿ:OAós”5¨Ð•ýøgšø¤Ë$pCUnUô¸èZöZ. zò¿îe-œNžÔX5í¶vôçt´£Á(  Âáä?hb ÏTž¬ÄÖÛ‚çvœ;ûÃYÏ/="¤ ÃáªÀþ$Q(ˆRk®­5×ÊMò g/8”¢;|ÑD䜎,_6: ZpÏÙΪëÕ~Ñ~åÇË}Â}ü"ý¬f«ªN¥®W·ÉÚ¼w`þ—óE!"œù§?‰BE¾¾„h“·ùFø¶Õ¶Meú¡ ‡ÄábUÊ'Ô'enJ›¬Íþù;ó•5JŸ0Ÿš35B‰P*¢Ò©Êj¥C6èV©B™Q&/‡§„;’¤IŽ–¦£ý¨±iªóª«ÏVWŸ­¶Z¬¤ Ý5&ŠB¡D‰…Ц¿2]Q­PÕ©f¬ž! ‰#ÄËö.#Å!$”§¿2]Y£¬È®@Y-VÂFÚpˆ°£æŒšò”QsFQ¨Žo]dz$…B‰ÍâßõÊ]ªZ•²Z9cõ q„ÚðUSs®†ÄïU)ºs-‘i‘К€çTŸ©¦Ð(U¹U ¯# tXÓ¨i“·í|q磟=*”ÿìÑü•'æŽ˜Ž–** ©ëÕ¢P•öç¯uþ®üªÓUù;ó£ÇEÿïùÿÍûd¾Ä•SWÈâ>a>‡?:Ü&ûðLmšÈtʦiÐÈjeØ’t†Rd(ÂþáDAåÂZ”“eŒÿp [‚°YlT:•°TÕfµQ¨›ÅF¡P(4JEVEÜÄ8rý•Íj³ÏC¥SB„ P)WóXlAØÇ']^×ÎØ¬6Úe1Ü…òÉòdwdÈÍrDØu«)ˆB¡…e$!tì³cty½\^-G…QÃäçåÎ"ªiд7¶ËkA¾Àæ±kÏ×Þ¬âÀmþËÁˆç»Ð®öÆvMƒÆYÖD„ÓÂÉ"”‚®™I†"ŠM)¡C\^†J¥ØlàßÀ-†í¢P)„«¤m“J¢EøõJ¥ÖÚjBÖZýƒãf@ƒp;s9ï –ÄšÚ»èÆü„&èµ>æææ½ÿþ'øŸÍfC}ðÁgøggçzx™¼¼ódUf³™<êÔ„йsÇŸô°ªóç‹ >Ðë ¡O?ý ôÏ?ßüþûŸ:t´Çœ_~ùMG‡Þ°`=±? ±Ùlï¿ÿÉéÓy×M=±téÂ+ž]±âY*•ŠZ¶l>ÀÇÇŽe{x™'r.|WÅ`0Èó‡g!„FŽ6~üòäÚµ¸o‚®.B(7÷¬^¯G=óÌSl6«­ùÍ7ÿ½ûî»V¬x¶¦FÞÔÔâºmÛ MäÇ æóxÞð À€ë‰ýÁU¥£R—,yÚsÉÂÐ{2¯¶P©ÔU«–#„²³sß}÷Ã}ûvÐét„‡Ã!³­_¿[p“'ß9aÂ.«Ú´é[&“¹rås¡ >Õéº :¶%7løÔ`0üûßÿB½÷ÞGGŽd™Í–×^{‘År¡zK—.Z¿~ã믿¬RiD"a^Þù5k>غõ ±XTXxá·ßÁ`Ð_|qÙÇñúë«Bk×~ˆ°X,,›ÃáP©T‚ æÍ[””@Ę1)þþ~»wï»x±dâÄñ÷Ý7³°ðš5|òÉúàK—Jvïþ :þüó‹/^™˜g³©©£ÂÃCwïþÍf#ètÚŠÏ xe ß°Z­6|Š:{6ßjµ®[÷±ÙlA͘1e̘TR²,ë<6zôH„Ðôé“ÇŽMë£>.]ºJ¥a›q„q'Oæ®æÊ³²r&Ož€e»;}\¼x‡ÃÁÆ£N×%•¾j6[֮݀zíµ—¤Òu8Ûk¯½d4š¤ÒW»½c:N§çæž9r…BIK}×]“°ó{nnA^^ÜÜÜÊçóvîüU.¯‹ˆ€èЯxyqBØKOOÁºÄd2²;Wè‘à.yc‰Ì,CU–±Cì%™Í樨ò?;;·¬¬üÔ©³&Œ£P(ï¼ó¾ÑhDỎ׋ÎÎΦ¦¦>Ôét•••xµho©««Ãá8àvÑG—i4jû"‘Ðf³ñxÞ®÷Žý‹‚‚‚µk׺LÚ¸q£T*]¿~½ÉdºU›ð§ŸXŒÄb´|ùu©O«Õ–••õªA:;;+++U*‹Åjllì­8*•ÊðððêêêÞÞjmm­@ hjjê­DvuuUTTTTTàž00¡{žÕËË«½]ãã#ª¯o@y{óh4 AIpg§ÎMÁ–––î"Œi4©Túá‡F&“‰***ÊÉɱÏóÌ3Ït¨b@`4"• «ÔµWVSSC£Ñbcc+**=)"“É(Jxx8ƒÁ P(Øô¤Åt:\.çr¹ááá …Ïçk4¡°çä®®®††³ÙÊãñB …"44ÔCelhh`0‘‘‘¡†††€€€>¯€þÖG.…ËÌC E›¿a³F„W5T···ÿ™Ë%Ä`0N:K6„P\\‚›kÌœ9óìYO=ÏãããíÿÒ¢¢¢üñ­Ýˇà ð$³\.7 ‹%22[è\.·³³ÓÛÛ»GË‹#yÆÏÏO©TJ$O.š˜˜H Â÷Ück·¶¶úùù \–Ïçët:•Jåããã¾ B¡P(ÑÑÑ ȈÅb…BÖs 8½^ßÐÐ@~d³Ù!!!ð ô·>ò¨¼yi÷^LMM·Xô¡ª‚j.׫¤ä²Ý_ˆ"::b̘ô¿,‘ëÖKâp8öÖÄ-"¬C«­/)!þ n0JKKq(:×VjµZ›Í³cBCCkjjš››Ã°eíRU*•ƒ¸…B…BqåÊ•ÐÐP7J×ÜÜ`ß¼T*5""¢¼¼Ü½ÝÚÕÕE„ƒ™P^^Þ£>*•Ê„„û¡jGDEE…——Wwš®×ëe2‹Å²ÿá4 ÅÅÅø¶q ;€~ê_S©”„„«6AAÁ6›U§kÇr “5DDvWö«¯¾:wî\nnî¸qãBŸþ¹B¡J¥!&“ùùçŸwuuÙoJs‹âååeoŽ!„¼½½E"‘ÅbÁ"Hj%VO|¬Õj5MDD„Ã/•JŒŒ4›Íuuu¡¡¡.%²¥¥%88Øù'$::Úl6744H$—©ÓéŒF£³^S©Ô   ÒÒÒ¨¨¨î´µµµÕßßß¹`pp0þ‚!!!l6Û¥ñ(‹çñø|>‡ÃÑét¡¡¡ö¿Žz½¾®®ŽN§ÇÇÇ;d±Xxû ›Í†GoÁ+ܪú(‹ëêjÉUUÕ‘‘á–3g΃>Hþ¶/X°€ÜqåÊ•:ŽÃá¸ü‹ºµ Q©ÈIªh4޾Éb±H­DÕÔÔà¿jêÒL¦R©,+22²¦¦ÆY";;;étºË‘;\0""B&“¹”H‡žµƒùÉçóqG;((È¥ñèååå\P ðx<³Ù\]]íÒU*•ññ®°2 ¡PèååÕÐЀ›Èl6Ûl6‡é^øð—…¿dàfê£Õj5›¯Î¨Zz±¬ùúúÚ´ïq¹ÜÛ§ODj%B(..ÎcËêãã£T*ƒƒƒÝ÷¬]”Ëåáááö "—ËÃÂÂÜ \àŽvcc£ÃtMWW—B¡°ët)UÁÁÁõõõƒƒuuu‰Ä½ƒÁ #Aðn}plÙ‚^!„.Dï¾{3ïä‘GPT’HŸß º‚H$"·‘=w÷Gƒ\.W.—Û{ …‡‡÷8íƒûËÕÕÕöS"x¦»GÙ­­­öw‹ õdÃ20ÐÇëAWjmŦÔM¾¹µ´ Ë—ÑOç´Z-›ÍvÙ1Ôjµ­­­aaaΩ---!çT&“ÙÒÒÒÝXd]]ÉdrNe2™ÁÁÁÍÍÍ^^^.ƈu:]ss3—ËuèMS©Ô˜˜˜úúzæÜÑÆt—ÛÐÐ`08޽ÙKÒÐÐ@¡P\&!„ ‚p9]c0Øl¶ËÔÆÆF½^äÜ)ÁY,Vw³ÞMMM »ÞŒ'³óÀàc€va.^¼¸iÓ¦M›6Ýh¿ñŽŽ«ÕÚîÉ«ªª,®†pÒÙ³gõz=:}¥¦".µµáÔššµZ][[ëìõ‰“$IUU•sµµµµ‰ÄÛÛ[©T:K§J¥’H$.½¸e2™@ è.µ¥¥E,wtt8¯inn®¯¯—H$Z­Ö9µ¥¥…Éd²X¬¢¢"—wëíímµZÕjµÓW—^¯—H$:ÎÙu\©TR©T‡S__ï\mAAޑܹ CSS“D"ÑëõÎŽåX7E"Q+þátjy‰DÂ`0œSFcii)‹ÅR(]]]ÎMTZZj4år¹KU-...))Ñé\¸777WUUuºú 7™LUUUuuu A`?öšèèhŸÏb±êëëÃÂÂètºL&‹ˆˆ ÓéØî ×ëõ6›M"‘„‡‡_¹r…ôüT«T¢ˆˆššš€€.—ÛÖÖÖÖÖfo²iµZ† ©TªÙl¶7‚ƒƒÙl6›Í...v0ÊjkkñŒ —ËÕjµØ+›4B¸÷J£ÑL&“½ ©Óé¨T*Ftö‹T«ÕxjØÛÛ»««Ë¡o«R©pª^¯w‹¬­­‰D<J¥¶··‹D"û‚ …"00ÍfóùüÎÎN‡É7…B«U©Tz½Þ~Š©­­-88X$iµZgÙmmmõõõe³ÙB¡°££Ã¾ Á`0 øÛ9/²T«Õ€Íf3™Ìòòr‡ùw…BŒ3´´´`ÇuR:;::ðÝÊd2Ng?7ÕÔÔÄb±’““ ‚(--MJJ²ÿiÑjµB¡P"‘´¶¶ªÕjìœÔÒÒÒÙÙIA¡¡¡&“©¤¤„Åb1™ÌÀÀÀÚÚZ„Ùl&³)ŠýC!‚üc04ÍßßßþenŽ>vthñ²L@@ð ½-///ü"ö8ÄFzÕv FÃêc/‹ö©6›ÍA4 Eqq1ŸÏ—H$íííäô®P(,++c³Ù, Û}‡tÇa2™eÇ323­z½·Ÿ_cq1éà-‹kjjêëëA]]AxÐ߆¯¯¯R© êì쬭­e2™L&;¬àáEìŽSi4^â‚’H$••• Øl´X,‹…œ3ÁÕãµ14Åbá‹ …B¥R‰—ÖÔ××kµZ*•‚ÇËË˱Ìåçç …B‚ ÈToooü×ÞÕÕ%—Ëñ_&þ³äóù¤TWW×ÑÑÁd2i4âôóó+//Çt¸9QãïïÃÛÛÛét:ž¢Añx<,¸¯Õj±èã|||ÊË˱Raa!›Í¦ÑhäO‘¿¿?vBjhhÐh4L&“N§ã&¢R©l6»««‹Ëåâ‹2™LüMñ+¶FcuuµÍfc±XÑÑÑäÝÖÖÖ2 R¤‚‚‚p§›B¡„……a¥Ãê@úŸ†††jµZ<  ‘HHÕc³Ù‰‰‰F£Ñd2ÕÔÔà×Yä_¼š„>VV–ÛÌûûû ”/@§c¯#ÅaO[÷þC~~~~Í®8äôõõõõõÅË)Šƒ‡Jxx¸ÙlF‰‰4Á`8üh„……©T*µZíìLƒ§¤‹‹‹½½½±ÑGæ ©ªª2›Í8Õjµ’®ã4ÍÏÏÿ±‘k IƒQ$µ´´¨Õj//¯„„›ÍfïsY]]m2™BBB‚ƒƒíS©Tj`` ®6>>ß Y­@ hii)..ær¹ñññ–¯D"ÁCCCCCCF#™Š*qjLL n[²Z×ÜÜ\\\h±Xèt:ùš…„„à‚ønííb*•J^422’Ïç›ÍfR8Äb±\./..–H$‰Äd2ÙWëïïåʆ/ê`n‡……³X¬¸¸8‡WˆËåFEEÙl6›ŽüIÃJg¯n¤¨ñùüääd—ï…BÁ—óW8ÕeAƒâ8Pô‘ì±þõWz{ù^t7©jï²ã2Õ¯ûIm¬¼.ë§Ñhö@ö‡ÿþÅbqwÕbÓ’Ô‡jccc»K‰DÝd{ìïÇán…B¡}×Û}ªö÷ã0³$HƒÚùwËAqì/Š]뻫ÖËËkذaÝUËãñº2çª<×2Æû—… Qb"ЉA0«Àá–5e2ôÉ'H @v&è#BááhÚ4x~ÜvýëË—/ãhÝú?z{#XÀmh?†‡‡OŸ>}úôéÝÎЕ” Ó§Ñ÷ߣ>í 0(ùøão“‹Àmm?òx<ìéÖ­ÿcXZ¿!„ÀÅ!„L&;sæLYY™ýüµ‡,Y²„Çãmذ¡·ëëë¯\¹€>0¼½QOAn+Ο?Ÿ””ÔÝ>îq¹.Û._¾Œ—9G„è_µZýØc8p ·92­¯3] …b̘1}ØØ !TXXO }úƒúúúØØXçð =â°ºWTUUEGG÷­ì¦M›p°"}žòÛo¿ô¶”\.ˆˆèÛe2Yxx8“Éìm(¹K—. :´o---õp÷Z¸‰ Ðù™’’’sçÎ!„ú6ápë¢Óéúð•óóóSRRúùV Ell,¹ë/€ýØO„„„L˜0a„ n¢? Jª««§M›Ö·„PBBB¯:­xsľ]ëZóòòRSSáÏû±/ðù|îévÛ¤Él6s¹Ü>[ͽí&Ž9²Ÿ¿css³H$Šˆˆ¸|ù2ü`?QSSc˜ËsÊËË=ßñú2a„ììì^9~üøÄ‰“’’JJJà¡ €Gœ9sf̘1}(èäµÈÎÎÎÈÈ@q8œÞ:•——w·6€>ˆÉdýs­>oˇ·(€‡€>ýDGGŸÏ3fÌéÓ§ûçŠx÷1„PHHˆýV×–ÖÖÖ—_~977Þôñö¢©©©»¦o4#GŽìƒße8}úô¸q㮥_ë¼¹+ÜèüuYYÙùóçÑíçÿØ<8cÆŒ~¾¨R©Œ‰‰é[ǼÏË[[[[[[‡ fìSP»¶¶6£Ñ ï pkÛiiiiii·¨ÿãž={öïßßçâ|>¿££ÃÃÌx'X|Ú?[Î_¹r¥oúx-à‰??¿ÖÖÖîTû_ÿúWwÅýõ× .t—ªR©n‰ô …ÂØØØØØØ[Ôÿ±¸¸øÔ©S½*²oß¾{î¹766öẩ©©yyyƒõe=}úôرcããã]úÀ+•Êßÿ}̘1999.ÇË—/·µµu'ŽkÖ¬é.¤Z­®¯¯±}®555!!!½Ý›X«ÕâÀýƱcǦL™r*55¯"õ¼oîfÒ¼¢¢B"‘øùù¹ô7:yòä‚ \FóU©T{öì¹ÿþû»ÇÝ»wÿý÷ðbƒ>ž²{÷î‡zÈ¥•wàÀ™3göÛTVVÚï"í9^^^×~#FŒ(**ò0óùóçÉ¥â\.÷:δœ:uêŽ;îè.µ¨¨høðá.“ª««ÒÓÓ]®ç‘Éd~~~ƒÁeYFóæ›o>|þ"@o;¤Riss³Kqlii™>}ºËé#O»·CZ­/©ì-F£‘Åbõg³œ}úui µZíIÎ>+ѵàáÖ:b±X©T:œ¼páBwÆ#B¨  ÀÍ"t<ýåííÝÙÙéü’Ì›7Ï×××å|úéÓ§ÇŸššš™™éœÚÑÑñÑGíØ±4ôñ&³wï^—¦Áwß}g4í„о}û&Mš´páÂcÇŽ9§šÍfƒ1qâĬ¬,—ƈ››‘Ëå;vìpøc«­­ '?z>}-£–%%%IIIäÇÈÈÈ>Ç ºé6âââœÒ CߌVµZ-‰B"‘H£Ñ8¤’QˆBBBœ'pΜ9“žž>bÄgû±££cç΋-ÒétµµµÎÏtÇŽ;vìËå P ×Êž={vîÜIþ†_¹r…tuÞ¶m›T*mmm%ÏTUUa­¬ªª¢R©O<ñDpp°B¡p¨S¥RuñÁ}‰7«úá‡ärySS“ýI÷cgnhooögâãã]ڼΠ6›Ý‡‹¶µµõmU¢‡ Ì Ew<˜€€‡½<Ü%"((È¡åÝC>눈ç¾IZZšƒÛ€ýsqiÙ²eËÃ?ÌçóÇç°V ‹ã°aÆ –““ã žgϞݹsçÎ;¯Å{ ðœç~úôéC‡‘FãºuëÜÿÏž=›Éd~ôÑG^^^6›ËåæääÒét©TŠ’J¥xÙÆï¿ÿn³Ù–.]zäÈ‘ûî»!D§Ó- ®ê¿ÿýoll¬¿¿TT”ó…Š‹‹“““?>uêÔ¾}»ßÿ}úôéeee׫¹œ8²X¬î&ì9~üøäÉ“ûvÑÊÊÊùóç÷¡ CÇ<--í‹/¾°ÊÄdeeñðÃ;üðQ-ðn^÷äÉ“K–,A9²¨¨È~‘ÒåË—‡ Ò‡ïR^^oÿ\ÆŒsæÌòcUU•ŸŸkŽŒŒüõ×_ÄqîܹX[£££wíÚ…!L&Ó•+WÒÓÓñÝêt³žr= IDAT:üb½6 ©Ô·ÞzëVÕDZcÇŽ;–ü¸qãÆW_}U(öX0))I¥R577ÇÇÇÓh4|LÚ€b±xÛ¶m^^^b±800p×®]uuux¼îܹ۷oá…víÚ5jÔ¨}ûöq¹Ü| lnn ܽ{÷¥K—ÜØMÅÅÅW®\Áƒ¡ððp¹\î ³íí퉉‰÷ÜsÏ·ß~ûâ‹/’çe2Ùœ9sú³óòò^xá…>lnnîó"H¥R9lØ0ò£———N§sÙ’Î'/]ºÔç&²w¡wÀÞðÄ&'N´ÿyöÙgñ±D"±<1 ä´˜@ pˆ£ž™™¹hÑ"çÑ’ŽŽŽ¬¬¬¹sç’?f³gÏ~ï½÷üñšššsçÎ-Z´ˆ4<™LæÜ¹s±O“É|üñÇí/†¡Ý;|||’’’ð’|L§ÿù0þüÔÔÔ¤¤¤G}tÚ´iiiiË–-é"‘ˆÁ`deeUTTÄÇǧ¤¤¨T*òo†Á``ë²±±1))©²²ÒÞ täÞ»wïÏ?ÿ\\\L¾Ü'Nœp¸ÃÚÚÚ°°0ç?'£Ñè ,**ÊM‡S__Ò·¶Òëõ}ë\ãù\û3wÜq‡‡Îðžl;sîܹÔÔTûA7‘"¿øâ „PKK‹ó.ÞmmmÇŽS©Tb±Ø¹àš5k†žy<9.¼víÚ’’:Nï’Þšæ‹/¾Ø¾};é=Š II•J¥£G&½°åX__ßÑѱk×®¹sçÚ;*$&&¾ôÒK‡¶X,«V­r-a2™IIIIIIý¿Z @·ÏüµOrrrrr2ÖÄøøx{#èÑGÕjµ<òNŸ2eÊsÏ=GÚ‰äÀ“R©œ;wîX,–¯¯/ùúâIêâââçž{îܹsî'v]jÜ¿ÿÝwßíp’Édö¸Ê¸Ïñ"]ârºÉeçÚÁÝÒåÜ®‡¤¤¤88Ç` .99™ôF<þüñãÇ]º”*ŠÓ§O_¸pÁÞ2%oõÓO?=yò¤³¨J¥b0……….ý·°2îÚµËå ð·ß~ûÐC-]ºÔ^ææÌ™óË/¿´··I¥R“äñÇ?xðà–-[zè!g/.‹õôÓO÷y¸}¼±ˆD¢{ï½—ÜMÅ~‚eÊ”)üñ‡T*Ž›÷Þ{ï™gž!SÃÃÃe2ÙÞ½{gÍšåïïÿÕW_Ù— ÅÓšK–,qcai4«áZ˜:uê‘#Gz|œ4i’ÃI§Õjo\#»Tsìòܹs¤J:;étºÄÄÄôôtǫ̀Q£ðZÀ®®.±Xì0ÏKÚ³---=öXQQ9R)‰T*:thFFÆÇì<ª×ë“’’ž{î9û]ÏÊÊÊÊÊÊ‚ƒƒýýýöÞ:th\\Ü·ß~k?:d¯€‹-z饗®ãƒ@ëÖ­“J¥.;8“&M:tèЩS§°£ŒÃÌ5¶)jkkÓÓÓOŸ>½cÇr…u£c¤¶öO|ƒp É~nFNçü5‡ rùòe™L¶mÛ6Ôx^^^ZZšý.—;lذ3gΜ>}úÿøGLLŒ½(iÏ>üðɉ‰¤{clllee¥ýÕçÏŸOö “’’ðÐç‰'&Nœèð4ÙlöÌ™3÷ïßïrîKäüùó¯£E€>Þò¼ûV­r¹½P(4™Lû÷ïŸ0aö&'šìû¤.]&ï¸ãŽœœœÃ‡¿ÿþûndÎ=RZZz]¾ }=999ãÇwÎ#‹±]ææ”J¥ËqÀ”””íÛ·ã! ì!àÉïÇøñãËËË«««½½½SRRœ­6rØÑaO¸eggßyçgáÂ…d‡Ã …MMM.½J‡ 6þ|±¶Ç½kúx;âÆÑ$--­¥¥ÅËË+###---,, Ÿ÷ÄÇã]¼xÑb±ÝÞÌÌ̪ª*2Cmm­ËÝYãââÖ¯_ÿÝwß‘³@gΜéñ‹$''—””¼ýöÛäBšæææM›6‘ºsG‹‹+//ÏÍÍ%ˆµ¶¶¾÷Þ{öë²»›œ‰ˆˆx饗"}}}—ÁØãå啞žþÀ8' >üøñã?ÿüówÞ霊W v÷Ež|òÉß~ûÍMØÏŠ€AÀ{æÌ™ƒ"„ú uà‘‘ÝƒB‹/îUÙôôôÈÈÈœœœúúúÄÄƆ†–––’’’•+Wº/ÓÐÐ —Ëñ¬ÅáÇ?Þc×Ãálܸ‘ÇãUUUá¡·£GÚl6r‰{N:E¥RñJ¾ .DGG»tßqîb#„²²²t:R©ÄN…ÉÉÉxª÷üùó£GvY0!!Á¥"—Ë]¼x±Õju9$«ÕjíW+9´@oöc3fÌ©T*•Jû9òÂ`Þ¼ynR÷ïß?kÖ,—IãÇ—H$äÇÿþ÷¿sçÎu^åæ²õìû€MMMF£ï3ƒén-ó„ –-[öÏþ“ܲµ²²ræÌ™.ÂÙ3nܸ={öx{{“¦nQQÑ´iÓÈe0 …Â}ß3%%åܹsÎÞÚ}[ëéÆ!fÔ¨Q.G ú× FãÞû}úôé‡ÊÌÌÌÈÈè•ÇâäÉ“±_ffæ]wÝeïtÙÝj<>Ÿ?|øð€€<ÃsòäI—]T—C“&M²÷PÑétãÆ#»Û/^tö¿±ÇÛÛ;!!ÁÙÞ}¼­ …¦®®®·®àX›šš CDDDdddç8DÍpÏŒ3âãã‡~áÂ…3gθtsqÏĉß~ûm‡“Z­¶»¥/ú88™5kÖ<ÌÌãñJKKñT é¥xäÈ‘iÓ¦õX¶o>ä8\Mee¥C/õòåËC‡uS/ì[T!FŒü˜ššúÕW_u7ø ƒÒQÙÍÒ`’ôôtr3,, ƒé±cŽŠ‹‹ûã?º D䆘˜˜­[·:w®u:›œéUhq"""T*•ýjh}¼] «­­í1^$B‡YíÃ%8ŽŸŸ_Bâ!Hì4~üx—;^¹ÄÏÏO¡Pñh½½½ñbB¢%''¿öÚký¼'€>fÏžýùçŸ÷9À„'Lš4É9”^â¾`JJJ\\^¶Ìçó¢i¸aäÈ‘™™™ÇaÒÙ!/Ü€ÿãMÃÇÇçÉ'Ÿ¼¡qYì;àxÝnênxôÑGûvÑçŸÞÞ- À~¼Î &ÿG÷]È~û‚8Jk?\(>>fœÐGà&„#NVUUu(áFØ¡&77··›@¤¥¥={žúôäl‰‡;®\ð¦WÎ{Ýôˆçè#p3ÁjU^^Nnäâ!Ѽ{‹R©$# è#p‰ŠŠúøãÉn<'::zûöí<¯W>Œè¯ÅÑ}Žã[TT4bÄxpè#pùçž{î½÷Þ>(΄ ÒÒÒžzê©>\tâĉuuu½5<BÇÏÊÊò$ü 4èз>>>}Û~Z$õ9ÖÃĉû¶”eòäɉ‰‰n¶BÐÇÞq;ø?Þ&Øt}¼žŒ3GUظq#<$n 0þúúúúú0ÿG€[JÁÿè_€>€>€>zDmmí7ß|ã2éÇ”J¥[¶l±Z­ð0¸íôñĉr¹ÜeREE…T*mooïêꂇÀ€ÂÓùëôô±&ÓUW‡k³Y[ZaC„£ÁX]] ‹ŠŠzâ‰'¤R)´5ƒSëF>6 þþ Bù3®Ÿ'û){H}}}UUùÑjµž:u ö àz~=õQ¥R‰Å>ƒ!¤V·K$al63.îϽí5­}æ°°0{ÅÌÉÉ‘ËåÕÕÕx?Ò;v¨Õê%K– „h4Ú‰'L&FÙ ‚ ìÌQ‰D²aÃ÷÷ÖÐÐàïïÏ`0Üg“Éd=~SO²577 …B6›í>[KK ŸÏïq—Áëxc …‚Ëåzyy¹Ï¦T*Ùlv¿:×ñÆÔj5•Jí1Pîu¼bGG‡Åbé1кV«5™Lb±¸ßn¬««K§Óùùù¹Ï¦×ëµZ­¿¿¿Ý˜ÑhT©TAAAývE‹ÅÒÜÜâ>›Õjmll ½.7†Z¸páO<á‘ðŠ6ª6nTmüöÀ—*•L¥’uu©U*ÙÑ£¿ut´à3[¶|öÊ+ÏöÙ6¼óÎ;¯¯\ùÜÖ­_mܸ®¨(÷üùûöíÈËËÆ Wdee;vìÊ•+ø£\.'kkk;VYYItÃÛo¿MôÄgŸ}¦T*{ÌæIUfûöÛoåryÙ¶oß^UUÕŸ7öË/¿\¼x±Çl{öì)((èÏ;räÈÉ“'ûóЧOŸ>xð`ÙòòòöíÛן7VRR²cÇŽ³•——ÿðÃýycõõõ_ýu^Q£Ñ|üñÇ=fÓjµ6l¸^7ÖX÷T*Y¶ Kâ}ÿ¾¯ëgT*•¨©©…Édþe6¶ëõ•Jãïì¦`FF†ƒuI‡††öø³Ð#ÁÁÁtzÏ_ÄC‹Ú“l,«Çlþþþ=Ú˜×÷Æ|}}{4Bb±ø:YxrcB¡°Gÿú6Ç£R©žd³X,ýyc\.·Gãñú6¾‡ÙX,V```^‘F£I$O²õhcz~c½‚Rd(ÊêÊBñϲf§ÏD±Ùƒ¡½°ðbjjºÅ¢GíÞý{[›†B¡P©4ƒAÏd2ÃÃ#T*Ellì_BâÇf 8áõ½?©T s;7 hü›HEEE~~þc=MÑ?èõƒ¡!ÔÎ0ì5Dûì˜GöãwŽõòâQ(;i0„B{5$nÄM߈ßàÃáp®£™ ô ôÑÏÏ×Õóc]wMlhh¨©©‘H$‘‘‘øÌ‚ ðAcccuuupp0žäú²ñJyy¹B¡ˆ·D<ôdŸd0òóóÙlvJJ 4Zÿ0°ÖnݺÕ`0üïÿÓét.“víÚ¥Õj᱃†ºººÌÌLƒÁ°mÛ6gsáСCƒaëÖ­¡ï¾ûÎ`0Èd²#GŽ@»ÝŽúh±X¦NÊf³‡ÌÍfóÔ©S9Ž'£ép«€}}¦NêltuuùúúN:¯.›6mÚÔ©S% ,ÆXýk„•ê˜Ófn>Z­ûÇéõúÑ£GâouáÂ…æææxžûÀ²ét6ÅŽêj™ÍöçàãÏ?ï]¿~cmmýÕÜ;v ·ÞB :s}÷B­]‹¾ýÖ±ÒÆF´x12™º»hSS“L&ƒ‡¸á?þøî»ïd2F»téRIII]]]nn®F£A•””\ºtéÖúFJ¥Òùü… ª««gΜ©P(à¹,}$›Õj&ÿi4jrr¦ªªfõê•ÙÙ§®æ–Éпþ…ètÔÙ‰ðbÁ×_Gµµ!TWwUD«V¡¿¼)B111R©ÔËË ;ñeggïÝ»'ÅÆÆJ¥R‹k {L&“^¯¯¨¨¨¬¬|óÍ78ðä“OîÛ·ï7Þ(--ݼyówß}—ŸŸ?`ï?44T©TJ¥Ò‘#Gâ3?üðCaa!BH"‘¨Õj©T:|øp„Pffæ… Þ~ûíóçÏÃsXýëîÈÏ/lhhª¯o|üñy.’§NE99;“™‰.D¡÷ßG\.jlD¯½†þZ\øøãÛç7ïjóçχ§8äååÕÙÙ9bĈU«ViµZì¹ÙÞÞîçç7zôh—ݼ¼¼–/_næßÿþ7>àr¹Ë–-#Ï¿òÊ+ð¸¨ýØZm§ÉdêÅ.ZXB zçÔЀ ²p ðx¼ÆÆÆâââ²²²ú¿cµZ+**AŽÃ4ôý8iÒyy磣#]'ç塆T[‹È5…ß°‘ØÒ‚NB55¤ñ}`ذa&“ ØÅÅÅ †‡zÿ?>>~ùòåJ¥rüøñÐPÀ ÔǦ¦¦ÚZù±£ãªâܹ³»-¦Ñ 9s^õ̘1|ñ*/G7".p-8øKÇÄÄÿ÷õõ…ön¸>úú |}‡»LŠŠŠp<„Þ}½õºë®?Ϭ]‹p¤¦˜?C¢¡ÈH €AÛ¿¶Çf³Z,F„z Ï«X‘å/GÖÕ/#„Å-À„ ¬7VM¦N“©°»eÏž?èô«³.ÞÞ<“ÉäIÀD€ŠÑhd2Yä‹=mÚÄþÓÇÎÎÎ BˆÃáøúú*•*‰$„Çó¾A1Ð<Áf# ÓÓÇ*•-Je›^ß… ìWû‘TF&“a±˜•ÊV¡Pd0èô€›©*•Úb1Q©(88Ðd2»\ÊIrCâ÷ðù‘HD¥"‹Å €ˆÅb¦R‘P(loï¸VûQ©T9ôŽ}}»Ýò­££].—3™L??q»÷ô?z½^©l3Í11±×ª§ eþaÉø¸­µ¹² óùçŸqØqÁƒADCC“ÉìêÒ#„ÔjÍfƒ§ÀÍñéõ†ººz£ÑÄ`0 wè©>rx>Jµ..i„JÙòÖ+nÞº‹cKKk@€¿ýî¶s¹<²,g6L­­j2$ÀM!,,¢¡¡™Íö&·íìÔ_«>žÍ^ÿŽtù«ë÷ý¼-uÜ䨸d„šBÛ¶ý¸`Áã~~âmÛ~\½z%Î|æL^qq BˆÍf …"“ÉtâÄ x0üM}èô#F™Í¦þ¼hKK«^ße6›ÔjµÁ`@…‡G sMú82}Âc‹^úì½ñýB åª%øÃ;—-[dŸ™Åbø …":f2/^¬ ô‡·{ †·7·¾^ÙŸ­ªª;vlkk³Ðjµ©ÕjìŒxMúˆzþõ "Zji4Bn®@¡PD"áï¿´ßã0$$Ä×Wl2F˜¿` ‚£2úù¸³p=¬+PH ãw~¸^*«* t±h6‚BsæÜ^S#Œ¼ºWr{{»N§ 0y À€E¯7”–VLœ˜q­ú8$!m¡¸(?D´íÍ…#?:ÄÔjµ~~â¶6…Bõñ²º3â´ÚÎþ½¢ +£J¥¶Ùl¾¾>×Á~ìÆ ‰O ¿ÿ!ÃØä\B!*•B¡Ðú92CbbRhhŸÏc±þ%>Ÿß¯úøÔSÀ³`b¦ZB±(dØh½³Íæ.„Pdd¸Õj‚Ö`Ð@ t^¥°þ¹AnkeëSQôBÕj y¬RµAƒ0˜ôQç¯#õQ®«Eû "‘Ð>êtà‘À ÅiI´ƒâ‰DníÇ?hC«ýX…ê=W<ãL&—Áð ßÇlÖÞ \/óÑX§WËÿ\±ÃP÷°¹´ }¤RLæ@Ùs• ,&˜%à:qW฻Çy˜ùúÇÇݲe‹ÙÜÇAÌ]»vµµµÙl¶]»v©T*ˆ‡·(t:‹Áà’ÿèt¶Ùl½^V “ée_¹ÕÚ­Ž)•mWú|¥nëU(¥¥¥¥¥¥8bZYYYii©B¡ÀId‡R¿þúëÑ£G­V ÑÖÖ†+´Ùlmmm¸þ––„J¥ÂÇÅÅÅmmm»ví:qâÄÎ;]ÖÀ-Г¥ÐÌæ.òŸN×QQQqýº•6ûÊ/\(ì.gk«bݺ}WùîæÍ›·xñb„ÐåË—i4šÉd¢P(åå寿þú矾bÅ |ÐÚÚŠ‹$$$ÄÅÅ1Âe…_~ùell,B¨¡¡¡¨¨ˆB¡„„„TVV¾üòË_~ùeLLŒJ¥2¾¾¾*•ª¥¥åÎ;ï¤Ñh`AÀ Ãf³íÞý{UU ƒA_°àñììÜû×NžÌ0aÜŽ»››[étúÓO?n0·oÿ !4lXòÌ™Ó<©|Ïž?‚¨¨¸’œœxÏ=Ó“’âãcÈënØð)B())áî»ïÚ¿?óž{fìÝ»ÿþûgõÚ~œ0a¼yóæÍ›W\\\RRRRRRZZzùòelN~õÕW¸ÝÚÚzñ/‚HNNî®Bl?&%%!„/^<ùÒ¥‹ÅBúc·µ©ñAbbœs‘€Oý)Š}¬E{öîÝo³ÙHeĨTê¾èãC=D 2dÇŽA$%%ùúúÎ;7!!¡¬¬lΜ9¥ŠŠŠRRRJJJ‚ÀúxÏ=÷Ðh4„Pbbbaa!BhéÒ¥W®\Á+î¾ûn‡óðÃÆÇÇGGGÃÛƒ‚°Ùï h²sC±Z­¥¥M;•J5j¸ŸŸïúõ½½½( •J !*•" Ç»~ýF„P@€ÿ?þñYƒ^oÐé®VŽ#9þu]b×®=jµ«dvö©’’ò >}å•çcc£öí;„Љ‰¤R©ýú­­ wj[d(ÊêÊBñϲf§ÏD±ÙG8@ZÙhìèêRÃÛ·š>Rª««íÏøúŠ‘r²³sƒƒõzÃ¥KÅ=6דÊÕêv•Jeo3FEEàãõë7’½¸Áf³íߟ™÷Ë/¿9äogöš"„Ž}vŒîRø­Ö²Ê\|àV„B!ÂÂvÇØ±©¿ý¶ŸNgx(Ž!‘H  \&Ý{ïLOj R©‘‘.\ºï¾Y½ë_Z£Q €~€Á`Ì™sÿõª-))¾Ç<]4sµ?Â7m„/B¨)BÜ.¦˜ÁïY1&ªå¸9çïfBXȹ?m†£™ ÐCÿº©¹µ°ð2´ƒN‰O’È ã“©Wõ188(5u4´ƒ›6š—$J‚ƒ±ªhÈ褄Íj±e²Zh>3~LäÁQ¯ïR«•< X]ô¯1ÿxú…qãïtfàÖÇl6±)¡ Bÿv–@-:¹¼qÈ¿M;êc°$ä½ )ÐG!õuµÛ¾ûxHc´LVËårh4ºX,j×tcb"""2ƒ·,‚vGB§‹%ð½½9mm*¥ÒÅv„àßÀm Fçó½Bb±ŽLÖ;}üßÛa…ƒ___›íÏÙ??_‹ÅÒ‹þõ}¿íûmÏÜGæC;0øèèЕ””àc‚@Pé©>JBÆÀ D¯×ŠÅ>äÇ€€à^ô¯‡ -Àm‹;}l¨¯ëh×4Ô×u´·CKúx•ãGÄ%$8~¬ºú ´·îÆj4`?º@«íp8sèÀ¾>¸ûØ÷[wIG3ÚoLAÒÙÙÙÞ®¹ŽßS§Óµk\WØ¥Ói4}ÙÂAÛqµ}2î·Z-.*ïêjl¨ol¨Ç®ú®.ò!tøà~g—n}¬©ªÚo'mZmeE•Ú³Kù?þ&ˆŠ \fëìì,))f2™ÎIµrYEyÙuüžõuµ¥¥Å.ï°¾¾®¬¤¸·ž:™ýî;oÛ‹l¥«íÏ·nÞt$óà‘̃»wíÐwuýôÃö#™÷þú3–E£É؇Kpóû×ÃFŒDíß÷Û¬{îCmúüÓ•/¯þË\ú£ ÿBè¹å+itÚŸn´Ù¬C‡˜uïý¬_{âØÑ …/¿úî®þ­[¾Z°h1>þ÷›¯RY^þ…ÏŠ}}íßš6!thÿ¾i3féõ]çÏåM˜8Ù¾†_vþT+—†§Ÿ}ÎËËûë/>3 ‰É÷=0çä‰ã§OD-X´$ 0ðÐ}Á’4ö„ÐgpèÀ –¯|ÙÛÛ;óÀAcÆ!„PNvVNvBè©§Ÿ‘ÕT«ÚÚ.],Š‹Ÿ=ça¼ #æâ…B«Õ"\Ýcöœ¹ëÖH_}CêðÇO˜8|ä¨3¹9ƒá·½»'Nž³ó§je5Q1±÷Ü÷Àº5Ò!ÆË·˜>b‰.*<ßÜÔØÜÔ4uúL…BÑÜÔ…•T(­[#%GÖ¶mùÚeýO?³dë–¯ñ²pooÞÄ)SÙl6¬7¬+*84ó Bè‡ï¾]ð̒蘸¬£‡jËd¬[³n4cÒ”ñ“¾ùê‹uk¤ú®.ooÞÅ¢B|‡þ¡O?ÞPTpþÐ}¸`@`к5Ò¢‚„Ð6~XTpþà¿#„ƒ‚×­‘®[#½ãÎ ‡K¥ÑB×Á|¾x¡pÝiQÁùuk¤xéç?=4ïQçï¸í›¯Î俬[#ý}ïîû˜SX¿n40(8<"!´w÷®ÙÎ…×n ±±‰QQ1ý‹Öju(E†¢¬®,„ÿ,kvúÌÇžXñÓÏ{»‹ÿx¡¨`è°žLÑxÈåK㻳{ÄåßM¡¨àüˆQ£û§}¦¾®ö§mŸ®Zµ¢ àBzú³YÏQ\|eÈØv†a¯ù BèØgÇzÿñº/Ç2tصŸ>ëžÒè}“9GȸÓÇ̃û òóBË^XÅãñ:pþÜÙeÏ¿ÄãóÈÝ•€„»žryiÉ«oHŸñ•­[6>tÀÇÇçÕ7¤›>ÿÄjµBÃp[ëãŠ_îÒé¾Ù¼iÅÊ—/ž>r4BˆJ¥BÄ\nw}ìêÒ}óõ—Ë_x ¶ëôño¬_û̲M©ìÒé¦Þ5óhæA¥BÁd±œ]%îægÂÂÂ÷îÞ…1:%%5½° Ï/;—=ÿâuôï¸%õqáâ¥öGŽJùb Bz}—Ù£‡õaræðÁýÝ%8vÔe|3ƒAߥÓݸ¯­V«tºN|\Tp^ÑÚê2›F­Vµµé:;“ŒF£ª­l¾µ ·ª>–gÚI›^¯¿t±È“ÎõáCì?žÏÏs™Í`Ð仌oVY^Þ]T´k'7ç䎿ÿöëMJE+BhĨÑ[·lrV·¼3§ü~ÛÏ;úò?Ÿ8ÄŽ4Û·nùyçO¿ïÙ jÔêª+•ð>Àí¢£RR}}ýH‰üü“–¿° ;’‰×)wvv ú÷ß{gÝéÁýû‚ذnÍ'¾¿n´Çȯ›7}±hÉ2|¼ößoíÿ}ï‡ëßÅJt$ó`[›'Étà÷=» ‚Ø·÷×®_·FÚ¦T:”ÊÎ:ºdÙó+^|yËW_à3þ­-ÍÙøþS žyêégøíïÚvýïdzî}ö¹å õu¡9?òËΟà}€ÁDë G¥¤nxoÍ”iÓæ¬óΜ^¼ìy„PYIqvÖ±§ž~†Éd~ùÙ'“¦LuŽoæIˆZS]åßìžû@øã7YuõÂÅKâ› 6<*&!´é?Ÿøúú-^¶bó—ÿûúµµ)wüøý×Û¾çp8}^£˜l4¿ûæëùO.ðê)È·>=|hâä)XÙl¶Á Çñu&Lœ¼ãÇïB‘QÑ¡Ÿÿ÷#N÷‹íã› z6›ƒZ²ìy—•³Y,£ÁÐc|³¸„„“'ŽGDE1™L‡øf°ŽÃᚌFƒÁàP*&.ŽÍf»¬B¡Úl6³ÙÌd±ð›ÍFq709‰£Éd´X,\®‹Å4™Œ!›ÍŠL&“É‚÷ n—þõ©“Ù|>?5},þ¸|åªÿlüçŸ;£Q«4j•P(š4ešV«Õ¨U ‰IEŠäáð_83Ígž[¾å«Ïq|36›sgÆ$‹%õã ëòóÎâøfß|½iá⥡¡áÇŽd:ÔÀåp5j•Õjåp8L‹J¡L½k&‹Å¢R¨•åï¿ûκ5Òqã'8”º÷þ6¼·æóO?ÂÂm25ju@@ C¶Ý?שּׂ•¶ñƒuk¤¡=¿ì’¾þ*Bhî#óO?Šcè⸹;úþáGçÃû·õõ ùù…ä?çÉ•ÞÅ7+ÈÏ1*å:ú?^(,H2´ÏñÍÜày·º¤øRDD×ËëZ.—Ÿw&%m ¼p0Ð5Ñ.¾™@ð·P;ÁÞÞ¬¾Ç7•’v}ïuøÈQ7¨¦Ü5ÃÜIÉC¯ýr Ž0øp§ë×þAØB£SÓ§MŸiŸd4?ùðý£Fß5cÖÀüb© XÜ8}\ýú[¡ãG;÷=?ùðý—_}½° ?óàþ+‘×B#‰§NföÉÃGŽt8çmG§¤tãû 0ÈõñŽ;'ìþýÐÆÖCKúx•cG2;;µZÒ³ï­ýÓfµ"„ØnG{{Ö±#“¦B#0(q7þÈãññÖ¬/¾¼Ÿ B Bhåª~ñÙÆ‘£RÆÞ1€ÛNSÓǤ¦ÿmxéó/^=^±š€Û´ ö#ÀmG``Bù‘ÃñBÈ ú€èt ‹õçâf›ÍÖÔÔ(‘øAÿ©Õjò¸¦Fî°ô€Û®Óh´`ã±½½Ã9è#·» éÒxDÎã6›M.«é.¾À-M{ûÕ½¤(ª^ß%“5ttt |„(=èãØ´!»ú€ÁÊwŽCI$A!!áIf³þoúXS[#¯–#„†QãB/¼ð4ƒž€5$‘çÉBT*•I!œ:¾È>t´à}\0IP``€;óŽ;B– !Tk®EñëX#ƒ“4šöˆˆ0¬Œ¾¾~F£…Ífùøˆ }¸åhhhär½˜LªZ­éììDˆ P(¡¡ÝYŽ,‰òz¹ ÿp¬ŒB¡Àf³^ŒŽŽs_ÀÀ¤®NŸÄdÒ|E"¡Z­Ñé:=/îèßãåÅ‹ŽŽáó½l6 4.ƒ¬’Tj/ :ê£N§-.¾ÜØØlß]¸Õ±ÙlUU5jµÊó".¤”ÅbéõúÒÒr¡PˆÏ€VpK+cM¼½½C à»ô÷T½½yÁäGµºÓÛ›WRR À-›íÍåz555ÿ¥l½ðÉqÔÇôô¿mHœƒ999€[³CTÏ'œ¯ê£fÑ0\£ À€`ðЬ©úhJ±þf>äœ[vN–16Cn‘Cƒ08åÉ2îÈ›{5Ïâ÷€íÀ`Â3M£×ÔÖûé˜ûL¶F›¬VM À é\S(¶&›¬®YûjÆûþ;ÎIEND®B`‚snd-16.1/pix/pyr.png0000644000076400007640000001540311147553270012463 0ustar bilbil‰PNG  IHDR,ë\…<š pHYsaa¨?§itIME×1ntCá¢IDATxÚíi\ÉÝÇg9FN„9•C”Ë]Á+QpQ «Ëj²FcV#&$YW]ãeƒ¢(r'‚¢ÂÊ rˆè2 (G¸9äz^̳ó!\"ÎÑÝóû¾êizf¨ý¿ÓUÝ]UôÁÁA@|0 !@( KJJÚÛÛÇ[rròùóçKKKA,á±cÇ8ÐÜÜ<Î{JJJêëëÿûß#‚|$ô‘WGCCCY,–¾¾þXïùÛßþ¶gÏyyùâââ‚‚OOOÞþ«W¯;ØÄÄÄÁÁÔ1JII©©©!w5ÓéÞÞÞHwb2eïéìì”——§ÑhŠŠŠCkzñâÅþ}ûöÖ­[ïß¿¯££CÒ±Ùì;vºšSSS ç΋Œ§ˆ„ãüÜÛ)##óòå˾¾>’èÉ“'ööö#ËE. cbbètº……’žè}‰ ­­ÍkžUVVêééQ;@)))...(ˆ‡‡GllìÀÀ’žÐVVV&&&¤¥¥åççó÷ûúúm­\¹òË/¿¼zõê¹sç–/_Náè´´´ÈÈÈ0™LjgçÎ!!!ýýýÈ{â6GåääÔÕÕyZ¦M›Æß¿ÿ~:Ω§§wâĉææfWWWjG§¨¨ÈÜÜœ2ÅÑÔÔTVVær¹h”WB ‘™™™ ÛcdddddDùèäååùùùQ©D7nŒŒŒ”’’255Eö“¸O(!äçç(++S¬\žžž±±±½½½¨bHHt(|ÙiÛ¶mׯ_÷îjš'OžXYYQ²hººº %%%¨eHHh­­­)\@ww÷ÂÂB<ý ‰ ‡ÃY²d µË¸eË–˜˜4J!!yûömww·ššåK !!AIKK[¶l™$”T___QQ±°°• ‰EEEŬY³$¤°ëÖ­{öìYYYê…§OŸjkkOŸ>]rŠìíí}ýúuò>d ©FYY™$< 4²s‰ÇJ©#aooïÛŸ!]§¿  ÀÒÒRÒòÀÐÐPMM-77Jˆž)ÂøÐ¼¼<‡ÃÛÎÉɤÀÕÕ544TSSsœI€P2.\ ÑhåååƒdàôéÓƒÌáÇhAŸðxýúµD]’‰ÏåË—‘ ¸0#"""6mÚ$áA000Ð××OMME>@B1ÐÔÔ¤®®Ž8,Y²¤¦¦¦¼¼¡€„h‹Š)'Œ-[¶„……!P¤DFF¢-ÊGJJ BBQSZZjbb‚8ð122êïïG£ŠˆçÏŸJII!CñòòÊÌÌ„‡Pp8'''ÄaÒÒÒK—.MNNF( ¡Ð©««ÓÔÔDF¢­­Íb±ÂÃà H(D¢¢¢Ö¯_/--PŒÊìÙ³»»»+++ H(,jkkgΜ‰8ŒÃÖ­[9NUUB …›7oTTT‡q‘‘quu½qãB Oll¬‡‡òཨ««»¸¸DFF"PÀp¹Ü9sæ &‚™™Y[[Ù×K…„Ä¢®®N]]—d&ŽŸŸßÝ»wëêê "”A½'%%…·=t‰5¢qýúu$ÁÄ‘––öôô<{öì BKèèèèèèÈÛNLL$fáùë~ƒ‰£  àææƒ¾4š£Ë7V­Z…¶è$˜;wn]]]SSB ? .—‹5ú&ÍW_}uýúõææf„Nž®®®©S§"&™7 Æž={NŸ>=88ˆh@ÂÉpëÖ­Õ«W£ú?’_þò—ñññðN†¼¼<[[[TÿG2þüªª*4J!áÓÝÝ-##Ã`à‘=°gÏž°°°ÖÖV„~Gýæ›oP÷‚bïÞ½ßÿ=¥p¢ 0 :Žº k×®½yó&<„„"55UBÖ%666555õõõ$|?”_[,ìÚµ+<<¼½½¡€„ã{ƒÂîžT¹°µµ1cÆíÛ·Љ )#ëß¾} E‰½½ý?þñææf555Dã=HÈrÙ'OžliiÁÊ̢䧟~ ijjB(°\6­¹¹™Á``rQ£¨¨hmmÍáp ô ieeeFFF¨lÑcee5cÆŒ¤¤$„BÒ%LLL\µj*[,,Z´¨¤¤c%ZB,‚-v|}}à¡äJçî#Ó¦M³³³KMME($Qžžžææf---Ô´x±°°ÐÔÔä߸$a]]–=#ŽŽŽ………˜Câ$LIIqvvF5??¿¸¸8x(AÖÕÕõööêêꢚ ‚’’’££ãÍ›7 ’mQ¢all¬££sïÞ=„B"$¼qãÆºuëPÇDcéÒ¥=êèè@((.!V¢'2»ví ëììD(¨,aJJŠ‹‹ *˜˜0™ÌuëÖ]½z¡ ¬„ýýýåååx^”ÈhkkâñnaIøîÝ»ŽŸééé}©ŠŠŠ,,,P»ÇÅÅ%==½··WÂã ”A½ùùùü_¸œœ±Hˆõ^HÁ¾}û¾ÿþûßþö·RRR’ê ê­®®¾pᆊ’…ÖÖÖãÇcP/¥¨««Ãâ$BIIÉÂÂ"33}BêpóæÍ5kÖ ¹IÄgŸ}&É©&amm­––]"‡úë_ÿ ©@UU%#²²²ÖÖÖYYYô°ÙìåË—#§Éˆ««kkkkvv6$$1999666ÒÒÒHhòz˜œœÜßß ÉJEE…žžR™Ô|ýõ×gÏž•¨;ø”’ðÙ³gæææÈcRÃd2ŒŒ2q;$ü0²³³ííí‘Ä`ÕªU¯_¿ÎÍÍ…„$#==ÝÉÉ L V¯^Íf³Åòà1$œ$¯_¿–——Ç’/Tâ‹/¾ ëîä ??ßÚÚ‰K%ÔÕÕuttž}úg‰blllllÌ?+ µ>ôóóCšRžõë×=ztΜ9rrr8ˆŽŽŽ¾¾>eeeä¨$àííE½;‡ä–ðÎ;®®®ÈN A[[[OOïáÇ@TWWëèè ;%‹ÕÜÜ\XX Á£GŒUTTš…‡‡G||ü»wï ¡ø)--511ARJ ¾¾¾×®]£Ì˜CKøüùsH(±C333Ê,¾MV ?~lccƒt”XìííÛÚÚŠ‹‹!¡Øàp8ŽŽŽÈEIÆÓÓ3**jppЇ7oÞà’ Ø¹s'oH(j.]º„§dFÓÒÒZ´hQll,$5mmmJJJHA@£ÑæÎÛßßÏår!!Ú¢@<Ðét‹•–– EGhh¨¯¯/’ðÑÐÐøÅ/~ E†ð‚‘hkk3™Ì’’H(t¸\îœ9s Ò ãóÏ?ÿñÇÉè¡PÆñÇ_ v¹ì”” ¢£"%%µbÅŠË—/Ï™3ÒfΜ)##ÃÛ.//à'·´´¨ªª"áÀ¨¨¨¨lذ!$$Äßß_Ò%TUUå«2cÆ A}lXX˜———””² Œ…®®®¬¬ì‹/øs; O(Hêëë555‘g`|6oÞœ››[VV OGG&ºénذ!:: ˜k×®yyy!ÃÀD““Û´iShh($$/_¾444Dz ¢¯¯?00 ‚io%EÂêêj---\’„ŸŸ_JJ ñ=$‡„W®\Ù¶m² |t:ýW¿úUhhèÀÀ$üXz{{¥¥¥‘U`lÙ²%22’È’@Âèèh<ª&‡±±qwwwUU$œ<ÅÅŦ¦¦H&ð1ÃäääêêjH8úûûét:Nƒà#Ù±cÇÅ‹ûûû!á“°víZäøx6nÜG@ -a___QQ‘••|<¦¦¦ÝÝÝ‚Q@} ñœ,ÞÞÞl6[ØËõQJ“'OîÝ»©È®]»‚ƒƒ uÇB(C™8ŠòüüüÉ}HOO¬¬,’¸¸8www:N„ÿ‡.ì ŒƒƒƒwîÜY^^>kÖ¬zã;wTTT°6‘‘‘–––fffhŽŽGVV BÂÓÓóÞ½{ pL0³(6NNNééépLòòòlmm‘(@xXXX˜™™aì/A%ÌÈÈX²d Ûæ¦¦úúzH8œ¦¦&uuu¤Û·o¿uë–xïQÂíÛ·#?€––^¸p¡x;‡„“°³³“F£M:ùDƒ™™™©©i\\$üZ[[q]ˆ˜yóæ566Š«QJ8 #""0Ñ==>>>IIIµµµ’.amm­‚‚¢gêÔ© .Ë:‡Ä’ó1bbbbffvãÆ ‰–Íf/_¾ÙÄ…µµumm­ˆïHÂêêjä{çðîÝ»¢ô@ÆÇǯ[·IÄ‹¼¼üÒ¥K%N®®®ööv $;zzz–––7oÞ”, +**>tÀ!ÂÃÎή¼¼¼©©IßE”‘õgõêÕ¨{@üýýÃÃÃׯ_¯¦¦F> yÛÁÁÁïm^WVVN™2E[[Õ9\»vmddd@@õ›£5550 ›Û·oS_»wï®\¹Uˆ½½=—Ëmkk£²„•••zzz¨l@X¾úê«+W®üôÓO”•055ÕÙÙ5 ‹¬¬¬ŸŸßùóç©)a___uu5nN‚£¨¨¸hÑ¢¤¤$ JøøñcÔ1 >‹-ÊËËëé顚„\.k²ðÍ7ß?~¼··—:–—— v)`0‡úóŸÿL 333-Z„ªäÂÅÅ…ÿ@é%d³Ù+V¬@¥ráè蘕•%ÀF©Ø$¬ªªúä“OP£€Œ _¼xallŒ*dGAAÁÂÂ"''çc>D #ëÓÓÓY,êP¦s˜šššžžîää4É2.\ Ñhåååü=ß~ûmggç âØ±cííí“{¯¨›£õõõJJJXt PŒíÛ·GEEµ··“ O˜““óé§Ÿ¢ÎÅPVVž={öä:‡¢–°¤¤dΜ9¨3@=–,Y288øàÁBK˜žžngg§  € ”dÅŠÙÙÙ:†H%¬¬¬ÔÕÕEU ãããûAŠT²²2###Ô 0êêꦦ¦Ô(„‡?#0ÆÞÞžF£eeeNB\’ƒ««kFFÆg‘„ííít:Éd¢z€„àëëýöí[¢Hˆµ¤1}úôùóç³Ùl¢HØÐЀµ¤amm=eÊ”ÜÜ\BHÈb±¦M›†Z’ÆêÕ«SRRº»»Å/¡­­-êH&;vì¸|ùò»wï&*afff``à•+WÆzÏÀÀ@xxøþð‡ŒŒ „€ñQWWwrrŠ‹‹›„}}}©©©AAA=*--ë=………rrrûöí;sæL?¢ Àø˜ššN:u¬U«éƒƒƒüÿüç?ׯ_¯©©I£Ñƒ‚‚F}ÿOUUUÉÉÉþþþ¼ýýýýúÓŸ†œ——wçβ²2!­Æår•••µ´´„Á´´´eË– ïóÛÚÚÊÊÊ„º&‡°‹ ‚¯(..VUUå%'‹ÐÒÒþõ×_ü“ GÖKIIô–5<­€¾¾¾Ð%+++¡^•)--URRêäGÍ\0±3ayyùüùóÉ[|EII‰ŠŠŠPot »£ÿaè0û‡Þ¾}{pp°¨¨(22r¬Ñøááá\.wpp0!!!77wü¡û‡ê´ÿùÏ?~,Ô¯v*++ÿõ¯‘º"øŠØØØ§OŸ’ºc}þÿœ >ÿüóìì쌌Œ¨¨(þ~ggg™;wîð^.[¶lË–-•••W¯^ï)ÞÈÈHYY™Ô­&“9wî\²·µ.\ˆ"LŽáÍÑ«W¯vvv8p@^^ž¿3>>~X7/!!¡··wè1â‚ìu¯¢¢BGÛW®\‰"FB™a;‡íÁèx…П˜¡ÀjØ(˜5k–ªª*%káîÈ}&üñÇ#"" Ç?,)))""âõë׈> $ÉÉÉMMMã——QRR"` »ººçÍ›·{÷îqžeKKKëííe2™GŽAmêqÿþýÔÔÔçÏŸu@SSSFF†©©éîÝ»,áÅ‹·oßnffÅ›ú~TrrrœW¯^íææöÞqV€F£½|ùrü•™ù?¨?ŠÏëׯ›››%§¾²³³ysÌŒExx¸··÷üùóCBB.^¼(H §OŸN£Ñ444Æ9aòæÀWPP˜ÈÈÒÝÝýÅ_|ûí·Cw–••¥¦¦Òh´ŠŠ //¯ÀÀÀ3gÎŒºr]LLÌ®]»‡ÝøU¿ƒ²X¬±¦*yøðᆠöîÝ;»lmmmmmó›ßp¹Ü‘ddd¬Y³æÐ¡C ¹sçBBBF®öññ >~ùòåãߺknnVSS£ÑhÓ§OçuÊ4ð¡ÝhCMM-&&f¨-YYY¼gW­Zµÿþ   OOÏ¿üå/Ã<ÌÏÏ?}úôÑ£Gƒ‚‚”••øá‡q¾HNNníÚµ---c0mÚ´eË–½wŠËÒÒÒcÇŽ={öìÙ³III‡îëëvŒ’’‹ÅšàÏbIIIDDDmmíÈ?mܸÑÏÏ/((ÈÛÛûïÿ{{{;“ÉܰaéS§(>lhh¨®®žÄ…hI¨««[UUÅ;Ìš5k¬Ã˜L&/iZ[[Iú¤‹ŒŒÌ¦M›<È{Ù××·lÙ²­[·Òéôÿþ÷¿vvvæææ¼ß¹œœœaóOøùùñ ®««ûÃ?ŒÓjÐÖÖ¶··—’’ë 33³÷þÃ>¼té’½½½½½=›Í¾}ûöÈS«¥¥åìÙ³'Rü·o߯ÇÇ:{e]]‰‰É‚ h4šªª*—ËMJJâýX˜››GGGS[B.—ûêÕ«ÀÀÀ°°0^³h¬j­©©¡ÑhUUU¼¹°&¡———¯¯ïƒ|||¶mÛÆßïîîþÝwßñ_ÚÛÛïÛ·/,,ìþýûVVV$ ·‚‚‚‡‡o»²²ÒÙÙ™·¥¬¬Ì_Ü××÷Ò¥KCßxéÒ%þ.}}}ƒqjKPøúúò·utt>ùä“I/TÞ×׳iÓ¦QÿzëÖ-:.''7²ønnnÙÙÙãœÕ)‹Å:qâÄúõëmll†zùò¥³³ó½{÷x/=<<¶oßž––öë_ÿzóæÍ4Ž¢““;þ|yyyHHÈÐ^_‘Ç’%K¦L™ÒÞÞþÇ?þ‘¼á600ào‡„„èëë“å?ŽŽùÔDèííýî»ï¶lÙ2‰µ ”””333׬YCíóaWW—¹¹9¯×ÇcÆŒ¿ûÝïLMMy/UUUOœ8QUUÌÛ#È¡L&&&&&&Ãv.]ºtØt,ÅB}}ý›7o&÷ögÏžåå幺º¶´´Ô××ËÊÊ>yòdþüùt:±'½™LægŸ}6t©©)ßIšÆJêêêuuuC÷ ÿ6쥬¬¬È:Æÿþ÷¿wîÜÉ`L²ÿâÅ oooÞE:þàÁƒ'Ožð·ªªªÒÒÒã”÷ÂŒ$‹Çßöññyöìÿ²¯í7ôàýû÷ߺu‹·]UUÕÐÐàææ&£££wíÚÅ3pr×HŽ9Rø3þþþ………C»—6lhjjjllµørrr“kSœ ?–={öØÙÙ>|˜÷òÔ©S‰‰‰vvvùùùŠŠŠÃ&¿Y°`AcccFF†¶¶öÅ‹ǟѤµµ5!!¡«««¢¢¢¿¿¨íêo?›Í®©©QQQi€‚‚þü\³gÏÙÙHLLä?‚ëâ⢣£3êçäåå ݳyóæaÖâããß¼yÃÛ^¹rå{§ ÉÏÏ—’’š7oÞÈ?½zõŠÃáÐh´µk×òÇ=¤¥¥1 ‹…„„ÂâÈ‘##gš<ŠŠŠ¸\.ÿ¦@ŸP(¬Y³&%%qõÄX\\ q&gB$ ! €„H$@B ! €„H€„@B$ ! €„H$@B !@yþ¾ûùôÀ¥•’IEND®B`‚snd-16.1/pix/fmtime.png0000644000076400007640000005251411147553267013144 0ustar bilbil‰PNG  IHDR šQÉ,æsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ Ùý/Ï IDATxÚìwTTW÷÷¿Cï½#  Šb‰ÅÞÅE£1‰-æI4*ö¨Q+–h4Ö`ì%vEÄ^ EA¤÷ÞgÞ?|™ŸH™{§—ýY˵äΩûž{ïÙ眽7‡ÏçóAAA!4HAAA(ŒòîÝ;<{öŒQa'NœÀ’%Kðþý{’,A!BBB¥+((À’%K°sçNA„²( ïÞ½C@@#äĉÐÑÑÁ„ pôèQÄÅÅ‘t ‚ ‰²wï^üþûïBÓ¥¦¦bóæÍ˜0a¼¼¼°mÛ6ðx< A„"+ éééØ¿?ÆϨ ³gÏbàÀpvvÆÐ¡CqðàÁj¿óx_¤|Ÿ·G”ÛLÍ{ØÊB\ù‹*{i”#jLïÛqÀô¾I:Û´ª6Dy¶ElžIiµY™Ù¿?4hooo¡i¯_¿ŽV­ZÁÙÙ>>>xúô)ÊËËkŒßÚþ)º\Ù>«„jB 5¡Ìc NÄÊÊ ‹/†¡¡¡D*Z³f ¦L™RíߨQ£Àår‘œœÌꃿråJôèÑC¬öÌ™3C† aoèСxñ⣴ááá;v,£´¦¦¦8wîœÐtÆÆÆ¸pá‚ÐtGÅ¥K—Õíëë‹E‹1–Á;wÀårEž|N˜0ßÿ½ØcjÉ’%èÓ§Xe|ûí·˜:u*ë|8v죴˜6m£´ýõž¶cÇŽE·nÝ$RÖÛ·ok|“¦L™///Œ7N¡•ï¿ÿ¡¡¡4ûRc<ˆ%K– Ôœ &¨ž"iæÍ›‡]»vUû÷ǰ.§¬¬ >|€›››Èm)++—Ë…¦¦&«|ÇŽCûöíqåÊFé: ÊüÆnÚ´‰ÕdŠ-ÖÖÖ"M|ž>}Š–-[‚ÃáˆUyy98¸\®ÈeA___¤¼úúú¬îknn.JKK…®d¤§§3Zñ(//ǺuëÕÄxââbÆý²´´Dff&kù]¹r½zõ{CWWMš4ÁëׯE.çÌ™3àóù¬ûbllŒ¼¼<ÆéCBB““#ôý¤¡¡Õ«W M§©©)4Q; 6¬ñMÚµkºté¢Ðíæñxf5îÕcÿþýàp8Õvõõ";;zzzÈÍÍU/äøñãÕ [´h§OŸnܸ!±Uªºèܹ3nß¾-RÞ¨¨(XYY¡S§NˆŒŒdœ/))‰õŠoÏž=qõêU™ßXF;*¢²bÅ ,X°€u¾ÜÜ\˜˜˜ÀÕÕïÞ½¹þ÷ïßC[[¾¾¾‚qÇ–ÐÐPtëÖ ööö¬'tíÚ·nÝb”öìÙ³ÈÍÍEDDD½é °|ùr¡ååååáÇb)_µ‘œœŒ¢¢"V;[³gÏÆš5kXוžž777èèè ##Cä6?|ø­Zµ‚††|ú1‚ñNØ7еkW¡éÞ½{###¡ŠJll,LMM‘••E_âÿÿüüúë¯%ÞÛÛ[ðÌ%$$ÀÎÎNâÏŒ¼1bŽ?N7]±³³ƒ¶¶69ýQcvî܉víÚáßÿU-$==þþþعs'Î;DEE ~ûömµ äÔ©SqóæMøûûÃÛÛ;v”Jƒ_½zOOOtèÐwïÞ«,OOO±VMU“'Oâ믿†¦¦&££!˜˜±êmРâããÅn³f͉« MMMØÙÙ!11‘qžèèh¸»»3NéÒ%ôíÛWæ÷6''IIIhÒ¤‰TÊÏÈÈ€¥¥¥ÈùŒŒ ­­-÷ ´( ‰¦M›2N&µ÷¢º°ÿ~øûû#;;þþþÕöòòrÜ¿%%%€¦M›bĈ‚ïX@@ë]o‚ B:Ô¹deeUïÑ9sæTû[GGÓ§O—zƒ7oÞŒ   ¼zõJ.ãp87þ«¨¨€î߿֛¶}ûö¸wïú÷ï/‘º‹‹‹áè舔”|øðBó\¼xAAA8räëúx<444”Ú€r×®]˜9s&æÍ›'ñ²ûöí‹K—.¡uëÖb—UåøAKKK*rxðàüüüDÞ‰”èJІ†È6Iÿý÷úôéƒëׯ³Ê·aÃÁßߟ¾$2bìØ±uÚÕ™™™á¿ÿþ«vÍÅÅ…ñDe¡¢¢šššb;b!”—ªï(A(34‚Yâíí÷ïß =Á†3fàĉHHH¨7]hh(F­Ô[®ûöíShOyãááQm§Qˆ»K¤ Œ3Fìmè/¾ø=’j;Û¶m‹Ð@'Dæ‡~ÀöíÛIjÌ¿ÿþ‹o¾ù†A¢ldeeÁÜÜ\ªu”””@KKK¢«‡¢—Îÿ'((ˆ±‹hu§{÷îBW÷³²²`ff¦t};{ö, $‘² „3gÎHµ½C‡ÅÉ“'iPA¤€¨ãäUÚÇ&^½zgggɼ'OžÄСC¥^OÆ +RÞÖ­[ãñãÇ"ט˜GGGz‚%øLˆâÙÀÀúúú"»‚íÖ­nܸ!r»ÓÒÒ`mmM7 ‚ H‘ééé£Wwwwdgg‹åA‡ yyyxÿþ=š5k¦ðr’•ѳ‹‹‹Èï›7o.Ô+Äñ†FˆôôôX»¯­ò% g¡Žˆ³DÐ ”›²²2”——ÃÁÁùùùJi¦T È£GЦM—Ë;2›Uøª¨¹Ò2è%DC[[eeeb•!/WÉêþòÔÑÑQ‰¾p¹\©øâ÷ññAXX˜ÐtíÛ·Gxx8 *5côèÑ8tè ‚Æ B ÉÉÉA^^z÷8±çA¤€È{{{±¢'3AÜx„ô¨r§+‹U$&†à¡¡¡èÔ©Ý#ªÞ*æÍ›'Ñ`€?FëÖ­áääÄÈáÓtAA ˆšÐ²eK‘å‰Ëÿþ÷?lÙ²E¢e~z N”¼VVV so>|(ØQ“6]»vÅÍ›7ëMsìØ1Œ9RhY6lÀÌ™3éáúŒÉ“'cÇŽ"+¢ŠB•[`aìß¿¿N—´AA !ñáÇzÓDEE1ŠýQÅöíÛ1eʑڳuëVL:Uì~=xðmÛ¶UŠ{P8S’¼ÿÎÎÎj?¾¯^½Šž={²ïòâÞ½{øòË/%Zfrr2ìììèEGA(\YW‰ÀÀ@ » ù¥jsDDš7o.—º£¢¢`ffÆx'çíÛ·hذ¡Ü”6‘º•»wïbôèÑr©ûöíÛèܹ3ãôÏŸ?‡··7½p”ÀÀ@DFFø±^Y8‚ ”™ï€xyy!((AAAX¹r¥Ì;\^^N†äµ0lØ0„„„ „PYY ¥ˆB»k×.Lœ8‘Už‰'b÷îÝt£…PVVFï" @ð]êÚµ«Â¶3""B)<1A(œ"I|||pçÎVy¶oߎɓ'‹U¯*º~õôôÄëׯeZg»vípÿþ}±ËéÑ£®]»&s™uíÚU¬Šˆ___\¸pAìrFÿýWæí9r$Ž=*ñr---Å·QVŒ+V¬À‚ ÄZH ˜£¨v1A) JAvv6ÌÌÌTnr`mm Ìœ9ëׯšÇÁÁ‰‰‰4zU”±cÇbÿþýBÓY[[‹\\Nœ8áǺwïÎjŠŒèeË¢E‹HA) Äÿ‘šš 333¡çÉsrr`ddMMM!w®]»†=zÚ¶m‹‡’P2|øpœ8q‚AABH–sçÎaÀ€+/::ÎÎÎ*=ZÞ”””@WWWð·´ŽÕ)ùùùÈÎÎVË]‰¢¢"èëë þîÖ­®_¿.Õ:µµµQZZJ!!ÞÇ[C|><„¡Æhkk+elBrèé顸¸˜â#±±±rs¿JgÙ²eÕŽ¦xxx **J-eQZZŠ’’«]ß?ÖéììLQÅ ¥ÀÕÕeeeHJJ"a¨ prr|ûí·8pà EÍ E§Në֭ìY³H!ˆÚHNNŸÏ‡ƒƒƒXåðx<<}ú­[·&¡ª1©©©(++ƒ££# ƒ µ‚maBõ8sæ  ¤Ô} „ U[ÄÚÚÚb•ÃçóQXXªS^^>Ÿ¯G---QQQœœº1AA !IŠ‹‹Áãñ`hhprrBBB †PkLLLPYY‰‚‚AA"}}}ÒH`@ff&ÊËËakk àc ¾›7oʽ]\.t“Ôùe¦¡‡£vF¹ÚÚÚ(//§@A¢,¬Zµ óçϧ‘ Ähjj¢mÛ¶'a(!öööHMMEee¥Xå888€Ëå"..N%äâêêʨ/½zõ•+Wh AJWÖFFF"00——'Óº‹ŠŠ‡ &°Îû©× ¶8::Š•ŸPRRR;@l±±±Ajj*llljüvãÆ tíÚU-eêââ‚> ²²RíãÜ;v #FŒ4nÜoÞ¼¡‡N"22†¶mÛ’P‚ ¤ˆÌw@¼¼¼„   ¬\¹R¦uóx<”––BOOu^qܜ͘17n”ùÍ566†žžRSSi¤Kˆ}ûöaܸqŒÓ?yò­ZµP¿»Äüü|©¹ÁurrBzz:JJJä.¿wïÞÁÑÑ\.WmÆLee%âããáêê*4mVVÌÍÍéA“1‚ï’"/Ü¿íÚµ£F) „⢯¯mmmdgg“0䄤ãÁœ={–u€K+++äää(D°ª””XYY©ÕNÇCZZììì$Væ®]»0qâDzÀÔŒ7oÞ qãÆ$‚ H!T‡¾}ûââÅ‹$¦²²Rê»m۶ŃHØ Lyy9´´´HA) ò qãÆxýúµÌëuwwGtt´J gggr«Ë---XYY!99Y¥úemm´´4VyZ¶l‰§OŸÒ  ‚ Buõë×cæÌ™5®·hÑÏŸ?—y{¼¼¼F‹ŠÄóçÏѸqc…Ð& ðù|$&&2γhÑ"üþûïo‹žž*++Y¹3ÕÒÒ‚­­­B*mW®\A¯^½¤RvDD5j]]]ÁµöíÛãîÝ»JÿB466F~~>}‚ ‚ -- ÖÖÖtÇ„P\\ ]]]p8…okÕ6“þääd±ÏÒ§¥¥AWW&&&‚kÎÎÎ(((@FF†JŒƒüü|ImŒéèè@CC¹7P£¢¢àîî^íÚ_|GÑ‹„ ‚ H!”/^ Y³f Ñ–œœhiiÁÀÀ€nŒ“””{{{AAB¨"LJŸŸ ‚P ®]»†ž={’ ‚ ‚åF__HOOšNOOOeŽ Õ±¶¶F^^žÐ¸666ÈÉÉAii) MÆÐî ¡téÒ·nÝ"A¨çÏŸ‡¯¯¯ào'''|øð|>Ÿ„£&¼zõ žžžÕ®¹¹¹áíÛ·¤€Ì9pà¾ýö[bahh(4p ¡¡!ôõõY{*úœÅ‹cÙ²e*!G????~\%úbkk‹ÜÜ\Õ›ÎÎÎÙÙÙ(..«¾5kÖ`îܹrí³››bccÅ.çÇÄÖ­[úþvêÔ wîÜ¡—!6½{÷ÆåË—IjDpp0† &øÛÅÅñññàñx$5!""ÞÞÞÕ®yxx **Šu‡¢œœ˜ššÊ¥©©©°±±Q ™›˜˜ 77—Ÿ¤§§ÃÊÊJ®m˜;w.Ö¬YÃ8ý©S§0dÈ×-,,™™©ÐòÖ×ת\A„*C ˆ”´SE1¸–6ÞÞÞrqƒL¨7>D›6mHA¡„pe]add$yyy2­û¯¿þÂO?ýTíš¾¾>]Ã%'Q={ö`üøñÕ®ùùùaçÎ5¶ ¢6 ahh¨rý266–ùûŒ‚¸NaaahÛ¶- … B•///øè‡?88Xfu¿yó7®vMSSúúú4y`@ll,6lH‚ DæàÁƒ‚ç_•˜={6üýýU²oê@@@€àÿ“'O¦#rAR†Ž`A¨(IIIbî$‚ R@>£yóæˆˆˆ ;Iñ!!!Õ<æA) ÉÍÍ…¶¶6tuuküæèèˆ>HµþÓ§OcðàÁ4Z¤À’%K»NII­­­ÜÚº}ûvL™2…nAA„ª+ ÉÉÉ000€‰‰ Ý1ƒÃá0 ôòåK4mÚTnmåóùàp8tÓ‚ ‚ T]!‚ ‚ ‚‚!ZZZÐÑÑAaa! Cغu+~üñG™×k``€ÒÒR”——«œLQXX¨TÑxOœ8???…n#Óè¶îîîˆŽŽ¦‡› ‚ „øˆ‘‘,--+óº €sçÎÑMø„ÜÜÜZó1Ç—X=GŽÁ×_-øÛÕÕYYYµFløð!¾øâ ©õùÛo¿ÅÁƒ§v,îó£hMš4ÁÛ·oQZZª4ã    Ö˜$&LÀîÝ»%VOPPüýý…¦«¨¨@|||5W×3fÌÀ† „æýå—_°qãFz¸ ‚ R@ùÓ¼ys¼xñ‚QZB~¤§§cãÆŒÞ¢Š´SXXˆ7"33S*ågddHuŒ‘"#,,,¤6HjãÀøöÛoIðõàììŒ÷ïßË´N{{{$''ˬ¾Ë—/£OŸ>j­ÔŸ³Dzœ8qÇ'A¨‚ïÒÍ›7eZ÷¾}ûðÝwßIíÝ^H—MÌ%Bö󢯣K—. cý^Ÿ4ivíÚUg¾|õÕW077GVV \A¹wïz÷î “zl×6Ú·o_ï.jLL 4hccc©§âåå…   ÉtKøýû÷prrRù¼cÇLž<™žd5çÌ™34h B <{ö -Z´ A¨‚ïR×®]²¿ýö~ûí7Öù^¼xfÍšaôèÑ8tèÝlÆÅÅqqquþ~çδoß\.—Õä3""Í›7'+:::ÐÕÕ­Õ[f/^D¿~ýª]kРA½»¨ééé077‡¦¦¦ÂôUm–Ê#""àííM£[ÂT½ëóœuáÂ… ¡~¡*ÄÅÅ!//OìrªÞ›\. ,ÀŠ+”¢ÿ¨¬¬Të1––&1û¿ª#X²€©³a©}ì¡‚‚‰…WHOO—™D dddH¤¬èèh‘wT謀:HÍPÕ±³³ƒ––V½Æßééé°¶¶&a©9>|€££# ‚Pz&NœˆuëÖ1¼¹páB¼}û¶ÆõÄÄDp8888 Q£Fˆ‰‰‘Kîß¿ÏØGzz:¶lÙÂ*®*òÛo¿aëÖ­Œ½‹íÙ³ÿý÷_­¿=z´ZÌ(iòå—_âÞ½{5®gggãÚµkŒËùûï¿ñÍ7ߨõ¸rå –,YÂ*ÖZ].î—-[†Å‹ˤݳfÍÂúõëYµ¯6‚ƒƒ±páB‘çÏJ¡€lÙ²ÿûßÿêü}ÅŠX°`Èå·iÓ>T«'''ÆÆÆŒí’““agg'•¶ØÛÛ#))IhºãÇ+|äje#55666$‚`ÈŸþ‰ÀÀ@$&&2²©xñâ=z„‰'ÊEéwppP·çƲ²2ìß¿«W¯fTæƒФI¼|ùRm½Í=}úžžžèÕ«ã˜A!!!˜7ožÌ—””€ÏçCOO¯ÞtK–,Á­[·êµ=¨"&&%%%¸xñ¢Zµ_ºt 7nÄ;wŸŸ/4ýöíÛ‘™™‰þù§ÞtÂŽâ‰ú.f†°iÓ&dff2Z\ÈÎÎFXXþùç‘8+…"Ì￉‰I½ç刚¼zõ îîîÐÒÒb”þÚµkèÑ£‡TÚÒ»wo\¾|Yhºââb¡/Q‚¡¡¡èÔ© ‚ ••…¬¬,4jÔ“'OÆŽ;„æY¿~=.\¸777TTTÈ´½.\€¯¯/€º­îÚµ ãÆC¯^½púôi¡e;v #GŽD÷îÝqãÆ µç΃¯¯/ºvíŠ[·n M÷î] 0£GFii©LÛššš [[Û:Óܼy­ZµÂðáÃqäÈ¡eîÛ·ãÆƒ©©)òòòïªû÷ïLj#`ii kkëZw8?ŸÇ&$$ÀÝÝõ¦õóóyR_çÏŸGÿþý«]ût…Ï磠 Í›7GDD„Ð#–/^¼@“&M`hhˆàرcª©€¨-Z´ÀóçÏ…¦kÙ²%ž={FSQ|||p÷î]¡é:vìX¯×‚ $GQQx< Ñ®];Ü¿ŸqÞE‹á÷߯víáÇøâ‹/äÚ§ mÛ¶hÚ´)^¾|É8_ß¾}qéÒ%µ111pwwP÷‘¦O‰Gƒ 0{öl¬]»¶ÚoOžJJJ ««Ëxܽÿ^`û| šæää$s÷Á¥¥¥(**bÕoI““ƒÜÜ\8;;³z^«v  I“&ˆ‰‰Ayy9233Q\\,E” ZZZ‚®­[·aß! IDATâǬöþ¬Ï988ǯvmذaB¡IšŠŠ ¡¨¨ˆ‘7:I×ý¹½ÆàÁƒqêÔ©ZÓWVVÖÈÖ†Lšc 44;v¬ñ­kcذaÕ®‰²F ¡2¸¹¹¡¤¤¤Î#Løt…’`ÇÆñË/¿ˆœßÃÑOý´´´zw$;v숻wïŠå™ÅÎÎŽ‘khB½iܸq½cvÿþý;v¬B-´jÕ áááGûöíç­¬¬Dnn.ÌÍÍ«MRŒ‘••%³>¼{÷¿ýöfÏž:0rÚ"Môõõ¡««‹ìììZŸ6mþüóO…· ,ªrBPE—.]êõìõòåK4mÚ´Úµ*·Ì²TV­Z…Ù³gcöìÙŒ¼·Ia¡!>çÔ©S2dH¿¿xñBæ‘êxÿþ=4hPí÷îÝ»ãúõëŒÇ['¤€Äg|ñÅxôè B(J<‡#× p’¢êˆ¹®– <@»víª]esàÀ8{ö,?~,UXxùò%Z´hQíº¹¹9²³³qúôi <¸ÚoŸÇ2ÁÜܼ^äÈ‘#>|8† ‚³gÏÖ°/¸yó& ???ìÛ·¯Þèâ)))8vìæÌ™ƒ-[¶`ÅŠ?~<Þ¼ySgžÌÌL\»v þþþX±b^¿~]í÷¼¼<„‡‡Ã××óçÏGdd$«Å ###°2ÆŸ?>V®\Yc÷AìØ±£†ã„ª™ððp''q[>Ÿ_§ýP||<úöí‹1cÆ`õêÕ5Ž-¦¦¦âܹs?~<æÌ™Sï"`AA6n܈±cÇbË–-زe °wïÞ:ó”––"22C† Á”)SY-<ÇCdd$ÆŽ L:yyyR½/=zô®ß¼y]»v­ö»ŸŸŸÔ̘™™!;;»š3 q055­SÏÉÉAXXX5û#.}V‚ Tââb¼}û^^^$ ð©¡®8XZZbÕªU°µµ…‘‘‘ÔÚËçóQXXXÃ^ÁÏÏDFF~þùçj¿ýòË/ð÷÷GPPPòj;v£F‚¿¿­G[Ïž=‹øøx¬\¹………8xð 1nÜ8p¹\DDDÀ‹/†™™>ŒâôéÓ5Ž%%%%a×®]˜;w®à콯¯/tuu±téRÁѶO)**‚ŸŸ|}}„èèhœêöíÛµÆÎrpp@VVãcffføðáfÏž]Cù>ÚˆHûˆ–ŸŸFkkk‰¼Û¾úê+„„„àû￯ñÛ©S§ðòåËjOe¦€¬X±¢†V+m “ Éò×_á§Ÿ~"AJOLLL­žhÂÂÂjL²ž?oooVåGEEU³—øt²Ô­[7VG8$ͺuëÎʹʕ+WjULêâõë×øí·ßpíÚ5ÁäÆÛÛÙÙÙxõê***п˜šš ìd,X€† bÒ¤I5\ÁNž<“&Mªáª´{÷îÐÔÔDPPüýý×SRRàïïáÇã‡~ðñˆm@@233±hÑ"tëÖ sçÎ…±±±`WàÒ¥KX¿~=¦L™"ðòSÅ­[·ªÕ!Œììl˜˜˜Ô8ÿüñ‡D&}¢2{öllÞ¼¹V¤E‹xöìYÝ3QŽ |¸ÆDîðáõN,´´´î8åEãÆ%êÄ`È!5ιcܸqÕ&Ùššš°´´DçÎk-‡Ãá`Ô¨QÐÕÕÅéÓ§Ñ»woèêê"$$už£ïÒ¥ víÚ…òòrLœ8eeeøî»ïбcÇ &–––uÞO4oÞwïÞ­V_XX:tèPkžª•ü&MšT»þæÍ¸¹¹Õú=0`€\Ç€¾¾~ãpúôé˜0aþùçÆå5 ‡ÂìÙ³×JKKqûömlÛ¶­ZÚ*;¢)S¦ÔZ–§§§@qÑÔÔDÏž=ƒQ£Fáòå˵ÆË°°°€­­-~ùåìØ±X½z5âââðÏ?ÿÔønU))µÉ@[[ãÇÇ’%K(P ‹ŠŠ––V²¾ÿ~ ¥ ø¸%Ï….—‹Y³fÕú[·nÝàïïñãÇW»ž™™‰òòrØÚÚÖÈÓ´iSœ={|>G þõ×_رc‡àZd"aJKKQPPKKK¥lÿ¦M›0mÚ4º‘b’••}}}¥¬/_¾¿þú+ÝH‚‚(Æ—õ•õêÕ+¹ö‡©3ayÄù– :•••èÒ¥ þüóOܸq»víª7϶mÛðâÅ ¬_¿+V¬ÀÈ‘#±xñb‘ëÿ6mÚ„â矮õX >øi0AibbbmmmÖÑÐ QPP µvñx<<{öL1½6>¢~çÎèèèÔ«0£I“&8{ö,:vìˆ%K–0r[=kÖ,L˜0#FŒÀÚµkÅêóèÑ£$¸PØ÷–]­N‚‚‚jìdH‹Å‹céÒ¥>=;~üx gJ£€dddÝMÐÕÕEÆ ñâÅ ™¶ÍÑÑ>|Pøi‡&·ú ê5¶dâq())‰uôYYaccÃ8 ƒƒƒXn‚ÅÁËË ‘‘‘r©»¢¢•••Œc¨:ÎÎÎxÿþ½ÄÊÓÖÖ†­­­DËTgRSS±uëVÀÕ«WѳgÏZWðdEff&455å¶ò*ÌßÍÍ ÙÙÙÈÎÎFqq1‚ƒƒ%â]ÉÛÛ»†‚0<==aee%vÝ7F^^RRRpâÄ ôîÝ[®6êõV$‹¸õalß¾½@ Dß¾}Å>ÎíêêŠÖ­[³ Öèàà€† ŠÝ_+++899áÀxñâLMM…*ÂÒæÄ‰u.ÊOŸ>½V—Ï©©©µ™Ƨ %S4hmmmDGGcûöíðòò‚………r* ª [_Òâ¼Ä#""¤V¾0_øª¢ÈI‹E‹aùòåR¯ÇÍÍ oß¾¥O âââ ¥¥¥p;œ\.¬]¨uObKKKáïïìììz_:88@KK«šÁæ‡PYY)±¿ÜÜ\hhhHÕk–¸,]ºË–-ÃÌ™3qéÒ%Vžž¼½½1gÎ=zT`D]þþþ5l&$½òüâÅ‹zÇ¢",¬˜™™Áßß¿ýö[ ·ÕÊÈÌ™3aff†U«V Ý[¹r%æÏŸ_íÚ¼yó°jÕ*‰µçÚµkèÑ£‡LúÞ±cÇ‹×üñ.\Xo>,[¶ îîî5\@Wûnѧæ#UQ,ë #iJJJj5¦R6FŽ øúúÒ@¢¢"2ìVªâhhÐÚªÃÔ~ j,|;B™Ç —Ë­ÏáóhÞuMØ7oÞ¬Rc`èС:t(£´:::(++«!7eýÆs¹\TTT<”1Eœ`´Šˆ¦¦&ÆÏH‘ÔÓÓ«_P=Ç-LÜ wïÞ½VÊ5Þô™ùH£FK‚ ‚ Ô–ž={ ¤URkLB5áp8r?ºM¨>¤€({÷î­3À¡>¬]»V¡ àB]±µµ­fü™œœ,w›µeË–‰ìŠ`ÀCðñܽ¼¡9sƒ ’HYñññäD„&&&ÈÍÍU‰¾X[[CGGG`[˜••%p¡L ˆš––&£:B¹IJJ‚½½= ‚ ŒI“&Us«^û>|ø wƒYu¢Y³fˆŠŠBii)`Ïž=2ó>>ŒA}zF“P^òòòjxKÑÖÖ†››Þ¼yCR´µµ•ÞýStuuÉø˜%\.W¥"_kii©ÌDZVp8èëëCCC5̬544 ¯¯/ùr¹Ó<ùùù055švüøñسgZ riÊ‹þýûãüùóôæú¤¦¦J,2Ð¥KܺuKªuTÏ611Q¨¾Ï™3k×®­ñâ722BNN=A„Ê@^°Æ“6Q&l .Äü!4ŸŸŽ;F‚V`ÊËËQ^^.ÒêÞúõë1sæL¡éúöí‹K—.Iµ999àóù ÐEŠ9? ‚B%xðàÚ¶mË:_rr2ìììH€*@NNrrràêêÊ:ozz:¬¬¬Hˆ! ÉùA¤€A’aÚ´iØ´i Bxñâ¼¼¼HjLdd$5'33&&&uƒ[[[ÃÔÔTilI!$‚¾¾>ŠŠŠH*‚¦¦&455QQQÁ*_}‘è ÉPQQÁȉ¨Ç& Å#$$Æ #A¨1'OžÄСCIjLll,¡­­]ëïGi<ñ‘BH„Q£FáðáÃR);''4™’!æææ°´´d½’Ò½{w\¿~]*mJHH€½½½Êx‘6Lí¯‚ B-IGq¤¦¦ŠímæÝ»w"‘'ê&++ ššš2Q@:wîŒÛ·o³Ê£¯¯/0Ю"11ööötó$H||<œœœ+ ’ˆHü9[¶lÁÿþ÷¿Z355•x}„úáè臤¤$†3bÄ=zT¬2hT¹Y¼x1–.]*öw³Aƒ¤€Ô…´WéŽ???¿zÓèèè ¢¢<O¬º6oÞŒŸþ™ždÿþý7nœPe‚íQ2äää ;;[píСCøæ›oHèr¤uëÖxüø±Ä•assóZkÓ¦ >|H‚'ÄBKK |>ŸõñGBµ011A^^žXe<~ü­[·&a*)ÖÖÖHOO«ŒmÛ¶á‡~ D^Ü»w_~ù%f5'44:u’{;T)~ !â‹WCæææb\‚ BáʺÂÈÈH€ØÚ=ÁŒ&Mšàĉ(//§¨¶ @Û¶mñàÁ8;;Ë´ÞN:!00ƒ ¢› ï/— WWWÄÄÄ{b 00‘‘‘€°°0‘\ŽA ¬€xyy!((…àà`µ|qq1 `mm]ã·ª£mÚ´‘H]&&&ÈÏÏûx!yÒÒÒ`dd$Rp?¶Hb;— T‘€€Áÿ'Ož¬týˆ³gÏbàÀt3Õ”æÍ›ãÆèÑ£ ƒP úVtt45j¤’‚/**B~~>llljüöå—_âÞ½{4:Õ€ÔÔTC__Ÿ„A„H 2§Nü––Vë⡺´lÙÏž=#A¤€H‚õë×cÖ¬Yt—‚ ‚!—/_FïÞ½IA" °víZº«J‡ÃA—.]póæM±Ë3f ?ÖBA) 2™8éèè€Ë­ÝV_WW¦¦¦HII‘ZªÜIrwûöízÝÑš››W‹i!*÷ïßGÛ¶mI±ÐÕÕ­s,ŠÂùóçáëë+õ¶Ÿ9sF¡>€â;£ DE¨¬¬ÇSÉ8§NÂ!Cè&3 ¬¬ ZZZÐÐP½GûæÍ›èÚµ«RµùêÕ«èÙ³' L‚¦¦¦ÈÍÍ,ôëׄ¢fèèè ´´|>ééé(++ƒƒƒãükÖ¬ÁìÙ³IJŽžžŠ‹‹§=z4> ¸víšB»e&D†4mÚ/_¾Tºv‡††¢cÇŽr«ÿùóçðöö¦$g>> “iÛ4h þC“Dñøá‡°mÛ6¥l{Æ ¥z;;;¦¦¦BÓ½yó7¦Á¤Ä :'OždïòåËèÝ»7 Pøý÷ß±hÑ"ÖùÞ½{‰c'ä‹8Þ£££zמâ€H¨¨(•Ú#DãñãÇhݺ5 BILLT‹ãt111hذ!Ýp ''‡‘•*”1`'!üyf3‘LHH€““) jÎÛ·oáææF ¡~ܸqݺu«ŒÊÊJhjjª”\444è˜ K***ÀåŠo²våÊÆ«ÃVVVàñxÈÈÈJŸ455QQQA7—¨‡ÈÈH4kÖŒ„¡ÆìÝ»ß}÷ ‚P­¹‰€ïÞ½ƒ«««XeìÛ·ãÆS)¹ôïß.\KÝ:tùñ4I°zõjÌ;W¦u‚ÏçKÍžh„ øçŸèEAA"Õ}ä¡C‡0zôh©”šš kkkjNVV«ãâ2|øpœ8qBmäKAN uaÈ!8}ú4 B±µµ—ËERR CÅÈÌÌ„……£´_}õBBBHaBÇŽqçÎ…NJJ lmm¥RöÚµk1gΜZsttDZZÊÊÊê-ÃÉÉ )))(//—hÛZ¶l‰'OžÐ/öìÙƒñãÇ“ ¤ÄO?ý„¿þú‹A¨…²ýêÕ+hiiÁØØ˜¢"4jÔÑÑÑŒÒjkkƒÃá 44mÚ´!á©ýû÷‡ŸŸ¾ÿþ{Fé­­­±mÛ6|õÕW¤€¨2®®®ˆ‹‹“h™¶¶¶ÈÌ̪XØÙÙ!==]âçÈ›6mŠW¯^±ÎçííçÏŸÓ Ps7nŒ×¯_“ B ,,,••…æÍ›3Γ““.— ### Šàââ"ð°È”ˆˆVã†Plºuë†7n°Ê£ ±ôV¹sç:vì(v9§OŸÆ Aƒ¤ÖÎ!C†àÔ©SR+¿¬¬ ÚÚÚ+Ïç¼ñ’¿õÓ§OÇŸþ©ã)44T©#———CKKKbåñx|8–.]J‚S!ŒqôèQ8::2Jïáá£GJtÎ ¸ŠÚ°*7râÅʾ›››B¹.ûõ×_%‰:%%ùùùŒ]ú%''ÃÆÆFéÝù½ÿÎÎÎÌ .VVVR=‚Ç–-[¶Ht&&5©®+W®¨e4õeË–añâÅôõ$D¦mÛ¶¬ÒwïÞ„¦b8;;3þvO0P<2ÕBGG#FŒ`œÞÜÜœUzy¡rG°lmm‘’’"rþ–-[âéÓ§J×ïÍ›7ã§Ÿ~’x¹oß¾…‹‹‹ÌV°'Mš„;wŠ]ŽƒƒEÓʹ\8::Jüh,8|ø0F%ñrŸsæLøûû+䊫ƒƒ222PZZ*ñ²oÏ)2vvv¸råŠØå,Y²?þø£D”™§OŸ*¼1Wiii*á]ÍÒÒ/_¾T˜öðù|ÄÅÅ)ü™ZB4vìØ¨¨(@xx8¼½½I(Aª¤Y|ö+´IDAT€¸ººbþüù€ØØXµ:šaccƒììl¡Þ­¤Áºuë0kÖ,,\¸P©d–™™‰víÚɵ oÞ¼auŒO•pqq‘ûNPII *++a`` ‘ñ$J”z>Ÿ¯2J>Q“Q£F œ~¤§§S P‚ )#ó#XZZZ°°°€……LMM×uuuQ\\LwDJÈ4ÖJii)tttÄ*ƒÇãáåË—ðòòRÛû¦««‹’’‰¥cKÿþýqþüy¹+¡eee°³³»,EõŠÎ;×ù»¶¶6£S¦éˆê ¾Kâ¾·‚ T@êbãÆ˜1cÝaõêÕuÆ9QUÜÝÝûkgʪU«E_±b…`g‘ø?ŒŒŒÀáp——'RþöíÛ#<<œù UC¶¶¶¬}øð¡ÞÝ•3f`ãÆBË™>}:6mÚD7ž ‚ D]¸qãºuëF‚PSZ¶l‰»wï"66V­wm 333hhh 33S¤ü¾¾¾¸pá+¤Aƒx÷î Ÿ ‚ ”I9{ö,(v9âÄ~¸uëV½G"j#77&&&4ªÔ‡’’èëë“0‰óôéSFÞÈž={†–-[’À‚ R@˜"© „Ïž=Ù›ÉÓ§OÕúÞ´iS‘¼uéÒ·nÝ¢'KòН­­ ===‘$1ÁÚÚ¦¦¦ˆŠŠù9²°°@vv6x<žJ÷%&DEEÁÃÃChºèèhƱ~‚ ‚ àããƒ;wWKKKà Eùæ›oðï¿ÿ²ÎÇårQQQ!÷ös¹\xxxàÕ«W"å×ÑÑ‘ª1ïĉ%â"˜-FFF077G||¼Ôêàp8àp8àñxؾ};¦L™Âº OOOÄÄĨ¼7¢áÇãĉô%"‚ HQvXVѯ_?\¼x‘UžV­ZáÉ“'ŒÓGGG *Ý£G\»vMhY={öÄÕ«W¥&ˈˆ4kÖL.÷ñ¿ÿþCß¾}Ež›™™!++K¤µñãÇcÏž=RíŸ2í²½{÷®®®r©[R;¢—.]¢8AA Èÿ¡­­ OOO¹K¶ÇŽž?.ôhذaÃ,´,¶+¨›6m´iÓ§¿wïÚ·oÏJUqNDqgéàà‡ääd9r_ýµØ÷çüùóðõõ)ïŸþ‰éÓ§Ke܈c£$k^½z…&MšÈ¥î .ˆ|ÿ>åÈ‘#"G‰_²d –.]Ê8ýû÷ï¡«««A! ‚ Be‡===™ÆªPtž|È(]II Ž?Žëׯ“Ђ ”E)**´iÓpóæM¡Ý»w=‚žžvíÚ…¢¢"ÖÑÓÓCll, `ff&VÇø|>x<455ER^’““ѰaCÆyvî܉I“& M'mãæúàr¹Œz54> ¶FÀÝ»wgd»RÙƒY}úôÁùóçÁápýa;‹‹‹¥2aæp8044d$‹É“' MghhkkkF_===”——CWWWjcÍÏÏüñ\]]¡­­-R?üð¶mÛ&v[F}ûö‰¼¡££Ã*Ê<»,MMM;v ãÆ«7££# „:xprrBnn.rssUö£uíÚ5FŽ JKK±mÛ6èéé!!!gÏžŸÏ§¯>A„"+ ¹¹¹X³f FŒÁ¨ mÛ¶aêÔ©0`üüü°aÃÖ7n¶nÝ .—+’ý@nnnxûö­Èù+**PTTÄ8¦‡µµ5tuuŸóðð`¥ÜÈ;;;èéé¡qãÆ¬ò9::"??_,£á9sæ`îܹ°°°«ÎÎθyó&ôõõaggÇ:ÿ´iÓðôéS0Σ¥¥…^½z1RV®\ÉHid2®´´´ §§ÇHîS§NEXX&NœÈ¸_lm06lˆ‡ÂØØX$寊—/_Šm{âî{÷¢}ûöàp8¬ó9ùùù¬ò˜™™1²jذ!úõëOOO¡ã¥¼¼õ¦322BYYzöì©’¬+W® 99™ÑâDHH<==1`ÀŒ7gÏžUû£„AЇÏçó_¿~]-.€••››‹/^ !!Aè ¿¿?‚‚‚|<:täÈ,\¸PðûŠ+]-O^^‚ƒƒááá.— ࣷ###XZZŠÕ±>€ËåŠt~_”¼)))°¶¶f4ÙJJJ‚½½½Ðt¯_¿†£££Ð•r¦éòòò’’Â(ŽdddÀØØ˜õ 6ÓþÕGtt4¬­­ÅìCCC‘ÆSYYòóóY)Blúž••}}}¡;lÒ0RÞÙ´3%%666¬'ï±±±077k7óÕ«Wpvvf¥Ö5ž¬¬¬`jjÊ:oaa!***XE6òMKKƒ¹¹¹à(nºÔÔTXZZ vÝÝÝqòäI¥ú0"22²ÚµæÍ›#''666˜0a‚à{S‡†©©)úõëàãŽÚŸþ)x>bbbðÇÔȆÔÔT‘lØ‚ ˆºùñÇñ¿ÿýÀ€7oÞTs[ëéé WWWXYYI¬Ò Ô¸–““#X-Þ·oŸP%çóIÑóçÏY¹Õ,--ÅÉ“'Y{VbÛ6Yæ9|ø0Ö¯_ÏXIÈÍÍÅ70dÈ•‘(yN:…nݺ1žT–——ãøñã=z´ÂÊà§Ÿ~b•çèÑ£ŸêÔ)~pp0Ÿ ãÇg•þåË—üÕ«W³Ê“ŸŸÏÿé§ŸølaÛ6Yæ™:u*¿¨¨ˆqú¤¤$þüùóUJ¢ä™?>?11‘qú¢¢"þ?ü R2øé§Ÿøyyy¬ò¬Y³†©ÖcgÑ¢Eü÷ïß3N_VVÆŸ4i’ÂöG©­ŸÅÅÅüÇósssù|>ŸçÎþŽ;ø|>ŸŸ‘‘ÁŸ7o¿¬¬Œq>|à/\¸U»¾ÿþ{~ee%«<Ÿ~;™²k×.þ­[·T晚9s&?##ƒqúììlþôéÓ²?‡æ_¸pUžOÇ*SÞ¿Ïÿõ×_¥ÞŸÅ‹óãããYåÙ¹s'?44”Už‹/ò:¤ãsÆŒü¬¬,VyÖ¯_Ïöì™J<£·oßæïܹ“UžøøxþâÅ‹ëMSç^~zz:æÌ™ƒÌÌL”””àúõë˜?¾àøÎ ¥¥…¶mÛ~þùglÞ¼ñññ4h† ÆJ#c{Ô†Ëå²>–Ááp`dd$“>>àñxð÷÷‡……¦OŸÎÊ(ïJQäohh(–”ª¼ÙÈ@CCCaŸ)]]]Ö6¬U6|Š87144dý­ÔÓÓcíôCGG‡µcEŸ ¯¯/“o¥,Æ€¶¶6«ÝࣃaïOŸÜ‚åSûB=)..ÆÌ™3ñ÷ß“0ԜŋcÒ¤Iprr"ara÷îÝððð@çÎIjJBBvìØåË—“0h~ª”m× ÛGAA„¬Ðüí·ß~#1Ô©©)\\\HjŒ††ÌÌÌàììLÂPsŒŒŒàää$r|‚ØÛÛ‹tœ–P ¸\.,,,Äö8IÐüT^¨ý¬Û·o#!!ýúõcìåáñãÇhÖ¬€Þ>¥K—.ptt¤§‚ ”ÔÔT\½znnnŒâx@AAâââЬY3„……!..NðÛÿkï^C¢Úú8ŽgJ±rÔ"µÔ1Q"³7™ƒ)aô¦)°p§ƒ¡a7Ô5 £Ô„"+FL‹" CC¨°(ÉÊ[å(“w#Dò:]çynš§ž“ržs2[˜7{¯ òŸq¯Y{­Y?WWWÂÂÂDa…)£¢¢—)ç¹X,êêêÆ`0ÐÒÒb5`žîNI‚ üz ´··:å¦ÑhdÉ’%888 ×ë­Â¤×¬Y3­óþiô¬‡ÊùEEEŒýôƒÁÀÎ;1›Í˜ÍfnÞ¼‰J¥’_'@Q„_gtt”’’T*MMM<{öì§×˜ÍfŽ9"çl888XÝ ôz½(¬0ef³N‡J¥¢¿¿ŸÊÊÊŸ^óéÓ'NŸ>MQQðu{m…B!Çm˜áO÷üùsjkkQ©T\ºt‰áááŸ^c2™Øµk—«áää$ßL&Ó”ú41ù—\¾|™Ý»w£V«‰ˆˆ °°ð/Û×××óøñc«ìL&uuu ÿ_³S„™éÁƒ\¿~]b–ÉÏÏgÇŽ¨ÕjâããÑétÙ~bb‚S§N)[¹r%jµµZÍ‹/ÈÌÌ…¦L¯×³zõjÔj5ÑÑÑßͰÿÈ…  ±:æææF]]uuuxxxˆÂÎb¯_¿æøñãˆý„f—³gÏ’˜˜ˆZ­F«Õþ04õ[F£‘ÒÒR«lœ7ÊýQ{{;ÑÑÑbò;jjj¢¾¾žØØXù˜ øúú¢Ñh0›ÍTUU‰bÍÝÝÝ?üð]‡/üY†††ÈÉÉaÏž=?\k2™°³³ÃÅÅEKøG|üø‘3gΰiÓ&äãÜ»wFƒF£!//Ok–HMMý“fÚ[ª ³GWWwîÜ‘Æÿ›N§#>>~ÆýÝ6â­›š'N0oÞpࣣ£¤§§‹Í f‰ÆÆFîÞ½KWW###tww“˜˜(§£ßºu‹Í›7O{xA˜ª7oÞpåÊš››±X,ÔÔÔÐÑÑV«µj722"Šõ›{ÿþ=ÉÉÉTWW388ÈÚµk‰‹‹àرc PXX(gU¤¥¥100€$ITTT““@II 555DEE%Š; äççóáÃ’’’0 ’›› Àðð0}}}lß¾] @fwwwz{{qwwÇh4âëë+Ÿkmm¥³³SŽ‘¿víš<ÅyèÐ!bbbøüù3ƒÁ:Z^˜BBBP©T”——“’’"ߨ-Z„N§³š bùòåx{{3>>ÎÀÀ ܸqƒÃ‡ãää€V«¥¸¸Xw†  ©© ºººðòò’ÏY,®^½Jxx8ÎÎ΄…… |}ú¤×ëåÁGgg'ãã㊢ ÓâííMGGëׯçíÛ·¸ººZ/++#00OOO¼¼¼¨­­àË—/$$$àííÍË—/Y±bÅ´ƒÃ„™kþüùr¿£Óé¬f;²³³ÑjµVK°úûû¹xñ"Z­–ŒŒ Ž=ʆ äYýììlĽÊÇLJ¶¶6|||hlldÕªUò¹Éeÿ“Ë­ ä÷?77—-[¶ÈmŸ;pðЋUÙò·Æ?¨d\JÍ”6ÒÁ^1yþòÄ7>u“aÚ3º”‰#7Ðêø 6éuãY‹MÖ€„c˦ŒTb ×L’»qlÊ/8"™ìt¯`<{BêA?ãWStTÍ0z–gzjáéC0¿…œódÒ8ø²}ÛL<—_[±µIíµ£2ò¬g¸ÕŒ’ûqä—ç\ÙéŽiH+Î4]½;r‡~Ù0¡ýö4ü›CçðgœFcOJˆ1K“RliBè}¡.SÀjDÌ1™ªE«%÷ãÈÊÂóÒ鎥ÎÐãK/ýÅjætE±<]ÂBžV=סøíĶ&[†€×Û—B Ll„Éœ(²iFÉý8²²•ƒ,œîXPSÎ@|…¥,ór]¡l S’ž–qÎÙ˜”2U;5.K& ŠÌ2|؉­MÊ€8˜¸œ²)ãIŒ;&!&ƹV36Ù#+¿˜Üd§»çíi•qÐ^YɵŒSd†écÔãS3 ܼ<á#0 é]¨dø÷ÌÇüMiÅŠ&k@øsÞÎ-΢baï¡ ¸Æ{£V3IîÆ±*Ï|³Ó¾3ëOU¶Ýrd£“Á¢{"eBmX(øí·&™-U)º,¶ñ.ä¾B\Û4ãh½UïjÇ«·Uæ4à„%ÔˆM”BâÁñ³ Y+¡„¤L­i¾ÿþU_<Ëè·Å:M&Wîϟꊦú=GÀÛÍ?Ö ·yöýðŸ÷w‹9FFFFFö¹ÉêªGS@œhYÝÂáM™h°ó¢€¬‡·õˆB‰‡7ʲ„W‰æaˆ ######ûá‘»¥¹ÛnW‰Üm¼Dî’‘‘}XP enì-”Y "ï ÌîHÝûÞuîE™®·ðD_ìñ’ÿÉŒÛ!E\ÐÇW¸ãÌ2ïDÕ$_»ÍWÒßN:£$óÁŒ®ã>>äŽ3Ê\²Ì;”y¨h -ìÚí±o'ß ™O(âLsÇuW²Ì ÊÜ’¥éÿ¯@¤¸’¾—tî’Ì#Üg™3}ŒsÇU@*–¹)#£ÀRw{+éÜ'™QF¸f™q”9’»8w\„±’e®ËÈd°€˜*on%û$3ÆwYfX։܏ãe®Xæ eŽÍ—pë- ¶)W÷‘Î}’g„;,3,ëªâÜq›!%Ë\£ÌÏ[÷u#éÜ'™1F¸a™OPfœ;nR²Ì Êì%í¥ûIç.ÉŒ1Âç,s¢¹{ÀW)YæenÐw==ãÞB×}ÝK:wHf†1§,óB'r÷ˆ;¾ˆ2+tMnoýé<^¿½»BrÇ×PfÌ›]·ßL:ëËg™·YæPæ½7Ýnÿ7¤3¡ÌMâÊLFFFv£5÷ÆÄ2×÷ÆÄ2§Ó±ÌåÕWEAP@ÒéŒ2¤(!åáÂ2ÿ4/=•§øþÇIEND®B`‚snd-16.1/pix/sin300.png0000644000076400007640000003132311147553270012664 0ustar bilbil‰PNG  IHDRo„gSbKGDÿÿÿ ½§“ pHYs  šœtIME×  4¾X67 IDATxÚíy\NéûøßíiJ‘=ÙÇ3YBö1ÄX ÓI²$Œ} ó±ÎŒa²¦aZŒ²¯e);Y¢ìkˆRRZ¥½žß~¯G–¢¸ß¯W¯:ç^Ÿëœçê^®ûº”är¹@ (”…P0@(Á—Err2 oL¿uëQQQBPBÁÅg̘1¾6-$$„½{÷âééIll¬ÖˆêÇlÌØØ˜µk×Ò»wo!ùÏ„Áƒ“žžþÚ´;wîТE BCCINN¦J•*<þœ1cÆÊAjj*—.]’î999±víZ!h¡`ÞÍóçÏÉËËRÿŒÐÐÐL~~>©©©”/_eå7޵µµñöö.tíÚµüùçŸ ÷²²²„ÅIð¥DPP< bÅŠDFFаaCBCCÉÊÊ¢bÅŠBXb#™L&J«U«Fhh(ÆÆÆ|ýõ×èéé¡­­‘‘‘Ö;HOOçþýû8::òÇо}{nß¾ÍäÉ“QWWgìØ±tíÚ•Q£F‘••E… pssS¨ÃÖÖuuujÔ¨Áüùó‹Õþýû÷Ù¸q#QQQxxx(¤]»v3f ªªÊĉ騱##FŒ //}}}–.]ÊöíÛÙ´iÏž=ÃÛÛ###¡`ïG³fͦK-[¶TH¯W¯žRINNfÿþý„††’šš €§§'ݺu£nݺ¬]»---î޽ˑ#Gh×®aaa’Ì:DZZ{÷î¥yóæüøã4hРÈíŸ;wŽ'N““S(ÍÓÓ“ï¾û###<<.^¼ÈãÇxøð!7nÜÒOŸ>Mrr2ðÂ< ""¢XíÛÚÚÒ®]»×¦íÛ·OáïÐÐPââ⤑ϵk×v ú-Œ@ (1„‚BÁŸ;YYYDDDŸŸOll,‰‰‰Ìœ9“ÄÄDž|˜úõ룭­ ¼8×dhhX¬ö_n«yóæ())qöìYnÞ¼I›6mpuueÚ´i˜™™¹N±‹$”LLLh×®öööhjjâããƒ\.ÇÙÙ&OžŒ••kÖ¬A&“Ñ A:uê„‹-âæÍ›¸»»#“Éèܹs¡“íïbÒ¤I <˜³gÏ2iÒ$”••Y°`-[¶D&“ñÓO?qéÒ%:wîL`` «W¯FKK‹ñãÇãââ˜1cX°`±±±üüóÏ@ í¶lÙBÆ ŽåðèÑ#ÒÓÓ©_¿~‘>€0´¼ ah÷ùñÖŒŸŸøúúR§Ntuu i¼>}úR0Ož›6mâÚµkÅ*caaÁwß}÷I¿cÇŠþ TU™;w®xcŸ‚y•k×®¡®®þÎ)Q¯^½èÕ«W¡û¿ÿþûí|ZZ“&M"--ÌÌÌBîßUvúôé2iÒ$jÔ¨QâÂÎÈÈ`êÔ©ÄÅÅ1dÈœœœŠ\¶`Þͺuë¨]»¶x{?Cf̘ÁÆ¥àýû÷güøñ”+WޱcÇbee… (++ãéé)•}ðàdÁ‚Ü»w55µbµýðáCììì¨P¡C‡eРARÚ¹sçpwwG]]]Šò––FHHsæÌá?þ €«W¯’ÀܹséÚµëÛLÏž=Y³f UªTA[[›¹sçbddĪU«X·nOž}š€€.\H×®]ß¾MݤIV¬XÁÏ?ÿŒºº:[·neåÊ• Ó’£G~²‡±téRiè¿R©R%ÒÒÒŠmVý_ˆ‰‰aûöíÅV./3|øp222D´ÄÏ'''\\\PRRâÔ©SÒýS§NqëÖ-ž>}*}éïÝ»'¥7oÞü½¦ü/·¬ ¤¬­­iذ¡tíææÆ®]»øî»ïPRRBUU•Ö­[Ó¿®^½Š……P;%%%…¿ßv]VqvvfÍš5%ÚFzz:ÚÚÚŸ…¼%‡««+´k×??¿RÛO¹\ŽššÆÆÆ8::L¿~ýÈËËãèÑ£ 8°h ¦´rþüyÉ©ÍûR¿~}…­Ñ’À××—!C†|º,--9qâÄgñ…:|ø0‹-bÑ¢E8pà‹V.ÑÑÑìܹ“N:±aÆRß_ºuëFjj*>dúôéìÞ½\]]˶‚ ~£ôÏîÝ»KÁÎÊ:M›6¥_¿~ôë×OÁ’ôK$11‘¿þú‹3gÎ0~üxjÔ¨Á¢E‹ˆŒŒäÎ;,^¼[[[êÕ«GHH_ý5}úôaÇŽtëÖèèh)ÊÀùóç_k*ò6-ZÄ£G¸yó& ,@EE–.]Ê•+Wxòä ‰‰‰„††Ja€CBBÐÑÑ¡råÊÔ®]›7n#¹z–¼‚OŠ¡¡¡dÒ^ðÒ~©4mÚ”-[¶påʺwïΈ#xúô©ä·gÏžT¬X;;;Ο?ƒƒåË—§Q£FÈd2bbbÈÉÉaåÊ•\ºt‰5j §§Wäö›5kFóæÍÉËË£_¿~ôíÛCCC®]»FçήPVVæüùó¬\¹+++üýý9vì­ZµB&“ ó2}ûöe÷îÝôíÛWCðɰ´´ÄÒÒRº600`ìØ± y  pݨQ#5jð^ËåË—/ÔVŸ>}hÓ¦M¡ü/ocËM¡&Mš(܇ÿ?ªªª¯5&ïñ½"(y ÂPtéÒECðF?~ÌÖ­[¥ë–-[Ò Ai7ÉÊÊ SSS¶lÙBll,5kÖ,t®/&&†¤¤¤B#‰¢’’‚··7ݺu£qãÆ éÇŽÃÂÂ555.]º$m48::¢¦¦ÆêÕ«hÛ¶­4’#˜@nn.>,äãT x™'Ož……úúúœ9s†qãÆ‘––†––2™Œ­[·²~ýz,,,Xºt©BhÙÝ»wãààÀ™3gþSû“&M">>}}}†ªpvpÆŒŒ=šììlRSS>|8Õ«W'22’éÓ§3{ölÂÃé[·®Â"1‚J -Z´vÒV¬X——ööö’ó¦S§NϼyóhÕª³gÏV8 Ø·o_ôõõ¹uëÖj?//yóæ/Ì^6´[´h©©©R¾N:Ñ¿ú÷ï½½=)))Ò©÷3gÎH†«bSF8p [¶l‚ø Ù³g´¸ZV055eÈ!øøø€¦¦¦P0e™råÊ‘‘‘!ñröìÙ×îÚ”ff̘Á÷ßO\\ƒ ¢råÊBÁ¥àà`j×®±±1 \¿~ÈÈH¹¹¹¨««‹7RðY±oß>fÏž-]>œ & ©©‰µµ5ÖÖÖ899qõêUž={Æøñã9~ü85kÖäܹsxzz’‘‘ANNÎÎÎÅjÛÙÙ™‰'R¡B¾ýö[”••Ù³g;vdÆŒ\ºt '''&L˜À7ß|èQ£ˆ‹‹ã÷ßgõêÕ\¼x‘¿þúK¡Î2©`RRRˆŽŽþO[qAifÁ‚ × ©/ójP´‚ƒ…À{ŠvïÞîÝ»+Ü[²d ðb‘÷e^5è{SI1E%†Ø¦|R¶nÝ*ܼyó¦ˆP0Á‡£_¿~Ò–ìºuëŠåöôsãéÓ§üøãèëësåÊ||| ÁÓÓZµjÅÈ‘#6l 4àÞ½{lܸ‘Zµj/^wìØAõêÕ>|x±Ûß´iK–,ÁÐÐV¬X’’7oÞäǤI“&<|øU«Vakk+ÅGÊÌÌd̘1Œ3†† ¢©©Éßÿ–––P0¨««“––&ñ±ÿ骢ªª*ýý%Ž©©)nnn;vŒÿý—{÷îáç燖–vvvâàà€££#þù''Ož”Œ††šššäååý§öwìØÁ¦M›¨T©666äç磢¢ÂîÝ»™2e ƒfΜ9ܾ}›Í›7Ó¨Q#Ö­['gؼy35kÖÄÉɉääd´´´ÄLß~û-‚|RbccÉÏÏ'&&xK¬víÚJî,š7oP(V™©©é[‹‚––¦¦¦TªT‰êÕ«+¤½Ü¦šš5">>ž¨¨(Z¶lÉêÕ«ÉÏÏÇÝÝi›½Dÿe¤¦¦2~üxéZ† o¦yóæÔ¨Qƒ#FpñâElJJW®\ÁÔÔTr–_­Z5Z·nÍ­[·°´´DMM­dLùòå¥Ó™»vío‘@ð–ÄÒ¥K¹téÇŽ£jÕª¥º¿6lPˆº©¯¯¥¥%AAAÄÆÆR£F 1EJ III 0€Ã‡KŽŸ”••qqqaÞ¼yDFFR«V-&L˜€¿¿?Ó§O§zõêøúúrúôiÂÃÃ9}ú4W®\áâÅ‹Ån_OOGGG–,YÂõë×QRRbìØ±Ô­['''üýý¥ÐEîîî q½V¬XÁ€X¿~=”+W®ä§HÁûrüøq®]»ÆW_}õÙÖüü|LÿþýQQQ^„æ)ØÆ/p‘ ©©)ÅóêØ±#<@[[›øøxêÔ©C:uþSž… ²oß>6oÞŒ²²2ööö|óÍ7èêêòìÙ3<<<077§bÅŠÒy#€1cÆHkD¾¾¾#(ý»wï.äÚP x¯‹¿cÇéLÒÚµkyôèuëÖÅÞÞž°°0vîÜ Àĉ©T©’B}/—}Ó.xaÙ²eK)mùòåÄÇÇÓ¤IlllX½z5?¦~ýúØÚÚò믿¢¯¯/ÅD#˜D@@½zõ‚¼///ÆŽËÝ»wée2™ä—×ÇLJÀÀ@Ù´iÛ¶mÃÎÎŽŽ;bhh¨ 55™L&ùÊ}cÇŽÅÐÐŽ;bgg'ì­^½š .àèèȪU«8tè=âÔ©Scaa««+êêê\¾|™+VˆŒ@P±··GKKKº®U«ÞÞÞØÛÛ––Æ´iÓ¨Y³&“'O&&&sssé$thh¨T¶ÀL¤ ì»ÐÐÐìÖÌÍÍÕÌ™3©Y³&®®®ddd°mÛ6ž?δiÓ011aðàÁtèÐððpO‹BÁ>)¡¡¡Ò!ÇsçÎ ”5jDË–-3f YYYÒy2F-¦H‚Ò®®.FFFQ¾|y!2·ß~KÇŽ¥óKr¹œ]»v1zôhŸ4BÁ>)õë×—†÷Ñ oÇßßx±¶põêU"## &))I!­8$%%Ldd$W¯^U¨çÕ6ÏŸ?Ï“'Oxôè={ödûöí8p€¾}ûrâÄ ž={&Œ@PÚðòòÂÏÏõë×ãçç'-òFGG3jÔ(lmm¥{éééX[[ãèèÈäÉ“Y¸p!?ÿü3.\y£££‘Édï< øóÏ?³páB&OžŒ££#***Òâî… ÉdhiiѹsgîÝ»‡‹‹ QQQ :”°°0"""Éd,^¼˜ôôô•Ê?"åË——ïܹó½ëILL”»ºº~ðþÉd²ùÜ%QïáÇå^^^òÏ wwwy½zõîòÇËe1‚)£XZZ¾Ñã»@PZ»He•ÿìXHPºÉÉÉAII UUUòòòxþü9ð"–ššÏŸ?'//UUU´´´ÈÉÉ‘¦?:::(++Ž222¤Ã‡o#??_rºVÐViiiäççKmfggKáJtuuQRR’"?jhh ¡¡!Œ@PÚ8zô(6l`À€XYY±téRöîÝ‹žžÕ«Wg̘1ØÙÙÑ¡C‚ƒƒÙ¸q#óçÏ'##ƒèèh†.rNOOgýúõŠDð:þþûo<==©V­åÊ•cÆ ())ʈ#°´´äìÙ³øøø0kÖ,ÔÕÕ¹}û6S§NE[[›™3gbffFRR~~~/”x¤AéÁÄÄDá att4[·neõêÕ¤¦¦ròäI¦OŸÎòåËqrrâܹs¤¦¦âååÅŽ;8vì˜TVMM¶mÛ*î½cÇŽ±cǼ¼¼HMM%??€   /^ÌòåË4h.\ fÍš¬_¿Ο?ÏÖ­[ñ÷÷ÇÃÃCCCi7K( Q«V-êÖ­+]ÿõ×_„„„àááÁ/¿ü@:u~ ««‹±±±45)P0_ýu‘¦GSccctuu%w ¼Ü¦žžË–-cݺu0þ|òòò #--M!:„P0‚RË—âæ]XZZÒ¹sgΜ9Sªú5dȪU«ÆåË—Y¶l>>>8::Ò±cGÉ'¯P0‚RË’%Køé§Ÿ¾häåå¡««KçÎ9zô(€4u)ø-—Ë‘ËåäççóbgÿÿÒŠÃËu¼ZÏË¿år9yyyèëë3bÄÖ¬Yƒ¡¡!Û¶m£}ûö 6Lr˜%Œ@PŠ8}ú4ÇŽ#((ˆ&L˜ÀСCquu%>>ž† âää„§§'“&M¢^½zܽ{—3fðÃ?P­Z5FŒAFFžžž„‡‡ãééINNÎ[Û®V­?üð3fÌàîÝ»())1bÄš5kưaÃðôôdöìÙ`aaÁÿþ÷?¬¬¬hܸ14iÒkkk…Q§ØEJ <xáánñâÅÒ éÆS¹re<==yöì~~~4kÖŒ­[·rûöm¾ûî;éôôéÓQQQÁÄÄ„…  ¤¤ôÖ¶gÏžMHH®®®(++3}út6lˆlß¾&Mš°mÛ6îÝ»G§Nh×®áááìÙ³Gaý¨ÄŒ¿¿ÿkgee‰7H @PPgÏž^œoùÒ©_¿¾‚£©‚5˜—yÙ@•*U$¸4lØðµeßF¹rå å/¨çe÷ Õ«WWˆô&W%¢`ÌÍÍ¥Ž½Ìï¿ÿþAê_°`³fÍßÎÏ333i‡BII‰[·n ¡|F”ˆ‚144ÄÐаÐýW- ÿ+OŸ>-´&(»S‚‚gù²—ú/™ÐÐPÔÕÕiÚ´)[¶láðáÃhhh°|ùr/^LDD7f„ œ>}ZŠ?6þ|IŽ©©©L™2…Zµj1sæÌw¶/–”Éd´k×NJ›3g±±±´lÙ'''>Ì–-[0`Ý»wàĉlܸ‘¾}ûbeeõâ;/§@PzðòòbÒ¤IDEEœœÌåË—INNfРA¬]»–[·náææÆñãÇù÷ß>|8ÎÎÎtîÜ©®‘#GÒ®];î޽˚5kÞÙ¶ƒƒ;wÆÙÙ™áÇKGQ–,YBbb"nnnlÛ¶ÿýÈĉIHH 33'''ÈŒ3xôèQÉ`ÁãU—™ѳgOÌÍ͹rå cÆŒASSgggbbb°°° E‹´hÑ‚HegÍšEóæÍ©U«–äßåm½°°°îçææ2vìX455=z4JJJlݺ• `ii)mi+++£££CŸ>}¤ÙŠÁ¥CCC–,YÂÝ»wz…‚€õóæÍÃÌÌìƒõIMMÆsýúu®_¿N¹råPUUÅÆÆBCCÑÕÕ F (íT«VŽ;âîîN|||±Êæææ²~ýzæÏŸOûöí?h¿âããÙ¿?[·nE[[›œœ¢££Y³f ÕªU#99Y( ´͉'ˆŠŠ’] B˜ü áÞ½{òôéS)måʕܾ}›¶mÛ²sçNɽ›xúô)Ü»wO²‡yµ-???ÒÓÓ4h=zô råÊRÚ™3g¸zõªÂtL¬Á¥///<ˆ’’)))´nÝšU«VѪU+\]]ÉÏÏgÆŒÈd2Œ±±±¡|ùòÌž=›ÜÜ\)pZll,III’ËçÏŸóí·ß¾µíeË–1kÖ,TUU™7o***ÄÆÆ2aÂ&Mš„L&£iÓ¦tïÞ 6ð矢¢¢BݺuÑÔÔdöìÙ,Y²'''É¢¸LºÌ,)×–òììì/Úgir™)“Éä^^^Âe¦p™ùyàææ¦öR ¼bŠ$”2ÒÒÒPVVFKK‹¨¨(鈲²2&&&^ì^½§*22’ììlttt¨R¥ ÉÉÉ’Ák… ËåÜ»w555jÕª%•# ±wï^ìíí%ÏtŽŽŽøùùáç燭­-!!!|ÿý÷øùùaeeÅ¥K—6l‹-ÂÉÉ 777©.†NïÞ½¥ó^ïÁ;99±hÑ"† &Ù·œ}úàççGÏž=¹téƒfÚ´i 4ˆôôtüüü2d}ûöåøñãb#(Ü»wO²ú¼sçÎ/ ÉŠ`ãÆèëësèÐ!êÔ©Ã… X¸p!VVVÔ«WË—/S®\9V­ZEVVcÆŒ‘Ê&&&²gÏBBB8þ) Ü¿Ÿû÷ïK[¬_2•*UR8g§¯¯/" lY Ò Ò´µµÑÔÔDOOO!À¬Y³¨X±"»ví*RÛjjjèéé¡©©‰¶¶¶BZA[úúúèêê2cÆ ’’’$/{3gΤR¥JìÞ½[¬ÁJæææ’+€ìììRç²4еk×.vÙ7nP»vmÆ÷ÁûÌâÅ9„¤TIDAT‹%…ŽŽŽŽÂÁJ1‚J1999øùùñã?J÷ ¬dSRR€q²³³IKK#77WJ{ð྾¾Œ;–gÏžIk*o"77—´´4²³³¥8Km´™œœL~~>ÞÞÞhjjÒ«W/RRRˆ‹‹ÃÃÃqãÆ‘––&”# qðàAvïÞºº:åÊ•£B… T¯^ */üç8;;sñâE|}}ùçŸؼy3...Ü¿Ÿ.]º0ažTàeš5k&9SÓ××GOOOaÛ·Àì?##jÕª…¯¯/111˜šš°páBiDлwotttÞÚö¤I“èÓ§ÆÆÆ(++³páBŒÙ¶mYYY :”ªU«rýúu©œ­­-ÊÊÊRdÇÞ½{Kö„‚)aΜ9CÛ¶m… E¢jÕªT­ZUឦ¦¦ÂuÀ*T¨ p (RÔÕÕ ¹¾,¨çU_»or‘ù*b F ”BÁ¥ˆÌÌL:$E¸qã¶¶¶ :”£G’ÍÔ©S‘ÉdÌ™3‡œœ6l¶¶¶}:®®®¬[·ŽŒŒ ¼½½‰ˆˆÀ××—)S¦0wî\ìì춣njƒ 999¬]»öm7;;;æÎË”)S¤ ¥K—¢««‹··7çÎcÿþý3oÞ<ÂÃÃ¥òׯ_ÇÝÝ{{{*Uª”ðLnn®BþK´9àKÂÆÆFÁ9~åÊ•iÞ¼9êêêÒ:HÁ–õ?þHLL mÚ´ÁÔÔSSS6oÞ,•]²d &&&¨¨¨(ŒlÞ„ß}÷@!«ß—Ûèܹ3úúú/BýùçŸ8;;+¬•¨‚ÉÊÊR°ì+Ø£E㫯¾bРA¯]È}&&&¬\¹R ¾VRlÞ¼™7n°yófΟ?Ïž={ÐÓÓ+Ù)’¶¶6Ó§O—~ÔÕÕÅóù믿„{‰—xyëôsaÚ´iøøø`nnÎðáËU6;;777–.]J«V­J´Ÿ‡æàÁƒ,^¼333iËZ¬Á”a*T¨ YX à?þ(óŸáÕ@öÑÑÑLŸ>333:t耒’k×®%??”””8yò$7nÜ`ÇŽ’ß^~ûí7¢££iÔ¨>>>’ugÇŽܸqƒ“'OJõ¼ÚfA? ú(—ËÉÍÍeûöíÄÅÅqôèQ)L­°ƒ|RΟ?/<Ä9$ðññ‘\5<þœëׯ3lØ0)¸™³³3óæÍÃÁÁÖ­[cggG:u$åêååõbä ¬Œ¶¶6÷ïß—b% 8ð­m{yy1uêTöîÝË?ÿüƒŠŠ ÊÊÊL›6™3gâàà@Ÿ>}èÝ»7’/^777¼¼¼5j'OždþüùRXY¡`Ÿ”Š+J–ª;_22™ ™LöÖ<³gÏV¸îС:tP¸7räÈb·]¹re<==_[Ï«k8=zô G ÷^-+Œà“S°û/üÁøûû ¡|F”¹5˜„„ñŸN  ¦d8vì;wON  F #BÁ”,jjjèëë+„!óaQWW§J•*DFF aBÁ¡`¾`vîÜIÿþý… BÁ>M5ÐÖÖ.q¡ôïߟaÆqëÖ-)|DQ‘ËåÄÆÆ2aÂLLL¨X±b‰÷wøðáøøøûÆgõ¶çË”)S8xð`©{A;tè ¹o|aaa˜››³råÊ"Õ{ìØ1±æóxëÌùóçÙ¹s'šššL:µPËiӦѪU+† VäG]¬/mjj*‡¦cÇŽX[[£¢¢òQF‹-ÂÓÓ“}ûöI¡Šª`iÖ¬“&Mú(ÑÒÒ’#GŽðÓO?‘‘‘AëÖ­‹\vË–-tíÚ•š5k2eÊ”2ý27jÔˆ"å}üøñGQþBÁ¼Äµk×ÈÊÊ’¾d'NœÀÆÆOOO222 )˜æÍ›¿¶Òþù‡ãǺŸ‘‘Á’%KèÚµk±§FFFFU0={ö¤gÏžŒ?¾X£.eee5jôÑd—.]hÓ¦M‘¦/Ó«W/š4i"¾ ‚’W0aaa’M‚¾¾þ; W«Víµ£‘#F0bĈB÷wíÚEÍš5ËÔ ]½zuÉqiGKKK( AéU0vvv…¦ aaa”+W555ììì044dÉ’%\¼x‘'OžkŠ$”.^¼H—.]„ >åLß¾}9|ø0íÛ·GGG‡±cÇ*œ«ùꫯ¨W¯ž¢ Ìáææ&̧V0€ÂzÉ«‹‡VVVB‚àC;@ Œ@ð©Ø¶m›BIM‘‚’$<<œ‡”ÚsHþþþ 0@<,¡`eÔÔT?~ ™H„‚>­Zµ¢U«V¤§§üQÚµµµeÓ¦MôìÙS<„D¬Á¡`‚²À­[·‚ F (999üüóÏEÊ{ýúuá4K(Á—ÌÆ:th‘óËåòb»í#øB9vì–––EÊ$¹ôüÐŒ5ŠQ£F}Ö²»H‚RÉ•+WhÖ¬åÊ•###ƒråÊ}ô~äå塬\ôÿÃ999EΛ]¬zår9êêêb#¼/OŸ>•\†Ìœ9“ ”‰~8p€½{÷–™z…‚|ñ¨©©¡¬¬,9C{)))èé镙ϔ––†¶¶6ÚÚÚ¤¥¥}ðú=z$Œ@ð&.\¸À×_ @•*UÐÐÐx«SïC‡Ñ«W/ŒŒŒÊ„óïÌÍÍ177/²›ÏM›6¹þ¢îzݾ}›‹/–Øçk0‚RÇ;wÈÉÉQðÎ7qâD~ùåj×®Mݺu¨S§OŸ>åÙ³g4lØ555 ˆ¥fÍš¬?êêê´lÙ’sçÎËßñ‡ÄßßUÕ¢}]¯]»F¥J•xúô)oÍÁ°aÃxúôi‘ê?~<+V¬#ÁÇáâÅ‹888››[(-??Ÿß~ûM›6!—Ë‹Tß“'Oغu+'NT¸¯¥¥Å’%KhÓ¦ )))¤¤¤°sçNnÞ¼IJJŠä`½{÷î>|˜ììì×þ\¿~úõ룪ªÊ!Cðõõ}cÞììlòóóQVVFCCƒÌÌÌ·æÍÎÎFEE•wæ{Y^¹¹¹ïÌŸ™™‰––Ö;óegg³bÅ Z´hÁÙ³gß™÷ôéÓ,_¾ww÷wæ]·n5kÖäܹsdggé™~ôLPPP‘µ¥àãbff& **nnnxxxàììÌßÿ­æëëKË–- åöíÛ4lØ€¬¬,6lØP¨®S§NQ®\9ŒŒŒðõõ}gÛ•+W–Ö3|||¾°/{^|SSS¦M›Æ?ÿü¼X<}›ML“&Mpuu`äÈ‘ïŒAµråÊ·¶ÿ2ÇÀÓÓóy›7oŽ££c‘êµ³³ãÔ©S…žÇ›>߸qãpvvÆÙÙ¹H}ž:u*Ë–-“dó&”äEý×òhÞ¼ùYЊ—^®É—^ïøñãßùÂ¼Š½½=Œ;¶Ð ýï¿ÿbddDhh(ÖÖÖ’‚ÉÍÍåìÙ³…êÚ½{7¾¾¾…¢W¼‹„„*V¬X¬íä÷‘ß)'—ËIHHxç”åU²²²ÈÌÌ,övZZÊÊÊhii«\RRºººEšŽ5lØ€€€w~ð2‡L&õ–`½ÅíCVV–|äÈ‘òÄÄDùœ9säIIIr¹\.ß°aƒ<00P¾hÑ"ùÍ›7ßY—»»»üôéÓÅ««<11ñ£Éï¿”KOO—;99»\XX˜|Ù²eÅ.çëë+ß¿±ËýòË/òˆˆˆö~ˆ5Á{aggÇèÑ£Y´h9rDŠöimmÍ™3g000f_bé5sbÑߢӥKïü'NœþÖÑÑá—_~)ñ> <¸ØS÷‘ßÇ”{Íš5éÖ­[±Ë™››i½æUúöí[ìiœP0E¤¨çSDKmÚ´ù¨òû˜r×××/RÄWù¯#Æ–-[~Ðþ—É)RùòåE?C ü}Ž())}‘ïÁGÝE_¥z“˜˜ÈÕ«WߘþàÁàÅ9”°°0¸~ýºxªe„›7o¾ÑÏʳgÏ B ¦äX¶lAAAøûûJ;~ü8#GŽ 88˜+VpòäIBCCÅS-?~V¯^ÍóçÏ ¥¯^½š“'O²qãF!,¡`J†¨¨(lll^ëi¾M›6T©RCCC²²² û(>C&L˜ à÷£(“E.^¼H·nÝxþü9¯ÝL˜0   R×÷„„æÌ™ÃìÙ³‰ó-”™]¤üü|222ÐÒÒBII ÉÚÐÌÌ TUU±··gàÀ%Ö)S¦°ÿ~™:u*QQQÜ¿xqBÖÃÃ~ýúQ·n]LLL˜"##IJJ’ï^¸pN:Ié[·n%<<ŒŒŒøë¯¿HMM%&&†… âîîNïÞ½¥ü{÷îÅÂÂSSSâââ033cïÞ½ôîÝ›uëÖǤI“PVVfáÂ…Œ5 ccc¡`Á ²³³Y½zu±O«¿Œ‡‡ƒ ¢B… eæs #JŒÿb÷V´óÛ®IEND®B`‚snd-16.1/pix/tanhexs.png0000644000076400007640000003643311147553271013332 0ustar bilbil‰PNG  IHDRè’ÖòàÞsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ õyšÆ IDATxÚíÝytTåý?ð÷L’ÉNö²°†}‰@¢¬ÁŠ‚Ò¯¸RªÕ¡¢ßÖþl‹­ýžÖÖãi-‹Ôª€Ô”EeÁCV²…„ìd²0Y'Ëdf2÷÷‡_æK$„L’{'ï×9žãd.÷>ó¹÷>÷ùÜûÜç‘ ‚ àáææÖãw*• r¹¾¾¾ "i---pqqéñû’’¸»»ÃÕÕ•Á"azkÔÕÕA¯×# €"² ­­­°³³ƒµµõmßét:”––bìØ±°±±a°ˆ‰üN_$$$`ÇŽ=~—ŸŸääd$$$ ¨¨ˆQ$’¨ƒâðáÃ=~‡«W¯âÌ™3¨¯¯g°ˆFôôt¼õÖ[=~WZZŠ . 55999 ‘…Ðh4xíµ×P[[Ûã÷GŽAEEŽ9Â` "ëžþØÞÞ'''¸»»÷øÎ;¥R عs'ÆA°k×.Ó2F£aaaXµj£L$B¥¥¥˜;w..\¸Ðã÷¹¹¹P*•ÈÉÉA^^¢££QSSƒC‡™–1 ˆ‰‰ÁÌ™3P" !t:ÝŸŽŸúè#ìÛ·?ùÉOE" ªªªÂ¡C‡ššŠ¤¤$ÀåË—MÝZçÌ™ƒO>ùÙÙÙ˜1cF4B‚`jÜú Ìã?xøá‡ñÑGaÿþýX¾|9Fd!ÒÓÓ‘€¯¾ú ¥¥¥€ÿû߈‹‹øùùáÀ{‚hÉz$Îh4¢¡¡`ee777‚€ææfÓ1F™L''§W|ó ú¾}ûe"ÒéthiiØÚÚÂÙÙz½¦óº±±ööö°³³ëq;vì€\.Ç‹/¾È€YµZýC#A&ƒ‡‡‡©>¸9h\[[ººº0jÔ¨ÿýÍ'è'Nœ`0‰$¢µµZ­àìì [[[´··ÃÚÚ …]]]hll„»»;äòž‡±ŠÅ;#°°0”¨Ÿzìâ.—ËáééÙ=“—ɺuWqvvfôˆ$L¡PÜvžÛØØt™õN#8‘eûqÝðãúÀÑÑ‘A"²0NNN·=xspp0ý¿••Uu™—œ! """"""b‚NDDDDDDDLЉˆˆˆˆˆˆ˜ t"""""""&èDDDDDDDĈˆˆˆˆˆH\¬jmmÅÉ“'qá´µµaìØ±xôÑG1qâD‡ˆn£Õj‘’’‚ÌÌLäææþò—¿ÀÛÛ»Ûr‚ ++ Ÿþ9jkk1yòd<ñÄðñña‰F€úúz$%%!++  Å믿¹üöçCííí8uêΟ?¶¶6„„„àÑGŤI“H¢aÖÒÒ‚¯¾ú ‰‰‰Ðjµ?~<6lØ€Û–ÕëõøÃþ€²²2üñÄøñãÀáNЋ‹‹qêÔ)”••1ºÐÐЀ'Ÿ|………X½z5ÜÜÜ™™ 777&ètG‰‰‰ÈÈÈ@||<-ZÄ€Œ0¥¥¥xðÁáââGGGÔÔÔàw¿ûÝmË}ûí·ø¯ÿú/Üwß}˜2e öîÝ‹ƒâرcðõõe -J¥Â‘#G V« ™3gðôÓO#44ÍÍÍ(--ŶmÛzlü?ýôÓÈÎÎFll,FË—/ÃÕÕ• ºD8pjµší TSSƒÇ555X±bÜÜÜpñâEŒ3¦ÇýÀصkZZZðâ‹/2AC‚ ¥R‰””ìÞ½›6SƒG&“ÁÛÛuuuèè耛›ÜÜܼî×^{ ---HII1­O‚ÀÀÓEFF"22’ljDêÔÖÖ¢££®®®pwwÐzCBBPXX|üñÇxùå—o[F§Óá•W^Á²e˰oß>ØØØàW¿úfÍš…·ß~o¿ý6wò÷÷‡R©DII ÒÒÒ‰¨ªª‚••¼¼¼Lí www¸ººh½«V­B]]œœœðÔSO¡¼¼¼ÇåÞxã ¨T*$%%ÁËË‹m Ú°aàôéÓ †å ]]]øïÿþoØØØ -- £ÑØãòEEExýõ×±mÛ6üú׿æŽK‚Næ÷ä“OÂÆÆÓ§OÇÁƒ¡V«1zôhìØ±÷߿׫V«ñÉ'ŸàÓO?ívËd2Èd2žHâžzê)ÈårÌž=ÛôtÃÏÏï¼óV®\ÙïõÚÙÙÁÎÎÎT_ô$??ùùùøûßÿ€§§'Ö­[‡3gÎàõ×_ǨQ£¸“ˆDà‰'ž€ƒƒ&Mš„C‡A­V#((ï½÷¢¢¢ú½Þ[ü;ÕøÏþƒíÛ·›’s¶Eˆîý¶µµÅÔ©SñùçŸC­Vc̘1صk/^Üïõ–——㫯¾Â‰'LÉ9€_SÑjµøÿïÿaõêÕÚ&1A—Œ„„„‡‡ãÂ… èììijÏ> ¥R‰üü|Èd2èt:üãÿ¸ëz¦L™‚Õ«WRRR P(ÐÙÙ‰uëÖ!77žžžxæ™gðÔSOÁÚš‡‘Ô%&&"<<qqqÐëõøÙÏ~†_þò—ÈË˃B¡€ x뭷ÐÐP¬[·®ÏÛÍÎΆ««+‚ƒƒ»ý}úô騳g™ ‰H||<¦L™‚øøx´µµá©§žÂK/½„´´4Èd2477ã_ÿú×]׳`Á‚{Jê³²² ×ë!“ɰaÃdeeÁÃÃO=õž}öY¶Eˆúèûï¿Ç”)SpáÂhµZ<óÌ3øå/‰ììlÈd2ttt`ûöíw]ϬY³ðÀ’““áììŒúúz¬Y³EEEðõõÅóÏ?õë×ÃÊÊÊôï>ùä`÷îݨ¬¬äa‚nù|||ðæ›ošžDýâ¿Àã?•J…€€tuuõ©;á­w¿T*ÚÚÚ°uëV<÷Üsxæ™gššŠ—_~ÕÕÕøÝï~Ç»×Dçé鉿þõ¯P(¥R‰uëÖ¡²²¡¡¡¡OuGWW×=m·¡¡¶¶¶ÝêpwwGkk+:;;¹sˆDÄßßÿó?ÿcjgüìg?ÃÖ­[Q[[ ___ètº>Õ=½“Ú›ÚÚZ´µµá•W^Á³Ï>‹'žx—.]¯ýkÔÔÔ`Û¶ml‹õ¯¯/þüç?›Îáçž{›6mBuu5üýý¡×ëût{xxtËššš°eËlݺÏ?ÿ<âãã±iÓ&Ô××ã…^€L&CII þð‡?à_ÿú¼½½™ 3AÆo:á˜FKnjjB@@ìííqèС{ZçÍ'ïÏ<ó ~ÿûßC.—cõêÕhnnƇ~ˆçž{®[w3"’ž &˜’ó×ÀÝÔîµîè‹›Ýß~ü©Ñh„\.gƒ›H„uÅÛF£¾¾¾ðòò”º {ì1¼ñƦ¶Hkk+öìÙƒçŸþ¶"ˆ¨oç° hnn†¿¿?FÕ¯\A«ÕbëÖ­øÕ¯~™L†U«V¡¦¦»víÂÓO? kkk¼òÊ+X±bÅ€^Ÿ#&èÒÛQ?êâu³q{³ñ«Óéðþûïßu='NÄÒ¥Küp§M&“!&&¦Û»$K–,Á®]»ÐØØÈHâní~ÖSÝ!Þ}÷Ý»®'((±±±}Þ®¯¯/ÚÚÚ Ñhºý½¶¶£F‚½½=w‘„ê Fƒýû÷ßu=˜;wnŸ·ëíí ++«ÛÚ"‹/Æ;ï¼ƒÆÆF&èDfÈ:::°gÏž»®gêÔ©ˆŽŽî–+,Z´È´¾›Ÿ8­V‹ÂÂB?~Ï>û¬iF—ššÀîÝ»‘¥R GGGî$&è#‹Á`À±cÇîº\GG‡)AŸ5kär¹éIÚM°³³ëvŽˆ,“ }ª;æÎ{O ú¬Y³ÐÖÖ†üüünÓ$%''#44tÀ#ÉÑÐjooïS]áâârO ú”)S`ooÆÆF¶Eˆ‘N§ëÓ9 À” Ïž=û޹‚ƒƒär9\\\‹ºº:ÔÕÕø¿^zptt¼ç×䘠“Eppp¸ç©-üýý±råJ¼÷Þ{X¶lœ¡Ñhðïÿ³gÏæ<ÅD#€\.ï×´8z½‚  «« ‚ @¯×C§ÓÁÚÚr¹ÁÁÁˆŽŽÆ?ÿùO,]ºÎÎÎÈËË×_~‰×^{í¶wÓ‰HÜ|||î¹®¸Y7?¼Þb4¡Óé`eeÓ´P«W¯Æž={ðàƒÂÕÕ­­­ø÷¿ÿY³fÁÏÏÁ'2—{>‡CCCƒ;wbÁ‚°µµECCöîÝ‹˜˜8;;ÃÍÍ _~ùe·—žžŽ9sæàÍ7ßÐL#¶mÆŒlÛ·o‡F£ÁôéÓ±zõjL™2;vì`T"º£àà`888`óæÍhnnƤI“ààà€]»vø¡»ìöíÛÑØØˆ™3gbùòåX¼x1–-[†^x$ áàà8pÀ4"´ƒƒ***L˽ýöÛ0˜1cV¯^©S§¢¾¾žm¢afccƒ;v ¢¢S§N5Ÿxûí·9Ë ‘ ?ÁÇLRRR°{÷nìÛ·Q ÜÜ\XYYuë&ÚÔÔ„¼¼<Ìœ9sÀO¢‘€ŠŠ øûûcáÂ…ðôôdàé®vìØ¹\Ž_|‘Á¡¼¼<Èd2Lž<Ùô·––äää`úôéprrê÷ºSSSMOÆnÓç7n >>uuu7n,X`šC,WII ¶lÙ‚'N0igX[[câĉ¦¿544àêÕ«˜9sf¿“䎎dddôøÝœ9s`kkkúÜÜÜŒ„„”••ÁÏÏ .ä88‹wÞyaaa Æ0ç ¸råŠYrµZï¿ÿ*• X¸p!\]]ï¸|kk+._¾Œ©S§rJU&èDĈ˜ t"ibw"""""""0û‹ (((@^^£Kd¡***PUU…²²2Œ;–!"?¼B‘——‡ªª*ƒhÉÎÎF[[Ûm£}ѽ3ût™L…BÁi1ˆ,˜•• ÅmóæÑoTÈål@ÖÖÖP(¦¹²‰h瓹Wèææ†Ù³gÃ`0à»ï¾c„‰,P@@˜˜È`‘‰““fÏž 777ƒh¹9©‹‹ ƒA4@|ˆˆˆˆˆˆˆ :1A'""""""b‚NDDDDDDD7Y[úììì|ýõר­­ðú.\ˆ‰'ÂÖÖvD0ƒ]]]¸rå .^¼8àõyyyᡇ‚µµ5G§{"®\¹bŒ2''S§N²í;::bãÆ?ZµÑhDRR233‡%ÎþþþxðÁammñ—+èt:( žÜýPRR‚“'Oùñùc999ÇÆáîînçÿ_|7n k9nîׇz£G¶ˆë×Ñ£G¡R©?ü0üýýy"ßÃñ°cÇL›6MÔå¼|ù2Þxã Éí[AðÅ_ ®®NÔåÌÎÎÆ /¼€3fHîþüóÏ‘™™‰€€€n_µjÆŽk¹ zUU:„k×®aÚ´ixðÁáãã3 uêõzìÛ·©©©K—.Ehh舨 µZ-Nœ83gÎ`îܹ€çŸ~ÀæsçÎaÿþý0 ÐëõxþùçÙ@¥>ß{÷îÅ‚  T*‡¥ ÉÉÉØ´i~ûÛßbâĉ{Þ¿õÖ[ðöö¶8«T*|ðÁX·n<==-ö˜þûßÿެ]»–'x?nl|ûí·ÃvŒöT?]¸pAòû²«« |ð~øaxyy‰¢L_~ù%H>IOKKCII ~õ«_ñîçõwÇŽ¢X–™™‰²²2É%èééé Ä£>*êrF¼÷Þ{’KÐAÀ7ðæ›oÞq‹LЋ‹‹ññÇcݺux饗̶^lÞ¼ÙÔ 8wî>øàüå/±èyF#^}õUDEEa×®]f}b¸téR,]º——‡mÛ¶á¹çžÃرcy¢;:|ø06oÞ<à›n1oÞ<Œ?/¿ü2>úè#‹‹± øÛßþ†­[·ë´9þþþxþùçqèÐ!,\¸pX÷ù`Ù¿?-Z„Y³fñäî‡C‡aݺu¢)O@@píÚ5„……I6®mmmhjjMr=ôvîÜ)š›1ýgŸ}–'o?uvvJ¢'ë¸qãpèÐ!DFFr§ ™L£Ñ(¹rwuuÝõ§Å½ƒ^PP€×_¯¿þ:ÂÃÃm; …+W®ÄŠ+°eËèõz‹<øõz=¶lÙ‚õë×ã±ÇÔî¼áááØ¶m¶mÛ†ÂÂB‹¾°Pÿ8qkÖ¬E¢æîîŽíÛ·ãÕW_µ¸8§¦¦bñâÅ¢™ÓvÑ¢E¸pá‚$/ƽihh€ÑhÄôéÓyr †bëN¾|ùrœ>}ZÒqýâ‹/ÌúƒþE¼A½srrBkk«äÊ]UUu[×k±&è‚ Xä±cQ zcc#Þ|óM¼ûî»CöD;&&k×®ÅÉ“'-òùË_þ‚õë×cáÂ…CV™íÚµ ´È›iiiøÏþëV?utt ¦¦!!!¢)“‹‹ ¦L™‚––‹;V£££ESOOOØÚÚ¢ªªÊ¢â‡åË—s e}kgg'ºrÍ›7ÉÉÉ’ëùóç±dÉ`$Z•••3f ÁÝ< °eË–!â³téRdff¢ººÚ¢Fƒàà`,Z´hH·ëêêŠ+VXd·á‚‚¬_¿ž5O?•——#((Htåš1c._¾Ì4Èbbbpá‹úM*• ~~~ܹýtôèQѾëÔÔTî$3 Fyy¹dËíÚ5Œ7Ž;’ˆ†.Aïèè@UUÕ°ŒøyéÒ%Ìž={X¹qãF‹k '$$`Á‚òí¹sçB«ÕZT>Þbâ9ÜǨ9UTT 55uÈŸb”••!88Xtñðööýt$÷¢¤¤„53gÎ`ùòåõ›4 RSS‘••5dÉŽX§àspp@{{»$÷crr2æÍ›Ç¸K}g677©©©ƒ~õêÕ«˜4i/ $ékÿ²eˆ6A÷÷÷ÇÚµk‡<)..ö'k“&MB~~¾Eé¹WS¦LÁÚµkE?éPrwwGCCƒEü–ŠŠ вlk×®ÅÑ£G-"Î¥¥¥w#ÄÓÓk×®²F£r¹8ßÖ DEE…$÷£J¥â¼ÜtO–,Y‚µk×Â××wP·S__œ$}í¿ÛXJñºV«… Ã>˜É‚ pñâE‹8x¾ÿþû!îNÐÕÕe£ž‹¹)ÍÍÍpuumù¬­­a0$g½^A P(DY>Kêæn088Q?HrÀÈøøxQ ¾I$uèèè°¸ßeCvv¶(žäÙÚÚZÌ»7byG*<<¹¹¹’ç‰'°zõjÖ¤ðŸÿü7nmù¢££ñý÷ßK>ÎUUU=z´hËgggÇw ÀÓ«ñIÚàèììåî7yyyA­VK2¶C5ËÑH0oÞ<$%%1A#ADótrΜ9¸té’¤ã)¦§½³fÍBff¦äÑŠŠ NYaá,m 8±²²²BWW—äGrr2æÏŸÏ:yyyu¡Ñh$ÛúúzÎÓMDĽÿÒÒÒ0gÎQ”ÅÎÎNò]²†½{ûM–Ô+H ²³³1uêTb‰uŽi2/—!Ÿí‚xÞôa%¶é*,áýÈææfQM&õw{kjj}Ð"sóq7M™2eÈg !"ñðôô”d÷¢¢"ÎND–Ÿ wttÀÞÞ^4å Fii©¤cZ^^.ªº­­­¤{%\¾|Ó§OgmCd&ÎÎÎ’Ÿ_º  &LàÎ$ꇉ'Z̬9Db¢ÓéD;H,t IHHÀ‚ DU&É>ñmiiÕÓsà‡Á`nܸ!Ùc´¶¶–OЉ¨ƒÁ Úù»id«ªªB@@AĘ ÷OII‰èæ‘•ò;gb|?*66Ç—ì1ÚÒÒgggÖ6#ÀòåËqæÌ‚ˆ$Kl¯¹1A§³··—ìœ|¹¹¹ ÊŒšššàææÆ@ еk×&úrzxx ¡¡;l) èõzÉ–_£Ñð¦èõzöB É0°²²b ˆˆ úpøÉO~‚/¿üR’eÏÏÏÇĉ¹Í„O"Ì£¬¬ ÁÁÁ ¦NŠììlÉ–¿µµNNNÜ‘tåÊLž<™ I¸qã<=="²ì½´´TtÝÛ‰ˆ¤êðáÃX·nAd&K—.ÅùóçˆA`kk NÇ@¨YÂôË4ôÌÞ7¬¸¸§NBYYÙ >33óæÍã^|ðA;v kÖ¬‘T¹ÛÚÚààà`qû#11ˆÇ¢E‹x€þ/wwwIwqoll„««+w$õ›J¥Â‘#G$9Ö`âŒb›çNd2ŒF#2‘8pàÔjõ´ÿ¥ÄÑÑmmm°µµe0¨ÏÌþ=44J¥ëׯgtiÄ_ˆÏŸ?%K–XÜþˆŒŒ„R©Dttôlïúõë3fŒ$b#OXêÕÅ‹e‘¿ÍßßJ¥O>ù$w´D%%%aþüù Ý“ 6@©Tòu4"1&èѸ‰Ñ„ PPP ©XŠygggh4ž±#Tkk+ˆ\§þ˜”g˨©©áÔ‹DDDdy ºJ¥‚ŸŸŸ(Ë6sæLdeeI*žÀ† DY6WWW455ñŒ%DZ­V2Ý𬬬ؽ•ˆˆˆ˜ Ñ?EEE Ñ â–DDÄ]dÔj5¼¼¼¸ͨ££vvv „™deeaÆŒ ÄUWWÃßß_2åurrBkk+wÑ Òét°±±a F0…BÁQ܉ˆ º˜ÔÕÕ‰:A—â;Ób¹ÕÏÏÕÕÕ’‰gzz:fÏžÍZf€ººº —³³u7þ|$&&2D#Ô“O>‰ýû÷3#Lyy9b‚N÷ÎÖÖZ­–0£Q£FInº"©¨««ƒdÊ‚ÒÒRî8"3A2EJ1± b ¨¡¡îîî 1A£’’„††ŠºŒ666Ðëõ’ˆ§J¥B@@€¨Ëhkk‹ÎÎNÉ£ƒ]0G ÀÀ@”——K®Ü………?~>‹-b`~ÄÞÞZ­vvv ï¿ÿ¾i OµZÍ€ü¯Gy‡Æ#<Â`ÅIMMEjjê´ÿ‰~,,, X²d ô;%xJ¥Òô9%%»wï”Bÿë_ÿê¶-1³±±Á`õ`ammmpppD<-Z„¸¸8&…ÃÄ××·Û¹'ƒr‡úÐh42t›ŽŽØÛÛ[äoÛ¼y³éÿKJJ––ÆÀÙÙFeåVt¯"""ºNúôi…†ŒB¡€N§³¸ßÅÇЃÌÊÊ ƒ0“ððpäå剾œEEE ã#D7oØI‰N§ã»þ$ZÀc=Æ@1A'²,­­­prrb HÚÛÛ%Ó‹æV^^^¸qãw 1A§¾‰‰‰Á… D]FµZ ///IÄS ïÊ ØØØðàÁ¼¼¼$õn{Ôà¡{IDAT{;¹ãˆˆˆˆ˜ [¶qãÆ¡¨¨HÔeˆ9Â(‰Z]]¼½½3Ðét|]€îÈÓÓSRï wuuÁÊÊŠ;n„±³³ƒV«e ˆHô<È"™ ß»´´4Ì™3‡{n›7oRRRD[¾sçÎYÜ|ŒdÙNŸ>+V0DƒÀÚÚš³¹‘å&èDŽŽŽhmme ˆÌ¤©©‰ã& ’ŒŒ Ìž=› "ËLЫªª ©2{{{£®®N”eKNNƼyó$O'''´µµñì´Z-ß…"‹QPP€ &0D# }u««W¯bâĉÜaDd™ z[[›ä¦Šˆˆ@ZZš(ËV[[ IÅs̘1¨¨¨àÙ; ¾³K½š0a $QÖ¦¦&¸ººr§€öшHÐõz= ÷š™cÊA¸Ì‡S¬ -[[[èt:bIKKÃܹs""²HÖæ^aqq1N:…²²2³¶ºº~~~’ ²¯¯/Î;'ʲÕÔÔÀ××Wr1õòò‚Z­†§§§¨Êuúôi¬\¹Òâ+ŽÄÄDddd >>‹-bMÚƒÈÈH$&&"22’Á C¥RáÈ‘#P«Õƒ¶k×®aùòå 6‘ˆ8pjµzPÚÿR¶dÉœ;wëׯg0høôÐÐP(•J¤¤¤`÷îÝf]·Á`€µµµä‚lgg‡ŽŽÑ•Ëh4J¶û°B¡@gg'ÏàaL>###! mCêƒêxzzâòåËK¸ñI#KVVfΜÉ@ ‚ÂÂBŒ7Ž "Iñó󳸛t’HÐ‹ŠŠf ºT¦^bDl(™‡J¥‚¿¿?A4õuÔf""É$è‚  µµÎÎÎðððpäåå kâããmñ Ãõë×ÑÙÙ9le0 œûœ$©²²£G¶ˆßŠââbQ–-%%÷Ýw¸ÎÅÅÍÍÍ¢,›Ñh„\.͉}/^Œ¸¸8Ñ–¯  &Là @D}fö¬¢¸¸§N2[·ãk×®YÄÓó›FË—/Ûöu:®^½ŠŸÿüçS[[Ûa*ê믿ƃ>8¢*ŽÄÄDddd >>‹-bM*QåååX³fEü– &   ¡¡¡¢+[cc#ÜÜÜFÄ1¥R©päÈö똧¼~ý:ÆŒ#é6 ¯@­Vêk‡–ôÀލ×ë…¹W ¥R‰õë×›e}gΜÁòåË-&à®®®ËåHJJ–ígdd`Ö¬Yu¯\¹ÿüç?‡eÛfÄu_ŒŒ„R©”žçÏŸÇ’%K,&V<ò>,ºrYÚÔ?¨ªªeÙÚÛÛáàà0"ê(•J<ù䓃²þììlL:U’± Fii)[žd‘6lØ¥R‰àà`^·ˆÄ– ›ûBø`Hç™ÿè£PXX(Ê.µRUYY www899YÌo’Éd0ÈÍÍU¹2331cÆ ‹:~ÆŽ‹/¿üRTeºpá‚ÅֻÑìðéÙà(,,Äøñã%[þxgÏž]¹¤üê1Aï&++ ~ø!^zé%‹ üŒ30gÎ(•JèõúAoÔ¼ôÒKøÅ/~a‘=ÀÎÎo¿ý6¶oߎœœœ!IΫ««ñ›ßü†µˆ}þùç˜8q¢Åý®Í›7ã³Ï>C{{»(ÊsâÄ ¬^½Úââû J¥¯¼ò fÏžmÑñtrrÂ_ÿúW”””àÕW_Å•+WPZZj–W š››QZZŠ„„<÷Üs°··Ço~ó‹˜K^ jkkñÏþ÷ß¿¤Ÿâ܉žxâ üüç?Ö¹:5 >ùä”––"$$Ä"¥ŸÿüçØ¿?êêꆭ سg|}}9ˆ¢™´··cÿþýˆŠŠ’ô‰Abb"t:hÊ´wï^<óÌ3’Ž«µµ5š››‘™™)š2%%%aÊ”)}Ú”¤WUU!**jP§C4¦'xׯ_ÇÚµkGôÔj%%%ذaþô§?™å¼qppÀOúSØÛÛK>6õõõ8|ø0ÊË˱páÂa+Ç… €ûî»Ï"Æ£Ðh4øÛßþŒ;vØÊ‘““{{{ÔÕÕáµ×^³ˆcö^ÄÆÆâ‘GŸŸŸÙ×}ðàAìÝ»Wr1innÆþýû1nÜ8Q—³¸¸=ö˜©"%›6m2ÛåƒÅ`0ÀÉÉ©O7î5Aß½{7öíÛÇ,†È‚ôúúú>݈û1;;;‹™ƒ»¿ª««‡ä®úرc%;DZ¹öÁ~¢.—ˇ5)c‚¾iÓ&¼ÿþû^—%Mµz+µZ¦¦¦aÛ¾»»»YˆÍ­7ˆ‹¥³}MÐ_~ùeñ˜½EMM Z[[E]FGGÇA¹±2Q__/ê2Z[[÷y–k €——׈nŒ „T/„R3jÔ(Œ5Šb¬záéé)É'Ub'—ËyÜ ³   îƒñõõe‘››Û€{ËŠªã.%""""""b‚NDDDDDDDLЉˆˆˆˆˆˆ˜ Ñÿ2û qÅÅÅ8uêÊÊÊ]" •˜˜ˆŒŒ ÄÇÇsžg"2Q©T8räÔj5ƒA4‚8pjµší"1&è¡¡¡P*•¦iÖˆÈòDFF"22ƒ4K#I”¿¿?”J%JJJ––Æ€6lœ>}šÁ  vq'""""""b‚NDDDDDDDLЉˆˆˆˆˆˆ˜ t"""""""&èDDDDDDDĈˆˆˆˆˆˆ :1A'""""""b‚NDDDDDDDLЉˆˆˆˆˆˆDÊÚÜ+,++÷ß~‹ÒÒRF—ÈB¥¥¥áòåËHJJBTTBD€šš?~7nÜ`0ˆF£G¢¾¾••• ‘Øô1cÆ`ãÆHKKÇ~ÈY ™3gbêÔ©Ðh4 ™x{{cãÆ(--EBBB4B¬Zµ ‚ àÈ‘# ‘Øt+++XYYA¡P0ºD–ZqX[›þ#"ºI.—ÃÎζ¶¶ Ñróœ—Ëùö,Ñ€¯¥ t"""""""b‚NDDDDDDĈˆˆˆˆˆˆ˜ 1A'"""""""&èDDDDDDDLЉˆˆˆˆˆˆˆ :‘„ô«W¯âÏþsßݸq;wîÄÎ;ÑÔÔÄ(IÔ·ß~‹>ú¨Çïrss±sçNìß¿ ÑR^^ŽmÛ¶õøF£1µª««," ¡×ë±mÛ6¨Tª¿?yò$vî܉ӧO3XDƒÈº§?¶··ãúõëpqqéñš››¼žÄÄDáÒ¥K½.³ÿ~¡©©IÔuƒÑh4µ LÿÓŸþ$‚ dgg ß|ó/\¼xqXês¬#55UHNNîu™Ï>ûLP«ÕÚŽF£öîÝ; uäææ çÏŸïu™/¿üR¨¨¨ÐvúÒ¾2Gì¿ùæáêÕ«½.³{÷nÁ`0 h;}¹ž›ã÷˜«¾n555ÂŽ;„¸¸8S=õõ×_›Ú3{÷îòóóïz<÷7ÕÕÕÂ_|!Šëk}}½©=t')))BJJJ¯Ë|úé§B}}½dÚ}©¯²²²„ï¿ÿ¾×e:$¨T*Qü¦¯¿þZ(//—TÛÎêü㜽 äää 88Z­…BÑ£G# ­­­pvvîדJ??¿;vŸïëôôôtÌ;·ßë°³³ƒ··7ú½WWWxxxôzÇôn¼½½áêêÚëâÁŽ'¤¦¦"""b@ë0G9İ[[[øøøôz×ïn*++¡P(z}23Üš››QZZŠ€€ÓS?¹\'''xyyaüøñ())Axx8e?ôe™¾›æÚ–—ñññ¹kb®8÷¥¾ÛïêË2æú]£F‚§§gOÇo½s>a„^Ÿ¦ˆÁåË—Œ¶¶6SO3…B1cÆÀÇǃVVVýº›c¿™£^pvv†§§g¯ûÂÓÓnnn°²²ê÷v¬¬¬àëëÛëÓ›»­ÃÑÑ^^^½>É÷ðð€››¬­­û½¾´¯Ì±ÿÜÜÜàááÑko___¸¸¸@&“õ{;}¹ž›ã÷ô¥¾2G;k°]¿~ …F£nnnpvv†µµ5<==áèèˆñãÇ#//«V­êõ8ëo Å]÷×Pµ ¬­­áãã''§»Ö!½Õù^^^puuP2”Ëèt:\¹r3f̸k}Ô—ºs õ‘¹–qww‡»»»(ÊÒ×cX&ÜéE3øðñyófy¼÷Þ{xî¹ç3IJJ‚££ã€»ëMÆÙ²|öÙgX½z5FÅ`ðxeûŠÇ,1Ž¢ÒÖÖ†£GbãÆ Æ0âOÐsrr0zôè;¾›ÓÕÕ…ææf¸»»øatYÑ? éÊÎÎF`` \]]{üÞ`0@£ÑÀÍÍ UUU¨­­Exxx¯wX ¨««C}}ý]ß{ºõ½þ&.]]]¸|ù2&NœxÇžYíí펎Ž(--Ecc#fΜÙë‘N­V£®®“'Of½@¢Mh 0}úô;>%mhh€‹‹ ¬¬¬ŸŸ£Ñˆððp¯ׯ_Ggg'BCCyî“ųÈÏχŸŸüüün[NÔó ŸŸ>}Ú4.‘XÙ·Þz ‚ àðáÃÐjµÐëõ=.+꽤¤111=z4ÊÊʺ}×ÕÕ…/¾ø‹-tvvâ‹/¾Àý÷ßÏ£„MYY¢££áëë‹ÊÊÊÛàÄ’%Kü0åµµ5222ÐÔÔÄàõâòå˘1c–.]ŠÜÜÜ“óÒÒRÓÈÂ/^„ƒƒC¯#§ ¥7n 22:ݾÓétøôÓO±|ùr@||<ôz=222ÐÑÑÁàÝA^^&OžŒ%K– ??¿Ç6Baa!¦OŸHNN†B¡èuda"sjooGWW"##QWWwÛ÷§OŸÆÂ… YYY¨®®FNNt:xçÎCll,V®\‰¤¤¤Û¾ÏÈÈ€N§3qúôiŒ7n@ãJ Ä·ß~‹5kÖÜñ˜MOO‡N§CPPºººPXXˆŒŒŒ;>T–K5•••ÈÎÎÆáÇ‘““ƒï¾ûõõõ8yò$rrrx¤Ð°$ïW®\ÁáÇ‘  „R©Ä¡C‡ 8yò$ ÊÊJœkÖ,(•JìÙ³‡ê§'N ¸¸ñññ(//ÇÉ“'‘””„øøx´··3@$ŠkWCC¾ûî;dgg£±±±±±ˆŽŽ¾c¯êÛ¹ŸžžŽøøx444àôéÓ8uê’““m]pó˜mnnF{{;”Je¥ ÇQÜÅ¢«« ß|ó Z[[±páBØØØ`ëÖ­˜ }}}`óæÍøûï¿‘••E¤J xöì>|ˆªªª{óæ nܸ¿þú HHHÀíÛ·‰ Až>}Šàà`¡}mdd$nß¾ ??? ::÷îÝ#$Ê£ >|0`€Ð“_¼x®]»ŒÁf³Q\\,Òƒƒƒñþýû&#èääddgg^¾| àp8ˆˆˆ¤¥¥!==Ž/^nܸ””deeáÚµkB?4ò¦@~ÿ?‚èpÛDII ¢££qqqÈÏÏçÙÏf³ñæÍ@RRrrrxö”›/^ 88‹-ƒÁhðØŒŒ AKK ЦMªmãÇd¨‰PR!¸þò¤l!4BCCñìÙ3,X°@豩©©011††ÀÑѱ±±"Ý'::="'ô)èâ(çÒ²hÑ"?~\%…ºÿ~@QQüüü·nÝ¢”ñß~û PYY‰]»vQãÇlß¾›7ox{{ãþýûxñ↎ÒÒRœ8qÛ·o§>Š4}­©b³ùÿ·OŸ>aÊ”)HKKÃåË—1oÞ<Àš5k¨6óï¿ÿ"&&†§ÍàСC€ÀÀ@¼zõª^›:rä5@áNô”cÀ„¥K—BMMÖ{ýóÏ?˜;w.z ½@pü埣8A%xòä BCC±hÑ"ÚûÚS§NaþüùDè>½°°‡†¶nÝŠC‡¡¬Œ,…~ WÑ.--¥¨?þøÏŸ?ÊËËÚàµüýýqõêUyÅ+$$„2u½yó&µª¶lÙ2¤¥¥ñ”±°°qqq¤ÒäÜ6òòò˜˜Xµj®\¹Ø»w/vî܉¼¼<øùù¡  ‘‘‘ÈËËãiIIIX½zµØ÷¯ªªBpp0 !!ÉÉÉ€ï¿ÿžZe Djj*²²²póæMTWW“Š“l6Ož<|||ŠÇÁ‚ )//Ç£Gàããƒï¾ûOŸ>:#¥UÐþùg +W®Äœ9s ££Cí?uêµr ¾¾¾8{ö,¥ èëëÃÄÄDå…¶e˵&¨\+€ÊÊJ¡>û\***ð×_Q •4 ÒÖ­[y®[SSÃSÆ?Âßߟ´t9··oßRJyEEeÁápPQQ!ô:u»}û¶Ä}úAåPÐëbbbkkkžmùùù”Ï+xxx`àÀðññÁ¡C‡°|ùr°X,•Npp0âããñîÝ;4kÖ ïß¿ÇöíÛ)`®yqYYµ’ž””D­†~ ÷øªª*™û,…„„P¦Ï‚ؼy3UÎÈÈHÒú¥ ''©©©€Ÿ~ú‰ò¯ËŠ+(‹ixûö-|‘Û†Âßßׯ_}"•L3nnn<¿Ùl6ÒÒÒ¨‰>KKK¬]»óçχæÌ™"8@ƒQ¯¯-//GZZµ ammuëÖaÖ¬YðññÁ‚ àììL„G ”OAwwwÇ Aƒx¶ÍŸ?Ÿg;È ÀöíÛ¡©©ÙèráÂlÚ´ 0mÚ4œ={EEEàp8`³ÙÔš»*š••…£G._¾Œ·oß T颺ºšZq ÀçÏŸëS·ìÜgÌÊÊÂ¥K—È› "þù'àùóç¸uëõ±ç~ècbb(¥¸îvY!¨ ±Ùlœ8q@­5‡¸ÁËËËQZZ ;v,åvqîÜ9¾“éY³f Ïïnݺ!00ÇjI[['Nœ@@@ÌÍ͉ÐAœA.“‰•+WòlóôôD`` ŽÛ×þý÷ß@‹-ˆà‚r*èM‰gÏžaáÂ…(//dzgÏpùòe™];55¹¹¹rQ£é",, °oß> œÓ§O§Ü¥^yýú5€Z·A4²$77»víBJJ VÖVùùùð÷÷§÷)S¦Æ@ @ ¸Ñ®«««±wï^* š¬8{ö,X,8L‘Ï( l6›òYç|hð˜»wïòøËhkk#33³QÉëÙ³gðððùu‹ rðüÖ)¥zÖW¯^aøðáR]ÃÉÉI`ûJJJ‚™™´µµqÿþ}*Rzz:,,,TºóÈÎÎFFF5AUVVFŒÛ·o•1à‡~\¾|‰‰‰¤×mä¼{÷sçÎÅ7°dÉ899ñìÇŠ+ðöí[,_¾ÿüóš2¼¯©q˜9s–-[†»wïÂßß±±±>|8®_¿ŽcÇŽ5ê¸"@ ÈT¯).FHHÊËËi½OEE:vìˆN:5~½ºº§OŸ: Súgáp8ˆŠŠ‚›››Üï}ýúuxyyÉäZÑawDýöóóSˆ<óòò°xñb$%%¨]9—†7â—_~ëœóçÏcìØ±JѾ"##áêê ƒ!ókÏš5 GŽÁ­[·Ð¦M=z@­¿>wBŒ+ÿ¬¬,ìÙ³EEErÉž@ ‡Õ«WSujddToÿÚµk©É)6›’’…õ„ZžÝôíS[‘ö ùùù¸téF(((@YYJJJ0iÒ$<|øLIðóóÃÿý‡={öàÚµkˆŒŒÄâÅ‹‘M„C š,aaaX¾|9í÷‰‰‰ÁæÍ›qøðaZïSSSƒöíÛ£uëÖWA¥”Ú7n4xlBBÞ¾}‹ììl˜˜˜(µ‚þñãG‰"¬wïÞqqq°?~Œ¯¿þš–çºví¥0çääÈ­mb÷îÝHOOotŽX,¢¢¢dÚÁ8::Ò¢ s A=D:¶¤¤“'OFhh(²²²„#(X°`Ä}ÁêÕ«ñìÙ3"H9sqßb„?àÙvèÐ!ž>‡;™™––†—/_R})Aq㜠6àØ±cxôèáõë׸qã†\f¼ ÿãÊá•ÐmÖÌÿÏÞááágÏž¡E‹Ô1K–,ÁÅ‹ybt•tÅ'Ož`ÕªUÈËË£²¯Lš4‰ó@ee%†Š%K–àØ±c<ûáKŽ=ŠóçÏÓzeË–!99žžž´~?Î;‡={ö`øðáRC…qýúuôìÙÍš5ÃÔ©Si‹©óòåKØÙÙÁØØ&&&077Çëׯ‡‚îïï   \¸p÷ïß§”n®‚~õêUµ³Î³gÏÆ‚ pãÆ Ú"X/]º;vì åÚ>|€££#_ÝÎÎŽòáussCdd¤ÒÖYÔ“«Ÿd?ÿü3JKKevŸ}ûöQ£“““e–úÍÈÈHjÓx‡©©)¬¬¬e§¾nÝ:lذàî°0˜››ƒÍf#//ï9©©©b=/÷]þþûï±lÙ2ò%U28BBBеk×óòòBtt4ÚµkÇÓgedd`áÂ…3f ŒŒŒœœ¬LM‰Ò¢|”~FjÜkô»jjWWWøúúÂÀÀ€çx+++`ûöíj]Tž>}ŠwïÞaÊ‘‡"""ÅÅÅÐÒÒ‚¦¦&@OO{öìÁ¾}ûxb›qâD¬Y³l67oÞ”É5affž•AQ°°°h”>Í¢’’’‚œœZÕqý)DÝ.Œ>`ß¾}R_GÞ<|ø}úôữgÏžxôèíe¸zõ*íþAÒRVV†Ö­[ãÞ½{ä+®`.\¸PÏTMMM ƒ 9¸¤ zöì‰ñãÇSÛ._¾L„K#çw‹×'Ž5 ÖÖÖÐÐР¶-[¶ -[¶Ä®]»(Ë5}߆W¯^¡[·nˆÇºuë$ºÎÌ™3iõ“$TÓ§O£uëÖ˜3gŠŠŠh»Oxx8œœœ°gÏqâ¦L™¢tRrr2lllä~_º^èÂÂB¾3]Ïž=Ù3g„žOw01ƒ‹E«NÝI…ºƒaeÂÃñ±±R››úT›Ò©C‡_ãêÕ«hÛ¶-ˆÀ·ß~Kõ¯;v”‰‚~ýúužmyyy044äÙfkkK™}ÙÚÚŠtíÉ“'ÃÉɉL®É˜÷Ïo!#ñ½Àýö­ì%n´ç‚mj!22ÖÖÖ<Û­­­ùN¤x{{óüæN¨së¥yóæ˜?¾XÖñ3f Õ׺ººÐLHHV¯^Ñ£GcÛ¶m´(~PZZŠœœ¬_¿P9—»1cÆàâÅ‹r¹—ª[ËRAOLLä›ÅKn º¦¦&©?®Ù@AAež——‡øøx±¯Íb±P\\,qÙòóóѼys¥«¸U«VaË–-r¿ïéÓ§1qâD™_788˜ öe§ÈUН_¿ÎcVtëÖ-Ê·®îË~ÿþ}deeɼ~ýõ×r1ç}úDzk9‘œœŒˆˆˆz“¥jjj<¦euiÓ¦ Ú·o/ò=tuuallŒ””\¾|™Du—’²âD¿¸‹1?Õˆœ» §º n=GIuݯ¾ú ݺuƒ5è"ȆÔÔTTWWcãÆ[×úúú())Á¥K—0zôèFù±èÛ·/ž>} 6›ÍH"../^¼lÞ¼™2ÿôéBBBxr6Þ½{—ÚÏ ¶–““ƒêêj©;…Ñ£Gãßÿ%_u£§§‡N:!88#FŒ ¬-vìØŸþ™HNÌ;—J]I;w¦¬tvîÜI[IÉ»gpñC“Úo—–. Úz2¹v‹-¨IkGGG}:þøã©]Õ³çççÃÆÆFFFõâ•ÈŠôôtXXXÐ^7ÜUúºÐáG]RR---¨©©)¤ Ês¼+/¶oß.ó "~ :¤¥¥ D§P=$$DhP8náKKKF%§›{÷î¡_¿~ “¡¡!ß`eqqq°´´„ŽŽŽ\Êñeç8|øp\½zššš°µµEll,:|=QOjWÜš›Z#/«vÀØÌÀ@`Àµµk×bãÆ<Û¸þ>\sæ²²2|þüéééxòäIƒ‘ô³³³©ÀƒÜYÐÊÊJTTT@WWgΜáIó¤(tttÀáp(ÅüãǨ©©“““BÊcee…˜˜èêêÒúÁÈÉÉA»ví`ee…ððpžüê–––"­ 3w9({yy°³³djèС4hÀýúúú(--m0ª¹¹9ÌÌÌ0eʤ¥¥áéÓ§¤$àâ>áÖ­;¢¹iK¨kH7ÈHäö_é”yJúN% $${÷϶¥¥%ÜÝÝñ÷ßãØ±c´ÜãÖ­[Èä«V­Â;w¨ P¡ÖÈÈiiiˆŽŽà§Ÿ~¾}û ¡¡555”——còäÉøûï¿ù¿aì[·eeeÐÓÓ#£‘Ô,¨¢¢?Fÿþýñúõk 2„SN`Û¶mسg¶nÝŠM›6Ñz¿ÔÔTüûï¿Ä]L®_¿Žû÷„µléÔ Ff6b+èmÛ¶ÅŒ3êmOHHÀþýûIH@FFjjj`nnŽÿý—¯ÿ¸8´hÑ¢A ¬ZÓE„SYY‰   L˜0æææxõêm÷ú÷ß1zôh888 k×®ð÷÷§å>7oÞÄСC©ßß|ó í®QªÌ”)SpòäI™]¯¤¤hÕªíe E÷îÝëm¯»#«¾³®k€"˜={6þüóO¹ÜK¡ ú´iÓàêêŠ-ZˆlF>bÄøùùQ~ÜÎH–xzzò€øŽ_ IDAT¬æìß¿?þøc“ê,X,š7oŽäädsdAÔpª‘• 3gd$½ƒ¹­3 †H|YY¬¬¬(ÿn777L›6 @­y³ >|ˆÏŸ?£gÏžxôèÀÌÌ hÙ²% …-ZT SSSaee…ââb„‡‡£wïÞˆŠŠ’*A0Ë—/çY5¨;óÞ`›ª©AQQš7oŽuëÖñR"Èžº&·cÇŽ…,X€V­Z¡eË–´ßçÎd¥OLòóóQPÈßJɵçH0™‚­b†ŠwïÞñDÿ˜ššÖÛÎf³qñâE’&OÂþ°¬¬ ›7oFEE…ÔQÀüñG¡XÓ¦MÃíÛ·‰ðDJJ >þŒ®]»BCC¥¥¥´Ý«®©6×?œ üˆ£5~øá™*³kÖ¬¡}±@fffrûî)º‰‰ –-[F-÷«©©AKK«^G6fÌžÔtD)ìÕ«¥üÉsssddd(E'Áb±`dd$4èÊÕk0|æ&p8d&EÃÂÞiño`ѪÀ`ð˜oÕó[½rå Nž<‰±cÇ ,OÝ\”X³f ú÷ï/r:´/D~|™rLäååÉ%RŸ>}B«™jC©~øYÀRmã—_~©ç»$ynÅÄßß_êØ2óæÍÑ#Gx{;;;hiiQ.e .ÄîÝ»©ý7nÄíÛ·QVVF*AÁLœ8~~~r 65räHXXXt5l¬ˆ²h$‰É„¶¶6­*éa0ÐÓÓ“*Ýv]víÚ…%K–(ü¹”FA×ÐЀ••åK`hh—&•#wß¾}˜?¾BË (÷zYY233©t;\’’’adf+ðzIII°µ­ÝñâEx{{#>>‘‘‘°³³CÇŽ‘““#Ð…àKåzÑ¢EbÇà¶)]]]˜šš"11;vDdd$ßã¯\¹‚‘#GÊ]ö”KÔ]‚ÃáÐvqÍ€üýýñÝwßQmÆÆÆ†Ç2ÆÐа^4R‚ì8uêž?.ô¸#FP®?² nBW$[U…ß·ÂÅc,ìÛÁÈÜŽH ùõ×_ŒË 000à±êÓÒÒ“ÉÄöíÛÔº‰µlÙ’ºW·nÝ`ccƒ°°0R ÆÄÄoÞ¼‘ÛJà„ pæÌ™^óùóçèÖ­íeOHH€……E=—NyEÓf±XèÔ©“BìèÔµìììðñãG•y&uuuôë×OfVB\+[ºyýú5\]]•_Aoh…“ÅbñäÆÄ—¦³ººº(//‡Ã‰‰ µ:ããダ€hkk£ªª UUUä«!„ÒÒR¤¥¥ÁÑÑQjö¯¿þ‚µµ5yK”——C]]½^ªMMMÂÉɉ2yjSoÌž=[äûêééÁÂÂqqqpww¨œ={¾¾¾2•ß÷ß???¥¯ç†&K„¡©© ƒŠŠ ‘ŽÏËËCll¬À½2õ#È—©S§R™‚)..¦eU§C‡ÈÉÉyò®²²R¦>†ªÌš5kpáÂtîÜYäs  ¦¦&Qú¢ž={ÊÅ5… œÜÜ\ž `tŠãÆ×¡›àà`ôìÙ“öûÄÆÆÂÚÚšv3ýììl¤¤¤ˆõnJJ]kAE)è´fÀ"ˆÆ‹/Ð¥KåWÐ d0vìXžœØ u‚FFFpqq½½=ˆgÏž¡´´[·nÅŠ+üoö­[·nHJJBVVV“n$b‘‘D‰óòò¢;vÄ„  ¥¥…AƒQïóçÏakk‹N:¡¨¨………Ô qöìÙÐÕÕå‰(ïââ"õj„0¢££áìì,õuÌÍÍÅò[áæzWÄ ²¡™ý†ÊåààuuuDGG‹t¯ªª*”–– L簾¦///Ò‹ÓÌ•+Wäv¯Î;#<<¼Á÷„˜M WŠg̘{÷î¨Õ• ³–m¤¾¶žž*++ñûï¿ <櫯¾¢b´$%%«ILL¬QYØD÷Œ3`jj*ñjNß¾}yòÖ—––RÁX òã·ß~£ÆŸÂƻҶ±/­å×B‘›B¶±õ©l6›JãL'§OŸÆÄ‰i¿Ï;wÌ´BP~˜ÊX¨1cÆ48« Ê ÐÉÉ  ’2¹páBìÙ³§QUÞ¶mÛ°|ùr‰ÎÕÐРV;¿üˆÓÁ¸qãx”ë1cÆ@[[ÞÞÞÐÕÕ¥&NÀÖÖùùù<4aÏbkk+0Ê»4DFFÂÍÍMîu{ãÆ ™+§ƒ ’Èèõë×033ƒ™™®_¿ŽaÆNœ8©S§RÁ۸PWW—¹%ÿ€‚RHs¬§§'¢££…¦ô[¹r%©¤§§#44”šØ1k3ÒÞÀÒ¾ —Ó§OÇÅ‹¡¡¡àáÇ”ˉŸŸY‚ s\î@ÝÝݱ±±Ï1|øpQQÞ‹‹‹qêÔ)”——“JQ &&&°¶¶FDD„Ê<×BQ¦ÓnnnHKKS©Å5---TWWËÌ¢—ŽÚüà—?ž Â º©©©LM@:$ô$''7xÌçÏŸ)sye 11‘òïhkkãÝ»wr+¯°z8xð ÏïÖ­[‹t]{{{$&&¢}ûö´•ýãǰ··§5W8ÝóÜFDD:wîŒââbhjjÖ›IKKƒ¥¥%.\ƒ!“\îíÛ·—KÞNÂÿ())Ann.¬­­%zÿÄ=vÆ BûЄ††’ÊáÃ’%K˜˜HM4±jMû=---1nÜ8ªž°téR@Ë–-ñðáCR1 ,¶H³fÍPZZ*ñ÷\ØäJÝS§N!$$„TŠœà篭¡¡---‘\7E%>>ÖÖÖ2Ÿ(ÿ’ÂÂB”””ð,¸ÐÅëׯùf×a±X`³Ù*•–“©±e2i(O½™™*++ nŒp|ÅK«”‚þ¥R!]]]jaÓ¦M"¥õ’†¬¬,TWWË´c|Ë8“ß8¨1ÐÐ*p»víðæÍ™ÜçÞ½{èß¿?i”™™ 33³&õÌJ§ 7oÞ\¬üsòÈÍ»wï*U^怀øøø=nÈ! ¤µ,º,ñêdÊ”) îgà7aÂÚ"¤€¶¶6Øl6 a``€üü|ê#øôéStêÔ ÉÉÉr1…É“'Ó=žÅb 5÷·´´Äœ9s„wBL&åÇN{÷îÅ‚  ¦¦Ö K‘°÷S`2ÅûÄX[[£¢¢‚dÖàCII‰XqT…ôôt”••aÍš5ÈÏÏGnn. hMI'†††¸qã¾ùæÚîaiiÉ“†íK8±x Ð2À ©*tïÞ]¬ ʲ§Ëâ[¡§§'p¿ŽŽÊÊÊTªž  «»¨¨(˜ššÂÔÔ”(è_¢¡¡!4Â¥³³3uÌ‘#GD¾¶ -~Ê’šË®?°¢a0˜øiï=˜X;ÊìšmÚˆØÊÊŠÖHœÄãDZwï^üþûïõ&“š5k†²²2•òâǪU«„úŠkkk‹QÖÀÀ€'4×*†@/ °··‡‰‰ 6oÞŒ²²2äääÈ,5Óï¿ÿ.ñ»Èí×oÞ¼I*êÿ©®®–8“‘¹Ìí\ÕóîÛ·>|€­­-.^¼ˆ˜˜,Z´&LÀ’%Kàïïßhž%>>¶¶¶PSSÃÞ½{QTTDëPKK«Á¾7//Oæé‚rÀ à+nªiU¢n*mi(**‚––V=W¢ ‹H×®]ùŽEÑûꫯd^eñ€·oßÂØØæææøóÏ?1{ölèé顼¼¼Á5YÒÒ±Z:vRŠvþüù2¹ÖÆI¯/ß}÷\\\ ««+Ôå¡n®{½Œ3®®®j£æ§¦¦ÊÝEA__ÅÅÅõ’’™Ý«¦¦………ÈÏÏGAAõ×øå—_D:nØÔõõ,,ì\`ßNv¾œÐÓÓ«W7¢–Qxðà— Tf mÝS¿Ímšã±;vŒo̰°0ªmIÂŒ3Ó§OcðàÚg²··Grr2:wîŒU«VQÍíڵÕ+WððáCL:U)•tnÉ#ðe—.]DJ)Ëåï¿ÿ†££#ôQPP€ŠŠ ¾Y+,--‘––&—rüöÛo*—ºò믿Fpp0id nß::: ¦8öðð YøPUU…ÂÂÂ'7䦠§¥¥ÁÇLJú‹zÎðáéô ZZZ˜8q" X,ßã…;ªË‚ dµ1;;éééBW÷ 444PQQ¡†1yòdÊ ŽŽŽbåá622¢5(›Í›Ín0ˆ×—(»Ñ AƒêmkÛ¶­Ê¤äSûöí£ú׆Ñܾ}[éÊÎb±¨AìêÕ«)Ëggg0 «Ç¸vífΜ‰;wî ::@­%¿•Æ3gÎ`ôèшŇ”F6l6AAAõ¶kjjâСC -›ŽŽŽHßraL›6 YYY”á±cÇê™é8šÄj Öµl Á”)S”b€{ùòe„‡‡+¼ZZZTîzkkkäææâĉ8~ü8&OžŒˆˆ,\¸tžbrðàAª¯å7ù¬222`nnNû}Šx.K>|ˆ>}ú4©vÕ5YS¦²²ÅÅÅr þúõkÊí¯É(èòÄÓÓS©"¬ËQg.Û´iƒï¾ûNä목©AWWWò†ÄTC/åõ5jTƒ/W®ÝºuCÇŽ%ºV©Í}‰ Ôº+n\¾þúkâF 'eÊ.(îÊhqq1®]»&Rj®5Stt4úõë‡ÈÈHx{{+ÌÂéKJKKqæÌ•l‹555¸yó&ÂÂÂlذååå }®ŠŠŠ£¨+ ‹…qãÆ¡Y³fD1WtuuUnÅTVœ:u “&M¢ý>\k-ž¶¶¶\¬µTRA711‘ËL¢"8yò¤HÇ5kÖ ¶¶¶"_ׯÆFìYQ'''¹˜nÉkkk³oººº2±ÊpvvM•ÛÜ—HÈ‘@ø’eË–aûöíb3uêT¤¦¦ÂÖÖ¶Aÿ_&“‰#F ¨¨ãǧ”ù·oß"!!AiVÒ£££áì쌘˜±²ZCÑÙHOO‡»»; ÿþHHH¨·*ß®];¾)ûœabbB¹Ë899!##C¡–ÕÕÕ¸~ý:FŒøøxØÙÙ¡U«VÔJ¶2Ô›††œIç¢`vìØŸþY¥ž©gÏžÊ7üСC"¥ƒU5úöí‹—PV¬XAk:g•VÐë²téRèèè4xŒ4+Ç‚¸rå FŒÁ³M”• …+yÞÞÞÔjfC²ñôôlJƒÁPºRIÚ\CÙ ÔÔÔž?z„ b¹äËùóç1vìX•~Æ«W¯"22²ÞvMMMTVVò}÷fÍš…Ù³góL Lš4 OŸ>źuë¶š~íÚ5Lž<]ºtA¯^½OOO™]ÿ‡~m Àd6èrdnnŽæÍ›Sn¿þúkƒ×«©©AYYŽ?ΓµaÖ¬YG×®]¥~¦õë×Ó‹C¼¼¼Ð©S'tîÜ™ Ž)Ïz²ŠKMquvÒ¤I8uê”J=“,ò†‡‡‡£uëÖb¹+ÒÉôéÓñ×_‘—TAüþûïBw«¼‚Þ®];*Ð üüüd~ßOŸ>ÁÆÆÎÎÎÔ eÿþý˜7o^ƒç9R*Ÿ&I‚x}‰­­-eª-L6ýúõSú6`ffÆ Zev†äêææccãzÛ“““æ¨ÖÓÓÃ×_­°¸\Zµj%0ˆã—hkkÓ’öÀŸ¢¢"ˆ”›¾±rÿþ}|úô ¹¹¹õö?—.]ÂáÇ…^§C‡xóæ õ!UÔ€3%%?†‹‹ X,öï߯r´oßË–-kp«©©Iñyýúuƒ×+))¡‚—ÑÅñãDZoß>…¶GeñeÆäÉ“II6lÀºuëh¿OPPz÷îMN”º¿ÊÍ͋Ţ}®¬¬ *kE¬*¼}ûVh °F£ ¯^½Z)ËåããCå æ–‘Á`P« }úôAPPDÏ–-[ ,]ºTä<Üò0Õ©û,Ñ4ˆ[æºõ¤®®.Óµ¢Ê¥n›á-:t¨ÈJ”–––Ôþ–jjjR=;“É”(à"‹ÅÂĉIO-'²³³Á`0äžç\ìííQUU…äädjÛ¹sçfÿ¨©©Aqq±LØ^½z!**ŠJ¿&o¿æ‚‚ÄÇÇË=ࣦ¦&_srqú½ÏŸ?ã?þ}óæÍ2+¯2­P>xðOŸ>•¨ÌZZZTŽwySSS£pk‚ä;vL.YQ„ •ÕÕÕ`2™ {‰¦¦¦T[ÈÈÈ©+Tcaåʕزe‹Ê>>011Á÷ßß B- ~~~”RÝ«W/¾±¸uÖ­[7*SÝzä*Õü”kU©oB-çÏŸG\\œÂËѾ}{|óÍ7"ÿeÛܺu+ßãŽ9‚k×®¡}ûöb—ÉÝÝz?âíÛ·xøð¡BäÖ»wo‰žMÞ˜˜˜ÀÄÄ™™™øñÇëÅĨ©©º:$mßÃd2QSSCY>,^¼X.V•••<ó² M›6=z´RŒ…›àÎ;*õLêêêRÅÝáö’Z 5uD‰xN ºÜI@mŽnIs¶nÝšRÎdå3Ô®];Zr†·mÛ–Šj¬*i~fΜ)Ô’B–¾\øé§Ÿê ºDM]Ö«W/¾ƒ6AþEÜã544øF_?yò$5aйsgž-,,(óçÝ»wÃÔÔTnr"ÐËÇñàÁª®…±±±X>ð_–WPné·oßÂËË FFF2-¯§§'õ¾XXX 77—˜7ÐhkkS)höïß_/šzaaaƒ¾œL&SjÿîÝ»#%%j'e£££QTTD«,8ŽL- yóæ2É3O ¨" ,ÀÞ½{%>?%%)))èÞ½;&¸ºº KÒ¡¡¡JWG;v”yOtÔ6lX½íNNNÔlõ÷ß_oå\X€7Q.777¡×ëÞ½;_ˆÉdÊmxàÀ|Íè™L¦JÌ8._¾œïvYÔ³¨ØØØÀ××Wàþùó猌Œ¨üáýû÷hVÄ=^ÚµkGYeˆ‚<åDœ´´4œ={øî»ïÔúø}Ù(mL A jjjønWWWGMM  ˆàà`,X°@ìX 3gΤ&?Û·o¤¤$¬]»–öç½~ý:¤N™Ôðë[yò3 Z¿#ܲÙÛÛc̘1† ‚ùóç«D=TdddЖ}B–ÈÛÊF™ppp@ii)222H£EÓÎOô:œ;wŽ” 0Úµk‡æÍ›+´ îîî´L>ä‹Åjþç‚èСš5k vUvãÆpppÀæÍ›©ctttpïÞ=,X°€ç\MMM‰‚©õèÑ&&&˜0aµÍÌÌ ¹¹¹¨¬¬xΫW¯PVV&“ç&™#è¡M›6<ܽ¼¼’ ú£ººMòùíì옘¨ôåT¶¨ÝQР fË$p—jÒªU+|óÍ7D¹amm ___•xƒAåA¯›[¸E‹˜2eJ½|Ã, ³gϦ~™ÿYؽê®&vêÔ 111ó£:;;#''999R=#׬ý矜8qS§N% YFŒ3†'ýÎÈ‘#qöìY"‚ÌIMMEEEìíí›äó8°Q¤Y#},Ktt4ÌÌ̾HV¹Eq/..ƃ¨ßtFs%ÆÅÅk×®%‚¢ðŒ)¿LU{6‚rpïÞ=”––bbbTþy-Z&“‰§OŸRÛLLLøfæèÙ³§Ô÷ã^£wïÞèÕ«Ï÷Lœ;w˜?> OVÓeÌúõë˜9s&þý÷_™­¢qûKÒoª>wïÞ¥,fbcc¥º–´«ÍÿüóisJNdd$ÜÜÜ”®\¾¾¾ðõõU¹,E’••}}}‘3²8;;CCCƒV+ ¹­ s8äççSÕÕÕä­U ƒ¬ÒËuuz渔!’.]ÏF ‡¢¢"ªm €¤EMM­žß,ƒÁ ½Ý2™L¾}h\\œÄ¾è7oÞÄ!CPSS&“ ///´oßž4jú4n›áþ+iœ†ýû÷óí/[¿Ù»wo¸ºº’Æ!………2ëk‡ &U ‡SÏ‚ˆ {zöì‰àà`‰ÎÝ·oŸRÆ©`2™àp8¤r%Ô¥¤ù~ˆô½’×Ã4kÖŒ'¨OcÌ?®¯¯'''¥)O‡DN•Õ¹sgòFÑH‹-Àf³e:h’5æææýh Ÿº³àqqqMb]™ÈÉÉÁÍ›7ѧO±sò¾{÷...xüø1$ͬZµ Rç+ ÂСC½<¸¹ã ¢ãííMý?::III*ÿÌkÖ¬ŸŸ_“­sÄÅÅ‘ÆOŠüü|¼|ùÓ¦Mz,™vƒ–-[bâĉJSž¹s犄dåÊ•¤iÄÍÍ Ã† Sê2zzzÒ¢ø„ZŽ?ŽÌÌL"%FCC^^^T†€ŒŒ \¼xQlåüÍ›7D˜„FÅøñãñÏ?ÿHtnee%444ˆ•˜;wî`àÀDJLMM 8ŽH–ÌDA'hD’HÒ‚,ùðáy¶ýôÓOpww'‘[[[™®œYZZbÛ¶m*/7kkk´hÑ‚gƒÁ ÅGsÓ¦M|SWvìØ†††jÍ•ÄÊ‹þá䥥‘—€Ð¨ðððÀ³gÏ”ºŒ?üð>ܤëÉÉɉ'ㄨp-±š2ÞÞÞ¸råŠJ˜î]…3f LLLˆ ÈêÕ«‰ ÅÏÏS¦LáÙ¦¡¡ÑäcQxxxHåú3bÄ\¹rEvc&³I¤8~ìØ±8þ¼JÉ`êÔ©8qâi  ®®Žªª*•x¢ KÈ’%Kd6ãOW€www°X,RYrÆÙÙ™ä'(Ë–-C»víˆ øÐªU+ØÙÙIumÛ¶Á‚g[QQD¾ÆäÉ“Ie OŸ>"À"΄¦G·nÝðüùs±ÏKLL”ºÿoª¡}ûöõ,¡DAW ´´´d¶%‹´g?üð©%áÇTš\Š ³fÍ"•Bú)•eÀ€pppPȽµµµÁ`0àããCåØþðáüýýE¾75ÞïhË–-•>N@.\À˜1cˆ $ ªªŠoQÐ ©?½ÿþD•¥C‡033Shzôè·oßÂÆÆ°qãF‘VÑ“’’Äò}&ÆÆÆ°´´”è¼N: Ü_VV&’™{pp0"""зo_R™ðûï¿cñâÅD*ÈçÏŸa``ÐäÓÖ¶jÕ ñññbSQQ’’¥Yðú{{{±¬åˆ‚®fΜ©T †(ë _Ú¶m‹±cÇRÊÞŸþ)ô’OLÜÝÝiIo–žžŽ£G =nÆ ¨ªª"­ 2CWW—XÒ4¦L™‚“'OŠuNXX\\\ §§Gd'¦ìòó󑘘¨´Á–'NœˆÓ§O]™4hÒ”ÅÌÌŒ–h¸@µk×¢¢¢¢IäGnl´mÛ?ÿü36¶lÙ‚U«V5i´iÓÑÑÑ*õLýúõý{÷H'È¢  Ctuu1yòäg×srrPRRÂ7 >ÔÔÔ ««Ë³mðàÁ¸}û6îܹ#tREWW¾¾¾(//G||< ÂH¨Giii½6ÖÔX¶lvìØA@t@ d“““HÁöÖ­[‡7ŠtÍÂÂB”——ÃÔÔ”ïþcÇŽÁˉ.]ºàíÛ·ÈÏÏLj#øóùóg˜››cÖ¬YèÛ·/žžN&X cΜ98tèPggg¼ÿ^¬sþúë/̘1ƒ(誊¼½½‰ A…X¶lôõõ…§¯¯ââb‘®ùßÿ T¹ß½ <·nÝXZZböìÙèÛ·/._¾\ïX‡ƒÌÌLèèè€È1]~‚ ’ø†+;6lÀúõëÅ:G­^ˆ‚.CôõõÑ«W/"@h¢¸ººbÞ¼yÔoAAàžÁÝÝC‰¹{÷®È©°Õ‰¸è᫯¾B‹-î§#+ÀeË–-DtìØQ¤ü¬•••(,,$#}&@h€Ç£k×®ÐÖÖ&“êêjTUUAKKKiË8hРܺu ƒ&&dšŠ&:uêDfÚ ‚Â!¾yÊEBBOú!6›ÊÊJèééá(sæÌ!ÏJ ¼yó°ÿ~¥,[VVLLLÄ>ÏÓÓ!!!¤r‰‚N I>¤ú¨¬¬Ä¥K—зo_µ¦‰999èСƒJ>oHHâââ]¹ãââðßÿ5‰6™““C^L‚LÑÖÖ†¢££•®l¹¹¹(..¦‚C*#(((Pʲ]ºt ß~û-iäDAoü´jÕŠ 5¦¦¦`±X÷“”+•">>^eú{¥¥áÓ§OèÞ½;àÀ*]‡HNNntå.**Âýû÷‘-vÊAÔÕÕ¡«««R®0ššš°²²RÊ>¼  %%%<1D¥ëäu£ììlüþûïÔïÔÔÔ&#ämÛ¶‘–FšqãÆ5¸øðáDHM˜;wâóçÏÀ7MTcdùòåP‰þžû,Àܹs©í¦¦¦¤ñ*1ÕÕÕÔ{E pßñüü|;":? ЦM<þ\äR(è2ÁÀÀÓ§O§~_»v­É [__[·n%­Ž@ ÈTVVJJJp÷î]•æÊÊJdeeÁÊÊJéÊÖ¶m[\¼xééé€üü|êÿª›ÍFnn®J¯D%&&";;»Á ¯„¦Åwß}‡ªª*ê½~úôéÿ±wÞqM]ÿÿAK¶ d:PqUʼn£Žº÷¬Z몫¶õãÞ£ZWµnkëjÕºVÅ-¨((¢,Y²…0Bà÷ßÜ1 $!ã&¼Ÿ‡Éç¼Ï¹çÞ÷9ïÁìKIIA:uHH:ˆ¾¾>,,,““#³µâ©S§XŃÃá G¸zõ*zõêŪ²­X±+W®duŸpttćTòT›‰»¡¡!<==™lŽ4¨Ê‡›VKebllŒAƒ‘ ¸ºº2ã«M¨sJJ 6oÞÌʲ¡¬¬ óçÏGYY1|øpÆ÷\HHHÀöíÛuªOYYYÁÜÜ €yóæáĉUZ05777©cíÞ½{1uêT’bdd„víÚáöíÛ2Ÿ“›› V׋­yä?~üÈú:ª æG>è¡å/ Yó6„6³{÷nDDDh]¹…Át\\\ðöí[tïÞÓ¦MC£Ft®æÌ™£õu°´´„™™JJJàììŒ÷ïßcéÒ¥?j×®]K&¡rrr`aa===¹Î355ŸÏg¬­‚`'” ‚`=™™™(**ÒÚò>|eeeðööÖÙ6JNNÖº21Bâö1cÆ€Ëå‚ÏçK´|Ó××'SfBcܼy;w†|Ÿñ~~~8|ø0RRR(°qåÊôîÝ›¡CÐ :Ah!löi"B[[[téÒ…Á2†*qû°aÃh¬%B+¸vízöìI‚P€Õ«WK´’" ¹qvv&!:Crr2îß¿O‚ h¬%‘‘‘>ŸO)ÉÔL:uPRR‚ôôt†øúú"<<\¦cÙØ‘t‚ B£$%%é´‚nkk[#£JƒÇãaÉ’%¬/çØ±cÑ¢E X[[ÃÔÔT+e}äÈ„††(O—ššJKA/..fµ‚îëë‹ììl$&&ꔂÎçóY—âQ[²4iÒaaaZÝHA'‚ 2sæLxzz’ þÒÒR$%%±¾œµk׆©©)ÆŒƒÖ­[k¥¬ÓÓÓÁãñekÕªU(((ÀåË—©#:‰‰ Š‹‹I*fÙ²eXµj ‚t‚ ‚ t]ËÏvx<Ο?O‚`C‡ÅéÓ§k´ .\¸€~ýúQg t’S§N1±MHA'‚ B­œ9sF®ãgÏžMB#´¡¿°"¹›k×®Í:sfu“••kkkêH„N’‘‘Úµk“‚NAšä»ï¾ƒ««k«÷±cÇ´ºüVVV3€›ÔÔT”••ÁÁÁ„¡£ôéÓ‡ÜCÄÃÃzzzˆŠŠªòØãÇcäÈ‘¬¯“««+LLLðæÍ¥_›t‚ ‚PuëÖ…±±±NÔåîÝ»5f…oÒ¤IhÞ¼9u`‚¨M›6ee ®Û·o# @¡smll™™I«Âwaaaa•Ǧ¥¥)d‰¢nŒŒŒ ¯¯ÏÄù  ‚ tGGGÌ™3‡õå¼qãÒÒÒ¨Á‚hCÞëV­Z!$$„uåº|ù2úôéCˆ`5¤ A„†044D½zõHAÈLff&lllHA :AA°a°&‚ ‚ÐÚ2‰bjjªmmàéÓ§pwwgepBRÐ ‚ ­!88©©©•3}útAD5¹ÿ>Ú·oÏúrvìØwïÞeU™~üñGlÞ¼™õ²ëׯ.\¸ SýÖÓÓ111(--­ô¸ÜÜ\˜˜˜€Ëå’‚NAŠróæM$&&’ ‚ ÀÒÒ9992«-þÚ}ûöÅÅ‹©q å _½z@ µu  ‚P;AAAÈËËSù}^½z…÷ïß“À ‚ ,_¾+W®$A)èAñÿ9sæŒÔUœ¥K—*tMIç=zô$ðJ(..®±>ˆAhžœœXZZ’  ??µjÕ"A°˜ììlDEE¡eË–¤ AÚÉ›7oÔz^MçÉ“'Ø¿? ‚@dd$bccI„Z™1cvîÜI‚P€={ö`Ú´i$Ãçó‘ŸŸ+++™Ï1Pu¡æÎ+Ñ_0&&ÔjA räÈœ?^lûëׯI8ëÈËËÃîÝ»)ˆ‹ †¹¹9êׯO¨ÀÁƒqéÒ%±íááá044$JçÛo¿ÅÎ;±qãF©Ó„ ðÛo¿aÓ¦MÔÀšVзnÝ*q{«V­HúAÕ`ܸq7nœØö+VàäÉ“$ ‚UDFF’ àáÇhܸ1,,,¤síÚ5ôìÙ“„¥"Åb„ bÛ/^LÁÉ*¡k×®¸yó&ºuëFÂ777ÄÅÅéT\]])&ŒŒ‰;AAr)Úä³®:$ðú÷ß‘žž^éy¿ÿþ; O‹©U«òóóuªNãÇÇáÇYSžcÇŽaÔ¨QÔÙ $$>>>077'a‚NA›ˆŠŠÂºuëH*"<<œ„PÙ¶mæÌ™C‚P!ïß¿‡««+ B233aaa)èA„¶³zõjæï;v 33“„¢!x<ÊÊÊX_N>Ÿââbj0Bk(,,„±±1 ‚ RÐ ‚ vóòåKæïÈÈHR¼4È÷ßììl™Ž½yó¦ÆÊyáÂüóÏ?Ô`„Ö°~ýz,X°€¡ãàÖ­[•GGGp¹\­¨S·nÝ4:Þ¤ A!{öì!!è8|>%%%ؼy3 £ahhH¥ 2yòä*ÓR†……ÁÛÛFFFZQ§iÓ¦±f¼ÏÈÈÀ‡ФI­ÝÈ‘#qâÄ RÐ ‚ ˆšAvv6ž?N‚ÐR ˆˆK9|ø0ÆŒC~ïZÄ­[·ª¦xöìÙØ¾}; “`EEEàñx°¶¶ÖŠòº»»#&&†t‚ B÷áóùøøñ#Î;GÂÐR>}ú„¤¤¤*ÍA ö|ìgÏž=˜6m ‚ tRÐ ‚ Ö±zõj,Y²DdÛíÛ·+ýM¨Ÿ°°0dddòóóLBQÙÙÙ •¸ïÕ«WU¦eûœ±cÇ’P B‹ÈÏÏGAAìììH¤ A„úFßµk—Èö'NÀÖÖ–L¨5DII ®]»†¸¸8””” ''ÇŽ#Á¨‰¤¤$üûï¿÷]¹rÑÑÑ$$¢ZÏ7¥ÔÒ,())‘º?==ÙÙÙððð a)Àå˗ѧORÐ ‚ B^Þ¾}‹‚‚4kÖLd»‰‰ LLL••EBÒK—.eRèýú믘;wnµ®DB%–ðóÏ?cáÂ…ZS^___‹¥°xñb¬]»–:£tèÐ÷îÝ«ô˜¸¸8¸¹¹‘‚NA„îRZZZežui+B¿ýökëUÙ*–¶µÏ®]»àîîŽ/^P‡ezzz(--%A(@¿~ýpþüyøî»ïÄ¬î´ RÐ ‚ м¼<„–³mÛ6ãéÓ§R7nìí표œ¬5õ5j”Ò¯ùáõ˜¡ W‘BBB‚mÛ¶ÁÒÒ?~¤Ë",--Ѷm[\¿~„A°Ž¨¨(2¥' ‚Ð6BBB ÜVVV†ãÇ#--„È6mÚT­ó¿þúkŒ1¯_¿icáʺ±±16lXãSè………á¿ÿþSù}¶mÛøóÏ?1qâDê૨Êâ†`·nÝB×®]I öq}}ùTnRÐ ‚ ¥ðáÃÄÇÇË}ÞÆ1oÞ<’Evv¶ˆ‚ªM<~ü¸Ú×ˆŽŽ‰"¾oß>²¾î<Ojdtm#!! ð÷÷—¸ÿþýû4h)‰ððpøúú’ àܹsèÝ»7ŒŒŒH„N2cÆ ìܹ“t‚ BûˆÅÙ³gu¢.qqq:SUĪÔl?~ÄÑ£Gk„ì·nÝJPIœ>FFFppp ÎB„Âܸq<ðöí[Ah!/^¼@³fÍX[>µ­ —––âÓ§OÌ?u®"Aè:ùùùÌøZTT$¶?55‡RÚý~ùå—j_£¤¤Dmòùï¿ÿBE œ>}†††xÿþ= ƒ¨qäåå1cmqq±NÖ199õêÕ£W€   tìØ‘ÁbvïÞéÓ§“‚naa±cÇ2ÿlll¨wA(‰0ãkÓ¦Me>ORôì?þøC¥9«|8 ‚Åܼy]»v% ‚`'÷î݃——^¿~MÂÐrssqêÔ)äääÈ}n£FŸ<>ŸOŸ>¡víÚUž‹ØØX¾œTŒH\PP€¢¢"Ìš5«ÒsvìØ™3g’ðBK Æ_|A‚`1 eÏ! ‚P úúúRýÏ/_¾Œ>}úÔ8¹\¿~111¬+WTTŽ?®E?** -Z´ ‡@ ¤¤¤ ;;®®®•gllŒÂÂB¡¸ºº¢¨¨H!‹¶âä䄲²2$''S×0HA'‚ T„ ™™™2ùs¿xñ~~~Ugbb‚«W¯âéÓ§:!§°°0¤¥¥i´ ‘‘‘"éùV¬X•+WªU©¬(ƒñãÇ«üž±±±ÈËË£•` ãÆÃ‘#GH P»vm”””Hµø‰ŠŠ‚§§§VÕIEŸ2f(ÆðáÃqÇîRÇ IDATâÄ RÐ ‚ BH~~>Ž=ŠÆãâÅ‹J»n:u0~üxµæQ×uvïÞôôtæwAAŒEŽINNFYY™JÒãݺu 6Äþýû>>>xùò¥J}¼=ÊJË¢æbhh¨³¹Õ5Í0iÒ$„>|_ýµV>O’2Õ‚NAèÅÅŘ6mšÜç¡S§NR÷GEEUÛÌváÂ…øùçŸ5&›%K– ))Ic÷ÿ”•†OÙŠ¯ÀïÝ»S§N­ò8á*ŽJêQ1°\ýúõñþý{±´?'NdþþñÇie åQÝ Í‘——===˜šš’0äÎ;èܹ3 ‚t‚ ‚M”••©ÄxÏž=Õöäñxý8æñxÍûöÙ-D…)|~aa¡Øj9›•!!ùùùZ“·÷àÁƒ*³øP§+!NLL ªôù'‚  ‚`5­ZµÂôéÓIÿGRR’BÓ•ÍóçϱcÇj%¨tsý÷ïßãÔ©SL´|‚ 4Ï›7oРAA :A¡}p¹\2 ­ÀéÓ§¦ñr”””€ÇãQƒ°œ?ÿüǧX «ùâ‹/ðäɪSË–-¥)]»v--ZD O‚NAh†7oÞ ¬¬Le×ß¼ys^!ÌÎÎÆO?ý¤¶û­\¹Ë—/—ëZÁU“'O&!Ôp222`gg§UenРÞ¼y£Síàíí·oßR‡TãÕ«WbûöíÛ‡)S¦h]ŒÁår•êH :A¡0+V¬P©p‡péÒ¥+ß²²2äææªí~Ÿ>}‚¹¹¹È¶?ÿü³Òs–-[F‚ÈÎÎVÉuŒŒ0zôh0Ë)--ÅíÛ·@ ´èééIŒ®žŸŸZµji]êÖ­ ¥NV“‚NATúQ¥‘{{{{ãäÉ“xôè Y³fpqq‘û:¹¹¹ˆÇìÙ³ÕRöÄÄD”––¢  @ëûÀåË—+Ý¿dɬY³FFFX»v-üýýáææ.— ww÷õ¼”••)}eíÅ‹°¶¶–©ïïܹ3gάò¹rpp€••ìííagg‡1cÆ víÚðòò¢A BÓ$‚ B………X½z5öíÛ§ö{s¹\˜››cüøñÈÎÎÆÁƒÿý÷`üøñ2]§  ÏŸ?ÇÇamm­–²:t>>>ˆ‡ÜççççãÊ•+èÖ­›ÊÊ>TzLŸ>},u·nÝ`ee…N:ÁÞÞžñ½œ;w.¼¼¼Ð·o_ØÚÚâáÇ2•©Y³fxùò%ã6®5‘Úò ­eË–áøñãJ»fqq1ôõõa`Põ'Û§OŸ`ff&²-77gÏže~¯]»(**ÂÑ£GѶm[f­Î„vðßÿÑóªÃÐ :AÁœallŒüžžž€9sæ`Þ¼yÌ1^^^˜:u*–.]ªÐ=¢¢¢`mmÌÌLÖÊÇãáæÍ›R÷+#ú}bb"BCC+=¦}ûö•Nj´nÝ^^^øë¯¿Ð¼ys‘}}ûö 8nnnؽ{7Fމo¿ý–Qf£££EÎñññÁ»wï=::={öDaa¡Zä«W¯âÙ³g̶ÔÔTp¹\,^¼X+Ÿ©ââbìܹøúë¯áïï Ü´½G4èÇggg‹ AëÖ­I ““SSS™&=IA'‚ ´žãÇ£¸¸X¡sLJéÓ§£M›62d¸\.€ò•tKKKæ¸uëÖÁÜ܆†† ÝgÙ²eèСnß¾­VÙ¢Y³f¸rå Ž9R­k¥§§‹mKŠ~‰Ä¨Ð*Ï­î½%QY{XZZbÁ‚°µµE­Zµ°uëV@QQV¬XQåµ322вeK„„„¨¼¶oߎ‰'ŠôáS§NaðàÁ¬žÐ© [[[bݺu033ƒ‘‘ Túöí+5¾‡¶ëêÕ«®^½J«M›6Õ:‹%E †Èw)èA„ÚˆÅÆÕv¿+W®(”öÉÙÙÆ ØÙÙ¡]»v27iÒ$´lÙ&LÀ_|Áê¶xøð!4h€{÷îáüùóJ¿~ZÂ[¤¾¬ò¸êÞ{çÎptt¬2xœ,}³~ýú2ëëë‹ððpz l/èß¿? ƒ`èܹ3îܹ£SuêØ±#îÞ½K«ÞÞÞ"ÖKº@=„¢¢"­+»ÚÖö?~üˆÍ›73¿“’’èi ‚P7nDFFàÞ½{Ìv>Ÿ¯²èÏŸóìÙ3´hÑB¡sgÍš¥Ðyøæ›o`aa¡63hmåÝ»wpvv®Òï¼*ìííñÍ7ßTë-[¶Äøñã±jÕ*¥Öñýû÷HHH@‡tº-oܸ===æûêÚµkRcØÛÛSçW"ëׯgÆÔ   ¡ÓDFFÂÍÍ ÆÆÆZWvSSSh¥U€Út+++‘ž59mA„²1b“¶„Çã!00Píe‡¯¯/ó;77 Òs.\Xí—çÀµk×ÆÊ•+UZGyV}ÙFll,Yñ¡Õ¤ItïÞ ¨²ÈCRR‚ƒƒµZAÏËËCZZZ¥ŠõÝ»wѸqc@ff&îÞ½+–¡€ËåÂÉɉG%3jÔ(ÆJ(77¡¡¡¨S§ FâââàææF‚`1ÑÑÑprrRØ¥ŒP µ™¸s¹\xxx0ÿÈŠ By¸¸¸0ã« +ÊôèÑ#‘èÑ’¨]»6¶lÙ¢”ûq8|õÕW*Míõ¿ÿý¯Æö1{{{¥F•ÿå—_`nn®•yoUIhh(Ž;&uÿçÑ›¥å0Ÿ;w.~üñG¨’quueÆZkkkxyy‰,@²³`Á¬_¿žAè$Ÿ>}BzzºB“úäƒNA(„„Ô«Wù½|ùr± [Û·oWú}[¶l WWW;çù?ü ·ÿ|~~>¸\®TE¨  ©©©:Ѧ­ZµBÇŽ•~]===…òÛ+ƒ¸¸8VÉ8))©ÊUïû÷ï‹X 4Hd¿³³3æÏŸÁƒÓ@D¡!òóó‘‘‘¡Ðût‚u(3,¡‚‚‚ªíçJh7+V¬‰Ð––&fÊìè訒{›ššÂÑÑQnóÞ””¹ä¼xñuêÔ‘z^TTöìÙ£Õméàà€.]º`Ó¦M*¹¾ÚWÑ>~ü@ ²:)Êúõë±`Á‚j]ƒËåÂÖÖ–!‚5 :§OŸ&A(@×®]ñßÿ‘ jZ¯ —••aîܹԒ:Ä?ÿüCBÐrîÝ»G :ËøþûïYSSSSÔ®][e×711A£FЩS'‘íÆÆÆèС“_¼´´ 6Ä«W¯ Yðù|”””HL›ÆŽ;¦’•óŠXZZÂÂÂBl{ÅvIJJR8^A||¼Èïôôt”––ÂÁÁA¡ë•––2ÁnÏ;‡[·nÑ C(…uëÖaÑ¢EŸ…ŠVIÚÄÀñï¿ÿjìþ?~„VÊ®S§N:ŒpÚ´ib×|>|>¦¦¦4节žœœL-©å\ºt ùùù$‚P<¦¦¦Í qòäIå«„cÇŽU齆 †.]º`À€Ì6===ÔªU yyy̶7oÞ`Ù²eøé§Ÿ$–UÕ$''ããÇ8tèkûŽ:õéÓÝ»wÛþÃ?0/Y²<O¡ë+Û;//gÏžÅóçÏ‘““#Ò§4I‡Tf™B¨GGG‰Ü?ýôë,>´mÍ뮫Ԯ]›É:#$%%)))ðóó#i³‚ž˜˜H­§C\¾|™t‚P!ÖÖÖ011QË„f^^žÄÔn§Nb”gu`llŒ~ýú)tnjj*‚ƒƒV齪À‰¾¾H:V Ü¼³bZYY©%m ŸÏ—; ¢Œš7oŽÐÐPÖ´Ÿ¡¡!ŒºuëÒ€GA ºú!³vÝ')) >$A„–„3gΈlëÓ§V™®™››ƒÇãieþÔÏy~[6ßÏÏÝ Õž®ÌÙÙY¬,--™ßC† Q‹Tjj*~þùçj}{¨ÛçÖÅÅ…¾‚ HAg¸rå µªŽ˜˜ˆû÷ï“ ´„˜˜ìܹSl»pŶ¤¤iii$(sòäI<~üXæãåYïׯ:wîŒQ£F‘ % ëó¡ˆÄÓ›'*“£££˜¿:ظq#ôõµÿóäĉÕ¾ÆæÍ›eŠçQ»vmJ_K(…ŒŒ •Æ!¢†)è¹¹¹ŒéÛùóçåN—C„âI4 3g€ò©uëÖ‘ XÄ“'OD‚peffÊåK+l[Y7nœF>ü4nêîÝ»øøñ#óûþýûhÔ¨‘HdÞ””"88X©2¯Šk×®‰µyݺu±xñbXYYiD^²¤¤‰Å³gÏtþýðኋ‹«Ÿz!‹áñxÈÉÉÑšò¦¦¦Ê‚‰ ØÊ¼yóððáCðx<åQòòòðéÓ§*ÓÔêù˜1c`oo¯òû¤§§ƒÏçcûöíÌÄÇÞ½{áéé)²:~çÎ4iÒ×®]9¿]»vb˪$;;wïÞSМœ°fÍØØØh¬nܸ±ÒýÑÑÑxÿþ}µû.dee¡¨¨HkŸe777̘1ƒ5Bnt1B¸º9r¤˜•LDD¼¼¼``` •uZ¿~=æÏŸ¯ómŒÖ­[“‚®,233‘››K£‚ÈÈÈÐø üàÁÖç<óæ """”G–e%ƒ ´¸¸8À²e˰jÕ*¹ÎˆˆY­»qãΟ?ÏÚºšššbÆ 4hJï³aÃ$&&ânj—’’‚:uê°R.GŸqã˜ßÉÉÉxòä k”ΪXµj–.]Zí{íÞ½¯^½ÒÚgÙØØ˜"·¡”q÷ýû÷$hÛ¶-=zT3tÌÌVpp0€æ—_~aÒÈ:ó•žžŽëׯk¤Šø!gffjÄ""<</_¾Tøü°°0=z°}ûv¦¸"j&YYYÐÓÓSê áË—/Ñ´iS™Ÿé/¾øC† Ѹ,F]ík„„„0Ñèå!66V,﫲ÇÉê2cÆ ™­ÔÔ:¬4‰$— ‚¨)äçç£V­Z$B'P¶5 )èZFLL €rûôôt@BB£¼ ÷§¤¤°f%DÒG ¼lܸQ«fõÎ;Ǽ€„aIIIZmFIh<ÀüùóajjªÒÂÏŸé°°04iÒ„ùmnn;;;Ö>§òðéÓ§Jͪ÷íÛ###1ÿíÂÂB¹¼ ezíÚ5Ô©S‡±x‡IQø+¹Ýoܸ!–BÎÝÝUíó믿bèСJ¹VZZš\YAþûï?XZZ*=õÜåË—™÷õ¦M›’’‚ÂÂB…¯×¾}{ØÚÚÒ`GhW®\Á—_~ ‡C mSÐóòò°víZj)9IHHÀíÛ·»víB||¼ÔcsssÉt»‹/–û¼ 60A …«æÚÀÂ… Õ~þ©S§jD€'MsóæM™"@W¤´´”±È© '1uZHHãßµhÑ"˜››³R>G•K¹Y¿~=,X qß«W¯`ccƒÃ‡ÃØØ¸ÚJ“µµ5¼¼¼°`ÁÔ«Woß¾•û)qˆ|*qß™3gŸŸ/¶}Μ9¬2—;vlµ¯‘ '”OŸÏGYY™˜ûÜùóçaccSeÐ>y9q⣠{{{#!! _¯{÷î¬u¡ B5$%%!''5"a°˜M›6á§Ÿ~ÒM]  66–Zùÿˆ‹‹CXX˜Øö .(÷! {…3ôÂã*²k×.‰×T&W®\QZT}IuP6ÑÑÑr·G\\œ˜>›ýr…DEE©ýüÔÔT™‚Šê'''ÿý·L®—/_FÏž=+]qsscmÀ}}}‰©+{Þ¥ùFçååËåJMuõàÁ´oß^æ{ÀÔÔTíqWêÕ«CCCêÓ6lêþ 'µ|÷ÝwÌß/^¼@||<¤Zt]¼xžžž M¨TEZZš\i ¢&¢l_`6àïï/’v¸¨¨%%%ä"ÀrÞ¿WWWÝTЕ¬«Aê„ÇãUjÖVPP f~”§p<¿üò ³b{øða¦3ܹs°sçN1Ÿgáqêæï¿ÿVš¹¦ê ©OUl!ÙÙÙ"eˆˆkU½ª>«Š>]XX(qE­&>ŸôÓV)Š@›6m0`ÀVÕ­W¯^s{ÀØØXn뙕+WÂÌÌ ŽŽŽ033ÃÆann޵k×ÂÒÒ’I·sõêUôìÙSmõ¼ôÇ |õÍ ¹ÎñõõUŠŸ¾²±±±žžžÔý›6mBVV€r@ÀŒÁ’ÈÍÍUè}ôðáC 2Ddd¤ÄcŽ=Š&MšÈ»$$$gÏž­ò¸ÄÄDܼy“ùMÖ…º‰‰‰ š7o.¢²Ó£GܸqC§êÔ«W/±¬„ìïáûA›¨ ú´iÓä>çþýûŒò« Å'00ÅÅÅÌ qúôi|ÿý÷ÊMJ/_¾\þQué€r¿Cá ûÚµkø÷ßÅ®[éGF|||¥>ÏOžeÊ™Ž»råJµï%¼Æ§OŸÄfÝ>|(Qiݾ};ã{,4uKIIÁ²eË”§!úꫯDö ŠÏ¯Wqe6##ƒ™xûö-JKK•"Oá=222$š® å-«Ük ÒÌ…-²³³‘’’"Ó5>|ÈLýóÏ?HHHSö…)–Ξ=‹ØØXäçç3é^¾|ÉDÞÿó¾%ìÓ¥¥¥Ì uFF³B?kÖ,ÆB#++«ÒÕ›Šý[ØíÁƒÈÉÉ;vëÖ­•®$ê#33Sé~x‘‘‘2ÇgèÖ­k}™}||ªuþ¢E‹pñâE¸¹¹É¬$íÛ·sçÎ…¿¿?Úµk'óSeeexýø*uxÇÞ¥K—BOOaaahÛ¶-±`Á>|¿üò üüüТE Æ’ º}EÙ¬_¿^dŸ B•?~#GŽ$AÈ@‡pïÞ=íRÐKJJššÊüSVÀ°?þøƒù[¨0É•¶Dx áù|>ŸñŽtéR•ùh³Úxúôi„……!((¨ÚÁ·TAJJŠL“¥¥¥¬âURRÂÈ]™TeV¶nÝ:¦ýùçŸr_ÿâŋذaƒHß‹Çï¿ÿ |%]¨´ ¯Ÿ““ƒþù@¹)ú»wïDÎ/((ÀÏ?ÿ,ñ¹¨ÈªU«˜gOÒ1›7of¬@„“M|><ïß¿g¢ _¸pAf÷ˆŠÏ¡:222˜ñ5//©©©°³³ƒ‡‡‡Òî"5 äš5kD\nF]©Y²¦éÞ½»D_tiŸ‡ŠõUdUÁÎÎ#FŒ—ËÇS(Èϵk׎œœ”••"+-‘OÿÓéþÝ®];ôîÝ[æqZ—.]‚¯¯/&L˜ôéÓGâ€Ã‡ÃÔÔTÌâ(÷®Näuyö=.—KA¡X@zz:3Öj"n AìdàÀ YÓjTAÏÈÈÀêÕ«™ò¦þ‘…o¿ý@y0žÓ§O‹íOHH`r‰½`…ç¿|ù’1+^Ž;†'Ož ;;[d:11+V¬ðÿSh+yyy¸ÿ>RRRXcz)wïÞá—_~©Ö5"""Ä¢ñ û4"##•fÙ ¤  @¡<Ç•`Y¢¿yó†1m—&S¡’%\ ÆÞ½{+}¶+3ï¬ø|¼|ùRê³_\\,1 !;vì`ÆW¡µ…‹‹‹Ò>èoܸ=zTÚ·„Ï…:ƒ¡)Š\©Ð*Z†têÔ uêÔ©r¬Æœ9sо}{<}úT,‡¼,¤¦¦bõêÕ̹fVvÈË–=žHbb"lmmabb¢5ýÛÆÆ£GffEdߦMtïÞ½Ò¨º 6dþŸ}Âo¿ýVeiáÊæÚµkqñâE¤¥¥!00P­3èê"++‹Y©ÕUÊÊʘ݇2“6ÚÄ?ü€-[¶(õù…={öˆ™ò'''‹˜ÚWÆ­[·¤šH⯿þ¢QYA–/_ÎŒ¯’V+RPP###¹,:„ñãÇKÜ×±cGtïÞù­¨âªn„Gò2bÄlÞ¼¹Z÷¶µµÅ¨Q£4’‚.22NNN033«–ÔÍØ±c¥¦±«ª 0|øp¹ý¶-,,ðõ×_ÃÈȈ‘—$ø|¾HTueX ÅÅÅÁÒÒ666Ì6SSSrEÓ0«V­bÆZm˜ŒdhÔ¨‘\Ù X¯@éë£S§N¸}û¶È÷WeÙDÆ2]³@áp8Ð××WŠ•¸VFqOMM­4€Ûç Ae‘Σ¢¢*t.ï¿ÿ¿þú+=a•ÃJ3ÿììlüðÃ"ÛÞ¾}[­luãíí·oßÂÈÈHHH€"##åz>ä%::š™˜º~ý:ur-e×®]8p Ò¬dlmmŧk×®¬Í{þ97ÖȹBfÍš…æÍ›«¥®oŸß† ¤XeuÑ4ÒÆ#ᬯ¯¯Ø¸/+“&MB¿~ýpéÒ%©¦JKKE¬,¾ùæxzz*ý¸xñb¥º­ÚATT<==I,ÃÎÎNÄ 655•‚7ÊÈÒ¥KE¶>xðþþþZ]'ggg888 $$D·ô³gÏJõo,++Sh¦åðáÃb xII‰BJ¹‹‹ DLt Yíg©Œö(**Rh6èyhh¥¦ÏlâÑ£GRûž&Ñ××gfã $æÛbbbwww¼zõ íÚµc2,^¼k×®ÅêիѱcGܹsÅÅÅJ ÚUÝÌ„f(--U©õÏøñãY®:ðù|ÁÏÏýû÷WÚu0uêÔJWg…\½zOžO®¿X<6ËÌ™3EVhµüü|ÆU'44nnn8uê”ÄcKJJäŠIS:uBƒ d>¾eË–•fÿ Y FëÖ­I„Îrúôé*³¢Ô$X¥ '$$HMó•ŸŸ™3gVëúÂäwïÞeR[ÉC­Zµ §§'bº}ûvÌž=[ê9¯_¿f|Ú‚‚‚йsg­éÂö8pànܸ»w¸˜ñoÕv”•?\•899ÁÉÉ Ožšä-×îÝ»1}útdee!11M›6QÊ:„¯¿þEEExþü9Ú¶m˺agg;;;¼~ýZdûÇñ×_aÑ¢ELÎvE)))Aq±¸©åêÕ«”<“ס¨¨@®s¶nÝ*Õ[Ò—p( IDATÓ(Òÿ¡  @c¢äy ùqttDÿþýeŽ4^VV&qeýàÁƒhÞ¼¹ÒS¶±…Î;W9qªŽçÄÖÖÓ§OPîš%ícbâĉR³G\?º¸KWrLbÂÄãR°=¨$ `hhˆ©S§V9¾ìß¿ß~û- {{{¥ÜßÌÌ ßÿ=–-[¦ö±³ª:Q3Ðeë]Uàïï¨å^C‡•¨\ëô¤¤$,Z´ˆu¹|ùr¬\¹R®s"##áãモ¢"äççÃÚÚZâq™™™°³³cM}[·n'OžÀØØÆÆÆÈÎÎF£FE]*""öööHLLÄ»wïd^ÑÀDè Ä‘#G÷ïßg”qaðÇc×®]r•óæÍxñâ…\å())aU€8???„††(B#Ï*§¢|÷ÝwrËZDEE!>>žÞ*JàСC2—žžŽ}ûöáÍ›7"Û9llldN«§m888ˆø ¾ÿ™ð›5k–HfU`dd ''uêÔ‘ûµë#üÁE”V({Th<ý$O@4kÖLëÚ«{÷î7nœLǾ}ûþþþJ­'—ËE£Fо}{ìØ±Cä9qvvË rëÖ-…³~ܼy“0B­­X¥}¿Ú«£êÁÕÕUì= • zUTŒŠª) %®ø*ƒ’’‰yVù|¾Ê-U¬×°aÃÄ|øºwï.ö`jj „‡‡ãþýûb9ËÊÊpíÈ:‰÷Û½{·Ø¶#GŽˆ¸ ìÙ³Ó¦M¥¯ ¯'©l૯¾Â¥K—T~Ÿ’’@OOO¬ÏIꋪ&//Û·oÙöàÁ™'\ˆª9r¤L†ºté"·ùtE/^¬õ² Gtt´ÄºÌš5Kå¦Ò³fÍBVV|||”r½—Àÿ«otª?‹_ááá8wîó[ €ÏçÃÕÕU$ºª000@“&MðìÙ3‘í{÷îUXAg뻊Ð<==‘ŸŸäädå‹fzzz¨[·®ÖÖ©~ýú())‘k‰Ë”…œ­É D°^Aþü¹ÆË°páBüüóÏ*¹ö‰'0|øpå3퀓'ObĈ*­×¼yó°qãF™Ž–ësnݺõÙ–2$¾S\±Šˆˆ`|öe]%‘i×øðáƒX꿊í¡*¬¬¬@jìUpéÒ%tëÖMÌ<ê?þÀ7ߨÿCžÏç#<<\ê~ñ>FÈ‹»»;ØLUÁ†:uê„–-[j­Œºté |¢lݺuhÙ²%:tèÀ¤æ¬[·.¬òI¬ž={bÓ¦MÔi+aÇŽ°´´Ù–™™)²j‚mÛ¶©­ß„²gudÁ±´´DII x<žÎÈÎÜÜ\$.!#FŒÀ‰'tªNÎÎÎHIIŸÏÇŒ3°sçNRÐՇÑÛÿX>>>ÈÎÎFjjªFê±k×.|÷Ýw¬”±´r Í£Kø’- 6nÜXåL\ii)ôõõ¥¶Çýû÷™Õý#GŽ 11Qîò_¼xaaa¸|ù2³2kjjŠ9sæ ¨¨¯_¿†ŸŸnß¾Í(åÊnI¾£NNNÐÓÓS¨Nl%)) ……… ¥*)){–Ùh‚¯Ì˜1@ù¤ *&ÿ¦L™¢5éÕ*“ÏÂ… ™m“&MbŠ6nÜX­ÊXÅr(‹â¢bæÉáp´º?ëëë‹ô7___|øð™™™Œü¸\®Äw‹²û¬AöBß*Ÿ×•Ð}*NQ=š5k†ÈÈH…2x‘‚.';vÄÝ»w¡¯¯âŸþ©ö5­¬¬PTTÄڙĠ]»v•cgg‡‚‚©)éTµbûçÊQˆzq™‡Ì”ò•ŒçÏŸ3ép¤qçÎ4lØP,ˆ°=>|ø€èèhå~þÂYÑ;wîÈ\¾¸¸8dff">>žÉùk``€¦M›Š)—’L»bbbP¿~ýjɨAƒbþ½ºH~~>Ø —,>|×®]£· ¡v\\\P¿~}´hÑBd»ºV²>çór(ƒ1cÇ(_õ„¿¿¿ÔÕ~©Øÿûù$…²¬>TAXX\\\äV°\«r999äc©f ///¥_WV÷Zµj%1³F@@+"Øóù|j/)c,‡ÃÁÌ™3Áápßtooo 4Hmåõ½2eÊìÛ·O®kÏŸ?Ÿ/Bç¸{÷.:tè@‚`1ûöíÔ)STrm˜šš"..N-u™3gŽZÜž`̘1øë¯¿tOA‹‹CzzºÜç 8—.]ŸÏÇŸþ©Ze“””„:uêˆ)>ûöíÃäÉ“ooo´k×§Nñ]»v-èHÙ9KJJ‘‘!ýXS|úôI$ ØÝ»å+ùÉÉÉøé§ŸPTT„¼¼<Ô®]»Z÷ñ÷÷ÇâÅ‹SSSyG° .—[íüõu˜1ƒP#FŒ[I¯È•+WDÞ{öìÁÔ©SYŒ t á÷Á^6oÞŒŸ~ú‰¡ úäÉ“±ÿ~±íÅÅÅxñâZµj%þëÖ­2Í\WTÚ…ùm¥CCCÔ­[Wâê³®qáÂ…júïäVtñ}µËrøðá*MÓœœÀápðþý{ 4ÿþû¯Î?°¹¹¹HHH`RÅÉËìٳŢXúùùáíÛ·U¦ö˜˜˜šš2Á«eîܹ¸qãc@hmÛ¶…¿¿? B ˜˜˜TÛú¨YÓfèÖ­ S PZ4‚ ´‘Ö­[ãùóçJÍÂTËL't˜˜˜ˆ)c-[¶ÄÓ§O™ßhÕªRRR*üxôèQŒ;—.]BçÎaff Ü_øùóç2û$ ý·-,,ðêÕ+F)Z¼x±È*¡««+µ~ö»bÄÁ9sæà×_­ÖõŽ;†Q£FÉ||zzºÂ±„«ê²`hhkkk¤¦¦Ê½Î Ѽys±í¸~ý:c/ uêÔAFFŠ‹‹Ñ¼ysÆêC›Áßß  Ĺsç0yòdp¹\æ¹RF]Z´h§OŸŠDy'TÏìÙ³åNsSqœ2dˆF|}k*nnnÕš“æD(i}!+HNN&ajÃÉÉ )))j ”[˜þïÿS˽>Ï$À¶ï+V)è¶¶¶°µµEdd$zõê…k×®I<ÎØØ3fÌPø>Uåò«hÞ|þüy 0@âqƒ†‹‹ ôôô0jÔ(üý÷ßÌ>]ó¡P·ÏÎëׯqùòe•ß§V­ZðôôÄ‹/´Ö/ÉÜÜœI- b†^«©S§bïÞ½€>}úˆµ‡*äU«V-L›6 »víÂwß}GoG <ã×®]“y‚kÓ¦MÌßd’¦^ºvíZ­À3䇩^Ú´iCŠ:¡0†††ðóóCpp°Êï5hÐ œ={–„Nh]ŒCTÝ÷­Úô¼¼<üûï¿Ì¿ììl±c$åêþâ‹/”rÿ'Ož0׊Eýúõq÷î]xxxÀÑÑÏŸ?gV$+‹pÞ¸qcÆ_ÛÏϯÚÁëØNZZ^¿~!C† yóæÈÍÍÕ™º?~\+Êééé èƒêîîÎäþ=qâ€rÕ¾}ûbĈprrBrr²V €Âl„üܸqƒ_ß¼y#×¹ïÞ½cÒÚÃßÿsçþ%A°”zõê1qräeË–-”#š¥\¿~k###Õ¢¼¤¤¤ˆ¥ËU&ꊦý×_i<ů26lΜ9ƒÒÒR„„„ U«Vô€°œ½{÷ÂÒÒ’õåT›‚^ZZŠüü|æŸ4Ó‰ÜÜ\‘tU˜=\¹r½{÷f–êÌrôíÛWç‚îôîÝ^^^ÊM4*®ÈΛ7OgêÉáp´¢œýúõCƒ dz*æÌÕÓÓƒ¾¾>Ú·o‡bÖ¬Yìôõ™çR˜wžÃá U«V”v­ ˜ñUß1KKKŒ?^kžBôý´”2 è"”ÿœ½ðx<…ÆZE)))App°N¤Æäp8*¿ÏСCqúôi•ß§bæš-[¶èLì á÷—.¢-ß:꺑………ȬYÅèÁ),,T‹9²hÔ¨j×® ÌÌ™ƒƒ¶nÝŠ¬¬,L™2ˆ‰‰aÌá9ŽDÿa¶Ð AØÙÙ:vì(Pa„ èß¿•y¬ÙÆo¿ý†zõêáêÕ«b+›ÛCYtìØQk>~nݺ…]»vÁÌÌ 'OžDII âãã•fQ£‹TŒ;ðîÝ;™MÖMLL0lØ0˜ššÊ¬>}ú”ÚBC˜ššVàôsÌ­íabfEÂÓ²®ªedd 66 .„ƒƒ Ž¥ 8ùûõë׈‹‹#¡°Œ¦M›Räöjàïï­[·Êü] -ØÛÛk‚NS´JdÁ‚ÊgÔ Êç>ôõõ™™p.— 022’+â¼:°³³ÃÈ‘#e:–Ãá0Ó§MŽó{•^žÑ£G3fÝ;vìPÊ59:uê$Mí1sæLzPnq£¯¯ÒÒRZÙU_}õ|}}en›7’Ð4H—.]мys´k×yq«<Þŧ´êN‚Óð·fÍšáÝ»w(((ÙŽK—.A__ŸÆ=‚ D0`Î;G‚¨-Z´ÐšÌAUÐcbb$š‡O™2;wf5j„E‹©äÚNNN)233S(‚vÇíýò8\4n×/ïƒeíºÈÍH‘ÉçyûöíM¯[µj…Zµjîܹ£Pߪ_¿>ˆDà÷öö®4 òˆ#˜TsÕ Æ¤(Â~ïææ†uëÖéì ”ˆü<å¡9dm-Z nݺLÜBý¸»»ÃÅŃFQf „åôë×OdÜÉÉ iiibæÑšxçìfÔ¨Q8vì˜ÊïÓ´iSŠÅR6ýû÷WK@:///•×G4mÚ/_¾TÛýœœœ””¤òûèò÷®Ö*ègΜÁàÁƒ”»=z4€ò”jŸû_U'‚»¢﩯¯Ï¬~+›.]ºh4ÊëÂ… :ÏÈÈ“&MíLú” ðhÚÑ/ïRô&Mš ::<†††ÌGŠºwWÎ*ÏÙ³g™¾µgÏ™ó0+ŠÊF^ ggg‘mzzz*ës•7M÷9===Ò(Ìdm… ¢cÇŽhß¾= Mƒp¹\Š¢¯%p8™VÄÕõÎ!´«ï¨Ãg[ÿåìÙ³R³i[ÆŒ#’iIW¸xñ"úöí«òûtëÖ 7oÞTË·‡ª¾wIAW?F›6mD¶Õ«WñïîÒ¥‹Úˤî{9r„ùûèÑ£¬ÿ8”%¿_³f͘H÷cÆŒÁ_ýŬ‹Û³gO4jÔHì–––pwwGnn.8³²þ9<|>uêÔa‚ª}÷Ýw¬OsãççkkkµÝÏÅÅÌä…PžÊöÃ711€ò`ƒ•ù,O˜0ݺu£™%ý±ª—iUÇš%ñÝs ©øŽ'y˜Š©TUIhh(ïrrèÐ!Œ?^m÷{ùò%š4i¢S2œ3gEÀg«‚.‰>}úˆ) †††øöÛo”çÕ%“0ccc‰+gggÆt»ÿþb+¶Õ¡~ãvpö’< ÏŸ?6l`”úÊ"ž.^¼XâvOOO >111044D½zõDöŸ9sƒ BJJ rssÑ¡C¦p¹\¥øòMŸ>]'###&B¿4ù+Š££#¾ùæ™ÚAYíDTŸªú‡Ãó©%4GÇâcÓÕ#kI0,¤M›6ð÷÷¯ô˜Ñ£GkE B}`þüù$»’ ª}j‚nhh(5¹ðãPè§ëîî777¥ÞßÛÛ&&&Z×VVVL¾Uooo1ßÆÆ†™mÞ¼¹RWlíœ=`ãલº>|Xl[tt4³ üôéS•ϼ Wwíìì”â{kff¦séù„Tw¦ÿСCbÛ’’B#¶šÆŠ  =ø´ê'¦R÷úi MHP,ÀÅÅžžž•Ó®];­ü!TGÓ¦MI`Ù²ejNïëëKŠsMTпüòK&×Ô©S™CE"YO™2¥ZùÌ…Lž<¹Ò bš˜e1ÑöõõÅ AƒYÏ åÊf>/£‡‡ºwïÎl—ô±räÈŒ7NíemÛ¶-rüøñrH ëäîî.’vP—X²dIµÎ¦õ000`âtéÒE¡`„üèééÁÄÄ………'K–½ÄõôÑsœô ¦\#z$(¿ó¢2–.]JB ”[=ªsµ~Þ¼y022"Á×4½iÓ¦L.íêëÖ­›Rt¶áêê ///åy¼ÍÍÍÅóÊPVÐ5UòyФIÖ—½S§Nb-¬¬¬*uІö°¶¶–ÉÂÜÜœ±`™?>ã÷¯,8h”ÖÀ‹/‘‘Ál6l¾úê+Ž–Ð¨M/´ì6’ÁòwžöíÛcòäÉ$ B#xxxàäÉ“j¹×ĉñ矒ÐYL¯^½dN¿L蘂®*„/8___ÖëСcº/Ï ¸b]ºwï.6 ±|ùrVɾ}ÿšùq!l§fÍšaàÀ Ÿogg'óù;vd”be~Ôùùù¡ÿþ2½Ì…V&&&d¥cØÛÛÃ××?f¶R´U–"iìåpaÀ¥L Ú‚­Vcâĉ•º˜*‹–-[ÂÛÛfff*½Oݺu¡§§‡ääd•שuëÖVù}Te_—Ë¥L;5]AŸ6mZ·n­´ë}ùå—ÊWŸ…Q¤«z°dMÃ% œۆ††ðöö4lØ n&,Ÿ¡¡!vïÞ 8p ÄmÿþýŒ²#<ÖÅÅ…QÆ|||?_+++899±¦C5lýeµÎ_·nˆ‹ÁŠ+ßz___Ì;·J¹ka;UdÍš5ptt„‡‡ÀÜÜ®®åþúõë×g̹…ç[ZZ2Ù f̘Áä¦ÿã?”çªÝkÔ¨³Ò-<ŸÃá0/X{{{ØÚÚêÌ`%”¡>™L»©8ö6ï<ÏoŸ&¡°˜mÛ¶‰YÄDMÀÓÓS-1x„±–*Z©²NQQQ*¿¥¥e¥qÝÁ€ …PG@”1cÆH½—Ë•« B¿X[[[fµ³[·nŒb¹bÅ æAªL¡ÔÓÓc^ÐgÍ«ziÿøãÌßÍš5c”õ¡C‡ÂÊÊJ¤ŒõêÕCÏž=Y×ñÆŒƒ­[·Šmÿ<…ZÅߌB+‰+V`ïÞ½­—Pî077‡¾¾>¦OŸÎÄZðòòb\&Nœ(ós!ìúúú•Î:bÑ¢ELŸòÍ7ß0ÖÂ26nÜX«"ÒǬúéÝ»·XúK‚½ø÷„GWÂÀÐ%ü"‹133±ˆ9r¤ÊW ‚-¿C‚Œ~M©h@@€˜©Æï¿ÿ.óùóæÍcVã{õê°°°`Lèýüü4\®C‡ŒB+,£³ û¿ÿýQÕAÃF¢¦R666L𺀀¥˜ò¹¸¸HÍ‹®.6mÚĤÅÊÝÑÑQ$š¹p»¦èÙ³'ó1(,‹››c•±eËXXXˆ·víZÔ©SîîîL{íß¿ŸF΄:L åШM/‚Qñ¤sçν¨1¨ó›Hžo}mÀÅÅ…&óHAW?¼ɪ¼–p»<¹FkÕª­nl333¥ÕA–vZµr•ÈïvíÚ¡wïÞbÇyyy¡C‡ ÝsüøñLº5yð÷÷WZP3 èëk÷\—………Ä ‹fffÐ××ÇÌ™3™€ŽB+ iØÛÛ£oß¾J)W«V­Ð¤I©5ȪU«”>6ª£mï ÐÓÓ'Ah”ïœ TKïÞ½un’yìØ±Œû,¡»°ñaÊÍÎ…Š—ƒƒƒXÞnìܹSì|oooFÑ^+ °aÃÆT¶mÛ¶ÌêòŠ+˜•Ø}ûö(7®*g©¶"¬£››c=mÚ4f•T¸ßÖÖëÖ­Œ7ŽñÊVO_öÎâŨy{ 'Aiõòòb®!´HpþíÝyP”GúðïŒÃ5häöB‰kXAaĨð#ëã}ăõ@]ŒhTPÁ¶jAE)4^hâÁ¨ÉqY•C…¸ŠŠñÄ忀þýAÑËÈáàùTYåôôûÎ;ý¾ô¼ýv÷Ó––jE ¯þL±X WWW>ܽ®8_}õU­`V5¯©šóÕ«¿«®®.vîÜ ˜0a¿ŽvíÚŹ:ïðáÃù5ÕZ¯š5Ó% /ó€€ÞëSý¾‘‘YÒ­[·ZOz-,,Rës«÷) ùHubHægaaÑj—lmú …Œ‹'1Ýw'D" ð£í T*© iïk¾ö˜1c ˜úcì•ɨe´IDATC|°³³3†а°°?´]rrr­e~îÞ½ËçäýªdÀõÇUÿ‘÷„Âv0·¬z¨1 *¶"##ñùçŸ7ûSÌââbdeeÕê¯ëš!ï_]ç!33ÆÆÆ<€"ÑŒõë×#!!wîÜ¡Âhåîå…RÕ´ü'÷Q©T “•ê(!'K u®¢1HJJBFFF÷Ã?à‹/¾hñ#*‰v¨Õƒ~õêUT·Ù{õêssówPZZŠ[·n¡}ûöï\“[êjhQÃ\;têQwoçÒ¥KßËçwìØ±Î¡òÔ8×u‰DÒ¦ÊàîÝ»(((P“Aºë×_…R©Dÿþýi‰3¢ón½¨H›öÛo¿¡°°`jjªVük×®¡¢¢ÎÎÎ-~J#yÿêšÂIˆFèGŽÁ³gÏøë3gÎ`Íš5|‰¨ºìܹ:::P(ÈÏÏÇСC©T !ä-7oÞÄ™3gx}Z^^Ž1cÆÀÑѱÞmñàÁ…B¤§§kt9HBi~ýõWœ?žOÙ+//Çøñã| üÝwßáñãÇÈÌÌ„··7$!D;è999X»v-tttP\\ŒuëÖ58ÏvãÆ˜Ÿ­C‡¸ÿ¾Jžääd¤¦¦ÖÚößÿþ78!¤M3f ÿÿ¡C‡Ð­[7 6¬ÞüR©zzz¼®mß¾½ÊhRøþûï‘––VkÛýë_Tà„æm U¶¶mÛOOOnrww‡B¡¨•~öìY*}BH›søðaj$âëàÁƒÑ§OŸZé2™ ?þø#6!¤MbŒ!..&&&YöÓÕÕµÎ%?ËÊÊêl¸BˆFèÛ¶mÔ)S4U¹¾å³tuiùB5ΛÂÄÄ„bªéíe) !¤-9tèŒ5Ò8ªÍ™ššÖJ722¢Â&„hœÊZ+V¬€““”J%ÒÓÓ‘žž®2=88Xe-Ü   ÄÄÄ ==gΜAïÞ½i¹$B©CRRîÝ»‡?þ˜×¯ÕQ†ªyÖÖÖxóæ ÀÅÅ%%%¸|ù2ÒÓÓñóÏ?cîܹT„Ò€'N //Ý»wçumQQÿÇ„µµ5är9`È!ÈÏÏÇÕ«W‘žžŽ´´4̘1ƒ ’òÁ¨ô öÙgÈÌÌDff&O³µµE»víƒ RYªÂÌÌ ÞÞÞØ¿?ºví OOO*QB©CÏž=‘‘‘äädž6iÒ$ÞÛݽ{wÌ›7/ï#‹±jÕ*DDD@*•bÕªU Æ!„|òÉ'¸sçŽJ];eÊÞÛÝ£GÌ›7ßÛŠÅb`Ë–-Édhpõ"BinV½èù{æì쌡C‡",,ŒÎB VÉ€ëë~oó'äƒX¿~=pçÎ*ŒVî^>P(U/¯“%ÐNHeFˆ¦")) T„¡ŸjB!„B!„è„B!„B¡:!„B!„B tB!„B!„PB!„B¡:!„B!„B¨N!„B!„PB!„B!Ô@'„B!„B¨N!„B!„j B!„B!Ô@'„B!„B5Ð !„B!„-&ú^ZZŠ'OžÐYhÁòŸ×ýÞ“vT>DsLLL```@¡&¥RIõkð¢(–ª—÷© ¨ÌHÃLMM¡¯¯O¡&…BAu-!D# `bbòaèÑÑÑˆŽŽ¦³Ay§£GbêÔ©TjúÏþKKK*BÈròäILœ8‘ BMÙÙÙT×B4ÂÝÝñññ0ÆØ‡8€ñãÇ#  EÖÚµk±iÓ&:V:V­?N™L†°°0iý±aïÞ½X±b…Zùmll`ffFµ·òòò——W+ýÈ‘#ptt„­­íý[ÈÌÌÄo¿ý†iÓ¦5zß~û-ЧOŸú]²²²éÓ§7zñññ°··Gß¾}?èw¹}û6²²²ð׿þµÑûHHH€­­-ìíí½uëÖaÆ ßÝçÎddd`ÆŒÞÇÑ£GÑ»woH$’FïcýúõX»v-Úµkü²ììlܼy3gÎlô>amm ‡wæµµµ…©©)U¤jxôè?~¬‘}•––"**Jëï5Q_½<@JJ <==µú8wìØwwwXXXÐ}p¥¤¤†ÚbËÒÌÌ 666®]__ÿ÷ÿ×"*`333:V:Öq¬R©æææ-âXóó󑜜Üb®–¤GèÑ£G­ôK—.¡_¿~0`Àÿ[P(MÚÏ•+Wààà€~Ðï" Q^^Þ¤ý\½z4hÐý."‘¥¥¥MÚϵk×ààà—FïÃÜÜ®®® &GGG%%%Mú.ׯ_‡D"iÒ>ªÏKSèzzz(,,lÒqܸqöööTßj˜••¬¬¬4²¯ââb$&&jý9ÒD}õ>ãþýûZ_žÇÇ€н{wºn¢§OŸ€Ö§:eIAâ!¤‹Å‰šö\ö£>jòqèèèhE<M}±XÜ*΋H$ÒÈwÑÑÑiטA“¿‹&hê¼èêêR%H!-€ˆŠ€BÚ†%K–4y{÷îmò>ؤžoMÑÄw0`@“F$À¢E‹´â»8;;ÃÙÙ¹IûX¸pa“#66¶Éûprr‚““S“öáíí­·ŽŽŽpttlÒ>,X@ !„´ÔƒN!„B!„hÖƒþù矷˜B¢c¥cm)Ç*‰0lذq¬pss£Z˜4ŠƒƒƒÖÕ!dĈM vGÚ]]]üå/¡ºWCŒÑ¿­?ÎÁƒ£}ûöt¬½zõj5mŠfâ^^^Žòòrèë뫵¦¦L&ƒT*…žž­wLH+ñúõkTTT@(ª5·´¬¬ …†††Z1ÿ“|økÀ;Gª?jjß¾}“çvÒÆŠ‹‹ùkuê-…B²²2ˆD¢qcNš^½ë¾V.—ãÍ›7*i†††`ŒÕ™®££ƒ7oÞ@.—¨Š¹`hhH…Nˆ•”” ²²Rc÷ Œ1H¥RˆÅâzÿæ«?šíÎ¥  ‘‘‘xòä ºuë†eË–ÁØØ¸ÞüoÞ¼ADD=z„N:ÁÇÇ]»v¥«ƒ,33ûöíCii)ŒÚ`þ»wï"66EEE°µµ…ŸŸbuýúu8p€ÿàuëÖ _ýu½Ë?¥¥¥!>>ž¿ÎÉÉApp0FŒA…IšÍÙ³gqüøqþºwïÞX¹reƒÛDEEáöíÛèØ±#,X*ÈV&==ûöíã7à]ºtÁ’%Kêíy¾rå :¤ò[èïïSSS•ø<€··7>ýôSDGGã¿ÿý/ÀÈÈ^^^øóŸÿL…OˆüòË/8xð d2ÀÒÒË—/GÇŽëÌŸ’’‚cÇŽñ×·nÝBXX˜J´öcÇŽáüù󈉉A\\T¢÷ûøøü/Þk&ìÞ½{Œ1ÆîÝ»ÇÌIJ³³cŒååå1___F´›\.g%%%üßÛÞ¼yÓ,ŸÛ\û%šõôéSÈŠŠŠÔÊ_VVÆüüüX~~>cŒ±k×®±üãTmTHHËÉÉaŒ1VQQÁ6mÚÄ233ÕÚ¶¸¸˜­\¹’½zõªÅ—CYY¯c¥Ri­:X¡Phü3•J%“ÉdtªÁÃÃCå|̘1£Áü;vì`.\`Œ1öüùsæïïÏJKK© [™ÐÐP^_UTT°Í›7³k×®©}ãëëË^¾|Y«.ð÷÷gÏž=cÇŽcGŽáï%%%±}ûöQÁk@ee¥Ê½íÛuls݃–——³ŠŠ :Z"((ˆ=|øÿ&±»w蝹m~~>[½z5+((à×Ô©S§Xdd$óòòbŒ1¶wï^–œœÌ¯³·¯«fëA¿ÿ>Ÿ ЫW/Ü¿¿Áü999ü)r÷îÝñøñcz|£Å ÂÃÃq÷î]Uk{xx¨ÌŸš3gŽ=ªñÏn®ýÍ’J¥P(¸xñ"^½z±X ww÷zó+•JÁÌÌ `oomÛ¶QA¶QüÿñññèÛ·/ìííÕÚ655öööõö¶·999ˆ‰‰AQQ S§NX¼x1,-- 044ĤI“4ú¹7nÜ@JJ üýýéB|‡ƒ***ñÎÞó%K–`Íš5ÈÍÍEaa!ÆŽKC“[¡U«V©ôš}üñÇj¯páÂØÙÙÁÜÜœ§åææÂÝÝ¡¡¡èܹs­m~þùgµëGÒ°¤¤$œ8q‚¿îׯ–.]Úì÷ AAAðññAÏž=é$hM›6ñÿÇÅÅaàÀ°¶¶VkÛ‹/B"‘ð‘ã§OŸFqq1fÏž€€žïܹsHLLXXX`Ñ¢E°²²@ˬ‘F’Ëåxøð!¾ùæ@ii)¾þúk•ºžžžÊ6(//ç¯ÅbqƒÁsd2 €ª bB¡? ¨ž{Uþö\­úÒõõõÑ®]»zÓ‰æœ:u }ûöEçÎQZZŠ˜˜­Yºˆh¿ÊÊJÄÇÇÃÐÐ'NTk¥R‰#GŽàÛo¿mñß?-- &LÀ!CÀÃÞ½{qûömÞ@‰Dµê,™L¥RÉß»~»N®¬¬„B¡c íÚµS™c'•JQYY ¡PÈçÏÖ¬{ëK|Ýn¥RɇÖLoM”J%¶lÙ‚Ñ£GÃÁÁ¡Á¼2™ •••èܹ3***PZZ Æ’k¥õWbb"„B!¦M›¦öµtðàÁZõ—¾¾>6n܈¬¬,ˆD"¸¸¸`ëÖ­|z…­­-¸†|÷Ýwˆ‹‹ãçÃÃÃC¥^WZVV¦ò~C±Oär9„B!¯uuuù¼ãÊÊJ¾¯šéÕu1Po@WW@U¬¯ê8ꤓ?þ7|ðàAtêÔ £GVk…BÄÄD9r„7Ο?ŽY³f¡¨¨J¥9r$,--1räHÀáÇqóæMj “¦144Dtt4€ª'»»wïÆ¾}ûTòTWpÕvî܉›7oò×îîî ^ð£F‚››òòòcÆŒÁôéÓQXXˆ¿ÿýïxøð!`øðáððð@~~¾J››æÏŸï¿ÿ^åiè§Ÿ~ œ;wNeÎj¿~ý°|ùr:¹4qâDÌ™3ðäÉ„……Q¡µÅÇÇÃÀÀ@íÆ9€Võ¨æÚÕç΃@ À_|¡R‡ÖôèÑ#DEEáåË—333,Z´¨Þȶiiiسg —ËñÑGñu̯_¿???H¥R´oßÞÞÞH$HNNÆÉ“'T=­ž÷ºuëV>RNWW ,€D"ADDi%‰àéé —VÕ8ǨQ£ÞÙ8ªÖVßµkPáííÁƒ7£‡´L‰‰‰˜:uªÚÛ8psçέ•ÞµkWtíÚ¯_¿Æ³gÏàææ†Í›7ó÷“““‘ŸŸO…®Õ÷®r¹X³fMƒ÷¶©©©*÷¿}úôÁŠ+êíðñõõEçÎy}ùÉ'ŸÀ××pèÐ!~oû§?ý Ë–-CÇŽ‚'Ož¬¬¬°lÙ2<}ú»wïÆëׯTÍ‘^ºt) ÍG^uíÚK–,¡¸^pðàA˜››«Ý8€ÈÈH•:¸té.]º™L†7n ;;vvvüa{]š­>cÆ ÄÇÇcÒ¤I8qâfΜYë•H$øÛßþX¸p!bccáááŸ~ú ãÆ£+£(++ÃîÝ»Õ æuùòeìß¿Ÿ¿¾uëVƒùE"æÎËo.§M›†éÓ§C$aæÌ™<Ê´iÓàáásssþÐfÍš…ùóç#>>^¥òÌÊÊìÙ³G¥¢9s&5Ð5H @ ðQ2™L%ºqII fÍš…888@,ÃÞÞW¯^…ƒƒ¶oߎ+VPA¶Q‡†H$ÂèÑ£ù5¤««ËGÑ?~III|!//¯Á©- c gϞųgÏ0þüóÞ¸qýúõ×_~ ÈÏÏgϬ¡¡!¶oß===\¹rgÏžÅgŸ}±XŒððpˆÅbdffâÔ©SH$7nF j*[\\¾úê+¼~ýš×¿2™ ¿ÿþ;JJJ——ÇÓ‹‹‹تè›7oÆðáÃaccïӚ£BCC¡T*ùM¾¯¯/"##±|ùrdeeÁÆÆ†"¹·B P(˜2eJõ×éÓ§‘ ®¬¬ 999˜0aO»xñ"D"œœœTõèUÿŽ* ÞKzñâE,Y²„ ^C***ޱcǾsê@ll,bbbø¹½}ûö;÷ïì쌵k×üüüPPP°³³ÃúõëT yþü9:vìˆuëÖ¡zÑ­ÐÐP<|ø.\ÀŒ3øµ‘——‘H„Ÿ~ú cÇŽåËØ~óÍ7¸uë5Ðÿ }ûöÁÈÈÇçÃzzzü75>>.\Piw¼|ùèÝ»7O1bV[XXˆ€€ØÙÙ!%%b±˜?Ø­­Öì ô/¿üÇŽƒ——&OžŒÉ“'«¼ß¡C•±#Fàüùóðòòˆ#ê|‚H´Ëýû÷£ò·!«W¯†———Jº!FFFuöütèСÎH¥ÇŽéS§øëÜÜ\@tt´Ê纺ºbÀ€(//WI¯/2#iœž={ÂÍÍ—±‰‰ ¶o߮Ҁ722âCÁD"–/_Ž-[¶`çÎðóóû_4KÒæèëëãäÉ“HJJâi!!!|ø—¾¾~­eû„B!lmm[üÜóšªçžžžïÌ;yòdDEEñ¿9ssówÞ´ÛÙÙÕ9dÓÖÖ¶ÖpôââblÛ¶ ÷îÝPµŒ”­­-¬¬¬0dÈþ¹zzz¼'>%%E¥ž2dH«ºNõôô¥r 8p@åHõ4- j¤–@ €——ìííiž+¥§§‡Ó§OãìÙ³ÃÖ­[±k×.ÀÀùßtll,._¾Ìa´,©fÈd2DDD`üøñ°³³{gþ¸¸8Ì™3‡7 íííѯ_¿·©o}öºÒ333±k×.”––¨êÜ7nüüü̯ +++ÞsÆãcàuòÇîAŽ?®²JGhh(ºtéÂßïСC­{¾}ûÖ;"JWWƒ  :”ß‹ <<<þ—™âô‘ÆJ¥Ì××—ååå1¹\Îär9S*• nÆóÊåræîîÞ`~vüøñZù§Nª’¯úµ»»;Ï{âÄ &‘HcŒmÙ²Eås§OŸ^+¿\.§è™„­òÃ?°èèhµë©Ë—/³ÔÔTž÷äÉ“ìСCõæ¿pásttd/_¾dr¹œ¥¥¥±­[·²_~ù…mÞ¼™çËÈÈ`7nd·oßfÁÁÁ|ÿ .d«W¯f/^¼`û÷ïçé=b¾¾¾ìÅ‹lñâÅ*ÇO!ÚlÓ¦MìÚµkj×[áááL&“ñ¼sæÌ©µâFM>>>lÕªU<¿ŸŸ{üø1[¹r%ËÍÍåùYNNÛ°aËÈÈàu«»~ý:;yò$ËÎÎæûÙºu+KKKcQQQìŸÿü§Ú÷æD;ÑtÒhÏŸ?W‰FèââÒ`oÍðáÃUFFÔšZkkkH¥R¾MuïkÍ5k¾ŽŒŒäyÇŽË{œæÏŸ¯ò¹ëÖ­ãÃWj¦¯\¹’"„M$!55©©©<Íßß¿ÞÞ™AƒaÇŽ|È““Ó;£Š{zz"88EEE°¶¶Æ† ››«tÊÈÈvvvèÓ§$ ¯7—/_ŽÜÜ\XXXÀÔÔ”§ó^å‰'òt±XŒ={öЉ%„h-@€ˆˆ•žÔ†îWýüü0{ölÄÍÇÇGe„p]ÆÇëEXZZÂÑÑQeº‹D"A‡°nÝ:øûûã÷ßG—.]899aíÚµ|.ûèÑ£áêê WWW„„„ðºvذa*ñLH ¹Yõ˜ B´Ì´iÓh95Bi&©©©ÈÊÊ¢¹«„òž,^¼ÁÁÁ°°° Â õRmÕš Bˆ¶177W{]WB!M׿ÿ—¿$ tB!„B!D+ü?Çn!±×TÖIEND®B`‚snd-16.1/pix/bongo.png0000644000076400007640000004770211147553266012771 0ustar bilbil‰PNG  IHDR^ÊbÉ¿¬ pHYs:ÊduhtIMEÖ §+ IDATxÚìw\ÉÀ_z„Ћô&ذa/Xîìb=À.r*?õÎz–³¢¢žzŠQ,ˆXQQPEDšÒ;$$!¤'¿?#MDjÀý~øðI&»³³3³oß¼™÷ó–ÿ‹ÃÐTi€‚‚ÒÑÈÎË660nüÁxÈep¤œïŸ“oˆ3Ì"e¡µŒ‚ÒáH‰O‘êHÙRöwäsž‡>ÇGÊaHß=¡BZ!ÃÉs$ ŠR!­hÌóËà28¼ü»T"å±x œÀ¯àƒp\´ŠQP:2àW𹼆ž_ ‚Åa‘Ï_EÅ+{^fjlú­Ó¨@ÕÕÒe¦3ÑJFAép˜[›KK¥T&µc¤JRÀAmÑfÆfÊvÊ™ ~5#›Á`1½ h-£ (yQyýFôËçë€ÏÑŸ-‡YŒë~…•BlVYI™+åÖ#@ |K4ðD<ˆ¾õ+ J;RÉ«ƒ¸Ç³’_)’}óùHX– dy ­ÓŽ…D,¹ºöꌃ3êþÄepý'øô4Ðíª;|Ép"…Xo'gì?»ï_{‡ï ÿp÷ƒ¹£ù0ÏaÚÚÍ/§˜ ¼ppÜÕ¸ÂäB=k½áK†Ȩ¦©@ô"õËÄò¯¬"V¾z=º¶Þ“»“ºw#v“ÿcŒÑ mKı B K%"‰D,TdR¸A…@*’Êd²7!oŠÓ‹kØuX×¹s…•BnWž yBy&ç”Id0hÁ n£» ˜;àý"¾ù“ÉdbÄB1ri‰XR792™LP!V  7!W¿»þ÷!|_P!˜0—ÇâU–W¢ ÚÆ¨aÕº“º[ã­«k_{—LüQøQþ÷0öa½™Ô¯5Èd²Âò¯I÷“º»tGk¼m`±Ÿýû¬’Y©e¦ER&&JÄóæêêñ×ã%" ð9ü§'žšõ7›¸}bõsó?äGŸŽÆâ±‚ Áó³Ï+™•ÚæÚ#–Žˆ:U–Yf1ÈÂaŠC½=>ý¸iSè=¡wÜ•¸I;&ÝÝ}WÏFïåù—6#mðd¼õëW_ yBËÁ–ö“íå'¾ }—ö,@&ôŸÕ?õij%£RUGÕj˜ÕøMã+™•xž¨DDÛ´!aI…âÂwqïÔº¨Qu¨Mˤ~ÑPZXšô: ­âv¨D$)‘ˆJĮúfÅeØ ˜=à¼×yŠeÜÿÆUˆÁ«ƒ)ª”…ÿ-¤¨Qj«¢©’þ<ÝÅÇ…Ëà¦F¦j›k'ÞIt¤;V2+‚˜ó1ß $Òˆ%# Öv_·¾éQ逜hlo¬ß]¿Æ Ê@MP!è3­Š¦Šº¡:I™¤f¨<6ïùÏ-DQ¥ mÚÖ£N™$óMfiF©†‘F“3©_4”h” jB{Ácñ¬GYÉÄ„ðeuemóú­Œ†6^»–AAUOÕÙÇ9êß(ÃÞ†ŽsÎøþöû¸+q=\{HÅÒˆ"¾uQ ¢¢¥"ÿZQZñ9泞ž<¥<¿|ø’á%ŸJ²^géYë§Ë$2]k]NgnÀÜg'Ÿá8msíÊòJmsm!Wy,rÐÂAª:ªhƒ¶=¥’RÕÞªö½í›“ j†T8T´TÞÝz—û.×~нD(!«@ËLkÈ¢!¡[BE<‘Ž•¯œ².Ä´Ÿé´½Ó¾ÚðXu#uMªµK÷. ŸÎ{w˜êà0Í!âP„¦©¦A/ˆ¿/Ší&ÙÅœÉKÌ“J¤Îkœù>’‰’º’A/ƒ‡‡ÚŒ²QÖT–ˆ$·MŒ>­m®ñODy~ù¨£àúÿ®KÄ’¥×—j[hŸ÷:¯ª«Ú×­oQj‹A왯3K3J`êî©uµ”v„UÉJzôuL â‹ê= ó–ÿ6AÀ0¸ ®j®*¾7þ[Ó¥ŸK­ ÖeFehå*¹ïrÕÔ•5”ÛåêeYe2©LËL m!ûaöృsD9ß: äQI7çn¥’ÒzT°±jÔ¸R.#›ñöæ[<›Ã.È+àH9Ž@T™9ÌJqý&ev1º@if)Ú Š™Fæ±y<6¯ÝJ€A;ƒ!‰¹ niÙ7[D&“±‹Ù¥œúñDZ ÅÌc²ìŠâ ÀK¥Ò.².2Œ TA— ÁÈ-‰DßÊÝ@¢)ËG'2QPïU¡CVÉS²o>žª:4È“©p¾iCÐ6Õã`ø| tAl Æ«ÑÔ²ÉÙÈ€‚Wè5i!‘Øà´PP:\.÷qB «; PdçecÑJAAA© *PPPPÑ€‚‚‚Š”Ö cÆL¥Ó=‘¿S§‘Äõë7ß»÷uuÝž=‡† ÷áCr 1tèyþAA!Õº~=,""òó étÏÒÒ¯á«rsóËËYÉÅŠµÈ‡ÔÔôÇ#ŸÝÝ—½yó®ù5(‹ýýO …÷ñÙ˜›[¿Ã|i)£°°†7TPPÈîÝÑ.ˆò£Èû³X,ööþ_½ÇìÝë7|øø„„Ä&_¥Q«!µµµ×Jܳgkõ¯ëׯÆãqb±¨ …055©›?ŸÏ'‘HÐ¥‹^­cÂÂîöêÕcðàßÍ¿¼œý¥*%U‘*NŸ>Ò"íTQÁMIIGÊv×Ë˽îa¯^űX¬Y³¾.^œ9s*ÚËQš€¼?ËdÀbÕvíÚ•A$·®h(--»té* 2ÐÈÈBCï?~ÆÕuÔÊ•^õžóúÈ‘e2Œã4gŽ[ùçç ù5LWW§¼œuðà‘ÏŸ³€FS7ÎþüsçÍ›·oÝ 266€C‡Ž]ºtU]]M[[kïÞízz: äïê:êÞ½WW§={ž9s N:xÙÇgù¯¿Ž€ÄĤÇOTVò o_ûU«¼æÏ_röì1äôêŸÃÍ›á?-+c€¥¥™·÷²ÐÐðÓ§/ˆDÂð𾾫{ôè–““·aÃ66›sóæE …û÷û'%¥€††ÚŠžïß'EFF—•1ÀÒÒ|Íš¥©©ŸŽ9‰4öˆC-¢£ÉÏIYy^$)ðx¼Ž$'§€––ÆÊ•^ff&µNñô\mnnš˜øœGΛ7³eD‡£ÑT€@¨:~„±úÏž½øÖ)ÇŸÙ·o;€eË~oX4àñx$YY9T*y¯_¿9fÛ¶ R©Tö%VÀêÕKÈdR#µ‰$ù|‘HÄb1°hÑŽT·¡ayúÛ·MªõîÝÅ®•ÉîÝ[|}·ðx<°²²ìÛ×}H~NÔÔhÈó"‰oÜCF²[·îF~3gF‹†k@|þ(|¾@"©•?žL&¡¥5¨ïyÄ())53Û¦h D"¡U‡D"1Ôµ$In}l Èd*PÚˆÖ~¿¾¡ÑºFAA© ¾–&ýòGWø   tt$ AƒðMÑ ¦Fk‘%F(((6Ÿ#)D((( Š”zøæ G”H„b±˜ÇP©*²&Ê,‡C×P¡ ("R©D"þ˜h “U¹ÜÒÊJ^Vv¡m/k¹“âB P””4Ð6@AQ@D"^EEñ‰† qF1´´à|LžØA³[TÔËzWQQF\°å¨©ÑŒ ÑÚGAéT ‰LúQø±z 'ži;¢k``•'¢šš:‘H***Ä`@GG@Àéëë’ÉdssË´´‘HäèèˆÖ/ Jg ß 7J++«?R©* FGG[(¨««éêꉩT¢®®¦­­ K$>~„ðð¯_=< AOP€à`èÒ† ù«<=z­y‘ÑÑðò‹^6q"XZ6+·þ,V¬€K— ?-‚7o`ð`øÖòÐê5t(ôï߬«Bq1xz‚ŠJ[´rPäåU}^¾š³6?.]KK˜8€Ã'@WæÎ­çàgÏ °¦O‡;w`ìØÖSýÁϯ곾>Ìž ­zÅ&ÎPq8,­ê¡é™L]]Zn ß‚Çãùúú²ÙìoÀb±6oÞL§ÓW¯^]RRÒÄ»|ó(((€.] ) ÊË¿J—.5¤Icˆ§¹ bnƒ“¨ª½Ù!ÞÄb@ŒDzz– ¼xßÞ¸ôôª®nm ¿ýEEͺºº:ää©­V‘ëéAj*89A^¬[׬¬h4xõ BBé™))°w/hjÖ°…„„<}ÚŠw‡Ã“SUëü÷µö›"‘H … §§ƒÄM ‡Ã€²²R#­–'NœxöìYr$<<|À€^^^'Nœhâ]ÚÙÁ˜1``ÖÖ0o^Õ‹}Ó&زàØ1xøöî…—/aËØ´ ÀÄààAˆŠªÊÄ×vìðóƒÈHøô |}!>âãÁ×|}!'JJªÿø£ê¬ÇÁ×¢£}}PW;;8&|}áÈ€­[«.÷é@AAե߼8s|}¿¾9‘»@nÄÄôô ¨8Àãz˜‘«÷ëJJUBD^QGBDDUE!r¹ú½{aaàë oßÖ¸z—.PÝáïùsðõ…GZ¥/ƒžØÙÁˆŸðú5øúÂÝ»Ÿ_Õ.¾¾UGEUžÅªqÊÊ ¥..U·öÏ?°jUUM¦¦‚¯/Wéç~~ÀãÁիЫœ= ¡¡PZúõrHgxõ |}áþýf<©X°³«j; ¤’“‹…¸8ع"#ÁÏÂÿv†Ö 2™Œ™Ë¬þ'Ÿ¤PQQáñ*¿Ô¡2âE ©TÕüü‚¢¢âŠ n~~Ac&5ètzß¾}›Pn>ŸO¯É¸qãÌÌÌê?ºG07¯ú<|8¨ªÂ©S ƒlÜ}û‚˜›ÃâÅÀbHk×ܺ&&°d 0°r%s Úööðò%Bf&˜›Ã¾}@£P(ŸaaÀçÃúõ—gÎ@ÏžàçLfcï-%ètX¶ Fðô}}ˆˆ€3gÀܼ½¡woX°`ñb°°ÔÔàúu8¬¬`QÍ w>>UïÕ¢¢*‰ó-Øl Óá·ßÀØ44à÷ßA$ 6m‚éÓ!'§ª¢**`ùrPR‰tu!!þø`θzž=«WppooÈÉiépý:Ðé°n,X"ÌŸàë 0™på °r%0°d 88€D¬][u7ÖÈMK vì€K—ªÄÂÆÐ³'ÄÄÀÓ§pâDEÁŠ ¬ NNpç €šZíΰp!88ÀºužÞô»;ž=ƒÇÁÇ ÁÔRR [··ÙÙŸîÞ…èhظ ´e¶/ÿæ D«mÏîÆãñ ¶¡¡žL&Óì®þE; q¹_dñk”H$YYYùùU»0H$ óÝÕMœ×$“ÉÕS¦NmtøöE‹ÀË Þ¿‡òrÐЀ)S`êTxô¶n –/øõW˜2¢¢@*&üüJéôòQ£@]¹CPV °Xøßÿ6o"”•ÁÛp8Xµ Äb`0@(WWh¼Û¬µ5Bf&Ì›Wu¡U«`à@ˆ‰ssX²f̨ìp¹`l ¦¦x<üþ;Œ OžÔÈÍÛ&N„ÏŸáܹªâ5Œª*“ sçƒååpäðù°q#hkW‰¤ˆÉ ¼„‘#áøq˜2æÏ77¸u *+ϯ'g©F77HL±¸UDÃäɰu+¼x‡³38:‚›dd /4X½tt€N©d20Þ¾…²2(/ªÚQΠA`k \.øøÀóçU‰¥¥ B`a¯_Æ ``8\U¯@þãñ ªZ£3°Xàæiiͺq.¸\ÈÈuu˜<€B%¥íØíßï>ožAr2¸¹µº’†§ ëîÈfs²² m»ÛÈd Effæl6§´´¤š~ÙÙ¹FF}ûö‰ªÞHee £¸æ×%K`Ú4èÛ·êEñ-‡É„ÔԪϯ^Á€/Ñ« +«ªÏ5 ‰Ó§• 11_Ooܰ­Jóçr!1bbê9fß>ðô,:4ÒÑqºD‚yõ ,-@=ixd+÷”õ 1cEdgC÷îUéÿþ ööpàÀžîÝ“¶nÝäèh••%Í̤œ9~ñ¢S­ cb kWHKƒ¬,HJjÝÆ%“é{• 0~|45aÁXº/CêâÕ§L½X´ˆšÚwèп‡ ¹¶hÑËÿþ<œœÀĤªEbb‹…/cj€ôtÈÊ‚Zþ¾ÌÍÁÌ ÜÝ¡[7øí78rd2V1ÂÖÖvþüùÑöêôëÍ~ú~x†¢¤¤D"ñù‚ZVIxååUÊÌË—¯ŒŒ ëD™¬MEE…P(äp8T*U…fåÊ•#GŽœÝ@‘HÔVCnÛ¶­¸¸.\اO$qçÎýû÷=z4òõèÑ£IIIºººÈm{õ ( ¤›AJJÊ‘#GÂþýûE÷;víz@&»°X’ÚÚföløí7Ø¿§§çä_=áí½qãF wÿþ}gggÅÕKKaÆ  ‚OŸ`ϸ~½[Øðáí¬¬ž?~õêÕ¸¸8ź‘ˆDz—.yyt:½Ö»q|] É&ðHžý@”§ºäæf——3«(JK™M[øøçŸõĘܰaCõ¯K›-ÿZ„W¯^õïß?>>^zÆÒ¥àãjjŸÏŸCà6n?vî„^Ê—ŸFƒ¡CÁÓœœà¯¿¥E±¸j’²^¨ÔªY.33˜?¿­Ë–š /ÖH:&út#!aŠüíç䄤·@`à×5rþÙ|Ñ€Ækh2 æÜ¼yêL¦vIIš•Z!rŠŠŠxšff~5€Ü¹s§ÖŒ@§`fPPÐÌ™?OËvx­áÆ!!!‹h}͇Dªg%µ‡‡Ö•+£®]KTMo.|=—–H±¸-JE"Õö‰ Dmþ¼ygCBÞ¾}H¯w†‚Sw˜ ¤<ŽH,*/çñùFffŸ³³¡}WëÔZ±&"Ðh-Þš"]JJJóò äò(?3vvvo«;Pt.\xæÌ…-^Zjj×®][#ç ù¥¥¥B¡ ÚŸPWW}6PPÚž¨èèÁƒ•J­¨¨hOÑÀãñðxœJMÐ}ÜPPÚOOÏãÇ·ó€¥ÓƒŠT44//¯cÇŽ)`Á´´´J[ÈQ ?Œ’’RjjêíÛ·­`ýúõ‹mß2$$$ØÚÚv¾F×ÔÔœ>}úÏÖÕÑ%OâÅ A¿LhŸ;wî¿ÿþ9r¤R;.˜­FÆ”)ÝÌÌrZ)nÒpöìÙÊÊJØ»wïÚµk÷îÝÛ¡»Vè„ *+àêÕ« æM VCECÑ*KžêpléR¹¿«‘‘—Ëe2™ "ž=êp±–ÛU{`gg‡|À`0MÞÓHÁ´j,r;耥~ttt8¯z@'T4 Ôí%HäûÌš5+99ùçé1?-†††ååå\. (ßdÍš5H¬'ƒ1uêÔµk×&$$ Õ‚‚Š”¯ÉdWWW´PgÏž!VyT4´3ïß¿·µµ9räãÇÑÚ@iwø|~K yPÑÐDLMM333³²²Œ{ôèñ¡5‚‹ÿ3fÌ–o©ÔÞèèèèé顃¬váõë×-2=ÔáEƒP(är¹\.—_ï¶(­Æ¨Q£UÛ Á`´ï“‰ÃáÄ­´ï˃Á`ùK¡PØÆíÒ´^Ôòf=ÉX¬L&{üøñû÷ïQÑðàÁŸS§Nµñ¥###G [E:t(¹ôšÒÞ IDATnÐÑŸž?þøcÍš5)))é¦/^ü¨•¶íl½zõ*,,|ýúµ±±q‹dØá—<?~üøñÖ– æàà@ WùŸ™þþªª «W³fÍzõêßá;›††ƒÁÉd—/_8p …BQÀB"Þ4::Í ¡‚ÚšF2dˆB­“sqq¹ßœ½˜›DV¯^&ÈÒ5qtt ¥P(®®®vvvcqä¦M›,X`ii9dÈgõnùÛÞLœ8qÿþý>ÈîǨhPLLL$ âÇñðáCù’á¶dìØ±wîÜQ w–´´4«/!Å §lëׯ÷ôôl1ãúT·D"„B!TTT888\¾|ù'¯“õë×;99!‡íÛ·@ppðÉ“'ïÝ»×qojçÎ}ûöE>_¼xqÖ¬YŠS6mmíµ¡¢¡%Y²dIbbbnn.N‹‹kãÅšššFFFGŽùôé“"ÔÆ¬Y³äû˜€H$âr¹...¯^½ê¸MüÛo¿Y[[äååÀªU«þùçE+äèÑ£wíÚ•Ô¼ÉQÑÐb`0˜N:5""bäÈ‘]»v½{÷nPPP› ³1Ìøñãù|¾b*,ÿýwaaa+…?nc©k™LF&“ÛwvV†ÃÕ5x„M›6|xZZ,^¼¸¬¬ÌÙÙÙÎÎÎÆÆ¦mÊ`mm-•J¯{ëçöÂÐÐðáÇ?NMMíÍ]\\œŸŸ?sæÌÓ§OWVV¶‹‡¾ˆ@ˆ‹Ýëû)((èÝ»weeešMÝS§Ã‹†ŠŠ $Æ6“Él÷ÂXYYYYYü²w“¦¦fHHȉ'V­Z¥££ƒÅ¶…ކÇãe2™D"ÁápŠÓLvvvjjjˆŒ‹Å………JJJ‰D]]]~Lii©X,n³Šj ¸\nQQ…BÑÕÕE^àeee$IEE¥•———™™I$E"‘††ÆO7 xùòåþýû÷ïßßz¯ÊŒŒ ³}ûšv®™™RÂk×®µ™xª¬¬DF EÏž=@III&“ñx¼uëÖ-Z´¨úÓ¦M?~|yÝûžèèh}}}Ñ—}ñÆàÀv,žžž\Yؽ{÷äÉ“F[ÃèÑ£÷îÝ»wï^ww÷VºDJJŠõºuM>ýìÙ³{÷lËN?uêÔQ£F)Î’^WWסÕ6ﮬ¬¤P(ÎÎΧOŸF¤ØÉ“'·mÛæææVPP€è€?~TäŽwìØ1dùÀªU«þý÷_???ooo6›4þ| …yyyYYYíU¹sçnß¾B¡tïÞÁ`üt¢AñA®z{{ssó.]º€¾¾¾‘‘ÑŠ+8ÎÓ§OKKKE.;vìX½zu{•PKKK(Ž=zÖ¬YMðÔFECÛõ$‰4zôè–]E—žžnYg§I___WW×»wïúøøôìÙS¡æ ‡ baaA§Ó­¬¬|||¨Tjvv¶D"‘‡e2YyyùþýûwìØÑŽå ³¶þ%,¬1G>|ÇEEEòD‹¥¢¢2a„ðððöº…‹/:::ª©© ¢AqÙ°aC@@@Ë:zxÕìP©TÄioooeeE§ÓCCCª*6oÞŒ˜ôÉdr×®]k-‘”H$ïÞ½1bDpp0²À4))ÉÝÝÝÝÝqôÞ¶m[XãÚæÀ+,¤4.®ba1bDxxxaa¡¹¹ù¤I“þúë/ uuu$8`YY™»»;2\jKe lmmÇ÷£ç¢“—mŠ¥¥%§ÓéÈ×9sæŒ3¦õ.7xð`DFôìÙ311±¢¢ÂÑÑñÚµkýúõ322R:±°°Ø¸q£<øŒ3|||ú÷ﯯ¯·xñâ³gÏ>þ|îܹx<þùóçd2^¾|ikkÛR^†-…ƒƒCaa¡¶¶¶¶¶vPP2Õ²páB;;» .Œ?þÅ‹QQQ"‘è÷߯×÷Dq@EC[³qãFùç¡C‡^¸p¡OŸ>X,ö·ß~C<ùÄbqEEFk¾ïÖ€äÏÛŒ3fÏž““sáÂ…·oß®Y³FII©²²R®b´NNNÁÁÁò K"‘xñâE$*/@˜:u*N_´hâÿ~ðàÁóçÏ>|XII鯿þš0aBHHˆH$[·níÖ­ÛÒ¥KÇŒãä䤬¬Üö÷²|ùò¿þú«êÑú²fyÙ²e+W®ÔÐÐ2dÈ”)Sf̘0dÈóçÏ;99ÑéôsçÎåääøúú"+îQÑÐÂH$¹ fæÌ™}²°°HHHxðàAŸ>}…ÇãÉÇ;r õôô„B!b wrr"‘H@ÃãÁ̬ÍÚ].fΜ‰|2dÈÉ“'‡‡™Lvvv®?é ÆÆÆ&L ÓéÈí ?™˜˜ÌŸ??))éêÕ«,kÉ’%–––ò>ÖzåÇb±sçÎE”¦k×®mÚ´I___SSS.÷ìÙƒL‚È›ƒÅbyzzþ÷ß3gÎtqqc0𥴨h¨B,_ºt©zJJJ ‹0`›Íމ‰sçÎÕÓÓëÝ»wïÞ½SSSÉdš››×̓Á”””ÔÊ!==½ "Fëéé!ý;vL(ÖZ(µuëV©TúáÇ ˜™™ÀÇ¡©š³……¢¹°Ùì~ýú!8—Ë­ëfii)•J±X¬‡‡Ç“'OÆÇb±ª2¡Ñ`ÕªvéYYY¥¥¥rðìÙ³òŸŠŠŠy¤¢ 9šðððÀÀÀ©S§Êûƒ¹té’L&377Ç`0±±±ò­CåK˜Zƒk×®ÉÕ#GŽ Þ½{÷öíÛ9sætíÚõÝ»wyyy ÅÍÍíõë×HQãââd2™³³sYYÙ¥K—¤X,lÚ„Š†‰Ä?ÿü³zJXXXPPNWUU0`•J-))ALßûöí£Óé Gd"“ÉÈ4u]îÞ½[vþ|«ÞÎÇ™LfDD„““SAAÁ7ºuëF$‘Å3rä_õõõ‘—<›Í†Î*“É^¼xQYYéââ2vìX$±²²òº:S:::ÅÅÅ+W®D¤›šš"Öz+7´——×ü!¬ZµjõêÕˆXÌÎÎ^»ví©S§zôèqñâÅààà‘#Göë×ïÙ³gT*ÕÆÆfÀ€6lÀãñzzzK–,Ar ÓéžžžrÕ€B¡èëë#‹UUUµ´´ä—¦ïßßRnFF"ˆå„„„$%%­X±‚F£yyy!ÚÄ“'OV¬X±mÛ6™Læáá1zô謬¬’’¤Ý‘â1™L"ÏV«ùNekÀãñ®Ø¯_¿~ôè•J1cFDD„¾¾~KÝE||<‹íÝ»7ò5##cïÞ½û÷ï¿xñ¢P(tuuýóÏ?×®]«¡¡ÐpVˆG‰DªîõÐ$&&òù|yL„ììì'Nøøø¨ªªÆÆÆª©©Mš4)44ÔÄÄ$**êôéÓ»víú÷ß“’’rsscccÇ_TT„¬˜Z¼xq­¥SõÖ­²²r½ºd‹ öìÙsâÄ Dï6l˜ŽŽN¯^½ôõõ#"">|hmmýîÝ;Xºt©¥¥åüùóåe®[ªÖ®ÿÎ):l6ûñãÇaaaÈc°fÍd¼Ó²>ËŸ>}"½{÷ær¹>LIIÙ³gϪU«æÌ™3|øp™LvóæMÄdÐŽ–ã°°°W¯^Í;·[·nˆ,xüø1"ÒÓÓ-Z¤©©Ù­[·M›6ýþûïGµ±±‰‹‹ûßÿþçáá±lÙ22™¬§§‡œˆøk #ù¶¼G…‡‡ï«éqóöíÛ·oß>þ<::z„ ñññ÷îÝëÝ»÷´iÓöìÙ£¬¬\Ý£LA–¢¢¡M‰D2™ìÎ;÷ïß9räáÇ‘YúÖ3Ö9r„L&‡„„¸¸¸,]ºTEEy}!c×ö’ Ë–-›4i’³³³@ 8räÈ®]».^¼¸mÛ6 õöí[$Bppð¤I“lmm%ÉîÝ»9‚ÃáÂÒ¥KïÝ»‡Ì5 :´ºwF»pøðá+VÀ¡C‡LMM¥R©T*•Çþ÷÷÷÷òòâóùB¡PIIÉÝÝ=44ÔÞÞž@ g)¨Ž>®mù†1b„@ ðõõ•[žšÉ€b &ÔIòäɈ#nݺ¥¡¡ñúõëõë××ë¶/oÞ¼100@¼×ÍÌÌúôésçÎÔÔTkk뜜œ{÷îÉc"«§MLL6mÚ$_A¥R§M›¦8·sóæMWW×®]»Òh´®]»ÆÆÆ†‡‡§¤¤P©TPSSsww6lذaì­­ útlPXXÈb±K£¢A …EEE»wï;v¬žž^ vëéÓ§Ó&ÔTL wìØqêÔ)*•êîî~ýúu…’ §OŸÞ¹sçåË—“ɬJyýb±ØZŠúôéÓ«W/Ål_‹UPPehhˆ¬þFô…¿ÿþ»úbM???ùš…6 åràÀoooTkP8þ÷¿ÿ9R$mÙ²¥µ/—žžÞ½{wdÇ=$EnÒk_nݺõ믿@ffæÈ‘#ÇŒs÷îÝ7n vÁÁƒGGG§§§Ï™3§î¹mf{«ŽÍš5Éݺ}7>×®]»?~|óæÍ_ýUSS388X]]½Ö"îv 2¾zõêÀÀÀ‚‚}}ý=·Ã»W¼yóæÍ›7í+Õßßñª®/¼yóæßÿ½|ùòÇÛF{ܵkWºB«rçÎeË–!rÇNš4iÓ¦MÈŒ=Œ92""¢OŸ>mÿjý½6o~ÿÅœYï yïÞ½Ègssó¬¬,‰Dd0ŠPÿÅÅŪªªoÞ¼ùÖ¬|'ײ²²^¼xÍŒŸÛ|JJJ`óÕÅÖúõë.\¨¡¡Ñf;k>}º-gpÇ9nfö]Ǿ—/_"oQ¡PˆÁ`iùƒ^¸pA~LõϊϹsç ) F›1c†ŸŸŸ——Ô\|ÕŽ\¼xqàÀ}úôiZ´Ž/‘·qXXعsçZã£FZRT4§GΙ3'88qjÌÍÍ]·nÝ7ÚÅϧÍ||Èϟ?#ë”ÕÙHâ˜1c:î΀wïÞíÙ³gii)™LVQQqqq±··W•AYYÙÕÕµið¡ñ¾‘Hjk7æÈ—/_Þ¾}[®BÛÛÛ·±\¸wï^«zy7‡yóæ^¼xqöìÙòDĆß9ÐÖÖV¿Iccã»wïj7®÷¢¢¡UHKKÃápˆÃ DGG@¿=zôúõëAƒ)B…ìß¿Yá/^¼8p`ß¾}åî ƒ·uBl)ÈPâüùóYYYÍq2FECK²bÅ ±Xìæææîî.‰u[><Ϭ ý Fîž|òäÉß~û x<žbî.ý£7Åçó‘µjÁÁÁnnnŠVH¡PX¯{1*ÚþýûøðA$­]»öíÛ·m3%!GCC£}ƒ)Ö¢îηÿþûïâÅ‹;tߺu+99ùÊ•+Ó§Od#…‘År"""<<<†ŽŠ†öGþbƒz'ç6æÏŸ_ÝVÃáºwïÞѵ†ää丸8¹,V¨µdÕñðð˜4i*Ú‡d*ª¯*Ù½{7@hÚ¾ ]]Ý¢¢¢OŸ>™ššâp8UUÕ>(ì¢Æ&°`Á‚7n(Z©äÍÏ> ÈÊÊŠŒŒŒŒŒLLLlãK‡‡‡K$±X¼iÓ¦  ‰VVV8Ç;•žHu ½ê::aaa¿üò *€Á`¤¥¥¥¥¥åçç·ýÕO:UQQñâÅ ùËpÍš5]gn) ***:âFu €Äæþš¯Ã‹{{ûÅ‹/^¼ØÅÅ¥-¯[RR¢©©ùôéÓ·oßΞ=‰øŠR @””djjÚinÊÐÐ077·¨¨HWWW¡ V^^>uêÔê{äü좡½HLL´±±ùðáÃÚµkÛ>³b"‹‘xŠ2™ ‰%I"‘bbbä[‡wH$RjjªØlv›9Îþ˜Î/÷³°@<ÀÙÙùÊ•+-åâ…Š†FañéS»Çƒ@i/X,ÖǼóçÏ¿wï: hS6oÞ¼uëV´~NZÉÙ¿e¹páBË®ÁíðfÈ´´4d ³ÎäÕ×Ù°aÃÉ“'333;ß­=xð@AüYÛ’¯5…B.—Ëår‘ðä(íÇ2dˆÜ¿¥] -µð´Ãk =zô@¶‡UVVn¾#jGÄ2((]1â´;999¨ÖÐÖH$@€|®îgÙî Z½úùóç‡jÕÝn~ˆ={ö(Z(´&@æóùŠ_β²²‰'VTT ŠvƒÁ 6,22266¶¸¸¸z€CÁÚÚZq–””üñǽÑ]îß¿¯x±ê"lll®_¿Þ²Ù¢«!ŒgÏžt„7I›A$±Xlç6ôèéé)++þüù§jYTkøa6n܈VBõdžB¡dddtâ{Dl{?› ? ‡ó÷÷Gëá[´T(Eãýû÷Õ·áCEJ <8bÄ´¾E'ˆ [§OŸ"AE"‹ýybÒtøûLLL¼téÒ¥K—"##[õB¦¦¦Èzuuõ9sæ ñZªÃ`0”••I$’££ãË—/;Ó­¥¦¦".­rWT4t H$F£Ñh­½ÌСCŸ>}*•Jq8ܬY³~Ų1dddhiiQ©Ô%K–;v¬SÞãýû÷›ˆµcÑág(¬¬¬¡.•J[ûZ%%% ƒàÁƒÎÎΨ„jU¦M›f¦s™ÑÑÑ­ˆµ5tΟ?/ß8«]¨>¡;nܸt²ÖÐÐPØX^¡¡¡&L@EŠ"²nÝ:äƒñôôTUUíd7èééiiiùSµiû(>þlllŒÇ³$III CIIÉÁÁ} Óo0”ŸN4dffNœ8122ò[V½ØØØ'Ož¨ªªòùü¢¢"ts”¶¡áááC‡mà€ôôô=zxzzººº¾yó¦}K{òäI´ÇÔK_ÔõÕtuõÉd²ê‰ŠÒçÏéR©T¾Ñ[­„B¡X,F>“Éd,»téÒU«Vu”ÊÒÕÕ•ïR…Rooo&“Ù)o ‰šŠ†ï#‘Hrs³‚ëÉù|¦š”ô19ùcµagís¯\¹òôéSäóÚµk;œ]‡D"u²èé-…½½}·nÝ:ß} ‚ØØXT4|ŸÒÒ»ê¢!;;ÇÆ¦›T*íÖ­›µµõ—:b0XIõsç̙ӘðuÊÊÊ [¹ù|~­ˆ ¹¹¹"‘hذa­ROÓ§C+åÜlÊ—.…Í›Ûmíöôé9\»vMII©³=ݺ}16LQ›p¸"_ßÒ.¡ŸŸ_«‹øüù“‰‰Iy9*+yd2)‡Ã’Ë‚””4}ýïïü{àÀY³f!Áš`̘1t:ý÷߀=zܼy3>>^&“ 2D~"™L ¬žUrròùóçkåóæÍ‰'6³þoÞ¼9‘Á€òrh†í===] Èï±i¤¥¥‰D¢îÝ»×HÍȘðë¯`kÛ¬LšV-'BV@SS‹4P(Œˆˆh¦‰Z <~üx̘1Õ¼a¯^Á,gàóù‘‘‘®®®Í¼£ØØXƒ.]º|ÿÐaúthpëÀ¦m,ØÑ ‹Ùl6‹•J¥ƒÁ  .—K¥*K¥&³\$7&+äuW½nܸ!dkk«®®Îår‰D¢¹¹yYÙØØìر£VbVVVÝÄ%++kGZdgƒ 4ueQxx8‹Åš5kVsJrûö튊Š3fÔHÕÓ,„ÆE—¹uëÇssskjÙ±†‡ädغœœšžI󨨨àp8Í̇ÍfWVVÖÈ$4¶oGGøûohÜvDååå ùwäçç7pàÀïï9$‘½{ÃîÝ`hزISì+R©T$!¡¼œ…Ãáäc "‘\ZÊÌÉÉ¥RU“•¹¹¹Mõკ™Yõ¹L###›†åB[Àb§'ܼ©ˆŠeAŒ?¶ÏÕËÊ`ölhe÷¶öA&ƒ€X³F¡ ùîLž -a¨‰¦Wƒ¡¢¢š–öII©†â§Oé\n…ŠŠJgê_ý…*+aÖ,¸p¡ ™Œ=zÊ”)Í,‰³³ó7=|RR`ôèÆHWW׿ëð5ªŠ‹aüxxò¤Y™4eeå}ûö53*•ú÷ß×ÿÛéÓàî¾H£ÑvïÞÝ}ôõk3Z4 N&/u ˆŒ †I&“¶IKKµ¶®1|ÅÔ¢è˜Ôt<,_TêÚˆDbóKòLòóaʸ}Ô°Z¤$µ«¸\˜3‚ƒaðà¦gÒ$0LóýnÊD*…3g@Yüü Á^Ý"%i" 0u*Òä7&(l¼ hÇ?Ìü7ž|•Å·õqqqi¤ªS¤« Ê\® 2ÞÑÖ†jA†ÄbqYYò™L&ÿÐG4x{{>|Æ·ßäqqqW¯^‰D›6mRkŽÒ¥¥—/èQŠX póf‹«‹™\½ ={vNѰ~=4{ê¡e »wïÉÚµ RQ±Üß_«G¸y³údJZZš‡‡â#Ÿ——wéÒ¥ŸN4œ;w®á0L&388xóæÍÍ]™£¥çÏ+¨\èÙBCÁÀ }®®§ׯCïÞP(ðûï°i“¢•+úñã}û÷ÀßëÖÌ™£µaC­IV33³«W¯êêêæççÿ誧N²8|Þ¼y /Ô•H$"‘èÔ©S¾¾¾,«éãˆË—¡Ù ZZ;;¸y³Ýä‚ܺÕ9å¬\ ;w‚Âl&g×®]ÀVU­;VïÐ!ÐÑ©u™LÖÕÕ€-[¶lÙ²¥uEƒÅáuÿ>âîÝ» X±bE7’ÐÓƒÕºuƒ‡¡½–~˜˜@Xôí ?~€’’’íÛ·w¡€Å–-ð×_ [À}}¿k×¼GŒÐþö1åååT*õGÄ~X4àp,–€Á`«ÿ—1™__Å©©é+W®ûï¿‹ U‰cÆŒéß¿¿AS´ ‚‚ ‘Æ¡6¦G …&´[MM ;;äÛÎ;@EEÅU1u«eÉؼH$Å,‡;|ù²»“SÃÖÅ„„›´nŠ­A"I¥¢ê) F‰’’’šZÕŠÆC‡Ž:´+4ô΃ù¥-bþÄÇÇGEE sssùòÒõë×'&&Þ¾}455GuòäIÖïÉ3g¯¨v™{÷Ú³lÁÁò«'$$DGGÓét>ŸoaaqîÜ9‡S^^nllüàÁwþüyKKËC‡¥¦¦ÚÚÚz{{ãñ líúåøåE\‹ÜÝ]Æ‹ ¾}ûöÚµk{öì ‹-‹ÅgÏžmfæ­Ò0R©”H$ìˆÇãÚ¦ŽðxüàÁƒñõ’ 8Η·>æ—_~yúô)‹ˆãQÎIIDATÅZ±bE. ¸¤}ËVíê¶¶¶ƒ ,**Ú»w¯§§çþýû9²`Á‚sçÎUTTœ9sfùòå!!!½zõ:þüÒ¥KZ4(|˜†+VäççÀ´iÓŒ‘Äå˗׊–Ò£G“v Lfùµk¡ééŸO:·páÜ6‹Ñ«W¯ºº@]7GÅõ®í¤tïÞÝÐÐÐØØØÞÞ¾¢¢âÆ0uêÔN°¶"ЧOŸ>}úÔJ´··¯3æÓlª~tÉd’­mOuu5[Ûžf¡4JãÑÕÕMOOÏÈÈ(//ÏÉÉ)++ãp8l6»¸¸¸¸¸˜ÅbI¥Ò«W¯¾|ù2==ýèÑ£h)®2Ú²ÙQ(”~ý455úõC£?ÿŒìÝ»wëÖ­`hhøêÕ+díž={¾xñB(š™™Q©ÔC‡ݽ{6lØ€ÖX§ ååå|~eõ6›S})‘¹¹)Z³?' ¦îü¹mÍ03#GŽD몳‰©TÌd2¹\n-eA>=ëÖ­Bkåg C´âPPPÑÐ|dhE£ ($²v G à -€‚‚j õ#‘H*++ÑGAQ°Xœ²²’Bˆ†üü‚›7ÃUTj„ÇÒÕíÂår**:›Z¡©©M¡(â¾ L&ƒËE•¸Ÿ ==‡ÅåÖˆmimm=p`_…  ©©‰lNA H$’®®^y9#=kjjÒÉÃÆ¦‡XÌW<¹PÎá”w¾ÚFi˜Þ½˜Ìb †P\\ÄãUiî½zõV”…="O$Äb@ àñxêêj¬1d2‰„ŠV*>ŸÇãñÕÕчåçB&“a0±±±‹Åb2ËkmLYÿˆ£-‹¨¤¤dcÓMI‰ˆÃa$1Úf((mûn¨$“‰úúº4šºT*Q Ñ€Ãáß½{Wï&Ú(((m£Aðx¼ääß} x@ÁfsJJJë¦ëëëÕÚ®¦.[__7&æµ……™ŠŠ ²‡ JÛPRRÊfsD"±¾¾Þwƒªÿ°h(((Ìg++ӾƛâVp†Û¼y}#sÐÓÓe0˜NP(äNÚ 2@ he Eèãñ"•JÅbqRR2‰D"“ÉŒ‘Ñ3$U³‹šv••» 7sӥ˖S(‰ä;=OMM­K—‹¬srò¬¬¬i4ÕNÖd2åÝ»|,X×®ÖªªTôiù©‰$l6¯[·áK¾+ š"Rã˜æ³ùCS‹užS˜¥%c&Í(€ŒŒ¬˜˜×3gN€ÇŸQ(dGÇ~_L ‚‡Çļ–çC"‘ðxB­éV”&£¤¤ÔA“8jêÐàpxee¥Zíhee1gδ ¯£?&¼ö]2MW߈ÇåúÞ•ÿÄãñ‹‹K23³Y,6“Y.)W×j0 “«bWc0‡+‘ÑÆk…ÂÅ—…|´n;4ÚÚ:={öJJJäñxl6IìÛ·oËk SéKhÚÆþ»}K‹ kÞµ@™ÈììÜÜÜ ‹«°XŒ›ÛdäÈÅ‹ç×:÷óçtM‡Ã‰Dâ.]ô°X,ÚN((mƒL&“H$99yœüaÑ ¢¢M¶"ûDHÄôôÏZZšb1º\º%m ¹¹y-›'—ËÕÖÖDë¶£Ãd–—ÂZ®Ï-< h²Pppp°±±‘§…Âw %J#QVV9Ò©²UBÍ<ž ‹ml¬«·#òŽWÑ`nnŠFšnm¬­ÑJ@iòmíT 8VI‰ŒwDA鈈1Ò\b™@öuø/â Mez*xJÓEWÊÊÊÊ2™­e”‡ #Ë’æf‰²ä)yIyÓµÆYê›5E40L. ∂Òñ!b ÎÎEÅ%$1±zв²’††ú÷EƒÇ`ˆh­¢ t|­¡û1µp ß(­A]ª®Ž:ç¡ txDXÉgÈ©•¨££f¨¯Ýt[ƒý¦¬d2jIAéĈ…b!OXýk#Oü¦hPVÖ":ÿŠ€SYÉ@;J§+ê摨Y_ý¨`ª¦Bk–h@AAéèàd˜~†¶ý m›pîwDÑ#G²³³‘ÏÛ¶mk¤[Ô_ýÅf³wî܉ğó÷÷ÏÉɀɓ';::¶qí\¾|ùÍ›7îîîÖÖÖEEE²5Ÿ t&ðxSO E‘¨²“]ô‡ECTTÔþýû‘Ï>>>þþþÉtñâÅ«V­’J¥ˆhˆŽŽF2¹~ý:‰D²··o³Û‹ŒŒäp8«V­Ú²eˉ'¶lÙòÇ ?y{{>|íý( )äXBÝòÅ‹WŽŽ}í¢¹¹y;vìÃb1Gh™b|O€á»|ÅbÀÓ§OÝÝÝÝÝÝ·mÛ†sâÄ $åòåËHŠ®®®’’RÝL–-[vàÀ¡PxöìÙÒÒRww÷íÛ·@BBBLL ”——_¹r‚ƒƒÝÝÝ£££/^œî_ ëwî @¸zõêS‚€D"uéÒeîܹ0kÖ,¤$÷ïߟ‡/)¨½¡®®n``à•+WÈd²’’’@ xôè‘»»;°X¬±cÇŠD¢£G¾~ý’’’œsc ÆËË‹@ ØØØèêê~üø±î1A&“$ZÔŒ3ë@½¾}ûúùùݾ}œõõõÙl6™Læóùr‰D"¹xñ¢‘‘‘““Ú§QZ„°°{Ë—ÿ¦££ Ÿ>e ÝìK“"þGX,vݺUêêjññ >177íÙ³ûæÍ¾™™Ý„À%R©´OûÕ«—€——w½¢aÈ}ûÚ@LLÜÓ§ÏÕÔTå:EÝlfÍø2>§äÿí_H[WÇæÆ‰1y‰¦•Iþ̆ÕKe #«XH6œ`|ˆ´ƒB” ”:d„öAÆ^"EæZ˜¤H‡t‹­lJ‹bK!8D¯!Úk¼ôÆ&¹{¸#Ëlb¢ë`âùóäÛ·£:(%ppp@’A†aUƒAÇó<˲׮uÀ͛߀\.ßÞ~¬ŽŒü”Kê¼%~éEô§8Š«\-³ã­JJÊБ'Ä'?_>?xx¯­‘--Ÿ¥– ßeYZZ>7t;;‘;wF+*Î/,J>ß©Eañø0iUÊßõúÚAÏÔc¹‹¸öÏ·4T0\ ~3,F! ¦ êÑ•¡JÓM€›Ã¦Çû—\Dvöy• VW-a€ݦ͂1@ÂhÎfàa0ãfÐM„ a@€0„ €Ñ uÓ‡Ú›A\¹yÐÖçLänX™[æÊòÀƒÂà¶¶ÒÒrí÷SÚ¨jnäÐkå…Ü\”þó“Êû'u3žØí±NÖéÈo qä†ÁÆ ŽnîXó“åµË ƒš.ÄÙåïpÑÑ žrÖé½ë$ aàK†¸ñ* 2„0e˜ÍöÁš}­Õã½öñß·üB®€lµ<\ ‚ؾÖêñžû¸n*ª3Œ³ TTŽ„k(Ä*†õ±ÜãÛ×§ÊîØûÔ~nîý)óyóÊ›õØþ»ŒÍýDÝ~¹Üã%ÕHî³J>wôÿKm|E˜Ýï;>šyšjèW¾çÜ´ø§ôåSa™Ú×Z=Þsÿ¼ig­Ù„Àwþ'µ¿ElÇ9r¡v×¶¦žkñxÏ}üc—æjµ¶Ý1Sƒû#Yìï’¼ävN«¹ Ü]^÷,åíÎç9›€ÐAe¨ €Å­=÷aš{šIEND®B`‚snd-16.1/pix/selpop.png0000644000076400007640000013726611532170777013174 0ustar bilbil‰PNG  IHDR!ˆÙx«sBITÛáOàtEXtSoftwaregnome-screenshotï¿> IDATxœìw|ÇÙÇŸÙë]½œzïTQ$* ½wcpÇÄ%®qKâ88.`ìØw\°1Ó;ˆÞ{H¨÷ÞO×·ÌûÇJÇ!N'.y÷û!ñîÞ̳3§½Ùß>Ï3³} €ùø…ß»ÿ#œyý`É®óÙíµ~ßÖppppppppüoàÚ5íÿ=V³öã?^¹r¥‡‡‡ƒ†dýú¾u䣽­†§ü.-´k,Ô¡±***6lØðæ›o:®±,u98888888î ¬ö r¼øÅ³GçïT±ƒÎ«MMM—/_¦(**** ÀfNcqpüORrÜ…çôbÝ;_´ü|/vníó¨ß¨_õßæïú¨i}O_u–ƒƒã~!ÐjZ)k& ãv}òÛWì [e0<(‰ú÷ïÏãñ¾ýöÛI“&EGGwµËi,Žÿa¤?šEBÒœ*¸k $¿˜ÅfÒ4öîíüÜ{g988îÌ8ZºCñX*ŽŸ0Á~¥½{öØ©¸wÏž®UndUÑB‡Æ¢î8j4¿ûî»°°°ÔÔT“&MZ·nÝòåËÙ]k:Õåààø·ÿWvñ¼Áz¯v¤W€§F†Hl·ôïD_u–ƒƒã>1`5Ü®O®È–é®âø öìÞe]~ÂÄI¶+v`ÛuôèÑ¡C‡8Т¨ÂÂÂt:]YYYPÐíØ$ÆØd2q~,Ž? ó]§<ëõPˆ8€Æt¹¹zOË‘V|Yýöù ÕTí+ôšìô}ì,§±88þ``è… ` !¿ÛwíØÞ]•IS¦bV+uSqÒ”©0qòdË6{¼Ã‰u»¢…rÞ­ILLôòòúâ‹/f̘áíí}æÌ™òòò9sæ¼|õcG:ÌÁÁñ›¤ðC€ŠÊ‹—¾ô¤^lÔR/Q3M"Ÿ3åÑ™b7ñõM|ARý¹\>4a¼úþëwl;:ýë·>·D4ä·ºy¬:¿’§åÔ6òöCaœöÅ 1éñó¿4¾ ˆûÛYNcqpüáÀ;æÇ€¡Ã«dUÑ~uŒqw`çöm“§N‹ÀÚ¹}ÛmƒÖ;è…Æ€àààÇüÔ©SÍÍÍQQQiiiŽ×åààøÍ¸Öœ­' Á~A7\«h®ºZ•õýù Õ·šù í>BKc n1´º+Ü2E\[{ Ò®Ã{P„è0>k"M"¨½ ›*wí<²wƒFN<¸óq­¿$ŠÝØ{t!º*Ï­m­óTyÄùÅìÜyF:rëDB¿á0êc€†0iPºÇ¨Âêbá™.²¶r³ñÖþ‚ÃãBÓÞõG+ R@NÁ­}Ç@XÇÜä Ð³Æ"ä.u€oýÉxÙÕ¹ÝU¤Ãx{³3ÇGYûÞ—gòÏS"¦¿wŒ«Ô%úåx£'ë™î1ЍbÇÉà }ßYnXãàø£ÁþB1ÆÓgα_rëæ_Bí?dKEp «»Š–“nÝü Æxëæ_Ø#ÓfÌÞºù°®h¡³Æ¢.áÉŽ÷™ó¹ÁˆƒãF}[áâãqòÈ~14C]/Ìúï—««êªP° 0²»#ÆðøÞçWüGbÿáÃãW­ÿøÕY/8+,%Ùy…@b~C„‚Ù÷ŽºOœååëNMœ¦mikÞzrû»kÞ£D4á&b¥Ëç?~é«ö”6±¾©þ£µŸ:u˜ˆ3bl§â_N¼úìÜi#&'F 7‘¦‚ê¢õg6Ïj˜¹L =æç1Í‘‡üûº³Ü°ÆÁñ‡Ä‘œwŒ1„îL«r,çÝVųæ²Û[~Ýh±°å×ìñé3çlùuc׊À:Âæã¯?ÀîïH9VÑfì±¼e¢éÇS/ÏÁÁñÛ€š@xÈ­46c@2‚‚߆?@Ï !/$ݰp­ ˜ÝEZŒÎq3„B„8ß$ 0ϧ\@pŒD7ÌHJ ‘RcXç¡JPƒˆKf\C!ƒˆpå£`£S0~g=ƒ‚„`dp-  „H-0û­Àv* êï’™©!‘cŒg> š¢±` J)på£D‘YÞ÷åààøCqiÔvß ÚªÒ³çÙ/¹eÓPT˜wsrÉs}Xq˦ ]«X>²®’›¨ä?×{7¯°+MF’{àãàø#"!AZLP€1 F´”.%4 ÄX9Ò`v—ò~Š”×ŠL #Œ# VÈS‹ÀŒ».” æ ò[„È "€’åŽeuFðÌ( ®˜"íU¤\0 òØÀFˆ*æ…! 0ÃàûÒYŽ?¬SšøÕ–Ö±†öÐ]Gȯo*ÚL¢ºý‘UE ÷ª±ä7qpü1!pê|‘@º`p¹½kva,»@¥b(•u l)IK0ís{·+Œ›¥wA sÇ­sN-Fº«´ÓW< €’cJŽ-…û¼³@D"±ƒ%ÑŠç·¯]5–‹Xààú^íå%n0âààààà฿ téÜ‘ÞïÐ6¿}E˘_8þñÇ­pppppppppt‡ Ö:‹[pƒƒƒƒƒƒƒ£ï¸#VHdK3óÏæppppppppü9 ÆŒ¹¿Õ®±x%™ùfóÅß§]f„ÂøÀ¡ý,»í‹ n¿`U ü[7ŠƒƒƒƒƒƒƒãÏŒN÷t*ö}9~,ïÎ’­¿qË88888888þ찂ʾÆâàààààààà謠"I8ÅÁÁÁÁÁÁÁÑWX *ÂrèîdVJÊÄ•+?éºý —«=y_Ïû÷èùsµ–ƒƒƒƒƒãɽÜO­U/4Ö´i r²üóõ€ŒŒ1±±Qw×O„“ý®Z·aäÈŒ>úÌñsMœ8gΜ%¾ôÒß  ÷§wÝ‘››?gÎ7·`±Ø3..aõê/{|»x§Îþ–­åàààààøã3mÚ‚%Kž´>²tés3ïß­•%VHt_þ6“'g¼õÖëì¶P(€W^yî>´ðŽ€·Â÷҆ŋç/^üdKK«“SûKËhš^¿~Ó‹/>s–{ÅÍ›·FŒ›””¸yó:WW—cÇN¾öÚ[7oÞúì³UŽùÍZËÁÁÁÁÁÁakAÕ»X¡‹‹ó€qì¿èèHèÞŸFQÔk¯½åã)y 6úܹÞ-»e}¢âÜÝÝ µU3kÖƒ‰WHÈ€mÛv[ [ÚðÀŸ:uö¹ç^EÈÉË+Ü‘M™2^,mÚ´ÍräСcuu ÎîÔ;›=ÚºuWpp¶À÷ßÿŒÓ‡€$I™ÌûÌ™óö÷é§_Š‹‹Þ¾}}ròˆØØ¨¿üå± Ö~þùÚ“'Ï@||Ê«¯þkܸ~~Ñ!!¶oßc³³Ö­Õéô>ú´³s€Læ=}úªªöx||Ê›o¾;}úBW× ÿ˜-[v²ÇüqcXØ >ßÕÕ5hþüGl6ÇŸG´ŠÍ[°î2VØ+žþõ£GOnÙòc^Þ¥éÓ'?«±±ém>öØ3……ÅgÏfnÛ¶~åÊOL&s§?þøåˆÃ?üðŒ[jjò±)‹çÎñÃ?[ŽüðÆŒŒ1îŽôhäÈáÅÅ¥••ÕpâÄiWW—'ÎÀåË×0ƃp¤ GŽœxê©Ç­W)?>=""ì—_¶²»Ÿ~úÕ¿ÿýzyyöêÕ+æÍ{877ß~g{ì™Ó§ÏïÛ·ùüù#­­š)SæY"kÖ|ýÊ+Ï56¿óÎ?/^ÚÖ¦­©©}è¡¿üã/—•Ý~`_9Þ†††¯[·áÿøÛæÍ;D"Ñ”)ã;•±Ó£¤¤„'Τ¥ª­­[¶ìÑwßýÐl6Ÿ8q:))±OšÇmÙŽ‹‹ÎÎεS877Ÿa˜„„¡ì®¯¯ÚÏÏ';;—=`)©R)[[5£F%Ž1,,lÐĉãÒÓSgÍš*•Jú°ñ¿ÅÛo¯lkÓBo´J¯nÁÖâ¤w‹M“ê±»¼i[[¥\.sĬƒ'"ÂÒξ n>øà¼~Øðümݺ sçΉD ØéQRRÂ{ï}tüøéÄÄa®®.¡¡ÁçÎ]:uêÜSO=îàÙCB‚àæÍœN³³²²ÇÍn[;íØ•Íz¡îŽßñƘ ˆÃ‡w>|<3óè¿ÿýþÛo¯¼|ù¸L&u°ýX:) WWVc9®Uzu ¶¹>áàÔBGˆŽŽäóùû÷ê+ƒ†1¶Aóó ÍæÎùXÀã=.yЕE‹æmÚ´íÈ‘‹ÏïZÀN’’³³s·mÛ=jT"»ûÅß¶´´ZÜH=âææšœ¤W= ô÷ññÞ¸q LJJذaóÀýzåÃûä“ׯߜ:uÁñã§oÞ¼µfÍ×óæ=¼téÃ#Gg dfýæ›u••Õï½÷ÑÅ‹WØ”©î:ëææ:wŸ~éÂ…Ë7oÞZ¼xé Aý-aÖ®\¼xeÕªOsrr«ªj~ùe+ÆØ:žÈÁÁÁÁÁñ¿‡ãZÅæ-¸;~‹y…«V½½lÙ#Ï=÷jPP¿ f»¹¹:^}çÎ}&Yþ­Xñ_øê«ÀÏ/fÀ€¤1cRlæ ½ôÒ399¹¾¾ÑÑÑÃzÕàÅ‹´´´vÍvw¤GII‰`èÐAì6MÓII ½:{\\ôÙ³™b±hÚ´ƒZ³æëåËßX³æK^xjûöÝ¡¡?ÿ|íÆßFF†Ûïì—_þwذø±c§šªPÈwìØ`S’²Èå²Ý»÷'$¤ûûǬ\ùÉO?}Ø«öspppppüépP«Ø¼w‡µ B0¿ ÿ¥¶ÏýÉl¾( h½}á¸KâãS–,Yàx‚GŸàø-X§Û —/ºq!\»–UòŸëí9ï÷NhŽ{ƒ¸ëy…Ýq÷k7pü.\¼xô÷nÇÿGz{ ¶©±úláŽÿŸX *ÎÅÁÁÁÁÁÁÁÑ7ô+Ôé¾ø­[ÄÁÁÁÁÁÁÁñçǞƪ«ŒøÅÁÁÁÁÁÁÁñ'§?–OìoÝ"Ž?3çÏoGæ67ÿ–Íâàààààààø€›WÈÁÁÁÁÁÁÁÑ÷ôb^¡™$ËÊk›)ŠÀcÀóù<©D"“JJ©‡› A ìËyþìô¦×¿4y<î’ã¸{~—‘ 3ôåmï]Øn6jûe<7îIGj¿xÍßWíååÞ]ܼ¢Ü¼¢)“Æôª1·r‹nåÑ4ÃîòxDLtXXH@¯ŒüOsûŶìÕñ{¶åOK/Ö --«quñlИÑ#Y!ÎÑ+z¡±jj† N2šŒ C3,˜a0!ŠB|BÜ5fÝCs¦ÄãM]ÍdîZB8ŠDýº;ýù‹ç?JR”õA±X<~܄ȈȾè Àµ'žGF—_û÷ˆÌ­½ªÛc¯ƒÂBoæ\?uöÊAq"‘ÀAËf]Y}î*]Ã…Wš{Ä3|Q·Oi÷B«±a×­Ï/UfT§ ÈCæw?ÎÂñ[²ÿlÙ™¬š«y [ßÏI½Þ,P]^YߦՙͤbB¡@!—ùù¸óù=,˜×·ó ËõªÑ´å èa³ŒV«;~òÒ„ŒÉ"‘(ëÆõ›ÙyƒÅÙo¤½ÞpáRvjò@˜›—Ÿ_î`]{Í.(ó÷ >,­¥¥yßÝ#*ä2떖רÕAƒøh4­ÇN40ª;‰våÚ­”¤Ñ-­M7n\9bð½4øþlÝÑ\y«úÖïèôc·ùù<Îã xqµÊÊ«‡'V×ÔU†«1f:¸r5;1!Q,‘–•åÛ×XmתÎþ`Ò6 ¸I›ÜÒÚìììÂãñh𮬮hhj¼ôå|À‹î~#ròïÝ3¹5z½áüÅëEE¥eCvG„„ï'µ+ÓY%+Ǥ&vÕQã›97ŠK«ƒ¼íȬ]»N<½°°P¯×F³ÙL’$MÓ`ðàA<ð«¿FãêOW§eSãrا‹$I„E‘c3cÌ0c†aHŠdÌWIò\͘r%î/HÝŸà™›?;ËBJ¡6m=zxĈd‚ Úä Í0ŒÑhܳo·‹³‹‡‡GŸt²íV¾jFœé‚Vså:c2¢^<¶ÚïµÁdhmmõpóÐo°RátîâÕÃ8²ˆ«Y[XzzQôèmRç¸úÂïò×xÅþóºØ-Û²?õuüdÄŠÕÇß9úÀË£¾õV÷X«­­íÛï6””V2`ÒÄty—»…^oرsÿ… W}ýÔ-žë䤲cíèÑŸ§O­ÇÉf3i2™¾P(ìôlý?‰ƒ_K'š4Æw¿»<4apeyå{?\y뉡½ªNQô­¼ò°Ðw7Oû*MSõ u·òr#Ãý쨢>7¨Õêär9ÃÐMÍ­6 ´iuÇO\œ:y†T*Óëµá›6_uPcéô†óoŽ!‘HõzmpPÈ®½Ù}¢±ªk놧¥R5iÂÔ­ÛM5D¡;R·¾¾iЀD£Ñ —+ÒRÆí?¸{èX¹Ì†ƒ§­M«T*pCc³ƒŽ\Z÷id³Ãåí+$Œ«.ÏÄom®õMC¨çŸy}}ÓˆÄ~áa?üøCPàl„îÐXZ¾¤´*yÔØ––æ+—í}'Pqú;/¿p¥Û­‘>}«I_ÓBQTaQÃÐÁcZ¯ÕÕyf$F¨db¢¥¾¤äèWüÌŽAûßóù‹×=Ü}ÓGOäóù`nëpµ{…:9‡(ŠÊʺvþâõ”Qú;/Ƹ¸´F,VFGÆètZŠêülÃçó£#c³so—ÖØóf©T*™LÆú®‚@Q% œœy<û—J¥îîqÃÞÒ EÓ4f³»@É3ía´?·0Zž0Tåö H\—èê>Õ—~Dð7_œ”?xH/»‰1Ãè¯i@o/;½f¯8©D’_;|hbHph›FsáRÖ°!ýí{hY;v‡DÁÐMÎ>i%WÞºOëjõáÉC–™PsŒoÂ3iŸ¿ø!GdÖ×k %ãÆ+**|åê—_|Z.¿=âëtú+׸{xŒ—QX˜ÿÍ·?¿ðÜÒ{oªÉd*¯¬—HD®Î ‘H( ÿ€±W½^ïÈS)ŸÏ“J{‚ÜË¿¹Øª59tòò`Üp¿ý{©¨jˆvwóÀÓ´½Ž DxzxQQUèßmP²Ï ZŒØ´Ö¦Õ;v~ê”YR©L«Õðù‚’Ò_‡b¦:½áÜù¬qé$)[·¢¢ÂÛÓÅ‘º=⬒WT”¹»{hµ¹\9mʬM›“– T*z¬«TJ«k*]œ]ÙºcÓ'ìÞ³mDÂÀ®Ï6 Ó®0h¦³;§·Ü‘Íšº¢¦Òëiã穽ßh4,{j™õñÕ¯¾S¯`Ë.ëGäóù–LüN`ŒKÊjE"9+°Š¾úºè_o¥ ‚¦(öŸÎdºù¯·0Æ!O>w3'«°¸"$ÈצÌB±þ*@@Q»ÝáÓb 9·Ž­\Á‰b?|[ÛíÝ£+64VwÐ X¯r‡6°M€†/ 04¬ÊF²–h4Ð:}ã6¾Ô¶'Ÿ¦è¦¦F½Þ úúzMwcAîîJ77Išmh7HÓ%¥Õ‘a1"‘X*•²ÝÛA ÆIb€~1ƒ(„(Šªªªjmm¹|%;-u˜‡3;½î(‚Ä"ÑÞý{¤騤d?¿Ú›¯1uØ»ßrÄëPgVôèŸ$J?Jw”à{´T,<ÿ`¦©èûN……2‰ó@…w†Ò»v©òàÅÊ…MWë´å]?=[¾ óÉH¿øbc¥Ú5ú¡ä¿¬™Õ¯_TqqqxxDUUe`P0BÄÊUŸ½ôÂ2XùÁg~¾~!¡ajounÞ­ØØ¾Éœ#I <=¼]]ÜË+K+ª+T ‰\&–ËeÂ^f%·µi«k[D"¾³J.—Ë$’ö´Fc9.“Iíg<Ø„ÇR’F³£!ƒÛcÜ€Öå~òô±^e`8–-™­­mv ¨TŠ3zžWÅJL“ÉäàyÙlïgÓàâ‡Y¶¿ÿv]¯ Zù±îHÓlkÓ>vnÆÔÙ2™œI•U•™™ûÇOVö’ÓéôgÎ]Ë;I*½-°Nœ:šš<¬«¯èîË$ÉIñ™‡Œ™âí­f¥Òü¹ ~\ÿý„Œ'»ùéR©hh|Ìé³§†Æ'x¸{²u§Nžñë–£S‡[{šÁØkîÌŽlãMG 0Æf}+Áð@#DLt*«îÌ¥5)ž7ÁÏǯªºè.4ÆBü¢sÛÆÍ\†xŠ¢¬æ¦úÄÇŸq°º³JÙªi%x„›»WrRòñg&ŒOa]Y§Ï\ž4ašA¯#IsIiIddˆ}S M³Æs†JLæn‡‘Ƕ›¹7eÍ/~e7æÌ›…JŸ8…ÝÝ·c+L˜6ƒÝݹy“ýg•Ò²Z‘H«Ói‹¾þ¦àŸoqq"ÄÐ4îpIŠx¼HïÖ¿ÞÀÁK—ÆDÅ^½~åV^ITDPWƒ¬œ²è*vƒýK™¶Ü\ñg«G, ¥tä¹'_H:±§O¾“ÿ‡ô¤±Ø_5ÆV®Ú×2‹TIÆæšòç”þw|h¦­©øYÊX$ñùØæ@QT}]Ùl€úzÍOëÖóx¶›AÓÔÂE ¤dgpÁ·¶jâ‰ÅSyùÅçžã‰Åóç“cŠ$IŒK¶o¯ùö[B©T-Zä›wS£ÑªTÝúóíôÚ"ÌÜÜÜhŠ...Þ²eóȤ¤|=%0Ÿ%Ï, ¹ÅÚ”I[RrjQlÚ×…Y³/D#\üc‰DAÁ55ÕÁ!!¡+× „üüÂÂÂ*++|}}‹Š kkj^~é/ݱW0 c2™hšÑ´µº¹zxyªsó²Ë*êœ ¹T¡ =\¢(ŠÖ´iCÜCJÊË\œ*¥L©” …ÂîŽ;ÞHš¦)’b0nh¬#I³™4“”™Çã ø@ à \(’ºÇ'à®´¶¶=ÿüóv ¬ZµÊqkÔ³Lîkƒ!¹\¶öëïàáGÓ4Ý«éHyj­SÛÚ´™GÎÌš>—X<¿¢²üà¡ý3RzòiuúÓg¯Ž7Ù^¬©©>vòÈè”á=г^¡PÈG§ßw 35e´Ú[ÝÚÚ¬R9-˜·èûußN™<ÚÙn΢\&M6àø‰ ÃGzyz±2k挹6þ4.ý¶'Œa6ÀÇtãçpœŽh#‰E –ˆÚ&Cs™Ê+¤­¡\æì“Óú77Ö—V”~ñýÆR/]©ë߯×Tõ9)@8ÅŽ" I–ÁsúÀ†1Ïü@t3Îw%""$;'{db¢¶­52"úÜ…ó••õjµkqq¹¿_€B.¯(/–H¤9¹¹Ó§Ží¡Ë4˜•Üï8fîýWÌ>ààá½–ƒ!¡P`Ù«]°’khj“:\§Ó¯][ð÷ P(ø4Eµ?ò1í)u„Bòß|‹¦™ ¥÷‹í¿eÛ&;Ë"°’’’„BaVV–åöF §çÏO˜èËk¥I3-èéçÆa‡ž4MXùoÚ…\Â/0˜º¦06Ö1T«H9ˆA¶Ÿ~hŠné¢3 Ããñ››m–tvveF¯7Ý/‘Ê0LYyuHHŒN§»öÜs1e…àü+1˜L˜aH’4Ô,=a’OCVÍ­Ï?÷[½Z­ö»•[8´û<;½@læn;áë˜b0èyÏl4Ñ­^[ª©Ú£TO°˜*½ð¼«ß0±ÂËÔú0&3i7Ù ¾X—±£äêòò˯ûǿ׵ÔÚ ÿ4 5ÍøoSRJÒkièáöÙÚVâ2Êß'èó3/¿9v£Í2R©ä¥—­X¹c «©© ŠD€q```UU•Z퓟ŸW^^öÒ‹ËîÂÔ Èh4bÀfÒ¬Ók)šò÷ä¡×®_jljñpwQÈe …ܱ{Ñh ŽðñöϾu£ ¨ÂÛËM¥”ww\.—õ8{ÎbÙL’ CÛX€@„™$û0w¡¼Fëçå¨0‘´H`¯#¬bšÇãõñd/~û‚̦A™LfÙ°TwРÅ}e¹ÃiÚ´™‡O³K£iæóå•å™™&MHáñyÇŽŸ/*)ðWǎ몙´:ý©3—'dL‘Y ¬£'IMàñøç.\//¯V{{ô‹‹Ë¥mZÝåË7íX£ÑTXTQSÛèîæê'•ˆõcvNQeU·—{LTȸô»÷îKK£V«ê]]Ý-\²ö»¯fLçâìdßÚ¨‘ƒ=’4"ÅÛË»­­U¡PÎ=ýÏëÆg$³ž0ša0ÃЖ á]cùzÙ¸¹€H]=ŸG`R+–HäJ'„Б+Õ•um^®ê(?oÁkiÑ0 îÕŠYš* oœÝh1 _^ÓXûÑ*7Ç-DG‡åäÔÕ5¸º8KeŠÑ©£3œ5cüÅK7Î_ÔØP+KrroùøxÈd= D4cCîWHFh»Üž†Áz,Iùàô¹ëc•JÕóT![´gY}õå7V‘B~ûÒzö¹g‚ü¼Øí^z~åû=<,!E^ÿëóCÜÜÑÕ~šv—:ͺ×QÔ­×ßð^¼H!WšIÛs~;ù®Š‹‹û÷ï?zôèÖÖö'ŸyV-«Wyz6þR{µ®1üÓwõ=p8¨±:ÂLj•ìƒ(RÌŠ1U¦o9lhÜ+uͨ!BB’ˆl;äiš&ïœï}ñÊy›%ÓÓÆi&yÂnÛÉ0¸ªº>1Á³®®®¹±‘pÃdqÛ¨7×2 C‘¤oˆ|ð$Ÿ¶s¦M›³c¹mûÖøÁqv3ým÷šE[³oÿög¦>xˆÇãÉå g'±·,+hÀÒ›g¿h.ùÞZcùǯÊ?6_®úÒÙ+„2gñ%Ãøâ~´9Ïvg0ƒ±žl;€xûÿíÂŽ }K¶Ô)ÚºHiSNV͉g|rC¿ËÀ´H'’tóí Oax-™×h.Vð=ç®+..z#}í² “I_zqÙÊ>#„……×ÔT«½½AÔÖÕz{«óòr+ÊË_za™ÌÖì§»ƒ £ÑˆÆ"_›$bIüàáZ­öÂÅ3J…ÌÛË].—H$bû¹·¬)ƒÉPYS œ»pº¾¡Yíåaó¸¯ÚS¡I¥=˜e-³Ó›m ,_€‚$É>™‰1l8˜ÿɆk§×Îr°Ê¼W÷¿½lxtp·£Ñ4MñxÄ»ï¿ÍçÛ¾^(Šz㵿³r‡­Ò+ƒ*U»ÏF¥R­\õ^¯ Zù±(дéfžš5s®\.onn„ååœ21ÕÉIuôعÈÈ~S&Ͼ•›sîÜåô1w$«iu†“§.O?E&m/V×T9v(}t¢R©8sîZXhôØ1“ ó/_½>jdü¥K7ìXcÉ/,ðKLH++/½•›3h@TvvAHpÔèÔñEEײn$8!#eÇÎ}iicÔjŸšÚ*Oï‡?òÕ7_Ì™5ÉÅEeßZZò°ý&Jõöònljpqv›7ïúnòÄÑNNJ†aÍ0}”ó ‘ˆB¼•~nÒ,gù¥S‡ -µ¾QC!Ÿx;úæææ†cÀÑÙ…˜1uG:¬¥>à%lh’Ëw¨\O6æÏt ÛBð ;"„ÒÒ÷î?>ntº¦µÉÏ×_&‘Æ€1EÓ4ÃÝk,ëXa}}}VVV||¼Ùlf¦týÏš½ iÚR›ßØ¢§¨«Oþx”Xìß K÷ç˓Âś+Ë™,ù-[VS[55ujµí ®ö{ÝRµkÿ¶g¢Õfñù<¾IWšwò#…G<_ ¢¬i,°6%V†%ÿxëð‚ðAcœ=}ÍÚ·cI×E_x‹gpdÂ+Œùe<>ìåâìo‚‡`]fÏÍoÇÆÏ©0]×’MN8`ÏéŸkëêº: BK&üt#Ku—•|Ïü’Ü›Wsÿ>î/e«íÉdÒ_xråŸ E"oou]}A®®n¥¥Åee¥/¾ðd ,„F£‘ÁŒµ|Aium©dlú„ÊÊò‹—Îûùzû¨=•J{i4Ðh0Ÿ/Ðt2©<-%½¡¡áÔéì þŽã §NŸP{»ùúxÙ7ËZf5–M%Y&Üë²–Õ º×Öœ¯ÓFs/<¥5mO¼{lnzèÒé±|¾ëÙ`0bŒÙÊåò7^³=›uùþ…1$‰16ìI"û—¿õNo Ò4ͦ±"àä©‹á‘2©¬¡¡N( »vŒIÁ.RXT:uʃAïíå½ekQ'UtáRVHH˜T*ÓhZø|AðöÜ;2a°J©€²²ÊŒ±S ½‡»Çî½¥£FÆÛ·ÆRS]?2q´Á wqv9VY3h@TYEÍè´‰ƒÞÝÝã@feâðNNÊ#oݾåùg_¤)ª¢²ÌÛÛ7&:fÛŽý/™cßšR©:¤ßž}»ŸxôI>M×ÖU»¹yDDDíÛtÞÜ)·c…}Õ>PTß:]~ÝÀn›umñ*®â DDÔÄ}§ +ê4ÞnŠII¡€ÀL:šÆfÝŶÊ׊P%ÐÜùü¡€F^æ!*?ÚAÅâââ”42>óÈ¡ ãÆËdʸ¸¸ó/‡65Ô˜)êÔ™Ó“&¦:’HÀæ¼w:ÈŠ­®í¶ˆ¡iš¢Y*È?ŒÍf¹;X?–%í¯Ó.ˑĞ 2 f»Ã0 {Û·EÖÞ, iŠ¡i²û$HëX¡L&‹¿zõj```KvÎ…§žJ]àÛr¬©ˆá»#LÜ|Ksõ…7FêöæÎÑc…€B€€v`&ȉæ-p ˜b„[@æá}èxÑ ¡‹¿Û.;žZ_UöýX¶gtÃ0yùÅ#GŽ®¬¬òôðPxzþé§‹Ï?ßÜdzE¡DRí%œÓؘÏã…®X!‰Šr sóò|ñâÉ“=mk¬î{ÝPºíÀŽg—,]{zÛâk»Gð…r¹s¸OH²«Ïàʬ Òé´¬‰!©ë³3D NpñðÓÕ>/uÿ÷àŒ oKüðŽó’ºªœ/êÊoz 6·m•8-Õ6¯éd­¬1ðàÄ\íÞÉÜœÂ!®Ó¦¤>*Üñëýîìr•Z¢t–ž¨ÿÒI¨.))É»^þ ?¨UŽ>–±“ŒðíX?]ÖtéD"±Ñ`d¦«|A€† ñQûÿ¸þ;¹L&“Ií¼LF$FH$‰…b‘P$ŠÔjŸiSg®ß°®óqoŸiSf®ß°N!—Û7ËZ&I’¦)›‹ÏðI’"QÏ‹+ÚçÏÏTiF¥&Tï<Ò«Š£FØxè̕܆oÞHíú©Ñ``çç"„d2EÛÛ±Kæ$É0ŒÑ`°sºî òy|°ì:n¢(LQ+F$Þ»÷¨³³‹··Z«ÕÊ<=úÄ·ß}íì¬tvv ð÷9wþ¬Ÿ¯ß©3'ƒ‚ü;™Š{øØY•ÒÉÛËË`л¸¸.œ÷à†ë”*¹“J©V{\¾rIíí}áây_5Ø·Æâæî”sÃÍÕíÆÍ,/Wðör»výŠ—§×¥+—||< ¹¹åÈѳYú´@(ÔÔVÉeŠkׯ\¾ré3{´ÖÚª9}æò’á ÚÆz‰Dš}ãúõ«3§‡Û9ït_Ì+lHçÍ`}írLLbWkOŒ žÉaÖžm«|Ã'd C’îžf“®ÚÌ\+¯¼!æZ ”÷zaO?uK´æÈ‰ãcÒ¯ee%J½pá\P``æ‘£‰‰ƒzœ¹ÉbÉǺ£©f3˜ÌÆýû´/Ö>™c “S’-eîv¨TÜ¡±•  K$±'ƒ ÍP@S²Ìýø³+‹n¿H(š¦hª»X!XÇ X^^^SS@3´ãêÍ m7n/?†D†IAåÕÛoãÿ9=h,Ц€G° f ö·cg8Ó0†aZÓ€…²Àk¹_fÏ1@S´eæ*ÆX«ÕøÙ>ª««F€´»ß9Í0ùù%S&»TVÜдµI%ƒJ¼jUñÇï¼~}‚kŠ€Ïßwó˜F­ö^¶Ì¤RÁЪi3“dâðaÛ¶o81Ífx§»^×l>°ëÙ%K×ê*_Hœþ=û³05ý$tÔZö¡F£¡)Ì—ÚXyU¢ ‰³þúQƒâ\Ýà õË•^_4U¿Ó©O ó™Ÿúq߈éŒþï„b^[sá³|W4™ ¹F_Ð_1ýFÁ†düØI`À¹ÂËýãXã§BVVZU–ÕøIŽ ,­V·rÕgþ>¾~55Õn®nÐØØàëëo2™W|p{A‡>A"‘FŒ™®òE(ˆ(-)>qêè€~1¾¾j„ì ÷¬)‚ „‘P$ ÅEUUU:r ±±Ñæñ訰Ͳ–I’„l ,¡@È:u$ ô”gŸ/^Iù|ëOõ¶âÕ WCÕÊåKmûƒ F#ÃÐl4S©R~÷Ã76‹)UJÖ!Ç0´ÁnhϦA†aäIXûÝWlØÔqƒlŽ—Â žzæöRO=óÔ'ÿ]½rÕJv÷¹gŸ³ÿøJQÃ0ìM¢(då°h,‹7«½×ESTw±B°JÉ ÐétYYY0’…… YýÉù‡éÇãyNVµÝ¼v[f¹‰¢¾öB¯¿‘ÿß8àÇB€êX¬ ÝöéXý© 7 ®€ÕÓoÒúGk2™óòsŽŸØ_RR`3+Öß_|¡àïÿü;B¨_\ܬ™³Ù0Æe¥Unnn4M3 ­öò ¨«««0›}´nÿþõ[¶ÆÂ±cUãÇ#™ÌÍÍÍÇǧ¸¤ÄËÓS$I%Òüü¢ÈÈЮ®,›½®ÈÝph÷óKžüŽ!ŸðxRÀZš¬%$±ššõu5:=6 ¯pÛsé%ʸôõ×ö/ïåé7º¦h³³zt—󚛪Nø„LbÈÄ“èšvò.w>f"¹Ð9§é¸P(ÔPUqAL ›"àߥ0öbÞaWàâò‚’¬Æ7§þ vrP`éW¬ZàXQQáëë[QQŽ1øûûWVUaÀ+W­yñù¿X/Oz/´;Ÿa-_„¡H(njnÞ»wG` ÿ´)bhº‡!¯Ã …‘´µµeÇ®­în.Ó¦Løô³¯lçñ G³¬eÒL"„ºX@šI‘Hl6wöbö >=5;.m°ÏëkÎ:^K,ä=06h^zXwƒÁ@Ñ4IQãy³Ø1…1&)Š¢iƒ]·“MƒÛv¶Ï¨•ÉdÓ&Ïè•Av’E‘–§)'•ròÄ´­Ûö§$§©½Õ%%…Á<òøç_|:qÉã’»³¦TÈÓG'îÝwtäˆ$//¯Êªrµ·ïÂù~ÿÃ7Ó¦¤§&OM~»°RaßH¥â!ƒc‡ ¾†"“IGŽ̾٦©¹å×_÷<òðãr™¼°(_©P––ïÝ»çÁE3ÝÜlDǬ­µ´jví>²pÁ"©TVV^"“ÉËËË33Ìž5ÁÅ¥]œÑ 1Ð}+dG6DLM‰¼3"Ñyn›åžßãx&íù¶Š×ýÂãñx†Ö"©ŒzLéÎç£à@Ý;8Õ¦ÍûƒŠ7a†Æ #óöv]ùþî½»Äb1sà`Õ²ÕˆPÏœþæß„.ÎvL1¶b…¬~bhúPæaö[¸½ú:ÆicÒàüX–•EåŠ;b…Ö XÖŸZ—±‰ÙL2 CÑ d I‘•cÀâȲœÔ ±/ $»Ï•%VX__¯ÑhXÉÅ04E‘Asç–;ž¿nøbkÌ\ßêZSؿޞ=õî¾ Žž×ÇB€d‹vg»Ž:¶¼/€î&»vï¼p᢫»3çå%ùy×1QÑÓ§ÎØ,- w^pÛÙ M –ã Ã\¾œ•\__OQAåååNNNÔétMÅÇÓF£ÿðá®®®r¹¼­­­¥¥ÅÝÍÏç“$™xîÜÕððà®™ï6{mÐ5U·eŸ}ša|>ŸÇ„ƒ)ÚL‘$I‘”¶Íd¤Ýƒt»¨T2`ü¦²ßä\ùÑ#h\à€Û«Åè[KÚ³ ­E.žÞsè–åI\k]«Ü­óëÉÂ=µ6W¸ø¹Oè¿8¯ û×KküœÃ‚=bÕNí¹V3=±ñü§§/œŒñòÖ´Õ^*‡žù´ZÝû+Wûûúùù———ùùù”•–!„ÌfSpPHEEE€Æøý•Ÿ¼üâS}åÍb…+_„¡T"3¿ìøY*Oš˜!‘iÚÄô´Ò Å”H(bhfç®­MÍ é£Óœ•Á·u\EÓ¦îýë I’B6V»Æêþ‘±·D»lxgœƒ«m57·ü¼<=@mo£ÁˆÌçókëj{4Èçó1ƒvÓ§ºôòô–Ëeì— —Ë"jj«7HÑ4Æ@Q”uÓÙI5mêØM¿îNKí­ö)(È {â±e«×|¼há ›òÅ‚J©È—´s÷ᤑ£¼<½KÊŠýý\ôÐ7k¿œ5ã¶|¹wšš[~Ù´ûч—6¬÷ IDATÉåùy*¥²´´tÏþ=KÍrssµ_·¥E³s÷¡… K¥²’²B¹\Q^Q–™™9wöD+ÝБÕ±BŠF€Àöc¹Uõw¼WxÏûw̱0™M=Žç,fÝŶʿù…>BššôMy…AðÍF=Ó^‘Aaz¡WLµu§FNðõõMKKãñù€P^vvÕ /;ÿõiâôÙ°Ë×c&NŒiš.ÍÎ?1dôðƒ[eÁݦ™ÚÌÇbõÍ0£Ç¤±ëÛYž¦­¾{ÑX€-ïg÷­°0Æw¾•ÙÑX$ifãò¡ï,/ù×r?“É’ÏlÚûP&û¼ò"x&³ÉΠÄöšÇã±kݱTVV)yAAA +Þßtþ|­FãT L]µíý9u×ôèÇb ãê#Ú\DÈ"?,OahÚæüù‹“&Nuvvö=10 ººº*£Q;f½Z^?S*œœ\oܼùÀÂ…k ƒ¯\½W^^®R©Ø«¤¡¡¡¡¡ÝxÅÅaŒM&SUUëÆ …|>ŸÏççççK¥ÒË—¯/X0͆ƲÕëèa ¼Íß¾8}º—É` xc Ít›†¬¬2‹D£f|ÃãÛK|–(ü#þ‘ð¯NÇåN*×Áðp ÖK&ÌœuþÓˆÿíTrtÔ¬U‡ŸÊðKnƒª›¦1áã_(—)0†}û÷Ô×פ§vws¦(EÙ»7w5uòÔ±“§NfŒ=6=™¢Œe‰]Ž›(Êž[¥«åö¸˜BÅ#xÇ#x<ÏztcÁÞu¾{D^ss‹T*±¿–T*©¯opwïaV¼ÁhÀ‚n¦ÚŒvýX] "„ärùÉ3G@.—#„î<]iŠÆíùXwŒ.ÎN³gNX¿aûèÑéjµ:7/;<,ê/O>ýÑÇ<òЂ®a8kœTÊÉR·n?””ìíå]X”úð’ǾøjÍ‚yÓØ0Ü=ÒÒ¢ÙøËÎGY*“Ëóò³UJ§Ò²Ò½ûö,Y<§G¥Ñ´íØ™ùÀÂÅ2©´¨8_¡P•WTÊ<0wÎd—;3LûÚ Ýk70MK‰ì¿Ûó!ÀÊ«…1æDã9˜uWZË_ô Y¢Õšu¹2eH¢Ä˜ik®)Ù7Ïb„ø€{¡Wª·íññp6ôØúõf½bÒäÉUŠ ó[¶Z¶ìà†Ÿõµu<±("668,¬zӶп=Û}—)€ÎÚ”ÕO<‚8|øÄ.pŽö…Bc3ÆA_äc-Z¸¸ÝIfc)X¼è!ëÂvw— —Î ì?Èsþ|šfÊ–¿íg0v½Í°Ëý¥çÜfÍH$GŽŠˆ°¾°Ì+äóùc@ iÓ´µµiµZ©§{ò×_n3Ö¥%PPJñÝ{¸˜9ìÐã¤í1?C`/vA‹òÇpÛÏ`'~d6“­š&½NÛ¡ŸÚ§K!‘Ê, [½9“Ý.//—Jåkz½¾¥¹Õ×Ï×ßÏß2mž&†¡(vú*Ã`LS”ÉdÒjµzƒÁ`46µ´Ò nhh4Mz½^(ì<Úv×ë~ßÁ˜¿å»¿NŸîµuk¥|dLT½Áë‘ÇÖ„wóÀL=Ðe ]Ð(àË"ùâÑõN¾Ó]|Ft*ÙÏ/qTàìÓÇŒJ ˆ,6œmáUyðC܈`Ñ‹wØunÆ.^IKSWWçãã[ZZRRZòèCóBãGYôÅ—ß34\ßPºwïîææ‰D,ßk¢·Ñhðr™òòå §Ïœ?.}lú(Š2‘d/dÛ//ÏææÆ§–=Žc6ëìïb‘hÍgŸÚ)àà›€!4dH”ýu‰Ø4&ËŠöÝ!àóu:X,é.ÛÝ>¯Óéì ²® L¸#ÜÆ7HÑ`ÜÉÅâââ<î”~Ü2fLºÚçFöõ訸ٳçï?pdÁüéöûâ䤚6%ý—Í{SF¥x{{çæå„‡EN:ãȱ“3¦õ0ußÎ_¼ºè%r™,çÖ g'ç²²²=ûö<¼d®{O ®\»9{Ö<©Tš_˜«R:U”Wd>0î×.‘/†fcºOüX#Û¶£·,~,ÕŒ´`gº ‡Še9ÊîÇsÌ4å/¸¸'´¶Öš4—•Šp‰Ìc¦®ê4CÊ]$ Š2ð… ÒÜÄã÷bq¬šõ¿F{ùœýaÝÈS{¥~{ÝBc’4X2ïìWßR¤F“rë"ÉãƒSF%_Ù°ÅŽÆbúWèÐO</##ƒ}^"ˆvÁwœ»ÖXìKWÙüyÔæVý×:»ÆÒ¢…ìÌJ޽r5çÌù3ƒÆ{ÌCÓtùÞõ3Þ–Y€(‹]Ÿ{ÆeÖ,‘HräÿØ»ï¸&ÎÿàÏÝe@H½·àB†Œ¸·uk­U[´J+*U±Ukëï«mm­£ÃÖYë¨ÖÚV­£nme© ¸Qœ¸A 3$¹»ß‡1ÉÁçýº—&wÏ=÷Ü‘<÷ÉsÏ=÷ï ¯G·(=ådö—Ëå"„ž={–÷4/$$Ä®µTli¡T*Eînüø)©Ç ^Ô§³ëw(2èY:ºï( áBMj>3š‡^"½ßÉ€€6gÏuëÞ•F”桘Ìú´ns˜v;MQôÕ«Yï¾3^;·òr…P(°“J'¼+à 8\.ËcF+%)J­V „B>_ ¶Yˆ- ®gg?}–¯R©(Š&IÃñ@oO…¢štõìu»ÎSHß½9/âOú(MÜÊ…Ïó¢OÌ3|㪔*N¹ÒG.‰—½ÈÊLZ+t÷k?Y¥RëÜŸ¬R©½W˜R¸sÛáȨN­O¤"0’P¢òòr_Ï[·oùxûܽs;ç^Λ#“$YVVÎãq¢ß=lÛo;•*•¯ïÝ;wZÛIåò"æzVµaV·ncjz4ýë0ǯg_Ûý÷.YLÔô©ïS”ª~aZ]ñAÜDš¦IR¡}m±¦ù†£(2öݱ$«=‚1ø° kk+>Ÿ‡ãBhDZ[ßm¿¬Y4¾¿_üÈ „Iª9®fÀ誘°³“ãÅË;GDª”*ým!NpyÜS§R5µ¿!—èvDcεfÈ Õ¤N,m‰íø±Ã~Ù´£OŸ¾NNÎW³.YYYß¼eÐa´±i5jx¿í;övïÖÓÁÑ!ûf–ØÂêÎí{†¬[«k×nŽ1>ëúk+ëû÷<ôÏ{Æ`!„nÞÈüÆè›·³Åbˇ;~äí·†T °V;–þ>ï†|´45ÛÐnÚXLM«™Qy+qmõ9† ­ÝVäÄó-mFX!‡ƒ?yD*I‘ØÉçy—ì\†–]F¼H…BA¦éD!iŠ"hš'*ó Êï?ä[Š‹ËÊøvR$µµðöz^ZÊYŸ_TTt.󜫫˛oŽtswãóJe…RY¡R«v’Ø÷5|äÛ®Ö°cNK̘/iþ¸¯îoÐt’T“êjïD¥i: Àûöí"އ‡;sEøe†8VÙ:ÆŒÀ|1hš¦˜¶¨ÌÌKb ±‡‡;óK«²dFœóçÏ·jÕªmp;‘PTRRRPX R«IµZ©Vóy|‘H$[ˆBŠ$Ý\Ýp‚P)UÍ|é0¦´®{Ý.b2¢ñ=[¦\gIëÝkÉ óòœ{ž{IQš‡ÑÊk¾Ä)Œ¦9U¹R…!ΈöÓ%‘§/Ê¥¯IÅ…¾ŽJž»ÄÖ©þíX$IuïsøÈ¿GŽvsuüF¡P@>Ÿ/ 0¬ÜÚÚòí1ÃŽ;yèð!‰¤UÏîÑÌ­õÞâK´——çíÛ×§O}Ÿ JUVuÀ@Q”Š¢ªéPÓ|éTe Y½~0  +ǰ? Í‰³¹˜…­P(|œsgê›íy\¦¯eD.š¦U*uTdÈúŸS”+Âí¬j¼FFÓtQQQjZʉÇâ&¿­R©9¢jŒeô Ÿ=Ë[Z\º|áYÁ3ÿôé3;;©&™ZM¾x!/..Ž ý{Ïß={ôòóõË?¿°U+k=ƒõ¿\·$¤CÐ?ÿéÚ¥‹——÷ÅK¤µ®«“³ƒƒ]RòIgg§[·o>r¨g·¨’’R à )•ÔÎæÔ™4'GÇœ»9Çÿ=ѱ¨¨„¦‘öºÌÁ±²´¸zõráó|¡P spê£(º{¦"}Õ·aèõ>…šÇöé¯Ù¸¢bçeåÏVæiíÚ+¿0_©âø®|‹V¤Z!/Ìní*.‘ßTq'Óeå‡Ëå‡ËåèÙ…Öƒú=;r²­Ÿ_æˆX¡M«àöäæÚ¿óMÓ’·G<øc_p`àÍ/VÜÈÏoXXX(é_ýmFE•—+xb»Ç9×Ýü+Í#„ÍÄOB}úö&‡ ‚ÃÜ/!ŒÆ0Tßv,‚ÀKJJ=zôòöªÙ€®B3“ ;;;=Ÿ ÃÂCÛ¦ÊLNIŠï,9Ürð4MiçF—÷ï¿',,ýúv«5À¢(êÂ… BÌØ7mll|EQŠ—×ôIR-/’ëé% ¤/ÆR©ÔNNö—¯\j×¶ÆÇÎè¸yëFk©D­V„níÏ|’ºwï±oßþ'êvwºXlù曣H’ÒŽ±¬¬Ä®®ökÖ¬¥(êDÞ íÎÌ .—kaa!8ŽR©T(EU^s'BÈËË¥ê%Cö:¼ëTG׎VV­¡þ½6Ô!À¶µŸJ5R©T‘$Éápx<^µ5ŸÏãñl¬¬,íìúF·íIÇår¹ d\ ØÚ¶2¸_EEI’ÌO++KKK1†a ¤¤„ ð¡ƒû«Õ*„‡Ã ù|~=/2ÔjÅä÷bišR«êFš†ÇGŒùô°5s»¾ °jGQ43hxX»}ûþþkçzïHçóyBÿ½1 c†qoì •JeII™“½ôرÃj’ ð÷.))³¶Vj>W¥¥¥eeeÅÅÅE¶mãw*-eÿþ}ÎNËÊʸ\Žžq’4ëªÕ*OçSi)‡²o- éTëºú19{y¸ž:•”›÷L$xSU\\L¸!¥rq²?s:%¿ Ïãzº;©Õêªë2ÇÁ^zìø!’¤ü|µ°@Q¸¢~ì¸@Àé* W«ÉšheFxüø‘R­èÞS& y<>Bt…RQ9 BÑ$EÕû/ÐÀBcèDß­B‹üç<|xÙÙ9øùó»4Mçå=½xñꃇ¹Ï ž“jµögTë“òê †a­[K<ܜ۵ rvvÔ9ëÓ4­Tªž?~ëÖÝçÏ_Ô©”ÖÖÖ~~^666<Óê( T*_¼WT(ëms¹›V|>_û3mô½fµšT©”4Ms8ܪ3äŠZMâ8ÆüeõβÎßÿÝyø¬tÚ¨¶†¯BQ”ZM*•Êòr…B¡P*UTuoc0 Ã|>Ïç‹D.—WõÊŽÑ3D1—¤KKKB"‘PçLÓ´R©T(****˜“ŸÏøLÇýG !ë6^Ά¯[ëÁ1¼´T³QURRZ^^®PTPŠSê,{„ÓOiªÑå!Œ†µZLÓŽÅãñôï‚B¡¸¹ïðÓe+U÷ÒjoOѱN~ÞÞž<·ôYþ¥Ù JÒ3É/H©Týæ§~=ýý}­¬,«îrEEEqq©B¡Ð¹â™”’ž÷´€ò òÒÉË¢)Ц)ÊÝÃebì[u=Î……/RÒÎ>}š_§n 8Ž‹ÅÂà6~AAþÕ~xÊÊÊJKËËËËKKË.]ÉÎÍ}Æ\ÏeFô )š¤Hš¢¤Q‘¡"¡Pha!‰tGØQ©Ôoû`òä÷¬¬-¹\.‡ÃÁ°—Cl¿ž’¢éM7¯X¶¬:¹yóLDĘÙKB[6oËY|©Æ !¤Tªž<ÉÕÿ0ת‚pt´¯ö—SA«Õªºv‹ÁqŒÃár8DÕ_ë÷@ášû#µ}¯0’¢‰º<i]¡xy ©q$Mw\kØ’&È4F­Ùhš~9ì%s³ÍŒ@T^ãnà€¢¨²²òââb¥R%‰Äb‘@ðê¹¢$I–––ÉåE8Ž‹ÅúîNWw† iš¢^ŽÙõúBͧ” t¯k¨´´,77¹kÏôLjg'‘J%z¢Oµš,//gbY•J¥Tª˜±IB̽Ì €/ …BaMÇdÏÞC¨ì££·„ýúvc`oCvhT±ô]+äñ¸®®ÎõØLM9ǹ\̇LU«ê'¾1ÚQŒ¾×K],ôÚ9Ã8e0z† i4j͆a—Ëár9/û6<Õ4AVV–U®j*Xµ¡Rýš aa!òöö4z¶ai)nøýËC÷2¸ŸQŠ QK¸cô¸?d!Z4?P³ÐΉ±ÒÓoúr4'º1–Hdáëa’¢4Ðt `|cÄXÆ1€ñAŒ`|µjcã¹¥h I“j¤Fq‡ÀˆA¤ !”’’fø–<=}œ[kÞÊå¥u*¨‡Gåèó66­ê´"€ÑÕú`ÀÚc¬ôôßQ@KïÞ½e`Q<=}tæää\6p]„‡G0óžóW{ŒþÖõ¢-z¼õÖXæQšÌ³Ë^>ÿ Óz^–ž~ºÚuýü´×ÕÄOöÚêFÕe§L¬žÔaoï«géåËõ,uvÖ·.B(#》‹n€93NŒ…*)yJÓE©iš¢iŠ¢h„(š¦y¢i’¢(¹¼hâÄ)?ÿ¼R,3ÍZ†¬˜3¦'ñ黦.G¥§`ï~õ”áÍ{i„öý6ï¥ÃcØ×½Ç¿U-½¬ g´«áŠŠŠß|süùó—FŽýý÷õ~Àø¾}Ü•+gÏr^¼ÀîßáâRýuÆeËß/((ÀºtQ¯YSêá—#4Š—b}Cé©Xì`cްi/M39¿;מSkIÞŒ#TK@f`n,eüK­V]¹r200†Ã! _«¨¨xÔ¨ñçÏ_B]¸pyôè ;vü"WfÕòÇ(-Åd2UÿþÊÄD ­þa¯Ù²…¿p¡pË–’€rî\Ñ!–™™/ˆ:”@3wáç½÷,ÊË1wwjëÖb‰äµ³IB‚Åž=¼ð§O ¥ÒÊE­ärŒ9›üúkI·n*íUce¤b±CjŸ6í¡ÂŒµ0Å‹¢¯æ“ÚsôÓN_“Œ"B£ïBmÓFޱÔjÕÅ‹ÇŠŠ ²²R‚‚bpÜÐhzĈ·E"‹=º2û¦PTL›öÑÆ«êQ†·Þª@=«o×V®L™¢6L‰Z¿¾ÔÙÙæß¹½z©ô¬ E;V¼lYiÿþªÿû?ÑGYüòK‰öÒQ£”óæ•ûùé'”ž.¯zý¤®íX©Ø„¡Õüîßø7iHðÁ–ûïC£è+ÏtUF*;äÕ¾¸ËæÉÈ1Ö… GqœÛºµEÑ·n÷÷3pÅ£G÷QEÓ4EQ1ݹèj‡i0ð£Ã$£éjÒWT`.p>û¬œYdgGgÎpzö„ Beg/^`ýú©hMš¤èС•ÎÙ$&¦ò”¡s¢©ö¼£YT«ŒTlâ0!ôËîêc ¶ÄOõE_~ªf^g¤b³&Ë74i˜eÄ#lä+4t€…Ek„(š¦ÂhšR(žw WP€‘$²³{;·nM=} CÞ¨ôàîæVyšpq¡ŠŠ°âbÌÒ²öÓoÏžV Ö«—jÅŠRkëÊôµŽì˜‘ŠMVyFþe·š½-7ÆM/ß@kŽ ƒEÇÇøý±JJrëz_!Iª˜Q²B†0ŒÀqÄŒŒeôâU«Úí,Y"üäQµéù|Z   Í.|4s·ŠmL]LÌÇêæìàÁ"wwª¨›2ÅbæLÝË‹5ZiXâ{œ »ÕaQ´þ”-Ph})ïÕU¦Œ´Ê`Tûp™-ÓßW˜žþM3—)æ3ê(B8ö’q·(‘О={Õp•—‡wï®{¡pΜò9sÊ«ÍÁÖbhÎ\]©û÷+OâVV´!XîîBÈÊŠŽW|ðÁ«Û¶ôôÇ:›†'Nâ,ÿYIAhU«ÐHúb®òlžøgùÏêÐ(³Àh1I*µ¢pg£Z£ÌÌêÇ×áâ¢ýÎÀÏ ýò_Ýô|>Ý¡ƒ:9™3hPBèéSüúu""BU÷[ àÛ¨+¨7ØÁß_meE<Èíß_¹nРÊsÜáüÐP•Î=†Ì¢âb¬´sp **°M›ømÛªuþÜUC¨³iøìÉœeëÕ Àª‹N‘Ô²õê÷†sB?ï4z¤ef÷^ºt@Ó EÓBÃpíæ(£lÅ@/^`99ÄÍ›BèÚ5"?÷ñ!Åbú»ï„W¯ë×— „¦O/Ÿ:U­òó#çε $uî°j‹lÛVïæó5Ÿ’°1à[Ð2‘$NÓ˜£+ÜTh#Ôi·Õ™gˆ©o¿z†ò¿)B"ª‰·ÌqìmÜçÝ|>¡æS[@½ÑÑ4Îá(‚lSêN¦Þª|ÿübšV¼ÅîH­ý³ÜÜï+DͽÏ;P'jµ@¥*å°ïêQssþ 1}Ü«èjåVEG­Ö,ãÁÐçÝ ß|#š?ÿÕÔù|šÏ7—!Θ9WRçÑ}ÌÍÎ&sþ ‘0^ˆúá×òÆ‹«´AŸwƒ|üqÙÇ—iÞJ$†½ ‘ЂÑîa®¦.E‹t>øp¼!ôý¯åÃIÔTç#hµMÓF>ÈÁ#º¨M]–çB:±àCÁ÷[Ê:4atÅ€>ïõ*AåŸÈô%a8bÀ· Å¢Ýk.wXâB:ñá;"„&À2L îón>כ̧$¶€z£e¢i!òá} Õ4.¤sf¼+B}·¹¬C¸Õå«gîc74¿>ïÀ( n´XF=ÈÁ¡lTÒ93cEÌëo7Õ9º2:èó4.¦ëÉü|:Ñ! ºdß… άX „ЊM¥š#lòˆú¼MaÅÆÒÊ8`ci{ˆ´Œäbgք׎ªÉC+ £ÅX{–[² IDAT$©¦iš¦)„Žc†ã8 Y£]¨úØe¹&&`,ÿâ­zº˜ÁIœh´Ž¡ùDW ãÄX§O'Ó4¥Â_b‚-£lå%ó9„æSv0·O?¦_ƒ–ˆéêÎÔíBUG/½`æ_Ìà$N#„–m(HËp38³ß{í¸õübN÷fddÖšÆÚÚ²áØ«jÐ.T}äâ‹‹g9Ÿ'Z|º¼´}(„Yµ»x–óE¢ÅÒ %Ìá2ç_ïìëeGSû ¨ 8d ¥ƒz£eÒÖh×Iõé²’Þ³D-ý¹¸DZ¯»t–óѤ×Zj–þ\Ü®“º‘¾Mæ>vtè9y·í¤>tþ¹v0ñÍú:[ŠrL l>ñû¥³œ'¿TU=¬ø¹1`Ú…ªŽª 2Õ^Lâ:ÅdÕ2$Pk`0§Ù¯šJ[kvacŒe>±«ù”„Xñ³€F_P;M°¥­¦À !4î}…fQÕèD{EýÁþÈFšZ·ré,ç‹Ä߬/Fiï“Øœ¢+sêóÞ,]*þôÓWâñ òÐPÕ^ã>(Gµ5€Õ1Ñž@M³¢&MÕLü¤³f•­k:ÙjvÄø½ Æ2ÈG•|ôQ‰æ­D"5aa€jéÃô\‹dâ=š&÷A¹þÚe¨µyLÙb, )ôëhê¼¢FèµÈæãÉú–Ö=vÊOfÓ%òŠ £ežË|úô˜OIØŽð--Ë>ô0vÀ …ÂÔE&ÀÆËô1]åš¾$lG øÐR÷I‚!v¶c¶‚ž(ZhÇ@3÷ì>hÄÝÝÁÕÕaüx›¢"L'AïÞR//{WW‡Þ½¥·nU¶@Íœiíãc/8Ô'^‚ ÍE¡„„’;wroÝÊ+/Ç–,ÑßkÓ¦çwîäÝ¿Ÿ©üôS+fæÈ‘å))ùõ¼ × ÐÌÙÛS½{W „‚îÑ£"=§“ÀÙ™DÑ4R«‘“Så£\¢£• Ù(ûb,Úl:õ˜OIØPo`Z öË/¢ÿý¯¨ê—±iFÏÝ]}üx¾ÎRš¦ëñå…k…hÔjkÓ«WÅÀÕŒXvð`þ“'Oz÷®˜6­•Q61š?’D&ØÚÙQ_}%¯) —KOšTšœÌ7ÊÙw­Ð@k}Áq`4ÞßF  øá…öü#G¡¡J C/^àžžj’D¿þ*j×Ne”B;–A–-³ 5“J±)ÀçÎñ¶m;Æ÷ñqðöv˜8ц™?s¦õõ뜒lÌ[//Ç«W¹kÖT>ñzÚ´VÞÞeeXhhëAƒ¤uÝ(c´…Ìž]4{v‘æ­Dbgª’°4ÿõ&ZQ^þ°êü«Ws™§OçU]úãϲQhÇ0>öµc™O[ˆù”ÀPoÐr@;€ñ±¯ °ü‚Ðr@;€ñ±±Ë|Ç$¶€z€–‚1–éÁ¤õÇ @K1h:š‚¦Ä<ÃÃ0 ÃL]@KľË|ÎÓæS@U$IÞÈLqoÓI(²Àqsé{ õ-ûb,0„JY1~x¿¿þÚå'•Ú˜O˜ ¤TZšº4c,óùh>%è¢( !Ñ'99­gÏ@[[[³X¤¼üO„"L] „1`+¸Jšóy6lØþýû;Ö«W/hÍb +5u0¨nÍÙÍ›7njӳgÏcÇŽÉår¦q šÄX€æL¥R]½zu„ ½{÷>vìXQQ„Y€¦1–A–/·²°pÓL*\c€T*•J¥ºtéR|||ïÞ½?^\\l”!îºwï¾lÙ2ý¯˜­,--ÿûï¿zoÐHØcÑ´ ¦Y³ŠJJîk&GEÓ´IJÂò €&…R«Õ*•J©Tfff&&&öìÙóĉu ³† †kquuEõíÛ788ØÀ¾ýö[wwwÍÛÇã8¾bÅ ÍœL˜0¡®Ù6o¦®¯`‚©–©V싱¢Í`2Ÿ’°kÀ”J%Óš•žžþÿ÷Ý»wÿï¿ÿJJJêf 4(ó¥Ã‡#„æÎÛ¯_?Wïҥ˃rrr˜·ÉÉÉ...ÉÉÉÌ[’$ÓÒÒºtéR×l›;“WY0Á¤ªc,ÌKy™©Kôb,&ÒJMM]²d‰L&KJ:YZZBÓ”•©­­M‡황M›@„è—õ´«Úª¯+§Ú[YY%%%1o“““gÍš•’’ÂàâÅ EEE]»vÑÉ6,,láÂÿ >L*•º»»ïÚµ‹™/—¿5j¤H$òññùûï¿5[,--™|ØãÇ¢wïÞíííͬ¸yófÇ9‚­R)Åbñ©Si¦>KÕçÔ+@¿"äÜi|Êhþäêõß½ömZ½£¢SgŠYjÄÍi6Ää¯]ýé«}ÛÜ©5 UL€Åü›œœ,‹§L™’’’"“ÉD"Qu¬LV^R’SïM^s®ÉêX`nØc™ÏOp3)Ir²`À€êk„ ýb›É¾ÐœOœ8akk{èС_ýuÚ´i÷ïßëÖ­›¥¥%†a\.—ÏoŠËÖ\.72²óÿý›–vjÍš5¡àààòòò7ÚÛÛûûû˜O@@MÓÙÙÙ¡›7o*•J„¿¿?Žã§OŸéÖ­+BèáÇ< jƒ’Ébbcc÷ìù[&ë¼]·nÝ‹/4^æÉ$õRLŒ¢¸8Lj´^]a_ŒÕ\é •Bóæ½øê«V5-…/'5quu=qâÄÑ£GÝÜÜ&Ož¼zõêÍ›7ûùùÑ4mmmÝÄ/”ɺ,[¶ÌÆÆ†+ ðèè¨Õ«× ÐßðL¤Ré°aCçÏŸÿÛo¿aöé§Ÿ2mWR©tôè76løY$}øá‡!!!Ì%Eggç;þø÷ßB11²qãÆuìØQ,7ÎŽE3ùå'“Õ´é¯ÿTò¬1V}8¬N­_5}‹˜|šÁw¬NÃÐ@ÌçíäÉ“prrâpˆéÓ§¯_¿~Æ ©©©ii©R©Ô¢)‹Ôµk—ÿý¡™#Û¿ÿ¦yÉpëÖ­›4i’››»T*ýðÃ8ÈÌ_»víÌ™3ûöí§T*{÷îµeËÍ¥C™,f÷î¿ÃÃÙ×$IÊd1FÚ-ÐPúã0ˆÀØ C¡}o´F-òŸSXxG'…ç–¢-$Mª‘!ÄA#‘2„PJJÚÝ»·**jÿ!èéááëìÜZ3G./Íɹ\RBRÊNÂýž?¿‹ârý.ëZI¥­BùùOõ¤ÉË#Ú¶uÙ¹Ó8}'ËÊ0‘ˆõÊÕüÖµ'ÀHJKŠ»µ±[·n««Khh¨@ ÈÈ8ûï¿ÿ®[·îÏ?ÿ¼~ýúˆÃ%I Üê ÃÊÊËd¸© Âuý1Ï€°Ì(T*Ý󲭭ׂì%¡-›·å,¾íXåûï­'M*6Ö‡¸X41Çÿþ{Cpp°ŸŸ¯D"¡iZ$Μ93&&ÆÇÇçÚµ,S#0äZ¤Ž:…e5c,ó‰6ª/Ir²`ÀG„Э[÷Í©´´,\¿K—¶A°P(`ú]uèÐ!%%åþýû÷ïß‹ŠŠ‹ÅЈeÞ þl2Yyqñ]CRjNg†8pà Dc:Øc™/ÍÇ>j˜AVVb.×Bsª2™¬cÇŽ†‰Åbs~s “)#ÓÖ¼O—싱š¬ÛôŠ­þ÷?›jaEÓ¸¥¥gÕE_]_„`4„êÀ1M Ãq Ã0š®êÃ@ÀçóyèÕ8Rð¡4O4‚ƒUbbEEEcÚê™5ªðpűcOŒ’ûb¬&3kÖ‹Y³^T»ÈÎÎ!ôìYžÎüädÁÀŽsçJþù§9æ°\ )1gƆçÃÆ+ÄXÆ$“)ŠŠî&' Þy§õ–-OY÷i g`üÄÆðÈ(Øc™Oóqõ%‘ÉÊ·lyú2ÌÒ}¨ØOmß²$' oyúçŸ'-øLWK£8c,Ó«u,M³ªc@SªS´¤­eGNF1VcaÂ,ø)@ó““³hÑç‡ÉÏÏ···ãŸ|2ÏÅÅ¥¦ô2Y—#F̘ñaS4KõŽ“pr1!ˆ±‘LV^T¤;n~µøBð- 1eggÇÄt Z³fµ‡‡Ç“'O¶oß¾té²ï¿ÿÎÔEìf`å5ˆ±Œb,ãcc,óéÔc>%aèL>y,8ÀnÐŽ`|ìkÇ2‡¶æŽbs( ÛÀ! êXÀvÐŽlbiióß'M]ŠWÂÂ:ÿøã*S—s1Ô.'çÞĉ“œÝù| 77Ïøøi>Ò“^&ëöÝw?4YñšR3Þ5Œ«n× \>ÂÃyÝ]»#q#•4gÐòX*;ûFLL×àà 5kVyx¸?yòdûöß—.]öý÷ßšºhóUçv¬^A½¢œ¢£(3ùSfis* »&XiÚ´??ߣG 4°mÛà>}zoܸaÁ‚OBžž>ýµK“ÒÒÒ&%%uüøwSSÓfÍšã|¤Têàîîµk×ßÌ|¹\>jÔh‘ÈÊÇÇÿï¿÷V[­[óó är…R©ÃÛoÓdøÕWKFcaaÜþܹ̋/…‡G …–}ûËåL²ÒÒÒɓ߷µm-·>|äãÇOô̯v×JKKßy'V,n¥]lc0y•Lú§ZÔ-ÆêêÚ5\^ßo °O~~þ‰ÿ&$Lçp^kø—H$5­ò믛£££V¬XFQÊ'Oè,%âÛo—ß¼y}÷î¿ÒÓ3.ü\³hÕª5sæ|œŸŸ»xñ—±±‹‹‹Bqqܾ}çÔ©”Ý»w._¾¢¢¢B'ÃÜÜ܉'}öÙ§÷îÝINþ¯wïÞšEß}÷Cß¾}ÏKoß¾ÝøñïΚ5{É’¯RS“îß¿ÿÕWK˜4qq¤¥:xpÿ™3iryÑ!ØÛzª_í®­XñL&ËÌÌ?~œ¦Ø Vû 3W·k…üVüô’t#!Y#Œ­AgëÛ·oÓ4Xs>:¿hµßV³Ê»ïV¶3¹º:þùÂY³fýõ—ÌœqãÆDD„!DûÖôéž;—ÜfçÎÝ'Ooß¾-BhÙ²%‘‘2œóóóBô•H$NNþš¥C‡ž8ñ]„ЧŸ~Ôþë¯wïÞ!7ù?þDˆÎÏÏß±ãÏ#GFD„!„6oþÅÝÝûôéÓ¾¾>ÕÎŒì\u׆%€æêX`æj½ï¶n1–yôy7Ÿ¯ù”š¨c»Á8ï éÀ¯R-GÇǵbß³tÌŒb\_pÜ´ÐŽ`|llÇ2Ÿ¶ó) ;@ó . ÊìÆ¾Ë|ÎÓæS@cËɹ·hчÍÏ/°·oýÆ>ùd®‹‹sMée²î#F Ÿ1czS²™:˜¹ZÇn€k…€f¯¡O~ÍÎÎ ‹¼{7g͚ϞMûùç5åååK—.7àa±µgþèÑ#š¦Lýh[s›h Æ€ZL›6ÃÏÏ÷èу lÛ6¸OŸ^7®_°`>BÈÓÓÿ¯¿vkRZZJSRÒÆŸšzjÖ¬p\èèè®?ó/¿üÚ×7èË/—<~\ûã¹Â¢.übøð7¥R'wwß]»ö0óÕjõüù \\¼ëÎegÎd „vïÞëíÈ$ؼy+Ž 9†R©Tb±äÔ©3õ:CAŒeï¿—H¥š‰¦¦.+Ñ4L05édùù'Nü—0Ãy­s…Db[Ó*¿þº1::rÅŠ¥UþäÉ=ýù/Yòåܹ8pÐÃÃoðà{öìS«ÕzÒ¯ZµvΜòó/^üylì¤ââb„PbâœÿþKÚ¹sGvöå¡C‡ 0¸  0&&êîÝœG#„RRR%Û””T„Pf暦;u‚§и Æ2ȇäç_ÓL¦0u‰Mäöí;4M6Rþ–––“&MHMýïòåsmÚÄÇ'¸¹ùÌ›÷é­[·«M?nܘˆˆ0„ÐØ±oq8Ĺsçårùš5ë7n\æîî6wîlï}ûþ±³“ø'%¥ „’’R¦1¯““S#"Âx<ÝÇÙš¸bX1–É; ÐæTvM´tü±“Ë3Svö íEþþ~_ýå½{7ßygì7߬˜þý³g3•JeJJªLݘ{i,&¯²`‚IÿT öÝWh` Òú‚ãØÇÛÛ !”•u=88¨êRìõ;‹j­ú÷ïsùò9æµ§§‡ö¢GoÙ²mÓ¦-yyOãâÞ‹‹›TmU¶ˆ(ŠB=‹Å:‰cb¢¿ùfyRRJTTg‰ÄÖÇÇûÌ™ŒÔÔ´©S?Ð_N@ñ/Æ2ŸðÆ|JÂpÄI¥’=º­\ùÓˆC ‚ÐÌ/((”Hl­¬¬är93'/ïiYYóš ˆjã-KKË€í9{öìß´iËѣǣ¢:ÏŸ?wäÈa"‘Èð¶iÈáp>6bÄPE2Ytlì¤={öÊd1ÌÛuë~~ñBaxþ¦5`;6^+€&µrå·YY×úô¸ÿ+W®9rl„ɋ}‰ê֭˶mÛ …B¡˜3篬T]]]N:•››WXø\扉sfÌHlß¾mVÖ…“'½óÎØ:X!›VññïOŸ>c÷î½>Ê̼ðÙgÿËʺ†òðpwvvÚ±ã/æâ`LLôï¿ÿÙ±cûª-^£ƒ Ðì5´×E` FFª««K\\|HHçI“> sæ$"D/Xð‰@ÀwròèÔ)²oßÞB¡Yeöì™×®]wuõ ê ?ó™3§ß¿ó«¯>÷õõ6¸ÿ‡ö[!zùò¯§L‰›5ë#/¯€‡Ü¾}G*•0‹d²h.—Þ !Z&‹"IR&ßl¦ IDAT‹6u/–†vs€Øw­Ðœ¾~æS@ãòòòÜ´i}Õù¶¶6ìѼ3æMæEûöm5ý®ôcú{(##UûíÝ»×™A|öÙ¼Ï>›Wu•mÛ6i^;99RT™á›35¨c»A;³±@3ÀÆv,ÀVPih9  ÀøØ×Že>m!æSh~ ŽlǾËÀ¤õÇ @KÁÆË|ÎÓæSv€Ð˜|òX þp€Ý ?€ñ±±Ë~øÁî‹/ìµf(*7Yi ùƒF,ÀzÐŽe„„gOŸ^ÑL`ÐÒääÜ›8ñ}ggo>¿•››_|ü‡>2u¡f Ú±@ÓþX€¥²³oÆÄôZ³f¥‡‡û“'¹Û·ïXºôÛï¿_Ö[ô豓“#†aM°-€A;ÔbÚ´~~¾Gî4h@Û¶A}úôܸqÝ‚Ÿ „JKK'OŽ·µu‹í†ëñã'Ì*aa1Ÿ|² _¿Ánn~>>Á{öìGýøãš€€šl+**lmöï?¨ë_~¹Ä×·í—_~£É\°°˜… ¿>ü-©ÔÅÝÝ×®Êçü¨ÕêùóÿÏÅÅG °éܹë™3¡Ý»÷z{1 6oÞ†ãGŽG©T*±ØîÔ©3u=Pm싱h3`>%aÓ~r¨Ÿüü‚'N&$Äs8¯5üK$¶¡¸¸iii§ÜsæL’\.2d”æ£þÓOk-Zpÿþ•+WŒónvöÍ·ß“s/=ý,“`ß¾<¯_¿Þú °dÉ—sçÎ>pà‡GÀàÁ#÷ìÙ¯V«õ¤_µjÝœ9‰ùù/^W\\‚JLœûßÉ;wnÏξ8tèà†ÆÄDݽ›óèÑc„PJJªDb›’’ŠÊ̼@Ót§NëyÈŒÄÔ5µ¨õ3̾ šÒíÛwhš jSuQ~~ÁŽ­\ùmDDXPPàæÍ?gf^8}:Y:jÔðððP„Pÿþ}ºu“mܸÙÖÖfР[·ngüúëocƼ©ºUei)ž4)65õÄåËgÛ´ ˆÿÐÍÍoÞ¼Ïnݺ]múqãÆDD„!„ÆŽÍáçΗˋ֬ùyãÆµaîînsç&úøxïÛwÀÎNà—””‚JJJMH˜š””ŠJNN‹ˆåñxõ>^gÎd¤¦žš:õƒj3Ú±@©TÒ£Gו+W“$©=¿  ÐßßÇñÓ§3˜9>zðàaPP ó6==C“øÌ™Œ6mBgܸ·¶nݾuëöñãÇVÝœ¥¥8 À™˜«uü±sÀ€¡‡™?ÎãÇwV¯þ¡cÇöîB›6çðácUÉdQYY×÷ìÙ'“Å „d²èuë6¼x!×4Îê Ú± +W~Ó£OŸ7fÎLððpüøÉöí;¬¬¬¾ÿ~ÙèÑ#fmذF$}øabHH¦/BèØ±6lîׯ÷Ö­¿Ÿ=›¹aÃfþ»ïŽ ‰¤(j÷î†l=1qî®]{Þ}wì÷ß/óõõ©GùmlZÅÇÇMŸ> Çñ°°NOŸ>Û½{Ϙ1£Û´ ððpwvvÚ±cç¿ÿNFÅÄD7±cÇöU[¼uÅÆË|nO3Ÿ’Q` FFÊ¢E‹ãâ¦æç88Ø¿ñFÿ9sBk×®œ9óã¾})•ªÞ½{lÙ²As©nÖ¬÷îÝ?}ú,ûßßàÇÌ l×.X"±urr4dë3gNÿµv×oùò¯%ɬYs=z,‘ØvïÞU*•0‹d²èÝ»÷2Ýóe²h’$ͦ3Ô±€ÝØcÕz³ä‘#V?ÿ,½xQ(—çÏ_stTU›lÕ*»õ륅…œÈÈ’¥K¹º*^@³áåå¹iÓúªóÅbñúõ«Ö¯_Uu‘M«={þ¬:Ÿ¢¨§OŸÍœ™`ঙaÊÈHÑ~{÷î5æAŸ}6÷³ÏæV]eÛ¶š×NNŽUjøæÔ±€íša¬²2¼sçÒY³òô¤ùã›eËì¿üòñ±c7x<úw>™™"ˆ±Æ’‘‘\íüâb}Mì€æ„1V~ùÑUÓrH“JUšEvvêü|NÝSÂoPhýiµ988:ô_ çCc.ÙNž!@Õf™KiM3dÛxÙ–b×Ç ²mÔœÙQ9°/ÆÒ¹›×‚Òn»Ò,e^Ðt5wÿr¹tPâôiqŸ>E¡ü|έ[üŽËêtŸð“'F‹s5mšw¶”6“gåÖD®³5D#eÛx9C¶FʶÞ:ÝrèüõÍøcÙ6uÎW`dÔACšaTTD\½*¼}›ºqCpõª°´G­[g—˜èʤ™4éÙæÍ’C‡¬oÞ$&ºúúVDGC‡÷&RDÚËIS—`æ 3`½fc8aÙ«—ßÔ©n¡·ÞòêÕËïâEB('‡wåJ倣F=OLÌ›7ϹW/¿Š lË–»ßç¦a`œœ{'~àììÃçÛ¸¹ùÇÇÏxøð‘© 0kì»VX뛡CŸú¼êüÅ‹j¿Ï‹oÈMÔÆÉæÏÜr²-"í¢«^44ÏÒ6}ÎíKfñã';ûfLLÏàà6kÖüàááþäIîöí,]úí÷ß/ÓN¦T*™§8#yí¯Ï®O/»²EA Ù0„Ð:Ñ÷Fk„Ð"ÿ9……wtRØØxn)ÚBÒ¤©BÄ!0b)C¥¤¤Ý½{«¢¢öưÀ@O_gçÖš9ryiNÎå’RÏZ:…;:ú=~!TQ!7tç£c‡'O.˜ºìó@ÙAgŽ‘«§oháþE“J §-M7´'@ïÞƒÊÊÊNž<¬ýÐÀ‚‚B‰Ä6,¬K¿~½ÎŸ¿”šzêãg%$L™1ã£;÷(•ª>}züøã æ¡„aa]z÷îž™y1+ë:Ç]¾üë!C6°T͆Ñee{‹Š‚L]–NjõÃç[ë̱µõZ½!´eó¶œÅ—ØØŽš"Ò!a0gùù'Nœüí·:Oe–Hl™?ý´n÷îß÷ïÿ«´´,.nÚ… —ü[,¶HH˜=dÈèôô“ÌS¢úiÝÑ£ûÃÃ;|ôàÁCÍEÆôô MÊ3g2Ú´ hÌRLb,`b`ó·råò¬¬ë}ú Þ¿ÿЕ+YGŽŸ0áƒE‹¾ÒI&•JF‘0;#ãÜÕ«×bcß éÊ,=vìß ¶ýe»|¹ã_<8|ø:GÇÆz“¤î]Ù†¤Ú,qhÁ-NFFÒ´iq¦.»@„e|ÇŽY¿õVþ®]7–.½wþ¼hòd¯ªià¤fDìkÇjJ6´~çgýû¿@-[v/$¤mZšX&+®k ˜Êž=Ùš×Þ{Ï«¸˜°´|mP8©´cÕH©Ä®^FDT>MV*UûøTœ?oQ×4@,0ee¸HD …”öL8©ÄX5zþœC’˜öµj©T•ŸÏ©k ˜ƒ’âÛo'N|Êá¼vMNjÆÅÆ×déé—ÿVnñå07tÓ¨¨H…R‰Mžìé䤜=ûq•ƒ '5c2BŒBÓMÓ4MQMÓ4BÃ0Ç0 Ç0 Ãð’’ç ßP³±QŸÏÕÌyöŒ­®k€©±àôнûÀûΞ`ꂘ èdÝX”Jì½÷¼+*ðmÛnr¹º_ 8©—qÚ±\\ÜišFˆf „0 Ã0Œù?==ÕÚÚÒ(BMx7/—K•Ÿ9#îÝûB(?Ÿsë– C‡Rí’Àv¡cÇŽþôÓ4sú÷îáá¶zõw&,C&ë;bÄ3âM]ナÔèT*lÒ$ïçÏ9۷ߨªGNjÆe´k…Ož< (’$)Š¢hº²†a<OÏZáá_gˆiœ¤i¦e{ùôz Ã0’¤ôdÒx&N|úÉ'n¡¡%ÞÞŠÅ‹]||QQÅ¡õëíoÜ,]zOO€€3•hMžì}ù²è§ŸîÞ»Çgfúù•s¹4œÔ‰éû¼ÛÛûÚÛû98ø98ø;88:8888ø;8øÙÛûÙÛûæåÝ4UÙFŽ,˜9óñüùn}û¶©¨À6mºE4BèÞ=þÕ«"ýi-DXX×… ¿>|¬TêáîÞf×®}Ìü­[wøùuärm¥R·ßžÈÌT«Õóç/tq ì:wîqæÌÙªÖ”F­VöÙçnn<žÄß?dϞƟœšzzÖ¬y8níèèÛ4û XJ©Ä³~ú”;j”_ß¾ÌôèÁI­Ñ˜EŸ÷’’§4MÑ4EÓde—.šb®<òx‚*É›ô=eJî”)¹:3¿øâ^­i-ǪU?ïÝ»c×®mÛ¶ýû~ïÞÝKKK'NŒß°á§ž=»ÊåE§Og0)?9{öüÎ[ì·oÿkÀ€7nœ—Hlµs«)͇~üÏ?‡×®ý!8¸Í­[wÔjõ¯¿®Ïɹß\¯B3¤qñùäÇÕÄôNjÆÈ1V|ül‡ÃårT*µ……Å_Ì3pÅôô=Fà8Æ\5¤(ŠÃáu1nñ 1Œ7:""!4vì›Ó§Ï>wî‚Tj‹0 Dbëääè’ˋ֬ùåòåÓ~~>¡¹sgîÞ½wß¾ƒ±±c5YÕ”fÈë×oÞ³ç÷þý{#„\]M²§ÃùZáÒ¥‹(Šºt)‹$Éyó>Ä0Cï éãøóçy/^<}ñâ)ŽsÂÃGXY9·xÐ<<Ü5¯­­­äry›6ÑÑýü:¾óNÜ–-ÛËÊÊBYY×U*U@@'·f¦ŒŒÌÇ_k0¨)MVÖuµZÝ­[LSï ¾ŒcYXˆ¾újA‡Á_}õ™……Èð9^ûö½llB66N11c¹\Aq1´ULÏçUT(´ç”••óù|Í[ß“4Mã8~üø¾;6;;;~ñÅ7!!1¥¥eE!„ŠŠS”\3}òI¢öº†¤°‚ñûcYXˆ¾þzA=V$N»v=®^MíÜy$†¡¢¢ÇšûµÁ¤€:jh­áëë}îÜM>W®d5T+gºêXŽ8ŽõêÕµW¯®óçdkë~útzHH{‡søð±#×PHºMÿjÓ0óOžLéׯ—ö|‚À™»³¸fCPÛö3‹>ïA´mÛ!º¨(·Ú š^\Ü„~ý†/Z´dذAåååËþ¿½;‡2ÿþ}žgŒ3 †BŠrtèÐ¥-J÷¶¥c7²i¥‹Ò}Ù£­Ý¶¤_­¶ÔV é.E¢!¥$µ9"DŒ03Ïï'Ó¬ƒa Ÿ÷ëùcžïóy¾Ïg¦<ó™çø>;÷#„¦OŸ"d•RoÞ¼ëî¢rùò’$ ú0ª¾¾ —/ÀqÜÆÆº¨¨8:ú¼——§……E!1ß|3gñâïØkiiñìY6‡Ã5ÊEOO71ñ¾—×T:®¦Æh÷Ï 2±ÕX<—ú-…aˆÞÇq¯Çârkù¿á0 ±ÙEA D41Ô/ü´t¨‘#Ožü3,l×–-»èt{{Û+WþéÙSCÈ*JJŠ11±!!Û*+«LLŒ"#ê#„víÚ¬®®æç·&/¯@]]ÍÙÙQCC½ÁºMÅìÝ»UEEyÁ‚eÅÅï õwìE­ZµbÖ¬…zzêÏÚë# ØÛé†!„¼Hãgš¡M¦«KKsD0\’ËA„ ÑŒ˜ÀuDݾ}÷åËìÿûo.IòøBx= ÃqWQ顯oÌdjò»-/¯ÊÍM·°°),|†I=‡¯?@<†áÔ ¾ÚÚ&ee/BUUï:êÃH7--YmI–K:Ð2†³ÙçJKM%Â(*6ü¡¥¦f¸.kB(âèñÜ-,1Ǫ¬,c0TZ·.‡ƒ [V–Ï/ÑH’K  Óess3Ûž$@GjSe``d``Ôºuõõ-õõ-óó³E ÖÖ6iÝV$¢M5–๿–¢NüÉËÔ C}1œiddNÅH‹Îu_¡(8yI§p{²Ô""ao:3}}Ëf‰³Æb³«D c2¦UYY5þò›7ïÐh2oÞd4ÛCnnz+St'Lf?„Üž&…0»zйéë[6#æãXyyÍWHLfôNœ8›ûúÁƒkÊÊ=DÜ……¥ŽˆÝº6¶¤­gb"l?@»¢ ­¸\‘Ž‘‹ÿ\¡­í !K=°öæM¾¥¥¹®n žNH’d¯^Æ.b±bÔÕ™ÌÆ—ºº:–¤S­§£ÓÊ{ªh£¤¤‹}ú˜)3zöé?§ä¯Çš5ëÛ˜˜x„ÐÙ³½¼¦þüóÑÖ#B••E Zë‡3%BeeùâM ]””$h؇‰àpjùϧjºÌ‰äk¬ÈÈß‚ƒ·äçþñÇ~Ñ×¢žcE]ÐÊáÔ&'_°·Ÿòi É\ ’µsgø¾}¿–””:9 =p`¾~ïÖÅt7°Q?@'õš—˜mc3ŽF£ ,õ¦äk¬Ö"B$ÉãpêRScqWPШª*BñËOjÄy¯¼¼-ŸqrãÆ­¿™™™®Ÿ8ÑëáÛA´4¦‚}8!¿Ì ZZZÂÀ®ñ©d"E~\¹t×XuuÓÒâ+*J m„x$É¥NRïþ>íaóæqq×æÍ›5oÞL-áÁáá¿-Y²`òäñ¡C‡ö3™æ×®ÝrsÑÒ˜nöá@RøkH’KxYYAZZ‚••3Aüë‘D!­5UDfd\¯¨(AaF’$ÇÃqŒ_`’$W‚ºªmÛ6Y[ŸùóÏÈ·Žãº`ÁìqãFÑ» ©¦¦&--=8øjVS³§™™ñýû)‚õ“(1ÝìäðÏòxŸ®>zÿ¾ 3óŽ¥¥†uƒãXÔAzssÇÇo¾ÿ–j$I’z†´À,ˆyWУ‡âÂ…> údeeÿùg¤¯¯I’sæx-Xàcdd(YRRÊår555ø9ôê¥Y\\,˜’(1ÝìÃDà8ŽÕ—üÿ„ †Î!žÆ«ª*ñ:$½55BAýú9=~|‹ËåÖ_†FðË,øû´]TÔÙ™3¿¡^gd$šš~¾gÛÔÔhëÖ ¡¡k×® ݾ}ÿ½{®];/¼7Qö΢ïÁ»6؇IÁ0Œ*3H’ÇårTUµ†õÂ0TQñ– j‘(¤»ÆBˆ$¼_¿aYY÷¨Ÿ} ü}ÚÊÝÝ-=ý.õÚÀà?·ûååDDœ~üø[·©{.\ˆ Þ’šz!tâÄé¥KNŸ>êììXWÇÑ×·:{öX£å0I’$IüÛèæxŽ*W¯Þ@£¼zp €ï”——_B¡ù©ªŠíèh¼JH&'7nܶÿÖ””k²²ô‰gr¹±§-UnõßÑ\±LIIIIII•¢Ì¶eª/H„Iò¨‰ dX¬ëN5‹)úÅHíRc)**Ž9òõë×ü+>>^EE¥©x{{›»w“îÞM²µýJMahØ'%%íþý!5…zá¡;³²²eddøŸˆ¸ß|¶yó.cãÁ›7ïÎÏ/l6xÆŒÉÁÁ«í…Ä„‡\²dÞäÉãÌÍMÚ—™™uíÚmñå €dðx¤X&„µµµ¹¹…(³mÜ¿¢Àqüýû‚'OîR-úÚU0 IDAT¥ÆRVV¦J+Q ,„½½MVVöÅ‹q¶Ôì‘#ÿ+/¯ró'õ¼FêuPŸ‰‰Q]]àR‡›~íbÛ¶ ßÇÄÄëëôðð>wîRSכТ¦¦6--cذOE˜¦¦†™™ñýû)bJVz‰úØ]Ð aŸb™,,úéë÷åw(|¶mU<`H @är9ªªZC†x**öäñHªÄñsh—B$**ÊÆÆ¦¨¨H” !Ô»·®¶v¯èè‹Ô+{{›3g. `¡¨¨ÐÔ*8þ¹ÆRTT [+Œã8ÔX€vÒ£‡ÒÂ…>wî\JO¿maaê뻪wïkÖlÊÎ~ÙŠÞJJJ¹\®¦¦¿¥W¯žÅÅïÄ—/úŽ&IñLrr²¹¹/rs_ˆ2Û–©¾x ª 5„Œ'†¡ ©; ùåGóŸC{|¸***ñññ®®®¢X{{fmmE½ær¹vvÂNbþ¹PÆ0%%ÅmÛÖc ÆˆETÔY™^Ô”•õŸ‘ÇMM¶n]ÿêÕ£Ù³§oßþÍ7߉e‹¢ïÁèœê¿£‘´MŽãÔßY¯'V^žG]°EÕ"~í5vƒŠŠÊ•+WD?thÿµ–V¯ÒÒáñT!E§Ó›€ îîné韮Ž20è-¸(/¯ "â¯#Gþ÷ömñ¢E³-šÛŠþÕÕÕ‚(*ú|ર°hĈamH kö;ºÓ¢ªC„.Ço¬®.•‘|/¢⯱:æIé†'%ÝDZbÑ£‡’™Ù}®©©=w.æÈ‘ññ×l‚‚ü===ä[׿¬,}à@ËÛ·=<Æ „ŠŠÞ=}ú|ȯÄ:Òìwt§…ã8†aéé—„ÄHæ8“i)–gŠ¢²²LE¥‡ð˜f݃˜Çð÷_{æÌ…9sfìÛ·ÅØØPøVÞ¿/ÏÍý÷Ù³l„PfæÓwïJŒŒ ””÷ì9™ùôС½¡åË¿Yºô[SS£ÀÀMææ&ÎÎCassI§ZI”ïèNKÄgŠ¢ù«¬ì%"Dê«cŽ`‰ò°kh'+W.Ù»w3&ÒoÔË—¯z{/¢^ó5BèêÕ³#F ÍÉÉMKË ÚgÏžþömñ²e«KJJœþùç8Aˆ¶ÛíÒôõ…=3€Î¯ù}ƒa€*:Ñó•™LMI§Ú£Ó¾}õEž1còŒ“¿lß*8°, `Yëb`o¤HDZ& ÇH Ë€ ÃὯnÒEVV®ù 55Ų]6»J,ýÐ(%%IgÚöÝ“iÙ1—tw0¨±€„ååeH:ÐeijZH:Ðz°sè>:lP‚5%ŸÅª}­Uú•9ûiCçøªj›«X¹׺O£û˜6mb`àÊ¡C…ýIHøgÉ’ù¶¶_Mž<>,lýÝ»IÔ¢üüÂààÐv ÆÏœùõÔ©_}5ÐÕuøŽ›JJJß¼ÉÒ@**ÊòòrW®ÜàñÞhBÄž=¡ÏŸßŽ>š”ôpãÆí¡iÓ<²²²Óë÷~ññ78Ž»»+BÈßÝõëwNŸ>’•uoÒ¤±cÇÎ())¥Ï¢ùóW¯zõ*õÖ­ó#GŽhïw @×àââ±iÓö©SçXZ:X[ˆ©/?~jØ0w--Ó¾}­W® úøñ#BèСW~LMM­ÁÀØØ–9C5ÄvPFúcÛÁ¯^çÇÆ]‹¿þ,û••UÿŒôÇöƒ[ÓcM-‘þ„coCÍ‘=չƆă4„쯇Uõ­¾\Cá»5´¤‡•ùp«ø äý "?Ý­-÷Ó¡º1®)Wkæy+Í[Jdç‰WXJ»}¿êدåÉWëÆVš6+ýÏ/*V\P°¢<ýö‡KQuΟŸä(ûDZß/~ÿâaõº}ý±Ê*jCDîëñg*#“ûéV[Óš4Íf+**ÈËË#„H’\¼xåªUËõõ{7\QQqôèIccC}}=QÚ ÈËË8°+<üwMMóqã¼¶nÝ_PðéWÙœ9Ó]\õô˜ŽŽv!!k¢£cBL¦ö°aCøg«£¢ÎNšä.+K//¯8pà蟆bݧn`à ##ƒóõ¿ÇøíóÝ»R„ÐØ±n::Zææ&óæyuÜû@Êýþû±  ¿ŒŒ»Û·oX°`EvvNƒÇ·lY—’r=2ò·‡mݺ!äééñï¿o>|DÅÄÆ&Ðé2®®-³M 5–‹ó°¾†zi©ììò ‹s_å[YõOge˜š:kÍÉQ¼¬ q¹dOu~ ©©¿+A‘:ZëñXI=ú"{ûFÎW¹fÆU¿î"=¦=H¥–Ö¹8ÕÌœÆÓÖú¸â[ÎWé‘§šŠÇ*>ÈþyœýËÎWyzÌß/æô‘¹œÐ`[¡º‘#xZ½¸&Fµ3=ù‹j¦Mâ|5!T;m"¢Ñˆ´t¬¤Œ~þ2{ûF®¥9×´:4qàŒ§ØTVV†…í^¼x¾ŒŒ BèàÁ#<oáÂFîo¸x1NYYO[ÛìüùK§OGRñBÚhÀÇgZ~~FDÄ϶¶Ö'Nœ¶°Êbe"„îÜIrt¯¤ÔÇ5'L˜ùöí§!O¿þzRTÔ9„PMMí¹s—§OŸŒÊÌ|VWWgffãšÔ”œœšŸ_Ø`[öiaa2t¨­‰ÉÙ³}#"¢àj0D7qâXkk+„›ÛˆaÃì"#O5ðòšêädÏdjÛÛÛù_¼‹b0TGvýë¯h*æäÉ3S§zÐhD‹6-žkÞGÑ[OûQkðà¯Y|òä©©‰¡«ó°æ×QýH‚µÇVžú³ÁB";ñx\ÛAÔ,OG‹ÇÔ&²²©Y®õ~$ÇÚŠÈzÞT<‘õÕq”m\j†ÔDKeá…E‚Ûâšq† V좸Ø~ò VýyOÇëóù(©Ü«ø@<H’*¼BœýѲДššZ/¯…L¦ÎÚµ¡œœÜmÛöýúën kdÜÂáÃîÝ‹¿x1ÊÜÜdêÔY•••ÂÛø’¢¢Âرnëפ¤$hk÷Ú»÷›]=aÂÌQ£œssS¹Ü·W¯Fsë/õôœðâEnZZÆåËWi4ÂÍÍ !Dj¬¨xÉãñ§ü^p+Mõ‰ãxB™¿þúÉÔ ÝemíRUÅîðÏ©daa*ø:+ëyƒ€û÷SÜݧ1™ýÔÔ gÌXPTôéV*ooÏ3gÎ×ÕqJJÊnP?–ZDl÷b†!„ã8†ã$İÖ¬Ìc0A`Å%Ÿ;[ÌÓP² •AË6óe¼š“óêÞ½”ö{t%§Ñ×”êêê3¸¸8±X·KJ^üóÏÿ¸ÜOW^ºº'ZBÂÓ§ÿ122´²jñCÅó•åÆ¿o m†Ø<|˜ú(õ‘E?óÌ'/®^»ÕÊîdéÜþæ´Ädj+.!žçpl*œkdˆpœHþtrÏ/Äó ¸fÆÔ,ñŤ=|Ä55n*žkj„h„Ì՛ͤ‡ãuÇV¯ÿ¡âÆEâÕk"¹‘ëâ?%fÜ‘$Qê‘‹jëšé4§¶¶ÎÛ{aiiÙ™3Çä©ÆÑ£“’îÝ‹§&:]&44(<|{ƒu¹\.·±T›j!TRRææ65""ŠÅÊd±2ÃÂöÅÅ];vdïÞLYYú… q¡ìì—{öü*¸Öôé“Oœ8sþ|ì×_O¢Z U_ßyË—FGǼy“ÿð!+88,33Kp­¦ú|ð m÷î_Ÿc±WVV!„ÂÃúúú#„H’ôö^˜––òcNÎ+ë1‹õ¸¶¶NYYÙÂÂŒ?a¦££Ó§BÈÏ/èòå+©©¬¸¸«Ó§Ï“——ws.¤€””­­ûïÚõ³Ýh[ÛQ'NœÞ»wó‚3 ÕÇ÷ûù÷é3hÞ¼å«V-\kÊ”qyy…ŠŠ #F8ðwíÚ´dÉ}íÚõKd䯆†}:à½Ðܸq'22ª  pß¾ii¬™R#„tuudeéÔ ƒ99¯~ùåÁ¥ÞÞž11q,ÖãiÓ&¶bÓbç=ñ^ÊÈÑ#ï'Þ×Õí5êÓÅdFúc«nÞ¸éäØšËÞkgLÁ‹ß)¬ÇËÊêìm+OüN]É„åÒ’Q†½7L~Í&¥)³QmÇyXÕÝüjæãÒ…2ãäW­#{õ¬ü#œkÜWH<;4HN¡Šò Ž£=OM !„¿|EËÈD!%™¸«rÛ÷cUln_ƒªƒ{xMÜÅö)±}aŠ+Uû;ðÔÔj–Ì“‰¿ÞŠO£ûˆ‹»6wîê5u¦ïòå¿^¾|EZSS{éRÒ®aÅ%¹É:³ˆˆS‘‘§y<žŒ 퇖zxŒ¾s')00455Í®F)+÷@YX˜ jcbb7nÜH77'OÏ ò ºÊÌ|VWWgf6T°qâÄÂ{/Ò¾€´kXcqG"yÀ—âÒãBÃõ†ËªÊ6;Û®<+W~}D]qãFâ„ ³B8Ž'$œ¾zõvBÂÍÐÐ=[¶ìKI‰WTTìŠÇã!„**^())¶wÚR ¾€´ƒë±Ú¨þ£†ëq¶ý¨ª*[Zš™™QÇ¥ž?Ïyÿ¾< `©†††aééOø‘8Ž»¹9……­}øðJNΫ{÷RB“ä§K¹-,Li4ZlìµH A cÑ`Ä,@§áÚÛÕAÉÕïš„Ïv¤Þ½ueeé.Ä{zŽÏÎ~¹gϪýÁƒG7o&º»»ª¨ô¸|ùI’½BzzÌÄÄd/¯Ét:]MMÕ×wîòå?â8nc3¨¨è]tôE/¯)&ü.:9ø>Ò®áÿ`#$’|IAU!¥*Õïš„Ïv$Cåðá}~~Áþþëz÷Ö]µjéêÕ›BJJŠ11WBBvWVV™˜FFþbhØ!´j•ï¬Y¾zzƒ44Ô ÒwíÚ¨®®æç·./¯P]áìŽëìÞ}ßR[ËéÙ³Žë>Ó¦M[õ““––fS‘3gN9{6fÁ‚•¼¼&çÖ‘y:‰–ÕXÐmÙÙ}¥  pëØ±SË–ÍüË/ÛLM””ccyR, ;hٹ¿NDNŸ<Þoù’vÊÄŠºCM\£ ³fM ÙýøqÖ¤Icø‚üéñã§••ì÷ï+JJJ%=‚4Nt-«±žg=½tñÖkí” tf>>žwî$O:¶ÁM… TVVÍŸ¿rÝ:?Qóç¯$I(èŽà\!ˆJ__¯¸ø±‚‚¼ð°U«6jh¨.«¨¨ìßßyÿþ?¾ûnaÇdè;kkK1öæãã9mÚ¢°°5QQ眆hiõ\:gÎ4ê…žžNHÈ~~¶ný‘j™>Ýcøp;„¢¢Bˆ$‘¯ïšëׯ_?­£ÓKŒv1ÏŸß—t ´IÃËÖv†Dò±ãp2ÄØ›µ‚‚|BÂícÇþ^¶l^ƒ¥wî$nIMÍ`³«BÊÊŸ¯355ŒÜ¶í'‚ ’“c455Ę^×ßG@Úý§Æ2Xу{9]E]]ºx;œ5kjHÈÞÇŸMš4¦ªŠÍog³«'L˜³rå¢èè?ÔÕ7nÜ›0a)Fvâädwá•˗¯Ïží)Þôºø>RÇ`EÁÙÿÔX>Kg¡¥›HŸ©6ìš;÷kyy9Áëùó—ïßW,‘““E¥§?Ò‰ƒÃà¹s¿ž2e¡’’â”)îíž´´ÂÖem“t´ \ó¢Ò××+.Nÿùç- Ú{÷fÊÊÒ/\¸‚ÊÎÎݳç`ck6jÔðÈÈðÙ³WÄÆÞh¯\’FC%Å'J:»àcÅÞ§ššê— †Êáûýü6øûoìÝ›¹jÕâÕ«7 ïgÒ¤1¿ý¶}Ú´E11dž ³{ž]@ÄÑã’N€6³Ý€.«®.F³$ɵ7wÈw$I&"G†èÛyÈ}#4‚©YóÙó5ªkQŸÏGv ­Âù2iîï"*C–µPCIdØ*ˆø¹7j`@‰íãŸa VCxµn5…X~Äèv`´ãônJ¾ñŽ%”¦³¿#ZÌa·‡=iÙE»ë…pƒ²öœ9ƒ)§ D™.ïª7éa³ºgL‰DÚ̇„p! 5Ã^›=ìQB^ZÞ ™ v)„_kÛŸåYìd@ª–%P|ŠUSÜ dÊ6³ÃÈ—A$>M@ÔË•¾ö6¯K; ü+·° ýBdózQ»ô1÷ԊȳÏfQÈ1Á“ñ¥ä2ʈÈVÜøL¯Ë|Ìæ`¾°X«¿Îð'Ãv°­„9|1kJ± l{¾¹VäÙ²ËcÍÌg&Oøµ?†µ° ©™Í…Ol3_4ýþÊ/Q(™ÀÄÚ©”/Û¨pm™k½¨úö×n'óùË çi€Ø¨> &úKý³£C•ͺ‡|»têzÇDôÝè!²\|<Ü`Š3‹cpÜdy£83f=¼°Ô°s3x‹ïCNè]=¶C×Ç-Az¤*m¿ Ǹ5*$¤ÔO\û`,<•ÇõØúk1ûWîü±o€ÕT±×Žª ‡õû .Ös;t}ÜlR¶_cP䣬ХV}\€ä\+—ÖÊ‚røvÍäÅšHÍL«DjÆÜ¢IT…1ï±$v4Óà qÀË£n‡nË­Aºx‘AªÐ v ®ØÅƒYn%¡Ëäµë“¯€ 4ȧY°$òø r¦k Œ2øÕxxSKõ Âfºœð¤}}Ÿ[%‚ôáA±®Ñ†%Á°BkÃìVÎ-g‰’׮ϥ6VMoœš·>*9¨˜ÀäÌ$§Wª"ïD¹>FR_W¸¶$v0ÓÅàä€w „±Ï Ûr‹"H/¢X×hk`¨PÒ‡rná³ ¯U £áÑ ÿ‘²Ø+9g†Ô–â ³Wd¨Ýé¦#Íü±n!uYŽ=w2ðÙ<ÿ¤t‰EÁvA† Î Å‡_7¹ ßÿxO‘¬k´Ür–ÍÈܹ¥Žm§Ü¢åÑúNºüÏÌ,°ˆÝä>R3‘™ƒÁSÙf§žîsKnôÇ:„þ…ÄŽfzdž9AŽŒÏ]á>ÈÐL.öú¨´ŠqâJºBÕ‰= ˆY¶C7¾ßºtqõ¦çë[SŠu•ö–b,¸ÂÎR\ŽDœ¯¢%Z^³>K~9ÉÖ™(φè…e6^*$yÁ ×ÏÞ3SØk?ÊÒÕƒUvAb;í¯á¡oO|o„¦aŠÍ³ÿŽ1xŠb]¥-°»Š›¿(ï±¾\ÛÔóuØ‚ÛÍ €hM[^¤ëv³™+* R×ÎÈ_BöA³¶Y\ºÖMO.ž¢‚T¥ý(ª'K´¼F}ù0=ß¶bR/xšãœµãƒÕR/@c·›¹0¨‡T[ ÙݸÅ?X¿‚éôÿ%잺é†öƒ¨ž-½)OÛŒû ¶±ìKä_‡|s\‚tG»=ª_uÁ†}ûoÄù@~!Höµ¨¾à€?¾AïˆZaIEND®B`‚snd-16.1/pix/fmad2.png0000644000076400007640000033761411147553266012662 0ustar bilbil‰PNG  IHDRÈaº^r[sRGB®Îé pHYsaa¨?§itIME×  .¾z, IDATxÚd»]mIv+sŸª{»{º{¦g8œŠ&Eš" Ùm=Y€,Ë€þªþ‚Ÿ 0`X¶dÙ’e‰ $R磧ûÞ[uÎÎ\~Ø·)Y®‡BS¹wæÞ¹23VD,Þ»ÉõÈ$ h†À|×NøøÃ ×wdÀDÈ«ÿƒן  ñ] þÅ/$¯fùÿ݉øÝ÷GCâ/Æÿ¨SòãȯîIp¾{ÈÿO‡¯G®'ùîp}Ï@LçãCëºüj§4Éë^N""TBåz=E`d¾ëˆŒP‡€ðºgxuv _@0H‚ÀD‚ ì„”&‚4ÚÁ‚oœ$B@„Û‡¢ˆÞW—×»D7û‘ «X"€Þœ7x#@ TEO–¾ E"ÉGw D ÉÇ9¸¦‡ü÷sæß¿jþ1˜ïbŒß`„!¹^’‚\¯I3º¦¥Ê$2îˆû† ðßGúǨúâᚉ빦?Œãþ‹Ææ^@¡6T€†.Ѓ` ¨BÎ;êÆÀN¿'0à—¬üO¹SÊ:ýa7[þôÓ4õ,¦Ï_ßçxÅ}QÀñŒçÊëFa¿Í(ï¾Ý~€çÅû‡óÝyT=ö¾}ï9Ä~¿ªÊû5Òs¼û÷>9ßÇëñöœÑÓö‡ÀÓûWõôü8_Ä5lt i¯û™•z9{ÃÝ+&Ñ÷óäx.†¹ƒ©í~d;ã ‰ú±ÚÏ·7œÆ<}ö&çÂÛ¬o—œã¨Ë{ëéöƒã«ß˜ñì1¸ÖB’Ùð"òx=g ÷5Tk¿¾¼?ëyœß>êàQ˜óxqn©§›^ï¶Çë~_m4×jað6+¸Ícw¯ÎØëƒ÷‰½9ߎR÷f?Zµ¿þÅàT¿ÙŸ~ñéz÷¾Þ>õãõÜëõ>?ÿ¢øÐ¹¾Y.£nÂË»¯÷ñ¶ÞÜÞÌçÛ»×~ºÍóñçðíý{ÎÛñ½ï~?ß¿ÿðþ{zûîý7ŸÌ>ë_x|®/ê˧þ°>¼ÿù‡ÇíSœ¿z¿Þ|ïÓùF·±~ù‹×¯¾ø~:¯xùæ%7JÖ\šÏßóËÏ_ǧo9ôo~þõ±€€&T/¯/·©o^Þõ8Þyëf?”ãþøðö¸Ýëé–Ç£r¾Þïc|búùíí×ß~óƒO¿|y¼Ô¸ àý7¯ãvã§ÏÒF³„ôóöîñúöÍ› ô†çùúŸOì*GzóØCçœ2&[TíóñöóÏÜk¿ôn×¼½ôBïÇÓ1׉!$ ‰çz}9ç¼õº¿cC Ræ1†ûáÞ#·[´¹áã|ùðæíó:ßn´çzýOö“ßþÙïðû¿yûâsúüuþóñóMñ3|ýg_ýõ듼ÏŸð«þ•|Šóÿüã?þwÿöåøÞóýçæ³¼yº½Ó|ã~óÄ—µ÷ùôÚ¯Oyÿ89ž9øVË8ÒͽqŽìA©ncÞï¯×f¶Ûº=ï ûœôúðŠ ž>YYîVr<=¹íåcp÷CUIl8Ñ,¯Ýíq|ÄÞ¶«ÝEÇ@'¤Õ!:Ün‡‹Qè…å1ŸyÔëZGaÎç—³—2aÆf€n½¹õ^ûtñh…i´+&‰*#جšc­ÓÞn(À!IIÆ(ÞÏÒ<Ç ‰IÁ^ÔXM€³Øk‡d Ü„ˆ‚ÝÔu(\gþa:ÜM¡Û † ´²j‰)Ûm'3ÅÝ.xÛ"D%»‡‚Ҕмg”MžÝ‡ø4Êv€µ7¡SâØû™¢°óÍíw~ðåøì·¾üÝ¿ÄüßÿÃû›Oÿô—>?ž¿þöW_¿{$Ù{q­5õòîÝÓñôôôr¢Î^5 ­Ucx·êæOÇÓxøÝêÊæ<”õúL¹Fçj>Ч¡ }l7ÈŠQµ»»¯c—a¼ívͣѥr÷<*½ù°¥Î.)šMZ)ïn˜•‘e¹oÀLiN‰€"¦×4븙^{O¨j6rºMî`£Æ˜Ì>Ý[ éP˜µ·Ñz#‡Ü{ˆVÁN¼;½IJ¢Š -’šèU½3nwG$܃˜CYËÎ 41Ë\Ñ(ècl¢Ih ÆKën†TwC";áO-9+àtsV˜ÞpVLiŠÚK¤‘¢¶‹3*»Ó»Ä«Žªjï‚:ç¡¥½’bˆÇoÿ೟}þÕ~}ó—þÆ6þ—õëÛÓëÓ~Ƈwï±y›ÏÛë‘2÷Sn»êè”iÇUó@e8†!K#òZ÷ˆÐÁ^~ôJ½ÂOÁt¯Ý²º(t d—´vóÚgHl ‹cn79¼ p¿¶PâBjÚ.üÆÝûLÝÆÞ½³ —Ã:T`ºêa<…ìÆ<2jw'5 û$‡5$zo€ƒ˜mX(ÆlW Ä“ß@ûlcè6[1¹³ñò:žßv´ƒî-HÁ€z¥Ý&r6`ˆî®àÞ&dˆ£¸ŸŽçqäCo9lÅú˜ÌÆî6ÙH³Ü=DmCÖ¤v³Ðé8ˆ°wm7Ь)8nêŒOj¨F'{-ä|<ÝÇí¹÷I@‚M£ÃAVРCFͱÖ>7o7Šc¸í¾?ÎûûÇY+ï{<‰(VQ[ˆæêLBs*’¬NÁâH²;!VVh²àì•pôÞ{ *ÄîˆÜs¶7ÎÀÍ´3§ éÝîy(é¸ ºˆ7Æè®AºÔ1šÓ‰[ Ì")³ ê6´{‘Îàfìð <¼…˜Úמڶ›¦CkŸOî†wƒtlÐ^Ä<%ŽÌ´í¶à¸-§ÁUu…ÉŠy ÁödÌqÜVzíÁ+ƒ6૸r¦7Â`&’›Å;0 €;DÝúuÏ”KW>tÖ˜2 Û-z!šš¶ZU_óîG_ýä±âè¥ÛÛ¹Êý­B¼bjiTÈq?ÂÛŠn`,nbÎ; F5Å œ÷ÌóT0ˆ€‰"ü(œ;“֕Ћ‘`ã±c·j»¶‚mîVš@“á‚V2W˜jŠiÕ\è°”m'¨ØU•XbPR@޳œi39 Îîb·oÎ îŠâ~Üm8Ú ÙîÝèLb5”D¢ÃgzÖ¡½™½Å¤'å1^OS,sàµ]h5''a'JvŸ0èÆêURˆ@0ÃάZ†Pi_ÇDŽZŒ Û9ÍO¤ÁlFÀrK!ð*œˆES»̉ /GÎsÕfâq µ)EŒÊö*V”N« ¨µŸHM?âhnp»¯ƒåqÞ»PÉøvï¼ýü~þó¿òýŸ€߯§‡áÒ7èºRñtˆG£*4Œ"¦¼=Î=HÌÑÁ ^)ó(ÃYÝ*/n^lL ìTÀ"Sd³†r·­oI–Ò“LÊr2#¥à}HµF:Ô>†L³U§E㚟2Å9‚=U+aP5Šð˜o€…Ú1ˆ{ìFÐ4òÚè/¶è;no¡;`‰•nƒ …`[†“n AìîªÏæ! уÝë-ŠÄ``f{í]㢓Ún©é苸;{H7±+3|l4tô5ó衱i4¼aɉŒ–3nåË¡$I½5‹­v qb¹Fyˆc€±œ‚:0“šØ`K hä ̪ !‘=Çѯï¿Îêß|p¼VdÔÐþöÜÛu±s…lKÚª!©:½¶Š5ˆAº(¤Àa=Û!1åÇ+GÁÔ Òð°*£œñܬ4ˆ´/†,¡Ý¢¦c؃n_ÌÖˆ6ÅÝ¡T£,¨r9´‚@’:AËÞ}Óp¸ÈÑDU‡s1X©ëšN·!¥"G oa¬-0E‹³?ò¤$wHHFØQ ŒªM…YŽFUéa’ÑÝlt8UN€Ä[* ¥ Bƒ!‘ˆÕi1A8Ÿ½Õ@ÇØÁA¨3D—ÍR¢Ãˆ[Ž!6h°_\£lš©:‰ÚF7Àµ»ÔQ$ ܈ƒ¬nÁ‡ ·qš Ãà³ÁûiŸÝ~þDïß‚Äïß<ü’³uZiu;0x¥/ NÝðæ™%Ô6ÌBñŠ@tG*„{yk¶éä<½7Q4’È ¨‰Ç³­µhÄôp¿÷îE²“ÝŽ¸DƒFæíHaŒY5D6±Ü’0Çêø"¢ºÕ‹Ë"JõFUÔu Wî${¤Ûûâg Ûˆ¯¤íFvì•c¡J%&XWëvk„Hv¼k¤f“ÛÍ¢ª:Iª9‚B1$æqJîN¨SºN½E½Ot¹ô YO5&ÜU é *iPšÐ-4 ì8ˆª]ãL«PLZà$*ΨãÕO‡d fP' Ïs,b‹b Ã$ˆÔö¢÷¼olp£N¨ÖkÞ,$CÔêsºoÄiD!ÒéYb ¬‡³k3#ÃÔ™LF  Ä´Ó–8¹±M¨É8'8“9Ëã’Fº²}_nq0˜¼ƒ:éÞ·9±G¤bAà}-)»ÎÒô¹ßT5Õ@!3Y‡¤‰Þ±4ëÑ­¡$}Æ«=âJƒe܉QbMøžlúÉ! «D7*Q¢´På¬ÝMjB¼3q(Û;À¾I6ËÞgaX.AÍ>û•˜T¹×óÛ q±TMôf¡zí@ˆ3«z¸E¨„†ÌŒB;”^áGñ ±Æ%4a†Øû˜•µP5›£û­ø¼Ïw&YãÔ~â8ףΨHV£ËÈ©¤…M”w;z4r3ÂJg4žn~?öoc僻½ɱÕr¥Ä0‹CZçεÐÀÝjŠÀ%’)`™A£‚îX 4 H÷ÝoJݽ›I† ʳÆËùh•òǛ§ìG€I-‡©+H„iºQ$ÕÙ¨m¡ûÆ"Ò ® Ú¾œ¡‘UIVÈá!ySCð6 b€Ë@pXq£Jeð&–d¶ŠêÌÄL#m«„`u`51@ ĺÐxcÔP@w £v˜ÌÀAJ>ûé@Â^"íž P",ÁB¦Ama(ã6±:¡{iÔí Ò•çÁY$9ŠxÀì  B•Š–Û.Uq‰ÅU¬r@L²ÓgUµ÷D!PrRýFG·&œCþáñ—Ï_B÷hνše˜ÍØ{8s{XÕ½ŸæP L¤ :ÜwÃ:Ú³ÒÛ‰ƒ˜ŠÓ¥)‡š^“<âÇîÜn±©zŸM£t`„lÃɼŸ- ^®>†Nh?z”ŠèÞªyQnT•å °È8Í&Ì©š~ÿnÏšä–ÂEˆÜe^‚oŠ]aCc`õ“XçÖ! Ïí£SÅ]9H2¬©šÇy.4Iyb1QÉÎ8ò ì5&{z5å´PCÓäYêV²»EœÛ)ŽYíT\ O³HzÙÏU@sø¡*n4ºÊT÷9PÙ,Tâ—.¾9¸€(p*¶ Dñ šyl†²÷é~–Œ¶[Œ&"´Ë‹LüÍ™Á•`ÌTe‹õí^oç<{{ $ót€%WöñtÃÃÙF»Æi”öz¸ ŠŠTÁM°ÁÍbÇsVºÏÔ•À €pÌ&ØDÝ­>Š}=óÓxÞD··WÅLŠÔTÜ„QB`ç&F1S—¬Q2BSE¯qœc0Úš³2#vÂ` €ìB$ƒ¢ÓqB©ÒJ­‹[' <ùrzt‘G qo`…J_ªøTïž hRY»D\Ú÷‡4ªj_&3-ÙdîùxMÔÀÈõbuÒtM(£Â Ô‚¡Ã!ë"Y‹cì½ Ri (’Š»OÐèîÑN( Æìp°Ý&».*I6g¯¨’m©$vQØýØOŸÂØUï^ïìí®%•tÂqLgßOѬâökõ¬Rx‹ÑÙi†(#`Š)³·¥š±¶MÖ1úáqÓh¡Ó½ÙàïTQ†¥kuFª ’ÌrÐnÖd¶ÐdUZÙ Ä©1Ð/ãâ§ì—•­¨Û,HŠcï%§D„p‘1Ýv4Š˜®°ÃƒÚ‘ Ic'0’{zwfi?A÷A2K$¼•ÃË4AŽ7Ï›s'ié"kN¸%=  ÷ˆ般A€ÝK€Û&Ç`±AA²r¨¶u$¬!çdŒ*>‚#R7Á‚OeY]BI/Ýä(éy¢;i £w+®qH0žÞ!JÚYLnz.8Œ\[UÞû¨±„Ù^½½×ù(zΈFX'ÙÈæÎ|ØÁEh†–ÂîFÐp‡0xr²äï<3V2Ì@ˆv“µÛûã– ÀÆYð1øtŒö¹À[¡u‰Øwoƒ*i gð¡yºšµÃ‡F= ò)y¯ì…"T Öi.)TÕeñÙ•” žèÚ4XU×N4¡º¶ÏËŒÕÁBí!,5 1‰£ ÑJ¨Á1$•8ÙìYƒ£ÒC"ËÐmè·G¹Ì­²Û6Óa·ì*vA—«f…(aÃ+ :36€æ_C²ø(n8ÇÍÅ*Ñ ôˆ t µ’T¯Lp^*r—Û{—t1sM|ägŠ&Æ/¿ùâËŸ㘚éw{µª@"þhÇ#ÙöLõ•">AEÃ$Ú‰’ ¶0&:]"”Ó'PwÓeuD)ÞÒ@omtg¬É1DdBj茞T3¿÷å÷Þ¾}s¼ŸóÍ3ûõ¥Ž§ÒJÕ7÷ñOþìWï~uß}®{?åØâä>Œuß $´…‘‡BÄwÖpèÙýfðµQ„‰NÜ[vñØA!ÙY264ª¨Zk]d!ÈbÁ›bì]tÅ‹‹õ4±®ÄÀdr6 (:îp,悆¢“$Tøl`uÚ—òáP£{3($Þ·©îÖ G¤Šq7pG]0ÑTâN é×F©ZØ`%³9t'Q¯¶5\Ü&’YìôöÞ+tç(‘ìØ€ó¾ÁhŽnšœv%^ëÍÓ'vÆ­ÆýìÄ"€-͵yzö¨ûM[Å$O³¢ êÚ×–[ºÅ£â]Âd%€(‘ÉA>”dVˆKBlЀƒçªöJÛí†jŸãØÛ‡öüÎëÇ'ó`Á}n7¨¢ÀR%I±±Ïý)ÇþèÓ¥úþýGÿæÃ/Þ¥Úm%AŸÆ1ôbVÃíBðËE÷Ft&HBÕK²cîHCˆ‘ =âNb«=HïS’EºûØx&ÞTÎäRŠ^s¹i0LyD/çRgÞê\.ªI“€s3Ñi±×–86ú²·URÅЮÇ9nG‹®BN¢‚¦n3ÝmôaÑñ`Ë«·]sÈ;5ë,ª8,À½$&@Æ–È A0Jåµ{9Æ=¨ÚËñ9ެýãŽû»_~òöÓúoþ»ÿöùÓ79Ïu¦×bgOó `!5'›Fµ8Ç ÑN%…s'cŠÅF.Ÿö–¶8*{ΦH9Œ"> ¦Û‰ÄOAv?§/núÝ|ö7ÿà‡?ú\C¸T„è0I©÷.1úh“–q¹žXÁ'Gýå½ùÑoǾ}÷š]Ý5ÎÝØm1 òÚ½D@u„ʬF)1äÄ0“X@‡º¼òË5piÝärPU'B.p›ÛèvP§­£F,Ruqäpúìi^Œ¡í–h? ˆº]¹ Šã 9tsŒ2²¡n£®4Ôé"SÕ° 05 ÂÚ`;©z#ÆH·¨Ï(C‰ÒN"‰ØNø¨Ùà-ˆy=#ØNL°p&÷•ŸüæÏ¾üâ£ÆgúG¿üôí›1 jX¥¡ R+Gñ±·ÛÛœæ•ë`kÀi¥jg”îé3Û,¸:­M”¬kGÂJd ó‡_}ú_ýÎ÷ÞNîí½´ÃŒyÐÓ9ÏÞÚ}~þ½·ÞqRblêÈG`赿ºéËßú¢+ÿëÿýëÛ²e)E†½P›@ÔÎ=¸y]‚žj4ÓLîæToÇž¬ŽR(¤§¸ÀF™Š)²;RŽ„5»my°tŒ>÷p¿xÐÓH'ö~e %yAÃ×ú©"ôö®PäI&8,ÁDIù¾ÍJ3`$;p\¬sgŒz¬,\8©¤$˜Šn¨/_,‰¤–E±‘F:Y¢$@ù(¨S§½Ñ^5Þ¶,ÙÙÉ„B3¨åO·o?¿XùÝŒw/¿Šæ·îÇmŽjŽ'Pƒ2À˜<ª¡Ý¶ ÷vzôš˜;f½'Éî4öŒî{R>‘s‘§.i‡QÓO¿ûÓ¯þË?übxï@`}Ûø—úË?ùÕýë_ç˽ƒÇSé{ÏïþêßþøûoÞ<+ “¤D)$SZø?þê'Ÿ¼ùßþøßþÉ¿ õ±äe@݃|ϨâºÕ“r–àôcƒfºõ\¢¡vªl`÷9)ê_xëÕ¸Q@†B*¦äìƒl/ûbÚa âFEØpÎÅñfÞnݹd5Þ=§šq{ŒùDz¯^9­On,¡ãÑnŽgõêÇâ(’¡è‚†^w½¹ED̬Qqôð<Õ3üh¦Ú>],§fq¼]Q¨ܯ笊£ªøÒÔ€\Œµ‹Š­d¦ °;a(QDXèG¯4ö•<“5ÅHƒZÀJp®MTbÒÏàqnÖ¸êžÎvùö¤@Š`B € ¢Qh2ÅdG>FEq·Ý ¤š¢à—×G±¶S7¶ÌkjgÒAãÒÒFXƒ«!ªTad(Ù‰¨ÈDL‚èæz=ÿêoýàöý/ëoþí¿u;>9nOÒª·;=¥ªaê2q<†ŠÜ@2‡$æoc¾Ú½ã˜h¹•½‡„´Ódµô‚Ë3 RGé¿ù×ë7~úÜ÷8ô‹ýþþö§ïγÁ–‚GgŸ ã½›Uz÷òòGÿîý¿ûÅý§ßÿ¢JŽ— ï«Ô¯]³;ÕúË?þâWÓ¿øó÷·QÝÉÐU„âp“Puâì<¿}òÎòö¨Ütˆ„hP±ì½ 8 ^ªµ_ç›Ø‰€54ŠLµòÅ‘vÒ¸Œ‰Hiäå5aíû²—žæ@AÉ•«QœSFªtï5Ú¯¶j‰M¢ n},~Wa͹×Áã\€Ïø€DŠ@Ρ٣‚í\$#nDYŵCš\}ª°w«­¡Ç„È8Eðìç1ðøæÇ?þê“/Pÿüƒ§zšœÅ²ŒPó€Uxiox¥LF$Á½ ¶§ýp3}%»7+S¦ AÊž¨!(ÇÀmí¿ó×~çû_}©NÇ?ýÕãúßQšW:Ì«¶4øh=ìN$¾~8_íßþê{û‚¿ PÉÊ^WM«÷ŸþÆ—/|ùóŸ/ JJ7À#OI¸×^gœª¨ ÀFI¢aÛÐP-`1¬: ÙÝq¾ä¡äc° YUGɈm´CfgqpÌN'Ó%ur¯‚,± ¾3ÝÐ"¢¿+ÇM´ƒåµ U ­™\e•Ùê&x Ê%€*îÕE'D³Xƒ§Æ-Ñ->Íšs´€v³¥Uîn&‚Ü×ô"¬Ïoó{úìû?ûÍú{÷ïç¥ ±!ŠŒÕ½ó‘“©¾nrQÀqi^l‚ºïçaÄŽ©ºÜèW²êy Â?}{û[ÿÅ|þ‰ …cüÓ_¿ü“ö'ÏelÈÀ!"¸¸‡\4UÑ1ëϾþðxÇŸüè³ ¢XÄ•-S!9Bi:ÿÉW_ý|¿ÿõY(™û²‰’ ¶ÝaÊËE’&¯ %Y +9€C‚$|taV`*öÞ;Z]u +Xû/}ŒRˆ3<¤”ö""{ˆ‚ãt:L øØCuØä­`Çt´Ý-:©6X!›”F1Em¦JOm‰Uɤ8fl÷˜š£ƒð &r°.݇žI•øHvaª$Qœè1+’ÅN¤Bщ*6H±`šHÃ*þìóßøò·SÛ¼Ý횪Qǘ#Ö† )ê€(ñ"ñ/Fžd͹Nr×` ñu´ån “ð !¦ƒŒµÿúïÿè³§ š€Ah¾{<þ¯?þ%=ãýPâ ,³À~Ë›|Õ}×b"ìdSóxþ¿üÕ„ï» IDAT?û—_ϧςÂdž<È ui0öë¯ÿîïÿô'é“L28@ìíPË0&”ÃàêZv_ÔDÑÄ"ÁyvuÂ^4¹=ÉçÒívl"¥HÛ ÕÌZ Íãv;,ˆÁyöÞaµ™ áI ekâö„ãiºW#éKHs#c„ƒ”ÉÒ8@Æ ¨qy)WUX2a6e¯ w³—œjæL)£êÍÁ!‘ËvoÁO£&g[¬mb¤cà fgœ›mØ‚™ÝxX}‘QÌè}†²Îûý¦ùñ0¹êýë¼Ím½Ð.‘Ý›R´ÂÎPÆLä –36Ê $íþÎ_ûí/>)dýEÑ<Žùÿõ¯p§"9q”9¶Þ|'¢Jy§mUÇÍÞUÿóÿóó_ÿü%¡„ û’AïÎôÌsýíßÿÉW?TÜ7÷Å'bPSUtaW€Z„â6¼ò51èQUbœ—¶çØ´ª¤R•à§ìu³ŸM,Õ&7±®Uk1”ûpÓ€Ï'Jfcòötv ªŠ†ë*­ÃÝjW¦¤BÈ1‰¬¶" Ûa†$—LIU RJc”Çm[¡Îu$«Ñ±ív“WilÙ:UwVGlxŠ0sÌb` ºxU¾=ùIæžô[ñî„8oãPQj`W50C$M%¾ÁÍtÌâ JsK£{tžkˆ˜€‚‚T³ê…QEåèþë¿÷ã|YFP´ˆo^¾ý?þôîKK,±‰ý~ãLër1tŠ„¡ “&báù³ãü'ÿâe×^±Ñ½‚ÑÍ}Âí|<¾0×ùŸÿÞW¿îí1÷²÷60ôÑùbQ·ªŠÓÙN ‰Iíu¾¸»WåU˜"Îsr4±Å ¹Êd:Õ9Š"EŽçZ¯&Ð{7’*¡ÂÚñ#//ÇhÀA°Y~<¶AbZNAJ—í~¯çð F)b ­9.ŸŸÍ*r×Yîk¹ÛNÙ¡]ny¨eV²¨}`”j²´¥Œš™çÐíüyz—˲+IÏÌÖÚç^÷ˆÌŒL&É$Yd½««Pý@£ÒD54ô‡¤Ðj=PÕÝÕ*²žd‘L’ÉdFF¸ß{ö^Ë4ØÎ޹ÇïÝgm[fŸ*ÅãÅÒ˜bŒ¸¡¤X#ýð`ƒ³TÍÇqÛD àÙ¦,›$$ µŠeÐŽv‚R¸ûÚ8¤,Aa:ab4³ òE²È¯—?úÁ'$(RðV…þêöÚ’¢I¤:@j˜©,—ARO^E˜s‹¾´c‡ÈªŸÞñŸ~ô«ëÃþœ(Hcÿ‡iÚ] ªë»ÿüÏ>¹Wk(È6Ëψv­šg-ßÛ†bRÊ T̈ ÝÉ~î:îz¹¢»ëì*#0E£¡QK,6Òʲ» ªsH œ½“ÒØþÚ[«š6Ow+÷a•ô¶ØÄEqDÂP¨ÙQ²hûŽ­ÝV éÚ¾tó¬Ó]U¯njsv.ÇÑEi÷Œu—3,A0£aí_·=ÀÈ´f9º&vѨÀ˃׬5SjwtîNCŒµV¬³>ûý4ofï;øå—kDž]nØÊ®Z ¦E„æ2Är…7 «äÈX´‹ÝáhÃÖH¯~ÿÀÏß?G×8¶-)2ÄßÓ˽¾~ûgßùèoôùZV61<;×|Ô^Áu‡jUÂGc¹Ð˜fiFšµÓPl1†qo+44#VuÚ½@iće]¦1úÞ;Ù¶VXuºÆ•qÖ(¶’š[n}j_yÙn§ N£Ã#ÌžÛAiÛ]@¯ê<vW/í= iÑ }dϯ4èK¢gyT¦¨€U1ù@SX@kÍ3òÞ}ˆ$®¤`’Æ<‹©*i 1ÊgË ÒWØŒvÀê¸ß²ÎªS¬ø­]x"¦][ÂälrÉç§ù_~ôeä£$â ¥½Kc̽W|8>9–2.BÆDØÝ5{ëÀÕEHŒPx_¶ƒÅ Î-܃SìP¤.ä@La߯M*”ôEŽëñŒzÍÙ½WNЭ¹²•ºÿx4 úE1˜…† d£«6¨‡htR—¸Æ6EÙ"WPÇëø\zdã›S\!µ¢Lä°bÅ1¡¡x@§h±E4íFAï ‚­jŒ»´Úg!V¡VV£ÝgyqµÏº¯è»t¯›FÀH"Q\¾Œö˜4k¾4xƒ.Ù„»¥0,GI¯ÅÞ)|Ôºìq€~ ãúÕ5®}çÞFï·–šl·´j‘8F<ÏjÊåî‚L¸¼®Ìç*À,¤,©zº³{-*9à¶öÎkýüé靸«ù¯¿]óÜF?/²6‡ǵo¿y¼<ŒÙ]Rõ¯ÂÈ^ «¹× -²[̆9”/·.¼2f¿¸@Ë‘·ÛÝäŠ8ÚûqeÊázw¿äåt ·6sÙꂱs5F°p«Ö¸HºÀ;$Ûu9VסÑìágX¾á ¥è­R¿$ƒØÝ1×eäsχÇZ+ªv(ŸY뉘 7reåAƒ@\TnÝÅ à³kc» è¾Ýä’ã<íW}oHÉã2Ït¬ŽwÓz±"¤½á6©ÞSlAõBÆd fuÎýJµÝÎÛuÍ8ànÐa–ƒlr£˜Î…íFìî)”MK#Bñìð N;Aí§I[ä5øH}ÆKJx¶¹®©ÙH7‚'tWµ2.Ñà0Tn@ÞHM+èÂÒˆ£yšÓáKª]÷EæÒ€+#÷w7©AzÛ_&¹©ªR«eµ‚mêæybkèí¾È·ê¶Á@ªx‡n8cÄ1£ì{¹‘2£û"ݵ"¢NäåZsÞƒ—¶¹½brÕR~qn¤¨çy3¬ôq­É2}¶«êÞɾð,e›8#h­j¤˜ìlqgW b眓|}äG¯G\“ǵ·¿@ ¹Qï"cUÔI·'\S—Ë!-<:s0Tf)Þï|H¯¶´Í±p0Œˆ˜cøõ«_¿ÿ‹¯n`ð…$ïP×~Ä™ïß}=–Gr$cSu`¹É^*§ ‘RlëÚAˆ¶çÔfÃÂ7¸4º|?ýTXö ½Q¾¨_|´Bh¾ÈV(@À$¤”޳‘æÆ&I3²$x)çn2$ç%‘±ƒNdëö8.°„æ¼W£‰ÄÆÑMóù¶Ö¬Y}Nˆ—9÷¤„¸{ æ5ólßWO£$7Onvß¼žn§AŽñÁéz4\T@ì0Ÿî×O> c=—ã~ÇêÕŠ–å%é^¬åKšÉsÞ/ÕeB›*» XÖˆè}:`3 ½CšŒ ¯ÍæŽˆ¸Ø€Ïy‰˜9ׄˆ#•·Y̳½îïùbS!h·íç ’k)ˆ{ôÀm*G$ÃíîÂûÅ;®ÿôäïpßÏh«kY=ërÄçïjÈiJñî>ƒA{Ë Æš«QDC4‚¶éâv¼0Ê j¡Z^£ÃÛmજîP<Ó㔯H3NìÛQ‚ÝM´¨>ç… ©f5ºöô'5:ºËy´d¦ñ@ÏÙ-е{-d´ˆMˆÜ_Ë”f¹!‰áû!/ð”p-#Æ,°»­Æqg÷uŒU딵¡ÄÄIKœæˆšÜó×_\­fAb#sBÞ×¼çÓ5[:>°Æ|ªTÄ~ºšÀé¾.™Fœut<´pæÊm²RÂת‹;ªÑ­èÂüð"y²×°^"^µ8Æ1ßiÍP[šÓ´2^LÀì*Ô¬»_´eî‰a^AÜnkñ Û³¸¤¡ËÐUþÍÏ~u»m$ö³,m»Öuýü·cJ ó~^›À’ê+úDBË%$šF'ŠœDSg;#±Ílª› ô¹¼BBÄudЙxgIã2‚„G¬Ì”¡KPjŒãƶXèãÁZË@jõ‹Á´ê6 ­;ìl–‡Y%éè †n”ó k©ž¨e§Àn/Ó‹Iğlxö½P\ån«™ÀFŒ&{™nuJÑ«ÕЖ´H}û|å²ÝÙçd#Ím¨0«›j¤UÚRQ™C(ÏŽˆMÖf!‘Ykv%l7«ö>aó!ïõ7Wò޶°ñãZeW‹QäÄ–Þm#¤é–«ã(ãȾÛËN ‰*d^Cjð^&¤0P(ôÕm=ÿ¯>ÃZ68¤ÙCûÅÛw_¯bNOTs4z!÷‰³ÕÈnˆêíÊïî`,[ͬj‰ò‘Ϊcgk¥|ùxÍ7¯®×K^.\¯ÄZgwq<ÝVçìûmO·µ&JÌËÁ,LšnÃF¡išf­:«cènÉ1€QHƈ¬õ¬ºÖ™|%䋟j5€nA l€#FA¬J›U>²ÊCñzW½X0z@má^ÝFŠØø8¤U³ul¨VE]À|þtÜ>Ÿß<—‹äBªÙh™|Á¾o\“E(h-3¦€›³Ö"²`´(Ø=/œÌ7á'ˆ `)’`Uª Í=v%V— Hð¢Ë•æƒòùvª‘9âÅ=8:êxñ5ædHųÁ<çüɯ~ýÍï¼yîËvøšýøl†] åxñó Ô½‰û\ƶ{K.ƒö 8ïÓ$å^Xì€^DÕ•úÆ›Ço|rùðƒ‡@è¸\£‡šU]¦ÛNÛŒ€bA)xU ³ãl,×W¿yþ鯿z>ÇZ­{M×PšÝ„é#¶B Ôs^®1mu6g¤N´°è£ýRåpxy&AhÙ Gî5÷|ÝãŽPÈêå"èehB¶Ã\nîî#ÍQU›Š^WÆ]ª2»YKàG¯ðüõo¾Ád­[û’:\»¸à¸®í$Œs¥ÐE- ».GÓ¡íuFÕ^°ä½ÂE%Œñº9‹m à %4ó¸*–·½gµ›E 5÷Þ®ÓÁ°d€Q½Bã,Žf ôo½yŒé¹ÔQîÆg3T¥V»IJ™±ì!½Çw^åŸþÞ7~õåÛws}ùvýü×·¯Þ>$6Q C衼÷½ª"õ\÷ °‰ìjSOÆ^ ‘ÞÜ„-/à¾æÆ™«¥²â\Gæ %Òî0æì«ÆÂâ&W+¶Ý½^,Ú-5A÷½]ód×Ê 2Vñë/ž¾ûmNäqq£ŠAZ±˜´Û-.4cœUC·¤“Ì`à T;÷ÕXv‰ˆ ˜«ýGßù¨<«À³DAì*Œ‡,¯³kDzWV,·îf8“pÐl›cø²FÔì&¤Êè9/×±Öò´•÷ªÛÏ>û͸ïfy¬ÿõ‡?ÿÅçõáÈsUÄAqµ6€Š§u4†9•›«Lé*îÅ¡ SÆÇããO^}úÉõƒ¾Ê­YžkÉ«ïÔÕÞ-#c_€Í ªr“‘°«Ë¶Æ0‹¸»ß>ùúrùôÍñ{ß]¿úêíßüÓÛ÷ï««aÚŽc¼;ßK–íBJ§›’ʘ©ª‹….apØJqï2ÔzéHÙÔù4ÚVÐáv÷¾ë$1{ë+;nn9€F6 ñT0Õ³”õ`ŸöT¾»÷õkwu^£Ã°0¤œª>Rž•dݽj¦’äÂz6Z c^0gfŒµ©Y¥0ú^g·w¨WÖå ´RÖýñ£ÐçËçÝÊ";ãÒBõr븰úa¹9Õö9s0{LJÏQã„ç¼7XÞ a¹ÿç~úßþÙ§—×ù«'ü§øùÏ?¿?Äå©ÇuÖÌ[ƒ`Ï._ a-mºë¾<è<À 5× ¿ù*?ûæãw?~å–ƒÉb5å:çj>äcë6m¶oëäñºïçôjaLŒ^ksÛ˜j6Ípð"(ÔŠêèþãO>ø½7—z^÷ó¯ßþú~»eõ ÎˆÀœÕ.62AÝ®ºàrB+ÀHÛ]kÉj,2ÝÑËc<µW-Wl&¼Î½\–Û ÚJt亯á0Ôh£0x#S·w×k¾ŸØ*N´úªPß΃ùz³½ ñ2I-2AÝ‚Ó0±`÷jÒÁj0ó 5Yxî».s;“ºIzÚí9A'YØŒ¾ýÖ×ùOO_þìÝq\|n’»‹‰”R<û£j^Ƹ»Ð–МçÜ.ÿ›}£Žíëá}(q«¯l¦Ørº©Ç«Ûº•жã¼÷zfÄs•ÇVÌU½Eßùi¾ö IIGïåsÚ§@Û@@œìƒ±WúsB‘Ñ“¶õ|«cä’Œ6(1v$;› Ìñб²} mÄ¿h îºØ#c)]KÂ¥Lt-–¼ìK÷óF¦ÑÞ6ßnöLP“láÀ}Î;2íØ·iHa?^\^ïÞ¹û<2l¸+;Ú0}ÐÕ²Ô*³+FNI^Gâ!â{ü»ßý81ÜOÕ)‹ûé À5„,¾½Í_ÞÞÿô‹ùå¯Îù|("r5è®K‚èüú¨eà—Çõñòx|çÍõÃÇ˸äQÒ².±õ·•#.ðÃ×oþ‡?{ý³ïßÿêÞþ櫓ƶŸý|®kÜ*ÿˆ„I¾_çP±Ú‡è!ÁlÜQæ§”¹öÕe{V^ ÛØÚ ²]9ýd`dÂ82æºEUæ…ïH2‘ªûýXßãîœìUõÆy\²îÕZÝòË —Œ…ŽHÃÝžá ­rÛÇÞ-1bp Nˆ©Eå ¶l/P4áÂ6ñ»F\®#Ÿ»+†ÑÕ¦¨e¬åCìç™qœU€e”›žŒ¸·"ÕÕÃ’›/YSM%V°õ‚Ygm{áH?õF™iÙjOWgžm0«á5¸dù÷ÿðÓo½yõñÁYU“Õ;®WköÞ>Í¿ÿÅÛÿòëÛ}õÓÒãeŒÝá&ºÆA*¼\ñ[’w)×9ß?ßÞ}õ|X—K½~¼üÉ÷ß|òú°ìe´`¼Tã¤Vë[Ç'øñ—÷ó?üÝÛwooqÜWCibu^Õ;ºus8ŒlN÷€Àº#‚Ôm-”1+öbƒÁ]M‡yÜO_´ ö »Û pÝ_¨K–;(JÙ(´3Uö¹úU\ÞþúËõ«÷úæý|f_ntj¬9½¹Þeg cWÒ˜DÍÀ0]…È$fgY%!èÊË8Ýa WÐx%®2•/m…ßf—z5‘*ù¬2›UË1´j¯ûUÍæÃåq®[:ÒgCÒAÊMÖ*à=úÑq_óÕ®HÙWW‘å£O/טé`“BdØäøô“WßûÎGŸ½‚‰û*áåý«»Xl‘Âožnÿøëûßþô&ë¼:ž2µºíaèÈóôØuåèŠ8 Ib°Û¸DÐÙçÂç¿zÿ‹Ÿþ替þã?úÖG¯™AƒÅ ˆ.#>»¼úïþüñ¿øêÇ?{ªÉC8.y»O‰æ€ 8G¬j°Mv„2Q÷ *Èqmm5Díêy’9Köù¤å¸›‹¾Ù&ÂîÖ^Ô€×\AÞÝo>ûy{öBüÛÿùYåÁ»Ça—LÄez›ŽFI·ï€“1 CÙŒ¢©ýe€ ]¡&aË"É+ðƒO?øàU’dM2¨Dä.y¯õùW·¾µ‰ "¤Ðõˆõ\¦Ì Qw™ÚŸWI» ¨ÁE=-d¼a°q(’ÝÛÜÉ——ºR»6°ZÆom+d¿óé›?üƒ_'ìªhP ,æÅtÙ:ògoßþû¿üåç_žNr×Lí™ÀÉÞuµ9š†»I2 2`£W{— ØÐ:Ž_¯õ“Ÿ~¹¯^_ór¼àÁµøH6/Ò§Ÿ|ˆÇñõû¯köªf» ( RÜoš…6»¯Saxµ 9@`h áÍÂú?6õÃu˜µÚRÁƒŒ «@´âå ¢ÃÙ CòówÆñÑ~7þÇÿéßbö1ަÚ»(•Äbl¨¤öZMå!…w‚Mнw+Dû€²‚‹øæ«Ë7?:ÜÍ8$Ááµ½8ÿù§_†³»CmìR LÿWOظÃiè ªš sÙî&)¤nÐìN—ƒŒÞ¢iƒ¤ä€e ò·­{a#dÐ1ñ‡ßúðw~ÿ“#´´+¦$é…ùéÅÀ;ø/~üÕÿæ+7NJf7 f  W¿¬g“q$©.Å"òš«zKÄUkÇçÝàmÊãí»Ûç_<ã½?øÆÃžFVWWKÞßçúPøäÃOžÎù´š"Ù•å‘à6¹Ó»À PØ}v‘;…¹ÛGé+…ƽz6îÞÿ¸ÌeVÁ¡¬5^wU °!¿ÛÆ!äP¸Îó’ãÓoúo}7»0AùòÍT„ζ1–yÉvݤt;%,ï -ÖØÒªz!Îö ÚkÕ¬.= ˜;Ìô¢ £v%üÑ5ŸnÛœA)€‰^ƒ,É«»Ù"¬ÛË3Ñyˆî |ën²¹Bì^ îž3ÒÝ!¿4öÒä˾ XÔlñªÐ:ÿðßþÖw^.tkˆj†E·À…öãø›·¿ù«ÿò¶¶1Ø>Èf KÖìM=Xä,fw(Êe÷z6ÁU¤0´; €’;v<íýú\ï~òó•úo?^¯”t49ÒÉlµ«>»úþÙ¿ÿñ_üüIâœ^s n»ClTr,ðk: zY‚{/)nZæ®sbÐ V'ë¸ÏÅa»ÚY›,€~é 9R&­,Í(=š&Tj †$PvV àldM®çÛyž™ÁÞõ8F"d%Ü„†2¼V¹—×^hÔOw£­€£$·ºid‡ÆG7—3Ðèr9ggï°¼k;‘Ü*j³*ù¼z®Âá‚C Ïýgdû˱fÝš'c‘]ÓÝ7÷ûò½^6,E$+= G¯?ùãϾ÷ÝÇ«*“æ^1½ÄØsü_¼ýÿÏÛóYQD…[†¨èêÁZ]GíÔλ»wLŠ}¸ÔUÚ›Up½»‰Ä=Ãh÷¿™z|ø«Ÿýú¯ÿî‹Û®4[ ”÷СFô¿ùî›WŸÄ“kvPf›P,³ÖGrcâá®*ƒOƳƒ¤#ÌeM¥S)pc5}·ˆ¦ŠI°§{Ú–@{Un›Œn-_/ʇŠFõ¼¬H˜ ‹!•·VÔi¿_£±–ªihhDv QP$©³ë¡ðº£oöVç+Ä&p<4Œ`äõ³OëZPŽŽXŠRðuÞí‚–ÝÙ’ˆ+9¨KÆA¸17]ª‘Á! sànÏVcᬞs-ÔzX­ª†Ú±âF…¡Å?ÿç¿÷Ù·>’š¡Hil –Ô©¿úñ/ôï?¼êÇ$8ÍA:Õ™í\EjÙ]m•ÝF3B€š£3I_‡¬n-¨dQáùJdq´<¡î}þîoþê5cŒ#ÈO±ÌskâHþ÷ö½?øÎxœ<¼“çåì¼Í˜·r0X!I IDAT³C½^ÁÑ“F»Ãgë^^ àìêZ»£›Ñuuë¶_x<»Ã½Ì垉 Ð8^ôºŠªçE®öo7t‚~_÷ åûá¸pÜÁI“ÀªUs¡K«²íS˜ìF‰«;šáèö×ë]MmÄb7°×ÆÒ1@Æ%O¦½iè^Qk÷*N²Èas7dUW HBÂt·a DpH‡6Qßð4È<´z©ÅìÞéEÖy% Wã_üà£^§ç´;T¯rwÔITKñW_üúÇ_ß~ØÉ¾J Üý&íØ]k¥B!¤ƒXU;Ó¬f$לh+†‚fe-¸Ï5o76k¾pVÀË‘ÿø›§þÃ/[’»¢jé"ìõo¾ûÍLŠPQ—á*Æ,¼ØSWŒ.Ê}{‚™ÄÁ*®;ÜÅ^ºOzµz½’/;E¸Ï&•Y¥½¬&nEé‹×¦¶÷üòê6Æ{7"ÛËåÕ³Öí°jèÁÇØ¥UZ¶äXųý´Îû:M›]èfŸð$ ¦cYçC¾&-d@zé¦ß%÷Àíg­†{Í]܃‘Û/x¶ž w V³DvôŒîE¦”؉ ö¾¨&VºÓÊ…v÷4'¢•ë2n¡åJù¸Åè¢üþ·>úÎ7u»?¹±+·3®&ðáÉñïþúgÿôå»[æYèÛâÂBOõŠÀe•<é§eŒQ8z°úœóùùt¹êiå—{¼Ð ¸\D^°/rÄ‚¾¥ò÷¿üÉ?½¬¶éqVtîZ.÷Ìó§ßª|JKQî$/òã(GȈŠôÚýÈUl×J×hf+F2Êf\6Ǹ‘^gTÕù0†ÍU0VP™m®Yˆ m!|úꃵ³å2?ì¼®Ñ(í[ÝðPúxUÇemݱz šU£Ô%!¥äˆqÐ@¨!4Y{‘XÄ3&z€FyWÐ;8h,P«1Ú/770Jé~ñ]Û-Z†§±‘.{M…ýa W°…£75È5' ƒ£Áµf*X k™x©)sµ?}ßûÞ›çªÈË+.j´¶ÑLIŒûèÿý~õü˧ 56C¼ƒÁxÈ1gèRŽYhö°Nxzö*S8ŒéÑÜLÕhéåÞý€m³3–võ7Ü…®¤°«~_]~ôÿþøíû>÷–a)¼[4•´TÂÊ?ýÞ7hj•XÉ’+ñÒgBìL\ fÛ­I!òHÃ#ÛƒLøÈÓk®¤]ð uC¶ÂŨ˜Z UÜõþÝ›x RÇ„žë™v(.ƒÑz4ó,Ͳª£Î(ûÞ@vëŽS/N¦m~íÆj`î úªY÷³ ĸœï'ò{Eî(Pn)ëõÇoæùŒ²ŒŒµ«0G^®Ž!ŒBVg7ººO¢6ŸÈçâ‹%h´ÞßpžªVf’-÷õ‚]‰­¼ƒÇñçÿì~|¸F½KBË–5« Wýþó_Ï_œÜgû(«F`ïàÑçÁ–4À¡°ãtïÜÜõ1Á§〨nOZ×Zb!u,ÊÝG—º†½“¿ Š6ËÑâé5ÿ¯¿ýõs±ËìÁˆCa\"òÉñ/ÿôÃØ#ÛèéGè",´š1›Í d„é%CI‰ò½C`>:Âq)pšX}4Žñp}xˆÁåBhѬ@“ÉËG¡ïŽ·} Qçý9ä]4`Wwyv‚Ñ»,ʪ“@*˜Q³.–Õ÷z„¢+°+ ÔMxˆ‰içûémK°‹ov¥^‚„ýáUïçĩé6bx¤ØZëÃãxõp½\ŽÓsgù%l5Çâb+ÖYËwª"oí½Þ‰ò0/PË^VÏy^P¿÷»u‡›Ž<È´i†2ëúøüã»/¿|¢àIÏöI•dm8¸=»ª›œ›.ÜðZÓ6˜mCïî¦Pó_™€Ü¥Mz†;~ s÷¦ª7îv°üb‰ëñöË÷û÷¿‘bKx¡••G°+Àšøî§ßóZêö*Rg­êÞsq ÊÃý:@î$ Ë}ƒuʧicɈz¿æ¼ß*ÒÞü¥>¨ kí¬¸D¿çõñÑpöcÆ™Œxò|‘\jÎ’uê¸DÎnœèóŒPôÜy,â’y.L÷¶ó ½u™–Îê÷§q[¦þë&ð àsôyáȼÔâ}Þ#ÈžÒÅv¦>ûÆã›¶øó/Þ µºZµÓ3¢IÃâ»îq\t+ƒ‹îÅ4)”ŒhŒ{c—‡ëÓyñÙÃñý¯]§1Z!î·I´xOÿð'oü‹û+p¢"bmmu>V­—¯1 ¸9'%]®UåöÍ­5ÌwÇc¬*AÎpt±ÔP–[bƒˆU5F.  ´°Ûba»ÂþÅ÷>}Èo?àœx±b¦ËdØrÌwÿú{Ÿýï_Ô<‹C4 Ê®´¿.]3Иw9FOå ÔZ éUKfÄØCÕK36pâåz/“dK‡1Sqµêþå×õ¨òã`½®ãJGŸ¦Lcž«#ÚF/u_À0·«[ÄnÄÈô63fƒ@uÏ-ÞD0è»Á¶ZûàÚ•ð xáCÏf¿T½—Ýì“}®s>ÝÖ³Ž_|u~ùÕóýÝô}®û­îÓsq7Æ·Œî*{R±V‘ò ·ÁNtw¡zªù(üƒßýt»æ…¨v›ð€Qÿþó·ÿôÓ_¾N,l*läÈ$h£né&á]žhË™ òâ°^?aõº§çΗ•„ö6úÞ¾z¶Û%¢ÎYç¬r/¢1¨Ñ¨YlX¿øÑÏÞ?ÅÚyý 8_"æ¡7ƒòGûPfì3> Ç†gŸÆÙØEΠä¬2¨  6R© …,tÒn_ì£Ö wŸý:F„†+_¾ñððñÇßð€¼DwÍ“à}åå2 —«ŠaB[3oº×³–ãxb³…®’ç)íÏ€fPf1Ù"EŠ×þê‹÷o>Ù`EBBŸà.˜P@ƒ:Þ¯»1šl[±š‘úå¯oos>Ï¥xÍ0cÅZr¬®išH¢Ýyn¯åa9/½©àÝ%2±z}÷›Ÿ|øxœ½¡²½ûµ¸ Uãú³§÷û«“3û\]%%æÐêØ2´“e/€yŠ0ŒÇÔéó©Î ì\ØÃòª#Ñ&Çj:Gír]t·‹Ôª0”iA!7F÷ ({sHÕ5OÏýË¿ûÅë?þÆöyS–Ù¾S´ÃèvÿÙw¾õŸÿ4ß ³Kw"ƒÃ¸¶¼s¶õÀ.hàì|ÿè sï~›ÕK&îm›Á:F¼ï§Ì@×ôIô'½ùøßm6!%Žóÿ'ê]š$K–#=U5ós"³ªºï¸Àà`dH΂ððïS¸!á!ˆ×Å}twUeFw3å£.{Q"½è–ª¬ˆsÜÍT¿0#â$²Ñ©.5…h2Ð}}L:¢X& T­rÏî0Ô+ Óo«º½ ËÏÎý×uû²ö{ ž[ôfÔpæÏ>ÝÊ‹] š9ÇQÒÈðÂ-ò¾˜ð2û+sq ÑÂ"ªYì*àêz¯ 7QDî4ìŒ vs9ϾþüW¯ lò<Ì*Çvªb|•þ÷ÿó_/èšôŠÝ« gñèež¡µçÁ1e:žóÒ!ÄÈÄq”ñ)_34’³ Å =÷•ý ­pmtq´…æèE®lZ„ìÅ@±…¿û·¿üøØ^.ºÛ EÎ0ލyýúg¥RÈÐw÷×ö¥Cí[h/6h{G<ŒM‡t£f×½ñ[ÜN‚º›"§FçÑhV ¬“×íãíã÷?ýôÚr¬ž^85"âêù¨·…RŒè=šæ¥M‚=­xóÓT&ÊÁ¼„íq*ó%eØ!çhp5qï… v«¥w"tn(‚¯CÞ 6mÎut –„µü,ö¤k>¥†„cg²‰ª…Z'{Íz,;bG,ÐÐHdzä9_¾ûþ;zyhç03MP¼ˆÿò÷?¼¿»PÓ—ÐYhªÉC»’kÏkϰ¶€°Eccüée×þ¸öÊYÑñ6×Õ®º\ˆÚ- 1mTo’5rc9léuœ ß¿!¯Þëñ=€Šxÿî¿Ü¥ÕØ+ÀíN©óh°WýÙ§óÏÿ݆ccuÝ‚@Ïg¸£7‘èÖ&mÂ^6v y*º`Âd 8lØ-öˆñÓ½ÿíÇÏqqį̀ï~ù²­‹/úùÜ‚{û‹ÌnËdœä€®«Þ«Ò«ìu÷]i¯åÆjüÓï~sýîštÀ†1š¯žènãv¼üêO>Í—€›³63C‘„÷>Y[îºèK\Ð\žË;ÑœG0öÇÜ÷²† ˜Â”V×>q½ÆéâýQ?ýðùÇßü #4´×ñúîãwÇðˆêU:½ûÓ=QŠAH“…6{(^M«O¦âD“WaÍå* u]{¯šÐ’—¼Ð…î.ň‘©v/®ž'|àhV´7‡j°xzÌ;û5¹W\èÅŽ`Õ®«:r樼-óâÆÎclÎXËd°:âÞ-x®µª'ÀÎÑc8úÅÙ™ö.®¬OrS]§ÿ¯ùÍ—¯kVïJ ·\ëºæ×R˜ØÐE¢PqŒdR!2Ÿ¾KÖv·Ð9ÉšDìoR(è$qo”%Ĉ‘<ôzvð~úB-²'«Sޏ@잢cœŠ8ÂJ¹Öÿûëÿy…Tðưè&ØP#‘ÿÝèÃ/GÜò8(Ú Œ¾z.¯ÙØ5«  Z;ÛárÝÛè–™­õˆ^`›†q{«k]kº}ÄKÞòí'ÏØX4¬u»ÕhÍN­¾¼ªÆ1•ʘXkÿ;{ °a¥¬H(ÆlŒÈ$:±¼!üÐ0€Ç®õSËè‰^ÀµÄÓq‹ñ*e“Mí²¢Â¯"«ÝM×!À¸ˆ ä1pN5]®±Q"/ÉÌ3T«QÜúšÃ­·ìªt{vS)…(Åû½ýÛ/·ŠÍdØd4p opO×®G¹AD¨,×N¿  @WkÙ°Eœ#‚6Í.dUM46œb“¶ÜÕ½²ÚX³ ¸f:“ˆ „û¼ êjvÌ©ÕnÞÆ¯ûþ›΄£Rû»›l—Ûò³_Ü>Ž6÷¢ë[v¦Ñ>¦Ó,£¤R¼g:eC@s”Ûtôl̽F]®è:”ð#dÔT­#óøÅGY[±`[ºú•ŠC®ÓT5ïî‡ÕŒü0ŽïŽ­Û¨Æz¢âòÔªžÛÙÄ\º$JÊíÚ¸Ãý¯¿ùéþe;…áu¯ëà€º^oýÉÒ\ßãÌûŠV•¾6f•ª³*Êä¾®^UËóZº.ÍVµÆikÍf]>w U¬ê9gu»,ž÷Ñè<õr¦hlÓñü?ÿvøª¹…¶«[p4bŒ´Ò[ù½Œ…9Q›]µˆ‹í¾ö,õª®Ù=MKwꢪ¡8p êH»zï¥z¥Ö-REt°W'¢§YbƒÆIró1c÷ö£bõ§ÛÇ¿þ‡ß¬Gíª*{›Ðè€Ò¬WÝÿ›?ÿØÙEϪ²ï $y¸b80dÒû XÅžx\Uó:ºQNe–ùê¾± mSUÊ\ÙJ”oë3ûi’ÒO÷{‡°Vt«g'úÆ0SÝQnqUcÕ†¦è¦Ú,»{´vqÕr—wjE â†Òž‰F£ ½|-ÔFõ-”±÷š» ¿ºE€¸„"[OÄ& ÚíÃ;eã^D®ZrÐBÄ8C>ªGõ2bhº¯ñRŸ»¤ÐfƒŠ_ýú›ß=>2wC~JËÅ$2!´±Üë4Ïý_ʽ.4`=Qf¢’Ü:éBl†Pµ¢ë&õ*ލÀò¤iqº#Fï´½ TU·2ÚœàZ¼_XEŸ'"Ú¸öº¹KGè>‰ˆ}óUV}w{9FGø"|ËnO`ƒ:à]‹Õ›#„ƒ‡kaË= Á™£{Èïô—å U 4N÷G¢gQÇñØ¥-2×»×KÁhÀj£t™¡r©M…ƒs´Üçûpâ©!tF´Uwk›IæZHÎаýxÌǽÏA×¼8ޤc“øð’?ÿôòO?](c9Å.n@4å^e~ã¿”2µÞLWØW#Gà5ßÇ8šjVó¤<é±¢È=—œ›ÏÂåø/¿y?G®2¡>æÚìãëêq÷97òé*§‹0G‚±ƒ©µ'Qh®š/drL9ÚáØìÝ* ²fuòÍÆ »2Á^u•…L»†d,yÕ 'L¸ªŠ9€òã݈säËá÷îÇk0#dIxªi kÛþ~ù°e…ç£øv#žæ,wf̉·6×*jn6ÙZë=uÐkÕ"nÒDS 2óΪ:žŸ*ÊOG<.¯vhGî'Y"Î[½I~EǘÁ¶{9zMȈ†í‚xfAÝf/{Ͷ·(ñÐ132oƒ¹6ÜõWœ·>û1ºÒ^½Š0kÀ6¦Ä#C½ý ] 0P¨no~mDË ä>"Ÿ-¹µ½:nRIâš^%ã_ïo÷ípòr}¹¾¾~«''¨5ºcÅ©uÍi‘Iö‘±%Q4,`ÊŒ›ìp¡ -|{|íþl8Üu¤• ÙŒl¤ÑuU_ L‡@h£9Ée×Ã݈ˆº=Ñ­\5Ñáâ?þîŸg½ltÍ­a{^$>/úgß?ººû± ¬muyù…TYif{e "íQ\«Ûb« ¡Ót ™*`u—ò—°nƒ;EfÝtú1U´—©FÉ8ÝÆÊb4«Q]jÍj7U²Í€%¶Z{Å!éˆß_ó§ëúù‹`F|§ø`‚:öc<ù*þÔp¿d  Õsn°=.?F¢šCçfqÏj«mG!Wá­ñÿåñ0›?-þͯ¿†¢–×£Võ 8ózBK$Ї»°Cäàí¨åj/£Hˆxä!ãA.uÍé^ïU ¸–/ p¸ÝîF3”ȈÑûFŒ`—LœÃR٠ʪ=Ðâݰ;/Œ!÷Íþá÷ëë5Ùh8ª÷uS‚›Õ?·ø8ŠˆCíZ…T&jq…–m¯ ¨ë½g°&úl±ï× Ä k„t|›,…¾ÚWŽñüXzüö‡÷;×:ÛÜx¶#³É‡/¹áËì;jkbiçl$A·Èã ‰ˆA¥‚™ý¨%Üóu'¨ ÍØÏªØ¯BµòËžàA*ä-$!kƒ¬ÅÐD7½åŠ®GÖô\l³1Í–pŽí¡Y;ngäNP1ø~½æ_ÿÍ¿Ôñò“ïŸß¿M 7@§èÕÇ4÷uA®µÖµæjžQÉ{=ªê¾Ømµe³\ˆGyÎY]Õvw Ž0†"oÁîµë;Bam…غÑià|Èk×k–»åJ›É]¿²}µñÙTÏnn(<·S¹7¢™h»Q¯?ûðá ùº=Í2«ö6h•î ñ©^×ͼUS lÖ1-Rqײvdµ¸Êî$G‡;xžþüõ6NΟt d9B;Ö1UX†qè/LØX1Nš´ç™ LEÄj‘–#x³|’GÛÏ„-³|"ô‹Oý·_né^eÅ:PõôvЬ«7Í­)·3‡]Gr™Â)ùêÎŽC¼oãp½_9–M‘î­¯¦)\ïàÿýÛÏ?þ/_—#\$èf}Þ«%^ˆ$’¸à€/ô@ßÂ_gYÍXèìJIê]‘¶…©)ìÆÊ€&»­Ô xýüÛ“ Óèeq–T§ÜÖJ´; ë:ZmŠÉÌöýó—ù!«+BáîÚk÷$ƒqÎÇyÃZ3 JV·…è>€]µƒ|ÜY‚ÚË[ý‘Jê±>ä=®WM›%]å·ï½î_6ºD~÷ËŸ?Ã9–Ik‘T¨–ÛÀC˜Õe·ûHƒ*¹Q6òÙ-wÕ)72Àý¢P[Š3k}IÄ êŽ.€ûnôvº}ºm ¾{8A‰6¤ÙBw èŠÈ‘ŽnJ<à0ö€£«ëÛ8¾iÚ»ÆÅ¸¯:b´ê­®kéPšÕ¸vïíápAÚ½ˆ<—ö__çÜS’ ÄUt'qíÅÖõ%âí³Ñb WÕ¬ð£û5#lÛ·¬³ 5%aï°,ö"€ŽÕq&7¤¸nëkÅÐĹ£”Ï釋±¹Ç4©ƒþþåuêÇWEê#øøZSáã ⎅‰Q\cyÂ9œ¡ ã ,Œå™íÛàõ¨†fuýôviŸ LP]¯ù"3)!`î×fí¨‹»«IBØ=‹&Êô#‡ö[éƒå”Ü=ý®ñfNIG*[à ï Æõ⫽VDÍ)¦E¯oÙg<Þ•¼ þZ®ŠÚõ#Tw€‡p¡v@B X˜dÃP造¬<½ýSC `ô̪[ù¦ Øï>zÑ_ÿùq|ÔVèÊ” zÇ Û?;_F¿·cuѾ3Ç G˜*¸¶‚¸ ,D8¶™bd„‰«°Zf[wky äuÁ‘Á83æ[ÿþþõ›Mú§ßþÄ{1Žëz[®Cƒç!ÙÛ ~¨åµ¸îîe†5ìæªlF¤H^«ÕØ.´ØgUúq n{"ƒgܵŸ«hªÈõñvV[8Œ  lTÚ=ðz1Ýír_º–GnÑy!Šyeò¦ÈÀíÐþY Ì18DÚ*è*»íê¾TÂW{€\K®¨k¸÷lÔ»l›ˆà™™ÕÝ;Ü ØQE/Ôó!OJÓ½ÖÚ’Fº&ÚÂÃ^ÝûC¾ÿÿ«²„\Ô‚`W[¯G¼&dø*w½°æ¼‹ F”¾|ÁÕgs”ŽÂ 0Åo)âMo@Jß½|§ugÍe2¸³[X™d&‹g©|‚s²ÞÛ¸÷ÿ[N‡Ã}hûL%CÓŸ¾ûWr=?ZÒÁqC./ŸŽ¤Q@'PÛ$þe^èΔXô¬À3½:¸¢¨©xŠìZ‡J±Ä&~º.7©8°w[ü¡t»ÎàO°3–×êKêÕ}nT5LöN^O7÷ÅÏ®…Ä©tišçl•=ÅY›ù†Á«Ó2†a†±™6Ò†œ…Ð&çÈ—it¹wYa`>Еü:÷s·­ /Ä‚W'Fj„:¤PÕÌ…Ñ‘ûH'Õhµa%‡!¶š¸>B‡ˆ.”oì#è·.PmàÄE¿ï—kœ@M‡ñCÏ/•ä¢ÙÕÁ­ïSƒ?ä5_qš#L¡«;D/‰OìKí[™Õn‘û<‘㪺ƒDI° .†±·_×ﯟð)ÿÿ[áËÇÓ^«„5·@½Â–ŸèîF_ä‘ÉÐÚÖ#(=W¸ds¯]àJQ.ΖÀˆx¿f‡š.ØpCõ|€u¿¼ÞâD7qÚëm5ö·ç±°2@ ¸Ê[øÞ8ªF™³Ñ½àÜÁI¬ýj\žG¹msºéÎ'/±Gû1ÁÇZmŽHcÁx‘ÒÞ!ÌGmQj]„ç>“NòŒÕݦ-Sµw‚E÷P‡-\ÝËŠ3#Áf‹^êYr‡œábv9 IDATâúZ¢ÏJÂÀŒU¬BA¶-vp¹æ[mšÝ¦k2ö2Üìs›XÈøb‹=aÁv„.å£Å %± Œ"é4éfëÈíê0èI-k3‰¹š¿¼á¸zï„ë×_¯zï—ÄÁêºîó}^Û†joøñ<}TˆCX‘ûåÝÒt-V«ÌBrÊÖ¢šÝ.#æO¿{H„Ï;!ã¹€Öø“¯Eœ"êò‰H ½{æ£gk™ëù*=ú![tfŒC9’Á Žö±z…k°ƒÈxC·_NÅh uŒ/fÅN420Ήàðj¯Å°Uè‡`!›ßaÁÆPÅ>í¹ûD=/µík™`ØSvª$‡.ðZ‹Ë7ãA¬FÙ˶Ñ¥À*¼]MkõŠFϕ9˜ƒ ðLŒ¹_Ð]õÚå¯4Û½f/ïã-@¢Ã-àuðgßÅìF6O`Uß»3 ¾æc²-¢·$YD6†u;OZü–™¹Wï·!f²SÊüý—T¼b÷ÌýjñåãË£ß/{Õ‚sT·¼YºòM²cÚõ®ñh(Du¯©¨-”Gžd¨ ÃU^×*O°ÎãÝ4ö ÃDãðôüè‹kØéKµdÖ‚Á ‰¦˜®aà ò"z Baê}'o z£°B ÃÓm•ûôfÒ»":Õ¹ L)®®छŒƒkó"ö¥{Mt¡—Û-Ábï‘éz u(Ž6&bä–q-ÐLðÐsk=¶#2“Ž\­ÇT»½$ÀP—®6Êï‹DøuMtØ !3ìà})gg¼Àk“Øhp]üv¿`b7ºq¤qcÅnÓC”<Æ "¤L½ˆç^.Ñtýôxÿ··BÆ#åÛøÅÇ#Xש›4ºnº¤U 糈ºõ¨«2qpx¶¦œ„bCñÐÜ:IR¯Œd~ýz¡ìê*ÞÏU=WÑõÝË~­ÕRV˵JîµÀ*ìõÞE…‰…¥nQM 4.÷mŸbÃËŽÞ'¥ y®ÐUÁ«øœC`c½^« qÐT·³Ç1Þç%#È{÷ C´Ó…6ž—SïF»ÐÓ4Ž”È¹lU°«±ŠGóYw»×‹ü(KæF&¸ÕD‹’è`ו-ª•]ßP/~bJ…åFŽÁi#{·íýw±ÏñŠ`5®1ÖuÑ"í=®\½|´^Xª”¡X}Ø0:«ðìZJOy&ñÝÏw«„nü²®ËJªÖâ4Úöºú„9ÝÒÃ3án»j@ÑQË=DE8Øðê5Mò’Á ?u¿U[øÝûeÖ·R¡Ÿ• rs=Ì‘G§‡sÇÙ#t†9ì° 6ᦴcA«Ñ…ûº ]'´m)ÅpÅÙF<êuNc.:Üà²A—Q5¬p ½¸VàQTõêul6µå!¢ð‡%>ò2¶¿¾èâëÛ£ZÐy­Uè&Û}Óà|Ck²Öçf‹µÕXäþ ™Z«Û†%†¦´¨Õ`G}Øç’`d@|}¤š4Ü¡•Üå­ç/îJ­PEè’9®‰UÃdW× À¤×-‰ìfù¥ k2yÙ¶ÖŽñ,×6ä@Ä"æêúr¯ßÏ>ñtùu·§‰[QbnyÒñ¨À¡¨<½~Jmª£¬öóˆû~¯¸šÅÍÑ{U ^íÇ"nؽ|£ƒì½`óÓdzfe;›µöÞß>p£@æï~úǯïýÁF¨¨†]$ù’7 “3Ø~Ìf°Û w‡¨ÉNkps¸}CÝÛm¡ý0KŠä¸Ö~çYU‰Ãþ&&¶ ì;о»å/>žóQ ÷D0ŠòJab\ìê\h Ðúö± ÜÍÆa4Ø|z, A%ц‰ εZÝ\Õgæ{õA’x¥DHì9: 5Rk"¶3y$Ú6=ȹ_Aª‰ñ"Ý«%IôÈ3ª{¶‹j‰ ®ËQì5FWªñäø†X‹&YŒ¬‰oBöfèCy¯ÞÚÂ&Ü/ÿ}Ïv ½âªyP×¾ÒïQM¹DljÉÏëáuŠçItqõ¢¸ËydXï…³:Œ=Û:ìÈ‘DRCãqu刀á¨þ4òç¾íO4àä‹Óù˜VŽ›ž;gW}Òñe²ÏX(6gñª™~“Ï]ÎÜœuöÒñX©cÖÝp„kí!³õ¥îßûØ×QÙß;âÈC¬mÀ=€€¶Ú»z.j¥ˆ oÊ0‰.·ÐÁ½øÔ$7ŒÛ‰l‘Ðu„ˆy­æ†Þ׫/úüCO"NˆD»FAÔ׬<øJÇá¹ì²ÃˆL‘Õ%:Rr_ËT¬† î=“X¡š16Ól‚!ׯ£H%r“kAk;7èPDWÝ€‚,#šUGûôþ&êºú<µ¡ã†éFuqH¦âý=^n£¶ä1éi‰ÛñtÓ¨*Ì,!ÐÜëfnD­}uµ8»ÑNr^2á²âþÙ-F?GûU˜ŸqÝPÌgE<ޱ  Êí®r#‰ËEo ”«F'G©Å¸úb`,tÁ ’,«;A¸o›¬ÝB¸@˜ß̯_(PÙ2Üþ°ní#6ôÇ;ójÏ…=BCŽ®5»Cb·BQ3õA¬¹0¯#ßj•‚m¬µŽP’ËMX8‘"¡z}-·ÂМ9³!½ƒgãyàΚaÒTGÕÙ†ø aVw‚à ºÍ€Q‚M˜PA«+CêÎîYx2’mtd£ážh$²:ƒBcŒÅŠ-1vù«WG¢ j{w5P`-gcÀ—={mý!õâ*ÅíèÁ4r†‰I µçz³L;ûÞŒ‚Q8ÈG?@¹|ËXöõåë~“È^|c*˜Zój1,K$ÊÝ’Wu&»»¨!¡„Š ¡×žy®›vïjjœáF¢Û@ùqÝky'eäÝ_Õs¦eÀñ“(3¦¡Çz¡î¡j÷²‰U;L~H!`‹ômÊØâ.ç‘ûh²šZHŒ"&»;À÷ë]ãTÕ)]ê­S³q‡ºê!–K³Ó{‡=òÜ­þÁôìnôAèížy”Š"Êî{Œ³¶iÛÅ–ƒ{G|ÆÀoµÄž’©Q°D•çôµœ:ÒQcWÃWìSi›C[›Í¹ŒE á}Ùp4jm×S†„Ýr$ HÁU X@¿Ä\>s7rãb]«\fÂ[¶¿·ói [g ƒW›á¢F vj’9òµ¼¨›n³}Šö²ãz¼$ol%»¬ê—3{׌ZÈqxfÏÅHÌæ²2ªšÀ4 ªf£üÇ—~üNl8«ž@í% öåÛ«ô–&Û ¢ø‚¾ÌSRðêBhÁm†ã…€̤å.‡ã¦X¾qÕ ûÏ¿úÏöÛû×ÿéûû›Ñ½±à:^>öºÛDãb3£÷Ò‹ÐÎ@ÑÍÚ›ÍÑÝÝkdl¿;fïDírÇ U˜‰x°»^Fÿ®n¤›F×¢„† !Dh7Ä]íÄèÕ€oG„ìêù½}äpWwsI×Z Ô«‘3sÖ4f95Ä ½Ib=8âÇì{ÇB“¢wƒ#¦Möµ ÆF·ÄÝŠ2.+Ì,&éƒØþ‹µ 3‡"⇟~W÷Õ¥|›‘ä.ÔÆòœB°¹‡ðÍ9m¥I®+M,·l:æ¦ó!}³íݤ×pØÊ12˳ڳ¹ïŠ€ûZSnz¹˜”ÝÍn¯î8äÔÇsüçÿôgù~û~°›‹A)LáqM”I±™\s4`b-ÔŒ(SbÆ6`2ùlÐëšïsÆíliFt ).¢¶ýeÒÈr¯«²Ágûv{[û{W-îñ)îò}¾æ?}ý‰ûÎ ä‡ÔûÕ/#g·Ù'à²8jDsû¯”JòÇ=s'™Zl(ŠîK•gUïöh¡¡Í¡Àn¥—ëðOèzÎH ï¢<ø¤s¾þéKýËo£Ç'ÅbO` ‘;³6÷1?#ªûÑü0ÄžnÝ `Üná•n%C}øú«ÿþ¿ú÷ñIx”uÔøOÿñçÿó?üý÷/wFÉm‰-thQißFž gQÞ¯‚-'Zc’;i¸Áz5t´'ÚÝx w``}ç‚VÆ¢`rp,‹ìÈS½ªÕ<¬?úðò_ÿÅ/þòß¿Žîæùù?|ÿ¿þíçøÇsÜI,Å2Ò†• âªT½z‰ø.L-%äÕÅ<ÉèzQÕ ýmÇÏd²8Æk1$¯®†`™`‹\Ý Ê&º"4‹$Úe™çy¿×/¾ÿãã¸un` ôè#ÜûÑ\Ìž,S ¤=ìáîѵݟv;›ÑG†€n\ÝL,°Y&ž`“µ©\àRàËõCo6@·vŸFÐXýÿ1õf]’eÇ•ÞÞfvîõðÈ9+k@¡ ’MjêÕRÿý`-½é©%±%6Å¡)$@Ì5defe„»ß{ŽÙÖÃñDw¬•kå[„GÜ{Ž {ïï6Ͳ‡ ·Qu#óš¦3:} H8 ‰3CAõq3Èìúøùãûo>ýîÇ‹é Ê!ÃøÓçÔ¾LT5ªv! ¢œXˆÚw+¸à;<éð°°°itÖ¶>¸«r°æ¶ï,äu'‡¡àëêoO}/ßå€ >:†˜9\Å!õáÓã_þøÅw>=xÅòßþÉS[9rÀl]ebÖ(¶…=TÆF[d·ëÕËH²rFϳ‡Ï÷¦µg™G ¬¨Þƒ™Ð˜¯º8$«^Þ`K•Cu¨³'kd¡º£ÌàÆìc¿¿üâ_~Ö^¼Y©EÛ?ûZlÀo`ê¥æF¢¨>:ˆN!Ù‹-N}š‚ÿ¹ÁU´#¡º$I™±÷‚f Qîc¨yž&ª€)3hŽK‘Ĩ"ÌäUe3£lñM@¦èC*êrå›É\Qæ´Û†~ó£O>}3qL6OŸZÚÇï=ìow¦Š7æJt†–ç¼U„CK({¹ywv¥CLûáwŸÿÑ<‡­·¿øêõú‡ßáB_ÝÀ}¦hçJÈ6T»ÖTŽLVÂmÖd2PP?øæó?ÿáÇa»¤¹ " †ýöþ_ýÇßì£$XOY#±×¨TwªjHñôx·›×Pƒ"¦øE,êÏžþøO>0Ö”Á\•3þh&6¸¼÷âñ¼ ³* hK•ª¤)Ï9<öEjWK¢Cšì8TQ”è_ß½Y »—kwPùØ)!¼™Ê~9Ÿ%–E–›×@¡Q(©2Ho²oê9jYÔ²Œæ#t:ß³±Ö ž{™ÄËÚÆ@8S:ç =ÉÍÜiµ6§Q—2Ž^hô1³ÙÊZ.4ç”Çi]—žV—j³H¼f¾ëú„P­\nÏ• >ª¼K{ e 1š R æß{ÿù‡ŸÞ<¾1 ‘˜s{fö³T}Yo_7O×–²1JY °Ü¬“±,9ºS)8¹3Çð¿ø‹?~t¾Î} 'þü‘¿ÿÈN÷Z+x±Ì(:9h£4EÂc( Ò ‡øÓ?ûØ|.ë}Ú%9í63˜ ø‡ï=üéÏÞÁ>=2 îSH6üCÒk×£#e*3\›@æCeQ>~ýåéòpMW :m{&áN:Ag )êʄ֌‘¼ÊûŽ”hÜûÎ!_`ä~?î}ç;$ã½£s§9èÙ1‘h£7k§<¯ _ûv^Ò‹H4ÂlñØ÷^ö¤S¢Âq§ZÁ¥™„+e)ƒêtéËy LÆùZẂו´7ŠmÜ9ÊalS¦¨‘]\[„´®îï—O?yøâý›‡7 •ÃŒ$Uó©Âïq=sœ‘fÌmƒ£i"¶L«2šïUá^J3šäUûÛí'þÇŸ>YµŸ®é©Ó³‡F3dàá£|ûÖHXL„©lW²jQ3QMGÿãïzì’&¡Èùiç}uÇ¡>Y]•5º4·‘£Š„ܯ !-·Òãuç¹ÅʾƒŽ%|ýLéo±ôZ7j§å”?L"{Íü–-‹º$prÎñzxÛ® h°$-ÜæÎJúúõ×–9âU,/º›s§B²°¡bi`—¤Ùv¿†Yöí4|}ÔÕý‰3…µ,-•ûè<8¸z3 BTÉâ’ffÔÛí’Ù¯ëÏùç¿Ò–ê:÷|ôpÙ¿îš0Ðjlîyˆ¶BmißÿÖóç·þìÅhèʬ™BáWaõTæ\¦ f#Ö`(£v”…C%“Ï4)¡hª¥žÿÓ>ùî'-÷3U23ã”Fpê}0üÃç|û;'2³¸—›™•Á¬Òl,ÁrÒÑðïþû?<> !@¤dîdBsVÌYX·ÞNÖa5Q½§)ä23–š=ßo‡îÍ{ÖQÞ<ûÅ<`´¿ûù–=mõËdÊ=ëÆq¹ž@^±í¹ú²©jŒÐÌö´ù‚ÀYÀ*¥Ô{š”»TK[kУ¢>üæ_lë·Š7c<÷ hŽ[鿍rº™˳Zb'ˆý´¶‡©ŠÍ ªÂÕ‡2êâqS£ucUe43Ž3ØëÚý ’À¿D€¸²ùÝ–h½ŸÝQe£›/†À³'ëw¿ñÑó¶?zþ8¼¬R—3ÉÉb¦Š ÐJeóUºžUó®-L/‰¥ÜOÆVrƒ´P{€ñ’ðšÎˆ±ºÔ·Ÿ=ýÎßÏ·÷˜ŠÆ±¼Êʧ:£²çáÍßô··lDCU&¥$w¢«D8M{þà[Ï>|ÕÞ'xhl´y³Í×€S 0WžO,Ù«ƒ™}@Ø•ÆV £špcüÆ“‹‡$«ÊJ„›Ëh× sÔÛËÏÏ ,UöÊVó~IÙ!j4£&ᛄjEušˆ½TÒØEÒ÷ÂB¿YÔ+=|Ï}•"p1ËA_yo!„?z⇃F5 K¸)§5±Ø³ 4+%[kÂ<‰¢ÙØ*Ör4Ê{æCˆ¢z©nªweA¥ só7cÛ·:6cM½éïÒŽªiNø“oܾ~ù&v_nŽÏž=xÚüÑ¡=~ô r£5`“¬hœz¹;d„£r&ê ˜.DJÌ©Ý⌉‡<ÆeC`d•uš;«\$ È”¨ï=¹ýÉ_èþ 'Qȱ®E"§ä›ÂÌäéÏâÑã'¯ì¾†ùn€ ÀRý`¶c0âÅ“Û?ùÉ78v2¯B>‚fSÔ3ЮåÛ¤Ñk,cœÊ?Wµ7ŒJ£[W ?®vûÞÍu!ùºØÕç1c“ªhÿôòr¹œØË-:†¥Öh ‚RÁBU •Á€^ã ÙÞ·]y#+c˜m•¥­ÃBµÛ‚àdÃèÌb[NoÆÇ>*Ö.;bí[×½6 !ÂXJiªíÆÁ#Í¥*Ò”nZªu\o÷¾Ý ‰%Z•ÝM©)¥ªàñä‘ïÛ¦[Y4T] ,$®îÙ¢ê‰Úÿüãï\RbTeð÷&L¨èïb¼ 7XûZý¯þŸþè;ßüðÉ~¿^3 UbãŒDm‘­këÝd"%LiŠÛÐ(ÁéVÒ!óßüð½Û§®œ7™ ÅéT¯ðr˜¯þø_½ÜÑVMtÊ4Úkä¶Dxîößýù7¯ÙëgWÍÿ5ä2]róÌ<Þ>æÑ¥2ó„={È™ "Ôïr|]02³O¼Ø)wáV(lÃDF}Ô,ýÜw# «Ô¥4 Ç ¶_õm(ftÈSÛéÆâAîŠH33(· Žî{ ¨”¸6\úb¾xŒ ¡¬¼Ò‚Ɇt(êBç†e­q<4£×‘Yµ¶L:X»]—qèXø®N¯©š™1¾˜wØHÀn|Ú´4‘¢ü½VÍ]¹ËÛÉðúþ|ÿõå_sÿê¾×fç·¡g6ߤ®g!“¢ì¹Æ{8½ÝHƒEÃŠŽµÕP{Ï}÷›ÏÞ¿­~!&]ÝhZèÀLœªj"Ô?zöð³_¾\ÊØfºqÊÏyhp¬ýä;Ï7Ž¿O&ã”{êÂ|g»Óu¶'¬‡ÝP#ÒÊ*• ÜùÁÓcDÙÈi¥ôÙFH$Tû¸ƒÿ槯Íbt l™·²“*«¢Å*ä(&‚æÒ¥zµ6 ¢ hË,YEcGn£Ä@iä™4èôe¯çoÅ˽>lE‘j´{fWfÚ…A ÚÆ€¦ó£&7±2Ëš=yø­·© [CC¢Ê[ãº4LõpYÛMC|„QÌœú@¨«wmf]ýÞÈ*R3X@%&ˆƒñænÿåëÓW÷ãî2^¿<…/4¶â¶UM(íägÍ—ï€ wÔãv8ûs\‚Cå¬,‡e¯:|çÑ·k‰¦!ksŠ3^%t3È'”sYÂ×PãÀFYí5NîfÄñ¸|óÛOkßm.~hp“Š”jf99€+ÔW|,¬Öìo´çõP\1vš…µõð¸>y²zÕÀŒ£qÐ")Dðå—¯Ç=\U)³[:$ñn’xµñ4™AÃgŒ²ˆQÑÌ •upƒ8Œ½಴óù¥£Ù"ÛRƒð*¹n· 3ZxB™F)TvH©‘Ý­¹ÍûÃT}’9 ´ì¬XÌvtYlo^¿ÿ­G¶˨j!Ðýzr˜D¦‰ê©‘ ìs†w7àŒþ¬k©A»F/ƒ½²ÔvÔéÔ¿|ýö_~ùvÄ °Ö–…Q»jãþþŽšo&(± Y×:×¢¨ÙOõ«AU£gŠ Lð&}k IDATÝLqiø‹ï=[µÏ! d@QEoTÎ4˜w%ö„W²hÞkeqm5TôNË idíû7¾÷âöPó5™¶±Ï7üoÿçßþŸþðÃo6˜ƒ/@ æ,tlÏž-{Yˆn–°¨‘¦˜Gø6^<|°Þ´žCtMF$}^(€Üý¤þOŸ½µ@ïÞÃ:q¨Ú†6(óòV ÃìÜ{»=à¼ÝÂwG ШÞ`Ž1›ÔúÌ^êD§idf´jaÑâpäÎdš7^•* 6s»Ì•¬…ÖQœÊ|¸ NLêéMös5Ÿ¤ˆšæÕT ¤9…åó±!ùΪz}M¯„ÈÓž_íøâíÝÛ¯Ï_|õÕ[;ÕíÍÍæ‡ÞE-T™Z.öëóö#¹!UBÉ(¶ÙuN*¡ö³+Qèš‘("GH“û/nßøæ£D’V”îQ0²46Êáí¿€[®é„xüð¸ØËL“OËÌF£ÀÄ“›øá·ŸvÁMZýÕ_ÿ¯ãå“»èr¡IÚINi3Ìf„w kŸþKÉH™ó¡þtmŸ~øÄcÌC5äLÔl]fDñ¯_~ýúw÷lkWº‡ƒi2— Eì=—¢;̬.Þ.á…~hËe”dªLopÓH©¤í}a@¢ÑÍë´??L*ìr§åQ›ø2sKÑÚpÌ´ –0ÒçÞXÅÒbpoæ9JØFžU_ÓŸ7²Dú|)¡š3\=#פ‹Ì›ïÝ~׋ï´nôüòíÏwÚ·>ƒ\-Ž„Ñ3“HLʰ¦S3ffByÞHTÁDI…t ²š¦ð)´oq|tàË{dAæô’fè^Œq ýè^„Õ\J§p¶öýÝ¿<-ÿÓŸ|—²Âô]Wãß¼FøÁÑož­wŸŸM¬™¹4?I+¬ßo?üî'KËₘÿïÿôú×_ŒçÇÛ—;ö‹dD]óÔ`  †` ~xÜsz(½l¢í™xøâ–â¿Ì®2œÊ«Cç^øÙoî7ºUÒQ•ȼê·MXݯMhžª1ŠŽfÔÒRUUÕÜ5’•T´YK"(¡ØaUdùÇ+â;¹ûò€æg€L ÖXv‘•Qv)ÜÓ”ZÎÔ`L \#׺YnãÝ8zîgÒ@Ñ`¬q1á¹%/=o#—p̵,ý¶i—pk›i?ïK»ÙU±ï3ŠýrÙ Y©„fåˆ`S¤³lÖSUó¨.Æ5úä:Ô°RÕTî±ä’寒Þ;Þ~ðþMŽ“yžÒ_ÿü‹Ÿ½6,írÆÍM»¦"L›õ¬àU¢{z›é çt[lÈÅÊûxþäößzX}€“ÓþåüæŸ~õæÖ|dµ‡–U§þn: ¬ë{ç(‹ÕF¿ g)7Sa=üíg·­±f\3þÌ¥1 ª/OãÍ«í`ÖSe»œU¬Ë¨Õ$s)Xú0’âl™Ä¨0KìnÖ÷Êå@Cd/(s3r \´L‡nnÌÜplª ·Åp¡ Ã•Fî)¯zj&rk1ÙJQ,•²H§•îww÷ï}ó½·÷o«ÅÛq9m¹+ﺭÔP~þúËÜíR´ÅþÝ|ðlf ¼³¾[¿Ì§¥ÜÂÍ´ï‚Å;²“j/k±k·²ù,ž™G.÷û³å˜SÇ)÷XŠ&æÀ‰sddkÃÞGE„À®Ý+ù êûôaöÓÔQ&ëóÓù7_Îø«Ã¸ªTÍ]•cä²r|øÞòù« Í¡JjF°/ÁO¾yÛ¬®˜u–ûÿ~Ö/}‰@Ï»ûûÚ8/×Ý¯Ý gàÆáÖÚÀ¢m¯t3Ϣݼ÷hœïãµI²úØÕ–Ö¡\ã¯ÿñ—–Í%“²4•"h@Ãrv§šÍ”Î"kÃÉëñÊ5lƒŒL™y¡T°­—Ñ" ¶gJ1f¬¬xyyZ¾q!íÑSxwkžX¤ÚzF‰ÆErÚæ¶“¨®b”;‘ªP:MIU.ÿ÷ç¯þæË7ÛÖi¶ÞxõÚ»‚íØïOëÚ6Ìn¿Öéýñl±k381rdÂÚ·ã£GÇËýy¯–=Iý@|çÓç:ßC)0`¤I RZàŸõêôëËC·„—&7Ûú.Z‰¦ðk£¬ «@-sbb±ÇVT¿7—#€Kî7Þ*Ë#ÚVÆ"a^¥¥p0ßMŸ:¿}}÷L´û:‘‹tÓmÁLÿ]€˜2J¬•h=—¡Ã(Ð:55<¹•à‰€¨"FQò¶Tgò¶Ðü°Ü(WÛ§ªŠ¸|ýöTÔ¶\CØæt €ÇÛÃX£VÖjhFP:å,Ñ f2+1÷D•çíþÍýÉÜ0©$× ™‹,z¨BŽÃªÛµÍf§.#Òi77ëñ?Xm;t¸ýìååë7g–ö^—ÓÞ/YaÀ˜޳YÑ­‘6Ù¬Î7U^)Y‡?¿ñÅçJÆS^þù—¿^—› 8J§8£æ™F¬â5Zi¡ÁjâNÂ+Vs¦;ºïÇ÷n-{˜œœˆ¼I¤³k¿Û¯~ûæAkIW0MW!gøŽì™°2“aN•æd°r¬±ËhZŒ¹m QfEW猞pƒ×8hЮf\¥›§O±‘F[üXlªîÛ9ú9j,i®‰'r¯MEG˜FÖðʼn»³F6`mfnÜI4£T™9R{&æ4t¾UF_CÍúeGÙ\dÌâiê~Ÿ^¹Ò׈©¡Ÿ)^\ÊÂ8m*ƒ±P×ãƒ\œüê×in4ɦ¿ØiN›¡Cæ¤þ¸»!V`uG,¾ø§Ÿ¾¯L3£ÃÍÿõåý›3¶Â¥0`pŽófW=‚¨$aVPÒè.#ŽX"Zcs3¹õ>~¼ÌÎî¦7uùü—¯o©ì`;\e•õæ4æ\Ïæˆ«f‡pm‚º=†¯>Öì&w?‚}úŒ6aÎÄlŒ0&LÖNµýôg¯³ùê[ÏQsZM˜YË¡¥Q*²b¦-l › Ë<ðÇ8n$T$§¹•I`’y1Hé…•ÈW_´ÇG– wxëk‹É¦“$!KJìFÕ eÉ÷Š™A}‘ˆ*¯:"©žè8ĢѱŸ3÷­*SÕK)ô¹„®*&«0 d„%‘‡µy3ŽZÂKVމö såPÎ IEÚgçÍ#®p0êjÙ3Ðs,wl‡õYcÈHO,™ð÷Ÿ¼X¦ ‚„ÿÿ~þåë­ôœ±Êï:¶”û *Q9¡d¤È™±­•v|ÜÂB™Ùm»ùƒŸbtk ݵ\þ—ÿç³ÜšY1öQ©‘hÞ÷™ÑXfsa8Ù«4ƒÎgËrÖBÈrËOžøø‰#T•Œf¤K%ãÅúßþü÷B¢èݨ’K1ùEó*Üj‰)ý]=\¸9¬U•âÎ1av«°0Ìš¹¬9ÉÀt<Ül—£<;Q³Ì‘^_Ê ¶ai7éËysSåBÂ,v]é#×+kôÜË5¹I¢gLˆ%œÅô,ÇX–­OësVS5C¢~zu‡š›1‘‚]§‚¤`“öTÇ[[šAæ3€šFöY‡“d ®Df£Ü(Ó%E¹YÌÉ8@$P½£` ŒÑ•Í6Üäaä'ÔNíT7âÕýùô2M(aƒ*¼ïÛ˜a)×ý# ]HàÝ4\ìæ¨‰ Þs~ðþ­GQæ¿üš¶Ù×C v`@ƒX–Ÿêœy÷ï¦ÅWÀB™ép›¾Ÿ!3kOn|z{îU{aÂ'25&E‡]öòóíëßÞ垨ò”§\@©Rêº>‚¬xÝÕ²$5º‡¥jÖ”hÃ(G±D‚RЂ`Õ¾“Å*ícAú ¤Ä4„÷±Ý\¡Þ¾dU7Á€ÒtMö7”¹{ µLÁFÃXz¯BUæô™{X9LEŠTŽ‚Å.î`wYHÕ8UU(¢T½cŸÄu˜_ðÕî÷­‚÷yNê‰>FæhóÖXªlÔIBU“¢'Õ58Ë«wS!½Ûwä;‰áÒ6/?׺áƒO?øä³fàåÆú›_¿ô›C•º¦0µÖuùÝÛ³–ËÌ®×5ì¦ ƒ®ëýÅÓ%\0ôýòÑ{ÏÚaòr’À—¯ßn¯î˜s5yÀ\p¦ûÝ©j Ì?yjʇ0'?‚$²m4)uºüø£'O¸³¬Ø…(pšGR6þúW_œ·*WgÍxæ.ÌìËš¡Å#÷,¹—òÆÌL;khHHªAVL©A­êšqB³y0‚&?eõB±è؃(`~£ôC[úr\Yl—Š’I¢f6û yvåpw÷˜hô…~ðùÄg‰ÓŸè«…¯Á,gº«*J³f\Ì)(+‰»{Õ¸®Ü "k:¡gkDŠÖn›ÉH¬tc›•¾[µP®ž‹I= BF•2ÛqÉK^_w J Á h†p˜s#{²î’}ÿ¹!'TÀ›ÂçŸfê}pj8¯.¨ã5…€×5¤Gts¾@)¼¼ÔG?AsÔ¾³^ÞuIÍ T–¼De¯}„Ÿ÷’LT]ƒøtÝF¨P…âwb8ñÁíÍóOAå“If“©7«ªÔòÏ_ܽ|9ÍpË}÷*Ž5(L.µbãâáÝ0c±Dë£Ö43ž-Ë%h.Z3«öÝË£,$VšLàBÀ΃®PLJ6tjh ì²™qíT…p 2¼»'-™F÷¡ÌJ.3ÊViáI™£¹KÌcacI$\æenƒæÒR2PðºEC.M,™/0ƒO;@R# ä@Ñe6®`^ôbŸ$Ÿt”áºhVó±oÛÞŹÒÄ»„æwØòÙ÷§BÅÇãÅÓƒ²$nŸ¿úrûrמÈâe×À¹ü¾p?-M“lÍ+áú-j†@?i‹Wò?½yî9rÆ ~v¹ûÅ//7nòBfU¡Êä­rï÷çá1m½CÎBŽ @ܘ»Ùâïÿàiƒ…`°D¥¼dvjÐ^í—þ»ßÝ:vôA3²GŽ¥Nënø›É9Ðç”ûÝ˱ ?ôn¥N”Y6ºB¿°†®É7ÓÀ·Bî}ß™ü’ã$— „=Ž£–(¢²9õ1H9<Äò2 ·]Ê5zU…áØÖ°ÒØŸŠ¥4‘…˜±õÆaØ•µgR±z{!5mœ×3À¯©JS¦<®…ìã‡6…R\ùþùÕ—Ì«-ñ`if¼®†`÷dO˲L —:4AÛõ N3æ·ß{ø­gF]YYûNMº\Ï—›þÓ?¿Þ­Uæ±$í©–¾Èø_L×PÉ1kçòFÈ*“–}¬%¦­e©Ë:²E/‹¬:Ýíª9f1Íéûüû “F ò“‡ÌÅÛÅœ§ŽhŸ]tÆR‡¥ ‚§ù®‚SEYÞ½Þ49ëïl8ÛèB’¬÷ÞÖBŠõ¶¾÷ Y–RæéŠ'¯9uê—Ëœ £êúû.é÷•gƒ^ý½UC™™Y½ãÔGV•C¯_½yûúNû9 ÚzÛëà6϶À"HQ ³i‹WxAäÞ„VÈݬ¡!KaEdjëÝ…­Í~’Fs„›£¡+b]~ãþøÈ#rW¡³Ò0¸A¨ÑJ­$‹)c¤LÅ: /B—‘TeGï@¬Çî¼ìÃ`Ñ0Õ@¬¡©¯ì*J”k¡\êãžv¿×-jfW]™zUx÷ÔÈg5ZDº9L…)ï=Ë,šª²0²`2¨—Ìhä6ædš‚*»~ÌÎúìÒF<ýè±thNñÿ󯿶mŒ¬Ú;ÈD­Y£rœF³å:²«QÁäTRŒ¥£îóæ6 ›H™ýæU󒵆è&À8ÆÒšÄ}§=ûÃwiމ9ŠS&j$ªBö£odŽÌ’¢fМ:¤y5Ñ/ÿð÷¿]Ú[† —ÖmF±+¬Ìˆ,$`fW+ˆ¥Û”dv¦µH² áUÍ8\ˆu(a¸=Ç(!e¾–UÎD/G…{¢Ê,aÛ}¿}úèd—G¥c«ÍÀ0šWØÖuʱÑZ5Ê7 †ÁkfZ•Öõ`3Z¸h]ÍÂYËÜËW¶É\­4ì4ÊÝn¦R£nðÔGÄ»®í¿^G XϪR…‘x›’¶af%©4J2[ÂM*Y°™r¨zYæšr(sÌ“~f¨¬í°ÔóÙÓ‡íáÀÐ^sùì‹{J w“Çd–;{°sTsáJ¼»U¯jÎ!éj¯åfÛŽ%hïýÒ_ßoƒ4•R‰b“\@Veù°a|~WæsO®ºBCô®ê*a=ŠYn€2%a‹Ú²»ýÿ¾\ÖFS„OKО{\Ê1h½¨Î¾wÀ†s]¹š\0’>öä(·ùù„#GviCÑM®’Ŭ&Š XU¦7ƒŒëØK÷w¬›‘æsB-­î>‘€fÓ Ü‹å9¡–Æ1.KØ„ÂT¥1MÝ€µÍø«˜~ÚÀañÛe’¢åÐù´½+¯M5u©Wƒád8z{n€¸”œN/o…êÔ°}wúqYW¨©¹¸ÌÛl‰×oî4@ €æÆ«uùúo惶ÃábûŸ}÷™î»Ïù¢j{û’o™_o6:îGž1Òè4Ÿ<<~u/ÈÀRÕ™ŠëØ `éFõÌN¿ÿ>‘€qXý«“2j0ÄP-’'œÒšùbç_}µÓ­@Qœ0½hÍÜI‡šÃ–Ѥ(…ÎhñÓ_½zóÙ¹h Yvsá+ÃÅ€IĨ%ìÁ³¥[Vqàn·l­ÝX‹’* Í9c¬Äˆr³uaóG†H§ZÓf2X»Õ й/ÆeµÒÈ$«*î¿ÜA„W‚1®¢5r·*™ÛP&*¦YSœNÀéÿÕ²døžÕ¢U5ØËb¥€AëFɘ¤¤ Wf?„WUÐö¤Ô%£5^ •9p¨Œ0³‹êИCÈÓa±KÒƒ´ Eu’…4óTAµºí=Íš©á`GMí¡cÊŒKØ·Ÿ?9—ë» Éã7_îTU#|eï”Ó‰$¨ «w$`ú$ +pJ uVä³g\%”Qoªÿì×§§hkóá~é»MŒ°zq5ÉÉÛµ%’3í9›pÀ©²yŠ/n*3%Ý{•…k ÿݾÿæó»äAá…ò½"g!]ö!Yó¡äéþ2iÔ£¸RÌ„ÊÓ£ëV™¢Af¬qKBôwJžÜ·µÔé2‹5®7Ð"T½M×v]ìà*ؓǺFטåm¹%$·QÒ(¯œ657ÒÍ=Êš•iŒ]âyr´ek3š4o}À¬Te°‰(ò³Ë€VRœ#¾+1ŠsêHÁÚ"ç&"ÛÝö+s»vƒUtz¨¡<–HùØ ‡¹³wª'¦®Õ®naÉË÷Ÿ·Ã­O]Û/_ŸÙÈV c¢´´¾ÕélÉvò}\á’“ñZsO msûRØ—»Ï>ýàh5ˆrÇWç7ÇÎ8Û0óð6–&ÃÅèãƒkÄù²k`ÆÅH"©ä´HÖ$ ÌÒ¦±; £íú‡Ÿýê²Á ±Ø3ÈØ Cê~ý¸7îÛváÆí¶¶‚k˜¦‘åBv0%åpò±› yÞGWÏeálÓˆ‰–r W¹1¢wJsD„ï­Ê´ÓݧZ¿¾)õkÚ°âA£˜ÊMî•yñ‘ €QÈ$,ÐLRìj[®Â/¥{½fD@•rTކbŽ^˜!Y×á;怔ȫbä0Æ·Ž+Ìg=[°žRª¦‚Þ=QÓ}3Œ;'‡ÈÍôÙÛsn6ó½gÐÈÕ«ú_ìntøÖ‹G>­÷,8ûæòöõh•­²Xª”ˆ½q09v’w_mãœä2oÔë æpc]ß»}úŒ-¦P/½~ýãÉÊ0gÃØnÌŽS®º³…ŽÔþ.mà÷_s'̪Ä3§OšA2ð¿þüÍg='F••§üš-ÑÓ Íì£ÊýÆ`%ï4~5TVdVŽ˜Ê¸ò„Më™Aº70jAcàf9pY@r¤1ªTà”f„F€—Óè÷³ˆ…r¡œ¥Z / † <’©NóJ¡´Øâ&9ò¼[øâF›òD™cdÍ Ç©3H6^7 “{SÔ¶ßk{7E«9>~ª0Ô†X(Z˜íVFHý"•1ÚÕ³Äa€£ßJ®) ÄÝvʸyÆ<)³«>€ØZkA §ø¾büâ´‹B0z 4¯‘) ÀLC;ÛÿÏÔ›õH¶$Iz"ªfç¸GdÞ¼u—ê;]Õë 8ƒÁ|çï'À‚ä 9ÝÍé­z«º[fFFø9f*ÂóÈê×r w?n¦*ò}¯Íœ;Ëèµ`º»~ùå—À’MT}ÿáÃ=& 9ûÇqvqÜËΪé:¥OO2G@+²¶bì¯s=“+ˆÍ`ˆÑ;ÿñxÿOù”±nxè-jHºD¢Bd¬þ Ó¥r;gô\kÛˆ~‰Õè¥6ò.f “miQ‚ÓÚzñÂrë›1lnm;T[¨| [÷6Ïvé_ÌqÆÎܬ˜·»Ií¬½å¨Cã…¨ë%/R8INÒ.wWZ‘Ã!’-hŒšeÄVAl9£ ­2^’/1ë6k cóÝ÷…~Y ©¼tnX ä6Ü£9舰7àÙ‚dÒÁ–âåí…U÷²^Wјø<ˆ_„î蟟dÏ/úùǾ lj D10Y𢻲Ö"~UµîÃê×ݶ±ò†ß\"Æb}½¯ùé§Ù’ º9=Æð ñ‚(¶'‰6j ¬$¸<”¼7îAaD¢¬Yð òÿù?Ø:32N³‚¥²ƒ"£9’HK[F£LwÁ³µ!ÈÍÙ×87[:ˆàX ª* "bËBø2x8IÔÔó<‡Ågƒ-o°K$[fD:Ìq»½$"ZÔ4öç•ãm*ã1³ØÚÞ3Œ­ÌÒZºÛMBÉ-.›V“#ÒÑëhǸdc(ÐR*CÞÒ‘¼îüéã:àúýVäs" ë½µh¤›‹½1Á²Ðä-µ.¯IeÎö¶æßŸjŽ0<_Ÿ3õú<Þ™'—oJv©<™‰ÞZÜÍÛ1_ÚKÝ% p7‹DÜkGȇ·oîo»à_ý0Az‚L;ÑÂÄÊýdp¡2÷ˆ“ÇÓs™$3˜ˆ2õëô÷6?!SûöüÓOO·rDEZªé¹øŒ¹XÙHƒbK†#–&)¬Ëg²GRëÔ+" ôì½E0å²L)„.ÉlFpFÂ…^h3âÐL"BDJºb5'F•05¢÷r}2‚NRV’\©´¾M¸1‘™–ÆÒžZµˆ9,´²¢&â%Y³¶Uåi®: ›Ð <Ýœ)”uásèÞa˜Ÿ{÷5ó_ßЇM„[SkÊpdn[fcäîɰÉbâ. Æïï°¿¯V¶ŒqÀ?+…Í0j­šöK7…°‡4&ß¿/Åzr¿nÏÄÍ[ IDATMüÛø„=˜ñ/?ÿ÷¿úAžC(Ę[$è ·ÖtÙSo«ÀГ™ÁXïÒúêá‘@´-±Bš:Оuÿ^^þDÙ”öÏ?ȨÌÛQ³Êç1íõ{ú›ÇpxÂà ¹š,y”YìâAƒ³ÔPi•µ’,=8T"‹T$[ôÒ±$èm‚¼,ç*ÜzT§ãÀ«þÄÃח߯„b‹pUªÍ¼ô{Ï7]–‡½‚‡÷X­ÈEdÚi6³‘Ó([.PÖÌ’Ê[öN0âF¸Ý™µo2BÂpýðý‰Œ–3z°…²út¢ísÍq2~m­ ­f±œà¨ZÍÑ}__ôRã M¢7‚. 3þüW¿}žs¥Ä}ÌêTÀçJ90k#LË&£eÝ ÏLGSÀysœ™™n¬çšŸ<Îð¤åÁ¡):BA#¸yî0ÊUyiýBœÒé2U3¹f5à¡Ô^êá¼2£Í1/åQÎÌaФºd;÷0§Z`ÝÈ$Ë®è{ÖRÏ·ÛN2ÑBfzÆAd‹0jÎÙ3>}|¹Ÿ*îÔžWÚû+Ö!\#­`Š}ëó˜ špÏÉŒNè–•¸ï]º>Q®6™_sy+¬ëf‹ èóÓ'e$±[7DŸË2m¥áL,¡ŒÈýÖѰ–¦Œû ¡tÏŸz]…Ö¿ÿÝÉé{C)£\Y&9]­Üª†EMy™®9úÎöÊHy¥ºÝ!l«r팙á Kãa‡%s:È=ÃÆÈûòÄ\×t TŒ@#6ßcD2oL".%À£†ÉÞòœÞLÆ‚´¢Übj5ª ‰™J÷9`I­™ëH•]oD4ËnÊKt¤Jç’ÅŒÀDB|Y?BZÆ­ôÐr¤6$‘}‘VŒûŠõÓ3†÷Ø ”YÅ&Hc´‡«+¥û¤óõ©ÏW¼‘¹w·ÐzÚN3²J‡ÕØ:Ç*­’ì6b³]6—£» eEœ÷ÇUÄÝZ°<+°*úáÃ4z»Ëæ‰-¥Ë U)pÇîÍq>ëyÆV¯h$þ^nßDÙù?½ÿbkh8¤ÓKª’­ÅÉÙdj¥^DªS sœÇ¶/ á×9V,Û­¯—þÐÇ¢m¼#CH"“C•[óœ®lÙƒÓ2ƒ«PUp€Ãl\Ú6k¬`HF ¼ÒšZ@ï·óØÚVU3Xp vF,ÞØ‰Õinw)äìmôäuÛ2ß§jaa %ÏaMw$lï­.M4Ê îÙdϨÑÊ0삎ôLØài¾ ÒÍ ”bŒ`u8Ý3œÁg¨z3âþmòùáïb×Ö'úz/¦3ù†ÑÌ9…Ün@±E¤Á1æPhTmû~«PwÑ&ܱßÿ–{ªØŸaÚ1§vìñš dšÛ-ó%Âp¶v»yOêuúºD@w3Ü}<ðþûÛ\Q ¹9ù÷ëmÎ*± öƒZ˜‰xÜÛ—_î±À– ¯:ß7_ö7Í}¼l’‡;Û•Ñy3Os2€JTxÝb‹ÂB8 [ɤñŽÜÖÕÃÕ‚­„¹:mà¾éN4÷ÖtlÑz[Ä—ûñ,’€m›-&)CVµÖ¸#×þ–++…ê-›"!ƨN´Ûùæ»*4Ù›7|â²¥# œò uFš`F…¾¢{` ©ŠÃœsÓLÅΨýRx!óžð]Â&~6 $¼ùḡ˜À£d9ÁÖÁ¨‚`Ï1Åõ<ªÛx9^†ïv{‘À¼Ÿ¯ïGìxºqÌ=ÝCBÍ*óVœDôÞ“½ç¥ÅckŒˆªO§Ækv¯WûÐÁŸÉòò Ü$±”žÇž-V@z“‘(3Û%úw¿þÊ!ýÛ(= -h7„õp튉¤ˆÁ"ÐÆ Ï Vq8Ø€:4 CÌàgç^ÚZ<‡oòê/Fä¶=À³Cr×è‘8om¡'Ÿ™gr/=J›¯ kÝ[Z0Ò*Îɲ /øÔö ÏÏ?š“W[+¨5Ž#fƒ „‡µV!eÂm'·¾ŒiL²1 €‹Z³ãP¬(TáÙàXMq3\[Ëóå6¸'¿ïF°e™Æw;ëûÛž¡ª•£:ƒpD Pòy¢²¡FL©´D ç9â ’iQÔ×*n ³mëüy.¹cZ½¹í—~ÝZw@>G­^#èbÙ!7YÃSyel­Ðñºm0,›ÙT³"2ÁF²Šó f#C쮓ˆ*ek#¤É8$…, áJž0¬ÙVô4h¶vAFl{™ª*{f¨Ážˆ¢m!­ 3¢ùzÍæ=øËˆÜÈYÛTwtÃe>E€ÁIš›Fq&+³ópÍΕI]·l}~…î¤ÿð]•§][ãÞ/i…§€"°íˆîH3JLñ…P ´ö|N òšý†ÅRÊ *HËñôÉ©,©…ÒäY(»¼tÁ«LË£\-2™—üéù'Se—´ö+=c¬•@yz¯Ì3ØDÞì)8ƒG02·ˆÆ<¦"¿ûêí/¿Ú@9ð*ɾ/ xߘÛo¿ÜgN奭”·J+=ƒ(ÊôŸ|}ùßþ×?û‹( J÷jy-ƒmÛá0Z-(OÒZè Æ¦54j'×z<ÜVôì˜È2å;ì5–­Ñž¼¾ë<ÂpËÆ~ªéRD Û “¥dd¦ ”3d+ÑDĆ:¥½Q%”V;o¶­yž¹x ˜% ¤‘=J’FCx%’~.+Çë…«|M=sÌ<Ý3*0Æ ¼GŸÀ ·`Ýõ…ãI`ŸOåR\Ðm![‹IëZÿÈøð±†GŸ½[C€ª¬ p‚­á(޲„ùlBMõé}Í‚j5nïË"2¸’ï‰Ûð4£Tªf—Tv‚´_lÚ,Yûm?ÿå#jÎ{AãîN–×sZ”“ÏÇl£Âtጨ^h ÑÎ¥N:xãßÿúþà¾ý/ßý¿¿{þ‡¿þÑ7J9¦ö i®ƒœ£%£ÌšÌ°™ƒàELbz‘þÝ,‚Ù3ÆÌL¸¤j-ª&íFy|êGàƒAöÁ>¨A¨ºÛÖTK½%ë¨êÒ !H 'è"³ïsº¢‰‘ôœóž6—᪔7¡Ã†§KFUÁ¹> ¯ì×i&‰–”Ë UùR¸E¯HgÎ £“:VîÊTe©æ8å;€öŽeö+½w}Áð2æ§2ј‘ ' )e4ÍÈ”›Š.—ŸŽ ³äR­“¨ «¯†w!>Üp9j.k|DÎÂm‚¥Á )ìÔüã¯ßµýâ9í:kõ×gkWå[÷K\¶N«ðÐNT¹²gÁC˜˜•©Ro­½¹|ý妪Gó¿üá»wo9XŒÚ¦]Uô#T­‹²’k‘T¨žîôŽHLtså:7ú±£-(†]µÊóÄ=³¿AÉRKb ©Œ{Cµ¡`úmä&“wó®3qSB‡,ÝéA…¼ªAÓÓ‘³TÖ&OE‹¸'y]˜*FFÅùév²ïð $*á•’ƒ¹Ç勯O™c[tØFž¥DÈ(²ÚŠø«oÏÇTÝ^€/Öu}‘Ú/Ë<À4Yóé€öÖ&Bi{x8¦¡t™¤ÑÆ Ã=‹êóü¸7Î¥Ãh÷Â<ÙáÓ–ê57?Wmoó,Gl=< y­Øìüözù껇c9ÆIyß/Âèy]¢>c#I>´Š©¾µD—”­¿H›£Qʶ™ÞÐýrþ/ßþ²õ Ÿ~FŒqv¢ø 4«ÓËt`N ]ˆF'L•n-ËÙZ&Ê;ÍÓ¨ìv)bg2c%¢µØ÷Ùˆó<µ [Œ-jùXã©jY§‡T¥Ó”µÉMžŠ[ÅJ_FKõ~’c…ŒP…æ44‰aKâÚzÐÑ+¢—뛟?˜y‡š/¼ñ·"À”hîXKy2rx¦Š¶¥9”€'­4ƒ7Q£ZDϼi1¹×šek EƸ¿ÛÊì³meÄ9qÎó”¦Âpñ_ÔC„" ˜s¸÷8n&k=þüªµÎ×oEãÜjìa†?jž`ç+~³¯µ~¡´®\À¥A‰AT»k[šúz ½°Â”‰3\‡ýóóó4>·¡ Êt„L­ö˜ánœ9=Åš´#ÖÁq%ÓªÒ6Ê5ÃqÞnÿêÛ»­;[fÕn½l ä—ûÅ/£Û–ûDp#Ê„”¾4î˜oñîÝ:N©~þô"…ûV5ËsŒ—Ôt”Y››(ø°Œš:‡¤Àh)'OÌó¸}õí»í-$˜žÿ×?>½ÜtFèÎý+ªVrð  óz”h_Ó´&Ú̈– Q2Fã‹GŠñöag)U¶BÀ ÃÌœÓçÓøQV›2ªí:fŠèbª€àÖHÕ¨xÕiÑÙšáex)L’²W¿~ÒTã. °Ùr.wDftIJü=Ùxa¼A ®ÉÇýbý¶»×r ÇæS#ýÎÛÀ<Ål92t}¹Ï3 e>x‘ËÅõ³+±N i Ž+2ÃõzC¥\¯HñÏçíñòº¾Ÿ k±)¥3øðQÊë6æ½Ú·Ô(’ãÌÞ,C¬žû’›Ò‘Ó±1Æèû~ 60ÁŒ<¬)w5\ T£4Š œOoÞõ|dÊèÍP­cÁÙ”!1—१.3¨£jWĽCë»YÉINŒêãíåêÞœÙÒV˜Eôì³F«FO‡«qfÍÇÖç9[®üDtèí†H›¢rÛ?<{ßZi{FëB’³øÕ¯¶wûÖæiÙ†¤à§¡·ž ȲÍLÚk„ž°Ð[cá˜Ê-GDÙxÉ6NÅðƒñôů¿¹¢V¹Øÿã§OõþFcT92ú•óVS@Š&ªŠyfB0ØraÜA‡©ê 0xTGkõÓžì@Â¥ÖÇyûüú—_1˜$^Ê'7²¥²;²¥’SZ¼ˆ„L1Ø«5)š1@Xí’Y&Ûýc] ‡|fÞæØDOYhÕœ(“ ÜA&¯ae# þâ‹KkÙd– L³"1Âê1×jTN¹{¤…ŸüiÞËû÷iÆ+vÆnF¨¶_6£› Ça…—:#+|K)‘4(É ÁO㤹ˆf^ ­àIgxŒsK„Ū^øÂÙ–:˵ßÿìë7ƒ0"Ì”} ýí?ÿöüy‚+p×"zÎy`ÌT9v}YÓr«1kN ž¥’£ÅJZþúË/Þ¾òèMÿóïžuxº¡ep¦n e ¡Ð›A1*@ŠáÇ–­m0åÌf/ñc‰Â €×d‹ÊÞèQšZÙíÄ|Ø<8;ßfo±³)UÕàÐ(Îá’TÖQ³ È—HD®|ƒÖ,a%'Òm–—)À«ÉÖ[¾ˆsx”MšmÉçͪI`Î’4ê¬ „ iJ.Ú¯^uŽÎf¦i¦[**B[B°µlI©¥4Q¨—ñþF2à5t»+"JÏôÓ‘íÊN©Š0ÂZ1[¢ñ•:è 9Þ£G&`xzNôAâDcÌ+β«õì×î»×Iôœß|ûØ¿|¸§n:ÏBüñÏ?|p®¦õbÞ'ÝÒrIz÷°ÉÐÖvCu¬¤‰—üõ¿{ ƒb>þùç¾»!¢9ZiD5Q/žS†Õ":scì‘"Æ’È$#@¯#ÔÊÞ£8'°m=áîF:®ä›dÇ¡ŸÎ¾yû ïN³àÙ…uQ;2@Ûc±@£)Rª ˆ1í.µ‹s¦×Íìš>4†;°»hÓêÆFªÅÍy6ê£ +ilƆh‹{ëm3“3<ÆgIª@¡ÖY0"b,<‹0íb´Ç~PK¸½†ï«´ž]ž†ôöÅÆv¶­µ= ‡k£÷Ö-gMWi7GChHòÈ8Ÿ^–“`s´5p‡¢¥‡ì[`õsdz&íž–Ý3¾ùöÝÊÕç¢{¢_ñ»ߟ3šËNSªHEŠñ9÷Œ}NË;#bEF$J󛯮o¾½Ü÷‹OOÏ·›“gBs¬ì0ψ#Iúj¥ ä\ôË5Æ3€è£Â (Åu©Oy+7ú85‚'ЃFÊi6ô½lûn"œì™è¼€fë–1¸R'Æòé¼iG²Í ͆$¸ÙmV(ªoÓsd®eAì»ûþãÓ 0戻kq1P¡zȪê+ ™AFdžÒ€=kœëDË¥zOôþþ‡OèKÛÊ;By¥=i.Ù#óˆ³WŸÖ4[.ϲÆ1d¬½cé3œ™‘°ÏùþÃmµŒ#aºõ–yMxcz+r(`süõÛ_<ôuZɯ-òo~óþý??_/O‡OFc‹¤PÈXfÍ€0Ñ'Šd£ˆy'ÌpÚ¾^ÛøÓ¯ñri7üïߺMùTȹG$°7f¸32#WLJ5w‹ä (ÌèɲÔ<öz˜‚¥Š*”OEmÐeÛ˜0Õ;²lU° (`îáPÞ’U’ÌôÖ#¢Ûoßôh™±G^ [:¢48–“Ï€B…E;6cX [22]æq»×›b18ŽÇà×7QsK<æú€Úû–-¸ÙqGUÈøðá÷ûþú†5@jI»zÏ/öíSš:Ë ôÔ³1qÂ0c-Ç÷:nŽ}ÝGKsò.û¸U‘ÛþÆ7ÉÄHž´¡u }“í~ù…|*lš`1ÿîùüÍßýˆ‰ãÓxþøÂL#/³¦Í»ÞŠ_~±EkE"Ãö³ÒR¿¨üåWoe­ÒÁÓ þûßÿö%²±ƒ]· PÐ3­µ0H"ƒû ±º‘¹æ®tÒñݯ¾Þ´H³HÿÅß¾oL\öØ·®È!ª¹&21'-\so{ÏËeÛZïá¶eÃÈ9—1h},þ…p‘9ŒšÖt0ÀÜr›¡ÙŒtC¿q±»B¹aÊ‹–æµ] (¦0`3JÔ±3%ŠÜ¶ÓêAi¾Ñª³C n® ꮘ5±RVsášAŒYãTºaÄx.!îüé;¢7É ’«ëq$FUKA‚×ÖÖµÊÇX±K%9t¢o,s†ç'Æò@+ùsWväv;¾yxxèqɈeu°ÉÆÚ=—˜X+‹2îÏàØ/ï?‹X¸ˆØ’¥@ƒÌYoÌ#Zp[WøÖÒŽ¿ú³_FVE,´Ö`üöû?|tîï.Û[ÿ‘Û ç$€}ÂZTüªz™t‹…¦æúWôà®úÓ?ù"P+êúãyüÃ?ýŒ›=æŒD-M ³eö–‘f6F²Eú2ÑY$sÚ§ è-[oP‡:‘IP 8Ûdm`$Ì•u¼°‡æ…ùöË/ç§Q•Žà0÷W'–^Cs€yÔèÆÖ#Ä45ÇíŠÒ8R÷mc0˜Px® 7„)L—;3wÄ")»r±k qç½Ûñ97w¿R!â\ðIzŠ"qÍN©’ 3¨D…éÙ1Úbm&ÆÇmÐâ/a¦×¤Ôw^oÙ«·Fp ôÀµÇÞÛY2QªQ ÙH’Ìè.—³ÐÌ #(Ä99ÕÑ‚©Ö}oGÙJ‹fã%ØÓ³ÎEÞ|½\.Þj06‚-üååñ„£²›ÔúÒë}—dv•OàÙ3:[‡ƒ£¿xÉF†'0¬“ré¶Û¬é±=i#Vè4¶Ê>sàÁ³§÷DP±=ø©<Œò½âÈõß›ÅèšU[¯BÕMžªó²çWònžcåˆÒ¸9ÿò7?7lÍ £ÌãЈ›mFË}Í(MlÔþuÞz%"’GÛ„ø³_|ûGòà9×Ë¢ùñüæØÙçÄ8QŶ¾ü"dLa [ëÀÝTÃ3¬¡:å¡j¼˜5Q“ÀX{Ky”Æ,«Mn ® ›ÆÃ’©´$ûËéc juŒã-xƒïb[Ž”1UKÆ˯ Ž13ŒÆ¸ÿRkY±b YZgg¯}'îµûi"Ûâ’5ªU³3_Ã!qW'Ü›†°ùîÚ¢7$zªg̵›]l£#¢·áòÆáåNiûÏ?½h^À]õºÜ ¨‰[2ÞÄ;´#TÛ-E¬9˜}ÇëTˆ¶‡‡—§gÚ/χ.Íy|~þ™‘†*Aöà“[´Ô”pùúòîÍÎ{H$ÿþéøþ_>¥ˆ\è7Gï­[%$½ˆ”†^{ò$ÊÚb“]¼±x5†±!~ùíãv °d çûíOžÇ#hp¡å°Út´mª`TfYVå;½\™¡Q/a¯xΡp¹åšVê£Ý*æ io5í¸©k?§4bcÇhüb-Àeªš—ˆ¬£uö@¶(zJh!h»Â›Ox™Í oÖr¬q¹mT¯Ú$Dƒ›F¡ž[-R„îãH¼‚¬òÚzži¡DpëÔÔnº¯—Ô#K‰Ìƒ|±Ga<ûº}8Ï{¾+© ‰»1Ê 3Þ>èÍÓS(ö´kh$9Ï£ÏÙ¹0+B>>Ÿæ Þ^ôT/…S¤$"—Ê ²!¢½{;Í€9•ëúêË€dUY±çÿ÷·ß#B ÍŠm–|ÒÇÛ‚“'–L‚¯Ì@˜àžèmN…2÷ŒØñçÿþí+mœ/cüíÿý/_ïiÃ¥À€NIòôl-[k/Ÿ> ­“ äbö“ºnŒ˜ÕqKEGÒŒŒ'$Ô‚e„#ŽÅÖ4ª_wôØò‡ÞHD+‹´F“Õ¡A•˳(éQÓ• ²NÁ¬ÈóÅѶÛsÝÚª.${:à–ê1ëuSžX‘Sq~šF{=ZªµïþLZØ®;Ÿ«{ö{˜>*lÆit{¸jê¨îÛÞXbJ’ IDAT¯×Ó+ó]óþP‰@ЯRŒÏß«j6Î1m£ÇÒÄO¬*rÚe(›¶,â|úþhíÙÖö× éÂZYá’§õíåí»·›]š7B•í/Þÿ<~xæ4¼– <¡S:=䱎÷Ðh-*£6t¨·£E´ÌÿüÝ·—öêv¡þæýó?s¾…˜+mtO¶2ØZDLMÙlÌ.£†ë¾Ž0KÓŽÖöÜ.I^˜ ‰¶£, qÇ}e¸f”=F÷'[ïqX/3€Ó±¬Õ‘¶Ál‘tƒÑ2ûÞo,IvAÔHW)Ö8 ôK‹K!Pð˜S Ä)yÎVµeî{( £ƒáÙPÝûõ؉ÕûS€Tm-žÏI!U„ó<©`U®šëTUd`KŠlÑ&y;ëù§aGY" š±™\‰”Falïœ=%«’n4Á[£÷Ý+j߯@ûá‡Ûõ-›»â bÔ0’Dót ûæ4¦е|&+‚³õy vbN3£•Á’b‚+ˆA™åvœyÝ÷PY3[ ¨Yóã··o/–ŸýÈÆŠ’vøÍCs¨ W, 7Òhª5‰D„ÚVÇa¶óNؘ‰µ#^vוÎ!îqGѦ{?¦jZ1T˜‘ˆ[ÍõNÊXem†9gí}Ö1¥!"îé|TOi›d”]Ï=/_|Á·oà¼s¿ýãOo? fV) d8À-9Ç1çIö²"ÛÚÇ"‘A eUÚ}ãúßìyÂÍþòûïÇ{=´ö|œ«1&°gf‰w€lzB™t%î—wÓÑ@DgX52ïÌá Q1#ŽFÎÑ`1W:½H0ZX—khäœ_}óõÞH;v2„‡¸&Émƒhí9…óVÓÂYP4Ä-›t¯Ñ&’Hµé(¡´šs[à²Ò½)^Ú*(’eubž"›z¼œb®óëüÜÐYM]8ŒøÅÃþ^5㵬î"*–8²¦–Ïj2ŒUâüé8e Îe\„—e;ÌtD\ݘ©èhŒÔT( ìæú>6j•™NU:û¥÷OïŸÉíÎ ´$³”1çq~ñMwÛxŒ_ýÁíÒN…òZì¿ù—+€¸@B#XZïdÖï~ûÜ÷Lj0ûÄØ–< QÕ/­dÞŽÿù¿}{Íò4eòçcþõß=§H°æ"¤[âh)bFÈœÖ*Gv-Ê%n%,œW˜¥É­h¶nýÿL½M¬n[z5Æxç\ëÛ{Ÿ{î­ߪr\¶l—b’X‰# !!,d$ ‚¢A‡ši š@!HH#–"N¢Â8ìø/årýÞºuÿÏÙ{kÍù¾ƒÆüN@:ÍsŽöÙçÛkÍù¾c<ÏLW¸6â~oE¯lAŠG¶\ù‚ùî[/÷»Y¥Éë¡U0'ŒÓ²£LÚ‘¾‹}c„묓U uNzI ÊÝÜÁf+Â[w£XDÂieÐ[)" (WJ•G£jžE>Ya¯VÙzuÃ^DÇ$²µ@å*/?Ë7£(”[”!¸jv³‚ŽWÏ´ƒè7-o³•âkwcukfw,âèy‹²ðR˜ÎBb=as´ÈçI]¢ìV÷2%÷º;|÷àÞêG>w &¡¯¿ñÝ>>•Bq©çÖsÖ¬šlyEÊ@r&j) —® Ì@ݽýNø:~úKïüÄO¿,¾™¨~ÿÓÇ?I9ë<˜Î䜻7˜¾šÃ+>®Õ„I¡n5á`8nmæÉ›VwŽQu ài¬‹4bÔY¤ƒ+%]9§kα Ã?8?ž×ç0õb{½ó‰uÄ è«žìŽŽhtbVVYÍ ±¡ÀÉ·žªžˆ³qÏéT̈Zk'@Š#"oAÆ•§Ù€Œˆ(kC¬YÖ3,ڷűÎ7mÍþbOÔYùLìÁR#÷æ®ûÉÈëDUÂU¨r”ðÆ^¦5LJÄ0ZU×ËÆ¢ÏÊÓd0ˆj+oj&T=æ¾=V±$GûTùŒ$¬Å¯Y»(±|Ù/ÑçüÑ/~áîs÷³PUÎùÁ½÷©Bíþ2]Õ›É £€F6`'ŽîÛÕå6fˆ<°Põ+þó¥}ÿ™/ÏŸýç¾ìcPfžßÿÎg›9J<ƒ§ìÆŒx\m/”P÷´Îë¶î¡£VÎ P„Bz–}ËqS­ÄÞ·Ëf1UÝ5ç ±lfn¦x«Õtµ2>øäÓêf%o7ÅŸ8=aŒ­ ιfôÅŸNÆÍسvÒOÙF÷ÓuFŽ1 ;Í*$`Z’PäY]"= 1î3@®ß.AΉÊÂËxñðòéáG^?Ï^v ?xïÃz®Q£"Ú(z” u{س!Çœ¯wäz Æ.¡jðÇøb»üÈÏþœÓ®¤¸ÿú¾÷Ù''©³l£’Q1Óé©Rëòs’`eÖ­À¶$÷€hÅ1X§Ù6e‰!”÷凕)F†"tŽ*—·¶·ÖÈI£ðl´ö”ÐP èn_åú½©Iû N ™8*f’© ±ñì¬,ß•û*#4 ã®À*»R®PÕ4Ðh‡KÁbññH´ÒÅU`\§î¼¹FûÊ—Úáìâ&®¹TWa᎚ž)ØŽr[w4Äó³kÉríIÞDs‹ûá‡>|â- 3Ò¨Ê98“:”`9óœÙ‹¤,OÔ@ç Röz'òäë{»Üm’=Z{ï½WM½Ê\¶»9Õ¼5nDQ!^éqÔ£¸Â2+OŸ.Þ<}4ôŸ*áñéxõýoðB}}2ºfž ‚Qä­BQ RQÔ@hkîa¸*بvl™«æ¼òçÙà͹…f …['¶ý¼]¶<=ʵow¡tٟߦΣ®ö!,(¨® •“TkŽìá­!˜Ìô<LZÍ)8‚¡çZóãöX˜Y‚ ž¬"Xµú‡¤bµ2/r2ôÁÓ“ž6"Á¤rjj!0Azó Øv5í†r†ç:3²¨ªÅlÔDæD•«Ì÷?¾>fÝn쫜¶0eЧÑJ÷ïÞp©&Œ£SìÝÒkfµ¨b6EnU¡þéÓ ,+å+ßÎ[`óáî?þão½ìsGè ñ›W|üˆq['!²ö­7˪ ÏaäÈíéÕÖWº( ˜¡\‡Ð`ªSúß~ûý§±=åtF_’\a—œÂú”Јpѧ§šÙ&ªlñÊBŽÊL,=jª³š³w•|¢D_™+aÛeç¬Kq žu=çëÁ ÔtÙûb¶L”@”ä ˆl g²ä-Œ‰ÛÁ) #£&ªÅb,gQÐtIÇóJ˜›-É*³mjP€ïÝk¾±(Q ˆí6ÊZ^äòÞÝ–gå$ŸÍ,¬è;²¬ƒD‘7^M–YœŒš߬†Ö¯5Å^ehÕÝåeŒ¡*ŒÅ•%:¡š4ïqÕÌ LzÂO(W/ÇgÏùô”,‘XÀN’$ˆ"Æ[ûÞ¶WC~üôð°nìkâŒ,B¢ZL“hʼžëGϵX©‹½ƒ·œ¥µL†ýí_=ÿpt—«DT•‰Þºçr;jFA̪‰šgXµ.”rjk£ÛHÒ¨òȱ!E 2É9-ø©Ì²Ü3‡–¶‹÷=z—âñœwØlix4]8Š­¯ IÃMXgâm‚ìs:‰;F³…L‚pB!yQj7òéÝÝÒ¥5R# ‚ ”)Bç'ïPëeíÃúžÜ:a—wúãžwgtñ´/5}–'²dgs·r&J¾›hþaù×Aüÿ;º¥\€{u?¦z{“=@{&ÊÁì”°X˜ù\s1Á1ÑnkÎD.4€Ø Báu´üí#èsíâby:­ÖÚBšÚ:X5=÷¥Á#<]Y.oº½x3Ðû6gÙ° (ki«ãº€…õ~U±‘¨²¸h@ãwýí Òš—>¨Q£ÆTI5ÑÕÀÑàìb u×Ú}4#¯v2Õ#Z“kÎ! ïñ¬<|”Wø–•.#M›]u…+CYµ)?ùàÕ2]Ùç|¿Q•à®þ¹»{OϺ…tW5´šPV‡#³æ™U̬™ÀüøÛ t²’ƒ$—½WÀ‚®×~¹x·Þ#;åglÃoè®Jš[¿²Áº^ó¼>{9\×Uà¦%ñZv·h£Nçè2?þô˜S¹*´à @*Ns’#†÷v¶öÁgOLóö¬Ó?%¾ßÒ2öÍÚø¼zõé°š¢E¨{z]7l¡­•TLßb½YžæSq²­’ÙªQžUÏe)M¨ÀèhF@–ɶ^ôn2!D¯y‹PƒIn-$Œ9æ¬(3X>[y= ʪÁ”†=}FÛÅ1Ë×ymé¾]ŸË-²´8çN9ײ¬jãb_ ÜéGmƈš+`™öœóÈÛ©h®÷Zë󌶸ª+úþÆîa¦c¾mÞm­RŸS¸Ëc'e–y$Z!DS“vÓlÍ­Ÿ³³n«ÈÕT[D7²ÈsÛ„“:¢?½zÚÌGÅsaškÇTøDеÛd;Æúw__7»Üb™Üèñ·ìîbQøqŽ~ðÄsÌbÙTWßFhH`Ä¢~²S˜·)`„É=´!W¬rß{Éí¶HòêáÉDkW{fJ­„‰éšN߆׶ $U˜6¶ç?|ÿ½ñÉiQ9ÏÜ·­O²ÙYHÐÕæÀìHå(/Û"²„âEÉœƒy”ZBç9«„&×Ùû̳ â ÖÚ¨sUÁ6"5Û"B¥ÉÂVëït­P©­8hìð†²½5tÑ‚CçŠ-ˆI&*Q¤; ¿Á8Þà{œp®õì]ïQ(gqCl8¦+D¥/ÆF ipn@G…SÎcF Žf \‹¹¨6" >þögµë²—:„©pú.­2{s4GC!È8^?^çó¼0L^L }•L¼Õßþõ¼~ÿqAFgá,³*ˆ@ ÙZ‹€QS(Õ&йØ€=' Ñf=e hX;yY! PŒfPìêMÁh±ˆmn‹þßöjB‚÷½YhÔĉb»»ÜWPv¸¨6«hÉd+¶i7*K=Ë…23±#*a»¢WÎàPW³º0h3F‘LÁɪIˆ*{Q«……JÚ㳄-ªêù§N FçšJTf•-=N–¹³©ªÄT‡•ÂVñö Øb`þÿ:‹äáË%ò,Sœ Aídhæmæeq­TRVPg ¾zæ8…~ƒÖ’KÂõG(up;®Ÿ¥õèCˆ’æ™ÁÙÛ1¸åˆæyœ@³Š»Çñøj^º+T·å|«ÿä˜_ÿÍ÷Ÿ>{Þ£ÑsQXE@ÙZ¨ZrÍÂ4)˱.Üo, +ßÜþ éˆý:NR%R>+GeDDS¦;Ð æ¼?õl Îyi¨<.ævÿÖu<£ª]göb»Çô‰"3z ³GEÙ°—ƒb·3xœDÖt²‡°‰äÒÊx4»ÐˆëÙ­74A²bT¶Â&¨Q ÏYó̸@aÚ•^LÖõ9°§6ôŒ“ìÕ°8@ p¤g ¢”7ïs˜‘8Yˆý³Ÿ< ·ÏÓM*ù†DkÈz)¾jLÁãæ¥!ºfYRVI ”+âÁízTFlQ{?Çó1æ–à™ ÐëñãñÑ @Zh`AÙt«”äªf—%^ñâîøôÙ_i.zEdÙ¼ fUüðÑ'?xÜDTÊ®LR ÊmÝ“,#Ú:ø¥á#BŒ5Û\× †¨Y”Î!b+^ç¡æ.Ý;8­„™±÷yœU ^H'ƒ1+ªªähaxäñôjÜ=´ò¼Y¡o z¯XaÙ/^ô?áVEÜ8ï 0á³æÖú<Ï à%´çgsüêßÿý˦þòòѧ昞wØòxþ…?õµK¯eŒvy5.Êi©ÍÊ­"äÙo²Ãµ …cTfž3~p}ú±þe׫eÔÑÍèZŸ^ßýÞGŸ~ðÔuk [_ïá¶Õ,å’¥²[ñÁñèE÷¬°Ç9Õ¥¦gÕ^¾oúÌyFlFåPÁ ïÒ1¬dD…¤ó˜Æ†"ùœE2§wL»šáy:öh²g>HGfÁš½³&sZ}@­$z•¦]Ê“kv‚±Â¯É–Uåš$PG©erUÇg–#Ùú.ÌRKgúÄ9ÎsÓ-aõ&ä§ÅダʇÏí?üÁáIÂQ×9Ü)ÌcC_§ÓmEýoY´é¯ŸOl]‘Ï×CG1ëHÆóy։ǣÞÿÔÝ #Q&·¥E•”ÈœºÜpiˆÆDLééq<]ÉÏá1Ý›JõîÃt_y {k>¯9K ­œ[ï#óœÕ(’Ó“R´BíßýäåýwòkïgÛw8?{<øtþÚ7>àÌK®rŸ)u:[W’£R±Š¹r¨Ydy³†p·mgΑ•@ÛÂ(z¸Ñ®TawÌR°Jl!ÍmIÉI’H­z@e)žy6u˜i>ïtµ®@vvN5ˆ.äQ³*Æñ´ßÝS\!ÂÛkõünmkåŠP¦re˜r3•<™`¸L3×GG‹_ÿÞ'þvVz(Z欄ó,eZí-óW<¶n7ØAI—LÒ¡¦e¿(PÊã`×Såý RO¸*M}{2¾øâ~ó¨õµG>ó•afýꀞ3›Óµº³¦\^cýÂDì¡x±ý£ïòÿ|ôêG.o}¾¿úðøì9Ÿsö‚‹Ã4ðpéÇq’¡g»ÛQ2Ȉ€à1w´çÂ`µ‡ðlÝ©Ù(Ô:jc,bÉ™FD¨@af“Q‚‚s eÍykÉ”«HöΈ"AÄB¬mƒ`³f¿P³¨Þ÷•gbg(KHKЏ?=ÔÚXÏí0Ên!gÁ©$ËUÊJ tÏ1C^¼/ôê²Ý¦zŸÃ½ ¹oíùÕ1Æyÿp·6ÈMÛùÆ9HÂ_¹¿5²u´ºÁådF» G¦}5›ìZ¹,>]¬5eùLAY•XìJ*+àhcž­ NQ5ÉÞ"œÆ1“•+,ŠÖh¿PCf®Ï"ïǘQóáí¶:‡ÑxŠO~¾ë[ŽqYE_ïôUÑà Á ³f%|buª1ÎßÇwÞŒp_O6zÌRoçq:‹!±í… ε»ì#ˆØè»4"*13ïcjkc&FY´7Ž5 Í´ìšd0ZyT¢ÆXhÌ´¹…D¹sZBt¯é&jŒÊÊ£ŸRï­k»[ßhÝÕ <[§ÍJ¾Á´ÀF y¹TsŠ,Œ«} ]Q!àdR‘åɦ™[¡9ovA&ËÀÆ‚ÍØîæ¼]ݼš«+v“*™žÄÃÖ™óO23ÚîÜÈÕQJmµ<ÌHÑú½1A-Îù1ÙÛ&M“Ï®{JÝ8=Î\elØèáXj,–’$OÜp®"Ó,¯›%Cì噯‹Öxß²Š\ŒrÎrd¦×(„pú¼( ƒ•UÙ’­wÇD™Šk±£" ÒÖZÕàaîºdŽÈŠ&Ë£ŽäÖŒ<ªÐh*’¬µÜ˜[˜i·œ7‚°)³Ü§°qº`U5ÎIÑšÌ^ƒÚcAéXȰ+VmçR¼ÒjˆhûE[¿ä¬YGëBôÒó¬ª\5æh‚]–« EÙ#Ë—Šj0,öØ)׈}snèלuL® ц=AáÌ­0FºeC‹Aí6¤Ô;±½¾èŵUÚ]Ó@ú…9fÖÖQsa¡(g³lb¥³ekªF–{k‡3€™PåtÏ…è®l"å7á0 jÛš1*ipb(îÇ1öÖWò€;ÈÄC´—wAMN[¸:ku÷q!‘>×ðfÖÓSžÙzˉÈ꘷ Æ é³5/LÈ*&è®NåÌõמÈ0Q³…FV)è4±XCšsþî •–Ü©¼Ѹrn9<Ó­õ³2†—7DÜ|môb[ÏXê†Ñ¯×~wYë— ¥6z¼z<³là(#ñÀ-g©™³]M³°gbÛ;œ^Šé*б1ìPá«kÅU2.͹,ôh—ÞP)2ïL9  ²tf!äd× |ªÕK>coMéÙÎã¼Dö¹²Á[ ¥]÷bˆvæcV4TkfWù¦Sk•)ÅËw75zòSlhpyz¢£ —‡Ïç(GN6y'ZJéÔÚe.0Ü51Á„ÏytÀ3\¡å9–A§@WݪWБðôÞð<¶PïÈÅ›ö8V½nõ¹ï»÷œ‹M<Ö~`[x‚™`XsЩ%~¦™4Gåyž­ÖZ\3€Ð:Æ%ÔaÝÌ®LŠF+75×y"í8\kKµô­e g¬´k‹ýípNÀÌÜ1¤ºk#kž…niä5­$VÀ¤¦ï [¨Æd¹cæxx»rn1§Ï,-È&dFDCkÍë¹jÏœ)b tÝPE…VÁA4"¸êzkå3'• oÛ¥õðÖwæl•{@ Ïs ªšYp&+{ÂvkA¤i9Óe!t´‚ϦªQ, ´æÄf²qåÅ+i°ž%­\À 4kyÍhWÔ ¨t6eæä™2 Ó(•Ö<òÄÞ%šÑ,¤›Ì¨T@[?‰ ±Å‚ƒÍ9qÊòHVt.fM¥«-­Yvz&¦í“$¥¢æ¬9Ši RZGˆQ«æJº/·Á˜ M TT¡mO¯^»²í­¦™µ"Єd»3Ìš.dÄ"žhUÑZNœmÁÙd'KáóJ2‘I ;N#P݆«fVï•P42 =’uf‰ìÖyÔ`îlåDÕ²ËÞ>èðÚN¾Õ¢£2FeõÖ½n|ª9Ž-üOUbî3å~ÃÏõ WÝRž8ªÞ"Õ‰ %YÌËÏç)5,Ú5»m¶4l_Ìœg©é$vðf0ÍTùzžoÝË"Q™Sí~¾üäÕGy)FDkM ŒÒ9S4¡1-ÂYl·ÞúàÚ±K€”naæ5ÁFã^ó°œÑTÐ2Ø-õß ³ §ÚªH9j¦aˆC È[*¯$(…nÍs! ©œj¹œ3<…r²X­Wæî†HT…™ %Òúå1¯ v™ÎqŸ£åHŒ]yDß,Í<ÕZ•Ùd8²Üd9tNí-å’Ê@Sw¥X ÝD¸&ÜöfWž)£!„‘M:QjAÓ:¡ˆ¢çñúüŒ¾[Ï®Š‹âw#T:ž¯×»mC%ã¬#ÙPÛ\Àº3Ò±L…œUTvcÝKyYVÆU˹·Nqž¹sËÂ`€dª)³B„ô8ÊŒpìvD9zëž3öýþþ2%̪¹Ü~­Þ~Ø>´³ÝbÅBƒW€„–bØzÓ­íáª4nZ¤<áZ8ßQ9ÁHwb $ÁÐH ÐŒa:XÙ¶´IÍ-P\ß„!–Ý*I­Šª2Å„· ')Ú¾¨Ÿ>=§©ÙDùð¬GMí»EÜofÐeÁmÛ.ÜZFAhŠÊ2¢;±5?„BbkØ @óª˜y_øªšÔ[W¿L¢‚•Îi`(l uŒ•ð ç·KkmÁ•’„{ã]7u㩌³A¯¯¥.:ˆ·Ì$MHteÜßÕ¶ì È¶_¢1à4ÀLØC›²‰naw÷‹º°Ã›ÂRf¡Å =c^ÄûÖ&ÀÖ¢íûŸ|ÿ{qŽÝpš²œ9Ž0 ¯lÍœs&iLx2â;ï}ýïþÞßÿÞ¶Ým½ž¯çÓ§¯ñêúåϽ»}~ƒ+AÏìK4 âgpVÎËU¶ƒh‘ûn‚–Øú6æq”÷£ÒHh8f,T")†+ÇH·2¬¸³;é(³à1ËyjUþsNÏDQH„)èA-æäA‘êŒ.¦XÔZ´Jùúõ³g¡ì…‡ H ŒLT Gù:¨ªi5e=Ûàlý„pX,0ãšn(D›5“ÔÞ¡Û¡g–—eÄ¥÷¶ILk<Ÿ ½ˆÍìFÑG&ÊE“×lj¹„à^xÝœ;0ï;‡ÙŘ«c½Èj®uá^áÓ²«U¡sC9‚Ú·§q”Ñ!`n6.ØžÛøÆoÿïßþÝ¿|÷G~ôOþÜW¾„¿ý·þêW¿úµ_þ•¿x­ç:p9(E0Ze‘¶ò1•}ðáW_|±?ç‹—ùÅ÷ŸŸ^<<ü½ÿó×þú÷ßûééœí/þÿÞ×¾üG¿ùêûag–F'³“r’# Âéì! OЖfzqÏ©_°ÞVéÐuom{¦+N‚àl-XžI‘.ºŠL¨ìFÈ©hUA›U‚éÙȦ*b‰­b¢d¯¾B.Šöù—4‰äZîöY c<•Ï1Íjág9cYy'`ﮬáuI©@ß)&½Å^pÕ4Ûä9­“håX=DkÌeóÄ ^€h[ÁJ—çÞç—þÕ_ú׿ð“w­üÍoýá/ þÒüŸüò/ÿËöñoþ·í¿ùOÿ³ÿè/ý§bg´f?SMΆÕhˆpz¿Cwù¼Ê9¢Å<ªŽœ/½=ô âa ’¬¦ Fq¨5 pÌ HE, Žf ÓSvS“k°*l‡@LÁ(cCÎCÑ Îqn­­Dõ¶ÝkÌhÄ*A.ÙJåº5Ïë 3³mlΤ»*R#½±ÛmÕGìÊl©³*ÊÙ¡™®XÞ¥-–¿Táôª!§ bôý¨ÜÒ:¯ŒÐv?ê¬ÌáŠUå`¸9mÁЛ ¡HÁ««ÙõÐôBôý(eaìŒ*'’„„ÈVlþûïï¼ú÷îýóãí?ö+þé|Mô–´}>çõÓÇéßü·Ž¸ö·ß:ûñ…/½¬Wûy¼ÿwÿÆ_ñòsG¾~ïÛü±ÿg¾ûé{ô«ùéOü»ÿá¿‘¼êk_ùùÇŸùÃø¿þãßøµ¯ík_ýÜçâ›?üð{ßü·ÞŠo}ç›?üÕOÞýÚýñ?ýsÛÃÝ[¯Ÿ¾ñ½¯ü;¯ÿÌŸüÅó²g |8UŒD¦°‘3okó"÷ÖH5‘$pA”=£E:H ˜N`Ò/ªÊ¸–+Ð#H¡ò´¶V ¶hžÁˆu¤¿mrEŽšfJ´+šjé Z< NïŒQgú¦âpÇŠ…½¾ŽŠ6„®Ln•âˆy¶\-Ñû›á(k8áX½#±7k:“(°¼¥1«jºYéÁ2ÎdÍŠ~B!-[§X@V Ùxªçs\µDp^8¢E Z—°hŠý~»3s’uƒÝ Y˜ö€˜b2pV'Þ©g¾w½¿|ááÝwþ¯÷þÑøá-ž£ê݇/¾{ÿ…ý¯þ­ÿüø›ù7þ§¯¿3üÝoüé÷>˜×ûOÚýàõ/ü ÿüËŸzûûßüÖ¿ñ¯ýû?ÿKþýñ»Ïï}óå/OÇüéŸý_ý¹_Ú¿Òøñõá“·ýðÅï}ï[?ùGŽìŸû»á/üÛ?úÅûïüÁïüÔÞÿüOm¿ú—ÿÊ‡ßø¬í]•s„ŸVw°÷ª$ HUƘ¬ÑGm@wÒYÌumË´(7iõ,¸ÀØ….ØåVè3;Ð+õ4tÍ•ptI#«‹R²:Ñe?Èí˜qVa—CÑ[åÉòùgUM[&Oòf"¬p^^.ªi[>g7{ôr=¼Á¶ýL\¥ý¾ÙɶÃÌ´YƒåÖfV‹ºQáj½÷Þˆ¹ä6CËC#V^:ÕI5@OÇsr0œ$öÐ&vlÊ­K8þ6e.¢´P+Ð&õÖÂlå ÏóÌ\±'±wom,Wq‚K¢:fq~ðþ·?üôÇø“oÿø®Ï¯ï÷~ÿþòÖ˜žTâœ_ûÿ•?÷+¿üög¿ò#o}ó»ÿó7ë£ûÕÇþ''GüøÜŸ¾úÕ?÷ÖO¼}¹¼Èäç?7ëõùçe¾%ðüÿó[ÿËÿØ>È/áÿeêMµK³³¾ëZkÝ{?çœwªª·æ©gW¹'wÛmÜm$)L0A±Í`ãºm7`ÓcUwuuMïtÎyžgß÷ZW>ܧ’¼ÿÀyÏsö³÷½×º®ßïáËÇo*Ïöož7_ÿ#ÿÙðêË_ûÓüÿ­¿ý?ñ½Ÿô›§Ç‹ý8oûø¦ƒ¡P3¸"5ŽaÎ9#¡/½H9›U„ä­6¯¬®RvÔ óbTõ*€Îʹ_\V@±J¥5RIƒêÄT޽×ð’uå&³£Æ]ÑÎlQ4›±PÔ0‘vLb[™9Øi(±öÒµu1¹%îªr AA³‚zZA;2j0–\²%Õ<=ž™.µb®Q•^eNP¦T‘}”Œˆ€dî£f‹@%zµæl±¡Âœ¹ÕvP;!Í›†Ç1†¼´ÙiЮ ·5ƒ¥ ±xnÛf«©PMñ«W™v1ŽÙD.;mw¾þàØŸxÿ£7?üúçíðµ_þò7|ô.´ ~¼7nÛ7¼ûcý…åükçx½Ýþ¦<ü_§¸þìòÈ+#/ï¼òÞºõ³ç/ïïæñg×®-_»¹>íËZwëÞþµåÙ§?ñ¡O|ì ]¾øÞ?ø®§ŽûüÀ7|Ëùß~è8ö”Ÿìv:ÜÿâË_zö½/œ=ýlç6Ñ¥UðÒ²Te…¼‰’Ï‚£³%QJÁ ¾Æ(Ô[£Z˜ì8IkÆL¸Êƒ£¹ö[À‹VWÀ$1LJY£¶ÑÂgx“2Îx¬K£zÑUµ&EÃ(›ƒY’ sHYéyÕ¥"@Ž´ ™j$EªÊÛ’"äF˜¹u¯ì£ _ÚB¤æ»ÁqldNE\ g ™1J0W¥ÜÝ\Ûæô<¬ E©"61¬™ª»,ÛQ'ÞêBÚÅ$º¨>Ç ER*3Þ:±¯UÁcÐLpŸÉx%„Åœàñ˜³JŸÈòúò—^ºuzíïÿêO×?k¬_¼øÜG¾ôÊé{žSFñtý?ÿ×~ýŸ¼þøs½þú[7ùÈÙíëïÀ»~n{sìO:=ûúõÓ‹‹~íÉgßùÑñl»©¾ó{ÖÓgùÍ_ßøÔ§^øÍÏ?8>8ß÷Ûûïxñ»>öñçÏ1r£Ç²£«¨Òåÿ¶ïzæ]þ/¼±W,¥R6×pWÒm-³Ž²ª%} ­ЦA•%ײšmi¹ÉZX@Ër±m>²XG_l ù:•‘ƒr„[z•hBš­Õ±·eÍãp“üÁ¾ÖþéKwßôÐ>ô‘oæí³w~øÙW¶ž¾¸þø»ÞUp¿¡G¾óûOÇñàµ{ïfùà8X‡·îŸß:bG¡½y¼óúk·n?~mräS&–[Xeö7Ïëýeº‚ø¢’©^iV“v8¹§³3bš‚]™[ eMÞ×b~¬RxeÎÊ[ÁZÖ$lˆ,“ªfÇ23ÍѨ†ŒôAve”Œ^<®¶1ÁùkLI¥*9wa6 Ö­¹ câ@:a«Ýh¸{³`™¯8¸™ëZÇM’".Pk#·Åb?Z[ËYh1+ é>½¥0av>¥ƒ[¼ÊÌÓ(kµm XA›y>‡IV´NHÛ˜c|Ùܹ<Š)(w5¢ŽÍv3YŒ'¬!¡&Úl1ŒýÂP–ê—oÖÛ/Þ~×­÷>Ó­þ¡ßò[o\Ó£}ñ4w¦Nn<öâ·þÀÛuÖvTßź~Ur[J&¨ö{Ñ*<»Lãý»o{ñS¿é$Ûƒm„s ”Ö³{wÇ“O3GIn¨DŸub*Û­žØÝc)G d¯ºÚNŒ/g6E_ÌÌc „\€¬Y¡²9ƒ`ʤDY°™_a_æWwõ™‚bºÏVç¨ò1̽ $ÂcF‰ t¨ŽbŠn–4q –±)pi!rÜ­gR sÖ¿˜÷6Öês EÐ=Ív¢µ¥€’¬h^bÏ‘U[厙\1šEM«¡ ô¥µqì*/©…Ól¡ÃÜa={ÈhÈi¯X¼Y•yMWRÓV‚1•c\`\ç|Õ)›šx^}nÁ`œV‡ä‚mˆ²2«ÌªÑrڱ˃bjyö~û¶8¹wèoøÉCO¿º®ø@6PV¬mï ¬¤0›¥°Ç“¹™¡Ê[}ÔдàÑ—ÖU@Õâfì4ãò0’ EŒ‡Ú$¿9žzâÆåƒ·öÇA°I5ßJXPu©Ã’æ@h¶B:¥€jöäÄ@äbM½;`2Õ\F 9Ö«hãü-ÑK UmT[Ôò–5Ø¥«›¨JfXMGÈA³&wcÆ—Žn‰ 8ŒBe¸Ë¯„†2Rqq~þøCøbÕp@UTL倯ÐHšÙHd'»h §g'nE†Ýº,%jUqVä¶)ŽÝŽËÚŒe´¥mÕ)¶Ò*][M²ìµ0ÒÔgˆªÁV#£5—øDáHWw”q ìÄôðÉšP)Í ÎÌÉ̱¬õ!«ÆKnm±]r=nÇ0j<ÞD]HÍÐ(ªH`Þâg ¦YéÔ®­Å†2[(r$&S&›ÉÈBÍá5Œé,åØß¯]dYÑ’êÖœ½ôÈÍëO¼óÌ 0ÁËlÂ@[™¹Ç#G‡Ä4ªSÙV’˜—IVÛFp…ÀJ¤Ñ<,h(j óÐ7®táúÒœu(ÀY¡®½û¨š@®‹¬íFð’u¬m+ôÒ&5Y#Ãt4¯¢o¥,h” Pmìëí³\² NT[îúpX´ÅãÊZŽLÑŒWˆP Ó¤HLa=â’¶0NÌÖ"s¤ =­×®ìCBÉPÒ(±^™—Q%”ÑÂDmuN ps 7+«Á £¹Û­‡Ïö}4“k4 ‰”‘hЉéÆúfjTÕbW@ÏSCZŽ@ìNs_è6X½0¦gêæ_nÖ†Ùª¶‘u'@ÊÒl¡5šQa¶›/tÕýÞ†’FQ¥P•ªlG¶ž·o?ä§k¸—Å´V(™Áͦ„ÜoKêwoJ ÅnYváëÿëíŒ]ŠyEw`%¼á îG¥$3 ‰ö $f–•Y&¶ÕêY}+“Âv¾¢#¨Â!³FAd U±4ÆŒ&mªìcòw«ÔÂÁóCVYŽ>4p* ”ÅÊ^(Ø “˜ç££ c$T92ú;S‘<‚{-†¹¥™ÛH‡Â8X›#½6ÅV4[˜ç©+,3G‚Ç­.s˺D«‚Æ•‘™FíÌT%o±,.!„à•ôy±:Ý…Z‡õÖ\U…Š–amÙÙè¶¶dY´A0û65tÊÁ)¿ÅL*Gõ®qh•«Ø¸–È­ 43iš8ƒËê\죲Fä»w7!«²r€â)Tù‚fx¸÷§žZ·*z“™»É¬@Âbi¤#tQDZN")s.©®ãÃeoIë#e>ˆé–Q›=1ssÊ>ú«vB^A‘P² Bݬûj¶øz¾º"²)Â]¹ÐBôæ0¬åœÀú¼PнLthÔ8O}ÃSUš¾¤ÁY ¡ÊlF}v€8Ä`skACUfÓ‡0ñSBïU5… ä¨ê=³zŽÌ¡QšåóN³Ú\Uæ•9mƒy¥I¾ðÙûù*oF˜  _qúM$“Ö+¶b‹ˆ˜iFN=À¨¡TY£ùB²;ÂFö1lw²ÀwhgUJ!x* l¨Áê$f†Ytò è7}±0¹Êû4Ë‚s >[FË«÷Ûå±9›{°nj€¤<†µÇ~ølZ–UyÅ–\™©D嬻ñZ3G•“‹³Ñ†¯‡fvvªFp&¾x¸ '4T›<—‡ÌC·D1fäÊù8Í*T?º{Å’¤{Ö³Æ0¿b›kG63y(œ¨0ƒ³Ì"–“XŸ„æÚ™7¬0öw^½ ÉVØ*jÛ-uõ‚7ù$pvY2(/ô-:f&T3³32ú0ÕF0‹¡5˜…I5 U‹Ðh·0-;zvð(öž€U&AmîšÓÚŒŽbbÚ¤I^–ÓÛ»i`gFUð½ò¢®89ׇÒ,¬ÇÌ`@ŒÚäIà–`ÆŠ¶˜ÑçÃ5Ú ¨,T;Yf ³M)Ëb©0z b@±'/Íî+_ÿêá 8ªÍc2­Ü'!&¼é|îm×Ü0V•U^‰0jÌùVId±6h+HdÁdØÈ9Š–´‘e’JEKeee&*›3Bž*š¢ÌdmÞNÌŒZJQ KNøH©Ät\ 'U§šE.Ã<çël†1Œ-¦Å¹3îÎÖxè”î6Àc ý´YFŽEðžKºõ„/4Væ¤OÖŒûÌ&X™ËiNw.®6sÔ½‘hÓHm§J"™ÉfˉÇZ¬+"Qðû[nà_Ítß¾]XÁŒô×- ‹ÃÉŽ$o¨X‹f”9h‚øÑEZɳ\(ÒÜÁd š‘ÞÈVÝjøD<Ì Ë~âºæZw;H…L‚ˆæ° 5¬-0“S ж¼y¾ß_öº˜Òüà@OíðÔ­EðMˆ(íbI’2 @¶Ù~@¹ÀmcÂÜu Ù©®JM±­”à¨LÑàT¯4ȬpËI郂Asì0¼²×8–4ÆÈÊRÒ0¥+¡}Žmdω?ƒ™J “‚u!¥ýØL ßÕywÁN—]”7•t·fAtúT0 mÀ¼-+Ã7wsw…Ï|FÂ÷´#¥˜ØV†Á0ÂÜ*ƒr@ VNVN3ƒ»Ó¬ÊÁ8ih줓ÉÞ’J,@ÓLˆ+ |Öu[‚îl Ç­‡M{*à Ûºc1 v賚 W¹ÉÃ^he‹µ–[ƒÈŒ“ædLƒMØâ$d† >t²É²Æ€Êànn"å†ÚI.£TrdÁ„óøûÊ®r¼{ÍÆ7;yn?q%£T$kiEôAÊg=ëêæÔšÌÌÂH«¡)£œ`Øt½Ì‘YOõšÂ¸2”¹U–˃~UN!Ç–)ÇÎ"Ј‚Kv¤¼ÄäR–•+son%ò°[<¤˜Á°Ö*3mêo=xÓv»öÈŽö s¥ªrx”™5O‡‘i4£™E[Ì¢`²m +ÜÌ sÈiÑÉÎá&zPN RÞ †$†3Íæ'2‡%ØÀ1j3v ‡qö’xzõOÔN‘Ž2Z³ £˜™óàÊ­³£Ž}¢(‹6qWPš…º£BÖT²™r–‘h‚sQ¼aõBO&™={Š(ÀXa0³!ÈÀ Í‡œ¹- dä×ïŸYf-l‡j«q¢n¨‹~²îÞñä5kHUæq")-£/ GÒršBJ"«eEOË!!åÓ]`™Ísƒ pS¸¨š×"iž©ÊìR„Ó 3¦­å:µË\G.æ‹™;NUK%c©Óp]€-K¸Ùƒóè‚ÀÊ Žà^ìÓø§8;œ,§‹½~÷¾Î®¹išH+ V”¹±ÒFk£E*§¼¥ÌJ±9— %Vè™)T‘„*%a£ÊU®MUJ”½UGg1‘8l—û‰ôصq|ðòk¥cBuï áØ IDAT²Üç€`ÉèHTºt£Á³|;\8Z h “rÔ0[ÊêmE­è½jUuG[V3“ñ•™ó˜dÒÑK¦æAé¹õ[-Ì­Fѽ»;Á+XX¥Õ[‚½hEÝrçËõë¬ÓbÑ‚ƒ5l4'amxìxY º“#ò¥… °¨Ò ä•,ù²yÌûŠ@é-ÝÃYc4(|6ÁhÐ.“6à­ÜžÐZ+‡üÿkåÞ6ê\åçQ4m+a£æ-‘ÊæmA)}g²’eBßö=¡Š^QfW‡ÜÚ4Žªó}ÇL„gy%û1ª·yIs¶«‹•†jmqB f5ƒµœÏfÙ&b“ef£´û@¾ôÒ[¥2u±HS¹¦f Å@éŸzø¡GN0‘ÞÒØ4ZŽÈ!(S™ÐÜVä‚ÌÆýö…Ÿú©?õ…Ï|tÓì*Ô§„ŒÓ**’6 Œ«©VMª)-‹#123ͱ8¡ÜPCÕ"dìê¬M[A3!#öQ¨D•åŪI±0‘~rqçÜ@k''"i{C¹™¦Y4¨`W¥·¶,ˆÖÍš7f^ÙXH_5#듞e ÃÂŒ6u )Ð4к ÈÍŒT,#Ú€l>¦Å ª8ci'÷TcZIfd^W÷)H–°ÖÉÝ*³iDc™'¢»¹(3Ó±6liÞ€²ì r‡$¹Õ²²Ê°1ee,–æ0Ð]Ú6S}d/"–ÂHi2+\A¹„*3y³ÝΗ€©NL5+ÉG³—?ÿƽ7.wkÛÙ®×,üKn€‡s1(ÌÛúÞç¹ùX¼ôúßÿ¹ŸþéÝ1›ÔÂG*É©` B §¯k[Þñð÷¿x¾yFÉ1ªˆòbª F¨ ä0fs ›Á¬P6ÉY²š\!i&w¡j~ €QѶéýš5l€RC–i¶í[s8èfûæ¯/ÏÖ¤g"†‹ÐP‹Ê%"¬QÐÕæÎËš õRq%`UÆ"ŒL¤ ­}Þö0 ôÒ`mQ—Ò^Y€¡ªêŸ«VçfµP\uâž|€Ìt´è•LÀš[£­Y¡‚*G ¼bÛ¹iësrÛÉÑ—8%:ÐÈÐ<¢]U®Í·Š­0Æp÷P!§Ž®å¦­ã˜¶Ñ`V›¬sÎw5á ÇŽ&%/®9¯™‹<žà³_yùçæ¯ÿÏ?ñ§n>ô°¤,¢ ¨ÊQ}ɇœßþOßûÂç>ó³ÿl{piˆq-v-¬†Ñ/×ó_ÿÕ_ÙŸßÿ«Ÿûü?ûÌåúÀÖÓýË×ѯ2ƒF)…mÂ23Í  ‹½c‚0SFgZa”@†Ó¼`^4h°rZb3A3ä(·á®ÀИˆ0 Râ ô­ârëÇãrXÇÃV0"ä~ı¹«L h=hB” ¬uõ­²Žj2‹Ö”&#j„‰Ãª¯"¬87£nX#²"¨a˜KjeÊ‚°I&yXõíë—Bß°ä•zj:8Ÿï9_\¯¯6*Á¬H‘{ Ñ:Žà:ßC•ëÊžV¢ÀÊd"¤Ñ'ëJM%w“íÍV.æ[LaM%(sùâVpÃkžI$åÑŽ«ö—çwÎïúvã‘ÇŸXÑ)´|¶xqkë›í•òwÿÌ—þyþáÿä¿= °U£c¿³¸—o~ñîCÝ|ìÉÇ>õ»~Ìwÿ0måÙòÊ—ÿÑ/ýüÏ_~eÿƒßùï=ôñ×~òOüYâìŸÿÊÐÖÏøðG>öcû¡ß¿wìôš.F‡\i¶P6q©r¨¹]æÔ a%.aVZ r”ŒÇdswd¡ÒÊm&ûTŒØÓY›HGxæ2!ÎŒ:i>¶~á×PŒ12;í5@*ËÙB£mì ͦ¥È0ÿ´TJãŽc (³vŽÕæ›Û¬"ç*—Œf[ÂRA$ÊP£§Nw»ýþ˜•2J2úµ?O<̘/7o/„ëjÜ@<–¶ÍïÀvvYYÀF3[5²ƒ‹&…ByºìŠ Õ((ÅJ'9 º§t!!µòˆÀ¬(À¬ÈòÒPVáˆ\<æ«nŒ×ÿê_þ›g7Úùùå½o|óî“·ô1ÑìdµÙ³JcTIJ?ž[ò­¾Ü:ï¼ñÆ—~ò/üÅh'?ôÃ?òúþ­¿ôßÿÄ®]ÿÊ›¿þÆW<óÌsÿÑúÇ>ÿÕ7ÿÖÿý7þ·Î}ægÿÒ_¿¹{ì=Ï¿OgùÏ?û3‡»ñ‘¾çc?ô?õ¿ÿÙË»±¬:ÜÕݰ-'ƒrédqÂdœv«Lú~V-ª´Ž4Q”3µ¸ÒIöÚ­¶¯¢9*Wã“"´˜eVãÌŒКZh“•¦H­*]&•­+€ý2ªF.Ó÷ëS„!âX“ùÆ“Œs)Ü…´Â–ÙèCÑ TÔ‘4Ã^o£øÈ@åæý ²B㘅]ÕÔFBJÕ`-ûQèf´pŒ¶-íXa4LjŸ °«IéÛœæn£`€ï8ääQÙÊ$UÒKÃaV²¶öð1Òƒ9ʲƒÑ#•co\ÛniM’t,Xçð¢Ñ%ËRM„3hô„¢ÔÖ@ó¾ø!øƒËw?ó­ïþà»ê¿òÒçîÿÒ—–“Ûï~÷ vºÛâÞ/üÒ_ùÊg¿º¼üôoû·ÿÃúȵÇùGÿÈ­ÝÿÚ½¯\Œ?ø{>ñÚk—wö/ÿçÿßü‰ÿê¿ù—?ÿ>ó¾ç¹gŸ¼îKô×¾ú/.±{ñÑg¿ë>uØùëŸ~´Ú7n>zvëöz²;ëÁ½/^>÷Mì?mq.>f}l°oÏxh’²çCb^ÁØ6i)z±Pvq9Ž‚—J˜råNÚ¨¤ÊÜ•“ªÃìòЖ녃 U5ÙS‰~ÒâÎ+o=ûü³æk:0–‚µ+®£I9'9‹Á +jÓÍOÂ"z˜E‹ÅÝPÉ©7­’R¥­†v¶‘Ù3sdi_"f‡TMáR¹TÍêšÜA,™:æ8Xàçy+¡dŠÑԼ̔N5;¥yÕÜh¬bƒo¨Bný˜§oþ¿÷WáïþbD â­xýŸüÌŸùÙÿõŸnm f\-B횯-öwÞúºãÒ>9Ô;ôÄýøzáO=¨úÆ÷|ëÍ÷<òù¿ÿWÿÁÿòç‚ñëŸýÛ?óÿ¢«^ùÒϽò‹_¾Ýž{ñ{¾eìb=y8í£øöý±ß~yúõ{a§:É‹Ü^xßû>õû~û×ú7ϯŸÞ<[vw¼üï{.߸ÿàÿ£ŸùòßûÇßý|®‡_ûg?÷þ»?ñÊ×^:=¼uky$¾þÖùaôI0¿‚>i˜ÐÁé(ÎftN/L\P‚¸+çàm–ñ“ 3UŒiö茗dªš(‘«Ç®×è˜Z9õÊJ™¬K}Ôñ¸Oá¤ÃeìÇ"„Ì #ÃdÓÜ1‘²–™nU£¦4·"|î[T–ÙÓ…?Y´¥•Lð9T4y¥VîÝ’±„‰5LVf[Ž~lUôÉk¨È9k€“ƒËVQÙQÔèYGÒHA àGi!~¬$ Åžñ“Ïüì?~ü±Çýµ{ßýû¾ï-Ï￾ÿsû8ËûW¿òµ¯G¾ýÌ»ŸÑîÕŸø¯ÿLJoÞ>Ö–ûóÓ|î_ûßúÐSý°·’•’ÇåÒ–xÂì7|ååw~sù7>wëì¹%Ʋ[ûåå½_¹û¥kŸÇ›ßøÂ‡ÿ–žï/ÛµWÑùÆ _Í·l÷îÞ”ßZÚ®Ÿ_Þ}ék·zü­~çµ—Þjßµ\;ÛÝ»ÿà#Ÿøž}øo|îÍ7^ûüý^¿ñîåßÿ{ð¹_ú̇žÿMx¢.‡n]|Óã?þá?¬v²«Jk&åtžQ%VMuYRs™ˆ”Pž}˜èó¼B(‚#w)M‘Q–v;Ëݨ™‚Tt°å6åY&jÔ+9YSnÙkm¤Ç±GúÊF˜—D`u³Y›¬~¤¹¸£ÒramËh„Òm"å9 ~u J²™u8“ÊËè¾^ë@V7˜ÖÖK *Õe·637ŽÔó¦ELŠb™ÁKœæâ²,5^RÒâU9ÙO‡PÉÆ‘꣮¯ëºr9óÏßùåüóÛoùƒ¿åÓíÑëíúý¥ùÿöçþôvÇoì–_Ø÷o{êw~Ï¿cäV•ßòâ7éú민ù…Wí»nüÿö“»k»í|ûÖßôØ^{ü‘Cq{ë¥#ž]prñÜ~ß!N걺öäͧò…/´_ù§Ÿþe~ñ¿å…Ú#¹ÏÃ{¯Üæótñ«ŸýÕí¨ÛÏ<³A£ÝÙÙïý‘ßý}0âæ÷ýÈï¼qöðƒ»÷øßù÷?ýéÏéÒ{úá‹Üž|ìÃïøû——û[· ^À5@KãUˆsÊ)†Øè>ë¬Cs›ïC¢X¾Ìí¤zfUU¢±£ &Ã9œGg7³2¸È** FÀ&iöjHuâ~ûöS–6ºù)±Xމ­±õ‘Z„‘^`D"IŽ’ÓÇ€ 0 š†Áù·¯¶T?VB§ï2if™VxŠÊ’k˜ê8äf%Ê«®ƒY.£JJå¶U¹yP…šœisB³–ò´)7„x![AØ€J¨ãe®‹–•±`oßæGÒíÍzäÖõ]•ß¼uãW^úìøó<—ãòÖÝ‹Ëýk/ß{Åÿõïù^<û…¿ýS¿þÒ?øŽ|*løù£O½ë;Qøêþ^}ñøøïüúg~ùçŸ|æ™UåW»=–gÑnäxåXﻸùèGŸyõò_~á•Ï~ñkÿâñþ´½Ï>ó}úæñùÏ¿rñàÐ/¯Ýxò›ÞùbØÓ'w¯ê÷þ‡×Nnÿâ¯}囿û·}ßµ8¿<ßíÖ?øoþ§eæ÷ïoͪËý~×âáG70mÄ¥¾U¶£‹¯šOÊÿÏwƒt(‹ásg²œ/=WâZ™H±ÑÁÌ,'œ(Tšyk3±¹š%*KAšj)'¬O*ëj9E™,ßÖ4Çb•Š ÄŠ}Ôp!“aær¦¦Q¹˜çH ×ì¼[fQÆa¢½af¤£à„“iæ*å¹ ¦<١ƱÒEkæ-#‘뤻ûœü«oUˆH6$T`пŹkÞ¢7ÕVisŒ·´Ö2Ù•}¬ÆÃô•¦ËÄ{ž¿ý¯þU~÷ýàߨýå/¼òµkkäñÚþòüõ»¯Rͱþ®gß|"·}{ÿwþÞ|b[»F7ò;>ù>`¶óGŸ|'燾?ö/¿Òc9±•ëê'Fso» mÛþ°?Äîpè>sd4Ò¢ Ì´«µÄÌCs”7³­¶«#Õ-LÁŠ$É<@³*%•pL*g ^ØA$MaTòb;`ÙíœýÔL…ÃP0‰4±‡Pj “&àÚÙgg''g7H„át·¤ 1Ó ýhÖª`J’J‹‘µÂZwmæuU$Ü)å4ÝL5ŒæîIËÑÃVUV¦›ÍK E†ƒmqYÂjÚ¨”Õ±_Ö¸¡%¯¤¢òÙ™&»µÖ…ûMF6wJ ¬SXÏìbÁ¹x)ƸØ_\Þ¸ñØå囸xôwÿÈ¿õçÿäÿ´?òš^~¥=ù¡úÏögþñO^ûòîÎù[ï¸öÁÓ[×âÉØ±K®vý¡§Þûè/Üýîi¬—}hôiºým?øûOc‘ç|÷óßÊwûVuâÛhÎ÷U<Ô¨¹üG޾‹e”(+Z»uÙ8pQûK»3Â{¹ .nÇã¾W˜9ÊLGÀ§p‹VÒ)÷}›EV¶l”;Ûɹ_mÉ3‡!ÄAòêÐ5—U³,„`)‘.`õ0åüa, h¼òíʲ]¸Øè˲¤êÁ–}2ÆøG~×áüÂ|®HÌ8ØÜŒtªhJ5ıÒÌ=µ¥RšmŸÈ,ЛI½F…ŠV26šÁZAf–)/£Ô ’#«‚ =őᒠ›ÅéI|êöYø,Ù;àÄÏh¢²ú—ÞØ6ÔäifÂbÍѤ½cs¯Þ-|xe¯^¼ô+¯¾ôÕ÷<õ-|øú3/<ñÊ[_¸1Þ÷‘wœ=òÜSÏ/Ç}¿vöä{ŸøÈ·ÿÀ'ïßùÀ7üæoûä·y\§Ý~ÿ¿é¡g¿Ä¬ÆTØ4ó¦Ã-¼Jˆ¥JÛ–[óuªó`ÖY«±[¢J%V%Yd–Ãmjml±£Ê¹î™t¢ºDɪ°O;Qd“ ••3’¬‚‰2Cqä9 ¦46LA ØûÔ¸wÔÄÓ‘‹S¼@Ï’ixÁU%‡;DCeq•9%[^½‡Íµƒ·‘¦cËí°¸Ÿf<ñôã†Íµ,~q<œùJ÷Èý˜¶˜Jc~D§›Š«åevú’’èÝ̦?€UuZÐÙ)9b(Í @–™0_ã°°ŠÚJ2Òäf5zºcNÜ«jN'ì}•-tvm¹<ßwøUÁ´ µB‹Vã¸9lž"€JÝpöø ßþ‰çý]käñ‘“g¾ÿ“¿ÿÞƒº}ífíùÜíïxÇ'¿Ýv§…q­NÛÅ~}•qÓ@WéiUZ`2ßT’Ü Í T¢U‘n® ¢FÛ9$GÁ—Ø*A²8ÍèÃCÑ<çÉÛè½NŠMÛŠÚzÙòbâöØS§»5«mtÉ9ÏLŵCWºƒÑæ¦l”/HaÛØ˜'’šõ?[·1xu°Ns”DŽÞMs¥¡‘› VÇ*l¤‹ªôf5’4CP/ž€c±¦ª:2Bh-Jº¶[,«Š‡"kˆ m§»¥eöMfVÔÞYãÌ(š3ir.1i£€ª»‡(Úš#sÖ º Þä™å5h¼¸Ð­jòVÇËiúŒ»ómô xeÐnZV÷„Nè‰QplÃj:¹_ ª™‚pDu<ùÞoï9èp¹rðƇ4¼!‘uìáìõ±R]h2y¢„ÜT Ë裪†—³¯ºzò±mÛº4"è†ÝäÔÎÑç¼èòX«y‹2óó^K˜…*½ÀâL|ž„I¤¹hÆq(.>(¢.÷Ûp-B+(&QEì+Ṵ̀U’4‡Ù|KObñªa\T3ˆ$`·.êÝŒe\ÝYl”•òjæÕŽcX±“ÆëÐeIæ[ÉÍÃ\5•—Õ"¶Lóq<=»Þ† GåQ¾Äº©7/ÍÚ°Oú¶§5si…‚’MPEÛxÞ§Ë•ÛXÅd4[!ͦ1áeBC°A_Õ*¢ïh7į<´–í cl:q@œ¾“yºG]éœÝvM C$E›ãpT)¥ðéœÍž `Ó¸¸g*”ª›×ù-;jG¯ÅŒ“Óíp‡¬*xª[Z!SºÊÝô c—RjÆL}œùr l=ôX$¡QÚ²ßhke9`U@)Wçý^£Uv£á²$A¢HS­'žÂ¬ê¤ù>Ç€è9šYΡ‚À!ŒnæJ¸™ V‰‘î,7BVéf@åí•@“ͼŀPPÒè00+Ws°²h -ç%ƒOæ 3GntÊÜa6Ò n~»Üz_¨ªX=M÷*–Ì"¬J¤s!*#¼²lm$S峡?Q\ØÌ}u,æÄ, Eãf*ú!¾ æ,¬õJ—&êm‰£"h#M,å!}ñî:;f?Œ:µ+Ø/@ÖTDîª8·®Eùˆ¼z²TóbÚn—Çîš@Ž*)a L #͸ÈrâQ &Œ²ÖVX8 fÇfÖT[çF„°zËš´º@¸œ#s.n§(cF¿Ï+;d3v¾„™/›$Ý p•IcÀÌ*»HI5\áE`¤ö5jÊ>ÒŠÎpwSfæ>`½t¿ÔBqF"ÉÝ•ïÏ&ÿÉÅ&~ûê£4Éh4Ëæ®Q4ºm•-šU×èñÿðô¦1›e×uÞZ{Ÿsïû 5WW“ÝÕÙÝl6É&%™ƒDR¢’–(j°[‰9 !3Àp‚Lpàv~I`뇓Ž#;"ÛI(ËlÊ¢DJl ”(Q¤šâÔì=ÔüMï½çì½òã¼Ôßê«ê[÷ž³÷Zϳ©Jt™¦qiWL> žNfƒÏˆîžè뺶• ¾Â¢xqZ&rXbl”µLV ÈŒGFBÚóB!J)ê¤GÏìšh¶_MÙW0Ù†®Ìž‰©Ö¤+º›Œm…D”"ÄbÜôiY×!™ä»Æ@Ka&5r`›‰ëRÒú¢APŠ!'œŽ¸(Ø“»ø¶R¤œ$ÆÕ'˜C<š)К ž’¸™”}|`[Ž’&МÖ–Îá±²…ÚúR¼:’ë8¦Û’€±+JñTBXZ2! ÜkÂáCkYˆÞ3Í YänÅ ïÒ i4¤4«©ŠÑ m°¢Ð¶ç¦Õ›’»Bdk)" ú-¥è ôÐ’ÅÃB»-P‚&XñÑÙN¢+–0H¤[ö˜ 8Å–nK†¼D/§r÷ÒP2ûÆç®N­÷g ušM.dHƒuÁÈy3a‘w±¸RP²Ô‰nÊ"!Ï\›f¯É.)¡\Xàä5à;aæ ê áæZ{.©œ*RFQ!”aIÀqÌ¿\ëñ=ƒÛ•£Ö* ‹‡ºï*‹îœÎ¦–4ŒÆ0ätflŸ@$ (¸Ø>U-ë²vÏ(S‰HK¹`D0—déi©É‡íRM(ASW¢dC×f°aºÉ,µ4/€Ir3ž21Û2k—¥úèÃ)Cæt7ÉŒ€hªÑ¢&¯#ðçèã0±t§³ CéæûÔZL‘žeA”âÊLi6L—ùl­eæ…Á…%-«”žê48]#z¨a?-Y‚röt‹\WŸÊ9§Ã SK¬ÚZ†³ˆÐäe|r6Åë™33›ÝÚ´Ò]N"zÄÖúâ:CÊgÊ$!Rb“uÜnÀYò”h™AÊÑ^ÌHëj*<‰Œe¼F$z.¶LeG€ÛÞÂè(i?LDÂSH¬æM8ÉlM7Mf/‹Æ>îf»¯k®c+:Â>-¬ÐÑiÌž&€6‡È°jm—,‡˜$EÀÝ$öˆì[E×Hp%$'˜i‰¥gVº›ÁúªÈLõ´¦L´Lˆ¦pÀn°#Fd¦6ðÖ° ‹rUžÎž?’ &"²ƒ,5¥4tîðáÇ@]1ï»)½%šÚYôtoÁ±€±1Çq2ÒiD&+8ƒFD‡Pº4¤È8‹€²¿QʶѸ9TZô®uá;™¡X{k=Yj†€Òe*œªÅS”$+ò¦Ýíx¢y- ÕhÛÈHKbõÌÈŒèžÙ{Ï„Š¯¡–2+{C¸†dë{VO΢VrêG^/›Ú¯³É:;ÆñzXÉŠLEï=# 1ÕZJâðÛ]VQëFÑ,ÁmKu4aUCºW=¥¤§r§³[ƒ+ >»M¢'$k´niԒljg4T …ÔœÚL‰,ÄDÍ0$h5Ç,¬ ŽìYO)‚©ѳïìë²{jC(P¥ª@ª Z°IŸQY„Id¨‰]Ú§,•òÊi!õtÑ’Vœ†ô C•¦+jñ24leê>‡•$J²‚4·¹Œ´»¥I ÛÙÎ*-NÑKd3ã’ë¾328ÆûB„6¥ÆÞ ×ºU¸Acc%¨˜)@'àNdÛͽ  YÕÀÒ3{ˆTW’…ÙÜǺ¢¶L‘gž˜qî»N‡DѰ¦r…šm*SáÚˆekM6Û™ÂiAteÊ2}¶ˆ8C&̳Ê …",‹•fÆHåð~gc÷ÛipòÌuø ,#È„•ìp,9Bý0…ZHÕ% ™*õ 1›IÙzšùi¶jn¥œmËT0ɳTÈììÌM²Àš(²jhÒ*íCñ‰Ìê•êÐH½kAA˜Ɇ!y„‰Ø[f®ŽÖeü+~à •ñßf…¶Ù ^I7FÁšÈHˆ£I|†Ü¸÷àÙq0Šm¥úñ™ZÚ4×ðe¯Ôí´)t„fGá.\W½Z1sÉRY§•î]*uÏrÀÀ%rò’dŒ4vBãÍ–PA–ƒÉKñ:Y1 ß ÷Í ’J§G¶ìÃ= 3,](b”ÃlÕá,X V{Xª"5)Gh±˜Yñ\"œsÙÑz*hHƒæT¥ÞÞB„ ZGÎ¥ä"á!ewP@ÈÖ9³0Ø#’‹D„e7¤e$dŽUI… f«H)…+•LËž¹t&Hu(-û 9 èuxRiŠÂ•´u™b+Gb“J3ZW¾³2º÷Ì/¢ñˆ)uh%Geeô •VXÅ c7ÄÔ;—\z®èÇ‚â!­‰È õ³Ø2“™¦,ˆafr,ØŠÊd`Y©ëátÈb…¤—¹ÎÓEô˜7X³ÒÖ4¯e6õ%:‡± e”ŒjŒu›²w™q,#ÙQXáÑ!š³¥ƒjÁ:c™‹ Z»r+ŒÉDMt)ŠlMîV¨èTT11&[Éy*›ÍªãI‡ÜÑÓ²H¹ºÂlíÅ]×@³‘ê1YIFôÆR•BpÍ0Ùäë ³P¯D·2¸ ÒIsEšÁ¥¦nœ«{ëYg]Üx®Ý¤•^-cAŒ å8;9þzÒJ³DŠ´6ý&«¥ã4-K·:AAd²X€¥Ð„by&m¼¼Î"½Tóˆ”I #Å~zïæ“³u]ãn<úø“÷òÅo|õOâÎæ½üž¨íÿù¿ÿ÷×¾øÂG?ô¯?öÝoåÈÒ„´p IDATªXjÌ%™ž–³O§½ÆR’N{oÙ0¹g&:RSÙ3Îæ^¶½Ï6õ“­Mµ`Q*±t¨c0Ááøeв°5 IÕ½:±ŠfÆ (Ä@&`^œè‘ØŸ’èw1Óè3 "Kg§eô¹L©T_7Vû$fªõ%lêf>*  ·1K€¦‹ó|§žÅJ›T¸u$¼öÄȳN0yÉPIOÓèo¸¹‘V p„b} ¦‘µŒ¯ˆìKsôì^Ê®üæžQª›õÌž–²ÊÉ‘­;@÷ÛT-kÀÍ@bˆc3 A[ Œp>"1©ôÍþteo:(Þ™g¡åwŽS‚;Б‰Qî´$ÈÉ)gnÍõæé·¾øÉßýÀ÷~ðüƒ×‡Aajë'?ùó-úÉÉéúª~òã?ýÊÃßú“?ú½éäâÛßðÖé;ö6Ûãk÷]yîÅ/>¼ÿô´U˜#“ ‡sÀâ•SFNmQf6pIëp#tÓÌè¹´åxÑ[‰îØxTG8-r ÉúvcóZQeæSo±WÊšm“Zi1™ïè £[ϱg%0z"á‚#Z;.Û AÍI qž)û(úFšûÉÑ›6³WD¦óÞÙ)¦Z, 6–%ÎǬŸßŠõ¶v¤¦š=>: [o)͡ӟÁ(¥ÇÂv²×g#‹ñnGµjJŠS)[K¬‰.•’Ž–Bkr*™>E´Ð$²¨+¹O3 mˆZB¨4¸Bè´ÂZ²e®*u'²äØà»g‹Ém€ðܜΠ—÷Ÿ~hSu*YmZ³š–Éïžõo¶—oõCðå-›ÒÍ-P Q‹o_ûÚ¯ÿ_ÿ`ïà‘Ó›/_yô±ÖOÍtóððú;.ýÑ/ÞúèÇ~øßó¦¼píî3_> 0ço}îŸì©÷ß:Y6õàäøkgë¾VŠLÐ5xð*©Úž¸¥ò9œ4Yf„©‘3M«2P²ž¿¶ ¨l6Öcà3<Š+¦Vyšbm™+Äž½(¢,[YJå(gŠÊ¢LSÓÀ-¾¼Ù;èJeúÀŸ:áÃi`&t¯ášö.©’òl,n›vz¢sCÐMÛãÅA`ËqM²ÁJ®‘£þ “!CiÉeò³³¥fVÚÖËÚ6°UI7o­;ª)ŦŠìÃEÖcR /¤”@2“ Ú VÙR¤òP$Ü-ÙapVª y2’¶ö¥· ‡çtåÊtß}ç/ÎS„3`æC'£•ç­ž»o¾ï\}ñÕãÛ·¶Pàó4{ôhmõ=¿{|T4½ù ^~ã[ E(MnçõôðÊéËw¾ðÚ?þ³÷~è/dj UnOîž|á×÷óžéÕ[ºuôµÍùw È8T–!Èê„2Ý}¤µNZVs†=qîɸ³²d±ŒÓn ›}òž5 ‹² $-á4¢Òm›Þ;”Åi}.a¥˜™E¢wFb4w ÈniÑ1'L¥#˜«ÛR|•zëÀð€£Œl‘)é&Ô’‚ÖÄ2L=>*ö‚4Rð‚{Åú¶‡‰êÕÊñ@Â]1gÖ³õÐËl#Yד6°UYäÖÐÓ°Ê4ˆ3ˆìâ auõÞs|ë5h]6Ü==7-lí;¡@lѺ”èÍ×µ$B;¹åüÍ{?÷³ÿãßúös¿÷ôco|â±ë—Ïퟟ6Óf†3\Ýr9»çl÷ŽOnÝ<¶â×f÷“o¼výвvûèK?÷þ7?ó?ý—ÿËÏüíã^]ì¹ÏýÎÏ—ýÍ×_üÏýÚß½ÔÍ{z kÓ{À,Žïö--æE‡›èxÇão·kë³Ï¾pÉßúô»ßuoÓoþÎI-v²¾üê×ÿ¬-%0ÃNÔÝsNôˆ ް´„÷܃7EHIѹ +‹ûT´vÂhÉâ™ð2D§Š)3Ó‹ ¥ÒÍ3 |5pÉ¡ÎYdI`]qâp­xW*9ɺ" ÌP&ƒ}`5YIISqwFƒhbC­3ã¬8V:¤©¦¹£ÎÑ»zi%Ƕ °RZ¤2m÷u–¢{d÷:.Énèæ9òÏs©á½ÁèB% éVX+´4äÚ‡TÈŒ„, .¸42>tV*™aæˆ5@ïV¶yë>ý+XýÞO|ôþÍ»žzï¥Çßùöë×®°Ý|ùÎoüñç:×ûßïµ}î3¿ùÙÏ}öúÕKöÕÎîœýèOüØG>øm{üĵöí ß¾÷[ÿâWÏ=ôyòO¿ø™òó¿ô—þŸ|êé÷?ûÌ>Pß÷î÷}ènef¹9µ~{×[ÞõØû>t¬3i=ÍöÈ…÷¼tptúûÏ_)—}òÁýúϾþÚWžØ|èSŸüùÃoÖÿäO•iÔ3Í©DK$mÝ}-d†²DØYt1ÜB­š…Rë6ÜPÍÌ­@‘DFÈ Êä>et©ôfŠŽJ}+ÅP!× )ÌÍ<ª±š€°Øú ãzOF„@‡WFRpº•J³Þ#R©„â(>Bk XõiƒŽÔβ;ÒYcŠ=ja#Í·1`Bl iL–w©eI—  5™ŸD$£Nž–›óWÇbeÔ‚Ùd¤»õ%(›4²{‰ýùå»ßü§ùø¥OL³¡uÏPvD‡o­4ú=õµ+Jé]«ÙåøøÛ÷­7^{¹}ý¹Ï½úüË/|ó·ÿàþêæìò—¿ôû¯}ãÙÃK›_øÅ_þ+ÿéò ¿ôK?û÷ÿþ¿÷þkó~rï+ŸÿòËß¼÷ñã·î¼ò›ÿìW5[)µv¾ãáK{h7¾úÊ[®~ïÓïûÐ#ÝÿZùîñ+O=ñΠ篞Ɖ_ÂQÄ–ìôÜØõ —>ã¥¶ÄÆŒ'·OïZ¿|ãñïú´ùêƒOµé—¾óêtéêÍ۟Γ—ßñ¾Öû/„2¤ -©ˆ1.Ê*ÕAug¯*ر`;ðT¢-e°¤†c­¢(èè–QI‘&¤*–C•šËÔ” R6ðŠ©0ˆiz7©O`ƒKƒ›fN–’½q7`öhs‘!;=í¸hE!DŽm0vnûý©K{„{ÙQÉE9îY]€ùž)˜¾öôlѸ­Ëy9( f•^ÐVxY©YÆêkï`‚¢)³Ÿl_z泿}¸¿÷ä…÷£j3ûÙ /woñ¥¯ßzèÁK_}ökÙÏ?ýæïÚtÿ«_ûìýÖgNîÍàòÒ¹¼÷c_~é·ûÕùœoOÎ^í·¯\?÷Ê+/¿rûÖ?ýÅ_¹~ýMí¿þoý™ÿáûõþ çÆMzn¦Ú‹ê|Ø[[¢ì^‹}?ºq›‰iÿâÍ{Ïß=ºuñòÕ-²ª\¼|ø‘ùÄ/êWóÙ›ÛíæG¿ÿý›û®óìú»ž>xåvnŸBÍdksÂ.¾íÿå·Î>u4g½zå­o¼Ï×Ìå¨=òÈ£K¤z®Ç'N\ºò¦Oü«ÿvº‘‹ØÝç0õ’wr"=5 ·jâŠi®M}ÔäîçPp¶-Ó¦˜ÉÝÒàtÄšFZq&Äá¡TJfœÆÞ½H˜gº‘3=0ÕŒ]‚¡ *6EŽi±«…ŒÙ;´" d8¢¯ry© '©½Da¸Ð Ÿâd»ø#%’û“7´66‰-ekdñb‘£3]³u–„IuYÖû®<üÕgÿø¡ëo¾ÿñǺb‰þÂ­×Øâ.=ÇoÜ|öÕzrß~ø;ÿÑ?ü_ïÝó¢Û/|éÅûžüÀ|ümï»vröê²}héÏÿæ/ý¼\~èñ'îëU{>ï´½Ëç÷Ï=|í»ßýþÏýo¾vï™^¯oqç¸ÌW¯¼É¼õ•g>u´=sžÔõÛ_{ê¯ß÷¥¯=÷ö§ž|ôÑG¿ö‡_úëõ¯žžœ>pù¾ü¾ÜÝžÛì[²}ç»Þòàï×t¨Ì Sâ×ÿÀÍW»sóäò…Ë~õ|»{zÀÍûÞòCþTöu ½F- -e>y ÓnfpçÚC)gIAäTPa“¡×¾vóŠ@ú (ïí.‹æ&ï‘Ãè–m9ÞlÎ;½ì¤‰¶YU2¶LººoøçTP½ô !ÍGÇQ 1F;Â̓B6ó’@O"Ð8íÓ¼7±D"²3VÈnõÑ准ё°ÈìØ+Æš¶m=,¹ %ka{ "cºtÅnÄ,%µ°df1$Ò«9JôÁ ÈaÑ;uÝwå¼[¿8?XïŸ.Ýw·ýÑ×þÑöONï?ùf»{úíƒOüØCõìÖ­›ß>yûCï}ä‡üÂïüñ|æ7ŸzÏ÷"“G×^;:º³=»zëêw¼çûŽŽþôó_ø¹ÓþÍGKùÒÉöøj?¸ráÜÝWÛ¥ùÁƒùâÑ­³_ùõÿ£Åíó3uü¼]úDðÂ)Ö{ë+×ßsûö(ŽÏÎþ£ÿßýüçÿðs¿ó¹‡®=úý?øQß\:wpî¿û›cS6:;ûÐ÷}¤­õÍ}Ü‘™Ñz9í ç#Ô¶#–¹äš(‚õˆ"£ÉĵuÀòõû 9þOv3I½ÁJÙoU¾¶¥išÍZ/ðA\+Õ2̓¢b]Ï&mØ;Ü9Wõ^̬Ø"Hµê<‡¡ e€î@Ò(/uß-ÒrütE;-±ql«Š/æãm¦ £1zqKgpÌݱ•)s‘­š¥l /©b… fKd²zze˜Ö']™E%„¹²Ó80é0• óá²}%‹Qš’–4 ÙÂ^]=ÝÐBqzºÖíÆëç_ýÍåèÑG/ÿÀ›ÿã~à§¿îŸü“Ï?ëyøïyôÁ·~‡÷ÝwíÅ/ë?õž+_þÒç_ÛðàöKW¯®=Ïmʹó6ÝýÜ3Ÿ~íø[çÎ]ðÁíÝxäÚÅVïûëoW÷»7_öióÝïÿ‡?üƒk_ÚÙ¸uù|þB­žhãßpº§Óê©4ÔC=UàpÐZ†SS‡IͲšï¶«> þj'ŒI¸ÈnðA§®rõdx©™ê”•†¨Öƒ¦Kd¯NÁ«(6Sf v—‘QåÜž›[Ëm!†VE¢–Hó:"Òft œz€‚Ú¶¸£T›K 5…e¬ÓðV›™ÛwÀE$b—ø´jE‘ã7€pf—ƒ2K¤[éRŠÐÁjpšGÏ]Ã8êî ¿ãT¥ÔÎ[ÀEsŠ¡ÔaF$I7)8è´-méíâÁå[ýôÏ=ø}ïùñä9,e9Ÿåú…7<³~éü~î wßtîùó¾ö¶'ž|æw¿ú©O~òþǧ“¼±ïã¼wxuúæ·Ÿû‘üð}è£÷ïüãoÞyâMOÜw¹\èOL¿û#þjÓÙÝþž§j}r¾·×®ðñ~ïƒjvnÿ€X‚q¼®×®¼Ù.żí{ýìh{R jŽÈÞûñz{ÜJ8¤‘ B^ÆÁÒl<@Z|ª>™i'’*D¤••ÃæI§2:¢XW˜ ­Šì@6ÓÇI'DOÁ}¦³3¢ÛdѬZ·’9 ¤±éJ%Ù|Õ{G´+÷½Q¡"˜¼˜×ƒ"™)†â@tTó€#[át¦3ç褌ÊYßL´NèõO™'{ï^j¢'è9^ˆ eç8,9ûÚ7Ü`Є!rî:3¡ÂLž™V˜«×Œ› ' ¢ëÆuÉËiÀn^‘¯ÿH²Ü’¨ˆEYZ¿wéÊáá…—n=ûéßþÛ_»õã?ú“Ûâ7~ãW®ëÍïüþGžù­gþßOóãù—ï¼á+3Ê…só+¯œ\ÛëG>ú/-‡íÉ0^œN_ÕÁýïú+ÿÅ»ûšØC•ë’_ww,™‡¼Pª­ëóÞT÷S§gýt¬¡Æ-;§rc›û5a±:ú8@ʉW¹¡€ò ÀCêP¶~Òã¢Õ꜀“F»Ì²‡0º»ZL“Þ:#l*j±‡B*ÒR…®¬àÚW¥hE†$Z©cï1OYÏØ¤{a“d~ªœ :{IPèçï㛯®G—³e[Ýl*±6¤J©PøfÂàig€¦Š {) Y"•Èj«qEZšc Nšh´’$Š#{%c… µ#\™¢RFCÑ›º…Ô·C}'±ånÚ{쫲樉7!9$Ÿ¼3;!w™ñ”²… {ö*&`@Š3ˆRRåäôÛ›õêKGG‹ö3Oþà÷ÿøÚÃï}ê¾ï¼þÎÇ.<ŽóÍ^=9—?|ñ‘ïû×òt‘Y»»<ýÐÇðHnÛb©ÓÓmS²ç3ºYõmë„w"m"¬—¥²30yéRîÄ„±ÈJÉvºÚ¥ô.I®ì¤+Ų‘íÑü¦2ãSÙaкÅÓÌ‹{<†< ™lÚ!†­XF2Å5X\.ËŽ(å,úDDFpB’^3ªFˆÔnÌ$zfD ¨¬Þ«¸´4w’™ 6÷h#ï}zºÕÝ›:ËÂ2ar[Z´ôyB[`=Ü͉®Å­€ãÃ*'å6˜4–yÎK8zt'aÙ ]”È/©´îCa‡Jëja¥®U¹Ê“ t*˜£„~”ۣ嬞? Bù:v†aÆqŽêÁfs+NÖ5ÔdIb›]J%ÌJ(O3œŠj^—‹?ýÓÿÕtpþôìîüà•§wÖÓÞîÝ>9ñzžOª¡¿¡^¿vëOxü}qÜÕ–•DÖζ¬!›•È(Àª­=‡Êe†›I±u÷Ò%*܋йKÿu£¹­Û;'Ë|XçL3_’ ¯hs#Óe—± (VêÊÓGWs>c…( ½ùðdIÕ*`u¼÷ªGì|+Ä´AA@RqP¼íÖqÙ'˜”"Wc12Dš+ èÅí(¬Œ’ŽlÜHìÑ%¼”PÖ{\¼v…ÃÑv»›ö&mªN»±´\9í){)3DAETA„²‡7§z¬™FPÑeÈÙ4šdéŽZ0xÍkx©­ˆ†È^: Ö›rìZ¤@a2ûm=“98<¤¡C™3x£àp³²j-]JEH:mMV®QRKá$o=‘ß_ÏÖHs8‘4[£“Q”ÔqîÊ[>ö±.^<é²J-©Ù =Uš)¦².ÂY½`p¬ ÌôÒ…Lå$Q­š Êú|ïÖÑÕ “6Ó6ᎎ¡§hÁágصM,šÆl›UEœ„ß¼}°µ á£rl¦…ÖVÑÒÓȳ5M£ücf.˜˜IË–[a´y޳ ½ %\îmX1ÄÔÆ½µ^ÍHPÉ>ü0H†Á2- ™q@ô­XY Ú¬@™Vdm'^'€7”tƒBÙNÉaFYŽl‚¥ÚFó)lR©D¢ PJHtwÌ‘´p“,äÐŽðQÊYïI1C¨¬;2¯:qÜRêÚ¹@^7Í%`TzÄêÎjq7Ó$¤Çhï¹CÖUI£9Ͱ„Žqö%¬Ò#>/c­Öz/ ÷Ò狳 !ò ¬×Úƒ2³–-DÝírù~Áj€rD‡¹RbÀÓŠ·e’†ˆ`ØnzªT;º×Ú+ÛÃG‹ c¡«2i ÷X`ÓhÒ„a%“)ÀnmOO¶}2™!€p% C—¦\£{Ùì§6Ebžîrs ^»¢¦rm>×±IY ¹øʶnPlä]Ý‘L—`Ñf` ÍR˜-%¶&"Ð 6 àˆso¸à³˜{›ÉÔÑ5“IK7Lu2";¡Rž;×ÝX†í†Pû]ÅIR;˜:–…I¤zt@Œ ,ˆŽnŠ ;}<é,2èÍ!+g½…r°º)9HYI²L³ §âÕi2®ÄŽfЀî”шdrß¹;c÷Ò(BÌq¬ \Ã4Ò©a ˜ÈêèQ.&2ƒ™…*&¹w¢m•2 é͌biT­A¶=ûÚÙ{Ë(h¶Ê¤§ ìÈ¡Zªd¯”ˆ%™c˜¬Œl¯½r“…¾˜ws”ar¤%™¨“e"i‰Z§t‚ª­±G5ÞTdf³£šˆ=Ã4"CîVXŽÕÑa-ee±šp“<º %¬­áTarb­púæpoO^K±ZGZÚ­2ƺ·8—~œ(1r€(C) ˜·5vz1X;]}žºrÊN–£bY¬”²á*YENÉÕGü¥ËÝÅ$GVΜHC )õop(Ç{ Rr Yh…¦˜7rXO‹ÄâhYËtQ$K¡ nB ¢‚‘ %Ä(ænÝ‹w%½ŽãL±ÂL‡ä–uVkÒœ-9¼Ù3Iº`A-©d°Òº!åD˜£Èz?Õ)u)í,ÊsÏ?öÐÅR1€tKC¶ž€S¹ÊŒ¨bîàQïßzéÎéV+‚š#ÈNUí˜ÕCɦúBg«v¸™"Ö’ŠDdÆžÙÖÒ¼¶Í1n÷ã˨´N†BÑ66Ç*YB½@‰œ†ýšÖ# ŠˆR†µÁ3ZÌsë·No%/Gé‰@)VŠ(@Åk %'3 u[›÷ÍÙ–,¬^È®@8Q7Âê0*FW’-rì ¥¨¬ãàpx~2Ì ngm+ÌfÒèøÙÙ–¬“†\í"Âi^2›LÑ­¦gW¢Ò!˜8%s×E¡RþLØ6A5¸0[š—mo4’…½›ú (&×Î –25ˆÈ òNBîÀv0o$3& ŠÕè—”‘)B-íÆÝëñУWö ²™`1È«™i¥) cYúW^¸±.d2•¥ÖÌj$­7¢ Å-2 9YIEë ܺQ=†‘bK¢Î©&qÊmw"Q,s' #¡½Øx⢈iÅÌô“!cÀÖÔœ(>íÑO¶6_˜`,uÚ,ËÖ­¸ÕÖ»'·ÛÅ€:Ín˜­¢L¤E¶@ÉŽÂ.sßP Œì¹÷vÀéOÒH/-Ç1Ôœ4Vd@°âs[cÚh˜ÚãÔ ä0ˆøÐ£eFîweI`77ë¾£±e†ºo|-Ý9&‡Ü ¡\3ÔW·2päÄ®¤"ôjÞSéªÄ0v§õyÒzZ«ÈîKP¦0ºŒHJHÊÖHGÈdpÊJ÷€UpE†°NÁœÊÞ"ÉÔAt_ضW¿që­oؼñâþ`¥Ó ®!ʬDï‚^=Ë_;¹so™lShȾ)›ˆ6)•¾2šyD:22Ь¤ä S7ÖW»NBZÔlÆM%·=Ì r‚³g"Z#Kñ–DéJ7›F=f‚ÙÎyGdšMS)aΞÛ;»zéR),ëÉ ÊÄZk™(úd5-kÑ]‰Ì‹2kM&­Í§¶]f+™áY³–Ѭ!Ž›Jö àÕ„ÐÚz:+äØïµØàuå3G„°9J1jà œÈÒ£“ÿœaŒ w€[#w?Ù9›‹m‡'sj–Õ‰€™›ê(I#¨,(-‘ž Í|ÍHÚÐËfãN¨d°X‘e*Á4‡š J5hÄlŠñ¥³˜£GK+‘œÜ`Y2”k¥-9Í‘ê¢õŒRÜ0ªF±t…ÚWžo·o/—Ïïííûf¯ŠÞ[3²K¯Ý<;>:½u÷´Ì“—ÒPÒ°®g6pÛÓ÷6´ÀT–eqZ%çZ–~zˆh¢»›¡*ªa 4ÈÊ,µ0[N3¹önî^Ü PÇ„d,ë:°v”=}¨@ITb¿ØÃoºrþÂÙ½U‡‚îÂ^]¬L› ¶ëºÝúfî™)lY¥H¥[Ñëòܲ©Ñ6haf¬t™’ #\&'Ü}€Ê„(!¥Ö„ÁÔ®Åë¾[]²n&6&ë&%ÈZ¦AÆì³ÐZ®âVý€•xÝ/7fìã{ËÄí”›m£­HF†a¦ÁT‹ZÚ6±™,Ë̇±!•©ôìKÕaKî–Ü¢%ÊJZ¦ŒÐ°³sôÈ̆ËyEVÏÀ3 l´€M#£ RÆ€Ïu¢g Ô!'n//Ü].‡Gñ¢L+Þ×õìt[æÉ6{;Œ^d Øëfó2 G­ÃIãÄb èQU²PPˆY­&Åi¤à2šÐ<8Mèê«ûÜ{ 0 bÌ>9Ëä°¹¥–‘ÞTT¯X[Érî¼ëèÕž¿¡ráÚýç§ÙË´wn9ÙúñqËÎi“0YÏŽÞV >²U Yi.Aª” ·ÇH& æëv±2ÕâP¦ÒˆR¨&$Œœ½ËÜÉæsCw«Fn:h±‹ IDATÝØ×æó(¿P4w”Ìè=©­ûA­D.M$#iæ §FGsŒý²”ºÜ9Þ8-‹œJÐ@ïrÉc9¬{Œè©€A. nÞ×iS3HóÒb¶ºÖLp WcÌ7BQÌ¥½š2d†–£›ƒÍRé6&ˆTÒtC'CšÜÐ5™µTzÙ¨Á¬GبÄv6£C·zŸÒH¶ŽežSæ,âxj9ÁFƒT…=Yš¡*-„`>mupÖhîðXÓ|•;ÓÝÌÔ3œ¥IóTÖ Ÿ­²¦ÀFóZ\²B³µ÷¹ª¤±Æ¤Z7+¾?Eéw_ùÖCo~ìøèdŠNkÖú*ÅiF£™ÉÕØaðZÜ3•B) ¥…Й]f§Ã$döH7Ÿ§Z6ÂTB2n6YR´2Ïp3ÙZš½ 5I5í%{ƒ”Ín•,@3© o3R{‰‘c¿ Q=·ÂÜ-w¼:ƒ2 S¼•}‘§Ô]õ¢,€+ëÎDÑ’¥»Gt:zÎÞ˜ÁûàboQÅXFv¶,6;}XÔÕ¶´1hŠÆÜ©(¡NOÚd–-MªÒžáœ©zà «õX¡«™vÀ Bw$°v¹ÙfʦхeÆ(hÕ¬VXÔ:ÆØØ …"¹¬ÈfeRq ›iS©´Z’Jà|õ áÓ~w+ÃÜ;í£ÐÍ|¢Š Oß.L‹0&ŠÕ̉Ý-gýl=>õý GôWÛö+_ø·Åÿ­óßxÈìÍ¥žÉ5-À’éé.C©…̵‡FÊ¢´“7\=ÿèý×§ÃýrÜ¢µax ÊH¦¥L YÈ[ª)m`;‘J†+J03ià ˆ%óâf>¿?y-6¤Ô(tÛ£^>êmMWC†úXá ·r·:Ã~¨XE7‚l B ![KkYöÿÑôfÁ¶eW™Þÿ1æZ{ïsÎ=·Ï¼Ù){5©*E'° ËPÊt.üPá7¯¶ ?8܅˶+ÂõPaƒK–¡Jt ,@H‰êRR*• ”Pf*ûöæ¹§Û{¯5çÃóäÛy¸qâÜÓÌ5×ÿÿ}) ሌ”þŸe”h ¤ ZhJFjfs/¢©0&Ū»‰ ƒ $yæ¯ gw§õÕæÜªÙØH+"ÌÎ*òŒLš¨faxs”¦ƒž…r„*5•Áì4:‡–²‘²ì8„LF ‰ * b$]3wןüøïœ¿qáÜm—2\3U¨* ®¤B*D!É>ò®)cMwjx*ŠÂ[×Xô¿žbn;vxRÿîù£'ž{íÖýË·Þ~Í<+2:•eŒLŠ‚ðP$ÃmXh6•,ã0Oðpq¨PÇrëÅý[¯ì4/ªì.v}ötÞ4a¡ÞÈpxFª*AZšYNMp†·ªD! ‘œgÕA‰7ì_™Ì„‚Ìõ–­¯q4á¾DÙ"µÍcJ«ë,eê•@°!Ñ­ ! ôIIîíl§YV=ú÷€ †S Ê­;KãÒÓ€$–EI¤§ ·Ñ:ÐËTÅc63¥J¿" Ì™Pól†dMC„)28†÷·§¤¸Ñ—2¸{É~[² ¼!Ê¢¿úRúxþæ›-k‘ÈÁJ“GP’!‚:×ÖÙ* #*ä ,Ù£l-Ý+P;Hšž·\]’g¿w}‹Ê^óùÒ£Ó9Ñ‘XôNkMÕŒš( 5d?è¤×E;“_ dCt Ò¼ÂD@¦B%¨JWê1:Í7ÙÜEÏAAv¿Ld?£(‰M#EMÑaTHQˆ âE§ÚNÛñž²XÐ=3³#„Ñ}ÏŸ4RØu ¹ÍlÔDß«ÁÜ9Nõ…}û“ÏÜ~妽±­Ú“ßúÜ£á•goìÔÅå›.5\ÿäÿó/}ä‘ë¼våžéÓø'W.\k²9<Á[ßz_e(¢zˆ¯ª´p’h‘)”tJ²Øªó,*Imý¤ÏP'xª_ÆÓôy{ýÁÝ ç._5†‡Ã© éÔ…GexˆHa›f¤0 8m‡Lµ!ýt߯‹Ë‘Q!•ì÷ âÚÞðÚñFSZS YÆe­ u+ª­€ ux$`‰`%„†ÈDOÖȸÐQkµ2ºa–Ò‡'@™sŸ±4 Y(^D³ÁeA†ý‚ÈL¯%˜5¥u‡\Š´LåÜÃ…‘*0Aí_Nf”ÈKRc’4‘ši$2–CñÌbåød³3@µ'^9÷ð£H´x}÷ËԜ߹ùîûßsÏ÷ÜRU]h`XFk¥,Ž77ŠÏ£ž+ËRë,ËòÍGþ¢®uAŸ¼ró…wÚêéÃç6{wÄïôÿúÅú‹¯<ö•ûø?ø‡þÜÓŸþú=ô«×~s³}é•CxwF2ƒÞ‡^t 1Z=zæÏÿðß͇zÿmïڹ͎^ÙB–wÝsóÑáKVÆ'Ÿÿ†¼:ìÞ~Óc÷{Ÿÿã?;ùîS_ûÜvôÊmo½éÙÇúÂ_}ÎŽ®¿ôꋯ\ðÝáÒpðÚë/ò}üÀ­wÜü©?øëÕÅ|ê…g§ÉÝy~\^}ð®—žÿÎáÁs/>ûD®w¿ÿ'ŸzøÓòà{ÿÞí¬ÖÛ!úÝÐÐÈ¡Kå3S±P§)™g$ë…‰ÚW"*Rš5°Ð‚“ùö;o³Ö-À¬ÃR3Ñ*k¤6f:-˜’Õ›QD4<‹d´;Óº“š¢=Û‚²*cK‘Ùf‚hM€a9ŽHxk€Bt³¨ikÝrZ¥ïQè5ºV[Z·;!Êi°Ñ¶žµtWj‰qD¦{$º|*1/tŒ£x´Ìr‰=Û¥(…ݡľd‚ åò…ù¹—¶"Z¨Vl‹:Õ°ÆFM22RÅ2‘Èö“!M%)Ís!pæfŠ¢  B² òDE[W!X”ŒP&ͧyÒåJ"Úý“”¬UKAl 8­'LJ7eoÜ;6Â'Ó¼*ªG IpŒA¾óúSÇϼðý‡oß½:NBÏg&‡'¯l^ºqñܵqÐÅÍwüÀÍ›ÏZ¹°zä/ÿ·o|ñàòî…w½ígnðòÆcí±öúA^Ú;÷¦ ®×§ÿò£ÿút³(á·,ÞÿýÿèžK«‹c»ôün:÷ì ß>··ÚlŸûÖŽ.,¸úýWqipTO«¾ôò‹Â­žœL¯¼þò•‹ŒÓásׯÞ÷ÞŸøéŸù?þç.¾úÉÃÓ7žYË;ød~áÑ/~ÀÎÝWÞö¾÷¿sÞœÜô–ûnºz~5^žb6Ñ’˜)žé‹2fKïZ@93ƒH²àl IoQD¢ai+r®9רm޽‘¥5 £o0µ˜ƒ;«*`’‰’DB­Ó0¼3rd •0í¨{J*"²_\H-2̲iÛI (j6] âhÖáîmë%uíclYΑâdÎa%L #Ú¶Š¤@‘ ¦Ð^NUIEÛ&Ô"Ý\F…¯V­5 ÒQfSLì€[e (—{ãg?ù¯¿òéG÷÷.œ¶y\_þÐÏÿø-÷Üï™Ã°:/êJm-ab­0Ÿ}ñ»y:¼y÷âC‡Ï­oè¹{î¼ï½'ǯ^·;®>üùßûÒ_~}qî".¾õï»ïƒï>~õïûû·ïÆÁ7þô;·\{ð®{îºå¦}÷Pšz;/#÷sŠöس_ü¥Ýÿä™·~àèÆ3û•ï^Ùym¡ïØT»¼Z,/ìf”[nÎc\Üö®ý‘/õ_{é(¸|ÿ÷¼ó÷¿ýúgŸ>wîüþîª^<]ÞØÈí·íì_.ËUÝœ {où§ÿÙo¾ðô«-÷þä=v±`Þùõö[ªȵ§vÛ]{s.°R癎P…j‹3‘I!·sÍ¢‘MT=ZDJЕAµ3sæ¶5¦Ò=wÆÑÕqêÐ_ùå_ªÈi9Œ‰…ޯφ‡t5EÑ¡‚$Ï™ïí-µ»s( öãŠ"™aÐWÖ[ˆÄ4‹¨°ïʪô0šÙ*r bd6 !‚B*!ÈÕ ÷wJaÑTéc¤(y¼mÇSM”d€Ds@š£¶8í¥Å>®b¨aÞ±|î…_|í¾[ïzà½ïxí¥ÚƒoK;W¾þ•?~ô3_›íúCúçv|ýö·=øðç>ñùÏ|æ¹G¾ýúÁuúêÞ[Þ}pá+ŸýØÃo½íÉ_ÿôŸ=ô£oû…÷ýÂ{žyök<þÄþà÷Þvó-“z,Ï=ñòç^}å`žN^›/Üz«(-yä¼éMGŸ{豌¸ÐvÊ­çŸzþ›O}ßßû‘¶;<ù/Muyÿ=wŽ‹•ɰºýòãÏ|îñ/ùÙÛozðßÿȇ¿ùìŸüù'žÜÞxèš^Tµñ-[_Ý)¼z{\¾|÷þbïIÙ_Ý ×rº·½ý§wÞ½øüCøÌ+Ÿ}ïøÞ­‡[²m—»?ösY|᯾ü»_üÃÅWʯý؇>tË;no¹}×û~4^ǰ³·1Í&w\xð¾¼g5pnm‹ˆV½ öo¿å=oò,WCÌž©j‹¥–aÛ¦AÇZ+ÓÃ]~ÅR\M3¤†Â2dÌ3É2x¦(%S„¸¨;"xÎ䤔hÎêT ƒ@03aÛ:¨€•…© ÷åjh£&óœucF86Ì ‘>i6Sç˜s5ØÀ>Ĩ‰9ÇÝ–”dJ’]m‚æ.TfWwÊ+§ DLkÕ¡ Ö|Ý0i-L̽‰hÖŒ7nk¤SAÒŠÀ}¤¼QSíãFU§ð©†‰Å(µ¶®³"9bh!goÒRbÄP=6Á=YeÆ‹{‡Ï¿ü{¿ýo.½ï'ßµ½´ÿä׿í¾óž¿ÿ“ïxç›~ëŸÿóz¢y|C{XÜvÿÝGõò°÷­S)7riyrçþ÷xYÅ¿ùµòÜ£¯?wpeWn¾øæ§Žn¸Èþµ“Ïý‹Ö¶2îý{ïûÙ„é"É4lëå[ß÷ã?}ÿöäDȽåU½4Ö)¬ê›ï}oƒWä)´9}žÖÞ/¦Ù&> ¥µq*Ó!ðlq¸©m"ÔST³³1tTOaŠI‘ê1…Kã0¢÷€(ýÝ‹iá ÀEBm̨ÝUWÆÚ¶Ì¯F¨44ÙTµ9Ø¥V„¦RXQ[ ‰Óm]½†«ûÏ„äºm2v(Hfd’ lÊ7H·W. ¯m¦Q–ð*uZíìnê¶ÖÖ¯ì0ž˜ã —zDÌËL©ÞU­GsLÓ´Ü-È9{B2…tˆn6§7¦©†DÝd iS ¦"I §°¹ŠˆšÃ‰,$D×Ûm^Ý_ÙÁŒÅ8”ea}ýøÂWo»ùé—¿óÔן™Ëqmrº]¾å‡V/>üíÿö¿ú/–çFUyéð•»âvwxýpó€ýÈÿÜêËŸøÂÉ Þqÿxß{_jÕU2íµ'†ÿø?ÿŸ’Ej[õAs»Tlˆ O·Õ¥ ;WÈ”ÍÉ4D:мuñ.³·dz~¤DÔQ åì•°¢ ºdW‡†ÌRTØ2ÅDQOiʾ¼o¨D`ö¾¦ˆºÓ‘ŠÌŠªêÐÑ©È2¯-sNc2è¡€R V© j ¨’Š U¨]¸\^~é°œ¿:œÛ7u§p4¡ÙN¥ ¨¤×tGZ›fz,†U‹ºQÙÓ±g‡;¾ BÈÆY13‚°m‰I§FÓç)[S"„Ñ)àu6ѬaõÊÃþïäòž ‡%g}ûƒ¿ÄÍ—ìpõÀûÞ~zxzá¦Ëeï܇þƒ_ß–'õøâÎ}?ù³÷JA6VßpR…ôíÑ$ZfFQ¢e Ob§’ÔÈfV¦Ïƒ¢)Nd˜™HVeF%­™ÑÌí4ºP:Dxdß-¥ˆe˰d£ø ZqvÐ4 -}—/`DF_¡ÚàÙ( BZd‚6ÕÆ`…1#MÅ«›Ð5HÎÑó¹¢Ì¨N¬ëvXìí_8?žê¯ýê/–¢}‘pRuÔ %<œ™4u–³A÷02¥ò`;•”ýó%Ã…ÞwqÂþã— ×¢­qjHMÓÄÛ,´h-)""ýÞB¶°†î©‡$€PS‰‘Z¸·³³XX‡ø <ýécßžÌÍÓ•j(ô¤HЍI‘H±Öª-c™NH(e8ýî7¾µvù‘ü¡Ý;‡×ÔÚý¾ÿ®wßn¼ðþ÷}ø]?öî|×»0Ĩ{wÜ~ï½ßó`Yíí_¹¼Z®è²¿ØÝÙ9W5WѶµ¥4r(E˜‘bÖke°ðìà1S{ ¡³ØÈ ÌÀ‚TÒ36ªH@8R"=DÒ]™\•"‰¤¸`f`F=*@G z*Šª™fK¨’쎊Jº#Ϻvý<°M—@»˜K„‹.`K ”TFõè™|Í„7f0u¤dCú|ýù‹…ü³O|’C 3™DBµµ4hÍœ2 ‡šSD5Å·)–¢;ÓôÀÝ×lL¡vø¥Ç¤˜P}ýx~üÕÉk…y¶Ì’ó\•F ]-2SstއBÉâ>SÓD”¹¿¿š¡€¨™ØNþÝ×O·Œ@ ­µªé‘’PZÚZ¶­¹Ç\g-«Í<à  “ãë¯,ø·/1ñ¹më™ì@Öªî4°®óθª­eb©ÂLQÍ2œ®OÙ\‡‚DŠ4b9ŒëÍFû¡š"¤Í-­¨RÏVF{ëH²$iŒT–DkîjÚsˆ…•êsÌÞD%½Ç è"!’µöiP0Ïv©g)}EW8‚ ‚6 p§XkîÒÛ¢!e'q#ª@vV E$T)B¸':hJÈbÜN§–,BÏ€@óò¹Å0àúÉñµÆÛn½$Å$2àk±µ7÷Ôœ’!„*:]H²MéÓ„ì[[ŠÜ8]{…×)£fzD "Ý陵í.!æ>yx?{Âe0(‡Ä®JÒ“<¤Ì@#c¾A4f¸¤KΧ§1{w=¦xD͈„\_oçˆd&èá¬a)lP ¦TL4Ï(ýeµµ±í‹ÞÖ.Ÿ¿²WpõVëzNÏ¡0„™-TLŠö)K)C¨¸°»“SŶÓZÄJ)šf[fæv[’ *TÀ ÈÔXÈq‚Ògp ¥ðî/,j…b„hŠT“0“¤y:0S’Z6ýúÜC.M5¬ˆLEÒÔA/†äHÕ R…lÙÐßwH%³¶L°7סØhPªÄ\8+¥ËÑÕ|á±VŠ !Фä¼Y³!3¦ðR-È9rÛæÝÅpÛ¥ó¯æ°oƒÚÖg@êTµk=aÍi;P=C(šÇqª‘ó\ÝX·e,ež;Z£ìŒÌè³RÍtddT­èP¢nČђR"«à„µí´!«ÓÚ<²0‘l6:(Ü”²Z¬vätç æY«‡#¦ZÉVEÄ3-Ò2ÉŒ®¨,J’%=fÑLAõ¦¡’ÍS'¦9P(Ù’gì“éw»–CÊD ÙêÖH‡‡H´ Ì=k6Q£öFd.sJέ¥;™îM©EûuisZ&äJ.%ÓsA`Sü-Œ½ šÂÒ"½µ…Ií}&É€hfP!ÕL‘eèãE W˜‘0j-fiYjÿÏ*MB,evŽƒHŠ{ÁLD x š¦´iæ0”bŽÔ ÌÛh—|áÕî]¿Y"ª¶:ˆZ)¦¤¤«:ÃZú–"s‹Èfƒ £ ) &N\ž?Ø&¨ÍH¥€z6P¹ziïòRÙ*0ãH-"ÌŒð¹[(¦dBiàvÎHTgMe¿œÅ’1 ÁqÍ“ Ù’p#¥ArÛ„â ·Rg/¦™®-ÛTË0@E ¤“®‚& Ã-‚ŽLæ( ’ý­RÅt(V™=†³|DDˆ'AA4QsGÁEdKÌ‚­k¬£Í‚T5ÍXR… •P¢, «Ì ±FzB3™Nú`MÚáÿ*Z{ëž‘š)>%["'ä!!š’U#…sÍÑĘT0I³…X²ˆŒ’’´œÙ¦Ò—5ÑRDlŒð( 'Lh¸H@Ü3\ÄB9•¡¦7j˘*,£MÞ¶ëçÝc÷âJ6 ×. D©ƒ»l§–"TÖôPsö4¨%Y1›èNÌ|åµãõ&$;d(ÓkÏ“$‚‘£ç-;4Π´¶¥#!b‹‘EM©ƒé¢¸02ÚÔ†"ˆÈXìœÙîÎ’fTÊÐ#¯9¡I…j [š+ªãî²!IXO¨5ZxÇ´… ’"¤˜ z¦›öUF­[I@¨Qt!žÅcÇg_ MTh#R¤ŒÍ´è#ÅRv¦WxÀZU 0!"c†br0AÌÃ3šeˆp&#sŽ­0hŒ EbI…b:FRTLR[À³'lƒ^iƒ çN^ÍÆ^¡g¶l Ï`‚!Œd2US„aQ€>Mt×¾ù'[Êa‚äÊ0ŠD›§ˆukÁhH2ÍV¶wQ²YzM(ÈF+î`°¢Ýx›XDÔí4Œ…e0eõ¡bsËjõüñ¶”Õ8 Ó!ìëKŠ2«»ËÅþrxõ4jH ¤hHWÁg"Ó•²Etw9×fÍe;KÕ&0‚AØ®ç˜f‰>CÊíÕ0gŸKj¯zLŒL`ÚºW2™5|Š:肚+ÑèÚi¡`5û±´6¦Q„`XJ±²LU#cëô·QÑ2ÏÚÃà¼]¿´ö­zJ’"9”æM(‘¡fB‚AI RÁ*¦Á¡ç6µÅ²Èi:(V˜žEÆ~`”h®ÜzeV;ûéý/7:yÈ M8(fâî)©ÔôtVëT‚&;C/F+³˜¶´¢2fFë©+ú Ñ’ì=IoÒ©¡gÀ„©Š@S‹HÉZK«»‹2«jâÅWËri/-²ËæŠhnèR2ÍÂl1äv®:jÖI†âLÅܪx„ðàxi~Ë›.ŸMU‘ ¦7²¤^»¸·ÎõQ“:»HAÀD“Ñ)3¨s(Ú1ª>OKÕåÂ.,‡¥u‹ŽŸiÇa/ŸÞغ[Rû›»‡S¦3§y±&ÉÁ¢›Ö6 %Ã¥E€ÌˆÓš¢‹ùäaµ£%¢™Cz’5½ã#\ZïïU-3“®»+0Šª‹¬§íŽÂ˜F¢˜žÁ¨H÷ErU,•%!t¦XC9$³ˆeD$¦ƒ¥¹§‡iq3uD„S•NÌ Ý-!£ŒQºž3-ª™ÎW§es¥²hsÏ–*B¦§ºcXe†G˜tÀˆ"#EÒUãØš7w'r1¸®µ¶ëCIÙ:E IDAT MîæóÜ‹- Su£Å]¨Õ“¤"hÈôÚÕ‡ K"™r {éÆé-—ÏÑ’G¸0™’‚ÝqqóùØÜ˜5Õ3U:ÀYãìû]T€ÞÔK[Náçåü®%¤ÞR^>^?R%["™–à:¸s`†e`ðÌFQ0Û‹„ÇRá³Kh…“’™a6„Ïf"¨•'‹„ƬS¢ÿ€[Ä0¬áIšjˆxhCÔ¦)¢uF2‚Æ V˜½±(ÈœZÎáJFÂtDË&;Õ‘šHZʨƒ Ó%#´ÞåÏ”í¦F…ŠÚÜ*3ºŸ9]#¥xo`”‘H•& 5Ä(1Mtj1$æ„1 šªNµ)¢‹ªƒÑñæÁ0³;‘ ¢`¤—ÁÂr3Õþ”ÎÚ ¼°sN²š0܃6Ù굘ÇVQjmFkAºHºÏSKAK‘ t l3 ɧ¯Ÿì­vw–TÎêè6´ˆ[÷.î®Nÿæ©‘¢ž’±P6f&ŠÑf_„D¶ôüjQÌÀ–ÞËß6·ùúz*bÙØ²ÚhA©Y”`†Ý Ö‚µ»@DaÊyrI¶„¤64 .RL Þfr€æ))9å 13¥¨Ïm#é ³³P{m-Lh:„C`½ =eŠû@ŠÕÍ6¤ˆi#sÃP1­kWCí1±)L$Òƒ€ è‘ ¢$3en3…Y RÂá–>Ч‰™®Öù£Q¡ Ävk"2Xk³EhBU` HŸõ‡À%%“ˆy[ºµ×$# Úˆ @%€ôÐA a`]“ÃõMÍ%¢Ms&T2:ݧÙàÅsX ó‘ÍÓRå—?²­ë²Øi™o‘jÅÒA¡J1ÉÌÔBBÕšÏä(Ò7D±ˆ@Fé ‹ÔÝ…][Ï%ˆˆèfÃÅh5³‚#%¢Ÿˆ6»ª¦Ìó{‹;.ïì­Ì¬/§AÉæñâÁúpíÍ%Â!trªiT2))§G'ó„¢ÚŸ0ÛÚŸÛÝëÝÖHCj$¬€ŠÌbžwaˆ÷˜<ƒÙj#‰H÷¡*‰ˆ鎤¦XÒ@—*]HÖÿ%e#)&$ÅŒL:¤ØÏô§‚ˆÚý/?E"3"ÕÎ •2;{(ƒ°!ÈþB F­"Úǹ ]Ðì¢&õLE9ÛqP$­E9U¤ }a*½ð‚WcÏ66D1Õårã°C«tR¦Iª Ä[úÙ‰HfËÞ gSw1Üô¦óú¿ùi«« 3­©)ÖÎ,€úYCRMÏúʈ‰*ý#)*d´6.ws³™G‰³d²_my/1`4ÙÅ$§e±Èþ²AÆÜÃâÜr¸yoqßÍ{—Ï‹¡ŸS(PñÀÁéúù¬çÌ][“"4žÎ^ɲì¢áîpiÂhì Q›FéoìÌ\¦r±šÚ³dkJ©Ì‰Št ©“‘)™”2–ˆ é°²Í)^”“Œœ3ÏöTÌ­PÂ8G×cÅ0Zf9Š´6g0)éÞScbÒæ­¨D¼ÁxˆÚ„Æ 0“,Q]T¥ª#OAfs…«¶)en,¶ç1%rŠŠœÙn>¥b)µQ9ÌM-³ÕèÅý&š"(šQŠª™‡Œté©:™pgãoÝ3œ#9»C‘m¦ª 5¨,€¤6ï¿ùµ¹ 1ÚPÑ\@Š!6„Ê4o§®…îŽ"*ù†ƒ™AIJè­ÂK‹˜RfÖë&«‹Ë….LUºÂ=ò¬ÓЗ”þÒÁñõ5 \˜LÞúTše!lQgZ¤j"{Ë,Ã[ŠF¼ŠVŒ± …IaP».®Šdm .¡9›Á°éýNª¶Þ5P.p-È”Ææ…I1í# mÂŒôæ<ذöd P#SAðdJ¸ªÖ¹÷bÄ[F÷&=·4¨ÐƨpÌ¡ÍÁ@ƒ€-% ^#5ˆ„fÔèo¶¢C"Íq”Š2C¢ÍªÅ3%S"æhCYz« p\é™ÃÙ爤  ž’p‡gdšÂ2kïÕ´q°I,¦ʶiðÙö—Öª¦Û°³àvÑu˜"AˆEsda V‚l™0J ¦àhƒGËdQ´Š4ÙLs´q°Éêë[–zùÜRŒ© ïÕw*Kf¦Êªp‡`D¬¬SÌ…LС„wìv²JÊñüÁú¥“Ì@F÷ÅŠiwÇÕ*AÉ,ÆÀ°*1M‡¡ÌR#h\*e» ÊX<-DLñÖf¯éM3W«ÝãõQU@k@¨-¨FfzKˆ*2"šsÁ¾SѪ–!ÃU‡Ð2¢9ÜU‘ˆÔì)õPY[-¦(˜A#½Î)ÅCLé‘ D¶áÝþለ¡‘d%è$Ùnn¼xãŽkw²X™Êޤ(7!È,Ù…ÂT”Kz"k¶%X›C¨CªÒý̯VÖÌiš%D‹¤ffj°¥ÇŒÉœÆaœ ²Ö¨uµ³sâuŠ9¸J[èoü‡¿”ቬ¨›0Qig€FY …ä^"E=Ë(„'-‰ ‹¦{Û6ë‘âˆ<ªØº,Š *rvø°[q@éyP š½Ô1¼Lž­ -Ÿ?ªÏ¼>¬£Í‘dóôHèA.­$›‘¢ì·Ôzv’$BÅIU)̾Tr;»4WI÷þÈ ì*'mÍ(µcBƒô§ìý@JAÂÛÜæªE@ɜ˰v/4.)â°Î}%1ˆZûk&jztADª7ogr¹:^ 4‹þ!ˆHoÁq°2ˆé¨ƒŠ 0^Ü‘¯}êßüÑ¿}èÖ›÷Î_¼bÅ`¥%„l 2MiE"ÁÒß“!lÅ‚Rl¤$ ÈÔPÑté Ð"„ù†drò²Z“ 3Šz²mšªÙ€‹ùðôÚµÛô×åç#€Úhc6f*KIQ0D—’ÙÙïoÎLQ&Â3P22M(¦Mmòv4UG•N¡¡tì„r¦é ÏßèsÒŒÚæÚü›¯nŽkzšHkM;f ÁÄ jA †t À4%(6‡×.šCÌ›uB„¤ê\½H5 $ ¤‹VfM)ÃÒ˜šaU= §ÌéµÕ-àB˜¨iÑŒŒ”VžA¢n+SPI“”ѼV‚TR|t±h€£/qƒ ˆ•FP&M2|Èìu>=ÂÖËQíð¹'þëG·;þñßýÔ§>óŽ;ï~ìñG¾òÕ¯Þ~ùÊÓß~‹Í›îº;U÷vY¡ªc!T › ¤‡‰dT ¡F¥¡Ô³ˆ@GPõG BÕºZ´%C&=+, %÷Ïï\\é²Ð½î]ØoëªìØ|ùÊMúO~ã×¶á!d?¬ÁЉ$SS("br¤3’ð&À6 " IOHŠ ¨©(¾™s®Rìdöy®Ñhʤô½ªbTJ×»ÃÖühÎëkÿîi}2§Ð3¿ó¸wqÆÉ7¾ü§ªzãÆ3¯}ëõ!/ýÔ¯ÿ£¯}þÿî‘§/œß98>Hµ‹—¯<ùô“ËyùܳÿÊúÿ‡ßúØý;¼ç#øæ#ðØã¿ùÙ;®^¾|Ôü{¸ú3ùågþÇÿæð¤ìï\úÑŸùðCõ_Ÿ»À›¯Þt¸}½t©lj ãÌrFŠÊ)¼„2“m³PµD7 7‘–9˜4‰Hdx Øj†—èyZ{˜(!T=<žOÖÛãí4®–ÃñÑùs{'7žß½|ßÖΙ6ZKZµ&ªµVSS¤#u "šŠ$GÍ‚€ªéЇ!ô½݆`ƒe­M4¼fCæ”%æÃ7XгŒG›õîbgôÓIK tÍ\""\Ħiγ÷bfd :½NfŒˆ:ê艄–¾U1gæ +Ì즅@£…I•£Z-„šXÈŒxõ™Ç7×·su¿¶w÷-oºÉŠ5én¥0š°Œ24m2H´92Ë-…V×O>öÌÅ ûW®ÝËzõê¸ôÕéfXŸù“ßyúËO­››ÿ©Ÿzÿ÷þЇþ߯öt½sÓÎìÉ3/<ùÅ?zxÿÍ—ŽOþöý÷¾ýƒüÔ'>ûÍo<ñ¿üwÿâ¿ÿ_ÿË—_»qc>ÔÖŽâõ¯é‹;{o}ÛÛe:½TÆi×—ËaÞL{‹½×^8>:]_àÆ–òÝ×^{O+k)e\¸×u×÷ ÉhÁì§d ª¢%ˆ†¬W‹-°#œLJ‘6‚N¤K’PS¯UçڊԤ̓.Pg”²hÔÓÚ6àæ¥ÅÅUÙçÞE»¾® $C²¡)‹fÆj(ŠÀB¶ØÎͤ¨S‘©Ðñÿ'êý‚µmÏò®ã8ÏóºîçYïûýË—„$¾˜„„*ÈŸ*­P±RÔ)Ö´2tœAu»åè†Ûî¹¥Ö錭R-™–¦@dÖ´€ò'„„|É÷½ïZÏ}_çynÜ+º½Ö¬5³ÖóÜÏuçqü~ÖvÑM!¡„òðu<Î2zÄÊýv³Ë“®d£îŽê÷ÑØ|V­çí«Øûnu˜Uõ‰•7Q^§`u$6WÇ#â›*\™;¢»mh°÷¡®aë4e Ö’e»ºPåöÂøµO|â7?ó… 7‹õóùÀ;ÿäŸÿ¡ûçolOîö‡7Þø\½öÁWŽãÖ÷¯ÿƒø{|Û·÷½óS¿ô?üÄüïù?ù¿øúg?ñ#ÿõoèþÍýµw½ÿ_øWÿÂíɶߞ?_Ÿýsÿè—?ù+ûcúCê~æý‘¿÷ÿ×{Þ÷Ñë[ÞR_Êïþ×þÿý?üƒÛåÉþõ¿úw}ô‡þýågþÆÏ¾hxÙçOüÝ¿÷+Ÿêþ>þ©_þ…_ü_~ýSïúÄ{þÔû7»>ÏüýßÿÝÝôÒû®ïýš÷úm/~ò—þØo¿õéÛcÿûð[¿¹íŸÿ—îßq}ö /|ÓOüæÿñ[×_ÿ ð:ý³ŸùLÝý®´÷SÏ×Ç>þ}ú‰ÿ±_øŸžÔ+ßûmßõî¯úÈoà÷~è/ü¯>ýÚÏñø—ÿÒ¶uíÏoRÿ›ÿÖdKÚ{˜ï(³qÒ•ª-7´ks+`Œ°Uæ~\F>ìÃm¨‘5†ÝöÍ‚·¸™Øuú· ;£›…nC¸¦û}»Ng'X½¸`˜ðËöÅgŸ+âéeT.IÖy‚cÝÌÈ~ܲn„¼+£Ê<é÷Ï}L)ÏDˬY6·\»Ï¸å¹o.BFÊ"E“±mÄ9žÒQ8IP‡Ö‰vQA¹ ˜ÄrßÖ~ #Îxª.J®&‡8ž€eÈãØ¶a4ƒŸàçë@ŒÑîHy#<Üi9xÿú³}qßýßõúâKxöänüÚÏýÖ»ßóuoûáo}ûxùrùü‹/Íýžè£ßqWý×~éïásŸýÕÿó×ÞùÖ»1?ð¶w|öíÐOþå ÷÷†W¿õ?úò‹_ùŽ÷\¾òůºÜÞú¾oýÖ'¯ý“_xxõÛÿ¹Û=žŽ}|ì;?þ±oÚglóÉ|#Ÿ¿ª—/ßðʃ™µÞèq¡©:²±¹˜–aêÊ.0W5.OÕÅ6­gÙmŽîÑЪ"I£ †Ç™»Uƒ,hè%r æ–júxŽ3QŸF ë¶ŸÁ ž×ѬÝöXŒíb¹nè0ZL¬+PvÙÛœ·çô­ÆX¡©Î”ÛìU®t¿lf;¹º ¬æ0k5®ÁÜ‚©dD<¸³`“h £Zg«ÁP×4Ãp h¯¾Ýü2„Øïߨ.×ì:ñLfuæ6¬jÁ´zÎÙ&pm44á£Ãs•Ó¨nÀ†!8 ±5_~õµ·]~îöìKŸýCÿ(|λùä½>÷úë{ïŸú½_|k¿ó[¾ù[­Þö™{û¶ú»?ùwæÿãXïÿ×°öw¼ÿëí—~åÝ~ú©_þù_þ™ßøÁçîß¼^ŸöoüÎï}ÏÛßþ=îOêÿÁë¿ó‡ï~û×üÉ¿øý÷/ÆEuÿìÕïû×àÅ×^xY—õd¼^ë/ý»ÿéÃíÙ³…}àôÃþ¥…·¾ë=+Wg7Ê q·©qË r²îfßÎÄ•#÷Û¼DA«¨=Žã0±ºƒ^:lÚÑy WÆX‡p;`3¨UiCikPnsnŦ÷É“«–ƒVRω1¦£—„é(P²AT®ýmïùjOZÇýóõʰg(k÷Ìnæ×Ë 7°AóP VÖãÖÄ 3Œ†5S>s¤U0ßèžUI§$58ŽT í´üì@µ¥ü5|ß×>¾ík_÷ê·¼û“?úcüÊqÕÝôñ¿øçþêùW^xÛ[ž¼ôÒûª¯ÿÆïüâ—~úoÿll/ýÀ¿ýC/¿÷ýÏ÷?úæïú¾ž¾å3øð¡oþ³ïùÈŸ¸}öá坸ŠìÕµ"âu¼ùú>ýÖ÷|û3O­Œð‡ã¹(!ÛtO…{™ä¡Vƒ²1È gëÙ³Ãçæ–YjQ‡®n3t¥µ»À1•鱎Ú`n¾?ÜhÚŽ,²ÍÉN8®­ÎΣ[ŸñdÀÌî!em‚ñd°¡Í[=,°9öSktš”.‰¥þßùý÷|ÅWñ“?ù?ßöÛ“'×ã(ø”  åÅ ]DýÀˆ’šÛq«¢:EØåP‡›ANë®jê)íu†Õ‚M¦a£ebƒôn(ÍBR23u j!³$:Û¨½ÅäÚIZø{ws{©¢ZdÒEÓKÕ(D` .UVå±›º+%«ÿû~òÇê§ŸÖÅÁuØû>ôÚ·ï÷_^yéwý“?ý¿ýîxe¼÷ŸýøŸññÔϼϷ¼cŒ9í† ³7W{«ec´HYEa‡BËô…/üÎzþüí/¿ÿòD3˜éVÀæ)›Xë°…Š`&—ùô¶xþæ³ëeøàQp™èµ´ÒÂ@æ*“5t2æãá€jeµo„Ñf†iK%FÜ9„R[Á£c­IËõXUƒ<»цgÐ-ë× cìûaä €Q #õ°tÒ–G˜™¡5š+XÀ.mAË4kè¦lÐì¬z‹Òe„ •ùe¬¬P©[\µÒ„i€BÖ›$F¬•ƒ„´¹™óܵ­ã|BkL§Ÿ™“ ’Ö7‘ >-WÕi07+à2òVb%5ªéV©áAu¯]dí›õ²CKv1E%º³r/®+WwµMS †…r©Ú«'é•›u³êË{e¡”Ë…né´€‹âœ9‡qD6 L4Œ ¬Ô™.!ÜÍyÒrÛ‘†‚d^ðƒg?·¡Õ<7J „áu±;óᎠ¨)ù0»q ÃGøÓ»mnŽ^‹dN;W•fÆF¯uª½ÊҨͥlÈ8u7üâ‚É0»=ìÊ’ZÝê²ë8³ëa[X¸·±JµçÚ@Âz„õ¡‚•$Êï &Y)ƒ™h0kãªlÙÚ÷Î6(Ðh3§’j+mþÐu—ŠB@„5Ö¢¥¨,søe0Ì..×ù_{È®çåœÓod¸5dÍ«Ûô(Wš5[q4õXƒ3çåsØÜfLÖGÞ…Å´xîSO^TKU0‹1Ùóä+Ažå²ÍÆ«vµŒívƒ&+bf·²Ü£ØG@~ë„[Çà6ìÌ«4x¿äad@t™yɤ&Uúæ0\ÈAo0œ+—ÑEª‹ð“G/`UùSvƒ6kƒ:»`G­9Ü*ž…™c?ŽîŠmGMc©V·[@ÀÅS€ù¾ö‰K¦Î›kAr/‹psx€(bÕÎ`t®2u»Ycóè¨êÕ"«˜”Gà€9[m0¡´ï{l›j¢ˆi,œ‹YT …€C]%úÅõ8´°¡• ¥#‘½D±ý8°Ý‘²4zqº¹ÑmS.áΧ[Vï«·1¤îÛÃìè°ªýɸ®îd–I¶¦• Ý4Šº_KÝAzx€•fèÞi'ÇaµWªöw^cŽ["àº"m̹šnÖ%µõàžP7²Ü£Ñƒ ¯“-ãf…0žét#p½Üî뱹̸ª½e®W_yGÄb·}ò²£«S ÿâO"¸mfp’‚ºJââX¯\ï¾tµíä IDAT{È^<"BÅîvž9ó¼V™0Ѳá翪ÏIX˜‘j?aÌ ½Î¢‘ǰ“†çÙ¬+dG ΈQ+ChŽÓ,†Yž~4sAû± d†:Ѷ®“Dä’…Ùqp:aG¶]]íÄab[ô±"6ÒÃå1Ê.…‡ CòðE˜¸n÷  ›|Ä ÝÏ%»zsú±lØÍd®Ÿ2·fó®E3&qŸM÷ˆõä: Ê„„KlByÛáqoE7ø¨.>dã8ÒѹcÕ6Ñ&0¯\\5ÝÍ;£ËáÈ‚Ô:›9Æl¢¶¸ßë dìZBÇ:rõe{R½×ðdq¯³ë£u™“J&c>;n3.m7«Ci„Ó6-^ç2‚›ˆ…ºª`«Ði&º÷ÃÕb?î7 JÎF’{Ôéì°3] 7FhUÞßl»8¥óPåN*Ìk—K´¬:ÛÎŽµ_ ¤Á˜UlæÙ5P'(º`8;)ìFX‹>¸Ö£¨j¤tþ7A¦G¡†B©è[Ý„¯çv¬¥± ¡;uꀔÔê,ùvŠöšŒ¥e§´Õ&»bµÒ®¨Z ø…§äeFV±«Ó£oG§bšÏ[¦°Ánæm·1†ëXØ[TEË¢»vq@d·6ãó`-ä*ƒ.×8íæVk(ÃMcT®juŒ†ÕLЭÐf¸›3Ñ–ëÅAiÌUçöhn‰(õ~<<8¯À9#2©A—†:Gï6#ò8$?‹XKZ6‡‡»üŒz%Œ‚‰ç3µ£-ü™yÓÔ°˜ NYónîa.¢3£mÏaŽížÚFð,‚m—èGaÕã‚:«!xÌ&t¸åÊãà61ÌéX¹Ð(C„§Z´:µ¿§Qw˜Š;{·WS`5ÃéZ½º»=|\£³$I˜ÃúXGR(Cöruy '¤mS£:Õ«·ËX¹ÀöbV²ˆBøZµ£ã¼OrÌNÜ‘·•WçpÈm=ÜèÑ(„ÛÓËmߥts¯²CTã 47Üî"29î†Cc\V-3_æ±bFe5à1·+YÌBÌB)õˆà2/›Ý kõ˜j1bÏîÌêV‘Àl©EzÐÜqßæÆ!É,\g<~/ë¬PÈÆ‘nƒ†D-UYŒY+ÝòÊ8ª»VB’»R…–j_y½lgÿËiI²a©ªuDl#¬öô¶S ™Ì$„{Õƒ¤ÅvÉÚ»µ*"®NmÃîWBî ÌÃR:§m+m›½/CwŠ{x-A ³8ýçáj9Cl©Mû´§ís%÷JWÂ,†¯n µÒE«ú$˜ ÍÕ$än\mãêF Ft›à‹ Ó¸†–¦sŒq»_}Æ87{^‰¥«cÇÕµ£Í§Ó‚]Ž6fGoPŸJU‹æ\uæ¹ËÍÜRaeLòr½.gÞßâðš{Ir7µÏ‹K‡œAžŒÇæD»c¯¹¶nhÛ.]MúY 4 r-š›y«qd0Ç0º³@{AÈpøZ;Zƒ©Á^Õ‰˜nnêÛdÖrÝrú©µl5ÆÉÀç&·fÚÎ&¢À“šFÚY…³ ,)Wû9Èê¦Ìr?.1<¢×aÎ3^hf†¥J:óp9ÂÏ9ßtùñpŒ†Nýšù¥PÏÖxi“ùZåIKÀÝÑ9Dua\÷ZÎaЙKag{ ʵÚX3zÏh¸óœW¯j£,ÔÜÆi¥;ß¡ZÚœ¢gËONvL§…¯ä†åñxOÈœ×Ëf¥8ÏŽF€G7Ã-„$$Á(x„èêNµ¹zõÚ‘ûç?{åz„›íÍ«_J=aF O.¥2à^ÖjŽauæ‹î°ÃªèZÕÝeô9È*i„kƒ¨*Ó‚ùÑ­ê"Õ@eìöi"¤TUKð.Û6ƹöW(3í]!³³dP§›¿±ï´IG Ï›—Ó÷^êðsrÐo&ÒY‰®fRÈo½]<ÆÝ¥t¼ŽbØæQBõãës8Vb\.R·ŠÁf•y=œ ’½AZ*y7bñxâ«(UG‘YË‹ð¦[t»1’2Õ —®æeÒÎ"MíÅØªŠ`V!²³’}HÃØYðAUÀ¶îã1G#aµ »§¹=ŒBO§çª¦Áybâ«¶‰ýh6\¢‹÷kéÓ¤–(Hìv¶*¤žƒÏþðÓ¿þÚ[_3Ÿq7ÌÜ^¾Ät™Ö­bd§#g‹áǃ“UÑÖ9¥8n# ÕVn&¹èF[B[á6!ºÆ8퀄8¨s‚e­,ž<ºD ¨‰ªU ×#®(/ ¬1̆%J1ffe7ºž’ x#öU«º*%—ˆÎz|ŒGo¯Á¦ ‰y<ÐѺÙuä9‰áÓifAÃHtI½ºKÕöpŸ‚ÁíÄÕœîÊ;ª³Æq‰ëÅèl¹ÅÜ®Swîq’{dþØ3r—ÜÔ:«Óäpd’×ÂØ»¥J´Hïµ@ ëÓì ês¤ŠÝq«ÊH3ðå²–Á9‡WW·Ïm³i«‘2J|ŒvÅ-{Á`ceVæIHptÝûZ]èý!³3œqyâó9¦·ºi{ÛJ±VJ%ݪW¡;©Ž*BsŒánm™Ý…Gs°™5 §ñP°¸s6Yf¤Ë ö¨¹ZfþešCûÙÌuÛg<ˆF¢ÕyÂõát"Xfãü;ÙÙClb±¸ßæ°1Jf>ެnñøãyF½!GvSeX΄Fõº  «-i&'œ6ŒîGE;³yjV ~ÖªìáÙ%Ü®·0wU§èî"Ø¥RŽ=Í s#ÍÙ¸Œír1í2HȉË6Ìé N).w˜f¬Ú}ÎÊŒi ´™Å lÓÅcÒÈT¿ÌiÃ!:Åãö89S¢ÓÑPα‰àÕa‡ÒNŽ_¯I £¿üÂÝ“'SÒ±꾚÷*§]mÇžæfa~¤8¯t<(â•—·éöŠ^¦f·þ¿»¡Î× Ôg"¡$©š[ø%\³Rô }CzÁ u˜q¸ÁO韺ªk©ÊÍeÚ_&…¢‘Ó'Ï×4ÌbµÖ¡ˆS…icÞçÊèLg„ɇef@ƒ<éO&%!Ô —ÔÝ\8ÉFÝgžÙºD§ Ýûæ<¡;¦;ù'î§{Œq®‚H8Á®qwÉÌ`UV ö1ýL‹¨"ÌYKB“–UîîdjU£y éµÊh(º˜0X³M¶úP±²Ás÷ºVÏV\¼Fw3g…wK{ĉͥ›/vw“Ö’Yø·ûA7aŽ8V•zαê˜svJYª."Ígß""CÃGkÊÑZK6.ÔÃj¦ùE…mtõ`fu˜]‹Ëý¤oÃ,Y¢Ú£*_ /ÝV¼Ðk7w_Ž£q=€ë<{My[Ô¾êáØ_¸ÌìúvÆ)ÏM–G¢nw³6<äÃ3sØvvÀ³Ò}„ƒáuÒœ’!‚BwÔ]ÊŠËÖªJÒQ䪋l'jR]'Ó;‹¦3èØÝ`mcœ©7T…AÆv?½e€Æfå…Ô©«Y¨=å<‹Ý¾Ù„(j½ WÕæG•›ÍaF«*9—XW¯•3,Ân}è:Øh§Œ!Z)ѧû‘ž¾™‘’« ì’ò¾ç˜2YDV¡Rær€Íð6¨ìÌ2äUi#<àMÐÌt,›UÖ»Ë×ZmcNgûÑ×ÝhÏŸKpgb'{RòoÆÓ?_ÕÕJW7Õê\ZQk„›H=†Ã«6óR§Ì-Ïx 3’£©®>{êu¡mÈêdks?›7e¨ùfq‚¬c\GmË,æM]ˆáÐMçãõQ­º¹¹WŽÁloj #;ldÕœeZÓÝ7¢ÑÙtIEÜáÛŸtá®êpƒù¾3õùñe¨Õ~®éé2b’lu5 Ôöä® ÀÉ6+Fv™yU+1Ü"Œ Úh’aÆq±A+t ƒè¸8Å:’Ƭ5Áð‘Ä:v‚ÝÀѵr)Ùê7žÝ¶1‘DÁk™»Fø®î–¹¹º«kD—YM åЪ³Ég¨öÄ»ë…æt“±ä™9bK)lB‡WO·&}ŽÙm¦v´´·Qұ߈èusnæ´Ë]eN÷1GWµ´yößô÷Ž'¼ê–4NüÈ8‹2˜áÑXK8¹`¾ªÌáÂYºñ°ê½n¼¸€¶®>’ù<1L}2*«[>ÇŽ‡9¢æÃYK ¯¢PtƩҀ ¬Ü¬!º«‰a°aÎ>ïç ˜wËŠ¨U‰8¡UMÓQÕç…Ý'íq÷"k’æ§Ói»ÝáÚÁlÆé-÷¬›(’Zgü{lZ ®.$#‚~ÜDóXÒ.B¼šéŒ7÷SnHnFeî>N ¤0]=²eb£íÔÐÃHv¸ØU2€‰ôbŠ;0Í·µï­­ÓûœOÁO6¶$»½ù¼»J¤YßöÊ^Gùõò°n}¬Tgjo9yÒÆ ¶ö£ ·7§EwöQt\Äð2óR·Ðûq\æ…f¢MC+™¾?;ärà€x\˜]ž’YíUTg¤§zŸ´µÁ'ƒe?µqºÜÉ󾆂ðÄxÀuÜÛ»Ù&JcžðØ>š&µòü…$ aY=¥”¼VÃaô³ÊZ™5.<;3ºË,Ê|@ȮΩխ™‚YŒÍVU˜›ds¶aï¾3¨´*±z_¡„é&dËN”à.«/NjѸŽpÕq Ãö£Vc ¸Õ9$»‡¡ Ûö=·KŸ »-:Ç퇲"ìa?ö–GHeä›5Ô0ÇJa™Õmï¶=Wegã$²ß×ë8Ô8bÌ=aàf†uÇÅô”Kf¨×Ÿg)iWx›½‘{´Oëæ#húxÄqJAZIuØÝô3¿­®•>lÊT`u`]ÄBÛiª,H§›Tå„™–Ъè–›ÖÇt@¯Ú½z­ÆKÊ1»×™¹ªºútzâÈ4sA6§ZY ˆ½Üùåò<ŒÄóÒ…ÚÂFŒá\Zê¤Ø4v£RB¹y¢/CµVÁ „±Vf¦uyx«Ið¬ã´ùV—l@^]P »Ü¬,¨KY¹/£™ÃX%„PÞ-@†ƒˆÓO*s0ÄH· ±ZÂÝ0Ã2÷Ì€b—o7ugbáh­û”f4øæÚ§;÷Ÿ½+}Üßß?$´½;¯ëéÍ*íUò±Ö ]íaŒn9¬Yêvw‡­V@gõµIV+œ†>‹µ¥]åªTI«Ûtz\:®âQ ä¦.e‚™jÉ lñ2fZÖua<—‚wi9Êk%K¥ Qtg¢I*À¶ÎUsNuã—y"¢kª–1ѫŒ„Ûž·ìh¨% Þn^«ÌG®œ›K»ànk¿Ÿ×§úÿœ|‘cȈ>œ¢ÅÙ¯­’ι—ëtÖ×Yiv ^+‘Yî* }~¼fNÇagƒÅ¸÷1;üÅ;}éó$ªýËõ–3—ÎŒaçxñì3ãÿ­éÍš-»®ì¼1æ\kïsÎm²ïDf‰¾oˆ– Q,²J Ñr§(‡–ìëÁ¡ð“lÿé͎Ћ,EXQ–ÂÕ±¤‹]‘` °@&2‘™È¾¹y»söÞkÍ9ý°Ó/÷Ü{㜽çãû0^Çý™/ºh4:i.ÜÞØê`àÆ|@…`,A`îF3R$j˜DŒÒä„(p N"¼šåB•„ˆPPÇfºPTM‘ç¦Ú$7RT£Š$‰ªаs¯PÁx Gãî¼îâ¥áèØàÃÝœî&DÓ¦¨æ^+rŽƒN+ISjqÐ@aU¨™.’†RiÁ$™Œ02, ;<÷ÔÃ^ú|±9Ó€سR!. 4wV2Ed m[¦¤átI>þùÙ×2ê^)aDàBFš‰†ŠŒÿ Â’ ¥‘å!’ú) Ò-^(’ÐÍQ(ŠÉÈ®®n HÊ¢ˆˆ.bâ`–œ¦cþ$SŠYÕ¤I¥mÓ,(©ëncÌ›!huôd µB@\£ $ú:ê?3Õ\"’FÈü³«‹;Þ&)±¬,ܑő( abäy‰ÙHêwæ„Öh›%m'4‚°òIÁðaà4GÅT(‚(6î¦Us©Eœ‘3£Â*„Ù °ºñjm–b1feÀ)”$¬¢2j¬)T¤·ÚÐQй†æanPdÛZ„Ã[¤‰•ñ$(êe¬è¸@Ô™‹>õôoŸ=m·¼Œ1':K}ÿüS>ýü®O查¢½Gã¨`Oˆª!2ÁÊêQSUMC”PƒUM‰¦ÆDÔÁ\TUh°Y¶ %QB$À&• %éhgÄxµœ$E͉R DÇ÷è&¢*E¥ºO æÎjš©*^+ š’G„bDß÷B‘f˜ÌØ‚Kw ‚á .<Ü*aZ ‘“Ò=¡&1¨5¬ "™¤&1‹;R÷váÊP !E ‘w²Ç} hSÂBÏ@”‰ ‰;ÃÜ:·ã‹Ítyóê¿óÆ”B¦ xíŽÞùâWî»5¿ýïþîl ¡ ªÀ1„îê5‹ödS&3›6,, ½‹6Ä0d’pÛ‹á‘ÆKTÖ»ÁŸ²†¹&†Ae‚P3$…`„·¨Èøô®>¨4€“,âž²„Gr«>Öú"QB…btFr6m•`NQ=5Ùkv6jLÈ„@ WF¤&i“b¬EÔZÅÌk) `rÊ(# G(UÈ5 x éÛeèí0‡(F‡Uˆ3ÍÑž †’]KíCÇwÞwpyyÊ;ýðãSç6º¼u{±¶¾XÊéÅGï™LÛ.VLÓÉúÆü§ç×ß³ÿÅ“~rý<%‰;œIXT(Å…®àh¦êQ—•)FY%接Í‹¡cn9¶«©"yÊ-ʪâ…W}òÅ…Óg‹ˆxÀa „´:}œn0‰ºÏÎW^¸çÖö?ÿùí¸–¹ËéuÜ?™½üüQÈúßüòwæS…bU =Ñ C^ѹy+ð„Ò¢´I$1™ÅåßÖ6˼ÕÛÆjËâ‚IDAT’»#˜5§JÈ‘iû‡OéÛòßùDÑêÄnFDV /¼t¯7åßÿâÒË¥Yʵֆ¤ªÊˆØ$‚2oÂYé>2¨ ¸X´²~·"FÀ)@ˆ„‡™Óín8R%µOÔ Š2Њ 2ᥪzÄø*¥£^¦Ô‘% $H—j¾áEE¬šh»ha=Øb\ÒÑp7ñÒ‡8,79›Jô’ᕚD’Öuóq QHi v„0„[ÍÂ03È€‹IÛÕÚ”Ân§³ÆˆhT„!vóîÄ‘/>þØÒ¬;·¶öÑÙkç¯b²*šÚ\kE)/<ì䉕7?8}ùR?m³GX Ýî¾ôä½Ú ×6Ö’Óm¤(ÃwD $:CFӇ׬z· ëm “1bq ¤hu,ˆDCXauÒ¤‰¯<ÿðŽÖaë•“ûgKù£óO>º™D”Q̇µ†ˆ²¿m¿òüý—}óŸ_î×=OÚRâ"Ú lQßxí•eÿ¿»²q­4ÓÖ¡2To³4šmQž1Eȸü‡£Âr¯õу»ŸúØÂnÿ£›Ï ¡œ'îßxáØÛ®¯_Þxíéû›}ïì…O.̧’jußáñÚËÇš](ÛgÏÞd£î0!…¡ 9ĉ"5â]Ü%C65Ô»ÍÛ»¿äa4Bà ¹CÒkÏÝ¿c)²@‰n1™.-§­íáÐÊäÆŽfcà VÛĶQ6©¬Ý|íÕGc~þ‹[7†¥YÜ–SÖùàÒÛ—Ÿ9±óˆ~÷7Ÿ_:³>›ÎJÀõÄÊòý/øáON—~û•“÷<òܾ½îŸnq4ÅZPháU)tõÞªç”ÜQcÔÙ0WF·àPŽMfÔp”Nš‰Ž_èµdUó¯£^SgÅ!’9Öp­úHax1‚“¬a½õ=š™æœ$œ 3É9ÅàáºUJ-Ó,ƒ/jm”$’4)ºÊðÑž" ´)õU)‘=‘"Dèr÷›ýb]šVSc%ÄÍ]Z¥Ãé2 ‚(‚Fœ„ES¤ç½g­Þù»÷®Í·kÓ¤ÒÇ÷¬<óÔ‘¿|ýó¯xøž“;Ïœ;{ßtÇÊ ;Þyï³íò‰ÇŽ<õèžËÛÛe^}âȃ®|ðÙ%žYoS*î!VQk{×@%fÞIDÄBCBà’r-IIÁ@q£$a M² a5AŠQ/bH-54% ¢V(!â@„—:odℊF@ê>Ìork:Ù·&ºe5@:z'½ ÂàŒ,y2Xi–&ìe¨=©iÙÓ¦c|lËÌAC¸0¤2´©cÕÀhŒX"€ÜÎvk:ŸN‘´¾¸§¤M’ ¡8€ð$%•zh¶œò;}–%O³çß¿ëøžwÎ]½úñÚkÇ?zÿê-[ÿ»·¯7ÚH]¼püàýÇvîÜ15«g®Þ~ëÔÆúZm5;ê¸ù$µ]_M}ìý•Á,;úò=XŽÿ÷‡Û²åId×î•ýûV~{þ +áH¢Žp„{æÄÞ‡Ûûë 7Nºæ‹šö%¶òƒO®~|fóÑ=+¿vr*Û“å}19ÿÉïo/³yòÈÎG^:yýö¾ù»—yðð}÷~ï37//&H„-Ååk·ž|dùð®•ãGvͦu³³³—ol/†ÏoA×7ܽçҰ臩±µxèÄÑí¼Ýo¼{êZ˜óòÄ}û¿ôÜá;6ó½ë±ÀžœŸzúøþƒI#¿ù»+³…½òÊ6ñ÷ßþøµÇ8úà®íí[k[Ýz÷µ“÷>õÒ=?>söÃßœåÐá§^;ñÁÇŸ®Úôè{¯^Y$›þÑkÜ{ÄÞ<}îW¿¾öÍgÝwbÇÎ\:}v}5 Ý%%u‡îváÕû×®±ÔîTPt2¶ŸxøáYççÝ›?=óòÃÏ<{Ïg7¯ÿøíëNG¨zxÒTKá`ˆÁ$åÉ …•B—eãy G»†ˆ–jªŒõp6)êÃñ¡f5ïQ2ª{¯á"Éë Öi‚:ò—â¦ÌÚ…6îa)+µÂMÉ̽ÉM·( ™—DbŒÕY\U‹:Z!œ1fªâÕd17j’8Q+´¡‹f*w’ãüÎPõ…=ÿÙ×xa÷s‡–W–+ýG^:wùNÙŠ#Íò3/D1¾zt—´IÜÙØx÷üæ'çîlWÞøÒ½OÛó½+SüðüõOOmížçW^8±çPº~îÊC'üîÊÆíÏî<}ïÞž½O—ýÏþò|Ùîï•É×¾õȵõ›ï½sóåg¹¶6ø¢>q`ï}‡§—?ûì[¯ž\ZjoÝwßýüö¥ÅCûw<ú≳7nýüÇg¿|üèSÏúèÔ'K²rìáƒýó·/û7^¹ÿÐ}ò·ïžþðÔÖ ÷>yrö«‹ç><³¶ÚÈÁÙtv`ßé3_P$$’w/?{b½®ÿÍ;Ÿ<±ïgŸ;ðyíÝ_ùþ±lÿéÇï½xüá'Û{c{ãg¿¾1AŒÚȤ˜{` ‚„)8 Ûu80hUº„^‰èÍð:Ô¦i$ä¢7¥¸‡(”ã¸IƈP M:/uX :mEèáD$D ›>ßh´m½™d]ÓMµššŒÔf#UQÝÃ#¦èia26„4ª÷[u˜ºFª€[4¨YFHëØŸ¡zTJ2Oô¡9'¹Õåy$,:HŠS/>“n«jä4Iè”P£]Z¾´1üê×VwM~uùæÅk]SL³N2^îÆì'§¾ØºYvX½5_\Y[Ì·‡ š âµ—¯s¿58²ûÃ;kþþæ=2}ã+'k»õöÛ§_xìáO®om~vçÅçØ»«ùüôéå‡vqџܵúÆ×Ož9wúê%{åù'Ïίÿ‡ç¿|ìȳ¯·Å­ýûö4“æŠ-þú»W¹=YYþÊëýîÚÕŸ¼wáÈŽO¿tïææƒûöߦþëo¿sKÿÕ7Þ{`ù{œúôt÷Øî=/<{üòö­÷~½–LuòÂkOüÍ»¿ WMhè{ÛÝG;øoþòÁ—vß3»ý_þí•WÚµú½÷~ùõÞÿàyéðÎé%™m´¯+Œa-Q¦®!4º»¬Ìr“Z%­6LÕà‰•¤µV‚)å€%mÉÊ$HˆÞ-‰×Ä”HOªäLËdÒ´b!©/Å‹7ñE×´ÍÒlÇ"7‰)4'„-KK/`j«î >„´9As¶RX‹! ÝbÞ´šÚåÂêî)†n2i¶ïô³É”°¥Ì½-<íÌ9š®ëe’¶¶¼W—¦>i°Ø®½Krë·}Õ•UöÅÙ•KÓ3ÓœÚ,,%!Ш8aáMΟ~~#®¤È¢¡,îl¾úü£+»ãf¿øäâVôqq} PÈ•ÜÈP_~þÁë~çwï\üÊ—Ÿ:¿½xkXÇëÿà¡©vç/Þ|õ™Ç/,Ö~öÓ ÏŸ<ºãžÙ[?üàï½úÒ©ë·Ù]ñ«O4}pÏ•=íw~óÉç×^½ïг/ºqñæ)gKKù¿¸Ðo–ý~õ+p²xó¯NM½}á‰ÃSؽò‹÷¿¸pnëØl÷+_¾e¶øôÆ­uãÕGŸyép;+?ùî'Ûó| ™üýo=ôës—úuo(lôë'w_ß¾nÝþÚë_jößþñ™½?º\†Å ÇÚ±¼\J”ç>üÎo¯•ÞeEMLÍDKµji–©Òöï½ûó\ªä%]ê6Ópƒ`¨5!àêSÏ1KÝb´ØJ;î¾³µ9kS­f ],"§\lcèI+­n{kýb-0ˆ”Þ—&²Ö­Wo¬+Ë»vz‰¦u¨ÓÝi±Ch–~ˆ¾_ßÐ2½CîÊÒ´mYÌ·Ñuë[{÷ùìêé?úƒo ™¨—ÿÙ?ý[ŽÔ’/bMBNÒöœ,Û&i™ðê%M¥MÉkS+*ÝtKÏϾyðOX•ÕNx0'aT‘lÔe­­Ðk|ùɣǥÊ_¿ýE@› w©PÛþƒ¿Ìµ;\ùæ×Ÿ;uëú»¿¸¨‘þàÑ}‡V£ÛvÞý½ßzçÊðÆ dõŸÿ?øÚC-íåî³›ÿý?øzšÙ/>¿~îó­µ+›W—ÞxðÐãÏEÝúå™K‹KþòëG¿ýÖon~Þ?¾Ïk_½¿‘îÿþþïÔ›û­<üо nüË?ûè óK9|ß®[—Îî:yt±vå¿ûúýóœ?ÿÝg¼ø@ÃöµVŸ~ñøû_:ó»«Hm¯Þˆj›ú½Xúoÿä•Oo®ýù_]\ÍÉØ|xáæ ÝµXÛœÝ×úDÏ\¼ñƒ_ÝšJA"4IDAFN)0X™[©áÞÛ°tçÿöÿ™¥™)U,%TóFs·¨M"{I˜6Ú4óùTR‹¹Uñ@jœak ³°@Í X©ÑÜÑy4’¤:fÙ¤]·Á 9é$sѹu5Œ:Ó&¨šb¢áQÍ„"˜J,,Ø»vææÿè?_F MÒμ÷â•­f%G¸·è5•i¢¨L¦Î´ƒFÉ„U«‚’§" ¦3  îlÒb#&e¨yDùËØÊ.`¥0já¢HJ¨ƒ$q/Çvï<~|§eüð÷—Ó֘Ę}æþúkOvº¹ññ×_ýÒµ~ã·/%ÉiQyà@ ÷âÖ©Ó×WkúÆ‹9(¾±õÿøñƒ{wV+×¶º{÷øvÝ~ë×—ÚÁŸ¸ïàOß»{ ðùÏ.\ûý‡›üÔQîÙ»ãñC{—V»µwìËÏî]:ðäÑ2ߨ¸}»Ýþä•ã;wÌ®,ÿáGïß—ž|$?ÿØý¿:wñGo~~´ÙûÈóíýú#\šýàw§?øÕµY3õâq‰¥vò‹ß_Û·¾êpþêÆ4Rkˆs77?ùôê?ü/Ÿ[Þ7ûOï}úÑ™›»šÔõ½3J?tµ`¾è®ÞÚð¸¾~ò‰%ëK_Û)f;V2ÑY(Ò‘i7É¢2˜ÊÀÕfêÑ›ÈR3ñÚE…Á§SÖÀÝVC©- Á©¢´)ž»˜˜WóÊIvb9åp H¢A1kÛf(0$lê`ÎY£=*¨¦ã»¬ mw=ˆ”¦ryu>H–(Õ»H «"‡‡£ôhFA¸©8Ð*¼7‚ŽÚdeDzÄPÜs®63Õ<ÒYH•bÔd0µ:ÞïÅã•çî…ï_½~þÂ|%·C©d'ãË/>:ìàüóSÿè›Ï’?ýÅéI“ìY~åÄÁ¥%}û‹³~·þܱ£|é`ëö-ÛñÙï?|õå—¯nÜü«ï\ïÔ™_{ö‰Ãÿô[âúú°víúžGNüô·ðÉÚ²§[ëåÞÃõ±cû?¿~ûOzå©få•7Ž>qÏ[§®žÿbsµ¦×¿toIúö¯/ݾ9$N?¯›ñݳ»Í~e2½Ãí¿ujÏÝœ;uýÎ0ÍÍÐ-²ˆ‰ CëÃââ6ËkGçÐoݼP{ìøßÿæW8ÝþÇÿãÿ¾ÞÕÕvéÎÚíiŠÎ!I’s»«m›RUË¢6A§$ hl søa!‘¼4 =b©†ã:ªÑ(¥v9'ÏÂó‚6ɜϢ«ƒG;V×Ã$ÑkI"™™ÔBp•š2j­‹ F^ôž©NïÀݦ'zI„îÕÕYã‡ìþŽyxªÛqøÐÎ3WO3í2gB¶¡$Šˆ:duÝûâYsŽ r´0±,\$FÜSmÝ ºaЉˆ cDªcZ#"°ãåûµµ«]ÿÁo¶gÑÀC‰R}µÚßûækØúþÏ.´=m»#ûæk'Ì–—n—xû·¿þüãÏ<òÈí–];~øÎiÞÚúϾþôþçžúí¹ÏßúÍšYZiN]¿½þ[¶Ëikkó³Ï·ÏvÜ.¼óáYÓDÄû¿¿º¹°ëeóæµþ—oõåo¿wMÚ]Í3Éõ'ïŸëÜKX,†^ÅYoœ=ßs°í­¡ïëÐýº/1T +Ù¢¥Q¼Ðûn}{®AÁÙèÒÒÎű—þɱ{:ð¿ýÏÿìÚõ;+;f>_[ÎRÍ&)ˆeµLÏÌV#GEp$“l=©0%‰J`ÜÙZûíO¯£”bÅlð®ÔÒml®• š[-¥ëU0¨w‹Á»¹÷ެjÝÚ°…¾ÔŠiIMß[“YÅܽEÉH1¿mÉc*£?¥ßd©¥H€Î„±‚ÓÓrÛÅ0¥¸×©VÌËÒlº(†á””óöºÿñ«/}ã/ðáGÿæÿúw+Gƒ¥ -ˆÊpÔ€f*aî ©5(ÝÚ÷.„‰:(9ÚŒj¨"L9¡be 4šœÞ0訅Ҁ ÆÏ7My„QU«P &+!ÎZC„KÓv«*‰Dq$6]5 „(VÁÚƒ°6ÀPËÉÝÐU‰¥Î^þê KD$4غuáþã‡.]¹™¥¡Ç¼`y2%‡àâªJÌÍI†ºZ0¤aa»R–šfc±5i²!D ¡×& fÕêNQ%kÒžñáùka]笃YwsÎd‹®÷¡ütCÝjk6ºÛ>”Eˆ#M¨â¹¯N¯°ê¬I³æš!3Ô‡¢j’XK¥¨Y¨¨ª ç0$WŒçÅ@…©ïªB° 7Y¥ïGI±ä¢ÍT—òìê?üþ›Êþßþ«-MZÖšÜkéY«Çá½Û²º;ù$ÌÑ&Í"µ1­Í„ªÕÓÌÍÜúTg¢;­’Ri2ÚØAº†R!f£ªˆÅ<«‰¦®7æ°p‘¯pi–'ýࢄèV55÷±ˆZMDÜÆmå”ë`“F!ØÚ*$¦"™É–!")e\]\Ûµ®+wZ !•[Ûbk·¦M ¨ q­5èÉ…I’ …;áÕ„B‘6ËÜg³é›7¾87Çúº˜¸ÔþÎÖ¢ÖRÊŠëv ÓÌÒÕ[ý†uƒ ÛR¼¸DÒÁµmcè Ð1k–#³–›Lj2¤2‹q7Øç E€±Ð*j-[¾'aáÕŠi–Y ‚Å•¹ñ zª×¡†6‰Ï&‰¢µ”&3ÈÁ‚Ôˆ„Á<"‰ŒÄQ,ëÕE(†ªŒ5&3Ksa!)†p0qíöÆÿú¿üOûüÿüÿ™æåÕ•¶vsïú‘´RhC !(Q=c§½Ñ±Aè¢ÙŠÀK/9ÙÐO<É–6pBMÓFÄ#ܳÐm¨²4mcD°ô¥™M¦QB1QOm-àCâá5ÌRO¬2Zdz`€·I#8x?kÛ~ÛÙ4EéDJJô¡¯d()šmX´yR¡%ŠG…¨k­´h–êÅE’ÅÁ>Ü‚ÙQ¬ÂzèHL­ÖD‘ˆð!R«ÞÐÈLt¡ªe|þù?ý—ÿêæbQ†!™ Qá!D©ž‚VÇ2›K™g…(£Hvë5µILRKÔ<Í”D"Ô)—€‹'«¦YµV¯¬°f¢Åj5±€ÉKuöeÑdq‘Eß ÑÔHŒ$)œapzbCèHš)]µÀàyšEÓVËm¤†ƒ >DTIP‡ZÚàû—nG€@ªÃu#û^"çz©C£»¡ Íèæ*(æá¢—¤ð’TŒRj`°V¼…o•^™4%«uÄФ“êÐ *Æp1B¼¯wãÒ”’K´.kƒc§^µn-ÒT¤i8/–„¦¹FU-嬩zgUm¤Ô;¥Y4¡Õ¡„¸æR‡†ÞÚ RdwÌ}£ 0(%jˆ¨°—”^EDÝ™C“»‡Ô¡o¦)…d&˜ôVÌw¥´ƒ«¾bRÇg§XZ™üä'¿4a›òæÆú$ V.y¢¡^,1b-dÖ&",YÍcÈáI%1ùî–¸;ÔæP‡V2-*è¨95QL]Ð6Qw” K)¤ô­Úb0AN"ƒ„@f™ë]MHŒ2u/ã¨*>8eXBÄÊàÕÁ,!",^‘C?t‹þ_~åέµ»vüöÐt¥“ËIEND®B`‚snd-16.1/pix/sceq9.png0000644000076400007640000000215211147553270012672 0ustar bilbil‰PNG  IHDR2&p(çÎ3PLTEÿÿÿðððÀÀÀ   €€€ÐÐÐàààPPP@@@ppp``` 000°°°s¡Ñc pHYs  šœtIME× *3clòzÊIDAThÞíZr¬ „Q•ÿÿÚžNçÚ2W¯aÝ1„TÆ~¯rÖí­M 5—¦îŠ—¦8cbpÆUwÆ;CtnÓÆýÒ]öÖ„”‚MƺuëÖío®–Ö®ú0ëþê>iÙœ9IÛ Ú–ñÕÊ,ìæ?ñpü¬OðjÈ ðÏgXõƒ„IþJ’a±5lãc£*³Ã ”2©Õ<Ï„Ãì[IÿG˜m×njJ«|Pœ1aš›BÄÇÆ cõÝ©q.y`·ïÕÄîA*tçäÖf—_Iîindt¾Ø;Ì ž ‡{X}@ïXÃá>`‘Ž¢w;ï#îá¼bõ“÷>Zdqºû¡oHÌž BÚL»Ò¨ËG{FÎ\rˆ°WQ5I¥·¯MšMÅ0B&êB2©¼ …`jò"$¾Ä¼H¨¹lt`¤S4GÉp4Šëd¨IfD$lÖZ“]ªÙGœñ“ZÂ!ÀVD]%]\†J+…úf˜CÔqðWÞƒ Ê).+Ú]^íýª4*R¬Al3i Ó¥;+MÀ(AR$›æó`eβÕHL¤h(9lMTER)gc‹ò7Ãl¤.é–’r®«á;Ÿ£“ÞKLe¤OŸúB™M¸~:¹LF9HŠdÛתV*ƒ’ÁÖDU$•r¸QX«¤2Qè: srݩȰ>ˆ˜’T–F¥6Ó1LÏ\v‚(Ÿ&(SD¤Ãev+Ãéº<)R™ PÁe)‡Äe¹¨Š¤‹1“Wj¤2QG_þÀÃ<.,þÁ7œ¯››»áÈ–¤œ”y*cjQ{á£s— °iµjsÃÒ™Ëî\&++Ù01á\Ch{‚Ê8lMTEÒEŽqg.j¤r .f. t˜rÂðûåe†mX$)G¦“8=®r˜¥œM8EÓaÕë bñùøNìäÓqDj®˜¢6À0¥yDgÎ!ÀVDU$]äxèTt@Þp9uÜ÷"Æ÷Ý9ùÅŸáØ,dÎéÙ&…@ج˜S5ºG@jÕeª^GŽ…C=}]­žª¢®’.r¨$áUÒ™?l6Èhl¹>d_7M#xZLß®™÷¿ TAì±ú¿•„oH7·+ßÜ}{ËÆu¶\)ó’ç÷˜Ÿîdè4$ÀXñŽçG;Ÿ53œMÙÅZ;ô⻎ÒiýsݺuëÖ­[^9ݼ‚×_Ï»±Ø à—ÆF=ï¶;Ú{ûÇô×ó,6(Ê(ë¯ç=¶;Œ¨ìžÓëyÿÿÓ¹PBá®IEND®B`‚snd-16.1/pix/mixer.png0000644000076400007640000003562011147553267013006 0ustar bilbil‰PNG  IHDR¢¾ügAMA± üa IDATxœíÝ;ŒÇ™èñCyÀÀdt%ÜÀd¶€0à+ÀØDÀ&2tÕ†„­At #Yf -6"ɳ™i`…U¨ÄÀL`@ @“¬ìŒ¼ÁÂÊ4 CÁɹA‰åb½ºººººÿéÌéî꯺ÏéþNuuõÁ×ûZµúQ–RîÝ¿—¥ô!W~xïþ½gä«“ó“åÅe)ÝX˜p,rµ°+!a@Õž1þ–í®i–, €þ¤å‡‡¯êÈQT÷‚ãŽßyãåÁiôÔTØ-¬ÆL‘dšËMWýIËô–,e¼IVT„Usw €îýëµB|øí‡ çÉ»`Ò`·¯ÜL ÷ a@ ¾¬ôøƒccX +€È6HI¶DªVI£yÒÙZxS¾ÐËÔ×Xµ¾`ÆP`@}Xo_¹øW&DS‰V¹¦‘†©LÑH+ó%¬*l¢XZ8ÝšÜx %É„ÏÈ}Í“F"¸°Ó¹ê¹óG† U‘‰âÚi!]4O5L¸†näŽsW]2TèÆtÂÊW4AµD:{Žf\ËòU—  (“(N$¬'ç'\÷P9½chäÕsc¶ÉöNßü“«–)iüü“«€zKyp€æÅ_gWsF¶kêó;×â[µoEë… £+€ØYþŽóµo†Èr&— -ThWrÿV¬nIÿº j$¬¨Ú3Bˆ{÷ïï¦õ0`,€^•Ì¥¾þÛׯßÿ÷w åË]úéõ?ïÝ¿÷ÃMWêù«Ç¿õO¯—Ž âôËÓÿóÓÛzj*£ܺy³P\€Gý‡ó}nº@ÕHXP5VT„U#a@ÕHXP5VT„Uó>8 ÆÁÁÎ~s¿¿0fÐß1´'å2›1sLØc3 /@˜±é²„±m@ÀdfXP¾Xû¿(aÝï/ÂõñM’ï;sÊ\&c /ë›”\f®Ö–ü‘ ÏIª @ dt]PµE-¬ai­Äk\¯ÅnP ¿¿¼õÛhýuöp–ïÛ8KšEãÉ2›.¼q’käÛMe>$@$vÃçñV_:’ÐJœ=ñòåO“Ù¶zíôÈ@™¬4ÌÞtòÏðÆI«‘o]5l:ãKØ–to d_seHXkÎbb3~4míԭ侎_WÍŸ@šà»°œ«À…V즛Ü1Lõ ˜•b²qÂì$¬¬§†ô£º„•ä#€#Ñ%€bj8É2J@úï†~pèìÎk¬"ûœëŶ’÷|]b”{ÐxߤŒW{e9ÎÒìÛÖô?a3/üÁáë°qô¢– @^‹=5rãäÝÝt  ˜ði75Õ5J@ÂS’'Í.Ç9 AdÓ£À=õsW=« Q-™šP#ûýŒºäÓî’œaº j$¬¨Zz—€p_Úm/Ú[ššckXãìŸ=gHOXkN_ˆ-Mͱ€54qö§KªF €ª‘° j$¬¨ +ªæ%àè£ÿ(àäna=ýò´p€“£…õúO®_ÿÉõâ‘âqf¼CVT„U#a@ÕHXP5VTÍ;«îÓO>[;,wçWwÔ룎â|ñ¥~Xê㣻¯½~vþ]æÈžvéÒ÷«–&\ÞÝ0Þy|ñP½Þín\h¢öŽ;Bî¬Ýî†xòõsîJir'ò Ý–oß]<}Ö®´wÜîé¢ìÝê[Ä÷PÎú„|ÿý¥Éy¢VÔïæÏn^ $1MS»|´9êG£¾ã..êïÈ×öν˜j,° ‰™3» «Þ€‡ª|uú•óýÃÛ‡úŸgçgW¯\5Þ¹ôÓKj´³^{ñÏ⑸ò÷ž=j~ N–Æhà”ªïaýÈTS¬´†Ã2-¬£8;?BŸYlÀ½û÷~÷ê‡Bˆ_þ߉™ÿÖÍL}ë·#׋1í¬‹\6ál‡Cýœ»Ì~3¼gõ>:£'€‘øÆ”¼ +„âäüÄxçøƒãY%¼ÿÛ÷|âí8ûÖ¯#Dí]WŸ•‚ë›e-ßÚœb7a4Éè@ Û@øÍõ°A6¯ÞºyëôËÓY¬ºçoÞR¯_|éåO?y ÿ©^ßþÅ¡âùŸ !>ÿâX½nm m¡È®|?EÀ‡„³ÉôôóÓ¯ôÖöî{oËäµráƒo»‡æv#—v;jsÎZþ™Ñze›Þqê{à.ò¦+c#L+6HX„ûý¾üªWå«—|ß9iVáÉ‹«æU!Ä_Ý9úè(¹‘5’jR=ùÓq=9k`%_gg †§©Öãè@x,ý†€&v–!\;¥žÛ·ãwœÍ®lOy@ vu~2'w¥: ­v—…¸tñðòîÆcmjŒøÖù]ò5lרï÷•g«*ÅœÅW¯úë;‹l^=>ùLñ¹gtl®Îƒl^›§ne8A”ÿ¶ Évqñp„}ŸF.¢-<éªszóª$‡';>™wOU<Ù¼úî{?Œ pò§µV”§ÛÖµÕ"¾„ü¬òqÅVïn<îý[†:¥w 0š!õFĘIKçi“Ô5ôYWäÕÌÎ¥Ò곺ðº 4ÐFŽ  7¯¾ð‡ŸýñØÙ“Ue«•Ûí® qò£Ý[¯Ú {°ƒ|{ªcOuéFbÂjw©ÔDß$ñ$÷²¯¹§˜´ßïN¥1Ý@}ÅêSgÕ+ ¾^i]Ä“æÕÓ/OO¿<µ§ŸËÇ\Ý»/­|§Ï¿¨¨ßjRMàt2H„jÙU²ßlZOuéC¶›®¹`Za–s:ó¿š»™ªä[Ìoyu¦ªºïÿû{ùt!ÄÑÇGw_{ýìü;眲yõî›w÷??ýJÖ @œ/Ñœn~Gп¨9‰ «žB©w–Ä(0׺ŒÖÐÉ- œüÕ+WãÈ&Øxv¶ €ÒMΊڤ·°®g/0ûº8¯à/,³æf]Û§Ÿ<¼Ú !öB<Ú:Œuù¢¾O‡ ý¶l}XΘg“ôtríÙ[[Ã1[WCv»ëö›³²Ï½Bôœt™ôôÝ„SÏ«@>·XIþ.á+øF_̘¥ ô0èÅúÖeüé«W`R|½ì9!\¹©3…§Öõ—ÃÖÁõn>±t`­P¶.mMš3J€þçÚÁ·Õy i}p»?Ú’Ì ^ýþ´û´6©ƒl•ÛàѬÀv»ë“ý._üäée„ûÝΊUOÔë¶Ç­Ä™K¯Ù[d^ÞnõÃùY£•²Åì ýáMTܵ‰°#õ7JWHXу˜lUñx÷ÿô?U7‹¶’QHÆùrØn œS÷û @.$¬h^d¶WTÛWå¤òÔY{M_ªòœ)²«þŠdÔý@ Ƈپä[p« ’üñëìw¦^ðNDV´->[}l/v?üß8¾ì…¸,ÄãÝË÷BˆÝƒºÇ‘vTÍï²U‹Y‹—Ï~ˆnLíôn›ç¬‘_~ö.=ù@Î]¼?¨~Ÿ4ßÌÚŤ§¾-1q¦ñí;çJ#2Æ7qqŒéŸL;¥öÕÎnï0®ÿ`!VŒŽ¾Ãje׫8í3åÈ6ÿ±1©æØ²XRÁÊ÷T„CùÑÖQv»ëö¨U;!..>õ3úâá㧯M²[ÛÒD¢ƒYø" +àðxwãñ`PyÂØínègýÏÖÏ(­ÇïC×·ød®¡´¯ã­s/4´kjÖmÂZíHûÕV¹‹‹GvcjÆæUˆ®Ï"ÝãŒ8ˆ¾¤Î*´þ6*ÕÁnªP3 +y°6gÏýϦÏ(¢ýøa˜À>ÑL `=Îöç¥âwÖ‚¼(#p$ákˆ°ôQì‡ÝËLJê/ÔTçR‘“ÔûÎg³._ðrÒÜ1ÄGîŒ[™<¤6—Ø9kÔÍ™#¾"-&åÝ즾ÔÙXžN­Œ[?,²v#|PW•˜°i“þ§ÊêœY ‘l :'ù–M2F ø´íE"w¾ƒ­ôw¸éû.ç Þ9ÛÒÍnŠáǪÅ7WüˆžunøþuÆù5l±jUY«K@™ìêÀey ¾—WÊH^ÁO¢S/2’\5P€Þ™UþYÿ˜—a*~_s²ÊkõÅÃ,Á9D+Œ=þLêéÁa™Ž0¾?‘E‰D61&d`ÒâÈUÔ¨C‰ùÖ?¸žÝ+@ÿX°ÚÕ&O «ˆkb ,e7ÙÚs&Œ07ŒìNÖ+­@²ÕÂfíœ70åŽh{äy“7´RÇÈ ;;/Æï&vâ,4Ç¿½Ïk“¼GŒL7S8½É3J€Þ﯋ŸdÏ9+K /ža®#k‘¶ ‘Åã9Nj˭¥§ k7kñòbÂS'¿½—…Ø !žT³ƒÚ)1ŸÌš/³†+k¤/=}PíĮ̀ݥ‹‡ß×}3Y䯗ßÄKõï oñð}“%e?„¶Øu~%nºЙ:Sœx?¿»ñ˜ÓCƒÒ>{ 7™?ý)}¼»ñ¸â_³\\<´S:]u è»vÙí”·Û]ÏR‡Ÿ†òŒÃ÷l³.¦‹½6¸ôV2T4áââ‘oR®\v4¤§hWµ]u½»Ú+Ñ÷Vê»v ­õàªRsPCïÌÚºAG `†¡N!ƒäƒT³~sGcÇa($¬fpžP9qÀ,CýøÏ‚QÙó??Ü:l£×ã¯ÊÅ»¬Z×ß÷.æ×îÍs‘¿mÖnUéOº O•Ò Ÿµ® , Å˜¥wß{{ë“óhÛÁó“bžUl¥¿O¦úÆr»v¿’1Ç“vk·ªUZXå5äX•<ª’0Jzô?B<øÃï·™ uë 5¤šnFÆ4Ô±4 ú°†¾K?ìÚÐ9ºE ë&ac©À$»È ÿçºÔë¹ú&…È,p²²@IœE´ÛÝP;½é½¯WDá#ݾ[%û®ÝBé]ŒËÜ‘W½yÔRöâÎeö¿"_T¾àÕ¼ÔÔÈ}“a ´Ã›¬/°ް¨™ñùä³Ú.5ƒ«÷IWv2ç{3!°ð<µõ7Õ„«W¹¶8±\+7‡Îí}¥ßöÛJáÔJK¤ýí,݉¯Ž±ËÚÚ1‡ßg²þšÒu–ÒÃZ¥5úJ dl‘«H®×ÜEHRkóØ:Ö8/8Ê—­IöâU™^¸vr#T•îd¬]…|ŸL#‡“ï4W;Ãò]Ys¯€˜ƒŒb×ÎȇjË"÷Ýnwc/Äe!.iWµ¬³F5Ô4¦vro^ºx(<µƒT4au^YоR_•%õZ'"lióCd‘mv’Tsf KhÁ2ªVÛ'!aËšÃj)Ü• 5w- ²¡jJKŽ­ÔÔù£Ñ©æ#ÌÚÒoºZÞ±rÖUûý^¦­Éë-ÖtV½–l(æ|0BB}ØÈ˜Q$·"£J L¯`…UsRŸÏV—2ÚƒŠÚ}ŸŽ<°g«ýæ~2‡¥uQV_J£Ã¥~g’±ˆúÓ˜$<­á[©ÂA.lÎ D¨W Œ%F:;?KX åéU µ$ÙPçªüò«2«}´ÚZ Y[ßA_¶Ú„Ë8êEC{0‹ÄVu ¼bL™$žN"}KÙ‰æ¬ÔsnÂÓêå caË~yš½L,Ñßѧ¹ÉÖÇ%m?ë1+°@¥šh¾’ªÝb›´B=Jpð]Vú¦+”wëæ-ûÍ£ŽÊG‚€†ÎýK8„“ò [ATCþ䜓UËÖ ô¶¨m#Á†*üæÒqÕœxÒ°±Ž8½Ö ½âwc[:>x*#Ô1-¬Ènw}ëL¾³cC·`+>³iñ”CÞ†žtüçdAŠ\\<Òÿ¬!õµèôqôiñ$/~dÙ7˜m}bGÖânU1·Þ9'º[2Ò*×tÎYùÄŠ'wémŸb~V5ý ë¸jN$¬Ö2B+^Ç5Bäe¨ÔhçËÎôñùjÔ|—‘°ÛÓ‡š! 踎áç¶7z¾á‡G‚¦?ÆM? ûq$îÁÒ}XÃøçῼðƒ Ú­—áÅ—^Þ:4I?°özÕeñÝ.½ rß ò›*^‹C 5p@`û÷z7Ò°¿K'¬û'ªš5©i½ÖK¹ûæÝ÷ûþÖQ ªþ#²ý`Ìþ޶ ÏžÕw\O nÓâÓ8û{×P ØP¨Ëjj|ïZÙ,M¹F À<Ç'Ÿé~öÇã­"iÑã9ÇšËVb7kñòÂá5÷zC®}ç:Óåpï¨Wx]€ËÊ i.ãüä"×iN‹ßAt2J€ÝCôÀer©I¾¬ql’ úWÝ@ºmHóuØ$è–§/ä¬bÇ5d•>¬5Ü`”œíÅŸ½«ÃªëPš*«ÅîÝr*·J ëÞ²ÆZÖ ¯¼‹¼Ý …:ÑZÐ4vßVâsš.±O›!aݼ=Uf™sÈY*¾ÌÍ7†ÂYÒpülTb—=Õ3Ò>; t `ÜT˜(PNÒoTŠi¤ ,5Y—p™³ªÞP€-²ùÃq…h:¶ü´¹V)½k »ÚjR|ÂX*ðgøŽ«„û±Ò&aX‘cïs¨­—ûmqül]b—®€"ûéMã@?•˜°ÊËÙ Í@ Èxê·ÛÝP'KΚÍ!×éû´ é7]qo;°!ýÄ)s ޹-b¯õߊÒw;±r<8ϨŸþ,VòÔž°7›Ãw°E«<8¨Ónw}ër2F¶¨æõsöcØYý!m +rqñHÿ³òüõ1gÄfö3ÑádY§À~$g­\ÌñÓøÞ±C+G 4Œ#l£x@kÓô¦qý4ÄØeìÁú­2¬•= ­ðYë*¦³ê–£©(c•›®:`md½@‹ÈlzBÇG $º`žÏþx¼u`,‹V½/²IÕhÔ— L² ™\œÇaö0" Œoxö¨Þßäy wß¼[xP-šÌbÒV#aŠÌŸŒyÔRöâÎeºŸ;# ¬+-Œø#/å ôÅYÀ§Ÿµ5o™h&a W4—aé]»קê“Kù&©÷Õ }Ò~¿w®Ë¸†®ÿ(0,&x»(ߦˆ,0><€.%¶°ÊüO§'XÆT=Aô-˜¤.µ«IHb.ô‡ L«²¯œ@xñ[#{ï#°1oû™ÜŒÀ†²u ÐÓµÈ0¾Àå³E:pɸê´h÷O·¼NÜ™t¤ô°V¾4ËnGÌ›‰F ¬t’ÎM6 ô¼¨\é„5œêV8Sök« @…²u Xx…zÖâ› q•e¥i…põ¿ŒÝîºêèf÷xcLo›¾ÅjPU0NUE(/—GάÏYU-2ª¡^1;eÛÆàM¶RàÈܺڎ¢5KLXåõq]Lc¡½T|ú ër^Ð_¼ÝµTá #akл rV´bVÞ™ü¼7>ÿø$`é]|Y”ý~äýX“iY¸äÉuÅ,>7€„Ii[ƒœ@.tÖÐèÙ9ÐV=à2%tŒ„@ºY7îÕ¢!¶rßwÅQ4 +àÆA$Œq+ÇÔè—"û×Y}þ‡:Plò­çP‰„€ö •+$¬¨ +ªVúѬy1¨>fq^>ËÞAÊ^K|ùrÙõæßj®m®6õÜÒT[u3¶†|síHÖ»|œü9œ ÉYf±-æã|ªˆŒ>Û¬PòÃËÆ¬%m‹ÉJ©~–JÚ¾Èró}Š"·›þ5ô=V#2Bç÷zV h;af <ãG?4;Ÿ4«»˜¾ø†O2lë™vòë£_¸‘IÌF3æ©aëÂĶyä‘Qgî2«äð²1‡ýçY|ÆZ|°…%Ï8‡-øÄ|Š–|ÒTT³ÖÒÖq»$º^›Ÿ»ŸN;X·5JNÉ-ƒ^eɽ°¾ã“Ò[XÔëý~¯®Îë/ÔTçRY&Ù‘L.%#t.˜4Y ðT9 !„µUi"AT%±…UfTŠÞ—Tþ©Ï`$^Æ‚Î#'9#Y²TZá*GnÃøÕ›“«1«+*Ã:ÈŽËÚÖê°< ” OJ[QdáËËÃçà&ÎëU©áÃ_€þ(¯Âè`-X(±«}‘:f©kª@!F7ƒp9ed_iB½¶ª;Œ“`¡<}X“ q¾Ì–KáÕ%¬ˆTôŠä0WžV×úh·Ë÷-9 ̲.aõõ5îú&¥…‘=Bc£- } ‘ˆ06´"O k|£]ÖHÑ|­¶¾IöŠ" ´#‰™ŽÐW倴}óc4Mä©#ôTÏ›ÿUÿóÛ÷šÄ÷% žW`]%ÃpšÛûvrþAºóVÒ:ããîž=ÑÄÁ3`„ªŒØ¼.}Û®´W:óÍJ"õ¥Öû8ÉÂI­œ"SøŒdyîÒñÑ£ªª% °R$ØDbº·îp§ÁÀ°85(cî£Â»‘þ¤«v3Ôp…’‘øT €Ö¯PÐ%À@È €qô×9òŒ„£‹ÿò÷wìË¢žÍ²m$“7Q9Ï4Mœ{Œ»ÄêÙã 6¿W¬›ïAã»°y¬Fš“ʦD;¹\Iý¢Í}±QÌzgßpÉ“ÖÊ@à.«ÛãI¶ºÔ÷>]>èaÚýgÙ%&¬“ÉŸÌü³ÍjõŒ,n‘È ÜØ³¡| ®T‹|Hÿ­©ù+–؇ÕαŒkñúÝHƤ@!Âs1Ý^pI„c"œ%mCiþü £ÅWíá ˆÑzwI žýQo÷ß~ÓUdNc6ߟviáF˜XoZ§Õ´ 5‰ìBÔ¶;IDAT€0~ŸtƒEùÞW Cޝ°*>ÃÕJÛ5UíPÍÚ¿£Ž¶!Æ÷Y‹dAh ú›­xe×J»[¦ÝÈ‘EÚÞŸ\ªÌᮆnò7h“àhaÍ~í{¨‹é§_žnÈÌ÷,Ù^ÑÂÚ³«W®Þ> Ìpv~V,PÀVV]o-¬êÑå/ø¦{;ɪúäW *D `)Î4btÙ:»%[lïV«ØêP}¡ŽsØ&üôÕ|ö* £3i[U_dÃïHé„õà‰˜9 ÄÓ ¶jÀù@IµZ?€—NX÷ûýP7éhý0Ûê,ßä¤@— +$—(Œ°•åypöLz½Ô<}X+ý"õ~¿?88PM§ÆõëÈ&U£@ß$}ª\i`Á˜uÙê3èN.¥Ï©Ê DØP •¤,ߢ´Bæ.•ë Ÿ\N‚yëX2òµ œUÂ’™—„ºá·ca™Ù¿’+}öÊìcΘŸ›ìµ… ®wDõÍYò ’V»%?W:læý5›˜°)š‘­ú²·Y¬.a]ú;*¹t¦° õ D8™æêïO®1Œ/OÚWtò)s—r.’¶–¹å Lø•Z}þ%·©ÍÝž‘æUi—€ø6Eßœ.‘…$·h:W±¼}ÔH^ão\Àzê&…&ð‘&­4èÁòb“ͺ^H>m<é*!9Ëu}ÕËñÖ ˆGF­kýHžØÂ*/+kgQ{˪«+¦×z¡W•ï:»ßè ã§ÖÃ>T¦<õE6Ü¿‰ «LR×K³ _ïβ:ûþª\¸úÊ9a¤•K°õl¶ É–¨æ³WIC©|›çiaµG 𵿪™ÃKé‹Ö•+ø˜œ;°”>H‚1`¬}“hyt ò”¨BÉm¢›üôZu½yZXí‘›|í¯‘“ÄÓ5}KÙ™\dncáRñ¦m `C]žlhWتúäWL‹JþØä‡G¥£Ué2K« í.°çïÉ UýŠÈÖ%€&@ MÚˆ§§wU" N‘ƒìvs²Hoa \Î0WÞ›w»ë³Ò>ý ¦Ôßlý¨'ã/_‹Y{¡Ëng«j7ò^Þ#ißèÉ¥Ê(JŽŒÇ‹4z0§KÐÎßP^ÍYàÅÅ#ù/ræ,>\ +€8IzL6<”ðYjù ¬’³ ú¶ÉÏø ?Û‘—×äl …ox a0IÆh6y£¯ü,?.D`=Û~º"SÕlÎ9#¿eölkׄjÄo ÍýFªóàóÌ’…娫K+°°À„•P¦^ÊS·s^¯}o\[gÄFmµ»±*ö©“Ý€:9Ϫ%¬Ù3°¦Sº@Üt½0ŽÍUǯ¼a+löndß•‘:¿¼|®69ÜÙ½q&çYÛ¢„èÞ&c!‰ÓÀ'½«zd€ý¾>Õ˜Á÷~ @{)}ãù ñ¥Ùu™¬—X Êv¾ÃU`[ü’Gaé-¬ò2·/¿4z¦ª™í«“úJ³'9ßq ”™°”³vJ– Õ\§‚øýÖ!8Ä^^yI»v£æïŒÈ5ñ {$ÐåKÎVròÛmðŒë-³Ö§kmtU_¥K@dv%ŸïºF“ ªÀÒò?úìFz÷½··ÁÍî5U`¥Žãúó¨ŒñÔ<ö›KÊL{€ušp±›èû8»Ä¤/ƒç+ëU?¾äbU+¶¯ ôvÕ;}ÙcN«©Å>Û¾u©x&çìX·}X{Íë÷ùÇ·q¸u«¨ùQm`è†:y»¹4\3ZÖÑÆa• ±Ê™è€U€È­Ñ®Án™°Fö›RrÕ[•¿F•á3ò÷?M…ÍÚâÉ¥ÂM ’¼ÁW8—ô.*';ˆßè´jüé+Ðîê3in$ÊtÞ[–¼¡"—B.\AÊ]✓œÙ'6Nçê²£‚ñï¬v5X:J@Ìûú;ÆÔÀ$%<@B&§ßÚï›jÿ®W ˜„ •<úP^'ž4FÏÎ>6ËÚ7±•ßDì”åjûpÖêÔ@V`m\µÙqlþ€¨5ÊöÖ@ÂjÜ4B[ã€U€aœ…ô„vâU5° !öOÛ:œ¬rÍê<Ô•m¥ õÑ×(–bD+û>Dnj®é—Ôeàm$¬|Ú:r­¼æ-$~Û¸ £f:7Hußqàsöæò tÎíØ}ýÂÏžuûà5áÄ ?$¬ÀÓƒìÙÆÌV³ÿTkë·_²Èjªf¼•6K±gÌ®ZþVz­W +€A ’  1Zj@—àï‡`2˜5¬y\Gh¾í¾Ž¨“ºh þm†–ØÂZà¾õ´UlrC}x¥Î§ XŽ3( ‚ÖÕq›»hpõIkö«j{nÕliß,ɰªÒÚ¼ó Ëlí­ö)Ÿ¥YHX!8p ‰ŽÑ,ü}’÷+3÷×Ú¬Âù%ÖŸE7]éÏ»×õ÷Ó&Ù&MX*vàÁ§¾u©y|—øÓ"I[€dä©K°õ ãÀbÒV#íÓs,_:?IÏäÒ–Jæ[—|ú”p¥•ÎH&SÌ@½ÂëÂÚ–¹‰ ÅÓYÎJO߉TÇUë›Üq­|Oçêµ^¨Szºjþ¤2¶ä¥œ‹VãW1ëý%ÈPËX㘛œ^p(Fmêú·y®í_bäÁÉb~Ó¦í¸Y;eîÌõڇŗqRã°¦%¯k¯kyBYr]¥ŽœœØ,:ckp®š«¶-–÷ã=«´˜™kÛ\ÊÜš&<Ô* f©2›Žß1ÚHX‹¥kÎËôë­Ž4´0²„J¬thŽ/¶ªæÕb˜îqQ¸ ›o±¶úŸl˜L—‘RÌÃ+¬ìÈ*MXÓÒÄYKÉÜ4rÕÈÒâ׎ú?y9rapUeùF“?aµ»ŸªL.~’þgÚR“ê·7-,й zmt«ÙPV;µÒß $^ñ“Ò ŒÌù…'„¡rߘ—O€ŽJ¥]€ò8ôÏ¢ºñ±ÝP¿ì¹r¬qmmõÆzxÒàÀ )Qå:îBÍožH$¬€G*A èM§@HX`²; žÃq%@¸é @"r¹ªÚbôœ«;ð!a ®ŸÐu|ÇU5ZO3]V}Jêr‘V^ @Íæ cj¦…µþôë“ÞÑÐT®™V@.ƒ4Ñ©.¡ä£@ëÒ[XKÛª}Q½¿ßïåk½é1°”|­/n/e·bú œ\—>5¦qTEè|'2B»}’³À@½hÓ€kÊY°’ÒÖ@ö¦ROß {);»uhÄN"Ãù¥‘.Lþ"#ÔgĨ×òPÚRWÖå©Xd ¾ÙœwDß¹Œ–]íµÀ”l]²/µ”5-él:Uå­at @'v»ë[‡V±Ê8¬¾ñðÖDûOcþÉÓ–’ëÕ§: ôk ?d5F  “Û¦YÙ*ËŸ°†³·_ƒpž á$Ò—:§à+0wª¬Rm²Ue·»~qñˆœ€^5ù¤«å¹ZB ssâU‘­*2[Ý: °¢Vãò½ˆN×Ònó-•œ#æ :²UFÐ@Â*’2WÕ'W”¶ÔՆ꼚?™‰’­0ˆÖ,×Ù 4sª{¹ц ö>ªä¼ÓÈtIaèR†÷®àÛ÷æ;ï¦/0~)»§%Ké7EŇ¡¿YeHFnêËV¹ €Ö-}pÀÂIúŸY ŒY—½H ŒÈL1¾„ðÚcÖ;fò*ó΄ÔÀ"ä²4 j ôaDDÛ*½Wè-¬¨-¬ˆõâK/o-¬Xäî›wï¾ywë(@ÏhaE¬O?y YO>“ï|öÇc!Äó7omÖbŒ@vyï-!aõvÿ…žÿùáÖ!€®MX'S@cðÿ U’­ÂØ$BÙÈzxû…ã“ÏbšWß}ïm!Ä[¿þM¡øæËòû/ã¶rUaH‹ª0¤ŒEURÆ¢* )cQ†”±(B*\T…!å-j®ºú°î÷ûÒÄì²?6­À2>ÿâX¾Ùêí_Ðà ©+a­D Í«µµ­*Ÿ~ò@ôÒ{4!±K€Ê™TSŸžBíFv¥Ou.eÏ¿ßï}KÅ„:w‘pQÎ0|“Ôû¾ÚùVTg¶I6²Ò¶ ²HLXU©gf*…ufœökãO#ö•à\Ez&ùf Ì\C¶*Yi^U*|ÈV…!‰*£"¤HFEH‘*ŒŠbT’Ø4ªE7]%$OiùÖ’,m½ ¯†Ü±$ýÁ‡0JÈ+Û(ÝgoF·ìП÷û~Ìl5Å8¬3º:ô¯ÿ×þ>f¶·Þx[ˆï׌¦ô(å["æ®ÔnLù"ï¾-¶!ö"¤†$ªŒŠ"U!Ũ0$QeT†”  køÒyà~ã†úÚÚ,õ WÙ˜!r”ûuà¦4€Ž¥'¬ w²ë7ÎÏ]*rÕñÅN.eßÚ¿äæýžF (‰x‘Ô€„U#a@ÕÖ =Ûí®Ë³î‘L[ ÝnwÝy(¨9†w‰„ÝÒs¾C^®¥Ù©ÔÓ~ßw æÞ+º OÆqêââ‘ïÀ·|)ëÙí®ó5S mÕw æÞ1ZXëê•OÎsvþ]H}£q† žtxôTÂS©êÑtðY¼ÿïÿf¼síÚs×®=·I0e4‰]\<"q;†Ò-¬áÇ5†>µ‡ñ¯MåáåâkC=úøÈxçÚµç¾ýö¯$¬âq€]°®o¿ýëÖ!hƒÞQ<ÝQ¶·9ÿÔï°VËœžÓh´+½KÀÁÓ"'Åè|ß7ƒo]êu`’óÏ@xwÁfȾ ë!V#»È›*ì–ý5~Jãn  '*¡T݌Ӹ\aü©¿V¥q¸Ú•˜°Ê ô:=3óM “3ÞWÚSíuÉ×z0«¦}à}a¬± ë!V¿ýö¯‘-¬v7µÉ³N¸g›qs¨³ÿ¾ïÆ,`sò»iŒ^ä<†èI° gíBà@Í1¼cÙºÔÙƒsnTμP¥ËZ?Úƒ9}jëÜ8mñ‹$ ¶€’-¯2ÔFÙmÂs"°? û”˜°Úm~[ådñM1¨…¾ŠæÚM‹‘?‹—ŸiÂG+ßTŽq@7ø:7jrÇ…¯°åÛKoa5r»Y-޹Ø+]ûº¿\c®ÊÒòêD‹Ð¥÷aÍG–µ'DEgø} ã0¿‡Fåïî- ßW?É(Ö·®È›“ì{³&1–µ[FÃÁO†¡Þ™œ´9{¼U'5J€˜9²}ä¨NAKŽª[‘Þňà Шl]V˜ÁÎk³¬ka«NÚý,+Ÿ%ïr'0,g–™ö§Qš [Z6âƒ6énÛ³óïî¼rgíµã,ÃÖ®è½ÓáÑbÆ Iú0bÂjw$Ø0ÄÍ$ŒTÀ˜FLXIj# -`éf ´…µI¸%‚ά ‚„ÛK»ÜO'AÂÚ³³ó³­CXŠ„uP§_ž !nþìfùUÿý¥ò+í"aíÙÕ+We#ë­›·ô÷>:BÞ>¤ ÔQP5ZX;'Y¿:ýJ5²ªæÕMãr{÷þo¶”ðÖoÇÏL +Šzë×óš¨haíŸÞÈZsóªrûŽðžÿù¡âó/Žå P-u¾þü‹c{j©œVÔîùŸÊOö»ï͸v6¡Ÿ¯ÕI|!ZX‡ Y›h^Õéq#[}ô?)˜ðà¿·ß ´¶F"aEôT•Ü€FÉ“øõÿýbYÚJÂ:Š«W®ŠFšWU¶Jª @ä ]5¾&t˜‘°~uúÕÜÒ±-ã¹7v³‰'|þÅñÉŸþþóëåþ— ƒ éýœ·VOŠMX7y†'–Ⱦˎ>>šœçÎ+w²¬K~šeÚêì ê·ÿsÖê—#á@mÞð µq6¦šW•çoÞ2Þyñ¥—…Ÿ~ò o„THžõZ÷é'|§ï„ .ma=;?“ÙÒé—§ ‹š¥ðêj 6u[®]{N&©òÅÜÅ_|éeù±¾ûæÝ¢ùégmu*_"ý¦+=y2ÒÇ[V Y^#÷©lm­J|ïU›þá&[Œæøä³­CHôÙ¨/¼Xš’°ê©ªÌMlï,Onjù€Ü ÓÖõÆ[UôTµÝ¯+ON凷_XRȼ„ÕNUQضiëÝ×^Ÿ»ˆÞ¤ß¼ªšT_øÇ<€ É3»}›J¤ «ÊVIU7'wêQfˆ€;¯ÜÉûäUŸO?yðüÍ[ŸŸ~%<—@+²œÊg$¬W¯\=>9O:T5êçhô^¼‡·[¼k’ü&ÓVFÓG“ºdšÜ¶*Íë G¶’i«Ì™H[ 3RÕ #)ƒ´0 žî6^˜ªJ)7]Ùi+ 'Uµ¿ècD:"ÍW¿Z¹*’>¬•ž¶Èb³Sã0ôªŠŽ¾¢ —ô„U²ÓV†¸ZI÷©ª˜ùXa0ˆ”Qlò.u9C±‡Úwy§‘Ï͟ݪ¾JlÂZ, @£¾¹j_{ö¬€îäüÄxçøƒEÃÊþhÉÂÀÚB-¬G3:b½ðÚ‹©áÜòÎ+ÞÇQ…Ö»¯½> ýY< L ç–iB +÷ß`†+¡‰É¹%}XP5F @N ǰE%¬W¯>›w­ƒ[2`êÑÇGw_{Þ N÷îßË^&-¬ƒºví¹o¿ý«üïÖ±€N<{~5ùéôaÙ*h ë¸ÈV@RÖƒ'²GÓº¶¶ÉµkÏmÀ´Ù}Xöû½ýz‰\å¬W`—ha`%W¯üxržmo¡®?BݼV#Üï÷mµ)–Wóö¡…€­¼ÿïÿ¶uâ#¼ví¹µ“Šü£È-²Såsê…¾ ‘íÅL ‰] ‘—ûÂ0Þ7Ö[a£/-¬¬Ê×ByôñQáH|²D(ïäÎ‘ÛÆ7]í÷{™ÆíŸP“d†§Ó“Qߤ@í©¾0ŒäÕ.!m­‡VЄü-¬›dfÙWjô|ˆ\Ä™³Ö™­ ZX¨’jQÒ[.íVLõŽ~B×çYãD¯Öh¯ÚŽANõUgÖz«Öêàiê}™ :'¥É^ ÐòÔj{úÒ @mä(é*Ÿ“/ŒÿªDÐÈU¹^›”oÕzü*=©µÿ;KÕ ëÞâ›”%gÍX`w§Ñ @…—:gògdº+ äz>qóÖ˜®™ [(c–U¾=³a®&UõÚÞ,ö  …€ÚØÙžjªlå•rÐ=ÔåU˜Ýª_=Ï•„9Ë \¦·'‘Ì r²À˜¥œ‹T˜§*M|èÍ-”Å]ryFqïþ½YË„“°´mn¶7¹–¹Ëúæ·•Ú‰r8ªª´òC €q¨„Ïnd9kë³­w¢—%ûRjçzã« p¬ÿùŒâ7Þyj–óÈ¢Ð6²UV•6ÞjøÞõ§ž5êiî¬;ñÓ"4n¨òÅ '©sŒõìôÞý{? kur~"_pü»W?LÍ¡…€õ¤=ËÊwj6º„úæŸuf_ò´­È³…é©©XcV´‚l€•œwç•;ËËY¯u)W„“²T!*a=;ûfájËWîøž¢:“°È•Ø™§µ,}XP5VT-ôà€kמ+:0÷A²ê¦«;¯ÜñÍJX«zp-Úó,«@žªÐ%ùÝ»/WQ¡V Á³çW÷ꇹJs$¬ß\9ËU:°™°¾zxr~2·”ãŽßyã„Ð¥Œù!}XP5VTí‡.1ƒLÊRº‘%?<øúo_gtÈëÿØ/û©C1IEND®B`‚snd-16.1/pix/fmeq8.png0000644000076400007640000000242211147553267012674 0ustar bilbil‰PNG  IHDRI)2¯3PLTEÿÿÿààà°°°   pppðððPPP€€€@@@000ÐÐÐÀÀÀ``` CY¼ pHYs  šœtIME× (12pØÚrIDATxÚíš‹’£ EA4é&þÿ×.5¼šA‚S™­¦jIíÒ{[®<­ÃØÅewF%(jr!q….EGà~áž Juy†Ó}Nyèb Ԟݗ©µÑÏósàgʧõ³9×Ê9­ADªÆ´ U–ÐÁ“gåh»óÖÆ0Ïì¿HhL ¸²­ù0p÷#í’»ŒR^‘0~ãJÕLë¹ ²5† £Y¿ç¤oYiDpeS‹QÿáLè…F“z=[õÚ8Ì»?X˜ÐPaŠºT\c˜0*Gžò}ËK#Ê€+ëzºé±rûÃe÷×ÅAo¢ÓmÍXØGbGéh…‚Šm &ËÉž'8ï¼û†H#Ê€+ëÚ~Þà“xÚÐE½–uóóiѾ© af2âŸH^{q‡©¸'÷ŠÃ^ÅÂ<»'¶ñq¼D:UŽþ_¢¬kp)Ü®ùø¸Ù©Ç_þ¦‚…¹¨±bˆ‚Šm Jµgý;2NéT9'±²'³ûBørþŠcv«ÙzÈ÷I—³:·í øž;éRi'+¦bĹӰͣîÙ¾!Òˆ2àʦžÍ_{š1:s;Tm×±òÅvw‘0µV “í% *¶1Jm;G@ÖØ¼4¢ ¸²©ù¨ø0Ùýza•ÓêÞò"åðàê8çÃ)êN9Ï’Ê3M¯±{žE"s /W\ÙÕ|›²ö¤à]™ø܉0^yeAÅ5F £‘²å™Ñ³WV:¯ ¸ò|ù­xXÜ‚Å{X­ ¶ùŸ¿yeŽ* q¹'æh¸:ë×Ò%`­¼!LËÙ'8§|^ÿ|1‡Çéå J³ ê¦àzþÚzJy®÷Ä^Á^ªb¤óº·Ùò‰ç„ò/XâæÏ“¾6&óG‘ñ&,ȃâæIÅ~Ûѧ%I>xE }µ]ɇ`}5Ohß¡B… *¿TM ¡ YWÈò„–í,©&ùø‡N@•bA=øØf<6ˆèÇǺÿ`f˜=I(C‘>2€,ÔƒmÆcýqØ‘5µcIÕÁˆnÝ Y4¨ÄǾñØ"›B¬ ›à±q@O>ÖíІ%»Q¥¥ ùØ Äñ±)´=ùXc±›îqw#@ êÁÇ6ã±ÁªpFú>–±%M†@@•‚>æc›ñX¿ôäcÙÆ’*}3a¦âp»Û©P¥xP>¶ è=ùØ »&ùTi1¨pÙØQÐ"ÛŠÇF!ƒõPÐÛŠÇVÝQ³ÿŠJ_ù(h T½ý>>6@AK êuxì÷ñ±ÌGAK7½ëðØoäc M¿B÷øñFñÿBA“B(hf}ý‹(è?ÎoArÆXûIEND®B`‚snd-16.1/pix/fmeq27.png0000644000076400007640000002637111147553267012766 0ustar bilbil‰PNG  IHDR”½YnbKGDÿÿÿ ½§“ pHYs  šœtIME× #:·y` IDATxÚíÝy\MùÿÀñW·E+Qa$[¤ì{"cìÛ2cfì ñ5Æn óýšã;ƾM¶Ôm†Ñ—ôµï„K¶!¥¤R ©pKëýýáç|çóý†¥÷óñðÐ9çžÏçö>çÞwçœÏb Õjµ!„/H%!B! D!Ä›I ©©©Ü¾}û/_|êÔ)$jB!tÈgŸ}ÆáÇŸûÂÝ»wsáÂV¯^Mvv¶²^«Õ’““óÜyyya!þ ùŒˆ’Ìè ^^^¤¦¦>÷…‘‘‘tìØ___òòò(S¦ 7nÜ`Á‚ϼþСC¼÷Þ{¬]»V¢,Ä_ðööÆßß_!J~ù£ììlnܸ““†††Y€££#«W¯~fý!C$ºBñÓ¹…DPPÑÑÑÔ«WôôtÜÝÝÙ´ivvv˜˜˜Hä„B®@þã‡~   €ºuërçÎÊ—/@‹-¨U«fffKä„âܸqƒ]»vaaa§§'ûöíã›o¾¡bÅŠ8;;3nÜ8FŽÉ;ï¼ÃíÛ·Y·nööö/UWVV&LàÁƒDGGãïïO£F”íùùùL›6áÇӨQ#æÎË¡C‡xçwøþûï™2e ¦¦¦ÄÄÄàççGݺuŸ½±±±ÁÎÎîIf12ÂÎΕê?/©P¡fffrä…âåçç£ÑhÈÊÊ@­V³víZÖ­[Ç™3gØ¿?]ºtA­VÓ¾}{Ž=úÒuݽ{—ôôtüýýñññaÅŠ:ÛÓÓÓY¹r%¹¹¹8p€U«Va``Àþýû)W®þþþL›6õë×+û•Š~ III\½zUÎX!D±Q§N:uê¤,›™™Ñ Almm©Q£ðäÎÏÿõêÕÃÜÜü™²âââèÛ·/ .Ô¹X˜?>ŽŽŽØØØÐ´iS ŸÙ·T$7npêÔ)9c…âOÂÂÂ6l˜ÎºªU«2dÈ‚ƒƒÉÌÌüË}$|BQz-_¾WWW.^¼ÈÍ›7iÞ¼9´k׎Aƒ)·Ø$!D1Íáǹ~ý:§OŸ¦J•* <˜† rõêU ÄÔ©S™9s&sæÌaéÒ¥/]—¹¹9!!!ØÛÛ³mÛ6zõêEtt4Û·ogïÞ½hµZ|}}iݺ5ðä¶ÿäÉ“9pàK—.åóÏ?ÇÆÆ†Õ«W3jÔ(¥\ƒ¢wÈ!˜™™‹Ž„Ç'** ///9kE±âåå% K©7npåʪT©BýúõÙ¿?7¦Zµj„……‘ššŠ­­-nnn¯T_TT‘‘‘ðþûï£ÑhHNN¦víÚÄÆÆR¡BÊ•+ÇíÛ·9sæ ŽŽŽÔ«WK—.‡©©)]ºt‘+!„x“jÕªE­ZµtÖõîÝ[g¹M›6z«ÏÉÉ '''eÙÂÂBI5kÖT~®\¹²Î{iÔ¨‘N³ß§d4^!„/E¯W K—.%** €Ó§OÓ¾}{‰°Bü…9sæ””ÄÒ¥KÉÊÊbÆŒ <˜6mÚ°dÉ®_¿Ž³³3ãÇ¥ºvîÜÉÎ;Q©Tüøã:ÛÖ­[Gxx8ööö|õÕW\¸pAyüðüƒwÞy‡³gÏâïïO=”«½^Œ;–E‹±hÑ"š7o.g‡B>>$%%ѯ_?nܸ¡ÿbbb‚™™fffÿuF!„(Í èÛ·/Ë–-£M›6XXX°zõjŒŒŒ(S¦ kÖ¬áÈ‘#DDD`ffÆ•+W8qâÄK×wïÞ=þõ¯Q¦L t7åç瓟Ÿ¯Œ2’ŸŸOnn.&&&‘››‹¹¹9~~~øøø——ÇÓ¶Wò D!^3cccêÖ­ËâÅ‹ùé§Ÿtz¤¿nŽŽŽÔ®]›ï¿ÿžäädÞÿ}‚‚‚8tèð¤»J¥bÇŽ´mÛV#QˆB¼fyyy?~œiÓ¦1kÖ,‚ƒƒßØ{qrrbçÎDDDмys†ΪU«èÑ£—.]bùòå¬_¿žÃ‡B… $ñ&…††#(…>|H»ví˜3gNNN¨T*<==•íÇÇÝÝ]õÖÅÅWW×—®¯B… ôéÓçÉ—¾JŰaÃHIIaäÈ‘dddÌúõëùú믱¶¶&**Š3f0`À\]]Y¿~=³gÏÆÒÒ’éÓ§s÷î]@úñÆDFFrçÎ D)T¾|yvíÚů¿þÊþýûñóó#++‹Ý»wãç燧§'uêÔáÝwßÅÓÓ“N:áèèøÒõYZZ2|øp¾ýö[T*îîîܾ}›ÜÜ\._¾ÌåË—ÉÏÏWF_÷óó#88˜¦M›Ož‹¸¹¹)£õ>}R*z¢÷îÝé‰.Š___/^LDD„C”H¥âÖµk×äH !„žÉ-,!„xC~ûí74 +V¤N:JS]gggªT©Bxx8ééé”/_^¹ô²bcc‰ cÇŽ:Ûòó󉉉ÁÉɉëׯ“ lsuuÅ€ .P¶lYeyˆ.„o@AA£G¦[·n¤¤¤0oÞš4iÂßÿþwŒ‹Í{»rå Ô¨QƒÓ§O“••EPPjµšeË–ñÝwßé? 0@ç !„x¾ØØXlmm±··§qãÆ„‡‡…·nÝàÒ¥K´oߞ˗/¿òäÑÑÑdee <¹­•’’òÌœ$O/Úµk§,ÛÛÛ£R©ppp >>¾h®@„BÎŽ;8rännnLš4‰;w2hÐ *W®Œ““:t`èС„‡‡K``àK×ekk‹V«eøðá\½zµZMrr2!!!tíÚ• péÒ%fÍšÅìÙ³9þ<£G víÚÄÅÅáééÉ•+WPÊ- ëÔ©ÃŒ3¤#¡(V¤#¡(餖BI B!$ˆ×hܸq!^£ôôtZµj…§§'žžžx{{³{÷nZ·nMŸ>}˜:u*ñññtîÜOOOºté¢>>Ìž=€cÇŽZ­ÆÞÞžÌÌLüüü˜2e ýúõ“"„oб±1 4 %%…ÄÄDš7oŽ©©)...ØØØP­Z5š5kðÊã`Á“ñµÌÍÍŸ)+%%…cÇŽ±råJ²³³øê«¯Ðh4¤¦¦0uêTÌÌÌžéð( D)F£L>#žåé鉿¿¿¢”:wî 6|£ÝÝÝÙ¸q#~ø!ãÆcÁ‚8;;ãææÆÄ‰Ù¶m§N¢sçΜ8q‚üQˆx=""" ’@ü;;;I°¥Ø¿þõ/ú÷ïÿF߃••åË—gâĉXYY‘””ÄüùóqsscàÀ¤¥¥1jÔ(š5kÆ÷ßOJJв¯t$Bˆ7`ÅŠ|þùçʲƒƒŸ~ú) 6$""‚!C†0yòd¦OŸÎܹs•Ñr_†¹¹9!!!TªT‰m۶ѯ_?¢££ ¡aÆìß¿ŸJ•*ñå—_ròäI>üðC D`` Ë—/gìØ±”-[–µk×2vìØ¢I ÷ïß'''xòÔßÌÌLÎ!„xŽ÷ß[[[eyæÌ™:t€aÆQµjUV®\Éýû÷Y»v--[¶|éºlmm âúõëLš4‰îÝ»£ÑhðððÀÊÊŠüü|ªW¯Ž““NNNØÛÛ“››ËæÍ›qvv&((ˆøøx¾ùæ:tèP4 dË–-ܸqx2 `›6mä,Bˆç¨Y³¦Îr™2eèÑ£‡Î:WWW½ÕW»vmj×®­,[XX(ã`ý¹ÞÎ;ë,ׯ_Ÿúõë?S¦^ȨQ£”Ÿ_¥Í²Bˆâ¯T<©S§ÑÑÑhµZ ä¨ !Þ¸ýû÷+ L~üñG²²²˜6mðäVÛ¶mY¸p!QQQ¸¸¸0iÒ¤Wªoûöílß¾•J¥3ÔÔ©S•ù›ªV­Ê¬Y³€'-('MšÄðáÃuPìÙ³'}ûö-= ¤råʤ¤¤H¥Jzz:ÉÉɸ¸¸H0Š™´´4&OžÌöíÛ9|ø0#GŽ$33“þýûÓ°aC<<<˜9s&.\ €Aƒ±qãF)3^D||<³fÍb÷îÝlݺ•Ñ£G³fÍœœœðòò"22’íÛ·OæsZ¾|9íÛ·§R¥Jôïߟ:°k×.å97H3^ñ,_¾\é $^Ÿ[·n±{÷n D1åææ†½½=}úôA¥RQ¶lY>ùäêÕ«‡»»;Œ5 ###FÅ«œÞ§O*W®ÌèÑ£)((PÖ{{{chhÈþýûéÕ«óæÍcÀ€ôêÕ GGGºtéBNNûöíã£>’"^ŸÈÈHòóó%Bü?SSSâââ˜8q"=zô [·noôýdffCÆ Ù»w/'Nœ`Ó¦MôêÕKé§Â| ³Ÿ$Á£G¤Ñƒ¯‘™™AAAŒ3†fÍšéŒ/õ&|ýõ×|óÍ7ìÙ³‡   ~øáÞ{ï=îܹ<ë³JÀ“©.·lÙ"â5:qâ¾¾¾Lœ8‘2eÊ‘‘APP×®]ãøñã°nÝ: X·nÝ+×Â;wðõõÅÀÀ€Û·o³cÇ.]ºDÕªU±±±y’T*¶mÛÆ£GØ¿?üôÓO|üñÇÏôí“"„¯™F£aË–-LŸ>ºuëàççÇÞ½{Y¸p!~~~ >œ† âííMË–-8pàK×W­Z5¾ýö[fΜIxx8k×®ÅÀÀ•J…îîîÊk-ZD\\“'OfêÔ©Ô«WCCCÚ¶mûL¹2”‰B¼fÏ\UX[[?³î‹/¾Ð[|ðÎ3ŒJ•*ѳgÏç¾öÏæ <ø¹¯“+!„/E®@„â ÃÁÁnܸÁ½{÷hÕªgΜáþýûØØØÐ¢E ¸zõ*:tÀÄĤÐuÅÄÄ]»vUÖß»wsçÎ)ËÎÎÎÄÄÄ›› @¹råhݺ5û÷ï§  GGGeH½^ÌŸ?_™¢ñäÉ“rv!Äsh4<==yÿý÷•Î{‹/¦ÿþL™2€üü|æÍ›GZZóçÏ'??ŸΜ9ƒ÷îÝ+t}Z­–€€¢¢¢˜;w®’ž&©>øzöìIpp0ü1ôîÝ› &››Ë?ü@LL ëÖ­Sú¤è5|ñŨÕjÔj5nnnr–!ÄsXXX(ÓÅ>5yòd>üðCeyýúõ„‡‡óé§ŸrêÔ)ùüóÏéÒ¥ ÎÎÎŒ=ºÐõ%$$0gÎz÷ƒÎìÕªUãäÉ“dffÒ¹sg5jÄ’%KÈÌÌäûï¿§C‡L˜0J•*ѧOæÍ›§ š+·°„¢{:ÊnPPVVVtìØ€ŒŒ ~ùå6oÞÌâÅ‹Ÿ»¯|øBuÝ»w¼¼<ˆˆˆ`ÕªUøúúpîÜ9êÔ©ƒ¯¯/Ý»w'11‘:uêðøñcæÍ›ÇãÇ©Zµ*+V¬`Ïž=lÚ´‰ï¾û[XB¼µ\\\HNNV”Šâ¥V­Z:è¯Y³†´´4üüüøæ›o”æ¶€òµjÕhß¾ýKÕçää„™™™RÖSwîÜ!,,ŒåË—óøñcêÕ«‡±±1ûöíÃÍÍ KKK4h€J¥zf_I %@JJ =*±ï½R¥Jr…(„:uêвeKeÀÄס]»vlܸ‘(CœÜ¿Ÿ°°0eŽô¿¢×²dÉÆŒØ1cøí·ßälГ­[·¾ÖJŸ¶lÙ¢3¾¾­_¿^æ[o ºtéBhh(¯¥NKKKÊ•+Ǹqã(W®G-Ô•Ž^ŸŒ7N¥ñeÛ* ñ"BCC9xðàsÛÔ Qœ]»v={öÉ'8räááá4jÔˆk×®1tèP&NœÈ´iÓ˜7o«V­"::š;vpþüùBÉÓ~'!!!T¨P Àõë×Ù¶m5bÏž=T®\™™3g°sçNÖ®]«$µ+V`nnޝ¯¯ÎÃ{½&ccãÿ\Ú¨äî˜x=òòò$¢Ä133ÃÕÕWWWÊ–-ËÔ©S `Ô¨QT©R___ÒÒÒP«Õ4kÖŒ[·nѤIš4i¢\-öÊfË–-ÄÄÄP¯^=:wîLff&ýû÷ÇÒÒ•J…ƒƒƒ2îÕ¤I“”ïpGGG¶nÝJBBsçÎÕé7&­°„â ¨^½:Õ«W×Y×¥Kå-Zè,W­Z•ªU«¾T}µjÕ¢V­Zʲ¹¹95jÔxn½O›é>åì쌳³ó3eÊe‚Bˆ—òÖ';vüÏ–Bñ&üãÿàСCÀ“ ŸŽuåéé‰V«eÞ¼yxzz²páBeŸ9sæ°{÷î—ªoÚ´i„……=³~ÕªUxzz2kÖ,àÉ`ŠOßGbb"ÞÞÞxzz²uëÖÒ“@.]ºôLÛe!„x“žNiëããõk×8~ü8ð¤_F@@ׯ_çèÑ£¨Õj8@TTžžž,_¾œßÿý…êKMMÅÓÓ“Õ«W£³íÖ­[lÞ¼µZÍ¥K—¸rå 6lÀÃÃúõë³cÇNž|ˆ•••C(>ùøøðé§Ÿ–ˆ÷\lÈöíÛå zŽÝ»wÓ£G „¥@ll,¶¶¶%fŽžb‘@òóó•ˆBQäää ÕjÉËË#//­VËúõëyÿý÷'CŒ8;;“““CýúõiÓ¦Î>Oo)öŠ÷é¾¹¹¹äå呜œÌ Aƒ¨Q£®®®äääPµjUºw·7yyyäçç+Ï ÉÉÉ¡oß¾ÊðDÅ",^¼˜ˆˆ9£„¥Bff&ãÇÇÝÝ]"ýÁƒ$&&ÒµkWàI¿Î;3~üxºuëFÕªU?~ýôSÆOóæÍqvvfÀ€ìÛ·ØØXzôèAË–-±¶¶VZ…YZZzîHF£ ##3339S„âOÌÍÍY½zõ3ëÿ¼îÏSÜ>oŸÂ¨P¡Â­oÔ¨QŒ5JYߤI“g^¿bÅŠgö×k #>>xò4ÿéÄëâÕ¸¹¹J«V­$BˆbC¯ ä-._¾,ÑÕ“&Mš°|ùr „o™ŒŒ ÒÓÓ©^½:ÙÙÙ8p€FáààÀ©S§HMMÅÖÖWWW=zÄ;w^¸9ïõë×‰ŠŠÂÀÀ€ž={>³ýæÍ›$$$`ccCll¬²þÝwßÅÊÊŠ¤¤$LLLtšK?QäFŽɺuë$BüÁÞ½{2d;wîžô0ß°a—.]âã?æðáÃŒ7ެ¬,þö·¿qìØ1Ž9ÂСCÙ²eË ÕuïÞ=>þøcnݺŊ+ž¹=•‘‘ÁСC‰ŒŒäçŸæþýûdffò믿rëÖ-8p áááEw"Äó4mÚô¹÷O…(ͺuë† §OŸ 11‘_~ù€èèhn޼ɢE‹hß¾=ÖÖÖ$$$0pà@*UªÄŽ;^¨®ÌÌLúôéÃèÑ£9r$cÆŒQ¶=oýéHÀO¥¦¦rúôi\\\pqqÑm]®@„¢155eÖ¬YþÚæ±ß»w/GŽáƒ>`ß¾}Êú¥K—2qâÄÿº¯$!„(,X€ ÇçóÏ?m dÓ¦M¬]»–ï¾ûŽeË–OžaW¨PAg¨I BQLR­Z5ªW¯ÎàÁƒ8wîœÎÿ¯"""‚ÌÌL¥¬G…©©)æææXYYabbÀ±cÇpwwÿŸeÊ3!„xöîÝËš5kHKKC¥Rqÿþ}¢¢¢ðññÁÄÄ„Ž;2bÄ._¾LRRþþþ9rRRR011Ñ™^ö¿±³³ÃÊÊ ///®_¿Ž¿¿?)))ìÞ½›N:1bIJ³³>|8ðdºÝ±cÇ*û²aÃŒyôèýúõ“"„oJ·nÝèÖ­Û_nwppÐy&`ooÏ{ï½÷Âu™™™=·%äÓ4eÊõî60tèP†úÌþr K`nnNvv6ùùù%ê}_¼x‘ P¡B¡Aƒ:p%''óÓO?)ãn?žÆ3hÐ <<<ÈÈÈžôéÓ§OÑ%ÔÔT’’’HJJ"++KÎ!„ø‹/t6lØÀíÛ·ÉÎÎF¥RQ¾|y  eÀ€¨Õjúõëlj'011ÁÊÊŠ¼¼¼ªïÞ½{À† tFò566ÆÚÚZ>00°³³ãÖ­[>|ø™©tõš@¶mÛ†>>>DFF¾Ð¾Íš5ãüùórf !ÞzÖÖÖøûû£R©”éaË”)C·nÝ077W^÷tÊã§ÿ;88жmÛ—ªÓÑÑ33³g¦Q¶µµ¥sçÎ:ënÞ¼I^^ž’<öìÙáC‡hß¾½ÎëôÚ kĈÊÏOGå-¬–-[rúôiš6m*g—¢T8{ö,^^^Åjꋯ¾ú ooovíÚE•*U¨\¹2jµšþóŸ|ýõ×E—@„Bξ}ûÐh4x{{«÷ekkËÖ­[YµjÍ›7'&&†“'O’žžÎñãÇ ÆÃÇèBñÚ¥¥¥Ñ½{wnܸA`` Æ #++‹ÀÀ@¢££ ÄÑÑ‘ñãÇȤI“¨Y³&QQQ„„„pîÜ9:Tèú,,,ø÷¿ÿÍâÅ‹éСnnnDEE1oÞÿüs ‚$ñ*233%o©œœœžý­4‘!X$Q$Î;G³fÍJôï°aÃÂÂÂä` ! D¼NG-ô(ŸÅÕÍ›7å@þÅU·©©©4—"^ETT¿ýö›â-õtn¡+22ZµjÅ•+W$ ’@ÄËHLLÄÊÊŠ³gÏJ0D©S½zuâââ$’@ÄË=z4kÖ¬‘@!$!„’@„xýúõcëÖ­!žC¯ƒ).Z´ˆÈÈHN:E‡$¢D+W®<@QÔ dâĉhµZ† öƹ¬¬,òòò°²²’#-„z¦×[X†††addôÂíÃ]\\ˆŽŽÖëèžééédggS©R%9Òo˜©©©ÞÞÛ¹s'½zõ¢HFX°`Ó¦M+’xÜ¿Ÿ *ȉ!$èCÙ²eyøð¡r#Þ.íÛ·çèÑ£z-3))‰*UªàááApp°ÞßsDD...E3fðÃ?ȉ!$”f)))T®\Y!J¥=z°k×. „$7cóæÍ|òÉ'%6€ûöí£k×®%þD000«?ñŠêö¡R(çΣyóæ%þË×ÎÎŽ”””û;,Y²„I“&É'BÊÕ«W©W¯žBˆxå ªTÔªU‹èèh †(|Xduyyyáïï_d廹¹qòäÉw 4 ‹/–!%+VäîÝ»%æýÆÇÇéœèS§NeÑ¢Eò)xŽãÇÓ¶m[ D!´nÝšS§Né½ÜƒÊ·ß~+A.¦t†2Ù·oAAAÌž=[¹ü}*55•yóæÑ¨Q#X¨žæiiiÿs²™?3òå—_òå—_2bĽürÏK±±±ØÚÚê¥üFŽ @Ÿ>}øç?ÿ‰µµµ^¯þìÚµkz«ãÏW3<ÐÛä@†»wïâè訬‹‹‹ÓëäC<Žvvvz-ûÏ3Þ¹sG¯å§§§ë,?|øPoå?¯Ç||¼^ßÿ{Ñ÷íÛ—™3gê}È wÞyccc dҪ׬lÙ²888üÏ×hÿÐøßËË‹•+W2yòdV®\©óÂ¥K—Ò±cG|}}ùᇰ°°P>hÏ»O¹k×®BÝ.òððÐù’Y²d ùùùz „««+íÚµàÊ•+ìÞ½[¯5jåÊ•`ãÆ$&&ê­ì5jðÑG)ËGŽÑëÄU&&&Œ?^Y^¾|9999z+¿E‹Ê”¶×®]cÇŽz¿õóô‹ìÁƒ¬]»V¯åwïÞ žžÎºuëô{é¯R1yòdeyåÊ•zíOѤI:wî @tt4Û¶mÓëû:t(+VžLoûçï }˜8q"FFFœ:uŠãÇË·úkT§N¶mÛö?›j¿rÉËË###㙂ǎKVVV‘ürùùù\½z•† Iù±±±ØØØP¶lÙ")ÿÂ… 4iÒ¤ÈþÅ‹iÔ¨EV~ãÆ‹¤ì¸¸8Ê–-Kùò勤üpïÞ=jÕªU$åÿþû︸¸`hhXâ΄„ÌÍͱ±±)’ò5 ÉÉÉÔ®]»HÊ¿zõ*µkׯÄĤD~n‹²ü¬¬,âãã©[·n¡÷ùûßÿN«V­þû‹´àíí­MIIÑNš4I¯õððÐ>xð@«Õjµ>>>Ú“'OjǯÕh4ÚÿÅÓÓS[T4vìØ±EVþÒ¥KµçÏŸ/²ò‹26Z­V;räHm^^^‘”ŸŸ¯õòò*²÷¾zõjí©S§Š¬ü‹/j—,YRdå7NûèÑ£yîh9RdåGFFjçÎ[dåO:U{ïÞ½û¹-Êòãââ´_ýµÞËÕy1yòd,XÀâÅ‹166¦ZµjÊ³Ž±cÇÊG}„¹¹¹\ã !DiW³i~~¾6!!¡ÈÊ¿{÷®633³ÈÊ/Ò¿dâããµ%ò äÞ½{…ºÂ}YYYYÚ;wîYù·nÝÒæçç—Ès§¨¯@?~¬MII)²òµ¹¹¹%ús[Ò®@ŒJbÒS©TT­ZµÈÊ×W+­¿R˜Ö Źü¢TT÷ߟ255ÅÔÔ´ÈÊ/êÞß%ùØ–)SFyð^ªT©"ŸÛ×ý]\T·hÑB.ïÞBrlßRÕ«W/ò?žÄ›ann^$ƒ_ê´ÂB!^ûÈÂ… ‰î¶£G²eˉ¶BèѶmÛ˜?>óçÏçܹslÙ²EgöÏ… <éPºpá¿,/00ð…úšé%Ìš5‹=z°dÉ’g¶ÅÆÆrâÄ ?~ÌÞ½{刋b+55•ððp „(1Z´hAïÞ½±´´äÆìÝ»—ÇsâÄ bccùúë¯éÞ½»òݼdÉzôèÁ¬Y³ž)kÆ ØØØ°yóæBý¦—’œœŒ³³ós;fggchhHùòå‹t@:!^Õ²eË ãßÿþ·C”U«V%99™àà`ú÷ïÏÇ)_¾<†††dgg“œœLݺu•a‹222pvv&99ù™²ÒÒÒ¨\¹2¹¹¹… ¤HZa…„„иqcjÔ¨!GX”gΜ!44”7R±bEúöíKýúõ1b6làÆ4iÒ„ž={âããCFFÙÙÙXZZ²víZΟ?Ï©S§ÈËË#<<œš5kâêêJpp0999¼ûî»4oÞœU«V‘ÍèÑ£Y·nk×®e÷îÝdeeѯ_?9¢ÐN:Eûöí±²²ÂÇLJJ•*z߇²}ûvúõë÷Ò-õr2iÒ$¼½½éÕ«sçÎUn888 R© SƤ¢¸±²²ÂÔÔ 100à³Ï>ã³Ï>#--MKÊÊÊŠ0pà@Ôj5¦¦¦Êpã©©©äçç³fÍàIË•J…¹¹9~~~„††²e˾üòK|}}ÉËËÃÌÌŒ‡¢Ñh(S¦ŒñBŒ9r$›6mâƒ> ]»v„……¡R©ppp`Ò¤IŒ3†ž={ЫW/¼½½™4iwïÞeúôéÊ¡>}úðË/¿àè舥¥e¡ê—VXBü¿?ÎËñÇŸï߿ϊ+044ÄÃÃFÞ={P©TüþûïôéÓ‡˜˜âããiÔ¨hµZÚ´iC™2eˆˆˆ`äÈ‘xyy1xð`Nœ8 6¤mÛ¶øøøàèèÈàÁƒå ˆEˆÿïîÝ»ØÙÙ=óóÓ$’žžNÅŠ±´´$11‘ììl¾ýö[Ôj57oÞÄÎέV‹¡¡!)))X[[cnnNnn.VVVJ™ñññäååQ«V-Ž=JBB (²…"D1tüøqÜÝÝߨþB¼Iÿ MÔÚòÀ|.IEND®B`‚snd-16.1/pix/hfft.png0000644000076400007640000011433611147553267012613 0ustar bilbil‰PNG  IHDRÈr¨Ëì\ÀPLTEsssyyqqqqÿÿÿÿùÿõ &(ÿî1þÈ-þ¥ýŒÎÎÍËËÄRRO7T7ÿØÿ½ÿþÿþÿþAÿþ*åôßââÝþeÞ[aaaUUUÿþlÿþWÿþ±ÿÿ ùù÷ÏçþÆ ›ù5ñ ªóª©Ö©XÿÿÏÙÙÕÀƹ´´¬ÕýÔ¿ø¿œ•‡ÿÿÁîîæþþíÿÿÞrrjyg¦gR‚RAAA”î”~É~þþõ«««u,–"tEXtSoftwaregif2png 2.2.4N°ž‰ IDATxÚì]‰zÚº¦ñ‡Ó‚k¼Zl™&pO”Ѓe)IIm¿ÿ[ÝIÞÀÈVÚS5e±,ÿfF³t¾¿Uë|Ü¿}Þ÷Àÿ=þûxPÏû÷ü=§ªOýGíu<4è9K3øK9~½…×<µø2miÆÆ‡- n@ÏFí`c×/úcGÓcN’dça»ü6Ù¶ z^ ¦ø1ÛÕ…O8ç̃ÿŒ nˆˆr ›§«ó]=ÇÉôÉÁu‡\ˆ àÜep ƒSÂHÙód{ÏO_6¡8f^ö,eÎÓcžìsàpž:Ðs Ç,£¤Þó ÅU€£ÅžBž¦}zî÷8åá” q#¥¾`ûôü4c=÷žÂö,ºû<ƒÍ1·?äÃ1‡¾€ðhŠwÐ _Ëžó'zÎŒ¸Nóõ6ëSG„>ƒ)…1ûÀ8°gÍ‘Šžã‚žšh ð/‡[;Pw·“Uã? hÄ]|ĸƒC=fèytÐÌ­5Pœû€ËneçäË1?Ñóâ×¥Ç\GƤÀ“<.i{6i‰Frža@˪¶lІÕì­Þ\JñYá’i = ¡zþ¶H–ÙNNàe±P_:ñžôœ3údÈð`¢„ž‘‹1·¶ïû>)&bŒl îÍŠ1'/}Rh (gpõ¤¼AÏ»ï`¾«gF`¶rÕ-Ò†`"-zÎ_Â7®€ÇqÒgjÐöŒ@¿ßp®‰à]¸}2=ƒÛL°ZÏù¤äýê%Û{ÌÀåL1¼ô<ŠDtìÒncÌе•òÎä×={ή¢³>õ`~ /5Á˜Ã7ٳЕU>𜬠 7ò«Ëytæñ.ˆ¤ŽF¬† ½wäçCÐ =xd@CKII/lFZŒyÝÆ°Ó¼‘>5¥jÌ/àu;Œ²ç¯ #yÂAú¤O?¢H.(m{Ž—»z^-Ÿä†òGÕÊ£®ì¹“½°gáÂÜJCì]i*‘pÄ«ôLQ0§•`  ,RcÞ‰sgž#4x€†«Œ‚3Õó¨P™äüÒ]fœæùþ=‡¨ ‚@'T#Pì µžógŽ9›Ì£ LyQJ<9fÝiŽy2°”°€cŽ÷3qMÃ9O ¨X0r.€üê=2u0Î(.Ò!1(,¨O0Jö =z£€ðá¦LPùEdRÕóbú²ž{c¸c„±µB4õT€öîyûî_‚ˆïúJ])Cìz>IöéYÒN»æ„ŸL2fP© §´¯{Ö©Ó`¢äÅl'“AùƒÈ&Q*–jxŒ§EÏÙ8[ëRtñ#Ö½dœP! 2)bB«ž÷¾ƒY‹ÞAY¡u*Õ¢¿ÉÊ1'Ii„ˆá}ÿ SïyµžmàÀ¢ @Î%çÿ–L AE¦¾,’ý¨.gÔC›‰SàLåF1fÙFëFˆ=éTaø'MҌīž_ø ’ž/@tR­Ð#•8¯^útGȉ$V¦¯Ð£|m¶š<“oxNÈ(äB¨ êKwýéÎÖ´¾}yÝ—{ÁqœŒˆu8æºçlª¨ê$«?ûógS8ŸÍLàKÀš9ïÏl¤A FÕP-‰Éä°1÷‡—÷Âu;ì1߃ž='"|“ó×ôé}ÇÌz!çfwì’Àæ)#j=g#ËŒøÁ6æ¡€!Ü”;®É95¸ê9kªãÖ¡wðòãõ=w…}u˜,5z¼¼ƒ›ÊøZÏ“ýZ†$ãªáƒ[*Úx¾Œ´U=ßù *u°1ÐöÏûH¹Ýóró‡ù¾cæ;9Ò %ólWÏ϶Bì0B`Ïßn ‚॥A"Ú¬ð‰ÊݨfŸ/§Ò ÷V꾚­PG~–â$Yÿmi„ÈŠžµ±C›ÐŒP˜T«TwõUµ•U¢ék5^|C~ê¤YzL ‡¬ ¤% ˜Öle@Ý›ìØ>mìæÓƒZщò‡Nvûl/™LŸ«Û›ÛC§_=äóN²!ò ‚G¾ÃEùZjä@èà!´Ž›ÇaUèd«Îy6zr©¥uÈñJù¥u{׬… Q §2WúÓHÍ´&D^òâ™(ã_0DÈÍH'8%Òd#)‡ ø‹ˆFîÊÏr§ó*C¦Ò†‡#ÔEɺ„0\næ‘£”^5äø|”l•{‹×¼á+Tò+ |GyHptÑäõmµ!5¤Ã\”CD0FM'&gGR![áê°qzªw ”›Èõ¶×A9“èXñ\—¡‚/×bÔhA¹³jÚŒ>ÔG=‹Î·×•ä„cË5dtjVƒ5 çÉ€T¯É!hèεÙp›tô’ÀÖÚãéëòeêMò©…¡=1SeïE”£ ö¢2ðå›ä×N%8›@7]á0T©Rí§aæ"`rÈ’å5g¿Ój™ÍzOŸ…÷÷c¾Û¸&„Ëo ¸iŽ! Ã!Îæ§;¬Ûo޲~³ðqá稔p­¤PE´GL rE'-C¶êKQÙ–Yü•‡|ßú Ô1t„ô-–€Ž8¡þåðÊ‹<€9-†|3ªÉèº.gílm}vRûüº„·ÿ…œy”ÎïÏ8q÷>¹”8éÜ÷ÏÆn83el•—“IGùMh±¾cŽóxõ(<ל3:¢Ë«ô„õîͤºÍúÔï›æÌ ¶ 9Ë[ÖW&uX¯>ä/?¯Æ×3Î{6F19”Ì®®Xêù^˜,송‰Q2åë17è•"Ý£³IÞ&Fæ¯O8D¤cÑw‚/—_ñ‘žS‡EÈž#êŽÇŸ>õ?¹ÇoSLÞóñS!¼`Ä@ªBºpdÄÆèÖíÏç³ñll²![ÏcrÙ Œj*‘‘gÅ' e)dðú§”ïàË{¸N²ÛW@ùÀsË!ß$JŒzÈIéì½ÍUž +ú>díKªy¹ðßrÒX£]w¾¶ŠðÝ·Z/×CF±õW ¬†<8ÄVÛ@Ù²&ÅŸU{­ÿ©­øyÒº¯esµµ:Jým |ð“d9HïÕ’†ï÷ù¢¿ZȽ烛eDÖB¿.àCR*R@§7‰u^‰ÿ2Új³}輤,eÃÀ°8SÎæß’s`Xí'ë,á¸æ–Å"i üžíû ÙŨö³ôëKTï:ðæâ]µ¾¾{M‡œÿ¥©5JGñ[ .òµp@†$ãå2y|üaepF+µPh³ZÚ3 O¬©5M2`e øŒ )YZþhijU÷¢vÒ‹‹âýâ¢1¹ÞÛümy¤^¾P¯ú×å·ÖW?(—§HÊýo¯ðvèÛðãçïäàÐyNdÆÁn¯ÖÓ¿ÿ¾ê?KÇ‹ü_àSþ€›òÏŸóW¼üwBù5[ C>—Œ'/vðÐ|fºÎg ’Wq I0äÁa±:ODþ;|K^Ú9FðC–CÒÏÅzocËçg´¬ð½ùGÙN0™|]æYé£?Ųø/áà!g·rȈò?Oõgr*ã­ýta5b+ƒ¹ÚNo0d´(äÝ g¶úwpNŸç^TsPšêÈκcÝYèÀáå‡ü,}æÅ­ñz”òׯ‹ówòRzÏÞ-ž9ä8[&ZkÏZlyûZ`~N5d´<ì Z¾Û@ÙÚoȓײ™Êý‚“Èã ÷&îT¢1"p»6äŠ/k+¢Õf‡ÜdrWB9Ð#挅C(üªyœ$r„½DùüÆ\žv¢§Ù¦)Õ*·¿òh žã¡ÜJ*ñtÀx¼Úãwþõ®>ä¼c™S-/ì´ðy4‘£]òëp WùÉ!76Í]‹L;À§*̘ 9u¾ ³_mÈF>Š­ s‰Cµ¤{œµ’”™[“ÉÉëÙñ€Åaö*ƒs6኶S8}âZ« ¼pùT´|R9¯N«Œï¹Ñ– äu†|¢žÉÊõ©+d|n:>K1‰œSÒ2’ :Ö Qç ”3‰òÚZÀ*V(g26ûU†|jM0†gGB&Ú¢f·‹#5mÆtàdª† ³ ß2ä‰^æÃt5'2£Ÿ‘áç‚–­· e“¹ÆNY0F†ìD3ZétVœgv Û:äŠcd–1‘´<)×ßæñóL†‰”gb1ä½Ä³Qö ´ í®y…Rˆ 4…Õ馌ỦT¡EH1T£æQ„C¦žíˆÒ}‡<Œ’Ä8̃d7_.4G• *ߘÉóuá“ίÆ"’Ö %¿I%ÊÐŽQ $ÉpÀ­ß‹‡œ­`% (VMo”iˆ‹!³a¾LŠÌpŽ®g©@«xdL®´>äò%ìFÙÚ ižMÚ…OÊB†’œër¸2Lß¶ s·Øòù²tq)ýn²Öv~¾mÈÏó˜ËÜh<Ç$D )_ZÅ• ŽÚõʱŒ¸Ó‰šëú«vlOJÃÿ6”­ç…Ç+ÀL¯”VFÚå-¸(ÚÕ?²uz±ÊÖüy Çåb±øÚØu³H’×5 0XŠé‹1M\•hÅ8äc¥ŠðŠ0V[\‹:ñFÄÃ×ìU%¹<09Ôöà? *?üÂÂEe”â-àZ„ :_enFTÎÓ\e;RÏ.{J?PiA,c–*ƒ¯¢\ñE„FcówLfúºêj—kIWi ­öáSÐHD1ù=‹/O_]Ä÷i ‘3ÐáØE¨–1Õ×Ѧa¿Êìwè™×s=ÎäÓÇ<’JÌÓ´ …¡ŠéUc¹êd¿V]P®qÅ:Ä—¦æj.ÁÇO„r%¥BùCç¤òžkw­_þ|&‡“R+õmÁK?ñbÈÄ@\Ƽê|má!ËÊlv}à‚Žõ’‰ãPÁ G…®òk%ï;äñÜ¡ Üíw¨=Œ”é¥D†OЮ!Ê!ß­ ÙÚ{y絆lKmÏš—=ÁÓÂæ)ÔHϺf(¶ 9[rþÖC¦Ã«}i¿°õŒIEŠª)7˜{hyQ¬¹ÍŽ‘Ué½í\ɹ2‰£õúC¾¼¤Ý~` qR>#YW5©Ôœ÷/¿€¨xá+>ª>–N! ñ¶Œ £ê¤å¹HßðºC>C3‹°#ν«ž PBd`¹ÔÇÍÞe×·¬OT˜^Nöå¼4*[™´‚Ãk–Ãö¬²O¼öòNð鋜…¹ÿs +º_öM_R´¸ gŸÜáœUCþÚ¹Ûäc‚ÎÁ  UùûrËx‹…‡“ÙU4¼êßû³¼ˆ2óìrÈÅГÙB{ŸúŒ‹µ/¢µ7ŒœB»‹Òç^{­#óÙÜÝï]Ï=˜íˆ×7h(†MŸõ†æxÜåÛhÐÜŒ-1 Âx Z&ÌY ]¯ËýËןÎf€k@'Èäü³P ¤já}}È™z¾ðñƒçM—GXjãí¿ûsózvíòX‹áŒg×CÎ‡Žƒ(#fz¡ß5É6”3µˆ°ÂÇÏ’ßè´†÷Äx Âàµ=Gð?p7Ç„±ÎˆäóPfÛ ø¶ [O%V±†?yÛ©Dfw¡„pߌzW—gÜ'ÒÄ ÛÒ¦’èÓ¬÷iØ÷hÛTb囓µõæ³ß}þñúú˵ϻW}—}bÒýX`,(ÈÍb¬àS*ø¾VüìÍ%9©7E&Ú1¸.ò$šRó¥ðМÍg³Ùxì=ä'Å"K ²¥Ä€ ‹:f-åÏP³qR;I§Eðbcy'‹Ÿ5äL»ö= eäIYZšè Ë}‘?V_‰Jj¤t©ºCgwOÛÿ³ÖõÚvÊ»µaÉ {ùìåÕb™ÔW%v´x×jÆ!MMØøyvÜ`ÏoÖ;[ìÖn¬¬šŒ±niq‘Ëù.Êh×q½Ã²¶¡¼{y§5‰ r¶<å“kå¥ðö|,'yÞZ²@®•LÖîåÁhË¿M­_⿜b¬œa ¬ýó~ýJ/ñ:aLö7Âׇ¼_ª!O—§Éê¶í$Îy¶\®ê<ÓC.òJM:oÛVUëÔB‘W;_ß¶hy³èÆÛEŽþÏÊ!—©Ú×ËÀÕWe¦êé´}4­ÿ›6 ò›¶Ä*}Wgò*ôPg5[YR¿åÅòŽrÚŒv_¼ÌÁîé¾?ƒ!_¤VjeyšZ«Øz¯!#Ð)Î0¸ ¸Íj‘ñHè·Íš|Õ¨%ÊFjÝev0yÃ!ì"ú>N¦8ä8¶Œ8M'i:¨†¬Cøuf‡eÇ«ùYn»X{ü~E„ÑšR –-¾ñùb#§ÀΔUŠ€‹‹*©ÀÖŒj×E#§€ 1.ÿþÐÑU~Ÿö£óý¹õÿ¶§Ë@êX•â/ȯÜþWù§ùÐŽ äÓÓüÇÏüô1„gíóçÇÏùãçÇŸŸ`Ó©Ì ñù'ë8=•ù!à€Óüç«&‡x9ÈXôãQr‰øH)@`%Ș[ãçæØ@ä9Ǫ(§Ÿ?cú 8àsþð#?>Jþ®ÞäÛk·¸þåçœø~6’¯|ãʼnAH¾`¼væW¼úðbƒ_àâÏo„‹ÈY®8Ks£( ”c[Ž V²ZæLôa“¼Ü_s8Ì’yc0ù—:àU\d1Œ5"0Ö‹(UŒ_в<—×nTÆÈ·˜ªf"3èX±ìÄJcØ›SK{â!vð}ˆ¦±N€‡`½îñ\»S ýš×nlé$èäHê ×®j×åa†±ÒÞôÁkxÐÆð =BÍ“ÿYþmo×4%'Û[ÚÈhý-Ü“_2]ü‚;¼àHio»dX‚Œçüz¾êdÙò¶Ècl½xÙýÈA^}XNÎï’»ä@FJŽ'–•%£eò¤á¬‘¿· $"Ï6#ŠñBûiSâÀ èŒ÷”9Uîò¢ ÃÈ,üÄèªÝk ã¯,Ë:ï`©xc?·•W äe¯²ä|Ùž‘ûÝAýÐ¾I4~²²!ñ‚ `B Š("‘é@M*…™¨Ì ˆë:ž°ˆ4P.@þÐ鬬ë`dù[Q²y°…'¿;È„zf4ì"<@–T‘* CâÉTªn¤gš,ûŠ’1'sh`™IBe˜E+È'5³÷ ä«€<:JæÄ·MF©A+_@LKN×wUê1Ì´T*ªê8JÉã2øî!SÖÊ.$%/£wbS ²dÇAÉÀ€ý ò<§"T¬_踑‹|Z—­c‚¹¤ÀX²¤d™Ñ‚ â¸27 åi+Èw‹§yrüºÀÌvuÆ=ˆs£SËß3±Š½GÓ;YÇ€?4ög±–.XäE¨ªzðV7t\ÛQýPõ8aÉ‚Ät]àN90õÆ¢³žn€|³•’ N»gÁ ¶Œ“¼)m[GFÉÅt>)>d”s|/‚9Lq L‚ź¦c÷}*£i€›¥~Šo— ZE„ûDdæ,B¨8Œ’»Àt‘š]X5ÚÜ€ƒSkìÂ’ì¢È sÌ<™€Zl›DÔ´€9ôz)rѹ8·‹‰BÒš'ËI T#âD0[<æ I™´UkÌ•À<dVåiÈ[wŒ“râ³Ê‰Ïj—.Ž ä4»€)¦LIËQà³yŸhž [‘)H„%hUÚÞȉ€Ì¹{AÈw;AnŠp¥™¬£á]:Ãh-éTM„û=¤ ?“RÔ‘”ËL”F³«ÙÓeOU晜õQM|ª:8LxÌ!ÄëºA@ù e¤ŒèÌžÌÝq¼ÒEv…Ý`8*OJrÞì~îIºJÆÊÎ8§1™N„Tˆ0§ªÓ㨉; [ò6³»'Õê?UãCSg0´Å.Q)¥<à®"eRˆ€=n1¢²Û¤… ‡\HÇ+± IDAT$<Dig¾R!\9½£=ùÈØ…ïûCÐø0ïœÀÜ\ðæŒç³° ú-’EDEäF¬HŒU좌;./Pü`”ïc ²ÞØ wd ‡ýY8îyLfkfr"óÍÀê&‘P… ( ŠÿÂ7à”VQÇ8ñA×ö]¢$ív9A.¯x‚Õ/²72Ú!%Ûóù|Œì³aª|LyÜí÷B¦¶ÄÕYbPÌÃu(V.3k@]Äþ­¸ˆØ²²ÂMßÍž¼ÈïvÖö/g@µ€ BG¦s3ǽˆ޼WÂË‹Tox+ªõ'iñÕqÉÅÌí¶hgÆr°~àˆc\µY=Å.¡žÍ.¿ :âiËÄ¢GTlM½)¯ekJË5(‰1õm8+ÖV6W«w±‹7—“7A¶ÔRÖî6ÊW'ÍÅ©CÅ ¡±¾{²ëQË z³¾GºÀX…èSäBAâÍLïŠO§…”ÜšA}0]'åå³ÊÛ¿Øuvžœ¯Ñä´YP¦6Ÿn™zÕñ–Äû)Å5ÏidÚ vP'dTæbÆ&úN ¬( {­!-Qv…Êi%tì5¿eK¦ú Äâlÿ–Üd7É%ÈèÁvÖÿ2VÆJá˜f$*^Ì¥ÏWŠuÚÕ`ަ"—P”«r%«…ÔÅÓq|ÖŸÊ“ùÙåõÕ8!Ž+y2.HSîøC]ÛP±^-ݼUCäT »Á3'Òå‘R¾m!uËÕØZ“?•'Û³ñ™\î§0íèÅ…„#g8"âŠ9 kÚ _TÊ ®ç9žòÃ|ieÙhxÚïp °ªŭ¹ñ0`Ž—’³/ ?}úäR½HJ#{~9·e“´bUŸÐfÊ ÿl<ö]Ïìz”I¶ƒó//{(ˆÃêË| v7ì¬9Zv³"*GyY[À”öœ¼^ÆJb•O²¥‹×u\Ú äñ¬ï£[ä:‘g¨¹ã±MèYoÜSRœPîEzV™™•Å!¨֟ϳ/W—ó~¯‹¦MJŽãx«ë¬\ÍÑ»»XÂY)¯{£ªÌ>‘ôšiGñ¼\VºŠz3;œÝ_ú€­c›ã+‚¡Id$sÀí[*5ÇväDZÇæÌ´Ã`(Ù ˆÌA ö´óä­žö¸H–åÆ';×}­¬ñ]Ë2ð›P²IŠ&‡¿o‚dìÏúÝOWaZúxÝwõ»Æé…½ˆìñØ+*Osô°Ü M{8´Í@8ä0e$H6¬5H¿žØ ª)O‡‡Lð“r„XY¥¸Ý<ùH@¶g×r•û>è_Îh2¸ü˜ßƒ\æîÐEÔ¿üxšç׳¥fÏ”ŽrZºlÓëö†ž’¯#³gK¹doQº° éÂ’Ó>€¦ã€sYù0“äš)!$ßÀªô^Û[ºØÇ%à•A¾¿úò‰ˆ”}÷?õ.ç!@D¢Kôr˜S µm°7ëyÜ?Óð bCåµ€ÎÇ8s·Qr{– .SãbÑ KÙ)b‰=€lU&¥z‹¼¹4Úa–Ÿ6d\àï‚t¯ÁG™+… ´fJôA”’´lÑ’Žiƒ×?s„t<:vzÈF>«Ó>ȉTFžÒ¹;ŽÏž_Ý__ßÏ‚n¿ç#žöýÇùéÇ÷°ýrHÃÙÕÕåå|lºHÝ] ¬”‚3ZéÑýÂ(è‚Ðñ€|›2²ØÃÓ~r˜Æ÷ûHÀ-¤lê^àf‚Np¾GÒTGâD‚ºHÂ,ìm&„×÷í€(E[ ×ÿè‚H;Q;%×=í-kSç+öGm…Ó  ÊGVú{ó¦—¬ W­|T»¶ÅÉCSP`€'»ŽÖªÓí”\Ê_oh´o¡äìóÂe•„ª@N›Nkµåzç•WKÝ1Îàknrß r¶x¯Àœé"[ɘá¢>ݪ^œ¬ú˜¯—:S«Ú1§í‡¨¿:ÊwJ>Õ©j…ÓNëgÖŸjãç•:vý ùÚY­vJÞœwófGyKQ·mµko¡äÁädsÒ„öAá%„ý&­y¹´Îï° Ï›rÇf6­óóséÄ85þðVOôÔy_ÿäª×nn¹» ”;x-—žü{‘sÝ=Î÷y|žpe?ÙþW¹¹·50'ÙòO‹ åÉ^Ì!—6Ø,Ÿœ[Â|"£Zଣ§•™=ù(7N'Zj€ˆpþU·£]Q$U`ΤÅ3VwA¿AÉÙ·oߦIn½Œ]䘸D:z¿SX%š7&hÚµòÙ…ŠYæ dë^lÉ3Êÿ‡­ñeòÅéâ?Ó“k…ž/ËÀëÐòЯȓÿXß90ç gÅÑ]ü`¤êÿ]”[^¹´èt¿±ŽôÉGÅǵ¿¤Ú¹íˆQ;%«ð“Q–Œ^Ô^ôóä…'ßÒbЭ ßÁö–˜‘ÅÆ8Ús·m9’'ÇqœU ¸Kâ?®Ý î²ÛŠ’ U /e`Vo^T6Ù´ú±Ž_X4Âoêð.6pþ ANÖ¥ .,§b­þÌVŒ9¢ ̱ªK.>n…ÀÒ­þ‹æ~üÃÿMOû[>Mxñ}]X߻ݶPò$>Y-‹‚Ì çUEäUÇZÒû9ôö:ÜyPÖYeMJnrü:SMÊI“k&ò=©h +MžÉaË9e”¨$ûpëjDÅ5Ô¯IokãÉ‹}¦˜DwxÀij3ò_h*sñ®gKê”<åøøpY°œãƒÄyíð›?äu¨Œâ²T:—/Íë}¥°г!ÈÉÖŠ\êaú]PœòéB@5 ŠI.¾C{h);f´”ƒL7{n ¾n¬[ ì+¢ÃïÒÊe±Ã\–’ç©ñ›¬`Y®ò$Éó¥¬ÙŽ—¢ZRlaâBVÝ…k̬ÜÂK-*žžæŸsø˜?<üøü€sv»òÏ??ÿÈaðã'xL žŠ’ê”üã˜(QýŒø=æùãÃgý9ÏÈp@ްã×ÏŸÕñÇò¿?Ú@~<*J2~ø!)ù_U(‰úá' ýó3ìy|Ф~D”×xòÑóä}˜ïçcáÃÆÄ÷ãÚä~”oÛ‹ÛOõö]½Å?’³‹„¯™Rù¯þK.dӯɵä—Åû…àú(uä…¸àG0ø†-h¡ØEV³¼u;Ü/ü{º©ƒ cÛÎcÿRóäæ°«cŽdc‹yÝXÛ»v¿xüFäO×ýõÍH[ž«â¿±ÿ¸á*–uv‘©1f¼xV3lW?Û¸+µÞv ;Á3\Nßã—á¥ysì qáÅR Ò d,üj,Š(‡ öMRK^E¦6âJ•¾¾‰|ÏSt‘L_æ©÷ÈÆV>ñk›L)/ï2.áU”¼()Ù’$›-GŠ2Ž_ Ä|Yt2‘÷ÂÊp0+)9ÓWh•w3Ë^‡c´Ag´ÃzÜ— 3¹^ °OÎäèi!Z@¦ÅÓoMàËÀ€ïFW×O <&..l` 2KboX1î¹M1Úû5®ÚxÙ³ß/pÌ ¸–‚q€ÃX6E¸ ­3ÉW$¬ÖÙ/ÝœÆmö³6¤‹öé¤Á· Æ>·áf¿ôf?£Nc v±Xêð4”†Ñœê_á‰}䣜ýêÃ(@^þmoØÈ·[œý+‡£isß´¹oª_MkG¿ä_m8÷æùk‹é;x2•£ÓjõÍÛä}=¢Ú(ùO~2ÖA~uA/mž­¢ä؃$ùŽq¦AÆ Žñ‚Ó7¾¥%¯:ƒÎÍÝ-œþ¿ò×økg‘ß¾ÈÿH—“›NrW€¼W(øï òù @^Þ¾qthIÉS™¹ru~yTK eY网Èß=Ÿ1Y-¤¨Î@ üPæÔÂd,‚Q…Q­Þ–NÇÉ… ËI„å)•y¬ù&È‹øk6X¶Å9goEÉ–…)6n›ì"¯Š¾3È,0m_ߤE%Œ("ž¢¬ö$q˜Ê›¬ó¥d‰ p]Ï‘Ùá˜h9†+ú¼È’'ŸcŠQÁ.²<¯gäz¹ãšshYœA戋|×qU±c“©§º¨$× ¦¼#Üu' %§õ %%c‚¼™±åÍ(ù<>©üŽÙjÚAö½®éuûXçW§!ÃÊ9熎¬‡ “ˆY"ª*Sdç, â(ì†.‰”÷YÃk+.ûj<ù¨@Žº¦ölYR«¬±îúaäE²¦"é„A@¢F½_Cƒœ`×^ÁÁÄu1³ò6k_l½=%ß©ô G2±Cs «P…BiÇ£A(óÁÉ’9®išA½ÆVYÌ lE"r¼î#„o¡äE'çoË.OŽ;DzÓõížòUÙ!N`À¼Ð °À¤¬TæDŽLÔYÔr)ªwÊJ:˜w/Z÷BUMü)ßCº¸9.J2µ}NYõ@ÒpÃH¦MVå<CY u­Tç¸g"¢£Ä6ßSº˜È žu©*‰£P„Q×e=ÔõÀ'ºÎH­²¤”.0ñ/»€é}݈lãÉ‹—ƒlý¾”Lˆç9®¯ ”L\¬]MuÑ'`$X­ŒÒf±ßTmÀ$ân„ï²²r;»x?od¬*ÄBø¯Ä7]¶ÌqU©I9å D¹¨ü$Ù…P…v-â¸~3åɃç‚<Ø%]|Ø>ñåïn4Ê)èn7BŽ ÊrÌeÎtº:ªã›f¨ËÛk9ÙДŒ¿Â*–ÕRù gm¬Ýß›ròĺ9&v8žéÑTTò™ ‘ÂPš2äô愳®˜šVu«ÕDTŽÓ¢fÎÛØ~nùtß¡ÆûüO£êÆ€lMrƬ‘2kr:( U@ ÛõC¢e²\Y·x ¦§øƒM—çç‹- £1[}U÷<7Œ­É³¢ CÅ$VåË&O–%GwâXx²ƒ¹ê/X²²Â‰ÀwÂe)]À´çZSF*%_"ž,yÎ&»Èâx•m¹Ì˜(yeÖN­¹4R6«peuKq %ŸÑćµ!ᑯgÊôý ]袇°ÁóX½ªr²Ì bS¥%Eº ò2ÆÚÝ[AÖêL‘+=§YêUW*@žèzZùÒRJZ@–<(ùæä˜x²Ç¯3e×wünaAæ‘ã8G„®/YiÕBòLf/+ëJ[LË»[AŽ•M=Güª†Yfùps+ï5A&›“A¾ÂJP“É@ƒœ?OFJ&aD|WЪ¢24Ï#¦WX:Iw8´±ŠH-Ýzƒ'À5@Ôb‹ZÝ^ó#+ VÃ Š„HLò²¬ÛD¢Md¡·LÝ UÇ%߯“JºBÓg¼ R„ºfš¡YP¿ßš²ú$­+# d¹´=Õ•­öä] ¯NÁ æ4Fv€5EN²LŽ1°ŒóL‚[yŒ Ã1¹ÕÉU–?%S'ô±þ­¤`Á‚€t±¬H*)”f8tD×E8m~fD6(*×Ûääv;r‹K:¶2EÓ–$cLïœ5µL÷¬r[Ƚe²ìlÐÊ“Š’Ǔ̂kÊDfb²iÒTS2ª,!¤¦SmR1d9q*§G.ŒØEÞžú‹?Õãò= A %ã+‰³¨<9dZVÜ@²ow]mjÈPÙ<‡H­P‰O–ôKPçŽ(Häl]ÙÆ.$%Ç;•ëú®SIÉqAÉ’äãcãÉ#äfe"x,^á„]amÃ4-@¦®ët»üÌwh*yrZä 8ÜXÑ<™SQðdÁ·™:wN|§(YC>é䯮‚|yv s_É“3%cO–Òe=Û>ÊɾKƒ®ËÒT0U¦˜«kfÏ&ª†2xL®g׌Ά2I~<™H„­Fû [5qw²^ô· íËò¢â”.ò|‹œüË@žX8Sã ^L69 =¯kT.é m#"¦€Ô¦e áÙ¶éPFk © Ž \˵µÉÉ»@žÔ”]ub ž<;&² "HRN¶¤œœMF¿ƒíBš:ó¡WáµÀ »}› U~ëñ‘ÀE…£Qä>E-¤” òs€æÑƒ@ÖéíeÉ\Uö͵"X”ÇXJ™yO2,C«eã¸ÐøN¶Û.Ž d¥?KåM(Ëèw½YWËÍÔqp݃ 6R ÊÊÔ™ªÃA žLàVÐÃAnÚ.r­ŒÈ \E9IɵíbRÃ*Ûi»8"׃ Ž*áB¿9Îçž@÷ D9AiXV­–K©©^HE&E xÀ]ý0¢ƒÜ´Â|"G‡5«Ôø´íbÓ ·ÝvqL »>VH&ÊíBùY0ßwf—3G­Ç%?Tê$Ú%O©¤ ,>‰ O$žq Z½aOÎb× DV‹…Îú-(Ù¦'œ.–’•+Ò)(è_^õÔ³‚¬à‹"2)„8¥|h™¸Ôñ½(låÉv‚¼ke$ŸLÖíɵY|ÇßR²74Ñŵbä ç÷—&(ÖTM|N€šÁÜ+Úš'Kû>@Oˆ:Ì|.ã¥Î·œjõ1òdÇóz ¬!#eB.‹Rgv5ó]B´GÊx ¨,ÝYóÒ’ó$º¾Ê$ݰ ä¹å}@>FžìvÏ”¾Ç¸ŠV êÚóqxÒYV¹„+{&e ,½Ô§Ù…¬oM×}% m­”¼X¼ÈOòdkõî ›æ˜S K2¥îl>.´o‹PdŽ*!JÂRñK n!]¹¡õgÆ]”lüg)Ù ‡g +­EJ×7AýùÜ ÙtjÔÊü¢‹CXZwE–ÌY€è£¿"£û9¾¥WçòäÐrì¡á$×`ÝÞYhÛAQ^×H%1K*ÚA6Uú|švÀ%C¡;œÀ+oíŸ|l”<›Ùý™)ý“ .pê˜Ý³¡/942Ò2),KCÕÚ³žøœ(ôl3t”ÛçvvÑt—E›Þ‚’PNî]ƶ£ìN ÌaÀôœrž«ŒõЬqù_le‚ëšhå”"ÈÓ ¿±ø1Rr˜ÊIN+@‰Œ¸Ã±!Õhiâ\®£¢rç2Q:Ê•êÙw©º?ÛLÙâ]ý“÷£ä÷ŠÌdzq2êJ­î› `”1eT/JKsºwŠbi­ …tí®O´óÓá o ò”H0¶v?Ï ä÷bι7ëí±ºT0Ó %ö }í¤• è-F*´ éBÇÑ‚i#h›npò>Ÿ¿glõ‡g‚ü6°çv¿7»º´Q•pd$H·Rév¯×ý¡ ”WÞ-‚2ß<Ï´É/J—+.–ƒwyJž¬OU|ð[Ø.†—¯g® K ÊßÆÝˆºeðWÏï"·´§héçÙÛ0ŒÜïÎ瞇“1{]Gyiú GäÒvA¹Z›Š¢õÏdÓó\R-Lmyº1‘eÅJÓ^VûÖ§~R$X8Œ'k¨áH>ÉïÞF¬Ëƒþ¬cö(éÚA$¹¬ïÆ.+-d<_iѧµåj\7 íq/‘ƒŠÃA6vƒ¼Â:pKy ´4鮵òþ<¹Xû*±ðD§ordwÃáåýåÐÈ´¥sñC JµDMŒSísQørjžÌˆÓí¡çKéa´7È ”µ‹V'Æ*ƒkoó:É#bK;Ã.'gOʤù«±ŽÜëúÃûüÚd„]ONu¨ì9a¤Øòdt_‘>žÈŒk”, öa7è¤äÉ›Ê&n¸Á’…O|dÅðÊÒE]É×´“šËXüJ »nÿêújæâúQÁ74¢¨‹pí ” ª£v„Rýx¡ðEÁp(@ òMeYÏÓXl kòΩµ:µN—Ùé`_÷âÉ%z'è“°XãB…óð¢m0ƒô7F¾'»pz½.ðBÐIEYäAÁö¯;¿)ÓŠW%”¨©¸vߎ€Ô©à[Ôj²%ÙE6ȳ‰üZ9Ùš48ÂdíÆg5‚ßÂ2¬ 9Ø$¯.vLBÛgA¡¯³³ÐЋ8ÈÉ-2/…èÐP9¤gg!2ÌlÕ½·Þä}xò¤ÁØõ×ɦV?ÒÆZ¨ff Ð…,‡IrµÊrëIJ™8r»ðá ÐdÈèÌ OYiÔ¬¦½Z8qlX2åÛyr2€¦'¾Á ô*ü…”\×8rÅ<²l-8¨¤l%èå íP~±”Ïž¥ÌvR²zGïr6Œ"¥ñ¹.z^É*÷Î_óšéÂ1‡h°gš'§m Ú¥‹_o»h‚šmŸ~óâvÔ'H«&îgOP² \ùêêjþ‰¡×„Dg¤K¥ IDATQæˆK«ímQäkAÂV §”DžËÐó‚ó5 nS„{Ï ‡[A¶&û¸¬VÍ¥19íÂc¨Ûˆó]V<Šº³ÙÐ lßQ¡#)®Z Ùµô-Ò4TÊR9 lx2/s’ìùý²Î>AÉYÍd!PPV¨k!uÿÑ|€Ç»°6œ‘ìh0²žbÄú”~ "Ð¥õ3—–,BÅ´×ÒçðÒžL» L†ÐÙòݵeò¼5>©õµc”Mw0tG·ŒIVÄuî‚8Ï©gwqÑP%‘4µkpºU$µÞRƒ7ó<)~‘²³^Õ=œùÒFXÎãìæ6kifû·ÛDýþž\>ðÖ«²eìp‡ì`Ó`?KGNºhq/@V¶MÒ³È+™* ‘QsZ®£z¶`".¦œñô —Éù]¶¨!„Ÿ‹ÅhÐlw-`.j¯õ6ÜÄÉ”l­O{ë6Å¿_Ëv±svæ€dQHb,¥QM…8i¶af9%hàè¢EYƒ¬œÅq¼¬(ùƒ¹Õb‘Ý Òµ¶äââüÜ}Èâɲ֎õ­×4¹Ä1góY/d2lÙúsj}OÆ‘©ô•\£d¤“¨pMí ûömZQr•ƒÿ°á[kÂz¹}Z5•y¿ü]¹¹1ñíË“s$؆Ñþ4Äo²•G,Îú®ã»´0cJÂ,Ÿµ¹çêþÉiÊ‚ JNN ]„·|a¡‰.ÿÚ29\Nžlˆ]ñàm(™Ñ®í¡8!°*$AÛöCN‹„ÉE Cª¬FÚvázð#"ó‰ˆ-r²¦äS ¿YËóIg[;‘íCñM½ßÊ–u¶·ó¬s~¸t‘¿›'Q:®™ŒW`j%] «;tn4•MËÀEWý¶Ä.žÌ§é´¨ÚYÅÖ¸ç ¥Çâ“] Oj ïmOÎGï2 }Gyƒt¡Ü”FSK\Ó©k¿õ\ `Æ(«]ó]Ò…ÕùºäÍk†°ãÕד›ä˜}á®Iƒ†ËKE*_Åby‘{¯b©tüNkV8ªlEž­ô)îft£Úèf4*>«ï77õïåöj‡:¾í ؘ«2ªá¸:ÇB³‹)µÊe<éÈ5è´‘*ÕXÏŸ,]’©Ê¨ÕdÉOªÕ£úëA¥uFÍšÄß¿%GMÉ”G P8nÀ”,Uî›゘•×`ÑJº®´¤–¼(}Š]¼A»x||H’ä˜ý“…½ôVf•˜Q׋”–ð£d ’—+RæUh{d¹1·i§ð±.ôÊšS5Q¹.Ã\ÿ¯Z“uCåîã¥d˜2S'ÆÝ.Ý[BQ—&Š)/­ó®äiYs©Ýø%V8¬¿ž$É1ÇŒ°®^eÇ‘DÄÇ[•Ý"•ò±¢å2‘ŠAáš•õ¾ôÃèìÌEšóêþK/Ä ëÌu(‹zãþ'Л]$¾ïåòs?Íg~8Zv‚p<´ÒTJOt³ãu9 ð„‰-2Ö`Ðà’•â€Ã` 5©Å“5%B÷×W—×÷cs~?ï…‚;¶ÝÇŠ[7Ø,µ/¯¡Í<ŒÕqL³‹qRŠ’£á ˜%ÝþÕåÌV °{O|í—ÛœÚÖà3cK(ÍÑòdPFÆW÷s“zó«Ypy=ÇIÐ1Ϻ’‡xÝÐEc|džy]L©Œ ÛÃP¢- {²n8Ÿ¹T'‰½í ï,zóÝ©N^ñÄx’”CÆjbÅ®xpô”<Ÿ¡‘ÓœýáÕýŒ…¶/¢1Mªt) "7òóÂ7w8>sÜ¢B- lÓÅ|g³9 He|sœ¼&Rt;‘U[v[,â‘—Ücòûðä®Êl˜>sÇóYÀ)&‘¤4œÝ_ƒ.G8s¼ˆF†ã!ÈÍdÙ…*Që ‡ Ì~Ï4M{6³»M¢ä\V‡CCJy{zškCº°~ é"T |„6õz!ÃÙÐÿr/ã[/ED¦‡Bpc†Îž½±MŠÜ¾ÔïA  Žo‡=ÛÍBÉ+©KX…2r*‹rï”ÜAAˆê 2œé:Õc Å¿ßAN1—ˆëôz6 {<•ô®¾\ç¯û^0¾FÔë÷¤U“È®hÛEJ¼Ðž• UÈ20;ØEº9#HƒB_V_†™Ä&#¤Ù‘Ö¥¥Œ7Ê;ɸëU1ž¥ñý Sgïþ#ÒìÇ/Ý9(ÇèvöýÇëùkZøC“Q~­ˆš#/2MGk|¬kûžÝÓš!ñì¡Ð(9/óv”år$eN2]’V ɹLB”­ˆ~#ÛÅ—ùG/æ×WãûëË!êvþ¸'—NA~C‡-`dzÙe8j‘9 "L9$ÍÉÌ‚¾}æ@Ô¦×5ÑrÜ&'çMÓ½Ò74aOS(-ˆw•/4±ÖŽC)ù¸¿Â…jáõÇŸÂùeŸÉì›®åhMK³œÃ÷Ar€­‘=:E6€”Xu5o7%Ìà—íì"[Ün«Îe›æå¢ x¬@–V¸ßx¯ÉŒN Mî õ"¨À€UeOÆ¥§2x’zf—¥;KßDåÖIƒñ|ÞeTå` ßòÞ+#™6J+ÜDM~“}A>:žlMò@æ±Äñ»¼žHS}Øõ#¹®*}•™ÌÎ HäI'|Å“}»7Ÿ?)¿EºØQ#ßXÖ[7u’Æo»Æ§íòÌ0\ ki9v? î§/—Ðú!ç彩2g\àky¨ñ„EÞ§ñ¸?üôéS¯ÿ) Év§·x‹ßEcedß„EGíAÔϯî¯aÎ ‡}Ó’tf×(o|¼‡Í÷ã€Ù—WW—ó™-Ó3¦§<²¤‡KÔ¢Gc´oÚ¦é){òÞ ounÉ_²zŒ<ùêã)ÈÄЮ¾\Ý_]nDý«+PG°8™×ï{ $û««ûûÙêõú¨†kïC5“Z `•÷þÅ ÿY«Õpa—ãO˜<™!Vá›#fÀtÖ¡L΃Îp<^Ùýq/ttˆZá¾ô`ÎTiudM9ò4Èq!+¼ÈGY¯\†œy¦¬xÕs㉓i:8 ×´½HûbŸ@!z>›¡ÍÆ}#zŒçQòËÚ1SrÝ×ó6ܽUyŒ:è¼äÉÊ×룺ë:D¤”ïô Zsû~/_¸Â¤4x'µCY·Zc•òZýSé”®eXC?-]ÂUˆß´¾}'%çF\`ýN”\ä^¨;Ó¼­¾Y(/ j%ºÆªÆzÒ‹´Ì­µêðë¼:×xr4ñë@N ± ·T8—iÕH¦ d[ü¹ÒÅ›Qò(S© õ’bfaü¦ú;­>Ö>Mê›O'õ=å_¾¾©¾¸ Ì^¬°èÂîâ°–šáÑpØ_6†W¦N¸È­£o½R¼Øµ¯å§x“'ŸŸgç'w{L|[L"ÖÓ”B؇ô°ÇðjWsV¯Q1g²{ä J^.WçLÝuÒÅóO8Ù䯃ÉI–Œï[Ý999ï`J¾6ï òóOï 2ÆV/–·ï[}~s”œ´ƒü'µ»8ÏÞ7rÕòv4xF6CkO6¹ö«Ás~µ7[~*ßEl¼ôôV}=ªNÉÛAÎ*jYÎãÜxÆ€×Dô§NgmœÜ2^2º ž¬˜³| b.·¯2úOçÒ¸mÕJ޾ÈzçÒ~žï[˜ñ©ÚOOWÌÉA’Ä"ùq'3¶TÌÙò z×áS´GÜöl òQnœNôpÑ燀<ÂׄOöâ x­+\L>-¶ vßÔý@>Ùqåšu'ËÐ}™t!kƒâ£d½¢Ø…äRÙ¡ Ë:#¹UÕÙûVÁ%ê*¨Oÿ Á“ã"ðE„«s±âdšÁíËÉ ä›åäÁ`'«ÛŠ’'o‘t»Á“ÅV9ùY5¡j?IFaåo0‘ì']üÙ ¿ŸÆ×L%¼iݳ¬†ÅÑÚm \?¶þe²Ç_ëûž¿™4,£íÇþÿ94}íèÙùn÷ýÉègÒ¿Ýã'‹ígm|´>¢õ¿QÛ°«žFÍ\ïR?æZ–¼gÅœÛd+%ße·ÉnÓïÔöîM– ¤Ým³·lTÕ ©•IÖz¾=¨bÎíZ‘&ÈÓÁ`¹^,æ×´óWìk‘Ý îÚÙÅ2Áb8‹E¶¨ª±`­àn!Rõ7 æ,nêlu9ZQ«àn±¼[â?®->,%È­s4`%xXƒa©ïšx.ôÁYìâop·\«ý¤”‘óåõ‘»Bˆ¬š¤©•€Yß[?¶Ø”ÔÅoy„Ü žhê Z— þ%­giB5võž”oj.*댤É.¹¤íi½(Ž.zÃ…h)š£þ¦ªÄŽú]íÇm¥âJ/¹À ÃoW?æZ–4й¬¾Òs,ùß*>â ˆ†›=4¶)!UÐ_ËV«›dÃv¼i$OÙ¹ÝV:æR'_ÖNΗÕC½,Úêf Ë«” ó‹dµDÚ¶;*ælÖrY`ŸÐñjç Λiƒ’y­$Ôªc­:¿w;׌ôC'¯Î¿žœÒÅmýŠ¿®:“zÏT¿ž¹Q1g]N†ß®N~s[y<\7­"œÕ9äÅêéz9€! c´UN^ìHqöhÝÞr¤Ú,õ0)pִƽEߤyŠÝ?M¶(©†¿ òÓ#xžÚðm»œül…øÈÛ÷ïß“v[®ø¥—QœípÛÅïÜ.n·]¼uÅœ)—ë‰~­YäÓš¨¤CýuÚ&9V_’éæ1 a²Þ[Ûÿr8Óõ^ë’ê–&Óm Ké7ÛR02)Kà”=4«DÖ‡_lŸVÕ&7@^«˜#+î`‰øˆ…zð ùŸFÉE ›E"¯)—SáºtW ‚uóšg+yrZ4#m¶Íyø÷ƹ9moêò+~²|¥âà5â?VÕIÓÜØøÉíCˆ’ïÆã—®oûŽÍh”Q{›Ô@>/zæ›Eim…­åÑl? JŽ­QlÅ™:WfÝ¥wüåé~ï#iÒÓ²=k<ƒß[©u‡„[™•æˆ.^¾e¥ø_]äÍz'Hfº#Ô‘Û8ªA¾Yæ^"›Zž )Ø’X§ùïÅ.Ô*¿|ÆóÕ2É—Ó +·–ÉÒ*@†kÌñ­àÙÆ»5¾?¦m„ïy¾ÿÈ¿øiÔÊÈÅÞ-¹X;ë..jÒhñ‹kãgÛ¥Ûú;;k;ëÆUÜî½Iã£ÊÆÙ.ZÎQíR ëV~øÛ^§]~tþ÷ Û?Û«¶ïŇïßÿ]k?6¶ümÛ1µ‡‹õ-ÿBÞ`Å?þ2ç¿í¨ÛÃ÷-Šþü§ÞþýçoûÛŽ¹}o|«ò?9òßvÜLø[92îúKÈÏjŸóýÍÞ°óÿN‹× YÓòRïÿê„üïÿdûù—ÛéñóãÃÏüôgþù4„¿ŸHŸùÃCޤŠï°ëGþSRâŸÅ®‡‚~BùÏpàüö~>}<ýÑÖùß¶…#GúÜ ä&GþWÛ1þr;??ç@pùg ÄŠ B’üüùô3l*}8Í‹]HÈ?±Â‡éÉè×:ÿÛ6ÚOIÈÿ<<´qä¿¢Å;=[¥‹¿4{!×E‹²!!ÿû—ñÍyø‹Á³ ¹¹«X¹mFÞ¼Q”âoÝÎUÛ‚ËÍàüü€0Ï¢³órñµí\¤R ©³jAägvÛê1ËkîòËß&Ñ(þ½¤R#möµÑõ_àw¶å¢¦ì-ÿ­ákl‡ÞøÏÓðá4ßBòÆžÝÏ?óç^49pÛŒ¿Öß5±6Ÿ÷v~m¬±cS£vÐïøKÍmùŸ:!—¢E*Óõá»eÈoÙÚ]X; ?âÿ¬ý,–þŸ[;“åùfY~ÜâÅ&m­Doìýd¤[y÷µe™&°‚êŒ ZlpäÅmÉL0VBE¦ÈM*t²äׯ¤è[Ö ÇýÈÒ­Õédí°xÞÆEoØ <ø„ nMz¿Èý1Ö80ðhÜ…ÛpüDo“o¿˜o‘´••¶ eFºµ£¦—´Ó󈺳¥"äâ¾Ë—8VôÖ&ZÜ6Ÿ´øî)˲»Œ×V‡IrÎKº†×5Š–1Â{ÄP7Œ.²Šç ­ óãêÇOÓª•zWñdbÆáìh”£•ß>Éƒí¢Š±&IÿuEßwM9ŠãŇ6ÑâŸæ3°NÈ©¬ TÇQ†ç±òú×,[—-¬Ï•U˜à±ÈñxcƒóŠ-pñ ZÅ#{°~S5Þ¨(ßh•wPþUíÓägÉ’S©œÍ )ÇVórS´ð58j¢L·MMÆOÜ-CŽšoœÏXŸµã¡ÊM¡b‡ÚgìdÎF›|²¦neÖÿ ýººä¦pÙäȃâ&¨´fVllr£†aqؤ½yXëm,ã¼qןâDÆ1àÛþ¨?×à³èÿ›jŸ¦ŒÑ&`)ÒnÊÈÿ¤ÏD¾õpc?õÛ8üLÆÝWã)©×HÛXªÑB´Õ¾¯sä6ÑbmêzRÁ0wÓ¨1)c'ÍRî3­ÂÎÝH#}†Ú·ëÑ6Ú±ý/«}[o}C´øgq»P­xßÞnkoO½½ÓF·Íí·ûõµçéß¼Ý4¢Û–·ÛÛÕùþ,¿o»m!ŠÚ—A1¹Å4ùÛ~×lï›qîÈ ùoûKȇòÅV8Í‹ @û¶Iíÿ?œÚ÷毭uñm²s×ä=LÖ¯y¯Ë^-Ÿ"äô÷­Øµ#Wµ Êê9éŸ^½ìOoY“Ë[¼(oñô$ä¯å9¦µÏî²Ñ2¾•y[­øeý%“ß¿~ˆÕ-î·øOäÈ_—ƒåWë9¦¼lò¨S/¯Û3YÔ²(ò‡SÄ(”1B9!$"\7#M9ð¡ò¸OÕJ aðxÅÃä?Cí—…‘(ôFË=åJ^í[Ù¤ {¤T¤ðçÓx7Ф_ì d}‹òïñ4Œ~BÖéWKUé×JFÞ¬A¾FÈúZÿø ª9<Ó¶‡½žé2”Å©¤'^#)Á€F© ¡ïnè…)(/-á@ÇÄ ‡ñFÓ}©Î ”›7âÔuàáp±9pÄië1b }p#"í84Ç(ˆåt S}ÐìD²3šÍñJ,Zþ€chšèE4. M@fY—9 Yä/¿…|± _@>†dU#¬!+m’¿@0È>8Š´\Sr•/F“Hϲˆ_vî·F¯EDø-LàÀ4{QÀ…=&6Ò0 s0Ç,U3Τ ×CJL¶åDåˆJZ϶H…÷-áÑl ¨àü/F4Zäo»–ÆÞð˜×ø\ Ã9¶á>çèË ‹œçaPD›¼NPIx¶mËÉi]p 77nß5²0Eìˆò™V@þ^‹_v‘½úÂ…Üù›GXAß$”Ax-‚2 ›vÁ³`v#?f¾#Ýì?<<Ü÷!0´ƒ‡;î® ó>ãTðÊ‘!"M æ)£9âôå${|t–EÎdÀZ˜ÍnÒê,dƒWëI@Þí ds²äÉùfûÖð «C–]ÆòÜ7w,w)Ë´¬§¨wÊí,¯åÓù¶³È ÔÂó —YwúÄ#I*îd f[Žn^¡"‹“½þt¾\.çÓQ_9ÉqÅ,²‹3'dºçatÐóޤ#Nã9md…á,¬ (&pÛßj‚#Á¥ ÈÕÿ¡ÖUÉ{™†Â Œ@æÖ<ßæ`/4}”ñ ²5ÂH¨¥¾[“íd³¼7kÉ‘o; ¦Ę:ºï„ fQf2À±;ƒAßñø |²[²Û¸Qi Ãi‰Z”•YMH€A0ÊàÄZ•æ¸Þ1÷›˜d@fÆI.5jWX]*5ÇäS*\bäžÌÍÆ8í“¥0ª AÍ¿(¸®F>ù,,»ßÂÂý¦ïrÜÃY~än²×8Ùƒœ6ÃsdçøAËùÈA"ÕÞ%ž® c0Ü Jʦ±ë¦é ðP#)%ÐQW„cFØŸ„™}säÊñ{r䯀ˆR ˆh÷P¸·!+Ç2ÈFòœ†òõ_c+rd¯Ñ”&_Gg‘/²ï¸™ÂM'÷F$…ÙËMi$@8.ÔDYÓù|41}I„%€ j«€eÖ!#Ó‹(eHX¹ Ïø”Òêc sHG¢2&î»Xêd’7Dü@Dä,2˵°Áfø@fxU»‘¼p¿©Œ¨*ÜlX¿ªMã#ÌÓfWBÔ™-…¨Ïˆì]Ë‘ÿ-¨!ŒÁ‰dŠô ”) úT¼ûéüy9êëLœ…zê’ˆë#Að˜ei_)""»ß¸gƒ2jb#üÒÀÎ µ€J“ä¼ì·‹,rCÒÐ^„¨÷bÆ"{" ¢A_9aR5$l,×bÏè°-b*J)~G7u>;‹|ä}°{fß2¢8–‹ð¨3)*^ëA—ÅðÍáòùùyèt*1ÏÏ,"Ñ ¦ßG …2--•7*öKKœ’"oR’0§Ž:ÐvLJZ“äœÈÞ¹ù`gSö[–Pµ1’Ó¹¼ðIIC%‡ÝäPjäŽ#·²¡û&ëüÈ–KEÝ0G()*@ ¬Gz˜?>==Ït^½Aå ‘Pðtµ„fôs] ª+¥N’Ó‚»E02c€J Ó€ÿ°„ï=,2è0·I¬ŸUgwå¤!B{¹z‘MÜä#‰õjg‘ßÈÀ|ƒë³Œú*„Þ¦d^ó„._ °ºãÌŸŸ^ç}H3r=ÐuB`«S¡¬„—àQ“\Ï£«„öÆÀÉö!ê¥àýô-Ë5ýlm‘WçZäë*D4Ûn®—VÃü´‹ÿ‚€H#w¹Å꺹ðŽcM¦à¶µüA"”)XðÂ™Ž—nD,ø¦{)ˆ`&hLÀ )÷àCNȤÍ4i̤’¶!9’EÚ3U4â r Ù¤þÆ|€Ä€§ï3Ù» iG8_ýÜœa‘; 3Ò—Ýæè?¡¡áÄò=!ÐNpèzDÃåã¯×§ç!E:Ó•U°m@ 0‚j+ÀqY*]RäèJC©T9‚jÔ³À |Ñi *ydéí8òz§n6›õõ@V¯ ªfo äù²<Ù#˜»Ÿ §´¥EPÚã~\L¢ Â9™æ-‡ ¯ïErÜ9.>ÿduôžQÝØƒÌ‚‡J-Äè ÆÜÁ„RšDD3EÓ–™Ë\ ä+ÇûÈtùØ*ªû“éÔ2"A+hÔÙ£‘æpúýÉòùyêúnM}(©É=ÍHÑ«LSòå9ÑG ªBƒ¾@r*â)`…ÉDL7 ké8ƒøj\°\¼´¥Eþ’Yöû¹ãÈG\ÈýétB ‰`–èA&&Õž;¤!ûº5AÛâ›”H¢t!Ä3¨ë-fRXØT$BQ7ÌÙ/k à'tªG4 XÆRG4,x1QÉ\¶ÆŸ[¹³ÈG©ÅbuËù’üN,Åó0Ý^Gr›ˆºS×€” K‡4#ÈÙŒ0$§ Ê« Ã‚ÍÏb–³‰lhm}”@,dbS)9ã'ÄäzÐïãTR÷¨Af".JÚÞý¶æ@.™ä²Ð7kØõù€ÜåZ9À !¿Ï£‡ùrèxÏeâJÃl,e(@Œh:M,s‘r‹ì.w K$D€“>ð©%)­ö—Ó†b–“„ùBLô@%¼ÈƒfÁs,r3ÿéÉÞ'°ÈÚWò`´\‡KbŽ#ê:ã¡clâÁkL  Â¥ ¯ˆJ#$ æ=NR¡æu!àû@pQXÀ2VRæ­•ø†Þ AZ$w&ÁÙ²²_Oèû=r-4û ¡K`?.ŸçSÑÔ— Úš®+ugŠôþd>õ È„1æ+¤‘“B”0¦I1ï!I}slS¥ª=$Ñþt:Ü[sr!Dåýde÷ǺfKm±mñoù‘ü]]îÈ­i±ð¶È¹ýÕ,òd2\>?=>ކnš÷¨E¦Yaª‰'Ô}w:šÏ§}Ó,tYq–Ûá@J›+4+hÌ/àiô’=æiÊ(*8 ôðc®7&@”¶¬¹Ù„ð#[ä6ͨóË_µ/÷#ŸªvýGüÈù—£Ö`!»Qß1ÃátÐ¥ï$€ Ç0¢„’YÏ`uö^2¼D’‰MA ›GCØO*Á³W4Þ«qäé }rÞÙ-j}Z³ÈãuÂýîXŸ½·òqhïä7ŒìåmŠÇUõÙ!$™°‹ù#Æ;]‡¬¶$ò]Z÷O+ÕÀb<Tce™olÄG[™Ñ|z¯¢_Há(Id@VØ\R1&cA“½(¨ËŒ· ãÍ^ë­Ö½—-™ð½EþÊ~dMÉzG¿n*d­ö>³#Ë¡”t8~ýöíõybêÌû憉"Ї Ã<³•$qÀ'{ ­ü :n©P²P¤J?êó(Ò†d÷[Ê)µ‰u€(X‹®7úmH’Ö¹þÔŠöd³–ùÓ{-Ú¹äN§¼Â®i8×®)XŽõi¨t–fß=¾þúõ´øè½…™1®Õý²²þ1‹° Ô®€¼!Á ÅCZŠWk÷””D¿•"²G³ŠÌ 0pÛb™›eÍ­S@ÞÙÀ® 8¾$߀#«wÊ~—iö ŽC€O5³ì³Ù˜ýùãÓã|Ø¿Ç\ Ȱ ”òá,‡I :¦ ªÈÐþΧñs'Ò‚ËÙl´ø?e: SóƉa1Ù‹™þa ô2 ß+fŒÒlò$ÆQ ƒþ4ý=ÌÈUöbÇÏeÈT¨÷ÓP®ï½,û‡¼ u†Êí¾äšwt˜ÈjøY€¬{X‡·Nú”£‚ÛÀs¡/á½E6œîX–`~¦¡#»}åÞéÐ D®7MÉ\Ëæ•ibÀÄr2¹wï&ö諹µ8Èõ*„…\Í%Tp¶¿î£W5!eXÕ{räB¦4'­àbvþ‰'„Z@/õÑ”LáÐ…Oïu” "VRªñˆ<ÓX¦y†áó¾’\ïÿMbn‚ƒrŽf*÷$‘¼´ªÕÓý ?Md»kaýÊ$EK€¬´ñ*\dªPa£v\‰†Rñ V¼UãoÃ> ä·³ÈZÙq¢ò –…õY0%Õ><–1 ¢»ý 1Æ?}ûöí×óhâêÐáòwú&^ëS,>EQ{ZL%q½_$f^]"Ș(Q’+ªÄC`%—¶c¿^ *Tв¥Ér ò·³ÈÚ¦©P çHµ/ãÈ­ýË™>}Æ„#O­ ±òÈl¬% í£jœo–k1ëUýj£·™²Ÿ²P¨)0üh„߬éüñÛ·üÛëãÜD÷˜dÜÅ<ý R& Nߥ®Œ¢¥:“ÄBr-t,$ŒÓ~ÓU\²´:±-ò.<¨ŸJj]°Û9NéßLö´møx-²<›ÍÊ@óý, ¯u¾¾ŸE®ÏÜ4æT®Äëë^çzÈ'·Ï÷hP9<±cí-ÏH¡˜˜ûÖ‡e¾S.ô<@JE'ô‰éØ›,)Y×´ê5¦éšiµ IC|šIZøýáhbBzœ¨¼>Ïk±]”€\¶ÈRüS¸Eß-×¢!¿¡ —ƒl} ÈdZš«‚QÞd ÇxÎØïrͶÁóg+h¨ôžö@ö}Ò&PPŠŽc@S€•|n¦"î¬cçPeî~“û!Ä£´Ü *-©vsÜ{P¾=£ûeêGNŽÀ¸Èqä}Á‘÷·ôHØk³½†õÏ ä7²ÈZ³‰, 奔Ýô¢Ã´ZC™ÌŽÑmïQבšPª^ϲkË}AY7±_©eŸ.”A̘À8¡éíL,Ùw±Âz‰ŽuB5{‡r…z™ÞfÙ­V÷`Pls« †5K£Xíb ÓÀ/rb(nH¦{ˉi> ‡S‹ËÆK6ÔÛ¤ŠXµÙòâ”UD˳´4N‹ÆìX±”V2Ù‰nZÈP³Q1΀§3ÇJ[ŽÜäòHi wø7 ùÉ4=çv`#ÒžÞèR|·‹ß§k‘£”,š8oYU¼¤5p瓽†]@ë߇òÓù€Éó‘^PX¹ùmtƒÝ~©²`­ƒY•"cOTž ¦’…e+°?Â,P‘%ò½ .w¡Eþäãí9rs ^Õ2Ú»Š°‚}¦Üi0)nvE„Ye²W~žÝ3¨b»!][N„š}*z·×‘>˜ìyÆ=È|ëþŽ—zÐ_–‘„XÔׄùž«W< i¥-dM¹0‘´í+î7h®3¸Xžêažœà)I)[îR ïn60^²M»¡¾Cm¼­7ï2²ü³> ä+ýÈZ¶ožÁÝÎÈeý˜ûM¦”g{ç[ÕÎf{b¾mlKaÛ'ÝW'>jA®íƒÉàð 6Øw\õ«Ptž§Qg¥lBrÌeeyº% RÓgÓjtº¬Y„…PóéRœ©pœ 9U®ò‹ºÍv›¬Ý ¦n¬ò\:U­ßv7Ù» x—[u½jòÛæZ4s‰ÃŽˆFº‘çTãü:WÛD’åMЪðèó.![ç"ªª#ÞR,bÄ#•ff)'Åi¹NA>Ò²BMÓtÈÞ"*ÆÂTi›š]äðçn­R ¯¡|d]ûá`,f¬åQFò.,ÖªÜÄfèé‰ÒnšoêVÍv»yû^5{¡Ü¾` •ëzÕÎjuUFUùPå#„#ƒË؃ª}貜hÙ^œðÎL /”Ö©"r³±"9^â%æœ 7ZCö[L;Ž^„º .§ÜÈYø2~!·YÈ&› 2ƒXVŒer¸;1Â5[“®ôRÿ^d|Ëò7DÚã¯Xg«ó8òŧ!M«Èªl¡‚»ÍÔ£ú£ h†CJ&q÷Ðäæááþ¡o´)–i¤<çG´£DÌ8©.½LˆeË\7ÉÐ S›=Ho]ð€f†ÊýE·HOùp,Û—oÚúnOîñ…ŸëòÈÖë:”ñ¶fv´Ýè\¯×’ æÛ¬ýã0”×tkïÈ‘‹Ä ÍÆ`Äñul‘×§| “aôQ5k@ȱΚ ÒJ<žÌ{àa 1¥¿§) ‡¹è¨G=Æ~!›d:ÙC9 pXS•oZý—ÈíR¡n dø'ßjÛ͆|m‡§¾wö¸éÝÜôðç !ÞnùƒÒØŒW„P¯ØÜõ.ë1½_lß]×BSîÀ.Ÿ\÷“‡ˆÉ^Mö®Ž™“vî š+…°16¹a:Þ²22o½PMé¤ÐKSõK…3Y1ÆÂ ÷öâB`9‰ÏæÈYŽc0ÈxÆyæœüõøe³·/ÂA,EñÍíí‘¥Âq(ÞþB o^Æ=1Û{O]‹0Ï>F[ šbçSž¯I  þ ¯Ô­Œé¬DcYL¶’æVdW¤2WŽL)ƒRžîa¼ÛcM¨~ªÔ9rzÂ"o¿WþвT­§iû½}Û»rÙÀf|KÆO¼£m_äl¯Ù½l| Èo¥kñ…àÀk:ñk2Fˆ¦p!ÒâQ¤°¡½Ma‰îuS„׸”'7aÕ×ÊáÓŒ·((DRäSÔâàØßŽ•LVì1£WUé¼'ió«æ5ϲȬl)ûM§ ™ ‰éHGLÌ‚¥È§…fP "Ë>ãiZxŠSÙ‹™ œyQÁ±heÆÃÒ¥ò¾ôP4äúÈÞâÈãÅu\llcqÞûzK?2V}y 3y¾îZ}×qMÇx%tRôøH˜O-³î8¢à0À9©·pJïPšjOQdã‰Õ‹«|%`«lÙôM|lÌ~GDúÏ?ÿ?ÿù«ÈEn7Ù ßÄêÓÐuÃᱯ"¥°æ—}èØä~\Ö~+Â"A‰8§Ja—Ë{fzYÈ‘é<2àJൾ|‡{ˆ¨á—/þý7 WdUo»"gsdªb18ó'RA¾RLö¨÷ KüOâ°r‰ˆR²¨Š©íº(£ŽX›Tf”ÙÄ0•&{'Ú“5eÝðyßw~›gŒg—ØæêJ³ã;¿2 ‹—:ÅúóŒ‚nÓCË›2qí¤Pbñ (2$«A³ßúlgj \§Š”tß)6ä›pLeº´×uz)G.ç#_—œ*éÛ|Ú´Òûáw±ù/þàRoΑÿ%“=ÝÂNÔr7õ$ ¤©Q'˜]d9QÂZ’Q'DZ©t’y.={åÿe §ÔÖS7 ÍÝH›Zþžj½À‡ÆâÈÿí·Î"¨{lú¬ 6%Kh&EÀ¡…òñoà-IRVÈÄ5(§Ì(‹Ø^Ù›V¬…. $àL\4S•{þžî³· U }¿¬×­ee?»"Gù)‚Èwï§Ó!$¹{[ "ÄKðšï9†ÏÓÜblë›H@f| à¶JÑo:e®å4N¥öd)Ë×÷Y'¾„Ñ™´¡ö4=Ù gá»q¶Sgá®e ßÎ"-‹ bä0—Ëát8MN€¶’5>eN8ŸvyB€;¦e™É.]L½qí4®¹•Yr†Ì‘ƒ¤˜é%”ÑÐÈHœœ¢Þÿ\¡Ð÷Š6Ãyézˆü92ȹ™ †9° Î@i7f±ŸµÎØE=Á.¨ €Î礌XÖÇš‚0eÖ¡4' Ŭï)Fƒ¤¶0rzÊ"ßüıÂÖ H-ê‡BïŽð3¹³Èm">XÉì^Â=Å ‚²Æ,ÍÇŠº$‚ Ž4dž² ‰•Š~KYkÒ8é—:J‚&sÈ]I’RúƹMÕX‰‹§ûìiÈù˜Eö10í³Æ74L³š½€»$ G¤áÅtðu…ûM*fJ¸\*kÈ1ê´Á"£¥7\¨ñQÔ Ø%@„ªSFÃÛyu¢=Ù¢(ÍIOXä\û ¹rq€Ð:H‚jç$ˆ*%͉cAƒ„¾:Z‚60 Óï™TC’6P‹šë8ÐD„¶%ƒšnÚ‰$aí˜OÚyͨEÈ »Víì§rçGnd¬–†IÐc£h¥.X(¬}£?˜X.h`n[%Wˆ÷+Me‘ ´Æ,ârLç‡ä‚àyŽãêE“”õŒ”RZR‹õ5Œì,òg2\ÎÉüùéõ×·o¿~=.§.«¡½?RVÄ„Šõ^RÄãJœ™.a´)T,¥°qÃÊÉEÉ"Ñ¡Ì5ÁlR ÊEâFQ"RJÿlÁ‘g×·ðý]`:Ž|GŽth†óíÛ·×Ççå|8Šš[S ƒ †€±ÖT¨>`MÕîR£IqP[Mª½ˆ; XäŽù‡+9å}Oiöh{ .Ç8EAuRænä·káû9,rçµ(0Ñ–OOÃ{’*QQéÔLûðz¶ªŽt`û¦R-\@XPÜN±ùnZ.@­8„ÿÙG [lðD2)Ò _Úමº…/tÍ•¬Õ|—VeoäŽ#·9ÀÁèù‘˜â©ë³ÄdÒì=¤é1²ÇüÈÐð܈"g0œÏG1$ Ó;1qäü˜™c¥D-Ò˜rd•4"ßê÷M=*³FI²@k@¾‘,òú|‹œ¿óÎ"ÿ O¡~Ú…n¦ S›§Ñ¼¸ë„@ ²î:H.—ÏËÑ=ªVǼ£oÌ»NË*õÉ õE¾kA&’yu®€rÀkQÙ\/=äÂ"¯Ï2:3òj¿„£@>ð’öî@îr-ì6ïCá)ŸW³`g(4iV§oM¦#hc6pÄ”L~Kª­öh²b\tá«ù‘é420¬ép8q [»Õ7±?Z#=ÕÓÓ@¾~dä¶“=­[Þ˨†ÖâÿlwÄ·#×jg‘ßÁýæùæ€æç'ÔG~Þ{IÑ̰?ËPއIDATx›“ù|2mQMt…iúºçåúÑ”çESRçSH"V_Ç®î󩣃ãÃ×ÌÓ¸¼±–“=ÞT½ ó& çÜ"ç‡8ÃTä5wG®5ðÒSyÍúw¹9ˆ sº|zý–çß@ÙýÛëóС–B±+Se)q¢° žt×u˜':KRI­?ºßœþt8ô‰­|&¶^—Üoh•ƒ¤”Ïùf“=„J軬†”D€ÈZ È»,Bi¶kŠ­5Y;ˆ+Úº³ÈWY×毯óÓ½ŸÎ—ËåƒmÈhÛ;æZ3ÜÁ oc(Pbs1“†Ê~ZšŠhgÑTDK’¢£µÈJbœsà+SB¾Êw‰\‡9e)Ÿí€¼ÝÎ^6³ö@γ2tðL^»äÓZ…k´Éüå _d¢M Z•°.p¥jûÛ¼-;?ò‘$zz"ÖÐQr¥×ïû}Ó5ish/¡¶À9áp`xàа&Cì•Êû¢&Üû†X¦"1.¸^, r¤E8$ð\2Á,Ÿž—–;!__ŸŸ—Ëùh4¦I¦â·2J­ç7›õ…Ñ„åmmÙˆS» ä¼d\8}F)ÙJ³“\šUV:›¼yd\¤z_È€É>™¿¥´˜.–kÊ}—ºsA©ûU»‘o>ÌÁx>/Éj¦F3 Ý§´œ”Ç3(G‰SanaåD·_1æd{£‰é°iòx92ÅmcÒP¾ZòÕNB Ème¶ÏU5 [ìÆ’“YØ.€e £H·ëT!ÌllÑ®†9.@Í1t‘éjä^Èš°ï¸|Ù`w~ä‹€ Æ$íp Œ×„Ö¾ @`t'd>6ì£åããó{"Ë®eê4[ ‘xbNÁ2Õ~ù?¤.P &q¢Ež@&¿9ȼoQ„qÈüÓwÌûÅ$NYä ´'ÛíÉ)^œa‘3%ïñþs!t"ºÝKó="²fS‹Ì8€-€Œà¥HßßBc^ìl xß`‹$Šy™ºH@Î{³¬©W]—kq¡Ôõ¥Ó!TˆDM­¤ýz‰6ú4Šýí×Óã’,àcWIª¤"øyýĘ́“ nh‚GÔeAæç``éQ©ù)ó¼õ™ÃÂt‡ø`bâ·o@Ø®÷^’¶òMØÛs‹œ´*uʳÍåP@gSV›õŸίÈÛØiŠ@4Ý#ö—CgEÎIwK wù˜EvÏyý Lùé×/LêþýhI¨êáÄêuÂ`O û\%\ 1Pj/!ؘPçÝëú²–ÁRÙr|[¦ Æ‘ Û~=Cž¸d9ÄòòüM\ÃÎ#Ö|>ÿ1š ÉÔÑ4˜K«¨\H;“òšè|{͇¦³\Ž& xè>˜®k$>x@&Úr: r6µÐ*1Šsº °.¡¸k\HSCtzàƒÛÌUûv–ÓUåŽjÇ‘¯´ÈÏO¯¯èøÂj#s³­ùpö•@ZÇ™˜äÉÀôSêTK<˜ ÜJH fw t츾;\bî†CY²¡– ¯êˆðædÆýt88÷“9±þLRB߇±Q|xNRˆ ´p¿Ç‘%´wÉKùº¢¾üG΄·„S‹2­é,òeî7!“;…ãÈš ‡ËpúÊàóáâžn@žî£™ {™CÓ©eúXÞ@’§£ÇtR0À5<ºÂÕèOçËѰ ‰!PypÝïƒG öd8NÉzK‘odu@<|:p¹&h+ ßžd”mÇD ðZª‡È|™×b¬e·Ú…e5çÎßl²×åZ9À#Ç ÷Õ zz XçLŽà{NïF„C<: \ú 9V\G:6.£ù—þ²¢B¦úý!ù²X>—.b^ zˆß‰ƒMtÚýM`j8§î (Zñ.UtÛNöòÙžú‘™uìÍ âíL=6ngÊ1Ò¡ÊT!R-z‡³‰a%))+EÇsÛî,òÙ£»]½f¨0¤Î;îdJ®ìíð­ØÇåÓ7 cçß¾ýz}}%s»å°ïhP‡}Ýw0>ÐðŒùͰ•*¢+A©Ž:b¯Ap…)(Ò|dHÑÇ$&ÈÀ‹’öÉV]ٳˑ=t¿‘ŶÖF€aÉE¶mãÈYdO;¢¦gº\‹7²eèîÃÃüÇ h1AçãüÞ»ŸŽFàP³hÉ îðé‡ðÓóÐr¬~ÿa´$×~ä$pÁù@¦‡»0F?b¥‰)m¦…rŸ>æn0¯EŠ^‹Aßr–b%{IуÏ`ºã'&{çåx®…œë†C™ÝÁ72À›ºßfØÅ>Ï´±Â O¬mˆs?[DöØÖÆmE9¢¶÷»¼Ëµx ÷‡?Uñ¯×ÿ÷ãׯo¯KòãèÁa²‰ÞŸ??þ˜?¸Ìoé†ïëŽyï:Бɸ¿X’Y#¤ÏÒûHv }çôüÎP'=AÐ¥æ9}bó-?±ŒÉÀ2QʈÅP òU¦‘ð³BÔã³,òì7[ò­ÖëÑæ  qV˜ Cš˜Ïkr€¿¾¡•]NMðué“98”‰…ŒÎ¹Ã¤¾}gŠ¢Âš\ýý(öh­i‚Í™úˆo9s˜%£ŒØv=˜HdfA`N;Qp ÚsV2‡$/òD¨¦­E&H¾ÈöY@ÞgUn`ÿ#@î¼GÐ!Ø…$Wês€@ÇÈ!FòÇ|D ÍÌ!™bFÑëë'òÂ1ãžaMqS'ŠÜÁ"Ýd’øIž£á½k°V‡¦¾¼ÍY\t‹}§?ô]ÉצT¾µk®œ™Xÿ~-Ú)T¼V:Ž|©ãíéñ*@^æO¯¶£‰u”žŽÄTÿþ=^в‘üÀPùd~7'<`2èCDÐ<ï;èÎp´özÒ7¨‘Dc0ÌÂRôuZؤ”„- Ü‰vb=Ÿ#¿£dÖ;wrî,òE@†È³·-WŠ¢ø¶k !KâËè5v ?ª¶ cÒiÌÚIR¥{ÇšL 6 4pÌõSˆv'™!ÄÁSâìcê&Ÿ`}DˆyoÒqOHΈ–IŸ]ÎäÈ@¶ÇmœiÈ]®Å‘h.ŠË=ƒè‚K B„Ž+¸Õ¥¼yÙ)fɶ4)žÁº;(¡Ò=¹¥Í»ÇßÈÃÙ Èàâ_pïé /ÎÖQÚsd.bëeØ×ä‰jŠá Àà‚üòoÓ¹ºÇ92õ³ñµzˆ„òE¡Õ/dòìÃó’{Þ=:­¶ñmHS¦&X´„Lyoô¤†]¥Ò ÅkZV7LS!ñ–6|Òô ‹Üè~Ã2²yþ:Y\w´òij’ýémn&O¨ëÓć´Ü… ‡’²Á*:$Xñ'°sXJ[î¦rÛšx½ßzÊÛñ5˜q©ùoUkë]üÈŸÈ'üÈ@Î?á8 ÈŸú[rä@þHCkäp€<«@žqÃ<ËØ¿m槦´ì·}Þä÷¼·±É3å}P;ïí«° äp‘3œÉ¹MëÓüòWÇ¡µ“×È‹8òø% ÷ö8ë½¼¨/«³üÈöžõþ,­ªgmå]$Ô?éh OÉ¿ ¾ŸãPG_UÕ‹9ò˜öwíeÛÍN} ¿ëø'»Wü–¼þ+Y§*9Å·ò)¾È#ßüü‰]b&ðÕ½jgŒOÙ}¼dvŠ{g„¨?ê8äÍj¶Â—?»+¦ ä 9»3ø‘Nñò÷miÌŠ‡'¬•.ðÚ›^îºô´¼|Õ{ÏoÛ'?À Æ¢Å;äšÞWü…ÍŸ¸+)iÎ-¼MG™_ã{½?GŽ[•O¬ö¾dù³ài ]›îX-ü’¯”TwwÑ3þ!T>ÿ3€¬ü. ç´Ð–Ø‚ÐÎ÷· ?ÖÛ“$«Î=´wóS|‰¼Ò"Ë"ô™ Ú ´¢íóL»Ë5m?kó-ÐÂâCh ä,dCm dp–gÅ5(Ëßê*_œgzUÕ¦µØ%sùç,`ñ®Dìs`È1A.Ú™%Zð÷saÒEdªµ/ísxľëŸÿAŽœ…ÿƒRãÿm“½üNÕÄy¦ŸA/×TíƒK?ìV¼Hé_°Uì¿ÿ„“—ʾ¬ìU8üÞöÊ ±È Èßá(aÖ×y-¾–×BùF¥§Xrq®ïTMûwÈ[~”Jä¯ d°ÈûÈ´¹‚F.ú6±È?7UšªEvµÉ^: A ¯Å4h¼Ùj¡ ?:¸ÔðSÜ)?òî·n|2 ðZ¨š†ZÚš­©6ÜÛê'ò¶ò¿ÈŸsœd¨¦éÆgÛS@Þ.øÏB:Û´ŒªüÞ”—¹Ûú¿Û–Û–·péx¹l¨xcÞ~¨ï´ÝÒªûR«/ª/ïvˆêÕ›eço½m}ŠÕ£Öª=Õú^=ð¡¿géûnÉ‘ÙøB/ùl{òÝøc½}ö²mä;Åj†™÷ô‡ýYÓ›ô“e§·¸Zó-•ïÅVèCy'ôߦ•ŠåÕ-þYm€|ú(oÔÕv¶Úm¶3µ}¬wëíjEnêì É*ãÝ&caÌ`&nO!|3èšï×òÃ|¯ëëªxlã£@^ñ71«ys³Û¬Çcu¥ŽkCÃ+ü—ÝÈ’Å ×S›ÖnØÜ¸qòÞå Ó½o„¾0¾~ÐMážñÛ1>`ÄMßÅûÂP;@~tª||ôó¥ Vv˜ ¿¬w7E¦Aa?OŸâ\e@Ë\3 ‹­ñ·ŠcÅ€|ëL†pi/®ªn³Í. ™DâºE†=wdÜŸþ–ÇÍÍ ü²‹‘?ÅÂüߦµo¶·kÚÃMiý¶êMñŠØÑîf×j£§öÉw°£»¸GÀ ŠÞá¿-¦q_lýòò£ãÛåoG,XÝáúe³Æ¼ùYÕ"‹S¼¨b¼¨ ¯« «ŠÂm[yåÏŸ^g²y•ï À®³’­Ï$ÈÊ –VUñ®Ük1ÞoVwpÃÖØg ¸ôÁ <èUÆMiHÿãÂòK7µµÅöŽbâÝÈ»åoJZèô6Ûî³:J{©=}sá¾z‡°'6|ÓøI7¼ãÅ! § zŠ3r¿§¸×í·~·‡?qô‡/~lëaãÃÃT ‹¼“œo~’V!£‘U7ãt÷p+}¾Õeñ“º¹W·áÖ{ÏqÃïÈïmõcíõêçì-÷MÆxÕ‚ž¬`©,o6ãí! #ÂóÍŽœâX>Åa«wsÛ+§?û¬ò6³–Ç}[ÿg½®ÇGŒ‹šh›'\£ÜWëpoŸ{ÖO¾µ7·½¯<Æ<¼|jØ{‚È͸6™bj†É-§˜l¯½ÓG¸Ã»áwöþòsE6µ#‘8ðZ|ß6ùâÈ×õ§½'@þÚHùè@ÎìòøiÓhruhû äÏ& ‹Ó|ð¿WìýâÝOmŦz{û'Ù £Mgù‘÷áX¾®­èlÅù¿ìÉ£¾C—Ã꺫ƒ?‡¶»:´ŸÕémžþ¹f\²¯U›îäçÜÞýV>Å+q’Ù»_•?ÅcŸ}ãÁ×Nóê¢ÏPÛ:ÏñµÓpåvÑbÁk^îÆ[Žlqî)>zòÅ<¶d›¾¨¼ 6¹XTW)ïõR wãÃïþ‡Œ?þZ\älÿý«x¢ä ÿñQÄ%†êi|µq½æMÕ^jZ;kþÍ*[8²‡Ê–²ƒÛ<ú+m¥Å¾¾ƒì¼½µØgmÕ—?ÿ&㿱s¥"WYã™L-bTáå¾ø7ú¿L¸<¤•ŸÓúEë`õMûCN"¢)¹x’kƒö’€¿‹ê+âL×§‹7áo9¶?^þ ‡ör€Z€¤7¬VJºÕÒ#yg³ãƒYXÝøÝ& \s¿okgQ)f¥vºñ™ äš­Z­>Æñ1 ÿþçŸß9›aÛˆè¼EÞvù²±X¤ð“®Ô ²Ó¢Öq“7]‹ñr¬´:³Åsô^K•ÆS¼Ù”þMñ=§ix|±í–ÇDN}`c¸Í"ãIË–û“ ˜Yä?ä\UÒ,K5òM…ÃqHЪpØ*él–îWô¥TQÛ¹ó‡\d©ÖþhXP§iÚV[ÿ¿Ô)<^G[kh<ÈÂ[² .V2;ÅÁ'ÚäÎ7˜%6àì«i¶#¯å©MÉ´ÔB-ÉÒ¸ôNÈíß-ywÚöE6-Ìh\á˜5¾U ßüV Æ _1|î·Û ÛÔ¶Åö$jñµÈp4ÙL#‡›ífðÌ,ƒ£—2OÚgˆ_€ç?p¿mòp¾øøÂï{¢î€ü%Fä¿ÿþ4þûçºÑ<þû½ôïßåñWí™ntã#ÿý³ö ò_ÝèÆçÿ`a/ã‚ejIEND®B`‚snd-16.1/pix/2pole.png0000644000076400007640000005211411147553266012677 0ustar bilbil‰PNG  IHDRT^Ú çÓsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ x­a IDATxÚìÝy\éÿ?ðWû¾'»6Ñr"Ù¢"û’%Û4ÕYËØše#ÆNF»¡>YÙ† ¥’D¨ˆRi?§sÿþðëþ:Î9mr´¼Ÿ‡Çùîë¾îû\×Ýû\÷v]R Ã0 „òÕ¤© !„*!„P@%„ ¨„B¾. &&&V«°G!%%…j•BU”k×®aøðáUmÛ¶aÇŽ¸wïÕ,!¤É‘­*CNNÊËË«,( ¡¡¡ˆÅÑ£GÑ­[7å7oÞÄ… ª,gðàÁ0`¶lÙ‚~ø€)S¦àôéÓøðáƒd+HV^^^ì~|®G7nE„êÔñãÇã×_ýê µiÓ}úô»|Ĉ555 0û÷ïGß¾}qïÞ=x{{cûöí°··‡¥¥¥D+ˆÏçÃÏÏ&LZ–˜˜ÈîwuéééÁÓÓ“­ÓmÛ¶aóæÍرc„4ö€*Jqq1ø|>TTTª½Ž±±1Œk¼­Ö­[ÃÑÑÝ»w‡¶¶6dee%ZA à[·nhÙ²¥Ð²¾}ûŠ ´•ÉÊÊBPP@çÍ›ooïZÿPXXX`ïÞ½i222PRRBii)¸\®À2ÈÉÉÑ‘OÈ÷¨Ož àp8ÔJ €†††Ðµ\q=YGGÇJóôèÑ<OìòÕ«WÃÞÞ^äYŽššJKKktÔFPI㤠  ö&_…ØØØJ—ûûûcóæÍBéòòò˜`nn¡t}}ýj½HHƒ¨Ÿ‹‹‹ƒ»»;TRc àr¹bŸNØ·oJKK…Ò?~üˆ—/_VÚ3®ªwM蔟FÅÜܼÒåS§N™ž““SéóÀóæÍCVV–Pº‰‰ öìÙCOêoõÉ“'ÐÓÓƒ¦¦&µ©rssEŽk‘œœŒ3f¥6¬Òg²õôô -M#hR@ý†ÕØØùùù¸}û6LLL¨…Hƒ.òæÙç=^EEE4%%%ØÚÚRåÑ)Í~é:$rÙäÉ“C-C¼aÆaذab—ûùù¡°°PðRV÷îÝC×®]agg‡Ë Æ C‡¨r)  öFé9AÒÔ¥`éÒ¥ÈÈÈ€6n܈éÓ§³ƒíß¿ÙÙÙBë­^½Í›7§JmŠUCCÓ¦MH›>}:µiòTUUñ믿bçÎèÝ»7–,Y‚qãÆ±—Äž>}*0(Ñç?¢Ò-,,è†Yc¨UÑÕÕ•ø0}„ÔZZZÐÖÖFzz:LMMnØš˜˜ˆ¼·>Ÿ/”/rhHGGGxyy ¥kkk×x5òÙÙw}»)õÛo¿ÁßߟZ†o(,, AAABéýúõùØ™ÔÕÕ©âb•òm9::ŠSáĉ¸qã†PúÇÎGŽ SSSªH ¨„qÆñãÇ ¥Ÿ?999ìçýû÷ãíÛ·"Ë000¨“i“( B¥/çN{þü¹@€ýÜË—/…&é€Ñ£GcÙ²eP !äs†††044¹ÌÚÚZä 3§OŸ¸Afnn.òÑ1àÓ[d ñš-TBH’’’‚‚‚‚Pº³³3œÙÏ?ÆÂ… E–Ñ»wo‘O3888Ôë×Ñ) B¾ œ:uJä²Ó§OãÞ½{Béqqq"Ç?ðóó£€J!¢899‰$üÒ¥KøðáƒPº‹‹‹``“•­Ö\hP !MÖ!CÄöv?ÇãñD0Þ©S'9r„*!„ˆ#êm°‡ ¥=zôH(¯™™V®\)”W[[-Z´¨Ÿ5)) =¢–'„HÄ—c,@çÎ…OLLPÛ·oÏÎú0vìØj½/±€š““ƒ¤¤$jeBH½¢¤¤$ò­/)))6f‰'á»ÔÞ½{£wïÞb—¯X±‚Z–òM%''cÉ’%izzz"§@oß¾½Ø‰¿{@%„oÇãáË1ž¸\.zöì)”×ÄÄk×®HSVVFÛ¶mëd_êU@ÕÒÒŸÏG^^444èH!„xòä Š‹‹Òüýý‘žž.&''Wé„‹ßJ½ ¨ƒ—Ëŵk×0fÌ:zi¢îÞ½‹””¡ô;wî ??_ m×®]hÓ¦M½Øo:å'„|×ÀyæÌ¡t%%%ÈËË ¥/_¾¼^OõB•"ؾ}»@š……ììì„òvêÔ íÚµkpß±ÞÔ¡C‡ââÅ‹tR}9k+ðé:§»»»Pú Aƒ(¦®®FSõ6 ~y‘™òýÄÇÇ£¨¨H(}Μ9Bi¦¦¦ßå†TBH½rëÖ-$'' ¥?xð@do4**Š**!MÛíÛ·*”®¥¥eee¡tèééQÅQ@%¤i*..9XYY‰¹É­[·¦Ê£€JHãÀårÁãñ ¤¤„¡C‡âÈ‘#ÐÕÕEII‰ÐCퟯ3`À4%%%±8«¨¨Ôë‘ï) Öð—óþýûTû„ˆàà`xzzBSS]»vÅÑ£GqíÚ5\¾|Yä:ßëÍ RêÇqôèQª}Ò¤áðáÃBéùùùPWWÇÑ£G±aì_¿GÅðáñ|ùrª¸zLŠùrTïµ#RRpvv†‰‰ ¬­­±|ùrúÅ%Âü'Ož¥ËÈÈ }ûöBéBÓ6ê¡Òèq¹\Ìž=ãÇŨÂĉ1nÜ8¡tyyùJ‡´$PëDnn.444““mmmj%"¥¥¥ÈÍ͹lõêÕ¸qã†ð¬,vìØ'Nàï¿ÿ¹®†††È÷Ò T‰ððð@\\ D7¯Hedd ¼¼\ä—111bƒfJJ Ž;&rÙ²eË„ÞCÿõ4 ò“o*==OŸ>…ƒƒƒÄN¿O:…üü|\¸pAäv322Ä>zdnnŽ«W¯Rà ¨¤þyöìfÏž;vÔYP=sæ .\¸ r™´´4:tè€÷ïßcèС"óÌ›7-[¶¤Æ!PIÓ€„„„Tp¹\‘ˆ "r$#àÓ]ssssdeeÁØØ˜*ŸP@% SYYÞ¾}Ë~ÎËËC@@rssáïïS§NÁÈÈ?ýôS•eݸqCì”½ŠŠŠPPP¨t}555jB•Ô?áááÕÊ÷æÍ?~\ ­sçÎÐÐЀ©©)öìÙ---z¶˜P@%O`` ÊÊʪÌ÷y¯³2úúúb¯mΞ=³gϦJ'P‰äœ={-Z´@=j´^dd$öïß_£uìíí«5³¬5 !Pë§ÌÌL¬[·[·neÓ^¾|‰qãÆaøðáÈÊʪqoÎÖÖ?ÿüsÖéÒ¥ ddd¨A‘d@ÍÌÌÄСCñðáÃJóedd`ܸq066ÆÖ­[¡««[«Z±b=zàÓ›+Ïž=«w•6wî\Ìž=¾¾¾5^·E‹ðõõ…¥¥%›Ö¶m[üóÏ?••ŸÏŸÏ¯Q™222““££™úP÷îÝ‹7oÞTY‹‹ Ο?ØØX`Ë–-ËSRRðøñãJËHOOGXX²²²pýúu<~üXäàß[`` ¼½½±nݺZ­_XXˆÕ«W ¤]ºt‰ŽFBê)GGG±Ožˆ ¨7oÞÄíÛ·Ù–––9r$–-[&öåšÈÈÈ@ttt¥ynݺ…[·nø4_w}5wî\;:!¤qùøñ#TUU«Pµ´´`hhÈ.¨í)»8}úôAŸ>}Ä.?|ø0Ö¯_/ÑJZ´h‘Ä·ùîÝ;8p‹-’èvãââðàÁLœ8QbÛLLLÄÝ»w1eʉ~×ëׯ£¤¤Æ “èvCBB`jjŠ.]ºHl›Ç‡ºwï.Ñïº}ûv899‰/á[Zºt)V­ZU­Þb]©É´ì^uêÔ :uªÖJ3gÎDbb""##ël§555áââ"ÑÆY³fÄ·™––†ˆˆ‰o·Y³f(..–èv###‘-ñïZXXˆ‚‚‰o÷ÁƒèÓ§%¶Í„„X[[c̘1ý®gΜÁðáÃÁáp$ºÝ7ÂÙÙY¢£wV;¯tU¼¼¼ÀçóáææÆ¦ñx<ðx<¡^ÁèÑ£qìØ1lÞ¼™Î!MN•ýæ   ¡´}ûö GfiiöúgC1xðà&ÓÐzzzèܹs“ø®FFFbG”jl8N“š¥tàÀ––®·ûפŸCÝ´iS“ù®5¹¤ÓÐõï߿ɴ«³³s“ú›­í“5’" B!+ 6¥·vêó)K]’’’j2ßµ¢]¥¤¤è»625‰MõfÖSB¡*!„ßá¦ÔüÒÒRüòË/•æÛ´ij<è!„|Õ«W£U«Vððð¹üøñãˆe?÷ë׃ ’|uË–-PQQAóæÍÅÎak×®EóæÍ¡¢¢"4&ù¶îÞ½‹£GRE4G­×¯i74K—.EÇŽQVV†½{÷ŠÌsîÜ9èéé¡W¯^èÕ«—ÀÛb ¨±±±èܹ3zöì‰ÿþûOl¾ÿþû={öDçÎ~ È·õâÅ aøðá5ZOÒ¯x~oåå娲e ,--ñäɱÇzÇŽaii KKKØÙÙ‰-ÇãÁÏÏ–––ÈÉÉ™'""¦¦¦lyoF >AAAxñâÀuàöíÛèß¿?Ú·o/v0'yyyaéÒ¥ˆˆˆ˜¿ŒÆC%¬„„´hÑZZZ€øøx@«V­PRR‚V­ZaÜ»wЦM´lÙ¯_¿fËxùò%455¡¬¬ÌþêëëCOOOä6ËÊÊØ¡!ŒŒ ££ƒøøx´nÝ)))066†¶¶6Š‹‹Ùýiß¾=»_º˜˜4+++””” )) `jj EEE¤¦¦BSS/_¾„™™TUU‘››‹§OŸ,,, ¬¬,rŸOœ8ÂÂBÄÅÅÁÒÒRä´.¥¥¥033ƒŸŸ»âüñÇ044¬´¼ÂÂBØÚÚbÖ¬YÀ¾»¯¥¥…-Z !!tKÀç=×S§NaÕªUøí·ßêG@½qãž?.ñ4ˆ0___?fôíÛíÚµCqq1&OžŒÖ­[cçÎCCCvKNNÆ_ýÄÄÄàÚµklôððÀµk×PZZÊæ1bΞ=ËŽrÖ±cGL›6 ÇÇܹs‘SSSLŸ>ÁÁÁ¸ÿ>ÀÜÜS§NÅéÓ§öäÈ‘ì¾EEE¡mÛ¶8tèBBBØ1v;uê'''Œ;...HMM…••&Nœˆýû÷³½’.]º`öìÙµ~ì«Y³fÐÖÖf÷§OŸ>˜³ Õ†¢¢"L˜0ðÏ?ÿÀÜÜ:::By%P]\\püøq0 Ã\»ví±cÇþ0'OžŒ}ûöAJJJâ\A³fÍÂêÕ«abb‚˜˜´iÓÚÚÚìµ$kkk”––ÂÇÇÊÊÊ3f ÌÍÍ1bÄŒ;–í9òx<äææ ¼Êãñ°uëV6ˆOš4 iiiàóùèС|||ðã?"==+W®d§.--Eyy¹Ðé±¼¼<öïߨ¨(ÀÝݲ²²Ø´iûFQqq1†ǃüýýŒ÷ïßãúõë8þ< k×®˜9sf­á066˜–ÆÒÒò«ªµµµPy4|dÝóòòºuë ''‡Ñ£Gøt“*33“ ¨ظq#¸\..yI4 6 šššàñx°··,Y²D¨w:jÔ(hiiAVV½zõ¢V–eË–á·ß~òeËÄæñôôĸqãØÓ{àӃσ B||<ÒÒÒ`mm 999öΧ™™Ú´i//¯j퇖–F%¦¢¢Â–gee]]]‘OŠ$%%áøñã˜3gôõõ‘ ---vÝ=z ¤¤íÚµƒƒƒÀÕÕiii_UwW¯^ņ °jÕ*ôèÑIII¸xñ"æÏŸ_«òŽ?Ž}ûöá?þ@ûöíñï¿ÿ"%%“&MÊ[U›‘êsvvF³fÍ ®®Žnݺøt3ýó3«Š8–ŸŸ===ÁáBþ¿””ÆÙÙ™)..f†azõêÅ$$$0S¦LaV¯^Íœ;wŽyõêÃáp‡Ã´mÛ–¹téÓ«W/†a¦  €ñ÷÷gþý÷_&))‰Í"v›111l¾ƒ2eeely Ã0S¦La˜[·n±ù®\¹"²¬ÂÂBÆÄÄ„iݺ5›÷Í›7Ì… ØÏÿý÷óæÍÆÉÉI`]Çœ233QRR‚¼¼<š¤ÒxjRRÜÜÜ„æúr$ò5kÖàÉ“'——¯õXšöööàr¹ì´¸Ïž=ÃÔ©Siš\BHã8寘Ççs"óúûû×ùÆÆÆ"22666ÔZ„†ÝC•¤K—.aÏž=i#FŒ@^^¬¬¬™™I-F¡€Z¹¹¹xûö­@š––´µµ±yóf :”ZŒÒpOù냊Ù-ûöí‹ëׯ£_¿~Ôr„ê¡~7âæÍ›8wîµ!„ê×——Çœ9s˜˜ˆ°°0j=BÔ¯¡££ƒ3f 22–––B×\ !„êø|>ž>}*r™¦¦&Ö­[‡¸¸8888àÙ³gÔ’„ ¨âp¹\üøãUæëß¿?¶nÝŠ±˜B$á»ÜåÏÎÎÆæÍ›Å.?zô(ÜÜÜðçŸb„ •–µcǼ|ùGŽÁ“'O0yòdPËB$NŠaFÒ-,,Ä•+WÒœœœ>ÇÅÅÁÝÝ÷ï߯v¹=ÂŽ;PVV†PëBUEE£G¹lÁ‚xüøq­ÊíÔ©V¬XŒŒ XZZÂÅÅÞÞÞEEEjmBÈ7UﮡjkkCEE¥Öë·jÕ ÝºuC\\ aoo{{{ܾ}›®±B_UR\\\àââ˜5kTTTЩS'ŸÆÐÑÑ¡#€Bµ¦víÚ…ÔÔT„††øôÖÇðiV‚!C†ÐÑ@¡€Z]FFFðññüûï¿ÈËËðiímÛ¶ôõõ±sçN:2!P««wïÞìÿmmmÙàš––KKËÿ« YYܸqC¸âde¿êZ/!„j£¤®®uuu@Û¶mf'àr¹"§ÄÖ××ÇÏ?ÿ,¶L‡Ã–I¡€JÈÉÉáöíÛBé©©©X·nØõ:vìXíÙb§M›V­©º !Pk·c²²ìõÎúÈÈÈ»wï»üäÉ“HOO¯VYÞÞÞ¨Íû X¿~=Å„P@­\ňR Õ¸qãª÷úõëµ ¨eee0`@ís›6mpèÐ!9r„}ÓÌÐÐ{÷Bj@UWWÇÅ‹›L#Ôv†aÐ¥K—:Ûׯ_ÃÒÒnnn¼xñBà&]}¦¤¤„7",, JJJ°±±ÁÚµk‘““ƒÑ£GcÞ¼yôOjLSSrrr 7 Ÿ___PËBšF@ÕÑÑÁ¯¿þ*¶jÕªZ÷vׯ_¾}ûÂÚÚš‚)!¤iÔº2mÚ4<~ü!!!H !PkãÇxýú5ŠŠŠpöìY4kÖŒZ’Bµ¦²³³±wï^Ôj„ ¨5UZZŠÄÄDL›6 #GŽ„ µ!„jmhkk#//ñññhÓ¦ µ!¤^«w7¥† ‚Ó§Oø4*þ®]»PXXˆÎ;SkB( Ö„LLLØÏÔJ„ÆsÊ_XXX­Â PTTT';&//°°0j!BHã ¨IIIèÒ¥K•=~üNNNðòò‹/¾j§:vì%%%´hÑ‚ZˆÒxNù/_¾Œ‚‚‚* òòòBhh(bcc±mÛ6lÙ²E`ù£GرIÅIMMÅÞ½{allŒK—.QëBêww÷j©ÌÔ .ŒQÚ½{w¸¹¹aΜ9øóÏ?¿z‡ÊÊʪ¼tðßÿ±“åBH}ñã?Ö, vìØòòòì‚–-[ÖéuëÖ Ýºu»|ë֭سgD+iúôéßæÛ·o±}ûv¬^½Z¢Û‰‰ATT<==%¶Í¸¸8ܸqsæÌ‘èw Gqq1ÆŽ+ÑíîÝ»–––èÙ³§Ä¶yðàA˜˜˜ÀÖÖV¢ß5 nnnåÍËË ••Üýô¹sçÖü”ߨØÆÆÆBòóóÁãñ—— €³³3âââÀæÓÐÐ@nn.Š‹‹¡¢¢RãVUUÅÀ%Ú8ßc›iii ‘øv 33S¢Û•——GJJŠÄ¿ë‹/PPP ñí^¾|VVVÝîÍ›7Ñ©S'‰×½{÷ÂÆÆG¢ÛUSSCÿþý:ßZEÜ«Ž*oJ­Y³Í›7Ç’%KØ´6mÚ }ûöùΞ=‹ àÆï}BH}Pe¿ù÷ßJÛ´iÑê86 IDAT“ȼgÏžmp×EšŠ6mÚÀÎήI|Wsss”––6‰ïÚ³gO´mÛ¶ÉÇ&L€´tý}ÁSM˜ŸŸ_“ù®¦¦¦055mßµwïÞM¦]GŒѤþf/^\¯÷O„BW@m*#ïËÈÈ@[[»I|Wyyù]ÐoèÔÕÕ¡¨¨Ø$¾«––Vµ#j tuu!%%U­¼R Ã0ô»B!tÊO!õ†ÄoJýöÛo())A@@@¥ùüüü ¨¨ˆeË–Q+B$fþüùh×®¼½½E.ß·oîܹÃ~1bœœœ$ßC]µjÌÌÌ`ccSéݺŋÃÆÆfffXµjµ°Lž<\.—*¢âr¹˜ŒqîÜ9”””@FF999HMMELL ŒÁ0 >|ø€æÍ›ãâÅ‹(--…¬¬,rss¡¥¥% -,,‰ÔÔTAVVùùù——ǵk×Àår!''‡‚‚ 4Hèû_¼xÿüóx<äååQXX‡¯ªÓ   ‘Ûú\pp0^¿~Í~:t(:uêT­ò=<<°~ýz¶½¬­­|£K—.8yò$ý=Õ¡#GŽ   ³fÍ„……¡[·nhÞ¼¹P^‰Ô™3gbß¾}(//gGp ƱcÇ€¹sçbÓ¦M‘‘ÁÌ™3©E%¬ÿþxüø1üýýáââ|üø™™™àóù¸|ù2æÏŸcÇŽ!>>ýúõÔ)S°wï^\¸pfff““ƒ®®.”••F.ÓÑÑÁ­[·Ð¶m[L›6 iii˜={6úôéMMMüòË/ÈÎΆ¯¯/¬­­qãÆ @UUZZZPSS(OSS“=•wttÄÝ»w±oß>¨ªªÂÑÑDdd$Ž;&2È>^ìñ¡­­ììl6møðᢢ¢èɘ¯0xð`´hÑÊÊÊìP¸a[ÇŠŠŠ ©© ##£ÿ+€!MÞÂ… ™ .0|>Ÿ‰ˆˆ`¶nÝÊÌŸ?ŸINNf™òòrfëÖ­ ‡Ãa,,,'''æÔ©SÌŸþÉ0 Ãäææ2®®®Lyy9³f͆Ãá0¶¶¶b·Çãñ†Ãá0ƒ b¸\.óçŸ2§Nb†až?Îxyy1<ñööf8ãää$¶¼E‹1úúú ‡Ãa\\\.—Ëðx>^`ʨ©©QÅÉÔîÝ»×h¬Fq(0÷Ê—*Ƽ$¤.åææÂÏÏ;vì`ÓÆŒC—¦È÷ ¨¢$&&¢°°°Òù% hhhP‰Š‹‹C«V­ ¯¯Ï¦iii!11‘_•ºRå5Ôˆˆ|øðAàºèܹs1tèP|ŽŽŽ8qâ=zªYR/xyyaçÎi쌄H4 ÃÇÇG`FOOO¬^½Z ߢE‹À0 àììL5Kê-uuu 0§OŸ¦Ê uªÞ ß'%%gggüïÿ£V!ubñâŰ··9ðô•+WÖ §Â& ¸‡JHC´bÅ ìÛ·Oìu~{{{´iÓÁÁÁTY„*!•ÉÏÏGHHˆÈ©~@AAíÚµÃÛ·o‘ŸŸOF( "Jbb"ÔÔÔЦM›JóM˜0 HHH J#P åöíÛÐÖÖ¦)È TB¾FEsüøñÕÊ¿páBüñÇ(..¦Ê#P ©ðîÝ;¼~ýRRRUžîWèСrss‘••EH( RÁÆÆçϟǦM›j´Þùóçáçç‡P% ¨„œ9s?þø#kµ~@@üýý©"ÉW‘ý}ûö-¼¤Îœ}¾j´2UUUL:;wîDxx8† FKF@UTTD¯^½¨öI­1 ƒW¯^áêÕ«000À!C¾ºL---øøøÀÏÏ èׯ¤¤¤¨²IµÑ5TÒ ]¿~žžžÈÉɧ§'deë¦o // 6àôéÓ¸~ý:U4©ÿ=TBjëÖ­[¸sçòóóöͶˆeË–áþýûèÕ«ììì¨ò õPIã…«W¯¢yóæX¸pá7ßÞÂ… Ѽys\½zîîîHOO§F ÔC% _·nÝЭ[7¬X±-[¶”È6ÕÕÕ1iÒ$dff"##žžžPRR±cǨATRÿ½zõ ¥¥¥¸{÷.Ö­[Ǧ߻wÒÒÒ“““ø>µlÙ-[¶Ä‰'’’KKK€¯¯/lll   €¶mÛRã ¨äû***BDDûùܹsÈÉÉAÏž=W¯öU^^æææì~ýþûïX¸p!´µµfù•••ň#¨q› ±ŸHLAA¶mÛ&Æ0 JJJØÏ^^^hÕªUƒú^ 8–ò())ÁÛÛ›ê¡R}‡Fxx¸ÈeŠŠŠBÏ‹ª¨¨ôî¢V­Z ̱ÆãñpâÄ ŽhBÈwÓ«W/\¾|¹ZƒïHì”_OO;w®4­­-ììì0dȬY³†æL'„4( ¨:t@‡*ÍÓ¦MöæÔÞ½{%v¨¡RVVÆ­[·¾é6¾Çƒôäÿðx<±§š|>åååÙWWW$%%5É6X³f ”••«•—îò7`EEE°µµý¦Û8pà@ò·nÝÍš5£Æ©¡W¯^!;;[(}åÊ•ð÷÷T£££±sçN‰ì_HHÍ"[Ÿz¨äÛôPccc¿é6&NœX£ü¦¦¦Ð××¹LII©Éކ_ZZŠãÇ‹]þøñc¼~ýZ(}ëÖ­øõ×_Áãñ„–ÙØØ|óö'5ìR•Ô¥«W¯â¿ÿþ¹Œaäçç ¤ijjÂ××·ÑÏ•+W ßêêêb×6lX•÷õPI3`À 0@l ùòI? ½)uêÔ©:0Zž={†ùó糟åä䄦ø‘““«“YTB Bƒ†ðx<ØØØ¤uïÞ<S¦LÁÌ™3¡¤¤iéú1t/ŸÏGqq1vïÞÍ^_622˜mUZZZìeB•owÊÊÂÐÐP ­âºàþýûÑ¿,]ºFFFßõ©””äää 33kÖ¬ÁÌ™3ëÝhX„*!byxxÀÃÃË—/Ç•+WÐ¥KX[[ÃÊÊJ¢ûñàÁ„„„àýû÷hݺ5¢¢¢¨qˆHtSŠ4ÙÙÙ8tèòóóññãG,^¼ø›?žõîÝ;üþûïPSSƒ‹‹ :vìH A¨‡J>x{{#%%©©©X°`Ž9òM·¹`ÁLš4 FFFhß¾=5¡€J—öíÛ£}ûö°°°Àرc±oß>()) èü5 1qâDlß¾­[·¦J'ÕF³ž’©uëÖøý÷ß1jÔ(lÚ´ 999uRîëׯ±téRüþûïLIÃè¡æåå!$$„jŸ|•:àŸþÁ©S§°wï^xzzBMM­Öå½|ù„««k•ãNRoz¨ ÀÇã ü#¤¶ÆŒƒÈÈÈ¯ê¥æää ((DÏž=©RI­Ð]~Ò(ÄÅÅaíÚµ®Õúiii˜={6Ο?O•IV•ºfii‰ 6à‡~/ :\]]qôèQªHB•àÓ*oooüòË/5ZïÞ½{011††U"¡€JH…-Z E‹xðàAµ×™3gþøãªŒ~ø Ty„*!_9r$Þ¼y#v\ÖÏýóÏ?èÕ«MõB( "JóæÍQZZЧOŸV:çRPPºuë†îÝ»S¥ ¨„ˆcff†¹sç"++KäòììläååÁÀÀ222Ta¤Nлü¤Qš1càøñã˜;w®ÐòØØXdeeÑ(ú„z¨„T7¨îÙ³G(=77.\€‹‹ U¡€JHuíÞ½›í­V(..F\\zôèAD$P_½zU­Â^¼xŒŒ ªURo˜››ãÝ»wx÷î›–‘‘V­ZQå:Wå5Ô»wïÂÍÍ Ïž=«4ßíÛ·xyyÃáPí’ïNSS ,€»»;fΜ Ç¡C‡¨rˆäjrr2JKK«,héÒ¥ Ell,öíÛ‡-[¶,¿sç®_¿^i X³f µ ©S/^¼@xx8ÂÃÃ~~~tœ‘ñññ¼¼|õêñãÇqêÔ)v½½=<==1iÒ$lذ¡Nz _Înù¥¸¸8šI’|sT ¤FæÎ[³€joo/0 ™––Vî™™ÌÌÌÄ._¾|9Nž<)ÑJ7nœÄ·™™™‰€€‰¿;~÷î]üóÏ?X¸p¡Ä¶yÿþ}\ºt K—.•èw EQQ~úé'‰nwëÖ­èÚµ+ìíí%¶Í;vÀÌÌ ýû÷—èw]´hf̘!ñ¹¶~üñGüõ×_}³mâĉ5?å¯TâK¯^½Bii)^¼xÀ!CØçø*èëëãÙ³gÈÎÎFóæÍk¼ÓŠŠŠèÔ©“Dç{lSCCêêêßnVV%ºÝÜÜ\èèèHü»FGG£  @âÛmÖ¬ $º]===èëëKü»jjj¢C‡¿W¢¤¤KKËjõ늲²rµóVy—ÿÈ‘#°²²xžÏÎÎ#FŒÈwøðaìÚµ ÉÉÉX¼x1#Bšœ*oJ-Y²D(mÙ²e"óîß¿¿A}y//¯&ÓÐFFF:th“ø®ÖÖÖ(++kßµÿþhÙ²e“9ŽgΜY¯_nÒ¯žzzz6©€jddÔdjSѯ_¿&õ7ûåKõ ½)E!- ~þ„Ac&//_åãc…ŠŠJ“šÛ¾eË–PWWoßU__JJJM⻚˜˜@Zºz¡²ÞÌzJ!ÔC%„à;Ü”Z°`Š‹‹±k×®JóÍš5 JJJB¯°BÈ·äææccc¬ZµJäò-[¶¼Fïìì 777ÉŸòûøø`ðàÁPRRBpp0vîÜ)2Ÿ§§'\]]Q\\Œˆˆlܸ‘Zù+0 ƒ›7o"** ¾¾¾Õ^¯¤¤ŠŠŠµÞ.ŸÏÇ“èCØ|>%%%——‡¬lÍû <eeePTT¬ôº—Ë…´´t•ðp¹\p¹\())AJJJl¾²²2ÈÊÊVy­®¬¬ <¯Ò‡Í+¶)%%Å^ç\·nzö쉾}ûVºM‹‹ |}}‘’’‚¤¤$øûû å™4iFŽ 333ÈÊÊ¢yóæì›¥=åÏÊÊ‚®®.Z´h·oߊÍ÷öí[´hѺººb§° Õ÷æÍÔ(˜øê¹–nݺ… Hô»&$$À¢V¯öæææbýúõpppÀéÓ§!®¯‘““ƒY³fáìÙ³•–÷îÝ;øûûÃÁÁ7oÞ¬ôxÿá‡]iy˜7o/2Ovv6V®\  < ___àÍ›7ôQE·mÛšššÈÎΙÇÈÈ6l€‡‡6mÚ„¢¢"v]Cm.]º$0ÕGXXŽ?Ž×¯_ãÞ½{lúáÇqàÀÄÄÄ•ƒ´´4ðù|8p¨t ›cÇŽ!<<III8pàÞ¼yƒÓ§O³Ëoß¾wïÞ¡  €-¯²!"+ò8piiilð¨H{ýú5€ÃáÀÏÏOè¥"_eåöíÛÈËËCtt4ÀårEæKIIÁýû÷«¬÷3gΠeË–ˆŽŽÆœ9sÄæ{øð!«,oÿþýppp@tt´ØÙ.\¸ DGG#<<S§Ne— 2—.]¢?ˆ¯´råJDGG#::Ǹ|ùÝì?rä|øÀæŸ1c>|ø€üü|””” ''<Ë–-ƒ““ààÁƒ˜:u**ÒfÍš…ÀÀ@ÙJ}||°téRøøøöìÙƒŸþÛ¶mƒ®®.`çÎðññÔ§¨¨ˆ§áïï_£÷³¿Ô£GŒ9²ÎÚgðàÁèÓ§O”ÕµkWüý÷ßðññz[ÌÇÇ–––˜" ”h@]¸p!6lØ.—˾¾zþüy;vL  .[¶ Ë—/‡œœœDGGjJÆŒƒÅ‹£OŸ>HHH@×®]qõêUp¹\¤¦¦ÂÔÔ0tèPtìØsçÎ…±±18À’coo]]]ØÙÙ¡¤¤„-[GG³fÍBdd$à—_~a—ÅÆÆ œÚž:uŠ ö“&MÂÛ·o1`ÀÓmUUUèêê²åŒ;ïß¿GDDÛS1bòóó…jŠЊéN&L˜ Ñ‘Š$ÍÜÜ®®®xþü9Š‹‹ñßÿÑÁ^6lÀ´iÓЬY3x{{‚ƒƒ‘™™ÉT‡ƒ%K– ++ í۷Ǽyó¾O@µ´´ÄÆÁçóÙ‘­‚‚‚„z§]ºtÁ–-[ -- ===jå¯ WWW‹ÍóÃ?à·ß~ƒ¬¬,vïÞͦïÝ»7oÞÄùóçáåå---¶½*®s÷íÛWd™7Yrss¡ªª ¤§§#99222‘‘ŠŠ rssrrr‘‘ÁàÁƒ…Ê*//góÉËËCFFJJJiÒÒÒ(//Gqq1Š‹‹Áãñ %%…N:±ûlhh(6 ÊÉÉAJJ ¹¹¹ìÍœ‹/búô騱cFàÓMŸÒÒR‚Ï狽‘¤  €üü|äææBEE…½¬âçç‡'N gÏž€ÒÒR”––¢   Ƚi¤  .—‹ÜÜ\¨©©6n܈mÛ¶!22’}a¤]»vÐÓÓÃĉqæÌvýªŽòéìcÇŽ——gÏ~Μ9>Ÿ/ÇÊÊÊ ¤¤ÄžýÒè½ÿž™sìØ1æÜ¹s Ã0Lff&[^Å~ˆ¢¬¬Ìæ»yó&Ã0 óäÉ6íßÿe†aâããÙ´èèh†a&66–M‹­t9ÂØÚÚ2OžŒI“&–/_ŽØØX¼ÿžÍ÷ÓO?a÷îÝàóù8p`ƒ¯777vjXQ^½z%vÖÖ qqqBƒkhhÀËË‹ŽÊÊÊÄNÏ|æÌXYY ¤Íž=Ó§O§#•ÆP%ISS|>yyy(--ÅÌ™3Õ¨*\^^;w¹ÌÒÒK—.H bo¤ÂÑÑüñ–,Ykkk6Ÿžž´µµéˆ&„ªh•M€ÖIKK }ß¹sçbîܹ€çÏŸãüù󈋋ÃÚµkÊæ³¶¶FÇŽÖµ²²‚±±1å„P@%_244Äœ9s|ºŽý¹‹/âîÝ»iñññBeŒ9R gK©;õf )))´mÛªªªÐÒÒÂäÉ“±k×.vÞuRs111xöì™@Ú½{÷ðüùsöóèÑ£+}šÒ@êçâââàîîNµŽeff²sÙŸn„=zÀ§ùÜÏ;)))|yX4¥K/¤ñcU…¾Š˜ôelj§üÒÒÒ011¡–¯c-[¶DË–-ÙÏfffìX iii˜>}:ôõõqòäI6 fÏžÍ\Õ}ÛŒºöôéSu9GÅÅ‹Å.çp8hݺ5:tè€iÓ¦5üjrr2Ôï â’À„ Ø´;wî`ûöí죣£à¯²¬¬@~BjêÊ•+x÷î]•ù"##‘——÷ÕÛ›8q"† VéþüüóϘ2e ¦N*ð~ƒ ¨DFFNŸ>Mµ*//Ǻuë-yi¥´IDAT„NŸŠŠŠØÏS¦LAûöí©²€OÏ^ÿúë¯iÊÊÊðóóCTTΞ= EEEÈÈÈTY–‡‡ÇWçQ]ÏŸ?dzgÏpìØ1L:666õ÷”?##Cìë—}ûöELL …õ”ŒŒŒÐ³²<aaaìçÍ›7###ƒý Èáp¨"¿±—/_"++Kä²ùóç CÑ®]»jÖV3Æêå]þ~ýúA]]ŽøFÊÅÅ...ìç‡ ü­¬¬Œž={ ¬ãîîN÷¢££‘˜˜(–œœŒôôt‘ù¯\¹EEEª¸ÆP+Þ"MCçÎqðàAöó‡°oß>< .øìëë[í;¯MÉýû÷ñ¿ÿýO(]MM ÊÊÊi&LŒ‡4€Jš6---øøø¤…‡‡ |ž;w®À pðàAèéé5‰:JKKƒ§§§Pº©©) $”nff:¸jhÞ¼yؼy3:wî %%% ¨¤qøò)+++ðx<¡K YYY1b”••Ñ»wotëÖM¨,uuõ½ý"Iùùù••èM>~ü?þø£@>}}}ìÞ½[h}u¬q8$&&¢¼¼œz¨¤ñúüm¯ W¯^œ;wÅÅÅ8wî–/_.”ï×_:ýUPP@×®]¿ù~¿yó©©©b—ûûûÃÈÈlÚŽ;êìf¡S~BjdäÈ‘ v’Eooo ¤ÉËËW:nÄ€+4SEM½{÷/_¾»<<<ÉÉÉ3:tˆµ¨woJýöÛoð÷÷§–!õñãG8p@ìò·oßBKK뫟—íÔ©“ÈY0HýÕ«W/\¾|ªªªÔC%¤:ÔÔÔØ¼E‰‡¡¡!;Ý9!P ©%zÑ é «ö)TB©DMžš Qƒ !¤¡òGDDàÔ©STã„ ¨_ËÜÜ\èÙ¿ÏíÚµ‹ZƒBµ:Ú´iƒ6mÚPB-º†J!1 vìØåååHII¡–!„Ô !!!(++kxµbÀ zo™R_V; Òs¨„àÓ %ŸOãò­Œ?^hlWÒxÔÛ€šžžŽÖ­[S ‘ûøñ#;«¨9ÜÝÜÜðñãG´-ZàÚµkß|ßNž< KKK‘Ë6lØmmmìܹS`”,999º¡Kõë :”NýI\½zÅÅÅHJJ—ËÅË—/ñúõk¡|—.]‚ššÚwÙÇI“&aÒ¤I"—ùøøàǘ={¶À¸B㡪©©¡oß¾ÔèP ùzþù§ÐPz?~ŸÏG·nÝ   € & }ûö æ;mܸ‘ýÿ¹sçØÿ¿ÿ^hFQiiiܹsG¨ ‡ƒ#FÐB•ñ¾œ×ÝÞÞ^è4x̘1r4(]]]¬]»V -77çÏŸÊ› 4—¼ƒƒ¦NJQ-ìÛ·nnnÕž°*©wzôè.—+öåX¥fffPPPh²u¤©©‰Ÿ~úI(=''GhëÈÈHtéÒE(ï’%KÄÂM>¹{÷.¦N YÙê…J ¨Dâ>|ø 0|LL Ö¬YÃ~ŽŠŠ‚œœœÀ:_~&¢ikk ŽÔ©S'‘ú­]»Vì ²#GŽõÊäååahhàÓ=WWW8::R¥S@%’ðþý{DFF ¥'%% L7ÒµkWºù IKKCZZø‘óåË—‹œs ~úé'¡'$ÔÔÔ0jÔ(@óæÍ±ÿ~”––ø4V‡©©)Ôï±Ñœœ9sHãräȤ¦¦‚aðù|¡å666Xºt)UT=oÃ/egg#00àáᇃ+VâââÄÎ$+//Å‹S@ýVäääè׬)))»»;ûÙÞÞ¦¦¦hÖ¬úõëGÔHèèèà×_H«ø„„‘ëñx<8;;WZöÊ•+affFµ6ÔÔÔ„.†WUáD2*ælü¼·ñù<Ž\.WhºeEEE™9õõõiî¥&†Ãáˆ&†ÏçÃÊʪÒõW¬XÄÄÄjmëþýûurM]\îܹƒ›7o6Œ€Jê§§OŸ¢[·n˜7o&L˜xýú5|}}Î.èz'© iii˜››Wšçï¿ÿ®vy]»vz ¤¦&Nœˆ¡C‡Š]þâÅ bÕªU°±±©~®OÓH;;;ÃÄÄEEE(((Àرc1dÈ:"¿¡ÄÄD<|øPPP€üü|²xÛ¶m±~ýzª(Ò¨>|áááb—[ZZ¢K—.PTT¬Ñe«zPW¯^¸¸8¸»» Ü &_ïôéÓ¸wïÞÿ¢Èʲ§OÚÚÚ"¯!„Ð)“Vñë{ûöm<~ü˜MïÝ»7ºuëÆ~611……U!P›†aÀãñ ''.—+ðHÒ¦M›Â~®¸>dgg‡É“'³ézzzPWW§Ê$„jÓóÿÚ;û˜¦®7Ž,¥—‰‚ ÅòâðeouN·¹Žàœ‘¡[ºx§téŒdή«ÉÐÅRLFµNqk…!c©ÉØwyq6ëX‚V›ÅUœR25å­ÛùýA¼¿u´P«Âù$ýƒsŸ{žsν÷á¼>ÕjEGG µµµµµØ²e ¾üòK‡Å!•JE‹(jP)wŒåO?ý4"ýÊ•+øóÏ?‘‘‘Ëå8|ø0T*ž}öYÚp 5¨S—ÎÎΞƒÀ×××éP<..‰Ä!-::š6$…B êÔ!55/^‘þØc9u0‚e˖ц£P¨Aœô÷÷chhÈåõ“'O"##Ãé5FƒmÛ¶H÷öö¦¡](”©lPÏŸ?ïÖ|]SS†óTÄh„……p?6‘X­VX,·dóòòF]è‘J¥t!ˆB¡¸oP«ªªðî»ïâêÕ«£Ê•––¢¬¬ Ã`ãÆã:®õo’““QYY `Øý[NN΄Ô¶¶6·dSRRœ:æ¥P(”»2¨v»î¦Ú¿?ŠŠŠÐÜÜ ½^? ÖÖÖ:ÄÉqFss3”J%ŒF#4 Z[[±uëÖ ­ðóÏ?ïö¢Î7ß|ãàôƒB¡LM4["¸£§yyyøöÛo¹ kÖ¬áœbˆÅâ1‡¶¯¼ò gPËÊÊpðàA‡ë‹f³Ùåý±±±ô©Q(”‡’îînøûû»ßCݸq£ƒ÷???—7ݺu CCCãšëŒˆˆ@DD„Ëë‹/vºó~²jÕ*ëlooÇ®]»püøqê­¯¯GMM ÔjµÇt ;Ý&v?),,DOO’““=ªwïÞ½x饗°fÍéÜ·oÄb1Ö­[çѺ¾÷Þ{P*•÷küÚk¯¡´´<Ïc:ÇE–3¨þþþN-ðÅ‹ÑÛÛ‹ææfn>qÆ hnnÆ78¹¥K—¢©© V«QQQã.ôôéÓâчó t À×××ãzÁ0ŒGõB x¼®3fÌ€———Çõ2 ƒY³fyT/Ã0˜9s¦ÇëÊçó1{öìöÍzÒ ŽÇ÷ª×X X·njkk¹´7ß|‰‰‰r™™™¨««Coo/>øà:F P(SŽ1¥œ¹sÛ¾}»ËáÇ£ÄîÝ»§Ìƒ~â‰'FÆ™LDGGß³âG©TŠ9sæL™÷xçÎðöö~t êdf*…]‰D‰DS¢®“!6‘»¼øâ‹S꛽IâaÅ  …B™\õ¿@&+|>Ì€e“…Y³fM©è¶ .œ2Ão±XìÖ6¢É2 pwšá¡ B¡P(´‡J¡P(”cP7oÞ ™L6¦œL&sÝA¡P(ž .. …ÂåuµZ ‰DÂýŽ=ú`†üÉÉÉØ²e †AFF ʽóÎ;عs'z{{ñõ×_;˜2~þþûo”””àÒ¥KÜqbw°Z­ ½k½v»}}}÷Õ{ØDsóæMtuuA(:Ý<>88«Õê6Ú @›Í†îînˆD"—óp·nÝBgg'€aok^^®û9ׯ_G__ŸK½½½nx<„B!4 /^ ©TúPo;zЬ]»ÇŽÃ… P__ïÔ=ç¦M› •Jñä“OB @$qïŠG·MÙívøúúÂÏÏv»}T9??? *Gqk×®A§Ó¡ººzÜÿ©ïÅ=᯿þ ½^N÷È´ÓÑ£Ga0„„„ÆíÒ¥Kˆ‹‹ãN úøøàÇtš_[[²²²`4‘””„õë×¹qãŽ;†ŸþÀð︸8§ù™Ífèt:\¾|ü1V®\9BæìÙ³øüóÏCCC¸yó&Μ9ƒÔÔTÄÆÆbÅŠ …ô£pA?x<œÊ,]º”sš4þ|lß¾‹-ò¼A¥<ôz½ÃžÛ‚‚ôôô 66mmmXµj@«ÕâŸþD"ALLŒC FTT8`Ø!Ί+œêÔét¸páŒF#öíÛ¹\Žêêjî„]ee%–,Y9rðÆo¸ iýßC#[·nÅíÛ·¹{Æ  É'°dÉTVVB&“!22mmm\DX¹\ް°0§:šššÐÝÝÒÒR,_¾r¹Üi/uΜ9œ1ÍZUUæÎ‹ÒÒRˆÅb§µ³³Ï<ó víÚ`xõÜ•AÕëõH$8tèK‡E«W¯ÆêÕ«YYY‘qß~ûmèõz(•JúQÜ*• *• ðÃ?àøñãHOOð,Jét:§!A(Gnn.’’’Ú|pp: \ïH(B(¢®®gÏžuèõÔÕÕÏçã“O>áäÊÊÊpþüy¨T*lÚ´‰û™L&#((€>ÿÛÙ÷ßÖÖVìÞ½›Ë/??W¯^Ebb¢C~íííœÌ/¿ü«Õ BÔj5—®Óé`µZñÑGá»ï¾ƒP(Dff&ÚÛÛ¡Õj99­V‹žžž»nK‘H„;vpù}úé§÷ôl.\©TÊÍÍíÙ³gBžù V«¢F$%%!77—~ãD­Vs²³³]ú‡öh5==J¥v»644@¯×#??Ÿ“ÓjµØ¶mø|>:DŸè}àÕW_EUUV®\‰+W® ::_|ñÑÑÑÁí]¾|9^xᤥ¥!$$ÅÅŨ©©áz…‘‘‘HLLÄíÛ·¹¼ÃÃÃñôÓOcîܹèêêBBB‚ƒqnlläþ>}ú4>ÌÍMÙl6( ‡žÕìÙ³‘€S§NaÙ²eP(ÈË˃Á`( ̘1B¡ï¿ÿ>ÂÃÃ!‘H0}útœ;w™™™€œœ ÜõÊ™3g:Ôg¢Ž[§§§ã©§žÂ[o½5!ù­_¿/¿ü26oÞŒ¼¼<ú»INNX–Exx87ZQQŽŽn*eíÚµP*•hmmÅsÏ=ÇõN=nP#""pâÄ ÿ÷àRPPà`LàñÇÇÉ“'ä(wOyy9^ýu”——»”‘Éd8rä|||Í¥Ÿ9s§NÂW_}…B¨¨(h4Ãà4O???ðx<˜ÍfˆD"Ì›7‹ýõø|>ø|>BCC9?¹|>ßiòòrdeeaÿþý¸~ý:BCC­V˽[Ó¦MÃ0,X°]]] ât¹\”aÞÞÞ0›ÍÆ´iÓP\\ ™L†‚‚ÄÇÇãòåËÐjµØ±c׫wE@@:;;a6›¹8bÙÙÙP(¨©©ALL úúú‘‘±X ‹Å‚ùóç;Í/00===0›ÍÜ¢TZZ>ûì3˜L&,X°%%%øý÷ßÁ²,†A__wÿXïexÄPSS///øø ›Çúúz§vŒâ  ”IÍf#)))Äh4BIMM%‹…ìÝ»—‘Ó§OB‰',Ë–eIcc#ùðù< ‰Á` ƒƒƒœLQQјº+**˲Äd2›ÍFÒÒÒHII ©®®&„ríÚ5.¿;åpÆ™;?«ÕJZZZ¸¿ûí7ÒßßORSSGÜk2™89“É4jy‹ŠŠ˲¤¥¥…BˆÁ`àÚãåÜÜ\²,±Ùl#ÚƒBÎ;çP¯äääQóÓjµ„eY‡çòßräçç–e‰\.çÒŒF#IIIáÊA¹?ГRS„––üñÇwDLy8¨¨¨À¢E‹îÊW1Å}¨A¥P(” ‚=¥P(” âËï¥%9!ÑIEND®B`‚snd-16.1/pix/noid5.png0000644000076400007640000013076511147553270012700 0ustar bilbil‰PNG  IHDRèëw‡sRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ%Àó IDATxÚìÝwXS×ÿð7{Ê”!  ˆ ±Š(ŽŠ£ÚjgkÕªuT­Zµ¸gÕ:ê¨{Õm« U»¬{/DAœì) ²GI~ø5?cHrnB>¯çñyÌ͹ëÜ›Ë=÷žóùhñù|>!„B!„R¯´© !„B!„j B!„B!„è„B!„BˆjÐ}ÿÃÔ©S‘––===Á´mÛ¶ÁÖÖVìnß¾õë×CGG .DëÖ­©V ! ÞªU«põêU˜šš ¦-_¾^^^bçyòä –/_Žšš̘1AAAT‘„òÓ§OcíÚµ°··L?~uttàì쌤¤$F+NMMŃê´ñ•5@I%PÅUíJNJJBee¥Ð´gÏž‰Üœ'$$>óù|<þ\¨LAA²³³é¬Õÿ'OžàÅ‹Ë#33Sð¹¼¼7nÜ@ii)U¨Šºxñ¢àzúã?¢¸¸XlÙääd899 z0ùøø 66–Ñz²³³qûömªp(­|û·ñÝ¿ò*ª¢yž?Ž!C† ,, 3fÌÀ«W¯Ä–-**BEEìììݺuÕ+W­§¸¸7nÜx?L! k :ÖÖÖˆˆˆ@DDÒÓÓ%^ðêbÏž=øòË/ë´Œœày_¦Z•zäÈTUýÿѦM›°víZ¡2 ,ú§¥¥aÆŒxýú5É*ìï¿ÿFnn®Äã?{öl,_¾\b™¸¸8üöÛo‚Ï©©©èÒ¥ âããÓnܸ!ô™ÔŸ¾}ûÂÂÂBp=511ALLŒBÖuúôiôêÕ‹*^ä¾ýÛøî_jÕ Ñ,¾¾¾°°°À±cÇ~ýúá?þPȺ?~Œ.]ºÐ BHý4ÐCBBJµ"FUUÒÒÒ„¦8q.\|þï¿ÿ0aÂTWW •ûóÏ?ÿÏÌÌ„µµ5222$®ïåË—xùò¥àóûoØ·oÍ6n܈ÂÂBÁ´mÛ¶!22R¨Ü‡óöàÍ›7‚Ï7oÞ„³³³ÐC“›7oâÞ½{‚Ï;wîDtt´Ôe_ºt ¿ÿþ»àó„ ¤ÎƒË—/ >¿yóC† *“’’"ò¶ž°¯cÇŽ5jU!„°ÌÝÝÓ§O‡ŽŽU!D³è‘‘‘¨¨¨[øòåËX³fÐ è»n•555xþü¹F‰{õê.^¼(Ô  CJJŠ`ZYY™PUTT ¬Lò+ý]»v¡OŸ>غu«LÛ³gÏdffJ\~qq1f̘!4í‡~)wøða:ûeT^^Ž“'O M»xñ"þûï?Ág‡ƒ´´4ðx<±Ç ¤¤D¨‡…8GèXçåå1ÚÎððpÁÿÿý÷_œ8qBèû+V`òäÉt>(Ø… $¾qyðàæÏŸ/øìíí„„Á¹qóæM G!µxüø±ÄI™™™<,·¶¶†‰‰‰à%ËÉ“'1hÐ ªHBˆê7Ð;wîŒñãÇ ÆLz{{ÃÉÉIð}BB‚ÐÛ9 :aaaøòË/1yòdxxx¨me¤¦¦ }¾ÿ>nÞ¼)2íÝ›o‡²²2Ì›7O)Û×¼ysdggK|ˆò¡üü|‘1ÊÓ§OGDD„Ä}'o{L¼?ăÃáàÈ‘#())Lû°GŇ*** ­­ ¡é .IJeËÄÎ÷ý÷ß yx÷{ËÍÍÛóâõë×HLLDÇŽeÞ×S§NIÜw";???,_¾\p=åóùºü÷ߟÝÝÝñí·ßbôèÑ àAƒ„ÊBùÿû¡3gή¯.\Àˆ#ßáŸþ<ä¶°°À´iÓ°aÄ……ÁÅÅ}ûö¥Š$„¨$¡(îvvvߤ?ãÇšÖ¢E ‘Æžºš9s¦P÷ð™3g⫯¾[¾´´QQQhÙ²¥Ø2)))°²²B£F$®ÛÄÄöööHLL„››"""Vç}:qâìììpêÔ)|þùçÞö àóù÷ëׯGAAP¯‘“'ObܸqèÛ·/ø|>öîÝ‹ÁƒƒËåÖÚÕîÙ³g022BóæÍ…¦ÛÚÚâÉ“'b×   ¡á †††àr¹¨©©©užššTUUÁÈÈHæ}ÍÎÎÆµk× ذa^¿~uëÖщ 'kkk‰½d>ûì3|öÙgøð|ôèQª}ºÐ´¨¨(VnŽW®\)x«žšš KKK˜™™IœÇØØvvv‚(øLè7t}NMMEII‰È0ƒâôéÓ—óàÁ¡‡3ñññضm[ƒ:'>püøq©óx{{ãåË—bͪ`Æ "ûö჈/¾ø×®]»ï%%%hÓ¦PB!„B5ÐåòáØá´´4¡nÝÿü󂃃…~ÙÙÙÏçË%ÝÉÉIj8¶Ìš5K𖳪ª <O®7¨åååBû~ôèQ¡Èã%%%XµjÒÓÓ5â|øë¯¿DRßIë®þÏ?ÿ¨e—¸fÍšIÜ·W¯^ÁÞÞ^â2¸\.ââ℺÷¿xñBb/B!„B5ÐQTT$„«¤¤{÷î•8Ïû]Àß±··ÇCNNàçŸÆÌ™35®¾V­Z…¹sç M;räˆHΛ7ÉÉÉ‚ieee(//W‹}üð!Kdd$¾ûî;Áç 6 ¼¼EEEb—Á4¨Œ•••ÐÃiJKKammN: Åxfûö헸͊ôäÉ¡4€ÀÛ˜\.—®¬„B!„Pý­­[·âñãǂχ ö&ôôt¡ yš"55ÎÎÎ2ωóçÏ«Å>Nœ8QdZbb¢Ð±?~¼Ì‘õk³|ùr‰cã>ôÛo¿aĈ077GAó„Å™™™Xµj~ùåÆó$''£I“&"Aë>dffdee‰-óüùs¤¤¤º÷§§§cÀ€‚Z„B!„Ö@çÖT£’#švìýôEªîøñã"¹ª™8rä¾øâ ¹Öidd$1¼››´´´„±µy?ˆðöMû‡è”­¼¼\¨Źsçpýúu™—£££mmm‘œöÒÖmll¬²çÚ³gÏàââ"u„••ÌÌÌ„R ~èÁƒxöì™ ~pãÆ ¡2¥¥¥*=>Ÿ¢¹JJJŸŸÏèºýþ.B!„èuöâ~š=ÅÅÅBÓŸ?.ô¹{÷î¸téR½m§ŸŸ>|XëwYYYpppy™r¿Ñ2dˆÄ hï™Òrº;Vðÿ””ôéÓG$­›²íÝ»·nÝ|ÎÍÍ•©Ëù;ÎÎΰ¶¶Æƒϳÿ~Œ=Zå7mÚ´êe¢(?ýô6oÞLWZBkªªª°mÛ6‰·êçÏŸ/öo/ð6æÏ?ÿŒåË—K½GØ·o¶mÛ&õïâ©S§põêU:P„BF½ººZèí(œúã”`Œqzz:8ŽH곑#G ¢”_¾|ݺuƒ¶¶ì»&1Ùùóç"2=$$Dæîàݺuõk×XÓ{åÊtéÒ¥Ö”`²¨¨¨@tt4‚‚‚Ó?~Œ;wãñx ;¸\.8ŽÈtIcã«««¡«« --­ûÖ)"ûºuë0kÖ,¹Öµ{÷n¡ÏÒnn !š‡IÌ’gÏž¡ÿþ˜4i’ÄrË–-ƒ§§§Ä4111pttÄðáÃqá±åJJJ™™‰ü‡[nÆ °µµÅ… $EŠŒŒDQQîß¿/ñánMM ë½Ç!„j ×Ù… pðàA±ß———ƒËåJÌ;ž““;;;¹Öß´iÓ:GÄfÊÎÎNæòÒäææÂÖÖ¶ÎS.—‹‚‚4nÜXb¹yóæáÀ ;ž={†!C†ˆtc””¿þܹs ”š›^•ܾ}:u’ùeddÀÅÅ…•zöòòbe_$Bˆf1b–-[&ñ­wQQºví*µ»ù³gÏУG¼zõJl™‚‚ÃÉÉ G¤—Ý;·nÝzÐ,ÎóçψÁƒ‹<ˆ~_zz:ÜÜÜ`jj*±{ý¶mÛ0kÖ,œ9sFꃽ{÷";;›N"B¡ºjøðmùÊ•+Y[¶ŽŽŽFFœÖÓÓ“iÜ´¢mß¾]â1•ÇÓ|öìYAú·7oÞ ++ mÚ´*3wî\¬Zµª^IMM ²³³QXXOOOé?Nmmðx<ðù|>|XæxÕÕÕxüø1üýý•ö{™4ivìØ!öûšššZ{TÔåœ „ÔŸñãÇcÀ€\Ÿ?}ûö…¯¯/¢¢¢Ä–‹ŒŒDhh(†ŽcÇŽ‰½†èêê2Þ>WWW”””ˆ}Ø}èÐ!|ùå—Œ—'iÛdqõêUìÙ³Gâ X½z5îÝ»‡—/_J½ÞÓu”B¨®p•••"ãy£££Y[þˆ#pôèÑZ¿{øð!üüüÔò ®]»³gÏfu™QQQøâ‹/DÆö(00·oß–zƒ#¯Õ«WKŒZÎápPVV+++¡éþþþ¬ž;²Z´h–.]ŠòòrTVVÂÂÂBê<}úôÁíÛ·•žF-..­[·™>jÔ(©½!¼½½%æFß¼y3¸\.îß¿/tó®ãö !¢òóóáãã#1öHFFš6m*uYIIIpuuE‹-Pk™Ý»wcüøñSžžžÿ®>}úƒ ‹/$Öï‚ 0gÎÄÇÇÓII!Ô@gnüøñ CXX"""Ísýúu¡ŸŸŸâããß»àC ì%>vìX’lãóùõ:fúСC8|ø0Î;'±Ü„ °sçN‰ûQ›6mRÊþž8qƒ™Þ³gO‰ãU––VêùôéÓ0`@·#99zzz"7æ£GÆþýû•~L5Mxx¸àz*é7Gˆ<®]»†°°0¬Y³¦Î—hœµx½{÷–úwµwïÞø÷ßÅ~ ooo|òÉ'RÝñù|: lݺUp}]°`U!Dsè»wïFDD"""&òýåË—E¢­fdd 33SðÙÎÎùùù‚®\Ž­CÏá³Ô¦Â‹ŠŠ ¥¥333™æû°QÃDee% åo¯Ë—/ŸÏŠ ~õêU±o·¥½W”çÏŸ×Ú ÝÅÅEjäàú¦*o˜ŠŠŠ ­­-×Xÿú:îêdõêÕ‚ëé„ ¨Bcÿý÷ŸÄž.;wîDDDîÞ½+¶Üœ9s$6àß]nܸ~ýúi|½–——£¼¼\jl–ú///´mÛ–~R|ûí·‚ëëŠ+¨B!šÛ@—fá…سgàó–-[0eÊ•¯Ä©S§Jìvý¾ÔÔThkk£C‡066FRR’¶«¸¸ÉÉÉðõõU©úúòË/õ`ñâÅbßJŠÒK4×È‘#qùòeªBXvüøqܺu‹•qÔDX^^^¿~ÍZ@MYùøø %%El@<8p Z´hA‹B¨.Yyy9ž>}*2ýÖ­[Œ"W¯\µ óæÍ«óvX[[£¬¬¬Ö´]’têÔI(ï65‚žžžÌù¹}||«ÐãÁVÄîüü|ÁÐÐQù»wïâáÇàóù‚ô4ýõ—P+++TTT ¢¢ÀÛt;‹-’kû¤uÇ—fذat“ûžíÛ·KM$ËyÞµkWªTBXöøñcøøøH,#k –%K–`É’%T¹,KHH©1moo‚‚TVVJ,·~ýz|ÿý÷TÁ„B tñrss±wï^¹ç×ÕщìýNqq1222àíí-u9­[·FVVãFóÞ½{1vìX¥ÖÕ·ß~‹­[·²¾Ü–-[âõë×ÈÏÏÇÁƒ1jÔ¨:/óÉ“'°µµ… £ò‹/Ɔ Àãñ†»wï‚Ïç Eýööö¼¥Þ¦“7§û»(éò’5š°¢>|X¦hÄïkÖ¬jjj••%÷úÅ‹ÐÐPDFFŠOOOmÛ¶Šî¬¥¥mmµËIH½3f ÆŒSç,ë֭ìẎŽÕWF”‰'JÌ¡îÄ ¬+]]]Ì`C!Ô@gÑÈ‘#•]Z’ŠŠ  I“&¬o÷7йsg8ìììPZZв²2֗ݼys$'' >COOObtòŠŠ >ûöíL“çÍ~yy9.]º„þýû«Í±8}ú4z÷î͸çÁ;wîÜAÇŽešçÞ½{°³³ƒ¿¿?¸\®B"ÆA____(G°¶¶6š6mªòcû Qe111hÚ´)ÊËËQ#¦ñ xxxÔË6ÚÛÛ#''‡µåuíÚW¯^­õ»ôôtF‘ãßiÔ¨:wîŒþùG介/ÂÏÏO$;ˆ$NNNÈÈÈ`í^† ñññpww‡££#V¯^M?B¡ºäFÔ‡³‰'Štoÿé§ŸðÃ?ÐQS!ãÇÇîÝ»%–:t(~ÿýwÁg˜™™aæÌ™4kÖLh˜Cpp0:tè###Aã<,, Ó¦M“y¹\®Bßt;Væ °³³«5uŽ2ßÌs¹\hkk+õmµ¥¥%œEBîÚµ |>¿þú+ÆŒC?.Bþçï¿ÿ–IzÙ²eX¶lôôô$þÞß]ƒõôô$æ.W„îÝ»ãÊ•+J‰"þÇ`àÀŒËkiiAGLo¼ššhkkË”I¥ÿþøóÏ?kýN©P™x×ëOKKKæÀ„BH=>>+W®„¡¡!Î;‡‰'ªªªP\\Œ©S§Ê¼Ìääd¸¸¸È46¹  @0&œÈ&$$Dvì·ß~ÃСCÍçää$ˆÔmhh‘hßžžž‚¢ÌÌÌZãÀ¬Y³ÁäæÍ›‡•+W*µ>þøc\¼x±ÖïÒÒÒj}‹cll ™»”/]º‹/®÷ãþôéSx{{cûö혯iÑ¢EX¶l5j$1b0“ß^‡¼?[RRBWeB>ø; @b¯š ]»v YHHΟ?¯ðýŒŒŒDhh(ÀÑÑ\.ÙÙÙt0ðï¿ÿ¢OŸ>T„B töÙØØ eË–¸qãF­€Nž<)4íMv*¬ì5î œ8qƒ–y¾›7o"((¨ÖF]§Nj½É***Œ ÿ£££Pz¦Ú´i#ò¶gõêÕŒSÊMš4 Û·ošV\\,ÔÐ-++úuëX‰üêÕ+4jÔ-Z´@uu5 èÊP'N”ßÎγgÏÆÓ§OѪU+À'Ÿ|B•G”ÄÄDÜ»wOô²6prr’¸œçÏŸÃÓÓS­ëâÊ•+èÖ­›à^€ÇãÉœåDœfÍš)½;?ÛV­Z…¹sçÒ†B¨®äÑÖ†žž^­)B***Dƪ_ümz›¥’Û¡Cܽ{Wl£Y’òòr˜˜˜°¶-ZZZ000¤&{ßÝ»wááá ‘ïÆ'”—¾.ŠŠŠð믿 Mûì³ÏpæÌ‘²oÞ¼µµµÐ4¡:yö쪫«Ñ¦M™·%**  ê‡îçç'2æ[QLMM¥¾  EóæÍŸÛ¶m+×±$D-Z´[¶lÁÙ³gÅ–Ù±c&L˜€~ýú᯿þ¢J“Ô)S°e˵ÞKKKzxL!Ô@W.›Z¥(,,DAA,--ë¼>Ÿ¢¢"˜››3*ÿÝwßaÓ¦M2¯Ç××1112u=´¶¶fíA}ËÈÈ ¶Ó¤I‘è¸ü1¾úê+Œ5 ÖÖÖ077—ØeÚÉÉIb7ÏÜÜ\ÁCœ¦M›Š ûøñc™ƒyyyhܸ±Úooo±cøÅ‘'ø¤cSÛ¢w¼¼¼ê-²4!õáܹsèÞ½;† ¨|÷îÝqùòe©åÖ¯_Ó[g*|û>|ˆÆË)]ÕÈò›o¾Á®]»è$&„¢Ù ô‘#G¢mÛ¶"Óûöí‹sçÎáÏ?ÿľ}ûêÈ­ººW®\AHH£òVVV‚tPŠ6xð`œ8qBíO*777ü÷ßBOû§M›ggÑáï–„††âã?FÇŽÅބΟ?_bš›ºÖ/\¸Ë–-cmŸ~ûí7 >¼A]Þ=cÞ={pëÖ-£Y³ftå%­  ‹-BzzºØ2¥¥¥066–)28vvv()ÈQø>r8èèè(5¸jii)rrràææÆÊò kí=¦Ìk#!„¢² ô÷-\¸P$` 8Pp3pÿþ}¼Ñq©¥-£eêèèÀÈÈH%l©³Å‹céÒ¥£¥»ºº*,`‘47n¤ƒ¤bš7oŽ¥K—")) %%%jýÆ&,X€ŠŠ ±½x4Ñwß}‡Í›7+teeeÈÍͣ!/55%%%õ’/B5ÐEdffÂÑÑQêê@G‡Y¾hSSSàÊ•+rmÓ­[·Dò²7DÈÊÊbtŒÞŸ'00P)ÛG?Å0`NŸ>-Ó<X´hvìØ!4]Rž`®ääd¬\¹R$ŽQŒììl©i¯ž±±±ðõõ…±±18x<žÂ·ÿý.ÝcÇŽ•˜¾’-K—.ÅâÅ‹Äùñ×_¡_¿~*¹m»víÂ7ß|C?bBQºÊ\ÙÎ; è;wî¶nÝŠ°²ü¬¬,üüóÏBÓ.^¼(ómuˆÛ·oË4¹¹9JJJê|S¨¥¥…   FÑeóòòÀçóaccÃxùnnnˆ‰‰AUU•ÌÛ‹¾}ûbñâÅJ¹ù%oùûûãØ±cÇߊãíí-LÔîÈ‘#‚†â»ë©8GÊ3-ÎÈ‘#Áãñ°dÉS%àòåËøå—_ ££#6¢ú–-[0uêT´mÛ¡¡¡èÝ»·ÄevïÞ‡Fqq1k«ÅÙ²e "##öööxõê•Âë,55µÖø#D1zöì‰ .ˆÄLyõê:vìHÄйsçHII¡ !„(•Rß ·k× DänÔ¨‘PH\Nxx8V¯^Íh‘‘‘4hFÄ^½zI|ƒ­ÐH[[(?¹$ÙÙÙàñxhÒ¤ €·]"§OŸ.RîÇj°%&& ½Ñ›6m¶oßSSSÁ´ÌÌLÂÛÛ[0íîÝ»èСƒÌûT]] >Ÿ¯ÔàG²’÷mÈŸþ‰O?ý¨©©—Ë­ó¶TVV²ÖuÚßߟµvš®M›6‚ë©««+£yLLLPVV&ö{sss9rDj/‰+V`Þ¼y ®ËüŸþ‰ƒÂÐÐN@¢’ÂÂÂAQGnnn‚ë+Å „ht= :uB§Nàää„-Z <<\¨Ì¨Q£Ð¹sg‘yûöí+táLLLú¾}ûö¸ÿ>ÑzТE $%%‰¼¥Ž‰‰¯¯¯Øùôõõk öãéé)q}...033ÃÔ©SÓ8ª««Eø¼£¥¥wwwlݺ½zõ’¸ü—/_¢¦¦F¥Ç‡¦¥¥É =''¶¶¶ B||}ðï¿ÿ²vƒbnn:C>`nnŽ–-["**J0Íjä‘ IDATßß111BÁl¦OŸŽ‡¢{÷î2-___¿Ö7×µï[ºt©Äïµ´´àïï)S¦È”÷vèСøý÷ß•-++ƒ‰‰ æ)óø|>¸\.ôôôгgO\¼xQåŽùéÓ§1`À™ëþСCøòË/%–ëØ±£ÈÍÏW_}}}}ú±©¨¸¸8´lÙRê[äÌÌL|òÉ'1b„ZìWqq±J÷hÒ¤ ¬¬¬ðäÉ…®çöíÛ í ½xñb,Y²„•eéêê"((W¯^eeyµ§ª¬¬”Ú³©êêjèé鱞^B5ÐêÀ¬4òMLLЦM¹nÔôõõ)zêÿ¼ÿ&\OO5ª57üûÇÍÃÃC¤¡][,€V­Z º¼¿kòÉ'2ŸŠzÂݬY3¤¥¥1*;uêTüòË/ÞF“g2»°°QQQèÙ³'ììì$Ÿª/™™™prr’X÷7nÜ@—.]„¦§¤¤ÀÅÅEì1Ò××§qά¢¢mÚ´¿¿¿Ì12”-66³gÏÆ?ü ²Ûhhh±çÔEëÖ­c{ë|£­Æãõë׬,oøðáµö:pàFÅÊ:þþûo æB!jÑ@—×È‘#Ýe­­­aee…±åÊÊJ:L˜0;wîšöæÍ :}úô©óò'Mš$2íã?FË–-ë¼l---‘·®}úôA@@€Øyüüü’’‚Y³f©õqÓ××—+ˆ›ä¹522Âèѣ釧"Nœ8Áƒ3.ïç燤¤$I,7lØ0üöÛoË”——‹¤™R¦sçÎI æöÓO? 𺺺JÙÞƒ²Ö0”WPP¢¢¢êý#‹Í›7ã»ï¾«÷íøþûïEײͷûD~gÏžEll,U!¤a7Ðíììàáé!4ÍÝÝ]¨+´———HÄðëׯ ÞôÙÙÙáÍ›7¬ÊR¶¨¨(´oßžÕezyyáÙ³gBÓvïÞ/^H·K—.ÐÖ®¿ÓÉÕÕ+V¬šÖ´iS‰)Ö¬­­QRR‚¤¤$xyy©íxåÊ•˜7o^—ãëë‹GI-—œœ ꢩa’’’e€Æ£¤¤„•†[ëÖ­±~ýz©©ùêÓû=‰¾ùæìÚµKáë|ùò%ÜÝÝëýoíëׯÕêïd\\œJÄiÓ¦Âm_}õUƒ‹¡ŠRSSñæÍªBHÃi Ïž=[¤1àåå…^ÞŽoß ~øvvÛ¶m˜šÎårqûöm‰]nBBŒ…º¨W¯^hÛ¶­Ð´o¿ý:::jù#pwwg¥‡€º ÃÆQUU%¶¡¦¯¯Ž;"00P0Íßß_dø‚¶¶¶È9­¥¥U¯qªÍ›7cÚ´iJ_/ŸÏgt¼×¯_Çãùó稨¨¸<.— >Ÿ/Óvp¹\‰Ëììl¡cÇŽpttd­ûu]ÿžÔéoˆ––ÌõTß jGGGXYYÑ–Á–üü|dffâï¿ÿ¦Ê „4œúG}¤Ð姦¦ ÆÊnܸ±ÖÔ_L0éÊù¡ôôt¤¦¦Ö¹^^FFF066yšËçó‘••GGG±ó@OOObP6dܺuk<~ü˜Ñ9£‰¹}KJJÀårÅæcÖÖÖ6`gg'4ÖxÛøÃýÎÎÎX»v-]u•,::íÚµSúzÃÃñjÕ*©å¢¢¢ 5ÇòåË,ó8q///xxx ''§ÖïËÊÊPUU˜šš"//µ:Ø´i“»Zs8üóÏ?øüóÏÓ:}ò5nÿµOmÎѼ¼<˜ššRú: lllàçç‡óçÏSeÔ“[·n‰ý –––"))‰*‰ÒpèªfìØ±Ø»w/U„ kÔ¨Æ/ó|ÇDZcÇ$–™2e † &M}ýõר·OøF?((H®üò„H2yòdlÛ¶Mb™5kÖÀÌÌ Œ–¹cÇF© !Dšõë×Ë=ïÇ1lØ0•ÎA¡º@xx8üüü”¶¾ãÇ×yBiƘøè£ŸŸÏøÆR°=F^–㨯¯_ëúÛµk'ÒíöÃey{{KLÔ¡CܹsGeë]OO–––bß¾/11nnnb¿o×®Μ9ƒ3g΀ÇãáÞ½{ ïÕP}xí055…ŽŽŽÔ L-Y²DjúLBÔEVV~ÿýwµ ¶HiÀ ôÚÆªÊ£Y³fs5¿ÃÖ8éË—/£GŒËkÕØÀýû÷K’}ùòe™s•oSŠI®°}“÷8Κ5 ººº—5mÚ4µ+mjj OOO‘†umN:…ªÌ¶Ó8uÕ0zôhìß¿¿Öïdµamm {{{VÇv‹Ãçó±bÅ RÅ8uê”P·z'''"11‘µ{u àÊ–ãÇË”UB5ÐUŽ••|||”¶¾/^ÀÃÃCáëñññALLŒ\óÞ¹s;vû}ëÖ­‘˜˜(HïÈ‘#BeÜÜܰlÙ2‘y»u릱?Š÷­²²eee°´´¬ó²,X m^QÆŽ‹={ö(e]ÞÞÞ">ˆú T©Ü奥¥àóùhÔ¨‘`ÚŽ;jáììŒQ£FáÚµk‚iµe¨xçåË—RS=æääÀÆÆFꃉçÏŸ£ªªJæ¿EÛ¶m÷ß~«ôzõðð`”¥C„‡‡cõêÕj³½ÑÑÑð÷÷§‹!„P]³uêÔI!x]]]øúú2zc)«ùóçãÇTÈ ÷¬Y³`dd$4íà =ÚÚÚ"ùÅš7oÞ ##Cb©6AAAbÈ|ØØWVÎZ‡£´ K3fÌj<¦””ðxK{ë©­­ •ŽàÙ²eK¼|ùRdº¸n¬Š`bb"훉_~ùEa¿µk×ÂÆÆ†•sKÒ›(èëëËÕÍ÷úõëððð¨—Èùúúúõž‡™°'00iiiÈÌÌT‰íyýú5¬­­ejÐN™2«W¯FQQºvíZëu –.] {{{±cbbàçç'Ô07nœRzŒ3¿þú+õ(##™™™r¼l×® œœ,˜öèÑ#‘ô£ª"??( ܃JºOˆŽŽÆÕ«W©¢!Å€Hn/// 6LðÙØØX¥"ovíÚW®\aeYÊ|ëÙ¼ysŒ3FæùLMMY‰S î¡2Æ<ëèè@KK 5552Ï[]] ]]Ý:m§¯¯/ž>}*óú­¬¬äN;HTžž¸\®ÒrsKsåÊtîÜY0<¢sçθqã†ÄyŒŒŒùÒgÍš…uëÖÉumÓÑÑÁĉÑ¢E Á4CCC‰¹ØÙRRR¢ô'üñ‡Jślj'0dÈV–ÅãñÀãñ¤öЍ®®.x<^ƒ#OdsçΜssssTTT ººZ®ž¼&L˜€o¿ý2Ï{ãÆzçΦ˗/cÊ”)÷[vvvFJJ uAW!IIIÈÍÍ>ÎÎÎõvá¶³³“úWôíÛýû÷—kÿ/^¬q?þž={ÂÄÄ„®‚jêË/¿\O{õê¥RÛ– {{{Ág¼~ýšÑ¼M›6Ehh¨Ä2Í›7¯uú”)S°eË©ëX¿~=fÍš%ÓµãÓO?•ëÚáêêŠ;wî¨õ¹öóÏ?cæÌ™2Ï———‡Æ‹L÷ööÆÓ§OYÙ6///<þœµ4¦›6mê-ÁFO¨÷}˜žŽ¨¦>}ú®¯#FŒXvéÒ¥X¼x1š5k¦Ð ogΜ››B¨NÈۜȚÐíÊÄÄDæ.¼ÀÛ·uµÝdj‚áÃ‡Ó NX·k×.L˜0Aè<;vì£yçÍ›'õ­¶¸qç999ŒÞhççç3 ˜___©×ެ¬,,\¸P$R¼ŽŽôôô”2®]‘lmmÝ}eqüøqÖÆŒ××¾.\¸Ë—/gmùlƈ‹‹C«V­”G…ˆ÷îAÔ¢E‹jMKËæ¹£ÊÁˆ !Ô@gÍêÕ«’Š*((Ož<‘xSgmm¼¼<¥í+ocϧŸ~Šž={Öi#FŒÀÑ£Gež¯qãÆr7ؼy³Ð´°°0Fxy"“úwùòetèÐAmzÀbèСð÷÷Ç«W¯]øëËãÇѦM©å²³³QRR‚O>ù„µus8hiiÉ•–QߨÕ•àñ(ˆ™&{úô)<==Eè#GŽÄ¡C‡¨‚!„èêÉÁÁA!OŸMMMÁápðóÏ?‹-3~üx¥¤ôygÓ¦MtƳÄÜÜ\ä-Hÿþýeº™¶²²¤¿yß“'O$öX˜0avîÜ)ó6¯Y³F®îq–––Ô^M•””ÀØØX%Þ°UTTàÇ”øÈÄÄ–––066FMMиïÚÁÁÁ‰‰‰õ¾¶¶¶èСºuëÆZãËÐÐPû]î¾ÁÈHxNYqƒ;çáàà##£zß}}}8;;×9F„¬Äým!„B t¢Ä›€#›™™)¤g@CĤËl—.]°ÿ~Vê<66>>>õ²¯Í›7WûHÏ ŸÏg<Î[^áááX½zµÐ´‡"$$£G–8/‡ÃÁÆYm¬ÃÑÑ‘Ñ2ÍÍÍQTT¤ðFúÇ,ñ%%%©TÚNMGGG•è5b``WWW<þœ aí~$''Gì÷ùùùr¥s%„P°ÌÓÓÓ¦Mš6fÌ´oßž*‡Û¶m“ZÆÌÌ ÖÖÖ‚ÏŽŽŽP»}544›ÚЍ¶²²2Ìž=[¡ëHII‹‹‹Ð4 ,Z´%%%ç=z´ÔlŠ4vìXìÛ·Oj¹Þ½{ã¿ÿþ“iÙwîÜa4 „ÃáÀÍÍ çÎSÉs¨²²™™™r½µ'„(ç~dòäÉb¿_¹r%£@™„j ðù|TVVÒÛooÄJ‹êîââ‚àà`ª,¢ž´µ¡§§‡ÊÊJ©eÛµkÇ(ËÅW_}…âôéÓ2oÏž={0nÜ8¥ì{XXNœ8!Ó</^”øæü}FFFµ^ßCCCY¯Ç½¢¢)))ðòò¢!õÀÜÜÅÅÅuº7ÿüsüñÇìÜìü¯wÇ£‹i°Îž=‹‰'REB tÂ6;;;|þùçHŽxtêÃáNNNô‡ÔÊÓÓS$íStt4üýý…¦}ýõ×G“&MžžÎÚú;wîŒ7n€Ïç#;;öööµ– PÈÛÓââbèèèÀÄĤNËÙ°af̘¡Çüõë×022‚©©©ÐtÉœžïÞ½{µ>tuu•˜ç¾>µiÓ\.OŸ>UÈ9UUUÅÚ57&&¾¾¾t±"¬KOO‡§§'nݺE•A5Ð5‹¹¹9&Mš$µÜäÉ“åS.‰‡‡zõêEB˜šš²’w|À€"tB˜:~ü8† "2ÝÀÀÞÞÞˆŽŽfm]ß|ó víÚ%µÓ1íïÆ…òùü:ÇQ|>ŸqYǨ|B|,,,`cc#4ÝÆÆ2ç¦?tèFŽ©Öõ¼wï^|ýõ×rÏ?jÔ(8pÀÛà\hÞ¼9+ÛvêÔ)VÇäÿöÛo>|8]èTá¦[[»Þ{qŒ;{÷A5Ð5‹|||¤–óõõ…¾¾>UKOOmÛ¶|îÔ©“\ËiÑ¢¤# ’³³3RSSqøða|ñÅj¿?·oßF“&MDòÍ׿×_­5%‘...­[·–{~ooo…¼W„çÏŸÓ\1iÒ$FCŒ!Ô@'„(ÉÌ™3ëô=!lHLLÄСCñêÕ+Ö—žž‡fÍšQE¿çÒ¥KèÑ£G—óõ×_cß¾}tÍ DMlÞ¼Ó¦M£Š „¨f}üøñ CXX"""\e¯ZµŠQþl¢¹‚‚‚”¶®'NP…k°ððpÁõtçÎ055E·nÝ¥azðà\\\§P“EQQø|~ƒÉ2ÀôMlRR\]]ë¼>DGG£ººùùù°³³kõ¼qãFLŸ>]c÷ÏÝÝ]æ¡Dq¶nÝ*¸¾.X° N˺{÷.:tè ´mŸ7oV®\)÷ü&LÀ¹sçè$ ¤¡4ÐwïÞˆˆDDD ,,¬áU¶6uX t¾v¬^½Zp=0a€·©™ŒIÖÑÑip燻»;òóó‘——ÇêrýõWŒ3Fì÷!!!¸páëûSZZŠ/^(5{H}Ò”â 4'Ož¤ ›ŠøöÛo××+V¨ÝßþºŒsçñxøé§Ÿè$ ¤¡4Ð DòÚÂÓÓS¦yˆzúá‡Å.¦mÛ¶˜3gU(©“–-[âåË—RË1ͽlnnŽšš”••©äþÚÚÚ¢¬¬ŒñöÅÆÆ²ò{õðð‰š¯léñé„'D6mÚ„ï¾ûN-¶µ²²¥¥¥¯†÷<|ø°NßS]C|ØUÊÆÆFðö‹é|ø¾¾¾ÐÑÑ©Ór Ñ®];ܼy“Qù={ö`ܸqJ«Cccc¸¸¸Ô[ -¶¢½«2}}}TWWË”ó]’%K–`É’%*¿ßûöí«Sîu¦tuuÁårë=ß6Q TVVŠLçp8044¤ " ¶mÛðã?J,“““ƒcǎɽŽÿý!!!(//§:!Då¯%Lyzz¢yóæ Yv||<\]]5>¸œ¡¡!ììì––V/ëøð!£¸#‰‰‰pss“ZîÌ®ùølüôã`HOO½{÷ÆÙ³g‘ŸŸ ÖÎùsçΡOŸ>¬,«¦¦ÿý7>ýôS:h„uöööÈÎÎûýøñã©’ˆB½xñBj™þùGìwûöíÈ#péÒ%¹·!** íÛ·¯—ý§:!*DKK _}õ•дº¤K! ÏÈ‘#qøðaª ·jÕ*Ì;Wj9NY MÍ©Âd¸‚Ãáàúõëhß¾=ŒŒŒTr[+**TvÛ"###4kÖ¬ÞƒB²AR:ä‹/ÂÅÅ…QJOBä5oÞ¼:Í_^^©åâããqëÖ-¹×sàÀ„½½=† ¢ò=AÖ®]‹Ù³gSB:SSSF»wïŽaÆaâĉË :Çguÿýw :”•e…††‚Ãá {÷îËõéÓ‡qãmݺuŒÊY[[K}ŠÏdY®®®ÈÍÍeõ¦¦º²:ºúÐÖÖ¥!j@WWºººRó;«ºÙ³gcæÌ™t@ /^àáÇb¿—wœ7×ÁÁÁ¸víšÂ“:::uúMzzz¢²²R¦1õÔ@'„ »ÁëÝ»7þþûoFå³³³aggÇÚúoÞ¼‰Î;³¶¼àà`XYYI-geeÅêÛq¦™æÍ›GGG‰e¼¼¼Ð»woV¶ËÔÔÖÖÖŒÒÀ%?¹ƒÆŽnhdIqMQM›6…ÄŽ:HIIAJJ P ôàÁ¤§§K,Ó·o_±c²_¾| .— OOOµØßfÍš¡qãÆuúMƒÇãÉÔȧ:!„V˜››ãÒ¥K aeyúúúyò­Zµû}EE¸\.£üÒDó”––¢¨¨eeej±½ººº055e=ŒR¶]Ñ+ؾ}{­ÉÙ%å¿#„"êøñãµ>•NJJRøº?ûì3ôèу•eµoßmÚ´©—:d’b-00°ÞŽ1“F2S:ºúÐ30”XfèСøþûïѸqcF˼ví¾ûî;F ÉéÓ§Ó–¨Û·ocýúõ"Ó©aÏž=7nœÊÔÁ¬Y³pùòe:! ØØXL:'Nœ€­­­È÷………ÈËËC‹-ê¼®‰'bÇŽRcàȃÇãËå*<ÛÈùóçYë1¨ôú¤I“0iÒ$‘é .DDDý!„¡!C†`È!"Ówî܉Y³f)l½:::Œ¢¤“ºûõ×_Y[–›Og¸ùHŽàä䄌Œ Æ t¦âããáîîN”¨ÀÀÀZïKÙŽ«ñ¡””iL=&$$ÀÍÍ |>Ÿ®j¦¨¨×®]SJBWWWœ?^ì÷ZZZpssCBB‚̲³³‘€ï¾ûÏž=“XÖÑÑwîÜAEEŒŒŒÓ Àåramm-vÞÜÜ\ØÚÚ‚Ïç³^?ÔÅB(mmmèëëSEBaÌÎÎ7®µ7ìýû÷€Ž;âîÝ»b—±|ùrªH tþüyôêÕKîù9¢££„€€DEE)t{===‘••…ââb¡é¯^½BMM š6mªð:«¨¨ :!„4W¯^E×®]%–iÕªæÍ›G•%'[[[‰ã55‰££#òòò)rÄiß¾=îß¿O'!xTÍÉÉ :::õ¾-wîÜAÇŽYY–‘‘ ê4¶÷Ò¥Kˆ‰‰¡“D‰¥F`¯«ÌÌL888È=?ÇÛ7ojíb¯ªœ‘‘‘.—+×ü_~ù%5Ð !DÓuîܱ±±˜Ÿ>Ÿ¯ç)Q_nnnàp8ÈÈÈ`–‰C‡aäÈ‘*Q—û÷ïÇÇŒ3gÎЉ¥D×®]Ctt´Ä2ãÆÃÞ½{©²d€˜˜TWWËõ@B[[›è„¢é?Á^°`«Û˜ŽÕdsL§±±1«c·U‹‹ ëcÆÙ>¾lJKKCFF:uêD?nRoÌÍÍÁårQZZJ•QGOŸ>…··7U„•––bÙ²eRóÓ·jÕ qqqTaJ²}ûöZcµQBk˜¦€¢TQš}| !„¨–àà`\»vMì÷ýõ£T¤&LÀÎ;©Bˆè„BHfoo-[¶°¶<ÊÕMˆâ888 ''Gîñ®LtëÖ /^¼À«W¯¨ÂÕÄãÇ¡££ƒÇ˽ ¦Q÷Ûµk'µ«üëׯ‘œœL†è„B‘›ã»Ù/Þ¤IÐMÑÞÞÞÈÌÌDQQ‘ÜËèØ±#¢££åï*ëõ@飈âðx<•9f1118wîœÈô“'ObРAt°¨N! ŸŸÕR37n„ÊnßÖ­[aaaÁʲöîÝ‹±cÇJ,cff]]]äççÓÉA4‚½½= kM«D„õïß'N¤ŠPã{q w___ÖÖQVV†—/_ªdÀÀÀ@(¿:5Ð !¤ W‰Ô>„9===•~¨¢¯¯ÏÚöéëë#::®®®011¡ƒ¯ ‘‘‘ ¥ŠÐpGÅ_|¡QûTYY)5­#Q] ,Pø:ÞE?W՞Ϟ=ƒ•••\Þ©N!„4`lFñ—EFFlll``` Ôõ6¤1òQQQhß¾=äîÖ­[ ¬÷íàñxÈËËS«ÖêbÍš5SX&''£yóæ ݆¹sçbÕªUõ^Û¶mc”FV’#GŽ(ý¡Ö‹/`ee…ØØXj B!D¼%K–4¨ýåp8044TÉmËÌÌ„––ã4‰„¨’êêjܾ}ÁÁÁT,›?>*++Å~àÀŒ5J¡ÛP^^ccc•¸†×õÁnee%ôõõ•¶ÍŸ~ú)NŸ>‚‚F©N!„×´iS¤§§«ô6¾yó`mmMŒh¤’’èéé¡]»v¨©©Á‹/j-§££333P¥èÝ»7nÞ¼‰²²2µ¾Æ½ãââkkk©ÑàëÊÎÎ999uZ†ƒƒ²²²ê´Œ:àîÝ»ŒËSB!j­]»vxðàÄ2ãÆÃž={¨²Hƒ÷ÑGáÞ½{õ²î'OžÀÂÂÎÎÎàóù¨©©)sëÖ-„„„À××7oÞ¤ÀÀÀUUUÇ[ýõר·oŸZ쎎´µµšxûæúìÙ³uZƈ#pôèQV¶§gÏž¸pá5Ð !„¢<ãÆC@@€Ôr]»vŰaÃXY§··7úôéƒ 6(}׬Yƒ9sæÐo`ÒÒÒ——µÛöÖ­[#..NæùÖ­[‡Ù³g+|û˜FúNLLÔˆséÕ«W˜2e JKK¶Žï¿ÿëׯ§n=ëØ±#îܹ#µœ®27jõêÕ(..\»vŽ!„ÈiÛ¶mÈÈÈ<|ø*„¨ 333F㌌`jjÊÚzóòòиqc¥íg=péÒ%ÀÒÒ’¼‰ŒŒôÈxwýPMM ¸\®ÒƒÖ§‚‚Æ©½½½qôèQTWWCOOO!Û3gÎDFFª}½ÖÔÔ`ëÖ­2dˆÂÆï+ûúHêF© ôÁƒ º²âòåËt!Dýúõ‡ÃâÆT)„(Q—.]ðÇPEh    ´nÝC‡Q¥ÈÈÃÃIII k gee!33‡ÂÈ‘#©ÂÚ¸q#f̘!±·‘ ^¿~ ¥o_FFÕ²nKKKQQQ!ö­lmmñôéSÕj »¹¹ þOP!D~ÎÎ΂ÿË“c“ú6dȪ¢’ìííaooàí›G¢z–,Y‚9sæ 33Sí÷åܹsèÝ»·RÖÅ$àÙØ±c±wï^„‡‡+½.æÎ«¶½"®]»†ÂÂB|ýõ×µ~ïêꊩS§âÊ•+R—EcÐ !„ ===ÆÝ(‡ʨܺuë0kÖ,®7CCCðx<…L"êçÔ©SøüóÏ©"ÔXrr2 Å~ÿÏ?ÿ oß¾j³?æææðööÆ­[·„¦ÿðÃøé§ŸÄ1­¬¬Ä7ðñÇ M_¼x1JJJê¼|j B!„ŽŽŽ˜;w.«ËÌÊÊÒø¼à>>>(**Bjj*D \ûöí…"¬çççÃÊÊŠ*F}ôÑG8pà€ÜóŸ>} P™ýÑÕÕ…‘‘‘HC4-- Íš5kÇ”Ç㡤¤æææ‚i±±±°²²b”çœè„B! õêÕ /^DII Œ©BˆR×K åÅ‹cÙ²etTÐÑ£G1bĪÅ(ƒÉ;\.ÕÕÕ044¤:!„Bˆ8VVVÈÏÏGDDBCC©BHƒ˜˜WWWªpttDqq±BÓ¨ÕÕ¥K—УG•Ú&www$&&²òFZåææ"!!:u¢:!„Bˆ&›6m~ùåª%ëß¿?þüóOÆåkjj ¥¥]]]µÛסC‡âøñã*½ãÇÇ–-[º>Ÿ/u̱››Þ¼y#qzXX"""ê­®Nœ8¡r;}}}'s}ãÆ˜>}ºÊž—¦¦¦RÖPB!Dœ?!!!b¿wuuEbb"U”’ÙÛÛ#;;›qùØØXÂÝÝ]íöÕÑÑQlŽxUñèÑ#$%%)t¥¥¥˜:u*+õ© éUAbb¢Pæ0yÜ¿}ô«Ûõ.Rÿ’%K°dÉj B!D=-Z´Hí÷áÊ•+èÒ¥ ´µÙ¹íÚ³gÆG'©•8ŽÆï§233ë5^EE®_¿ŽÛ·o+|]FFF¨¨¨ œeS§NÅæÍ›…¦9sŸ~ú©à3ŸÏÇï¿ÿŽGÕºŒ¹sçBOOOâz¾ùæÆÛD tB!„¨,___F傃ƒU¶«pNNlmm¡¥¥E”(Ü‚ °bÅ ßOKKK”——£²²²ÖïMLL`bb‚œœ…mäI“°hÑ"¥<$ؾ};&Nœ(2ýÁƒŒƒ“iiiÁÙÙÉÉÉôCùOOO<þ\b™ììl 6 µ~ߺukhkk£sçθyóf·‰è„BQ{ãÆƒ¾¾>U!*ŒËåBGGGì÷|>|>ÚÚÚèÙ³'.\¸ R&::îîîhÔ¨‘ÄuY[[ÃÊÊ ñññõ¶¿[·nÅ”)SºŽˆˆ„……1køik# @(•aϘ1c°oß>j B!¤asrrBóæÍUrÛ‚‚‚Xy£Bˆ&øùçŸ1sæL±ßçææ"..=zô@Ó¦M‘žž^k™ÿcï¼Ã¢¸º?þ]:"½R¥ªˆ]ìbŒÅÆØb-cŒ¯Æõ½Çh$Vì6Ä‚XŠ Ø(R—²ôºüþð·ó²l™…]–Îçy|dgîܹsîrî=¥I“&R'ä^¿~ 77·Z¿Þððpxxx4¸~¶´´Dfffqµàr¹¬«è-[¶Dtt´ÄýÝ»wWX{HA'‚ B%1b„L©ŸÚ·oooo•¼†¹sçRDu¢V¹té†Ú ®ùÂ… ¹æ9sæàôéÓ4ˆªˆ»»;âââ]'ÚûæÍüóÏ?RËôïß7nܸ_‘‘ãIA'‚ B%qvv†‘‘ ‚ ä ::ºNFŠWl¦áׯ_GdddRŒ_½zUoû+,, mÛ¶Ux½&&&Ø»w/>~ü¨×I :AA ‚¤¤$•ÏÝL„òxúô)‚ƒƒkíü—.]Š./&L€¿¿¿JÊúÔ©S3fŒ\uìß¿¿JÑÐeÅÙÙY¡ý /J w:mÚ4&ú]DD=‚ ªÉ²eËðöí[¨ñ<¯Q_ÈÉÉÁ—_~‰víÚÕÉö«««ÃÄÄ„¹÷‰ša×®]¸sç ==½AÊÀÍÍ °¶¶–ù˜°°0xzzÊ\^àÓ[[¾âÏŸ?‡™™>|øPk.2èÛ·¯ÊEä äI“êäý ­­ 777$&&*å|J]A?pàªm ‚eÆ ÌótÆŒ$‚ …å#W6ºººhݺ5BBB¨#kÙ³g3Ï׆®L3gÎÄÞ½{«tÌo¿ý†%K–È\¾¶W{7lØ€üQâþ€€,X°|>Ÿ>}’X®k×®õ>ä™3g0räÈûL066›â®^(èAAAªNhh(ú÷ïòòr‰ù¯ÀÉÉ©VS¹òÓºuk©û=Zå:wîÜYí{¤ AÑ 077ǰaÃHÑ@èÓ§nß¾]#uß¿_æÔZ~~~µ >88¸J&üvvv(((@jjªÊ÷ïСCqá¹ëùå—_¤î×ÓÓ«rEEEÐÖÖ& ‚ BMš4A§NH„RHKKƒ™™™Ð66³jB±´iÓÿþû¯Äý À½{÷ŸŸ_åº#""döŸ÷öö®µ`tUÍ onnŽââbdee©|ÿvêÔ‰Õå‡Ïç#88¸NÅ“  ‚ ‚ Hyy9áãã#´ÝÀÀ Îä†nhkk£¸¸ååå$ŒzJQQºw  RÐ ‚ ‚ ‚ jŠÿüç?Xµj ‚™yóæaûöí"ÛW¬X¡ ææær»‚NADƒ`„ $‚¨G!##£Þ^_xx8ÜÝÝëlæ U„ËåÂÔÔTìX’ PVF…€€RÐ ‚ ‚ Øðõõ•©Ü¶mÛ°{÷n!Ä‚ ðûï¿×z;6oÞŒE‹?~ŒæÍ›‹øº+šmÛ¶áû￯Ò1¶¶¶HHHh°ã%77ºººPWW—©üêÕ«±råJ¡mQQQhÕª£ ;'Nœ¨ò™:u*„««+ŒŒŒd*/‹i´¡¡!x<^½¸Ÿ”eýЬY3üñǸ|ù²ÜuYXX(%º=)èAAAÔ ¸\.Š‹‹YtWWWp8X=GSS#FŒP©öhhh °°t‚ ‚ ‚ ˆúб±1ttt””DÂPQlll`ff†/^‚NA¡(455qâÄ LŸ>„A "##ÆÆÆÌoqn¹¹¹Ð××'a‰ÁÄĺººˆo0×üþý{ìÛ·¯^])èAAUÄÅÅ£FBÓ¦MIDPTT„¤¤$888(¼î/¿üW¯^U¹k®œêjÇŽ˜;w®P™ãÇcܸq4@@AAΞ=‹´´4RÐ ‚ ‚ Õ¤¤¤Gæ҄ꑟŸ?ÂÅÅEáuO˜0þþþ$d)÷ššÔÕÕ¡¯¯ÜÜ\JôôôPPPÀü¾sçºwïMMÍj×yéÒ% 2¤ÊÇ988ÀÖÖŸ>}" ‚ ‚PMÂÂÂиqc8::’0¢Š<þFFFpppÀ’%K°iÓ¦z{­ñññ011ŽŽŽÌÇL˜0Ge~s¹\Ët/99–––Õš,°³³«W}¢¡Ì“M›6IAw?AD5Y¶lÞ¾} à³ÿAÊgÒ¤I077WX}ýõ—JäÙnèìÚµ wîÜð9eAÔ|>åååµnåÔI9®Zµ çÏŸWê9ׯ__£)•ª 8p€ùûçŸF@@ÝAÕ`Æ ÌßûöíÃâÅ‹I(¡d½:ýáÇñ7&ªÆìÙ³1{ölÀƒàííMB!λwïvíÚ‘0äÀÃÃCé zDDÜÜÜj¬~2q'‚ ‚¨AzôèîÝ»“ •äáÇhß¾=´´´äõ/Z´[¶l‘«---”””(½í|>(Ÿ{=ƒt‚ ‚ ˆÄÊÊ VVV Uø‰ÚåÅ‹ðôô¬×’œœ 33³7µ~úô)Ú·o¯r×ߦMüûï¿rÕñ×_aâĉRˤ§§ãõë× mû³gÏ`hhˆ-ZÐMYÇ E‡HA'‚ ‚P&êêêX¸p¡Bëœ?> ¶–9vìÆß e0}út!÷U6Ž9‚I“&5Xy½{÷—.]¢›§ p8”——+¤®%K–`óæÍ*smÒîRÐ ‚ ‚ j555tìØ‘µœ»»;ôõõI`uœŽ;"44´A\kÛ¶mFNÔÇŽCãÆñçŸJ-÷óÏ?cÍš5RËtêÔ !!!uã½A]OAQ»L˜0¡Z)†ÕbÞ¼yضm ¢ž“ØØXxxxÔ¹¶wîÜ¡¡¡(++«wýrùòe <¸ÚÇ>\éçHA'‚ ‚hxyy‘ÀŽ;0wî\…ÖYTT„¬¬¬*Mªœ„AˆðüùóZÏMO :AAA¨:::(,,$AÔååå(--…¦¦¦JµËÀÀ¶¶¶ˆŒŒ¤Njà‚NAAQ‹èèèÀÔÔñññõâzZ´h·oßRÇ’‚NAAªÏÍ›7áããS/®%$$:u¢N%-Z„-[¶4¸ëvrrBrr2rrrHA'‚ ‚¨ëvDÃáÉ“'èØ±cÔ½dÉlÚ´Ii×òúõk¸¹¹Uù¸¥K—â·ß~Sh[6n܈¥K—ÖùñQZZŠ«W¯Ê•6LÕINNÆÌ™3åRfU [[[¤§§ËÔŽt‚ ‚ `Æ «ËÆÆ½zõ"¡6P Áãñ™™‰œœØÙÙ©t; ǃ¡¡a½èÇüü|èéé1¿œœ˜˜¨´ˆæ5¾¾>’’’ðìÙ3ºi+@ñþ ‚ ‚ êVVV°²²"A4px<rssÑ´iÓz{æææHKKƒ™™Y½ïO¤¤¤ ??5RÊ9‹ŠŠPZZ*4QPU^½z…FÁÑÑQh»»»;ìííeª#77::: "]R¯póæÍŒ CPP=5 ‚ ªÉþýûñéÓ' ™g‚ rþüy¼xñêMÀ®úÌäÉ“qøða,Y²„„QÄÇǃÇãÁÃãÚuBMMM$rþ–-[°cÇ™ê ““LLLHAW$C† AII %%©©©4ê ‚ ªAß¾}QPPÀü¾wï … BtèÐ-Z´„……áÏ?ÿ$¡UæôéÓ ÷¯¯*™™™xýú5Æ_§eiii‰äädp8œ1v”ª ·jÕŠù»!˜¡AÔÍ›7gþ~ðà „ BA4mÚ”1 W´t]¢sçÎýÿéÕ«îÞ½[¥¸022ªÕv—••¡  úúúuZþëÖ­C“&M°~ýú1Þ(HAA°––†òòrA oooÜ¿_¥ÚÄårajjªôó~ñŸ~ýzƒéû9sæ`çÎJ9ט1cpòäI¹ë™?>¶oß®22”Çz‚t‚ ‚áÅ_\\¬Ôs>xð$|‚ ˆÿgáÂ…øý÷ßU®]jjjhÑ¢¢££ë…œ›6mÊĹ©iÌÍÍâöÜ´iS$$$¨Œ +Z:VÆËË ÖÖÖ¤ AŠ'++Kéçüé§ŸdRn¯\¹ÂZ®¬¬Læü«l×ZZZŠÜÜ\…ÉíêÕ«HII¡AF„DΞ=‹#F L^^^•¢¤«««ÃÃÃaaa$¼ „‡‡+du¼¾Ñ«W/©©IA'‚ ªÍ·ß~«ôsFEE±–ÉÌÌ”iFþãÇX³fB®5::7nd­§¼¼S§N¥ÁC„Ü$%%Q:½`×®]˜={6 BN²³³‘˜˜¨2íiÑ¢bbbT^n¤ ABðx¼Z1!|öì.]ºÄZŽÏç#??ŸµÜ¦M›——'µÌªU«Xë B—.]DÒÃT¦  gΜÁÛ·oå–ELL ´µµqèÐ!¡Bèêê eÐ G@@üüüHõˆ3gÎ 55U%2wq8xyyáéÓ§˨««CGG‡t‚ Bµ())‘i•ZV"""œœÌZ.33“Õç-<<fffX¶lk}‘‘‘(--•ZæÕ«W¬õ¤¦¦ÂÔÔjjÒ_™ëÖ­ÃøñãYÍÜoݺÅzΜœ¨©©áýû÷ ëYÎK„t–/_ŽuëÖ5¨kNOO‡ºº:š4iR£ç‰G³fÍhÕ#¼½½QTT„ÂÂÂ:ÑÞ6mÚ`áÂ…¤ Au“ââbÖÈæ\.£GÆ›7oXë+**b-sýúu 0€µÜÍ›7áããÃZŽÃá€Ãá€Ïç+Mn{öìaRö(¢Ö¯_²²2Ö²»wïf-sãÆ „††²–‹ŠŠÂ™3gè&¨c÷+¡Œ1gÏž­3퇆††Ô V’ÐÐÐ`(%e¢¥¥¥òm$ ‚!&&IIIRËÌŸ?\.Wj™ÂÂBðù|™Väǯ°ö'$$ÀÆÆ†µœƒƒLMMñäÉ¥Ê×ÊÊJ!~y|>Ë—/Ç… &·€€Ör™™™øðáÝ(uˆqãÆ‘T‡sÿLž<‡¦N'T†Ã‡C[[›t‚ B58tè«R wîÜÁË—/YË <˜Õo¼ÿþ¸qã†ÊÉâÔ©S=z´Bë5jNŸ>­´køý÷ß±`Á™>Hdõ”%¬<ù]2Š”[yy9«KŲ„r)//‡Ã!Aȉ††:v숇Öèy8N½¹O|}}qîÜ9}‹-bU*x<ÆŒ#Ó„¡8”=YWo55…YIcÚ´i8pà@“OTTœ…¶µlÙ²Þäc' ‚¨³b×®]2•e‹Ð¾ÿ~LŸ>]é×àááØØXðx<…Ô7k' ”ý IDATÖ,™ü®•Ipp0¼½½Zg÷îÝqÿþ}Ör#GŽ”ê7ž——‡7oÞ ]»vtCÕÏž=CPPÜ÷hÅr›7o–Z&..|>Ÿ‚oÕ3z÷î;wî 8çÏŸÇðáÃIuiÖoB úîÝ»áççÇüsqqÁÇ¥V~ïÞ=øùùaôèÑxþü9I› ÀÉ“'…ž§íÚµCpp°Ôc^¼x±cÇÂÏÏ·oß®åÐÞÞ±±±J—G›6m.WïÞ½—ËEÇŽ•Öîòòrœ:u cÆŒÁäÉ“qäȹꋅk¹˜˜899ÁÙÙY©+ò²bdd„¢¢"™ÒÝÿ#!!õ»êÍ›7¸zõªLõýý÷ßxüø1k9wwwÖ9>zôHèùÚ³gOìÛ·õù1sæLøùùÕ ŸhGGG…fyhHLœ8GUúy›4i‚’’&ýgdd$\\\ê¬]]]áãã#S–Y¾þý÷ß:qÝS¦La VëááÁêç.m²^HAŸ5k€ 6૯¾‚©©©Äƒoݺ…ˆˆàøñã ”jNHÑP3f ó<Ý·o '''©Êù7àïDGGãæÍ› mŸÏW˜OdDDš5k™ÊÏž=[ê ÿÁƒ1uêT™fcccXXX(Mq-//‡ššÔÔÔ”í]à?aÂüý÷ßrÕõöí[4iÒfff k_«V­••Åúa¶sçNzT‘ãÇ£C‡2™Gkhh4HuéÒ…y¾ [·nèÕ«—Äò©©©8räÖ¬Yƒ€€˜ššâÏ?ÿ¤ÁÖ@)--­•{§eË–ÈÍÍeÌõ9‚¯¿þºÎÊñ—_~ƒƒ«ëθqãpüøq¹¾”ÉÈ‘#aee%YyVScý–š9s&ŒŒŒªÝ±&îQQQ˜>}:ÆŒ}}}‰¿yó†ñ{PWW‡ÈÊLDDnܸ!òfý‚h|øðcÆŒÁ¨Q£`aa!±\\\¬¬¬˜WWW¼~ýZ¨Ì»wïÄ>O_¿~ }}}ôèÑÿüóBÚmccƒ„„‰ûadd©õüðÃ2Æzðàºuë&SÛôôôиqc…ÌÚ+ŠÕ«WcåÊ•*9ÓRÓ ««+õ}^/^ÌjV-@Üû÷ïcÁ‚ ‹= ª„‡‡£M›62•õòò"«DYÆvZ† †^½zI'‘““ƒÂÂBf’ªk×®"AÇRRRÄ>_e‰íA  tïÞµ\‡êTÜ’víÚ±ZµmÛ¶FÛ VAçr¹3f Ž=*S´_ip¹\|øðAä_VVl‚ ê=<£FÂÅ‹ñöí[¹êÊÊÊû|@óæÍYëzúô)~üñÇzy¯ÛÙÙaÆŒ ÄëׯÅ~oVEæâ€`Ó¦MõNvjjj066–{!NVѤI4jÔ¨^ÈoñâÅ*c’-/‡ÆüQ­c[¶l‰¨¨($$$ààÁƒrµÃÊÊ ÆÆÆ÷ûøø &&†õ}Þ¾}{‰ûëÊd¥Ð úñãÇ¥¦ß¹qãV¯^-¤È "Ç–––"""Bfó-‚ ˆúÌÕ«W‘””$qÿ“'O°páBæ·‡‡¢££3ß{÷îÉõ±)~ýú!00°ÞÊ>;;[fßxÐÕÕeM=W† V§'L ““£´ºÎž= ___ÖºjzÅBëÖ­Caa¡Âê«|ŸKB]]Ga10tèP\ºt©^ÜãaaaR]âãã1þ|¤¦¦LMM¡¯¯Ïè;qâÆŽÛ ßQZZZèÒ¥‹Ü– •ÜÜ\…¹ Õ6………¬îjÒ(//WˆµÜàÁƒå«««+5¾€¶¶v°êRÐ €éÓ§3Q1Û´i[[[fbb"^¼xÁünݺ5¦L™???L˜0‹-’kuˆ ¢¾Ð­[7¬[·Žyžª«« ½xÒÒÒ„|²±hÑ"|óÍ7ðóóÃĉkÌlj-?xU°¢¢"S§ÿ?ÞÞÞ¬ûkwwwK\xÿþ=D±­ÂTµ¬µµµÔ ¹Š÷y||¼B]F…€€Ör]»vŃêEÿµjÕ ×®]cž¯·oß ¶•——‡fâÍÐÐ ,ÀŽ;àççwwwôíÛWå¯óÇ 枬ILMMáêê*S:ÊÚf„ ð÷÷§N«vvv s#ªm„¦ŒŒŒ¤¦˜¶ÁÁÁøâ‹/‰¼mÛ¶8rä’““’gyĈ8wî\û𥤤 ¬¬ ÖÖÖuvŒ…††ViµASSåååWe×®]‹3gÎ(tŸ¶8zô(&Nœ(qÿ²eˤæ„>›è;99aåÊ•¸xñ¢Ô²_ý5Ž9‚¡C‡*ýZõôô™™Ù ž¯ºººX¾|¹ÄýÎÎÎ"~±زeKºNÁ=Iȇšš455ëD ÊF1i؈**µõ&Æu'ADÃàÙ³g¬A¥ÒÒÒšŽK²³³¡¯¯uuuøøøàÆ «û«¯¾›¦ŒËå‚ÏçÃÜܼÎögxx8<<<|öig˯­L¸\.bbbеkW™Ê³e HKKƒµµ5ttt¤šÌçää ,,ŒU©ILLÄÚµk¥–yûö-ìííU.FA(š‹/bذaõâZ¶nÝŠï¿ÿž:UDGGK¢l 䊋F :AQ'9vì˜LA¸BCCÑ¡C…œóÞ½{ðòòª‘àA7Fvvv½ï·Í›7cÑ¢E*Óž²²2CWWW¦òK—.ÅÆ%î÷÷÷Çüùóáää$5çjÕ*©.AAAèÚµ+kÔx‚h(äääÔêÌÌL¹òOÿÃÈÈYYY*“Ò´S§N5j)èA!YVãÍ–-[TJ ­*åååÈÍÍ­R;---p8•1;ÏÏχ––444`nnÎá’ø‘¡¦===äææŠÝŸœœ +++…µ/ þù§Ô‰ W¯^ÐÐÐPHpÀ­[·bÁ‚ itt48Z¶lIBåQWW‡¶¶¶\&ÙöööÐÕÕEDD„J_«––ÔÕÕë… ¬üý÷ßàp8¬ÏyE%KKKº©HA'‚ ê)))°°°¨³í/,,Äýû÷áãã#ó1Í›7‡––"##«}Þ´·Ñ©S'…\CHH`nnŽ%K–°¦Ÿ200€———ÄHÑ?ÿü³Pvy‘uõÌÊÊ VVVxöì™BÆ¥¢\%ÿÚÚÚèÚµ+>|H7>¡²˜šš¢E‹råÁÖÖÖ†šššÊ+¾öööÐ××ÇË—/ëEßùúúâܹsRËT . ???¹ÛÓ¤I…¾ HA'‚ ˆ€··7^¼x!q5Xe'6¢ƒáííÝ újìØ±8qâ„RÏibb‚ŒŒ …Õ×£GÑGÿÏ;wйsg¹R‚Ÿ3f Nž<)“âÌ„rܸq¬õlÞ¼™„N :AA(CCCäææ¢¬¬Œ„¡D²³³‘““S¥ˆûfffHKKSj;W¬X5kÖ°–ûòË/qõêUêX‚¨"<PS#õEYÌ›7Û·o—»ž.]º(Ì’‹t‚ ¢Î §§‡üü|•i¿¿?&L˜ ÔsÞ¹sÝ»w¯Ó‘·³³³Ñ¸qãZ;?‡Ã¶¶¶\&§<¯ÊénôõõÅZ'dff"++ µ2Ƈ † .(¬>e®î×öXjˆ(âþ!ˆú† úôéC‚  ¢a1jÔ(œ>}ZeÚ“˜˜È¬zêèèÀÜÜqqq5zÎôôtƒÃáÔÙ~\½z5~ùå—©»S§N¬þ¢ÚÚÚèׯ®\¹RíóüøãX·n]•ŽùÏþƒÿþ÷¿àñxËLš4 GŽQˆ,Ú¶m‹°°0¼zõ ñññËYXX %%E®sÅÄÄ yóæ52.ðéÓ'”””ˆì[¿~½Ô|áDõxúô©Ä,:::èÓ§YIÔaîß¿=z RÐ ‚ ˆš#//¯ÊiÌôõõåŠÎ[‘FÁÖÖV®`gµÁªU«°jÕª©[‘ò••ÁƒãòåË"Û «åש««Ë }À€2)+öööÈÍÍ—Ë•þᢦ†ß~ûM¦1/-Å^ïÞ½qçÎãÍ›7"ûoܸ!ÐOÖØâ&Wž?޶mÛ2¦¹%%%(**b­‹Ï狵X½z5V®\ ððð@tt´LõŠáÚµk0` ¢Â½öòåKtîܹ^\O@@FŽYëíÈÍÍ•;ýÝÿû_,\¸P쾇âúõëò+“jj56©L :AQoY´h¶lÙà³nqq±Ô•JصkfÍšÕ åöêÕ+¸¹¹ÕHÝûöíÃôéÓUâ::„o¿ý¶ÊÇ-^¼˜W’°²²BRR’ÂÚú×_!++KÄãîÝ»èÕ«ÀÚÚïß¿‡¯¯¯Ôº ‘žžŽ×¯_‹ìKNNJûÓ¿™RA½zõеŒºººL–...bWÀ#""ª<. ¡­­­tß|¢þSZZЬ¬,˜˜˜ÔÊùÍÍÍQXX(uB®.òí·ßâ?þ«Ž7oÞ U«Vb÷¥§§ãäÉ“b­oª‡Ã©±÷$)èJ ??yyyÈËË“{0A4d ™çiqqq•޵··GAARr›Êúq§¡¡QgûâíÛ·ÐÑÑ‘9%MCdéҥظq£BêÒÕÕ…““ÂÃÃ%N2´lÙû÷ïG“&M¤Ö•„„‰ià*[·nIUÌÍÍÑ»woìØ±Cj]@LL «BñÝwß)T‰ÑÓÓÇh@²PTTÄ<_kÃ—ÜØØ¶¶¶ø÷ß©3dÀÁÁ999*5ù´yóf,^¼X¥åvùòe$$$°ŽqŠš¯|”úE´lÙ2dee=t‚ ä`Æ xÿþ=€Ïþ­Š ??¹¹¹JÏ5îïï3gÎTégggDEE1+¦µIvv6ÔÕÕ«ìBÐhÓ¦ ¶nݪríúâ‹/`ccƒK—.I-÷øñcVó]èêêÂÚÚ7oÞ”ZÖÔÔÙÙÙ¬“k5‚¾¾>RSS–k`çèÑ£LŠ»ÚPú´µµ¡¯¯¯Ð´}„ryùò%fΜ©Òmìß¿?Ž;†ÄÄD©å.^¼ˆ»wïR§*¥® oß¾ýõþúë/ :”¤OQMV­ZÅŸ¯¸“šÊËË¥–ñññaU‚ˆêÃápXû@^ÊËËE‚¦)2œ,csÅŠ¬÷§§'>}ú$“ À!CàêêZíöžÎ¼½½qÿþ}ŽQPPGGÇ*7}útˆl?uêFE‚%ˆ:ÂÝ»wѳgÏzq-‡ƤI“ä®G‘ì)èAD%ÊËËqáÂôìÙ¥¥¥RËfggËm¦Wâã㑜œ\«rª¼zááá—/_Ö™~...Fzz:¬¬¬”zÞÝ»w7øÈþÕ¹'“’’дiS¡í‚U0Ë—/—)wüÑ£GeÊË~ãÆ hhhPl¥:‘ø«‚³³3tuuqôèÑ:a;??U²n© LJÃAãÆ«]GPPš7o›*;zôhœ={çÎCŸ>}äN‘&………¸páÒÓÓéf# ‚¨MæÎ ‡o¿ý»ví’Z666ÇWzïÞ½‹Z•Ó±cÇ0~üxæ÷ôéÓ±ÿ~@,TŽ?@°SZZŠÇ£[·nBÛgÍš…Ý»wWY¶|>?üðk¹uëÖa̘1°¶¶f¶ 4W®\¡NQþüóOL™2¥ÆêÄw8tè¾ùæ•—GZZ¸\.\\\ª]ÇÇ¡¦¦†fÍšU»yÜz±;ÄÅר*ÁÁÁðöö®öñ\.»wïVh&‚t‚ ¢ôîÝ_ý5¾þúk& ±$f̘à³_.Û‹¢2oäååaÚ´iJ•GDD„ʤ”#ªŽ<¾šõÜÜ\aРA¬2ëÖ­›<¸»»Ë”§ …™™x<žJ¤W.--EFFFȈðîÝ;4oÞ¼ÚÇëèèÀ××—‚»‘‚NAÔ|}}±wï^p8Ö¼È|>_&Ó[YñôôÄ£G”rêêêàóù5‘¼¡bkk‹ÒÒR$%%ÕØ9öïßéÓ§+õºöïßÏL`)ƒ?BOOO&Å¡¬¬ êêê"Û{ôèÁLÊíÝ»WåS< ƒöíÛ#**Šu"XäççãåË—èÔ©“È>777ÄÆÆ"77·^È}ÅŠô  ‚P5,--‘œœŒÌÌLèëëCSS“Ù×±cGŒ9öööˆ•XGrr2† 333¹W¡­­­qüøqܼyS¦Ü튌æ­Ltuu¡¥¥…ììl¡í‘‘‘r™oV‡ó{–bøÌ5V¿‰‰ ÊÊÊ™™Y¯îÀÀ@ôíÛ—u|ª©©±öé´iÓpðàA©eRSS¡­­ CCC‘}666øôék›]\\I>Ba4nÜÅÅÅ(((P‰öœ:u £G®‘ºmllÀårQTT$µ\QQ ÅÞ«ª„ `RÐ ‚ Uã‹/¾Àõë× '''4iÒD¤Ì¤I“pøða±ÇkkkcðàÁ4hzôè;wîÈÕžÁƒãôéÓ2ÎY¹re”»••ŒŒŒD&Ö®]‹Ÿ~úI©m).̃–. « ÊÊÊÀápDV³õõõÑ´iS&wyNNŽ\Á¢Fމ€€8¡tÜÜÜ™™Y£2U¡¨¨ÚÚÚµÚ†ÔÔT¤¤¤ uëÖ4@RÐ¥¥¥Ø¡MB jMMMÌ;³gÏ–©|\\ rîÿüç?À¬þþûïX°`ز}ÚÓÓÓåÊCÍFóæÍñîÝ;¥öÃüùó±mÛ6…Õgkk‹øøøkoRR’Ò£ËgddÀÐаÚìÙ¯ººº055­ÿý÷غu«Ô2!!!°µµ W‘Õ«W×ÙÉ/¢îRW‚ÕÕ4Ë—/ÇĉÁáp䊭ÁvŸ¤ •8q⊋‹åª£¼¼¼Þ™ UãÇ$!u†„„Œ=qqqr×åàà€+V`öìÙøë¯¿|^…—‡:$$„ñgçóù ¬QÓ¾Ÿ~ú k×®Uªl ê¿9cÆ ìÛ·¯ÆÚ{üøqŒ7N©2 BÇŽ¡££S­ãW¬X_ý•µÜ°aÃpáÂÀÍ›7ѯ_?¹Úíííàà`™Ëgffе„pæÌlݺbýÔÀÐÐPÄý‚ ¤!‹Ëyyy”òŸÝ222@Èí¬ªK½Ï RЉJüóÏ?¬Ñ*Ù‚2 ˜;w.ÊÊÊÚ¾?Ö©€I±±± —AM²råJp¹\¡m111øý÷ß«\ײeË_~ù?~¤HÔ„Êrúôi;v ›6mbîÛ¬¬,´mÛVlù;wbΜ9b÷5mÚ‹/–)—mxx¸ÌÏS¢öàp8044DVV–Bêóóó«–Ù÷Â… YWœJ°¸4I}úôÁíÛ·>D×®]åº///<{ö )))°°°«®îÝ»cïÞ½X»v-&Ož,±œ¦¦¦HNv¢n'WJ1YyôèºtéR£çøôéSµrWdÇŽ˜;w®\u>|XêýC¤ ÿ?'Nœ¨“x/\¸€üü|ŸW—îß¿Ïì[¼x±Lu²3gÎȽ*/`éÒ¥uJá]µjòòòêL{ÓÓÓEä[RRÂ̘V…´´4ðù|p¹\<þG¥§¡pú÷ï7nH-ãááׯ_ƒÏç‹Ý߬Y38::2㼤¤eeeýÍÍÍ‘šš*WП‚‚|úô ?þø#«²‡‡Ö‰n©«¤Êbܸq8qâ„BêÒÒÒB=¨úªkU ££#qbHÀõë×áãã£Ô|ïŠP tuuáèèGGG©¬,,,°dÉzðUsss¹W“E}rWزe .\(ñýóòåKV] 33FFFrµ#;;[¦ÉáÚÆÎήÆ'Mˆ¬ s¹\VŸÅ3gÎÈ}>ŸÄÄD©eBCCáïïÏZWBBk™ùóçãŸþAAA’““‹G¡°°iii¬Çÿý÷000`ÌÐ.^¼ˆ£GâÔ©SBçGrr2Ö¯_/ñÁSÙ´mÕªU¬æô²\ó”)S¶:¢*:t¨ZùŸçÍ›‡ß~ûñŸÈ/!!›6m’ØwÉÍÍ’§,} III¬4²´OQí!jŽÞ½{#$$„™(”DÅUAI¸¸¸àÍ›7¬cÇÌÌL¦gœ€sçÎÁ××Wì>wwwäååáãÇb÷ïÙ³3fÌÀÂ… qñâE©ç‰GHHˆÊ÷YBBôõõ«¥  77|Mh×tp²¬¬¬ŸˆÐÕÕEii©Â&¸«Êùóç1|øp‰ûõôôPRR‚ÒÒR©õXYYaÛ¶m”ÓX055E¯^½HHLL¬Q_h777¼~ýšÒeV Y³fèØ±# ‚ôšaÿþýxýúµÜõ°}Däää`ÅŠRÉËËQTïÝ»'ô±‚#F°¶£¢ò²~ýzìÚµ ÀçÀ_{öìAFF†Ôâäädôë××®]c¶M:UHa{ò䉨¡’’¤¤¤ ??¿þú+Þ¿Ïì»víšP‚sUþ8¨,Y6Æ7OVBCC¥¦xª©ñ ®LRR>>¸ÿ>kš Êäææ"-- öööJmo@@üüüjô­[·Fff&âããqïÞ=ôìÙS©×Èãñ¤NB´oß®®®8p Ôz6nÜ.—‹víÚуP9dá@(Žš~v HAŸ6müüü¤úŽ:u Ož<úpÈÍÍ*#0û­ÈñãÇ…~§¤¤°¶gúôé¬b·oߪëáÇ" eEsõÊíì{øð!ÊÊÊSç²²2ܼySä||>_hB`ãÆøá‡@Ä?­²Ù|\\<==‡ôôtüüóÏxûö­Lý“žžÎ(ꕯC\;Ùü¡ Áãñ„”Ãõë× ­d¾¤qc¢r™ÄÄDÜ»wOH¾•£å>{ö C‡êÛÓ§OK\ýX¼x1vî܉ÒÒRp8&€VNNŽÈØËÍÍE^^RRRpúôiŒ5 fffˆ‹‹ƒ––Úµk.—‹> 33#FŒÀîÝ»™ã¹\.<==„£G";;S¦LÁ­[·|nõòåK<{öLè¼×®]š˜:xð “Hš<Å)6ÿääd!y&&&båÊ•B3999¬«»„x–-[Æ>>¸~ýºÔrÆÆÆ2¹‡äääHu…ñ÷÷GJJ kº ‚‚fž–¦ IDATb+77Wl`:E2|øp‘‰4e“››‹ÔÔT8::ªÄØž>}:8 ðzoß¾>}ú(¤®ŒŒ …e 8p f̘!µL£F°fÍ´hÑ‚~J`×®]ÌóµòâAÈò>ªéw‡²qõXA?pà˜YóŒŒ ‘6.—+df~éÒ%‘•ÆåË—³šRÏš5‹µ=<¯Z~ÁyõêtuuqéÒ%\¼x111°··Ç§OŸ`aaääd@pp0²²²püøq„††âûï¿GHH³ÿøñã¸yó&òòò„|Ãìíí;;;ܼy)))ˆŽŽQ²€Ïù!ߟÇ#44´JײfÍ$%%!((HÄ’ ''GhÅ???ŸÕ‡-44þù§Â¾|ùr¡Ü°lfµ·nÝB§N„&-Ö®]+ä®°cÇôîÝ[dr â‡?ŸÏñ;ŒEXX˜Äs‰u‹L(ȘêÇHJJÂ¥K— ¥¥___4jÔH¤ÞÒÒRLŸ>ׯ_JiµaÃôìÙNNN°··GII ^¼xÝ»w#**JHÙ())AXXrssqêÔ)ܽ{™™™Ì$Ill¬Læa닪òøñc&â¶8Š‹‹±fÍ¡± ’[ûÊ•+¬æžÄç±!xž²}Ü+’ììlÈíŸËápФIV÷šÅ‹cóæÍRËhhh ¸¸X줧€ÔÔT³š:W´:þ<† &¶\`` 3!ðøñctîܹZru¢!QñÝ©ªTœ<—öÌ‹‹‹CóæÍ©Së³gÏfž¯´2LTi®[¡r º¸&KKK>|Xh{åüuëÖaùòåBÛ*~Ðð²y"&ÆeeeB«·Ue×®]¸{÷.þøã±ûóòò°páB<}úžžž8vìüýýñéÓ'899ÇãÁÆÆoÞ¼AÓ¦MannàiYlmmÑ¡CDFF"77—.]ÂË—/ñäÉäçç ­2FDD E‹ððð@BB‚‚‚àççÇä~ûö­Äv Vg*×Y™Šò¼zõªHrÇêãYUx<nݺU#àòóóYc¼}û–IÏTú qçÎx{{cåÊ•ÈÌÌDAA444PZZ uuuhhhˆ|ŒëëëcÅŠ°³³Ã³gÏpñâE\¸pAAAÈÏχ®®®XYW ''ååå066ðyÅÇãaË–-"ÁõôôŸŸ»wïJ]©dKéV9íŸ8…Biá pèСZó­¯(*½,ʤ££#ÔÔÔd¶Ü‘…ÆK ¦¥¥…#GŽàêÕ«b÷/Y²„±2ÈÈÈÀÞ½{1sæL±eÏŸ?777Ögùsçë®[·n)le–æÈ‘#˜4ik¹«W¯âË/¿”û|¥¥¥ ’ÚŸ'NdWãëë‹›7o"##®®®Ô‘„?~¼J´%##ƒùžPuêJ;ñ-ôìÙ3tïÞnRÐkkkk&V~~>222`kk+TÆÉÉ ÑÑÑBÛ¦M›Æü½ö×µ0772OHHÀþóŸ*µ%<<YYYÈÍÍEll,222ðéÓ'dee ùz÷îÝS¦L« ÌòÿgggCGGZZZBåtuu±qãFìܹÄwß}=== 33SjnÄU«VÁÐÐ:uBQQ’’’ 6å‹……c2-.Js\\ÌÌÌ0oÞ¼*ÉêŸþú}íÚ5 0@j™têÔIh[e9FEEÉä¿ZÙ<¼[·n"þãÕáÑ£G2åŸ?{ö,®^½ŠôôtáíÛ·X´hæÎ‹V­ZÁÍÍ –––ÐÖÖ†¦¦¦HTQ777èèè -- áááX±bpîÜ9fRÅÞÞ^èîeË–€íÛ·£°°€¶¶6æÎ‹5kÖàÇ:t(Þ¼yƒ¾}ûâúõëØ³gÎ;‡ŒŒ ¡I—„„„‡‡3¿£££ñøñcåK ÜóxÉ”ŒËåÂÔÔTîóñù|dffJ5_÷ôôÄÈ‘#Y#¥oݺµZé5‰úÂãgT—éÓ§cÿþýuBnòº¾¢_¿~*eeeÈÎΖ;"=A ºBÈÉÉARRþøãlܸQh_qq±ÔÀ7 ¬+33¿ÿþ;V­ZŘAJBîÑ£GLj===|üøãÆÃ›7o£GЦ|^Á©¬„ŸS`hÔ¨Ö®]‹o¾ùÌ,YJJ Z·nÍ(Wß~û-¾ûî;ôîݽ{÷Ɔ „Rýý÷ßèÕ«ìììŸŸØØXœ»yó&îÞ½‹uëÖÑÓYA,[¶Läþ­Œ DbTIV âY‚^ihhÀÄÄDÄ"¥2¿þú«Ô‰Y___Ì›7Oìê§šš"""зo_ÖgEII ÔÕÕE⣈£°° Y×Ù´iSMÏ%p›aC²`gg‡íÛ·ÃÌÌŒ0„D*¾ï‰Ú—‡ŽŽN:…¯¾úŠ:ƒ ]Mš4A‡D¶·jÕŠQ†\¹rEHQpwwÇ«WBe6lØ òY\\Œ˜˜ÄÅÅ¡K—.bW‘ããã…ŽËÉÉa‚Ž-]º7nD\\’’’›› KKK¸ººâ«¯¾ÂÝ»w¡©©‰/¿üÆ c”&¸¸¸ _¿~pwwg”ÄÁƒÃÞÞžQLýýýáéé CCCX[[côèÑ;v,¾øâ ˜››ÃÌÌ ‹/fR«tïÞ^^^èÒ¥ SǦM›0zôhäååaÞ¼y000ÀðáÑ““#´:õòåK|øðƒÆëׯq÷î]‘LjˆÏ2ýá‡ðÛo¿Çãa„ RWØß¿/Ù<&&^^^ˆŠÞ®];ÆyùòåBŠX~~>îÝ»‡ÄÄD|ûí·Bõ¹ººâõë× AÓ¦MahhÈ\«ØR[[fffL?FFFbøðá˜3gŽH€Áääd¼|ù/^¼€§§'àùóçHOOG›6mŠeË–áîÝ»ÈÎÎÆÈ‘#qçÎøøø09}ãââ`ii)2Iãææ&¤ŒôèÑ­[·†……š6mŠ7¢eË–L¹Ã‡ÃÁÁC† a||W¯^Í(üÍ›7‡——–/_Ž–-[¢]»v DûöíqòäIæ\–––"¦`ÎÎÎHIIÁÉ“'ñý÷ß#&&\.ZZZÌÀ7ß|#tLeŸ^Iyzƒ‚‚УG¡1ññãG”••I´H˜8q"x<žP;SRRгgODFFÒÓYA8;;3Ï%i µ†††H Æê²dÉlÚ´I¦²}ûöemŸ³³3¸\®Ðý$777VsâvíÚaÀ€"«Ÿ–––àr¹èÖ­&Nœˆ£GJ¬#((ÎÎά>ÈÀç ‹ÁÁÁˆŠŠ‚³³³Âúµò=§ ¢££ÑªU+…ÔuçÎÖXYYY(--UÈÊxDDÔÕÕ¥öAtt4þüóO•ÉqM¨.žžž¬Aɵ¿‡jƒÉ“'+$‹Ã£Gj<ÿ¸ RÐkKKK©ùA+@Ÿ9;;Ã××wïÜ z¥¥¥…µk×øl^fff†±cÇ ÕSXXÈüëÓ§ž?Žˆ««¼‚2vìXìÞ½™™™hÑ¢zôè 6 )) ;w†††444¿c9eË–-¥ú²côèÑÌoI~‘&L˜}}}Œ3FFFÐÒÒ‚žž´´´„V£ûöí '''æwYYÔÔÔðüùs´oß?ÆW_}ź¢'dr\^^Ž¢¢"p8¨««£´´? ¶öüùs8::Š5I}úÀ¼,Ùéÿ‹b½bÅ æcHGG:::¸{÷®P=£FÂ7ß|ƒ‰'âúõëHOO›ª`Íš5øý÷ßѦM4nÜ#G޵ÛÚÚfffðó󃯯/¬ÔÔ«W¯Æ£G°|ùr¼xñBl™öíÛ#((Hèc355U(’xJJ ôõõQPPMMM4nܘ™¨Hzz: OOOôêÕ‹ p6räHØØØ 99ÉÉÉ000R2Ÿ?^­ü­ïÞ½›Væõë×ÈÍÍeL²õôôп|øðA(ÔÞ½{Ì×£GÆ÷ºW¯^ˆˆˆÉû)sÔV;;;888 mÛ¶À˜ÝwîÜsçÎEÛ¶m•n*hCÅÿ+¿P,--1iÒ$„„„ø$F $•••¡K—.ˆŽŽ†®®.¬­­]Á„†`R$)) žžžB1²²² ¥¥Å|ðx<ÄÄÄ }ûö˜;w.vìØ7oÞ C‡Biâd ¼DÈ7&¤áîî.S^UÁXgãÑ£GuÚÄS`~/ÎW}ܸqpvvFjjªD·à³uNåÀõ‘-ZT+(`›6mrþÿý—µ®Êß•ÑÐÐ@ÿþýiåŠPŽŽŽ¬Kòbjj*S|E¼W¥=÷UÆŸ¾¾ ¯¯¯°ô©)èÕfìØ±By–õôôàêêŠG!44]»v…——^¾|)чÜÁÁ1çóùPSSc|•+¢££ƒN: )’°µµÅ°aÃ`ii ???F144Äwß}§ò+X˜;w®ÐÿùˆŽŽ†™™x<ôôôŸi+++¡º»w»»ˆUÀ’%K˜¨ôâ¢Å òz‹C]]eee(++YI»ÿ¾ÔU§¸¸8ðù|Ƨ¿"ýû÷ÇÞ½{™à'³fÍ‚††¶oßΘíKZ½«èW?tèP¡•ÿ^½z¡sçÎèС:wîŒöíÛ× ³HÁ˜pqqÁáÇ3ÞqãÆ1¾™ÅÅŰ··gÆzåUºàà`!ÓÚÖ­[‹¤¹«x®¤¤$1uŸ£^“©j1hÐ ™ZuèСAD,×ÒÒÂáÇáåå%²oÏž=èÓ§V¬X'NHŒl_VV†¡C‡Šµ‡À2E‚çdUølaÆ¡í§Â~ÅR^^Žòòræâxüø1<==•¶B4yòdôë×OÄ¢Ž jŠ.]ºˆ}v¨={ö .\UúôéCæüQôÊhjjÂÄÄIIIHNN†µµ5ë17fü­7lØ€eË–aþüù˜?¾ˆ¢hii)´z,ÈÉ.Pþ%ù Ãikk£uëÖÐÔÔ”0¬¶èÖ­ó!-‰ÁƒcçÎÌ jåc4jÔ...ÐÕÕE£Fˆ;vˆ¬2xyyIý «LTT\\\˜ÝY³fá›o¾Ê›. ‚”c‚ÿŠØÙÙ1éí`äÈ‘Ì$NXX3#|ûömäçç#??ˆÅ˜1c˜˜WWWX[[ãÂ… øôé#S¡c 4kÖ bWüUuL˜šš¢U«VÌöŠ“!QQQŒ¿©¦¦&LMMáââ‚õë׋ÌÚïÛ·­ZµBNN3A#müUþ©nº;BùXZZÖºi§ªðÅ_`õêÕ¸sçŽÈ>gggܾ}.\k}U‘'Ož0“ÆoÞ¼ûþÙ¸q#–.]ÊÚ¦Î;#6âóýóâ,ìœÑØÄR¤mººº­®äáØ±cHLL”úÑŸ””sss¹]ºté‚“'O¢Y³fRß?®®®:t¨L¢!Ñ´iSøùùUéû ˆ¦ g’4hIJ[¶l‘Zל9spÿÜNÜ?¿EyJ¿n…ùÆ?~\êª÷¼yó0vìXtéÒ… ‚È#ÄZV¤â{_'Nd¬*k ___ìÚµ‹:Œ TQA¯ªŸò¨ùÛpzÛ|©ettt`hhˆÔÔTLž<ƒ BÓ¦MÅ®ÊwìØ[·neV«ã‚èñÍš5cý8REôõõqèÐ!hhh0®‚këß¿?¦OŸ.!_ÀêÕ«±råJüðÃ2¯†ŠãéÓ§044”yõB]]~~~BQÉûöí‹ððp‘hÕaòäÉ8|ø0`çÎ2¿x2ÓÓÓÑ#GÀáp„ÚX—ô·àCCC™£37#FŒ`ú¶}ûöBûcbbä¶"°··Gll,=¡‰z››Š‹‹Åt8p JKKáéé)u¥]OOïß¿—ÉÊ(;#a÷Π¬Tþôn¶¶¶ˆÇ“'Od*¯§§'Ñ|ìØ±8uê«i}›6mPRR‚“'OÂÃÃCòŒš†.“•AÔåwµ$öïß/5W¶‹‹‹Ü¹´[·n-„¸:íÜ·oŸHf™Êí”61 'OžrÍ”öVS,]ºTä›§:4nÜX¡Y=RÐU G © 1p·3`L™G%ñAÁápÀápн{wÆünÆŒLj¬~øAèæ˜VÜVWgé× ø¿¢©¤@.ÀçÀ&C† ­­-†Îìì—–nM_}õ•LªÄõUÅ8Áïk×®1¹£FÉG_Õº+ö­àÚ$]cE™U–g]ŽŽŽcôíÛWÈ¿¬âxغu+¾ÿþ{¡ò.\9;ƒ$úõë'’â ê*«W¯Æ¬Y³Ä¾?1ˆ«W¯J¬ÃÂÂgÏž•i"­‡ï,…(çÀçÀšAAALZQùÞÙŸŸ½<q§ª\näȑظq£Ôú444pîÜ9¹}h ¢67nœÔ‚ýúõcMM¦*ß líPD;Ùê;vl/¢)J°³³c\. BìûMaggkkkœ8qBj¹?þøîîîØ¾};³-7+ VÆ:000ð9ònÅ”_$)‰â>¹°•¯ÕÄÄ„Éí)n¤rɉ'ŠH:xð .^¼àsù§OŸ ­Àÿúë¯hÓ¦ “ÚN5¾rûÿýW$rhdd$ã».è늬›7o†³³3®_¿àójNß¾}Yg+^[åklHãA__Ÿ±t˜7o:wî,÷‹5::ZÈzBùzÆŒ̶ӧOÃßߟÌT ‚WWW©‘ã ƒÏxD=»ÍZWAA¢¢¢Ð¤IÖ²ÅÅÅpuu•š®qÓ¦M2å†ÿðá«Ùm›6må T¶ r²ZµŸ‘ÅW–ï¹cÇŽ‘0‰ZG%¦Þ+r#ÔvëÖ <*§¥¥™ò>V¦r´Ø™3g )_ý5ôõõ@î|ªu Áµ¶lÙR$ªö!C`cc#õø¢¢"Ù–––2ÁÅQ16ðÙÔÇÉÉIÄ4iÆ 2Eª7oÞÊ0sæL”—— ˆ*--Uj.l‚PEþþûo|õÕWRËÌš5K$vˆ8: ˜„Çפç&OIIÁÁƒYë:xð öîÝ‹«W¯2ïÉÊøúúâÔ©SRxÁý?kÖ,êl‚ jí›·*úBMP2A¤ 39ò¿‰–-[âãÇ8pà@œ«oß¾B º···ÒR¾¨"–––pwwÚÖ®];©>CcÇŽÅÀYëöôô1ƒž7ožÈìq¿~ý˜¿ÍÍÍ…"°Ÿƒ#™™™ mkÔ¨ëJLeLLLDrvvîÜYäób{"ÊwË–-…¢wÛÛÛ³úš{yy‰¬ÎU–«¶¶vÝçQWèÞ½;._¾,·{ˆ€mºãÝ¿÷%î·³³Ã?ÿüKKKôìÙ›6m’XöîÝ»RDÿ³–’åÝÛŸ­A¨.­ZµbddÃÍÍÕžJ5qÿé§ŸÀãñ@$½WŸ>}Äëªlšúè#Œ9™™‰ØØXf 5øÜIÔ¡+èOYnh[íü¦ôèkãžÿ›»jjjŠÝ»wóõòôÜbèÖ­¦NÚè>/½ô’ZoyK4uN˜˜˜Ô":lØ0i¥~j[ãÆÃ€=GêÃÑ -÷ôê¿!ôâèÙ³g³ßpðÑŒ úN£q ›µˆ&Ñ‹ÄÄÄDº¯Ö^Ÿ†¨¥ÏÆDíº‚Þ&7Ñž/£·ÿÍ'îÑ£ìííY²òñÇ7k›¦I­Þ5ž~Eµ­Úyÿ¼Ï¢Ù{ãÙ£MDÔž‰ZB‹Y@DDDDDDÄ :±‚NDDDDDDÄ :±‚NDDDDDDÄ :±‚NDDDDDDÄ :±‚NDDDDDDÄ :±‚NDDDDDDÄ :±‚NDDDDDDÄ :±‚NDDDDDDÄ :±‚NDDDDDDÄ :5ƒöóLüêÕ«èÞ½û3ï_%!- “±0‰:‹Q£Faï޽̈¨¨¨øM÷Sê>Æ k÷Ç™€7ß|ýúõk×ÇyèÐ!X[[ÃÌ̬Ý_0ÿüç?1sæLçs8ÎðŽÝöööîPÇ\UU…;wbúôéIïúõëÈËËÃÈ‘#5’Þ±cÇ0pà@¼úê«ò> ÉôJJJðÝwßÁÉÉ©ÍÓR©Tصk¦M›¦‘ïvíÚ5àÏþ³FÒKJJ›o¾É›f 8!!!ϼÿÎ;1yòdhkkæ‘»  /^Ä_ÿúWå‘R©Dll,ÜÜÜ:ýó%fÒ 9IDAT¦ÓÌÊÊüáÐXšyyy¸|ù2>øà¥YQQ¸¸8|öÙgK3** NNNÐ×××Xš‰‰‰2dú÷ï¯v©í¹VÐ]]]aeeÕ®oÌ·o߯„ ðÆo´ëã¼s眜œ0tèÐv}œwïÞÅ'Ÿ|‚ßÿþ÷íþGùøñã˜3gó;ÎŽhÈ!2dH‡:f•J…“'OjìœHMMEFF†ÆÒ«¬¬Ä;ï¼[[ÛNy}i2½¼¼<”””h$½G!--McßíäÉ“ÈÎÎÖXz …BcEß¾}Sù¤¦¦bÖ¬YÐÓÓÓÈñfgg#!!A£÷ƒû÷ïãâÅ‹ÿÏšNó›o¾¸¸¸h,ÍÌÌLÏ_ýW¯^ÕhšgΜÁŒ3`bb¢±4KJJðá‡6ÙPʱ:DDDDDDDí€6³€ˆˆ:»·Þz«Ý0ú-¾úê«NûÝÌÌÌàïïß)¿ÛÛo¿Í!çDDÄ :½Xºté‚.]ºtÚïgjjÚyT´µ;íˆzzzúLDD¬ 7ªOŸ>âa©wïÞâÇ“ÇÙú:ÊBe'zõêƒNûý:kÙÉd2µÅ{:SSS.ˆD@ÿþý5ºú»žžz÷î­Ñ逸¥ssóâ>¤é459?º†Æ}µµµ5¾€´¹¹¹ÆßÌÐÜzL!xû$""""""z¾Ú´=!!;wî„¥¥%–.]Šnݺ5ÿÒ¥Kð÷÷‡žž6n܈>}ú°„ˆ:¥R‰ÐÐPüðÀF¯áªª*ìÙ³±±±°¶¶†——ŒŒŒ˜‘Ü£GŽcÇŽÁÁÁ¡E«ïß¿?†‹‹ Š‹‹áëë‹ÒÒRÀÈ‘#1}úôN=L¨)¹¹¹ðöö†––¶nÝŠ¾}û6k¿’’ÈåréuŒ¥¥¥X½z5rssÑ¥KDGG3sùmÛ¾};N:…>øS§N…®®n³öŒŒDÏž=áèèˆÐÐP$''KaÅÅň‰‰ÁþýûqôèQµÏ\½z5²³³¡6gñâÅ1b …¨•=z;v쀅…üüüš=êçŸÆŽ;ˆÓ§OcÆ RXee%ÜÝÝ1qâDܽ{¾¾¾¸wïÌÍͱyófµÏ)--…¯¯/ÂÂÂÔmäàÁƒbçÎB!®]»&V¬X! Eƒñ322Ä?þñ!„J¥RÈårqíÚ5ADÆ DZZZ³ãÇÄĈ½{÷ !„8{ö¬X¹r¥¨ªªbFvpaaa"))I!Ä÷ß/¶lÙÒ¬ýħŸ~*„Bxyy‰¼¼<)|ÅŠâìÙ³Ì`zaegg‹•+W !„P©TÂßß_\ºt©Éýîܹ#–/_.ììì„B”••‰+Vˆ7n0S›!((HœnÞ¼ÉÌmDJJ Þ}÷]ÀèÑ£qäÈ‘Fã !°ÿ~TVVbÒ¤IuÂïÝ»Lš4Iê­;{ö¬týãáÇ€¼¼>>°¶¶†­­-òòò`ll ¥R‰üü|ܺuKŠ«P(°~ýz¸»»càÀu>‹«¸S‹x{{«U”œœ0f̵ ¼J¥jõtËÊÊP\\ÌhÇnÞ¼‰   ( € ÜÝÝ™1ԨÇ£°°Ó§ODZcǤí5 ñ¤¦¦"==_~ùe§¾¯KÓÀ/^ ¼òÊ+REº-Ì=z„‚‚ž„ÔíÛ·†ùóç×Yð);;AAAxðàd2FÑ£G3ÓZÁPQQ77·z;’““abb‚Ý»wcáÂ…°³³Ã?þˆ}ûö6n܈¬¬,X[[ãСCÒöèèh$&&büøñÌäVpðàA ** úӟлwoøøøÀÄÄååå˜;w.+è­$66<ÀðË/¿@¥Ra„ ÐÑÑ‘~œœ°xñb”””ÀÑÑŽŽŽu>ÇÞÞ^YJ­ï/ù d2€êN ï¿ÿ^­WÔÊÊJmUq•J…˜˜ÄÅÅŒŒŒ°mÛ67˜Æ’%KЯ_?œ:u °nÝ:XZZâÉ“'Ç¡C‡¾¾¾6lÊÊÊ0mÚ4iOOOŒ5 ÷ïßÇÌ™3QUUpuuŸqãPYYÙ¢glúmþûßÿâĉ8wîT*•ôŒRó[gee…   $''#55666077G@@ôôôpéÒ%ÄÄÄÀÜÜF@¥§§#44sæÌù_bm5®?<<\|ûí·Ò\???µqýéééb÷îÝÒÿÇŽ!!!B!>|(V¯^-Ο?Ï íT\\œø÷¿ÿÝd¼… ªÍ#7oÞl0~DD„ptt”þ¯YË ))I888ˆ²²2!„™™™"00°Þy]óæÍwïÞ3gΔ¶WUU‰;v!„?~¼Ú>µÿ§gÓT¾îÝ»W¤¦¦JÿoÛ¶M$'' !„¸råŠðññáôN`Íš5"##C!DVV–P op^eRR’4=55Ulܸñ…Ê»“'OŠ   &ãÕž›š‘‘!²³³ŒŸ––&lmmEqq±Bˆœœ±lÙ2‘››+¬­­Åõë×…BÜ»wOL›6­Ñë»öu]3—÷UÍž*•J¬Y³Fœ9sF ÏÏÏ¡¡¡¢²²²Ñ2,(( ,P›9eÊfpž^ÿ"==]¬]»¶Î\ó”””z÷Ý·oŸ4ý»ï¾<Â-Z$rssEzzºÚÕšõ\Ο?¯ö¼%bccY ­ìÆÂ××W­lêsùòeáãã#ý_VV&bbbÝçõ×_W;7j®ÁáÇ‹øøø&ï—5Û]\\ÄãÇ¥íÑÑÑB¡Pˆ ˆüü|iûòåËŹsçX¨Í!öïß/„âÖ­[Âßß_ܽ{W ?sæŒˆŠŠªwßÊÊJiúõë×Å•+W¤°ãÇ‹‘šš*6lØ mÏÉÉ~~~M>? !D›5±xxx`×®]pvvF¿~ýàíí­ö.¿¤¤$ÄÅÅáÓO?•Z²tttàìì ]]]øùùÁÊÊŠÍ5íLMÏyiii³zG?ÿüsÈåri^ÏÇÜ䪳5Ëjsuu­ÓRY»ES©TbàÀèÚµ+†*Í-‘Édصk—ÔV³?~Ì‚mNNNjùêé驾mÛ6ØÛÛÃÎÎN ÿꫯ‚×^{ _~ù¥ÔšM×_|àà`¬]»666˜7ožZxxx8LMM1räÈ:ûjkkK+ÇÇÇãܹsHKK“Â7lØ ûîlÒÓÓ‘••¥Þ‚Þ€±cÇbݺuÒH #FÔ;®öõÙ«W¯:ÛGKKË:ÛkV¶­ñèÑ£z¯óõë×~ùåµí:ßúÞ}÷]téÒÎÎÎÉdËå:t¨~õêUøúúb„ õ¾ë¼ft[¯^½`aa!•—¶¶¶4Ì—êš?>¶nÝŠ€€¼ýöÛ˜;w®Zxhh(lllêííÖÑÑ‘z={÷î éZ²µµEŸ>} R©àíí-½±ÂÚÚVVVP(X»v- ƒ ‚—— ¤UVV",, ^^^M¾!ÄÜÜ=zô®cccµÑ˜õyýõ×ë=/ÌÌÌðá‡ÖÙ^TT„/¾øBú?33àççWWWˆÿ3ö”)S`hh˜={¶tm׬EÍ3yòdDGGÃÙÙ}ûöÅ’%KгgO)<99ÑÑÑõ®%!“ɤ|722¦M›¤© fffðöö†±±1Ž?.•I÷îÝáããÓཹv…‹¨E=ç»víjvüÓ§O‹òòrµ–èÆZ÷"""ÄüùóëíA¯éY{ºýüùóB.—«í?oÞ<ñàÁqêÔ)i»J¥ÎÎÎìÙ!¢v'%%ElÚ´©ÙñsrrDaaa³{ÖÒÒÒ„‹‹‹4ééôE‹IñjzЕJ¥øì³Ï¤í'NœcÇŽ•zšÓ³NDÔÞ{ν½½…J¥jVüÒÒRµ+wîÜžžžî3|øpñÓO?5y¿¬oûÕ«WÅ[o½%¾xú8gÏž-îܹS§:NR Ù¾};ôõõqðàAÕ+É~óÍ7 Æ766Æœ9sPQQ zá°¦zÀŒ¥Ö¦þýûcÑ¢E¸rå ^zé%)Ž––´µµaaa]]])¾´µµ¡¥¥…ôôtµ¹’K—.P½ ëÓ-Œÿú׿ÔFwiRTTnݺ…ÔÔTµ^¹šEfjÓ××G`` ´"¬¥¥e“‹èaÞ¼y(//‡‰‰ –,Y"õž>Ý# ££]]]Œ1BºO:88H# ÔîŸÓ§OP=Oþéí«V­ÂàÁƒY¸DÔ.9s§N‚‹‹‹´möìÙxÿý÷믭­£GbÍš5ªß8ÕÔj캺ºˆˆˆÞÂ1{ölidEí‘@õ´šûèk¯½&­MÒµkWLœ8QêA·³³ƒ‰‰ fÍš???éÛÅÅEíûPÇ%5¥MÔDFF¢k×®uŸ#"¢góÃ? -- ‹-bfiˆ““_LÏD‹Y@DDDDDDôüýÙçÖÒ%ÄtbIEND®B`‚snd-16.1/pix/scldlog.png0000644000076400007640000000246411147553270013303 0ustar bilbil‰PNG  IHDRΓIm±º pHYs:ÊduhtIMEÖ 2 êN+æÓIDATxÚí1nò0@M•é;p€^£‘¨8E@·VêV‰!C%¤H0p„œ"¢RÀ zƪã?¤B‘MLâØÆqÞS‡4Å.±þ>'Ní÷À=7VjÉ–M%¶z6[fI¹µûÙu¯ÎJ% {¶XÖF5OÕ ’ºÈj’!> zvú2•öŒÊ“Õ¼¯X‹·í ¶f¥©‰•IGi'3Ðð§¶Ýd\„\ ˜À§1ñzûZn¬Ž«¶¥ZÿŒ3®$nÏNºT·/²:®NŽž­|_ÍÏÔ)gkÕºˆÝ-‰Õ³jÿ:íÐĩȽ©M‚¬RËNÝÙS)ËþuÝ¡1Ðj,»ÿlHmdÕzzñI;³`Í´@Àúk[]÷«£Ñ`㩟þ½¬Úîg×Ç@i6ufšï§c>¯¦WG ˆÝƒuùC¬$WÓí©þ©ÜP<}6ÑÑ8ÚF~ W5C³Gݨ+UýUpm‡¨ÚGP@5#(Ȫ½+Æ $³42ÖdËJ‘ÑÙû@ÇÇ1]ÆnÒžó7çëbû´ýþþ¦ÉÀ€<Ïg3u.ëÕÀ¨¨¨€j€j€j4  ªªÁÐ zQš¦Õ_¿¾¾º”’ö·ªbV-MSÉuO«RjÙ³òÔ¹Ê0PÕ †4ãRÀ¨ÖÉM)D5žªyò Qñ ÕBõ,MSé„ÅÅRˆx-út W4;ãjV †«šÁ©&¥ÐŽ ¨€j€j¨ýš²üÆîTÕt"‡k¢œSßøü€¶:]äa`ˆuFæq%ÞŽ¹.#‘æ’M‚ÚYe * <€êß^ÝñªãŸêÐ 7×;g–ì_½\T˜‘—k €j€j2ÁNZQ P P À€D‘-3+u ü \øþš*źöŒö¿{õuã㘯ÈãÜìc&íÌ–Ùß)ÜÝÏ®êãöiK“A$£ÈÕ€i ªª   ªª   ªAÀÔÞÊB?ð¡Úáö ®n°¬ÚôeZ]×Ö„b],ÞmKAøXìYr5`Z¨`ž«©·R™Åu4ÖŒ­{%£ýïÞÖ} þ¾äßìîF)…IEND®B`‚snd-16.1/pix/edithistory.png0000644000076400007640000003214411147553266014226 0ustar bilbil‰PNG  IHDR·á )sBIT|dˆtEXtCREATORgnome-panel-screenshot—7w IDATxœíÝÏ«%×} ðó‚ ¢›dÙ&+[NÚ›!‘±°ñÂH‰‚“E¶b4“™F³²eoNÐ*D™™¥½²hbGÓd,ô¤1­N$¼0m¬„! žH–°ÒÏmx³p×Suuý8§êTÕ©ºŸ4zºuî©SU÷¾÷ýÖùQG¯¾zõ$ï¾BøÌg>½v;€=÷Üwï¬Ý  ’ „ 9î!Ép‡ä!H€;îK}ÃÑÑÛNNÞk-Û|½­®®2sI9޶÷¦ë\ÚÚÒõúZmŒÕvMælkéçØ®”-¦®ÊÜqKrrB|£†ÊUÛûõ9å<¹1uù0äTrœó û¾’Ï@eɘٰ" „0²ç F®î¥‡š í¿ëîvìöÜÝB''ïÝs—¼oHQß~‡Îuî»û©ªýô]“Øsó| }FÖþ åÊ'ÄÆ$1F%1;ÎÑý1w0Ô¥z]ÇZß¾VP8ÔÆµÿX]פz-ö\ç:CíÙÊyòŠƒsÏKˆ‰e‡Ì:ç tcŽ£-+;Dk·¥}öƶ§´ãòQ2÷¾Æ˜mXQ.ñaõ¡ES‚vç:¿®dRr„P^üU|r ˆZŽs=Ê€.¥ÅV+J”3»+-SŒÕ5ée©}/ù¾©¶z€mÉs,²ZQ׿†ÊÌ=$chq׬ïæk1ÇÚöÞÜÏYè»ã\7÷1uS[ûûößUn̹^ê³gXÐ%6Nˆ‰5W[­(×Ðr–cÊq´]ŒÜû#fuž±ïï*³ôƒär•Ëq>º¶ÏyŽ€mÈ'䎑úV„$ÀIÊb':”>ŒÂq”e/ÇÂò±MÎ))9ØKpæ8ʲ—ãaÛ±aE@ArÜ!9B’àŽûBá¹ç¾»r3€µݼùæÉÚÖgXBwH€‚ä¸Cr„î,eÚæÅÿnÉv™œ?ÿû§??÷íKáé§¿~~ûí[¯þ꿯º˜ËÙ³çB!ܺu={Ýÿôö¹ð›¹~ºŸ9ö®_ü¢= èLBá©§žš¥1À<^{íµµ›lXorlË}¿u_øIxïôÿÿàëþ9¼™»Ë}üø…[lävæêñÕÞíW¾u%|÷+ß !„ð¥/ýIrý¿õ[ÿ)ªÜ3ÏüirÝÀº$pàyäS÷¼vþüáÅ¿×úúßþíÿ=öùÓ×}ôñB¯¼òRãµËßX`V“W+:::jý¹dcÛ|ttÔ[¾ÚžzÆœ·¥öµ•kšË¡o›óçŸW¯~?\»öã¨ò7n¼nÜxcæVK˜”…“““\mYÄ”6Ÿœœô¾wh{Îö,¹/ËÕ«ß!„ðÅ/þî`Ùª× „^~ù³µ ø`e$€9yÎpêüù'îúÿ¡ÞƒzÁ—¿ü¥YÚ‡Î2¦À’F'}w¡ëC^Ú†i4·7Ë4_[Ï\mÎ¥«=©ÇµÄ¾¦^ÓœÇóùÓf>è5¨ôõÔ{ *9{Rï’ž={ÎÕ ;sö“k7‰|gaF%CAv5ä¥ú×ãßÜÞ,B¸ëõ)õähs½=¹ôë)ǵľr\Ó\Ç5g›=AhöTºzÚæäê=dܺu=ܺu]°+ð…ýȾZÑÇ´o¡Ík¶q‹çgì<ŽCNš½•/~ñwÃOz÷–}ôñÎIÈ/¿üƒÖ^…s )uÆñöò5„ F$%Mj äJjs˶§¤cÏxwð¥c ®|ëJò{ªŠº\»öã{–<½té…äý¬-æ¾»˜PßYX^RrPR B\@XZ›51!_ß7DêÐýû?þûéÎBá¹o_ O?ýµðóÛo÷¼«»× Òì=xå•—îzÖÐo|{÷ûúêqÇÈÁCÐÂ6Ë5۸ƾ«Þæ~çlË¡)ê5¨\»öãÓy S‡ UF‚ ¶ ÈùÌþÓÛçÂo~äƒ÷ ÕÑLJøžøÎÂöD'¹‚²Ôa!}¯ÕÛæ® ÈuÍɬcÊÄ´'öü,¹¯¡óSO®á@sÖsÈs._NŠÔ5çàÒ¥Â7¾ñç“ÚS±ãëã!”`±ëÍý-ÙßYØèä 6ÈŽy=&h³ž¶29ëšRGiûZòüÄ–óóSzÒ^|ñ{÷Ì'X[W°ÐD0XÛÔž‚ܪ|‰¶øÎ²”¾²±ÛrŠÙO×ðÀ¾²]Ç2ÇqV®k S M‰Á®;ôñLlÞŽ±IçÜßæw­z–GÛ~ÛzúÚêëëì« É5çàòå+áÙgŸ] 5@Nõ@¢þÿ°5}ðØm¹Õ÷ÓµÄoÌÀ˜6ϵ„°ä@3Ih¾[ЗäŽÝVš¡Ä`îdgÔ’€í©HÕ?ØŠúg¶-ɳmm]~5d¨+™ŸkHQ’ؽz !!`ëúý±ÛJÑLàë¯U?ÏìH ƒ®;}k’°W¥NJN3Yyc™<ç`ÌóêkÉâÒ‘9”z‡>1í^²ÌØg*”Ôf`Í¥× BJ[RØ–U&$WAOŽNmáéÆsÈysjKóZµ]»%Ë ézÏPÝk¶Ötæì'G¿÷(œ„“³ãŸßj(ßZbW)™¢¹¤áû84K>‚tÍÏ|WBž²mî6Æ”[Ç\¬VDU Û• ´ºUùz¢³T™\¶Øf˜Ë”ýLød8eøS¥<ü¨[wyÏ0à•¼ZQõlKÖc÷ßWG}{Û¶\’’ƒfà74¼¢¯\꾚õÔ·÷ ÅXª=1eší¬þ¿ínq̹^¢Í±ûÙcÓk"åù?½}.üæG† 8[˜gû´ð)íûx¢“ƒ®aCeú^OÙWóõ¾;®k´§Þ¦˜2}wc†œähs®ós(Á²ÄØ»IÊú†‘lE_û‡Á¹ŵе÷_¢½'—/_Y» @²Ï9È•,,UOLÀוÅ ÑYS̱çvµg{O ^|ñ{á‘G>µv3€dOrQ[¨'vˆÎZbŸ¦½Ã)œ àLJJ»SÂ<ÁÜØ:ÇžŸ¥Ò%ß¶•wÚæc,U&FÌ{Jk3ì]ì2 ±Ûš«ˆMð»\jß~ÇnË!:9èZA§kžf¹º¶•†Ú¥¡zºÚ0¦ž>1õÄœŸØ6ĬV”ãæ:?mÓcö—z=s—‰sýJk3ìÑÐs¦l«/9:öY)K÷íwì¶\~%¥ðÉÉÉ]ÿª×úÊtA9Ê´•ROŸ1m®^«oïª;¦®©í™ëü´Õ³¿˜úæ.Ó§Ôã€CtëÖõÞ¥BÇl«¶·ýœ³}©û»-‡¤äØ/ÉB˜aµ"¦1œ`{RƧ™§^OVºè9Bz`4wà—5_ PÑslBµLýLUO:—L@ûö;v[Åö”´ÞûVF•ëæxBJ›r•ÉÕžœJú\CIŽÏ¾‚@èÑ××û³­zv@½Ìؤ3¦ 1û»-—b“ƒ*p*ñ)Ì[‘ãv%F9ž8ÜVG®2¹Ú“ZO_ž€ P¦Ü‘b±Ï*HÙ³=Vjæ:ž© +bmpó‰À¹ÊäjÀ¡Iê9ˆ^’«L®ö䬧Y.õ¸ª€´¯ž˜2)mž*W¯Á^U×a(i“c8”ë0LÏÄ‹Nb†—ÄAÉpæî[OÌð–\õ •É9Ô'•ÄànU"3¬ t“çÌ}‡tо!"Cmjr’CÉçkˆÀwœf¯BÓ¯±ë‡eànÑÉA×xì\ÃxƪgéjÉñêK—´‹V¤W¡\mà $ e&Ö\(eÛÔágÍ¿!CõÅKsûœ+…Øs0÷0žT%Z9+Æ’Ç.¨ífX,#ææM_°=´mª¶åK»ö{,m¯ÅÔ?EôjES—Ü«î¹ähS‰Ç•jLò×ÕÃÔ|½í{Ž21rÕ³–®ó {5ôà»±‰ANõ} -G:µ=sOtrPSÍm[j™®;îõ!m«÷´í+UL›ÇÖ3W {ìCç0VÛ¾rœë¶ó“«L®öÄÖÓö3ë3Tð0LI J\Íjî^Ž>“‡å*3fðR“„»¶Ç´9&pL-ÓW.µLî:ÆžË9ÊÄX2˜Ï¹/IÜ­o,~×¶“Ǿ65ŸT2MßÃ÷ºò”d"&ÁÛòš€}²”)Q=pM9þ˜²m=‡|~€2D'Õ]Σ££»þµ•K-3V̾r´9æØsžŸÜæÞOÛ1u£˜sØ,³¿T)½¹w‰u1«Yä*Sj]ö·N]m’†µ5Í׆‚«®:RÅr9Ú[ÏP™¥‚Ï¥=Í×ONNN? ]ïëæªw¨|=‰ìÚ_Ý–?,oÉ%ïŸÀ†–"º­mûØö ÕÕW¶kÛOwNV4W ÒPÇ܉ީ+W›cê)5;99Y´mSõ¥Ïã’I[u-ê‰Ps}eØ—¥ì-ô[?WK¶Ë×ú¤,:fÛ”ç¤ÖÕW¶k[u(G[ûdŸskÈG׿9,9ÔgaEKê ¨ÇûœÉBÌþf{û†¯m))‚¹•¤–Ö¶ÒÚ¥ª?¿ ÷¶®ícÚSW_Ù¶mc—CM•59h»óYzÀ³t›—Lz–6—vìcÚ[½°‰‡jîçlÍ\CI“’ƒ±sæ¨wκöx7ê1 qÙÚ¼‰%'ïíóÄa€Æs®`y}ß»±ÛJÒ6ô©þÿsÎ1KšÜ 6'ö¶m¯¿Sfl[ší[Ï\c½cÛÜ\µ§­LIú†Û´M6nÛ+W=!tísÌ3jsÎãbŸ–œl ¥ÚJ`Ç2öÚ“pëÖõÓ þZÓ\’‚6¬´m™$<&Ó–1퉩gʾ†Þ3UÎIÙmwÈcëÏuì9Žgl±×yÌþ$ýº$K_P&A#‰–µ¥?fk$ÂþBbP·F»%œÚêP`ÿš¿ŸšãòÇlk+;µ±u •mkwζv‰NÜ1˜×!>¹·-ÉùoÎs5¶íKïö¤ »¾#©ÛšÏ¨¿–ª¯®®9}e»–.ÍÑÖ>ÉsØ­>Uyl»«÷iËÒ½*¹ö§7ˆ½˜krÎïGW]CÏWˆmÏßå¨äÀRŒP6={ÛÓ÷Ô̾_þ}w”縋ܵ¿®²süáJÙ_u¦œœïËÙë2¶ ÕësOböÁœ€•ÌœÍ9äd®¶wµyËû‹©kl/H®º*’ƒŒ–|êïГ†»žFSnŽzÆÛ1õ,YÖ´Ö˜¹z4öh©s¥×è³Zr°Ç *Ç“ˆcTÏhþk{˜ZÛ¿”z†êHiϘc›ò<‚¡z–,cÌÄõ [·v®$L@©LH&Ù’O®‚í”ýÅÔ³dèS#Ï:¶p Jo,¥kÅŸ6} þ\Oî{`Y_Ù¾•È–|:r‰=1CGb‡Ÿ4ËŽ‘³=Í65Ë´Õ5W›‡´]Áhß¾Rê‰Ý^‚®§8—ÞîŠáILµõ@²ëº!J÷rNâ9WÛ×¶äg¥ÆXý«ëÛÖ¬;Wû†—¾cÚ6÷ç8é9CCGR†©Ô´MZÓU¦^gWp9eøHÎá7mõÆìohÜüPbPÿïP›ÖTkõo+‰û–ëúÒAÎÐþ¶žŒää\Á¼ªïOý{Ôv×½­\sÛœíkÛwWÙ¾eN»9Mžs0×ð’®k´gÎz§ê |S“®˜º/ák^§µÏ×–ç,5w¶J€ ‡iÎUË–þ²ö³ úDÏ9è °Ú&§N-Ùžœr¶'Wž£ž’‚Yóè’r·}éás>«€i¶|m¶Üvè3f±€RŸ2>ÔÛ¸´¤ É1cÔ— ¾†ÚÓ7Üf-¹ÎOI‰lEÌݘ9I_¡œ¦zÚåè%‚\¿?Jø=TROBÒœƒ9¿¿Ä~¦¾o1}ì¼€õŒ­»)u"q×P³˜z–,“Ê„dÆÚr@8WÛK™Ü¼åk¥éº±0¦×`íÄ µÍKÈ:¬(v¨O[ÙdL{úÆŸ÷µ¡«®ºæäì˜ö í·ËÐ1Lv5µž±ÁñÔÏEJ=K–¹ÌõÇcî`}?x%)¶°Ä*,-÷w¢ù{nÉï\‰‰A‰’ÛVÚS¦­ìcÚS½VßÞUwL]SÛ3æØÛêh«kÌö1õÄœ›±ÇSnJ=K–‰•«ö%w ûã\wÚ¶ö²Ôý-Õ†1퀽h~§šK|¦ÚmKœæ|ÎAÊÊe}Dzô÷}µ'$ðKÍ¥ïæþCPÒª¥ï/¦®œ‰[Jz8DÕ:ÿ%&Èõç´=« ­—¢ëXº¶Õ_›ëI" Œ'±‰·å¶å‘0H pLH xÍ}Ë}¶-ó­m{®6v•ïZ` «Žœím£ç`ƒÜÉgˆl_ýÙ,õåA‡¶ÕÚÖ¶=µ±uõ-CÚ×ÞJóxs’fïÁì–ƒgç ÖÑ·hÌ2¡}9˹pl]C}W{—X4Á°"€…YRÆ‘(QIy"òÖ~߯ EŠ)7–ä`çöœŒ¸³oçjhl6û×ÇÍ]O#ž:¤h.]ó ªaI†lÜÒAúûËõ˹ºôñC~[¯B}@ißɾ¡Ps$3z UÚ¨’í=‘’Ò+PZÛ!Es…¢®áCm‰wW2Þ·êÑš†nÌÕ¨ç€([*·žSÚÒN[âX­Ø ãUa[|ga{ôÅ©¯”sg%e_êwÐwÊ%9ŠÓ,ô XWײ›)åõV0QIÉŽ¶´+©-%“!Ép‡ä!Hf±·±­Ž‡R¹–lQÉŸ[«Á»xñù¤ò.<9SK€µI€ð…/=3Xæs…Û·ßÇÇït–yðÁOœþ|óæ›ƒuž9ûÉÓŸo½q϶¶×ºÊÇì+õ=ph$À Ï=t4XæÁ?qWBÐüÿ.} @WÙ¾2mRËI}ì}³|ÛcKîbfyS?cõ×CØþç+õ8örÜÌ/õ»“ëõ¾ö¤”ŸƒäèU%?|ë$„ð¯³ïol°”¶À>µ|×!Ïg¬z}Áqý8bŽ)µ<‡+æ»3ÇÏ}í)á³kB2BøeÐì!ˆé1èÓkÙ³ŸìM$r'JýeòÇàôýQ>t9>c‡ú¹"ÞÙ³çþûæ;ÒNÏpW𹇎Âß:¹ëµ_ö”©/ð/µ÷¡rè˜ÛøcOýóå¼RWÊjÊ$9îIRƒú$äêç¥z b”< ùÿ8×ÖæØÚ¶±¶õ×úænÊùKÑ»’à.õ¡ä¹Cbž›0F×/ì\¯o¯çÐgì^ClÊ6Ò=ŸmÎƪø¾ÄTc>C9^/ý³+9î±fBýnõs̤ã’çp¯¶;d)wÌ÷tgJÖõ]Ø÷s½žÔýÖ·ùÞÏCr„OýÚ½Ï/¸}ûýò\ƒ\ó RƒüØò’‡ò´Í9è*ÓüoWy`X®»Ù1C†¾³}¿ºö+1˜—äÜ… O†ããwÖn ’ÌOr¬*eXPéÏ-8TKìƒùI€ÕÌ5„çWÖnP=Àì~ñ ¿j` ô!Ép‡¾~`ñÿkí&ÀAyæ™?,#9VóØcŸ,ó裇Bxå•—æn¨ú~¶ñ…ù¥üüeÙ,'9Šô裇7Þ7n¼.]z!*‘–wãÆ½K ûÎÂrnÜx#<ôÐÇÂÇ>öÉ,I¹9@Q}ôñðÐCk 8€vU’Ð×£CrARÓMM$Àª$ߨ$Ar¬¦šWÌãÆ7ÂË/ÿ º¼äXÍ+¯¼.]zaífÀn¥. 9VõØcŸo½uC’]ºôBxë­É+‡YÊÜÅ‹Ï'•¿páÉYÚQ% /¿üƒðå/i–}ÀÞU=c—îM^{íµQ•Ûò…/=3Xæs…Û·ßÇÇïÌÚI¤›šT:“ƒ§žzjRÅÀ:Þ}÷­ìu~î¡£ìu©' @¹ „uåJ *†½ªÄà‡o„þ5kÝ1Ë«M}˜ 0¯o|ãÏ×n´ÜßAÉBh&w¿ÖçÁ?nÞ|3úõÊ?þãÿ üÇ_Nn'0Î /|g°Œä¸+ øÜCGá‡oÜõZ=aÈé‘G>Õ»ýüù'B!¼øâ÷fÙÿšªcÛš=^ €-‹ý[ûw§39øŸÿã/š”â©ÿž~7¾™ ŒM †z b?ÿD¸zõûáêÕï‡Ë—¯ &[uõê÷×nB’=_ €-»zõûá£ýHøÂ~oòMœÞžƒßùíÇ+øô#Ÿ !„ð£k¯þÌþüèš•«ÖRÿŽÅ”ýùí·Gí§™ ¬¡žir$ £‡}ú‘Ï„÷önxÿgþÎßœ&ïÿìݱUR¨úõeïÿìÝpîÜo„ÿð?4k¢¶V‚ )€|¦$ ÉOHþô#Ÿ çÎý†$VP% söÒÕ‡RôàƒŸˆ~ÏùóO„~ô#’(Dtr )€rÌ$¤$UBPÍ5hþ?°Ž?û³?K~Ïà°¢úð! ,¹†m UåIDAT}ê×î}~ÁíÛï‡Øç4ØÄ êê¼víÇá‹_üݨ÷óéMªÄ(Ûû?{7üý?¼<ª'áÂ…'Ãññ;3´*Þ#|*üô§oK ƒju¹1+Ìõ+úѵ×Â_çoF7 XÆ^&WIÂåËWÖn lÎåËWÂOúö¤e§‡ýÎo?®_ÿáïÿáåð_ÿä?Þ_•ì!1¨«÷$ì™$€¦ô4E/e*I€rì%)zZãVŸ"ëÙgŸ]» ì@ο'ÉÏ9$Àzö’„ /|gí& £‚VOêÌQ€üö”å\­hH³ÌÓOmZ‹€{ø^•Ÿœy/ªÜÇH®ûèæÍ7ãŸv¬ê'gÞ W¯ö–¹ò­+á»_ùfrÝÑOHöMr„sžûö¥µÚDøƒ¯ÿaT¹ØØþ©ÿþåÓŸïJLz€²ýsx#ª\llÿóÛoŸþ|_× @g⊉íÍ9B’àŽÎ‡ }èC-Ù2{÷Ý·Ön3¹ò­+³ÔÛù4ÉÁ¶IHeXBl΃~bí&‰k ”¦sÎA›£££ÓŸONZG#-âèèhÕý/­ëxí<@ŠüD¸yóÍEëi–í üƶ-×q-¡~üs·¹í\¹KÕS­¤kšëš-yí™ß™3N*|üÎL-YÎ!s%:9h¢ÓuHسœ})õt•=äÀ¨:ö¹ïŽw}nš¯]‹˜zºê¨cl{JÓ–ÜŽio®z(Klð{ñâóáÂ…'gnÍ2–>æR’ê¨aEmçÉÉÉ]= ,£í¼K à%ôÌEU¦©×¥ê=XSÛ1ŒiW®zàݼùf¿ã“†Ū‚×±k[ÒÑu·¼¯LL=±û2TOÀ§¶¹­-õz$Û3\¡ùK¡ï\߆˜! )í™z7#e¨Æ”}•š4®_þ¹®{ýõêÿÛ>9Ž+vøMŸ”»ô}ms·_Âv·¶aRÎlË,ÉÁ±ÃfÚÊÕ_‹©'×9ÛÜ–tÔú)W®aCÁZì¾b‡O í+¥ÝCû[÷Ð~æ¬'61Júr˜2´¦«Lßg&ÇqÍ5ü&¥Þ¾}Å$1åêes›c^ËTÍÄQb@SΛeC7)rÜ€˜jÉ*9~7Ï’,¨n!nŠ5¦Žz‚Ð7Äk ç„»ý5æ}KîëÄü²-áÜÍՆޭM×u™£ªërW0G‚PâuÐs@Ÿœ7†á’æÿäºQ´Äñ×s°´ó&ºæ_̬wÕ)18lÍ»¾sÞ)Éu§cÚŽk­@(öº—v-r¶gae]5î›sp¨ç„8{¿éµ¥ÏÿÁ'¹‚ê5V’Ð¥”;%}û--HMUÒ9®LN¶–\竤Ä`I%+‚>sßÀÚ»%~_G%mÃVúß©’c¬1Œ¦ë¸æl‹¡ömɱç%‰ýå6÷±´Í©È]κûîÀŽÝר?4%}ÎÆÎý˜«Lêû¦œËœ=‚)ú¾;©õp˜J¼¹²KÝà‰î9h™+Ž¢3´òOL=¹†ÍY%c÷!æNIß8å”_˜c÷Õ,“KÊøë©›uŽ­+W=kŸçæ¾RÇÂ÷µ3u"`[0™óü ÃÔaWSëÙBÐ3õû—»öiìÜ‚µÛPê>‡Î͘swtóæ›­ì‡>ôPre”ãÝwßZ» ÀL־ööþ÷Ĺd ΜùpÖ‚¥&Ø)=Rmå†öÕ&ç1ç\Y)æ&âйrðs¶F0¹®%[qñâóÙêŠùÜ•éÚÞ6Ôm¬œÇÂøc*“ó˜CÐãøøÁÞ€œJèQ[ú˜sÉqî$$Yû6°o1Cph—ãÜ™s°S檳ç@p ‡Å°"بŸœyoÔû>~ü@ëë’ذ«ÇW“Ê_ùÖ•ðݯ|³uÛ¯dh°’ „ 9î!„î{îÛ—Ön0Â|ýG½¯+¸ïé§¿6¥=ÀJþ9¼1ê}]9À}?¿ýö”ök93îm]9€9@ArÜá Ép`.^|þôç ž<ýùžäàùÿówË´íÉ?úýÑï}üñÇB!<üðgÃññ;§¯·öü—ÿöÔèóúѵ×N¾ò­+Ùê5¬6êãÇ„ï~å›§ÿñâ󧽕sç~ýôçë×ÿ¥·>’`§~ø³wýÿK/½Ü[^r;UŸOÂÝ“ÛH`‡š½•¾ÞÉìP³× Ò×{0{rðÀýGsïÉ÷ö©«× ÒÕ{0ëjEÜÞ»}2[ùê=•Ô÷òK¥žÃ¡ÏCL»—,3¤-o«kÉ6¿wûdÔ÷([W¯AåÂ…'[W.ÚüR¦UP“ãè¡I9Ïa.Cmi^«¶k·d™!]ïª{Í6ÛÔ|°Y——^zùž†Ù’ÁcUŸ®¡í³Õ¼¾d™\Öj³ÞØŸ‹Ÿõ¾ÑÉA¸åb14¼¢¯\꾚õÔ·÷ ÅXª=1ešíl»]AöZmŽÝσԘ^€^ýÕ{„k•aE]à †Êô½ž²¯æë}w\×hO½M1eúîÇ 9ÉÑæ\ççP‚e‰0—¡ÉÈ}F'¹›¾a$[Ñ×þ¡ó5W ¸vºöþK$1æ3çàâÅçÃW¿úõ»^+zBr®da©zb¾®$(fˆÎšbŽ=×°«=“%+:9ÈDm¡žØ!:k‰M|šÃp.€Ò~Ú÷ £I fK»SÂôÚØ¡,cÊÄ”]rxÒÐùéª#ö\çhϘ29ëX²ÝS­ÔãÒkÔVKàåòýêfO€m옻¤!„ ’‡&2Ƭ”²d ß¨ä`hMûfâЖH,Y–<¬(¦Ç mIÒæZúK•â$%îÊÀ~%%Ø/«!Ép‡ä!Ì´­Ԝȼd NÒsÚñJ_ÐÞ¬/Y–”¤Þ1e—,ô3ç!H€;$@aä 9‰–äó/iBrªR–-i5£RÎIª\ç°-X[_L›ªÕ¬¶xΖ6krPŠ*0ty¼ç°+H¼7ß#˜n¶aE‚5æÒöÙj{ ^Ì6>0ºç  ¶r ©4ëÊU&W{rÖÓ,—z\U€ÜWOL™”6O•«×€y¬2¬(fxIì”g®á.±õ´•s\1õ •É9Ô'•Ä ,£“ƒ¥î,/±ß}ÃR†ÚÔ6&‡’Ï׉@yVé9èžkÏCõ,È.9F~éñø€2­¶ZÑÜÃxr´g-9+Æ’Ç.1(×èÕŠ¸ÿhp¨M×ö©ËaNÙ¾†m*ñ¸RIþºz˜š¯÷Õ-!ˆSì°¢±eºÇæÏ©ûŠ1g=s-ÇÛæ¡s«o¹ÑÍv þ¦›uBrßÓisM¦©{ɉ»©““»^:®˜z¦ìkè=cŒI¦Ö§× ÞlA«ÌX“Ï@¼Ù“`$@ArÜ‘Í}Æ”‰ÝÌktÏAõÇ{L°X Í íncÓP™±Áë˜á1íi–‰9öœç§4cÛÜvn@Ž29÷·D¥(}™Ô¶=–¥ß7Å”à>æ½mŸ‰¶ùCerµ˜fµžƒ¡•[º¶w­ Ó÷Ú˜¶4Û3¶ž¹ê1Cb¦Œá1´¯\繫¾׫YOê5íkCê TKœÃ!1Çs¦^+`³NH®‚®²c&†ÆLxŒ¤šÚž˜z¦ìkè=Sõ]ÓœíÉ]nÊûs\ÓØýå<‡KÌÛH)SF¯¬k¶‡ Uü¡ß×t¶x¶Øfؓٓ`VIÜäÐøÌ[ ç!Œ˜¦îwNk×T¥µg¬fϘåJ´ûæ”Ün`}«$!¤ ­Ù’)CYÖ²Åóc©áR{1zµ¢)ë§ÏϹß9Žké÷ÍiÌÊ7sÇZç&&ùÈ• t}Û®Aß>%L@¥ØaE)ÃBJ™|9ö¸†–™LÙ_ߦ¶‰µs¿iÖ9åüŒ´œ²¯f™­*å;lˬ’û‚ºØ÷çnOsWÌpª1û[ò¼Ôë›óüL©g®2!,ÛkBžk¯×¨›ý É{ <öz\¹âùY#›ª´öëš=9¶aµÕŠ˜Æ_º\¼øü¨÷I`G^ýÕðøãzï¨ä ×*(VS€r$'ÍÕMÆ®v’« ¤ Émü؇^å¨Èg•ÕŠRŸà Ìoµ Éžà eY-90çʲʰ"s <ž „“ƒÔ‰ÄÜÔÚ`B2”'yÎA®‰Ä&$@YFMHŽ ä‡ÊI æ!„—2ò{øáÏŽ~¯ävæøøÁ2/>¾úÕ¯ßõšaE°#¯¿þjT¹Çìž×$°3gÎ|¸wûŋϷ¾.9€ê=hë5Ar»ÔÕ{ÐÕk‚äv©«÷ «× ÉìV³÷ ¯× ÉìV³÷ ¯× ÉìZÕ{0ÔkBÇCÐ~tíµ¼-Vñú믆—^zy°× „–äàÉ?úýYÌïá‡?õZ›£›7ß<ÉÝ `{Ì9B’àÉBhLHŽYÞ(Ã… Of­ïžÕŠb–8ªf;¿þú«Ñ3Ÿ€nõغùð²6?üÙp|üNÖ6´>ç`¨ÇÇï„‹Ÿ?M$r7 I3¶>wî×Ù3ŽJrŠJêI0¿5’„Þä@RëZ2IhM$P–%’„{–2cbÇññ;ᥗ^ž¥î{’ƒ×_Õ’¦P¨úäåÜZ‚öøã…ë×ÿE’…¸xñùpýú¿Ì–„0ð„dI¬k‰¤ Ò›T$ °¬%“‚JÒCЪ$¡9BÒyTs –L *G7o¾yRoÈW¿úõŤ˽Êè]Ép¸¢æû'9B!ü”]BCïè4IEND®B`‚snd-16.1/pix/mixdialog.png0000644000076400007640000001777611277024426013645 0ustar bilbil‰PNG  IHDR HÚŽm¬sBIT|dˆtEXtSoftwaregnome-screenshotï¿>IDATxœíÝ{Waçñ_ß;o½Æ#ù!°,Y–c=fü¨PV6l¡€$,‹ñ’Ä!UIE.¤EIì ñRÆvlÁn’‰‘I™8 8(~…, ˶°%Æk‚„Æc[=fæöþ1Ó3­žÓ÷v÷íÇé{¿Ÿ*[ROßsÏtßîó»çœîv$¹è¤ÍÛ¿St=€%¹ç}ëËŸ› ’ôãÝß-²>À2³!Á­MY¬ô…;®oº Çqôö>^ŠòüBCB­æÊu„oæÊ©8Jöjìò“§~œøµÿþð×%ÜÎÚ^žÇj³ §jÒè 5ML:’³©w]ut¸Zº¸¢j5ah1þv¶,å{¦¦¤£Ç+Z2pºúOYëM^|á%=è?U[0¥ ] @S¾ø‰ÿ!Iºÿáþço\Í0}Sï5ïUÆ=Û·E*Ï¿ž‰i½ú= î\‚p]É©tè´Ó—jÑ’ÅzéÈÑU—-ìUoo^=$×”ËÅ•€$éOnžýûCîÑ_~æþÙ,Y¨OÿÅ©£Z‘$}ááG5|ßt÷ßûŸÓ±ëGß~P?òQvîP¾;›uyï½æý¡A!,˜˜Ê3ö$t8ÒêS]]²z¡ºûztðÐøüù3ÃŽïï§.íÕä G“‡\¨É­‘€ uŸ§ÝºWÕÓΕ$½mÝkg‚$<©ƒOîÔ©k.Ö†Û>¥ýßþ¢äºêY°XGñ¬z–UuMHûSy÷lß6LAÁ‚?‹<'¡«*­]îèª ûµìÔ¥ë–ãH޹®+Ç™ž«àÈ‘ã83ÁÑ’Åý=<ª—Fí©éÄ$!𛜜TGG‡Þyõ:ýã—þC§¬8WoY÷ZMNN©£cnÏñ¡£‡ŸÓC÷þI¦ºÿ+ú«­ÛõË—ê£ü}IÒŸø¬vîÙ§µkÎÒíüïrG·þý¿èáGSWg‡ÞóÖuúÕK_­e§,ÑK/ë[ßß«Oýë74~ì¸$iÕ+OÓu¿y•Î?ûLõvwéÈÑcúésµý‹èOì/`ë­-lA£¡O° ^y¦ P/ „•7äOGUWÝŽzº:Ô×Ó¡¹k\i6Lÿ'M_>ÑÛÝ¡îΊªÉ©MIô$'ùÚ7ÔUo¸Rïù­wiÛgïÓ~ãZ¼ W÷ñKzûÛÞzòʾñºñëØøËúÞÏê _ýw½ãê_ѾûJýáwë†kß.Çqô…{@[ïøsqÞ¥úøÿÚ¬¡µk419©Ÿ<ý´V®X¡_û/—hÅ© µéŽSíПüþ»´âŒeªÕ\=µoŸº:;õªsÎÒ€ó’ŽŽþ§zûOÍyë-.í[ Ô)/‚?‹Zž±'Áu™›5;ª8RÕñºBy!AŽä89ŽTqi&F8ÓÈ­1Ü÷e]xÞ*½ò,mý؇µt逞ýÏéÏoþ¨z,ÑE祡µk亮Þý_ß«=ïÕÚµkõùÏ}V¾ê|³dBO¹Z¾ìIÒW¾úU]ÿÁMêììÖâ%‹Ô×Ó£—ŽÕÔÙÓ«jW_.Ûhy_Ýà þeqÊóM\ô%ב+wºÅŸí-˜VpÝé?ç–Í 7xs\¹rÝZê“4€V°ýÞûô¶·\­M7\¯… j×÷vë±=ó¯qv UqåjÂutËÿ¾[}Ëf-]: ×uõÁMÖÑãÇ5°ül½úUk%M£Ÿ¿ïÞye¬ý¥5zô¾/ëÑÇžÔ/^ ·¾ùMºô’K´ä9íÞó¸îûü—ÔU{Q“'Ž©ÒÙþÚÔIílIÊ3÷$Ô¼ÍÎ;˜žƒ ™,0=AŽÿçsÁÁ+/íÔ´‚ï}B»{\ƒ¯¾@’ô©mŸQgá»éò ™^ºÓ_q¦ª37"qGg­X¡g~ö¼*ݪv÷J’¦¦jzlÏžyE«ÉZMg.?C==Ýzï®×ÓÏþLõ‘zyü¨~vð°:ª­µ…ÚºõnIsY 63‰q6$x‹íÉË„p/ LLLH:)$Ä»³"h-Á,0*ô$Ð΂Y`nâ"à ´µ``¸Hª7Ü@Om-˜ @R½Pa¸€vÌMO\ôîÒì±~ý†ØwO®3q1ùpÃúõ¿¤kË–»½®Îœ„憺»ç?‡”7SF¡7SâêÚ—@"wŽÓ_t€Â¹îXÑU •6¾ãâí·o)º -eãÆõó–ÝvÛ_PÀ›6Ý4oÙ®]»S){hh0³²ÛM™·¥©îI³= 3®»îÚ¢«Ðúú–J2ObݸñÆ|+Xàøñ#Æ 5bÞZFZF»(ó¶¬W÷¸êÜL©½Cí®ÎÄÅön<à „¨3q‘@; ¿-3xBNÇ™·ÌuÝjð }Àà ȋÇ!øï5Âý%«o¦ä6«fÿ>:º¿°z´2C3á¡^9¦^ŒàºQÖ)‚-Û'íú \ðœ˜ôÆdŽÓ/×›÷gÑl©Gau.ãïb’ÙžÒ`ëXuR0þÍ ö*$íehTNX™Q¼z hÖòÚ>R´?­úÀ,í/L^9Á?‹fK=â«s–¿Kž$˜fÿU©V™¼h` ££ûOêY@sª¸rÒr¢4pE6‚EoŸ¬ÊÁɧö?×KµQëà–éñ±-ó SÁ,0ª•j&7Tòðýÿn´žéçq—s ‘¼ÇqJÕˆzõ5ÕÛèIHO B”o¿Áóe£snðϨ¯ +'LÔõ¢¾³íBœž„f߳ѶÎB0 Ì…„j%³!/ûrð—m”œM¯i•1 ÃkèÒèih%Þïëÿ/,(xÿµÓö)£(MðÛhÜÝÿg”‰•ÁåQ‡>ê­ö{Ä-'Ž8_X›}Ï"†‰‚YÀªVL^¬ÇÿalÒî®Cë©×fõ^¶‹ZÏ`(S/I;ŠÚØ4jˆ³o¦÷8JpHûÛw’^™fë’g¯x0 ”*$HsA€<ð-y>æ$”O3]õ¦Æ/îC½÷<5Ʀ‹4»í£†Ó{6Û£‡Ò‡ÿ%<Ðj²8·Emdâvý‡õLÄéõͺ'!¬¾I·sÔð’æP= eÜðõ6\ZMW2p dºâN„ ›¥œ8ßvÓìEhfâ¢mÛ‡‰‹Ùð†H½s[š C³“þâ–#ÅŸsdyœ9 I× J^šQdÏy®!¡Qš¬w„)æÕ£àï?BúÒšרœàÏË2ñζíÃÄÅl¥ÒìIH«ë>j9Q'[¦}•D˜<¯n+/OWiNÜ™®Í–µ¼¸Ù‹ÚÐ4Z¯ÙŸÇ]/¯²ZyûÀ¬Ù;-f!­nô¸“)›½j¡ˆI¥ýžEô(dÍa¢6ŠBH@îüãÙÞßùV ö!$ w(‡R]ÝòCHF„`DHFL\œÑ×·´è*´¼ãÇ]À*ÃÃÛJYv»içmIH´qãzISEW£¥mÚt“6mº©èjÖÔÐÐ`éÊn7í¾- È7‚€rbN0"$£T†¶l¹+b€Eš ë×oH£À2M‡„ññÃiÔX†9 ÀˆŒ ÀˆŒ ÀˆŒ ÀˆŒ ÀˆGE·‘›o¾­è*rt㛚z=!¡Í¬[÷ºXë_qÅë%I;v<”Eu€†¼Ï  8P„¤çáé×M4õÞ„]qÅë52²O##û´}û½±Ã¦‘‘}EWã…Ù§•+WhÅŠ5¹†Uæ$à$W\ñz­\¹ÂŠ“2àd^XÈ«‡­-CÂÀÀªÂÊ [?Í:%A8€òÈ+,´eHHK’€0:º¿érÒD8€òÊ:, kð‹*'.Â´Ž¬ÂBêMߊý ×(× 6”ÊIºN½Ù[·Q£¤a7½¦ˆ€àŸ@=©†„zÝ馠¶N”r’®“F×~!I9ÔsË-Mõ*œ\†‚a‘c½÷Ýßò ÷ŽéÀmß~oÑUX.ÕžÓ0‚·<®(ßø‹¾" Š¢æ4²nÝëtàÀˆ¾ùÍoéšk~»èêšàÝÇ#í{y¤>'!ÊpCÒr’¬S$[‚aÊ+«pàIu¸!ê7û"{ê½÷ÀÀªRôNdÁ C€ý¶o¿WŒd~ÐB†]Ý¥œ¤ë„½.Žàëýÿn4±2n9y£gì•uÏAP.à IÖKk¸!ÎUiÕ=ÍuŠâ @ÑèáB»Ë;xxÀS›‰{£ ›žÀ‡öµyóŸ] PE„„62ý\ñæ h¹ß–Ùæ.v0‡g7#† vóÍ·]@‹šfNŽ`(³U½ „;v<”uu€TÙ:ù•c e§-˜^·¹yh„ËùŸÚè]”mOåXB™y…^±bMæa—9 –ºâŠ×kåÊÖ\vðÂB–½umÒ¸ý²wç(·zŽú~„@Y†…¶nH+ ø/ç4݆9Ê:ÿ°qe1 Ñv= i<™ÑTFð™QÖñx€fŒìKí–ú©÷$4zèRð!FÞ¿M߸ë=ÊôžQ¨dãÍœvìxˆ*R‘æÄÜ\ðlœMOJLÒ}ŸFÝlÁÓÍÈâ!PÖ7ÄiÐGG÷[âðÂO½D±}û½:p`$“Ëzsn@|ô,êÉãñÑ©†„°á‚Crþ°”=c@zòžÌ/LâÌ?ˆ:q1ILåz“*ëÍ¡ˆ²Ž'ʵ­¶ÞÚˆbóæ?-º @ËÈóxJ5$„]‘ê5êq®nˆ*X^ðJ‹8‚õ3½>Ê:ÓßhîÞÚd!—«LW6Ä}]Ü÷lf½¨ëG)¯U&TÚµW7€b€‘•!.zŠgeHÅ#$#B0"$#B0"$#B0"$#B0ÊüQÑqmÝzwÑUXjýú ڲ客«Q ë×oÐøøá¦Ê 'P ë×o(º ¥‘Ö¶²®'ÁÇà1õÐN˜¥ÙÓBOÀj /D—ö¶²¶'ÁÓÝ=Ut£È= ÀˆŒ ÀˆŒ 8NÑU€ÒáÜY>Ö_Ý`‹à‡Ûû·ëŽQ(ÎåFOBõÒ/ÉÌ8w–_©CBÜ™ãôgòÁäÃñqî´_i‡’¯{Ëÿw@ëÞký|àý™Ô£¬J\w̪^1Øéâ7_ßpËV:Ú¹óáTÞÏßÔûBZ†ù¥ Y1í¬(Àæ E(Ë—§ËV:©–ç﵎²žÍJ='€fxá»Ü‚kb§–ëI(¢û¦ il“ç¹Ó’ô ˜z’ü†$¼¹sÁ÷Ë»½)mO‚·á¢vgy;ɤÅzëÀÌ–s§? x÷/‹Ú‹àµÁÿ’ «x¯û~yá”¶'!lãfõ¡ô¿¶ “MÀ6œ'¿{À5ïgÍÊêw´aÛ•¶'€¨˜s !Ð ñmÃÒ YͰáÒÒÎI ‰à…¨Â&çø× ›Ãe®n $ZZåÐ#ó–íÜù°dXÞH”F:­u⬗B eñ,†æ0'°LÑà B0bNB6\‚@ $}t4eÇp0"$#B0"$#B0"$#B0"$#B0"$#nË hY»v펵þÐÐ`F5)'B ¥Emø‡‡·nF„`ÄpC< M·®;Öp¹©Ýþí¬´!Á{`†é¾Ùi¬@»ã¶Ìq{&Ñ´Ús Ú!! ʇ˜ph„„„ŠNĶ<ŸÜ†zØP[êA쪇 u°¥|¹*§ÒÎIÃäDÒQÚžÿÄ( 9îú´»Ò†ÉÜØ× „h/»v펵þÐÐ`F5)§R‡„vfKౡ6ÔA²£ÔaŽ õ°¡’=õ(JÔ†xx!! åæ$€t€à DdºzÎ?œcºÜ4¸Ìûw°,Óëê½W ´ûøÄÕ çͰûM$¹E£0‘æ{5ƒáš¤ÑNÚÐÓ“€…ÂØ ½$a !âÞx‰5À´¸]âe:Ú0'† x 5$÷X¦óg’ú¥ý;å½èIJ¨•¿¹ ÜÊÐØ'e¸!¸NÒíaËÐ!(!Ýðð¶ÔÊŠú¬ $?.·á8'$òÑš®±ö~æ_ÖèZí°÷ð—¼~;ìr,z2PCCƒ¹Þj¹ÕŽ BB eš\ƒòóÿ‰'ì&,¦uÃÔkô£\« ÄÕ.çÏ(7I*B‚¡FE SOBðï@\Þç*êg±ÏŸ­ò{H„„P<†e§'AŠ÷™ÛSöu¼=êÏP,.JÆÿMÍ¿¬ÞpD·Ž÷_ ýГXÈßàûÿ þ=lYÒž„Få€öBO0"$#B0"$#«'.nÙrWÑUXŒv"[Öö$°ãõÐNdÏÊž„õë7]€Åh'òa]O;PíD~¬ëI?\t€,ìIv $#B0"$#B0"$#B0"$#B0 ½ãâ]wþmžõY´¸×¸<4$|èC3« °ÇßÒ¸<4$LÕ^̬2À~ÌIF„`DHF„`DHF„`DHF„`DHF„`DHF„`ú€§$¶n½;ÍâÀu×][t-"Õ ÑH©¯o©ÆÇ] @‹`¸¥Þ“à©VgU4¦j/]…yž~zÑUh«W¯*º ópüçÇÆãŸýŸŸ¬÷f!A’/¡£"k7Ýx«6ÜðEWÃhhh°è*´¼áámV†‰ã?6ÿìÿìå±ÿÙ‹ÀˆŒ ÀˆŒ À(Ó«šá8ýó–¹îXæï™õ{`NÛÛÿ9bßÚ©ˆc=/ÞïÖ*¿­ÂÎ%IÎ1œ3NfeHHs‡Ç}O‚B>òÚÞ^Ù¦†Å+âXÏS+üí†sÆÉJ5Üu@ðÞƒG¶ØÞh„ưƒ•= Q¥ÑMiúÆü†õÛN£ú˜Êi•oLQÅÙÞÁíiÚ–õÖIZŸ¤û$êþò{E©g;ÉjÛ¦Ñ6¤Ð¨Ûš}¿4ÛŒfÏ=eQÚ`ãf[}Ê,Ê Ý¦Ð'HÚRç²°qÛš¾@ß«Q·µi¸ÏBrz$Óž·Ð.Çq)B‚MIZõƒ`›(Û¸Œû¡Qi8’+ã6òïoössÂ@^ïÕªJ²žH’V¹Œ­GÓªÛ©U/d‹€ŽÑøJ²–F­×•…“µêvJë$Ï·Ëö¾ÎÛ7¾R]ÝP´° +õÖoæçí,ʶÉbû±Oìd?$ öEãJŸrj§ýdeOBØÁœ”×MX‚)ß”úÃf»†Í„{ ¦E™=eÿÏM³ÐÓÚ'iÛå›ešÇz£ÏCÇ_½ýÓè³åJ¤'êç¨Ñ~ +«U÷™•!AÊoâZX¦E£×EYÖª¤¨¢nïzëÆY'Ï Iëwy«Is¥ñyHúqõvßïiJkŸD]'ÎzeÇpCŽè5°û¤}°¯ø¬íIhEíÔEUì“öÁ¾â#$䌓Rcyß#}R~t#/íöb¸€!e:'á¦oͲxXnxx[ÑU@8þÛû¿5d¦j/jà Uñ°ÜêÕ«´zõª¢«‚pü·7öë`¸¥Þ“Ð×·4í"@R ×]w­ÆÇ§Y$(à ÀˆŒ ÀˆŒ ÀˆŒ ÀˆŒ ÀˆŒ ÀˆŒBð´uëÝyÖXf^H¸üïPOÏ¢"ê rùß1oÙ¼ð¾kß§÷]û¾\*ìÅœ`Ô!IÜsGÑõ–q$¹EWØçÿOG;ª Û…IEND®B`‚snd-16.1/pix/addamps.png0000644000076400007640000004101311147553266013263 0ustar bilbil‰PNG  IHDRmÄ7¿sRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ0kof± IDATxÚíwxTÅÚÀÛ³»é=!!¤ÐA@Q°  "¨¨Ø÷®¢BQTPôÚë§(‚AE×Hï½·PÒ+éÉîfû~, ÙMa~Ï“'ÏΞ9gΜóÎ;óYeeŽÛív³rÅ@pñ  ×bì^O‘£¨AyEnþÛt¤'{ý]ßk/E&“!«¬Ìq(Ñ›@pQ/·±Ú½É«éeéÆUz{ýÓi@yr@ .\8@æã;—£Y¹ ]è«ó\üðÃB|öîqd2n·[t˜ ™qB³céìàF O/£ƒ) ¯b_ö¾£`5Û™í”ì+i0†o»ífär¹ Í>vn7U¤¥µõÞñÁøûëq»åç‹4IçÎÝP©Îýã–CUU¹¸ï8 uI8C¯~–ÂÂ<ŒFµµÕ Âš–Ö¡ð8oˆÛíæûïÒ»w/bc£›=>3ó0o½õmÛ&3aÂXé¢öî=ÀûïLûöi<õÔ(©|ÇŽÝ|ôѧtéÒ‘Ñ£G —ŸþLP¡Pкu28vV­ZK›6 b šÕh+*JÏy»›6m$55EÜA“Øí6T*9áá¡„……’——‹Óélöwòóáäüñ>øàL&S³ÇîÚµ—E‹–’‘1•;îÂLÃjµ²cÇnV¬XCFÆTnºé¦Lù»ÝÎÖ­;ذa3S¹îºkøøã¸\®S>Ç  `bccILLÄå²ãtÚŨN§—ËNbb"±±±ŸžY¿~C:C:#FŒÃápb6×óÐC3jÔÓ,]º’Ñ£'àt:©©©eöì¯yýõ÷0Ò7nbéUVVÎ÷Ýw'íÛ§‘““K}½…/¿œË°a÷Ð¥KGÈÄnw´¸Cår9IIÉ„……¢R)°Û…±@ ¸Ð5+*•‚°°P’’Rɼ¯Úø\ÂêÝ»½{÷Àh41nÜó¼úê$BCC˜œEYY…×ïL&ß~ûUUÕ§|»víå?VHŸ»uëÌλÏÒX@€?~~~ôèÑmÛvPZzŒÐÐPT*—^ڃ͛·PTTBTT$ EËÍfÅd2¡Õú±yó6ÊË+0›ëŨ4fs=åålÞ¼ØØŸ“g¯ˆJ¥¢[·Î é\vYT*jµ =?ü 2™L*×hÔ¼óÎÊËËÑjµŒý˜T_EEãÆ=Ï¢EßÒP“Y¸ð7~úéWŽÉbÇŽÝèõ:Þxc2QQ‘üòË"Ö¯ßÄõ×_ Àw áûïb0¤Nzúpü¹çž¡Ì›÷=C:QQ‘¤§G«õãÁïfΜo1Ò‰aäÈGP*OÝø,&&šÊÊ*ŒFV«””¤ "@ ø'àtº8rä(›ÍFLLÓV±R(“¿CYY9ï¾ûo½õòÔ‘NfÎüÒ§HII)II‰lÛ¶ƒöíÓÄÈ4IZZGöïß}ÎÛ=t舟‚ŒÏäçç••ís¹*-­11¡Ík §ŠL&C­V_`]*#,,ŒŽ»xý¶cGÏR_ppx#­J 8NO\\›sÞn›6)ˆ hµÚØØx}û éõþgG¹q»ÝìÞ½Wt„@ §K—N LzE(¸\.V¯^O\\¬×ïårAAÁ„††sôh¦è0A3š@2Z­îœ·[WWKAA®¸‚&IKëȱc%ÔÔTãry÷@oÕªu£²óF€ìÞ½—6mZØì±eeå,Y²œˆˆ ¸V*/)9Ʋe+‰ŽŽ¢_¿k¤ò¢¢bV¬XC«V±ôí{å)¨ujBBBªl2¡¡a„……aµšE(A‹ˆ‹‹Ãh¬:çí®^½]„24Kll Z­¦-TVV4 ßÈ¡ð¼0#:z4›Ç{’ÒÒ²fµZ­|öÙ—DGGQQQɯ¿.Áívc±X™5ËS^RRÊ’%Ë—[˜5ë+¢££ÈËËgùòÕ§uŽr¹œPâââ Âj5‹Q'.(¬V3!!AÇßs¡Íú¾ùÔ@²²rX·n*•’{îŠÍfçÛo@£QÓ­[gvíÚËwÞŠÅbaÏžýTVVqìX9:–¡Co‘ê2Müøã/ <€ÐГ4},_¾š!Cµè_yåFŽ|D º8aÂd.»¬;o¿ý!Ï>;ް0OýcÇ>Ëå—_ʤI¯ðÆ“ÑëõŒ1Ž>}.G£iÙ¦ÿ #44›Íãb·ÛÄH$v» ¹õ„‡‡SYYIe¥w?ŸâE§ÓK\\,!!!|òÉL, ÿýïïøóõ×óÑëu|öÙÔÕ1bÕÕ5ÄÅÅ¢V«øüóo¤ºªªªyñÅ×(**nÔN``Ç;/;2((„¸¸xBB‚$á! 6[=±±­|ÆÂò)@L&3ùùäç——ÇÁƒ‡ÏZÙå—_ŠÑh¤W¯ž:t€~ý®áî»oçÚk¯¢Gn9’%ÕߊììÝtêÔ¡Q;mÚ´F¯×—çr9±Ù¬ˆ‘$.J-ú‡ÃÑrb·Û™5k­[ÇÓºu<¡¡¡-T6Ÿ¸\.ª«kZ_þdêë-ÔÕ¥ÏZ­õõÀ£K.—#“ÉÑjµÔ××Kå …™L†V«•ÂØí”J%²¦©««¥¤¤”ššZvìØÃá<­Pð@ðOÂåráp8Ù±c7ááa§ÊÄóâõ“¯ŸÐ2N Ñh¸âŠË”mÞ¼O?^¯Çn·sé¥Ý¥ïòó ¹ä’«X±âºvíÔàw»víaÇŽ=ìܹ¹\Ndd·ß~³äüôöÛ°fÍ–.ý€‰ÇóÉdbðà„‡‡òŸÿ<Ï[o}@TT$F£‘;ïB@€?o½õ2¯¿þ±±1ÔÖÖ1lؽ§äô(“y®W£Ñpà@&ÁÁ¨Õ¢¢"Ä(¥¥eØlVª«kíY7z?úr$,-=Ff¦gÙª}û4ªªªIJjCVV.©©É’¦’››OPP ï¾û÷Þ{µµµ¨Õ.¿¼§T—ÅbaóæmtïÞÿ†ÞŒ¹¹ùäæ6Ìré¥ÝÑjµdgçR]]Ã%—üé^[[Çλ ¤[·ÎRyuu »wï%88˜.]:Jå••UìÝ»ŸÐÐP:ujߢNôÊÄívc³Ù1™LtîÜ5k6”ÔFŒ:A“tèЙÊÊcç¼ÝÕ«× 3^A³tér %ìÙ³½^Z­j´ïá-”‰ˆ…Õ„ùúëùôêÕËç155µTTT "h–ððH6lØpÎÛÕjµ>a‚SPGPo?¼ÈÈhBB´g^€Øívòò HNN¼`:Ôív“—WHxx¸]@èõ~ >ŸOt•JuA ðl"ÍŸÿ#ÁÁA>ÑéôRZZ,F– IÂÂÂQ«5ç¼]›ÍJEE¹¸‚&‰ŠŠ¡®®³ÙwöÕàà†½éüŒ…e6›Ñh4(Šh<jjjP©”5ЄjjjQ©T T1›ÍFmmjµú”"“ø{Ͳ¨T*‰Ãív™yÄg&Fà;vÅn?÷¾D›6mãSÐ,Ý»_JYY12™’¢¢¯µii틜¤ªªšÇËk¯½@Û¶ÉÍ?gÎ<<„V«å®»n£cÇvÌžý5GŽd¡Óé¸çž¡´kçÙŸ9óKrròÐëõÜwß´m{z”N§ÃÏϨ¨hÌæ:d2ÇŽ•ŠXX‚àÆj=÷¤¬¬Œ Ñý‚&q¹\Èå2ÀIÛ¶©”––`±X0››ÙäS€X,jk=þ2™Œˆˆ0Ün7eeÈå2ôz=&“‰ðð0\.f³»ÝÝî@¡öçn½Ó餢¢ŠÐÐàFÙM&3Ÿ}ö-Ûk˜9óK:th‡Áðµµu¼ÿþÇ´j5’¹sгgw}ô_TW×ðî»ñüóãøì³/éÛ÷JFŽ|„ªªjÞ~ûþóŸ‰R&Å– R©ˆ‰i…Ûíñ#1›ëĈ$fsAAèõ:ÂÃ#)..Än·ŸšÙ¿?“ï¾ûQ 7ÞØŸnݺpë­÷Ñ·ï•„††PYYÅàÁHMMáßÿN§gÏnX,V 7ß<Ë/¿€‚‚"Ÿ~ 6lfذ{™=ûë]\NNƒ 9’'ŸÉðáÃX°`!àÉþôÓ£)..á©§FñÓO¿ÊSOâÍ7_"=ý~ùe±TWtt$¿þ:Ÿ””Æíýû÷•òŸŸoètzBCC©ªª#J \”¬_¿Ög¯ˆÓéä“OfR^î‰ÀèK}ù+ÑÑ‘xß öx®_ú븊Š2>Lmm-ÁÁA´n/F“@ ¸hÈËËÇf³âç§i¹ât:ÉÏ/`ôèÇ=úñF¦¬r¹¼Qâ§eËV±q㊋K©¨¨l`íTRrŒo¼£A€ÅFŠ‹K©«3RVVNqq)ÇŸÒ.#ã+ÆŒyVú<|ø0¾þú;Š‹KÙ°a ©©)‘ž>œÙ³¿¢¸¸”5k6Э[ôzcÇŽdúôÙ—²bÅz÷îuJû2™Œ   Ìæz23SVVŽÍ&¹ ‚ ›ÍFYY9™™‡1›ë òW1aÂØ—*DEE2{ö×lÞ¼;ÀÀÚµk‹Ýî [·Îôí{%n·§ÓE||+JJJ±Ûí,Y²œüüB&L+Õwb¢OŸ^´”µk72oÞ÷:t”Í›·qÉ%]Ðé<zKKËP(Rl­àà ââbùä“™Øl6††B¡ 88ˆ¨¨H¦OÏàßÿ¾ÿx¨`ÂÂB™1ãsÔj5=tÏÎø+n·›íÛwx6Ò•J%V«ââ,+ÁÁAäææ,F I"#£°Ù,ç¼Ý¬¬œ-7¢£c±XLäææO»!C¥R5˜l‡‡Gp<Ñ/ÔP&_y Až(Án·›£G³èܹ£‚&iÓ&™åË—ýf“vÉœ] ðEllkŽÍùd6›eËVQTTLFÆTn»íf¦M›uZ©uÃÂÂ‰ŠŠ&..»Ý"<ÒÁ‡ËåÄn·GTT4aaM‡˜ò©¬_¿‰™3¿@­VóÚk/àç§á¾û†C¿~×°|ùþóŸç‘ÉdLŸžÕj#//ŸÀÀ&O~–ÏŽ}II)÷ß?œéÓÿ¯Q°Ä… #99‘¾}¯lÑ.Z´Œ‘# !!žòòJL&¿þº˜gŸ@rr"……EX,V~þùWÞxcòq,…>ÈÆáp¶(ê¯B¡@­V“ЇÆËåÄá> àÂÆn·¡RÉÑhü àСÌSÓ@z÷îEFÆT22¦òòòËoátºHLLàÕW_`ݺM¼üòs¼ñÆû8–,YŽÁp?Syæ™1¼÷ÞÇR]†«®ê¿¿¾Q;·Ü2ˆ>}.?/;144œ¤¤$l¶z¡q‚‹R#)..Æívµ\q»Ýü÷¿¿Kq®G³Îr—]ÖÃg¨`^zéÙ\çUUU}p:Ìœù%iiÞÃ@”—WÅŽ»}†;N–Ö­[7Ÿóvóó èС¸‚&IIiGnK%¥ÀÛމ m^9Uþª‰\(Èd2âãã¹ä’ž>q8$%¥J_h4zô8÷) .»ìrüüüÄ 4‰J¥B«íD§NÝ|ãm‰P&§¡™lذYt„@ øÇÓ«WÏSJoq2"”ÉiÝ»÷‘àÝâL­ÖŒV«'77Kt˜X8§@EEÅÅù¢ã/r:tèLEE9UU•>cõÅÅ% Pü)Ž+“öºfÍšÃõ×÷m2‘Þy!@ÊË+9|øW\qY‹³|ùjzõê!…+9™%K–sÍ5W¢Ñ¨øý÷¥\}_”Ê¿É*•ªQ»r¹‚ˆˆ±ÙêY¹r ‰‰mÄH¾È Ád:w!L¶mÛÒÈYWpñ؉‰‰¦¶¶–òò²F8BCCXWmݺ“~ý®F£ñd|øáyï½8ðz:vô¾v^„2)//gÍš ->~ÍšõL˜0£Ñ{¸-[¶“‹Jå‹/ã¹ç^:+QI5 ‘ÄÇÇ¡×k±ÙêÅèç6[=z½–¸¸8"#£$áp2Ó¦ÍbРë}ÿØcÿæ÷ßÿ /¯àÔ4}ûðë¯KYïØ±#°Z­¬\¹–ššZrròÐé´Œõ(à1·]ºt%þŒñ0›7ogåÊ5ÇgcÁ > € 6KB£wï^ Ú>v¬ŒÏ?ÿ†GýW£tº+V¬¡  ˆþýûúì´ 6sõÕ}Ëå,Z´”ÚÚº3îí.—ˉŒŒ" Àÿx¦9N§KŒX@p^át:ÐjÕ%PWWGYÙ1rs ¨ªª¢U«X.üµZÅîÝûÔ1wîn¾ùF:tHk^€Øl6fÏþš‡~ðÄE™=ûk†½…çž{™×_‘›o¾£ÑÈ{ï}Ì¿ÿ}??þø ÷Ýw'UUÕ|ôѧÜyçm,Z´”;ï¼€²²2>ýt6ƒ]ÏÊ•k¹õÖ›øðÃi$%ý¹ÜS]]Ë?þÂý÷ßÙH€tèÐŽ«®º‚^xÍkg½ýö‡ÜrË´k— @×®ˆŠŠdÕªug솄……“€LÆÿ$M©@ œ®Fâï@y¹Ç©Ûã×ç/­ÎôèÑ ¹\Þ EII ›6m#..¦eˆg=?œ… “4'ŸImmW_݇ûPQQÉwßýˆÓédãÆ-R¬«º:·¶ÃagýúMÒ>DUU5z½«ÕŽÛí¦}{ÏK~ìØ,\ø»Ô~jj26üáµ¢¢"|vNnn>n·›6mþ¼ø˜˜è3~, 555ÔÔÔ+F¥@ øÇ°~ý:)Э^¯E¯×RTT@«V1Çß›Q=šÍæÍÛ?~´Wl¯D¡3dÈ d2Ùñ¦•×_Q£¥ºº“ÉÜ(§FRRn½u°ô9$$›ÍJÛ¶I ÊCCC©©©mðÛÂÂâ“^ÐV²³sINND­n¹‰Ù‡NãÅ'œu«“ÉHEEN§“mÛvÒ¾}jµêŒlÐ Á™Æápb³Ù8p “ÐÐPІÛßC† â‹/¾á®»n“bþ—ðý÷ 1Âà3z‡×7žÓéâçŸÃíþÓE¤{÷®äååóÑGŸJå\‡N§#)© ?þø àÙIONmmqq­¤òàà Ü€B!G¡Pðæ›ÿ@eeUGÄÇrÍ5ƒØ¶m‰‰ “5-[¶Š-[¶³uë>úhþþzžxâ1Ö®ÝH¯^=-yýöÛvïÞÇž=ûx÷ÝP©T<ýôèÇÃò…L&C©TFvv(ri-Q ΊŠJp:ÔÔÔ5éð=lØ} >ïܹ‡'ŸL—Œ‘¼¾}9ÖÖÖQRR x6ŒSR’¨­­ãÅ_güø'0›Í( ’“¨®®‘‚%*•JiO£ªªš²2OŠDµZ%e﫬¬¢¼¼â¸ºÍf#,Ìã&oµZÉÍÍ'11¡‘“KYY9UUÕ Ê’“©¨¨$,,´‘`(-=ÖHãiÛ6YÒ®N›ÍÆ_Ìmd*év»q:]TWWÓ¾}*ë×oæ”Ú·ïDQQÞ9koóæm>Ãï.:vì±c…8pˆ`äry£w^rr*ññ‘«Ÿ¢%00€ÀÀ¯ßy[÷j4ûåÕ‰õ¶¿Bhhˆ×ú5Ï4œá^|¤ñQQ‘R`Æ3…¿¿? ‰>¿¯«3Ò¾}Gi=Qpñ¢ÑøQ[{îL»»vívÆÇ»àŸ‡L&ÇáÑ£‡ïPL¿S eâr¹(/¯ðù²¾p»ÝÇ÷€ü[ÜgÕÕ5bD ‚ó•JáSQø[ˆ7<¾u‡Ëd²ãÖf-“»K=Ë—¯”–缡×àç§¥¢â˜Ñ KÇèsÖ^YY1.—ðSºxƒŠÐÐHÊÊJšÌ¦Ú¦MÒ¹ çšúz F£±Ù˜ô¥°°˜èèÈm’×ÖÖ‘››OPP ­[ÇIåÕÕ5äçD||+©¼ªªš‚‚"BB‚OÉ|700 Qì,™L†F£!22…Ö­Ûä3¾–àB|ÀÕ¤¤¤a·Ÿýå­;v%¬/"´Z= m°X’0ÍÔÖÖx‰•ššŠÃaF£ ô9)6¨Tîž9tè0+W®c̘Ç[t|NNÿú×~úé¯û1'3mÚ,Ôj‡“Áƒo C‡4Ün7Ó¦ÍÂÏOƒÃádÈA¤¦¦`·ÛùôÓÙh4jìvwÜ1¤óã© × ×ë Âåò8ð˜LF JŒü‹·Û…Ûí<ëí˜Í&üüÔ¢Ã/¾†B!#(HO``uuF**Ê}h$n¬Ö:¯µ¬_¿–+¯¼Âë¤Ü§©ªª&?¿à¸º-§S§8NŠ‹K¥Ù·Ãᤴ´”¨¨HJK˰X,˜L&T*íÛ§WË).ö8©¨ÕjÚµKÅjµRUUCmm-‹Æ´4ϦyII©dÍeµÚNzÌ9’Eûöi¬³ ‹˜?ÿ§[>Mšô*#G>Bll4&“™gŸ}‰>z›çž{™qãFŽÑhâùçÿÔ)o1iÒ«ŒÿáÔÕ™4éU>üðÍßÊ“5¹\. @ 8›Èd.‚‚üÑëµ&jkk}Fé=¼ ‡ÃÁôé’C ¸ÉÎÎeÀ€~Ì;Ÿ¡C=³ï¹s‹Z­æÁeðàP(¸Ý.òó 0à:òò ¤˜W.—‹¢¢Z·ŽgÔ¨ñ p-r¹—ËEii)ii©|ñÅ\) WVV6ÉÉIÒyíߟɀ·±wïFbc£OÒVŽ0jÔ£LœøJ‹.üر2"#Ãk:L&S£r½”½¬¬\ZJ ð§®®î”4ŽˆˆH‚ƒƒp:íRŸ Á¹Ôx=‰?Ádg>;Äét²k×^)¯y}}=sç~ÏÍ7ßÈã?ÌôéDGG‘ÏÕW÷¦¬¬œvíRIOŽŸŸ†¢¢b>ùd\G||+úö½€¢¢bÖ­ÛDëÖñtéÒ‘Q£C­Vqðà!.ü°°0”J%cÇŽà?V°¦t^;w`ûöÕ^Ù\{íÕçíS©Ô¨Õ*jkkyð Á¹fÕª•´nÝêìð8à­^ýgÂ[=™;ù IDATn¹Qš}ÇÄDQ\\Ê•Wþá6 À?¿†¡€kjjÉÈø ΣÉTVVI L‚ƒƒš SÞ@€h4šq®þ)TWW““‹ÝnG¥R G/@ð?¡®ÎHYYù›Èz 2™œK/íÎUWõ<ëõ]»vÂét2wîZ·ŽãÖ[3mZ÷Ü3?? Ë–­â×_Cuµ'È ÅbÅn·sÕUýO†«¦œœ´Z?\.;vì`Ê”étëÖEú~Ïž}<øàã,YòC#sâüüBÊË+(/¯`÷î½Ð¥KGiãçÅ_§ºº†)SÞàõ×_äw¦0p`ŽÉ’"¿ùæK¼ùæÿqà ýÈÌ<,E~å•I¼óÎú÷ï˾}yè¡{O­£• ”Jv»mÛvß ½^/4@pÖ©©©%/¯FÛ aa!g¤^Å„ c_jT¨Pߊ•+×’—W@qq ={^‚Ãá ªª†¾}¯B­VÓ½{WöìÙOdd8%%žÍô}ûb6×3|ø0üýõø³nÝ&òò xà»‰ŽŽ$!!ž€ââZI*00€N: PÈÙ¸q+yyüûß!íw¸Ý-ä²Ëz V7´*Ù±c7[·î U«JKËÈË+ {÷®’q:$$ÄKî:ŽØØh–-[Mtt$7Þx=z½žÈÈV¬XC||+®¿þZÀcŠÌÊ•ëHJJàºëZ¶df·ÛÉË+¼î ~~~˜Íf*+«¥8`GŽd5é+"¸°P(„††CŠüüB´Zíߎÿ&øç R© ¦¶Öã’PPPD``r¹\JY ‰ËeÇd²²}ûv ‹ý•”£]»Ô¿“”SñD÷EYY9ï¾ûo½õ²¸s'a2™Ù¸q+:´ó!`FJJŽIáí>J¥ §SÆÁƒûÏz[V«õ¸å¢ð¹XÐh´fd2—´âÖ­±ÛM¸\.Ìfß>I'Ruœb6׳u뮾º·¸s^4ÊÊââ„“ @ 8¿p¹œ8¶Óþý ‚3GMM-Ë—¯–’pyWO5(rœNW#˜³ƒ³Ù$nŽ@ðA.Wàç§¥¾ÞŒÛí;„MLL,—\Òéô5iÑÕçÛŒÀE``€Ok³ˆˆ(´Z?ŽÉ&!!  À&È™àð᣸\6qs‚Z­žÄÄd**J1͘LÞýÖÒÒ:âp˜Q©tM¦¸°ÙLÿ;räH))Iç]ýß}÷#‹-%)© #G>â3¼ü‰û×_ÇŠkh×.•Çû7AA8¾úê[V¯^OÇŽíyôÑàÉ1üå—sY·n]»vâá‡ò¹ŽØ*•­VKxx82™cçQp8,g]€deùGšO ÷dÔ¿¿N‹ÓNYY)K}ƒDÕX| ‰·Ð³ç%²ÈÏÅ…¼þú{ç]ýß}÷#ddLå¾ûîä“Of5yü×_Ï'.®S¹ùæ™1ãs¾úê;’’ÉÈ˜Ê 7ôã³Ï¾àË/çÑ®]SéÛ÷*fÍúò´®-<<Š˜˜"#ÃŽoˆ‰G@Ðrär*ÄÅÅé3…'6[ã?‹¥Þç{Gé{¶=Ÿ+VŸ«˜0a, ñÌ™ó­ä`èççÇ3ÏŒ! ÀŸ—_~ =%%¥èõzÆ=O?ý[¶lÇ`H'22‚7ß|‰’’c,Xð))É|÷Ý„„„0nÜHZµŠå‡þË/¿,:þò cìØ‘0kÖ—ìÚµð$‰3æqjkëxóÍÿ“êoß>§Ÿ-]ǺuyôÑ1lÙ²®¡¿ÅÒ¥+ùäàIJjCVVv“7aÅŠÕddL }ûTÞyçCV¯^Ç¿þåIÙ©S{Þÿc©í‡~€®];ñá‡ÓNIã """ð o³@ h¹Fbÿ‹FI^^Ö߮ӫ±Ûí¬_¿IzažøÆÎ{¤òŠŠJÞ|óÿxæ™1dee3sæGDGGI¡L^}uS1Ò¥ßDGGb±XÉÌ5µZÍ!ƒ¤¿F£áí·_ÆßߟþýûJåz½Ž×_ŸŒÓél\I­V7°Ú™8q<C:aa¡¼ôÒ³’vpò¾DZZ ;vì’ê¿ë®Û0MDGG±lÙJ>ÿükZóÌ3îu<þ¸ƒ!ääDÆ%•&öî=à5•çu×]ÍŠk0Òéܹ#G>Òàû¼¼‚Á!ìÏ¢EK1Ò¹ôÒîÒþÆàÁùõ×E é\qÅeÒ~È!ƒøùç_1Ò¹êªÞ<ðÀݧuƒëŽ„çUUÕl߾˧ÙlMM-Z­–ƒqà 9p`VëÙÕN ‹èÞ½«¸9Á?­VÛ-Ãj5QWgôéBpÂÄb±“•uÔg}íÛ§yõä<£®Îȱc•¤¥µóyŒÓéÄår£Ñ¨±ZmçÄB«¹Ðûà|B†ËåB&£IA™ ìvói·"<ÑÏ3 %%Å””‹Î4I›6ñ´j{A^[AA¹¹ùâ&Ÿe‚ƒ騱½  V«“Éì3[˜V«'88£ÑŒN§%88„–8Z­V ó±ÛÅfüùNxxAAÁ`±Ô{ÝÃóóÓ—€Ûm¿ û ¢¢FíuéÅçɰ°HJKK°ÙêO©nΟ֭Ep°X¬]ψŸŸŽ6m’),ÌÅb±`·{E”šÚp —«hBQùK*îóX€—°oßAú÷ï{Z¿?r$‹iÓ2HMMn‘ùîž=ûùüóoèÒ¥#Æý™ jÇŽÝ|õÕwôèÑUJ(ë«yó~ W¯Üu×mRù† ›Y°`!}úô’|Xþž"o仢R© # @Ûídݺµôí{r¹£E¡LÊËK(..&&& ÁùF£A£‘Ó¦MF££ÑL]]MƒcÔj5J¥»Ýó`¿öÚ»TVVó OtVÏÏår1wîî¿ÿ®?}z‡g1räÃ$''Jå<ƒìì«çTVVÎË/¿ÅªUëš=ÖápðÙg_н{W&MÏO?ýÊ‘#YØl6¦OÏ wï^Lš4žùó"++Çg=r¹½Þ0""ΗË!H p»]¨ÕJ‚‚t¤¤¤€J¥özœÃañú———ís’*÷uã¿ùf>6›qãžç¹çþLµqãÆ{žqãžç…^<¿?üð_é˜êê~þÙã§±bÅéø1«ÊÊÊùý÷?(--cܸçyûí´ÿÆï3nÜó¼ÿ~CïòÜÜ|Æ{žššÚFç|!!ÁÜtÓ@.üýŒÜx•JMtt ±±1ètêãꥰw¸‘ÉdÈå.bcc‰ŠŠ"  ±†ˆŸŸ_£òɓߞ¿õë70þOìܹG*ß¼y[ƒß|ýõwdd|åå%ãfÚ´Y<ôÐ=-:o£ÑÄ™\vYBB‚yè¡{ùì³/¨ªª&77ŸîÝ»Ì=÷ •LôO& ˆ¨¨(bcc‘Ë]Mn š&v¢¢"‰ŽŽ"<<òŒÔéu K©Tâv»¹ÿþGøì³)˜Ífž}ö%&NÏ‚?óâ‹$Añ⋯3n\:{öì£_¿k dÏž}TUUQXX̪Uk¥ãóó y÷Ý)Œ7Š}ûòÛoðÊ+9z4›)S>¥_¿køá‡ÿòùçŸÎ™|úéli9Êjµ’““‡ÃqaÏ>""bhÝ:îøM‡àOD­Vc³Õ oÁÚÁË/¿ÅCÝ#¥J~ýõ÷èСë×o&3ó°ô\¾ôÒ›têÔN{|)§Â«í¿L&cüø'¥“>[´iÓ–À@ 2™LhgX#©®6ž=rBˆ<òÈ0‚ƒƒÐëõÜrË Ün7kÖlॗޔ^èþþz‚ƒƒˆáÀL.¿üRfÏþšŒŒ©²lÙ*ª«kk*u´i“ ©á#F"99¥Òs*·ß~3mÛ&_¾Ñ6ðÀNMMᇾºào²ÑXCAAn·‹øøVbÔ $jkk8t(“víÒš=¶¾¾žwÞ™"i&›6mÁíÀOëÔétçlWQQFqq=ññqèõ:qóÏ [¶l¢]»¿ŸB»…±°”ôî}µµuôìÙ—_~NúîDæ¼aÃîeôè 8‰Áð€ô}Ÿ>—óÜsãþr¼¦QýÁÁA±oßA²²r0›ë¥ÙPǧŽmÛvÒ»÷eêIMMáС#\qÅ¥TVV %€a·ÛéÒŲ¤cÇvìß.]:QVVNdd„T¾oßA:vlGié1¢£=ª^ûöi8pˆöíS)..!&&€´´¶df!--…¢3bVY_o>BÙ³AŸššBPP`ƒë\\”—WPRr …BqJ“ЧŸMxx˜ô900 Ùßìߟ‰Óé¤sç§tŽN§“Õ«×Óµk'BCCP©”øSUUMHH0‡¡mÛdÔj5Z­55µrôhÉÉóùÔÕU£ÓéÈË+ÀårÙàZ§FMM F£‰’’c¤¦¦œ] Ä~~~$''ñ⋞½½^Ï믿xvóoºévïÞÇM7  $$„°°Péøðð0^xá™ffXµ¼üò›X,t:<ð§¥Ç¡CG:ôAöîÝHlltƒß >ŒY³æ0oÞyè¡{¡?žAeesçÎ’fYü³fÍ!$$„#`ܸQL™23f*…8yòÉ‘|ôÑ ¦OŸExxééÃ;v$S§~Æ'Ÿ|Fdd£F=zFn̉µÞÈÈòó ¨®@£Q'4’‹ ³¹žÜÜ<êë-’Æà}¹êMV¬XMqq)är9*•úŒZéùôD·ÛíÈd²F³^»Ý.-+WÅívc³Ùh6›M f(—ËÐëõR¹R©l`Uâr¹p8Øí\. …¼A¼,§Ó‰Ù\¿¿ÞëfÚ‰ï E£f±Xp»Ýhµ–;êë-(•J´Z¿¿\£‹Å‚J¥l°1yâÚ}—«ÄÏ:|…29ám^VVAÛ¶Ilذ™~ý®§¶¶²EK åå&aÆû 22»ÝJII±ô žl}¥ÕêHHhƒÝîÑTM&.—[ÒòOD0MÒØñóÓ R©°X¬h4jé²X,h4šŸÝn<jÆF«'ž·ÛÑhB«Õ¢T*A§Ó‰N§E¡h¾8néÆß¿aò#—Ë…ÝîYrS(”²¯^€^ïOMMeƒò²²rL&óñŒhµz‚‚‚©©© ¨¨„  @¯|'B™ÔÕYزe³×ºýû÷õú{Êä<£ªªš#GréÒ¥KZZ6›øøxòòZnT(fnÿüüt;vŒÀ@ŸÇ(J´Zµ$@.4víÚKdd ¡¡¡>)++G«Õžrªh¥R…Ñh¢ªªê‚}F %õõ Y#áüW±Ùêμ"øßàv{²Êå Ñ‚æFË{ež8Nra¶{ž£ bWvÆ-Ò:ïÙB.—så•—£Tú!—+½Þ›ÍÄ®]{½ú©‚W^y¹OÇMA ˆÓédÙ²U(•J®»îj©|Û¶ètZÚ·ÿÓ”0/¯€ƒ‘OZZÛszf³™k®ésVÛP«ýq¹,(*¬ÖÆ6Ô«V­åškúP^^qÖÏE p–Ÿw=.×Å7N¡P²&díÔÈÌ™_ˆÓé䫯¾“,¢jkë¤ »X,²³sY¹r­d™u‚Y³æH ˜ÎÞ6ûÏ4*• «ÕâSås:§}.¿ÿþ]»v"66F<¹‚óóϿҧÏå´õl̬•*l6Kô•Jë3ÖÁƒ‡IJŠóª5©ŸmÚ´•{ïÊwÜ"…)((Äf³¡×7ÜhJMMaÈÁ„ÊâÅËøþû…,^¼Œ5kÖKß=šÍâÅËX¼xëÖm<YY9ÔÕÕ±xñ26lhhP]]ÃâÅËšMïZQQÉ«¯¾ƒÁŽÁÎĉ¯PXè ¾gÏ>yä †t¶oßuÎnPAA¯¾úN£ò£G³Ù±c7ÑÑš%9’Ř1Ïb0¤³dÉòfë>xð#G>…ÁΚ5¤òýûòøãOb0¤³qã©|Ïžý >ƒ!mÛv6[¿Ëå⥗Þ`É’-ºÖµk7`0¤3räS8pH*?‘ò‰'žæÐ¡#Rù’%Ë1Ò3æYŽÉj¶þÚÚZyä òó [t>sç~ÁÎsϽLAA‘T>gÎ< †t&Mz•¢¢©<#ã+ †t&O~’’cÍÖ_XXÄw<Ô¢s±Z­L™ò)C:o½õ´Üi6×óÁŸ`0¤óî»IÖNF£‰÷Þûƒ!÷ßŸÚ ÖÕ A70qâ+âm/øÛ¸Ýn«×¿ÂÂ<Ÿ9‡Z4UöóóãÑGÿuü°SXXÌ’%Ëyï½×š}ñTW×`·Û©®®‘¬…JK˘?ÿ'Ž?€ÅTW×Ò§O/¾ûîG***éÙóòó ©«32`ÀuÒ‹õÞ{öêòWöìÙOëÖñLšô4ü±‚Õ«×Ñ©SV¬XÃŒ"—Ëùä“™¸\.zö¼äœÜ ùaC.ü›o¾QŠtYTTÂ÷ß/ä•W&À·ßþÈâÅ˸á†~^ë=z4›_]ÂûᅥŸŸŸþ n·‹¨¨H/^Δ)o£V«˜9óK\.7,_¾šéÓÿ…BÁ´i¸\.)Ç»/M´®ÎˆËÕ|X•իד••CFÆT, Ÿ|2µZEnn>EE%ddx^‚Ó¦ÍäÎ;oãàÁCTWב1•ºº:¦MËàîjR›>}6F£±E‰´æÎ]@xxS))9ÆŒ³yæ™1ÌŸÿqq­ÈȘJQQ13f|ΤIãùòËy¤¦¦`0<@~~!Ó¦Íjà8ÛX ؘ9sN“q×þÊŒŸsÕUW0zôcdffúô &LËŒŸsÝu×0vìHöï÷„ð?þ f̘ÍÀýxê©QìÝ»Ÿ3fóä“éÇgJúö½Š?þXÁõ×_+Þ‚‚sŽW Änw`0¤³eËv Oœ«$'·á¶ÛnjQå:Ž»ï¾øøVÜ}÷í |ƒ¤i:t”ÀÀ@i‰lß¾Rþï‡~»ï¾~ý®‘|HºwïFqqf³vÚW_Ý›ûï¿S&û÷gr×]·QTTLTT¤¤ŠµnO^^Á9é踸X^xái¯Â55µÈårÉc¸C‡TÈôYoyyþþzÉ?%%‰#G²)--#$$XòHLL ;;‡ââ"#Ã%Ó¾„„ø&÷lÚ´•nÝ:Ó«WÏ]çÑ£Y¤¤$JOØí É[@¯×¡Ñh¨¬¬:îÝïÙK @.—5i„°`ÁÏ<ðÀ]-ðmÛNzôè@tt$UØí6oÞÆe—õ 66†’’R\.7náòË/ >¾ùùMŒŒ9LœøÑÑ-óرc7—\â1ÑöD18 ÀîÝ{¥( :¤±ÿAöî= %üéÔ©{öìoP_»vm9xðx“eÔj4𝇫µi#»Ýξ}°ÙìüþûR鯪ªÚëñ2™?¿`ŸmÖÔ4ŽUvèБOdÎØRŸ÷õ0%S1ÒÉȘzV¶ÙlÔÕy샂éÓ§×_Úÿó¥wBK#¢·P(¤âq±ÿA–/_Ezúð&m¡O‡Ã)Eîý+¾ŸBö ErBpäääçsÇCΫþ9Á@pa#“ÕêÝ_"77¥RÙ¤C£ÉdfÖ¬¯˜8q<3fÌæÞ{ï`Ú´ ž~œ×ß86Ÿéf·mÛÜÀ° àÛoäîjðÎüŸ¦ÈÏ/`ãÆ­äå°téJ)ùSNNë×o"''—åËW7¸¸víRùí·%& }úô¢S§ö’P@€?:´kÑlrðà;Ù±c‹ª©e¬åËWóÄQS<§ÓÌÕW÷O”@ h’‚‚Bvïö¬Þü5öTJJ’”néÒ•Ì»@(—ššZ~ûm‰ôÞMJjÙdgç68®_¿¾RÃ3¾„u‚û'ÏÀe2wß};õõõ)÷„š¾ýö[”¤§Çl®'00€¡Co!::Š!Cc6×c6×7}ë­ƒ‰ŠŠðz>‰‰ |üñ»ÍÆr9p “eËV1räà „G—.9p SÚ‹Ù²e{“kÿÞµ3-~~^þNë 2XÊЪU4N§‹’Oö°ß_ÊÀ×Kßçääñè£c¨¬¬’cYY…´ìsœ¸]»¶äåH*íºu›èÓçr:wî@fæl6ʽyóVi)çtX»v#cÇ>+}¾æš+¥dCµµu;VFJJ"ýû_ÃÒ¥+‘C]‘6mZ3p`-Z @ié1çß²F›7ïÞygŠôù¾ûîä›oæ×H3IJJÀÏÏaÃîã‹/¾‘–:vl‡R©äá‡bÖ¬/-.ï½÷1sç.>ßu×m|÷Ý€goîÄþÞí·ßÌ?zrêüöÛ ÀÍ7ßÈÿ»€Ÿþ!C5¨É’å ÐO¼­Ï3¬V+³fÍ‘ÞqӦ͒¾[¹r->:†GCqqéàÉþx¢Íyó¾§²² ›Í.•íÚµ—_~YÜ¢ýÿ­œX >ù%îMEJII"%%Ék=z½®ÑÒCûö©´oßx»©ï¡¡!-ZÂp:]ìܹ‡Ç+•=üðƒôés9/¼ð #FŒÃáp0}úÒA‹%®\éU•]±b ×^{Õ)߀Ë.ëÁ_|Ãu×]M@€?<óÌh&Mz•’’R^}õ….—‹úz‹4ÂÂByþùq<õÔDjjjyï½× `âÄñŒ3³ÙÌ”)oKß /<ÍÈ‘Oa·Û™6íý&—7mÚʧŸÎ–̶¿ûîGÆŽA—.Ž÷µ£U\RRÒÓ‡c0¤Èûᅥ\.'<<ŒGyƒ!°°PÞzëeär9!!ÁÝÁNTT$¯½öB“ã‚?óÛoKp:]Lžü2¼ûî«„††ŸÈØ›_zèÞ½+jµ ƒ!Ò7nr¹œž=/A¡P`0¤Ó¥K'F~¹\F¯^=ÉÀ`H§GnR0M_|ðÁ4vïÞ‹ÓéÄ`HG§ÓññÇïüåEbkàäzB` é\ýµÜsÏP¾_~YŒÁΠA:ôiBõÓO¿`0¤sË-ƒƒ!“ɤ½%ÁùƒÃá ¢¢Rz_]{íU¼öš'¡ÞÕW÷æ­·úèS)ú÷™`üø'¤÷ðäɯc6›éÚµ]»vbß¾ƒäçðñÇï4zÆÊËË|ÆÂòDðî#rA„2’>¥¯sIDAT9yÉìl Ñ`µÖIÿ}ÃéœËÁƒ‡ˆ‰‰n2Úª@p2{÷ 11AäÊ8 ¨ÕþØl&Nøh4þ^ˆÁc yòˆÉdâ¹ç^fÊ”· Âþó6'ŽçÍ7ßçw^‘´î>˜ÆoLnøb–ÉQ*ý|îx{ϼòÊ; ö@&O~áÇ׊£G³ùùç_9ò¯™+ÏŠ"87œ‰Ä.‚‹NÚ‹N8OQ(”„„„HË+V¬‘¾ËÉÉ“ÊwíÚËk¯½pVÏeß¾ƒŒ?‰# üñÇJ ¸îŒì(&LûÒ?ýfétºSŽÈyª¸Ý®¾Îá\œ‹@ àœ<ï¾>7ÔVÔèõºËáJ¥’¤¤6ãr¹¸óÎ!´m›D\\,~~~¸\.\.wÜqK¤Ëç^…·÷Lxx­ZÅH)‡#"ˆ¥²²ŠÄÄÜn·ÔnÛ¶IgÄ*TDãÁi!BM à´ø]ž\”göIEND®B`‚snd-16.1/pix/rcos.png0000644000076400007640000006110211147553270012614 0ustar bilbil‰PNG  IHDRX>Q#nsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ#w ® IDATxÚìÝy\Teû?ð²+ˆ;*î;Yîš»©¥¦i’V.)æž=šÙf¦©I*æîi‚Fj*šàš‚" ˆ¬²È>ìÃ0ÀüþðËù‰Ì 3ß÷ëÕ+™¹Ï9÷¹Î™3לåºd2™ DDDD¤5u""""&XDDDDÕ?Á Tkf‰‰‰ðööÆ£GY"Ò+uSÙÙÙðööÆÝ»w4"ªºëìÙ³X¾|¹ÊåääàÀ055ÅùóçÅè‘^`úôé*Û‰ÅbüöÛo055Ńðï¿ÿ2xD¤&ÊÞüûï¿!•JѶm[•3úúë¯ñõ×_£~ýú?~<\\\àááÁ‘Nݺu ¡¡¡xóÍ7U¶=|ø0 „¾}û\\\ÔšŽˆHSJÏ`õíÛ“&MÒÊ‚Ž;—2ÿÍš5 íÛ·Ghhh™¶Û¶mÃóçÏ•Îïúõë8wîœÒ6999X¿~½Ê¾­ZµªÒmJJJðå—_jeYëÖ­C^^T%¿ª~}'$$`ÇŽzYØ»w¯Ê3—÷îÝÃÉ“'•¶)**ÂW_}¥•>}÷Ýw‹ÅJÛœ9s7oÞTÚ&..;wîÔ[,wïÞ˜˜¥mîÞ½ ooo¥m¤R)Ö®]«•>}óÍ7H$JÛœ:u ·oß®ô²4ѹsg̘1C+óºråJ¹ã”‹‹ ºwïŽ3gΨ5ÐÐP9rD£å^½z>>>M“””„¬¬,~‹(¥g°7n¬µM›6 Ó¦M+óZAA,,,Ê´E"ŠŠŠ”Î/??¹¹¹*“ž´´4•}KII1¨6iii())QÚ&77fff*‘H¤·~gff¢°°Pi±XŒœœ½ÆRU%’œœXZZÖÈXÊd2­}Ôe½zõ*½,MØÙÙim^Æ ðaÃʽ޺ukµö[H$'>ùùù*T½ÊÇÇíÚµÃàÁƒÕžæìÙ³èÕ«š6mªö4ÅÅÅ066æ·%‘†*üáóçϱgÏáïàÖ­[^ÜlÚ³gOF—ˆª”X,ÆîÝ»‘ èÒ¥‹ðNTT”Z·?Ô$!!!B,ÔõùçŸk”0&$$ ""‚;éÌ•+W4jïïï¯ñ˜k×®©<ÑQ©kß¾}pqqALL \\\àîî^æC´k×.áogggäææÂÅÅ·nÝÂìÙ³¹‘Î?¾ÌqêåËËùùùpww„Áƒ£}ûöpqqÁ±cǰpáBPËÂÂÂ4~BóÂ… ð÷÷×hš´´40à:”­QB^RR¢Öm9¯nÇ—s u>|X£ögΜAff¦FÓüþûï•N°”^"üä“OðÉ'ŸÈ}¯wïÞ勞2e ¦L™Â½’ˆôæwÞÁ;ï¼#÷={{{<|ø°Ìkƒ  Aƒ8’žž¿dG…îݻ׺xeddÀßßcÆŒQ{šØØX$$$`àÀjOsõêU”””`âĉjO­ÑºH¥RÄÇÇ×ÈíÄB£DDTãEDD`ëÖ­M“––¦òamØ»w/}ŠŒŒ &XDDDDµ,""""-3Ñ÷E"‘ð„Iqq1·$WWW¡R¸!Þ‹BDL°Ê°³³ƒ‡‡€ƒ=À–H$Š+@eù"¢ªâêê*”/IOOg@ˆÈ°,;;;xxxx1ØóÁƒ¹ˆÈ฻» ÿöõõe@ˆH#¼DHDDDÄ‹ˆˆˆˆ ,""""b‚EDDDÄ‹ˆˆˆˆ 1Á""""b‚EDDDÄ‹ˆˆˆˆ˜`é˜ÞÇ"ÌÍÍÅîÝ»R©”[€ˆ Ò¶mÛ„cTvv6BDÑû,sssŒ;cÇŽÅÛo¿Í-@Di̘1±Ê¢VÆàéÓ§8xð wR[JJ rrrTÁ,téÒPPPÀ-@D©S§N¿MMMke $ 222¸3ÚNŸ>ÐÐPôïß¿ÖÇ‚÷`1Á""¢Ú,//Û·o¯Õ1øí·ßššÊ ‘v!::ºVÇàÙ³g(,,äÎÀ‹ˆˆH±û÷ïd¿/^\#Öƒ˜`U{»wï6س †zimÇŽÙ¯ÜÜ\Ú»»»äzlÛ¶L&XDDÕ[pp0JJJ ²oAAAÜ@µ¡n÷sçÎ1Á"""ÝXµjƒ@µÒÉ“'õ²œððp’ÑãÇ3Á""ªîRRR"Ú¸q£Úm% ²²²˜`&XDDDDL°ˆˆˆˆ ›ÞÆ"›7o†³³3Ƈ™3gÊm³ÿ~8;;cÉ’%X¾|¹Ü6W¯^…­­-òóóáåå%·M||ˆ‹‹S8¯‡"-- ]ºtQØ&//GŽÁÀ•öióæÍèܹ3¬¬¬¶Ù¿?D"~úé'´iÓFn›+W®àñãǘ7oÞzë-¹mâââpçÎLž<... —÷Ï?ÿ $$+W®TØæÎ;ðõõE“&MP¿~}ù&äååaÕªUèÙ³§Ü6‰‰‰4h¦NŠ)S¦Èm#‘HàììŒÙ³gã³Ï>SاÁƒcãÆJ"nÚ´)nܸM›6¡uëÖrÛäää I“&˜?>FŒ!·ÍÖ­[áììŒ÷Þ{Oa,9‚wß}+W®TË[·nÁÄÄÇGãÆQ¯^½rmlll b xWWWa¼Ôôôtµ§‹ˆˆ@»ví4ZÖ¨Q£ðÏ?ÿ(Ü'äIKKCÆ ù-FTÛ¬iÓ¦aÚ´ie^+((ÀÁƒaii @£Fàéé‰+W®( z÷îÝ CRR’Â6+W®Ä¢E‹&÷}xzz¢I“&¸}û¶ÂùlÛ¶ ýúõƒÂ6‹/Ƙ1cpûömdffÊm3~üx 0ÏŸ?GLLŒÜ6]ºt§§'ÌÌÌðàÁ…Ë;|ø0:uê„+W®(lóÍ7ß`èСJcùßÿþÇÇãÇÆòÍ7ßÄÂ… !‹µ˾}ûâÂ… JcÙµkW„††*lóî»ïbÕªU Qئk×®ðôôDxx¸ÌËãáက¥_¢«W¯Æ¼yó„òÌœ9Ÿ}ö”&E ,€¯¯¯Â6öööðôôÄõëב——§°ÝŽ;‰„„…m–.]ŠE‹)å„ °`ÁܼySib*Û4hÐ:tÐÛú+:£ú2'''899i%–êôiôèÑ*ÛôíÛW­XvìØ‘ß`zTXX©TªqòÓ¹sg¥?d^åíí÷Þ{O£eܸqƒ Òhš9sæ`ïÞ½js ]ïÞ½qïÞ=…g¾_uíÚ5µŽ/sppÀóçÏQRR‚:uÔ»;hÔ¨Q¸xñ"¦NªVûÏ?ÿ›6mÒ¨_7†¹¹9ž={¦ðŠ…¼czll¬Zmãããabb‚¦M›jÔ¯nݺáÎ;•Ú®¼‹ˆˆj¼]»vaóæÍˆˆˆP{š'NhtÙÞyçœ?^£iúõë§Ñ—ù•+WÔúáüj‚•˜˜h°pk"&XDDTãeeeaùòåøí·ßÔž&77ÖÖÖ-ÇÒÒRé¥ýWíß¿_ώċˆˆH0tèP\»vPý{÷лwo‚ Š&Mš 99ÙàúõÁÀÓÓ“¨Û¶m-ZÄ@0Á""ª}fΜ‰0¤u‰‰‰hÞ¼9Á‹ˆˆˆj²‚‚„……©ýÔ;,""""5Èd2µËL0Á""""ªÆäþe‚EDDDT Ož|¸0¬ˆ¦ã«é=Á255E÷îÝ@£Qº‰ˆô©k×®eŽ[DDšà=XDDDDL°ˆˆˆˆ˜`1Á"""""&XDDDDL°ˆˆˆˆ˜`,""""&XDDDDL°ˆˆˆˆˆ ‘Žé},B‘H„+VŠ‹‹¹ˆÈ ¹ºº 㥦§§3 DdØ –<<<¼ìùàÁƒÜ DdpÜÝÝ…ûúú2 D¤^"$"""b‚EDDDÄ‹ˆˆˆˆ 1Á""""b‚EDDDÄ‹ˆˆˆˆ˜`1Á""""b‚EDDDDL°ˆˆˆˆtLïcæææbÿþý©TÊ-@Di×®]Â1*''‡!"ÃN°ÌÌÌ0dÈ€D"á "ƒôæ›o¢¤¤`nn΀‘a'X¦¦¦èÑ£   €[€ˆ ’““S™ã‘&x,""""&XDDDDL°ˆˆˆˆˆ ,""""&XDDDDÄ‹ˆˆˆˆ ,""ª©D"ìììR[ýúõ‘™™É@0Á"""E8€™3g2¤6gggxyy1¨‚±E"V¬X(..æ "ƒäêê*Œ—šžžÎ€Aéܹ3ÂÂÂàààÀ`0ÁzÁÎÎ^ ö|ðàAn"28îîî¿}}}²oß>¸¸¸à矮µ1˜>}:\\\0räH‰ˆ¨Z A·nÝô²¬·ß~>>>jµõóócÂCL°ˆˆÈp´jÕ Ïž=3¸~½ÿþû8yò¤ZmÿþûoŒ7Ž“˜`‘a˜9s&oÑ‘ .`̘1 ,""Ò•Ž;"<<œ¨E=z„®]»\¿¢££Ñ¦M&XDD¤ž+V`Ó¦MÙ·âæÍ›ÜHTåЫW/ƒëWFF†Vê¿1Á""Ò²Ö­[#&&† 2¯¿þ:úè#•í[·n;wâðáÃj†œœ°oß>|òÉ'ÿ?2™L–””„/¿ü²Lãõë×£I“&a€fE–-[†¯¿þõë×—;M||>>:›¿¶?ƒ¯òððݸqƒÛ¸ çïçç';|ø°Îæïãã#;~ü¸^c¤ôá;w…¨¨(;v -[¶Ä Aƒ„K~ãÆn(ݸq#~üñGtèÐ111jæ%"ª¬eË–áçŸF«V­˜˜ˆ+V磻¤ M›6FÛ¶mñÉ'Ÿ`Û¶mˆŒŒDJJ ,XÀ‘NóÍ7ß(;ÝURR‚!C†ÀÊÊ 4.ÚØØ`È!hÛ¶í‹£K—.ÈÍÍÅ Aƒàèè¨óÎwèÐ52Èù꼑˜˜ˆ>}úTz^hÓ¦ÖN¹¶lÙÍš5ƒ©©i¥çÕ¼ys4oÞfff•žW£FТE ­\n^<ñ6qâD~´u36F÷îÝ‘••…^½z¡K—.Â{¦¦¦8p ºví SSSÔ©SNNN‰DèÞ½»Ú—"µ¹Íª"VºžÆ Ñ¢E ]FÕögðU÷ïßGÆ ѪU+nã*š¿­­-Zµj¥³ËÌ‘‘‘H$èÖ­›Þbd$+½]žj…{÷îÁßß_íÒ¤}êÜÓHÜf¤?ûöíC§Nðæ›o25Ô… ••…>ø@oË4aØk—zõêéôW©Ö½{wÛŒ ˆƒƒƒÎn®&ÃаaCU„g°ˆˆþONNŒÕºÔ•›› ###>yFD/äåå õ¿,--all ‹Å(**‚µµ5ŒŒŒ¼¨_•ŸŸSSÓ2ÃP@*•ÂÊÊ u꼨³^RR‚¼¼<˜˜˜¨LÀd2rssÕ>Fð øøø nݺ˜>}ºP/Kž+W®àôéÓ¨S§¦L™‚þýû3€D:rçÎxyy ÅO{ôèY³f!<<û÷ï‡X,Æ›o¾ gggÀ¡C‡kkkÌ›7-[¶Dll,öìÙƒ¼¼<ôìÙÿýH÷yëÖ-XZZâ“O>AûöíöãÌ™3ðó󃙙>þøc•g¶™`‘ÆbbbššŠÎ;ëì†Ä—EGG£M›6e~E”¿+ÝÁÃÃÃË ‘Ò¸qcáA‹€€˜˜˜ G:ï냄ºÝ»w‡……ÒÒÒ àÅœ:tàNd`üýý 777`íÚµèØ±£Ü_©aaaÀæÍ›Q\\Œõë×£uëÖhÚ´)Y Ü¿4ªµFU+$$Ë—/G³fÍ’’"2wwwÇ?ükkkxyyÁÇÇ"‘­ZµÂ¬Y³™™‰ï¿ÿ[¶lÁ/¿ü"Ôê¼pá<==aii‰ºuëÂÍÍ 999øê«¯àææ&·×®]ƒH$‚››òóó±jÕ*lݺU8Æ‹*-** üñìííqùòe¬\¹R§ËóòòÂ_ý…ßÿ]xíàÁƒH$‹ÅHIIÁˆ#°víZ >\hÓ­[78::âøñãÈÈÈ@QQâââ0~üxõõ¯¿þB||¼ðä­[·°hÑ"¸¹¹ ú²²²0f̽${¤¾ÜÜ\áRŸ¹¹9 Ë a󲂂Ô­[uêÔ®/ùA†ËÛÛ[ú-::“'OfPªÒÑd¤R)¶oߎåË— ŸÛÒâ³¶¶¶HOOGZZšð$±­­-233…coi!t{{{DEE¡°°^TFÈÉÉQ؇œœá„‚¥¥%òóóUö› V5–——‡ˆˆ4nÜÿüó:wî,T¨>zô¨p:uÊ”)°´´ÄãÇáïïhÛ¶­PÓìĉÂÎ2aÂ¥eRRRиqcÌž=[xªêÖ­[èÙ³'Ž?ŽÆãí·ßðâ’Kiõþ#F E‹HII`àÀ(,,D×®]å.ëĉ°±±)s ýÊ•+066Ƽyó “ɰtéRôíÛVVV0` ±XŒƒ ¯âþýûððð€¹¹¹ðúËgŠ^•™™) y”’’"$aaa˜;w.‘ššŠsçÎáܹsHMMæ»}ûvÀ/¿ü"¼¶yófœ?pqqþ+#ÍÉÉIHÖJÉd2áFÆÒÿËd2˜ššâòåËpttD“&Màææ†—Ÿß(m«ˆ±±1Nž<‰;vÀÑÑ~~~ˆŒŒÄ‘#GÊôMÑéãÒ_EqqqˆŒŒÄÑ£Gñüùs/ê…EFF"22’ú( ˆÅb/¹711)sê?66¹¹¹333H¥RÈd2áGŒ:ƒçRÕJHH@ff&bbb`dd„©S§ÂÌÌ ;wî„——qôèQdggcË–-Âqªe˖ؼy3bccqñâE8::¢^½z˜5k’““ñÛo¿ Ë8zô(òóó‘žž.ÌÓÑÑׯ_Ç“'Oðûï¿ãСCÂë[¶lAaa!<<<„×¢¢¢ðèÑ#üõ×_ÈÈÈüóÏ?åÆÍ¬MD"Ž9WW×2ÉÕËg’JÏfÕ¯__Hšsss…³NÖÖÖÂg¸ôlÖËg­òóóËÝ)^^VAAA™þ<ƒU•Ñ\°`Z¶l +++ØØØ ""Ÿ~ú©° :999(((ÀСC¼W*33íÛ·ÇÅ‹…ddñâ 6_ª IDATÅ —÷äÉøúú"99=zôÀ¸qã¼xüuòäÉ:t(âã㑞žŽ€€\¹r-Z´ð¢ò?$%% }hÔ¨Ο?ž={ÊM<:uê¤v,víÚ%ü»  ÞÞÞ6l˜ÚÓ›››C&“ÁÕÕ°´´„ >úè#µ€åË—cÛ¶mÈËËCß¾}…‹çÎ+üž6mw\Ô¿¤¤¤`õêÕ¨S§¦NZæéÀ¡C‡býúõ˜>}:ºt邸øx¬Y³FFF3fŒFƒSSÕ¸|ù2ÂÂÂpêÔ)Ô¯_;vD½zõ••…ŸþÀ‹§ÏJÏ>ååå ?àÒÒÒ——‡ºuë ǯÀÀ@…Ë*,,„ŸŸŸ€ Ç£Ï?ÿ\øÒ?tèJJJŸŸ/Ì·ôÿôÿíØ±IIIÂÜfÍšá³Ï>Ãüùó±aá{÷î ï{÷îÅ… `jjŠ%K–ßm?ýôŠŠŠÐ®];áÁ‘#G°zõj˜˜˜ÀÕÕµÌr;wîŒK—.aèС>|8Nž<‰Õ«WÃØØ...Jï¿b‚UÃôîÝ[îëAAABÅýW5mÚóçÏîZ·np¶éUýúõƒL&CHHˆ\½ªE‹hÑ¢ðÁ—Ù–.]Z®íÇ…ƒ»»{™³I{öìQx–¨tºììlXZZÂÄÄAAAå.»Õ«Wyyy(..Faa¡H©£´ßGŽÁåË—…לœ„lff¦0dTé²E‹xq¯ZiÌ_{í5¼öÚkÂ_£æÞ}÷]ôë×&&&°··/óÞ½{÷Ê 4>^ø["‘ ,,Lå1äåy4hÐGŽQÙÏÄÄÄ2£Y#44ƒ®µÛnÙ²eÂÙ'B|ºv튥K—¢°°°ÌçpÖ¬YHOO‡¹¹¹pßUÛ¶m±|ùr”ù|O›6 iii033+w{LBBB™×&OžŒAƒÁÔÔT­ËµL°ª9ssórYôœ9s°hÑ"á&Ý?üݺuC«V­„¬½E‹3f RSSñã?¢  ðÞ{ï)]ž±±q¹ágLMM…ú$¥Fމ;vÀÛÛ[H<5j„Ñ£G }ptt„•••Â3X?ü𢢢pÿþ}¸¸¸`üøñ˜4i$ \\\P¯^=,\¸HOOækll WWW´mÛcÇŽÅ‚ `jjŠ… *êÁ¢\,•ÁŠŒŒÄŒ3œœ,\"Z¶l²²²Ð®];!Ùú÷ß±oß>ÀŒ3øH¿222îŸ{•¼$ªqãÆ Z5ciiYî3.¯ŽÙ¬Y³°zõj@:u°wï^´lÙR8ö˜™™ Ç×ùóç ÇžnݺÁÓÓü1š7o.Ìcøðáøè£`iiYæv+++˜šš¢}ûöÂ<°páBL:7n„T*-w|­m¬¬¬Ö›“W ÖÄÄDîg¹~ýúBÂõòwš¢Ïý«ŸqeǹǥªòèÑ#œ?^x"„ˆ¨ºøñÇáì쬴nReܼyNNN°±±ÁöíÛ1xð`¥µÙÈðð Ué¯ÉæÍ›3DTí888èt蕎;bíÚµÈÎÎFÏž=ѹsg½šá,""""-c™""""&XDDDDL°ˆˆˆˆ˜`‘,±XŒ-[¶¨5³Ë—/ÃÅÅGŽQ8P*‘¶I¥RlܸQ­¶?†‹‹ ¶nÝ* %"Òk‚%“ɰiÓ&\¸pAåŒ|}}‘””888àØ±cŒ.éÅÞ½{ñǨlwÿþ}øúúÂÃãF*3‚‘6)­ƒuàÀÌŸ?±±±*gtöìY|ýõ×^T­uqq)S;"" r§íÕ«W™a(ˆj²'Ožh4Î")wþüy <*Ûúûû£oß¾€îÝ»cëÖ­eÞOLLÄÓ§OåNÛ¥Kµª·çææ";;›5Þˆj9¥g°fÍš¥thMˆD"ÄÆÆ–ù/""Æ Cxx8·Õ?ýôƒ Eï¼óœœœ´2¯ÜÜÜrÇ©ØØXL™2—.]RkáááÂQê’Éd‡rýúu;‰ ˜Þ*¹÷éÓG@·TAAfϞͭ@D¡cÇŽèØ±c¹××®]«Óåúøø //S¦LQ{šÈÈH¡ÏDdx”žÁŠGpp0D"‚ƒƒË\* Ä€„¿—,YÃÃß~ú)£KD:—ššZæ8õòYŒŒ ôíÛñññ€I“&áúõëÆŸþ‰‰'ÖºXI$î4DU`=~ü~~~:t(üüü,¼×¤ILŸ>]ø»U«V˜0aüüüеk×rg«ˆˆt!66¶ÌqêÎ;Â{æææøðÃ…{<5j„™3gÂÏÏfff˜0aB­ŠÕ¾}ûÔº§–ˆ*Oé%ÂQ£FaÔ¨QrßsppÀgŸ}VæµöíÛcñâÅŒ*éMï޽ѻwo¹ïYZZ–;&ÙÛÛó8¥CW®\Ajj*œ ªÕXh”ˆˆÚ½{7òòòÔn_\\ ©TÊÀ,†€ˆˆyòä ŠŠŠtºŒDGG3ØÄ‹ˆˆH[>|ˆ¨¨(‚˜`U'ÏŸ?ÇéÓ§b‚EDD$Oaa!nܸ¡Ñ4999xüø1ƒGL°ˆˆˆä‹ÅøóÏ?u¾œû÷ïó¬1Á""¢ÚÃÏω‰‰:]Fnn.222lª}/0??_§‹ò‘¡òôôŽQš”) ý BFFFµT»  ÿûßÿàææÆÊ«rŒÑ¬Y3/®£¢&M𠏏X8n©#-- 6ÔhMË`!77¶¶¶ 8¬ÿÏÌÌ #FŒ2w""C4tèPáßæææ ©å‹/¾€‡‡‡N—‘€C‡᫯¾bÀ ïÁª¦ž?Ž´´4‚ˆˆtâåñ‡‰ V­qõêUÜ¿Ÿ ""¨È}ab±˜c‚EDDT;\¼xQçË())Á¢E‹l&X†kÆ ÈÏÏg ˆˆH+Ž?Î 0Á¢¤¤$áé%"""záÊ•+xöì,""ª¾BCCYŸ‰ nŸÔä¯ÜÜ\1Á""ª­6nÜhp}’ÉdÉdÜ8¤3ÉÉÉ:zzz• wÄ‹ˆÈ<}úÔ û5~üxœ={–ˆT:qâ„ÆÓ¬^½ºÆÆƒ )4bÄøúúÖÚõ_²d‰Aö+,,ÌàŠuûøøÀÎÎ"‘¨Fl“¨ÝöÂ… 8þ<,"¢ê.77·V¯ÿ„ ôré'''Ç ×ÿèÑ£HOO7¨>¡cÇŽxòäIµÞ&EEE(((ÀöíÛÕž¦°°°ÜðL°ˆˆª¡Å‹×êõo×®"##¹#ÖâСC•žÞÇ"‰DX±b°,WWWጡ) ҇˗/Ã××#GŽÔérâââШQ£7æ§Þ,;;;a Ì‚‚zôh…Æm2d†jpë3lØ0\¹r… ‘*ðñña t 99b±Xãéêׯ[[[°‚ô>¡X,Æ©S§R©”[€j” håqðŸþ&L@ûöíÔ*ròäIᕟŸÏ€h ¸¸èÕ«—ÚÓäääÀßßo¿ýv­‹×Ó§Oaeeŧ†Ñû¬:uêÀÞÞöööhР·Õ(‰D+ó‘J¥())a@«p¬ªS§NÚGóòòtº ©TŠýû÷s'RÓÅ‹keqÒëׯÃßß_§ËÈÊÊÂgŸ}†† ê}ýô~ËÌÌ £Fð“EDiĈ¿ÍÍÍkÌzùûû# 3gÎTÙöÖ­[0`BBB¸CÖ%''#--M§Ëøå—_àáὯïÁ""ª¦òóóÕ>óQXXˆ§OŸj4ÿÛ·o£ÿþ 4©$‰`ggÇ@0Á""Ò­Ý»wë| ðôôT«mVV<<<¸a ŒD"™™Yµ_tïÞ½Fm›k×®Uª04,""- Bjj*àîÝ» ©´lÙ2lÙ²…0@111HIIa‚EDd¿x"b‚EDT•NŸ>¬¬,½,kôèѸpáƒNÄ‹ˆ¨f»{÷®^êlÍ›7o¼ñýôS½<°aH*sß,""Ó¾}{DDD0dPÚ¶m[¡q «³U«V1Á"åÄb±Æuoˆˆ*£aÆ\µj•ÖF@Ð'''ë|9­[·FLL w `kk‹íÛ·cÓ¦ML°ªwww½-+%%üñƒNDzÓ£G©Ý>''2™Ì ×¥°°+V¬À¶mÛt¾¬wß}gΜÑÙüÍÌÌPXXÈT ;vÄÀQ¯^=µ§¹{÷.úöíË«*2DDîîÝ»pwwÇôéÓkÄúÌœ9à†Õ‘ÄÄD4kÖ¬Ìkz‹P$aÅŠ^Œ¸NTS¸¹¹!==½ÒóÉÈÈÀÏ?ÿŒI“&1¨UÈÕÕU/UÛ•ªNJJ ²³³—/_†¯¯/FŽ©tšË—/ë|œ<ªÙôž`ÙÙÙ Ã5ààÁƒÜ TcâÚxR«¸¸XkO±PŽ|9ß××—Ñ1{{{ëdL»sçÎ!((Ó¦MCnn.rsspÒ9^"$"Ò¢Aƒi<͉'ðþûï×ê¸Y[[£¤¤Dg5Á~ûí·§£GÂÏϯVï+ 4@vv¶Á—a‚E¤©Tjp—‰òóóõVœÔ7kÖ,ƒïcRRR­Û.FFF×§€€üóÏ?Og¨èK«V­œœlð7í3Á"RC||Äk¯½¦·å•ÖàÔ6OOO¹·Ú0ÁRCRRžû Û·oWùÝQé-Ázð༼¼Êü'ï¦ð{÷î!44Tép ¡¡¡Ø»w¯Ò+)) Û¶mÃêÕ«¶),,DAAÒ6¥}RUm÷Þ½{ˆŽŽVú+1** 111Jë‹deeáéÓ§¸wïžÊå©Ó&44b±Xa›ÄÄÄ(ett4=z„   …m222päÈ•—RO:…C‡)ms÷î]ìÙ³ ÛDFFbïÞ½Jc™™™‰ˆˆøûûk%–!!!*φ=þ JÛªõ$ª>©Û&22Ré¯ö½{÷âêÕ«J#‘H„½{÷ª¼Üxøðax{{+móÑGaß¾}fÑÛÛ[8Véjø–—Õ­[666:?Ó4`À|øá‡ã””¥ÇR.99Yã$+66–ÅMõDoƒ=›™™ÁÆÆ¦ÜMé/+{{{! éÒ¥ æÌ™sss¹óŠˆˆÀàÁƒ1oÞ<4mÚTá¯ä#FàòåËpqq‘Û¦¨¨íÛ·‡‘‘‘Â6¥ÉÚÔ©S•¶ ÅÈ‘#1oÞ<Ô¯__᯵`þüù“6¯ÊÉÉA—.]°fÍtîÜYi"®´OÑÑÑèÔ©æÌ™£ðÆÛ§OŸbÈ!øôÓOѤI¹mRSS±dɸºº¢S§NrÛH¥R8;;cÿþý8}ú´ÒXZ[[+í÷£G0lØ0Ì;Wa,ãââÔŠe·nݰzõj¥±œ%÷þûïã×_EXX˜Â6~ø!®_¿Ž9sæ nݺåÞoÚ´©A\²´±±ÎvÔ©SsnW566†±±q­ú¢ ÁĉqöìYµÚ—”” ;;À‹!v:uê¤Ó²ÖÖÖÚÇP{š«W¯âÑ£G:t(3 š’`uéÒ¥ÜÎYú víÚµèÙ³'·U™qãÆ©lóñÇ«5¯•+Wªl£ÎÀ¾o¿ý¶ÁÅI>;Vk±¬Jo½õ–ðoE?öHÁ‹‰ ÞyçƒéH$‚ÚíÓÓÓ±~ýz <FFF°µµÕ鸟3fÌÀƒpýúuî<5Ÿ"$""­'Xêüh©ÉvìØ¸¸8¥mN:…‰'ÖúýeáÂ…hÙ²%,"""C¡êÁ‹ª’••¥ò†ú¼¼<½ wdÈêׯ“·^L°ˆˆH'üüüt¾Œ… jôd`›6mtþÄZÿþýqûömƒØ………ÈÍÍEƒ j»é[ûöíU>áÌ‹ˆ¨–{öì™Þk={öLãiÔ­…¤OÝ»wW«ìL“&M*\•üøñøûï¿ b}Åb1D"š7o®ö4G­qŸ™ž={âþýûjµU·¼ ,"¢æûï¿ÇW_}…Æ#??»wïÖù2¿ýöÛZã™3gV›‚–¤‰Dèß¿?,"¢ÚÌÖÖ‰DíòšðððPZ„HžY³féet]H$_Ne‚EDTI[¶lÑú<ÓÒÒ v}‹‹‹5ºñ8-- ÅÅÅ kÀ‘|WÏP«uO\FF†ÖuåççcçÎz[,""5\í¶‰££#:tèPë÷͆ VêA½ŸÁ²³³ƒ‡‡<<<°k×.]ˆÈ ¹»» Ç*{{{H$lÞ¼¹VÆ¢gÏžèÞ½»Áõ«AƒÈÈÈÀ¡C‡ª¼/6l€]™KE Õr{×­[5ªõÇ€±cÇâܹsÕ'Á""¢Ú´iƒU«VéeYæææèÙ³g…¦mÛ¶m…ãuuuÕËÙ%Mï)êÕ«—Ò'15Ž•··7¬­­Q·n]ƒÚÇnÞ¼ÉZa‚EDT•a-Üàž——‡¼¼<¥mlllðÁè}ÝJJJ´:ÏüüüJÞxã î :dccƒuëÖ¡gÏž˜1cFZ·Ç#&&F§ËˆŽŽ†››[…¦e‚EDÄĬŒ5kÖ ]»v:_—›7obàÀܨzTÑúV·.AAAxúô©ÁÆš ‘Ži}ž™™™¨_¿~™×fÍš¥Õe¤¦¦båÊ•OooodeeÕè}F×Cåüïÿ«Ðt¹Á|ÿþýUË;wî ÿþ:ûœ0Á""ÒcccØÚÚjô´ÔW_}…ï¿ÿ^ç}4hÚm\m·A@@@µ¹ìË/¿D›6m4šfÛ¶mX´h‘FÓH¥Rܾ}Û cðï¿ÿVéò###ѶmÛ }N˜`鉩©)š5k†gÏžUëõ˜9s&7¦×®]“[B"‘ ==½ÊúUPP€ŒŒ ¹ýzyø ªröìYŒ;À‹º7oÞ„µµµÖæoee…zõêU«}‰ Ñÿ‰DhРA¹×###qàÀ*ë×£GpìØ1ƒ[jjªPÔ ÐhoUú÷ïñãÇWjfffhРž?®—˜è}°g±XŒóçÏxqj“ˆÈ>}EEEÀòÿgË–-˜3gu¶Œääd€ƒƒƒÚÓ”ÊÛ°aC­öeûöí€?þcÆŒÁ»ï¾ËàiiiøöÛoÑ»wo-#,, ;w.óÚ† àè舣Gª=SSSÔ¯_©©©hÖ¬™Îc£÷3XFFF033ƒ™™™ÁÙDDôò¯ÝÒÿtq³º|||ôòcWÓ¹Zúæe}ôV¬X¡ñ½;ݺuChh¨ÖûS:$™™$‰ÒXj2|!»téÞzë­ÿŸ$ü_§ââb¹íe2™Ò:QÚàååUnè"C¨Ë&‹•Ö!Ó{‚ennŽqãÆaܸqxçwx'"ƒ4fÌáXeaa¡´mtt4=zTéeÎ;?ýô“Öïózúôi¹Çóÿýw¥W…Ž;"<<¼Úí+‡ÆÇ¬÷åŽ7NëóŒG‹-„¿íìì`oooeªÚñãÇqçÎÃI°ˆˆjšˆˆ<|øPçˉ‹‹C~~>:uê¤ö4‘‘‘.w‰¥ª%$$”ù"'ÍMž<Ù ûgoo¯ó•øæ›o”žuÔeŸE&XDDÕ„§§'bbb°bÅ ¹Csȳ{÷n׎ºs炃ƒ…¿gÏž­rš?ÿü“&MÒxY¯Þ8­Í© ÝŒ3`jjZîu###×Ï ÇÕ«W5š¦ÿþ:/!‘šš*÷õ´´4Ç€ÒzqL°ˆˆ¨Rbcc‘˜˜(ü=`À-k÷îÝeþvwwW˜d%''ãñãÇUm_òìÓ§ŒË¼fmmÖ­[—Ipu•ÈDFFrg×,""59;;ÃËË«JûвeK½,§Aƒuãvaa!êÔ©£Ñ«èèh­»üå—_““Sæ5™L†øøx¹íûöí‹»wï–{]*•"))‰(³uëV,]º´Ìk•¹ŒÍ‹ˆHM7Fŧ×U IDATJJJ•öá›o¾ÑËr¦L™‚îÝ»—ymôèѸxñ¢ÜöçÎ MV–¼zO 033C£Fª,öqqqBéŽRÅÅÅWëOIIÁĉ1fÌö×ëfU•¡C‡*¼ÔWîLe>oL°ˆˆ´`ÅŠØ´i“VæµhÑ¢r_äÚddd„>}úh4MÓ¦MqæÌ¹gdàöíÛeÆ}« ___ÚOŸ>½Ú%wïÞE¿~ý䯹´Xe­\¹£GÖhš è|Ýýýýu:‘H„§OŸÊÝÇ_ýuÁ‰Dpqq‹‹‹F7 é“«««p¬ÒõpºRPP¹µ£6lˆ;wîàСC:ïGll¬Fí[¶l‰¸¸8õÇÖÖvvv˜9s¦Væ×°aCXYY•{½C‡èÝ»·V–‘’’‚Æ«Ýþï¿ÿ®Pr§È´iÓ´2ŸÔÔTDDDÀÎÎæææ055…ƒƒ:t耧OŸ*ÖÈȨ\…æÍ›—)r[« È­z¯mfffhÚ´©a$Xvvvððð€‡‡‡ÎŸ$ "ª(wwwáXUÙû<Ž9¢ôý>ú¨ÒýÍË˃··w™×bbb`gg'÷i°÷Þ{üñ‡Â¡F´¡E‹HIIÁš5k4šnùò娲e‹Îúell ­ `ÝVÛûfýˆ-s¶äÂ… ÈÏÏWØþí·ß†ÊùÖ­[mÛ¶•û^HHˆÊ{/^ŒmÛ¶Üvèܹ³Ál»ê€ Q%?^îë-Z´@QQ‚ƒƒñüùó2不§ë­†¢þÀwß}‡¬¬,½ÆK,#**Já}K&&&°°°(7°²&víÚ¥òAªøøx ûúú*-wñÖ[oáÒ¥K•Z÷Gi|©iß¾}Â}K?ÿü³V¶ÁªU«ÊÔT ÀªU«4:©ÁÁÁJß777†²qttijgÏʽ®ilïܹ#w¸#&XDD•TRRòâ@ªàÒ‚±±1d2üýýqýúu/.H$<|ø¯½öšÖúR‘BÆÆÆH$ÂzèÊ7Ê$22™ ÅÅÅ Ÿò²°°@Ó¦M+4…ï=£FÒ¸2û«µ˜BBBäŒ|Y§N°páÂJÅàòåË*oÒGJJ €—åôu™©AƒJ>'22Ráå=}˜ýôS¡¹——.^¼¨³Ïô7““ccc¥g;ûôé£òl(,"¢ š5kV™¿5©Õóý÷ß ÿ;v ßÿ½Ê_ä>>>¸ÿ> ((_|ñ¦NªQŸ[µj¥ö'ؽ{·Ê3o À¿ÿþ àÅýJÍš5Óø{eIœ¼÷’’’„ÉíãÇ\¡ éênÇÒ~UôÌä«ëРAµê"99­ZµÒÚ¾\·n]4hÐ ŠÓvëÖ ï¾û®Væÿr¬d2Ž9‚„„lÚ´ Ÿþ¹ÒiK§)Ý6•©‰5jÔ(…uº–/_Ž#GŽ -- uëÖ­Ðe[&XDDZôæ›oj|ÖcÖ¬YÂS„Ý»wÇš5kT~Q§¤¤Th,¹˜˜øûûxñ4^‹-ÔšN*•"&&F£eåååÁÜÜ\å º=zôÀ‚ÿ×Þ¹‡5u¤ü›@¸$D.+H*"B*‚f¹(´.VD°¶¢t±´ZŒRjmñÒ^Жººë¶[•Š«¶«T-ZW¡T¥ºàÓ]]©riå⃤%Ë=Pn¿?xÎù.É9˜ Ôùü£9™Ì sfNÞ¼óÎ÷ݸ‘Ž÷yöÙg‡-;Ô{þþþpwwWÛ† ª««;vM¿8À8 ~çÎ*¯ßzë-F‡#ÒÒÒFÜgGGÇ!elmmñÆoÀ‚ÞV …˜4iãº322†M&=p¬ª««¡T*Q^^±XñññŒÛ î}gg§ÚØ3ê^#::yyyHIIQ+¬KÕHbªZ[[qòäI|òÉ'àñx×Ú¨{°ŒŒŒ°|ùr`­;A £…¿¿?ýmˆ/îÝ»&LÐøð§8xð ÊËË333VËl˜9s&ÂÃá§§‡%K–06nß¾‹/ÂÛÛ›¾Æ„‡2Ú C@@ …Îw; ñꫯ2*€eË–!>>ž±\ƒ:::÷‡cΜ9Œ?»yóf˜ššÂËËK'ceaaÀÉÉ æææË ¤§§#55•u[ÙÙÙˆEiié°kèÛ ½ÿ>€¾MXWWW¸ººÒÛöº‚Ä`°´´d•,WOO ,€@ `ÕNVV+%:yëÖ-qKEEE())Á”)Sý²_µj ’’‚ùóçÓ×ÔAˆS©£¦¦˜>}:cC& >>>ˆŠŠR[výúõôZ`` +#èXe³…»víZLŸ>}P,–:ÊÊÊàììL;%˜P\\ŒÐÐPÆ'=£££1}útÉ©ûóÓO?ÁÓÓ“Q`¸‰‰ –,Y‚††ƺlŽŽŽ¨©©Q›r(ÔI- …§§'Ö®]‹7ß|“Qù &ÀÒÒ’ñXéƒ@ ¬ñññÁÔ©Séךº|>DGá¹\.d2-Ö¨‡ccc:ý ÓmÙ³gcýúõŒO)êëëãäÉ“8þ¼Æ²!!!tú—_|‘µgeÍš5jõ‹úoᆅ…aêÔ©¨¬¬Ô·Ôßû²jÕ*ViR8ôôô4qý133CYY£xªþí0 ¥ár¹àp8ظq£ÆmÎþLœ8eee077Ghhèí-]ºTŃÊåraii©5\º(ŠwÞy•••ŒúdhhˆÎÎN¼þúë¬Æª±±‘±'’Z“>d,Áår¡¯¯sssF饈E #$!!ª¥<9ÚfïÞ½X±bV¬X¡±,¥™LƸ [[[V\.kÖ¬a´ÅÒ_TÓÕÕ{&(oAuuõïÏ;wWÄßß/½ô«1Vwªq(¬¬¬ÐÕÕ…œœÆFƒ………ÆÔE‰e|_(}.¶A熆†t|ßpö;77óçÏW™cÚУ¶›>9oooÔ××3ú,•s’šcL Aww7«þ‰D"4773u%@ °äI(µë6ÛVýa“ƒ±?FFFغu«ÆrS§N…··7k£a¤ýÒ"‘666 Ñ(iÑŸárö©ÃÏÏQà9ŸÏGzzºNt úãææ¦6Ðç­¤`«ùFÍãK—.±úLÿ6™–miiaô#XÀ’íÛ·ÃØØfffðõõÕY;'Nqò[6_P#=Î;¢Ïq¹\ÖI˜G£_º€ÇãÑRšTòµ5gFòƒA×sl$©fØ2ZIºMLL`bbB ,@ÐB¡PcLÑŽ;†ô(|úé§ë733qÂf]~ ,x,um6PcdkkË*UL>¬1>h¤ýš?þˆt½˜àää4")]cggGq#cNNNŒ·eE"£àuê‚X,Ö¹7Ž)ÄÀ"– 6'ŒŒ†¼>¿<}ièÞ×5F¿ûÝï»]ôK—cñòË/ÉûÏ6åPèéé1Þ*år¹Ã®¡þP'™Ê…‹@ Æ3gÎÔKB},,,´rÐ@[ùød<ùM‹‹‹U&—Ë‘~øÌ*0j444 ;;›Q®°ÖÖVdggãîÝ»dà~eÖãxº(Øž@$ñ±•MË⫃JP[[‹³gϲ“#„‘ÒÕÕ…cÇŽ¡¶¶ÿüç?iEç¡èîî¦Ë^¹r·nÝ"H t‚Ú-«W¯¢®®ŽQd~dd$öìÙC‹µÉd2$&&’&:åã?ÆŠ+hµouÏžÄÄD<ÿüótà8yNXíííƒ\ëNNN‹ÅðññÁÕ«W»¡3gÎàÊ•+ƒ~M}b_|>ŸÜ €'NÀÍÍ퉴}íÚ5œ:ujÐõúúzìÚµ ü1¹AaHLMM‘­j`)•J\¿~]¥ JˆÇeõêÕX½zµÊµ®®.ÖùŸúóÅ_à•W^ÑZµYßX­«ªª UUUxþùç».¹\Ž;wî`ñâÅZéÛ7ß|777V©$†#77Ó¦MÔ)S»®ï¾û¦¦¦Œó¡×¹1Vú6iÒ¤'ö€\¸p!.\8èzMMNƒuµ}G»þ[·nÁØØNNN:©_Ûkp ùùù˜4i’Nu”Æû=Öuý¥¥¥hll„‡‡‡Nê/..†R©dœŸs$¤§§«¼Öúr2mÚ´‰õ—ë·ß~K ¹¹¹áöíÛX¸p!ŠŠŠ²Ñ××gÝnnß¾ýXŸ×e}cµ®ÿûßøî»ï'·Ô´ ÖúÖÜÜŒ   ˆÅâÇ®‹ÃáÀËËK+‹éôéÓ˜ppp ßkooǹsçð /ÀÄÄ(//ÇܹsQ]]ÍØ·±±Ñéߢë±Òuý©©©055Å’%KtR¿¶×à@ø|>u–îè×pu]ÿ·ß~‹‡²Ê%Ȇ¬¬,466êTþâöíÛ*¯Õ¹'%%A&“¡¸¸2™ GŽ¡ßûñÇUÄ¿^{í5TWWC&“!++K+_àš`“É|´ë«ui§UuÞ &€Çãi¥.¡PÈ*]„:#–'ÁÓ²Ô±|ùr}ñT)))xë­·è÷ZZZ°}ûv:Ÿ™,--!“É””„·ß~ûWyG»~]¯‘±¼Ÿ–{¬ëúŒŒXéˇ{Ìé-I^˜@›,ÂÈ ÕäžÆIII:÷`ž,£áÁ— ;@ ‚v!JîOööö077'ñ 'ƒ@îa ±hÑ"…B2¿b\\\ÐÙÙ9ªm’-B@@ŸļŸ~Љ'"$$Dcù#GŽÀØØëÖ­#ƒG 蘤¤$477èS%°²²œ;wUUUX·nm$Ëårœ9sŽŽŽðóó£ëÈÈÈ@YYBBBè„Õøì³Ï`gg‡_|Qm:::ð·¿ý ÖÖÖô?u-BðÔÓÔÔ„¿þõ¯J¥xæ™g””Dëô ¤­­ „——f̘£Gâ—_~!ƒH èˆcÇŽÁÎÎR©R©}ô %%J¥8vì êêêpêÔ)H¥R477###pñâE(•JH¥R|þùçË娯¯GBB¤R)¸\.þñ Û‡††ÄÅÅA*•ÂÜÜÿû߉EÐ>§OŸFxx8ÊËËG¥½Â]]]ÇÞ½{•ˆˆP9ñªK"##Žððp:]T~~>}->>žL 1ÈþóˆD"H$,Z´………hkk²lii)ôôôàîîŽyóæA.—£®®Ž â8á½÷Þûï¾Kb1gÎxxx@"‘@¡P@"‘èÓN €D"‹‹ ¾ù椦¦ÂÇljAAAøòË/ôyºV®\ ‰Dooo|ùå—ÈÌÌÄìÙ³!‘Hð / 33sØ>ܸqöööH$ðõõE^^zzzˆEÐ7oÞ„R©D\\þüç?ë´­††ìÙ³GeÒ?zô±±±ˆ‹‹Ã«¯¾Šýû÷«ì«'&&ÒýR(ؽ{7öíۇ͛7ãÃ?Dkk«ÎúƒˆˆÄÅÅ!..»wï¦ûD]›ù䨨Ø`Û¶múrÄÕÔÔ‚ƒƒ±xñbܸqIII€Å‹ƒÃá`Ù²exôè‘J;HNNƆ °gÏú:%(Éãñ`gg‡ºº:´··ƒÃá 99NNNxî¹ç …¨®®†R©„©©)ôõ‡žòõõõ¸xñ"žyæœ={X·nÑÔÔD—ãóù‰DCÖÑÝÝ }}}ðx<444 ½½3Jßë矦÷þ ÂèB­Q333lذååå(,,\ºt R©ÁÁÁxðàöíÛ O´xÿþý055ÅgŸ}†›7oB @,cåÊ•HNNFdd$ý,|ýõ×add„äädäääÜÝݱ~ýz?~"‘ˆþÑøî»ïbÆŒHKKCVVÀÙÙo¾ù&RSSáïï+++¤§§ã·¿ý­VD˜Ç+999¨¬¬Äš5kÆMŸ‰5ޱ°°@ee%ÚÛÛi/Iqq1Nœ8C‡ÑÂ|‰D((( µ|NŸ>‚‚\½zÑÑÑ´Ñ‘‘1¬uýúu$$$à§Ÿ~‚¹¹9V®\ °µµÅáÇ‘˜˜ˆ7nÐûؾ¾¾´®ŒL&ÃâÅ‹‘””D÷á£>‡ÃAMMJŠ.—‹¨¨(ÁHM$''cÚ´i˜7o]¿‰‰ f̘ôôtôööÂÓÓ†††C~þ7¿ù ***ÐÑÑÄÄD:t%%%¨­­Å­[·T ¿átT|}}qøðaôööÂÀÀ€6Ììììè-Êêêj¬ZµŠLÞ1†½½=òòòôyIÍÍÍUæÊ_þòøúúÂÅÅ"‘õõõèì줷©$÷„±ËñãÇ‘››‹ööv„……ÁÙÙ°ÿ~¬\¹‰‰‰ˆŒŒ„ŸŸöíÛG?GzzzðÆo`Ë–-hnnFbb"Z[[Ü¿Ÿn£¢¢]]]Ëå(--¥ë8zô(¾ÿþ{TTTÀÊÊŠ¾N xçææÒ×îÝ»‡ºº:TVV¢££ððáC¦ñëdgg£¶¶vq%‹Q^^±XŒÂÂB,]ºmmmÈÏχ««+îܹ€D"Á÷߉D‚›7oÂËË ¸|ù2-Z„ÒÒR8::ªÔ¿k×.Èd2L›6 ŽŽŽHKKЗrnÊ”)àp8ÄÀúµ@/Ö¡ÔËýýýéÓ‰ŽŽFLL m PFÓP¸»»ãøJJJå¤ú0wî\¸»»ãÌ™3øÓŸþDŸôê°ª¿¿?233ajjJï©S¿ÙòàÁäææâóÏ?Çõëבœœ TTT`ûöíèééÁÞ½{1cÆ Lž2™ ŽŽŽô3›âîÝ»tX‰X,Fhh(d2lmmI ¬§ >ŸOÿû¿ÿýþ~þüy¼üòËàr¹P(€ÎÎNðx<\¾|›7o¦·ÆÄÄ ûàóù°°°À„ †M‘ÃãñÀãñ`hhˆˆˆ: U¿¡¡!݇'N`òäÉèééQ1b¸Ü¾ÐÀ¦¦&tuu¡££ …ÆÆÆ˜5kòòò P(P[[ [[[«l#Êd2„„„ ±±---Ëåhmm…‘‘,,,Xeww·JߨmW(++CTTÒÒÒ §§Gÿý===¸rå 鿇Ú",**Bhh(™¬c ‹aÕÚ^ …8zô(´q„¹¹9ø|>,--‡õd›˜˜ÐFô| 27îß¿žž( ´´´ ==AAAô3Ë墭­ \.Ë–-Ö-[ô¥¡ž)C¡§§G×ñßÿþÖÖÖ022BSSêêêðÅ_`Á‚Oí½ Fppð ëFFFˆŽŽt]"‘ Z³ؼyó ²öööîûóçÏ«¼¶¶¶f•Ñè`s._¾ ˜™™©\ß±cmìÚµ ¦¦¦¸~ý:¦ü9®žIDAT¾úê+ÚµzõjÀ‡~H{X¶mÛkkëaÛ«¬¬Ä£Gè8' Ï¥ÝÛÛ;(Á÷‘#GðàÁ@hh(œñã?Ò'é¤R)îÝ»GÇl $..UUUôkøùù¡»»›ÞÖܺuë Ï¥¥¥!((ˆ~½sçNðù|ìܹSíXfeeÁÓÓ“ñvOUUìO…±±±hnn†··7–-[ /=QJJ àý÷ß'Þá ‘‘‘ooo•58ðy­­­xÿý÷û¾$98p@ßQÿœœ…Bðx<ÁÞÞQQQúòb>zôAAA¸zõ*¾þúk€——ñÕW_ÁÏÏ6ð¨¶ÿõ¯áܹs´·ŒÒaûãÿˆ¶¶6X[[cÁ‚ƒÎø?æ!wè;ŠIEND®B`‚snd-16.1/pix/phase-paths.png0000644000076400007640000000732411267144660014073 0ustar bilbil‰PNG  IHDRZðW!]sRGB®Îé pHYs  šœtIMEÙ '«fIDATxÚíÝ]z›¼PÈã ô›ÿO‡À¹pËCùÐZW©;NìíW[ÐÃÐ@Û~ü @€8q]×}fÿîû~úÏø6ãíÍ î8ìû~fË[¶²pü¶È»@92L–Îòo†Y‹I•¼ˆ hšÃc­!o«ã¾ÿóÏñ @ѼÝ'²çËÒD†¿Aô>\Ó[/Pßw^P4mÆá}aàM®1¾MÃ~îÉB¨)eaC#[£\P4¬ÆaLö}¿<6qz‹@-·¦gký^&P4üµs~·Ãešˆ²°ôñíxKä+åEÑ(šÖâ02ù’n§hð9ûãEÓç,m`d^îPÁ hwHõ5=®uF³½V4*FwHmãÛ˜ÚUÙ(š”¢Q1âzJyÕrrÇtŠFÑ0a²´þšçwR—;߯îQ4‹:° ¨;¤†ñmêIe!Š&Ó™E¿kˆC€ÓqÈÓµ˜ÔØ­ŽZµ†(š”¢Q1-°vXOMG8±[*Eãî°âñín˜{@P4ÁGS4â‚ÛncŠ&å-¿„ŠæML––7²+LzAÁE£Åa–·¯Ù‡íhärDZWÙ(šE£bÄa®QÕ w*/×!Q²EsAÑð>ÖËvÃy¢d!ŠÆk‡n¿Uu餌^W1¾¯UŒ8$wYO¿È¸Ü! i£b.*s¤-3Yú\e_]‚*“µb Å!×ÇRö5B•¢ÉJżžÉÒ[j:fR4cµÉBÞR4·½‘M¦ ;¼q|›q¸,¤Õ¦PÑ QÖ h‡¯©°ëV<”5o,šK× #k‡¹ ú[=^NFYSpÅ„‹æ©7¯¢‡œdŽ»fÊéGAŤ,lÉÒkªju×̃ÛÀU6ÅWLWÒ±*FwÈÕÚÓ€JÞ­*FwH¦nQE¬²Q1)E£bt‡¤Tó´b®;ã¨a-o,š¢*FÑ Ï k\ýE0Yš^ÖË[L¸@JѨt‡ï¥šAÅ ÓÇŒ•$y…^àߊQ4ˆÃÈáPz:Þv…^xKÎ*FÑPk‡ÁÊܨÄa‹¬þƒ¢á½l¥‰è*e8T1ŠÝaÍ­|AÅ ;l·¬$ *Ý¡!îN‰+zP1è[¤šAÅ ;lt  ¨Äá¹:ég‡ÒWpÞ£YP11W“o†¢Ï5¨˜È³v8”?n\Ý·<‹”0¨ÄaCCÜñLêT d\;ܽÞÜ~— —ùWÊ ª`÷t‡Ëä+h5Ñ䨸¡;,.ÿà‘îpUAˇN!*®è¿Q÷íëØ5£šAÅ@ö8|Oã‡ãp¶R¸ºpȼÙ÷KGž•aípkÍ›kÄ*(¸³;Œ+³þ¾DtMRP4ðx><Û8£ h ÂUW´€æºÃîÁÃð…1((¡;|ø|4æw@Ñ@ qØm\ì×$*µÈ0Y:ÆÞcù皤 hàñ8,¥¸EÏÆaêYi (ï:+ <Ø.{AY…p|=ÜÔvkó¢fJ¡„ üâøpaw8½öáôÆüç,5Ê…”rQ@pww¸Œ½üAh” @áqøÀ(H)àŽ8´vE1) ©>9 oø®.oO£\”m·Ë™-V7ãì$¢Ñ/$& \ÛÈ?àŠâ]¸•&ÛòᲦU9v‡—oœ‘ÞÚD €îpìß1 @»Ý¡+Z ÿ$Ÿ#ñ¨Wέ4ò€v»C)€îð[ihº;´•qø'ùl¥ ^&KÇØ;“IH/=çk‚’âð|McqwÎÇQA¨h Ä8\]&ŒjW¯t¯¸AÑÀ½l¥º³ˆªß;Å“áò¿;ï=PÙr \„ïáªîÐB-MáV›˜aíðÛöý¼ÑœÝ2[J4–…¥­tàLÜw ÅÊlª±.¤ÚZqùóÀYåM–ªlØiÌ­a÷ðÃ0oe!ì·†ýnõÉUVB-ß› &¢8„ƒ â;K³®& ¡¬îðä¸Uw MÉ@jƒ¸ÕvÃ?3n‡<+çVšé†fJ¨HεÃÙU%"mu‡ÓÙN)@‹ÝátÍoëkxw(h½;ÜbÖ€¶ºCÉ@ëÝ¡,@þ1¬ñ÷àR©W®Ø|œ\'i;ó8ÎJ¹ª š ÂÀ ØîëgàOCˆÂoÕŒ_ñMáÉ6ñs¸n#oŽÕ”6îô)¤òàpkødîŽ[™7»¯tDkè ôkÈžˆ×cæpÌó@Æ‚.õãO@ âî-IŠX«w t.vúø@)£]ùÏ1Y ®hyÃÝ!´‡ÓËV¸œÄ0­ÉUóû¦ªÉp ÅÖ™ãϸè@ Z BïvH “‡^؆ǼFÁ @ cSxu›˜á¸ÃïÕ–åmü @-²]ïPBdk¤¶†ÕÄa·ØMãåCC8X5¿¨š qèÊÝÔÎq‡ð@ƒ¨e„Ôñê–1Û-–‡U8ЀZdØY:ΔÆO™š\àmqx¤ ^ô‘^ ”í@ 'ic;H.™ß¥”L_BnY;ä}Aèý IAøÈÁyâp,þñ¦I+yeSè- IM᳉øs¾ø¿_Ï>LP‘Sk‡ãá´S\Þ ¶†@RkXqŽAË/:ÓD´Ä»ÒJæW‰%ã¬4 #„F;žá±íîæ—¤Ý1¶ÒPo®n%ó~†­ [÷í,ݺ»8¤¦Ð[’šÂ2'KŸ•&üà€ŠX;„S­!ÔŠC¨>Íy@R–9)ºåãŃpZÛ†¤ ü~QWêa¿) ‡¢˜„nm^t+‹IÝ!¤‘V2•´‰ºC˜·ƒ¶Ì@RGX×–Ý!ìá8: ƒD„ø ~ /HDÝ!²pç`5 ·ˆÃ„Ï )o/JcË ¤•L=[f¶<3Y:ûd‘ˆÒÊ?Hm ëÍ¿"ºC(!¤æ_í™W\w¡Ãê!)+=¬^w;Ma8Å$tÁý2/X&Ôòd3òbӨؘye§(¹©-{pŠÒ^-*mËž Åw8‘Êd)·æÐmÉdË µgáýá˜mî·õd¶Ìð¦,¼ùG7²kFwHCY8»Å–dáÖ[Ý5óÖý2ºCÞœ…‘ûtä$5‚­õˆâгp6/ ZÃÔÔæ®™U&K¹5 3¶h"F²°Í•Ý!…¶†»Ùy^…Ó[Äž8¤â,‡¼q»}„Ճ%ÓªÖÑ®,‘ÔJjó¿^Ö‰|ñæäjš…N®¦;äýaéÀ H KNˆCªo ãÿKkˆÖ0õ2¼ZÃû^5“¥KÄÀŒ¨WÓžœÐòªîÐ R»C'W‡Ô„á™Rk„° ¼ð* 5šâðØe]¼°‘¦pÉ!¤F5Â}–‚ÓÃÈŽ]©Ç§ak¼â\5ò¯äîp–d3Lž¿ïh ÔÖ ât{ ÛkÓ§œ†CG¢„ºý/â{þëúNÕ”8Êÿ”ðT|¤oðß"ÿóGÑæÎíÔ–¥ð¬âIú­ýÖ~ë³9x­Ky’»¬À¿q8ÛºšÏ˃ cî%›O–N³->ÕŽÝ QÊ)¼…((xµC‡  +dít‡ð°›ÎJsì0 o°›©I±.Ÿ{ž±k(pQ²$%ÅV¸üÜüŒ]C€BBt.֨ϱÖ0àãoJƒÃÃ­ŠŠ¿ïêé|=æãŠ,OØJ?åô|Çèi7 »ôkmJ®ñ‚T…ºCZÌÂoåX–aÈBÝ!@€,¼·;üîÛ 2±\Àˆ¹äj†fë^«+j©ÝäòAV×,§?z¼Køùì>½Õßzœ˜'¹ú‡ /FþúÓù™%^dápù¹ç3¨ÿ+õŠ©÷‚“19~ Ï.jýý¶ø£fW¿!œ%çóôÂ9·»hù8«A»ŒÕ¿þrùL û{9ú©3áò¹ÿã&þ¥ —R·½W{5lR­Iâ['Ó‡Šyzc©Ï²p÷)%ýšßo[= øØ¯?}¨˜ßbÞIáb+ d…¾­ØmÏ<½wÌû³Â¿þ7êNÎNÃIâ­áÝ?´ÍúÕ_üç²ùÓ r3;K‘…¯ý¡UüÍwûf‡pùç²àbcòä @·o7Ùs¯Œ›ãh¼­½š'§‹Øws`“Q`êV¿h âˆÉÕÛǨØúÎݙm]Þ+|pÅÖ!ãÓ[ö¾«O)ü8áš%yæ×_}¨nï K¸äsÀû H:øÜ@wâÄ!вÀÒ)Tÿö¶ÿ¨6ÂÜIœ›IEND®B`‚snd-16.1/pix/fmeq28.png0000644000076400007640000000277211147553267012766 0ustar bilbil‰PNG  IHDR€sgæúN3PLTEÿÿÿààà€€€   ðððpppPPP000ÐÐа°°```ÀÀÀ@@@ ÍçðØ pHYs  šœtIME×,ø6«ZIDAThÞíšÙ’¬ †70úþO{Ø"K«,ötש2"3:ˆ˜oþtÝ ãb?ÝwŒPeŸOý/d‘$i[Œ½8ž.úŒ³Áwr3¶…-•râõôžž˜Øj×€æïæ ¥LÍÄZïÀ8áÙ`'ܳ£rÚ—^´­z1øŒ‹ÍÇ.r —¹{i7û–˜ó•Õ: _û ±Sn ԂϾëmJc°µoеp|:ã€k[0!Àáʳ 謮mtÀ„,´Þ&`­°L5Ë?`˜pJÀÅ~ D¸“z0¶Ý¬_€­fzµÝô~HFNÏgS¸q´‹zkÈV3ý@º©÷[P·ÙÓáecm9 ³ÏaÃÜÃÞrµwöuŸ$ØÓ»Çê=  a' }4JÖ}ÍÀ¼XÁð¥ûQns¿0ÿ)ùÍó{ì±ÿ >a pJƒY.àR²^][Oéû7¹@§ÂÓXÂúãI¸¬ ý›\0LÕs\0¨éª?Âqÿ&/f(âµNÔ;€ýÛ\ ~¶qÎÞt L ÝgÔôosš|(á•ÌÕ\ ó[ì7„‘Œô¬ˆ Ì\á53‰ûU!ÀYGFïæb9Lì¨ÛͨUÔ`¿ž ô⯀kNTì ‘ç0ÏšÁµû-\@ VÛ ¦A£€ ô¤©MÈ¢™šú½ßÂvôææqV¶•p£ WuToŽ~ì·p]öZ.àŽ¸Û x3aVýg\@^jÖ.x¸à±Ç{ÀdÄ‹b0Ù… Ê>!XìxQ &(TôêrL<^”‚‰*¸ÉÆ>!X ^‚ `Xe­`âð¢LðßôÂ:Ð$Xp¸`Ç‹B0Ùu=xþj,D> ¶xQ&»b Ú‹ÅdÄÖ…` ÕU‚Ig_%³æ^‚I$TðWÍèÁbbnÄ^”‚ zhb³ƒ WC…¥`‚B•@ûʪÙP ˜ìxQ &(ThÔ° å ·Ðß :|0yÀä±Ç~·ۿÈý£ç_då\P²c¹”R†Şݻ6_Èä®\ÇU™Îì&E ¹Ü?ú„f÷{9R– ðÊAOð ;>ðN̹Ü?JHBË|9RŽ ðJ=h>Y‡:ÈäþÑOC³û )ÃQá’^Š)Èý£ Ìmƒbœ „e;ú_¥b& )9 « ( Ü‘@qà@† BzÓ—.Q< § ¨8ð Wdg@Ø|ZÇÌÈNBÀjR¹JÝ1(0»³ük‚+ÄBŽ+©öÜßhú™z&Íðc³{Ÿåg¸ ¸r5±o‚ðí}ó¹¿~`ä@,P`vïË‘r…LþJ+“è·†¼íx^”Ð39 ˜Ýûr¤ø+­|•°ÂYîo5±è¿koE’å2á•"énVè…Nþí1့Qþ =Ì#x{u¾Âô|ʾÄäÖWþ±Çûø œ’@žê¹ Š x š Ò‚¦+(àz.H š®H €ê¹ -hº hä‚´ é„ x ‘ ’‚¦ë¸ä.H š0ÞQ$’#hâ‚÷‚¦ <)D‘Hy  Ò‚¦¸<)D$×}–½{÷«Ã–ÿ»ŸÙ4eee=zL­Ãòå«éÒ¥uêÔº­e_¾œLAA! ÔàèÑcøù5F¯·%&æ QQ1¼øbï;¶S"""‰ˆ8@Æ èܹC•_£´´”åËWó Ïâêê"ïtñÀÙ½{;w¼îð_mܸ™ÌÌL è‹N§«þêúõ¡¸¹¹Ò°a6l@ݺµÕqÞÞ^Ô¨áa6½··¿ÿ~œ¤¤ËÕ²1Š‹KÕe_ ·«—°rå:uØ××;;½Ù4¿þº›WiÙ11gØ¿ÿ:²‰ììlœœœ¨[÷ÎÄKIIåÇ·¨ë}ô¨ù—Úµ|ñEPÅkiIÆ °¶¶–O–x -Y²â†ÃU·nm~þy;EEÅw¦… ЮÝ#xyyþ¥õËÊ•ëèС-õë×SË›6m‚O=³ióó øòË™êðÿû¦R•kÕª9:µ3+KMMgöì<óÌ“jùÏ?‡³oß!\\œqssà§Ÿ¶±té t:›7‡1jÔP<<Ünº\ŸzìÚµ€ŒŒL¬¬t888`0˜7o1îøû·V§?pà›7oÀϯýû¿Ì¾}©_ß/¯j(_iÝßHqq €Ú*=GNNÛ·ïÄÍÍ…Ÿ<øuj×~ˆ)Sf°zu……Exzz0rä`Ö¬Ù@tô6¬¯~É2eÊ uYŸ~úŠŠŠ9pà0§NÅ‘‘I«VÍù׿ž (hYY9¼ùæ¹Dü#þ"YYÙèt:ìQ…!CùÏ>†¨!µfMï¾[^¿]»ö²mÛ/DEÆÞÞžœœ4¨Ï¦M[+¨×³sçL&Ç¿À”)3˜3gö#""’!CÑéþÜO=Õ3gΑ’’¦~!~øáçfûbܸOxÿýQŒûß}·77W¶nÝÎÞ½8|øw:wîHÍš^„†nQ—-ÄßÑh 0p¸:œ››GQQ«V­W?{öìgëÖí<ýtk¾Æ¬Yó5j(C†’‘‘É”)3øàƒ1·¨3g~Q¡…jccS!ɯçâÅD>þxâ-m ÆVh¡æååS«–7#GæÃ?ÀÙÙIm™^q¥ÌÎÎN§²Þzk ‹GNN.½{`aaA­ZÞXYY©Ó)ŠÂÖ­ÛÉÊ*ïHL¼ÄÛoQÇÏ™³ˆ/¾ø´ZÞ #F ⡇jªA~¥›E¯×WX?77WœÍ¿@rrrͦ»Òú|æ™§hÕªùûÖš’’Rºw‚o¾Y¬þ\ùâïB£ÑT''G‚‚æ²xñ2t: ~Íë¯÷W_ï±ÇÚS£†;«V­ã‡ÖPXXDß¾/©ïë¯ç³víÞxãµJotKKK:uj‡§§çU!c`ðàQœ=G`àpfÍú½^OË–ÍÔ:µiÓŠQ£†Ð§Ï‹,[¶’#±sçnž}ö©J-×Ë«nn®êë5nÜýëy¶mû…¬¬µüÊúŒ;’ÀÀḺº¨á?{ö‚?ú•2xðëôèñ£F 1Ûï¿?F‹»ûŸýÊØÚÚâáá·þ¼¼|þõ¯ä“(þV®œ¿¸zØÆÆ†6mZ¨ŸƒÖ­[2zôP>ýt2ÇŸ`äȱ¼ûîHZ·n­­ ›7ocÚ´¯Ñëm7îÆ}¨çÏG*r²áþ÷ÑG6ìMõ_qçUåÈlçÎ=×o¡²wïkŽëÚµó-_§UŠ¢þë5ǵk÷NNŽwt#îÚµâ⊗N´lÙ¬Bru;r$‚Ì̬kôYÊ%PBTRFF&G»æ‘gOTúuš7÷«Òr¯¨&“‘ŒŒÌëŒSîʹƒÁpÇ—CAAA…ò’’Ò;¾ìÜܼk®û+¯¼ˆ»»«|R„¨„²2Ã5?GZmÕNÝìü‰ò !İsçù-¿BTmzz©©i²%„â6¤§g`‘’«&ÙBq»-TNÇ´Zz#bww7jÔðÄÖÖ ­Vƒ»»;5c•*…‹‹ 5kÞüf «W¯&--AƒÉïÝ…÷Ì-!rqqÅ`(ÅÅÅ™¢"ó>VN‡­­µ®F£±Ê¯ŸÀ Aƒˆ‹‹»át&“‰ï¾û''':tèÀìÙ³ÉÍÍ•½*„øûª››+ùùå÷ɬYÓ‹üü?o$âää„¥eùËÚÛÛaaQµ×ŽeùòåÞtÚ‚‚Ž9ÂÓO?¿¿? 4`çβW…÷Ç!^jé9éfe¥%êÿÔ0…òGfØÙéQN‡½½# Ôñññ têTù Õ«W÷Þ{ï¿ÿ¾ZVpèС”””˜•%%%qùòeNœ8!ï!Ä T[ ±h‰É“¨S±´hÙ£±ËW²ØÙé1™þ<Œ·°°ÀÖÖEQ0$%%™Ý6ëê»ÁWFußguþüùÊV®\ɸqãdï !î\ jÐÒÈÓ—R/ Kx¤A³ëP±µÕsêTÅçÄççáëëC›6þ””ü9OJJjµVxõêÕ4hЬ¬¬pvv&-- âââèÙ³§ìU!Ä=Q¥>Ô¢¢"²³³qrr®ðçë[€’’"²³ÓÕ¿cÇ"ªT¡èèh å믿&00ììluü¦M›8y²<Э­­yûí·™6mТE Ù«Bˆ{ßB½[[[ZµjMvvÅGtäåPVVrÛòóó#88øºã—/_n6ìááÁÔ©SeO !þ^ ““MbbB…ò”” ||êÊBÈ!¿B T!„@B T!„¨Bq§h”ݲe k×®¸éMW„Bõä§§Bˆû$P‹‹KÈÍÍ«P~õsU„Bõ¦aZDlì.]º\a\ýúõek !$P+«´´EQðð¨x)GGÙšBˆšœåB T!„@B T!„¨B!*„Ì/¥8 >búøñã²ç…¨·ªQ£F¸¸¸åOVݽ{·ì}!„ê­puuÅÕÕ€£GÊžBT;éCB T!„@B T!„¨B!*„¨B!*„âV<0ö_¼x‘óçÏ#{^!z«²³³9{ö,)))²ç…¨·ªE‹´hÑ6oÞ,{_Q­¤U!$P…BU!$P…BH  !„ªBH  !„ªBˆ[ñÀ\د( &“ @ýW!$PoÁÖ­[Y¿~=çΓ=/„@½U½zõ¢W¯^¬\¹’qãÆÉÞBT+éCB T!„@B T!„¨B!*ÄÝ”À¡C‡ÌÊâãã9zô¨YÙºuë*Ì[™²Í›7³|ùr³²ÐÐPJKKÍÊ6n܈Ñh4+[¿~=Š¢¨ÃqqqDDD˜MËñãÇÍÊNŸ>ÍÉ“'ÍÊ>ÿüs¢¢¢ªeÖ®]«^’X•ù¢££ùßÿþgVvòäÉ (ŠŒŒ$66Ö¬,""¢Âå&L >>^6lذÁlš²²2BCCÍÊV¬XÁO?ýtÓúK  ñ‡¼¼<.\¸`Vvüøq–.]jVvðàAvíÚeöã—^z‰ÈÈHuøìÙ³Œ3Æ,DbccY¸p!ÉÉÉf¡¦>r'//o¿ýÖl¾ÜÜ\/^̈#Ô²ììl-ZıcÇÌê5pà@³@ýé§ŸèÑ£‡Yý7mÚÄš5kÌÊÞxã vïÞ­ÇÄÄ0uêT³ŠŽŽfðàÁüòË/jYTT .$==]-{ï½÷Ø´i“:œ™™ÉÂ… Ù²e‹Z–‘‘ÁÂ… Íû—_~aÖ¬YDGG›m³3fTøÒxî¹çÌÊÖ¬YS!{öìi¶?Oœ8Á¦M›HHH0Û¿‹-";;[-1bÛ¶mS‡SSSÙ½{7Û·oWËRRR˜3g«W¯–@ÿ\Š¢P\\l*×*KLLdÀ€¤§§«­¼˜˜^|ñEòóóÕ°œ3góçϧ¨¨“É„Á``æÌ™ÌŸ?Ÿ‚‚L&6lÀÒÒ’˜˜uºï¿ÿžÄÄDrrr(++ 88˜;wNYYŠ¢••Edd$;vì ¬¬Œ¸¸86lØ@«V­Ø¿?ƒØØX6mÚDff&%%%j]·lÙBPPúú³fÍ¢o߾̛7O.((ˆœœÂÂÂÔèŒ3˜9s&Û·o'::ƒÁ@AA³gÏfÛ¶mœ?ž… Ò¨Q#vìØA¿~ýHHH`Þ¼yäææ’œœÌwß}‡¢(Ìž=›;vÆŠ+ˆ‰‰aãÆ4lØ~ýú±nÝ:"##Ù¾};F£‘¹sçb0øý÷ß gÖ¬Y|óÍ7 òóó)--eÖ¬YÌ›7€ùóçÓ¯_?úõëÇøñã˜>}:ÙÙÙlذA}¨æôéÓ™>}:7näâÅ‹,\¸&Mš°sçNV¯^MZZAAA<õÔSüðì]»EQ ",,Œ°°0Ö¯_Ñh$33“ððp¶oßÎæÍ›9pà§OŸÆÅÅ…~ýú±uëVöîÝËÉ“'y饗ªüÕÊÇTÜik×®¥I“&ê3½®´:233yë­·ÐjµDDDpðàALaa¡Ù¡ñСC9þ<¾¾¾Lž<777Lll,7æË/¿ÄÕÕ•·Þz‹7RXXˆ¯¿þ:³gÏfÈ!DDD0bÄÜÜÜ Â`0àïïÏСCñôôÄÕÕ•sçÎáêêÊóÏ?Ï„ 8uê999ìÙ³½^ϯ¿þªÖéÍ7ßdÉ’%|ûí·DDD°páBÈâÅ‹ùì³Ï˜1c]»veÑ¢Eìß¿Ÿ7ß|€Ï>ûŒÏ>ûŒwß}—þýû‚‡‡aaaüúë¯téÒ…¸¸8çàÁƒœ;wŽF±jÕ*öîݫ֎=víÚE=0ÁsÏ=GVVvvv>|XmAÿþûïœ:u µתU+¦L™ÂÉ“'©S§§NâÝwßeÒ¤IDEEL\\ü1]»våäÉ“<ñÄ,[¶ŒeË–‘Í£>J×®]‰ŠŠ",,ŒÜÜ\‚‚‚hÖ¬{öìÁÆÆ†ÈÈH<ÈÏ?ÿLË–-ÉÈÈP·kzz:/¾ø">ú(¤Aƒ,]º”¯¾ú ???öîÝËñãÇñóóãÑGEQ¦OŸŽ££#‡¢C‡XZZòÁ0~üxâââæÇ¤C‡Lž<WWWúôéÃÎ;Ù¹s']»våÌ™3ÔªU‹ŒŒ ÆÏ´iÓ$P¯6tèPõýê¾§¬¬,%íªÉåË—©Y³¦YÙSO=Åwß}ÇsÏ=Ǹqã°³³ã©§žbãÆ$''STTDVV]»veذa¼öÚk|ûí·äææÒ¶m[>þøc>øà¾ýö[Ξ=Kbb"ƒfóæÍdff’‘‘ATTÆ cÆ têÔ‰iÓ¦J=¸xñ"ëׯgøðá(ŠÂçŸΆ HMM¥N:ÄÅÅÑ£G,X€Á`àwÞ¡~ýúôìÙ“¢¢"BBBðööÆd2‘••…··7 ¤§§óÅ_0eÊöîÝËþýûÙºu+o¼ñcÆŒaÆŒj_ÞÀÉÊÊ"))‰Ó§Oãéé‰N§S[KçÏŸgìØ±„„„ÇÆùñÇyçwX¹r%,X°€?üP=ŒNOOG¯×Ó¤I222¨]»6'N$==V­Z…ŸŸPþ€J²³³Ù²e íÛ·§oß¾dddЮ];æÏŸOnn.|ñÅÔ¨Qƒ}ûö±{÷nÞxã ¡òÑGQ»vm"##¹|ù2ÞÞÞêBZZ 8°ÂçkàÀ„‡‡§bôÑG$$$ð /°fͺv튵µ5;vìÀd21~üx5p÷ìÙCË–-xúé§ÑétŒ5Šùóç0hÐ Nœ8Aqq1ñññP§NqssÀÊÊŠ¾}û’͇~ȳÏ>‹½½=ƒ ¢cÇŽ>|˜¢¢"þûßÿ¢×ë«ü9°ÈÌŒW•´Z,-5”–°ë·Ctëþ8CÑU}BSÑét×|¡‡ª…V«åé§Ÿ$;;ýª¾Ÿ£¼òÊËXZÑëݰ¶¶¿çþ+?=MLL”$¬&[¶l! À¬lÆ 8::Ò½{wΜ9ÃÆiÛ¶-]»vUoCCCiß¾=]ºt`ùòå¼ýöÛlÚ´‰Ç{ €W^y…_~ù…M›6ѱcGÊÊÊhÛ¶­zèØ¾}{Ö¯_ϤI“pss#<<\íÿ ¡uëÖê œçŸžÐÐPyä>LLL ¯¾ú*<ÿüóŒ3†+V0lØ0Z·nMpp0¾¾¾,[¶Œ×_€ .pâÄ ‚ƒƒ)**bË–-\ºt‰Ã‡³téRz÷îÍÚµk™2e 7nä“O>! €ž={òÌ3Ï••E»víÔ®‡=z°bÅ ÂÂÂ8{ö,“&M"??Ÿ àîîNqq1K—.eÛ¶m,X°///<<< aÚ´i\¸pyóæñä“O2räH¢££ùᇰ²²bذa8;;̾}û¨[·.aaaìß¿ŸÓ§Oóî»ïpäÈöïßOaa!ÿùÏÔ–lxx8;vì oß¾lÞ¼™O>ù„•+W2eÊèÓ§­[·&33Sݯß}÷—/_&55•#GŽpøða-ZDbb"³gÏf̘1lذyóæñóÏ?sæÌ.\¸€‡‡‹/æÐ¡CŒ1‚¨¨(úöíË‹/¾ˆ§§'ÿýïÉÈÈ`âĉ°dÉbbbpvv&22’•+WræÌ‚‚‚())áСC>|˜sçΉ‡‡£G&<<œÍ›7coo··7C† !,,ŒŽ=Jhhh…¾Ük÷ͧ`0sU§r¼rå/77YÉÏOS23ã•Ö(¹¹)ÊÕãÇŒ®Œ7úš_=M™;w†rîÜ)åèÑßÔ¿yó‚”ôô‹Jff¼R\œ§ÜV¬X¡<ôÐCЏ?)iiiÊÒÓÓÍÊÖ¬Y£ 4H...Vš5k¦ôë×O-»xñ¢( PË>üðCPöîÝ«–õêÕK”˜˜uy]ºtQåìÙ³Š¢(Jxx¸âêêªÊ… EQ”E‹)€2aÂÅh4*Š¢(óæÍS•©S§*Š¢(&“I™4i’(3fÌPEQrss???PæÌ™£(Š¢¤¤¤(€âïï¯*Š¢(QQQ  tîÜY­ëñãÇ@éÚµ«ZöØc)€­–µk×N”ÔÔTEQ¥  @iÙ²¥(™™™Š¢(ʆ PòòÊ?Ÿ_~ù¥(S§NUL&“¢(Š2iÒ$ÅÑÑQY¼x±Z׆ *€²lÙ2EQåÒ¥KJƒ @Y±b…¢(Š­J÷îÝ•ââbEQeÏž=н½½ò /¨u}íµ×@y饗Բ¦M›*€2yòdµìÊ2ËÊÊÔϲ­­­baa¡NóÑG©ÛñŠ>ø@”Õ«W«eï½÷ž(!!!Š¢(ÊÙ³g•zõê)€Z©÷jnn²YFÊI)qß±±±ÁÝݽBٕö+^~ùe.\¨[[[óã?2gεÌÓÓ“Õ«W3kÖ,µìÝwßE¯×ãì쬖 >½^………º<t:––å“=zðÈ#ðÊ+¯¨õëÖ­7ÆÞÞ^N§ÓQXX¨ÍYXXàââ‚V«E«-ïespp`ذa4hЀ§žz GGG^}õUt:¶¶¶899¡Óé°²²RëêììŒN§ÃÚÚZ-6l˜úWo«éõzììì°²²R×ó…^ÀÇLJÀÀ@lllÔüC=„ƒƒƒ:Ý•uºRÿ5jðꫯ¢ÑhÔ²š5kÒ§OZ¶l©Y<ôÐC<ÿüóX[[«õqvv¦¤¤Äìhw̘1ê~¸zŸ\=îJÙÕÛ¢ÿþxyy™•õéÓ777³ùú÷ïo¶¿¯þkµZ4 ¾¾¾ôîÝ›víÚáïïKï]9)%þQ|}}͆u:¯¼òŠY™««+feÏ>ûl…²åË—³gÏ|||̺‹<¨ö¯Õ¯_ŸÁƒÓ¬Y3uš·Þz kkk `xöööfeo¿ý6ÎÎÎêIþýï›]GêííMhh¨Ù¼N:lذ:¨e={ödøðáØÙÙ©e«W¯æóÏ?WƒòÊ ÂÓ§O›…KŸ>}èÔ©“Œ7fÈ!4oÞ\æý÷ßÇËËˬþmÛ¶eúôéê‰5€víÚáååE:uÔ/Ž×_K—.©Ó4kÖŒ~ø§Ÿ~Z-óðð`øðátìØQ-{æ™gˆŠŠR wïÞ<úè£j]^{í5³î¦æÍ›3tèP5j¤–µhÑ‚¡C‡ªÛ`òäÉøùùÑ»woµ¬sçΤ¦¦âíí}Kï?éCBˆ«œ?ÞìK´*}¨rÈ/„W©l˜^‹ªBT T!„@B T!„øGz`.›Ú±c›7o¨p{0!„@­‚Ž;Òºuk üa½g¤BH V’zóÕ? !Du‘>T!„@B T!„@B!*„¨B!*„¨B!nÅsaÿéÓ§Õg—:tHö¼Bõ–WT«UŸis½§!„j%øúúªÏÊÍÍeÕªU²÷…ÕJúP…BU!$P…BU!„ªBH  !„ªBH  !„¸Ì…ýùùùäåå-{^!z«~ÿýw¶nÝ À©S§dÏ !$PoU—.]èÒ¥ +W®äèÑ£²÷…ÕJúP…BU!$P…BU!„ªBH  !„ªBH  !„@Bˆ{èù¥Ô–-[X»v-qqq²ç…¨·* €€€ ü§§ãÆ“½/„C~!„@B T!„¨Bq—T餔­­-mÚø_sœ^¯'>þ<Š¢È–BH Þˆ¢@ff¹¹!’Ÿ_Œ‡‡+'Ož"::Ê,„…Bõ/Š‹‹0h4ŒF£Z~éÒeêÖ­XàççGãÆÔq¥¥e²•…„*÷¡ÆÇŸÇÙÙE.))EQ,,,P…ÜÜl rÔ¿˜˜¨[ªØÑ£GIHH¨Ô´ß|ó Ÿ|ò ÅÅŲG…Ÿ@HIIE§³ ¨¨­¶¼¡k2™ÈÏ/ÀÒR@jjÚ-UêäÉ“Œ5Š‹/Þp:£ÑÈܹsñ÷÷gРA‘––&{Uqÿòÿyè_ŒMy æç`mm­ŽËÌL§Fœ;w–””<==«ôÚÑÑÑlÛ¶ÀÀÀ›N[XXÈéÓ§1bM›6eÿþýôîÝ[Æ`0T˜Ïd2]wœBXZZbiYµ6ç-jQQ!žžžDEÃÎN_aü•Ã|WW—¾Îš5kÈÍ6/ º!IDATÍU‡ýýýiÓ¦ ~~~,^¼¸Z6Ê;ï¼CII‰YÙ¹sçHJJB§ÓÉ»FqMcÇŽeÚ´iw.Pzț֭V‡ëÕ«‡•UyKÕÚÚš¸¸s´jÕÆl KàÚ—Qùúúšõ{º»»WûF™3gN…²•+WÒ»woÚ¶m[é×9tè¹¹¹ôèÑ£Òóœ>}š“'OòÒK/U©ÎK–,¡W¯^Ô¬Y³Òó¬_¿žf͚ѤI“Jϳ}ûvh×®]•ê7yòd&L˜P¥y¾þúkÞzë-ììì*=ÏÒ¥KyòÉ'ñöö¾ãõ»[óÜïõËÊÊbÕªU >¼Òó˜L&¾üòKÆÇëwâÄ âããyî¹ç*=OBB»víâµ×^£jy÷Ð=äãW¨Y3ßëmòk–úûûW¹Âß|ó Í›7§sçÎX[[ãææÆ¥K—ðöö&::ºÒáÕ¬Y3:uêTéå‘‘Q¥ylmm),,¬Ò}úÜ•eÉoù…¢šXdfÆ+öMØ`i©¡´´€]¿¢[÷Ç1Šª±é통µý=_éôôtt:NNNwt9äååáååuÇ×)99‡*ô¹UçÎÃ××÷Ž/'11³Ëòþîët7—õO\§¼¼<ŠŠŠ¨Q£Æ} yy) Å·¨–hµ6×}q£±“Éxßjhh(û÷ïçõ×_§qãÆ7œö÷ßgíÚµôèуîÝ»ËW­ÿ`)))Ìœ9???xÓé###±±±¡Q£F7 Ô*ò[XX`0Wø;þ/&šM¿|ùFŽˬYó),,¼«lÓ¦MFFÍÏ?ÿÌ™3g®;íÉ“'Ù·o£GæòåËìܹSÞqBüC%$$°lÙ2FMíÚµY¶lÙ §ŠŠb̘1•zÝ-ô¡*(Š©ÂŸÁP†ÑhþË£3gÎWXZj¸|9å®n´þïÿþ///ú÷ïÏ’%K®;íŒ3>|8^^^¼öÚk7ÝÀâŸ!..ް°0³²o¿ýV6Ì?ÜO?ýD·nÝðòò¢k×®7l@?žÍ›7óæ›oVêµïÊI©‘#áëë#{RÜWÖ­[Gpp0áááDDDàêê @ll,ßÿ=GUÍ7þ|V¬X!îâããÃûï¿F£¹wšp‘‘#ÇràÀaÆÿLöЏ/Õ«WÚµk«×(zyy±fÍ ü—q.\ 44”©S§2qâDlllÈÌÌ”V¬¸»Z§NmæÌùŠöíÛòÅŸÞ“ëØ±#ûöí`Ë–-ôêÕKwìØ1³kW_~ùeÖ­[@xx8={ö”wÆ ~ýúÔ«W P³fMllþ<éZ«V-L&IIIÄÅÅ‘ššJQQ~~~²ñþÆ:tè fCTTM›65ÿÉ'Ÿ}ÿêý 00S§NHÆ yüñÇÕqÙÙÙf'©ž~úi $--í®],î-'''òòòX°`'Nœàܹs$&&ª÷á½ú¬nË–-iÖ¬>>>r‹È¿¹6mÚгgOÙ¼y3£F2M^^PÞ‡È?þÈ÷ßO`` ÉÉÉ×}í*]6ei©!>>‰øøs^¨  æÍ›R»öŸ7ˆˆˆ¤M›–êðýrª¾G#())¡}ûöÄÄÄpâÄ üýýÑjµX[[ãééÉáÇiÛ¶-ëÖ­C¯× N·yêí’@Bü“U~z*„Õä®Þ¥¬¬“IÚ'„øg0™ ÷2P‹)+“é !¤…Z­¢£O}†?~Íz 4 &“©ÊÏsùë/µ„âVi4ZŒF#Ÿ8bÁ÷¢nÝÚ÷O ¦§g¢×Ûš]÷çààˆ“ÉKKoïZ7¼ÙÊÕRRÒHNNDQy'!n‹N§£M›¶ÄÇŸ¥  ‚‚|uœ££µk×åZO"¹/n0mkkK^€ Ø»÷þþþäçgSRR¹.‚ÈÈ\\œïÚ]á…ÿl%%Eèõ6ØØ”?j)55•ââ¢ûóÀÆÆOOOœ(..¿•40…÷ EQþè–4Q§Nmòòò)--½îô÷ô²)ggL&ƒ¦Bq?·XKJŠHLLªžª¢(”•]ÿ²'­V[¥I/&`ooGii)õëדÃu!Ä}É`0pöìyt:-îînÕ¨ÙÙ9lßu —ŠÏ‹Ø·•aCqv®üc‚u:-X[[y OOûæÑBQ\\LVVII—ðð(ÚònåWå&¡»w#j7éðg3¸¸ˆAŸâ 3áææŽÑXZé×ÒëíÔÇ%ÛÙÙSVVFZZƒ ++bbÎ’‘‘Q©×***¡vmG4ùñ—âöhµZ’“SÉÎÎÃÂÂ’zõê©ãlll«/PæM@ÏçúÐЯ ƒ>eù‚iMÊÃ41ñ‰‰I´o߀ß~ÛCÓ¦MÔ„ÈÏÏ'>þÒuÀ¶sçî*×+*ꌼ„wœFcAãÆ¾·¨á?­fåâùlX±€Ïö!ü§ÕLùf-vŽ@:iiéœ:M:µÑjµDDœÀÛÛÛ,P‹ŠŠIN¾„••NýFppp¤nÝzÄÅ#77çÚAmÚøß•'–^‘——GdäqÅ$Ÿ!®¡aÃF899sþ|™™ê5î®®n×횬r ö|¶»š,œþ ë—C£¦­éð/,¨ø+¥C‡Žboý°´´ÄÚÚW¬­­Ðh,‰Š:IZZ:®®.Ôγ²²âܹ3wí‡ Ñѧquu©ô£„xÐèt:²²ÒqvvÂÁÁžüü|rssÑjµ×ýÜÜÒ!ÿ¿‡ý''&BûÇŸºît.\ÄÚÚêºã½½½qss#++£Òð !ÄÝtåWRz½-µjÕæÒ¥K׶ʪÓ(ØêLôy-¥4—NÝžÁVgÂJóg˪I“F8÷,PŸ}ö)ÙcÑ´©l!þÆþ¨&ÅâCq;¹FQñÀ)Ö¸¤ÍÀ ˜w?–å”ÒÌÖ§òj0üù³Ñ67Ãh,‘­+„x ˜Pˆ6œ!Ãhþ³÷ø½çiÖcÌ͵¬Ì@BB’lI!ÄÏÒIžËF#çÎ]¸æ!!ÚµkË'@ˆjeÑXvÍûvÄÆÆag§ÇÛÛëÕ«ôšçKΜ9‹££^^7ï¶ÌÊÊfÑ¢eÄÇ_àÛoçÜÙ@MIIaÆŒ¤¤¤Ð£G^}õU ™1c‘‘‘èt:ÆO5˜?¾¶-Z´`èС$''óÅ_¨7;yã7èܹó5+‘ššÊÌ™3¹|ù2]»veàÀ¼óÎ;øøøpìØ14 &LÀËË‹ ¨u°³³£S§Nòþ⋎>M^^ù½C}}}pss%..žúõë¨ÿ/,,"77—¤¤ËF<=kP·ny£èÈ‘L&ÓYÒ [[›ÛªSjj:œ?@ƒõquuÁÃÃ?~Ÿ‘#ß7›þÂ…‹¤¤¤àååI:µˆO NZXZZréR2®®ÎØØØTþ?44”Þ½{Lpp0Û·o ¤¤„îÝ»ÌW_}ÅÌ™3‰E«ÕªÓ*ŠB\\Ó§Oç믿VË—,YrÝ•þùçŸyòÉ'ÕiëÖ­«¶>üq‚ƒƒ™3g_}õñññ ‚ƒƒ™;w.ÉÉÉòNâ;xð¿þº›˜˜Xbbb™?¿üó4WæÊÿãã8p(‘‘'‰‰‰eíÚ\ºt™Mœ8¥¾ÆÒ¥+n»^?ÿÎ|ª¾æ‚Á7 à4uÚÕ«CHNNaîÜE”””ÿŠtÍš«éÓ...´lÙ²ÒÓ2­¶|7º)ë€øòË/Y¶l™ÚÊ}üñÇqrr¢uëÖ×O§ÓѱcGy7 q Ft:Ú¢ìßÿåNÿÜs½ | €o¾YBff6‡å£ÞW›d4«¥nƒý[}`è_[¤×Ê”+ëpæÌ9²³«öl»kª999$&&¨ÍÛ¤¤$~øá{ì1 pvvÆÊÊ ƒÁ Nk4–oXÆŒ£ÎëåõgKZZýû÷ç»ï¾£fÍšìß¿ŸÇ{ŒÊoX=qâÄ®°Éd"11‘’’V¬X!‡üBÜcmÚ´D«ÕR\\À’%ËùüóÕñÅÅ%©Ã•yÜ{^^>ÎÎN·]·+Ý7sþü~ûm­[·Àd2a2™ºÉd"77¯êÚ¿-Zľ}û>|8C‡E¯×³`Á¬­­ùì³ÏþhÂdz`Á:uêDãÆ™8q"ÿûßÿ(++¿vôèѸ»—?õÔÚÚšöíÛ«îÔ©K–,!,,L]Nù·ØsVT«¥W¯^4lØÖ­[«u˜9s&5kÖ”w´÷Plì9víÚ«Þ'Ôѱü>Ç>ú0_}5“ÉD|| _£[·.jW€‡‡ÿþwÿÛ®[hèŽ/?ÇããSÞ˜žžÁÒ¥+9y2ŠÙ³òöÛƒÑëm)..áðá23³èÞý æÎ]ÀÑ£ÇnØú¶ÈÌŒWþ -¹°_¥¥†³gãIL¬‚eeZµj»»«YùåËÉ—ü†îØÛÛskkkôz[>ÿ|sæL£´´Œ¢¢"œœÊÆ™››‹ VVV\¸pQ=)U«–w…Í[Zjˆ=ORÒÅ õ*--ãá‡[™=‰bÙ²U4lXŸš5ËkÔðÀÎNOiiII—þxMKõ¤XFF&¹¹yh4–899akkKRÒ%EA«ÕʳÏ>Mƒõ+ßBB<ØL&#õëצ~ýÊ_’x%´®ËŽ¿дic¬¬tXYý”ŽŽþ>þJ°Ý¨^¾¾uðõ­Sézét:µez…•UÅ277WÜÜÌ¿(ÒÒÒY¹r-&“ oïšÔ¨áQ¹ªF£ÃÆÆéoû&(,̸kÏdBT6œË[œ×}tÈRž·ý¨ŸÊ®ƒY Õh,£  ]ÞBˆjì>°¼gË®®¯ì:XÊîBˆjúòM „¨Bq_ù=:ëC‡ZèIEND®B`‚snd-16.1/pix/interp1.png0000644000076400007640000014671011147553267013247 0ustar bilbil‰PNG  IHDR ƒÓgtsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ  ²‘³ IDATxÚìÝwX×û6ð›Þ{fAbIBÔh,±„$jì&ÑD£&bdícE4KŒ‰’XbA Á‰Q£;*ˆ(¢H‘*½·}ÿðë¾òc—‘r®Ë ÙsΜÙgf‡yvfÎQ‰D"5E†€ˆˆˆˆˆ˜€QëL@Ž;†ŒŒŒZë”––bÍš5ðôôDYY#KDDDDDuO@Nž<‰mÛ¶!??¿Öz^^^˜={6¦OŸŽM›61²DDDDDTƒrm…ÙÙÙ¨ªªÂ°aÃ^º ¬¬,ÒÓÓ«•;w 5Ú899¡GÜ MDJJ Nž<Ù$×­sçÎxûí·¹‘ˆˆˆˆZrb``€áÇ#66¶^ØÚÚB__¿Úkk×®Åýû÷™€4 ªª*œ?^jyff&`ii)±÷ ªU¯^½pùòe©åĬY³0|øðeEEE:t(FÍ@yDFFŠö½}û6Ú´iÓ$ƒràÀc×®]ÜC蕚0a‚Ôѽ:„üÆ ƒ¦¦&ƒEDDDL@êªwïÞèÝ»7Ô:Ôì«– {{{Lš4©ÆÁÀ³!†ÝÜܸwÐkõá‡âĉððð8`Avv6´µµ±uëV‹ˆˆˆšûzPPBBB¤>Þ¶m[ÌŸ?JJJÜ ¨YJHHÀ´iÓàää$±üêիؼy3\\\,"""j2šíCèÅÅÅHKK“Z~óæMlÚ´ ºººÜÊÔ"ÙÚÚâÌ™3RË7nÜoooüðÃRëXZZBEE…Á$"""& /sáÂLž<K—.•XÞ¿&Ôª7ªªª–X¾hÑ"DFFJ͈ˆˆ¨U% ÙÙÙØ³gÔr///üþûï1b·"‘¶¶¶pww—Z®¡¡Q£FaæÌ™Ëûôé#~f‹ˆˆˆ¨¡4Ùg@bbbàä䄘˜©Ë033ã\DrÊÏÏÇÓ§O%–íØ±‰‰‰øý÷ßùœ5ßäâÅ‹ œ9s½{÷Æœ9s$Öõññ±±16mÚÄ­DÔÈÒÓÓaff†Ë—/C]]]b0XDDDÔtÍœ9{÷îÅÆ¡££#±Ž‹‹ :uêÄ­DÔÈJJJpðàA©åB¡sæÌÁôéÓ,"""ª“×ú ˆ@ z„ˆ^uuuL:Ujy·nÝп$''K­3uêTØØØ0˜DDD­\DDŽ9‚ñãÇ£sçÎÍw,"z}ÞxãZ“/¿ü˜?>ƒEDDħOŸ^Ë„ˆêLII úúúRË?ýôSxxx gϞ˭¬¬Ð¾}{’ˆˆ¨ÈÎÎÆ­[·¤–¯_¿B¡P<÷˜"CFD íí·ß†——rrr$þóõõEEEEDDÔœ9sß|óÔ¿û^^^èÓ§¸>¯€Qƒ³°°ÀÈ‘#¥–ÇÇÇcæÌ™R' 9r$ú÷ïÏ@5™™™X·nÔòýû÷c×®]øðÃeZ^£Ž‚‰ÿýpèÐ!ôïß_ê< DÔ:ùøø 44AAA Q‹.]º ¼¼¼A–רW@ìììÄߊ†……qkQ £F‚@ @pp°Ô:o¾ù&,,,,""¢òàÁܹsGbÙ¶mÛ°|ùòë«QñœÚÚÚÜÒDTƒ™™Ξ=+µ|ÕªU=z4‡ð&""j@ÁÁÁ8qâV¬XQ£ÌÃÃ:thž Ñ˨««cÀ€RË•””0qâD|öÙgRëèèè@II‰Á$""úŸòòrJ,«¬¬D@@¾ûî»Zÿ3!¢VÉÚÚÓ§O‡Ärooo„††¢W¯^ Ñÿ>| ,À´iÓ$–ðÁ4hP£¬ "jVlll°råJ©åVVVðððÀ©S§,""¢ÿ¹víFUëßÐÆÂ„ˆZ\‚¢¦¦@P£¬²²;v„››EDD-Jdd$¾úê+¼óÎ;Ë£¢¢ðã?6‰umÔ$??OŸ>ÀÈȈ{ 5¨!C†`È!Ë*++áéé‰ÜÜ\èéé1XDDÔb$%%¡°°B¡°É¯k£& ñññây@`ccý…ˆ’’”””°hÑ"hjjJ¬3vìX©ß½.¹¹¹µÞ>uðàÁ&s…ãeu"ÂÍœ9FFFœˆˆšŒõë×ãöíÛ8pàƒADDMJrr2¬¬¬PVV•fý^ø Ñÿ<8¯¶I]\\`ffÆ`Qƒ‹‹‹Cdd¤Ä²;wÂÃÃÊÊÍÿô ÑÿX[[ãäÉ“RË¿ûî;|ñŘ>}:ƒEDD îĉ8pà€Ä;„æÏŸvíÚAAA QK¡©©YëLË—/‡››ÆŒ#µ'A$""ij› 8€9sæ4Êd€L@ˆˆšöíÛcòäÉR'AôôôDxx8,""ª!$$3fÌÀ¬Y³$–¿ÿþû:th‹""µk×®ÖHΟ?k×®1!""‰®]»†?ü°ILØâ»wï"==½Úk)))œ„ˆZ”‰'â矆Är;;;?NDÔ‚àúõëRËwíÚ??¿V§FI@ ‘““SíµÒÒRî¥DÔ¢¼ÿþû011©q¼€½{÷ÂÎÎÞÞÞPTTd°ˆˆZ ØØX¸ººbÿþýËùå8::¶ú8q"¢FðôéS#//::: Q ´bÅ $%%a×®] F-ø Q#PWW‡»»;–/_.±üСCðôôÄçŸÎ`5ñ$###jjjË¥=`NL@ˆˆ•––„B¡ÔrWWWÌœ9“ QVVVlÚ´ ššš "¢æËÒÒËïÞ½ ///8;;3XDD¯Ð‰'°mÛ6´oß¾FYyy9œœœ˜|0!"jþ:w°0©åK—.Å/¿ü‚_ý•Á""z…âââ Ö«ÖÄ„ˆ¨Å{óÍ7ñõ×_cÕªURˇÎ@É`ìÛ·Oj¹§§g­CéR3K@.^¼ˆÀÀ@ÀåË—áêêÊ-@D$ƒ>øÑÑÑRË7oÞŒ¾}ûr„-"¢—xøð!öîÝ‹7nH,Ÿ;w.¥-)éÓ§úôéàÙ0¼DD$èëëK-711ÁñãÇѦM‰åíÚµCÛ¶mH"jñŠŠŠpíÚ5©å«V­ÂâÅ‹k=¦R J@ˆˆèÕpuuEdd¤ÄIwìØîÝ»cݺu µxIIIxÿý÷ ±|Á‚pqqa ˜€Q}ØÛÛÃÞÞ^bYÏž=ammU«VAY™‡}"jÙ‚‚‚0zôhŒ9’Á`BDD¯ƒŽŽÜÝݱpáB‰åþþþøé§Ÿ0vìX‹ˆš… 6`÷îÝ1b„Äò9sæ0HL@ˆˆèuÑ×ׯu8Éâ»ï¾cBDÍBee%îÞ½‹)S¦`éÒ¥ ""jnÚ¶m ©“ FEEaË–-èÒ¥ ƒEDâÌ™3 …èСƒÄäöíÛœ§ƒ ˆl8 /QÓãì쌫W¯J-ðõõ…ƒED"!!%%%L2˜€Ô‡á%"j~Þ|óM,Z´Ríƒf ˆHf=ÂîÝ»¥–{{{ãßÿe ˜€QkôÉ'ŸHe½¢¢[¶lAŸ>} ¡¡Á`‘L!5 ád€L@ˆˆ¨SUU…ªªªÔò.]º`áÂ…PQQ©Q‰™3gbܸq $Q+’ššŠáÇ£ÿþPPP¨QÃÉ™€Égâĉ˜8q¢Ä²?ÿüžžžL@ˆZaòèÑ#üðÃPTTd@ˆ 5GGGDDDHa ¦OŸ‹¨™9þ<‚‚‚$–?~ß}÷“’HA$‰^GÇ3g΄‘‘<==¹ˆˆZ©Ù³gCSSÞÞÞ Q33zôhôëׯÖ/ˆ$iÔ+ ñññ¸uë€gëq µb3fÌÀÚµk¥žÀ?~ÇŽCçÎ,¢FvòäI,^¼ï½÷žÄr‘H„É“'3PÔ´555ñÃFjjjŒ>Q+×½{w:tHj¹††„B!|}},¢FöàÁ´mÛ–sqPóN@,,,`aað÷÷gô‰ˆ¨V]»v…§§§Ä+$EEE1b>þøcŠH X½z5ôôô$–:tüñE ŽÏ€Q³tðàAøúú"$$êêê QyzzâÎ;ðóóc0¨Qq,""j–>úè#œðòòBNNŽÄò°°0üüóϵlii)ñ›c¢ÆR\\Œ´´4©åþþþ8}ú4æÌ™#±|üøñL>ˆ QcÐÓÓÃÈ‘#¥–;99áèÑ£–X>þ|ÄÄÄ }ûö &½6¡¡¡˜2e <<<$–khhàСC044d°ˆ ˆ$/^D`` àòåËpuuå "¢×ÂÞÞîîîRËUTTðñÇ㫯¾’XÞ·o_ôêÕ‹¤zÉÊÊÂÞ½{¥–¯_¿{öìÁ°aÃ,j18 ‘ùùùxúô©Ä²ôôt 6 ¿ýö”””$ÖéÝ»w­ÏŸPëqÿþ}ܽ{WbÙãDZwï^Hmoff ’Z Þ‚EDD$ŽŽttt$–YXXàðáÃRÛÞ½{Ÿ|ò ¶oß.µN‡ ¥¥Å@·ÙÙÙHLL”Z~ìØ1ôèÑCâöÖ××Gpp°xž4"& DDDTƒªª*  µÜÁÁšššˆˆˆX†ªª*¬_¿^b¹šš¿ñnB***PPP µ< Û¶m“zKß|€=z0DL@ˆˆˆ^ L:UjyïÞ½qèÐ!øøøH­3oÞ<èêê2˜MÀ¥K—ðÑGÕúÌPHHÚ´iÃ`5T +++©—¢Ÿ;|ø0”””ðñÇ3²DDDR888ÀÁÁ¡Ö“Ùï¿ÿ^âð©yyy€~ýúIm?hÐ ´mÛ–~Á;w&±,++ 'OžD×®]%–WTTàøñãèÛ·/IÔ^úúÇ1}útìܹöööRëýþûïh×®*++ñøñc|úé§µv̇Љˆˆê®´´ÑÑÑRËcccqâÄ èééI,OMM…«««ÔämmmakkÛäÞw~~>nܸ!µüÖ­[¸uë–Ô÷žžŽéÓ§KxÒÒÒ&&&ÜÁˆA­W@²³³‚Q£F½tAâËÍîîîÕŒŒ V«_PPeee$$$p+Õ¾¾¾Ô²^½zÕ:<ð£GpóæMdddH,?räH½þ6Ïš5 :u’Xöâpüu• kkëZŸ¥˜={6ŒŒŒäZ~aaas"jX¦¦¦ÐÔÔüÿ Hrr26mÚ$®Ð®];¸¹¹ÁÍÍ ?ýôS½: Ãýû÷«½–€K—.á—_~áÖ ""j!¤MìØPöíÛÇ 5ããÃÇ ˆd°eËÑÇk­3wî\‰ÿ—¦¨¨Häáá!’×?ÿü#ú믿äjûôéSÑêÕ«åî;88Xôï¿ÿÊÕöñãÇ"ooo¹ûö÷÷]¾|Y®¶÷ïßmݺUî¾wíÚ%Šˆˆ«í­[·D;wî”»ïŸþY#WÛ+W®ˆ8 wß›6m%%%ÉÕöìÙ³¢àà`¹Úæå剖-[&÷zŸ8qBtòäI¹Ú¦¥¥‰<==åîûÏ?ÿ?^®¶ "¡P(wßûöí………ÉÕ6::Z´}ûv¹ûþõ×_EQQQrµ½qã†hÏž=r÷ýã?¾ô8-Í… Dr÷½aÃÑ“'Oäj{êÔ)ѱcÇäj›••%Z¹r¥Üë}ôèQÑéÓ§åj›œœ,òòò’»ï?þøCtéÒ%¹ÚÆÆÆŠ¶lÙ"wß¿ÿþ»(<<\®¶·oßíØ±Cî¾·mÛ&ºwïž\m¯]»&òóó“»ïÍ›7‹åj*:|ø°Ü}¯]»V”žž.WÛQHHˆÜ}÷Ýw¢üü|¹Ú>|XtîÜ9¹Ú&&&Š6oÞ,÷zûùù‰®^½*WÛ{÷î‰~ùå¹ûÞ±c‡(22R®¶ááá¢Ý»wËÝ÷O?ý$Š•«í¥K—Düñ‡Ü}oܸQ”œœ,WÛ3gΈŽ=*sýZoÁ*..ÆÉ“' UUUtèÐÁßß_¬¬¬êÜVSS666rëØ¦M˜››CUUµÎmµµµaccmmm¹ú¶°°€¹¹9TTTêÜ699ÙÙÙptt”«ï¶mÛÂÔÔÊÊuµúù¶ªÏ~*íÉ—122‚………\s "<<¼ÖQv^ö±°°ë3¢®®[[[¹÷S333´iÓjjjrF^6âŸ47oÞï/u¥££ƒ¶mÛÊý±²²‚™™™\û©žžÚ¶m+÷¤xÖÖÖ055•:#xmâââPQQŽ;Ö¹­ŠŠJ½åò~Fê{,711………\ûivv6–kiiÁÚÚZîψ……ÌÌÌä:–ëêêÖë3rùòetíÚU®möü3"ϱlll`bb"×gäùù޼óÂØÙÙÁØØXâˆj/sïÞ=hhhÈ5(ºº:ììì^Û±ÜÖÖVîý´>ç;©©©HMM…³³³\}[ZZÂÔÔT®Ïˆžž¬¬¬êu,711i”óå—í<Ò’ 333˜™™U{MÞƒ¡<ä=){þGËÆÆFîöÆÆÆr·USS{mC#jhhHõDÖ?ZòÒÒҪ׌¿õYïúªÏö’÷Ä”””`gg'w{CCÃ׳úŒ$£®®.W‚ýâ±I^šššrŸ`Ô—¶¶¶Ü'VõýŒÈ{ýâ­×AYY¹^£5Éû°2ðl"ÂúäIRÊë<–×g¶ïÚf¦Õês,ž€¼®cy}þŽÔ‡ššZ½ŽåõùŒÔ÷Xþ:çs©Ï±\WW·^sÕç˜V×óòZ¯€¼jJJJµíKÒ?”œœJv ÐÕÕ}­ð›£ú&ê­u_³°°¨× Zkd``P¯d 5îgõýB©µjÛ¶­\Wf[ó¾fbbRוּÑÖÖ®W¢ß*ö­—ÍRW999†““S­Cå=mmm˜˜˜àƸ}û6`È!âƒkBB´´´8>7½6¥¥¥ð÷÷G‡ЧOŸ—ÖOMMEYY¬­­±gÏÅàì쌨¨(DDDÔZÿÑ£G˜7oâââ™™‰“'OÂÙÙÎÎÎðõõ×™?>bcc¹×ÑkQPP€ß~û ÎÎÎHIIÁùóç_š|,[¶LÿüsüþûïR릥¥áÏ?ÿ|60ž]®;v,œQTTGGGTTT 00P\‡ˆ¨®.\¸€_ýõ¥õŠ‹‹Q\\üJ×åĉ˜>}:_Z7++«Æk[·nŵk×^é:æç磼¼¼Ö:'OžDrrr×}||0{öì]Ÿ%K–àÉ“' ¶¼û÷ïãèÑ£âßËÊʰcÇ$%%x6˾}û jÌa%¯{÷îÁÓÓó•ïï’öIþûï?\½zUü{QQ6oތŋ#''PRR‚Ÿþ™™™R—µsçNñÿoܸñÒ/‰š«û÷ïCWWÎÎÎ3f >,µnNNüýýñÑG‰_svvFÇŽqúôé?V¶êDViiiؽ{7ø^LuuutèЗ.]Brr2ÆŽ eeeÌ›7÷k‘Üúöí‹3f¼´^hhèK¿Íª¯#FÀÅÅyyy/­»zõ꯹¹¹áÍ7ß|¥ë¸oß>ÄÇÇ×Z'>>ùùù5^www—kä–Úlذ¡^.¿èáÇøí·ßª]Qß»w/\\\  €¤¤$8p]»v…P(Ä™3gSï¾;wK—¾òý]Ò~ó]»v û÷ïGJJŠøµmÛ¶aܸqX³f ~üñGaÇŽ:t(„B!¶oß.5 y~ëôó¿ïÒfX'j-Š‹‹áããƒo¾ù¦Æ ©©©ÐÓÓ{åv6uʯ«ã´´4ÄÄÄÀÉÉ o½õ.^¼ˆ””Œ;–{/>ýôSØÙÙ¡  ZZZøöÛoqùòeœ;wÀ³Ñݾþúk©£wÌŸ?iiiØ¿?ÀÓÓùùù())’’&L˜€ÒÒRñmŸ§OŸ†··7îß¿]»v¡´´ðÁÀÊÊ AAA(..F~~>sssøøøˆ9xûí·1tèPüðÃâ“t'''|ñÅ×ïܹs8rä€g£Ÿ,X°8þ<F…wß}·o߆——Œ©S§víÚ%>ùÓÑÑÁüùó1{öìñ’u†£G"00×®]CçαdÉÀ÷ß‚‚q¼ˆã¥  €Ñ£G£oß¾5–—˜˜___ñ•¥÷Þ{¯Ú·ÏåääHŒWHH„B!6mÚ'''ˆD"Ì›7žžŽÂÂBÃÛÛ[|•ÄÀÀË—/ÇîÝ»‘››+îcÖ¬YˆŒŒÄœ9s(~=** Ó§Oðlµ´´4ܸqŸ}ö€g#|=zô:u’)†aaa8x𠪪ªÄñêÕ«Ö¯_ÐÐPüý÷߀€€œ={VüÛˆ#ЩS'lß¾ý¥ñ€Ã‡ã¿ÿþÇküøñøî»ïÄûÍ´iÓЭ[7‰m“““1iÒ$dgg‹_KJJ†QRR‚ØØX´oßÀ³Q rss%ŽYXX@tt4ÆŒƒ€€\¾|YœÜïܹo¼ñhÔjäææbÉ’%xüø14551jÔ(€½½=ÜÝÝáîîΤ¡ 8{÷îEAAøùŽ¿Å*,,Äš5k`ff¡P8xð ììì‘‘mÛ¶á“O>App0tttðÞ{ïáèÑ£ C||0tèPÏæô044ÏOqôèQlÙ²ÉÉÉX¿~=ttt°sçN˜››ÃÅÅnnnž]èÙ³'ÌÌÌÄßF×ö‡ÆÊÊ ýû÷ðìê¬_¿ÅÅÅâã$8::bÁ‚Õno‰ŒŒÇaË–-xúôix%%%Éœ€|ôÑGxüø1\m^ŽwÞy¥¥¥ÈÎÎÆ™3g §§‡±cÇâwÞAII V®\)1‰‰‰²²²øý8qBâ uqq1455Å—888†^í[z…B¤¤¤ ((Ÿþ9€gó;<ÿÿ®]»<Ȥ¢¢BÜVUU£F£G^éþúèÑ#ôîÝêêêPQQA‡HKK«V×ÕÕ|ðAµ}DIIé¥ñ€öíÛ‹çuTë IDATøóÏ?ñÅ_@(ÂÝݽÚ~#ɨQ£Ú`ïY]]#GŽ^`ܸq7nöìÙƒ)S¦È='QSÒ­[7DDD 88©©©â//ž{®^½ ___hhhˆ?‡¡¡¡â[#7oÞŒvíÚUû¬0iøôÓO†îÝ»W~ܸq¨¬¬”˜´¨««C]]½Ú†|>~³¾¾¾ø-Ï„0DÔ¼©¨¨Ôk~ IjW¿ªªJ|¢¨­­-~òy‚¡¬¬,ž‹`Ú´i “ûÙ‘ªª*ìÚµ ï¿ÿ>Š‹‹QPPP£Nrrr†[­-^·nÝBçÎe𨫤¤………øûï¿¡¯¯}}}ñ3Ï“Yhii‰c8gΩۣÿþâ«Møî»ï$ÖÍÈÈÀáÇ1yòdñûTUU÷ñü‹¯Ý»wW{bݺuç022ÂÓ§Oadd„¢¢"hjjÂÔÔééé055E~~~µ¹F¢¢¢`oo/u޾}û"&&UUU(((À_ý%u¤Iû¡,ñzòä þþûo¼ùæ›ÈÍÍÇ­>ûŽŽ  ¡¡‘H%%%ñU===”––Jý¬¤¤$ŽÑóyxªªªàçç'~è–¨%PUUÅ矎 . K—.Õ®Œ¾ÿþûo‘íÞ½»øËñãÇ‹oýú믙€4$---‰“J›ïãÅoæ$µ“eVu"j¹^œýWEEJJJ1b€g/Íš5Kjûùóç#,, 6lÀ’%K ®®ϾQ~2îèè___œB×®]akk ddd`È!âí<»/00½{÷–ø^ÒÓÓqìØ1TTT@YYY|efýúõ  °iÓ&ñ¾üâ~îàà S¼tttP^^Ž#GŽ@OO¯ZÂÙ®];8::âË/¿”Ø~éÒ¥ˆGii)BCCñÃ?`ÆŒðòòBQQ>ýôSèééá믿†P(Dnn.Æ/õ*ã‹ûœ²²2”••qðàAüöÛoèÙ³'öìÙƒÏ?ÿœ·`QË8qVV–xnjee%qâÅçP‘V§5jðy@ˆˆZ“°°0<==ѦMpK1‘]qq±x2¢ÂÂB©õ²²²Ä³¿*))¡¬¬L\vüøqœ9s¦Zý’’899µú#‰ˆˆˆˆ˜€40WWW¸ººV{ÍËË çÎcBDDDDÔ4ØC躺ºÈËËCNNNµ[ªÒÓÓ þÝÒÒOž¼ñccc¬^½ºÆëݺuC`` øw]]],\¸{ ‘œ*++‘””À;w`bb‚5kÖ`öìÙøóÏ?Ñ¥KÌ›7S§NEVVÌÍÍëÜω'°yóf¤¤¤`Û¶mØ´i`çÎØ°aÔÕÕ±jժד€QãÐÑÑ««+"""į9::Š–––ÂÑÑŠŠŠppp»˜››ÃØØ¸Ú몪ªèÔ©ÔùŽ&NDHDDDDD† Q pûöí?«ªªpçι—™‘‘ÔÔTñ2Ÿ+++CLL ‘——Ç„ˆˆˆˆ¨%KMMÅ’%KpçÎìÛ·ÈÈÈ€@ €¢¢">ùäDGGC ÀÔÔT<_]1‹-Š+ðõ×_cåÊ•ˆ‹‹Ã´iÓ°dÉ,^¼cÇŽ­Ó2D"‘¨)×ËË 7oÞÄüÁ=ˆˆˆˆ¨™ã"""""j4‹ˆˆˆˆ¨ºtéîß¿{{{¼ûî» E||<:uêœ:u ÉÉÉpttDÏž=qâÄ ¤§§£gÏžâ³duõêUDGGÃÖÖ @ii)üýýü1 ‰°gÏq›~ýú‰ç yQ“¼’••…sçÎáܹsˆ‹‹ãÞEDDDDô‚¸¸8,]ºÎÎÎðôô„ŸŸ6lØggg,^¼~~~ؾ};ºuë777øùùáÀh×®¾úê+”––ÊÜWff&âããáìì ooo„‡‡cíÚµHOOGii)–.]*®›˜˜gggäææ"66VâòšdRQQœœäää ¤¤„{Ñ JJJ0lØ08;;ãÃ?Dff&>þøc8;;cذaÈÌÌÄŒ3ЫW/Œ9™™™pssC¿~ý0pà@TUUÉÜ—±±1&L˜}}} :ÖÖÖÈÍÍÅŒ30yòd(*>K)°bÅ tìØééé:t¨Äå5É[°LMM1räH@LL n޼ɽŒˆˆˆˆèÌÍÍqâÄ ¤¥¥áúõëØ²e ¾ýö[ñ¹ó¬Y³´¿ŠŠ ØÙÙaË–-022€0bÄhkkã£>ªV÷äÉ“R“€¡5;†††8þ<&Mš„¯¿þo¼ñþûï?|òÉ'˜3g êÝÇ•+W p÷î](++C$ÁÂÂ.\ÀèÑ£qéÒ% <Ÿ|òIµv¡¡¡x÷Ýw™€µùùù8|ø0C›6mpåÊÄÅÅaçΘ>}z­Ëå< DDDDDÍLQQnܸ~ýúòòò…wÞyG\'22YYY°¶¶†½½=nÞ¼‰¼¼<ØÛÛÃÚÚºNý=xðÉÉÉ011ƒƒ¢££¡©© @TT”x$,ccc¨««3!""""¢×·`Q£áD„DDDDDÍLNN:„ÔÔT|ÿý÷ÈÈÈÀÔ©SѱcG<|ø6lÀñãÇabb‚/¾øñññ˜1cÚµk‡ÂÂBxxxÀÍÍ ¶¶¶PQQ¯¯¯Ô¾òòòðÓO?!33111ؽ{7ÂÃñqãFhjjb̘1˜:u*àÎ;سgnÞ¼ __ßæ3!I§®®GGGbcc1xð`…BtïÞ………èØ±£xÂÁk×®aÖ¬Yغu+TUUqêÔ),]ºÛ¶mCQQQ­}©©©aæÌ™ …pqqAzz:þúë/øûûcïÞ½¸r劸î?ÿüƒaÆÁÝÝ/^”¸<& DDDDDÍ0qrrªö𥥥ø§®®.:wî\£\YYfffâßÕÔÔ`ddôÒÄÀÀ£F‚ƒƒ¡®®Ž#GŽàÔ©S(//×íß¿?¼¼¼päÈôîÝ› ÉæÅy@пÜ»wqqqX³f ŠŠŠ wwwq›ÐÐPüöÛoppp@XXXóM@øû÷ïÇÇѧO <;wîÄãÇ1hÐ ôíÛ>DUU:tèPç¿ÿEEEðööÌš5 fff‰DÕnµ9r$ºwï^c¼BDr' Žôôt„ˆˆ¨¥¦¦B àÌ™3€°°0þý÷_,\¸±±±2÷¹uëVìÚµ À³²ºt邹sçÂØØX\ÇÆÆsçÎ…µµ5 $.‡ Õé½~æææØ¸q£ø÷ŠŠ ôèÑúúúpvvFii)zõêCCCtëÖ ¥¥¥˜4iÚ¶m‹AƒÁÅųfÍ’¹¿˜˜$''ÃÄÄpýúu8p‰‰‰PRR(((`êÔ©¨¨¨À“'OЧO& DD$ÙÖ­[!!!X³f BDÔÌtêÔ ·o߆@ À½{÷àêêŠÐÐPÌ;™™™Ð×ׯó2óóó‘€¼¼<üöÛo˜>W®\a š¹§OŸâÎ;x÷Ýw„Q£F1(D-œ¡¡!üýýqìØ1¸ºº¢]»v@`` Ú´iƒÇ×y™‰‰‰8}ú4póæMTVVâüù󈋋ƒ½½=ºté‚iÓ¦!//¯Z»«W¯bâĉL@ˆˆˆZ‹¼¼<„‡‡ãÝwßEhh( 44ýû÷Çýû÷¡££ƒ6mÚ0(­\VVvî܉°°0„„„ÀÙÙ€³³3 „„„:t}úôÁ;#ððp|óÍ7øàƒpþüyDGG#((UUU°´´„““S>ºuë†nݺ€øŠ†»»;ìíí1kÖ,tîÜpttÄÑ£Gamm³gÏbÞ¼yµ®;"""¢&.((ýû÷Gxx8¬­­™€4s·o߆££#‚‚‚СCñI~]èèè`ìØ±;v,´´´ ««‹qãÆ¡mÛ¶333Lš4 –––€7Þx‡Fii)æÌ™EEE,^¼`dd$s¿Ë—/¬]»°¶¶ðlÖtuuuØÛÛCSS“ QS±sçNøøø   eeer-CEE¶¶¶Õ^{ž|€†††8ùxîÿ&®:::uî×ÐÐ`ll\mô«º ÇχЉˆ999 a ˆˆÙän[TT„œœˆD"@aa!rrrP\\ ¨¬¬¬–à ''%%%žœU^^^§>Ÿ/[$!''999¨¬¬¬V'//ùùùÍ+‰ÅªU«°jÕ*œ>}š{&Ñ+VTT„¨¨(‚ˆ¨‘]»vM®v4hÆŒƒ}ûö!)) ƒ†ˆ+W®`îܹây;¢¢¢0dȬ[·®®®¸rå ¾øâ‹:k_ºt ³gÏðì”Ñ£GÃÇÇ™™™â:—/_Æ?ü€÷ß·nÝ’¸œ&y –­­-æÎ+þIÑÿW^^Ž+V`À€X¼x1:tè€Y³faÊ”)ÐÓÓƒ¶¶6¦L™‚7nîܹOOO 0óçÏGçÎë4@…H$¿ÿþ+¾Ú±víZŒ?_~ù¥xh^àÙ…ݺu' Íf&teeeèëëC__êêêÜȈˆˆˆ^`aaaÆÁÏÏOü¹†††ø§ŠŠJg<444   uuu¨©©A[[[æþ¼¼¼`dd€@ @VV¾ýö[Šëõïßþù'6oތ޽{K\Ÿ!""""j†ÒÒÒ——'ͪ¡]¹rgΜAvv6†Žüü|”””ÀÚÚPWWG\\œ¸Mhh(¼¼¼ðñÇ#,,Œ QKššŠÝ»wC àĉž ×üâÏÿ+((ùùù2?ÞðöÛoC(¢gÏžhÓ¦ ‚ƒƒñðáCdee‰û022’8,´£££Ôår^""""¢f(-- =zô€‹‹ îß¿@€éÓ§£ªª ¿þú+àøñã?~”””†††5~*((ˆçî6l´´´Ð¯_?ôìÙŸ}ö™Ìý]ºt iii°´´|–D(*Š'<|>¡‚‚†ŠÀÀ@èêêb„ L@èõ*..ÆÑ£G1|øpTTT0 DDDÔj•””Ô«½’’”••qäȸ¹¹ÁÉÉ ŠŠŠ(..ƤI“ðôéS¸»»C[[[|8þùç‰Ëm’¡§§§#88p÷î]¼ñƇ‹‹ ÷¶f* cÇŽe Zˆ¤¤$ܸqƒ ""zM÷4¢&"-- cÆŒÁºuë`nnŽÐÐPtëÖ!""j$]»v­1£ù¦M›ÄÿïÒ¥ 6nÜ(þ½cÇŽ¸|ùrµúï¾ûnûõññ€js€ÿY–Éax‰¨^bbbPXXÈ@‘LšÍCèƒ ™3g¸Åˆš˜²²2ñèÔpà@X[[CA$‰šÚÊåççãáÇâXXXTUUejWTT333™úIIIŽŽŽLs‚””” 33SæÑ±ž>} EEEñU’—ILLD›6mdzŸyyy())©©©ÌïSWWZZZ2ŸŒ´oß^¦º™™™PVV†¾¾¾Lõ`ii •_—'Ož@__ššš ¾ìºÖOHH€••”••_ûº¼Êe7¥u©¬¬Ä£G`gg÷Ú×¥¸¸YYY2O€Z—e?4CÒ’äææ¢¬¬ &&& ¾.EEEÈÉÉ………Lõ322d~V®¼¼Ož<ò2ÏOÌŒe>022‚††ÆKë"/”Aî IDAT/OæHÒÓÓ¡®®]]]™êÇÅÅÁÆÆJJJ/­›ªª*Éü>e}°.Û?-- šššÐÑÑ‘ù}ÚÚÚÊ|ëq]Ö%)) ¦¦¦PSS{íŸÿ‡ÂÞÞ¾Ú<þ¿Úe—••!55ÖÖÖ ¾l‘H„¸¸8´k×N¦ú(((€¹¹yƒ¯Kii)ÒÓÓѶm[™êgee _Z·ªª ñññ2¿Ïºžs§¦¦B[[>>>èÓ§ jâ6lØ zòä‰LuÃÂÂDû÷ï—yÙ;wîݺuK¦º "¡P(ó²=*:}ú´Ìõ×­['JKK“©îåË—Eþþþ2/û×_EEEÉ\îܹ2× ={Væú«W¯=}úô•¬Ë¶mÛD÷îÝ{%Ë®ký+VˆrrršÄº¼Êe7¥uÉÏÏ-[¶¬I¬ËƒD[·n}%ËÎÉÉ­X±BæúçÏŸ¾’u‰ŽŽmÛ¶Mæú¢ .ÈT733S´zõj™—}öìYQPPÌõ·lÙ"zøð¡Lu£¢¢D¿þú«ÌËö÷÷]¹rEæúK—.ÊT÷ôéÓ¢cǎɼl¡P(JHHx%Ûÿþý¢°°0™ë/Z´HTRRòJÖÅÛÛ[”””Ô$>ÿóçÏ•——óøßˆËNII­_¿þ•,»¢¢B4oÞ<™ë‡‡‡‹vïÞýJÖåñãÇ¢7Ê\?$$Dô÷ßËT·´´T´páB™—}ýúuѾ}ûd®¿{÷nQDD„øw>MDDDDD¦IÞ‚õ"///|þù眃£…X³f fÏž-Óå@jÜÝÝkp¸=éõñññÁ¨Q£d¾•ø%nÏÆÀ+ DDDDDÔhšüGÁÜÜ\¦‡³©éKLL„………Ì¡SÓW× ‰Û“O]B'~F‰Û³1(­\¹reSX‘´´4|ÿý÷ÈÌÌ„ƒƒƒx” ==½j#ƒ”””ÀÃÃ111èÑ£‡L£†PÓ¡¯¯ÏmÖÂðv:nOjºtuueø¥ÿÇÞy‡Eqµýÿ ( U±ƒ"V$6Ô¬kì}lXÀ ‚1–Ø(ˆXÅ®ÑØ06Š ÒK‡…ÝùýÁoÏ»sÖ$Ï›ç5OÎ纸.vï33gfgïûÜí#•JqùòeøùùáÓ§O°´´Çq¸yó&|||йsgrÍqäÈ“êQïÞ½ƒ§§'ôôôH¥Õˆˆìß¿jjj +;¦¥¥aûöí¨¨¨@·nÝ~wåµ//Â’™™‰Ë—/ÃÙÙHHHÀ¼yó}®¢¢û÷ïǦM›ðñãGÜ»w«W¯fw?ƒÁ`0 ã?Î¥K—ЩS' 8¼wãÆ èêêbذaðññµµ5>|øŽã`ccƒ3gΠwïÞ(--EQQ¦L™‚+W® ]»vPQQAjj*æÌ™ƒ[·nAKK #FŒh´ßäädaåÊ• A^^¦M›ö·™·/"$33“X}ýúõCDD„àç*** ¦¦†¦M›ÂÔÔ”ô a0Œÿ6nÜø‡· „““víÚEšX…„„ÀÉÉ Û·oGaaá/44'Nœø¢çéÕ«W»k›••…¬¬¬?µmMM fΜ‰ŠŠ òÞË—/áää„mÛ¶!77ggglÞ¼€¸¸8¸ººÂÍÍ )))êC>ÜÜÜàêꊸ¸8õ}46oÞ gggDEE¨LضmœœœðâÅ öe0xñâ”””púôizõêdff"%%Í›7GUUõø  èØ±#iDxÿþ}xzzâúõë(//GóæÍqíÚ5xzz"((………‚Më$ ùÁÒÑÑ¥¥%€úp‚Aƒ‘Ï}üøÊÊÊHIIªª*L/!bbbˆ4hÐ ˆÅb”””e¸ÿþÐÔÔDrr2QÐÍד'OpäȬ\¹æææ022BJJ Z´hèèhtîÜmÛ¶%qÕòß¼yƒÚÚZ´lÙÇ‘¸kÙ\ 2„šŸ&4_²Æz²E3™Ò±XLæëÓ§O¸pá8Žƒ••™¯¨¨(”””B(<µ¬¬ ÐÑÑ,`!33¡¡¡ððð@II <<<àää„Û·oã§Ÿ~BUUöíÛ‡íÛ·ãÌ™3عs'$ ¶oߎ={öÀÏÏ[¶lŠŠ 6oÞŒ½{÷âĉذaš5k†]»vÁÄÄÇŽƒ““tttpàÀ´iÓæw7@c0þ)!55}úôAdd$uÁç‹ð€¨©©¡¦¦†}BYYÒÓÓ1uêT´nÝ999ä½Q£F‘²†øùù‘ñbbb  ¾£¸——ùÜùóçáãã‘H„>àúõë D|| ‰D‚I“&ñº*×ÔÔÂ,:::‰DH$äwRKK‹xÃd†P³f͈+ûýTUUEmm-ùíÕÒÒ‚ŠŠ ””” ‘H ‰H×z5552ß ãÐ××Çœ9sЧOèë룼¼ºººä»^YY èéé‘Îä²Å"Ù÷WöÜÐÑÑAóæÍQZZJžÇzzzd_ùùùdÑ¢Y³f¨¬¬$º²®®îßjÞ¾ˆ¥¥%²²²àää„æÍ›ÃÉɉȎ?ŽÈÈH\¾|>|8œ¡¦¦†åË—³;ŸÁ`üÛã×_E]]š4i‚ýû÷ãÒ¥KèÕ«¬¬¬Ô×j§ÈÈH@vv6QUUgggÀÓ§O!‹ñàÁbcc±qãFTWWcòäÉ@ »wï’E%%%¬]»äsoß¾…X,Æ“'OššŠ7n`íÚµPRRBXXyÏÞÞžZý¨S§N¸wïù¿OŸ>€I“&5rù¯Zµ ­ZµBvv6Yþü9ôõõQWWMMMÁ}èéé!++‹x;¶mÛ†¤¤$Ìš5‹œ‹££#***H¼H©©©°³³ƒ²²2ùœŒÉ“'ãÉ“'¼÷utt`mm>}úð~¬b``€¡C‡"77M›6%?ÞšššHKKSxÈÏWÇŽÉ|éêêbΜ9(**"œððp”••¡¢¢&&&˜:u*Lâ¿ú¬‡ÂØØ˜ Ë–-ƒ‡‡G£}ÿÝ 㟄µµ5Ñ[544ààà€AƒaïÞ½‰Dèß¿?lmm1fÌìØ±EEEèÑ£–,Y8pà233abbBòš=Š€€aÆ d_+W®Dÿþý±~ýz >W®\!^JWWWf€ü&L˜€ &4z_~â`ðàÁ$€Á`0þ·pssƒžž©´gaaAdaaad…¹!¯_¿†ŠŠ <<<‹Ÿ~úI𪰰ãÆÃ?ü@Þ—J¥äÿ¼¼<ÄÇÇ~×1ÛÚÚâÕ«W<ãhÚ´i Qh0€ªª*QvÃÂÂpõêU̘1ãwÏׯannþÙÏ-[¶Œ„‹9::bîܹxúô)æÎËûÜ´iÓ°jÕ*òºaîÊÓ§OI¬´¢÷¾þ=ˆÅb=zT¡Á&?_ááá¸rå fΜIäúúúÐ××ÇÞ½{±råJ´jÕ —/_ndØH$<þœÌ‡|¸[bb"Ž?N^[XX`áÂ…ŽEGG‡¬‚ÊBÍÔÕÕÁqÄb1òòòH¨”¶¶6JKKQSSƒ–-[ ‘ŸŸ555qЮ];V(•J¡®®ŽÎ;“ñå½! ã˜2e ¦L™Òèý­[·6zoóæÍÞ“-TɳbÅ Á}]¹r…÷zæÌ™¼çÐ߉/¾ƒÁ`üÕ”••ÁÃÃÅÅÅPQQÁ¦M› ªª oooäää`È! !±òéééèÛ·/ÔÕÕ1qâDøûû#11={öDmm-ìííáçç;;;ž±qùòe’@½dÉôèÑׯ_GHHZ¶l ---¬Y³FðŸ>}Š7nˆ™3gBYY¹Ñ~¾×œœìÛ·кuk¬\¹šššpqqA~~>ºuë†ï¿ÿ×®]ÃÈ‘#¡««‹ââb<~ü£G&ó%ó QUUEæ Ö¬Yƒ‚‚üúë¯ÄÛ±téR˜™™áܹsxûö-`õêÕèØ±#o¾¦L™Br'dsaccƒ1cÆàÑ£GèÔ©¯\å³gÏðË/¿@UU_}õ&Nœˆ‹/bÁ‚¨¬¬DHHúöí ###TUUÁÖÖ¼àß3_ 纤¤?ýô*++1dÈ(++cêÔ©¨ªª‚233ÉýuäÈdggöíÛ'Øï*##Dqq1tttеkW¬X±صk:wî ;;;¨««C$aÏž=044„ƒƒ444PZZ www¨««cÍš5ÐÒÒByy9¼¼¼P]] hkk£²²ÇŽC^^6nÜ]]]TWWÃÏÏ)))Ø´iZ´hÁ ƒ ƒñŸÂÑÑžžžl"þM^¿~¤¤¤FƒÁ`üs`U° ãw`kkË&áN: Våb0 Æ?æa0 ƒÁ`0ÿ1”Ù0 ƒÁ`0 f€0 ƒÁ`0 f€0 ƒÁ`0 3@ ƒÁ`0 3@ ƒÁ`0 ã‹4@âââH#*ƒÁ`0 ƒñßÇïêòöí[hkkóºÌ %%%˜››Š‹‹ñáÀ±±1 n€’’;vŒ]ƒÁ`0 ãŸf€H¥R\½zUUU(--ŰaÃлwoÁÏ#-- R©ÙÙÙ>|8Ž9‚¶mÛ®_¿Ž-[¶ IÖûÁ`0 ƒÁø§¢0+33Ÿ>}ÂÂ… ±fÍœ:uŠúÙ»wïbÙ²e°··ÇÍ›7X¸p!.\ˆêêjH¥R6ã ƒÁ`0 Æ?˜¿ÔÑ¢E œ>}µµµxôè›mƒÁ`0 ƒ +W®Ä‡дiS$''³Ùf0 ƒÁ`0þá( ÁjÙ²%¤R)ÒÒÒðèÑ#|óÍ7Döäɸ¹¹‘×]»vEtt4Þ¼yƒ=zTUU¡«« h×®Ëÿ`0 ƒÁ`0˜B§Y³fpvvÆ­[·P^^Ž©S§™‘‘,--ÉkDGG#..K—.dddàÆxþü9V¯^ eeÖv„Á`0 ƒÁø'£Äq÷¥Ì÷ßÏÊð2 ƒÁ`0ÿÅ0—ƒÁ`0 ƒÁ`ƒÁ`0 ƒÁ`ƒÁ`0 ƒÁ`0„Á`0 ƒÁ`0„Á`0 ƒÁ`0˜Â`0 ƒÁøg’’’ò§åÇŽCyy9U¾ÿ~ª¬  ›6m¢Ê/]º„ŒŒ ª<55Š Ø~Â`0 ƒÁ`üIŠŠŠ¨2???ª¬ªªJ¡‘ððáC¸ºº ÊÊËËqèÐ!H¥RAyZZÎ;GûÑ£Gxøð!U¾oß>ˆÅbAYaa!lllPWW'(OLLÄœ9s¨c‡††"11‘*/))D"aƒÁ`0 ãŸÉ/¿ü¢ÐHX¿~½ ,//ÇW¨ˆ?~ü˜*÷ôôDii© L,+TâOŸ>?Rå¾¾¾hÙ²%UC•Ý»wíÛ·WhteeeQåÞÞÞ(..”I$L˜0¹¹¹‚ò‚‚„††2„Á`0 ƒñeóôéSªlÆŒpww”%&&âÊ•+‚²ºº::t•••‚òââb…Šü±cÇн{÷?uÌ›6m˜1c¨ògÏžQeÑÑÑˆŠŠ¢†X¹¸¸`Ò¤IÔíoß¾Gý©ãŽˆˆ@EEUþèÑ#…ÆÍ›7ñöí[…Ûß¾}›*‹‹C~~>3@ ƒÁ`0ÿÛ·o§ÊvíÚ…k×®Qâ{÷îQ·UäI¨­­Å;w¨ÛîØ±ƒ*KOOGDDâââå 6"‘  ”áÅ‹ “ÂÂBAYUURRR¨^ŸÏÍ×­[·¿þú+ÂÃéò7n(¼ÎмQŸ»`„ øôéÓßÓ‰ÅùóçÙ·Á`0 ã?€££#Uá¾víU‘ÏËËCNN”””å©©©TEN:E•9r„*+++Cvv6 åÁÁÁTD]]±bÅ Aùû÷ïñäÉ꾓““©ûêC V­Z%(+((ÀÍ›7©Û¾ÿºººTyRR–.]*(‹Å8qâ5g&##C¡òæÍ…†Õ½{÷¡Ð˜l8çD"‘àÇTW·{÷n<þœ*¯ªªbOƒÁ`0ÿ(é?ùùù¸uë– ,22—/_FNNŽ üåË—ÐÐДÃÛÛ[°b“X,†»»;š6m*¸í;w¨9‰ÉÉɘ>}º <<<EEE˜1c† üÂ… °µµ”‰D"œ={;wþÃÛõÕ¯hy)UUUÈÈÈ€™™uìÙ³gCYYù ‡B×®]eÈÊÊ¢Ž]TT„aÆ)4ø…|ø@5>ÀÝݺªîææFÝîÊ•+PWWÇwß}×HV[[ ªBœ””„³gÏ¢oß¾‚ò`÷îÝÔ}¿zõ   n»iÓ&hii Ê_¿~MÝöÅ‹hݺ5:tè (ß´i–-[F•¿~ýýúõôýöÛohÒ¤ 5o%$$666Ô9qssƒ££# ©÷í¼>7g29 ±X,x)ÿ7|y€ÏWðööVXàåË— ë23 ƒÁ`|‰ìÛ·ÁÁÁ‚²;wRCÞ¾}‹Ë—/SÇUdD¸¹¹QûQäææB"‘`åÊ•X¡‹Åxôèlll¨Û*20bbbжm[AÙŽ;0cÆ ª§àÉ“'°°°”ݾ}˜5kÕ122BÇŽÉÊËËñîÝ;ê9?þoÞ¼¡†gÅÄÄ@EE…j€„††¢G‚²’’¤¤¤P“G!-- ‹/”ÀÈÈß~û­ |÷îݘ|ˆ«W¯ ʲ³³qìØ1ÔÖÖ6’) ƒ€½{÷R{Nœ;w:tT\?}ú„“'ORC‚îÞ½‹ÒÒR¨©© Ê/^¼HíWáîî;;;èéé5’Áßߦ¦¦‚ÛþüóÏÐÔÔD¯^½Éjkk‘˜˜ˆîÝ»CEE¥‘<..Ïž=ÃĉÇŽ‡©©)TUUÉ8Žƒ»»;u> D ßJHH@§N¨ó¥(üªºº‡¦ŽœœjHZBBLLL¨ûŽ‹‹C—.]Ãåjkk‘777Á9•%ì¯]»¶‘gçoa€\¿~%%%‚7#Pß5rèСèÙ³§ ÜÏÏ—yßwïÞQ«4õÉïׯ_§ÊËËËqìØ1ö„d0 ƒñ‡‹ÅÔæuUUUعs'µzÒ™3gðáÃAY~~>µ¯ÃóçÏñþý{j¨Sbb"V­Z%Ž”““‰D‚6mÚn{äÈêjþÕ«Waii)˜gQ[[‹¤¤$˜››£I“&ä/_¾D^^ÕHHNNƼyóeÅÅÅ8þ<õ¸2331eÊòZCCƒç9òöö¦ztŠŠŠPVVF«tuu!‰xzèâÅ‹‰®¥¥Å뤮hì’’¡S§N===^/‚‚ <˜,Âëèè ¤¤„·oÚØ²}ÓæDv999 ÊÒÓÓqûöm´k×NPž••5’ý- íÛ·cË–-‚2‰D‚Û·oSå8~ü¸`œ¡üøŠ8yò$²³³H—.]R8ÆçÊ—1 ƒÁøïåÍ›7ÔPñŸþ™ZMêéÓ§ û;<|øPPÁêKÊŽ=ZPöéÓ'H$Aå‘ã8ìܹSГԇ2mÞ¼YPöúõk¨ªª¢wïÞTÃÆÞÞ^°¢SRRnÞ¼ ª.5yòdòºC‡<ãkûöíÔÅè7n`üøñd%ÿ믿æõ½Ø±cï|Gމ_ý•¼¶°° ž—±cÇâþýû¼m/^L 2GGGxzzyll,ï¸fΜIzœDDD@UU•„~ :!!!<á›o¾!ó¹qãF^ÚŽ;`ffF<ööö¼&Œyyy2dÀÒÒQQQD===tëÖ 0bÄ^Ÿ‘{÷îaÊ”)ÔÄùíÛ·cݺuÐÔÔüÃúûo€DDD`„ 4h üñãǰ²²¢Zá·nÝ‚žž†JÝ>&&kÖ¬”˧Èßð ¡Y†2k~üøñ =( ƒÁ`0þ»;v¬ 7¢¨¨ÞÞÞJÇpssƒ©©)ôõõ ÂÂBjÞ““<<<eŽŽŽprrL˜ÎÌÌ„D"£££à¶ÇÇèÑ£‰‡C~E¾¬¬ ›7oÆ7ß|hÓ¦ rssI…¤§OŸòŽI^QêûhX[[“×­[·& ÄaaaX²d Q¦Åb16lØÀ3äL  ’œœŒÖ­[S½'„ªª*Ñ5­¬¬HÕÕÒÒRDGGóŽ«¡I½ŽñññhÚ´)™/ DGG2<<œ:v\\Î;G͉yðà^½zE +333^÷ØØXhii‘¼•¾}û’rºUUUðôôÄàÁƒyç"oؤ§§càÀ€víÚñJí¦¤¤ÀÐÐóçÏtïÞgdqÈùó瑚š J¥8|ø0i;¯¦¦†ºº:H$õ¡OžžžÔÄ›üü|ÀÙÙ™º?EÖPﺲ³³”ÕÕÕaÅŠTד̀RÔ8¦¬¬Œ:>ƒÁ`0Œ¿§Nâ­ŠËë +W®¤V‹zøð!ÕKqþüy´mÛVP-((ÀÑ£G©žˆ;vðBŠä9yò$,,,пÿF²ÊÊJ¤¥¥á‡~Tùå^N‰¼2Ô{äm[´h‚‚¢ð®^½ZÐ`ê›å %qõ9)íÛ·'ÆK—.]””Däwîܹ¹9y-?/oß¾Ehh( E244D^^O.j6kÖ,’œÏqbcc‰®¨ªª ŽãˆÑTXXˆgÏž‘sn8_111<ÏʨQ£xê¡ššš¤¤mMM ñB€ºº:Äb1oþåÇþꫯÉÛ·"W~ßÊÊÊPSSCuu5ѱƒƒƒÉ¾555yÕ¬222ФI’œÞðz\¸pW¢yÀ€xùòå—k€”••‘Dªôôt}IIIÔÕƒäädüòË/X²d‰ <-- óæÍ£V€ 6( ß*--Åž={Ø“Á`0ŒÿC"##©‰àÁÁÁptt¬6õþý{\»vM°¼êË—/±wï^²Jܽ{÷bíÚµhÖ¬Y#™——f̘ccc4oÞeeeDöäÉäææbÔ¨QDq•)–‰{÷îźuë ®®mmmÔÕÕ‘cŒŒDTT1TUU‰ÞÔ—Ð]·nyݬY32v@@ DBvŒIÒêêj8pæææ¤…¼¢ÿâÅ äååclÔ¨Qxøð!ÙOBB:tè@æbÚ´i$º¤¨¨.\à-èÊ9ïß¿‡É“÷~õaNòºš|ކT*Å;wЪU+"“J¥d¾²²²x9ªªª¼Ä~Yþ‡ ùÜ™÷G>ЧuëÖ¤ô±··7æÍ›GŽÛÀÀ%%%ÄøixÜòPŸ:"þ5 IDATo#ïÅêÑ£1޲³³1hÐ XZZš4immmb({{{ÃÎÎêêê䏯ŽË›3ùùÖÑÑáõni¸€/Ÿ|‘ˆ<îîîppp@‹-Ô·q¿sç‘8p€W:×ÀÀ€—¤Õ°j@CËðàÁƒ˜?>Z´h%%%èëë“í+++qèÐ!¬^½šÜlò_@‰D‚Ý»wcÍš5J‹õn3Œ7Ž$5äÅ‹ˆ¥&€ÕÔÔÀÁÁgÏž¥Î‘X,æ%21 ƒÁøsˆD"H¥ÒFï×ÕÕaëÖ­ÈÌÌl$“U!2>$ ÜÝÝqïÞ=ÁB:ÞÞÞ˜:u*ŒÉ®^½ŠN:aèСPVV&Ñ2…úÖ­[X³f ”••y!¼¼¼0{öl¢4wîÜ)))êCkºtéBWµ´´PUU…ºº:ÔÕÕaïÞ½ÄûÔçJ„……¨/÷jhhˆáÇF   õž‚„„´mÛ–xœqðàAõ‹¶!!!¼.ãòa;™™™¼j§ ½^^^¼*yJJJ0`ÀjcCwwwj^IMM ttt¨y/^Ä¿þõ/jžÍÁƒ©‘8b±]ºt¡–À=qâ†JÂÆ’šš sssjªÒÒRªùøñc˜˜˜ðB¨´µµ‰‘pøða´iÓF°‘¤D"ABBºuë&XÝ*""ñññ¼ôkkk¢ˆŽ;òÊ7t|±HAA~ûí7lÛ¶¼×»woÄÄÄ‹"•JyÞùXÁÈÈHhii‘jðàÁç]˜òòr^%MMM¢Ìߺu ºººÄÕ—‘‘Á«tõîÝ;ˆÅbÒŸ¤[·nˆ'òàÞ½{8|ø°àù½~ýNNN8}ú4ºté"ø™™3gR]¶2fÍšEíÊ`0 ã÷ñàÁèéé &ŠoÙ²¥Q'g™ò:nÜ8Ìš5 }úôi$÷ôôDQQ¾úê+A= %%…”£ !Qåååðòò•+W ££ƒ.]º 99™l{îÜ9XXXðyyxx8²³³‰nÐ0±xãÆèÑ£Ivuu%­ž={†øøx,_¾œ|ÞÔÔ”„Æ{{{ó¶ºwïNtYÄ-!00Paÿ777jÄIpp0,X@íPîææ†¾}û *ËïÞ½ƒT*¥&Ô>|ªªªÔ&}¯_¿¦vOOOGUU‰Ô2^òòòH*AÃ{çñãÇÔyyyHJJ¢ö¨ FTTÕpJLL¤æOWTT $$„a‰ÇSS>|ø€ºº:j9丸8Ì;—ÀB|±Èýû÷©-ãúÒ»´²¼àããƒáÇ“ 3hÐ ²:PSSOOO,X°€LÎîÝ»ÉE.**‚¯¯/Ö®]K\Oò)##ëÖ­ã•-kh€;v þþþäuŸ>}x•¼½½accÁãß¶mÆG-VUU…éÓ§+,/üìÙ3Ìœ9“Ú€ˆÁ`0Œ[¶lá-FÊøù矩ÊñÅ‹!‹ÅCCCQTT$Xi333ÏŸ?Ç… 3fÌà…p9rLJ©©)TTTPYYIA=z„‘#GD~õ8-- ÷ï߇ƒƒ«K—.ÄÆiÓ¦‘üTy$-- §NÂŽ;ÏõÕ«W‚y!2RSS©ý&ÜÜÜàêêJÕÍ^¾|I]põõõ…©©)ñ¬4äáÇT/BDDBCC©IÞŠ ©TŠˆˆª"žžž___j¾Ë—/S{ÐÉæ“6¶X,þ¬"TŠXÞT¢¿qãFêØåå娬¬4Ø>wÜŸÛ·T*ŦM›¨ûþâ 7nPÝeÙÙÙ¸víU9OKKÃDZtéRAùÛ·oñÛo¿ñb.›5kF>zô¥¥¥¼$*ùøË«W¯BGG‡TÖš0anß¾Mä;wîDï޽ɗeéÒ¥ð÷÷‡D"AMM Ö­[‡öíÛãûï¿´mÛ–÷`{þü9±xñb(++£uëÖ—D(t¨Ñ7n5¡ÿþý˜>}º`SE >¡_¨P¿ß´iSjHÚþýû1mÚ4ªüÿÜ),,Dzz:ïOV¦-** ˜4iubÌÌÌ¿|R©ÄôéÓs/Äb1öïß'''Á¸·ÊÊJxyyã !¥¥¥‡yO__Ÿ4…)**«W¯xÕZµjEJï%%%áôéÓØºu+ù²¬X±‚”‘ Ç÷߀€4mÚÍš5èQ£ˆSQQ˜˜˜ÀÙÙJJJr[nß¾ ^è†çpóæMÌš5 gΜ¡^£ÊÊJ…ƒÁ`0þ“H$¤§§7ZX“ÿ]kè…ƒ 8mÚ´áEüüóϸpá|||вeKLœ8‘üÞfffbΜ9عs'ºté‚–-["33“$ {yyÁÞÞž(Z£G&ÕÎ;‡V­Zñô TUU¡¨¨/^„««« Òììì 333Á ’’øùùQCcüüüðÝwß‘ÜYyª««Q^^N]œ=þ<:uêÄËQ^^ŽC‡Q ›ÔÔTÄÆÆRE=<<0sæLêuUÔˆ///666ToÀçšøRC…üüü0yòdjU®ãÇSó3ÊËËѵkWjØØ™3g0dÈjØØÑ£GѵkWjŽÅ»wï¨ÕÑîß¿öíÛ£_¿~‚ò'NP²ššäååaÚ´i‚Û†‡‡ƒã8RÀ !W®\Á!C=JuuuHHH@×®]›êêjòýû?3@¢££qãÆ ÞŸ,~ÑÇÇGð ã—_~¡–“ÕÓ¦•¥‹Å£G¨mPPFE½0ß}÷&L˜ øå...ÆèÑ£áää$Ø”%-- ‹/Fpp°à)22ÎÎÎðõõ%nÊaÆñê./^¼¦¦¦pssPŸÛ’ššJ*)899!)) ~~~hÛ¶-ÆÏ+,«ú wwwÁsä8NNN˜5kµÛ(ƒÁ`0ÿI>~üˆ+V S§N<#B*•R×’““±páBøøø gÏž3f çÃËË ~~~hݺ5 _¿~xýú5²²²0yòdxxxà믿P !SdW­Z}}}žRmllLí-ZÄ«%ÏÅ‹1}útÁ¼ÈÈHÄÆÆR«b?~ Ü6//'Ož$¹© CëÖ­©¡ßÛ·o§êNµµµèر#5>>6l˜àMQWW‡‰'büøñ¼d§^½z!&&ÅÅÅ9r$\\\xFƒ……‚ƒƒ1cÆ øùùáâÅ‹xöì€z7ÚÒ¥K±sçNüðÃÈÈÈÀ‰' GGG :ׯ_G||ùóæ >Œªª*,Z´±±±ÇèÑ£qóæM¼yó...˜4i222°lÙ2ìܹúúú8sæ üýýI•"kkkìØ±AAAxñâ‚‚‚Hžð?U‚æÍ›‡U«V FZDGG#66VPÑ///Lj#páÂÁ•ï°°0¤¥¥‘Ò´ ñõõ…µµµ PSSƒï¿ÿž™ ‰»‹Ëë?òáâ éÑ£‡àâªlÞ¬¬¬¨aNïÞ½C÷îÝ©cOœ8±‘Î'Ïš5k¨Çnll WWWA™™™ôõõ©Ê´ìØi4mÚ”$àÿÑmðºË£¦¦+++…ÛÿÙ±eÛÒ¶×ÑÑÁ–-[¨ùÿÎØR©TûscËÓäK{øtìØýúõ£º¼Æ‰'RcËôõõ©¹!ÆÆÆ011Qh‘ÚÚÚR]u7nÜÀÉ“'|üø=¢Z麺ºÔn§GŽÁÚµk‰g£!?þø#¶lÙBuÊ‚„<ééé˜4i:uê„_~ù…¼/+'•J±qãF|øðsçÎÅúõë¡­­ÊÊJøúú"<<‰‰‰ÈÉÉAbb"êêêàììŒI“&¡sçΤJBBxûVÔAžÁ`0ÿ<~ýõWõ ‘ÉÉÉx÷î>|ø€ÐÐPÒìÌØØíڵñcÇФI899ÁÜÜMš4AXXÜÝÝqøðatìØ»víBóæÍy¿kwîÜÁúõëqóæÍFú»wïàáá‹/òŒÁÁÁ˜>}:µÂäòåË ˜P-‰0hР̘1ƒª£È‡p7äõëר»w¯ ¬W¯^2dµZÓ¼yó¨y:t@ûöí©FÀرc1qâDjNÁ‡°víZêqÛØØŽØBÐ<+2hzYÇŽ©‰é@}˜œ"Ï‹¢±Ïq)ÒaÚ·oO]€­­­Å˜1c.Ð*ÛÈȈêêó‰hù%%%055¥†¬-^¼˜×wDè¼h å0|øpª±8wî\ª‡ ¨oZ)óÜ|qIèÍ›7§V2êÝ“4w˜ìáCKèÑÐЀ››ÕrkÙ²%¯ªDCÚ´iCm*¨®®777êͦ§§Á¼Ùök×®\]PSS#U·„,ÚæÍ›cûöíÔOnn.V®\‰C‡‘‡4±@›4A\\† ___Œ?žœƒ††8ŽÃ³gÏ ««‹aÆÁÃÃ<ô/^Lòiœœœ°qãF¨©©AWWººº¸pá¶lÙ‚èèèF)))ððð ¯å{¬õ/nß¾wïÞ žÓùóçJ­ðuøða’WÓˆˆÒ¼Hˆ»wï &1Ê8uꯢ<ÉÉÉ8uê”ÂÕ½»wïRåÛ¶mã50’'??Ô¢±±±8þ}úPK²ÊŒ.Zóc˜={6u5¿U«VX¿~=ue;33“×(N---lܸ‘jE û’7´ùÒÖÖV˜¨Ý¢E …aJöööÔsÊËËÈ#¨Û**Ÿ sæÌ LMMM¡ç䫯¾R˜0þ|ª ¤¤###ê‚´©©)i’-Äwß}‡Þ½{S円†Ôž' “×E")¢DÛžæéRQQQ¨'üøãǧÊMMMÿGæ¾ 6lØÀÙÛÛSåUUUÜo¿ýF•çççs©©©TùË—/îÿÕ«WTYYY÷îÝ»?=¶"ymm-÷æÍ›¿dì7oÞpµµµÉØïÞ½ãÊÊÊΧ¿¿¿àßÈ‘#9kkkÎßߟ³³³ã/^Ì­^½š»ÿ>W\\Ì8q‚ëÝ»77nÜ8nùòå\AA'‘HÈØ»wïæTUU¹µk×r%%%ömooÏõïߟËÎÎn$ ä´µµ¹;wî·¯¯/gllÌ=þ\P¾yófnÞ¼y\]]]#Ydd$§ªªÊݸqCpÛ7np={öäjjjåÊÊÊÜ–-[¯YFF€+--Ü6,,ŒëÔ©W]]-(;v,wàÀAYuu5§¦¦Æ½ÿ^Pž””Ä 2„z­{öìÉ]¹r…*×ÖÖæÞ¾}+(+..æúôéÃUTTÊGÅùúúRÇ655å>|H•÷êÕ‹ËÉɔ͜9“Û·ouÛ‰'r/^¼”íÛ·›‡ÎùøøÊSSS9 ®²²RPþøñc®k×®ÔûÿÛo¿å<==e¥¥¥.##CPËPÏËÌÌLáõ1bçíí-(ËÍÍåp‚ò!C†pcÇŽ¥î»]»vÜÒ¥K¯§T*åÔÔÔ¸;v>7&OžÌ5kÖŒ³··çRRRÝË_}õ7oÞ~ïïšT*”åääpéééÔmSSS¹üü|ªü·ß~£Þß"‘ˆKHH n›••E½?7'ÕÕÕ\tt4U^XXÈ%''ÿ%zDEEû—Œ-‘H¸ˆˆˆ¿d쨨(êóùß;..Žú;Ïq÷úõkž>ôGÆ~ÿþ=———G•ÇÄÄP‹?7ö§OŸ¸?RåÉÉÉ\aa!yý·2@ÿÝäæær[·nåFŒÁ aPP7nÜ8nõêÕ\JJ '‹¹mÛ¶qK–,á|}}9+++.44”7ÖÚµk¹ÎÊʪ‘òÈpVVV\PP bbbBUÂ6oÞÌÙØØp?ýô“ €6l˜ ÂpãÆ 7kÖ,ª€ûõ×_©È€x_byÄÆÆ†ªP·jÕŠkÛ¶-#ø4dÈÎÎÎŽj€Œ7Np¾dˆ©©)õÚZ[[s§OŸ¦ ¸ââbAùìÙ³9kkkêØcÇŽåŽ=J•7mÚ”KJJ¢ £F4&9Žã¬¬¬¸‹/R \XX˜ |õêÕÜÖ­[ d™qãååE5@lll¨†ì¶mÛ¸ 6ØÇq‹/æ6oÞL5@lll¨FÝ‘#GÈwí>§_¼xÁÙØØp»wï¦ ‹/\Hª­­åpÓ¦M£*o666œ““Õ±±±á<<<åzzz\‡¸¸¸8ªÒ»wo.++Kб±±áÜÜܨH‹-¨ÊŽºº:×¹sgA%.77—9r$gee%¨ 2„³±±áFŒ!hd´k׎³±±álmm GGGÎÃó²²â¢¢¢ ä^¼xÁÍž=›[°`ÉqÇEGGs‹-â®]»F­[·rVVVÜÆ9 •iƒÁPÄÛ„ñÏÃÐÐÛ¶mÃÝ»wQ\\LªVŒ=ׯ_ÇìÙ³±mÛ6,[¶ {÷îÅæÍ›±dÉ<|øÙÙÙ˜4iJJJHLñ×_ÀÀ@ÄÄÄ`Æ <7uïÞ½„ü7oÞlt,&&&>žú°gÏj²*.Bï¿yó†ÎallL k CLLŒ`¸<~üAAAÔc*++ã5ãlsíîŒ êö´sÎÍÍÅ«W¯xõõåIKKƒ¯¯¯ÂùzõêUöðáCjè¢ãúÜØR©?ýô54ÍÀÀ@ðþ‘¿–ŠŽÛËË‹fø¹ÐÏ}òäIRhâ†!>xð‘‘‘Ô9½xñ¢Âе[·n‘¦±Bc=z”z=xð¯_¿¦ŽÝªU+…!bêêê‚ÏÙ}òøñcÊ©ÍÊd±æŽŽŽ‚²#F`ëÖ­Ô^¶¶¶°³³Ã´iÓ¯©««+ú÷ï[[[^›ì;::âôéÓ8uêNŸ> ±XŒ°°0èéé¡G8p àêꊣGbÖ¬Y8rä>|ø@ò  €mÛ¶!88®®®(..¦†¶0 Æç`ã‹C]]ººº¼˜P555 <¾¾¾X±b¬¬¬Hܯ¦¦&¦OŸŽ±cÇbÙ²eð÷÷'e”µµµ±gψÅbüðÃJ¥xúô)† †æÍ›ãúõëðññá5 JMM…©©)\\\`dd„uëÖ5ÊQQUUÅÎ;áååÕ¨š‰’’fÏž¸¸8^ díÚµÃÌ™3bÀ˜1c ®®N͹pqqÁÉ“'‘–-[BCC£Q1yEFQÅ¢¢"ªqSUU…€€j΄¶¶65¹R,#66–jDØÛÛ£°°Ë^UUEÚÚZÄÇÇó ,44ºüüüÆÑÓJRõ }?~¤Êe]ŽiÇM»°° ý?;¶ŠŠ Z·n¤¤¤ÿõ±úk´UUU¼zõŠšw𹱩I¸JJJXµj~úé'ê³ãÙ³g¼fqò888àöíÛÈÌÌ”;99áܹs‚F¸ššV¬X7 æ{tïÞË—/‡‹‹‹à¹0ݺu£v¶±±D"áåCåçç£eË–PRR‚­­-&Mš„+V °°@}Æ¿þõ/4iÒ«W¯†««+ìììÈsçâŋĨéÚµ+<<<››‹yóæáæÍ›xôè1šš6mŠîÝ»ãøñãØ¸q# €ž={6Š3×ÒÒ"y~B ç ƒ ŒÿJã¤ÿþxüø1ôôô)‡FTT/)QCC{÷îEnn.Nž<‰ððpÒ¼ÇÐо¾¾ð÷÷' îíÛ·1qâD¨©©aûöíJ¥$‰´¬¬ AAAPRR„ `ooÏ[}üø1©Ø±lÙ2ìÛ·O0ñÛÕÕ555‚åêttt°|ùrª¡0eÊTTTZÚò4mÚ...Ø¿¿`2¯™™ôôô¨Iø®®®8rä***•Ú±cÇR\:::âÌ™3Ô„q;;;øùù ÊŒŒŒðæÍꪼ._¾L5P444¨JçäÉ“‘™™‰ˆˆAùüùó‘’’BM~VRR¢*ëC† A“&M¨ ãÚÚÚxÿþ}#V†T*ÅÑ£Ge={öDÇŽqçÎA¹––222ï/ ,Z´GŽܶ}ûö:t(µhAß¾}¡££CM¬677Ç¡C‡“ºõôô0wî\j1†Î;£eË–¸zõª |úôéPWW¼ÖJJJèÖ­ÒÒÒ“ºŒŒ°lÙ2ìÞ½[иïÝ»7 D5”G MMMª1;oÞ<„„„ <<\Ð@Ù²e N:E5*·nÝŠ/^ðŒaùïËÁƒqëÖ-r]ž>}Š~ýú‘dè¥K—ÂÚÚ(--E~~>òóóѽ{w¨¨¨ OŸ>عs':Dä«Ý¨¨¨`Æ pwwGxx¸`QÙ8K–,Á¡C‡ØƒÁ`ƒñ9 qÿþ}Ì;·‘ràëë‹Aƒ5RªÚ´i???8pÁÁÁHOO'•-”””àé鉳gÏ"""b±ãÇ' Á°aÃðøñcb¼<þƒ "ŠÔˆ#°bÅ ²¯””tîÜM›6…££#.]ºDVcoܸAÊò}ûí·PQQ¡†èlÙ²Û·o”õèÑ.\@ZZZ#™¾¾>–,Y‚ƒ *Ü&L€²²²`•$eee¬^½šþÒ¡CÌ›7»ví”ËzÖÐPtN½zõBbb"uU]Ѷ2£¦TöèÑ/^Äû÷ï©cß¹sGp¾Ú´i%%%êŠú²eËE š2e ž #êÔÕÕ"¿sç©z¤¥¥…•+WâÛo¿%¡y¤,¥¡¡!N:…'Nï üs¨÷ààx IDATÚØØÒ¢………¼P¨öíÛÃÏÏ;wî¤ÆíÛ·Ghh¨Â~[ ƒÁ ã‰^½záéÓ§èÔ©S#…ëþýûøá‡Wÿïܹ—F¡M:::xüø1¦L™‚?"//W»{ëÖ­PVV&¡GOŸ>% ~ˆvíÚá矄„„à›o¾P_¶ðîÝ»ðôô$+½îîî$œbüøñhݺ5Nž<)xžžžžÔxó±cÇ¢¦¦=¢nKS,ûöí‹û÷ïSË[[[#22Rpå|øðáèÕ«¼¼¼·íÖ­Äb± Â­­­ü‘zN033£æX[[SÏI¦*’‡……QsÍõçö­h¾þݱˆôôtjÈœµµ5víÚEÍùùÜœ|óÍ7T¹¬W,THh[ÚwM¶oEåØ?'W4oí۷Ǻuëxrù…ƒ¯¿þVVV¼0±ØØXôìÙ“_ƒ&ý¦~ûí7^¹Ìþýû£¤¤„„‰………¡{÷îÄcûí·ßbÆŒ$¿¬Y³f¼îÒºººX¹r%<==©¿Å‹ÃÁÁÎÎ΂ò¶mÛ"44ô³=>×Á`0˜Â`ü/ѵkWÁîZZZxðàfΜ٨®¼……>Œ•+W6þ)+ÃßßëÖ­T¸V­Z…Q£FbbbЫW/";{ö,ž?N’‰?~üˆöíÛ¨ÏméÙ³'^¼x¨®®†šš‰»n¸{÷î]R{Þ¼yøøñ#Y=vìñÄhkkcÔ¨Q¼æwïÞ‘NÁzzz ¥®P+ò6L:‰DÔmi^ ªªŠ*_³f ÊÊÊÇnݺ5,--sndÆ‘‘uE¿S§Nxøð¡ ¬E‹ppp ®ŠëêêÂÐÐ:_“'O¦æ¯(++ã‡~ Ž­¡¡SSSêœ(¨_íW4¶‹‹ bccåÍ›7GDDâââåS¦LQ¸ï)S¦P÷-k«Èã5~üxjžÉ˜1c ¥¥ÅËÝÊÎÎ&½-Z„øøxbzyyñš¨mÚ´ gÏž%¹=÷îÝãÕäß¼y3/Œëùó缎ØvvvxöìIÄöìY<ê“ô###I~Xnn.ZµjEäË—/Guu5Μ9#x~3fÌÀ¿þõ/lÚ´‰:¿Ó§O‡¿¿?  ð0 3@Œ/===\¾|™òôïߟÚäiáÂ…8p `…©îÝ»ã_ÿú¶nÝÚ(„HKK cÆŒÁ¼yóÔ'T˺—*++cÍš58qâ*++QPPÀKÎÿꫯ`iiIò*d «2åqùòåd·¤¤Mš4!1ßK—.E`` QÀHª.]º`ìØ±8|ø0 S‘éÔ©D" ’7|”••±hÑ"^#¼œœÒ ÌÈÈHa¼U«VQ›èéêê"55•*µjÕ*œ={%%%dÍš5Cûöí© ­ 233C¥TTTàââ‚>ætéÒÄ“Õkkk¨ªª æìÈ âÌÌLÁÕnCCCL˜0šOaaa.]ºPó):wîL5•””еkWªÜ®]; 6 çΣŒ ¯§H$"ÍÊdÕ“ä«€UTT@SS***X·n233Éœ;vŒ4¸RUU…±±1¼¼¼ ‘Hׯ_ÇÔ©S‰ñÔ®];Þõ|ùò%QƵµµ±lÙ2âM‰DPUU%÷¿¾¾>æÏŸOr°ªªªP[[Kš°víÚ .$94ééé<¯©¹¹9F…£G‚ã8TUUñ¼ijjbÖ¬YÔ†t:::ðõõ…é ÞðÚ,Z´›7o†¦¦&õû²páB^…?ƒÁ`ƒñ_ȶmÛ0iÒ$AÙ¬Y³Ð§OŸFï«««ÃÓÓû÷ïìŒ=~üxÔÕÕ ÆòwèÐ-Z´ ¥ÐÔÔ„££#âããÁq¢££yûŸ:u*ŠŠŠðäÉ|‰ FŒAB¸êêêP^^N”Çõë×ÃÛÛ›(‡YYY066PŸ¨«­­MVŸsrrx]nÇŒƒàà`â8zô(ñ¾´iÓsæÌáy"ä¼ÍÍÍ‘––F’¶£¢¢`iiIäëׯç}¾¦¦†tlíÒ¥ rss©eoׯ_ÏK쯫«#ÆžÌiXÑL†‰‰ ©»  @0Yf xyy‘UyùÊWC† AïÞ½IrlFFOéìÝ»7/©úĉX¶l9æM›6ÁÍÍȃƒƒ‰§eË–èÝ»7QÆ_¿~Í _0`ïœäãþ`÷îÝd>Äb1ŠŠŠˆggÀ€¼ÞEEEÐ××çm+?vZZoEÝÆÆ†Wþ866–„Ä 0qqqÄC"S¸ÕÕÕÉØ›6m"ç™››Ë+wÜpì'Ožðbÿ»téÂór¤¤¤C ÿþˆ‰‰!Õ®rssy•Ûú÷ïÏ›ï†ìÞ½[¡|Ïž=DÎqÊËË¡££ Þ¹~ýz2o>|@‡x÷ÂØ±c±oß>bË®Œ7zzzÔJ_ݺuƒ••¯ìmC,X@õ.ihhÀÑÑ?üðu{E!‡2ƒ–Ç%_2 3@ ###ªbooéÓ§S ùjYòôîÝ–––‚±øM›6…““~üñGÁmgÍšAY¿~ý`ff&X¾VSSk×®ÅÑ£G!‰UÚ±´´Ä¤I“HC¹¤¤$b€(ò µ¬ß,TJGG‡F2`ÀžQ’œœŒÎ;¨9JOOÇíÛ·ÏÉÂÂYYYÄ Bß¾}‰Ò«W/jòýÈ‘#ѯ_?ÖÓÐ@­8Õ¢E 8;;eº¡ÁÖ¢E ´mÛoß¾¼ÿ&&&<£Œ6vCE¾¦¦ÇDKK Ý»w'ác ùóçSûÂÈ®mßÍš5Ö-[xFĶmÛȾÍÌÌ0þ|¼yóðæÍRâ¨o°7pà@²ÿ›7oò*:ÍŸ?:::ÈÌÌ„T*EYY ƒ777äääP½»wïÆÞ½{©^ˆÏ@K—.Å“'O¨¤%K–ÀÛÛ?”=š$¯ÓΞ=Ëëi$4ÿ ƒÁ ƒñ— ¦¦†“'Oò4òETV†›› }iˆƒƒ¯º–<&L@pp° ÅØØ}úô¡VžRÔ˜pÚ´iÈÏÏ SQQA»ví¨†À„ жm[â‘)RRRœ9sÈ~•””ˆB ÔWø Çq꫃ :”Èœœ°{÷nòZ>öâĉˆ‰‰á…;ÙÚÚ’ÿׯ_???Ò{Áßß .$ÆœŽŽ Y€¼¼<¨OúÍÎÎ&ÀNŸ>M¶URR‚¹¹9ÒÓÓIe'ù¢Ž;¢W¯^Ôù9r$444Hφam]ºtA~~>ñÉ—Š600À˜1cx¡iëׯ'ÿ›™™¡mÛ¶8{ö,™Où„éqãÆ¡¶¶–„J]¹r3gÎ$çµbÅ ”••%_þZ)++ÃÌÌŒ„:É_ghÒ¤ ôôôpâÄ õ9NòíTUUQWWGÍŸQWWGvv6ïš4Tð,X@5 ,,,0hÐ j¹Ù>}úÀÒÒ’Z®VMM ëÖ­£V@€_~ù…癑GII óæÍSh1 3@ Æ_ŠŽŽé!Ò6mÚÀÎÎNPÖ«W/ÞÊqC¦N*ب¯$«²ÕKKKjþ PŸØMk¸jÕ*œ?^°ŽŽª««qéÒ%Ám'Mš„’’Á¤îV­ZaúôéÔýþ¿öî3>Š*løð?›Þé´EšôÞ•®€ˆR”"(MÉ"]D5€HUPià#¢ˆiI@: !$”PB ¤÷ºï‡<™—…Ýb ûú’_vN™93;;÷Ìœs¼¼¼¸ÿ¾rAœ’’¢5jYQV­Z•ììlehÚ ]Û{ðàAºuë¦\è[[[+ÁÍÃyÇŽËÁƒ•å«W¯Öê„üÎ;ï°uëV¥½ì¼okkK•*U”ÀÈÏÏOëÎøàÁƒ¹zõ*ÁÁÁüôÓOŒ9R+hûóÏ?•€ïÁÉç@û)Hrr²ÖS{{{ìíí•ÎýqqqT©REk\¼xQïœ!“'OÆÏÏOﻓ&MÒ;!baþ¢–Ïš5‹åË—ë<¾ ©W¯_~ù¥Î9bÌÍÍ™:u*ÑÑÑzËŸ:uªÞï$À«¯¾ª÷©&<ÝÒ÷ôòÁï¶Bˆ €œ;wµZZ­Ö9ˆÏ“‡è}Ø7ß|£Ì²þ°Q£Fé¹ FË*œíaÎÎÎ >\礅mÛ¶åèÑ£:/>---©ZµªÞ»×E ×[«V-õN&7pà@V­Z¥ó¢¶U«V4nÜXï»ó£FÒ9Váé´iÓôëììüÈÌúøãK=áa£F¸|ù²r7ýÚµkZ¯a}üñÇzó>®ì† rãÆ ½ój4lØPïìà…u5ùÞǬwÈ]SSSfΜ©w¹³³3mÚ´Ñ;ú™··7ÎÎÎê\>dÈô“ìããþ}ûôܪU«"_sª[·.o¼ñ†Þå...|òÉ'E¾jUÔ÷V!D @š5k†¯¯/¾¾¾tïÞ]öˆzXYY)ýt]DùøøP§NG–1eÊ”GFñ)4`À­‰Ô¾pmÞ¼¹ÎÅÜÜþù罞žžžZý9TÔdq:u"88Xï»ý;w& @yMëAõêÕ#<<\o`ÔªU+nݺ¥ó®¸ƒƒuêÔÑê¿ò 5j`gg§ô}ѵÞú^çqttdîܹz'ÐsvvæöíÛzƒ²¢Ê†¢'ç«V­~ø¡Þüîî¹)}9t_GŽÑ; A‹-8sæŒÎe…ë-_¾\çPÃÕ«WgàÀJÿ}Û^”;Æ?ÌÄÄ­WÇöÝwß` 4è‘þ@B!*q"„øo¨Õj½#põèуvíÚé½ð}ï½÷ô–[Ôdf}úôÁÛÛ[땞BU«Vå7ÞÐûz—››ÆÆÆZ£Z=¨¨'(d÷îÝ:¼úFêÑ£aaaÊ(ºò†……éR·^½z8::ê þÍ7ß$&&FoG÷úõëk ýûp{½ð zÛëå—_ÆÆÆFo`åååErr²ÎÑ ƒI}O)<==ñôôÔ»ÞÍš5S†zÖ¥{÷îøûûk %üp{èÐ!½O¦†®õ4èaï¾û®ÖW–––:—ûûûÓ¹sg½ù‹Z~éÒ%œ¥SµBˆg’<BˆRhÑ¢E‘Ë‹ >·¼¨>"B!De'}@„B!„€!„B!$B!„B @„B!„€!„B!„¢X£`ùûûãèèHÆ ‹LwòäIT*-[¶ &&†Ë—/P«V-ªU«&-.„B!Äs¬È' ¹¹¹üüóÏ$$$pòäINž<©7íï¿ÿÎõë× gïÞ½¬Y³†ÄÄDY·n¹¹¹ÒâB!„BH¢ÛÝ»w‰‹‹cÀ€¼óÎ;lÛ¶MoÚC‡1tèP† ÆþýûHHH`À€ 0€¬¬,òóó¥Å…B!„xŽ)¯`Ý»w-[¶( ªV­J«V­ÊT¸««+Ë–-#//C‡i-Û±cÇ×úìèÑ£ÜK!„Bñ  ¶¶¶ 0@Y`ffFvvv™ ÿý÷¹w†ÄÄÄh-2dC† ÑúlÖ¬Y$%%É^B!„âY@LLL¨Y³¦ÖÂÌÌLŒ âÎ;ôìÙSYö÷ßóǰbÅ š6mJ`` yyyÊSŒììlIOOÇÛÛccciq!„B!$ÑÍÌ̌ɓ'óÓO?QµjUºwï®,óòò¢wïÞÊÿ£Fâ×_ÅÐÐ#F}@‚ƒƒ±°°`ìØ±ÅZ¡¬¬,eÏ!„Bñ ±´´ÄØØF£©(+5kÖ,–,Y"{G!„BˆgÌo¿ýÆ«¯¾Z±ÌÌLÔj5‹-*Uþ   ®^½Ê믿^⼆¹sç²páÂRÕ={öìR¯wzz:_ý5üñ¯»,yW¯^Mß¾}©^½ú¯Û××—#FàääT⼇"//—^z©TuñÅ|ðÁXYY•8ïÞ½{±±±¡C‡%Î{÷î]~ýõW&OžüÄÛûÚµk>|¸ØO2+Ê1ú4ë.KÞ-[¶Ð¤I“ÇνTuÿðÃtéÒ…Zµj•8ïÙ³g‰ˆˆàµ×^+qÞ¼¼<æÏŸÏgŸ}Vªõ>zô(IIIôíÛ·ÄySSSY¾|9}ôÑoïû÷ïóóÏ?3uêÔJuŒ~õÕWŒ=GGÇ'^÷çŸÎÔ©S±°°(qÞ={öààà@»víJU÷G}ÄgŸ}†JUòyœwîÜI­ZµhÖ¬Y‰ó†‡‡Ș1cžx{‡„„ðï¿ÿ2tèÐJuŒfggóÅ_0þüJµÞëׯ§Gxzz>ñºW¬XÁ!Cpuu-qÞ€€ÒÓÓéÕ«W‘é Ÿ€Q˜™™ajjŠ]©ò[[[caaQªü¦Lu—%¯‰‰ fffO¥î²ä577ÇÆÆæ©Ômff†­­m©ò[YY‘››[溭­­Kœ×ÒÒ++«RÕššúÔŽ›R·žæ1ú4ë.K^ ¬­­ŸÚ÷º´u[YY•ú8ÉÍÍ-Óz—å{mhhøÔ¾[ÙÙÙ•öü_Úsð±Þ¶¶¶XZZ>Ñsðƒë]š¤,ßë§y.˵ÕÓ} VN¥bàÀtéÒWWWÜÝÝøþûïµ&AB}¶nÝ t¤œ1c†Ö²üü|~ùåÔj57oÞ FÄÛ³gjµšÐÐÐ »=Å‘M^^^…Y÷ùóçsãÆ§Vÿ•+W*ü«’ìß/ˆÔj5»wï¦ð¥†;wî V«Ù¾}{‰_9Ý·o[¶l‘“‡:|÷Ýw¼÷Þ{téÒ…zõêD§ô˨Zµ*]ºtÁÝÝ»wï2a @Š#**ªÜV$55•Å‹3mÚ4åq–¡¡!Í›7çßÿåèÑ£Œ?€™3g–©³¹âùqêÔ) `ô²/¿üRkYLL ׯ_Ç××___ `èÆcÇŽáëëËš5k*ìöÇöíÛûÔùI eéä^V111J YÑ×’^ùúúrîÜ9RRR€‚y:|}}‰ŠŠâöíÛ%*¯gÏž >\NB”Á‘#GˆgàÀ,;~ü8¹¹¹>|ø¹mŸ Ó =//˜˜¦OŸNDDÎÎÎôêÕ‹‹/ræÌF%G³â±®_¿Î÷ßOFFîîîÊáÕ«W³}ûv½w«tMÜ´hÑ"222X¶l±±±4mÚ”ádztéRÌÍ͹yó&ÞÞÞL˜0+V(wø«U«ÆÔ©S6l^^^¤¥¥áêêÊÔ©SÙ±cgΜ F™2e ûöí#00(®sÒ¤I:‡\ÎÉÉaÉ’%DGGciiÉ»ï¾KLLŒrçÜÌÌŒ1cÆpãÆ ¶lÙ‚ƒƒuëÖeÞ¼yZ\¥¥¥áëë˰aÔö2dÕªUcݺuÊÅl¿~ý°±±áÇT††ìÞ½;ýúõ{dý233ñõõÕj¯‘#GrèÐ!¾ýö[fÍšEëÖ­ÂÄÄ„5kÖpåÊ¥i‘= IDAT½j׮ͮ]»ÈÈÈ 66–nݺѩS'¾ýö[âââhÛ¶-¯¼òŠÒ^ÖÖÖDFFê=¶<¾ ÛëA³gÏÆÔÔTë³ &è*}ß¾}øùù(íeggÇìÙ³ÉÏÏgùòåÌ;¢¢¢”ã+##ƒŸþYi¯·ß~»L#D ñ¬ILLäÈ‘#øûû€¿¿¿Ò9}äÈ‘$''óÕW_ѵkW @ÊC“&M¸páGŽáÆZĆ gÑ¢EØÚÚ²zõj夨ÑhÈÎÎfÉ’%Œ9’£GbbbB»ví äüùóäååaee¥÷EñüùçŸ4h-Z´àîÝ»ÊS &(ˆ,\¸ÐÐP<==yýõ׉‰‰áóÏ?çĉÔ¯_Ÿ·ß~›˜˜nܸÁ°aÔóVáÅiûöíñññaåÊ•;vLy¤¾jÕ* `˜ÕÙ³gciiÉÇLff&§OŸfÙ²eÜ»wcccöîÝˈ#€‚1äoß¾­3144däÈ‘¸ººâïïÏÙ³g ä•W^ÁÀÀ€ëׯ+3&ÇÄÄРAš7o<ÝÉËËcéÒ¥Lœ8‘ÌÌLŽ?N5”aUÿçþ‡ž={bccC·nÝ€‚œGŒA­Zµ”»}||t äååñꫯ(ó[tëÖ¸¸8rss•´Ì›7333åé#GŽ0vìX6nÜHff¦Î h[[[¥???nݺEnn.ãÆÃÉɉݻwsùòevïÞ­´õ¶mÛô7!!!tïÞsssT*NNNìܹ“qãÆQ»vmÂÂÂøé§Ÿ´^kËÌÌTò·k׎zõê)íõÝwßqõêU>ùäœY¹r%ÑÑÑÄÇÇ+ëýóÏ?Ó¥K4 ¾¾¾¤¤¤0eÊòòò˜6mšR¶¥¥%Ÿþ9ׯ_W¶¥°½>ýôSøè£X¸p!K—.% µZ­<ÙÓåâŋʺcee…™™¾¾¾Jù…ûôÝwߥzõê\¼x‘€€¢££éر#¶¶¶Ü¿??? @ÄsaÒ¤I¬]»–ºuëªü6ôéÓ‡ ТE  À€”ïkçÎ  55 ²²²žêág>±´´däÈ‘øùùѬY3­Q°:tè shÏ_|Fƒ‘‘¯½ö©©©ÊyaTY8Bbb¢|„:5áWÍš5Y°`›6mâõ×_ &W[ºt)Ÿ~ú)o¿ý¶’633S9×<ø¹‡‡“'O ú\¦+ &7c³©©)*•м¼<%o›6m¨Y³¦Îô:'(LLLÄÀÀ^|ñE­e¹¹¹¤§§+“111ÊÓ €””¥î1cÆIjjªòÙèÑ£ÉÉÉQ¶·(666tïÞ˜˜% Ô7.½ƒƒÃ#Û’““£Ô;pà@½ûpݺuÊxùwîÜ :x5½¹¹¹Þþýû÷çèÑ£$&&’žžN|||±¥sçÎqâÄ ÜÝÝIJJ"''§àÖÈH™mòäÉ\¹r…ôôteûFŽ©ýƒld„±±1†††Eš7o Jð0}út"##[Æo¼¡<‰»}û6666z÷•®}Ÿ””¤üV^h ñ¬«S§yyyJðñà(X>>>:ÏÝï¼ó:uâï¿ÿ&11cccF-Hy233ÓyrÒ7ùÒƒ³VêÊ׿ù!tjÑ¢7ndË–-ØÛÛ+œ«W¯Vî öÙgÅžÔËÚÚ///üýýx÷Ýwõ¦mÓ¦’îµ×^Ó›®aƨÕjå‚}Ú´iôèÑCÉÛªU+½C;æää°|ùr155eܸq8::*¯¹¹¹)çÍ-Zðã?²mÛ6† FÇŽÙ¹s'ÇgÕªUôéÓ6nܨ¼úÓ¿lmm TÖgÁ‚\¼x±Xí•••ž}û”‘a Ÿ¬:tˆüQ¹Ë^øTæa:tPêíÝ»·Þy ŸEv´ïÝ»·ÒÖéééôìÙSgº°°0>L~~>††† :OOOÖ®]Knn®2ÃzóæÍÙ°a[·nÅÞÞžßÿ-ZpûömÂÃË’ÓÙÙggge½§L™‚••ÙÙÙ¨ÕjÌÌÌ”ÀM777e[Ê2ñb¡3gÎ(ëbnnŽ™™™Ìž=›€€¾ýö[Þÿ}y_zé%¥ƒ»­­­ â¹R¯^=å‰çƒ^~ùeé ì_zé%i@J8È¡C‡”GòB!Äó"--/¾øBëIƒBˆÒ)Ñ(XÿÅ!„¢²122’Ù …â?òDfBB!„Bx3¡ !„B!„ B!„B @„B!„Ï®ÿlÞÈÈHV¯^J¥b„ ¸¹¹éLÏš5kˆ‹‹cÒ¤IÊ8îB!„BˆgßödõêÕÌž=›iÓ¦)3šë²fÍÆŽË—_~É–-[d"A!„B!ž#ÿÙÔÔTe¶ßääd½ébcc•‰ŒŒÈÊÊR–íÙ³‡ƒ>’§iÓ¦Ì+„B!„xŽÿB¿~ýèׯŸÖgK–,aïÞ½€!„Bñ øÏ^Á²²²"--äädlll”ÏãããñóóSþwvv&66–¼¼III¤¦¦’““£•6>>ž¬¬,RSSu–%ˆB!„âaaaüøãܹs€ÿý—f͚ѦM>ÿüs¶mÛÆÌ™3ñññQòLœ8‘k×®1mÚ4Þ|óM @„B!„xV]½zõ‘¿ùùù\¿~½Tå9::Ò´iSlll ãøñã¼úꫤ¥¥áääÄŒ3}šÈÈH<==iÒ¤ Ç'&&ooo4h@@@ñññ4hÐooïÕÂõë×qww§U«Vdgg³wï^ºuë† †Ý»w+yš7oNµjÕ)«B>III!88˜àà`¢¢¢äèB!„â7oÞäý÷ßÇÎÎŽ™3gòË/¿0{ölììì˜8q"¿üò .ÄÊÊŠ1cÆðË/¿°|ùr 9r$YYYÅ®ëþýûœ={;;;æÎË… Xºt)§NâÊ•+|òÉ'h4üýý±³³#,,Œàà`åUÈ' ÉÉÉÊ ß½{9Ê„B!„ø?iii <˜.]ºpýúu"##yë­·èÒ¥ ƒ&22’÷ߟ=zpöìY"##™>}:mÚ´áøñãäçç»®*Uª0zôhéÕ«ÎÎÎÄÆÆ²dÉT*Ó¦M@¥RáëëKNN{÷î¥ÿþ•'ñðð`Ô¨QÄÄÄpîÜ99Ê„B!„ø?NNNüÏÿü‰‰‰øùùáëë‹Z­&""???&MšôŸÖ—››‹½½=ëׯÇÅÅ…V­ZѧO¬­­éСƒVÚ={öЯ_?½eI't!„B!*arðàAºuëÆØ±ciÓ¦  C‡Lœ8‘*Uª”¹Ž'N V«¹téFFF$$$`iiÉñãÇ6l¿þú+-Z´`èСZùŽ;F»ví$B!„âY‘žžÎñãÇ gäÈ‘$''HTT#FŒÀÁÁo¿ý–°k×.<<>žS§NÑ«W/%MyŽ‚uöìY¬¬¬¨[·.Pð´ÄÙÙFƒ»»;æææ€!„B!ž>yK!„BñÄÈD„B!„BT2)))øùùÁôéÓ‰gÒ¤I¸ººǼyó8xð ––– >\–×ÅÅCCCÔj5jµX²d‰ÞºÒÒÒXµjwïÞ%::š•+Wòï¿ÿ²xñbÌÌÌ6lƒàÚµk¬_¿žÐÐP¾ýöÛÊ3¡B!„B?CCClllHHHàÊ•+4jÔHé4‹™™)))=z”Aƒ±|ùrسgãÆcùòåܸq£ÈºT*Æ Ã××—:uêpëÖ-vìØÁêÕ«ùî»ïØ·oŸ’ö÷ßçÕW_eøðá>|Xwy²û„B!„¨\,,,èØ±£Ögµk×Vþ:88ЪU«G–›˜˜P£F å ÜÝÝ‹¬ËÜÜ777FM³fÍxñÅQ©TœýôS¨Q£ÁÁÁܺu‹Å‹séÒ%V­ZÅŒ3”<þþþlÞ¼777NŸ>-ˆxz—†B!„('§NÒú«kyFF!!!ÊÿÉÉÉ\¹rEgú† 2eʪT©ÂæÍ›™?>ܺu ^}õU^ýu4hðHÞ‡®Hhh¨Ò1fÏž=r4=nß¾M`` K—.•B!„(ƒèèhfϞ͵kר´i7F¥R¡V«ñðð ##ƒåË—sìØ1öìÙCÏž=¹rå Ó§O§K—. 6Œ£G2sæLe.‘‡™˜˜`gg‡¥¥%W¯^E­V“ŸŸÏ‹/¾È–-[ aذaòý÷ßÀˆ#X·n{öì¡_¿~:Ë•y@Ä™3g3f >>>,[¶LE!„â9$¯` !„B!ž™DQ*þþþtîÜ™ÿýWWW¥Q„Bˆ'(77—S§NÑ®];öîÝKXX7¦[·nüöÛoDDDвeKÚ·oÏöíÛ‰ŠŠ¢}ûö´lÙ’›7o¢Ñh¨Y³f‰ÿ333Y³f #FŒ J•*h4–/_®¤íÙ³'õëפ y"„(•]»vpâÄ ¢¢¢¤A„Bˆ'(::¥¿ô¹sçX»v- à³Ï>cÆ ìØ±ƒ~ýú1}út6lØÀèÞ½;“'OæÐ¡C¨Õj._¾\ì:ׯ_ÏêÕ«•ú,,,0`666Zé €™™ÑÑÑ:Ë‘D!‘‘‘ÒBQ‰¸ººòå—_*ÿgeeÑ¥KjÖ¬I‡HII¡GÔªU‹–-[’’’Â;ï¼C£FèÞ½;mÛ¶eüøñÅ®ïÖ­[ܸq{{{þþûo:DNN&&&àãヽ½=ÑÑÑtíÚU!„ºŽNwèÐ!|}}¥A„¢’©]»6@­VsâÄ ^zé%vìØÁ|Àµk×°µµ-q™ÙÙÙ$&&’••…¯¯/ƒ ÂÔÔ€yóæ1sæLFŒÁ;w´òíß¿Ÿ—_~Yo¹€!„P„††ràÀiˆJ.!!“'Oàçç' "ÄsÀÉɉ?ÿü“¾}ûâããCƒ ðóó£gÏžøøø`nn^â2/^¼È²eË8xð aaaüù矜>^™ÑËË +++^ýõǾî%ˆB!„OÐÊ•+Y¶l ddd”ª 333š6mªõYað`ccóÈèTuêÔÑú¿4Cè{xxP½zuªW¯®|îééYì2¤ˆB’’’8tè4„BK–,!))‰ððp%¿¿?+V¬ cÇŽ•ë ˆB!„B¿{÷î±råJfϞ͑#G€ÿ?ñ¨¾ HýüüHKK#00°Xu´iÓ___š4i‚J¥bÙ²es÷î]¥Ž5jàììüHÞV­Zé-·R ûk×.NŸ>­÷1ŽB!„Ï“œœ"##Q«ÕÔ¯_Ÿ1cÆpæÌÔj5ýúõ#77—µk×’››Ëž={4hK–,aΜ9L™2…   ~ÿýw `ÈÞöíÛë­ËÁÁùóçàííMõêÕÙ¿?jµšyóæaggÇ÷ß··7'NdÑ¢E˜››£V«+o’““Cnn®iB!„Bîîî¬ZµJë³÷ß_ëÿ+Vhý?wî\­ÿKÒ ½Ð°aÔѰ =øa°¢¼‚%„B!„xb$B!„¢Ú±cjµš””~úé'Ôj5;wî`íÚµ¨ÕjöìÙÀ²eËP«Õ8p€+W®è«CŸÂ‰ÓÒÒP«ÕÌräÈÔj5_}õ• B!„B<+.]ºÄ?þHß¾}Q«Õ?~???|}}ùþûïY¾|9AAA,]º”Å‹³|ùr¢¢¢X°`sæÌáàÁƒÌž=›ˆˆˆb×ùõ×_³eËÔj5½{÷æÍ7ßÄÇÇ(˜+$11___’““ùùçŸu–c$»O<).\àÊ•+\ºt‰‹/Ò°aCi!„B)( ccc,--Ù±c£Gæ…^àÞ½{Ê+Q¯½ö—/_fÊ”)äåå)“–D\\ÁÁÁÜ»w­[·òî»ïbhhÀ;ï¼Ã¬Y³7nýû÷×Êçëë˵k×ÈÎή<Hnn.‰‰‰$&&jͬ(*¯ÀÀ@:vì( !„BñÈËËcÛ¶môéÓ‡FaccêU«hß¾=Ó¦M£jÕª¬[·Ž¶mÛ2uêTLLLÈÈÈ@£Ñûúº0¹|ù2!!!¬\¹’€€®_¿NóæÍÙ¶m=zô K—.JžÄÄDþüóO^{í5¥ïÉÃ*ä+XlÞ¼€cÇŽÉö W !„Bˆ²¹rå Û·o§yóæ¬^½šO>ù„ 6(¯W]½z•-[¶Ð·o_š7oŽ©©)ãÆ£C‡„„„pþüy6mÚ„F£¡J•*:çÛóööÆÛÛ€N:àãプ—»víâüùóÌž=SSS¶mÛ†§§'óçϧ~ýúœ8q‚5kÖTž¤víÚÊøÁK–,Qzê !*†   ®\¹BHH§N’>=B!ÄT·n]¥“·‰‰ &&&¨Õjlll€‚ʧNеµ5 6äï¿ÿ&77333T*ß~û-æææÅ®wÑ¢EôìÙ“Þ½{cjj À+¯¼‚‘‘»wï&##CCC¥îJ€!*¶¼¼"…Ó YYYiýobbRâz ƒ ­Ï ;¢JP¢tBB”IFFfffÒ•Xhh(õêÕàîÝ»ôéÓ‡àà`i˜J,99™ÜÜ\’““122’þ”Bˆ E!„xÎÅÅÅáèè éééIll¬4L%¶qãFn߾͆ ¨V­'Ož”F©Äbccqttä?þ ""‚   iQ©É+XB!„XBB666;vŒÌÌL­Y§EåBãÆ‰‹‹ãìÙ³4kÖì¹ky"„B!ÄSâîîÎÝ»w%B!„B”¿¶mÛrüøq @„B<_ìììHII!//OC!„ B!Ê—……™™™äççKc!„xúÈØ±c‰ˆˆPþ?þ<Ó¦Mcîܹܼy(ÆqæÌ™Ìž=›°°0½eݹs‡O>ù„©S§rîÜ9ÙB!„BHR 33“•+Wâèè¨ÜKKKã×_eñâÅÌž=›õë×Cþ-X°€yóæ±qãF½e®[·ŽéÓ§óÕW_ñ×_'{A!„Bˆç„2 ovv¶V|333lmméÝ»7{÷îU>ÏÏÏG£Ñ`dd„‘‘©©©dee)³fddè­099Y™–]¥R‘››«,Û³gÔJæÌÙKB!„B> `•ÄÄDòòò”uîÞ½ËÞ½{;v,5jÔàæÍ›xxx………ì!„B!ž·D—„„,X@rr2W®\¡zõê̘1>ýôS˜4i~ø!_ý5†††ZLrr2ÇWñãdzfÍî޽˜9s”×±„B!„Ïyboo¯¯ï#ŸÛÙÙ±hÑ"­Ï¬­­™?þ#iëÕ«Ç?ü üonnŽZ­.ÑJvíڕÇÓ¶m[ÙcB!„¢RS©T<·s/UŠy@œœœˆ•£U!„BTz–––‘””$HEÖ¨Q#.\¸ G¬B!„€<™äâÅ‹²Ç„B!„¤ü5lØPJÎÍÍÜÜ\¼½½‰‰‰‘B!„¤â²°° _¿~ìܹF#{®úðÃyóÍ7éÝ»7û÷ï—B!„¤bkÛ¶-AAAEδ.*.###êׯ/ !„B!HåñÅ_ðõ×_/{¯«S§W¯^•†B!„xÎUÄ•ŠåŸþàÒ¥KDFFòÛo¿)Ë===™ç¤¤¤```@jj* Ò0•Tdd$.\ !!œœ9çVr7oÞäêÕ«ÄÅÅE`` ÉÉÉ>óÛÞºukÜÜÜ0ÐTÀñññ„„„°mÛ6Ž;†±±ñcó¥§§“••…½½}±ë177ÇÜÜü±i³³³IJJÂÉÉ©X¢t< IDATe'%%¡R©Š=Ó{LL ŽŽŽ=>&LKK#;;»ØÛ‡¥¥%fffÅ>Ñyxx{; ±²²*VúèèhªT©R¬í,éºÜ¿++«rÙÎ’¦ŽŽÆÉÉ©Ø'“ò\—ò,»"­K~~>111¸¹¹=õuÉÊÊ"%%…*UªüçeçååqïÞ=\]]‹•>55•ÜÜ\ìììþóuÉÌÌ$55µØÛ™˜˜ˆ±±1–––M›››Ëýû÷K´yyyØÚÚ+ý½{÷°±±ÁÔÔ´XÛ™––†££c±ÊNHHÀÄĤXÛ …‹‹ *Õã_JHII!??¿DÛikk‹‰‰É¾ÿ055Å¢XéïÞ½[páa`ðŸ¯Kll,öööźV(ïïyn§œÿuËÉÉ!>>—ÿ¼lFÃÝ»w‹>##ƒŒŒ Êe;pvv.VúäädlllеQQQ¸»»«ìôôt233‹½…×ÜkÖ¬¡K—. ©à/^¬¹{÷n±Òž>}Z³yóæb—ýÃ?hΟ?_¬´__ßb—ýûï¿k8Pìô .ÔÄÄÄ+íñãÇ5Û¶m+vÙëÖ­Ó\¼x±Øé§L™Rì´»víÒ>|¸Øé,X ‰‹‹+—uY½zµ&44´\Ê.iúyóæi+ĺ”gÙi]RRR4sçέë®Y¹re¹”˜˜¨™7o^±Óh~ùå—rY—Ë—/kV¯^]ìô;vìÐ=z´Xiïß¿¯Y°`A±Ë>|ø°f×®]ÅN¿bŠ͵k׊•öâÅ‹šuëÖ»ìmÛ¶iNœ8QìôsæÌѤ¥¥+í4üñG±ËöõõÕDDD”Ëþß¼y³æôéÓÅN?cÆ Mfff¹¬ËÒ¥K5·oß®ßÿ?üP“““#çÿ'XvTT”fÑ¢EåRvnn®fêÔ©ÅN¤Ù¸qc¹¬Ë;w4_~ùe±Óÿõ×_??¿b¥ÍÊÊÒLŸ>½ØeŸ9sF³iÓ¦b§ß¸q£&88Xù¿ÒõB!„BTbÏÒÜÜ\MVVV±ËÎÊÊÒäææ+m^^^‰îÜdgg—èHFF†&??¿ØÛ™].Û©Ñh4éééå¶%}R’uÉÌÌÔäåå•KÙ%M_’ýYÞëRže—ôîMy®K~~¾&##£B¬KIÏå¹999%:_”dæåå•èœ[’óEyogIÎåùÛRÒóEI·³¤O@Jr,–çoKe>ÿ?/çÜŠÔ.ùùùåvÎ-iú’ž/JzÎ-ÏkÑòÜ·ÏFÏR0ehhX¢<Å}'@¥Rë]áBÅ}µPqû-”÷vÅêSÚí,©’¬KIöOIË.iú’ìÏò^—ò,»<÷gIÓ”¨ÝËs]Jz¾(Ïí,n«ÒP©T%:¿”ä|QÞÛY’ýSÞçÜŠ²?Kz,–çoKe>ÿ?/çÜŠÔ.åvÎ-iú’ž/JzÎ-ÏkÑòܷφóçÏŸ_‘ƒ \\\Êý¤+ž WWW\\\ž‹‘žÅîø'dŠ'ËÉÉ —r¿Y$ä;*d–(˜ª(+’œœŒZ­fçÎZŸ×©Sç‘»C3fÌ`Íš5rÔVBuëÖ-ñ]3Q±5jÔHAö§¨ jÕªUìQª„|GEéìÚµ µZ͆ ”ÏüüüP«ÕDFF*Ÿ V« W>ËÊÊB­V+£¿üû│ÕjNœ8Qd½ÑÑѨÕjþüóÏJ×fbÞ¨¨(~þùgfΜÉ?ÿüCdd$¯¿þú#éÒÓÓùòË/™3g7nÜàðáÃŒ?^Ž|!„BñT‚GGG:uê¤|ôêÕ‹•+WÒ»wo"##‰‹‹càÀ¬_¿žvíÚ‘ššÊõë×:t(›6mâ…^ÀÐР  FÅŽ;¨Zµ*íÚµ{¤ÞˆˆvïÞÍ”)S8pàYYYôíÛ·Ò´[…xróæMjÖ¬ @»ví8vì˜Ît©©©˜ššbbbBݺu •#_!ÊAJJ O¥î¿þú µZÍòåËÉÍÍÕ›îÂ… Zÿ/X°@vœâ‰ò÷÷ÇÞÞžß~û“'O*H¯^½€‚'V!!!üöÛo 0(˜ŒïäÉ“ìß¿Ÿž={Ð¥K>L`` ;v OŸ>ìÝ»Wg½—.]¢Aƒôèу¿ÿþ»Rµ›t¬Bˆg@pp0PЉ°nݺÄÄÄ R©ˆŒŒÄÄÄDù¡º|ù2YYY¨T*7n @XX˜2ëy“&MHIIáÀñÚk¯Ñ°aC²²²ÈÉÉ!==ØØXêׯÜrttT&455åâÅ‹8::’––†»»»ÞI°âââ¸}û6U«VU&4Ü·oË–-cÕªUdeeéìxõêU–,Y´iÓppp zõêÄÇÇ©L¾çééI^^ž¨XYYQ»vm½mxñâErss166æ…^àþýûX[[sçÎÒÒÒhܸ±2ù^ll,‰‰‰4iÒ®]»FJJ 6$;;›ììl222ˆ‰‰¡^½z%œBQñÅÇÇsúôi¼¼¼ *ñ€Ï« €*w¹²³³µv^VV¹¹¹XZZb``€F£A£Ñ——'ê„ضmYYY@Á¬Ý‰‰‰ìß¿ŸŒŒ ¼½½ÉÊÊâÖ­[†¹¹9ùùù„‡‡ãîîΙ3g°¶¶àÚµk´nÝšÐÐPîܹCpp0õêÕ#==¯¿þœ9~ü8]»våÈ‘#Œ?ž}ûöQ½zu¼¼¼X¸p!Íš5ÃÖÖ–´´4¦OŸ®s½W®\I5øõ×_Y°`ÉÉÉdee‘””ÄĉõnóÕ«W¹wïÁÁÁÔ®]›êÕ«“ÀÖ­[qrr"..޾}ûròäI ß4NJJ¢C‡4oÞü‘ò~ÿýwbcc122"++‹Û·oS³fM,X€··7„‡‡óâ‹/²råJªW¯Ž/^¤qãÆ‹/ÆÀÀ€5j0jÔ(úõ매svvVnH|ùå—ddd`ccƒZ­`ÅŠìܹccc>úè#¥ìÑ£GÓ²eK¦OŸÎK/½Ä¦M›”2?þøc @JcРAôèÑSSS­hÏÇÇGëàîݻӢE ±²²’#_!ˆƒS¦L 44”Í›7púôiå=äB£FÂÓÓS *þ÷ÿWkù©S§hÕªÕc?ëÕ«W¹ôÃS«Õܼy³ÈàãaW¯^ÅÁÁAç2SSS¥m,--õ–óÞ{ï)å<<¾±±1ݺuÓýõ×_]LJ÷ƒâÙ0dÈ’““•óDá9fÖ¬Ydff*O— ?ËÈÈк~õññ!==]ëÜ4aÂÒÒÒÁnãÆZ¯¤6Œ””ÌÌÌä Hi©T*ìììtþx<ü>­­­ñBñÜÝÝ•»`öööLž<™ï¾ûŽ»wï¢V«±°°`Ê”)¨T*V¬XAJJ &&&,Y²„>}úðÝwß±uëV%ðòòÂßßµZÍ{ï½ðHÿ OOOŽ9‚Z­¦fÍšäææR¯^=ªW¯N¯^½°´´,²ÏEÇŽ•úÚ´i£|^TžMž<µZMíÚµ3fŒV¾*Uª`iiÉû￯´——ï¿ÿ¾Î²Æ‡¯¯/YYYØÚÚR8E–®uyø³öíÛ³víZå)GáèŒÅÝ!Då¥ïúUWP ëšÖÄÄä‘é Œu–ùð CCCé*ƒ 1 ¯BˆÿÖgŸ}ÆÄ‰qtt”ÆBQ±7i!„xö¼üòËE¾n$„B<-ÿËÙ*¿ëbüIEND®B`‚snd-16.1/pix/bggrad.png0000644000076400007640000007762011436023321013076 0ustar bilbil‰PNG  IHDRôõ¦ý›sRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEÚ9 £ô IDATxÚìw˜EúÇ?ÕÝ“gó.,9'Q JÐSÌâÀ¬¨˜³œõüΈžžYÌg@ÁNP=QDÉ –]6§‰Ý]¿?zfv‡œÂúû<ý°ÌTWW×TÕ÷Mõ–h;¼£ì2¢;6lذaÃÆÞ†`e€ÅOþˆÖeDw~¸a ªPI‹úª@UµFoŠe ìž´aÆ û $2 Ù XA¡X”’!Óš]{5A$?ÞfßS&*phˆg4 8B!-Ä}ÏÜBÏÁ½qÜÑMV¢tÀ+<öïkÆ 6ö Dˆ°Í±|M)³‚òuy¤gÌÁ/èœÛdB€”ŒÚ6Ó-˜“>¡(MH ¿ýö=‡t8-¢ !@ ‚â”˨ŠV°~ýz ðù|tÐAH)¢æ%”(¶‚nÃF“0¤ÁaîCÈR3™šfª;uTF9Íw›å6†EÝÉûwÅû v WmÅG¡Y8LÍþ‘mìPàƒŠê2¢QM¾,P!…QLaðÅœÿ ªõÏÝÜÜ\r[gc†  8U–-û¢¢b=ôP ÃHÔkš’ùóç3lø‘T†*QC1BDX EaÊ”)œwÞytîÜ™9sæ™™I»ví’_,$6£Û°Ñ4!›Qþžs3Gz‡à{¦-btÊNÝ4¼Ùé>ûòsÆæM@ õµ¬–bF¸-ûZFû†ãýGkÄØtûG¶±ÿº”Hd£g)% !$‰¢iÜvûíx½õ›ÒO3†‹Ç_ˆˆHP­š¿øâ ¦½ÿ>Ï>ó ]:wFAjZ‡z(¡Pˆ¥¿ýŠ”¦Åß@Ä5ô(š@Q«W¯æÂ /Äãñ ¥äˆ#Žàî»ïæ‘GIhé¡â jX±5tû $’Öj—fŸKª#…ßCëy³ü}R¥ŸÛZ_ÇÌŠ/‘r8K+y£|né"GËâ꜋ù%øA=@Ê—)ÇfrGæ ¼Tñ&Ë+Wï°`(\”5Ž^žî¬ m䙢W†5Ñ‚ÑWÈóh›Þ™½H@‘QóÂ)éÇ¢Kƒé¥Ÿ°,´Šâ´ô–z[ÃÛx¢ðE4´¤÷ÉTÓ¹"ûBÒi¬ mäßåÓQ …ûÚÞÊŒòÿ0Ì?”5¡õ¼\ö6né"]M府 , ¯J¼ï{ ý4º=FlìûÒ"NÃ4’,Ö ­A8,S»ßïçÊ+.Ç0ͤrN§“Õ«WÒÒ´cJüUW_‰ÃédÜYgñØäG9þøã9ù”Sðù|Ì™ýeåå ¥eaP£¡+A¢‰¤GdffZÇÃ5×\ÃŒ35jeeeü6ÿW”öEØŒncÿ@…^Å/C~ÅahÌ™ÿ'õ:†oç|ƒ8ÊÍE™ã8…Ql¯*䚎—°ú«,쳂÷yš~ξ¬È_ÁÁm¶&¹éÑ.ÊǼç¿dÕˆ5HÍZ%t©ófg9>us~ËÅýÏâJå|:­`Iñ£N¡óšÎ ÈìG¯-[}9#s†óq·7X¶v)înèr½¿ÊéÝOáí'ñõ‚¹œÝûT.Ì:“kGáp;¨2ªYxèRðóÅ÷s8¹÷HæÏþŽÂ#«¸ c,§*Dz¥4ë:Oà÷Ù+ùî€_x©÷?æÊ’K887ö>ªµ Ä…6öi ]ZãÜ4š&tSJ ¤ßú¿Ûíâ¤ODד¥_Ÿ×Ëý<ˆ”Xš¶b ••œwÎÙlÚ´‰{î½;ïú;)))|;ŠPSJËZž0¹ aPôÚ¦‚dÓAÇŽÉÈÈ ºº¯×˱§ߘÅÞìfcÿ€jòÂtuu—Âã_=MþªmtêÑ„{Ÿ¾Ÿ9‘oYzÿ—ÌÂÍKŸ‡Ï¼ÁÏGÁ‚%?3êÖxû¡78yÀ‰pV“_þ?¶lcäøãðžÁš‡~ãêMçqH·Aè¦N»VíˆJnm»2ðå,µ¢ š [ÃùôõõBsk<1÷Y6®Þ@z§è¾ü8oç}ÀÚÉK8,8yë~àè!G0õ“w¹âÍëøò¡YÒyP€n¯6öBÇ"[iÐTÐBµþ–`š&Rš;¿™ˆšQ™ÐÐ¥i #yäÑÉxथ¥2ñ¦)Ü^€)-ó¿ÅںЊª°dÉÒÒÒj9ák™„@JI÷¶ÝP J“/dÃÆ¾éç˜y§2bÉ`Fö=ŠÉg?@…·Š©ë(7*‰f[sF àت&¤ï`®Ž3ǰٹBNzq ÕSæÚŽ*@‰i¹~¿ŸpŽŽ:ÐeMøÍÖlõ¹½D² œ-º²U Gp9Ò1r€#­òáH³Â àÝYïaJƒÜì6”¯)áÔãO`ƒ¶‰EeK8þû±ŒX<ˆa=硱÷Bºà3××”†Ëˆ¶Š½Rû}|su\­kv¸ˆ @˜¶†ncßG|œK$n—³¡RCA„¢ „D ¡sB—Ò´"àˆ¨HD››ÒÄ¡¨Œ5’N:0pÀnšx /<ÿ ú÷Cb"„¨GC!u&Þr ë·ohò¥²Ò³+%Âæsû Ê£l?m%k†¬%Eó#¥$:·×!*f¼¾-ÕijÌ)œÇ™ÇÁ‘9’VΜÄwmd+^ö—<}9›; c&9\¼½ñ}Î~?öKÏœîüºâ7–n^@Ï.=ØðÔJÚdæòÎŒ©¤d¥rÍ¢[ùzäǬzu ·ƒ@(ÈËï¾JaZ)Gx8yR•tLoÏÝ dÑ¡ÿ䣯>æŒÅã)žXÂÚÁëq+1Aà¿•¸Ú+0ÜÊ0aÖz·éâ£mŸ1fĉ¬¸”V®œøÚei†=Flì„.!(È/à’Ë®@Óêîð¨øæËÙˆ •·Å ¤i˜È|èÒ0‘2fikN^‡a#Fbš&?ü÷[***PU•;Ÿ}šö: u5th–$댦7´Ô°bG¹ÛØo*S8áó±tú©š®°yûVW,!¥8“º‰eË—¡·2¸éÙ[Xøãƒ\ýõDFnJÞŠ­8Ú¸h#[árº(¬(ↇofÙÂ¥¸„J4×)Ðи廿3sûLr*2(..ä۵ߓ= ×Ï» /¯ÀÙÉKF4o–~ƒ{` ËKVrä³ÇrPIOÌ*Å~#ÜCçõ’iüöÔ2º—u Remá:T—àÆÙ·³áÕ´ögrìgÐe~kœºÊ–¢m,*YŒ;%•ŸÈ¢_¡®pÓË·²øÛE¸ú¹¸ùÛ»øOÞç®ÈGæ(tÔÚáqzÐCl ÝÆ~EŠDP\Uu5Z=ÛЪ«Vô¹¢ ‚"‘mÛ¶|î¾çÞ:nmUÕð§ø‘¤¡?þÄ“¸Ýn¦¿÷eåe!¸ñ†ëÈÎÎâø“Æ°aíjë!‘ tqØ?Ž–kÛn&(«™wüFÖ–moÚüèðsîûãŒIö6lì'ò9ŽÅ’¢M+ ,ÚÚÄQ¥¢”It¿D¸j±@÷˜èÙ&ZPE-–ÉMˆjI¨‹³RC)µî12L‰§`Å*"j©‘l4p¨‰zƒži`z%H£<¶x˜Ã+Ñ3L„8JUDÓzºÄY¨ ‘DÛ˜8JTD˜¤÷Ñ*j è>¼µH`ºM¢9&ZHA-QjÞ' u6¦=:lìûˆH±«È/ÝBŠß_o®! ²ªŠpQ=ÅÒ£æÐ&»=£ÁÜ2ÑhÓ”\øÍÕàTùääiåátº¨®®NJʪŸÏK0bõê%œ²îj<º‹¼«WÅ|è!kꜮ¡(ÙM¾TŽÇ‰ ‚Pm©ÜÆþÝgB­mà"ºf@1R–ÙÖßJ@`bbfÔ–†­Ïuµæ¬;ôÔ¶0¢FR=µïÕÝ&¸ã6<+.@÷ÔÎ")¢5õˆ`=߇ÀP Ë'/c‚@lI°ÞGbîÐ%`¯6ö Ý„²myT”PAA£e}€ßégëšÕÍJ”î0`¨¬[²]6X®,þ ‡¬‰¾‡=p´ÜèÙ‚ævP)+Pšá—R’âLµ]6lذ±_¡B¯j6O¦j~*¢•M§qÁ­¸¬àxnv{¼ºÅl¾u%HDH Î× NËG8š÷à`Ò‰ 6lذ±?#¸“å;Y^AÊ ] Çâm ŽJ•õ3–#Íb’ì‰6lذaÆ=¡Ð4Z½‘œA­bŸ§ûËŒÉv’6lذacÏ…ƒ@ Í¡¡i±ÓÖ¤‡ÃY+ŠN`ŸsnÆ 6lìɰxZÕ´Ä~x$‡Ö‡§Õº|¼øâkD"JJJyæ™)uöÕ5Ö=ÞêV’ê ‚ÜqÇ}€Æ¬Ysؾ½0ö©Í|¦øe­€Fyy·Üò÷?½‹kÚåKôWòç !)e¬œÂ¢E¿²dÉr{ÌÚ°aÃÆ^k-w¢ÖúŸZkO†iJ&O~j§Ÿ£ª*jLCWGƒ„^ZZ;¤ÅÓéäÒKÇsÙeãt:)--ãµ×ÞÞAbÍ"0!TN8áDÜn7!+W®D%QO8æá‡Ÿ$Ç3œœœl¶o/D!;tT]¬\¹’^½z!„?vRœÆ½÷ÞÇŒ3HKKçÞ{'5ÒöÚu‹¤r=SÁ¦M[6l))~†N~~A­DþÉÿJ)1M“6mÚ"„;öþ&ýúHß¾½whC}}+ê´Ï¶²Ø°aÃF ëÏÂÁ¤Iw°ví:„PˆD¢¸\n„p×Y«ãÇ­>÷ÜË;pDÓœª©j†n™Ü&ô8ƒED"…¼ôÒ³Üzë]„B¡¤ÓfÖ­ÛÀQGÀàÁG±hѯÍzáh4Jeå‚Á¤,£w—»ïþ}ûfÚ´âMæÍ7ßcË–­¼ñÆ;!èÙ³×\3±Ñoz÷îMYYK–üûÄÏ[oMãÄ¥¨¨ˆSN9sÜq§1`À|ùå7áào»!܆Áá‡"²pá¯Üpí¡6(‘E"N8á >úèm**¶ð1`À0JJJ©®®fðà<ùäóôí;$ö.^"‘ùùôìy :ôÒøúëoùþûÂÍk¯½Íåüó/Ã4M„PùᇟyóÍw>üxÎ<óLÓÄ4%ûÛôêu(#GžÂúõíYeÆ -§Ó™8óDðû}€D×^û7úöÌO<‹µ3´*,_¾Š˜Ì˜1g3xðV¬XÝ ×©ššÈXÓÐ5ëià½÷¦óöÛÓ(++å÷ß×aš2IÛ¾ôÒkùð÷˜7ïs®¹æo¡4©¥;Þ{ïC¦N}Ÿ·ßž†”’¸—+Vóë¯ÿeóæ­1g¿ //ŸP(ÌEƒ×ëaõê_xúéG›|ƳÏ>Æ”)¯#„ÂŒSéÑ£+Š¢Fc‚‡3θ—_~ŠE‹æqÏ=QVVLjj sæü‡>úŒ-[ò¨®0sæg r(  ¡°jÕï\pÁÙdfZÙ8rsÛsà W²nÝ ÃdÁ‚Eøý>.œËäÉOñé§ãt:éÖ­ «WÿÆæÍË*JJJ)++ç›o¾âùç_aá¹wÜ1œþå€—ŠŠ ~øIfÍzŸœœlžxâ9¾ÿþG"‘«VýÆË/?Çã±g” 6l´TUá“Ofñî»ïóÞ{RUU¸øë_OgĈ#X¶l1 .æ•W¦$e‘«®®æçÉ'âw^æ¯=7vR›lTC×,º£IBïßÿ ÃÀçó&=XQ¿ý¶„¯¿þ–ŽûPUUMuu5>_ãyá ÃààƒÄáÐb&qÁŒŸóÕW3Ð4k®™Àƒ>þºÓäôÓÏŒÕáäÎ;ïãµ×žKH:B6n\Å7ß|GïÞƒm/**aذ¿ðä“Ïcš“'ßÇG}ÂO?-âÿþï.@oày ÛÉÎ΂ØI8`’““M8\“(àâ‹ÏC…_|’çž{™ãÙÀ`И3çkÞ|s .—›ÓN;™ ®#~¾ÞUW]‚Çãç’KÎç•WÞdüøs9þø7)--ãšk.cðàÁ€}j† 6l´LSÒ§O/Ú·oG4Åétbe|ôѧ̙3— /¼]7ðz=\tÑ9I÷žwÞX:wîh}ô‘ƒA|>_=}¬³¢=7Û· @°3ƒˆ7½ˆpðÁ}™=û?x<<²–”#ÉÉÉbðàC¨¬ÌO´½{÷.qÄP>üp&EEÅüõ¯'ñÒKoÄÌ%Z#VƒCéÏô驱vúxå•“›Û:Q* *yyÛHMMIô£EÔ¢Vßšdd¤³uk Åb<µ„)%ñ[Xes¨¬ÌgâÄëxå•7™2å{FÙ°aÃF AJI]éÝ»}úôÂét¢ªÖžŸ¿†òò̓¼ðBÝ`¸²²r¬ neeåhš£~ÅO«¥¡×øÐ› ¢2äaÖßR‚®ëäææRP°§žz†Þ½{ðÝwó¹çžIM¾¬¢(|õÕ< Ã0éßÿ n¿ýfŽ;îtž~úQ^}õ­yš±#ç²³sp84þóŸÿбcúôéÙD‡š\~ùx†Éôé¯U !Á’Œ2èÑ£=ôƒ`þü\wݤ¤´fРôíÛ‡#‹5kÖ2`@? Ò¨ß>==œœ,.¼ðl.¸àl^ýmºtéD·nÝ©¨°2ðÞyçýŒ9‚+¯¼™ùóg#„ {÷.L™ò½zugذ£‘R¢ëýëÉüå/ÇòòËO1cÆçÜÿ]@¸N¤¤ _}õ%+W®¦wïžäç™°|ذaÆݭ¡›1î’Hi¢ë:à`Ê”'¹è¢+¹êªKY¾|%:uàøãGc5Õ>ú”ÿûu*+«Ù¼y«ÅÓõ@S54Õ"t1øþa²]Ÿv|xÅtäö<ÀQG‹^»v={vK|–——Onn+ Ã`Û¶:th‡®ëlÚ´…h4JZZ*mÚä6ù²Û¶åǤË4Ñ©S{üþT¶mÛFyy999Ù”””Ò£GwJJJðû}8.Š‹‹),,Âï÷Ó¾}ÛfII«WÿN—.p8!Ðu7ÓµkgLÓdÓ¦-„Ãaü~?mÛæ¢(*………8ÒÓÓÉËÛ†Çã&##½Y?äæÍ[©®®Æï÷Ѿ}{@RQQIZZЋ׳}{!­Zå™™ H›7ç¡ë:}û@eeBü~?%%%lß^ˆÇã¡cÇö!¨® ëQÒÒÒ…ÂTTTššÂÖ­ÛˆD¢¤¦úi×®­=£lذa£…P\\Bjj ‡)%ëÖm [·.XqaÛ(/¯ÀívÒ¶mœN'6l¢K—.,Xð3o¼1•›nºšh4JÇŽp»w<ÝT£¤ä޾ïmÚ iÃϰ½óA™6a*fÁÖ:„nãÏCyyé鑲۷mÆ 6êBðà xõÕ7yá…')gúèÞ£ÍÐ\>»àØÉÝéˆí¶±+‘––Š”•H©Ûfp6lذQRš z(C‡BJ³I®°‚â4@ZÜŸ+XNx»Tþj`» 6lØØßù¡þ¿ë²¦[Aq±\îñÔ¯ŠÀf**Û=jÆ 6lìñÚ|ºµ]Ý!ÊÝJfÓ]Oµ{Ɇ 6lØØÃFPµ7kkè$"¿›Vñ÷eIGF}ao÷²aÆ {:´„½–É}Gò’R"vHð.i>Éí²s²¹þÆÉ„#g;‘h´¿?%FêûoР 6ö^ÔŸ¦i‘ríÏMS‰­ÕÉiš‚)S\\uµ‡åe =}ÅH©ìä3ëGI‰Êu×yqþéO6lP8ì0íÛ+WªdfJú÷×1ŒÎW% 8ÈÉ1ë]ÏÏ>;¨Qá:Dï³=ˆÐãc&ÜÀ?ÿù“Çׯ\Î| X'«]uÕ„‡ÖA0»}È£ª.rZ÷À—šÁUWÞˆC“ŒùEÁëõ¶ˆ+À† 6þ(>ûÌÉßÿîåì³ÃÜtS0ñùEùyýu7RðÜsnÞxÃE8 Ï?`ðà(‡IŠßŒqsýk´`š°i“Š™Ïëââ‹}x<õ“ºaÊËKд?²æ×6CÇ–†•/KРACpòÉ©œ~º¯VyÁ5ׄ¸æš º.èÐÁH¼ïž ¡ÿi„îõz¹ì²Ë Cüío÷ðüó6)±Ý|óµÜzë ˜¦A$©·Œ”»»§¬û¨ ¢¼ÓÐ*&L˜Àý÷ÿƒk®¹”`0„Çã±}ê6lØØë „É7úXµª”ÛnóÅÈ×RÈžy¦¿?™ìæÏ/­‹–fš ÎØ¡›µ×è¸Fß§O:[·ªüë_Õp€Ž”‚^½t¢ÑâFÛfš$¬Ô ‘|ütãϬŸ%3gVÔùtÙ2¼<… 4ŠŠ\üýïÕI„¿;9«1Aâz à7žÇ0¢ƒ¡F¡ ( ={vOøÞMSî&ŒõëU~úÉ 2ȶÍ?ѯÿ@›p÷Þs-Á`‘H„¼¼ºtéˆÂö¥ÿÉÂTEÔ…ÀÞ"¸;áTL\ª}@Ð~D鉿|>™ô¹×›¼e¸sg“«¯öQX¨pë­A ÐcŠ–‰)E¢.)-óõ /¸ù׿ÜÌœYI÷î: 0Œót@°wô“Y± O)aÐ Gñ0zt[¶¨<ÿ|ÆE“Þy¯ÔЪ««1M)%ªÚð6¯¼¼5ç!¥iš1bTb‡ÂÈ:‹üîÄwß©Üx£›£F1ë³ç ‡uŽ5;&]Êï¿ÿJVV¹¹Ù€¬eÖ±ñg@Ád[Ðb÷énE†3ˆKÕíŽØo`bD%ÑèŽ~m™¸LS0jT„Q£"D"pøáé,ZTJÜŠi‘u¯ªJ>þØEE,[VŠiÖy"ˆnŸ²r€aÀĉA&N Æ>“(J·ÝàÁ«wƒð"ÿ|B×4uëVSUUaÔ¹¦©õ&cQU•eË–Ôk®– C§o_Ñ Ã[o¾ÎÚµ«ÈÈhÃ}»ðÈ#OsÑE'àóyñzmsû®8¥dï 6Ýëí"6ö·‰vË-.¿<…œÓ„gžqsíµzÈÇŒN ÃÏxé%7›7+(<þxuB{—Ròïç*¶ø)/lܨ2bD”ûî«®Eäûx/îð~–Û¢Ï?wrÎ9)ÜrKþýõ³JüO„¾iÓ6n̯g–†IÛ¶më¶µ­MÔÛAµ_¾F ¬¬[§’“cÒ¶­™ˆdBR\l B€nÝŒfGNÆýöåå›IMõ³iÓjN9y8wÿýnŽ:j Ð)áŸ1M{iØ•ÄÆn"ô&æ™}L?7W^‚€@××^$U¸í¶·ÝV(wË-„Èg–Öm)^’m[§Žž!><’¨+>¦öGèº`Ô¨(£FE9ôÐ4|0@Û¶&¬cšnLXSëåÿD芢4°m!ž.Uþé–4M2vl×^dìØ>û¬‚.]̘®ºÊϸq¢QÉM7ù˜=»]oŽ_C*­[grr²Ð´Í,øé+6mZ…®ëµèØ‹ƒ}A_öXÞÏ`)?5gv†@Q’?·Ê‘ôk{›Ä0 ÿ`“1c"&躲_hå;ƒ,gÓ&…/¾pÒ¿%%Ådd˜Íä¡ÒÐw±î@C[""ðû%'žF×áÑG=<ûleLJ‚éÓËä÷Ý^Àlf›Œùó¸\Ó4éÙ3‡ââíté’‹ÇãFQ5¾&³H¤)1…ݯ»w–µÔöP{ëˆ1M…ìVfBöœ­K¨tébrõÕ:&9õÔTRS%—_bĈpƒ{ãwFß˽þF !Y³F£];Ó„¾}uþõ/O¾!â’¥¤ @aÀ#VO²9¿þAX“pAËçïõúp¹Ü1í_”˜F IDATµO`Ûeë„mùh9ÁÙît;AèR%3;b iÙ+ÆEª 3g–£ªpÖY©œqF*ë××Ùe°kè ûbü~“PÈê€êjÛìŸ~ÿ]å´ÓÒ˜?¿4áÛ©‘ž$“&ùøúkgÕ®#n’RÐ4Q§ÓíØþäßZÄÄ)»_wóvŸÛØÉñ¢™cÆö¡Û}Ò\åT×aêÔ ¶lQ8ê¨t<k‡À¼yeìh%‹F•F•›]âCßõšC]S iB§NkÖ¨˜¦ä­·\ŒLV¯ÖèÕK§¨Há‚ RY¾¼Ó”±`·šNˆFá*ëÔ=mš›Ë/÷Ó°Iݽ»Tz³•Å=fžÙ°QLS ©5î®±×Ä®Cn®Á¢EÅ€dÊB´ gOkŸÿa‡Eyýõ t½qÁj¯ÓÐZÝu]2~|ôôVœ|rˆG©B×á¼óRY´¨„¡C3Ù¸QÅåÊ!HY뜚@µv€ª*ÑlÈŽ§ËÙøˆÅîÊ=jžÙ°QW340 Õ•º=vþG½ÅálڤѩS6ï¾[Naa!RBF†YKéücÁsÚÞ3 ,éäüóCœ¾µõ"µÞ|Ñ¢b¢Q…  ë˜/šc¦ˆwxóÚaä?›Sì ¸–Y`lØØ9”ÛT¾³ ‹¦I¦NõðÚkÚµ3Ðõí¨ª¬EÞ5î¯?J/{¨½aS`4ZK³‹™}¬ÏÌZßÅa6sñªÉ”$í•n÷kèØAq-ÑïÍ36’¡X„^$ìu²Êg|[à¦M œÍ„ fÍ*F×E,w}|îlÝ{™É½%g©Ý©ÒŽÞܽ}/¤×Br”=ÖmìÜ© * ˜`(öø©C¶‡ÃJŸÛ§O6ÅÅ Ó¨¶gvÌþùìýZI·û}÷w¹Ýç6vJÑÒyí_~^,‡ë¯ ŒŠî"öëÙäpÀêÕýk:n·äË/Kiß^OdÚû£¾ñ½šÐmذaÃÆžEZн^Å‘]BÂÂB…Þ½³Yµª—k-2?æ˜ Ö­Óøí·"ÜnKC‰Dv&½½fÛÚ®ÕÊe­gÛ¶ßÝý{ÛyÅ[ v§Ûhö*‰”ÓU“¸…¤S'“ï¿/æä“Ó5*ÂwX[‚MÓÚ{½/¼¢X{ÇkcâÄTV®ÔHK“Ü%‡IjלÌùçÿ{¡[‹ûî V‚L F»q™PdlðÛä²{癴ǺZ—L Ò´ÖIÓ„¶m æÎ-æé§}ddäR^.˜6­Œ¾}õÄ=YY&YY ÏoÃHŽçB¢ªu?ß嬾ûEÆKþ^Q,ëC2ˆD;ª«ß}çä‚ Ò …Àé´ÚöÒKåLž\aXԄûÞG¾&–iÉ.þLÛ¯Ø2‹…`³Ì3ûÚØ„Â+®pÕUt]°x±–Èí!%\|q7ªõ¾š&lݺM«±Ž.Yâ`Рl6lØNn®A4*0MªÊX¹¸ ‡žH .—ÉGyÐ4ÉI'…‡k²®9&'¦òùç.–-+Â:^Áé4ùì37ãǧ%H}Ò¤*®½¶Š  ÃÓ¦•òãEdg›¤¦ÊØés$ž±§Ì%Ûäžxfü_ÛäÞ2}oc÷Ã¶ŠØh.,¶óxAÑLœ ˜~NÉàÁ‘¤ÏæÏ/lpžWVjŒ…ªBJЉÃa¥è®®ÎçÌ33(,T8ñÄ099&[¶(|ýµ‹Ü\“’ÁÀQzöÔcÚ4|ô‘‹®]­³>^|Ñ˘1!¤„B0}º‡Ë. píµÆŽÍ ªJpÚi!fÌpÑ­›AAA~¢?œÊ¸qY”–æÇæ‰RG ±€?wý2Œø™$ ŠR{¡ Z6äÙV[Z‚ÐímköX·±gÃ0àÈ®ðþÉ5WÕ‹o¿íÆ:»¾û.¾8@M^ÔÙ³w\4µê‘ÌœYû»j¾ùÀ«Wòùç5÷<ñDíw2ϳ[ûøã#wÜÿ.hïU‡³ìëÏÞo)]Úzz‹ô¹Ýé6š‰áÃM^=bwÄ.ÆÁ›ÎË}æp–]»¸ÉXPœmrßý¿¶·¿Ì3{/ºu³.--ˆïC‡³ìÒ'Š–{ö~OévP\‹hèöX·acß‚XƆ 6lØØ ÊË—_ºX¾ÜAv¶É9çŠÌÊ•sç:ÁøñÕx½’§ŸöáóI.º(Ðì-¦{¨]î—ÏÞ/!jkŒ6ì±nÃÆ¾»Øy½’‰+yåìáä“­à»nÝtúõ‹²l™Æ¹çfòá‡ÅsL˜NÈâ’KFóŽíÞË´äI>Ò&–ù½íÈ…ýkžÙ°±jè‡ ?_›k$æ Ï'¹öÚ4,pñÚk%躤W¯hÒ¹×jè»êÌqE‘üò‹“üüä=…K—:jGkûw÷ ·úÝ&—}ežÙ°a£>!Úâ O>q³fƒI“ª…¬³ÐC!xê©2¾üÒÍ£¦ðÌ3¥;dÏÛ‹Mî» ¦ Ý»ëtê”üùÆpÚ#ÎÖmذac Ð’Y³Ü|ú©›W^)%±>ÊÊ<A0(p8¬µÐå²¾SUI$Ò¼ÓÚöPBßu‹»ÏWw«Ž×+wùsm4©£Û±Û{Ýï6lìN¬^­Ñ»w”Çósì±!<IzºÉÊ•o¼áÄë•<õT>èçÒK«yùe]T]ëà—½ˆÐ[âä­ÚÊ¡}ê×n–Z;SÜþ2ÏlØØßqÅUõjîƒE4ÈJܵ\ç\}MÙpXÄÊîe„ÞÒ‰îm·bË‹Íç»_A·ÇºýzX+~‹·#8òOiËš)N¶ÐkÓJ‹Q¶ Õ2nwõ×ñÓËvÅœ ‡-òÚuÇFmNÝEE*YYÍ=·<µ\³^;žÞÏ-·T 5{â6\ßž+=í¾ËÊT&[äÙö%1cAqöµ{/{ìÙ׎—’@@Ävü¹—Çcræ™Y¨jóÖäêj#¹æ•_±B«u kãeçÎu’—§¢(M—7 èß?ÇhVÝ‹;дøV³ÆË+Šäá‡Sv’{ö"B§ÝWòó…}íξ·•ÄœköøÛ÷/K+nîºêñHÞxÃÛÌòP\¬òóÏÎf•˜3ǃÓ)›,ëõšqDk Ôfµ[Q$¶iVݪ*).V=ºnwÓå+*[¶hÍš3ª*™<9•_u¢(Mת«fÎt7û÷´5ôfJ<¶Ö²û/™$ÈÙ×îºØão?¸œN¸âŠL\.š¡]Zÿ¾öš¿YÚ¥Ç#¹âŠLþóGÓ勊ÔÄ\oNÛW­rP^®4ÓZÐ|îp:%ëÖi¬_¯5y”5&y]WšUwI‰Âí·§£iM·góf•_,fÚ4ßÖÎ÷PBo©ÁßÒÏßIÝ&ØÝÙc}¿¸4ÍäÝw},]ª5Ëܰd‰àYå?ýÔÃêÕ‡ÙhYU•ÜuWGJšªÆ w,`¬qÒU”—iSu a²b…Fs]‚Ã|ù¥«Yåûöðõ×®f "••‚£ÅR»îƒ&÷ZaR»ñjÉgïïWM ‰}í¾Ëë{ïårÕÎÑxÙ¼<•Þ½£|ó»Ysñ…R2$ÛÒØty!$+W:bDÓpYEW^ñsÒIòóÕØl¼îœ“>òÅ|î —UUøê+7ª*)-mªnˆF•Ø60Ñdz½’ñã³¹ãŽr¾üÒÝhù¸[!yž5\w<¡L}g¹ª.öÐÃYZÂooï‡nÑMÄÏ£·7EïîAoõ½眓͢EN/ÞÖdÙO>ñòùçLŸî­q “‚¢ÀäÉ©ÜY³ÖÂ3¼LšTÁŒžf•w8$ýûGøè#/—\R…®7\vÕ*'ii&Û¶)4uƆË%9þøÖ¼ðB13gz8óÌ@ƒ9:¨-sæ0fLÛ¶©¤¦6\ùÆ¿ýæà´Óªyè¡´FßSQ$ÿý¯;‘áÍ0ï)ãÇg³mÛæfsÏ^·=9â|wšùw. ¾?¦lÞ)B6vcËì{4Mâv›j“É~âDqÏ=elݪж­Ñä/“cPY© ($Níª†%% ÙäZ¨(ðæ›>Þy§>ðÔ2u×åË5Î?¿Š=¢<ø`—^ZÙ`ýBÀĉ,_¾•¬¬Ž‰µ¹!|ú©‡‰Ë><Èwfpæ™Ëƒ‚ŽuÚ·0fL€+ n°îÉ“S“·1~RUɈ­‰D6°b…ƒ¼<…¬¬†Ðë¯ÏdÖ¬ü„«ãϘ{èá,ûç³mذÇú¾E‘¨*Mæà–~úÉÅèѹ|ùe>ýúEšø]$Ý»GéÑ#šÐp*¯ª’­[-!¡¸XÁá±sµ­èëäû$*÷ÝWFe¥BY™B«VFƒ½×k"KC6 +x-qnš5õ«ªäçŸ]Üzk9íÛëÌ™ãŽù¼ë–·å€"±(qëÿ ÷‰õŽ÷ÜSŠ×+™;×Ë^ÿ ‚Ë/¯$T3&Àwß¹2$ H¢Q¦%÷§¦ÉXºðÚÛš­m}¦i¹âˆF!5Õ*{ AòòT²²ÌD¾öß3/O¥ÿ05î‹?aÜÙSÏF‹’ v€ZËE¹ÛØ%Ö O?Jß¾íp¹d“Úù’%NÖ¬ÙÂO¤6zê`<ÙKn®A8,ã$J-ò«Ûm2{¶E‘)±=Ú°}»ŠÃ‘\^Ó૯<zh˜t>ýÔ‹¦YÏôzͤ²ñ¿Ûµ30M8âˆ0óç»p:­÷©ýn·É½÷¦'´U‹-2ÿõWWâ0’ÚÈÍ5ˆDFX·Î: Óí6cÖƒÚB ””¨èº%¨Ä VJëÜËÿ^W1MèÝ;JI‰++9óÌVö<%«¦I>ûÌËÊ•Ž¤¶lß®ræ™Õ˜¦`ôè Û¶i! …®¿>+©-õ)ã†ÁLÙ=\’›ÛŽœœÖää´";Ûº¬ÿ·¦mÛŽµ|¨v„ûþwÙhÚ±¯H¶²e‹Êßÿž^K[kør»M¾ÿÞEZšIi©H$ò©/êÙí6¹ãŽtZµ2ðûMœN‰iJ|>M3“"¶5M2k–‡V­ Ú¶Õyýun·õÝÝwgà÷u敳ÁVVÖl¹zõU?W]•…ÓYó..—É#¤Ñ½{”ŽufÎôâpXÏÌÈè˜T·’ TÒÒ,sÿG„øáë´ÊéÓ½ Öf‡-[5DXû¸d§SrøámbÁfµû»&ÛÚ¥—V0{¶!$Ƶ᠃Ú%õ£ÃamýÚ‘ˆý~!ºðÁÞ:uמBXÂÐܹnæÌq×ÙjVãôíkYEÜn“±c[±~}r"›ü|•ÓN«&øý&¦i½ãI'µâ¿ÿuáñ˜I}X£Ý˘°¶—D¹KiÒ§Ï@† ÉàÁ£2ĺÉàÁ#q»•$ÓŽiîÞ+î/ŠXa_»ñ’5BŸ}íÆ‹–üÝe,rWÌãäºzÎŽýÑX½^¯AïÞíùâ  :½7NÀ¹¹¯¾ZÈ?ÿ™†Ã!cÑàÚå%¡ ;ÛÄ0$ÙÙBHRR „èÊ;ïøÐ´šò.—Éé§·æ´ÓªÉÍÕyùåTÕ2}?úhEEJ¢~)%ß}çbРPÒ¶.—Ëdûv•×_÷£ª5uƒdÓ&¿ß¤]»(_|aiö‘¤¦Jþýo¢¬¢H^z)…£Ž "¥äðÃCüðƒ)%³g[þìM›Ô¤ºkûž-W,^ìäöÛËøá¦YÓî`PÄx@2vlóæ¹cßÁI'D¢nU•lÞ\{?9èºLr;Ô®;žy.^_\Ð:ýôVüóŸ%”•ÕŒ+KœˆýNpàatÝJÔãó™¼ñ†·ÛL´%†tt½v<–dÁ£G©ªI¿OF†”–[&-͈¹šã{ˆÉ]AqñVŠ‹7QP°žüü5äå­&/o†­ãÛÛý[xd‹<{¿¿v‚Ì-³¢µ§Õ&å?˜öU¶Ì<Ó4IJŠdÃBX`ÜäZß=Vy¯×Œl°Üºu hÏ5×d£ªÖxñx¬k—UÉ 7d1dH;†mÇ AíHI‰’’b’bÖiKÜl¼dÉf=´kÖ8‡¶§ @M*¯ipä‘m7®Š®]£LêÃå2ðù 9¤=~ò»¾øb ·ß^–Ð5ÍÊ3~ÐAÆ·2™ÅËÆ Âå’±7Ks\¿^còäbÆkT÷¿ÿ©§8ì°0o½åGÓ$ÕÕ‚®]£”–*õ†eiŽV;7lÐxüñb>øÀW«ÿॗR>ÜJ>Þ¡C”-R-)Q¸ôÒ ÕzëÖu8çœJ6mÒX»VãÆË).V¾kEŸ~rÒ¶­Ž”§³ÆÜ}è¡a† ‹ZuKÊË-Ÿv4*¸ðÂJŠŠT6lÐè×/̆ ±sÅ-!"=ݬÓ.U…¿ü%Äo¤$Ú¢ªÖÚd]‡ CðöÛ>}´˜… ]I…Úü¥(–49‘ÑÌ™^–-ÛÀÒ¥›¹ì² zôèŒÝ5*·N®ñ¸o9Tr-¶gäÈ6¼õÖv{,½Ž)õçŸ]1í;,ĸq¹ôë×.]¢,^ì¬eZ…éÓ}\rI%;ëÜuW;w䇶Ҫ•AY™R¯¹Ø0`Ê”"^{ÍÏСí¸ùæ2¶mS“”“Y³¼yd€I“J9ï¼V€À0ãÇW²zµ#Qw0¨Ä„ «Ú·7(*RbyÌÃI}n%[Qbî‡MØå’de™±=Þõ›ˆ#Á¹çV±q£–°ˆVT(±X‹Ô~øÁMÛ¶zÂŒ 9$L$²cFÏ¢ ‡cÆ(-U˜=ÛÃ×0ož·ÛL¸,~ùÅr…Äï5 ‘4ú÷óÒK) 3ºªÆ5t’¬ÇŸîåÊ++“”Áäuk¬/ZäJ¼Ã1ÇyùåÔ$a)=ÝLÔo nÍ=c¡‘˜Œ=Ó··kàñHÎ:+—?ôÖy¦ÛDUM\.;ôwgáp˜у©Só9ë¬\B¡uµ27Õ`ìØ\ªªŸ¾-a:Z·ÎÁ…gº¹õ¾0y›w^ëâ‰×¼5Eã…÷B¤¤Kzøü¸=’PPÝÊIZ†ä¡;¼0-Ìeg¸YYQ"àøCÝlZ'h×Iòô[a.ëbëF…çß qÅX7›ô*nåãà ¾üTÃí‘;Æà®Éa´õárKÂ!7^çÎG"D±CÛ¯t1{¦ZóÎN8r¤ÁœO4>ù1@›vüm‚‹êJÁsSC¼øO¯=ã [î|4˜qzR Ì„ÓÝ,^PW°5MÁüuÕ±LYÉ3äŠqnÎO¾çú;£\xUÃC·Úxþ n–ÿZŸÐì%33“ÂÂõTVZ>HUµrs§¤tbÈ3fäÓºuçD$²”¿'Êj,]êdðàö xøð ï½W@vv:vŒòë¯[bZ‡ý¼x±ƒoÌ¢ºzee GÕ–5kœ±ÅÍàâ‹+e­…º={Fؾ}Šb=sùr£Gç2gζ„/VÓ`Ê”¾þzUU óæåátJ|¾®n '§s¬í–FšŸ¯qÕU„ÃÑ(L˜PÁ%—Tž{.‡Ã2…ÇÛ2}º¹sóUU‚üü Hi-ÈS§æòøãEIí9çT&ðí· hÛ¶3+WZ[ŸºwïȦMcfYA$").¸ ’êjÁÕW—#„äŠùì3§œR ˜M )áüó+¢[l®™´o¯c$‚¯âB’”’ª*Á×_oåoË$gŸ]Å·ßz8ø`kËÖ/¿¸8õÔjLÓÒ¿þ:œœÎ¼÷^>‰%²‘ *^?þèfÞ<7;FÁcÉ‘á5>éˆðê«)èºà˜c‚ «I¼Í?þèâ‚ *Iu5´k§ãtZ$™‘aðÓO.N8!PKȨ1ëkšIi©B~¾ÊùçWr÷ÝÔÎV÷Ë/N®»ÎH´eýz•ÊJÁ‰'p8 V¯v$HXU%ºn™þzöŒððÃi1A¦vp^;óÚ)`/v&Ìö~4©î ]&¬/ÅÅ ~sòqˆ½‡Ð›“€þE ˜:5?a‰ãÕW}\vY&wÝ•Uk0ÚØ™¨Þ°LP?ý´%6‰êbÀ€0BÀwf&Ý|ÅÄßϵöÉ^wG„ß)Œå釬C|6Li± ß ƒo稌<ÉàÍüø­Â”÷CôNõqòX‘'é nP\(˜þ†ÆIgès‚Á×ÿQyìå5?nŒÐµ‡ä¦»£|þŠaÀ³;¹nR„ìÖ’PJ‹ßëLš6ÇŸ¦3ùå0Ò´,ÏOvÐç “»ðêSŽD¹Þš à釜8]’KoˆrêÙ:­r%BÇÿÏÉ3;“úåª[£ fÔÙƒ¼i½`Ê?õöåe7F9ìãš{¤„w_Õxö/>î$#KrÖÅQ†7xÿ›áŽfl—QÅÓ8P”n\zi%Á àÓO½\w]9ùùÈÎ6,$/¼Æ¨QmiÓÆòû­_¯Ñ¿„`p],0Ë"K‹ýE‹\œrJ.×__Îé§Wñä“éÜpC6Áà:"AJŠÉÒ¥›Y²ÄEv¶Á%—ä°h‘‹Ç+Âå’œsNk~úi ‡¦ººF éß?Â?þQ¸q­xçí(ŠE@ßïFQˆº.$þøãEÜv[wÞY @~¾ÊG„bdZc&õù$C†„7®¯½VhYt\’Õ«FM&°x–6]‡?ÌçöÛ3¹÷ÞR@òûïn¿½Œ@À²TU),\¸%æ7©®®9(ÅŠ ÕÄù|5uŸw^wÝ•ÉÉ'[fóŸ~rrË-eD"5‡†Hù; ‡U  <v³ž9p`„¹s=<ûl)†÷ÉŠ¡;9õÔêØç‚Ü\Y³òX¼ØÅÉ'hÝÚHl½ª­ZíPÑõµÜ{o£Gëw݃¯¬ÏRR$Ó§ûiß^OVã[ÞæÏwÓ¦ës8ø`+Û ;ê<õTcÆTÇ"Ûkû–]ºè{lN<1dш׽p¡¥¡›¦À0$ùùVN÷+¯¬@J%©|Ív3«î ÒžÓO¯Â0ãÆU1{¶‡¡Cà _~çÎÑĽ¡`öl/o½U°DÇûÀ Š«^ǯ`ôè6üë_E &ýßKí_Äeƒ‹{ËßÉßZpvD($q8¢Ü}wi" ÃÆÿŽ;î(kvYU˜,*ð0䈺’éá#ê&ÍèÒÃ*wûƒq3 ü¶½š@uÍ–,!àð£jî=ÿr$,)¬¦ª²fœž3aç²ÓU–×ü}ÖÅ5’ߥ7Dš¼7þÜ 7Ö_¶¢¼îg™Ù²Ñºw¼ç¤3-Íÿê[£QóÌâº÷ë 7ÜPΤI¥InE…¥ÅJ­èh8ûì*ƯHø4­ïѨ¨³øTVªôèeÞ¼-8Ýq»[qÇ¥H¹6Q¿EB‚^½"H)˜5kÛ¶iäätáúë˘4©”¾}#Idnà°ÃBÜ¿ÁĉY<òH1;wbùòMuæze¥Š”pãep@G&M*#5ÕäÈ#ÛQ\¼¾Þ>1"ˆÛmòþû>Î8£E‘p@4¦±×µ  äñÇÓcgðÝwÅRŠ˜)Û2u|€¢"5fö…®]£ ìUa&Yº~þÙÅÍ7—‰$¿c\Kì×/Nè²ÁóÌo¾¹ )-Ÿpü˜T)K–8¹ôÒÊDÝR ?<Ìᇇ‰F‰ìÕ˜ûkᅫ—‰­¹~½–¤”™¦ØA‰’tíEQˆY^, B\Û®¨¸Ý–¯à‚ *iݺ3ï¼S@Û¶ìKÔ·v­ƒÎõDûý&n·díZ­åÌzަ{OÁ+¯l§S§N,Z´ec‡”¬–IÁ‚Í|õ•—@@pÁU1—GM³Þû˜cjî5k]»v"?Cî^Y¹ÒÓ)èjÁñ IDAT ‡­ï“pXi°îx=¥¥ ùK( ¾#œN“ßw2`@Ã,[æHDÛÇëû÷¿ Ú AafÎôròÉÕõ˜é-ò-(X®jHíçŸ]ôë¦&¾új+RZþñŽ£lØ í±­¦Í©©’ªªu1¡´±X*b{×#tëfI ™4)3fÎ7Y¿^Kl”Ò‚‚Áµ‰ºãÑïõÍŸÊJÁ–-0 «OºÉ]U8à * È 8+ÐmÕªe¸Ý9Þ†)*ÚFVVEÙ#HÅFK[OlËȾ÷›’¤½7õK =zD7T>núýôÓ<4MRY©ÄÁ†„?Á„ ¤¤t#;Û`ûöõ z}uƒäý÷}œw^×_ŸƒiþNUUýëT($èÐAO$m …D’)uG¾uk²2+ÉËÔ©)tïm´? ­²µƒ³j·Ûm j úô‰4èBTUX¶Ì‰Ói«þFqÁ%ÎEee C†„4 §¥™|ñ…‡óΫ$€%K\ Nª/Œ& âñÇÓ3¦ºã¨&_I<qÔ¨ 5ÜH˜âA2bDY³¼œ{neƒëüŽïQ#øÔ'\%[jûÛׯw$\ñ{ãu›¦eY*/&»–k¿cS™w‰Ý0 ŠŠ¶c†a(ŠÒ¬C6*+ËÉÊjMzzÅõøYv3Ë–{¶­ŸÛýÞ"ý¾ôyÜ-И&”–®‹™©•F-9‡¤¤DåÿÛ;ïp+Šóñf÷´Û \:R¼T¥j¤ (" F±÷$Æ^±D£¨Q‰šÑ“54‘˜`,_KL{AQ@z¯·ßÓww~칇{¹íà6x?ϳÏ=÷œÝÙ™Ùyç}çw.¹¤ ùË6B¡Æýz,ËÕÄþ÷¿Œä\lS]`^žÃCå3qâ6ž|2‡çŸßÖèµ£Q×I1#CÃŽf“u6xpŒ«®*âå—·×ôÆò®ë•CSm¢wo‹wßÍ`âÄ0¥¥Gq=8?;Ûáí·3ËK_íeÚ´p£å2rd”W^ɪµ4¯ñ¼Ô|Wó\Ÿ|âçºëÊÍ÷äÉa~úÓN žÚµk։׸X4÷žÔü¾q£h¦¡Á\,¦˜4)LI‰IV–Êòòì}þîµzlŠ>úÓô¢ujs’ùùÉÍíL8\ÕXDŠ“HqB« §˜6æzã§vî‚›5*ÊI'Õì Öø¹³g—sÜq=¸ôÒ.ÜrKI“eÛ©“ÅË/g6|AÏžq_êjÝn¼t‡µk›ÞûgO‹×^s#¼YI¯÷æú<¥j{s7|vX„'žÈM®c0 VËäÞð¾ê5÷ùúk?‡i´\j‚çìúN5šÛ† .¨äãÝP³ëÖyeHƒÏ8xp”%K|)µ{ÇÑôécQQáZo>ùÄ—0¯7^÷5!gkòVcáÙýˆÇaÒ¤¥¥¦é® èÑÃÚç}å^ tÇÑŒ9Š^½Jy´¡µÃŽ‰Ç£í°ƒÚRc”£•b¹ MbšpÎ9•µ:鯉DZ‡ÖßQ^n6{íc|öYf³ýRðƒTpùåE˜¦ÃæÍžfû/Ó¬Ýé&ÏÍÊr()1‘ìj›ªë3dHŒ—^r£Ë¥2;V{IW(¤ÈÎnJÝ©sûv“#"jó¶ ?þq‹e¤Ü_ײ+~øÃJ–-s——}øa É)Û†¢"»¥°a QçÎvÒ`—@ß·2jL`k23¬_¿:åùðòòÇ&;» Ýòæö ZR˜Kä¶Ö'R½y! R^J¹€••&ÍuŽï¿¿‘Ã?(¥ëO›âoËaÃ_ƒÎpõ§TÂyQ5hú­Í5×”ó«_$œéhrÉn#Zª®.ãLJùôÓ@eÚP™(FŠP^n°q£‡I“ÂÉ9ö† £FEÙ´ÉL¹.ŸvØý<8ÿüJ–/÷%…nqqã«L¢QEÏžVÚíi×Ò<{Ÿ·Û}`r7Y´h‘H,åý\óó;Ó«×@âñ˜ôB²ÁËÑÚᎅ6héTVI¾1g»]Z bäÈ(gÕ—^ÚÒ¤Ò+æÏßÂÓOçò䓹ôîo2'Ÿ\ÍOä&Cç6umÇAƒâlÝj6+”?ý)w¹^Óç‡ÃŠ«®ª`ýz/6x˜<9ÜDU§ 7wíx\qÌ1¡—+7tm7z›{ý>ÈHz´76x**²’ƒ¸Æ!»¬>šuëÜP´ß}ç£sç}/Ð÷:°Œã8 6‚CÆÊ•ËR4g”—om´¥âX·¯Í½î߆—²-GͶ­\åbÑ­ÿž µ­”»¼¶›UUð¯mÄõŠÖM¾'Ž'Ÿ\ÅÝwwâ±Çò¸çžu–wîNuµböì2/ö&ö÷nüâÁ ¼üò&î¿¿€SN©Nä¥ñó‡ðÑG]“›Î¸kœFó}È!Q¶o7Ù´ÉÃ9çTbYº‰X'šŠ ƒXÌ]¾èn¾ÒðµC!˜:5Hi©¢ €Dð!ŒþVÿÚŠ; ”r(-5ÈÉ© ¿Û05»½E"Æ 'ò¢Qdaþü.¼°ÊäÍ7Wóûßwâ׿.⦛v 5ضbîÜ­8ŒWÌìÙ;ˆÇÍ”:.¥d.·ÍêZÉšè¶çK[è-¯´)'ÑÙ+ ¬„­X²$@Ÿ>1l[3iRsætœ¤YÝ4ÝNÊ4¡sg Ûv£Î5/+vÍ¡×Ü[h=Ñ"©¶)wië‚РŽ&Ðkæö²³mºv=ŸOsÄ!æÌÙ–Ü:Î45¶½ëüšÕŽ?¾?>¸™êj³Ž0WJ³i“—êj³ÎݶmóÖ»·Ðšº¢Ð–ï™ ûGÙ®—­ƒK—.Kþïó9lÚäÅçÓ|öY&C‡FÈÈp… òò,Ž=¶˜GÙÈ!Q,K:,AáÀ ].[«½x^©]ŸGѹ³ÅOÚÿþ7›¿ÿ} G]Ì;ï¬äøã‹))ñ°`A>ù‹Á½÷n&SuÌÝ»Çx;vébÖ:G4ÆÖUÅ˽­úÒÖA4ô–Ínùµ,xàIG8Ç×__I8¬xñÅÕuLìѨJ RD ñÜÛY} mÕ-‚ÐûË)ÎõDWɹóAí8îzóÝ·>ÇiAá@¡ t}€Þ[tEAÊ^„={gÛýz«Ü1é!/Á6Ú ¶¥ڪ쥱 B{g;¤†Þú¶r¥ 7×Áã1Ò)¥›ÏtÓ´Æ=ZsdY?_SãÛ¡Éðw¤òêøuŸ­ÉÉÑ®½ìOm_ú i/» )l[íOzó™Þ÷x°m…RýÓÈŸˆ¥ùLé¦ñ‘4Ýž¤1H£ŽtÒh 7/ÍIgxùç ±4Ò4Õœí´ë>½4­U÷=¨ÇtÒäy{Ø^Ì=(çtÒìIÝïIš–~Žš|€h §Ù“zô%îÑžê~k/éñÌ3Û™:5¼’L:‘ˆ‡ ¶á¤(Ÿ²²ln½µ·Ý¶5å{dgÛÜtS_î¼3µ4JÁWôçÏÞ\/NSi®¾ºO>¹™ªªÔÒƒ&ß}à°Ã‚i”—Á×_grÄÕ)Ÿ‘á0sæþùÏ5u–Ø–MïïÂé§U‘e–¡/WF†ÃŒCY¸pmrµBs¼òJ'œP–Ö´Éë¯ç3mZùÔã¶´ÒÌžÝ{îÙ–r=^sM?þßÿÛ’r=\}?<½4?ùI_~÷»ÔÛX,¦øôÓlÆŽ­Jù–¥X´(‡‰+S–fÎÊÂ…«‰F´Ò¼òÊj"‘ÔÒ¼ýv“&Ub©7˜ÿý/—1cª{H¤V÷W]ÕŸûïO¯¯¸üòƒ™7ok‹Õ#À­·öáá‡SOcÛŠ÷ÞËåè£+RïÉ5¼õV>Ç[žVŸüÚkù|jiü~‡NH¯î}>͉'áßÿ^M8œZš?Ìá°Ã‚øý-aqèÐx3ò¯jèZ·®ĶaܸH3¦Ž]äç[äå9Œ›úº À"7×aìØÔFц¡ñzaÒ¤¥¥©U“RŸŽ>:õ4••™Ö³ƒ±˜7å4996Z+&LˆÔ{y e±:ŽìFo„L£ Av¶;ž0!B(”Ú ·d‰Å¸q‘z«šbåJ+å:©©Çìlvš¬¬ÔÓ¸õ¨ÓªG¥4@úi²²Ž>:BYYji¢QEe¥?­öbY°}{FÊiêÖ}jÂ&+kWš`0µ46Ä;6’Œ>™ [¶Ä3&Š×«S®ûÌL͸q‘”ûµÂB‹@ õ4Ji23Ó«GÐä䤗Ʋ`ëÖŒ´ê^kX»6žV¥4Ë—[)§ÉÌtìĉ‘”' ™0!õ4¥¥ÆŒ‰$wôlò¯Cí¶ÖÒ÷Lõ¾‘ˆÁôéiå31˜9³"y¿æp8ûìÂa#­ûœyfiZiÒ}vGÓ§O,å4±˜âÇ?ÞA<®ßIOivÄûÒÙ£È4Ëj¥I=oÆ…Ó~–Ú!ƒS­ÇN(O;ÍI'¥—æÌ3ËÒ®ûÓN+M;Mºïœahú÷¦u¥ ¸8’V{¹è¢¦Û˾H³'m¿¸8Šaè´êþ”SÊÒºO8lpê©é¥9å”r"‘Ôë¾ö¶Óé¤0 ’vû4(ý4C‡¦ž&‡‹.ÚA,–^Ý7ô¹)úõ‹bšíÛqº]z¹×Ž׺÷Mõ…Süð‡;Ó - ).¾Ømt©<ŸÖpóÍ[ …TÊå¡5Üxcziö¤Ìý~Í!‡„Sž¢ˆD¿øÅF¢Ñ¦òåþ¶ÓêCg4DKSHS—ñã«°¬ôŸ½F+Hµ/¹$õz¬IsùåÛÓªûnH¿îgÏÞ¶uŸ^ý{½0|x(-+ˆi¨QÁ”ÓD£Šyó6‰¤þ,±XúiÒ}ï;,˜Ö³‡BŠ«®Úžv{¹öÚmiµ—k®ÙÓºO½í§[5yduZi´†1cªRN³gu¯ÓnûÆ…Ò~ö}¯|6W!eóYí‘jºqâ•‚x\¥Üy(Eâ…n¹{Լ̦™~'à8éå«ñgÑõ„ú«/!§X,½à@®cãžÔ½ná2N¿î[ú5eïšÓ­{Õ¢i”"1£EÓ¤:¾7ÏÞ^Û h'í¥‹-]÷5ÏÓÒí +ËIKÛnka^¿¿Þ gžY’–€ÚŸÈÎv3&ØŽr¤0”¦ÜîÞ*w;唲ºí?ùä**ÌòÙO8¡<­ùóýÇ_KeåY÷‘ˆâƒ–¦ìŸÓQh—sèŽÓº&÷@@'úhÃãÑm7 QõëßTEž•­R'~ÿ]÷yyV"”ò÷ü>ŸnŸöBnî[÷:Å÷»ç—9t¡Íë»ögCÙtó,ÅP– B…§éÝ)˜Hq5£ðœÓÔTU™»Í‰¸K…23"ƒpØÍ]ZY°›Äéâù.!Ì¥ðÛWG¹¹6••¦¼B‡h¯YY6>ŸN,³5êxö{<šìlËRTW»mZ)Mv¶“”®ƒm{V€êÓN'ô>?”ÒD£Š †0hÐþûßœ:¿k ¿üewúôÉÜ/á(&GK*9„³Â<Öbm@ŽÔW¨Y¢£Éɱ0`D‘L9Ú÷á8pê©èÓg$¿ým×:¿†æÍ7s0`3f J¶ñ%K29ꨡôí;‚Ï?ÏJXŠÛÛÑ4í4°Ì¾7¹+—^Ú›nÚÌĉUœþÁ{ly"Љ»¯úòå¾ýv1·ÞÚ›_,`Ö¬Rê¶øÐMc*M7ó ,вX»°‘)¨®6øè£¦L© ºZñê«K±,©¡Ý·^^|±€I“*xá…œsN1眳3°('Çæç?ïÁûïÃË/pÛm=ùío×òÀÝxço1 7xV{ܼ¨ƒ.[Sûü°mÅ7ßd0eJ%&61M÷^Ji¾û.À¨QA,KqòÉe|õUf‹äCŽº‡ƒI‘¹´–™]Žöp”–z=z8‹eãñÀÚµ~/ÎB)زÅÇ»ïæ²bE€ÇïJ(dòúëùüñ]“ag•‚%K2yå•.,@k•ˆ€%‡-{†«mÏšU†m»±ÜðÑ®=pÃ?>ŸÆëÕŒ_Å›oæ±m›Ï?ÏäÒKûsôÑCY·Îßb²hïZF »[Ö?ÚóœŠÖ»¯9×ÉÎ'6ðùÜÿý~M<.…­5xó©t7•Zšž=cTWydx>8Ê~p0¦ Ý»Ç8眬[`Ç“'áðë ι” ùÛß ÓŠ™.{C,¦ðûur¾¼¶hŠDT2׫‰Å *+ >8Ê£®áW¿ZÏu×õé¾"{dr/,, /¯­Ç䆡PÊÀëõaÛ{³*½@©bšÐ©“ŪU~>8‚ÇãPÊ!Ð æŸÿ, °Y¼8ƒÞ½ch­ÅH8 ©éíÄæRvòý,(p?uT%6x©®6éÞ=Fÿþ/Î"3Óá©§:sÐA16mòrúé;éÓ'†L¦­ã@Ÿ>Q¾ú*ƒ©S+X¿Þ— •“c8TVš†Ãš5>† ѯ_„ìlÃÐäæZ‰©ØŽ×^÷H û|^FŽM$Bk'!ø\þÍ7_‘››Y/Mvv.Z;u4ã­lwí¾%}¥4wܱٳû2uj9#G†ˆD Ö­ó3wnO~ÿû5|óMO>Ù…‡êοÿ½´Åò"@¤'ß›ºïì.m§&vR»Ç×TUy8°‚‰+qÅÖ­^yŸ„VcæÌ2Î;o—]¶¥K3Èʲ©¬42dk×~Îøñ•<ùdþõ¯~ùËuÄãŠ>}¢<÷\'^|±3·Þº©Æ(h¡ÝÖlÛbÛ¶Mضƒm»k† ÃÀqìFL6‡>ììüÝÅ,ß|ó~M2Z¢µVŒ[Űa+±,En®eA1x`Jižyf%ÕÕ'žXJF†Ó껾 B{Òг³m¶o÷¢Ô.K•i’4ïe­æûXLqþùÛ™>}(<²špؤsç8Ó¦•‹@Z…ƒŠòê«K‰F§Ÿ^‚iº; ¾ÿþB!ƒ;ïÜHe¥É©§–mÌ™³‘ª*“éÓËÉɱÛI¨×VÐÐkðû}<õÔ|ŠŠ ©ªªæ”Sf6z®a˜lݺ†gžy޼¼\´¶)--çG?:x<\O›n)rrê8LS'½}>‡ÂB§Uò!í™HÄàå——óÁÙ˜¦æ¿ÿÍáŠ+¶ðé§Y\uÕ¶lñÒ­[ŒÿxÛ¶y©ª2¹îºÍ,_`øðO?½‚?ÌfäÈ Ó§—íÁÆ9‚°çdeÙdeÕpXÉ~¿æsM_ïñPï»ö8Ðn1‹Å6l×^ûSæÌ¹Û¶›<ßçó³qãn¾ù{ìÁVó*BjÇÀa cYŠ#BŒJþ>t¨û¹¸8ÂñÇ»[ÃN›Vδi»¶‰2¥‚)SÜ-ƒ÷dãAê½™-'ÐµÖ :ˆ?þñAúö=(¥ÌÜ}÷mtíZÄ€ý˜4iñ¸„øA„½eºa(寔íÓ§wò»Æ–¹ç*,ËâŠ+.Æ²âØ¶izê }ÑÚA¡ºizøàƒÿâ86–e¡µÆ4MLÓD©†—¶oÞ¼’’’Íhmã8:;×@)£–÷{ð.‚ uÔ]½/MîrsóQÊ 3³öÒ´º»¿ÔÖº=/AaaWzõØ„Æï%¬®u=AAêá}%ÐµÖ \œò¹îaá÷C0¸­ÙŒºÚº’åb‚ ‚ЀâÛ”POÛä^[åF›Ù™›ÛH¤$1·î’••…×롼¼¢‘T~Ö¬Y¶OG4‰R%‚ ´{\ëF£­t$ŽÇ0Ì}#Ðk£”Éúõ_RPгÁß33 ê„O­¨¨`Ú´ÓðxLþö·§ÈÈÈh誘¦ÁˆG×™WJQV¶@ ŸÏŸj)-ÝÌ_|‚išÒRA„vMvv£G­'ÿ¶o_O~~gª«·ì; }wí7;»ÅÅãeÄã!âñ*LÓäÃ?ã’K.`Ö¬›¡8df îHZ”‚ÒÒôï߇h´ŠTçÙwìØPË#_AÚ399…””lL u¥;vl G¦§¼[mûT¯× yýõ·yè¡ÇˆÇã)Xà»ï>¤ªª DZ“aemÛýìjݺÖg’Ÿ•r?km#Nv‚ BÇAñÈ#¿ã‘G~‡i*ÇJÈ2Ú‡@Ç-fÍ:éÓ冮Âçó5#Ìß}÷ëÖ-ÁïÏÄq,j6†°m Ã0ù׿þLii ¦é~Þºu†aðÊ+ϲvíÊ„Sž#mCAèÔø©p×]÷ñüó/&öIqš¶h´fFk¶ZMußtÓô%…¸ã8µ®cG;v&ÅÅ#ˆFCŒ5™¡C$ qè¡GqØaGcYQi‚ Bì®ÌËÎÎlpÓ³†ð´ß‡Ñôê5pÍ îÈD¡”BkÛ†@ÀÇÆË0 ƒ‚‚6n\Ša˜ueãÆ¥x<ÞFÝ‚ B{£Æß«¤¤”yóîaÚ´c°,×*Ý¢›³ì>’h^ã6áËØ¹ìIDATAgRÑж§gÏbrr:Q]½3éªï8:¹U£+àuÂ›ÞØí³ë‰ïÞOæÑA„ŽÁå—_„ÖÇ1MOJÊé t­5¹¹ÝÈÊêŒeÅ<ÇçÛµweYL›6pÚšò:WÊ`ýúωŪ•ðöSضÍöí멬ܞ’€vã¬ÄèF4uA¡}ã8šåË?& R{•W*Šó t¥áðN´ÖD£ežW£U+¥’óàM s¯×O^^yy=µäçwJ+¯ƒ‰v.‚ ´\+sÓòtŸ ôMz_/ïöz5Ôhj[Uñ\Aö?š’©áðö&Mï{%Ðãñx“ÏÈÈ%«JË1méÒe,Yòu£žðZƒÇ#Qßjæj¯hoH„>A„Ôp§ÉU`}ûÌGŒjôœ½èZêUâóeì6ÂpÕú÷ÿ^Я© ñxœaÃF7:zùßÿ5kz8PÈÎÎbøðív¤ùé§_Ƥ¢Ašaðà6Ø—Æb1|¾¦Eö^‡~ÍÏïÁ!Sê|ûÞ{ï1~üxb± UU[’B>77‡òò ü~^¯—ªªj²²2‰Fcu´L­5EE]عs[=g¶’’í-bê︺CQQJJ¶cí©PápËŠK] ‚ 4Û—kâñ;w¦¬¬¤ž@_¿~  lIî õšÌ(¥øì³Ï8öØc‰D"uΪ¨¨¤  ÕÕùÕ¯aáÂ7øä“ÿpòÉg3gÎ |p¿:×ÔÚ!bË–­àCcY6±XLDB=îñšûš€»P*áQ©0 •0¥¯G£ØG!¾Ü¶-B¡ 6l¤ÿ¾X–…¥B¿úýFRŠU«Vqä‘Grýõ׳ûZónݺ2|ø!lÛ¶ƒeËV°xñb±0o½õ.=zt¯w]Çq°,›ÒÒr~ö³_`šžD wqˆÛ}T§µÆ²âضµGÇ’%ß°xñ×XVœÕ«×ðÉ'Ÿ‹ÅÙ¶m+‹}@4Kûš–e%bé˶µ‚ ©à8îÖ©–eñÙg_qãw`Û¶mcÛÍïK²Oggdd0eÊ ÀÏþsî½÷Þz]<ãÜsOcùò¬Y³Ž /<‹‡þ#ÅÅýÉÉÉj@ÃS¼÷ÞÄbq´®ÙœEÔóÆ‚ã8{täæærüñÓ“u9cÆ ‰i3fœ@nnÞ]×­+©/A„t5uÓ4Xµj-•••€NiÇн6¹G£Þ{ï=ºwïΕW^É-·ÜÒ V[œvÚ÷9å”ó8é¤éÌœ9O<›Ûo¿ÇÙý|…R–e3}ú±ìر3yŽÇc&"ÀI¥ïø¸QñöTîÚµ+«V­À0 Y·n †aÍæÍöØ”ïñ˜‰€RO‚ ÍaFr Ô4M^|ñ âq×ä^³»h‹ ô léÒeäçç%…Lý‡&33“¯¾ú–§Ÿþ=ÅÅýÙ¹³„óÎ;£A3ºÇã!`—^úCÇ!‹Çtý²òøÛ]4g'UD£Q§„²²ò¤C]ÍuÇæÓO5¨é†A^^VJæ‡@ÀÏÇÿöhÚV rs³°À‚ »ãõš|òÉ¢ãwøý¾f}’èŽÃ&V[ ¯7’°í0YD£U ^#­ª7ª(/¯L¦//¯¨'˜;w.bòäiâL%‚ µå²³§&wep¨@LGÂUaa×êûš‚‚\XW/‚ "Ô§QÙÛ¨@×8鼺ߩÖÑšE9oýâ–»¼ ‚Ï—eEÛåÔnSyòHÕ –e±}û*zöLj{Õ ‚ ìŸlÜø-ÇŸ@iéš—wè{L:‚¯ý;ði]cÆgCAÐ^]kz÷>Ûî˜+tD ï1ŠÔâòHd;A„Ñ««¦C¬Ö^‘µ7çX]k´Ç„@Ul»(2Z£M²2¡ªú€Ð]Ýx~b±8ÕÕÁgNN6¦i …ˆFc(¥ÈÉÉÆãñ‹ÅCddðûýضMuu5Ž£)(ȯsÍX,Öè}AÚ“ÀF£ÛÒÚ!/¯ ‘HE³ýl^^.••UûtR$’@À_çðz=M:PiÃ@mÞ‚÷õ·0?ÿÊ5N§áp¥ ó‹¯É>áltvòZ)Ì«Èü=Ôâ0fY§žz!‡:Žã?êê`½½nÝÆŽÆ¡‡Žåúëç$— Nœx‡2†)S¾OYY9áp„SO½€aÃÆ1mÚ©,[¶¿ßÇQGMeèУ:ô(”*ä‚ .a.B‡`ûöÕ”–n¤¤dC£´t[·.Ããñ§40(.ãì[m¾Y ½¢¢’ÎGáñ˜X–…ßïgÆŒãx≇Þ(EkŒuÈ?ê…Å÷Ä3›·ûþ ”m7®{<€†XÜýÞ4ÑÙYàó¢Q`ÅQvÂÛëÓǸ…"1£íõ‚¡À²Q–UG³w÷€a¸ƒ‹¸åþõùÀ¶ÜûÇ­dµÏ†B{<èÜœ¦±Î›÷'ŽåÒKÀþó>W^yóç?‘ÜÓ<33ƒO<›—_~Žââ~üèGWóÊ+o0cÆTþñgñû}¼ôÒ¿X°à 8ýôS8ùäD£Q®¹æžyæ÷¼úê‹Äãq† 9йso“^B„ÖN½-Ãk(+[[O.úý>,ËNÈP˲’Û‰ƒ,Íãñ$ûD­5>Ÿ7Ùçz½^ÇÝ ¥9á߬@/(Ègùò¹õÖû¹òÊ«xê©ÇyðÁ{½¸6þ…¯üÃCX£FàôîIΤ‰ž{:æGŸ¢"Q¬‘Ã\óµÖ“sÚ…8õF•”b=ŽÈ%ºòÁÇd^{+F…k¾>ö ƦÍdŸw ñ±ßÃ\¶‚ÐÝ·b>ÿ ð¼öäçb~µ”êçGçå&…¹±eYW܈=d *&rÙqú÷!¿û¢_€ª®FUUSý—?â}ã2uÄaÛw þ¢¡*¥øâ‹¯yüñ‡ÐZs衃yõÕ7똗vî,aÓ¦-ôéÓ ­5çw:‹}ÌÌ™Çáñ˜ø|^.|ƒ³Îš…iš¼ýö¹ð³X¿~#ÿü竆Rª–¦ÔKLî‚ ìwƒA ûó£‹iš|ôѧ¼ôÒ³æ'…ùüù/ñÉ'_PYYEÝùÉO®¦K—ìܹÇq˜8q&sçÞÊØ±ßÛ{ Ýq:u*俸3Î`Ñ¢×›¶ù&ÆÚõÄN; âqtÀ±y+Êq0ªª!®%ü <ËWb9’ðœÁ¶É=| áÙ—»÷>¨¡‡î¿Ÿ¬³ Á ~Kð¾;±&ŽÅ\µ–ìgP±e)WßBå‡o€Ï‹ïŸ¯áy÷}b'Mw†¹b%ñ cˆ^|dg¡M‰ ý>Â×_.È'oô$´é!û¬‹¨øämœžÝðýãU>~À4@Û¶ñù|ÉÆæî…¾kºÁ²ìD\apG’vªaš&ùË߈F£Ìœy¡Pˆ^X@ff,&77'9ó¸å–»¹óΛ E˜ ‚°_ªI†ÁM7]C÷î]yþù¿s×]¿à7¿¹/)_Ï8ã&MOŒ²rˆÇqzvÇÁ:(™Ÿýß”¤).îÇþó't<›6maôè(åš}lÛ¦K—"22”••Ó­[W^}õ-† ˆRЧŸþ+ÿ÷ïð—¿ü‘h4ŠÇcòä“¿%‹áõú8î¸SÑÚ ,]ºœ÷ßÿ!CÊîy‚ ì×ýj÷î]q‡#eþü»ô_Ã`Ö¬óú'Ž9æèäo±XŒ÷Þûˆ[n¹Ž#MUUur¥‘ÖšûcHZA›£E–­Å§NÆóÕ·t„uÔTÿõ ˆÅ1?ûUYMìÌ“]m\kì^=ˆOD~Ÿa8]»PýÒÓXòd2ˆì“ÎÅ\³–êǃÎÌ |óµd;•‚.‰OOð¯B••RýÖ?È:ë"<Ž5jÁ§E{žxâaú÷?ŒI“ÆÑ½{W”r§69f"O<ñ,=ztOy+j5ú®ñú¤sgòËcï£zÍZÊÊÊ÷…íó&<ÈmˆDQZ£=P âµ<еF{çj ‘ˆk7 ÷;¥@ºžë€öû]õšk“ðbÀ4Àv’&|²2QÕAדÞïw½àéÈÌDƒ®Õ #€JÌñëŒ ×#>s=à#‘ôùý#°L,cÛ¶ôî}ˆ¼}‚ àØ&?¿êYµÖF&™™94-T¡µC(´€`0DïÞ‡oÁ0\å¨öŠ¡P(ŒÇã!ð'Í B¡>ŸsϽ„›o¾–¡C5ºL<qÙü9ôwMx¨…Ë(å í¸U÷»m¬v!)å jk·s½KèÖú@Åb® ­SŒ@$R?/ÁPâz„Ãõ%~GvÝ£öµ,KZ¹ ÂŽ»mx5UUÕMžS³2È0 @,KZ#k áp$q=;ˆ Üen‡v4Ç Æ %§<-)¡_÷n,'E ‚pafÊçfdøðÃÿK®=O…h4Æ'Ÿ¸sîésèàš‘lÛBk ‚p ÷‡û¶lveX~zºÃ"ÐE˜Ó©Sºu,û¡ ‚ ¶íù~€£”¢ªj ²º B²gìËiw膖5ÁbãAjÑts·•VIîÃÃBޥʬ–ŠA„vŽeZu„º§¶–VMˆ I) B§¤º„²`Å]Š©ŽV³©l»$îÄYµ}ƒº ÂðRP‚Бº¶Öд̥ B‡g[å6ÆõGÔŠ²±|#Ãz #ßÌgeåJîz0²°2¼R J:0»ËkOíŸ<ø0=1)%AèàÒk8(ƒ˜aÓ»s_2=Ù”;Uäg’cæ°ÙÞŠéñJA B‡EÅ©í•è¶ ßû.Ëî&å$û ER‚° •1lø…¼®ßjHC‡ŒüÎø|ùÈrdAAhÇ”BL7¢¡×P\DkÙKAÚn¬ø†5XFk3»Xb‚ B;B;Nx}ƒ¿5¾n¥ anšáwµù€ßÝ lO†j­ñzÝÝIÛ2ì¨Ö§f×–ÉGn¢¼L»‹ëÞÜGkMŽ¿î¦u‚ Â@ã±æ÷h!êóÏ>˽sï'# ¸áÚëY·v-†‘¾tñzþO±ð_ ÓJ¿kZ`ß_GñÚ¿_å7<”ös¤’—x<†id‹¿XÌsÏþ5í°‚¯¿úJòsF@qì±Ç±â»ï$þº ‚º@×Zã8NR£þÇßÿÆ-snÁ²!#3e8ήsj§Ùý;­ë~çóùðz½µ~×õîY³óLÍïµ·•køºÞùµ¯U?àñxñûýÍ>ÿîyqvÜ7ÕºvÝt_P€­áC‡3ë´3›)£úßÿòÞ{@»÷ˆDá™ùç™§žÀë5]AHqsÛ¶éœíåÞy2ûÆÙ„Ã!,Ë5ùz½>f_y)ãÆOä‹/>ã”SOçìsÏä·?FyYk׬¦OŸ¾üì®Ûyò©çXøò=Ûv¸ãÎÛwƒU+VpþÙ§ñìü—(êÒ…éS&0ãÄïSUUÉï~ˆ°£yÿý9kÖ‰\våµ=åþµà%"‘0þ@€/?ÿŒ—_}“‹p.>ò;çsß=?çäYgPPXÈÁ½Š¸ù¶;Ù°a…<üÐÜ{ÿ,ùz1æ­7^çœó/¬÷ì‹Þû7_5§žy6_/þ’×_}…m•\sù•lÛºáÃGpÜÌø÷?ÿÏç㥿½ÀKÿz ¯ÏÇŒc&2ëô³Ø±}e¥¥˜ þ÷î;|ôá"®¾îΚuã&L¤¬¬Œ‚‚Bæülï¿÷1ç~ —]}-/½8ŸÙ7Þ©gœÁ†õkyø×óˆD"Ü~×íØv&ïÿï¿d˜P×r#A¡•ºRŠÉÇLeðà¡|óõrŠºtÁqܹtÛ¶¸àGsú™³¨¬Œ2bp.<÷L.ºär–/[J°ºši“Ç1÷®Û¹ä‡ç±µ,DFf^/D-ÅŠå˹kÎOùèËÅØ¼óÖ›\zå5\tɈÇá¹gþŒ Ã`ÂÑ“¹õÎÛˆF4—ýè¾\ö™&\rÙlܰ!¡e»ÂÍëõaî®9>Ÿ›o½`0Hï.yü桘û³9l.©&;˃R Û¶ …B,_¶Ƕ}đ̾êR^øÇ+ôëßO>þ˜wÞz4Êàšën`ÜıXt)êJEE@_-þ’²ÒRnûÙ\N?sÕÕqž~òO˜¦‰ÏççóO>á¸é3™4åXlË┎cîÏæ`GO9†Ÿüôf¦N›ÁOo¼ŽSN;ƒƒúôeö7áhˆD\¾cû6la.‚ ¤fr7M“·Þ|ƒãgN¥ê˜•ÇaØðÄb®­¬¬@#‡ÌÛo¾Aee¶m³½"Šiš22Ðb1Wî*¯ÿ{!}úöñÁ0`ýºµ <„X âq›¼¼üäýŠºt%ƒ ë×ѹ¨+® Û0hðPB¡ u¶½«%ç ÃÀô˜¨Äùæ•dffa˜&1 †‰ã8ضCuUUUU8Ž& Ò§O_zôè‰cÛÉç>xà@, >ÿôS®ºôGìܱƒxß,ùšP(ʯy^¯—œœl&NšÄäcŽA)ÅQcÆñЃóÐZóü³OãÛmžÝ4aé·K8ëÜ ˜8i2ïý÷?hí0fÌxæÞy;¶í°ø‹Ï(/+«SžcÇŽçÕW2jÔáŒ7žììœd™6´ÂÀôxغe ï®yöîÝ{`€8Æ ‚ iz¹ ­!++ÓÜ¥ùþà¢KÔ·;7^w5Ïüõïüáÿ=CÿyòO$//Ÿ°†EŸ~żûæÒ-?ƒ¿¿0é! qûsÈ/(ä¾{ærèˆC?a"=:e1ï¾¹Ô§/~¦aàóùEáÅü›ÇNdøÀ~Ìýůè\TÄU³oàþ¹w3áÈ‘œ|ê(¥P 23³J»"33“o¿ÿ1œ}*GŒÌ%W]SËêàÏÎŽÏ>ùˆ^E¹øý~lÛÂ0\g>¥–'~¿ùÕ/6°g{>&M`È¡‡Ò­ “?ýáwôèÙË60M¼^/ àâË®däÐbú÷ìÌë¯.Ä4À0Ìä A)E @kÍ÷ÜÇØÑÃÈ6ùEUUc'MØ“» ‚jô]ãõIçÎäióX±è-¼Þ<7°LVq~ˆ[`Ûð¿¿È’¯sç=sQÊ~^¯«XÆ¢5ëº^ؘ„ó¾> ,âqiºÂȶuÒc;Šñõâ/9j쑼ýæ;Ü?÷.ÞùïÇ\8׉Á„{=€xܽ†RÊ]ç 8¶›_­Ýµß5sÏÿ®üÔ(Ü5–m˪ë`¶uËf*++£a¸¿Çbnz¯w×,¤qãùýŸž¦O¿~"ÐA´à o¤´tt§ÿîlzïÃcJÍ) Ýõù´3OçœsN'Ù%ü¢µ~wÌ\!g—‹Õ=¯F®Ñv]C€âÅùÏqý5—ÓÿàbžÿûËÉ{¹Þõ5sÈõï»{^jˆFwý‰6~îîÂÑçó1ç–Ù¾u 3O<™;ïº`Dã8ªÎù±®cY» =¯ãÔÏ¿Ö$Ÿ1ék°Ôœ«µfÑûïQCâî ‚ © ôÚÔª–Ò =^/÷ÿ꡺£’6\Zk ;uæ… “ß#m/A•RTF¥ñ ‚ {)ÐÛJˆµ‡{Šy[Aè½fޏ¬´”X,F^~>@ Þ9¶eQZVŠRŠÂÂN†AEE9‘p$!]‡¯¢.]¤ÔA¡µºÇ£xyÁ^zq>Ó¦Ïäî;n㓯–‘™™™榩¸àì³8jÌ8**ÊY³z5?õ,«W­dó¦üû_/SQQÁ ˆ”*‚ Bë tøñçòíª tëÞ‰ ë×óÔŸþÀåW_—X¦ˆÅ,¬xœ›~r=^à˜©Ç¡Œ>üF~>øõ¼ûY°ð æ‚ ‚Ð4»½¤¤ŠH$LaçNÄã0ù˜©¬Z¹"9—¬|³ä+Š"ƒ  ½z÷!Ž ‘;[±¥ùyEAÚB {½îBoÛr× …BA¼5‹¿dgçM¬©RÊÝ.Ô“X`mšpñÏãâË®L®A¡•zA®ŸÁCá«/¿@kxü±ß2nüD´ÖlÞ´­aÈÐ|½øKG‹iV¯Z‰išh­Ùºe‹¿üœó.<_„¹ ‚ ´ÍΡ‡¢ðÚÛïqÚIÓY·v5]r9ߟ5‹XÌb̨CÙ¸³œX .¿êZÐÓ4yø±ÇÚ½âÅùÏsçÝ÷JI ‚ B[ t€üü|>üèL ¬!Õx<ÊËË)OZ9åôS9ÿ¬S¨Š»‘ÍâqÍì¯KDts» ‚ ´©@¨n ÄjE­ª¶VÝ4J©d¸Ræ‚ ‚ÐrR‚ ‚ ]Aè‚ ‚ ´ª@ÏóƒÏ‡†A„Ž*Ð-ËB)Åoü †!Îm‚ ‚Ða5t€ÌÌLDAA„öGJËÖ<Zkb@("ëÉA¡Cjè¶mÓ¯ÿÁ<ÿÜ‹"ÌA¡£ t­5k׬fÆõˆ<A„öGÊ&wGkÂÄbbrA„)Ð*%„« ‚ ´[$°Œ ‚ ˆ@AAº ‚ û„FæÐÚ±GJHAÚ ÚJO +eà„×KÁ ‚ B;£1çô:=,ö«‰ï*‚ í•êêÒÆº­ãôë7™h4&%%‚ íœH8\'Ø›+еæ‡ó/åûžŠòˆŸœ ‚ ´w”‚!ÇJU°ÊèѪ;Jw¢ôžÐWJHA:UÕU”WU€¥dÆ*á“&¥b¿B¢‘™Yiü×$S–žGj?ÎJ cœT0:žóÙ'sŒûé>f¦d 6ÉЈnŽc¢9fr½šg,ýL¿ÞN/‹L2Y»Rgpž#KÀ‚¨<óW—Ê#¼ÞVOËTå˜é66Ëû:lˆ#îs0¯_4äÌK_´äÐËs»ÀÜkšCßnf³q›Kƒ| ÌMÇú£‚Y]õ¦œ{ÒëºÓø2?jÀ…‚ N‹’R ›:…C˜!9ªê_"Œ„Òh|J$tÃÇwçJWåI§}º‰0z*ÍÆÎ”ëÄ•*Ó†ÿÿ|Óuû—ßßéE÷i=ÿ”QÚrí9ºIã*´¤ ÖÄÐ?A:æ>:‹,MW£\fy£HL‚{sd%erÉ„a6)k6o.©tÃJtÝPÇ…³ô´°&jƒ­+H_ý“]ˆªâ"-iÌ ƒ¼ç,ðõTÃ@rZ8«¯ï,VÒ†ñ`ŠOõ!»+¬+H¥%¨Js¤1ïeáòbpìÁ´<ÅuO¡3õ!¸Á ;ÝY äÙ-!>u‡L衪 åþ5¾”æHãsP´·Ôœ›v^\/Uš†•èvHLééy]þ^Azµû¬ÜŠéVi¶¬¤Wkù!1å§xù²îÝŠÎ÷*Íž•Ø 1Ý3úuéÍ$Wi.X©!¦!s¤ Ò{I©Ò\°RCL#h—+Hï%¥JsÁJ 1¥©þº‚ônæ(Ü£Üúuþ-°ÏõhÀ7û6ï1tã‰Õ´ÿ1ÿAÒw‹ áckÀòƒ?æÓ5dVNG6Çãó?E!8vàá±ù"4†#Ñx&!IEND®B`‚snd-16.1/pix/sceq33.png0000644000076400007640000000353111147553270012751 0ustar bilbil‰PNG  IHDR*_¹vé3PLTEÿÿÿ°°°ppp```ððð€€€àààÀÀÀÐÐÐ000@@@PPP    ÀgF pHYs  šœtIME× 0$G 8¹IDATxÚí[‰Ò› Y.QÃû?m9U‘¨‰í4Ì4üº²ËÞŸ„~koaxjg ¿Ó?XZ?·w÷SO}qòàæ0üP]ÿ_÷X¢è:ãw–Ù©ÿ© æ:²pºµ…¨¤ôÚÅöÌóeçê×wh?’2Yúԗ߉$‡D}´ã 1¼›¯Êe«Ê@k¾ë»b¥´²)ÝÊJ¡‘4§¥ÐOšg„ ;é‚ëp‰0›µ±ÉOÉÅE÷÷²@d1«ô©æ©|++ïIsÚ5égV´Ås×qö2ÛGÇ 7iÆMu˜6;˘–‡àŽ€áˆ]‹ gäC&ëÚZk¤%Ú[ *ÐK9¤•L&Ú™ŸßºŽ¶÷"©‘,hcabÚúâ¼öÚñwø‡X#£æÇX{܆I§5?— ${ÆÝC.ĆJ"ct%«ç­Œ¡FšÐÁ.Úцowö4zŠÀG”p6‚p®Í^"¸F/É(Ÿ”¹vL"§%“mD¸Ã?Ĩ¬¿lkØçÁ¨v¤t ©v,rÀ.ZÛµí^%ƒ8²6Ëêy4_‡:i6 &îìÖ:Å8¸Ó°ÿƵv(qŒ1ËŸuÉ‚%äp“/ 1ö.>¥•õK/L¸#>Dwöm(ƒÉó`µ`äÅ©vŒyãÛ”µg[MU[Ú¡‹´^ÖY ¡ŽÒNFêV@­›tY; wØk)d–U/³ïØèÜóJ{ ñŽð=Ýçèypß Gíœ)ÑT[ÚY°—u–byÂ^ÚÉh£`·jÇlj£àÂÔF˜ÀlDìjǬ¹§b’Ö Ãá!Vº¤ò<¸¢€âÛµó’H¥¹#œϲÎR`r@šÓFÁðÝ€Â\c1t\L„ÓQ/vmš9¸×ùèUhágíp"˜ÒåèÃ_ã8ÒxG|˜Q ë4ǃk°B8GÊ ÒùÕ)5™/§´C\-p-ˆŒ…bu–"„ä]ÒmŒÞÙICžB£ú!¶¾|êváU͇2lnâñsá!^CR»u'ñ:¥ÜŽ\àP‚¦}€sÛÈXø_AiBxWŸFØùÖIÈ^Fϰ"ãñöã:XJ}F;±È¢ÈØ»Éܦq`ö#¨‡X°Y´B+úôê~ÃÂØ_ëöI¶¡Y^;uõƒ9;X@â`tÛˆ úˆt—t;œwžcìYí,Õû"¶U­¨‡äE,ÈÂÜ¡ú#– 5–Wi­tùR4°í°Åwà9xÂ_ƒ ÝHŠØVó?îB^ÑN¼æ[°“#Zm‹Ò°±Å·à9ý¨ó$PU?ê¶U©O!¯-A¿‰ÅD{LK¨ëõØž±Å·à¹N>§¦Ózü%slKkiÖ¸¦:äÅ'uti \§ˆS¶ àbÀ߃çØc…ÞøÊ6õXl £Ft€åUCI;âÁ> KÙ.€‹[ ¼òÐàÑGGÞj˜SuYAÚ¢¿ÃÛ ~hyîj· oÐ/¼{Gº©ÁX¶ àbÄËÐø×®u`ÞŠéâÄH“ªï¨çLЏ4¿jd-Ûp1b‹Oòz%Ðmk6‡mázf57¨%íàç¾&‘4²ží¸±ÅˆÏ°Ùþ™>©JE޵¬µªà[À?}Ël*´¢}˜]YÇv.Flñ,<‡¿É6@l±‚ˆm­Á­T;qÈäò‚ Cm´K# j\„+ðÜÌEmêžA©’rx޳1QGüâÉ1äu¥2z›–ÕŽè,<¹¨MJÝ4(Uè'å yAÛì†L@£Ç]' ÉœM_äb= õ©A©,.ô±ü'ªǶ$‡L /Ìyœ1Ú8ÀòÜZ9ð2 õ©A©­KÒtµŸÄ Z /Îyœ0Ú8çñÕ")iUÙ¤Ô…A© ˜qß:“cFÙ´J i7S0_QÔi+.òI©óƒR50ãNåÔm3:˜V©Ó¢o;Ž-Z5g)©T¥6“Rù T ̸M;dr¯ã˜QuZ倶0óùÕ¡aÃEf#ç¥j`FCPi)ÜýÉAÚˆcFµi•#Ú'~ÈÂI˜ ^¸Èläü T Ì8fMï¾ÂzÛçÔ oÿ¬c¦}m1EXÊEö´óþ TÌÈËŠ!‚p ¨@â¦PÇŒ¾M{¹=ŸmbævµsfPjÌÈvY Ä`8÷igÌèô÷­oJe!$BˆÁw´È^ÍýÖsÖ±ÌÂDç¡¿_Ëÿëâ“TÀny‰ºIEND®B`‚snd-16.1/pix/jetcolor.png0000644000076400007640000011240411147553267013477 0ustar bilbil‰PNG  IHDRúûÌÒÏ pHYs:ÊduhtIMEÖ ' ö^Q IDATxÚì½i”egu¦ùœéŽ1ܘ2"ç9BB CÉ ]v¹Úí®j·»½ìrU­ö7Ø.–M›²€±—½\µì2à6žªÜíË,À‰Á R9‘1Ïw>Ó×?Nî£}©DRgiAdÄ¿³¿ýíýîw¿Ûzºõ4×»¦ç¦‡‡ ù;×ÎõÊ».^¹xhÿ¡Í<Ìþ©õO¾ñ7xÜå —ï;~ß\<·³²;×+ÑÜ_¸OÄ3áÌ šÁçÿôó.àcsM›xãÇì\;×ËuÅÄ‘‰6¶O?öýÀw_táÿtÙUÿÌ<´êcÁÔSS;+»s½/§å¬ž_šìmŸ…Jaø5ÃÉÏ/Ú·ç{o}ë[×âµî',O.ŽÞ»ÿޕݹ^®Ë?ï—Ž–BvÿiéìÒþcûûôwÿieze¼2~‘‹æ¬Æ«= É¹ÉáÁáikzgÑw®—ëjN7‡µL«‡}NMŽ{ØçôÂô`aïÚ?íu|I®GÞÿÈæü‰_ùÄéÏÞÌ#Ûµö§~íS;Ë»Éëuù×õŽ&ÿ,Œt? G°þÚükëq=ùymqm~`~gÓëô?žŽÃøøCÇ.,Ìž™=ù¶“A+8ûøÙùsó‰Ñ¾ÿðßsGúø©g§ÖæÖöݹ/ß—îÑçvÛúa±¿hb£_¶¶P;÷Ĺý¯Ûß®·ÝœÛXn¼ïà…/_X¼¸EÑβgbq«p4wtqaq¶oÖX™e¬ÆÕsÁ¹äç³§ÎûgÇ®oîKÕ¥gŸM~¾úÍ«¯yûkv–8]Ë_»~åé+ÀþÄèø[ÿý[Ó§¤;ú¦£ßÇ‹ʳs_ü£/¥¡Ru®ú÷üûÿðWÿáÒ×.M=;UÙSIo;öر±+O_9ý§ûÇúwV^_‘;âŽô0ѕٕ³Ï½‡ÏöÀ­§[O?Ñ|Â7þôÓw¿ùîÞÈÌ7&ï?~ÿTqw¿Îuå©+džËCåÍ?åÔc§Nþó“;Kw}dæKÍ¡7¬ƒÌ<1ùÀ›¸^íÌîÎÎÏN^œ ÛµöÊÕ•©…6½:½ÚoMß1÷ë\NÎYZ]ZÝüSƦžÝYØë_Cfhöôlݯwÿ©µÖZ^š[Çt+­©ËS¡Ö“+ONV'câ`Þ?áì‹MÜóÍÊ¥r½QßYôë床…BÛ÷㸇}:¶íy¹V»‡ã¯×êÖ‘ò|´Gñ“ŸyÒ-ŠófÞ7þÔ—'¿û-ŽŒ ï¬ìεm®Ó§Ïž5ÓÓåi¿á_¼|q§Ì´s}];æ¾sí˜ûεs}šûÏýÜ/¾ûÝ?ŸüwéÒà/þâ‘O~ò±ä¯—/Oþ»÷Óýèlþý¾ð…/þðÿXò‚õWóbJQ¯ÿê¯þ&ðÌ3Ïÿçÿü;éïÏž=¿ºº¶ñkþâ/~ ã‡_þå_½reò†å«_}:ù„ïÿ¦¦¦{>@ÿócûoO>ùåcz ¯î{ª¯?û³×wý‹F£¹Õ—u7þsE¿ú«¿œþ³Ùlö÷÷9r(ùçûþãüéüo“.,,>õÔ7€'Ž<¸¿ç ú~ðoþÍ}ß÷½=ýÍ—¿üÕÕÕµýû÷Öë `uuõîKþtáÂ¥ßþíß½ýö“·ß~[úË[Ö¶ªÕªmÛé&|à{’ž;wáüù‹Àë_O>Ÿ[XXÚ¿o’Äœ8q¬ç þÉŸüyò­?ýéÏ~ó›ÏÕju˲.^¼<1±ëÎ;oúéo|à¿þ?ñ£û÷ï=yòÄÊÊêÞ½»“׿çž~ú›ÀÉ“Ç÷ïßwúôÙ……¥z½~篙˜¿xñò™3ç€{î¹kØàª×ëú‡³gÏ_¸p ¸ÿþ{~ðÿÇo~ó9cLb0++k§OŸÞö¶‡\×½qïÞl¶?·´´ C³Ùüƒ?ø“žþÈG~?Žã8Ž?ò‘mðš¿û»øîwÿü?üÃç€ÏþÉçŸ!ŽãGùDò×86þðµ§cŒ1ql’/¶ÞuìØ‘³g/\ºtEö˜ùìgá…³@£Ñü£?úÿäSýþÌÌì#üýÜÜ|ÅùÈïoréý×ë±Çþ1ŽãÏ|æñÓ§Ïű1†8ù?®^þ›¿ùdòó‡?|m>üáß~üÇjff6ùgÇýè$M¿ïÎÕóúÜç¾ÞóÏŸ®Vkÿý¿ÿYz;ùÜs/üìÏþßëýukÞ½X,|èC¿”þ³T*>üð[¿úÕ¯¯¨|iqq©û¬ï¸~ìÇþ×Ô»ÏÎÎõ™G}¬Ñh|ÿ÷¿ó/þâ‘?ýÓ¿ºë®;wï?vìÈ>ðëµZí«_}ú¡‡Þ¼îuwþÞïýñ©SgÞõ®ïµ,k½¯qðàþ»îºcllxüñ'?ýéÏ>ûì©}ûöìß¿·ÑhüÎïüÞ£>vâıC‡ÌÍÍÿøÿo++«ß÷}ïèëëMnyøá·üÌϼïÑG~è‡~೟ýüž=þðÇÆÆF¾û»¿Ó²¬|Ã{ßûþJeðî»_{éÒåßú­.,,Y–uôè቉ñ}è7}ô±w½ë{ÜŸ.`³Ù:yòÄåË“¿õ[}ôÑÇ~ìÇ~dlldÇŽ7ˆ¢Óu»ûî×®­­}øÃ{ôÑÇNž<188ðgöñsçÎîsß{ïë—\×ý“?ùóG}ìýïo.çé×Y\\ZÊÕ–¼å(ˆ.?uùEŠØÔg&æ-ÿ~'ê¾Þóž_¸áSkçºÕדO~yjjf=ï~úôÙ³}ÓgŠç®QÄ6x¡ùù…~ð7ôo~ôGÿ—;nßøßžœ|‘¹öÚ×Þñ#?ò?ßdNóÈ#¯óÁ¾ßqœ~Ájµúþ÷PÿæMoz`Ǫ¾•×ßüÍ'?ûÙÏ«Œ±ôŸþÓ{×{ðwÞ¾qj§¯ï¾smç«Ã»ïTUw®o£+Ì\¼xùâÅË;‹²sm›kqq‰;¼æžó¼ƒ÷o\ÐÙ¹v®W×uàÀ¾SÅI‚Þݺ™ oçÚ¹^™—Å‹øõNì¾s}»Æî/6¹²ï×Ï»xâÄñ( ¶¶™,»TÚ) ì\/çeLÔh,mÖÜ—œšï5üakÁ­;ÌEn9ÊEQÜeÙO´mÛ¶­\®´³â;×ËxÅq›6÷³á¹oÏ0mçñè˜wècûcÏólÛ™ŸŸöîÝÛß_*—K{÷˜ššÌårïxÇÃ;ÈýÎõ* fz^££#åréàÁCW¯NîÞ=nYÖwÜÑlV><::ìû½{÷W*•5ݹ^±×ÖRÕ|>ï8öÐP¥Ùl¦ÑËàà@Gq¼#Þ¹smïŒOT«k@¿ïû@¡PÌå¼( ‡‡+Æf§ÙDQüÌ3zÒ“68ƒ‘}hC Ø`Aš9¤¹~Ú 8²«“H$ñó` ,yÙ$#1òtK>OF}Œ­(¬^O´ºVÀ’omÔK?­>‰ 9ð †"Y³þR _3Vß÷¥½ôËväv¦k^ÊÏ0>Þ71Ñw#æÞZhM~óJ†9Ï3Æœpår9ýpÃÃCIýuhhø‹_¼Ö¦éyù{ï½k3ŸlmÍÝëþköcôABh@ eÈAB(A5¹ßM”Ñ[ÙÍÐqvaòàB?ŒA+`Áø0srû]O^Ü‚¸àBZàCÚoh[ë-µ aö£:à@r‡28Ѐ*4³ï’|Í"”äë;°&  S°uµ2›Ê‘Ýž‡H¾Bx¦¼1bж܅ôYÙÏf«Ç7iî?ÿóoþ¥_úç7bîo›xè ƒw|å+O½ñoÃ6ð¥/}udd¤Ù|Q©yh¨âû¾ïû÷ßÿ†ä7…Bñ&\BMqW¾Ø4ÐÔ•{Ó^ÙWžg1]Ö|¡ }° ŽAfáŒÂ(,Á¢¼iº‹Ê,ðÕ[¾¸Øˆã¬Ã³Å¯G°x`C"ùäx "”¿ÚP…*ÔÄÖ-p!‚hýu¶ þ-pð&ëÂcõ}meÜ©ÑÇ*œ¾E§Í3FóìÙ³ú7‡¬™xöµ¯=û=ßó]7ºLIA·1$\#pÁÀ øbv´T„c²Q‡‘UÖ.-‡iX€Û°G1LN<\Kì y‘’ØVB1úä„i‹ktåÝ£›³@Ü­#îÜOg­å&#h‚®M¨ïnzY¡QQ7äMÍÖ«MõŠgb¾…×ÌýÈ‘£wÞùbû\«ÕÎçó™oinæ®§'{ý¾øu[î–ßX½NRÄehCAhÞ1÷î»n–Ií;µ-Kù¹î[eu NPÎ2aÀ¸ ìÇßO«‰™I5RÜ‚(CŸrÀÉ.Jb$[>XpÓ!i Τ(S˜= Ò¤ÕóDküçg_ÖU G¬*u½šËuó!Qˆ$’°ZÙÏc)€²$ û2Ô!ܰx¤SÞ8»…^r·ee”8kñ&ûÖ=É3ß.©j1kG«*#¸òzª£"T7KIé@ª×tÓ J>_±#?¸b‚ œ„4ÝNýfÂ¥F] MO¾”#Ûµ­h^¡²§ž¡pZA³n¥75Ù@–Ýi©O­s,|»Ä:È.P¬@nÖòbh&Ã$î/%°Lv]«ã+ä+Tû‰á2„Ð'q¹¥Î–œJÂ~K‰ŠšüÒZOOsŒ›ª h ,yX‰²Ì:áVÇvÆšR˜áÛˆLI¡€Í)eCs+K‚ï¦a¤ðŽ–Ô ÞoY¼r†a?{vѧªDç%,nIˆŸž|y__>‰+æKí3ŸM ÍM»y³NfÔaÒRQ²!“bÓŠàKë³\Å}¸vßñõJH¢­ó¥·³w'Òu»±œÖ&:b‰e“ ?¥4ºb¦E°i¬Åø“°&‹,¹,{NùQBwõ…˜[él)?ûR5ÂAØ8‹0·˜fuµÈÚyÙ-~ æ¾¶V=uêtúÏV«}ôèñ—Î+¸ÊtâlŽo)Zb¸N©BoW•¦$ÁI-)É;—á<Ó»àä  ó`+ÆN˜-ÇØòÖnW1ß—§¬Ö'nr‰bµ sªð”Ä3«Ð¸ž­‡·¾¬£3l;ë­L¯PǼrÍýÌ™:ø¥R饸‘FÝN“%Št¸ÿõ(P¶"YÙôc0ÔàœÄ$ÃòÝmT¾Ý…!åÞœÄͺ©±Šà­.îZôR›;*+µÕ‰çK¥âºÖl6lþºy„ÍdÏdÓÕÙÔÝœp3üûWS0cuÙ–énµUÙiÄYºo¬býXêŽu‰ÝÓÀ7µË@j¢À8¡óôÄ#–ªsEª='ü5%F Lcè¥3wK¥ìb ´T h6±æi-º~Ýîþ;:›zÖtÍ+Ñ»ß2s7]åIKÕDR(:'&u¡¼Å*kÁ ´¡y’õ—޼¾&¨m>,ŽÕ+Ä/éÇëÀøäÓ=‰õöËÛ¼Œæ®Ë‡¶ H¢.2LÊ îøë n®êDFŠ©Ué}.à<`jhÔÒVþÏîÚ])œœ–M×cÌVäØo$ýS’y¤Lá+eùÖ«­ÞŠàÁî»Ûꯑ:‘:0œø[Æ#xy½»¥â£lÝêbíE’ÈêsÀl˜–¡ô6P¬]f †!‰dV )ªdÓM;ÇÙ‚@¤ÌÈÊ2à7 GZ½èé×}p¬x¼NÖÈ:Ó7¤ oÍ­4Y/–Þ_§«Ô… ÿ¬®h¶Ÿ¹›,9Nß°”èª2g¬lÑÎfºzÉ,u^'†ž NhÚ`K‚ªà•¶b„'xŽ'ošW~=í-ì—ÚmЫ<¾™f²®wƒ'ê0}ÊÁ·`E>R-TWéÝ. Ðº!µ«+ï¢ xñº¾Y†ÕEŠìH¦·›¹›^·Ç&wª²ÔRIg$>©»w qä®TUmÅÑM6Rj¾ JwRSñRBA3ÉèSF_S’F%¡'XÒ’Þ ™;vUA7î%µàÉû:*…ðÕ}ŒÕ:Ä •'Ë'KÚ7êã-Uï#«]¥7˜ÖŠÁ›ìG•µ:ÍKÒ¿ì©jÇ>NÚäŠb:ôAbhBúe9RÒH”  ÕÄ„rÛ-IF~• +ÒŸ*έ'‘q*)Óƒ‚Ù7ä½Z‚ë×Tôe«fj³>&M6Ï ·Þ’ä!§’c£*ÍŽxô¢Èæ´DŸÇV;Ä“ïg‘P!<ž2Ð-èi}õñFöRê¹] Ÿ<¹•ªÖÙêcut[›à{¿ÊÌ=îÊJcñv–p¹\Eo†1Á¿kÂ`©eÍ+éý³Å=礋uzÒ¦¤kC±ôŠEð#uª‚£âÇe¶TÛªC%Zß\LWƒùFŽê²ÕšI>IúÀ…5ÕãB6u6j›å²‚ñÖäŽèёӑըSÈ•7 ¥RUò¡*_Á–}kڻݼ{ÔeýžPê0ÃRýiAÆaB˜‡Hª¤«Šª®ÑOÖ:/n£$$ªDõ.Ñ4”¹8J@&ñ£´ sræTøÝÑÂúø·­$(²/¡‘+Ç‹Q®XùøX>X†%³/ À”d#±¤+¶*YxÒÄí é«àLG2ê¨7òä¸eñÓ¦°²<2QÂj€ƒª-Á«PºãÍ­ËV_9Âil:(GvŸ°\F`X”ƒ®À’2ÍH¯©_)(ŸIÃkÚ¹KP4 ýІI•ê\°(ž~@¨cé«Ò'j+þðÆí|ÝP£QÌçäøƒXÜ^¬D¦´GÈ‹é…%1 { „YI!Ò­ådéæâG4·hO½‹9ÉÚãìÁ•Ø}r*¶¡!XPbÙà 6MQãÔSåó§……à%E^ŒHK‘ÀlxêàÂaaíΉ›˜¥! I ìÉ—øÇQð‹%©’+ÕЂ ¾¢¾Ør扜K Ä û$ Яæ+†¦¹^„ÐÞ»Ž÷IŠâªd7”xÆ•Ã*'žrŒ€3¶<%'ù†Éâ¡F€mÈ‹Š ½õH•&91bÎʲoÓL#¯ˆ:éwÏËŽMh§Éy¾&‘a¬yóxî«É»kî„%H®Ꭰß+„89XƒI˜“­+.W,ìöœ4/»ò°ú{>ƒ°ì†UX?íüxÖ²͉SŸ—[ëK|¿–ެ÷êøÒb-Kå‰vZ$v™—Œ9 më"˜Dü!ÔTC–nŽA‚þ4T¾±%\!V_h‹46¤±ÐW­†Éq »¥Â÷ô»Ç²™ƒ¬ŒÂK¾»¯ ['«…Ô”p"U¨Ã8 ¨Â9YÓ½0¯ð™Pø0ZÐT—Ê[‚¦§õ äÒäËïõÓäuê0+XM jâ,›*Ð5Eg}sïHÍ} Ü=h(,²-Ékª H¤´K`¥õ7Ò¶’‡‰þÛÙ2œ£›E:ýR»Ö¬Š”=Ÿnïœ"Z'w¡%Ä;O-NjÖºõÖW%‘د&ïn©»*ä1ql»` ƒËð,\Á‚iÅO U®ºÁ~bD½:ÓÉvÓÕ‰gA ÉqáË{µ%1õHj«¢eôL–úFV7!…\:CÂæÍ«V#’É–ž€qhÂ*E»YãŽ:¥µ„ÊÚn€)ž9YÆ”¼âZ5É+Rˆ,µ£èÓž¢¸9Ê1Ù2¶ŠÝ5^›”~JŠŠ¸O|üE°aF €%h¨D'TÑs]ö§ÔÙ“P»(TÞÄ “ 3•í I»(’½1(8·-MO)j™êW¶TóG¼‰oŠÊŒuŠ\cêÀï:ýJ"è×–èyFâ=G,>…´cØD džÑ a­í©ÂPšû&JóéæEÀ/ÚÕc媽ÝÒÂê+'˜‰ä~ Û:wMµÔÚƒ’P…~hÂذ¤ û<çɲ&àt‚B: ôõ`†¡³¢›— uùlý²Ü }L$¸D]•¨6_™O9É‘ìÕ¶ÅŒìÒXQÐl‰gbA<æ¡ »¡¢‹ÊSì^lêH½)]l­Í§XP#ÒLÉRU¤‚ªXk >9µ¼l“±¹ENý•cÿRwð¾ME/&ðDÏÀYp`€%‰5z•LtI³ÀAØ-€cEˆa®Â.WCNrâd«$N|(ˆA(ÁL(©dǧxC,R_¡‚h-)ë·²-9YK$/sÐ/.¶)»4Êæ VV¡ÍÏío€'w ÐzYüGÓWƒ¬úM *þtTô¢+f[š{¬¾¶-µ[E û¯¡(á ñŠÌQªˆk_\"V§a[ð»A‘M‚ã ¸*íÌP€Qh ÄéÈ)œ—§#ŒC krÛbè9y7ÔfŸ¢'øQ/e)ÕRìšœ¨-%„¨ ¶ˆJCí,ÇΕô±"‡[}‹ÂÅv/qKÁüiè)ÜÉdKlš>`$IíÓ³·«w× t¨‚™H 51Á+ÄG¡À IDAT«P†£M^€çUÛ‡îi $®J”¸üДߗÀ‚ 8,ÁÜpßÓռܛæoHDãzŽBǯë“L¯žC[Ñž {¶êÍo6ËóJŠ!€E˜—)k– Ðm%VUVá–pwÓ…äØÙþkGe ©Úf(çR¤fU¤Û ÎöÆ]óy¶a쮸 KRMtb8÷Pƒñ"ƒPÍÊä"}Ù e  «øR‹Ižè«|¶šÞ 6¼"ªFÆçtOwT$Ij¼‰šHwSOΦ¼|§ë‘zUÆ`H%y‰äFÎÁŠ@ïQ13øëò:–R1¸±»Ö!¢ɉ‹‰ë!¶82ý}u§¯Ý‡f[š{;"–Iš:{a °aNH`¡êÀ·”h°‘”eÊääaBêD‡¯Y|±@9ÇBç$?¶ 9/Šrí–ÖQ§WkÅu¹´¼š‡Òiwz\ ñW$¤Y{Œâ˜«ªÏÐdCá´Î@¿°Êê7W×H:(%§Æù*FÕiãv5uwú:·hÎËˈ´»ŒÞ¨VQGyŽYx€ @ꪘJ3$EmÌ“`ÌJ µ„Àõ„?c„zYFn,•©Á7Ó‚b zz¹¯ôüÛ—›®Êš­(é¸Ì4¦Ò'~B̬3—À`P„P‘ÃÒ( å¶àƒæ&À>+{ìèžñ8«ŠëqÔúh®¼«Åq–×ÉöóÅGêê„2ôÃÌ ‰ÊÊÞc[j{ž€`F…T[/BbZ_g¦"~¥,¯“~ ¥f™œÂCRêï“»Ryw¾ê^³AÚu¹Pµ­jTJþN‹byùË‚B:˜?€º|e“•4ªœé©–®ø†x&[fBÈ–äÜ–¸öX™¾¥KâG¹ö\?Þ–ÝL9œQØœ“Ê2Zñ<¬ þ)H¶êá(ŸÄ©Kp¾)BÂñ˜…yÑWj .J y&¡4ù‚ü¤ùnDÒ¬/dÙ“, ],ζÕµ+PþÞº¦Ü}îŸ|—”Žd±HG _Ú0…DnÌâu»£ˆÓ¡JfŒ"f{Ùm£ªuV—×snîðy%š»Ó%‹ªhj<Þ“iî ‰Cšëh†ª@›¾N" ™0ÏFd½%¯f¤Pµ¦˜«E±ï$-IŸöUùÒyäw =[ª$õŠz;ŒÞËbvVè=ÍjVõI,7©ºÝñ‘©v¤Qž¥|mq‹ýàÝî‰^¯)’EÔü[]’ΨL#î2ômDvÇ»V¶‰=lnEªÓZ#ÉZGñÂRE¾”ÕÕ»aöÒ?F}øb ‹ª%/'øqQðéØ%Á®§ªª¾R—–fcÞ:‡òz:Ô©«ëèå‰T?^ÒC˜ô¸T%Ž€J4ì«°œ=î49,/·»¥*¸7|ï:Ã쬓 ²s(bY”ÛŽ»jX&Ût¿­Ì=îUP0½%Õ4m <Ò¡De²™_ª†ž°¹p`Oà`"l—x\©lßw(uÓ¶ðÕÆ¤ s@€ dJL’6¥áµCÝÒÙ• ζ¢ÚY²Z M:–ÉËã_ƒåaÎÃUéVY‘îÕ8+ÓàHWQ¤hÊHîæÍ¡V¶áC ¨DŠe²™˜••kîöNv£n7d¦C+ÐUÝ=©·+ UFMÍ:Eœ8+x²éf*¯Rkc•°Æ1É´uÓâC…Ù IAgEH¶ÉKaARÕºrÌf}Ñ¬ŽØW˰¤œØTV ¥"ÛŠ;´ X„2Œ`“ë§]ÁŒÁ*,ü0gèR$NçÇç$?‰n:8î`À§a'Šga© ÜÑ ¥ARWEnÛ™Du%vzŠP¤–2#p•ÿ3ëWs\!À¤æ2G)Uš†8Ñ…œŽA Ì]†ƒ06,Â8 Ã4”„˜àó°ª;ž{ÆõP[%ž4p5…ÖR£IÛíJJÓ&"¾H+‚I!–¤n€*ZªÃË’ÉR}ß7§j©J]ݳ³mæ®R,óUOÙÙD®j)´²£+Ì­Àg^vá mè©ôENÕ,êbO ”›¹®ÇQ±• Er³§Ól`ûXö"–Áì&jÂ3‚î5>í ÖQ P†Ššð˜„UÃâ8Én×xýô.=ßÓaf Åôj«ö+G5ø Ã08ÅÌ€ °"›+G_C‘"#õ"FZþ<™!îoåfyÊykO¿©/–šÚ&bÐaW††Špì,PÑÍBÛV@¤µÔ¼„ ‘1ÐýÐ!¤`ý)|š^KÓ~b ËØ.ŽE f»Ldà pÊÒÐÔòYaÛ¸æ°Ró‰jò©†àpaJ„CUüb¦=b¨kK:—[²Ãm á"•YŽHªšÑ p†ÀƒKꉉ%9IY*ܧÜÎ–ŠŒb®»²{Ó”#ßK§¶cøŠ£ÂN}P8Ùdw›xwÓKý´ Un_Ó®…–÷Q/”££âÉï]™gT%X#ÈÁHI/ó(äaQrÓ¤¢Y‚J–pöÓŒ‰¯P†à TaQŒÏ¨Bf¸N®gs²ÄÝî,¼%ÓD|E^O¡Æ„¼™BÝ#¢L? CàÀi)YÙð#>™'ÔânùËëz7tÖ¡¯{‘ôô„(‹ª™l¢e«öY[ ؆±»ÕUoJ)Oò¶‚”“–…•UÎèvö,¶ÔžIƒ™d$ÓU¨Á ìÁÚ±¥«:)”î—~¹59XŠ¢c“¿†»ÛGñúi—²* ý)¸,G  ž3ì-Eȉ²Ì¤ÿ0^."*æK’ìÀ%ˆaFa7Ö~ "¶Ñ.tuê4ž¤Ã5äTß"Õ6uº¦«bªëG®ˆ ªÚÚΊ8˜¬X¹Fáâ®úú6iÍÖÔÖô|Ì ŒhÅÄÒöRV…ôªÂ(; –ZiÑSàbòc%µÕa˜E¨Ân¨À² XÖ`á$¦€¿$~}Ö  ç`UnpI…^‹æiŠDÊR¬‰M§CÔR¹¢’š”V’ö+`“|ÈDãi®Hü–›4šiÔ9ie'LmÒµÇj2k²‘-‰?c oZ]Ъ­ÊÀšÝ5e›xw;‹Æqxèºù¢Ôü{]Ÿ×ÈfîV %q‡+rJ$éà$­’˜Ñ.ÈØ†qI=‹Ò= >xJ˜L v -@VaI¸PµõhÅF*¨ÀnqçEá¯*Eâ¦üÉUÍÎ˰"Ù}B&Õ(­¥¦²%‰û€$eáMlÞN<5ðÌÉö­êI‰^VøÛVû?ζ%tƒ³¦WanVUÓ“=AQÚ0 ^Áȇ¬‹éª9¿#˜±T/# e ž¬»a³‘LìxN¸1%©R2¿é4$êþY"Y3¡4ôôÔšõN3TyßRnvKДˆ¨Kп,ÛÏ':,Â"ì3P´D­ôÊgÞ%m~íMG2z$›¦°wŒF´ÔéšJ øjô¹É² :FuC1ÛŠï®/[õ#»ÂSMŠ…E¡¦])¸õb,‘•ÝJ» Š/!³†±,¢ÞFï¦SK¢pWèàÆ•ÍÃ~9+ rz”DÈ`M¶S´ao]cá¦m¦—aMÚµ¥Ü’–“›R|()Щe…59|´¼zB„,INIâle¾ˆ¥j i(¢óT¶¶%žqºôn5wº¨5·ðzy)bF5_§Ö\“'à`rcÆG¯IôÜ]„3ªË=’Ô61ô¾kþÞÞÅ€G5‹Ò(Ç œ ©¥Ê© a$R©Ë0ƒbpýB,K€ùó0#"XºÔoŽp’ü° ˜­?´?žxb¤d3 ã2I¡-T+²V¨ÑQ¡°öõ^ž»¶Ô®êf£jMê2ªBl)‰[µA’/Ü=Âlïa5d‰P–Šüˆ‡ðørbŽueaº™l5.'Ú‹i@Â(ù=ìrˆbªmêË\ÝÍr ®HéÊ—[XqŽÄ WaB0"Ôˆºê‹|Ùîy–JÐK°GúŒV•„પCy"î7&Ö¿(¼5)½yÊ( ‚ˆ$|O:€kÙŽïM†4Í.اã;Æ iªŒéª™^4iÓ ¬ÛVÁL¬jéiaµ©Zã\E¦K’È–šÚÞQÂÐÙ}bëÂ9:¢è[¤5Å…6¡-¬QÚ† yáÖ¦¼ö$–á2ì‚¢d‡‰œ»Dœ±­òÖø¬."gÚ´Q’m^ ÿ~!)Ì ÓUSÙ\©FY"2ãðJþÐRKç© Ÿ6Úz[ÄgâõE£ìlçd”å/9j3D½jÌ|kæñrë»Ûª&Åe[‚=ç•GMHä}²%BUšÖ‚*–„þ5)C&ýJ{¯õªšYçšÏ˜É.Ã>ˆàªI÷I;߸P^4FÇÁòpÔYëdÒV6œK€¦,ܰóqHê¦Ú ¦4!±œ‘.^G(@k]£gcaJ–eW·E­ÄÚ¢oÒHšf®Ç rp”›î?ì¹ùãlµÑîÂm¶[0£}Cª;U=ººÅQõ UÈØ=ýËQÃR\8ˆ;Ž·HÔGc=ÑÙk‘ƒ ¯RÂ*RŸ¾x„P•†胃°¬8ŒË°(B“Ýrw®b+ϧGÒõ)ÎVNtù<Õñ™íÛR%‘¨¦ ÓÔj"‹ÉË"I­–I4s¦TŸáæÏa«WìÑA`Œ…‘æ¨ÂŸ¦ŠèÔÖΪ€ô¢¶}ªªzÒéY©a† H€Q•qQ¯‘ðzR{L@…Ü^*ûÈC5fñ4æœÊ!ØäF¸gˆ5xf‘8RŸ!9@ŽÀ,@ŽÊyR†¦`Nž¸«ášu⻫ ŸšƒBüZ–­©F;Rµ­0ҜØ’…%ÐjªÛ(±$Zkl1ŒIMEÓñã^°­ÄdP¡¥4+›Ów‹“YY÷¿}ÌÅ©p4ÔZ¾#bLm ÜQl鎘!}‘”i8 MškDî0á†k`âà!îÈSÌñBž+EG ¿œPb\¸gœ¨‹0(Gž•¾Õ¼>Ü“£éÊ¡*Єê¼JD's’nê$»( ‰+ñOŸ¤1-1²¶ÊmÒÉ6UUª `A`~+“÷ì®)áݧ4ª’`©Vc·ëˆ³÷õÈjÛPV)ÈöhòTV„8.tźª§tľ"‡ôA3K{„öeð)¡éÁûFy»M"Ó†¨Jü ,@Ÿ ~G ‚iÀ¤”ŸÎBÊà¤,Pë›uÀG=K>mÜlÀe˜•á3i“[Q°—ªj¸ž†<ŒŠS¿,rø¶è©7$Iu²ZvÉR×E3'Þâ(²Xª ÝCÂL}w³ÃéRJënbê9i{jDš¬î¸j•DÒmÉ> Ò´äÔ¦É8³Ë.š…eì1FsT÷°jsþ*9L™¯-ÓZë) oÂ7‰‘vªÂ<ôÁ¼šúâˬ¼õX&›š%g™¶­8Š8$âÚË"_Ñ’„$QA_jF6|^†{‘ ôµ¬rP4ÄÇ/m¥ÃC³ãuÊÝ<Þ8«‰JO7°é[ˆÏ¼øîúŸA¯z²--ßeeSœôë$±~BŽ?ȼ±*ñY–ûpú`€æ4_)ìgpˆ!æ¯"IMù/!ð¤X“Д:ˆƒ^¥x[uvW"ÕKêJÜ⨲CrGJ2 PRàEñ¯i{x¨ÞH+Þt¬°­ð€PpÏš„ÚL0ãe…Ø{ê‹D*j·³>(î*©~+ÇWšwï†oÓÌ,¡Ž¬Ê˜WZN“C¹%P ÎD_|[22ÑÍ[z±s§¶€bVaãÍÓî§Ò‡3FX‘€xTœPR”™… P“—éI7†-Èi¨`f1›.Hv¨e,ÕP Ve3hjPÚ¦¤…Á,û R¶ Õ˜(ëq=©7ùRsõ¶.‰ºžÙ¸Åî2qÓ«síe°õW޹§}ø©ÆKÊpDŸz\ëU‰ò[RóG¥ù‘0]û•¨y(úý¸{(í¥:Gœ£˜>˜‹q›„ýDEÙK쨱!§  EÛ´Wðï¼ý®ÁˆÝä>mý‘ˆ,äe[x‘T9OR©ä’ÄÊy©7Y½0ò´´ ÈL¤Æo)˜±z5%jU²| [‰FYJAÇ]”ÛÍ66÷TV3°dÁ˜(úV¥©4P’ÓžŠmR¦kNº§“ñtc°û¢âr¸©]ÌMQwˆûl†‡y²ÌÌ"œ—!Æ3° Öm˜Ý0`–`Zæ ˜—2~:‰nƒP£IF’„ìÉÕ„|ßVñI¨*5F:YSNbŸHßTÅÜ­l7Ý]m5²*Q­ñÕàªMVHbu³èÂ"Q$g';›À’¢a¬˜ôp‹c>Îé6°ûÁæ_9ÁŒQ]9qH»©H&ª™5’E¤KG3ùR«‚4#Q¿ÁtžÐÁÄŸÅ/QÉa,¢XèIE8Dî$¹ Í&Q@î‚Ó†qðáLIyÒdïë¤Ñl“T.¡-Ÿ9”R‘­$/C…g'¾$Ò U%ê”Sþ5PÁaŠ—7©,oqò‚Qó?¬ÚcåË(–˜£ô:]I\uª7J7lrʤy•zwKÝ΂ZDÉÓЂë.•˜ôÚ­ÈXSWÕe}!ÄöËÞÈ /¼áW™]Áy=ãGh³|•'Bé«Br`öÃQ(,MÃ^ò9‚%ÑG¯‹’°&ÜáüÖóIÚÇ')ø‚|Ά’+sT ‚çU< }¿ŽPýu‘ˆ; æž ­­M·„Úª/ÌU~ÝUDz­$çûÕ¤ìtœjQðƒT £°^æî$áBÉ”j¦¡UÆÝOþ(ÑaLàK ?áiuãÇ‘HþÅ6Yt¢$$G$te®j¤È*%–ňLâ¤×`UÐS:J뚬t}* —=P« $©±gkо(<™P2Q£ÄXÒ52 0(ƒ¼‰Œ[ò¬´W=•nMçCu€ÓÓ Í†ó‚ÆZ’ì:›–‰ÔÀW¤bOüT’{´hŠd§z}yár¶²’‘b­…JùìºÞýUYU5jÞy^ffxX°/·Y\ñ™\a¥Íâó°p æ…[buUCŒ’ŽÔð–X˜•ùSMÄ{ûUÕ#/}tk2Ô²,¹c:e !®íœ|%Ðle·ºóò´0äÊéU9Î4² xRÏïKã¹¥+G q²ÃMõxÞHZ]ÇÄãMWUS²ªþfCh¡Ia-«+Ý(V™f¼ÅkF¤+él ÊRÛÐÜÓE©Ji‹Õ)ÖZ ”~ #yÚ‹Mæ§ ¾&j0Ž*:ê»b«™^ž„7i¨PT`yŠŽU ÈÆ[•ä5[P€I¡:X’$¯Û‘ÇëHÍÄ]j·ˆ¡ HŒ^j gtÚs%*s•;ÔŒB_åëV6m d5ZÒ~žàž[ºAÍ,'ÙWª v¶E5eU¸*° •l%jÜš¥ÚÉã-²5_eæ®áaW08 «Mÿ!çh6¹´ÀÚí$)+Ý~G‹iªV˜Ä*z’#ìö)þc$e‘Hãa À˜èÌÔd«TW$œ'Ì*­W›4ª]Ã’¶ŒPŠÄ¾(™Ò}}•–h j\Œ«Øäz`¯®´û° Ë0 #[Ñ™AïÓÿYX‘þÿUh ²KÉsN•6÷Ž–ä&Š•¦HKÚds‚VùÙHÓrÒlÕ5ÊŽw5Y^,޶¡4 6cëdG$¸]™’«-ådjå£l Dve˜Ì ŽzÕÄîHT»Æùö[ø-¸x=ôK+Ý Ì)q¥ «f«ÒfKÌ7UÕò$Ê+UOL?mô…3c¤RhÁ!p`FZFl"m÷Â7ìuˆ¬Ó“PuPÇTÁ´KØõIm+P:d¾¤wŽj ³J¼ʺÝ]NÑ:Õßõ€È ë;âìLÉ´AÉÊÎ'ë4Û-®©[f²ŠÛÐÜÓåË‹®Ð(X€=8%þu.À‚ŒgñåY®ºÍ©æ–­d÷|¡7iE K 9m\Ř@:-’ŽŒÁ^ÈÃUEÇkUp¡ëúõõhzªz¨ ¨(ˆgª™“vd§cÜsM-B”uŸôtðTõ-ÊÎ­Þø¹J“5”U²³ Ž¢9Êy§ih˜µl²rqa–äcmKdÆriIƧx=À‚|A0ï<ìƒ ,ÁŒ "Ý{ukœ®Ò¹ª(ÓT¢‰VQ]ødŒIŸë>p¥Õí2XpX¤íBì%0ÐĦhýJSÔѬÀ¢ôDtýbµ,“—l§k2 F[•ÕèÀ‹\ùúÑú3¤6ˆÝc…Ãh~>¬ jØAA5§¨W ²X[±ÿ-%¸Àõ´h^•æ®—¼ZšapˆæákÐÆ9HnÑBˆW¥D’vÍÄÙS"õ )Ù5ÐÍ“ÿ- ¿·-’2mA-w þøZ´¶ IDAT†LÃUÈa݃iÂ%ˆà @ædxØæQ3£ª @E˜[I«u"-¿"‡Ê‹Þ‹‡{I…+~V€×Ë:Zmî±€Nö†(= Ý i)*„§7Ù¬)'¿Iý}$[ÅSiwœ= t[V¼Í檦+Á"F„5r-º°}ŠÇÞE±,6ðÏÀó¢7äŠíY7)€/¯º!#…]¢XÔTXµ#Û Q¥„¸mÜ£ œ îÑ~FXVy™í¸ :è6C†#ÛŸŸ`‚{ħÀóªÈP¢X\m9¦RNUN v¶a*ÈÆÄ±Ò½ð„¢ØÞt|쨱?±éf[á)Ò?™¦­®|°P…– x,åûQÍVÛÄ»§m2ÉtšAS³(ÇìÎQñXh3¿J}ÿ ´Dš4T5B§kbm( h,³\jY'WË&”±Â(mÜø%Z“ð,äé=Lj-^8M⛄‹2p“®Î#cPÔ઒à+ s`NƸª/–³ËÏÖ&5“ÞU‰Qç^rPä³CL¯»QÓ‚®¯°ãH¦žlãT35/¹~j÷¾ÛˆaS—É,•`l7œŠÐqC&v‘á2E83ËÚW1+XÔïedˆV‘å5‚‹c,w¥8é8_Ÿµ„–“s9§æa„8%œË¥ïö°{„<½J¼Ìè]DE–/¹|Lb÷ú&‚=ÿZãQu± ±ÃZÈ|‹×–ƒË1O,P†»Ùo*ÄßÙÏ^‹‹ðÉsC̬bÎÃóBÁCŠ «0бYY±Ò%˜jT^Žæ¶êÈ”†šy‚ó¬…˜v‰‰9TbÀeÉðø*íïá ÍiÃì,æy‘w\^d´!îNV4/1‘ ÞC®PöÉYìÊÑ2œj0·@»‘ ÜÃì \T]K®˜r¤&.¥õ¦‚„Ô-é£ÓLÃX Õ6]OµUïH«)1z F°rKÞÂmäÄ É/Û"[Ò¡ûn€ãH&`+~²yµ{wsm½ì!ðˆBÜ<ŽÅx§Ç¸ ¾q>82po>¼Ó ûÜö•8þ¸Íÿ;˹9fdªðnhÊ|‹$š•~~#X¤f¶²:XŽª±›kñUXŸþLXÏÖ˜Y Ÿçû÷1 gc¾²Šïsø­”‹\®³ö<œUÕ¯?À5!uN2~ˆï‚ÛÛôáX…§öðUÖf°=ø²tÄ6¥^ãHldõmš2¥Ð‘ø'/ •‚¶µ•UÕЇ¤Dƒ÷‘ߣÝ$žÃŠ1Ɉ̤±ÝË`†}Òž»&L;GîK fˆÇªà¥dŒ½ŒÁLN\ …Ýø‡éÏó?À`¾çç̱Ýçgæ'¯8ÍOx|ê"§ qÈ—3zPÄ*šªO9a¢·¡‹¢Ä©~0Gt]|©¤¦œ† ~EêWùÚ4¬a•Ø÷ª`Á#«\Ze`ˆ×à,Á¤#ˆ7½¬~P‡¹5m¸lCç6Žîâ<œ5<}™ äö£Œº\‰9ÿñ? ž3.1R¢KÜ^_ +VÔð„Ò¸‡#wòF›Á€À¹LNµ™^¦5%”úIÊÓ· ‡•¯…ÈcC•Qã,ă™td&Éè"”à$ ãÄX+„ƒ”<ÚDmú†(Ù¬úD5¬AZmZK¬YT ¹<ùzC¼#ß"„Cp æD÷jDZ^ÝÞ=¹7S°}°—êO rÍ8\s° ç÷ˆúŠV32§ Ñj>Zk^yŽjÈÊ &‰ “ ×kê®—S¯.‘Œ+]ñm•MFжšÜþ NqÌé*³5–g¡Ÿ{Ž2—.ž!®1ðq=®,¬b’Q WE‡~=UTK)<‚C³ÅZŽŠG1µFãR µ‡ù:á$\Щ¥Ú²INR8< ÚÏ"*tŸ\—è‘ m·T@˜À‘—1h„4ú°öÒÞCdAf“Öq…¾!š 08ƒ8+1 c•É áDq‘â%˜W³¨BÓð’ép¼ŒÁLt6®©Ÿš³,cyˆG"ŒÃ=°ŸøË1ÞŠŸfr•Ÿ|÷á<&Ñ^ÍrGm5?¾š…´U¯¶o,lÉ_è]kÏóçlûZ%ȽݻY 9}•µeì •Ãì)2Ñ )y¸}K¢õç)z‰éeîš¹0Íô xxýDâ+×Ú½Û‰FEúkX4î\ÅkO 1Ê6C¤žÞÏì,õÊÚ´žhÊ@Nõ¬Óy>Ëâ#ŠQ³B;‘7Da‰µÈAÐ#„§¾¯Ý5 )Vð‹¯êJ¡šõÀV,¾c–.lña’&2!ƒR}K{| JL/•ÝK(¥ý"ab]Ëâ˜Uö]í¥õðª4÷X¿‰ç"—,Åìîãá>&`ÎÖ9¿ÈââY TZr”Õð›vg¦DÙ–j0#›½¡Zfrb£y“e¥Ó˜%L«Â®7ðöQÖà+MVžÂËqà+Ì–.Ÿ†¨ Q1ܰªšþP€€•çyÒÐ7@£ mv×ÙSá¾7ÏÀï i=q©­°N+;Ê˨ãÅΠáMÇ’^“¢ÿS²~]˜v)Ù¦Àâ2 H£«Ôús‚¨® ÿ§_štKЀyÉ RÙ½¼ß|Õ›»­¡¢u™EÃÄnöÂ9Ã'ÎÓ8CÔoŒÊCxÃÔZ4¦0“0-¶š¡jTY.gæXaÿV–ÔãàÀeXÄgô~îç¸Ç9øÒ-ŸïâMEöØ< ÿà³\qWé®Ä½>-Hp,ö”©Ä4ëTú]æçy¢Ês1oeŸÅƒã|þªVŸÂ|r*lK»ã¥OfTï" ïg‹@dœé¶õº$ÉÊšÎàŠîZ¬¤—Œ:Êòá)X2c«$;F6mc+3¤^Ñæ®!…„ï¾yöaÜf:àòÂ%¼;86ȰGœ'²ˆ ³1IUWTÐÊÒÁÚ JÍR>®êt¶¥Ê=+zÐòoãî]¼®„ §>÷uÌß»w:Ôà±O\`áfIÈÃÝlªîÙEgø.~¶ìsÇã«%ëòJ±òüÒõ¿-ò‰O¶ˆÊsçËŸ¬Þ¯­Zž£uÐ!MV»nžj”Ì[”M|}Yº¢êG`Êô»"_å*„@œzKvNÂð) í¯©>çvðîiœˆ LžÂmxgš,?ÏÀ('¾ƒ‰~\—¸XÿÿÙ{ï8Ë«úþÿù)·ß;3wzßÙÞØ ,ËR°€ØÅ†1‰F£ægB$‘ï×_¢±&|ýªQŒ1JP@ `évÙÞwvzŸ;s{ù´óýãι{î.‹»ÈœÇþwʽóù¼?ç¼Ë«>H~‘”4-EQ­¬[î$åÐ[ÕrðG'­ѪI0V;‘5¬md• <žg`á 5ózƒ"ü[‰mÉôÝPºÝú :}šÂU É*bŠb‰ÙXÖ›i«Ÿqëg,ülÐɇ³y¬€@÷ðÚ¥AåT•›*CSUDI;Žšm(`Š“· ЕjÄPv÷Êx5&qeh~Ÿ\#Å4Ë{ù””2/«x[ò®”…9¸ÿ/9(™¸ú‹¸µó2 ï…%B«-ˆ&KdžÎ&%°×ã€ÅÈÓ½x£P’ÕdXF¼VÝÒ®8[øç¦ôs·BY2"YÅp¢ü{ê¡M‡&êZ ú<ú3 íàk=l‚~ø±ËÁq°Ñ¢(Ñçî‰QïºÜäL¹1 ˆ‘Ÿåö@¡/4¸¤ÓõŒÒ®N–HŒ&“ >t#»‰"ÅZØ-O³ŠÔ¨­­Âòq-(ãwKÉ^¨ÎjN‰”­É›¥É²¡bŽàH$OX¾c­|¥]>üòS%å¦Pi *Î\aéøY„F %x!L/ÏpG±—iƒzJý„£\ÐH‡Æ„àþ>Fúã ÐZ‰I¨ŽL†B)ÖìÇ€`+ReªÁLµ9ŒPLW¨6 ªÇXIG=99ÈÈðn`ó2>æ<Øß<åñô ëõèÍ5¾ ÃèÔD«8¢ñL¥5¤)KŽk‡#‹³Àœl¯‡³£œ >Á Ë”FN0¸–Ù ™£{ñ5ãy¸eôï¸t[ðÉ#Â5«¦¸L …HŠÜ5Mì.Né.ÌLNiá{ò£w]iÆÇä[‡äY—{&O†Šâ¤¥jºÀY™Æ ¯^ ÉŒ&!»å†ÃEtÔ“…½®‰òšåD` úa‹ÅÎ4Ó½‡ -A!E·âPî)iŸ¡è-¢°õ*¢.¦T+ÿT/% Ð²Ž³Cœ¦‚[,žñš.KoþÙãë—nÛ=íÞK§o ‰]3ȶ…ÔÇéÔˆ™”ù"5vœlŒa€‹!)%E(Ý'IqB™Ôز0”ɃQ]žz§’ɨ>ª˜TzÒJH‚XX¦%®ü$ºT-J¾¹'‰—ºbƒe@-Xø38aD;u>²öai™˜±2ø?`¸›JcÁOd1Í XŒØœæè„¸ £)˜ü·òž]–Fbk+m>CA˨ö¥^5Šæù·$]i~«²MŽ úŠ+SLꟹ²â ÉÂlZ1# Hpža4±<á8õµ¤-²&xZRø¸¯øÜ]:—‹hmÀ˜ïp>ŒÂwÏî'$ØH{#ç.¦=N­Á>x¢@rö@µ:œ-TãrÌ‘SÐ&•v„%ï‡_ªCês‚ŒµœãÄ_ºzf¢î"ó¾óšÁßt×^“~àCËÿn×çw¼›'÷\LsÇÏT»& £Ð'*XUuòØeÂø¬ÂÀ/Ë×”ÝÈÊBNÁ¹GT«Ã· ·7­(§–ò‡S­M +E|ÅØÃ<•_…gh+FQŸ‚ ËY)¥¥ ¹Y¦›ô Õ`:¸y„†_ŠR_G£ Ñ Õdvë§—ˆŸÄ²)zu4"m™Ì,ÀßBBï r;¡Iã«kX&%ŠpÀŒ…–èHÈ ŠÅ'!u(ªWKQ´òK_¤¤ÙÅÝ,=ûó{ß³êÇW=ýó3@œÎ?\ÿÙoü亩oÙX°ú–Ã2˜„{ÈKÈ€Üöž3n|ÒôO“£™vhÅáÚ’n—“ÖhS²WåÔb¬aQ++uö{´`ò’EåÉìÙEª©4yEµ8Œw*ø°’LüY2V”|*à Ÿô»¬¨kød‰Y¶Õ.Î 4¼Fh%db‚S"ŸÃŒS‡ƲÌÖR˜Æ2iˆS§¬0Þ “¯‚pHÕ— ¡QV¶°4ÈÜ ‹ þc±uÓ˜Ž×÷ÛEâ~}9öOp(=“05§Õq¬rKe†—0œ)”Š\BaÇx ò»Ú H°†Ó2³Ýëßù¥Ï9ÿ‹[¡o¥þÔ_Ÿýõ†OütÓ…¢ÖcqiÇŽð”ŽÞÌèì‡I%[ПKðÚ•™Æ¨la?tâF%B3#·ÉryŠëK,J6ÓòD`-aL‚„˸ÿ‰€(ƒ«U fE€‰SÌ l¥ãi*V9i©¢Éi¨.5m)¬bÌQrýÝÔs†òqè/€`HpÏ,IðlØ y )¤QÍËyƒ1lZÀ5ðôM7½×k½j"­Ÿ~¶©p³-þc™i„Ÿ:“ž0æ&¦’$Ž ¦aFVî®td[³VÚD–‘0…Ž­J*¤U“·µ^ùOÏ~Ñ÷ÙEõ¯êø§k>³cÏúþtGâæºì ŸGì‡Çs îÀÛ!è€L)sDq‚V·+ÙtB¶ÉËí”J>VÁ~E¥$NEvô0îk#´A'ø!­²Ç7*«Fb²7UTp ®¢½êôm2˜†¡@?t…e“"3ºD•ËÙ6Ì8á,á" "ÔCÑc‘N+Ly,P0 DÑ0(ŪB²KÉ«<9᪗{¸QD ÍËOßåÇþë5ÝÊ»n½ãÝ¥›ü¡ÖdËÇ„yZ£½0œ®­Ÿµêù%Ü^O¢¡& %³aM!h—·‘)(™”Û¤+KÕ 2r`låL³­u,­ùE÷U?ïÿåopï08ÝÕßæ±ÎGÜírß“[Rå¯IÂ…xr‚íS“ÖH­ýkA›’^W"»$m|rdV!kzxeÈñ,‚Fh”>•“Òܦ,É]98SŠ»]HÞ'má“x¯rlȺ³‚{)†æ¸¿õô±b1x8¿$¿5lý@p×Nfú0:ñ­Ä1e2å0îJ„%•$ÅõN«nŸirìR©ä"²¨Ð• ¥-ˆÔJ/H‰OG,¥uä+1iŸ´B“ä•Û‘³rs)o ÙŸ1N"ÜU0YeS@T’÷ H86W“„œà-Ð ûa ,¸vÛÌNHÙŸIY«¸ Ò³ÒYªHnØÕ.n¯àÝÝG¬‰÷×-¹æé”VûÖÆÛiåk»?¹ü{X½ü¦Û?–ÿñ(˧Xh²x9þõàÂcñt†±ý°ý8ØL–³h9KuvqjÈl · &”|½¨<ÊdwU8ð/֛꫃‘[z¯žü„Ÿí£LØØüu¬z=†Ÿ ÁÔ(€^0qʰ­i™Ï<Ï äaL@TB—}ò!q•´Œ¯ŒH¹ Ì*ÉHÕ«œiˆY“â"³2Ö+ÃAŨÞ=ÅûUÕUz©®DÎT,R,{¸"0wþÅ`=üö•Èð|ÊÁ⇔väv`Ég2£LÍ_Ù»» —çv¶ì>këYg^xå_Òÿª&þí[.). µd'î½hÍûwù;½ÄÛ>[ó?¼ãl…&h†ºã]ˆQèS /å"Ï&+XŸ²7Èwagá“Û›¦ Iü²ÍgAž¬k÷Íž—y*šû¹`Ë †`q7+ã´i‚}{; a¨‘!XjªA¹Ç=ÛsæÀH.HU:z޼ÙE©EaBFr7+`æ’‚ƒð¤'GJivùåUm‰æªU¥N>!Ö•Ê[SL9‹ÒÛ'­èÝÄkèðÌ·dÜ 1®ñü’Ó:{4²ã•êEùôV|M‰ûÕeNX©ŒÍSÄ>¼KUb†û3âpXô“Nó§ŸüÊÀÔ‚nú·|ç[þ›&Æ1ãX×Å*\ðÔ¾|Y°½—À ÞNyäæ*JûÞÊtåJÖh°ž‚‰"”م¦XTW`ÜÁ¹0:<áþe|<_ÂõXÞ»–РFcv•xb'Å^(@3¬—· d`ú¥GÚ‰4€ÉmóËI9µpäˆ@Èõ˽¥¸òªD£Ú[Ó‘ña+mмTß=ÆJ@(EçInêZõ £)# $FǛĂ+jþõ¤ß7¼wdµÈh˜°GgxÍ“úÝaÙ%Ë+ÌOÁGÅlÐ{eøC ^—`ÿ2VL³û¯Ö„Î,|òНþåίD·ç&7ÔODVíú“ÿ·tÝöÿ»®Ã=oácœ],5j½{–ÎìÒ›¤4!‡íö‘,²Šwø|¶Í’SøFˆ­P’iVPLT Rÿܦh “Òh«aMŒ6“¨IBðxŽC$÷!rh]Ш‘<Ëh”³”r‹çz¶Ëf!E…@¨)®óv5\Ñ/5Šý²6-*ð˜c¤ùTD€¥´;j»CñC­ÅN†áá*ç•®H9”µ®¹ƒnY;d„>”Ÿv›kÛgO¿7t顽KÿÄøÎÇv~ÉÝîvøwv§ÚFá£á/Üø7ߨö‰ÜõmÜcâz2=ÐæØ{=÷׆·VcØðxˆ]qDPñ@u”‘vÔåËìä´΂„àö2G°<ÜxøÛ¨]]CÞÁ…=Ð Å9ÜòKµp¿l”²ÁVܼj ®|)МLBÒµ¤˜Ú3ÉRme]É­x?Y2èQÌÝ…œ.Ÿ¤ïˆ§L—4 êZ- ãk¡§–EmÔÖ¥LÍ~´‹_ z¡¡0+Œ„ÊXòš«6â–£P¹ö΋è;ù wIi±Ç,m ‘¾Ÿ.¸öéïx¦qÚU»¿ÚýÉ×ümæólžq?öù¡G;/|ðר[u4 …2 öA®ŸÛZ¼‡Z¸Êd%Œ Æ OÊr£'7w=‹I—û†‘GsÐiXB}31Iñ$ö8(Ÿ®rC3+狦Ò}Έñ”vµ7§’7§…ÒÕŽHSïœÌt+9.ÕF»jcÊSfµ¤¨_ž Ú ÂEêJ§¬‡8´ÐÁ3Y­™78 §'ÆZňƳp·Kß4f­d %Õ±‘QQÝâô) ˜TÛéx¯ôÎL9—Ïd$ÀÙ’€K‚k¯Þ°ÛIšO®9çðß/,t;Y“8;^kÞôôŸÏþe˜íÛñîƒ3d“qJ‘z„¦&ºuRC°]â·*Y¥úq•L ‡·‹þø‰´°ô4ê!L Fgßý`AœÖ u?¤a`rR\N;Dà(ÏXE´:­H*¨¶JaÉ{(UÃ-m¥×é‡1Ö5ŽŠ ·Ê­v«Ý!OI’ "Òä“ Ç}0Có…¼Uã݈Ÿ†‰ ·Âd|86Îäò•uEÂ2¥1ep{ÊQS’·CU§®Wü2-U+ dÇiZÅ›9—â°ïö[ßúóŸ\ ¥\gEÜ[›ínݸáP­•úêÂOvýíð=uO˜ÍOLüA;šI— _b ºÐu|`:¤‡¥ÜOIÑÊ \Õß*Ëú´XE[Óej–CyRÓ¸½ˆiéT±z I:Ì(BvŽL”ÅqÛg…Qª+M@¯ÚXE™5/ûîZ5GSÒt½Ú ¾ÊÕ«™„¶òøyÕ.¾'!fõ‡,_Ì´5´trŽÆfèÆÝjNÿ¸‘ôÁ¬…×+/ˆÃr¤åɌήf{J í(±î½:Ìj‘áÀ ÐVS×H¿Ë³iš»4Tw½¾ì¼¾«þySí‹ÆúMùwÙl‡ —œyŸ÷:ý¾]üg—}«÷‹xÒAøä 'Ëäã$\D'†Q˜RŒŠ* €§´PLù¯Zp]†P:ˆ”¤Ï8¬èV &`1&U¯š@‡”œzJzíV7"} Û‘Ã&_u§O(v.EÓº"~&NÐFŠSƒQ„Ó”üG}TÄI¤1*|@—í×.è†Bc3tÀ° ’ð¨`lσ:yMJr àÊŠÜ­vÀU;Ç3èy軫·VƒFôfÀ¢½–kZk?’Y×µ{“÷„3ê{tÿy÷e.q›ŽÔ·8« ­Æ'‚øFEMÔIÙµ8qD²È¡ ÖœjÛ5ôãÞK( g”@W.â¸ædŠT¯úô°ÁG}oôë¯õ¼6!„½y4?nöH¶G¹‹5+•dt%©SßÝ­–óÊ%âUCÞs©è>|Ý\°œ+ 6Rmýun[âî*0œÂ5† Ù¾xT íIMX>:›YIÖŠØ*óÚ²—]™ÇÔ'ë*»š¦+Ý@•B? .Dá4¢4´€å1\€CÒ4¸â~\ÉRÊäeS)+9Ž«jJ¯"K©-%°T¶‘!)~ÉáW‡Çzµ°L%»UƒÞVÂT«®üN>†*…cå¸(ÿÚ$X¬Þ’/Ügò#è…CÙQ)šY>ÄÆå±fJyKÙôj–‰z™J¥ñ*±®ô‰ËSîÓèZJ‹ÎÁVißL) Ë,í55þ=]#-+&"‹sMÁ=E‚»5C½]…ïÃo`Rƒn(kCÛrr.dÓ#!‡;îsÄ=%™)cË"ÐuØ£ŒÏ0 V d5ƒF9!ÊIžŽ_A¡ø•éxùߊÒK…ÌV,7P µ¶DG™ÊÞ¯UK‰êFª£¼n*»¾V]Kœª£¨n –aa‹±kù‘(<èÑG`w»(ņ`\}Ž¨ÙŠá«V yŠ^§®\@íÅÍd^áîHI‰“‡,-‹¸²÷Q³9¼Éx"L>Måœsb¦%Ÿ‰ØY“(¬°}ž’GgÅS`ꡚd›âøM®²ÇWškeîL¦8.eŒ|….ˆËVI–V€{•}Ú|ÞÒÊUºË¦BS ¯5ű¤pò=¥‰¤UË>jІjY£URõêöå)mœj&])D˜>§CÏN˜•QM‚ÞÜj3W½úù4•îE@¥ñêØÝ…D­”uH¶Q¬%¶’•œi²“Ù}`pµ6’ó†„Ók‹Ü~oo7ÆÎB‹ÈøNÊ[Xö'+GyZnóE¥ Rç‘®4•⵨°ÎB$,¤•ͬܮ*¤£D³vœ0ï1c&Oé‘—KŒc6ìŠÃž'ó{í¸úRµqªõ"uE™USú`T«êêýBBeQð‘_N³Ÿá ö~é,Y³0,©µÒ-'ƒ­¢Ùí*ŸG•4ÔÕNñ¢ÇÜvªZ±†Ì@}ñVpy"ÃS¤wˆBÒ%¹q†$ʪì@6Fî ‰¸ É.¤Ory\©*œ–°r•ˣ涬l¹›–?[‹¼îeXyN2*JŸa…™šW„»¼'ÁT?xT«Ï©Kµ\'>ÓÅqÛÇñ$ M97ŽéÓ¿àîB·—± ¦\ÜE`HŠ­z>#€¢ßo*œZª-&©ÎÓåIÐ~Ïùr ÷Š·D3ô`Ô1›c(ÅÌk¡n¡¦¦ƒ/@1€0 Xd-&§ñöËŠÞ/ó"[*5‚.GžÇdÌ(™heÜèI>ƒ”ÈÈ 8+Ü&´&Ì&DN­t1ƒ1IartÌ/ªËÍŠ”¦´Euºå)àoïwźŠ[<¦A„‚§J¥{Ja¤UCŽËp€ œò”´j¥Q_Ù×sr¢dÈd†ê¿×­Îý\ÅÔ«žª¾’¡d±·áxø£ô,áüfÎ1ÃŒÁˆ`ÀeÄ#5 j‰ðQ…Ýrbj*‰òŽ”¤ŠRõ†a(ö5•êP‡h’øçƒ(f7f=Äê FA'ë’È#F¥è¥¸‚©#¡cÆL®Rö E!Ñ;NØÕ«îÖ©q\çwªÏOy¶…‚/h‡ªdbeUz9"5œÃ²‚w%õΓç§[ý9…’_©h0£:ÛÔ_܈ÿÃŽ™*7~rÄ׳ñ4Î6èfàQx¢Ñ1² ʨ:\R­ÐŽìÆT\¤ý’BZ®¦”ÄFÔø”í¼Bë.3t¤Ãír¢ít×ÑÑDwpÎåü¶™$Û ½¾TìN Å›NœeUyÅVR—c’rC±¤+)wêøs@-[õêÍ[x~?·uµ‘e)xL*%•d‚„zyNVz²~E>R( §zw÷ªYi¯ªRµaŒ5ô¬äÒ í„ÿ,±mŒÄ!¼4Z ÍQ–h_AóF# èz¡äGfØ;Ép;ž_Šžª’í@Lz•™>¹jo&]’!*pðJŸ{%ͱÆÇZf°`Ø<ÑOº1 Éà†õteK1-GƒÏCD¨„`@B—]%¯J—Æ‘ƒØP5Zð˜á‹¨¾˜êv¨¢‘µjH§Ç ¡0*{/e ÄIyeÊ@·’L鯫fW)TvwçÅÕþýƒ‡»-G<ˈ®¢9À¾"?›d¶Ë"ÔÁ곸<y§ÕÑ5º0ØWã?ìùu¿a72Uô‚OÎÙùÀ:þÎãÙGaXÆœ!¡/ÔH#ù ýJöéWîz™?œkÂhat“¡)ús8©Å^J³ˆDÑÚð¯Çß58! ;'}@û¥Ë¤÷¼@+$=Ü£Öd¾9J¿²(LšBt8¾lUSµ)ªs_­Z§‚æ=™}¥Áï“}Ò¨Ô9ó”é[P–O¯úŠ'Šš¡ÙJì‰ê¸Š ¥[ý*éÌÈ“`»…•FÔ^G{ˆÆ §kl$ž5f¼C…¥é#~±'¥e,_Ûi^w,kÇÙmQÒdÂ=,§ªåaP»T OJm™€$¹¹ŠÚ5’Ã_ÞéãЃLìa|ïœðª' ~ÅÔ )™N\‰¬'[: ¶IÊcJ=MùÛ+¨2G~O±}-*SvEÙþŸó)òª™u(ŸÁ8NLꔌ&Õp7¤áLFåU]„ÖLÀAKSJàME§ÎtÅ·ƒŽˆùÙïy»R¯<˜£¹a Qè ÐJNÞáp?}ãÜ×:îæÆuÎ(þ)D‰B )…")û\.cEÐ0usÂÂs2&*XÅ–"¡hyGQ% M¬<—– uA‚ü:ILXLäIO‘Â䉙©¤ÝEëøæF¼P÷šV5cãSrªaUš’ïºJ1ªVªò«ªMrªü1ý}ndvÑT‹Wdô0 ‚xÉ2C¸ DN>É1%?¡z¾k)BØelOùÛÝ㷯੪&Õá:! ‡qö“ ûkZBo/­_•¸"|{¬7ƒ !¨‡:ˆ“j©½-õög~½NütŒñƒ0&ÙB¡”³ùŒäèò uI[M¶S"•BËÑUÏ•­¼Vvóûû¶çÙ¿k&N:5Sú¹JãïDp«Šfe£ÜƒÒËΓ»~Q–zªp—P`ƒÇëùçxʱ`U·ANµ pZ¶iÍè:1\—Ä £iBA-Äê 6’¶±“XS0)K[”NkyVÑT2¤¼‚{báÒ•ÿ†{SU~H£eÙØ~Ö½KWß{~â‘Kù­y³ëìDz jèeaÁvX…sµéCé@óòTo¿mÆÚ{åµ|'–¡/@ópH³Â"$$gLÍÝ]Å/Mñ“†¯åè;ÄT‰¢‹”õ@uç°(JWœÚB&8ìrx’™‡QIZõŽę̈}KRî[`Ô‘IpeŸËÃ,LÈfe¡Ú~¼eeû0ç´æ4 TJµxAýOIýà‡öaFf? t°‰kø=“d|¢ê` ¤¤ÕJ^&~¶ü ¶ÜÝM…`^”Ôó+áh¯ p÷æx™¦Îk{Úo˜ù‡ Ÿ}×}? ÜU"…ë7ö\±jû;ÖgŠ5]·Ã?¨7±i½käPûÈ£«­»tvîÅ5”¿ëK1ÎdQ†àp ç Ì¤=…`a*4OÖ^aB§³¼™I‹ÛgéÈ˲ԯw„#ëZãùÚ Ò…å‘Ù¦ºŒ›±œ½&}°ŠÃ-JÂ`VKFR=ñòíÊ’Ž˜VÄ&e·°å«ôæ+9ºVŸTÞÅRxÜž|È5Ay ¬à”öø2¶tòÐËèj£ÅÆK0Ç´†X"í1#ÈeÈO0k` ©ßæW(ê%ùÇ:2è] *dWÇy.ȃV]”¿2JÕ¬cÝþ,иéÐl!þó¶«úÏèy uááýKÒ–ÛšiNLÕ¦fx¾R”H±¡(ôáµñIkÿÙž•ã{Š,ÉÝÔ›s©u÷Ñ%؂ьãÂa¹hÇu¾…ü5 äRB—8g6í¿ªý+õ}mÁ±˜™õû¬„Yÿ.Ûe­ÙÑ»nðñN÷7 ¶Ì’™ ”Â6)•`JAP¯zUÙ½tyoHO]¿ÌÁ*JZ®,¯£2‘Í*=QÍÊrQ–.å©0Q6SÒXOþN¡h–Tš¼Aˆ°(ÀÇ›g»òϸûµÂCÑÁÉ®”¿øêˆÔ¡AÎfÂaÜ#[Ä*`çñ*ÇŽ­ìôBN©² ²Ãù]®W@¸ëÒ]gÆâ®Àž'Nû«™¿î®I×/O. ùßk¯ï ÷凧}ŬðRÙY7•"S¤$ˆÄX¼Àœ¾fÕõÿøÿß}åFôCFå¾a`%¤PzJ±S;к$ÚÄÐj èêÖ'ßÑ|[O©_K‰I§yÿìŠmS§?šÜpä?›§ö†Ý¡qÆ~ƒ3!MWBÒÆRÔŽŽïUëÕ3rߺ¢Ð$“xKîÄå4I…ÎlTÓð„¢]¡êéŠ[YÂ.'+uŸÌpLù™OÒâKSÞ¨,ÒÖŠÖÉúeá÷YmkÇ G¬¿/lmn|ììî§{.í7KîÀH÷3g?ž?7×N=U7ÒÔ‘kP£a¦mÒ® wGîâùé6,d>––†¡Þs=„¯ŒRµüGF0J´”/.½gÙ/ÒذkkçÁamL0ˆ—Ö‹Å`Z¯)j‘¢+ù54,#/Üi·ßY½sï?t×Ý×\Η.!yF s3›Ú¹ bpK]iò-x%%#4ª“is®XlìŽ}A\ðڻƂm_¹íSC¿ìðv$ 1ëÑ7‹£v§®Bµ˜ËZXàwë#¥lMa»Ï~(Kb;‡=†“–¦r*S-!¥…|Pö.«Š†eâ“*éM`Av@^‚áŠÏ凣IÓÉò`¿¢_6ï ÈI*²úI‡‹Pú&Ä1V³©U»>´øuG>¬ÿëuãß,=è›ìÙ¾aý/ÄU®Ðß¾íìà3¯Ý©Éy5ÚøÂ¶}þI/nY¾LwŸÝ6l¶Žøš'–l"lÏœ™› 2Ñ‘ý“ØÓ YÌ”ln÷¹6rí•î&úf¬Zl|ʸôm·þ9ÿ²`Ï ×¢ïª_óãÒ¡Ã]Å>†Üà³Zç 1'fÈ&í£Ë[²®tYãÃq3ZlË/Î$¡avK’;‡H‡õðÍÛ7r‹ÍÃõwÁ˜,öM¹Ûi’Ùé÷ξ|Ë&Þ+úôkzþmle+­¦+´†f—1³<<²ä´^ƒµ8ØÛÕ0TŠú‹Gèx’sþ˾òÀ£+¸«‡ƒÁ}Û»¤Zy¥ó”ʬ"P„aØ«Ñ!ðãN Òh>„…0µÐ ‰¡e3£2…ŪNfŒj‡Í&´(Ñ:EÄ€l©øóTFª•éRtN^F ²4´|ãÁúþo¤?1æ¶_Óôƒe­|pÿeÝsgý›>üš¯·¢ÖŸZœ8²¬æà%±ûÎO>ªð´¼ÐBk,¢°*ôpèüÛ½·í+h‹ÆÚ¸nõôXLk+‰Å"‰ ‡u†p’,a§gqÊÿ wÓà‚•Ôƒ{+·ì}Ïo-îá@#‰ñtlýäúPÿÒ†ÁÓ"{ ¿«‡½¹F¤Id&Ìé~wjió£OoæöýLG Ëã×Ìž[ûXt*ûØšÍÃÝ]ü…3×pS-é»åDÓ ûÔÀZšÚØÈþmµÿ•æf~±ð*–C§¢Œíƒc˜‡õÅ:ç?ûä;ŸX³¯ØÕ¹gø_:þü“±¯\Øq~ò‘…á¾ú¯\ö‹÷òSѦËéºÑû\f¬¦öüd‘Œ’ P*§u¼Ô*öh‘l¾;6¸¦÷¢®#M?ZÛ®ËýÖxíOòïšúa ÿê1P&Fæ•1â+nww]žé'ÜÂÂ`×ûÇÖmØQ·oÖ÷†âÙ×lyóHKfB÷%_Â2LO«Ä¡tƒ§à?)öã[ }ú†/_û³oßþ×g:ôaåi^øJÝ-¯{ó…ó»ÛÛ׸æºåÿg¤¡s¤¾Cüº™g—ÀÄ-9² ¦¡ét@=¿1/;ïŠG—rhåè¾Þ…‹ï<× ™Ô0“­ß1¹âÞígX?²¬]F¡×s³³#=—KjˆG wpøƒ‡ñ-&Ú‰Þ=²ß\’ddîPvu_ξԼçýÃÿÁÿ4ÃF¨Eš3옯ÔH^U÷Åë?³'yÚ“·m²TO¾K¢$Œê¹©>÷ûÏŽÅþ!SSJ|±§ËtVÆÉ×±cGöKHz¥V.V«\<ê¡<¨Ãá,í´ »ÎÖŸNµA§pøæû—ýðVÞõ¯þßò‹«³[£þv+¸¤¸Ðí[ÐÖ߸`º­u|YÇÁ(Ùf&뙩!%¢äkÎH½’°4}‘çÃÖ\1\ê|ÜÛô¤sNâW ì,×p›Ù8ÎàM…K¼üÃÝ§óæÆšæR×Çúÿjá—®*ü"Ú™Õ‹^a08n:è[–lª1mÊj|Ä>mˆ¶É™fk? »ŒâkÓÞòÉÇÎÍ>±a`[|löSïûÊSßüiÿu¯e¯G»á‹fú 3[#c‰3>¹íî¿ñο¼âÃcßuF*´G6Ý¥ pÊb¦™Lô?6¼wwíý'…䡱AáÓDD F½Æ÷xKÎÓ¬zq¾î^\ܵ’=+ͯj9óÎÜ»ë_3£aÍXáÑñàŽï±Ça¤Z×Å“ÐùZÜ\ò[uŸxæ‹ÿþîk^ÿ_úÇr9áùƒÁg#go³—õè} ½k¢} WLíû¿\7~FËÇÎþ—Ûô·ózÄ>%‘Õª€„Z„&³»ãàÕ5· ýk×}¿ºøÈÍ‹¼­:!‡€ŸÀ2Jl•'¡yr‘*j×#WàQ!^£e—Fÿ*ÿO~Þì6ÚV 7µÍ45O%®j˜yK½•õg‡¢Ó½Ï8‹è/<’‹´å}Í¶Ñæõ®ötÓÓ„Ð]ÏŒ:!3_ †„¡Eû³þ%¥ˆ/w¶ûôeWüföÍñîº-÷œi½{#ùLT³ÔO qêá¾víºººÚ£/Û CžçÍÎ&å–}Ò}Ü Æ?Õ.lß^oÏükÿ‡¸ZË ÅÞH"]7ÔŒl²iØ Œ̺.|õí.DÞÇð[}ñOÃ6³ÞÙž^7ù½&¶õ‘ž&aeÿré'^÷µ[6½û²ÿ¼çõÿ*֚鶇êºg§ÃÈQ“BŠ®ü!ÆLŒ¦«êþ™§¾¼jéý5g­¸x‹¿ÏóúL‘ÐÝ"3a/Ξˆ=e {ÙÛçΈÃТíù»ÈâQAC+³i»ñ¿>÷o·¿µø½SB6˜+Øc_·þ¡Ö®w ÅŸ™˜þ¯Ææ?@̦?K”°ékÌ$ºF¼Ž¢—Ï®27io\y÷ŠÐ¾|8LDQ‘TЪçM>ôZúÀo{îÜpÅÅ÷¿íwÜÿº‹w<¶Îº]c hVµxïÉH¢VÈVúÜ¡ fÙ3¼š…Ô×Ìè7„öÞ³dïc+HêLy8Ah‡AÐ%fÒ€× gÛcÙBŒ#2óª8Œ ž@WiÉŠCÝÅYkÀ¿=¹.éÅ‹Å`ªPëöÉQk ÅÊ“¤9…pŸ˜ÏfSž7—<¥R©Å‹—YV¡X,ÃEhnn9Ùß•|ÞêÿľÖEuûfK·Ø¥Ä¼(7 Ššž³¼ÞÖ†¦™±tÜ"‡˜D<‹WÂuàÿ"Íít½;üGï¾9:•‹½ÒaÛ¨¯[ú¹é¿9óSí¿ÉíˆüÛ¥ümð’z}&ŠÐfÐ×#²6Õ#€Ýˆq½df&ÞðH⌿3ò'¥Æi¹×mhdüäüAM4DbNx‘¥ˆŸ_÷5â.q A¦§ÍH¡ø‘%ß~àÓزŒßW«p ÐñûƒëK×ýÍÏþ‰,âAfv“Ñqëñî4šœ@}x2¼tOÍiŸÝý“Û[¬´Ÿû‰³ÍWó$äxҳȉœÙöàÛ­kîœv7î™&Ë ŸEx¸ôa¾y¥áý|yg•îZ} WiÚ±çÊÐἿ®HÌãu:LëL缞ò˜vÈšsÍF#C0‡/ˆBÓ.š†á4ˆúàz%Øã.Ûã®ÆÑÀ£ ê´C Úã ^ˆ•ƒÐIŇâ% ÷t:][³,K†{Ú4ÍööŽööùv÷ßñÍ·\ô'¾sö‡ ¢nId˜®"ÃbebzAäÚ$DJÖRkK¤çéÄjçɃE´Þ²”¤àÛC¸3¼qñ‚¶Dìg™üäa²r_ÏÏM ÙÂcÁ[W½3á5¼îŒ{.ž¾ßW"4—Às.ñ•ˆXùvÿŽõì¸òg¿øTûWþíŸÿÈÞ?%-x. €¡´Ê·Á|ÛâÛB¹Â®‡ÖlýÁzïeSë£Pîš EËîdøÕT)O`mÊ4·LÖN¥&wfFÃŒD˜lb>Â剂A­1Ç,ÏC&F&6g«ã€ë›ò!=„Ž?0׃õC“N“ÌG`e„a¿,²+O óZï§î…BAÓæ2ÑDbÆçó}}‡j¤XÅsIDAT,«”L¦*_ýÝC&C¬\±ïƒ…4lI¤Úkg7Ç‹ë}îÂúroÊÀÅk*Ž7‰½,ÛÊò¤¨³gƒ ›Œ™ÌêÃ4×{¯Ysà²uë‘ÚZ»ktm!N¶\î~s­è}ÓõO·iký;cþtmmÓ —ìcÄDõ¹1äÊ%yÃÿá¿ûGÍßçg3|çHÙ>NøÃÄ2Ôy,´™Ñ ½À¿8þLãë“uXzþÁоxãlÃåÓ…ÞôþȬøÏ:†¦ðvKø{¹LÍui¼)qÛÄÖ»º¶N¼åK‹ßÉâÉ|À; Zœ)ñ=2#5=øÜeÿkÓeOLÑ´_¬ècá±|j¶9?J÷ÖÌÆ“‰Úd>d¢èúÜÔ«B»­°¸Ù¤‹^‡º$u>jbÔꘀmð«aœ­’£“S±½—0Ü©©É¶¶¶\.›N§£Ñ(`Ûv.W°mkff¶¡¡é$O)íÿÜ›?÷¥÷ý¦é8[µšÐP£­LÅ0†† xxv<"^oöù„‰æk:Òµ^&(Šž¦k–ߟjhÜa¬ö¶žƒÉ€3`|Wó/n2W×ì®:ä.ÿå̆ƒ{­fZCëiSÊ;CAŒ- Üûî;ßáÝZicâëëHEQ+hZFIM¤ð¦`/FÖ fK®gÙØ®ð <'lèÁ¦PúÊÚßþê’o þù³ÿg3÷µ/ÛB¹Òÿ¬•u–ÿËÔ{š~díч½vÛ3°–ÀÐ0 ŽFјJ/ØùȦ}OÖ¥ÅJ1 ‘(ÈC\ W µq"grIƒ“ÓøÜÅOöo2ê-{¡[2sÆ£êQ¶B“­`'GàPÝä6ÁGcˆ7Áöí_ù©ÂWº',h˜Œ·%Ã-ù–†‰–† »Á—_.4qÇ3 N(ï†3N¬à… ^¨ B%p0] ÀÅðÐÑ0uÇg:ž©LRºçu²0à«Çé!p%Äøï@D–J%Çq†"‘HåÅDbºT²ÇÑ´“-“ƒ‘â¾øùxvviáPhE1<¯;’ŒÏŠT©”Ç)â1l —À§¡r.TQvˆAldäuíg¶î4× fºƒÏ®ú´§÷ÄŸÕúE&MÔnîþö®ýå¦Ë“?=Ý>ŠR£">Z„”©ÙݹÁ¶Ÿ9¿¥ÉƇîG€áÇõãFqcF!ÊÍÓ’Ñc_À5LŸp4áyhAÍj¦â¥ä¥Ö=—-ØÛ±¶xízžtŽ4W B7+k×­½÷ã‡ÿ¥î§I¦%½¶ IbdBÇ^àKŸU3±¤ùpÓÒŸL¿ã®-¯O}ï4ˆS|Z*›ŠÍK - 懼u¯{¶39’¯Ÿ´›’ã‘Ò½0±šý¬0H®f2†3.SÅ2Z¡2~ªPмjBwX¢¥®õÝã×.þöÊô¾á‘ÎñGj–t–—zÖ¿—ÕŒQJ !F«?ž¦»~Ý ž®{Žî¹º't!ÀÖðhs¿(´¢`Fóft7mØÂO¡i’ŒF¡™R-"RÞð% ÷P(¸iÓ¦ÆÆ!èîî€aºÞÒÙÙ9×]ôùO6w׬w×Üê±éÃ3KÙ@*R;Ûw;ðxa¨4¸dЦ,±ŒMê5=RÒ‚%Ý/t¢Z¾Ù—lˆftSËGû–LÑ$„7•¬Û'–-[ÞÛÚ4¡'=-(:ì‘«O»åðÒ%OwläoÎ`Ð’åäIÀÉxúû+ÿ¢õ«—_{OðõùݹÙlˆ¼FÒbNz¿d;þ\^ÓSI)´"Aaj>Cã@«/éõ½Qó‡ÁÉ»Ûíq‹ bVVå=Ëcã÷ýóæ÷_ðÝ W>«•Jy=X0ƒ,嫱„~Íxu¤[´©ÆäÂÂ@©èïŒ7oN¤Æ–±§ŽÁ8$s‚ zÖ"1îÞß9ÜÝUOµ5·ûG3Ëbãµê “ <çÉ8?ì`j+”‚Seíb»ZgêáXïhg)•Íïå›#=ÑþMmOút»T矡>AÃM´ÌP?Lç èNj …PÑ KAÏ­€åú…§u£²\®Õê™Ëû’#¥(ˆ‡{Ø»`¨„Ó'õ­ì—0Ü×®]½víê“æzýŽ•)F/üòQRvo-á9Ó6#6)”FÎÃ)#„*žÑKe!}iB Z]Gè^ B!â:KC´ûcÔéD2V#‡Ó$öÀ^) ¬rázy*¹õm ¶†.§Ç}VRŒU‰9G:J&²$þ±i´þ¹Óg¶ÈîNœ„C%nÐ﹋3 ¥0ýŠfe¹JïB?ƒŽmõ„KLîe¢ÃP”ÃÊÀæqR÷НwN|?>Ó ÕQ%ê'ÆgA–œÉ”MvÊø6_µ´ªW­Á{Œ:€˜“Fº7ý¡Å_^uù×z®lòYQ,Ûô¾ZǬu´®i”üB0déÛôÙ~Ÿcøa¸ž‡î¢{GyK^EÌJ¼*rPË„‚ YLÏÈà¦aÆsÙWÂTÕ+Ù¿÷ëêy~‰¥qžNE8s¦.м„etΨ dª Tª•[ÇOáÎÕežíUk/ E›I¯šÔtWò’²Õó?q´;>øv•bMQjrß*×µ# âhóXbT…èdÁ b–¤GR(N£.yÓªlêñªc•O«jT _3ÝËîû°;~tŽ‚ ®¨¬qœš_¹¶rÑ,IØÉçÉ¡oEOÓ­N±´PÆ^–á×]wös¬ãª%­ZÇÙ§@=ªŽFª~*aYWîè1÷¸’˜zÕ–¨Zõ5ÕÜUÛH(›¢û\³Mùl*?Cœ@óña SùTj·ä˜ÇÉSÀÀ*#Û«æC¸UûBUkçbŸY_Ÿ¿ˆó땲Na.õìÎCGf¢•?þÙc{÷®|õ¾ûºá†/lݺ}þšÎ¯WC¸ûüẖEõmKš:W ßùóÛ—®XSùêC=zã×ß}÷=ó×t~½Â}blè}¯?ýo®{×¶§ùø.íßÑØÜ~Ì÷ÜpÃ_Í_Óùõj÷Ææ¶K¯|÷ƒ¿þÙÇÞwéeo¾úí¸®üºëº7Üð…Ç{ê‡?¼uþ‚ίWI¸†yÍŸ}öÚO~Þ*—®\§ëº|ݸñÆë7oÞøþ÷¿kþ‚ί—ó:…ÎŒ®‰XØøè'?«{¹÷|àƒ>O׎6˜ÛÛÛæ¯æüzõ„ûêå]M‘Ià?ÿ Åô*cÜ?ýÓÍ_Íùõê ÷úú:×-Í_²ùõ?"ÜOr !ŠÅôü•_À%„÷ßî^¡0;Åç×ÿˆÝ½²êݲe»amþÔÖÖ•JÅ`0<Ýç׋²ŠÅ¼ÏçÏdŽf>Ÿÿ 7ÇãuÿÝá^(kj¢‘HDÓ´@ ÐÒÒ2;›twñâÅ–Uœ¿Uóë÷\##£†ÑØÖÖšË妦&‹Å"P_ßPW?ïâ¥EDjš …êëëC¡ m[©TÒ4ý¶]ªhu̯ùõ‚W"1]_ßèyŽ®‹®®Î|¾899ñü Rý%ý@Ýíím¦©Û¶5{æ×K·,«dšÚ‚ ²Ùü&w:P_ÇëjkkæoÉüz‰7û™d2UWWÿâ„»ß=¦¿“H$jjBÏó#ew"1“HÌœ¨z˜_óë÷\33³SS ¿ßgš¦ßï{qÂ]϶«NŠ}ûönܸáy~$Åbe YÇI¥² ö ONNÎߤùõ{®b±ØÕÕ3::Ả¹¹¹üb8yi“Çqî¸ãÎw¾ó-ÀüÓ÷¼çå×s¹ü“On ƒåÿõùü†a Íß§ùuLG£,ÑõÖ#<®išm[Ž3dz3Mómo{SkkóKîž'<üôÓ[,èÚ¿ÿ`åuÛ¶óùœ®®ë­­mº®MOÏÌ÷dæ×±Á®içž»izzêüìÁƒ‡Ö¯_?44P*•‰„çymmíµµu/y©zèPïsÖ£mmíáp(N}}}mm-ó7x~³²ÙÌèèð øÁ¾¾¾U«V•JEMÓº»”[ïϳ^„F¤aè¦iƒÁ‡~¼££ŠßtÆ\×)Çúüš_/ÝBär˲ŸÿÛNIð:µs玪6MÀ0Œ|äjkkŠÅÒ1Mþ½{w Åx¼®¦&6Kæ×Kî™Lvll|õêÕ/N¸‡B¾Ï|Î/•›Œápè¸Ú¹‡2™L2™ljj<Nm~ý_–e¥R/Eëyžëº™L6•Jk¿Sæ%3þ³Î:«®n®n(•JK—®ˆDæñaóë˜R•@ ´lÙòð³«WŸÖÒÒøËn@(zÁKî': æ×üzÎÐ}!9Ì1OÎïúþçwÇ)mm-žçÎ߇ùõò\Y³´[ïuÄ\Ç=5–º4~ŽÏ8õ©ªm€ÎÎvÏsæ/ëüzÙ®!{¨ åÿîï뿸æÌS ÷ááñññù ÿüz¬P[”jÑßmÛöø£ž­­Í­Ïî]] tÍ_Êùõò_i£°×>¤¾²aÃúpàh{Ðó_Õ¿túEfÓ†Ïïªoá8Z±xB’gooßwÜ9;›ü}Þô„»{2™Ìd2GŽÎ?ÿ|]×·mÛ–N§u]?ÿüóÇÆÆî¾ûîŠaüñ롇âñøÚµk{{{5Mjnn^¹re>Ÿæ™g€L&ãºó}ý—eZ,8ŽÊ³çù©<§¾4×-¹îQP×øø¨¦q ÊPI°cƒƒÃGŽôoذþ…‡{ÿ`ÿÀÁYõ ;vìøÎw¾sõÕW7ß|óªU«öíÛ×ÒÒbÛöüãÍ›7¿÷½ï=tèÐsþÒ›o¾¹Ì. _ÿú×׬YÓÝݽmÛ6ŸÏ÷Ë_þrÑ¢EÀwÞùæ7¿y>¶^q+Ÿ/üû¿ß2::üùŸäðá#­­Í‹õüèG?yï{ßyÏ=÷§Ó™;wÇb±k¯ý ëº7Ýô¯Žc766|èCïF#'ù.ßúÖÍÅbqffö¼ó6]zéÅMM==Ý•¯ÞÿÃ>øpÕUoêììØ¾}祗^|ÿý¯X±¬½½ªùXJGwŒz® †Ìžî·Íu„“?”=æý®¾úê7½éMÀg>ó™x<¾jÕªM›6år¹/}éKïyÏ{žçƒ®Zµê¶Ûn-Z´xñâh4úÑ~¸å–[R©ÔÐÐP9 êïïŸWâzöÙí==ÝeÚÚÁƒ‡ÇÇ'ÊèÀC 7Þx}_ßÀwÜ999õ©O]‰D¦§‰ÄÌɇûc=ùo|±¾>~à _¸ôÒ‹ùêæÍçœyæéÀ¿øõk¯ýàÐÐ00<<ÚÝ}¬ÿ^M}í† 6¸–›I™À„3a kzd’…—ü>Wᦛnzã߸páÂT*õå/¸÷Þ{ï¿ÿþ}ÿo~ó›+®¸b>z^që¼ó6ÝvÛ/¾ýíï§Ÿ¾öøoxÎ|£±±¡±±áäßeáÂ'B8Z–õõ¯³ì00>>ñü¿§ä•Æœ1«hMLMœ0wooo¯pC6mÚôæ7¿ù¦›nºýöÛý~ÿç?ÿù'Ÿ|ò¶Ûn³mûÓŸþôUW]uÞyç³³³ålþ¢‹.úô§? ,^¼øÚk¯ÍfçÎ¥K—655ýÅ_üEù«ýèG+Äíùõ Z½½}“ õåÄfÑ¢žÇ{ê©§¶lݺãøo>ýôµ·Ür»®ë¥Ré‚ Î]½zåI¾ËÎ{¾õ­›ý~T»wïþx$¯kjjliiêóù¼ëº±Xtv6uóÍÿñ«_Ý{î¹g?_¹°½¸ýñÂã–°¦üËó®-¿Z[Û9ßwÿŸ¼\WÛ²åõÏ›6Uù߉‰ÉB¡ôôtŽŽ¥R™ššè·¿ýýo¼>΄Ã!Ó4mÛ)‹±Xt``HøÛÚŽfÕºnîÛw ™œU"Á]±bYCÃÜŽ~à _øÓ?ýc˲ë£Ñh:™™™šÿ_{çïÒ0ÅñP{\Zµ¹¤hA“E+éÒ:ÿA(ÝÜú÷øèÚ¹CVŠBé”Ô´AH†äš\"4CH#tˆå}ÆãÝ_Ž»Ç»{‡årɶÛv¢‰xžÆ’$‡j§sY¯ŸÄWþŽŒÇ…F]ªÞ©w£„ËôüíZmõÔc<<8ŽÓl^D!”¨¡"B{Ç%¦¥04§)S(ÊqüÒY©ìÇßÄ""üW|_Ó^ c¢(²,ý9éº_éímÆ ƒàS­JýþíÆ‡íõn2ZbŒ»Ýë,–i À°eÀȶÕafGBoHO4ò¿=a—x¨AäÏöˆD<–¬O›sä.ž‹O‹çÄæØlµf¥xÈ!æ‹Ù¾jOƒi¦Ýº”.ÓÊ „4d!£.”$ò X@ê¥é3RoQŸèê½J×U×ÍPÿÐÁ³@á1?·æÖ§µÖòì°’ÜKí$IIEND®B`‚snd-16.1/pix/waver.png0000644000076400007640000027751511147553271013014 0ustar bilbil‰PNG  IHDRôk'æ{sRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ2&ÐY2Q IDATxÚìy¼$ey¨Ÿo©ê>Ëœ™DP". šbEÔˆ‰1&zM41šh 7WÉUc4÷j4ÆhÈ•h$&Q"ˆQ‡¸EqCE‚¸±  0l300Û™9[wW}Ëý㫪®îsfa˜yŸß¯~U]§»ªºªgžï}¿MÅ#‚ ‚ < Ñr AA„.‚ ‚]Aº ‚ "tAA¡ ‚ ‚ BÿQxÏ{ÞÃôô4ï}ï{åÉ ‚ ÂUèeY²¸¸HY–òäAá*tAADè‚ ‚ BAA„.‚ ‚]A„=aå‚ û+;vÁwÖÿhŸý™#á¡ ‚ ÂýÊ'χ3>ç_´' WcoÜÍ$â¿ü³pÁûaíŒ]Aî>ðxÕ?U®ž÷^ ý{·ÃÁ¿ úÛðïz¯¤–:tAa¿!Døè×à¯ÖAœ¦©jÝÞ?µò'áô¯Âì¢Dè‚ ‚pŸñыᥧXõ#d…ˆý7þ>ý:xä¡"tAAø‰²«øæ!òÝÈàŠíðüÀ#BA„Ÿ>ÂñŸ€Ë¶µ„ï%¡«´ÿúyøüµð;?÷ú­·ÞÊ;ßùNxÖ³žÅK^òƒ§v—_~9O~ò“yÅ+^A–elݺ•SN9…7ò’—¼„g=ëYlذ“N:‰oyË[øéŸþéÝ^„sŽ~ðƒ\rÉ%sÌ1üÙŸýÝnW~¡‚ Â^qý6øüm¤paï¢î½z«Ýø«áWfò}ï,kwúé§óÆ7¾‘uëÖ±nÝ:Î=÷\N;í4Ž=öXÖ­[Ç/þâ/rúé§pÊ)§p '°nÝ:vìØÁ—¾ô%6lØÀ'>ñ >ðpÆgð©O}Šþð‡»½ˆ~ðƒ}ôѬ[·Ž'?ùÉœvÚiòëAöš“. )2Ÿf¸žÞÍë½]V-_Ÿ½ ®Ùö‰ÐÛlÞ¼™;Ë/¿œW¿úÕ<å)OáÔSOåÄOdãÆ<ìaàñ¶žu¸fõ>Ô´|ÅKÙ¼y3Þ{Ö¯_ÏoþæoðÊW¾’3Î8ƒßú­ßâ‹_üb“~úÓŸÎ…^È£ýhÎ>ûlŽ?þxÖ¬YÃE]Ć ÐZsçwŽúÔSOeÆ ¼ûÝï൯}-§žz*¿ó;¿ÃùçŸÏ+^ñ ù• ‚ {ä’¹Àç ²É’˜+è …n¼§S0Á£c‘z\6TÜPèŠØü=hM™e”6Ã*ýÝxÏ—ẾæIÓû¸Ð?úѲsçNûØÇ6úSŸúTœs¼ï}ïã9ÏyO|âxÙË^Ƈ?üa.¸àþüÏÿœ#Ž8€7¿ùÍüíßþ-!ÞñŽwŒÿÈ#¤Óé4¯Ÿð„'Pï{ßûxæ3ŸÉÓžö4ù¥ ‚ {ä„ÛÌÒÇNyЉ< ÝC^LõéÄ:Lô{ßÒ½¡{m(mF‘å,LNãAňq4¼î.Ã¥Óû΀«*Þ•ä?"'Ÿ|2o|ãy×»ÞÅÞðù5 ‚ € "¼s—ã›vJ‡"27=ÃRg’¼W0³8—„^Ð1 CØ{™Ç$óˆj"ôÂæÌMϰØBÈ]L7çÔYþhBí»º ‚ ì«l ‘S–YcV§zîU`¬gUžÕfSf‘,–Iè1ŒFßwSÕŸ+"t›ƒ•GŠ,Çx \VòñAÉïu'˜P÷¿ÔEè‚ Â†Û£çÕ½]̘E¦²EY‡AÞA­ŠÌôçXg™1sL™E¬rèêÏw_‡>^Ï´¦Èrœ±(Ñ*°˜O8à»ÁqU0k:"tAAØ[Î=~f™6ݼOì*ЉœŽ0æXv1cæ˜4KhÒíM„~w´Sîu„nR£¸hZŒöôºIèå€Ì—œV*Ž5‡‰ÐAao¸˜yÞoå ÕCÛ€™ô¸®%Ï ²¢dMØÉZfYeæ™´KM¹×ÒÞ*Fb•>¯ÅycP6’ë‚\ä¦ÀÃDìaµã;z‰/Ç ž­V‹ÐAaO\Æþ7±š>¹)PD|fèthP!¦è\ϱÊÌ3azIÐ!¢ {ÝÊ}E¡kC0š\Xå°8J2:v€õo g©[x6¡ ‚ žx'—¡ˆ„ÇhOКí B$– å#kÃ,kôNV™y:v°¬úi*S·r7IèÚ •ÓQr J—a¬Ç*G4Š-Ìr%‡ó8î¿ ÓEè‚ Â>Kã³|Ÿv­(LŽ)Óà1±TèXãw²ZíbÚ,Û‚ˆJ)wö²•ûˆÛ^¼1xmP&â¢%S%68Êa´O©<šÀE\ËÏrùý¤Vº ‚°Ïòy.⛬g-*µNWi·Â烜à4”`ð¬ ;Y­‡]Ö¢J¢Wì}„^•«”j¯#t ¹*°Þá¼Mä”LJ&p3Û¸™Gòh&BA€’‚¯ñ®ç;L$ÅÙš¨E™3tèôĨPe$3e겦S w‹#(ݤÜ÷Jêc)w¯M³ã Q'¡‡Jèeª»ït•¢ô¯sæ‹ÐAàÛñsÜÀ×YS×gWB/\N¿×%+JÜÀ¢TD»@¦JV³‹Ufž)³ˆV 4*Æ{”r_¡ë4pM¦J‚Jkã<ÎÛTHpÐ5}ò¼@°÷Û=¡ ‚ û ž‚+â‡Ø¿Á!*‰8 ñÑ0(:ô{]Ì¢'8+,ÆxttÌ€µq–i³À¤]BÅÕ+â=ë‡ÞŠÐƒÖ•„ÞÑ¢Rtâ€Ü”e‚×tMŸ®î“ÛîáãüJÝw¦Kº ‚p¿Ãùô—þ˜°d™Œ©{ØdX"Í`¡Ã`W‡l©¤³4@ "Ák¼3ëQ*Ò12[&¡gIè¹-ðÑàƒIÓz/¥£"D=œÄ¥5¾{î 2WR9ýAï y,A3a{Lè¹-Pa=ýÎLt_+BAöcüP\ ‹¯B-èø my§ ï,-NRôrÌœ'Æ8O ŠÖ:´Iá:zÀdXb•§CÕƒÁ '– uDk:¢UµÇÐjÔD´¨JèQ'©£Øsã¸!êjÞ«‰¨_x%œøÇ`»"tAáDÙ‡-?€sß7Ÿaf(ñ¨ÆÚ¦7T  Ë@D‘û"5–SÖ¦úéè¾ñ&+ÔÑCª7}Pe@P&ÍΆٻèEU‡^EøTë<òê|:3UÍG¬/±Þœ&:…¶a(óH*\ôOðo¡ ‚ 6^ ×|®=®:§Jsºª–y‹Ô+¹«1! j•Kék›Rç΀«DîMå*T‘½z1Mœ c2¾'s§Æt¼:¤<óáyƒ†*#õ"ÆEp*u««ª _ÿ/8úÅðàGŠÐA„}Ù-°0ŸùøöaËMIäµÄ „J¼Q%A*Rû´4Áy+J¯^+"*,¸,EãËD®ÓqB}\¦ŒÐ\Š®£IBj/SîŠ*垤®ªH<ª”»·à«sGUe"Ø2b]š°…Àh›€Û¯€oŸ¿ýJº ‚°qéWáòoÀÅ_„ë¾3‰Ûa+ S50W®µ*øâcžÃ\g†_õñ”îÖLÄÛ—Y*x]¯JyS5F×UvÛú$ôX·pw xSGè{öøˆÑc•® =èPÉOߎÒuª¿¯#õKëÉÅ$õRCi ÿé³±/=ù“~E„.‚ üøô®¿žþ 74‹EÁ]/ù°GÙü<*„ÑÞec½Îœ‚èÀW)eÍ0z^ššá{Ç<·¾é_ÙvЃéçÝ&Í>"Ô8*Óšsžñ"Î{ÚóxÌMßço‡Þµ‘zl]EÏ:BðUÁÁƒõ¥»(ÛAeY:fo ú®9QsµÂ°±~B)B£'& ï‹|(qÚ5óêH=T™¯“À‰`ôúU¤ïÓ×/,ÿ?yÈ'Ï¢óó?Êsº ‚Ñ{b(¥†’Š‘#·œy&ÛÎ=h¥†2VŠÞÕWÓ»î:MLMOãœÃ/.Ž´Sk€>rŒXêFPkÉ''QSÓ\ôôßä¬ç¼€KŸú TŒDJÇfö²Fä{Š’‰t¸ê˜'ñúü/NýƒãÈûE•P˜&(”ͰÝIÔT;³†ìðÃÑ«V¡­M÷e~³¸Ht®JÙ+Ðz773BŒhc0Y†ÎsôªU¨NææÐóó¨;`×N ï÷på§"AAÐi­RÆã`ÁÓ¤ï‰évù·£ßýnÓ›è}´]á@§œ›ãösÏeöŠ+è¬YC>3C1;Ë]_ÿ:K·ßŽ1m-ÆZ²©):kÖÐY³†lf†ƒŽ:Š|õj²™T–1{ÕUÜøÿA9`¬ÅdY³èDŸ9J„]AøQø![ù'¾ÅN°E@£¶öªd®TZtõƒÇàÑ*`”OïiEèMºJwÊâIc¼†¨é|ŸE¶òÄ´<º ‚pO8“‹¸ŠÍx–˜B3‰ÂGCC¡k1ª”NW­Z ]‡B¯Çƒ…‘=ê$ô:*¯ ±ú”SžK¹çòKò`Dè‚ ÂÞð®çb¾Ë¹P¬E¢&MðÌpsãÓ e&uGÓ„¦Ñ›Á§¼JBOÖŸGTŠÒUê²æ*=Åê|EŒ  Æx¾©.à©<‚ƒX#I„.‚ ìŽílæb¾ÄÜDIhêɽ7xWEæA‚iø`T•Z~$B×*Õ©kRëõv'«*B*Eáu꽡‡¨qÞ¦hßz¾ÏWyÏ—‡%BAÆqô¹™ÿæ»|‰Eæ™Iq6Þœ³øÒ|•¯­*ÆFèV§ÆoפÖÓQ’ܵN©y¥âpNt†BGÑÔŸ7zTÍ5hR=üvs9;9†5ü”<8º ‚@¥ÎM|…[8—íÜBŽ!#¥¸Ë2ÕWÚ$ó šÖìµ µ ˜àQ*bƒCë$t«út5lñ®ˆÃ½K6FÕÈ<ªÔØNSd^EèeÈpÞ¦B‚˜‰»Ø¢.f5ˆÚÛnl"tAa¥Ï-ìàËÜÆ™€f-,e‘Q–Å '/S<ú46;0lü¦CŠÌUÀÆ¡g±lRîut®ªyOëtº¢ê¶¦i†{­Óîí=DMé3JŸ¡b$Í´]à.{*ÔÏÅ2%B—Ÿ² ‰ãvÆO° ¾JÁvÖbðÁ0(;ý3ðXç°¥K)ogÐ*‚FÛªn\{´ã“ÐM¹‰žŒr$åÞžœ¥î†Ö¡ÐÛÔ2Q3ðœOY‚à4Sv‘)½ˆ‹·bÍωÐå'-‚pÊ<œË®ð*|è±*wø`è]ýq  ]¼7d®LÖœnê¿MHs©Zã0¦.8Œòd¡Ä˜$ôzp™f™JÜuʾº¯ß×&V}Ý]° |‡Ògxgp¥eÚ.0i–˜õÿÌá«N¡ËÏZá@¡€â|ÊÁÛqá&um8XêMâz?0äe.ÎÙ”j)2A¡Mª·Ñ%¡gÃÉV¬qXíÈb™öUuèÑ'¯SúÐjXšùR›ô½Ñ©»±¾©G/}Fßu›*WZ¦Ì"¶ptìFÂÄh{˜]AØ_‰=ô/ù÷By6*Z:&4Ѽ3°¶tøº ØàšîbZ‡Ô5ͦa[3J”‰dªÄR‰ó™lÚ´IþÑ ‚ Ô‹°ý&Øü¸ü˜½zåh|%¡«*BW)Z¶Á•J‘·ŽÃ4»UñHTÉÏQRÃh¼ ²ãp_³í+™W‘9 _7­Üz¡ë*:o =’ΨÈ|™Ž€ÉY( ?0gaÛç…®”âq{‡~¸üA˜Ûç¿vm„+>¶<W+È»°zݼž£•u¤n€u%n5zLÕ–7-™‡á6¾êŽbjñÞnÙÇŽ§†3°)‡Bgôºc뚈1/›> ½Žúuº ‚°rëµ0{ôæáƒ'Bt°xW9·ü­Æ„½ÒþÖß1‰Q§uЪè7*¡È¿µVÕ,kš1‘×s£‡áv‘I3°µ…ÞJ¹×B×:4b¯© QA0Uj¿:ö@ ¼ï5ðÞkDè‚ Â>ÄW>—ŸW~îÜ&E¦õR{Ö„¢óÝ ]µÄ­ÁWÇ fTâQ W…ÑuÌ«PÕ£×õæµÄãPîÍèoõØïm¡·®³º¢ª?W°lˆvÕºÕuÆÖ.þŽöç"BAØøÖ7áÎÛaÇ68éu)úÆñ“$L%âÚ¦•Öz[Þj(l_-¡Špë5TÇg,âou?ÓŒ[©öº%ï†Q{[êíYÕš)Sãn Uæ ® ¯>ˆ b]°Qàuº†À`6Þ ïþkÔþA„.‚ üdˆKKà}ó:¼öµ„ÛSõ÷÷¾ [7'ñZš5uz¹Ž”+IšÊW¢­¢æZv¾*x“„×OFçõgj¡«V+õz­ãPèu^Ÿ³N±ëj;†åbofXkÒé+´Ðkïªú¾©ö…´ä_§Ûƒ~Ç*¹ÐéEгÎ"ÞñØŸùYº ‚ðãÓ»øbŠ«¯nœÕû×%^w]“Ing”ƒN2BqG=¬³6!‰Tû´/ðUÛWà³aîl%¼*î«(¼^‡ñz÷ê: £ðZâº:o-é’Ô©¢óúuô ”&*R”mPFÑ`X Æ€5i­UZTKæ¡úr.¤ÂOá†Û΃÷Äà&âê*ƒ*R·Ä”Ûoä®?yøæ•"tAa…Û{z·Þºb`¹ù”SXüÞ÷FDín¾¿yó²lx»š»í2UU«¨Q(tÐØN‡¬ÛÅ÷ fg‡Ñs¸VuÉ>´|è‡)úv‹ð¦e¸ÂU=nK]h@¡QªþâÕZG…¶² ò e-ÊfhcÓv–¡³´Ÿ<ƒÌ¦%·Iæ¶’¸1 õPèÍ Žé ƾI襃~Iì`P¤LGQ} ôqÁS”žEçq®¹‘;N}?ú£—­>0›¡ ‚pÀ³sýzî8ï3ƒévɦ§1›>ÿyvÌ®X˜ ’8¾’6ËÚ› ¯!‚6c3´µcÒkcÑõv§ƒét°yŽ®×Õ5ê,Cç9ÚLKàÊZ”1#kŒNB·:m×7:¥ÞõXóû¦%|Ly$É<8TQËÝïƒsÄ¥%TQ z=TQПeñŽ;˜Û´‰ÁüÛßþ–ææyĉ'bV­¡ ‚ ìïL=ìaü„'pçEQî܉˜@gY·‹év±˜‰ ìä$¿|æ™#[¿õ-nûÜç(¶m¥’''±dSSIˆÕçëý&ËÒºÓÁNN6kç˜nw¸îtPÖ¢óœè=[/½”»¬¥?5Z£”Bë$Åz­´ÆX“®·ÛÅd9[t0³kÖ`²Œ«÷‹|æ¹ÏCÇ2J¡*©F¥‰Æðä[oá%W\2†ŸïLjnÉZgªÚ‡JѺÒ:É[ë$òêúš”º5IÞF×¥š*¿›áëj¡×ç|•Ó/=„€*K´÷(ïQEõ[Ä,CoÛÆŽ¯|…­wÜSSä«WãÊùyº Â@¶j>î8|Üq{õ~ßë‘=ô¡<øÙÏNâ­¤¦IR«Ä¦ÛQk%Ýñé:j­$Xïk5ìØ¿ùf}Ñ‹Rt\EÊ&«"ì¤ñs‹h‡ÍâSýyè%¢ˆ* ½x\AÙ_æÙΛ8šry"tAáž2Gs¸žï²™ÛY`íXQ#ëq©·e®TlêÏ#ŠPµÕ_Iæíãn`–dOç¿ÝÔ…rÚ»VaØŸ­Õ¯­•§ÜÛÇ©÷og;gq9=ŽãhyH"ôÝsà 7PŲýwÝu—<1Aö{–Xd·sAü½X°-ÎqP]× Új¹¶·÷$õˆB§±X‡2W˾»cGþ1*¾Ê¹äj‰'òD”Dê"ô•¸ð ٹsç²ý×]w<1Aök®Ž—pm¼’[ã­ÍÔ£k«èºi²¦FëÉ÷”&‘òJŸkEéãÇOÛ½zßÅñ,¦‰&öÝÆ£ï‘Ætc]àj©‡ ñÞðÃø!fl—#Ô¯ËC¡ ‚ ,p.,r£ûWËyJ§™š†±kªÿ¤“Èmt蘄ގÐÛuàËÖ1I7FÕ,!¦[ÚïUíúyÝÚVq˜æo-íã–.Ã;ƒŽ î$lg3‡é—ÈC¡ ‚ ì¯8<ÛØæÿ–]å÷éÚº.#š51ªTÏ­ÀDR‘L—hÈcQå–„ÞîfVφ¢&ø1‡ ‰^ª‚Béø1¨&ºnסk•ÒùÚ”Žã1Ö§µñíWzßuñÞ B$xÍ,ïaºk™V/d89¬ BAØákôü±0ø4ƒ~ë,"'¢È\™Þ5Z¥jb’h¦K ž,–hB“‚÷Á¤ÅÊ2EÉÎY‚×Í:5*óÖ2N‘kP¦ºã±Öa­#ËK:ùk]Ó—Ý9ËÀušóyg˜ŒK,ù×Ð|V?F¾]áŽßåýy”å-¸þ<¶´øA‡€*S$¼F™ª¾Üz´ ˜ÌcH2ÍB‰ÕŽ,–(‰Nὡ(rpK…q>m;… 1mW2Q-z»ñ{D¦Ø«”»1¾‘z–•Xë0O–—äyAfKœ³ô]WZÊ"׆ z˜ž§¼»ößAÏÜ‹%£» ö†¯Í¢1º ÂOJä;aöß`á½· Š]æçÉ\™äí=Z‡™›™ÛÌ¥ô6‹ÃF‡ UDXd˜>wUD´è2`¼‡j>ôà5ʧBô)I^×Í·£óv”^Ë@ëŒö#Qº1Óñè, ó€Í™.ÉC+,ƒAWXò² z…š?›ÐÛ…~ȧ@ß c¬oÿXú(¸ ÷M¿VýtŸ ¿;º ½@9 ‹×ÀM¯J(nªLYý½’tuMý·6i —¦žÚ§µ*Z}Í#È:T‹UFtHB'$™×õØÚ‡‘úò‡kâ02o„^÷mW­Ô» h0ºU—ž{´MBWYUׯ<:¬w¸Ò¦ºõ²Ê6Ì} f®‚™'ÿè÷ÖÍÁ-o€íLS¥¶k ¶œæcð˜ó`úDèò/QáGdáF¸áß wlûÒ¨ÄëíÊE¬r(›1Ôµ 4µJ ÑV$¶Öax<å*¡»4%jSX©î|¥:óf=Ö­MQÉœ”rGÑ\W¥k¢r­*C{TŸ3$±Ÿ2Ö¸ôý¿õ"xüYpд{|åkàŽŒÞÓ‘ûsø·À±çˆÐå_¤ Â^âpÛWaa|ûMËAÖ¢QcÒ©„n¢OÑ,¾¦Òa¹´w'óV¤®BDù”n'‚q>ÕƒWiöôhWµºE»R»? g`ÓC±7 ôtjq¯³ª’¥´üòñk"&úfV·T¹ n{¼l'(³÷÷º˜‡oü9ÜôŸ{¼·DàίÇþ­]AØT#DŸþp}øágv/˜ñm•LœÆPO"ÍP«-IÇ1y«Ýˆ¾ŠÐëhœѧ®gÊÇf —eÑx\>:ÜøùÚÓ¬6‘:©Z@«j±Õ: ËÅÚ:fS8¨¯9,À·ÞOzõÞß÷/ü¬_—ޝÇî©-äà 8ÿ$8ö­+„ð"tA„—Û®‚Û®LÛŸz‹ã¡èʯ¶£J;-±5fz%p@…Öz%¡³B„N¡ÇÐDìQ©¡àÛéõÖÈpJÅᾸ<²?·V!WçP¯»Õ˜#.ß Tý=ëzÿ¼6n†þÃÝßÿMëáò/Â\%sîi“ys=àKøðËá}H„.‚p@²8E/-ÿüg`€-Ò¢X^'ËÓÍ•ÄCµ®ck¢ñe©éJκyXáºÔn„®’ÐãÈÀ2Í /¬=¸‡4uýU©C‘„ŒÖ÷ÇåboËWyÐU |Î>žó×09½ûo¾™xÒóQ[6%‘ðfx_‰·„®}U(úÆypÜð¨_¡ ‚ ÌnƒÏ®#à+Ÿ Þpyržj¹ow)u5V-ð`ª×Õþ¨©ÒÜ•tTN•GW2ŠU&ߢڽ€UÕÊ[Ç¢îV«ïzבYÖj©ª8ò]âJ§ˆã/[ã¹Ç±h~<ÍÞ–¹J÷’ˆuë@• ÜNÂkþêŸBrØŠßÑ¿ýåè+~|e6¼¿ŠªDë~’jDtUÜŽ:ç?áu"tA„ý‹;ï„Ù)Züæ7àÌÓ bÙ#Þ|Ý0ŠL fÕ0ÊŒz%z›Dªˆ1´¢ÑvýxN¯ƒÙZâ:@¨Ö±NG‡1¡ï&ªNQóp; »ª›§*`¨±ëi¯i­ã 8º®£`Ó÷Ñ15)©÷£rUT¸,½Ï{Ðò>Ä þ›øK1Ïú½±DÄôßq—~‡l](òtßëô½Šé9µ¯ Òý €r`Þ÷^Ôä¨W¾V„.‚ð@Å]vå9ç`jqñŠïL1UôXÁµd­Or­£ìzq‚_‰¼Ž>Ç¥9^-݇¡€ÚÑx-ÈX§ŠÇ…n dÕbÓâ½£è-VˆØ(šT½Ð®»oeÔŠøH„>"sFe^FtSEÄÆUûê´:Iæ¡J“—Y+Sá!ôÀÐ;áOé~d5_ÎÌ6øÏÿÄýï XèˆKéxƧge|ºW* J!¤ç¥ÄA‰ÿø'èüî¢|˜}Ÿúê/}éKX¿~½ü%"!0wñÅËÚ¢myõ«Q;wÒt†šŸ‡ÙÙfJXÕuÇHŒ…ªÕX„§âhê¼–·Ý0oÄIÏëÖqꔺ®#Ú J£H‹I5Ò`3TžCžC'ƒny“9ä6½Î,t2æ~pó» Õ—h¤=V_ßû¸Ì÷Jè-™· 'uÿˆØ]’¬ñyÅÌG—ˆ ‹¸Xâ¢Ã(m* Š*š¾};÷ù,ͬfÕŸü »>ùIf6m”àH÷¼¬Ž«"dlT(eP4ŠÐjb$ý<ÿ}ýãÿˆ‡Ÿ÷Uú>uÖ²nÝ:N>ùd¾ÿýïËn‚°â—–Xÿ1”n[Þ!°õŒ3–í_©šÛƒévÑÆPÌÍí¶1úJBk¢ôJþÑe¹’ìš4z­ :Ë06ƒ,GY›„m,:ÏÑÝ.ºÓÁv:¨<Çä9:ËÐyŽÊ²$ô<«Dž¥È¼“ÑøàÙvÍõ,”c‘÷¸ÀëÌD]æhw‘cÏRWchGèõ‡tÝUÝWÏÈ#ô©™µÌ<ùW`aµ°;wÂΔós (‡íÿ"„»ìÜÅì;Þ­“bQ»§È²Ý©iTw=1‰™žÆt:è,C1c„²diófænº) ¤¡øÞ•ôþê¯ø™·¾»j•]áÇ’t¯ÇçÇÕÿøÄ~“eØNc-6ÏÉW¯&Ÿ™¡˜eëe—Ñ»ývŒµèj1Æ`² m úˆ#ÒÚZLž“OOc¦§±““ä«VaºÝf °éË_föškF…ÅònÌJk´1`4Z”Ñhk’ µFƒR“e˜n—lrrø=òÛé ;t:ϱÝ.»&§¸èáG¦ãX‹²6ËZ~}v˜T@ë$r£SDntº1D¥˜»ál)`¡7ð¨ÈëôöŠ´¾tÜß—ݯÖûÛQ;¤ê„!Ë:dO8~㙨þSع9t¿šEíÚ…žeiëVúÛ¶ÑŸŸÇÁ{‚÷cèg¶“Ó™YÍÄ!‡0uØad33t׬Át»ØÉIL§ƒÊ²TXÒéYû[·²õœsØÆ°03ؾu晘իyØË_N÷ðÃEè‚ ?3~4O~ÿûS”šeé?å–´ËùynýÌg°G‰ÒÓé`'&ÒºÛnON&YNN&Ö‘ÚØ1ƒsÜ~ÞyÌ]r ’h­MïošÏŒË9˰Ý.¦*8¨€÷˜ùyºƒÅüâkãì°ËX-G¥¸òMT¦kØQ‡®à)XþžÇpv²°s'êð#8ò¯DW¾®®¿¹¶*ÓÐ\oë{DÝw'sH)ìG^Çšôv è}ZWËÚ£æ'>ÝJm×gÊöt®R‹¶êzñú~Ÿì¨£8êMo"›ž&_½šîCB÷°ÃÒ3=€¡ ‚°_¡³Œ5?÷s÷ê1wâè8íÜÈ€kHù﵌õÙfl²“¶«hf\ks=‘·¢ø49GójÄ¡«VqijŸ Ï~v#ë¡¡w/À{+&+[´àVUsÜSêBÈõ¼óœC;.É[©ú·/BAØŸb_d7ÐÙ¿vO¢Žß62†zdt8Öñ‚@Í"€‹¸—™ÃyÆäƒxSò0~B…º Â~ÈÌÑÇó!®e–é 5b[1‚]a*ÒÖöÈßÕðýã󑯴 ðYvp 9Ã8œi&ö˜ÄDè‚ 8%žÏðm¾ÉFvVÑxD±fi·‡W{Hn×ã¡/“¿Z9ª_I芈þŽÏs Gð+<Š_âHy`‚]¡f‰·³™[¸“op%‹ô1ÀÁ-¯$ì%=jáúË"ô•¢óÝɼýwEä&¶³‰k€gðKße7–GÔãuÝã’ߣÜÕžëÊ÷$ôñ}í÷]ÀgÙÄz~ƒßf‚Iy˜‚]„‹;¸–^ÜÅe|žy5 À!c²¯ão¾Lè1M]ZOa£"5ò·qÉ×]Ù”ŽhÐ*Í3Þì_AâzlŽÕMÜÎ9\˳y3¼°ç,ÞÊ2#w†à5Ö»™·…ÞNµ7ƒ¨š¨¼ª¦h«ÓíZWb×c<ÊD¬uXëȲ’Õ•û‘{o†"¯ëÈë4{kªÑz˜×fè×ñ½Õ0N1¬OW:6)xkZ²¬$ËÊ$önA§3`rr ­¥Ë(Šc<Á}‡Eó‡¬Zõ1”þ ÷U·âÊ‹èõß‚+䥕2!# 'Ú\Å ÿ :Ù³0öA­’ßï ô·¼å-lÛ¶mÙþ+®¸Bž˜ à7Áü߃[G }bÑAMVæXåÈB‰Ö)ʵžL•<Ê'ÙEŽ/ º è"É;"8Ð! ]@‡¢o_Eó^4vk½µêÎk™¿N«Ñ©Ê´ ØëµÖ)ú66ÕgY‰5›9lÇarí;²¼¤Ã FúвÈ0úJBùÌAŸ}ØOæþ‡»`çóñýõè2' ãýÈw¨Ñ:Qí±Ù‘; µæýò;>„þæ7¿™²ýïyÏ{øÖ·¾%OMD·ÂÒ÷`á 0÷qˆ½$Å 1Þ§n]a(k]ŠÌ &¶º’• ÊˆqIäˆeõ7—Þë¼éŠV§çëcH{¼‹y{Òõúµ{[‘zkݤàM{–•س5¤‹n(Øväßámd×ña[#õö+ }¥Ætíîoµ˜ëhH#vcýÊ‘ñJ™‰l¾>÷Zxñ™÷üm¿>úû°¥’¹ÙËÏÝ]!«¾¶œþ8þÓpØÏîec>úB¸éÂtž_}+üò‹öþó"tA„ƒ¹í°õÖ´ýÉ7Áì&ØöCny$^WY+ˆz¹ UÜC®î^.*FT¨ŸUÝÊt»@A+ò6Ó*´Zr7NVéâbë\±•mß]– I8TlÊ¡’|PÄ&M=,(wÛ6€±{寎8Žûã{ óMð®çÂ×€`ªBÍxRDí…Üãn2Ø|¼ó9ðÏ7íE6g+üûñpÝ…Ãçõ©·Ãy¿þ:zàN-+Bá'Ë¿¿ ÊÜv |ÿüå]Gá±xå²äVêºjû†©ë`Õ^H|LöÀ CÑÔuÞjx©0‘ö/#ïwUë¼q7-ÜÕ˜ØTd8f]õ=UŒiLeêýj´®<î^èÿŸ½7—¥*ソk¨êî½÷9P@AÑ bœPsˆÆ8Ô¨ˆÆ(ÆW’¼Æ¼Þ¨ÑçH¼yc®7§Ñ8€(‚&80 ‡Ã|€œyÚcwW­áþ±V Ý»÷ðõø)«ºvŸêªZE}×ïYÏzO¸Ò°“pòŸŸ€ç½f×í¶ù^üG^X³ Ÿ€Ó`(ÏqwUùB ½³è@l\‹¿è»ˆcß°ð¿ïwáão€ÕãU­óåwéƒ÷ý{ôÆk¬±ßÈò.½8¸ÃÏÿ\ôÃJQáÕ·¬Á[P ÀÉJˆJЋ(Š=Hßá–‘ØFn×LÈ®ü½r­jà¦vžµïŠãÊyb»b•Ø…J­ŸÞØ!‚»}uîƒtáX¥°v ½¸6‘wu<îï¿„|õN”úÚ;ññ*üÝ«púí8T/@æµsö»áa´g¢0c”±Ø÷¿ ù¥‘O}îüºyöoߊºêbLJz¼WÅ=ßù6bÿ§Ã '5@o¬±ÆÛ#»qîsÿˆ“@ÞÇŸ}"¸t%Gp»è²uàu[á-+õZ(S¨©¹“PJÉ ÒN-5w¾•µŽFía.a] LŸ£†ðGá@\Œ»¯\Û£”ºŠPW¦¶6nĎ׊£ éƒîu1ŸýéN€îÏøöÊU˜6dm°}Ð&¶G½#CÞ7äÁ¾ÆâÜëU`«Ã>oÁùößþ7­/Îzÿo‚ë.!×·Âõ =.žŽí¡Nþ$ªzc5ÖØ|›;í40!HŒ­[ÉÞóžð/`ÕwqeË|/8 &‰ðÖá^€–¨€ñAíÊèBÅ‹ºT¤èÊs%UHÁšç¥‚¶*,e‡¡ò¢óàj®üÂ;P€yX…Œáç ‹Ïá?ùQyÜGA}Ö;7Py*êŠ]™pÏ´©–4 û\„¦Ñ+È3Ü/o¦wüPz"ã/~ñÀÏvOÿ.ùû?Dކ̽øû9$ly®Âq®îyéц9a_YÐt¶]l Vß<Þæ>úïbü¥/ÅmÞÌô[ÞB~é%¸$<+b:œ‹rÄ)‡±æ Û¸ñªWÒ9õÈ¥K 7ÖXc_³Ý.nnnäߦÏ;ßüæ@PvÿüóÁÚyCÞØjL{8HÊãǬ‰ ÎVÌ=þ§|Ø–^  ’:-Ð 2m!’ÙnÓÛ±éµwDxÖWŠÛ› ä…‚„¢¶`^ Û<Õ] nó»ë´<ë IDATàÑB|¤‰Ým´šR÷ ºâãõ Î `Æí£á8-ñÎcñÈß= ùËëè=á ö…/ ¥äž¿øs¸äbtîé' fA IâÝ^N?ž‡ÕÁIbE¸çåP‰˜?ÜPz¢GA¸ci«Î›áXNÄ|B?<û«ÈŽ<’ )q^ˆI@tmÁ¸ª³PÜoïÃyegÿyÒIôÕ¯"HTÖ½±ÆÛ«A}ë—¾4o¦×ð,°Í\À¶ÿ¸>•¦¨V •¦è4E% R)º6`­ÐÀñüNÀT(n$Jk„ÔH¥Ãñ•NP­Éø8ªÕB…óhµPí62IPí6"IÐí6Bk¼÷l:ï<¶Æ¸¯fžQdŒ®C{ j¾ØW¸¹‡È:¬žGÎ~uÍÃûüžµòÔ¡8Ü™¨OÙuõÝàÊT ¾ìp)Ͳ§<•|v–¹M›ÈfgÉ»]ì­·ÂÖ­¬=üpÚÞ£º] µ&_ÊØÒe¤ûïãÞóÎ+/Òúè"gȳQï =ºÜeì„Ô;&ÞׯO Ú-̽÷b™$!™˜ ]²­SfÖ¬™÷LÃüéísßþ6Û¼çà¿ú+uzüáŸb¶zc=DÍ;Ç–+¯¤»~=ÉÄD ä-W^ɦŸý Ûí¢´&'#àl·Ù÷ÍoFµÛ iJºx1ªÓA¡;„Rl¹òJ6üàä"HY!%BˆEjJS’NÕn(·ZÈ4E·Z¨$Aw:ás´îtñ\eì<¨v!eXkLS¤R­iö%!“Øä­·²AÀ]+W0»|ù`¤ùð¨;ïB:¨Yœ{D,·AˆÂ_ÿ¿u­BÊx$B „P[Ëúg±;úÛã]è•xïÁy¼sxkÂÚ9œs8cðÖâñ~>R÷~àß?ÑüBk–}4'œ€éõhmßÎ܆ ÌnÜH65EoÇt¿ètPããŒï·e˘8ð@ZûìƒlµØtÙe¬¯u,¼ ÷+ÌÓ/îk¼‡žóeÊW·ÀãÊk¨Á_kqû¿à¸<Çf­%KÐñÞtÙelˆ@/ÚLJÚF©xN@’p·Ù‡ ¯>ŠUŸ8ˆÖŠùkdÃïÿڷzc5öš’•Ç3°o铟̊g?›#ßód’ ” j;BRH J…`TË"‚³ Ùµk™2†G¯XîtJèJ¥‚jNÓóV ×R©ðZE_&I€ RÁXv¤,·¢üNñ9DØ…ïýJX~äzL-ï°E¿kžôDÖ<ûY `²J«úÊ/|™4ÏJñŠïà Ùnè<×.%RÊp?ŠÏJ…ß­ý¾P*ÆÈòE;”ß©uö¤cìœsxkÁÚÖ.ÏñÖ⬠€·Ÿç8c°Y†5Óíb{=L¿é÷±Y†ËsÚûïÏþ'œÀâcEËsÌÜÞlüžˆ÷^j:tÅZ)vÜr Û®½wôÑè4-ª´ÏV|¾TÑÎE[×ç‹NŠÅSsžcúýòº¼µLz(‡¼ùͬ|æ3AJð¾|~6]z)3·Ý†|Ö³¢ÇG†Žj§ÃØÊ•´–-CµÛtÓ%|aõ‘œ1õ<¶æ!ˆoýžŒoTvÕ×àóçÀO;ü!ðNðÞû‡Ê ìä“OæøŸýìgyßûÞ×¼ÑkìRÿñÅ[øƒU€¬Ø7´õ}ÃÛ»iëÉYOÀØFÏ °•=] b<‚}f»´¬áÑNð¾n›EHŽíª#1|M øÆÅð¾æ÷ǽ÷œ«©ðòÕÕªòÙÙú¢èŒA€îгPvpò–ÄóôÎ3ž«/:5ÞÓÞg’E‹BsȺ6`ûýš—¤ê„ÕMÓ‚·}Qsþª(ÇÝÈbg“ÁïÄñŽKàâÁQ6 ½±Æ{¨©ÿ¨Àlû%Ó\À6VÑãFº®[`é‚ïa±[@·ãž.ž;€w/ÍÙÍ üOƒB4 ?ÂÆ8`¯8Îþ;¯ín \r0Îè¿Ö °ÅÂÇÏ‚ÓöòÙp{=ÐsœuÖY¬^½ºù¯«±ÆF6IÆMlçF¦8“uäxrBÉÒeC ö»î¨¿‹oôú¾ÏläÜÉs ¿Ç¾Êâ¦ab¶aNø&\r/°ˆ˜mÏÇl{~äs°KO /ªå·ÁÇχüAôßÈLtýÕ£mk¬±‡žyÀ`ÙÂßávÐgÛñ ‚ó0Ðëcãå~/vª®ê ¯«ué_‹ýg²+ãwYÉ[8Ýhö‡„å.ÔuùɽQ™;ΡA:÷ÝJ…Q#ÿërøà‹ ÙK »íõ@—Ròº×½€;yzkì!j›ØÎ ÜÉi\=êå5Pü¨'^®‡³¼ø]«÷zE´²Bš¨_}ÆV.ç®äjŽãi<™ÃØŸåMãí­ÏÔ¼ñ,¸xcPæÂy´1$6GY‹òA ÿëÝI‰• ¥,}ÝbZ Þs!œ²—ªôf ½±Æ{À¬G—»XË¥\Á$]6²ƒ¥ÃÀ†xQBÔEÔÆŒ0ÅztùÊ}@¡×J“˜¥pHéÊÒ§õºæÏEü„¸š·ñ:³„„¤iнȦrø“KàâmÀëILN;EÙPã~ðqØ}°{NH¬RX©p‰$× ?\/xãxÞþ Ðk¬±G€­ãÖq'·²šuÜS¾ —ż^Ú¸€·8'qN–ûê ¯«óÎ;«{¾€R/R‹ áK KåÒ#…+á.qX¶ñU>Ë“x/儦a÷ÛžÁë?Ù”¹´ŽVÖ§•÷Ie†ôÁ厄øî½è –@ Ÿ H`HùÓËáŽ×ì}÷¥zc5v¿˜Ç1ÉÝ\ËÙÈæ˜`y àY*pç$Ö)¼/·c™ÐynöŠË¤}[àÅ=”ZLˆÀeX¤ª])þÏ|=s«y ¯ä`žÝ4öoÑ6çð'×ÁOf‚2—ÖÑî÷èÐ%•-Ù@9»àó²G ]*œ”øD í(îUŠÿsüÅ! Ðk¬±‡™ÝÂW°ô¹ƒóð:ÚC®uëTX¬Â™ Ä­UA»ÊÕîbÕïDPÕn¾òV]!c™ß©Ú"vDØWÀ@¯)u´6(eQÂ"qx¶²šÛãÿc%Ç<4àÇedlç^ö°xκÞx3\Ô Ê\YK»ßcÌÍÑö=™“ª @9‹¯åÔÝ£À81t/>Hå0M·Ýá?'oÈaå^4Ó½±ÆÛcsÌ2ÇõÌú;¹W|“ŒìU8€óAi«±F‘ç ÖF Ûð7kUv‹nõæ¥"¹FEY•$¾˜ÅNÆËw¦º†€^æ`—¡S b©8­ J[´6¤­ ­L ö;ù š²Œ½'2ʰ·0É5lâGå­³Ìápläó!g?ã"é0ÆÑ©gî“›áó›<›¬€Å sÃxw–ŽíÒI»´D­ Ú¼Hç* ï¡:VèЙãZ’|"árŸð³×½±Æ{¨Ú?aÒ}—)~ŠG0L_)q ç &רÜb­BÆÈmpµã îu8b~o9è:~ðe\D§×÷‹€îç«ôP'<ºó…ŸWÄ\ªD¥´EJ€n2’$§Ýî¡d€ú6þÇy,ã#H–üVÛc†Ó™t?dÆ_ Æ¥á¡Ø\>ø,á…,ãÃH–íõÏÜWg<ö¸–€$yθ›e\ÍÒÖ=:®K"r´5(gqB"½Ã ùkÁÂsâ„Ä YÝ I5ý´…Wœ<#9nQôÆkì!dÞÿëÖ1cÿ…ÌÝŽð‚eº (+ÜçY–’e)yž 2¶†Ü$x'0F—cçÞ×"ØEt¯K?PT¼Œ<¯E¨ËX>LÈù _°vi­XH1?+ÎAi‹À£µ!éçhehõhµútZ]”܈ô·3ç/eL| )}ð½$î¦ÝkéeÓ$ʱLTç]\O1Ýo ’߃ð›qînføãê¯Q⸽ŸéZ>Úµ°H!ñ$y΢™iÆõ,czŽÔg´é/гïqR"\X:qö| ÝÉÐéI¸w¾%0-H=×êÿÚ×üykïÈXн±Æ[€“€ÃõÞ‰óWåÛÐN¢eP²JØèL’õS|&P¹Ee ˆ<(niÞ ´1%ÄëÓÔJÈH?¨Êe èq»€Òðwë®ø:¸ëÓÚŠ1z|tçdå¨]ÅúžZTÏ¢´%Í3’4§=ÀŽ›_‡ñL:qÈ¥R慎ëþ y~Ú­£ãI+ãÿÆã]Ê(f @Õ^JY” ífrà:Pǃú$‘î5ß8>l ?7}dG£$´²>cfŽErš¶î1¦çHÈiù~dŒ…n¬T¡]ÅotÕ9¡=Ò9\*1‰F*‡O_w’?ñcLˆß>Ô 7ÖXcƒ6õ]°›`æ£x¿¼@ H¼BJÀÌr“à­@ô}p©IbBRäÊX„ða¼<ªñùá A:¨•ë^Ì/{=AÌÈâØžyª¼€y öZt}™¼Æ ¤tx'ÐÚ€¥,­v€†îT”°òÜ5ø™c+¿Éa0Ì»°éÍøîYH$méh²à%)`.lHyZÌÃVÒ–m§´/SÝ'÷)ho€±ãaüØßú#x=9ovÓlÀ!RO’´˜ÈgsŒÉ9&ä ‰ÊÓsHéhÓ C&><FhaÚÙ@1ùÝ…z-(®È'•#±9¾àžª 4Ü¥.öðJñÛ¯·Þ½±Æƒ¹[ÁÎÀ]ï†ìF`6º±EÕ0Ð]—0ãÎ#û.Dç"¸:DÚm Bxœ•ax¡ÆŠ»´”CsÂG¾¾”J}èÜ —îýzšڼwïE¤Wì‡öB©+mÑÝõ®3ƒPµ!ØkaëÁã/€ô*ž½ñk°éó_‹D”sèËëvñÞZ°¡½Š Àò~i_ÎÃÜWAœ‡|–¿ôþ=÷þ˜<6ž2?ÖaÅÛ`Ù«¡õhf°|ŠÍüœ>sX&„Ä¥’ŽèÒ¦Ç8³´dŸ 9ƒÖ†Žî"¼'%D¶ãæJÙR©ÿÚ =Ž¡j]KCbrlKÊpZÒÓmNó=Ž¥Í8ªzc5ö[²›O; k>^ôÅX´d0’|Hå”*؆|è2sçÃgÔ¢¦r± Ýï2@^J²”®Ü'¥ YÜjÉ^Êï–jÜÇJ¦Ñy?b ½Êö¯¢øBÍ:+q^âL ì®á‰P*x´2È®«:uo€»¶¿ž~Œ=æþm§{¿×½ ˜ÐW@ª6@†”§’rN½Ônt¬A öͰéðÔ3`¿Ý?ç>{\õZ˜ýUõŒÕí•ÐþöégðÑÅ)—0C²XV¹:téˆ.©È—³HíèèP‘/%+ÝìVª0¬ó°}w ^¨r'Â=,>§*ç‚¶î‘©/Ñeµpü‚1þ€} 7ÖXc’mYÙ\ù~讃îÝ•+8 Ãq'@6ªê<ÐÄ[ÆÖ]mŒ¼ž;½PÙ*&r‘õÄ.)=ÔS´ÖÇÅGô'ö F±LéZtR  ÷•›Ý;·Ø“¥[^Ê Ä•²ˆÔL©XÜÕ°ùUðgÁ¢û ê«¿W½7[RµÕpÛÁo6œŸ¤êx”!µ«›¸)8ïõð¼ÿ„C~ƒùëù,\ö~¸çû­Ÿóšsäáœ6v÷’²¤æM©ÇM´éÑ=R™ÑQ]„ð´’>I*2Œ 83Jc”Æ U´í ÌËÛÝíEžé©Ê‰ÇKA®P`Qx_ãþ€4@o¬±Æ`»êK°á:¸ýL˜[_A,ð’]h*Øð×\º 7?gz]… éMeá&÷á+"Å%¬EPÜuf÷1Ä ûú%Œ¸–¢hG(³ [ˆ«2×AÍ/«>Ç< lül-¼éÇ0þºßo<~ü—à{£ÛK,t-¾™¬å©—C7gÐ=àwÀ÷ÿ^ýxìïÿzç~á‡àº ˆž³MK÷åœc^ÆO|1™œe1½ÐŒç&…+;&‚:OEFª3„ó¤> .vi1Zãä*Aj70‡¼¼/»9~! ®¸¯ÚšV6 甩´Ì_à2;l‘îÝ¢O | '-qƒ t#ÀèõWÃÆßýVþš/øŸ}ÎøsÙhï‰XˆG~þpImÿÈó©Ô·À¿¼>}L¬ÜeÞ…ïü¿põ¿ÏWåq;k¥Üvä|÷•o`ó²•L0†>âG¡¦¥ Ñùmz$"'‘9‰ÊñR 1X¡Úa”pOB4¿•ªt¹J{Oz½#ä9-Õ'Is›“©””¬<¾Gp ×óTögœ±è…eY†Q‡ÞXc#Ìpæ¦á”“ÂKsÝ*ØpS9îEýÅήI¸Ô‡¾/EÌÆU¸Ê X×à]I5`»ÑÅ.à]t öêu ûݹn?v tïAÚøw?è®¶½ézøÌkácÃÄLió~q:|ù¯ñ6ô0ñ #¼(uû%Û©ŸëBJ½¼¾>œù98þ w£¸³ðÍÀ¹_Ák½ñü­V\p‹¹ôØçà,ñ“X§0FWžgÄD>O[„Ä>‰ÈQÊ–É ðæ: × tK·Cc ¥õ<–Âw»ÌB®xÕ'!½-zaz!YÒ¹…û8ŠÇqxôÂ>ò‘°yóæyûo¸á†æåÝXcÛ·ÀÅg…í³¿ «//Ýè>.ÅvÓ" Z¸]€mæ5 [zœ/}!`K AWœîøê¼ˆë¹_æb`>ê ^ìâûµs*þ¹ŒñdÒ†mmjp¯ƒÝÕqßuð®çÁg~=v÷ÚöG§âO~.¯@»@/ܲh‹j͈ŽS½£"\õpa»XRîþ‹ŸFܹ>üåÚ¸Æ¨Ž¥…O¼á×qiømY»—S,æîçÌOþŸßÇ!YÆö Ø„9óÆèéÂü€ÄçÁC" E)ªÂ9Å8{Q<%WIp·‹0ãÂöÕ@Î1²G8ì¡JÊC¦PÊÒJB%7å- 9FêxˆÇzEn´6\"Oåq|¼zaŸùÌgFî?ù䓹ꪫš—yc,[¿® ÙþçOÀ·5~ÓÕáÅ-‰` /t§ª—zù^÷ âË7Zá ÀNÄã©AX”‹¨:%H ˆAhú!>ÿ%Z­½ŸÃ@šrîH7Oý/pn¢T v~†×•;>ÞOʆ¥„{¼¿ÅØpþ¯AžöSXºl§ÊÜŸñMü§ÞCß‚,ÚÏ0àiq ¬ÛÆÆýE[øá¶õƒ÷º„zí:¤«®GÔ`îxòë_…d?Ä{ÿZí‘§oþåcÈo~l¬»ç¡¿²Åmo<‚»_t0[݇%Lb\Èïoó*Žs²ŒÆW6@;%+ÇÐ[¢_ë„lÁ²Œd7R5o"ó!Ýpì(ì² ß=»ú”?¥C‚V+@½ˆª/Ži½¢oZhah ÇíâçÅ Ðkì‘næ?þ¿qc|™û;0y˜Â­j UÕK½€9„m9íÀ¹¢zYØbð˜V‡¿Û!XºÎ ˆPuæ©âº [Œ`Cnßòo#Üßb¨À(È/tj°†x9¶?öQ½â·•‰.y چϭ^XÇäwx¹®Y…|ù‹hýçˆCÙîÙ÷¿‹y×[1)¸RŽëmh“<“@žÔÚ] ¶»_ÈÛâ½ÒU÷XÚð¼hÎ=ÉAçá;VÆŠóŸÆlÞÁÄ?ýë|q~ÇmôÎ<¦Áô¡…NÃöç-ãšSŸF>ž÷º›$Ï“P¨Çu^æ@( ‡)-ß/ž’… 5]ÜBá„ÄMß¶sÙsȾ+•=íïn½€¹§ ÞTÊÒ2}ÒDœ 0r³²6ä>xµm>_ ª¡?Êñ2”N >ìR*õèa(€®£bÇKèá‹Ì¨KÞ~"#Äu»äwÜÁ¶ã_‡[s ʃÒŽHÙüé™}Ú"&ÆgpN’å)ý~ m Iž—Yíê­È™£„¥E¿ fÓ"TQÇLpMn²,…БyDÏTò —/öèEb¢zYÝ–í“d9ße|Ñ,‰ÈC=Û¦gÛhi}‡i_FWþŠôAžÆÖ½±Æ »ë“ŸÄLN }ÚÉI¶}ùËÁæõE‰+1œ×¥péFר¤ÈV •¦¨$•Ðß²ÛpG—Î"€Æ¹ÃDTb%ÄÄ`F½ƒ1‹Q®»y‹$e®úN-–)B"„X#‚»Â²È­ÇsëC ¥[Ã{|qb1˜ÍÇl3Þ{¼wÕÚyœ·8çpÞWž 1¿CS~ñÛ2 û–îwé…íäò²Ù0¿ú›^ýj’¼ ³÷݇™™A*Å5ñˆ,CiÒ©52IPZã¶oÇe3kÖ”ƒ½Ã³ŽŠm©R)”Rˆ¸H¥R†ý­z|Œ¤3†j·IÆ×zl Õé [-z7²ñÌ3éÏ ËùÞW\1ûÊ b`ܽ¬E )¤DFÈJ!AÆ5)"BV Î=IÂu$Iø\Ü­J‡ã)…©4ÄëJ°K ÅgŸ ç#dù{Y€?‚;4`Lzã"Ä]pÖ‚÷8kqÆàãÚ9‡Ë³°Ès\ža{}lÖÇ:‹ó.|ÏYœµXkÀÅ6vUG¬>+lì1$aæöÛé¯^MÏ9„,Ÿ˜ uèa,9ôú6²eõêŠ+.<:®_çK!J¡bçG ‰,ÚHȪs$[Ýûjíñ¸Úýðñ~xgKõ.ÜÐ5øªcbW¯föûßGîØAç™Kè³ÙBŒ Übpv’~¿E¯ß†>2¶L@dr]VéSÚ–nmí ZR—‘ø<ÂE—»ó’¼ŸÐïµ°]EÒÏq= ÐÉTfÑyPòÎÈyÅzÄîFRú*)R—Ú %-Û¥EŸ–é³dé$R8fÍ8½¼´Ž,K÷³´Õ¯ÈÔ—HõŸ5@o¬±½ÆMn-fno-Û®»Ží7Ü€ívIÆÆ8äOÿ”tÑ"’‰ ’‰ ôÄz|Õj1yóÍÜyúédý~¥ [-T’”jZ¦)*MÑÉØºÕB!Ó4À:MQNøwí6*MI‚jµÂºÝ.?£5¦ÛeÝé§³1¼ãº”e‡C¦ R'H­j°MZ!eªJt€E’„NJš†m­Ã¹+…LSDü\Z­ãqˆ¯ï/À,„¥Âw ˆû x—=ŒªƒQL£œ†W¾Á£-#œâÊCÎPY[ÁÞ˜·<Ç{Öñ³Í2lžc{=\ž“ÏÍaû}òn—lf&l÷z¸,#Ÿ›#ïõÈggqÞ³èðÃ9øï¤µbs÷ÝG>=Ísdš²øCh-[F>5ÅêÏží€P Ý鎡Ú-’N'´’¢ãs´Û¡]b[ˆØ6õ{‡”áÚãR\§³6\Sžcû}lžcâ9Û^Óïcû}²¹9L·®Ë˜î‹=”Å¿÷{<ú3~äzÄ @ôÒ“Ï%ôû-dÏ¡3ƒÏD²eBĺs2Ôž÷„’§Â“$9Z•“úŒÔg´|oÅÈUÏ¢z!§¾ëI„ñÐ'TúË-:º1œ¬ †¥v/yAùýèr/€.„§åû¡Ã‘å!k]§‹¶†–é‡J×Òñ]ÆÒ)ð_Ã/~=B.k€ÞXc{ƒ©N‡E SŽq¿þõóß#¦óˆE‹xò“ž^²…2ÕºTßBÊ nñs ³Bî®Åïºõëi}4Gzhø=! ¿8‡xlYƒ,ñ;…gàç*g‡)Ãß„R¥R®Üâ"ºIƒR?H&<Ö „KÕXLÿ‘£A\WÚµíy÷µ¦ÆþÞ.{e¾æn®7ö…²°/ÿÕ¼·¶ì8k+èv³û IDATG@jßt»¸<'›™AHÉ’£ŽbùÑG/xz¶×cëÕWsлÞÅ!­p™¦èV+tŠÚí²3&b›Ïµ{>pÿj›y÷¡èÀ ufœµØ,ï1½^èÄĵ³ÓBççràs¯¤µôŸbD°½p†È –Cõ-‰É!emHãdÈ®æJ‡ pÚ™PÉLä$"'UÚ´7øž Ë‚»^ö¢r‹î|.ð}²ÑÅŒÑä‚ùµî©¹MÄ®—jÊZQ¥.ÍB™¶é‘ö3’nNârTÛ²XNÑ1]zsmÔœeÜÍÒ–=„½¸–¾¶zcíu&»‹‘¢ð`Z{ß}9ôMo:åA°ÖǑŗÜ߈ ±î³â*™1EÀêEX$Ú˜çºöGq Ç~(þ'!³XI‚xä='EÇ jQ;¯Â%[-Vs +Ž9¦‚r­½Äžv`î§kÀ{|>í·¼|†è^üî;FO÷ºtÁý-œ5Úk‘ì¥êաμö˜ç-"wƒ3ryv“=‡2A¡cÃø¹óÁíîœDå¶û ô"ê}gYö†zô$Ïñ^ÐvèºgPXD®EKƒ˜óˆ9O‡n^ðàg?‹_ ò¯5ß½±ÆNý8¿Ía9—x±ƒ«˜Á UûÐx–xÑ ½>(®©}ÿ¿¸‰ãXÊËYÁ1óŽøèøí€K¯ÌÞdw}òmˆ›ÿüôü>#;¾Ê÷·Â†<ÿ"8‰p,겫ĢŒEôì}mÖY(Ó+³ÐIðF 3ÊóöC™S™xZ«ÊN¾öÜF ×!¿ë|Á5 K‡N ÎIZy­ I;Gç¡”®Ðá{ºÈž#ígeGØŸÃÄ©pȉ Ðk¬±ßÌ62C†çŸ¹>‚Û˜)ÿ¶t!•²à»nÏTâLr÷ržÂ2^ÆAìËxÓ({£Í¬Ò®þ$ì¸&¯ßÝy¾0”Ö…úáÖ„’³.B/Nÿ’Ú†ªzq©'¨«äy_u„õˆ¾®|kIò<¸÷3ªý9+ÃÜñ@†õ‚Aq£€®B†:g%i–…©u­“\Ç0çûÜãoÆZ¶Š /ª¢+1Gkáþ,ƒ{\P*¼jvËå¾3U¾Û@÷ЭWe‡Ã9^ζ¨_r±ü%Ï•'p(ÏC š¯›µeÆ;Ößÿþª¬ÙÆûàÚ_”…z|½`O½ò^­t½¬•zuBbu¸çŸúÃqË~Gzǯö} ·-;¢TÆÂûy+¬G›Ž=­¬‚¶8Ÿäùë.Ä Á[®ý2ǬýÊZ”sU9Z‹Åsñv¨" £ò& Íeþ`Z Ú b¼…K™Ýº©.÷žö²%èÎÞº±ðÑ‚0§VŒ¨Hì!1m-*mdøF-Ó¢›Ä&+á~H¬úà·l#ÿΗHÞðÎd¢ÞûŸcË©§ž ÀÕW_Ýü‡ÝØ#Îú¬gײ…U¬u—`ŒÆXÍ„­ÊNúPO²œ+UPáR† IWx4f$ˆ‚÷ÎöïJéã뎠ÌÕÁýéļqO!<7&ÿÌZõEž!>Á8G<$Úgšë™ã^|ínTw-¬—p4m½{·™ú§Ÿ>˜ƒÿË_B\~y¹C^UÇ‹p÷C¹…ËêpE,œþÂ×3ÛçºÃŽæ”—žÊ–::1ÀmÌϨÆ9ÚÂNïEuÅ^²±ç/}NJÎ9ê5X¥8ñ§ŸçUWžÆÓo¹¢t««¨Ê‹_{®‰Ò…ÐZ tZ0Ö‚N ã°½¨ƒ–wm*ïƒõ؃ÑûíÇÜÚ{Ø1³û@/rùKŠÖÈX¼¦å$ã%0=½ olîOÀ¦áßäI8ž± ,ŒÍ€Ê Sþ.ú;¤Ïzî#èB>ø`–-[Ö¼Ý{äˆ2¶°3Øì/bÊ®%7 í\‡Ò6”¬»° €{Ê®TÈÆ%… ‘ÂÞ-¨ÐG{W ]àw sÂâb}¬me™šÓ9‰pÚt²;ôßð8õZ<Ag/l›mìàÇìð?cÆßK×m/¯±˜ó,¨Æ`'äÁtÄböo£ÃáøÍ–©ÿü.³gŸ=T.Ñëa.½´Ü7‹¿Ž¬ò¼{WU—ß*Œ£̶:L-^ŠôpòIå¾ýæŠßy¹NÎ1îgô2ç.À¼PäW /Pý¥HØR½XœŒ¥N¥äÔ—¼‹syÏX}÷¯ïgß­[Æ"☸ð’4,íZ ¢@; Àk…íñ¤ Œ¥qÝo3w÷LÏU1péøË8¿r%³k·05ÇÎÓ¾ÂÀð„±æ½}‹ –îÿ(Æ=6MÂä,l™ÄOÍâfçpÚ“KªìÅ/øP9 Û>ñIö=í 䨨# èRJŽ=öX®ºêªæ-ߨ#@‘Ã6¶Ú/Ò3=\–’æ)ÚL®ƒë:úóJ˜Ç ©jŠ\8”°¥:W>$úPÞ–.ùÝ…ù°{}¡¨öQÛ…:·NaœÆ9‰5*@ÝK¬UHtnÐÚ ô$÷v^Á2ý|–‹S¤{EÛxæèò5¶ÚoеÛ1™F:E«æy(ÝÁq-¥ÃËÕdÚ°^_Bª3ì·¶1÷.Ý+̼ø³á jÃ-#cî{¥52)rð‡â@nvŽ|rràûës(?yùk¹ù Oá¿^öz´5(cCS—Ór¡¢™r6¨ò¨ÎK;Ì[è½U>‰" ±x¡.$NJŒÒLí¿Œs|5g¿üu¼û[_หÆS×ßꤡr HÄX x×­’$l+×:mP—H¦×¬gG•jÅûî ?‘¼ÓfÇÜ•lŸe·:¢òò•ô¼€–HYôØ'‚í³Ðíæ0Û…mÛð““ØÛÉ{sd½.†0Ö>—Å } æÂ‹Ÿþ4ËO:i ”îÃè5öˆ0w=ži2ÞKÏÜC?sÈ,%É0!7vBdH Q¸× Xªpj4+eÐExY+iј²zU=sV‘–O©úKb^ùɲ•ˆQÀ¢šâSŒ¯¿ã}p¹§Э$7 ÎÊÒÛ „ÇM¢ÃÜe­ mÛÃ&gÓoIÚú³ –Üÿ€6†m×]Ç5ú®‚„ªr!缌9ÒÓE“¬xQÆ'Jfz÷ òÐ6Ò:¬Shk˜c¾R†%CYP¥,­VŸäÏRöy­å–,³·w°s!¾Tª*â“ÆB,í6ªÕ …|Z-t»]æy—±hLS|ž³ö?`ûÜëŽ<’9„S?øQ²v‡M>Ää,¶S¡SG|6ÜÈ©€^ªñZ‚–…ÜíõNžÁCáDÌ©^ºUA©ç:!× _=ñœyüó~—ÇwçX ˆ$­¼U±Žnv­äµ-ö”ÐJA@6=ÉÔ,LE  )˜xÔápБt''™œ%(ô…ž‡:ÐãuJW©s/aÑ~ûÂކ'> z9ô2Ø1ƒÈsÄŽ¤½^¨´¸cLMa·n%›šbjûvlž“gH׬aâî» 7ÖØÃǯ~3ô¾Š7ÿ„% ˆŠ~ ™¥¨Ü†9¸Ö‡ù¶.NûŠÓtŠjURE®lºråK[ ƒæÊÇ4œÞ—°. êjãñÒ¹ª†÷Ðý|)YÂ\T)2‹¬Z:1(i«K ÝEn¬Q£±.ü¾5*D;ÐÚfYø<ö |kB¿Ú¯¿¿]€´÷ÛÇŸt>Ï‹ UèúŸbì°µ¨¥[É·%ÈnmL(:âmÕBT„1BZÉб’Ê‘¤9ZÚc–gœ Ó7,aÇ B&²²]¹DË$¨ðâ¼ÊÊjIRb{=Öw—?ë™\ðüçrÑ;N <ÏÑÆ°ÄL¢•)Ÿ‹Â{S€®e”2ðÆø*ndNt_Ká^Ar^Œ¦\'X­ÈtÊÌŠ”—½ûD^ºu+ßZ».ä½W2À\Êq! ‰k¥@Ƶ Š‚?s«V19S³Ñݾt øxxÌ‘L]u5“³ÁCÎÎz- Zi›´3F6;ƒµ†ñÃŽ„' O~jˆèË ¢Ÿ1èX•‘©)Ò,#›™¡==™›£»m¦×cÇš5¡ߣE&åýš7±zc=¨J¼ 3—YÛþdü¶0µÆù°ô}(iBiIål¥¤‹â5÷ºR¶Êí¸•ÁMÆUîõZmhç$Âú2I‡°á· ˜ã§õ¢Ã@/ÔˆZð]ì\’mUýM CJð;Z”¹‰1ÆèP#»˜ã«b'DZt× ÔÁ_ËwÀòwÞoÍ!¤dü ƒ?è ùœ¹ ¦¾sçã Øª¬"&¼/çGIsÊcÖŠ¡9Ì‹Ž’UGG·CJÔÅû­gbùGKÞ+þz~µ´zA ¡êsS8V‘q­Ë8å W3÷öWÒë°Ün ¥HEҔʉCÒ±J[½€wÑænu?ä•©Ÿï*Xr@©G¼S²»’L¥ä*!“)—0λýN¤ÍÓiÍŒ„•¼Îåm,}ÎóXüôcЗ/cÿ¾Ö¡‡aWÝÊÒç<Ÿ‰£Ÿ±ðžÎâe…“„ÖÄ"pºÓ¡»mùÌ +žó–>ëY011 ë…÷$ñsR¶1¦ZUî(Ê+…lµî××KôÆ{°lûŰþ °ýô¡H§âmà*³è¶6QÙzUÅOײW• W¡j•0¾L¨1ü2˜ò³má)A^,å¼ßZ2ŽQ.÷âX2N*. -dõ2g1µªæŠÖ4†Ôg8/ØM ˜32ÏÇëì*¶þ¶V¾þm«-gÁío¦J_kq¯TãlL8âeuÏ#ËtJ2•AŠÊ!Ójšô[`û‡A< öënâLó=&¹˜n¸ÏãÐÂÓ±ýà•Á’ˆ!=Z¤@G†ó)\ì;'Ž£ˆ»ØÅ´+/‚‹¾®Ø½ Ï“Ñ/‚R7R“É”¾èó%¹ÁgÙ——°h{g°ìè§²Ï3ž‰ÐmEÙ`¼çQ/zzÑ‹v1ãKÏ"xhZ-„R¡¼¬1èÝd+=ö÷3° 7ÖØoËz›`ý%°ãJXó¿Ã`\Œ>ñ$|† ß)æ;/Kwv˜BºA­â‡ËN€^Ìïµ¾üÝy ¯yF²‹Ðã|÷RÇ<Øe·}^Bø>Þ‹*ú݇8%m8Nys°îMð”)8ì÷›MÝëÿ V¿7ôzê¹Æ£{º(:RÄ/­"ÁIŠ%<¨î—r¡ G1”áo`ß‚ú üó`Ù`’ ô¸‰i.c’ÿb+Ã$ÎÄ€H‚×Ò„©Šq]Îp¾šŠVw§Çc8d¹ž§ÈÅ|ØÏ{4¢k¾zY$%ÂÝÆŠ€¹J°R‘‹„L¤å1?ÆVræì·GÍ—.4JZ˳”«"M‘iºW¿r 7ÖØýeÞC6Ó÷Â/>f+lºt0U¦gt³¯^„ÊÛr“Ebâ4¨’¯~p¬o„ïsó¤JÜaƒ«ÕG—¿óÕ¸y=`n!RØÉÚ4­B­G çÌBQ‡‘EúN쬬† ꃛÎÂÅ ù<î÷_‚ŽîøÑq0uÃ`›‰ vÒ¹PtDV×&âÜ0Qï÷øùí✈iOEÙ*¿[&wà×…óxÅÉ–†Áqwóßläv¦X44› ®žë3”° ÃôEáìËß/:*¢'ïu]UðPä;q¹At¥úó;›V¯S®’ Ôe‚zÀðL²˜'ò?8 I ܽ±ÆDÿâȧá'T¤ |ÌÊqiBR¦ë¬óÏÕãj)4‚Åî]”¹G”ê¼PÊÈ^Ú#Š[”CEíb,]º²œä¼¤o ɼVÀ> ¼²pÇ|ëxxþ]ð;ûù›µá–ÛáÛÇÁ–˜^k+Að&ø¨Ä½¨ò”/Ô™òC+;/úÊ ^ã]ÎYsÓ§¹â9Çs#›ÊîX`Š`ÝŠÔ¾JزŒ¨ŠS§„ŠVð®«èäå|òÌK¨zí õ_Ÿøjü=£t»H°¨Î‰Àóe6’ðlžÍc›÷LôÆ{lf;ÌlƒŸŸ 7]ÒHÝ}ùèIÄ ¼®þ|ñ‚¬C¢V^RÄ>ƒˆŸeQ™ªy.Üžt@ªèeá|™­­˜ÆV_Šižª†¤2¥«¹æ‚.SsŠÝzq;6x¸x‡†:pÚßÂ’¯Âû Ëé?Y¶­ƒ}l¾iP™ËúÚ‡Šab(Ûˆë;ëL €—²Ò˜p0½xy’pîËþ[Žx<Û—.nf9{–s_âªEæÀZþ~‡Û¶ˆsÈ‹îe j«à¹ê`”ibk*½z9.ºü”%ÐGexÎäB4=žÁï4ïžè5v?XÞ‡o~&¨Íÿn¼x(½×¯ï«ežª*SUµ¡Ë¼Û ¼Pàõr“øZE*¿$÷ÈøUÄÅÖõ€®rZÒ.à4ð–UôûptýH S]s,îj_O]jcþoWºÖß| |ø 8èq{Ö®ÿö7pÞÿ oÂ!ˆû"¥ªbP×+†QyI±½Ð%סÞù»G°ùàý¹þYOfóþ+Ë{¹‚-»Ñ7›×z\Cëb6B9½®®ÀEõ¹h÷"]o‘ùn^ R?èµd:e€d1­1Ö¨ç„/½RÞc…xžê‹Gp§ó4ž€œW¨½±è5¶3ëÎÁÍqõ{_Æ_ûß ~ýš¬¢bÔ®@.jð–!ï¶UÑ /£×¼¦Æë/{QWp¾ _ÕŒöuåº;&Èöå«ôy°]` }”j¬×\ßU6®y YÕ“.ï x °Eîo–¢:¸oþÝ/GüÛpà!»ÕÆþsÂýðßB^ó¢3ÛÉ&äVÕR€R‹ª&êÛ~>¼<ÀŽÇ.ö.{×óÙ~À>ô[­¥í¶—÷°`[â£>—²8,P¨ëªã$°¨ Ú1A m+ªb:.@O ógaOKð2®BU%H…òaN~L~T(õÂ__êϘ÷‚‹øÏ¯'eD”ùävXs<õ™ ÐkìoW^ßùOPশâÎþvØŽUŒ.n²Fº•ªóQÙÙb;*@[Séu735åsÜå.ê0wC`߃Ëïȧ]ÐÏßÞ n£¾RV«y-¬ªÔº‹õ"Ý‚6 ciJ¸Í·Ã[^…úúYˆÇìêþ>BöÏ!eLéÛ(k…užTíUÏ^–ô¬·ƒÛÞÏ÷>ž‡µo:œéC–°öØÃè. `j»ÛWTaƵw¦Êr~»Ib¼»(ˆc]•O¿ØWÖw5 )óáÙ#Óÿå'È (ª¼EޭÜüa˜×³BÈ^¸ ¹Znç9⯪s¸ûNÜ)ÿ?òÞ;á¢ÿ‚ÏŸŠxÝ› 7ÖØÃÝÌ]waV­*9lN=.¸!A˜ ÓŸÃé\â JÕ \H‘} ÚµÅKTá¥ûX89Ÿ“uõ]V„tU‰Ká?»øÙûšB-NVÖ—èN(> 2k%*dßR*¤ÏÔQfÜÕZÔ—„÷Å´+Öƒ‹'ç|HXÛPj*7qmkßµá†÷ÜÆÅI0:*óú°„ @‡ò4‹€ÏcÇfã ä/~1éÙ?F=n¾ûÝ÷ûÌþÍ{q_ûNC'ƒL@w,@<3äªRãª6Î]´êhÉÐëÖ{ÂýÇ´Y÷–ƒÙqô>äí#4-Ÿ‘öóÒ ^&”r°ˆÎ( ×¡>°]¤ìõØÆ†Ä=>Öð®}!˜Ï›º8 æ~~–¸z‰Ó¨Ë*?B¡Ö¥®ò'èÄ$y ÷Ò5_¸Ük)ˆ§9[å'’ßv+3ô2Zkî(°ïx;ù‡>Ìø™ç Ÿð„è5öP4o̼}÷ýå_âvì(‡GÍm·a~ùË2ÏIˆ^¨@"«”ò@Ýh_Ú%¼#›|d“7ƒeË®¦Ä w­¨Ÿôóá ]ü&¼HB*P1Y†Rˆ$®¥B$1Ïušh'º¶®å¾V1f‘VSEЋa ³0ÌKiè«éV¬‹unÂMÉm|?ûú²<¬çzø~y²iå>ϱ6p÷¡³$ªN’pÑcbbIPidÈ‹¹õvÜk_Ë~çž‹Þo¿ªSâ=[?ñqf¾ðÒ„Oîƒ*ϲ0Îæä2v¢¨:r²Ö‘òq š,gŸ „JžÍ½j3¯^ÂÌ“3{È"œ•$Îä{uÈñaZ‚_Ý»œû£”ùÀËÒÖÓø™ø¤ 5†^¼˜û”…eŠý¸‹q÷"æbWÞœÒåNmj_-»!€Òv@¥ëĤ9iš‘¦Ù€j/ ûS+ç8Ÿ5Ÿþ9úÌ_¢n¾ƒ<¶ôàzùô]LwûŸs顇6@o¬±½Í\–±ö[ßžÌZn>ñD$!fmT.“ú¶Š0Š|ÙJkòÉIl¯7_=3z˜ÜØÈ3W¹Ë/ðöƒ*\H‰R)%R*¤¨¸–J!´FÔ q¨˜ÌBÆÜÝÅZ åöª;Â:Õ ã¾ÞJ‚\Eõ® /+ðÉš*ba÷»¯«ôB¡Ç¾R}{0&¬3Àž™J¹w³°Ýë!Á÷zø,Cõz¸¹9\·‹ŸÅÎÍaò>&7˜<Ã/ÆY]€y=>_µŠ5ˆ]¹’ÇG{åJ¶Ÿz*~íZt|>dl\cÁ÷;rJ%h ”F¨‘(ÄØX(†Òj ä[J!öëc¿ÞÓ³/1äY ãÓ³ƒùÞ½LÄ#<Ú›*£®Ì»^w¹×«Ö9'Ët¹Æh”±%È«ŠÞhkJh{Áè¸wQå»Jå—J}8©gþtÌ…†sÄàŒ‡B­—@®{ô$Éi·{´Ú}Z­>JÚPÀT£Á­†7ngËÇ×Õ“–§ç<˜›oæ¾ç?Ÿ?ûYõ²—¡-zD¼'÷J oÞ¼kç„LOO7d{XoófÖ_pÿû¿Á{ÚË–¡;&¯¹•¦dÛ¶±åŠ+À˜P KD§Ö±:VÒn£;’ñqôØXXÚmt»ö“Œ£Z-òéiîüþ÷ézqÌÚäz€žˆêUHÔ *IBµ¬¸È$aÛ’¥áå¯_8þ­ÜsÀA(Q@%œoqÞQº¿½Rx¥øÝ-›8iÕ¯R‘(ÅJçBJK)ƒR—Ñe®d¹–ƒE-tìæ¨!Ø º— ÍÍb¾Û½t¿G C5.á|t]ø Ô½«\ï¹)U¼È²ÿËÞ™ÇKV”wÿ[uÎéî{ïÜY™…a_e€ (â¾ "Àø*E n‰%£Æ¼&"諯‰(®Š,"(DÅMY†}˜}æÎr÷îsªêý£NÕ©súôñ:]ŸOO÷íÛÓ·ûôéúÕóÔóü¾ 5¢Ý¶Nyí6¢Ó!êtˆ&'I:Ò±1ÔÔíÑQÄø8éä$íÑ­¤ãt&&0Æ ´ÆhÒÈN‡µ?û2Š˜~ì1q ”ÒziK‰ˆ#Z³g“ ј=›¸Ù¢1"”*¢q-|á[HÒ ‘gzø¶kBï;œ°;˜O^MèÞwÛ¹(Q>íž´S’©”æ`›ÖÀ´]³ç‹˜Ît£³L3ýŽˆßEch6ٳ錎2þøã¶Àn`€tt”Íù­[Ùíä“i,XÐôÿ‰ñå/™M›6uÝóÍ7÷ÕnQ«ÅNGÍâç?Ÿ¨Õ"Ì'шÍwÞÉÚë¯gø˜c¬@ X±°¨É<‚rHIDâBÊ‚ZLj(¢36Æ£—\B{Ÿ}Ð;ïl“ƒ<¾2¿Žóˆ9Ê'õs)£È?wÔhpËNóX6o62ŠøôK_‚"à*µñ0ŒÐõŠ¬ïµŽ$¿•{qîKžƒ–’9Jó÷+W±XH^—å‹È#lw-‹}sq²"ÖA˜Z~<¹} .4N1ºpx3ä¯}š^äѼžd` Qšb´öþÙ&ËPSS˜,#œDgÙÄÙÔ”%YmÙB:>Îäúõ´·nejËHS´1´µFAôÌg% ­¹siΙÃà¢E4†‡iÌšeyî\K¢VËŸ"ÿl‘µÑˆÆä.—yzÑiD$ij9ªãRz݉™´PH[¤j,s*žÊ}âs£Ÿ´“¥1d :v/<ÊTIÈEfi|JEDZ)v¤×Uåç{Ñ¥ýñŠ{Qåo—{~žŠn®náSPÔE!ò2ÊQ­±ö‘zgÄqF³Ù&ndÄÓq+³)øX‘ub¦'[VÐgM2ç_$;½è@ïÎøãóÐw¾Ã–M›H††˜{àìýú×3ë€0Z[*Ý0„1Æü±¼Ø³Î:‹3Ï<“³Ï>›3Î8£¯|;àPív^f£Z—&!™Jˆí%Õn3¹jºÓñâè°™"Šüs9:’û;Õ¿=Šf­P\'Ú|O´Y×h0҈ݗ̒ϴ¶¶£ZénR ¥,.9SÚÁ€} DÌ»bš•}Þ¿ø2Ò¬m—3Û¼m\ôïüѵ.®ÁcokVÊ.”*ÿ?— ÉläºÎ—!)}¾éP#°ù‹0}#B(à~/ÒÆ9+y …Ü¥œ»èxyQ˜cÈ‹J¿›ÖÒ¦îsÜl–Ù7•Ù¿ãÒëYÛT¼*þ¶ÑÂ#p²  Qñ’ »×ì"õ:‚™’7Aû£³”­×xN|d3qœÙÔ{”ÑhZ˜¢Ñìø}u€NÛFè¤c·â× –~ƒ5×_ÏÔúõ4fÍb`É—.¥1w.ÉܹŢ·Ÿrïþø‹ÞŸbzQÔl2¼÷ÞOúÿ?B›+ØÌtø!h¹ÍÒMðè§íí­×Âä­õ…NÀÒz¢¬K›ÂjÛV«5+MmÛ_yµ ¤9/³‹A%ä­Ãà#|VÀ»k ã üþ¸(‹x5t ÅõŒLUø«‚^Ùsw¦7NÐýžz¤h4:VÜ2Á74"±Ç²iÚ¾ 2¾±p»¾ò•ýɱ/èýÑO|¬cеLs5ø›ÙšsNC‹Îj®3Ñp.^®ê·¶';tçâå­8{à%Œp-+xó9%Àìþµ½cË}0µÔüötÛªÐYWV€:ÂX¶¸-€ÔÌ%lÕ¦l´cº£Úúô‰«mZ]m#m]ºAØ¿oðѸ¿Î‹èBx¿¥Si; ½©WZÑfŒÐ{‚DåÊð!ƒÏ^Ä2#JlÖ"nåml ]€~\å»y»æ*XóJxõc ïð§r_Ðû£?žÀ¸”ø%ky0§^ `.õ†*Æ74ŸRuÕÍ!£Nй˗ ™×µ …ûläVáXñ—Ì0þ‡V7ÆV¯?–¯Ð~ £ôŽ<{üìdÒh_½]´Wžî‰ÐðÂ]勆ÌnÓeÏ ©µß—ÊmAä @]ˆ¶ßw³É«1+s˜¯=·j2b;Cßví˜|ï\ëR¸Ð¹ï¹ ¶v‚tºÅºŠòyPAôz¬mi‡­e%[à.17EÙà ‚^€^ìó¸ÑyŒ‹âµ(ax]:^Ħvä“5°æ·pØOà¹oî zôGرžÕ¬áQîå>–ó0;…5õ^Ú33ÊHñšÿSù}/?ôžÑS³¨þ^`XËF¾ËœÊ_²ÛŸWú®àÁÛíí‡~ מ¿}Û\¤«"úëQ¡áÏ[ò߯XöæÀ¹ ’ðÄ Ñ¹¨Ð]K£Ãú¢¶pQh®Šr•à`Ã^b Pôø—‡ ·Ñòœ}e+c®ÓVO—£zÏS¯:ÇT"tu ä_߆ùäîˆÃ_ØôþèyŒ³žÛ¸†ÇÌ}ŒšÍÌ—Ý‘o¯}¦È=$T!|å±0^Õh¾ E)Êñub^ÔÃßà§œÇböà…¼…CøʪÇmä LïÔ"»ûטK¿n~ß³_°Ìjºäv¾u ´f‘Œ§47·ëÅ;.Üq­C¤m~Y5g7R™XG:Sˆ´ l{½Vê*¤E 4,˜aîÔÖ'.è~q Ë‹H'ÖÞ’·ˆ´ýâC‚¦”Q0¢¶´p 2Žvgê^âS èer ÉÞØc§ 4®}‘g)jÄÜ([ ‹¬—ÔQè ¿HtàÑÐè zôÇŽ'ä«Yi~ÁúrÛúÌñ)ÚhU-R«dhYî v?‡‚Þ#o"0ÃV'—ŠtÔ¡çuUÌí­ý\(a”Gùµ^Ïsäiü!UÂß}\q¹'Õ!Àœ÷Øð¬„-‡Ïã±ã÷`Ëóàˆyù±~Ðþ¿EÜúÑ#¼À,¼c»üt nØÈ¼G<Ï_LîÙ_bÒ÷írW~ré8žwô{Ù<0¿äЫ3¡šu1¹àwïÕ½â&_Üx꯾ÅÞë–÷ò’К"Õ/Œ_€hYù9 ÒyQ–…X‡×nûº¯Ã½nÍQÊfô>݉‘ ö×£fCŽA è‘©§êE*÷ÑWAÏßsšØÓõíKè4–0ðÉ/ô½?úcG“æ!Vš°NÝÈ„ÚÂ7É\$…鎎*‘·k rìh¥£ CkÙ%ê!ì¢D²ªŠy%:÷æ$ŽÆißÛEŠ8ʼh(ê!àÃõwÔü–w°«|»ò&Äïihßq¢Ý.Ï÷›61ù¾÷y`Ž÷ÆŸì[cÅv@Ò>t•_ßñ§Í¦=Ü`NºµË¬¤Ún•³âà=XûÆ%4·N3ÿ’Õ ÿ`òái´„å»ÀØð0øþ1¯ãº#^‰0†ÉÆëfïl—)„»I» »-AE6æ'G¼˜ëžñßrø•¼•lŠ¥›Öðoßú8Y–²Ëꇙ¿uƒ°{d t˜Qá?¡`W· *섾K”E½P÷Üöï%èõ…òe>| è†TTEŽj§ì%ÎE=N!É,]OäæƒiŽºU´­|›Æ;ÿžh·¯@®/èý±CÍækL©µ¬W×0NÁ°–žÇÖS[ ]Cƒðºh¥" Èp^*BgÒÿ®Ë;;0ü(¥â{¤_=µª·¢^У¤ W¹È]ælU7É:/ðX0"ïc0,oyRÇrÓå—3þÓŸÖ‚pƾþuÄèhmAti[Z‚¬Ÿ3Húæû_‹P*¢E›F;EJ]¹(ŽM(æáñ³ bØ0öEÜ}Òa\y鋯pí1¯aÝN» öî}RkZLûhÜ/ª‚â3aŠB³^‹°j]„ïNÈ[G–.@ɈG÷Ú“ç=ó¿ÑRòìÛ~Æ~+îåäï…ýZVDÝäÑ8Á¯K¸ÃÓGV"ïAï%Þº*õMa‹žúÝ•lèj‰3õ¼!‡Uhƒ.Šw˜Ü(³‹3+ê‘‚†Ž˜»•uHÇÆÉTF&­ ›‰Œx";_y%ÉÒ¥}AïþøS†µ¤úfFÒ`:íÐI%M-‰Tl…B âÄF¸I”åÝœð:âS–ÆÖŠ3de{„}dî¢rÝ„QJÓ›Òí•´;t.éÂ<¿ÄqF)’fJ#éÐhvH¢4÷·yÊNÖ Íï˜hüoš5Œ_ótÿ÷øèG™zä/ÔQY/‚¨zr ƒËDÎ2×yâÏ›g¯sL61Aºuk9040çå ïŸ ‡Í†Fƒ¡‰ ´‘>"wŽbná%d%·«íç´’]y@ïDsNç 6«y˜Áôë[DÚÚîÎÒãv¡¤óK^|$ ×kVñ27O°ýÏQµäâîütd]o}ö³¹å¹Ï岓OEÃ[Îý$ÏüG,ºá~Ôd!Ò&Xüø,ö 6za-^øø§¤Q°ÝÐAM]`Õ<ΔëöÀÏåQôb¦:·"ÚM#TìÖ E"R¢X‘èÔºU¡0JXñî$tÒ¦# R<Cjm½´uÁ›v)xïé ÝHÊ0š3õ‚î¢ô0"õ{ꑭŠ£Ì§áãÄÞNš©ÇQ6›mš­6I’b”`:kù׫²ˆ†êeŸfÅ÷&xäü FÓl9¼lŽ˜•A.j4ˆãØ¢Dóë¨ÑðT;‡šM¢dÓçÑK/eË֭Ť-`¯¿’,ýô,bz:#Jµï©ö[ :¯0ù1ȯ5Ö\å7âH¾ŸÆczwîæ`â,#&óÞéCbÂBq(‹xÕà§$Ú.ò¯i3ì¡W#TÙ­dn]çãΫ_ÍŽÈâˆs?öI®k¾…%×ÝÅ_Œ_ÄÎïÿjL[+ûнz5x¢‡`ÖkþŒ÷á«Í÷ob׿º©,Jêzõ+Õyù)Oœ4<ò(ä _JÑêt07ONb{Œé‡"f΋_̦[oezË–¼ð…4æÎí zôÇݘü>LŸ‡é\ÊbÐQ§AS·‰uV´ÅHcSì±&‘)1VLÇŠs–ŘŽ@¦ÙÑÄYf­8•µû™ñ¨JÏœ¼´MЫ´…uZ–Ì?fjf.í‡HJQ†[H‘§ßs‡-G§J)QC·2š­6Q¤h©iÒ4±Ð4"é¤`à°’ì{êKQÙqÈÁ£mÄ#Z¨ÆkÂKŽ…õ×üBð5=ÍÃ\€<âæt2ŠhÎz„y„½þb“4‰é`Ò±)c]€L´òÛ B®i½œ­r<‹Qf« ©íg4—-–+kÛË-´äØLƒöQx)KRí÷•N!¶)è~Úœš w<øoZÚsBI{Œt$Q2BG’Ur;nwn”Çsà_ÜË+Ïý<ϽüjÆVî\ìSÂg@džq šBCð3¼Èã{]%xþ³¬³®<¶¤Ãül´¶¥À´»OktÖ1Z£Óeè4%˯uþ|™R£Þs/ßøFâ¾ÐžwJÑHS 0<6ÆR°‹Ïâ9s­V?åÞýñGwÖƒÚ «ß íÀŒƒÖL5‘P(ù*ñ(RÄ:³¶š¢5ÌË™Ê@ÛºtE±“Q¤j•5ÃP*Ÿ•M¡j-Ë{ºT³fj_ nJU˜zGJW,'5I’Z¸E#³Ð‹–F´¬˜D¦•¢²¦,‰+Šù ®ED÷Áî—ÀÐQOé'$ v{õ«ÙíÕ¯¶"1q+ñ¦776 6FˆiM){¬F¶ãf'³èÈ_\ðnlîÇ-ÉQLˆ!†¹f ‘¸âRûÂÆÒv….lwÀ–Ú …¨½ÖB–D¼ÎO¿KÐ}PZ„¢aMF(úN؈GG2o—³PžÇånœ÷žs¸ó/^ÇšÃÓ;‚A•ƒŽú'‚0½D ï+Eô¢üêûÊFÀ¨Êk–,œªcLýÏ®Á˜â´zF)/ø&¼(ûtšbŒapéR†÷Ý—(j·”ì¼ó=ö½?þ¸ÇÄðæRxäCÝ6ÎmKhz„ˆò¨­Ú0ë~ÔÅEv,Cv4±É<ÙJ*5†iuŸ^×e¢•ÛG-!)g¢W¹p(²àJc(Ìed.èR!›Ñ(§ñ#‘È·”µÐÁ†ãáÐ+`ÞÑOÙÇ$¤d`ñbÈÆaÅy°êH7Ø×¤)>i·œçý-óâYûsÅN¯áþÁ§ùçkÒ¶èùˆ°ïß {). #eŸFw)ð%j¤(³ès»Ýð¶uQ¡— êSwäÄÑ”ÿ[\ø|$Q"‰¥ìå¾wá¾|t¡áH9›=˜Ïï‰ñÁŠÿ‚•g[HMøVå ìù HæÃn§õ矾 ?Ás+Ë8í4{âÜ}÷ÝýO¬?`j=¬ÿ5,ûd[ary½çv>i:h—Êí顺㕋Ԧף,ç˜;•֥~ó0ú.)j[]XÉz5 QG«Š"…Ñ¢ÄÔv˜Î¸‘!È!±é~îç±¹rH ýF2/ž3ÚŠ°®´y–²w x(î5†B]uÂt/ÈÑ.]kã_c¸0B Ñ6R—e¯:f3ËDZ˜±˜Å{=ø&ì­#ðoofùà½d‡ìÏU{¼­ÜNlþ!¶›\W÷ûЬ'´Ù =Jíƒ5ï9|._´X“èź£å™½¥—}kßÐ8HJpÅœ¢Æ^6²‘s;^Â>Ìf¨øžÃ|ú¯¿¸¤ñß+žðÂ@]âÁˆâœÚž#Ÿ#?ß¾sdrÎ>~u©5a|è üì&xðËð›[á—ÁÎ{ôçʾ ÷ÇÔЦ¬ý•¹ôkpÃup÷͈«Ë[¡bi™O6ÒÂ5Üý%úžQ˜¢ãFè¢óZOÒrT­”¦»è*f³jË º›M@û¢‚áœI L™vY:L:°ËÔÆ¿ÿâÚøhJê÷Ëø¾á™´ÛÞR[’•Pðž“áó—¡3OØŠÍÍ|éWLñès_€Ž$ÃŒõLŸ÷íðw^¼´-‚º|ã=òǹ,†kS¿¸)mqTkõ¿«uÓûÅcDáƒàz]¾ýNà#…Œìuk_àYSà_Ç2¾Ãc,âå¼—aw¿–4Åüë0ßÿP1¨²¤8dÍ9ç‰(¼ÔEîÜ)Ù$æ¯OF|î8t†ô{šbþí Ì÷.BŠü{åßkŠóYfùbaÍ­ðΓಛ!Šúsh_Ðûãt<ôúºÛÈzã:ôÙ÷béÂÏò¨;•G ÊÝ–+ŸpŒÈm!Eyˆrj“ÔVÐ…©‰Ð«- —_<„P üý b3ŒºKYÛiYŠÂkÓ›¸V–0C$J^ØÎ*SPg—i ºpÐ ¬BöwC*Aå¬éF’6ˆÕ+àU/E\r5â™ÝEP¸…)³ûÌLˆ 0Äóg÷ܯ%Õ…—\œìF©¨äÈgŒÀ(ûX­ A[ãºóÕDÖm?„YšžÛŒÐgöêß ·i\Ç[Üz‹ß¼??²Ž€q”­ŠÁQ+zÝ7rá@Nd^Фaïžž&{ç_¢®þ.RB;v+_ GEV+2åÅb(æÆ÷Ï—íY“DkW`NxÑwêÏÚmÔéIzÍÅÄ@»aŽ€z»»ó´Ñ†hÕ­´Ï?ø¸WíÞ©«¯~‘u`ÿÏA_Ðû£?~ב­]‹É½½Û^HúÃÚùkãFôC÷c¢¢8-Ê'ˆ‰Š¬˜™_§Åª=¤D…Üi©aÓ¼…L7‡®}Ö«¸üE¯+ñ©mU\Ù@ä_Î;ƒ£ë0æŒn Õžð¢]¥\¹…ÕHºHV%-¨lËŠ0*¯©p/i~ETDå±¢²½Þvµ^Ø~Òäit]@.â4‡_h¼¿xi²È¾w%!í 1¶ýÚS¸ä;È£ö`Â<ÂJ¾…Ñ’1ó)ã$æç@u¹§ˆç–¸r£l®t„Êrü\´CñîòPeŒmɺ5ð¨!v :ty·÷Ú+¯õx7åv9oZTgJ“· ú‚¸HÖh°vÉ®Hûu›èaLï¨‰Š°çý¾ZJt$Y¸~5IÚæ­Ÿýýöæ­_[жë‚ë’&‹ò7ÛíšÇ„ívunz)º©ÏCžA‘ KË›QË„ÅG?›‡N{ëV²ñq¦6l %ý0lŠÎE*ÌžMTyqEæÏýï‘´éa™"ÏÓçY“)K­sèÙ,‹‹hÜAnro|‡¢u‚îÄ<´×u^ù¡€kIóÅŒ¦Ra^M›WNЮLjíœ*MME¼èѧ)™U£v!s„Hƒ,K‘T“)ŽõÖ”Gc í$diL§ðà4£Ÿž`ËE)²eá;Íáa,¤1kÙ³‰‡†ˆ[-¢fÑh”2a+;u–a² 5=êtHÇÆèŒŽÒczÓ&¦·nEw:d¹û¤ öiæÑc"²‘ÏŠiíÝaÞYCpÀj8Aåé8—ÙÛ/åú”ôº ¶þÇcwÇö° A3ŽíÜÇ`zdÄq“˜j6‰žõ,Ž:ïÎÄÚµ´7mBŒÐ˜œcßm40@2w.³eÞ±+zéV:© Sz\w1Iaßs$b–aøÁ’S"V}æiŒ?pQ£AkÁ’áaŒÖ¬þÑØ82â ;í6òXñío³ïé§3°°Ñû‚¾£!X´ˆÖÂ…Ì?ôМAgíÙíµ¯µ¨ÌVË“· €>äbåjzýzÆ•âi{ïM”§êˆ_&‰Ïˆ8&JÈ Q2ŠI‚ˆc&âˆßÄšûšüû‚a¶4›DJ1'ÝŠDÛ}BSJ„6e‹Ì /¹Rû¤—)s/íH¢…DEóg\|ôÁ|ÿŸ>Èÿã|Ý2ÁüTlïüx9U×íüqHiõ!ø]¯ÏCHéÁTÝ ¼q?Ô*´F;¨…Ö6ŠrÑT>ëœd¥:´R–h¥2²é6ªÓfÑˇ˜õâ!’Ý®‚© @NƒlcŒ ³©A¬m…\LV M#ã#F)5‘²‚.ÚVà”¶és•FÈÌÚç’É,üÆ ¹1Âëb••ZÎÂýqOªÓbÆèXÈ Û\Tøò˜n¿€^}âPz*éøj}@]{Õ;Àt›Ùt¹ Q£óH=twîG±%í%´Àæ63KØÌ<Øg=RIeì÷·’µß ³þ’¨Ñ°d<÷ýÎÛmXòóÐ(…IS{žu:¨vÛ^OO£³ÌŸËQ¼™Vóï‘Í{Р7I¹µÙˆ¦#ÊÛÆ’8%Ž3ö|Û½(ñf˜ý6d³‰NSV]q­ÉIv}þóiÌžMsñbZ;ï ­–%î ĵ¾ ïÈšEµécÇ ,Yò„Ÿ¯µd {zjoÑÚv¦’Ÿ0Á…Œqíœ%ÝfÓ&â\µœ kÉÖ³ ×èQiì݃3+OÁ«(²PŒD`$|öcïäÈMcœ4s²˜],j*‚\Ü,®ØÞã‘GAÛ“]éûWYC·²Ñ s Ñþÿ˜‡ß‰Q“ /ü)ˆ«`MwŽ_f¥,䱋¨L3ëª"×”üðEjz"¥¬ ›\б°c„Þ8Ñ6"¸¤Óë"æ\ãÁ,t·…•D>OëzÑ–ÝŽ~]Â>ãGˆxEлúçÝû ]—SzßäV¿FX‹ß<3’$)CÒL-¡®¡S9Ohë¯%:“ö;d ñ)Xt Ì{ ¿ ñ\lïÿ^.l¾¦nÇ´FYêabRß{šé”Úsc Ç+ÀdÄâŸaxO8Ñh°ø¥/eçW¾Ùj øàcG}Aï§nð$¿Dó‘óYÏòœ 5¿2MD(ˆ pªÊ5ºp¥#Ëϯ=è¦õ–<ò Z¾*Ñ·Axb[ùu »4Ý^ë{Þº}÷žÛ;5.t¡ ‡Ö³Õ¾ù0b?!½Ïe(„4þ½F‘%å5¹7”Å冋ttQ0ª3 «þö‡g\ Ãûÿþνû?Ëÿ¹ä-!±5±Èf\$uýη”ŒÁªSà ¯!v3­'€ô½?úã)SdÜÍ.a·°€¹Aú2LS:Rš¿_äœê0ú 'TÄÌqÁdàxœe½¦Àð¶ð Zü ‡²”Aü]hÓ#ÅÏ¿x;¨IØp]­`ÏT¹Xµ­=ŽuÂnòÅ—Áî“m#}ìÞ¹&0‚Açm >­nDÉb·5›r„]òEw-_‚n³–ª ‹PÄM¾5Ri¼õï·Ä=¯ñÞïrå 2ÏTv´UA×ZzA÷÷ëÀÖ–bßÝm/HW8—äèØ†*fvQ'†ÁE=#¯ø) .zjÏ÷Á-gÂÈÏ Ëäð˜÷Z Ù¡Ús.$þòýpTû¾~û3a}AïþxjÇõ<Äu¬àÞ‰¹;ÉSt7YʼÕɆhº-<+EÕ~xI(ê¾âÂe"ðw¬æhvæ½Mò‡"ê÷\[VÀä:¸ù¬nõ¢½M‘æÉ=N˜`a÷Ðóš‡UòP‘³E…·é*ló‘©û¼B¡v{ã¢û3-L ê €B¨e±lÈ WÔˆ‘@—l{ËþEjÙ8„ügWèÎ}ßk_iyó0ž†ž‘"XÍ¢°ö¸à%pò¥°`¿§æ\\u \zL­í¢ë͘Ùéõû^ïGm§Â^;ß{_ÐûãÿÛ˜dšUlàRn`%£¤hæQO´òe[ÏêÞd,©ïÒ}5Er¥Tkþ˜ª·vhµFŒ÷³™‹hóržÎbüÿ;cat½}«–ÁugÛÛ›‚öh}´]CÐ2uâ³=b½= SˆºÛÖ@ÙcíIuÁgV”ûEVd*Ó%Îøvóü_YëÒu)¢.¿v3ÃûyB}½3A×Dùx‹j6ƒðº¸Ä¾fŒ–¶}O瑾[ ™ Œ§—˜÷ØaíðÅào~swþÝÎÏÇnƒ/…˜Y¿ÈÙ.ÑÞRX¿Nù< Ìî úÚ8çœsØ´iS×ý7Þxc_ÿHÇíÜÁÜŬ`8G[†î…Ø€Òye®±=É%äeÐâî©‹J”4Sã¸]Åvh48u¹ž_/ìnH4÷2ÂýÜÌ©œÀAôû;€?ûùJ8ã2X¼×?GUßú(Üø-ز¢ÂaÑù <Ù…a­+Sxýƒ¯Á>ÇÁs^×ô?´ñ†7¼,˺?[cøéOÚWÇ?¢±…u\Ê1Á©/v YÕ€n­l¢tT´t7«n_7d‚Wï7]a].^þ>Qˆ¼CY:‡.GÁr.h+ò×ñM ¯æ`žóäÖwÂèæbûüû`t“½=¶:SÝ"aÜm-+~ò¾¸¯ˆ 7°ÕˆùÒëOgº9@§Ù`j¸ž¥<=eðX Ô9úÛ72ÿñb±ýì57˜´^̃E…È÷¨ÆÛë"+"]½ÑvÕ+ßT܉L(ÔFç3EˆÛ›¡¨ÙbßÐŽ½½—Ø‹Šß<Öe¾ •º¸ŽTÞÜ +±¦ž®ç ÎÉqÍí𷯂³»<Qß2Ÿ:~uÄ kåìœ%y$-zëmÕdôt÷Ùg >õ>ÌGì±ÿ;ßþA úÒsçÎí+äѸ• YÁ2$ë"ãðâì?3Ûˆ<“ÞQ,,êšHƒâ¨ÐBÔ̶N\jùÖÁsøû‚â+×ë ºŒ­©G$T Šq_g˜˜Ýyæö +¾ƒùÕuÅdõó«ëWvGÜ}H{s@. ÝEó‰;|à„÷~ï¼po:³šÜôø³HÕpÐ:"¿äã÷^À@6UzÍý¿²Ç–Gso|S¼Ö„,@L%5nD%úî…‡âmºE³V,Lyð»–Qu­ ¶sq º_Né5V½û%…8†œ‚ðgà a<Î#TwÚÝw È"GL¹ö^8ý$øÊañö¥ßͧa~q%"‚NËÜŒÌÙ¹3a©HµWaf…S¯â¾Ðn–µëÐç}Šè_¿Òôþè§bLò8¸™ûø) °S¥b]éí>³´°þt$-—rwQy)5@Ø¥©í®ö*wa9uà³]Ax:Aw]®ÿ:ŠQœ[nÆ©ïõîâ“D¼‹ïÚóÀÅSµ§áÝo÷èW#@¤)¨ÌBSt@€ :$À¹Ÿýã(Gçí¸É|•ÿ›þ_ŸcÓ¬üñ›JŠc™›YÛ¡j3ˆÔÏ~c×ýßxö_"fŸõðÁk>pØ#7±xË*+ ²’:§v.ªéñ*àF‚Þí«>£{­_þözî?¡ú.1ó^¼½3]Œ€Jç KeË /Uã‘Êzö‡ ·°3Ž®ƒR „%ë5VÝŽzÅ‹ˆ.þ>rßÞ…rfÓw½yÍUdMHÐéXÞ@#‡¡¬ ;ˆ‘ ¨†:*‘L%Sá"|—ð  ]:Ú®Ò¯}“xçiýÍßõ½?úãÉÍkÌWبͤ|„Ù¢‡™*kêÄ<Ëb¥gQ©‚WkÙÓãÚ º¯vÆVNW½ºz¦«Uñtzhd±ŸDïg)#í£õFÖ¡‘t¼õ¦{§«8‡IÑ`îßü˜huZìaçÐ7Y©†ö` YPçü„§*ž×“éHÒn`€ ^óN~{ÈsèÄ ~üŒWå!êSÊf;"ÉmU‰šThðmšÜ5ïéœö´K8lùM,Þ²š9ã›øðùïCMÃm!„‘j˜–•È7tQ m«Ö¼%ÑŽ€†ôQ/˜ƒzÆ,ŸYUº2Ð63Öfû²ö½Ž™é%ä¦;³`zì/Ww•Lð~e 쎺é {œYqÆŠy瑺´Ôvô²û0§œÌœ«¯A.\ˆˆ¹Ð==Íæw¿qÙUô°v¦ I±¨DfHN¾xpTÅð<ÏqjÝã€sr`â'¹¸+i©ÌÈ>öQ†ç3ç´Ó ëÚ¾ ÷Gl{(gJ_Çjõo#h ”YA¦¬p·§›D©"ê(•ûÂ7•Û{~ÝÞ+<ï³-õ»}lž®_t{uWyØ!0DPøƒë r8$bÉHû×âöÔQ¤h¶Ú´ZÓ4[@‡Á(»n êÏ×ݗᨖ½2ŒF{ŸÆØ¢@+xðõ/;M;-aÍÒÝ9ïígÚB3m|Ñ™ë×W2ª¯îÚ– ?QTÓ¶RÜùkXvØQ¹ .=þ-,Ú¸Š·}ó³pýjžsýfüïÕ×o¾R1>>Z(i¼ržÖB¾ežÿl# ÀëöõO îœÂ\°s_JzCg»Ž…N«'#èu5]µÔêÕ,ÂíaÊBˆ.RßQ– }fE77^󑮊Dî×ÚÝq'/]ÊÐi§‘<ëY~+~@JÖ¼ç=´Ò”»0S#i 5sç1=6Æä:k?¨"Èò'ÈÜß•tw#THƒþ³ÕEúÞÑ]ÆÁ¼ È&§Yÿö·³plŒ]Þÿþ¾ ÷Gls˜U¤ækL¤?¤=Ì J¬cUdHH1F¦ ´A{º Ðmé-@´C[ôæp—¡½§Kw‡=ÆÞzÔímÓíVνd¸OnŠ”»‹Ð~Ò׺´–Hií3]¤îiWRÑH;4Ú§h L[«M%‰÷Îßkpÿ µx/wYç…/¬e¬@XÚ\’ ²yÁNDIÂ…§¾…ûžv?íP&††m„KÇöz‡V·27Ü‘Ô º7{ ÛÊZËLq_YGE)ò÷S”ùJ™Qü ©srcßÈK8û#_`pb”½º›n»™“Îÿw®ZU8æZdMþo9RÁ½ÂŸn’Ã§Ä þ¯äÁM»}Óž(‡ç…oo<Ð >9„\ßAÝ’°å£ · øŒ‘°®3„Õ…=·gòãw–»þâ`:Êþ\êÈ4ÁúËàžüícò?ezgL±Ï…°¿F& æqªÓajãF¦6mBu:dJ±î«_eò¢‹hí¶s>˜ôÎ;-M­Ñ Žc’¹sZ¼˜æ¼y -^B2w.Q’°öê«]W ‘uFn TY¬”©²]5„Ѻ¯ð/²>q`»#QI†O|‚Íããì÷®wј;E}Aïþ(O#0}.FÕ™D¦ Zäq’Y+Ƕazº…ž’Ä ÕŽ,Y«‹cšG‘YäÝÁJ_Ú02Ïý¨xÏg·Ÿ-„©µ÷ôzªQ`T­6½SW.â%æ¶„ÝH"i™ÔRjš¶MÁ·­°7’‘°Ñx׌ƒ¾'xà¬CQK,¤&Š,i.ßDͦØä¸Ê-CC\¸ß^¬Ùi!—ó\¤ÒÄʆQRiZL[1r0!-VHL$Šã‘÷€K£Æik½*Ua¿êloC!÷¢_e Qsg“ëþ¾’‘…ÜH‰‘Ö’7Ò ©¬õ¨ÔºxM²Á,|÷û,¾ÿÎwpêç>à ¿¾‰E£cvñ#e €8€#£ÜãÍìgý–¹'nDÍ‘(¥Ñãm߆è²+¡K™À(»Õ"gkxÌIÆä—0}ßAdvíAÈ›!B¯xò;žKWwmLÖq­19`Ç(ÅðQ· dÇŠ¿6L­Ø‰ñû—XÐN–¡Òí.Za”Fke/*¿¤™ý½Töšr‘lµXrì±Ì=õTŒÖdããL®]ËäúõL®YƒZ¿žÁ4ÅhÍèòå4-¢¹×^ÌÝg—,a`áBKjÌ1¬¢Ñ`ão~Ãj`ÔY'[`#Dd?³ü3´À£¨Ôѵ&ÑÆ.|T$Ê”=Nù±*²‚ÙûïÏü£¦½u+]v»¼êU öikýÑùh?ß…‰óA-·ÑeÚ %¦­'sb…܉¢˜6Dme O ©4¤xç07‰–ZÇ(§Õ GR•…\å· "uY´“õô¯úl»ˆ\—Ýá·¼õf^‘/„A+©Kt™vÕN‰§,åªÑ´¢n´`öb8ìã«éÈsÍ= ²š¤(â.™1I>”tèD+††ˆ”b¶õ ŒÍk!óªñ²˜†€ ^À#­¬˜æÅ{RæE|鋦ln²‚n„ÀHaa6¹€+aá6*Š,š6Øæp ‰H«Rf@EÄðݼ_nÚD3M9sÙCüY[±€¨LªyDEçš .¡¹Ë*{ 6'Ä2ë)äÕÍï*ù,Š9Ïy˜á§¯czý9˜äž; µqq d§ ‰ëî«@t˜¾xà¿I†’ù›K…jr5¶Žé‘£™Þò¥ô¿OïÄ»‰b&‰øÐ·ðs‚äfhYÝðmÄãÿhÌFk›˜Ônl£?¼T@YÊÝÚÿ'õ8ƒs>Ã'ÂÞŸù=g¿:ðȇ`ôP«‹üó¦òÞydÚD²Mc§1{ñ2̬“`ϳ0ÄõÔ½êB´=‡6m6‰*¢÷»”“ECCìrüñìrüñ>» ½ø?ÿõš÷è2Iv詺/èýQ?Fïƒ5WÂßµ±Ë‘¬ °¦ÌµA´­ëL"."^×*&+Õã0;4¤ô8.¥FÈÛ)MÉ.´¶ÿˆòDØkQ¸=õœ¡µ@«È·Ñ)U6¹Q*òHJŸ%’©ÔFÀ‰¶ö›¦’“U˸W½Ÿ±Ã¿ÊçYÅFR¶ ÐæRÓ6'»ÛìJoËÜè*vR`ýÒ…°±Ë&ø…“³³e„l­ËXEÐ-÷Fz@Ž‹ÒÃÔ¿÷À°Ñ¡èù÷p*s ÷IÃÃRðUçãìÉÌb6ù¤=z?¬ý<ø`t±øÙÌéLâ^úÌ  ý9ظÿ46¿k®…åŸM×ÔÚôÖç ³Á¿ÃÃ!öú ðáßÏ|°ùN˜Zj–½Z;ß¶¿›s0 íV^ 4›Èf³?ö½?þÇÇ ‚•WÂè½åÉ¥®]©.ÿh@vlDh²"]]z¸4¥T¹”y*ØEãQÞHëá¦Ü£œQÛå²-¯9KˆÈ¼™M»ÛJ|×b‡¥¢’pD“6ŪÞøÞÁ'òà‚ýøÍ’#ÙÂo¼ÕípEìªíte{ÐBð|T«Ë&÷çdç„<ì ²H¹‡‹ÿséå‹®ÏÙ§ÞeþùŠr¤n„@uQóBsŸ°ž¡ô9 º 8)†°‘#™ËqìÊóÆRøÑI0~Oÿè%ÐOFÔ+ndh`Ãå0*áe—<µß·{·ÞaÝ_ÂïÚ6¢¥ÛzÖ|VÞG~æ>í©{}׿Vÿ&–¯k#<ú û·ç?ö~=öþþÜÙôþø:ƒÛ¿ ¿ú$l¾¯{RñÒÌÜS$ qt…o]^ë¹@ûÔzTDæSr ë²l®”S/Úb¦ ú Ìé˜BФÑD@œ÷÷˜Ü¢ÖÍåQ/ÆBE[²;«îÂu‡¼˜»w=¸$²óØ\+tFã4¹´Ð0……mˆzõ‘u¥]/´¦ SìRäF9ºQnŸÌ¡‡ûè>R¯ »]YMÐ=¶ºóË=¿(ÎÿZ1<Âçò£¿½#¶laéH.æu ÍßUÐëèdk/… ¯‚#Þÿ»}ïVßß|1t6Ù^º:ŒíLÖ§]Ñz«/€Û~§^ KûW­ÿ \mÿ~Tóš °îf¸ëfXõúzØýèþœÚôþøÿ:Æ7Ù4å×ßé<|mÅØF4Þ+Bî‹”EeJ£=èDH›*7¹õ“Éá¡ýg•–U;UzÊ=Ú\¶'B¯þ.lI2e¾Kú2­ò¶+ÀY”0ÕàÞ§È­Ï8‚µó—°aÞB4’¹lñ‘µAiè—éÄÜ‘³ÂìAÉæ6ôÊu5Bw)w·w¦æ]»Ÿ4ÚSèÂçé¡‚ø¢7_¨GQœ§+wŸñð=—(zío¾B= Þ ?|Á+¹íÃ9ôÞ;9þª«ˆÓ¬ûœ”O<[S^èöxìúÂo'ý_8æÍy;Û+ï‚sO¶^ý²fQ²-™™AàõFûÜï¼–> `Öðë¯Á¥ï5^΀˜?×ü_ëå~Ú·a¿cžøßƒ{þ~ñeûóüÝáÏ? ³æ?¹cÜôþø“c›àÚoÀ%Ÿ€ÉÍ>20îZ:!¡›eèíÁ,}é#*mK äP²ðñ®p„Q¸ÝÛ⦜•-¹d‰^“]¯½Îß»ÇßíŠþç*Œá±Cöá®g=eG=½”>ïŠÄsS:*<êMP¨ì/—à}øÞܦۇ¯l¬“Gè.sànQ |©Ë Ȩ_ø`§ IDATÌ´ˆó…nAë\µ ^U8ñÎö·$èAï¿ë&0•FïÐO_Š"ÛÐÞ©É­ÇN$OÿåìsëÃÝ Ì:2œ™!…ž/z†hXÃ9o…q ǽí‰}¼>uŒ®ÂDE/¶xª`õrøèqpæ°ïáOìõ]s>|étˆòy vm[[kVÂLJ_‡<Q_³>}2¬¸½¼x¸ü¿àÝ_…—¾¥?w÷½?X·ÆGar>õnȦ-†3·5ÎG9*&™OZ“ñ+gïVšL>úÌO°|xoÿó—þvZz Ä&c¯­åÍÆ[:jYãÕ,¶· é`¦‡h‡ ¥5†Ù>Aw~FT¬F+p!љݢ3»Åòc`õŸíÎÖ…ó˜( ¸¯Rk\Ø Wi“*ÞC%u.LIÔmá{ч/ŒéªZ÷‚žï—‡¢_¼ý ²\…h3 zMJ»”zÏ#k/ê•t»Ð þØøNƒÀäÇýε4úL¥`ÒEí+ŽÞƒõ‡,âŽÇžÎ+>~5›¦|¶ÉÔe‘LoqÕè¼.ínòݧ ÄY £)¼öÛW±ýà]ð×`¶®"KrírhÑm!iƒsy|é,TÃÚ%ßóʃXuØ.Å–H˜½Úé×rǰ3{#€C Pà 7.9Îý:«CdÊ‹ç™] Ùø»Sà_ Ï8væã1=…ù¯F\)fýCÞç]„AÅYý;|ã&ØÌaú‚ÞÝãÚbnù5âÇWÀCwù NGöâhHy+8FæÐ`ÍðRÎ{Þ»Y>wo¾}Èë{¯ÆÃO½ÍßîŒò®Û¿€𢇯æÈÇÕ ¡ÞÒÔùœw‰5ôöë65n]URÕ6™=÷ç¡Ë‚sô ùlzÎRF^ÌÈ!;{±dŠA¦¼`9 ¬cº»ö·ÐÀ¦KÈE¹ÂÛ‹˜0%ñvUëaÿx˜Ž®ÅyA¯ô`ûžs¸¥Ò^zè®VuéŽÔƒç®.rºÌ|”ô”¡ ûÅÊߣ#ßÅùµÐÈYš‰ƒ†øù??½~´œ½¾ù ÙèJ6¨tj˜€Zæ¼ÏMá.]rZØïT Ò1ÄïB0 þâ3'ï¼ Þy2ÙÈJ²Ä f’û©;kà.A¯‚®8iOÆwŸÅ'îÏä‚Á™·FØ€`=¿åNÏ"öd)±˜?c!E}‡ºì›ˆ3ßMÖ´óƒöxP=u.Šãbˆ5kõZÄ/£ŸÛó¨Oý#|óÿ`ÈJŽÞ£>E>ò[ÌU#_óúþÜþÇ,èZk~õ«_ðè£ö?±º/Å=÷`FF`d#ꌿµ_ˆ­›ã£Hc¿œ*¶_-íDò¥ArË!ÇpΉÿȃ»@G6X;¼sióûºUk,QLêcb6Ÿ~É?ð¥ç¾›YQNýÕy¼üöËØkÍýeðFeï[˜Š ›"‹_ë×m*¬hSÏ4êœOi=;¢sÀ‡Îaäu{ &¤³›€`>›Šb6Šö6q<÷Ü£ÞCgª{ îåÈ×b[¥.ÛÝb c„0~kÛÄTRîáí0êï^Ÿ‰r `ÍïÃ穊yéxŠJ‹Z),öÕµ)²¡™Á¶†iù0Rw×2²]qb|õÎ(xt¿=é,€yW¬&¾w¢T§QÊÀ‡Ìñ`Å ºTÖ"5Î ¸‰05ª"[”®$AòÎw Öo!ùë¿®=ÆÙý÷’½êe˜ñL å5f¢NîE®‹,–ÊÜZBgÏéÎ Ö¾qwFŸ1—éd͘¦håÞÛõjfF³‘UÜ™Ë~ìÃàºïû&…¬±£¶¥¶Ö®6“æ£ùRåÇE馜~7SS¤ù:ßøw»èÊ;«–®FX¤«0½ç¯ˆ7l¡õöwu½ÇÎ 7e™õ^:ôPÄŠÚÆó-VJñå/Û"‰k®¹†Ë/¿œ³Ï>›3Î8c‡ñþ0fóf]s <ú¨Oß…-¬ZZ¤!¢H¡y®2ð±¿ÿ¿L5¹ð¸·•RŒB[ÿmoשƒ0d*‹¢ÿØÈÀµL/duñÂ[¯äïÏý@÷Ö» ®«¬)‹wÝ$ì×ÛÙ’^M¥W3ziÂô‹È7˜|Ñü"…y9Ž»c¹«4ò¹ëYw}뀷u×¥‰6ßöBN`sí÷I¡‹´ÔÅãd9uÞ)ráÏu‚Ý+å.z0D}Ñ_zïÎ芌§zœ”Š a7E4”Ú‚r‚ÅN[ ÞFÓ¢l“$õçi¼±ÍÐß,Güz¼´ÅS]»„‹Ié„=+„=Î,ܤÑ)Hf+ZYl#X‘ÚÂÈ¡¯}ÙoxCYl‘×þ9ñƒÑiÙLY¬ ‘Ùk'†Yl/nÑÝþÐb&_5ŸöC]nqXÚ©´–¶lòK$U©kÀ}žÓ ^³‰Á® ÍŽ}m.c¡¢2Í?©Šcå¾OYda-RÙÅNg—]™wñÅ <ûÙþumùð‡iúSd ó—+{ ¿Ûî9•Ì ¬q“ø-o'7¥ÿò/¤=ÆÖsΡsÞy$ÇOë´Ó>餾 ÿ!³Î:‹3Ïÿå|ñoþ‰ÉÖè eŠ8ˈUVxkÝÓç;ôôÖB¢¢È_Ò$±÷Kk™ÚêLò®s?Æó~òözè¾Òмt!$ÒÁJܵCuäÖŸÅýöÍï[ä€úJ"²ðka/é çD˜Ï-°½Õ-é]\D™é•YJœJ#Ò,A+I¦bŒ IK›qv±!t¦Öæ6*úĽ]iè–çúõÉoáÏÕ½pQäÑk…Ú!cŸÐÄŠ¿3FïîwUñÖAo¿Ëp“G]GÕ üôÝñ‹"ëØl´‰bK¾k4:$QΩï(ÌmSl~û&Ôj]Ÿ©Ù®ñ?G)Ë£uw_˜_·5'¼5C±­£Š­:ÊÜ\2`ºÙd<ǯÆÀœ©)âÜ (ÖÝÅ­Õz÷|&>½Ë.˜ùóifêÞ{}!¾ûÒ$aÑg>Ãüãgh¯½ú)÷þø=Ž|²Ýúàƒí®Ñ"*! •¨i…r¢aQ«Õ©Uë–‚wo¨ý¬Æ¼YØfTòr5¦¥Îä nÚƒ‚püx‚ñã\º”øùç¹ÿ}ïC„!U­‘RÒ·ýŽtoº)]Ó¦ÑX±‚³g[Q¬B˜ªÀ´Sú¯î^9H â À£8¤Ù¬Ä ;W× ”º$üšœ €ÄVP)Œ Ù5ƒ­­8ŠS‰Ó:S‹ÓqìÙb 6}Ï{˜ñ®wÙ¿MVÝ?Ï_x!ÍF#STN Åñ¼»4½»F©0 ÆdÇ¡6Ý„µaw7"°Õ|ao/ã{zýýV-ndÆ}lû[lÕ‰‹÷”Lyë[™²ï¾£zõÓ:ˆMÞñŽö^ª“—t TRÒ°F>¥™ô˜![…l@™Äº¨ˆ˜ŠhæÖ»óΠGZ¨Õ¶µ) ­:‘ŽD)ŒÄ*ÈBïMY!#¢‹X™!ð‡7íÄ)ÛLᣃ ïR‰LΞ²–¯ª´u»×B€i@´Â.lC?øQdíPغ€Væ”Ä£˜M¥4+¬,š™hT”ØÔDbeH³4§.‡A›RxQ´LâUæíW׺хpºVqo™×^žiçg­¶ºóB[ ÏŠA–æ©ýºŸ§Ç]è÷˜ÿÊ9þ ì%YJ Ð]P’±Í€ÜÛÇqQíúayLzD:椆˜Jµisj1r8Ë´Ó\ʸ]zˆÍ¡NÏ@)“/uŠ^©$§SËdJS ×QD4<Œ6yó›éßi'‚Z­p‹†¸{³þðÃLž5‹I¾%ײɶ?§[0ƒ©Ø‘òÒ#±£åù'µõÌ•NòúŒ6Q•‚ñ•^N¹P©TþWiTh÷2Ôˆ0ÂõŽƒ½þÖ<1…¡uÇ!º¶Y$x1Ib•ÙÒó6IB\¯“4D##è8fê¾û2a×]­&90²|9ƒ##l}ꩨ0DU*µZfÐKO¸EÖº þf#lÒþmªúV›8‘ʤIÈ®.+ÒâqÉ'Í&•þþ±ûØö¿YÍ ^ôßkS¦lô×ý‰A®cW0H‚b\úÍ"UáªQGÉ„ŠlÚB"ç¡_§]­u1„Z×p…q¾>vXéÌXD2$–5Q·üÞ^KÓ¼M¾´‰dÓx}/ÏX6WÀ çBc>¬:7'ªÀHîmvŒñ¥‰8©52J9é#aA5ÑŰºcws<ëÎc–­ûöòá~¥vVx˜yòΠ•æÖ´D‰[ã“:ß “ƒz¡[Á©‰±·eF[‡\{¡ŠÞó‚‡.<©R'–¢È¯A)Dïþ^‘e ¯~ èI¢ì>Nëâ¼ÅÍv Cûa-Êåv¿@0¡·r!¨ßÃWCÿËKSúbè÷ÚËJ”.ú6,þ–—U¤MV f5Œ¨ØFbd¢³žýÌ(%=R~îÒ;®ö@©$v†ºí Lœò'>;\›öWQ×ôéls —©oo˜tàFÿÞkIm Ð_eÛšÌaßf!k0Œ#—Ùô«[%Ö ¬Š†Õô–¶ˆ(0VCZèÔ£Lø~ïr9ë«niiÃÎN ;QŠXÄ" !«~o¿b÷›¬çólÎ^ô3‰—¨Ò4ð,4×ÚÇ£§‚®C}A+'ý‹­¾îuBvÞ2± j¤L©„ª6²uñäé"¯:w‚3å°tN9gòv*Ïf2¢s"Q¤ /hèÂØRlcr0w€.HA“#þ÷w*’óûÙ {ÇÏ/t!‘½V¦- k»Þ¿éM ÇŸŸöí{Þ»ëïÏZÜR/U©Äz¯Õ¤PÝݲ%Ë`Åa°Ïoaµ–\ÛXû<òIh.(Î9Ñ&9¯ADV5˜\äH´ï´ÊéŠÖz)Rï^%iJËF0ʆOá‚8#ñO„]~ [ø·£újXûˆ½Mz—'¹š½»Ãn߇ñ;ƒSuôWá6HÄðsØ€FÑoDÁ*·«8@ÒÊȲ½É8»ñ³v'ÓæF§¸øÅq`‰´€žHECT[EI¼×ÿÉj^G_e&Pýd7,„‡~doöÅ7À†y­Êp\&ÓäEî¡;%2•$~uE’aV<ç÷‹K°…±Ô~%ò±ô8téÚú\~;%½òâëµúJÒèº4¯¯ ,'í½¾vûBZÁ 8QQ *ßpÑmß7™w`9ô‡êËÜÖü É9ì;Œ%z\}L?»Ä߅̸éXz³]u;Q({<ÂØâK_¸ÆOç´ã¢ý½Zîv(×>d†W›HP~qÖÃòÂvÃ^§Cßf/ïén>–þ®ÈßÒ¬²ôm0wo›xÓׯÿ1@õl‹YŽ,â,`=1ý&g#Ëä2ÑE*ÐÔƒªˆ&cÜX§…Y¬Ä/^öÐË´ŸÈ…0Ä*°ÕïBÑ•Bˆ°¸/g5g²ŽæLòCð‹†Á•0´ nù˜Èzä²3xß¼ƒ†èl½ïhždsó\ëßê\JT™¤‰(€˜ma²†z# Q©²`³mZX¾Â¸ÉÖÏ=“© U[”¼o¯÷Þ@+^yÖä^¸)õù¥Âxâ,~È}Ôr"þ‘"/ô+¼W8Wfè+{èÚ'~ñT÷Zç!©^ÊšçþØ+ö“Rg×±}kfü,ûl8Þt:lÿΗÿ}ú6øÓaÁÍÅùjÚD|Ý7ÿRlþI0¨4†e@7>SRú›…‘(}W»ùT(]¯Ãâ3á‘[à×Á¤­_ž1ºãûp÷w¡¹²Í餞— œkà=ß9gc#ð ßžgçr#«AÉ8Wåx¾U+-¨[”‰Í™C`b ¹w&¤imƒ)-ìûì`©ìez— #‰TD„Å¿óe5Óv&! «Å:Îãz>yámÔFêöÏü6¼ÐàwíÉ?­`t¸òÍ]m½ƒà æ>v0OåÊgéy|sÝר˜ÉpÈÆ} _™Û0ƒ\ÍeÌç9´Qô'¹‚—cÓØ–³Œ°„"c˜Â¶§¹JkçÉaÀ/ø*0‚¹§ ̾¦ìç\ïi" jT@O´ÊÀwƒZÅùï¼ÿŒëè_¾Ž;¦îÇ’î·#€«&Áµ“Ï8Í €…G€Ô¨wˆ¸ ewE…4#—ö¿?« ÐBòË…'¡DÂÖ#O³×Àý! ,xÃöD•>x¤ý|JÒoÖ·ó†ðô.;"„fþ®Û3íù%¼ñ÷wÓ¿bÓæ-ÉŠßd‡Å´;ïæîÚ•i{ÝûYÊ€ö^á(hÞ êääÚ£|#( ½nwT»eE6¿ŒÿßäŸÉš!tn R{¤'IIÀÐ^MMGð“`Ù*8ú3Ý ºàqøêA0°ã*×eI½ö)¢œªV[v6I‹Ìp;=FÉ2•A=r€4Öø)}–!2ŒòKϾ ¾zÌÜî¥ÑüÇà«b†–g!vaF1zèl¼rö¡o+xû1c€>¶½r6ƒf.w2—ûXÅ ô$AV(d»Dæ}K‘ö){ùs·ØDFZ"ŒÉÚeüü\¦]M›Åßøòj"ŒÁH Ôyê%“2 Ç:@ÃP³! sj»òÛ7ϸ•xxž¬ªLÎ@¼bšÙsˆÊ­u-+)ý~é<² |)²v¼Oìx‰TlÚxž‡ç¢…äs˿ŊÃ7cÍžSˆƒ€^3Xhe+æÃMëÂ$ R†görÇÿ{7ýkÖ1ãÉżéwÔãbU»侇Þìåôˆn] …p¥qÙ(ï¼Cø³Põn(´Öµå‡/©îù¹ìèyË{G=ê"R§à¤-hðŽ{¼àˆqÅ„?üÜúøÂÁVÛ¿´´Q‡ÂéGb–/ÉG¤/>äïX;¶¸”ZÕW*ÄßòÏ:#|ù’•t2]ÇÉñÙww°ü)ÄéGÀ9·ÁÄ—à©?û|æ(’Ë1Ê ¼™@.;¤˜|öšŸö9º{Ç}lûûßÖ³€ÅÜËcÜ@¬úâ¨Z¯<…Ü®"AÉeÒžr§QîyÇR¦í"oUÊBí¤”“bôÖ˜Ìk/‹‚”¤9“´à¨%pû…ƒ[òØêÝFóûùïfp¤×Šôd¯-„ê6ÃY±šÅD]¨Ü.O;0¥Ä¦Us—Óž ¨+ö’U]S¸sâT´Ü¾ù»H–*Ž˜x5ŠyçÔ?Úâ¬6â+-Çàz·%Y;›¯Yõ–©Ü_Û—-¯{†éÿ½¸Å«,äÐ;yN”<ç6‹dæÁ—=ïem~GЖ5®“ ŒŸ#7¤ &Šžh;`×)XÆ…#‹agá'J؃ÈÒ¸:o\Z£Þ„¸ÿÏpþµˆ]v߸q‰š$ŸüGÄ—uçʆ•ˆÜ¸rç– ™è”¿ÝÑ¿¶x‰á‚ÀŒ`ÔbJ³1^;žw®s@Wé#ˆR°÷ÆK§© ±ä ÌûÞÇž‚úÈ'_Ôà1¿:}þ™$«‡ùuñÖÍ Èhà¼ã”>﮳ôAšÇ@ø³Ë‘36{MbÄ ¿¶„!FxŽÇù&f=q…¨'qdP™W`A<1‰3‚Óȼ`Éñ–ûÀæ=c…›Ñ/®i—³w¿ç^7u…åÍ©Ì܆k^8œ¡‘Ö OD% Òhº+Ù(Œ#ÐpÄ*.ÿëSÑ–•ÅÚÊ<Ò>:à¿×N×;kËó¼vGs{ãüƒÑJòÀê}¨ >8í|6Q+ ETÔ /åŒ3™È´X MF4÷èbáë¶gíQSØêsOÑýØP¸Û¹éäIw àñ<ÙÖm„¦7†Ææ!¦"Ü©—çNݼ•CC÷üa¶üÞBÂ¥j É[´yH´±^k&Jäµ,*jüd:¾F€£) " ValŸ±Á@@¤ìûbõ"ô‡R¹ìjÔ6Û"Æë<"Œ|áÓèK.G‡¥R¬ÒX~#!qQhÕÔ¢0WWó½ñr¢ Ú9ø¹œ¦è»Ì€Î÷.eájÂÈŽ[ÆE¤­‹~pâ¾S ž^HõÿŠèînù =°ú§OC^økFúìš# ¨´¯ØäÊmÆ„1¹Á¡tnh¨(piÜù?˜»fS;æ„×$VŒú+ ÈþÿÂ*îFźU‚fl)I¥Ò†WU`Ãë°loŠ ˆ³V«L]Kxíy©N£:ãÛöÄF| oìÊRXˆŒÆTæÀ¾>éç’5Dzº>‰ß­<ЊÀ$ AÓSB%IâB§UÌZ§aËœSÞåò .hášo»¨ZùÎ)Öøä7“æhrš[WðË€•Mˆ“€¯¼pï÷Gú‚Ž®\AjÉ–Z\ëPÅ–‚3l"v,ÿùæÌ8áyªÇs–¹@MV"Ÿj[Ù*ˬ‡ò(p¥eÙÊllÓ£ðÌBšb£À\÷VÛdʼnãiN ³šLꔜ€fh׿±ÍÄ«Ö0áòazçäÊœ¸¸Õ5F[¦6“2ŽM‚)x뙟î}P×eÏžb¾]x^»ŒíkR*†JÂW,s"`ž}Ždï½ <ŠéW\ÑvL6\s õ‹.¢qÍ• ÒÐ}ê©) ±N•Ô*62Û¡•D)jzù´(8¢mÕàü×¢j\ÛÚ±6ݦ”þhvá Ôè<ÊFù˜‘=æ8UBCkô÷¾O8RgêÜ2NËN: }ÕUÉpjPi«Ÿž¨ÔÐÑv|Ll£Ùñ‰ÜxÉ"‚¦=ǵ 8åcN›l IDATLèŸLÏAúØö÷ã ©›Ûàl½’®F 1b\LaA‚T* ¶ž¹Œ dœ ­øºï}ûtš—£ßÔ ¥“,Œœzêbfáû2 ‹œnÓ=‚>ž;ðï뿬™HÅô"ÎT ¤±{ÇN'ŒN vR­pçñ{¡äQ ËŽs”b0?uàòþèë¡·cÅs sZJb÷6ßLdBîæ­¬näâ¶Ô ³v4S¢ˆuàî4½ÃJD¥Ò¤:­ÁðÕãÐ÷)z~²b¤–Qûfœ×Ù#r!,x;°N©s30÷èu‹yJѦbË‹M]źO>B¬õÉŠZ2BP²ùÒèŽ7\Zäpņƒºh<ý?›†xn"¢!­â˜ÖÈ”BÔ$ $ &Ž!Ž1:!‰­®€Ž#D’ ›M˧Eh ÑhcÐh£ÑKEŠÎ‹í< st*ÉCòJçyôrÍ\$W^É¢­¶b³o|ƒžÝwÇ•înÿЇ?N00€¬• z¤ŽH´§3¦ìckÇè85ìd)îê=é`Û8àgõAû婉—]îl>‚UîÿmLþÊØQ2Æ`RÊ hسôÐ]g†ÖÞxÑÙg3ÿúë©íµÛûÛ<ý…/ çÏG?>‡JX8BŽ˜LªV`ÔL’Ž.¢Õ q•g®ðQɺA–{,›|æ3Ì8í4‚ÞÞ1@Ûþ/·EDñÑDúiB£{©4šèºÌÄA\E¸A¨! !–î2ÔV5-4‘}/tm,fœ4£ I¤lÈÞ)ˆiKmªµDé$óгÅÚ%1} ,kv+•ð\us.ë;†¥#Óy0Ù›jÒ@™„qjƒ $±­²×&kŸ“Jg—~µºïg¹ù)|kç…—½ñr.ßq¡wa¬‡.0ØÉ+à´üõéØ@!uUã’ðXþ¼‹7›{ùü†ï¦aJa¥(= å¨DM‚zLµÖ ÖS§r@¦v!¯;>®Žã^–À[ î.|çÅ‹"€Ü»ÎÞy¼ë%$;;šqÍÆä…³þïbK^ú¢Ø«®³‚9«0gÄAÑÝúJsCA7Tá–ñññ5?ãw°u}¥ñôrá®81 #„0T« Âzd#›?‹:îfÌê¯!Ä„\°¦¤~U£»Í»èœ[m3Fò|ÌÄŸ"*MBeЫ«ˆ!rÜö-Þ9¥T‚´óSJMP‰ +ö|Ä6O#·˜Yp&~#ÊLOë$,©TÆß- 9‘'œb’${d"*Q„1&ýÌ“OECt a’õ¨ÚClyòS¨¾Õçªôuëp˜väZtVÜ5ž% L¸3÷؃°§‡î)S{{©¯\ÉS¿ú3gÚ–0¥Sİ«‹°VˤUµJØÕeÁ¼ZEwoÚ¥×åA(¦W|às®º§†–=÷TÌÐÚŽ3­I «:×læ‚+CCÄõ:ÍÁAšCCDD##ŒÛqG6?ê(6yãi¬[G<8H<8HEtMšDÐÕE48ÈÂ+¯dð¹ç¬a"%aw7•žj½½Vò¹VCU«Ù88ã¥zÐIbo›8ÎDa Øã¦:e Ó=”þÝw§±nÍu먌ÿªtaÌÆ–¶þßoßùÎwøâ¿È÷¾÷=>ûÙϾb9Ñ%pãƒpñlûÞ÷†›¢àUöT†xï.7„ã÷ø-ûmq;Â#U´‘DÍ0ÏÁ¦áJ%¹¦qV"‚0ÎB) FJeà$SYO©”õ¶\°‹²@Q"¸IÁÚ$ipˆ—ÀÒ/@uG˜ú•üPU%§uô±ì4ŽéØ §8ÎÀ¿`0% ]Ó§Ó=c²Ré8­,`pÑ"LtuYµ´0̔Ӳ1IÏW*΀)ÌOÓòÚ`Uu’Øïëê"èíEÕj¯©Øî ÿ·ÛæÂEw~}í«Š;&¤ú¡ÎãÈͮ⭓ï&ޤ²‹¤ ’˜AlUºJ^§1"“¡Œš!qØG’ydu©§U³ûÞW»íööãúg±`âÖ@tÅnÐ¥Ö„qdÃëqJ3«“¬ ͬ÷—;à¢ÕãnÓ?î/¾…°9¢mμt#´}íæ{C±g=Q–8'QŠD¦ ZÙF¥š>N àûþ,û-»=Ó-7ZdÌ¥Ô6­â þƯ»‚¿Ç1ð8ÌùHz×öI£Q%N‚¼ßÞWš3¢ çZ(úKÔÕ°‘yíJ&…è]o€¯€Úß°ÝhhÌ9šssÖ¶69Úb*‚ŽôºÄÀÁŒÿ…ŠêÕ·Ãò‹`ŹE¶Dí0Øú'0eT§e._ƒÛXýo°5X1ÿág +6€ìÍ=Í–¢«6`îrÆ<ÿÜ´â½ìÕÿçlw +kÊØ¼d˜ "ÝÚªEqq –4´ë¬à˜™ØKF»y ~ ^ÿK_Æ‚ŸgaöP_Ø–®UD¶û@kp¸±o«ÌVok„Ú €Î˹³¶»û`Õ!0ãXxÝgAU^¾óŠëðØ7`Ù50òT{@ìä¡ûÞy<Óç÷ v30ý½P{™Ût†WÀ‡ ÷C¼¼½¡‘cV}z÷€Íþ¶<º§þm¹‘x9àµÉc‹ÿ ¿º¶»ÁÅΞ­3‚ÕgŠà#ójàB®¶ x``“¹eø Žæ·œ8ñB>2)_¼£pGœQ^ø&´±EY‰)„N]˜Ý¤¯ÇeÑÌ-x`·}øý›Þ-âYÓvQ°aVêJڈƂ}æ…›œJ6ÃV! yr-[=«:÷úÄËÞøháx´Ëî÷¶»×Å¢<íQàzlwR"Ñ$Òº.§®¥$aÞöVPkg'nŇø%‡=u-¹ë–ÂW‹,e’)†ù¸ìRX5_A×_?qW=7 ƒÏäc]æ q¡»¡ Ú-^£OzÒîó°œOÏõ#°ï·^Æ0Ù?Ó?o/§+6"äÎ(€Î:X|"ŒÛ¹&n÷ò÷½ÿ}³•~>–?O?Õÿ„YWÃô׿|Ç4÷2X¿ÿ Œ,Îwüë`‡“àŸ1@åo«Fà¡e†^iX½!Aõštçõ™¼XÚônÆôý[Öa-øÉ×÷ fVîÜ›WìÆÒM6áýý—±­~:rŸM¬eñÑ  èNZÓj!_žæé ‚uÇóç]^Ç=û¾…¡®6ŒÇ$V·YÿŠ‹ºÂöÄ+‘ö£›´u.U€Ë*ÊK•å9[[^E¯QY˘3ˆ|Ò¿o¼ ä/Jgê‡Ö}0÷Õ¼üJ{cŠís>6 K§›IȦ}êF b‚ÜiY‡mäæžíÞÂÂM¶äèÙ—³Íóó7°ÁРõ±üzü~6tOøË'ïšEpî{`hqð\›{ À‰‹ï9¡F?Êd8¢è]–éi5pëwaH»¾A{µ¼e¬#*ð·¶Ï©Løãé}® ¿´ô²úÙh`YôÌÀšËgÁɷ„¿2mðì=pÕG­q¥Û€¸Åàð÷úøõ¡ðÁ›`Ó=þºcZ³~= B<˜g¶þžù<Ü}¼ë°ûÑc 0è¯Ì­žÀq7îX#&èÑyµ´,2é0¨[À’s÷#‘nË ‘ܶ¡ `1¢ߨâ4~¹é ݼŒ]'ÎåÄí/Í” ‹Œ#cЩ§[ ͘×ÒŠr?Oîr¡Æî8úÌÙgWVL›b«éMÌ$V·±–Þs §Db ø´Îõ–=¢-¤-2svÍæ©³œs©Üä”uÕ³z¹ú½¼`—îüãöE^$:K ØÞx‰€`JŠcŽÇÞØÐ»›‰P~ü¶›„¡‰=œwøIl³ðNþÅ/èÉ µ²B˜–^Ëáôþ²É{ù×áÑ+`E ÌKàg$ tNL"Û`·éµÎz«)èºRŒ:¾â›0Âá¶àëþ̳2ûÖ{™Ç õV"¡Òý³ã¦k˜¹ÿ!l¾ð9ö¸ÿ‘b:¡\oU–#í”?oÇÖ·|œùðO×À&[þe×ãé{áìc`à…V㣗þb)³ ~tìrœøý¿pŽ|¹Vþyt£ËŸ€ÿÞô'˜õYÿäò‡×Õi„f¯Y°ó~c ³‘ÛXQÜ_¹-¯ÃÉ·'ܺ0&Ðq–ÎÚ›¤$ž+0 ˆ.0h¨{RPÒ™ M¾·¤Ráè°´¤*"úƒAöŸ|'mù¶©-dÛ®'rª-xËÂê‚û@\ X²Ë ÖMÏÇ¿¡Þk˜¢Þu)ÎCß.´Ÿ²H@p¡Ð×±Ø9ã'#µ{w¬YDÁä‘?5Pøí­]Xµ¬ïíÔÁ ½õ©„¥ýwíQ^Èçˆo|ùV׻ޤ¥½le,~é±k#ébÏ;`ßKo'H "ÉEG2PqÏ_$œösèßÈ<îÐøÑ©˜».©s]væ)¯¸ö8ÆÛi˜·òÖE¦u尿JÒ’ÎÁ2ª„¼ðºMY½é4n?ùHŒŒˆ±IF5";ÍE÷4lFTë „0pÉ­ô¯^Ïô¹Ï£â¤E ·Å!§u\â9¡yÉÈš¾|äǰÛ[¡Ö½‘ð ˜{æ' šZ#^·‹´xêécï#à3¿x sdÎ:f_€qsÄt8†r”E›í_¿ ¦o±q¿÷Ìc0û2¸ùç0˜¶-×zaë7À1_„×°q]c€þêôü†‡ÞþöÍ9ùä=^öãùÕB¸xAÄ=‹#”I ž¯–’ዺÐÄ÷9eˆ”’Jj¦J{«E‡˜_êy.ÿ¥–ùñ®]fÏž9œ0ñìÿ]®õV7¢E¬déÞÓyü¨]xzßí0I^ç@ÎU*Ke­z6±tZ­®‹áõ,¬žzâëZJ!êXét*kIKlõ·ð˜û‘…6½ò>Hú‹½ŸÇÍÄd<Ű Ð=`wLxBj¤ô^§=×.<ŸÓyŠc…‚È6`”µà¹k•) aØáÎ'ØùÊG™4o%AJ»é€Ä[@ßvœyÕÆMÞ¯‚¾áçèЦh]g›IE’T4Ä )Ô`‰6ÞkY¦(*ðŒË„Tj¤¨t%àÎϾz­Æ¼·n_¸¶~§oŒ‰NaÃ(sÔ]gØîž' £ˆ7y"ÖЮ3Ó%EU êŽrT´‹œDÀ±Ÿ†/þçF]óá1ÿSIYëJiãSÝ–sê~€Oçc[8÷xËáðã«7nŽ|ãc$ןcÉEµ8Ñfonn»œ{+ôöþ[~ó™#1+f2ªÂˆ$ ?wò„OŽ¡ök ÐW­á¸ž[ny g|k_¾ô¥7½|Çò¬æލ4IŒÔVª´¹¤Bô`Èàµ=¹+Ä©„ÎÝ)EHW±cþÎÓK,“WkeŸ;¹¦Ø»Ô°{å1>×ÿ=ŽU—ä@–—s³v÷ nÞËÜvbÅNS20õùÚ3æ·”'^©¤-€·hœ;õ6Ýšפ\ñÆÒ†: Z¿Þ>¬§jüü¾äþ‚ï{壥ÃÂÞ¢éílù .<@9Ò Òjm)uÆ  T’™äÇßÎ+÷ÃûþyÄQPÏW“:{|û&Þ³‚êê&AaÓN+ÛÏÐï<ù“ ã'vðº†0Ÿú0[/eIäÂÄ‚DBTñDC2e³‚¬i»Î+L)$<Õ8 ™PcÝë7ᡯíkçª`x:²!ÚDRDñ:¶xçÞµ÷kC|¾U÷½J$͈ݾwãï]A°®™‰Øÿö4¹‡î݉–8¹Q,== ‚äèRýÏs C¶Y¹‚æÇŽÇÜ÷tÅò¿InXÅanX%žú˜EäÑ™JƪTtF&9ÆŠľ#~~!Lì0G†‡IN;™èf;G*q.àóéô¥È…ôŒÌˆwÜð×× ·Øªý<ôñûö#N†<žv¿¸W ˆˆO|‰Ê—ÏCî×Rý”SþÈ-·,j€ÄøñYsúéûÐÕõ×r48į†ºøîóuj•&aISÌ`à¿û¨Ï©‘,WÐmr×'ÀŠeH‘Šf8‘ ãåó:kMgoh´ËX’{’>ÒV4m$›=9~è·\¤>@ƒüªç4ºº"’qЧNŸÊÊ}&10¥­%=¡Ì›uUÕN†UÊ\WÝ ½”sÁ-¤î¹ÌCä‰V9w¼÷\ki£Y¼]€Mê¥'ÃåšÕQ”ŸŸ])mᤓÛu†R¶÷¢#è—‚öæ—‘©B˜W Jýq\ A[¡£ ¢:w=ñO×ݯV˜TÝ̓6)§ƒHCÜ:ï@õ¯E™<™pë­‘@ud3gyCIeTc÷&h 2¥ê-º›VüÇ*¨¹cQ]Ð5M¢€^AßO& ° ¶}}tï´ˆž_HýÒ… ÿj…!Z¤¡i]§têZ´/n^ø_é\ÕÎ) i@W«Lzßûˆ'Ndåå—¬^…Š¢LuMRôC €N±´¬ÆaÞ¿7ðï`«o~“q;ïL¥¿ßÎÕ1@åúÓÏ ²ý7¦áhwGÈ<$b¾ö•]ø×¯í’ýÍú'Ÿdõý÷óä™gÒ=q"ÕñãÑÃì~ðA+V ÂZ_¿;öx.øÊ7é z$dèî6üi\‡ö ZKye:Ý{> ¿hÅŒ(µ§ˆ|ïréħ^p•J³=ÝÞ¶×üèS§R š¶­äŽR6¨Ä IiÅ[â$îfÊ …9 § uäqà>½¬/ìá¢eþx­K‘CK‹]'/¼~÷¹ßÛ…ÜÛ†ßý0¼!§×&•!/*Íe€î([0‰ö0÷ÖLj¥ÒÌ>g´ j†4U’ØŽ¯óÚµ–„Ajµ:•Jž¯3ÿdÍúGc’f³¥jÂ;ßÉÚÙ³!Ž[»Ñ]]]]„ÝÝ„Õ*A¥J¥¯ »›jo/²Z%p""• 2å—ŽwÛ I%äR4Í…U‚÷^‡yÓ2††{2=$±”ÃI¢r W9KQGùh×yàGTü¬ÖÂ7S‚$±#ኟ¾ žz¥aužOù}/ënÚ ÝlZ¡’‘«ì5Sá—a+dâ] DÝÛoOeÊâ•+œ?‘^_/¨utU ª5TT«H ªUË ¯Tv „”–{=åZOR!š¸Ù$‰"Ôøa&¼ŒÊVŠþ÷׬‘íR\ºUhɵ‹È­ùy³6báϺI R±¼ôéï§7@æ™$A'š$j’4#’TÐÅJÙ—Ÿv…û* jUd"U¾N.ñÄv’ô;eÊöôvwcŒ!¦94Äpa¦Ne»SNa»~”®3Ær诤í3Ÿ™ ¢ËóAüþ“TÄo/]ÂG?¼-›Î°¹£î™3©NœÈŒ÷¼†D,»ývÆ¿ë]TzzPµçm6•kvÙ‰žuC$sË/œŠ‘ÐGg@ÇsƒJÒ•ä7C™5« 0Æ3Ó ‰HÐ].=Ë©w2 Šû;Ÿ~³¾y=Ùï¹vÑTš둇*Bé„ ¶ýõ¦aÇfTA7%&ÈH£âI+¬Ù*_ZÓyæn!Itæ/‡Ò -ge¾†N IDATù6miÎ ÷«èÛaûzVء׷ÀMî|rï< Ë ÏZûÒ|f$¹‘¤‚$ÁWT%É…u‚83ˆšQ…¨iS#N`G úÕfƒ@Å„4»]±è‚ýY7™h(°êRCCDõ:ë7l@í¹'B)*ÝÝTúú¬ºU?ªZµûZê¸q¨JU«YàN\2ÐpJ_ÂI·úÂYz#ìø9„º9ù|š•aâU 5b•eœ’¥­ˆ.?î@4K[˜`$ékãåÒ½|zÁ~-K:ÝE~ªÇß“Ù"2Kq„A”EXº7¢÷„ú^¿5%ûEÛa¢ÈJ·& ÉÈÍ⑚6×ë4Ö¯'Žc&í½738‚úòå,¸äš“'Ôj]]tOØÛkA©§‡05²ˆ )‘©Ø‹ô”Ç„™˜ŠQA/ñ(ãv¿ƒœ`—h¥½Cdá>Jç¹/},•fú1‚0L?²&bÕíïG„;ƒŸ«¾¹„S½K âQD48hÇbhˆhdÄ*·5cRÉØ0Wžëî&ôÏ9÷[qööz…áøñl}â‰ÙëKäÂÆ*jk,úå4êók6Ù—…<•Û‹à)Þ.wnFÉ¡—Y” å2`/yõ£:À M9ã÷_aÑÚ-øç7ÿí§Ì#ÄŠ¨ÈXçž¶’Z Ë8é ÐÑV†UiåY¥”u!u'ÚyC:÷ÆÛõ—¤$רö[— Åo£xèm{¥;‰ç…ûýV~~=¯¶6Žåž¼ßÚç€]ÉÐ ÑèA‚ª&6l_5ˆÀÒ«ÄTt3‹zDQ˜u-¨4,à áÇìøÁß5ßC<éÜlÑs’’N½ËyÕ2õ¬…(g`íhvÛÈ³Š²L«¿/ä¾–ÃâAüº!*( A#.´wfÀ,SIR×i·@ è")ò¼èõ6í¯½ÏYà@€ûv|ÏNÝ*[xkÔÛö_ÿÖYìöìcÔ¢:ÿxóÔukLx×ÃÏ©ŠÑ¨Ì|A_&ÕG:ßL0¥ä,•~3[½=À¶ Ÿé¨HÕŽ®6 õ·k,0»  û tþBé¢Rè–^vÖtD=®XÎ…á[zª;E Åü¿ÏææÑ›¿ Û “vøÛÝ”/ÀõÇÀò{ZE’åÉ3Ðp=oÏ™H;½Ì€¾1#Jã¬Ûü¶?ÞÔàè?ÀÌ·üm•Ã5³`hQ{JXQ¼W|ÖGž–ƒ6ºï-µ%¦ÃcûaÇ„­ø…_/=bŸ?ôCèš ;S÷„i{Ž¡ø«-äþ‹_@%´Þë¡‹À+KãÅBZf…@0waÌu7sú©ýy:Íí<Éy‹óÈUo¥¾¡†è3EùÂvbí½‹¥êô’ VVžjk1Å<¯F=ö6?Ñ:D„1\fŽáÖø©øÇD—åÇgÈ4Ô÷-´ÉŠÒo¼6VtÅ{Ëi>0®k<Œ'wØ‘>Ú‚tÀ;†À9ûìÊ¢¶à„K~ÃæÏ=G­^߸~´ÊxÓÜËä5ft?S•ó ·2@O=¾ÌS•¶ým£0,³CL~I}pqûk?Î…ÞýÓ_Þ›.‰àŽÿ‚Ç~+må÷v,bi´ÂÏ áõK·ö—ÒBìE`¢\{*0è’ÜB[@7u¸à8æ"˜¹ÔƽÌ)àŽïÂÓ7ÂÚE9Þý6>‘Ï“®íüCëµ0åkÒŽR`Å…ðÀMpÄ/`×Ã_žs­ÀÒÇáæ/ÃówcѼíÑ?BÿVÖˆ8ìL¨öŒ¡ù«Ðç>™0ÿya½YI½ôDèIB¥($TΧ>ó/ƒüÓ'úq5÷˜‡9gé|n½áºŠìÓV9KåRž-À]øBϸ)zß0É¥8qÚ¤<[@F9Ðôɲ¼hòN€.:x&õµLà8s1]ËF˜µîz[Åž†P°Â+®ÈÍñ»—¼¼¸þéà7q˱0™U£Ê›Žöoe†5úà²ÃÖÏ,àø_ü–žÁ¡ϹšÑÁ¼¥ÏÝo›óxã Ÿ£Ýõ.ògáLȈzdJ#ÛJmê!·ºãrÜÝŽ€£¨Æö|ç@xóIðŸ~ynº§þºnÿQG01i]ª–)å¨)2‹A‡ÎM³±©Q>Ó!Ö1ZUúþB°‹"k™oK‹rDÄË^€3ö‡íß§^½_ž1ð:8óмáºÃÃ1¸™²˜N§º„î¬Ç#*3zœù>8ô xëq°Éæ˜ÂÞßTì³,oËž…'KVÀ'/…°:è¯ôxôñ„'¨…`*6w.„ СÁH´S@SžÆº%Ï-Öl½ÜÞx˜ß¬œÇ-wL,To’±ÉœÂU”<éNâ:_2 m­íÃä"þÞÉœ¶„¹Ê€ž‚º–Ò>R]p§½­Óv8ãƒûÆH0z Ð)X¦zéÚêqßDž}áH›Ëì‰-¹Ѓ҂aÚL*St¥mN cTb[u¤):9¨ cstmÃÎÂÓT÷ÝiƒkaÁ=‘*(eßñÆæm´•3#$Ñ ˆ>îï=‡¿í®ºúH6]ÿB®"^øÄnõ6Öì0‰y‡ìÀ#‡ìÁ8µ¡ DÖNÜläjÞVm ذã8®ý×#Ùóü{ØöÚ9µ¨û¡E¿a¦Ð]h|oÅ´0÷J°2,-ŠÞMêÑÏ9qWFÆwñØá»‡Aá¼Ý9]ÿU[8añZ¶¹g>S_Îf·-Ê<ô$¥[È<ß3¦áT˜Ã.¶~þ#X°ý ìÿž—v£ÅæôãÑþå =]ž\ZƹL-Å.Ÿ ÞyãŽ_IiÐ&ý’¼óv×±œŸf)ÿ–Ó?r€žx†‰ö¼÷ÄqEé” 2ñÇX:ú<Ð ø T–-&9õpļóœ'm©2ž*oÙ o‘¯m—æ(†ÚD÷Œ—&q†£Jr‘šÌ€\ú æSG κ&o¤ú¼'ÐWœ‹¸ôL˘ç_S_ñOx÷¢/c{éo`ÉœuõkÐ_ñEqᔘ¸6]M¨W¡^³½®ªLï0i q³‹X×Ð}#Ð=bI—GªÔtÞS5C[Uã(Ó#ͰbŸ—ó¦%0w!ó ‰ ¢Øî«‘®´t¡Ó^PSrA1äÞÖC÷Ý2¾z€N+ k%‰U=¥2ñ¶ž»Ë»yÇÄqAþ4QŠVÌåʳ`‹• ‹êKª$ñ˜z9#ÛörïÏ`¤§ “XêR×{ìέjÛhÀ^öÐý÷ …n ØüòÇ™zÞ“­„|¦ntXè|’‚òV‰K»åáq G›ÔذÇ$ÿô^ŒôweÒ±Žî4Sk³I¡ ê1}K6°ëãÆ¬Êñ,¯+ó…¡¹}7‹¿»A%f\´¡bš@îè›?/»Ï<°á¸™T–®§zÙÒ´p;`I™ÈF”s«%\>qkœÁ†]&¡tBo2Xø—¶h1æLžb0Àl)™sΞLùý&]ðÝ·¯Ë<´ ØSoʉ¶„M«&K$ÂG> ï¹–q?ú¢¯¯3¶\p>Ÿú0*‰‘dêêÝV ¬™†b]=j&âXŽKî¼8‘´ÉAK²áé@¦Ï¥}-SµBáí³‡7ýtXÊ¢†NB’T×4Ööy¢!I ¶ãÚeþH¼pv"‹`±ïeáè$÷Ô«u 4Æ@4ØÀ¬\BýðÃè½êZÔÎA½qÛmŒœóS’ë¯@¤Ò¶Q qÅ*⥇šƒ³i¤/GDüGK´©˜‹ÖçZŸ »§ Fit(X3ûAâÛ@}ã›ô|õ«mÏ7yæêGA}±s’TÑ-¨ÑqÊæŠž¡¤ó¨Ò€ Í .c¤.Á%c€þJÛîzL€ „ªA˜€  T‚P6™¨L‚hƈ(ÂÈ ±ªZy£@@ ©_ÐÿƒA‚$&R¡¥¡¬$ °ì]*×ôv ’J,%j¥Ñ$Ô¡Jœ8t™ê¤»p{rw¡öl!O ƒB»­lhÌ;ÝàåÔ…´áv!‰TH"Uæ¥G*$ ìÃE´*¶ä90Æ šIF©tªf Oí´»_ºˆC!_úþ§PIœçS@W»Thž» aE3ndCÖžU5 Û¾åŠèÜ#åØ.(°¥ó.”_àõés/k«‘í$±¢Ù¬èþi*Íî˜ÆW¶÷ÖÄ(!øvž)e.J^½ú•Ý«pð꘎L½Ãƒ9ˆ‹œ¸C™"{š)çãeàsž|´_«öß’I§=‹œ]G/l’c'¡íBXI=t¼…=YM|Þy¬|ôQ6»ê*ª[nY8Ýá9sXxਕ+hBmµ†6I𩬦n:Q—ÜÓVûwC¿bä[3I&U²ÖEŸ‘¬úB“)ß 2T¥{n¢Z0€J`î%w\v‘®a˜•hÒÂa¬Ø¤:"Ó!Êo•úœ!š3u¶_ÖÆ™]§^÷¨‚ï–êH4?üð€áwM‘­Á5žs^vÈ|ÚAt3 ±L¨ÙNÏgJ[ÒÂà¦uÓöË&üÉf!Ã&ÒV‹¬ÕÂÞÑÏÙîìw±ÐZ@ßt³çœÃôÙgck5ŒÖ¨v›Ù«®B4ÈZ×löÁlê#e‰¿G#–±—!ˆ0ÁŒD„Æv:å&«:º'WYv¼+&nYÒ;:L|ñx„È=•¥ôº*"ô\È sµŒ˜/ôüÑæ»]ÔrµÑ:v ©ö ’fk‘I’?ŸB–!ÒÚmD’àšM\’`Ò“t0Y«…5+ò׳¹ý©ë:0Æ ¿ð:/y c'žHsa°^§yã´þã? qiŠt®Kas~JPÆo§âQLX¯!bïÁ¯ *^œCN xåÉx¥ål¿•lNÇ+¡:Öâ´öÖµYiê79i YŠM²$A·Û˜,çJ0®§*iœcËûÞ‡üÒ—ØçOÿ”ú¡‡²áµ¯Åþú×È$éöžI B3Ž"o B.t³§ÀX‹ôµ×²ðçÎ!—\B¼z5*Ž÷ úïòmû"ÜÛò×?„P„aJdSD`”éÒ¢¬†P R™§iA¨ýV3ƒöÏëŒ?v'áx†V2²>Ýû ÀhÂ4#n{QŠIɈD.èdNû;þ±re»uó""/"ËrTÍîBÐÅ€Zz!èäŸIú¹Ýnw­©!Eª"©çbžŠÈßeD'®¡£ ¬£+m|„® a–•#j¡ñèÏH¥è(àß_ú—l_1É…/ÿóRÔz¼$’Ø…6¡ÎcŸ¹¨Gmjt@C¦=QÌ&¡¤”žÓK@-A¯‚N ifĵ¤K,3‚Nêd ³€ZÔaå+ÂÜñN½{÷³üÚ!N>Z0téA||ô<œ¥¸):Ž/EgôöKT¾c+%'ð]Nw×–ý'¤ßåp}[%ËYRï¢(%>0C~,Áþð@ÒÛE¼¸ˆîtHççI :ss’$èN‡,IÈZ-´Ö í»/Ѻuì¼ë.Vz*íM›˜ýþ÷?õT„1l¸òJ²N‡`hˆ°V#¬ÕPqL4>N<6Fmb‚áÃ63ý··¤!Ye·³ƒ±ªg ¡j¼S¸èƺHóâ+ˆ¤ ü髇÷F㢠í{¼åwiœT¬.ÒïÖ–bÛýsžv¯¤à…µÈ,CN]‡£M`Á…Ó5¬ ÑÛGo=˜¬Ýöt³fÓß;:;w’5´ggK[Vóv›`lŒ±#Ž #q³ÉäqDZå‹_$ít˜zæ3Ùü•¯°ã?ÿ“ s žŠcÂzxlÌÃuFFü÷1<\‚Md jµ¦S¥áþðBJïÑ}á ¯õøRW´.ù&I°Z£[-OœkµÐÍ&i£Aº¸Hº¸H{~¾{Ýj‘u:çpwÝÅÖ7¾‘U§ÆÌÏî÷´BÖëDCCHEDµÑÈÑø¸‡¯ÔjÝÏTœùÄd™ìt0YFsËÚÛ¶Q[·ŽúÁóów½‹¿÷{ì{ÖYÃÃ{ýwõö†ObžkmæS¬Ê¢[æk øæ.«$&ÂÄÏóA{¦Žk ¡ ú]ÄZêºM¤Sb›Û„ˆÔ ºÈˆdJ óÚ¹ÊPΠQÂíÅ1o„+GÔ*5ÓRÐwÑ›8PÔ+:t›äz]¥°¡z#táɉ\JFè£õ@úRAâË aš¡ŒßœF£BŸ Ë‚X¾÷¼óníà©—^ΡOØÄÁ¢Y˜³^¼X%þ®DÑ&2µÈÄ¿†ÏËyw9¿»ïF¦Õ»`b+eÒƒN•CNjÞ=®ù”~”¥¤iý§q–t4] ‚µlûáQÝù¯þã],ö•oÀÚJpΖ  µ~“¶m(¦H>~Ñ hq3ö¸udÙŸàŒB·Û¸,#m4r´gÓ/Àí6í¹9’5'ŸÌä±Ç– øÂ’îØÁ½×\Ú .ðR«ŽúvxØ/¾j¡Õo$˜ÚL²=·ÿբܜº*öWô z1º§”)þ¤Ò¸ýßöXÄØ¿@0½Ʊ[@É®2*Îöº8–5vÿ(²MÓ€ä-` C¿öMýÿT{Û^Iž„I‡58F°9MÌt:èV “¦¤FI]K=äÖ>ñ‰„ããØ4ç˜<î8œ1Ìþä'Œ ÁÄi§ŒÔëŨ…ÃÃ]ÑVªK ‚nä­T—Š—‹7Bt¼óA‚^¤Û«ëPŽ¿ueî»WäÉÞeºÓñXÓ+ÛéÌÏ£Ûm’…Éç„`¿—¼©”?§††¨ML”(ß Ž‘Qä?£R>Ë ”ØVQ~w.·mtÎA5›XcPÃÃÔ÷Ûƒ§§=míÿ åAÛåþÎÛÿš™Ê9èzÖ&v ‘Mq¨ )[hC›"S‰KBŒ èÈÍh˜v=Âî\IÈŠ'lgÅùÛI¢˜$Œ½ I”¦Ä„(ë>FYJh2"únv§ Mæý¶MEÐñ‚^Ž‚Ñ¡—Æ#•†¸Æ2a¯¦Þ‹±¯ž®÷üg-¬“è Àà]‹J-]†¤QDD$5ŸzÏ¢ùå ¡ÉˆÓeòÆ?£±J"O»§q„•„œ÷«›x[û<ŒS4#ÈÀ{•׆;¥‡¹5’¤{l­W/®r–¿ÌÌ䥗¥‘¿(3/E?Y­ô© IDATDÙ3Q¹šEž?w+“mœ;s•ÏDYŸÆ•Ÿ `êU°î’ßèZsù†¦$~õß¶¼v^É÷pNÐIj8Ú½›°*Oz@:U[Ü0ÌÊÞ ƒ¡“`üÙ°òÿ=‹Ëæ7Áâ¿AzûžÕ^ªS.ÃgÁAWywÊ|À}Ä)*xÔ=¾Íš?©§CýöÞþïÞ¼Mq#] ´öë2B›a¦ |§H`5*8%PÖú:s È¢¬–Ï|İó¶q¦Ò9â‘„Ðe¸,GUšÔß­ÒC2b¡‰Dê£D›§Ú󺔖@zoni{;ÚE滌Ðû.ðêøY5B/…=ÜTXçSîÖÉ® Ëü1е 踙 Élèe›×x•#¨û¼(ó›'ÕdaH]¶ýæA|ý°ýyצ—óg·}€¨ÕRTh ®Ñ€HÒXDš3šM^ws9 Š^êvÑWxŸ«ÐNJbYŲ3ħûõ½EÞ—Ãø‰°î9èô»&W1Ë÷h°Qš8 Ãdž•(^¿$Xåï’çëó2ëRitìŸð݆pùÊçÙ”O­8ŸWß~ uÓæ¡³ÿéì,°õаpèëA>°Úá²BnSøÕëáîwâë$þCÈÌ×ô¥³ei¤ÌD׋á-šKévñKe{Sæö ¾û߇¼ò¿þ±ã'pÏûaËe½3ˆƒRú=5úª°6û½VžÃ>€.º ð]Ýl;~ w¼:üûʶY€ðƒ †!Z‡½‚?f¯Êíô Ka‰Ò”(M}”ì2D¨yZÖ)‡2E >gzK ÒZDVöí¤d&¤ùƒaÖžzŸw³Þ ,Ò]A\Z ºÆ :¾£=yd.´OƒÚÜÖÓvÓëå˜U¿Í«ÛM}Öõº¿Um`#TO÷{‘~/"tksADze‹zBžr'EÛ€Ìø:‡ÈA^Ôe` ”&ÔYÙ`UvJé<:¹fý™Œ6yáMFµÍÒ†%ëqšÂ:d’ã‘u²×Vµ/BGt;à b™ ô¿)Â¥sg娗ÝiÛýaX}õ=>ív’ñ¯ÜÉul£‰Æ!ˆ€±Äµ®ì“¨{1ߟn¯ºZGç=7 ‹µQ^ùзpî]WqömW³ßüÝž†5óVhÁÃ^óÛ½îny;Üò–ÓN{/zÑˈße„Û¿qëÏV¹̼²q8òÏûkÈÆÏÁ ÏÛ\êÉP<.g9Û_¯wwÂ=/Ñ£áä«aô¿á¹í‡ðËÂÆK—±CÉß×pÇïC´NüwX{ò^¥Û+è¿ã·Ñ<:7ššê ã#ëq¬z$œõ [ÿ[ÊjÜ[¿ú4üúêÊ&3„Ó.…}†¦÷ªë^A¿ºÎ§vEJ¤|íÔ º@~dÍIPÖ¢”FHÊŒ¯cHki‘ÕƒbB‚íWìÐŒN,–il?kî2b×Mµ+aˆ\êëæ… KSÞ¥õƒ¤Ê™.‚±²l÷÷VÌ¢W£v+¼ Z™cKóúºuùøšU^Эòf3.@‘bP$6öixë;â…W¹(…½ ƒ©À”ѱt¦¬ùUì{G=†•sÛ8ë+Ÿï$ Bç‚n NTÒì¶×`F  ¯F¸Å¨š òQÀÀí¹x1»5óMØþtxÉ7ŠžÅñQ¾Î/ØÂÚÔ€¸ï½íÒÝNô Wõõ®ª›´þìDÿ&°Ú9^Ý(ð³CŽæŽ}æØ_ßÌùŸûc_ý«à ¯ðãäv×÷àò§Ccg¯øU|ÃËþ7×;›?p“º ~¸ÞÒ¥ÇeðÅKà;‡ > ë~Qol‡KÏ…-7÷~–nR… Šeö×ÕÓ²Ÿß`mwÁ¥çÀgÙ÷À»sÞYåŠçÃí×.õ5ß“¿ëÀ}ßíçÁÃþ÷’ßàýXhïôÇoæ¦Áßé‡Î‚O†G_|ÖobÜ{ûß#èŸþô§Y\\\òüüãîÆ!5Ñ¡&;Ô‚N B¼ {O@ï%î#t!L³r4KÇDÔbÚµº8ÇÏ~x4§Ÿ|m™Œu.è6#r©t|wqh3”ô‚^¦Û…ç[Wë¦Kª?R©Fl{x T~+s\©ô+¬^̾¾]t½kôzæ|´^DèZhÛµºuN”XOaò¦4ã;ÊU  „7ï‘\Û¾wâc°Rò´Ë>Ûãs_×äŒ*rtÙT­XF ].ì…Ø/C(+Žs.ÞØôØvüå•0ÕJüŒŸs7q÷+–q±$®’‚/Ъ½‚\Ý¥¸Aï ÜÝ.…}àïÄpÇQóÖ£.æ‘ßý1OûçW#ï þáþ_Œ¿¼.y<ØÄg?*0ªjÕ w)¿„#VÅ2w•Ûî‚×yäýÓ"?åføÖßäDL=¬GþÎÍþú@®Âe–x3€DfM·ÂOo…;7‹.}`$°kÞ ÿ«¥œþŸû÷½®ï»°ÀæÀ~›fàYo~` ó‡^ßøààMEu“6s=Üp=BR¬’N{ÛÖЖ e-ò)âPf¹E¢O¹‹ÀÑŠ†H†cl !† ÖÔ“6¡ð·¥ Ó{WÂÊ\Ћt»4]AÇ–›‡=Yàúçu«âáœ`>›`6æß6<{¹ü+˜þ '®ü6£ábé¾V ºðÝîZzÑÖdxA]â£xãÓòeS–eôQŒ#)mP¡ŸQÂÌ‹»°KFb¹ý„ÃøîÌ ÿñï£RSvø;|}q/ÙÈì.ÌsKkºt|‹ÍOn[™Ût Ì|žpœt.[¹—or ÷p7Í$b—Â=°y Lljeô¬»Š~ä§XÞ³¾_̉~ñxç ñé‰óxä§¾Äú«Öõ2£=Á›¿ oz&bÞ‹¹S]_íÒ?\ôú´ ·¼`ïNЩÒÍD×ÕN™ŠU¬›‡WŸoü þð%ïY“’äX²op -˼‹ pÆz`ý’ãyÛ£-ÝÓ†æ[œxéõ¾ÜÖL Ûz 1z]Ìp9 ¥Ø„Xàꃆ½mÏEÉÜþñ/¯ñðÂV9Xº™Z’)`)K ´Ü5ÀGßLÂÓÿÂ;lîÉí‡_Ã}ü-ˆŸ}=O­÷nÀf+ðž‹áKWÁ+>ëö §À9øê'ásïƒ_~·ûü—ÂÓ^§<}¯bïæö [{ÏÃþ½m£­E†²õ¬ ¡ËH¢ÒG¬¡M¨' "‘Ô;RM3&U³#Ól_Esx•j'í÷ >}#J?šæ|T^Dä‘I‘%²)RÙ2Ý.¥í ºè z½t`zv·¯l"ï¾ë/tI÷Eþ¦â9Î\{ g®¸†PdçMI´ðcxZhã£õŒÜt&ˆ¼ÈCt›ÔdîN¦r!VÝ&´ óÇ¥*0åpÔg~Îñoù~WèJÏl×ÅUŠ>éÁyÏ‚e»žÎÕûÁ¨Œ# º~ÔoÓ©2ГSÜþíåf÷uZngÙ|×cQ;À{¾:VXZÖº®•mñçbcÖß)*çEµ3¼´·•¶·c|^öÕwÙ[õŸ[yüMbèy¯ÝýÚúÃo£_v6jaBz/ñ,‡‚Pµz-7”ƒRîb7z1,¬«A l˜æT/nj-¼ïsˆc À›¹—›¸ÏÝÉn¼ÉÛEcP¿‚C°ß·7°úg3ìóÍ{½k¡·< ºô5Û÷^ƒ,w ééï¾b®u{ùû°o{ Aq\Ð9¤¤ÜìäïAö y±W)wÂúó[å€ ¸½ñ²×íþ<øÞõ𢳠mø×,6uªÂm kÉZøº—e ný¡ˆú ~ô®?÷uŸA¾ôÜ’(W-ÓáÀ¾ô-ˆ'ŸØÿà½Êý¿­†×:Dq‹ºi q!!&RJP'%Êøm©$¡Ì|‡´Ö˜P(MÆ´ƒ:¡añÃÆ£ùýÑ ZD&-ÇŸ ¿ö@êž] Sšd(™ ¾a̧òDOͰGËr g²5¼rã[ØÚYE0ªKôè’RmÅqn'ãüÛögóÖIœ=}5OûF( ão4£Ežzw©|}Ýx V‡·-êñÎúÔ»³ÂÏ”çMiöV»‘I 줩åȘòým={?Ÿ?‚þñ6\j»ÜlU¢Å{¨NƒD` S»àU%y© ¯¹ ¦°Â{‘›üuŒô%ÚìnéAÜ£/¥&5ÑíR_NÐË;Ò­Ÿ¿¶&pÓ=vƪS z_Æ@Yœª§~Þø§„)-o…r½~öù¦q˜‚Öèc¾?}빜Cx’Ášùî·Ð/87¿$C Sï#^,Ü2G JÓ]Ä1jè{ˆ1u,h›1²ëîå¸ÎÄ–ûhÿŲøÙäö±¯“¸6-¶ãLU(yàñŠs‚ÆcÇh ×tkéÚtÓð¥ö"êÒa­DiSN ¨L#•#2)A¨‰MBûÙü"BxÀÍŽ §f?FÞ¼Á/†ªWÄw)æ=ý”Å YF…¨{Ã@Í3…Ä:‡:çHkóç¬`Ã{ŽÆXÅ„™/7cýÑZ1Nf¬Âo†c´ß…&ë ºí zѹïúÒ®Òqµ¤ù¯:s/lwT/v©l™%) 7å97`ûÑÓ±Ö1£?Œ’÷°JžÁ(ë9ξÃⳞN0³Õ#RH$Ð!ïGɹ€S²°=$I(oJ”µš=Ä.ÄÒ”p2Qa˜¹iŒp›™ó¾]›q³SžªÕ¼h ÛÏ›dçÐ?à2Aèy¸*UîÆ(–~‡ýà£] ~Õ‚Ø­þþPæ~º’éÏnaò½3eùFçå‚|ÿ†Ìy0Qâ¼÷ý¸™íÈç<‡Ñ3Ïìy­ô–[˜}ƹĿþRäØÐ°K³³>>ñ×x߆¶¿Þ_f¼*µ~‘›½E‰ßd`ì«^‹Û°‰ø‚ ¨|oûúëÙùÜ?"Þ2K&¡S÷0žbh¥€Ñˆ>1÷A….ÌrA·À÷`Ï8ƒ‘Ï|†ð!é–H6ndáiOÃÝz¡…TùMƒÓÝø'È7rXp7ÝJó)OÁ=ýéL¿âÝã÷‹_кì20ü'BpÈ!{Sû§O9±í>†:-”3 éI#„#‰bÒ(ôŒn)LÊpÒ"Hõv,„:ó(Q$ÚsÃSl™\ÍÖ©U ·›íx4?ä…Á‡‰lZΙ²{WY©råzÒÑBt£®ÂÑmÐÈYµæ а#¼yáU|iáŒR<•5¥ñHáû]]˜J¿xÓ…ÀKz„Ldz¼oøÅìkïA`3éÅÜä.r.ï€^Э“X-»‘zž[4F¡S2¼ “—(ö¥‡¸žE)õ¡6q””‹jágÚŠð[H.Ù†Í\€»åj®n@£/­X,$eôX¤>uÕÁø>û¯XAg~žta'éÚ&'Öi\¼†8'"ÝóúŒŸêL‡d™¿ë,ð‚nüÝYÑK‰sb©  zÆ*Ííe£Ÿ]&záw.DÞøW!ÎïQ)?q ‚¥°?LhK+]çÎx÷<¥ ‘¬±vç›Hþ3DEÛßñô7¯'Ü¹Ò J±ñR¤D2$”a  £j5‚zLj(¤3?Çöo,‘ºK6h•2ITfêècRz_ôvxëÔ¤ÑÀXMf3ŒÑ°ZÂcjdoYG2YÃ*_J!/ìdˬ†œZ¯¦ÞûËVEƒ¦µù.w1,D^J‹Ð–x®ÃÄ«w ~b1›<‰-s«=Í Ÿê.‘¶´ƒÎð0kÞû^Âý÷Çá[}¶¿øÅ˜ÛIdóÔz…žõ2@I‰ ‰D A÷Å©å!)–œf=ÎZ["u‹ò“µ¾'´3>Î~Ÿø"˜l½äÄ„Z\D¹cZ €Èîû‘DNs+lX­+ÞE¾Ñ«4æiÉÔÁSžÂšç>—­W]Erå•Ô·o/é¸EFµ¼¦L÷¼qù{nU«€¨u:¨¹9ÿRÓÓ Ÿsã^Èø£µg†={#ôÿù]Äm†\ËïAÃñøԢ²6.å&GHŸ+úYŠÍÌîÆ —k:¬ö@”¶Ü–X‡3‚`R“}°Ft«"úî8úºõ¸…ï'¾°@Öi“.,’4›%šÔºÙdÛ…"ׯ'±–hófâ¼l¬òã&Rj5¢Ñ1âºß4…9”%¨×»$µ‚œ&¥ k±iŠMStq[-²Æ"Y«E£Ù$k4sá…èPÉÊ‹vl:7?g¡þLPÏtHYcþß3æ¿fDH42BX¯#cÿú¥Ÿ¼R%(Ehît0I‡¬Ý&k61iê7€ž›#ùØÇØô±ùuhRÅÀJ‚¨ŽªÕ¹ ®Ó«3tÛXLÎèäÇM žFçœÃÌβõC"ùÔ§˜~Ö³XýÄ'²æ¤“ÇÆö úïêm(j¡âC®…•’šî@6˜Pac‰Q'A>f*í*Úg‰YA¨q÷Ðn¹!ZÃC„qFÒŠÉ:!“f‡O¯KÝÛÍ.M™îTqä6¤Êå]»¢¬µÚJçx)’Næ¶à‚C¼2x+_qOd4^DF¾Fm¿Ã´ÊƒVœôQBaZº´9<%u¥M9–³rš˜ËšÏç sg)æÆ)´Íñ¥Î ºµÒ zyæžÑªL½{67HéR¿ˆF©‘¸“u¼ýëèØ"B8Ú:: uÆÈó"Œùåk ÑÅ9Šœ×Œ(£×2¡K‚ªÂüÖ#B]o &H©XqôCgž‰Üšš½}ØÈŒ¦¶Óh‚ÐCgê¶íÇéR¼wbL¢RKRçHY£ýqrÒ—øè(q¡ƒ<é{Òî Ó½ð’ªú a/#uiüg]oû0ʈã„0ÊüweI£³ ¤¶Åã ÓçJFפÜóAKóöè¯XÁÐÊ• ¯]K4:J}åJT­F4>î¡… 2Š<4# AîbÓ·¾Å}–¥F3}Ÿ?žœbòÔSáôÓqŒ°ÒÔƒ€’„@oʼnï0ò{7 ¥#IcÜÎŽg$ù¢Ìš²·E‹ta­÷c0ù§­dL*QyQÒ¨6 –#Ëþˆrƒk%N‹Ò|*8@ºùì»H¾úôÂ^ÈrN¶°@{v–Ö¶m¤³³$†G­jOýÓûí‡ËéjÑÊ•ÔW®¤¾bÑÈñä$²VóDµ(Bű‡± (ýß ü©5Æ {–•âž6˜N+¾‡É6±ò¿F­L½O…ôçC5Vø7ù^œ =,ÇŒšNïlŽ!E¢‘çÙŽ VóÇ= y\pÌ{Ž;•®ÊrŒ£* ›ô¼§¤myjô—Èp§Ÿ|Y”yîÝtÇf]¯Írq\”²¬zê×Á˜…-0õ&ˆŽDÈZïkV¯Oã»$M’`;½ZlÊ…”^Œ+¹ò³–Ý¢¢ü·]þï×<ù1qÆpßW¾B”$¬>ê(‚‘Æ?œU{£‡Ži·ÿO SÔ‚>,ââC´H‚˜È¦&Rdq€”oŠ3† ˆÐeæéiYRFµF*Dè/âC(mh1\k²=ZÁí£‡ñ˜Ö÷üîßY„Écmëpi·ƒºœ˜òg#þ¼v9rÙu…<,ëBÀVœÉ—‡žÄsD¡£TÉo/£ñÒ4Â-í–/vסC„û(=Ê<R:K,æƒ ^¼ò}¼æEÔ¹³ŒÂQh]© ga7>õXd¬ñ]1Ö¨<ížÃP"/qÝóÉUlPï Q1e% =î^ö;ìºw,EevÕ¼¿[©7Ø+„Ýõb1‹ÿ&k5âÉÄσ…+ýb•ùò@æ=¦bQ«½=­È¼ß¼2† ÕHkÑ:ð^Ö§cýKä,+Êè®´r-Cñþºmåcºå½;”?WDèÒ “R¦¤âç"""íË@¡EDy×¼ßÂÚ¬›Q0ÒZ ËøðG`Å4L£GÝ¿‹ÒZ&ññð‡÷ ÎÀš‰ žœ\²ÐŠæ-0wlyC>.)}_HÎD(„¼p-\Ö{ jªbý¹ß_þXRÚ¾ySx³„î1ϯ²b 5²iw’ÁŠÒ±ÐOwl>ç-e§/$Üï¼2µüßÖU¶©oƒíWÂ}ƒmøÿ0—¯¶ êáIˆ®Ÿ~Õ°©<ÎN£¸6=FÏ„©çÊsþGµÀj;Ïx\pÁ@¨P04´·†þ»/è ²¸Mݵ‘¡E9ƒ$.˜HÄ!äÎfE„îSæ¡ò]ñʤÉOÚÐïÎ[baü& ®ùÈí»SÁÂ& IDAT'pÒÜ×ËÂ_µ+»§Ú·®8ëvk].äÂÿìrÊÿ±­õÕ|qÕS˜bÎ_d¯õkôv™;× °`°ÙIœ!"çË Ö§ák¢ƒ&`1å«ßÎûn½ˆÕ-„h¢¡ËúÔº­ {¥«»è€/˜Ü¥ð*ð»ý0É<­¦׳X(LYóÇBà> Á~pøkA-]ú6Ó¡áÍlX’ýCVqc¬ &f€­¥nÀÏ^›¯,‹4~sSÔ_{ß×É…É#> Aêû-¤¶=#}=ëU×¹´³º§U¿â'*ßeµq®§a«âW4fáºÝRV•-)t9°F•÷PÁ÷:'ºXßÂdëÛ!ú<ò 0±ç6«BJ†÷Ý÷]к;á'O…ä®AUø®(¡\¹mpkzOǯÿ|¦k³Üï ÑÓ§ ºB¾d£ z3,eÃaå»/¿g l½6|Ûkž õµÿ ­ðóÃÜu½ç^å’–=ƒ÷\®×o¿ºQrÀ¶k`Ã7á°í°ú,¨¯ùÑ™sá÷ÞÔ‚¾@7r-Tä/x \$0±"Œtý”ÝÀyÊ= ¼÷{h<ß[:ßÌÉ”¶¬#ŒO³Êš÷†ßV[Áæö*V·¶,1=©Öx,e7©O»jùl[Ç?ÿ ÒZÌ ¶—¤E:¯ ¾õ ¹p½Í>=]ÔEt˜/NRù£ÊÛE­ðSâ¨Æký;^õ£7²~ñž|Aò`òñÓysP.ìÖÈ®°kÕ¥‹DùyU3°°t1)?‹ÍÔÌ[a¾ ¿ÿžòwfhñu6ñ16öØ»ô76½“{±HžÄjÖRã ög‚|¶ö®«áŽ+àÞOuí3¥‰A^ñ€ÇÒÞêVe¾9ÎiQ~΢k¼<ÎUñ­¤Æ—ˆ¹è7.Y&Bw]¡8ÒXÙ8”‘zž‚ï¡ÐE¹ÑOè|·ÕÀh.²ÂM¬øNÜ=°ý,xüg`Õ#þë/èo\wj‰_y1º·Ëyv±L„ž‹ë@Rßç¯FéK·âïI–øÐ/{«f\6¿FßíãÔÑÿõÇqÛOàWWÀmï^jÏZy,\,«ÙŸÝmz>_¹È-Âæ?…‘wî‚É#÷ªê^A¿ÿ·1µ@;l”ºQ  ß (l–]Y¿¨Fµ”°îGÏ"å=ÎB“_3V‘ˆ™ùº³Õ’ZØaçØ·ÉÔÆ-Kç–_l½pû”»+DÝâîW‡_pÑ:ÓÌ–"cmÞheGæe]Õue®ŸRV:¼åp©,2°9«ÛyßææÑcYsç==£"Å£g¸„3„VZ ¥°Ûn¹£ ðƒ¤*6 w±XTÀ­€Å€{ÿW\ÞǸ—Y:L/csÚßµüã|Cô=~Áã8€îÝÌÚO?׳¢ ÷©ÒiË Nu /æÒú&2e|—8&ÿ»¶r|+§š¾-¦ÊË1_2NUý÷\¯£\Õ¸'0 b¯6ΩÀäŒíýÜn¾‹"ÊtwÃgÀ¾‡3ÞCS¿ý yÓðã‚[?5>²D0 í.œèJ\î€Ï=hš`‰ø-SÙíÍU6H[÷ž ž§½jã¿ýãØšƒ-?ƒÏ­Kå ã´;¸Ë®¸ýŸsæ—> à™pÚ;!þ-6 uvÂÖ_úŸðNØrœøz˜<ö9‚Ú^%ÐGèr6ˆE‚iábß©N²í—¼{•ð†'C)a=#”±L¨©¡Îˆ³ÄG¯:²Æû•§íˆzØFàøæCOá1ß¹¾÷<4:Uù³ÍHk]Eà‹&ËÏ=ŽïüÞɬ`{7…gDY³.¢óRÈÅ`A¯.ôÅxYÙ˜…ì6ûµµÖÂ(åëÇÆª™û8æÖŸ,1ªè1nq.4Hg,¹ë‡Í#vgükËÜWU†vùç’¨FsÛ†/qi¶†F8‚À1Í`ôè A/þl™ãzîå¦Ñyþ8žâ€ Þ‹\ìBÔdo„.±Ýì^àûÆ;ÖJd^¤nûE¾+n)Ø¢Úò^×j§|ùs±y«ÌFWËUözaê³Ë¨kPäUˆºÝ > Û[pÑÕ¿Ý‹ø§Ÿ…{6èVwÃ%—÷(ß­ ·Y»dTMT2,u‹Ý¿eÓߏ=.ƒ\pùoA¼üB¸õêž+²w<²Çf9‘ßÓÏVì‹ìŽ;? ; <çÒßÒ9ò9øþGýg«¾ç_?Û¿öqÏ^‡þÁ^50 ú¸ÚI ½#YÞÉ+ŒC6-A[¶}·2Ö7ýDYêï#~”ªô8ó‘H82"ÐÛiZìIn±ì°M¬`bËöÞRhÿ®¿UU|.¡w†‡¸óÈØ–³¥MªÍ|³X1VTÌ4—â(ì’HµˆÎ‹ÇrdÊŠž±¶rÌGû±º°–•ÞìVJþãIg µä¡ßþQ׺ï3Éü3Iªs£™Ù(‹·õ²Âû¤»½j,®÷ç…c\ùçÈÌ~k [ ÓMíJÐûvã‚+.zûß¾³>ô9†æ›¥÷µp§B¨óïK:ÛcÿZFÝå‡ï¦…p¥#š«bEû^ù]GšUÐGg¸ÎÌAë9à–_çǹBÐê·×ëÿ¹RÝetÞÿ,þ(»^ùžÿ˜?N{1÷„ßìâÝ|¼ý©>r5žGî‚ÞãVµ7Ý­ ‹Á©ôêù0ˆCßóœØ…sœ[&BÝÕÏ¢×~Up”k¯€¯_ÏûGxÂsó…ð‹ï‡O¾’m« FB×÷½¼ní2ÇíþnV\÷<¯n>ËsåšÁ¬†'ü1sâ?Gnº.¹'ý‰¾kµx×^_ý4\üe8f¯¨?x#tµˆ²éÇi--‡J ªmºîXZøQ5™”h¬+êuÙ¦&;Ä.A:‹–A)|ÖD픡°EXϸýè£xø/¾IžÝìo1P°Šq‹n÷œË£êŸ\ðX™(£s›I²NˆÓ½ÎTXº PÂöFÕÆ¸"Š«¸”•^ã¹°Z¤w”ËüèOg¨Ð[Å:%¸í±ÇrÄç< «<¯»åF!eI³½¤-eÒºÐPF( HéæÏ™HqíëN§qðãì\.ÒŸ†^"Ä}À‡ï©˜;zš¯?ÿ œñ·_ðX×·H÷GÞU¸L.â6É8ÙÉØ>ˆˆ«2µ+Ú**ÿm¹¦“’l(âG>®|®5:Ì=GÀa?úE¹É¨-tø½~ËOZXü¼uñ=Ø.rTVJ5KìA‘xåÜ->›¨Ä„qð¥ÏÂW®óô¬ÓžyÿY×ÎÂŽípñ¹°ñgþ©Šww8)°©ƒÞ«¸.®•žF¸e"ôeEz¹}‚^8ìí ¢zÍ<¼ý¥ Gáä§=°pænÜ?ý ⟇Ôg8¬òD¶‚ *'‘?îRÐÝnÒï}¿cUï¯T7©-|örøò5ðªÂœuÿΑùYŽl¸¹'kS„èž~ц×<Þp%{Â^A0Þ&Ô<¡\$!$`$ªeÚÚ›—t²²;Üjée’Œ(I©e¢±”x8¡^oSWmo’p(ü w˜eMMäRÆV,0{ʾÌaŠÑ s=‹Í aÑw®xôWFãðqô1k˜ñ3èIˆNt'(M+ ït,¥E1¦SM–‚n»#HÅŸ­Ëc#»f0™Wã@k‚TSîD~dËL)núÓÇqÄ;¿‹jf8±4ûP½¶E?Õ)v‹—ÊïAª(Ð’UQ¹û¬ý¸õŽÄ*YÃL»WÕ̦+ 0*‚^úœ«^ýj*>yXo¿îdýÔm¬¿vÓÒ AáÅ ·U`¤+½ºm¶²çNW©Šzµ9X X ¤Óuv>b5?{é 72k˜aáQ]lðNàêSŸÉ½‘x®Åʯ݃Jí\¦°Î{~Wüí«0›%›¬ÊË^êÅFFš‘4-¸èYð†xÞE{~Áƒý›?Æ}ö2TŽ5¤q.~An×[”qK¡@»ô"+—³D~<Ë‘õÞîRï„ ÏÁ]üN8õLÄA‡í¹æÝv+îgà¶lD6„,ôð'º™ió^aÁjXa¸«h|Às®Èªà7¸%DGøÏ§4H½žw6î½W"Î<Ê÷ÿþsõ¥Þ1/ðç….Èn¢â!ïºëŒ4 6oFœ÷8ìÇ¿‰|Ô {ýwõæœcË–-,..öÖÐåÍö0fAa²mm‡Õ’ £»s™7d ³Œ ÕÄ6ñt0“&Ô£¶7ÉG»À5‰Ô¹V3:²è­W3ÙN$¤zÁWŸïþìÊô{¶®ÆÝ¯;’ñÑE$´›uŒVd0÷+ö‚¬”ñ‚nMÉp/ü½ûªUA/°§\¥-3Vù'|wb‰mBm¸C\óÎyÙÇØôü‡°ö·”Qg‰¥Â^DêŽ @"_¼¤ñ i=¬Aé¶ w¿hn{ÅáåÊL…À¡´(-Æåz0¤®/jÈ;ù…ô`Aàߊñ­â™GÜzä1HÖì^„ÉA ¹¸˜|î'~U£ò‚Ññ¸]¤…ˆëÉÅ3÷añÔµ´g%Û ú@Î:‚íì‹C0ò*¦®ÜÈÈ×¶.µ¾@£S¦KI+6\Eª´,‰½ÇAúÓ ƒ(õ ÷7¯@#Î:9¹ëf9—t0oz=Ée—Y]éÔóãt+.?O¤ÎËS¦+>‹‘ÃZ*›«’Ö'»ô£xÅže’«×o?S¼´¶ÝM“´}›ÔÊF¾Œ”¥$á|5Jä2©½Ï;ýW˜Ã>L|í7«Víú8¶Û$ox5î«_DݱѣL#Hj>+mUžÝpØî1,6=z•§.vÓ/P–pº7§rÁLSÍZ™ÈR€`²]„L!8çü]œ# Ù›_ûÈ¥_‡iÜõv¯ÞdeZ¬7aabHžû‡„ÿrá‰'íôßÅ›1†w¾óüð‡?,Ÿ Ðja潘ÛEéSí-Ÿj“¬tî2™´ ö‹|¬s[Ò4%H5ÑDÊpØ$°ššíøÑŸL#Sëý¢S¨Õ: O4ÙyÑþÔΛí¦{,½éUa$Oalue°ZÒl #ýïêNÐÓðTvŠ[ÓcO9h·LµççÖÉ¢sî¥ÉCk¥wA“Η!’”щEâzBfB8ZÑ^5Œ¼µÙyÒož³tçÞ/ìÅb"sòY!ì­W­aö¯¦YÍ–.Ì ²$ô‹, KîS]z2HЋf4øÙë0ô%…(N‰¢´,9t¢÷½aDšPûÈV/*Æîšj$.—‰ÄˆvµQR,wlª·‡ ‘þÓ¡¸‰€Q‘0Æ–²V¿\ÿààI±xôØ ¼nâÞ´ƒ ­HÇ×/E¾i%Á÷ÞÆùï+íD$í˜, =–4 z¨oEæbP$Qõö.,AÃ(#µ'¿Õ=Ö5Éb:i ѱ¨¿ßBç_ÐÅgêñªpïN¤Å2ÁMµt®&£oF<|˜`µðÍ–©ÌÜJ¶¬65–,ôÊ\v'©•è[ñ«ÉË7“Ýep·”ß—ª,E)ÇÍyD¬êuF9Ýn‘..’4ÉœÁeãl™¾-²¸ì·µ'?™ÕögX@Æ‚¡C³ö:wßB¶¦Õ ¨‰Ë{3‚…Œ¡I꿘 ¹£Á↻¼hä'ºY“%ßSß÷UÝTõ”ÁÅò‘¹ëK½WKgUñ¨ JAô«FíÎ'˜|èC±YFÚX$k6Iš ¬3h£qÆ"t÷º1€–’ñ—½ŒÏ~Ùz¢ÂÖ7²õíoÇÝ|3Ê÷½y^^O–Jˆ%Qmˆhx˜hx„ ·S»ñFo¹J7£áëƒ}™ó¦ZRWõ:õuû5›dÍ™ÎÐF#2SŠ{áˆÍ1ÇpàWäPaî¾›­o}+Ùw¾C`LI™€$Jä„9$RÞW)ÿ[‡I:Xm¼õ³5èL£qð!¬ÿÈG{ìcºÇíÐ×ÞøM8›-¦Ø¦Ä6¤O#·üÕfYwt+ó dxŒtêkêiFØÖÞ<$³ã)µ<š ¬Fdž–e!±Mˆ£„‘zûLc×­ë$)‘J•þÂBˆîcq?g#‡ÜL-‹;G1‹Êc‚š”jµfXÁT¶Ë»–ÎöÎÍå'×íè/¡ðd×™Æ.aŒê‰lƒX&~h¤EiC#$O¦õIÕ…=XÑXã.ê’n™tµÿ­XÂ)ÁʳY l{“Ÿ, i,Œ@ ¢ãP©·‡ÕY…öF_tîªYƒŠ¡‹ÊâÊzX‰2-ª†Æ[Œ “#/"k´ØúQ½D¼ÅnF•ú0=%ÞŠ@”‘^ ~dˆúã,6kt4Q˜z#žÌ÷ ”ëWÝu©æ¥_»òY¦(òüùŒÐž,Æ®—L}~’ùnpÏÚeM³ø,ý}Uq Lñ{‚é#dò‰O„fÑnãfgaaö¶mtæwµÚ$ è$ÉÇÕï&ùÀ¸é`ì1’õÏŠY»~©%õIÁpÚëŸ^ÌpNà¦ü7¥è™6ú³6¿2?Ž2·]z›íï]D߃z(wW*îÉD»J/Œ\O/öWEä.„`ìàƒ™>ýt„1Äbq1?Oº¸H¶méÂÉÂÉâ"Y§ãEÝZî{÷»1ï?ñ‘GÒÚ±±};A«Ehm9‘¦¤$¥6>N44L45E4>N<1A02â©lõ:" ™¿õV6ßtSÙŠPŒÒVËDnw}•Ìc¿ïŽCV>ò‘Œ=âÈfÕjá¶oGïØAgv–´Ñ YX ít0Îan¹…}¨·uCjZ8W~¶xxŒx|œ¨>D<1A46F8:Zâye@áiï¦ÝÆdéÎìüÕ¯˜¿ýv¬ÄYƆ÷¼‡©mÛXÿÔ§þŸA¨>h=œËˆ¶§d:`¹h·uO-Y_S7™B…>Š2Ï”°™¡:‘X\‚±”1³Ó ºö„°Ô¡¤¡6Ö!<Ç`£ó )iCä^>Bég-„@Ô =íXô d>&[ ËMˆ¨8¡•žÜÖ–¯ïKÕô%_ÞuáæVP¢²,,¡`¢L¿;Ù>­ ÇðD“ÐdØ—I:‡GëæýqÆxꑵ­qZc´Æf)ÖxŠÕ™_ä³ “¦žo$è,Ã9G4ÑâØ÷µ;¦i¥~TOK\&3H½ÇºL}¨³ ï•‘½Æ9n@JºÒ¡^4Éްîa²íÁ%µ°CfB’4怋%Y ØxÅX—ô&RHŸY‘zkI¡d ª€e¤RÈʦΟ ]ÈŒ‚é“ÉôÙs¨•¹ÐDb½w:ÖSíRûPÚà²Ü¢4·+­º”X}Æ)TuÑ&ÕiA Öœ¯™âΞ¦"Ÿ¬(œ m Çp¶ºPgCëÖ±êÌ3 ŸüdBkqiJ¸¸ˆK’ùyt³Iº°àÉaóó4ffèìØll౯ÙÂô£ÁÕv®]Nb”\÷J3g/ë¬@›À¯èµÏMXcwÿ»`Çm!BæÇRH] Œ§òÑ+)Ÿ«*¼»íÿr•ÿ“¡aäÀ G¼Šžì‰s3Äqïgà¾/Cóî˜Î¬Gˆ¢ Ñø8§ŸNxöÙ)›e„í66IÐÍ&#Í&Y³Igv–,?–¹9ZÛ·“nÝŠÑšV³‰S V¬ðð©ÉI†×®ehÅ êSSÄ““Ô&'QÃÃêÇCCˆ8.‰límÛ˜¹ývî“«”ŽW€:RäÙ±\ÛG…pH—“Û`Ž?ä!¬;çêÇï׈$!^\Ä´Z¤;v ÛíòóuææhmÛ†››+Á-ñô4ñø8#k×R›˜ 6=í7&CC„##%Ý¥aØóæãŒÎç~úS¶ÏÌ0›[ÀŽŽ²æ”S˜~ô£ilØ@<=M41±WЗ#ô`N62Dê0M_gUíÜ4¥( OöÒiàG´¬ðD0e} =ÎP ©ÅuÀv@J͈Yôãn‰¦Ó©a$$C%†úd}ÂN‚áîèNIªy÷ÊÈ콈… 4(cˆS²ÅÐ/x é Gø÷WP¥çÁ ÿ¿½3“ª¸×þ÷l½Ḭ̀ â #áÅ%š×ˆM‚D£¢&*ޝFB’{÷hðºÅ¼Q‰ÑWÔ‹ †8ÑhîK"ŠŠˆÄŨApafg˜¥·³Õý£Îé>=Ó 2/ çù|úÓÓ35§«êÔ©ßRUÏ£82,È1Z‰|7[äRïx‘¸ckX–!…W,=«¦fÛ’'ÞuÔl_·m)â‘”Fdœ(ñcë‰O¾×qsr¥Ž“{÷ÕÎl;«x†8–žF²cY¸v#¿pã€V¹ùе=J×Aï±¥Aws]wìkZ`i¡O~PЇŸ…ì=)3JZ€JTÓÓR¦Sw™4GCz¥4Úªšå†öÊDænÈ©`Ç@`D"Ï2hÒ«’)°ÝÛ áç!…ܮڮ<ê〰)$ˆÐý6ùŽ\Vž7*ó¯Š*ˆ*RwÀR1oüÙ‚ŠêCèjþ6¶³Ž˜ë9e®m#Û4å{ZjMWqæOÇ7NêK;ï—z×Þu\ËÂI§¿AµZ(˜.nJŠ—yú]§w_ÑLÑãg¨“>|âKd‡KE®H$«ú¦ªjVOQUÔ€S­œkÆ«˜ÍÜ‘è;” [JÕ}øyÜðò¾Cõ·äkÛöu‡ÐQwv:Myu5Ìœ‰1a‚Œ }§)ðîzN±kÛRyÍ“õ]Ë’Ž¥§{®ûªd¾¹¯…È ¢ªRÊÖksråJÜqã¨:÷Ü\ßøÙÄ^c{GG³Ï»ëJjÛR–Õqýõ¯SyÊ)#Fxip—¸ãÈÿñæ'“‘c.“ÉÎ ¾“ yJ~Z,æ9ÏFN6Ø® ²ùë'Ži’Ù¼™²N vÔQè%%TLœÈiÓˆ)0å¾oCmq1Z-"=&ªãâ&To·£•(ªÈtE•im=%õ”#1ͰQãZÊEt Ü„ÜÁ©âRîva¤-’É2©(Q+ƒ²]Èï(}câ”’ƒv^ÙÔfXów¨—‹eŠ+ˆdLìn¹¦mØRR7ì¬ ¦¦ÉMy(¢`*[šŽDþä©cc1/mí8z6­k[òˆœméÙ#mFJ:$<£§¥AÿcÔÃ0qQ1GúËPÃûg ´wfû7gÌ!0ÒŠ%Ð…nÙÙ~ª{­¡÷fSËÒ¡j’íÍ0dÿ*ÝB2×RŒ'¢šòü®P™ôWà°?@døN×Ê‹FÝ<Øü0lus»ŒEþËÆK*_i¶¤šU}ñr´°þÚ¹ªyT®ò˜ÁEÈÓФÛ6b%CGý[CNÜé=ó'ÊàšcÖY鯛oóWà¸òÞº«ž(óî§#³2±€¦Hjb餸Lžþ*”'aÒŸ vàÀM(é:Xû-”ž·ävû: s¿ Ñ'/_98Iå—ÞE·_ƒŽÌ_·õfàß>ñª®ÝmžðJëCÐù²¼xÅI0ü; ûâ×vì±» ËwœüÏš†‘7^ÚÈh±ÏšÅÁ\ÃAãÿÂþkÐÛ]ŒmV&DRÞ<ݲ³²þ±ë¨XCNô®"#EȵՈ-#¸Œƒ(‘Ç?„áÍ“ŠKÌI¢¦\´„”ÐBtãÄèWPªÇïÄȹðúLhloRwäúx$iæÚã­ù*ÙÃ9NŒDw…9›u¨8èÂA&ÂUq,©[¦‘=ë­§¼c^IÏXhÞéYU¯Ã°œï >ØÁß7>þ©œ1÷ ºâÈTža[`I‡Äq´|!šÅj_VN%—™ß*ª*#]©U-döA¹v©²ªâ"Ú—¡t_ _~´è'œÂ…Á;·È­ºÁsÀA,@+뫸a“·_ ›v(€ù úpŸgËy†^Ñ,輎~Fœ´çÀÎ5ðÞõÐò<Ønqúg˜öIIDAT¥ë³Pÿû<>|U@ë*Ø~œø2h{˜·[8ðá=°å°ýÍüº»ÉÞNI`‘YQ{ ë[0â˜:ÿ“£‚†< [Ÿõ  }Y_‡iëø`‰ì¿ª¯@õ÷á€o€þé–ý,m|ûTt%¡£i²Q]V ÂKcûÝßž=â¤9¨†ƒ¦;h 7*=ÞR.º›¦,íäÖž“2ÂcÝ28¸”l¸Ø¼þõ¶ÜâéOzW¸aY^åYGÉçÒR±³¼a?ÌY¹ù^ à  ÝUˆXfvšªJ£¢D$.…æV Ž×6EîLv©lçGûÙƒò£ç¡Ò¼’s`ÖŸw}Pº¼ñ¼ø}²y¯ï·ê8ãû“MÍk³ÈÕës¯ƒ[ºývi&üáÛpN-òÕÝðÿµ3¡£±oûz{ »s ¶· 2„5¾íçÁ¹¿‡!c@‹ì~;6¯„%×@Ûrî° Ü#Q„Ó\¨¾Ðøt¦ÿª’‹î» 3 Ko†ó ;P…ê|5¾§ÁçÏ„“oÈ'ˆÖ… í›à¥›aÓrèªÏÏd”€ÑGÃi÷Èyñ“Ü£Ÿ¥] µÙÙ5sÕÉí¤U57K0" „†•2庱£æm´R4Wž›N8¨†”0v##•.7† QËÁ0=ã¤ÉÔ¼ò‡«à‡*\ÉuËáÅ¿Êè<@»(ðÉD–”Ï + ºÛkŽ…y¡I± Š8'\Q…@w†ã1ä¹ËïM NÔF­½e Tq7iéï`mkþdY úHªU×§Zõê˜-¾ l_¹vÉ£0Š+Ð\×#ÆP²D!}3UIf¡ª ô¬€£^‡‰ÿ{×åòß@írK+¢€Á+ä‘å3õažË9vJ/âQØÈôšÔ]CÚ¥±åîsáߟ„Ãv#ý¾ém˜?Z6÷5,ýQ¢îÖÃÝ+Òô.GuëßPVUÃY·Â7oܽëô:Ü6t4åÚáiÌéÇ “?ŽPAmøoxé¿á’…0í;»ß\ ¯>˜Ë"¸;È"瀀ê[?BYs'4wÁÅÿ¹ûuyõw°hv^‚Û0¥Ö=¯<gþ ¾yCheCƒ^œAWÛ\"–L¹XrÒÒ”˜†ZRA²³GÄG %昸ÝIœ´ÈêŒ ï`©Pˆ88¸1iÐ}:P<&% 0]ˆZ.%1Këù%Ç-ƒ©_é[É»¯Í¹‡PÉveiòåx‘¹­æDüHÓ;È*O9YÏR÷!Ýð ºÇæä/yû+ºš+ˆÚ¾q÷æ+0ÀŒ@äW?D¹å :jÇyìÄ£¢£Ÿ€qò«lM:2ŽÇþ•¥Y ìp Mž½6ø+²¶ŠÈ?¬»ÕÃcõ ¸(òip4p››1æžrë_àð/7 ··Á“¿ClñYºè»+r÷%˯ø¬g"'˜Öo&Bä“|x¯,W»è5Vüþ1<4:Ñ? ÕÇB4^ü·ñ}¸îTĶf¹ÿÁ_N €AïÍE ô¯òd‡EÍwÈ×6¼“W*èþ¶ÛpÁ  ïÂ.æ5oÀ-g :Úä¹v_ÌÆ¦ÿ|…– vDï«KJVY_mÞeÐÚ g_¾k“ÜŠ§á·×"Ö#<"ÕñÆ}û¼OýgÊmÑõ±ß¢ôD`öí+-¾. à†ˆÖzD:÷<טo4Ê‚ÿ‹Òaìÿص{ô¯•ð«‹smü·{áÐ#`ðÐÐbZ :­¥ÅEW(‰¢”D!²8T‚Cèyû-2Ý=ˆñC©Y…¶¥­­±=© "e"\pQpu¦ƒ•Ýp=5(W•ƒ4#À6¡4ìŽnÔÎú¬¢¿ðgXµAn0s¥Ñ6uHGÁò¨ ϰ:Jþ$¬¸ùÄj/‘ˆzåЇ˺«–šcÎAQGþ.mK.èx"–Ç f€šþŽþäChßÝçÝTøÓŸ°[Ò?úÆÌVeûMCöÕ‹3/Å$¿ýM ì _€PEó@t¯}†-Ûg8ÙDN–RÓni#rå·ÐæýÊ”ìv]ÄÕྱ ÉÑ­[ÉNÉQcÚZNlÂñùÇw@ÎSо‰|GÌODéo¾Ïú¦99GÅo—¥B¤vºvÊU·÷¬}ð.⊳q77ã¨Ò˜ëfŽÕ¿WYÅ£ŽõéYÝœêAäI÷“¬“ˆ|EÄë?"ncÞ­¨v)|çÚâÚñÎßáªoá4µa©^ÿø\ìVßÁä’/éZÐa$^õÜâê`8 ŒŸ^‰jTÁ7/,Ò˜?×^‚»½ËÈBîáÓm ,õ4jNÍÎ2䳦(Ñ÷¢v+(sï)®.ÖÁågálø_!9H‰Téóý@Q2Dîü)ªS†òkvþ=Ž ·_…Xö$nK=Â~¿óu´£OAœ1 åÌ‹C«ý©ŒÐKGÁ˜!(ƒJaP *ƒhÊbPZÃcmí¢ãÝwÀŒQzÈ´ªô$QZ;¡'…Ò™€î$jG7Ng7jÊBIZaâhÛÈEê–&3W®* ^·ƒz@íkÎlÊÿò2Êç<>ëî.œ‡AlÈ HŠIƒné2JGŠˆ@Ó¡V]é-³ƒÝŸ€ú¨ƒ©ùb–uË{W=ílŸ¢5âq|—¦üÑQHê n¿Š1SÐO=½¯mÛ´ç¼oâ¬{[‘“¿%—çIG¥!·5Ù0jÁ‡¤<ûÉJôYÓ¤¯˜ŒB€“Úk£î@I:çÐØ˜1H·Ô=óJ?ÜFáµ@ÑÚ‚uÙ%XK_OÄD³ÀµäϦh³çÄø¦YcN>ýf!>ø^Ôõ}4Õ@´®y|ùº QÏ!ªŒÍ(¤U0~õKJ·ö Ý6"ý¯sŠ5ÿÂ:ó+¤;Ûsަ±µ@û´€1d(@/šw«‚\éäøÈ ;×ÍãG÷ÚÒšŒ8ËæÞ€V¿ íÆÛw|–zõ›XgžŒ•Ld’/¤¸r£¾Pr™3'È_ÀÉË’¸9*âóáGäæZ3"û[Qß½µ¡ íWì8Ëöì_±æ|;ò(ae?hžj¡ðôÜ^âAAIcß™ó³^ާÆf`Ü{±Ö4‘Ÿß ñþ35bÝZܳ¾ŠÙÜ@ÆÈ9¾0M}Ðçæ·½q`ëò>j7_O¼¾È·õ{DK3ö¿_ŒûÒlo2¸Ü¦-^Šúâ«D¶´¹ìÚÐrê"ô/ †ò8Ä¢0¨4Jb‹ÁàrĆfï­Gí†a#Ba€iAGdLèIA*#zgF2‰èêÂíêÄéîFItcwvb [Yõ©´÷@'-Ï ljÅ9ÿÛ¨_ý:ƒî¸“ôÏJ矟ÁÊȉÃu!-¤xkÁÙÉÁU²„ªëhzUךŽâQæØÈz³Ì²9 ÀÂÇÉ’€8¶%I!‘“PDÖèûr™~Z^ñ ¡nÃvâè™B´iÌ9—2ôw Ÿ’¿Á*ù_ÓõöûÙ5Iºªœ4M;w‚ /úîå¬zQ•öÎtöåÔé»þ\HÞÔû›¯íîó—G=õ¤ã&zdtÕÙ“`øüû(½ì2èMéºt~çÒ/>‹E.m+ü=€ XBž\*XV¾ý,;+ýù1Ja'µ+ùjw¾Ã¢92#¡'=.olÃ!ùÿ¼’²›n.8Ñ:k×Ò=ó,2Û1uÏÑtr’Àïžâ‰ÛhÁ%„\¶ÅwPÄΖËEN=ëœx"2 TTU'Z1œT{ ŽâÐ#,Jö bU#)ý·Ë ¶Ã~ë-zÎ9›TKB:™×WG³½º;®|å=J_+»ç}õúÛðùÜMÐâ1ôX©Ž6MrL¢×Î¥¬¢Šø¬«õâ‹$.½”Ô¶TÖ!ö5ü%¸,ÿ»&÷ö'—Ýò£æà2Œêo¼ŒGšJÂNƒêùϤ¢ì¿(|ÿ7l kæLœdfMó–ZsV!Éølàà ¿hÝ·ßAåà(ùÑú~—ëÒyñÿ!óÒóØôJçŸÅD¿áFF vÑE}ç?×ͱȅ}÷‘ÉdxüñÇ©¨¨àÌ3ÏÜiù7ß|“÷ߟãŽ;ŽêêêÝ‹ÐgÌ)š’˜¼%Qimt¢1ˆÇ a;檵lë‚.·ŒØG‚íHcnÚr†5mˆD Ýq ™”ZèÝݸé4fGfg'éöv’¸]dR ¬d‚ŽdØŠ€Á MŒ|i)=ÿk2™X„º´•[ÿuÇ@‰ÄÐc1´HM`Äã’{¹¼-GÇÑ¢Qù÷X Åc‰R4M²:ù¤Aæ¤àä¤et]ÉÁî³zyŒ`N&ƒkšØÉ$n&ã *$ §Û2¥ÀA&…“É`%“’YÌ3|*—2öÔ$ššH\v9Ãî¾'ÁÙ²…ÌöíÔ]û}6ô;)G×F²_©QTÝ@7 UË1³©ªª¢hºì='È ö"±È›ûš×F¿}®›¥›tR)\Û–íI$°º»±zzpm³» »'Aªµ•Ê)SsÚi¥¥¼7k‰æf†{,ƒgÌ`ëŠlûç?Q#bUUh±‘ÁƒÑKKÑ¢QŒÒR´HD:1Ñ(Z,†æ;.^ûU]Ïö½h<•þRv E–¢Ò£¡õéNÓÄ5MœLFŠ:˜&fw7±1»»q-›Ì¶m؉é¶6ŒŠ ÆŸ}6ƒ'L ÓÜLbíZºÖ¯'ÓÖFéèÑ”OžLIu5‘¡CA×Ùºt)-+Vàš&ÑÁƒÑb1ôx½¼\f\¢Q©ŒUR"¯Š¦IJÏÅ,ý1] ‘£ µ¬,—µðè8­„”¼uLoÌ&’8ÞïÍíÛI45¡‡^tU“'cwv’ذ»¥…®M›°L“ªÉ“Q++qºº(Ÿ8‘ØÈ‘è••´¬\IÓòå$êê0JK¥`F,&¹Äu]ònG /£¤( ªGת©<ƒíòǧw¿²4–‰“‘÷˵,™~NgÈttP9u*sñað;;1[ZHÖ×c54  š?ü=aȤI8ºŽª(”UW9!Ÿx‚æ+PT•Xe¥t¦KJäýÑ5T#‡¿¢äSýöq$m ázc̶±Í N*_Ã;ŽqgŸM¤¬ «­ ³µ•TCN]© hïîÆˆÅ!yäñì³Ïf?ßpà bãÆý–¿ð wøyG¸ãŽ; î¼óN±/ÂM&…ùÑGⳄíï½'Þ½îºÏL{3mm⫯éÖÖO]ÛšŸxBlY°@XÛ·ï¿÷§®Nlºÿ~ÑòÔSÂîéÙ§ëjÖÕ‰ºÚZÑò—¿×¶÷þ³üúëbËo~#Ìööÿ®tK‹øçÕW‹L[Ûî͵–%Òë× ×4û-“ܺU|pï½¢uåJaíãcaOaŸ\C¿êª«hmmíóû5kÖÐÜÜœýy󎎃²/ÖmÀr< jM;y?Ú%—ðqs347ªÚåŽ cÇÒU_õõûo;Ž9†žh”–M›öýº~8ªaвnÝÞ¯Ly9îGÐÕØ¿Þ{É%|ÔÔMM»‘?ÜñßO:‰Ímm4~ôÑ~+ÒRRRÂøñã÷ßMqwÝuW¿)÷·ß~›yóæ1oÞœ††’É$ªª‹Åò¢j]×™8q"cÆŒ¡¾¾ž1cưnÝ:>÷¹Ïý]cÇŽå„N`Æ Œ3†Hdç´‚»òétšææfÆ·Ó²Û·o'N3räÈ–mnn&‰0dÈ¢ê±+uÞ•²õõõ <˜²²²–]¿~=cÇŽÅ(«ݕ:¤R)ZZZŠîãL&È#vZ¶©©‰X,Vô~Œèc˲¨««ãàƒ.êºü1tº®ïµ1ÑÑÑišEõqcc#%%% 4h§e7mÚÄÈ‘#óæ‚=QgÓ4©¯¯/ª»ººèééaÔ¨Q{õ¹Û•²”––RQQ±Ó²7ndÔ¨QD£Ñ=Z‡L&ÃÖ­[‹Š »ººH$pÀ;-ÛÒÒ‚®ëTVVîÕ>Þºu+eeeE÷ñèÑ£ÄÖ455qÐAí´ì”)SŠ7È{"oÿÌ3ψٳg‹þð‡bõêÕy;çœsÄìÙ³³ŸÛÚÚÄ7Þ(fÏž-n¿ýváºî.ß5×\#‹*»+kôü±¸ù曋*»lÙ2±pá¢Ê.Z´H¼ð E×cWê¼+eýë_‹7ß|³¨²W^y¥hiiÙãuøàƒÄ­·ÞZTÙ_|Q,Z´¨¨² ./½ôÒ^íãÆÆFqõÕW}ÝË.»L´¹^9PcbÉ’%¢¶¶¶¨²>ø X¾|yQeo¼ñF±aÆ=^熆qíµ×UvåÊ•bþüù{ý¹Û•²<ð€xíµ×Š*{ýõ׋͛7ïñ:lÙ²EÌ;·¨²ûÛßÄ|8\pÁ¾iÐ÷eyä‘rÝ¡C‡2tèÐýªÎ»Kâ³·ê;“Õ@Ö9røá‡ïW}<|øð¹î¤I“亱XŒÏþóûUÔu;ì°¹n<k3f¿›çj¬•”” È3òÙåÈ "Dˆ!>EÐn¹å–[ö·J !˜0aBQ;w'Ê*öÌß®ÔwäÈ‘Eïîܸ®; Þ´ëºÒÇBâñxQ»;w§‹=I°/ô±‚C9d§!²¾£F*ú$ÁÞ®³‚òòò‰ ÷·>¨úTTT0zôèýjn=ztQ§5ö•>.Ÿ˜ú5Dˆ!B„±÷¦ÜC„"DˆÐ ‡"Dˆ!Bƒ"Dˆ!B„ zˆ!B„b2èÔÔÔpÕUW‘ðôœûƒmÛ,\¸šš/^ÞÁ!B„±_@ÁÓO?MMM 555\ýõ¤R©þϪU«¨©©á—¿üåNI öºA_·n .¤¶¶–¹sç2oÞ<:;;û-ÿûßÿžêêjjkkéêê zˆ!B„Ø/H$X²d µµµÔÖÖrÖYgñàƒö[~ÅŠ¬^½šÚÚZ¦OŸÎ=÷ܳoô·ß~›#Ž8Ì`ŽãÐÞÞÞoùåË—sâ‰'’^ò±Ç GIˆ!B„ØçQRRÂܹshkkcéÒ¥œþùý–_¼x13fÌà _øï½÷Þ¾mÐC„"DˆÏTUeìØ±ttt0þ|æÌ™³Gé—Cƒ"Ä^DoQ‰çž{ŽM›6…"ħÜÿý\yå•{\øe¯ô/~ñ‹¬Zµ €ææf4MËåX°`?üpöó×¾ö5^xá-Z4`êV!B 4üq/^Ì÷¾÷=º»»yòÉ'QUùXþä'?áµ×^㡇àÕW_eΜ9<ýôÓaç…±"“Épß}÷q饗¤ž}ã7¸úꫳŸÏ:ë,žzê)V¯^ÍÔ©S÷mƒ^]]Íå—_NMM wÞy'×_=åååÙ¿÷ôôÐÓÓ“ýúè#~üãgwº?ÿüóy¿££#ûùè£æÄO¤¦¦†åË—sùå—ïðú!—{ˆ{555ÔÖÖ’ÉdˆF£Üu×]œtÒIL:•ššâñ8Ó¦M ¶¶–ïÿûX–ÅôéÓ©¨¨;0DˆûN„"Äg&L`Á‚üñ$•J±råJ–-[–ýû´iÓÐuÃ08úè£iiiaíÚµ$“ɰóB„Fè!Bì+èèè`Íš5|ùË_Ʋ,Þxã JJJ8òÈ#ùàƒ˜8q"mmm(Š‚iš|üñÇŒ;–qãÆ…"DˆÐ ‡"DˆŸ6„)÷!B„"4è!B„"DˆÐ ‡"Dˆ!Bƒ"Dˆ!B„øÆb]âÊïIEND®B`‚snd-16.1/pix/split-noise.png0000644000076400007640000001437611147553271014130 0ustar bilbil‰PNG  IHDRú›KD†ÂbKGDÿÿÿ ½§“ pHYs  šœtIME× #8((ç‹IDATxÚíÝyTSwÞð'¶°EPÀPAT@‚KKGëq¬bGZ*(µ‹BAQµñt\Š¥®”Ñ©èpðl¦!¸•E0ŒŒ‘°T!e Éû‡¯÷4”%, ßÏ9žã½¹¹á~yr÷ßeÉår9!jMƒJ@BA'„PÐ !tBȽ­­ ýë_QSSóÒ7Êd2¤¦¦‚ÇãáÔ©Sèèè j2L±ÿ8âóÏ?Gff&d2ÙKßXPP€ØØX…B!## ÓÔ××£¶¶ö•„­­-Øl6µFI$>žZ¡JKKqóæMÌž=›ŠAz¿Þ•ììl„††âîÝ»T±aâÆHOO§B¾=** ¥¥¥X¿~=3.??‘‘‘(++cÆMš4 nnnX±b,,,àââBÕTA £BŒ´M÷åË—cþüùÐÐÐPØwuuŤI“˜q\.«W¯†››&L˜SSSª¦ jkkCVVb¤ÝÊÊ VVV ãLLL`bbÒéÍ\.ÎÎÎTÅAôðáCìÙ³ÇïÑÞ’H$ÐÒÒ‚––{¤í£“áC.—£¥¥g@æ¿iÓ&ZÃSÐÉHS__Û·oS!(èD•””àÈ‘#T :!„‚N¡ BÞ ÞIbccƒßwQWWWG-@ˆº­Ñïß¿¡PÈü[¶lµ!´éN¡ B(è„ ºÊñõõ¥.»]ÝåææbåÊ•HLLdÆmÞ¼7oÞì÷¼ÓÒÒðå—_üüüPYYI§ “¡"‹1~üxf¸¾¾­­­ýž¯D"ÁöíÛáìì '''H¥R*6¨“ÆÆFê=ˆ‚N†£É“'ÊËËû=¯ÿüç?ؽ{7•‚N†WWWÈår‚ûŒ§OŸ"&&†ŠMA'ƒeß¾} ƒ¦¦æ }æ³gϨ—^51¨×º¿X ½PQQA-ÐCYYY8~ü8öîÝKÅ Ã;èÉÉÉ ÃHJJ¢VBîîîÈÈÈ€»»;ƒ‚®ãÆSÖÓÓ£b?ÆèÑ£»}Ãá@__µµµ;v,ŒöÑÉ@),,D}}=`áÂ…^ÏÉÉAKKË€|¶‹‹ ^ýu?~œ‚Öèd ”——£®®qqq°´´„±±1Nž<ÙiºmÛ¶áý÷ßÇ„ úüY“'OVè›ÿÌ™3Ôå3 †_~ùùùùžÏȇd8;;ƒÏç3ÃÿøÇ?óæÍ£† Mw2Ô‚ƒƒ1uêT¥Ï÷رcƒz*PÐÉ+ö¡ÇŒ£Ôyž8qk×®‹Å¢Ó¦;Q77n‹Å‚¶¶6`Ô¨QTZ£u£££Ã„üÅ1BA'„PÐ !tÒ#—/_†¥¥%ìíí©¤Ïõ`Ü’%K† ©^!//ëÖ­ë×Å0}ebb‚ ´´”‚‚ÞsQQQ Ã[·nEJJ µÂsppÀ¡C‡:×ÕÕÅìÙ³)èôÞ±³³S622¢PSSSÔÕÕõy­¯«« sss*$ gIIIàñx …T BAW%õõõ¨ªª‚³³s·Ó899 èõï„‚N˜P(Ä;w°råÊn§Y¾|9Šô^#„‚NTULL ²²²¨„6ÝUA@@44zÿ{, Áår©€„‚>\=xð€ù?‚$´é®¦,X@E tòr%%%((( B¡Ùtß±c‡Âòòò¨Àµkב‘ÿ—N÷õ×_cÆ T0 ºr999) _¿~Z@I:„.¯YïΩS§““CÅ£ +—···ÂpZZ…]I<<<°eË–^Ð>:QAB¡°Ó©RÖìçë©TJE¦ “¡ÖÑÑ'Ož(}¾>>>`±X8{ö,™‚N†ƒºº:<}ú¯½öZ·ÓA,÷zÞyyyøõ×_©È´N†—Ë…••„B!V¬XÑít'OžDss3/^Ü«Ç.}ýõ×ðòò‚›››Öèd¨˜ššbýúõ=šöäÉ“ðó󃎎Ž‚NT•ŸŸÊËË©„6ÝÕÍo¼iÓ¦ÁÂÂ=ƒs„ÖèD êëë{}½;›ÍF^^ aaaÑå4—.]BXX€ç7Ëôæ!Ї6óiN”I.—C"‘ôú}úúúÆÃÙÙííí())Akk+€çÏ?ïÍSX·lÙ‰D‘H„¶¶6…G7 :é¥Ë—/cñâÅHJJRÊüÖ¬YƒöövÈår\¼x...}žWxx8æÏŸ¹sçbâĉÔXô®íß¿_ᦖ{÷îQ üAhh(RRR““ƒ¥K—*ež………àñxزe 233©È´>°ŒÁår™½9‡;ÒLœ8>>>J™×Î;±qãF@ff&LLLàèèHE¦5úÀøä“O†¯_¿Ž›7oR+ ¢»wïbíÚµ°¶¶¦bШ£·Þz Ÿ}ö‚‚NÔMNNLLL»víêôÌôwÞy‡ LA'Ö–ÖK—ÜSöööÆuwà ¡MwB­Ñ{îÇT~ôèµ€Š™5knݺE7µPл—œœ¬pSËÿþ÷?jsàÀðx>>8þ¼Ê/ÇÔ©S‘ŸŸŸþ™•‚Nº"‘HT~æÎ‹¨¨(ѳô(èä´µµŽ­[·ªü²¸¹¹¡¼¼þþþhll¤Æ¥ ðóóC\\ŒáêêªË´wï^ˆÅb´¶¶RSÐG¶––´··£¤¤öööjµl<cÇŽESS5ô0Ħ žððp˜˜˜à·ß~SËåËÌÌ„µµ5._¾ ;;;jpZ£\[·n…©©)tttÔrùÚÚÚÜÜ\jl úÈSXX]]]„„„àôéÓjûŒµ€€lÚ´ {÷î¥F§ <999Ð××ÇÁƒ1qâDµ]ÎÏ?ÿœ›‚NF+++,^¼111TŒabPÆ988(<ÀááÇÔjÈÐЖ––ð÷÷‡žž|}}©(#)è7nÜP^»v-Î;§öEnkkƒT*‡Ã1_,°ÙlÔÖÖ¢µµUm>Ò¦{8ŽÂ?6{dœÝËÊʽ{÷ðé§ŸŽ˜/ÖŸÿügˆÅb<|ø”4ÚGWµµµ¶X¡ «™’’DGGS!þ`Ñ¢E(,,Dmm-Ž?N¡ «¾œœ¤¦¦öïßõë×£¦¦?ýôV­Z5"kâáá;wî@,ãÀô%¡ «&???ˆÅbÄÅÅáí·ßF^^"""0vìX,_¾Ë—/GQQÞ|óÍ[£/¾ø_~ù%¾úê+™EBAVòóó±aÜ8q666ÈÎΆ@ Àœ9s  ñ÷¿ÿ2™ \.ï¾û.,X±XŒï¾ûnD×ÍÑÑ÷îÝŸÏÇ©S§`ccƒ€€ˆD"øûû£²²’¾\lÄßÔÒÐЗžúrttijgÏàììŒ5kÖ ´´X¼x1.]º„×^{ Àb±Îüîß¿Ïü¤ÿH²X,…zžžÞeï4aaaÈÈÈÀÝ»wqåÊèééaܸq€ºº:Ñ); úsOžxðGŽÁŒ3PRR‚¿ýío˜1cFŸ‚~äȦëcàóù˜:u*ÒÓÓñÖ[o¡¹¹?üðƒÂ{===‘žž©T kkkp¹\äçç3¯¿ÿþû´ÙL:IIIaúµãñx044DAAAŸç—““ƒ––Ìœ9ÖÖÖL§ׯ_Gss3ÀÌÌ ŽŽŽ(**‚H$‚››®]»ÖéXPUUžZ[[1mÚ4ÀÂÂÖÖÖÌÈ‹ƒ¦¦¦°µµEEEjjjàââ‚;wî(ÌËÖÖÕÕÕxöìY>Û‡†——×Ðî£{yyaÑ¢Eݾ„´´4öù3^lÖkiiõûïmkkSÊŽT*…††F¿Ÿ¾"“É “É”rO€2–M]— xþÔ6›Ý§­@MMM”––BGG555¨©©¦¦&0gqûömf\QQQ§³<`^ïÉ÷º¾¾µµµÊ;×ÐЀššXXXôªgtû:‡ÃAfff¿.&ÉÍÍÅáÇ‘ÐïÆæñx …ýžŸŸ>þøcÌ;·_óILLD~~>öíÛׯù455ÁÕÕµ_?¨/Žq|ðÁpssë×|.\¸€Û·ow»[ØSÍÍÍxýõ×q÷îÝ~·Ù‚  ++«~ÍçÀàp8è×|Š‹‹±uëV¤¥¥)e¥Ûé§ÙÉÉ ¥¥¥¸rå æÍ›HHH€½½=sŒŒŒ`nnŽôôtèëëcìØ±´GÈ0Õ)è[¶lACC®\¹‚o¾ùÀó#`ccÃLgccƒµk×"-- K–,¡£Ó„ cš»ºxf¯««+ÜÝÝ™a+++xxxtzˆÞøñãáááÁ|è­äädÌœ9–––}_MM˜˜˜0çÊûƒÃá(œ‹ï+L™2FFFýš›Í†……E¿7'ç½¾ôö¬È@.—¹¹y¿—‹ÅbÁÀÀ ßËzzzpppè÷Õv999ÐÒÒê÷ŠOCC£GVZÿÿ]žG,¾¾¾X·n݈¾áƒ¨eí£ø¦;!d죦‘Ôttt†åÍ6CºéN¡MwBˆ*ýÂ… ˆŒŒ|åt•••ˆŒŒd® "d(TUUá§Ÿ~R'•J‰ääd…ñgΜÁ±cÇÆ]½z‘‘‘xüø13®¤¤‘‘‘Ì‘/ØØXÕ zBB*++¡««ËtÊЕšš|óÍ7ÐÕÕEjjªÂ *„ –úúzãüùó ãÃÃá««‹²²2\¸pÀó»úè#\¿~ÀóÞY<==!‘Hμ¿´´÷î݃§§'> ‡óçÏC*•¢¬¬Œ™nçÎH$Xºt)ÊËË<¿ªìÃ?1m$‹öãU:è<"‘€é²çûᅦ™™’’’˜éôôô0~üxhiia̘1”Ö~ˆGvv6ÂÂÂÐØØÈd2\¼x|>B¡ÑÑщDøôÓOqöìYœ={ååå(((À›o¾‰’’…BDDD@*•¢½½2™ ÀóÛƒ[[[ºº:æýaaaËåÈÎΆL&ƒP(DBBŠ‹‹áîî¡P¡P[[[\¾|mmmL/2™ mmmCZ·––£¶¶Va{ÆŒ¨©©Á¤I“vvv¨¨¨@^^æææH$°³³‹Å‚‘‘¸\. all ¹\333¬\¹Ráó§OŸŽ‚‚”••1}*À_­²}ûvìÝ»—/_fbØØØÀÇLJ)ðüzú 6`ÿþýðññÁ‚ (­ý°~ýzüûßÿFhh¨Bï=+W®d¾\gΜaîi>zô(àƒ>x妫\.gºç@€§OŸ2󬪪Âܹs±qãÆnçÁçó¡¥¥… à矆¹¹9òóóáêê:¤ukllÄ7```€Û·oÃÂÂpîÜ9øûûÃÙÙ¡¡¡€}ûöaÇŽøõ×_ñí·ß|||‹£GâøñãÐÖÖ†ƒƒÞ}÷]=zü1ø|>är9|||:õuƒÀÀ@èëë+õtÁŒóööFhh(sƒEJJ 233ÅLÓÜÜŒˆˆæj®%K–€ÏçãСCH$̦éÓ§ÃÁÁÅÅÅÐÐÐÀ£GP^^Ž={öàÒ¥KÌŽ!!! …رcóc°lÙ2|ñÅHIIa:vJ¥X²d fÏž¨¨(455aܸqøè£¨á@—w¯õðâ®>}}}f÷ÈÊÊ &L`¦ÑÖÖÆôéÓ!‰```˜˜˜à7ÞÀýû÷¡¯¯ºº:# MMMÐÐÐ@PP&L˜€ùóçÃÀÀÍÍÍ000€““ôôô0qâDæ¶fØÙÙaþüù¨¬¬„æÎËl9¤¦¦bÊ”)X½z55Ú¡5:y¥Ó§OC(b Ö Û¶mÃÌ™3±bÅ êÌ“‚N†RSSÚÛÛ1jÔ(¥Ï[,c̘1Jéótïÿ¸»¡zËŽI4IEND®B`‚snd-16.1/pix/j0j1.png0000644000076400007640000001251511147553267012424 0ustar bilbil‰PNG  IHDRÈv˜Ü›sRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ / A¯€ÍIDATxÚíyTGÇ?Ü Äˆ‚D.ñЬ ¢F\ã…MV“ÕÕ©/<äÁƒTUUA^^.\`Ò¤ItêÔ‰ÀÀ@ñÔÏnbôM™›cnnÎ’%K(((àîÝ»lÚ´‰C‡áääDÿþý4hVVV"š–@~‹½½=öööDFF¢R©8uê ìÞ½›)S¦àææ&ZÇMW bkkK`` dff’Àš5kðööÆÇLJ×_333‘3@÷ÅrwwgÖ¬Y$''£T*IOOgàÀ|øá‡"g¶IOOçêÕ«€Üû®¬]»–¼¼<¶mÛÆ¼yó(..æ­·ÞÒYÓµ@¤Vlll´|–––z› ¬X±I’8}ú46lÀÎÎŽ™3gâè舃ƒƒÈ5B ºÇÅÅZµj¥÷ cbb‚¿¿?þþþ;vŒóçϳÿ~&L˜À¤I“°µµ¹GÔA„……ñõ×_STTİaȈˆ #"ø-K—.%!!êêj ÀîÝ»Q©T"a„@iÑ¢ ,`ß¾}ܽ{—©S§M~~¾H!ÁC:tèÀüùóÙ¸q#ååå̘1ƒ¨¨( EâÒ¾}{æÌ™Ãþýû)))aĈܼyS$Œ`.’@wXYY±hÑ" Àüùó±³³#,, ooo‘8B ‚‡ôë×ooo®\¹ÂƱ´´$44”>}úˆÄy2GåĉüðÃuÂ6oÞ___|}}9~ü8k×®ÅÑÑ‘5kÖвeKÝœ¤° j†yz‚(¦3Œr<ˆ¾²cÇ8@hh(ÁÁÁ5‡5WVÖ<81ÀĤöSSaÄx(¸øxpr‚º<<€÷ßkë_ÃÌÌÀ\B z€Z­fÙ²ež9CÔ˜1¿î8p^~¹æÁï½Ï=§Û HL„ãÇk†= £GÿúÛÏüý…:D¤øôS$ˆ‰ÁÒÅ…¥Î΄'$ ½ð“§LÁ+4ž¾þ¯eÈy{”[·äë“,—0Ÿ}wï /À_þ"ï н`E ÒÄJŸ–·k×àË/ÁÎN6aƓ͚‡™ (++ãÌ™3DGGãææÆÊ•+iÖ¬™þÜKY|ÿ½ü=%23e“¯K0@¾777!!:¸wÊËaÛ6¸}®\ d1øûƒ³óSE3{ölŠ‹‹™9s&}úôÑ/¡>ž#GްpáB `X9K’ds35N‚;w`î\pt//!ßRTTDII S§NeìØ±ú)û÷!/OnŹ~]þþÆЫ—Ü¢ÓÀœ>}šÈÈH,,,øç?ÿ‰£££aÚ*—.An.üç?Щɦé/ƒèô•kæÍÈÈàâÅ‹€þŽIçüyX·N¶¡»u¥²Ñ/iàÀ 8””‚‚‚˜6mšaÎÙ«—¼7nÈMßëÖÉaÝ»Ã/ó,ëaIØðŒ5JÚ¼y³¤äåIÒš5’Ô¿¿$Í›'I7oJúŠF£‘Ö®]+ùúúJ©©©’Á£ÑÈÛÊ•’Ô·¯$EDHÒ¹szu‰M³¢ÑÀÑ£°u«Ü ûòËrë‹®|¤ê™´´46lØ€™™›7o¦yóæ†ß\ôóÏP\ ÿú—Ül>d¼òŠ\g•ôB¥’[¡¢£¡M˜6M.Þ I’X¶lYYY¼þúëøûûëÎ ²±¹u ¾ø’“å—Ù»ïÊûF˜ Çø"Ir³ìÒ¥ò[ªcGY]ºE^ÊÉÉa×®]\¾|™O>ùkkkLêrp44.\+öffriÿöÛr³º±UÒ…›7aË9‘çÍ“+ˆF†‹‹ +W®äÓO?% €Áƒ3{ölÃé;ù=úö•7€;esx̹#òQäzÂ8¤§Ã¢E°p!üõ¯r¯ŠãQ^{í5Ž;†“'O6¬žø§åÍ7᫯d+`É „ÇE òTÁÕ«²Ûxn.„†Êož&4Á› ÁÁÁ¸¸¸°}ûvŠ‹‹ñ÷÷×NØg<÷Lœ(oéé°}»\W17—MgwB~¤¬LX´w/ôì ]»Â/+a5u._¾ŒB¡`äÈ‘,X°@¯§|}f]\zö”-¹¶4˜@Ž?Nrrò/÷r€yóæ=»@bb`Ó&y°Ï[oÉîׂǘ3g………,X°€Þ½{÷ÍîÛ'ç‰Aƒ GÙ ÂRUUEUU•Ö^ üóÙ½>üP“ðÞ{ RY3dª««ÉÎÎfݺuܾ}›½{÷÷ÊZjµ<´xÕ*Ù;bêTøÇ?ŒÜÄ*+ƒ“'åqÞÞòM“mÝh4”J%)))Œ5ŠQ£FOkWmdgË/S•J»*»·•@ââdsÊÃ&M’½iš7nðÙgŸ‘””Ć p3òQZŽ“_°íÛÂO5R¿[±4˜?._–(uè r·èСsçÎÅÃÃÐÐPºté²eËŒ¿4 ·¸8˜>] Ù£‡Ü|\ËxýìÉÍ…eËdœÁƒåñB:gäÈ‘|õÕWL˜0±cDz{÷î¦qãAA”${kß¼ ýûCd¤$#Cv Y¼XžzæóÏe‡5A½òÒK/qàÀ~üñG† Æ¡C‡¨üí<]ÆÊòåpä””ȃáRRô°’™)W¤22`æLxé¥&ÕÁ§Oüïÿc÷îÝTTT†‡‡GÓ¹ùœyhuçÎzR‚””À;ïÈ- =zÈnBˆ§§'«W¯Æ××—°°0Þ~ûmíHP£ÇÅ¥†8­™Ä,†¾ÅŲá„ "gê)û÷ï'""‚¡C‡2wî\Z·nݤî¿ÞrìØ1nß¾]#¬ë¿ÿíoÐyölÑÉgTTT˜˜È–-[˜5k£¦ÔÈ©÷f^Ú¶m[#lƒ­-ý­­é,ÄaX[[Œ««+[·neçÎ,\¸___ãöïBLû#ø\ºt‰¨¨(***˜1c½zõ2Ža¿O@,$!øÃôêÕ‹ÈÈH–.]ʾ}û?~}:jµšÁƒ3nÜ8Z´h!"hÚXYYaeeÅŠ+¨ªª"==3gΰxñbJJJ ÅÙÙ™N: š6x{{ãíí ÀÙ³g¹qãkÖ¬¡cÇŽLž<gggìììê­t 20aÿýï‰'))‰ÄÄDúô郗—3žq)îß"Z±F£àƒ>àöíÛœ9s†)S¦hë6ãÇ%ˆ ébúËœVáááܾ}›ÒÒR¶nÝJÊ/3•óÚ#›»ººÒµkWýHAAvè­J¥OUPo´mÛV;ŠuݺuÚð¯¿þšêêjm©³hÑ"<3KgÇŽ™?~à 䧟~â»ï¾ °°P>ž¿ýíoõò`vîÜÉ›o¾©óx=Šööö:;%%…Ö­[Ó¹sgÇ‘‘AII ~~~:;//Ë—/?1vìØññÄÑÑ‘qãÆ=õ ÉËËcâĉ´hÑ‚{÷îñàÁ233ñòòúÝÿÛØØü¡ó=-éééX[[×KÜ………äääÔKܧNª—¸sss ÀÅÅEçq?xð€^xá±ÑuÁéÓ§)((¨—4ÉÌÌD£Ñpà@ƒ»fwww þy^|ñŧ¯ƒ< WWW”Jå÷1¢¦ÊLMY¿~}£ß¸££#ŽŽŽ)W_}ÕஹW¯^™Ö®@õ§KúÄß:fffO¨úD«V­°°°0¸ë¶¶¶®·¥ÿõºÊmuu5jµKKKÌÌÌj=N£ÑPYY‰……Eý-ããÑŽhš5kVë±jµFSç1º¦^sã¦M›((( M›6,\¸°ÖãöìÙCFFÍš5cÉ’%XYY‰œÓDXµj•öû™3g8}úô»ví»víâÁƒŒ9ÿ†¹@©žØ²e‹ôã?J’$IYYYRDDÄ‹‹‹“Ž?.I’$•••Iï½÷žÔ”HII‘bcc¥ØØX©´´T*--•bcc¥ÔÔTŸëÒ¥Kuî/..Ö^˹sç$I’¤ŠŠ )##£ÞÓ!..N:qâD­ûßyçéþýû’F£‘V¯^-ݹs§AžO½ÕAT*666Ú–®Úü´îß¿¯-2mmm)++kRoÐÖ­[‡ƒƒåååìÙ³ggg¾ùæÒÒÒtz®>ú¨Îý´mÛ–øøxZ·nJ¥bÆ õ¾èê•+WˆŠŠ¢¨¨¨Öc*++±²²ÂÄÄírÎõðæmd<==qrrÂÏÏï¾ûŽN:ѯ_?BBBرcG­ÿ;xð ……BÁ÷ßJ¥bÏž=,^¼…BÁùóç¹£P¡PðÁpÿþýß­÷íÛ'''<<<Ø»wo½tºþ–=zpøðaΞ=«wϧÞâïﯵ'Ož<É Aƒ´û>þøcíìÖ­›ÖÍ%11‘!C†Õ<¯¾ú*J¥¥RItt4jµš]»v±jÕ*”J%±±±€ìHªT* áêÕ«èÓ§O¬gY×|ùå—O ÏÉÉaݺuÚßîîî\»v µZZ­Ö™§G£UÒûõ뇉‰ …‚ñãÇÓ¿í¾¢¢"***ðòòÂÂÂ…BÁ!C ¹ÿw(--%""‚»wïr§î×Rm íÚµ£gÏžzw/æææZw¤G{¶«ªª(((Ðþž9s&‘‘‘äææ²zõj,-- ¿ËÏÏ4sçέñÛÍÍ­ÖNIcåÛo¿å§Ÿ~¢eË–˜››cjjÊ€ˆ‰‰!))‰ÌÌLfΜùÄÿ–••aeeÅèÑ£¹uë–V O¢yóæ$%%QZZÊÅ‹k=.** 777ªªªpuuà›o¾!;;›k×®‘””„ŸŸÖÖÖ:M‡áÇ3|øðÇÂ=<p/f™¹7IEND®B`‚snd-16.1/pix/brownian.png0000644000076400007640000000250711147553266013476 0ustar bilbil‰PNG  IHDRþxÒO”bKGDÿÿÿ ½§“ pHYs  šœtIME×.½ !‘ÔIDATxÚíÝÛvÚ:Ð(ƒÿÿeõ‰WÕÕwËs¾œB¡^[[ÂÈ!Æ€Wùõ€à‚> ø_!„ŸÂa÷nüÂOŒñ'ÆØæÑû· ÷yÊ-…ü[H€ ƒŸ ·.œã‚ÿw46"ä­þr‘®g®=zà¦sü\€k¡x0Ç|@ðÁ|@ðÁÁ|@ðÁ¸¹Ço¶ L|›m‚V|@ðÁßK‚> ø€à‚> ø€à‚¿‰ç‚|@ð9‚c4Ï#>P3Õ.»ßûä6æüÖ.»ßïkùA«>0mðCZ~˜aŽ¿f- „`¡´úÀôÁwbñÿ[ÁxxÏì`ÚîkÿáE#~ŒñŸ~ÁAèk_ƒà¿”ÑÁYà¿¡Oÿ ³ú¼ùO[~Lj¯åêÀˆ?A'û¬?ñ' |î€ÚÈÞz[0ýž.#þCÖ–»ûäþ딌ø7 }O K]Á·ƒÈÝ®0`ÄX1èiû׬ Ø?Á¿yë¼ælÀ\°ÓÛ„ÁoëªbP fî{½ €=ëk ƒb‚9þÜUܬ9>'M ¾#q铃¹·Gƒ»W G.h‚à3¸ÞYÒ¯sÁ+½»PûÂ÷±÷(GÅEð__$–A_žs‹-J Κu„;‡õ­…DðÒä¦ é4¡õNC:²—ŠC+ µ)H©@”~¦·ËX~}ÖÙ3ÁèúÀ𢒮#Ôv%êí–A©#éy»²wŠÐÛ µžóÞÁ~Ú©Ø‚¯»(®-Ô$[?ßs¶b®éYsh­uŒt-­õÖcì縶0”ÖnzŠ›à³ª”~¶ç´ãRñÈ}¯´ŽÐ{°çÖ;jE¦ö:ÔO{:‘žðþköލÝGðÙTJ÷oM5z¦2é MµÇ,u)½©TÒ"°¼_îy•Ú³–’+ éÂm©Û¨uJ¹à\}n¿žQkùkEfíž µiÉh‹^zìôs¹Ïôv/¥ßS{ Áç’)ÃUϳgÑsôgj…£5%*¨ÖÏô®¹”¾§Õçkw*8½ïÒôœÑ¢$ø(u5£.˜^\]p^HðAðÁ˜C÷ <µ³ Fw–ݲ-pRðk­¹ÈÄšûŽøgÛ{»'x³t€ý´”û¸ä£ô– €¿w/÷;µèwš*Üqêâ9yN9¿G>i#2Ƶúè”*ì«ÏÔ¡×)™ãc„û炌¹ H¶nï¹tîqFïšËjóЋfútßþ¯eé2Îé6i¥½F®Ÿû}­íÜî¼'Äñ[ßG~Ï{{¯"›†zËë\û¨÷]æÞ¥ÂX:Ööºýècüó„sä]à¯ù7 úEc¹.ÑsÉè½ÿÖ‘«ÜŽÞ~ô1þq³¶ [„¥…ÁÒµâG÷qìÙ FÑ(œÎÕç¨ùÌvÜa<ƪ> Œxƒ?›ìkbPÐIEND®B`‚snd-16.1/pix/prefs.png0000644000076400007640000052031211526026052012762 0ustar bilbil‰PNG  IHDR¼rÊê±êsRGB®Îé pHYs  šœtIMEÛ % æÄº IDATxÚìw|×ÀŸó¾ï]¹÷&¹Ù;2ÄHD¤JB­PŠj)­ªÑ–jêW´ÕVi«èP¥jS1Z3©Q„U«ˆ½2AÈNî~ß÷üþ8¼½îi(z¾øÜg½g>ç9ãAˆCê/À( …B¡PœÁ›xÓU=§Žðj—Ûï2\E´H( …B¹/±o“{?°hõ`¼­OOÐ`À•`@·ñ Zð`1ª8Õî70¾ WO\:M… …B¡PîOÒ Ù—0‚­nüx3žI¸w}¨ó3|mÄî$ OFÓòå&ø® ÜøT3ÏàwN£ š"8@<0f@^ôrìb«!„Õ¬6¦…RË`À<ð@:€jõ5’GÊB•Œ¼—X®"ÚC)”‡n„#¶~XC,sÙ»BEgÏ3 –1LÝzXrîc\þ×°ˆÇDÆ`–ø´ý%—ª+×ÅJ+#Ä£›BƒŒ€Åʬºq¹íÕN“1Mgêd™ž< "’(”Z&Bò¶ïK2$„ ¢q·þàªÊ_åÀÙÈ 0€ã(€ñ~ýǼUXpué¡•ïûOç¼ä®… ‘P(”ûÄT”—"—Ý›ÍFÄb®ª¨øbò$•RiçÉd6ðþûFc#LFýøñãûôéS§N¸)6,úñÇÇŽÕë++B ÈÀ‚`ÄÑ‘Ñe&³Ùz˰‚1DZu£ÂN¶ €H«B©eüYݯgä “qƒ½zÇœùÚ¼@!„aÀJ¤@à± b8IJˆ5‹Öš–—¯^iÚ+E¨ Œ‘_{‰yXÄrˆ³h!‘€ÉDm#a €Í¢…E,±È"–CðX°@–r$ó&‘3Ä€þ¦X„Z›Jí ™EwB?dà0`333µZ­—ªªª> `´&#cÓæÍÛÛF†™LÖ·?ƒÁðÑGc²b$Ú À²FÐÀ_Ò,¼¼²Êl1£› „ “Ë}¼¼Ïíæš€¡7-(”»0"p ·}÷ööýÓÞþî7ïLn]Øä«sß_Í+0_½È_MQ%uÝ= @s}zÌ„VbFœY¸ä}¾+þ§G=ƒ\Þó×g¿^zmíªˆñµm`YI樼‰—ÅB!%ïŒ!¯é¸¸¿?oñ¦ÇLh¦h̳ü7—çM¹2›ELEÓc»*(Å£šÄŒÒ-ý³ßöôÒ~6bP@oÀp_]ß42,bJÄû=}:ƒ¿Td½uî“kP<­Î¸—}ŸE|-qò“LÓV†Ê J­€‹"v¡i û ÈrCÀ"Öjµ5Ââß }†e:„E0F@"£Á¸qݺ¯¼’Ú¢å/ Ã<ùÔÓ~~¾?-[f6™Iœ ÀKš3ˆ†¬u1ÝĤPj@E×'@ÄÀ˜oÈ¢(ÄÇ7œñÝ4³Ù,ùQ«ÕO>õ4ÆXø[¼À¢nú´oûöqèða Ã2 óÝ·SxžÇÈ ˆ·Ûž0B<cŒ30B€ ÀŒˆø¿3D¡PjSh°€(Š~½Ûô¬2T-^³ä“™Ÿ1õ9ÀètΙôÌ%•øØä˜`u Zî±aN •Â$­^³®|¸Þèú=oD‡˜hß:ŒŒYóý â¡‘¬¾Ï&Ú3‡Ž^º~¹å&¡A‚¿Â`6Ï_Oü¤ŠMveíeš1ëwlÜvrGÝÇë÷¨ÏÆ41×€w¦Œ‘'k^>šÞ€€Ÿ¾]B6PÖ­Úp·Æ/>Ó¿SûŽYçv|ýë÷Ê ˆ¯ƒA UJ¡Ôê!mO¸›„1²B0EA4ô«ÕV±(ŠÂ-: ,ò¼¸}Û–VmÓÃŽß²0ÆV«åï8o+4X€a€ôs†A ‹ˆTà ÝF" +Ýž PîˆÀƒŒ•ý¶g{Ú+<ý¼å u‚§aE zƒà¬!¨¤©™á˜«×¯~4}‹¨áDá™ìËÇ“Âã[¦¶¸.”¦ÅµúbÝ×ØÂ‘(0ƒÉ.£Å´ãÄ®NÉíW|½ôÊCD6n¶®óï—ö5ŽoØã‰§];––p¥üê>űٿýíÄΊëÀ^•¿ úvôL…RÛBƒÅb=æ}•Jé(1Lýæ+ SÎX€á˜eÀ¶"üÍK•!ÄXn¨0KËÊßxëm«ÕúÍWS†yîùÞ|kÄ÷Ó§ùúú rdRàÍöC„ J¥ËZoH Ä`@2–³Zyr9“j(”Z[°…·ò¼° cù IÂ*Zɶ"c¥UÖó÷ÁSÔ£»·{ ±èÀ™C¹Y§…VÀ‹V+o 2‘r`̵×ûtx®ƒ¢}vÞ±C¿#Á"XAÀˆg”VY—íý¿ñþà™ÖÝE,î;u `Ûy¡áÆŠDD2¸Ì<º¡¡=ûôÁ3Ù?Z?0E´ì¥ŽýZ'·:~þäŠå?WxW•éË_iÒßÃCõÛŸ;¾^0‡W‚ Óç"(”Úx@‚ ¢ZÍkC</g,#Î~òæâQ¨\d9V¨‘]SvZú›eöòñ, ÇÜG_ðúxT,0,§òW{ë5A3<~4á^Œ•a, baè‘÷„yo¢rÌÊ9 º,׌‹PïEê¯yg—Ìœ1CS¥òl¢­_6cÌ\¸beÖ+ÌÛRÎNâøüÍ/ñ5žeX¥Ÿ‡ŒSõÌx™ÙaÂUËqê0O&P†ÌXè8A¡ÔªÐ e<êÐ>Méðú‚ÅjµZ,76xD6<µÚ Ÿ~n{EcW/Îjµ"@ÈzãôÏó:´ïÓû9I!ðüœY3L_" `¬ˆ±ÞÜ‹ÐD{5ÞøxîÎÓ€@-ª¼ÌM¦ÍœUÏŠ Ê]Ð5 !–¶Qð3V0˜Å7.^ñ€DL6X@€˜Ìa@"ŠÃ¿=ðö‘0<€]$Ö©#|C)Êoæ ¤Œá["G€e6QI‚Ö&…RËãCZ@ê’'g—”ÊdΧižLEe-~¾¾WÌÆî?—”_“qœ Ÿ¼¥¬ªý®¹fo¯eUE,Ë ‚ Ú¼É Ä²¬•çùJãÓ»^=o¾,7r—Çž¸©i0BÈ&£{{V`¨Ä@¡Ü…Äß¿¬Nºâo<ãzëHrC\Ö"H@îÕ¬ ,Nœþózy¡Ÿ*V V̘o¼Ó€4Ñ^MÖ>ž—udˆaéñ% …B¡Pî;¬"oÍ·{kXµ€ƒ`B·ó©f=0ÆzÁpÛW\U `xà®`‰›!à©(Øþp´j( …By )«uŸ<(ÛF¢®ž6!HVÉy]ô¸"bz½šB¡P(ÊMPÃèú¦J–h.8`Är,À¸ª´ô:-! …B¡P((''ïZQ¡#¾)4°ŒÍK„¨Ù\ …B¡P(Ç!ÄpœŒy oE³ ËÉ8º1A¡P( ÅŒ9Žc0€aŽ“Q™B¡P(Š½Ì “q à«T â8–Ê  …B¡Pá8–a$4°2ŽnOP( …Bq*4Ȇ›·'Næò}ŒñMcY …B¡PNbœß„À˜“q Ë‚t{ÂÍ™„O4-M …B¡P4°A p;²´ô/çQÈ8îoMË0ǹٜ8}úìÆëIb È¢Xz3“B¡P(”ûU\@ˆ}öÙgCBBÈßf³yÖ¬Y>>>äO‹Å¢T*A@ñ<ߪUk—¶æÈí ¶'dëæLË2r¹<66.^¼S·ž ©tÏ‚B¡P(”ûYU®V«µu OLLÄÆÈÈÈM›6¥¦¦ ‚Àó¼N§¨p#4ƒ`r¦Av‰c­V‹By{ûX}Â=7I¡P(Êý©g@Âå[6'0Æ¢(Š¢âééùôÓOçææ²,+Š"ÆØÕþ&gl®\2Ça*P( …ò°CÖÿ`±XÊËË«„»y¦á†ÐÀrÿ¾uK™ îA.0Æ*5xzƒ(Òí …B¡üç0>>>cF<ÏWKh`o ˜aÙ}ðŒô/+–lÝQ»qŠ¢hµXl]ä ôö‹Ï5бÞ> m: …BùOÁó|ãÆ1Æ!ŒqJJ ˲·]mßx§ÿ½=ÁÖ@f@ÔðPƒB rËI]­µæÆUŒ±‡<Ôà¡•yø«<@&¿áȲ€1f!D\¤°Na¸¡æFX–Ä€mX’ĵ«—fó±Z JÕæ¬üù/‹PV,Hº¥Ê!¬úﯓÂ2ìßé2Tä P(ʃ†B¡€›w/É¿W¯^åÜêù1'coÙžà8ÙÊ ãÒâ¢f‘^i aï |î‹÷ßæ­–Ý¿mÚÿûo-$‡z<ªö @Xµž(5Ú'-!,-!¬_—V>~H©BCû<5wêí‹ó?ðÇN"ò‡Õi]?0-!ì‘0µ ÂÎv0ÆòsS£ti a-cýŽÜYëV_¿z屺þi aMÃ5ÁÈCútLy©[³‹f´k>¸W'5€#îiäÓ.¾‘§7KbóòFÃ^xŠd¯i¸60y¨QïöÍÌ&ùº7<ãé0Æ'jã›––퓟sÓc  …Byp0™LÑÑö/µiÓæÀîõ ·¼ÓÀ0¶¦±«‹F‹ÒbŽ—WUÀŸì?{2›“ÉÓ:wÔ£Ó;»«2 á,:SŽËJñÞü¢É8ŸS0nÄÈ÷&~µ+ë—ŽO=ÿÛñKr<›ÖjÖÏ;”*¾O4>U†y+xû@8‹N—ãŠ2ût•*4¤wÛìÂRC(UÐ-å‘ÅòVK—GCÎV`³¼tÁ¡S¥x馽ò/e.ŸÿÖØx zŒjÜ4õdII8‹–(KÐ_~ýÊÛ'7<½¡Žœ¹À‹…—/îùر¢r}%ìÿ}ï¼o¿ë3èOÞyéÐåb“TÐ¥YÓå[þ´˜i#¤P(ʃ\._¼x±Ñh´s÷ôôtÐîi–“¡œiEìG ™ŒàyÐWU¾Ru墨ô`^ö¾Ñ>þèÃ7FÈ (/- ‰€ð¨Þ/½PZ‚­VÄq20™ ?ü´½¢ #„d2àd2W+y…Bi¨£8™ŒýÂÌý¥%!ÄÉ@¡T€É&ƒÁjµô€ñ =Œ(‚¾êֲ˭³ÑÀrà¡Ö€¾ªbóá+—/a„ÕjædrQ„¦-Ú}2r X̦ùkö˜M"Bt—‚B¡P( ôlÙÒÑÝjµ ‚àrÛcNfó¸Ë ŽãîTfÐWÁÌå¿E)djMt\ü¬;‰;B¨²ØŒxø˜Ïz¶n9qæ ³Éˆ1®(/Ù¹9ˆI‹[#D€ôU¨¦MŠn›b`Y°Xp5ãGUUÞòâ¦(âQŸ~{þÜ9Ä0 …rÈóíýò»ÕB!…B¡PApÜ[ÁM ãX†e°d{âŽMc«<àãý·/3ªž7 j Q?Hó®( `XVQTjMÏ6u‡Žú®\:?cÒ—­Šãd-ºa K„«oÀ¼}ýós.XL&™\®õô J•zàÓ)»ó­‹‡ZCŽCp2™( òÎåž=QRTøLß×LFCñõJ8ŸSè¡Ö*UZOï’¢kò΀J­ ˆÅ[SÇcÌrèÅ'S?Ÿ±Üb6“w7iã£P(Êià­Ö¹çŸ ÐWUŒøèg{¿ô¦­cÔãÛvŽ{ç]¹\a6à»wb€°È˜„¤æëW.x~äÇSÃÔ‹O’¦4áÍ÷&›MNÒ5›ðÔ…|÷™L®àyë“æŠ"6õK7]¹x&ÇÉLFï•c„Px¨”Ö~Y±00$¬ÿk¯ë«pIQáÊ¿ã½I鳿|¦ïЈègúõ[:göú£€ÙdX·ïpÉu6z¢”zhDŒÆÓ[àñäY«–Í›ÊÉäV‹ù˹3¦¢…B¡PþBÃ3 Hå9èÄÿ¼.Ë—·Ÿs&?»´´Èq",*²nÚôkrr2BèäÉ“ÉMS¬>ñ5<áy²´¢ªdrеã×ó×q2bo™M1ÆäÍj¢' ZŠ#¶»`Ôßp$wF킈¢ËYYr&fþ4?(4²y«öÄQ H¢E0€”+»°cÄüŒ(bpL]ŠÊ6,…B¡P(÷!]ÙS¯A¼tÈÑl6¯_¿¾Q£FŽÛ<Ï1L¥c<ùùµkÙõ­;vü—Ënh8Nv§³`U%^»;¯‘¿Z­µZ-ã¾^$“ËINífz„]ä¢ÑuãEáï©×i7ëx»½t>jÆ1¶›¢Ã-Žva‰Lì‚8f‰Ê  …Bù"ã8†a1‡„XöŽo „t>~{rKnŠ0À[««®7ñ¬†ÚQïcŒÓºtÇ"Ї¡) …B©u†%yŽ(1jö„4Æ`Ðۯū)p˜ŒP[BOë”B¡P(”»,=Ð" P( …B… …B¡P(Th P( …roájLÄôÔ!…òð€B, <ÉË+ åA‡½ qÖDhàX¨D¯*P(¨²²bçÎ]O=ÕÕí{² åáä•ûCh`hä´:(”‡ ÞÀW•\VËdgaD›E˲v³ÝH¢â­Ë†aîvfÓE¶ï¾Ý—<ˆy¾Ó´}°è4ƒ£XîMå?Úþh'¬üçÅø/VIúÀ–ó®Ï+×” ŒÐ$·É€.Bë†ÚæÊÕïÚ!d2™Ž9âççGR)--mÒ¤ ˲wµBF£1;;; €LTIIIŽÓ°c9H.Ž?\9ÖJëBUUU=z4((HEŒ±Á`hܸñmú'euÛ&Q+mc,ŠâÑ£GµZ- “’’T*Uu2S<»wü¯ Œô $åÆÊñãÇ—••Õî$ô Îý5ójݺõ?_BcÆŒ1 ÷¸lÉà¸ù§Íc;Ï|þòÖËW´Zñm÷o;àpõ–gWHS‰ŠŠzùå—o5+ªTªÔJfDQ,,,LHHˆ‰‰‰‰‰iذáo¿ýææÛ‹‹‹'Nœèª ÈB\t»óŠ1¶Z­EEE‰‰‰$ÝØØØ üúë¯dζ«©E‹EFF¶oß^šÑÇŒfûjm¿~ýbbbÆoëQTTTýVñØc9ý4""TUU5nÜ8:::66¶nݺõêÕ[³fcž%þüóOâ¡Æe…Ú´iSHHHË–-횇¯¯ïŒ3jEb@;w...ŽÔEtttbbâÙ³g+++m? !Ô¬Y³¨¨¨U«V¹I!ôã?†‡‡wîÜÙ¶:š4iµnÝ:[Ç7ªÕêÿÚRŠ ”;àüùó<Ï»Ÿ–$GòÃö_§þûï¿'=8èïtøp ëÔ¥šŽŽÁ‰7„ÐèѣϜ9sÛB°Z­d¶\>ì>Ýj~~nn.Y/:­¬¬¬wïÞ¶éÖŠ<Ú¹fg§':{[9+` = OûŸî¡ïaª2ÙÆÿÑGåççïÚµËÖ‘a£Ñøè£ÞQí¸ÊÌáÇ###=<<$G•JÕ¡C»ÙÈ6B«ÕzáÂWÂ0 BˆXåq“'N„‡‡Û¦«T*»téâ8 ^¾|yÏž=ýõ×¼yóFEþ÷‹/¾¸té’m7IOOÏÍÍýóÏ?mósíÚµ^½z™ÍæêË…v­ËÖ[~~~PPmž E=fΜ骬*++Š,î˪ªªÊöÓ:uêD Á.xqqñ°aÃ\ wÔ öïß_¿~}ÛOóððhܸñÚµkm#Áïᨒ 999î;ø€.^¼h×t>¼jÕªüü|[ÿ;wÖëõî³êª“>¸k'º=A¹³‰ÙÏÏoôèÑ*•J„ &ˆ¢È0̨Q£H§MIIyâ‰'ŒFã®]»:vìHzõwß}÷Æo8íðüñ¡C‡8°cÇŽfÍšuéÒöïß¿~ýz¢ž4iIÂq¡c›nZZZëÖ­`÷îÝ›7o–Â"„V®\Ù«W/â“eÙ?ü¦M›Ö¹sçÅ‹#„žxâ‰ÔÔTؾ}ûöíÛÀ`0Lž<™$1nÜ8’¢\.ÿý÷`ìØ±{öì1:®C‡­ZµrúiééégÏž½pá§Ÿ~Êqܘ1cÈP{æÌ™¥K—bŒ{öìÙ¸qcذaÃþýûíÒuº°þàƒ”Jedd$ÑÄ"„222ÈTAÂÀœ9srssOŸ>=aµZýÎ;ï`Œ-˸qã …  ¨[·n jÿÊ¥+?›ÁÉ튜ÇwvLé(}¾Ýò{ܸq¡W^y%44”¸Ì˜1£M›6+V¬€§žzê‘G€M›6‘iÆMdggK‘Ø&M›6]µjUÏž=%ÁtìØ±ÇÆÏ>ûŒ Ð<Ï;V©T ‚ð /4hÐàüùóK–,€É“'Oš4Éi!:t(,,ÌiºIIIëÖ­{òÉ'mÝIÎ=<<Ú¶m W®\™6mšÏ»ï¾kÖd2Ùµ"âØ6€òòòÉ“'Ëåržç‡L4ùùùf³yâĉntÑÑÑNóÜ AƒíÛ·“¼I±J¥ây¾OŸ>çÎÃ_¹reÆŒ2™Ìb±¼ûî»ÞÞÞÈÊÊ’Éd“&M*++›8q¢íÓO?½nÝ:²5àj£dÚ´i¥¥¥;wnÖ¬q™:uêk¯½6a¹\Þ°aÃçž{ŽHÆ .dYÖl6ôÑGJ¥Ò1œœœ   §Ÿ–œœ<{öì!C†Ø:FɧÝÒ´iSÛºs¬“Éd'`3F£Ñ!…4×ãÇ8pàúõë¶c×ĉ‰ð‡1þä“O`êÔ©½zõš5k˲­[·NKK£BåáÄÛÛ[­VŸ>}º²²’ã¸=z¬Y³&..nëÖ­•••™™ºtéR"4Àÿþ÷?§BôîÝ›a˜:uê<úè£: ÓÓÓ‡*Š¢F£iРÁ©S§œ¨ÈFJ!4{öìÐÐP¹\¾víÚbŒ5M½zõΜ9³|ùò!C†dggWTT‚ðÚk¯Íš5ë­·Þ:uêÔÛo¿1ž={vdd¤ÑhÌÊÊêÛ·/ÆX«ÕÆÅÅ={¶_¿~|ð‹Ífó+¯¼2wîÜ>}úuîÜ9222 ÀUYµjÕ*11qûöí½{÷n^H¨¨¨˜7oÞÀBS¦LùꫯrssOœ8AFI)]§ÃVrrrff¦^¯ÏËË[°`Áwß}GV±RØúõëŸ>}ºC‡‰‰‰'OžìÝ»·¶E‹«V­2 2™lĈ«W¯–Ëåw>Xp;êíprÃq㥊ÒÛÆðÜsÏ­\¹òÔ©Sd¾€áÇ1âÕW_€o¿ý¶N:W®\9xð`u $((Èq;cܼyó‚‚Àáâû IDATÉÛ“O>9uêT‹Å¢ÕjµZí[o½Efˆµk× ŽãÆ?gÎÿ_|qìØ±ýúõ+..v©›e˜ÀÀ@§é¶lÙrýúõ¶Z4///RÎþþþ]ºtÁëtºaÆ…‡‡KBCõÕ<ݺu[´h‘Éd’Ëåƒ Ú¸qãÊ•+ ÅsÏ=çáá‘’’BDIGX–•Ž}Øå955UR%|FFFUU•B¡ˆMOOG 8púôé‹E©T>ýôÓ;w‰ š0aBß¾}É~¥$Øét:»ÃŽtéÒ%77wåÊ•Dh€1cƬ[·nΜ9F£q÷îÝYYYmÛ¶=zôĉ­V«J¥jݺµ«]­ððp§Ÿo«ápZ•õêÕËÊÊ"cׯ%5XuqâÄ÷ßï^~·X, …!4}úô6mÚèt:Û#Ù‹ÅÍÈ.uÔÉ“'÷èÑÃî(ø V«µG’¦‘ ×ëmÿ$ªE0™L*• !4jÔ¨‘#Gº‰–ädðàÁóçÏwô`6›û÷ïÿÚk¯ÝV‘2“ŸŸ¿dÉ’Y³fñ<ïtîÇ“o/++ûì³Ï¦L™+ÿêØ±£{õ+‚Âû2}ç0s@´?Öð˜á±^Á½  Àîìö€ÉR›¨¯]}¦ÅbyþùçÉ&‚›ILL<|ø0¹ôhwnÏž=Ç—|VUUIÓÃÃcôèÑD»`»Ìµ2†ÑjµDkmG“&MŽ=j§í'¿÷íÛ'mÑÿª¨¨ ØÍ?I!“ÉàÖ›“2™Œ¬PÉŸ_|ñ…]Y‘í„Pjjª«í‰äää3gÎøøø8æ9;;{ذa’O©XBM›6%‡111ä3¥}(ÒºX–MII¹~ýºT ¢(º:O¿k×®ÒÒ¿ÏR”••mܸqøðá¶+þ .øøøH͉ò•+WHaúùù 4ˆlLF¥P( Eee¥Ó†‡ŠŽŽÞ·oŸmºååå™™™o¼ñ†ðAZ”­ËñãǵZm½zõt:9í‹zöÙgCBBŽ=J$Q’ŠF£ÉÈÈhذa›6mˆ‘••åéé¬Óé¶nÝŠ1:tèW_}¬Ñh²²²¤“"v3 Gµ½/]^^¾bÅ é ƒôù*•Š$qõêU™L†1ž3gŽ··wpp°§§ç–-[¤×½Ìf³J¥R«Õýõ—¤Yܼy³t¦!´aÃNW¯^=­V{ìØ1I¾iÒ¤ÉÒ¥K===¥ó˜RÆÈÑ™L6jÔ(__ßàà`­V{öìYW·I›7o¾fÍšòòrɱ´´ôÀÝ»w·¬B‰‰‰íÛ·Ÿ:u*Ù[‘ª›4¶“'O¦¥¥!„æÏŸïççæááqùòe¶~ýúݺuûôÓOýüü¤{IJ¥Òd29’Døþûï÷êÕ‹46«ÕJvcccIG%8Ð××—<›‘””ô é›=¢<_;=Ú·ÐcácÓÏžÏ.--r¬›¢"ë¦M¿&''#„Nž<™’’OgÐÿv²¹«ÇdlÎÕÑÊÚ-j¬âsÖiˆÚÙÕc;Ž>c«ÙC1${îÓ½#=¶«°·ÍžSÇ’’’U«V <ø¶)–ä”Ì7Ì¿"»bEÖ¾å}? üì½È÷RQjuŠÝ±¾ªS®())Y¼xqRR’ d;üÅ_$€›Ì¸q©f6®_¿žžžžœœLÖˆ999 ³ÛV“ûFë´[¹Š¡:Ÿf«Æ_¾|yÓ¦MAEñÒ¥KýúõcYÖ}BwÚ…oëîøi¶Í \Z¼x1Yð,{ðàÁ¾}ûÚIóÕ¾\?vÞ\Ýo***zï½÷æÎ{Û°v:Ñ»·9»gÏžøøxéà…Ùl^¿~}£F÷ïxž b'Úµüü¿Úµì:êܧÙÙGV÷]L·'(Õ0omÖŽJöØcdqì¾ܸT'c[­~ëÖ­Ýl÷T³…¸éV®b¨Î§Iy µ½ÄÄ0Œcž«aͲWÍF{GÍ!¤P(^zé%I3”šš*—ËÝ7ƒRÎNO{®a{KöŽÂ>@(Êߣ^5gÛƒ¥žàù¯ |$Erà^Á$þÜYý×%þ+Ïw6“UCºÛ,Z´¨šòî\Ô5ÃóüÙ³gèϦP(v#¬Ùl ;wîœH-ØR(E§¾­–{$4‚PXXHmQ(^^^ä">…By¨Ù‘çÚ Err2­ åa¢¼¼|Ù²eÒ³»÷žçí^Sv„\›Eñ¶ïðûu´Z)ÿeþøãZ“^¹¤P(ŽO`Ýc ŒF#v ±šW¯^ÕëõVA°û“˜¡PþËÜ z’B¹ë9ÏÕ{®.¯V~—6/Ý| y` Ö#÷õõÝ¿¿«˜CCC¥‡†<==mmäææFDDØŠt<ÇN¡P¨¦By(++{æ™gܬ–/_^ã9¸k×®’)Î{ 1 „z÷î‘‘q—â¿|ùrŠ œ Fã²²²:<ûì³ð€ŸK§P¨Ð@¡üG±»ƒ`û”¬í„G~ôéÓÇÎ¥š+~Ø´iÓ„ Üûpt¬ÙÌJ$† 4iÒÄñ¢cmZûöí›7oîø_ÿûßÿ‚ƒƒov·ÏŸ?Ÿ‘‘qúôiz@›B¡B…òv-†AqGÞ—%“Ù¹sç$ÇÉ“'‹A俈£›9ïĉRØiÓ¦Ï}úôá8®cÇŽÒc5©©©Çq'—ËBãÇG:tH ;gΜš}BèñÇ?uêTttôÝ{-ßËË«iÓ¦ŽîS¦Lq¤]»väÇ /¼@…B… åÁ#66cLŒ! 0€X˜Œ‹‹“9R\\Ü´iS²‚'Žnt RX“É„1^¶lÏó’i%Œñž={xžçy~ÕªU£G&æ:[·n-…]»v­3`î5 [¶l»ÿlÎôéÓí\¦NêJƒ2iÒ$É%''gß¾}´íQ(Th P0¼½½¥¹íçŸ&¶m7)Ⱥßq5ï*ÂM›6y{{‡††(•J7ÏŸ?ßd2}ñÅdfÕëõááá¡¡¡aaa6l¨±¦á”ÉðªU«$—ÈÈÈîÝ»;ŠS$?¶†+++—,YB§¢P¨Ð@¡<`ØZî¾xñ"9Äg;ŸÙY¬!?®\¹â*¤¤¤²²²‚‚‚k×®-X° ªªÊn•gÏž=|ø09HfÖÀÀÀ‹/\ºt‰Xö«ñtNâ´µ\»åF.’ØžmÑ¢Edd¤S‘eôèÑ%%%¶.ß}÷d ›B¡Ô:ôÊ%…rWxóÍ7GEfÁëׯqaÈ!Ä|||¤Kƒ~øá¨Q£BUUU3fÌpá{ï½çççG&鈈rd!==ýرc'Nœxûí·‰þüùƒ š;uêtþüyé ¢N§#éæççƒà5þ.’œd<Úé•Ú*À6mÚÄÅÅõéÓÇÓÓÓ±LX–ݱcÇ©S§Ãfee>|øß}¨ŠB¡B…B¹³µrtt´äâççGÜcccz–Ü]v600ÐÎ%44Ô18˲Žak€crw£ÜÈOOÏ… ¦¦¦‚ ÓÕkÖ¬q*èõzz÷’B¡B…Byhaf÷îÝ· O·cÇ[ÅÅÅäÇüÁ²¬!æÒ¥K´H)*4P(”»5gÿ»÷ÂÃÃo«É ï>ùúúº?ƒY³s ¥ö…³Ù¼mÛ6ªý£P2¡¡qãÆ¿ýö- åá@«ÕÞBÇq5¢—¡)”‡ ½^ðàÁvíÚݽ×)ʽ$??ÿ¾X–õ÷÷§õA¡¶ÖS¼«ŸP»‘ßi%:õY+YrŸ„ûäªöþé_w/ZWIÜi©Þû¹Ó±Â)ƒÁ©!u•JE.6Sl¡/BRþ)¡;wÆÇÇß¶Ó"„¶nÝj;Z9õöì³ÏöíÛ×}„f³¹I“&iii÷rÄ'†¡k1ÅÓ§Ooܸñ.}BQQÑüùók1rby+)))))‰âr3”?ùä“-Z´Ø³gÉñ|Û°wT?ýôS«V­^~ùe"ɹñ¹uëÖÜÜ\[—E‹µnÝúµ×^sö~è_ß|óÁ`¨õ¹öõ×_oݺõ‚ \µ„PZZZëÖ­>l;Å6iÒ¤}ûöÕoW‹å‹/¾ø‡íÐÕXñøã1âŸDþ×_ ‚Àߊ^¯?~ü8Þ©¦rWhÕªU5;رcÇìúüìÙ³ãââÚ¶mkëþóÏ?ß6*¹\~øðá:uêÜãÍÈÈ¨ÅØŠ‹‹ï† ‘`4=Z‹3 1ÝI†orÛÂé !Ô¿ÿÅ‹ëtº®]»®Y³F&“Ù†å8ŽXϪñX1¾xñâÞ½{wíÚuôèÑÏ>ûìƒ>påS¯×wèÐA* Œñ¹sçÎ;·sçÎýû÷óÍ7#FŒ¸Ÿû×X»‚È´iÓ ššúñÇŸ>}º~ýúN}nݺuõêÕùùùMš4‘Ö߇ ©~r‚ ìÝ»÷ŸçùÿûßðáÃíºüæÍ›ÿyøøøØ¹èõú»q €  `Œ,X R©úôé#éòóósrrÊËËÍfóÀÉôðÓO?ñ<ߦM›°°0â3==}ß¾}.\(((ˆ‹‹{ôÑG‰`‘ôøãK©,[¶LZ›öíÛ÷Žv.–.]Š16™Lƒ Ú¶m[ZZÚ²eËúôé³~ýúÒÒÒGy¤AƒpðàÁS§N!„Hž`ÇŽmÚ´™7ožR©ä8®wïÞpóµ€7@óæÍëÖ­ë4é 6téÒ…Ì‘¡Ý»w·lÙÒ©OOOÏåË— ‚@r(Š"Ã0?þø#y¶H©TöìÙÖ­[÷ä“O@iiiQQQݺu¯]»&“É6nÜ(} »hÑ"ŽãÌfsÏž=I¬Vkzzº\.¡}ûöN€ªÎ¨ýÈ#`ŒIEˆ¢ØªU«]»v9úÌÎÎnذ¡N§Ã¯_¿žÈ 6”Âò<ß©S§M›6¹InÙ²e­[·v•U„Pdd$1·‘˜˜8qâÄÒÒRòü¥»víš0aBzzºdÛ!oµZ1ÆÍš5ûôÓO_}õUµZ}Ÿt¨¼¼¼Ý»w3 #µCŒ±§§çüùó …(Šýû÷'M\ aÆMš41™LgΜiܸ±$Ý>ýôÓ·M®~ýú†Ì‘ DFIJJ’ÉdpóU1»’¯f¿[²d  $‰GÊ’”\IIIqqqݺuçÏŸÒX‘žžN’ÉdÏ=÷üøã§NÊÈÈðõõ•úìž={òòòêÔ©C: +õ…BÑ«W/Òccc÷ïß1nݺudd$·k Ýž Ô!!!o¾ù¦ôgeeeƒ ÊÊÊt:]:u$M¦N§ËÏÏÿõ×_%Ÿ:N­VkµZNGŒG“¥Lxx¸Q £G®æ !ôþûï{yyétºèèè´´42 ÉåòøøøëׯûúúΞ=»°°¤ëããCòÜ®];øì³Ï’’’bbbt:J¥úôÓOÉò}„ ~~~¾¾¾Ó¦M³3˜$ѤI2æ&&&ºZ™Éd²Áƒ«Õj)‡ à 2$00|,ÆxÚ´i@†NÈÉÉ!F Ož<,}]‡†8p`HHˆN§‹ŠŠJJJòôô€nݺEDDètºÀÀÀ7ÞxÃénuðöö&Ó™Ò¼¼¼œzcY–\Á°­&bö“„­ªª"sà /¼°mÛ67Èu2’˲®š±è]PP`ë¤N\œšý·¨¨¨˜2eŠ¿¿?©A²¾÷òòª_¿~tt´N§ó÷÷ë­·†i×®]TTi$«V­ÊÍÍ-))±5\Ò½{w§I¹M­V“êëÓ§OXXXaaáܹs‰‡I“&ƨx÷ÝwIÞ¢££6lHÒ’²tõêÕyóæ‘y}úôéñññÑÑÑQQQíÚµ“Æ ‚L&#ÖÏ}|| iíJ¥’Ä£V«ýýý‡*¥ûúë¯K}¾ýö[èÚµë‚ |}}ýýý'L˜P»{=TÓ@¡ÜññÄOÛ:<¸_¿~äw·nÝÈŽ;Êd2Û­å®]»ƒíöDlllll¬­E„PÛ¶m¥MÍ)S¦Ü‘jw„ då‘––V¯^=èСCFFÆK/½Û·o7›ÍP·nݨ¨("=tèÐ Cvv6É€Á`X¸p!YúO:•8fffJëW;âãã>ܳgÏÓ§OŸ8qÂÕ®¹ÕjýöÛo¥"JKK€ßÿ]²ÒtíÚµ±cÇ’toHú ÃqY¯Ï™3§k×®¶awíÚEmã½{÷~þùçpâĉöíÛ“™ S§N„úŠ”Ø??=צM¸Wv½ÿ9<Ï›ÍæöíÛ“ír˜ ¼¼<;;[2†þÑG‘v+=ªqìØ±ŠŠ •JEÔ^^^ååå®l™’}"R&>>>Ä* Bˆ„%‚ì?ÿ}ûö‘~Š1>vìÑ–IY’’S«Õ………T(¡.]ºØ6f²Y±b<ùä“Û·ooÛ¶­íöDbbbbb¢dvïÞ=sæLòûúõëï½÷X'NœHÚÒ‚ è¥b*4Pî;î´[º™Bûöí›4i’ DO{GšäçŸ~úôé!–e d—CŒ1YÇTTT|ðÁ.\ c®›“qÒŽCuR¯W¯ÙsqÃ?£%;UN‘Î~_¼x±C‡jµZÅFIRÔb0ˆÕ+2H+6»CìDaW­z½^*=Fóײ$3¶)JUV9ƒ¤N|’vuŸtŸöèуeY«ÕúÄO¼ùæ›!‹Å"ÙDu߈$êÆ)«¹sç¶hÑ¢aÆReÝ=X–u_ÂV«U©TŠ¢Hêeûöí_ý5©D¥Ri§”ª±I$¬èö¥–ÄO޳¶œU ÕjÉ”/P0™L¡… ž:uJ n;9rõêÕ™™™û÷ï—Ò²õæ*Ý={ötìØ±S§NmÛ¶;w®Ý¡}i9þ¼¿¿FFFFF†tL(W‰ÊÊÊ;’êÔ©3räÈ^x¡~ýú®ŽèËd2[Q†PVV&ýöòòªªª"ËMââáááfÊ/--•>-22’¨…SRR²²²222~ùå—ýû÷»5Ü™™Eö\êÔ©#WE=óÌ3O<ñ)«† ’S‡¡áÇïÙ³6oÞL !õã?ºß#""²²²Ü ô™™™S§NE]½z588XšZBáááä°…Tæ*•ÊvîYºté¬Y³BçÏŸ¯Î||o(--ݲe˺uë2226lØðÖ[oUkg"úhµÚæÍ›gff®^½šèÏœz&"iQäO[©Ëb±xzzŠ¢H:‹F£!æLmûÎmûÔ\Bd¿ ¤,Ë¥N3/¿ürff&錿ÿþ»Ôßõz½§§'BèÃ?,--•b Ýüé´ïTGÒr%pS¨Ð@©eÈ™——§P(È6„­2€Œ Ãøúú¶nÝzðàÁÇI+Ñ7ß|sôèÑ …âĉ 4@Mœ8‘ã8‹Å‚"CÃï¿ÿîååE˜gÏž%sžÑh$d2Ù˜1c\Í.sçÎ}ä‘G“““Õj5I×.‡˜˜h2™är9B(%%Å××—Œàyyy!…B¡Óé¶lÙ·´&âŽÓ9/55õüùó>>>áááÇŽ{ñÅ]]…_¿~½§§'ù:rTðÒ¥K$Q…BCr^¹r…8¾òÊ+999UUUÇÙª IÆŠŠŠˆ7R8dѹbÅ ÉqÈ!®×·ÅÏÏ/??ŸTñùóçI) .^¼(IË—/ Dµk×.%%Ha"„òóóZ´åâÅ‹D9áŠ.]º˜L&™LÖ¹s篾úÊVʼtéÑC (Š1cÆ4jÔH.—øá‡Ð½{÷Ë—/ËåòçŸþóÏ?¿Ö :.88˜eYRYdêU«ÕŽ2H¿#äêÕ«M›6 U*•™™™:tضm›Á`p³¾'g{¥?ÉÁ™LƲ쀴Z-9}¢V«{ôèÑ£G©ïTVV"„ôz½L&ûøã]µê#G޼!„._¾lÛg E«V­<==¯\¹B„»°ùùù¤m#„ HXŒñÌ™3›7oβlhh¨N§C ß& IDAT*»±ÂUßqßgk÷«û={öÄÇÇK:6³Ù¼~ýúF9J“<Ï1Œej~þ_íZvuîÓìì#«û.¦g(µ-‡ÞìcäéÀŽcäbÛ']õOÇàNßpvÿþýdì`YÖöîõm“¶ÓmJÙÔî ¡wÕl ÍÍç» âÔgõ˪õk÷Û®ˆjœ§©¸‰¤:¿]9ÞW³ÂmËÊiÓªf?º£qÓg«SzÕé³®]…­N£rÕw\õY÷eEA8B…ÊCŽJ¥"7*m(ÕDÒIüw´D´ÁP(”Zxž¿pá_(”‡ £ÑpñâEjÀ–By8¸÷bj"4‚@4Ñ*¡PBwïMk …r¹g9k"4( ;K åA§¼¼|Ù²eC† ¡EA¡<ÛÎÿ¾Ð@¡P>A¨Î‹Oc‹ÅRPP@þ$.<è‡Ì¥OCíܺS‹´`¦äVÉr™ü¡ù´ .HOtH-S(w}§áõX¸oN™ÙfãA9˜Rý|Ú> øïVÇ¿R¶wûÓÈÜsèÐ!Ne0Ž9rŸ[—®þ§¥ÏM_U¹ªi㦩 ©ïiß[6sY-~š«Ú©N£ý‡UO^R),,ŒŽŽŽŒŒ ?yò¤Ùlþ[é¿8þÜW2(Î{lãÆk}½²ÿþšeæ±Ç ž2eÊ]]BÕ,{®òœ˜˜èííMžj‘¸|ù²Ý+¡–-[vëÖÍýU=GÛ}w£Òcccår¹S;w/Qÿ»÷i<Ï?~<55U§ÓµD|||BBÂÖ­[ïŸQø?þ¨‰Ä€Ñ‚u ú?ßZûi"ÍœyG½/¿úò²#Ë€j«v¼¼¼œÞú‹ŽŽ~ï½÷þáUX§­šTʵk×üýý}ôQŒ1˲2™¬eË–[·n%æÖîqÅ!„‚ƒƒøá‡K…C2@åQ¡á¾ÆÑ¦ŸÝuéÑÖÛž]—z8±Ä(±ëù®òÀâŽ;lßvV²Tý<;fÏŽ_ê*]ŒñÑ£GW¯^-™´ a׬Y#½B(Ù½{÷/¿ü"Eî˜g°yôÚir® PúÞÛ†%î999³fÍr?";þ¯dÃMA¹Y°Ú>~Wý°ÕÁd2:t(!!A .Y˜ÔétvtU³ÁW³"ª_ ’ rââ´8Î"Vnø&ì°ðˆFx1ìÅÂ#…n¬98æÙéWtíjGò™——G,*¹ïîÝžz#ow^»vM«ÕÚ={Õ¥K—ùóçÛžjwõ!¶_äêÓ\!NËÿÊ•+C† ¹ÓïuUu ß1¬]EP¨Ðpß¡V«Ÿ|òI²8|ø0Ƙa˜¸¸8i}@mU*•Ò%™µk×®^½Úé(ðÙgŸ»‹RX2H<óÌ3nì? ë¸LAõíÛ!TQQA~ „F}þüy’g___»<>>žØá%AÞÿ}„PRR’ôÜ$É!ù_¹\.½ñ²lÙ2â8nÜ8òcĈÒ§ñ<’ $"„<<<È÷zzzΛ78Nš4‰ü:t¨íRO]½ÿo[ò/¿ü2 ¸gÏbX+!!!DRñ÷÷'õ+½ßŒš3gBhëÖ­ëׯ'V¡m“üJž;wNò“žž^³5–Åb‰‰‰qz|!99¹¢¢Âö£Þ~ûm)EbAªn„F£!…éåå5{ölâøå—_’¯¾úªí!„Ès´‹/Fét:òQä±mÂŒ3ˆa3)ˆô®°mº’Á-;6 Es¨°2Ö·½Þþï9éÌ™3R„R+’z·DRRBhÊ”)111’ÕV…BñÎ;ïk×®%?ˆíøAƒIÏWUU‘ÿ%-c¼ÿ~)ò_ý•TÄc=æ¾—@qqqBB8{jذaÄH›Ôh%Z¶lI~¤¦¦’sçÎݾ};iöÄÔ¸«ñ‡|ƸmÛ¶Rù9r„TGll,y-^ú^ooo„PVVÇq¤$­VkïÞ½‰¥l„ÐéÓ§I؈ˆ7éöêÕ‹üX°`ä(]AAAR« Sîw6mÚôÍ7ß)¸cÇŽdžÛ¶m¾ 1@V™ öc\-a?øàŒ±¿¿?ñ#Š¢Ô}úôY»ví©g%ºvíºyóf[Ùœd!ôì³Ï^»vMò·´$¿}}}m³ä>éV­ZaŒÃÂÂqéСƒ£ê—RMèí‰{D›6m$Û‰Z­–èl÷ãmmÿŒ=zÓ¦M·µ¥9Õñ…T‹ÅR}ûÑäUö¸¸8¢²»páªU«œúÔjµ¥¥¥~~~äO÷§¯«ÿFéÀ¢(ÚíÜv°“,õÙ}¾íPèååe{/`Ú´i “É^ýui‚'‹õ~øŒtR6ÊËË÷îÝK¼ ’O¥RùòË/G–e‰~hܸq‹/†fd›d•a˜7ÞxƒŒÑŸ|ò ÆØl67iÒD«Õ"„<¸hÑ"‹Å2oÞ<»HÊËËׯ_/Kii©ã»CJ¥’çy³ÙLrÕµk×ððpÛ2×h4’Å8òcË–-5"vJ»víúñÇÆuëÖ‘ÆÆq‘µZmYY™J¥"RZýúõé¬D…†ûÛåøm!§úþyž¯þtëhÿ†ŒÔ’VcöìÙ‹ÅUæk Ù¾£ì9Í08³Lc' ¸z“ß±"X–uŒóĉ………pºsŸžçßÿý‘#GÞQž mÛ¶]°`yA^m“V(D·(IHÏ>û¬$Ê8)íÒ0`ÀÀÉï®]»®^½º†.B§NJMMuTt=z”©“ʶó i]åååûöí»må’ó³Ò)ZGË 2™,11‘ÌR’̾}û:µÁÃq\yyù©S§ÜOŸÐøJãä¼äCá‡ìôZQ;¹p2ÂË@æX ‚ ÜÑ£{¤+9m޶¦ì2çêÚ½ûÆÏ0Ì™3gˆ¶ÉÎL×wß}÷è£J>SRRˆMsرcǬY³^{í5§Ééõz»äŒF£ãT„Ùl&>Éë>v"¦›Ëºv£›õرc7ö•ÒÓÓ7nÜØ¦M›îÝ»»ZùTs  üŸ½óŽ‹âxÿøì^?ऩ4AÔˆ ‚FK,»Qì…ÄÄ®ÑD1¶h°Äˆ½Ä^b71–$vÅ‚¨€"  ‚Òëqu÷÷ÇóÍþ.ÇÝy¢(âó~ùòu7ÌìÌÎîí<óÌìóA£á-£P(þâ"—B|}}ÿùçQäñxƒ ‚gß’%KV¬X1pàÀŽ;‚?ÜüñöíÛ !×®]Û²eËðáÃwìØÁYú4ö›Ù»wobbbLL̦M›`¸6l”efÁ‚µk×ÞºukyyùöíÛ§NJéСÃ`2MQTÿþý !C† ²Z­¶nݺyyy0ó2dÈöíÛišÞ·o¬w£wïÞðŒ`¶lÙ²<¿ýö,(lÛ¶-::Z.——••qJŒÍš5»|ùrllì;wæÌ™S¿~ý¨¨¨„„„œœœ­[·Ž5 t“Á¶Evvöܹsum2¥RÉ0Œµµuii)ì¨ÞUƒ¹>ùï6xiÍÖÖ6''Ú¬P(&MšÕmÞ¼ùâÅ‹>LMM=z´ÁsOJJòôô|8LÇ !-Z´°´´ÌË˃!0==}Þ¼yÎÎÎEyxxÀïèÔ©Siii<ظqãøñãõ."Ã0P¶uëÖp"¦W¯^...7¾råJrr2ŸÏ?wý¡-[¶LLL,++ƒ•nÔLOO÷ññÕ1H{ö¬S§NR©t̘1S¦LÑh4<oÈ!„ÝçOݺuáG ½çÏÁƒ“““£¢¢¸ó…<°ƒA£Ñ€vþüùåË—Ã{:`p´iÓæÏ?ÿ‡ MÓŸ}ö!ä“O> †.ÊÈÈhÑ¢ŸÏ·µµÝºu+¬HŽ1B&“=zT$ ‚ßÿýU¦1ï9(ý†¸wïÌ !·oßöõõ…é<4M×®]á§¶ÿ;wZ¶libþÍ0ÌÅ‹aÛ”={ö,xžííí›6mj¬ldd¤Z­¦iZ­VwîÜY·,,Ù2 Ó¸7nH¥ÒS§N}þùçnnnE]½zž) Ãè•¥iÚËËK Èd2H?wî˲ü±±ùĵk×`æÊ²lfffíÚµ-,,222>|Hñöö¾ÿ~‡!—/_æž¡ºS–èèèâââ ¸¹¹BRSSÓÒÒD"QYYYçÎÁ‰ÎÍhaoãõë×ýýýá€?®[·®H$zôèì™òõõ…)µîUÓjµÉÉÉ7Ö-›ššêää$ SRRà=µZݵkW8Ù‹/òù|Xý1æ?~ü8t‚T*ýúë¯aºÆõ w¹Y–½páŸÏ—Éd666ÎÎÎ/^ÌËËspp€z?þøc½ÛF©Tfff6hÐ@£Ñ\ºt Ó¼ysݵ0ŽJcC‡gee;w®OŸ>°˜ñüùó^½z˜#55vØAà,Ü®ðćËjaa‘““ˆÆ׫W’œœœ‘‘Á0̇~ýP±C!çΖ––öööõêÕãóùÜ V5|½páŒCðª¡Ñ_©šl½¿õ¶åív KZ–µ\’½d’äȺ‘vÄŽ«W£Ñ„‡‡Cg¶hÑœäñññ999º"::ÚÏÏ›…çä丸¸Ü½{W&“¥§§3 ãëë }x÷îÝÂÂB>Ÿ_^^e¹‡………õêÕS(‘‘‘<.¢ ¸………¦sçÎ7oÞäîL½ §Õj/^¼XVVöÉ'Ÿp“òV­Z5iÒDO…œ{†Ô®]»E‹°åæÍ›<ÏÉÉ©¨¨ÈÏÏoÉ’%LOOçóùºÏ.½²„œœ>Ÿ¯·ŽyãÆ …BAÓ´J¥êÒ¥‹ÞÅ…½2™làÀK—.ÍÎÎÖh4;v„íÌׯ_S^«ÕV|î988€E›““GÓ´F£ ‹ÅEEFFªT*¸@¦Ÿ®5†ªÆF£1Lqqñ˜1cvîÜÉ0ÌÂ… 'MšäêêŠÝòÚ¹~ýúÍ›7Á!“Éd2™îk¦9wîÜ“'O`Êþê¼ÐhàF ÌÌÌ“'OÂ0¬Ñh¸Ý!•¨T"‘Àª|uà¡«¢n‹ybBˆˆ}äôч'5 Þ%œç ÿ)ûÉ$K–,éÑ£˜U„Z­îÝ»·‰­]ÈÛ2ÐEƒF&“}ýõ×£G¦izذah1Tþþþ÷ï߇•ã’’’ââbðL˜SÖÉÉÉüí®¯Í9IQõë××]ê~•1Õà’ù[ó»R˲¾­}¹”'äI͈ §¦g_VúÔüüü¸ÝÐUMÓ}ûöÅçC5Ä(ØUÍçŸÎíR$/£fûzw€Ó4ýRÛuu¤JWºjÕªê6¸¾Æ³«©§Ö­[·ªn-Ç›8q">jˆÑ T*!Äv‚Ô Øyxx8v‚Ô ª‹46ÇswwÇ ZR“P( ~~~æØ@¤:c"Nè5ø|>„D¤ÆŸŸÎ…ÓAä]'33³Z 5ƒš±¿éív‹ÞËZÕ¤c_¥•.k°+Þ䙾–˜(XTTTѹHÓ´T*ÅWÞäýá½ÓžHLL2dhƼgú;×?ð&trr²‰“*((2dÉá‚í¯\¹2$$dß¾}ÜÐõæ{ //ïäÉ“•»²Ïž=;}úô« ·ãÆ }½÷•é¤(jÆ !!!Û·o× #8lذ]-ƒWgß¾}7oÞ¼ö/‘‘‘qqqãǯ’A4j¿ýö[XXX•Ö½qãÆwÔ“ËéM¨Ú·o¿}ûöõë×wìØ"Â>|ØÍÍmÅŠYYY :EQhٽɖq1 ^–üü|c1zÍ$44ô5î÷–Ëå£FzaŽ1båÊ•[·nÕM\³fƒƒÃë5AÆ ›6mêáááîîн{÷ÌÌLÐ)@ä=á½ó+”ꉅ˜¯"÷éÆ ƒ°€,Ë–••ÅÄÄÀ›i~~~b±øùóç2™ v¨Þ½{¢DEEÅÆÆ>xðàÚµk2™ÌX ¬ÌÌLkkk.Ž^ll,„݈ˆ¯ „‹ONNæÄ®¸l·o߆ÁZ­¶]»vÆœÒÙÙÙ <­Ñhx<^zzº‹‹ ÔÂ0L`` ”½|ù2D„Ô íW‘²²2‰D"‘H ~!D©TÖ©S§N:õêÕ …jµúÞ½{¹¹¹±±±EEEmÚ´1(ã¤[/쮕H$àÙ³gÐBB`‚ê1·A‚ÇEGG7lØ0>>ž¢(ggg'''BˆX,†žK eAt LÝ ¹zˆÅâ[·n©ÕjµZÝ¡CÈÆY4M·iÓ†rãÆ6mÚܹs§¼¼ÜÝÝ4|ø7` kÙ²¥V«=vìØÃ‡!MÓÿüóÏâÅ‹ Ö’›› !`AÐa÷îÝ+W®Œ‰‰ %‚sçÎÍŸ?ÿ‹/¾ðóó‘åÕ«WïÚµËØOt ìß¿"YZZÂèQè ÅÕ«W5Í7 ýüü Ž+E=úÃ?ÔjµZ­vÏž= .ÄÄÄž={², m¢°,{óæÍ©S§¶jÕjêÔ© 6dYöÈ‘#3gΤizÓ¦MµjÕ …<Ê®[·Ž“³b&<<|Ö¬YÃãñV¯^- Á‚Ù¶mÛ®]»V®\ÉY™Z­6..n̘1áááË–-kÓ¦T*=pàÀâÅ‹e2YZZZbbâªU«|˜a˜M›6]ºt‰eÙ+V€õðí·ß>yò„Ëéêêj° ½ªmmmY–8qbJJŠ®Ø¼^‡¬[·îâÅ‹¨+äX^^Îmh@v–£N:æ_ˆ¢¢¢!C†pµ$&&êfÐ;Î À¥üðɉ‰)))Ó¦MãaRÞ±cGݲ …Â`KâããçÌ™Ã}…ƒƒ(++ëß¿?˲ÙÙÙ æÌ²ì˜1c233¹æð’^ƒáVtï«‘#Gæåå]¹reåÊ•;¤¬¬lÀ€Æn¡ààà’’îkÛ¶mõ2,Z´(66–ûjoo"""Ö¯_o°òòò~ýõWcWŠ³Þ€íÛ·?xð &&¦´´”E¤Z [˜¹§ßÑ£G“’’T >>>77¯â蟟ÿ8::\&¶\üdÕ§'Bhn{&¤  `ĈOŸ>…gº¥¥¥ÞÜú¥vó »fÌβ¬@ ÿpíڵѣGÃzGaaáºuë(ŠrssKHHèСCAAç”îÒ¥ ¬#°,Û½{wcþäÅ‹ÒÒÒ êeeeõë×ïׯ,6ƒ¶Lm!CýúõÁ< ²¶¶7nÜ­[·`âÙ³gwîÜÑöepTV(÷îÝ#„„‡‡ƒ8ä ™4iÒ?ÿücÂÒ þ&Bii)ŒFºC~~>” 2&<£Õjù|¾Z­®U«ÖÌ™3õ΂;Ú Aƒ8•ä   è"†aÖ¯_Ïí=ÔjµGý¯¿þúöíÛÜW___ݯ¦£ÿùä¤R=)©Š¯;r’ÓÒ¯_¿õë×Ãf ÝÛÈDíœ5¹lÙ²Y³f'.+g/B½° †ÓÔ¦iZ"‘€‚"|…–ƒšù¢E‹*÷KQ(“'OvuuݸqcëÖ­ËÊÊ^Ö¤F†w nìAÕ.]º|ÿý÷­Zµ‚=ÿÏŸ?ß³gîãX¥RÁ¶–eW®\ÉW®\aYvÁ‚ÞÞÞ0*ØÚÚÂl>00pÇŽ Ä + z#:˲?ÿü³½½=쥰´´T*•œcœkjNN<— @…žÑ6lpuuéabüÕ|©T:dÈøÓÂ… aËžAS@wØ;tè®ó£r€SŽùìÙ3c-}úPekk›““òì£G ¬¯¯ïçŸg|øðaηÝÂõI½zõÀ…v÷î]HŒ¿téRå®iQQ‘V«mݺuëÖ­!ÒœV«Å`'ò^ÒØ†GÜ}ûö :>;99edd˜Y&væ;‚œœÛ«T¶ IDAT¼bAƒ™aò­· `LÑXóô2po˜ß]æŸà î?©êòåË;uêÔªU«ŠG3x(§+°¤ÝH¯{Íl•ùeM÷€Á>1‘M¯^½;ÁÌë«{½6;vì“O>!„\¿~ýÆ7BšÆÆHhò.‚ÒØUc7zº¹¹yzzJ$•JuîÜ9óËÂóZ7ÝØÓrrÏ÷Š_˜Yï¯æ7O/ÃK‹˜n³iΞ=ëááÛ§L™bðh¥'‘ ݨb™Ù*óËšîƒga"[Åz .Ó˜> Þ»-ºeóóó5j$‹÷îÝûZ~#‚¼‡ Ñ`˜¶mÛ>|ø›fa‡T]»våöT¾TWë¾æ€ÝøBtÕ·ñ~Fä Z­6;;=R“(++«]»vnn®î¢‚ ï.æ¸{߄ѠÑhîÝ»‡3<©aÏgg縸8ì ©ŒûŒ‘HÔ¹sg¼R“(,,qâÄÌÌLc>€ŒŒŒëׯ«T*ÝôÏ>û ÂGšö˜ÓfhjRRRdd¤nW˜_ö…õêö³‰‚zy(ŠÒùmºÞŠ-7ØæŠ!Eoë“™e«­ïA4ÿ $>>>‰$,,Œ ËqaŒùôÓOa ~òäI'•J)ŠJKKãžÔ%%%Ü#›¦éºuërqúõëe>,$É/¿üÒ 4M»»»K¥R©TJÓ4¬Ø¼’’’qãÆÁA.\*ÏOdÉ’%œ,‚——ܺ¢€‚\¢Z­¦(ŠÏçs+YYYaaaM›6…óU«Õ°â`ccm¶°°0ÖfŠ¢æÏŸ/‹?úè#®+>ûì3nØ®U«–‰²sçΕH$P/ùw¥Cú/¶¶¶Ð]...pðǃ§'66ö?þ°··×++ !PÝ'N„kq÷î]øàççGQÔ¾}û««+´9-- ÎB üöÛoE…‡‡GDDXYYA-ÜBw¾žžžP–»©ø|þï¿ÿŽ#=‚ h4¼{ž†ØØØÌÌLÝÕ%%%S§NeYV.—‡„„ìÛ·O£Ñ¬X±B«Õ‚ðÁgŸ}fì‰ÿüùsîsAA!¤¼¼|ÇŽjµº¼¼ÜÁÁ!++‹2zôèû÷ïËår¹\Î0Œƒƒƒ1NN®©´´T~üñÇzõê9ýKpp°îàW‰N Ï­›8}úô¨¨(8_¡PHÓt§Nòóó¡Íeee-[¶4Öæ… *Ф¤$݆ì¸\./** 4X666V ”——C½ÎÎÎ4MûøøÈÿ%77÷ã?&„€\!D«ÕrT ÈÎΆ²EÑ4íéé©R© ¥víÚÆd!/]ºµ0 óùçŸÃ‡èèhŠ¢’’’Ôjõƒ DQ ËårµZ}ôèQ0;tèPRRÂÕK±¶¶öòò‚œQQQ_~ù%EQîîî¢ÑhNŸ>­çìA1Üù6= „¢¢"Ý1¬¼¼üÈ‘#0¨T*Žä$X–½yóæKù„9çáÇóÍ7„{{ûÏ>û ¼å|>ßüyY–7oÞ¼yó^{Wèî„`æ›o¾±°°€¯pîõêÕûôÓO9 I.”ºÁ.%Ä6³²² ÓÔjµ±²®®®999ƒ "„?yòD¯"¹\n¬¯ÔjõÚµkõ9qT–eóòòFŽiæ-çñx ,€å¡ &@-ýû÷GËÅ‹išV*•Ð;HAAArr2œoII ôä‚ z]¡¡¡ŸAÐhx'-‰*òƒãZ.—¯\¹’S¼äFbSw Ÿ­š1c†®ÔçG}Ä sp3lÓ»ÌÛ¨ÁQZZºmÛ60¡8KÈü.Õjµ/<ÍZµj­Zµ ÔÏ­¬¬¬¬¬JJJ̯¢¼¼ÜDª¡}ôÑÎ;'Nœ¨Õj<¨w±(Š’H$;v$„¸¹¹=}ú´¤¤D$ ::\£Ñ˜s Íž=»¸¸˜¢(¡P˜h7 ‚FÃ;Ƶk×RSSSSSÏ;×µkWBˆî ÕjA]ÚÖÖ6<<\«ÕŠD¢©S§Þºu‹rõêÕ¤¤¤ääd®lûöí¯]»£W½zõJJJ„BaíÚµ/]ºÄ0Ì¥K—rrr!5Ї™´V«—{Ex<ž……Å¥K— —.]:~üxóþùçŸõœ,ËÍ™3G.—gffNž<ÙØù†‡‡GGG?}úôüùó]ºt¿Â•+W ¯\¹bgg׸qc–eu;éÞÞÞ·oßÛ…b"¶XJJJvvvqqqDDDÛ¶m9-ìŽß©©©kÖ¬éÛ·/!D"‘øøøB|}}/\¸ÀµÄÛÛ›ÒºuëÈÈH…B‘ŸŸ¯Ñh`×EÅ×FZµj=/•JÜ­[7ƒõÆÄÄxyyݺu‹¢¨¼¼<¢#V©—ÓÓÓóêÕ«J¥233óèÑ£;wî …!!!4MK$’víÚé™\\gúúú®[·N¡Pðx<™LV «”eÙ¬¬,½Våçç›P÷Fäu’‘‘¡T*û÷œ ¿î\ÓßߟeY÷óÏ?Ÿ:uŠÇã©Tª«W¯Â ;!zôè‘’’ÒµkW–eÃÃÃׯ_/‹ !ëÖ­+,,tvv^´hÑéÓ§)Š nÕª!dÊ”)û÷ï‡ñÉÄ’¡¡¡þù§L&[°`ìi0h[BvíÚuüøq‘H´dÉ«'iii¶¶¶vvv=âãââÂÂÂÁ-occ3fÌî¯Ð!‹/Þ¹s§9šñññ›7oŽõ÷÷'„,X°€[­àñxsçÎ5XÐÝÝ}äÈ‘·oߦ(J¡P\½z•a˜5kÖlÛ¶s·,\¸a˜ˆˆˆ 6ˆD¢Zµj1B­V»»»÷ë×;Ôþýû !›6mÚ²e MÓ …âñãÇÆB³YYY•••EGGƒeðàÁ°â ·îÀ²ìùóç7oÞ,‰ìííoß¾-‹ayö¨*ŠˆˆBȆ ¸R¶¶¶ SuãÆ­[· …B­VúR®ÀÃÃ#++K/‡]íÚµñ‡Œ ï”´llâ¬:Ï¥;Û­Kz|·  ·â?7W}úô?¾¾¾EÝ¿ßßßßËË ûîÑ\9wtÅôŠWÄ`žŠ9 ¦ÿú®ñÅÅÅãÆÛ·o!dÆŒ&LhРÁ OÄ„ÅðRç¥{Fæ·Ùœx•DÓ»IL·ÙXñ+W®ÄÄÄLœ8ñ?HŠâÔ;_¸yåܹsOž< yÙ[Èà‘óóó=úå—_šÓ±‚T®]»æååÅíÍR*•§Nòöö®ø2—F£qpp¤ik²¥u ì5óáâ»wc~¶= oÏ^ûïSX7Þ‘‰l&òTÌY¹@&“5ªU«V<oÒ¤IÆ,½#˜Z^ê¼tÏÈü6›™³Ò‰¦NÓm6–Ø®]»ÈÈHpŠBÈ î}QÓ·­­­îßü[¨ÁÄð‹ Áå ÄAAAAAAØUÍÌ™3gΜÉ}5_ͶE‹¯±<E±¤&Qª1•1”JeDDN>¤†áíí?m©1lq{ûFÇsppÀK‚ 5 ¥RùäÉOOOÔ´DšAUHÃTÆhàóùz!üy×)((¸víZÏž=±+¤f`쥭7m4 o˜7¯ ]ýÏ÷…/P 4öëmž±í4Mãr‚¼? öÄ;EQ»víªœ‚vLLÌ?þ¸eËó´ãããuå0ÞÊù®]»vãÆÆÌ’KE­ZµÊüó}3(•Ê3gμiì={öTEE·oß~òäIú¹}û6Jc#È{zÞ  E% :;;9ÒÓÓÓàû÷¹r劧§§““Ó[<ß®]»šx‰ ,,lÀ€ÆþÚ­[7.vd5”ÃŒ…|½Ì›7oĈ¯zAÓnnnz‰r¹¼r·%‚ h4 U…\.‰D–––\Jqq±L&KOOácgggð-C !D*•ÚØØBlllllltࢢ"KKKˆä˜•• \YŠ¢LUåry~~>!„a'''N|¹âÔÿÉ“'P…¥¥¥ÁPEff&Ã0 ø¸¸dggÛÛÛgdd899åää(•J+++y*..¶²²Ò•é¢(êéÓ§ÃÀÅÅÅ„DQQ‘L&ãT*!yyyuêÔáή~ýúÆüðEEE 7µèFÞ„I|ýúõ¹N#„h4¹\.“ÉÔjµF£ÉÏÏçZ¨[–akkkm.(((++cYÖÑÑñùóçNNNÏŸ?wpp€þÁt–eµZmff&7S*•*•JŠ¢@uê%ÿÆè„óåñxp}†yúô)Ü-¶¶¶‰ä5ú6ðŠ h4 Õˆ„„„}ûö­\¹’ÛÖ¾hÑ¢œœˆóŲlóæÍÇŒ³dÉ`<›6mš§§gÅ£M›6íÇGŒFE-^¼øÙ³gP6&&fñâÅJ¥rΜ9°’Ͳ¬¥¥å’%KŒµpáÂ… ¦HQÔìÙ³95,Ý¡åï¿ÿþçŸ`³···³³?~üÒ¥KmllÀÅMÓôœ9sììì®]»væÌ™mÛ¶A:EQ'Nœ8{öìÿnY>$: rùòåK—.íÝ»— 4h··7·$ß¹sçO>ù¤bÁ¼¼¼E‹qÚ E­^½úСCW®\áòõêÕ :òèÑ£uëÖ­^½:66ö‹/¾èС ÞvvvóçÏß·oßõëס V«5ÖæÌÌÌeË–AÈÚµk¯^½zÿþýÅÅÅyyypuúöíÛ¥K—¢¢¢E‹ÁxÏãñ–-[vùòå øùùA½uëÖ3gŽ……ÅÌ™3Á@QÔÀ;tèðý÷ßËårà ņ ª›3AwiÙ4åO‹Óúx0LI^Þ£üüÇzÿ’’®]»öêÕ«‘‘‘[·n½w)†<Kœ9sfxx8÷< 0ºeeer¹œû* ¹Ï'N„Y;˲|>>è–]¼xñÅ‹‹ŠŠFŒÁ%Êd2sZ»yóæÈÈHƒúì³ÏJKKu«§¶mÛBâüùó£££¹ó…p‡@ïÞ½•J%|~ôèQ§NL÷Œë@PPPJJ |Öh4ݺu3X666váÂ…Ü×´´4–e¹¶±,[^^Þ¯_?–eE"¤$''Ïš5‹eÙèèè3fp9áìZ¶lÉ¥ÄÄÄèv¦.ëÖ­ƒÏPœùW ,;;4-u2dHIIɹsç@ìC·ÞFåää@JFFÆäÉ“Y–•J¥\¶‚‚®£tÉËËûõ×_]Ù[·nUL¼wïÈŽ#R ‰ŒŒ,**â¾*Š£G&%%=¨@|||nn^ÅÑ??ÿqtt¸Ll¹øÉªOO„Ð2>n„¬î[ÐÝsP1ê°T*­´ š[°Ø³gƒƒxLíÁƒb±ØÞÞÞÞÞ~„ Æ4—ÝÜÜïß¿Ÿžž.­æü% ,}ƒ>–eÝÜÜŒ©oŒ£¬Õj]]]á3¡¹"ÞÞÞÀÎÎÎÞÞ^,‘ÿg4Q–bgg§—ÂefYÖÝÝÝX›-,,ÊËËïß¿ÿðáCXQ‚ÆÓ4 G°³³ûí·ß!/^´°°°··wttÜ¿?¼%Q¯^=½2 ckk«×æ'OžÀ5²±±Ù±cþ¬Á剚 ·ÿÂÅcݘ<±±±,ËúøøT,[ZZÊé—èŠPs,]ºtûöí à :†+½–èѤI®ê¦M› Ô²eˈˆš¦åryRR’V«Õ]æ¯øj¨î]RR¡Í(Š5j”îöŽÊõUEž>}0{öl®=,ËëÚa°ãÓž¶²²2q@0;àP#GެhU666ÅÅÅçÎÓh4‡2ñÞcçι¾µ¶¶†•šÐÐБ#G¾ðì/^ÌíXìÔ©Ó„ t·}TšJ¨e"‚FRµž†ƒ<>ß»wÏËËK¥RéŽÍååå` PýîÝ»ÿù矄]»v…„„ÀPôðáÆ îܹöªTªììlŸØØØ¢¢"(ËãñÖ¬Y£T*e2™¯¯/MÓ@¥R¥§§;;;la~~>”‰D‹/V«Õ³ 2¤N:eee„~øA£ÑÀ)pc0w¾¡¡¡óçÏ×h4Eåçç[[[_¼xÑÊÊJ¥R©Tª¼¼¼^½z뫹sç.]ºÊ–””XZZº—G¯:Žúõë/Y²ÞÚP©TÏž=ÛK(Â(ι’““á|]]]{÷îýüùs†a*žõÇy<ŸÏW©TYYYS¦L1X¯««ë“'O–-[FQÔ7ß|ÃI\VôLܽ{êõññB£ÑüðÃb±˜eY•J6 Ü œ¥R©!ƒ ‚²*•jÓ¦MƼA¦ïÃÍ›7ëmçT*•Ÿ~ú)þHä=’Pû]ñ4K1¡mpÎ]ÑÍn¾Žó«túôi‡GJJJź Ök°ÍæÈ[¿¢4¶^½¦W(¸Áž¦iòÍióÅ‹>|øÕW_éz8¸ƒ˜¯:wî\zzú矮wQA‚ÒØï­§ÁtÊËêGW‡Ì×q~–,YÒ¿XaYVweý…âÚ•nó+JcëÕkz×]U1˜Ó`Í›7?xð`Ÿ>}!*•jçΦ¢‹Z­G‚ÞñQA*ä ùK|}}8À¥À;8ÙØØ¬]»–Ûæ k fvKPPŠK!R݆aŠ‹‹íGsÐ]zG8Þb€Å²²2 ‹’’c2‚¼[TŬ¬2FƒZ­ŽŠŠÂ9"‚Ô$hšöðð¸yó&þ´¤fÀífxËFƒH$êÒ¥ ^©I˜ØYÝÀE!f8PA÷¥R¹eË–:uê`WT)jµÚ˜qÁdAGÆXô9xß»±JMçÆCù7 ^Tyéß*<( ¾iæÛ’¯k(WQuÛUªÛ&ÞùÔýÓ ;£~ýú_C^ãV¥R¹¹¹ìd>Ÿúôiwwwƒ›Ûhš¾zõ*‰©¢‘ žªÃH#ÈK?OW¬XAQ”Á´4_8øQ5tèP}¥0M ‚¾}ûêf0ÃêÕŸS„;v@è0Ó ³¶¶¦(jëÖ­\‘’’ÐJåÞ¡(jÑ¢EEyxx˜i1p-AªTò†¢(©Tja‘HQÚ$‰Á ‰„‹AªT–ykf{ʲ^:÷ùÛo¿…­±²fyùøüŠe9é)ÓmÓÍ©V«?®ÛZµZ=bĽlO¤.–°°°_~ùÅtꢢ¢Q£F€ÐצM›(Šºpá'eYvàÀ7nÜ€£yzz²,?nܸ·øò‚ h4 ÈKø–/_îìì\·nÝëׯ»¹¹Ñ4=`ÀŠ¢._¾ìààиqc˜1çççתU«AƒÜ̘¢¨üÑÅÅÅÑÑ1..ÎX èTªZµj¹¸¸ÙÛÛ“ÅÄ]\\\\\,--a">`ÀBˆ•••‹‹ Dbe¦¤¤¤víÚ...õêÕûóÏ?!ç„ \\\¦Nʉ–õíÛ×ÃÃãÔ©S®®®~ø!dëܹ3¸"îܹsèСÊ-dP5bĈ€€€Ÿ~úI7¨TEÒÒÒ5jvÆäÉ“ÇO™5kÖ‘#GÀh8xðàÒ¥K !3gÎóxù„s°WœmkµÚ¬¬,µZýüùó‚‚BˆH$R©T)))Ož<scÔ¯_ÿÙ³gÉÉÉ.\زe EQ"‘H&“Ñ4 £¬»»;øtKÁPêììlmm 9¹¶={ö,55U.—§¥¥ýÿ¯š¦Á£G®^½ Î GGǬ¬¬§OŸ¶hÑÂÒÒ²Ò½ÏÊÊÊÊÊJNN†UèGGG 0š7ož““sçÎôôô=zÀ¦Ñ¸¸8kkkp¢ØÛÛÿõ×_ Ã(ŠÑ£G?~üøÂ… ^^^ŽŽŽx+¾+ ç = òþbgg§T*W¬XÁÓË—/'„,Y²D/§B¡Xºtéwß}÷Ë/¿ôìÙó£>òòòJKKÛ²e‹F£Y¹re‹-ŒMǧN*‘HêÖ­{ùòe±Xìçç—‘‘±eËBˆ\._³f !ä›o¾áJYXX 8òøñãéӧîˆY³f›áÂ… ±±±Ÿ~úé/¿üe !2™lòäÉ7n´±±ùé§Ÿ†‰‰‰™:u*ŸÏOJJ:sæL¥{éüùóqqqB¡eÙ­[·úúúß~üñGnw$˲aaa .,--]µjØ1 ÃLž<™’ Þ‘H4~üøM›6ÙÙÙÁ;)8Uƒ ¤¤$22Òà_y<ž\.OII)))1§!''ÇÓÓ{²æm”´llâ¬:Ï¥;Û­Kz|·  ·bSrsÕ§Oÿ»¸ïß¿ïïïïåå…× ©IÄÅÅýñÇóæÍã~°Ï>˜ø}VÜñG^&Ô’^NîhÓ+V¡W¯ÁˆIðÙÝÝ=55•uõêÕ¯¿þºbK^FÚàIéu‘‰6<”élQ*•GŽiܸ1wªR†ávƱ^ØÿB¡»±Jqtttvv6‘áÚµk^^^œ…R©\|÷nÌïÃö §A!ÄÛÛû¯¿þrrr¢(*??<êÜ{Œ/kï›? ÐË©·¥ÑÄM¤èþ î7oÞ¬U«–L&óóó;vìXå&ô&δbÕzm0³©æ4C$ 6 ïX!o#, ò?fÍš5kÖ,îëK(¬ÎPekk«ÁàS†Çã¡(6‚¼s¿î7\ceŒ•JUÚY‚¼Ý)‹——þ´¤ÆPša•9"EQ–––¸ ˆ 5i¾¢V«óòòêÖ­‹ï=V{óŽÑjÕEø|±™ÏaŠ¢´Z¬¸ñxB|z¿'?jx¥ùí 7B"H £°°0**êã?Æ®¨æhµÊ’’gEÕªåb~)¹.6™OBB x—/_¦iÚÍÍmÉ’%2™ìСC»wï¦iZ¥R}úé§cÇŽ]»víùóç=zÔ·o_­V{êrüß IDATÔ)cµìÝ»÷ÀPvРAcÆŒYºt©Íĉ !ëÖ­+..þþûï·nÝzèÐ!·5jªÕjgÏžšš vß¾}M£»wïž––víÚ5‰D\TT4{ölPP*•#FŒ5j”AÅúõë;& e2Yrr2 {kÖ¬¹xñâ“'OîÞ½ Ù.]º´téRÚÁ?üЪU+‘HôÝwßÅÄİ,Û¢E‹E‹{ŸªgÏž0N‹ÅâE‹5mÚÔÂÂ,‰Ë—/ß¾}{úôé•s±À\èС`œ™Ø±mÛ¶?ÿü“¢(¥R9lذÿ1cÆüþûïB¡Çã-X°À××wãÆbii RŸ&ê ),,T(¸ýÂô5JNNž4iÒºuë°C4wKKKŠ¢nݺõôéÓ~ýúqÖÃçŸ>{öl°RSS›7o>dÈ{÷ÃØ±c§M›6mÚ´–-[?~œ‚Ʋì¨Q£¸›¢¨1cÆÌ;722rìØ±f̘1mÛ¶%„€,5dûᇲ³³‹‹‹ííí¹çì•+WŒÍ¶ÏŸ??þüÑ£G7hÐR>|èîî¾aî^ƒF!dúôé°lϲlçÎáÃôéÓ§OŸÞ²eK.[pppvv6÷õÁƒ`Ìž=úmàÀ … ôÃ0çÎƒÏ …búôé6l°¶¶þßžÏç$¿+he <^º66r³,;vìØ±cÇrbaaáãã3~üxð.;vlòäÉ\¬ânݺ™¨—Òºuk???õ"`Nµk×îêÕ«ØHU€¿=äÍÁ²lIIINNŽn¢ƒƒƒî<‰¢¨¹sçòx<¡P~~Ýâ\6c”3fÌG7§mͲl@@@çÎ{ôèѶm[® ð_~úé'@àããS^^«E5jÔÈØLŽ¢ÕjÕj5·ä¡+;inI‚¢(]ëGwy";;ĸ…B¡££cãÆ !‰D&“AE&FM𦹲–––vvvºø*.}¨º¸¸xË–-?ýôh[»&L€Îä.„F£ „Ï*• –KtWšÜÜÜ^ØFƒ«¦­:›{÷îqF9‚ Ñ€¼“Èår™LvêÔ©øøxB·Pôôô¼¼<­V«R© '‡B¡€»ví28rööögÏž•H$-[¶LHHàÊêÙ:º„‡‡[ZZ:::¶oßÞËË îS¦LqttŒŽŽ‹Å𬶱±qtt7þ}û!VVVû÷kÓ¦ X-_}õ•££ã•+W¸²YYYÐK–––Ý»w/))!„>|ØÊʪvíÚÁÁÁ&¤ _ÈìÙ³÷îÝ úŸ»wïž?¾ÁlÍ›7OOOwpp¨S§ÎíÛ·!ZÂù ÀQqõêU GGÇ?üÐÇÇÇôž¥Rù*¯ñ…ÂåË—óù|\¾Aª”ÆFÞœ†2¬IÃðŽ}ƒÚÊzuSŒíƒ33§92ÓæœKåÊšnŒA1nøjmm]PP`¢Í&„¼Ÿ={æèèH¹råJLL l ÕãU¤±Í¼/Ôû6¿£ÞgÔêò’’gE[[»š_ª´4"BZZÚc¾' 46ò.Û§ÿj(Ãn,7¦­¬Wð?þ1#)3sšS…9çR¹²¦«Öë ÝÄââbsÎÂ`{æÏŸ/‘HàsHHÈkiêK%©®C‹A×~bY¦R¥XŒû„¼"h4 È»A¥ÃI±,»aÆŒŒ Š¢D"‘ƒƒÎÚßiÉKù [ –¼îÈ7X–U*•dA7C­Zµ`?cåà^£0x¨  U*îxwPa ƨ¢‰AeŒ•J3©IÐ4ýÁDDD`WPýï‰yÙR,Ë‚KHu™iT £A(véÒ= R“(((8~üø_|ñž{(Š*)y®Ñ(…B ©´Ž™EÑi,ËZY9ðù"¼ê@UHÙñ+÷£‚XñxI¤ÆÀãñà•üióx<†¡x<šÏÿ‘Žn¡iŠÂçó°‘ ¾Î‹ ÿƒ PE;Ìu÷®¿.ªnsu¸"ÕD°‘¢¨7‚ þX4ä=Âà !x[·nýÚ÷ë=\t?þø#Dž6]D.—SV&g·4ŸÏïÓ§OÜcDÓ´P(¬>¡ŠÆ/“ÉÌŽ h4 HM°(ŠZ¸p!º‘óäççGEEqšÎæ˜ÆÆ=Õ n£À¼yóX–Õ›­Bfî–e¥R)¨Y¾Ðo¡ÑhNœ8ÁU§×ƒ¯æWzÌ«xp {aYƒ ÓKT«ÕfÖûf<¥¥¥mÚ´Aáiy_ (ÊÏÏoûöíÆ kÛ¶í–-[À°zõê¶mÛ~óÍ7\$¢ÐÐЀ€€åË—Ïœ9³sçΠ;LiÖ¬Y@@€¿¿ÿÑ£GémRÕ¦M›€€//¯ÚµkÃ8—››ëííÝ©S'nö|ÿþýS§Nqq™Àg@QTëÖ­Û¶mûèÑ#n¸R(>>>~øáùóç9q¯€€€Å‹ëÆÓôõõ èß¿?d3fÌž={Ú¶mÛºuë+W®TÎ-o×®¼cÇŽ;äÀPã¦M› DÕjµEµmÛ»ví Ù tæÌÿcÇŽq"  U«VÜéSõá‡BÙîÝ»S,{ž–e¯^½úÝwß½Êë¯òî‚v÷ÑÓ½dÉ’Þ½{{{{s3שS§N:ÕÝÝý—_~œýõWddäîÝ»[´h±páÂþýûÿñÇ"‘ä­ !ãÆ „Ízv‰¯¯/'»@QÔ¤I“!¶¶¶qqqº „ÜÐH9uê´'***,,,77¸išvtt,,,„lÁÁÁmÚ´±°°X´hÑ¢E‹~øá¨ÈÃÃ#%%²eddL™2eÍš5Û¶móññ¹ví!¤W¯^¿ÿþ;'>ùRÆV§N8ÑpµZÝ»wï“'Oòù|Î2uêÔÀÀÀÂÂÂÜÜ\N^¢†ûûû_¿~Rärù§Ÿ~zäÈ‘C‡¹»»Cú—_~––¦Õj¡ìgŸ}ù[´hÁ­ÔŽ5j×®]oí¡Éç+ p  Ró= 俞ðμ!3dS©T‡*++£i:::ÚĬ”s°,;lØ0ƒÙ¿ÿþ{0)7n ûì8ÅKÝœüñÞ½{Õj5Ã07n´´´4]/¾Ö­[wÊ”)p ¯²û¡{÷î;vì€Ï<ïäÉ“àEà:¤â+^ÜÎA݆q2ŒR©tÉ’%ƲìáÇ!±oß¾»ví‚ãˆÅâ]»v½• –Pihhèðáëâ x©þàòò¾{^ú7CÓ...NNNõêÕ µ±±yÅ6ìÝ»·}ûö÷ïß;v,1¢—Á0ÌáÇmllœœœ4h0cÆ NTÚ ªÊ+޲,ËΚ5ËÙÙÙÉÉÉÉÉÉÞÞžsop²páB{{û—íÿ6ìÇttt„z-,,–/_þ¶,†€€€^½zõèÑ÷B"èi@÷@ P( Åwß}7}útWWW¥R)À1 ;’ñù|ïÿßׯU«–¿¿ii)!D( …BƒÇ—H$ …B£ÑXZZrËœØ#!D­V Bˆ³³ó;w²³³]\\¸âeeeJ¥²¼¼¼¬¬Ì‚¦é:uêäåå•–– ‚_ý¦Ý …‚a­V«Ñh <€D"Ñjµ`R”——Wl^¥G;Š¢ºuëÆmãP«Õ[·n%„Èd2½s,++cYÖÒÒÖ/$‰\.‡fËår±XL*l%ÿ®e”••‰D¢AƒÁŸ`+¬‡ãÍ;¨¦Nzüøñ:uêÐBÐh@÷ÊÁ0cÆŒo¿ývÙ²e£Fruu%„ìß¿ÿĉ]»víÞ½ûÉ“'A¿~ý!C‡%„¨TªnݺBòóó»wïneeÅ0ÌðáÃû÷ïoðøýû÷çóùÅÅÅ,ËÂøZXX8lذ!C†ôïß̘1½zõ"ÿîÉÿþûïCCC¹# 6ÌÊÊ*&&F*•nß¾a˜gÏžõèÑÃÒÒR£ÑÌœ9Ó‚²aÆÈÈÈfÍšõêÕëôéÓ,ËÆÆÆöéÓ†ä:uêlÚ´‰2bÄîÈ=zôе^ªÓΜ9 £;ŸÏ?räÃ0………\‡ 4(88ØËË+66vÔ¨QEk4†aΟ??pà@ð£ˆÅâ={öB¾øâ îø:tH$~~~qqq£FR«Õ«W¯¶µµ%„DEEAgB,--wìØñæ—'X–]½z5þv÷JÚ@66qVçÒíÖ%=¾[P[ñ§˜›«>}ú___Š¢îß¿ïïï;¢ä¶¸[Ý “2è NÇ*c£—99¹½º^X©Á6k0d3øW]òóó=úå—_šÙiæ7ÌXYƒ 3ØKÏ´êî’’çju¹Hdiaak~©üüÇ„°2Y]>_Œ¿/¤:píÚ5///nçµR©Wôô–ƒ¦T»ví&MšÄí®¥¸bY‘HÄ…v®tƒ_˜Èécݼy“HÔÍ2q4ŽöíÛÏž=ÛX.]¥RMŸ>}èСgÏž5³Í•;wŒ¦Œ h4 È[ƒ¢¨M›6y{{ÛØØpa‚‚‚þþûï 4kÖ¬Y³féé鄳gÏBŠ——×øñã•J¥Á(@þþþ ÜLý !„;Z```ff& ´&LðòòjÖ¬Yƒ Î;g¬…'NœpwwoÖ¬YÓ¦M§OŸ®Ñhnß¾-7n|ðàÁzõê]ºt‰¢¨¦M›r-lÕªUVVEQ 4عsgÇŽ›4i²gÏŠ¢ÊËËG çÕ ANxº"OŸ>õððÐUƒ<}úô·ß~ëíí e¹MO`B\\\Ö¯_OÙ¿Æ ›5kÖ¤I“ÐÐPÜ£€ HåÀ= Hµó4Œ7nܸqvvÿ`G&“¥§§?zô¾¶iÓæÆݺuã¿øøx¥R ‚ zXYYU4&zöìÉ•m×®EQ>twwß°agmYûöí«[¯Z­fYvÅŠS§NuwwÏÌÌ„²ÖÖÖÙÙÙÐf•J5tèÐ#GŽ1FãÆ_ã–Ã7€V«…- ïV³©îFƒJ¥ºpá"z,¤&AQT“&\¸p»Aj2™Uµ0ø|ž··+Ã`P9A©¦¤¥å½öcVÆh (" Ðh@AjKUċǂ ‚ Ñ€ ‚  ‚ ‚ Ñ€ ‚  ‚ ‚¼³T£0Ò4MÇÅÝ/**®WÏ¡A7–Å·3A¤Q< EedŠb ‚ HõâMŒÍ,Ë |Îq Ñh š$ŸÏcYBQD«e†Ñh4AA]”JÕ… á&ÊBø|¾F£áóùPÂZóx¼5{ˆZ­Á€•‚ òŽyx<^\Ü}ÿ®;öìØ±gŸ>ƒž>Íâñx»whÓ¦kÇŽ=º……m †”ôx<ÞÝ»q­cÇžýûËÉÉ‹E½{_¿Õ©Snk×n&„6²}øa—Ë—#ÑW ‚ A"0Ÿß´i–e…B¡Z]®P(†áñøÆËŠ5šÿ•U«U€¢P(Û·o«Tª ett¸V«>}bÇŽ½ºví¥ÊËŸ•—+ðê"‚ Èkä l„¤äòr¡ÐB*•H¥µZ}çN,MSJ¥R J¥ )ìT`YV$I¥ga!eY–J.—óùÿ++ŠT*ÕMQ,ËRu÷n܉XVŲ*–e%GkëÚxuAä]ò4Èåò3gþpsk" !ÖÖÖ»wo’ËË/þÁÕµ‰X,T«5!!Ã)Š‹Å_}5õÆ[ÉÉ©õë7II¹+——]¸pÂÕÕS,BìíívïÞLÑh4Jå¬;;Û!C¾HOB‘ËË/_þ«¸¸¯.‚ ‚¼KFÃ0 îß¿ _Y–U*• à 4`ĈÁ¨V«µZ­B¡Ø´)Œ¦iBE‘òrEQžž Qÿ–eÀVèØ1°S§v–ÛQ«–ì?~Ó-«Õjñê"‚ È»d4B(ŠR*•º_9ëA/Q­Vë¥+«Õ²º')ŠªXAA׆‘FAAAÐh@AAAÐh@AAAj6•|å’e–“žDä݇¢(¯Ñ¨u~æD,Õ˜˜†U*•ø:6‚¼i£¦ùµk»aß!HM"?¿`Ïžý'NÐMüä“þ¦½Ó( WW×-[~Å ¼?°ì³ja4 Huš>24MÃÿïÂo˜­ÆwV(è%‰Å"7·Æ§OŸ~§µæY–‹Å‰/‚Fòv$¨î…•š™­Òm iZ*•Êåò7Ы¯~EMŸ>}æÌ™¯Þ!¯·mÆ\ZZz÷îÝwý×áäääçç÷Pÿjðr¼ú5ªÄL×þê·Š™M2¿Cª·1üÜYs (ÊÍÍ FèJÏÉÉÉÉÉ©Du/ÌË™™YXXXé'—D"‘Ëå ÃT]Ç®X±âƒ>ðõõÍÈÈxõa~åÊ•uëÖ­ôeÒëÛo¿ýÖÇÇ'00Ÿ¹¯Å@$„,]ºôƒ>hÙ²eZZš‰l§NâîÆE‹}ðÁ~~~Ü­’““Ó¾}{//¯o¿ý¶eY†a¾øâ ooïž={–””˜hÒ6lèééMþn_;jÔ(ooï¾}û–••AæÄÄĦM›6jÔhãÆ\Ù—¢   K—.Íš5›4i’±“‚ …ßNzz:¤çåå}ôÑGÍš5ûú믹²—/_†Îü믿*×$†÷âñÀ€Ç0LÅ‘eYƒ¿½œð•eÙÇwêÔÉ`-&ÊBÊ­[·nݺõRõÖªUë…gG‘J¥&ê={ölrr²éz ™ÿüóϲeË!ºkpc½Ê¥pf¢¯€cÇŽ%$$DGG6ÌÄÉê¡âÑ :ÚÏœ93vìXüÁëkðÞX±bEll¬ncç«+á†ecwÔÀ?ú裄„„;wî¬_¿þádzmܸ1111%%%%%¥¨¨hîܹE 0 Gp«„……=~ü¸°°pÞ¼yáááñññ_|ñEÿþý_Ö¶£(*88xÁ‚qqq‡ž4i’A)>Š¢&Nœ(‹“““>|qôèQŠ¢¼dÉ’¸¸¸½{÷Ž7ŽeÙÈÈÈC‡Ý¿?))ÉÓÓsøðá/Û¤òòò3füý÷ß÷îÝ›6m𱓂ÎìÒ¥KBBÂíÛ·×®]›œœ\RR2{öìóçÏß»woüøñPvýúõIIIЙóçÏG ÄÀ/jÁ‚ 0àYZZÒ4ýì}wXTÇ÷÷Ìö]`é]¤¨ b!XÀ¶$¬±ÅžD1vcO¾ÖÄkÔ¨¤Ø»ÄÄ’ØKŒDƒØÀ‚ADD¥,°,Ûw<_î»Y`]Ö„ù<>>w‡9wΜ93sæÌ™¹‡Ïç§§§ÃÒ¼{÷îð°oß>v½ž––>y6‘Ãá°þ=Ó1c¼uëV6[FFÐzyy™Òr8×£G=z`Œ‡ Šg³åää­‹‹ ¤XXÜcŒW­Zžft‡ãàà`V.ÆxôèÑ­ZµÂê–kl¶ââb 3ܽ{÷"""Ø >œ3gÈ„ ¥p¹\x›"þù&*ž1cFvv6Æø³Ï>cËÕjµìkùüÿÛé?þpà›­I“&ãQ£Feff²‰~ø!BÈ`0œ¿ü6YÌ9{P¥ÂæfU™©GaÖ.fçx5 ÇšÏç³ÞƒÁ *¤5ë ­ª0µðÌbw4P(„DÓÒu:˧igÿ ›ÈöG›} ¦E0 £ÕjÁKgY˜¦aBŸÕëõÖw j4Ô.´nÝú·ß~;sæ —Ë2dȾ}û† bÚŸ D±1¢}ûö°Ø­[7„P»víöîÝ ^¯×OŸ>zéš5k222Ö­[Ô³gOçéé nN÷É'Ÿ899EGGïÝ»º+‡ÃÉÈÈX½z5B¨^½zÌÍÍ}ôèÑ'Ÿ|èääÄÒÆÆÆ:88téÒeÇŽ<ÏçŸ:uª²«D"‘D"Y¿~=B(;;[­V#„zöìùÃ?p¹\>ŸâÄ Ö{zîܹ[·n¥§§Ïœ9ÓÑÑ‘ËåmVV–N§³0›Nž„y¦ÙàhHHˆ§§'Œïì¼S»…»%† ²aÃ0¶t:££ã˜1czõêÅ–ëîîΆ'Nddd<|øpÍš5Ó¦M/ K«Õj£¢¢`ȶ I vbÓh4ìØ±#˜°‘‘‘ì_ÅbñôéÓW­ZEÙ¶mÛ Aƒ:wîŒ:räÈÅ‹F£F£2dH‡t:‹‹KXXB¨[·nË–-³³³»víZiiiU/!„ܺukÒ¤I!!!………‹/f'i£Ñ(‘HΞ=Û¹sgBÈÇ{öìÙ«W/BHJJÊO?ýDIJJš:ujýúõóòòÖ¬Y¡‘óæÍËÉÉå‘ËåUeI*•Ž3fÉ’%NNN7oÞ|öìû†äää¶mÛªT*±X Â4hPtt4ØU­[·†ÅC\\œƒƒCJJJqq1Ã0;wî8p ˜ÚGMLL¤'0«3°$P:îÞ×<ɶöëÓ¥–o­ÂBýÉ“'ÂÃÃ1Æwî܉ŒŒ ¥²{Iׯ855U¥R †¨¨¨«W¯¶lÙòÚµkìiòââb„Lfiiic£ÑÉãñ øæ!†aÚ·o$‰‰‰b±X¯×»¸¸4lØ!TTTt÷î] mÙ²%,®^½ Sв]ôþýû2™ÌÓÓ³^½z¡ÂÂÂû÷ïmëÖ­ÆøÊ•+z½xNKK«Lòòò233B 4xòäÉ;ï¼cŠÑhÚ»wï6jÔŠNKK“Ëå¾¾¾þþþ¡gÏžeeeB6l˜nA’?îÞ½{ZZüÌÎΆ—dddÔ¯_ÞŸ””ëõ¨¨¨ôôôàà`Hi³ÕÏÉÉ`1ƒÁо}{ !ééé!!!¦ —˜˜ÆGPP——B(333 Àt?*ÈÚ999°#׬Y3 ® (ââÅ‹ÀŸÏg#×.^¼È‘¹¹¹!„ÒÓÓ ù|¾Z­ŽŠŠÚ .°«O¨ F£)..öññ± É¢¢¢_ýö’X|øá‡®®®6lxÛ{\:uú÷ï¿víÚvL…BqóæM‘ìx˜œœìçç2dÕ!ÄŠ!]•Çã±€lW­W¯ž§§§mÌgggçææ:::†††šÞm””Ô¬Y3ðo±,aŒ;tèÀfËÊÊzö왳³3t7`éâÅ‹ ðچ±ëÆJ¥Òßßß××—ý“R©¼qãFdd$k…”––š JOIIQ«Õlß©L˜/¤¤¤ÐÐPvoT«Õ=z´iÓ¦åÝ–ƒÁÓӋé R*++»S»ž³,IM½q`ØNj4PÔóëmhª3Ÿ5Ûhðõõýàƒ^h4PPP£Á²Ñ@·'(Þr_™uGª·o†)..öõõµ9(µšÀÑÑ‘ÞNAAñò FE­õVˆ T„††–•• >¼4ºiÀPuP-ª‡ÔhøÏCß-]êd0ªÞ¶Æ0z__D×µ õêÕƒø5ëGö¸µq'&UÓ.3>zŸ·H2c@°qãFÓÄ€€€Óôc³Ú½r˜mõë×ËdöN•‡ †Á>>zÚk9´ZíÈ‘#«tœ› ÿ×ùBÒÒºïÙcifv6ÒÓ¾W‹`ƒ›ýnƒ»»z¬G™ È@e^€1.--­*•@À_´h´m%feeVt£4E-R9•JõæO¨Öí ¦ÜLP8tèñŽGÄÆæÇÆžhÞ|äĉÏfÌ8íç7rÚ4ÓlƒÓžWk`›C˜Ë˜k×`Ùà®ÇºŽ1vLþ˜ðáFN˜ölZàéÀ©#§ši—Síª-0Ú2’T uëvt̘}Tкõ‰ñãGL™ò¼~ýSS¦Œ4Ó.†¡»TåÞ4jì5ÒŒX¬rrBíìþïÁÞ^UÉ–((ª1#vR9!„$ŒÄI턲gìUT»(^…v‰gg5BH"aœœT!;;£££ŠJ†¢:€~{‚‚‚‚‚‚‚‚ Ôh        F5(((((((ÞZÔØ!Ožø¥¦"„„ÕåóB¢ŒŒº mrŠ—G® 7Õ/!”-Ìû‰B™ÂLu]5• ÅËãéS~JJ„ÐãÇ‚7üBŠôúºT2ÔhxeÀå.hr:y²ÇÉ“!—ƒ{ „rÛ½»GyBzkm‚mÍ­ÇæÚuÚñôé§B‡îq!´×m/êAµ‹ªVUQÁ]gÏ:ž=Û!ôûïοÿÞ!”àŠÊ©Õ.ªro™ÑP¾þBHQL̵9slaI&£ÊW«àââR%í%„t/î>ëÚ,´«Q×¶AÜz=Á#„oÞL1l¹¢§¸˜Š¼¶Ãh4BÞð\l‹Ñ ÕjÏž=[­ìÜÿ2¹œêÅ QVV–••U%í  —Õ|íÂóx<ý¿v<¯Æ¬h†yÝ7èUi`$„„††•Ò^IasŸýûï¿-(˜ãk¸ÏУÏçGDD0 CÛŒ‚¢Æ ´´ôÏ?ÿìß¿?û5H>Ÿÿûï¿+•Ê`7B‚‚‚Z´hA.ŠÚƒ;wîT £ÃáØÛÛÓö x3c}MÚ»­ÎÕ1 jµZ"‘˜&*•Ê-Z·ÿK°Ïž=c†\µmü¬FE™T ¸7PhU‹ „ètºË—/wèÐáeØ«V“40sæÌ™Î;cŒ_ž1ÓÚ½¾šŠD¢ààà·½gñùüçÏŸ¿ÂNQ>C…ÍñJÚ¨ªýÔré¯DU¬aÉzÔ°µAͽ§¡zc,‘H<<>&ò°°°‚‚¹\Þ«W¯²²2Û¬Õ°°0V¥+ÃóçÏ—/_.“É233{õê,Íœ9sß¾}ÏŸ?ÏÈÈ€Jq83aRT[Ð퉗Zç%%%zyyaŒW®\9sæL„ÐÒ¥Kg̘1cÆ ¡P2fÌBHvvöš5kø|¾V«ýꫯ¤R)äåå!„4ͺuëXi;ÆøÁƒñññ<O£Ñ,[¶L,cŒ—.]*“ÉB:níÚµ¡/¾ø"==]­V§¥¥5iÒdÔ¨Q¡´´´Í›7s¹\F³jÕ*Çáp–,Y"—ËU*Õ† *›?0Æ©©©;wîÄ8ðĉ .LHHÇûöÛo|Ò¤I°Þ¾}û>}ú¨Tªëׯ'''?þJáO*•N˜0ÁÎÎŽ²råJ >I‰D®K€V$-Æxùò儃Á0mÚ4ÈÙ­[·®]»"„Î;wôèQŒ1[®éà‹Ú¸qãØ±cB'N”H$ÎÎÎÑÑÑ7Öétééé:t˜8q"!$>>ža‡3kÖ,xƒ@ øúë¯BË–-›3gB¨¸¸8%%¥sçÎÏž=+++Û¾}»V«U*•,íŒ38¤°rfæÁƒB¡°2»Xýì³Ïx<BÈÁÁaÁ‚ Ã0 3mÚ4±Xl4GݬY3ÓÆ2¥:uª@ @999ýïÿC-Y²dÞ¼y .T(±±± 6¤ý·BŸ={vxxx›6m,çìÓ§Oii)¬‰ËÊÊBBBîß¿_§NViÛµkwåʽ^ïîîNY½z5먪3iΜ9Û¶m³œÓÉÉI©TªýÊ•+3gÎ\¹rå¨Q£ !íÛ·Ÿ5kÖøñã·lÙ²zõj`ãæÍ›6°¤ÕjcccSSSÍÂ_ÊÃÛÛ›H·nÝ.\¸,“É|}} !K—.…Òcbb +ÌFݽ{—j#5j&Ο?/ ½¼¼B_~ù%k4>|øÐ¡C*•*99ùàÁƒýúõ›0aÂÆu:D"‰ˆˆ¸wïÞÚµk[´hsdDDDrrr… ˆÙ³g¯[·N¯×K$’¶mÛ¦¦¦.]º´C‡>>>!±X–ššûçŸ÷íÛú³F£ùꫯV¬Xa0ìììÂÃÃoß¾½pᘘ777©Têëë[·nÅ7Í•••­^½ú«¯¾b&>>¾OŸ>¡~ýú5iÒÄÞÞþðáÃ:®GÇŽ#„|öÙg\.!´ÿþÔÔT??¿:œ?ÞÏÏÏÞÞ¾Aƒ}Šò÷÷ÏÎÎ4hвeË€F3~üøï¿ÿ~þüù`48q¢sçÎÍ›7OKK‹ÅR©´nݺ?îÝ»÷úõëF£T*±±±ì"†x óÄûï¿¿yóf°‹ŠŠ>ûì³Õ«W‡††ž?^©Tòx¼Ï?ÿü§Ÿ~*?jcŒ;uê´{÷n°Hòóó¿úê«ùóç·k×c|ãÆ ggçéÓ§ïÞ½¬ 3Œ?>00môÊ`oo/—ËÙól ®¦œÑhär¹~ÂÿB¡Ð–¾øâ‹ºuë¾pjíR( vvvléÐâB¡P­V³=Ë5àóù+W®DV_.Ù ¬X€CH&ííí ëV4&5j `Ö×zRRLT÷ïß/((€œZ­V§Ó©Tª{÷î!„`­ƒ;Ç{üøqeëÎçÏŸët:NÇçó³³³a"ñöö „ ©©©„€€OOO馴z½^ €£,}†arss+‹qcF«Õ‚IÁ0 (àÁƒZ­jÇö­V Õ/..†¿N˜0!** ^ÓpQQ‘V«e®W‚D+!“ÉT*ÐBž={ÆŠŒ™LQ c°Ã†‹Ëå>xð qãÆÉÉÉ ° ÉÎÎvsssss‰Dƒ*¥@½`0}úô)+L•Jn!ÓF‡g½^¿~ýúÆCbNNвÒÓétÆ ³¾¾¹¹¹uêÔçÀÀÀ-Z „òòò<<<ØÕ^e[¿Ož<ƽw”»»ûÊ•+Á9aÁ^¡`›»ú 2³þ?ôÜÝÝ©ªP£âU:9ÍÌpBÈÎ;—/_Îçóa†[¿~=‚‡i€WÙ =z´sçN¸üë³Ï>«'>ܵkÐÂúØJˆÅâààà>úc,•JÝÜÜÌÞL9räBhÆŒööö`Fܾ}»ÿþ•1cºž°ŒÒÒRô¢˜êiÓ¦9::B8Nzzze9…Báž={ÆÏN¥¡ 6Œ9’Çãq¹ÜO>ù„åP.—»¸¸ÀB•ä¬R©¬Ì ;Åoü>?à²qãFÚI« h5V'ËÊÊÁnãp8r“›å —Ë5 ð%`[¿>KJJÐ?A…ÐÜzlZºV«‹Ål˜¤N§{Ý¢ƒÒy<žÁ`€]66˜,++spp`… }Ÿ‚ 5:Žu9Z˜60ÆC† 9yò$üôöö^¿~}iiéܹsaYÌö.ÈÌårù|>›Ò¨Q£… š¾z>ûòàààôôtôS!tðàA±Xݼys3ZF´°b¨_¿~…<«ÕêÌÌÌmÛ¶ ¶¬ò¶Bˆl€ÄÅ‹cŒãããÿ÷¿ÿÁ1ütuu5 W«Õ¡µk×BŠV«…BÙ1jggg§T*U*ÕâÅ‹•Jå€.^¼‘_³gÏV(jµšÃá…B3ë„õ%@A‰D¢Ñh 8H‰D/œ¤ámãI“&±?àU/¤…qæÌ™ßÿ½)3Rʲm:Ÿ™Q‹Åf2{áôfæLb[Ëå.]ºb\> ÚB†¦ÉÏÏïÛ·ï¡C‡†ùûï¿g̘ι¼¼ž>}êéé »Å^^^°S&‹!ò†Âò,z R©Îœ9ܱ;; Ã(•JˆiP«Õà‡pwwŸ6mš‹‹ËíÛ·Á~]»vmTTTVVÖÒ¥Km¸îcìâââààдiS¹\^XX²cooovÑÂ0ÌóçÏ9ŽL&–Þ{ï½ DEEíØ±Âoܸáëë«Óé®_¿nC˜EYY™ŸŸŸT* ö÷÷W*•`©€…äíímŠ4þ|oooGGÇ{÷î@V¬Xѹs猌ŒÅ‹ÃŽÃ0*• „©ÑhX§E5í&’@é¸{s\ó$ÛÚ¯O”Z\\XÞ°-,ÔŸ±ÂÕaeï7»8ÅÚÊØ+))ùøã8À^l ô ob),,œ={ö–-[ªTY3–t:]JJJdd¤• [_5¶:ðüÙgŸMš4)((Èz9[Pöÿò‡??¾C‡–/w²RP¹]° UÈÊË…ŠŠŠ~ýõW8ZÂbëÖ­mÛ¶µlὸuëVAAAçÎm[Ö—ïboær'Ûn=zÃ7)YÓéåNÿ ’’’BCCÙØR­V{ôèѦM›–«5 žž^Ž¢üK²²²;µë9ûÁ’ÔÔ†í¤ÝË.MÊ»1˧W6o•ÿY>ÑzZ³t+i+cÏÉÉ)::¢1ưýQ!“fwéXSY³ B¡°B‹Á¡õ9óòòت‰Åb¸|Æz9[(ý¿Bf!ÑÑÑlP½•zUoVª•üW†š±ì³¦–ÒB_³ ê—”¿mMf¹ôW>=[Óß0K¯t{‚¢RL:uêÔ©6º»»oß¾ýµŽG/¹0òðð0»ìèÍ [Õyp¬pZuvv¾téÒÅ‹ßöacôºK©’"Ñå55þ@?Ý«U`ìí Ïíõ—Hšÿ;,Ãò\^{´K¯×ëtºãdz‡91ƆÇãñx5a xôèQiié /<à¾=cOPoaBXΗCÜõvÌ©S§Ì¾ENQÛ@rtd8[.iU*™öíß{á-[Ôh¨`X¯1ß⣰Êb‰ê(¹|¹ÊªÂåfäçW•ª¬¬¬eË–µA»Ø«&j3ÎØ™è;ÑÂë×®Û`ÇtíÚõe>4Cñ¶ÃÎÎôð¡- –Û©Ó›^ÏÐÕ9E "2òq£F¡Òvíž„„ „äQQ¹•(¥ °~Z¿ˆ¬„P&¨UV+„P°:¸EV *Š×‡.]ò¡Îó¤R%B¤sçgvvêÿœ1j4PÔ<^´è‘#BââÎŒz¸råßýúQÉP¼$:—vþ߉ÿ!„bJb柃T4hæ±™T2¯ßŸ’ƒŠ¿ðc´aÃeoo5((^‘*ëõ\ƒ!ÄÑé¸F#Bëtêø¥xi±QÏÕWø@Añš Õr#„tºÿ{Ðj¹„ü÷‘³Ôh        F5(((((((¨Ñ@AAAAAAA Š×£N$BííuB!Bˆ±·×[ü%…5Ö!$`þïAÈ%: • Å냃ƒËeBzöÁ¶; ^-è5Òo!0FÿÜZÈ¢IçÎMB5ŒlŽB(<,,Ü,S9*« Äôê°Z£]æ [Ü·l™¼!´Ú{õê)«B‹ê,BS¨¤(^É`†áp„ºÁC``/x¨WÏüù2&Õ£ÃáÀ ¸Œ­SÅ[†)èۗߺuUé‡ÃÓéªÚ¥õz½V«¥ÚUKàGübŸÆòª86j±Ö†²ŒF£N§£7I×fB†Í+)áV…†–r8žoÑ Óé.Wýß׊ºuë–””Pý«=(íÔ ÙöÍÆ¬¬‚Ç«DâïïOµ«öÀ¹Ž.m¡ ©ª40bŒ7n,“ɨÌk9bb¶èêÕk>ó:TF IDAT¾cãù|~µzu㇢&¡–h—Ñh”Ëå...ÿßÀâà;wòtº²vuõ¨S‡_­v™¤R)í_¯¯Ã‰e‹Ñ BCCi{PPÔ$”””$$$Œ7Î41"bN—.}¹\Ý[Ñ1NK»Ó¾}‹íÛ½iCSÔ$%%UOE5!¢1Æo ·Õ“7†aÊ\(ÄM›¶Y¶ o·žètL—.FÚ_((¨Ñðæ “ÉRRR$IÛ¶mßÀÜ›®®®Væÿûï¿m`¬ªøë¯¿ Chh¨‡‡‡•$—.]ŠŒŒ|M“hffæÀSRR^ëüÚµk</::ú%ƯX±¢~ýúý^Ñ—´nß¾]PPàååÕ¨Q£×fLÀ¤ûÖ›—VöÓÒÒÒ+W®ðù| Í é§N"„¼ÿþûl¶¢¢¢””>ŸÇm0ÆIIIjµºaÆ>>>6+yvv¶³³ó;ï¼óB–0Æï¾û.›íÁƒOž{öìéÓ§#GŽ„%J~~~|||ffæÁƒSRR€¥Y³feggçææöíÛclKã)S¦tîÜÙ²0BŸ|òÉãÇïÝ»·fÍ(ý·ß~»páBVVÖ‚ X™÷êÕ+//&=ÞL= Õ{òoöB—ü¬S§ÎðáÃGŒQUZ˜Oœ8±téRëi¹\nyw±Z³Ñ„-×òʾ²lå!}Ĉ—.]²%nVŠD"©g("++Kðﻲr+38Ö®]ûǘ‘˜J²ü Ù3[XßdeemÙ²E¥R :tâĉ•UÖô Ê™m#BˆÏÓ§O«¤“ÚL]ºtAmÞ¼Ù­i}_•ƒ§f.¡8gøç˨ëÖ­KJJ*oòbŒGŒ±mÛ69rdddä¥K—Li—-[–’’âååuöìÙøøx˜>íìì”JeUMš4yòä üìÞ½ûo¿ýV>2c\·nÝÇÿ jÕªÕ¢E‹-ZùðáCHìØ±ã¹sçöî݃=z´m,-_¾|Ú´i¦Z÷Ba®Y³&99¹^½z‡ÂO>ùD*•–––:tÇŽÎÎΡ#F´mÛöï¿ÿ¦ÚH= Õ}úô‰ˆˆˆˆˆ ;{ö,Bèâŋ͛7‡Ä~ýúV¶Î‹‰‰ai“““B‰‰‰,mÿþý 0Æ¡¡¡<ˆŒŒlÖ¬ÙÝ»wBÏž=ëÞ½;d{çw®\¹‚:wî\³fÍ"""Z·n}ýúu.·âû¹¹¹ï¾û.І‡‡Cãp8›6mjÑ¢EDDÄðáÃKKK1Æ¿ÿþ;¤„……mݺc»uëVà°E‹7nÜ€ÉìÇ„œ£GV(F£qÞ¼y­ZµÚ;w²³ï ׃aîܹ­ZµjݺõÂ… µZ-ÐvêÔ xnݺõ;w0Æ-[¶üúë¯Ç±bÅ àdË–-PnóæÍþùgËÖ‰©]õàÁƒI“&“ØmÛ¶…rÛ¶m›žžÎ¦ÃÜùé§Ÿfffj4š‰'B¶fÍš>|˜"¡‰DrèÐ!„PBBH¯uëÖ³fÍÒëõéééŸþùo¿ýÖ¼yófÍš9rª9qâÄAƒEEEeee™r ÓÊpóæÍ–-[3;vÌÈÈ@íØ±#,,,""¢U«V ,€%ZyÚ”””ððp íÚµkNNÆ8**êüùóQQQ-[¶üòË/éJ®2˜¶‹…%/Ã0¦}¨^Hk¹Ñ-/ÙMMÀrÎáp€ª<­Y—1TýÛñJ¥Ò`0½¼0!Ã0ìÉ@ÖgCA= Õ›7oŽ‹‹kܸ1ü„Ù"**Šíoiii “&M*O»iÓ¦~øvæ`^Q©T;vd»Gqq±B¡ „¤¥¥…‡‡_ºt‰¥]¿~ý®]»Ø''§’’’.]º°´S¦TzçÜÊ•+·mÛæëë ?Oœ8­[·3f Bhß¾}‰‰‰111½zõêÕëÿ.svvþè£ììì´Zí7 Ñßß?;;cܾ}{ˆœß¼yó•+WZ¶l™““¦ TÍÔÅb%%%yyy@›››»dÉÎ;ÇæiÖ¬ÙÍ›7¯^½ºuëÖ† ÂzêþñdzþvŒñ Aƒ¬,—ËåÚÙÙ!„†¾k×.ÖF£éÂ¥S§NçÎûõ×_¿ýöÛéÓ§Ëd2¡PX§NnذÁtŒ›9sfbbâ½{÷5j¦BhÈ!l}úé§2™,888;;»qãÆ U %„\ºté§Ÿ~jÚ´é;ï¼3bĈýû÷[Y‘>ø Àõëס,•JÅfP«Õöööåi{÷îÍ.Lóóó-Z¿eË–)S¦$&&"„Úµk7gΡPHû>… °³³ƒ­ êi¨ „|þùç£GfWŸ}úôAyzz²)Mš41=¼n WWW???6§ŸŸBÈt8vvv®[·®éŠoÜÜÜÜÜÜXZÈÆZÜ„N:Uft X¾CÎnݺÁû›5kÆšð\.c¼iÓ&¶¸¡H¯×÷îÝ›}•H$‚—°Çh!ŠžÃáìØ±ƒ¥U«ÕUr`Âj†âëë Ep8ö…¬¥÷-²^tŒñâÅ‹ÙlV6¢YÊŸþijIðx<ö…ŒÖ¥K˜‰ËÊÊ0ÆB¡P Ìš5ˬܕ+W^¾|¹eË–wïÞeK1m_6³Á`€ØF0X¯ Ã0z½^£Ñ°TÖ¬òEÿþdFxx¸YbeûV!±XÌ>kµZØúÑh4¬YvñâEj1TU£ØÓ?±mm™ÖÊF¯*K•e³†¥ ³½1aþç,QP£Áv`Œoݺuùòeò`¬þü91ÁСC+TèÂÂÂ'Ož°Ùîß¿#µið‡#„`™ˆ1NHH€U`QQK{óæMSo!ÆøÀ•mOhµZvnÀïÙ³§Âl*•ê矆÷—•• ªrlŽa˜#F˜ a‚X,†WUÖÉ!3ð–žžïܹ38]!T(¬Ñ!ÜwîÜ‘Éd?ÎË˃lyyy–™lҤɅ Ø9ža¡P˜Ð¥KØaA5mÚÔ`0À ÷îÝ[VV†rtt ÉËË X³f !D§Ó­X±Â¬¾å³öeebªQ¦?õz½™å{FC† ±P/Ö£8þ¼Y"¼“-š5ÑB¦[Ôb±X£ÑX` C‡MLL)=|øÐÓÓ“•ÛÖ­[oݺêÔ©ÓöíÛÁdܼy3¬4>üðË/B†ÜÜ\777±Xl4a#éæÍ›­ª€½-ŒqYY™——k/2 ³qãÆ‚‚Ö¶wï^`éСC-Z´@µiÓö§JJJüýýBõë×ÿûï¿!ÛÑ£G‡þ2ƒ§™PTT´qãFVá‡ú×_A¶Gyxx…B.—k00Æ·o߆ЊÎ;oÛ¶ XÚ´i“mR¢xc Û¨N:°õ ãrZZBèöíÛuêÔ_7ì¬cŒÿúë¯Ñ£G#„ùå—-ZL™2¥oß¾ѦP(àáÆ,mýúõÙýôéÓõêÕ3 6þøcÓùÉ .ìÙ³gQQÌaÇ7›ÂµZ­^¯‰D;v¬W¯—Ëíß¿¿N§ƒ²Lw:åryy‹Ä`0ØÛÛÕ¯_ŸËå*Š«W¯Â½uëÖOž<)++[¾|9cegggŸúõëcŒG‰ûöíkÖ¬™V«-++Û³g[îÈ‘# ”™™µ~ýz©Tjgg× ABHll¬åL×®]{÷î=cÆ ðŽøûû?þ<,,lûö탆³''OžlÔ¨Ã0eee»víbË\,ƒ0—/_>jÔ(‰Drúôiooo„ÐòåË£££óóó{õê‰MNN®S§0ø JT›7o ¢×Õfdûvçâb® ´ýuG‰Äž Uî¯ÞmOŸ¶ôþ–-ø5|qœ¢:{ªJ"ó–nk‹vmNßl@*óÚŒ±Ù)k  7n¬§CP-†½=“œ”•eËgd]]Ÿ ozçÔ˜.k–7~üº£GBOçÎýîàA„Ð㸸ïÊ»)¨ÖÖØè .G›{lÝ1„Ь§³}w!´$gÉÏßýüjŠ£¨=ªE•„j!W hÓ& !”•õ{óæ“Ì̃ÁÁ9ÿž÷þõ©±—;aN T"„°V+P©BFðï;s((lƒë”%BHËѪ„*„†£Q ¨vQPP¼(<£‘ƒR(øfÿ-è«(((((((¨Ñ@AAAAAAA j4PPPPPPPP£áM‚Ë5ÂGy<#Ÿ"ÿp Ç „Üvíê!‘P]¤xyœv<}³ÇM„Ð!çCç{œGíqÝc×ÃŽJ†‚‚â•`ܸ°{÷Ä¡O?m‘•eO?>âÙ3Gj4¼J˜Ú`‚ìlÿìl‚033!‚èþý€ç»è9iŠªª×cÁãÇþA…QB¥‹ÒQEêEµ«–àe¾*B•„¢üm0çιCú¹sò矞ÿÎùßÜÕj‹ÑÀ0LQQSn_Ö ˜4o^•ûÆÜ‚ª­µ 2™¬JªÒ_Ûÿ‹¤/ªª]áBn!x­²Š‹‹­¿šÏçK¥R™LÆÐ›ìk1Š‹Ñï¿_çrm1Õj$“q+»åcü:¾g‹Ñ ×ëSSS«•ÜݤRíÓ§Tÿ(^•Jõüùó*‘8º;>ÕÖ|í ­Vkº‰Ä5æ³ÅF#£×k_k)))UÊïíí­T*i¯¬åx™oÂßµ°ž‘J¥ÕÂh …;w¦-MAQ³V<Åû÷ï5Mܸq•V«®ƒ1$$¨[·´¡)j’’’ª…Ñ@AñÆ@©1+Ýj^ y#„´k×ÚÁÁþmßwÏÎÎѽ֯bSPÔÔ^£a˜7ör+§ `éu3fúþ76‡Uµ BˆL&Û±cÇôéÓ_†Éj5I3_~ùåÌ™3E"ÑË·²ií^_M9ŽŸŸü՟oÆryi~~Á«"Ìþ?Íš€ýù’ýÚÊV®K/©3V²dú'–=3>+3UkÒR¡†¡Ö]˜á!¶u`¹\^¥üGݺu«•€ÃáØÌX•æŒñš5kÞXÏÄ÷íÛ×ÊoÃáïïÏZ ï¿ÿ¾Æ¦}?Œq‡ †ÿøûÔÅÅÅ ÀB,XàààúËKuذa"‘¨K—.¯µ) !„ ·ùŸU†L;wîÄK¥R =‘Ãḻ»‹D"‘HÄçó!'ÆxãÆG$Mž<ÿó B†a$ÉËX ±±±"‘¨mÛ¶Z†5`©aÆ,K#GމDãdz,=~ü¸{÷î6ë Æ¸Y³f`Ö¬Y¸’/-çÛ·oÇ;99±Õçp8 6–òòò0ÆS¦Lý‰DM-j4¼‰5\ùŸ&FEEU˜þBZHéСC•h9Ne¡­Òše&våS†)€M*)†ÉÎÎÎÌÌT«ÕÖ‹_˜‚*??&‰^HËI?þøãüùóÑ?'Ù„B¡5åVX4 OÖpXþOf±r6ÍVÙÛLia4g«³hÑ¢-[¶XÍÊ­lP&„ìÞ½[£Ñ¨L>ßZž–º¬‘@mÆxÅŠeee„ÒÒÒ>ú(//¯Âœ}úô)((Ðh4F¯×#„–-[†1fF£Ñ¬[·fÍ+W®L:ÕÕÕÕf–¾øâ‹Ñ£Gk4šƒNž<¹²ŽcooO–Μ93sæL„М9s¦L™¢Ñh!}úô–víÚµ`ÁÛXÒétãÇ¿xñ¢N§{ï½÷,XP¡&cŒçÍ›Çãñ!%%%cÇŽ}úô©Z­þôÓOSSS%OOOBÈwß}§ù_ýõðáé*R£áµ[ ã>}ú¸ºººººÂzaŒ1ǃDXŠU8ÃB²ñx<––ËåBbÏž=ÁŠçr¹wïÞuss‹ÅÉÉÉ@ Ùø|>KËáp\]]üýý-˜á‘‘‘@+ ¡ãB D"‘««ë°aàÜ888¸ºº ‚ÜÜ\Œq\\!j'‹9‡Ã©_¿~vv¶X,vuu3f Ð:tH*•{………„0ùKKK-›óã½{÷::::;;oÞ¼988˜ÃáLš4É`0dff …Bv¹ ÀÊ£¨¨hÕªUmÛ¶uuuår¹O‘J¥cWWWgggËKí3fÌ;—Í@¹ßÕÕÕÍÍ hÕj5´‘‹‹K\\ÔwåÊ•... λ„ŠÏÍš5Û°aCNNÎýû÷×­[mgêUvý~~~ çÆC†Ç/_¾c|ûöícÇŽùûû»ººšÒ:::'NNN¦u™?þ¬Y³,è3‡Ã±··‡rCBB@¯JJJø|¾«««T*Ý¿¿éy*S_1‡Ã‘H$@Û´iSÈÊápêÕ«çààpäȺ’« ³gÏ?~<4VË–-322*›¡ÁéS8ĨÏ;w̘1¦Ùòòò6lذaÃ˺elÞ¼¹mÛ¶0Ŧ§§Wv¤ÓÉɉÕ.—+‹B{÷îmÙ²¥i¶_ýU£ÑlÚ´©¬¬Ì6~4Mqq±ƒƒ!äÝwß]½zue9GŒñû￳¢ðððP*•Z­Ötý`ªŠãƈŸ3gŽL&ƒCÏÞÞÞ0¾ H\·nÌ+åiW­Zµ|ùrÈf0ØiÃh4Bâ7ß|³uëVBˆÑhlݺuaa¡Z­Žˆˆ€ýé7B6½^ŽJâe2™B¡ µ³³«ç9sæ$$$­V« A‰ÅâQ£Fi4™Löá‡îÝ»—Ò¿…B!“Ét:]“&MBF£‘­Z­†EÓ'O>ûì3µZ-“ÉÞ{ï½Ã‡«ÕêM›6•––{uëÖµ~¶ËåËåÅÅÅwîܹxñ"Ã0ëׯ‰DŸ~ú©V«U(°ÍÁÖW&“\¼x‘2sæÌÇËd2£Ñc„‹‹‹P(„`…âââÐÐP Ìp¹\ÓÅÕÕU"‘maaaË–-1Æb±Ú¨¨¨H£Ñܽ{7###??¿¨¨ÔÀÝÝ}[NNN=ÜÝÝ÷ïßožïÞ½ëççòàÁ.—Ë0 ˜t',,LörrrÞÿ}„ÐÇáµz½¾¨¨fŽž={fggà @"—Ë@àììl:JVæ‚ þþþeeePîÍ›7§L™Âáp<<<ôz½L&+--ݳgO…ƒ>ÆØÓÓS¥Rmbb"œ†8qâÆ8##C¡P¬]»Öô\%E…bDwÖ=<<À]WTTäîîήÚ÷îÝkggçää4f̘æ·mÛö’̘ö ]¦nݺϞ=ËÌÌÌÏÏ÷ññaÏÚM˜0ÁÙÙY"‘lÚ´ !ôÁŒ3F¯×¿¼|à`¯BÛ7$$$&&F"‘xyyýöÛo ó Ä……9;;s¹Ü«W¯²ù“““þùçFiµZjÔVgÔ@ÈÎ;oذaçΡ²²²gÏž!„¼¼¼¦N !Ó999]ºt©V*•Ο?ß××\Ù!d:Ó7oÞ¼yóæ`üš™ùNNNsçÎõôô:X÷¬/ráÂ…ÌÌÌ Ë‹Å¬W™rÿþ}„Z­>vìŒVz½^ `ŒïÞ½»jÕ*>Ÿ/JJJ`F·ô. t:ÝXZ{{{ŒñåË—'NœÈ0ŒP(´y¹ƒ1.--…9˜Ëåž>}JY°`»¤°··G]¹rå‡~ „Œ?ž³% B¨¨¨H«Õ²aPßJÈd2•JÅÆv±´P.ÆøüùóÇg06@SŽ7®nݺ[·nõôô4‹Ãâp8¬Xär¹N§ƒ ß|ó“*•ªBû¬‡õë×›%:88°œhµÚ*9]YZP§ï¾ûÎŒ 6‡éÉì²²2¾\._±bgìØ±È)¬qm®^½záÂ…F©T°«y¸waåʕ׮]kÕªÕc)))iÚ´iÐÍ‹ŠŠ¾ýö[XHL›6->>!ùÉ'Ÿ¼IÃëóÏ?oÖ¬ŒrãÆ[¸p¡P(<{ölVVŸÏ‡<¬S!""¢¸¸!Ô¸qã;wîP5£FÃëí0 6\²d ŒþR©4 àÑ£G&..‚ï!¬ûÎ :nìØ±Ð½ !ÿûßÿ¬ÜAiµÚñãÇ7mÚ”u;›å´þz¸ò&<À`0Ì™3gëÖ­z½ÞÅÅå矆 r¹¼ÂR³èè°°°/¿üR¯×BæÎk='ŽŽŽQQQ€ÃáLž<9((ȬBŒAžžž=oíÎ;¡ÊåŒc…Ba:Z,£Y9W¸Ìòòòzøðaii)‡ÃYµjÃ0¦‹6³Z­^´h‘Ott´§§'¤?þ|=bIär¹‹‹ !äóÏ?¯R«™F”ÿ«©@¥ Åî&Ð;!ƒ ¢Ÿ5œËå² Çª"<B/^ljPÂCLL d0ÓÆWÒpãÊBz¥5kÖÀÏÇÃbÉßß?88h̓^F8ldÆØÂåTK—.…íKŒqÓ¦M³²²BBBºuëÆÿçÃ’Š>dåAA†—2i÷ï߯P(ÂÂÂ`QKÿ&Mš<~üú³X,öööF) ¸0##ÃÃÃC*•º¹¹)•ʧOŸÂÖCÓ¦MïÝ»´·nÝâóùC‡E…„„¤¦¦ ‚Q£F]¹rÅÃÃC¡P˜Ñ6kÖìþýûJ¥’ÏçGGG'$$Tȶ··wFFŒ°+qùòeÓAÂî ·çææ †-[¶óf¶P™ÎÓàc‡o 5`Ü@îÞ½›““síÚµ-ZT6m_¿~=33Ó`0@hˆšå•=<ÜÁÁaðàÁ»wïZ­VÛªU+ðõ}ùå—°ïçç÷á‡Ât²}ûöeË– pÑ5jûöí@«Óé€öòåË‹/†w¥R™““S!ÏãÆÛ²eËÝ»wöòåË¡~øÍ1M+W®Ü³g—ËíØ±ãž={B psscsÂ@öý÷ß³)‘‘‘B¡P(.^¼ø—_~áp8:®~ýúP£ÄÄDF|òäÉÊŒ>Ÿïææ¶oß>àaíÚµ°'jZ TäÖ­[P_>ŸŸ““Ãçó !S§N-((HKKÓh4p·.c -xt`Z²dÉáÇûôéƒ6lØîÝ»¡8ØÆ0 [®Ýýû÷ÝÝÝœœ pêÔ)Œ±Z­ÉOŸ>65`wyÿþýìӧ϶mÛÀ&ËÍÍ…`ò>úÈt‚²eË–åË—³Y¹r%Ã0©©© ...|ðV«­[·.„;@D»wï^ºt)lÈd2PŒñ¾}û–.]jaþ&„ìß¿?..–ªvvv÷zéÒ¥o¾ùF(2 óÅ_À*íÖ­[÷îÝ›0a¡C‡`í·ß~ûúë¯aj‘J¥3gÎ$„øúúöêÕ‹Žw–z²k×®íÛ·‹D¢õë×›vkÖ¬iß¾=›ùÏ?ÿÔjµjµ:77V!BÑÑÑ 6T*•'Nœ …+W®~ü¸X,®ªÑ@1bÄöíÛO:õÑG™:‚‚‚–/_º½xûöí;vì‹Åß}÷¸{'NœxìØ1Œ1Œ ì[·Ž³!„ìØ±ƒÞÓP­Wé’@é¸{s\ó$ÛÚ¯O”Z\\X¾µ õ'OžÇß¹s'22244´ºÍ~Zy“I•h­¹,¥|AÖ\`®q_ȶ…B­©²•b‘Ëå±±±¬›D$Á)© +XNa çÌ™³yóæª Ê4!D¯×Cì¤5ò´FVfî\xž>}ú”)S ¨Ó6YUØåÍø“V«…¸™¾ê…íX~7ʲX濨¨è×_;v¬iâO?­Œˆ ©÷¶T)--½   G‘¶*å·'^8«½ªk‹l¸IÉúò†Yz™‰Â$%%…††²qNZ­öèÑ£M›6-¿}l0<=½8œ ¶M³²²;µë9ûÁ’ÔÔ†í¬!ñPfJVáxeŠX%ZËï¬,¹²yˆ",jM•­‹££ã°aÃ4hÀãñJKKKJJX'ä »4Ç«_¿¾ ‚2ÍÀîÂZ)Oës‚ãÔÛÛÛÉɉa˜Ù³gX¯–•ÐBÕ*¼sÂær+«¬ZÆbBPI‰üÙ³<†y»OÁÉå¥/3ª˜uOk$ie«ÙƆmÙþs–^fD¢¨& AÔ•¢wïÞ½{÷¶ÐÉÉ©J„ÿ‰‰ Glèâ†ø?ÌР¿BQvûöݰ®pp¼îRª¤HTë(¨Ñð߀²~ýúWLQí`Û½Úpp9Ô¯_¿ü7Z-ïÔí"„üôÓOf)5¨~Úû÷ÿU;Ž­Õ0ˆ©Ð.1ÛÜy¡³qãFz‘Q­–*™lN§9räëøþuÍ7<<<"""ÞömWŠ W"©çímañ‚Å£G—ï6|ÀÝÝ=22’jW ƒãä]ß[‡ªüéK䓚‘ªø÷î/ÜebÃØÕ½{÷—¼j‰âÍÃÙÙèâÒÀ6ÚÍ›ó;v,{%l¨Õê7¿ž©!Û4Gmöš¦ÜxJºüý÷õ¾úÊ¥ àÒš5¡ Ú«ÕÇÅ…Ï›gg2jë8½^Ëé {bjW-‡Î¨“%:†uÖ+>v¼õñ ÷7üªúõwþøþÎ÷»˜]›\dóˆµb^gàšŸ¶í»hz½þ?ÿ EÕ[­‚ xììŒqqÏ›Îã ,¸øùçmœñŒæÌ‰2L§ZÝ«jñÿDs8´ù)Þ:´i£‘H‡“ߦN$"<^^›6†Š¶ä)(ª„ÈÒÈ:uBmåm}d>ðàYìI%Cñâ%8´i“Çç„BñœË5J$LëÖO9œµÞ F5(((((((¨Ñ@AAAAAAA j4PPPPPPP¼µ 7BR¼}pFDˆ¨ €c4"†`zÅK£_¨©Bü•ðÿÔ5• Å A*(1 ‡aPa¡˜l4¢ÂBI ;¬]sŒÓOQÔ¤f5OA¨ë»ïÂs·¾-Ó£‡Y6Ž^16»ÜÉæ[{©vÕLII±û×_Á_ù|~—.]BþùçƒΞ={ÿþýÚµkƒêp÷îÝ/^øúú6iÒ„í19"„Ba§NBçÏŸ¯V­Z||, †iÚ´©ŸŸÄlöðáÃð!–T*m×®BèÔ©SíÛ·?qâ„^¯oÖ¬Y… ÔÖ³muËåòN:]¸pV,ûM@ @i³³öÄb1BH$1 #‰jÕªž_¾|ùÙgŸ•"IŸ}ö™J¥"„´oßþ«¯¾0`€E¥ƒ·ÐÐÐk×®ÁϨ¨¨M›6ýøã“&M:~ü¸X,îÒ¥K=z÷î]¾|y777‘H„1¾uë–ÍÜ9Æl6O˜0!>>^îð³&naº»»õÕW—/_®Y³æ³gÏêÕ«GÙ¸q#xèÒ¥‹Á`€†a‚ƒƒ>|H[ã{ Ýž ”²²²6lØ ÑhÔj5ŸÏoÞ¼9Æø—_~Q*•jµZ­V.Y²Äæ$&--mëÖ­à cüÍ7ß`ŒçÌ™£þ…B1þ|„J¥2 Åøï·Sz½Þ`0ôïߟí1gΜ©Õj!lvvöÚµkBmÚ´ùõ×_µZ­V«]¼x±J¥²ÙÛNž:ƒ±’$‰ìMë;öàÁƒÆ7iÒ¤zõê?þø#!äܹs“'OnѢŀöïß1nÛ¶ígŸ}†1>sæÌ©S§þú믒&‰.œ\ ` S ðx|•ü¨¦P(lÚ´)­zª4P(Ÿ¿aÆ‹/ÂЭ[7g¦\¥þ“ýZ˜PBØ Šãšåóùf³Ù¢®¹—/_ ƒÕî>B(22Î÷=}útðàÁ¹¹¹ Ôî¦,XR¹lzl6*B¨ƒ=;vlTTT‡”J%!¤S§N7îß¿?ÆøÒ¥K .{xx”èNÉüü|nŸ;wî\‹ÄF¶ÿE V-P(¬7www‹z¾Ì1.\1b”RlllãÆÙrkÔ¨ÑÎ;Ù„OW¾ûî;›ñܼyó“O>ÉËË‹ŠŠ‚k"¡±•bgÕªUÄ?zô($$ê!d6›kÕªuïÞ=ø™””‹ümÛ¶…6³råJ8X“˜˜êò™3gRRRNž<É6†R/;±EÁÆððáÃàà`výìüùó£FogÏžmذ¡§§§‹‹KAAÆxÍš5ÑÑÑ¡õë×úé§ uÕ«W]N£Ð• åíR©R¥´´4XfÆ`0Bnܸ!‰`Š& u:Ƹ¨¨ÈÝÝ]*•ÂÁ…ùóçׯ_Ïž=<>BÓét"‘(11\BR©ΣA?^³fÍGEFFúøø „FµqãF±XŒ16™L<ïñãǼa,—J¥ljá0šÍ™Yzz:¶\¹r¯^½"„¤¦¦²YÛ¶m›››Bèûï¿?tèDjD^^ÖßßÿåË—°áâx{ž´lÙµH¥RFÃÝïÏÈÈàz~ùò¥§§'ûÓl6ö½««kaa!!¤¨¨hõêÕìnLµKš¤ððð‰'öéÓ§E‹—.]bc „<|øU k×®}üøqv¼ 6løðáaaa_}õÕ©S§àLÌСCüñGååååø#k”J¥\.çñxb±˜]?€?i4š””V‡hÕª•R©ÄËd2µZ Þ¢¢¢‚ƒƒSRR–-[zŒ¯¯oRR’EÊ)ï-X$þ`ºw–lÇkSž'äççZwd¹¹ÆØØ5Â'''7kÖ¬nݺ´ì(ï6—[-–…m®Û»‡Ç^X®»óaÑ¿_”ñx<Ç+Ã¥K3Äé ¬c¡ …"::zذa\Ç™¿¬›8äzy³ÂfBR²‹¼Ô<µÉd*õ¥Å0ŒÉd¢—;}ÌèõLãÆJÿýK Ò½¾½±w¡4Ƥ¤¤÷ꂼòåËçççÓ;ûþs êÕKŠB%­ŒqNλI¡F£Ñh4%j**T ­ëÃ"¬{µŽk{©fˆp!.,µPŒq‰:F>Ÿ”——G›ÖGδi…¥Ð91F&JNÖØSX1ÆüÎßÞ–Ò@SPPð^ºL&£Á÷“ •jÚôÎzM½^¯×ëië*Û˜‘Y‹JuqÓk4DBHI;FWWWÚ´(%ì,æðŽL¬•taõm) àÓO«0 ÕŽ) …ByOINÎx/”„ˆÙÌP¥B¡P(” úÉ%…B¡P(ª4P( …B¡J…B¡P(ª4P( …ByyG—;BÄb±T*1›¥RYº‹P( …B¡ü‡¼£•>Ÿ¿aÃV¿† ¿ðòò.Ñe&c±XDï?¡P( å£P23_%&&iµY‡í1bÜ|)ðù|¾@ÀÇB`ùu$„Bø|~ZZÆØ±ÓÄbŸÏgUnXZ‹ …B¡¼ÞÑöƘÇãJ¥Ò°°o†Q*UcÇN“J%F£qúô 5kV¿[¥J¥©S*•úر¦hÆŒyÏž½HIy¡ÑhD"Ñ€ÃûmGFÆ«¯¾ú&55Ùd2ÊårŸÊ99O¦L—šš¾mÛž¹s§!„u:½T*éÞ½ï™3G´Z­X,îÚµÏéÓ‡éMS …B¡|ðJƒ‹‹¬k×>¤äç9òwzú}•JÖh´žžB¡P$ F„V«=zô L&ÅXæáá^T¤D¹¹¹º¹¹ŠÅ"ww9h CÊ—/—˜˜l0ÌfæÔ©Ãf3CW( …ByÛ¼õ3 jµæÏ?÷]¾Û»÷·™™•J•=Ÿ£¢"•ƒáŸÏçI$bNwøð¾›7oß¿Ÿòøñ“1c¦¼{Û  …B¡Ð•†7ÆX«Õi4“ɤR©A'À™Íf@ „B!ÅÛy„‰‰ÉGž˜={ê'Ÿ4KIùG­ÖH$’fÍÚÂ9JZ— …B¡|ØJ ‰jÖ¬ÎþT©Ô/þ]³fc™Á`ˆŠŠäñxåË—“H$àÁd2µjÕÂh4!„+ׯ_7$¤]µjAü±O¡P>¼¯V­¦2™T¯×oÞü«Ùl¦Û …B¡”¥ÁÃÃ}ìØ ã¿+ ¸\9ŸÄÄ«„ Œ‘^o0›Í­Zµ uy¥RuäÈ•J…16™Lýúõ ïKQ(〿»w¯°a©Az …B¡PÊŽÒ€2MÜõBˆV«cbŒÍf†ûS§Ó±†Éd2™Lðl–B¡P(Ê;€!¤P( …B• …B¡P(Ti P( …B• …B¡P(Ti P( …òÁRʯ'Aô>% ¥,ß*Y¼×ôºU å}ÌAۣߥcžTêÎýB’B¡|èƒV«{øða£F ÙW["‘DFF¦§§ÓËÓ(”÷“3f¸»»Û{© yõ¾( b±;­- ¥,¡Õ*SBBZsçÎ]œššf4D"Bc\PP@ËŠBy}¼téR•Êèëëiß×›ßТ§|„BØ‹ÂJ=vþäLä\?Åú/‘çÒuCÖ.åÊùLœ8q×®] …‚ÇãFvÏÂ"›o©0)ŠMÊ•+÷î…Ò KÊGª¤Ÿ={¶OŸ>¥¨T*Uß¾}ÇŒã ,Æø×_u&rŒñöíÛ‡ ¶eËg4†)S¦ <øŸþ)QÊ_óÒªU«òòòêÕ«v^ž>}:pàÀ‘#G²Ù3gJW˜ÜrˆŽŽV©T´qR(ï3Ti |¤4kÖlÕªU¥(“ɶlÙ²{÷nÇÞvîÜéd„=zôˆˆˆX¿~}±ÃêÔ©S‡ ²|ùò+V¨Õê É£Fzͳ٠QýøãkÖ¬™={v¿~ý@Q )]ar9qâ„F£¡-“ByŸ¡Û”2EZZZFFØ+ A=|ø088¦Úcøi6›ïܹ# +V¬È†MOO‡CÖÞ‚9Ç“ÉdÁÿywž?ž““ƒ2Æ € IDATÍ›7Gÿ.õ_½zU(òùüFA®]»&!U«VõññAÉår's§T*½¼¼¼¼¼üýý!þ§OŸæååqå&''שS'..N ˆD¢O?ý!tóæÍçÏŸß¾}ÛÅÅ¥Zµj ·ÔhµZwww™Læåå…2™L…©Ñh”Je…   oÞ¼Ù´iS„Ð7 Ù<¯qãÆðWHª‹‹ › P(Ti PÞÏŸ?¿~ý:ƘÏçoÞ¼yÛ¶mÏŸ?Ÿ9sfLL B(,,lÔ¨QÁÁÁ&“éÚµk“&Mb×í_½zµråJ„@ ˆˆˆøã?œ—ûøñã»wï"„ø|þ¶mÛ¶lÙâææöÝwßµlÙÒd2™Íæäääþýû4¨Aƒ°È¿k×®ˆˆ™LæLü Ãðx<±XìáኌŒD¥¤¤ìر4>Ÿ¿k×®7vïÞ½I“&Íš53™LF£ñéÓ§aaagÏžÍÎÎŽ‹‹‰Dnnn¯©4€Â$¢¢¢!f³Ù¢0õzý„ öïß1^·nF£iÚ´éêÕ«Yƒ´ Ã$&&8-½^¿ÿþyóæÑ6L¡P¥ByB¾øâ‹/¾ø‚Û¶mÛÖ±cÇV­ZuèÐÁd2?~\,BÄbñĉ#""ذyyyr¹|Ò¤IðsèС%’Û®]»víÚÁOŒñ–-[T*Ull,Ìž GÕ¿ÿßÿ}ûöíàmðàÁ:ÎI¥ÇãÁ}íÚµõêÕKHH@½|ù²Fƒ bånܸ‘²wï^𜚚º|ùò°°°éÓ§'%%5ÊÓÓ•öÔ¡D"}ší¸Ÿ¾xñÂßßÂB(dz^nØ„„„:uêlÞ¼!´qãÆ[·n!„ÜÝÝ;vìC¦‡‡GQQø¿sçŽõøŠâóùÖ@œ^¯/((¨P¡ø1 ΫJ¥ÒÃÃcŸÿ†áöíÛŸ8q¢iÓ¦ŸþùßÿݹsgŒqQQÆŽLΙ3cxîÜ96,;˜Y“››‹1†ÿ—,Y‚1 yðà¬V­x+,,<~ü88º»»9r!”––ÆŠX½z5 ½áááã[·n»`qel—.]Ž9ÂF²ÐuØŸüñ‡§§'Æ8((èu4kãW¯^F‚1NLLÌËË9r$Ç;|ø0dêþýûlR]\\ ,„Â׫W{*‚B¡¼Ÿ`Y|øƒéÞY²_¬MyžŸŸkÝmåæccO4jÔcœœœÜ¬Y³ºuëÒ²£¼oXOÓáü`±ÞØ5óR aÍf3¨,ŦÄ"l±kþ\ØØ¬Ý1ÆÜØ”¢P(¢££‡ Æu”J¥¬þT¯^½ÄÄÄbï­²¸ë äÂHn Ø, …â<³fÍ8p`5ìyˆ‹‹«[·.û}–^¯?vì»KÈÅd2U¨P‘ÇSZGòìÙ‹6-B§=Z”p'¦ßnúÒRÊ l5ŒÙ–lÞ{Xꋉl†µÐ¤Ä"¬“'lº°±ÙŒ“›€’fváÂ…7¾wï^5ŠU°Ø?qåòx<‹ …ò!BÏ4P(”b˜9sæ¬Y³àÙh4Ò¡PÞ‡9œ.ú”³Ùœ““Cw)”²„J¥rwwÏË˃;B2™¬k×®Ÿ}öµ A¡¼‡B~øá‡ììlŠÅ{¡4˜L¦ÄÄDÚP(e W¹rå;wîp_í±cÇÒ7ByoÉÉÉq 4¸¹¹½JƒX,þꫯhmQ(e‰üüüß~ûmøðá´((”²{Ú›œ]Ðb¥P(!B=œH¡P¨Ò@¡Ã!ùO$¾q¹¬í†ÿ$S °þé l¦–ž‹¢P¨Ò@¡¼wÀ·ˆ§OŸ~—k×®ýÆOÀ%T2™lùòå% «P(ñN*Cr¹\.—{{{ÛõÁ=//µÆ‰1nÓ¦»»»ü_ÆOOKP(ô“KJÙYNpp§ãI­Í«Šl^±{QBˆ½ô ëàš)ë›üðÃÉÉÉ2™¬C‡Çwuuµy¹“…\Йƌ³{÷nÇi.–‚‚ö'¡`sÇF‹1>zôèÅ‹¹æ4u:]aaa±ÅN¡PèJ…òæÑjµcWWW— `ŒŸ={öË/¿À}…<ÏÃÃîrww—H$çÏŸgÇ*®\]]e2Ydd¤Í¡ cÜ­[7xpuu-_¾<ÄÃÿóçÏAÜýû÷E"‘@ HMMe£b‡pWWWP5T*¸H$’­[·bŒãââvíÚ…98Ðo\\\”J%BèàÁƒ...ã!C†¸ºº‚ö„„„°rƒƒƒÁ<&ÆøÐ¡Cîîî"‘hß¾}¥ªÝÜÜ@s‚Dººº"„¼¼¼XaΜ9iiiÉÉÉ—/_ŽˆˆP«ÕÖ¥êêêZ¡BÚ€)ª4P(ï©TJQ©Tjµša˜äää   BÈ™3g0Æaaa Ã0 SXXøÇäçç³ã r*•J£Ñ „RSSí­@øùùÏììì: „233á¯f³†pF³jÕ*“ÉÔ¢E vöìååU¹re›––Ö½{wçææ.:îüùóyyy!!!LJ¥~Ç&(ïÞ½›———œœœ’’âééÉãñŽ?Þ¦M•J¥R©X¹&“©V­Z åúõëp-4!$<<\©T †¾}û–ú0APPPbbâÝ»w_¼xQ®\90´­P(zõê…1Žuuu ¨S§XÊææ¥Q£Fþþþ°¬¬,0B›1…òaA·'($°ÞµkW777˜¯÷ë×2{öì½{÷†‡‡ƒ9(vG@­Vs¯vŽŒŒìÝ»·@ `fèС•*U²)%///##di4˜XÛ\“åƒëA¡P¼|ù²4hÁ`àñxüñÇš5kBJ¥2//|þúë¯ö²óâÅ‹“'OV­ZµfÍš!¡Ph}?c~~þãÇA‡P*•ì.‰Á`(((€a¾ÔV6¶lÙ²xñbBˆF£ÉÉÉ …?-]º4<<¼S§NÓ¦M³·×³nݺuëÖA6U*•½Â¤P(Ti PÞ0°ûPPPPXXÈãñ–,Yžò3fÌÅ‹92vìX{ƒß”)Sòóóa»aÞ¼y5kÖ´©7X[m()çL&Û¾};líGEE¹»»ƒ½^/‹ !cÇŽµ7èΛ7ïÕ«W&L¨P¡‚ƒÓ6ÍOpãy+„Ÿ~ú‰uÑëõ¬B3sæÌ–-[öéÓDZÚA¿ê¤P¨Ò@¡üÔªUëæÍ›F­V/Y²dРAF£qÈ!¹¹¹|>ÿàÁƒ'NœèÔ©BèâÅ‹÷îÝãóù>>>-[¶Ä׬Ysß¾}jµö)왊¶˜ÇÃMï 6¹ …Âd2F†aàêåúõ볞]]]ëÔ©³{÷nØŒ¨U«B¨Aƒ7nÜÐjµ„êÕ«{xxp¥8ïÙ­îiGøøx8Šèââ§ wfo§¾~ýº››[DDÄ¡C‡D"Qéô†‹/B\]]ûõë÷àÁ„бcÇ´Zm­ZµRSS ´iÓ&£ÑxíÚ5—›7oªÕêÖ­[÷ë×oĈ Û †:uêÐ6L¡P¥ByB®]»¶f͉D"•JŸ>}êíí­Óé&MšÄçó !‹-Ú¼y3x~ðàA¥J•!‹D¢)S¦ „âââ ¬»»{¿~ýŒFcÕªU»víJ9pàB>R˜>}z—.]V¯^-•JE"ÑìÙ³ !W®\° Ãx{{ „f̘!8õ&6 '€&Mš¨T*¹µZíÕ«WBÜ ooïBqÍš5kÇŽOŸ>ŠŠ*ÆÜ¿Ä=xðÖ-233þùgBˆD"=z´^¯7IIIB¡pÅŠÿüó!¤uëÖ{÷îݸq#¨;B¡pþüùôë åƒË‚äÃL÷Î’íøbmÊó„üü\ë×87×{¢Q£FãäääfÍšÕ­[—–å½Õ'`!ýÁâ»Dg¾®´ˆÇ±O›r-¼Ùœ>aPlœll6ÓÌu´™…B 'Iƒu~Ž3A¡PÞ qqquëÖ•ËåðS¯×;v¬^½zÖG¡M&S… y<¥u$Ïž½hÓ"tÚ£E wbúí¦+ ”2§sù­‡%‹ÿâqìóÍÊu¿ö§Mw®ãëkpßb §Ôy§P(ï ôP…BA!>ŸÏŦP(e€·qS{iVôzý¥K—èDB)cÔ«WïòåË´(”²X,~/”>Ÿ_¾|yZJYÂ`0¤¦¦V¯^Ú‘¢PÊ·ÿgJƒ@ ¦õA¡”%òóóãââºtéB‹‚B)ÄÅŽñ8é™ÊÇ;æÎ§ßÍÜúõíe¿Õ4¿Îç ¥ÎšÍêxOÉ›¤’J/Ö¿½L9“Y' ä¥ù5ëëGøQA•ÊG¡(¼zõê—_~Y¾|9|äöíÛ—-[vóæMÖÂä[í)0Æ[¶lyc¼nݺ%K–<|ø°Dñ¼½L±ßRîØ±ÃùoG¹eríÚµùóç¿Wg¤0Æì•:nÖ¬Y …â« ãK—.±¿ì ö!ƒÁpêÔ)n¶×x6lØ`ó«]0™æ81lX›"XoÇgïsPõEEEqqqŽÓ þïÿsFîáÇ4!6lNNN|||±/÷U¥ªU(ã¡C‡vëÖ­U«VcÆŒ£PÛ¶móòòêØ±ãþýûÁÆ.#y{)3fÌëäâ—_~©[·nhhèâÅ‹ÁÚ…óaúé§¢¢¢·Q¶U«VEMž<!´téÒŒŒ {žÁÒ‡E ¾‡{"#GŽ„@ðÍ7ßÈd²wÙ\ëÕ«‡Ú·o_~~~zzzTT”ÍoV÷íÛwïÞ=N÷¿ÿý!T½zu—‹;vÔ¨Q6# w˜°°0„„mÛ¶­½‡ƒ‚‚Bk×®5·nÝŠ‰‰±é-"""777''çСC!{oœÉdÈÕëõ•Á`p\‰P#¯^½ÊÈÈ`-wXibb¢¯¯¯X,Öh4mÛ¶‹$ÖÞúöí;dÈÂÂB±X\£F 0Tf3Î}ûö}ÿý÷֓襤¤øúú:¨ßÑ£Gÿù矡;vDFFÚ›ñ?{ö¬nݺ‰D¡PLš4éÛo¿µémÚ´iŸþ¹^¯‰DåÊ•»}û¶ÍAÇŽ/\¸ V®\ùÛo¿Ù“›ššÚ¼ys±Xœ™™¹nݺ6mÚØô¶téÒÊ•+›Íf‘Häîî~á›ÊåòÀÀÀÛ·o‹D¢Y³f]¾|™®4XV -J†Ý§‡N_(îß¿ -J$0´8þ|VçÎk6›úé'…B±eË{)*T¨0sæL0´-‘H-Z¤Ñh-Z&$†©T©Ò¬Y³BóæÍÓš0]k×®»š:vìXN·fÍšÂÂÂ%K–ÀŠ.!D.—ÜÉfFD"‘››BhË–- CDFFBX†a‚‚‚¦OŸÞ¤I“~ýú) XPéÓ§Ï_|1sæÌ»wïFFFòùüÁƒ7kÖìu ÓÂQ €ñ° 6 0À^ð$&&>{ölîܹ|>Ìj4š lÚ´‰íš Ô²eËŠ+¦§§W©ReÖ¬Y¸pá{…Ô·ß~Û¶mÛÙ³gçææ‚õBÈêÕ«%‰µÜ:Èd2Ng2™zõêÕªU«Ù³gçååAX©TºlÙ²ÌÌÌåË—ƒuoooÖ&êœ9s.\¸pøðaöÜ*Uª€®péÒ¥¤¤¤qãÆýý÷ß+V¬¨_¿¾OVVV5àÆqkfÍšåçç—““Cqqq‰ŒŒ´wéСCcbbòòòf̘á R&Mš4oÞ¼k×®N`ï`Jjjjß¾}-D¬_¿þÙ³g‘‘‘6lp¶~ýú‘‘‘¡ääd›ª¶[·nûöí›?þøñã¤yæÌ™‹-JJJ‚å{r›5ke6›_½zåïïï@n«V­¶oß¾páÂáÇ;ðöóÏ?GDD¤¥¥Áª˜=¹m۶ݼy³N§3^^^Ti°D$Ÿ¨ÿeÑËUÕ+Wce^Þ3…â¹Å¿””GQQQW®\¹zõê–-[îÝ»G(”„Áƒ{xxÀÀ:ŠÅb‰DâææÌõ,‰ŠP(ÂÐB>|xffæ­[·¢¢¢X Èl6sC}ÿý÷„ww÷;wòx¼¬¬¬¢¢"Bȹsç6nÜÈz{òä‰=¹<O$ÉåòæÍ›ƒËÉ“'·oßn!·fÍš™™™à’––“TBÈ?üPXXÏ ÃXÇŸ——ƒ·ÂÃÃÝ9 >œ+ØÞ:thZZÚÇy<ëÍÅÅ…¡mÛ¶ÖiðôôdŸoܸ±jÕ*BHíÚµÙLÁÅ·l@0ƒÎ­Ð‚‚“ÉtóæM¡PÈÊ…„ÕªU‹qûöí¬¬¬ü‘M3ЫW/µZ}üøñ]»v‹V«}9þü¤¤$ÖÅŠááüùóPw111ÑÑÑ Ã@î a!!!lJ\]]ýõWBÈÍ›7Áz8!¤qãÆ Ã=z옄5jäçç?>++ëèÑ£P !ֈؽ{÷Þ½{5Mß¾}5¿¿?!ä“O>a½Éd²Ý»w[´`ûöí§N‚çråÊÁCÍš5Ù°R©ôСC„Ï?ÿœ [·n]BÈæÍ›]\\XŸ 6„ Óé ömÛ: ii^²dÉÉ“'_¾|9cÆŒÜÜ\ˆÐßߟõ&‹O:e4Û·o*)!$((*ÑÍÍõÙªU+¨J†a¾üòKBÈÊ•+Ïœ9*ë Ž1M™2%..îîÝ»+V¬ÈÈÈhÖ¬„e½ …Â7nöìÙL²B|}}?èÞïêÕ«ì[OÑétÑÑÑ)))­HJJÊÍͳýŠçÿüsA.q]”ººç_ƒxr]i ”ñ•†­[·nݺõ‹/¾€•FŒ1Ã0:nåÊ•aaaÐÙ<fo"ÂçóÁ&LåacìØ±óæÍƒ°!­Vëïï+ãÞ½{ÃNÄãÇ322রäô×_ùøøÀ_>|h/#f³yܸqË–-“J¥¬tëiÃ0¬ý-XSáÆÀMv) sÇŽÖâ`ǧJ•*!ÖH˜Åå’®£ƒ†Á†kD»\¹rPDÀĉ¡„a‘Ãd2M™2å§Ÿ~jÒ¤ ×È'+ˆM?[ …‚)F#Çc ,oqe83×d†að*س®DØ „ܺu !j±aÄ0LJJ Bt©ÐÐPv°·ˆ­ÿþ!•Jåãã#•JÓÒÒ†ILLtf‰ÈÕÕµW¯^ñ¼¼¼ $$$X7?° ‡ªV­BfŒC‡:t¨EšaË©|ùò à 4ˆ»  NRSSÝÝݽ½½ïÝ»Ç0 ìCYpòäI„œ˜yúô)!dêÔ©pàÀºùA©Bð–Ë0 ,–$%%¹ººúúúÆÅűa-€ÃpD###ƒI±€ži ”eØ·Öðá' :N©T¢ÿk†Œñ°aÃìõ:.66þ C…N§[·n]nnnnnn^^Þ³gÏ “-((ÇnݺAÌr¹¼OŸ>k×® ¿zõ*ÆøÑ£GáááàÍh4B×l/#ƒ3ÂO£ÑhoÅ•J³®7:8ßîLaþŸ„ǃ>úúõëWV`7òׯ_om,ƒ÷ØæÓ§Os9ÀîÏôéÓM&SnnnAAÁ;w $ö&ØŸb±8''ꫨ¨H"‘°… E?¨/‰LþÀOh6!©TÊ=ë@Q©TN ƒqˆ-Ò¹sçV¨PÁžÖÅÕÕuÍš5Pt\M˱þ׳gO…Bg}||lVÛÎ?~ ÙwÜ 6nÜèàB6l¥J•f̘Qlš†yøð¡3r8àLó«[·.,59–K¹{÷n‰ìÉQ¥B)SXŸþ3 ÐqÑh40‡e›ˆÅâ””¡P( +V¬èëëûÙgŸÝ¾}¶<0Æ0Ÿ~õê•@ —ùóçæT*k×®½pá•+W®[·.??¿FË–-“H$àÓæÔ‡E¯×sÓܹsçdzaA÷H !„¤cbb*V¬Èãñ†a7ì߬rVl÷Êãñ Äãñ¼¼¼à4~NNÆX¡PˆD¢+VÀ:œ¹{÷.ðÙ³g|>rÊ®£ 2c,‘HAÓ¦M===m …™2eJ£Fعrå „åóùÛ·oG}ýõׇ‚’¬S§h0Ÿ1cFPPPµjÕ`˜9yò$„6mÚ±cÇŒF£Ùl6™L|>?66Öz•Åb„Ü•NE+hÒR©ë¥&ÐuŠÕcŠÕHÞ`šK!×yéÅú,i„×LŒšÆ¦”yœ´ œ»àH"‘èt:n›ý wk€ëÿ³‚JjzÛ‹cÓØ[¥3ýF*Â^ùp=pÓl½[á8¬ãª·W’Ö•è¤\›õîØç;^ñvÜrœI0党ƦPÞÌ<ØÁçìÅÆfñ¥œ½ Ö]0wÚäØŒµ“i+‘ilnzþ«)W®Í!Ê" ö&šŽÃ;etÒN·“rK19~Çåï8¿NÎæ)”ÿ×`hP(%¢D·*Q(JY¢4+ Ã(•Jëý` å#Áúˆ~@­VËd2•Jå`KžB¡|@¼5­Ò( F£ñÆô…R–àñxÕ«W¿~ý:}µ)”²{šá?VÄb1{‡ …B)3ö $}µ)”²ñR¿ ÓØ‚×I­ÊŽã‹˜(ÜR¢¯6…ByMèAÈ’áø$Ç»9çñ:ÁÒ™œ·™¯b I¿ƒÒ€±ÐÂÞ2Qf3ûî¥;#¬\¾½JhK9›ø·”0çÍsý8ðÿúõëdY•T=ÛÙ%Íû›æ×‘[ºÎB•†·\^<\Â5ÀúòåKpd?[b¦t—î99œ4iÒÓ§OKvĈ¬EDÇ>áÎ>ooo{_¸9¶Ë–Õ‹/JšNîEŽ5??¿›7or{ü/`ïñ5 77·–-[¾ËiúÉ“'·nÝêŒDBÈâÅ‹¡‰¾ñS§ÓÁ}M<Ïh4:q-ÎbŒ—.]Ê}wÞøËR£F gŠcüÝwßñx¼ÐÐP›þŸ?>~üø×¬_½^ïÇ3 öÊJ§ÓaŒGŽ 7CÛëL xNNÎwß}góÆŽ€€{ 6™L ÃäææþðÃco7Íö,s²i†[±†±wœì¶<}útÒ¤Ic¦> ƒórCBBà^5{r¡eþóÏ?K–,q —B•†7 ¿KXYÇ*Uª€#û~Þ¹s'**ÊVëä´ÀúÂyÀâòZdçjz›Yü_ƒ#äŽ5 Œ÷Ø‹ÓñƬùA°ÅàLÖX¸½®Ø^þÉ“':t@Vw0°fxÈåN_JTGÖŽà®T*/]ºÑ:ÖÉ9“=¹<{_“ƒfå3|øðãÇ¿qµ¦gÏž= “C† Q(öò -2× ;žM:Y 6ÃZ´R•6–¸×Q[x8g¬ÇA]÷ìÙS©TB­õéÓÇž·1cÆìß¿ßÃÃÃËËkΜ9ÿý·=¥ù¯¿þ0`˜ƒâ¾ñññ½zõ²wK&BèÌ™3³fÍòôôtwwÿý÷ßíÙ‡D­5ž¿ûîÇaV IDAT;{ÞxìØ1¹\.•J§N +¬9|øð¼yó¼¼¼<==wïÞmÏ&Ã0`–S äçç÷èÑÞܾ}ûž;w,ÖN˜0áÞ½{6½íÙ³gñâÅ>>>^^^›7o†…7Ji V.K|#„p  Bàþö† úúúzyyÂûf“ 6˜L&ooïÀÀ@Bèà`é.00ޤBŽ9âççÞ²²²ÀpË“'OX;-Z´€6,kÛК‘#GB<<<Á^Ÿ…Ü©S§rýËd2®Y† º»»[Ø´ÆÛÛnß¾ Ÿ|ò ˆ¨\¹2kèïÖ­[»Å‹B²²²|||0ÆU«Võôô,((p bùòå·nݲ°ÙÈVÇ­[·à¡Zµj ·Fà;v¬\¹ò† ìÅ?yòäÀÀÀ™3g2Œ.2 £P( r+W®¼cÇð9kÖ¬*Uª 2„ Û·o_¶Tëׯo϶d||üÕ«WƒƒƒÙR…ê€2 lܸ1„}ùò%´–€€€?ÿü“rêÔ©mÛ¶±Qñ-°7aCBBX¹ð¥J•ìeÖ+—Ö@´K–,A5mÚfÏ62dH`` D" ªS§8æææzzzV¯^õöðáÃJ•*ùùùeff …B¶@ S 4ËOZ­*" ì1Ú ™BƒoÚ´)„-,,„°þþþGåúgß&Ȧ§§§Ùlž0a‚M'Nœ¸xñ"T7T¢…Sn„#FŒ@uëÖÍf{`½]¸pÇãùøø€m›žûí·õë×ëõúÞ½{³Žf³Y¡PÀkÎÎglŠÈËË+_¾<Çs—6E€c¯^½Bƒ rìíÏ?ÿÄûûûs-+Z{ËÊÊòòòâóùW®\±!d¤K—.!èÍÈÝ·oB(((H¥R9›žž.—ËôHöä–%Þ†•Kª4”¥RÙ¸qc…BFan4¥R©Á`€® â;wÖ­[çÀ 1!dÅŠˆc©V.—[Ø®ý믿8`LúN:õùóç …bܸqÜù%ë-&&æøñã6傊Íþ„Q„ë²uëVÖf.Wi „ôéÓG­V³ nݺµ½·]§ÓyyyéõzFŽÝºuƒB€½ÊtðàÁà²dÉV½€ž·XV­ZuíÚ5ö§Éd2 R©Ôh4jµZpüâ‹/¸AÀœ.ÜÿÿüùsBÈ„ À†ž50~ìÙ³çÌ™3„Î;[x>|xFF[GìB!¤}ûö¬Ih½^ߣG›"nܸÁ-|xf‡hu °õí·ß*•ÊS§NíØ±#77wÿþýl$¬áf&MšÄ X­Zµ×QŠŠŠ¸†£”J%!äñãÇÓ¦Mó÷÷7 #FŒ€ŠsP,Üb±~/¸†ªoܸvÆA“€|q-˜ëtº^½zBÀÖ(0tèЂ‚ƒÁ`-·E‹lü0òq[u×®]¹ƒ «4°ö¾Ùª™?>!„+";;2Ò¾}{V[…4çççsS/Bllìï¿ÿÎãñ’’’Ö¯_Ï0Œ^¯çF˜——ÇÜ7ožÑhƒ×„ììl®\n¥p•“ÉÄ*å¬Ò`3,4³)S¦Á» &¬€œœN¦MoÞ¼‰:qâÄáÇ¡ßã¦Y¡P€ã§Ÿ~úÃ?°o7Ã0\¹ ýBÊ—/¯Ñh"""|||Xõ…ë l¬¬\¹òÉ“'B¡p÷îÝçÏŸ'„¨Õjn‘ÂŒ¢¨¨¨M›6ðnÂËÎ0 7y¬\¹\ž™™¹sçN®­vª4PÓØo‘aƽ|ùròäÉM›69r$B(..nß¾}ƒaÈ!+W®„)2BH«Õ²{·öVƒ ÓÓÓÙM „D"Yºt)ìÄÇLJ‡‡cŒŸ>}ºuëV@ ‹ÁôŸX,^±bÃ0ýû÷_³f Ü?mÚ´yóæAŸÕ¤I“N:Ù”›ŸŸ¯V«Ù«æ­7Ìf³=ƒF‰D£ÑÈd2†a ëׯoÓ›F£1b„Z­=zt×®]¿ùæ«ÕjÝÜÜ,6 ¶nÝÊ~a±Ø^Ròóó'Mšd0FŽÙ·oß6mÚ€\6G á!„ÔjõàÁƒÁšsëÖ­-Vw­ Äh4j4XGM›6M*•òx¼Ë—/ö«u]çåå©T*(gnXë ck{ÓÞÞÞ .„l¥R fÍfóO?ý6–âããB|>ÿ·ß~‹‡É7#·xzz®X±â ~Z²{÷n?€æÍ›6lÙ²e›6mŠŠŠ …;vT(z½~âĉl›Íæ]»vÁ» áàì*¼;\c‰ÞÞÞ ,€íjF1bä”a˜3f¸»»?yòäçŸfòx¼­[·ÂH ¡Õjá¯ÜêàóùöÊG&“±«åóçÏG=šuW«Õû÷ïçóù………¤Lž<!´bÅ Öâ3Ã0ßÿ}çÎÏž=»téR†aêÔ©Ö­îÝ»·råJvÅÅÅeíÚµãÇÏÈÈ2dHfffrròÑ£G¿þúëÑ£GC/R©T`ÁÙæþãÆçÌ™#‹óòòîÝ»÷É'ŸŒ5 ðÙ°§NºqãFNNNjjêÓ§OG޹aÆùó粇FݬY³ÌÌÌððp„PÇŽç̙ӭ[·«W¯îرƒí%*T¨°téÒ±cÇ&$$´oß^«Õ9räêÕ«!!!\¹jµú·ß~‹‰‰yþüyzzúË—/srr&L˜°zõêY³f±‡* ÃŒ3êÔ©# «V­j4û÷ï?eÊ”V­Z>}:::ší%çÎ;~üø³gÏ6jÔ!´~ýúÄÄÄàààQ£F±e¥Ñh<¸sçÎÂÂÂ7n<þ\¥RÍœ9–Ç(%…* ÎBÙ¿HHȶmÛØn®M›6mÚ´Ù·oô‰Žì9³÷i6›øáxo¿ÿþûÊ•+›Íæ©S§.[¶Ìh4z{{¯Y³¿ï¿ÿ¾]»vMš4iÖ¬ôJË–-KLL„m×sçÎ]¼xñË/¿´yàmvuuݳgOllìæÍ›‘ßûÙûk±¦tt:L Ÿ]»vEGG;#:)X)Qîj×®}òäI•J% Ÿ8¿n0úöíËêp8£Q£Fýõ—Z­–H$°>Á0LÇŽ—-[¦T*QMœ81)) äæææ.Y²dæÌ™la²CBé^0Miá¸iÓ&üBÝ»w÷û 8¯Í †>}ú°ça;oíÚµÐàù|þ/¿ü²fÍšjÕªÁJµ3­«Ù‡‡ƒ:¨nØ5#„,\¸Ð:†¥K—"„RRRB'N„jݳg…78µdÉ///@ðõ×_Ãf„3¥÷ôéShÛR©tݺu5kÖ„ãaÛ·ot)°I·zõjë4Ϙ1ƒMó‚ !_}õÕW_}eá ^º;wŠÅbØHBYËýöÛoáØÜ¹sB«W¯†½Z›;X¹P¤]»víÚµ«E„Ð!9r!T¯^=p·.+Ð{êׯ[“K–,¡ßiS¥áíÍ‹=šËmmÖçuÅb±^¯þüùåË—…BaïÞ½­#”ËåÙÙÙp}o@@B¨R¥J‰F ©Têââç¥R©@ عsgvv6úÉ*h4š …Âüü|WWW//¯'OžÀ¨Àçóí,“Ëå®®®°¶,‰üýýA.l»À2 Ì‹ŠŠL&“ÉdÊÍÍõðð>>>ééé*•ÊÝÝ=88¸víÚŽ'èܲ*W®\jj*LÑx<žŸŸŸµŠÀöË•*UÊÍÍåñx5jÔ°g-º3oooXÑekÄBnÅŠŸ?³"(7V\±# øqqq‰)üÔëõR©Ôl6gddìÞ½;22Ö ƒN§ËÌ̬X±"Xh´ŽÊ±XŸGÅb±MMÎ8R'·Fc¿~ý`&¥W®\¹«W¯B¡?þêÕ«ááá ,X·nÆxôèÑÜm8Jfs{âàÁƒÛ¶m3™LjµúåË— ÜèÀÑñ*â¼yóz÷îÍNÖíÅcÝËÛK²Ú'vfAØy¹‚;SVöD[€ÅÖHFF;¿qFn±UãdÍ–¢T­Ã^¹r%!!Õ0JQÜ šA~~¾§§§ƒ¨Øk¤ßöäLI:™©Rì€ØófS„óÁßýµ¤Åæ—^–J‰‹‹«[·.«OëõúcÇŽ±‡Ð¹˜L¦ *òxJëHž={ѦEè´G‹îÄôÛMWJ¼ÙÿoÇb ßf«(uÛ~ãï…ãàï¸l‹ÍÈ’*J™‡* ÿÜåkÊGKÆ 6lø>¤„ÏçS£Ø åÍ+ ƒ!..Ž*°JY‚R§N{ùQ(”î¼…[J#Ƙý–B¡” L&“J¥‚s´4(”2€3F|Þ…Ò  ?΃J¦  àæÍ›ðù>…B)ÄÅŽñ8©Á*ÊÿOI-ÌR>¬šuŒƒK´( …* oq -((سgÏ›:V‘:tèàÁƒÌé¾¾ßÓr?ÙBÔdïáGAX“ÉÄ~5‡1†»u1ÆçÎcÿê ›þý÷ß—-[fqLllìöíÛB`ÚÀž\@¶€A®ÍøÍf3×¶‘ƒ~ì¸. Ãðù|±aŒM&SïÞ½-,Z±ay<\ûÏZ½qlXnší]wY€g(+H$œÍ/XÄ`åZ„o`æ Ì;±õËÍ/›fŒñ‰'¬›AŸ>}ØÂt_öc6k6óË6|öìY©•×Ö­[_¿~Ýâ &H6<³µÜ¯_¿¿ÿþ»V­ZlðË—/³þÂm› …®4|Düý÷ß:uÒëõ¡¡¡Ük›[·n- ÁX%P¾|ùaÆ…††vèÐaåÊ•¡3f$%%Á_YwvëéßÁòåË—„G}÷Ýw¡¡¡¡¡¡;v<{ö,D²víÚŽ;†††6,77×h4¶lÙ2++«K—.­[·v¼¶Ï`ã<€ˆ¤¤¤°°0Û¹sçË—/#„BCC£££ÃÃÃCCCGeoE½C‡0²Âø¦ ÌfsË–-!±cÇ*•J…B1vìØ]»vuèС]»v[·n…4tïÞ½nݺ¬$Œñ®]»ÚµkÚ¥K—ñãÇ«ÕêÇ?„BùÀÉ'êYôrUõÊÕF™—÷ÌÚœvJÊ£¨¨¨+W®\½zuË–-÷îÝ#BÀÀ!D&“q]àÿ=z¨ÕjÖs5ôz=<BæÎ›œœ .ì»›L&___‘H †€ !&LHMMeýøúúBø|þÓ§OÁeß¾}ýõ;¹t&;ÑÑÑÑÑÑìO•JåççÇç󃃃W­ZŽýû÷çZg¯U«+r·lÙ²‹/ÚŒ?333$$ž›7oþüùs kÖ¬¹}û6!dúôé;wîdÕ ¶Hccc÷îÝËú‡?³gϾÿþ“'O¦M›.½zõ***"„°f£øøxǵɼuëÖçÎ£ÑÆy<^NN8><##ãæÍ›‘‘‘6j3~BÈСCÁÔw%€Û„Ö¬YsãÆ Ö?·‘|ûí·J¥òÌ™3ãÆ³ëêêÊ•òðáCîÏjÕªÙkyyy›6mrÜHÂÂÂjÔ¨qýúõ³gÏž:ujÆŒà>zôhƒÁP»víÜÜ\®ÿêÕ«[ÄpæÌ™•+WÚ, …òf¹zõ*·ÇÖétÑÑÑ)))­HJJÊÍͳýŠçÿüsA.q]”ººç_ƒxrÝž(=-nz·8Y¡BöÒhîºB±7ÃóùüŒŒŒ:uê$''³þ…B!k7!13 ø㞄·™w¼S¤2¤×#“‘!d6#© !„Ô*‚1&„Èœÿ‘¨ ƒ´‚r’b³ …!¤×!“‰ „$N˜Ïÿ§~Z!¤*)ÆòŪûwoŸ;q ih[IœþɦÓ!³‰„˜0ˆaþÛ.m‚ÇCz=‰!H«!6BˆE»!© kµH*Et8:-A¹¹ãw Ÿ8aN‹†ÚZðµŒz¤×ÿS?w¼lY‰Fñ¡ÿ–¥=´/¼ ŒF£B¡°6Ø ‚R  ò[¤2RÛå÷c?÷n[¯CÃêgŽÀ_ùã̾q÷ï$´ªçÚªžkVæC¹¸â6õÝ;ùtòéߥ¥^§•9ãp_銹S;ùthXýÇïâB&£aâ ž4[k?·'Ry<Äç#¾@Èãñy|Ô(¨Ù”y‹1F§üÔ®AµÎA>zܳc|ú—Ÿíßs'ñjk?·Ö~n¹Ï»{à¶þ®ƒ|¾ÿvudÛÀa=ß5ô¶'Ñ ÙéŸvë»çåd¹{â¦Þ8ñêm<;ùŒŽêb4èùì%»w'!¢‰O[»7oÐIõQ×ö ¼—ÏÊçc„‡r²2[û¹Ò Çxßh4`Œ#Û5žúqTç ŸvžgŽÀéõÚÝÂi¶¶žtó^&“©yóæáV\¿~Ï._‘¥A£&7s”ŸŽ5åV7^‡LFÒùýîC?X¬×ioç•8I‘ÆJHQ¡*p IDATù^q1Õl2RU›V>åZ³É4dÌŒk6ˆÅ(ºS‡è'8´çã ³>ìrâ£ÅóV‡|¶xæ'O3>y”ú43-.þˆN‹Ä´~é§I¹…’8¡ž­[ö5dÀ‡­‚úÅLLÊU8IQÎbƼ›9Ï&µëØßYîûnÝðIs¬²÷Æé_¬ mÓ!äêŽ|ø©™¸ºyäå$dÉ ztýÒµÃ?n0<önºoÇöû~¿L¤Õ †A5ÙñËYyròY´6gôQÿ,†ÐCž9wêðÞÈ£‹ ó¿;|µfm™3 «[«WÿèÕ æ¬ß}²q°BHÄG«3v ÃÀ] ¼0Æf³YHüø|~)Ï ^¦mµ™MFJÅç»Ó“ 1fóÇ?+Ì'ã?R”Š"ä]ƒ_—y|>Bˆ1›cç|…ªV½fƒÆ~j%1°@(Bõ‹3~@×IC.ÐlDQŒ&|º4÷Ùã»7ÆÎýŠ=;!–HÔJ¤Õ “ …"„ш!1ãcåÿ´[¢@c•ñø|­F­×é„"±ÍE"ƒA¯Q#„dή!£ÑÐoØà¢B‚16ôB¡ˆÖÆ0f ±¢c¬Ó"ZÅvAB‘XY‚h…FƒŽÎÿ ¯ê5"‰%N„Aó¾ÚÙ¶QÖ“t:Þt )ȃ  òò²q“É(‰Db”þà.ó¯,%Qá'•9ËœQCásBªLt¦•›h4*®æÁþü<'7.þ÷‡*ÓC•©ˆFnØÍ9IeNR™@(’:;s ,"1ŠHŒ³ÙB•¡íR—Û!“ÉèXbÌf>_ ýS!ÝÅàñ·ÿNq’b¡ñùÚ FÈh0EH"AÉI×1F„ E"Ÿ'#BÂÈhЋňVÈãóÿí¡e2RÓýõ€Ž7)vv¨¼^¦0àQS>Ÿ;±¿Á o;gÆH¥Tpóè´è›½§?l×™/šŒÆ6ß3 #¥¢˜ÆÖÆ©U%!³ÙüÅÔ¡ÅE!£A¿zÛ/j5m…ÑiÕl…Fê?|òù!c6u|/’0c¤*)þÿ–¤,)&E›äìâj6› zÍQtþ ïú¥ŸmúœVo=¬Ó"Æ7¯_\õùd¾Pèî^mêçÿ¡öŒÙË6í×Ýl6‡¶‰hÚJâ„N—ùð^zjrjrÒÞ“—´ôŸíGúuŠ † ÏjÕ§Î_R©JþUkRQ„12™ŒSb¢´Z5BÈd4ÆÅŸyÅŸ¡ÀK¥õ]Çߟ]í¹ôûq©™IEEÖò‚ãéÓ§BCC1Æ)))¡amŒžA˜üóí€ÙlFˆðx<ŒytáÎ㜧ø7éËOáñxf³™=vÁ˜Í˜ÇÃ3f3¡+r‚ø-K¡EØ B cf+DÿîÓXœãà¦XTbѽÿ¶‹Ÿ/pvE-}œž©E&„F˜÷ï~;n»ˆSÖb¼´¬Å´°³YnJà%!ᜫš¹ººÒ½^ðàÁ¾}ûJ$‹ÌÛ·oŽîOH±u==îܾ笴¥II· ÝóR–*á,D5ïÿÿúoƒRl›e1Æ\Qj]á¿B—ï Å¢‹Ú,ÛEH¯Óbl£ÛÖMó_4^롱El–€Ê |äg­ß}J£†™Pb6¡Öïvÿw‡P¥P¥€ÊJ9?¹43Ö¨ºŒ±Hˆôz‚àÓ_ø_ð^§H€BêÁ倷 \,/Ü÷ÓO&N‚¹°§W™MÆfâ áRç[/𠹚S5ª Â|æÁz½áÁƒÕªUs'77·^½zwî¦T«VzCË1œ ¶ …ÂÃãN:0±@Õ”¨Ê’ža¨sô7胜Û4ëúÝAghŸÙžW!¼¼¼ …D"±Ž‡1Öjµ®®®z½!äêêZ·n]ö¯f³Y­V³Þ|BOŸ>Õh4pU0Ž@U~€y¼š5kÆÄļ Ë%K–>|˜«%|ùå—ÕªU 4 T-˜0a‚··wõêÕ%Irr2·¸J¥ÂW9âêêêïï`…¿¿ÿíÛ·Í[»vmÛ¶mu:㈻J¯J~S ”››»wï^jú¶)“¬Ë'º¨~0räȤ¤$6à Æ8666""¢°°099yêÔ© …âÖ­[ÞÞÞùùùyyy:.88˜Íœœœ¼zõj‘HTçÜl6ûøøôíÛ×úOƒ ¢f BhÖ¬Y)))W¯^…ø2( ¼!//c,‹y<ÞîÝ»é6ù!CÄbñàÁƒéÂcÜ¡C±X,‹E"‘««ëâÅ‹1ÆOŸ>¥e1Æ(ŸèÂðÁ«W¯4hÑøßƒ~[¶léܹ3U)œœœJJJš7o>oÞ<ú×þýûçææ²šÊäÉ“—,Yb2Ua'í_~ù¥uâ’%Kì©k¬ÎÔ¥K—rklJeØ5jÔ „èõz†aîܹ£Ñh!?üðƒ^¯ÏÌÌd¥Ô¥K—ôz½^¯ÏÎÎ [°`B¨qãÆ´,!dûöíÖ âR*.'OžôòòâèCœh´l ŸÏ§¦ˆ-[¶ >¼FÔ"Ò¤I“?þøƒÍ\EÅgpppLL 7¥Y³fݺu³yÕ>|˜“óß#ì›6m¢g>à–ª(pª_ýõ|  M&ÓâÅ‹¥R©…ØæþpæÌ™‹/ž;wŽ4Mß¾}M&Ç;}út¹—Ò«ã:´W¯^ô×=z„††öîÝ[$™ÍæmÛ¶;¶Š*p#GŽüùçŸé„Ј#¸‡¹lÛ¶M.—³¿®\¹òã?–Édp? 4𪠄LŸ>}„ !¡P8dÈ;vØ”=„F³sçÎ~øýŠÁÛÛûСC:Žæ©Ø#t«‚m‹=ú°aÃj¡é f³!$‘Hø|~Õ(]ºtáóù쯟|ò‰Ílùùù«V­â¦<~üxÿþý#FŒ€[¥€W¸º _±b…N§ãóù...ôCbbbnnîóçÏ?Þ³gO„ÐÝ»w›5k–˜˜xìØ1„PÆ 6lزeË3gÎÐí‰r»HHHÈÉɹqã=ZQ§N-ZB† #—˃‚‚|}}“’’´ZmBB{<³wïÞB¡P(üÇ„ÅGUäùóçÔºðÛo¿Ù˳qãF›‰ü1ÜÒ@Î4@Õ°4üõ×_Ïž=S*•r¹|Á‚NNN!­V«P(V¯^ŸŸOsfgg>|øÞ½{J¥²¤¤„_8zôhvv6Máža,+Z­V©T¶jÕªyóæJ¥R«ÕÒôeË–¹¸¸Œ;–ЧO…B¡T*i£õ9r¤ª_—aÆ5nܸ{÷îÖgx<žR©´ydòÆGeõ'KoiÀ>Ü"½}ûöíÛ·ç¦ôèÑú¸P(´.[:tè`3½~ýúõë×g»êââ2xð`õDFFVõËAY¹reqq1²sÚ#''gÓ¦M6ÝQäääTQ7J@©(((`+Ôœ ‰RSSÙ”ìììF!„ ÝÝÝ?üðC{U¥¥¥y{{Ô 4P%áóùô "`±X\¯^=½^ïà+’ÀÀÀêÕ«óx¼€€­Vë g@@€——Ì*ðJy÷–GiÐëõþù'¸6€·ŒfÍš]¼xæáeHKK«ðœP>XÏ­oXiàóù>>>àŸÞ&ôzý£Gš4i6¼V ¥A Àõ€·‰¢¢¢Ë—/÷êÕ ¦ÞتްÒo–7ºL=,_?ËTÖÂ¥Ò«žUš'í~Ú¡s‡!ŒøJþ'S>á ø•$6·½¿æää<{öŒ~³`0Z·n]î TÙn3½^óæMê°Ëh4Ëd²ª>4 ÒJP5D8Ø´fÍ‘H´téÒJþNÄïÞ½»|>|0Æ;vì5jT)3ñÅ 66lØë¹Ði§M)œrí£k W⣈äˆë\ÿ¹ÝÏXúº/‡B¡X´h‘‡‡Ç_|á¸ÏYYY&“)$$„ºqÌÍÍÍÈÈpqq©^½zUî T*U“&MÜÜÜB*•ª°°0==½Y³f¯ôyµ¨ÒÀ·Â@È_~ùåÂ… ¯º•ÁƒOž<ùã?މ‰©ü¯ª¯¿þºÜeW¯^]úÌÆ £á_Ã…¾}ñv;ïv§ÛœV8)!-ºpaËý“r&#y͇!¤Ré§Ÿ~j3¼$W°=|ø°zõê~~~Tc „Ô¬YÓßßÿþýû ÃTÝc…BÁãñüüüÜÜÜh¨tggg___OOÏ{÷î½Ògc X Ì¤§§gdd¸»»×©S‡®ÞÌfsQQ‘——WZZ!äwÞ¡o™G±~…4h€ÊÌ̬Y³fVVÆØÝݽZµj¡âââ‚‚Œ±Ùlnذ!»š‘ËåõêÕ#„°•SSS©$ððððôô4J¥ÒÓÓ“~:ß°aC„P~~~II‰³³3BH­VûûûÛ[Éåò¢¢"BˆOvvv@@À³gÏ|||4Mvv6Ç£e†ÉÈÈàñx„ooo777½^o6›Ÿ?Î0 í3BˆvŒöÇãÕ¯_ß^»´‡!›eù|¾ŸŸ ééé´Ýš5kÒåææòù|Ö½à?Æ€´4j‡tƸ}®U«Vù&e?Ë>wë\APb}@ÿ;š§Â§Wÿ¾Ú®m;ú«Á`0yyyì„ÐŽ¥§§³"Çßß!”‘‘áïïÿäɃÁ@'Ó`0}JËÖ«WO(–”” †ŒŒŒüüüââbú€ÓKIof©TZ«V-„V«}öìƘa???@€1~òä‰Ñh¤fffúùù¥§§äåå)•J™LV³fM„R©|þü9-ëïïÏçó‹‹‹ E"‘‹‹K~~þ;FP€ªÇ¶mÛ’““œœRSS⣣õzýÒ¥K ] †µk×"„vîÜÉlܸñˆ#êׯ?kÖ,úØëõú9sæH¥Ò/¿ü’¾ì0Æyyyß}÷-†Ú·oBè³Ï>cSôzýçŸÎãñ–,Y¢ÓéÜÝÝ !f³yõêÕƒ eð…„„ 8ÐzË–-£cl2™V¯^}öìYê™JèV­ZõíÛW§ÓÅÅÅÑ×½N§[ºtijjêСC###Ù÷×W_}%“É&MšÄ.;tèлwoëv³²²Ö®]K7¤1ÆÅÅÅ›6m’Éd±±±...´l§N>øàƒ3f°R«Õ®^½Z$={öîÝ»çÏŸ¿ví­aãÆTèR!Ô±cÇÞ½{Ïœ9“ýøJ«Õ®Y³F (ó³/"¢Í7#ëW4AÇÜŽ -Úý£4¿M&SLLL‹-fÏžmQ6%%åĉ&“)..N¡P¬[·!´gÏ•Je2™Äb±Éd9rd``àœ9sزZ­výúõ/^üõ×_éóˆ1®^½ú'Ÿ|²k×.­Vk6›E"‘Ñh?~|Æ ÓÓÓ÷îÝKoTN·nݺ¥K—–””xzzÒ ëÔ© oà×´¾ë'úeKŸ|ÝÀ7€a”……äòL‹©©iß|óÍåË—¯\¹²}ûö»wï „.a !{÷î=yò$7eÁ‚.\ )ô¥IÓYÂÂÂØ?Q–/_ž””ôäÉ“I“&±‰ÏŸ?'„Œ7޾g¹ù¹?þùç÷ïß'„Lš4éæÍ›Ü ݺu3›Íû÷ï?|ø°ÑhìÑ£‡Í$''ùå—ôç^½zéõzÖvM5Íûï¿oQjÊ”)999 óæÍ³èXxxx~~>MQ(C† ±ÙîÅ‹ãââØ_srr!M›6¥ Yz’côèÑ„Vÿ „DGG+•JvJÛ¶mËþ‰šC(f³Y¡PBh´IJŸ>}t:uO ·nÝêàZçeå5Kh†äÈÆ¿"ôSÂOlÎ;wî|úé§Òºuk6E­V÷ë×^ßÁƒÓÄaÃ†åææ^¿~}íÚµ„ÀÀ@¶¬ÙlfË †˜˜öWggg}ÎÏϧ3`“íÛ·³?;v,>>ÞâB°6BÈãǧOŸNñòòb{ôèa0:´ÿ~6‘ª;µjÕbS<<<è#pýúõ ÐÄððp†a,ž @À61yòägϞݺukÙ²e6½ØÚü¡ÕjÙ_颜BÍi6l8zô(›H5T‰D¦üõ×_[¶l¡ýäÎ'û³T*e{BGÁùèÑ£;wîdæÝwßeóûúúÒG•í6mŽ–e§zß¾}?ýô“ŴКg̘ñøñã{÷î-\¸B­h€®\¹Â½ÿu:]||<÷Æ`Ù¶m[QQ±µô—Ë3.¸Jœ—>]ýëHž«, ÀËnmr…7 ‘@Sè)3öáW*•-[¶¤fX‘HDͰÖÔ­[·eË–µk׿ñx*•êØ±cÕ«Wß²eË–-[Z¶l™À®mzï§’m—Md;iϘéääd6›i IdPÀÉÉéäÉ“¡?ÿü322ÒÙÙ™ž°›?>!„n¬pa†uùÇ0Œ½v¹étßæ÷ðð`éH­Çk³Nn6G#1>þÜ××—î ™L¦ò> „TSUCYDf‘”H¹9é¹<{c'„B{HÙ½{7BèÉ“'ôzqG'—Ë›6mJ- <ï£>*}·u:m£ÑÈîs!„zöì9mÚ´Y³fQÃøµk×jÖ¬iquØ}ŠÒ\‚ÐÐÐäädN'•Jé&µ´Ó+K¹~ý:5’EEEݾ}›š(¸;GTùppÓšL&›e†î•°=?zô¨§§§T*Õëõ«W¯1b+‰¹O“««+{ŸP¥Êâ ÚŒÅ´°6!ÖFj9éÏuëÖMKK£ÛMš4aÓÙ²ÔHùúë¯W®\)ANN;ìs ñ;Þ0é@ ×ë% ÆøÂ… \Wüìƒ1îÓ§OZZZVVVVVV÷îÝíÅZ”ËånnnÙÙÙYYYÅÅÅï¾û.û'êä˜} Y„W¶plñB¡»ì† ‘HÌfóÍ›7ÿúë¯7Òý›DDDgee=}ú”ZJA™Ž.Zˆ.VaŒ `/§B¡à–bñ¬£¿qçdçÎ!™LöäÉ:ù¹¹¹å ±èâå2;m6â!L,¥Ô0ŰÎ;çößÙÙY©T:V€¸ùsrrhÿ[µjeóRÚ<Òèêêš™™ió¯—/_gMJJ?~ Û l=Ÿ~ú)[D£ÑÐÄQ£FÙSkt:û3=/âãã“‘‘‘””töìÙÄÄD{žËM&Ó¡C‡rss³²²Ž?nñ¤s#€ 4UÑ£G/Z´ˆÏçïØ±ƒšèˆ›çüùónnnô$Ôš5k¸²}M0 ãééyëÖ-Œ1ÍùôéSî«™›???Ÿf£6 ú–§ÒÔB*B зo_ëJXjÕª¥ÑhÆ7iÒ$v-h3çãÇi» 42d=ë÷ù石££ï_‹†ì©,:uºxñ"ŸÏ§e©Œ§›Ù¬  eoß¾ÍNK×®]]\\0ƃ /^dm<ô )]ŸÕ«WoäÈ‘!š–ݳgOù®²“Ä©Çè^$‚g† „˜»ëÝçÌåö™»ˆ§$''óx<Ú1WW×S§NqGÇ]%Ó²<`óòòØþoÞ¼™î»Óó³*• cg-·!"‘¨U«VÛ·ogÿJ/«R©trr e¯r‹-æÏŸO»GP–ÌæÍ›oÞ¼ÙâêЫräÈñãÇO:µQ£FôªõÌŒ7náÂ…´à{ï½Gu)ÚĦM›|||Ø ±¶35lØðèÑ£\kM?xð`ÿþýÙ?¡víÚq'Šóï¾ûŽMd­qìxÙˆ¦‹/f³Q5‚B¦Ò/„ÙŃE'§OŸÎ–¥ñÐ{öì7~üøiÓ¦aŒù|>mÚâyTáóù»ví¢F;ú,ÒOf¬›^‡uYZßuüýÙÕžK¿ï—š™TTT`ýìOŸ>Š1NIIiÓ¦MPPÌ`a¢ä¾”mšL-Vÿf³™ÏçÓô:)záwá6Ûµ™ßfâ­[·Ž9Ba¬e˜öͺç$&&þþûïÔ²í ·¥é ;Š–µ/ÍcÑ[›·Ù¹\~ðàÁ±cǾðBç&æ~æöÙmÉmÖ}“ûM¦(³¸Iñ,þ,›™Ù9DV;ì¯6Gç ¬ƒ"öú×¹sgwww¡PxèÐ!???zB…{ß–f2©˜´¸¾6Ër€åçç/Y²dÆ 6Ÿ‹nsŸ‹ÒÜ<ñññÎÎÎôäArrrNNÎðáÃ_øYÁ† ÂÂÂÚµkǽ¥¹c­á–u<4„дiÓæÏŸÏzÈ ×·4emN|=ᘫW¯±Ûsz½þàÁƒ}ûöµŽI±}ûöèèþ„[WòèÑãÎí{ÎJ[š”tëÐÐ=p¦¨ÝÓjçÒ†QËJt±[ÔÜRŽ÷þ¼ lþ©ô‰ô‹¯nݺÑGkïÞ½lß^¸uj2™¸fX{½-Mgì̓uY{)½µÙùr¿gékÚ«™×&Å&>â#„H=’ç–7Ž?ÎúõÍíu7¸)ŽÇRÊ!8¾sFŽ™••¥R©!]ºtá~Êë`ÂíM¦ÅõµYö÷߈ˆ {...kÖ¬)åóÂ}.^xóB†zÿþ}j¢ðõõ}ï½÷J#Ju:wkÀâ1,Ó}Â-ûÂWÁ´iÓÆO{k4Ïž=[ʲ6'4†×( €BÎÎÎ6làž±*ý"&<<œû…Û[¯ çjÎlJ Š©ä >BˆL&kÔ¨QY×Ð/ÓbçÎ;vìÈU^E£´ÂÆ—UØsO'¼Î áïïàÀW=-@åR†)..v|B€ª…J¥rvvV(öΦPåTüJ¡4Æ„„Ð àm‚º¼äú;Êõšæý»¨&e,… aþ9\ Íß€Ò ‹»ví ×Þ&ärùÆSñ2(•¹&“^,v‘J=K_ª¨(“âææÃç‹`ŠâêÕ«¿º€iàßõ.˜_B×…Æ¿‰ä…¥J“ Þ8 4@•{èõ ›-¾d7Øâo÷)Œñܹsßúa 4PZ¸ _ÕãÊãÕªU c¼~ýú7"ù"##…B¡H$‰DB¡päÈ‘/iœÀ¯Zµ cüv»&„¬X±ÂÕÕ•, ( 𿎻»»Åš+J¹L§)ëQ6[LLLFF!äĉÔå€E6›íÚk¥(•J£Ñh0¨[î;w:¨œÛ´ƒ ™5kõ£åxN^8™•ÜÒÀ0LIIItttZZl 4Àÿ.÷îÝ£§”k×®-‹Íf3u Œ1>yò¤§§gÆ ©žÜÜ\©TZ³fM//¯øøxŒqbbâŸþY¯^½š5kŠD"Ö ¡‡‡GÍš5kÖ¬Ìzùuvv¦”wìØ!“É0Ʊ±±4-‹1nÓ¦ õèååE½¸bŒi*½Nœ8Q!B‹+ËÅbqÍš5«W¯¾qãFŒqjjê¦M›hÓãÇ7ãž={bŒÏž=ëáá@UPP ‘Hh|2V¾ÎŸ?ŸM¡‘²;æééÙ¸qcÄ|éT IDATvBªÒ«–Ç#„üüóÏ ,°p 4ÀÿMš4)))áóùÙÙÙz½žú«ùí·ß¨œ“Ëå)))QQQTxk4šÜÜÜ‚‚‚S§NšÍ戈ˆÇçææ j¨÷õõ-**ÊÍÍÍÍÍMLLŒ¥5U*Uvvvnn®Ç;uêTëÖ­i6Z!tíÚ5Œñýû÷ Μ9C¿†ÀÓ „õë×—ÛiµjÕ\\\hØ Ög"Ô›››——÷àÁƒÇëõúÂÂBZ$++‹šŽ?Ž1Þ·o_QQQzzú‡~ˆ1öòòÒétÜþ\»v­zõêƒ:{ö,Æø·ß~“Ëå·oßŽŽŽ®¢‹uÖk2<5@}zvv¶X,FàKüC£Ï™3!ôüùsº_·nEž;wîÌ›7O"‘Ô¨QãÊ•+NNNþþþ...lZäܹs ,T3øòË/éÚtРAÜÌmÛ¶ÍÏÏ?xð BH£ÑÜ»w¶kýAæòåËBwïÞEM˜0Ö\¦L™b°øÞ½{sçÎ¥ èÁƒÓ3Œ;w>xð Ùl^½zõŽ;Z´hÁŽŽ‹^¯ßºuë²eËvîÜùÞ{ïyyygggÓAiµÚfÍšqg¦êÞUºÿð_ XZßuüýÙÕžK¿ï—š™TTT`­OŸ>EOb§¤¤´iÓ&((æ,÷Ù¡¿–ÒÍÍÌn.¼°*-rÿd/ݹ\~ðàÁ±cÇ–r€²Y/¦ÙÄRn¬8˜ŸJ~””äšL:±ØE&«VúRry&BÄÕµ¶@ †G ¨(®^½ÄF ÐëõìÛ·/k¼dÙ¾}{ttBŠ­+yôèqçö=g¥-MJºuhè°4@)àÿ_ž±g!K_Ö^Çé/¬Äqåå`™²±‰Ž+±÷×—ïükƒÏ"Døü²½Z!l°+¨¼€Ò•v|Šýò”ÉÀÀâêZ¦¨p^ÅǽåQ ÃåË—á,¼eï—ààà+W®ÀTÀÛÁË|_]‘JÆØÝÝü“ÀÛ„Édzþüyݺu!¨ÒkQѳـ Jý.Åf³3Æ<@ o`à…h4šJ¡4…B8 oEEEýõW=`*^f³¡¤$cìî^¯,2 Ð`P …N2™7Ì!ðB®^½Záu¹(Ó‘T掽L÷¨¢Òýåã`½|ŸËÚÃÊu&Í06æÐ¥‡†O"ð¦¥J…Édºr劽£<.ÿL&S\\œ\./e~Œñþýû_éI#Œñµk×¾ÿþûï¿ÿ~óæÍìסƒaË–-{÷î-këãC‡U`Ÿ1ÆW¯^µîaB©T:Ôl6ÃîJTa Ê+ˆ«N:U¬üóõõ-Ó9¦¼êI˜7o^­Zµ|||š6mÚ¬Y3ÖwBãÆGUŽ £££+°{wîÜ9wîœOpppDDD•;¯íêêúí·ß†……Ñx§ðÜ• øä=ã‚Âçó©'„¨Õj*D"‘P(¤~/]º„R©T4h5BˆTB&“ÙôMd6›†a•µZ-“ÉB:®k×®ÜÈFF( „X,¦^õz½Éd"„8;;³9U*ëØ@*•Ò²ôZ³X,.Ÿ4ÅwïÞîb\»v-22òèÑ£B¡0""ÂÃÛ“vŒN—³³³u” :Lêd†þU¯×‹D"BˆV«E999i4ë²ÜA±B/DIII5ºwïNsþý÷ßUñÆóðð¸y󦻻{qq1<†( P5ÀŸ;wnãÆ!“ÉÔ¶m[*á”JåÀ©P¯^½eË–åååMŸ>a˜!C†žŸ3fÌhÕª•u+—.]úûï¿g̘A‹P‰2dÈÍ›7<ÎJÙÙ³g?|øÒ Aƒ¥K—Êåò 2 ÓªU+*Ë;öÝwßÑvE"ÑìÙ³›7oîááÁ†ŸîÑ£Ço¿ýFƒ ”‰D²víZŒ1ŸÏ¿{÷îÑ£GíyiŒ§±°Fãûï¿?qâijgÏnÚ´‰þ•ÇãMœ8±sçÎìT/_¾<==ý믿~ðàA¿~ýÂÂÂ:tèpîܹ޽{?Þb2gΜ.“ÉæÎ›ššJñ÷÷_¶lYûöíÛ·oO),,7nœZ­fÃkU­a˜çÏŸ9Ò:*€Ò•”yóæ]»vþüçŸ&$$ „\]]OžµX :T£ÑˆD"ª%DFF^¸pá…G;+­‰‹Çã%%%Á3T6àLØ×©ÿ ìD §ööÐÍR©týúõtùË}㳋i¡Pèô/Õ«WwÜVjj*w­‰¬BJJ$v‹f`£oBªW¯Næƒ0™LÜØT//„ÌfsXXXXXXÆ ÓÒÒ:wîlÏiôĉi¼J*Ô‘•Ÿ™€€„J¥ú믿rrriÈovà܉µ˜LooojGa+g»Áãñœœœ®\¹"ª¨:Œq­Zµ>|ÈŽ@i€*€J¥bßãóæÍ£2»qãÆtß]£Ñ4jÔˆÕØ ÕtÅ_³fM£Ñ¨ÕjµZíÌ™3é>½5&“ÉÕÕuÁ‚]ºta=±Ðp‰„žT°wÞh4R€~:A¥lII ›ÁÙÙ™Ö©Õj¯_¿>sæÌï¿ÿþeßìÚÇãÍž={„ \¹ÎæIHH¨[·®N§ÓjµüñMW*•ܪâããB2™lðàÁ±±±sçνqãW̳“ª^½:;™3fÌÐét6»—=yòd:Õ´ª*w–P«Õ>üÑ£GU":JÿåÚµkžžž|>üøñôÈ„„¡PèééÙ¬Y³–-[²b);;›ÏçóùüáÇ#„=zäæææéé)¬P(l6ñî»ïîß¿àÀkÖ¬ùàƒ=zD°L&›2eJXXØ;ï¼C…·ª ôèÑãèÑ£žžž2™L&“Q­%==]*•zzzzzz¶iÓ†žÉ8pàÀV®\)•JÛµk'‰Ê7!b±˜ÖÌçó'Nœ8pà@BˆB¡¹¹¹žžž+W®Ä‡„„ß±êÃçóÙñ@%00u3ÿÚ€ƒ@h»>äsPäåÝרüž°|}.wUp¹mÂýÖÑ:§ÍJJÿydÍš5»uëf/( Ò¦Mn¸¯ÿ÷Ö~ûí·-Z€¹¨ÒO¢½;üÕ®.`êßJâããÙø6ï6dßÏ`YÁ:tˆ:(}‘¶mÛVˆÆ@݇|öÙgeª cÇí3Æø“O>Á·jÕª i {)K9ç,öÚ¥Ž#ÝÝÝ1Æ{÷îeõnqÖõåïï_ú¥?Ã0...nvpuu•ËåR©Ô^™LF£|@ÕÅl6¿S( o•âÉý™b3 .̾ʭ¥ŽÍ{Ñfúß¾}m6砸ͭ86·r{ÕbŒW¬X±gÏ·:99ÙÞxm¦ÄÆÆrw !_ý5!$??ß^ÊôˆZOMáÜzÒ\5{—’U}ì]J›í–ïKIIi×®­³]»v¬·G 4ÍСC‹‹‹ !ééé‡BݹsçÝwߥeÛ¶m›––†Ú³g››!äÎ;'N4ð @e”†·ê4Ðßß?44444Ô××—J”#GŽ4kÖ,44ôwÞQ©Tã7¶lÙÒd2…‡‡±îqhÙE‹ÙsCôŸÿü‡ m@ÃÒ%£¿¿Ë–-ÙR …b÷îÝÑÑÑ¡¡¡ 4 ²cüî»ï†††úûûsåísHHÈúõë1ÆÔ@›øðìûœœh„‚1cÆøùùQûAHHÛ ¹úùçŸÏ;—Z!*•* € 'l9>bmôç=zØëIZZÚåË—¹££ãmÞ¼9Òˆˆ*ÚiˆÈ?ü°yóæG¥‰ , ÙüýýiʧŸ~²qãÆ#FtëÖúFÔjµï¼óNhhh³fÍNŸ>1¾yófÓ¦MB­Zµ `w|i…|ð­°G<¯S§NM›6½páB¹M)ãÇ¿rå üW®\™:uªÍléééô*/\¸zŒ9rä¥K—hÙ‹/~öÙg¡áÇO˜0"“ÉL&SQQ<ËP™3 o‹öÇãqÍÅã³gÏBúôéÓ§OšèááQTT4iÒ¤I“&ùøøÐ8Åìñª!´}ûösçÎuéÒÅæBÓ`00 C÷4l4Æ8##£E‹l6“ÉDƒîøùù!„è×ÿÑÑÑ¿ýöÝ„ …Ý»w§eÙ>¯X±"))ÉÛÛûÁƒ!ƒÁ ‰Îž=koÈÔ£€Ñh4 4 c‰e'rþüùÄÄă ‚+VtïÞýÌ™3ÎÎÎéééµk×v<«ÜPοÿþ»½l:®C‡ÔÏÛ.!äÖ­[4ƒZ­4hо}û8€1ÎÍÍ­Q£ÆÇÜ¡CÅ‹/^¼˜ÛçS§Nݽ{wíÚµS§Nõóó5jÔŽ;jÔ¨ÁjlÑÑÑíÛ· ¹sçÆøúõëì¥ôóóã†ÆŽ‹‹ûöÛo1Æ*•J&“}øá‡mÚ´¡]-+b±˜=y ×ëíUÂÝ}à–eSt:AÝÙ²š%P€×÷ßÑ£Gu:ÆøÑ£GÇŽãóù‰D­V³™¹ê6kÖ¬¡ý?þ`å®M._¾|õêÕY³fY˜:¸•Ož<™j èßÓ€z bÆh4¶jÕÊÁB2™Ì±±:222++ë—_~©[·î?þH‹ß¼yóÊ•+tÿ…ÍI7ÿh»ÜPѵ#h06nÜh!A©ÙƒÊWFCÃëõú9sæÔ¨Q!Ô¡C±XŒ1þóÏ?©ì·…l6›ÙðÖfÇŽ:ŽÏç'&&Ú›=ggçmÛ¶Ñ©+,,¤ŸBètº5kÖÐú»uëŸ>J€,Ä¡^¯_°`Á¤I“Ìf³———õQ[ö`ZëÖ­7oÞ¬V«1ÆùùùŽ¥©»»; Ùì{‘ KƒÍEÖ=?}úô7ß|Ó¾}ûÐÐP:gÏžÅÇÇGEEBj×®]QËVÖS¦R£G¦>!b±øÎ;T®Ó•„qãÆ!„nß¾}éÒ¥Ž;"„êÖ­ë B‘HJ·cvïÞmq5Y€Ùl aƒGׯ_ŸµvÐvg̘Qî©P(l)±XÌZ>Ø h7Ìf3í ÷ãš’–uvv¦1*é}†§?³Jðšpww'„#„úôéC·'´ZmÓ¦MM&Ó¦M›ØW<}kF“ÉÔªU«;w¦¶hÑ¢¸¸Ød2uèÐáòåË6›J¥&“)&&¦U«V………4x!D§Ó™L&*–èrÖâT&M§õ{xx899uêÔ !DÁÑ>›Ífúõ¼‡‡‡——W^^ÞW_}eÏ£Et{‚ýÕh4òx¼   >Ÿ?sæLn„B!]^³§M&“Ùl¦“@°F£¡O¯×‹D"Œ±««kqq±D"yÿý÷­ãÂq+Ÿ4iRdd¤T*uww§}~ôèQPPÙlvwwçñx“'OæÎ+JµZ­L& ‹Åƒ âæ‹ÅÜ>{yy+•Jz€µÐ9äñxtH*•Q¥cìîîn³Ýò)Oÿý·H$2 !‰D¢ÓéX½Ó××W©TÒC -Z´Ø¸qcff¦··w¿~ý¨™'99™-+•Ji0ë’’’Q£F­[·.--­~ýú5kÖ¬pà46Vçr¹<**Š:½ÉÊÊR(‰dÞ¼yãÆãóùC† Y¸p!ûöOLL2dŸÏ¿sçŽÙl.**¢eù|~FF†Í脸¸¸Ñ£GÓ­úáÇ_¼x‘Š¢!C†téÒe„ cÆŒ‘H$ôÈ…ÊËï¾ûnüøñZ­V©TjµÚ5kÖ „Š‹‹Ù>÷êÕ+88!–››+|||òòò|¾Â3~~~;vœ2e Ã0sæÌ¡ÕFEEaŒéÁ³ÙüÑG!„t:ÝСC 4räȨ¨(zRïðáçNŠŒŒ}Š~Ÿ’’Ò¦M›   ¸f• .t^˜RÊ—5×Po¯”…ß‹"/ì ›í…]*ßx_Ø.—^½z;vŒ}DíI©ÄÄijgÏÒÏJÓÇŽ¤l^‘ÒÔöÂ‚Ž§T.—Ó8g2™Œ«=‚äää™3gzyy½­7^RR7¨J…žž^¿~}îÍ|÷î]¹\^»vm6„ Æøüùó„‹ûÞ8`iª±±±Ô“`E1>yòäÙ³gSRRÖ¬YSXXHÇŽ›‘‘‘‘‘1tèPÖ‘ÀòåË_Ý[ûæÍ›4pF™˜1c†GÝjµzóæÍÛg‘HÔ©S§÷ßÿÝwßíСC¿~ýöíÛwæÌ{.;ßÞÿý ¬RTTÔ AÖÉ7!äöíÛ?ýôSJJÊ·ß~›——GU„Ñ£G§§§gddÐØª`é@i»/VëD W$6󰉬£häЮ~óæÍ=zиÌìw•»ví3f̘1c~øáV½`ã[–éÝm‘Ù^Ÿù|¾P(´î¹cè„X7ÁÖpåÊ•ÒÌU™ýû÷§¡4z÷î}âĉýû÷W¬2WúÉ,åU¶þ“½ ±y½¸aÏÊT¡=ÃOxxøÐ¡C¹Êë”)S–,Y2a„¯¿þº}ûöã%K–LŸ>Þ‡§OŸ®W¯XPÀ6F£ñÓO? ЧËÜ'N†……………¥¥¥!„~ýõWšÒ²eË)S¦èõú´´´ØØXnœe{^›¨¤n†×­[ÇääîG „fΜٲeË7n„‡‡ÓºÍ>߸q#&&¦]»vaaa§NBÝ¿?$$„v¸}ûöOž|ø®]»ìmùcŒCCC âãã}}}ýõW„Г'O>úè#£ÑضmÛÏ?ÿ¼gÏž„ £k×®gÏžEöO FÃ.î©=¹_¿~l‡BÑÑÑðöö~ðàM;vlII !¤N:5kÖŒŠŠúûï¿íµ2nÜ8!Óh4¶lÙ’ö端¾âŽ‹²k×.N7a„ï¿ÿží³ŸŸßýû÷i¶>}úF{qësô‡µkׯÇǾ¢ðªU«bcc6løðáC:(³Ùœ””Äf8pàO?ýtãÆ?þx÷îÝû÷ï·yÕÝÝÏç'''#„Š‹‹g̘±cÇŽÉ“'³ÏÀu:T*]µj•ÅdÒ¬Aƒ³fÍòññ>|8½pì—l l>ŸÿóÏ?Û;A¡GÙÁl€Ò†¯¯¯ûbÍÏÏGéõúþýû³/_jœ·8É}So¯kÅŠ½{÷¦bÕ××711Q,Ó7;78»tn£mÛ¶‰uëÖåæœ:u*B(++‹ÿzÕªUb±8**J§ÓѸšN½±{4B¡°Q£F´?ýû÷?pà›NÐét¬oGZ[JJ ÷3érÈ-†a>ÿüó'Ožœ8q!d0^ð£["‘ˆ+¹ÍM›6þ°{÷nº»doê C¯^½è_u:Õ–”J%7óÎ;1Æýúõ£J*ÛzµjÕ<<<ŠŠŠ¸!Tî޽˖ݽ{7UàØËaoPå¤P í  r¡V«£¢¢È¿x{{;c¿2 #‰<Ø©S'µZmÏ)²…6ðÂøì ûìÙ³ö2[¥Ÿtøðᨨ¨aÆmݺÕÁ©7öä£Á`¸sçBè×_íÛ·/­-55•/;4†a®]»† bÛmÒ¤IùÎ4èõúøøøž={¶k×î½÷ÞC¥ˆ õ2pOzÖ¨QƒíÿÎ;Y ÿ°aÔJe×®]醅ÍzÄbñ¾}ûè_œœè!DgggîÕ‘J¥¿üòË Aƒè¯< “YXXXTT²aÆŸþ™nxݽ{—-¸mÛ6öTí[AA=µ€µKqJÔ«WO¡P`ŒŸ={Fo‰-Z;vŒ¶uàÀèèhx-`iÛ…ÂmÛ¶}ºvíÚ3fÐÏt%‰Éd5jkà1›Í£F:wîZn­Y¶k×N¡P¤¤¤4nÜØh4nÞ¼¹[·n[·n4hÐÇÃÂÂâãã !}ôQRR’¿¿?!dÕªU6l€¯.Ê„Æ*ÞºaµÑK„–NLLüý÷ßgÍšå  Ç]²#^J Qš°Ú¥¯ÍAhì×/´JW½43f¡‡Ù»ôŽ›(ëýYú[ýÿã·¥¼ 4@hlà@­ˆðÖå«^"´´Ùl¶>âþÂØÖöš.½´(MXíŠ ‡ýšoƒÆU/ÍŒ©ÕêrÜN¨ì1ÊË}ËYÿ Pi¥^–àà`ö£M ²qæÌ˜x“JýÊÞ)3ø_ƒÏ绹¹½7G¯neo2™ø|>!ä-s àççW¥/ ”û¡®,JƒÁ`8þ<Ðàm‚ÇãÛóM¼‚W:=¾À”Q `êÁfx!¯ÂË{9CcGDD€¥Þ& ÅÉ“'cbb^Å7€&“^­ÎG»»×-¥Þ€1ÖhäƒF(”Èd^ 7/¼aX/yoXiÀ …BöC#Þ4Ñh\ÆÀ+ÂhD!,‹¬ÿjïë “I@_(”á'TàÜ Þ$ÜõbUY;²ý´ð¯¼<*•ŠuE 4ðÿÀ3F"‘DGGWQ1îÙ³§«««…'okÅLèeE&“%&&>}ú¦¥*`9ŽÊî¹4eK™Ù:€òK¶K+ܾ}»N§{øðá Ûul–°)§ËÔçÒsüøñ’’›–Öa‘½(£€cV­ZMC¹‚êT6`ó¨ÆxРAôÃ9ŒñÁƒ†áñxÝ»wwqq!„ Ôg³L&Û³g¿Ü£Gggg³Ù<}út®¿avÕNËöîÝ›rssÛ¹s'BhĈßÿý¨Q£ æÌ™Ó®]»´´´Ù³gB6nÜ8pàÀ?ÿü“ö¹W¯^4Þ’——×Ö­[BsæÌiݺõž={L&ÓÂ… ÙKåãÆ_~ùeݺu7oÞÌL†aFÝ»wשּׁ¬I“&Ñ«&—ËOœ8ç$JoÅ!„üõ×_‹-jÑ¢EŸ>}`N€Ê…´¾ë'úeKŸ|ÝÀ7€a”……äòL‹©©iß|óÍåË—¯\¹²}ûvn¼x ôïß_.—«ÕjµZ­R©:wîLƒ BÔjµF£™?~jjjff&BèÑ£GjµšBƒõêÕ«¤¤„–-..îÓ§!„ªjµúáÇS¦L¡­|òÉ'ìÒœVNóP h@#‘HD©]»6!d„ ¹¹¹6ûܾ}{ŠB­Vggg6ŒR­Z5Z§^¯>|¸\.g󇄄°?·lÙÒh4Ò²?žÛÜ8`˲_1H$jbK–,ñõõE5nܘZ&Äb±D"¡CÐh4´ø… èxóóóiµjÕ¢ÚƘJô—¹´rvëA¥R]¹rE©Tòx¼û÷ïBhßh™L7pYíj‰‰‰3f̸pá¡`{Êü]´hQ||<ëdÙ²eóçÏ·™Ù"Ѐ=Ž?Þ¦M'''©TJƒVÓ ¹\îééIùã?BK–,©W¯BˆaWW×7þú¦££b/ÏÌ™3CCC_^3(ÓÊÉÉ¡}2dˆ——÷¯T £ÿÃÍ\ší‰#GŽe VÏDÚ'VÉ )ÂÉÉ)''Çte £££Geb Z·nýçŸ3|z ¢Ñ(ËʲˆWÍSUTä©T‰ÜÒÒ ûy"W®\ ¶²²¢ÿªTªèèèAƒ™™™U‹¹eË–Áƒßä¸býL’“S»FôûôÁ˜˜[ûßÙº?ò2è¶ÿ/{ Š">~àÿê§å8®²²’B-ç666¾¾¾¦ó¬"üû”u6ÍDÚ'VÉ`AÕL u“åÔ|"‹ùƒJCµ@L>#¤I°c‘\ž@â«Z.—7¨Uö´´´'ơ۟¨ ÝY¡ôª3‰Y­l sóFææ°÷—LiÐh4·nÝÂMRŸÐét¾¾¾øÓFz=ýï+ ôŽ©OÐ{«”J%* ‚JóT¤Rihh(Ž‚Ô'JJJ~üñÇÈÈHì ©ÐsUÏ܉ /™=j×BMâët:có´= BÁˆ)233u:»»ûó,´¸¸¸¸¸X&“¹¸¸¼°“ò‚‚¡X}â!ÌjÚØØÔöö‚’’’ˆˆˆ{÷î镞žîîîž““SUUE¯‹öññᘎ;öã?nÖ¬YÚK¹qãõ%! W©TÁÁÁ–––øKATvîÜYYYõ< ½~ýú¹sç6lØP\\übvË_ýµgÏž7 ÅêüùóMÜî¬Ï˜1c6nÜhoo_sk!ÄÖÖ–žuÔ×N<<<8Ž 2dõFann¾`Á*é7lØÀŸ“¬Ã©BHË–-«ÆÆÆ–——£Ò€ ¨4 /ú—“ úÁãÛ „©è‡O?ýŒ_×SÃ"Œ•k,mÏž={öì¹eË–Ú¦­IMjxÉ|øÖ[o-Y²„_S°±±Þ ‰ ‚JCƒÖøÏÆ¢étº[·neeeeeePï™™™sæÌÉÉÉ6lX»víÂÃÃ9Ž{ÿý÷³³³ÅÿéC† IHH ióòò8`l:vìØÜÜܬ¬¬²²²N:À€’’’hÚœœœÃ‡×¼i¯¿þzjj*M›™™Ù£GhݺuyyyVVÖÍ›7ÓÒÒ|}} ¦U«ÕYYYÆ 9rdzzz¿~ýÀÒÒ²ªª*+++;;ÛÌÌ,---..ÎÙÙ9;;;//oïÞ½™™™`ggwìØ1ZJJJÊàÁƒi`yy¹Ð—cPPPII‰H$ÊÈÈP*•t;¡ÐhÏ÷a—.]ÊÊʲ²²~ûí7zóï¿ÿþꫯҦUTT}g<‘³gÏöïß?++«°°P*•R»ˆD"9tèÐÑ£G÷îÝK‹ ò¬À剆Çq"‘ÈÝÝ=;;›†´iÓ††oذ!<<üÒ¥K"‘ȘÙùèÑ£t«V«5¶@NY»ví„ „ ǯ¿þjccC'ë:ŽeÙš· …R©¤÷¥S×MÂoµZ­ðšBýÊèt:Z[FCÓj4©TJ«§Õj###…žD"-®ªªjÖ¬Y´ž••• …‚ÏÖô副à•9‰DÒ±cGŽã ň#¨“§ÚšúÅb1m8Çqýúõ£®Ã«ªª¦OŸÎ›@fΜɯV ‚ ¥ù[! .\¸ ôÖXM‚>üáÇF£ÑÜ¿Ÿšú !_}õÕöíÛ322„T(ÉâââòòòhZŽã\\\ ʹÜÜÜëׯS!­ÑhheîÝ»W\\LCX–5è JØ á·TÆóát—ßõë×½½½CBBúõë·cÇÓÇ©šÂÿ+•Jùê 2„eÙÀÀÀ²²²fÍš5iÒdÆŒB‡.¦ÝRðåR™MûŸZ8„j oöàS¥¤¤B”JåöíÛiMÔj5ui¬þþþ7oÞ*.Ôº@IKKÓ?ˆëææÆÿCuÄgöú@Ç•‚–ä%eÏž=ݺu#„¼õÖ[&.›3gÎ[o½¥R©ÔjõСCéß¾}?ýôÓ€€€L˜0a̘1Íš5;räÈÆ+**ºwïþã?:::VVVþç?ÿ¡2[§ÓýüóÏ‹°¶¶vttìÕ«!¤]»v4~yyyÿþý©deYvçÎÆÔšÝ»wïÞ½;//¯k×®‡¶´´üòË/ ÀKÓ+VÀƒBBB¤R)˲»vízçw fXVVÆq\xx8Õ„ÊÊÊ`Ë–-ݺu“Édr¹<++‹^rÊ0L`` Ì;÷âÅ‹@5*^ÌÓ¾*--8p`AAAÿþýß}÷Ý!C†Ð{÷î¥ýÿæ›ovîÜyÆ ½zõbF¥Rmß¾}åÊ•“'O^¹re÷îÝ¥R©••U~~>ÇqÍš5Û±cÇîÝ» !¥¥¥—/_6&‰9Ž›:uªðDëÖ­g̘ñÓO?étº¾}ûÒþaY–ö³Z­=zô„ ømž¡¡¡u>=ÁqܱcǪ%,,,¤KE‚4Ð5vý13BÔj5!D"‘têÔ‰Š=ƒÑ¨‰D¢ÕjÅb1µÐo©ì¡î‹øÙ3µä ÓÒäÆ$ŸV$ét:jl¨aZ¡UÀX¹ “ÉT*•F£!„DEE1" @?7­V+‰øã:ŽÞ7ÀÏþ†a&>>~Ïž=sçÎå8N"‘H¥RµZM;‡ï:–eéÚ0-ÕÏ„Ë7MØÏôê$>-ÝIÝE ÛkÌD$ÄÃÃw@ŧ¥Kt@yㇰ“GŒñõ×_;88ËÖ´kl>-ñ‚¼˜ü®±ÑÒP_´?BÂÃÃçÏŸ_UU¯¼òбhÕ$Š4„~ËÏt©4­–C5©fL`Óòj˜V$é[Jô¥i—.]~ùå•JEµ¥jª5/‘×BªehaaQUUuôèQŽãd2Y×®]õÓÒZé§ÕïXý~6‘Ö`{Mh‡iii¼* LKsÖ‡3øá‡§|ÀP9@—$ë¥áÊ•+:N§Ó-Z´¨~_ýËqÜÉ“'‹ŠŠè&Ç‘#G ï뀻»ûˆ#´Z­N§+**:yòä‹Ùü1Î:¤ByJêniÀëè_@9úöÛo G§Þë |{ŸIc›6mÊŸxlhì?mAž¥Ò R©Îž=‹s©O0 Ó¼ysüi#H½™X[[¿JƒD"iß¾}ÝΩ#òbRZZzþüùAƒ™¸ôA—ˆØØØBi`ÆÄ…ƒ‚¼ŒhµÚªª*áV‚¼ÔüK¸yfÏåоj^Í8÷ô Ìá_ìÒjEëo1Q·¤ ‚ Ò€<'!ÇçïB0S"‘}úèt:ÓW ï;2æ-Z背;€~bAPËC†Õ|óá±ÓðZu‹~¸N§{ôèÑ[&ÓÒÒf̘aÐ+„ÁÎ1Ø °qãÆ7†‡‡ë§5á!ýÙº´¾ÿþ¥K—xÿ™4ó!C†Ü¾}[,:´iÓ¦îîîÓÞ¹s'...;;;++kÊ”)ô®OAPi@êƒEáìÙ³'Ožôñññòò:uêÔŠ+¨è?~¼¥¥%/+++ÿúë¯k×®åääTVV®]»–zIøì³ÏT*Õûï¿OO6R7ÜyyyK—.9sf¯^½úôéSVVöûï¿÷êÕ Ž9Ò£G¹\~ìØ± .4kÖL¡PüñÇK—.5(öŠŠŠnÞ¼Ù­[78pà@¿~ýxÕP*•Ó¦MS(Ç 0 S§N999‰‰‰4ç3f,Y²¦OŸN?~¼‡‡ã8•J5}út¹\®ÕjGMoË~VVk]LLL‹-èÍ›?ýô“ Å«yóæô®I—²²²œœgggü­!È .O µ`×®]C† iܸñÝ»w§L™Ò·o_*®fÏž½oß>>ZUUUÇŽÛ¶m9þ|z)ä‡~ؼyóßÿ9oÞ¼%K–ôèÑãÓO?½~ýz\\\ii)ï5{ß¾}•••°iÓ¦>ø@,EFF6ÌàD¹°°ðøñãôóîÝ»U*•AYÅqœT*}Ž?Îo„”Éd¼ "‰lllŠ‹ÿç n̘1åå啾QÔ•åøñãA`®OII¡6c}5qâÄ1cÆœ;w.##ƒöÕ¦M›¨ÔOJJš7ožp“£PBWTTè×ÁÂÂbîܹO9îÆ:“Ú‡xm€ã¸–-[.^¼˜ºN}óÍ7yË!äàÁƒ¯¿þ:?ı±±Ÿ|òÉŠ+233­­­œœð÷… ¨4 õ±XÔ†Ïqœ———§§ç!C–.]*‹é¶AJ‹-¨ÀV«Õ ÃÌ™3‡:w :ovrr’Ëå7 õðð`YvÓ¦M¡¡¡ñññ¾¾¾„ÿüç?´8ƒÕóóóóöööðð 7nœ1õ…êÖÖÖ¶¶¶®®®»ví¢ö†ÐÐPŽãŽ?îãã“””žžžfffÔ)v||<˲ÅÅÅ666666:î‹/¾pqq1(õccc7nL÷ap7{ölÚFOOOBˆ¿¿ÿéÓ§Õ¢P(úöí»páB~^PP`gggeeÕ²eË%K–ðŠÎ±cǬ¬¬¬­­KJJ8ŽËÌ̤=YRR¢Ó颢¢¢¢¢’’’ìíí---5ÍêÕ«ßxãg¨AÒÀÆÆ†eÙ¹sçzxxÐýÍ›7ÏÏÏß¾}»p}G¡P4nܘÿ7((¨E‹îîî¾¾¾çÏŸÇ#—ò‚CÞVcâgØç(¶½²6!%¦¨(_>‘Ÿ¯9yòD«V­!±±±aaaÁÁÁØw ƒ¦fÓÇ&õ/ £ÁãÂ|ô3¤›MW†’ýÇPÝbРAÛ¶mãÉת&ê\óã‹OlHMN¨>Û1yaaattô¨Q£žÉs",Bp ÷³=Š È•+W‚ƒƒù× J¥ŠŽŽ4h5 Ù²eËàÁor\±~&ÉÉ©]#ú}ú`aLÌ­ýïìÀHÌÿ¡óÑ,<þ'ü«Ÿ¼Zƒ¥€`áÃDe(ÎÎΗ.]¢9wéÒ¥¶CMê\ÚԤ!¦dMÄgmG¤V™?ås",Bp 7j òâƒJR¯ W8Ð=صö¸:€ ˆ§²l IDATiê²§A£ÑÄÇÇãûAêÆÝÝýþýûx„AêÂØÿ¦ÒÀ²l~~>Ž‚Ô3¬¬¬òòò°¤~@ªýûJƒL&kÕªŽ‚Ô'JJJ~üñÇÈÈHì ©¯ß}VàžAt:1c&®E"ÈËÈ?±¹ïi@UUUR©ôŸXá3](Èd²gâRžHT*•ÇI$’ºÝêXçWÏŸþ©®Õjƒƒƒ-,,ðC* Hƒ gÏž«W¯~ÎËjo½õÖ;w~øá‡N:=É}ëÖ­… ªTª¦M›.\¸ðyê кuëj!±±±eee¨4 * òoÂ_ƒÈ0ŒÁËŒ%ÑO Ã\ºt©&i«Q­èš_3EÃ9²eËÓ傞 ÑD{׬Y³qãF{{ûÞ½{WUUÑë« 6¼&¹=«aÂÇA¸§y±ÈÌÌ=z4ïRÁ˜̫ªª¢Ž!¤Ré¤I“!ÉÉÉôM«P(xG‘„cÇŽñiSSSiZ‰D2cÆ c’a©T*“Éd2™ ­ upEÓRßÓÆ PÍYFll,M+‹/^L£ >\&“BNœ8afff°½T½‹Å:Nœ8aiiyîܹõë×Ñ{¨ÊÊÊ౫ ZgOOOšÛµk×h`ÇŽ{÷îM}X ‚ Ò€¼Ü¸ºº¾ùæ›S¦L€wÞy§¼¼Üصr¹œã8•J¥V«ccc½½½{öì9mÚ4ŽãÞ~ûíÊÊJê8±²²òøñãÔ¯ÅËË‹¦Õh4]»v5v„X§Ó©Õj•J¥R©Š‹‹{ôè|ÚV­Z•––Ö¼uÁÁÁ4­V«½sçNaaáùóç;vì¨R©¨ ¥Ri°½„Y³f]¿~}É’%ëׯ§Ýºu;räÈ”)Sè}VÖÖÖШQ#Z„J¥JJJú裠k×®4ðСC/^ÄÇ AºËÈ‹Çq={öŒˆˆHHH#×HS«»H$²³³€üüü!C†p׿ÿ.]º4kÖìÞ½{´åååÂ]ýõ—L&³²²bY6**ªwïÞk"‰5jÄÿ_{í5:k733³´´ÔétK—.¥¢º†—ÿÅb1µðghmYVÞ{、¤¤×_ÝÍÍT«ÕÛ·o§Ë´»¼½½ižjµzôèÑÀûá´³³ëÞ½;>f‚ ¥©ÐUyŸ˜˜˜O>ùŒœ÷£FxN——————7yòdNGÓz{{_ºt‰z•ämÓu >7;;;•J•——WPPœœLZêׄúi¤EÄÄÄ”””€“““R©ÌËË+,,¼~ýzff¦1íG¿\º¸ ŒÐ¹sçëׯÛÙÙ)Š•+Wš8Ühkkëïïïíí-¬$m8PçŸùùù¹¹¹´Î%%%Ë–-£:Ÿ„¶âY >±‚–ù×())?~|VV!¤OŸ>£FÚ¼y³Á˜óçÏ7n!„a˜3gÎDFFNš4‰Þi1f̘o¿ý&L˜Ë0ÌÙ³gW¯^ +V¬àwH$’F,bÞ¼yü1Šü¯¿þš—ýr¹Ü˜¥2vìØ˜˜‡ƒ._¾¦L™Bë ööö …"33ÓÑÑqìØ±°mÛ¶W^yÅÄÖEºà" ¡ûªu _g›/¿ü>üðCZ®D"yðàAÝ,@ú›Isrr¨“tAPi@ ‹uëÖQ£}Ïž=›5kfL†EEE=zôˆNå—,Y"•J€®÷sׯ_¿ÐÐPyÖ¬YÂUŽãV­ZEÓ€•••ÁCƒÇ <¸C‡t¦Þ¸q㢢"XµjUFFMkmmmnnn¬-sçÎeFxºaáÂ…4-Çq¶¶¶fffŽŽŽC† ¡¹9;;gggËpÍš5Õªzüøñjî¶ßÿýž={ò»Aià—_~™••E7–4«<‘-Z7…ðÈår|h•ùw‰DÔ¥5{...Ææñиqãjátñž~ëêêJù¦Ó,B˜ÖÖÖ–†?1-E¸ùÀX¹‰D­VçææRC‚1›EߪA·tT+B¿\‘HÄ—kPö?‰D"‘HðùDTù×hÙ²ennî‰'¨Òp÷îÝúòƒ &<ç[¡A¥Ag믾úꫯV³üsôë×Ï`8ÝFŠÃ È3VT*Õ¹sçpã4‚Ô'!-[¶ÄŸ6‚Ôø³Öÿ²Ò ‹[´h“©O”——ÿñÇ={öž EäååáÇ/„Ò ‰ìííq<¤>!‰JKK«í¬¬ ÿ¢ ý¢ÑF}Gó)ILL|!”Aêö¾«æ\ê–ò|^¯´”ÔÔÔ’’‰DB)..nÚ´©••Õ¿ò~×ViüþÇ ND¬ˆ%lïÒÞ‡ËÄÕ*ü ëöÌ3|aI£åçç'''[ZZrWYYÙ¸qc'''aϧÎ϶3i`UUULLŒÇq,ËŠD¢ÀÀÀ'6D¿íO9”5̰€7B"È?!¤uëÖmÛ¶½ÿ¾0pË–-AAAuxï¼,’öÉ'Ÿ<7!..ÎÆÆ&888(((000$$D¥Rݺuë9¿I9ަÿ>}Y—e[{mÝÜ{ów½¿›×nÞî„ݾ"„Œ3æÖòÎ;ïüÓ%„·iÓ¦°°Ðôp¤¤¤ˆÅâÀÀÀ   …BqüøqáÅ$„þJ±í72|øpƒ£ØÊÊÊš5kF›ìæævèÐ!aÓŒe{èСÐÐÐ!C†˜h5½>®&ÝBéÞ½{»víΜ9ƒ–T†hÐ1X-²±h_aÇýù矣FÊÉÉ~ôÑGqqq&ÞzúÒBÈèÑ£ù«Ÿ¸Ç\½zuÅŠ««jØ´:¼âïß¿deeÅ;ò077wppÐétµêöZu¦ÁÊ,غ`Uت».wA  ÐBœ[Ü{ï]¹qEøfÿí·ß QmdkXg8wî\MÆ«†Ï˜Á"8Ž»wï^‡ªªªLô@^^ž½½½µµµ™™ ”J¥:tøã?„Pí6Oý¶×ê‘0Ö^ý¿OLû믿ŒÆ²lvv¶““½µ…baañÚk¯mÛ¶MØ4ƒ½úÚk¯Ý¼yóСC¦‡’u®Éo™^&ïO\ž@¢ `Ïž=ááátBÖ¼ysøóÏ?ÿüóOj8q"¯¼öÚk™™™‡2339r$lß¾½´´t„ kÖ¬éÞ½{Ó¦MéK™º½¦iyfµý•••[·nµ´´|ÿý÷iH^^ÞÞ½{% Çqr¹\©TŽ5 6nÜH³™™Ù»ï¾ ëׯ¿ÿþ®]»,,,:uêgΜIJJ ìÔ©?û\¿~=½ˆÉÜÜüí·ß€C‡yyy]»veÙ¾}ûzxxÔ¡ßJKK©7NýÉ–““ÓÎ;'MšDÿ-...--=þ¼J¥¢BïÆÞ´iM+‹igîÝ»·U«VgΜ€Î;ÀÕ«Woß¾­ß™BvmÛuÏ÷°Âo§,O9Æ9úù ÅÚ5kÌÌÌärùðáÃ`ß¾}ƒ€‚‚‚¼¼<<š5kþÉ'Ÿ„„„4nÜø³Ï>€÷ß¿[·nÔ\¹~ýzj@vtt¤iÃÂÂÂÃÃÙ0ÅbqÛ¶m©¼äßæMš4ñ÷÷oÕªÕgŸ}@Ãinþþþ¶¶¶ÔoE`` µµµO@@5¤‹‹K“&Mf̘Á¿Uß~ûí-Zд …bíÚµôezàÀ€€€àààÙ³gk4šºõ››››Áåg777áÊÌÌLOOO¾C†ùøãiKýýýÝÜÜ¢¢¢à­·ÞZ·n]PPPPPК5kŠŠŠâããOž<ùÄδYýÜîgÐêOQ!Ê)Ê’ü}ÒÌÆÆ¦E‹aaaþþþÖÖÖ+V¬~=jL¹:t(ß™R©”Ä£GöìÙC;sƌԉ‰««+Ö¾}{ªÀMŸ>½}ûöíÛ·÷÷÷'„lݺú÷ïæÌ™€€€I“&qwæÌ™äädš¶]»v]»v­¹ÜÆÆF&“é‡ËåòÀÀ@a>7nܸzõª¿¿‹-FŒAå:u‹ |ð {Ô¨QÍ›7÷÷÷ íÝ»7!d÷îÝJ¥’Ö¹uëÖ ªQQ¦M›F?tìØ155•¦8p ß´£Ú·ooÌu õcЊеkWaõ^yå:¸~~~&L ×¶ê·â›o¾±´´¤u ¡Š8Ã0Æ kÞ¼y@@À¥K—nݺE{•>~mÚ´éÔ©®G ¥A@"‘¬[·ŽÎ?>¬R©*++ÍÌ̺téB#\»v |}}¯^½zåʎ㪪ª¶mÛFÅ|pppLLLûöí·mÛFoeöððpvv++««W¯+W&“……… O[YYuëÖ?V­ZÕ©S'Z«Ö­[Ó·U^^Þ‘#G [·n?ÿüs‡œœœøäÁÁÁðÿ÷A]¿~w"•žž~þüypvvŽŠŠ¢9/Y²¤Îs¦±u:ÝâÅ‹ûôéCÿ¥róæÍuëÖÑòòrê‡L.—ÓµBÈÎ;5MYY™X,nÕªÕ;Œ5âÿëX\\L׃!ÙÙÙ¿üò 5ãóâDè3]¾«ï‘ËÕÕuþüù4ÃE‹Ñ>ñóó£Úƒ••Õï¿ÿNM×®]£Ñîß¿¿sçNðòòš5k œ;w.äææ6jÔˆo/MûôT©–-[R…’––"‘ˆløÞ0H~~~Û¶m•J%Çq´ziii½{÷nÙ²¥p|…™ð7ŽwíÚ•Z΀ê()))o¿ý6ÝÏxíÚµjW¼×ðéþ{ùòåvíÚÑÏQQQýÈÀƒ†Ê_KOkŲìž={ø1*.. Bˆ••ULL ¾-Qi@ÿ½Rk>‡ „(Š]»vü¶°°pÞ¼yÔZkp¢cº&„åË—k4šY³fÑÀ#GŽìÚµ‹nø’J¥ÕŽAÖaÿ6Õž~ÎT\\loo¯o/))©æo³VÆ a†"‘hçÎ÷îÝ£ ̼¹UlU›ä67}:/Z†Q(Ô® tx]íøÖ´iÓ"##…+¸£GÎÊÊ¢Ÿ­­­ù¹Zyy9]Qž0aÂâÅ‹ ¿E€ÏΖ(–––Ϫ‹,--SSS žRKJJêÕ«—éäT¦R,,,Œ½ŽU*Õ¸qã&L˜`ZIðÖ€{ßß»áw”‚m €–æ,Údè8CÃlmmè4×ÊÊŠ–KUzHúOâ(—••}ýõ×Eæ¥K— п*·LÈ`}ÊÊÊ-ZÄ›¸àñv<†ad2µÞSííí5Ðf@#k4šFñ»#©™ç·ß~£köts¥R©¤ÏÏŽ;¨¿4cú\ddäx+KTTTUU•й+õþ*t„F·¤²²’ª„V­ZÙØØŒÖ¬Y³ŒŒ }'&&fôèÑ|à®]»nÞ¼IGÊÓÓS¨– »¥¢¢B¸§’Ægæ£>Ú²e ýiµÚŠŠŠ´´´Ÿþ¶nÝJíaôÇkii©P(ªý– ¸§iˆÐ¥^ŠD¢­V«P(ÌÍÍ©\¤oaLaZÞÍ0Lûöí333ÍÍÍÅbñ AƒhúÒŸ4iR—.]\\\è[&++‹"—Ëe2õþ矮[·®eË–ææææææTÃÈÊʋŴ&%%%üvô;wK¥Òððpúíˆ#ÌÍÍããã !´Úyyy ÃÐÜÚµkGßzŽŽŽ|ýmmmëlr Ùºu«V«å8”JeQQQee¥¯¯/M"‘… í»wïÒî577wtt<~ü8—Zhg†‡‡'''ÓhÔ†ÁÚš™™}>öó©¦Úéþ6ÃØ°6+ÓW¶jÒêŒõ^í‰D „ssófÍšíØ±ƒeY:„ŒŒ cê ÝHš››·mÛ–j Õ:†ºcÇZá%K–PAèààð÷äL,¦’RH H#GŽüæ›oøöRQÇ0 !äûï¿wqqiÓ¦±ñrww?qâ„J¥â¶F£Ñh4‡îÑ£‡0fÿþýwîÜI‹Ø½{7ÇqŸ~úéĉ E^^ž1_²´¦NJŸ(BÈ©S§8ŽûüóχÎ×™>T¢›››K$’C‡ýôÓOðÿ^XiÛ—/_Þ¿šð¯¿þ2¶2BÅsrr2¯Peè‡~;v¬Pfß¿ßÖÖ¶iÓ¦M›6}ýõ×é°nß¾]"‘X[[B’’’8ŽÛ¾}{HH­³H$ÊÌ̤C9iÒ$‘Hdnn~ýúõîÝ»ÛÚÚöë×O&“ÉårFCwÈ2 ãææ1uêT©TÚ5 o«1ñ3ìsÛ^Y›ST”¯ÿ€æçkNž<ѪU+BHlllXX]IE—:Q M_Ž$ŒY«´T¦ _.g'Æ ­––)ÌDßЭ‡æÆë¦¯²),,ŒŽŽæ­ÆDÝl/—Ëíì솹~ýz»víÚ¶mkìrF¾Çô;„†Ôd Œ¡­Ð¦ßMŸm?[ÆÉ´DûqÁÇký×î²ÛÅr,CcCÃ0Ì_|A·µÞ¾}ûرcüÂÁà‰i¬”jáÂTÆÒDc}BÃýõ×´´4ºK %%ÅÎÎîÕW_}â}D/^ £2[.—›8Ûi¬\Ó5Öj0´dcìr§¸¸¸ãÇwêÔI«ÕªÕꤤ¤÷ß¿Z|áµ ÑÑÑ„ª:%‚ òï) øùû5éó+1?'óÞÍkµJbcç0yîש ŸA:ÞÓ„ûwb4ZuH«vwþ¼æéhaiM¤§<¬(+NÛ¼M;ãï…4ËÉÊËÉJ—JÍš6Âà8N*#ɺyøˆÄ$-‰O«kѦ­ZÍ´ TUV¤$Æ1 Ãrœ—o ™\QVR¤°°zw‹!D§ÓµhÛV­â¤2rëúu‘HIJ¬TfFÌ e%E™éÉ"±ØÉÕ#-)¡e»vj'‘„{7‘¨‘£ 3-)ÁË/@§ãÄbòð~œ·#‚‡÷ãUU•ÿ«óÿ— +O_?–Ë·A†«4(0¼oèôkŽþ¼­±§ïÑ}Û§}¾Z*'ÄÆ½½ü§Ìû&þNÌÙ_ö™[X€H$Ú»}ÝâÛª* ]^Vrå ±DJ9¸{ÓìÅß^<}xïöµ= a9Ža˜ÓG÷|¶lùW³f[ÛØ±Ë0ÌÅÓ‡{½6Ì`CŽÜõ ö–›§oiQƒÓ¯'öOZ¬ÓÁÕ‹§ý´y×ñ + öl[=däD;·Žîý~ú‚•\:ÿ×Õ 2390„¹pêàŒ/¿\0uj#'–e ´¸°ó«¯…´ ÇG Ai¸J`×Èiâœñ^2IB™æÝ¾ýX«Õr¯þç `m Þf¢+Wûð½E³ÆÜHWª”–”pè§-Ýûõ–Êd ¦ÍüaÃ’?38µRKyxÿn‹6]{õ¡fŒÂü2ƒ8:»Ž>8™Á[Ý#€Ç±Nš×©çÀÊZ8ÉoX½sý©Åå¥@…´Nˆ1Ö–oôò üfÁ'ó¾^ÖÒÙjæ—‹•UÜè)s’Äòö –åf-Z;¼o»Ý'þXùÅ”o>§ÓÁ½›×º÷{3¨YS°°‚Pû«¾Ü½eEŠŠ+)Ðh@­Òàs† ‚4h¥áªÈÿî«$ ¬ªœ=îý‡÷ïrffr©LFÕ †a¤RP)ÁË/`Ú‚¥é)‰öÎ;Žý%‘ËŠY÷ÖûÃ玷rÁ'PUU±|óÁ¦-ZétÕK$ïùþ»Õ_H¥2F$NJ¸K«!W˜óÚ •ô|ÅX–³´¶5}t‚tR-: Y¹ýøÀW‚¾;ð;ýVnn1ñÝ^ …p×®cÂ|Èà¸Gg++[p÷ö_°j—X"ÁG AyÙyÚ„€V«á×ë;s¸ßà÷/ÄÇ]KŒëÞïM}9Ͳ R¸zø´ïôjB\ÌÛ½Âïß!„üzüÜð1Ó.ÄÇ]ˆKÌH{·_k +%ÊÌ`å©wÒ’.ÄÇ­ÝuÊDÅÊJ‹mlÁÊœ\ÈÌÈ7ÍÌ&µ¶ª¢œüý/gc©ÔÊÚÚÜ8Žã8îáý¸íë¾:|%îÛó3ÓÓ ¨ Ó:ÿ–¿|ˆÁ]û<Èͦï›yâÀN|ÎA†®4°,[Z W’´%EÀ±,pÐð°è<%Ä™Ž=ú«UJêØŠÕ³hÔªf-›xsäö#W¾ù| ˲ºv[4s´§„xJˆ%!7³þgᯆ² ¾ùþ¨=!ž²xvdhûNTÆ –eËJàNçJH 5ñ’‘o¾?Zedµƒ¦µ¶±_´þg­XVæÄWAŽîÝÖÆ é¦0'b1™7ùÝé_,WVÁœ%«'¼ûªT“æDMчÖÙCL¤R¨ª„ ?§Õó”õKf¿=j,>g‚ H= îËe앤ÜÒbV$©ÕÜæèã• Rqßþ|T,B ¬âK¸âBîä«J Yòø²¤Ê îbÜ£ÒŽ¢Õr?ûµ¢TJîûÃgÄb†@Q¡Ñ¡í:Ü/å8´ Ê˸Á#>dYÐiJŠØ;yÊ’BÐh´2þM›¨”Õóä8îÝ1tZÐé€RVÌÞÌ,/)bšt:(/å úÂòRŽ¢¬âŽßˆ/+áàèÕ»Œè¶â–0ŒJÉýV åextAiØJ!LY Â!¤²„(¥ÅÀ0 ý@×+BÊJÿÞ=PQþ8m¹0£‚V§¡‚¢Q Œ' Ã'Œ¦VÈ“¢V þe˜Òiiв¿ë\þ¸þåeÿ—œ~«ŸAA^vðždAAPi@A•AAPi@¨Ãè[ IDATA•AAPi@A¤~S—#—„€TÀbï!HýåX¥R©P(àñ5i„Ò¬lý›Ù^R,Ì-D6ÖÀáP# êDiˆ ØAêÅEE?ù1rÜxaà,O·.íÚi¼äÂöaBÂ^½Ø4®¤½J‚ õ–#"‰¬ú\EaÑ«kwøæJ_êÖ](-ÕÊ8Ê‚Jò“ðâd/•J}||j[Çq„ú÷yvà£GJKK­­­ÝÜÜþ©2´Z¨¬„ÊÊ—úIãßÖ„´´4'÷íÛ· yóæü¸———§¤¤ˆÅâÀÀ@z“T*•NNN52¹¢¢"99Y$ñ¥'&&ªT*;;;‰ Ò€ ÕiÒ¤‰i—åÏ9óC‡ÙÙÙÕAi „|òÉ'+V¬xÎxõêÕØØØ_~ùåêÕ«ø8=Ý‚ãRRR|||L<9TªEFF6nÜ–-[¶cÇ–e†7nœŸŸŸN§ 6lœ>}úüùó2™,55õ»ï¾£ÑjUŸŠŠŠ¨¨(ggçòòòwß}·yóæÆªôöÛoÀŽ;–.]Êq\qqñÂ… KKKGH+\UUE‰‹‹Û½{wm«Dùý÷ß>,—Ë3226lØ@ÑÏféïïϲ¬Ïˆ#àüùó§N’Édééé[¶l¡ÑÆŒãîîË—/ÿá‡Po@¥©Ï/Y}` çqÃ`4aˆéׄ~dƒET ‰Dµ­óŒ3ª™ j^ÏU«V •†Z5ð‰íÕOKëúhÞ¼yÔ´SRRÒ³gÏÓ§OãÓøÂ‚G.‘§‚BñòòŠŽŽöðð9r¤Z­&„lÙ²ÅËËË×××ÙÙùäÉ“t"þÛo¿mÛ¶­qãÆÞÞÞÕ^U—/_ž>}z||¼±R‚‚‚|“››KË]¿~½§§§ÏøñãµZ­V«úè£>úˆŸs°,»bÅ BÈ©S§=ziii4í‡~øÆo 4ˆšOõÑétqqqü¿mÛ¶½~ý:´oß>55>ûì³ÄÄD‰D"•J“““ &&Æ„h”H$éééÖÖÖ%%%Ÿ|òÉ£G¼¼¼æÎ;wî\~m‚ã¸]»v­]»ö?þ(,,tww_½zµAQݤI“ÌÌL±XÌÏiiÝ(ƒ Ú¿ß¾}é ÷áÇ»wï¶¶¶6X½Ž;ÒΡœ;w®[·no¾ù¦R©äs«¬¬´°°ÐOÛ¾}û¬¬,ú9??æÌ™7n·úâðáÇ€ži- È? B,ËŠD"BÈÊ•+éJ'Ã0¼ð‰D={ö¤ÿ&&&ÒÀ9sæœ={vܸqáááÅ<Çq"‘H.—3¡–L†aZ·nÍ'¡_Ñ×=Çq-[¶4¶<ötÊEëiÐm:ÇqãÇ·µµíСèQ£jnÕ§uæ{€B7*JŸA vcÉÍÍÍ…ÿvëÖ¯-ß“ÆÒ 5‰ªª*333:ãìß¿? <þ¼ô%? ñÏY°•äy@Ÿ”ÜÜÜ¿þú‹š1Õjuµ%XújæåÜŸ8q"..Îà[›Ò¡C‡ªª*–eY–½té’ÐÌ[mýž_ÂOOO×=éV"•JUMfHU„#GŽÜ¿ÿþý§N¢j„±ÜøâŽ=Jiܸ1í–eùåjÅŽŽ ÿâ‹/>ÿüsc¹ +·nݪHÍB…‰ÿ—·FÐNŽ oeAéhB•4¦=œ8q"))‰~ =yò$ý|üøñˆˆªÛÝ¿Ÿ·ñX[[Ëd2–ei¶©©©4ZmiÑ¢Enn.Y;;;áóyôèQ~  k×®.\ Ÿ/]ºDÏ @ee¥““¸¹¹ñ»nܸѳgÏÚÖG,›™™Q•733³mÛ¶üW¥¥¥GåÝ»wç „999¶¶¶‰„Ú ===<<ZµjÅoÊùå—_êÖKÈs—'gÆ è{M«ÕÚÚÚº¸¸tèÐÒ³gO~JmPŠ%%%íܹóĉ&LðõõÕóÝwßuîÜY§Ó)•Ê©S§–——ó‚“RYY©Óé<<ÿüóùóçËóøñã­[·&„L™2Ž9Ò¡C†a”Jåøñã+++i=---ÍÌÌ222Ž;Ö¯_?ƒYýôÓOáááÔœ`ff¶fÍX³fMÛ¶m©êÖ­›™™!dÞ¼y¿þúëåË—[¶lCõ’°°0ª¨™››ûí·´ç+_ò3“ÏÇÒбcG†anÞ¼Ù©S§ŠŠŠ]»vñKf}úô™:uêòåË9Ž›6mÚ¡C‡Ú´i“'O^¹r%˲gÏž3gιsçÌÌÌÖ¯_OŸäÙ³g÷éÓ§´´´]»vgÏž­íTŽãŽ9ïàà°yóf^×ét 8wî\×®]9ŽÛ¹sç·ß~;mÚ4BÈ¢E‹zôèÁqÜþýûÇŒ“˜˜èìì¼yófBH—.]äryxx8˲ƒ>zôhm«¤P(-Z4pàÀ¢¢¢-Zœ>}šÏ!66vÀ€•••r¹œã¸3gÎÌ›7ïôéÓR©týúõMš4€ùóç÷ïß¿¤¤¤U«VgΜá8îÓO?=xð íÌ)S¦¬X±7ê¾Ð?…·Õ˜øö9Šm¯¬MH‰)*Ê×­ü|ÍÉ“'ZµjE‰ ƾCÀÈAÇ„_™8¤`°”º•kðÜAÍÓÖüDMbZXXPÞ{ï½o¾ù†U¯CVú§EžXaÓ\XX=jÔ(aàlkëEcÇÂ’%/ûƒzÀo̘Æ7>ña6ýU 6ƒÑê& ëƒéÒŸ^$×°J5ïÔþ!®\¹leeÅ›0£££ DW-…lÙ²eðà79®X?“ääÔ®ý>}°0&æÖþwv ¥yÚÉYµ¿`Ⱥkð+ƒiM”ò4åÖ9mµpõ¬IÌ^½zíÞ½[£ÑBÌÍÍí-¨IVu¨pßË÷ä¿Ôˆkü0›þª†›‰¾n?±Zå`ºô§Ï5¬RÍ;5†zöSBäÙXe¢££;&‘HX–;w®Áã/Z­vå† õÀcUÀì!* ÇÑsö8œ K×)Cˆ‰£FŸ.¨ÓÓe(Q¯^½„"ù…Òª}àÄâ%K—BUU=xZ€¶¢B ÿdŸë_»Tƒ>瞢MHCŸ‡Ôá"pT€ã¸7º¸¸à•5 F×[œ9#ÊË«ýk–˜OŸѦM­ÍÝ2÷¡ÿC†­ÝQ#5£~·è]öåq!Ï0Œ³³óÞ½{ÿ/ÔÃê:NTkݳ̛h4zutÍÙ°aý¯¿‹Åµ6å¨ÕÌðáEøÂkÈB”JåÀŸ³Á²ž,O888„††²h~l°r¹ç¢Ef7nÔ!m¢É­pÉvÏŽî]‡²¾IøFK´8^ ä ^‡« e2³º×­Ä¯¿N`Y464hªªª$Ï}ËQý¹§ž‡F,Ëê9ȹwúô÷K–À­Ë—wFEÀ_þùóŒÿg”‰ê`Ž"\õWó¨ÜQGÖ€©YS£×FÀ‚G ~\ûcõg’Ãg²=’ÏÊÒ9rdÞ±cë`òäìÖÀüùöìY[-ö9ò¯×ñr'¤žÀ(•bµDUUb˜ª*‘ÞÕFÏ Ñ(ÅJúA%Q€š¨UbŽòôhµD©”€Fó¿j5Q*qÓ:òb¼i± AA¥AATAA¥AAT䟂‰X‘8±øg+Äb®6÷8ÕægÈY10#bE âDô‚<íÓÅp"+ü ý€ ÿ:¸#©'¸¬^žŸnË–É33Àý«¯¬û2~¶\²¸”Þ9ÎXŸ¹Ýù6±=bÕÅ Gyz~ÿÝ23³3œ;gÛŽ³¹|¹ ö ‚Jó„ú÷ÃmB4šja¶'N؀ݱcÔq¤ý¡CöÕÒéêâE%Õ'y ò„„¦ pWqšüeþýðÅáE¿ é‘|VY=x`öàAÜ»§¸w¯)ܼiú‚¼,J˲ååå/Îõ‹ljD¢¢¢"T EE·vìàÄuyzírrÊ$’š?*ǽ^ñúgW?c¹Ú=ð 0y¢<Ô”ÞP«£D"Q(‰‰hµµÖe Dèo§Ã²lYY™J¥zºìS) æÚµk/”ƒ(''§ŠŠ |†uõ¢”ÉqYYµJbïbŸ¡Ìh2O*•*•JôýVgjõbä8ÎÃÃ#=½û ©3·oß6ñ­•Õ³_3­‹Ò “ɺwïŽÓz©Oî߿ԨQøÓFúÁÕ«W_¥Ÿ—à H½ÿEãOAcà‘K©tÅúÅÙÐÃ×äù›ø m¢£ž²õ‹†4(õŸFä?M"* ò´SUcóWýY¬øñ© óHú!¤G&"›(·&­ 1µZí‘#G¨2VÊÓÌ€«Evˈ#¨Whƒ1% ÿ¹Y³fÂ8Õ¤¾ÑÂXC!+V¬Ø¼y3? „eË– 0€ã¸ýû÷O:õ)çß"½ ÁŒõ@XXÇq|3 Ö¹Znü¨={v÷îݵj>ÿUaaá|€‚J‚<§)róæÍ5££ã¦M›ètùË/¿ôõõõóó³··§Ñ† B¹té’»»{HHˆpʲ,!dÑ¢Eyyy‹9r¤ŸŸßõë×ýýýCCCiÚÜÜ\'''???ooï½{÷Òr?ûì3???ww÷øùùœæ²,[QQáèèèçççååuäÈšvâĉ~~~Ó¦M£"„òÆoøùùùùùùúú¶iÓfåÊ•„ÂÂBZ®§§ç™3gj5'„Ìœ9³êñqBÈG}DQ«Õ5ò÷÷ç¥!dË–->>>ÞÞÞçΣáÓ¦Mó÷÷OMM  E3 sùòe///__ßuëÖ ·Søûû|ôèу„e•””›dŸ:u*44T©T éÕWGžòÙøå—_† –˜˜˜••E—*æÌ™³nÝ:Ú«ÙÙÙ666ToÈÏÏæÇK«ÕFEE¥¥¥%&&ªTªÕ«W€T*¥—™™éèèwïÞݵk» 6G<...77×èûšad2Ùo¿ýV7£‚<=x4Ò¡¯Z333*lè ñ… .^¼HUaä]»vq§ÑhÞxã P*•Ÿþ9Õ3xíAN jµšŸóÓÓ9sæÈår†anܸÁ kel–ùÞ{ï}ùå—ÇétºE‹YXXT+NøáÞ½{QQQééé,Ë2 S^^¾lÙ2•J%‰®_¿^·N;}útzzú˜1cªÍ}…Õà5ª¥K—®ZµJ? ‰V¯^Í·]ØOìÕšnݺEDDÐÏR©,--¿ùægggÉdt=‚VF÷ÿwŒ ›YYY ÅÅÅt@¡PÐ*•Šj`Âv±,Kí›áááË–-[°`¹¹9œ8q¢wïÞøsFPi@çÍÇOŸ>=tèPjåž6mZ5q%•J?üðCH${÷îݶm[­Š Ë"¬¬¬”J¥ýõÇq;wÞ±c‡³³³J¥Z²d‰±´,Ënܸ1&&F,‹D¢9sælܸ‘—@Õb2 µwï^Žã¨¬²°°þO&ÃZNÈ\ü@ëÖ­=zäááááá!‹ù×¼4rƒ8Íݳôê' iy-Üdê/­Uã"XÈaIÒ}õËŒÿ7™IcG‘H4sæL'''kkëÄÄDùÏ\ÁK]®Å$Æ›‡ Æ[æÇÌÌÌÌÌÌ„C|oëÒ¡Phð-£´´oß^.—gff*•J¸•Õ £’Q–3 æuØÎb0oBHýúõÙ«Í`Tž ^TþÇË£ñ‡ì ã]G§Ó9::²û‚ŒÊAi¯q{]BƒX,f!ŒJF^^Þ®]»¨± ƒñ®[îq²3 ¡o…bõÀ`0˜ÐÀ`”BÈ®]»²³³_%†×šÃÇ_½zõ­TNjjêž={Ìýzúôi~ ðëáÔ©S¯R™{÷î=t轩|)ù5Ûr¹|×®]–¿vùûï¿á>éòꄼ¼¼ÌÌL“QYƒ Æ[C©T–Í¢ N§›;wîë>B_\\Ì¿{ñM¢×ë-̈aaað€1Žˆˆà×ÿ:£RÍ—ãfÍš‰Åâââb³UåÅØ±cKè“ã8 ÅÖ¯_Ÿžžnì~ãÆ³gÏ–¶o€•˪U«œW…š©S§\ðÅ`¼>Ø Æ?Ã.½Æ‡*êáþœ!C†Å0Là nΘµN§ƒÁF×0\À·rD­E˜\Gš Û§Oƒtù‚OZ:dþ:‡—ÎU|»JP¾¾¾ƒ6Y ;ç .ðëþ‡¬äG¯×ÃmÊÆÙÀW¯^L…•ð¤2÷ÞмÑ.ñÿ+­[ßÑÑñóÏ?7¸â‰¯<‰D èõz¾NŽã233_¼xÑò[ÜØå?‹< pXÂÄ{{{ÿý÷ßS¦Laï2ƒiŒ×ν{÷Û¶mûÛo¿5oÞ|ÇŽ0Ê·oß¾jÕª|Mx»víîÝ»3ñçŸnpëeúôé]ºt¹víZXXX¯^½À177·yóæaaaíÚµ›6mšV«ÍËË5jTXXXhhèêÕ«éêÜx¾Ü¸qc›6m ì7ß|æ,XСCj•!4~üø°°°öíÛ÷íÛW(îܹ!´nݺ֭[C*³gÏ.­â¤K—.EEEôÏ €%$$„ÿM—J¥š4iRûöíÛµk7þ|¸vbéÒ¥íÛ·øðaXXXÇŽéÔ¸páÂvíÚµoß~„ üõºH$Z¹r¥¹œ@£lܸqóæÍ{öì)ùš%çÙ³gC‡ kÓ¦ÍÊ•+1ÆÉÉɽ{÷ Gª!hÑ¢…H$‚†‰aÞ¼y¡¡¡aaaS¦LéÖ­BH,{öì¨Q£6lØÐ°aؘ'''“Š0YÙ­[·èèhº&vqq¡çFŽYXXx÷îÝÀÀ@Ð*7mÚôÊ•+æVÏcÆŒ¡ä£G N0„A5BÖ®] ÏÝ»wOHHhذ!BhΜ9`T !Ô«W/­V+•JK^3¶¶¶ãk×®eggwîÜÙÁÁ¦ÃØØØZµjQo™™™Pcð y›6mÚ´iÓ7n çhé¾øâ‹3f€tõìÙ3ÏéÓ§ëׯo.'ŽŽŽMš4Y±:™ IDATb…R©ÌÏÏß°a½»ÜRÁÆ¡~ªV­ùË/¿¸¹¹'''¹\N¹rå HTGrþüùsçΨ4tèPô¯uЋ/‚OOÏçÏŸ;vìÌ™3YYY 0Зœ={¶jÕªæ”aЩ_;ÕªU«'NXYY_Ì`0¡Áx-À’”êükzùÖ–éJ×ÝÝ|&çxpÑh4üÁ&ûZµj’Y¯×/]ºT,ëõú¢¢"©T #¾I‰’žžŽ1† cÕªUãÇ7Hñl:Ìš5ë§Ÿ~kΡììl‘Hd°ÇQZ,œ¿£©Ó]¸›þdPÀÓÓÓ8ÿ„víÚ!óûùùùIIIðkJJÊÏ?ÿ\îÝ J•*T¢=Š‹‹‹»»;Ý2øè£hžùwh‚QS­V íEÖétmÛ¶¥~hÌZ­–ª(øÅoÓ¦åNeÌ¥K—¨ÉrŽã&L˜`Nì`0ÊAªfUÀ`ðáëáaF”Édp›ݱ2dHVVVÏž=ïܹcy¦Ç‘#GBµjÕËF:îƒ>—”””ñãÇ:tÇŽæ”íãƒBXBÈÉ“' ©g°I ÙÃÿüóÏAAAµjÕ¢ysppÐétz½‚—Öx´R©´±±‰‰‰¹{÷®AÑ©”ü ä6>>ž/lÑKfvïÞm!!ŒñÊ•+a÷Ǥ…BA§O›âââ7Ð%233srrôÿOK*‰@6‚šoÚ´éÈ‘#ÇW¯^=ÐñXPA"INN~üø1-þÚµkcccÍ Žð “ɨF¤ȘB¡˜4i“LÓÀ`¼vôz=Ì@`¥N~>>>yyy"‘ÈÍÍíáÇ!??¿ÿý~þùçË—/§ŠkÄbq§N<==íííá–•Ó§O;;;ÛØØT­ZÕËË‹ã8GGÇ‚‚‚sçÎaŒk×®]XXhî¾ooo0=nÜ8Œñ˜1cŽ9’ššjoo_PP€úä“O8P£FñãÇs7yòäI“&mÛ¶ ÂjµÚ5kÖœ|);vì¨V­ÚÕ«W%‰¯¯oBBèQÜÜÜ ªV­:lذ¹sçz{{‹D"Žã¦NÊ!""ÂÝÝÝÊÊ >häª0ø8%""â矮W¯žÉœÜºuËÝÝÖë...—.]*÷žPXXÈWl „fΜ A( ¹\“º½½}aa¡O›6mþøã„§§ç¦M›Äbñáǃƒƒ«T©¢T*ùÚz&,,lðàÁS§NmܸñŸþI=Œ7nĈ&ƒcŒÇàÀ‚‚BˆƒƒCÏž=׬YC=äæææää°w™ñZa¦±Œÿ,æ,ÛDFæÍ:›‹Íø™3]rÓØÆîåþõÄ+šÆnß¾=œi@9;;çææZŽÜ\©Ke¼$Ëx?y¦±™¦ÁøÏb™·;l`¹¸\LcרQãàÁƒÓ§O‡?§M›Vª¬Zv)­Ï’T *¥ÝêRÕáKmC›óÿú:€¹"çD 4hЀ6ågŸ}VÂÞUBÓØ¯Éî9ƒQ*˜ÐÀ`¼M|||¦M›; z½¾N:l¥øŽ"/^üìÙ3¸×Áßߟ5%ƒ !DÑjµü:ƒQfìíí©þð5ÝrX4X,ÖétôT?£ rƒ¯¯/<³šd0¡áÿ—óçÏ3 šÁ¨d^ýúõá(]ÀqËJP:Œ±J¥b³8ã½®TyûBƒD" eš£2!—Ë£££‡ FgV±Xé|õéV.—ÇÅÅÁýQï.OŸ>­^½z™[Ùråóm˜Yî±–ã,ÇV®Y2™ºAr%ÿ¸”QA`ÚÆ;³X„[+‚ø"j×®1þñÇßâè†1þôÓO…BaŸ>}^k6„ï>%¬BȱcÇ0ÆÖÖÖ0éZ˜1Æ3µ‰ºoß>øsìØ±ãÌÌLðCóP--[¶´p!$//’«]»6ÍÒ¨Q£ éýû÷cŒ8ÀÏ’OÙ$†† bŒ-[~ÇGGGCr#FŒ F\ëÔ©Y‚úùꫯÍRxx8“˜ÐÀ`¼ê< ÿ÷ìÙÓÀý×üÉ€/u¤.Ñø¤÷üDDDœ?ž’˜˜øìÙ3sòÝc³s“éû!„ìܹS¯×§¥¥Yk23¬S™äâÅ‹p]·R©ìÕ«—¹kªŸ?@oõ†-Ïž={áÂøsݺu`€üÀ}£­[·.C–¶nÝÚ´iSŽã~ûí7°f’{÷îuîÜ’ûûï¿!K›6mêÚµ+dò“O>!„ôêÕ‹f)55Õ‚m0 :ŒÉ“'Ÿþøc„P``àñãÇ-\zé‹ã8µZݤI“ÐÐÐV­ZÁµÓ4¸Á^IóæÍ!ì§Ÿ~ Þ 8={ölÙ²¥9Ó „PëÖ­7lحܱcÇøøx“ÞÆóæMÇÐÐP“F½9ŽS©T³fÍ:wî\ĵˆˆˆþýûBjÕªkî-ZÀUå|fÍšÕ£G“þccc8s©ò£P(ÒÒÒ`¾ÿòË/ï°¢´iÓfݺuowaa¡££#ÿ ¥Ï+W®|úôéš5k˜PË„£¤(•Ê€€€¸¸8û÷ïËd2˜;6yòd°þ}îܹ¸¸¸”””‚‚‚ÄÄDº ß³gB¨U«V111§OŸ>}úôÞ½{{÷împg_`` L&»qã†B¡Ÿñññá7‚ý¡‹/nݺÆÖ .\¿~ÝÁÁáæÍ›;vì0¸f˜Æüá‡^ºt Ò]¿~ý—_~)¼¼¼âââNŸ>}áÂ…µkׂé&ã°µk×¾|ù2„]ºtéĉB FÞ²eËÅ‹.\HÍG1LB-Xš;É!“É0*´>}\`{‚ŠtVVVK–,1ÙÜ/…oûÔÂÉkkk¥R ©×¬Y²dgg7qâDp„í ð¬R©š7oþÕW_•­rèÞBl¹™ãÂ… úðáÃáÁÙÙ¹nݺ𜕕EßÍ¿þú+""¢W¯^¬ûUpØAHF²A=@Ç0'Í÷fcc3~üøõëן8qâÀ–Omß¾],òÉ'4‰ßÿ]*•bŒoß¾1®_¿þÝ»w‹ŠŠlllBBB ]±X¼k×.¢V«Á±Q£FYYYÇŽ«^½úÞ½{ùÙ¦†¨ËüV%iÑ^º04{xxüòË/Ž% K+D¯×ÿôÓONNN¡àà`öéÓ+bgg׸qcÚŽ5kÖ|ôèBèÆàøã?ÆÅÅÂŒã8¾Å×—¥ÁƒCüééé“'O^¾|ùÇ{÷î úààà^½zA—Édo K|‘}Íš5—.]ªW¯ÞŠ+ …Aê-Z´€ç:uê|ß¾}{÷îµ<àÒqÙÆÆfÒ¤Io·®@3A™9s&ÿ£J†¹†‹ÅÔº7Ý႟ ®^½J[¤1„ÐÔ©SÁ‘ã8úy'ÝÀ8gi+Æ!ZFcÁÛ¾}ûhö`V®^½zË–-©…wãP¥5’9-ˆ šãûï¿oð½+ìh@Þ@;b„¿yÁ`BƒQÒ!Û`8S«ÕZ­V«ÕRÕz^^Þ¦M›†ºgÏžaÆ™S3ˆÅb½^¿jÕª%K–póelllXXX‡êׯ¿gÏXyW­ZõêÕ«r¹ÜÝÝ®Å;ð öšu:dƒž „h4p´0›,š¹¡\­V«Õê´´´Q£FAAÀ>Zƒ¤¡Nø¦¥©7¨1ƒ› ØiËÒ¢E ŒqAAÁñãÇéÑE¨ð9sæ@ŠÅâ‚‚hq½^u­¦Ñh4 |&ðüùóQ£Féõú—v YŠ‹‹›?¾V«=uêÔàÁƒ©À§Óéàþ ¾DYÒét°‘ÿƒ¨ÏÛ·o?tèt²É1ÁÁÁ×®]Óét“&MJMM¥ÂÓõë×áæM~7†,A…€ô@_(Ë€²³³!K:® µÄx“°í FÅÂÚÚ:88!ôìÙ3„ÐàÁƒÁ}À€0çíÝ»÷ðáá!C†ÀAwGGÇ=z¤¥¥ùøø¹GíÞ½û©S§BÝ»w?|ø0ÇqEEE­[·¶··wuu=}ú4ìËrWXX8jÔ¨7Â8Ó­[7˜'$ITTDûÑGQk¡ÀÀÀ›7o‹üü|:¯þùçù4hB(;;!Ô¢E “C6!äÆ;v„ÑÓÁÁá?þà8.55µmÛ¶¶¶¶:nÆŒ°\ûé§Ÿ.^¼X£FÖ­[Ó:ÂÂÂ`Yéêêºyóf¨¢ °Þeþ6mÚÔ¡C[[Ûýû÷ó÷¼z÷î {L„­[·öïß_©TÂä}ùòe Zµjåàà@ ÿè£B=zôèÑ£‡P(,((((((í¥°qþá‡.Z´ˆf cܵkWÈÒ“'OÚµkkwooo8ÎyåÊpT«Õ«V­Â4hΜ9›6m…D²Dùæ›o¾þúë9sæ|ñÅü—ÎÕÕµk×® ÀÑ]Z!Ý»w‡Íš~ýúA…æååq·cÇŽ~ýúÁ‡*z½þâŋ잆 ýšXW·uÿ[—Lë-!kþNN˳[+;[{âÄñ   ŒqbbbÓ¦MXÝ1^ëš~A•üëu¾ CŒA$%ôLßNcƒ… jŒ¯Á)yž_¿qµÇ\ò«rss£¢¢FŽÉw6lØôéÓãããßõËî߿ߪU«6mÚ”¶<¿´’-4Ы¼ /mÁWé3¯)K%¬’äœQ6bccè G­VGEE…‡‡ïUEFFöéÓ—<ãHžqâÄÒ¥K8ð&óƒ1>yòäÈ‘#K;¢•y°Àoذ¡´e$„:tÈ\¨WDhXŒq¹7ÆøòåËóçÏ/›±ÍWIzÛ¶m+W®,sq6mÚtøðეjÜëСÃK÷‹çÌ™c² 5*íË¢P(–.]Ú¹sçöíÛ÷íÛ·I“&cŒqíÚµ 0pà@ö‰r%¦b}r™››«ÑhBÇyyy!„Äb1B(==] ˆD"WWWBˆ^¯ÏÊÊ„±X¬R©„B¡D"x²²²ÌÕ|þü9!ÄËËëÙ³gîîî"‘cœíããÃþ233=<< ßët:­Vkmmm[QQ‘D"L"„^¼xáææF3 C­³³3BH.—;99·ììlWWWðÑ¡¼ ­ÚÛÛedd#„Ôjunn.Ƙã8¡PXPP`kk‹ÊÈÈ@A]eeeéõzWWלœ™LæèèˆR©Tr¹ÂV©R^o“5³k×®%K–ðuÔJ¥2??Ÿ†„ÄÄÄÂÂB…Báéé yHNNvvvÎÈȰ²²‚o‹ŠŠ ,xÃgffÒÅ 8ÒFAÙØØØÛÛ„¥Õ%s_éõz•Ju÷îÝââb¹\NË a*Uª˜ÔÃët:FsçΕJ•››ëéé‰1 …üÖ„°aè~öööæfͼ¼<•Jemm ýº,Ë|}}©7F£×ë­¬¬h1«T©b2ÂÌÌÌG¥§§k4èŠAzþü9­½‚‚{{{Ä !UªTá×FéVAXXØ/¿üâééÙ¤I¥R¹oß>FCß»rA«Õfgg#„ÜÝÝ322¼½½ù…‚ŽäááÁI1ÆùùùvvvS_Úåä丸¸ÐRTTdoo¯Óéèâèèhee¥V«9޳²²2ChºÀÝÝ’KNNþðà xÁÕj5ì‚ 3‹D"222ÀógÏ\]]Ín‡þÒqcœ““û {^Ûââb‰D¢Ñhrss !®®®"‘¨¸¸c|çÎxY Ï@aa¡R©„J6)€J$’† ÒêE 0àÿû'--­fÍš=bó+^/=úùçŸAl‡ÑmΜ92™ìûï¿ÏÎΆ|ذa5š1cLf„;;»eË–mݺÕÏÏ.àè|oŒ——×W_}åå啜œìèèkÖÈÈÈû÷ï#„¶lÙÞ~úé'//¯ & „ÆŽ;bĈàà`ãØ–/_Þ¹sçÆÿù–ÌÓÓò?}útÓE"Ñøñãk׮ݢE‹ÄÄDx¥}}}‹‹‹¯]»¶eËøúŸã¸Æ1!dkk #Iã8î»ï¾+**‚iÀÙÙyÑ¢E/^Œ/((P(¡¦M›:ÔÃÃcâĉöööYYY"‘è›o¾ñööž1c„%„ˆÅâÕ«W›«±X¬Õjù³éµk×¶oß. 9Žsss[°`ÁÉ“'ÏŸ?Ÿ——7cÆŒâââM›6!„æÎû÷ßËd²‹/6oÞü³Ï>C]¾|yïÞ½0ryxxÌ›7ïäÉ“ ígÎPGïØ±ãâÅ‹ëÖ­3YºiÓ¦ÅÇÇ/_¾\"‘|öÙg-[¶DíÝ»7>>êªFS§Nýý÷ß/_¾ ½Å××·Aƒ=zô@ÿÞ"²f …#GŽLLL éÕ«—££ã¹sçž?nggW¾ã@BBÂСC[¶léééùìÙ3??¿ï¾û!4{ölá0ƽ{÷n׮ݴiÓFŽÙ¼ys•JõÕW_mÚ´‰Nù|6lH?²ÍÌÌœ>}úÖ­[årùwß}²šµµõ’%KŽ;VPPðùçŸÃK cÈÖ­[ccc©Ð0hРæÍ›ÃËîŽ;BOž<ùé§ŸàÝç8®víÚ“'O^¿~½D"ÉÈÈÐh4`È!Mš4ñôô7nœ§§grr²½½ý²eËL ñVVVüqï‹/¾ 2÷B¿ýöÛ½{÷”JåÎ;¡rÖ­[wëÖ--<<<ÂÂÂBBB=z4mÚ´ââbt—.]š°cÇN7}úô¼¼<:ô!„F޹k×.sC¨ÝÆ9ŽƒNJJ‚ + ™L~ÞCýÓ{„uuûõÂOWÔ¬Zƒã sržäæ&üûûW¯þ믿._¾yçÎòزeËÉ“'éŸ=Ñ!;;\îܹ3oÞ­P(ÆŽK±À$~ø!]ì6hЀ.þòòò† ~À%::zçÎ………ÔÑ€%K–ÄÇÇgffΘ1ÄŸ—.]Ú²e !dÆ 1110 ÃHGiÙ²%!dûöíÑÑÑJ¥²sçÎ4ìÓ§O-ÔTTTTTýÓ ¼öööôÙÏÏúoÛ·o?~ü¸#š£oß¾ …‚:¦¦¦BCh4pùá‡nÞ¼™––6yòdêM$BºvíJ½=zô¨mÛ¶ bmmÍÿ344”æG¯×wèÐÁBX‰DÂÿ³U«VIIIð¬R©zöìiàç믿NOO7U£F!ëׯ¿xñbAAÁ€èOvvv|ŸjµÚÑÑ111ñçŸ6×ÓÀqôèÑYYYæêzuõêÕ jžï­FæÊž““ÒŒI"##—/_NÇ-[¶Ü¿ÿÖ­[ü6-âââV¬XA©W¯-”^¯çWÅ Aƒàyøðá„jÕªñ=ñlذáöíÛÏŸ?=z´‡~ýúéõúnݺA]uíÚÞM___êM.—O˜0²$‹è‹µwï^ƒ† „…BÈØýû÷'MšY¥Zµje²­a²ÏÉÉçÿýï , „Ô©S‡zhÖ¬mY…BÑ¿ú:øù‡/i>øÀ¸Ãós’ýøñc mžÝÝÝu:¸ 6ìÅ‹Ô ­Œ·ÎåË—ó•_ú IDATóóéŸ*•jûöí ;°iÓ&¹<ÏxöÏÍMŽ?o/³]º²Ïáa{Q:Ó0dÈ_ýÕÅÅ4o°šä8ŽªA¶‘Ÿ¿-G•f ++륛»|u+¶ hœ0p9räÒ¥KðZÞùãï4gffJ$(HXXÝ^^^°ÜÉÈÈí´££cݺu]þ%((!”ššzöìÙ7Ò+ùIóË ñd2lee5fÌ{{{™LöðáC Eà8Ž¿IY´h‘£££‹‹‹‡‡GAAqMÒŒÑ Œf`Μ9NNN6Y@ë@ÃúøøP ?ó`ùòå®®®...ÎÎΰ# `Ú³|9£Áñ.~ºz½^P‚»âhX½^ïïïoV£Ñ¸¹¹A«ýöÛo/UÎsg!]¸“’’FŽùõ×_›ëiàHÇkpá8®_¿~“*Uª@MÖ®];99ùÁƒÏž=ƒc:4¬A?/í©ˆ >"”J¥¯ï”.´¿ÆŠ‹‹ ¤îîîtLˆŒŒôõõ}øð!Ý&0GAAÿðÁ¹sçd2™‹‹‹››ÛîÝ»!9GGG‹‹‹½½½BnnnÐ]\\jÔ¨Q³fM¨ŠÊåòS§Nñû<_+C‚@)êԩùø#¹6ØÖä{< ™¹sçÁàu¨W¯Þ³gÏHh¸zõêÊ•+srrrrr´Z-Íø$}† ]µZíîî>vìX???bJ5"„`ô‡qc~üøÅ‹IIIr¹<''çèÑ£4çT•1^°`Élètºˆˆˆìì윜œÜÜ\8î@5Ÿã#FXV~BíaŒGBq±Xlù›R¨jŒ±å¯H^¼x­VXXH'0“¨Õjãƒr|Ic¼mÛ¶¥K—;vlÀ€ ˜‹M¡PÀ…ß~ûM­V9r$<<r²jÕ*رcÇ}ûöEGGoÞ¼9!!/zΜ9Ó\µ—•JµhÑ¢iÓ¦¶jÕ ½f“|9µzõêùùùPÒž={Âî!dðàÁ©©©tÁä¦ì ¬\¹ÒÝÝÞ ¶mÛªTªœœœ/^ÀôLÙ¶m[­Zµbbb@×…züø1tE`ܸqà®Õj!{¨V«åËŽ/2Ëv%yÕªUifàtdÆÎÎŽŽ]¡nݺíÞ½;::úÏ?ÿ<{ö¬å´h‡7n=2²ÿþ‰'š«O•J5iÒ$Ø• ~†>aÂØÅ=z´És— ¶=Qþ´k×N*•Âi¥RI±±±¡¿&$$Ìš5‹râÄ ôï™þù'Õ¹Á‹T­Z5úIº1°µš´ÚµkS]}çÁÅÕÕ•jÞ8i.ÂjÕª¶ÇÍÍ ‚À¤K±#GŽlÞ¼Ù@]L©[·.-/uû ÂΟ?_$‰ÅbX`ggg(¯X,6Pä‚râÆ„3fˆÅbÈ3Ý‚ýpÉÊÊjÚ´©…R€ óݰ€tùÝÉ$J¥ÂÂî l1 …özSí£Z­¦Ž_|ñ…qÎ)pÉ L&3»èZ¶AÍñ®oO`ëêö£îë’i½%dÍßÉ ry¶±€™­=qâ8|–˜˜Ø´iÓ€€€r_ ³|½Ÿ»ÉŽé¢Ç8ˆ±7þÿ‹u¨AÐióõx–Óå1ö .ð+ÖÀ›¹äL¦k•Iô²ëzL–¥Zµj)))&ÃDÎwá{6®R“ gêbPiÊk¡·XøÉ ¬qTæÂòû‰…t-wŒ†5ÙCL®PéO&ëtfôîØ¢¢¢qãÆmÞ¼!4qâÄ•+WZˆ<777**Ê¤Š¥T©GZ!ÆJu~]YΞA$%é4B“ç¥}À\k?%ÉÃK»™ÁŸ|õObbâ¦OŸn<îYîŠ/}SŒkøÍwÆK‰ €C» FEE…‡‡Ó#«”ÈÈÈ>}úbâÚ•'ORÚ¶è:õá‚„„[ûm«@_Ot8ú§9wcGsALz3Â÷CK—<]~“qÒ_i´ÞÌ%g2]ã³Æ.¨”f÷`(III¡CÉDMº\Û`.Ã&] *­„Á-_ec!¬åqи /í~%é/ k²‡X®s5°cÇŽž={ÂŽŒD"O!+W®|iñKX¥ol4°P!üŸ,gÏ ’’t¡ÉÎóÒ>`.ó–GžÒvs~öìÙÓ½{w8àbkkK÷_:î<”¼«”¤•«†åÑŠñAéÒ¥K›6mhƒÒ Xå¼' OŸ>Ô€ˆ@ Éd¬0Þ²ÐÀqÿl?ƒÁ¨°ðOÑZ¦¨¨ÈÚÚZ¡P°£ï• 84ÊxŸ×o_hÐjµqqqLte0* fÍšW¯^e¯6ƒQ9 §޲Р•JÛµkÇ®g0*r¹B²W›Á¨À7ðBh b­Â`TʱÆÀ…mŠ3ŒWŒ7I™ç­’9f¤ ß|éÞ˜ñðáC­VkìîïïoÎêƒÁ¨|X0Þ•å/ÆøÀ¥îâØ¤wS–$\hýÊuéÒ¥Õ«WWüu|AAA}#!`lŒÁ`0MƒQ±Ô ü½v“·Ó SªuŽã´Zí‰'èmÆ÷Û‡5yÓT.Ë2Ξñm?&/ÿy©*Âä½dÆ5PÂØ*¥‚„Á`0Mã=U3Ô­[×ÏÏïüùóÔ¥I“&—.]òõõõóó[¹r%¨"Ö®]ëçççïïïää„x{|“ãàà`˜í²²²À<1ÆxùòåÕ«W÷ññ¹ví½²¢zõêþþþþþþæL-} ´ZmŸ>}öîÝ{þüyŒqNN޳³óàÁƒÁ„˜@ ÈÍͽpáÂ'Ÿ|B-”§ròäÉ.]º@éÂÃÃCCCmllÖ¬YÃ,!ÏŸ?wwwÛi/^¼3fÌúõëÁàxëܹs«V­ØAƒÁ„F¥Õ4 „T*••p°ìEoí…³ð+ÇqEEE%?ÌÈß#ذaÃ/¿ü‚rqq¡öú4ñ…í4{p‡&ÆÏš5 ¢U©T ùP(ß~û-˜UìÒ¥‹•••P(Ü¿ÿýû÷ÁZ˜…¿‹‹Ë„ ÀÜ ‡<BB('''++ ®R© KEEE‹-R«ÕB¡0..Žõ(ƒÁ„Æû+O¼&ÔjuÿþýéŸ0Ù—¾}û.X°,LŠD¢… BnÁ*!dàÀ Ü´k×níÚµÙÙÙ_~ùe©²ûôéÓþýûB|}}§OŸŽÌØk°³³4hPQQÆäÛqf0 &40*)))™™™ÉÉÉ~~~è_;™T¯€ûÝOŸ>å8ÎÁÁÁßß´ôÉÉÉYYYB¡0%%¥Zµj!ooïÜÜÜ‚‚‚/^À®¿X,Öét)))"‘húôépvÁÝÝŒÃ|ïááa2oÔq•*U¨£J¥²¶¶Öëõîîî €É`¾¬ÃqœµµõÓ§Oá–ÕäädÈ¡1999³gÏ>|8Ø:z½^(ZYYÉd²~ýúAœ—@Cr>>>VVV`­ØÍÍ­l’–R©4ˆœZ!g0Lh`0*ëÖ­ƒƒ~kÖ¬ùñÇBóçϧ¿†……¹ººº¸¸tîÜE*•J¹\Zúµkׂ<±víÚ¥K—r—œœ_4øF±$Ÿš;4PÂo-¬Ñù™±üõ£É´Œ‹c€³³3ÿR I¼´È&“ÈÍÍ…k¤KR9 £â@-P¨Õꨨ¨ððpããY‘‘‘}úô%$Ï8’'ORÚ¶è:õá‚„„[ûmc𯻠Û}šÈ0ø³„a-{+¡‹ñ¯Ì‹[ÈçKÃ"„êÔ©óÒ̘Œ¡´)Iå0Œ÷“²ÜÓ 1QƒÁx ‹†×?;É`T2^‡ñ¹ROÿã .\ºt‰µƒQÉÆ½^ÿ믿²ª`0*oYhÐëõp·k ƒÁ`0*2:î- ô+sƒÁ`0™×qñkY¶'XK0 ƒQ‘y3XÅ`0 ƒ ƒÁ`0˜ÐÀ`0 ãSº3 „Ú d0 ƒñ¶xMK'4‚ÔÔT¥RÉŽC2 ƒQa!„4lØð- c…BññÇë9Ö" ƒÁ`T\tZõ[‹tnˆ°a0 £‚‚ÓËÿîù2Y‘ „™ÐÀ`0 F…ä5MÑìT#ƒÁ`0 &40 ƒÁ`BƒÁ`0 &40 ƒÁ¨ˆˆÊ7:Bˆµ ‰‘V‹Š‹»ÎÁ`0ŒJC9k¤2<~pxwÙ÷_ —H˜ÄÀ`0 þE$þçƈ¢V‘Õ컕¡JO}‚0BB„"$# EH(z]ö: ƒÁ`¼Vʾ=AQ+§Œì%³¶Ñkµ_NžWïÃF¡b%â8=þ×D…T†×,žóàÎÞƒG_:s„òúuy¹lç‚Á`0Œ÷Fh°±Å=šÕ;zý©RQ,K"†uûñ׃b±Ä0:´ë×c×SW-œÞwÈW!ËfÎ5y.S70 ƒñ¾ #­V#“!½Îв)꘲Ȭ_© !‚Äb GˆN§cõÎ`0 Æ;ûä’Á`0 Æ$üeß®Z­†U(ƒÁ`0••²oOrQçÿîݺ‘•µ­N§™øýOb±D,F+æO»kcg߯ÝG»N'èu¨YëN:-š4g‘Vƒ²ž§û×®Ï40 ƒñ  lììwžŽG!ŒtZ¤×Mü~ñ?_N`¤V-BsVlR«þù\µŠW×Þƒt:öõƒÁ`0ïЀBiÔ|1#„øÇÁE«Aÿ/"¤×#&10 ƒñÎÁB2 ƒÁ`BƒÁ`0 &40 ƒÁ`BƒÁ`0 &40 ƒÁxg)ë×±»ŒJ¯!±› Fù BòtBÇjÁ¨4àâbåÝ»w›7æô¬6ŒÊ@êó #4T±cÍÁ`T*rõªŒ¤›UÚ5fUÁ`TR^Æ€ˆU+£¢AÈ?†Ò‡Ò,yØÒ&ñ*y†ŸÊ+ÅW̧imƒùŸŠ‹‹‰©-I™L&°£Q Æû{ÛŒñW_}5qâÄÒN®ã;wöë×oáÂ…% ‹1ŽŠŠÊÉÉyõ<:töìÙÆéÒ¹cñv¯Ců[·® æéïܹ£P( þËýû÷år9ë± Œ·É’%K,XP†€Ÿ|òÉÎ;ׯ__ò ýõ—B¡xõ<¯^½zêÔ©|­VÛ»wo¾”°iÓ¦·^·GŽÑëK}lA ¸»»Wù/R©T«Õ²îÊ`¼?°í F…#99ùñãÇŽŽŽAAAàrïÞ½zõê8qB"‘ „Ú¶m jö“'OŠÅbBˆ¿¿¿ŸŸBH*•Äv÷îÝúõëÃÌ}ùòåæÍ›óÃZYYYYYÏ'Ož}Z,s÷ᇺ»»çååi4wwwH®aÆ¡øøøFAé¤R)”W¯×Ÿ={V$¹¹¹WƒÁ`0Mã]E.—§§§·k׎ºÌœ93444333)))))iéÒ¥ãþýû?þ<))éñãÇK—.}öì™ÉØFMÖ-Z´@AØôôô¤¤¤ëׯ¯Y³F ¤§§¯[·îñãÇIIIýû÷7·Ð¼ysú¼páBØÚxñâEjjjïÞ½éOééé?V*•IIIOž<ÇÂÂÂyóæt²`Á‚¢¢"ãø1Æ3gÎLIIÂ&$$¬[·cÍ¥k'èEäÇrry6.‚¹tõz½P(4ˆ¼„EËÍÍŠŠ9rdI…Á`T|bccìííáOµZ.“É |FFFöéÓ—<ãHžHz`<1?{öL&“I¥ÒÄÄDȪ««+Æ8&&¦l aÎ&_bxøðáG}T¿~}‘H$‘H<<<‚ƒƒÿý÷2Ï@pîÛ ¦OŸnkk[*]4TŽ\.·²²jÚ´©@ J¥‰¤E‹gΜãìå%:€±V¹\Îwäk_*ˆ¸ðüùsÚuU*ˆzîîîžžž*•ê äÄÊʪoß¾5L1~üxsFäoß¾]£F jä…v &40¯kåÍqœñ8vJÖÀƒL&37‚—dùb2Qz{R¿~ý òÌJ,ä977wË–-–§+ƒ°ð§Áñ%syÏ™™™üñõSæò¾”BEáÑMGç÷™A!"™‰f¦>J54}}}U*•Z­†»à8ŽËÎÎÞ±c‡¹Ø\eÒ†>|¸…BaŒÕét .€aë6mÚнÆÀÀ@U !jµ:--müøñ&×ãàà`¥R  Å!CXZR«ÕZ­öÅ‹?Æ:ôùóç. å{÷îU«ÕíÚµS«Õyyy i£W®\Ñét·oß~öìY\\œF£¡aK>+Ÿ;w.00²Gñ÷÷™æcW IDATG999}ðÁÃÇ8cìéé .ÇEEEB¶oß®V«Ÿû RY¼x1ˆq_ý5M·{÷îã3fÀ«Ž Ö@Znnn5jÔxiyýüüV­Zeà 6­Výü Pô ¢=zԤĀ1ŽŠŠ¢.?üðCùž˜©ø°¯'oˆ~ø!<<ÌKrM5½ð*r'‰D"ÑÎ;Ád%­Fy{{wëÖ._à*uþjfþüùæ”Þööö`‘þܺu+ú¯á(Œ±P(T©T‹-2ž~!Ô$&¤˜=vìXÈÈ#œ_åB$±XLã'„<~üd©»wïBµäççÛÚÚ"„ø¡ø3ŠâÏÐVVV³gÏF)•ÊÞ½{kµZ¡Pxâĉ2J~«D¦¶™ BB¤Çÿ_ÿ*•êòåËÇ]¹r¥eË–nnnæâ´²²¢ÏB¡dÁÈÈHØ-æO¥ áñœÐ`òS¾AN@ —Ëç͛ަL™+æ+Vœ={Ò¥BF^^žF£1N—?OH$ê™2vj<ñ¸ˆD"~„ìÒ¥ ôÒ5j¬X±!”––oH$‚U8Ƹ°°°°°ZQ§™ä¯à©@ÀOÚÊÊŠoz—B¡ˆŽŽoJ¥,ܽ{÷“O>Ñëõb±855!4lذ3fÀ9 …BqãÆ jQeöìÙ³gÏ.Û×4Iß¾}<øŠöîK«õóó ;u긴jÕ*88ظ`/îDGGß¾}ûÃ?dBƒQίe£FvìØ#£P(lÕªÕ… L½{÷^µjÛ¶mƒiûöíT†°`êúU(ÉúƘ!!¯iÛ•ªåË+B0•I'þd\r4Í”˜)#?i¨lÀ¨onßzêz|Áe̘1&LóW¥šBâããóóó÷ìÙCõL%œzB¹¹¹ÎÎÎîZ­öøñãC† 1nnBHhh(BèÔ©SŽŽŽ»wïFȼÊÇ¥° V·n]c÷_~ù¥fÍš4‰=z„……ABwîÜY¶lÙ”)SjÖ¬¹oß¾W<X’üxøè£öïßÏO·fÍšô°ŽL&óññ)ÛaaƒŒ ƒïߘ!4xð`*4¬Y³ÆÜ èééiàÒ¢E jzž F¹½–3gÎ „‰öDá§áÇ÷íÛW¯×+ ;;;™L&‹O:EÑjµ]ºtA5jÔèܹsT=еkW„PëÖ­Ïœ9£R©”Jåܹs d2é&Mš;v Þ½^öìÙ+V´lÙ‚†ÃÊÊJ¡Pð%þ²ÏÓÓóøñã*•êÊ•+‹/†ŒñÇ{{û‚‚‚#GŽÀJ¯>‹ŽŽNHHÈËË+..îØ±£Éì999åää@XkkëI“&ݼy“/¾Ðä>þøãÓ§O«Õj8á’Ó7222233= uÕªU«'N@Yòòò²²²"""‚‚‚N:¥Ñh8Ž ôññ)C#zyyµ iù±òãë¶×ÿ9Iþ9ßàªuý²î—q(Î`ª6˜„¢££oܸ‘––¦Óé:uê„jÖ¬ v$‰]~~>ÝÞ±c ÎÄ?~\¡P$&&Κ5ˤ`š’’Bß hjjjXX˜‹‹‹q­Ò¼¹¸¸ÄÇÇŸ9sF,ÿú믴ˆÅb™LvìØ±œœœÜÜܯ¿þº°°ðÚµk:îܹsµjÕòöö®R¥ÊåË—ihß¾½ÉI100ðþýûJ¥ÒÚÚ&oø?77×ÛÛ;44”n1tèÐaêÔ©Ð ²²²ªU«†ª_¿þÉ“'µZ­^¯oÚ´©L&Óëõ EûàƒøÚ…Ç?~üøäÉ“¾¾¾-[¶ǦM›=zT,/Y²äÌ™3~~~·o߆sR©$'~Çã8æoèQz½¾eË–2™ì÷ßW«Õ^^^ €¶hÑ‚6ô'Ÿ|ràÀ—ªë‹‹‹Oœ8aooŸŸŸöìÙÂÂÂ=z_¸p¬½C |ccÔ矾lÙ²;wîtéÒ¥víÚ&ýÄÆÆŸRR*•ûöí3y¢RÂÎ40Þ¦vòóóóóóår9h\BëׯñâE~~~ß¾}ýýý]\\Æ'—Ëóóóóòò`;Låÿ DóôéÓüü|¡PøôéS“g! ! .,,,„€J¥rÅŠü°r¹|Ô¨QîîîU«Vå‹ ãàÊ•+_¼x¡Ñh@bppp˜0a?•š5k†‡‡COŸ>‰‰A3???44´zõê"õë×ïܹ3„MNN¾yó&BhãÆÔƒ££#$wüøñ´´´üüüœœœÙ³gƒb_©Tæåå-[¶ ¾&'„üú믙™™¡MDD!äðáÃéééàXæóÞ„:×¹hsqQÊ"/­ $BcsÇ®M_›ïœëk0UŸŸÙµk×.]º07lÓ1/MÓ7oÞd´XŒñéÓ§srrÌv¶þË/¿B‚ÞÞÞ£G†ý+ÅÅÅJá€Ú·o/–/_ξiËËËgÏž séLß­_¿jwêÔ)˜ÌhÚ´)¤VPPpêÔ)„Sk„Pûöíß~ûmš¦÷ìÙSRRÏ#¬qLœ8±qãÆ [XXxüøq¦¾_|ñ{ÉßF£ sèС¢¢"x¨wîÜ™››+“É åj7?ÛBhõêÕðÃLjšðÅ_˜O„ †M›6½>[° @<#u©ÛAl÷¨ôœ$©´Ì|N¦¬LwñâØí’’’g¨„§Ÿ žÏê ‰$..l¿^+++322`_l‡´ Q;©ë‰QH(ÆöíÛa›‚N§1b„——W½²¹ÿ~8¿ƒjÚ´iÿþýÉí÷R¸}û63å ]3uêTöÍüí·ßNœ8ñÎ;ÁÁÁgΜ1±~ÁLªMœ8ñûï¿gNׂ‚‚`Ì$ÅÅÅ >v«°‰‰‰9rMW˜'’Û»ÛàˆŒÈ¤¤äS‘å ÂËäõ™ÓkHzž³³s§N˜5Ri#…©zR<š¦á}½Õ’M†–úc„ûuÃh4fdd°¿[ú÷žÎüd6¨Ò4——×¹sgk=U^^þâwc¼ˆÒ@x™Ôd&“ðbxš=hõDc`æz®u½ZnÀƒ] v ût.BhÈ!ÎZÛHmĈõ­‚Ïc·.JƒF£ùã?ÈN 40Úµk÷矒v æË/Giàp8¾¾¾d)š@h0€ñÍììì6mÚ¼>[º„†ýP———× ¥Ëå2GŠ BÃ@*•ÆÇÇ¿¾} „ׄÒÒÒz¡4^0ì³XµZbǯ¡lݲ°häÎF™Í¥^é½`Ϫ"Öóyç[“à¬ÅO²RI ¼>; ¯`0ޱz[+ÁÛ·o/[¶,**ª†²ã»wïæååÕ<‹7ZÜÛµeË–M›6YÌc|øða·=7nÜ())y‰í Óòu˜œÇŸ9sæóÏ??zôèÓŒ ìÆÔjµsæÌ)**²ÿرcË—/?}úôó¹ÿþû¢Âÿ’œœlñ@ JáeòöÛo7®‚Í›7Ÿ?¾Eָ߯qãFfffÍãGDDX 6l˜•ß|óIÈåË—?~ü2ŠjݺuÝ,Þ‡‡‡O›6míÚµOY¦1¹\îÇlÍÕCÏž=?üðÃ7¾€Æñ÷÷oú_êìûŠ@ ¼Šå‰W…B¡ÕjÙFÊÀÀ>Ø¡iºyóæ0·Ì˜ÜqttôòòB999999±?CËËËœœÀ$snnn“&Mز`VbÊårøô7¶}÷=zôcìä侉Á'$SfÈ";;E¶hÑ‚›!_‡Ããñ ýÊÊJ0ü1B%%%žžžLí­Í¥K¥R°Œ ²-++‹1* n$sssÝÝÝ‹‹‹BnnnÎÎÎZ­¶¢¢"++ ¬7oÞc\XXبQ#¥Rùøñc‡`ÒÎîîîàéZ›¢1ºEQŒ¬y™KKKe2ô#˜••eâA§Óåää@ˆ——x±S¾&ùB_€æýk4³²²(Šrppàr¹Ïjf‚¬MDi Ô/=zÉ,*¯[·.77Æ!„ŸŸßœ9sV¬XÁ|ö)•ÊÙ³g›»ÆoÙÕ«Wƒ÷¦M›Â0³|ùrƺðÕ«W7nܨÑh–/_ΜØÑét[¶l±VÂ%K–p8°ç¿xñb__ß»wï^ºtiãÆ` &ð¯_¿×2™L("„–-[ÆTêüùó”Ëå+W®d´ 0Ñ:mÚ4OOO777ˆÜ®];‹ž&¤RéêÕ«÷åååûöí;vìØfÂÂÂFÝ´iSæ›^£Ñ¬^½Z«ÕnÙ²Å`0ìØ±£¼¼|ëÖ­\.÷Ò¥Kiii2™ <8wéÒeøðá‹-b¼`h4šÈÈH¿M†Ò¤¦¦2cyhhèØ±cÍË\PP°eËðZÉ6“°gÏž«W¯îÚµ‹1£$—Ë£¢¢ GÔjõÆÍýNaŒwíÚ•››ËäÛ¿ÿ~ýú-^¼"ƒ÷Â-[¶°ý|BMˆh¾ŒÌÛÚÜ?Ðh”——gK$9&ÿÒÓ3vìØýúõ˜˜˜û÷ïÓ„…Ñh„ •ˆˆˆ„„æ§¿¿?c¶ P©TjµšùÉãñ˜ëÙ³gÂ5Ø;3‘]·nÝ•+W*++?øà&P,[+![vÛ¶m L™œœ˜?=Z.—ÃuIIIxx¸‰lDDDRRRAA¸KÀ£ñ»ï¾›ÍöèÑÃbI=zÁü,**¢iºoß¾ƒBôz}ÿþýMsÁ‚Lâ솂Z0%T*• 0‰3cÆ ÈhÓ¦ sݪU+vÙ$‰Å2ÿùçŸQQQ& YoÙ²åæÍ›¥ÆÇ4&8Ûd®›5kÆ\çççòÉ'4M{xx@ȵk×vîÜi1Íòòòèèhk½|ëÖ-óÀû÷ﳫO êׯ_¯¬¬d~ªÕê#GލT*ó˜ûöí“J+ÌG‰$çöí«b{ÇÈüm#œL‰É×F½Çâô/MÓžžž&qØ1ŸÆ¦ 0ãC‡]¹rn)ggç§,3ãfÆ0óý†à„¢¨­[·‚‡bš¦ýüü`­ñG.t«Í—¦ia»·0 k²ÓÚÑ6.\0—µXš¦SSS½½½áƒ^ ܺuËv™Ù™2OØ1/^¼8vìX¡PHQT~~þ¾}û,&Èn¦­Zµj•’’¢V«óòò<<<ÈcE êÙYßaFŽjÙcLRRÒ;w,Ê* Æ Û4ÃêÕ«íììŒFã¸qãòóó sssknÎËb¾r¹\$AàøñãášÍ–-[8Ž^¯Ÿ?~AAä[«-™0£Àd=~üx„L&/Ò!;;;'BZ­dÇŽk­ÁÙ[ÿ 3!b2ÂGDDCEÒÓÓGŽi15NЬ,0Ê ¨ÐSðóí·ß–J¥¹¹¹° Âä )ÀOöq±X ~[´h‘˜˜xçΗQ£F=+Ël&w Bƒ‡Ì4¼3 ÇŽƒ£ãû÷ïét:ö{†1Fƒ1†qkðàÁà˜866vòäÉ ›‘‘ѼyóØØX__ß’’ƒÁ •Jƒ‚‚«þ­95,a½¢²²òëÑÑÑ?üð‚1^¿~=øÎ~ñ]F ˆÒ`õ •ùyðàAš¦a›·µO^k²Ö"oÚ´É¢ ú×eB¨k×®¶‹!ìï-&°&UƒÈC† ±Ql&œ5°e{õêŶÃS“ÉÛ»AØ•&MšdQÃá0ÃS<ÀÄ%£µORH6+++%%â˜gd[ÖvˆEY&ø¹¶Ùö-d;#‹·É´ ˆ€÷ðšÜWpÁ¸±vÛÛ­íÈ1þꫯöîݡÁoذÁßßßh4fggO›6­ªªŠ¼X ¢4¼c, }|||||zõêŸÑwî܉D-Z´[¹㸸¸Ç»¸¸øøøØÛÛƒ—aŒ±ƒƒÈ0ÀÚ'8ÆxÀ€>>>ëׯg %…††ªT*ÈúÝwß…Ïk{{û´´4±X î1Æýúõƒ,DkÒ¤ EQŸ~ú©··÷˜1c pöìÙ“&Mòññ‰D999 Û£Gutt„âAØf’1ƧOŸvuuõññ …EEEão¾ùÆËËË`0øúúŠÅb¦Ø|>ßÝÝíáÇtssƒâI$Œñš5kBööö>>>ÎÎÎÖšE¡P,Z´ˆI¹sçÎP‘6mÚxyy>}þCÇóññ ÿRR©T @ñAii)ô¦X,æóù>>>žžž`ÑbwlݺÕÃÃcàÀŒý%°1¹øøøØÝ¶m›———ã {ôèÑ¡7n8;;ûùù¬\.‡{ÃÓÓsÇŽãÌÌLp‡áëëkoo¯ÑhÀÛ“··7d`ãZ±bÄÝì0º»»ƒl«V­ õºtérøðaOOO#GŽ`ŒïܹóÝwß1v™Ú´if°¡Ç}||‚ƒƒA¦^BBBÜÝÝO:…1NLLÁ××—Ïç3·““È‚WŒq‡(Šjݺµ««ëÏ?ÿ\·½ `µzðàÁË—/gߢ˖-7nø …åååäÅJ 4Xê¹kl¶âÜÜÜõë×3?á =z±œ,Ã5ÛýñÇwìØaÃ÷´F£™8q"èííݹsg¸NHHؾ};D{ã7زkÖ¬IMM5ñã øþûïiš¾|ùrLL „0n޽½½iš^ºt)Ûݳ££#s=`À­Vkâpqqa®A?`âÀÿ}úôaD”J%8)hšþì³ÏØmåëëk±Y*++ÇŽKÓôãÇ'×rrrò¶mÛ,ºÆFݾ}Û¤xÀÌ™3aÀ‚‚‚l»g‹øá‡LÛÒ4ý¿ÿýÏ¢lzzú’%K˜ŸÎÎÎL© .4MwïÞÝDjáÂ…YYYæ÷MÓ:t`ÿרæÜ¼y¦©Ø]Év­Óé† %Ù¸q#N˜0¡¬¬ìæÍ››7o†Zëõzš¦›4iÂÈ*•Ê &Ð4ýäÉ„¸µ}÷Ýwe2™IûC"^^^Œ¬T*>}:<;è_Ï o½õÛmz ]c³»æØ±cgΜ1¿íišž7o^^^qIL ר/‡M›6-X°>Œ7nÁvpÀD«ªªJLLdþäàà€bûQlݺuëÖ­-šÐ‡…BÁþ“L&cÔh4<þjb÷F,¯ZµÊÇÇ!Äçó™9ÛfÍš/A???˜¥ïÓ§O§Nà¯P<{{{•JÅ$eîõ‘)^zzúŽ;ìììx<{ÛÄ™$üo⸒íaH("„*** ã¡ü%Ú´ vFUUUÖ>U÷íÛÇ|ƒš|”K$ð ùBa,Ö×<°¼¼\«Õ2Þ"¬ÉzxxhµÚ… "„är¹T*5 0uôèQö˜#…3fÌ …ãóçÏÏ›7Ïb‚žžžLÿ‹Ñ8{ó¦\.7iX…B²"‘hñâÅp_q8Œq§N,X¹´mÛöñãÇï’%KàfS(pÃÈd²Õ«WÃ=6nÜ8sçÐt^^^pTTTÀAm™L¶iÓ&hŠ?üñÆYÛ™ò•E ¼æÔk¥¦éO>ù$;;†™ÌĮ̀¨¨9sæX|ÉåògøR³æÐ½nÉ|À¸ïbÆxÝcŒÁï"zŠcz½>""b÷îÝZ­ÖÍÍ-66ÖbajîRc\YYimÜ5IÙâµ Ìw 0ƒ>²¦U[fµZmîdÅggçõë׃OH±Xìï—ÇN„Ãá|ðÁ!ÿääd™L~/MjÇh6jµzþüùÌ_ŸÞRŠEïVW¯^mܸñ™3g–,Y!jµzÑ¢EŒnf×h™4M›»©d—yñâÅŒ>êââJ¥d'L˜ðlŸSØ´Ët49@A 4`êõžŒq»ví0Æ …B¡P¨ÕjX0V*•ùùù¡‚‚øªƒ‰Sö@‹jÙ²eNN΃>>Mš4!/VÌ4¼œ™†»wï~öÙgð‰ééé9sæLš¦%Éž={¶nݺgÏž‰'ŠD¢®]»²?a·lÙ‚JLLüôÓOaj×××wÚ´iÖ>Ç/_¾\\\ܳgÏÇõÕW¡Í›73mÞ¼9,1Àæ‰U«VéõúK—.Ñ4ýÑGEGGÿý÷ßð…"°ÙMÿþý…Ba\\œF£¹páøÚµkWbb"BH£Ñ\½zŠ;bĈ3gÎ6iÒ„Ãálܸ166–ÃáôîÝ›™i i:11qåÊ•E1+)?~|\\\«V­üýýù|þÊ•+¿ûî;‡£V«!¯Ñ£G³Ï|ñÅßÑÑqÊ”)7nD5 61`ŒÏž=«ÓéœOœ8l4ÓÒÒÚøòÑ IDAT–.]* ¹\nnn.( °œöÙgŸÑ4]PP€šøÔ(ÏþýûGŽ Å8sæÌŠ+ Ê uëÖ!ww÷¡C‡šO0@û#„Š‹‹Fãùóç—/_êµH$jÕªBÈÇÇçí·ß~úG2111%%ÅÎÎN&“ÅÅŵk×î½÷ÞC}öÙgGuuu]ºt)ñ£M 4`° @<#u©ÛAl÷¨ôœ$©´Ìü/+Ó]¼xvb§¤¤„‡‡3ò/@o`—ÇâûÈbóy`kï2sq´–¬4ÙqLþÔ£G?ÿü³&ŶX‚O#kciƒ½w„}†³&Mjþ×:ä[«N¯6°†#YMú·Z©šÜW¶ÄF¾6Ú§Ú[Ôv#H$’¸¸¸iÓ¦Õ°q,ÞfDc ê AAAÌt£F£‰‹‹>|¸ùRoLLÌÈ‘£hºÂ<‘ììÜÞÝGdD&%%Ÿšp¨¾o„4yY|YŒcmÃcͳ¨I²6â˜ü >k[ìšÔ÷idmlݰØ5ÉÂâ_ëomÁv`Í7|Ôöö«USÛî,Û÷^µíSímð”Ãy­ªI $Ä|Û bß¾}¤õ‡Cœb ‰ça¸.3 Z­–1L  AAAäÑ& ̶ô—¬4€É¹úïZ‰@ ÔNWRRâççGÎL 8hýò•;;»¶’@ ¼¤RéÍ›7 @š‚@h$$$<ó4Éž†—C=™§±æ «¶Ñê`ª~6È ëÓzX_ðµAžM@”†MyyùÎ;M,D¡ÿ~~ðàÁKwÄŒ1¾páBµ;Þ1Æ?üðƒmû˜—.]нyóf­öÏƽ{÷:tÈütâ3VŸ>ÁšèUã½{÷îÝ»±¼VîܹüuJ¥2::šñPE Di ;;;???“Ón}ô;äèÑ£`×òå$«eìØ±6TŠË—/§¥¥ùúúž?þáǵ*@‹-æÎk’àÀŸ­Qð?þ¸n ‚¦šèU}ûömÛ¶mÛ¶m{öìÉÄ÷óócûçp8­[·~憜 áÅÀ%Mð4èt:‡ÃLê*•J°ñGQTß¾}Ù“½F£ñÖ­[:N«ÕÚÛÛs8.—Ëápªªª ‚P(´fG¯×3nÀÙ±R©d>Á‘“;B<5Ð4 Þ2á(‰,øcdiÖò …Œ1“|¡ÌEEEÍš5ëß¿FF†B¡€–ÏUà_ÊÄﻡúôév—ÙŸìñññ!…B²Ö¾ì7càÍËh4êõz¨“8¹¾}û¶ÑhwçPµãñxvvvF£Ñ`0ÀfcFV­Vëõú¿ÿþ[¯×ÛpX\½zµG¡Û·oCˆJ¥êÛ·/ÛŽ ŸÏïÙ³§‰F“RŒ‡L‹UV©T\.Z•Ï烽HYèz¨ØíÐ׌7 F–@ ˆÒðBùꫯ ĸ¯‰D0<=úÂ… ŒoC„Ð;3——7~üx¥R¹}ûöÀÀ@wðàÁ‡ÂùøI“&E^ŒFãŠ+RSS1ƃ!88822òÞ½{ëÖ­S«Õ!ƒÁ0eÊ”!C†ÀRáááIIIjµ:00ðí·ß®¬¬Ôëõݺu‹ˆˆHJJZ¿~½V«Õëõ½zõ3Ûõ¡Ï?ÿüÑ£Gàv ||ܾ}{ãÆŒƒ¢™3göïß!dooéÌž=ÄÏŸ?àÀŠ¢ — Œ1â»ï¾Ûd좚PQQñᇪTªqãÆI¥Ò“'OZôÉ1Þ¹sçÅ‹a˜oԨї_~Y\\¼}ûö;v „†~ôèQ±X¼sçÎëׯgffŽ;c|üøq(ÀÊ•+ïÞ½‹1öóóûòË/³²²Ž9²nÝ:„ÐÛo¿}þüy{{ûo¾ùææÍ›>?~<—Ëýî»ïjrWTUUùê÷ßÿîÝ»èÙ³§µÈeee_|ñEII ´ù!C¬ÙdK—.ÍÈÈ iºE‹‘‘‘vvvQQQpHR§Ó½÷Þ{}ôQ›6m:wîܤI“’’­V»téÒöíÛoذ!!!œÅ·jÕ*22²nŽ. ÂëŽ @¼@óedÞÖæþF£¼¼<ÛÜvzzÆŽ;âãã¯_¿sÿþ}â§X¿~ýíÛ·KKK###išvssïV4M>¼ªª ¢AH‡زkÖ¬9räóÓÝݦé6mÚøý‹‡‡ÇåË—u:]=˜hÐø ,ÈÍÍeÁ{5˜@D©T†‡‡Ã'MÓÎÎÎ4MϘ1ãÉ“'LjmÛ¶µXµÊÊÊ1cÆÀµB¡€y‹÷ߟ¼ûùù¹ººzxx4oÞœ]_>ŸŽe2„€ÎÁвeK“ÜÅbqµÏNdùòå>ÌÌÌçé4M=Z&“1% g— \}BÈ‚ ²³³ï$>>>gÏžeGŽŽŽ¯"lD"sýÇÄÆÆZ¬” Ì5bĹ\nR ¤izíÚµ)))?ž={6MÓL´wß}{šP^^Mj¡ÁpýúuæEGÓ´Z­>räˆJ¥2¹oß>©´Â|ô—Hrnß¾*¶wŒÌß6òÇÉ”˜ÌR> ødb>‚Ñ32®Ë8¿Á`èØ±#¾˜7›l"""(Šâóùjµú?þ@q¹\ö.K<<==™U˜”fdiš 2wÈi^l¡PÈçóB|>ŸIpàÀ¡¼¼¼'NxxxôêÕ‹©]ddäš5k8,Ô­am»0ÙêoÛÈ1{ *BˆÃá€^‚ÿÅFõÙ² Óºuë²²2.—ûøñc¦ØL/Û®£½½ý¤I“fΜ ‚6b2WŒÅè‘#Gž;wZn¦xz½^¯×C§—––2SJjµšlÃ$uƒl„|*Ôjµ»»û† `½²²’ŸìììàÏ 90Ã16qºh£Ñ¨T*a=¾zB*•Š=i§0Øþ6Æi¥R ²㯾úÊÚ:=MÓ O`ŒïܹU+((Ðh4ª9uêd ̈URR’––¦ÕjU*Urr23io²–Ϙþ™¨ÆxåÊ•ÖF8DF£‘í!]§Ó‰D"&Ó €õêÕ«ŒZ˜Œ`ß # ÛB‡®ÉpËÖ µÍ•HÈZ©T~ûí·ÐžjµÁwíÚõé÷Z9s³ó_Ëüùó ™Ò&&&2Ñ~þùç—¨U€(I~~>cÿc¼ÿ~ö]vÓm7;Ûoµ…ùý÷ß!°vAÀÒÏ’%Kžù~8võÂÂÂØ?¿úê+ó8ƒáܹsìggg(sqq1„´lÙ²¡>qDi Ú¤‚ÉÏuëÖÑk‚Öd« ¬UaÌS0ùŠe;ߪaÖæã™EYóiš¦wìØAÓtiiiµmXí×vUUÕï¿ÿÎ8ò‘J¥ãž={víÚÅ€ÈD{ca­J(‰¿¿?cƦé)S¦°«LÓtXXXîk³;æ]Œ1ž6mãÓútݺuß~û-MÓ\.¼îU{OÖ¼Ë***† bâ¼­´´”òÙgŸ!„üýýÙgðàÁÌÏÔÔÔ¾}û"„nܸ1yòdLOO'3 Di êµÆ€1 ëׯŒ?nÑ¢E·nݘÿþ»mÛ¶aaa¡¡¡}úôéÒ¥ ¼ !0,,lРAc£ÑXYYÙ²e˰°°?þø£VÃÆxíÚµà‡ùàÆëtºæÍ›Cî;wîÄ—””ìÞ½›±@5pà@(O—.] <:ubÆ3 Û¶m‹1îܹsóæÍ!;Œñÿþ÷? gÌlÿùçŸíÛ·ïСÑ#GØzÛ©ƸcÇŽ Û£G¶9Ô÷ßâĉ6ÁÕÕµ]»vaaaãÀCBB,XÀ?~üñGÈ+99y„ /÷¶quu…‹ß~û ªÙ»wïÐÐЋ/š´Û*ÆøôéÓíÛ· kÞ¼98p±–EjjjHHHhhè7ß|ƒ1.//ŠŠ‚öß´iÛ>ãvçСCâàà P(BS¦L À8p:cüñÇ#„îÞ½Ô¹sgv—M:u̘1ÖºìÏ?ÿ´Öþp‹:~r¹Üýû÷‡†††„„$$$°c‚縸8„РAƒÎŸ?OÞE!! „úƸuëÖ©©©ðS"‘LŸ>=::Ú××7##ƒí`¬cÇŽŒ[Ô.]º$&&"„š6mš““EEEŸ|òÉŽ;š5kV^^C‡íÒ¥ ¸-­!ÉÉɃüq8œ¿þú !dgg÷èÑ#ˆ°víÚ{÷î9;;§§§3Rà‘uÀ€7nÜ`^÷½zõúý÷ßͳhÔ¨QJJŠƒƒ{¿7MÓ·nÝb¾txþüyFóÃ?€#´¹sçöìÙÓÏÏϼ ;uêô÷ßÃOµZ=bÄB‰‰‰66{ŠD¢víÚ±½©FBŽ?ÎŽùÆo@Áf̘qãÆ—«eBõz=ø´£iúÊ•+·nÝŠ0`€5Ù²²²³gÏ2^åÀP‡µÈ‘‘‘÷î݃¯¿ÿþÛËË‹¹KSRRÀ¯x“aûN:¡}Óèõz­VÛ¼ys„PVVÖÇ™‚òƒÆùÎ;ï)æÏŸøða¸vttŒ‰‰7xyy9LK 8pïÞ½ƒÁ`0ÄÆÆÖJc`¸páB~~þŒ3˜-[¶ØÛÛcŒ¯]»6bÄ???•JUZZêáá1tèP0Ÿ% £¢¢`6ñ]R“±p÷îÝÌp( a`Û¼y³m·æ!GGG¦ Õj5£%ÆŒŒ dÝ“3Ñ )Ûð;1¾~ýzddä7êà-åY¡V«ßyç‰D2tèБ#GNœ8‘™T¨ÖNÆ899J(2]-ÂÜcȺՠ¨¨¨Ë—/çääôîÝûÊ•+L“œ:uÊÏÏü¥Q•˜˜ËvØ ó7°Çè:0—c£Ëx<Þ¤I“L\؃ö "ƒ¹™[ ¶8€ˆÛ…££ã’%K $???""bÆ ä½D”¡>b4W®\yõêUxÍÉåò 6DDDXV[´hñÛo¿1_Ûƒ¡}ûöÌ÷b@@MÓ‡¾r劇Ù;wîlŒ…Ö†p±XÌvnÞ¹sç={ö(•JŠ¢@i4š9sæ|ýõ×0‹è.ƒA£Ñðx<ØÌÄqvvfš×ÓÓ“ÃáY,ÃñãÇ1Æo½õBÈÙÙìÕjµL&“J¥€Ïç÷êÕ+??Zž¦ifWÁËÒ5MÔŠŠ ¹\®T*¥R)Óì*•J¯×3“@c??¿   P˜V²Èرc÷ï߯Óé@„ih‡#“ÉÜÝÝÙ…aÏIèõzØKÁŒëMš4¢iÚÚ]Á¤ ‘HØÞáÙØÙÙUUUUTT°»¬E‹÷ïß'òr¹ÜÁÁ!äï™©P(x<ÇC:uJ¥R 4d¡œœœt:lÂP(æ>!‰Ò@ ê 4Mß¹sgìØ±ðR‹ÅQQQ4MK$’™3gNŸ>}üøñÓ¦MëÓ§OZZZHH³^Àáp8pûöí1cÆÀ„³³óöíÛišÎÌÌ;v¬@ Ðét«V­‚”k^žØØØ?ü0>>!4qâÄ .ÆŠŠŠaƉD"¡PxçÎxSÆüüü¹sçB¾0Ož<¬LbŒ|Û¶mLw—–– †ÔÔÔ‘#GÂþ!___8µD<'ü£É Ä3R—º=ÄvJÏI’JËÌ›¦¬Lwñâ8e›’’DÚŽ@x~zƒÉÉCó§ÒZ úïÔzÍe%I\\Ü´iÓ¬•‡½èkãÊD†85©KÍ+n1YZM°–”µ‚Ù¬Iú¨öëÏü†aÀbõkXµjÛÄš,;…±}[Úˆ\ó.³XÙš?/µºië3 AAAb±~j4š¸¸¸áÇ›ÏÄÄÄŒ9Ц+ÌÉÎÎíÝmpDFdRRò© ‡ÈLPÿtùÿ¾¡,¾°jXsÙjËc~²±‘k"[«êXKÐZRÕÖ¢†®yI^Ø Ã.€ÅZÔª/ê|_U[˜šˆÛtYÝ¢§l¨×ºØi ¦é „†Gm·F„zÎó°RZ—™†øøø›7oÖsKì¡VF½^fûHk Øzò2•ƒÁСCbˆ›@ „zÛúçËQ0Æp”‹@ B}¦nfÜž¥Ò€È–@ ê=Ïi‘,4@ J@ ¢4@xÁÔnOC­œÔ@x)<§ ˆµS(Š*,,T©Td;$@ õš¦ƒƒƒ_²Ò>ÍÂÂÂÀý @ „úÉó©ëb’¦ì î±G B}?N¨J¢¢&J@ õ’ç4D“]@ ˆÒ@ ( @ ˆÒ@ ¡Á) ˜BŽbä(B4mdiÚè(B|ûçå-ã%BÓ´½þ·¾@ ¥¡zr3ÓƒÝ8ÝZx‰Äÿ—ŽØ™êÔÄùó9ñx¸šؾ~7 …ìxÿQ}øöxáGcÞt;“@ ¥¡64 l™o0ÈeŒiiš¦å2t» âë]ÿO«¥™@Šƒ(êŸ4MÓ4mï€gŽ¤Ñ¨)Î?qhšÆÿÆ¡8ÿ„@ÊŒ83„ÿò¯,c ’âü#k«Î–d™@&ß´ww­_Ååb&_­}sðxbNY¥ÔøU³Yfl¥Ì@ ¼rpŸF˜6"Y%B¬Úγ##õnXxïÁ#Æ ˆ¦i/<{ü<¾=BÈÕÃkéÚH• -›ùAö£‡ë?ÿÑhÔ¤9mBÂèà®ï"„TJÅÎïŽ*dhׯճ"V.›9ÁÞAàéÓxን²JZV!Ù²f>g¯×é¦-XéÓ¸éß7¯ù6nêÐxÉ´qá]G¿+/5bL™Oo”—G}½ÔŽÇ×é´³"¾òðòMú+¾mûN_.˜jÇã«UÊ]GÈehãŠÅó³‹ óJŸ<öõ ˜¶àSe¦ß?´{ƒ»—ï¢Uë4jDÓ´HŒ¿ùrmqaBH£Vî/+}ڈÈ4j•@(îÑ:ðRRæ‡/ËL¿ŸøÇ¯ã¦Ìçp¹:-Bù7m¹|Ãþ7šó>[·N£FãÿÕ±sÏ€mBÇÞA­®¥§:²ç柿ìùþªZU•tóÚO'Nôw£ÂÜ,­Vƒç¯X¥Ñnîn<ßÙÕÝA üGáÐéž<Î/*ÈE EbIi1E!…¬òî“’¢B£‹›gyé•R‰1’”ähÔ*;ÿIQ>ˆÏGÅs“Š%¥ÅFGÊÝÓ×hq«"FjU•›‡H­ñí‘Z¥D©”Šc¿Þw8 „"G1ª””!„œ]ÝÅN®¡‹›ÇÿÍ£ðxbçÿ¤§V)…Ž"7O„P„*%å!µ²ê×ä[…y´ƒ@hï JJBÂÇyÙz½Î`П»™¡RÒd¦@ ¯»Ò`‚²Êxâ·s_.ýšÇç#„´MQAn·>ƒXZ-tÄÊ*„)*3íEaübÓ•aŒå2d²ÐP¥ß¹qU§ÓÐ49q6eÀ˜’U"LQ 9}ì×UŠg6*s8ˆâ ­¦Æ þSfÌ®ãêm‡N~»‹kÇŘúáè¾5ÛþŸNGn?@ ¼NJŸB<>¢(d0Ð!®æ ƘÇGZ í(¢B5²èì4 IDATù#5WY…ByY9'¿ÝÕ½ï „^¯ãñøŽ"<ù½þÛ¿½ ÓjÞzgÌ›"„0FZ ‚Esœ]ݧΟ­¬B!½òŬ!ƒ¶aQV¯×óøÈ`@<>2ô!P4ö­àÔ Z¥B|>ÒjÕM1F<>ºð(õÞ°ñÓ1þ§¾|>ÂÑ42èõ®ïŸFÐj5[Ô"ð¢)CûM£ABGÔ½…‡‹ˆÒ@ „×Hi(ÌËúF¯Ð®o¶i9ÿ‹Í=ú ±ã¡/—ξsãªÐQÜ»mã‹w ªô_y¹áMìB„w£&<')£Fôí¹³ƒ:uRÈ*Wmý–¢¨ïOX1Öö¯– „òÊ_þÎ7PHhWÆ·§ƒ@èÝÈ_­B{¿¿Ú;¨™½ƒ@«Õ,_þ¦ÑˆÚ¶ûŸ±:ë Z ½yÿÙ¾!|{ZµåÀO:-­¬’ÿ”Xз] ßÞ¡J.{¤Ð1Euèpëú•á=‚[· Û¼ÿ ¬‚Nþëúª…;véÙ­E³õ{âZu˜ÿÅg•óè!BH©§VÊ+$¨Cçý?9Š]1EÑ4ýÉgú‡¶àñø*eÕ³7Èò@ ^9° @<#u©ÛAl÷¨ôœ$©´Ì|0++Ó]¼x!44cœ’’ú¿pk¦ƈÿ¯­éõ4BˆÇÇ8Uˆ‘ªŠÆÓ4í ø'MšFjÕ?ã%MÓa¤Õ"ƒžFñù˜bÉ"„ì0cÄá Ž¦8¾øBZ 2ÁêV««‰) ñþ+ûýÁ¨VA»ôèÌpNÓ´s¹ÈhD51fËj4ˆ6"š¦ùö˜9qªRÒ!f¡(„1ÒëiÿŸ¬ÑÄG(@ ž4B¸(¡U› ±Xüï°¥‰‹‹>|¸½™•¤˜˜˜‘#GÑt…y:ÙÙ¹½» ŽÈˆLJJ>5áÐÓ¹¤û “:-Òý7clíŸpõµZÓhpHÉN¯GcÚˆLŽ`Œ5T“ow£™,¢iŒþ/]<½éuÿh´”¯VcZfµêÿ1þ³ß[È—@ „W îk^š¦ßŸñ‰A r3@”ë˜L@°ñ¡@ ( @ ˆÒ@ áS÷= äРЀ áôMÿÇT@xUy>Ïq]”…Üň6’>!Î F­V?ÊÈh×>ÄHm¡APô¸Þ( ~N¤;„…DRõ{êõA=CHS ƒÂç° À%ÍJ°M?3s×줘kó ÂË›x†cSUUE›-IbŒííí9ÿ˜€% ¢4,£ÑhΞ=;jÔ¨g8"-Y²D£ÑL›6-$$„ ¼uëVTTTlllMtŽú [>>çÎ ´³³£(jÏž={÷î‹‹KII¡( ¤~ÿý÷yóæÁLÓôþýûßxãnݺÕ\_ùé§ŸV¬XÁ¬—WVV®]»ÖËË‹¦i‡³nݺãÇ'''ß¿_&“9sF§Óµk×c“À–-[2×ùùù³gÏf~VVV2×íÛ·‡ £ÑÈlqV¯^ššš™™ùÉ'Ÿ0EÑ4Ý·o_v^ €d‡!sæÌÉÊʲXZȈá½÷Þƒ‹Ï?ÿ<==Ýb†¶mÛ²* ¸X°`Ann.#k"ÎtS»'OžLœ8®g̘³6òmÞ¼9síèèîîîLà AƒÔjµ¹`yyytt´µŽÛ·o_LL óÞ8pà@jjjrr2S/P߸~ý:ûªV«9¢R©,>àRi…ùè/‘äܾ}Ulmä“)1—Ì4 ?îîî®®®¡Î;ïÛ·!ÄçóÙŸÎð?{ ={‡AEE xOY˜Æ‡‡‡r8œªªªØØØ·ÞzËü;òjݺ5ÌŽ †>úH«Õ²WF š‹‹K‹-˜¢N˜0dÁ£|øäɓݻw·¦šˆD¢N:?c Š‚N§Ã§¦¦Â(‹1vwwôè“Å“'O˜¢¢¢@pãÆ¡ÊÊJ&¨4M³Ë ×7oÞär¹ ¶ìÁØÉŽiÌÌL&‹“'OÊd2ߺuk÷îÝ1ÆÅÅÅ0=c”prrúå—_ <:::88æD"Qß¾}ÿüóOˆÖ¦MË„#GŽøûûcŒmì6-//gò---?>BÈ××÷Ò¥K8~üxöR 5ž={îÝ»·¨¨H&“)•J2ß@ ¼r_‰O#Žâ©KÝžb»G¥ç$I¥eæo²2ÝÅ‹BCCaó|xx8l'4Ll˜Ø\2EÁ0ƾá Ü¢ˆÅ™k²ì|«ýú·![ç2×<#vâ¶±V_Yóú2e6Ͻù^^^lõË¢¬D"‰‹‹›6mZµ·@x%HHH bNKi4ØÙ­V«Mp''§ž=ߤé óD²³s{w‘™””|jÂ!²§€ÌÇ-“•u„̇"vˆùb¼mõÖ¢¶[ÑɶlÊ\óŒØ‰×­¾ÕÊZŒYóÂ[l8ÒYÛv®s|Po§`G¹I8S¯ÉQ„‡!³ý»óÝü-QCqnݲ,//7_xB¢ªªJ,K$’šìö õœ§9*õŒ•Nǘº# æÓ´iÓ¤¤$òh °çöò•>Ÿß§OÒBCB*•~ÿý÷3fÌx1ÙÕd:”ÙÙZØ €yùJ@hx€ Í“—Á`HJJ²f ”€ŠŠ ww÷FݺuË$¦‰}µZÍçóI'Ï¢4ÌCÛûþª= úœò­mjϯ}žF·`*ø4©¹¹¹F>Ÿo>‘€1V(žžž`C,7kÖŒ¡¨¨ÈÇLJù)‘HrrrÈÍO ¼ˆq'Â+ŒR©Ôétÿ¹¡)ªiÓ¦:u²=rcŒ÷ìÙSçB …ÂÄð%EQÏÊy7EQ`êöíÛϤ¡ÒÓÓ¡²O£1Àè^RR‚1ÎÎÎO©…ÂÆû™Ñ¸qãß~û Z±–'à")))++ ,ê“G€@ Jᵦ&gÀÏBhß¾}>d¢AÌœœœ¿þú "X”…‹™3g‚Û'å&eB¾þúkÆs&“oiié¥K—sÙšs2z½~÷îÝ6Šg2”BLó2Ã_Á%ØSú°ÆÿðëV­¢iZ©TVTT<Í*ƒÁàåå5tèPó?ùúúΜ9ÓÄþ úwUâÈ‘#gΜyøð!ÙÇ@ ¥ðºN¥Åb±³³3Ø^ÄO™2þäìììâ➯Á²e˺uëæääôÅ_À—ôš5kÄbñ€ÿÝŸ|ò‰‹‹ËÔ©S'Mšäáá®/år9ÆX,3ßÊ=âp8ÎÎÎÎÎÎ5rtt„\œÿÅ××Bx<ÞæÍ›Û¶m+‹·lÙù.X°ÀÉÉiÔ¨QÌ"EQŽŽŽ Û¤IŠ¢0ÆíÚµ‹‹ÅŽŽŽ±±±¶ 41¾6 A©T -  ?Ž1¾víÚ‰'{SM›6…òù|È7((ˆ½üÿôŸæÛ¶mÛ½{÷3ìn‹©-Y²Ä| ß®]»… êtºaÆ=“¢4^aòóóSSSe2YEEMÓàžQ¯×‹D"š¦+**¤RiXXŒ©Û¶mKLL¬¬¬\»v-|ñ¯X±B&“Ý¿ŸIðáÇR©tÈ!£F*--íÑ£ÆRc¬«"„š7on0******Þ|óM…B_íÿòøñcðž¥Õj?ÿüó´´4™L¶páBÈwëÖ­•••L¾ã–-[* ÍÎΆAîÞ½{•••2™L¡P\ºt©¼¼¼æº”§§'´@UUÕñãÇår9EQEEE0p* ;;;„§§§F£|¦OŸþ ¿ÈíììÒÒÒìììÜÝݽ½½µZíS&èíí½páBvˆŸŸß¸qã,¶€T*ïܹs“&MΜ9 Ñ„ ÙI¨gj,E±WÊaF]"‘ÈårØvGÓ4søX¥RÉårfPa0ìkƒÁ ÓéŒF£N§sttdþdbÅÒ7nÜêÕ«Ñ¿¦Q¦L™©ét:///ˆ©Ñhär9ìų–/[#‘ÉdàÛS$Í›7ör8œZ çz½þã?ÖétE]¼xcüÆoÌš5kîܹ¡¶mÛæåå!„|}}g̘U«¬¬lÔ¨Ñ3ì>Ÿÿí·ß2ûHzõêeÍ!jÍ»û½÷ÞÛ»woUU„Œ3ÆËËËâRέ[·G-“É®^½ZTTôÖ[o±Ý®¢4ÿ ÆÖ†Øgr`œÁß7¤ùÎ;ïÄÆÆÂ\—Ë5qæT‡|kè‘Ë"b±xÛ¶mp àË/¿-.ž>}zÆ M©T²gC´g…J¥ŠŒŒ„Šk4¶VgzôèáèèÈ( àÂÔ¼‰ôz}LLLjjêÕ«WW¬XñÓO?]»v-22rÓ¦Mä!ˆÒ@xMáñxcØÉ(‚ƒƒB...5úõ×_a^q!ííí1>räÈüùóòóóa?)))$$„Ãáèõz𦙕˜c¸wïžR©¼wïž‹‹KãÆõz}Ïž=ýõ×7nÀ¤wxx¸¯¯oVVMÓŽŽŽýúõ{ë­· ߯§¦¦VVVîÚµkÆ ÙÙÙ2™ìÎ;;vÄݺu ¾øU*X`Ï盜¿0áÆÙÙÙ°–cÚ´i“––¦R©hšnÖ¬3¬6iÒ$33“±Rœ‘‘ñx¼Ž;B233u:]JJЧ§§»»{Ýz§uëÖ‰‰‰µ^¯oÙ²å3éô¬¬,PnŽ9b-NfffxxøŒ3Þxã©S§~÷ÝwŒŽŽÖh4d…‚@ Já5ÅÃÃã£>ºrå ÆX­VÙC©TZXXøõ×_;88 „vïÞ ãÄØ±c;?~üø€€„P^^ÞÍ›77lØpáÂ…¶mÛr8œˆˆŠ¢úõë‡2‹/†ïÂ… ›6múõ×_»víÚ¸qc…B1nܸëׯ3‡ÂÃ㣣·mÛƒnQQѯ¿þ ³3gΖ<¢££™šNŸ>ÝÆ4@|||›6m Å­[·ÂÂÂhšŽß´iŸÏ7B¡ÐÓÓ sçΓ'OöìÙ~ž:ujãÆ°¿ÁÑÑ‘QÎ;·oß¾ŸþyðàÁuShšÞ¹sç7ß|MÄáp¶lÙòôÓ<4M ‚‰'^¸paøðáæ R¥P(Ö¬Y’œœÜ½{w…BqóæÍ®]»ž:uª¤¤äÍ7ß$ðbÀ‚ñŒÔ¥nO±Ý£Òs’¤Ò2óW@Y™îâÅ ¡¡¡ã”””ððð   Òv„çÅAhèСßÿ½½½½Ivd‹3ÿS3´ÍZ‚Õækž&Í<…jÁv-L¬•,‰Dg²S‡‚ÕƒÁ““öá(‘HRRRºwï΄(•Ê–-[¦§§ÛÙÙ9s†ÏçS¥Ñhììì8ŽZ­ær¹:nÊ”)ééé¡¡¡äñ!Ø$$$1û«4͹sçBBBÌ'çôz½——7EÉÍÉÎÎíÝmpDFdRRò© ‡ÈL¡ž©±–¡öîH&޵Mˆµ ¬­lµùš‡›”¹ZÛS5/žI‚µ’}ÊÞyš9…B‘ŸŸÏN*00RRR;^ …··÷øñã­‰˜ƒ$^Di ¼|ùå—¤ž7ç…9Åæp8>>> …‚­v˜÷tuuõõõEùûûËd2 ŠP(4±3M Ðó1dR¥A£Ñ\»v˜c#ÁÁÁñññõ§<?~æ1 „ׇ§4ûÌ”Š¢ÜÝÝÉŽe¡!¡Õj?~@m¡aÀ˜±yÉJƒ]ëÖ­I ©TzãÆ’¦  Ï}úôرcÉ’@”Âÿoïî㢨öÇÎÌÎ.» (¢â"’øü„Š^HÔÌn–^S4x}ʬ¬4¯ÝÔB-ojZzKËÇK…}ó!MMŸI-ÑÊT¼¨À.,ìóÎùýqbîÊよ ~ÞøZƙٙ9sö|Ι3ç T¯8ŽëÓ§Obb"û“òòË/¿õÖ[„£Ñèææ–——7{öì~ýú­Zµª°°­öÌ3ϘÍf˜7oÞ¤I“z÷îÍæÙz饗ÜÜÜ&MšÙÙÙï½÷^¯^½vîÜ9iÒ¤µkײepˆ#Fddd`Ú!ô8þdá%@袔WL°¹6|||vîÜ l–N)¶`DQd+Kÿe·Ûƒ‚‚X3€Ýn—¶b-27·ÄÝݽC‡ØÒ€ ¡zÅóüºuëœYÓ±#›ï[úÓqµZ½`Áxxx”””°åÅÅņ²iÓ¦ªgå®ÖÕ«WçÌ™ƒcÂ"„AB¨^ÙíöéÓ§{{{«ÕjBHnn®c‚£´´4BˆZ­V(ýû÷www·Ùll¾†£GJ«Æ„„¶f·nÝþýï³å»ví ”Ëå%%%޵‘‘±víZL;„Cا¡GO«Õ²¬ý@EJ©(ŠŽÏzöìéØº@)‰‰aš6mÊ6ÒçÒšÒNDQÌÉÉqü–Z{úé§ÙÛØØ€¶4 „êÍfc]V ³b¾êñËÌ…-­¬ÓéîËá¥Ë+œ[üA`Ä€¶4 „êUÿþýûôéS‡;¼qã^U„  ¢(–””Øív¼|Õ “ÉT‡{«ÝÈF£Q©T †ì&‰r„‡ÑX› Ájµ²—Â1Uj48Žk×®ÝÉ“'1k#ÔPJ===]"hP(C‡Å·´jL víÚ5mÚ4ÌÚ5§Nr‰ ÁêBI™ž•!T¾=Q¤wáêç‹Ênp׊)?VA#»%ÊœfM“¬ž“»Â¯(¿* =h®_¿~õP#„Œ3†òÔSO=¼¯{¨å!K–,!„´iÓ¦êw4°A=o+æÄ‰ €ã8…B1lذš&!dܸq„'Ÿ|²~î®gŸ}–8øÛßþFÉËË“–,^¼* US£’Ú*[­|ùWfMi[Çêue%SùmÙ‡o¿ýöù矧”Ž7.99ÙÉ Ëv'~~~ÎT=kQ¬²ï]´h¥Tšœ©Škåü1—_mÙ²e¿þúkÛVqåß|óÍ[·nÕtÛòe°´C³Ù|èСʚª8ߤ¤$6evµ×êÁ›%(¥_~ù%-•”” ¾¾¾ÒB­V‹ï|"„ABÈܹs_}õÕ°°°–-[þñǰmÛ6VðB†Î*[±±±!!!§NêÒ¥ËÔ©SYÙàéé9{öì°°°ÀÀÀ¬¬,6šÞ“O>Ʋm;vìÈqÜ‚ ÂÂÂf̘Qa¥mͶmÙ²%!„r¹Üb±@ttô!C*<‹>ø //Oúó¹çžc_íççÇvÈf. „ìÞ½»M›6aaa&“‰’˜˜¦×ëÃÃÃ[·nMaåÛ¶}ûö¬‘@«Õ²Í›7E±Â l¡¿¿?ÛvåÊ•ŽïIØùvêÔ)¬[-22²E‹%%%k×®e ?ùä“ÐÐа°0¶“9sæHGÁVkÕªÕš5kbccCCC׬YÃ~øá‡íÛ·—¶­ð˜ !AAAŸ~úéàÁƒÛµk·aömbb"Û–ET•¯Õj  =z4[“òÆo´oß~îܹ,²dçÂN¶oß¾ì+âââ¶lÙÚ¦M›}ûö9^«27³m£¢¢¤mÙÊ/^ܵkWí·š1cFDDÄܹs --Ùl6øsPc…ƒ;ÕÀêÕ«:ôþûï@Û¶m¯]»–-MtöìYöáÈ‘#&“iÔ¨Qééé)))›7oŽß·o_jj*±ŸÅ .\»vm›6mØVÞÞÞZ­öòåË„¯¿þúÝwßݽ{wRRÒ¸qã* _¾øâ‹-Z°%Íš5ËÍÍ-**2 F£±¨¨È××·²³ÈÉÉÑjµ>>>`µZÿýw¶O©ö¹iӦÇGFFnß¾ÅFàãã“——÷Æo¼ñÆ­[·f3#SJ9ŽsÜvÍš5iii}ûöU©TÒržç+գ̶‰‰‰?ýôS×®]ËŸoLLÌ¥K—¤%}úô9yòäO?ýd·Ûrrr-ZtõêU™LvãÆß~ûMÚRz÷î]Žã¤R|È!)))7oÞ\±bÅèÑ£Û·oÏNäòåË………RÛƒ~•ØnݺõöÛoÇÇdzÙ))¥çÏŸ—ÉdÒ¶Ž'Uæ| ›-"33³U«V .¤”&&&&&&J'ÎÍHõu½^Ÿ°aÆ}ûö 2„ÝØ±c äîî^áfff²ÏwïÞ1cÆúõ륛S¯×KÓ[ÔÚž={6lØðùçŸ èÝ»7;»æ Î —lIDATÍ›çççcŸ„0h@–UÑÑÑì³ U¯Ìó¼Éd²Ùl2™ †Ú¯_?©@µZ½víÚfÍš€››[ ÂÃÃÇŽK)•&8.O.—;Ž=ÌæPž5kÖ­[·ÌfsJJ ›L¹Âåý÷ßwl™æJ^³f +Ž=úúë¯B¤ú«(ŠyyyÒ,ÒQ•¯°²0t:]nn.Û„Õõ+#}ïž={bcc+\ÇÓÓséÒ¥Ò%bQ(ÒÁð<ÿã?._¾œRªR©ØrväìH¬V«´¾ãøÍ„__ߢ¢¢ÄÄD())±X,ŽóJ—©m—Ù–ã8'KJ–Rœà8}C™z<; pwwß°a4mÚtÞ¼yl“Êz{°ÿ]²d »?u:‡‡Gg„‘#G²(pàÀÇŽ#„\¹reáÂ…ùùùeæË@aÐðøbuÄÚ)_¨Øl¶¶nÝšý'-gEH—.]jô[¶l9xð`~~>ëÖPa4[xóæÍ˜˜˜~ýú>}Ú±$`ÝbbbBCC«ííXõ|Eì!…¿¿?¥ô_ÿúW+;~oXXXeW~øðáR¬0a„Ê)444&&†]mÖ8A©°ø/sþþþ‹-ºyó&+§;vìxùòå¹µ¸%¤å¯¼òJzz:+}‹ŠŠ–,Y²hÑ"göI9räòåË- ¥Ôl6'%%9îÙÓÓ³Ö-eÎ×l6k4öyñâÅÉÉÉRȈj¬0‡×€ãƒjöÙÝÝ]§Óeggùøø°3û////V¡g¿Ñ)))ÉÉÉÙÙÙ:ŽÒ¥V«ýýýýüüüüü|}}Û¶m[þ[*£Ñhòóó³³³³³³YÙÌ–Ûív)æ¨bóàààœœœììì:°%Ò‘øùù³‡ ‚ ܽ{—=‚ñ÷÷—Ê///N———×·o_¶mII ;‹ÅŠö2­•ã÷†„„°f½^¯×ëív{aa!»žžž~Z¶l)](öœEzÒ¬Y3¶ŽOÇŽË—ÍÒåuww×jµwîÜ™9sæ­[·®^½š˜˜ÈŽ' À±kayùùùwîÜ™:uê;wA°Z­ì °kUÙ†>>>z½>;;ûĉ7nd—E«ÕÞ»wÏl6ççç³kÕ«W¯   v"Mš4ÑëõŸŸÿöÛoçææÞ½{W.—³m rssÍf³ÔO¥  €]„víÚõéÓ‡µ44iÒ¤°°P«Õvêԩ‡NF$qqqYYYìLsss›4i–'%%åääääädeeáóaKxñÅ¥Ï3fÌ`ÿ&&&&''Æßÿ}þüù+V¬X°`lÞ¼Ú¶m;vì(((X¶l™Ùl>rä«M.]ºtÇŽ¬Òöé§Ÿ²=Ïœ9³Ú ß[o½µxñbVN˜ÍæÓ§O³Z`›6mØ×U»‡ãÇ_ºt‰•(lÒäI“&±â$222>>ÞÃÃ㥗^úÇ?þÁó¼Á`ÈÉÉa-ϔңGΛ7O„´´4Qsss¥mÜ­[74hPÓ¦M« ·4hгÏ> ©©©»wïž>}úܹs×­[§T*7oÞùD¡PL˜0Á±ÃàøñãÙ˜3gλロ””4vìØ   0`ÀÒ¥K ¤¤D:ß ¯Þ믿þÎ;ïäääLž<ÙßßßßßÿÚµkË–-€ââbé¹Lùó½qãF||¼J¥ üá‡ØÓŠ={öœ>}zÔ¨Q¯¼òÊçŸN)=}útBB{ãáá±bÅ ðõõ]²d‰(Н¾úªZ­€o¾ù&==}ذa¯¾ú*ÛöĉÓ¦M“ËåƒRºwï^Jé•+W¦L™Âóüµk×8Pë–†½{÷Ξ=›^2™lË–-ðÚk¯Íœ9“]d£Ñ¸jÕ*///ü¹@¨Q"ªMÂÕ×›ÞQ}Þÿ£ßn^ÐjóÊW óò¬ß [·n„ŒŒŒÞ½{³:Üc…•Êeþ-_‡v\¡Ì wXÅþ«='ÿtf?å÷NŒ XÙyAmG¬lÛʯÌå*}Ø’K—.eeeI+EDD`²"Ô°`Å¡†òÙgŸÝ¼yS¯×/^¼Ød2ÕhÛÕ«W?à,[¶,??_«Õ²Q,ÙĤ•E #GŽœ:uª´0!!A§ÓiKI3½!„°¥!T÷Ξ=ûÏþÓßß×®]l¼pÇN‹ÒWeJzöáüùó/¼ðÂÇ”’’rèÐ!60¨Åb;vìk¯½Váˆg'NLNNw<’ñãÇ;Ž/^'í!li@•­»€L&S*•ðÕW_±¹3¦L™Õ»wïÝ»w@``àŽ;úôé5bĈëׯ@ddä÷ß׿ÿƒÖú0ŒF#ë÷@Ù¾};›gdàÀW®\aÅÿäÉ“óòò®_¿>fÌi‚ é¶mÛÆlذaÒ&!li@Õ%BHëÖ­ SRRÂÃÿþúk8sæLTT›åDª»{zz:u îܹóÎ;ï¬[·îܹsñññëÖ­c3†×ºŠ¿}ûöÎ;SJ ÃêÕ«Y(süøñ3f¬Y³&22òÀ¾¾¾¾¾¾Òô­’7Þ¾}›˜Õj}æ™g¾ýö[LY„0h@Õ}KÃõë×g̘±téÒ&Mš°RŸçùòs¢Z­Ö°Ï‹EöÙn·›Íf¥RI©u¿U«V/^”v¾~ýzöyýúõ999Pù|O<ñ„ÔóÑl6K#„êùǤüX,Î΂'j- Š¢4Õ'Øl6žç܃ÑhT«Õ„ï¾û®N†‹^»ví¨Q£Øç)S¦dggÇÅÅýüóÏNÌÁ¦Ï–þtww7˜¬Õ3³ÙÌó¼ü~nnn7oÞtòkli@¨Á())qlZoܸ±K—.EEE3gÎŒ‰‰©uìÒºukQ‹‹‹¿ÿþûîÝ»@HHHzz:!dïÞ½S¦LY¶l™Á`èÕ«—F£¹qãFëÖ­-KVVVÿþýƒƒƒYÜ P(ư3¡ªñ<R>>ÈÎΦ”:Ó‰AB ¥tëÖ­ŽKärùÎ;W ”Þ»wOz@¼qãFö§——WFF†´f­õ¬”vB)½qã†ôyÓ¦MìóòòÊlؼyóÌÌLÇ%˜¦Õ3AΟ?ߣGÇ—ž>ûì³84àã „†j'þ–:+T;Ýv­û4”߉“Sº—ïH¯N ôHêžžž÷îÝ“òì­[·¢¢¢ØsOg`ЀB=FÕö“µö ‚`³Ùœâkóx‚RjµZë¤/BÈE~G¬V« v»Ýù:BÈ•3ueÿe·Ûo߾ݢE NwéÒ¥çw[ã Án·[,–'N`’ ÔÈ~bÚ·oüøq¼5jµº²ÌÎÆ¡ÏÈÈhÓ¦Mšœ ìv»›››(Š:u¢”º»»cz ÔøHã: „ºÊº³Fˆ­[·J="ë8h¡ÿþ …Ó!„j(AƒãÛ•„¥Ri±XX0Ñ£G›ÍÆf±™LVn¬¸Ú ­Z·jŒ €B5Pr¹<66¶Š´Zmµ;Á·'B!ä B!„AB!„êŽS}®]ûã‡99›B!„9›Í6jÔ¨ÀÀÀúl6[=¼½½ÙŸlFSXXÈÞõôôôÄ‘äBè1Çq\fffPPèLG|TGL&“B¡P©Tz½^©8¶X,æ´4'Ž"Š¢ÉdjÛ¶­Z­vss;uê”O«V­0ÙB8p 00Pz‘Õ³Ùܾ}{BˆF£ùõ×_U*Çq”R›ÍVçõùši2™BCCÝÜÜ'ÈÂC!$56àE¨¢( ‚ R©ºuëV\\|óæÍ‡4P›S©ËžG¸»»wêÔÉÍÍ p†:„BÈŰ¢ÙÝÝ=""B¥RI³YÖwÐ@)áìÙ³˜$!„ë;sæÌØðÁÙv$JiDDÄþýûóóó- ¦B!äj,KVVVJJJçΕJe÷ip6h „ØíövíÚ8p 33Óf³Éd2¨|J „BÕAL&ÓíÛ·÷íÛg2™Z¶lY£¹+WƒŽìÕ èСCQQ!äðáÃAAA2™lÛ¶m<Ïc²!„ÐãŒb±X°Ó[=_s¹\¾sçξ}ûêõúˆˆVR?¤Tpv–K«Õj4jµÚž={ÚívJ¡K—®ØÞ€BŠŠŠð"Ô³'žxB§Ó€Á`Š"­ó—Yœ Z¶ô òç!„PCAØív£QçÜÊNµLT4PJ‹‹óðê#„B=Î 4àÓ)„BÎr‰B! B!„AB!„0h@!„kº¯#$!ÏsØó!„Be_†ø_ÐÀqäÂ…_.\¸€×!„B@©sˆþ4ˆ"íÒ¥khh^#„BÀµkˆc;Êî(Ì&S Ì€B!°Ùî›×;B"„BÈ)4 „Bƒ„BaЀB! B!„AB!„0h@!„Pã&sr=J©B!o@'f·‹6› Çœ@!„ê;hpss[¹r··§ÃÀP®‹RÚ©SD·nhƒ8\„B¨1 ÔÝ]=cÆ‹&“ÉåOŠÂñ¼Â`(Ä–†*â*Žã\üúˆ¢H)ÅDtÇq.~¿‰¢ˆIéÌ…põª!ø\ÛÉÔ_RÊj´¶Ùlæ8!¼Ë^žçF(ZA†·lÕU~~NWèÊéëëãáᎉU-ƒÁ˜›{Ç•ÐÃÃÝÏÏ[þœùW*½]ùB ‚¬°ðŽ‹©.ÿ©T>®œ”r¹¼°0§¦qC-JVN©tÙ艜:•æíííç燷lµ,K÷î]\4,*ÒýôÓ¥N:bJUËn·‡†¶õððtÕävìØc·Û1±ªÿQ–L沿±Ê¥K—Ì›7Ël6cJUßsD.wÙ{ÞmÅŠ3gN³X,7h(m_tÑfFž—a\£Â†ç]÷Ø8[³kp¹\öçIäyÞõ[Ý]­ äšõg…B-F&)k az"„Bè¡ ”R@ PÔvÆ­.Fá¦X×o *̪”RL垦fÕÆ’”rVRJ«xà yö‚Bä›6}1thLttl}...©dMAƒ¢‡ýKffæ£:ÚzÅà—_.fgç:ô”Rž÷æ8^E§:äSJ9Λçù“'غõß'>‡·Ž‹Ä¼Ç<¸Çn7ó¼G``pVÖŠëü‹’““9Ž3&¯y=¸|ùRVVvù¬zðà7_|±3+ëv‡¡x•›Í¶pá’<ȲjË–­þûßL€¼2 °kמ/¾`•(ræÌùçŸ@]ÑšÅGŽì]µjÝÝ»yÁÁA /h`q-ëx(Š:QEQËqš/¿ÜúçÞe²§Ÿ~ŽÒâòïg—”¦N·ÛMô›oöìÙ³äÈ1ÇŽ¥ Øu˜²X¬W»téd0¾ùf ”ÒÞ½{·ÌÏ/(.. n À8‘Ö¯_o¼éêòžÉÔ}z(5¼÷ÞªQ£žPüýï/ȲâââåË?à! …B¡«TÊwßý ¤¤äçŸ3öì9òÙ³çcwκµÿ¡ÈȮÇÇvìØaåÊ%¦Ï?ÿ´  €¥©§§æÅ'¨GŽ b-¢©©'Oœ8e6[-ZªV« y“&Þ£F= òòò|ê© £GoÒÄÛÃÃãïŸà¦PÈA™B!ö«¯OÇVø’!îÇöñiªPÈ•Jå¿þµ^§Ó±8’¥¾ŸŸÏðá±>>M££‡-XðŽ»»Úb±|øáJW¾¥Qây~èÐA]º<1pàÅ_l¡Ôr¹PšU=§Nä˜U)¥©©§RSOZ,–·Þr̪Ï¢ÂKúéõŽzEFFöŽŒŒÜºõ?„+W2öìÙÏÊ>??Ÿ¿ü%–Š6U >fÓ¦­nn µZùöÛ‰¥5=—liœ9s¦W¯¡¬¦’šzjÅŠ%¬(..‰ŸQa— áZ­VJ©ô&+{díÚ5]»v “ËpsSŒË~¹vîüÚjµq'“ñŽ› :3tÿþ”J¥Ñh(°_¾|uÚ´É­Zµ¹\5kÖ«6JÍ;v¸|ù"¥†uë>=~üˆÑ¨ÍË+92Æb±Èåš¿ýíÿðmÚt9t(¥¤Ä@©Ž·7ß|À>jÔ“V«•ã¸Ñ£G°*.^vif:~<íàÁï-Ïó»wg6[hDDxxx{Ë›ÄÄŒ€nݦ¤E‘RNW8oÞìˆWÿuÓ ^]°àu£±˜’ž~¬k×N¶Áƒ°P^.W—fUKxxXFÆ%ãÚµSSº{÷ò¥¬:qbB]•¨vÜÝÕ§OŸ(àãã§RJ ´ÞÞ^±±Ãhi¾«8.÷ööz÷ÝU”ê¶lùÏà ¥nn”ž={²gá5øb™lݺOIe¡±ã ‚àææVú—|ýúOþïÿö ‚ “ñiigîoCã¥èÕQ¤£Q÷ì³c¶mÛ(—+ÔjÕ´i³Õj5‹ 'N|À`ëÑ£k^^Öþý?Œ ` ‡‹{V)¥tÀ€>V©¯>!„RÓÏ?_¦ôÃ{SJ D| `#þQʪýû÷f/Уf ì}™L¶zõ'.ýÕ`«,|¬×ŠÅƒll·Û !žÒèt…šÒèI¦×ë+¬‚Øl¶yófΙ3”ì´uºBÕÑ£©[¶ü'-íG½¾@>kÖklÏzým&¬V«L&ð¼téDjê)¼ÑF5Àôé§k‡sôèÑ;wîíÝ›äáXú¿Å”šà™gF_ºtù…(¥”ê(¥C† Ú³géjfJ„(‹XZ›Í//OB¼öîýÒ×·i¯^‘xÑǬJ„†¶ýí·k¢¨å8oµZíááà)ŠZöûíwR€P”–v&,¬ÝÇ‹ͯ0(Áˆ¡þƒ†Å‹ßŽí˜mW­Z÷Ùgyz¶€ûñ<”Úþú×§.^üåþ¬:pïÞ÷gULAb4š,xeêÔY¥ ”³T*¥F£‘òlAvûöO˜0 ¬VÛÃ~‰æztéÒ­°°Hdr¹@¡T/ŠºŒŒ«2/— r¹àåÕâÀÔV0J%ÏóÇX,R æúõ› …ü?ÿINK;íîÞt×®=”êòóoBär!*jÄüù/ÀС9uê¬ K—¾…·WÝ*­€F“s>þø³®]²4%„¸B!qqcÞ{o¥fJu„•JùüócYbBþøã !€–¯žÀøñ“7lø\„]»v÷êÕ/ûCÕ¹sW½¾X&û3«þöÛJuç-“É^xazTTœ——'ÇySª+.¾ÍR㸕+—¾}ûÿñÇ A!11ÑRjV˜¬¨þ*|2Ùk¯½$e· R)-ܰas÷îƒØ’cÇöÛí" ÖGŒxjùò)5±¬ªT*'Lø«´íµk1}N¤_]!„ã¼ !óæ-èܹo@@3Ö•Ð××çîÝ<™LF3&îaÏ×CT!š„«¯7½£ú¼ÿG¿Ý¼ ÕæUx÷(ò?Þ4}z<Ç©•JÊ(¥„¨ä¥k²ø—Ii8¬­ä± £ÔDa›ˆ¢Ê|à8€”6]ˆ6cfæ   èÖ­szzªÔ¸}ölº——§ ¨,l/­JnîÐж|ãH«YS3¥”OJ )¥ç%µIiJ)%ăR=»Î”RBÊÒýèD)qËܬ‘@`¥´‚zªV«ûå—ŒˆˆpL©jéõŇ—W¥sOÔ$«JÙ L¬IÉaÛu¹ZýïLRRrll4+ÃPÕ×ÊÃÃ[&³WÛG„RJˆ@uv£çYºm!€†= dYUzwºÂ¬êÜá)V®\9cÆ‹5°àq (uw÷‘ËmÕ&¥ã$¥”5€‘R‘µ4˜ ‹ö*ʳ^ÞÞÞZ­Nj¡ Ôì\Á'_½zÍ‹/¾PmRÞ¸‘9¸ßˆù¿/½páâ® [èñ!À`¼¯í‚ã‡j¨ü7ÅÀšLËtç.ÿ–û¡yóf/¼0ýÈ‘ã‹eÅŠwðqx]û³—ž&°åÓ”ð¿ÈŒ"5•¹Êß„érŒízATƒ¬z_v+MÇmËçPô¨ÒÔZæ·‘ãî˪ÒÓ@–Uïß¶lVEŠã$!ÀàøÁ1'V”gIaa‘T¨‡ŸÓÙcV&“íܹ@À.+N‡Bè1lÏЉ¢…µCÔSùÛ`ClÞ.!„g¬É¶>kk4PJ®úb=‘Éd8þºóx^¨ìÝßGNpfŠšäd™Ì…çòÀ§5Ê•<€ËŽx†ãâÔä¾çˆ —ŠÚ…5äráƒ>¹k&¥tôè'ñfu†J¥Ú²eGæ«çÄìÜù L&'så÷ßÿ ×»ì¼´E‹æÍ;Wq„sçÒÓÒR qÍH‹6mÚgÆrÒÝ»÷vîÜæªÅ%å8¾IY£ @aá„„x—½i!V«Gt&ºÒh<\|¾(Q´Ûí"v“¬¾Ê P >Ä•Çd¤”Úl6LJ'îy144¨C‡\ùÇÃb±`R:S)•4!aŠ+d-’²AƒÍ&ªÕ¾<ïê Ød6vz¨æ††?'¼iljœÈžvLÊÆ‘1E‘Š¢“²q¤§ÕÚØ’ÒÙ Ád2Ïš5-??«áÜ-ïl„B¨.«åΗÀ‹_ËF!„[ „Bƒ„BaЀB! B!„AB!„0h@!„Ðc4àØ!„ªXé8 8‘éoÜÈÄ‹‚B!ÐjuÄþ¿Aêÿ ¨Þm[ÔÉ`1â5B!„;Ø{¹QëŸSÊ›äÉb}eó|"p8ÓB!„J£ VÑf±²Æ™Ýl»öÓoò»Ø•!„B‡wµy„x€ó£#„B¨Ò°»Þúÿ&n^ ‹¦ÅIEND®B`‚snd-16.1/pix/circle.png0000644000076400007640000002610311147553266013116 0ustar bilbil‰PNG  IHDR¾ÒôBz¼sRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ/-³Ø T IDATxÚíyl×}Ç?;³³÷’»\Þ·H‘²d‘R­ÃŽc9²-ÛãØq $E]E“"½€-пýGÑþS(#mÓ6)š®ºMl'>jË’[·%‘E‰7Å{¹\î½3;3ýCÙÑTŽŠ#™”Þ"/ÉÇá›ï¼ù½÷»\¶mÛH$wÊõ>´m›_ö>ΡC‡øÁ~ÀÌÌŒø<™L299ÉÐЗ/_–³*Y÷¸?ù×륥¥…ùùyñ ˜¦‰×ë%SWWÇää$†aˆŸéïïçÌ™3œ9s†ÑÑQÞ}÷]9³’µâ›¦I.—cyy™L&Ãðð0G%™L Éç󨪊Ûý‹gæàÏþìÏxì±Ç(•JrV%Sø.—‹ŠŠ –——I¥RÌÏÏcíííTTT°}ûv"‘ˆœ=ɆÅåäqæË/¿Ì‹/¾È¡C‡äÌJ6ÖŠ/‘HáK$RøÉíƒÛ©æææ!“ÉpêÔ)|>ÝÝÝhš&gYò©Íf™˜˜ —ËQUUEKK‹8tLø…BL&ƒa$ Ãàã?Æ4Mü~?íííÔÕÕáóùˆF£x<yg$Ž`Û6étš¥¥%t]gxx˜¹¹94M#‰ i^¯˲œ_ñëêêèèè ³k×. Ã`qqÓ41 ƒx<ÎÄĆaËå0M“­[·ÒÓÓC Àív£(Òò’üz‘—§sss¼ýöÛ˜¦‰Ïç:ª©©¡©© ÇCee%dzÂ÷ä˜ð}>¡P·ÛMUU•xàjŒO&“!ŸÏcš&Åb˲˜˜˜àÕW_¥X, Ñ4 —ËÅ¿øE‚Á ¼ËÁG}Äøø¸XÝMÓ$‰ðÙÏ~UUŪ®( øýþ[cãÿÊ_âv‰DV9½ضm¦i’ÉdDàÛw¿û]òù<^¯—;v ( µµµlÙ²E*à6'‘H022B6›evv–ééiJ¥½½½lݺ—ËEee%ªªâõz©®®Æår}z›Û!  …€«ã²/­©© Ó4ÑulÛæÔ©S¼òÊ+øý~î¾ûnºººðù|TUUýÚ§[²þÈçó,,,`ƒƒƒœ;wŽR©Dee%­­­øý~º»»Ù·oªª …ðz½¨ªzCb_7¿UUÅ¿«««…=W[[+ Ã0Èçó\¼x‘÷ߟb±ÈÒÒù|ž;vððÃFq¹\kž‰³vy9ÜýÇ?þ1CCCøý~b±š¦ÑÕÕÅ׿þu4MCQaò~2&ÌQ+d=O˜ËåOy™ŠŠ jjj¸ÿþûWLê¹sçøÎw¾ÃÒÒUUU„ÃaEáé§Ÿ¦¡¡Aªï344ÄÁƒ)•J$ R©‘H„§žzŠßùßY±8©ªºbá»%æ·ƒ”J%LÓ¼%‘™å•à“µwï^öìÙÀââ"©T ˲D(466ÒÙÙ)| òX;†aÐßßÏüü<™L† .Ïçéêê⡇Âív‹Å¨¬¬÷o],ªN©½ùæ›|øá‡œ?žx<þ©©‹Et]`~~]×1 ƒwß}——^z ŸÏGgg§¾C¿pá ´µµñÇüÇÔ××SWW'œ—^¯wÝùm6tt¦iš J¥–e‰ ò±cÇ T*QUU…ÇãAUU¶nÝ*Þ çY\\äý÷ß'•J±°°€iš(ŠÂž={èééokEQp»ÝøýþOÍwãÞH+Kùü¿P(P,I§ÓŒŽŽŠ n*•Â4MöíÛÇŸþéŸ ÁËî­!‹ñì³Ï ó·¼89r„ï~÷»¨ªJ$ÁëõFéêêÂï÷ãõzñûýâÁ(ŸÇßqÂ/›)åävÛ¶Éf³ÄãqáN$D£Q¶nÝʶmÛ…BÂ=-ùô11n7àÀ”J%âñ¸8Ê<|ø0Ùl–X,FMM ªªâ÷û©ªªBÓ4Âá0•••â áäðn„?33C:ž9˲(‹œ?EQˆD"477ãñxعs§´Ï7èÃP__À¦M›Ø»w/ÓÓÓLNNbš&étšË—/S(¨««£¾¾UU hšF4GÜJøù|ž¥¥%ŠÅ"…BB¡€eYLOO“J¥°m›`0ˆ¢(ƒAþèþH*æ6§±±‘ÆÆÆUŸ qéÒ%á¿)ïÙÊ¡0𦠅D˜B9TæS~©T"™LbYétš¹¹9a«g³YJ¥†a`¶m³{÷nšššP¯×+ír ›7ofóæÍB7¥R‰ááaúúúPŸÏ‡ËåÂï÷ Åñi8Æív‡¯kþºº®ë$“I<(¢èlÛi•••tvv  …B„Ãá[î¼l<4MCÓ4¶oßÎöíÛ«ÇÖñxÓ4™ŸŸgbb—ËÅ‚8=*ÿ]]]]]â!pLøW®\áÂ… X–E>ŸÇívS[[+vò­­­òîIÅëõÒÔÔ@kk+»wïÆ0 fggEl~Ù¬Öu}EéKÇ„ïñxTUUñÄOÈ»"ùÔÞ ---´´´üÊïsì|¨±±‘îîn9ó’ Ly’HáK$Rø‰¾DrnnŽ3gάúܶmÞÿ}>L&“‘³'Ù°¬:Î, ?~œvîܹâkgΜÁ0 Î;Gss³È—=vìçÏŸçØ±cÌÎÎòÏÿüÏrf%ë—ËÅÓO?-RZÜ–eqîÜ9þã?þƒ`0Èþýûikk#¯@×u\.†a`𦸼££ƒH$B:æìÙ³¼öÚkŽ\p±Xdvv–¶¶6GÆÓuééiÚÛÛ›Ô\.G"‘ ¹¹Ù‘ñ2™ ©T꺱+7z}™L†H$âX2H"‘À²¬BZ Ùl–|>O8^•jz#X–ÅÂÂ@@Dìß¿¥ðEaçÎìØ±CüÐÉ“'I§Ód³YNœ8Á¥K—xâ‰'Â|m˜AMM 555\ºt‰¿ýÛ¿ù°kennŽ—^z‰o~󛎌·°°À¿ÿû¿óçþçŽ xx˜ƒòõ¯Ý‘ñ.\¸ÀéÓ§ù½ßû=GÆb``€{ï½×‘¨F@$ú?þøãŽŒwéÒ%ÆÆÆØ¾}»#¼®ë¼öÚktuuÑÛÛ{Õ¦ÿDH³ûÚ× Úþ455‘H$DEªP(Dss3º®ÓØØxÝ°àžž|>ŸcqÓ‘H„Gyıñ***xôÑGë®­­eß¾}ŽYžo§Æ«««Åœó®»îÙUNP__O0$:2¦¦iìÚµëWþÍkJ=Ìår …UpåˆL—Ë%ÂF%’›…eYär9ŠÅ"@@Dl–dÊÑÀ×D®I‘ï¼óÿöoÿÆùóçWäL&“|ï{ßãG?ú‰DBÞÉM%óúë¯óï|‡Ÿýìgäóùû‡×_ï}ï{ÌÎΊ@µ5 pp]»vqöìÙ›]]×Y\\¤ººšññqyg$7]ø†aÐÛÛK±X$›ÍН-..Š/--‰zMÂ÷x<¤R)|>œ;wNì\.ÅbQ–—Üt‚Á º®sþüyLÓ$‘HpñâEÒé4n·Ó4WíIÖ–|÷Ýw³´´Ä¶mÛèëëãòåËôööâóùؼy3^¯WäXJ$7 ŸÏGSSÔÖÖ2::Êää$ ¦¦†X,°bó¼¦Ím¡P •JQ]]M6›¥X,R]]-6·¶m˶ ’›ŽmÛd22™Œ¨ØV.=ïñxH§Ó¢ ­#—H6*òœQ"…/‘HáK$Rø‰¾D"…/‘HáK$Rø‰¾D²¾…oYƒƒƒ¼ù曫¾¹X,ò£ýˆþð‡2ÜX²¡Y¤f###ô÷÷óÛ¿ýÛ+¾vöìY‚Á §NbÇŽ¢ù믿ÎÏ~ö3 ॥űTA‰ä–­øå´ÃX,&º’d³YLÓÄåraY¶m¯¨_ÿ…/|¿þë¿fÏž=¼úê«rV%oÅ/•J,//³¸¸H"‘àÔ©S\¸pgŸ}–X,ÆÌÌŒˆz+S~d3Ɇ>@[[›hŸsçN:::¨®®& ( ;vìqö’ÛKøn·›ÖÖÖÊ=‡GkÒH$ëÆÆ—H¤ð%)|‰ä6ßÜÞW®\a```Ýýãããäóy,Ë"¯¨ÿW+E” bE"ª««EWn‰þ¯Å0 …§ö‡äóyR©¦i233# ›–ýÀ*ÑÃÕ#Ød2yõõ§(âH¶©©‰H$‚¢(ÔÖÖʇA ÿúlÚ´‰ßú­ßâÃ?¼©lÛ6¥R Ó4Y^^æòåË$ \.—È w»Ý(Š‚¢(lÞ¼YÃÖÔÔ¬*g¨ë:©T Ã0H$,,,`W®\ŰÊŲ¼^/ŸûÜçPUõºƒ%w˜ðo&–e133C__–e‰®èš¦‰b£>Ÿ`0ˆªªÔÔÔˆÕú×áñxDùèk áÎÍÍ‘J¥°,‹D"!¶7ÞxCßçóáñxèèèǼRøkçìÙ³‹E7T.>[]]ËåÂãñ i@€††Âá°ã×PWW·ÂQ6çΟ?/þ],1M“³gÏräÈ|>ÕÕÕƒAb±MMMø|>©2)ü•¤R)a—÷÷÷377‡eY455áv»QU•ÞÞ^E!‹¹üµ[¦i¢KŒiš”J%J¥‰DB¼2™ ËËËLOOsäÈJ¥´´´ i^¯—ÚÚZYAúNþµæÉÉ“'éëë û»µµ•ŽŽE¡ººEQPU•ŠŠŠu9qåæ^¯—`0HKK ¦i’ÏçÅÛ “ɈÍv¹°®a,//cY½½½Üwß}¸\.TU•Ãí üd2ÉÁƒEÝòt:¦ilÙ²…'Ÿ|R¬Üš¦ár¹¨¨¨Àëõnè@7UUE_°kinnGªåˆWÛ¶âÛßþ6Š¢ ñz½Äb1öìÙ#ê=JnŽ”frr’÷Þ{o}ë[ìÞ½›úúz¾ñoAWVV [=È™çjíöL&ƒeYd2 …“““ü×ý“““lß¾‡z躓äÿ¿gëêê'qެøåW¸išÔ××óµ¯}B¡À;#attt°ÿ~Eq¤¹×í‚a¢ñÙ±cÇÆï÷óÀÄ&Þ0 9YhôÚ5Þ‘ß4M,Ëâ‡?ü!ßþö·y÷Ýw±m[ü²±±1>øàLÓdii‰ååeª««ùÒ—¾ÄæÍ›¯^ÈmË_žæ‘‘¾ÿýï“ËåˆD"TUUáõzÙ³g›6mö¾Ìmp–òžÑQ¿¼Ñ+ß°O:v¶nÝÊ]wݵB‹‹‹ü÷ÿ7ÿôOÿ\m¢ q¹\|õ«_%¯pJ•›M¬WQ—…mÛ6–e122©S§X^^&‘HŸ@gg'ñßï_ñ÷¬ç¿Onnot#q›Z[[Ë7¾ñ ñßóóód2lÛæþáH§Óøý~î»ï>qÒ³yóf\.n··Û-ƽ•‚){qMÓD×uáå™™`jjŠ¡¡!ÚÛÛE罪ª*G»JÖÉæ¶ÌË/¿Ì‹/¾È¡C‡/—ËqôèQ,Ëb~~žK—.á÷ûÙºu+hš&š{<q4z3N¨,ËÂ4Mæçç±,‹+W®pìØ1<---455Wc|6oÞü©ø$ëlÅ¿Q?ü𪇡¿¿ŸS§N‰Í¡®ë´··ÓÓÓC(BÓ4avUTTüÆfÅb‘\.‡mÛb³nÛ6o¼ñ©T UU‰Åb(ŠB[[/¼ð‚Tþ­{öîÝËÞ½{Wl ùàƒH¥R„Ãa.—‹mÛ¶‡Q…H$²Ê,*•J¢êüüŸ'S(hmmåî»ïÆçó‹Å…BrÃ)…ÿ«™™™áòåËë⪪ªÅ®ÊQ“†apæÌ™ýxyøá‡¥“H ÿƸûî»Ù¿¿ˆ^\ohšÆž={ä—2çV"…/‘HáK$RøÉ!ü²cèz$“I–——WŽH$‰U§:º®süøqÆÇÇyî¹çV|mnn޳gÏÇyä‘GDNj9»T*‰D ‰d=áñxVødܶm399ÉÑ£Gñz½tww£iétzÕOOOcd2!ü“'OÒßßÏñãÇéïïç _ø‚œiɺAUU¾õ­oÑÕÕµrŇÃtuuáv»‰Åb˜¦)ªÌÏÏ“N§illD×u‘Hrmq¦-[¶ÐØØˆmÛttt°uëVG.8™LrèÐ!ž~úiGÆ[^^æ½÷Þã™gžqlRgff8wî?þ¸#ãMLL044´*Fi-×711Á–-[ˆD"ŽŒyîÜ9 Ã`×®]ŽŒ755ÅÜÜíííÂñ¸J¥ÇŽ£±±Qä8ÔÖÖ®4u\.•••ÂÝo'NœàâÅ‹ŒŒŒ0<<ÌÀÀ_úÒ—èèèàÝwß% Å Ñh”h4ʦM›Ø¾};»wïvdBâñ8Åb‘'žx‘ñÉårŽWK†B!ÇÆ¼|ù2uuuŽ7>>ÎÐÐ;wît,·ªª ]×yðÁott”ÉÉI¶lÙ²ª¤Ë`‡ööv‘òÉ@ÅUaɶm“Ïç) „ÃaJ¥º® QE$MU¡·…BEQVtKY –e‘Ëå 'pz¼òêR,W,k½i†a8–—\.âñx Ù.'Ë;U3¨¼GtªlŒmÛ QÌàz¬)jjŠÓ§Oó裮˜„b±Èùóç1 ƒ{ï½W™’›Šišœ?žöìÙCGGÇ*Ó,“ÉpÏ=÷®i xõÕWEY½R©´Â6íµ×˜ššZ·±;’Û‡‹/Ò××Guu5/^d~~~ÅL__}ô£££â~MÂÏçóTUU‘ÉdÐu]c–ãäý~ÿ§ZAYrg‰DÈår¼÷Þ{¾×u˲0 Cäƒ_ë{Z“ð€°ÿ?úè#þó?ÿóê ?/#bÛ¶cö¾Dò«-"‘Ï>û,~¿Ÿ£GòÆo0;;+*g—ó´þO<ÁÜÜŸÿüç …B¢xkEEûöíÃçó‰Ó"‰äf±mÛ6Z[[9qâ---´´´ˆÊÙ´¶¶ÒÝÝMKK‹Ø<;šl.‘ldšD _"‘—H¤ð%)|‰D _"‘—H¤ð%)|‰d} ¿T*Ñ××ÇO~ò“UßœN§yûí·ùŸÿù‰„œ=Ɇåº%“É$£££«>Å0 .]ºDoo¯H;|ø0ü1étšp8Ì7¿ùM9³’µâ—{Ëúý~à­mÊ™Y^¯W4I(³sçN¾ò•¯ÐÐÐÀOúS9«’·â†ÁÔÔ\¹r…'NpöìYžþyjjj¸|ù2–e­H骨¨ ¢¢‚p8L>Ÿ—³*ÙxÂWU•={öÐÕÕE4åsŸû»w簾¦ÇC0ĶmÙ€Xrû ¿¦¦†êêj\.Á`h4*Šñ8‘/‘¬;¿Ì'[QJ$w„ð%’;ÊÔ¹Q>yÒ#¹1®mh÷ITöÉ]‡Â_\\drrRÎè P(DIŒk»0^K Àçó¡( µµµ¢”£äS~2™ݽ%¿œx<Ž®ëØ¶-:3.//söìÙ«7Äí¾n•º|>O±XDQzzzD§ôr[S¿ßïHÝI)üÿ']]]|æ3ŸáôéÓrV¹ZM.ŸÏcš&ËËËd³Y,ËbzzZø:‰.—‹úúz~ÿ÷ÿê¦ëç¥0®×·\ŠýÝwߥ¯¯O8].¡Pˆºº:E!‡QU•`0({óÞLáßé6y©T"ŸÏ3;;K*•Â0 …–e‘ÉdÈçóضMoo/•••¸\.Z[[óõóº0^¯—§žz ¸êlœ››Ã²,æççéëëGÐå·†ÏçÃívSYYICC^¯WÔ¨¼“Oë¤ðoPì‰D‚ááalÛF×uQœ5—Ë¡ë:¡Pˆh4ŠÇã¡··—ššG ¢^‹¦i477ÐÚÚÊîÝ»1M“™™æççÑu]Tˆöx<\¹rUUÑ4 MÓ(WÊnoo¿ãö Rø¿CCC‹ELÓdnn@¬òåîên·›H$®]»>U[[UUš››ÅQfaaááa²Ù,™LFlžæRÙtjjj¢²²R ÿN ›Í’N§1M“‰‰ ‰¶mÿ¢ú–Ë…ËåBQêêêØºu+.— UUWÕ__oÔÔÔPSS#ö eá/--qéÒ% …ËËË$“Iàj$®mÛx½^6mÚ„ßïÇçóFo‹cÕ;Rø–e¡ëºØ`^¸pd2)ìr¹ðù|ƒA\.›6mÂãñˆpŽ Ó¯©#ÙÐÐ@CCƒxð3™ –e133C:Ʋ,._¾Œiš¢«mÛtwwÓÝÝËåBÓ´ ÷08RBp``€ÑÑQ>Ìo¼ÁßüÍ߬kû|ff†#GŽàv»Ù¶m{÷îÅëõâóùâ¬<ßñá†a0;;K±XD×uñ`?~œ'Nàñx¸÷Þ{ill\×Gss3Û¶mEŒYñUUU„ÃaÑGk= ßëõâr¹0M“b±H__@€h4Juu5𦇠…Bw¼ðMÓdii‰\.G:fzzÓ4 <øàƒbOQ.¼^)¿½5uššš¨¯¯gdd„p8Ì=÷ܳaLžååe–––Ä«>•JQ(øßÿý_ñªðÁ …B¨ªJKKËm+òT*E"‘À4MÎ;ÇÌÌ ‡úúz¼^/~¿ŸÝ»w£(Šè{¶Q(ûG~Ùf,ÛÇéhÌï÷S__ š[X–E6›½žúúúÈårâ¼\UU:;;yì±ÇÄ©ÎFâÚx ‰‰ Þÿ}R©Á`p8Œ¢(ttt°cÇTUÎ0MÓðûý·Å[Pžê\ƒÇã6àµGyå¨å¦b–e199Éßÿýߣi‘H—ËEUU÷ÜsϺ´w'''9}ú´èJŸN§ÑuúúzöíÛG0\±x…B¡Ûº©‡þoÀõγkkk¹ë®»Ðu]{.--ñãÿ˜ÙÙYjjjhooÇï÷ÓÙÙISSÓ-y3”J%ÆÆÆ˜˜˜ —Ë122B"‘ ©©‰žž6oÞŒÛí¦¢¢¯×‹¦i¢£å„þ âõzE»£ÚÚZlÛÆ¶mvíÚ…išÄãq&&&( üô§?ejjŠR©ÄO€rżõzåžå4QEQøË¿üË!ån¸êf…BhšF ΀™™–——iiiA×u±gY–¤ªª —ËÅåË—ùÊW¾²æ”2©TŠãÇsàÀGÆK§Ó=z”G}Ô1áÏÏÏ388Ⱦ}ûozzš‰‰ î»ï>Ç®off†M›69–,288H©Tâî»ïvd¼¹¹9âñ8MMMD"‘5W*•8{ö,uuu477£(Šht"„ïr¹¨­­¥¶¶¸“>::J<gff†‰‰ ÆÆÆˆD"´µµqòäIêêêVLbùçgggÙ·oŸˆ9Y+‹‹‹455ñÜsÏ92ÞÒÒõõõ<ÿüóŽ rr’“'OòÌ3Ï82Þðð0<ù䓎]ßÈÈ===ŽU8yò$º®sÿý÷;2Þøø8SSStuu9’Ól‡¢µµ•îîîë~Ï*Ï­išÌÏÏ“H$Ä*ŸÉd¨««Ãëõ233#"?¯H$DÈ«†Á‚cñíNˆêNõ Èård³YÇ’Ú …¹\Žp8ìXEµååelÛvdu†_”G Žä”ë• üFÂÿÿ>©gΜáÀ+~A±XäÌ™3˜¦Ég>ó_"¹©”J%úûû¹pá{÷³ShζmΜ9C:f÷îÝ`çøï¼óš¦qðàÁÇ›©TŠÃ‡‹š-ÉÍäòåË ÓÚÚÊØØñx|Åþaxx˜þþ~¦¦¦ÄÞtf0Œ ·IDATMÂO$„B!WÔs/§¶)ŠB&“‘wFrS ƒ$“I>L.—[Ò],EÈ|9‡ZœêÜ(^¯—¥¥%‚Á o¿ý6ãããüÉŸü‰ˆE/·•Hn&™LÇCOOŠ¢pøða–——Ù·on·[d¨]{üª¾ð /Üè/¬®®f~~žGyÃ0PU•îînQã= ±sçNÙÉCrS©¬¬Ä¶mfggÙ¾};‘HEQhll¤¶¶Ã0ˆÅblݺŸÏ·öÍmÙQ ªê*Ç‹°¥¤è%·€k`em–-ëiÑÑD‰d£ —c‰¾D"…/‘HáK$Rø‰¾D"…/‘ldá—3•®G¹q˜<þ—ÜVÂ/çÜ>|xÕ7§R)N:Å¡C‡X^^–³'Ù°\7H-ÓßßÏC=´âó+W®055Åàà ›6m‰}}} ±´´„mÛ|ík_“3+ÙX+~¹Qq(Õ à N‹Â¥×šB444077ÇK/½$gU²ñ„¯ë:ÓÓÓ 255ÅñãÇyå•W˜››£®®ŽùùyEY‘"ÖÖÖÆ}÷ÝGgg§,.Ù˜¦ŽªªìرC´tß²e õõõD£Q4Mcß¾}†áXŽ©D²n„m·ëP(´"9ûvnw)¹ƒM‰D _"‘—HncÿFçܹsrFoc®õÖ‹®eÂá0===¢ÆÒz®§ä˜ðe[ÉÛ ]×±,KTŸÓu‰‰ Ž9B±X¤££ƒŽŽŽ?333Ã[o½E.—£££CT9ˆF£Âÿ£iÚºÈÖÍßîp …‚pFZ–…iš˜¦É[o½Å¥K—p»ÝÄb14M£­­|ð7*322¡C‡(•J,//“Éd¨¨¨à‘G¡­­ —Ë…ªªbÁôx<·¤ó»ã+¾d}cš&º®cÛ6ÅbÃ0°m›Ó§ODZm›t:M2™DUUž|òI¾úÕ¯^ÝÞ@ùîkßå Éd’·Þz‹×^{ ŸÏ'|CÁ`îînjkkQU¯×+šV—»±KáK~#‘—‹(¥R)ŠÅ"ÙlV˜,sss,,,`š&÷ß?[¶lÁårQYYI4u\heÓ&‹ñ»¿û»ÀÕB±ñxœR©D:æÜ¹sÌÌ̇illF,CQ¢Ñ(>Ÿ—Ë…Ûí^ó5Jáß&d2æææ°m›B¡@±X$—Ë166F2™¤²²’ÆÆFü~?ûöí£©©é–šŸÄï÷¯p†öööWK¹ŽŽ’Ë嘘˜àøñ㘦Iww7ÕÕÕ¸\.B¡ªªâóùhll¼¡‡@ ƒ‘N§I¥R˜¦‰eYd2Q{ddDØË^¯—ŠŠ {ì± ^F‰F£«>?~ü8cccضM6›Å²,B¡ÝÝÝ(Š‚×ëÅçó¡ª*‘Hä—–—Âß ÏòMN$¤Ói2™ ©TJ´ Êf³Ø¶Mkk«0#Ün·cmzÖ {÷îeï޽ض-ö' :tÓ4ñx844ÄØØÅb‘……ŠÅ"½½½|þóŸoG„ŸËåX\\$•JaÆŠúä’µÙíåÍa$ƒ³³³¨ªJWW—ô\c^¹r˲ðz½466Š·£a«yŽ¿Afzz˲(‹˜¦¹Â“¨ªªBUUêêêDGÊÛR©ÄÈÈ…B]×YXXóp­O lòlÞ¼ùºM錄AèììÝ$Ë^ÕË—/‹¦¦i2== \u†!NN"‘>ŸH$ò©žäÜèFÞ¶m†‡‡Y\\Äår‰cMEQÄ¿ëëëioo@Ó´_»Ç‘Â߀”mÜžžžáòiÏÒÒÉdÓ4¹rå ###”J% ÃÀ²,îºë.6oÞŒ¦ix<žO}`Û6¥R Ó4™››£¿¿ŸT*…¦i‡©¯¯GUUšššðxŸO4=(ït]'‘HÏç1 ƒ\.'ºZ `Y~¿UUÑ4ܲ6†a0<<Ìàà 0ßJ¥Á`ºº:êëëñù|øý~Ê-iÝ¥¾D¼êëëW}¾¸¸H"‘À²,r¹†a`š&ßÿþ÷1 ƒ`0(Ì*¿ßOww÷ ‹Î¶mÆÇÇ™žžF×u¦¦¦H§Ób/ÒÐÐ L–røBMMÍM¥ðï@b±±XLlË>úúzLÓ¤P(0;; \õ¤?~œB¡@}}=;w¢‚ªªªUâÔuùùy Ã`jjŠ?þÛ¶©««#‹áv»éííÅï÷£( áp˜ÊÊJ°v+M.Ç„_Žì“l,®ÝìnÚ´ ¸ëSÞ(š¦I6›Å4M9sæ Ùl–ååe ÃX1–¦iD£QÜn7µµµ<õÔS"´ ¼ õz½ëbƒíØœ:uŠ×^{M*é6@UUQW ®6W¨¯¯§££CÁ}ò$üÚ2MÓD3åuùÀ;5ÐŽ;xüñÇù×ýW©œÛ”ò)Ëí€cF•ÇãÁï÷KuHî,áK$Rø‰¾D²A„_öò]T*%\ãÉFeÕ©ŽeYŒŒŒ0>>Îc=¶âkétš£G’ÍfyðÁ…$•J‘ÍfI&“èºÎÌÌŒœYɺ¢ººzʼn”Û¶mR©¸Ýn*++¥¯¯o•ð/^¼Ààà ===Bøccc 188H2™äÿñ¹X˲Ðu]Ä ¬·ñ‘Ô픋ýfŒgš&n·Û1ÏhÙqåÔÑf9ÒIﭮ먪*ÆüÃ?üCÃ$VüD"ÁéÓ§ñù|lß¾††¦¦¦°,‹xÏ™3gøìg?ë˜ðËÉÑ»wïvd¼x<Îôô4;wîtìúhiiq,ÈkzzšR©DWW—#ã% –––¨««£¢¢Â‘ixx˜X,F}}ýuõèv¹\lÚ´I¸«K¥§NÂ0 ’É$£££Œ±ÿ~êêêH&“Ô×ׯðÊ•„·nÝʽ÷ÞëØM[\\äÍ7ßä¹çžsl‚ßxã žþyÇ„?99ɉ'øò—¿ìÈxÃÃà ðä“O:v}ÃÃÃôööRUUåȘ'NœÀ0 Ǥññq¦¦¦èêꢦ¦Æ‘7Ò¡C‡hmm¥»»ûºß³*«T*199ÉÜÜ]]]èºN*•¢¹¹™`0Èðð0.—‹æææ]QDŒ´‹Efggikksìõ7==-âPœz+% 𛛝œ.wmO‚µ^_6›¥²²rÕýZËbY–cY^Ùl–|>O8vÄij,‹……Àu³¯®+üÿcccLNNÒÓÓ#¢ìàjRÄ… PU•mÛ¶Ý6nnÉú¤X,2<<Ììì,´´´ˆ ,Ó4$›Í²mÛ6g’Í9‚ÛíF×uöïß/~Y&“á½÷Þ£££ƒŠŠ aFI$7ƒééiúúú„Ð#‘ˆ°:–––èïïgnnŽX,F{{;Š¢¬Í533CSS“Èn¿Ö\J¥Røý~‰„¼3’›Šišäóy²Ù,…BaEÔh¹.‘išär9ñµ5 ? 255E$áàÁƒ"2³œížJ¥M“H®‡ªª¢¸ÀéÓ§yå•W¸rå ^¯]×)‹+òÔ^xá…ý…¡PEQرc‡Xñ»ººPU¿ßO]]Hj–Hnš¦áõz ‡ÃtvvФ—††¢Ñ(Š¢-–¿¶¦Ím©T¢P( ÑuÓ4 ¢5ਲ਼H"ùUÜk“¥RIÔ×)‹X–%D¿æS‰d£"£3%Rø‰¾DróâÀÚÑßÿÏIEND®B`‚snd-16.1/pix/ffts.png0000644000076400007640000021406211147553266012622 0ustar bilbil‰PNG  IHDR®¾ÏPsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEÙ 9÷..ª IDATxÚìw|TÅÚÇ¿sÎÖì¦BïET, XA@@®("( xQìb¥X¹¶×rÑkņ¨\ëTT@zï=„´M²õœyÿ8»'Ùz~|€äÌΜÙ)O›gžG´º°¡l{Is¤Ž ,X°p@Øl*K¾_ŦïöbkÛµ9ïÒ)Y#cÁ‚ "?ÅHä!Ô’8pcÃN EÄ!Ô”$ˆŽFR8„º $¢¸ ™-Ã` RB‘¯ˆ"ù•ÒZ ,„TXûÄBE”âãyuÉJzëØ¥ƒ—µ»X,¿áÛ:¢¤Æu]º—Úé4m¹_}‡ ð׸nPós“Þo0 ]wÚ€ dÈ`¥»Ó æ&Öˆ‘(Ž0I­²ªf­„Lê è%ÕŠ.%á˜ô©¹ë4jÙëãPœ¬ ÿJNiÖ1]jDd‰TaÃ&ì5¯NH÷cvlÂ@D†¸(y!JYø•’P±µ- ¥ ìô“Ñ Z$âàt×—›o!Ò-À¥“‘Y§fëR×Ù¾r=24¡á©—ˆÇéEQU4M«Ø9T›-ú£Î‚Ÿg!êªHÆ?`ddH %äþÒ÷Þ‹ñxª•—ëì-Ü@Bݱy4³A '€Ô£óx³HECJ‰¦kªªâ <”u¢Ä^N†@;­ ÁÕh—x1£ë>MŠ-ƒ`q˜û_½½gâÖ•üÃ} Ë]'Ñ%õJê;›QªùXê›ÇwâžµÑÀÙ’‘ ŸàÇ’O™7%bïù¹±ÅcìÚ¼‡?ߌޡ!¬=c1NRRì+ªÁš”–ø@è¡2²ûøc°ÿþjk%$x?îa4-bÔS‰ qÛ-·Ó½[7zõìI0ŠöK’œšÆÈ‘7Ò½[wºwëŠ=(ÐËíIC‰€ K¤.•†õ CÀ¬r?*ŠBíT…%»ŒÎ8¢#aá„€®IR” Š·EHLJ¤a½F„Â!6n^OBb2«†KNy%„^ª”-aGGG—ši¯¡š6؈ #¢tôråi—R¢S&å((¡ IIC[kRl¼øÆs¼ôö³¸ܤç;IäG éU¿O!„›Á.Dd‰DAAFÿ(¨&£PQ£õd%ösJÂÙÜ×ä m)ìÌÞNjb4èOG­OäÅ¥&‘a³ÿ:z…6Ái÷Ð&¡# ?[Áž¬ õº ¬ôýÊë›&°;¼‰ú®æ¼xÆl–üˆM±sjÒ9¬ö-äÑe#ºŠ©ãhÄÍMŸ¤mò¹ C@”ðÒʘ_ô)v‡Ãâ!' «Œ™HDÜacL@1|MÓiÙ²%²ŠúŠ¢••Ôu£nPB?P\\Â÷sæ0pÐ Äô?¤yóæŒy{²²èÚ¥ wßy'y KôPT‘1bš°$HAªZÕ÷`w¨øýΨIN †ô#ªªàJbíz…uè!C´p‚,ZÀ-½´ºIR/#¡¡Þ(™f’pçc´J<ƒWÞ~‰ÛßfÙö]´ê—Áû9¯³êÛ¤e¤òøÝÏ0,e"+–ô'P¿€4{mÖ³›å¡ÉŒ¼v4çÕ9+Ho‘ÆåuG°iëFž}õ_Ôªô öûÁÖc/¿ìŸÍ¹é=øòÛÏøþ—ïXðËn{n$—×þ'³æ~Åü_àáÛåæ:Oq߆kÈMß @ÄÌýpïlúÅ›6qÅý~H…Ìý­yéý¹sä} jp?üöO}õ÷Þô}\£˜¿þ´yq¶ §&ò•KXº~-.­ ™Ÿý9-ÝÍ©‰ø|ÑB± ¾% ã—>Àý7gpú½,û}…¶2}Çd®l4šŸ~Ç'³¦³sÛ.Šº  äR¸)D$5ÌÐp^z^}o2¹ûsyð¶ñ K|” +†¢75ÁižóxòåGÈnWÈ%ç÷ ùÊ®,ªÿ1·¿‚¶Éçò¹|0óZ5?‰m[J)¬­~ ¬ýxBìEÝÐ*L ¥Ff/=bXbuKKK™ññG‚ÁJŸw%x¸è¢‹R–i "J ¤ŽÍ¦2ù¥¹õ¶Û~ãôêy)ß͙í·Ü­£ofÿþ\U1¬¡¨Ù­¢"C‰@j"Ú±˜Š$¢DGA"P!š.Ñ5ÐCÂà¢Öz=á`KÕ°¥è&•ØRul‰ñZºòw^ýàßxO“(‚=¹!.;§1—ŽºwB‰Cua_^°k;ölgê§oi^ÀHF“ê®Eá<)u"”êE4oÜ’‘×bÝÞå|±h:‘}P¸«”M VpnzÖn\Íw›f¢¶ŽÐ­ÁUøŠ}|øÙT–ûçsÞêséÕñ8~oDøŒ­¬ß´ŽW§NF´,&”@µ&Ÿ¾˜ÊÔßþèá·"‚‚gNc~ΗÜ{ÓCØU¬H#”Z€=¹l7HÅØ¼…E…$Ôvà¬Am ¥‰†mÙisáßl¬õÂâÞŸù6k#¿ÒiíYôêp¶eu©ÛYäþž+fËöÍ|·á R»PuGÌn‡îöi\Ñ—-Û6óágï#›ÒsKÚµ8‡Ü êŽ4&å‡ßæðþgo¢Õ-âzPßÝŒÙóûZãÝñŒ³q¸UVf-föEˆ\Z¡ŽâÑ­=yB˜°Ê¬7º®£(5d<C{¦ð¾b¡P¨ †£—ý/ -B*Â4‰éºFíÚµ™þÑ4zöîìÙß0îá‡èÛç2 L©SJÝà•Î@†Œ~!¡ (j¹ DT¢ÌÞKÔžf­ÕpñJAÔœ_¶ØB £BLnn.®L…„FZðp‡Wè˜Ñ…={w³aózêÖª‡¢ÂG(ê0UZRŠ’¨£$…M«î—ìßÇÈûÒ)òNiyW_4ŒÞg àºÏ. ä AX˜ëÌž¢x¡†êÈ Dõ€3QÁVÏh3R$ñ¯3Ö_AA>¶t‰£ž‚çÔ0¶c% qfF ¶®”¥ØÓ¥¹Ùô0„÷ lnißiŠNQ8ÖÍÚàt¸ EhÉI‰íAÂÎÝÛ‘¥ª9V¯ŠË¡`«íW±$¸Ù†h*Ì3Õ)H쨣ºÊmlQfƒÖugš‚^Ôô¡}:ÁÍ*œûssH¨kwôüFHŸÊÿ6}ĺ¹;9·^7Î<¥=#{ÝE—3z1âÛ. xуÖú>!4˜¤Ž®Ø|%DT[@Äö15 c-Uò¤ÂXÿ1f"Œ=® 꺆®ëØl‚›FÝ‚‚´´4žœô§Ÿv Ô26ã¬Qç6e ¤œ–±‹b&+QÎ#@šîeB@”'86¬3ÒþjH2å¬d¤Œ©ã`5Y'è—Ôr‹éóYŸ°5k3œ}QÙ" *euš¢—Ùk… zŸ~‹ùsS¿N}š7nIö4H"z¹õ£ƒ-äàû]3éß|—_2€ú¾d.¨{9¹ûÈÊÙž¨– 6ªÀ–*Ñ‚¢,¢‚(ž2¯H)ŠWÆíFèaAì:"4¾ØøƒO¾{†Œcaøk5lL—ýÉÍËዹŸâL2Üy““RèßýJ–”¦Ñ¹Noöçí'·`Zº@‹ ¶iu*du%âÍfUñ¯qc¯j6dϦS³ôº ¡ú9œžrËW-#""è~¥ŒjØAõ–íZ sSz“˜žÆ¯‹ç°}ÿ&š4lJãŒìž!éFaXB,©îøâL& رc6nŒëʇÃôêy)BdôèÀXà²lãT1éÒtp’„¡EØË’0~Â#,[±‚«¯º’a7 eä¨[4xÿ÷Ü3œ×é\ …¨¥*î „2¢!¥±™UÁír› M튪`Sl†-.,ÐuqH·!-/ê3¨š»ê Ñ›d¨·å„ Çp[847o.ŸÄ½m_⦡·òæ_AQ’“PU1VTbb¢¡uh±6¼6ÝF×úý¹zØ(@ ™üæ øý¥¸·©8Îtf"‡$Øu7SW½„¾3~ç]M_Ç?Ø‘µƒIÏ=Fvx;‰Q‹×ã5ô $(^ì6;RÓñÚ“pØØl6ÐŒ>&%&¡¨ B7 23­dÆê)oÒxþ ôN½€Çs¯û'ûçjó%2,IïT—ÞÓZ³å¹²wçgóØ£¹s’N(WE’ÐH%¡,Çλ§%y?ëxO²1Ç̸þ3J6ë$æaöÖéL{o:¥Û$Z©ŽPÀž¦~z2¢ßËÚ“Ç? —Yw!°ÛlØíU_ZµÛíH]7Hq$*ü(¤ÄãñpÁÅ—Tû¯× RÚKȰ:! 癫V1dð5\uÅ?EáS’“™õÕç\pñ%ìܵÓÐôÈJ&,d”›§ìùìåÃE¯×@v„(E³I¤fÀ[8ñ …%I' < èaãV‚«4¼Ê4ãà )Hh.qÔ²‹WH t ûAµKP$ ;фĞ ¯vR‹&qfBínÂ"ê}Â.±¥éD|P»‡­(jJ ëHi˜¡RÏ$Û {1 $J„ lvAÃAô áK¯‡zHRÿ*;Z1(vˆ”ê4lG+Å%ÑÃ’FCœh~‰b+û^qŒÕ­“r¶ ñ»±Ñ¤q–¢&k„»ê06³$·¤up # \Õ££lÉ’ZÝmÈÒ¨×Lôÿî0ØjI2ºªÈRÕ4¿©)R€·µŠ;Ó†Ô@ è¤uRI>ÅÐü5¿NJ{ð¶R@SA)$ŠK"\ÒpË·pü[ŠÉç¯pC®r@šëó!ÅpvŠj %¥~¦LyUU«”øJJÑ3K(BàùuÁO„B!‚Á(em#~ûuÁPM×A(¦³U9–0.†Œ[¼{Õ-d«[j>æ!¬%휰:J2(ÉÆ4Ì”Íp*”±ƒu‰ xãêoY=%1‚’ý=Jr¹6 xª°ÑÆÎ—mjzÙù ±çŠ4úVn©Åú•¤Š}áÔ°¹ÊÚ ¶„²> o›7þ{ß<‰’X1´8" ¼ôÓxvÏò³{÷nÔ4’¢EoJÆ·'Âe Tÿna×)U|?¡£¦–ï”DM+÷@M’•úhi'Ññ:“Ø·cÁ`þÁCÜ lÒŽ IÂIî¾,# ÊA+ Ò ªÛðø•,¬>–Vž/­*ðØ=h!IœaêŠ'.”j‹R öZ³iÁB 4oÐ^A{ ¨É–¢…Ã4a!Iv¦¡k5?³üZ)a=LŠ3M B]/\€ªØñؼõüª°ôñ… Š@ÛocÎÃk° ¢n¼aA¤D#Œ`…è±`áà› 7h ` ‡…ÃG){ÿ@Ýà 8¢ˆ’C®åNt‚½LZ²!@"…’ü™ œÛ®3šnE×µ`Á‚ eº’jSùߺé´ìS+Þ—°‚î4kМWÞü?ü~+¹” ,X0àpØùàƒÿòÖ—ÿ¡U¸®ÄÓ&UUQm6t©ûñûK¬PÓ,X°`]w°}ûvìv6»P4ì»`SmØlªuhÁ‚ ª…¸”…‚Õ¦`³©ÿ°`Á‚ d ö8‚4LXªÍ ,X°P=Q6»Í<âPbg † ËÒA,X°`ÁBõH¼ ‹Øˆ¥X°`Á‚…3»ubÁ‚ Š0LXå4‰¢¨(ŠjŽ ,X8€¢Ä—Ç›°¬3 ,X°P-‰‡èÑ‹„† ëP ¥ÄétZq³ŽsèºN(®t1TJÃûÎÈ=` Çñ–%ð—¥®0‡.—Ëš? ‡µ®ÂᚦҥñØH¬ŠÍ81Üxe:NÞÿ#ŠŠ|Ö\Çhܸ }úôÂï÷Å-!;vì䫯¾9` Ç‘H„»ï¾Ÿo_%&âp8˜<ùuk,–`yÉ%ÝiÞ¼RÖ<"oÌ7”wã=´ Š¥¥¥ÜsÏÔK bḂ䭷ެVK …Âôêu§vº5TÇ%ìüç?ÏS]¨n!Œ½{çX{ÐÂ!aÇŽmìÚµûÐõ– n¼6ã"aÌ7rÈ JD¿5#Ç#ûT= ‡#@©e9.á<¨th[†á0Bs[ø;Ó†ÃËA`˜°ÊRîÚ$`STõºñZ‡!Ç£bÍßß ÖZ8º0ÜxËLÞJì äPÑO .+ãþ·ð×B$!//ÿвªY8®¡i¥¥þrr˜¼¼ü#¶‡u]'//Ÿüük°S±ÙÊ…2PU›áÛ+ÿj_ÖÎçŸ]¥‹…[¶lç’K.'''׌¿6nÜ̈·†™ä÷ß—Ñ­[?#“ö±  +®¸–´´&–ÆöH ƈ¢D=qþJD<Œ3–¾}EŸù£g6*àBÊ’è 8£šJ!lÑÅë(·ÀJ‘2ýlB´,†¤ [ùSŽ’)DJ 2EQRÒªU;–,Yš)a*Jj­…‘2–ç&¹Ê6-+$Ç(¯×cþ~Î9—ðûïË€¢*èSùy”躡Uó_ $Äf]/BQii©|ÿýœzêÉÕÐŒÄòúRú¢ýJ©°N‘²èo·ï…ØÊ_$””™°þJìcÇŽ!ؾ}'B„¼÷Þ»¡°nÝzn¹e4BØB0mÚ¼÷Þ{!X¶lÿú×$Ú¶=Ŭ7kÖ¬èÏNî½÷ó¹‚yóæYÌã¨1oÜX§¤$£(©Ñ2»ù|ûö­e ZIEU•¸zªªrë­·DWÖ¢E3³M þWœŒŒ s. ùÜçóÅÕóûqõÚ·?EIEQRHJJ䫯¾4Ë:wî„¢$—›c­J³ç¶mÛâÚìÓ§7B$"„›úõë¡(†0S\\B·n]£ÂäßLQ*…2‰¹ñþµ‚)6jÔ0*¥¶@J‰”’k¯½)u¤”hšVNÕÍ¥ª*÷Ý7yó¾6ë;ž`0ļyßãõzÍçRJþùÏÛ,üQ‘tRÂ7Ö9 z B¸2Œ”’Q£†‰hqÚ„¦éf]»ÖХ˼ôÒ«€!’ãÚüí·9 4!Ö “9ŽŸ&MÚ’œœ€ËåDJI¯^Ýâ¼)$$Ô‰«÷ÙgÓxæ™GÏWÌ¢EK̲çž{œ‡º'jy¨Mš4‰kóæ›Gðâ‹Ï‚H$gò2~ÿ;ΙLѸHhžü•¤0U]õ8ÇÁ´…H$̃ÞMZZ&P$àv»\.ï¿ÿ[·nCJ‰Ãá`ÆM%8*ðï?͵×4/:z<Þyçƒr¦„ÒJ¶qãy!àâçòûïËøöÛÀ4‡yÁ`€ýûó©[7ÓîcŽB¤”lÜø;?üx¹ç!‚Ñô©eð3iÒ† h:ÿ´lÙ‚|¸\N&L˜sAi©·Û}PmHÓB\}õå¦ mãÆÍŒyƒ55MXv;±Ëe60ÜxÿêÑx ³GPùΊÇã¡°°ð mhšF÷î]¸÷Þ1hš¡uÜÿ– ë(@×ýŒ}7=z,5Hqq C‡^Ã;ï¼8×K–üÊòå«xúéÇLBäI(((›ïÔÔ¬‹x'ÒÚ0vì86n\jZNÖ¬YÇ3Ï<ÆÝw?t˜„1¶mÛòãÿÃç+`Þ¼Ÿ+1/)%^oâßÖä©ͦšº˜"‘Y7^dd¤““³—‚‚BzöìM~~6›Š¢rs÷²mÛú÷ŒÇcØ3m6;?þ üDvö^ ³IH0Êìv))ɸ\.ÜnN§“zõêZ äh,T%•¤¤DêÕ«‹ÛmŒ·Ëå$*ÛÐ99Ù”–úÉÉÉeß¾œ¨‰A°o_ýûfâÄÈÎÎ&;{Ÿr§ví sþÜn^¯‡””kÀj×ÎÀïßKvö^ŠŠ|Ô­Ûš””d“Xççg Ù·/‡ÜÜý€@QRILL¤aÃúæ<ÚívÓ¬¹îºA’½Ÿ¯¯×k EEY„ÃaöîÝK^^¾¹nB¡ nÜn6›Ê 7ÜLB‚¡¹¤¤$SR’…ß@Q’IOOûÛj ñ&,(»‰þcªºîã—_Ò¿4-Âã?Ljj*©©µ¹òÊþŒq+‡¹s¿`ÇŽ€áw>iÒ>ýô ¶nÝN àÕWŸÇápбã¹lݺ›nºEQ<ùäÚ¶=Ù¢G|îò)*òÑ£GW½QM1iÓþÕ(T®½öF233ù¿ÿ{'·Þz€[n¹‡nÝ.fРa!¢vôî ~={÷æÐ½{’’ o›ÌÌÚLžü2†×Ž…?{ŽËÏG @ÊbÞ}÷=@'‰põÕÃhÑ¢9÷ß?‘úõëòüó/¢ëùø|ûéÞ½§9-[6çÉ'Ÿ$n·‹ îcèЛp8œrJ&N4LZEE>®¾z\ЉѣïæÔSOf„ñHYºu‹¸ì²$&z±Ûmde­gÆÍHYÊúõKèÑ£_´ß!.ºè¢¿¯ «âˆÍ̉þ×â Š"²€O?}FJ­[7°lÙ fÎü €?~ÛTU…0$ØgŸ}ÐãêA€«®ÀUW]]î-!¤Ô--äˆÏ‚”ÌžýUœF3GI©1kVÅ2Ãô0}ú‡U´¨EÝ­ ù曯+Ô+±æïÍ1Tœ ×]w-R†±ÛíUÌI´^ B==º6’ÑufÍNçóÏ?­P&HMM©Ð¦Ž”†GWå÷…¨S§.`§k×K™3ç‡èóÒ¨Fû÷[3†–=^Aˆ¿lXvƒ0ã~oÖ¬9¥¥~“hôë×›O?ý)KËÕ ;x/{Fô™VÅ;,í¹+?Ö*«î|¤ºrkþŽ5*ÎW¤†su°y F½Š}‘Hàå—Ÿ1?—@III¥³µ¿×¾,Ï@þ0N<àÇqÀ[>7‹‚¢Â⃷}û²øõ×­Ýg¡æt;¡aÃfÇžY­Tzõêw9ÏÂ1×?}|þùgÖ=T•¥K—sÛmc …‚Ö°%„Ãb“è/[ºšsÏ9×ô’RÒ¢eK6m܄ƕ¬ °mû¶ƒ¶½oß>ou IDAT2œL£&-¬¶P#•굡ÉX/GD³Ûí¸\nvìØaMα–u¥$11‘´´4TU¯‘¿zìÑ^îpÌ‘f 6|¾â¸3‡ÃªªD":tìȪ•+)(, Nf&RJÜnwct9]n<^k -ü©8¢F¼Æ[#z`èС¼ýöۇ̀ªÊŸ#z5­±À†VÂA×u222(*,¤yóæ¡iÚ·ò2”KËTiáød ›7o6cÉ$&&rÉ%—°jÕª£ö%¦NÊYgEË–-­óâãá3EQhذ!N§¡8 ™šå€Xºti:ýôÓ™1cºnh;µk×&5Õˆ†»i“æ¥&cž”dÄ~ŠD"4nܘ‚‚3ÔÊá N§ ÐygÊ{8Æ\ÖÎÌäÒîSbY*-¯ ¤°°víÚý©_bðàÁÖL(ŠBff&{÷î{^·n]²²²˜7o999ÕÖõz½T3±P†zõêár¹ÌóÃZµjñéÌ™\xÁ‡Ý¦Ã!xÿÝ©èºÎ°áC‰EãÈÎÎæ_O=˰G‘pXó …PU5î°ÿ a$µ³qmõxYš¦¡ë`˜ŠÿJûâˆ3ÙÜSRRèÞ½;‘ˆáç½bÅ 6n܈ªª´oßž… ””DݺuY¿~=v»víÚñÛo¿Ñ¯_?l6 .4¥â&MšÐ±cGŠ‹‹ùßÿþ÷¾FqÖYg¡ë:ªª2þ|öîÝKbb"7fÕªU 0EQ˜;w.¹¹Vb¢îÝ»Çm¾/¾ø‚Þ½{ÇÍí|€ÓiDJ0`€yãÛ¡1l¡(qÎ'@€›FŽä»ï¾£Aƒ‡AÃÌÿáG®0·ÇFdúLÔ¨'^Cà¾á#Y–µ‡º™uðxíÌÄn‡v§žÊwßÇõÇñG}fСsg²vïæ®û䟣F×ÒP(ÄšU+iס=Ç:Pv±ÏÇø‡îcÉâEx½^^|åuš·hÎ_%€÷7P·k׎/¾ø‚¯¿þ:ίª*Ï=÷‰‰‰ddd––ƨQ£hذ!.—‹çŸÞülëÖ­9r¤I˜.»ì2fÏžMff&)))Ü{、§§àv»q¹\|ýõ×qýHOOçÞ{ï%%%…ŒŒ ’““yä‘GLóε×^Ë7ß|CJJ ‰‰‰Lš4É4Ûü]!¥ä½÷Þ3™Ç£>ʶmÛxã7Lâôüƒ`0Hnn.yyy<ðÀ1H4BJtîÜ™ž={Ò³gO‹©Ôi©©B• ié釜ISJIaAž„T [žx®ê§_o<ýzãî×Î>““NnÁºµ«±Ûã>]×Iv÷7V®ë: lÞ¸›G#)KÝ6ÕÕ+ÿ<ö9]×) H.^Ä+o¾S)%BU}9XÚ„XEQxâÑñ$ÚËêÅÊt]ÇYE›RÊ*ß«'DÕ}©®^ K—üNff/^È{Îà–‘ÃqØ+Wå~jxª)Kv‚ÍfüŸTƒq9¡4Õ«WÓ¿<OÜS…6mÚ0lØ0óÙÓO?Mzz:yyyqa¹u]7ƒæ…B!víÚņ xï½÷˜6mIIIìß¿ŸµkײvíZÞ}÷Ýxé&1—Ëe?€>}úàt:ÉÏ7òhOš4‰¹sç0lØ0l6Û²=Ÿè(ï!4}út233ùç?ÿi2”]»v‹8¹,\‹-xâ‰'HNN¦~ýúìÞ½›‚#3\§NX°`Å%ª!v§¶mKIqq•¹xԯϺõëÉÔ¡(‚ŸœG¿Aðœr*êšÕq·³$ nÞ„GQhÖÙ²e;5FJƒ¦ºjÕ®mÎ_$lä\)eÉ))û|LxlwÜsš—àâ‹»òÍ÷sÌPß±zù~T·‚ÓéD—’H8L^©Fjjùùy¡$¿?îK¬/fèð }©nLRÝ -[µfÛÖ-hš†Ãá@Ó4SÃKMM#??ɯ½er‡ƒ`0HA@âq‰¸÷9ìJJŠ£ÂhË×m!¹v26»O‚‡‚‚|óû•¯—’’Bξ}f?UUEJII’’“™þÙWø’„ ïkа![7oŽš „B!®»a¼÷-ZµbÝšÕ¸Ün‚ßÎ[À€Ë{ѤI3–-ýý€ãrB1p8L$©QxôC!lå3’ 4¨FvÇáÇsÙe—™[>b§"®;wþÛµ£X´h3gÎdêԩ泘{pE"6¶………¡ë:)))H)ãæÌBeðúë¯W©ùJ)¹è‹¹ÍˆADQ‘1?å窬qT5^rMp Î9·3›vî35€ÌÌ:ìÝ›M¾_§  €ek6ñ櫯ĽÓápY…&%¥¤q“¦øƒAÓÔ{žï¯ÞC/Ù%HŽ®¡òp»Ýøý~ «‘ñòý:ë7¬'¯8̰k¯æóOg˜ÏòóóBpßCã‘R¢ 6bûÎø2î}pR›“Y·v ¡pˆ«ú_f–GàÌöXúûâJZ¶/ ®Ä´§±dÙvlßJnÎ>Ö¬ZM›SO!!ÁÕhâëmÙËåý¯`ÚŒ”†B†÷Ù×¼;å VoÚÁÀk†ðÑï…RrÖ9ç²+'Ÿuk×3|äͼøòË‹WÚ]|!D¥ãÐ1Ÿøü~ÿ~ŸÝnçÍ7ßdĈ¥:„9zíµ×ÈÎÎfêÔ©•´’qãÆñÈ#ÄÕ‰1᳈!EQ"f¡*mAaÛÖ­\Ú£GµÌ¼AÆ,Zòçhpa n¾íNºïnóYII1{÷f“WjÜ/ 6ýŠ’n~^ûòóM¦ä4’¯•_?å5!½Ü:©uêÔãö»ÇšÚƒÝf'Áã9è˜ú‚PTXH8&ƒeïÒ¯7‘'@AÀ Þ·ß5– ).Á7ÆM<¥k™uꆆ´à§ùøu„¢PRRŒ×k˜lïx·Þ~·ùå<ÿýx!`ÊëÿaÏî]ìÙ½›`0ÈÞzŠwuc̰¸¸˜!  8ÌYçœË€¾=)H\.7ý¯¸*®žÓ風¨i) î„c– ðˆ3˜KbE„B!^yårss (ŠÂ´iÓX¾|9š¦1mÚ4rrrƒlذ+Vмys6oÞŒÓé¬ö’ÛàÁƒyæ™gÈÊÊâî»ïfêÔ©lß¾;w’M$Áét2räH>ùäSšù«¥ñ=xøá‡ñx<¼úê«æ³“O>™o¿ý–áÇ“‘‘a º®›îÙ;vì ---.óÛòåË­=Á«.5ª”ò°lÛ‘H¤F @×ôr–ÉuW_AË–­Gûäñxh{Ú¬X±Œ¢Xv…"(ô…ª ›³xÅ:6hˆ”:žb¾˜=—’äî …‚ 4Äì H†\? ß!æý’R’ä ¦K=ޱÝtËh\ ´ïpÿyë]ü~?Rê$&&1jÄõ¾g<Ó O<2ž¹?-4MQ¥%ÅŒ=†çÿý"Ͼø" ~ZÀ¼æòÐø‡‚™)‰ö3£V-z÷í{\®á#NA›7o^mÙ믿Î믿^eÙäÉ“™_1))^<ª [žÕ tT ˆšïò! Œó’‚²öìFŠ ]×4Âáø‹¸ ”ê˜ç,€?êÙÿŽbß;6®††'ªþð_Ñ„eáÏCù¬}‡jÂ:Ô²øðê5oÏÂÑÓáÄQ’Eẵ$u½uùhÞ‚í¿.!m.º^6Gþ€ä_~N¯>—Sì3LEEEø|Eäûu’Ý ú ‰àp:éÙõ~^´ ¸à¢.q&©0Ðçò 7Þý€\ÖÃ$r¡P˜±Ž£GÏî8èÝí2œN'Š¢ðù'ÿåçß~¡Ð¯³níÎí|>v»A¢BÁ?ýòs.AfÔJgÌwÓë’ °Ûí¬[³š‚€ŽÛ¥pYßþTÔùòý:û÷çÒ®CG¼^/E…EH)¹ãžûèÓïq U›Îç_H©nìµ3Úµ7-/ÞÄ$¾þâ3óP;=£­O:9ŽoåûuJJJ8ýÌv¦CJíÌ:ü÷£i$Š¢páÅ]+õ3 \Þ`öìÿá BrJ §´=ý¯aŠ™‡,[4mÚÔ„¿)RRSp¹Û°uõÄ˯ÓvÅr´è¥¿RŸµk“ Ò¤YS4MÆ ɧ_|fʵL‚V|5ûq̨$zŽðÄSOPÞy±4 ™úÑè@Ï.ç““³¯’`ó¨š;ÿ‡¸²’èû ’y?ÿWV\C¦I:×™1Î b®àHÞ›ö~¥vbïûmñ"SK+ “OO"߯óáô()WÇår1á± ’°hÉï”WÊ{Dµ9¹ §œÚ&.„Œ¢(añÒ%UÖSU•'Ÿ™TÉäU|4ãã¸þ7iÚ”-› ý¼°ú÷ïoí` Ž!t]ât:iÚ¬‘H˜ù¹9æ­q×Kë–­‘RÆ1ò„=¬^ÃôWS¬âyì³{röa³ÙУ"²ÔuJ4IaðÀm¨¬&š´¦_«ºÍê´åÒ ï‹ÀWU'XîYéú©ëÄizåq zÁ*ÞYUÿøfÇNÛ?*&¬ò®ŸGó‹Ulß qdÇó`sZÝÏÖ|;”—r'g}V±©ŠqMûõJŽÇê΂…ãœH)yñÅÍj!ß~û-­Zµ:*‘z…üøãL™2…ÌÌLž|òÉãŽÉhÄç…^`Íš5qcÒ Azè!ó31Ï«SO=5*eî›×_½é¾ ðŸÿüÇßcŒŠáFþ칈™kŽe,œ@ ä7Þˆópš7o G-Ô{Û¶myüñÇ©W¯Þ!1!çŸ>?þø£µ Êá©§žâ§Ÿ~Š;ˆ¹íƘAÛ¶mùꫯL¢( íÛ·ç“O>‰‹(ЧO¾øâ kPºêhÜ{:HòI ¢ÄïÈùmqVÅ(Š¢˜G(¢¨¨(.9½ÛíFJIqq±O —A—Ë…ªª•êy<SÒMII!%%¥Ê¾JJJLâ—””Þ`Ë–-ø|>‚Á ‰‰‰ûXX14mÚ”ÜÜ\SCËÈÈ0Ç055•™3gV ù’››KãÆM&³ÿ~òóó­Áü`w8˜þÑ›¨Š•ÛÞBÍPþ¾ÖqÅ@bxÿý÷2dHܳåË—sÿý÷ãv»Ñu–-[2qâDEá¼óÎcùòå&5j÷Üs­[·fâĉ,]ºUUÑ4SO=• &0ïEii)&L`ÕªUf½3Ï<“ñãÇ“››ËСCÉËËcÈ!æg­p&Æý™W^y…™3gšÌv̘1\zé¥ 2„‚‚^~ùeêÖ­kÖÑuíÛ·›s7kÖ,&OžÌO?ýd™°þèºN㦭HJN±ÃBTUËß äÚk¯c RJ:vìÈwß}g>{øá‡Ù´igœqW_}5?üð]t7n¤V­Z´hÑŸÏǪU«â¢íÞxãdggÓ¬YõIá³³³ÉÏÏ«wùå—ãóù¨W¯ß~û-7æ³Ï>‹ëãߨ}òÉ'äåå1{ölóY­ZµÈÉÉáƒ>0–_…1*¾äË/¿dùòå|ñÅÖxþiL?Â:Ó´¹•ÝBøËÿ||3ò‡©1âò¿ÿý^½zÅ=8p ªªR·n]öìÙq•EÁívøüóÏ+¢‡~øÀ_Ìfã7Þˆ‹Æ[žØÅFÅ>þ!¥¤S§N•˜iMÔ])%999L™2…3fXÌãhŽ4?‡ ‡Š#žD×uŠŠŠèС«V­Ân·£ë:Á`{î¹ÇLw+¥dàÀD"¤”\ýõ<ýôÓœþù<ýôÓf< ¾}ûÆÕ‹…Õ¨.T†áç®1bĈJõbéV8;þŠ+âûü-!Ìðëñ>éÁJ̹bl²µk×Ò¿f̘Wß grlØôùŠŠ(öù(öùðûK±RÔ[8’8¢ˆ‚>}úpï½÷òã?2vìXJJJhݺ56›¾}ûrÍ5טÚÅš5kÐuÝ$6“&MbÈ!L™2ÅlÏëõrÒI'™õ"‘×_=—^z)BæÎË;ï¼ÀСC:t(]ºt¡V­Z$%%1xð`„„B!ÆŒÃyçgö÷¥—^bðàÁæAñ3ÏüðCš7oÎĉ9å”S3fŒ9Þ't’éþkáÏcv»`û¶D4 —ÓizÜèºNÖž=´lÕ‚HÄÒ-‡ dܸq„ÃFä˜'Ÿ|’‚‚ÒÒÒ?~4·;@ À“Ž7ëM|â_æÍµ`0ÈŒ3ËÆ?ö$ŠPðûKy䱉<÷ìóÜ{×í<ÿâËÜ9æfÖnÙÍûï¼…P(š`IðøÄÇÍ|>š¦ñȸ(Õaê»SÙµkg݉ÂÂÖ¯[Ãćî·Â§X Ä‚…Tۨʑ@€SR\\%aËÏÏgç®Ý‡LôòòöS¿A½žqhšäÌ3Û³há¯Ô©“‰.ÁéÜ5öÎ:ç\\®Só?åÔ¶¬^µ’[n¿‹‹º\‚Ýn˜Ä\.^Ü•yßÏáÍ×^æ‘qðÊïPZZŠËå¤Ë%Ý™ûÝ7 v#ÿ¸r ±ÜN§ƒî—öâ›Y_3hÈP®¹v(º.q»Ýt¹à"êYBÀ9Ï£ãÙçR¿AFŽƒÔu.ï?€Ÿþ— í:tD‰jhªª0`à þûÑ4î¾}4Óg~ÍOó 9%…ÏfС¼óþ;•‚3Z8Nȡƙú£A-—Ñ#ƒGy„ñãÇ[q‘™™IvvvÕÚ@T#¨.:¬¢Κ6ÌIËí¢éñ9É«W®à–Ûî"¥œ§â/KV–/]Âã&šÚM².ë>0.íþºt56› !INè×Ë´dñ"žŸüªù.¯®¼¼7‹þÊkSÞA×öúüö+œÓž¢ tj¿/úE¿ýBA@âv †_7ˆDà¢.—˜}´;n¾ñÓì×å¢N,_ú;õë7à¢.]¸óÖQ–¤|"0)% .4¦…lÙ²…´´´jÃÄ>—••ÅÂ… IHH [·n5z_,ýmÛ¶m­™<(OtÒÒÒ°ÛíUf(ìׯ3gÎŒ{Þ·o߸ȫå/q–G—.]˜;wîßnLÿm=8pdeUUâRæú’Y_Éy\hæ¹÷ûýüû?oУËùGEˆ»¸k7f}ý5RJ\.çtêL¤š1ô$Y{öà êË1ô#¬w‚›ÄÄ$kQ¯p)e¥ð%¯½ö+W®œW¿/ZÈ)mO3S¥:‚ÆMä§ùóX¹|+—/cÓ†õôìz(**$%ÅK²ÓЀjó¹—GaA>©nŬ§bœÓ€‘M/?/‚ü<¶nÙ̼ïçPì׫eÄ…AH´ÃygÁÚ5«~®XF›“OA×ãïp‚Aó¼ÆÂ dÂòDs1Çàp8PUµZ %fnÙ²%-[¶dôèÑ5’lbÏ+Þx·LZ\Z...fäÈ‘•ÌŠk×®¥}ûö”––ðá‡ò믿rÎ9çpÛm·™‡š1lÙ²%.BòwÜÁœ9s˜0a‚5ØG —’Ò’““«ÍUî´ 6oÚÈ%Ý/6½°Âa¸ÿáñÔ®IQQQTð3§_~^´„úiøKýfÙž¼b´¨¦R1¾kì ~õæí¸Ý æ>ä) ÁãO>F¢Ëe\n=ÒÌTh˜â*¢ä•jQÁ`€;²éÔá´¨9ÍžúÏ›F£DïtŽ3‚…c ”ǶmÛ*§o¾ù§ÓIZZÉÉÉÜ}÷Ý%ö±#‡´´4™8q¢¹¸4M£W¯^¤¥¥áõzÍì………,[¶ ¯×kÚ³Ë#==Ýd`ôÆÜ´Ë3ÇÃþýûiÖ¬™ÙÆ…^H½zõøù短>ŠHJIdÛÖ-deeEC®¬†;«FÀïgÊ[ïqóÍÿ¬”25ÑÉÞ·À?àGJ‰×ëE×!ÖÙŸ—Wæv'à H–­XŽÃQvç§0 Ѥ$߯‰è”úKãêÙìv¼¨_;“` €¿´”ÒÒR“¤¸~=ÚF<=0h‰.¥Ù^­Ú™díÝK¾_§4 8 q¹ÝÑ` ’í;wP°h ¡ÄдiÓ8B.¥¤{÷îqa1|ðA~ÿýw:vìXm;yyy|òÉ'fXv€éÓ§“——‡‚ï¾ûŽM›6‘™™ öùk®¹†úõë[³{ˆHNNæŒ3ÎˆÓ mÚ´áá‡&==Ýt¤¸é¦›HKKãž{î±ù(C‹H.¼°?ýô¡`Ðþ£Ú®éû¸zȵU^"T_5ÉŸTVRÅs_°,î\Qå!àÞûâžûËG*Œ{ä ‚€PŠ‚ñ±ëÊׯØfq°¬å¿—‚â çî„c US\¼x1½zõ2Í\Û·oçꫯ>`;©©©ôîÝ›úõëãp8…B¼øâ‹ddd••E¯^½LæFbÅ øsXø#š›á5¤ðÄOpå•WƵ÷Ê+¯°fÍFŒa†®yóÍ7>|¸5èGÁ éH:žu6RÂÞì,Dt?8ÒÓSÑ´cOPɘ;neþ¼_̾hšÆEwÆoÝÙ°H,„Bl!ƒAFž}ûÌÏÜyçf0ÅêÎ9EáÎ;^¯»î:Úµk‡ËåŠó$±pt™IŠбd_±Ïççç“””T%Q+]×-æq”™Hlú2ëÔ×P´ã§ œuιñŒÅÒþ¾ DÁ)§œÂàÁƒ),,ä¼óÎãâ‹/&==EQhÕª3fÌ ‰PPPÀóÏ?ÏСCB°sçN–-[†®ë|ùå—4kÖŒ“O>™¢¢"† Æ AƒˆD"(Š‚ÇãÁãñ‰D*µ`0h&Âá0]ºt!==Î;£iš9Wß|ó 6dÁ‚Lš4 €ûî»ÏLk+¥¤sçÎ 8Ðÿœœ¾ÿþûƒ2 ªª¢Z—,Ô„NÏ ä…^0S™þðÃ,^¼˜Ö­[ðüóÏ3cÆ ìv;µk×fÆ fðÃH$ÂîÝ»™6m{öì¡aÆ$%%ñüóÏóÕW_a³ÙÐ4;3ڵkã÷û;vl\ÆŽ²Ý¡i $&&šaݽ^o\ÄN:qóÍ7›?ÇЧON:餸öŠ‹‹«|ÏÁÌ–•yØX¸p>×­°ÃB‹(p\1XÄÛŒŒ ÃÛÂfãœsÎ1%ÒZµjqÓM7UY¯iÓ¦•Êbõ4hÀÈ‘#+•¹Ýn:wîwóÝJK{øp8|ùå—ýÜË/¿\éYMêÅðÑGYƒ}¡( »vl±r¢[¨ùš9Bi+ޏr°ŸV¯¦¦ŽªÚ·L# ´lÙ²Ò} lL6¡ý®N³–M­·pp: LšpïñÇ@,œØ5j£F²âã¨ŸÉ ‡C„¬`j¼dŽŒ°m1 Žöf=†šqyK…”Vn GGœÄÎ#ŠŠŠHJJ:숼'"¡PEQªMdu ï~¬Ç üÜ•Glcˆ•á2ªŽ¤ìóùHLLŒ“ÀTÏ‘Øݪ•ËÍ4ͯ—-Zýeö›…cåh,Þ%K–på¥h IDAT•W2sæL“0ÖDJ›3gN´¯xíµ×¸êª«â²0ÖTBýøãù†Žå˜ïׯW\qW\qýúõãûï¿7ÃŽÿûßÿ¦oß¾ôíÛ—×^{-n~cóÿóÏ?›÷AbÏž{î9³ÞÛo¿]ãuaáÐçÐï÷³}ÛV²öìæÜNgѾC{ÚwhO£FMØ´q=ë×®Áé<~ÆßåÄZ 1ïúõë™2e ³gÏfçÎLž<¹’„Z‘éÄ0nܸ¸\)eµ ë”ÅPñâÁÊö¾1cÆ0kÖ¬J¹ÀkÒ—°üÏB×®]™;w.ß~û-ß~û-sçÎ¥k×®Üpà 4iÒ„yóæ1oÞ<ÒÒÒ¸õÖ[ãœfÍšÅÒ¥KãÖD·nݸð ÍzuëÖ妛n²$࣢ûÉÛŸKÓfÍiÚ¬Á DÓŒ „N§“6'Ÿ„Çëå»oæb·ûñ×u;n½·ËZ {¢ë:×\s /½ô·Þz+ÙÙÙüòË/„B!Î?ÿ|“h¬Y³†Ûo¿!%%%!X°`™Sž|òISê6mš*#&ÇÊÞzë­¸²Øïå?+‹µ³nÝ:n¹åó¹ÂÔ––.]ÊØ±cãʾùæóç±cÇÆµ9þüJI*F!7ÜpC\½•+W"„àóÿgï¼Ã£*º?þ™»==!„jè‚ R,D)Šø‚" X°Ñ^EQá§‚]l Xì‚"¢¼"]š©"½š^¶ïß»{ÙM€¸ßçÙrÏÙ»3sO›3çÌ›–oHÁ¶mÛ4Íýæ›oFQvðàÁs*X‚YTƒßa45a:þ|zôè¡ Ì>}úðÃ?h÷gdd0}útxà°>/^–¦¿[·n¼óÎ;úÛwàóúP í4záµèñHêÔ«Åþ}û0(’¯Îh“éä'8×Á½”Â4­©dšÉTBŸF0V®X†…pšÑ´^Kßgq4ÿ&¬OE9};c¡g1™ü5߯“4ç oaÍÝh4jƒšŸ_J‰/W!22)%:uBUU¤”Œ;VcJ|ðRJ¶jÕ*öìÙÃáÇ™7o^mË–-œ8q‚={ö°jÕª0Ú|@FF7¦ZµjšEJÉĉÉËË#55ƒÁ€ÉdÒh#FŒÀår±téRíYƒ}Þ}÷ݧM§"¥dÆŒaí:wî ø‹0ÏÌiM›6EÁ”)S2dªªj´”””sª¹­'—ËE§Nðz½E~_qUôöìÙC×®]ùæ›oе¢æÎ«Ú½{÷¿fa]èØ»÷/jÖ¬^âØ !ð¸%ÿ¹ív.øƒ!h=úËá¶¾´MêÕ¥I½ºÔª’Äæß7ktº¢-+W,£v•$šÔ«Kí*IìÚ¹“ þ>q‚K6ÐÚÕ©Z…=»wa2ÁñãÇhšRO£Õ­^•];·kôïs ÍÔeÛ[©[/…:ÕªmD[];uä-›™>å-êÕ¨Nýä:x“<@ýäZŸ jÕäÈáC˜Ì°ß^êÕ¨F“zu©™”ÈïÖÓãú®ÄYmR[°kçžöÿhP3™¦)õ8~üŠVAÍʉZŸ—6lÀß'NgDMêÕå¹ ãévMgR›4&#ýotúl¢oÛ¶ûî»ǃ‚åË—sýõ×—ª­×ëÅn·ƨ‚yµB…’Á`@QLA5#À^{í5À_f³ðy³Ù¬1¾œœvìØ¡iú£FÒ˜gnn.{öìÑh?þ8F£«ÕʧŸ~ªYf³™]»vVx!˜={6?ÿü³ö{222N뮊å…^àÛo¿õûŠ­Ös^$G ”:ŒÕj {ž`©ÓàoWE‹¬:pà€–—,..Ž)S¦h ǯY_'N¤Aƒº)O{'nøé×Õ¤ÔªM~ž¿b`vvRJ\…ì©ÿ{Žì@¦ÜXËÉ05k×!.>^;[ (ŠF‹ŽŠ!×q²þº”’ÇÆ=¥Õ"ñù|þˆ1üiá »‚ûõîA¶S¢(‚­»÷þ¨@þÄ‹A·Zt¡$ž¢8Áðvt»æê@Ñ*X±öwò\oS0 ÄÄÄúŸIZ›ðDŠPp:äåå…n?ŸbµZ©VídЄ„qØl6òóó±Ûíää-»Ozz:ÑÑÑŒ3†1cÆ””„Ùl&77§Ó©U8 î Frrrp¹\X,Ì”)SPÿ‚ÈÎÎÆívcµZÃ,P¿ðs„n˜‡ÒŒF#ñññÄÆÆâóùR¯Ý“——‡Á`Àçóár¹4 Éëõb4‰Õò…>|8ì;µý‡ pðàA,‹ö}Ág:—'›…ÄÅÅ‘‘‘AFF†&ŒF# ¸Ýn¢££ÉÌÌÔ\‡¿¨O0wY(‚î¾às9rD0¡„t”üµÎOŸÛí ˇ$%8ìvþ:°_ókB4xEQ8~ìuëÕÕ2ýߑ̌tŽffa™Jà¤TûwAF.øûÄß$V®|²b¢ô[ ŠŸH'±rb1Ö $׬åW`¤DÜnBñrÝ^¥R› §Ã+PáP{ï ½óÕª× ÖròwúÂçÐñlúôìδÊ*:ΉBлwï°k­Zµ¢J•*˜Íf¦OŸNŸ>}°Z­Ô­[—®]»ò×_Q¯^=¤”|ûí·ôíÛ—‚‚†®%a7nýúõÃl6ãñx5jµjùÓƒ>Hÿþý1™Lx<žxâ ªV­ À€¸ýöÛ1™L¸Ýnžyæ-Ñâå—_^"3n×®]± ÓÒÒØ³gƒFQœN'/¾ø"—^ê/§9{öl,X@ß¾}éÑ£o¼ñ5¢k×®ìß¿Ÿ¡C‡"¥dذa<ùä“an£cÇŽqíµ×°}ûv¤”ôïߟ—_~YÓÔ øøãµßw.ððÃsË-·„]«S§“'OFUUòòò´ý‡Ã¡¹¼ cÈ!an‡ãÇkév»½Äv:þ‰ É5ksìèªU¯^bIÛ«à›/?㑇 ?À\M&˜9ã]cÀµe0¸sè0Mýðpºt»¯×‹Á``P€Ö»O_&¿29Ärv1ê¿ÿÅ`€>}û3õ­×O2ƒ ë×òÑÇ35‹£Ej*¯¼ö&Á–M¿óþŒ÷Jt뺃3ùÕ7PC”¼Û܉F>øïΜ…êó!„Â+/OfìèG´2¹öÂtAx€a÷=ÀK“ßÂçóa2Yüã(Es­´J»œ„„JH N‡]õÑsB{Ùû®ë)8ádþ˜|ûýlòò²O«ú îºë~ùe)=zô.↠Õ0K£mw(­8 á\ÑN÷œ§«ë~6íN5>ÿTCw:óøôÓYÜvÛ­ØíyEúúë¯}X­±üðÃFzâ¬~û©î-Íï¾Xàñ8ÉË;¨åmfÊÛ1ò‘‘ZeÍÂÈÊÊâÐáÃìØµ…¡Cï&/ï8B(…ÞAÓ¦}H—.]ñ*QÔMi„ªªü¶z%­/oKD„—K†„YC”>ÿz—·mGå+@JI¤U0ÁÚ>›ÇíæÖÿÜŒ®íЉï-aÁws1™üŠÜn½‰§$Ê*˜;o¡æiðz½ô¼©^¯Ÿ6gîMs÷z½ü§O/Mpäåæ²l©?íÿ­šÉ$øyñÏ\sÝ5„ “ÒßçW_ÏÓJUå–Þ=À€þé× ¯G{'ç;‡w?x·–þï:vîX¤ÏH«àË/çb4™ð¸ÝÜòŸ›Yµb-í®Hcñ¢%tº¶38´×ëcëæM¤¶jIE-G4y񣆯½õë×DÊÓÿ³ÙÌk¯Má£3™øÝÞ{÷C=¾ùܤ2).¹aiFqᯥ½·,hgÛ¶,’EwÏùf²ÿdÜN7ÿÿæïº˜ ( Ww¼’O>š…êS4d Á’9Gå«Ïf3dØ}DDD ª2l® œ’Î×v ëÏîô[,~˱€î=oÖhÁ²¸ùNÉu]ÃÝ=^ïIZ—n7†ÑB…‡”’è˜nèÑ+ŒæñH:tºG-Që”tëÞ³HŸqVÁ¢…ó™5ûcìîàxÀØÑ`ì^É•Ww,¶Ï§äÆž7i×\.hÙ: §SruÇÎxCÚ Z¤¶ÔÓ çÂҡゃË%pÇí¸\’f|Œ9]˜”T…G¥Õ0/Â&„@š6kŽR(]ü©…ÒÐNõ ¥mz-Ë¡’•E­Úu°"9UUåÏÝ»Èvªšw&ÊÚ™>‡.@tèÐQ¡áÓõÿ;`Ð@íºª†kÿ¥…Ó)yóí7p”óUEQÈvJöíß¶ÙíßD×÷ÛʽÑ}ÞÎ$Éã™îáèkâü ð±¡³s!D¹¡ÏšçÒ-… k|ùå—ôë×ÈÈH|>ƒæ7Þ8§“xüøqªT©¢Ïæ9Š¢h¡¸Á,Á¨³={öP¯^=À!Kdd¤ÖOFF†vXmõêÕ´k׎èèhŒF£ ¬£ ˜&—ÓNA~®>:J·bD9¬"¥ä‰'žÐR”|ÿý÷üùçŸ4hÐàŒ­“ÓES¯·mÛ–½{÷K+.Z8ò)´]c>©±-`’ ӽᆴ¿7lØ@Ïž=‰ŒŒÄëõòè£2lØ0Ï>û,RJ¾úê+¼^/&L`à@¿ÿvÉ’% <«ÕŠÛíæ¥—^¢OŸ>¤§§Ó¼ys233iÔ¨.—‹^x¾}ûrèÐ!Þ}÷]&L˜@JJ ^¯—3fйsgöíÛÇ_|Áÿë/ë¸hÑ"|>7Üpýõ]ºt!//ãÇɲeËhÙ²åEñRû!CX¼x1Ó¦MÓh÷Ýw¹¹¹š øè£¨]»6½{÷ÖÒ·‡ö¼v÷ÝwWè4ýå^¯›N]o¢zÚú`œ'ŒFVýú#‡î¥ÿGðT$!"à³™o—ORX“ Âívsß}÷qèÐ!íÚèÑ£Ù°a5bâĉÌ;—‰'j̪uëÖT©R…—_~™ýû÷kíî¼óNZ·nM:u8zô(Í›7gË–-a‚+99Y;%dx7Üp—]v‡#ÌbIOO×\NN7ß|3/½ô’vª¼M›6,[¶¬HN® ÁÓýÅ1ü`®°Ðy ŽI°hQðÔ½‚«¯¾Zk—™™I¥J•š›ñœçôº˜ ¥$.>‘*Õ’õÁ8oÖX¬6’ªÕ+W¸r²Œ°œ×(¬'N°hÑ"œN'ƒAKi.¥¤k×®ôêÕ«ˆ«Èd2‘””Ä‚ ðz½ø|>^}õÕSm ÍÝ´yóf­Ï–-[†%;Õ d¦%¹Ð.TX,V®\ÉܹsµJ„k×®%--í”í233iÒ¤ dgg#¥ä’K.ü)l† æÂjР–•W‡TžkÍ(”ù:N<¨%ÝëÙ³'uêÔ9eÑÑѼúê«|ôÑG˜L&„<õÔSL˜0AÓhKú>!ÙÙÙšzöÙgõ? ¾üòKÖ®] @vv6ÇŽÓ„„'SÌÊÊÒÆ~ûöía}“/ÚívæÎ«ÍÇã!..Nìså^1œþžàA?:Ê•q»Ýa |Ò¤ItìØ‘–-[R½zuîºë®"m X´h‹-¢k×®C’R’™™É°aÃøê«¯´û @NNŽ&@ìv»ö}䥗^*’/ªpŠ”PmØPÂw±ùí¥”ôì~ÂwèСZ6`¯×KLLŒ–dÑjµj ‹³d‚Š‚Ãᛓɤ]ÓQ¶°Û عc{‰ Rú^–šzÎÓpH)±Y…–5WÇ…‡2 ƒQ…Ù³gcµZILL$>>)%íÚµÃb±ðÖ[oa³ÙHLL$..N‹ò‘RrÓM7±`Á‰%55•¦M›’ÀàÁƒ‰ŒŒ$11‘˜˜ºt颅J)Ù³g‰‰‰DGGÓ«W/MxÄÇÇkµ)BÑ´iSRSS‰%11‘+Vðã?RPP€ÅbÑSPÈ$'_¾åâ4Ò”””°¿sssµLÈN§S³F„ÚÜ*Š‚Ëå +„e6›µ‚RU«VeëÖ­}A)UJ²³³ÉÉÉ)òÉË˃³H×§ª*Õk$Ó²UKR‹ù´oÛ’ëוÊJù§ˆ¶ ×K9ãrŠ2f0ÀÁûà O+îÞµ“];¶“——[„¶kçvîØNA~þÅeH)¹ì²ËŠh¥AFÑ®]»"šg–Íœ9sxã7ŠÐn¼ñF eÑ ºC„¨ªª+ m÷àƒ–øœ÷Üs÷ÜsO±Â¥iÓ¦ag!B­Ÿ‹ŠÁ©*»víÒ¢ªBC£C•†à˜†Îmð Iðÿ¡–i°‹9ŒW…C²téR-ûmaS!íòËÙ±óÌ…¬TUB"éíjCñ‚ í.ˆµø‚h©ÐUU%Ö¦h"­44‰ **ºÈ÷ÄX¹úõ8[ø³ä8+¾kMJ^®1cŸäóÙ³ÿ>r]¼_VÁ´wg°î·5þäðÞ˜: ŸO%ÖªðÆ”élÚ¸AKÿöôi¸]åwLÊ<û™\Ò¤”ëÌÚfb¥iWzè=³Ÿ88®¥aô§Ê«TÜ^ìg@!HOO×eÇ„âÎÛÉ‹Upÿ½Ã™úÎÛÄÄÆKNv6yy¹d9Tâm 5ÖÜŹ99äææh´ºõR´Èº¼¼\r²³ñú=VAÃÆMرc; P½F²¶ìv;™éd9*®r7÷ù÷s¾ÒæPQ|ø ‡7§½ƒ"àØ± ®º¼6®ç­wÞÃl¶ðÖ´w =ü7mSSÙøûFòË©°\äÂŠŽŽfݺuzz ™"JtïHy~Ë)Æo (t 6qRÁkÛþJV®ßBd¤ßZ ¥e;%ÛöìÑú²‰`i]5ìwÞs×ý|øþt­pSí:uÙwø>y²]¥ÄD2ÒÓÉ© û&Š"xíÍ©Ü6`imÒðÚG=~ìM›5'mžºÕ*±k§_˜=r„«:tÒÒÏÔ«Q™Ûþ <‹Rcy{¡tèÐñï #=l§Ô,›å¤¥Åg³>ÆjõŸŠIYc|øñ§!•G#4ºÙbæËÏfóþô)Œÿ,3Þ›F¶SÅfUèÞëf>š9›à zÇCFzŶ@TUr߃÷¡ªp1lýœ“Y îA\웤"Bç´pj’¢/“Zâ:¸7V+:|>/^¯ÿ““Ãì/çâžxrN§¯×‹Çã!*::,«Šÿp©)LA´;TÞ~ýU<·Ö§Ñhâλ†e«¸îM!.WÑ$–*ÊÔQU•öíÛ³zõjm0Ÿ}öY®½öZÚ¶m«¿D@¨ªŠÑh 0 Ÿ¬œÓ™3g¯…ü7Ì…ašc°n|°}f2™p:ºË²œ¡Rb"qV¿[ÊYHÐçåå1`Ð"#ýëBN—_N,øn.ËÛˆÙ V ^J}-úÑírsÛ€;¸µïmŒñ Ý»tÒ\X7aëŽí÷û­ÀÃ÷ãÃ÷¦_°cìõù35œTª„`âõz0™Âi§\—Î-sQ_8Ëívk¡œ%1¬SÑŠû¿nÝœ;:tˆÆkóÒ°aðô3K—.åÎ;ï ;ÑRJ|>Ÿö©Y³f±4§ÓI½zõtáqnt` ÈÈH/þ“ž–ì4Ì…•‘CJ¢¢¢¨W£‘Héwi­Yµ‚6—5¥^Ô«QƒJÑÑX,þú"›ßHó†uým"#Ù¸íO’kÖ‚€0‘Rb4™˜öÞ4¤”ÔoÐìܱšU«i}ÆÅÅc·卨ÖiVf&¿oXϦß7SPPÀÆ­»Ø¸~BÀø'ãí×_eó¦ßÙ¾ízÜÔ›cÙ²*/N|†gÇ?É[6³cû6ºt»‘—,×ãQæ{ AÍ5›Í¦iš[·nåõ×_Çb±àóùèÓ§×\s 7ndêÔ©˜Íf|>ýû÷窫®¢  €Ï>ûŒ¡C‡òðÃãr¹+z„Þþ}{ùlÖGM&†Ü}¾7 —ËE›v­ÉvJ-\Àƒ#Fãõx;n<‹ Uõÿö_–üÄð‡Gâóùxî…WüZ~92 ëׯ§jÕª¨ªŠ‚'NðÛo¿P»vmzè!EÁ`0ðî»ïR½zuš4iBJJ =ôBŒF#o¾ù&5jÔ N:Øív, k×®Åjµòâ‹/’œœL5tŽQÆî«Ñ£GóçŸj‰·mÛ¦&ìׯ7fêÔ©ENúO§|RR7àÑGÕ„G‡˜>}:5Ò]Xç&“‰¦Íšö¾âêyÛ òA¼GQrK(ÔT-×å¿^PL›<×I¦˜{’R’Úª­.ož]_øK !ÈvJ&½ô2P}'ç"H{á•W5ZhÝú‹B€¤¦¦²aÃíïgŸ}VóñÙl6’““B`0p:šËËf³Q£F M€àv»5a3wî\-f¾¤l±:þ¡ó#°P/½ôR- ‰ÍfÓ¬ @(É )„Àd2áñxRÒ,ÀÈ‚´ÇœW_}•† ^Ì¢ü2±ÒÏu§dñÒ¥:ï©ã,Þ!)Áç-yÌ…a`á3S%Ñ. R8ºÆívkqà“&Mâ×_Åh4b0Ø´i÷Üs^¯—çž{Ž+V`41¬]»–±cÇjƒ4RJÞyç}¥žÓ@j~r‡Ã–¿¤6Åís…æ(›4iõêÕ£U«Vú —Óy×…‡Ž]€”ÇçŸ~ʶmÛ´¿ƒ‘‡ƒï¿ÿ^suU*ÍIGÙâ·ß~ãÊ+¯dùòå\qÅZvÞ "##‰ŽŽ.QihÓ¦ sçΠOŸ><ùä“´hÑ¢ˆå¢ÏgY˜þº,¯£ŽóÄ8 Љ?zLT ±Pf‡TË\€v-5S‹Å¤I“4†Ñ´iSƇ×ë%::šQ£Fi´V­Z1räHM >U—޲t}HÒÒÒ˜?~XM•àyƒ øóÏ?‹ŠÐ°í \.—Vlêÿûß|óMØ^ýõ,\¸Pô2€ÉlfîןSKÇ9cªªb0xíÕ‰®˜°ÕQþˆ¢(Z–ÕÂ58¤”ZÁ¨âWß¾}éÛ·o±´áÇëëyrcÄÅÅ™'UUK,UÜÁàÿUU%##£D¥ÏgÙþ˜Øx"""õÁ8oïŠBvv.§ƒÄ¤jeVáï|‰¿#‡÷•O $”.¡Þ™ÒtfóïáT¡„ÅÑB#tÎfÞuœÕïñpUçîÔkPOŒóeõ ˜7÷kvïØÂíãª@&ˆ^˜ðhù :tè8¿ÁëõàÑ7ÁÏŸÕgô[×pC…û²RÝ})èÐq2@}OQ‡nè8WÌ%è^:Ý>E•tOqíKê3tïLwo<YÚõ%ÌF£‘„J‰¥ZÑâO6EcÈw—î¼‰Ž º¢£¨y+«V­bñâÅaŒ<¸YžœœLóæÍiÚ´©v‚öºë®£yóæaŸGyD.—‹š5kjù± ‡þ3têÔIÿ.—»½›Í†Õf-ò‰Ž‰eÉÏ‹1–BuŒ¶ :vìD¼Máéqã¹´Ysš7kNíZµÈÎÎÑ­˜³„ªªÄZÐ>¡Ë=”f6—ÞR mg2? S·@tAAAíÛ·ç›o¾ ×6³ÙVž6¸P/^\D{ fB””DNNŽöwá®( -Z´`×®]úüCX­V¢Cr“…Âl‡ÝNid´X¹ìWV,[Êâ_WE¬’’ªpðÄqœ.}¼Ïñ6%LIÚuàIIUŠ Þ^… IDATÐÞyÿ#n0°T–^h»Ïç̧k·Okñ눎2dž ¸úê«Y²dI‘:ôƒ¡Hmó @&þù'—_~9[¶l mÛ¶¬[·N»ÕªU 0@k#¥ä®»îbÍš5Z çRJløõ—%ü¼x?|?án*‹ÅŠÅà§e«iÓ²1úáÅ3BVf&W\ÕA[÷RJªTñ ŒŒtÚ´»B»¾mëÎÿƒáTÞ8qü8©-[kíÌ›Ë/K~Âd‚cGÒ¡]+lçhžt DG~ûí7Ö¯_χ~–² >>€.]ºƒÏçcΜ9Zö]!K—.¥cÇŽÜyçši½zõj&OžÌÿþ÷?n¹å>ùä­]¯^½xúé§±Z­ºûê_‚Ù,xgê»dgea00 |&“ŸEDEGsÇm}üyè<Ú]y¿oX¯eäÕqz¼ûcŸ_T“Wàí×_ãù—'“íôKí×_}Q³Ös|%X‰xfü|8û ­ÝÌÞÕÚ=ñèH¾œ»û9š']€èÓBï½÷Þ0«"qqqT«V½{÷’Á` ]»v¬ZµJ»'--£Gý)º;uê¤ I“&±oß>’’’¸ãŽ;P…äää°z#çÃì./PUµÄÚRJ¤zþö |7÷ÞÿèSââãPp¹¼Ìúhö‚^Ÿ2ˆˆH¢cbhݼã­¿4ÅÌ›É$°Š$ã¥ÀíO9S¹rþ“à‡ƒ#™DFF`±Xp:aëÞd2ö”»ÕjÓrÖG³Ûíçì]ÒˆŽ"®¨’Mzz:ªªjéÜÓÓÓÃ^žˆˆ"""Rj´ 6ZÝ®aÆìÚµ‹øøxbccµÍxUU8p üñ=Ö>Ÿ´¶mq*À*\N—IJÌç_QP¥Š”àõJ*EÞ'©J"#£PU•ÇžÔŽu¯cˆ%!øüÓϸoè ¬V›v=//ªMÛ–ÍðæUó>Ïeú{õ)×*‚°ÙlØl¶0z^^^à%QŠ\ ÍsAÚ¸qãxýõ×QEQxê©§9r$[¶l!''‡ììl²²²P…?þø‚ðŠàÄÑ£äæäùädg“þ÷ßlÙ¼Eœ¿WÔHbm8«`Úc8॔DGûiñ6…WߜʈѡŸ],,ø%ýnï‡Ëå"''[û¨ªJ¾ òòsY¼t%¹NIžëä»þ:›ÍV¥µ¸’¶±0O¾¯N‡]SÚ ¿7‡ÈÈÈsö>éDGӿᆨ_¿>Æ cèСԯ_ŸîÝ»ðÇP³fMêׯOýúõ©[·.kÖ¬ G$''k´úõë³lÙ2žyæjÖ¬IµjÕ¨Zµ*ݺuãÞ{ï-vQ­” Ý}¥…cÇŽ©ýÞàÇd2±ð‡¨]»öYeM5X,`.æcÅ­Ë Îú‚ŽíZS?¥>ÕªW'!!Ç£õÙ¬A]ê§Ô§jµêÄÅÅ1ñ¥IØz(oáwÈãöå*ü\N'n·‡8« Ö‚æÆxdô£Œ|è~⬂8«àÞá1÷ûÅä‡ä§u¹œÔ¬U›ŸÿŒ¯ž™ô2ýn驵ë× ‹þ·œ¼üúÛô¸þ"¬º KÇy°@¾ÿþûi)))¡u«Vg•°ÈÁ-·öæte´Å0”ÂÕð|¾`Á0@Õß‘ú~å8%K—þ/Ìõ“rª?Ëq²t…Cž,ƒ«Í¯Í†”»·ëd)ÜÐvvÜî“´àêˆ222HJJÂçóa0X³f -SSKŒÎ*eóÏ”çVˆä"è@Q”bkÒ‡"H¥•¦Ý¹€¾¢CÇ¿ƒÁÀîÝ»µ>))IO¢£Â@·@tèø—^¯“ÙÌÆ ÈÊÊ¢Zµj~ÚÈ¿»BÓófI('=ŒþPÜŠd•#b6[ô…[Na±X82éePÏ L&‹9ðΘ‘RR·n]ÜnÈÉÎÁA“¦Mñy}€¤R¥JˆRl„(Š;·™q\èóe9*²³2ŠÂo«Vãõy*̳ cÙØgÝ‹cMòÞ{Ó(((ààÁýºé]á/sZò¦õ¼ysp:Lúš>çøµUUo€á 9|ùͧac.„`ýÆÕa/úÑ£‡O«  ¶nZ‹¢krçÏzDb±X1ŒüïǹnOÉl±þ»Äétðàƒ#„¾RÞápäë>©_¿—^š¦ Žrîn8]8¯Çã¦wߡԭß@°ó£æÏùŠ=;·2öéçqy+Öó¿òì¿\ÒV…üü¿õ•TQŒÖbB6½^¹¹Çôá©‚äÔŠšOUù[:ÎB°k{XpÑŽ½ñ\.jåý%”]ud:tèD‡^;>TUOîC :tèA~~>»vnÇb±R\ž 韠Ó5‹¸] ذ~>Ÿ5’©RµÚyyf»Ýζ­›ÁWµ)ö”|E”Eþd‡¡ãŽÿt8€Ñ(ÂÒÂx<¥ïÛlö‹×®œŠ¦ :t”–…Q#¹&Õ«W-¶ªÕS§¾Ë5× f#,œÿöïÃjµòæ;SKÍÜΪª2áɱZFÚËåѱc*l©\!k׬æÃ÷ßÕB䥔X­V^}óu¬^|õ vnß@AA>ïÍüŸïÔ _JIœUpÇࡨªÊˆ1ciа!R‚TUâl  AJ•ÇÆ§Ví:åÛñK<³~¤œCUU<o±‰ E ,r= «³$\.çí7ÊSl¨{ex:þ0KÀ)yâé§Ùµs7o¿þjتPL*T£V# ¥ ü©6b,íPKü®Ðu¸rÙR6oú (BðÔØ1-çôgŠ ”tÍv¨EѦ y–¬Àw­ y–¨@_ç˪iظ P’ªÕkP³r SÞz)Ó? R¥JÜÿТ¢¢hݼ ìØNëÔ£e«4fÌúEQ>l —,ÁíR‰·)\ÒüR>ûzB?¿®ZAA)Æÿ_ V«…w߉Ï'uTŽ‘”T…>}nÆnÏ-R¯cß¾|ÿýb¬V½°uy¹¹9Œ÷4¹¹ÇÎyÐJ0ñžÏW4&ÕbQˆ‹Çá°àv»9–íÀf³b6+DGEáñxp»ÝlÚñWµI%';»ÄbSÁŒËBÅ€?“wI‰ 4n؈_V­ç‡ßq× þ~â”( ¨øË'›Íþƒ™‡l—ŠàdòG³ÙŒÛíæ¯Ãé4o׊}û÷2UY"&&–˜˜X¤”Œ‚!úóçÁä¹ýîºZµëРa£€; rr²OÊb4 îhoOÿ€ÚuêþÚõÁBTwƬ/æP³VmV¯ZqÞŠ}ý į•Œù8àFæ)ŸîŒ>x¿DïóùèÞ½'—^z©>Tå&Þygò¿~N'­S[r$3‹%\àH)iب1Ùùù3 ^Ï:…l6 ¾þâkŽ=Bzúß¼6ù-¾ !¬¨ªÊî];B0ñ¥×ÂÒÿ=…Ç$::†¼¼\„Y £ÝØ£• ¥Ë?_PÁ}w áØÑ#T©Z¯Wòà#àóù÷)rssxèÞ»Ùµÿ(yëª$˜Íf\.W‘ŠæbJáž/üã=)]áÐßõò(>äé³rú Ùu+²\‚”ÿ~uЪ³³óñDFÁªxÆ-/œÒ}â¯?’¤¹QkÖ®£ÝüWÁØÑí” ‚ù?þ€ZµëвušV|LQbãâý `wù­œ¹ß}KÓ€¶ÿo k·îÄÄÄrÓ ×³àÇpºüŠw¼MáÆ[zñÑg_ù«R1D”á&ºn”G DŸ?ç»vîÀl¶àñø ÜnÜög‰þü“Š‹¤ý•WáóùxqÒ3Ürs÷Ûø]k’+¯îˆòóóØ´sN‡7ìžâàþ寪JzÞÔ›X ì×~¡oSÂ\L9¤úÂ2°aÃòòòéСþ3£glˆ²eËV.¹¤ñ9ßÒqnàr¹X¶l&“‰®8 N"„%¥Šc¡ EÁ` Ø(,ƒ Äƒ"F#,ÿu9{ÿÚáƒøåç_¸ªCGT ù¥-X³j¥¶ï`µÚhÓ®=· ÄÏËVc0BpðÀ~š4IÁqŠëÐëžB½ ç ð­ÓÚ°|é ¼^v_§k:áÒÚ´å—¥+q»ÝDFF1lÈ@Í:9_8zä0‘‘T®|ò{=nmó¼Ü\ztíå/ ¥‚8EXá()%+–ýJã&MI¬\)¡NÝzü±u íÚ·`ëîý´l}9))õÙ¼i#©©— €Í;÷Òúò6ç¥þ×/@6mÚʱcÇéÐáš³ 6ú÷¿‹uë~Ѳ©ê¨Xp»Ý¬^½–'Ÿ|)s)mi=! |ýõÚ¶M£Fjâ· !ؽs‡&Zä0ÈÏË+ž`ío«ñ¸=\ݱ3¿,ù‰:âtJ¦¼9™ÿ›ô"·Ÿi;–ÿº”tèÔ™X Y±B–üô#/¼ô<×éŸwô£Oà*4%Nüá®ÎB÷ç;%óçÍå±qãµ0YŸÏÇu]:‘ç”,Z¸€GŸx³ÙŒÝ^ÀÎÛiРáyƒììlž›ðn—ÿÇ{}^ÆŒ‡x÷·AßÛœü­.'_|ó•ºìõzéÞ¥#¯¼1…»î¹ŸOòÐð{˜öÞLö»‰$!¡Ë׬"Ë¡òßQóÖ;ï1 Ÿ?Ø RbeV®YMîyˆ<«àDà÷;4“PàBJ!$ƒß0'³B,%ðÓ@ FRz‹ÚX´{##mZî!¬@¨ ±#¥7 ©{BÁg‰BÊ|ýÄo­>UÍEQB+*˜2¸¢ñû² 0/Ѩj^¡vÆÀ˜+@tH;/RÚB͸qÏòÉ'_”°†¢Bþö· ~ßêÕk¹ì²æ¾=ÚZ+¯ˆˆˆ¤UëËñ©% ÉËR[{¾Ãá”<oå܃ߟ˜X™äšµH®Y‹Zµëh›ä‘‘‘Ô \¥‡.M!5kÕ&"""ìšÏ 5kÕ¦VíÚX­Öhuu€Î”ŠÍŒ”À V S¦L,Øl6„PÒÇðáà,æH«Ñh䫯æ±hÑ7äçàóùxÿýÈÏ/`ݺ¨ªŠÓ餠ÀÎÈ‘ÃY³fK—® !!‡ÃA~~RJÆŽï÷6þaï½÷aÀr‰Ð%Æ)°`Á8.E œE‘ØlH)ÉÏ/ ?¿€ùó¿àÞ{Tî¾{K–|‡F„PX²äW®½¶#IóæíÂÚMžü|4¡‘DþÅë*aQ© t±±‰@àÆbñ[*ÆÀF ä#e6Íš]NûöþÍ*“ÉÐòí¼aZ‚–À³è8^ýìv{¨. بV­ M›6¢iÓF´kw-ÕªUìLž<‰§žzˆbxñÅ×éÒåf‚{Í›7ÕÚ]wÝMD• i‡~ŸÛí kwë­ƒBæ´§ÓInnn`¾ twd n¨aŸò2NBrËÑó\h¸`6Ñ‹KÕQÜ¢ ­C}ºÍT{¾3Jö¯†™—:J†Éd ÌSðÊI÷ä°qã&fÍòï]DDD0hP–,™Ï5×ô ¸²²"«ÕÊ–-Û´vA!¥¯Äu $$Ä—ÐN V =ÐVþ õÂ`çs´¥@Ûo“\´c_¡ˆÅb¦råD®½¶#ªªríµiذ>‹!{÷îgÿþƒüòËêׯGrru¤”ÐÁ“ŒÀˆ.‰‰‰FUU.üU•lݺ5kÖ‡Ëåâûï!¥ŠÙl&%¥.B+áõziÙ²%99Ç4¨?Íš5A? WÄþ£S§«.¦GéÑ£ýô}NœH'!!€ììÖ¯ÿ÷Þ{“uë6R¥JÕ«WeÈœ ëuóÄ£±X̤¤4`À€¾,]êÏ'Ó¶m?þ8ƒÁ@“&ÍèÝ»+Wþ†¢ÜnÓ§¿Ž‚Ë.kEzzO<1ð2jÔa¥êæs˜æ–Ç’%?óå—³¹üò+X¹r ï¾ûÇDU³X²d1Ï?? ›ÍŠ×ëãÈ‘üöÛz‚›à×_߃¯¾úŒ%K~Bʼ€ÅRÀÏ?/àùç_Æf³æ¸~­¯×ÇÆ›™4é)víú“Zµ’”N,ø’W^ySËæ?ÝŒÇ÷2l؃̚õ>þ¹' <º•»H,ŸÏCëvIªR]_`:J…ç© )U.¹¤±öwåʉT®œ¨¥HM½”ÔÔEÌü¸¸XÚ·o£1w)½ÜpC—ÝCË–-hÙò2­Ÿ¡H¤tÓ¦MkÚ´I+Æuà lèúŸëÒK/ÑWi1ð3^;·Þzs`CÚÁÝw߉”¹0k'=62l|Û´i2Wvúô¹ p„EÞ€¯P;Ò‚¨¨H}tD!š'°çe(D“Íÿ}¹Ü~{ßZù ãUU•šµS¨S¯‘¾Àt”â„…ß~ª Òœr-ìB*S~òßÂþmY¤âiŇ ê8­øÏSÍYIsU\Ÿg³N¿Fd¹Ÿ[}ûCÇ¿±Vþ±ñ¿Pz:ðóÁp!xúK¦RÌ<íbñ[Oú ûóƒÓb˜8}þ1Ë ,!Àxº/Ü.½¤­Žr @ìv}ô¾¾Ï1âéÞ½[ æ‚‡¯¿úƒÁæÆP„Ðò ü‘fѱ§Þ,³Z-|úé§äææèƒ|.E‡Ûà@] ³ÙÄœo¾¥ ß&CTŸ%dN‘’ÌŒ¬3úžÌŒL/[Šˆ°"ˆ{V&ýú߆×[~Ç+˜±À®úËÁæ1±–’i:*ˆñù¼$'×¥{÷›õÑ<‡p:s°Û3BÁãñ `$µE*ªêß\®S·.‡ „'û…G«´ÖÌšýái4V…#GŽ2jÔú ŸCø|nrrŽN*8vô;tÔæKQꥤ°sÇ RJj×®Ã7ß~~Fßã.›ü i«VK¿èûݨjù¯`ÆZ€÷fΦOßÛÂèùyyÄYcøô«oéÖ½§¾À*ª9éÑq®5²ÂÚd0¥‡Íf#6&†%»vѰA<RJTß™q‰]»v±}ûv=ëpÂb±Ð¥K—"óœÓ`Hyë´4vïÚEn^q±þjvêYÖQCæ/´ìëXààÎbü[RJ,Û ¶´=p¢\J‰Í*œnöÀén«Uàrù_«9œf± |ÒŸZÄdï3Ân9iYÿØ|9wÇ+ò¬I‰ÑH)qq2–¿ö¸(r:ZÅŸ[ û>ÒVÇ¿(@.6Fd°¡ÿ?€ ]¤¥mWZá]­zuòòòèѽ;ò i­[ŸááG?>ùäžyæ}’Ë111äääœr=ÕªU‹¼Ü\j֬ɾ}ûðz½aîÉ3EUà!ü;.ï®õ>ÞŠic6 žnOK›6m‰ŠŠ&//—u¿­!Óî#!Â@·î=µùyy¬ým5 Ý÷ïL}‹=Žsûn ¿­Y…CÂÄÿ{–å¿.¥UÚå4jÜ”éSßbm ‹lŒM¡s§k´wÁép°jår­’aŽ òòóŠ0ø(« ÃU0™LL˜ø—¥¶Ò®¸ýŽ;ª½•*%’˜”Äo¿hÓ®=‘ëÛŸ58["åC€¨ªŠÁ`À`0hâõzY·n­Zµª0ƒdøÅfW…””ìv;G-UB†ʇ~È%—\ÂæÍ›ËôY^¯§ÓI÷oäðáÃgÕW0=valÛ¶¦M›žõ3;vŒªU«–êÞììlâÎsý†s‰¢©nŠÎ_PXx½^Ú´iÃ4×֙ –‡“­À×@k`h-vlûƒä¸$¹9¹ÄÄÆGNN6]oèΛSßÓ~OLl ñ defòúÔ·¨”P‰:uëòËÊuH)©\9‰¿ÿ>ÁÜo¾âûÅKY½jlÙÄO¿®¢Zõê=r„ÌúbŽö ¶ˆjÕ®ÃýûNYË»ÀŸÏùŽÏf}Ì_îÖH ^yc RU‘@µÊ1˜„À!% ZõêlÛsˆ‚ü|mìÛ¶»‚å«Vœ¶–Žód´jÕŠuëÖs.É5Vr* Qæí‚ñÿV«U;Õ\¸Ï={ö±$N×ïûï¿Ïû￯r, x<Z¶jE^NNXIÌ?÷ì!¥^½2ûžÈÈvj5::ºT®žŸþY+XtQ@JªV«FDd$¾€À°Z­¬]·Ž´Ö­Ï*‰˜ Ü ,&„ÐÖž¦mff&™vªO%:&†³¿ú€½ €¨è("%mcÌhuEl@vV&33´ïÕª×ÐüDQÑјÍf„Pˆ±@~^~Àêýû÷tŒYm¶B¹ÑNµ¦b°ÙlE†(˜ÿÌãvÓ6­ >)Éq¨Xm v»ýûöb/(ÐÞË‚‚|½gyva™¬×ëeÚ´i >\c¶?þø#M›6%))‰yóæáõzY½z5>Ÿ~ýúqÅþêqÛ·oç­·ÞÂd2áõz4hiiiäåå±råJ<ÈÖ­[ñx< 6Œ-ü‡×®]ËÌ™31x<xàš4iÂßÿÍ®]»X»v-ûöíÃív3räHêׯÏÑ£G™4iŠ¢0zôhìv;<ð€¦ûí·üôÓOÔªU‹1cÆ„Y_~ù%Ë—/GÃá`âĉ$$${ö¤,,¤¤$òrsÄGDD—\r Ÿ8qÆ}Ÿí­·ÞÂãñÅÝwßæn{ûí·q»Ýš5öðÃðØcñüóÏk÷=ýôÓL˜0!¬ÿéÓ§SPàÏ~ýôS¦OŸŽÛíæÖ[oåwÞaÈ! ¦NJõêÕIHH`üøñL˜0·ÛÑhäµ×^£zõê ®¿þz>ùä† ‚ÉdbÒ¤I¼òÊ+¸Ýn¦OŸÎˆ#ðz½˜Ífž~úi¦OŸNVVW^y%sçÎ¥sçÎX,ÆŒìY³ˆçá‡fÖ¬Y 6 »ÝNrr²öûÒÒÒhÞ¼9Mš4  íÛ·§Q#ÿi`›ÍÆ-·ÜÂ/¿ürγ-"¢Ø$’I•+‡1¥Ò"77—… 2bÄL&¹¹¹ìÝ»—¬¬¬0!ÜVU•ùóçÓ½{wÆ&@‚sŸŸÏï¿ÿÎM7ÝDtt4ƒÙ³gÓ¿MAhÞ¼y˜¥wq þÇvPÒét’Öº5êYŽEPÜ¿D/üÃgÍÏl-™ IDATË#&&ЍŽQ’›-˜7Ò~o¨EðÔÿ%#=]ûûÒ—ih0Œ72°_kAÛ ÒlDFDj4ðGo5½¤9¿mÚ¢=kP%ÉHOçõW^ _ónýLL¹ ©©©lذ¡X—ш#èÕ«íÛ·'--ø#)\.®½öZî¹çí~ŸÏŸÏçó‘ŸŸOãÆ'S–¸Ýn(«¢Ð¯_?n¿ývæp8ðz½x<òóó©W¯n·«ÕJff&>Ÿ?»îƒ>H¯^½Â|着AJJ F£‘† ‹–¬^½º¦}F¥J•4wMtt4‡:Gœª$%a³áp­Oa6›Y³f —4kvÆB©qãÆìرC»V·n]8 ý½wï^Éû|>4hpJft+\vÙe'ÑHýúõÃÖGLLL±¿åB…Ïçã²Ë.ãèÑ£%ºZ·oß~ŒM¢šMø¬V¤PxäUCü™ßŒ;²§ (=¢-èÚ¸a±±±ØÏïÕê~ÄYQ%¸)ƒ{&]®¿ž®Ý®ÇZA«ŒôtEAQ ø|^²]’KRji‚@ÙlCÞ†”’WÍb ýÜ.mM¦ÔoÀñãLj³ ²IkÓ–å+–ikÍ`ð³=¡RrÅ•Wžñ>ˆM1pèå×ù½Z5¨7þ=‘ßO~1QÙÙE28’o¾ùŠ÷ÉTY•œœM»/M–r›—›«YšÕ┬^½’\×Éê€ù^ɱ£G´>CùEŽ < Ñ [£Áþƒ!¾…i{þÜ]”'¹ÎS÷©£œ£ÑXâ ³iÓ&fΜɢE‹xíµ×عs'C† AÁO?ýÄï¿ÿ®iªªªâóù4 ¥°Ð8¯ÜãñлwofΜyV¿#33S{îáÇ3yòäbSá‚QJÉÊ•+IIIaêÔ©,_¾œï¾û®ˆ*+S9+;‹Ö­ZR£zõ5ܳþ…7ùúé§@A%X¼xqØó/\¸P{!cccKì×n·óùçŸÓ·o_mþ‚‘VwÝuW‘¹½Ð…GÑQQ ¼ãŽb“ !ˆ‹cŪ3sÆÆÅqyB\‘.“BÿHH@U‹ÖÏwUÂrBö GFÛ¾¯°+«ðµSõy*ZðzðûŠ£•½,o\R;g‡2½õë×ÌRÿGÁºuëp»Ý 6ŒW_}UsgmÞ¼™7Òt_Ï‹/¾¨EA%''Ó¬Y3*UªDÿþýuÍýý¥¦¦’’’R¬ü;%%…æÍ›‡µûøãKd°…û ú¥…\wÝu˜L&„Œ=ZÛ$B°dÉ„tïÞ]³>„ÌŸ?_ÛB0xð`„ddd „`ãÆÿXƒ•R¢ªj±Ÿ³ ñññı…w÷îÝ5¡üÎ í¦›n">>¾XšÅbaÓ¦M€ÿ,D0xÂçóár¹ŠuÿèüCE‚D‹¯ÂŸŒÌL–/_~V NUý2éTÝ篣ÜY Š¢œrtÍš5aa¼“'Oö›µùù8NfÏžÍìÙ³Ã4{€!C†0dÈ"®¥jÕª1gΜ°>çÌ™£ÑGí¼Þ¤I¦OŸÖnÙ²eE´ñÐßüÿË/¿ÌË/¿\¤O€iÓ¦1mÚ4íúóÏ?¯Ñf̘ÁŒ3*Œ{%Õ«W/Ñ‚ª ÎP´hÑEQ4·aa·ðZ öQí¢C@9Сã¢ra•–9vå÷œŠ‘•D+®ÏÒ¤z?•[©8s¼´ ·´´ò†ÂQ2Å É3¥—Ä‹»?xíB§:…^†æ &“³ž[GixpÀ®¤8DFF2oÞ<}fÿeŒ3†¡C‡êî2ÄùpÉM&-ü Ë«>à:J‹ÅváEQ¨V­š>«ÿ2âââ.¨4"“Néõzô a¥_1e¤#žR\ú’Ò†Çêøwq&©gʪ½¾6Î ^›n=o£^ýºú`è(žÿßò'@¤”¤¦¦†¼ÿþû¹ï¾ûRO0vìXæÌ™vXMGyÖTýúõã³Ï>;ëö7Üpßÿ}‰k&??Ÿ-ZƒÅbaÍš5úÀŸ™‚ÛíÆ¥'ÔQê%S6 Z™Ú¼ÁÄM›6±aölÙÂÑ£GY¹r¥vÏsÏ=ǶmÛô¬@¿³AIé\‚ŠF½zõøë¯¿Ø°a«V­Ò\‡Ž ‚2wa…ö "‰“žžÎúõë±Z­tèÐ!¬]VVk×®Å`0 ª*Mš4!99¯×ËÒ¥Kq»ÝtëÖ вeKmÏäðáÃlÛ¶ EQðù|´hÑ‚*Uªàt:9~ü8deeáóùhÙ²%‰‰‰Øív2339zô(¹¹¹ø|>ÒÒÒ´3 +B“\s—uëÖ-,**H Îëu×]ÀªU«h×®vßòå˹òÊ+Ãú_¸pa +« sçÎEBvK“ÙXÇ©áóù°ÛO‘@‚bøöÎ<ΦúÿãÏs÷{gߘ0ö"!¥,!²Ä×N"©-²dß"T ýdI‘%K*•ÒB‰KTd)!û2˜}îÌÝÏùýqïý¸w6ƒ¡aÎëñ¸™{Þçó9ç~¶÷òyÞoˆª[TãÆh”@ÜîëÓF#¸\àñ¨ãå¦a {÷î¥W¯^„‡‡“œœL||¼ˆc•žžÎþýû6lXТäp83f •*U××­[ÇØ±cÑétôìÙ“1cÆðå—_R¹re¾ýö[&MšDtt4.\`ÇŽâ”ø_|Á´iÓHII¡FŒ9“É„$I|þùç¼ù曜8q‚úõë3lØ0ŒF#’$ñÙgŸñÖ[o‰3 %R­•$&OžŒÉdy*V¬X!â!ìØ±#(bêï¿ÿΨQ£rEÒmÒ¤‰èK³ÙL¿~ý¸ýöÛÅAÃ}ûö1hÐ QWûöí Åh4²téR•‰\!l¶lΞ9CD>Î:Ž-?üH×nYNôP“Ä£=ÃãqÓûɧiÖ¼Eå‰j„Ì<>Ùí6:·íÈËS^£ÎÝuÕŽ¿YÈ­·ÞÊŠ+|¹Ÿe222Äéæ*Uª0tèPFTÆårqøðaàÅ_$99™Ò¥KS¯^=,¤Õ'žx‚ôôt¢¢¢¨S§NP ¾ž={ŠøL­[·fâĉ‚Ö¶m[qÖ¡}ûöL˜0AК5k†Ëå*Ñ `þüùAñµ’’’D20EQ7n\Ðý•+WfÔ¨QAL&'³gÏyE<õêÕcРA"üüöíÛÉÈÈÀn·óÐC±fÍuv^!Â#"(]:>_©==-¢äÍÙN˜<íuþøm'[~þ‰Z q8<òÐì]÷¶û;ƒ‘·,"..Níð›‰ø`ÿIñ3gÎé6PåÍ)ù~ÿý÷„‡‡ ºÃá`ðàÁùÞï¯ïÍ7ßdìØ±B“ÈÈÈ'Üýõ–ó×—­¤#Ðô¨( ±±±Âi³ÙˆˆˆÀl6‹{ó IY– ZE`"®ììlöïߢ(„……‘Í… ÔŽ¸:›Òe“EA§“8yâTP¸þJ•+âv{i'ŽŸs1ÞR±qÇ Œþ¨( :½Äñ£'‚Æ‚¨S/qìÈ ÁÌü4Y†Ä³‰X­™$ž=éÓIdggQ¾B_8}ê$ åùŽ9`…Š•Ë#{àÌé3ÜR¦ 'Ž_¤W¨T·KÕv‹  ìÌ'NЯ_?^ýubccó=…®( Íš5cÓ¦M¹êñ5Ì §OŸfóæÍAÁ«T©¢†Á¸ dú²ÌùûiÆŒ‚aø™€ï¾û.³gÏó‚Á``áÂ…"p¢^¯‘üQ‘ýcÂb±\u„ßÈf(b¬åejº® NbÓÆXùÁRdŸ)Ò#{¨}ç]Œ3‚/¾ÚÀG+— æâö¸iÚ¬ýŸ}:_ï/ƒAâ‹Ï¿ä³OV ¾â‘=´x° ýûõæÃ>cígŸ Y‘iب C_ÈäùosìèNž8Á¸Q/a³eóÑ'‘í³&ŒÁßícĘñt}øŸð*±|érÖó5Z?A¡S—nôêÞ…¨ªå?y ûöü‰V£ ºtëAÇÎ(dpnךøC7H¾ÉËþýûiÖ¬›7o¦oß¾¸\.ªU«ÆÀûŒôôt*T¨@¹rå A£Ñ°aÃvïÞMBB‚È¡×ëY¿~} м&š–/ÏÓlêr¹D’­ëƒ&Íæm¿pxþ«ï6£^›ò2[¶m Z0$IbгO“Ÿ÷°QFçà?r ûõf̈¡}ºÐ4š5kÆÑ£Gsi*†¡C‡2tèÐ\´˜˜~úé'E¡aÆ(Š"ì㊢0~üxÆŸçû¬Y³&è]~úé'À›øiÙ²eA´‚ò¸—$T­Z•#GŽäÒEá¶ÛnãØ±cA´3gΈ•Ç¢ù]ús`‚-ÿµÚµksòäÉ\ý~³C«Õò×þýÔ»÷Þ|5ø *°ï¯]×å}²í ¿íø•Ȩ(ÒÓÒ. V.Kô94¥ÈKx-*¾r95¬r¾T½ƒ§ëb®EQhp_cáÅåt:QàpHu8¼´sæR1Œ¸ÖZ‘åÐãöÐàÞ;EØzY–1 ¨bãU¬ùE£þêrhæ—ÜðJÆnYPÀÄ¢ÎÑqMÖë´¨^i?¦/·_J:®ç¦ÕJlؼ•´ÔÔ °òaz pöôi<9BΧ¦¤ˆäNF#Œt:f½Ï8súT®Põ'OœÀƒW3éÁdô~BM¾ý½ábÿ»Ýnô@ˆIâû ߢ×{™ˆÙèÕV z&ãÅùa·ÛÐs±N“ž\ù„T# D’4|÷Ýw,Xðþå PQ0dY&22’+ãp¤« ¢¢P/Ûk.˜òeÚàv»hß±‹Èãr9Y¸t%.`êôtèØÛ;dz²¬lؼ FC¨:uìBbâΞ9Ã/?ýÈúM±{à­¹ïÒ¦]ñ26[6ßmÚˆËo¿³ömÛ‹=ÇMÏÇz£ñ½ž^¯§UëÿѪõÿ$‰^OôE£ñ2šÖ­ZsòÄqt:KÞo×C¶ï/_M«ÖÿikÞ~g!Vkf®ó×é¨âÊÊ@$vîÜɰa£iÓ¦µÚ¢E ÿ–+V¨¡âÒ&†­[~&555ï…Q’ÈÊ#u‚ۭФiSjÔ¬u1¬¾¬K–]¡Á}÷1÷¶÷EpEV„™(Ë o/ð.Ò^/;‡Ã«4} wìå(Š‚ÍGkÞ²%µï¼K8S)ŠB\\¬0WiµZ†KF†WpòÓ\‰…KWxUz]‰eY¡]‡ÔkÐð"“T 6.† 'KL!Ó¼vý²sw®LŒ*®#ñw|•*•…·ŽŠ¢Ã¦M›þÓ(«×;˜¢z€ðê`±„еÛCH ‰‹{ ‹©,CTTtŽþ åHwxOttLžÂ¥,_‚“CãÖôz=11±A4Ehßµ¼Þ3&ͿǕëÂÃ#ÔAs5KQ.4}ûö ºÞ¨Q#Ê—/_¨:{ì1Þxã µWxêû¿€$IÌ;÷ŠuI’xóÍ7ó-¯( N§“Aƒ1hÐ qNDÅ•Ãí—3ÿÓ©î3©(f ÄaƉÿÃÂÂxî¹çHLL,TÙmÛ¶ñÑG©½RÌ0eÊ”«*?zôè<¯Ë²Œ$IÔ®]›0pà@*W®|ÉÔÈ*T¨((òs ®€9GŽ 5˜Û¯ÃN£ÑpæÌNŸ>«N­V+\ñÀºÚ¿aŸM’$t:.—K˜ÖËÝ,(Ê…Öo>ÊÎÎ0‰X‚´ @šŸÞSê&ÌÀïþòþ²’$a6›Ñh4˜Ífl6›(·gÏqfH… %ŒÄÇÇÓ¢E &NœH\\\P´Õzõê1{öll6†ß~ûqãÆ‘••E“&M˜2e 7R¯u:cÇŽåÁÄív£Õjùõ×_7n‡ñãÇÓ¼ysÜn7:Ž~øW^y…¨¨(¦NÊÚµk1b„8¼6uêTÁ´ndôz""#ũ᜸…$IlÙ²…áÇ£Óé°Ûí <8ˆA7kÖ “É$4ˆ3fP¿~},K3 ü®×ëùàƒ˜3gF£FÃÌ™3¹ûî»±ÙlüïÿãÉ'ŸD’$–.]ÊæÍ›Õ½Ë1#HÎ=¥z©(äDM¥Z¾&Èûï¿O… ‚˜ÀöíÛ©W¯žø>yòdªW¯Îï¿ÿÎ?þH“&Mr-î4mÚ”F‰kµk×F«ÕI•*U‚h+W®$&&†³gÏrèÐ!Z¶lI“&Mزe sæÌ!99ùFW; '!!§ß&°SµZ~Ù²…ò*\vÕíÛ·'55U|_½zuÉiÇŽA÷—)S†3gÎäŠ-–111A‰¢j֬ɾ}û„éï÷ëÂãf€V§gëOߪ DE¡a¶M8ÿ"Ÿ­ÉÉÉÜu×]X­Ö\Z[´hÁ÷ß/Bzëtº *¿úV¬X¢(x<´Z-Ï>û,{öìÁb±Ð³gO~øaÁ¬t:C† ñJéü±¨«yóæ7Ç¡"IEÁåráÌë÷ =r„ûï¿ÿ²«ö›¤ü&­=z0|øp¯¤«Ñ I’ð “$IDê½”PѶm[¡U𣢢‚VË–-iݺuÉgRdB›ƒŽÝúP¡Ò­jc¨(„"1gƸâÉ@ü åðáÃÔ©S«ÕŠÁ``Ö¬YAf‰Å‹_ÒËH«ÕòÍ7ß•[¾|9ëׯ';;›•+WÒ«W¯B½ÓÍz"5OSÏš5@I’øë¯¿D©œå©S§hÑ¢…`õá±cǨX±"à5iùŸS¥J• ÚáÇ)W®œ:Ë/W ÑêÐë jC¨(¤£hª)rhʸí¶ÛX¼x1ãÇçÔ©S¬_¿ž9sæm¢qãÆ"šk:uèÓ§Z­–™3gòí·ß²aÃôz=&LŠÚzþüy.\¸€Çãáܹs¢NNÇòåËÙ²e à=„§šD.S¦Lá¹çžÌ"44TäP™7o^-$$D˜Ð^ýuA“e™W^y…Y³f1dȲ²²xï½÷HKKÌnäÈ‘üöÛo 8Ph5,Z´HÝQ¡â@‘¯®Í›7ÿ˲Ì!C°ÙlȲ̄ ¨R¥ ²,c·Û™8q¢Xœþý÷_.\ȼyóÐëõœ;w»ÝÎK/½D… Ä¢rêÔ)¡÷å—_&!!Aн¸f̘äá£âB‰¢ðôÓO³oß>$IÂãñP»vmú÷ïÀÀÙ»w¯Hìw¿xá…rÑ> À?ÿüí·ÞÊž={ÐjµH’D5„63gÎöïßx÷·TæqµÚHa4MµUC’3"k`>›Í&6Ns"333_šÕj LNdddäK+(—ˆŠÜð/(5kÖ º^¥JñÎã•+WΗVµjUÀ›¥ÒÏòzžV« ¢© Û•#+ËÊßíG¯×çi¥ðlبòx´§¦¦`6[„'^ ð‘WÄ«5“Ð"íÓÌŒ Â.á´¡âc †§Ÿ~ZüE‡Ã!òÉ«PQX-²|ù ”)ŸgöA£æÍ{—ÆM.Ÿèõнs;žyöº÷|”À€ĺ/ÖÒ©k'ܾí°P#Ô®V‹Ý)²u!Â¥J‘n·cWcXÝ D£ÑСC*\Û¨Š‚ÑµkW5´‡ŠË‚,ËäwÔÉ­E8Eäd-C!Ô$EÍÛ*¹û5—ô|LP’o‘®wçAåüÌ,<<œ&õî ¢…‡G‘‘.\"®T).œ?ŸË àÁÿµcÃ7_åI»­Zuþs Í<ÜãQ–¯^YâÍhEº‰®( #FŒ T©Rb¢'&&2|øð ÍÖ¢BRR/¾ø"_}õ•:û¯!xà Ã~—‹{ï½7ߘ]Šï@äí·ßÎ÷ß/,{M½{÷¦zõêH’ÄêÕ«™?¾ÊD®1Ž=ÂìYo²bÙâ !1ÝééAæ'I’°:@§ǃ d:.j"i©)ü{äi6É—|*44ì’ïž–ÆÉÇE9“Ñ{è¼ïpèà?‚¦×{Óëz|ZÓCÝÁh4‰÷+[ΛB÷íwòH¯'‚Âú5§ðˆúôë/ÜÒeÙ#6êgÌžGG¦?“ÉÄÇ«Wªf¬kÁ@~þùgöìÙsq ¤§c4óô×sÞã_t *—W’œuÖ¡.>—îÜí–/ÍQ7ÐÇ¿øûÿæÕGþ}FCµjÕèׯ_P݆ʕ+³{÷nq¶hÏž=ôîÝ›¥K—ªuí¡aaŒ†«Cá& ÞŒ¥W±Ð*+D‹$I8|&¨@hÚwÞÅ'_|Ýn÷î]DEÓªiCÜÀóÏô£Q“¦‚(ŠÂƒmÚ²áÛ¯q9]L˜< «5SÔJº†¾0]-Z‰rv›MÕ@üó´È+ÌÑ©"«Þ·ß~‹$IX,ŒF##FŒðJ0V+ 4 ȯ¿þÊàÁƒÅ÷ùóç£ÑhDdØ©S§=¯M›6X,q¼‘€{ôè!·?þ˜Ù³g«Ìãð‡‹±X,H’Ä™3g‚ò—ûûÏ߇þë:NÜ—3ä‰F£áСC¢lxx¸0{FDDpôèQaò Äñãǃ¦–/_^œRQ$)ß@ÞëRž uTTYYYtlÓ‚;jÖfãÏÛ‰+UJ”;îÉÉIdeYI<{>WááœM¶’MlL z@Vr;€äu-'¢¢£‰ŒŒÂétr.1‘ÄÄTbãJå[^ñ]³;ì>7c3ñ·”áŽ* „‡G J—ާT©Ò˜LfññG§ˆ‹Åd2‰ëf³™¸RqD!""’ø[ÊšÑdÂéT]ÀŠ\¹”TÒ¦M› Eb̘1ìܹ“Ûo¿=HJÕjµbqJIIáÓO? òDzï½÷¸pá’$ñùçŸsôèQÊ–- @çÎéÑ£&ÈW]§ÓýçÉ™n„‡‡…¼üñÇE|,YÎm_މ‰!999hï"'ŒF£ˆàÇm·ÝÆÁƒIOOÏWËTq¼‰3§O‘táBÞ^§ÃnÏÎuÝnWX½r9uï)ö1žzæYÏž%Õ&fÖ0väPÜnFƒOõæ‹o¿im].…Ï¿ùŽ>>ì·ÉÉd+йk· ¾u÷~ç%~GjJ ii©4où aáá8Nöíý;ðH¯'pËÚ,<üH/ìÀÁÓºm{L&™X­™ =›çÎ%ò`›¶˜}ãY’$~Ü´‘”l'ާUëÿañcNÇê>$Õ&“žžFËÛâ‹íg2™XûÙuýz2I’øóÏ?éÚµ«n¹sç°nݺsV¨¸hô‡Z÷£W¯^¢söCÏž=-gßöéÓEQèׯãÆË5&r t¿›öرcƒ®©Èc"ëtèT…™çY:¢×@.çzaè…©3§­ B… Ü{xÍfŒF#mÚ´áÃ?¼y!IÂn³‘•••‹˜°ézôáÕö_aé*óÈ Y–q¹Ü¬ût’Fm…ƒÑhB).rÓf[R…>}úЧOŸ\RíͧÓÉŽ;8Ÿ—»¦¢äyxOÅÍÇC­ZwröìYÞ׸åJ7¿à¡ç;W£2(ÁffdpkÕ*”*U*ßÅEÅÍ ·ÛÃ}÷Ý«2W,d{ ¤ùûÐÿIHH ¦Äl\.—(k±XD¹ÐÐP¾þúkî¾ûî\f·´´´ ç›Íf•y¨Pq33]»vO©R¥ˆ‰‰Ál6Ó¤IC‡EQœN'²,“’’"‡uíÚUБœœÌ;ï¼#hŠ¢ðï¿ÿrâÄ NŸ>Íš5k‚h¿þú+çÎãßÿå—_~ ¢-X°€ääd$IbìØ±¬^½ZЦNJfff‰ ’$Ôf+V$22Rh ~š¿ý›øAu~ ¥aÆ¢lvv6ÕªUæÍ¼ölüñ²UªT§ØUkÌêGý\ɧ ÿ?3aÕ­[—ß~û-Ï׿`†Ï ‹…š5kòÒK/Þögžy†òåËcµZ©T©’ ¹\.†JéÒ¥±Ùl¹6ïýRµÛífÈ!"H x#ƪ¶u‚‚ʲ̱cÇ(W®œÐ, $ö44 ·ÜrË%ë´Z­üöÛo¤år¹‚´´@Úl6ú÷ïÏþýû…†¤Â7yuZvìø—ËI^!ÚU¨(ÕªU'**œ«ñâ+r’×¶«Y˜Íf33fÌ`×®]hµZt:3gÎdÒ¤I”)S†7Þxƒ?ÿüSÐ&OžÌŒ3.Y¯ÍfSGÐeâ`Μ9AÚÇÚµk¯É³üÌÆ/ä>Tx=ÿøc}ú<)òZ¨PQ$&ž%11™è舫ÒBŠœô2~̬¬,±aê—(Ýn7:N”w: RRRèÕ«ëÖ­Ãf³a0p»Ý¸\.yöÙgY½z5‡£ÑˆÝnÇív‹„F~s‹ÉdB«ÕªZÆ%‚ËåÂápJhh¨HG|äÈn¿ýv²³³ Åh4Š8gþ| V«•ÐÐP‘CÄoªP¡ÇÇjµâv»=++ ­V‹ËåÂf³aµZÑét" ™¢(X­VaêòÓT\d"^3b–Ú*.C@Ëâôéä«×‚‹ò¥$I±¨rÂ`0ðî»ïÒ°aCÌf3‡gŸ}V,@[¶laäÈ‘tíÚ•Æ3pà@zõêEtt4'N¤I“&F\.ãÆ£B… 4ˆfÍša0p:L:•øøxzôèAóæÍÑëõ8fΜITTÙÙÙÜu×]Aï×´iÓ\^@%oPÉúâ‹/òefË—/ÏWËU5É›Þ~D–SÜÂ>š£À>÷Þk (Jš:>®×šqMä Ë#èp½h9ÿWÛµë§ü6½ *SP9µ¿næ±BÙ²· ÑD‰~þôÓ5¼ÿþû…¾i`Ô¨‘¾q¢6æÌ@T¨P¡âJ`·ûŒlÙ²O?ý‚'Ÿ|.`oUï3œèmÀu¯½6ÓÙ ç~PNhD„üh^øëÏ‹¦nâ`Š*T¨¸%ZŸæùꫯ’mcùò„IêìÙDFŽ|‹ÅŒ¢(4jTŸ'žè‡¢dqòäiÆ{…ÈÈHfÏž xcò)ŠBrr2ÆÅlö–kݺ]»> Ø9sæ cÆLÆd2!Ë2:µ¥]»¸ÝÙÌž=—¡CÇ0dÈsX­VºwïB«VŠºU\ƒ`Š—>äZ"ð¹y…áPQø6¼Ò>ô·ûÕ†ÉEÅ͉¤¤d¢££Xºô:th´ŸͨQCÐj½ý¿~ýF¾þúsÚ¶}R¥byõÕ‰Üzk]fÏ~[,ò’¤¡K—^¬X±›Í†$I,]ºŠØØ7nÀcõgÉ’yØlv4 K–¬ L™[¨S§11ÑhµZvìøððpÞygeË–¡FjjGù~QW¸víZ$IÂh4¢Óéxá…þ3›µ$I4nܘuѹŠ6Œ½â>ô‡?¹óèß¿?;vìÈ“XÚ77J—ŽcúôɘÍ&À4ôz¥JÅC\\,™™^÷n“ÉDÙ²·ûÊ`²²²)]:ŽØØbb¢™8q÷ß߀sçÎSºt)Q§ÝîŒÆb1³xñ<êÖ½‹[o½‹ÅrʼnÚT ¤ÒêK/½d'üì³Ïøûï¿©^½ú%µ“œ’èÕLôÓ~ùå ðKz Å¼~§ÿÌF~Þuþ¶Î©­¦¥-¨¦L™Â§Ÿ~ÊÀód`ûöícÚ´iâ¬‰Š›.—›§žzAƒžáÈ‘côïÿ¢O Ñ1sæÿ±aà z@âÔ©ÓL˜0âãÙæMëhÓæ!BCCP…òå˜|¸Xœ<ÈÂ… …äúóÏ?S³fMêÖ­KíÚµùâ‹/mÆ ÔªU‹ºuëR«V-6lØ h+W®¤V­Z´mÛ6W€ÆÅ‹sçwR·n]î¸ãvî܉$I>|˜/¾ø‚ž={R·n]jÔ¨ÁÞ½{KóeI’D{V©RE\÷·ÛwÜAݺuEúÛºK—.A^m>ø`®6«Zµ*uëÖ¥~ýú¢\£FhÕª/¼ðB®$XŠ¢páÂf̘ÁÊ•+ÕÓÖ%³gÏ#**’_€$EzFšÈúõùòËoùòËo8|øHÀÓ”z Ä'Àh0`›6ýÌ—_~˺uë©\¹"Û·{Ã-Ýv[U>ÿ|æ¥WªT1OAl*ó¸–È¥$ÙF±gÏïƒu:^zé%vïÞMÕªUƒâgeddpèÐ!RRRxýõ×Ù·oŸ8­þÄOP»vmŒF#ï½÷{÷î´nݺQ«V-n¹åyä}ôÑ<ÿÞ½{óøã‹wiÑ¢k×®Ån·Ó©S'öïßÏm·Ý†N§ã¾ûîcóæÍ7}¢+FCùòå9qâ„hO‹Å­·Þ*îùóÏ?/ŽêÕ«sàÀ~øá‡ º¾ûî;ñXXXP½n·› °}ûv~üñGt:Ÿ~úižã§N:œ>}Z©%~!BQ2yøáθ\.Þ.O>ùüñ³˜Ëaa¡,Y2›Í+TüñÇÔ­ÛT,ö}ú<ÊâÅ‹Ï=÷TÐðÌ3}y饡(Š“9sÞ¢ ú<3f¼¸<µT\w"IeË–åÌ™3lݺ•† ’™™ÉÎ;E–£G^úu:"##Ù²e .— Y–™7o¡¡¡$''Ê/¿ü"²~ðÁÂdR½üìÙ³..ŽJ•* ³c~ ¥fÍšìÛ·ðÕÌ™æØh4æÚ?˹©>jÔ(Z·n­†2Q¡¢˜ H7Ñ5 |ðHLd6›‘$‰ûï¿£ÑÈÛo¿-h;vÌ$44” &ˆ uÏ?ÿ<áááüóÏ?DEEѽ{w´Z-¡¡¡èõzxàªT©B||<-Z´@§ÓŠN§£G”-[I’˜;w.z½žøøx4 «V­ÁµjÕ‹ÖªU«xòÉ'Åâô»bbbJˆ A!##C´§$Iœ;wN˜™üYý´ .äòlóÓEáÞ{ïÞŸþ)è‘‘‘üý÷ß”-[–ÐÐPæÎKƒ  ¡gÏžy2L•yä7•%õ£~.ãSÌ4ÿ¢‘sãÉÿ½I“&ynJyO‡¶Îs¯AQ:w‡x£¹öìÙ3OÚsÏ='¢Åæ¤=ÿüó<ÿüó¹žW³fMjÖ¬äŠúÕW_•‚ß܈?þøCôMÎþÛ¶m›ØlÌIÛ¹s'GìuÒýõå·AžSËe™“'Oª ó„Þ÷Q¡¢°’Š)LÃË¥_IWJËë¾’&íæ·8_*¸a~í”ßÉ¥˜@Îúü÷«ÌC…Š"÷‹Ÿ K… *T” Sm*T¨PqÃ3õÐN1Tt}}r¥gaüå *9ý^’Îä¨PQ¢ˆ?†Éd"66VäµÌD—²²²èܹ³ê]S !IwÞyçï=h4.¹‡òÚk¯±{÷î\ŒåèÑ£"žV©R¥Ô=Ëdü1ç@š*¼©øÏˆÿô¨Ýn';;»ÝŽ¢(Ô­[7ßê÷ÞIOO¿¬]Ð=êd(Z-0555_Z ÷U~“““ ,·qãFFK€HLL¤K—.(Š‚ÍfãüùóªRH¤¤¤\2ë£,Ë4iÒ„¸¸8q~ërçÐ8× ³¦¨(t׫“<~ø!½zõ ))‰Ý»wÓ²eË\å$IbýúõÜ}÷ÝÄÅÅqðàAqÚÜãñн{wîºë.¬V+?üð;vàèÑ£$%%‰ó*.¿Ï$IbÔ¨Qèt:²³³™9sfPäÜ‘#GŠSÿ²,3mÚ4fϞ͠AƒÄ}o¼ñǪèСX,´Z-“&M`Ú´i8¦OŸtH L™2ꤾBÌœ9“¨¨¨ï;v,³fÍâž{î¡ZµjüóÏ?AZáœ9sHLLÌcœØŸÙ>žˆˆÂÃÃùóÏ?Õ ^A`êÔ©Ìš5«Àû, 6› —Ë•gèŸûï¿?ϰ>aafZµjFjê[tù Ñ.þq½`ÁÚ·o/hF£‘ØØXÆŒÃСCÕAT܈$IAór~7™L<ú裬Zµ*ÈbµZIII¡nݺ8 ÿ÷ÿ‡ÓéI«ÕF~uصk÷Üshÿ èuëÖ‹·V«ÑyýZI^ÈÊÊbÇŽbáw¹\ <€úõëç[Îd2qÏ=÷’’"êiÑ¢7nT;ê ¬‡½^_èøeµk×Ηö7YYun(ÍZ’$bbbòL  ( IIILž<™Í›7Ó¬Y3UP)N äRÌåÛo¿eΜ9ôéÓ'í»ï¾£qãÆA§¡CBBr˜Œ¡¥¢è±eË,˜EHHH®°/E »ÝΞ={Äés—ËU £RqqÎlܸ›Íƨ^½:Š¢`6›™1c†°kÔ¨ÁüÁéÓ§iÑ¢ÅMݤwïÞdddäÍÀub„ ôîÝ›äädzè!•‰\×M\÷o„úÄÚ´iý÷ÞËéÓ§iÔ¨‘H%Ë2­Zµâ—_~aëÖ­lݺ•mÛ¶‡,ËAvóÇ\dÏSqeðKûþIÕ±cGÁ$7nÌÎ;E?DFF é¶ `Š‹…>}úˆ‰¨×ëIKK ºÇl6tÍ?>ü“=222ÈÙBEþ¸pá+W®$)éb¸Š÷ߟN:‰9×­[7ªV­ŠÍfãµ×^»Ìý&owÊ÷mª0wî\v'?+…Ÿ‰,]º”¤¤$ÆŽ+®©¸Î $§W‡Á``üøñH’„^¯§}ûöÄÄÄ×ÍŒŒ êÕ«Gß¾}ùî»ïøòË/9pà111<ôÐC¢œ$IÌž=ðâkÞ¼¹ -[¶,ˆI©¸|øóAûÛzÙ²e‹Ê/ùi‹-Ê—–‘‘Á]wÝx½¸¦N*è&“I$ ‹‹‹C¯×3iÒ$ªU«&’‚ùM.þ2z½žèèh¶mÛ¦vR!„µGy„ž={Š\’$Ñ·o_ªT©ç­]»vôíÛ÷ $íHÒÓËÒ¯Ÿ†â, ûMSÑÑÑ‚I\J[Q…gžy†5j°dÉU¹Þ&,Y–…›f`ãwëÖ-_n¾eË– Úï½÷žO?ý4O?ýt®áv»éÑ£‡Ø¼Ý°aC® ‹*®¬ïqîܹ|&ž8q"ß3»ví¡üsÒýÚÅ… òøþÜ#9ßOÝ纴ɦ0߯_þ")VŠ»¼vðàA&NœÈÆ Í$ý÷”*UŠ]»v H*® NSøz9ÛŸð~üøñAf+šZW×wyµ÷•¶,ª`Š…-§BEà‚ïßÿ¹\ ( ­Zµ"99™1cÆwuEÌ@ ã5ÍJW˜={6ÇŽG£‘ £L™[nÊŽ2ȲIÒˆÿ:Ù#PÆÄ¥¢n ê¦ôõ€^oÄh4úúÅ›YS¯Ó#å“—AAÁ 7¨RïU0Ž;²wïÞ+Ò°ü¦,¿)ПYU`Š„„„òöÛÿ‡V«á¯¿öª­yM­†~\_àý?mÙHÅŠ• `>ýôŒF#o¾9EmàëÔŠ:–ï7Sàý›Vr®TQ¸vž5k  fÍšWU_{‰ÏóP¥Ê@®v»'Ÿì‹$©¹8C–²³Óó”Ò*V¬ÈðáÃU/“b¾ÚlÙU¹’§ÓIrr2eÊ”)’öW…_ý•>}ú°dɵ‹‚h422’Õ¼µÿw—ËAZÚyµqnÀþS‘ŸÀä53ýøãL™2¥H6¿%I"66–¨¨(Ž=J¥J•Ô†¾Z¢juQR¡¢¸A£Ñ)Î%Õ ‘1T¬"b *T¨(é¿÷¯¢P,΃üûï¿ÔªU«ÈëU…·Þz ³ÙŒÍfS™ˆŸa«S@… W£î¼þúë¿gþ}¼ªU«²eË–"ûïgï¼ócÆŒQ™‡Ê@T¨Pq50™ Z5Ø·ï¿I’;v,›7oö.l×ÀÝVQz÷îÍ«¯¾ªv¾WeÂr8ȲêÁ£Bŵ„ÙlFQäb)õ* —£III”+Wîš2)ð†ßQq• Äh4°hÑT­z+š%N…Š¢†V«eïÞ?=z<gQ]yóÇ/¿üB\\UªT¹¦Ï‘e™óçÏS»vmöìÙSâ÷B®˜( hµ:wîØÕ¬BE‘ÃHbâiå¿ÐòZ$ÿ«èù½_TTV«õš?K£ÑàñxxôÑGÙ´i<ð€ª\]繑$õ´¬ ×`¹*‡<%I¢[·n¬Y³&èzDDx±h%&Í£G^7Íð–[náÌ™3%~„¡oÉQã¼™ ð (®+Ra½uQ‡êÑ¡¢Ø÷O>ù$èZ58sæt±x¿íÛ·Ó AƒëÚ½{÷¦~ýútîÜ™,⨸‰ÇB§N±`Á{H’þŠëxî¹AHRˆÚ h³R¥ØŽ÷ÜNqH›à/ 6 J…}½ÚÃn·Rä.Ã*¹éagΜ7èÞ½ à¾Â: Ì›·P£á:tˆQ£F^13VQr[çÎ…éêzkò»ví¢L™2%:B¯z=¤¥¥b È¿-qêÔiÊ•+ À™3gò”vRRR‰ŽŽâرh4dÙCÅŠ•P’¤ãÔ©“ȲŒ,ËT¬xGÀ€×ròäÅÄL^z%ÀÃ… IÄÆÆÜ+qúôÊ–-Cþ¡Ú%Î;GéÒñ;vF+êôîYi8~üD@tX… *2§OŸ¦lÙl¶,Ο?HT¨Pñ’åq:„‡‡ãr¹°Ùì”/_ÁWNç{‹­|ù €Ì©S§8uê4§OŸáÌ™Sx<D›–Óh$Ê•+Èœ8q’òå+‘––DFF–rå|ÏSM‚%ÙÙÙÜrË“ÂA£Ñ Óé°Ùl˜Íf•¨ð6ÉСcUÛ„$…ñÇ? Æápb2}uyëóK쇓ÉÂÎàp8Å÷·` z¾øâk$)ÂW§›Í{àÓCŸ]»~Î÷–wrÊ@’¤ *·mÛwdddæb¢9½RΟ¿TNQ¾úê%Ëצ²¯]Í€žŸÞxíÛ9Ë-_¾¼&¡FH½Ùá_ ý‹C×­[— *°xñbÕ„¥Âà /<ðaciß¾ 3gN¥G^,\ø6`C’Béׯ/ÇŸdûö4o~?7~$IX­Ö|]ú¦LGïÞp¹\¸\nÚµ{P0‰éÓ'Ó½{_<·``~ø>àâ­·^£C‡îôï߇–-›Ñ©S{>þxISËOJ;yò4­[·Ä`Ðãv»ùè£Å€›µkWÑ®]k4 §ÓEçÎí‚AÞ¿!›/¿üÿý¯:§ÓE§Nmãñ—ïС ‘‘‘¤§{s2¬Y³Œ6mZ¢×ë|ï¦eíÚ/ÄdKH(GHˆ…víÚ Óéxá…g«V-¢uëB“±X,¬^ý±(—––ŽÞ£dA’$†ΪU«ŠS{öÙg ¥oß¾%«?:NºOéúT²ÎÛY7|k¿^IffÚ%9©Á`àÝw3xð0$ÉvÓLd¯J¬!55•¨¨(ßB˜NDDxM–½ÁídY&&&ÚÇ@²°XÌÞF)))DGGûþO’tttiié¹hþwˆõÐÓ’œœDLL, ˆú ®Jwð×_;IJº ÒrÆÆÆù¼›¼u^|V iiébá¿øÎJŽvÑæ¨/Ö×6‘¤¦¦tFF¦ï´²DRRRÐûÆÄÄÕo³ÙÉÎÎF’$¢£c|ï© *ç¥]|/ï³#nâéi`þüù<õÔ23ÏåJm0èyç% 6溿YµjÕ8w.‘E‹ÒQèÖízÍM‰ÈÈHÒÒҊݦµÅbZsq×DŽ?ÊéÓÇ©Q£J¡Bå f͚Dz¯–2íË!,|o ëÇìQ5¼M6Šo1ô.Tþ Á´<–íÐ\&•èè(_=þÿ/¢ ÚEsŒ—AyÍHË\j€zµ/s¸9G!~ïÅ÷ÊmÊ ®Oñµœ«M$I u‘ó=ÈU¿ÙlÂl6åxÏ‚ËÝÜÌCE^s³ÿþÅfï#², ¨$탨{ 7%œ Зüω¨PqcÂb±‘‘Qì$üœ‡ K )" DBµE_ /zEpÈ\ù)yÅF4u^ùqèÐ!jÖ¬Ylßñ§Ÿ~bðàÁ¼õÖ[*)¬ê–––¢z¿\!Ž?É×_o8õ^°”ãÝ{)¼âø_‡W‘‡¸%i Ù/‡š*Á/ÑÛl^Ç‘ÂÌ•ÿ wÜq¯½öšxç›}],ÑWB’PÈU0à;ï¬EBBrk½ ²,‹N'˱cÿp×]ðx v\Ðj59rŒôô jß#„…EP¥Ê9²EÑžž‚F“Wn … ª²zõGj£á]_¶nÝÊÝwß]¬ßÓ`0ORR±±±ªR”ð{5¥¦¦zq‰‰&99¥H–)ŠâÛ´õž‡HII-TýŠ¢`±X0™Œ—UîRÃãñàr››Ünaa‘DFFŽ¢¸Ø´i#aa!8Ùdfž/P1™Œ|øáJÚµ{0WÝ*þ;)Úétaµ&‰FcÀb±pî\"v»M„lñßëp8T 2£G&55µXKö¡¡¡Ô®]›íÛ·Ó¾}û›¾O®Û&ºÓéB’"¤233 U&22‚ÈÈòyx(]ôz=o¾ù6’IXXYbbJjÓËd22zôËHR$ññ·SªÈ7ËEÁårQ§Nâãc±XŒ¸\v_HmKkAN‡!½8JÓ Ë n·“IGBÂ-Ô®}/.—ó†Û|õxàZ''Ìyh°¸kÔ/¾ø"Ó¦MóEžP5Ë«0‡åv{££ zÅN›6íåàóz½Ç#ÂwøËdgÛ$¨7°Î‚žçÿ®Óé$ —Ë%×uë¾Ånw (™dg[iÒ¤%¼ô’1¦–/ÿˆ„„²(J:.\ mÛ.,^=yýõ·0 ”+W† Fú‹Äyíµ™èõz*UªÀ¨QCHKKÇjÍbôèIX,ÞPÊ·ÝV•!Cžn~F£‘ “˜xŽÉ“Ç`³Ù1›Môíûv{))‰H’D¿~±zõžx¢gŒqüø)œ;wŒ””  š5kÌ÷ßo¢mÛ¯ªÍ"#cˆŽŽ¢L™ìöL\.Çem”«¸˜‰‡#›ðp3+Þζmß«÷ûùçŸÙ³gO7‘‘‘ ™{µªkÅd?üðC&L˜àc¶7Ƽ1bcÇŽeêÔ©ªr98ð)_Œ(o ¤—^Ëĉ£„F‘Û,dâ7þC‡3~üGŽgÚ´Œû‡“‰§1bÄ‹8N8ĬYóxê©'0›M ØO½zu÷IôFæÏ_ÈáÃG™>ýl6¯)(4Ô‚,Û„dàtº0 —ümf³·Û.¤!·Û}Õ!Š"K\\,÷ýT£äj$ƒ÷ߟO:w›÷R…'žx"èÚ'Ÿ|ÂÙ³g¯Ëó,XÀW_}uÃHóŠ¢Ð³gO$IRÈ媚eÊÄ ßu§ÓŹsç ìtEQÐjµ|öÙǤ¤œói*vvìøðš¾V¯^!h©©iïàÁƒ"Ö¦§gðçŸ[$ЂŠ4-GŽÀéÌdÇŽ?xôÑn"LJIÌ/PáïgY–ñxûì ûV­ZÅ”)SnÚ>-ÒMt¯é*]„OKKgñâydeeûÜxÓÅÁ(Y–IMM#**E.]º (i"£]zz¦oÁO :Hxÿý÷ѼùýØlvÊ–½E”ÈÌ´Ò¤É}ØíÞL~ûm3Z­VÔá?¸7nÜKL:>è@ ¿“SSÓ8|x’$•s¹\Ìœ9yófŠ÷,w¥ª®Á`ÀlÉ÷žNÚ³k×>Nž<Ã=÷Ü…ÓédùòO Ì­( ññ·`6[p»Õ¯ÅKÛ¶ýNddíÛ·Åår“·†‚^o(±í¤( ƒ‡ÃqCÿލ¨(²³³q¹\Å:K±` ÞÅ7ø”¹÷‡”'ÍŸšÒ+y¹IMýöÎ;LŠ"ýãŸêÉ3›—°Ë–œs:$™A$(˜¸fñÌΜ9ž Ç©Gæˆ ˆd,’ÓÆÉ3Ýýû£gzg–MÀ»KŸgŸéšª®®ª®7ÔòbÊŠ’ÅrÓá°L8,ëÜzl¨„ëpTXèŽ)£×ýþ€~îQœ[—$IOT¼žÏç×3ûU—ŸžžF:‘ü¥ÿ®~ýtíÚ…p8Œ,¹é¦ÿ«äcª'Ô©S;"i–ÇYP”3sþ„Üu×]Œ7®Z?GÇŽyùå—ÙµkMš41He#//Ÿµk“ŸŸwFrYZðûÝÇT72r×|XÏȳ¯¨qË믿Îk¯½Ví­ý~?‰‰‰5ÒªÒ\Kýúõâ¼ÓÏ$.K–å å87pæA–å3’€!"¹Zí7]UUùàƒ°X,52´‰‘‘ð4cçÎ]üüóÝÚëè— dYÁd2S·n&‡¨Óáʄә€Ýî(±™Íäå9£MT-+ÉÉi:´UU0™¤RUY.W¢®.=Ó¤hX£êαGû¯e­y!Þ RX“&ÙÔ¯_ï(nS ¬¤e˸\&6nüƒ´´ÄJˆ½U¹/|VV6™™µË{R6oÞÌÁƒ 8ö3v¾’hÙ² ^on·Ì¶mK‰‚ Ò°aS>üð£3î}xçwôœ5+V¬à’K.᫯¾2$ò¸‡êÂé玥NI\Fñòci7ÖY0ÚNrrÍ›7A0qøðA, KÕ¡ûQïiU —I——ƒßïÃá°q&":ϪÂétàtBíÚg³~ýzü~oÜûµF<ÓÿñÇ\~ùå5ê™:wîÌüùókÜ\UÚN”ššŠɨj~…ó}ÄâàA-ñQíÚµNúK ðØcO3oÞl6ï¼ó&-[6' –ºé›L&Ú´éIRR¢N¶mÛλï¾Åô# qï½±bÅjTUeøðÁ<ðÀ?Ž)‡fÒkÃj5ÓºuG„2ª*0\j"A¢]»ÖȲ‰Í›×á÷ ‡«Ÿ#¡°t)ô|8ß~ûmy®JwW^¹rB¤àtfÒ¦MOÒÓëêÎrB$ãtfâtfҹ󹤧×!55“)•[o½‡›núNg={ 9YãôóòòõöœÎLúõHZZšNP\ <’:ušéžíe/t3ß|óýúõ&?¿€@ @çÎØ´iK9/»ÀívSXèÆjM Aƒ6LžüuëÖAÁòå«èÞ½{DEQqµƒ¢(4hЄnݺ‘‘‚ËeÂDS83‰ª LR’‹ŒŒ¬j—‰PUÁå:ñM6!!¿ß_çX””D¿~ýj”*«Ò È?ÿùªê£°p7Ÿ~:‹!C®"==ƒ„íØë݇׻éÓßæÚkÿŽÛí!<Ìäɯ2uêîaÉ’ïuG¾””$T5O¯÷ä“p÷ÝÇ$ŸÒâÍØŽ!›$‰bú抟W¤¤$Ó¦M'F¾-ÆüXåÖ[ÿAzzcÒÓsÇ÷U8 f®¨Dœeå:7PcZ‘ywòüóOc³U/Cƒ]»àDüj£ïcãÆ™6mZ4_ŽZ—…B¡ó|•~ûùç_“³ !^¯7bq£qSO<ñ°n–¸ÿ=¾SAA!~¿“ɤލ§¹ÅbåÎ;Ô“FíØñ­Z5×ïçñxøàƒ÷*¬Â:Qäææ±nÝL&/¼ð*_ý=—]v![·þÉäɯñÖ[ÿãÇ?¿Я_ïrˆ™ÄÎÛQÕÛ·ï¤S§4jÔ»=U q‘ÎÒ¡ªa#/ï¹¹;iÒ¤qµŠÀ|Ç Ý»ŸØæ:iÒ$Ý󼦮û³Ï>›¯¾úŠóÏ?ß ¥,…RK è—½aÃ%ú4˜L&¬V ’$qÖYçó¯=ƒ×«y^gg7d×®='¤.(,t#INT5IØlÖ¸(Š¢’’¬ç‘$ UUINN"?¿@?ƒ‘eY7©mÕª9}úœCNN.&“ EQ*l-%I&$I¢Y³&ìß¿Ÿp8Ìò嫸þú/ª*ê¬K8Ìaç¿ÿL·nÉÏ/ iÓªE@J²®4Å$B¿æøûßáD»|ë­·ÖçÁ²ÆñœsÎa̘15&ÑT¥³ë½{÷Âf³ …âòœ[,zöìJ×®èÚµݺu¦^½Œ8N\QB¡K—.硇Çjµ²qãÎ:«']»v¢G®Üzë=¸\N½^bb½{_Œ$¥’žžVnÿ</‹Ï 7ŒFA~~!S¦üÛn£‹•©©)4kÖ™„„,½M‹ÅBÓ¦p8„B¡ˆJLÜ- ¿ßO8Ö=Nõ%PU—Ë…×ë¥]»Ö|òÉl6oÞlä©‘ÐÖÆâÅKøþû/èØ±@‡£ê…îB0lذ¸hÏ7nŒûMeÄ tEQjªô}.»Ý^c¼Ò+M …Bœw^_&N|‰nÝúât:¨W/ƒÏ?ÿ„#Göãõî£U«î$''РAs漇ÇãAUUÆŒ¹Ž‡zœ‹/J‹͘5ë]Ž9ÄÁƒ[iÓ¦ÉÉIȲÂοóÍ7?è/Y8,Ó³gW*4)BZ¶lNß¾½éÛ÷R\.‹ÿLNÎ^}‚C¡0çž{6¹¹ùz›¡Pˆo¾ùˆÎ{ár¹PU•!C2hÐ%¸ÝfÍšJ—.}p¹œ(ŠÂÈ‘Ã8ï¼¾ò$VUå("!Ë2 dáv»yóÍ)Œ=ŠC‡“™Y·Šq§ ’$±}ûNÂáP™ã~àÀAl6ÛO÷ï?€ÓieÚ´Ùœ}v,sœ§rôU!$Ñp±hÓ¦ {öì‰Hìàñ@ãÆÇ¾}û’ŸŸ¢(5:ªª¬Zµ*.uCu&˜•F@ Ý|ñÅ|>kÖü‚ªj›KNÎ$I¢°Ð͆ KõƒeUUp»Ý:G“Ÿ_ÀO<ÌÓOCQrr#I¡P8®žÏçcäÈaºÏ†ÏçãùçG’Lº+4Á`¡C/gäÈ¡‘pî{ãêy<&O~Uæícffk×.Öû‡q»=!ÈÎnÈÚµ‹bÊBq‘ˆKC8&-­5§4§±‘#›““ã¥E‹6dffê9à« ’8|8§\^¿~êÔ©]¥!O5¬V99¹È²àª«Fê„£$$'§PhHIk8¶ßÑýÞb÷߇>} #C#,åÑ‚èêp88räuêÔ©Ùrgd,§OŸÎøñãyòÉ' $:0Ñ,‚±Iâ7fo© S *,·^lƶhhöc}µÜaÝɯx½hØöâeŠ¢”ú e••…&M#HRY;…LR’ää,ª¢ñF0X@ƒµ+tNc$V –æÔç5æ(¡„MÚ‹¢„«Í“I,YýûCݺó Bðõ×_sÁÔxâK4GE»ví ¢9ûI†µÐñN€ÙtŒ„ººs`ÆœËXUÇñ²X ¢YhUUeÿþýg ñˆM-ëhÀ1¹ Ô¢E‰•™?ÿ'üþB ß*&“)âH[}úìpÀóσµ‚ÉEᥗ^bÆ 5Öúª4"òè£òÊ+¯ðÐCy$0jÔuȲa!dÀÀÉBÛ¶‘åê¡÷óx =î¿jU ¤¢(˜L&=m홦ÅèÝ»7ï½÷‡¦V­ZÕòN@…%°ÙTCò0`à¤ȯ¢j[&©*|ñtêT$‰”ý{I’jŒ5ÒñÀjµâõz ‡ÃÕöùOè Ä8÷0`À€¶@¬Þ_Á…ÂcAïÞÑpAñ{Ç¢E‹:tè½—ôéÓ‡¯¿þšÑ£GŸiˆ ‰áÈÍ/äÿ€ àÓOþÝÕW_Í_ýuFJQ)lìØ±!=ztµô‘ŒånÀ€ÊÄ¥—j> “'ÃÛoÃgŸiׯ½öî-r–Œfb\-ˆHµjiê«(–-Ó¾ßudgç²sç_˜ÍYq‡ëÅÚÏ&AŸŸ£<ÓµšD@„9’ÃÝw?„¢·Ý€J†$Ùxë­WÂTíún6CffaøåX¿ìvPÕl¦Ný„`P%7W°p!lßwß­I.~ÿ‰g7¬nhÚ´)Í›7gÁ‚œ{î¹Õ†)?a+,U !I~ãm7` òeJ °Y½8lp»ÁíV¹ùfÁ[o©(Š`áBAß¾°x1<3fÀßþãÆÁÌ™±{Ì™!™tëÖ%K–ЧOŸêÃäTâ21þŒ?ã¯RÿjÒæ×^+سg‚¤$?^ À¨( %¦JL,’>‚AM*ÑrÆk×jj&UU¹ä’KxöÙg#Ï©œiÄ€Ê[–•o# ‹ŸÓˆ´4•ÚµaúôïØ½æÏ×¾ÇÂIŸœ ­Zij°ß~+’bê××NQJˆš3>Q•UAAf³¹Ú˜ôä÷²e+ª­Ó–e™õë7UêòðûüñÇŸåpÖ&~úég®¿þf„¨¼Å;þbðà«Âf,ÁãÄúõë™?>óçÏgùòåø|¾£~£(ÚFiäÅ_Ì),ÔvþPH«cµjç#ÑìÖBI.—>Ô®ååE)ŽUk­\OTª3qéÞ½;;wî4HU†¢¨@"óµ|qD6ºø²"Ñ2©ÂeE™åœ@"½z]$+Kˆ™ŽäRÊ¢í/KŽü·ëeå?»R¬ÿÉ(J4+b"&“›nú‡>>QqºìzÑ{[K,óx<<þøóúøѵùH ÿ¼÷ÞLTÕi¯ôûÅŽWl›Åë !ôt©Ž›6mâ—_~aÑ¢E,X° DÒ´) Xrý?þøƒ¶mÛêñ¯|>ͤ÷µ×à“O´8Zá°¶ñ;èyRTUSk ¡I$Ï?;v•¿òŠöÿüó‹ˆÏ=÷Ä¡ê¤öRU•%K–зoߘµl*7I’”BïÞç””HRRbD„4!„™G}ǃÙlŽ)³EB ¤Ò¾}»bõ\zYË–ÍãÊ„HA·Þz ‰‰”ó IDAT ƒA’““"eV„p0pàeìÞ½;&ït B8<ør=Z©$¥Ð®]„p"„‹‘#¯"))‘Ë/¿ŒçŸN¯WÖ¢Óž=‡Ã¡÷S™S‘¤dzöìAbb]–.]NRR"6› IJÕ¤DœNg¤^ YY™‘¬Y3±Z­$%%FÊRiÚ´1µãý÷?&))‘´´T½ÍØùèС-þDNSBè÷«_?Ko³~ý,<¨—7i’$¥¢( B$ë×…deÕ3ÔW'ø¾\yå•<öØc<úè£Ü{、§§õ»ÌLí¼øP«ªÊ¾}ûHJJФƒ†ü|¸ür;~ú©He6ÃSOÁ¦M%÷ÅnÏr8gŽF ÒÒà™g 'Þx#²¹IÕOí .ùÄO0mÚ´*ouF!ÌÜyç-Lšô* ª*ÉÉY@Bê‡)(È‹Äêq I©\}õP~øan\=!,HR*—_~ ¿þ:‚‚<½^B‚ pðÖ[oRXè&==üüTUFUƒ¨ªÏ?ÿ!R¸òÊk‹E&µqèБ˜ÍO°oß~¢‡¬7n¡ à=t7Š¢èõ„H)ãÙ“©U+ŸÏ§?C8&;»!K—.¡°p/ýúõ¦  @À‹ªæE^¾|Âá^Ïëõ’‘QPÙ³gBV¬XC0¤  F2Û¶meûöµ\ýÕ’“sXoSë“…üãVfΜJ­Zé€FP¢/Sô~ýõ;½{ŸÀÁƒ‡1â†HyëÖ-æÂ  I©!é×UUÅbI'--Õ '°©•DTJÿ}üï„\wÝuŒ?UUiÔ>þXÛÌ£ioeY;H?tèè¶ÊÚC£ÄDM½kDèÝwaÁˆ¤m?Jí{ŸÜ\íþU…¸!¨S§GŽ©òŒÏLQåâ‹ÏãƒæòÅßZôüü| ÜÜœNGDâ§Ÿ~FQò$ÇãÅé,þìî!ÙÍÍ7ßeP‚Ó ¹!xñŹí¶ÛŽ"F±„aÏ(,›M3ç5J»¾ukÙÉ©,–’¯[­!X±B#&É‘×xéR6L‹üÙg0iLªIPK—BÆE>,Q©åT:;ªªÊE]ÄSO=Å­·ÞZ¥#~˜ÏÌ…-sñÅC©[·¹¹¹8zõú¿üòk©\hÌíÛ·%++C_P ~Ù(+ލÊKÛ´c9* Uõ2qâkDóÃW&ÅË#<É÷ßÏE’DDm`aÈ|üñ'€§„M !B |)÷Üs;¡PEQ©[·6S§N‹i[»Ç{Uõ—2–‰¨jBØ¹à‚ ˜5k*€so…ž=»áv»u läÈ¡Å8Ðò_,#PÂéã¤o¼ñF†ÎùçŸ_jÔÝ@^]ûœœ\E’´óŽèšLå„€uë4ÂP,–¢ü$ùùÁHO×ÞÝLJví4éç²Ë W/¸ä>\;ŸÙµ  ‚?ÿ„¹sµó•XÂíKT’*‰è¯Ä7gÎ:wî̆ ªl¤^ó™¹°Í<øà] :ˆ~ýÎ,ÖT–.½€´´²²Z£ª>Ň$¡O^8æì³{ФIv± #„@QTý0WS§DÍGóc~«FtùR‰öÞÚo‚€3®MIо€ ±–\Ñs“ é,¥dš6m̶mkQ”p䚃#FÇ-‡è}„°Ð°a}þúk7‹ÿÆÜ¹£(^$)‹ÅL—.ʸ[(¦_B—T‚Á çœÓeË~dÖ¯ßHFFs}Œb_ž=û£(yq¶¢/ 6f $&¦rÇ7;úiÀ²eË˜ä‚ úsðà!½MUUuÕªzعów7ÎÖ78­,™þýÏÂÅúéá—_–гg7ùù>¼ƒîÝÏbÙ²•ôèÑôíÛ—¾}Ï‚ôéÓ Ë@òÙ¶m;íÚµÆy“ü~?û÷Ðû™ÀóÏ?NË–í1™Lüõ×nd9‡ƒѲesmLB¡0×^;"ÒoAß¾¥ß;;» C† ¤mÛ®8–/_(tëÖƒŨù¢ýÌ% Ѹq#’““HHpñË/K…úÄÝËb±Ð¡CÀƒ¢(dg7$%%·Ûƒªzyæ™gã¤'/¼ð&L(“è›L°|yÑæ§ªš5WÔò*†ºuµƒöŽaÍ"Œœ–°ª4ÂP¹ çÑŸáì³aáÂ"B`µjÒSb¢Ö×Õ«!#V­‚¬,íYÝnÍ4ÙdÒžuï^زE#’þ©Çôì©™%[­‚öíÁïï΢E{èÚ5‹Å‹µ¶UÖ®…³Î‚ýû5`¯^†rÊDkUÍcæÌÙÀ ˜‘$ÁαiÓ¦ª_!y|ñÅç1œ@´¨jß}÷m\™ªæé/PÔœtûö?õßkmðÝwß¡ªîb:b­þÒ¥¿ÆÝkÙ²ßP”\&Mš„v¦´´˜_~ù%ªZX*·}†ßÿ¢0ñýTU…=z°yó&½Ÿ&“ UÍ‹\‹ŽI>Ó¦MGU5ÃW_}Uê½U5Ä Aƒ4h êç$Ë—/‹»wñ~jc¥Æ´£I)?üðCܽRSSyâ‰'QUÇŽÛcúéæÑG-Cf rÕ¤šºeݺuÜpà ǴI+ ¯Þš6 .¸ )Iû‹Ö‰ª‘¶mÓ,²î½÷T1¡Z?b—SjjQ¢ç-uêhj²çžÓÇôéMâY»n¾† àûï5BrË-Ú9Ìœ9*^ï¿éÕënvì˜Ã€ðùç½â í¹ß}WSžŽhðglFBm#ñ•XVt(í.¥ž·Œ6½%ªSb–žÞn´Lûï)qs‹–ÅÃÙp}%þ¶¼MR+w—ÚOí³\J?‹‰7¦né÷Ö®‡ˆžU¼Niý,^Ob Dñ~ âqŠ IõêÕcïÞ½‘Ͷâ=ž£¯y½št‘—§ˆ¿ýMS_Åt˲¶ñF-­¢^í§æyË&4±¦ÇK‘¤d6k.—Ög›­èŒÇሞÛj×nÈ7NÅfIR1›….½I’&ùœ.7§J" 5çÅTÕo¿=í âT©<ŒÍ@‰[Sµ2ˆŠÃ‡“’’RUúfë÷ÇŸ¸\EŸUU;ìÎÏ×ÂѶéîØ¡© µMÕçƒ+¯ÔTG ODÛ0„ ;wj'K…f2™iÐ ‘ÌÌDŽÂ*5çæÊX4€¯†m‚Sv§‚‚ „øÐ8lY–1™Ì(Š| ‹Ï„áCW¥¶Y}ËŸ; Ç[­¤úùóç3eʔ㲊ҙØ*gŸ]D¬qàGŽ@ß¾0e Üv|ó¦ºÿ~-ÅîìÙZ8”ý RR4"µì …4B=ôNH8vŸ“-ñøý0zôC̘¡õ5?_­{n¥Çg¨Ž»víaÇŽ¿¨S§v©¿‘å0v»“Ö­;²aÃ*š4iU®ƒ‘&:[Y³fY…6+§‡‹&MZ²iÓÂá0¦RXb-OvVkõˆß¥ª*Û·oçƒ>`ÆŒ‘èÒ ¶Yü=ÐÔYQüíošJHŒ O>©}¾áøè#íœaÎí ~Þ< ¡…NéÒE“Rn¼Q³¾RU¸D½âíö¢öµr“I“4,–Ò¥›­lß•ãϧòøãòÎ;>.»ì>þøýš!€ˆè«)®“­¨Ž¶¬zÇÛfô`=%%¹Ä{ɲLÇŽ=rY¸p!.—‹ŒŒº¸Ý‡Êä@ìv¯¿>™‹.:/âh *¬»„„d’“téÒ‹%™ V"I¦×OíÚµuK¹ªEQ¸ð ٺuë1y”E<¢Ѧ7†_ÔÕ£%Q“Û`P+‹Z:%%iÖO­[kŸ_yE;?YµJ#,ë×Ã’%šEÔãk›¿ªj„¤ysís÷îZØ•è9‹É¤Ý#qÕ …´{‡BEý ´k²¬}¶Zµ>ƒÚç`°(€d´Ïªªý6˜2ԮɲÀãÑLîgÏ~Ÿ‚M UÂaqÚ´ æSùò˜L&„„ÃáJ!8Z˜ sœïEEÕ:Û¶ýÉÊ•k±X,Œ9ŒÂÂÂrûd6›Y¿~#6lÆn·1lظݚå”ÅbaõêulÙòN§“+¯ˆÛí9æçTUEQIMMÇn·‘žž†×{“ÉŒR1“²ۮ.!¡Ï4D­‡‚Á<Ú·ïÈÞ½{‡UòòŽèÁ«V®\Éí·ßÎÖ­[+Íá-:¥ …Ù¬™°aŠ%<¡PÑ}Âᢹ‰žÃääh›x½zš‰m^žæ„8ožFœN8%$†¯¾ÒÌvͼ¶[7xë-­]³¹ˆP¡Ynõî­´fÍ4³_‡C#X›7kÖ\hõÇÓÔqC†€Í&å9´l9œ¬,­Þé€tê^Áo¿­àÇVÚ "I_~ùk×®?&¢ãv»™0áMüþ99¹Œ÷4II‰å!Ü»w?ÿùÏÿðù|ìÝ»Ÿ—_~—Ëßw0}úûx½>vîü‹7Þx[»QQ„Ã!’“Ó©W¯õêÕ#1ÑI à«V¹° Ë;!áó¹#Ž«™Ô¯_§3p8T-ú/I[¶laæÌ™,Y²¤RÔV¥¡¸´!„t1VúˆžkT6±‹¬»"+(,Ôó%I;¸Ølš¹qÔ¤6'G“jÒÒ4Bóÿ=zhe=zÀСðå—Zù}÷Á{ïie'ÂÓOkí}ô‘V¯iSMõÖ¿¿fÖù"7â—_¾¡°Ð×ë##£…~ݹsgP»vm6lÂ_3vì}¬ZµŽæÍ›òá‡ï‘žžFZZ¶®Z²Z­tïÞ…?ž¦[®$''Ѳe7¶mÛŽªæGâ^ |>v»M' V«…P¨¼sßÀf³ ÉdBެ†@ ˆÕjÑ ˆ$IzYÙºc™&MZ‘Ï—[ÌçÂÀ™FH$IŸŸW g¥ŸÏËoÊBrr2³gÏ®”3ò˜/m«Är2Ѩ‘–z÷Ô5jçMštâÆ;±víZ¶lS}UXÉÉ)œ}öx½^ØÇûøí·ùúë(((àСm¼ýök¼ôÒSìÛ·™Ÿþš‚ͦÙårøõzS§¾ÁøñÏáñxX»v1­ZuåÕWŸgïÞÍŒÿO>ù^¯—ÂÂ=Œÿ 3gNeïÞM|üñ4Üî"O$¿?Àر7ñÐCw—˜§ª¨1rrsäÈV¯^‡Ãa7ˆÇˆè&œÀ”)“±ÙŽßŒGˉ"¸ùæ›ùôÓOË$o¼ñ÷Þ{oL̶cëóé`v|°ìr‡C‹Gu*7ôÓµ½D%’Y³f–ûWš’ŸŸÇâÅßát:u ¤aÃ,–-[JNÎ^òó ðz}ø|~òó ô…§(*v»«ÕFjjJd2|Üyç-!(((äüóû‘݈üü|Ú¶mM“&Ù(ŠJ^^>~¿¯×«£ØÅ=ú„ÐÚ¬Š³‚üü#>lÅd2ñÍ7óèÒ¥#µj¥Å©ã Ôlâa³Ùؾ}{÷î§OŸs* —­ 8묳˜6m³gϦvíÚœu¨ˆYw“'O¦N:ôêÕ‹«¯¾:n*OªˆÄœÜw_Ù*#Ð2#>ùd‘Ŕͦ™è ¡|G%š¤¤"/îädíwQo‹Eû³Zµïv{Qˆ’„„xÇA›­¨ÌåŠoßéÔî›fÞlÖ¾'$õ+¦%1±Hm—œ\äÍn2y³›ÍEɲÞ|ó© Ï]•$ Š¢•UÜÜzXï?ÿÜÎðá#øïߌä‚(Z¼², †ÈȨƒ$¥¢ªA|¾„€… óå—ßÅ´­¢ªŠ~†QÚá´,ËȲŒ5b„-„ °Ð¢È$$DSê8ýl  a·Çs|7&!”VOS{õïšC˜)²€¬ƒ!}E)ÕÆ¿$qTÃa§aÃúäääòᇟrÓM× † kª Y–±Ùl¼ùæ.¸ ?ii©•’DhÆ 4kÖ »ÝNaaÉÞË M›6´k׎?þøã(Ó¥KÖ­[WbݨixÕ`pr"š0l;B4Ž|ž}X½z¯½6ØÎ5×ܬ–Ѷí9@ àM¬Ö&ÀÃÀEÑøÈåý÷o6rÿý“¹ÿþÀ&úõ»-Üϧ‘¼Èk¯= üÁÀ£ýÀ<6ìôþ‰M€W€öÑø‰¥K×2yòÝÀŸŒóð°š.]À;¸\Í€±ÀP„è Ìd„¸X˸q37î}`C‡åƒ>¨~HB‚‹+®ÅÕWœh €Î=÷lÝĶaÃú¬_¿‘iÓf“—W@bbwÜq#ƒ]Â[oM$Ö6Ë7Þx›Ë.»PߌµÍ¾ä…ÚºuKÖ¬ù½{÷±wï~ÚµkÍ¥—^ˆªª$%%Ò±ã9ìÚµU- 77¯×ǯ¿þÀ7ÞÉYgõ  qàÀAž~ú1 4SÞ””d6l‰äªÕ …ÂÌ;‹;ï|€Î;àóù1™L\vÙ…x<^¦O›{îy„víÚàñxHOO£ÿsõdH•F´Ka èÃÂ…‹©[·²¬Ð¾}kL¦¢Àf³¥Ì—×l¶»sÕ”7$f³™Í›·âõz ‡e.¸ ?¡PH7œ8™™è*¡*ŠÂÊ•+K-oÞ¼9=zô¨Ð9_y0™LÌŸ?Ÿ=z`³«ã¤†WE¾ß\ÅÖ­[q:Ç’•5"rýsà `4àÚW-#„à:à2à7`0˜i8ùù7ðÇ»éÖ­ª:ˆ¬á‘{/.F. 0èä7F¾| Œà›oúqÙeƒ ‡‡FÊ‘ßÔW"í]¬–GúõN¤_#€ûÐ`°ó)Ï`Xi¤°ÐÍ×_Ä»ïÎÀ‘ ëÔ©ÍàÁ—á‰DHÓÂÃŽ;ÉÌÌ`àÀ‹(((dúô)L›6—Ë…¢È,Zô[·þ¢È$&&0~ü:Q*¾È/½ôìv;âœsþÆ€çêWWO[ëv©Í¸÷ÞÛY¹rm„ˆÝ¤·ÛÃŒS‚qõêÕË`Ì˜ëØ°a3©©)q~ gsÍ5#زåjÕJ?&?E‘rö“e™ZµÒQ™ýû`2 Ö®ý®]; ™=ûC]Ò*ù¥”üÈrØp$¬bøí·$';Ø·o¨ª‚ßï?j“?ߦâ(ˆè?L&Á ´W¯^Œ7Ž‹.º("e{p:X,òŠ…r-OêÍÏÏgÆŒ•6&W\qÓ§O×÷ŽÅäÉ“ÉÎÎæÂØ˜ï'€mÛ¶1qâD^yå•J{æ60}ú'•Ö^ àòË/¯žDßï窫®,¦ òĘ*éܹ;wÐÕDBB¡ÐQõZ¶lŽ¢¨X,ºví„,ËGmÆBhæ¹çœÓS¿%Q1û¬³ºëjªèuY–iÜ8[ÏËQ܉0 Ñ»÷ÙGÕ ‡Ã´jÕ‚V­ZDMQøõP(D»v­i×®µN„*BQØív4hP©Ïܺuëj¿F({§*f³Å8³0P‚b=nŽ2–”ÆÜÄ^?ÄCUÕJU ©ªÊˆ#âˆee¸x ÒÚB0gΜSj1e!»víeÞ¼xc­¾ ÓÞª3‡ÓArÔÁ´"’UUÕÏ2jú{pª´U¹¯1pÌ4i’Mýú™¥†D0›ÍØíš5kÃúõ«…‚ÆÀU(ŠL×®½P”ŠD2ð³k×6ZµêÌúõËe¹ ½ºJÆMùðëäs§¥¥“_ qRÔ‘äL& ’$a6›Nª#ªª¸\Ný ¿¢ul6‹%’ÅsTÜ-­L©p»š3¥‚,Ç[ÜȲŒÝîÀn·Ñ°aB!7Ÿ~ú©©©1¾)N7dY& PXx°Ìù¶ÛmL˜0‘Q£®Æí>DVV&f³“½{wáv» …‚q~CQsnµ fS…7V{õKMCrrò)W‹UI-[þ`Ê”ÿƒ#Þ±´´t®½öf,–ŠŸ=8&Mú/:õâüó‘––©¿à.—“W_ý7;÷æ’K†‘––q\/¿¢ÈƒAš7oKFF22êâó壪`±X‘$ã…­ªÜŸn¿ä?ØívýåV…`ÐMFFêÕ«K³fm'dº{²]ÏQukt“ŠísUîÍ’|•RÇ;–©->wg),t³}ûΓFEÍf3ãÇ?ÍÌ­ð†¬ª*?ÿ¼˜ýû°xñwL™ò:Ò7…o¾™G0ä—_¾á•Wžcøð«Ù)JQ22жm„`±˜‘å°ÁåÕ`¢‡°Z­HRöí;’–V«ÊHš¯fÿÑG•SK’¤H0ÓîH’T%¥¦Òˆáénãxï+I‹¥Ì³S!÷ÝwßIuN•*ó¡¬V ?ü0Ÿ ±`Á"~ûmv» “Éį¿.Ãçóñã Y°`Ë—¯ÒíÜM&“^ï§Ÿ~Æét íåx6nÜÂ’%¿°T"IÓ¦½O:µiÒ$»Âõ, £FÝÈK/=¢(dfÖåÜsÏæã?C’$î¸ã~žxb<ªªÒ¸q#Z·nÉ·ßΫ ZÌŽÍf¥sçî$&Z‘åp Wkš/¹D}‰ü¤§'ѽ{¯*áü©…×q ª*&L(1$Š‚V­Z ™2eоaUUÌ;—|0ÆiØÍž={ôò½{÷òý÷ßóã?ê×,XÀ÷ßÏÎ;ðz½\rÉ%¸ÝîÓ6/÷Þ{o¹kdÁ‚¸\.]ê=óRig .—“[o½—ììºX †Ø·o?7Üp—\2Œo¼žúõëéy;<İaWpÓMwF$jñ®&L˜È¹ç¥s:ÜrËݬ[·>&,ûñÇÃ<ÂsÏý똟1öéA C¡°î ît:…|1g2KE,m²²²iܸ.@A$S™A4ÎTbb2™øî»oHKK¬}Šr¸6›­Ôu™’’B0ÄëõF˜¿ª©ò‘$‰+®¸"Ή¯{÷îÜzë­Üyç_!Ÿ~:“ÌÌÌȃÌ}÷eÆúoívÿú×DV®\ÃÃß““ãØápØ©_¿5ÉÉÉìÞ½—-:áõúyõÕç0  g<üðäååsÏ=w‘e™ žæÆsà ·’ÀìÙÿ%++“p8ÌË/?Í=÷<Ê’%¿‘’’ÌÌ™SÉ̬s”GyÒH4†Q»v­9|ø.—‹~˜Ïu×]…Ùl #U¢Ì3))ÒAkakl¼ÿþÇ´o߆p8L‡mõ€¡';œû±¨}¾ýö[XÔ«W/. o´¯ï¾ûî)WŸ+ãøÌ3Ï „`ôèѺäüóÏ' 1|øp|>­Zµ¢Aƒ´hÑ‚þýû³páB:uê„ÛífàÀtîÜ€¥K—Ò£G2#bŸÌg¹ë®»Ž’d'Mšt”6dÈ! 2DW‘VY"Ë2=zteÓ¦eÅ‹¦sÌËû‹œœ}qµmÛš‰_ÆçóÓ»÷Ùqõ¢‡éápXO 5oÞg!âÚ8ø|~6o^Q"·øÜÜŠ|»ÝŽ,ËtîÜE‹–²lÙ*úõëeì×UŒx^}õÍr*£²ß}÷#éé‰tìØUUõÃΪnªªŠ1P'a9m   †°[S#/–…ÅbÅë?‚¢„’ãÏ!ðz½:tİJŠÙl!++³\âaµ$" #ÝAåŒ:8vróö”©ÉPU»- Tƒaª´}Æ*Qè>T!â}ÒH”’Y¬&Ì– 1+' ‰y?Ì£Q£,Òk¥–K¼7nDrr’1l' +³fͤ~ýzå2B—ŠÃtâ°óü³/sç]£ ÊÞ?$aÁî2ö˜Ê’>Þú÷;\{ÝB¡ðé& ñ3p¢â¼0†ñ´ðÂÆZ?mëÝ÷SϪŠÊ9»6NÀ 0`À€A@ 0`ÀÀ©ƒ¹ªtD³,²²qãï(ЦRe™:¡ªÁ¶ðx¼„ÃaãÌà˜çÄÂÚµk0™L€fÂݪU›rçDUUÖ­Û€Éd¢eËf˜Íæ»wïÁb±Ð²eË=^Uæ­ÂÂG}Èüù¿=ÇTU•´´TžzêiÀw\í*Š‚$%q÷Ýÿàí·ÿ])éL€^xáyvîÜg%sÎ9ãê«GeÀ½ñÆdæÌù„M›–‘™™QCÇÈθqã8r$W#I’¸îº«èÖ­ eŸ¯V¯^Ç{ïÍâÿ{»R6!L|úéôés))ÉÇôþÍžý>ƒ]ŠÃa?j›øöÛy,[¶’É“'÷»X †¸øâa¬_¿ðfü9F¾†nÝ:—YwË–?˜9ó^{mRÄ(£æfx­Bl¡• ÞdÁ‚/±X‘k&V¯^#„ µ—W.,I©dee²víb,3 4g×®=Èr&S*ªš¯·¡qaÉ(J> u?EÉl©ú½£ýR”ÜèTi㡇¼žÈ5™?þø#ã•;â(J’$!„`Ê”ÿRPP@ÉŸ±››sbÆ2°DÊ $QeÇèÙgÿqöÔÆháÂ…|ýõ÷’Œ,çb2%& Œªºõ57`Àå py kYc¾‡PUOd³O‚€½„²D>ýôKz÷>+2ÆATÕiÛ$Än“1e.¦OŸÃðáWDêPU_¤M•1cÆ2f që<ª5gL›~TÕ1uDæ>ºÍøPÕ@µ`Þ„€ÄÄX7‡ÃÉd*ó¹zôèFýyíµIG1 ÚœIÕrLJBÚñTÌf3¡PU E¸Û:ud$É…ÍfÃd2a2™"Žt¦rA ÖgÏž¿HKK%11‘]»ö˜˜ˆÉ”FݺuÂÇMÖªU IJA’RBÄÝO’HR*N§!ô O+K­‘FQ GþTš5k ¨Á¸1ÊÌ̈lüE›^T‹üü‚¸z-Z4G’\HR*‹IJeÈ+1™L´oßIrVé1²XÌqc$ËrdÜ’HJJÄdJ¥W¯^˜L&úõëÚÆ¿cÇNÝ!Tó-YµjuÜ 2!¬a£^½z<óÌ3‘u'1jÔÈH™!ï¾;“Úµ›"I·Ür‹~¿ êm !;ö„ÐÞ9!_~ù-K-„<úè£aAÁܹŸêýŒ]çBÞyçݸ6Ÿ{îy„8pàC‡å’K.ÖË^}õµjµQʲŒªzp»=øý^‚Á þÜ3f̈{î'žx!¤Èó•,uîÝ»#®â‚ .Ðë½ñÆÄj­ ©’,³+W®áwfðÙg_É4oÞš@À‡,Ë‘‰U#œXÙbºÕjLáDm#²Ù¬‘ÿñøë¯]ìÜùWÌ5EÉEUÕ¸û¥¤Ô«wf#‡£nÜmÛ¶† /¼°•Y/%¥a\½Ÿ~ú‚k¯½ð iÜù?ÿù ²,óá‡ÿãïÿ¿ª%,Wìß¿!³fME–eyäž|òI@ªª4oÞ´X=çœsaÜ]sͦNý/ûö C‡¶¨ªŠ¢(ôíÛ›Ù³ßGUèªÊ˜1×qäÈvEaÒ¤É:gܧO?½MUU©_?‹yó~Äb1£ª*ƒ]Š,ç ª*Ï<ó,ªBUU¬Ç¿‹Ennÿû߬¸67mÚÌ–-[‘$‰>úŒ‰_ÖË~þy1»ví®6³·|ù*Î?0^Å%— cúô9˜L& ÝLšô߸ç>tè0¿ÿ¾¡ÌöL&‰9s>aÊ”×õzóæÍgÏž}† ëdp¾))É 4U½š””dB¡,–(§–ˆÃá(›KN¢OŸÞºƒ˜$™"¢i~úéd9ÌßÿÞ\—†$)•=ºêfB²³t£Däë’ERRâ1×+(pGBâ€×›K¿~½éØñ,T5ºuëp÷Ý·Õ1˜ 77—k®NƒÍ€|Ú·oKãÆ"\ª („ÃᣤqŸÏGÿþçêe[¶lã_ÿz€F0pàUµ—D8Æf³F8Y@€¼¼<ý $Êánß¾•¡C¯Ãår‚7óÙg³#÷  ÉÉÉ%-¸zÒUVñŒžˆ0cÀXt‰IQT† L“&m"ý´E¤Ëê£æ=ûìžüðÃüˆºÐÌÃß‘.‹-¥oßÞ(ŠŒ?ÿ¼˜Ûo¿±ÌöE媫®¤Q£‘µ_ýƤZUUèÔ©=:õÂb}Bm²dÉ÷„ÃÚät:¨]»iÜKnµZe)FW/ѨQCvìX‹ÏçÔsÒ´iÇbýT93ÏâOî²ÑæJS«¤¤$“’’Œª*ÕVÔ×¼}5Ž3#£PG·Þ* µk§óãßâõÀF%gEQµBq»45¯Šª*\y嵬\ù ^¯³ÙÄsÏý‹p8TJ=3Ú¡þñyÜ QôÜÕuÞ´s­šÑ€‰P(JH¡W¯³˜?ÿ ¼Þ"ƒ‚ò¬³¢{[MŠ¥V…ˆJ«VÍYµj-V«Eßì;wn@›6-Y±b &“F­;:µ§<Ë•`0„ÕêÀj•uõ@t!´oß–¥K±`Á"L&Íš5¡C‡¶´hÑ”µk× ILLàÒK‡G87èØ±k×þ†$ ~ø‰L(T:ujφ Kñx¼¸Ýf̘Ãþó¿HÙox<]iÚ´1  ª*+W.åСì^½–ƒ3騱# Ð¡C[6nü ·ÛQÉì§Q£:W®qÝâ(n·Šn3´iÓ*nvïÞC½z‘y‰}!@€-[6àñxYµj%.—‹-š£35eýú5ú•ššB³fM#)TŒ³U"D@¡qãl6nÜÂáÃ9|üñç\|ñyôêuµk×bݺßñûý9’Ãã?Ïô×ë5o®­ù¤¤D¦NÆ-·üöíÛ››Ç[Q…M›–‘””H½z™˜L&’““Y³fÁ`³ÙŒÕjÅf³EÔ;ᣃê2O›·ðQE3Ì‘¨];5k~' ¢ª* dátj–†‡çpäÈV6o^NJJ2uëÖA’ï¿ÿ _ümÚ´Äb±àt:cÎÐ ræãí·ßeüøµÄçó±té %—÷ޛţާ‡6÷ûý,^¼´ë§?|O1"â‰'||ùå·<òÈ=Lš¤é–yä^¾þú{%—ï¿ÿ‰{kłÇãeÛ¶müû߯æÏÿ…»îº !à“Of`±Ôª‘äCQòX±b5wÞy N§C'êÿùÏÿP”\V­ZËwތөÖ¤¤DžþT5€÷Þ›Iÿþ}øùç%$%%Ò±c7%Ÿ5kÖ0vìm:A®S§vÄÚ+‹ÅÂm·‰¨ ªÃFãfåÊÅŒ{þçÆëjÚöíÛЬYK ÌcÝQiDþ¬³zàŠô'Äã?Ç‹/>É‘#9œ{î9ôîÝ0}úÛ<ûìl6ééilذ—+Z/À«¯¾Å“O>‚ÛíaøðÁ´oß±wï>¦NƳώgêÔi\|ñyÔ«—Ebb"O?ý“&ý‹Å‚,ËŒsõë7Àã)äúëGRdê-síµÃ«–ÙlâÎ;oÖÕw 0pàEdeeât:x饧˜8qJD{¡pÉ%ç“™™ ¨üõ×.¦OŸÃ³ÏŽgÊ”÷<ø2êÖ­‹¢(Œ} f³™>úŒp8Ì}÷¥V­ÚTW_qùg«CÆ\„ç Ÿ/î_ŧ_ͤ°°lóXI’˜7oÝ»w!!!‘Ä„ôH0Eq‚/cTt޽¦©2Ê*+O„WU¹˜©®U G8Á£?—|?Íæ &MóçŸ;â¸Éʱ÷ü8ï6ªGzz*6["~A‰Ï˜——OZZêI!OlNLqÒLì<”]&û~²aaÖ¬Y\|ñùeSTU›%g‚(Auy¼Ïslc¤­·¢5­Í¤«GŠ®™"ïcimª1%͵¢‡P×ÚeÒÊ/Óî'ëgqGE/<÷ cÿqC™ÁUUÁi¯‹Ýyâ{̱A*aœÕ˜ÏÇ6&û÷dìØûùðÃb$å´¨g'¿5Q×®p0E«ÕÊ+¯ü›ÿ}ùÏ~~7ÿ™ò.ß>²¶jhƒ(—¨º(«¬ìö”£TñzÙ’?—t?m²óùóÏ!°Z­Ö_®OJuʼnÍÉñ–UÇóŽã}žã#¥Ø¨%Ì‹R¡6Ëšë¢zj}Q¡ŸÕË.kœ}L$IDŒEäRÆÙPaÕxh΃¹Å8Õ|ó݀e¢nݺ¼ûî{qޤÕ9ÁV’¨Éá 0p2 Et¨IÌf¥m8ŒÀ¾•@šŒü§G®<¦q4¤ÍÊ÷“7OªÖ­ÛÀ¢E‹L&cDO˜IQiÚ¬|‡E»ÝÆüù?린NtWŒ²ÚL¼=i²bä讌µž‘Q»Äp7GͤðÚ«S#‘% œ(ê×Ϩ”4äæ›E “ݤM[\Y“ücNãFF$˜Z*·¥ª*v»~ýÎ5¸áJD(*s<…º3òšAÆ`U"‚Á`9ã.áñâÿn¼Šÿoïþq†¡8ŽÿŒíXéÄ1¸#RGÀÌ:!uä@]˜9RvF†ª%y1CJ"ÄÿÒ–"¾Ÿ9“-ùç'Åïý™‡${ŸÝ¹ïö+Ò4µÊòP£ó56^®v¥mëw2Iý›l*¼Ý¾9øñi¬¹î5‹µãußJ€˜™Æã™ÕšÏïÙ‰=ßdØÊewÝC­»ý:q¾ÀÿįS@€ @;÷âH–cPJ‰•Hzž÷ž?¼f³+UUÅA@W\d­æÁ»·¤(£Gwš\N Æ„Î;NÕ,‡|ÁG¯” E“Î/Î䦔€×š¥)„Ð÷è 7×·ZøµF›dÀ'•ˆs²ÜU!äx¾á Jœ;ÂpÃM—IEND®B`‚snd-16.1/pix/ampenv2.png0000644000076400007640000002413311147553266013226 0ustar bilbil‰PNG  IHDRȳCßÄË pHYs:ÊduhtIMEÖxVŸå IDATxÚíy\gþÇ¿9I$„p‡ ÷% ÔÔZkÝj=j=j±­mµÕíEm+ÝÝ_[·îÊn·µ[«¾¬®b=ºµeoªUPäCQC ÉI~Œ1$aŠhŸ÷‹¯™Éwž™yžÏ<Ç÷yæy(•ºJ“ÅNP«Õ½Á›ï į´¶¶ŠD"‹ÅâÌ ¹¹™n²˜ŠµÅÎ,°Ì_ç_˪E±‰¸­ Öå×¥6«þTH'¶Ì¸YÓ£ék¡UjqŽua(6Vp#®Qh0ƒU°½ÙTn K£Ð0ÅL®?×>:îïåOÓÐPl>ŠRã ·àvÇ™LŠÂÖ³ûÚã<ÜÆÛ®?WlŸ¹arŒ¦¡õ=Žx$мJÌ?Ö¿o‘×QÙáŸêà8V‰ù3üf#Pñ¸+ÙSÒ÷àÍ+7+o*µJíÀÂzøÑüBÝBEn"‘›ÈKée÷«½°¢Q„©*¤ôP†RD\Øw¡ùbskUëµ_®u6uöJ{‹¶u4vܼrsÏë{¬f½ÒÞ¼µy gàüηVµê1}Ñö¢nqwINIþÆ|=¦·7œi¨:\Õ-în¾Ø|í—kP´½¨±¸qˆi(˜ÜWt ½ÍÔ&6ŠÅFqõµj»SèvûÝòîò«å`6™ n whD´AÚu£ËËÏ«¹¬9vJìå#—)TÊøWÆn-ô‹ôýüh«%Ç—’1.¢dOIçõκÓuã^gÆÍŠ6E`| 7€Ëð`–:•îÆ…¢TQýÏõfÜ h,jœòÖB3Ä„E£Ð Î0<ÁÞÁ$O±Ï±äžòÐÇBC <Y'“u:æóÐÚÚÖÜÜj0žyfº‡‡X,™¬S&ë4 ƒÁd2€³›ùüóÄÍäå4¦–É:U* ®]»þÅ›»»{ÀEøÄ)¦• “É:{zCHXçV­Ñh$ÇͰbÅ«/–€]¼9ÕëäÉŸ•ÊÞùóçDD„µ·ßüôÓu›6}ÎåÞÑ+TRRVQQåîî.“ufee:Ìù²³×ûú ^}uÉåË5……çØlvQÑù>‚ššº;÷nÛ¶ ©¯¿zäȉW^ÉpqK§NÉÊÊlmm[»öó?ÿù}‘H˜›{”PƒÑh ƒD¢ààÀmÛv9¼[JK/}ÿýÉɉRiGfæÊ'òkjê ™3gfGG§³ð‹ŠÎGGGJ$í|ðÖ¦M[üFãŒӄ¡àL.)¹˜½^¡P&%%ää$†òq8œ æ8‹7‹õ›…5mÚ”+^%¶ÃÇ;º¯Íõë7ZZZy <W ð©©©ëèŸȬ¯¿zíÚõ²²Š‘#S€N§Ÿ>}–ÃñHKÕ7œèèÈC‡?þx:tuÉkj®À‚s#"Âü`ĈĦ¦……¿47·8¼™aÃDÄÍ0™L8rä¸N§Ã05N S>|,>>–Ëõ²†/§p8w8—Íf3—ë.‘´77·7Äê[ÇÇEF†À„ ipölQ}ýU©´£o¼9„R¦-+Öcr,ùfôL?ŽãÝÝ=¾¾kèúõf92Å`0\¾\ ±±ÑŽGuu­^o ƒüû^ ­­ýæÍðôäÄÄDÕÕÕk4ÚÀ@ÿàà ±¸U&ë"Ž@ggWKK+!2gâ&.¡TöUø””$¨¨¸ QQ\®acµì Q VW× T*ýýýüü"QˆÅ­¦Žu>0n,‹ßîþ‡ÄsUIƒQ_’’ †‹x³õc]«Íê­…N…UVVQUUcÝ}öÙg¼½y¸WÛv_HHð´iSHUUm“dæÌ§üýÒ·gÏ~ƒÁHl«Tª3ž"ä‚€+W®ž;Wj[ qPq$^9‡ñf+,§YY\\Lhèm=zzzìvgÍúƒu›hT€¨¨ˆ  ëî€ë4øÃ4‹åV?¼››Û© Ɖ¾u×®•f›dBs*,¶‡ûîo×Z˜Þ l6‹ÍfÝ}8¶‡°ƒÅb²XÌÁ í¶°4MyyŠ_Ä€Ñéô„åçç6,ÅbÀÐŒbK±ú ÷u,*•n6›0LÃáü†:–› Åæ£‰Åb1™tý ËÀ ŒÆvL.äºQÂÄI9Q9?Å&f³I©lë_XÕx]£¹ ¡Ò\‹U÷NbÚ¹s/N÷òòÂ0Ìl6ûøøðxž^^\‡ÓÓ#OJJŒŽFÞ Äå^ßC&Àuñ§Ñ«F0™îBa0…Ba2Ý…ÂwwfddŸÏår¹!!"ˆþs,‡­VÃf³ 0nl6“Ívw1Ð JJJV¯^Ý÷øùóç-ËÓO?œœŒ’á‘n4Y?öÅ8Ðh4‡£Vc<·­­¸\žF£&r2£ÑÄb¹9 ÝÓÓÓá,JçÏŸÏÊÊ‹ÅÅÅÅ„°êêêþ÷¿ÿݺ(ŽS(”?ýéO(y†”°Â´!–6][[Gp°?;€:ðööÖëoUû½¼&êë ÷ººzkÛ’Çó ä23»Ùqùò刈bd&Õ±ÀÇÇgدNy‹ÅâæÆ0›ÍZ­º»»D"€»Ãׯ_/‘H***RRR ''gåÊ•ÙÙÙîîî( ]aQ©”›7o9*L&•ÊàóI ¡É̼c|ð?ÿùObC(fee¡Ø´Ü  „…@ÜÊû}C&“µ··K¥R”0(ÇL0 “J¥2™ % Ö`>}úôÉ“'£„y$ŠÂ¶¶v‰Dòëž%9yŠ8Ä «««Óöû‡ƒ"Z…$,„…@ÂB<:­ÂûFIIÉÙ³g J$¬Á$-----M,=z¥ * $, @Âúèêê***BÂB 2Æú¢êëëɘíÚµ«¥¥ A ©TúÍ7ß´|t¢yÞï–k×®mÙ²eùòåÖ¹'€<Á`p½&Þo¥°°&NœˆŠB)ŒF£N§ë×ìܹsçÎCu¬¡Icc£Ùlôj~~~>ª¼?Òddd466ökÖÖÖ6oÞ<2úúúNš4‰Œå?ü€„5tß9*5''§_³={öDEEíÝ»×µ™Édêìì &µ^&A#a=¬´·· “¡µµÕµZ­ÎËË#õo¿ý–ŒÙüùóL/–crssÛÛÛÇ ù9xCC1Ý0ÖïLAAAEEÿ«±«ÕêÄÄDbQà™øøøºº:$¬~())ÉÎÎþúë¯ïÝ%Μ9Cr¾Ý´´´¯¾úêw‰’‚ÎËË{çwÊËË‘°úOˬ¬¬•+WÞ»KtvvÞSáÞ=†½óÎ;$Çg3û+z{{QQx!¯*___’–žžžL&S.—ÿôÓO®-gÍš—.]rÑÌT©TƒûÔ­­­«W¯nhh@ºWxxx<ñÄý¦Ä«¯¾J&À„„„+Vðx¼={ö¼ÿþûýV‰¾ÿþû 6|ùå—ý6÷ñ© Å7ß|ÓïS#aÙÓÔÔ´{÷n2–t:Édž:uʵá—ÊÈȨªªráÿT©TF£ÑÛÛûÔ©S_|ñESS™[U©Tý®±íïïÿã?®Y³ÆußΓO>éïïßïEsrr222ȸå°î ±±‘d¿õk¯½F>X¡P8uêÔÎÎNg.¨æææ‹/Û‰$!!ÁuÞååå4­¶¶öæÍ›.Œq¯¨¨X¿~}qq± ³É“'ÿôÓO†ÕÖÖº0“H$B¡dm ë6û÷ïW(Ö4vÆ¿ÿýo@ššúÝwß…„„ôkŸššª×ë‡ ¦T*û½‡%K–,^¼ØEí™gžF£Ñh”J¥Ñht ÑhT*•‡vaóÌ3Ïtwwã8>eÊ”šš–ƒA.—#aýŒFã‰'ôz}mmíñãÇ]”\0mÚ´ãÇ/\¸pݺu®ƒ6mÚ¡C‡ú-¶`ÕªUÓ¦M£R©Î|D¥ÊÏÏoòäÉ , óPçÎ{ï½÷\X+jçΓÉd.ÔÇÇǯ\¹R§Óýõ¯=vì˜k¥fgg»ÖèP–V«íׯl6óù|bU•¯¾úê£>r=4E$™L¦9sæ8ôY«T*F“˜˜Èãñ`êÔ©«W¯>s挙Åb±øÒK/9[¾åüùóÇŽ#®åïïíìõ°Žëâñx&“‰Á`¸xëýz{{;3‹Å Óé»vízòÉ'333eÀÇŽãp8+W®üóŸÿLÆü° «ººzòäÉׯ_W(o¿ýv_OŒB¡P(‰¤  `ãÆ‡ª¨¨¨©©Ñëõv–'Ož¼~ý:‘`Ä‘ÈÈÈ   ¾Úúàƒ.\^^^Öƒ¥¥¥}ÝB †õû•••Öó`ß¾}iii-ß{ï="âñxo¼ñ“Éœ;wnbb¢™Édúî»ï4 ±;}úôãÇ߸qÃaVýñÇ[ã-<<|æÌ™ï¼óN_K ÃN:uðàÁ}ûöyyyíܹóüùó7npу2‚Ôv½B…B!‹ÿûßÿæçç?öØcü1ŸÏ/((øòË/?ýôSÛ³Ö¬YSRRràÀbwÇŽóçÏ7n\GG—˵µ|ÿý÷ccc›››/\¸@ ¸råJCCƒmʉÅâŸþ944ÔVU9~ü¸¿¿ÿöíÛgÏžíÚÇñíÛ·ðÁd$ØÝÝ•™™I£ÑÜÝÝGýõ×_×××ÇÆÆZÍÚÛÛ_xá…#GŽ»#FŒÈÍÍ%N· 077·¨¨H"‘ØÝdee%ñòXÙ¾}{ooïÎ;‰]>Ÿ¿råÊçž{.>>~êÔ©ÄS=ztùòå°ìÖ+ùä²eËÊËËwîÜi[’Ëå£G®ªª*++s}J¥Òßß?..®_¹TVVFGGïܹӚÀ.¡¡¡b±X$º½Æ±]º—މ‰¡P([¶lÉÌÌäp8D;·««««««oin}fΜél¥¾+W®L˜0¡¸¸ø…^°œ9sægŸ}fk&—ËõÔSÖ„!Þ˜ñãÇÿýïOOOŽŽnmmõññyþùç}}}ßÿý_|ÑÛÛ{ãÆAAA}Ûe%%%Z­ö³Ï>«ªªê÷ÒQQQ7n$ù2…Â~ÍZ[[/^üÃ?L˜0Áz0,,¬±±ÑVjÕÕÕR©T,÷;®a÷îÝ‹/...?~|DD›Í~ñÅV›vïÞ}úôi;…„„}ºÝêÔ}«/Û·o'9ÔﶃB—-[æ¢ÝºhÑ"Û#‡‰†‡‡÷»Ph{{»··wGGGSS›Í&2Œ˜˜˜¾–ãÄîÁ«««ûF…•”””ߪª‡ÌÝýùçŸggg§§§ñÅùùùo¾ùfhhè¥K—lŸü¥—^úÏþcwîÈ‘#û8cÆ »ÂÑ¡›'88xîܹv Fbbâ³Ï>k;9¹ÏæÍ›û†ðæ›oöôô¸h¸Y™7oÞ‹/¾èº1Hxn£££m›Ì,kÔ¨Q${g̘a{Ÿyyy3fÌxÔýXIIIo½õÖ˜1cd2YPP…B±ËÃÙl¶µÅDð¯ý‹¨öåôéÓd2Ëëׯ۵¤þýïÛm¶Í«¾9·~Hæé’““ù|>‹Åê×rÆ 6l°=ÒÓÓcÛ·m6›Çï쉈¢Ód2͘1ÃuŸÁCÜ*L&ÓÙO„¶¬ÅùÆ.\ev_’“ÅbQ(’k§'%%%%%Ù=K_Y0™Ì~›f[·nµ ÊÖ¥Âçó ƒ§§gHHȽXíö!– Þ~ûíO>ùä/ù‹V«õôôôððè·p!´Âår%ÆÀP©Tý:/ž~úi‡ÏÒÓÓc+q‡óì³ÏÞå½k×.»vèýd(O Bx«×®]ëÂF*•’ùæ}Ð é[yº{š››òòòŽ;¦Ñh¢¢¢°~IAìJg…Ñ믿n7\øõ×_¿›ë¦§§ÿòË/ƒû,Çd2­Y³fÔ¨Qyyyjµú^h÷‘. ÉóôÓO[ýì7ntX}­oÝݸq£3§ÔèÑ£I^z×®]¿õ¢£ÓÙ%ø|~IIÉ®]»233 ·Ö½bÑ¢Er¹|Íš5³gÏv…ØúÆìüd¶Œ7®ßñƒZ­Öb±ôk&‰„B¡Ùl6™LÏ<ó̬Y³¦L™âÌØËË‹Lû÷‘+ ‡‹J%ºô æM›{ì±» P¯×—••5ê·žÈ`0jB$ÕÖÖÖÖÖ¿òÊ+›7oþ«äHX0€t]µj•³_ÝÝݼ®¬9ÆÇÇ»(Fóòòrss?ÿüs¡Pè"ÇBÂzÈˆŽŽöóó»råŠÕ÷ãºÃÛJ{{»‹ži+W¯^-((pöë¼yóJKKW¯^=ḟýHHX1^^^eeeííík×®‹Åd¾ô€Ý»w÷;Âý›o¾±õ­÷eÉ’%Ë–-ëwÔÃUÇ@Š!Ivvö7$ÉØ±c‰QÎwÉÒ¥K¯\¹BŒ v=ZÐÇÇçáRÕ—cUVV^¸p¡»»ûŒ)?þz{{‡îÌlĈ$ïßßß?777..®¤¤dêÔ©Ó¦MJïáƒ%¬˜˜‘H$‘Hœu‡= eââÅ‹ý:}úô1cƬX±‚Ìס¥¥¥Ï?ÿüªU«GŒ„u¯`±X,‹Ì§/2Äø»Ý»wS©T …âÐl̘1G±àóù[·níîî&“ù¿ÿû¿‘#GΞ=[$åççŸ;w.>>þ¡‹Y‰Dòý÷ßËd2 …rèС„„„ÊÊJN7a„çž{îÀt:ýü㲦R_rsskkk###@¥RMŸ>XÇ*77·´´´¨¨(==ýžTÞµZP´té w¸•ýýÉ„W_¢—P$¨«‰ˆ©ÌW®„;;—.]Ša˜»»;±îG}D8“CCCqçñx°„Bá¤I“²²²²³³ãââÞzë- ù¯ý«ººº­­ÍÛÛÛ¶ÓâA#22rùòåÄ:ÙÀáp¬3µL™2eâĉ®sV{ûÍÜÜ£\®×G½×ÿkÎs777ÛÅõl—o$¹L÷ƒ •JíííÕëõÄ6Ùl¦P(ááá/¿ürEEÅØ±cØû·õ,P(kçÃÀ…8{öÓBa§§£e±¤RP(@¡bóövèîbA‡övP( ·fÑaáÂ…999D/VEE…¯¯/ñ?%%E¥Råää¼öÚktK©T66^µîªÕjb#11Íf9k­BR47Ñ«ÃfƒuÑÇ  ) Z[!!ah +44tåÊ•ÖÝ´´4ëÿ… ¢Ê;°Ù ¢¶nG` ¿ý!Èχäd°®»v- <XëIsæ j’åV³1$þñ7k+rõª;vC‹¿‡ÂÂ0ŠbÄà ‹ ?¿ »»ÇÆó¨Ñ¨9OÑC S1 ¹üöcÇŽ ï¹°p÷õ€—Ë­­­‹‰‰¥Ñ,(I†jµF¥êÕé´ E¯BÑAAÁæ{., …âã#àr½p܈ãF7ÀƒìDÇl6Ii±˜¹\—ëe[:Ù1ÈÐ4M¥êÕhÔ(†ÕÔ\€áÃãŽ9þøã=<ØÐÚÚV^~™8‹ÍæÐh´ýû $yáó¶_†ºF*íÂqÃTí¡S #!!z€Âb±=ènn«^­V)O”Ë~Í0ؽ{ŸÉ„ß²€ÑhÄq‹ÅööæQ(põê5Bpˆ–  @…¢›¤q{»$%%µ§‡¡×äò.“É4ð‹Åæüõ«œ?¿ù|gG×Ûà–],–H¥2Û/ÀÜÝ݃ƒƒ)ŠÁ ·X,jµ ëoëáä[½½½f3®Õj¨TjlllCCÃ]…Lº%ć¶sÏw—ËÏùyXn8˜`ôèÇÌfËܹ3/^¬°p P(†™Í8ùÜñpÖ·Ìåå4í®„•š p0)- à&˜¨Tê¸q£€øO Óé”J¥Á` R©|¾7r>èX,ƒÁH:{³X, ÔJF#>‹¸°Èãççó«ÈôaaNÇÕ  <<8ƒt…LÀd2ÝÜn)‡J¥ÞaÍžý4Jª‡Ž‘#‡“ÊÛŒÔÛ¨ Ýò[r,ƒA ¡¡A(ÆwÔ«(æ ´Úó­nÖUÚÔÈ ¤„¥Õj;::­»(26¸QÔ¡êü–°:ZÕÍt‘õG_àÐ ‹Á`úù¢D8®¹S- ±î²Ù¶ja0è¢Y×WX4…ÍvC1ˆpˆ‰rÇ(:êB-êX\n0•J»o€W*ÛP‚=,PÂkbê»n5ó‡ \M)è¬UH¹×w©V«Y,w”Z®1 Öî²[UfÖ ¸o(»ÖœÅbéßãHµPÆ„¦@(I:!//Ìù$Íú²iÓ¦’’$×”U\¹Ô¨'þÎ^êØñíþÁ©…»±i47ëŸD"uhvãFËgŸ}ÞÓ£À%çX%%%›7o®®®ž5kVHHHNNŽR© ^¼xñÁƒ[ZZ8NFFÆ‘#GöîÝ[]]™™iûÁµB¡ÈÉÉÁ0,44töìÙÛ¶mÓét\.7##£´´´¬¬Œ˜z4-- …ý(€Áìµ0}ýƒŒÃ'¾õ·u·§&À0uCC#$&Æww÷ø  S3 ¥R)•Ê|}"‘°­­]*•±XÌøøX› 7™nÏìÒÕÕ|ëK>[û°°Ð¸¸hµZãíÍÃqœ˜ý%22 7‹%•vø;αZ[[U•*Óu›}{í´´4bÞøøøªª*­V›ššzñâE ÚššRSScbbpÏÈÈ Ìì>ã¿zõ*ŸÏOMMõõõ5R©4+++11±ªªª¬¬,++‹˜=åXýÒ#ï|ÿµ9Ÿ}ðêê7æÅ OI¸=CäÁƒ?j4ZF{áBùþý‡@&ëúùçššº;öh4ÚÜÜ£fß¾4­DÒ~ãF ™+®ZõFÛÐp­¬¬âΈË<øciiqÝ;j8õjU¥ŠçÉ£ŠD¢ÀÔ@Ÿb|ºõõõÀãñÁË/¿ÌápÆŽ+t:Ý›©ˆ3FsâÄ  ¥¥¥`ÙŠV«…_¿ F¸ÀÛÇ÷£¿séü™ò’‚ÅËÞ£Ño7ªRS“/]ª¼t©’ŲïïŸ6mJzúX¶É„Óéôôô±Ó¦M #U9JK•ž>6&&Òn<{}}q9bž3üâüSMfÝb±`f 3bÄÜV–.]š=qâÄ‘#GÖ×ןÇ'ON'£­sçJù|žV«KO+‘´kkk_±âµÖÖ6>ŸG´$„ ¢¢óÅÅ%všµE­6«15F)Ó–k‹196^•’<,áWwÃý˜›Ôl6¡:–knÞ”‡„€^§ug²¨0o2™LÄz3\®WEÅåððaÝÝ=—çÌ™t:]¯×3 N§Óéi4ªí¼=]]ж6[W';*êÖ,£ë×ýòË‹ {£Ñˆajàñ¸@ÌòÏ`0¤R™ÙlðÛ¶í?ï¾»âvAD3µœU›Õ…[ Èb!Õø¼{îÏUjýÌ&5¸ÑÁlR›ïðOÒ½½yÖbqÆo<=9¯¼’A¡Ür_‹Õ×C!ðÇSŽ?Ƭ›››u¬Û¡¡!99åòî7ÞXúZ…½½hù‡ …b›sÜ £G?FærK–,  ¸°÷„ÛE¡ŠkiF#ˆc â€ß),6}Í«µÕb?‘F¡áëù:´À.ÂFõŸ8­¥Ïœg8hÍÚ;„E¥Q4£ÑlŸcaFŒe`©Íh.„*4ËÒ*èÍÍÍ…¹…N=f‹(HԚ׊bqÛïàéÝPÓ vþ5¢É`ú/ãg:IEND®B`‚snd-16.1/pix/sceq21.png0000644000076400007640000000700311147553270012744 0ustar bilbil‰PNG  IHDRuÉë\R@3PLTEÿÿÿ°°°ppp```ððð€€€àààÀÀÀÐÐÐ000@@@PPP    ÀgF pHYs  šœtIME× 5gdd± cIDATxÚ틚³&†QQ1š¬÷µå Èp¢¨ù;ßӦݬœ%0ò !BUÝPÒ¶±UÕUH=#Ã«ë ­ìß -F§”JH7òfÿ¦cC…ñ)¤®m†aj;jÿbš)FýrUM1 שªX%ºõ‰a, ôéïw«Tã‡ÿ Þ®gÒ6bªßFvØ×ê¿xT1½Þæ€9ÈXw¼¿zŒMÁlýïo0Ã.^Ú–ÐÙM_’FZ· Lþq6‹Fúªâoð1e>Vê©'8ß/' ëÆy§–4h¡hcƬ N?‘V ×Õ̽yäÿ¢½–©É5¯5nÆ×Û˜PNoW±¥-”nøÊé`Ô¯•r:oà]ëV•Ó0Wjq:xCéJ­N烡(2fú™ítPe¦Ì,¥ŸÝ{5¨’K)“¢-# sÅ+¬©¹”£~]†He.ÚúÌÄízÔݺ¹”±e-Ž¡( …B¡P(Ô£¤|Qå¦|‘­.èOƒ”/²Õ¤|‘­¾CÈVß!d«/Nk­.9’"[}‡­¾EÈVß⑾e«ÓÆÙ´Ú"«chõ¿V“¶ÚLè#Œs.Zm‘ÕZXh°¢ õ¸©kOd«MH6Æ8g¢Õ6Y ÑêÔBCM¨Ç]]{öÈeœ3Ñj›¬¢ÕÿXMRØj‡WŽ1Îg¡Õy…*²úgÀj’ÀV;¼r„qö£Õ¬NB«³ ]Æï€ÕdŸ­vxåY}ZSèê0~¬& lµÃ+GÈêÓÐêœBµÃø°š¤ ǯ!«ýh5 «ÓÐêœBW‡ñ#`5 °Õòuxå0ã|ZSèê0~¬&!¶R¾¯œÀ8F«³ ]Þÿ °š„ÙêÊw—q.4ÿ#`5 ³Õ{”ï.ã\hþ'Àjf«‘ò-iKCl5R¾·ø&¤|oR¾7)ß{J¤|KÎØjTÑéd«o²Õ·XSd«ïÉË‘­¾¡[G¶…B¡P( …z²‚lµXSލoÙê¾ œõ-ãOClu?ªCÔ·‚l5¡-£¾ƒøKA8uô[0“!ŠúvUõž¶˜í×;üÏ8V1Ôwàm5Ùpêë´ÆÃR¸»Ò‰®GD]­ƒ*Ò‡¤³Õž]鄸aY'1 TDélµgW:ñî¬×‰mÅÿ½)ïßóOf«=»ÒÉ ÓuÁå3†ÍÙ9&•­öìJG†AsË:1ˆQ¤Š<†žSÄ ¢Àæì”ÌV»»Òõo>¬ëÄ F[»¢DZ:x_Ñ=ÿ.®Ú¬ ØuIß·ÚÞ•Î:8c½ØºÓ[âò›ôm¬o㪚H›ãjnG³._í[}LKÔ“3žz~y®Ú¨‰´9 ÚF½Õ%aßê£u²Sý±Úhim\C -€šuç{¸jxzÙY¿Í¡sˈº®Ë.[f€R»©þhÐÒ«9ð‚ÕH0Ú=œïrÕðô¢51:x³ TQßêe«3åëÑœTßàvµ9ðmd…ýÙ°ž^¼ËtlN ‡%ê£Ýó’›êQ׿Àk «êÿ˜Ø†ÕàôâQwlƒ“±0êiÔ1ÍI‚!Jí¦ú-­ÍÇh «èÎw¹jxzQšâ®â½Ô%eßj•Ž‚ÙtÐ)m¶S}“–ÞÌk´PsÉÎà|—«¶N/)x%Þ¸ÏÓŸYU]lµ'…³é2ñS­¨?Õ—×Èó£Ö_þÀù®Ú>½ IƒŽÅâ‹e]Blµ›ŽÚ³é"ñ<úlÓ.í¯£Óο‚«N¼’¥.!¶ÚMG­Ùt™x†“hérþ5\u÷­êÜ·Ú“Ž0›.O\?pÈÍØlµßÁ³éjHFx¬ü¼ œMQÇ»¥ÓQ8›®O¼M]<³é*ƒÄ›GåÓQ?ëáB¿¥T¶ÚMGîôóµ’Ùj;¥¸Þ눥B¶úz![}K"Žlõ-Ý:²Õ( …B¡P(Ô“…lõ B¶úŠlõÊa«áAˆV—ø¸l5Xhu‰‡­F´úì´Æe«].C²:½Ig«=(1ƒ!Y®t¶ÚE!ˆ¹ ÉjhsâJß·ÚƒBÀÅ`¸8ư9;Ǥ²Õž-æÌÅ`_‘ÕÁêçpÕfQ§²Õ. ƒí‘Õ[¢¬Žïb}ç~Õ…ØjZÔ¨Q‰hÃ2ý`utë[÷«~<[}Xý®ÚªÍ3Øj'Ñÿ ¬öïbý®ZͪømΕl5@«Dÿ+°Ú¿‹õ#¸êÅ·ÜÈVûz<ßþÓÙ`µ÷SžÁU¯½æ³ØjßþÓÙ`µ÷SžÁU¯Q/ÀVV;‰þW`µwëgpÕÒÍ”`« Õv¢ÿXíÝÅú\õÚ]œÎVA«C‰~XíßÅú\µïb̸ËV—A«‚ÕÏáª3.&‡­.„V«ŸÃU'_L[hu;g«­¾CˆVß!D«ï¢Õg»uÞX6 Ò`D«®b ÎY Z}rroP¾¼§f£ˆV‘µC̈¹$'4)_Œúeݺ¹Š‘½Ž‘( …B¡P( •¦ ‚*§ ‚}…è¡_?1š‰Çl7ǰ_æðMûxÁ=®L-eORÁvbplØYÛ´ô?öˆ‰‹/b¿vÔSø€©ÿ_EݳÚ?û m×FÖUørEþ°m5ú½KÙ€§DÝ»Ú? û nצWዹ衫Únv硯e®zÁ&þ}•ó°ßàvmz¾øy s¿4ç¥&jiìµlÀÅmÝ‹`«èW½Ú?û nצWá«~¾&þæ|%puãC°×Óí}•ó°ßàvmz¾\Õ7¾Aúb6à¸5XöXWKÙ= |ׇ`«|ÒY퟈ý?a£ˆ—Uøàá#nÓy²ÙKÙåì¦Dwþ@ ”gÑëÖ´ Æ|@Ó ­öOßP9°3óúò ø´kÙEOôt¢fÛR³ÎJ³Ð{Xе7wõ‚û+ò/Z%²¥¾5¿Y¬õ¯[ßÞ·Cé: õ0±Õsì@þÈsöæa.Z%œC'–“/Q4a/Óž˜ï/¡Ô×ë: ð`ž&lõ(‚ ÐßPþýl ç ‰.•‚L­Ç9Øï«ó¶ë…ÎB¥i¶ö7Ï6¶z&‚mäß?¤FÝD§M{B-¼wžëå9›EDm] 6¶ú-‚혖üû}š®‰z×é¨[ñý˜¹Žñ¾¤-ôõº©úu‰XØêAîªìÏ¿.áÄèØ¶F|Uç`Ûª; E[èëu…ŽºB ¶4"Ñç\…~éÏ¿.Ùîj˜9Õ,=ö¤2B¹]¯ë,œYrÁ<çJÝÛ>k/›÷<;é~)zb`_\P„¶ 4R`ÁϹÚ|–ú£F‚MÜg'=@Ð9,=fåN-ùßÏvQÛxΕñmYΠ‡ï®=(ê‰,﮳ð<¥ÔÛô¼¶:Ù|ΕõåÞÆœËG†ž´•—c°)ßSJ}ƒ·ÁV'ƒç\mQW÷6ì‡`¥üÏNZËûMƒFBßSJ#¶ ØöÉÐgi;»!ž´–÷› ŒÞ§”8ykëúÞF¶ÏNÚÊ ÝàøyŸRzää-êÂζ"g'éò~Ò`®Ã÷øž#'ë¨ovvÊxv’.ï' Vž[Y¿ô0 ž¼µuúíÝ.^ŽFþJD°£> •ïÉÒlÔ™Bû!‚}O·Žöiú3¤´ûªÃöIEND®B`‚snd-16.1/pix/8.png0000644000076400007640000006152311371053202012011 0ustar bilbil‰PNG  IHDR¤žTÏâ©sRGB®Îé pHYs  šœtIMEÚ ¿Ž IDATxÚìg\TGÛ‡g¶Á‚H°¡¢"vc4**–5Ážfï±`lIìú5vì-±[ì;V,Q Ò‘»lß3ï‡y³Ï> ,Û]á¾>ðÛegæÌ™9ó?÷=B@e‡E@;µ­F•S쨺I¥R''§¶mÛbŒõI"--­°°Š€Fì0Æñññƒ …=R©Tú$áëë;mÚ4(J>&7vùòåã!C†Ì™3‡ÍfëéÉ:::êø•aý3¾3–€£õcüý÷ß¼{÷nΜ9¿ýö›•Åêß¿ÿ£GtS©T›6m:t(Ô ;•JÕ°aÃfÍš1 “’’b®ËüóÏ?™™™ºÃ8pàÝ»wzZzö'”!v„?ÿü3$$äùóç7¾zõªeEŸ¤’““Ÿ={¦T*u„áóùPs/vc†a®^½J¿2 ÃbYo"^³fÍ"""~ýõWšÈf³9¢[ *vc5ÕÍšJGiѢő#G* yêÔ)¨6 ÅVVP@Vµìt “Éd2•\ì~ÿý÷7òx<(5*­ØB&Mš4iÒ$ð@øÑ·Ï €*!v v v v v v v[„@UƒcD¡P¸råJ>ŸÿñÞ6Æ8==ý?þ0}+B‹Å Ó½]3ŸØq8œF}¨ucæÚ‹%>>þÊ•+Ó¦MS(¦¤Ãçó§L™2bÄ;¨lbÇçó‡®þúõ×_[3ÇB¡ÐÑÑQ‡J‘Éd4˜î¤Zµj5pà@Ó³´aÃ3ú×°XlEì> „}ºÛ‚‚‚ô f®ž;3öbŒ1Æ\.WGšJ¥òþýû5ª05Ó pƒôı3›èÌ óÌlJÊ1Æîîî999ºC2äÕ«WºÃ$%%Í›7oöìÙ¦—ùãÇ+Ó³”••õúõëúõëë.óþýû”n¬\.·CÚ ¥°Á³d‰òù矋Åb=½~«$7pàÀ¡C‡ê¸GBˆ§§§žCLºËŠa˜ääd}Òáóùááá:äääœ={öþýûÊ«>ÕGÑsV¦Y&½oÚ´iÓ¦Mºƒ½{÷nΜ9æz€©%¥¡Phý¦•ƒž$«)!äĉV+ýïëðáÃ))):Ú÷g–&Ê0Lß¾}u{„)S¦ôèÑ£Â"5Ë“PTTTé‡VŒ»¬¬,ŸêÕ«ƒ¦Ö7Z-!Á¡¡¡Öìa¸råŠP(Ô]PwïÞíÙ³§‡‡‡9c±Xé,+„ž3@Í8ˆaŒØyyyivÀX;PE$Ø\ºO…-< `̘1Ö”sÝ>é°Ùì+W®èéòƒ  ¿f)BHzzzll¬D"1%>ŸŸžž^¡BÕ¬YSãpÌ)P v //¯úõë¯]»Öôñúõë{yyÙà=‚Ø€¼¼¼öîÝ[¹ïv* Jbˆˆ€EQ©TÈ|;¶Ø`£<}ú´[·næZáb€-BiÞ¼ùÇÍ• ‘ËÅjÖ¬ ËŰf_šeär1ÍÙϰ\ ÛÜX@ì@ì@ìÌ€žCzí¡¥ €Í"‰V¬XQÞt/¿ &T¸E ˆ6ÍÙ³g Eyö—Ë]¶lYïÞ½;õƧpâ/BH¿~ýt‡éÛ·oÛ¶m>|¨C¬´ÅN­nööö7ŽŽŽ.ý€uÐSs¼¼¼ìííuvuuåh%ýæÍ›ñãÇÓSÖ5OØÃ?þ<..ÎŒG^˜Ã0çÎÓ'$çÌ™3'Ožär¹ Ã߸qÃÃÃc̘1¾¾¾‹/Ö4è²²²¢££ËÜÞÎÎ ë£ÿ68%%%%%…ÅbBüüü~ùå—îÝ»7lØ0---66V}ž¼7cìîî^§N÷T7*?ä4hPll,!$66vРAD  øÈÄŽaBH§NÜÜÜ:uê¤þn|||ˆ!tïÞ½¨¨È (wïÞ3g1@`h”ZµjeãÆÇ7( ›Í6ô*Íš534ÊñãÇ7nÜh…0´œ+YmQ;•©6 !sæÌ¹{÷® Ö¦Ú ÃܺuKÝó§?LwÕ¥RY\\ìì쬑H$“ÉŒÐq#:; w–H$åÍx4o/¬H$úG‹ÅFœjD_„¡å\ÉjS$Zh•©6B2™L$Ù`mj÷îéèí3סZZ …ÂA)))14JAA¬iC_¡ÂÂBCŸ¹\NGÕm­l¹6¥R©\.·t ØrmQÎFðAÚæXAáîînP”nݺ}ú駆^èÝ»w†FILL´B $%%åÁƒŽŽŽE6l˜ªj…°åÚ ³Âä*[®M#ÊÙ>HÛübgÄiá|>ŸÏç«víÚ†FñõõµB Ô©SÇÐ(µjÕ24ŠA^’5KÀ–k³ZµjVxl¹6(g#ø mÓ ŽjË–-QF¥RUñ97Vðû l¼ |³2Ø‹/6%>!äÛo¿e¦Ê.&S©T~~~5kÖ¬²ÏºB¡èÚµk•½}ÚÎpÌ+ShР›››çÃD9ô*¾i½qX:]Å€¢@ì¨ÀNÅ€ù}:õ‡2¿ô~5ñe¬^íU°ì3{4§Nâr¹}ûö¥“Ò;æââÒ³gOúë… ¾øâ }RS*•×®]ëÕ«—‰¹:tè—ËEq¹ÜÐÐP¡PxöìYBÈwß}Þw•v*Ì÷æÄ8<<Í uh///±cÇÊd2BˆD"¡bGCÞºu‹ö²ÑD¼½½###i€ÌÌL‘HTfÆ5/Í0Ì„ bbbôÜÔ¨4Àh,`¶;„Pqq±P(ÄÓ¯B¡bê`#FŒØ¸qãýû÷5;×X,Öþýûûí·uëÖ¹¹¹=xð!´nݺ¤¤¤ØØXŒñ®]»:wîÜ¿ÿ•+WJ$’Ñ£G¯Y³&<<œ.¼‰D5kÖœ?~™›={ö–-[6oÞ<|øp„Ð×_ýôéÓ¬]»F'ª v€9Ù²e‹½½½úë¾}û´:ˆ÷îÝKáñxZd2™X,0`@§NBnnnÛ¶mS(!‡sèСÂÂB'''‰D²gÏž¼¼<©TJêñùü={öÐÒ]ÒG¥/ö}ûö)Š.]ºLž<!dèR|à£ÃÔÀŒƒ]š¶’î‰:FQé3©cŒÕ ÑXý3 €Ø€ bbbbbbˆ@Õ;­Ýe*-™Ã¿ÿ¾E‹ 6¼uë–>IÄÇÇ»¹¹éylAAAzzºÖ?›4i¢µ;#€Åc|ÿþýÍ›7gee!„T*•>§£>\kÉwyìÙ³gÛ¶m­Zµ¢f#Ç;r䈦 ˰¸Ø!„¶lÙòîÝ»zõêíܹSOéqppÐñ«z[íâââÄÄÄG¹ººªíÒ¥ ‡ÃAýôÓO=zô€ZÀìh;*•jþüù¿ÿþûСC§L™b#‹ÅbuïÞÝÙÙÙÕÕU&“¹ººjšr7nÜ8pàÀ¾}ûúôé U€5,;‡ãêêêîîž••U\\l®Ë<þ\š–µèáá¡þ@Ýgpf°¬ØBöïßÿÕW_½|ù²Q£F§OŸ6£è¨“Ò‘`|||dd$‡Ãùì³Ï n°”ØaŒ†9}ú4ýZú;ãÔ !¤Ï@G›6m=z±zõj˜õ€y1Ãæã‰'nÛ¶­Lý’J¥</::ša=÷­ÅÓÃP`> ±ìÌNBB‚X,¦'ÝU¨˜êÏÅÅÅ 6LLL„êàˆ=8Ê Ô©iæäädP,''§üüü’’’ÂÂB///}\`³‰ÝÉ“'wîÜYú\(Kмyó~ýúݸq#55ÕÇÇê +‰!dÔ¨Q£FÒíšBȵk×B0Ás¡ï€žŠf–QTõµè™¡Ö;ýuêÖ­[ø_ í­³‚’bg¤Réܹséì™™™ôÌvãhÙ²eÛ¶m½½½ííígÏž k*°!±£z÷ß ;W޲~ýúÌÌÌŒŒŒÈÈH¹\µ€m‰¹™cfD(r8º”îm£ÊÌÕ·ß~{äȺsß¼yóºté¢C¼!ÁÁÁô³¿¿?‹Å¢wîÜ9nÜ8KÜh(ØØ•gmÕ¨QÃÒÙ¥s•égƒ6P‹Hzzz~~¾‹‹‹ÖÿË”õ? !÷ïß§ŸOœ8ñèÑ£ÌÌL¥Réëëk´[·nÕqƒÛ¶m£Á¨‡hv4“½|ùòôéÓÕƒ'š<{öL%GGGËåAÓ­Þ²e‹æ¯¥s¥Y}ñññe&hh4Ó|öì™æµ*L„Óœº´xñb=s¥ùë‰'4Ÿp†aT*•fý“RçJËxבBȤI“Ô'L˜ õ«éÕ­¾­ÎÜ2礤hU„%šMs„ :Úcdd¤Ñ™ÑPïÄ}úp8œ2vg̘1kÖ,‹úšÉFEE}õÕW43ׯ_G :4--Mká]ãÆ¯^½j¡ yñâ…P(l׮ݦM›Äb±»ÌßßßÏϧ©©©j_ÁÐêÓ ß¬Y³üü|6›ššAÇÐüüüÜÝÝu'£R©œ»uë¦P(0Æ¡¡¡[¶lѧú43““Ó´iS.—KóðöíÛ‚‚ŒqóæÍ z4ÓLHHhÚ´©¯¯¯J¥òññ©pÿ?þxìØ1„P^^ÞW_}5þ|©TÚºukÓÛEé^???‰D_žU·nÝ888¸»»ûùùYG%JJJeO«RØ”ìj]¨ÿþŽŽŽãÇ[­ÇG³p̘1vDº¹¹mÞ¼ÙBÒàÀ¿ÿþ!ôæÍ‘H4bÄ[ÃòùüüqôèÑb±˜Íf}:=½¯OŸ>ßÿ½é…œ‘‘±wï^ª"‘hùòåºÃoܸñáÇÅÅÅÅÅÅ7oÞ±¬­Â•;«šÉŠD¢3gÎ ñ´ë­oß¾ÊC³fÍ›Íîիׂ *ŒÛªU«jÕªEFF.[¶ŒŽb5mÚ´yóæ&Zaݺu“ÉdGŽñõõ5ú¾._¾¼lÙ²iÓ¦I$’áÇëÙGœ——7pàÀÈÈHkŠ1™™™ÞÞÞ¥—‹¶ÉG4ÂBYÕœ¢$è´!++¯fR7oÞ”J¥,ëâÅ‹cÝMI&“åçç‹D"„P5Ô‡íš=­À|>ÿÛo¿ÕÜ}RÏ45ƒ988´nÝzðàÁH¿`ôƒD"Q/Á²ÚûØç¥fÍš„’5*¥˜Z®ù¹ººz{{רQcÔ¨QšM©L”J¥“““······æ±¢&f¯fÍš...5jÔ¨®0vìXÍ·B™§¾t¿~ý0Æ\.·S§NêÕúg‰Ãá\½z•ÃáÐK[ç}Ì6®¼ÒBȺuëèŠïwïÞ 8ðúõëR©T ”9Uc|ãÆ ‰Dâèè'‰ÔóU 5ͼ¼¼4¥ÓÒ½"tPÄ@m‘££c·nÝ"""ìíí—/_>{öìÒCç|>Íš5 ,())ÔÝŒ3¤RéâÅ‹Õç•GHHˆzþJi“(°]îܹ3lذ˜˜˜ÌÌÌ k.8+íü–aÙ©Çzáls> „º£”ŸŸ_yZ¤–)Í}ÞË6µ¢!„„B¡‹‹Kûöí5S·Ü†Se¢)Aô Ê·oßæççk)]óæÍ5jÔ¸qc©q´’ŽŽŽ^¶lYaa!BH¥R©÷¼Ç?~üøáÇš»àXÞ½{Óc6sss7n|àÀµ.½yó¦Y³f111Z†^bwäÈ‘p¹\BH=bbbD"Ñ—_~Y·nÝ 6hÆT*•R©´L±³··‡úÀBŒ9räÈ‘¡¼¼¼F7N©T"„8ιsç4Oy×Ñó†srrrrrhˆ5jL:uРAoß¾½zõ*=ŒC·^bŒkÔ¨»`QäryjjªÖ?kÕª¥½ÅqwwwwwWgÆÏÏÏßß_,gee飗¡’’’·oßê™]MïXOèv¦†žZoÄ…ŒˆÂ0Œ¡gÁY'c6[h•¬6¸4S2V:¢¦RU\ˆ†a!½{÷®]»vïÞ½ÕÿÑ1„¡PhP”{÷îÍ;—ˆ@ 04J­Zµ ~òäIƒ¢¨wÜן   C£œ>>«W¯öññ©S§ÎÝ»wÕî¤z1@wD IDAT‰…P(ìÔ©µkoo¿dÉ’&Mš4iÒ„.Ú¸qcbb¢>c&ãÄÄÄ.]ºÄÆÆ"„<==E"!dèС ,€J¬=ËÐ5 ˜ŽP( LNN¦_SRRøèÑ#u€{÷îýõ×_ãÕ«WkF,..þõ×_===Y,V\\ÜîÝ»cbb:wîÿСCꯞžž[¶lÑ4¬:tè`gg÷æÍ­ˆ<¯eË–<O¡P„……!„œœœ>>Õ«W?~ü¹sç”J¥ŸŸ_ëÖ­aR4Xv`˜?«u"ú«žóìËŒRÞ¯èß ´ËLÓ ¤@é@ì* 0@ˆˆˆˆˆˆˆ€þbGçËd2¹\®O|Ó7¡…YÍX\zsˆ/^ôë×ÏßßÿâÅ‹ú$qçÎZµjÕ­[·B¥Ãggg'$$¨Ï!nذ¡——T–æ6À_¾|ùìÙ³¯^½B©T*6›]a:u1bÄÞ½{u„a†ÅbMŸ>Íf—””Ð¥ˆ¯^½z÷îÝwß}·dÉXŸ€õÄ!tøðáGµjÕªaÆþù§ž¤ûuªt=zô˜9s¦ŸŸ_“&MèÿÅbñƒBCC¯\¹rïÞ= ªkˆL&Û¾}{``àóçÏÇŒ³gÏ/@wåîØ±ã½{÷®\¹‚4NuppèÚµ+=¢¥I“& `ß`!´-)gggBˆ\.W*•t#0Á<øÞ½{êm²©œin°Cyùòepp0(Ö°ì!;vì>|øëׯýýý÷ïßo¢©%—˧L™rþüyz2^™IQ+O¥R¹»»8ðĉ yXVì¨îìß¿_­}¦èµ:”˜˜H7Ñaý!„^¾|Ù´iÓ/¾ø"""úï°¬«©n¦(Ã0ãFuèÐÁ××·ÂÉt„77··oßFFF¶hÑ” ZvæQËÙÙ™ÏçÓA‰ uS=d!‹õÙ¿ÀRb—“““­§ …B¡PX\\¬¿CJS¦ç{ÚÛÛK¥RÐ;>€Ø]¿~ýÀê=u8¤ãöíÛ6Œšx†š„¡!C†DEE}úé§ wXUìèqÂC‡-Ï"Óüzîܹ„„„¸¸8㤊²gÏž~øÁÎήU«VPI˜Ž¾f—žšE"îÞ½KWg”aŒ¹\îöíÛçÏŸŸ™™ •€õÄNºtéÒªU«êׯo¢ûÉb±$III ‚Q°5±‰D½{÷>~üøgŸ}fºBuéÒ¥AƒÑÑÑÐm€‰˜sê !D  4ÈôBÈâÅ‹]]][µjE—”ä`–„U(È´ ÉêÔ!Ó¦MCÍ›7~… àÃ[v¡‡2 cFõDeddx{{»ººÎœ9ì;>¼Ø999Õ©SÇìY¬Y³flllPPP«V­ºvíjÞÄA=ÄÎ`†yûö­Ù×ðBš5köóÏ?GDDtíÚÕ,ò¤Nc|þüùâââ2íʯ¿þ4ª®ØŒ9R hjBH,#×LèéÌ~óÍ7Íš5ËÍÍýã?LÔSõiaaa{öìY»v­D"Ñ Ãçó-ZtäÈggç:Lž<žø¨1¦×_¡PDGG«§hÓ¦ÍÌ™3•Jeÿþý»uëf‰\Ry*,,¬^½z¯^½þþûo£×fÐX 6LII 7ožJ¥jÞ¼yéÀ©©©999b±¸S§N¾¾¾ …‚Îp†í§ ªXv\.·]»všÿa³Ù 6´»G‡b]\\húƒ>~ü¸¡×RÇ=qâŸÏ×Üh tR„___º9•J¥b±X:uÂ{{{§§§[ȱÕ3Mð©ÀJ–]™næ™3gú÷ïoéìB …ÝôéÓ7lØ`ˆB–-[¶råÊ‚‚;;;ƒ 4uàZµjeddL:5<<ÜDÝєڸ¸8„““SûöíuD‘ËåuëÖ=qâDQQQ‹-,¤}ƽE -•в+M½zõ,1[¦°òx¼wïÞÕ­[c¼~ýzÝ-þŠ1^³fH$òóó£‹ÈÀ¾E˜’žžþêÕ«Y³f-[¶ŒÏçÏš5ËèÖŽ1Žˆˆxþüy^^ÞŠ+¾ù曼¼¼¬¬,ݱ 4{öl•JÕ±cG„PçΩ•mÆqŒqddäãÇõy~÷Ýwê“-¤z%kM啝Жµt¬S÷ô*TïºuëvíÚµòüPúŸƒnß¾}ìØ±®®®ýû÷7}¯yµ%[PP°cÇŽ#FLœ8QŸG_3@÷îݹ\î¥K—¶nÝÊçó›4i¢Õ3P!{÷îMJJZºtiHH—ˈˆ0‹]Ö¶m[77·K—.­^½ÚÝÝ]GD6›}ìØ±èè耀BH·nÝæÍ›g!>|xZZšî·Ã0‡ªU«²X¿jéd'MšôòåKê7`ŒéÓhet×8t1ÿOI™BhâĉĊР>ß¿ŸœœŒš3gN™Á““B(""B3¢¹2@IMMýí·ßØl¶@ (ýkéÿLžóæÍz¦¦àúõë\.—WAAArrrrr²>ù)))¡Ÿ?NÝp.—kÜ•ŽâêêJ³T­Z5„P~~~rùdee?žæö[ˆîÝ»;ý Í} œœ‡ÃIKK3ïS§…J¥RÞ¼y3ŸÏ§Å¥I÷îÝ­ß0M `Q>J±Ó*»]»vQOS‹úõë[­vëׯOߟ³gÏV(¢R¨}á¼¼< )ÁEßaôºB¡PR*•ªóCiÓ¦ Ƙæê÷ß7K®zõêE ¥y())Ñ'¢X,‰D2™lÍš5´¬ÜÝÝõo'š¿æææªËÞ¬L&3®AÊåršÂëׯ5{3J‡×JöǤáëÖ­KËAÀèVGT©T´]\\裎zðàA™m“þúêÕ+‘H$‘H,!:êÔÄb1=®«tcÄ·iÓFK£­†P(4›;qâÄmÛ¶}(ËôƒÛðê«$%%õêÕ«Ìóv¬V={öLMM¥_ÅbñîÝ»BŽŽŽ#GŽT(öööèß©‘Ô"3W”fiGEE :´zõê±±±<(sÚ¶‡ùóçÓþJ•JuäȺi«‰Õ7jÔ¨Õ®]{õêÕ‰ÄÁÁ¡C‡F|øðaqq1Ç[½zuTT”§§g5nܸaD]4mÚcèÐ!OOO//¯ÀÀ@£+7::://ïÕ«W“'OnÚ´)‡Ãyúôiy5¨þºlÙ²#GލTªüüüóçÏñù|ó>uOž<)..=z4—Ëݼys=JnÚ´iBBÂâÅ‹-ZdåîÎ’’@ðÑ‹MuØB×Ié ÑÍhMmܸÑÊE±pá‚‚ÝOvIIIxx¸æy›fT^©T:g΄½½ýêÕ«çÍ›§¤*Oy—/_þã?* ºõŽ›››q5¨¾‹S§NEFFÊd²;vüüóÏ2™líÚµÞ©æO¯_¿Þ¾}ûÚµk§NŠêׯƒzŠgÍšuôèÑzõêݼyÓ\ÏdAAÁÒ¥K†‘Ëåj(/W÷ïß?|ø0!dÓ¦MÖìL± ®rã•ׯ_—Ë媇à 1×]hF¿|ù²@ èß¿¿‡‡‹ÅêÛ·ïªU«tÄ5kÖ¥K—!AAAãÇW(j£É¸\¥¥¥%%%………¹¸¸”7¸gлÄÝݽeË–.\àñxúL@ݼysÞ¼ywîܱæ&ÆØ˜>»ŒŒ Ú'Bù€}v`Æîs«u¥‹Åâââb‘HtèÐ!ͦ¤íÉÌÌ,..‹Åf,¡P˜˜˜HÇôNÄßߟÅb©·›Ô³Äh°/^ôíÛ×jCÿ¿Ü룠€*"¾–€ŽÂSs/--­¨¨¨Â鄬¬¬… Rßè¡ý³ ,°ÂmŠD"‹Eဣ„ëàBºví*—ËgÍšõí·ßÒI .d†‚ª•Õ¸¸¸èèh„Ððáûwï×´iÓÿzˆR£F—/_6jÔˆÇãÍŸ?ߢÓÑ]\\¾ùædöÍ;øˆ¤–BçúÈd²õë×çääL™2åüùóJ¥R30—Ë=zôè¸qãüüüŽ;6xð`dòZɆ >{ö¬Y³f[·nµÐ=8p@©T8p€ü—ÄÄÄòF«i7¢×&æääxzzR_Øìû`bŒ{öì9{öl:ª–ÿ¥aÆÖqÀi"¡¦M›ÆÇǛݬ۶mÛ•+WèÖÈìG)èÜHII ¡gu™ ¥RùìÙ³¿þúËÛÛÄ€ 'ÍÍÍ}ñâÅ™3g̘r\\ÜîÝ»4hðßkAqðÁÛÙÙÍš5kÊ”)èß…Œ&B©^½úàÁƒÕ ‚Øðá kРÇ3ý„h:4Q§N:œ¢îa4f€‚a‘HÛ`.!·oßnذ!›Í¦;£§0ê©íÚµÛ·oŸf:ƈ]^^^«V­\\\ †0—3Ë0Lbb"Ýš·N:ÄØ À_¼xzðàÖtcÄÎÃÃ#55U3u¨*LD½#dݺuïß¿ÿÉ'ŸgÖuéÒeÉ’%¨ÔÑ 0Ïrfûí7‡#GŽ|òÉ'†wãðððììì… –Ž Ø3‹Z¼x1BèÚµk†ž¦B½×{÷î•©’ vØÕ«W§Ûë42~øða77·2UÄ›sf-ZtïÞ½íÛ·ë9…RPP0}úô‡–·â Ä›sf !7nT(sæÌÑGï0Æ£GîÖ­[Û¶mË بÞM:cÌf³W¬X¡c°‚N19sæLII *~§´5H'¼ R·VÖ»ÌÌÌš5kúøøüðÃez¯ô8P‡£Þ8½e]3’’{{{ƒF?”J¥R©4Ô~ …I0ÆX( ƒ®B]¦GÒéy•ââbC3&‰ šPN´çñxÝŽH$rrr2(oÅÅÅšP•ªMjˆÅb@ gÞ*Ym"„¤R)‡Ã¡û)Yº6KçM$PUZ§C4(((hРAzžéããcÐ1Ž!!!"‘È (QQQsçÎ5ô¼HúüD­Zµ ~òäICì5ô*AAA†F9yòdxx¸JÀÐr®dµiDíT¦Ú$„Ì;7**ÊkS í †aŽ?N¿êyÞž6¤æ;ª  ÀÑÑQÿ(ÅÅÅR©Ôˆ®MC£Pq7è•+‹ x·‹J¥‰DÙ)"‘HOs[«,]Ε¬6E"‘¡M 2Õ&µìŠ‹‹m°6µá2ãҟ͈P(4´ …5MgDAAz m¡ÂÂBCŸ¹\n„¦X¡l¹6¥R)íü¶(¶\›F”³|¶ùVPÜ»wÏЮ‡Þ½{÷ìÙÓÐ I$Û;#šú›7o -´‘#G‘7+”€-׿¼yó¬ðØrmQÎFðAÚæ;;;;C£°Ùl#æ÷1!Æ:shø|¾ Í ck–€-צq…V™jÓ:MàƒdÌ ŽªvJeB¡P(•ʪ\Uü £±U¹är¹=3Ö‡M÷É3??¿fÍšUÙšvqq©_¿¾››[•-:uê´hÑ¢ÊÞ>‹Åª]»v“&Mªl ¸¹¹5lØÐÙÙÙÆóižSËL%ù¨ßêôÆ«x TÙÛ/ý$@¨´bðqØàP€Y^µÞ ê¯zn9kÞühåJ󯯀ØUŒq^^^XXX^^=¢899yÆŒt†ÆøŸþyþü¹>nÆxß¾}†NR-È7–.]ºtéÒÅ‹GDDÐ\mܸQít¯\¹rÉ’%§OŸ6ýzĨ*H¥ÒI“&õìÙó›o¾‘H$yyy ,èÑ£GïÞ½©ŽÜ¾};..®´¥õ•Î6oݺ5Ç+-@šC~t>½ÓlÛ¶m;vlß¾½§§'B(444,, ý»…·OãÆãââΜ9gWLêN`` !$77W¥RåççwëÖ’““C•ˆÃáÐÕõ¥£ÿý÷ß!{{{{{{BÈŽ;BYYY„Û·o#„ìììÜÝÝéñ3gÎd³Ù4$!däÈ‘TK3räHŒ±ƒƒ=”€"‘HÔ«’sssé‡Ã‡/Y²*±*b˜ã1B!´téRͯ۷oWKáºuëþüóÏÒ[K¤¥¥uíÚ•*‘ú×îÝ»§¦¦j†¬^½:!dÏž=‹/V©TR©ÔÏÏòý÷ßS'´Lý¥$$$|ùå—Z[0ÐqqqÔöÔgà àcÜXÀ<ÎAPPЂ èç’’’=zL˜0A=A,—9õºV­ZáááÍ›7ïØ±ã¹sçÔ“ÔÓå³³³{õꕟŸâóù6lèܹs·nÝ’““B‹/~ðàA™}vÿüó]LZzJÃ0tçíÙ³g_¼xjúì@ßÑ¡PH—.Òq€ÜÜ\*Oj•ùâ‹/îß¿?bÄ-Ý),,\»víçŸrïÞ=„PTTÔÝ»w'L˜€1NJJjÔ¨ŸÏŸ4iÒO?ýÔ¹sçñãÇwèÐá³Ï>£ÑGŽÙ®]»2s•žž6qâÄ-[¶Lž<!´`Á•JµeË‹µuëÖ.]º´nÝzäÈ‘7oÞ„>»*ñ Â8`:*•*>>>((ˆ~•Ëå¯_¿V/* ¶ÕË—/322ºvíªQ&“ݽ{—Ãá(•Ênݺ!„222’’’ EpppQQQLL ‹Åb†ÇãµoßþíÛ·©©©ãÎ;#„srr:vìXÚØÄ?yò„î¤ÔªU+„Ðýû÷1ÆöööÍ›7‰‰‘J¥2™Œa˜† z{{C%‚Ø€þ¬¦‰¤ùUÏyöeF)ïWµåXfšå®0eÄà#úì±±±±±±±Ð_ìèã¼¼¼ÂÂB}â´ ­î,ÖÚŸc|ïÞ½éӧ׫WïèÑ£ú$qöìYݧ+Ñ” Åùóç5ÿߪU«ÚµkÃb¬*v¡'NÄÄÄ,[¶ !¤R©ô9Ìc|8 àÂ… zjŽÃº !,kĈû÷ïö왋‹‹ýI*•>þ|øðáiiiÏž=£šU€5Ä®¤¤äÔ©SAAAÏž=ûöÛo:dJêT+§OŸ¾ÿ~™LÆãñÆI£ööö-[¶¼xñ¢]íÚµ“““Á¾ÀBh[R^^^¹¹¹ÉÉÉ999¦:É9r$<<<++‹*úw§µ¨1 #“É ÚµkJ€5ÄŽ²aÆ .̘1ãÂ… 6l0e¨”ÆMHH¸{÷n5ÊÍ‹E)..ÎÉÉéÙ³§P(„ZÀ²n,õ.7mڤ鄚bÖõìÙS$-[¶LwRô§˜˜ÿììl'''¨,(všÞ¥ÖgC¡£ W®\¡¯&EqvvNOOo×®]tt4 V`Y±Ó!Fi‹ÅRŸq§§ˆâr¹êá ¬àˆÆ8%%%99¹Bƒ‹ŠT³fÍè4cƒ‹a˜§OŸ¶mÛ6))©nݺ wX[ìBOŸ>=uê‡Ã©PŸs按ÛPåÊÈÈ9r$ŸÏ?{öìþýû%‰f>Ÿ?sæÌcÇŽ ‚àààŸ~ú $>j°~œR©LJJRÏ®_¿þ‚ ¢¢¢öîÝëíím 9PŸ×Ããñ>ùä“û÷ï›hÐÕ¨Q#;;{̘1K–,Q(uêÔ)877·¸¸¸¤¤$((ˆÅb=yò¤yóæ wP…ÄN; ŒBýõWhh¨EóJ…ÆÕÕ•zéŽ:pß¾}/\¸àêêš——gP"]»vŒŒ$„( .—k‰”ËåºgØ`Œíììà©+¹±¥®®®fŒ !YYY!!!ýõ—³³³þ2Gˆ¼|ùòÓ§O ‡Ã¡¾°žJÇ0Ì7ºuëæëëëää´ÿþ-Zp8S =͸7oÞ¬V­ZûöíýüüÊ Ïb±^¾|SPPÀb±:uêT:3¾T,>bË.,,lýúõV{è×­[çîîþŸÿüGGÿ:?¿ÿþ{bbâªU«""">ÿüsã.ª¾Ð´iÓþøãþýûþüóϦ´ö£GFGGîܹsÊ”) ÃlÞ¼YGø°°0‰Dâèè¸~ýú¹sç"„z÷îl–RÕ,ÉóçÏß¹s§BCM™2Å××W+ú‡R^kÊn™×ݯüb7qâÄmÛ¶Yó!KOO÷ññéÞ½ûÕ«WË|Èèž>}:vìØÇŸ={ÖÓÓó“O>1Ëãøúõëôôôààà¶mÛŽ;vüøñ†6–-[r8œþùçèÑ£uëÖmÚ´©þÑu:²ôÏ?ÿÐç–‚XÝwj‰r0L©>F±Ó,»””„}YY­”©uƒúᇠ²Jþ=J¼¸¸Ø¼¹Ò”~z‰·oßj^Z²¨¨HýO‰DhgggooÏb±>l–\…††ÚÛÛs8œààà’’’¬¬¬÷ïßWK(Ò\åææÒ Löööµk×6Z%íííB4YõÛNŸTP(™™™YYY!šà»wïôiÉóæÍ£Ù¨Y³¦L&ËÌÌT0º„Õ•J¥P( æp8´´éA€e¶Mšíèèèììl 5u‚ïß¿§ŸÏ×jŒ®®®‰D$}™£g~|n¬)~‡¥¯’šš:xðà2Ç=Ìëåé&$$„Näñx‘‘‘þù'}è'?å¯ IDATOžìæææèè¨Î³f®LwðÕå@éСƘÇãݼyóÂ… :NÈ´··_¸p¡\.wuuU*•ß}÷ÝÔ©S®>Í»˜>}ú?ÿü“ŸŸÏãñ–.]*‘HªU«¦O§íÙ³g%É“'OÖ¬YÓ¡C•Jðûï¿‘‡N:aŒoß¾½yófww÷Úµk›²Eã¥K— óóówíÚeggwïÞ=õ…ÊëÉA­_¿þôéÓ·nÝ:wî\ƒ 5jdv':22277wÕªUgÕªU;w.8 àóÏ?ÿì³ÏhåÞUB›Í®äbg;½'V«]-8räÈëׯÕX°`•‹eãÆEEEºK†vÌ©gÕ˜w‘ŒL&[µj57æÌ™3~üx­ äZ¨T*êŠöë×O½¢)Ê{ùòåÈd²åË—3F¡PìÛ·O÷ÍjýøðáJ¥²~ýú<¯Fzvk¦³f͉D’››[PP°ÿ~ÓMšrvvvXXXíÚµy<Þ’%KtßTlllóæÍÇŒ³{÷nkö'Ž7n÷îÝ vUW«B´ˆŽŽV*•ºÃ(•ÊöíÛë°˜L)„G9;;‡„„Ð%ä¡¡¡êcšK³oß¾yóæ±X,™LæååuðàÁ€€uתqÓƒÄbqƒ B—.]2ú©T¤¤¤ôéÓçèÑ£l6[Ÿ÷}~~¾››ÛçŸaµÇcœ””dLŸíÖäƒôÙ€»Ï­‰J¥R*• Ã;vLw+½~ý: ¬ö1½hR4ýíÛ·]Œ5kÖ´··W'¨Oñjö/Ó]/-])4}*µÆ˜‘ÞÞÞ¥=ÀƱ“ÅbÑÕ–´Áë k×®c6›m–‹Å¢‰ß¹sgÞ¼yãøøøääd݆¡úóóçÏW¬X1~óæD"Q{£ú/ CÇñ?þã?ZtS^õ‚ªzh`Ëâk ¦í¿cÇŽ¹¹¹K—.]°`Á©S§vìØQRR2cÆŒ2ÃߺuëÑ£G,ëêÕ«C† QËŸ*LG®èÙÐ&L0ã€Ié EFFŽ9’æúìzuÑÞ½{y<Þ?þX¯^=:^_º³aÆ ÃŒ3Æô®LýŋӦM»|ù²%+è%:wî|êÔ)WWWŒ1XvPÕ­K:Ý!Ô«W¯2' B<<<¦ohºipòäI__ßÔÔT³V`Œ:tûöm‰DBS±¼ÿW777777ë¸Õ4''§ÜÜ\ÿׯ_›]ïÒÒÒ>ìããóÿ7Ô4 †a$‰ŸŸ_vv65÷Ì•²T*-))ÑÔn;>thxçξ¾¾TïÌ’,!äÝ»w=êÙ³çÇR ¸ø°N´¯¯ïàÁƒëׯO·Ô5Kš3fÌØ±c‡¦ß bÀÆÎÎîàÁƒÍš53ËÔ]šÂÓ§Oýüü4S3f€B¥ReeeÁ&…˜‘ÀÀ@ÂÂÂjÕª™¢tt°˜nj«)Sƈ]AAAŸ>}LÉ€–Híܹ“Íf»¸¸PûÎ8sŠî1óå—_ž>}ZkúL*À& Ú´nÝ:‡3mÚ4#ôŽFqqq),,,æÙ`БÙÉ“'Ó½?õ߯JÓðZ¹reQQQ™B Ø c{{û¿ÿþ;!!ýïú˜u¡èèè'Ož”-¦P¾Ø„^½z!„ÂÃà šfLwÃo×®]Ë–-ËôÁÀ¶Œ;„Pß¾}{ôè¡P(fΜ©Oç=bå×_ŠŠ*/ ˆ6gÜ…„„<}ú´E‹IIIºSFÿŽlŒ;öéÓ§Í›7/Oa4[Ô;õîºg¢ÐŸ5j”’’"‘Ht„d•މ*))‹ÅPâ|@g¶zõê999;wÆ—ÞÓ˜ŠƸM›6¯^½Ò­tÚbGƒÆÆÆ¶k×nذa¥Ó°¦ä¹»»¯]»c¼sçN-!«Tª/¾øâíÛ·ô¬ Ý]{­¤ÏŸ?ýúõøøx„J¥¢;åÓŸþþûï .Ð#æ¬ã϶mÛöîÝ»;v|ùòåúõë5íß¿llì»wïíq¶nݺaÃÇ0LhhhQQÑåË—/_¾Ü¨Q£“'OjŠeƒ ¾øâ‹Ò»'oذD` ¶C‡III¹¹¹mÛ¶upp ?)•ÊÜÜÜÔÔT}“’Éd2™Œ¦(¾þúëiÓ¦5kÖ,>>~Û¶m{÷îÕôpËË ‡ÃQŸp `!JJJ4¿²X,=;Ù8<Çã©¿W¯^]"‘–””¨´BÑÓÓSÏëaŒsss]\\Ô²>PEvvv6¨\²²²¼½½õ?« cœ••U£F ƒ®"‰h‰ë•ŒŒŒZµj”±ììlwwwƒ– ŠÅb†aè¹úóþý{///ý»hY,VFF†——WÕ¬MjäææÔ*Sm"„Š‹‹íìì 2wŒ®MCíªÒ:Pv̘1]ºt3fŒžGØúøøtlmHHˆH$2(JTTÔܹs =W ¥V­Z†F §þ¾þÐ³Ó "((ÈÐ('Ož ·B ZΕ¬6¨ÊT›„¹sçFEEÙ`mj¡=@AÙ½{w…®«&*•Ê yU(¥kÓýêJ¥F踡QôÓ)ýʉD–¶ÞU*•H$2èÅ.‰Œ˜?dġņ–s%«M‘Hdh¨Lµ‰’J¥ÅÅÅ6X›Úvk™Ýú¸®F#‰ ­¥R)‘HLtïõ¡¨¨È ý†¶ *†>r¹\&“Ù` ØrmÊd2¹\né°åÚ4¢œMïz³Î“i†ÞÞÞú+ºq{T—6"Š¡·¿jÕªš5k>ܦ2fµBC ý­![®Mãò&‰Ú·oWiš€¡9 ëÓ§OÏž=m­mV`ÙY#r¬ŽbP\؈(Ö)KgÌj…V™jÓ¸¼U¾&`é†ð¡Ú¦ÄÎ =V¶Œ\.W(U¹¬ãøØ,„*Þ¤R©=3ÖÇ Ë!þüóϪ\ÓC‡­âsªÏœ9S•oŸÏç«Çôª&“'O6tŠÏÁÔ>;ãœüÊôV7¢3¥ò•@•½ýÒO4J+v°-;`ê‹]óC™_õ|¡؈–—gÄôra.\8{ölºßÆxöìÙ .Tû¶ô³^^ÆóçÏ7Ñ¢ú5zôèÑ£GÓY¸ã'Ož|ûí·èßõBãíÛ·ËårŒñëׯÇ7fÌdÔ\à#{^Àhf̘qòäÉ . 0€2jÔ¨ˆˆˆãÇ=šP?cZKU*U鯱±±¥ÒŠË0Œúk™Ë£¢¢îÞ½Û½{w†a^¿~=zôèGuêԉطoBH(fgg2äöíÛwîÜ騱#ÔfåÄ0*4]»vÍÎÎfF,S¡‘ËåT­&Ož¬~§Nž<¹t\'''ºcضmÛ!,«uëÖê…,‹nžxóæMµ¿¹k×.µ†Òs”KSRRB?¸»»3 =dÈBˆ££#!$22ò—_~iÞ¼¹P(LIIùì³Ï´D±m4—QBV¬Xâr¹š6Wy–Ý'Ÿ|’–––ŸŸ/—ËÕÖÝ¢CmÙ={vÅŠ4¥R)•J¿þúkjý988üòË/:òöÕW_%%%Bž>}ª;¹\îííMiРABB!äðáÃÔq¦'+ vP¶e×£G’’µkI÷óÐÔµ2ÅŽÊÙ!Cúõë7vìØW¯^ÑÿS%¢¿îÛ·ïçŸV'2`À€=zܺu‹þ'""âùóçååjþüùwîÜ¡ÿyüøñ Aƒ¨åH éÙ³§££c‡Þ¿¯¶%Á²«ôÀ`$Ô ÊËËËÍÍÅÓ¯ùùùB¡PsaÇŽ}ûöݹs§æ?Y,Öüùóù|¾««+Ç£û 4(##cÿþý,ë‡~1bD^^^ï޽߼y³wï^GGGwwwõb•>}ú,Z´¨Ì\uîÜù×_ݵkWïÞ½ !õêÕ«[·nß¾}W¯^ºråÊ¥K—ÜÜÜîÞ½ëèèØ»wﯾúêË/¿Ü±cÔi%b Œ¾&’’R³fM.—K¿&%%Õ®][½w?!cüôéSOOOooo͈oß¾¥Ý|Õ«W÷ññAÅÅűÙlggçZµj½xñ‚º®*•ÊßßßÑÑ1&&cìãããêꊊwss+s›ÉØØX.—«R©T*UPPƸ°°ðíÛ·-[¶Tk´:Ÿ"‘èÍ›7!ç v àÆbbbbbbbbˆÝÿ@T$%%¥§§ëŸ˜¼é+,áÀ üÏr1º6ðüùó›6mòóóÛµk—>IüñÇmÛ¶Õ­hc©Tº{÷nz½n—.]6lk°ªØQåÊÏÏŸ9s&BH¥R±Ù슓ÀxÔ¨Q¿ÿþ{y†a±XcÆŒ‘H$;v¤W`ŒcbbŽ;–œœìææ5€EÑ>7öÞ½{Ç_µjUãÆé±úØ\vvv:l:‹zúôéÜÜ\-]S*•îîîTp©&B•` ´Å¥¸¸øöíÛÙÙÙ›6m2dˆéÞ%Æxüøñ§OŸ&„ÐÍy4upÿþý„@P£F P:¬'vþþþ‰‰‰>|õêUƒ LL]¥R-\¸p×®]yyyèß­Ä4ut"‘ˆÃá#¯À bGY¾|ùÓ§O·lÙòôéÓåË—›"=„‘H´lÙ²„„-›îrÀbBÒÓÓýýý`¤K =@¡ÙI§g‡Æxâĉ۶mÓü'í€k×®““Óµk×ôIª  `ÆŒ7n¬V­T æ…SZ¹Êül°ÅÈbÕ©S';;[}Pq…f`õêÕB...ôt 0ñ° Øé#CÕ'%%…õ¤§yHÙ»wï«W¯ègÐ;>€ØaŒ_¾|ùüùó ÇL©H5hÐàÓO?5È<Ä3 s÷î]Œq\\\`` èÖ;„Pjjê½{÷*œfŒ1¾|ùò€V­Ze¨ZQ%]±bE³fÍ.]ºÔ³gO¨!¬íƆ„„„„„”þiåÊ•ZfÝÕ«W{õê…Œêõ#„üôÓOnnn;wîìÙ³'w˜}çñê©8ã;wî¬^½ZŸufå¥@7n\›6mŽ= J€UÅN»,--mõêÕÁÁÁFÏÑ£ççç7lذÌÌL˜f €õÜX=•!ôÓO?½{÷ÎD÷“òÍ7ßäåå:ujòäÉàÌ`Cb‡1aÂôïÄ`óâçç;tèÐC‡q¹\³hÕMŒqxxxNNŽ–ŒÒK—.Õ ÀG 6´ÉÍÍíØ±£zo’G-Z´èáÇûöísww·„ñ…1ÎËË£{›®;4…”””ÐÐP>Ÿ÷îÝ‹/Ò Ô888Lœ8Q 8::†„„,_¾$ªœØ1 “——§nööööR©4--­V­Z–È¥Zeø|¾D"1ZtÔ$É´iÓþóŸÿÈåò2Á‰DR©´¤¤¤N:¡'Ož´lÙôªËb±<<<4ÿ#•JÏ;g!¥CÿŽÌB$ •b¨EMB…BѧOŸÈÈHooïÔÔT݉@@ÍÉõë×·mÛV¥RÉd2¹\.,q›EEEJ¥RG6›íââO-Xɲ+­DnnnçΣۜXšÖ­[çääÄÇÇ;99dÍýúëÿµw®AMmß='„¢PƒD…AÚz×ê@é8Skk±UZ)¶S/R„Z V§S:âë¥8EÐŽÓVÑj½Dª¥¶Uª@AZÄK°ªn$r’“ó~Ø÷Íd 9‡#ìïS »{ö<»ûϳ÷ÿlÙ²eæÌ™•••è„;‡M)ÄÅÅÕÖÖjµÚýû÷ÇÄĸ¹¹ ÄÑ3ûã?Ž3&66ÖÆ”A\¹r¥¨¨èáÇqqq|>zÖlE°«‹Fb—’’’í„zñÒK/ݼy³¾¾^(ÚÐ,S~²³³kjj$É‹/¾¸`Án6=(33377÷ùçŸÏÊÊHƒ?pàÀ•+W‚ðóó£išÇãeddØ¿uëVNG’dkk«^¯°žÛ "ñ-**²]7hš^¼xñ›o¾iݰJÖ™ÊÛç³°ô}±³>–}PQ«Õr¹<))©··÷êÕ«}V2ôŸªªªøøø†††òòò¹sç:ª:666vvvN:5888)))55•mó äóùuuu.\ðòòš>}:«èÕÕÕZ­V¡P$%% ¹\Îãñ¸)Žy²Ó§Ooooçñxuuu>>>¶ûÔçÏŸÏËËãóù¥¥¥lðæ‰$%%ýúë¯ýjbfffBBÂà)¯õ{}þùç?üðú¬×ë/]ºìälÛÚxßQƒYðÁ0Î~lz4 99ùqìÙ³E1è Puýúuô”ÖÖÖ>shñçŠ+Pø9sæ0 £Óé8äÍ}X²d J3&&†› €ÙÀ(EQ¦ŒÙ b"S£èeee³‡zeJV¥RQ6)**2UéñãÇR•KNN¶h>ÿþû/EQ ÃlÞ¼Ùâ+™Læ;ô[|ååå}6mÇ8Ûo:v`ÅSéÙ™ÿjµ´´[ßÒ&RÓ¹HMM=|ø0 ££#111##C§Ó™¾õòò;vì˜1c EQJ¥mv¸4jÔ(www¥Ryýúu¡Ph ‚>´µµutt ÏžžžóæÍCW\¾ñÆàì ˜çaéÒ¥þù'EQááá†$É   Û)´··£œÈd²×^{ÍÛÛ›¦éqãÆÕÔÔpðnÆŒCÓ´Z­.,,œ8q"@,£ ÷~mn€¢¨††!ŸÏ  …:®®®Î××·_÷jÛ¶mYYYèæ<™L¦R©BBBÐÜÚîÞ½+‰^ýõÛ·oóù|š¦wíÚµvíZ‹(AAA*•Š$I¥RYRR€¬áØæ`J­¡¡Á`0\¼x155Õ¼ú¡áf¥RÙÖÖÆçó===ßÙ×h4#GŽ|ŠÅÎEFpÌŸÒÜܼzõj¡ùs†‹Å‡rÎ[gee•”” ÏîîîR©tïÞ½€#F¤¥¥EDD ©d†a‚8{ö¬me.”¯¼ò @ H¥ÒƒÚØ1íîî¾cÇooo4ÅÿÎ;ï,_¾Ü!Ê»~ýú†††‡*•ÊM›6©Õê?þ¸ßÊÊʪ««ÑXÁÑ£Gccc{zz~ÿýwÎê!üé§Ÿ¾üòK___“$q0øµk×***}ôQ\\œN§+,,|\m77Ý~ûí·Ó§O:thÆŒaaaŽ­ü2™¬ªªjÕªUK—.?þ'Ÿ|bò­·Þª©©VTTˆD"ç®BÓ2Ž!)v.¥­ÎW^Ä/¿ürÿþ}ó’r²Y>lÏÙï¿ÿ>š_v¸ÏKQÔ·ß~‹ºuR©Ô¶zòùü3gÎlݺy‚ÑÑÑ“'Oæœ%S¬Ë—/߸qÃ`0œ9sF§Ó9rdüøñ¶_ÖüÿF£1&&¦¤¤$--m„ ãÇ_¼x1Û<Ÿo#)ÓW===B¡pîܹåååN¨HRÑIq\&( Ò8SÍ™ÌSiœ¾­­Íä.Xƒ¾º|ù²cG÷Mé ô³³³iš¶óæ“ih˜ÝòÌaz ðꫯö¬JÜÛÛå“‹éïïB` ƒaÕ2M¤˜Ú¤5è+4k|®ÅÓQâUUU¹¹¹$I–••ݼyÓ†SfŠ[UUõý÷ßCoݺ¥×ëU*•Ñhd•74t¦×ë ‚P«ÕƒêÙAш-Ê'^ƒƒÁ<âèØ4†™1cF]]]vvv~~~DDDffæ–-[ú ÜØØøÙgŸeffΚ5«ººúܹs¦¥ÆÝ „<oÇŽŸ~ú)EQƒj½eË–­Zµ 哇+3l5”a˜””À’%KÁÚµk ,Žärù¢E‹V®\iºÍyà—Ì„††>zô(,,¬¾¾~ðëõú]»výoBOP`0ÓriµZó%¢æˆD¢ÁØŽ ÑhT*Õ`¼WNNŽP(\½z5ú{v öòþ'^ý^«àØÉ<ðööFžÃ'gÛÚÚBCCMâ1; óÄDÖh4*•J’$›ššÒÑ4Éhmmí¶mÛLÛ‡°Øa0˜' ª[·n]PPÐ;w8é¼qãÆ„„„Y³f™wc1Ì“„a˜¼¼<­V{ãÆ ne»téRSS“y¿{v æ wf‡ÎËËknnxO¥àáá1jÔ(óÔ¸xvƒA&“¡m+ ã"##ц…ÎTtuu™¶v˜¯háqK+%%ÅÎSÑ1 Æw,;;BxäÈ‘„„„è]PPÐ{ャßh4._¾Üh4?~ÜÍÍ-,,ìüùóæbÙÔÔ¤P(¬Sœ1cFJJJvv6. 3HPåîîþì³ÏÒ4þãîî^XX(‹íܧÑUFH‚ˆOOOŒŒ¬®®Þµk×±cÇÌ{¸6Ô×þIb ƒáàåYO˲’„Ð\%‰B¡àóù …bܸqŠö8ÂÂÂLrk‚ îÝ»çç燮&²“îîn­V;vìXûQ[[;yòd;3 IòîÝ»AAA¬  ½½ÇãyzzÚit‚ d2™ýC«¯¯ ´« „°³³Ó`0ˆÅbV?Bõõõ!!!¬ò&“ÉBCCí/š¡TšÈ¸wï^PPyb¥IDkk«‡‡‡õ5=/Móc‡¹`}§ì† âââ6lØ`ç¶hº×~bccÕj5«(ééél¯È‰Dl£Œ7Žm”œœ©TÊ* I’lŸ2mÚ4¶Q¤RiNNŽ,ÀÖÎC¬49”ÎP*M†aÒÓÓ+**\°4-°œ `f÷îÝýv]ͱ_žz½¾££C$Ù¥«««··—ƒŽ³‚ÄÕY ÝÝÝf°}xš¦5 +£i4šîînl;±ÒÔh4l›ÀP*M@oooWW— –¦¥GÙçœ=]WÎtww³-š¦94­VË6ŠZ­vÂèÛ¶ê:Ûú¡×ë9Ü@ì ¸riR¥×ëÛ®\šìÌ'Ò6pϤI“är¹ýŠÎíŒ*¶qQ`QؾþÎ;ýüü]*cN3@$Ùï ¹rirË›F£™={öÍ›7‡L`›ÃÔÔÔ—_~]žíRm³ÏŽƒÓ+—Ëí÷Ô8䨅U\˜C”ÁÆ9sšÑ†RirË秸¬Ñ»!<©¶I8$ßÇ+t::>®Œs:>. Ã0ÎýpYzzz ƒëçÓa·Ò[îß¿Ïçó}}}‡­JKK,X0l_Ÿ¦é¿ÿþ{æÌ™ÃÖÿüóX,=z4»!þ«Îa0eèY`ؾ¾uMÀM‹ƒÁ¦éeË–YK„ÐÏÏO¥R5440 ãïïïááQQQ¡R©P€®®®“'O2 3{öl@TT:³{îܹƒ!==ýÑ£Gr¹s wc1Öž]FFFNNNFFI’ñññF£Q @÷ìÙƒ>tvv’$©Õj­2?gL¥R]½z•ÇãI¥Rë/MÓÍÍÍ+V¬ððð‹Å_|ñ…H$¢iZ  #GŽÜ·oí´×ëõ›6mR*• € .¬^½zĈÁÁÁ[¶lÁ‡=; †µgwðàÁ³g϶¶¶¶··‹D¢íÛ·oÚ´):::00P­V£s½hš6 Ö›. £££.\(—Ë—,Yþ\‚õ I’ÑÑÑÝÝÝ …B(’$ÙÛÛÿõ×_£ ª¦ý *•Ša˜}ûöݽ{·¥¥åÑ£G===111F¡PøøøàR^UÏÖcEgg':ê‡$I4]ÐÚÚJQ”D"éìì¤iú™gžiiiñööîééñôô4÷ !„<@~™—— ©© %b É0Œ@ 0Bww÷ææf???@KK :"´±± ‘HÐS‚0x‚‹ƒÁàn,ƒÁ<…üþ~J‹Â<¥DIEND®B`‚snd-16.1/pix/fmeq31.png0000644000076400007640000000152511147553267012753 0ustar bilbil‰PNG  IHDRX~ZR3PLTEÿÿÿààà°°°ÀÀÀÐÐР  €€€```ppp@@@PPPððð000 * ô¼ pHYs  šœtIME×6#07µIDATXÃÅ—‹’ƒ E*úÿ_»<[¢Á–]e¦OMî1$ë /ÙaåÛY¯üy=æ tÊßÀ%4³>Eàf|ÍøÁXò)^4ÛÉîèù‹Ù2×O×a}ˆ@ˆC VS« 8ÌKš¾Éžâ/F¸’‚DêðÁce}Ž +'Kfkac·æySJ㢀æýS]WÖÛ ¸É¹V1øÊƒŠ:¾ /!ç`Vð=â-MÊeÊóÙm[‘UÁ :2—¬wÈ`¦€‰P‹ÜÍ* A ifvªV›íFÆÇ"çÆ5×IÏg·ˆ«(XMFæ‚õ‚ÐPÊ»ÄJC]k݆t#Û ŽŒX@Ṧc?aÚf—´Ø­Q3uÍœu…ά ·Dh›=Ò"0®á¨q²Þ…jÃ|u Ò6{¤ D¼äºK£À•0n “6‰G1L'|ÚtÔ|¸¥>ióÿ÷v“î :pË-•~݃!%$Ö‹­H¾«èö¬ÞΕ½ÿÁ‘Ç m!$Ë %}È™ï9§œªÉ>Z9 RB2¯$Q¤s&<æÝìè+È>à"´LV‡ $FÝÁàç¾Òk(§â9îô>É>à"´0HAI11}ê‹MýÉo=)…ò9î¤,-“½ÝEhaÂ’ä3ÌŠ0†týI*®¶ itI(Éuˆ·Ú±F¹a¥ei™ìí.B ƒ†ä„¨™¯cHAןð$¼ô"H¡KRPj¶jŽPMYM{²´Löv!UMˆöÁAHr[ûD0¤ˆëO¢³­¶Qsäñ².WãAgY¢ ¢— ~O––É^謂g0ƒ¯Ê:©›uß•Çf=†!…]za#­°”õÍ^~tÖ>²ªõâ­¯wÂl¨Ùº åÈ^˜uÆm uYç^Ö=iÎz C »þôÂF>F¡‹½‹éÂÀÔÉþ`Yú†¸ÙP ¯çÈÞé"d$›õ „4ûÄ0¤µë¦b"ã ½k)£[‰£K&!ÆwŒ¨ÅŽîÉÒ2Ù;]„,ƒd³„dŸÒ+"ÒÊõÇP1!¹y×RF+ÄÑ%=VÁDµBh€$-KËdït² Ò|Ç‚FkìÃV®?xŠ–ì6ž¥ŒRH Kx"\ 40Gêú.dq»+KËdouB¶Â›¬‡ ¤ÁYÆ|ן³ùx–2ÃΣ3SO9²´Lö ™ÑžëÞ¼íi8²Â9ªÎ&•AŸ–2G-|’²¨Höa¡ „d¤‰•¼«èÞx¬¶³GewZCH3ƒ”4ö9ãús‚rª%ûÞ q1<ã€hæáæ«×Çc¶ æxò¤Ø“|f@²Y½åb2?-O©WÇc6Ç‘ãÉ“âa p• /màb¼½=€ÅxsJùêÕñ˜MÖs£å>%\Œ‡µÀbÖ‡›©^¡¡²ŽZLRž<)&‡1ð.†úk‹±˜õáfª×D¶ÿŽÊ”‚4¤£ï§|bJämÖ7m´/´]¤o¢þ0cƒÞÍåþ0zTöeùÄ”ÈGû:ëÉvQXÒ-3ê©ö:þ0ñš®üòضu|b¢Y/‘÷€˜ÊuÝáat•®áÇ$Õ×ð³­ÏUñ‰‰»ó”ÈÓ ¯¦Ž?ÌbJýa¦¼}3g[Ÿªâwç)‘Ù…cÃÃd:r ˜†¤Òæ)TÅ'&îÎS"_úÕ…#AeESû^Á¦èU¹PŸ˜•<:$ïï º&눮ŸOTð‡)¨’OL ù»€nwü~˜ÒÏêÿÄ\ï³U:½ÓgåKvå[‡‡*ÆItKIEND®B`‚snd-16.1/pix/scanned.png0000644000076400007640000003742211147553270013271 0ustar bilbil‰PNG  IHDRÄ ¥è”Ü pHYs:ÊduhtIMEÖ "5„:.v IDATxÚíÝyXSg¾8ð÷dƒ [ØwYEÙ\pÁÜpÁ­j[mÕÑ™vèŒmyæ÷Ü{¿Î}nçÒÎ3JÛn«µÖjkÕRÀµuAAA@@Ù [X²“íä÷Çñ¦1,Fïçá“—““ä{N¾yÏ9ï‚••+ÕJ4 ¾€!ŒÉd"0Wœ6Ž·Z­m…––ŠR­Ì—æšLûø^d/Uј-~ŸïÌçãüÑV¸Ÿ}ŸB,áJ\Ì_C2(Q2”Â^!D`¶”r¥dP"” ­í­IBèy2óÄÖÖLgÝÓy%]élãL’ š€O!RÐôáW>)nK¥¥…ÂB7CŠ”*{•)~K¦!¦3Sä.Ò­Ürù49mx9Ì<eþ³ýEªa™°Œïíë-ÂuË…åB7š›W „ Ê ŒÝ£oA€1`‘Y¾T_oª·7Õ›É×=§è<¦KÕR„J¡êì€ð©Tq¥‚B£8x;HùR2•ìâúèÛG= =‹Þ\ÁSÉ…âBÇè­ÜV5ë·;øŒÒ©ì”«å¡Vv«O´ÏXÉ´§·§œ]N$Sk{kK¦%„L a°»®ÛkžWííZÖ,Vw}wãÃÆe¿[vïŸ÷ 8`Ša+,)”«äÞ,o=Ÿ¢›Ly¶<ítËçò!¬`ÊÌ^=»¥¤!ä·À¯§¡‡B£ˆÄJ¹"¦X—²Ë5Âux¹\"—á2„®Ä_’L˜. g·†ë6ÛÍÎÍÎÒÆ2tm¨£¯cEN…oŒ/¾ŠßßѯP*B '†n2å øü>¾dP¢¤+‡×CEý"¥­ê§`j¸¹ ⱕ•tP´,ÎÀ”Q )Äýb¾T÷xSÈ¢~ÑÀÐÅšBùß:(ŸËÇe¸¨OÄ—ñÕ¸š‚!Ì‹â¥bª<†œEºÛ¶@L*Ó_èQÌx4wIHòÒM„îH€dr™N¹Ô^!"Ë™&σGa2™ª@Ø+ôàÛ¯\¼¢ zzðäq—=G„‹8\´3€d “™LáG¥¥¥HK;ÑÛÛ‡:q"ƒøWWW÷þç§ííz5é?þ±‘›7ok ïÞ}€jhh¼~ýQ‚ã¸L&m#lvS[[B(/¯Çq¡Pôõ×ßãÓ>~\š–vâïÿ\*Òù—T*Õ,·¶¶ýüóU88˜ñˆ\„ãx^žîàyééÿsûvž’©H$öóóIM}/5õ=''Ÿ/ظ1ø—««K\Üü®®žÿÍtÍlv“P8rÿýööb# «ˆ´ØÒÂyü¸!D§[FGG"„ÔjuQQÉgŸ}ÙÞÞ9âFz{ûš›[BÅÅOpZ³fñ/¡PÄf7566#„x¼A¢P³0ÿüˆŸ…ªªZ§½¡¡qÄ,Z4ÿÑ£b„J¥¢P(Ü´´ãÄ¿NŸ>WQQùäIÅ•+7¾úêŒX,„_}uæ¥AüÛßþqëÖŠŠÊ~¸Üß?ÀåvUTTö÷óB-Çÿ‹X-#ã늊Ê_½WZZþá‡ÿ‘Ÿ_XQQ™™yåòå슊ʊŠÊ_~¹G$&ªªª6-íħŸ¦#„~ü1“øRÿýeíuêêþýßÿ«¢¢ò»ï.ŒVQCc7Úß°!á7vËþþ~aa³‡¯S_ÏV($I,–Œ¸ww×ÔÔ÷4ïéÃS0 kmmC­X±”øY “É6$P©Ô+–Žöf<<ÜN:›˜¸!4o^¸·÷ó¶ %%eCCC8Žú#„ª«kG«#ëpttxóÍ×Bii'fÍò MNN"þµt颇‹žˆBINNªªªinn ˜µgÏvâ)IIërrrB ÆÀ €‰š3'$5õ=¥RuâÄ¿*+kìííB––ºCímܘ°~ýÚ³g/H¥Cöö¯žLµ566?{V•“s=)i=7˜—W`mm •a¶`ÁÈ9e`€wéRBhÖ,ßÀË—³•J%Q3½sçþ³gUÏ""Â---z{{Ïû1>~‰——Çðíú_»vsçέ¡²²§ÏžUݽû`ÅŠ¥±±‘nn®$)99éܹkjêI$ÌÅÅiÄ7ciiqéR‘yóòò¿ýö{+++WWg„PppÀ¥KY …rÏží<|ö¬ª¤¤,&&R©T^º”%çÍ ¯ªªÕlª§§oÖ,_„P];>~ ”˜º°°P Bhõê塜œëÏžU—¯^½!KzzzéôQ‡+ÁJ¤%ùÒ|a¯0ºwöºÅ«5ÿP*UR©”Á°!òù‚¾¾~2™ìëë-“Ɉ‹›ÞÞžT*µ©©E­V»¸8ÙØØ ®®±XŒb2NN¬ÆÆf …bkË´³³íèè’ÙÚÚ²X¡žž^…Béá1jÁA¾-qÍÏXZZzx¸ …¢žž^ ÃfÍòU(r¹œD"‘Hd"(:´WNK;ñ曯‰Å//Fü`89±˜L—Û%‘H‰7<0Àãñi4š——‡æ ò ›–Qõ¦Óép `Šˆ/µZø|¾µµqwÄÓÓÝ¢¥…£R©X,G§­¡¡1""œÁ°qv~¡¢öàÉãzŽÝÿêþ¨5Ó¼¼ü'O*49àïïG,[XXh–‰*çháñ¿ûî‚æáüùÑññ‹µÎÜݵWÖy—Ú.]Ê"2BˆJ¥¾÷ÞQË‘xÈ`Øh2>•J¥R©£m„ÍnÒ¾Gommåêꢽ‚æC¹¹ý6Àƒƒ½ƒÃój=‘I5 ÚA˜œ¦¦–Ÿ~ÊÑÆX0­­­žžžd2!TVV¦R©bb`„@¦Âx®»ñxƒ™™9™™9"‘"hŸïÞ=ˆ FšLü1366:66úûï/!„NŸ>§Ï³ô\ Œ[ccã²eˈåüüüµk×®Zµª¨èù(×yyyiÿëÈ‘#|ðD ÏM çÌÌœ]»’ß|sOiiynî/B¡0!auHHàÅ‹?s¹]j5:zô­ŒŒÓ†Ôj”œœôàÁCbµ””£ôI²jÕªªªªÑþO,geeeggCĘædºnÝKK‹ ~b0l6lHX²d!‘"•J¥R©B=~\zøð~ C))G»»{ Åž=;z{û “N*>Ÿ/‘Hx<‰Dš;wî“'O(ÊìÙ³!2éiþ·ß~ßÚÊY´(¶³³ !Ä`Ø´¶ròòòŸ=«vp°ß²eƒöÈþ..Ξž!‰ÔÚÊ!fû“áÖ­[×®]khhX·n]___{{{RRD#­™îÚµíÞ½|„1»Üo¼võêÍèèy^^÷ï?,+{öç?¿caA[·n­ö³6mZWVölË– ôI²cÇí‡k×®…˜`ÔÉÔÎÎV;'R(ÍÃeËâ4åAAþÚÏòõõÖLf‘L[[Û´GóFB :::@0dªRÉìíí ™!{{;kk+ˆ¦‘LÕj5“É€ÐÀ„’)‰D!“a`Sc¤V«•J î€É$Sè›oœ^Ú7`DÉô¥†††š›9!?Mß:lcc³¯¯71˜.999555UUU°#0¬ñ4Ú¿t)›ÃiãpÚ ±š@ š£::¸8ç§Ó,)))55uÛ¶mÄÃöövˆ ÓV3xýõ]ÄrK ';û:Bê  ooÏ;wà¸ÊÞÞîµ×¶ñÅÉúúÆ®®îÝ»“ëëÙ99×£¢"¨TÊÙ³?¨T*@-‹cb"­­­rs]½:þÂ…L‘HÄd2^{m»¥¥%ìžÉÓÞÞþí·ß–––þéOòóóƒ€0 5SmW¯ÞxçC))GëëÙÈßß/%åèÐL¡P>¼Íšå»w'#„‚‚ÂÂB•J%B¨§§79ysJÊÑââÒÞÞ~…BãxWWwG·©©ÅÍ͵ºº®¯oöͤ²±±IHHHKK»rå D€é©™jTT<Ó)qt´×)éííS(”î*•:ZÓ«ÐÐà%K-Y²ÈÅÅ öͤ²³³suuU«ÕCCC ¦§fº}ûæôôŒôô ww÷ßýî­þódzzÆÊ•ñžžîî!âtÞÑÑÁÁÁþ—_8Õ׳ûúúÏœ9š??šØÎüùÑ;wnÉʺvêÔÙ¹sÃfY[[]ºôóÓ§•p{dj`öôéSý6•HKò¥ùÂ^á2iL¸÷l„…b©TBmÅišFÙÚzLdB=b<Óo¾ù!ÔÝÝ››»ÿ~/¯D$êâ‚ëê{"\tÿ«û#!!t'5Ê'¦R ÜŸÂÅÅ¥»»b ÀØ7_Áã B25NößfLLLqqqll,„\.×ÍM¯n2#öÍWùøxA͇»»{CCÄJ¥òüùóï¿ÿþ8“)†‘I$¸ÿc¤p\©V㦀T*µ²Òwœ¶’)™LÅqœå!'“É Þn, 77 €ŽªªªÐÐÐñ'S„Ž« ŽFyÒ¡ :>ŒÛˆ}ó©TªB¡€ð #///55uBÉtl?ÿ|•ÃiCú¯_¿¶  hñâw“”””””S=`pãI¦ÝÝ=Û¶%¹¸8ÕÖ6”––Ÿ8ñ¯’’' «ýü¼/]Êêïð÷÷KL\™y…Ëí²··ßµk«……Ä0ƒ§Ô®]ÛŠ‹KOúÎÊŠ=oÉ’…))GCBŸx𨨨D»\¥R]¹r£´´<''W*• ð~ÿûc*• vÃŒ±víÚ[·nA0L2½xñç7Þxmçέ……ÅÚå|¾@(mݺÑÅŹ¶¶!?¿0::‚8“°Ùlˆ07 …‚J¥>™ê))iÝ_ŒŸÏg2™†O¦ÁÁuu |¾@³õ¬¬k …ÒÂÂB.—!„`ÀXÉ4!aUsskf敽{w% 8Ž[[[mØžž1{vˆ··ç™3ß …¢Ï?ÿª¢¢B €Æ¥K—Ž?~üøq™LÑ0 ¼•FëNŠaXbâjí’>ø#±àææš’r”XÞ¿ìÓ"“ÉT*|Ã'›Í>vìØÉ“'¥R©……Äø¥¦¦>™‚™êîÝ» OŸ>…PLž––???_PP°aȉ9 ŒXy‘H w¶1²±±žà¿ÄÄÄÄÄĬ¬¬ììlˆç$éîîvuuE………]»v ’©ñS«Õ“’L\zaëR©”N·V8Ôßßmˆ·^ŽJ¥††Î†ÖœJ¥mµ‰žæ{zºá¸\»¤ººÎßß¡¦®«k`2Ð:jjÐhÖÖÖ*•B€‚¾ùXqqqll,ÄÁ„ÔÔÔŒ{€}H¦L±Xlmm q0!ׯ_Ÿø¥mH¦`#_3U*UDO'­åÐÐB/Œi¢P()2ÞÞ^'''ÍÃ+Vܽ{wÅŠsL¦4M  ôkÚØØvvêŽÈgeÅpqq&‘ z;H$²Nk `„~ëi=þü´´4H¦ÆÌP¿v#$Ó  „'DÙØ¨TŠ)x•¤¤¤ìììÍ›7CÀ9¨®®~óÍ7 PÝP‚a¿¦Aõõõ`&¤R)NŸ”š)˜Á ÛÚÚŠ‹‹!“äÞ½{»ví‚8˜Ô ŸZìC25;~~~NNNýýý½½½É088hggq0999IIIٜ曢ç8@(ÚØØ@2ÀÄÆÆ>~üâ`œÚÛÛ½¼¼ ™ãÒÓÓÃáp̹šÃ`0t £¢¢ÊÊÊàð˜ñ ™ƒùøãóóó?n¶H$VVVp$˜Š²²²yóæA2“ðq<«¾¾>>>~Ïž=®®®"‘ÂŒ_gg§»»;$S0ig+$Žã¯ú¬ÁÁA[[[„•JU(F§ùLÈÎ;/^¼qÐ`0â`„‚‚‚ ™ãRPP°dÉ„Ýàà y¡ººzø°˜d2y5}0d2™§;„d C.—Óh4ÍCµYÎfóøñã ÀÁ`ÚÚÚ Õ(êÕ’é£GÅŸ}ö?Ã'Ú“H¤Ÿ}ö?=F)Šóç/fg_Çq\­F7nÜ>}úœfVa©tèÞ½|Ø…Ókpp°««‹Çãv³J¥R»CÞøna0•8Î4$Óââ2Çß}÷w§N}«ó¯S§¾}÷ÝßḺ¸øÉÅ‹?¯]»jîÜ9W®Ü¸y󶯯÷Ž›ÏŸ¿„ E—/g—Â.œ^7nÜ0x³Ç¦¦¦Y³fi:88ô÷÷C´5æÏŸíöM}}½/˜ê›L[[9¾¾^† ?wS«Õ†ùúz·´púúúœýü|ZZZëêêCB †P(ׯßJNNÒ> Ó">>~ÿþý+W®œÔW9xðà×_ ÑÖðõõmnn†8•žž—i8ÍŸˆæf›Ýtòä™üüBØ…3Rww·aKS„ã8 ”n*ZZZ|}} »M½FZ½zùÕ«7étËààçµâ?ÿùÿ>| $$0$$è§Ÿr¤Ò¡Z[Û~øá²R©Ü¼ynùí·ß[ZZ.XûÏ„lÛ¶-33sÛ¶mz®ÿðáÃÔÔT3šB¡ P`6Ó ‹ ÞWM¯}ogg»eËoÐË˃(ùË_þlkËD%$¬jkë°··³±±¶³³uss¡P(ö¡Í›7H¥Cnn¿UXØ{Ñ$ÀEOÃb2™B¡â`þøc__ߦ¦&ý“é7ß|wጎãúß\5ði>Žã*•\ûO$âK¥’a…©T {ËÜܼy3!!A§ÐÚÚZ,›è'***Z´hÑž={¨TƒÕ ¢££KK¡ÓÊôkhh˜Œ-Ã5S0[[[>Ÿ¯çʺ§<ŠR©4Ñß××çää„Ú»wïùóç ²MGGǾ¾>8´¦]VVÖÖ­['cËÐ,μܽ{·¹¹ùÉ“'/9,(•Je¶Qª¯¯_³f BÈÝݽ³³›£²²rΜ9“´q¨™š—èèèM›6ÅÆÆB(ƨh³X,¢ëóøÆÉFëÆú_7LÍ”D"“H¿Ýqä···j¯ ЍT KË®(‰Dbkk+èQ7Y¿{†,Ñ"djn:ïܹóÇܵk—1D¯¡¡áòåˇb±Xc¯Éf³ýýý5£¢¢JKK£££á4uOž<‰ˆˆÐÞlÒ“©››«³³›N[(ggìŒi§RÝt r¹|´»4$IŸvrjµúçŸNHHÞXÕ€îß¿èС¬¬¬-[¶ŒO=z¤}S>222;;{âÉ”F£Ál.Ó+??ßཞ^’LT*„ÞÌ1™L@0m›u\½zU"‘œ>}:22’«ßà***ÜÝÝY,ÖÁƒÓÒÒÆhÀ4|èub䳉¿‡9sæ\½zuãÆphM‹’’’9sæ¼×Ó µˆ2ÑÚµkoÞ¼9‘-XXX ½tµêêê}ûö½ûñA¤Ri^^žæJYrròO?ý¤ç9>ñ)4œÅçókjj&£¡>$S0\]]»»»õ_?66¶¸¸XŸ ™™™Ÿ}ö™ž-ŠŠŠæÏŸ¯yèïïߨØ8ÚÊ#Ž%èêêÊåra‡šn&½råÊ–-[&õ:$S0Í´G;×g&>¥Rù‡?ü!<<üСC7nÜÐ'™jWIFã\£¸¸X;ó/^üðáñ_¥¶¶688v¨±‰D?ÿüó–-[ŒIe ’)˜“'O>|xÜO¿}ûöªU«ˆåðððgÏž½þ—_~yüøñÀÀ@:¾cÇŽ¬¬¬±gQqD«ÉpëÖ­áÝÀÀô’ÉdçÏŸßµk—ͼ$S0Ñ_þ1ŽÔ5kÖüòË/c<] hª T*õ¥÷»µ_ÎÂÂbþüù÷ïßcýÁÁÁáíÀ8púôéá+wvvº¹¹ /···×§ ƆãøíÛ·_ÚadŒ“…B¡g³_Ç 222Þzë­I½é¤ z@‘dN2™Ú$ s©õäÉ“ ˜ÏQÔÙÙ™››+ çÏŸÿÁhÒ_vv¶ön‰Dëׯ'#2ŒÔÔÔüüüýë_Ä%M®|øðaFFFtt´««ë/¿üB£ÑˆŽj2™,))©§§‡Çãi^ ’)0¼¼¼¼ÂÂçVUUM^?mcÔéär¹Î„µáááW®\­·«T*^ ÎÎÎ1oÊd²Ñ&Ä‹‹{øða\\œvavvöhMP§¬Õíäbgff._¾\»ØÙÙÙÕÕ¥ÏJKK‰S쀀{{û—®ÏápîÞ½‹aØæÍ›u*žŽŽŽo½õ–ΞÍÍÍÕüÿñ$–—,Y2¼éq\\\\\\AAÁ³gÏ^ýuÍe"¡PxåÊggçÕ«WOK!™š‹øøøøøxb9++K»j0©ˆ¨FìÀÚÕÕåêêª]âääÔÛÛ;âv~ýõ×Ѿ$»wï¾páÂk¯½¦SþÓO?%''øOOO}šaiͶ4÷ʆS©TFÛ‘ºµµõÒ¥K[·nÍÊʲµµ%öE__ŸR©tuuMKK‹ˆˆHLLÔ¬___õêÕ… ÆÅÅõöö–••UVVÎ;—ø€—.]b±XÚÊgÏž­}2‘——WTTäååµvíÚ¯AG§Ó_u€Q >!ƒ±gÏžiŒ3$S0¹fÏž=b{i.—«“I5‡ãíí­SÞÜÜÚ¬¬,Ê‘¥¥å¸?¦\.×é:e :::nÞ¼I§Ó;†a˜¿¿SSÑþL“×®][QQ‘žžN$>>ŸÏb±Þ}÷ÝG¥¥¥±X¬ÈÈÈwß}Ws©wåÊ• Ú½Âîß¿/—Ë×­[WUUUQQ÷þûï›áLÁô(//Ÿ7oވɷ¶¶vx2pppmkÄÀ£{÷îÕ”œ9sfÿþý£­O£ÑœÛÛÛ===5'Âc|ÿœœØl¶iE8''G lÚ´‰›•0kÖ¬ákFDDìììˆ8/[¶lÙ²e#n900PûaTTTOOOnnnhh¨vÚ…dj6ìÞ“LœõgŸ¥MÙ•{÷î-_¾|"ñòò*--^3ííí1™FFF¦¥¥­]»V»ðæÍ›:%ÃkšÚ%ÝÝÝÎÎÎc<%44´ººZ“LOž·ívUèÒ¥KÃ˹\îhÔX,Voo¯v}ª¼¼|ìé•0 ûÝï~—–––””ðÝwß½ùæ›cÏéîî^QQ¡y8|ˆÃÙ¦jÈížžž’’’ÀWfJ¿ž“‚Õ»ùòË/õéþD´¯Ô.ijjòóóm}î›:ƒŒÈÖÖ655µ¡¡á³Ï>óõõñ‚ì‹¿÷.š¡´;bqe`ÄÖ©ú[ºt郦àìþêÕ«IgT2•H¤Ÿ|’þ׿~ÒÖÖ6gÃÇq<ÚÚZMúá#9!))騱c+W®|¥7V^^1öÊúôvv999: Àtžæ·´p²³¯!„"##–-‹««kèììZ±bé+mÚÊŠ¾m[Rmm=ƒasþüŽ{w"„~ü1³««›N§ïرÇÕ—/gÙÚ2wîÜ ãó›>Ÿ?v£??¿––???±X\__?IÝÞW¬XqãÆööv‹5‘Û&úTl§FMMMRR`FT3Íξ–’r4%å(Ÿ/@õôô#íËåŠë×o|¾ ­­ãúõ[7oÞ&ž50À+))ÓÙÔà ÿÖ­;­­íÿ›a­RRŽú·µuäæþ’œœäëëóø1LkŒôÆIñññ:=è+**Æ® îܹ³¸¸¸©©©°°pÑ¢E“ô×­[WWW7b*c´íèè>?ëÔ#æ€ãÖ¸’ék¯íHOÏ8}ú\TÔ\„··gnî¯!2™èïèèPW×`aa‘•u-0ÐßÝÝíòål„78<™ZZZlܘhmý|¬M› Kèt˹sçÄÄDž={áþý‚˜˜(Ø&qz>>ööö<O»ZªÏ$TÛ·o/++«®®Ž‰‰™¼Ïèààpøða}ÞODD„ö +#4y3ƒñŸæwtt¦¤„gÏþðÎ;‡}|¼¨T BˆL&»¸8=~\ú‡?¢ÑhOŸV⸠ÇÕ‹Å"„üýýüýý†%SK+«ßFm),,AH½pa,Bè×_捻‘Éä§Owøð~ØSàúõëõõõ†ºö§ÿ°NNN===D[¥ÑgÒý'‘¶lÙ2Á{>æ#;;{ãÆSÓK¼BÍT,–¤§g|óÍ9GG„йs K>,:zôXwwoFÆ×ÝݽDN´°  ÅÅO|WgS]]Ýéé……%éé2™,==£¨¨$==£µ•³víÊ/¾øêäÉ3û÷ï=15Ö¬YsôèQí¾ƒL¦/m¥ÉŒšÁÓêêêBBBôy™Lž²ñÓô¬bOpø¨±‡¦7ÇôŒ*˜Òšé’% —,ù­•õ¾};÷íÛI,Ÿ?RSþöÛ¯k?+66*66J{÷÷÷[ZZ¾ñÆî””çÍ¡øákí§ÁYÉ”"*’SßGeþüù?&îèyÒ×+ÆèˆõRõõõ“?77711qìvµ`zj¦!—+š›[)2LJ@›¹ÐÐКš¤÷SÓ288hgg7]¯.•JÙlvXXfÆX35KK‹Ý»“!Ä&- €Ífä¶•JmjjºsçÎð~÷¦‚0{x£W©T:—#òóó—.] ÇêLN¦d2âkX6Õ· Õ: !4kÖ¬‚‚‚uëÖC+¢ñY¹reZZÚð÷¦×“'OÆîk L;™º¸8?þ/ˆ¯ÁÑé4}çÐr2´¶¶úøø@fr2ýÛßþ/wfËÌÌܺu«¹}j ‹¡¡!í‘O[ZZ|}}§ëýLÁø,@OЉŒ“X,¶¶¶6·Ommm-‹µKž>}:wî\=ŸnðîW®\Ù´iL±Ógúe ¿-[¶èŒð?AJ¥’B!Þ;™bùÅ?H»æhÙ²ecOLon†£7ÆÀ¬“M(j¦“F›L1*•N"‘5Nûˆë•––ÿ¿ÿ÷7ˆ#0!!!uuuÚ%ÓØÈtz›d£ž à¸R¥ú­[ôÀÀ€——;BH*êêêæpÚœCCC¢£çåç?"ÖáóååÏB‹Åvw÷xyyJ¥R±XÂb9B DNNNMMÍ”Mõ &ÕÍ›7'ipB`ÈÓüÑtuuñÅI&“Q\\ÖÑÁÕþ™Lf2L&ãÂ…ÌÌÌ+¡ŽŽ®Âˆ²ñHJJJMM}ÕiuG444džÕ"íqÊÊÊ"##§ëtvvº»»ÃQmì5Ó1,[9·­­C&“i—?|XTSS‡‰Ä66ÖÜ™mìéBg6Í`%B¡P{ù©4ötªÀ4’éõë·ÚÚÚe2ù’% ËÊž>|øØÖÖvÿþ=<Þ ™L&޳yó¿øâ«ÞÞ~í¡O€)":AMcßóÆÊÊJ"‘XYYMp;pßT’©º­­­§§[󘋰~ýš1 #‘Hvvvߊ(ß¹s+ŽãDKºÒÒŠ×_ßÍá´wttB”M‹ÅêëëƒdªqìØ±¿ÿýï~ø!BèÑ£GÄ‚þlllD"ÑÄ“iAAA\\쨙º¹9¹¹9 /wtt˜;7Lsû‚DÂz¾Œa˜¦<::âôés¶¶Ì; !˜QH$’ö˜¤Ó5ðÝãÇ¡K¾iŸæ·˜ô9à|â f0~¥’)àÕ(•Ê466B4Àó$„ŒCAAÁâÅ‹Íöã¿þúëd29((hòfNÛåË—·oßÇ!$S`JÖ¬YsëÖ-Â{{{³‰··w\\\\\Ütaû°‚™–L/]ÊÊËË'–«ªj22N#„îÝËOOϸråìWb2™B¡â`(»víºpáÂ7II^3½};!44$GUUÕr¹Ý2™¬¿ ­­#%åèíÛyÏžU‡‡‡ÂÞº“N;+++©T:Á¨Õj˜>j¦õë¯÷0 óðp“J%uu OŸVFD„I$Íá¥ÝÛè_wR ÃtBªR© Åøt)))‰ŽŽ†8@2(''—ÛýðáãæfŽ Ž«oݺËf7‘Éd•J…`ìñIàèè¨3_|]]Áç+zª©© …/8ÍŸ°ˆˆ°ˆˆ°–Nww‡‡ÛÞ½;Bd2ÙÞÞnΜôôŒˆˆðh°f,¹\N¥Âl•L Ä××Û×÷·ƒwïÞ†Љ‰Œ‰‰„jpííí,‹xÈãñ wé4êëësrr‚8Ài>0=‰‰‰7oÞÔ<¬¬¬ ƒ°É€éD¥Rårùøž{ûöíU«VA Mã4¿¦¦®»»×h^°X.z¾·¾¾ní)L™Lž;7ŒÉœžÑ3‰úÄšÓÕógf˜È—K"‘@s}“I¦*•ÊÃÃÍhÇ ž­Ti—TW׆††#ôÂ$šµµõÎÎNTêÌi¾C£YØÛ;hÏ%3Å©\“L[[[wïÞ _žiÑÝÝ ¿dpš˜¨þþ~Í@ɘž7^½z!ÔÖÖæåå™"‘ÈÚ&‚d LYpp01Å1ŸÏ·µµ…€L‹²²²¨(˜ÈHA@ó}óA@@›Í†^Lf‘LííYF{ª§g€ËíÐ.‘ËUUU5©_,TzzºÏ¤”a¾ðIIIIIIYYYÙÙÙãÛ½{÷8ßœ‰Ø´iSZZÚ8’iOOODDÐd’iHH•JEÈxǤqt4Ó^á*•b_="""--ÍÊÊ .ÛM6›œœ q0™dJ¡PÔjµNE€ÄÄÄÄÄDˆÃtÑLý ŒÜ€À4TUUÍ™3âÉ ™¦[IIILL Ä’)`Bzzz\\\ L’)`ZuvvÂ`QL¥R© Óš‘ƒî¤æE(Êd2@¡’)¿’’’ÆÆÆòòr…i)**Z¸p!ÄNó±X±bÅÁƒW¯^ ¡0-þþþH¦€lÙ²å矆8@2}®µµ-;ûúˆó,]½z³±±™XîééãóŸ_¤«®®ûå—»w`æ¼¼¼ÚÚÚ LŸgÒŠŠgsçÎ9sæ{;w1$$°¶¶ÍnêëëÿïÿþGkkB¨²²¦½½ÃÃÃí§Ÿr ôèI,ÃH]39™VTT†……úùù ¿5Üßß0kÁ‚袢6»)1ñùºÛ·óÖ¬YÒÞÞ¡@O0^ÔÌ?Í×ÇÂ…±Õff2;wNUUm{{§Íó™ÜOŸþ®¥…ƒ²··omm+.~Õß?Ð××ßÓÓËã ®X±ôÎûõõlwwèË€¾D"ƒÁ€8ÌØdêëë6»°°ø­·ö%ÁÁ † Bè7v—•= ˜P_Ï&‘HƒƒüææÖ¹s縸8566ïØ±B€žÎž=ûÆo@ŒÜ„NÀýü|üü|4/þ­Qñ–-ˆ…E‹æk?%,,4, ææÎÂÂB&“A f ˜2™Œã8Äa†×Lù½½}#äææjc3¡&20Õ3S—LÛÛ;0ŒD"½¤)†?•úÂÓ% ‰D±´¤iJ¥Ò¶6 jÀF¥ZØØ0RMd#Ÿê o2EÑhTÒËòŸ¥%DÂ_Ì›"Î`Ð^¬çŠ¥R‰½½Äz‚h4™LV©T ŒÔ’)&‹Édòùü—®vãÆÄÄD$SÀÈ6oެϕëÊÊʰ°0—ñ;S‰D:8øÂMoB±H^èª?8ƒºÌ2™ÚÚÚº»{bØK+­˜NC9&Óa¤s: q&Ã0µZ&š•JE‚Ö0&šL½¼<RëӇɤëH@¬'Zy›íï(ÁøÁ/@2Àd¹»»s¹Ü±×yüøqll,Ä ’)0:===MMMÝÝÝ “ðôéÓ¹sçBL Ûl^ššš8›Í†P5S0~ .ܹsçâÅ‹!Æ€Åbõõ5¨B¡ Ñh(H¦€±,Z´èÑ£Gc¬ ˜L& ’)@2L«úúúÀÀ@ˆ$SÀK8;;÷ôôŒö_¸•É ——Þ€LÕÝÝíââq€d ˜‘HÄ`0 L/QQQ1¼¼¯¯ÅbA| ™ôÂd2‚Æü-//ˆˆ€ø˜èNj^`ªgSÑÓÓq€š)0RIII©©©Û¶mƒP ÃÔjõðò¶¶6oooˆ$S€^FìQªT*)8k„d ˜¸` ÉðÊètºT*Õ.ñM ™^Y@@€ö³‰¤²²rþüùH¦€Wàææ¦= —Ëuww‡°@2¼šÈÈȲ²2ÍÃÜÜÜuëÖAX ™^ƒÁ …!©TªR©¬­­!&L¯ÌÎÎnpp!tëÖ­åË—C@L´e`úÅÆÆÞ¹s§¯¯ÏÁÁaóæÍH¦Àص¶¶677C(ŒJ```MMÍÞ½{¡­>$S`¹\.ǃP›¤¤$$S`2""""""†††ÚÚÚ Ü€H¦É ™€d L’)˜DŸ~ú©L&C‰Å⌌ŒþóŸ#NÖ€d FuñâÅÎÎN•J…:{öìž={Þxãï¾û"À€Fû&L¡Pœ?$$ÄPÄqüÁƒšÝ4†‚‚‚ùóçp²ÙlKKKOOÏ—®ÙÖÖ&“É õÒr¹¼¸¸xñâÅ/]3//oÙ²e†ê¥kkkíìì\]]_º¦NM’é wðàÁƒj¦¦¦Ž±òÛo¿¬Ï×ûƒ>xéjõõõ•••Û¶m3Ôõ_óäÉ“ÉÉÉSÿÒOŸ>moo_¿~½¡6¨R©Èdòûï¿ÿÒ5---ß~ûm}~Bô|éÛ·o3™ÌØØØ—®ùøñc‘H´råJC½´X,þæ›oÞyç}vͱcÇH$’¡^úÚµkÞÞÞááápš&ÁÇÖ4øW­ZecccnŸzݺuÜ`xx¸>õÜéýÔIIIúTKõ¥Ï$S`úœÃNïgÍše†ŸZŸ³ìWâììlüaÔç\ꕸ¹¹pkäÃÿv˜£äÈ%r¥»‹­¤“`iÉİñ7ksuue±X‡ØÚÚÚÓÓ“N§6_¶Êið 2™LKKKCmÃ0#ÿÔvvvîîî¬S(???ÃN{eðO="¹\"WËP‹\-o-m…š©9²³³3tr·4`NÑd|#ß N7ìï†aÆÿ© >Ù‰D2x½ØàŸZ¯™ Pņ˜ƒû÷ï?zôˆÁ`>|Xûì^"‘|þùç¡M›6…††B ¦‘X,¦R©4핞…ã¸D"¡Óéc·Ý‰DSpÚ;3¨Tª?üð÷¿ÿ½¿¿¿v¹R©<}ú4Ç‹±1ÔLÍ£GRSSׯ_ÿÓO?i—þùç©©©©©©W®\(M¯?þñýë_õ__­V …B@°dÉ’û÷ï½òÂ… !ÂzÊÌÌÔI£„ëׯ/Y²$55µ¸¸j¦ÒÐÐPgg'ƒÁprrêïïïììtssc0õõõ Ã××·®®ŽèÔK£Ñèt:›Íö÷÷oooŸ5k…Béìììïï÷ñña2™ Ú—ù¤RiWW—ÍÀÀ€\. ­®®FY[[³X,@àééùå—_655ýå/!Ú3°ÙloooÖÕÕÕÛÛëííM¡Púúú¬¬¬0 ûñÇBííí …Á`üºçL²cÇŽË—/ç4ŸÓÆlTÉUt?:Äqfëííe±X¡þþþþþþ   ww÷ÎÎN;;;ÃÞH1üñÐÐÐÐÐпýÛ¿9rdÏž=GŽY·nL&{øðáÉ“'O:Åår1 ãr¹™™™û÷ïß¾}û¥K—Þ~ûíÄÄÄcÇŽmÛ¶íĉK—.-..V«Õš®}ô†aR©”N§ß¹sçÞ½{ï¿ÿþæÍ›¿üòË-[¶üðÃ=*,,¤R©b±˜¸Œ“›››œœüÚk¯9rdïÞ½Ÿ|ò‰J¥ ’H$G‹‹knnÞ¹sç²eËÖ¯_¿lÙ2Ø}z’ÉdUUUQQQŽŽŽÃWÖ ùb>ÓŠIòñöñ‰öqíŠÔ·kß¾}iiiÝÝÝ«V­B544äææ"„öîÝ{ûöí¯¿þú¥ýŽÁp†=}úôСC7nÜðòò"2ãÆÝÝÝ[ZZ¿¿?†aŸþySS“Étrr ~÷ÝwÏž=‹ã8—ËU©Tï¿ÿþ‘#G´;ãböìÙ³C‡½÷Þ{uuuUUUÑÑÑK—.Å0ìý÷ß§R©2™lÖ¬Y¡¡¡DPÿ?ýéOçÏŸW©T‡J¥¶¶¶VVV¾ýöÛ~~~D¯¡þþ~ww÷yóæÁ¾Ã… ŠŠŠÎ;w÷î]„P(“ÌA=`Æø"¾-n;v&¤´´´ÜÏu”5®æyð8\D`¶˜VÌ–Ú¾?Ú J™òÿA‡])ïÞgIEND®B`‚snd-16.1/pix/regions.png0000644000076400007640000003113611147553270013320 0ustar bilbil‰PNG  IHDRɱ NMÝsBIT|dˆtEXtCREATORgnome-panel-screenshot—7w IDATxœíÝ}”eïñ_÷Ì$“!¼LxM/Jä¢Ñ•M¼ \E…+îŠîÝ»\õì=¢ì.ìf+碢»wï {cÈκ AQQÄ$ÑŒ(j ¢ˆ`@∰$!!„ÉÛÌÔý£Ó3=5U]OU?O½t}?çh˜îê§ž®®®_?/UU‘ä LÑ)Iß÷¶d]rãßÿ¸6°¿’’ôvÜ›e}ÈñͲ€œú—‘‹¬”ó_+DyÆCÒ³²@›ñ<»àÄ–ŠøéÖË;~¬å5˜É‘ÉOîþáVé€äyñæõxÞ˜:ŽîѬW%U* « ÈjíŸ=»_Lôò÷Ê󼉜É{y &º[}-Éiß~A•‘£5¼w_¼•íß§—nÕŒÌUuZgô €‚úæ‰×J’¾±{“úv|7ãÚîx‡BÈóö8zµÿ«çLcyç¿ím±ŠºïÞ{Ê»ïÞæól&-ç+¯QCKrò˜äQGöêÕ'¾VލR©¨¢ŠTQí¿µëW*Ïíyi·îûÝ};0¢J•–$ÜûÖ+WMú{ÄÓÎÑ=Ú<ü[}iû÷´kôe'ë}|ß´ëN=ú½Ú¾ëaÍ»ø5NÖd®³Ö£·g±Q­¥6Úryõ×D•wþÛÞ¦oë[e\ðö·7/¯Aè˜ä¢cÔŸ\ø&IU«UªU+UU*UßßU«‡þ­T´mûvýdÍ4::Æ8'Rµ}çýáùç4wö-8êXwøéš³£C}ñNuÌœn}}W?}›¶~ò~iÔSÇq³ÔõijšuòQÖ×äÅXÒ–¤<Éó¦dB’òj¯ /ï[ß¼Go¿ð’jaø­oÞ3i™ús’ô­oÞÓ´úgWkÉq§hñÝž}ýÈøë^ؽK|àRõ9_ß¹e@’tÚÈ‘ÚôÃ:âÌE:fÚIÒwÐ_~꣪1MGôÌÒL¯[/;ªÊœéš6kF [hmLRc~ã±ëФ¼ºo|ín½ó¢‹§<¸¾¨1Iÿ¬Ïó&OЩTT©6fÿ‡–Qµ«‡Ê£%‰õΙ§Þ9-«_=þ˜~ýÌ“µ–å´.½rƱ’jûêWþùKS^ÿŸŽ>Y?Øðmxfm\ñ‡ÿXû;F5}ÅB=´ý1½«!$ƒxcÒâÃŽ“$mÜô#½tp¯fœ{¢ÖU×Gë똒6>p¯ôúÚß?øÙCÚ;º_;N›6^άÃfjø§ÛÕ}Ê|ýx×otÖœWé‚oÑë–,ÕS{žÕ¦ç~­;þŽ´{·F_Þ¯±ûã­@¤³[ë915gÆ&ýkZ‡¨ò¢^oZ?©Éy’èÅjH ²*Õf´ŽÕ[’„$Òsû×ôÙ/Þ¬Ë.¸H×}ð¯ô¦3ÏÒß¼ÿ#ºñ±Wϱs¤CÝ+£cczô7Myý®Ý/jä¹=ãWüUuþaêèîÒ´9‡EWÀ÷ë´zd*3:uÄ)GOzüàìÿï—^ޣꑇIÝ KT¤ƒ£yq¯>ñø—uæGèuǪž 3_yªÞpÜizÃüSõ—~AÕ]çv.x ï‡Q;;¢2e_­—§\O^dyu]|ɔ׿ëâwëkwßeT?©É˜dÅ›H×ñ1HùZŽÒ¤¬uÇNôí2&‰´yǦ¯x›uö?ÓŸòZ]¼ü|ݶá. ¿ªS¿Þý{IRGµª¸ífýô÷µ ìèèÐN]ª'†ž’fvèÉŸÑ©séõ¯y­¦»K3gÍÔ²Ù¯Œ^÷˜§_¿4¤Ó8I+–ý‘¿÷VÍìÖ9réø2¿çJWU‡Mm ŽŒéU=Çéþ™ëëßÛ¨±ç‡õ™ÿþ·ºàÞ¬Ó=E/üý/ÕûÞ¥|ÏàÜøuaÆv·vÖ²¢¾¯N)/N¹c^ty’.z÷ÊñÿþÚWÖNz좋/,¨~¾ª*Û×[© FÖÆ$«þ0lœôßµ×xžW+¯ƒó$‘¾ióÓšmèOy­:ªUýéëß©Ï<ñ5ýìcúñ3êõǦ5Ÿü=½ã¬ŽiááGiFçt]öÅkôÒþgµö© úز?Õ‰ éÞߦŽ]šÕÕ¹^ÏÓŸúŽþñô÷«wÎ<Ý÷‰/éùƒ/êä9µ.ØÍýBÚ¨Îe§‰|U©‘ç÷èå¡êY0·¥íD«í žçéâK.õʻﺳ jÌ™‰òÿ5áy^dyu¼û®;Ç¿û®;ÇŸ»èÝ+u÷]wŽ¿zryB[’ÏÿÇóúÕ¯?rJ‹±ZQµ¢‰É<‡þ·sçNíÛ»—–$²3&=±÷YýpèzãÂ×袷¼]ŸÿØ:°à þöÑÛtÙæ¥ºàµÿY ÷CIRçI³ÇgW_óÈ´ëï¥Ñg÷HÕŠfž<]•³õ…—7è–Ïþ›F~ÿ’¼½#Rµ¢êÌiªÛ£Îáýš1êé»~¥[?5 ‘Çw¨»cš¾zË¿J’z‹*‡zHÂÖû›îtÕþ¯Fþe›F_Ø'Œª2£K fjú)sÕÑÝøÚ Ç>û‹;µó¾Ç5ö/klø€4"U¦WUí¡ig£jW'ß3¸W™ÜR‹£þšJ㘟¯¼Æ`³Qž$}eí¡õýÊÚ;ôî•—‡—× tvëa¯>&4 #U*ò*ÜYé™ñÞÓ¤k­}4ëª E;wîJüÚ&-IÆ$åæÏ‰ó$iIJΟ…t·pHîº[çÎ=aü¿_xáéLêeQ©Ìžò˜ç튽Œ9“2L– ZOšB»[³jIÖƒ±1, T*³3?ø7«Gãã&˘ü-™žI9iògáxdvttp RX 6k=º,Ç&:kIÎ{‚^xáé)-Ä$]ªA­ÌÆrêë Z?øEu'ú[VA˘–ôßI»7—MÒÚ2i!š,‡ÿ½å¡EÝL“[eÙ“´^AË‚’0éNllÍ4ë 4)§Ù:MëãŠÉ:Z È yÊðËÒ9èj%ÄEÐ;s[uryÜv&B¯¸“çó$™ÔÀ–°1/“ƒzœœq¤=ç: ‹,ü<Éœ^q'¬[•à”îÍfݤ6êã Ùœ? 'f·V;œLÞq!ª\@—­6Ó²[©C¥2;ñëmdPk<èTŽ(&å¤ÍŸ…NÏ“4™ÝÚø|ý¿— +Âf@]+Ý­Qå4+;lv«­ú˜ /“€kVoÓS9¢–˺›ú­²¢&ï˜Lî ZÆÿ“„˜J2þhºLØëš•'Z [ïÛtYÓ²²ÆFþ,lèn­:9 $ ´6ø³°-nºl뢀rKí¦Ëi‡¡hUè˜dg[’ØàÏÂbB‚ÎèEâY½úvÛE(‰+¯|_àã7ÜpSì²®¿þÚV«ØIH⪫®ÖððŽÐçW¬8kÊcË—Ÿ£ÁÁõKmV%å,$¯¹æ*WEh3û÷ÇŸ±|ù9Ú¢ PÀÆ$ÒÐÐIÒW\f½ì,oú›–2¼G2ïnÝ´éáXË/[v†£š(Šz+²ŽÖd<¤¹ÌCR2¾¾¾5„$$eä"k‡m×R­5¹uëPFµ)–úçOPšÉEHf¡Ù’Ť\qؾ۹ÿùºVÖá×Êçcãómö¾âìÏõdQ÷7+².NkÒôó º€yœrÂ)n9AË&ùüŠü¹g¥´!µ¢˜‚n×÷ Ðì>IL­2y_e9ø¤dÞš4ý|ƒ–ó?f£Ûû[3eÙGlbâN~eå_³Ï(,8²üác«iû}e½]’ªÚnãÆ—íêGGÒršÝM„ãTzJÛ’ô3íÂsÝ}g£[ÆVW¡«®¤¼ÁãþªÛ7²øÑU´mWX+².í±I?4Ò¾Ÿ$â!$5±£»:¨ÙêÞ1)ÇV×Ë:­“t¿È" óÔ®„EúmÜø`d‹Ó†fß‘¸ÒênE|„¤‚[GÍ–I£ye£KªH]}&ª<|ny¨Cúûœ•m{r•«õ¶Ú«…xÉ6Dü’Ï—ÁÁõVÎ…´µo‡ 5Äýþ¥ù]ó¯ÇÆLðvGH¶!—ÊeyŸEb³ 5iï€IOJÔìWÓrâÖÍõk˪´!™Ç.Ž,'z¤9–ecVfØÁ)Î) ¶Þ»­}#¬“÷ekÌ9ïLÆ$ûû´jÕu)Ôe‹ìë[“ú:Óìâ0]WÔLQ“r\v%Ù*Ç嘤¿l›³‘ã–g³k+ê}Ñ=¸‘yH.[vFf—šK«‹ÃäõõçmL±õ¾Òê’Š«Yk2NÙ­¾>­rl=_WÔV$.&€Bâ ŸÛ0GH‚ ! @B€™ÏnÝ´éáXËsÓe­*Ú•fÒœ‘çÞ¤IÊŠºÞm³ud13;ó”̃¯¯o ! IœÆàZ»o߯ ðçE^¶yÔÅ7L%½I‚Í ÇÛ‹ÌJ'_í¬+­Lok&Ù»EXPy¶÷[É$“«ü ¼Ò¼CR³+Le”¥ I[·”je„ì³±M~IÛÞl}ù“t•å©5•'.ï§ê¿\в&?tâ^r1 —Ç)—\´­´!‰bŠº««Q?žZ «$åD]¹(ëTV’vú3¹Çg³e£êäúó©ïK6{9üL.¹˜¥Ò†dÜV€‹ œÇù²ùë§œf7ãò—tÙ¸¾|ÒÏ·ŒŸ…Min¿4/£TNÜý%ìØtMã<µýJ’~yû`‚¤ÙEìú—t‘˜nß$ïËÅÁÌ„íB;*Ú~šGQû–ËÞ[I™(Záÿï4v;š®¬àm2ý•Üø\žäù—{^ØØ&&=-È·Ò‡dÓ1‡< ;à¥þ¶DÙ͸œÅõZ)ùìî8¯‹³® ñXº[s,oFÞ¤=ûHKT‰qʉšÀ’›?MZÑQï;h ³•:ÅUÚtùkÉ›3£fÌIî&”4[gÍÞSÜ_¥QŸi’}Äõį´[íúƒÈä}%‚ie"]Ü^ W½¶& ™–c£ Wr’}}k2YožÆ‚~M™Žy5ë¾H:îò—´Ë1É4Ûk²õ+Ù¤ºÐø2ÉeËÎÈäRsIö®×iã×mÐ2I¥Ùø%¶\+Û3*ømüzµñ¼É²¶öC[ï¹®[‘iâ‡Iñe’¨á ÛÊ-¶¯=lËb#$s‚©â?„dŽŠ/ÎBò³Ÿýœ«¢´™}è#YWä´%ù×ý!—ÅÇBhâʼ»uÓ¦‡c-ÏM—iÉ<$%óàëë[CH"—®¹æz}æ37d] À[ç›LHŒsŨ²lËEHf­ ¸ ÷xÍ5×K’ó÷^_OëJª•}ÀäµQË´º_ï×X^Ðr­|&q¶[¾gíÂÖõTM^g²®,'5–>$›\Ú]Z¬úzʺ­£Þ·?<’„IØòë+7ixÅù<ËúÙ‘­ÛW% Ȥër©šu²Ä/[´Ê¤…÷ùÏ|æ+¡ârÿ.r ²R™=þ¿Æ¿›-´LX7`ÐrQåDÕÇÿ\Xýe¶Ó÷n[i[’q¿¸­vMštsE-ÓXçfÝsþrÂZQϬãÖÙ&Óí·Îy’<®;lŸ/r@ÖÕ[)-– Û8ùE]Ù´«0l]ÍêTvžZ\al]ã8«÷^ÚLó‹kÚ͵Lc4 Ï8AÖ¬ÅVVœ:Ûbº £êlº}lÈ2 ëÿšŒ•ÆUô€´©1(]´mÝ™#M6Â-ë÷RÚŒËÅ—=i™IÆ«\ ³ÔU™¤Œv3 ûÑÖÊ{ïiMèÉ+Ó.½¨€l·nÏ8²8ÉIz Îò`”V¸„Ì‹~ N[Ú=(Aá3kvȰe㴚ʜECHæD³îļJ»Îiuí¢uíøY5 HÉ|VfÒ€ŒÓMÙÊ͹MÇZÓZWÖ㮥žÝÇ5×\oýàorj@뱩Õu…mg—ï¡•²[íª z}³0±½}’¬«4»?§6¥I+1ìæéÍÊ1©O’²Zá_W+Uç¨u™–ãJ.Z’}}kR_gЩÎö¯]“®Â¸ãEqÖv öÿ·±Î4×e«Wc’¦û˜ý6ÇU]ÌìMó»ã‚­›…§]N³e“.g£ŒVnÜnº\–-ÉŠ$ïûÞýâI’þ×qïо}/ixxG¢W¯¾½Vp¥ÂÎQEïJÌZý. aÇn¸I«V]§¡¡-‘eõ÷hÕªëÔÙyP«Wß®«®ºZÓ§Z­oÚ²îr,š;ão«Õ«o×µ×~L·o6öبqù ÍÊC¾”¶»Ú§”Weؾ„\{˼% yÖòCy’)(ïi Ð*„Ÿ³Ü¹“``¦§g^ÖUHÌfë“1Êü¡% ªµ"£f·-ôXÐìÕ ðó¿–€ÌB1 ©°°‹[N’e‘>f·‚ ! @B€LÜPZkní˺ È9B@)-YÜ«%‹ßšu5st·‚ ! @B€LÜPJ<¾=ë*À‚%‹{–OH(­3–.˺ hÁš[ûœÏP¦»€„$!IB’àÀìîJàMœQ,„$8°kŸgå†Êm¶IBp ¨Öb۵ϛÒrkl Ö—©ÿwÐ2QÏÅY—iyp‡€CC0è±Æ` ÏÆçšu•š¬+l9¤‡îV8Ä4Œl„ÁW „$´ˆÀk_„$!I8¤§[¡Ží„‰;pHÔŒSSA3S“vÉúëD×nºIhB&!•´Œ¸Ã=º[AH‚îV…Ñß?à¬lº4„PƒƒëµbÅYYW%CH(„åËϱ^æš[û¬—‰öBH(Œ¡¡-‘Ëô÷hÕªë"—[²¸WK¿ÕFµÐƘ¸ ×-G—,l"$ÆÂ…¯hú¼Ë‰=('B@aDµ&iEÂ6B@¡„µ&iEÂ&î(”ÁÁõZ´há”Çã¶"y|»­*!CK÷:-ŸP8 ¾bÒL×þþD]­g,]f³ZHÙš[ûœÏP¦»@áøÇ&‹„+„$€BªM2 —œu·öôÌsU4hpp½6n|V$œr’W]uµ‹b”XÐeé\\ªÎÓ›$·zCf¸g=$¯¼ò}Þa»X%výõ×J:˜u5ŒÕC¯1,›-תÙÝ‚ÖÆ$Á)  àÖ˜ÿ±úßþb’VœI—lPKÔ_Ÿ8å!>Bb0 SQ]²ae6>ÞXÁèÝ­CÖa”õúˆ–$äPP·nýq¤ÇzHÞpÃM¶‹PµY¬¨‹ên…{NZ’&'÷ÖÏo\ŸÛs€,˜Þ\¸¿çfËç4×Z C‚ÔžÔ»[—/?GCC[44´eÒE‰/V ”UÒ uçÙÐÐ-Z´P ¾"×?Âf­& œ Y§A“}š-§»Õ¿,iOj!َʧa@ÍžzÜ$¤l-“dY˜s>»uùòs´hÑB€¤‰°d˜Eà,$ GÍ–('!YïZ€(CC[´qãƒYWä$$×s7FÚq²Ú‡³‰;+Vœ¥­[‡´qヺâŠË\­@AÕÃ1Ë€\sk_fëF18ŸÝJXh”‡p”¤%‹{µdñ[3­ò/µk·ÖÃ’nX œúû´uë‡G®ÍßIDATPæáÄ‘úÅ[–O =å¥å$á$$M¦tû—Yµê:U1¾Û(2ë!Y»@1×_/O>ùlÖU€®×Ì0Zîà/ö:®I ·Êж®¼ò}Þ¡Û²® ýN»´axCÓeøÜZó¡N¥>Üt€„$!Zîníû|¿z ó¯¾Ðh9Óìyÿ®h¥:­‡ä‡?ü‘V‹@’ô¸Ì®ûmš={÷mo¥:­‡d«`\Ùbiec’„ $Qøó$çÌY”u–ünÿ.=ð¹"—kvìß¹s«µú>$íãôé§ëëûzÖÕGw+!œµ$/»ìÏb¿æÕ¯>Õh¹ÚõapËiwëÒ¥K¦<¶rååZ»öŽÀÇ¿üåt;úB×ûãê÷Rín]¹òrmØp¿6o~Ähù¡¡-2;±ÛR É î—$wÞ›#—m¼ß¤ÿͤ!µ\¹òòIGµ&\q™“:ÐLj!YoEÖ5kM6¶"ël¶&+•Š*•J¬eM—´TBÒߊ¬ kMCÚjMV*yž'Ïó"ƒ¯qY“åí%•ô·"ë‚Z“A­Èº¢MÒ"€bq~ÅúŒÖ0›7?2åT‘þþ×Õ2âo=zž—amis’ÍRªµ&·m›¸åÉààúIçJf©ÞÝö7 ½9ín ‹ô3=oÒ%ºB~Î[’ëÖE_Í=M]¨Q­Bº[ Üœ†äÚµw^š.kAa€#”w ! @B€„$!IB8?$®f—¥Piž>Å…>àŠÓ4½˜€_Ø–ûû´jÕu­T @ŠÒ¼1A 2¿,T»àÀ7Þèº*@î™^è¢(늎1IB’€®í ”! @B@[Hs’ʃ`3MÑ.Jw«,L•òVYh/iµZêÝyEo!ÕßCZ]“®·[;|&È/º[œ¨ìÓ 0Æð€h„$– P^„$!IVÑ…‹vBH¢ÐÒž„Rdi^5ˆîi´ BÈáe?˜`! 4ÑŽáÕîAéÁ[^„$ )«Ö-•|Isæ1Ÿ{9’p"­óüÚ©UDùãü²teÁ­ý”áüÈ´®"Ô.W+Bù’–˜|ù R´»vB‚¾œènmsiŽÝÕוÅitO6ÇÁ=9¶]¹Ñ’„Ue«VZAÛ&¬[ëqy€Ok=aëZ§Í_»ïˈFHÂ:×K×w”ܾ‡zÙ®À¦ëI*þ׸Z¿|ZuHÝ­m,í»JøÙZ¯i—q+ëkì&®ÿmó`ì/ß•4דFXù»ðÓÜ—ƒÞczJ0-É6Õ_dËÁÅ9¨ubr 4m5kýØ<à¶ÛzêëJc=q1§\É6æ*P‚Öas|(ì@œVxÙbã@jò~Úm=¦ëjö¼Í # Ë,8h„&éD ×Åé5=MÆäàgCÔzZ‘·–FZïÇÖd™VÒÓý0OŸ1Ü`L²ÀÇiLÆk’ŒéDq™^õÆd½6ù‡­Ëæ˜ÀnuÛÙy:HF½[uÍÃû)âzÐÞÉ‚3=í¢Õ†?,›­ß/ikÉõAÎåi ­Î&N›­ÙœE:¥•:ÀåAH¶±4»È\L‰ÛR–’uÅý °Á¤ÅF Üæûi5øã|>&½i„˜íœ(B²Måaæ–T£$Û*IëØåÁ5­ƒx³÷b{‹ú‘¤lcyèòKs½­„CZ“UÒ33ŽËEÏA³uIùKZ‘åCHº¬Ç‹ò*ì`ïj6§i0&]P7¯®ðfëKSzc=B²Í¥}`)ÃA%­ƒ}B%Ë*a?–Šø ùEHš,'7p`l®¨­ï¬¥1žŒ|ãŠ;¬iç.J‚²œIšËrÚü,Â…ûæI8‘Ö7 í^š#$QHžgv‹.Û\…W»·X]içî]ä! 4‘Ö QZùÇgTNÌnu„_·È#öËdÈò"$ »‚ ìâÔsq/2Њ¬>öØFw+«)´BˆÀä ¼I 'c I gÒº@|»\H€p‰Dá¥5ƤsÚ! @B€„$€¶@w8\ $|r"$C%P>„$!¸v+#iµVÓº»IZ§Ðʇ+´$8E€¡ÈIB’œ¡‰¢#$AH‚ ! @ˆ\ž'Ùß?uÈ_H®×Šge] ò’i¨_ÄdzzãC˜ÎåRºl¼NÔ­uüÏs+(—Ò…¤+i]£ž¶ É ÀJÒô_ ¹Yqºn Tˆ–‡ž»¶ I[–îV(7§!¹råå.‹·*ÎdžVä=d‹òC€zÚE=í)B¥âÔ3kÎ[’6ܹ̺uèÆot]I“»P£v8Ý­€öãôŠ;k×Þa´ÜÒ¥K\Vc Ïó¦^ÐcP>Î[’gŸ}nÓÖäºuL ÉåËÏq]%Œ8ɵkïÐüù½¡Ïµ"‡†¶.Ûß? U«®³V7LE‹Ù.¶§]lO{Ø–fR¹ÀùÙgŸøøºuLylpp}h9\®¦TB2ll2l,ráÂWLyŒ‹žÒ–Ú­²ü­É Vd]Pk’V$ m©]LÀ?65£µÞšüä'ÿ·¤öIÆìa[ÚÅö´‡mÙ^R½âN}¦«Fkzk²ÂPL©†äÚµwhóæGR?/€$R¿,]Ô¥êŠ~ždÜËÛ¥u9<­Kzó¾çÅå,$n‹ýšë¯¿VÒAû•IIœ{U&Y@¶üßQ“;úð=/¶Ôf·Ȱƒ;·q3Gà•! `}3ü˜(ÜÞOrΜEYWh;wÿ8YиYãcA÷W­+[¸Ò}ZÖC²§g^Ëe ï°P“ü`ÐyÑìàî¿5œÿñ ëÊÍÞ'ßóöä¤%ÙJÈ­^}»®¼ò}k“ž8÷ªL²<'elI&¹Ç,ßóbK}LÒFK3ÏâÜ«2ê9 ÏÊz¯Õ°÷Í÷¼=¥’==ó4<¼C«WßžæjøÔ[7Ac”&“R_Ï$´³T'î ïÐܹ'è…žNsµµ„–ñÿ¶<ÐnRkIöôÌȹsO 5 ȽÔB²»{Öx@¾ðÂÓºöÚ¥µjI%${zæM Èú¿´&y–ʘdãX¤ÿ_òÊyHöôÌ›ÒÕÚøïM7}"ð¼È;·º®M9ïnmŒMòÌiH†E26 (§Ý­ÍÆ"ãŒMÞpÃM.« (¸Úýˆís’Qc‘¦c“u+Vœ¹ÎåËÏ‘$ ®ÿo@±4Ã×G._[ö “º8mIÞtÓ'´zõíFÿ¶bùòs44´ECC[Ôß?0¨CC[l¼ @JüÇðE‹jáÂW…¥ ÎBrxx‡ó»y4†# =e–NBÒõDÂÊ'‹°´’.[„# ͰLý~’IÕ©–7>èt… ÉÁÁõêïȺ€œhœäãJaBRª²uëa %Öß? ­[‡œ¤T°¬#, |Ò Ç:ëwzzæµ\Æðð£åêa¹qヺâŠËZ^/ êݪi†c“S@LC.ÈêÕ·ÇžÛ–hi@qeŽuN/KW³p5¹Ìœ™U«®‹]@>äáîô²t¶®ÝúË_>¦÷¼ç —UØÀÀmNÊuzY:Ó€Œº ˆ$-]º¤éó+W^.IZ»öÕ€Ò¨?ódíÚ;Œë.ëï´%ç~’I¯Ò³rååÚ°á~mØp¿Ö­{ 2LSmØpÖU×x,ß°á~ÍŸß«³Ï>7“FÓS@Lï'™$ W®¼\óç÷æêƒ¸QË´[½Îϓܷï¥È±È8G(¯´ÃÒiw«=6iª±[€4¤r۱I×·Ô´§¿û»¿Ke=Î[’Ró±ISõÛÍ›Ñyç½ÙQM˜Úµ[ýc“qÇ"ë–.]¢mÛ¶kݺ,×wëÖ= mÛ¶§v&C*-IiêØd«êaIËÚ_ý´´OóK-$¥‰±ÉV΋ôk K@2yíË*ëR Éáá‰2jºo¯Eqã7f]…@Y×+Õ””( ]]“€fœ„$§vÚõÞam¼€,¥v ECH‚ ! @B€„$!IB’„ $AH‚ ! @B€¡wéû|šõ 3ÕŽàÇCCòÃþˆ«º+Ÿ»ù ɽû¶;« EÀ˜$!IB’„ $AH‚ ! @B€„$!IB’„ $AH‚ ! @ˆÐûI¶jFw¯«¢ÛFÜ{v>õÔÓn*ÒFN:é„X˳M£Åݦ|÷£Åýî³M£¹º²³”¤î#.‹/´Oêf½ÿWÄ~ݲeg8¨M{èë[û€.±M›IºMùî‡KúÝg›†KºMMÐÝ @B€„$!IB’„p:»5L¥2{Êcž·Ëù:]¯#KYlSD Û†eúÜØoÓgŸ4)«®]?·ÔCÒæwí”YlSØWÆÏªþž‹¶¯­¾®4~~í*7Ý­®²¾Žvþ0‘Oþ}Ž}(ŽLº[MØè† úµçoQš¶Â¢êÖ}–å¯Í°î¼°elm S&å´Cw\ã>×øo£¨n«²ö„m¯$ûIœý?ìóh|¼Ý»mƒ£>¿<ËeHæñ€·ú4òï„au²ñl~6Qåäq?p%ªÛ*h¸ ·C¨ &û‰É2ߣ°í\Ôîa¿¨Þ Ûã–yk@Ä‘yHæé×X‘>8¿ _»IB«â¼ÕÇ„1ñ i$}Ÿi¿®HÂ0­uIæ!ézà×V¹EG ûµ›·mUNØrÑ¿t­([@š0ÝO’î·eÝÖE:æ¹”yHºfãS³®‡<09hš¾“ÖŠƒFœú˜¾6ïln·¢nWLö¶WòVGf6ÇLí`yØy¨C^}Û¤Þ’4éI³›Íÿ«<èWzØì,ÿxj³¿]JºM›½®Y+ÒÆg“d›&]WÍšŒn‡eÔû6‘Å1Åt²\Q%éÂûü˜Ýš€É²±MgyFýmúX–|Òmg&lœu™Èû6µ!é>˜´œ¢±õ¾mSâlÏ¢nû´·iœåòˆîVKŠÞ¥˜ªí'è] €©I‹E˜ÐÇDº[AH‚ „Ó1ÉOêf—Å—R_ßš¬«ÐvئöñÝ·mš g!¹wßv½ÿW¸*¾”N:étÒ YW£­°Míã»oÛ4;t·‚ ! @B€„$!IB’„ $AH‚ ! @B€„$!IB’„½ŸäêÕ·§YrgJH.½éRuwÏÊ¢.dféM—NylJH^ùž÷Jïyo* Ï“ D§$}øóϸäOE’—u%È£ÿr8“¢°IEND®B`‚snd-16.1/pix/asyfm2.png0000644000076400007640000000703111147553266013055 0ustar bilbil‰PNG  IHDRv³ªÒÇä3PLTEÿÿÿðððÀÀÀ   €€€°°°@@@000àààPPP pppÐÐÐ```ÍüÏh pHYs  šœtIME× %˜-õà yIDATxÚí]‹Ú¢ åf&¥öþO»\†›à…ô¯tç|û¯” C#∧! `DŽñi¼ZAv ýÁÃôkM‚Qæb+á/ôv·CÁ§æúHo Õ¹Áo0{»™ºß`ï>/ÙtGÒÌm‡ç¡¾"ËRÓ¾uàLu!”œ ‚ÛwLŒ¸ | }¶÷&úìÐ .ò>k2xs[¨†>VÛ9{ØLݯÛó¡3á’öÉŽ´™!„:Á‡üý–¥Çx2©ÎG½%äÆavëÑ›®Øöˆ^ Ò|^Ãúz‚Ý“eQ.^ê¯3Ž|5=[ë«Á!Ø»jÀ}é+”íLØŒŒ·Éލ™5a/Á‡]l©¤X.›jÌ{*FilSªVrƒtY/RÝkÔ{;Ó(_MóZiWäì]5Ù·êé²=„]> ;¢fR&i4˜©— Œê R†‘AlÔ¾pÐÝÀåÂnãÆÕ™:Üh'Dô\Øín#¡»Ck¿qß°x$¤ê% k<ë4n¬oÆÂW#ïkÝ!rìõfâ^ŸtÍ^‡}hëÇiÅ¡™òñik{™^ÕK~»AŽ÷Qêâ¯|˜8©}BmXskÈ‹‘‡TÃiàLçm«†[‡mz^‡ýŒíTàx5cL+ÄóÅín£¸±„J9˜;óZ> F®ÂËa{½ñîƒm?n»P‡l|–ÃnÏì—)p}">¥~9‡*žT÷’›ŠÑ`»¢úS;úáÝ+͉÷vW‡ot¡©N»Çà¼z»jµ¸§íŠ—ídh7éqö®šÌýãµlß¹ÑÓo…Ý~釰0ß]ïÐÍ3^‡’æNIûbŒ÷öPF±suøÊKu´éx^ {ÓM‡Ú,¢“¡Ý¤ó¶Â¦!ÔúPMç²<‡éØÜEC0Ø›Mpl èÄÞxkLØYº£öv&ìzð!ì„>G•þ‰pj…ØÉv&ìQr9ìÒ´Ú\ÿÕÑUß\ö™à6˜3n’Λ±]g¹±uÕø±}6ì‘Cgo7Á½³mZ:“É€½ ;}jCê›]‚àKûAFØìÇ…L¿îE½;†F6dX2È”ë`R_®Ø\ØíØ®Ç}x<´/V¸5P#aúõM:¯¯#òÖ)X[¨f=“‰‚½«&s_¾Ó‰Ìû®çzÀe/š0ÍdØýÎøSÅHp©ƒzɉz-E÷’}'TÏ–#¿sý1voÙ 6úÃlFU§lžQÉÇ8B¶!yö3¼—|ô^ ´à¦Êf·‘ IÓXºÍswn“t~zí…jVóöÄád8›¸—[íáRÅí–‰‚‘ÎÏ*ŒQ3ä†:äò„„Ü£BâlÓù¦h»á.õ³hù5¼#—·€-s2ŸÅæ9™Ïµh_ŒprÏ $@ q†à X}T„ø“ÎÞ^à.õG±Ä“°À“)y“Í¢‘óD«5?Œœ'ãfxYÃü ³—'SdãÜY¼Y4j1ì!ݪ͌š_îë9O&t0vwÝm'O¦èe°ñÒ°Ë¢Q7¦^jò 9£ætXàɨÓßEd/O¦äelÌ#/ØxrLl4PŸêè«kG¿'ôÛXàÉħûNžLÉ‹p<©4ì“20¤~à§âK =cØ7ódX-O¦à…[öw$„œ“„}4ÏVèëy—zš°×ódL®ãÉä^4…­µúvz9rÌÄh|Ú«Ï¥†žfl¯çɘžVǓɽ4ª[ßz·!%rLl4£A¿x±™†ž.“©åÉ´µ<™²8B]bÈ1‘‘P]œvÒð1z9ÓгåíÛx2i:_É“)x‘êúÈü&¹ ËŒ¨ºˆê¼ýÅÙÀçz²‰—<™I:_É“Yõ’çí#™l(ùï`Òù“ðd.‡“ðd®×éq@ ‘Þž²†b>ž—¿6ü q8¤žŒÂÛ¥¿Á,š„}ƒ° µjGÚ¾¨°q†°o$l˜tþma“RØG®ÉlW…Mu~öŸ!ž3ìbnöo—öc°Ax`?a#Þa55d¾cÞˆ^ì×JK„ÑÓ4v+l$d ýÛ'xg‰¥‘S;®Ó×ç dlˆ{X³Ÿ°E45ºlGÖù»B+/%ÂÆ³m-l?a£‹Žf»ö„¥ÑZy |Œ°¢ëĖÞ°4ºB+/ö„ “ÎW6Â0M‹a/²4®öj†Mç+ áý ©Qîí$°4ŠÔŽ‹ŒíÕ„ ›ÎW6ü0í55Ò°Y]ÞÊ e2•„ ÎW6K#D³ö„¥1¡v\+o¯%lèt¾Va#°4@Sí"³ÀÒȨךðª#l@:acån¶ÜÊÿtªÆ¦óHØøR„„¯g @ Ó³ð/€=p%š¯Üˆ2¼]ú+,6\ØÿLaƒÈدÜFÊ S§PÍ©NÍ%ÂFèí¤°a‹à„2* +¤@5 ·q޾¾@؈Âþ' ®~½ÐFá¬(7VH±Õ8½S`iI”ñáÆŒ¿QØpEðë…6Ö6Ü )¶§·qŽ«æ6|ow~eúpkUaVH r°o]E§óG(l¸¢óë„66+lÀ )¾ÆóÌö¿±$ŠIçP؈‹ÖïøœØ-*l„R šó¬¼øÎ’(‚‘C6 ~ƒÐÆV… X!Å×x"6þ;„ ö#6ܵÐú B[6`…öáD?‚xƒ°¡ÿ;Faí_'”‘Þ-6VHq¤q¦ßžT6l:$aüN…6ä†ÇŸ¡—ž¹³é<6¾”!aã;½¾ÐÙq@ øÐlAƒ<σödäxwôçaž6ôê3öiCÂÓ¨ãgD¤ ™.{²@5‹U4&½ÞbÀaCD22§Q)¨*£`{gë-I™œ“×ÅΫœ°‡=<Ì«âgD•‚Q°Ò°ËbK&ÇxW“qÊ ð%Ãü:~FT©{bçl¼†C e¤*“Ã<½è®5̼à”<:~ÆD™ŒÌF4씑ELó¬®c— {FØÐ< ›N®ð3&ôŒIØÁHo¼¼FNÊ(„Ý6HÚæja_"l¨¡ÒÉ:~FZ)éM׈¤ŒÔ(fr0ьݵ®©³„ ài@:¹ÂϘðA 02› ¯‘“2R.mPÑpþL¦DØžä5+üŒIØãeKÀ6Ù ¤Œd­“˜ÉA’q­°Ï6€§a¯Ôð•‚‘³yh<¢¥–$Lu ðž\ s„ ËÓpéd%?c³ †\4² ¢ìÿ›„€tù_JyŸñà $@ ñS:Þ}3z&x»t(r…¢°Æ^ÂM6uF<s…¢°Æ^ˆaÀf£Qxç~1¢ZIa£$¬±“°áÄ0¼&‰Î°9£ðÎpµ°—6|Ø#l81 ¯‰áP$l€‘gÊò8? „ gr aÄ0¼&†ïã3„ mäßäÊa/6ìÕl7aÄ0¼&ÆaC¹w<ËãBa_!l@:¹—°bA#B‘°¡à"Ëãìcû aÃýÔ}'aÄ0‚&Æ aÃÒ;ì;åq±Lf°aßKØ1Œ ‰±LذFÑB(ÝÕî–Vö½„ '†›h<¢ FÎË”åq,6\:¹›°bK*¹Ñÿ» ¤“HØøRʃ„ït{œD @ ~i¶€c>u~&âë„]”çYñ.õPV¢ÆÓ¡ïðdü3öW©ÿ°‰]bÜâž ëx2®z!iŸø½L_Ïy2v‰qƒý<W¬âɸâƒé'‘ßË çÉÀ㦸Ÿ'ãŠU<(Jû°{f…Scq%šx2®XÅ“âÐ2tð{ɰ—…MLÿ6OÆ«x2P*Ö°HJ{±±}'YüÛ<(Öñd he“ÆÈïuÆöž dñoód XÇ“q'›äý^+“Yäɘ,þmž ëx2P¤OÝ XåRyû2OÆdñoód\±Š'ãŠüÅ^<ˆ¢\læk‘'Yüû<™d6òd øßòd\<™/¥<È“ù pò8ü¾<”òÜ IEND®B`‚snd-16.1/pix/sceq39.png0000644000076400007640000000154411147553270012761 0ustar bilbil‰PNG  IHDR»"0'XÓ3PLTEÿÿÿÀÀÀ€€€ààà   000``` @@@ppp°°°ðððPPPÐÐÐh¶x pHYs  šœtIME× œŒ¼èÄIDATXÃíXÑ’« %QHÿÿkoQ»bívæî®3Ím‡pb•zÛÈ[VZGu?3 Òbº÷ÄJE' ÜÐñQÛ”‚ެ>ö±K©O“®æåÇÈûÉá»q6Lû̘ðÇ©kÇÓæ‡Óä>ÏiO¾3ä5 ëkDsFO€¹eˆŒ U¸ƒèÖ´×Íè%sš†ÃÃïÕA¶#š³1ÄY!r}Ö“Œ¶œ!¸¯Cú’ Ä«9ǘŠ1”JNžXc0&¹,‚­q¹Xñ©Ì…«Z ]á—‡9h“×à¬Ý‚wBqØ¢"ï#J¿)òàÑ»hrk›Q£Ë2> }–•¯²TV©Á]uɲâ²ä¿ õuOîIoÜ÷@Z¯í$ó¾y*}¯cûØß4z|ŸÀ;qOe¸[ý— .†b|þÒó'­\[ s'îµàº¥ß[ÁÕô>À¯üü9U¤Â¢úÙIEND®B`‚snd-16.1/pix/fmeq52.png0000644000076400007640000000071211147553267012753 0ustar bilbil‰PNG  IHDRpκVl0PLTEÿÿÿðððÀÀÀàààÐÐЀ€€000```@@@PPP    °°°pppL0? pHYs  šœtIME× 1{Àß-IDAT(Ïc`€8‹Ñ7+3U "‰Édl:•±€ÈV°ï„)l‘•1.@ˆs"©áSÀéR¨²G ŒÊ‚ÊŒÊB ÷ 2Ì& ¼ èê‘•™0;0Ü`pe ^ƼÂqC6Ì+×,˜ Ð5")còMžÂ`ÎÊàÆÁ0 !à‚+ó4 €kDRÆË´ €ŸÁ¼B ! , T™Í ÊÖÛ€¢•1²05 ¨ÀD `#X£Àµ#+ãTjLd˜ú‘ùÂ&Q5")³ågPùÑ(¨R©\û”4TY»›/b U$e;l€¡*àˆ,ØâI3ƒ(á€W@ÊAV†œr¦UŒ´JVîéÏLÈ3¿Ë¹IEND®B`‚snd-16.1/pix/hairy7.png0000644000076400007640000034712411147553267013072 0ustar bilbil‰PNG  IHDR ÀZ« ÃsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ öÔk IDATxÚì½y|TåÙÿÿž-™}c ‹!a‹²‰¨— .ˆÕ jwk«mmm¿ýuù¶V»<õ+­µlBM¢@‚  lBX–¬$“e’L–ÙçüþÈÌqf2vä~¿^óš9çÜçœûÜg™ësîûº.ÅíOÞ/ Ÿ•Œ@ @ \LveoE=|fæù#¸þ ?ö ……RB¡@g7ð}¶h-@ à;N¼ÁËA·¡T*=æKÀÁŽ2ZÕîšØk=I‚Õí_sÇ I ˆêµÜd2òßö-¨OF£–Žn †ÒF,5í¨T*Z[[™«ßC[ E.¥ &FF©¹¾Ïíõ·œ7c‡rƒm8ŸšôÙ¶@ð]G¥pÝfëµLÛe'4$€ÆÂ*²?óì xê‡O P™ÁŽ7qÓM71jäH:::Xýá_üv«É!õ›ÑŠÑhD£Ñ0räHL&µµµÄÇÇÓ¨Óa7ZÄÙ×41š0î ¿›‘/[ñȰ›1ØºÑ™ÛØßUNZøx†©#¸ž8ô»+x~álÒ Kme2_ÆÌçÈÑ#¤Íÿ×ø)#Gðô¸ÛxtCÊÙØ9h µ°9BÇ+“¿ÇŸ¿Ê#÷-$B̾ŽR¬f+úƒõŒM c||"³µZÍ&ý!æGßHNý>lZÉCˆ©ƒ®ÁJæ0–¿T¯ç‘7PðÍÜ~jTlm=‚F¥&=üzºf¶ê2fÐPÆi‡3%p$~]Ë#>€Ñf¡ÒØÈ1S5·…§®Ä–Ö#¨”JÒ#®Çl³Ò`Ò¯d\wAÑ¡tkL ÃÑ®*,ؘ4(½±í†ã Šàö°ì ‰­ú#-ØŽ6òbÒ£,8Àc£g¢+ÓqæÀ SG Põˆ»bg‘*fys>5ƒ:¸%t" Ö6¾é(åŽÈUhÙÖr”;b¯—˨kzRÐp¦'Rclâ¤é ·FNêy“×^Nµ­…{£n$RLtµŽ–‚GLj ^ \³ØUV6{oâ°9pX%t:=ãǓ緷·Ón0`¶!9̘1ÿyçžyúiÖ¬YÃüùópHìF‹K€8°›,1|øðž‡ur2UUUÔÔÔ T)± "®q¦bZÇ0>?˜G»±†ÜÈÒßãÉ;¢´¦„LJ¥ò÷Ìÿp÷ÂV;¦²fZ—¡œ=“ÂA½¹•¨ÐN–•b²u°ch)‹ÕwaiíBí|ÆJV;ég1Á6žE Ö6#T¬ijÃo&·¾€Ä¸qè”&’«ƒùûWŸóÛü„Óµ¥$Y‚iü¦œ°#)”Nñrô\šºÚ(n«`†-žÂ“E,{ ƒ0I,ˆHað°ÁlÝÃÄIIíŒãÞá·ðÁÇ«x艙 â ©üßþÁ\Â?kÖs_è$šõzY';l0EÛ 8ÐRÊøáL˜5—€Z5ÿù>Ë~üGŽãå éäTïejw ¿ßð ]‘F#U¶031sc7LL¦†bº­Fv$rp4Ë‹09,¨-ßþùÕu5SßÄžì|~÷ÂÏ1W¶rWb*†Òz~0‹¶|†¾¾œ3wÆQoì)g»eš° î2õ©. O–4\Izø8²÷nfÞ¨d¾–ʸ^ÉÁ3ÅDG&à°ØÄž@ ¸¶ˆÆ†$9pø v6’$±àþûäùµgêè0pXlH‰qÃyú©'ùåoðøc1{ÖMtu°™,`w Æ!á0ÛˆŠŠbÛ¶í¨T^]Ï1AØ»ÅÃX \Ûm,ÃÚØÈ’ôïSº£‘Žî.Ž›jÐ(Õ˜ë I C¡T Ù¨‡8: S·µZEœ*’å•ùÌKNãƒCÛK€JÃèØT:Ÿ±«­¿æãÊí|üôÛŒÔÆòÐÄÛÙ{´€AR¦3mH‘8¬vÊšªhLT²¥³ˆ×g=Æ›kÞEŠÝhá”ñ C§ ¥£¬ƒ-õ…üæžøíªw˜8jÊA*‡a©hÇŒ:2ˆÀØL…-8®³¢‚B£’[3$ÆŠf,ñ•Qgh"5hª¨ ÂG¢ Åh6ÁðÙI RÒØÞ–½Û馛S¡ÄOMbBlcÃãIÑ Åd6ØîÀÚiÂd±Ðe5Qaj +*;¸ë–tººº8hî†ÖªmG­Mè´(Ô*:Œ]|¹o§*ÊxϱŽïM¼ e¤–ênjšÐi#˜6<…Z½ŽœòݤtÄòú‚çùÕŽeèôTÒÂ["æ– J†„€¥çˆÿ<@pM @+6›cÇ{J‚èhpHH6 I’p8¾¦+9ìHH8¬v$Ú í|¸v-?¶˜¯wîdê”2$»Ñm–Ãâ`ö£K0YíH^•è’Ú±7Ї±@ ¸ÆQØÑ:Ô¼¿~ ÅõÅ|²™vK™[¨ël潢Ϥ·“±ís$IÂXÛŠ±¬ÇÄÚVþrøcF:BYúé2×I$vFðùæ$©‡r²ò(CB)j(ÇRqÅu¡|r`3UÆFVΡ½ª‰â†Ó”[ëh­mÂ<&©´ FJìÕgqTZËPމ–‡Ì®(ÜHÍÞ*GYX³k=G›Ë9YkäVi,Š39%»·Ä“®™Àž/¿fSÍ7T™k gåëhï»›s¿ÿÏ;œÜNXÙ6"Šu•*m$]3žÅpTYÌÝ èÂÍ 5óÇÿaŠ2žêºZ#-ÔVÕbDë×|1¶Šnijm¡Q×HUP;5Mu|yb7­]íì:u˜š¦:n º/·~e¬•FÅÑÆ2†ÙÕÄWkø‹æ#nv\‡QßI«ÔM°#ÝG÷óÅñ0cqÄWkèo§u_ç%bî2ñ§•ãLžMí;8£jaÛÑ=hO3\I×™VNuŸÄjÃŽÁ5Ca£»»›7ÿü¶Çü{¾w7CÒqØ$45[óòåeƒëSzFH‰Œ>æžïÝÅìY³˜2åV®ú_¼þvSQüàíKú A¼1éuŒ¶Þ‡6=;ù®8@¼²ÚÀ.õ8)+`w€R(4*f+((P€J6ÊÀo²íH  P÷to[zž¹ •¥³×Án¶¢Ô¨‘$ ìjeO9gtBI’Pª”8lv”5‹†ßBMA)ùÊã¿}%õôn+ÔH’Ý*PƒäèÙ¯kŸ»ÉjG¡V¢T«œu”Vky>*¿Z#‚Q:Ë @ ÂázÖU){ê¥Tâp8zê‰vIÞ‡{]õq»dw P«¬v”jìf‰ÊXŠ+ËÐ&Åô´5ÈuUjTH’„dsôøˆ(=õP*P¨=ŽI²;PjÔ8lvpHÎåöž::zêŒRÃÚ3Ô@©R 't@pM“Ç_„Ùbò|ìÖÇ q0?vJ/ þ^ºÇ’î$ŠÀ^ÛµšÍ¼TºŠ²õûQ<òç—¥ÓC(Ûl>+!IF»Iœ @ ¸qØHF+Ê ì°}Á—ÙŠPj.ýIÈ!á@piP¡ P©é‰«ëý¿Ðóz 5¾ŸÍÉŽF©B!ùùÏŠ D÷U jÉî kO%¸óI4¢Õ@ Á¥³³‹ÿ»mmºR¡DíP0wî""ÂEë@ ‚ JUU5Š-kP((• j•Z´Š@ @ ¸h¨U*” %J¥B‰ZÝ[€”––“½‘ìì´´èiiÑsìØI:::ÉÎÞØïµ´èåm•––{(!€cÇNÒÒ¢‚rÿþê«Ýç¥Æ²³7ÊÇÖ‡¥££S\=@ ‚k—Í]_߀Åâ)°¾¾­[·÷O€¨Õ(•J”J¥;÷2wîæÎCxx]]Ý„„<ˆººz¹luu-ÇÓÝmô¹³ââ2âãã˜;w#GÆÓÖÖÆñãÅlÚ´›Í†FÓãrðàþõ¯47·ø­|~þרívvìØÙlA« ôY—¶¶6Y0Ùív¿Ûš;w{÷î§££“ººzŽ/öY»ÝŽZÝ©F§käøñbÚÚÚhkk£ºº–òòSò6„X@ \íäç @AÁ! †NNŸ®âøñbÌf 11Ñ”•õØÀÝÝFÙöe{kTj” J…B‰Z¥êUÀl¶½‘ššZÔj56›ÜÜ-(•J @{»Í›óhkkã³ÏrüV|ëÖí8p˜ÀÀ@²³sèì줤¤ €S§*)*:@WW7CV«Õï¶ Ðë[‰ŠŠ@’lܸÙg]²³s())cûö¯imm÷»½ˆˆpT*Û·ÍÎ{éììdãÆÍ½êräHÕÕµdfn ³³“ìì22²(--çäÉ óÉ'Ÿ;EÖIqÅ @ ®jtºF–/_C^Þª«kؽ{mmm¬_Ÿ‹F£‘;.$'çK:;;Ù°á‹^ÛQ«ä%C°´Ú@–,yŒ””‰Œ3Š  m¯rV«'J¨¨8ÍèÑ#ýV|áÂûHO¿Užž9óFŽ`âÄqòü Æ‘œœØgèŤ¤±üÏÿüƒ{ïýZ­–1cFù­ËŽ»hnîÿð®‰Ç3sæ455÷ªË„ ßÖ3(HËÌ™7Êm•ž~+II‰ttt’0‚ŠŠÓTTTŠ+V @pU3dÈ`–,yŒôô[1M”””QQqšë®Ý«lrr"3gÞHkk[¯euOˆjÚÝ©¿ë2v±0õv´Úo†Ãá`øð¡òô®]{©¬¬føðaì߀–=))°Z­tuu3sæò0-w$I"/o……ÇQ«UÄÆÆ°ys ñŒ—DNΗÔÖžaúô©PZZÙl!!a„ÏF<8†ˆˆâããho7ø­Ë°aCHNK@€†±cÇô$œòÂáp°ys£F%`±X¨¯×±oßA¾ÿýû õ¨KNÎftº&&ON¡µµíÛwrà “:t°ÜVAAZZ[Û0:˜6m²,²@ ‚«—.p8Œ3 £±£ÑDZÚM466qôh6› …BAYÙ).äÞ{ï&8x¼öövrì¢ÓjBñìß!547°úµ?x„áݲe›‡ÃÂ…÷s¥¢íökŒ•VHlì`ÂÂBÐNDDÆ ! @CXXhŸë¿ùæ›”––öšúôi>þøcÖ­[G{{»8‹@ ÁUBPÐ  " @îLA£Ñ ÑhP(|K^’Äaµcî6`5[!T*5ƒa2 èzŽÁ` << £Ñä·b¥¥¥L›6Íç²íÛ·³dÉJJJ8vì©©©QPPð­BR*yòÉ'ÅŒÉd"##›Íưaø÷Þ{E£Á%&44”ŽŽ"##¨®®',, ƒ¡§c!$$£Ñxv2Æ:’β6´Ú`‚‚Õ)µ 2“ÉèÜQ‹‹Å†^oè3y_RRMMMý>””RRRäé´´4!@@àV«•_`½õÖ[B€ÁeÀl¶ÒÝmò$GŽñîv½_2$4–¤¡×NHhuu ˜ÍZ[[å2ááQÄÄD¬Åb1£×ë2Ä·Hii);vì@«ÕDBB/¾ø"Ë–-ãá‡fùò儆†òàƒг(@ \% ‹Jõ­÷þý‡±ÛíîæìÄǾÍxh2Y$‡3¢W’¤¤$~ýë_{Ì[¶l!!!,Y²Dœ=@ × ’ÃÝbéwùÍ/¾HcQÑ9ïoöo8o • •cP 8çkY’$Iž¶Ûû—!½_Äjµb2}Ó×b±‹@pÕÑYWGóÉ“—d_EEÔ»ùµºè¨­¥úë¯/Ù1g?ôI÷ÝÇCë׋‹@pÙQ‹&@p5 Éá K§£<7wÀë7:DéU`„OûÑŠŽ>ïíD%%Ÿ–€¦Ÿ]@@ 'Ídzõµ×¨Þ¾»ÕzIö;á‘G<¦ÛNŸ¦nÿþ³®7êöÛãÛ7V¥Õ2iÑ¢³ncDj*šà`qòB€@ œ+]tÖÕyÌ+ÎÊÂìÌVž›K—N×k=ÉnÇf2 ÌÀ $züxyú¶7ß”{ú‹·pØlØÍæ³ï[«E!, B€@ ¸8ØL&psD=º|¹Ïr§óò(ýüóoÚ~„Z«eb?zÜE@Ì„ ô8•j5Jµ0!@@ \TŽôe7ú]^‘›‹Ù`8ëvÂGŽdtzzŸeFÜ|3ÑcÇzÌ›ðè£â$B€@Лšš”J%qqqX­Vˆ ¹¹™€€ÂÂÂ0›Í477€N§#$$„`cÞëë뉈ˆ ((H4ðÀn6ÓÕØ(O—çäxL›ÛÛ)ÎÊòXÇÜÖ†Ù`è#è~O@~Éù‘Œ  ÅÄp÷²e NI! , mD„8  @ œ?›7oF¥Ra4©®®¦¾¾žÐÐPŽ?NBBåååX­Vn¹åòòòˆŒŒ¤¬¬Œððpêêê0Üyç„……ÉÛÜ»w/mmmtttpÿý÷(ú<9ùÉ'lxâ‰>Ë(|üv‰ÉÏ:®ù£ÓÓ Š‰aÜÂ…D&&2dòdÑè@@ \xÒÓÓ1›Í|ñÅ̘1ƒU«Vñàƒ²|ùrêêêX²d %%%”””ÐÝÝÍ~ð–;}–,YÂîÝ»©¯¯÷ 'OždÉ’%lØ°ŽŽÙµk¥¥¥444ˆ† !qqÜõp:?CUÕyoÏ{ÈTòÂ…„ &Z \}$##Ó#^àò’““Ã<€Ê+J¥Ân·c·Ûåe’$¡P(P(8yÀd2¡ÕjQ*•½–¥¥¥‘æŒfTRRÂ[o½%~Œš;—Qsç2íå—Ec‚+W€˜ÍfZZôòtppØE¯Ø"g¤‹å~"iàÊ"??Ÿ®®.Ö®]Kzz:S¦LaùòåÜzë­ÄÅűfÍ"""¸ÿþûX¹r¥<äjõêÕ 6Œ¤¤$Þxã þú׿2þ|V¯^ͨQ£ˆ¾IÙ@p•ÊÊÓh4ß‹ -'®I:;;  ჻îºËc:!!)S¦ÈÓ?üáåß7Ýt7Ýt“<ýä“Oz¬û׿þ€˜˜˜^Ë@pu£ìO!Ir ÑhäJ¥-'®I>ùäÑ@ \l"@ B€@ !@àrRRRÂÚµkEC@ ˆ@ \|š››),,¼ Ûììì + @àÉ_|qQ¶»téRѸ@ \D&t@pÕÓÜÜLLL «V­Ân·{dÒ^µj<òÈ#Lœ8ñœöñÕW_‰†à z@ÁU‰Õj•¿7lØÀŽ;hiiàóÏ?—¿]Ù·Ïœ9ÃêÕ«±ÙlH’$P !@ ojkkåß~ø¡Ç·Á`Àf³ ×ëåo÷u6mÚ$ •‹Y?ÁÅÅd2±|ùr²²²®¹c鶴¥bófùc·XÄ!„‚‹Á–-[èî¸¸×²ƒú]Ç›?þ¸ÿÆ^GG¿ËøÚ—àâ ÕjY²d .¼¦ŽÛP]ͧ÷ÝÇg?̦gŸåË—^ÂÚÕ%.@ È… ##ƒåË—‹3$¨¨¨ ¢¢€îînJKKåeMMM Ž9ÒïíuwwóÅ_ÈÛì‹þ8Ÿúé§â$ . a ,9tˆô¿ü…§öïç¥S§ÐFFžu½ª;8¶f ÇÖ¬(.;W¬ú¢E‹„®aššš¨««ã«¯¾"$$€={öx,/--%&&fÀÛ®¯¯§¾¾žë®»®Ïr_ýµÇþ\ìÙ³‡˜˜’’’z­³qãFfÏžMtt´8‰‚‹ÂägžéW¹¶Ó§ùèÎ;i;u Éá ÷é§™¸hS_z µVËà”Ñ @@píâp8$ •JÅÆ‰‰‰Ád2ɤ¸¸˜úúzâããÙ¸q#’$Éþ.ŒF£ÏŽcÇŽ¡VŸÛ£Ïµ?×>ý9³÷µL ¸”|óÖ[´–—{̳[,®\IáÊ•¨‰JJbÎïOò‚¢Á àÚ£¬¬Œ#GŽ‹ÅbA§Ó=Þ#FŒ<ÎZZZØ´i·Ür‹<¯««‹ªªª^Ûß·o©©©¢¡Cm-MEE4Rà€Ç²q>HTRC§M»dõ™ôØcúç?ý.ÿÞ²e„†2tÊqò à»KGG¡¡¡ó<(gÚ²e ©©© JJJP«Õ¬\¹’eË– x_V«“ÉôDÅrmÛ}¿Ó.¡A(ønóÕÿù?TæåÑqæL¯eÅ™™$Ýw­_߯m[Z0µµñaZñ7ßÌ­K—Æ ØØ³®oéè £®…JEœ9ŒJOà†%Kä2Áƒ£PŠx4@@𥼼œÄÄD>ýôS–8 òòrJKKihhàèÑ£>{'l6–s 5zêÔ)9B–Ãáň‹¯¿þ“ÉtÑzE6mÚÄ=÷Ü#Nþ5½+W¢/+c÷ÿÀ‰uë°›Íòòš={8òï“tÿý <Øç6Ìíí|zÿý´:…¡¦FžòÓO9ùé§„ JòCq×?þásý¢U«8ºb] ´””ÃâmÛÄÉW ⵇ@ ¸¨Ô××ÓÚÚJSS“‡C÷îÝ»ePVV& ƒ+Vœó¾V®\9àu¬V+---æ’††ã|÷‰;–{W­âÞU«øyg'}ö™¼ÌØÜ̦çžcÓsÏñÅóÏÓåbèŽ*0‰‹ajmõ¹ýΆÆÿû½æ[::¨Û·#Ë—SýÕW´””ôo«½[ä8@ ¸Üˆ@pÁq88Ôj5~ø!ãÆ£¹¹Ù£LII Ó§O °°˜˜’““ûtÞ>[/ˆÃå§¿lÙ²…ÇóöÛo³qãF¹WæbPRR"|O®A”j5I<€6"Âc~õW_1"- …BÑûY«eÊsÏ‘0g¥ë׳÷Í7=–'Λ‡Z« f×.¶¾ú*v“ kw7m§O÷Úž¹½å7ÞÈû›Çð+ÁåÇÒÙ‰Ã+€†7 ó.[Æñµk/y}ÎÍEŽûSZ„*0PœL àÒ±mÛ6æÎKqq1¡¡¡ÄÅÅQVVFss³Oƒû½÷Þ£¥¥…¸¸8Ö 0'Áš5k¸ï¾ûú]^§Óõ)ZÖ­['N à’ðšŸÞŒ¾ˆ7ŽYãÆ1ë¿ð[&>-ô#öÿío>Ň¼­ädÃÃʼn8NoÝzÖ¬ó.± /+£zçN¿e\媾ú cK‹_¡½‡ª¸¯¯ècÙÙüüöUFr~þ5jàþª'vÒ$¢’’ä²³ùK†9_.5z ³9 IDAT#‰ó手N@ SP‘‘˜xÍ7ÅÉ“'9qâsçÎ¥¥¥…ƒ²xñb8@KK Zç[Ú®®.ìv;*•ŠƒÃÉ“'ijjbΜ9­~ûöíëW¹Í›73fÌ>úè#}ôQå.’/¿üRîµ\^ìv;§OŸöéìZãú§žbÂ~€Ù`ð[FñyKm·X0TW÷YÆP]Íé¼¼óÞ—»1_ð·¿a3ý.w BÁõQºý´>ÊŸm;¾Ä‰â,b§/‘ã-@nß.Ááìn߮߆cÇh=vL.£P*‰;€ŠM›hJYYÝÝÝ”••Q^^Ή'X¼x1………477˹;òòòHNNöHXZZJIII¿H¹Wƒ ÙlÆáp°iÓ&Œ^ÀQç¨Édð0/555˜ÍfÅP… ‚Ãá ®®ŽÆÆFÑ€:(uPÐwæxÌíí|ꣷSØŒFê ü †óéðe¬»ÖW9&…qà.”~D‡Òkž²:z÷>x‹ïiÉkï:úûø6 ¯º¸ w1bó%U™™Tº­àc} ¸þÉ'i**¢Þù‚GáU÷=K—Êûß³t)ÁC‡”Ä„Geê /œÓu•¹`Õ_}åW¹·sÁÿþ//UTˆžC!@¡±±‘Áçù¦@ ð6¯»î:vîÜIii)555lذ¤¤$vîÜÉîÝ»œ‘¼¤¤Ä#³¹?Ü×/& ¬X±â¬¾ +V¬ð™½/:DGG‡ FÜ9s())aûöí¢A®0Î|óçK„Ü\Ÿ÷JÀf6sÌÍŸÁe KÎ=¾ å?¤Â‡áìëw_ëøâ¤ðóíkv?"/Ñ#_¢wσ/!âO¤H^Äßþýµ~Š?q¥ö*+ù-v<{NŠW¯IBå£Þƒ&ÒÙ+íNsq1_¾ô_¾ü²ÇüÁ)) ›>¡C™ó‡?x,Ë{í5,ÔìÚEËÉ“gž®:[Zøøî»¹ïɼÊFËœ ÇŽ£´´”|PÜ‚«S[x]÷õ4ù4æòö³>{¼çkú0ø}Š}âŽ~澄P_ûíËP¥Û÷'v|>_œß®ãÐFE±03“à!Ch,*òÛûθ… }.ëÒé(ÏÍí÷ùö'L½÷v£±W/ŽûGåõÛ%P¼Å•Ýáðè=±¹‰•ÈQ£÷ÐC¨µZ&.Z$×Cwø0Û~ùKê½Ú`èÔ©ÌxõUT½Ž% 4…RIâ=÷è#$úÑ+0éõ½æ'=ðC§N%døð«î~½{Ù2Ò~ó›žûÖ‹+EL]±$##£W¼~ÁÙyóÍ7ùío+Oÿãÿàõ×_'99ùŠ«kMM ñññ×Äyqk~~>·ß~;:ŽÈÈHÖ®]Ë’%Käù®rîÝ—«šššxë­·øÏþêU«èèè`Íš5r/Ç»ï¾ËwÜArr2k×®¥¶¶–Gy„6cØ|Ø%cçÍ#xȳֿ? Ì«·hêóÏ“pÛmDO˜ÀøGð53a#Û8âo» ‡ó:(ÎÊÂä¼®@ãÑ£´×Ôô$j7Q¢ò!V$§øPñmïHÓþý4ìßl}ù峊»š;ý†­ 'ýwÐFEù\>æî»±øø?Š»é¦ æb·X8½e aññ ¾á†‹þ >üŠOW¬YäT¼Ëý<¾Ùºu«‡¹T8p€o¼Ñç²C‡a³Ù˜1cƒ°°0¹®Z­V>×.ÜË\vÊÊzÍ2ÖÖ¢êì$À+{ð¦&nœ=[Îwa6›IJJâÆoä©§ž"//ªª*º»»Y±bÏ<ó Ъ¶¶–Ûo¿eË–ñÀ°wï^fÍšE\\[·neÉ’%r»tuu¡Õj/Z¯–wû8p ÏëmÆŒ=FÓ9:gddôºl°]BGäòòr>ùäþþ÷¿c08í#òÐÖ­[ùÁ~ H‚sB_VFÁßþFó‰~ËÔðô¡C~3¢w77sìÃÉsµPøn9J¼dwCÙÛÿ¡?Fµ÷Ð!_½®OÌ„ Lzüñ~µÏÄÅ‹Qûé9 “C”¤ Îkù…âRíç\pLå]OKG¦¶69q‚â¬,ôeeè}ü_\÷½ïaíîö+@F§§_ôv“ìvšŽë¹W”ÊK"@®tÄ,Á€ÈÍÍežÛ¨¬¬Œ±cÇRXX( ×<×ïuëÖÉ¡S333=Æ×›L&ÚÛÛ)**"--M.³xñbt: òö8€Éd’Ëåææ’––ƦM›xðÁÉËËó¨ÛÁ™DN>þM›ˆ¸çb€¦ÌLªkjX䌘TXXHxl¬ìÌœšš*·‹N§“ÑeffRVVƦM›ä¨PÐÓ3ðù矣Ó騫«£©©‰êêj²³³ikkcáÂ…üéOâõ×_gß¾}$%%1vìXª««2dÈY‡s¹—kll$00ððpù¼‘••Åï~÷;yÂÂÂ>·™™™9`ßw®¶žN»Ý.GÅò¾7‚ Á”gŸ%>5•U³gûí¹ÐFFà òà‹µ·ÞJÓñã>޽}ü…tíkˆ‘¿7ÒþÊ\wÏ=ìsÁ))Œ¹ûnb&L'ÿ*& 4”€ÐPfýò—@ϰ¯_y…Æ¢"J²³©ÊÏÇÊ·=îBÄû:u•q]G'22z]£§·n•C{|iìX>+/ççO=…¾µ•Z• n¾™gžy†èèhðjÎÎN¶lÙBCCË—/'55UÎŒÝÐÐàa¸oܸ«Õê‘°O§Óa4ÉÍÍ%55•÷ߟçW§Ó¡Ó鈊Šâøo¾ù&Œ;–´´4ùXÜûÈ‘#$&&Ê+xàøê«¯(..&<<œ•+W-Ÿ#œK¶ò’’Jœ™™¯rœ®{c×®]â$èÅ™½{å¡P®±úq³fù,{äßÿæ‹^@òqMÄÉ“™ýÆ>£^Ú¼™}ý+MÇ{ˆÉM|Øñ?<êlŽÎC'OFÔ¯áF·½ù&ñii(”Jq\cBð!Äß|3Ó^|‘u÷ÜCíîÝX::°ãßwDá&N¼òÝ{ÍÔôîQKœ?…RIg];ÿ{ g˜–¿^€QééÜýÞ{D^w8yB€ú‹Ëéüràît\PP@ss3999,^¼øÛ?0IB’$Šœã™Ý Q‡ÃAQQ&“‰ÖÖV¦NJvv6C‡å›o¾Áh4ÊNÎÛ¶m“})âããÉÉÉ‘·=oÓ]cìçÏŸONNO<ñ …‚ÒÒRÒÒÒ(**’#6 JJJØ»w/©©©´µµ1}útÖ¯_$I¨ÕjÆŒCss3‡…B$I¬Y»–H§Á™ía¬»ê=×Þÿ}ŒF#ÙÙÙ~3aFÞxã fΜIQQ‘ßK®ýdgg£V«=ÚÖõ{ûöíØív***˜>}:¥¥¥466²`Á, ëׯ'::šÒÒRÖ¬YCdd$Ð×µWˆ\ø'YYYüêW¿º ×—»ƒû¡C‡Hñ¯~19gó¬¬,ùº>›‰àÚ¡$;›ÉÄ‘>`ß;ï0÷í·}–Ý÷Ö[àpøì‘:u*÷üûß‚Q¯' $ÄÃñvØôéÌ|í5ºt:9ÿB@x88{èô¥¥ä,Yâw(UÒ‚²óÍr>w"®»Î§³¯@à…‚G¾ø‚öª*lÝÝ4±ã׿¦­¼\ Þ¢Ä=ü±Ä·=w¾D‰·8)ò1|ß=’—/q}zËÖ?ú(Óÿë¿˜è• J ˆààrˆî/.§ãj¯Ä>K—.%!!Ác^AAOrÿþýŒ7NÎÁÐÖÖÆòåË™2e ‹…µÎ1¥ØívÙ/Â÷}º“÷íÛçÑÓPPP@AA111²s~[[mmm ^yåÂÃÃåLÞû÷理¤Ä#Ň«WCI O<ñ§NòÛ6®u]TWW3hР^庺º8~ü83gΔëçqÊW›ÇÄİe˹‡§Æ™m¶²²’ÎÎN’““yë­·0 Œ?žO>ù„-N'¸ýë_Ü~ûí|øá‡¼ôÒKý>ßy}$÷j÷3\Ä×5Ö_Öº…ç4}f6¿PTŸ%I•û1Lž<¹×5MYoÚÎõ^;ßõ—¹o¿Ýbatz:E«WSòÙglûùÏý†{Uù0”$àÌîÝü{ÂÙp>s¦OGÙ–“'åmZÚÛùÐÙ ê½/×vÆÜy'S_|‘á7ÝDÈС℠. á#G=~<á#G²ïw°™L˜Z[©Ýµ«Ï\%îøó/’€iiÌúéO9öñÇœ\·î¬™ãÝ_3ÕP¶q£ B€.›7ofÆŒDùqÂrÇåЛ‘‘Á#<‚Ñh¤¡¡½3LÝ(--õp~÷ÝwÙ¼y3£Gö0T~øaìnIûìv;zyy9§OŸî5„lß¾}Lœ8±ßÆnAAyyy²0©ªª"&&†ŒŒ bbbˆŽŽ– ðöövŸ~ ‹…úúzÂÏ’x¨ªª ªª8sæ gΜñYÆ—±œ——'ûÜïbݺu¬_¿žE‹±uëÖ^ÇÔÙÙ)Ÿ7×y=pàUUUò·ë\ÿä'?9'ãÜb±øLÞןkìBã^—¾œç½ÉÈÈà÷Înz×y:›_‹ë¼ˆ ÷À ÎñËÞu:×vÙ¿¯,¼û.»¼rô…µ³Óo8Ú³åˆp”…©µ}Y&½¾—¡å/L…·CøÔ_$ý/9gçmà\>s& >ù¤GPX­˜ÚÚØþÆÔ:‡n÷,p ÷“ˆVÂÐhµ8Zåš#÷¹ç<†0J>„~îµòœ2n¿aÓ§{ÌŸüÌ3W]>!@—‹Å2à ή!Q{öì!99«Õ øvJîîîö*ã"??ßÃkmm%??ŸqãÆõü[­Øívìv{¿ëW]]-år7æ]órssIJJ’{7L&&“‰üü|Þ{ï=^ýu²²²|ö0äææ1 vòvÌwqèÐ!Ÿ’|áz[î¾3Ðó4\çÏý<ž#øéÓ§û}œ}µáøÃó¾ÎOŸ>Í¡C‡ü^§þöç~üEEETWWŸ—c½kÿ.âÚ~aaáyoWp呼`ºÃ‡="ô¸7}å³pø˜ç+™ž÷0€¸™3÷ÐCgfrú‹/ü¾9>›ãøð3„ø\V” ƒbc™ç¢(ë«•:ç°êÍ/¾Ø+ï̤ŋ‰LLÄÚÙÉ–W^`Dj*³ßxC.ãVÚP]Me^žßûÅÞÑAõ¶mToÛæqJ’ÄÜ?ÿYœ,!@‹’’9b“;.'j•••~C溜»£££/xýŒF#ƒÁïr—söüùó{-khh ÜÏÛ׺_ýußFâîÝàVµk×.Ÿy ÊN÷7>ýÄÝÙy×®]ç•ëålmÚ_:;;9räA>œcû ”p!Úp ôµ?ƒÁ€Ñh<§:],ôåË—_6¯+«ÕÊþýûÏ:\®bófŠ?ýTž®Ùµ ½3 ô8IÏúÅ/ü®»ù…h÷Ñãä ÛÕØH¹›ßÀõO>‰¥³“âÌL$úÎûàÝã¡äìy"\ëœúâ *ÂCíGì¸D‡P1|êT@áCØœ½…{–.åú'Ÿ•àŠ&#RS9òŸÿxˆ×uþÍÒ¥÷…TäæÒpà‰óæù ” ùþÞÓ®{W¢'¼óè;î'DÁ@),,ô›m |ðÁŒ3†’’ÙO—WYY‰N§ãᇾbÚ¡½½}@†eQQüÆW»÷R”º2ãœõ%*Ü÷}¾õpïU:L&UUUr—;—3PÂ@immåµ×^ã7¿ùM¿Êgee±páÂ~Ÿ‡C‡qÛm·±mÛ6,X è¯áí>¬ñš5L”J9D_ ¿ñFöüéOÔø‡AQQù÷¿‰4‰Äyóh-/ç芔8ïq£^OwS“Ç:ÚÈH*US¹3#´·cëéÍ›‘ìv”~ ŸÀðpTZ-FÎ#›´û¶ÜkÐ+ó´ÂÇ·{¯Šëãnl9ìvºœQö$·kH_ZÊ¿Æ#öúëî쵋JJ">- ”J‚ú1tW ¸˜¸¿4Pz}ûü/Òé8¶|y¯„•’‘a÷#DÜËEE1z4v‹E`D0 xá…ú,c±Xd>z=±>’_íß¿ŸánY7½ý=ôz½Çt_¸«««{9²_,Nž<ÙËŸ£   —φ/?¼¼¼~%žH8p€ïÿûWÔuäîSr>bçrÑ—½;Þ×®ëÚpïÑ‹ŠŠ¢¼¼œ}ûöÂÉ“'û]£ÑȦM›ä  Áå7åݦ—ê>¹RP©T} ôš;1êõX::<ÄGPTñ7ß̨ôt¦<÷œlL´–—S™ŸÏþ¿ü›Éä×iõÖ?þ‘и8ŠV­¢ä³Ïz ßP¦†9¹š/ƒÆÑÞŽ£½/á^Æõ6Wò2¸Üs(ø.£ª—±Xhu ŠáUH_RBKI‰Goô¼ù½oõjb'Nãß—äàè`Ôë=z&|ݧÞC ]¿OžLøÈ‘„%$øL>xè_ÿ¢Â™ŸËû¾n¯¬dYb"³õ+†;“ïöEÈС Ÿ9Sœ8!@¾[¬]»Ö#Äí¹ÐÞÞÞËÑÚ`0È!lÝ íµk×ò‡~8X644ô¡ÈeÄM›6ͯHšîtúr©îNå} €¦¦&*++ý«‹άÂþ½Ýůö¨Q]PPÐ/‘s©¯¾Dêt/§;oΜ93 Cû|DÀ…Äu>ÏUüøŽãÇgãÆDEEâS˜ø¢x!„˜ûùr¿OšššèêêbÔ¨Q×ܳÑÜÞκyóh-+è×ãp†AŽ™0AbÇDgã}Ä–ÿ›Ñˆ­»[6Ìý ƒÚú£yð 7ƒ?jìX”*-ÅŽ¾†xøêѰ۷+g‡šo³E»ˆû[\wááþñeˆ¹5v, •§»ºÝb¡ÍÝÏb0ùÀh BÄ K–pÓÏî7»@p1ˆ›5‹;ÿñ6¿ô’GrNï5Á±±:_Iv»GÞ¸›nâîeËzmÛÚÕÅÎßÿ‹Û3^r»GÝï›=ÿýß@O/fȰa[Zzõ’¨ ý¶'Ñ‹¹o½%ˆ¸¬¯Â?Y§3•Éd¢±±‘„„„^Ã[ª««Yêé>,$''‡ùóçóÔSOyäïðEVV?þ8&“I·àrÐ=ÕvÕË—Ø—ao4å·Æ®õsrrüGVVÖyêï¦ Ÿ:ß¡V¾ ´ýÏÆ®]»z [»Ü\ˆóy®×€ûÅêêjêëë/èý’ãå ×ëinn¾&H`x8OìÜIÝþýlzöYyÌx—N‡îða&.ZDcQ«ç¤½ª ³3±§wÔ(_Û}9x+螥tæçq7\ì}lËW†Ú)(”n†p~»ÊºD‡ Ou÷ž¾KH`ÉÁƒ„†zÌ·4>Ìê´4p>û­ÝÝX»»ùæí·©ÌËcôwrÛ›oŠ?dÁ%câ¢Eäý×a†^¾U®k}аaLwFtl8tÈC€[»–Ø”¦y…Ïyê)NffÊ׺ ‡çË#Î’àÁƒ‰LL¤ãÌÙGÌÝIÞnµbÔë9óÍ7œq&Lt'á–[Hô¼F+€ŒŒŒóŠÌs-àrøMHHø6s·›ÁíÊ á•Åüùó{•×ét¬ZµÊçØ}ø6#´ËA÷|ÐëõrD­óq>>[]t:]ŸÎäÞmp¹ˆãò®]»HMMõ(`ùòå}æ¹TºÝÏïÅÄu¼çz ]*Ç÷²²2BžÑhÐýãÏùÜjµÒâ4œ¯”ëørR³s'9ÎvªÌÏÇàÖ»tÓë¯Ë‘kÊssÙáL”éKL(¼EÒPº‹ˆgr€—ã«Â;2•K8¸Ä…«ÇCí&:\Ë\Û¶V|;Ÿ+ðÆåóZ]Íÿ„…‘8oƒœ"¦ÿøÇ ™2…³gó+‡ƒ’ìlù³¾´ôÛál 5;wóÍâÏXpÉèr{Þ¹‹×}ÑTXȦgžñ¸\׿¥£ƒº}ûz Ÿ|ÂíÕÕggËþ_Þħ¥‘¼p!Ü>R.Bãâ‹àgâOÁU.@\9&–ûkx-ârríþ„[QQQ¯äh………\ýõä:³äú¢¼¼œööv®sfÇuÍ+((à{ßûÞ9Ü®Lß}í÷lœí}nnnŸyDúCmm­ÇК¾B»^hº»»û•Ì®¿ô§÷äb‰þþl733“_ÿú×zøs½†|­ç}~õz=µµµçÕãרØ8àؾêb2™Ð:C¥¶··SQQÁÏþsŸË¯5ôeeú¹WŽ|ð¥Ÿîa”ãÇh÷ þr8ðŒã¹ÙõQ;—«ñ ×{Ø•˜BCƒç0×Ç}¨••žÞ«ÛoïºIÀ¸… ц‡s,#‡ó^t÷ÿ8åv/œþòK4!!Üà%~'.^Ì­nQ‡ÌÌ[$ WnCu5§óò<ÑéC\ûʱã*{líZ:ë꘷|9j­–€ÐPÔZ-a ÌxõUf¼úªhøk]€zÈËË#==ÌÌL.\è1~>//ÏgVmWÒ3o¶oß.¿5u6×_}ŸupùN¸ ׼メ»UUUÑä6¾³¯ävUUUthZww7'NœðÛ+u1ÈÈÈè³å\ý7ü]“8p@vü÷å'áº'.Þç·©©é’%ýûÏþÃÓO?Ý«.ƒ}ûöøFÖÒÒÂûï¿ßïd’ß5F§§ó}ÇÞrò$Û~ñ Lz½GÄ_ù1\ßááŒs¾ì)ÉÊÂâ4²û ë$Ðû­¬·¸q/§òF®õTn‚ÃÆ·~!®áU.›×÷¸… ©+( £º•óOþtV–ÏP½’W$ÀXWG·sþŽ_þÒ£\ù¦M<þÕWr=à'' ”oÞy‡Î|þ‚Bx߇þD¾ìÏa·S™—ÇÿKH@n|ùeFÝ~»¼ø9sDÔ7!@î˜k8Uff¦Ü{ÐÕÕ…Ñh¤©©É#*ÕñãÇ=Æú»°cbb(..öØ~~~¾Ghmmm2”½ÏÝÛÚÚœÜïrŸŸÞëßyç—­þgsÄ¿×ã¹2ëÊŸà¹Q´|¸X¬]»–W^y…+Vx‹…†††>·Q\\|M'8 KH`ì½÷P¸r%µ{öP’•%;¡» w÷hQ¡¡„ñír»}i)æöv =ï¾Æ˜ãGd¸ñ·eÞQ®^Ë]ßî®\Û—‹—àðŽlåml•9ÅF€Ûö|EËòvXwï9Ï^É ˆ?eÁ%Ã]|(8{~ïûÁû¾õµƒï¾ËÁwߕˆ…É~\a ŒJOçÆýˆðkЧN+I’P(t›:ŽÀÀ@ƒÝÝÉôرc;vŒ×^{ …B$Ièõz¢¢¢äråååƈË{Μ9ý®‡ËAÝÛÁÕ‡î• Û]eggÈX§ÓùT%IÒ9µë¹8o÷çØÏe¥¥¥²ˆ<×}øÚ~_Žø}µiÚᦛnº ÷ÆÙ\)\ˆœ(ýÅW`W¾š!C†ôüqžçsæb<«®TâfÍ¢rÛ6LN±«Pzf œ’ÂÝË–¡Š"ڭDzþàA²|Cuµß|zzÃé/( ©¨Èç°.¥#y‰‡×2÷=ޏ*­–#^Ó½‡~iœ•ÛÇuV<{TÜ 5ÉÇq£P P(ˆ5 ÉÏpBïvΗÄyó(w¨èCHàu=;üˆ_/ܧ­yî† IDATΞx‰ž<@º#G8µys¯@ ¾ðñêlLzì1Ô×àðY!@@CCC‡è•„¯¥¥…°°04Íyí£¼¼œ 6ðç?ÿ™/¿üƒÁpÖ·Ÿ.¼QwîÜÉÍçè èrн®®,êÞuoá½9[&q_Ø>|Øç0¶ó=ö¾¾Ý}`²²²2¹]êPîݦá\ÚaÅŠ"s÷y>kÊËËeͱcÇúåÔÐЀZ­–ŸW---dffòüóÏ_mœÌ}«WsßêÕýƒ,>\Ƈ/G ²“ª/A¡ôcàHn"Âß2—ÁäË}_j 8#CvV—è 1l6読•×uw`w!®íið¶å$î=-îb(.5•[áG—z…ìˆMIáîÿ÷ÿ=Ú£gI 8g[À)>\÷£{Ïa_¯"%Â#xèPnsó_:õå—œøøcŸ÷­ävoMÿÉOPz,?ž‘Aݾ}˜½’ žÙ»—¢U«Îé¥Iìyú« òÃh4$OoÚ´ÉèÊÌÌ”ÈîÝ»©««““ýy¯ëΡC‡HIIA£Ñàp8°Z­:/ð5kÖ‚ÙlfÛ¶m477Sâ–8ª/¼VËÊÊ| ÌÌLo_äææúÌp~9ÈÍÍåÁ<«q>PÌf3ÕÕÕŒ7î¼#{] ûÝ‹ÑÚÚJ~~>#ÎÁp9ƒ .¾îÍööö~‰Á/¿ü’»ï¾[~^íÞ½ûœ{¿®L­­¨Qb7› ŒŒDåãe’ÝjÅÔÚêáÔ*šAƒp:n›Z[‘¬Ö^¾/Qã>,Ê%8úÊlîÏo£»µ›É$O+Ý„„ûú6<{[¼{\¼E•{OLý®]d8{Е> ½¦¢">t.Љ!(2’¡S§ò€ÓÀ»TlÚ„®°Ê¼<(gÉΩ¯¼‚ÚÏ®àêdÒãsìÃ=®G×ïè±cyÛm~ÿ}ù:ôŽú6å¹çde@GÊ¢¦Õ™çÆû…ƒûúaa¤<ñD¯ëêú'ŸäÐ?ÿÉÎßþÖoÝG¥§ÞÏä°F/ß\!@®qZZZX³f ¯¼òŠúè¬Ç}æÌ™Kî|___ÏèÑ£¼žw&ïà~_Éç컌÷³e ÷Tbbb¯LéßE, ¹¹¹$±gøÈ‘¼PZJýt540"5md¤O¡’÷ÓŸRèÕ2lÑãÇP»{7–ÖÖ^YšÕn¿½“z÷v¸ ÷ÝÍ@Š?^Nf¶~ñâ^¸v·oðÌŽî'Þ¹B$/ñÑç°,?Œ½÷^Æ=ø Ú ìÈǦ矧£¶Öc~ĨQ„ÆÅõJ¦(¸ú¹óïG©V÷ºß §×ÒKo'õÖÒR:œ/ 554=ʰiÓ¸ùw¿“Ë|rï½>TîëŸùæ>}àTL^²D.W_P@cQ3^{Äyóˆ4Iœ,!@ν^Ͼ}ûä°²ÅÅÅÔÕÕy”q9‚÷×€(((`Μ9DDD°råJ}ôQ'a—CîÏ~ö3î¼óNšÕÕÕòð èq$ß¼y³Ç>Ö¬YÃc=摽¼?tww{Œ;_ºt)3fÌ8ëzùùù½†Õx·I_çýqòö·¾/G÷þ2PÇgÇÝÙÙIkkë%½. HIIéwy×5q¡ÈÏÏ—{ÂÖ¬YsQµ««‹ãÇ_S/9¢££}Þ¿±±±œ8q‚}ûöõ™Ô1++Ëïýæ~Ý»|—’j4n½õVÊËË9|ø0ÖînÚÝž¯ÚˆBÎèãßmd$w¿÷‰÷ÜC{Uå¹¹´WVÒZQAkEE/Æá£.–Ž:kjz9x{g]öN(è=†½µ¬Œœ'žÀÖÑá³×Ä;ò–·Ãy@h(aññ½ŽsøôéÄöó¹“8>ÁÎ"ê  ‹2ž}ð 7ðÜñãHv»ÇüÀ°0!>¾£¸î·¯¼BqVÅYY4Ÿ8èÖé¨Öé<‚6xsfÇ{GAOr ÎûÆî&ª·làTNN/á]‘“ÃÎßýuPa <àí1,>¾_~#B€\å”””x„?u9*÷åt¹sçN®¿þzÂaÙÙÙÜu×]ëíܹ“I“&B¡Àd2yø$Ô××{ µ*..ö›š••ÅÓO?ÍÈ‘#Ù°aÁÁÁ$$$PUUEII ÷Ýwwß}w¯ð¸Ÿ}ö™ŽÔ=“7ôøE¸†c,]ºôÿgï»Ã£*Óöïi™É$™ôLi¤AHBBI ”h( ¸(¸QAù”UÖUq]WöûTP÷ÒŸìå²ëZÖ‚+%¬ MJ@JÀ ô6©3™öûcÎ{xÏ;g’IÌs]çšvúyÏ™ç~Ê}###ÃåóUTT„K—.áòåË0 ())áÈ¥K—®K ¢¿ ç®._TTÔïu‘FÞ_Jãs_FÆõŽ;œÎ3PæŠ tÝ®6ÚÓc| d×c•••?ªÎ i /))Ȉˆøùù¡¥¥AAA½–J²÷ }Þ>ýôS<ñÄ|€å­·ÞÂË7‘rµD"¯¯/4 ÊvìÀûG¢‘°Z-rÞ{oÐÕ†å*FÝq`âÿˆ–òr|þy”lÚ›ÕÊ;) µ‰wß ÍÌDçôè¶oÇ'¹¹|„”WÑlZ4x¡KOèfw˜Í°p:»B2¬¸"[¦R¹cz2• žZ-b¹ÿ›o}¥Ì¸#Íï©>ø“]s¥F3äµýÚœT• AÉÉJNÆÔçŸÇǹ¹(Û¾]0¶{ô«•{Fõz¨|}1Š)í6èõöqO-8k|çI" ô hhiÁÛT‡_\|FŒÀ¼>€L²› €lݺáÔmà»ï¾ƒ\.ô0|÷Ýw¨––ìÙ³·S´‚õõõXµjïô“ùÞyç˜ÍfÜÿýøê«¯ “É •J‹ÿû¿ÿè&<ðÀ‚aB­©R©PPP€ÜÜ\¸»»óN~QQfΜÉïŸF£qÚ Ø3þþþ¸pá„hŠþØ©S§ÐÑÑ!ȼœþ…)yÒÄb¿ý¥(ß}÷ËûÞŸÞÒ€ïêõ.**ÂpN¡ÕÕ}„*ÛƒambÏ›ÈõXww7ÚÛÛoȺM&“KÕÕÕÐôâdõ6ÞÛÛÛ±fͨÕj˜ÍfÃd2¡±±ñºž¿ëjh€ÕÇó¨Pߘ„Nšt÷íy|€i/¾ˆË{÷ÚŸN‡†3g`æ2Í—vïÆ%.ÜÎe?Øž ój¿h´cÇ¢Y§C}q1êŽí¡³%IIðÐjq¹ À¡´K€ž–|û裰˜´j@B'O†©« §ß{?ΫGŽ®Pÿo™Ï<ߘþsÙ38þÏÂ̱”>>gÏ= À¥¦Ûî¦&4P]ªPܰkZwê”@XQ¡VcX/B·?•µUU¡•ë_Ц¦þj@ٕÇ¡ûüsXM&a ‡êšðpDeg£lçNt×Õ ÊiZéðiÓ0éé§šËz=Ú¯\Á•ÇÖ/nľ³ˆž3£/æ%Cv«W¯âøñãHII\.Ç‘#GãÇ#99V«/½ô¦NŠgžy/¼ð{ãò3Ï<ƒgŸ}&­ûÉ'ŸÀÍÍ pñâEüç?ÿÁë¯¿Ž²²2Œ5 —/_FPPÊÊÊ`µZÑÒÒÒ+p³žž\¼xáááØ¶m¦NŠ5kÖ §§Ç©ÖAUURSSoPøá‡ T*rúôi$''_÷zXb€ŸÒZZZPPPàèùä“OpÇwÜ–1B€PUUÅ—Úõˆéõzý“ôFñS™^¯ç³­¬¥¥¥áĉçÎÙxwPŒF#t:RRRøû¢¶¶‡âç9qâl6¼½½+z/9r„ÿLÎ#™ççxn‰%Þs¢gφš*ºÑfîîæV™B(N(|êT4ž=‹¹ì‹˜B:ë´ˆõ[\Ú½•ûö¡«¾ž×ôp¦ëA€Isq1š9z`@\lQ̉:ýÞ{8÷ÑGׯ“0^̱‹iÂÃ1ú·¿åˆÍjEÅW_¡xÃÇÿùOûv¥R$Þ{/æýç?‚ß ­­° øzÅ Ôs™HSW:jjøy<´Züæ“ODuÚ›µVTàƒŒ Á~Ë hÂñäàA¸ðÚý1£^ŽÚZ|Ädá”>>XÌe†Uþþ¢„äœvÕ×ãÄ›oâ §­ehmå›–½†w(w»ýÜ–f³F# TÙ°ÂÃc@eA“ †¦&ÈT*¨®CÓ«§½ç>ú‡)6*bKìuÿ޼ò .ïÛ£^/ÿô}`¨¬ÄÙõë! é¨×ìÝ‹÷îå?ËT*$äåÁ¨×ãÊáÃ} ¶g„)WFóùó»blV+:kkûCÅ6ààóÏ#7?ßióºD.‡ú&Ò{úE'NÀÍÍ ^^^ˆŒŒDZZÞ|óM¤¤¤ ((J¥ضmÂÂÂ0vìXÄÇÇcÓ¦MØ»w/öíÛ‡¶¶6h4lß¾³gÏÆÑ£G‘žžŽÖÖV|ûí·hkkãµ4zzzeIÕÕÕøÏþƒ‡~ØíjnƧŸ~ŠÜÜ\v•ð«W¯B£Ñ`ذa|í5+wìØ1"š†XöÖÜÍ:,µÈÈH¾Yùøñã˜mÜ<< ôöÆÈ… íE©DìܹN·Q¹o¶/Y‚6'½£ÿàz»†gdÀ"<6~<‚¸þ›š'xgˆ”hçèñôÍþÀ(tÕÕñÇ ¾QQðgK΀*ý»¡¥W á¡Õ"8- ~qqÏÌ%'ˆ˜>—÷íÙü|X ÚXZÊgoÄÎGÜ‚Èxê) ))¿ãóÏñݳÏâà /À!y Ìé÷b÷Š…™Ì°—Q]¿6Î)v¦äì;„Z[ahmÅî?þ»ÿøG{PbÚ4Œ-P]'ãoxFšÏŸ‡6%ùÙÙèqþýGŽÄï(1é«……Ðmߎ'Ï Ð)SàÇšbç̓Œ ª³V{âZ9ÿ¦·ùnzR\\,P!®««Ão¼üü|äååA¥R¡¶¶F£&“ ±±±èêêB}}=ŒF#¾øâ DFFâܹsÐéthoo‡J¥Bbb"8€ &àùçŸGJJ bcc¡T*¡Óé°aì^½7n4u’FQþ„q–ÞJ5ZZZÐÑÑcÇŽaüøñغu+n¹å|ðÁ0Sʼ´ÅÆÆ:”ãDGGó¤¾Ôêž{îÁìÙ³{-ÕpÕn¹ålçê) ˜òóóCss3.^¼(pfÂÂÂútDÅœ"1 qhòïËÄÀ5Íu9óíííØ¶m›KóîÙ³ç'»/~ìæwv›ý!`,;zô¨Óµ––ôôô ««ëgé kµÚ~g·H¹g@@}ôQ¾Ùyyy9<‡ÑÜÜÌg)Nž<‰Ñ£Góë߸q#är9Nž<‰ææf<ùä“XµjV®\ ­V‹U«V!'';wîÄîÝ»!—Ë!“ɆÈÈH¬X±âgy¾C&NDöâÅLJBÈøñ7¤ùÓÐÒ‚ö«Wq&?'Þx=mm½J2¥ðýºu°rÏÂÞØ¤ØH®Œz•s“ð°Â®ßa¦&«ˆc)s+2Ô¬YHº÷^ÄôâPôz^Ål0àL~>šÎCå‘sà‹°ÌLøqzGpá‹/P[TdgÛpäsWº¸ Ü×?Œ½þ3{óû¤§Ÿæ—ÿ('GPBåÌ$¬==0qÔë2… ®zA.r®“’Ð~ñ"/P©ã% TÔ0Û`ìì„Íl†;u È5´RrGa!:©y¾üR°?j^z;4e3ípK ù÷¾üé±SQ‰`¬ BòwQ,uu0~ù%ª¾ü—Ö­¾JOOtS Œìºe½8õ>ÿå;wò×#cÕ*Äää@©ÑàÂ_ lûv¨|}ali,õËÀO3ÆÈ2f8j☜ÜSîR‘{N켺?®îßÓo¾) 4(SÕ3–ÎN~Rf{­eeXçãÃ« ®$Í@à`tÖÖ¢»±å_~ÉïƒR£˜r0òÉÔÝ ÈUj4°Qóe½ü2B)ÐïëPºvÓ¤¤$ëÏúõë±bÅ §|:ûÛßÐÒÒ‚±cÇ"++ =örssñôÓOã®»îÂâÅ‹qùòeÌ™3111hooÇK/½„•+W"** ýë_áéé ™L†èèh>úØÖÖ†ºº:¾†/""—/_8fÁÁÁxçwØ)1yä¬]»VZ>ûì3¤§§Ã×××)#“T*…•Q˜%ô«EEEøÍo~ƒÃ\]¢«Q²Ni?jéù«««ÑÜÜÜïŒJ_™WöYÌ>ûì³Ao{÷îŲeËúÔZ1 |¤Ú•hvŸ‚œŠ½+V[[‹“'Oèøjkk=>ý±q¾ûcf³¹Ï±0r‚Á4Ÿ^Ë«\µmÛ¶A*•ÂÃÃÇ糫}™ÍfùsçøÏ?þ8ß+ôÃ?àå—_ÆÛo¿ •J³ÙŒyóæaÇŽ°Ùlxë­·°téRdee!)) “&M»ヒ®®.¬Y³W®\Á±cÇàåå…M›6áp)¸ðSX`B&¬\ÙkÄ»b×.Çÿ›¥K{el:ûá‡0¶¶âL~¾½öþâE'P •Hø>©Dâ@gK—LÑßÑŽ’×DåŒsI³YY!^†"qæ ÉdH$°ˆÁ‚ÆŒAOGšJK2q¢xpÉÛ[pŽ'­Z…/x?lØ›ÅÂ+¤K$hSRœ’"8ÆàÔTÔ;DÝe ÌÑ¿)U*HL&ÈÉ9°Ù å@ÆÅÍ›qqófÁµPörüRˆ«ÒKL&€.‚ Uq1ÔÝT¤¿‡·ß~ùË_pË-·ðßÿéO⣨۷oG`` _"EJœÂ†èèhÜwß}˜7o¦M›†»îº Æ Ã=÷܃¦¦&¾†Z̹ŒŽŽÆöíÛ1a „……aÛ¶mxê©§PZZ*`窩©|îùûûcÞ¼y Ø'OžDjjªè2÷ÝwÖ¯_ïR9Š^¯P4yêÔ©ýjpîËÈ>ÿܬ££žžž}‚ OOO—ô7ˆ#芕——#::z@Jæååå|)a¬¨¨©©©×]rWVV†ª†»/#Grþ\Œ{¹\Ó9[»v-–-[&ÈFºb:›7oæéÃùßÚÛÛÌM,\¸“'OFrr2fÏžÍxb¨&â;ï¼Sð°÷yyyá¯ýë Þë?†õzoØ€óŸ~ŠËûö9üÞxîf¬[Çþ~Ý:ÔQ`_·mz¸?dÖId 쥵­2ùmt^.íÞ.ª)VÞK´”uTYZ]ºtÄL9 'Ñe²ŸaS¦@éí ݶm‘à£k×ÓßÅÄÄübÕ{ÚÛqöÃqà¹çÐΔz*½½áî닜÷߇ot´=ÊÙÓƒî¦&He2sÊËl„ØŸµÍI´’þ“/ÍÏçE1ö*:«!Ù«fÎÖ¯»ùúÂS«ÅÈ… aÔëQ}ô(jã,v8æ!âðyÇÅÁ76å;w¢õÌ~?/pç‚vdÄÀƒ€†ñqYW!¹öÊÿ&á¢ó2@&¹µ—Ë©„‹ÚSN?(‡@bzœη™¸©°Ø„Ž;{^Ég© Ù¸W w8D$QPèHF!=npØlÜõæœrwlj°q^¯Õzm?¬6{†ÀÌe zl€Ñv lp­ˆÎ"ôp>~·KžÀÇxõží€Wà&äÒkÀÊ*ŠSÚ¸ãSHì×ÀM¨$€› ¸Ù'¨ìž¸„KHTvï\¢´¿—¸só¸ðâ^8^qÍã—uîí€{‡¶V=`m¬m@O;`îŒÝ@“håðK+€îT+¹M±ø‰Î@Z(pÑC;¸©{M*2–ÅCVì$¦¹C^S–-ù­[a¦2f`2[bÌx6‘,ž”y–ˆ/ 5/«V8ö‹Á c{e¬"@KÈil‚^­2H&³ÿ©T×üe¹\vó/ªæwúôé‚ßâ9…Zúžm¤\¾|¹`ù'N ""jµøÃðá‡" Ë—/GMM _‰÷ßßpb5$ŠØ…²"""ŸŸI“&ÁËË z½wÞy'>þøcÌš5 ë֭ðaðgÏ?~Ë–-î]»ðÐC¡½½]àP9r„oj=z4ÏÒE›ÅbÌQ¦´´4‡l̘1cžžÎ—z –) ,\¸_Rµ­ý½¶999?YfÄÍÍ !ý4›9s¦`<üØFJéý¡™ú{? äååý,3S7‹EFFâ‘Gé7ÐŽÇã?Ž'Ÿ|~~~˜5kÏò7gÎ>pröìY¾äz,c×ù¹›nÛ6TìÚ…á"”­i?Œ*[^ôöÛøáý÷yšY6Z(öÇ+èvVŽ!‰Ä³Ž†„‰t²¥Z‚†YÆ™öŽŠÂÔçŸÇ‰ý ÅÅè¸r…wR¨à¶  -a%:BAÂåÌ÷rÀáÆ8ˆd9‰°Éç¼Û¤Ü$¹6¼RçÅb¬¦kå@6«Ý‰'%B`¶ÚKƒLV Çr-o ukùFrm€ÜÈ­€Â¸u Ï3'”£G—ôØÄ-o‚cY…q˜­"‰:O/ÛÁc3½6{ÅBEý%tFZ{]e €&ŽºKR;hñTjà®” @îÈÜ™P¨… pul²@Iþ\w=€F5€ÿ ¹ ¨µÚñŒ·Ï6 „‘„Žšû8ÙF ´¹kod2,lŸ‹ÅI Á°‰d$}¼—(昹äp”‚¬_&²?'cÃB5¨H™ùMÔy•âZÙ§D$Áe¦ÆÔ iiiçÝáÙÜCù=7/H”˜¶%Œ2fTT<<<øÏ'Näöœ>}Ö IDAT'NDÇeîëë‹ & ==õÛ¸q#ÆŽ‹˜˜„††âܹsÈÈÈ€——¿¾Œ?'Ož%Fƒêêj‰ŒŒäé‚£¢¢úݘ‹Ç{ íííèì섇‡N:ÅÓqΞ=[ ¾~³ØÄ‰qôèQ§¿õeãÇïU®·±ÅšL&ƒF£¯¯ï /5š8qbŸû3d7Ʊ¹¿œYPPöíÛ‡ˆˆÜ~ûíý¢LöððTжcëILLD`` ÓùnFK¼ç$Þs08c4¢I§Ã•ƒQF•?žûè#tTW þìq¦(¢³aÐëÑÁ5%‹5¶²™1Ö*ºlŠ.%ËŒ°ÑHµVË‹,xöYÔŸ8ùµÀ5Ô\Pšô/xrŸÝ)çM.á2 ²k™)7I$öl€”Úap¯|fÁÆíŸÍîôuSûJ¢ýV7Aè›8óLe’ o@¬d„ž×LEÂ-TZ-¼ÃÃQÃé¨@$zL—ÈH!, cA!¹žáá謯‡Í`p(—sxýââÐ¬Ó œxPŽ% 4$pÎX&a"Õ8–êY™1“¼lJ·n4ê÷ÖÃ`àæí ™J…îº:AƬ[fܬ€»Iri@ã@#ÜÝw॔^€LȽ¸üøÊ`X¬¬­@g+ÐÝ töØ3"fnܒ䋌Êl:µm«ˆÓlc²AII6~ö8$I¿šå‡Ì~¯†Þ;áƒ\.‡¯¯/_"š””777xUzz:ÜÜÜú,ut6þV®\ÙïÞ’Ÿ»>¨æX\Ù€†X/‰D¡€Õbáÿ'Èy ËÌÄ­¯¾Ê/K€cͱc¨=yÒ àÆ¿¤¿Cb³ÁÄÝwÎäÙÞ–„¼<ÈU*tÖÕ¡lçN§¥¨ƒaCÄE›Ä¤ò]iìeç[†d=Hóõ´iÓpêÔ)øøø@ΉÖhµZÔÕÕaÑ¢E½RÁºÊÀ-ˆ¼Oš4 555ÈÎÎÆ·ß~‹û¼ò †q<ådÝžžž‚õ¨ÕjöŸaƹԔëê|´yyy!66VÀ5iÒ$”24ήÙõ9/½ý~#, ÷Ýw8ð£Œurqqq˜4iR¿Ë·èküK52ÖúkZ­Ö)Øeí‹/¾À{ï½'¿ìŠ‹‹ÃâÅ‹±j ööö†Édr Ë6LÐøp WËÌÌD&G yþüy<»r%Ï>E¬Y§Ã‘µkÑR^îпàìÙÇZnDLŸŽŠ]»`hhp¨Û¶1¯ €Ãf>ÌTôV,óÂF!é}­Ú·Õ……èjhDê•ÌD"À¤/¸†rÐ@-'å@ˆÍrmßXjR³H6‚žoDV`2á*E’BŽ9<3ÓN£º}»Ós~•u¬%%Á= @p>, ³²ìàüOB4GÀ@¬¡¤ß<ú¨à»»{ùß6~…ÿ@Méí¥GŽô) IaHµp¡èÁÏJ*@ÙTZŠ’Í›QòÁ訪‚ölš×(rÝ-€{7 ê¶æK)‡Ÿ`ÒãA¸z¨ûPÀÒÐÀƒ|š‹j­Ñ\)£Q¯GéÖ­<û[[e%.8Pî²™M1¶+gÏúù±céRÁ9Ô„…!iéRx‡‡#2;ž"A¼™œ( >­VtÔÖâÌæÍ¸zø0Îþ¹Ã~$ÿÏÿ`Ê³Ï ÀaWc#ºñqn.š¹ì$_´‰wß@.‹¦Ä’î!ò3‹º²ŸGŒ777Ìœ9³×y‰Ýu×]ýÚæƒ>ˆööv^WdĈ ÁªU«p‘ã¼§mĈß{ ’èWtt4ÆßZ­v©ñžµ±Ýd@@ÂÃÃþžS/// JLjü‘ë1–¢Ó¼ÞÆx¥R9 ñÈþn›¯× ’cgذa¢cüzM­V÷yíËËËñ¿ÿû¿.;b …‚Ïê $$œbðèÑ£yÀD_÷Žá_šùŒøqã`ééŽcˆaÇQjöE‰ f^:³"@Øz1MÚIbë÷ɾ]âœ!öxØã´À±7‚¦n¥ƒÈ|ª€>rNìbA,GÂÜ˹Oº÷^û1ÉdHyðA@ìܹ0´´ lÊ(¨^Ê›Ùä*•¨ãï3bbçÏç?ZZ0zñbÑùX}¥··À‰ÿ1M¡V÷ ÈŒ{ä‘^÷5 Ó^x±sçbï_þ‚Ë{öÀ <7r77Ô?ŽÚ‹ìTΚ¶mpìû±AHçÌöe±ŒNäµ³®?PÁ\)€«âêÁƒš^¶Œ̾ÐÓøGu£–ž”Q¢Çô}4f &þñð9Ò©+fêìD'„*U(Oò”ÞÞµp!áÅ€u@ÔX°e º]íØ±|@`Ðï™!·ÿçmYYY¨®®¥ÿìõá®4­&&&¢¤¤Ä!Œ°;‘û¬¬,œ?YYY¢Î™³ïi›8q""ÒÓÓf&èùœYPP(è¹Ñ¦ä:;;û½lHHFŽéÔ ½—ûÃvõú³¦ÑhÐÕÕ³ˆ aIóóó|½è^^^7nœË½J¥èììì×¶ÅŽ÷FÞ[½+Wï­i½»ñãÇó@Í××W@šñk3…Z Ϙ9uk:ÒÈ–¾(<<àÃÑïzhµ˜òÜs¨:xÍ:.ðŠ×tö„í ¡³4›˜ˆ™Y$2Ê®›vdè^ :³B;Ab ì2f»lÉiâÓ%°qÑ×[ÿö7hÂÃQ²q#¾þýïÑÓÞîôœ‡efbá§ŸŠ?¯Ã‰ú1ìØ?þa¿‡6ÌÃT¾¾ˆâtx~2q"ò¾ù&®„ÔÍÓH`6ðÙ¢E¨Ü¿FŠº]ŒAN"¾Ù,"+úH²„l Hؾg‚„`ž1ô=úÃ{ïÁÆõfÄääÀC«…ÍfØeËp&?f¦T>ûÕW¡ tý57//ÜþÑG^>X$xuCAû‹ÿ ¸a{¡€MHHÀ…  “Éx†,Úæs‘—•+Wbýúõx衇œöLôÇzË8ÐÏ£Gvª¦îJƒ´¯¯/BBBú @"##]î‰q¶|@@€@rvžûå,):ÇóçÏÇöíÛ1}út>|ØàÄÇÇóT« ,pЩ Ë÷fÉÉÉßd–ÈùKIIpÿȰàà`žÐÁ#÷±ÖÖVøøø ÚþÌŸ?Ð)¯ûsoÝLÖpæ Ž9#øNLuØ/.ѳgß#¨è¬«ÃF®—DââõûlI[£O3Ð) ) žZ-.2#Ø÷rf¿hV&ú=«”Nƒz ?II¨ä±˜œÄääàGÝpæ >œQ’V<ˆ¢ÿnžžP!.7RùãRØl6Xzz‘kÖ¢n» >‘‘â¿Íš5äXü„&‘ÉàÆd¹å*îܾ-.ÀÐÒ‚óŸ}†Ã/½äL`ïËX®|ª|çN—Þô=Äô:HPÁ]«Åˆ[oEI~¾ 7D¦R!!/€½ÇŒô<±ÀÈÚÙÉï÷ùÿþ×á9Ä‚§üìlvö>ÒÓ¡ôöÆè»îêµÉü—nCä&°iÓ¦!::_ýµC‰ i@ À´iÓ0iÒ$hµÚ^ëßÅšËY´téR—KR&r½ÖŸ¦æ1cÆðÊåqqq‚ÆÜtvvB­V;U áËÒØã¦{oHY»þ\»ýû÷‹þ¶”©í«™¸¯óìJ3²§§§@séÒ¥ƒª~=Ð2®Á°èèhhµZ—kf³™'† »‘Íáÿþ÷¿UÏ@ÏDRŒx wß ¹ˆ(ãçŸÇ1®†š­çvÆÿÏ6ªŽ Ãb%U¬²³ÂÛ¨=uJ0/[F³ó°ú,Õ)á!á=ÔD ð@ͱc¨9vL¦|cb`îîÆ©÷ÞC퉎΢È{rö<õÿ[úSOá–ÿ÷ÿ~”ëÝ~å þ;kÏÒÒ òöFà˜1ˆ7Ïéòþ½°'ÙOk¾11Ø–—‡3[¶8`±±XÁfš"ØÈÌçLpNž=uu(ÍÏd{ŸÏiêÿ_â Øbž%¾11ð¦ú/ òÀXM&”lÚ„’M›øï½#"ê„Õt€Ü@ËÏÏpôú×d*• ±±±°Z­˜={¶hcº¯¯/²³³ùˆytt4jð´………!,, ‹-ÂG\:o¶ )ãÝô|Ûm· ²7‹-ri9ÒÈKÀÁìÙ³qþüy„……9U³ž={6¶oßÞç6È9g·Ñ§ØéÍØ¦â3fÀ××·×F|©TÚgV¨·k8Ðf±ó媑2.v<7 ü8øè:ÒÎ}mï§²›½q|PÁåìÙÈ{ï=‡ï-==¸´{7ÎoÝŠ‹設uI ”ÃÆ9³ [Â!eâàX ´–—ÃÒÕå´„D »ÆÉlÐàƒ4œÓN-rGDØz ÔÍ t#4±Èìlh““¡Ôh`6á?r$¯}À; ^^}µµ°2% Eÿþ7FdgcÄŒ7üzkÂÂpß÷ߣ»©IDƒƒ!S*‡nˆ_¸¥ýþ÷¨|8®^½Úïã]¼x±Ã3@&“ÁÝÝo¬ >J¥Rt{?•Ýìã7Ú*víÂwÏ>‹êï¿w:Û€–™ ÏáÃá‹°)Søïz=ެ]‹Ή—0ËFßv/D¦¯¨@-'xG7°JŒFt]¾Ì×§³4 ¤AÜtñKKô7XJ\+³oÝuu誫mX¿TP€K½0¶Mxâ ŒýÝïàÇ«ª„©« g6o†Ùh„GPbæÎ…öGÔŠróô´÷ ÙMg¡“'ãUU¨!/iÖ¯_ï´I<>>^àôåææ:(|/X°|ðAŸÛ$Û˜6mß”Ìö¸ºßdßXÐ ___"‘Høëž›› N‡ŒŒ ÈårÌž=›_D"B¡pد¨¨(¸»»‹gÙ ú:’ó,69ÿsçÎuéü‰mö:f¯Çd2!•JŠäƒa‰nnn.ícÆ{¯ýÚ¬ñÜ9œàT®ë‹‹QÄõÀ%%aÑ—_ºÄ]o6aíéA1ÅRsð…ø„¼}:jjj ÕjÊÌ®š³Œ‰Xc2ÛìM,-- {÷îEZZšà{ÒлtéR|üñÇHKK8Ù8tè""" T*áïïïIˆ‹‹Ã×_-[¶`úôé())mF'ûæíí ¹\î@m}:zÚÛ1ñüUsÙŽ8Ë5ŸÓ÷^åwß¡ýêU‡L™Ü\¸÷.sÍê4¡Ä·<"Úûႎêj§¥ñç¾Y§ÃÕ«Û&˳&U*1ê7¿LY½Ú¡„qȆÈ/Ò¢¢¢ÉP úûûó:!2™LÀbt=F´0žxâ (•JDEE¡¹¹ñññ8zô¨`ÞeË–aäÈ‘|¯Éĉ¡P(`2™zÝFjj*RSS]vH‰<Ýc ¶ß¡¡¡|ÆÃÃØ1c†@Wôûýï“É„ÎÎNŒ7 …#GŽÄîÝ»4Ôj5¯ÒÛ¾íwvvºÜ4ïÌÒÓÓqéÒ%Ìž=!!!ظq£(h`÷‡Œ™E‹¡¨¨‹-‚Á`@GG>úè#ddd 44tÀ€•œ¥RéôšÏœ9“wæÉ¸Ó1, °dBB©&wáÂ…øæ›oššŠ¢¢¢¯G¥RaÊ”)üg???Ìøš}Îf0ŸŸÚÚZ§ó$cٹϜéèÐ4Ö„IΙØ' ä#³³yv*…§'ª ÑPR‚}O? )ìR9sß8»ÇmF#ÎmÙ+€K{ö òÖ[ ¤Y§CGá+ø/Õjq×—_ÂýWr _˜‰iHÐQi___Ìœ9r¹MMMøúë¯ùßúÛ=nÜ8§ßUWW#22þþþ8tè–-[†¦¦&Þá[¾|9jÝYç855µW°%fÉÉÉýr./^Œo¾ù÷ß?vìØÁŸ‡]»vaúôéðôôä'àZ)Xjj*Z[[‘’’X,œ>}¸ýöÛ1jÔ(—jùIc³³fiâðVUUáïÿ;^{í5þ7Ò…éÓ§ó}cÆŒÁÚµk]¾–‹9åÝÔÔTÌ™3“'OFQQÜÜÜ Ñh°páBlÞ¼Ù¥uÑç/##'ND[[Ÿ…;'îîî˜3g?†öìÙ#˜>´„B‘èvo.šå(訑±7mÚ4¨T*MœáÇó@¶7›ÉÔÚK¥R§â¤¿S©TX¶lΟ?OUù‘·ßŽÀ¤$øèikÃ…/¿Äç¿ý­ ÂÊRpÒÆ6›@Äôéð9Gÿö7Á:hgÄÓ¬Œ“D3g9Óa3Rš¨(øFEábAƒæŽ*Ò°ZaãjÒ=àH-Ì*ÃÛ˜ý£ë²dÉìܹMMM˜;w.ƇSï=‰755aéÒ¥ØÉ¥DÉr¬MŸ>]´l‹0¤566 ~_¹r%Ìf3_ETÔinÉ’%|_ýÞ™ÑÂsyyyððð@CC222pôèQ¤§§£°°éééøâ‹/Ë.Y²eee­V‹¨¨(¾<ŠÝFJJ ÆŒƒ»ï¾žžžHOO‡N§Ã¼yó`³ÙøýŒk˜Ã 7eeeaÊ”)Ðét¼Æ )ÝËÌÌDKK ÒÓÓaµZáïïyóæáÕW_ÅwÜÂÂB„‡‡ãÖ[oåKÔújš>|8Èuó÷÷GSS|||Dig {^o¤B9;朕Ø-Y²6lÀ˜1cð?‡1 IDAT ×ë%K—.Å«”æææ†   –ÙÀŒîþþ047ã›?üÿNææï#0“ø— põÈtrõãb¥Z-È8 û'f1TDŽ×3uvbïÓO;fdðBvý5¯áÖ ƒ6¿‘#±€*¡êË®¢³¾— ÐYWÇ3²±2ØË¬”Ì8'÷Í çÎ}¶1Ë‹eJHY#}‘õùÅÇ£½º&½ÞA7„ ^°÷й§Ä–ü]uuØ<}º +,3~qqHY¾AIIü÷—  Û¶ %ùù0utÀ"¢[¶óþII 83ƒ^óœN\`R’—-CêòåCdÈ\7( <÷Üs½6~Ôd2ß ›’’‚äädÄÄÄ@.—#77MMMð÷÷ÇèÑ£‘ÌQ3VVVbÑ¢EX·nïP‡……Ál6C¥RñË:tHNNƬY³ ÓéåA¤ùZ«Õ"66„\.ÇüùóQ^^³ÙŒøøx”••9p DT.77………HHH@pp0šššŒÑ£Gc÷îݸõÖ[ÑÚÚŠøøxâ/ù >ûì3`ذa<ÉÍÍÅ+¯¼¹\¹\Ž÷ß6l€¯¯/0zôè~5!ø —óÛ¹å–[€¿v6lÀèÑ£¡Õjy§|Á‚hjj‚Z­Æ¨Q£àïïQ£F¡°° Á$NÉU&“¡°°ÏÚ%$$àÀüu®©©A^^ 1{ölR€Þöy0=Ï}‘+°ûñøãã•W^ù f7quMF—Eüð߈Šq@|¼hÉ’â ¬IINME=×Ô-…£:=Ñq‚äœã$q„À©ˆSÅFYóòpq÷nt×Õñ`C @ {vÀŠ{%`ù5rëìäÞÓ4¾¬"4ÝkBƒ¡Îº:œ^¿^Ð lêìD³NçÐTÏ‚:gµð%½d_ ã˜uÖÕA®Rñ:%tiK[e%.rmHù#ëžûøcÑm(<<ø¨>1–Ž•l×f6ÛÁª;³e Žp™3ïðpDfgÃ/.a™™H$RVÓÔÕ¹Jõ“©h_عYY¶˜œ\Ú½›óµp!ŠÞ~6³ÝÍÍH¥*°Y­°Z,| •”å³! ðÛ¨1k䯴Œ»7µ5 ÊmÔ¼„Qλž ¬Ô=(yØDžA2ˆë ±ãüR6“ f“ 2wwH$„M™‚˜œxá†ÌLtÖÕ¡ƒëür• K¨2¯ã¯¿ŽÓ"ZI½YõÑ£h*-Eí‰ü=8˜Á‚!r“š–Šä\o“toQt²~¹\.PO§£ÈäýêÕ«ÑÖÖ†ûï¿þþþ˜>}:Ÿ¨««CBB4 Fމ‡zŽW?##¨¨¨À¾}ûàïï/h4¾xñ"î¸ãôôô`òäɨ¨¨@TTÔ )°³FÖëïï/8ΜœA¹Î¹sç0cÆ !77>|8ŒF#üýý¡V«±dÉ$$$ðN¥\.¿aûÝß oô1ñJ²0™LHOOÇd‘zd’ùÙµkfÍš…ÌÌLDEEáÔ©S>|8222°lÙ2ìÛ·¯_åRãÆCSSÚÛÛáããs]‚éééü¶ûs¯LŸ>ëׯwȘÚáã ™ã:ërñFƒõœ#JŠaãÆaƺuh<{-åå8Ë©G£¶ õðRˆS꧇U2§!7 x° ÃHM\Ó! ¡2?nÈp〆_^<)BöÑÌ­ËÀ­·‹{OÊV 12 ÄLíŸ@(`ìeXúK—œö½Ð޾¡© ßR)1³õ±Ž¾Œ]Þ/6Þ‘‘¢âˆ5ÇŽA›’Ck+ÔL–•>6Sg§€ùFä8$"@˜Ý¯î¦&^<±®¨:*8¨ÔhpÏþý}’¸bk=<ð»ÒR¸ûùÁÔÙ o¦o¸VÒ% æ D\‡ßPýý÷ðŽŒÄ5kàÅ‘g KKCwS¼#"ñÔSˆÌΆot4|¢¢àÅ÷ÿ|½bN¾ù¦C" Že̹–8,, ¹Ÿ cÜDÝsF=çÎAÂÝ¿l6’Þ/©Ba' èìDõá±@æ ÍÌ„ÅhDͱcü>Ú˜›yœ¿q#”œ¤ðôˆ.aúG. êðaxî¹kÿO/½„.ê?5tÒ$§DåããPNÙxö,Ú¯^…Q¯GÑÛoóߘ1c€ ™ëv=5샽~ZØ,%XGdd$>ØíhERäloË>^WÏÃâÅ‹¡T*1aÂ@QQf̘+Çcþä“O šÛªý¾Þc6›ÍÄì1‘kD>§¤¤T×µZ-¬V+öîÝË—­‘žÒÀN+°>hooGBB‚€t@Ìè^#B–ÐÕÕeÿ³•Jùò¯þ\góáÅ!ûñLJEDYÇÏ*ògÏ;- ö<õ ÍͰtv jÎYõq±2’é N¼…›_ ¡Š¹œq””€Q 8ÿV\ËTtq¿»qƒ,«æÀ™4À]($€ÌX¬öåÛ4h çÖi¦Ž jŒÐ†„¸Bîî߸8ä¼û.Ÿý¨ãÊkÅD׬½€D8‰R…ž\9(ï(_¹X­}‚1ð2ë70";[tþÓë×cô]w¡­ª þ"}X{þügyåÈ”JžªXCE¡‰áh›Ii½îþþpóðà¿‹™;AAN¡©´tPȔի¡ö÷GWSºÑpæ ¾~øaÁ<=00%¡üu’J1æ¾ûÓψ9±©kÖ&>ñ’—-ÕC‡ òóCCuKzj‹ŠpåÐ!\-,DéÇ;dHé ÉH1*‡0 A;÷¤$Ë ÂŒ¢ ÂRE7ê^'™CuO÷PÛ#¯tVÄf± ¡´6“‰ÏÚ°ã¼– rˆ³t‘‰þíÓ;î¸öŸâ奔ÞÞ˜ö⋈c2à‘ÙÙ8Àsb\Ù D*…G¾£ ‡Åht 7uw# !* ä\áÀ(Dhu0µK†Èýì¬7¶(–êçlì¾² ÷¿¤céõ!•‘ ƹš?>öíÛ‡ŠŠ ,Z´Û·o‡»»;bccñý÷ߤõ@üüü‘‘êêj‡~“ÐÐPhµZœ9sÆe@0Ää󣛄q¦Å&+ìe MeeháÊ…êãwK5ÈDœ+å™(‡†4µj(°¢ 3€HH`ÏT±ïÂB9=Ý”E2(^¼¹Wî½vÐ!‘V `µ›x´s £…›È~Ðd6JÌÖÄÛx„„ðY‚­ ¢æøqAÔÙ(´‰€›ð2…‹¿ü¦Žè¶mCõ±c訩áÅçz6Q³g#¢¬ Ÿ6Íé˜!eTþ#Gâü§Ÿ¢¾¸XÀLÔÂBäîîXrð Sµê)\ÔYLQ>`ôh^óFšÅhDé§ŸòŸýââPñí·üç _|á3.­VtÀ£ñÜ9Ô:£^㯽†3[¶@ù2jµh¦)zölœ^¿†ÖV¾¤ˆ¾'h°oĵrE¥À—áZé¡'„e…=Ü=EÖIܺ”Ìzݹ©‡ L!Ý/"±Za©ª‚„Û&=Þm"÷˜{F*(‘0@ÞÜÞS{;Ú«ª°kÅ ÿ׿Σ«hSRäÆÖVì]µ F½^0~Ž­[çôšúÆÄ`ÂO€è5 C6dCvSØôéÓ1eÊ”””`ùòå())ÁÂ… ñý÷ß÷Y"u=¥I«V­r@ìH$û6@~£Ëh‘>ºµrçNH9§ƒŽ€ÒQP9„‘TxÐSą̃8†€ãLò,j›Vj=¬BÖKú;¼¸W·O­ÜdµÙ{äéýêÆµrj̘2C¼ôƒÞMD"²²0lÜ8¾Cù²ÀéWùûÃ;"ÂázÔŸ<)8v1B¶=eõj>SaîîÆ†É“ae´r4pçîïö«WQÜ +Wbú_ÿ ‰\™SäW=ä "'pà ¾ÍA÷¥µV¯FÚï 1cœF€#dZ\±žŽõz˜ Þ1ô¦Ž×™5?÷RS›ÏtÅÆ®X©kÖÀz¾õz~ùeøÅÆÂl4Ú3O}Ýsf3êøÿ¼!36³“‰?gÏ:\wrlšðp¤._Ž´+øõ}õU¾ü2bÄ\¦œ·!\ða‚xKçIƒ ¶ÃÂ9îty•™q&ˆ#CGK HPAØã!¥œPH¹˜ö’¨ L´s¿k( C³þtÀ^NÕkÍä="@Ì GÊ_+報޶ €B­†T"AÒÝwC_Y‰¸ùó¡ðð€Q¯‡›—B'O¶‰ µ*ooܲv­(³Ó7>гÿý/º޽˜X½šysVB'OÆpŽiO·m›€\,(@üw"hÌØÌf‡fîð©SÑ|þ<ªp6ô6ÙéõëQüÁx¬®ÎÁQ³ôô@÷ÙgÈdˆ™;§Þy*$Þ{/l ïH+ÔjX-XŒFÁò¾øûŸyÆ@ŒF€hÂÂøm%äå9(k—lÞŒ†’˜»»ßKår^_°7¤³bœ'ßx—¾ý (½½‘·{7<‚ƒ1ÃIüÀêÕh©¨@Èøñ(Ù¼™?«ÙŒ†’ ÉöfÐ[ÉÉÁ„•+¡P«Qsü8®:„ïÿþwû3ræLY»ÃÓÓ¡¯¬Dg]¬&¬==èÑëyðA{º7„Œ{­ °f¾%Ü|tc;Ë´%gŽ‹Ü;r‰#ØF ø K¯ÄJ°hÒ+Ä{ËMí2?”0# 8ŽÒ]ùæÑGQ{ò$®pÚ=ÎŒ¾·;© @`Ôw tòdÑ`ÃM@ÕêTL²!²_†áwÞÁ‹/¾ÀÞâŠËOi~~~‚ÏIII8vìØÐżAFÓnŠõqÐ4·t‰ÝtMê½Y&(PË“+REg=dÜüm@èæ~÷õ²)/ „ž/nÝî”#DÀq¬º¸©›Z?Ñ>`ˆÜÛñ ¢£®vît©Gcæ?ÿ /ªÔè¿N´£Æ?ú¨Sg•^WÚŠ¨?}Úîhï܉˜œ”nÝ £^aãÇ hEàòþý8ù曢 äl~>ÎR*ìôo ÅÅø€kŽHHÀ¬×^CDV?oB^òòPuð :8-%göíOð¥@ôv†M˜€š'ÁÉ»ïâÜÇ#~Ñ"ÄΛ‡úâbجV$Þ{/šJKñþĉ0uvâ7}„+GŽàû>ôQ;ånêòå0 ¨9v F½£'ßz íW¯B›š ck+L"Ä‘·ÞÊ—ËÀgwÞ c[›Ã|ÍeeLH@Íñ㸰s§Àqe-&'­ÐWV¢îäIXL&DÍœ‰ªC‡ÀDÀ}-ËwîD9GÁÏ–ã)½½±+% ™0*4•–¢þôi”äç£|ûv]¶”Œm¤€Ü¡YYsÙ2 €úS§ÐU_ÏH?!tP@(ÜÉfEÍ ¡÷Mt––î/±µp!ªƒžë)Rùø å0ŒÒes@ä­·ö9ŽfþóŸüùcM_YÉ— Vîß3Ô½E›:(Ó¦aÖo ºPèP Ö Ùý"lĈX¾|9FoooìÙ³çº×9vìXÁkoFÄÃs]Cfÿc'å2f¢©:Ùþ:«A¿'eJ4#%¥#¥$ jaRS®Áµ9ê)§ÃÆ98†Á‘½ŠØ›É ¸!ûG]æa`ÖëùfqÒ¼« ã©Ymm0Pİóú<×S׬qP?'v&?q @Á‘:øÿQ£ñ‹£­² gÏ¢íòeXL&œÿüsAíºÕdrpd%"ΣT¡€gH,F#:jkûÐxæ ò³³1<=¿ýö[~_»¦1ÝçŸãà / fî\Œ˜1M¥¥8°f ºêëÆ–@ua!>¤ë<›»»ñýßÿŽ9cP@B’î½V“ çÎና:}§/0ÁÁHa®GéÖ­0´´àö-[ÐVUÅ7 W:„‹\†¸b×.TìÚå°ÿìþºyzbþ¦M¸rø0úC6~<Ï’$‘H`êêBæ³ÏâÄozEÈx3ww£«¾^½'×Ñ#8=0utöK;2¡CV 29=z½ œ’hƒÐ}[t`Á Gf7š`¡¹´Éx–Ë—ÑAí3 n¬ÔýF v3A r¬rê^´ÀyÖÑǾRNƒƒwÒÕjT:„®†h¸ìÃió™Ï<ƒÔåË÷ kéúàÄë¯c×#ˆÎšžŽÛ?úè†<·‡È Ùýblâĉ¢ßßvÛmʈ¤¤¤ ::ZÀÈåÌJ˜˜ˆ0¦õf! ø9™MäÏ^ qv&zbº„2t„8%¤AÕʺ‰•L$‚j‚=‹Ñ{¹•ö̈?÷»'·<)1ÃQ@¬Á›>rœ´¨ ÇÔ5kø‰&Ÿcz£î¼“_Wåþý8òÊ+‚žÚqªÜ¿ŸW¹Vúø`Ôo~cwœ>ýUß}‡æ²2¾1›¶–òr|¶x1jE²b×" „GÜüùžžŽæ²2öÀÞD}åða˜»ºxRþÕWˆ¾í6~ž²;P{ò$ä*’—-Cå¾}‚¾‡èÛnCùW_9Ý 8Ëvì@ù×_£I§Ãmo¾ ™R‰®†ôhSS‘ù쳸ÄN®>Œïžyæ`¥¢ÿß>öv?ù$¢fÍ‚&, uEE8²v-êN‚T¡À×+Vð¤Óë×CO©uÂ~ÚÉÏ|æ„s½jžÃ†! >¾ß¬[Þ‘‘| éÝàÞgŸµƒ»íÛñ W˜˜ˆÿø‡D´µ¡½º558þÚk‚Fh$©|}–™ ³Á€3ùùö* ÷é‘R2@„ÐO·ãZöd{jj`pö¿ÿåï):  ¡îk:“C÷ƒÐtÖ4ÚñãÑVYÉköˆ•=ÚFîm7ooŒZ¸þññP dófüðÁ ÜÙýs`ÍtTW#01£(F-1ëm \9|ù\¶eâ“O î¡!2dC6d¿J[ºt)t:FŽ‰ÆÆFŒ3žžžèèèèu™#G޾›Ö S`×϶mÛ¢‹B$`hÏÿƒkÖ>uŠÒÔ”«~ƒH8¼É¥ÞDq³ -KÊzÖ/ ûpÊçyÈŠ£ÆãÔ'p@QLØfwoÁBj´-38ÈŽ}¨ àïýÖ·Øß}àT*¹T§¼’¢ÇŸxÂu>ûõ%€žÿóhX°€î›n*_éS§ø×÷¾·*®ÜkßqçmÙÂØ¡C<þ‰OP°G½Å¶(á0/~ó›¼ðÿàl&°î¶Ûˆwt°÷[ß²’ª?ÿyÎûÀxæK_bðW¿âý=TÞVnlÌÚ^(Dnt”%×_Ï"!lKRV¿ç=œìéA‰F™¿q#;¶nۉ™ 4.XÀœõë9´}»ÕÎR‰Þûîcí>@´¡_ø‚•‚•›!) —ò“,Û¼™H<î ËÑÒi~úö·[¢TÃà»Ë–!I†¦aêºELK%N?ñúô4gwîätOO9)üž½÷ _`ß_ý•/Éó±~ŠeZ±¦É#ÿõ¿–—©_¸wÚÅ$ó©?»å–r¿?x—øC.úã?&?9É#¶÷LF¹}×.žúä'9óüó3dU¥ã‚ ÐòyF(·ôËûp¼‡Ž÷ÁQ¾j%Ù1’† %JÌèÑaZƒ´iyÓTò¨œ†²0˜à„Sy•©œÐɰç1 ,k×ýˆáNŽ/s7nD+Ú½»ª›XŸ}÷ÞKâEåЧ¶5k=p êÞ–<¤F2gÎ0°c‘ÆFÀ’Ìö+X–üs-ËŽ•Ió >ê[ ,°ÀþÓ™X-þÁdÙ²eD£Ñ29ï¼óª¼"¿i¢ùÍ7ßLss3Š¢póÍ7ó]O…íWcâ>W­Z\¸×È¢Ñ([·n¥¯¯û?õ) ]§û¦›\»ÎîÙãŠA/¿°K%dÃpU íü$4°ÿ ÈaÖIFwò7fpKë&±rAÂᄌŒá»¥CÅdr1n\,´æ§¬#'Ó; kš†¢‹H²L(‘ ¹»›‘Þ^ »¾A­mJàƒi²cëVº.¾˜u·ÞÊ‘ÇçÌsÏ‘uUˆV’å´yßÝw³÷67£¥R.dg½°¦•Ï™W}häç?ÇB© ïoþ†~;W%ü«FdOÍÀ̯~Åž"løßÉ{î¶¼TZ4O2yrNI8ïv¬ŠÀ)TWžv΃s®•^àø /–Q;GG,ØX›œ@9l}JaTBÇ‘–cý¦¼*HꄵŒ=ÉáÊwI±>qÀ¼ÝIIÔE•=¿–Â-©&þ/y>eÜñ|ö§.É’Œ.)貂&…Ðd]V)Ê!û·Š&+嚬R’T49d}Jª½nMRÑ$…’¶Ö•­åœïº¤ Kªý]Æ@Æ”d«¯˜Ö•L úJ&H¦lšÈ¦l(¦†jh¨†Žj”ˆèºõÕs$JYâzŽ˜–£¾˜"®gIh3$´”)Ãú)Ð&AKž¶&mÒú42`¤£Ÿ‚¢f…3ÍhùýûÉcåCpçV9D?j“x'Q¼h 5 f“½@³½¡ù6ÛÛ×·‰4$& í8pÌÓ‡Ñ4œ¶Æð¼yL;Âó¡8íI÷¿W«ˆ»Êz–Š×¥Hµü¶H&²'O2sòdù_xÍ5ÄZZ˜èëc|ÿ~×óÍEB‚-‘lØíó>t¦ö5khX¼°Âç R› dÇÇù×÷¾—ëþæo^³Ú6 ,°À~çm±ýð¼õÖ[yþùç]ÿ]ýõåïõõõlذ¡ìqÖ{=ÛØëo2p|ÇŽòˆ¹7”JôlxG Eµ+/áPE£ÉWOŠj9蜗«&ެý;ì!3 n¯†)€-1^ŽÇ‘B¡rB®Haß1¬ÊèqâŠõ¾á-4ícÕŽa>Œ%2Hqü9ÝÍR§!I•­Ï°‚²¾ËaÉžˆÊI3&aFe´¨JAPRBhrM Q’C”•œ¬¢)!tÅ⺪ZßCVÐTCUÐU-lÿRÐU™¢¦@„¢d}æ¥(š©b š®¢Š5éÎoÝP0tk¾aȆŒnȘöwÓ”¬ù¦„iJ˜¦ýû;&²õ S²'$L¹ìÂÀ,³2Éú®X®gC–0eg}‹Œ69ÐLÃT0 S“0óf Ð$Ì¢5QS³?‹¦”ìÿ5{ù¢„Y’0µÊã45ÉÍ<õŠ‹Ñ”K IDATCriÀZ¿¥rmI2$IÖ‘Yµ?9l … 䈎5 n¢„5"rDû ‰¹Y⡉h–†x†ºÄ Éd–„š¥-;JS~œöÒó2ƒ$M“èŸ!t$Ïé“%h–an¢íj©^Ƭ—‘C&ªa §L¤“ Ÿ‚#)‚î!X|”…Xªõ6§,wM¤4ÄÆ`Þ)˜3 ¹4d¦ uúiÒºå)ÉÙ÷œC~D™ìrø”Ï €é¬P„çHÉÇÃ#æœ lïäO”Ÿe"'sdÁ3`!ÊkÀØž=ŒìÙãºçØi; ë¿|îs$°À ÌkkÖ¬aÍš5.ùî·½ím<$Ä~ƒU[dìßYé×ÏêëëikkcÔ®yØkŠ'¼¹ÞQ1‡C¬‰áÕÞw^ı†" Ì —_ðbqÀ˜ð™þW„mË6ùpÈH·j–óé¨êLSIlÕ<íUãq”xœ\*å’ MØXª hŒ@}ê»@Z,º!Ûg¦.A.c&§ŽX¤@QÑÔš¢ +*ZT¥ ¡ETr¡(“4‘Ñ’dµ8ÙR‚L)IV‘ÓbÌhIf´89=NΈ2£'(èQòf„¼¥`FÑ4Õƒâ=p—Œsv&™&JAC5udSG5uIGFG•tT©„*éÈ’Ž‚ŽìÄ`è²èuÉú4$¤rl‘ýiHVH’a‘ Iðr™H’‰,Ö$È²Ž¢T>Õþ­è(ªÒ¬yª†ÖPC:a¹HX.“rÄä¼åYÐ4T­„b(ºŽlà7­f$d I*C’-d“$¿álë8*˲LIV1d]¶æcZçÃ:f§ƒ†L±B+…ÐJ*ZQE/*è%½¨P,„(Âä‹!rù3ù3…(¹BmL‚!¦ó-@:Ù"d5˜‰€¦Ú=µ±B••´†`a æÇ`E’Æõ.Xùn}Ž•¡>â{³ÄÏf‰hœ]&£- QêT™ %ÐQ¨cšvs„ö‘QÚŒÐp|ŠîW º€åLqsL¦á˜aÝ_sT˜xHË짘ò5e¡~º†mwÈä§!_­hþ,˜•G¡n +”KžC8ÅI¼%š@<ÄoaBÅóŒó*m)øK;ÏBñ–Ìáöøz½ÆÞÊí ,°À«a­­­˜¦É§>õ)º»»Ë¤µµ•o¼‘“'OÒÐÐÀví€ÿ_›3gË—/È›d¼êð$½ÉÀgt±~ÁºÖ¯§ûvd ?8ˆ†•0î„Z„=ß—¼f!Êù:a`Q* ç^‚R°‹£Ž5e–|@„96†ÚÐ@GGÒð0@˜jXÊÅÀ%`\"Óß½Œ¾ú•ì•/`¯t!‡ŒULÍ42“KOG1Ó’βR…ñ”À, #æºä:q’i"›:ŠirEÒQdE±& pk$Cš"S¨ %¤£„uBÑáxU*¡ØäA‘tI#,—I%"R°\ !Í“òD¥4]4Á¦+æ†+áºâ£t>9 ¿„R/”&-2bæ-Ž‘¤ŒÍ@h¤Ç R‘fuíöM¿+|+gݘÑS= Ú䦠T¬x*¢Âó$*pm ·$°áã­ Þ¯œ7­wÃÂDBã• Q] `xë‰ß^OK@@ ,°ÀjØ;Þñ¾ÿýïsÓM71gή»î:n¸ášššX¸p! _Ê®![Ú4°7Ǽ•¿½ÄC§¢°äµ;xæ‹_Df9:8X¡ ã®ý^â*õ8elˆj:N¤GVâ¹²% £Þ\ޏÍœøñ¼½ÿ 9•¢e:E[ šÛ!ºB««¡xa˜‘®vŽÆ³W¹ÓÌe’&ê˜æiáXX8G²n†Èœm¾R/tå4VÌØÎ˜äòå¤ûû]²›SºBBýª¡ƒÛk«yžsïܶî¾›3==e£ äü½ÀÞ¼7Sè³åpTªóàX`æc·Þzkùûûßÿþ×d›LNNR´UIüöØoš *ĈS”2𢭰„àd$ˆùÅ~/í¢ØÄ¶·¦ˆ3€Z’J’jHq,Ø1°”lP×$bkP>‚æ(t$ <X œ,æ€Ù$a S78ÍêâAVÎô!M¨“Ñá<áÓy g¡0£)ÈAÕ+y+¦iqƒœÃ"ª ª}`šy ¦4k´]±—1uÐuÐ +§ÄíÍ٘ʹμêV†0*«äL s{¼@_À˜XôNB¦ubŠCMay 3+£ÀÞÿ¼ª\­ÝÝdΜ¡0>îKŒÅíxÁ¦ ÷÷n™ç}v¥pÉî#â:Õm“B!^=…éiŽ>ò;…”EO»ÅØ~I8yªÃtäD‚¥×_ÏÁŸþ´Lxl!©Êú&è%KÕ*PуسYÈÒ®ŒRW›^ämß#¼R¢Ðždº¥Ñwv29·‘‰D #I–8†"£„uê¢iæi§h96AãËSÔ7…²ÐÀ¸\¸\!ÛCA§Ø"²©ˆ’0Y¹V‚üqHåà¬Å!¥¢FåÔÜÉbý_СqÔJP¯;á8¨KФVhO@[Öêó¦}*‚\WѰHóŒ=M™ëïwÕèqú S§Ä›7Rúx^ýÄ êC[¶”‹²*‚·Â R¯HÌ…4ļÉóÜßvz@@ ,°ÀÞxÛ°a;wî,çx‰Íúõë‘e98Qo°é@¨£-ŸG³´Å‚^£ç…©¼ðvlZÖ®%ŸJ‘t…r‰9nˆ6Úd¢ÃþŒ( Êh/î‘Æ&›°Ì• ¾’­ .i)H]É Óf(ÎÐäÖ0ìKPi*áñN˜†"¢ •<•ˆÐSÀƒŒ;äL<Ÿ¦wæ•|Ftñ,¯¸•~ð!^b)ã€ê\ÓC\$ü ü‹?Ž÷öÖ­¸·p¡—8më úU0—=çJÂ’[øéOË×Åô9^MØ×•wÝÅË?ø©ÁÁr$Ÿ6ÓÓþéOË¢ ~çËeðæ\»jø 0 œÖA²¦ð1H>gRÏ4­LÓY”Å«‡pä0Öh2„eË›…j³úvÐÛNEçqˆ•œ¡‹b,LëÕc,Ýp„…ヴö½ß$ò϶mÛ*×Àp^h÷†T‰yŽ·£@µJ¬šLrñý†iRH§9³{7£½½.ÐÈGƒÍ3ZV Âõ6r QÑèƒéq8`XatAè&0WI /ëà96ð2çqÕ¤©G¤…q–1ÀùìcƒþówŸB~È€'aúEØ›…X`ÅK´ÄQsp‡ˆ©Pés§°š¨–›íï/W—< Ò!sá†ôB-Ÿw‹€Xö€šã6x’|Àº!´'ä!™Ý»Ë¹;^P,N"ñÕÄü=†gÿ"P†j¯ƒß„‡(8ßnÛ†d·Ù¬Ñ7›–/gÒNHÍBür^dò¡& iè…BUø—wÛ§ùK~ôË_–ÛèW?ÇZ¢Ú¥xΗäi£âC¢¼¡z"Øu‡Hæ5 Ê ƒ 7½Äxs ÕÕœn™‡†jÅ4‡@?¤rè•|oím¤" \²òÚ®$Ó9CSJ'™ÓiŸÒ¨Ÿ2INZ‚d[ôÀIÆwú`ƒ=–Ð$YS a dò%ÎÁHκݳTò¼Rö9u¢(;HÚ¹õºaå]Í0nZ÷sJ D"‰tYFvì Þ‡<ˆÞCoŸÖ5ÓÄÌç«j…àé“&Õµ5_K H`Ø9ìšk®ùæöú[4eëÖ­ôõõñȧ>Å(µ+ýŠàÍ vMªUgæ_r “ƒƒ…‡|Ф°•P ç^R&D&Aš±B–PX†ºf¸<Š¥{–”h#ÄŒ+ä>ÚÌQ.-îB)é$ 3täFh›¡q(Ex Ïû t&³•¢†1*á ˜Ó=àÎ[}\ü-yˆJ„ê< ñÜyUs–]{-cýýŒ÷öVy¤#¬µãÐk…ÿˆdÁô´ÅÛVAí0©ÙrIÂ5ÚnÔ y2þ^ ±„ ;ëÌdOú^G¦ÍYÎoûºudÇÇ™°I7¿E }ƒÙ=:Þ> ãï‘fYßKìÀ?Éß9—y{Þ0p 4aÎ,x愺'¦yǵ?§ûªÃüËÂ÷óËæëé[²’ôõ° x ?ŒðHË&Y´ ÖBüÚ,ÝègeÝ!–ÖeCòYæœ>KÓáIÖdãË“H¡xNMÁPÖ*gRÌS¡UµI;ݺñBgAÍY´TÖŠTêµÚç:j?#ŽêPÔÝ$Ò¹ÖaÊSQÚs¹Ÿwl6ï”è½3€ÖÕ«1ŠEÆí•ZE %Ÿ>W«¯$°À ìu²E‹ù†]-Z´(89¿VÀJ°®UPЯ —ÂTL?õ3öü.ü+«‹ù$Ž£#•ĪiPÒ o“„v`‘-- ,.–ZäC:kÒ5y–®âYk¸ó8h£ ‚qÌÐ&¡˜¶j”¦a¦d²:êP¢JŽX¼Ð Dâ5Ðô®‡ø{‰MßöíUóEPî±¢‡Â[¹^¥:‡Ãg¦ñЀ…×^K ìØAvx¸*©V÷€y¿°&ÝCT¼£ÿx€œH‚–ÙádÞœ oØ”@—k}¿Äv‰jO–<Ë5œzöYd(”û`ëžãÿÜ¿ú:mk×Ò¹~=±–¢Ö¾ ƒ—¾ó¦}ÛÕ¸|9ó7n¤oûvŠ©T€6©ÎåqŽ5 œ&t˜ìƒy§¡y—Κ·¿ÌŸ½û«Ü°ô¾pÏ¿–#—,!·/NþPý~­ÃC&Ùb„}ÊùìK\M /6u•/)]žcþU'™Ó1Dwè0‹O³jêÎO’8>/‚q2i+vB,ë­Ðª:rpÁ ˜ãX®Œqà4èÃ05c©pÄrÒd .ÞÃ"‰½Z%Ÿ>%yî/áõžËé^@ÆòÜúy>Äœså7$°À ,°ÿÔæ„J8`I 3_îŠÏw±F‚·à–Œ%bgEDˆI¢y{1!¾ˆ%c[.u>bodО7dcú'á„a•<î‚aa*›ܲÁ^Õ'9aõûÞÀäÀ§ŸyÆ*‘«„åN=ó ª°î‘‡&R_ÏÄÀ óçÓyñÅôýìg.Ââ¤E í¼eÀ“þk™ÄŽ=ö˜k^Ûš5t^tQyûÿùŸ«Ú‡˜‰ž/èš­.XµdD‚6ÛyÀ³íeo{GìB©Ò,Ç)ÃCŽäsœ'©ÆwonæµµŽÃ¹.#½½ ÷öÒ¸d õóç[ÇT*U©k‰6ÕßÏ”-=ì&“7OÇÉÛš¶¿g2Ð~æõCÃöW­èáª5=ÜuÉ™\ÝÄäUMŒ®â¥™ 8“›Ëé\g ]œ)Î!•kÄ•0ÎȦ#Цûël‡ù—ãÉyoáÚ¦G¹†'¹bþNO¤(= ½C0_‚yq¬œ”U@7”’*%Ù’ÇR3¡É"ÒI ”Ðrä³`¤­ãšÄÊ1Ñ„ãÄCú4â\Ëþ=!‚bžSIèëbBoÅö€€X`½Iö¡}(8 ¿EÂJ u¼q*ÿâöä(?Em)O§8]Ø´b¸]#½FEAÊ ƒpŠ—e…ï9*úúâd+9µ+æ{‘õÍXU•çÙq´@DZ†DOZ޼-ÏW‰êªÄ^Å('DÃ!®%…/ÿð‡ð0ÍšàE÷,—èèàŠ;ï¤küå-œêéaþÕWƒ$!É2çoÝZ–Œõ*;É5Ÿ—EéNÛë,`ѵ×2°c3‚g£aÁò““¦§}‰ÏØÁƒŒûäi™À[Rà]¬Ï¤:¤ElèñXºy3‰Ž‹(åó\|Çe0þðÿqðöó<ˆÀûè/éòpø-ã]WL.÷ûßK8$üU³ü¼Y¦g?pîÄ÷©£G™:z”+>ùI–mÞ À wßÍËÛ¶¹Âª¼}à²?ýSÞòWÅOßùNvì¨RØ÷(¿CÀ5,’> ¼\é¨G¡î!h ÏP_?CGý)&ð¶ÆŸ`D$4ò ’ ¶¨äëI/èdê¼&&ç7q²~§ê摉%Ñd•¤”a.§)š!ÎÆæØ”%ÒYbÃAÈŽYÏØ8ÈG­›On7¡´„BiŽJa^˜èº<¡Ë58Ê1h= ­ûáÂcÀYÈÌ@º r†] ‘j,gò¢É{‰ê»ÙDtâòô¯g, X`o’ɲT>ÿ-³àÜÅÿ¢6ÉPK»ßyƒŠ¹"»žn@I¯Ä^"Æc—„ßNâº!ƒVÈUVÒiS  °b¹ìp $Y¤!0‡@KAÖ¬FtFEs¸c¹ýrXÌs|%eõ–-R)ú¶o÷M.'Fë:á†ÖÝ~;²ª’äù¿þkҳԌ՘oÖòµÃ–Ä‘ðìà /ß{¯«¨$@ÛºuŒ8@azÚ_ÑÇ00²qþÖ­üú3Ÿáøcqv÷nÎîÞ]¦báï9rÀù1ÛÛáô£ƒÛ¶UõÇNäômßNÁÞž˜ßP>]w,‹!0ø€Õ[¶Ð²|9Ï|éKèvÒ?T'ª;ë·e j4ÊÉž¦úû}=_MK—knæÌîݾ$ä"× 0ÑßÏ©žžª>ôì¿È³_ü¢«ïùɺŠûèýÁHvu±òÝï¦yùrmßNÆîkb?×|ˆ‘×S#›A*@l¢£¶—.a2ƒ¥,¥Íè´2ÊâÐ(]íP7B+@¾Ô†(´DÈ'#¨ªF¼”C4à ÌgátÚjß|m`.šuÂ9" µToMå|‘¬¼¯ MP7 u'QK=«8㚢5!o©ÆýíGîšmå:¯ð‚èyÓp sˆýRö!Šç"Æ ,°À{­»»;8 ¿e³±½óÂ+4cBÉ€b©’Ø)Êî:½!âËÙ v,¾ã•Ë»âx=º€.“ ´Û3šìG,°Áˆ•ë1ž…!ÝŽ$¨W¡Ëðç Q©žÏsÀòµ’„ESH¥~é%bÍÍèÅbùg?brvÓÒ¥D›š8³gOÕHüQ›|ÔJvƬ:6` ÔJÆuüÐîÝ íÞÍ~œ¿Ÿ¼í€@,¼$ʯ-Ò,ÿ;ûõÎ×=Ëúµ½–wÂ9/¯ØjZµ®¥—¸’Tƒ¨³YP”ªþô{_øOÝu`y{ö ÖåýÍÛng›s.¹„Dg'ÍÝÝÌ¿ê*Ò'NðÄ_üÿïÿíÚ†\ƒLá!ËÞ‘~¨8'©xLTŸ69¹¯” qOCÇó°p´Ö™DÛóD—ä­Ñ„„½ƒëS^ ‡A³¼g†áô°µO£© £T¢.“¡hR 9nÕR]á$}éb寗§-ï«„»¶H:/ˆ1KNõ÷»Î¡X¸Ð/4Rõœ_íç? X`o % V­ZœˆßB›Æ* ûL"Ép¾;¿ýFøüF×nÙBzpA{Ô·mùrRýýĨÈðΚ%«úq² ä*õ?ÊššæF •ƒÃ*t6J%¤Ë ìCÌžxêM¸·€(ÿê—Xjó7nä-_úu󿡯büÛ–-$çÌ!sö¬ëüH@í­½aé³gÉŒÕLP÷PÞ6‰ëøÂ×Jæ·ã\Ïú Xl‡t9Éê~$È/ùÞñ¨¨‘Hy¿Ò9ÈŠ÷÷2ÛË¢åó´‰D­ó!û{ÉsþÏå]¨USÄ .sgÏ’;{¶êîúÊW^•ôªù½@‘†mßÎÙ]»H2²?…T CÓªŽÁðô#Ç˦ڀ\Ì׉‡·&T<²‡´—*l¢ïxGF5hž„æ´ž€º$„’ $íQÃZ!R‚¢a œÁRéš´LÕ0ÊóC:$§­)>ÉšÇk‚aKþ– w.™èuÕЮà/cì'Š=˜³\7q]£Æ²~UÖX`öX, ¼¿¥6Ä«/QÏ.ŽœÖõ¢D­“s1µm`AâýýÔÉ A"‰(DAMbUO‹ÛoW§´òãPHC&CfEã?eƒ 1Û•T= ÓW‹âN²³èÕ‹.BŸÀ]YNõôðý¹â®»˜wå•lyìSH;Œ IDAT1rããœ~öYžýò—9ÙÓcùùóYôÖ·áÈ/~Qu]–Üp‘†þèGh…‚ë?'4¬\Œ‚"€oØžI0’qðK|7©é’jÓg»20l{5fKwöߨÝͼ+¯dôÀ†öì){}üzgSÉÛãG̤`Ò› à% ~!|Kßþvbííhù<¯üË¿Ÿœ¬:F‘H‰JVÞBx£»w—Ï—×ú·o¯"Z~ X<6•ЬmܾÍ"Tê¥èÉzú¼SçǾ%ŽþëTò/†€˜myhÏCë˜Uß'šÉ)’"C4­%l¯E-•Ê÷\+Ò2ƒ»b‚dVˆáCÀEaMx.,¸æê,`òðaNïÜéKÚë³êýïGF9µs'‡——q®Ûho/Cv¢Tc0À¬AlH`X`Ù¦aŠ MTÒQ=󼕷yN‘¯r.‰l%­Gˆ©‰@ÈžÂq’Ø '’/§-ÒQLA:úå嘲AN··3=2R&ޤ¯˜<ïlZ‘ARÀ”­\U¶  EåJˆ‰˜†@¯[I­y½R$c7-»cíT«‰#xæ _ qéRÌ?ùR'NØ(Ç(–éS§8`«Káp%@QUUIª—/ ¡Au]]´®^ÍÙÝ»15­ TË>@ 0m]—_ÎðK/¡çr5€ü€¿_]’Zû“f! NÿK :rL³ªµŽ§™¨U“%ÞÞ@nddÖÚ)³W­wæ<üpM‚#¶÷¨®æ—ØîÍ)ò ô*^Auexç¾ 9¤+z©ÎžêˆØ÷‚dÚÅüt˜1­ü‰I*u5œêæ:ÕµZd€˜Â-ìxŠö=›6¡s³¶7$¡84kÐP‚9(­b‚Y¦J™˜Gæx[ €©ªDêê(NNV]+o £cO=ec[DÂ8Ë¿òã[ËØË:׿ˆ@€g#µ‹j¾–À ,°À~§MÅ …ewCx SÔžçÌJöoÉÒò—# ‡­IŠáBø¦¦:¡ƒ‘·ÐY„b´"”òÍCF‡Œ­j3e€ix(Åb9„«+E¤Q‚Ùòª( ·‚Òl#/}9Ú¾NV©{â$µ§ížs ´iHk–§%CEÅ+»"¼X Þ!$F6‹¡ë(6ñpgÓ,ƒ!/ùp>üä'epéJæ¦e7ÞHsw7õóç—Á“¡¡(6„v§¦tÝ·’¹ŸD.>dÀ ø? Wô¦‰aš.€ïÝölûð «ñªTIÅb9äÍ{­0ŒªµZy`¦a D"„ ëžÈdÐí¾Â,}L"MM¦§1íиÙòÅþÃmÛ¶‘Ïçƒ7k`X`³ZX(ލÍ"²á’2`³]$¦†dïb´`Ý;‰ÀÞ¤"Ül│›š¢Q‚†0Ô'!Ü¡&,™Þ&¬xޏÐ`Çmãd‰æ±XEŠJ ú°U°pºSkÔ6c'',ÅiŸæ^LÜqõ†÷›üãž\@Üvß¡d’¦¥KÞ·½ßþvU;¾å-¬¸ùfê,àøã³çþ¡fYPS¯¼âJ¸õÙBIÄ\¹iÁçøkÕÙ¨åAÑ©]°Ñ/[ tyõ¦¦ìþîݾ÷|û]‹ú Hrü±ÇfÍ¥¡Yš­7>d‡Æk:n¯&ÂÀ‚jBSTÉf'­Â¥ƒœ…úQ¨‚“KÁ˜-u;IEèÁ©0^ôôy±}ºp{…°<+I¬ð¬xby÷À†Šå‘½¬N3Ãö@CÞÈ]§0=íRÔ+âöHʲnàöRH5ús²³“Ž /àÌóÏ—s¸ü–ïÙ®Ë/çÌsÏ‘›˜pý÷zßZ²ÅN4»×£^X`X`ù|žmÛ¶144øw^ðbxˆw*Ê•šº@(¼ŸÞð$wR« „“I­­L?^•ÇÃÅmÄŇ¥Š#·`éõ6Sɱ«ŸOC&ky/òš%1q€2õèEKå+eXa3¦ÛÛRš„‚Âó¹ÌœˆÎ;îJ¿áBñ8u󿹍–mÞÌ÷ÝG¤¡?ø¿øð‡Ñ„ÁHóàÞ¬AüÀ´9 Ó_űË>ÄÁð9Þº®.ÂÉ$©“')åråmyó`J©T¹o;OįîƒYDš5þ÷怴,_N!•"/È{Ïå¦{î¡}íZþmËWAïrzë z~¼^†P2‰–ËaØ+oí DZ7…EFì{¨¹]G-’m¥¤.ûÏzëž’Ö@´Ñih±6bL€1ÅiË;™³t;Ü0ÝÉì¢gPË´@À]^1Ü!•bŽ–„;9ÜÙFÁ³Ï’ð¬ñJðz¢ü¼ ©'*¡“ÔözÍÉåZ|Ýu¼ó‡?dúÌŸ|’‘Þ^ö½Æx<Á ,°À ìw΢Ñ([·n¥¯¯?õ)NQZRkÄÖ;Z[k„¸uíZ:/¹Äwÿ·mC+Êu6Ö~ä#4.^ÌÐ /pª§‡éþþr]¬ÚV ]‚ú–—£ÎÞØ¸>2–´g6 #¦¥¬sk6do+$€9Q6¸ 01¯ÃÚÖ®eÎ%—”ÛìàÝÝÌÛ¸Ñu|ÝvÂêmÛxñž{ÊóçoÜHóò倕ǡ{È@“°½ã?Îôà ë:dÙÿïø…;xðAŠ™ ¿üøÇg%~ä ÑÞÎåwÞI×úõ€¥–uèþûË$§VÖ¥ÿë±â]ï*ÿ~ìOÿ”³5’¨M˜¬• níkײöƒ¤qÉš–-£N3ÚÛË{Û¦irª§§\+„àÜÞ‘d¬x×»8»g)á<{Ûê—Ë1hWWg9¿NqÅïz ßúV«–Ìý÷»Ž¹Vhh ßúVê,àü­[ˆµ´PL§ÑK%¾oKóŠvþÖ­Ú¾éTª\”o+I|XƒÆ´5µœ„dÂR« %@j¤žå¸(ÚAn¶$tÕÄf!ºJ`*S1o'ljÜþÔ©„t‰¡m"¡w‰,?"!æâ>ƒçê÷ÕÒËÎwñ^-¤R²“ÿ½ÛJ´·³tófìŸÍÝÝ„ëëyð†Þ»·¦b\@@ ,°ÀûOk!;¡Ûï%½tÓ&VÞrKŒžìéahï^4a$úÆï~×µî3_ú“Œöö2zà€oØ‘lšD`‘ÏóÊW¿Z!¬ÒNâl –“Ã)`@Ò°5›Ó*1æS¸C½œG¥Ç++ܼr%ÑæfbÀ©gžñ ëíeìÀ0ͪP$ E¶þ9öØc¤éý§ò;§zz8iË{-ÖÜLËÊ• ILô÷3¼w/¥lÖ¤z¹E{Ш¢…ëê8oË–2±pìÈÃsè§?-ÿžá±O|‚Å×^˻￟y7²tóf|c=fIÀööR´«¨;¶ë¯ÿš3»vihà};v°þü2¹éí-“‘™‘&¬‚o+WknáÜ{m¤·—ÇÿìÏ,P·bçß~;—ßy'ÙÀàäÓO3Ñß@Þ.990@vd¤¼ŒìÓëÿ×Å’Ýýˆ@Ç…¢Æbh¹Ã{÷VÉ(×"zMË–qã½÷ih`¼¯¾ûï÷»ën¿b&ãÿóºÖ½âÎ;YtÝu4ØÄÏæ]q…ÅÅ*‡ÿˆ#îŽGÀá iÜaY¡Œ59áP÷pÂ2Åb|åtÉxP$+¤K•*)_²i}:%@§÷þòÊþФÂKøü”ÏL`Î¥—’›˜`r` Š4-[Vþ}f×®²l±_Ž÷šœééጭZç%²®g¥$!É2§žy†§?ûYwŸ°Ÿ¯5ùH`X`¿ó¦ ®êÑ"ÀÚµ‹ôñãî®®»Âgö|õ«®—ºvút¹|‡bš®äv结c➘0OLÝpª„;¹gL˜.Y9NB¸“ŸáT_wÀ–Œ;tÃ6އ£uíZVüþï3öÊ+ŒôöVWr°G„dúû9Øß_ ñ*¢—è¼-[¸øŽ;xáî»]jV‰ÎN–ß|³ëڜڹÓõÛÙ†ŠU²Kôb‘‚‡Üðo°èšk,°‹Q¿`ù‰ ×~sããD››‘lµ-Ó49öè£<ôá—ãà:/ºS×Ú»·ªmºçV½ç=åm.Ý´©üßò›o.“—ÂÔ;ìoîW°Â>ÞñC‡Øù…/pæùç+À9—+“°‰¾>žþìgÙÿ½ï¹ö}¾‡p-¿ùfv~þó(Ñ(—ßy'‹íQéÞ¸Ñ?ñÛ&³Œs’ÍãmmèÅ"¡D‚“==D‘É&?b]°Bâ®þìg14Üø8?ûƒ?ð%¦£½½<÷Õ¯bÚáTÎ>3§OóÜW¿Êsö=æØÊw¿›HCC9 í=<€‹ñô§?]µ¬øÅð,oŸÕ³ª“ñER–z–¢W ÂT¤~¢a[õöïz*aŽyaÀÀ¹7½y8no™÷Úä''Ñ2™*Ïl©P@RU.äÌîÝ„ëëËýmDÒ•=÷ÁÒM›ÈMLpâ‰'xñ[ßr%W¿Qv…§Í}÷ß_E8~Ós&^3‰ÚµÔd’…6a3ŠEŽ<ü°¯ •x7Ý}7usçðäw2öÊ+¯ªmµÔÁ¤YHÌ^Wbßÿ9+ßõ®2ÁèÛ¾|*ÅчöUrz5Ö²z5MË–qgM´B?ü!Ç~¹X, W$¨Ôq¤±ÅB€N˜£˜»áDv‰¹bb9™(xk–xïiÙç‡g°Â/ç˨ñŒð’3ðÏ›ûÀ¡C4­XQ^æØ±£<ûìÄ„ÁÓ”'ž*Ïkkkç︀?û§¿cÿ‰Ã$°À ,°ßm‹`åWx="q< ¢\©Rc¾ø¿—À8¡O9ÓÕÔíÑJÓ_¦î¤V5ÂÿJ,†©ëP,–Û¬zȈ8â*ÙûK ]'?:êÞZÌfÄ)ÑÙI¤¡b&Cæôéß(qÝ$E¡yÙ2dEqýŸììdím·J$˜¬Äl%EDÊË]üÑrä¿`êØ±ò¼ã=Ɖ'Ÿ$ÖÔ„Q*•“ªg“ýMëH¯bž‰U?¥Ö~æ¬_Ï*;àÀ¶md‡‡]€ûÕ€~£Æñ”r9N=óŒ½á•µ¶ûÈwÌJ&ÏuþL(_ϱ¾¾W}]&íïƒO=EÛêÕ¬½í¶òrËßùNöüýß»Â&›8|˜“O?]sŸ‹®½–µü ]—^:kÛV¾÷½üM[ù±1l%Ýr¨—ãÕôÄB¡Þ˜Îb1PÝ3ùÕcñ怘>ƒ~5L$ük¼È± PÌdH>=+a”ñîxõ ì¿©$°À ,°ßisB(D€æTö‚¿ fU¨ LÓex@†ØŽZ5fα…C¡ò:^b…pÌ" q@N2™ÄÐ4 ›€(5ˆ‹á9^/(qæElµ/Y–™±As¾æoÜÈho/y»:6€°öÿ}òK.ùØÇ¸äc;çõÖr9þé²Ëéí­\ ]';6æ ýÎqÛºulºûîWÕ¿^Þ¶_å²’Ï~ïéÁAN?÷Ën¼‘ú ØðçÎÌðpUì¿hO~ò“UÛ.¾ãγÕB_Þ¶î¾S×É ç ÙªuN–Ýx#WÜygÕ~kÕOi_»–9ë×sÝßþ-ád²*ÜN´“==Ï-¿mSc¾ kmYF¶ jÉëÂ>UÜ·×ËX`Øï´e±Šs жnÙáa²v±µZäàPËKà€•º ¸ôOþ„_ÿßÿK! uÕ*Öìc(‘Åéi~õéOSÀysw7‰övòŒÛ¡/²Ï~ {{ î*G–×)¼èE€ n½£¤âè¬Xפä9VoÈOq`€‚„ñ§3v¸´³¬Zù"ý(]ôÚ—XŒßûâËž’WcNÎc"XîºôRäP¨æºó®¼’¾ñòï}÷Þ‹n‡íœÙµ £de$t^tj,6k;fFFØwï½å¼DG‰ŽŽšËßúë_ŸóØ-*“°öÛ×­ó]6=8È1[ý*ÑÑQŽ÷¯µß‰þ~~|ÓMå$yñ¾éíuɳ¶¯]ËÛ¿óWšx×ÞvÿxÁ®ëæ ~é%¾¹bÔÛK¤¾þ }ŽüñÀ@Y)ÊK(gFF8üàƒÈ6Q2íkî•Enêî&ÞÞŽ$,'1»¢Õ¹Â!E cñ>Ž67Ó¼j¹‘&®",z:ÍÝÏCžÿüöë®éŠù†P(LDp*×i`X`½YVÂJæVc1.ýøÇ1‘ýû9òÐC®fzjŠB>_®F.¾ˆç^v ~ï÷ª¶}ÈV$ba©ÁAö|ûÛè¥r(D´±‘·~ýë,Ý´‰;ØóoPÊd\Û.LO#IÅ™™šäGœtùC&"XqêbxˆWõFôxˆJZbX˜Xƒ VM ïö¼#¹ŽÇDÏçÙ|üõ¯‘dw‰»Hc£Kö,YÖ þÛ«yµ\ŽÝ÷w.0?ðàƒåßËn¼‘D{»KæÖiûs_þ²k[ã6 K©I¶Û×¶ns|¤—›»»Ëí=ëV´\ŽB:ÍðÞ½e²ð-oá¢|Ä¥\ôjìÈCÑuÙeeE­ßĆ^|‘Ù´‰ì訋 5ÌŸïêK󯺊æîn7qeôÀšÛ~yÛ6´|ž‰þ~ß,oHØHo/ß»òJ:/ºˆ->Z&|/}÷»¼òã390à"µÀlzp'3‹>ò‘šDêõ°HCC• €h—ÛÞ¡žÏ~–ÓÏ=Ç‘‡B”p¸|¬?ó–mÞÌ?_uºP½ü\mläÂÿþß]ó|[ ­Jaxr`ôb‘üèhYÑÍ!â}XÆíT{LkU§7|‡—˜¼adñâÅÔÕÕUn˜œ=;D6›Á0tÖ­;?xX`ö¦™ ºÎÈÁƒLŸ=[õò¿ø£åø£–G€Åÿ³ããŒÙëŠV´Õi$ŸµwTrr`€·|ùËÌ¿â W]e›73÷ò˹ÿ–[8ñä“åm䇆È ¹’ᩜùbø‡üiRÃ4œÿ5©ð«ƒ"` ¯ùzU<ÀÅÄ¿,œ¿|‰³»v¹~‡“I?ð€kdþìž=Œìß_\Çy¤fØýõ¯Wµ¡Vµnq5-„@Mõ÷Ó'Èú:–èìd¿:¦‹õ´åù¯}ùW_]& ¹‰ Núx0ï‰cÃûöÑ´la[ìgÙ7rá‡?•âÇ5BÇd›à…ûV<–ýÿøDšš|×5tdWó7n$ÑÙIzpÔà ©ãÇ}à›â×ù—¾Ï¤ZÏ W›ÃarããœÜ¹“þpÕ©Õÿ½ƒrO) ,øy9ð!pnQ‚×€LO§™7o.Åb‘™™$Ibdd„d2Êèè‹/©ÍîL“Ï}îsÜvÛm¬¤»öïßÏÐй\Ž 6Ð1Kd`X`ÿ1m÷îݤÓi¦¦¦¸öÚki@ÒÓO?®ëìÙ³‡w¼ãD=É©x^ÂÓƒƒ¼ò£Q×ÕÅä‘#å (>/VoØS8'ÞØHvxj5¬ZÀW³ó5¼IëͲ̂«¯¦05ÅäáÃUÄ¢–wAL7%‰¹—^JêÄ f†‡)Ú5J¼Ié‘“áMYÆeLIB—$ta]•jåwR½”Ôº:—Œ(P¯2 £ ù‘)ÓnO-ó†Á8$M@²÷Õ£¶¯&Î^ô(©‘±ÆFŠž¤y¿þ`JHÕð«kýúòÈ÷#ý(ùÉI×µS˜]ü@ì+" |ê)¾½zµ•K‹±ê½ïåÊ»î*W¶Ž57óöo›}÷ÝÇû|ÕJWÂaZV¬ aáÂò;v”á^þÑ=p€âô´¿ôs>Ï{ï¥×Î÷ð Ä/NL”ÛÿÏ—_nÝGuu´­YSóZŸÝ½SÓfW-+ùþå—×åâw§oúeô(¥$´Sì+‰ÎNþðÉ'«rržýò—yÒ¿û|­p--ŸçåþîÏR‹°:û¾äãç­_ùŠ5ØòðÃ<ÿõ¯sìÑGý#dÙd0M$ïö%ɺLÓ†éÍésÀ$ûYàê7’„$Iåûy6òôº€ÑÑ1J¥bÙ‹13“a|<ÅÈÈhyá…Èf³ÄãqêëëÙ\ƒ©îÙ³‡­[·Ò××ÇÀÀôöö²[ˆÝ<|ø0úЇ‚7t`Ø›lÉd’¿ÿû¿Í·ÛÛÛËÖ­[Ù¹s'CCC.røða¶nÝÊ<@&“!ÒÓÓC¿"144Ä1@ š1Oœ€'|Ë«¶#G¬©Æ6jëšßŸ}Öšàœ#â~ÄÆ]s ýóçêUdGF8ò‹_¼*E/%aõüýàZ—߀X˜##`: ¯ûàÑ …òhÿlçº\Ìð}ïCrKEë÷ÃcÉX²¤jµÂ«f#®ksæŒ5½Šõ]s õv^…«­v{õM›Ê`ÞïÏÖNs–>dærð½ï1`€&OÇ©;™˜eÛ&X×ìg?³¦YL:ÇïWk®c˜ž.÷ûsíóß³¿WÛæsݧ¦õ0á™­[‰··W­¿_øih`Åïÿ~u?-#k•ô5×püñÇ_U›þ{w×uþÿ=û³° «Ðb‘°lm–dK²-+–,ˉe¥±ÔÊQ“4[ÓçÛ¸í/i“&OS7K›&íS»©;F±eËÖj훵¡¡’Ø÷`€a¶ßÀƒ@«µ|^ÏÃÃÜeνsî™{ïgÎ=ç\¬ªâÝ~÷¹­>—‚¬ß·Ý¾`±öÔ©€å¶Œ Âbc¹¼wïMöïTÃ$?ó ŸõžGú$?ó ¡11}üq@p¾víZÂââî\b2…ñå/¯Àl¶àõzÑh4øý~ŒFf³™‰Ó0­²Ùltw÷+cÇŽ¥~À/P---DDD`0p¹\¸Ýnt½=PLž<™É½¿&<öØc×õ>üðCVôëg{ Ó§ONRRÒ §±wï^~øa"†¨Æ»ÛIÃ-¿i܉mÜ+ûÙÒÒÂéÓ§yòÉ'ïêm”••a·Ûyø½ÒÜì÷èNlãnù=HßÕÛÕ‰N§Ãív+טþ× Fƒ×ëÅçó) …ç͛Ǽޥv+ IDAT6ÝÝݼØ;‚õH܉²{G–ÿð‡ð›ßÜxóæÝú}üéOoÿ¹înã¶|÷ûíßÍ–µ;qM¹Ýç¿[q¿–ÿp˜6!wûg¸fYûÍo‚—µþ0`µØØØ[Ú3Ù°ˆÅb桇ү+ѱýªùŠ‹‹9vìz½žÆŒï~õ+^}õU^|ñE>øà"""X²dIдRDûÙ9sæ5ßS__Íf»æ:Ã¥ÑÒÒÂĉ‡|Ùëõb6›Õ;ºèl£°°¤¤$l6Û §1Üò[‘Fllìm߯½²Ÿm½=QÜÎý¼Û ¥­­í¦Òî{t+¶q¯|†;Ü-åóV|Ïn—/~ñ‹¼÷Þ{$$$0¡·oßubÙ²e¼ûî»L˜0È ½éõúëÚçáÊ•Ï磱±ñ¶æõ½p>»Ýûx'Χ·{oö^`¸ódcc#µµµwuYî{+ÎãŸ÷q¾îQn6ýáÊÚH¾o·šê¯_ÿ±¿£³_½ü= —/—c ³b2ëGœF£ÃbIànwäÈl6Û ö(w›Í›73gΜkÞ8Ý ²²²X{nëd?ïÏý”ïуyÜEEE4662wî\)/²Ÿ«ÆÆFŽ=ÊsÏ='çX)‹w¥òò2ŽÛGH¿ñoü~5M´¶Ú•yÑÑ1<÷ÜbþîÿŹË%hf=;ÿ'nO7OOëéâL«ÕãpØÑëè šÞÄ7;Q hŒ¥Vk0ÌwM¦øý~e}>Ÿ²ÏDDD(|õ_Ïëõ*ŸU¥R}®ûƒÕjU9¸[5Š°Þ®e?œýø=º[É÷häçI¿ßð˜S>ŸOYÖ÷Úï÷ßõùz=׈¾é°°0¢££•±¯îÆkĽpž}¼yz½ž¸¸¸€›;9ÇJY¼ç@¯×‹ª·ñùÀuú+U*v{ ••åîTtttâru)sÂÂÂHKë©ÝÞ}æ8uŽæ‘5B?|¼UXO톣¥‰–г¬^Õ3 Ïþý‡°Û,_¾ìêþç`Ù2((€äd°X ;þöoïH¦ñÑGñƒü€Ë—/³ÿ~t:Ë–-ÃÒïùµŽŽ^yå^{í5\.ï½÷twwó½ï}ïs¿Á»Äi¬%ûyÿïçµ7ºÛ%9îÁõ?ÿ¹Ýn>þøc:;;ÉÌÌdJ¿Á¿jjjøàƒ°Z­DEE‘››Ë¸qãX³fÍ=|\¾|™·Þz‹Ÿüä'ÔÖÖ²cÇÔj5K—. èÞívóãÿ˜ïÿûØl6Þ}÷]Ün7uuuüã?þ£œ'do+­V{ןÃî…s¬”ÅÁNœ8Á©S§øö·¿Í¹sçÈËË#$$„/~ñ‹Áĺuëðx<ÔÔÔðØcqèÐ!âããyä‘Gxè½›uu¹hi ¬hD!«Z‰ã§0˜ãùõ¿ý”™}AYVUUCFF:îÞ‘@ 1c@§ëé}!6‚ôí~»´··+]úîÝ»——_~™éÓ§sþüù€õÊËË• 4 ¬Y³†””–/_Ž·Buu56lÀçó‘““@ss3x<êú +ÄÔÿüçp80¬Y³†SzV‰ŠŠâßø L:£Ñˆ×ë¥}À¨Þ÷’ÆÆFÆŒÀ'Ÿ|ÂË/¿Ì’%K8räHÀz¥¥¥ÁØš5kÈÈÈàKFðb¤~ÿûßÓÞÞŽËåâÌ™3tvvÒÚÚÚ;Κgñ+„¸•ººº Uº4?uêkÖ¬Áh4âÐ%õ²eËX¼x1S¦LA¯×÷tÛëõÒÑÑ¡¬OBB¢òg0ñù|ÄÅÅ+ÁÚ(±77òûÿú±t:O-]I|â8rrN’“s’ÐÐPBCƒT&&~.™ûÈ#Œh½ŒŒŒA}Ê_¾|9 ½7£¾¾ž³gÏâñxØÙ;jî¿þë¿ò£ýˆßýîwüð‡?dw¿þ¾…¸S‚ÿ‚Ñëõ:tˆôôtFÍ?üÃ?°víÚ»ú±[uHOOôXDaa!'N”$nÈùó穬¬Än·“““ßþô'Þxã ²³³ùîw¿Ë~ô#É$q[ÆkÖ^ôçt:ÉËËcÉ’%̘1C9ÿççç+ë¨T Ó©ÐéTtwwÐÚÚŠÛÝËÕ‰ËÕ‰ÝÞBkïøH×€Ä&Œæõ÷÷iãÑWk?fÏžÁìÙ3HL¢ñyY”—ßñÌ]·nùùùlÛ¶+V••Źsç˜5«§Ë·¾õ- gð«üü|²²²p8>|˜eË–Ié·Ì¸qãHNN¦´´“ÉDKK £FÂãñàõzY»v-ñññ’QâŽëþÓjµèt:²²²X´h‘r=|ø0W®\áèÑ£ìÞ½›“'O²gϲ²²èîî¾g?û† ÈÏÏgÆ ¬^½š¬¬,vìØÁ3Ï<p8þ<Ççý÷ß§®®ŽóçÏóøãKá7lÆŒ444ªÜ”%%%ÑÔÔÄœ9sX¼x±d’¸­ºººÈÊÊ"??ŸÃ‡³hÑ"²²²ÐétÊ#¨}çÀ>ø€êêj²²²¨««#++‹¬¬,¦Nª¤×ØØˆZÝÓf¼¹ÙŽÁ §¾¾½¾§]{{{Ðö¢#ꫦÎNtÜZšˆˆŒF§öâ÷:{7ÜŒÍØ Ö›oÂ_þ%äåÛ 3gÂï_ûšyñÀ)..&))‰ââb¢££žg{µZ-J`,„âþÖÖÖ†ÝnÇd2QQQA||<ÑÑÑ444ÐÒÒ‚Ùl–¥Ä=£¯¬1cÆ V«¨ªªF£Ñsðà§ŒHww7ÍÍÍÌŸ?ŸyófW{ÁQ#ôøØpð·a+~ïÕe6Ûà~Ù‰Ž†ÊJè𤾾§!º ÔÔT&Mš4h™Bñà0›ÍJ'ýpGGG+?P q/1™,¨T›ˆŠ²ÑÑÑEdd$¡¡atvºˆ‹‹'$dðã¾Ú[µ^¯‡£ªgbÁôžÿ}Ó`ñÜ«ÓB!„Bˆ{–Å¢aΜ½`õ bèv»yä‘)h4e½`½–koÝnøñù<444‘››§l¸¯‘cWW—)!Ä}C§Óaµöôîçt:éììLBñ@³ZÃq8®vÁ›”4žääq·3A 4ü~?aaaDFFbàĉSDGÛä¨!î‹•˜›òòr"##$S„B<ÐÆG[[+G+mm­DE¿ÿ×ÞŽÇÆÆa¡§VÄ0Š¢BÜ/|¾žQb½^¯d†B¨ÕŽÑh »Û}ãHcc3n÷Õ.µZí5k4._¾DWW4V«5øø B!„BˆûŽÏ磶¶žöövn<ù¬²SÜdŠ/œÁÕp¯üÙ³C®ßÓÚ¦¦fìv FcˆÒ°BÜt:UUÕtvv Óéå'„â×ÚÚFuu-jµŠ°0*•úÆúÚ*þçµßóüŸ}_ýäÿ±iÛN “}û>å‰'çäÉ<ÒÓS0›M¸\.Î+PŸÇÄÄP__OUU­•û@DD䠑ŵ¨®–ÞßÕÕu’ B!ðûÄjÚÚZñx<=†VËÌ™™7€ÄÄ%ÒÒXÏ·þì ~ößë5™Nª«kyÿý°X̸Ýãðz½´··JXXÅÅQ«ÕrDîqq±47×KFŒPUU ”!„B<÷‰>_´µµ)ãÞÜP¢ÕéøùëëyõŬǞB…¿7ʱP^~™ÇŸ«¬?nÜx|>/.— Ç‹^/7`÷¿4¸½n·FÍB!ăqŸØÕÕ‰Z­Â`0[Œ$©ô±ÂÃÛYÿÎ]øýx½°téâ ë—––¢Ñ¨±Z­r„B!„x@¸\.œÎ:;;o.1™Bñx\#Ú¨V«%#caa&|>mmíX­9÷ ³ÙBg§K2b„’“'ÈøB!„x`îµZ-¶7†0Ýxr}7\ãIN/Gà¾6C²@!„B(º4|½Í4B¼:TC¬;(q¹œÄÆÚ`È·!„B!ÄUEªKä{ hºÔÄÚ¸1Æ@Ê˪ñzeÔr!„B!ÄÈuŽsáÕõtTäñy(/«&D×3 ¹F£f|RBð¤ÿ!„B!„‰vm'xãŠÕ€˜LÑh4zÉÅ[ÄçóÐÖ&” !„Bˆû—¥9„èÊžŽ§¢<&ôZÝë @T* jµ–O>ù„©S§2jÔ(ÊÊÊHJJ X·±±ƒÁ€ÙlºüìÙ³Œ5 ›Í6âïK§­­ —Ë5¢÷ÛöPúïóÍhkk£°°™3gPUUÅÙ³gY²d €’qq1R"…B!îSÍÍ-ØíŽ€ycÇŽ¹-«ÕZT*MÀ<¯÷ÖôNªR©P«+!ü~>ßÈÆK²$’4)qdŸ#ØÌ;w’‘‘ÁÁƒq8¼ÿþû8p`ÐzEEETWWpàÀšššÈËËSæy½^ôúžÒÔÔDYYõõõ455)óêÛNuu5EEE\¹r…¼¼<.—‹¼¼Ÿ0fÌ>ýôS>ûì3¢¢¢(((Àãñ““ƒÉdâÂ… äææGnn.jµšÜÜ\L&ǧ  €ØØX*++ÑétqâÄ ÆǦM›ˆˆˆ`Ïž=L›6ÿøÿ ==Ó§O“šš°oeee477SYYITT[¶laÖ¬Yœ?ž÷ߟ™3g2yòd^{í5jjjøêW¿ŠßïÃåj“o§B!Ä}¨¬ü ?úÿ^!ÒË/ÿé»|í»¯0&.€üüºº\äç`µZxã?ðÙge\䡇&±mÛN""¬ÄÄD³aÃfvîÜ˨Qñ47ÛÙ¹sçÎåcµZ ·ö Z|¾« -›ˆŠêùAüòå ¶nÝÁùó„……’“sŠ””d>ùd7%%eœ8‘«¤·cÇΞͧ¶¶N>£'¿ÿj‡TMMWÓÿ÷ÿoÊË/SZZÎĉ© zŒÆ¢¢"ÈË;Ǿ}©¬¬¦¤¤LÙnJJr@^í>sœ:GsðÓ§O³fÍôz=ÝÝÝ„…… ™é/¼ðk×®Åh4²mÛ6***8tè@À ¼ÑhdÁ‚¬]»öjÄØ[1PCC555„……‘™™‰ÇãÁét’™™IBBíííDEE1eÊ ƒ)S¦E{{;eeeTTTžžŽÇã!33“I“&påÊl6111\¹r…ŠŠ FÕje̘1dff²téRΜ9ƒÛíæÀTTTpôèQ£FRòeòäÉÌ›7É“'°téRž}öYùF !„BÜçL+sŸXÊ_ÿùb~tÒ'+ËœÎ\®nZ[Ûðz½DDD°jÕJ<žžÇšæÏŸ‡ÓÙÀâÅO°`Á<&MJçäÉÓtw»©«kÑ~èõ:%ˆ ¥¹¹èyD¬¹¹…U«V²dÉÓ\Äãñ²jÕJž~ú‰θ¸XV­Z©ìo55µœ/^$55•3f(µÉÉÉœÔÑщÙltÿw;¸ÝêëkDFŠºîöí»éèè$""œ'žx|D¡Tcc.×ÕÄj5c2™x÷Ýõ¬^½rØT Š(,,ÂáheíÚÕËþîÿŹË%ƒ.µZ#¥éñû}tw;%#„B!Äãñxp»=T*ÕM§çõzGÔ¸Þï÷ÓÕåB§Ó¢Õjƒ Ú;êñ´ÊB!„â§Óiñz½·,=Ç3âí\¿0€ÔT7ãóùäh !„B!n µZÍè11Áþ îF­­ma„B!„w/FƒÉØ£®ö^ú[¶lèØd2¡VkimµËÑBˆ5j4ƒ^2b•••tw»$#„b„ÆO¢®®–ŽŽ«]õ&'O`òä´Û€ìܹ€Å‹Ÿ ˜ïp´²}ûn¼^/Ï<³ˆ .råJcÆŒ&##íÛw£Ñhxæ™EX­–AéFÂíX,ÂÃÃQ©ü\¼X¬ Î"„bx116|>·dÄ0:;;”¸„B />>«5 ¯×OccÓçÑ HCC#»víÃãñòè£3زeQQ‘Lš”N^ÞYL¦0Ün/¿ü­­müç¾Æ?ÿó?(¦¶¶nPºGçé§Ÿ 22‚wß]ÀêÕ+y÷Ýõ\¾\ÁêÕ+innáèÑã<óÌ¢Aï7™ÌŒ•€^¯ÇçóÊQB!„â.â÷ûQ«!66šŽŽàµÈAGB¯®îͰ à"--væÍ›V«¥¸ø3ÂÂÂXµj¥Ò’Ýb1+Á@t´±cGß–äóyihh ½½]Ž®B!„w©öö6ÊÊJG€455‚Á`À`00uêC˜LaTVV‘½žÎÎN §aøOú å½ |ôÑNœÈUF@üÏÿ|ÊÊj.|œ={½ž/}iéé)dg¯'==…/}iÙÙëÙ³ç ,¥££ƒîn7UUÕTTTÒÝ-!„Bq·èì줬ìuu ƒŸ÷4ápF: âí°sç~FNT¦=/--v¢££äh !Ä…†š¨®®’Œ†Ïç'22\2B!®ãúâpØ•q@ââ≌ìM=è@„#ñÒK+>·õôÓ ”‘ËË/SYY…Z MM=CÒët|>^¯ÔŒ!ÄP—ËEHˆQ2cx½=ƒgõ]_„Bô £³Ó0Ïb±0uêC½Sñ½çÏæ!;ò¸îD­V»ÎŋŤ§§]ÖÐЈ×ë%..vвC‡Žb0˜9óšššÙ±c+W~­V˾}Ÿb³E)®±± ¯×§ìStt šââ’!«{„âA7jÔ(<žnɈ!8Njkk%@Bˆ!Œ=»½…ÖÖ6œN'à'<¼'Ш®®Åd Ãb1söl>éé©$$Ä,±Ûœ:•Gt´””$.]ª ºº†9sfâtvpöl> ñL𔯱c'p:;˜?. QVv‰ôôT:::¸t©‚I“Ò”àcýú™>=sPrèÐQÆŽM[›“¼¼s\¸pQé!+>>–ŒŒt._® ¤¤”””dt:=V«“) ¿ß‡ËåÂårI"„Cðz½¸Ý€ ¥«« ·Û-ˆB Áï÷£×k‰‰±ÑÝm¥¹¹¥7ø¨áÊ•Jâãã8q"€?Þ¿ø, ñi­ÎØ»÷ f³‰¦¦fÊÊ.sìØ zh[·îdóæO0›M|òÉNòòÎRW×€Ùl⣶°oß!zh••U½'r•Jº‹™E‹ý0—/W2fÌhâãcuá[SSG\\,‘‘‘ʇÔjµÄÇÇjÄï÷IiB!„âñù¼hµjÀ@DD8&S6[=4‰´´¬V ƒÛÒ @&LHÂíöpåJÝÝÝ„……Cw·§³·ÛÃìÙ3éîvãr¹p»=Ì;€¸¸tºžvu:-‘‘Jºƒ•*p“‡çàru“”4–òòËTUÕ Š’FЧªª†ÆÆ&l¶žç‡ÒÒ2._®ÀápH)B!„âé«hhkë#$$„ØØ˜Þ¦1äåã¹ç–2è½AÁŠ‹‹!?¿€±cÇ`6›ðxª««äº!„ý„‡Gâ÷ûp8ìýîµõL™’AHHè€`Å´R@{'vtÆͼðÂsƒæ766“ý>ó7ß´ìÓORQQIFÆDG±sçBBŒ,Y²˜C‡ŽR_ßÀÃOcâÄÁÝýj4¢£mh4ZÂÃñZ-´¶:èìtbµZ¤ä!D¯qãñx\’C"µµUØl6É !„èÉ‚ÛíÁn·ÓÞÞŽN§Çh4¢R©ñz¯6¿(--#)iÜÈãÇOñÙge¨T*-ZHYÙ%’“ÇSQQÅÙ³ùètZT*/½ô"[¶l§µµ‡žÆ§ŸÁd Ãh42{ö 8„J¥Âçëùõèg?ûßûÞ7±XzÚjFTTðÚ•+W*•nxóó Y½z%%%eœ={žººeÙPˆÍÙÖûH–üz%„B!Ä­áG§ÓEddõõõÊüþµê'軃>äzôè ._®À`Ðã÷ûÙ¹s/Ó¦MF£Ñ°jÕJ|>?ííN¥ªúèÑㄆ†²jÕJ:;»8w.ŸgžYÄW¾ruäôüàûJð0gÎÌÛ–-‡ƒÎNyÎY!„BˆÛÁçóqéRyo§R#4™81­_€ ÂnoeÖ¬éœ9sžªªj²³×ãp8hnnVºÞÒëõ úÞ×:ÆË–-;X·îôzÐSÒÚÚ¦lgË–íœ>}†-[¶PPp‘¬¬?=]ïfg÷Ôp<ýôB²³×söìy¦LÉÀf‹";{=Ó¦Mú¡úÚªªª¡¬ìG+~¿Ô‚!„Bq+ÆÆ&>û¬ ¯×‹VÛóP•Ç㥻»[ùóù‚·1¶¬Þ}w=«W¯¼«3¥  ›-Z™îîîÆëõâ÷û •R#„½´Z--’Ax½>Ôju@ͽB<èBCM´´4+ÐÓ VTT8 ´µµ*óû&ì3â^°Z±â¹»>cÒÒ& Õê‚.»r¥‚ÖÖöàžlÐh4Rª†ÐÝíB*‘„¢††.É!„Pî›[ðù|´¶^­ÝP©T„„舊 '**|ø4®w£F£ñŽ|¸ÖÖ6¶mÛІäêÅ ‰C‡Žò¥/-`Ïž$%#)iUUÕœ9sž¥KM·¹¹“)L 8"#£p»»ñùÔÄÆJO'ÁÔÕÕÓÒÒ$šB!Ä.66£QGSSíí=?ê FBCÃÐhôøýW»ÝµÛí˜L# ½½ÝIaaáL˜Daa1íííLž<‰öv'UDDX±Ùlüö·¯óôÓO™9»ÝA{{;Z­–ÄÄQäåÃãñ0cÆÃÔÖÖQQQÅèÑ£Ðjµüîwo±dÉÓdfN °°8 G«-[¶ó•¯¬ ;ûV­z1`ÿvíÚË—¾´Œ?Ü„ÕjaÊ” λ€J¥âìÙó,Xð[¶ì`Ù²/ ¹é°Z-„‡‡>êêœø|j|>·”ª ::Úñù|€!„B<ðühµjbc£‰ŒŒÄnwÐÝÝÓõ®ßï èÚ½ººŠÔÔ ƒRÚý“Ova±˜ijj¦¸¸”ÒÒr,3Û¶íâÍ7ßA¯×³gÏ4 F£‹ÅŒJ¥bÇŽ½TUÕpðàa“ IDAT §ŠÏçcË–ìØ±ŸÏGII:£Ñ€ÙlR¶yäHNàGóƒZ­ÚxÜº\ÔÕ5ƒÅb¦¾¾ƒÁ@x¸‡£5h–!$$Ändð-!„B!n„N§!$ÄxÝ= @º»Ý¤¥¥0~üX<7ÑÑQ¤¥¥ÐÙÙEbâ(22Ò1C 1KZZ µµuÌ;›U«VrúôY._®àÌ™ó8­$%ëm-_ŠÕj!66–±cGS_ßÀäÉ“®¹£õõ ”—_V¦Ýn7z½Žˆ+v»§³ƒˆˆpº»Ý8„…olÞÕÕIII •Jµ‘B!„âú455SQQ¡Œù7RAÁš?.ÙÙ뉉‰fÁ‚ÇØµk/ÙÙëyúé'hhèé-¥ïÑ©e˾@vözž}ö Ê<€‡šÈgŸ•‘––Bt´ —ËEEE%S§NV¶ññÇ[yþù¥@Ϙ#³fMWÞÿôÓO½ž+–=…µ´Ø?~lÀ{5 ;vìaܸ±¤¦N@­V³{÷>ž}ö C~hƒÁ@w·›ªªÔj5z½Î8d­Éƒ®££•J%!„Bñ€óz}Ô×7ÐÚÚ†ßïG¯×÷ü µµu47_íYÑãñM㺻á½×ÕÔÔ3໋ÐÐPìv»”ª!X,f¥p !„Bˆ“J¥ÁíîF«Õô›§F«U4@憻á½×UUUSZZ®LkµZBCÃðûÁd2ݵûí÷û©«« Þ^!ÄÝÍj ÇçóÒÖÖÖﺣ#3sr@úwÚ¾}Ÿ¢×_ݾ^¯G¯7ÒÞ~o? 0úŽ\'p»»¥€ 9¯ 8¯…„„º ”ܶäÓO2ujV«uÈuòòÎQPp‘I“ÒßÈÉ9Iii9™™SILL`Ë–í„……ñ쳋9rä8••UÌž=‹ÅÌ®]ûˆˆgñâ'‡í©I§ÓŽZ­&""‹ÅLCC=>Ÿšøø»·Þ®.MMõ, !„¸»ÅÆÆc6‡ÐÕÕMK‹Ž'z½Pêêjyýõßóãÿà ¥}ìØ Ün?>'`¾Ûíæã·âv»Y±ây .ºÖ†……a³EöIHˆ‘¢¢bÌæØ{:¿SS“zà¹}H=ññ±RÀ…œ×œ×4^ïÕàüÒ¥KŒ;zdÈ©SyTTTâv{X´h!»víÃãñ™9…††&æÏŸËÁƒG˜2%£·w+/³gÏ ²²š††F =Z­–·¡Õj™?‰‰ üú×ÿÃ׿¾FéýêÂ…‹¬^½’wß]?(ùì³reÙéÓgY½z%%%eäæž¡¢¢JY°zõJŽ?EYÙeRR’®™iZ­–¨(‹I)BqÛùý~ qqÑx<6¥ó•èhIIãp:lݺS¹Ö^¸p±·³=+V,§­­7Þx›¿ýÛïÐÐЈÇãÅétÚÞž=xê©DFF\'û_kõz=ÑÑ1X,&@F™BÜšóšßïÃç»ZãárÿA h/X^¯—”” LŸžIee5ÅÅŸpúô9ÀOYÙ%êêê).þŒššÚÞeg©¨¨bÙ²/œÜsB]´è V­Zɇøú××(ƒ~^T*5N§Sé¯X!„¸SìÊÊŠ ×Ÿê꺀km{{;_ùÊ ººz.Þ&S_ÿúeýèhé7¼/Z­–ŽŽvº»]r`„·å¼v-ê¡ ’’ÆMttÏ£IÏ=÷ óçÏcãÆmLŸžIt´ ‹Å¬,ë{ߤI='Å-[¶“½ž z’_ÿúhk»ÚõíèÑ dg¯gôè .’•õGbblÊ{,èé•+/ï,“&¥cµšÉÎ^OFF:>:ƒììõTVV+é\‹ÛÝMWW'W®TP^~™ÎÎ.)=B!n«ææJKËéêr) 7ÉÉ9ÉÁƒ‡±XÌ×ZNÐû`[[;¿þõÿ(Ó |ðÁF8LAÁEþó?_£²²šÙ³g°sç>²³×³xñƒ®µÐÓ»¡ÓÙAYÙ%.]º"HqKÎk#õÀõ‚•Ÿ_HTÔÕ¶øý~¬Öìöæ»v¿½^_ï~Z¤Ä !Ä=Âd²ÐÔÔ3HnŸžÇŸ¢ðù<ŸÛ~>}Žøøxeº»»‡£U ‚îUCH@ ·KGGç=ŸWBÜŽóZmmv{‹2ßb±wµ÷Ù¶¬ÔÔ Æ Ëbb"¤T !„¸¥¬Ö±ƒæõFúó0yò¤€›‡û‰Íf•B'Äçt^3Å›Ñ$ž[Z<íDØÓì€èõºÏýÄ/„B|žt:­\ …·\ª‰Cžãó<.ÖNúòàÄçóa·;$ׄB!„7¤ÛâÔÂÜëñ*q†Ï绀€ G-¹&„B!„¸!>ƒ¿Ÿ~q†êj¢V«°ÙÌ’kB!„BˆÒ¦m‡ýkhu%ÎèƒoP•J…×ëE¥Rt8*•Fr^!„Bˆ¯Ó½Ô0Ïä ´Þ Ä£×Pר€ÑFHˆ£WÇHÂF‡Å’ 9/„B!Äh:‰Ly40¶ð¸hk«½vrÁ[D¾¥€¦²&žñ?ίÿÐÐBBÂhkkÅf‹Æf‹ >>ž¶¶V’’’˜6m²äºB!„âšµ<÷áÃã÷àñ{p{Ýø|^ôz‰‰‰˜L¡èt:bcc0›M$'Ãjµ+9)„B!„ÖˆÇÑëõ€ƒA@LL >Ÿ‹ÅŒÛ}ûFs={ö,S§N•#%„âšÜn7ÇŽ ..ŽÔÔTÉ!„¸ ª w˜1žTc>„¶1èµz¢¢ltw» ÅçóÑÒbçôé³”•]Âívß¶üÎw¾#GI!Äð4µš„„ºººøÅ/~!"„w©A5 i‘0ŽÖ` ³b2ë©®®ÅçóSVvIYG¯Ád !**€ÐÐÉI!„Ÿ+FÄ ðze„o!„¸§`ZZš0›MÊ´År}c†lÙ²£ÑÈ¢E‹æ{½^6oÞŒÏçã…^£!„B!„ 7gË–-Ìž=»ÝΧŸ~Êã?®,Û¼y3=öƒÞçñxäè!„B!Èõihh ::•JEaaaÀ²šš¶mÛFgg'O>ù$)))ʲ 6àr¹ä !„BqQßî L:•S§NQXX¨ï¼óV«•Å‹3mÚ4ìöÀQ¿üå/óñr„„B!„däyä ÑÑÑLœ8@ D^|ñENŸ>ËåbÆŒr4„B!„¸ÏiïÄF&O%ýÑG{†h×ëõ,Y²DŽ‚B!„µdB!„B!„÷…päÈ:::8pà€²ìüùó\¹r‡Ã¡¬——GMMMÐ4Oœ8Acc£d®BH"„B\µmÛ6ÆŒƒF£áðáÃlܸ‘1cÆðÁpüøqººº((( ²²’Í›7c³Ùؼy3T¦¦¦€4wíÚEhh(ûöí£³³S2Y!$B!z,]º«ÕJ]]óæÍ£««‹¤¤$ÚÚÚ¸pá3fÌ`üøñ\¾|·ÛMZZ”––’™™‰ÍfTÓQYYÉC=„ÑhÄétpøða²²²ÈÊÊbÆ ’ñBqÓJ!„¸]ZZZ8räË–-´Ìb±ÐÚÚŠÓé$,, ¯×‹F£Á`0ÐÑÑËåÂ`0PZZJrr2ƒ—Ë…ÇãA«í¹ŒÍ›7yóæPTTÄ/ùKÉ|!„äú¬[·Ž®®.9BBq+,,¤±±‘?üá<õÔSÌŸ?Ÿ¬¬,ž{î9ÂÃÃÙ¸q#QQQ,\¸NGvv6Ë—/Çh4²iÓ&F͸qãøøãyå•WX¾|9~ø!'N$<<\2Y!$¹5^zé%²²²ä( !Ä=jΜ9Ì™3'`^rr²òzÅŠÊ댌 222”é/ùËï{å•W0™L¬ZµJ2W!îQÒD!„B!ˆB!„B!„B!„D!îv~¿ŸÏ'!„B!„·_qq1?ÿùÏ%#„B<Ðd!Ä«o;µZF£!//Y³fqæÌ¦M›v[¶YZZz[ÓâNk­¨àÜ[o ¹¼úäIΟ¿fãžzЏÌLùÎw$C…D!îM.—‹ÆÆF, .— ›ÍÆÎ;IMMeüøñìܹ“ªª*l6QQQdee1kÖ,þíßþ÷ßÿ¶íÛéÓ§©««cñâÅr Ä]ÃërQ´qcðï“ÃÁÅ!F˜wÙíÔœ81âíøƒÌ;ûûߣÿÞ÷ä !ÈU&“«ÕªL Fââ≊ŠÀï÷£Ñè$'…Ÿ»¦¦&¢¢¢xçwX²d ¹¹¹¤¥¥±uëVæÎKUUUUUŒ?^ >ÊÉÉ¡ªªŠœœRRRˆŠŠº%ûæp8ðx<ÊôPÛ7®««‹uëÖQ[[+™q »zoô[¯\áÒž=ý"?žŽŽ€uUC¤1p¾&H€álø°˜L D¦¦2zÞ<4F#½ô½^ŽàÄo~ƒ½¬läÁsWÖ­»fÐË„¥K‰™<™i_ÿºdò½€ŒŸx•é¶¶6ÂÂ’Q«ý¸\.êëë‰ŽŽ¸%;tþüyNž<)GFq]7ž555ìß¿Ÿµk×âñxðz¯ž³ °Z­¨T*T*•ø|>ùùù¼ð ʺ}ÿÏ;Ç7¾ñ›Þ?ÇÃÁƒ•`¦°°‰'ʻŌF#k×®¥¨¨ˆ_þò—|~ø<|n77lÀåpŸ×å¢îôi%€P÷ (T½7ª~ÆÀâZÁEßÁ€J}µ‰éÊmÛ0ôþˆ‹yÔ()¬"({y9›V­¢áüyºÛÛÊ赂`U ¸ùô­eeœúïÿÆ`µR“›ËÜú',‰‰’éwsâv»éêr*ÓÝÝÞÛ¶C“'OfòäÉÊ´Œ„.„ÊX°`[·nEßûëéxûí·IOO§ºº€cÇŽa³ÙHKKãç?ÿ9 ;vìšé¿óÎ;·$yçw°ÙlÊô±cǘ8q" èt=5Èááár@Å-Q››KÎüö²2ª¸9SÓS[¡ê÷çpøúÝ´ 6FÍ™ƒ.4T™N|ì1¢RR”éq‹Ú¯¼ 1RÎÚZÚ««êevàʰ¿_ö÷¾¿¯ÆðpVnÝ @åÑ£¸NjN¢þܹAëö•wOw7Å}Pæƒ=’åï·Ü€H"„újRSS©®®¦ººš´´4 §­˜Óé$,,Œ×^{åË—M£©©iм­[·l^§Ó‰ÓéÄãñtÈq3º»»ihhP¦8€Õj½eÞÅý­lǶ|õ«8{ÜwÃÕÿ\o€n;–ñO>IÔ¤IŒ{â ÉTq×Iœ3€ñ‹]s=OWgß|€sï¼CÍÉ“A¿ ø> @„0ǃV«eÓ¦M,_¾œ?þ˜¨¨(fÍš…Ýn'<<œM›6¡R©(//§³³“°°0rss™:ujÏEÅïh|¾qãFÒÓÓ¶åõzñû_~6lØ€VxJôù|ø|>Μ9Ù3ghjjâ¹çž»®ÏÖ÷™FbãÆ¼üòËh4)bH¼÷Ì3CÞTõÿoŠ'ý…”` öÖ qWÜÌ<Òû«ýÒ%jNž ¨íŠßëÅïótš î Éq!ÄçÆétb·Ûyçw€žZˆ¾šˆ¦¦&š››),,Tz­jjj¢­­S§NM¯¸¸˜œœœÚ—¾}诤¤d؆êùVÍJ°ußzë-Ün·1¤`ãqôoÓ3mi/¾Èóï½Çsü#Oÿ÷3û•WˆÍÌ”àCÜ÷Z+*F¼nUN—{;.w8h”,BÜiï¿ÿ>©©©„††ÒØØÈ©S§¨­­%..ŽÒÒRþïÿþOYwÇŽÌ;W™v¹\TUU)cÝI»víB¯×³páB È>çõ:vìÏ?ÿ<·´-‹¸?øÜnJ6oº,uùræÿìgD$'£ ‘̤g³²h))¡6/oDµ e;wÊ#ˆ€!îWëׯgáÂ…Ô××sñâEœN§X¸\.qqqx<Ž?ðÞ;v°zõê›Úþͦ±cÇ:;;ùàƒ0›ÍAÑPúÊ4ýéÓ§+¯»»»%ƒä¾ö5CÔ~áµ×”Aþă§µ¢‚­_ýê-KÏ2z4ϾõÖ=—º°0ýÁøxåJ€aƒ²;xâ¿$ˆâ~pìØ1RRR°Ùl466’››Ë¨ÞÈ:zG[~ûí·YºtiÀû‚ÍëË®Žv~½ú§q-ííítuu]óýo¿ý6jµšG}tÈtŠ‹‹9vìØ5×éû<Ó¯®®7D€Ëû÷sàÿqÈå| ­á¼A¾×׫¹¤„ŠC‡®ë=CÝøæ¯[‡'È>©®#Í€ngý~¼.× õT×±¯c¾¨T½÷Þµ×¹F:c{ŒÈÞ1bªûõd¥5Éxé%eý°ØXR—/'¦·=ßÍJáR–-£dË–aƒÖ+WpÙíd,& @Ö­[ô&@q÷r»Ý¨T*ÚÚÚØ·o………üùŸÿ9›{Ù¸q#Ï>û¬²~ÿãך×ߦM›nªKÜáœ={Véêw(^¯—üü|fÍš…zˆÆ‹.\Àçó »½k5R/(( ¨¨ˆeË– j /‚Üôøý8N%À½ŸœyóMö¾ò îë¨U»«ÏNgÐÎ t!!¨4¼nwÀÍtÃùóìøÖ·nø¦¿éâE<nÎGr³¯á:×»?}ÓšëLÓõúº_¾Ñ€H5ø ׸jäñþûX³{7Õ»w+ÓšÞå¾®.ξöZ@Û¥Ãÿò/Dgd°rÛ6 ½½ jôz4½ƒÌ^WЧVóÂGqò7¿aïßý²_ý·¾ýì²Û)ß»—ô^“èÝ€444ÐØxµ»ÈÑ£ÇÜö{©72–‘Ð…¸7ìß¿Ÿ“'O’žžNZZeeeÄÇÇóóŸÿ\©ùhnn4*ø½*''¯×Ë7¿ùÍ!—ߊm466òÉ'Ÿ\wï[¢îîn>ùä“×vÝ+.íÛÇž¿ý[ºÛÚîŠý©8|8 ê#Z}ò$õçÏzÏÀã¢M›ýZ0î‰'µÙh¼x1`ÜU›íë Ô€þƒÿ¶{=ݺWƒà&Í›ÙÖpù¦ òz¸|8O=LþûÖ7>Ïã¡éìY^KLTƨ‰JO'zÊå½S×®eô¼y膶Ëngßßÿ=¥Ÿ|rÍòÓ·Ýó7Dgd5 ×Dñ9 MM ˜LW¶Õj‘œâ6iooÇd2 z}·innæÕW_åïÿþï±Z­”——+ËNŸ>­¼Þ¹sç ‹÷Þ{þçn¬¡öHuvv[£r3ÊË˹xñ"cÆŒ!44T™ßÑÑqÓÛ=}ú4?ü°|!®ƒÁ``åÊ•q>ÈMð½*ïw¿»fð¡Öéxòßÿ}Äéy\.œ55ƒæozé%W®½!ï?Út{]þÞžéŽJ­ºÆkÀ±⦺vß>eÚ8àæ¹ïlÿuÜûo ¸žõ-£G£ ÒmöHQê3ñ…”_ýo$ÐÿÔSXÆÜØÃ­W®P¾gϰÁœrî/.æÊáÃÃ2}Ë]]--ƒdªû½Ö øÌ¾~yÞzñ"ö‹•ù…ë×˲wÞ!éé§i¯©ÈîøÖ·¨ÍÍ¥£¡Uoúý÷§ÿñT÷¾n«ªbÓªU¬ÍÍ•éÝ€!n½ÖÖV ˜={6¥¥¥3wî\^ýuV¬XArr2ëׯgþüù$''“““äI“°X,”––’œœ|Ç÷¹¢¢‚Ó§O³|ùr>ùäZZZ())aûöíÊ(ÞÛ·oÇb¹öý‘qÞÆGJvïÞÍèÑ£okžüö·¿å_þå_”ÄápðꫯÒÒÒrSéž9s& Ù¾};©©©ŸËqŸWk+Û¿ùM ׯ¿æzI‹1ã{ß º¬*'‡–ÒRZ¯\áRïMf·ÃAMnn@í€j@1pTu_¿i3ƒG[W3ü@ˆýñö ˜fÀ<¿y D®w ¹”eË09/Ýì€t_xýuôfó=]ÎÌ£F1j˜¶j7ã³­[)èmKR¾k½°ª¯ñ§êW¼ýÊŒpÖÕ±ïïþŽœ_ü‚ÚÜ\\Ç r¨ê䪂8ÁÊš).NN:€qïñx<´··+cVØl6vïÞMll,yyy¤¤¤0gÎ~ýë_“ššJJJ o¼ñ³gÏæàÁƒ@Ï`xÅÅÅ ueÿ~š/^Tnì4½ÿͽ7ÚÞyš~¯û¯Ë…oÀÍœoÀMâPÓ}7”¿!È !À¿ü%ºÞZ`ÑÈCý._µ^J¥’‚õ9˜ðì³Lèmûçu»9ûæ›”ïÞMñÇãxô/ƒÚ eP)çÎÑ„3¸VE5 |yàîýO¿29¥·v~ÜSO‘þ¥/ÉÁ’DÜˆŽŽt:€òÿAáv»ÑétÊǃF£ÁãñÌïûß?hÐh4A/LýßÓ—§.\ 55•mÛ¶ñüóÏsáÂJJJ7n‡êêjå†síÚµäåå1aÂ</^dÆŒx<JJJp8@OÃì>/^z~ý®ªªbéÒ¥\ºt‰3gΰyófÒÒÒ°ÛíÔÖÖrá¼^¯’†×ëU|Ûl6Nœ8Á×¾ö5~úÓŸò—ù—L˜0­[·ðüóÏÓÙÙÉ‘#G˜;w.!½ãôÿÜ}i¥¥¥±wï^V¬X¡ìGŸ .(¯7nÜHttôu»¾ýÿÚ×¾6â÷ôåÓµŽ8­áá§êË÷5kÖ DpóæÍ×Ý~£oä÷³gÏ0mÚ4åØˆàÇŒÎN>\¾œ+Ÿ~:¢õOüæ7ägg÷Ü y<4¡ý ]ßtߺ ¸Éóö»Q뻉ø:XÀÑ?°Ð†„ ÖjéßCßãB}ÆÀ‘ú³Mš„Z:`¸oht:þÖ·H_±‚Ç~ò\7làäo«Ô´iú•O퀲ª°\3 €¡_Ùu÷þu]½ݽóè-Ãç³²ðç²²8Ò[ÖæþÓ?1ñÅå`I"Fêé§ŸVžµ¿½µµµ±wï^¦OŸNbb"EEE˜Íf|>‰‰‰TVV’˜˜ÈþýûÉÈÈ@§ÓQUUÅC=ÄþýûY¸p¡ò???ŸñãÇSXXHZZšrSnµZ)**"!!¶¶6ª««•÷¥¥¥QXXHbb"'OždÁ‚ìÚµ‹µk×ò_ÿõ_¤¦¦â÷û;v,¹¹¹¬]»–×^{ &PQQÁ7¿ùMöï߯|–9sæ(Ï‹÷mcæÌ™üïÿþ/ßÿþ÷ùãÿ¨äéñãÇyçw0›ÍíòóóY¸p!'OžÄf³a6›ùÑ~„ÙlfÛ¶m¤¥¥a³Ù”´òóó•|jnn”ÇN§“O?ý”¥K—âr¹” ¡¿ýû÷S^^ŽÍfc×®]„……1qâDåxØl6š››Ù¿?ÍÍÍ455‘­ìßþýû‰ŒŒäOú---¼øâ‹ìß¿ŸsçÎ1wî\ÎõkzäÈZ[[ƒ–‡þcv477_wÒ÷¾ûANN%%%·-ý?þñüÕ_ý•RvÄ}úƒŠÓyÍà#25•Ñóæáíê"Ý::kj誩Qj2Ì×8´ÖhøzoÄúþ¼ýþ< ~üeà3ú}z³™%¿ÿ}@0zî\éX Mhïµbôcqò·¿Uóc@9Óõ+‡}ÓýÛ ¬9é„ôÕ|èéy$«põþu(óÍø€“¿ý­ €ˆátttP]]~@7um€u„ IDATmm˜oás©m½ ·mÛÆìÙ³yë­·8yò$O>ù$ƒÜÜ\6mÚÄüùó1¬]»–ÜÜ\>üðC^zé%²²²øÎw¾Ã‡~ÈÂ… Ù³g&“‰ÿýßÿe̘1dff’““£ûì3$&&"$$D²|ýõ×NÏÑÕ~%Ã5Œ9ÇŽÃñãÇ‘žžn'~—qs`÷³Ïо³Y… ÑTX(ĹÓ!Tô‹d$$Å !F†t˜ÄÇ …̓A…=Ñ¡Q Ó§#=s |åz]ÄÃyy(Þ²wíBSi)Z+*`Ôé ‡X›D‡d±Bvºß“Ï ŠÌ°D› ´ ÑÑò ‘ ˆŒÎ°k×.»º999hllÄ‚ </þí·ß Ÿ¿á‘&“ _}õ222pâÄ èt:´´´ÀËË çÏŸ‡ÅbN§ÃùóçØÂŠNœ8íÛ·Ãd2Á`0dƒ¼ÓD§Ó¡¨¨HX^__ššáûO<éÓ§.\¸€C‡I¶½¤¤Ddè¾ôÒKÈÈÈÚwõêU”••!..o¼ñfÏž-cõêÕ Cÿþýíj    'N”ã_~Pyìô|DľW^Á圀'̃–.ňßüFDÊÏ~ý5N|ò‰0&4̸ $Ü i_<•El _A]Æ-J@òòò1¯ {ìܹƒ ’\V[[ £Ñˆ7Þxo¼ñF—BböíÛ‡’’§Õ§'OžŒ§Ÿ~ZôÛÖ­[ñ,XT0éM&“(cÐçŸ.«£·mnnÆÑ£G1€ÏÓ}ìØ1€ÐÛ°(,,}ÎÍͶÜÜ\ihhhµåøƒ°­3A±³e与HCVV¬V«S’••å–±™••…ñãÇ;¼îŽî7ÝÆ}ûö‰Hnn.RRRìÎÛºM&“è~ô4\¹FÎ@÷%O$ ‰¨ŸŸÂÂÂÜî2z/šÊÊÐRY‰§§Ãb2Ù¥²eë,($ + o Ñbo3Ä¡S!Bíç'ºir3`Ñ"x‡†‚S(ä"ãº"ŠÊxÿÏ?ÃJuU(•¢ÔÇE›6áþؼ}V†¨2O<)ä3 l×.aÜœüì3x‡…ᡜ¡Š» Ï£×>e¼¼¼ÜÎØs«À`0à›o¾Á‡~èt½üü|lÞ¼Y$v¿üò ~þùg\¼xyyyD¶}U“&ÞÀ&¸Ý½{·ðÝ•êÑ,ØmèýÓ°Z­vÕwiAsCCƒˆôÐû•Ú–ÆÊ•+.³Z­N+^»"ªv øù矅ï7nìò¾èmóóóEtvß/\¸€ööv‡ûc×ïì<ö9ˆ…ïN¿î)xú>’g¡ŽªF\YY)"eßt’¢Õ•1(ãÚÁb2AßÔ„3k×âÐûïãˉñ¯¡C‘9j¾;V“ÉajRÚÛ¡¤H ÜêaÚ¶hãß J%¸€ô[¸£þßÿÃ’­[±âÐ!<¸oFüö·I½|ÂÃeò!£÷ª*•P]©ÑØÕ]©/.†Õlî4 4 ×"ú( Äá[œÕжš|6z4v=õ,=XKJ& ½Djjª|‡üûßÿÆ›o¾i÷û¾x“öïߪª*·Ž³gÏìÚµKHµª×ë%Ãm._¾l÷}Íš5¶]‡ˆ³=ææf<ùä“NÛÙU8ÛOwë>9rÄcš“É„¦¦&áÚw¥måååÈÏ϶uõž>}ºÛµ=\9-~ïÊö7 þö·¿¹=¶àí·ßîÂ$Ã1̲ÿ÷ñ×À@üpÿýØýÔS¸’ºS§ ¯©¥Â%ÆuŠõfÐiFÙT£dýq/¾ˆg±pÃLï=%&Ê7BÆM…Ô_ý }ÒÒìR;;«;#µœþƒ­Ï¡÷ßGù/¿ÈùV" 2¤ñÉ'ŸàÇ´ûýÒ¥K’ë>|yyyxõÕW]Î4ÔÜÜŒK—.aݺu"ƒXÊ8fÛâNÛþøÇ?Jþ^RRâ0LÇ• Óz½^T£ÂQ»“38Ú+×Ôƒ_ÏTt%XçB-)Ð×ÞÝ}477‹4,ÎÎý¨‡«Çvõ:»»½;÷ßÕsôññqYCëžÜ6fÍf(©™@WÏ…ô ru:ÝM“ÞW§Ó!336lè•íÛþÈ#È~õUöÅþØÂ~äšž±%žv=¶~í§í¿h‘üÇ)㦆wh(,\èT°!‰V†´âÎ’Á&¡¢ dÈä–Buu5öîÝ‹^„EÿÙ–••9ÝÖ`0Àd2A§ÓaíÚµ¨®®îôx«W¯­·mÛ66Á0+l|ù²Èð%Çl¢ûîzh¸sNt;Ü]‡ˆ­¥–Ÿ>}ºÓû(Òä¬ÝRÇqÕ]zRhll´ë»žBwû£;"xgçè*aÛÛR__ààà. K¬.\¸€²²2‡øFÉÀ·¨—ÝWøgç€@£Z-=ôBÖw”á û"ïÁIIˆ6Lþ•qӣߜ9¢±ÄÊ´2¤ž„`iù—Ä)«i’Ÿõò˨÷ í#C& 7jjjPTT„5kÖØeTjiiÁ±cÇ\ÞW^^žÓ999ÈÉÉAEE…h½ÊÊJáó> cyôñ]½fξ³põœœµƒصUjyccc—²I9k·»×L Ÿþy—·%×£¹¹Y”2ØÓDäZ÷Çî¶¿'Û{àÀlÞ¼Ùáò_|555Â}%Úò=//;w×Î*‰›õzœY»µçΉfbYâB~“ª q“&É[Æ-à¤$Œé%øFG‹²¾Ñc‹5~¥ÒW³ ÈxÛÒƒµÕnUÈix{1H¾ÿþýû@·f'7n܈{î¹§OŸ†ŸŸRSS¡àņ---Ðh48xð òòòÐÇE£ ƒ¨6 ¼Z­V‡á7nįýën›agΜÁwÜáÔ(ó nˆ>µqãF<ÿüó.­Û•dôõ Å KJJ0ŒŸ…u÷:yB(M÷Åï¾ûÎaö8wΫ+íkhh@BBB—³z±cŠErr²Ó$ IIIؼy³p_ãããQRR"ºÏùùùX°`ð¼ÑóDââÈgôk­ªBñÖ­#F§+> c”ÚûâŠ-¦flm…™y–³ä(Ã!•ª#”eg£ŽÊTè±'¢ÿÂ…ˆŸt(úŒm{†Í›‡& £`ÌzyáŽ×^ƒÙhÄ/o¿-òJt)ý¢Å>I+EþúõH¹ë.¹ÿÉä&ŒêëëñÄOˆÒŲÂmw@–:„C‡aÙ²eB ÛY³faÆŒðööFSSS§Äïš5kìÚ>eÊ\½zÕa˜’ThšäLh/…ƒâŽ;î¸áû!¬»p¾ÖÚÚjÒÓÐ>/Õ=•ÒwÏž=˜:u*Ö¬YƒôôtQu”’Ød2A¥Ryäúcžx3>ø@î87 N}ù%v=õÚ¯^µ#°P{æ έ[+€]Ï<ƒþ âοý þ}ûJî¯d÷nÉ"…Jf Y Ö_IõuºoÛÚðÝ’%è;n–íÜ  =ËDF¯@uu5Ìf3>Ü£Çùé§Ÿ V«1tèPá{ß¾}ÑÚÚÚ©ÈûǼ2Ë]ÙöܹsÐëõBˆ)Jx½àÊu¡ÑÔÔät¹;¢mg錛ššÜªÁáŒTž={V4»=¯Fh4š^™.ÖQb…Ÿ~ú #FŒðøñÎ;'T­ï ë֭òeË„ïYYY˜0aB§ÛÕÕÕ!$$DHVÐÔÔ„üãx•MËè¼õêù¢¬4|ÂÃ1t(,f3®æç£ÏX(•†—“ RY}Æ=ÿ<’çÍâÖ«OBÅáÃàmÝŠ6þ,iÐ]½ ðiÕ‰ñF¯Guj¡Ôwìõ`‡Ò1úlaDú;ǬÛè`ìɸ±`5›‘õÊ+8ü·¿ÁØÚj×õ™‚テOx8¼CBPqø0jNõW]M ¼`¯•RP—ÎtE|V´.•=«üÀ¬9—,Á°Œ pJ¥œYN& 7^xáÍrΙ3ÿûß1‡g±x÷ÝwEç‰'PPP€øøxlÛ¶ÍávÝ1r]­ ^TT„ôôt€¡¬§PTT$šíß¶mPVVfG¶mÛ†Ûn»Í-ñûúõë.wUÐìÊqžxâ‰NEìŽÀV:ï)ìÞ½ñññnmsáÂ$&&º¶ÕýÕ455u+d­3ºLÙdï¾û.óbfg°X,P(¢í=ÕOouœß¶ {„>úFE¡¹¼úÆF´UUÙ…[±ä a_)wߢ͛±ë©§Dd€ßÒ/ :ê‹#lÆ-¥Á`Ûb…}X y!s1B\•š% ŽÒ¦*µZŒøíoåu@W_Ü7Þôø±ýŸ%±e,l±ŽƒNÎ@ú޶š8:Øj嘘ã@¢ï±$ܶh,.Æ/o¼o¼N­F̸qX²i´ò½ÈÚµkEÅ·nvTVVŠª{QQQ]#{BÄüÙgŸ9-ÎçhWЙ°¼3ìß¿_Tñ»²²MMM’bðÊÊJÜvÛm×´?äää ¶¶Ö¥¢}---ÈËËC||¼Ë©XI–3¶ÒyOœ‡;¨¯¯ïRJXwû«N§sz­ŒF£[„³»Ô»ƒñãÇ‹®sNNŽÓIŒaƹL,Hö¶¶6DDDÈÿ˜]€©½?¿ø¢ãÉÍ›ãJªð «ûìEëôlî…Í›¡°Z¡EG¦ ÿòàÍ¿“—ÄÅØŒG“Rc„|6P¿ÑŸMé"ލ÷ÈaàôöÎ9<5³ÿùO»"t2n|pTÿ¥û+é³Zþ³–ú¬¡>«9@ÉuT;“Ð[;Šr6håIé»lýÚóÁzc”TßyHŒF”íÛ‡÷BC‘4w.|"#1`Ñ"Œ„,‡kÝhdùòå€ÌÌÌ^Ó&½^­Vëñý~ÿý÷HHHŠ·ÝŠÏŸ?/Ìh÷íÛW$↠b NŸ>!C†¸µ Ia9»/À&:î ´··ã¼D8…§@fý]½€-TëäÉ“.­»eË–krÜïÛ·ˆV=ήUccãuÉøÖôïß_tÉçW^yE’ˆñ¹+ ™²¶lÙrÍô'7KKQÅ>:¾¼ÿÝwÃ+0•‡ãê©S"Oëy †=+¬ È‹€Ælj¾ÙÐò„ž-eL颡£ˆ…ÑÃÔ Á íõ ÁЕ+íHFHJ b„'%Aé$邌ÜøôöFp¿~h8ÞN(ΦÍUñ}×—ùð/oÐ(…àxGؼ°‹ЛFž„´ðD¤…êß„@k í a¡„}¡ÕlÆÅM›`pò_ÿÎeôï!<€ˆ¡C¡¢µ 9Ë)ÊÊÊ+¼¿òÊ+xòÉ'‘ŸŸiÓ¦áÅ_Ä믿.,ÏÉÉéR ýgŸ}†gŸ}V¯Y³wÝu—ÐwôÛ·o‡F£ÁîÝ»qß}÷uº~WÎgΜAZZ !!—.]Bhh¨Ûû9tèiè*¤öå)Ñ1‹ÖÖVœ9s¦KZ˜Þrêêêº]ż§®7[HsÀ€ÈÎΖTP^^î‘ÉŒÖÖVüðCüßÿý®^½Š––œ9s“'OfHW®\‰]»vá¹çžCvv6>úè#Ü{ï½xê©§ðÊ+¯†Ó…  & //‹!!!Âñ¥f%úé' 6 áá᫃À‘#G0eÊìØ±ãÇÇ)^˜ÕJJJ<"bv× ñõõEmm-¼½½{´@^O£¸¸‡rkZ ~äÈŒæS vž¸~¤^[[Î;çR–³kË—/ãܹs¢ßBCC]Öy ¾¾¾½’ Ñ =lµôÎÖ§±sçNÌš5 —/_†‰&“ì_2\CKy9 ­­÷ÜsINÆ7Þ€±±Ñ®þ€’2¬ØJçtMe(‘°Q( µ+lñîm{- {9 § µHå¨}|ï„TêS¥V+ǼËèÞ{/ú/ZÝÕ«¢tÌí558øî»¢ÄRIh-’‚!á>°yK!!D ~œ=íõ03ÄÌŒA0ÇVH´ƒš°×œ:…œ×^Ãâ~o¼L@lBääädlÛ¶ Ó¦MÃSO=…üãø¯ÿú/L:111(..¶ ÕØ½{7æÍ›‡eË–aëÖ­vZ•5kÖ`ñâÅhhh€ÙlÆ÷ßÔÔTÔÕÕaݺuÀW_}…Å‹»”ˆd§q†“'OâÉ'ŸÄŽ;zýuß½{7222™™‰‘#GºULQ ÙÙÙ×$lG f³ÙN³PZZ*À­[·bîܹ¢å´@ýäÉ“Ý" ]¹~tûXÒœ:u ¥¥¥.­ÛØØxCz/¦M›æÑ´È=˜˜\¾|©©©Ø·o_§©•Éú,ôz=ü™Øå?üÆ¥¬Z×z½ëÖ­»®šh­®Æ·Þ©/¾°e–BÇ *=ƒ«xvבÇÃÀKF~9!´gCÇ¿Ìk1h‚Áj/è¨a+VÀ [M’ /¿,×:qM P*áþ  ¿™ÚÛ‘|÷ÝìkÉøFF"™ÿOm,-Å< "ä$\‹h?h ‰’"*Š0˜aŸš—¬G{3ÌÔxaSNKÁÊì§±¬ &½ªå— H/F{{;ÊËË_~ù3fÌ@FFöïß×_cÇŽ…ŸŸŸä¶III(æÓF¨ÕjTTT`øðá¢Økz½M›6aùòå8~ü8üýýÑÞÞo>þ¯­­M˜÷¤ÆåZe4êMÈÌÌDzzºÛÂåââb‘pyåʕ𵵵ny‰ÚÛÛ…û[ŧ»tD Ø´.+W®t¹Ÿ¸"ü§ÛçI455¹ì1=ê½(..ÆèÑ£ÝÖ DDDˆ®ÿŒ€€§^Ó®àöÛo· …ëMÐjµx衇PPP€wÞy纵£¾¨‡¨\ÄaU*Šˆå$ôÃJ;Êè!ëC‹Sìì­‘z‘Ù\•Ÿ¦¿÷¬°só•H(À)²E$£w¦ÞÞˆ8„w)„76bèŠ8ùù碱Š8˜ öœßÚ)Òn¸Ör¡€XŸ2xùrD ¿?²^ym¼-ÁzeXÍSU^ŒÍÍ2¡ÈßM‰¦¦&èõzìß¿{öìAii)^ýuœüo´ADh¤kjÈq3#ýÅ5j”ˆx™!üÄëØ ›·±Àeejaó6±º?êEÆÑnmX°ÿ™3'V¯Fp¿~&‘)-ÚyòóÏaºïx7Œ¤´´HMMÅgŸ}†Q£F¡­­ íííP«Õ˜'97×=µv-L.>S(}+äÕS7iî\øv#|<¸_?,۱ cCGÒNb!º†:2ÖèÌYD›Å†8 5q,l_µJt=8‰wb•Öž;‡M>ˆ…T2™€ô2JèUUUøßÿý_”••aÒ¤I(++ÃÊ•+±cÇDEE é!é?ÙÊÊJ‡UÀ DµöïߌŒ ‘· 22ÕÕÕˆˆˆpÉsâ*Ü3÷ˆž…m©žÜ™h·7iLnûîiA°+òäy¬ˆ¿+Ø´i“ Ídff:]¿¹¹~~~' 7Š‹‹1iÒ$Ia?! Ý}Žcøðá"oXaa!QZZЏ¸¸[~¬_øé'Ô †[?€ÉB‚˜)B×ó ÉM<¤ ÆN˜€y’kô6\=wí ꊊz„Dã°±´»à9u… pë—x~q.îËÑq9Ží qù%'GÒ{fu@>¬]$$f›¤yóà•—†,_.¹Ÿ>cÇ:ÍÌæ†ä PÌtôRRăNum¦Æ;æ8jœ/ û¢?X%®9-dÏß°ù6`À¢E2é +¡?öØcÐh4hooÇ¿þõ/Ì™3›6mB@@ZZZ„m²³³ñßÿýßxï½÷0uêT· $ƒÁ _uuîܹÈÌÌĪU«°oß><üðÃÎÙ{RŠŠŠ\*ÄG«Øí‹‹‹¯;9qtJY“Éä²7$55ÕåÚ$îÀb±¸,8µZ­P("YW@¼d=©Ãp„©S§bÛ¶m.¯_ZZŠéˆÿV(¢¾{­B®dtÞ5T‹ž8q"²³³±`Á‚.ƒŒö Ê´ IDATs"ìgÃñÝâ¢4Ô>>P¨Õ°òÉh=Ò“5âèßiBÂÖ ¡SôÒµ=èºfœFƒ Ï=‡‘>Ú³uu8ñé§.ê­ÕÕ(’Hò Ðtå --¢YcG´ÕM£ß‘Ï90íGªMœƒ}Hý3¹Ø>wÈ…+íQ¸Hž:»Î®‹ƒålØ!!å[¶ßOÿßÿÙéž 8) œR‰a¶j¼%&TBSRPÄt2V ÌïJtdÄÒ¡£2º@lZ?ØB®¼)ÂB{DùhCG1O=ÄÚ³"´5#}ÆŒAÀ-(--Ÿqã°~ýzŒ3Æn¿—.]BBB‚Ýïtˆ1‰ûöí‹£GJî§«8tè222ºœútìØ±ÈÍÍfA !qF@üq¼ýöÛ.Œëa»c@Ïž=¹¹¹.­ß·o_ 8999×´¤ÿ9K>pÿý÷»œ…ëþûïw» ®zwÆŒƒÃ‡ËV'…Îî]O"  Ól^—.]Â!Cºô¼%:¹³gÏbñâÅðõõEŠD…ì['¿øWrs‘¿aÚ¯^µ3à-Ï ³zâå 1èÞQ@:ìŠö|к’½{ÑTVðÆY}a!8¦¶6˜ÚÛ%CÄhƒSÁ)bB ©0H§µ@ZãBÏ+Æ öp\[Á‘¡mubÜ»K๰:YÞ¡è¬VŽM ñóC@LŒKm ¯iý… 0óžmG䑃´wEÊ£$EJX=”Šù® ¸J‚`›²R¾m®lÛ&Ú7ÙG€Y§û"ÇÒŸé¢-<ñ 5B¼ ®á£aȈŠ9&}>JthRè{6¤ ÿÍ2éeP*•ÂçÔÔTÁpŽˆˆÀÃ?ŒÀÀ@x{{C§ÓaÑ¢EÈÈÈÀƒ>ˆ¢¢"a»¡C‡âµ×^Ðy×ÒÒR¬Zµ ë֭ ìꂸ‚Σ7"ȵ¿ ´,®@$„èZÃËË ñññ.Òÿœ±Z7Ši»Pð¨³Ä ô=¿m<¶š/=…¾}ûâÊ•+.…cö:Ób\¹r3gÎtÙ“:aÂ|úé§xöÙg…ßŠŠŠ””tC„Œ^ ´VU!÷7púË/¡««Ä­œ„OCôì«âPò"Æ‘3ª´!FJIAì„ 8·aŠ6n‰o•¹a«¯Ó±î*†„°m—"A$Œ…õÆÐºPÛÒäÆJ}'ûudà:" ©ß8ê9Й‘ïဠmIþy$Í›×åíÁ;$¡¸Ý+óòœfeêìiY–½Ï?ß麱µZE)m•`½#¤_‘m½˜þKV2ãNŠÓ“,yRQëúðûóBGMV¾?+%Æ]—‡£ˆ¶U‚è“þ~ðÝwqµ 3Þ_& 7"ø,ééél¡D3gÎ ¯ÜYZÐ~üøq >ëÖ­³ ^>¬Éô¯ÅÅÅx饗°zõj‡áCî„ õ&`üøñ]òÐõOœ!** III¨ªªÂ„ zõõðóóõ—¢¢"Œ;Vð]+Q¿;boT¢e×ÛÏ„qtÖ&wÐÕkE§¤®­­½æäÀQBŒž@^^ž}öYìß¿‹-ÂÆ»µ?©0DÆ)ƒ' ÕÕÈûäÁ³@‡ ©(Ä­„NHM@¼`_`„uÐØvþe¦ÈLka! …ô¡´‘Æ†Ž¨ žVH$’Ê”ž…¦««“ïR¸ÌŒ±gaˆˆWH êR¥ÄéÓ»ºœœŒØ^þßqÍžO#FtoÒ%=·SΠolÄ–‡Fᆠvž 6ÔŽ.ÚI+ EÖé"‚ˆEãtd®jР‰µðÛùÁ–ÞZ+A$èÊèl6+MBtuuhkjÂ&é1ÅAœùŠLК–ÆâbþàøEE!í™gœ ìerƒžœ;w.ÚÚÚ°hÑ"$&& $Ť·ÇŽßþô'á»+©:ƒƒƒ1uêT¼ýöÛHNNFJJŠC‚‘gŸ}Ö.Ý) ‹Å‚ÊÊJ§^©YÚ^—Z455õš¤rõ4Üá’ìjtìíHv1Mrr²[Ä]Ü×ÊÕçGO£¨¨ÉÉÉØ³g}ôQ†>ùä“ðññéu×9;;[x^^ËšD©©ÿÒK8üÁ0¶¶ÂÔÖ&Ì|ƒ›&!4Ùð¦Œb¸Ò¡‡8ŽœºÒéE9†`Ð^¶^1ìô11„‚ wqTUZðäxyAãïoWQ`ТEÐÚ°AƒúÐC²õ‹AˆEë×cïóÏ#Ãè¡»z&‹Å.U5yÑÞð}!ou@®•TWòDC ›ÖƒäNURãDI‘e0ÈÄ }K‹-==ì=‚jØg»cÏ‹ÆÞ^À¹o¿Å’M›àï†'>>>xˆø‘ Wä.`ę̀ïJzS¥RÙ©—dàÀØ·o_§a"DSSNœ8ææf·ô& Çòå˯¹Æ¡§/º+W®`ذavdÔ^¥3f^ wCðz;¦OŸŽ¶¶6ùßÒïFo G¢x²0' ¼Ö…>]Å„ hAAËú5Oàö?þáƒãÊ8ðöÛ‚æöd yOèøq– )c‹2ëêM‘ÚP#FŽ"l%vÉP)·Í™#fä(¤ ¥—ÄÅ!’yÎÊá SÞ|SÞ|paçNÔœ>²ìla9é¿…ßïPÄ&& 3Æ•–tö*=5îH±O_tx@èdì½yíµµˆGäˆ(Ùµ æ–A`ÎQÇEBqx˜‚Ú§ÊË êH—/+W®a~Ö¬YðóóÃìÙ³†lÜÿýP©Tð÷÷Gxx8––†òòrÌš5 ƒA¨;Bô $êý÷ß>ø@´?òÐY˜HHHH·ÓÉ2v=´=…iÓ¦áèÑ£¯éÓ§ãØ±c êÖqbcc{ìÆŒÓeb(•XA AAAhhh\‡üüüërÿº*lw7É€§0vìXdffº,ìnkk³óHýÖгkÅzVI:_’|@£ÑØe[ó$™¹ÐVSƒ­«Várv6¬V+ôõõ‚ñÁMd&—ži¥ëÐ…Îá ÆBöA'†ŒöY…èÐ(âµÐÁ/:Z£?úŒ‹yŸ.ß\× ·Íœ‰ÛfÎDÚ3ÏØ-;øÎ;’Ûp.îÚ…F^Û§õóCÅá·ƒr:4KMM éªÒ@{"µ ‰Qñ¤E >ýne%Ê÷탑ïe‰ ö‚J½„I£>}àå¡zs2ñ¹¿®›.\éÎyuõ>Ñ‚þy.ˆékèj2€…  dÛ“¢ìîÞ¿® Û]M2àιzz¬6FFFòòòœþÖ“P(vçU__ÞÁÄÄD»”ËóçÏ—­%úyl6£üàA´×Õ‰BFXq-­û ½tx‡‰!tZ]zFU{Ñ®T*SBl,b&MBú /@Ë{j}""ܯŸ|eôz¤ýáŽ'¨e[~W%N°Rc‚%ðÞ°Õc¡Ã"ýøßIX$í5iCGf¬fØt$íz=ôz=¼a_Ãèú³” ™=ïkSéî9‘û‹ÀÀ@· kOáZ'$pUØÞÓpÔGÈ}u´|Μ9غu+[8Þµ¼~f³Y”~ÜÈXg±{÷nL›6­[û¸UÑ\^ŽÜ7ßDî›o"çõ×Q}â„ bñvØfOÛÑ!(§kw°dÍ`³e‘×Îf b Êq+ ÿÂ…ˆ6L2M4=Î8Ø< ^Bô ’Wt‚#?©ò´¡€ ¼/ Ò¼I `¤`4€!nã÷[]jܲٵ89¯½‹Ñ(׈DzeË$—=Ë—/w{¿3fÌ>“í 4h|}}{ìœèc“stlû]GËÉw’X §îÛÍ€®ô­›Žú¹¯Îú\Oõ«¦¦&§ýª¸¸XðP:¤I“tdh;{ö, $,oii‘ûD S̬«7#jÏÃÇýûãç^@Ö /àJNL|*NÚ;ÁÖ9`kö3´´„ŽI§3[©™ýÑÞúü>|Õ*$2Ïa2nF<•…÷Þ+SμF~r Àçœp‚·gŒÀ…& ¶h)Œ•š…P¾á@t0À©Æp@*lÞ‘žäh!* txC*CΟÿ,×®ÎHºWÅÒÝeÛ= x G…Ú×êºúøøt©˜Ÿ'àÎ=quÝÁƒ‹ ϱcÇöHÛµZ-|||Dû'¿yŽÚßSçÕÓã C·C¼þúë¢6Ö××#88Øn½C‡‰®UHHˆ1yàä‡3¹>ÉɈ8aƒã½Ptee2»J²êøó/_þwZ„.UMªn]c€NGJÈÚE“˜Ä30ëŸÿD@/yËÑ“Pj4¸kÍõë'[ŽBioˆ?laT~üï .8à€Ÿ­À^#°Wd7yWüj ´¨ªê[&#ÐjíÐnÂARj·ñ/=ß:3 ÷7ðí‚(?tH& 2®æÏŸ…¢goͰaÃ/¬¥DÙî‚øJê<º"êî)p‡øøx!̄ڎ1BHqìJ»ããã†ã¸sî®ÜÒ^zÝÈÈH‡„¤_¿~¢°":{}ÿ&MšÔ­ô 1b„°Žã„ß< GÙ§\ÍJu³!!!A²ÿ9Ÿ>}ºÓku3eÉë V«³³_Œg÷úrâDèêë¡ °KhÀ†~°5ØlWtM²> ¡"Õ–I:Í.˜ãÐÙ´Ì^^¸ç?ÿÁ}Û¶A¡’]ʸu P«1`ñb;–‰gjÒ€Œ35?öt°iAj`óŒ”(p6ÏÈQ­À/V × ²Ú¼%ç¬6Òr¶.:Äî¡Âa É æ 7Ä^M (Ú¼ÿ¹Aë]uòÓ©"<<øÃ V«a졸@R>88§OŸvi›ÎDç+W®´+$8þ|dSù½{¡ò¤I“®‹ø6,, óçÏGAAüýý…kïãÇï´Ã† ƒŸŸt:Ã}¸ ‡UâÃÃÃíêš$%%!22Òaš]Wî_pp0Ô¬ÌÚ¡|o@```¯,¾ç¨ÿIõ)P­®Œ÷5gΠ;'ø~ßTV†’½{í'* Òµ! F]“À‚Ž´¹d{Ö "„ƒÔô Ã®”¤C*Û5+n ¼÷Þ^sÛ¯^E‹ÿ1Π Däðá²p¢¥²u¨>u LD•—ó!‘#F@ÛIØs¿Ù³qà­·=–•Ÿf~l‘4Ô ˆ+•"~™™Ù޵ £ø!Éžå…Žz"dß~ü:><1ÑA\hÔH=8£¥YYˆIO¿é«£Ë¤—büøñ(..F}}½Ý22ƒ­P(Ü¿&&&ÚÅ­ÇÅÅáOúN:%»Žà®èÜ‘Ø2 ‘XóÎâÙÝz{{{cúôé–¼~ÝÅâÅ‹a0zÌ€d‹ÔÔÔn ÆôéÓqùòe—¯ãõÄâÅ‹ñÑGõŠñ8dȇ!…½‰˜ sPÎÑr4öFuMÂØ®%Úª«aµXP–ºÂBœ^³µçÎuº]Âô錋´VUáüÖ­™` ¢£…NûIHǺN]ƒ€­âlA‡×„õzÐ[+€ï¿‘>*yf½ºNž‡¤:µ;à:ù½öÜ9œ^³Æ¥m¬¾[ÆÇcôO`ôcAyÂbexf½ —.áç_DÁwß9ìyŸ|ñÈ#˜Íÿ'°ý™— ;w ûPzyaÈòå8³v-Ì:@2è~F×é!2 ``Æí¥´2ý“èJ,è£$ãÝì`[¶ÀÐØˆ5“'cüK/!røpÄòÅU•^^ðòp¨¼L@d81î¸ãÑïË–-CAABBB0sæL;¯ƒ#h4$$$Øe À AƒpôèQŒ?¾G‹Ð5 €ÍûàHÄ›€qãÆ‰Úç–-[†œœ—3¹SEž´‡õ: 4ÈN¼ÛëÓÝv'$$Øyk”J¥[I–-[ÖåjÒwz ¯y@@€äyô6þÖà¨ÿ¸:†bbbqͳ¢y :k×®Eee%/]Bþ† (àê‹»vÁìâÄA`B¢GÂÕÂB\ÚµËÎx¦ ehÐu@Hð)1LHè]Å\ ±ÎC)aÐò¡ƒ8|‹Ži·IIÁ˜'Ÿ\9p-åå:¼;mUU¨8zÔŽÑÄ °÷ö@‚49úMê»¶L@Žˆ›½‹®8MÏ^7•”`÷3Ï áÂÌüðCÙ@¸ °ë™gpôÿõ?…bpòãÑ^V@KUʵKq«€Í ÁPèt¸™ _ŠhLWÄBAb]‚•‹dÿtÿäxbÂQ¿Ÿ*j_D‹Â†^¨ z\pr)Qº€od$¢ùç{ÌĉINFLz:ü¢£e"£çðç?ÿ7nìÖ>ÒÒÒS§N•\Œßþö·Ø±c‡ð`Μ9Nk"xS§NEŸ{Þ¼yHLLÄÅ‹íÚå 2}úôýFD·¬%99³fÍrxýâââ0gÎ\¸pÁnùرcâ¤ÒiZZ<èöur¶lçνVP*•vY‘"""D÷ˆ²RxàÜ2Ö{ân`Ʋ•!ÿN'WªªpaÛ6XœçßS,@P¿~IIAì„ ð ƒï :Ûk ÈÚµkÆÑߊ¸çž{ì*»"”2dêêꜮ«Ñh0qâDTWW …9ŽƒF£éVµlW„×3g΄——t:¨"3)XGŒ[Ò.À£„††;‘-+~w$ÂíÇå¢+jßsÏ="ï’B¡*ÜKA©T:ÔM 2ÄÎkBcðàÁhtú0þ|477#>>%%%.]÷I“& ×ÇÕû7`À‡×qÊ”)رclG¾úôé#" ÎúØ Žã<–¢;ãI£Ñ ©©I"GÆ‚+Ï©sxðÁoX¯‡Ãk¬P@Á{Aãâ0}zG?ç w8^F#ïãQ}ꔾ¡p@.ŒUU¨«ª‚Ä¡l2ÀÞ; gÈ1N*Lf3¬V«d¸Ùïù „l>Zgß{Oð°DP¿k¨wRKD q¬:}NlAE‹êì;M,LNL×?±À¾Ž }Þ µ‘©©ýøã²Ap ýzÔŸ?/"ét8"é¯ÞTŸõ†MKA×(¥Ò–WI=ÚÌÀdLf Íj+>ØÌVØ4íL Ú-a<Ííµh‡¸–Ïùµkaâ×eõ%& ÂÎŽq:¤KôÌ’øîhÀÊO4ÐÝ/:±±ˆ3©©ˆ»ã„2ÿé2q¤.«áE·FŒúúz»JèQQQ¨¬¬”Ü&== u©âupp0V­Z%\÷ÐÐPA¨íªÑËbñâÅÐét(**¤I“°oß>»u}ôQäää@§Ó!==Ý%²Õ¯_?AlÍŠlW®\)Ì´GGG‹Äü/¿ü2Êùð+V¬@ff¦°3‘®Ô¶ÝAzzºÃeáááð÷÷ŒDWÚŸ'==Ý.´.šqÝFGG‹Úàããƒ'Ÿ|RDŒFŒäädA­V#,,Ìn?×ìýu"$okkëÒqÈX`“*¸:i¤¤¤¸ZVQQÔÔTTTTØ]s2:;NH?Š¾ÝøŽ0tÅ <¿zµKë^-(@KE8§yÂqúË/E)v9 ƒŒáD‡y*š8¨$Œ|)>iî\T;†&>Ü„6Fh’£¦Œ4B2ˆq&ÞÅ1F Õ:ª™@‹Ü¤‚&´P—-¬è¬P¢ÀÔ·Þ‚/Õ­÷(õÁe#à& ¥KqøoCÕ±c¢>AÆñ6(a¯—bÃUTV~%Àq€Æ hùmaY¾°e¸RQDÀÿ¶ÛÐ^\,ˆÒi!9òZÏ•6Š¼Ð…FÍ$JEu’’—&!Ff I +ìCန´UT µ¢‡Á  ï¸qIJBÂôé¼lY¯µË!X7bcc³Ù,2^æÌ™#IÔ–,Y‚òòrº}iÉ’%(,,ĉ'œ®çííööv¶ð‡””X,â:¼@QQ’’’$ HW@χ†† ߉(xذaؽ{7îºë.|ÿý÷X²d Þ|óM,X°@zz:Nž< Ì;%%%G`` æÎ‹ï¿ÿC‡Emm-¼¼¼„™c²ß?þ—/_Æ•+W¬ì5ýöÛo¿Q£F¡ÌIx-00`€ÝL6½\Jp¾dÉ‘`úÛo¿2 …††béÒ¥øË_þ"\Ãþýû£­­M2µtéR@QQ‘žžÞ¥Ì^®ô?W1{öl—+’KþôýíÈX$û³X,Ý"=4fΜ TTT`öìÙÈÍÍíÒõ€á|6¡Î@ÜL°˜Lh«©èñ •î²½¦†æfÁÐH+e[ AG&bt°U˜U”Q"´‹Ùýðüãâ04#Å[·BWU% 5Ñ0/:U/™½mçgzÙZ!¬§ÂÈ,ã¼¼  ¶40étðŒ´óJ¶ÌTùb—¬®C4ö–/‡Ò‰‡Í?6Ê›<ã 1”Z-îÛº¿¼óN|ú)ô‚`[ï€ØÓú*áw  ´Ø§®ö¦ˆ„š·Jؼ(AüïíÅÅ0ñÄ„è3ˆqìM-h䉈ž" $Ö-[pûí·#((¡¡¡¸té–.]ŠÜÜ\Lž<3f š››áïïßýîwˆ‰‰ARR4 ¢¢¢½Â¯ýkÄÄÄàÝwߎƒææfäçç#::………5j.\¸­V‹;î¸o¿ý¶èÚüðÃ"ÃØŸ ó`u'¬@\êÚŒ5J¸¶ýúõt2pûí·cèС8yò¤hDTLŽ¿téRÔ××ÃÏÏãÇG||< ‘€¸¸8¼úꫨ®®ÂæÈ½ut¯úôéã‘BDÄO“¿DHŒÔqõz½KýæØ±c÷{\Ð ¸C P[[‹¥K—zÄ“+uMbbb0hРN¯‹Ç{Ìíä7/]BþúõBvck+ÊøÉzF•¼k!­y2(”Ô̤öš BeÙ€CV¼n‚´~‚ÐTZŠS™™¢Šèäåqm3O6ˆ§B{kÑßÉçþý14#ãž}pìŸÿDùáØ'G"ÈèøFEaÚ;ï iÎýç?EF4ƒçwî„úp¸J?/žÿó?ÿ#›ìÓ×ÉP#µZ3fûËÍÍEaa!^~ùelß¾ÝnŸ^^^ny¶ˆ€½³6¸ú¼¯×Øì.Ðiưë}®½ ˆÃ¨¤z=+|fÅÐÄpak|Ð3–€½• :«‚!8l] N©ÚKk<´Ìì)GÍäOŠ‘ÙŸ0sš—‡;ÿþw¹Cȸ!¡‘(¬JÐ^W‡œ×^È>Úh„8d ygÓP“ï$ ¬Œm… • V£ «U‡d\z1ŸÕÔg+5>uè(FH·LèÈÆE!å˜çý¼00·´ß ׯGÕÑ£ð Æ~Òܹˆ:IsçŠÒ+{Q"™€ÜàX±b¶oß. £££QQQ!2Ú{´ÀyÅŠHOOGnn.FމK—.‰ŽMÚ‰qãÆ!66þþþB}“U«V‰H‹ž<ži;aˆz“Ï´€þüñÇÛý†¡C‡^—듞ž.´yæÌ™ÈÊÊÚ¶ÿ~øùùaåÊ•n‡ÝH"h"ÜNII±KAÆŸŒÞA@h£ŸwbÅÐØ2e26åÂØÖ&"lv+Úˆ!3š  …Q¡5Šäèkk…ØsÚ¨!äCÉWl­#³OßèhD)w7%òׯGÕñ㈟2Eó çÏ£¥´ÔN÷DÆ»bÏ"ÔA‹ŽJçzÊØõøãH¹ë.T?S{;.îÚ…ÖŠ \ÍÏöC³¼©±ªd!èð~Ðcš&$äyBOx°Â>/^DãÅ‹Âo5‡KL¼Ï(Ôj¡À¡L@dt ³gÏbÌgÏžÒÒR×Ë xúé§Ñ5²&''C©T"%% @ss3Ôj5”J¥hv{öìÙ:˜<å‘q}Я_?Q(Ͻ÷Þ‹={ö`Þ¼y(,,‡œe÷"ýhäÈ‘.i‡4M—¼[îÁI¿v„¤¤$ÔÖÖ"<<\H§K’ ÐcÑ#³Î×ÇÇGäi“a2‹)ÊBåã-?Ñ‘8}:ââ„e±'â¶;ïĥݻqåÀ”íß‹Ñ()€U0Ç¡…älˆ–Ž£ Œâñ „ƒÄÓZ@,`¥Å°ùP(à…è1cºbúß}·Üdô*mÙ‚êãÇ’’‚÷ÞÛåýŒøÍo0â7¿ývîÛo±ý7¿¡¡ÁNëDŒp/‰ñÌIŒm’ëØàè@¯øFEÁl2‰ª›“,WzØk:ÌÔ…RâY@§à¦k ¨œL|g©¼Î¦Ëv”îzíÔ©€R‰À¸8Ì]½Z o2‘ÑeÜyçB}___—«€» ö#™™5†EÏ~«åÌ&75è{=vìX$$$ ÿþ9r¤`ˆðÁøá‡„õæÎ+œtc†v̘18zô(Æg§Gqw„à#»0c쮊-ÜØbbb„0"0–!ãZBJÀ>fÌ <åååÈÏÏGHHV­Z…ÂÂB‡û¹ýöÛG£Ñ ""Â-r-ÒiÑÏ)S¦Ø¾}û:\?55¾¾¾hmmõˆÈýf…ÉdÂÙ³gqéÒ%„¤¤ ïøñ8¿c.íÚ…¦ÒR› ÓÁb4ÚeÁ¢ÿØ!]HRᬗ„ ™  ˆu ¼Ñr¥¡ ’A<­°¯æl€}Ue}s3ÖNŠŒ£G¡vØáûeËpî›o`µX:`’ŸŒ®£æôiÿôS@Pb"Æ<ùd£®°eÙÙ0¶µAíãƒèÑ£1t(Žÿë_¶ÐA• ±'"‚ ÙåÔ"$%Vز-MþóŸ…å /âð’çÏG´in·ïø§Ÿ¢†Ÿ4¹øã¸ýÄÁ¿þuEE° ‚‘¬«®Fþþƒ³ÿù°­wHîüûß1xùr4\¼ˆ/'M‚ž)ÒË0µ·Ãb2‰ˆíidÓR·òãˆd‘ó‡ÍËHƞĢr2@üæzêpiÏô›=-ååÐóÏzrlº=yAW['û¡Saë)‚`¢ˆŒ£"¦¡ýû£¥¢†¦&ÉpP©4ÀlH–ŸôF& äJè¼2dtjµ©©©:ª²ýÄÛo¿ÄÄDÉêÛƒ ²ûÍ•"š€X`ïÉÊ完=’¨áî»ïFff¦GO4´¶¶Ê^ÅN`0`4Q_XˆS……vä‚ù*†4p°—Óٰآ{RéméÙH©¢´¦ƒNëI2÷´QÇ0P/BBh¯‡2`óu6Z«ªP¼u+®`ÓCaXF²_}Õ.‹²3ýzÜvç.)³šÍ0óFŸ8WH¢N‡3k×:\^¼e Z««…ï¤ÖˆÕÉñ.îÚ…Ø ìjp°…û´VWC¥Õ"õþû%Y~ø0ªNòLÿkh@}q±ÍöóÃÙ5kDFçâu’:W²ž:øþcjnZZPðõ×°´µÙ„Ì&ª÷îEõÞ½vI*¶o·ÍÚ«T(ÿñG¡}†–\å‹Ö^ذ¾QQ÷ßŶ֣πÙwìX\Ú¼õgÎcC"7é÷œÅ‚CgCï½cK Z¨ZVp`³^zÌ[™c)‚BÆ$(âˆEè­°¥Óm…XÒrñ"T …P0‘6ªÙ±N{;9j‚ §l‡¸6ˆÅÁ³È€S«aU(DI'ègÝ&–x@ü”)ÚÍâÉ7-‘+¡Ëqó€&0cÆ ´··#22R²Ož<ˆŽŽ¶±Ó!NÎë+V¬´$¡¡¡˜7oÞ59¿_Ixò´F#::ZHÓ,ÃÁšJ%¤h&ùú0óÇNWû–"äÝ¿O´”— ûÑH”„(ùwB8Ø*b!öh˜a?ci– Cg×®¸€m&û̺uh¿z çÏ‹ 8%uî§>ÿ—÷ïG_Æó(Uq¹þüy”ýò‹ÃÊÌlv!úE{›¬ÌoìýñfÈ\áîÝ"ãIjÆ»ä»ïìڣ䯻lÕ±Ëä 9®ã] óyçèï°ÿSt|Vp€Bp}mŸÁµÕGD ç¤öfŸ`Ú²?~™€!'k%Âx\@ (T€B p@¡8ÞòçxË\0H­&X­G `%ƒ! °ZX.Ãj¹, +•îMê³ÅjÛ‡µo<[˜+àï±P˜« °˜ƒÐéÞöjkl@Ë‘#B†¨ˆ5 læ:Pýˆš\¨©¾Eú iw`+J¨à›WR Ûu²p€Ú-¶W+¿M3€öü|A«EƲŠ:)Ú&ÑÿÙIߎ@j\²ãN:a`<}Z~{#ì½­äsßÛo‡ÚÇ¥û÷Ãj4v<÷,˜ÚÛ¯kŠ^9K† ×#FŒ>7òîõÄÄDx{{#::aaahmm…B¡Àüùó‘-„\‘dž]ÞS áRžÜßÍ^8°'þܼ¢AˆM:Ø?{úå «É„ö«W£V×Ô$Šù¶@¦Å¡#„ƒÁ g@éÐ :CÏNIA}a¡Èg –°uFªóòP—%:2ÿ°uD„mΟGÃùóÒ¤€”ü+”"ÔßUÔKM>+ ×ñR+ߎOíÅ •Ù8X½8À[«–ëø®á`Uq€ ¶w…%X‰%N7’,SÆò'¡â÷¡ß@Àªæ`UñËÔüþÕ¶u¬jV5³LÅÁÈ©`„&¨`â?¡±}‡ ¨a‚Úö;§‚ j˜¡ä—+aBx™ùïVŽ>[ €…Sˆ>[¡€™ÿnå8a™UXÏö›d™ÒvLÎv\=´0r衞Ó Ðm7BeÛÆª€ÅjÛhªœùÌYmkpV 8>Ä[ÁVÀ ÎÊ·Êj+Vú¬m­ÓÀ5g„7ÚÌÕ#çj… ÜÆ]@œ¥>WÚ¡9¥‡ªØåe”%&˜‹€ú ÎÔZkGÑM-Ä^D…Âv«µàË~#Ýlt Í ´Xm^ 5N‰BÀWhµ€‚Äg©y¢e,ÀÒ ˜@«hµØÞÛyÂÑ„Ï û"Ï#%ó¼¡3h ý™­ùCžKô„ýì Ï#5‘ÑVV…JÎlí§4+ ›W¬ÀŒ÷ßG@l¬L@dÈqë}¯X±ýû÷‡¿¿?233‚»ï¾pº™3gvùøK—.u{R&00PR³rß}÷yÔ{{ß}÷ÉÅMÐ!MVŠlX$ y¯°0$L›&̨†$'#vâDÄŽãÿú~zê) ˜ZZD¡ .$ôJ ±&L;ˆ¡@ŒbS7ðäÃ"áeð Ddj*ʳ³RAǯ é{9@¥´>€·àãøøêp@(‚³Ÿ :­Œj- j- -L*5Ì*5ÌjL ŒÌL^*½T0hU0¨ÕhSú@§øÿì½yxç™èû«®^Õ­­µ! Ø1;cÇ8ãlâ;Çqr<ËÉ,Y&'™Ç3“3ÉÌy²œ›¹INΜ“Ü›''ãx_À±Ç,³ØØ, ’Ú¥V«[½WÕý£ªZÕ­³Ì÷{žzº–¯¿®®õ}ßï]Ü$mN’š.’ØIIº0ž¤$cÙæ )9HÙì¤lv’6)Y&‰ƒ¸æ&¦¹IhRªE±£*º`¬ª6TMB³L`̃.8k–6–yU•Ð4š*¡ª–OMBËš„¦ÚÒÛõï™ËèÛ´Ìmã|ñ²/«?ѰMvú%óäç2“ŸkÊŽB63dûø$_­2Û§/;³A,ÇwS(¤]ªW5ý3eÌk†z­¥@2vDJ¤€MY34a8eð8Áï@*o~œââE%Q "—˜šìdŠÒM…Ú‡/$ÕH¤4ì©$š¬‚CCuÚœ z%§JÊ¡”“$´Q¼ÉÑÊýö¡R'!q †СA7ЋR”ªP…ü8\àÈÓ•É r>È¥àÐÀ‚’hHÅõÑœ‘”®„˜#,a‹r`=”¦‹UÜ8̙ŭi¸–g‰iÌpgŽXÓqÇ­ëΞ%ec¬—¬z€{îaþƒ D \ß,[¶,=oìý~?3gÎÌù¿ßÅb=Ln»í6š››¹ùæ›/kUño¼‘·ß~[\€„a”ìvÊçÏO óÞòrf®y©XŒÁãÇñUV2û3ŸIˉ'^z‰“[·²çûß§sçΜrŸU1ÈÎ~%çP<¬±²G@²ë‚%·ÊáÄ ¢íÚÅLt ¯×Ånðæ«\åઠÈI¼ÔE´ÆC¤:¡?Íeô”vç3êö2$Ó«T0¢Mä{ˆ+.Šƒ¤ê$¦¹HjRšƒ„Åzž2,ý*6Ý⭪Ȫ¢[¾5YSÆìý’aŸ·)ú¼MŸ·K)œZ—Ç%%pi ¼D°kIì(È’‚MV°£/mQ— û¿4fÿϘ×U$TãÓ°Þó˜ë´Ìõæ:s»Íl«iؤ±yI²lËšÒMï°k)ì(HŠª£”ŠMQ°™ËƧ¾¬¤—%ãxJª~<%Ußn¶•TY1¶«*’1/iº”¤e:ä™#)š]BqØPóeT›Œb“Qe;ŠlG±Éºòi.Ëv’v)ÙNÊnG±ÛI:¨² ME±“Tì();)c>•²£¨²¾œrRdR)‰”ƒXÒM4å&¢æ1¤úQÂ6bÃvÂCv‚ƒ."=.‡]„ƒÎD t…ÆUÅó¡Hƒ"۠Ȇä–pB¶©º«”MF³ÙÀaÃæ]àöªäûãäO á¯bQå{,w`nO3ZO‘ÿR×Û®SP2])§€fŒ4Ø8càŽ#’¥ º9ÂgŽüiº{Yž!Xç¡»U… Cˆµa"k²ê°)˨I®´»ÖÑÔ\…Q5‹$WÌŽu$U¶þ§ÿ$@ °b Fÿâ¿Èèè(………¼ð Ȳ̜9sعs'Ÿþô§3ÒüΙ3‡cÇŽ]ðï•””Lª \nV¨¿”¸ÝîôèŠy ‚Y`“£aãF¾ð­o¡)J: PëK/1Úۛ͒¡‡} ØóÝïæŒYpeª­/qñkL÷+«?¸ÕõAÉ2L§_m-ÎÂBúNsXF7 €2 T‚Â|(¬g=Øg€4Bóòª*ædq%'< œöL§ÍVÇjh×êD‹H„\ÄG(a;ôƒ”Ð]p–Iá²%pÛ¢¸ìq\r§=As§3‰Ã‘ÀåHàt%p88œIÜö>Âx%O‰âNDq%⸒q܉žDW2Ž+e,'£¸R1Ü©y‰ˆ>¯Äq'£8ã ]J3ìGu3®š-iÕƒ§Yb4ŘL÷sÞæ´¬@šô÷ÌeÕ²Þº¬æhŸã{Ö6ÙFzÔÌ}4ÿ‹uû¸ö9T”¬Ñ;«;ŽU‘U³×ì nÙŠ²yÙ²[SЕl ±d×ç%ÙSb̧'˲)kvPœú‚½ kÁ9ÝF÷œ*ZËfrdêZKgÒÓ[ə֩twT2Ø[Bò„µ+ˆAí¡5EÑFch‰$ -Zbì¨h†H«é‘a­ˆ© ¼µ0ÃΛkoC¾]¡ti?«×íæ¯oþ7v¼MÉëaJ^ƒ)Û¡;g4è7”† "»ÝD{{õøóØhú³ÁÃX܈9™Ê@Òè'j™d¦Ì5]À¬# à(,dæ¦MDz{9ñÒK9ë•ä2vd»mf×Éœó74|hÏh¡€‚«žŠŠŠôüÚµk™1cÍÍÍœÀƒŠ—Nòéd¥ûMnñ» JÁUrµD¤¶àÂ2Âù…„òó û|Dò¼º‹*¡¦l¨)ÉÐè%RQ±”‹ˆäc ¸Œ®)UœvNçl¢š!ÕOÔçfH-a¶šj×Yh€UÞÝxó#äGÀs¼CúHFƨE0ˆjÔ÷}v-¯Åx`Æ›žmf`}vj^, ó3 rØ0ŽÈ9¶kç9îLò>Yõÿ @ ˜ 3fÌH~ë[ßô íõë×ó£ý(½ ™UØ­ï”Å‹sðàÁIïç¹;3C‡s»àƒ3rêݧNá!·k½t%#;è[Ͳ&*Œ¯íau“²Žz¤²„Kk{—¥,ŠG0ÃÅåàlip $gÛšRD·o ö"4$|Z˜º‘6ò»CäŸ £í×H¼#ÅpB×’ú„ñ©& ¬Œ 8¤³ûeË—3ÜÑÁhoï¸4 Z  ú¦›¨[·.½Î1à<™T®7<üpƲ55oAm-Óß¹ZðVT »\„»ºPS)ºöï§ÿðajÖ¬ÁߨˆÝã!¯¬ì’þflx˜ÄÈgvíbȨ«4ï°»Ýë\……ÌÞ´I7pTV¦Ó-/üÒ—.ê÷£ƒƒ$Ï“hc¨¥…£?ž¤M|0«8ÍàFÜn?ú(ŽðœÒÝ—¼hä3LÃø$(t‚äMEÒ' ×'Y9 ‰¨~}•ù t h#ÑyãTö”ÜÈï¥OÒÄ\†)BF¡:vp3R•ÊÊOîÅÅ=Ô÷/œ%$g+Ìó~˜ægž! f¸?™q`NCÙ*ÈRÂÔÏ’ìø %G[‰³óe?·üÔ¬YCßáÃtïߟ3-¯§´”i·Þ*@ ¸¬õ0Ì í?ÿó?' ñÙÏ~v\õðÅ‹§GL%æƒ( Ä%êÎ;ïä·¿ýí¤Û_LP½`ìåæÎ¡hHäNW©žg¾Ø¸f§NeŒlXý²­Å MÅ|jfæò0æzaºj(@P冊(ZÒ H.r0Ôè§{j%ýžR†$?~†h¤…ÚÁ3Ø~¯Â.`7š¡)mÀ ™i|íØNb#㊖Yÿk`ÿ~T jÅ JçÌaÞõ3¬ÖÕ]6wŽ%ý××Ä5ç3F- jkÓBÿåÂ]T„»¨ˆyFÉ+¹Ö]j<%%xÎã‚ZPQ“¦Ÿ IDAT[Ë”eË(7–çŸçÌÎä•–’_]MïûïóžQf®‘ äÌÎôŸ=›™¦V)¶xf1(/PøÛ(p¤m5Ê*ní%¿(ÄNnæ8³é¦’!üe*6F‹½¬Þ°‡’ÊAìÓ5ê·Cq †ô¬[Æê€Ä-ÿïУ¦«”›#{ÖÚVW7‰±8/3Pܬ°n>¯¬Y¯²Sg@’9æ­ÛC--4µ´¤•¡lå ¯¤„‚ÚÚkO`t4„¢(Ì™3W¼íÁ‡Žé¶TPPÀܹsÙ±cƒƒƒã‚¹7mÚÄ ‘Zõ|˜.PfPüÚµk'½?7Þx#@ ½_¹ÈGr®ªè‚Éa-:¦qîŠÀVÿxÙí¦tΜ K}ßáÃ::Òm!Ó‡Þªxh–ßu£×pR1ï€|'ä{A®ÊJPjeâunâõnF<¨˜M³m6§muô0…Q¼ä¡’nV°úÄIªÏvaÛ§Â6ÐBô4ô¥tW»ñ›,E ÃáŒc$1ÞõGìn7esæðÐ[oa³ ;¥à⥕_ÿ:+¾úU†Nœàùà¦ú'ï¾›×ÿËáØ“O2ïXgŒ^?½q#-gÏfe'&0"`Q BŒ…%5Hu@É« €³/ÁM߯:L‰}ƒ,æ 颊&æ²[Z;i+XU»‡wî£dÛÕ¿W©~ FÃÑ$´£&-÷·UÁ°ÍŽÉ0ûc± æ¾Æ‹ù²3¬)³³ûÏ6X3饲¦\ÉÚÌç£ÿתºb H08LA^À¤°ðÒç§•ÐÁÅ,V¸qãFöìÙÃܹs37N*Mn]]‹-J+-Êܹsyë­·ÎÙfãÆç\LMÓˆF£D£Q»„ÿ£UË—S¶`Aæu²|9åYëL@M&iûãyrýzH¥ÒîSÖÑŽ\qV÷b Z‚òBÈŸÒÐKæs²vÍîY´¸i‘9­¥?VÊH²èYI‡­@¢Ô×ÏRÞaG¹EÛÉÒ¶wÈÛÝ €‘&èŽA0€žýËšA5m•UÕñB€ÇCÆ x8«ºuëð76¦@p)d™’Ù³ù³wßM¯ûøOʪGÁ]X˜^·îÇ?ææï|'SÞìè`÷÷¾G×¾},ùÒ—˜ûÙÏbw»Q…Ö—^bÏ÷¿Ÿ²£è.^ýq˜v ¦ž„‚·¡ààk>ñ‹W¿Ç~ÿ2ž>Ë^VÒ¢5r*RÏû‰xÖ¾‰:÷iÖ~|;+—½MÝñv*ÞíeÎkIÊN« hC0d&ŒkcAå6H&4ˇXG9M…Àøo/LZŒVãFö3&WÅw?Rbí#ÛcuÅlnFSU¤+œEò¢˨„..æFuu5«V­ÂçóMú».—+Or¹ƒÁ‹ŠŠX¿~ý%Ϭu=‘H$xñÅéêêbÁCñ_þ2½mèÄ ‚mmã¾ÐÝ‘ú¦kÿ~]X2_ÐÇŽÑ÷þû‚€œ%XË-¨èµüèÁãu@µì À `ÄW;iòÏe'7³—•œbZ)©˜‡’Ä#G)wô1ÅÝËW7ÓRíÌ 4³`à0m}䊠mƒÈî×vÆÜDâdº—L]½»qgóé§ŸÆ%Š\ >$ò³F‡‹r¸ÇV,^Ì”%Køÿ.¤çÝw‰ sfçNBgϦïWsä1‰»1„H^”€ÊV˜Ñ¥;4|Ëì½c;5wt²£ôf^6²›Õ ¼WÆÐ™ŽEçðrÁ'¡Ч± á·üåVzÞ¦êdÓßbåû}xND‰·ÂÙè C" NJTp«àPôX«QU7Œ g׊‘™èÂÂM-«•Õ¨‘=çOš×>=Fçìž=L½é&¡€ÁåÂŒ«èììÄf³±xñbñx<çýîÅt¹\¨†åÙ;0oÞ‚b—ŒÌAš.¬˜“éïnV ѧ@õYhüäïQ¨_{’¯Þú?¸qåÛl¿ãVv/½‰c·Ï¡ç`ÊQœ²A_ µm„X,F,¦0œ7§)× ñB Àzp,OÒ8§™›>ñ}é7Ìíl¢êý ÕÐàà(ôõD!Æ\°bdÖÑr(ÖLXÖÑ’‚Š |UUôD£$£Q|55¸ŠŠ  &“Ø®Âó)žJຣ±±‘††l6%%% f¸>­]»–S§NQUUuI\¢JJJøîw¿Ë¾}û2Öá _`xx˜/|á â¤\bÜqr(äP2¬Sv]ŠìOSà7G<ŠÐSçVK0År#0X ̪t EÔpŒ$õ`fà p”ˆ‚¤ê>ä1táDÕ2ƒL­Yt’YÊUñ0Ùð«_Q{Ë-âb\ÕD 5MN¿þ:5kÖÐöúëÌܰ€âúz\–8‘\Üöƒlo§¸¾ž[·’ŒD>u*Ÿ¡°§ëÑŒ@å»PØî]n»å¬Zô6g¦ÖpdÎ<Þ_´ˆ¾‘r†E†Š‡|Ä¢n´aʰDÌF<’"a4&S|$íx’}Ž6ΧyÑlN_̧jžgcõ Ìó6é;Ñ ‰ ž¥.a/ŠÑcFl9Œ Ö‚§Ö‚…I‹ò’jj"ÜÔ„Û0´„`„±àv«ÑÄì×[Q‘ÓåM( @p™$ IÒEP3 Ý þ~ñÅÓJHQQÑ% —$‰ùóçS@ìv;ŸúÔ§eYœ”KŒ)¸Ÿ+VvkëKÚéõ¢$“¤‰ôvó,9 åÃñ¨ªœPPò|`0˜iHqC£è4>OMl†`zRº¿úzõå(c­’åÿXGal.6»-CS”qÿù×¾FåÒ¥ëbG,é g®_ŸSyï¿`æ† øŒdWšpw7ÇŸ~:c¯²’ÙŸùŒ¸°?b¼ýoÿÆŸþ”‘3gÆmÛaŒpÔÞz+³7mbög>“qM¾÷‹_ÐgÔRJŒŽÒ}à‹ÿâ/Øÿ“Ÿ¤•3>$aL!ã>;8Sàé…ü^(ÝùÎ(ùÎV{[¸5ÿ9$hNHJWõ)ªAR–±¹8Š\x+î»0sÃ†Ž§ÿý÷Ó¹ùèÖÊ"ô‘ `† \• Õ è#S«>vÖÐ*ºã@+$:!Ô==05`ìk”±L9Ù£ÙSÅÂ…ΘÁ™]»ÒÁ¸ÿ?⌑M‰Å8²y3‰‘N½ürºÍñ'ŸÄkIùlºŸµ<ÿ<Çžx‚¼ÒÒŒcwYe+20@Û¶mç#¯´”cO?ÍôÛo§nÝ:ЦOù5LÛ¶müÅ/hyþyÔx<­ÜçŠwèܾ3Û·sâ…Xý÷À©×_çÀOŠgÄIlÿÊW}”,‚x=~jhàŠë“;Ξ±ìRfó±Ô¹ üÄh‚Ì~êçò[°îÞ×骯ä˜wÍÌ¢‡)È(zÝ‘üyx׌â÷°@~ïÙÑK œ)¤C®Å9=wY©KÞ€êãºKŠ0!SùQ,ŸÙE ­.£díw¶Ò¡’™²WÚ·mã?n¾™ºÛogÝ~DÉìÙB‚ƒùóçgTY\›Œöôpvûv=½åÀn2]샃؟ñR=ó £Æ|c®ùèá~ ò Á]r úð‡YzCªé@÷ïèuPëˆC(¡„®tŒ0fM5ƒNS€«°Y›6ѱkC--i!ÇUP@Q}=#ÄŒTÀæä´Lf Ó…Ãm¬³.Û`³ƒdÉ’!ÑH²!\IYZ„ š:¦h†4¦þš!™©Ú˜»‡éþaõYÏŽaÉðag¼o»µÊsÊ"4ttpð¿àÖÿößÄ…~ 2ÐÔ„šJeó4'eò÷ŸÏ0x— lcÊÙ ’KŸp1fúOê7˜uRH@(© ù}è#!ô‘Ç™q^Xúì p, HèI¨j‡¼}zö”BÕ²nRuv<¶(=La˜"š˜KÐWÈœÕÇ)ËïGªÓÈÛ ³ß†²pJÓŸN2ë‡Ä-“™5˼o¬û•­€e\€Ì,€Z"ÁÉ—_F’e6=ý4²Ëu}+ ï½÷©TJÜ©àŠRxž`Ç‹¥´´ŸÏ‡Ûíû2âéîbJ_Nêeð€[§d7Øó@vÍ v7ÈN]0—`sIò’W—|$³²˜ƒ1§ò úHG7h]è…Àˆ.Ü´ÌÚI2}³³sø'ƒAu¯¬™£«‹xW†"d-væÜx$ýÓ)ÓØíú±j$i!Íôí0MÇVS©6¦hdhñLÍA‹ëu´¤®ˆhqP“àHéY»–saU”¬é|U›³…>0*µÏŸ/.òk”ŽíÛ!‡€,[”húˆ£©ã{\`óåèqUÅÆÆbtwGã>M_Ûª~ÍJQG@îWx{¡¢j{!AEïCwÇ2{…ÌTÛÖ âæç¨ÑÎTDc0ç-ðµí8N$©ÿ“STÎéáTÞtš¥Y PJ3³èµUÐ0諒x"¸fı¿§8 á‹B¡ ^Øe$P’ŠA2ñ„"NA,‰¤PPÔÌ[Õ¼³Ó‡[ÚÍÿtrëVv~ç;¬ýþ÷¯oÄáp`³ÙÄ*>2Ì;—o¼Qˆ+@¥nm'†°’ϘIµÐäM¥Âj"´JÆ1t“d]£­´>P Ü#1JꃃŒU"7‹ZÝ&–ŸËvõ0§!Kå¡+>c·=¸$pÛÀ!]› Y”MjMAX1„vÉP’²+—‘å¾adÛRŒÏô²:¶.=¯éŸ ¹'u%"—R‘+Îe¢˜SH’=7nd®Hi}ÍR¾p!’͆ªªº+ c.ˆfAA3mî ©CÇÁÝ îApʺr-{tc‚ìÔ ¦AA¶ëŸ’$HNCùöë÷¾T¾³àëòD¡P…AMÏ’eÆb$-ʯÌx7AS?7ã7ú ÕPÕÇ@n‚¼Eæ.8Fõì³ô••Ó몠ÛVÉ»ò¤j Wuœü;B”hƒ8bIˆA(%¥cÄ%UÃOâŒ&qEâä#L „pÇ‘ú4l*¶>iHC B$ñ$"ºÂMBDÓ§°ñßÌQsÖ|ì½ÿè£,ûò—ñeˆ¼®Q”K |ÔÊÇd:pw–baJ³QtI#ah £¤ßÌÚ((ƤÆ@‰€-jbÊ˜ÛÆ¨ÑM”ÌXÓª¨W Ð ·¡÷˜†Zo—1*ã4(Ù© WvÈÖTS2‹ëÒN2¬»“€Eßão8§N%ÔÙyÎ Éd)*™±ZÖ¼¹­tþ|ò§N͘n]–-BÛDì% ÔÞ|ó¸>Þ3F‚¬xËË™¹aSoºi\õlÁµÅò¯~%‘`ï¿ý‘¾¾´"l^ÞaÆÇ1è‚8؆¢ûH¦o½í»C9Pæw1ÈæÊ`*8T(CyRˆÇ †XL¿×ã)}J&õQ†¸’y¯›#w’qŸ§t£1ð„Š6ÈÛîj•â¹Ã7 3«ºEÿý2P|6Â6A{žRyE zKètN¥:z© @1a|(ÈØPq§ E S Óh§–ªÕ³”Gû˜:x–ü¶”>:{8œå, Ž@·¦ïcÀPœ¬ÆÑ¾>†OŸ¾¾@ .„X,ÆæÍ›éééaä}h>fXóÍØ‹¥_±Xò“ª>z`Nf€ª)\XÝ€¬îÙV|sÞÎXì…՗ݬ’oƒ<'8Íèv3hÃ( Iz\…š4ÚA, E–)fѧ¤¡¡´ ”†_2÷¾û(¬­åÄÖ­„ûúuv¦+$kÀ‚ÏccúX¶nÝ @Æ  ÄÌ ¨X´è²žÇÙ÷Þ+.æº1æ›ß¤pÚ4Ž<ögwï&bk5• g~># [am-3Ö­×GçîÝzìヮmƽ×mÜbE1(^(´CA8‹A.© ˜ vŸîŽé5µs«FÒ-jX¿“q}Râ Ä —ÄDR0ªBH…a†¨è…²^ð…¤ R2$ŒÑÊaM%(`“F¨¶wÐP ž*ÐfÊ(5v”R¥X&êÉ#fw‘²ÙQlvT»„$kØd§œÄe‹ãÖ¢xRQä!ïÌÌíÖŸ%ªšiÈe˜®à5 @ |$p»Ý<üðÃ477³åŸþ‰W’c/\{A3ï¾€£Gé;x0ý=«ÛϬ{ïÅeaÎÞ´ Wa!ñ`ßÿå_éïO¿ «–/§bÁŽ<ú(vÆjƒ˜J‡™5Ëôø2ݨ2hPm3„EE1%3P;Ž>Âbú§[ØE)Ã)AŠêëiܸ‘%ý×××°ê[ßôJÑÉH$} ¦YRQÜd´.sî»9÷ÝG¸»›ÁãÇ3¶ù*+Ï›‘)‰Ðµw/gŒÄ ¡ÎN:Þ|3=bŽTŒr¸p©àM@É€>Mi…|xjÐÓ¿MêŒO¿qûHûMÚTð$ÁcÞ˜£èÖ€ã³}haÒ]5‚dÎÆ¡;®Á' »ƒ)„;0’TÀy ì»ôT¿æèŽF(­`É€Ó¦”:Œ6»l2$mºAÅôkÓŒQ܈:æE:lìö(cñ.æóÃYP@^Y™P@@ ø T¬^Í-Ÿÿ|zy×w¿‹äóѹkÇŽMX=Üáõb7œ~õÕôzY–Ó‚ îßOpÿ~òË.•ǘ›•9òaÆÄš‚PL¨2V`Ô”’n7šËN*—ãßRYŸÙép tÒžÒRæ?ðå‹1míڜǧjåJq‘® |••¨è¥#/i·Ý–Vžƒmmœ|å@eÀb,h{õU†NžL§ýí1îY¯ù!(m‚¢cP C^xòÀi&¡ð1VÐzsf§ñ2ÓìÙ åÅ¥g™3{ìJæ½m>ƒBèðf–«c5ÌŸµf”³© ÇÁ{hÌSÓD²ìŽÍbœ0³Í¥ÈÌTgÝ/þÒ—2FB…"Á0xìÿ÷ÿN[ ÝÝùùϱ²ÄD)NZýë ¿s›åe^l|ZÓÞæ1–âÖ¬I`ömÒš©f­Ÿf*MS Ð4 T•‰r?¦Ý»Ünd§sÜþÏ\¿ž?ù_ÿ wq±¸×…uu,ùÒ—ÒŸ&“'Ùñ_ÿ+Çžx‚¤ª¢÷d}D pjàN{DŸ€Íxh(R¦°ŽQwÄad¢óÚ D·Ì&ë ‡,éðlެB¡–¡ ÍxØhIPãPôQ‘™Yú"Œ%©0Ý»YÏ3óõ¼óFœÜGBimm娱c¨ªÊ’%K2£GÒÞÞNii©P@@pɧ9wV—lå »d¦ Õ&øN¶+À]¿ù hm¯¿ÀÔ5kð76’WZ:é"zÞŠ q"‚ËŒìp°î'?I/wAí#gÎÐþæ›9¿óñÿù?)›?Ÿx0ÈÓŸúTzd!a1z˜.Pf©!§¦×î‘ ÆÓ‘4Ú›±cf,™zbÆX1Ÿ;Ù…=M÷¬„E1²†¬Ø-Ï3k†òd8|EûeQ@:D,ÃívsàÀ~øaؽ{w†¢ñÖ[oQ\\L `Μ9äççsøðaöïß/î@ |`¢èÖÇôËÎí&¿²’ÀéÓ9Ðc'ü ÊÆ…rçÏ~Fù‚Øìv$<ô8ÁUŒÍáÈHÖ`Îkš†–JÑj¸EÎ\¿>ÝF²Û‘$]|$‘ÈèïÈæÍ¼þwG$ÈpùÌvý´8c»“bÏR8ÒEC³öÝT,&2¬X *ç*ꫬ¤aãÆ«O©®®Áï jóùòI¥b¶÷x<Øl6\.N§“D"A*•Ân×.ãóù$‰;3®®.:ÄM7ÝÄ‚ X°`Aº¯Gs$à\4Þsÿ뿦—e—‹¼ÒRBgÏNøWAµµâà $IBr8hüԧΫÀXYø…/0ÔÒÂîï}/-ð+LofÍv§L LX•†š5kHÅãtïß?n„·¸¾žÃjßœÓÝ4[IYñwÇ’ÿüŸñ_áØ²I) š¦ éõ‰±XŒššjŠ‹õ˜‡Ã™Ñ¾Á° ™ó¿ýíoq¹\Ükú—ù~øÃrË-·ðÔSOa³Ù¸ë®»ÄÕ.‚K‚»¸8§«“È%.7Ëþöo™²d C'NйsgÎ6J2IÛk¯åÜæôz©¹õÖ ûwõŸüdz9¯¢‚™ëד_UEõªUTÝtý‡óîÏÎhooÆ÷+—.Å[QÁÌ XòWõ¡£I) ½½½44Ì$‹ …)..ÁçóQ\œO4ctt”’’¢ ¿ÿàƒf,ÿð‡?`Ö¬YÌÙ<@E2™ä…^`úôé,]º4c[,ãùçŸgþüùÌŸd<…@ \)|••ÌÞ´I_xäÂÝݼ÷‹_ŠÇHE"œ~íµœqj6·›òE‹Æ­Ÿ¹~=ÞŠ ÜEEçML1{Ó&foÚÄò¯} %–éµä..F6 ®~XLJQ”‘HMSH¾nƒƒ”––ÐÖÖÎ’%KÄÕ&‚KÆ /¼ÀÇ?þqöíÛGGGµר矞»ï¾›—_~™šš ÅW-M?Ϋ_þŒlÐ IDAT2ÑÁÁôº\ñ&ñÁAÞþÞ÷€Ìx´Ýƺ²ùóù‹Ã‡'õÛ«ò˜LJ)((Äår12¢¢¢·ÛƒÝî PZZ†Ýî¸l;ØÓÓÚ5k&Ü‹ÅH&“äç石Ÿþþ~ÊÎQ^>•J …(>Ïðüùúm>šmùùùé8¦ÚO(Âápà6*-оÄu/Ú\-×}aa!/YjW\*FFF(((ÀãñF3¶E"òòòp8$“IvíÚEKKKú½±oß¾s¾;.ä8\èý{¡ýNæ8~¯†¶åÿ&ÚŠ¶“m«©*ZC! ý}}”•—O®ßm%àÿäx¾] ÇáþáXo ØŸ/ÿ쟵?ûÑ×µ¡¡6mh¨MКšökí-ÚÐP›Ö×ת9sLëéiMO]]ÍZoo«68Ø® ¶kCCíZ0xV»üò—¿<çöãÇk»víºè~úûûµ^xá¢ûm>šm^xá­¿¿ÿ¢ûÙµk—vüøqqÝ‹6™ëþrñ‡?üAkmmÕ¶lÙ¢õööjš¦i?þ¸¦išöâ‹/jÚO<¡…Ãá|Lö8\èý{¡ý^Èq¾~¯†¶åÿ&ÚŠ¶¢íäH&ci=ãÏ~ôumùWïÒä•nýN2•àã‹VêC"v'Áà0N§§KÆf³át:e[z²ÛíȲ-]DÀf“q¹ò/¹ìàÁƒ,^¼xÂí.—‹ââbòòòÎÙßï§èÃPv»âââóZ”Ï×Ïdöy²ý\É6bŸ‹Î3 X@qq1²,_T?gΜ!//ÒÒÒ‹Ú§+}Ý‹ëãúÜçÉ\÷—‹úúz>̬Y³¨®®`ppºº:f͚ž}ûX¾|y烃ƒD"‘ ·­‹9&^¯—¢¢"\“ð¾~›››©©©9ïý|¡ý^®¶“¹N?È5t5ìïµv|ÅþŠý½Úö7ªªHèuF^{o/½Á¡+S ýb(((8çöó N&Ó¦M;çv§ÓIeeåE÷3™}žl?W²Øçss©® ǃÃá¸è¾®ôu/®ësŸ'sm\NnÍÊc]¾ãŽ;&üžÃáÀãñ\’{ÄJÉT#¿~½^洛¼ é÷rµÌuúA®¡«a¯µã+öWìïÕ¶¿“EúòÏþY‹DÃüð‹_ÀåòÑÞ~Ÿ·_¾ž^÷Ì™³D£1‹Ðâ ®.Ó²$Ë ª.z‡ž{î9–-[–³2úï~÷;>ö±Q>I¿9@ ¸Z™Ì³à÷¿ÿ=Ë–-ŸÎÁ¯ýkî¹çžqéñxœÇœ?ýÓ?ÔÈ…@ |ôõõñÆopÿý÷ÛvæÌ8À=÷ÜÃ[o½Å‰'®™çZ*'êà›¿þ)‡ÚOL€ŸAOІ4å6¤)·±ïD’wÞ;‘Þö裿åßÿý„㽃Ï>û,k×®eÏž=„³JÂoÞ¼™»ï¾›­[·Š«TpÍ>\ô1E ä:f²Ïº²²2zè!.\HÜHÝ(ϯ~õ+zè!žyæ™qÛ6oÞÌC=ÄæÍ›Å\3ï‰P(4.ù‚à£ÍÖ­[¹ûî»Ç=«Âá0{öìaíÚµ<û쳬^½š‡z»Ýަi×ìÿ”ræô þêþ±í¥§øômnY§WYŒD"¤R)>÷¹{ñxܽ3ÃÃÃãv»‰eå,ŽÅb“ò®F‚Á <ò---:tˆöövvíÚŶmÛåÉ'ŸL[4}&û¬“$ I’8rä‹rä„èhš†Íf;ç¶kùE-¸>èèèà‘G¡··—;w y饗ػw/£££<úè£iEðÑ$///ç;ÁívS\\Ìðð0’$100@QQѤ2ò]Ó HíŒFªk¦óóY¾ø7ÿˆ;Ï @këiZ[O“H$.I¢Ïç#“H$p:u÷¯·Þz Ð}ÕÍ$ÁµFaa!kÖ¬¡±±‘ÚÚZ:::hii¡½½¯|å+´¶¶²cÇq ®.äY×ÔÔĬY³>”@ðk•p8Ìûï¿/„àš¢¶¶–5kÖPQQAaa!Á`ÞÞ^ž}öY¾òÝM^¼'>ÚXß ttt¤ß ápŸÏè£%6l¸¦ÿëy³`ô „øÄgþIM²é?£À­á"TT”ÆXºtÑ%ɂըØÈ–-[¸á†¨ªªJßl .döìÙ<ù䓬]»ö¢"ñ‚‹S§Nqú´®°·´´à÷ûY°`Ñh”¢¢"êêê˜1c†8P×ò¬ëééW \Éœ9søÍo~ÃúõëÓÊÝñãÇihh`úôélÞ¼™OúÓ×´µPp}ðî»ï‰Dèìì$c³Ù˜6måååhšFccc:+œà£…ßïçå—_æ¾ûîC–eÚÛÛ‰ÅbÔÖÖb·ÛÙ¹s'÷Üs²,#Ë2×ÌË•kRAè±Xœ¸Òqª…¯õ“Üù©Ï1ÔßÃß}õKÀ0O=õ·ÞzGŽ4±rå2üþb¢Ñ(/¾¸‡Ã×ëÃçóÑÛÛ#Έ@ ¸"46ÎB’$q &I  ¯¯W@ \4uuÓ …F`ýú;Y³fåS@jg4ò·ü€ÿû;_åǿڊÝáLoûãwŒ \.//£ººšd2AGG'……⌂+‚ß_ÌÀ@Ÿ8“dhhP<£@pI(++Áé”)//#_\ºKVyøá/2½ª€Ûn¿·=*,Yr²,sæL'ùéö……E<·8@ Áu‚ªª¨j‚îî‰G×'¥€,˜]t±iÃ@å<æÎÀ¬Y33Úwwwc³Ùp:Äã± PàRÇ †Å˜$‰D¯7O@ \4©”ÂÐP€X,ŽÓi¿8äBðûýÜÿ½i·¬d2)›ÁÃf³±hÑq .àx‰g´@ .²,³bÅÒt,fqqáäEIáv»°Ûmè‡ËÊJ(++g@ @ ¸Nè±@÷@ˆ&˜ç˜Ãf?¿2<<‚¦ˆÆF‰Š¬¹@ àv Áàï¼óee¥¬X±”ý×ÿΚ5«xà{q»]é>B¡Ï=÷©TŠ{îÙÀŽ»bæÌ,X0—çžÛŠÇã6òÏÏW”@ @pb)™°4…ªšé<õþ)Å™¢ü‰'Q…Ù³RTTÈð°‘`*#ÓÐPO_ßCCCL™RAQQ¡¡€H(JUM¥û;{¶“ÆF½Þßààýý”••RRâÇëÍ£»»—††ýéß5ûÎ&§j²fÍ*Ö¬YźukikkçàÁC¼ðÂK45éÑí‰D‚ŠŠ2Ö¬YÅÃ?˜¡|œ:ÕN,3Ú&9~¼…‡~ÖÖS<÷ÜV~øA-Z(®$@ ` ôò¥Ï®åÛ_û<»ß|™;6|6½íí·÷ÓÙÙE08ÂÉ“§ÙºõU¶n}•­[_¥©é8==½ìÞ½-[~Ïèh„ææ“þíŸüägŒŽFغõ€Œ"¶±XŒ`p„-[^ÎøÝ‰˜pl$™Lòûßÿ›ÍÆœ9Ô××ññEêêj©¯¯£££€’?Û·ïâèQ]1ùå/ÿƒîî^Š‹‹˜9sõõué“)S*ؾ}ï¾ûž¸’@ ‚Ià/­àÿúže÷›¯pÇ]÷“çõ¥·56Îd``¶¶z{ût…e(@*¥hÜ~û­Ì›7‡`0ˆËåféÒEÔÕM›ôo²té"dy¼ÕK/½J[[{÷¾“^×××7a_F›ö³Ÿ&‹1eJyyyÄb1; Χ§§—¹sg°aßÐÖÖA]]-wßý ŠŠ q8¨ªŠ¢(Ô×O' pï½ÉÏÏçäÉÓÌ;›¼¼7oýý½ »ƒ$q¢D©©©×6§‰D9}ºü|å´¶ž¢¸¸’’¢Ñ==ýø¨ªªDQÎží¦¶vjú»O=õååe|âwdô{ìX3ÑhÇÃim=ņ ³ÏnaæÌx<¢Ñ(ÇŽ53gNnw0§ÓEYY)‡MS x<qÖ`’¨ª’.+˜˜`0˜6z àühšŠÇãÂç«"%ÎÙ.§ LQÂá0o¼±#Gš8xð}¶ly…—_þ?ÿù¯‡ÃlÙ¢WAŒÅâlÛ¶=ã‡ï¸ãc9¬­­ƒ3ê˜7o6ÇŸ •Rðù|¤R ÇŸ`Þ¼Ù̘QG[[GÎï——WPYYŽÝnCÓTq–@ ‚« EIáñ¸p:“W@þøÇttt²k×Û¤R)êñz½„Ã<7ܰ¯× €ÓédÅŠ¥éïz½^ÜnWF--­D£QJJü ÑÓÓÇ”)åm¦L)§§§ÁÁ¡ -N}}½œæ1a%ôóña)sç6¦ç8H[[{zÙf“ÉÏ/ £("-¯@ 䢪ªF¤à=ªªÐÓÓƒªŠÑu@ ÈEee5ý$“ Ë»¥šÕ«—‰De;.—“²lÙâœ}\–4¼fjÝ\lÛö&ÌŸ?'c½¢(üîwÏàt:Ù´énÞ}÷}š›O°|ù¦N­æ¹ç¶àóù¸ë®;±ÙlhšFii)’$‘Ÿ_€ß_L<åÈ‘c”––Š«C r0mZ ‰„p¿šˆ‘‘v»LAA‘8@ƒúúTUU' ™LR]] @këifÍš @ii o½õ67ÝtãäÇrèÐQÜn7+V,å7v`·Ë,_¾„‘‘ÍÍ'ðzó¸í¶[xå•×I¥R¬Y³ŠÎγ´µuÐÜÜÊ'>q==}¼úê6¾ð…? ³³‹h4Îèèè¸ß|üñgxðÁû ðê«Û ðàƒ÷ñÛß>ɾ}ïòàƒ÷qâÄ)öï—•+—!I~¿ßp¿ÒÐ4Eøë @ — —ËNMÍTB!]®?yò4^o'OžæàÁCôõ 0eJõõÓ3¾s¾¯oY¶RSSÍç>wûö½Ë믿 ÀîÝû8~¼…³g»سg§Owð¹ÏÝ—\/-õs×]w¦û:µŠY³.Éß–$Éd’XLXò@ ‚+M<£³³€úúé$ gò¹ÏÝÇí·ßÊÂ…óÆ)* ùù><ÝÝ}Äb1öî=À³Ïn¡¤ÄO}ýt<÷ß¿‰’?ee%x<>ýé»xöÙ-´¶ž ··ŸÇ&Ýoww¯½öG¶o‹öv½ÖÇ~ðcB¡·ß~+O=õ@bÓÐË,À6‹ÁìÆÈ’Bë•оÜýÜ5.ºè¢+ m ¸ýü>‰«sŽÞóêpÎyô¾Ïóðùèï¿M0’«@!„BˆÇ ¿ÿ6Ýݽw+]y½eÄb™\쎎N^zi[Þ}óVÁJ¥RD£*:ŽÞ^ÃÃ#¬^½“ÉD:BUcèõ: Ñh”T*Ùl"™L‹ÅQ=Š¢J¥I$âÙ\ÉdUÍ$¬ z½Ua0(h4b±&»o4Åb1߉°bhµZ%3kìÒ¥«¤Óšl›ãñ8étšH$ŠÓé«B!òp8\ HGÌ!ó S°Z-ÒB‘‡Û]Àððz½&ó.^^^×ûå9Ø÷­‚¥Õj³/þUUåx½¥ÙƒnÆ×™2…Óôz=z½~Æq49õuºÜ}œ¨iæ¶Z­&gÛ™Û,]º“)ÿbxx„ññÜ¥ß3”FÒD„ßf©T‚âââœû½˜[:’ç†BÌHÄðx\9÷F¿·ÛöÀ¥Ë¿´ –ÑhÄhüj ½}{ˆ²²’‡ú^8áÂ…Ëlß¾€ææUULMùinnÉ›U022’íFƒÓéÂ`Pðùú1¹r„âŽÚÚe$“Rr6Ÿx« ‡À¦Më8xð}**¼ :::Ñjµ|òɧ¬_ÿ›xýõy;G«Õb³Ùp»Ýèõ:¦¦¦ˆD"€!Ä ©T‚dR•ŽÈû,Tï<<%Bˆ»2°ÊËK‰FcLLL’L&3ßI§H$î>Sz{{X´hÁƒ ï¿ÿ›ÎÎnvîÜÁ'Ÿœ§²²‡ÃÁÁƒ ¬[·†¶¶vþôOFOOáp„ææΟ¿Ì¶m›¹yó+W.g||œTênôöÛøÉO~ŒÍf ²²œŠŠò¼§¦ª1Ê˽„Bg¸q£#[†·¿€x<Á¼yUœ9óiÞ}Å@UU5:ÝÝŽB!„B<:&“—ËÅØØøCí—wòoOOýýèõ:œN'^o)==}Ì›W‰Ãaçùç7ãp8èîîåúõZZÚèíõ1~ Û·oÁl6366ƺukذamö¸;w¾š“3RZš;õ* sûöà¬ö8vüþáp(›˜H$ÑëuyO*ÑÖÖJÿm"‘¨\B!„BÒ/B1[:fbb’ÉÉ)b±8ƒ’M¯f||$»m4šŠoÞ2¼÷óá‡'yñÅmOuÇôõõST”;º †0 (Šä€!Ä݇C ¿J:bN§sVF!„ø6Ójõ¨j$çZ«Õa2é¿t$ä¾exïçi> “[r/“É ÀµkÍD"‘œ³X29)f³Ô}Ï'™L211JZjQ !¾e|Ò B1ƒÍæ ™L‰„³Ÿétz–/_š§ o:ïû£þ«6¢»»—yóªù~ŸÞÌõë™R»÷nwñâÚÛ;xá…ç±Ûm44¥¸¸—_ÞΙ3çèíõñê«/QPàÉ{좢ÌB)N§ —ËÉØØ(©”–²²B¹ªòèééÃétÈè‘B!Ä·\IIv»…`0ÄääÑh£Ñ„ÅbA§3JųÛöööQ^^ú`È7¹té*v»—^ÚFSÓ Âá›7¯§££‹ÑÑ1ìv;ëÖ=Ç/~ñK6n\Ë®]opíÚŒŒŒb4xùåíìßUUyíµWøâ‹6z{û¨ªªÄë-åþáÿ²}ûvíz€ú§_ñgößf -ìÞ]Çž=ûf 7ntP_ÿCþíß~F£á­·þ3.\æâÅ+øýA~ô£]üû¿ïçÇ?þá¬sÓétÙÀC¯—¸„B!„xét «ÕŒÕjFUŒÝù<wæE@¯`·ÛQÕápðÝßµµËH&¿þ$ÛÚÚ$—TÈ}ížûšÅbE§ËÌzš‡1t€ÄãqÒéÌúf³‰p8B2™ÄjµL&Q…x<Ž¢(„BaR©6›•D"A2™B£ÑpöìyV­ZŽÍfÃn·‰D1™Œh4›X°à›øþ÷_ÏiCccK–,äðᨨ(' X¹r§OŸcñâ?þ1‡ýNÒÁ–-p¹œ_Úq:›Í†ÛíFQô ‘JiI§ŸÞ¿Åã*Á`€Â¹ò…âB«Õ`µš°X*‡£LLÜš Ñh9vì£lrï³VUcèõzL&cvÊðô¨I2™äwâñ¸fqéî³EчioïÈó¬Õ Óéq»Ý8v´Z ­­70¾é‹.¦˳|rr’ÂB\àBîk÷Ü×Ò鉄:ã~ÔÅ¢E ,9uê,}}ýD£*/½ô»„+W>ŸÕ†p8’ýÞÄÄ»w×qóf'==}¨jŒ+–±gÏ>‡Ù½»Žóç/122ö¥ˆÑh¢ªªjF ^Y\O!Ä×K£«Õ„^_Äèh¦\¥Åb¦¸83xppˆ#GŽeŸµ×®5³dÉ"z{}üùŸÿ1Á`ˆþçÿÏ_ýÕ_™Y[·nà‹/Úfý¬ÖÖ¬_ÿ<7{öì˜õ¬u8œÌ›W…V«‘_Žâ‘Ý×8ˆÉ÷¡Ífeóæ üáþ˜t:Ï7@0Äét°fÍ*šš>¤ ÀÃøøCC#ƒÁì‹ÿ®]oð“Ÿü€_ÜÊo¼NOOf%ÙŸþ´«uîÕÆUUebbv"øtÒ»ªª™üŽT*…N§Åd2¢ª*ñxâ’¤c1•ŽŽ[ ËüW!„M8¦³³3ï¡@ ”ó¬­¨(çÍ7wf§IY­~úÓúìö›Í–sŒ±±qâñ8fsæ™ †°Û­yÛ ¸u«“ááQ’IÉïB<úûÚýä}c/,,Àf³b4©¬,§¶v1ªª²lÙ³8vº»{X»v êM$,[V›f6›ñz˸pá §OŸã•W¶pàÀ!þàÞÂfËÜŸ~{÷îãùç7àó píZ3¿÷{ßcýú5ìÝ»W^ÙŽÇã¡¡án·‹^ØŠ^¯ãw~믾„Ùl¢¡á(^oé­ÈžN§Q=¡PˆÉÉIÌfó}“Ö…Bˆ¯Âï011I$Á`PÐÞIehh˜“'ϰnÝšœgí´gž©¾ópàÀ!~þó?Êî{øp~€êê6ž}v MìØñ"Û·oáèÑ㨪Êo줷חó¬…Ìñ´Z-““SŒŽŽQRR$¿(!ÄW¾¯ 011šÝ.‰æÝ?oÞße]]½”””æ$~—ËÅÀÀí§ºín·“É$W½B|Cèt ‘H('·B«Õa±H¥žÜÈí[=”••ÍxfFP¾éy Ñh,g>ú×ÅjµdsP…ûÚÝûZ2™È.D™ÅÁ§s¿áKÊð>ƒƒ¿]µ’’<žB¦Ï'•J NÑ×ןs’sñùzg}öMXdttX®z!„D¾g¡Ï”Žy~¿Šß?!!ž f³™ÊÊòÇú3FÛ¬ÏR©ä¬€c.s ÇŽ}Äääo¾™¾˜?¿Ÿo€÷ß?ÊŸüÉ ¿ÿ6ååeÝð`0˜7+þAèõ™)SÓYöíí8JKKò–#ü*í¹&'§På¾¹ççÎ]dݺç°Z­|öÙuE¡´´‡ÃN[ÛMV¬XÊÈÈ(÷w¿`bb’Å‹ÐÜÜʉ'³K²ww÷püøÇÔÔTc4Ø·ï 55óP%gåóù—½´´´qóæ-Š‹‹8x°ŽŽ[ÔÔÌË»ŽˆV«ÏFZ@vÕöér…¼Ç³Ï.2sgO:Cmíb:;»ill¢¿€gž©É©ÒÚÚNSÓ †††)/÷òÞ{\¹r ¯·ŒööŽì¹UWWæ´gttœ_ýê_Ù°aí¬¶ž:u–3gΑJ¥Ð땜sûè£Ó|úéEE¡¨(·¼nkk;ÇŽ}8«>|<çðá&.]ºJA‡þþÛs¶ùÞ…!|ŸH$BYYiÎç@ýûߥµõÏ<3sç.ÎÙf£ÑÀ{ïaéÒZù/„Bñ„iµú':¥3·-: •T*I*•¤««+g¾cŸghj<¬O?½È§Ÿ^Äh4b6›Ø±ãEš›[gmWTTȆ k©¯¯Ãh4ÒÐpNGCÃ**¼?~’úú:®_o`ùò¥Ù•Çgzýõl܏޲²RŽ=N}}Ë—/ãÚµë¿ulÙ²1ûõÉ“gضm gÏ^ ¾¾€©©©œ}._þŒúú:††F¸ví:Ë—/£¾¾Ž£GÓÜÜJ}}]v4h¦ööŽìjá÷êíõQ__Gssë¬s¡¾¾ŽË—?ËÙGUUÂá0©ÔìÁÝÝ}””Q__ÇG¾o›gòùp:y+:ÔH}}¯¼ò'Ož¹o›E!“êaB!„O[ ¢×›ÐëèõF4…pxvxgg7×®5óöÛèììÎùÞÌýõz#¡š³ß£’w Ö† kéè袢 @[ÛMzzz‰FU¢Ñ(==½tw÷2o^.—“Ë—?Ãf³2o^555Õlܸ€ââLUM›ÖÝyù?OUUŬr¹¡PˆÁÁa6mZ÷À'7::Âðp&'bf²Ë´ÇYÑãaÚý ŒF#kÖ¬¢µµý‘³¢ÂK$e||\þ‡ !„BüŽÑh´$“jö½8UÉÎÜéîîejjŠë×[4o½µ‹#Gš(,,˜QT!3«¿¿/›2qöìR©ѨʲeµÙ? ;,xæ¡Ú:ç¬êêÊìt¦P(ÌÂ…óñxܤÓi**¼X­Vìvóç×Y¸p>55ÕÄãqV«%çÓ‰ÛíD«ÕæLÁúû¿ÿß ƒƒClÞ¼žwß=Ìèè[·nÌ;b¢Õê±ZíQTTŒ¢ˆÇc9S°f*++áãϰdÉ",3GŽÃ`0²lY-Z­–¿üË¿áÕW_D«Í¬J[XXÀúõk8}úW¯~ÎŽ/`0øè£S”——QSSsü††#œ;wX,ÆâÅ iii£¡á«W¯dllœ³gÏS[»ˆçž[‘sn##cœ?‰U«–gƒ5ÈŒ€¼óÎo¸rå³l=øýûá÷¨­]ÄÕ«ŸsùòglÛ¶ ·Û5g›­Ö»õß}¾:L{{^o›¿ýÛÿÅsÏ­dÑ¢8pˆîî^^~y;@pÎ6kµZÚÚÚsÊD !„Bˆ'cz –V«ËÉ¿H$’„B¡ìZ}¿þõ»TUUréÒU@CGÇ-âñÏ=·2›8~ït®™ïë/^Áf³â÷ûñûƒ˜Í&ZZÚ0 TTd’à‡‡Çñù|Œ366ŽªÆr¦§`=±2¼íí< Ýd2Í™„Þ×磲²B®Ò¯h||ƒÁ]ËE!„B<9ÓIè:T*ž3244œÙ³g¿ÿû?àÿñW²{w~xŠ%Káõ–æ+ßûúž=ûؽ»Ž›7;Çh4¢(ú‡Ê ~âex c6xXétzV‰/N‡¢˜æÖæ³fͲ²²rss;tèPÇû \³fMLLŒÝgŸ}¸nݺ—_~ÙÒÒÒ××÷—_~ùõ×_ƒ‚‚,,,"##ëêê´‡˜7ož½½½••ÕÔ©S+++µ{ûàƒ¦NêèèØúèáááŸ~ú©æ{•JµfÍWWW‹Åçó>LD{öìáñxL&ÓÑÑqæÌ™ø Tîüö[š2…ÜÝ)9™bc©ªŠd2‰èóÏiÙ²ô‰§OÐn155ݸq£L&KII9þü|ðX›öÙgÏ>ûì¥K—fÍš5{ö솆†Ž÷¹eË–+VÔÖÖ.Y²„ˆ6lØ  /^¼øôÓO¿þúëñññÿú׿Μ9SZZúÑGi6™?þ™3gD"Ñùóçëêêþüç?k›~ñÅ wîÜY·nöè­-Y²ä›o¾ÙºukQQÑW_}eiiyóæÍ¿üå/ï½÷^iiééÓ§###ñx"”J*,¤cÇhãFZ¼˜„BârÉÉéAî,)¡”zí5²±1Ô P÷++«ž:VÇÈ9zô(ÇÓ|öÉ'Ÿ´ÿ¾µÑ£GÏŸ?_ó½J¥b³Ù'Nœè`Ÿ£G^°`ÎÍ% >|Xó211188X­VWUU™˜˜¤§§k–—••1Œ3gÎh6×îÍÎÎNstíÙÖÔÔ0™ÌcÇŽµ>Ÿ+W®0™Ìêêj5Þ{Æ o(j©TšªÞ°A½h‘ú…ÔÞÞj µ··ú…Ô‹©7lP§¦ª¥RµBa4Õ[m@åryë—š^ðýLvvöÊ•+/]ºÔÔÔDD6ùW†¶»©©©£££¦Þ¼ƒ}úøøèÜÜÉÉ©ÍKÍ® ZZZÆŽ«Y>|øpWWW‰D¢Yâéé©Ý•­­­¶Ö^C"‘¨TªðððÖ Ahh(Ç‹‰‰yþùç§OŸnii‰¿Az°\³}Ÿ¡ŠŠGz£N;Îî@|555Mš4é…^())iii9qâÄ}=Ê:¸õ&&m \;Þ'óÑ‘^ÛlÞúeë‚a}Ñ¿ÍòΔ%›˜˜dddìß¿ßÅÅeíÚµúÓŸñIè&mÛM6›¢¢èßÿ&™Œ¸\Z²„ÒÒ¨¾Þ@Ûqv‡Ñ÷‚RcÖÖÖ._¾Ü‚ˆ®\¹bhû1b„‰‰‰X,Öd–———••ùúúvf[@Àd2³²²„Ba› :qâĉ'®Y³ÆÞÞ^,GDDà?€®åNM_õ¬, £ØXÚ½Û€[m"€777ssó£GNŸ>]&“%&&Ú>9Î+¯¼—””dii¹dÉ’€€€àààÎlkoo?þü |õÕW~~~R©T¥R988œÝ“ŸOii”šJ§N=2­%ŸO<98HôHG¢§Ÿ¦>¢ìlZ¿žfÌ þ8%(àñèir9¥§“HD"‘PHB!ED›­wm—öÇiõjJHèhe@@¢V…çÎQp0ÅÄPT=:ÌS«Qê‰ €ŠÇ@¿.v(àñ芖Ú¼™–/§gŸíba'tzÁÀ€#“ÑܹDD q¹¸} ÑÀÒÒB›6ÑØ±ôÒK”™‰ô‰ÚO±ÙìÌÌÌÎ/ï%Ÿþù¹Ø¾9ôã ÿôÓOñù0: åæÒþýôþûK1Äå’PH‹ÓÆtì’R©c[™ŒÂÃéàA:{––.%ä 'Uð0@ …B???ÜC¦sì÷Š òô$__(6–ÞŸ<=©²ò÷ÕD"’ɨ¸˜îß×±Ï).ÑŒàoM…™™Y?;tBBÞYäoì÷èhâñÈÃX¬¶›ðxÄãQt4nžq@þïºÆÆÆyóæÙÛÛ[YYM:µ²²R³¼®®núôéƒ òööNIIÑ®¯oy|ðÁÔ©SÝÜÜ:¤YîááqàÀíjl6ûôéÓšõ×­[÷òË/[ZZúúúþòË/¿þúkPP……Eddd]]v“ÚÚÚ©S§ZZZzyy>|X³P¥R­ZµÊÅÅÅÜÜ<88øÜ¹sÚÓX³fMLLŒÝgŸ}¦oµN^Tccã¬Y³¬¬¬Z_QRRÒ¨Q£ÌÍÍ,Xp÷î]‡îäê{;ôÝÏÖUð*•jÍš5®®®,‹ÏçknΞ={x<“Étttœ9s&>ð½J.§Ã‡iáBòô¤¨(’J).ŽîÜyP¢ùùç´lÙƒÚ>}‚ñQ÷‰î«ÏNòqÍœ9säÈ‘b±877w„ £GniiQ«Õ±±±þþþ999—/_ e2™'Nœè`y£Gvrr‹ÅjµzÏž=l6»¾¾^­V»»»'''kW³²²:uê”vý;v\½zuæÌ™>>>&LÈÈÈøå—_FŒ±bÅ ínmmmwìØQ^^þñdzX¬üü|µZ7vìX±X\\\¼nÝ:{{ûêêjÍúvvv™™™jµZ.—ë[­3¥9í[·¬ZµJ{E»víJOO/--=yò¤¿¿ëSm}èN^ ¾·Cßý ûä“O4Û.\¸ÐÍÍíØ±c¥¥¥?ýôÓ7˜LæîÝ»+**$IRR’Ú8ìã QW§Þ³Gýâ‹j6[¡NLT_½Š»Òÿ%ê­ªªª211IOO×¼,++c0gΜÑ,?}ú´f¹X,&¢'Nè[®3€ÆÇÇk_ÚÙÙiVë €ÎŸ?_³P"‘ÑáÇ5/ƒƒƒµ»}ùå—µ›?~ÅŠµµµ,«  @»<((hçΚõ,X Y¨oµN^Të3T©Tl6»ý:GåñxÚõµ‡îäê{;:¸ŸÚZSSÃd2;Öú|®\¹Âd25!Û¸ŸpP0ìÜig§~ñEõž=êº:Ü•Uð]TPPÐÒÒ2vìXÍËáÇ»ººJ$M±bpp°¶þ×ÔÔ”ˆô-ß¿?ó¡‚‚ÍO===µ²µµm]®“¶3““S›—­· Ò~?f̉D"‘H”Jåˆ#]¸pA[yíóp@^}«é»¨ÎÐÔÔÔÑÑQsVÙÙÙãÇ·²²b0“&Mºuë–v}ŸGÇþà Ô÷vtæ~J$•JÞz¡@  åñx³fÍÚ½{wSS>ó=eÛ6:”’“)6–JJ(%…^{llpctBꆮÙ^MLL´9ÌÔÔTû½ÎåQQQ¹¹¹mrR›Ýjʱt.Ôî¹Í è\­½––"jhh`ëšqŒÉdv¼ÚéÓ§õ]lû{Òæä›šš&Mšôî»ï¦¤¤8::feeMš4©ý¡ëz&ßíàÖécbb’‘‘‘‘‘qüøñµk×~øá‡/^´²²Âg ;îÜ¡ù󩤄.]¢#p?.ã/U«{ë_‡FŒabb¢©t&¢òòò²²2___µZ­-Ë,,,T(D¤o¹µµµÏCw÷¶±±ÑÝݺu« er.\Ð~þüy@ ˜Læ?þØñ†úVÓwQQXXX[[»|ùr‡Ã`0®\¹ÒO¾·£3Ûj®.++«}8qâúõë/]ºTTT¤Ý9À@V_Oß~KS¦ƒA'Ò† ”ŸßÙmÓÓÉߟ¸\:{麄Ãá¼òÊ+qqq.\ÈËË›={v@@@pp0‡Ã™:uêªU«š›› ÅêÕ«5Åoú–w^xxøž={îÝ»wïÞ½+V˜<þf?þøcRRREEÅ'Ÿ|rîܹ¿üå/öööï¼óÎâÅ‹øá‡òòò‹/®Y³F[s­¥oµî\”›››¹¹ùÑ£G‰H&“%&&öÆÛÑ™míííçÏŸ¿`Á‘HT^^®é„ôóÏ?'&&^½zµ²²rÿþýjµºu=>À€ÍîîªÎ+*(.ޤRŠŠ"OOZ¸&¹\÷æ ­XAsæÐ®]ô¯ÑÙ@û…­[·GFFŽ3ÆÚÚú¿ÿý¯&~mÛ¶ˆ\]]ýýý'Nœhii©Y_ßòNzÿý÷-,,œ„Bá Aƒ÷„ÿú׿¦¤¤p¹Ü/¾øbß¾}šv–‰‰‰ï¼óN||¼§§gttôµk×8Nûmõ­Ö勲··ß¹sg||¼››Ûœ9s–/_ÞKoGglÚ´éÕW_;w®§§çÂ… ›››ÙlvjjêØ±cÝÜÜ>ýôÓo¿ýÖËË Ÿy”J*,¤cÇhãFZ¼˜„BârÉÉ©m“ÍaÃèÅéË/éúuJK#>Ÿ6o&GG3åæÒر$“QNEDà£3íázà0 u®íÎmûæ$úáŽÇ:Ìš:çrqù}ìw>_ïØïÜáµk´u+ÍŸû   0PÕ×Ó‘#”œLiiÌ3ôXYðø@gsgV……Ql,MžŒÁ¿A@ Èå´~=mÚDÈ`0(@¿¥VÓÞ½”@¡¡”—Gnn¸%€ ½F,¦øx"¢}û($÷@ ×”–RBegÓúõ4c=æÀÓ½ã€ôùù´aMœH|>yyQ^Íœ‰ô †úõŽÇ ¿“Ë)=D"‰ˆˆ„B )"‚ØlÜ0\(è?ÿüóÞ> ›ÍÎÌÌ|"‡~\áááŸ~ú)>ЗtN>Ä`лïÒ­[z·ÊÉ¡7ߤ!Chófâó)-®_§/¿¤_DúC‡6  …~~~¸Ð{Yó'ŠŽ& ¢ÄDhölZ¹’† y°•ŠRRhóf**¢E‹¨¤„tÍ  € ý”B¡033ëg‡NHHÀ; ½¡¥…6o¦eËÈÛ»mÖÔ7ùPb"­\Iü †¾ù&9B[¶—ÅÅÑ”)Äįq0N½UÏf³­ôË{§R©V­Zåââbnn|îÜ9"Ú¸q£@ hõ—®ÒÑÑ1%%EßúDøÁL:ÕÑÑÑÍÍíСC:§o5´¾ó§OŸÖ¬¿nݺ—_~ÙÒÒÒ××÷—_~ùõ×_ƒ‚‚,,,"##ëêê´›ÔÖÖN:ÕÒÒÒËËëðáÃ\f·kÖ¬‰‰‰±³³ûì³Ïô­VWW7}úôAƒy{{k._§ÆÆÆY³fYYYµ¾¢¤¤¤Q£F™››;::.X°àîÝ»:ÝÉ lllœ7ož½½½••ÕÔ©S+++;¾Ÿ­«àU*Õš5k\]]Y,ŸÏ×Üœ={öðx<&“éèè8sæLü'!“Qx8t'/pæÌ™#Gދʹ¹&L=ztKKK÷3,,ì“O>Ñl»páB77·cÇŽ•––fddüôÓO7nÜ`2™»wﮨ¨H$IIIjÃf°ÀÀqÿ¾zãF5‡£Þ¸Q}ÿ~·vÕÒ‚Û ý„ÑÐ_ßv륟Umm-‹Å*((Ð. Ú¹s§Z­~öÙg׬Y£YøÆo¼ñƯ?zôèøøxír;;»öY­ƒÕ: óçÏ×,”H$DtøðaÍËÄÄÄàà`ín_~ùeíæãÇ_±bEÇg»`Á‚ŽoBUU•‰‰ÉéÓ§5 Åb1é  Ú3T©Tl6»ý:GåñxÚõµ‡îäjÎ$==]³¼¬¬ŒÁ`œ9s¦ƒû©  555L&óرc­ÏçÊ•+L&S²ã Gx¢ ÕÏ<£~æua!n ,-JÅÝŠüß~>róÈgÅ[ßÎÿà¹[Çþ­ý)zÁw‘D"Q*•#FŒÐ63¸pႦz÷•W^Ù¿?577>|xÆŒ¯ODžžžÚ=ÛÚÚÖÕÕíß¿ŸùPAA¾Õ:>Img''§6/[o¤ý~̘1‰¤ã³õññéø&hÊPƒƒƒµ•ݦ¦¦Ÿ¡©©©£££æ¬²³³ÇoeeÅ`0&Mšt«UPí¡;y---cÇŽÕ,>|¸«««&­þáý”H$*•*<<¼õB@ÊãñfÍšµ{÷&< —Óš5Ä`èøÇãÑK/Qf&q¹¸O0 4ß¼V¾½hÓ«¹ïú–l{§îb*ÙĸÏÿÂéù·µ«¡ýHµ´´QCC»ÝXÓ§O_²dINNNII “Éœ8qbÇëÓÃqR[·‹ˆŠŠÊÍÍm““Ú¯¦o¡†‰É#`´~©îplÈŽÏ–ù°Ù‘¾ÕNŸ>mbb¢ ¦¦¦úh›3T«ÕMMM“&Mz÷ÝwSRR³²²&MšÔþÐuúZ!wpëô111ÉÈÈÈÈÈ8~üøÚµk?üðË/ZYYá‰¨ÍØ~Ÿi½¤3­Ã@ EÍòüìIVC^&Yû†sÂçx¼½ÍÄ\ïïG£ £¾,y"ÇL&óÇ|饗ÚühðàÁ&LØ¿qqñ´iÓX,VÇëëdmmݦ´OmÑÝ­[·ºP&wáÂí÷çÏŸ7n\'ÏVßj>>>jµº  @s ……… …¢“'SXXX[[»|ùr "ºråJwÞ¦#F˜˜˜ˆÅbMAfyyyYY™¯¯oçß⬬,¡PØ&ƒNœ8qâĉkÖ¬±··‹Åøß`ÂLëÐÏÿ¾º¯RÜ)SÜ.n¾]Ô|»XQUÒ\U¬¼S®n¹ß~e¶O¨ßsœ s͇zwfç(í"{{ûwÞygñâÅ&&&AAA·oß>tèЫ¯¾ªé?cÆŒþóŸÕÕÕÚà¯ßááá{öìyíµ×ˆhÅŠm ;ãÇLJJzá…¾ûî»sçÎmÛ¶­“gÛÁjS§N]µjÕ÷ßÏ`0V¯^Ýù‘ÜÜÜÌÍÍ=:}út™L–˜˜Ø›Ãáp^y啸¸¸¤¤$KKË%K–hÛüá[<þü |õÕW~~~R©T¥R988œfZ‡’,ÍœÜÍ<ÌœÜÍ{Øø=g6ØÃÌÑ•aÚé´ë9N|||EE…££ã„ 8Çž6mÚÂ… Z· ì`ýîxÿý÷_{í5gggggç¿ÿýï|Ü=üõ¯MIIY´hÑСC÷íÛ§)¶ìäÙê[mÛ¶mo¾ù¦««+‡ÃY¶lÙ±cÇ:ŸìwîÜÿî»ïº¹¹-_¾|ÅŠݹ?[·n]¶lYdd¤B¡xþùç¿ùæ›Î§áM›6ÙÚÚÎ;·ªªÊËËëÓO?e³Ù©©©ÿøÇ?är9ŸÏÿöÛo½¼¼ð,£ö3XÆÅÑîÝtâ%'ÓâÅF±±$RMMÛq㋊hÕ*ÚºqfÍÚ›,»¡½”,; sÁôgx|HÏäCeeôÌ3CQQÔ¾ÅS}=9BÉÉtøð#ãÆóùð„ã¦JÙ|»èÞÂæÒ{7 ïUJwÊZgMóÁ^}Ÿ5@@ú³œÚ¼™’’tü!ŒÑÝrÉ;kÎìïü&æC¹ÃøΤÁÆCFüK î…jÕM›üBJ»XSwOÇôH#GŽôõõš¯|>ßìácŒ € ðdÈå´~=}ôyyaŒ$0,:ÇoWT•´žH3¦&ÓÊ®!/«öbj£Tlű ˆ±5ÑÔ ›†èL–ÅT|ŸÚ†HïkÄ•=øÇ—¯<ŠésP®»û­€ë  >ŸÏãñ<<zôh뙢úìÐýþ0‚ßîjÚ»—(4”Š‹ÉÍ ·úÚX¶Ÿ…’e7TY{S›Jò²4©ÔæéH»€×9 0wê.Ť å`n-‡[iÉ•QtNï¬Òã<«Åɽjð`™™Ù%…"óöíÌÊJrqùý¯Ãçüu8ŽÅ×íCíuB¡ÐÏÏ÷ï hˆÅOD´o…„à~À“ÉÚËÇ Žæƒ=Í{ZÓüºöϯÓu]Y“Èžj9TiI2¢³M”XMç•4ÜÜÜwøpMù‡Ö˜÷8Ð^þ(( êzÍžP+­Þ;ô€zzUi)%$Pv6­_O3fƒ[=“&õ•bêdÈ–§¯hÓ³y˜oÕ`Ì,ö’âýÌf~&1ìtdÍÁ,×ɉËår¹Ü±|þ]ªFïuŸèαúì$×èÑ£"##‡îåå•’’¢]¾zõêèèh[[Û>ú(,,ì“O>Ñþè£>Š4h@ øùçŸsrrÍÍÍŸþùÚÚZÍjJ¥òoûÛ°aÃÌÌÌÆŒ#‹õÀûï¿?eÊWW׃j–»»»'''kW³²²:uêTç>zôèµk×N™2eРAžžžÚëÒwVm®Wßjµµµ/½ô’………——×?ü`eeuâĉöW´~ýú×_ÝÒÒ²õíØ±ã©§ž233sppxë­·ššštº“(—Ëß|óM;;;KKË)S¦TTTt|?[¿ƒJ¥rõêÕÇg2™<Oss¾ùæ.—kjjêàà0cÆ ƒú”ìãýLs³úÊõ¾}ê÷ÞSOŸ®9Rmjª&ÒñoõjuCnt‹ênÃoç~¸þå¼Üx¿ë_Îûíܪ»ýùS¥P+¤jiª:uƒzÃ"õ¢Ô/x«½-Ôn ·€ÛãsÆGíˆ{køÞ§,êY$!J&ú_¢—‰üˆÌˆ¼½½_xá…E‹mذ!55U*•*Š'ÿë ´;BU42 IDATÔÚÚúܹsjµúرcùùùšåvvv™™™š¬Ó&€:99íØ±ãêÕ«3gÎôññ™0aBFFÆ/¿ü2bĈ+VhV‹‹‹;v¬X,...^·n½½}uuµÎprrÒ$¼={ö°ÙìúúúŽhgŽ>zôh[[Û;v”——üñÇ,Ks]úΪÍõê[-66Ößß?''çòåË¡¡¡L&SgurrÚºukAAÁªU«´W´k×®ôôôÒÒÒ“'Oúûû·>ÕÖ‡îäΜ9säÈ‘b±877w„ £Gniiéà~¶~.\èæævìØ±ÒÒÒŒŒŒŸ~úéÆL&s÷î݉$)) ”K—ÔsçªÍÌÔ#Gª§OW¿÷žzß>õ•+êæfÜèa÷nȪŽo»¶qæ•¥#ûkîüì9þÀø€5nnk‹C‡uu­¶¶®sp(‰Ž®øâ EM±\©ÑPa÷È¿Îйsçj_ …BMÄ=zô‚ ´ËÛÐùóçk¾—H$DtøðaÍËÄÄÄàà`MI!‹Å*((Ðî!((hçÎ:O >>^ûÒÎÎNé: xtÍj/¿ü²vóñãǯX±¢ƒ³j}½úV«ªª2119}ú´f¡X,&"T{†*•ŠÍf·_çèÑ£<O»~ë[Ý™ ÔœIzzºfyYYƒÁ8sæL÷SûÖÔÔ0™ÌcÇŽµ>Ÿ+W®0™L! €B?¦Tª““ÕÏ>«>\½nºª ·zÅý{òºœË¿[uuõ¸««Ç•·ª.çÇû÷äý#YšªMÛo½ ¢EŸÓ†e”MR)Xz’JD„:1Q}õª1¾³hÚ-­û¦<õÔSšÐCD>úGIÖnâääÔæe]]I$¥R9bĈÖ[UVVîß¿ÿÕW_Õ¼ÌËËÓ¬àéé©]ÇÖÖV³‡Îœ°¾£ki¿3fŒD"ÑwVm®Wßjš2Ôàà`Í’ÀÀ@SSÓŽÏÐÔÔÔÑÑQsVÙÙÙ+W®¼téRSSÙØØh×os«ÿð ZZZÆŽ«Y>|øpWWW‰D¢YÒñý”H$*•ªMÏ}@ÊãñbbbžþùéÓ§[ZZâÑcwë}ü1mØ@ÞÞmHb³éë¯1ý:ôB›@]#)«´âޱñ{Ž3a®ùPo£nÙŽçýoX2ü·Ñ-*•ê÷œRùûmÕÿÿ±‰‰‰¾—šòª––"jhh`?:Á\CCCnn®æ{mNb<Ú†_³ ;yt}ôU›ëÕ·ÚéÓ§MLL´¡ÓÔÔT_ms†jµº©©iÒ¤Iï¾ûnJJŠ££cVVÖ¤I“ôÝêN^ CO߇n]ohFFFFFÆñãÇ×®]ûá‡^¼xÑÊÊ Ouôüúkš=›ÊÊèîÝ߇ˆ‰H&£k×hî\L¿ÝŽ›*eóí¢{7 ›oHïÝ(¼W)UÜ)cÙ m3ò‘™£+ÃÔ ³Šu>>jµº  @s ……… …¢“'SXXX[[»|ùr "ºråJwnïˆ#LLLÄb±¦ ³¼¼¼¬¬Ì××·óoMVV–P(l“A'Nœ8qâÄ5kÖØÛÛ‹Å∈üv£Žž ò`9GÑѸ=ÐßÔ:‹6koš9ºZ ã[8ólb†Ä,3ìÅ`t9_ç;ž›9±ˆëD\îm›3ÕÕÿlÊ=Ø|sèïxŽÚo?~|ÇŽB¡pÏž=?ÿüsRRR÷÷iooÿÎ;ï,^¼ØÄÄ$((èöíÛ‡zõÕW‚ÎNÞ¾gÏž×^{ˆV¬XѦP°3~üñǤ¤¤^xá»ï¾;wîܶmÛ:yV¬6uêÔU«V}ÿý÷ cõêÕŒN¿âææfnn~ôèÑéÓ§Ëd²ÄÄÄîÜ^‡óÊ+¯ÄÅÅ%%%YZZ.Y²$ @Û6àßšùóç/X°à«¯¾òóó“J¥*•ÊÁÁáäÉ“QQQ¶¶¶"‘H­V·®Ç0Ðߣºf¿¼~–.}$ztRóÍk y'ês3äg:9¨»m¶Íš —dw¯TØ4¸Tü>3PôÙX\sòþ`ÞØòaÃÒN‰D¢ÔT" …ÓV®Ü¡³ qÀBí–¿þõ¯‡^¼xñСC÷íÛ×ÉÊ?”˜˜Èápâãã+**'L˜Àáp:¿ùûï¿ÿÚk¯9;;;;;ÿýï?xð`®+%%eÑ¢E­¯«“g¥oµmÛ¶½ùæ›®®®gÙ²eÇŽë|"ß¹sg||ü»ï¾ëææ¶|ùò+VtçönݺuÙ²e‘‘‘ …âùçŸÿæ›o:Ÿ†7mÚdkk;wîܪª*//¯O?ý”Íf§¦¦þãÿËå|>ÿÛo¿õòò£†)?ŸÒÒ(5•N"W×ß›™EGcöKxl-ÍòüìIVC^&Yû†sÂçx¼½ÍÄÜÈÚ ém²I.\µ7·È„›V}¡Ž7î-—?/©hi.¼_(UJeJ™è¾LÖ"+n)¾õ*]½ÚzŸ111K—.í©`Ðÿ`.ø®3Ìy#Œâñ>#—Sz:‰D$ …$RD¡,Úø½3?»ýŒç,Û!Š;emšlZyÚø=gí;ÁXº‘ž&›ƒ•ƒ9µËJK’QSNSõÙêæìŠ¿Ü»¿ˆ¨ˆh3Q ‘¦Ï‡··7÷¡.Oƒ  € ÆJ¡ ©”$ÊË{ðU*¥û÷u¬A11E(‹6Ú—bZ ¬xÁ*yM›&›Šªó¡\M“Msg¾…3ϸšl^,Iϯ9îºÚ¹Åó:ùæ‘@òà+_Jf:{%ÌKqqèm×KP`èt6Ù¬¨ OOòõ%€bcéý÷‰Ï§Ñ}ºK;ƒ¥x9çdúI‘H$‰¼•Ê·ÝÝÃärεkŒ‰)6–&O¦VsãiÛ´¤¤„ˆ^zé¥C‡µ^~ãÆ ÍßD2kÖ¬ÈÈÈÖð@—sgV……Ql,íÞß§ —‘NVÙÙñÛE÷C•µœªJËFýz¶©)±º:÷æÍ·||²ÙÿV*Y,…Jþ@uº~ý:q¹\ÍË×_}Ö¬YÝœ` Ëɡ͛éàA Gî=ÉòN¹º¥mÇÑ]_Ör×Á¹ÒÒYÚârånô¥Æ§m ©Ê•EyT$!:H´–è:QÑX"".ѳDï± rrB¥À  iiiDäááñȇ¬ÕÔçÐ*¥¤ÐæÍTTD‹‘LF3Ëô߬Y{Óè¦A¬¬ùUUÙÚ6:;«½GYúû;Íg:ÒÒÑ@{›ÍnllÄ=h¯ºš¶o§-[ÈË‹ââhÊbb¼~ín¹äΉ5gö·ÿ‘ÑÍKID …\Zz\R••×|QbQ”7¸êú°fóRÞЕ5Ý,-Ýð™€Ç  QQQDT\\ÜzaûžeÚ>òíu~ªÃþdíÚµï½÷ÞŒ3¾ûî;}w`Ù²e›6mÒ¾\°`Áþó|.ú¹œÖ¯§ÿ›bcéÈ kÝÏ©[Tõ9?UgîRT—:†½!øä“í`\—ðHÑæodõe¬’ ‡»ž&æ¾ §÷ÝŸºêg¶­¦l i5<Øó†sc±5¡g¨§§'Éd2ÍË={öÑSO=…Û×]»v­_¿þ‹/¾øßÿýß+V|òÉ'úÖŒŽŽþðÃ5ßsPП²ˆšö ¥Ü\rïe#×ñd•&æV¿‰ÜÉÚmÆqã„ϱñd˜z)·Þ‘í¸%,îϵÜV´CoÄGߘ´³§’““·de………ÅÆ.ùrÃd´\†®j;DËO?ý´k×®Ó§O—••=šÏç/[¶l̘1†©½ÀÀÀI“&ýúë¯'Ož´²²Ú¸qã´iÓ4?‰D¯¼òÊ¡C‡"""®^½úÜsÏ­^½Zç¤Ë–-«®®Ödz€žÂ1 Ó“#“f » ($÷ÃX=Öd•ã^vœð—AÆy-ÚjôËM.1®J]jËÝ[ZW£óV£+Ç–øù]àpÎ××Ëd2™LVVV;y2r'ôBuww/--m½düøñ§N" D¯+€–––9r$88øÛo¿}ûí·+++­­­/^¼õý÷ß?÷Üsš5 &Nœøïÿ{êÔ©íhRRRss³µµõäÉ“íííñ¹P§>éðaòön;G‘‰ ýýï”Më×ÓŒ4 › ½ö“UZûN0ÌAŽtR*›Š+² «ÎH›rdŒk2«2§ºŠÁJ÷2æ0)ËôWå·q¼§F/“74J¥RÙC×®]óÆ îÐÇ´÷~ öRePoý×®&õÐgŸ}611QóÒÞÞþ‡~¬£:t¨¥¥ÅÃã°°ðoû›»»{VV>—€jà¹S;l§PH55mgi¿vV¯¦„ŒThĹӘ&«Ô“5]n³¸U¶ÜFç¡ Cš‹˜¹§oeý_á³ÏF  :av‹¦u¬†­­m]]ÝãîA[kèåårùòåQ£FáÞíœìçÎQDDÛa;‰Ç#L4mtô êní;Á. ÆuΆ'ž;ÛÏ$%é}j;2(±ÈÛ„Å5±å2œ¹jïè–—x-ã8wŸ>yé¬H$J‰ˆ„BáœWßþfGh?Цo{7‹šˆ¨¼¼à‰k?'{\¥¤ P³eMCz³³se²Ìœ<´m>þ'=}å—_^#å5ªþ‘ª‰®¥hö³téRŒß =ÿß õŸêÅ‹/‘‹‹ >—OJëÂNÍœìK—búcû½ R6ß.ºw£°ù†ôÞÂ{•RÅ2ÃÏš¿Oƒ~Û&úŒï‡z*XÃÍÉw8 äëK ˆÏ'33MyÇÞ½{Þ}744TVRâ†þІ òòò¶oßNDo¿ýö¤I“†ªi:~üø§Ÿ~· /¡°ÓieÖ_þ?êt-“ùP®Å0¾…3Ï6 fHÌ2óÁ^ æ“é@Ó¾ý:]ÿ=k7š¢yÄsùͶvïAÕÑ£vâï•J¥ØÎî3¥òÛ†{|~ì”)mšlŠÅâøøx"Ú·o_FXPè¤k×®åääh¾¿sçμy󪫫ÿüç?ÿë_ÿÂýè½ ¹~==u÷(ì4ÐÜ©í d2;¦·<}ÉW@‚XŠ}ŸÞ÷l^•}¡êÌ™¦œƵ“V7n˜×Õ1•ÊâAƒrÝÝo …ÖAA|>ÿ¯<Þ‡"‘(99yñâÅaaa±±±O?ýôG}”½~ýú3f00Â-£ïx|þPëáׯǀðöîtØÈ0;¡ÿq5:qùÄço˜œsãxVUVVóÅ‹EEƒ«ª†57ßf±NVéméïï4nœKh(ËÒRßáêëë9’œœ|øðáÕ«W'$$ / €"€ €4 oèYóÑÎ@šY… gnt½YS9˜[ËáVZreÄÏiâ­öÈ®`Ý»ß~Eææ·œîyy™8……¹MœhÖÕø¨V«Qê    ­´”0 |_SÕWßþéËêôí:Ú~KÃÉšô‡M6oÛðÏTó~Èõ8ø k¨ëÃe6gª«ÈÍ=øË/C]]1~;(è@y|”J*.n; |Q­Z…áû:zþ&>`2}päB¦ Ç ?3ÔdSó•/f–~ê‘NjBacHÈq±X$‰D"" …B¡0"£l €@?}|tfÍŠ rqi;%¦‡¡ì Ñ“º]žN”J”F”ßj¡f”ͨ¨(Œ² € ýùñ¹u‹>þ˜6m"OOd; »Éæru‹Ž–Žœˆy=uW£·Ïšço³»´©Fÿáҥឞ¾¾¾@ó•Ïç›™™áÀ îñÑDϯ¿¦Ù³iåJ2ïm/ÒÔw‚e?Ì›l¶–Oùi”–J©Ù”ý{5zÝpÁÖÓü÷ö˜¹´ý«EÎ᤟<‰jtPPPDÏ'Ÿ;µCoæH­ÉIžNé"‰HDDB IAlbëûèäçç§¥¥¥¦¦ž;w.88Õè  4€æäÐæÍ””¤û§ññˆž½¨ù浆¼õ¹M×sØ>¡Æ5ôf•=CÏÄPLEù¾¿Zäryzz: ;@@@I¥¢”Ú¼™ŠŠhÑ"š78¼i}¡¥¹QžŸÝ ÉjÈË$"kßpkAÛ'ÔÄÜÊ@ΰãvœÃ.7 ;}›w¶ztþ= ¥ŽÍ7}Lt«Õô@Eè´ºš¶o§-[ÈË‹ââhÊbbbà®êÚlélŸP¿ç¬}'˜õ~²çß¶h³á’ìî• ›Ïëä›GɃ¯|))†–°X?×Ö–°X!!#&M ™1ƒmoÏ((hG4µ£;vÐôéGþþx—º›;¨ÉfG3Xª½¹E&n‡ó¼Å55ŽO•U)Ú~tQŠ €Š €Ú•è‰îD]пgKw*5©\ó¿Î‡Þ¿¿ËÚš1ujdt4h €"€ €"zö®?¬F7Ê,;ÝdS4lXõÌ™óæ¡hÔ€(Þ'€.ëg\(7lxŒMГ½ãÜiÄÕèh² Ïšý£øÀp´.˼y²‹Ú|ä:gƒ‘U£?l²9áA“MùU…ú꣛Gøújšl¾rMx””€€¡EO”ev±Ž|„&›€ },?ŸÒÒ(5•Μ¡·ßFôì}}†¬¸c t䣇E›f°löö½Ð$ØŸËßšiÖ¬ãÿm4ÙPèar9¥§“HD"‘PHB!EDJ¸:›5ko²ì†HŸ¡Î÷FVÍþmÇnÆ޹¹W’‰¾®©±vqá>Äçóy<ž‡‡‹ÅÂ[ Ð´…çÎQp0ÅÄPT¡„KU}õ퟾¬ÎH2ã¸zÖ|Ø+#~NïlµGvëÞýö{Ȱ¶Î9R>a7 @ ðù|333¼×€ = …]Žž¿‰؇L¹ió„ç­§ú#t$™’Ó(ÍU9´mÖ<›5ØåaY'·ˆÉÜž•µ1%e˜»;Š6ú ;õÑöO—çg·zÓ„eQ•¾Ý@¢g½¢úÈíÉŒY޹aWb“iò×56Ö¿gMâó‰Ç#b±T*UJJÊæÍ›‹ŠŠ-Z4oÞ<‡ƒ·@ w¡°SýÓ­xÁ*yM›ÆŠªNļ¾žÔ­ÿvAVQÆ*)ãÜ}á¤Õó§½Ï)øí~æíÛ¢¢"Woï6åšl6û믿޲e‹——W\\Ü”)S˜L&@€ž§PTJ åå=øzý:…†¢°“Ô*eóí¢{7 ›oHïÝ(¼W)UÜ)³ò4ðþé.vÜ÷çZÏ" ù°«-û²Jœ†{úúú ÍWOOÏÊÊÊÂÂB©T*{èÚµksç΋‹ó÷÷Çs ÐC‘EIÅÅTXHRéÃÀ"£Š òô$__|åói ÷'ÑÖ­7^ûÙÌÑÕbß™gîÌ·pæ™öb0ŸLÛG…B.-=.©ÊÊk¾(±(Ê\u}X³Kqeþñ¥Ä+$bª9*‹ÍþOIÉ5K( …B ½   O€\Në×ÓG‘——ΆýþÔØï:«Ñ+îzVšûÞvÑènVj]pºæà·šu ½¡™UCo¨^l6»±±±ÍBP€ž¢VÓÞ½”@¡¡´~=¹¹ Ðûð{Ÿ¡‚3¤ë¶Ohß×­ÿa5:·„Åwá˜äè“–q*999+++,,,66vòäÉ666ø„hO% =G,¦øx"¢ ($dÀ]¾ÁÎi™Oùi”–J©§è”ó]Žs¥¥³´ÅåÊ]ޥƧm ”©ÄJJ%J#ÊoµÕ‹/¾ˆÜ   †«´”(;›Ö¯§3ˆÁèÿ—là}†ä$O§t‰D$Rݽ5(|OõìÃry3«ÊÖ¶ÑÙYííméïï4nœKh(ËÒŸaPãP_OGŽPr2¥§ÓÒ¥”ÐÿÇN2Ð>C¤’TB’<ÊÓ|½®.zªÈy̻ӿ©æ0Šø|ó_ô[ºÔjÈ|n@Œ8wfeQXÅÆÒäÉÔëi£ÏÐuòÍ#äÁW¾”òØõÏ<ãúÖ[^ÑÑøÐ €+M÷öM›("¢¿åÎS¨§o×ùSƒí34”)¸ZÐòùŸ‡¸y·z³¥tæÃ0,­»·çåõ«îí­§P|üË“šÇRG5:]wQÖN¡ÓÄ;«ô·°B|[¢¢þÉüèø!Í –Ň1ƒ%@÷¡À€ô×îí­£ç“šB]ÛE=›²=›‡ùV Q`:,ãÖˆôA—kÕmû ™ñõwßaKP€~Ë»·«ï«wÊÚÌ–®¼S®n¹ß~å'2…zë.ê¤T ¯º È#¾”Þ7sÈ#:]SÃðóLŸòÆ5r9f°@è·tΜYTD«VG÷öû÷ä —×^LmÈ;Á²fîäaæän>ØÃ|°—Ù`3GW†é()ÔÙŽ³ŒÊž©ò‰ÉbGý§Ä;Ÿ®º»Ë·^»2q"†Þ@@Y³¢‚\\ŒoæLmîl”Š­ø!v1Ö£&šZ<¼¬·ÏP«vœüœ&ÞÙjñÍZoL¡€ Ðÿi‡OJK#WW㞥];gÓõ¶OhßçÎ?ì3ô kž¿Möƒk9œJKKQNSÓÙêjñÍ›!Ï<ƒ)Ô@úî4öa; a<Îö}†23ßK Aæm~f%îmÖ<ûö`îC|>ŸÇãyxx°Œ(ì €"€t@gÝzYEEYîÔÝ‘è·J+S®ü-½j¯HuTd'&¥R(¶QF¬eÙ «Y`HPý–ZM{÷RB…†RI ¹¹ôÙªä55Ù{ïdí6ã¸qÂçØøG2LzøñÔ™5+¨B;¯ú°ËM§oóÎVÊW40K•îî61ö3‚Œr{@ècb1ÅÇíÛG!!–ŒuÎ~y§Â>dšÇ;Iƒ† zöpõT„Ž$Sr¥¹’ëƒÉ›nÛDŸqãýPïq°La­(aUý\[[Âb5†„Ü]8‰1cÆ0{{|Š —  ú›ÒRJH ìlZ¿žfÌ ÃPN¬g¿ÔæÎ,Ê £°XŠÖ>Óü}ªÃ‘ªIDATêèQ;±X©TŠíìŽ(•É55z晘˜˜¨¨(cg@@á Ò á¹k½ó%$ÄT™}3j’¾yÕ£Ò(6™&!›úkž4(×ÝýV@€uP&ºP€îFÏ'>z|£&õÆì—Ú’NÑ)Wr媽¹E&n‡ó¼Å55Ž[Îݲuõòõõš¯è´ F=u·ã¬½iæèÚ«£&µè’„BŽ-åU¯Yï|èPáýû»¬­S§FFGGDD° ¡ú‡ü|JK£ÔT:s†Þ~»ï¢g·ãÔN>t±ùâ‰['®š\mà4Xf“{*¥Ñ˜|âq‰Ü‰ŽV=sfà¼yhÇ   ÐcärJO'‘ˆD"""¡„BŠˆèõ¶žO¦§fŒ$u¹S­]Žrȹ†°R뉅¬€ŸëÍœ\4Ù‰ËÅI€Š ½B3KûÞ½4v,ÅÄPTõA1ßý{ò†ËÇk/¦Êó³-=ýû¢§r¨v<ÎaÆã¼WgaÝ2rä ÌH >ŸÐŽŒÆÃÕf–ö’’¾˜¥]›;¥b+~ˆ]@Œëœ ¦=YÊúH;N¥RxÕ=ývvÊ•¿¥Wí©ŽŠìĤT ÅvqG”)ÉJö3Ãë"#×ÿYòÕ÷ßÏž=;çÎ!Oj^&CÕ[Uðl6»±±±ÍBTÁLéé4gÍœIÿügÏ Ô³_ê›iý™ŸÅäºGÝ ð±ÒŒÇykР¿þúëÙ³g¯\¹Ñ OhÛà 耤PК5ôý÷´kEDôðÎï–KîœØùÛùÌ8î½1ûå#‰δÎM+ä_¨ã›íòç%òæÂÂB©T*{èúõëK—.Eô@…'£ €^}•ÜÝiÛ6rtì±Ýª[Tõ9?UgîRT—:†½á:ƒÉvèÁÓþ½#e…QX,ÅN¾3ÎfÛ>Í PÓ¦P©Ž¤¥:uÊÕÕ•ûŸÏç¡q'(<)·nÑÇÓŽôé§4~íV%¯©ÉÞ{'k·Ç>ÇÆ?’aÒ­FÌú錪½ê79ÝÒæÒ5Í P¥Ï>ûÝöŸ&"¡P( #0j@W¡ô|ôüúkš=›¤RêrE´î!âïT؇Lóx'iÐpAwNò‘Ù/Éõa|nt‘o{–Ç¿ËZ†”T ¾{ÑÌì’B‘ÙÜœib¤VÇŒ—¶v-FMè>”€BÏGÏ•+»=µÓ`6äh=D¼ù`¯nÿÈì—DB Iø¬òÙêâjY~~Ë¡C#~úÉ®¦f—•ÕF¹ÜÆËË××W h¾òù|3L¿€ "?ŸÒÒ(5•Μ¡·ßîbôl?ýzLƒI­Gè¤sÁC1QEù”–––ššzõÔ©xkë9µ‘‘&Ó¦q}|ÐŽ Ž\Néé$‘HDD$’PHÔ…&‘šžìu—Ò¬øc{*wê,ì ©}åû#GÖˆÅîJe »RiU]Mo¼Aqq½2ã' €B7i ;Ï£à`Љ¡¨(êZ“ÈìÉ® …”¤’äQžæëuºþ§¦?ù•øq.pýX2äâE¿’’À»w« Rº»ÛØ=¶³§`Pèš,ìÔ詞ìÚºõlÊö$O_òõnönºÐ”»?÷×Ù±l‡É,VHm-‹Åª aNšä4cËÞo((¨)ìì '»ã„¿t¡'»Îºõ1 c2þ›‘œœ|133žË%rÉÏg„„t«„@¡ôTag÷d×ّȇ|rrr6oÞüÓïòx±D.2#<œbciòd²±Á €Šj¸4#(ýç?4n\×Ë {¶'»ÎÂÎå³ìâêûùù¹‡ýô“CMÍÓVVv …Ü `D0=¢çƒÁ;¯_ïÊJÍ7¯5ä¨ÏÍhºžÃö µ ˆq³¡Ë¹S; f:¥k ;—ÒRò!¹œÖ¯§¦Ö:8üÚØXãààé7mš©:”€"z>öà-ÍòüìIVC^&Yû†[ ÂØ>¡&æVÝÌÚé×…JaMqMaa¡´ ÀN$Š>yò“¹ìÞ½ð7Þˆ‹‹óǨI  F$'‡6o¦èÍ7/z¶.ì´ôô·ñ{ÎÚw‚ùPïÇ:ºÞé×)*–bÃÂ3ÿ›™œœœ––æêê:‰ÃYZ\laaq}ɧɓ1D<(¨1Q©(%…6o¦¢"Z´ˆæÍ#ç·ê©ÂN}Ó¯ó‰Ï#žC½ƒèˆ(999+++,,,66öÅ?ý‰ýÏRv6­_O3fƒwÔhTWÓöí´e yyQ\M™BÌN4ýÕÌQTûóK¯€®vêž~½il]ö¯UgÎ4åä0®]³ºqé®ÎE©4m¿ýêÕ”ÐõG´ïijÛ¢iÓ:;ßd÷ç(jß‘(Š¢|ò©bûöúï¿÷®¬¼ÉbUÙÚ6:;«½½-ýýÆs eYZâý Ð ¾jSÛ^XØ©ÚönÎQÔ¾#ÑîÆ/mŽŸo9vìîën64d˜šZN›6xíZ7ww7¼IJ@û•Î×¶«UÊæÛE÷n6ßÞ»Qx¯Rª¨.±3õqç(j=J|EÄRìä†p›ÿfRr²úøñ’¡Cwß¹SÈ徸rå”)S˜LüÁ ýB}=9BÉÉ”™I/½ÔQm»¶'{㵟Í]-†ñ-œyæÎ| gžù`/³S}Ìuß0†ýß JNVgfVp¹ÉD‰……‘Ó§cÔ$@퇹3+‹ÂÂôNÔã=Ù™3Ÿ4ÓÆ«Åâ Ÿd¢ 2Y@xxllìäÉ“m05 €öšÞERÇ“Ÿ÷ROöˆÆöq±vÚøêÀÀ½µµëΟš0¹@û•NŽåÙýžìvÒ¹sÜõLæG‡-Z´hÞ¼yœÎôuPP£ÐÉÞEÝéÉÞ™ÂN I(¼ãï¿íûï·lÙâåå‡ÞE€Úäç?(s<{–fÌÐÛ»èþ=yÃåãµS¥gmÿõX=ÙuÛiv¬¨lëV›S§x55çˆR‰Òˆò[m5wî\ô.øÿöî4.êrýãø5À ÀЏ€ÊæˆKaXY(v@QOâÉ·J1#•8h¨ ¥T³ÐJSrË%QJLs ") <.à~Q1Ä…AQù?˜Rÿ†Š(óy?f¯ûžß×õ»@ëFné9Š—WWÝ”;ÓÌœÝ<ÛǼCÃúÕº:èïÇvzy1ïËW6ovÊÌ‘gçzýú==a‚Yõo‹ €>Yt[‹¢¢¤sgéÓGz÷–¶m«~¥nwÑ…ôX3çÎ÷”;«<¶S»zó‰9sŽͲ²ºøÒK-ÇŒqòöf:À#ÂÒ½ÚwËÖ¢¼¼Û^\tËî¢6ÿùµ:»‹þ¾¸3P7•¬VEo»Y™øæv­¶ØË«I\\GµšéÐÚTý‹‹îcwQÕ;Ù¥­h4¦ýò˃͚}UXhåë;!4´)ÏÙ´n+,”Y³dùrññ©ÖÅE—rö4xþ•»î.ªz'»x©D%"¢Õžš3Ç|æÌÆÆþ.ôñ÷&z¨^Dψñõ•à`ù{ü»¿‹‹ ¥p–ÌZ,‹»H—ÍN]*ÕhŽDDôüé'ùÅÛ»¯¯———J¥b:T£çfgn†©£kõ/.ÒEωð߉å/»œ•••™™™ý9~ük+«NW¯–Lj;q¢(|ï@-bRMÐh$,L.”Q£äСÑóïÍNkÏQªqÕ½¥ýæè™ôGÒŠOWØÏ³wttT«Õjµú ‹;;û‹MOž?? 1§å  užV+QQ"îî’‘!vv"7ß©ù_Š®ÙiÝmtõoi¿¾»(URÇÉ8]ôôˆððõõ-ÈÊj²¿ÄÅÉ–-""/¿,ÁÁU" PKxÿ¥¥IPˆÈܹâæö@çÆW¹»ÈåŒËWa_EDDŒ><¸}{ËøxIH_¼Ë!¢u2€ªTªÒÒÒ[~©?ôøq ‘” “aÃD{µôÌÏ‹Š¶­Pµu¿ïs㯥$ÿ“ØØØ-[¶HMýÂÓÓG«­—–&2x°¼òŠXXðµú@oý½é€ên3Z·NÆ—Q™iÏïŠ.ØfÖª“Mÿ¥•í]ÿ…*›n¥ni[ÓââââââZ•—³·÷Ðh¬UôèAîP}  ·Üfäç'ÖÖr)7ýÔºé"b;øCSÇŽw¯’.áQÕY:ßÚìLKÓª•JÕ./O©TÞé†x€Ç›T•·•Ÿ:¾"¬ôèN›þ! žï{ç“*¤b“l —ðÉ €C¥‡2¶fÄÅÅÍ›¯kv®Ñh¬E³¸@õÚÍ·ÅĈ««\9}ô|RâÅÛJ³w6î9¶ÅkŸÞù@¥")Z&ËÈ'q ”@Ç½Ž ç/|!ªýXµÚ_¥š_^®T*¥Cš .áüýGOÝ‘òS‚JM‹ïí⢋r1FbÖɺí²} zûÚÛ¹s7ÏšÕ:;{d£Fö§O+ÜÜhv(ôÿEO?_ÍÛ½·jÞ8Ëó®]ÏI’ä!ƒe°û ×ÝSg]Ú°¡çµkæææ&x{ÓìP¨È_·­\ªyoØÖN[*òîá,OÝî¢äOñ,ƒ=K<ÓVoVΙÓ+''ׯÆbøðæ~~4;”ú'­V6®8š´:Ñ«õ6GÓ óvÕ=Ëó–ÝECK†¦F§þùBbâH­ö¤—WóùóÍÕj¾…€Jùë¢öìĤ û·‹ˆ¥‹§ºÛ]w^wóî¢ù+ÖWÄÆÄæ¦¥ÍmÖìåÂBñõ5 ½q%<”Zœ¼&Í´Ü«/&du÷ÑmÀèVwã¦[]+=wpAð™œüw~ü¥ÿ(§™s«µ#èúÓö#åGZF·T]íÜðŒêR;ŽR €Þ6DVHüŠÕÎI y}ͺ-Øž¡´¶¾û»®?m·(²pyf¹|f#.E¢pæÜxèíBd‘¬XZ^šø™—}´¦Ó¡‹Üî60×ÏTJÔ&:ïw®œRîsBE¬J4Hbc¥:逪o22$<\vmÍù¢w`“ÍŸ ˆ54kXÜ™$InWÜë §T†ØJߢlc}ã.N@oVQ!›6Ix¸ÈÙCÁ½¿y§_Ló!Zu~‡·hD&aódž—xõºÐ«Å¬[}»ÄÉé% E‡²t©¸ºò} €Þª¨H–-“Å‹*úwˆŸí¾ÒBŽ7òiåžj¤²ºÝ[´¢’¨ q÷¤¢¤ÈO"ç3u‰“Ó|ùé'vµ@«¶aƒüÛ¯8Ô'*zÈ*3;kÏQ®½w„4I ’ Ë—/Ø<àÀ²SÜ#Ú·ÿœè @½3­V>ý¤òÔÏ+ã^ÿ̪ӿu[aÒ¢ýßr¸ôðØscÓMÓM¦›˜Å˜5~.…BÑR©T=€^D_V&“ß:ÖMÞmß^Zù}fÜØáί_{dí|åše¿ÙÞÿì[¯iÍšoØ 99 ~~loxu¿zº 2|ÌÊÍÃíÚô% ƒÛæÔвi»¦-3Y¦i¢éQÐãÇÂU­O$Ê‚âäÄövhµd$;¼ðÝž­Äõýõš8Üîe™…ƒwûÇ»¦ØÖ›ùc›1)•™Ù’×UFŽ”˜¶·,ª^—ð=¨1ug hyñ©‚Ma%Y;¿ÍÙ[Ú7*Nan~ã¯/^Œþ1zöåÙ‡èó‡*éã†Þ —yÃD¡àK@½7—O:›øÍù=[ŒŸýFܧÏw6‹ŽCC‘‹EE¿-_~hýú¢Ëû^®U‰yÖ@í3^6…ˆJÅô@ï¶²âbF|Ñö•W‹Ž7òyÅ'Ù{¸UP‰ˆ”î4襔Kó4\>Ö 4sH r¢Á¾¶blÌÄ@ïA…¦¸8%êlÒ*cë?¯ÓŒŽ13R¾þZúõmeåï&8,^lܼùŽôu!®óE$MÔÕÌ7@­{ò6!•deþ§‡U—!º½¡»Nsî\™;W6n”瞓˖éZ —¾ ‹ö-X >’%Ð@ ˜l€ÇÁÖ­¼zùøRÿ–¾_4tó‘k×$0P’“%%E óÓR†9äççúË›×ù=Å{îâ¾WöÚ‰Ó @½Oùk¦™Ø?£KŸ%%2t¨ˆHJŠdŒ|&2òj—.Gö,|ßj†È®µ²ÖMܘ`èý;—¶þrÞ^uHŒˆœ8!}úH×®2}|Ö¡¶žÏŸß¿måמq)â&aÃd˜B8_ àqôĬŒ,+È*øa¦Ý[‹ ŒMvïwwyã yËéóЧÛkmq. ¯g“8”ƒÃe8éà±õdt@uK?mM5nÚzÞ<™1C–,(³žãÑtÏî•›†.þW²»œL—t–{@ÝÒϳÖ>ýÓ@}8þŸ–r¼Øî¤ú“„#½ "’¾ki?ûqc¯¾ñ~Ó¥ì7 €>4ûÒoxuGÉÈ •ï6mj&"¢ÑlÞpœqy¹÷Ù˜—’K –ö•¾Ì @VËP]û³q†‘÷oÊ ¦‘>ê¼ZÞ„?{Þ‘üöß2é/þÌ@W›P]ûsé°µ×'ò “@}´¶†Í­lk˜ÿOûX£U\ò@}´öý~蛤ñcÎ&Z5cf€úhý²2¨¨ë…ïí’-Å’i €>ZÙ‡÷w59|ÂfªÚ¨-s@}ä¾ý.Ô¦Aý1=™}S;Ç0YfæW82úz¨: žzö‚FÑ"£ ‡j¡ºlIHŽ…²‹Ç?}hM0º–‘]Ñœ¡ÐO5ýþꕲç//é4¡ÐO5Ý]ðå”âz}‡¼ÉÐ@kÂåK)Íwh éx¥¨…mÆ€Z–/š!"oú‡2îКpòÔ–ôzÖ :´†<­=mbêΠ賚;†©¹¹‘Õ•ÊWBg3èúì: æææŠ¿|üñÇ÷úIÝMv™60®WŸA €Þ­­­F£qvvP(¡¡¡.\¸ÇjZaèʈè¹ê>‚/((P*•GŽ77·#FôêÕkÇŽÕ|»•‰ak+eŸ±aŒ8€ž«V477WDÔjµîÇ×_]Döïß_ýñt0I=YÖ¸©-#@½»ØØXqpp¸ù—åååÕÿ˜îŽ& 9—n<Ì]ð*•ª´´´Ê?îh‘|¼L¡P0âúN[ 999"Ò®]»ë¿mµ1ÎЩVÔÑÑQD²³³u?FFFŠˆ‹‹Ë½&ÝGZ‰B¡¨¤[ŸB!B!zRÃE!B!z;\Õ}occSPPЦM›ž={.\¸PDâããÉïxTôÔ©Sæææ™™™™™™"2cÆ KKK†*€ŠHIIÉã\‰™™Yݘ ¡ Ñ“B˜ ¡ ÑÛB5³C¨f–>P…P…P…P…èg!OV-@@} ,}  ¡ ¡ ¡ ¡§Ä &ñP@€‡âÿ->½:@/–üIEND®B`‚snd-16.1/pix/pulsefm.png0000644000076400007640000010622011147553270013322 0ustar bilbil‰PNG  IHDRôMö7sRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ ûmñ‡ IDATxÚìÝwXWû7ðï HU ""Í.ˆ½`o1cŒÑDMÓÄ<–'FLbIB,‰Æ<±Ä‚5Ø+l ŠAzïeY`ç÷‡ïÎ˲3È.  ÷纼æÌ™™=³;÷Ì™S Ã0 „BH›¦FE@!„P@'„¼ÆªªªpøðaÜ¿Ÿ ƒVNÈ—PTT„}ûö¡¸¸|ðlll8×óóóC`` ìíí1oÞ<üúë¯ÈËËcÓW­Z###*iBÚ±XŒÀÍÍ ‘‘‘€þýûSÁÒÖžÐ÷íÛ‡… âûï¿Ç‘#G8×¹{÷.***àéé {{{œ>}yyyX¼x1F…yóæ½4˜_»v ÕÕÕt&ie •Jakk‹Y³fáôéÓlZ^^®^½ªðïÙ³gì:qqq€üü|¹›üêêj$%%’““!‘H™™‰’’ 77Wî8âãã)))¨¬¬”۶쿵ÕM“ý·¬¬ éééœëfee¡¤¤„]^^^Ž´´4¹uSRR ‹‘ââbÎíÔwµ?bb"ç:………rŸ_*•²eZ{ÿEEE(**Bvv¶Ü¶Ÿ={©TŠ´´4TTT(]V2HMMå\7''EEEr7~)))ìþkjjØýçææ¢°°s;‰‰‰ìµŸï8¤R)8×)..–ûü ðߕ´´4”——#77())AVV–ܶ“’’P]]ôôt”••©|>+++ÙÏ/Û¿lÙþe$ ž?.·ÿŒŒ ”••!??ùùùœû|þü9$ÉKÏ'o@ÏÏχ‘‘„B!oÀ-))¾¾>ÀÔÔ999°´´„¿¿?455áçç'÷:tè<<<äþM˜0åååtõ$¤ ÐÔÔ”û·ÿ~=zû÷ï|UUUõcEENœ8Á¹Ntt4»ÿþù•••8vìÀÇÇ999 ÁÓ§OƒÛ·oËmûرcH$ðõõEff¦Òe%KËÌÌ„¯¯/$ þúë/¹uBBBƒ˜˜!77>>>€¿ÿþ‰„½ö‡……!**г¬Nœ8Á^ûùŽ£ªª Gå\'66ÁÁÁÈÍÍÅùóçÁ0 :¸rå ÒÓÓq÷î]DEE!!!7oÞ”Ûö‰'PVV†ëׯ³¹î16¤¬òòòpáÂ0 £°Nxx8"##‘€ÿý………8wîàäÉ“(--ÅõëבœœŒàáÇœÇqöìYö&ªî>j6õ}É’%rwÖb±˜ýûÃ?TXÓ¦Mtu$¤ÒÐÐ`oæsrr`jjʦaÔ¨Qrë_ºt‰}J«íÈ‘#xÿý÷QVV¦ð”´gϬ^½šsÿu·SeÖ­©©Arr2gZQQŠ‹‹abbÂ.KLL_g ºûMJJ‚T*mô1VTT ##£Y>}ëÖM“J¥lmJ]ÅÅÅÈÍÍE·nÝ^é1ÖUYY©PóÒTŸ_™uëSZZŠììl8884ùçoP@9r$nܸKKKXXX°Ëoܸ§OŸbÉ’%pppÀŋѣGܺu nnn¸rå zõêÅV/…–»"íÛÓ•™˜˜˜`èСððð€©©)¾øâ •¶óäÉ*LB^Þh;aÂܸq¡¡¡Xºt)»¼S§N€:`ÆŒ8wîÆŒôèÑ{÷î888 K—.-÷é¶l<=é,¢"ggg8;;·ªczðàû’Ò€€cÇŽUXfoo{{{öo333|úé§ìß@îoBQVnn.û.½®ÄÄDäääP!RõC'„´:………lc*BtB!„:!„¼N~úé'*BBÚ‚;v°ýÀë¢ñ.tBi# @H’7•°MýÇ@!kKJIA·À@þüݺ-Ù­Ž¼–RRRЩS§–ƒ(%11‘s¾ ±XŒÃ‡cýúõTH„žÐ›•X ”—óþÛûþûõ¦ƒ§jŽÆðööFii)D²oß>ÎåR©”T¹¹¹ìØÛ„4”lèZ. 9°m?B LßBH‹ˆ‹‹Cxx8gÚ¹s甎”¼^Š‹‹yÛrÔ'66–7í?þ`m{=ŸÐ !¤…äåå©´kÏêV×™3gxÓΞ=«ô¾*++U ,¤qΜ9Ã;~}縱Z$ K$”——S«SBÈççŸæM»wïo_m@AA‚ƒƒ9Ó®_¿Î;â^}¾­Þ\»v÷U‡lF8¾˜Ä¥¦¦¾¾¾œi)))ˆˆˆPúë;ÇÕ"UîW¯^U© !­C||¼Âû¾àà`Lž<™ ç+--Edd¤Òù~ùåÞÚ‚uëÖa̘1m®,ÂÂÂx§û áÍ·~ýzΩTŠ;wî`Ò¤I iÙÙÙHHH›…°¥µH@Ÿ:u*¦N øî»ïèIHcmm7Ê-£·×ÛÇQ\\ŒÀÀ@Ìž=[!aܺu +W®”[ˆaÆqn300µ=þûöíÃüùóÒ.]º„éÓ§S/ô¢4@555¹²YÉë)44………¸råŠBÚÆ!•JqõêU…´+W®àÑ£G8þ¼BšŸŸ¼½½§psÀ0 îܹÃ{Žìz®-G¥üÉnâ8“˜˜???δ   Þ¿×? B^©Ã‡³­Œoܸ!wñ©]•[·Z÷ÀœiR©T®¯wíõ?~ŒÛ·oª««‘™™Ù¤ŸE•âiìw­¢¢yyy*m‡:!¤É<{öŒ}ß›™™‰²²²F=yWTTààÁƒ¼Oå¹¹¹œiW¯^ENNŽÒOЪ¤UUU¡  €3-<<OŸ>åL;}úôKß=“Æ?%ó}T}º.--EEEgZnn.o{€úöÅ÷Û¨©©··7ïoMvCKòÚJJJâíFÇ÷Ž[Õ´ôôtÞ÷¡™™™¼ÝbccyûL«òn¼¦¦×®]ã|Çš””Ä;ÀÌ­[·xk7NŸ> œò***xd©®®–»™«aÞ÷Àñññœ ÉJJJ ¦¦ÆÙ– ´´û÷ïçÜ^eee½¯wøÞçååÁßߟ3- €·ÁÞ½{y¿w¿©Ð¦‹aÞF|……… #R@'„¼|dÐÐÐPi2MMMÞ|êêêœû¼­Æ…B!ï1Ž1<³7jiiñ6¨²³³Ã“'O8Ó 8ƒ[JJ oíƒT*ålÀ0 FÅ8òóóann®ðD'«iß¾=’““9objjj8o<®\¹ÂØž?ŽãÇ+,/..†P(Äÿþ÷?…´'OžÀÄÄ„³•ýÞ½{¡««Ë™vøðaÎþêÀ‹Æ†ÎÎμµ?ÚÚÚ Ë322 ¯¯¯Ð•NV£¡¡Á¹½‹/búôé¼µ8ššš¼7};vTê{_]]ÍÙŸ:!¤IéèèàßÿÅà:“'õìÙ±±±`F¡ÏúÌ™3qîÜ9Î@;a¶sÝ|³fÍÂéÓ§9ûÀÛÙÙáñãÇ izzz(..æ<ŽÁƒs=pttDTTgÚ—_~ɤ sçμïãuttPVV¦púúú¼O±VVVHLLTú¼ôêÕ‹·úßÔÔ´Þªé¦R^^δ””tîÜù•}O% gÍÏχ‘‘oŬY³8Óîܹδ³gÏbæÌ™ 7¸ à  ††† 7åååœ7AAA:t¨â )]~!MI$!44}ûöåLߺu+þûßÿr¦ùùùaâĉrˆÎ>›››s> víÚ•s{>>>˜6mgš§§'<<<8Ó>|È{üéééœÇ!{wª®®ÎùÔשS'Îí:t~ø!gÚ­[·0|øð?§¡¡¡puu•»1ã2lØ0ܺuKéíwêÔ©AÓƒÖÍÃ79Nß¾}y{6 6Œ·û`}ŸÍÀÀ€³G„žžo—6kkkÞö!«V­ÂÖ­[9Ó>ýôSìØ±"‘H¡Å!Cxo:é Ò¬ê{BíÛ·o½ƒo¨zCÁÕhÉÐзñšÜ…üÞ½{0`ÀÕÕUîš–– …§Þšš0 ÃV…³Õæµoôôôxû»ºº"44”ý; £F|üñÇró¶ûøø°Ã¦þç?ÿÁöíÛÙ´¤¤$tëÖ àææ†ëׯP¬ÞíÔ©ûþüÆpsstëÖ ÏŸ?g× b‡oíÕ«—Ü+„½{÷âã?Œ5 lÚíÛ·ÙùóçãÈ‘#lZII ôõõlpÎË˃‰‰ €¯T†a_«œ8q‚vÖÂÂiiiìö6lØ€ï¿ÿп¹IPΞ= wwwÎc,((`ŸÈ{õêž³‹Å‰DrßY@OMM…¥¥¥\LDD{3hcc#WuÿðáCôëׯÙj(( BšUÝ‹Zm#GŽÄÍ›79Ó/^ÌÛØièС¼£zéêêr6L233CVVïßûàÉ“'ãòåËœi à=ËÜÜœ÷©“ï~}í „B¡Ü»ìšš¶6@CCC.M*•²ÕøµÛÔ}ÍP»=Aíí ÞÖÚuñ½Ï•mSMMóøùÊ ¾ÚŒššÞ}Õ÷žºººš³æ²²²`ff¦°¼¾×ñññèÑ£gZ`` FŒÁ™€‘#Gr¦ÅÆÆÂÆÆ†3-//÷5€Üw¤%~àgΜiÖ)ä!­ƒìÉ”«jtçÎXºt)vîÜÉ™WGG‡·Åp}áyÝH¥RöƨÕ=¡»»»ÃÓÓžžžt¦y…‡‡cРAœi\!ª£Fq„¥*´ø®ý>³9=}ú¶¶¶¼-¶ ySÑ;tBˆÒªªªP\\,÷¯)«À¯]»†qãÆq¦•””@OON!ô„Ni,SSSLžx]—/_VhÍߥ¥¥ÐÕÕ¥Â%J?~<;³ tBQ!ø¶k×Né|YYY¼óXçääÀÔÔ” —(E[[›sb!°´´äœþ è¼…CHsRe¾jҶܹsÎÎÎM¶½úæáNNNF—.]¨ÐÛˆ)S¦àŸþáLëÖ­’’’”Þ¦††ªªªÞÌ€~îÜ9ˆD"Þùr iN|³„‘7[^^Œ9ÓîÞ½Ë{ƒpâÄ Ì™3‡3-;;›·6@ÕÚ‡¶ª¾9ÒMLLØélJ(B pR”••qæ333Cvv6gÚ| 7lSj‘€ž™™‰§OŸ6ëXÌtGKim*++¡¥¥Õ¤ÛtèP,X° , _!„´Æ ÃöíÛ9§ÃussÃþóL:U!ÍÞÞ=âz·}ûöˆ…™™™ÜòvíÚ¡¤¤„}B®mܸqعs'zöìÉyœ‰ä\¨sçÎ £R+wB!/åè舳gÏrÒþýûc÷îÝpqqQHëÒ¥ vìØÁ9ÙŽ®®.ÒÒÒ`hh¨V_#ÁÔÔTXXXp¦íÞ½Ÿþùk>LMMammMB^5###äååq¦õêÕ‹·ÊwĈ ä ²u祗ák˜%{úåbaañÒ®QmÙÝ»w9kÀßߣGæL+//‡¶¶¶RûЉ‰A¯^½8Ó1bĈ&ÿ|Ð !J‹‹‹ƒ‡‡‡Ü¿   6÷9úô郈ˆ¥ó9’7Èò©¯•u}ÙÍÍ ×¯_çLëÛ·/>|șֱcGdff*uŒ]»vErròkû½ Á!C”ÎW^^Îß gž¨¨(899q¦]¿~ãÆ£€Niy666ðôô”û7lذçÿú믱eËÎ4Uú颠 €3mÈ!æ Ìœi‹/æí~¨®®ŽššÞ'ñüü|ú’¼¤R)ÔÔš6Œ&$$ {÷îœiOž<tBHó³··g2M›6·›žžoµï Aƒp÷î]δîÝ»³ƒöddd S§N/.djjœ]‹@KK ‰DéÏÒ®];Þ~Æõ>%Õs,„¼ÌíÛ·áêêÊ™VUU è„æ÷î»ï²­™õõõÙ ýøñc888pæ¹páf̘Á™æåå…… ²kjj²Á9<<äÌÇ×Ǻ²²’sùË$%%©Ô•«°°íÛ·çL«©©ºº:}i­°\ @ 4ø‘:!¤Ù•••q¾ƒ€ÜÜ\˜˜˜p¦Õ~ WFVV:tèÀ¹/¾‘ÚÂÂÂ8[iõOàrñâEL›63íñãÇœU¤ Ã@,s6´*//¥»ðÝüÈú©·¼#Ÿ¸àÎ;œiµokÓÒÒBee%gžú^ïÔרpÊ”)¸|ù2gš®®.gmºº:ÔÔÔ\ÃDBðbXV¾nRõÉÈÈ€¹¹y“G||©‚ï©x1 Iaa!o¾òòrÎ4sssÎ'ÁúÞ›ÛÛÛó:aÂ\¹r…3mÒ¤Iðõõ•[–šš KKKΧΧOŸÂÖÖ††† ,##ýû÷ç RÎÎÎ ãL[ºt)víÚ%·L61 × `~~~˜4iôõõQ\\¬öÖ[oA,+õ»wïbüøñœO¿………X¼x1N:%·<11‘÷UÈÕ«W1aÂδú^…¼ìæ§sçΜµ|ÝÚbccakkË™VRR===•jU¸öGҤƇÀÀ@ÎÖ¿|ðΜ9ÙoàÀœïÓJrfnnŽÌÌLÎñÑg̘ .pnoÕªUøå—_8Ó¦L™Î4… õ²®'\™ž={òÎiÑ«W¯&ïBOOóØ£Ž¥¤¤4É~bbbxX}ÁíUúõ×_±jÕ*䤤$tëÖ󆳸¸˜óF ¾×õM¥{öìYÌ›7ó100ãÇWHÓÐÐ@HHg?v è„&Õ§Oôë×–––ì²Ú¿¾ýö[¹õùÒ{S ¡¡Õ«W+ìËÈȺººrÃH«©©±ÁßÞÞ^®:¹ö¾ÆŽË;Dè¤I“xÿ®ýÿµQ]]]î\û8,--å&I©}ƒ ’kCP;­îqð¥ikkcÔ¨Qœë©©©±Ç¨¯¯/×½°öM—¬×öëÞœÕN«Û°¯ößuÓjo§ö6œœœØïKí2€ñãdz -k—)Lž<™w_|Ǩ¡¡777ÎóÞµkW¶ñ¦ŽŽFÅæ?>û]ª]¦\ç©ö>ë+«Úß÷Úi–––èׯúô飰ÝñãÇóÎÊGÒllmmaaa~øA!mĈÐÐÐàL;v,:tè€/¾øB!m̘1èÞ½»ÂS”ºº:FމåË—³ï­­­annsssØÙÙÉíkðàÁÐÐÐ@¿~ý`dd„±cDziÇg÷@.ÖN³··g§5USSc«jÇŽ‹wß}ŽŽŽ€:ÀÆÆzzzpvv–;GGGÂÚÚ]»vÅÆö5dȈD"¹|Æ ƒ©©)–/_‘H$7šl½±cÇbøðáì &ºººèׯ{üK–,aŽ7#FŒ€™™Ù}ÀŠ+`hh'''˜™™É¥ýðÉD:t¨Ü¾eÿßµkWôèÑ=zô»ñ>|8 „3fÀÆÆ†mÄèàà€wß}:::puuÅ!CØà9gÎ888 [·nèÞ½»Üy©ý™ëž³~ø†††èׯ4440xð`¹ïS¯^½`aaN:±Ã©ŠD" 8ß~û­B Ј#àææÆ¹/ggg´k׎=µËjãÆ …œO×?üð,,,8k0ÆŽ‹þýûs‘[[‹Ì¶væÌÜ»w®v„¼æ-ZKKK…Æ@k֬ᬦ433«w,n777X[[sôÚO©µÍž=vvvHKKSH»té„B¡\@^Œ•}þüyÎíuéÒ}ôï1ÖÝ–Œ, s5 ûðÃѵkWΪû7npNn" è|Ÿ™ë5…,ñ=¥º»»ÃÑÑ‘sT»óçÏs‡H$Â7xŸzÿþûoÎ4¾'Mغu+ç¾àÈ‘# …œ èÎ;ÇùºÇÈÈ_~ù%ç¹²´´äíÅ Ä\>ÿüsH¥R¹¶...h×®ÜÝÝ!"—GCCkÖ¬á<7–––œÃÅŽ;"‘ˆ÷ÕM‹twwwvþÞM›6ÑU×”¬JÔÔÔTî⬦¦†‰'²Oñúúúlš……;ñÆÚµkå¶W»Ÿ{Ý´Ú×M“‡®®®Bx¾ !ØjÐeË–Éuíª=AIݱÁ?ÿüsö‰ŽïB>Ù1+ŒV÷ÍÍÍBÝíÕj|ûª/M$±5 /++®4kkk¶‹`Ý4®ñêGí<õ¥ÕU·Z»C‡ì{ïÚŸxñJFÖE°nZís'ÛŸì8dÿ•}G455ªÇëÞTèéé±ÁZöݯ]æ²õë~gV­ZÅ~Ÿê£¦… ¦¨¨¨É·ûÛo¿1žžžL||!„Ò–úíÛ·M¥O!„´å€>~üxŒ?°råJ: „BH#Ñ;tB!„:!„B( B!„:!„B( B!Ð !„BB!Mˆf[#„(­²²¹¹¹rËJKKa``@…CtBH[‘••…K—.É-‹‡……!Ð !mE{±ý IDAT—.]°téR¹eÏž=£‚!¤Ñ;tB!„:!„BZƒ©r?sæ îÝ»G¥O!„´å€îîîwwwÀ¦M›è,B!DUî„BtB!„P@'„BtB!„P@'„B( B!„:!„B( B!„:!„BB!­ MŸJQZ\\<(·,((S¦L¡Â!„:!¤­°±±§§§Ü²•+WRÁò¦ôçÏŸ#//JŸBiË=''IIITú„BH[èÄÀ©ô !„&B­Ü !„ è„B¡€N!„ è„B¡€N!„P@'„BtB!„P@'„BtB!„:!„B( B!¤ÉµÈXîR©R©”JŸ6ŠæC'„:àÂ… xðà•>!m͇NtÀÌ™31sæLÀ?þHgBi$z‡N!„P@'„BtB!„P@'„BtB!„:!„B( B!„:!„B( B!Ð !„ÒÚÔ;ôëõëבššŠ?üwììlœ={cÆŒAÏž=Ї²ésçÎ…¾¾>•4!„ÒÝÏÏššš2dvî܉¥K—*¬“™™‰K—.aòäɸuëàâÅ‹øì³ÏØuttt¨” iÒÒÒ>|8ºté‚êêjœ8qèÛ·/!m1 ²³):tˆsÇ£{÷îèÒ¥ FŒ0 ¤¦¦ÂÌÌ ü1„» Evv6•:!­ÐÁƒÙI“>Œÿþ÷¿ðòòÂÈ‘# Ô iíýöíÛ¸té»ðã?VyƒŸþ9ÔÔÔ`ii‰ýû÷#++ Ý»w´oßž÷æžä iuuuŒ9Råüåååppp@II ’““QPP€šš888ÀÁÁl@ÏÏÏ—{µÉÉÉh×®üýýédò èèè`ðàÁòÝÕÕ®®®r+!??úúúì6ðâyii)ºwï===¤¦¦rrr`ffÆs.½zõRX6hÐ lܸ±Y>ljj*ï±¼LEEÊËËall¬Rþ¬¬,ACC£Mî¿1e×Öó—••A"‘ÀÐÐP¥ü055•ûݼŠýkjj"((¨Aëúùù!00ý{ÕªU:t(<<< §§†aêÍÏ0 ¤R©Ü2@€èèh|óÍ7­ê·Üœ¿“úäååA[[»YVš«B`ÕªU ËçÌ™ƒ9sæ°O˜0&L`ÿvttdß½·eÐÖÖV9»ví ®®Þf÷ߨž m9¿¦¦f£Ê¾±ZjÿOŸ>ÅáÇ!‰°`Á˜ššÂÕÕ066ƲeË¨Ž“VLHEÀÍÖÖ¶¶¶*ç_¸pa£öß³gOôìÙSåü}ôQ£öߨjÓ¶œ¿wïÞèÝ»w‹}÷œœœàääÔ"ßùº7ブ{GGi½^ëeaBß½×à37×¶Ûâ1·åmÓ17ïq ˜—µ~!„BH«GUî„¥ÄÇÇãÈ‘#X°`¬¬¬8×Û½{7RRRзo_Ìž=› ޼ÖBBBàããÐÖÖÆ—_~‰¢¢"|ø0óäɆaÆ××— dHó a:DÑ‚j·X÷òòbbcc™uëÖ1•••ŒD"a¾ÿþ{&''‡ùõ×_†a˜ÒÒRæ§Ÿ~bN:ÅÜ»wa†¹yó&ãççǹýo¿ý–©®®fÄb1³~ýzÎuÚü;tGGGüûï¿M²­k×®!22Ré|ÚÚÚ4hP³Ö«W¯¢´´”3ÍÆÆ!!!/ÝÆ¶mÛ–¹¸¸@KK«YŽÙØØM²-WWW\¼xQ©<÷î݃† †aÆÁÔÔÞÞÞˆüòË/¼eª©©©Tƒ°3gÎ4iÙijj²Çmbb‚'Ožp®ˆÂÂB 8üñÇKû7VUU444 ©© ‰D¹Nyy9ÛÿZSS•••ô×L222ìØ±ƒ ¤cÑéÓ§qúôiö:%‘H ©© TUUA*•BMíEØÕÕÕEii)***Ø^-ZZZ‹ÅœÛ¯©©ºº:´´´xO­¶Ê}Ó¦M‰DÈÎΆ >úè#vLy___ôìÙÖÖÖ°°°@»víØ|±±±ìPµ;vÄâÅ‹áïïÏ»âí·ßVØßƒ°gÏèëëÃÅÅŸ}ö.\¸¡Pˆàà`tëÖ ‹/Fxx8Ο?;v,ÆŽ‹S§NÁßßxyyA"‘ 99¦¦¦X´h‘B7*±XŒ?ü#GŽDFF¦OŸŽ.]ºàÀ())®®..\ˆœœ?~À‹Á{°åpïÞ=H$¸ºº¢C‡ ƒAüüóÏ())‘‘-Z„K—.áÌ™3ÈÍÍÅ”)S0tèPܺu {÷îÅÖ­[ѱcGܽ{þþþ(**‚––.\ˆòòr>|`eewwwÉí«²²û÷ïGZZ€“ò8::bïÞ½ÈÍÍe[O‡……áüùóPSSCçαxñb¬]»:::‹ÅpssØ1cpìØ1DGGC(â£>‚••zôè¡RW¼ôôtèêê¢ÿþÐÓÓƒºº:Ž= KKKèééñæ;þ<Ο?£G¼½½‘ŸŸ´´4¶L###Ùyž?lõL™2:t@||<&Nœˆ»wï‚a8;;³7)¾¾¾œy…BØØØ 66ÇÇÁƒ9ÓÏÏ-_oooÔÔÔ¨<¨ i{ª««¡¥¥[[[èëë#88¸ÿ>tuu±hÑ"DDDàÊ•+^ ð5þ|ìÛ·‰‰‰èر#Äb1†MMM 0€½ÆÌÐûõë‡yóæ¡sçÎ8p €ãVïÞ½›6m‚——jjjеkWvûÞÞÞ;v,Þÿ}v¬kٱϘ1ŽŽŽ8uêЯ_¿º¯:àè舒’¬X±[¶l³³3ÆŽ gggDGGÃßßÑÑÑìÅúË/¿”+‡ÒÒRÞr€qãÆA"‘àÎ;xôèæÏŸ˜˜¹®IÇGtt4ªªªÅÅÅ066ÆêÕ«‘’’¤¤¤°y<<<‚¹ìXÊÊÊØ²‰D€+V°çO$===QYY‰M›6A]]YYYؽ{7D"<<<0fÌ 0VVV(--ÅÉ“'±zõêF=éŠD"öÎX]]óæÍÃßÿ.]ºðæ›5kû•ÝP 4ˆ½©ŒŠŠbƒiUU/^Ì>1úé§€S§NaûöíHOOÇ_ý===v¼tزe tuuë=~ |òÉ'ðòò’›ø¨¥ÈnB¤R)†Î.ßµktuu±`ÁLŸ>~~~èÕ«9s¤ñ²³³±yóf$$$ÀÁÁLJ¹¹9>úè#ìÞ½÷ïßGJJ Ξ=‹wß}°oß>ÌŸ?‰‰‰ðôôDff&6oÞŒââböw+»Æ>|Ó§Og»ÙÙÙÈÌÌÄÖ­[¡¯¯ 0êêêì5"11yyyìS¤l[oÙõX6bêÈ‘#áãã¡P¢]»v ABBæÍ›cccøøø   Ož<ÁŒ3%%%˜9s&®_¿ÎÆ£ëׯ£´´ãÇo[]]]šššJç{ë­·ˆ‰‰µµ5$ òóó@nP>åå娮®fŸHÿ߯|ß¾}èÛ·/Š‹‹Q\\Ì» ¾†B¡Ì’>>>lµg\\ú÷ï/—ž™™‰Ž;6èØÇÇewwwÎ<pqqaË9&&=zôPXoРAððð€ššæÏŸèÔ©{!€¸¸8\»v VVVxöìY½Ÿ³¢¢ÉÉÉõŽпö&M¦G˜;w®Ü Áw^ûÄb1[ï¿ÿ>€¯eÊËËÑ¡C¹|†††¼]WªªªP\\ +++XYY±OXÀ‹†i:u‚®®.;Lsûöí!š½ Ï´iÓpëÖ-¨©©aèСìòQ£F±5æææ˜0aøàhiia„  Auu5&NœàÅ!¾¾¾8p ìììØš¼ððp̘1ƒW$aùòåì¶gÏž ˜››³5|m& WVVbïÞ½(,,dÇѵ°°€‡‡Ú·o 888ÀËË ؼy3V¯^ÌÌL¶zÝÐÐzzzl¡À{ï½Ç»ÏAƒáàÁƒðóóÃG}¡P¨P%Û±cG„„„@__Ÿ ˆÇŽCDD6lØ€uëÖ±VÙ{®@¸¹¹AGG†††8p :„óçÏC$aþüù°¶¶fƒiII ÔÔÔ`ggèêê²ãŸ>}ððð€§§'zö쉣G¢ººl°?~<<<<`ii‰%K–àÖ­[ð÷÷GLL <<< ­­Í¾ƒåúüÑÑÑèÓ§B•nuu5ÂÃÑ——ÇÞX/ÞÙGDD`Ïž=rO—R©‘‘‘°±±‘»ØÂØØeee ‘‘ ëÖ­CDD¼½½Ù󘘘ˆ¹sç*L"ÃUþ†††PSSCÏž=a``À{1“•éÚµkñÓO?A__Ÿ­ò×ÑÑ––FŒ…BÔÔÔ† Æ~ß–/_Žøøx¤¦¦â³Ï>ÃÍ›7Æþ gÍšÅ~N®ªÔC‡±eZûÉ~ùòåøî»ïàììŒÏ>û {öìAaa!æÌ™Ó¨ªvð±··—ûÛÂÂ¢ÙÆÀ&ò?u§uo ¦NÊNq=mÚ4öZæááCCCH$ôîÝ^^^¸rå ûúíwÞaÛ†¸¸¸@[[[á÷jdd„òòrö:õöÛocÔ¨Q8rä´´´PVVöÆœ Y em²›ªÚç«îz;vTX¦¡¡)S¦È-3fLýÐZ ’–õÃ?0¹¹¹Lnn.³{÷n&))IåmmذÝÖºuë‰DÒ¨c«ªªb¾ûî;:I„´¢ëíÝ»w™øøxöwN^V;°LPP† F·ß­€T*ÅöíÛ¼–”ïýMCaÿþýìkÝYþTy‡XXXبar yÓ5ÇõöÀl­ÕÔ¼4R!„òP£" „B( B!¤µôÒÒRv€ >yyyðööFRR•&!¯™êêjx{{#""‚ ƒ¶Ћ‹‹±eËøûûófÎÍÍŹsçàè舛7o²#eBÚ¾ÊÊJìÛ·ŽŽŽˆ‰‰¡ NH+ÇÛýƘ6moÿ^xô謬¬àää„öíÛÃÇÇŸþ9 55•óéÞÞÞ¦¦¦Tò„´rùùù¨®®†““œœœàáá>}úx1Zã£GòtëÖ ]»vmÒãHLLl–šycžÐgΜɎX£ŠššˆÅb¹«V­B@@•:!m×ïû÷ßgÇüoJ€T*¥B'DÕ't>EEE¨¨¨@ÇŽ¡­­ÜÜ\v¹lD/èÚµ«Âúo¿ýF%NH[¹8…ìÈùùùr£Ù™˜˜`„ rë_½z• ÖÐÿúë/„‡‡#==)))ظq#àÂ…  ÃüWWW\¸p°¶¶Æ¢E‹¨D yM˜ššbðàÁì„<_}õ yíUWWãøñã˜7o ñý÷ßC à›o¾Att4®^½ cccüç?ÿ––jjjàåå…ÄÄDôêÕ |ðRó)„„„àüùó°µµÅüùóñÇ 33C‡e'Æ^Ì1âããƒÙ³góoìUK7qâDæäÉ“4>!¯¡+V06lhòí®]»–©©©¡&¯ÄÇkkk†afõêÕLhh(sÿþ}fùò医»;“››Ëxzz2W®\a†aÒÒÒ˜¹sç2 Ã0S§NeJJJ”ÚßÏ?ÿ̤¥¥1 Ã0¡¡¡ÌêÕ«™ââbfÚ´irëýùçŸì~øP?tB!@JJ 6lØÀ>«©©ÁÅÅýúõƒH$BÏž=all¬0duii)†Aii©ÒûÔÕÕŻヒÔÔT/&á’J¥r³Ô#::ú¥ N) B!ðã?*•ÇÜÜ .ÄÚµk1dÈ´k×î¥ynݺ…M›6A,ãË/¿Äž={àáá <k×®•›ª: ?ýôÓK·+¤SH!„¼åèÑ£ì4ÇR©aaaÐÔÔ„X,FJJ òòòŠþýû³ù&Mš„ÇcÅŠ Ú³³3úôé---„††ÂÌÌ #FŒðbnô‚‚¹6iÅÅÅðôôÄÍ›7‘™™ÉNÝMBá°téRÀéÓ§áììŒ=z`ݺul£¸¨¨(lÚ´ FFFèÑ£¶mۆŋcÛ¶mX¹r%´´´´---vÝK—.ÁÊÊ óçÏGJJ Nœ8%K–@SS¾¾¾ÐÐÐÀæÍ›Ùãâ æÀ+žmmÒ¤IX¸p!ÞyçúæòšY¹r% ðý÷ß7év¿ýö[lܸjjô†úÐ/„By P•;!„òÿxzz¢´´o½õLMM±nÝ:¨««cåÊ•¸wïû FFFX¶l½C'„BêóôéSÔÔÔ`õêÕ000À7ß|ƒµk×B(b÷îÝÈÉÉÁÿþ÷?;v wîÜÁøñã‘››‹””¬Y³{öìiPkôÚ®_¿Ž?þöööxòä ììì°wï^899±ë\¼x®®®xï½÷ ©©É»-ªr'„BCWWŸ|ò JKK¡¦¦[[[X[[CSSÐ×ׇ›G__=ÂÎ;1~üx¥÷9xð`¬X±÷ï߇ÒÒÒPUU…nݺ±ëØØØàÁƒؼy3ªªªZ. K$    Þ‘©¨¨hÑÚØý76uu5;~v[ý b±ikY]]Ý ïJsíÿuøB”gbb‚+V`Ö¬Y8vìXƒòÃÍÍ |ðAƒç3¸~ý:<<< ‹1sæLìÞ½»ví𢠾î~ûí7äççãÉ“'-П={†ýû÷cÿþýìH8|"##ñé§Ÿª¶£¢"ˆýý±zõêFïüùó9§}m¨7ÂÏÏOåüÀTÎïëë‹-[¶ ²²R¥üñññزe ¢££U>†_ýU¥“dîÝ»•óïØ±§NR9jj*~ýõ×FÝLž<EEE*åe_}õÂÃÃé KÈ+”œœŒÈÈH0 ƒÁƒƒa\¹r‹ÅxôèÒÒÒØk|MM ›wÀ€ î‰áææOOOˆD"\¾|¥¥¥3f ’““!‹accJ¥J¥¸u늊ŠÐ­[7têÔ‰w»Íþ½W¯^èÕ«Àßß¿ÞuoÞ¼©z×”’ü»};n«x€˜˜ˆD"$''ÃÚÚZéü•••ÐÒÒBPP&Nœ¨Ò1<þ¼Qå}ëÖ-èé顪ªªÁ}"ëî_SSqqqpppPéüüü0`À•Ë`×®]pvvnT9$$$ -- JçÍÌÌ„D"Á‘#G0þ|•ö¯®®Žÿýo½õ–Òyïß¿+++DEEaàÀ­ò—€¿ÿþ[nYhh¨Â l„´%jjj8uêfÍš…Þ½{ÃÑÑ6lüøãHHHÀŸþ [[[8::bçÎX¶l¬¬¬ðã?â‡~PzŸOž†ÊÊJ•˾)„‡‡cÉ’% S) ·VVVXµj•Ü2ÙTÊ„´U–––ìÌ¢²óÚ;99É5V[¶l€£»M™2E¥}®\¹RnÿµÕ®zoHLkuâÔÔÔ •JUÎ?yòdøúúª”÷áÇx÷ÝwñôéS•òGDD OŸ>*ûóçÏѵkW¨««ËUå´%UUU …ÐÑÑ‘›\ ¡âââ`ccÄÇÇ«t b±K–,———Jùÿù畜À‹š¨1cÆ4ª­­­õêçUüNµµµåþ …Ôi†ý]¶¶êر#233[4©Ê×ד&MR9ÿƒЯ_?•óËj>ÿüsìÞ½[¥m„„„àóÏ?Ç£GU–íÛ·Gaa¡Êù]]]qûöm•ókkk«Ü°Löê¤%µå›:BÚ²¢¢"lݺaaa¸ÿ>f̘www¶ŸùÒ¥KñÞ{ï±qª¢¢Û¶môiÓ©ôþΟ?/¾ø‚m;õõ×_ÃÃÃwîÜa×™9s&<<<0oÞ<ÄÄÄ´€Þ»wïF55µF] Gމ›7o¶¹/¢T*…ššÚ·o‚‚•¶QQQöíÛC,·ÉãÎ;ñÅ_¨œ?//íº¢jþªª*hhh¨| 7nÜ€››]Y yÅ qòäI,^¼ÎÎÎ8uêþüóOìÙ³ÿüóÛ`vúôélœ*((@RRþüóO?~\¥Á¹sçbÑ¢EˆŒŒ„T*Å_|v]»vÁÓÓ¶¶¶õN¡ÚjzVV:tè rþSS˜úúBMM *·ò•[(7FII ôôô^‹†¹¹9ÒÓÓ_ù~322ê¼àe"##Ñ»woXZZ¾´WÆËjJT}íPXX¸»»ãÌ™3t•%äñóóÃÕ«W±jÕ*ddd@  cÇŽ055…ºº:Ú·o‘H$×Ò\__ÅÅÅXµj•JýÐ-Z„_ý¾¾¾èÖ­\]]ñé§Ÿ"##ƒ]§S§N¸téÜÜÜ ­­ÝúºŸŸŸÊ­¢ RK Zu&okd£©Nž<‰Ù³g444”îË]TTÀ˜1c^Ú+¡>o¿ý6Ξ=ûF_ºvíÚ¨^ :u’ûQBšW`` vî܉9sæàâÅ‹ ÊS\\Œbݺu*õCwvvÆ®]»àãã===¸»»ã«¯¾Â… äò4¤V«lÅ2`ÀÜ»w Oøî; !UéššÀO?uûø!гg³ÿÛo¿sçÎaÞ¼y*åwrr‚··7Þ{ï=¥ò%$$°s蚘˜ 77·Þ>‹u°]&,,,pïÞ=¥ö/‹¡¥¥@ rÙɪü !äU“Í[[[`ïÞ½ÐÒÒ‚¦¦&=z„?~ï¼ó’““¡¥¥…ªª*¨««ÃÈȨAûqssc_«íÛ·ÖÖÖ˜:u*âãヂ‚Œ7yyy¸}û6F ¶ÐeÕµ ½¡}ü~üøúkà%¾¹ØÙÙáÈ‘#oÜ¡ºººÑ-ƒƒƒáééYoÃWEÖ°®¾*®ºÊÊÊЮ];•÷ùôéSØÚÚÒ••°qãF\ºt vvvõ샎 IDATx÷Ýw!•JqðàATWWã›o¾AZZ0}útôéÓ˜5kŒ›7oÊuAk(===H¥RLš4 999ÈÊÊÂÈ‘#amm°°0…BtíÚ=zôxé¶ZM@g¦Eç;¾{÷. Ô¨ãoÌ“)‘'Õ}ÌÌÌ 333•ò/\¸^^^XºtiƒólÚ´ ëׯ ZKõÌÌL¶V¥¥Úr´6˜e¯²ZNàEëÚ[[[Ë :6kÖ,/z帪øÊwΜ9ìÿ›ššÊíOÙ¶ZÍ;ôØØXv¸;U„= ç°0•óËÞ_«*##æææô‹h"¶¶¶* cdd„üüüû sçÎUMMººº(++{£¿eeeزe ý i€×f$ˆð ð¶‹ ÐÈ!C[ {{{<~üööö*åïß¿?îß¿¯Ô)èß¿?ý*!o¤ ÀÂÂÅÅÅèÝ»7¬­­±qãFhjjbÉ’%¸~ý:$ âããqðàAtëÖ Ë–-c_³©««+=üë±cÇggghkk#** AAAøý÷ßÑ·oßñ-<[¶lÁæÍ›aeeÕúŸÐ[“: ++«QÛU÷ªª_¿~xðàÊù‡Šàà`¥ò$''£sçÎ*ïsÛ¶mX±b…Êù“’’ä¦ $„WiÏž=ðôô„©©),X€7nàÊ•+ðññAXX´µµ±gÏ|ýõ׈lÞ¼žžžÐÖÖ†‡‡‡Òû¼xñ"f̘E‹aæÌ™ðôôÄòåËQRR®ãää„¡C‡¾t[ÍП?Ž£GâèÑ£¯¬_ò²eËðûï¿«œßÊÊ ‰‰‰:†ÆaÛ‰ÅbˆD"•ó?zô½{÷V9EED"Q£Úbddd(Õ3€òúÐÖÖFll,ºuëÆŽ)‰ØÞ;šššPWW—k(«­­ÒÒR…å µ}ûvœ8q‡‚¶¶6/^Œ›7obøðáì:ZZZ/máþJº¡¡!ú÷ïþýûC__ÿ•œYGe”––6ªu2iyR©T®abçΕžä%22ŽŽŽ^ÔÔ4¦–…Òöœ;wNéI•öîÝ‹O>ù¤Áë×î‡nnnŽ?þø€uëÖáí·ßƉ'”|ÁÕÞÞöööÍ0ËËË¡kh¨0U¦LjjªÂL7ÊM¹§ªÌÌÌFpÖ©:@ŽLcGJ=z4þý÷_•ó …BjaÝ |öÙgøóÏ?© H³‹ŠŠBçÎÙ¶ºt邵k×bãÆ011ABB¼½½ñçŸBCC¡¡¡ÈÉÉ@ €‰‰Iƒ÷S{>ôuëÖáòå˘={6¶oߎ‹/ÂÛÛ:::ˆGbb"RRRƒz‡¤~-Å%''£sÿþÀŒ-v ºöÚµk7nœÊùec7•.]º4z¤7Ù²ªýª;tè 7Ai=ŠŠŠØwˆµoJe¦diiÙ¨ét QæšUû:þé§ŸâÆ^Ìñ1wî\DEEaÕªU°±±ATTôõõõ07nÜ8èéé¡OŸ>°··ÇÝ»wѧO 6 qqq` Ã4hâ¯VÐ3SVkahhˆ‚‚‚WöÔ-‘Hšt†°–è2¥ì .¤åTVV*Œu¯êd6„´uoHÜDI;v”»¦Ëæ(oLcâaÆÉí¿öþjwåîÒ¥ËK·Õ*[¹÷íÛ>lÔ6ÔÕÕÕ(­±Ów~ðÁoähqÑØùä/^¼ˆéÓ§·é2¨ý¿5333ÃÌ™3åþ5d$+BZ3‰D‚´´4vjÔ¢¢"¤¥¥±>›6mÂÒ¥Kaff†Ù³gcôèÑHHH@¿~ý ¡¡’’•"ÃÂÂ0qâDøùùáÂ… ÈÍÍE||<Ö¯_áÇÃ××Û·o‡©©)œñÕW_µî't6•´í_QQÁvk‘iì÷zÔ¨Q “CÈ+pçΨ««£cÇŽ ®]»°téRìÞ½Û¶mƒ––&OžŒ7x1TkXXRRR0a•b_PP444¡¡¡˜ýôÓ—®oddGGGlذkÖ¬Qz{öìÁ;ï¼Ã6h=z4N:…ÈÈHvï¾û‘‘‘X¾|9~úé§ÖÐ ““SSS•óGDD4jP.NNNr_,e½ÿþû8vì\BH›°~ýzœ8q®®®8pà@ƒò”••ÁØØ#FŒhð~dýÐ+**ЫW/<}úëׯ‡‡‡\\\——ÇNÒ²iÓ&|üñÇøã?؉Ÿ( ¿æ¾PÝ»wdzgÏ”ÿÌ™3pww—[6lØ05(?W u¡PøÒF„ÒZ899!88¹¹¹0`>ùä>rkÐ'L˜€ÇKíµlnnŽÔÔTFb/²DUU• t ÅÅÅ2 ½zôè‘Ô7À‡#ûm`` æÛTß šüeÒ¶P@577«¨Ë"ºIz_ê´Cîöööððð g(Ab^¿~Aƒ‰ýfjj*q|é… °bÅ F£í¡´F $£¬¬ ÁÁÁxþü9€ºÈ—àà`¤¤¤ž?Žàà`:ZUU‚ƒƒé?i‰ˆˆ …™bccÖ`TWWË¿A¯­­›-»Á//¯Vå '(ˆ—ºü§Ÿ~*±@Pjj*ý¤-BGG‡¥†Î šH ( ;vìÀ½{÷ðóÏ?ãöíÛøý÷ßQXXˆßÿ¹¹¹Ø¿?¼½½áëë  Nv|É’%øì³ÏÄßZC@@&OžŒ˜˜„††bóæÍ˜7oîÞ½K¯ãááI“&!++K¶=** ppph ý,"77Ý»w—º ¦™ÒRSSIîN SƒÊ”©S§Âßß_êòı@è8bccacc===DGGãÂ… ˜3g.^¼H{½ÛØØÐé¹ñðáCxyyañâÅR¼~ýš™SSSÃÅ‹1a¨› LMM•HÚ»Ý º••áè舴K7nÜÀÂ… »ìIØTb55µ‡hD1A .Ʋ¨¨ˆ\å¡KðñÇÃÅÅaaaàp8-®¯¥¥…>}úàÈ‘#رc‡ÄíTVV"??.\Àĉ¡¡¡ÊÊJXYYÁÇÇtöÏC‡aÑ¢EPUUm1¿ [“c”••%òRojîuéÒ¥¸|ù²Dm5&Ž£¡¡!q @%%r:ÅeÆ °¶¶Fmm-V­ZE¿ä(++CYY™V~¥V …(--…FŒ!q;/^¼ÀùóçQ[[‹Ñ£G#>>NNNøï¿ÿ0lØ08p111àñx`³Ùèׯ ±gÏbÐe…¾¾>=l" ëׯÇÉ“'b_™ªýEGG·¹0@ ´GGGDFFÂÃÃúúúØ´ivíÚ…¯¾ú ß}÷ÊÊÊpùòeìÞ½sæÌ‡‡nÞ¼ Vµ3~üxlݺ›7oFuu5ˆÝ»w£°°vvv8yò$ú÷ï---888 ºº´älS°É!läçç3ª£[·n(,,„¾¾>éÐˆŠŠjÕî»TTT´ú¢’7233"ÓÐYÙ±c”””èÑFGGG±éH777PxyyAII B¡qΆÈÈH°ÙlŒ5 Û¶m‹Å‚ŠŠŠØizz:­ùN z+éÙ³gƒvù…©cdS¨ªª¢¦¦¦Cöir˜Ž$>>gΜûíñãÇ$Z„ Ð¼m%jQß ŠÖm‹©Æúõªªª¶ø?1èÍPYYÉH% ¿˜™™!-- 666R•çp8$l¬,,,àèè(öÛ·ß~K:† ð¢W¯^èÝ»7"""‹ÂÚÚ·nÝBEEììì ¤¤ooo¨««ÃÞÞ^¬www6ÊvåÊP…ùóçƒËåüýý‘““ƒqãÆIõp/ó9ôS§NÑ"ô²‚é°ø­[·0oÞ¡#PVV¦G^õôô ¯¯O;¯ÕOÚÂf³¡­­M+¡š››cèСHHHh²înݺ‰ýŸ’’%%%z.½~B˜NaÐMMM‘žž®Ð'ÄĉñèÑ#©Ë#33Sî÷³-FIâããŲµ–ζF d‹³³3=/‡¯¾ú øòË/ñù矃ÇãáÚµkرcvìØ777”””`áÂ…øàƒ0gμyówîÜÁ'Ÿ|Òd;[¶lATTîß¿íÛ·cÕªUÐÕÕÅÀqäÈ888H÷(¯«§§ÇXvT#(mXÁ„ „ &HUÞ¢Ah¡ý.Äw½®[ÃóçÏ¥ö„'ƒuëÖaݺuô÷Ñ£G‹-¿råŠØ÷K—.Ñÿ‹²2ÖOªÒõ×{øð!àèÑ£Ìl^g>8}ûöErr²Ô凊—/_’³¼ Ç(×@gðå ŠM—ŸCß³gO«Dõ „ƨ¬¬¤ç¿Úš÷ߟ~‚'íËõë×ñêÕ+u9*œœœèœÇŽƒ““222 '''9r¤A‡†‡‡‡Ämž>>˜;w.6mÚ„Y³fáòåËðóóƒvíÚ…O?ýÙÙÙ Â_|ÑìöËu¶5cccF󷺺ºŒcÙ òOzz:LMMÕÁãñ ¦¦&³}ðññÔåkkk¤~$­ãÝ8ô)S¦ˆ-?vì˜Ø÷“'OÒÿM—”Ë—/Œ¹sçÒ¿?~üpñâE‰êéÔw€… ÂÁÁ†Z$>>ÿûßÿš|0,..†®®n“åËÊÊ ­­-³ígš Hšþêˆ|襥¥ÐÑÑ!ù sè„N¥¥%£ÉmÛ¶aß¾}Í®sêÔ)¬Y³¦]¶ŸÅbAMM <OnúT”½þ_s¹Ÿ¥åðáÃøê«¯ÈILèÊÊÊpèÐ!:Ýqyy9¾øâ \ºt Ea÷îÝØ¾};’’’ðöí[lÛ¶ ;wÇãá§Ÿ~‚‹‹‹Dmòù|üòË/HIIALL ¶oߎ;wÒ×{UU¶oߎo¿ýiiiòmЙÎR‹¥°'iZ‚dÓ²Œ²2~ñññŒê`³Ù…Áé¹sçŽ?Ž„„TVVâàÁƒèÛ·/V¯^;wî ++ “'OÆÙ³gqþüyŒ?ôp»P(Ä‚ 0|øp,[¶L¢6¯^½Šßÿ¹¹¹Ø´iƤ¤$zlïÞ½8p ¾ûî;ù6èL³lyxxÀÞÞ^aO }ûöaÛ¶mäJêĘ››#55•t ç,^¼˜ö$çr¹øé§Ÿ°}ûv(++#** %%%€Gщ·ÊËËprrÂÝ»wŠÂÂÂÛ ƒ††˜:u*>ÿüs¤¦¦bäÈ‘­Þ~òj¨à´¤T'ÉÛaYY´´´]¦££Ób;@ tF„B!æÎ‹ .ˆ¥}l6¹¹¹011Á’%KˆA—%LÓÀΘ1Cîu¼™¤˜€ÄÄDZú@ñîƒl@@ C%´+ÎÎÎèÖ­ž>}Š   ())!22¾¾¾7nôõõáçç‡õë×cíÚµxøð!4551yòdøúúbãÆ …´8LShhhÀÐÐ|ðNž<‰5kÖ`ݺuøóÏ?áïï=zà“O>ŸŸüýý1bÄ<|ø°E­ ¸Ú FFFtiéÝ»7RRR:4¤HÑðõõÅÌ™3»t$$$`Á‚äd¨Ç»¹§ „öæÝ8ô©S§Š-ÿóÏ?žÿóÏ?ôÿ¢XòÇ·ºÝýû÷úõë'–ƒ]Óþîvt¸AÏÈÈh 9ªhOתªªàóùä,ïâ°X,())5©¹_]]MKBJKUU£hk×®añâÅä`]˜vr¯©©Ayy¹Ø_ss ²¢-²¥ä---”••12èjjj¨®®nòáÕØØX¦û(Û@ (: øöÛoHKKÃìÙ³áèèˆÚÚZlݺ_}õ^¿~øøxlܸ[¶l«cáÂ…tIX¹r%fÏž TVVâÛo¿ÅÒ¥KÅ´àííí1{ölìÙ³G6½wïÞ˜5k–ØŸ¡¡¡Ø:………{¶åååÐÔÔ”º|EE444ȕЎèëëKÒcÇŽÅÓ§OeºDíŒ@sÒÓÓˆ¬¬,TVVâæÍ›X½z5víÚ777”••aÆŒ8vìŽ?[[[ðù|x{{‹Ù”I“&I,´T\\ŒI“&aÊ”)¸yó&ÆŒƒŒŒ \¿~½AãÇ—A—„ýû÷cëÖ­R—¥ã÷dÉTÖ2–––ˆ‹‹“ºü7ß|ƒ(tØÚÚÂÏÏœ FIZж ˜2eÊz¤‹Ëåâ‹/¾@PPÆììlú¡<::ÑÑÑê¦Ëê‡'$$ÀÉÉ Ož<‘ø!bÏž=ð÷÷ÇÒ¥K±páB‰MãÅÇÇÃÉɉV°“KƒÎ”¬¬,2ÌÈÚÚZ¨¨¨´kmá\HèÚ06!Z EQàóùX¶lBBB$ ™¬©©All,ž>>xÿý÷accƒôôt€ý"¤¥¥kkküòË/àp8ÈÉÉÁªU« š¬ÛÖÖ¶¶¶8v잀NôÂåráææ†ß~ûMqßÐ™Š²´#FŒ@dd$†.Uy+++\¹r¥E…E¥-’ã4§T' òàKAèX~ûí7üüóϤ#mJýtsæÌ¡ÿß±c‡Ø²úqé"ôÝ»wKÜ‹ÅÂ?ü@_¿~½Øò>ø$z8{ƒÞèëë3Êmkk‹3gÎHmÐ íOpp°Ä!" Ò‘­ ++«“ßëׯ1vìXFõŠæ*GŽÙ¬‚`UU9BW3è½zõBjj*Qj#4I@@¦OŸN:¢hiiá½÷ÞûÍ××—q½<UUUÈÉÉA`` ‘&t(EEEpuu…±±1ýf///lݺûöíCJJ JKKñÓO?ÁÉÉ ºººÐÐÐûö-.\¸€ü±Å6===áããƒ#F`íÚµpppÌŸ?cÆŒP'ýý÷߃ËåbÁ‚MfíÒZîÇdž |ò ÐþÔWj“–I“&Ñé‘Õ«WãìÙ³r³=šššüðC4)-ŠC¯®®ÆÄ‰qôèQ¸¹¹AGGË–-Ã_|7n´þå‡6Å&33³Eq"66Vê66mÚ$U!ARªªªPSSÓêrŠ® H/ø|>rrrPXX>Ÿ‘#G",, YYY¨­­ELL ž?ŽëׯCKK ˆ‰‰Ahh(JJJPZZŠ1cÆ ::š–m [[[8::‚ÃáàܹsHHHÀìÙ³‘˜˜ˆû÷ S§N¥ëÔÔÔÄ… pçÎfG;Û}¬·¦¦†Þ)i’³¨©©ÇãAMMœmR"º$¡]yÅÓÓ–––­ûâÅ ¼}û–t¡Í)**Bll,”””••…+V,,, ¦¦†½{÷âþýû°µµ…½½=îÝ»‡W.%{ IDATàï¿ÿÆëׯÁb±°téRºŒ¾¾~‹m²X,”——cîܹÈÉÉA||yòd³7(UUU‰êáóùä$%0¦[·n˜>}:íѾgÏØÛÛã·ß~—ˋſÿþ‹Í›7ãþýûXºt)8 ¦GrêÔ)Œ7ßÿ½DÓ·o߯‚ °víZüóÏ?pttD=°lÙ2z¼¼<\ºt ‹-jö!Af½ººjjjŒuÀ™W¯^aÈ!]b_»z ÕáÇãÅ‹Œê`*®#TTT@(KB TTT```@ß°aTUUñÙgŸÏçƒÃá€ÍfÓ¡ÆZZZPRR‹ ÿè£Ð·o_|þùçi_üñǸpá\\\ ©©‰„„‹Õ9}útáîÝ»Í&²"ak2„iÒ–çÏŸcäÈ‘í¾, ,‹ÑwäÈ‘xþüy—=֧ɘTBÛräÈÒ „6ÁÀÀŸþ9ôôô$ÇÒÕÕÅ’%K0vìØ&ó—×CïÝ»7Ž9‚€‡‡G£Ò®...ؽ{7ÌÍÍ›l›Œy+0ååå‰ÒŒ=§NÂûï¿ß`YYY´´´š-¯¬¬ 6› uuu±eDò“ÐêóÖÓÓ“ïikºš¢¡í(++CDD[·naÈ!8p ttt€7nÀÝÝÓ§OÇ¥K—ÀårŽÔÔT@XX455¡©©ÙdÒ'Q>tpttÄÀñÑGáõë×èÙ³'í“’’%%%<}úååå ‡Ãi2ÇÜ¿¡³Ùl©â×å TTTH]~ùòå¸té’Ôå›Ë©Îtþ7 €Nñ' yyy044$w’.Dmm-ÒÒÒZUæã?nVò²1²³³IgZ…@ €žžF>ŸI“&¡¸¸kÖ¬ŠŠ <555|ùå—X±b ðßÿ¡ªª ÕÕÕ9r$jkk±dɉ^¸ÆŒƒ^½zaÒ¤I022‚½LTç¨Q£`bb‚^½z¡{÷îŠû†®«««ÐÜÀÿ 7Ož}Z¬‹Ì¡¢¤¤ÔÀ -<Ü+** ¡¡!uùÇcâĉÚ|>ùùùb-å(OHH€»»{‡7Y´IPì·ôw<óóó! ÁãñŸŸ’’@ii)òóóõ)**’ht¹±:›Qmi¤·Kô®ìaß5SoêîÝ»7{õê†Ú!û ¬¬Ü¨—{lll‡Ëúfeeáüùób111RÝ<›BKK “&M¢¿Kûà$ÒÈÍÍEXX¹M’––† 6ÀÍÍþÍÇÇçÏŸÇÃgŸ}†½{÷ÂÞÞ~~~˜;w.Ž9‚?þX¬žgÏžÁÙÙ¹IÃ\Ÿ«W¯bÿþý¸ÿ>Þ¾}‹#GŽ`ñâÅ[ïéÓ§øöÛoåÓ ?zôHìbíh*++Ááp ¤$}$&&6éœ@h[&OžŒÀÀ@©Ë3Ïž=“é>XYY!**Jêò7nl4ã˜,077ÇÖ­[Åþ¤‰¸øå—_š\ÆårammMß½{7£m.,,”ꡃÐu033Ã×_-fÌUUU±uëV¨««ÃÄÄ{öìÁÎ;‚-[¶`×®]6l˜˜1ÏÎÎÆöíÛ%šJ»v톎E‹!++ ÙÙÙ8uêTƒ{Å£GZ´W kÐåÁ˜ƒ®8]6lX—T-|ðàüýýÛÄÈ·¥¥¥Ø»w/¹¨ÍR]]={öÀÇÇÓ§OoqJIÄþýûáïï[[[‰„ ÜÝÝñàÁ8pfffÐÒÒŠ+0fÌzþù={ölQÑRa‡Ü»’(K[ЫW¯Éqˆ.6¡Ý …Ow¤¥¥I¤®ellÌ(‘h]{{{xxxÈÕö·44-œñðáCrÀÄ ·5vvvŒž EC㊞—]a2å’’Òª4…Q]] ‡#³ý—E¦4y@ôf;|øpZC ‘——'·ûåççGß'¼½½ÅöU–/%bÐ; l6›cB£0M]zëÖ-Ì;·Ã¶W[[¥¥¥ ßç)S¦  SŸc¢}¥ä,//Ç‘#Gáááä"$(¶AÏÏÏWh‡6xñâFŒ!uyY¤¼”5L½ÌW®\‰sçÎÉÕ>UUUA]]]¢uÛÂÓ¿Gm¦ŽÖYQUUŸÏ—Ûí£( ååå€ëׯ¨ËMA (¤A¯­­•+ Óö¾‘7†««+-Z$uùÇ3ÊV' iøŽºQNœ8?–º¼žž^‹±ÆòŒššý–¦èÄÇÇÃÁÁAìɱ•##£ådßUf,**’ûøñK—.¨sðËÏÏGFFnÞ¼ gggÚø“‡9‚ÜtBë155Ezz:ý½¸¸¸UŽ@C‡ÅË—/éï|>ÊÊÊ­z°ÒÕÕEII ý8tu],,,àèè(ö×¾vvv%º}û6¸\.’““ñâÅ‹‡¶EFSÖ¼zõ Ïž=ÇC^^„B!Ô*//|>AAAˆEyy¹B?ຨAWQQEQ]z|Íš5- g4‡HϾ-),,$š× aªe¯HHªC””„¾}û2j+33ÊÊʧ¼LJJR˜~ÌËËCii)^½z…ÀÀ@höͼÕƒÞfDEEÑCrÒ¦;©©IšS¹1ZëMKèüܸq .lõÃ¥èÁ²-”úŠŠŠÅP?yòcÇŽUˆþþ÷ßQSSƒÛ·ocΜ9M®WZZÚfaháááxï½÷:ý¹üÏ?ÿÜÝÝQSSƒ€€úJ´ìÚµkêF÷Ä K…••=$7`À² 266Fff&}ÃÐÖÖ&G¿‹QÿêqˆRûJй¹9RRR¡¡¡5jT«Ê3G?~<‚ƒƒéï©©©mšÉ¬-áóùbÚ "§À˜˜ <¸Ér ÀÈ‘#Ûd222`jjJ¿¼«%Áãñ½(È/_¾„@ @bbbƒÑ‰/^þúë/ú·–’ Q…ªª*ró ½iNœ8Ï>ûLêò°¶¶–º®~¸ºº"66¶Õu>€ÎÈvüøq¹ŽkooDégïÞ½+öYXXHÏåïÝ»WìØ¾zõŠ$)"½íxýúu³Oø]'Ož`ܸq­*3tèP:<&00°Õ^ò›7oÆ¡C‡ÈUCh’Ý»wK•¼#Ù»w¯Ä±ü555Œ2ô) ¢}}–”” **JlŸþ@;êˆAï’˜˜˜Ðé¥ÅÀÀ U) 3袼ðL»Ü»w³fÍbü&Ç$Û\[(ÅÉ’§OŸ*Ìü7¦L™BK£ÖçÙ³g3fŒÜnwPPjjjˆ„k„……áÖ­[(++£ý“ž={†ÚÚZœ={ÉÉɸwï=E$öI ]flß¾ûö퓺|Ÿ>}§\ìè!ö– 2c\[[ ‹ÅÈÃûõë×4hP‡î·¥¥¥ÔÎïâããƒ3fH]^Q•””§¾ÿ>ìì줮×ÛÛ›Qÿ8pß|óM“˽¼¼È¯„B!„B!JJJh£}ÿþ}ÔÔÔ@ ÐËEÇ^ÔŸ¢ÏÈÈÈ&Gsþøã¿‘äPrhÐËËË¡¥¥%Ó>{ö,V¯^ݪ2\.—v2‘gG¤Îަ¦&­²% K—.ÅåË—¥.?aÂF*\.•••mÒ555PQQ‘Ë㔘˜ˆþýû·[ý'N„‹‹ TUUÅúƒÅbIÜ'•••àr¹êT [;/üâÅ øúú’‹RJîÞ½K;܉^–DŸ¢{-ŸÏ§§ùÜÝÝÅÖiޤ¤$F÷ bÐ%$;;={ödTGBBúõë'uy¦Ù™‚ƒƒ1a©ËwÕøm‘S˜JŸjkk‹©ˆu4L§M¸¹¹ÁÖÖ¶UåZ£~¨®®ccc±ßDŽnÒŒd;OŸ>>|¸Åõ>Œêêê&ÎÞ¾}K¼Ã[yO¬ÿYÿ˜¾+ž#ZçÕ«Wð÷÷Guu5RSS! iü ;;?Fxx8âââºDŠ[…r777Gjj*ÙgÈ’Q¦¨ÚÚZ°ÙìV—_¼x1®^½*ûaƵª ‡ÃAuuu›ŒrQùEYYYªhˆÒÒR™Þ=yò½{÷nñÅ£%§0ooo"èÒÎTUU¡¤¤ô0~vv¶Ø:eee¨¨¨@UUüøqué—kkk‘““C?˜‰–½ûùîÿ’RTTÔæ‚^ 3 ÷yWúTÚ·;&™®¦N ©Ë3v¬k+˜ÆòK3íQiÊDzôµµµ (Jª«¶êiár¹ óöךѰùóçcÈ!í²õ‡×[ºëééÁËË ~ø!€:ýø¬¬,ܾ}»MFWêk!:Ñ‹¡‹‹ ***àííMO·ˆ–½ûYÿÿ³gÏŠÇššäåå¢(:y”hÙ³gωªªª‘éí2Nq¢ÄL†üUTTPSSƒ·oßÂÌÌLêm)..†®®®Bö£¨õ¡ÈÈÈ™™™´£Ç>Yå28p ^¿~­çËÇ[Œ¦=ýú믭VÍÍ}kjj6;•Ò’˜MslܸGň#píÚ5$&&ÒS~ï&‚Т†hX˜ ˜ˆœbEÇ1//9}wYý2>>>(--¥GŠŠŠ  ˆŒŒ DGGÓ/¢sHôY\\,Ѩ—Bô¦¼e[Cyy9455;ì­£=ÞNCBB¤ ÷%x)++“zh“i Ô%K–0š6E ȳC˜¤ˆæ|»:®®®øøã¥*«££ƒÅ‹cúôé–2µþtϼyópöìYp8Ü»wè›2›ÍË?!ȼz§ººšö#:yò$JKK‘ššŠÒÒRäææÒr½¢ðbÑç™3ghß7nжL¡ º®®.#bkkkZþP‘‘6y…H)MQ}êÃ4†ùÞ½{˜9s¦TeMMMñöí[©CîTTTPYY ¡P(•¼hŽšÉ[ggbÊ”)°´´”YûåååPQQADD(Š¢=ï „ëׯCMM ¾¾¾àóù¸víÔÔÔP]]M{å“;Bk 8::ÊÞ 3M– ~¶ˆ¶ð²fJQQcg®ììlôèÑCª²666xþü¹Ôm3-//0u144Ä¥K—0}út©ÊoÙ²…N˜! ,€»»;’““ѧO™ô_BB~þùg±?"Òääd¨ªª"44Ý»wð~{÷î…¦¦&îÞ½ 55µŽv÷ïßøùùÑñÞ"©V¡1ØÝ`dd$†Îè`Ù²eR—ŠŠÂÖ­[¥*»uëVüôÓOR·mee…?ÿü“‘˜FŸ>}€¯¿þZêQбcÇ6ð•”#F`Ñ¢E¸~ýºTåutt˜˜Hßܤ¡{÷îŒGÿýWêò‹-ÂÇŒ%K–HU^]]wîÜ¡S_Jk(¦N*³G¿~ý°k×®oªÏž=“Ù6}ðÁPSSS¸¬Š‘‘‘PUUEVVîܹ .4¶oß¾øã?0iÒ$…B”––âùóç033ƒ»»;¦OŸÎÈ…@ ºTôÊ•+êÞ½ ´†M›6ÁÛÛ[j‡´aÆáĉRϳX,̘1R—ß·o£Ä«V­‚Ôåµ´´àââÂHuÎÉÉ©Õ!k"ôôô0vìXF²±“&Mj6ýfKØÙÙ1òng±X¸xñ¢ÔÓêêêØ¶m£c°hÑ"ÌŸ?_f7ŽÆTþZã`øã?ÂÀÀ[·nE||úH¡o<õ5 H*cæ, UUU¨­­E~~>444h‰å¤¤$˜˜˜ ??ÞÞÞxòä †ŠˆˆÄÅÅÁÛÛ™™™ðóóƒ@ À7PPP@€ÈÈH¨¨¨ ¢¢ùùùðòòºuëHçËDË@ t*V¯^œœ:î¼+¨óIƒ(\ðÑ£G°±±Axx8,--QUU…ÀÚÚšÒ¿sç8 ˜˜øùù!::ÉÉÉðððEQ …8|ø0ÒÒÒàææ†ððp¢¤¤%%%¸|ù2„B!-ÒÓèv±Ùl¤¤¤ˆýž’’Òf²Éä @ €nݺáàÁƒ(((ÀG}'''¸ºº6)×ìé鉹sçÂÓÓ“t^+Åßß½{#GŽ„P(DMM =òR?Œ0)) ¦¦¦HIIŽŽòóóQ]] www€Ëåâܹsàr¹¸téÔÕÕáãペšZ°ÅÀÀ/^—ËÅË—/‘››K?p$$$ 11‘Ž©¬¬ÄÙ³g1dÈðxX,c_I8sæŒXF6Bç#==]b¿$>Ÿ6›äädTVVнµÒCýõ?“’’ ­­ 6››7o‚ËåâòåË`³Ù@aa!RRRpìØ1hjjÂÕÕB¡iiiˆˆˆ€––‚‚‚OOOZÛ](âòåË(..Fyy9=²aaauuu¸¹¹ÑW®\ÁªU« ¤¤„ªª*ú¡¾_1è¡ÃÐÔÔìФ%"™çåË—Kô¶N HB~~>mô®ÐWRRRƒl ééé011Abb"ý[ii)=eP_>¸¬¬ l6oÞ¼›ÍFll,-·}çÎhhhо>>>b²Ä)Ž@ ´ ***ô<ª(»ÞæÍ›[ÌTÖ¬Zµ ³fÍ‚šššXxªª*x<^“åx<žÂ«*:999Š‹ƒN Ú…O>ù®®®€ÜÜ\tïÞššš¸víšÌ¶iëÖ­X¸p!f̘ooolذÿý÷_“ëïݻ۶m#“ !wÐfLž<¹M’(µZZZxï½÷  ñèÑ£f×=z4ÉŒFP(È:@h3¦M›ÖhÒš 4˜W”éOI ·oßn6cßøñãñäÉ“&—7—$IãM ƒN :7n¤#å…?üªªª°±±iuY###Ü¿C‡mtyAAã$LB›ôŠŠ $''7[Aaa!\]]‘ššJz“@P`²²²àêê WWW:f¶¶¶®®® ây;...077‡¡¡!òóóaffÖbÌð AƒÛê¶rrr%&"¤2èeeeØ»w/|}}›,\PP€7n ÿþ`”t„@ È–3gΠÿþèß¿?Ξ= ‡S§N¡ÿþxùò¥ÄF½OŸ>¨­­‡ÃÁúõë›|‹•´µµ¡¢¢‚µk×ÂÊÊ 3fÌ@RR’Ôõéêꊉ£ÔG 0J D 4G“g–¯¯/fÍš…¨¨¨& GFF¢OŸ>°¶¶†nß¾/¾ø™™Ùàí¾¨¨qqq$o2ÐOçJJ7nœÔåËËËammòòr¤¥¥¡°°|>ÖÖÖ°¶¶†ƒƒe¯¸¸˜Îö%"##%%%˜6mnÞ¼‰øøxØØØàÅ‹ Ó‡ÖÖÖÈÊʆ ðêÕ+üòË/ ‚‹‹ ~úé':åíË—/QVV†ˆˆ±ÑI>Ÿ dddàÍ›7†èq¹\äççC]]],ã^ddd£#ÊÊÊnrÔ 44”Þ@@/‹‰‰iõè)›Ík‹ÍfÓâ>>”¿¿£ë]¹r…޾8zô(õôéSêܹsÔ¥K—(WWW…>×vîÜIñx<Ú¾1.^¼H½|ù’¢(Šòòò¢=zDÚÊÅÅ…t„ ©ï±~úôiêÍ›7Ô¯¿þJUUUÑÞòùùùÔ¾}ûèˆ1'''êÆThhh‹Q6?ÿü3USSCUVVR»wïnt…Ÿ.))ŽŽ€:oìÆ‚ü¹\.æÎ‹øøx„††bùòåÈÌÌ„··7–.]*u|·"põêÕ&—YXXàöíÛ-ÖñÏ?ÿHÜ^DDD«4¸\. Ð&û:pà@ñØË¤¼¼œŽQWWW§Å1ÞeñâÅHOO‡¯¯/V¯^ ]]]¼yóVVV033ÃÙ³gö\ãóùPUU…ššZ“¹ÄËÊÊèXf‡Ó@ăÐvdgg#((ƒÆ¿ÿþK:DF 8žžžðôô¤ïOÕÕÕàp8PUUŸÏb×ÖÖFII ÊËËéÈuuuTVV6Zmm-Ølv³÷N§A˜˜˜ˆ   ¬\¹JJJxóæ ^¼xøøx<|øÑÑÑ´Ú•¼òêÕ+üóÏ?7nRRR°nÝ:8;;C(¢gÏžX»v-ž>} ???p¹\dgg£²²ׯ_ÇÊ•+áêꊩS§¢[·nèׯŸX(TEEþøã@ïÞ½±fÍüý÷߸yó&rrr°víZáÔ©SÈÊʋźuë ¢¢gggðù|°X¬&½òÏœ9ƒøøx€½½=F ¼|ù¼yó†6jX°`Ž9”””`üøñ˜3gnݺ…§OŸV­ZKKK 0 ]Ä:Ú’ŒŒ øøøÐ’–––øý÷ßÔå?h)u' )555àp8°²²‚¾¾>‚‚‚PQQA‹­Y³ÑÑѸsç`È!X¾|9}ƒÏçc„ PUU…µµ5þûï?lذAì:555Åš5k°oß>±ëÔÎΧOŸFZZ}¾yóï½÷LLLèº:;+W®¤³ó1’…1è+V¬ÀåË—1tèPTTTÐóvoÞ¼Á_ýgggTTT`ÿþýX»v-"""Э[7L™2S¦L1éJy¦¼¼~ø!ž={†íÛ·ãÔ©S¨¬¬ÄO?ý‡ƒ+W® )) ~~~pttDee%6nÜ@€ŒŒ ú©Ïç7Z¿šš=§yþüy”••á»ï¾Cqq1¶ôúõkã£>‚@ À™3g ¯¯/¿ü†††Í¾Í'%%Ñõ«©©Ö­[z³gÏÒm‰âœSSS±oß>èèèÀÁÁsæÌÁˆ#`bbB?(899ÉôØÌ˜1>>>())A\\æÏŸ NlåÊ•ô“¹““–,Y‚˜˜hiiA]]/^¼€±±1***ÚMyª#=z4|}}! 1~üxú÷ãÇCCCŸ~ú)æÌ™ƒû÷ïÃÊÊ ÉÉɰ··'–·ÈÍÍÅž={˜˜ˆ!C†`Ò¤I033êU«ðßÿáùóçHIIÁõë×±bÅ À±cǰ|ùrÄÇÇÃÑÑ™™™øë¯¿0dÈúAY”—ãÌ™3X´hÀÍÍ ¹¹¹ ®Ó#F}=ÇÇÇ#77—•éJ9>êK±š˜˜`âĉðöö›Í† tuu¡®®ŽçÏŸ#..K—.…îÞ½‹ÊÊJ¼|ùsçÎ¥íÀ'Ÿ|B?ˆ 6 (--Å´iÓÛ ÷ë×B¡ÑÑÑX¾|9-`bhhˆÅ‹Óikk+¦ƒ+rB€åË—wÊ“ˆÍf·JªôÂ… ôô…èMº>"]åüü|º/—,Yz]]Ý&ëŸ9s&].//¯ÑäÓ¦M£ ¼HÇÀÐÐÞ. .ù‹‹  €‚‚…B™÷µ‰‰ ììì‚ùóçÃÀÀ€*[»v-½ÞôéÓ‘““èÞ½;&Nœˆôôt¤¦¦BEE…¾¹*"öööð÷÷›ÍsN7n-Ìcjj [[[„††bÁ‚$•h;ѽ{wìØ±^^^bN–&&&PWWÇĉÔM“ˆ®Éyóæ‰Õ¡¡¡Ñ¤ô-EQt94¸Nߥ¾´kEEE“ÃÃQ_­\¹³gÏF`` jjj°páBúåææÍ›°²²¢ï3gÎÄÓ§O1oÞ<Òö¬¾XÛÒ¥KqïÞ=èëë‹=H+¤Aê†f-,,œûì³?>¦¦¦055m0ê!z[@?eׇIâyC=RŸwó›™™ÁÌÌŒXÝvFYY¹Bcýk ¨­ ;7 àààTWWcذa8}ú4¼½½a``€ÐÐP,\¸€1cÆ€Ëå6¸NõôôPVVF? ÏŸ?“'OÆùó硪ªŠ²²².s,³?“'Onp¼Þ]ÏØØ¸Áoªªª DÛfΜÙlû& Xüúë¯Øºu+=b0wî\ró'dDýÄ;mAXXzôè]]]ìÝ»—–'´/Ä d‚@ À_ý .eeKOž¡ýxðà=šÖV;v ÅÅÅX±bEƒ-BûðÿFÄ=M«.aIEND®B`‚snd-16.1/pix/randi.png0000644000076400007640000000263111147553270012745 0ustar bilbil‰PNG  IHDR}@§ÍŠbKGDÿÿÿ ½§“ pHYs  šœtIME× ýÔ&IDATxÚíÝÛŽ›0Ð0âÿ™>!!×÷b`-©RK˜LfŠwÎ1˜,Û¶m€ƒ?¿@0‚ €` €›ò,ŸeYNÛ¸Y0,ËòÙ¶í³m[Õ`oÝøõ/2"½nî!õí> ~$68GT>œ4Ç0se±ÿû¸ýø÷XKû ƒèÕ«u´¦R0‚`è,ñ÷hh£KøØ¤æ¾­4°sUÃí ¼¢bØdi[ÍcgÍôRÍÄä·•Œ ÁÃÄx,ÈRÁV©¿ç† ‚àÛV%ûöÚçwÖÁ0QEгoK‹±ï[šÓH=g¬J¨­0à 먚öadp„•AëÅS‚ÃCè©P +‹Ü> ^R±´îß‚ÁðÐðˆµ% ¥¹‡–ÉJx}0ì×ÿ¼-HŸ;öïÜ5µã~|>/_]y—¹‡Xk‘;£áú ´/™{8>Þr z)@U†Iϰ}È:$‚ÌOÔ, ëi;„`à%ZÖ€ xX» ‚§JÝýJ0pó6£ç6-#¸A•®çhYM®ó¿¶t "xh˜ôT%Ç0‚›Ï=´Ì5~Ëõß|O“Hí=.r§D tÁÀK*Œ–k#Âë*Z+Õ„`àÁmIn°Ç‚ ÁÀKƒ¤eá—ûcžïöj˽Ã!±IMwçV1D{ÓãžÛv´~|`é®ÛÞx´ÜP˯pßš–ÄÄ¥`àaÕC;±S¡©IÌÚ»X xhäÚÑÒ•˜¥ Χ‡‡``ÊÁÞúA±‰ÌÒ x·É+Uo³:,Ñ–Äç(Jáðä³*(´aë‘;ÅÚ3o1ce"PEdö/}HjRóîŸ$& 2Dr+HÃIÍØ×ÕȈpñ‚>m]õ܉;|ðG0ÀÛšçW™æÚˆX¸„íH)`,»†…BïY–K´{?ôا]Ã…Ÿ~ž7¹}µpÃ7ÃÜÍlF\ .àæ­È×:xyÐxé@W1‚ ÀÉm„` Á@0×±ì¸g0Xv Z @0‚ €` ÁÁ@0‚ƲkàžÁ`Ù5h%Á@0‚ €`  €ÑÁ°,Kt}Bj{ëóóXksj!Ó¾=µÏ7û“Ã/pkôIí57ÀŽïî¥'ºâÅ ¸¸bÈ Æãc3µ3¶"³¶H^—×Õâï¬ï<ǰm[²•8>V“b­û“CK›Ñ»?08 6kðy]Ïx]‚ €`&¶lf €gƒ%ÝÌ|l¶ƒ£¶_uìÿÍü‹ß¶í¿+/Gíg„BìµýÊc_+Ê«Ñæë*/íïŒ{@Ä*‰}[nûñëS%yìyZ¿oîùi³Þí[yþï6¶æ?v[¾p¿Üöš*%÷½j¾ï[þ®øY§ Kº÷;/­˜M úo~ï¹¥ý³õü©Mƒ£¶_y쯳¨-@˜ãÿ¨5F„Êq^$pgÿÌ©ÇFl¿òØ_ÚŒ¨êŽgjâ2|g‹ý½æ ¯¹y7‰/«"k%¸¢ô¾ê0 c8+BŨ€ÿÙù~{Á1PIEND®B`‚snd-16.1/pix/am.png0000644000076400007640000001040711147553266012252 0ustar bilbil‰PNG  IHDRÈ Iÿ#©bKGDÿÿÿ ½§“ pHYs  šœtIME× /Ãx}â”IDATxÚíÝyPçãð‡pt¨Tт֪`­‚)D[ÇÁŒãU´£xĆ©š¶NkëÎh±Ž£­ãUÔz5íx! µ VÊá`Á¹A‘C!°¿?ò54þÊy>3ùc“w7›wßgßÝäÍ®‰ ˆH/«€ˆ!b@ˆÚ= ‚  ¶¶ö•3655áñãǨ¯¯g-R÷ Hbb"d2Ù+gBCCYóĤ™‰‰ LMMÿ—Jìˆ=BÄ€1 DÄ€1 D BÄ€1 DƧC†šÄÄļ1·&¤Í5 ï¼óŽvúäÉ“F{hb@Úœƒƒ´Ó7nÜ`ÍÏAˆ"„ˆ!"„ˆ!b@ˆ"„ˆ!2:2Ô$55IIIÚéäädÀ”)SE‹qKP÷íAD"ÌÍ͵æ‹È}õÕW:—$%ê–=ˆT*…T*ÕN[YYaïÞ½¬}bBÄ€1 D  ""yyy¬„ô¹|ù2oĀЋNŸ>ÒÒRÌ›7•Á€¼ù’’’ØÒšmÛ¶áÎ;lÄ€1 ÿ111˜4i[éÕ!CM pïÞ=ítNNN—©³%PçD­V#::Z;}óæÍ—–¯ªªÂ™3gзo_n!zó2qâDLœ8Q;­R©pþüùVË—••aÛ¶mX±b·ñDoooˆD"$$$p+ò¢>}úÀÄÄåååÜJÄ€1 D BÄ€1 DÄ€1 Dm¬C†šh4h4ítCCkžf*• Û¶mÓNß¿Ÿ5O H³   éfþüù¬}â9BÄ€1 Dô¦äÀܢĀ´fíڵܢĀ1 D H×ô²+®Òí}óÍ7¬b@ˆ^¥CÆbíØ±[¶lÑNó–í£©© "÷yF׃,\¸jµZûX½z5k¾x{{ãñãǬb1 D È눋‹Cdd¤ÑUrjj*öìÙÃÖÆ“ôöUPP€ÊÊJ£«äòòrdgg³µ±!b@ˆ"b@ˆºG@JKKQ]]Ým¯–òí·ß"99™-šÑoÒ¤IˆŠŠBMMM·Üuuu:ç#¤]DFFbòäÉØ¿?+ƒ:æw¨¨(9rD;}ûöí.[!*• aaaX¸p!æÎkÐ<‡†££#¤Ri‹×***°~ýz|ôÑG]9sðõõe:3 4hv:&&ÿüóÏS‰W¯^…¥¥¥Þ€ÔÖÖâܹsßÿŸ}öŽ=jPùììlˆÅb¤³Ò¯_?ôë×O§A½®'Ož ¶¶ ¨©©A=ºTE~òÉ'¸uë–ÎŽ YÏž=ajjŠGá­·Þj·uprrBNN[uw<ÉÌÌDZZJJJpùòeƒç«¨¨@JJJ»¯_SSAÐûš··7lllpâÄ ƒ—wúôi¶N¤ýåææbûöíF·ÞË–-cëd@ÚW}}=1 /;ìILLäV~ÅN¤©©‰Ñ]±ÚÛƒ ‰`kkkTë]UU…'Ož ,,Œ¿Àwç€ØÙÙ¡oß¾ÈÈÈh—åÇÇÇÃÒÒaaaˆ‹‹k³åVWWãÌ™3íV/W®\A~~>¦NÊtç€ <ŽŽŽ8{öl»¾ÏâÅ‹u®Üò_lܸsçÎÅæÍ› *á 0ƒn÷úÌÉÉÁ±cÇ7Á—_~‰­[·vÉu;wî<¨÷µ#GŽàÓO?5xYjµvvv°··o÷õÎÏÏïVçu]2 •••èÕ«×^Njj*F­÷µˆˆŒ3‰¤]?ËÇõžŸ”––"33OŸ>m÷s¤¶\V`` LMMQWW×®ë]QQÑ%¾>wïÞmó• ÂîÝ»Ûõƒ×ÕÕÁÂÂff¯?˜ÀÅÅ™™™­þ0ø¼9sæ´¸oIuu5ÊËËqðàÁ×:o‰ís)___üûï¿—¿sçJKKõ¾–’’‚ùóçcàÀ:½_YYÙKÇ×%%%½Ö:ggg#88øµê¦°°ùùù—×h4ý€Ü¢uìÞ½YYYèÙ³'f̘¡w+"""PRR‚^½zA.—ëbahCݰaC‹•ovâÄ äççë|ø£GâÚµk-öȶ¶¶6l˜vyÏ_àáï¿ÿÖÙ#%$$ @»·jž'77P\\Üb½²²²`ccƒàà`¸¹¹¡¤¤W¯^ŰaÃ<»ÿû‹ó<ßCœ:u eee(..FAAÕbxHaa!€gƒ:Ÿ_^~~>¬­­Ñ»woò/^„¿¿¿öÛ©çç‘Éd˜>}:–.]ª3Onn.LMMþù§vtBUUÌÌÌ`mmÝb[mÙ²·nÝÂÆ‡ªª*í6¬¯¯ouÍëŽ~¨¬¬Ä÷ß &`ñâÅ©<Öcˆ¦¦&XXX¼zŒœð‚‘#G ‚ [·n"""}…?üPAN:Õ¢Lxx¸ P(ô>¼½½‚¿¿¿`mm-ÐyØØØ …BpssÓy~èС‚³³s‹ò͹\.Œ7N;mjj*( ÁËËKoyoooA¡P"‘HçùiÓ¦µú...‚B¡Þ~ûmísR©TP(BÏž=[”ïÑ£‡ P(„Ñ£GëúÖA¡P>>>zË{zz …B0777ø³Œ1Bxÿý÷užsuu ¤·¼X, …àîî®óü{ï½×b[ºúîîî‚B¡Äb±Áó 6L>|¸ÁåÍÍÍ…B!¨T*áeL„Ž$ Ôj5~ýõWˆD"(•J½é“J¥HOOGHHüüü “ÉtÊܸqC›êèl2™ hq8ÙÖš3 ˆ"##QUU777€T*ÅØ±cµÃÄÄ£GFdd$,,,t†²ÊÜÜb±Øh6˜¥¥%D"‘Q­ss@LLLŒn½E",--;}½[|‹µ~ýz¤§§cäÈ‘˜0a $$³fÍÒ–111Axx8ÒÓÓ!“É´A"zÓ´8é*• ååå-¾YéÊêêêšš ooo£ÚÀ‚ àìÙ³?~¼Q­wBB<<<`iiÙ©ëaÆ}„a¬¬¬Œ.ͽ½±…ÆŽÛ5õØô‰ºXâèè;;;Ö>ñ„Șñ‹¨³’™™ ‰D‚uëÖ¡¾¾^o™æoY$ öíÛÇËg’Vyy9$‰öñÞ{ïA£Ñ ¾¾ëÖ­ƒD"Aff&€gcÞ~üñGH$Ü»wÀ³KE-]º‰ä¥wV®©©Áœ9s0~üø7Am×€B­VãéÓ§8~ü¸Þ2<ÀêÕ«¡V«‘˜˜ˆ´´´nÕ222péÒ%¦A;;;í‘:OOO˜˜˜àøñãxúô)Ôj5<»h^sùI“&6mÚ777¨Õê—~+ ¥R‰={öh—ש'éôÌåË—…ºº:”””`úô鬔V¬Y³ÁÁÁ¯ÒÖN///øûû#66 €ääd<|ø?ýô`×®]HIIAÿþý±|ùrÀæÍ›µ‡¾¾¾hll„‡‡¡V«qçÎL:¡¡¡(..†»»; 6mÚ„éÓ§cÕªUðóóÃÌ™3_ý5êëë1qâDL™2«V­Ò¾×‘#GàììüÒñuí)..|ðÞ}÷Ý7û$½yà\xxx·G\\T*‚ƒƒQQQ)S¦àúõë ‚ƒƒ¼¼¼°lÙ2ìÛ·Ož<\.Lj#ŠˆˆôèÑr¹‰/^Ä… ´tº{÷.RRR°bÅ H$ÈårTWWãàÁƒøë¯¿0{ölÈårÜ»wÑÑÑX¸p! —Ë‘žžŽsçÎáðáÃ:=]AAA§Õ•Z­FÿþýѧOŸÿ¼¬íÛ·c̘1())éü€>|‰VVV€ (**Ò9aêÝ»·öäÊÏϯտȾi|}}1sæL„††¢oß¾Úç/^ŒY³fA&“!,, X»v-”J%öïßäååÁÞÞžžžpqqÑY®F£AYYàæÍ› R©D~~>f̘عs'<==!‹QZZŠk×®áã?†§§'”J%F{{{£ººfff:hÐÆÆFçZ̰²²‚D"ÑY¡PàÁƒH$ˆ,Y²W¯^…D"ÑžçUUU¡¨¨HçË Ÿþ;vì€B¡ÐÙ1ü¤SýðÃðôôÔžT6ÿ/á‹/¾ÐÙÉÂÉÉ 666ðññÁÞ½{Q[[‹"##>|8Äb1¬­­±aÃøûûÃÆÆööö°µµÅ€àêê ™L†Ý»wÃÁÁ›7o†X,Fvv6¼¼¼`ff†+W®`ܸqðððÀ‚ àââGGGL›6­[n#Ó•+W®dSíC† Ñ:455ÁÞÞ ЖqvvF^^RSSQ]] www¸ººâúõëHOOGnn.Äb1V®\‰äädÜ¿!!!°µµ…\.Çùóç‘•• 8;;£¡¡®®®°´´DSS P(ðÇ //>>>ÚÛ!dffÂÉÉIû×äîˆ=ˆ‘KLLÄ¡C‡Úìš\Í‚ƒƒ1nܸÿe@ȨÔÔÔàÑ£G¯õoOCäää`èСݾ~ÿx©‰Ì›¾RIEND®B`‚snd-16.1/pix/uppergrf.png0000644000076400007640000002617511147553271013514 0ustar bilbil‰PNG  IHDR¨š´sBIT|dˆtEXtCREATORgnome-panel-screenshot—7w IDATxœíÝ{˜eçñßéKú–¤I„„pÃF4*™EEäN Dvf6‚.:èø¬+*ÏÎê3èãìî°Ã* Ã¬Š‘!$ ÊEȲ!’‚@€È š ¡\:!Ð[÷©ý£©îê:uy«N]Ïù~žíÔ©zë­:§ª~õÖ[UI–€‚h“¤G¬My×Mîš›ÿV>³|$ JÒ?ì¸?Ïú’4P«Cã¿ñÆGtÓM7éꫯ։'ž»ðÅoÜP_íšÔ÷†'RÎh»»å9Tk¸::ðÕW_Õüc-^¼¸®€ê,X–›ud]E<ùë‡eQ-Gycu(8LëÕW_U__Ÿ9ä}ôÑ¡3 +>ZFþïíÝoÆš|ÿ=²,k,½<‡±Kü­¯¼òŠž~úiõööjÖ¬YzüñǵqãFþùjmmõ.¨LÍåʃ?ªó:Y’tî¿“smšë(/ëhY1ó”5ò?vs–wæÙgG*êûï7*ïûƒïi7ž«<'G êp͇’´qãF­\¹R_úÒ—4yòdIÒ¼yótå•Wê½ï}¯æÌ™ã[ ¿24«:¶Úü¹ŸjÞ ¤2Ÿû޹V’ô³]¿Ñ-ÛJee’Õz‚¶‘'ZVü'‚Ž´P×]ž=MXygž}¶~qß}žeœuÎ9Áå9xöAµ=óÌ3Ú²e˸pj;ûì³õÀèÓŸþ´ZZZ¼†T6×ñõ5ÿO‡þÛãR›Ý›¿|I;^xN½ÄïGïÔViÕU“îŒ×;€äUã¶ Ê’,«&Å)odÿòî»÷sîy’F‚è}÷Þ3nû3IºïÞ{Ë“ÆÝÅ_ûáa‡¦O|âjkk«ùìãÿ¸¾ò•¯è¥—^ªéºsçNmܸQÕ^*Ps;gèÓ‡ž®ãºf©«e‚Þ®îÕ–½Û´|ë/õìÀË’¤N¼N’toÿS²†uú”ù’¤ŸïønÛºv\y—L?Eü!µUZõàÎ ªT+5ó¬UG˼{Çú_¯?˜Hý$éŠ .Õ\*I:ó·ß~|÷,}rú"ß=K-´ýÀn­ßý;-ßúKí­WÎýýO«½¥U‹z·VmL?zýa=xÒ~g<©aËÒǦÎ×¾êVmTÿgçsúüagiá¤c4XݯŸlL«¶?VÈõ  êkAµÞùol›_Þ½÷üܨœsÏ;¤¥Ó ¼sÏ;_ÒH µË·‡Ù㌶žÖ”7&°uÆŒžáT’ºººôÙÏ~V?þ¸vìØ¡… ªZ­ª¿¿_+V¬ÐÉ'ŸL *P"_›}‘fwLSÕ²´é•—ÔÞÚ®Ÿ¥iOïÑž–mêœwðè¸gt’ví}Köí×ÔîƒôÉ‹´~í:m~×HÀûèÔùú«C>*IÚÚ¿M§¶­I“&ÕÌӹؽþêþyM=çøØõ{aðU×}¸$iûÎzmëŸ$I[þÓ}:âú³ôžž9úö‘W¨­Ò¢Ý{ÞÖK[_Ó1G©‹§}HÇî;X_~ýDzÚÇ®}ì ÷è@uH¯¼ñª¶¯yA»þô餑ÏΘt’vï{[{÷ìUoÏd}úÐ鼞÷ª½£]ƒƒê8YË=]¿ùÕãzùè¡Â®wÅeçRgWh¼s Ýî3ê*/J¹VµZž$Ýó³»uÞ#ŸrSû³qót•çÚ5Èqǧ¹sçêG?ú‘6oÞ¬£>ZÛ·o×Ò¥K5eÊYOý"r™ò1sÂTIÒƒë×èo¾ýuµLž ÉÝ“4ÑêÔ›‡ «2µctÜþÝ»tÖU—hÚŒézð»+$I' ÍÐS­Óä÷ÏÑâi %I[^ëÓW_®–ÎvýìnÓìC7OkhXÿºw»lÐŽ]ýÚóú.µÿq«zf,7“úýõïnÖê“¿!Iºÿ‘‡ôíÞ¨Jw›Z¦vjÛ¯7éŠOþ;µUZ´}çó™Ë´{߀.¿`‰¾þ—_ÔüÃÕ»î²ôü±09°gP|n©¶íÚ¡–Ij9´{ô³­ýÛtÞÕ—kÆ!3F×ÁÐà>ó¹Ohú¤^=ð?ï$½gï!zö7é ã—=ïõ <êéƒ*>žÎþŸ‘ëPžíçwߥó_X3Ìs~a}PãÞqßÙÙ©eË–ihhH­­­ªT*ªT*u• {OìúƒN™zœÎZôQ½oþ½ôöëzêO/èÎg”vïÖðÀ¾ÑqõôãÚ3¼O;N˜0:lRÏD >¹]ÇN×ÜÎC$I¿~öIío·Ô±h¦žØùûš T®ê/ž»A¯Ý°N¶Ô6{’¬ª÷¾Ã¤~ÕîŽqÓ´>QíógH­µ¶·ë]=#ó_÷Ô¯õÖ=ê:ýH­nyQ_güwOŸ§ukî—FržùÍ£Úöf¿:>:W-­ª´=µä×Ï<©}•!íxOû¸a{÷hÛ)cÚ8QƒO½®Žy½jŸ8¾~y®wå÷.~¿£Ÿýrª[õ÷ñõÁè¤ÃŽUÿù­¦}jÁ¸ñ+í-jë©m¬UõÇÁ?é]géóOÖ„_´«ë ‰Z0ù¨šq­áª~ø¾/I ¤ßxZ·÷=<:(+æ ©´T4cútUŸ ŸP7Ì¿Jo¿G¯Ÿ¾CmV‹æNž)Iúý–ÍÚú¶úvÔNT{ƒ¸,«ª»ú~¥¯©æ~„îÿÛï«¥³]S:&ÖŒ[Öì®é’¤ÎßÖ[^VÏfÇ®_÷¬^m|CózfjñéçêøãÞ-«§UW?÷=IÒÿ~éAý÷“®Ô´©ëoüP[¼©£¦Ž\þÞð»Zûø:µ|ˆÇrVÆí#Ç江ôfYUÏeÍk½(ƒ‘ݲ,]xñ%‘¦¼kÕª¼SÂØ6?VžóÿMX–Zž³Žw­ºstø]«îýlñEKtת;G§_ÞÏÔWö ëµÊDÉÿ%Q¡‡9KJäç¯>¦c÷OÓ3g©³£S;w¿©ÇŸ}RÿíûßUˤ Ú³¿v"¯M¼*ýâÕ'Ô³uXKœ­‰]=ºç‘¥JE—±xܨÎ}Duïö½þ¦Ú¶OÕ„©ÝîRêg Wuà ?Õçfœ¥£›£w1ò¼ËŸQï'æë™›ôïïú¦þjÎǵàøuäA3õÚ¶?éGþ¯¾{û?Ëš2A•Ckª­Ž>ë h˜sYó^ïŠ/Î%þ‘iÞ¹„îî3óPy~ñ¥£ÿþéª5eÿtÕŠÑq.¼øýtÕ ßò$Ÿ>¨ƒCÃzsïãJ{énóîG ˜þëÆ;µóU}c@ÕÁýÒTéhQË´.MxÿLµ´·éÏø¢¶Ý8ò\϶yS$Ëòf Uuûà£ú§oý‹†^è—U¹êï~~“†þ8öÎfk¨Z3½54ì¹ï0©Ÿ5TÕ3Û6é²Ç¾®}¿úWUßÚo?¦O}ýêž9Eèì×_ÿêhè{Û4Ü¿WV¥«]­³&ªãØ^µvz/§]'Óu`2ÌÎm½(ÊøÊ(ìi*Î>ž®òœ¡2‰ò$é'+ïð­ïOVÞ¡‹–\æ_žCÝwñûÙ±g?wŠ%Óõg³5¼{ßÈ΢ª‘‡ÜµTÔÚÑ® “»U®ªëS'HoŽ´êYUËwXkk«ºÎÖã¦Iû†U‘¥JG›ÚO>TÚ?²o°÷^ÓÇ­Ÿ$uÑ«ÊÁ]²Þ>ðΓ -U÷©:\UEu9Mû™¨êÀi¨*U*ªT¤¶îµMîò]¦Ñz®ãa9­wÅf÷æ±diÕʉ4­%ë*£Û|兵ʎÏUžS]ÏA 2µ³gí%ÓÞÚ®ö©µwšyV]WW—ôÎ H’|‡IR[K‹Ú¦ÔÞEîÏoú8õ“FöyÝ]Rw×ø1ŸwtuJ]µÅ We…ÔÉt˜Ëk½(‡ŽŽ®ð‘|Œ´PŽßæ‹^žäÓõàÎ ²&Çž—$©·£~NqU*zêñ‡ë-b,½<çpIÖ#Ö&ýÇ;ÿ¾®õØ¿s@>³Ü»ÈKMÔÁ{ÿ çï\—[…ÐÈJÖy,à&).ñ {þ™Êà&©¤š‹³¾ì6¿V>ÓÏ“nF·¬]5­…A—÷ƒæ¶®“nåŒÊžOÐwbº®“\a¿‘¼Àæ•Ä1Èôxg*µKü&L¢¹8í@d,¢„ ¿eu~žW0 «cÞáÓ”ßwb3]×I­°ú”e½Ê',c%ÝOÕ$'™Hí9¨r`³^gÍ(¯€U´ß^Üúm9åvÕ6íyÅЂZž>¨„ÁpÎËüõGÖuòüNh¨€,ñØîΡcÏA-уú9g‡u.ñòRÄc;‡ŽÆÕÖ–VÞ&S’g"E<«1á×Y:«yg9]½Êúà”äñÌC3½Äïu7uÐ G^ã¤}y4ì¦&¿;ÖÜÃL–ÕkÚ¤ŸÃÔ*—ĺvÏ£Þ.^õš¿ßxqÖuV¿=.ñòbz 2É1‰ÞÅŸÆ›¤’zH’ãÄQÏrx}iIÏ7“»ÖãNï7NÖ/;Hj¼$Ö‡ßçi®#¤dAIäö˜) ŽÔ3Äáß‚óU§¦d‹~I“å(–FY²õq3éã¯ÿ«Nc^âo”€ÀrK£,Y(ûqÓ÷™žƒ €ÆáΡ¥|“G*™â ¸IŠ€ €ì?õ–[~I…ÐÜžƒ:víÞ¼¹š7onf•@sºêª/$ÿ˜) ¼I …âÛµTäÀCyø) …€ €Bi eÌÔ©s´sç–Ñßrór]sÍ´gïöÄ+EGÇP®ó#zzŽ’$ löçùíGeUÔœ0Íù’ÒÓsTàz,›}ûÌc'-¨ á-œ“w âéé9j4ô7“H-¨Ïî{Vêû÷™_ecòã$œ0Öâ™d˪û1VÎÿwÏÓ9,m&Ç~磧L^/·i•&R@=©ã¤Ñ‡ðKÒ-7/×5×|A{önœ.(œJ#­¨Û¶•±~ýÃãž… ÊɶÜ!'JðsF¯iœ-¢Q.ã{•XœË%Ĺ[B£@÷óQÃBeÔ@ëü<ëg±¦þ þ°ÖSÛ† ÏöS ºÄŠÏ/¹«3 º‡yñjÕô*Ï.Ó4øšþ=6_ï`çʧWÀŒ:­×¿½°W  +×+ä¦-õ€*I«WGïà÷pþåËWèÚk¿Vo•bóûñxYp Yùÿ6ëùíµÁ(Ê¥sgX4¯^îržØ"0Íù¢ð ‚qx•`ã–Ÿ¶ÔêÊ•wx¾î´(ÜgI4µÇ€F§Õ4P†µ &ÝoÔô²~Ð%ö°®ö8Ie÷å|¯yúµ úÕ!˾¨™\â/²¤Ï¥3g ª»Ï§Í/TšôAõëKêÇt½¦sãuYß¹ÌA—íëÄ$½þ?ˆ_öª‡{¾î:¹Ë jÏB&—øMú ®^½F×_}µY 4^aÓïÆ&çx~Óôò¿W™îù›Ü”%E¿ŒîÕ4êƒøƒB°_À4 —îàÂßÅ´¢½†Ô«>iÔ1(HÆy˔߿ã¨çÆ­$dúªS€8’|ªÝBjRfšá9nèËú&ì<º/P@Cóº¡*ïל–åž•¼êI@…â”I¿AÊ9Ÿ¢r_æ·ÿn–GXP@!¥ÑÊi‡Ý"‡S?ÍN%*(°´ZO˨Y©Ä]ü€ÓL­LŽ`:¢Ó…}Õ)@RžeŠbiúW€âi¶›¢ü4cë©Ä%~€BjÆ`j# F”·ï ]ÿ]4úòùË"8s? …T˜f¾,äЂ €B! uhü>Vd€ ” ¡ˆ†m(*“û ÇA(†Íl@ÉP:dq ä@ ÄãÜvØŽ€r! V³¾…(;* …ç — Ê‹ï(&»õÔîŽCk*PÔñÚq|Ê#Ë Z@#ã?P§,ƒ"Á0çÞV¸»(*„@ãèé9ŠmȈÁÝ’I«&¿¨Wœ@qPဠ”Û*.*¢81÷ÃÅ£ô›ã  hT Av˜ ºÔ7DúMG(jùm^'|Io“aÓ°Íá¨@‰Ð×Ð ¨@Šü.ϵ ˜\Ò‡Ö \Ôî3’ÙÉ   ó{öb¶ JP”HWH ¦I†WZweF@"Êëòž×<íàëlu¿{@°°§’ÚæÛ(Û&Œ€ dÈôÎ~Ó~¨¢«wÛIê$ ø# 9p¶zÈž3dú‰²}fù¨ª"” ¤€ äÌïò¡I¿Õ0\J’h£>€7*#wŸÑ ñêvФ5e—D?Q¯§mD œYòv94:*ÐÒ ·@3°Ã¥s{IsÛq÷cÍ¢;A#Êk]𤀠ä$éƒ_Üòxè8Ê.ÍßpX¹vÀ4¹ôŸÖ“ü^ÒhÛuÑBaQêS”z$€ DPÖ~ØÁÌ=ÐÌ’ìûí~ü›É4q˜tãÉZÚó4}XÒõHûqaì‡GP&dúf+÷³ "Éêµ£i_pãõLÖ¸ÛŸÉÉi„…Ñ"ô8⼂מ®ÑP‘(gðAñ8ÏüýZu‚¾Ã¸$§QÄÄ/„Æ ¶î€ân­s÷‘‚ó¸Jâ¶ë­‡s¹ÃN²ÓîKÌ6—*×HoJi„ep2¹ÌèþÏý–ª"…ÔFû~L…äƒÖK‘×YÔ…’x[ZâÔ«žåñ µqêânm­çwæÕ2ìÞ·˜Ö)ïÙ¹l&uI»ÅÞºMëä|âD”ð_ä}D@ED~;­° ×tC«§^õ^Æ*RðJC’;U÷wïÞAºÇñ›6éºäYFÚœuô:ÈÇí²áµ-×S?¯³°ñ½ö%^¿%¿ÖˆüZL½Æs [7ΓΠïÆ9ÓiœÿïWf˜°}ˆ_«qX óûܯ D” —Dÿá(¡Òo9↓ayhË»0ãÞa$Q–É0›ó3{¸s#ðÚ ¼>›¯sü°z{­÷ŽÆ]/¿etNïUï¢l°yð:HµëÎï»ñ*'è{÷ú>ƒ†{•çU°ß”ßß&‚~·Qæö7Y»~óò: ‡­_¿ùø}~Ãõó›ÜuЈ¢.§éø&ßWy~ß›óo÷w–üöaß·iÐõ×ë³°}‹Éï.ê8aû¸aܤ>^ûh÷pÓLj yí°%ÿŽé1¬<¿—W@ñÏ4ĆéºÇ÷›§×ÎÆ«ÞÎù-+Æ­¿Ðêôõ×o‡ö›1ýÜïÀëU7¯å û݆ýmú÷š·— D¿ ´Î‚¾Ókæ5¯ñÃ>G}â„Ú `éWfP³™ü„m/&7h;ñ´pgzBë®·WÝLëã7_¿ïÒ9­ßgio‹Ô’ð Q^{|[ÐÄoXÐüÝã.GÐð°R”‹×°¤w†0廊ò *Ï=<î$Nyÿ¨òž?hÔ™¾¨! ìxÌTƒpÞDâ µ¦×=]Ø|ògÙ‚Ê@þ¢~Q~ÓAÂÊñÚžâÌ×=m¿ß¬…­G Hù·™Ô1/j.0ÍI£µ$¢ÞèwóTÐôö¸¦wê™ÞÅgr·¶IÝÂæt¸É:ñšñy­w÷p©ö.R{˜s\ûï¨óóûí9çëþwœ›ÔÇo[ Z^ëÁôwo²>¼Êô»aÒ]owÃêdò]¢\¢ìëMo&4GÔáögNA¿Ñz·3¿z…íKLד»®~Ç9“zy•ãþܯl¯“ë´·gjID½ 2è€6½×ÙëßaTÉÿyˆQêepƒéºð;`\ã$œŸ‡ííáö4~óðûžÝÓú…U“ºzÕÉ«~AeyMç·mº‡¹ëc²Ípù•´~¼¹{Ùãø-»ß4îûg¿r¬°ý¸{{<“aqëá.3Ê÷î¬¼ÊµÇ ;.„…Zçð =¿cŒéò„1©oÐ|üêãþ,‹í€Ú@ü®QHA頲㸣ÖÇ«Ópa:“ƒx³1ÙÑ:Eù>¼Ö½óï –º °ß@ØÙ´œ¨‚lPݼ~Au29©0Y~¿a&Ø ¯“¿ÓlÛ`šË´O39™ŒS?¿ý©s^QëµNîíÅëDËkâw’åä·2ݘž¬yÕ+êzðZÓ¼åöG@EdIìH²®Kœñ³ »[ÂL®VØá+N‹]Z]lâ*òw“„4÷Q[—õŠ©hÄ¥ì¼.µyôo (¼.‹&-N¹EiÉj´n Aý±m9eYêE@@Ø4l‡×H;x ^¦ÛCÐv% šÞu§Ž¤žKôI®«(ýƒ‰k¶¦ÓWÚ;8“»ëý.ýó=¢,Òü­zuqn¢ž@öèÍt_•æúã»IÈYذžr˜ó:Yój¹tcrƒaRâ<Žé`ý¦‹€ €×AÇ4¸DèêyÈyP™„ T %a—ƒ™RïA2êôTQvõö ÚÃÊΣ?"Û,ˆ(ì`äõö¯¿£k²Þ þIDAT–ë7¯ Ä€lp÷5,^u d,NëhØ+Ýÿ¦õ(‡´_O ”-¨@Æ8¸ùJâr<ýMtÑ‚ dÀ> Æi)á&( ~q·A¯2ârnÏ„[ -¨@ÁøµÌ˜ÞÑÏ—÷É'ž@0*  €hM§%ˆÑù=ÎÍtÚ¤±þ¸Äd€ƒ¤C`-¯ì€p´  q£¼‹; ôo^Û&€b# %So7 Yxm+yo#yÏ( *Cš7Xí€ ”EÚ7>±-Ù! W€ò! %‘÷cq€FÅÝô@ñp>`‚)?¶C ]Ô‰ûpv1 Ø¸2—ø ‡Ëö@¹Pp0ŠQ 1P:d} $ùc;ÒGT &û Ek É"  -œ@ùq‰¨C’E@@¡PM« @ñPp€ 9T …B@@¡PP(T …B@@¡PP(TJ[Ú3X²ä²´g€’z@•¤µk gõê5ºþúëGÿ½|ùŠ4«€‚J= ®\y‡¦OŸ:Þ‚óGÿ^¿þa-ZtJšÕ@AeÒ‚zÚi§¶¢®^½f\@=õÔgQ-P&5¬ÕNm}}›<Ç]¾|…®½ök‰Õ Å’Ù]ü§vºçðÕ«×Ô [¿þaßrÒ¼ôßÓsT"eØÿ ºÌêÊ•wx÷j=•¤Ù³®–æSI…ÓÍ£ÿR¢Ëô9¨îVT¯ÖS›W+jZ­§v°Lº B*@t™ôAµ¹û¢úµžÚìVÔo}ëï$¥P“§HN¦U»£ß}ç¾»5Í~§y†Ó(­«´Ä€"È";ePW®¼C6<N“êŠÐjjR‚)h6¹¼ê4ìõ§I=µ!´^Y.Cº;P‡bÔ!ïùSêP¤ùSêP´:ä=ÿ,¤PW¬ø~äi®»îË’$_”B¦wñ7¿gœzÝ±ß g8I˼jÑx…J[Ôpé©„S€èš> Æ ¡I–W$e®{’аò®CÞó/JŠ ë!ï:ä=ÿ¢Ô¡а¨CþóÏ—øP(T …B@E¡4C¿”¿G ¿G4* %õ»ø»»Ž4þààŽ”j‚¬…=6©Grñh/eåõÛìÑì2yÌ”iè¼õÖÛ´lÙ¾Ÿ÷öÎý»¿ÿå:k…4íˆíÏ;˸/5HªH›ß¾)ì%/ìÑŒJs‰¿·w®úû_ýÏVQ,&-§îϽÞÄg>qÊ€¼˜„HöhF¥ ¨(ÎÐb "„”b` ø+m@å1±³Ší4öI' €·¦Õ)4wøq_BæuÉÙF°M}C`…¨Î¾¦öß´ž€?¯ éþ,h÷ÿÛR²Rø€j‡Qû&)@v¸ ¥íƒŠòòjÁ j™éé9*°ÅÇ´Ñ l÷â3 ûì…oAE¹xímΣ{çw§™T9@#K*˜pêÔ½"h<öhFT$*ÊÐtܰñØéµœáÄë¦'¿çdú•áõ9¢Kj¿g:ßÊ*“€zë­·Õ]ýO ¿›¤Â†¹¯v@ÖR¨ƒƒ;__ 8q“ …€ €B!  Pâ.þ}ûb1 ZPP0TJÃ^ÿæ7¿“wšÚu×}9Öt P%iÑ¢SBÇ9õÔK’Ö¯8íê¤Â®?€ò(ëþ¢ä¦‘qÄšOCÔ §žúaõõmR_ß&-_¾Â(ÌU_ߦ¼«ÀPÙ÷7Ð×·IsæÌÖìÙG§vÂÝt}PO=õÚ3g6¡ vPMãjnÓT‚)@òÒª P ¦éK2¨6t@µû™ }}›´nÝ£u•ÑÐuýú‡µ|ùм«Ð4’¸´¡ª4ò¨©-[úª)Z¾|…¶léKäI%©?fêÖ[o‹4þ²eW¤R;¨®[÷¨–.½4•y4»Å4ÉGèeòÔÓ.½.tœ…s*Ú»÷- îHµ.U€ú¥Lm…xPÿÂ9•Ìçé ªeG÷•4ƒ©-÷€j‡Ó'¶X’ÞN´l“Ç4«B¯½ökyW4‰,rGfu|?,Hoï\õ÷¿l<ÜöÛßþN—_¾4r=Œ+¾kºLª3ˆ.œSÑ[¬qÜ¡5I Ìü|É’Ë$I+WÞ‘Êüåg+šÇC˜0ÍOõl;™Tw NÃZMM-Yr™Ö®}Hk×>¤Õ«×„Y@s[»ö¡¼«:އˆbíÚ‡4}ú4vÚ驜ØdöÔ´ZI£X²ä2MŸ>­)v4i³ƒjÒW2}P^!•` ž¤ƒjæo’r†Ô8—÷{{çOC0(Ÿ\^u%˜Ú¡Ôî{êþ7Šá«_ýj"ådr“ÔüCjŸoºwï[2}î©;Œš†S»Óî† ÏéŒ3>b4 ò•z@]¶ìŠÔ__fÁ‚ùÚ¶m;A öS ’zD.—øóbÕÕ«×ä]€Ò[½z¶mÛžø#ÊrÕiœ-ª„¡a/éS·†¨a:h¦·ƒâ»þúëó®P(io Pã¾ûùjª>¨(¾†mA@2^éÞe4ÞƒS™_¤€ºsç–qÿ¾òª¥Ú³w{"@q­\øùš×èŸÿÇDæÅ%~ …z‰ÿ–›—gQÔ™_<×h<ÓÜxåUK? ¨×\ó£ 1½¨MFã™æÆ°{˜B*7A4¹n³Ñ’ÊôA@¡PP(‘žƒ:uêœ´ê ¸Ÿc `jÍk2›o’@ #§$ö~\â@¡PP(u_â¯T*£[–UoqHP¥Rá;”Nw÷Á‘ÆÜ‘RM²ÓŒË¤®€ê@EDE¨¨i»õÖÛ´lÙ)×&Y/soïÜÑ¿ûû_®»¼$žÄï-Ë×¢ €bêï¹pÁÔ–Ù]üvpÛºé|Ý­·^»çgRŽýo¿rÜÃëY6Óú¸Ç [.Z‘@Y•â1S~—íáÒ/œ™–ã8ÝÓzÍ/j÷“úø6_Z²á¼”ms¶ööέiIt³ÿí.Ëkº yeÁ´®¦e¹E]wqdPÓhÑK³•0ÏH¯®qÊ ¤š_XŠ¢ÂÂX’óªWRÁ1¯å)E ª_ØÊ2D¦°ó^.šQœ€7”åÑϳ¨}KM•" JÞ¡­îØoÔå ¼.uÛÃÎkÝe!v@µ[ÿL3UïDõÜ\•wØó[ö4ëÆå}Få²{ÙuYH[]o’²Cªý_ZaË=Ÿ ùÕ)J9QêVÏ´IÔÇ«œ¼C9E'L%Àòh…Lkžaå&5ߺ/ñ›¡zS”éƒÆ5)'l¿Ï£Or^~a€ffr‰ß=Žß4IÌ++QŸ8`ÿ´^¼†%µîÜJÓ4[o½-±²LbØ8~Ÿ»‡×F“\f)þ2…“ä2û! €BÜ‘éëK‹Ð5ëeNJZ뎀 šZRµoFi­;*hzH³^–Ü[PwîÜ’x§º3$€ €B!  P¨(* …€ €B©yÌÔ‚ï\’È;T€0 ¾sIͰš€ºìòOI—*“ n\â@¡´IÒ57ÿmÎÕFT$YyW°ý!VLT ª¨IEND®B`‚snd-16.1/pix/hotcolor.png0000644000076400007640000007727111147553267013523 0ustar bilbil‰PNG  IHDRúûÌÒÏ pHYs:ÊduhtIMEÖ 3\më IDATxÚì½y”$çuÝù‹ˆÌ¬¬}éê Þ4±±‘„Hp‘HK²8’µF–,[G¶dÙ>%ÛJ%ÿ¡ÍG:²- )Ê¢VsF‹EAâ‚A‚ˆµÑz©®î®ª®½reþÜ/22««ÝèF±âôjÉŠŒŒxßûÞ»ï¾û¼§kOs±ãìÄÙáÁárW™õcý¸öާOìÚ¾k%/+_«}­‘4–yÝ©—Oݱÿމxbýή×¢¹¿t"ÞŸ Ï-óšfµù¥¿øRh$åÍ=LÂ8‰—Íú±~\­#&Ž’hyûlÄF³Qø¦ ÿÚ©‚ù6óÒ…Fscsü©ñõ;»~\ƒGP æŽÏµ·ÏòPy䯑ôëoÚw±Q|ç;ß9Ïçÿ`flftóèíÛo_¿³ëÇÕ:Ç={{Â$Ìÿjúèôö}Ûû÷ôç5{vvóÐæœh5w`.žkMŒ ŽœõήßôõãjÕ³Õáõ¤ÖÆ>ÇÇF÷ž ÛØçÙ©³ƒåAН|ë¯ßÇËrÜ÷áûVþâÏüúg?|x%¯¬/Ö?÷_>·~{WxÜÚuëÞâÞô߆© ù´ ÖߨõÆ¥x)ýzþÂüäÀäú}tÇá/ŽÃxÿÛ÷O½rtòØdjô»ïÚ}ówÞì^?þüøüÄüõ·\ßÕ×õÂý/lÚ·)l„ÝýÝIœØÓ.N-{ôØö[·×—ê…R¡2SÙyÇΗŸxù‰ Q­ßöL,î•÷–ö^˜ºp¾ï|âenãB¼p¬y,ýúè¡£û¾mßÅÍ}zaúù ϧ_ŸyöÌï½qý»»qêë§6ìÜpäKG>ûŸ}ÿ/½ÿËÿãËa#ÜÿŽý¥ž0¸u°w¤×þÉ_ýû¿zïÿõÞGÿèÑb¹¸ûîÝÏ}æ¹{þÙ=•™JË™ŸþäÓÀ‘/™:15°eÀü©SJct×èÔ‰©õ;oïÌô™ÇìÀ½‚b°ª¿mÌŒ×Ç•FúoÓMë÷×£{F¯¿åú¥é¥-7lyÃ{Þ°ûîÝóó•ÙÊ®;võoêîú‘»v¼y‡ý“oÞqûn¨ÎUçÏÏïºcWPâ0¶/Xš^¼ã@÷`÷À–à­?þÖÞ‘Þùsóýû[ζ~¤1U›Ý=êVŠ·ñîq¼±ãúmÍ çŽ=v,I’Ù³³©_ ŠÁÖ7lýä/~òôÓ§?ùç²ÿíûßù/ßéþĽlïÛö~ò?Ù=Ð=qtâ+ú g¸gabáÓ¿öéŸý›Ÿ=ùõ“ãÏ]7”¾Þüû6ž~úôá/îߨ¿~çí66nhc¢³çg¾pô•8ü|ŒÑ{ºöô£ÕGIãì£go{Çmí‘™gÆîÚ×x÷:î~‘ãôS§Gvô÷®üO=xè໮ߺ‹#3W‡ßÒ™ytìîwÜ}&<Ó™yñìm×ßv®ÿ\£Òxä)œŸz49{¶÷l£Ò8qêÄz™iýø:ÖÍ}ýX7÷õcýø4÷ÿð~éøPúïäÉÓÀ_ÿõ}ŸýìƒéoOû™Ÿùwûدüý¾üå¯üÈüdz¿ù›¿ûfJ±´ô›¿ù;ÀsϽø_ÿëGÜÏ=>77¿ü9é—~µå‹ÿüŸóôé±K¾)O>ùtz…þ𯎟mûûíÇ?þç=öĺ1]Æ#ÿLíñ—ùÉïøŽï­Tª«=maù_GQô›¿ùŸÝ·Õjµ¿¿oÏž]é·;v\ÿÿã¿ûä'ÿ>ývjêÂSO=8°oçÎímOØh4ÿñ?þáïþî÷ºŸ<ñÄ“ssóÛ·o[Zªssswß}Gú«—_>ù{¿÷7Ýtð¦›Þà~ØfÉúÞ‚ïûnÞ}÷íé·Ç޽|üø àÎ;ßÜÕUšššÞ¾}[šÄ8°¯í ?ñ‰¿J?õ|áÙg_X\\ò<ïĉS[¶lºå–›ž~ú™_ýÕßúçÿü'¶oßvðàÙÙ¹mÛ¶¦ç&'§ž~úYààÁýÛ·_øðÑ©©é¥¥¥[n¹qË–Í'Nœ:räðæ7¿iXæXZZ²_=züå—OwÝuûààÀüÀÿöì³/$I’ÌììüáÃGw½ëí…BáÒ½{µZKýÜôô $T«Õ?þãO´}ñïÿþÅqÇñïÿþÇ—9çüÁŸ|àúüç¾ô¥Ç^|ñ¥8Žï»ï3éoã8ùèG_ùó$I’$‰ã$ý`Ž}ûö=úòÉ“§µÆ’/|á‘—^: T*Õ?ýÓÿOWõGçοï¾OOLLFQüû¿ÿG+¼õ¿õ[¿ûàƒ_Œãø¡‡9|øX'IBœþ€3gÎþÝß}6ýú£}å&|ô£üÔOý›sçÎ§ßÆqü±ýqú[÷y×¶ÇÃ95¼_<¼°°ø?ÿç_º‡ØòÊ^xéßÿûÿÔé·«óîÝÝåßø_qßöôt¿ç=ï|òÉotT¿pa:¿×·?ù“?æ¼ûùó¸ûî;î¹çîÿò_þðö·¿õoÿöSéo÷ìÙuÓMo¸çž»<°Ì ßò–;?ó™‚ xÏ{îvìØþ¦7½ÂI ÃðsŸ{paa!Ý|~àÞ|ä#øoþÍO¯üÖ÷õõþ‹ñO™™¹ùùù;î¸m÷îï{ß{Òß ¾ýíoýÜçJ¿MõÀ_H½Ñ?úGß“~ëyÞÐÐ`úÊýÑZ·éeŽ{ï½'5¼Ÿû¹_h6›÷ßÿPÓ¦n·åøÁüÞôžÿÜÏý«2÷Uoxû6Vu|êS˱ºÏœŸššvFÜrìÙ³+ÝéR£l9ÞûÞ÷üâ/þ¼¢£Íf3Šâüâj6ÖÊÃ?rï½ßÖòóÇûêÁƒû‡‡‡V~ª›n:øüëôÁÜvÛ×Íz…Çw~çw|ðƒÿnãùþïÿJÎüô‡~útx:"Z81Ï®;{zº[‚™ƒ÷»o/\˜þ•_ùõz½¾°°xãOûßùffæâ8Þ¿ï¶m×ýú¯ÿöý÷?X.wíÜٞʆÑ_üÅÿúÜçºÿþ+•Ê÷}ß÷üõ_ß÷ñ7ozÓ-[·nÞ·oϯþêo-..>ùäÓoûÛ€[o½åÿðÏ:òþ÷—çy>ÆÎÛßô¦›7nyä±øÂóϺþúë¶oßV©T>ò‘?¼ÿþØ·k׎‰‰ÉŸú©2;;÷Ýßý¾¾¾öä–÷¼çÞŸÿù_¼ÿþþáô…/|éºë¶|ô£߸qÃ?øßîyÞ=÷¼åƒüðÐÐàm·½ñäÉS¿û»›ššöñW÷ßÿà‡?üÁR©hÏsáÂôtiqº85£SOú&Elü¡±Ÿ¿÷_®çOùãç~î.y×Z?®ôñØcOŒŸëäÝ>z´ïì‘îc¯PÄ–9ÑääÔ¯ýÚoÛŸüÄOü7ßüªº=~û·olì›Ìµ7¾ñæÿñÿýUæ4÷Ý÷iû“_ûµApÉ'\XXøð‡Íþämo»{ݪ^Ëãïþî³_øÂ—LÆØóË¿üÁN/¾å–›–Oíì±îÝ×µ|´x÷õªêúñ-td‚™'N8qjý¦¬kæ¸paš›‹m̽T,îܹ}ù‚Îú±~¼¾Ž;®?Ô=F³w÷^M†·~¬׿áñMüz=v_?¾Uc÷o6¥ÞFc騱ì¢æê“ç÷ô¬PÖ«y$IT©L¯ÔܧƒÅF±Òñ¦ ‹‰–¢BoTŠ¢8gÙ­èû¾ï{¥RÏú_?®âǬØÜ†Çži>Ç0Ô‚G¢}Å]ÿøŸ‹Eß÷7lØ099 lÛ¶­¿¿§··gÛ¶ããc¥Ré}ï{Ï:r¿~¼Î‚™¶Çèè†ÞÞž;w93¶uëfÏón¾ùæjua÷îÝ££#FeÛ¶íCCCë÷tý¸fÕ¥ª]]]AàU«U½ Äq400ÇëâëÇZñîÀæÍ[æþþþF£”ËÝ¥R1ŠÂ‘‘¡Je¥Ól¢(zî¹çZ– $àé_l¾Mó÷ÅJóf9} BˆÀƒ$A²ìŸ“½˜+T•ðÌ¥¦ow~™»Kô)Vry.ÕZ“µ•Í›7oÙ²åR̽6U{öt3 KÅb’$ »€ÞÞ^w£FF†ÓúëððÈW¾òJ›f±ØuûíoZÉ•ÍÏÏßzë­ÖÖËÐ1Ô!.(@bè‚jz`M³ÏÌëðü<(A7Á‡n€RùÝ~hÂÌA¬3#Jí©øP‚„úo¬w\¹ÝXSnYE(@ÊàCªºIöc– 1Äàà A¦aI×ÖÖè}]@b}„xõkr%Ë)É9 ÷C/÷ñ“Ë·?ô¡ýʯüÊ¥˜û»¶¼ý-ƒ7õ«O½õ­o Ã:ðøãOnذ¡Zý¦RóððP£Ñh4wÝõ–ô'år÷%û¶Ô’RóJ¿N£nôìSãp^Ù:ï(w—9†zº5(Ãl^˜… è‡~X„E½i¢3”dˆ@¨·FßF—ô„òãüz CA–íìÒƒŠúón(A>Ô´6êÚµò‹Ê¾Wd–´·Ê¬òö-<³·¸ß&Ù¾{Î*‚™J¥zôèQû“Ý»÷%šxöõ¯?ÿßù—p àAU×”>˜ô©T Ô BcüеûÀ,¡ÌÂÐ y¸tÇp¤(ÛJͺ(slê_¢Ÿ¼úð&’Y§okiùNžèe t‹Vb1‰–o¬íJÖ©ÇWÆ©_)sß³gï-·|³}®V«wuue>[òªnŠ4eèiœ]×J@”s«Öô½vanjI=P„¯Lé¹eØKpšzÇXÖД£-C ôµ{Óp•Ÿ1éާ·lÖ^Sö‘˜U‘ÆëÝ0 X„ ¡"h˜¿Z~Kyìê¾û%š{…/¿|Ì};99µgϾ˂²'ò£6›t^߇&4dˆ~»Í:΋κ°$õÖ5X€^蕽¦[‡]! ³áĺM~Öd“Î1ÃÊ£[dÁiÒiSϤ¡-3]ðéõÏ@JÐerV:.»mò­x®…‹ðŒibs`ŒÀ‚$^‡¤'Én ¾VH P‚~肘‡ôÁ‚ò¼Po@I‹-Г^Œ‹gVø&~™…ç–™gV”ƒ§ÒOÂ4ôê"k0Ég’Îïeïd²nîW ÿŒMxzê‘Lâ\àž´ƒÜŸ» ÈÓƒ0 ³pAË Òîál¢]Ù%T ªèÅËÆî¯ÆhÒÐ(2èMÔnÇog°$Щ PÏå3m—d'ëÞý*n«m“²É»Î’p²  Ú²Ó˜¸ º`@Vµ¶Â¢±ûÔÈŠžÓ5Öe™£»Â0‹½úÒšgÅ*Q;¤Õ™{†„Ï.À’ [”ù, %Ù•|…¶ëdÜ·¨¹§zÝ@ÎÂNlã“eJ*ž9¡Ã›ÝÉcX‚³@ôË;¶â‘ ‚¾&{ZL1(¹LöÖ˜×.OpO«W–î~eáôq;œ»í¦—\Ž%zÑÏr Úú5»{&_ô³Ü†Ø€3m-,ÉÚ‡§zJIåbâØ£2¬%M¹¤7Åý¹o<ºgB¯ðò9ÈD¹Ý è̤¡×‚âøÄ„7p[¨ö;K—×yyfG¢CIÄË~Øä[ÄÜ=ƒNxY_îvö–¼í¢7:cÍ^Qƒq˜‡„~•izuþZÖÎbJyÃlˆuy£‚‚ù¤qö¹Ø©"„´º –F“‹ÅÑŽa:=‘‹¢“ÞµVfº¢yª'Û ¨N:¢-úîVŽ/H.5¤[ 0Cp@åÕq-0gß¡‰gŠJÙMÁó¾þ’Wm(~‡´Ûeî´ä Zõ³\£Nè¾Í ’ÕsV›€µ­~äÝ9WŒ¿úæžd“o²ÌHFg#Úe¶lŒYd—ýPÒ­ï…ôANÂT¹Ø0É7Ž ® ˆTÓÌî‰Bÿ‚ÈÉagÀøÝäÊ4È%¹ Ð7ñU¸òkª¶ÅˆZ²¶õ¦o•ØÝñQ[BÏ8K/Ë!Kr;flZ’,ç,ÎV%]eqŠÐ€yˆaV;Ld°öÈ$Ð._ŒÇ{æ-¢+lU^¶ôæ+E‰WÃT»ríªÞÅðPkññU2¶ÂU´òìÅÞ&ß”]<Ãnf©íùÚ3ÐuºŠf¡©Þ¥^pÎÀ4aRym1ËËãB¾éóðÌ·q»k¸ñLb:Í=CŸ\ùÛ%ºf/»ƒÇ\jÜZH^CÄý*›{’C|7'¹.?Ç–YæQù¦Ü˜~[WSÊpìÖúY¶ˆ‚™f. É·JyÆÇ¸WßöÑévÅbËÙ/²ɲ˜ïeæ;…(-wÆïì^›æ*{w›ö‘km´•—hÅt¢Ä¤›^6ÍMOšÂ¦åÕºò¼FÖS&¹L€l™3Î5û9èfUXõÊï˜Eiýv×Ü)5ôĦl^nR¤×.°i+¦’g%y—»|qíÆîq»•mï” -‚,rbïKK=Ïîø‰H¤ÞÉ"à h¹ïó¦Es ¡AE,&x )éøvŠŒ}Å]enÊ5ZÊQ ÈUéƒËBx¹3Û}¸%woË×O:´{NµÖRUrOÅÏFónÿ M”ìwØ+l‹o^ëtLà´JÚ”…ÙqgÊ)§Ü-€š^S0dëM«5 û‘Q~’§8¦g—nNAÈL‹ï[¿–ÚEz7š«O³•µì~´Ê3Y¾gž]lþ*îÿ$kÌܽ\˜ÞehÜŽ²K…¦`:!Â\¹Î"'–Û˜º@ÇbïQà¾d0.-ˆ™ž¡ºõ¾õ¬S]B -)`|±‹YWÓ9ÞÐuÆí*Ê®ã¤$>s(M/Ûoå g‘:órWâÚƒÜi[¢©bŽÅšGeE8Ð ý¬4H|òéÂ5â×mlSL nK½Q¯ºïB¨BMgQçP­®½?0]“S,ä¼Kbv†Dvœ&µ5ˆ _-¡‰¶Ž¦Ñ‡ÉÛAÛh¤mÅÀ±jú°AV3Ð7¶^Psê$«. 2Z‚®ìò¾´‡e5­0” ÏXUA¥CÑ–TÒôbû4²Ùv’e¿®dÆ>’‚>|z¤Rƒ&aº!FÞe ‰Ä솞 "ò,)Iu´ÛH”ULÌàö‡‚¤¼R&œި–#XþÂ2]…ùÄ·ig•²!—·8²@zsÒõP‚^èÃGYÛѺT,k\2cIÚ¾y£BN¤$4«ËÝO_tån-ß0ð"Ѷ¯(SòZ!c4ƒŠÊÆÒçݧ¾Ò.Àbª÷³ú%ã3¸ËpSáÈ~(+ð H—îÅeéTÆ ~ÜV[”–å›ãKMX­²i”Q¸=$ʦæ"½D²bQ™¬™M|[¢êÐEõU^ªŸÍ‚lw‹[ ä8BVÑ@Ã}ÙÕˆáh MÅ…—» u­TUÝSq½Òuða£X»sróý&ÞhŠêˆAr"£ÁÔÌæU¾Â÷¢ntÓÄ÷¾…úeV%Ùå”Y}=’ÚØ ^h¨{A ë)+cñ³ƒ(´|™u"pCØ,f¹±¹'èF5Xû«Ä"ó°I`8¡¾¼C`ÖXÑ4^b?ÝÙÇff·Í5Ì´MUšžk]|Ý’îB?lV‹Æ˜5-¤‘Á"&v/f™ºÝZQ›¡Àƒ!¨š´5„yYC—mJŠ£å¬uñã1¼Lªš´“ÿõ ýxQÆ]0ÝŒ®Ó¼[Ä71^UI-„9Ž]b"iÏP$¼U"Ü-8I¬ÔÓ7„èÎwäK®0VZåTƒB]RCµ3?§í¼Ö‚™à¹(c*É{¥;û0lƒ^¨Â„‰˜7"‘lÅÍ,\ÐÔ[øæ™%0¬þ Kñ užÌ «©)mEi@’…,³à¢¹Š«|5M ëÒ¸È|(+; À7…ŒÑÝ °`âé8—3 FÛD~tUqW ÃÑv{9?íÒÓPVžfös22…ÙNÅð•©H­€’·Æ²%ÉHVîÚAØ ã"œ† ÎQ›iœå¦"ˆdôeÅÜMYXQô0G[/gÁþn­‹‹‡FŽ=΢ «ªAº¨ (®¦ +dCŽHŽÜ‡!{96‘}[ݼ(k¸ñêÕ ¼EÂùc²rø®œ·¤çR4幆i’ ¸83Î]ðÚLUe9è‰:*â(@UD®!嬋P7€@dè5ãE¶)ÇŸ~à²$E+0£ígÿ›âB=Âg|פëǵV5³dý•'~¶µfnE’šàê]Z‡©xÍGŽrömã{Y)Éåe|$Y™“4îšÌÛ=¢,Þâ™{g!W®|¯Ì5¡DàBˆ‚‚\D{êÐÃÊ }e ¨¨c#4›`,³v1wÙ¸gú¦mÎ}Úpë2 º6ÖDõÔª"Ôz÷tÒ“ñ%Ͱ€c¨&Fµ=Ì6ݹß6aº`X*b5­ùÐ8û¶’±IâÆ¥Álja#õtl­­h’Wù$Ùe—¹B ᫟ª:W*jwR†- 8'- `II› ŠÊ‘ZR C.°b¦Õùá°‹¢‰ˆ"š ÅñÃqhL3+U—¬€÷’´{¢v’ ¢™%cPó¥Þh OQr½]àeé þ%Y¹—Ó½±…pWàÃôÆFÖŠlYÃf~¶nu…zÁ®¹TÕÁÌ 3V € BQ¦aQs”z$Œ¸¨àÇÚPCqaôÊJ‚i$=Â4ÓñL ö¨„2»AùøÄ .Oˆ²;YåRLžj]M|o.mt%°šDÜx…fË‹M"Ô=ÚÜꯎӖä‹YÝ®+ßxô8[ Ûù Ö¤¹{¹ÛWÈŠF²¿ °eØ"Ó 8c´“Z*š¾hÎ\Jbü¦C/€!ؤð`NE(3*èÙô«(S2|²‚Q>jf÷è•¶Á*1Ñ‹%-Û“BŸ)™Â7" =I®~)ë&-œâjmy>Ö c÷|ÕÉÖ¿ü¬YG¦æÊF£ˆy惿š@ëõÌ$YfŸûmÊ Ù{…Ê/ÉÚz”Û‘%âÙj%Ç$$–†%K&ÙòŒB¥·H»ŸõØbc Ž©­L‰.iø:æc”Ç·¼K)å"®á¶çÍrÛÍ÷ t÷œCüê(ï-Üú(›[Ûa'±¹€8 £y LÚqß×”¹'¹JSà …óeÓé8Å¢ð™9yÙXInLM(ø%¥$,B† m‚^uôõÁ8¯"®g°ù¢X²‘!´´2µØåªR[7fdC”-]aX m/i¶µLçBˆ£ŒEzsL¡KFµ½bã›êf…—íîõ²Œ–eß)ÉY æÞ"`çBbvðô^ÌÁ¸²4÷´ê&Åñ²¶î2çƒ â–ÌA*ЃÂmúÌbëRÉ©HwgâC£·Z4øÉ2ÍDžbË ƒ0Ë ‹²é`ê¼{¡ uSr E¡ Œdd’õš‘i±]•rÁò™k’³éØ0b3TÐÏ‰ÚÆ¹LÚr!½5Ɉl+E⼑¯>^èV¨Ú«™J±©­ÄYál×÷°Ð/jÀ& žÔìbÏLéhËöÏÄÚB¡“žxçv°pÛ!˜,Þʧ&$ð³“pÂìV“è]0dü½+A$í:V‘4Gì IDAT½,½¬vImr^gK ±'0˜i’ãz٨ݢøñk2üê#3m%­mó^¬§Û„ ¡ Î墆 WŒ´^áœÊªÍÂ<ŒBA™qÃxG_´°ªÈ3‘hO‘©¹†9D²Sè¹Ì¼Å8ëãœ2fdÖ†'ðqJˆ;—¬@ÆÇû">xfOx5ˆ;¹ÜÀÎÊ³å ÆƒøÙ!¯žÙÐ\j¯1ïîµkÝ÷¹cpÜfEL¯Ê7Ó®;¤iÚa<ÃǨiþhYó ,Í}Q0NY_ÙÈî•äY èLôE‹lgv䋎8µ¬ã–¦¸–FϺ,µW(û´y/ßÀ6Šó͉Ím¹¼C Y7j‡A%{‰Û}Ø$û“5D&¹ ·E%&ѼŠZ6­i;h²ÅSLðzåa„Ø 3pBçY”}4LTQøt·dÆ0({l²á–ÌÕ_Vð6é'Y}¹´œ*÷膸ñ¦¨äUÅ~-±ŠoÆ`Æ­%¯úÙåUò{Ê Ëx92B’Ó~Krú9k'v÷:hMå‹ÉV³Žvì”àÀÄñ]*—–aú«ÀL‚JdF¶‡â« ˆ¹5 ¥Ïð _œS¦^y,çåÚãì.çÂOzþë¡çaZÀkEæ–Aœ®‹¼[´ê¦ihzõû³—Í>;éÄÙRš×aÆŸEß×g&ßÌf…%l¥KP1fÓL:ø›8WÔ@inš\.Á4”aPà 0cܳ3}×#·¤*lEŒ±™Q=«Y×V4«SžÚ‚{Z6[dÂîHÒi¬ úµn{`*°óÙ*DKW¡«4ÇÊò_%úÑV+¥`›ü@ /kÓ-¢ ùbíšíUMÚsn²YýuÛ§Óö´±0`ÌßöÀQ„“NšND¶ÊÏŠ–’R†ê BÌ*sQ3uí¡¹•AK½¨hŒõÜÈ(}3G-4DH«isΪ[¯!~h§1w¡>TË„Ãx•öÝv®XœÓ³¢‚ž¡ïG¹p4È*j+µF¼{‹MÄÆR}£uÑ4*0$u–•†+ȆRRxYCwck=Ø58%t¯nX‡¡êY=ªÒ§‘ &ô©×Û~¨¶=M- Dv,x]{}Ãt{`JîE5ìú œf!Ô á”äã449 L X–¶Ââ*ãã–ñ vƒråÏ,ûÐäÊq‡çnkÉùLf ‘-Y¦˜ÉN9íã·*¬pùÛ‰Õ«fŸ´¶êè–½ oNÁ9ÅKMC×91Œª`',À„¬¤¶C3jê‹Õ™]¬Ìäâ%ß ¤´xê2ú’ñÁ©õôC·Éiþ=ªÞ—I-W¯í12—W_Uü™§š_Œ›wk#ï†,ÇÁ϶içÃ÷µI"°~¨(04½m¾za+h<³ºyž¼f]Ò4ÑNêBßSØ‚rÓ@ àøƒ‹°jpA…§zõÃÅ\w€ [œ%r·ÃÐ#F~Åôï…Ypºs&ídÔ/Ç?®Ñ°^6lˆ³ª—À=ôsí¾éȱ9zœUƒj‰<ÛJ·0@“+9 óê3"[œPSÅ|_eËXøš¯¬®™#–´´á!L«)i†õJ×Í=ªú|A½g]¦A$ÅÝ·@Œ‰½½$þŒ:Äë†gïuÞŽý,ÇÆqÝ(àªBð¢‰z]·Ç"IJòam;sºc âB'9‘›I;Ѫ83ùSEfñ²M%Cj÷ŒG‹6˜×.…»Ò#œ®2Ùò™ ²fL[WhðÄ‚àp:]Ø©L‰ c'œ€HÙgZ`Jý뢤ËÒáM³ÐÛ (·Ú ³R‰8¯^*ßHs…å7¼všôžJ`ΦÚÊ\†š((/É‘ó¢à§‰%¸ ø-ɆÔ.8n¨*Y¥Lq Ë%6ñzK _Ó|í›^ÞÄ%–ØäusÖBªšŒ.(ª.*Šˆ²d@OQM[êd&Ý\wfZ†<¡G>(ÒüŒè–Eµç5Ô‹íA?tÁ"Ô`æÅ•O}Û(” ¢ël.«¬d{y,Z× Cڊ«Æ}¦©¹•hMÝsE¯„²¢¾0[fŠ a«¨© NDcÅ«¥ŸÐ:޳§ ‹ÆÆ¹"ÚòKr…ç–]½ªžÑcX€¦S×PŒò°ÀLìT™O¤e;hR!ƒ~Ø Š RšÊ˜¸S®õ©ý&Lw• ÆìÊ0¤öíTÎiœû‰'"»/p½(fQN=õß¾bôÔ‰Joc6˜†˜(ÇÆq€iµ¡nð®> (É´(0'YP21qfhbzÚ0½ok w÷ â ^_ÑsÃÂ|Óø·›Ó„qfnÊ{¢ÆÓ@ª,ýŠ"¶Âm°ÇaJjo)/`PÒ)î>ª½¢¨ §K¨Ši¹¿hç¶ìPöÃ$T¥$åå·o4$XYè”jWt©è»dD”ÕÈ.™¸¨¾zá LKÔYë+64~î5I»”É«|òú0w?«Ñ“˜L7; d´Ôôóª¢ç¶ñ_b0`ÛÙä —TºcAÑÈn‡Ó&…E6Ý€%‘UšÚsêj°á<ÌfÅ•.Ú‰ãeWi$>#Ãtú…‘»V‰´0¤>¦¦f#§çi©=ß´6õÙUØ7üŸ•û¦ GzÉãÈVJ;4“Ÿ[Ê,þ ŠkwoÑáà|ÎÔŒœ.d='ßE»©êEñãm‡r?l‚!a¦af`JIª+ŽÔ *çšVO‡” •ÐXͣʛˆÍXÒÝlØ(#ЦbêP6“Yÿ‚.¯bk«­àoEÃâ¬/[™îTÊˆÚ «jéÑ M'$¹©€^»Q+y\rÍ3d«±LÙap±)¯ÖžÆ [òp=J÷(A—Êï‰ø)Ô]TŸGÙȦK0¥¾§%¥¤5½ 2Ĭäbܦ|=¥(´,ZN":WJs˜7Ê3¾ù¯»†ºÁ.­v{3[µÁì¯òy%¨Jù‰K^¶‚‰éÛŽy[ûÞ=1‘%&l*¢(ª·ÛCËz–Qn‹gŠØN‘«z!RÃkÊ“ñå³SùÂ9qi¦…¸»¥2¯ŠRZÄ©6(2ÂJÆšz+M‘( srØe­½Pa• %›“(6+JLa*¹ë‰µMu©>Ý4M!«òMùÑK-H‹Ÿ•FK:€ ޲㠓5¬3Cn@OI>/2åôB–YŸîäRÕt-m„¨Êq¦!ï¬$¸"˜‚ PRŸÔ¢q®)g¡¬É6eØ(”° e!Çíîä¢,xײ•— hXɧ omgC@{Ÿ€È’Âw»õÅf¬v—ÁÚÑ–5sI|w3㜶ŒgJlI»ºU>(õÖ°…l“X[R/¶{¨Q."·i¦˜¦t¥¶WÃ!ë2Ú¢·BU®Ý™Wj:›`@Øèf]˜ãEÎwÈö:%¬ùaö@·®3%~¹Œ³iÆEùʶS!Ø­Ût š‚9£=V2ê7¡©xæ`B½ ³â„m‡!˜ÕÈËE˜AØó*ã‡fÀP²²t%R >$ø|A\;¨52ј‹I\w£ƒIa¢”ëwªp²‚§³ü$/ç¶ü3ÌÎ޲–q–_Éy5׊w³òþ±ªôš-œøQQ¬] æÐ2¯¹Ûr6xMiRS"šÏªû36U-Oö6ÂN™xûÓ©½c&[ÅdeÌ>;q×)¡ºÒrÓ T¶kÓªv™¡e.Ÿ ²d–§ÓÞhêoW;v/ȱ_Ú*[ùF†À5ˆùµ;U”Õˆl‰Ö¸w÷¤Õ_Pâ«þ—Š« ¨ÄS—Ð{Å„ËÎÿ¥èxÙÜñ@ §a?€8 ã’ær0H7ŒjjÈ L”ÕÛQ¾Yɪñ'+@Ž[6ñ”…¿ \ÃH!ø¹S¦oÝâ÷ÖSZt<2öW0"6Mú¯pN``Fªãó¹:P4: ‘†D”œ“›¨JNòwm*·ÜÍ¢ª÷#´’rZ†äƒ‘„—ë‘ ³|G/›—ív©ü¾ †a'l‚6 µä!†mŠ ŽÉ¾SÍÔc0'&zª%6(öb-GHîT©‰s­Ó]Z؉ö¢fv·—s´%åÇ, +1i}UÈp,Ñ¥àó«¡Í´L…÷ 1Á9)«çf›èƒlÍ¡n¶¬$+m\ª(ñëÆÜ­ÞHQdF`A¥¥^ˆaÚ 󳂱QØ)ŠænkÅä¾T¨:¦Ö’Ñ­N$œ„ºa„pæÔcµ(3ÅÌÚ¶|)¿:iKëÙý‹Yõg²ªí±oß«éÁMAU®íÈúV|ÏÊ`u‘M…ò+ŸßnäÂ3Å´…a¡5³-,dW;¹ßk™ñ²Õ¥>±>RnÓ)Ú¥$ï]4„‡DÙŠFb†¥XÉžºJ±FšUÄöåÂ+׋2”´k6{¬GìóÐÌS¨´Køâ|dç ›*ZaÆe O.:¹ &Sof}«ºy&§»´rú@Áˆ 4Íû%§œ¶JÙ¹ª¡™­Ò4â›q»š‰w©"~ÉëÔÜ ÂøR¥®š3P‡2l‚ë è^“QÎ(þË×/‹rüiu}QÛB—"à>£0:§´Ïñvœóž_ ©Ç™v­˜]~åSž­šJÃìiîM}£o礚šÝÐ'* MŸ€Ó§Ä&ÝOVËuf;K§¡ÍvF` l„98 s¢îXõ¼¸Z˜MKòíÛkwOS¨t̆—•öä¿B/Tà4¼32‹Z®¨i7ŠXU¡¢œ´S°I›¬kЭ7J̨^$Pãó}ª[u©F› w Æ©˜Pµ“t ÷u64Xפ†W%Óè6Œ¸HØ]l/¬“^\eI52jà.¬*‚ñ936¾§–Sº ÐäåxDÑåk½vÍÝ34ª¸‡.mÝ£êÒ4<geЕË<¯£™y5ŽAåüJM½§%ÁÞ s8 l³¢i‚˜ÂDZøü‹ f²ÏÒ]°•PM€%E8%ƒH:wKšu|ƲžÅläÊ{QùL .åÉ-®™ÁL« ìS2]ðiEÂÑB™WÁ¤"Ð)ÉN2LV©ºqi¨üµÌtkwîÓS€|æ á6(ÁuVW$8õ¢~’®Çðé‘7i˜Þb[. Lôëóz&RB‹Ä½ÝšÕ™‰tGJ’nLå¾^àVØ` ŽJSwÌÏ!r)šåè9z°kàGC/å§äïÚXSú¨æ{êžÏιh_¶—ÃÎ"3ù5æuAæTóªvq’ÕHCŽ¿‘ݸZ¸hNÀá3%9éY# ¿|ìî·‹‹ŠÆO×մÎÊ«'Ô†à™úš“ŽŠrtÍÆî‰ŠGn@@šb pÃ7àŒÌËã[=7”]Uåã=Ó›ìj*ÜÖÍtÕ÷µó‚Æ­!…=õ•Y|~^E ]%¥ôI_;€yU…}£¨á„HÝè(«ž™Ø½`0ÍÀ:f=û+‘“¬v±Clã§Šf.H¬wñ £³ <ÞvºD&扌bO´‚Kz½‘N2qØ×Ãy‡Y8¤-RÂvã³­Çfx‹k©îÕ­Im¦œµ’­´A» êbPv‰Š@?L{‡·²¹ªd­0U§ÍJ(êVØaÜEcÙ…ì' ³ªƒJ÷r”›t¿Ôû®ª•É7Èi¤61G_­fw0_Wë[hðSÏŒf g[vÖfó^¬è¢©[V ñ<ó0½0Cðwmž¡¡çágç/e稄†§Q04}„ýj¶hhÓ‹+‘.é‚|p ŒíwÖ¨hI³Ü ú‚ASp£Ké{hêP¶¦æÆb³°fœE~<ã,S )å?Ó®©|ùÂjɸv;“<8z ÉqŽ©f‚[ˆ}^V/d-3ðM‰»©¢%u]Ü X7Ò²h*‘qnsíªnpd‚.‘+«F6³Ã:|À„ï>l‘„‹* ÷“Õ^ÌíÖ%ùRø¨‹y†±Œ¤ ‰©ÏÛA“INÿÈÅ3ƒú\U^s`¨öî„™[Ò­v²6Eqfd:†S3ö³Szâ+#ñ~­0"¶hZ¨S`sƒÜê8©T56t‹(ë#¯)»·ú]ªaÙb%³äBõL,)šïƒP„iµc'Å“l|²|XÙiZ`Q¾Ü¡¥é· ¢é»LÎ7õš¢)%rŠ‘á~zÙa€lšf¿ÅU> Fv¤f˜_ëgû÷,A-Èn Ž×™‘Èq–¹6½»glÔ—_Oñòp,Âq8§Œb¦#¥Z4›¤ZÓP'Š“EˆWPñÚñ|*°`|$F- ÃoѾ,IäÞÏ¥ÂÞ²iRltâU¶f'YªÙÍÍ7^ÆÉ}úYAlödK"hYKË—/^¯æž˜­¹`¸¯}ŠŽC›aƒÔ¥—L‰¤%˜ñ³9SÍì¿ êÄ4NÌðʦè:ê‰ì„>¨Á LCö@&!†Q!HsúÛÕ±6‡^e½žj¥5ñ½"Ù×M?®g&*'Ùª{Ëh¤8WÄC±š<5ÊR£½ì\È‚ù8²à¬ÌSU(ðsHÙÖ…µãÝí(•~ñ±úE÷`7\Ѐ)8cÒ ´‡F93r_bÚbCw½K,è[Tª: Ž)aìŽC]¢Mµ™®\iÑÏ=È‚F‘u›d-$.aŠP±ÑŽ³Ñ‘×Îz’Tï™ÒdeWd£[߈r•W‡Æ²ql®ÍzwKsŠ×¤w·ÃdJ¢é¥jT„MÐÓpÎÃilo‘žó³’)‰¬¡[¾¼žåý%B½ìòpOe+të‹p3ì…ž‚†„ø.ÀÄêç¬'Ù|:P¸2m˜U%11ûTµ­¸óW‘é~òrd“­K_S!YMk¶õdé~®9ÃÊà„"¨†YÏb3ŠØ “A;§°¦RÕQS"MIOIe8Ï *~l¦à,̪ ¯EuÑm—aVQ3Å nº@"ÓÛZSjºŠöÃnØMxàf(Âq1Å:ÄîËDnž©øzF¡7VÍ!ÚÌ€øÉÝê6´s`ü¬åÙžÝ kÍVÈ.6ŠWŽÌX[·Ë©¨_³l¥²!w +šBA¤%QÈFJq–Ǻ¦€HÇÙ ž½!…æé —`Þ{aPÑü¸¦TÛÖÊ’0 ¡†`ÎÀ‚ò’*öž‰ ¢¿À 0 3p'ì`\Kî!£P pÔà,L¯²dƒyº½°I*ò=Òî[‚1˜ŒÂ”¡ï;]ØZ6˜±0N’+jÆY$ÞÕ꣣qvD‡e¤5Ìd¡néC9BDÃtyÂ$Bƒ1LSyÁÈPF&k¿.ÍÝ5>L`“Â[TßÞߦ»<ÇàÌK’ GÃ]™3õ+¶¾ 6Â,ŒÁ 8#y¬¼‚âïºÈ#Ч…T‡¯Ã8ÌÃvx'ôÁÓp¶Ã0,HŠ£¾b£!+ã©ÀÔÇî:èÕ¤´órŸ%s»ÓïŒiˆv3eû•£G&F÷²*³«bøØ ¹¬‚`S’.©õt£K:3IVÙ30˵d–_Ò®^þº7÷~‘ bIªžžú†ÝГð˜øGà-°Nó2úØ ås=nbðaa2óæÁ#í2¢ÒNBº¤ª/”áÍð&è†Gà,ì-0/ÁË"H®<¶ó- š#y&Í€ìÉà¤äœÝª%×Tƒ[ÊÊ{xYTÊÉõÔ ‡á´¦ K‡Ã×ÃPÔ˜(Òõ²Z‘aÙ 6¯ÒG²¶@Gà4tÃû Æá¨Á» ÎÀQ8+ä4ÎvT,“°¦ôë`?Ü ×K\ ‚½ð2¼g¡‡ÅªošzM)«Êëʦمfpglɪ §óáXÓ½Š÷Jb¶"ñšd”§"}ð zAEé‡g<£À‘çËhôW-˜ à,L@? kÒíp*p|¯Ïðæg9ódƒá $DiËöˆŠ6Ðmè¸MĹGðhȯ—༠15o„;Àƒ/ÁI…Ûa“ê»å,eÊâ ˜¾*£ œ†iIŒC¶ÂFØ§àˆØ Kºø$K?Œs³»Ãj˜×$9’V´š¬#0Jóž2÷B]hi*"»YJXŽE—6§ٴšrB1áRGÞ¥¸®(¹‡%uHz—•EsÕ¼{S2‹©K·\õ#Ð ß|bœ¿€s0ï„]`[‘ 5¾”ð,‚1…}NävR±> 3bƒôyFf,5tÉVÒ»œ¦V©pÊf¸ ö@þæal…E¸ƤÙb‡çËš‘›aïÄÝK0-ÿÝpFa§Æ¦:{г]¹¾Á%]ß–Ó"­™Ð¥-…aURŒ€?*œ—[ …õÕ„‡4…³,öÛ‚Bµír:5#Àæf*"ºk"iÕªjÞ— †¿j±{]÷"Pu³aÜ|>æE¸îöØž° "ŸùÂ+>8&³hvgŒîQ¼6 IDAT;FþÓÖVr9®_ÎuòWµù–àz8»¡gákЀ;n> G!ÔŠm(ߪ,Û‰ÓRþLY@wÀ ZcLÃIƒI‘ ̨¦Ø`ç‘aå¹ äè4^n|Òª( ¹[~¤"žÛ$ãQѸ„i¨ÃèÖàïÔaŸ•ó.ëÏ+¦nàK¡v ÌÃÔ¡ß”5^ßæžJÞ-BF Á^‚ pá_ùtÇ4à <7øFƒ%˜]R´ÉÕ z*u“Ÿ•eܶÌe]`YÀB"ÖãJˆ»á-Ð çài¨À[à:(Á¤\IÃvᦗýoQ,)¹²WäBÍ㞀I˜’}7ŒG&^jÅ-'1ʶi_rMÞ7hÓLŒKïÿLh“Ü¥"±ç´i/ÊyRÛ‹ŒœI¢¦¾ªuZ°UÓwöúFf¢l8‘N÷Ý _öÀNxžIƒ9è•¶Q WÚB(pª=U¡Î¡!«Xä®%§lÊ€\Hý<%˜të<«éN;a3ô+ÉîÑÜeæãEaר: ×å '…dïž]4fùÚn Za×"D6Ü¿ÇäÉþêªGÂC{Äw*©§±W¥ R-¯ ±q]ØuMö,À”’±n…”žàËÆeµº«»'ªŒV•S>ÃpæáóðP„&ü 6C&áœ6ê› m³2¡):úÙ…Kg+P7w]«k Â<¼ì‚ Pƒ'à¼xZÈ6ã%#Gm_„AؽP…~ØuMp¨I›òH¶1?[¼í¢ LÐÒ2ô4^–'܉æ÷a‰™©Ïª¨Ÿ½K†›À¢:ºì)3$'=Â,;:µÈŠàÝh TU1ü¡¢ ûÓ°vð ˜…;a³Üí$œ…q%þN¯"ʲÞ}£caíÛé™`X¦qv¸…ËnûdÖ©ºç18'qÖt,ëspZ|›X ·tãeAww©#pvËPÒ’p:…áy8 ÓZ·K–¶³ZÎoÃô–±„žéÆ`5z¨¾éÇK }á`%øjêör]5KPU•Ú7óqc•´ÓÖ°=µ´òèî^ue’U¯ØÝR/êÂ=ó°îÐ °p kD^UHH`l(6–äXx Ë’3ÏÐ6ÜæÛ+p3†qÁa½p'ÜUxž…2|ŒÀ ‡3êÝ®å&æcwWJ+ç‡áeÑjì†ëá6¸ úa6ü) ¹M,Î*–)µ›†Ç%•']ޝ KñÌp¡¦jI±zØê‰ k£¢(´ œ­‡y#B_—7‰Ú¼îÍÝn¯©©…v܃ÏÂIÕMF` Á<œ3>ÞŽ:qúš¾ú¯Ä@œµxWë!ÛDœN´Ly—©hÙ›á6¸ÎÁSP÷ÁͰNÃÓbàÔ²CÔ’v!gPð‚Œé:膊Êò‡5°ûn…»àSrÝÆÄãÎ-"N¶C4jç_XåˆÉ¤ÝÌ=_(d¬H&0Vu”(º¶5×W ®*²­~¿ »‚W()iXn„a˜‚`vÂ.)é%²æªâÅJ®¶µÎÈLW´N×*9½”‚œ3¿·Â›àà4|úáÛáN¨ÁSð%IùÙ±¦ËDÀ³Ÿ”`n‚ƒ;ˆ·â•(UXãÉ:OÀ Ø Bih ;.Ø¥Ý~n÷hÛãì]R'¨•^³K74w¸voe\9rǾnzpÃLñ®ªOÌ”Šø’´«®Es·!fª—–£OÂaØ·ÂV(Á œ‚c‚üª*$Í (áfMFY¦&Q³Ó‹xÜMxþN›JgÓl˨CúJTB˜—YPct‘&!d/4àKð }˜PºB»–Ž8Ën²î<ÉQÑêkL±Æ­ŸBìöª¨ùE…d‘€óÌ‹)YÖ Â¬^HC Ú7ªB×Nªêú^SS­§`î’VÞi8 /ø üšz ÈémÄÆâKYºˆ%9aš‚]×'}›Ø&x4­ä_€`¾/hVT,QY7«2ç©ëixÎ6¸nŠ8æÙæ+ÂÂC°_Œ‰wÀƒSª0„†ª•dµÐk{½½W½»‰Ç–ÇÒ“U6u˸G?ÖF„8/™eÓP"P8 ýBèYœ™2F†EÀ…Û`fáA83À0Ü Ã0-º›1MÖIŒja3×ñ”dÍúã”ôv@ž‡Uú~|„ðyø2ô¿…Mð|^‚å©I眯$O–&s[ ¾@RgTà$”a?ì×E¦Úó©Jk`ô<¹‰8;•ÉE,ÍvaÌ%0®|EØ9Qµ¡+;"ØM€+iÚJ¯¢”¦¼OYj’Î/¨(‚ï1ÒäkÁ»»Ù¢)AbÜp^€Ü ;ÄéàœPògÙ¤‰©öõI²½f7‹FìÀÊ\•LOô´Ø­ °Þ ÷Èò>߀Ýð¡27t™˜}¥¾k»‡âκyŽžÊÖmÛ`/Rѩ¤þ=«®®ó‚çšfð³=Ú˜BÏl ANÛèÒWÑ*³ÖDLj¥áêI7Å嬾üˆ†ˆ’™ƒzjò,QVع¾b¢òµnîžÜFYHó6Ø5Þ7‰Ø˜¶S‚£pNÖHë«‘Kzä-ZÁIVø µœ9êY8 áMp#ì€< GàÎ~ù¶ì¦|Š©gø³ŽÂQx.dvj9óU2KÖ˜Lƒj[KjhL'lN°YTœye®^V&EÎq6eganŒÏ%f33ÕJÉî@—ÚR f:ŸÃ šj½M„29†v¢¡Q¡Â¤€%`͆ö:6w;[«;a› I7Â`Æáix ÆaBz·‘^±µR+‰˜"\CP“•Øîµ ;…ØU z%8œâîc0 ØØÇ?y#wýBÑmr?gã·+üµò¥Ü8\¯3ËÊ­8'4Π ˜¿6šŽ‡tU¡ª³Š#¥ìݪï¸9¦Íì|Ž$›ê°bÉ ¿ƒ8¡ëõ.*ä( e·*ØÂ"-‰¢‘5îRð¹Et‰†!œ9ñ"S½®—?øv8Óð< Ø;àp=ôÃ<§~¢É¬,‰{}2¬ºQØsïZ‰5¹ù6Ã-À×à‚Ç=ýüÐ{Š;r“÷ŽÝtþnüô'ø¯§y¶ÃFðà ŒÃœàÑøb*b±é×t ãK&Ô^ÒÂ. eº|®vH˜À57… ÀZ$Ó’¬8^` pÉjFw8Õ»Z¶CÊÏÎ ) H(ëoK T|Øhô“S³AÚ*C0‹pJL„6©qam3±r”b¡”à=°ÎÓ0¿[6åûçİë–BAÝD&IÝj™¶¢?¡©õä`R€å)8 ï†ÙÇmßÇèîå¶7RØFòÌÂÏžýäŸñÿÎS†wÃupÌÁס¢1tÅÎ*KnÀ`¿ˆŒrzfuÉÏ«Ê(µÝ`‡XþÓ*>Dªã$¦€d%Þ½¬ÀØÊ±šÐl¤M£<œ˜(1¼æ´L|ù{§´<+²ç Áàçaza ÎA”ħ-­úÍ­swêúéÓÝ ;`‚Íð£E ƒÇ3<—p^€ã0 sšèÛ“eDyFb%æ·C¦Ì8ÈÀDîÙ§$Õt²ÅF8PàÇ~Œ]?6ã3{.þÂC/þúìxŒn¸IÃ.ÖŸÕ"$GOhÙÊÒHcÚ,Œq#vâhï6pÁ”ÓÔrµS‰ êFú5[jFÒÞ-`¼·Jd&ÉÖ˜|ã­xâ|¶¯¶ŒH_ûґݬ¤%YÑ™§àQ1‚æUQ:ip²|¾×1‰ Q {¼ŽÂ1ø®î¢kãó|ªÁ_%¯téÀ&¸ÆáÌ+Î ³m>¡\B¯ú”ãTò0.*ÌÎSxüÓ;øøï„çÿ¿'OŸ˜š9=1͹? eõª~ ^–>‚›Ð”Ýme‰v)o;e¢ŽÄ°ó{Ì@¯ÎÁ<¯²ÎlÚ=¨dcF0W,~ÿR¶Ý32¼‰K(bæx&€D^¼h(!i?¬Î½2lÔƒØ,6Ô9¨@ÌI•-1ýµ¤/®l æë€"VVÌz캎ïû6z÷?Âãò™&½%~|ˆÝ>["*4—x •tæÙ!]û psÉð„–¥—„°1U@†¦ÿŒÚ}<ôTüxÌNx›Ç˜€¯Áá)˜•øÙ€ÈÜI–ãÞ¶°ZçÑõžg5g"3JdÑP¯ê¦“£&ž³ÞNwšS€×#ôº.Ž´›ÍB´±ˆé+÷J^NÃÚ3ã–J‚}û4üÙ‹n Ô­p#Táøª²íY‘ÆšFpÜqë=}–µª: ²/ÃoâÀoÃmp?õ lÚÊ¿º‹M)'0¦9ËÂ!-ñyx¦Õ³FæôD·Â 0§ä'"Ã7F9bA…ë:<=’<ÎÄ<K\_ä­[ü*‡Bþ|Uâ3;¡`XaÌ9Љ:UÒ ¤6‹ùÔÐ^ÔeÐXœŸº!·E†[æúÔÇSpAmGß%ñïÇáœÚÐó‹³Êåy¢U]ImY¶X0µF;¾¡ùI¶©ij¥vf|C¶ÞK0«$aQ¶îÌ}Ê 3ñŠÍܨ3—Jvk¹ºÓ^¸vjIì†Çà„iru3­¼,»ØñÜ8“ªQW}›»k8š‡¯À©cì=Î7âÿ(à¯Îs†ËoûÓ[ÞrSà{_ˆ>Âã_ä8 À l€Q1U¬ƒ/‹_¹¾ÎÀçᘨ­¶3Sð|DíGj|±ÆãàÃMÒI= /ËE¥èr·©àÜM[RdAs‰»!¥°—³S.ˆ^WçÝìû%C;±Z!T4!°)‚q ß½nþðÒòÔ–ú bœ"›`# Ámï‹™M8 OkjñœÒ 7C%4…ÏÈzfÄÚjUq®éTu¾×%lLˆæ8ò'ÌMqË{éúàöÿ˜_x³Ïcœ˜ M9ÂßÂãP“÷*‡áàä>¸ö‚ãp& mQKWë.ʂߋ™žÅƒáûa+ôÀ ƒxÀNqžR ´4ož7µžü‘–išæ²#Ud†Æ)Ð*á§b6÷séŠgä ‘ûtéAЮ—oU`?gñ¹íÚÌ»à;à6˜£–ÀœÔþ95÷ºÙ1¬Ž_˜¥T­%_tÅ4‚_€?=ÍÞ·ÿCºþOýÃŒ?îħ{~ùåOÌ+º†¸3?¬až¢KÑsÓ!Qplᣆ!À$9IÊÐTÐB3U¸iŠkùªêʃ™8K·tŒK_zå=p#¼Þ]"ž'Lèñ8‘ðUUÄæv’+A4³e /KÖo!¨%¯wsT9'à­ðÎQ‚M,=ÇþôÂCOO\`ç?¹á?Ü[¾£wç6vútä¥ÏóËç^þ^ç3zfNª¡”öÔÅìL^Ѭ à˜°[Œ­[¨!õ ávØ ð)8)3QØ/žê„ª€Mñ–«f9ÑÙÜ=SÐMufzÍõ8c µÄâÀÕŒÀK§ÄÀŽD¶½|avb™ËÑW.Í•×KKH›Ôè8»`3 Co¼t¯‹æ´`†~zÆ‹;õB ³ƒ,݃Ë=wòª o¸––ß8ýðèÇ>BpçvÞð¯¸îgúéÿ·pOWZWŽ%óÏÔ¿XyáŽG¯¸–1ÓjnŸ…îN¸f༡ƒ'YûsAm, ˜§ày8«ù{¥‘rô\#¶'¤¥¦^Y™d›¡r]ÙZ¯Ë›ÓM©&/˜ä&Ò´Øzd¶¬ÀØ4ÙX.É©q¬0˜ñÍÉSÌ a|Ø?°©™9¦ŽÁWá8”}N¨ ÍÝj;~&¹ÜÉÚUJ£ðÔÍŸ!÷ÀٓΈù|Âù¿M&ï_ŠÃóñØËOü9÷/ñ0ÌÂ(ÂÌAàzØÏ£pNˆ¿…Átý,7=¥_Ÿ„y(À&éý¦Ã9ƒ'ìÑ>à]•Ü×’ò˸ƒw³s¼j¦©ÙZ¡k· ²¢‰¹ø$;¡EI&ßLhÁ¾hõíª¶ªêØg`n€·ÀÛ`K‚'< ŸVæp>[[()¤±u0^?6 ì—f\ë$O0ö Ü÷ p¡É#óÀWYdq_ôµ ãÜ}€ëwòî¼kC±öµ™s/Åc/pÿø+hÆ„&Òl0¾í”x#®hçeûSýlȘJì‚ëDuL‡gœUËv/ŒŠÇWëµ uvfXÜγ `bìÏÇ ins,—¶MII–xeÉa‘A®’¬päÊcN{‘it4$qµJuŽÅÿ{g%Wyžùß½·öªî®êê}SkB G Ç`Hœ ¼Ä‰Ç˜Á‰ÄvNN<‡sŽg’ŒOBÎarlgŸØL2€íƒÁ162‹À’A+B[K­nõ¾TWWU×v×ùãÖWúª«»‘2®÷ôRuu-ß}¿ï¾Ëó>»2afXÕ]á©1lJ‚"Tù´S©áá¼oÜ]‘bwtC+LÀa˜ƒe6 ±¾ºë‰¬EÛk\F¯JÄÿ;©†7íµÏ±ùŸù‡‰Ò´GNÜ1^Snp’–E¥2´°Å}FÂQ°àˆPÔ°E+´Sû,˜…Ì Ö«:ÑBÏWºÑ¼CW“ê冨Àø%ð‰–Èýy7wõíp¦Fà™…ëEÈdLXyœ4.RyGL¼§!G%²Øœ(Œ*ÉcIßbά Ù/†½ÇxwKàø€7Á„.¸ v„hêÅYÍŒÅð1Ìc˜92 2Œ×+ ¦ãÕiS°r":÷‹Æ ‚©Ô©¡²è>ïò{ÌxDLÇ®„Vh„€ TÊ6CCꀖd«Š³i^OÍSYOtªŠ-H7MR×a¡)%áÕ*†jM‘›¾çR“A|$ôÀõpµBÌ) ^ pLˆ9• [ÉIi¨]¥joW2’ÛïK]UKŒÀ¸wÀø ¸VìÎÏNqà-úlΈ-¡B‹FDqfLX½‡œ7ñ ¨Ee (6•L&ªIëÉSJ`?º¡b‚ÌzÆ`LªÎåìÍ'¢&c‘„R+ƒá¤Õ¬ uªšà‘³+=U© ~do–µfeZ*E'Ï‹dF©ãpEë*ØêåM]0#‚ ‘ÍJ·µP¥(U§ø<ùÄwò½Ým T 6B á58jP0ˆÁ…Oh4ÅéŒÒæÇ[Ö&üLç ¤„cB\¬pbŸ$àaWU3¨âWʉQÑ0Làè§! èLI$Ç#B­R÷y±ú†"1šûªX|)’±¥P‡ÊÊ·Uõˆ-3Zåû:•ÉÒùæ©óÎxwú̯À>f˜€SP€8äÁ[VP¨’S*[HíUµjK8ïw/÷äê 'áçP€Õ°>kƒ¨kKè'ËbÆ"›"W¤h€…½Ð' –( Ί©Öz‰’j^,—84 pDŽÀ¬Ø6n„íîM̧é‚÷G•$(”Åi•ʻ˔Xï¼R‰L¡|¶•帔ªC±:ÝŸçúv¥BoßjÒ·V$iù÷Ï鎄™ÎÁiÁjX«¡Æ` @ÿaÆ`ÊaÈæ”søß ›~8/n.$5 Ò¸¿2¨Æ$QY¤sOÖ €¸”™ü‹qU¨œ™˜Çŷظ-[¶¤$E•†hyYduBã(UǶ*17Y•¤]yCp.è„r?ö¸’h ƒ.²Ø,$¾-(¦ÕŠRù_‘,Ëßݪ«µßU^ÈKÈÝmQÓp‡Ž;AC0à*9f)Àõ‰Ùä˜îyMÒ×Å;E,–*v‚.ÅîÕ±-6ƒ);)BþÒÉnQ d8R î•jö‹µ<å>'‚,f-ôdµR~±fê<_TªÎEçÝ>#ÝK6*"–&±ÔñqL”Ç´Ë×®ºá8 ñóÌ£Ú|Ÿ¤ªó:šYÐaÜ«¡4˜ƒã° ú;RZxóq¡r‘K_›'(õöÓRAW“N_­²ì]žópgÞr‚¾¯z ÚE¦5#0ƒb¬Ø7Ÿò§*e` vU)b1*ÁëNe §Ü“’E[íÅw”²8¥µ½ø®8¯l[¶Äø’_”SÊœ9áâåäÄSÅdæTvæ•€<ç‰Ù¼£ â°®€`9cŒ¡<ÇaN¡U£ËÁÉsFæ× êwUœëÒ¼!ñwšÒÆ@’bõ ¢Úfg†¼Ì„a t b [ª~ELâ–tüÒt…³ø©TêÏS›)GVZ%ªµÈY+;±*ê21² 3T/(&V¤æ¦òIQ?h…,7ŽOUúë<1ÅäÓ©>ã\¨&æ¥ÌèRo" MÐE8» ò³(³¥:@V´ ËÜøÞJ„I™ßÝ/˜†ÒUÔŠ4æãHÜò\Þmwò2"8“⟀Q¡2i‰…^yG¶ ßUé0S+‘˜ó p2#šºPE_YÄ”Ên±VYê¹°Ø}^T¤h”ˆ‹ Ç™•Ê2NðXî§ZÒRèR÷`^cî²ïª:‚UÂ…aÃD ËÃÍ6¬Ðš®÷8Ëðˆ†hòøÂ`ÙÔ1{ô?xý?r8 I14àH£ìs¢d^æÃ eIKég§Ë3º n€¢œ? CpvÄà.u>‰WÚ~;’7¹ðìrj¢¥ ³§[™«SÙ¶–”S-‹ljRQO•x’ßIeF®hÛ£+?§aÂÐ M¹ZR•ŠqZåÁ_¦Ì6%‚òòp ýΤG.¡ÊŒ_¢Òt'ó·Âo­dã¯Ñv[ŒÛ»h[û]’0 GG†ZçœúQ94èƒ!éÌ B;´‚Ã’ΜtÉU)OÕÄð 7rßï)8 Ñψ)µÍBá£MîÂq8#àÍ%e„Ë~ "¼™ÛbpNÄŽÄHª,òúŽ$úUŽþE°ò€øp¤æQ¹PmhdÈ. hæDÛµ ÚelN°!ÈèQSšP« ðêâJ†–žÇLnp²ò><Ÿ…Õu¨A&|¼4ÎÀé¾ô‰IÓ›t²ãNrÌñ¥m'á§yÃ`¯„Ø¢ÐÛ k W`!‡…—ؕɓœü•™ßÖ€ RuТÐQGsŒõ!:uæÐ ˜sŒXLˆ`9ÍHé*j”yÁ€G$Á†ØHå™%ñ•eõ*ðÙÝ"KäëN%I‹ßs¡¢î]È%„j„vXáÇ BÈåÒ4IDAT4à A¶‘‚„à0³yD¹FiJJö¦Ô ÷I§»¹$š@¹ŒÜÝýb½p ÜkëгŒý ‰dvîðÜ©ÁÑ ^›ls!êhn¤¡Åk·Ô)«[™ Vó öÍ–tÇË‘Ÿ«0qˆ €G±ŠâK>n݉Vm‚>êV¿¥_ _ª )8€9ÄÄǼlñ¦˜rB€ÒXðhU‚*€à _ §˜qw²*‡;©„ÊeGClS°IªÒÙ<ýý¼ ‘2cx@¤4è‚;`m=ΰÍQô4ž\©u¥ ãž$dÄÌÇ<®‘ò',JºÖ")ïüóž3õb~qÖe¶fü»45±ªÅŽõønúPèîký‘èJê—¨'¥>Š?ÍàÇž&¹ß9ðÄø_Žÿ—}|_ôùe¥”¬BÒ¢R>ï\D"+—Õè Ó° ³…¬‚™";FªŸä1^˜àdš>›!s(E¦ôã,tô*•FnݺNúÕKªŠ8ÿòb3¤ôcÁƪ²PõÚ+ ²b8k"Òëóõø  Þ·øéA=1ƒ€FýZšV±¹ÛG2Áì …c g81Gà ME¦„ÓgÅ—*㈠¼!H<‰ë*[ÕÊP.¯ÓÝ=‡Üªm®¬£};m·ú`€åQê½X«(¶ ÈÛ˜;7©ç¦-FUZþ^¥!L¤]Ùkß2þ¡}ŒCÌ@Öà pa'ì 7[9/##“Üdq9|2Ȧ+ðͲû‡¼‘àç6^Ȉ±4 â m~6øèÒh‡˜erªÈ/¬R“uJø¨^uy¼–O´uêô /÷ˆ¨¬^  BQ Õ PH±Wh—:Bó, Qlg¥pK=O&º2æÂEòm…?P¸ªåv”?€n‡d^ƶl#v ñ;ÁÇ¿Q„ACLM37Nvk{ s–t¬EÚbÎ.ñöœ„¤Øù²†üBü…¥°ï»k°€ká^•­W¡Üs5¶cÙ/æýÉ·N#9Eú4æ¦U óõm¬Ú ^ò ºN‘Ȉ#ÁQc/<‚—à§p ’Â]<Òø¶)Écl^Eãß«øµÖÏ›ËRŽšB8J} ¬^Fk>w´Á ÏЇõGGÙ#P„Ø#¦Â-éûzEcÅÕYˆÂ$`LÈÎ$E`cˆÁP÷àÖ­ØkPš¼ž@®ëýùl2éøòäódRÌL8Ù,? ¬B³ÀYq¥@®‡-‚ÛÞ£Xg`JH $/×ÞÎ]©ïë–\;á#p „ZPþ¡kÑÿ…ÑÿJ Aî ::Ðâ´_7HÃ(¼‰ó"ÉÑjXÜntHaÌ2äPôhbª‡¦Vþº™úå`Š?çå4?cQ*Ï_~…HvA+t­qVô2æŽ0½[ЮBëÂÛ‚ÒìÃãÇœ#ã”+lh€Ž¡í°Îo ÜþÙ§V~:óÈn^°ÉÂ:ø¼‡í¡Ü¿ïzç§Ï™_ÊDf¨›áu‡~˜–åZôîxø>xb’ÍûXÖÌH°xTI')Ì0=Îô‰×0Ô™´™ ®‚_‡8´Ã>x:¡¢Ð">²!5¿Ê]ñ‚†¶ íX%¬ñÁ:gs?É™R…„Ì!1~„Ý'H[Ä…òž*òËíýl„û˜!¾?à è€اaŸðu[Æã …!h¬]ŽåÝ(«K‰§ï.:¯ÆÞ…ç§ì~•þ1m^ìbÍ4ÕÑ ‘1°íÃëcE°T^îçPçuÌ>d8°Q "; ¡!.w÷ÂíÐäÎ&Z>Œ²5Í"q3a’ìq)cnÜœ9êX“ØI&u¦lf ;”¹ö¦­¸cWxc'-¾Þ»øë>Z¦8ã²Ax(Ž˜rXÑ¢ÜywÛÆçù‡Éä?1æ”à×å>¨) ¸n°ù<áÇõñ¿9øŠÆþ9ú’Ì:¥™½€Š§‡ºVÖFƒVÚVù£Þî Ú£E:†þtêՉߎ8¶ÂØlòä)ã‡ý¥êS9ë®!Èóû;~Nø†c³žþ\‘:¥õçS§ð4c·í¡g5‘-´þOZ÷±êk(»y FªYYâ&ñf‚7ñ@‚}o²s‚“N‰N¾lè— no[·ž×ˆu»ÔGa´Èý ßùº}tDi¬£¡žë2\7GÑdºÀx†‘S B^eÆGÌOƒFT#¢âWPG! áñã3PaÌO›FжŠ-›¹v{€ƒýœ49 ¤>ªó–‹åî›6]6œÝñ†mÛN&gK_ë\G®|p?4¶`E˜zÔ+X^F,Æ d3äR$UòuŽrÌ Uóû½¿7ޝ-Œ–ùÖ]ï=„7ðBŠ=0 ¸ù±þ…Ã×ß>À] ¾HŠVš"xÓ¥>¥"M0¹µËiÐ` D®ƒ?ó65­{=°l¹×Û¥yâþ°Ö¥·Ai׺:h ÑE逨È‹0æ„‹~_fõ]·÷g7=tü…|ßàˆT/ו[á# 76q2ÊÞ ö‹ù§pÆq’A… Ÿô,ùI|{hœãºzÖý±8~°ÄRæ, ÚbÅ^âWrãV®:ÌñAv™œ©ìkjç ¯µ%–pS¨nLÑ ¡S84ı¡²aÁ›éÂ"±‰Ð %N‡I‰²&"Kˆ{éhÅhfÊ$;€“Å0ÐsLX¥D?,¤‡ÞÉ ëy¸ûÄÄøÜ\ʶK«”J¥V®\£ëùBÁ%¡¥¥õ_ªOÀ=SD'oà%Giózâ·ø×nõtG—5i«´ÖV:êi 󣹬wçCßžþã©» f ÚT>ÓÎÖO+Þ-mvÆ—þúÈÌn³)Œ¯@;Ô qFU‚¬è0TªªóÛYkã¾>¸ñnx™ h/âÑMòY«8XdÄàŒC&„bÙgò“Óèz¤5ïkK-¿‹ß“ÑQ¤Qk[b _îcͬù¬Œ¸Ž@N]CÑð¨˜YD’Ñ~ýðþWÿ[ÚH’79$JÝÅ…0–¸{ØŽœfø4Íõ¬vXiÓGaz´Ä6=¿‘'\yÔë¡Map„qA~Ø,ški.r eeY×GƒB Í–JÀ‘2µ˜3Œ2\Ú‡‚cÕ€1¿6‚²¦\æºXîžN§êt]îžöx<­b?LŸãKù=ÜsN7þ›ÕMw¶mjî@]×À¡fU&ˆÖ¥Jô¤@×ù ˆÒJÏmßyà™Y‡‚ÂýÚnQYýÈ÷yþ­Ü_ð=ƒRžJ¾óxaüh÷}sFûôñaÐCÂfÆbDOOe‡IŸ¤¦8•¶çÞbê‡-F¡> 9x2p¬i¦#€>ÅiA(ƒÜ7MÃÑ"]¯Õˆßnpû­!” þp©bîóãÓˆµ²ªÅ·=zkï¬àG/rÄ,Iî,¨˜`Á ä`¹‡¶­}¼u†§™´K¸QSÔ(- sîø0hT ZO:ı4é¹’î±%NkWq-,öyQ/É­ ࢑ËenG9&9nky…Ó¥2cQ/êéžÏç¥Ä‘HÌx½^àôé“ñx½®ggSåß¾}W¡³ >›`Lᤅ>ÆÔè£Ož±'DZ©sfk˜b?NŽœÉ,¤qrBNl¹¦lZÏUÛœº ‰ƒtÒ &¿Jà»ùU7>±ölU˜¡P‰p¦XÙ?—±ï~Øž"/þ½ðÕ=ßgÏ>Ð眲såŽc|M4oàöz|a:üÓ4D¸>ΛZG>ÁóFI¬bNàȉ^X ~ ?;ÅØ):¿•Ž*{Uöz *®hê=D:•èj–u;WÚøfh….\B 1 ¿Y—•yÊj%!ëXKUhG^ =02‚ñm¦šhl"¡ÁG}uQêLz‹ åàØX:¶Ž•ÇÑqŠ8ŽQòz°qlP5Tšƒª£d1ì8/%”p¦EÒÅ;€IžŸ»‹EÓ´‡ÂápùÁDbºXÔMÓT”sý?ü4á[©^·"Š·^A¤P>?^Ÿö9ŹQ™jf`<–;úÀÁ)g/…£¦ÁGÝj<¿«ѺÉëL÷ç^,6=ɪ}ìÌò*Œ ¼¬cšGEéA¹¦'ì½-\"X/BÛÂT0U †BÒrI †‰e¢)( Ž‚Ç"4§…Cu·pÍ)š‡1 Ð/hp|‡U°l¡©ÜÚ M¥*´3ƒ5KÎ,µ×mÆJÁ1ЇI¿Æ{y.ÇËpD¨5©eHºàvMËÈ6’šÃH‘È1mÓ©7K 0$ÄiJrj%# Í£xÝÉÆ(­¤ÐE*E`ŒÐ(Öý&‡¼MV§ÎÀïTð8(Ÿbc;X88ŽÞs„’‡RB€frÎY&· D¶šô†ÎÅs÷`0°mÛ¶¦¦¸ãÐÓÓøMÓTµµ«««T^ôúÎ5˜ñÐu,ƒ¨'Ž@Ÿ-N' äMÝ1sŠ•QÌŒc§m+i‘·¼íäl'o+†í˜68Šßñ4ZdNÓQ¦p†!íN£¤ñ®Ìz;΄Zm?f¨—ÐM´?Y*„O‹aðòÔLžÍÿ{º4ƒÃ³CJºPÌ¢')¤l3o3IæÈëèŠyŠYò90°L¼ªJÑÁë¥.LGÝ* )Rý"ž)ßÐ °ÚsÍ—­àµÃ¦2åèºI^·s¶^À²ñ8xUÔ0j_#Á:üá8ëHåJ ã•n™~Ú4%ˆ„¨ái¤3:‹2Íl†SÐ?…B¬!(8­ŒÊØF|™G’1#EŠ[ ] ª«]p’ûïN#G±ˆiœý±Mçl~Yb”¬Lbå•äfà „3b"Â:Ö+˜Ù´iæMÎý6VÈóèýØ~,¥XÔÏÌÍad˜°˜„¬w/Hóš¶$ÅæHåIx÷øÉ ¬H„bÅhŽ Aò ÁaAÔaTð¯ð““4ž4æ?%±ÓP©$QM l›â 4Pr(S%p¥&¾‚Œ#0à5x-ƒýsÇóól–¬)!¥  ânßž€„hšÊY vÃI‡ÿ“*%|¡¬ôßC‚‡G•s^ÇÊ©òrÄÆØ Cy–?C׳Dêñ@% ÖiøA³ñø ÍÂc¡Y8ŽêTd½e’PCšóÐ¥»yNàÃÆa&E8:»¤ Ö¥ØfÊÛ|it>ºm 1[„)Ÿ:qS“kòàæ÷ù³/U“kp¶ÐœƒÓ‹ÓË"vI†<$UABõ÷*J“ËNUÒ,ï.7¯ax£2–WI­D‡ga@b°P¥(bÊÉ¡JÍjöKÇ&ž«ÍÌ$ £&íõzcµE¬Ùåbçí;Ô×?)ÿ<þ½W9Yþí /¼ôÐC_Ý»÷@mMkö~pw¯/m]ÑØ¾ª¹kÝ™¡ñg¾ÿÔêuË¿}é¥]?üågŸ}¾¶¦5{?¸ûÄØÐÇî¸ú¯?ûûûñÊç>ñ›üÐï6µtÌ{ÎCýemMkö~p÷¦–öþƒÿã{ú±¿q÷½¿ó‰RiŲ¬‡úꫯîùÎwþ­¶ 5{Ÿ¸»¦yþð?ÿÕýþ½XX}ÅUªªŠÇµ‡þòM7mýøÇ¿¶ 5»”í<*3ªâÔ…´ÿü¯T;{ß'>ðÚªr¶8ÛÑÑ^[Íš½Ü}ÃÚîæð$ð7_ù3Ⱥ£˜åÞÛüqm5köþq÷ÆÆ¨ekKV³_ w?Gs§PH×V¶fï¡9ŽýKsw;ŸOÖV¼f¿§{ÙúúN½ñÆM;[üihˆ‹…@ T[÷š½+V(ä¼^_&s6šðz}·ÜrS,ýe»{>_¨¯„ÃaEQü~kkk29kšÖÊ•+u½P»T5{‡622ªiMíímÙlvjj²P(ñh4¶ØÜÅÅED*Š ƒÁ€aè©Ô¬Çã3Œb™«£f5»`K$¦›lÛTU§»»+—+LNN,=Aª^ÔÔÕÕÓÑÑîñ¨†¡×.OÍ.žézÑãQ–-[67—{obw ¯ïxcc,‹64Ô×.IÍ.òa?3;›ŠFßw÷ù"óê;‰D¢¾>¸ÄŸ¸܉ÄL"1³XöP³š½C›™INM%|>¯Çãñù¼ïŽ»;ŽmwŠ£Glݺe‰?‰DêêêêÜ›¦™JÍ-_Þ;88<99Y»H5{‡V(º»{GG',Ëiiiq …Â7˜1Móé§Ÿù½ßû-àñÇÿß}÷ý®ûx6›Û½û@ÀÕLÆëõiš688T»N5›WÑp)º.À^yå5EQ C7ÍÒœÇãùÈGîlkk¹XînÛΉ'ñ‹½Ë–u;v¢ü¸a¹\Öq,UUÛÚÚUU™žž©Õdj6ßÙ寷MOO]Àßž8Ñ·yóæ¡¡Áb±˜H$lÛnoïhhˆ^ôTµ¯ïÔ‚ùh{{G(L§SÀéÓ§ÛÛ[k¸fóln.3::|xúôéõë׋EQzz–¹¥÷%ì](DjšêñxÀË/¿ÖÙY1ßtÍ5[,Ët}½f5»xæ8N6›Ñucé§áuêСƒìñš¦}æ3ÔÐP_(çù9œÏb±h}}]í’Ô좺{&3766¾aÆwÇ݃AïÖ­×.ø+·È «rçb(Ìd2³³³ÍÍM‹áÔjö+nº®§R‚¢µmÛ²¬Lf.•J+ oKsÛL~¿ïºë®‹FKyC±X\½z]8\ÇÕl^ªŠß\³fíüí† W¶¶¶ùý>WmƒKà.¢»/v+¨YÍtÝ ‰aæíœ·{þÂînš ½½Õ¶­Úu¨Ù¥isžâaõ”é”*î©±ÔŽØ ^íü»ª†‘ºº:lÛ¬-kÍ.Y2†òN‰âyàôÀmõמŸ»×:ü5» ,Ø¡«â‘ýûßòig55ÚÚZººÚ–r÷îîÎe˺kKY³KßÒZþˆÑ'?²eËæÿlyжmDZ–rwDZ,ËRõè=w¾Q+PÖìBüF±Œ‚¡Û¥Q ˰lÛ°,ÏyÇîõõªªýr>´i3™ñÚÅ«ÙùšÏö´ŒŠ% bG qéÀ÷JΠf5{7Ü]»mÃMçõ'Ž™ùÜç>÷N>î·¾õ­áááÚe»=Éòz+~Òéwyš^Ó¼>_D~ ÓT …E‡g £GmË‚žÞž^«Ý23×77ïýî½÷Þ;ï¼øÒ—¾‹ÅÖ¯_¿mÛ¶l6ûw÷w÷ÝwßtýúõO>ù$°bÅŠ•+WF"‘|xâ‰'R©ÔÐÐ Ô\çr´}ûôöö¸ck'NœŸpÑÇ÷ƒƒCMMñ‡þòéÓƒO?ýÌääÔ¾ðÙp8<=H$fÎÝÝ_}u÷?þãß66Æzè«;vÜ6ï·7Ýtõ×^ üíß>rÿýŸ†‡G{zºæß¶|`‹¥[©‘”˜0'tGŸ™dùíïd}ôÑ}èCË—/O¥R_ûÚ×€Ÿüä';wî\ìù?þñïºë®š÷\v¶}û¶'ŸüÁ7¾ñ-àê«7U?aÁx£©)ÞÔ?÷wY¾|ÙbG]×yäŸ\…ññ‰¥_§hÇÌ1½ OLM,»wtt”gC¶mÛv÷Ýw?úè£O=õ”ÏçûÊW¾²{÷î'Ÿ|Ò0Œ/~ñ‹÷ÜsÏöíÛd2éFó·Þzë¿øE`åÊ•÷ßÿÜ\é¾±zõêæææÏþóîo|ðÁòàvÍ.#;uêôÄÄd<Þè6+Vô¾úêž={ÞØ»÷`õ“¯¾zÓO<¥ªj±XüÀnܰáŠs|—C‡Þúú×óù|.¨öÈ‘c?ûÙ+±X´¹¹©µµˆÇs¹œeYuu‘d2õØcßýÑ~rã×/•.(x-ÿšîèÓ»&ÿbûýî£ ]µºû¯²Y–òƯËض³mÛuåÿNLLæó ··gtt,•ÊÔ×G¾ño=üð—ÓéL(ôx<†a …ººÈààã8~¿¯½ýlT­ªž£GÏÎ&%O°Ö­[—Nô‡úê|J×õ¦¦ÆH$’Ngff’@KKs(œMÍΦÜ7 ÇŽhlŒ½øâ®íÛoXµj…üÉßòî5öë9}×ÿÙU«»×lÁ*¡³4~»µõ쨿ßïî¹§R©ÔÕW_å–PÜǽ^ׄ¥Ø¶¹víÊ%Þ¢»»SN:ëëë䙸h´!m(…+Åâþý‡Ïtwwuuuœw!2—K,͵÷.šm×—·Åã_øÂŸ¼ë/ûéOòŸé÷û?õ©ŸË3—׬fï3SkKP³š»×¬fïC;ÌhÞÃÞŸTÌÂÑ‚ZÓ ¨Ù¥h…ÙB´1Z°öÏYR ¸{l}lŸq`Á?>1|ýêëGƒ£µ•­Ù%hÇ·~`ëˆ9rN§»žÓug)¹K·lËÖs5I‚š]Šf›¶©›za)ÿt½×3pf`ד»ô·S×°†­¡ÚÊÖì´€?ËŽM޽í3ÿ?ty¾‘¦ ¾GIEND®B`‚snd-16.1/pix/fmeq24.png0000644000076400007640000000056311147553267012756 0ustar bilbil‰PNG  IHDRd hÇ;ô3PLTEÿÿÿàààððð€€€```ÐÐÐÀÀÀ   000°°° PPPppp@@@—U pHYs  šœtIME×  2MØ­ÓIDAT8˵“݃ †• ×Ïý_í°V-‹éÁúòèåƒPœ«É¸§Yz~¸†úMþOfÆL0é1Q…ªºvË:Å ÔYg×.)Ú 3[”ï6•}y½TÈsÇàOïWGÝéÈ,xíVC"¼AmºN뛽8–%åæ^I›8(ÔÅÉñ»HáS’ôÊ3eñÃõ}¤IuP$3Ê€+ÛU¸j§ÿ@gö>ìG—£¶Ÿ†+i݆5Ñt`ÛS.]GªgÍKn]ËìúxéXyó{IEND®B`‚snd-16.1/pix/1f.png0000644000076400007640000000272611147553266012170 0ustar bilbil‰PNG  IHDRƒ®¸ÿObKGDÿÿÿ ½§“ pHYs  šœtIME× 7R ËcIDATxÚíÝ뎫*€Ñ2éû¿²ûWâE]+9ÉÙNoS¿´NX–eùôç%Ä@LĘ<&!„OaØõÄ$„ðY–å³,KQ j¯Ìï{§› Ãe@LŠmÃÈ4Í‹¬`šS=ýøE£dí¢öúÀKb’ŠB."¦9bˆ &€˜ˆ &€˜b &Àus>@LŠ9Ÿ ˜æb &€˜Ô±vbˆ €˜bò?Ä£ÀÈ£“‰ ˆI—ÑÉz”’‹‹ðÀ1=Ÿ‰?? bRˆ½ÀXCÓœî!“®#šBñZJË ÄÄ(¥‰ÐÀ cRâ ‹  &/··¨+ &‡ƒò ÉÖ1+ñõJvC¯×i@L.ŽÃom¥4Hb˜P4Z© ÒÞè%5ÊG‘CL&‰H*,©H”ŽRö‚22ƒ˜L0 JmˆëiQêz¿àÄÑÙºìèF_ºž#>ˆÉÉS›ßÆpÄ4Ɇ˜Ïîè d´Çj=zÉM‡r#¦QÓ§™Â&²bòêà”ŒrÎܨֻÄãöØXgÝà…HL;¢iË:©¯oVöFCWm %ç¡©½/ç¶yyL~oøø¿7f}²§ÔBm||Lnʕڵ¾|ïqýÉѧ›päó‹b/€ÖP6K(F<Þõ$”Ú׫ôÀ½ß\³ñåörñä"qF4Þ&Óœ‡MŽÆ¨×oþÜîïÒ no‘¹ç4j+¾=G^¹€>%6bòÀœ5J‹G"%Gõ^Ô–ŒZ ¿Ó)Dü Åäå#”–ÛÛ;J8µ‘¦þZÊMuS Éë‘P¼ÖT»¡ì}ßz/Wë†X{gŽdjîKL^—Þß»^ ÞI•n8%ë=5kD­æÜ›®äžÓV˜öF-{SºëT=c%&œ2ݪ WéÁ}µ÷Õ¥’çŸ:5hm¨R»ìÏ…´œ´]L˜"B­k -Ç뜱²7:I}=·»>þ¾Ú[¬[w±‹ SæŒé`í^¬Ñ·é¬…ÚÚ=rbÂí¦H­Ö™{Kjb—{n¹ 5·ŽS²î´wtoîèç#¯©˜pË5˜;räëRrNÍÑÏ-Œ†.ˆÜˆõ›Üç®ZÊ«}Œb“M¥z>ÎÖ=b-׸yXrŸÇ:óyˆ <0lWOL1æñ½ÓƒuÂè7zuLŽ|n0ÍÄ1Ä@LÄ@LÄ@L1Èq>à}1q>0ÍÄ@L1Ä1Ä1Ä@LzÄ$„°ùIÝÔåµ·ÜSÕ)BÉÓü.O]çÈõÅ䊾v¤Œ•kÀ·d£ŒG%7zƘ|d’Û€ã¯Í4=™uš4ûÎãóøzúýdŒà¥#“ÜoÿÔ4'þZI k¯<(&5S Öë÷å µf¦Ç÷ìÇ'&€˜bpHXLü#@L19}.æôÜXê½X{:ÙOÿñw‡IJ,ÿÛëúpUH¶Þ§½.¿bû0Íaè(ñíÞ´CL6Jä]Ä„C¿qQÙ±ü.Ë]jz°u;µ÷›»}úøÞõûÔñ5¯÷Ö92¶Nù¾^îò’ÑPî¾Jî÷­?¯3Ÿûô1qzƒ¹~{ŸO…âÈÏ"wê‹Ù×,RN½O{]~Åöñ½Ë¹æM""óþÜjãÑ#Dñ:O.Šg¿©¯õ¸üŠíãë-ÏèeüN-Þ®cnýɆPr/¿lÂ|6‡«§g½…d,{s-ŒL€yüK@‚‚©WIEND®B`‚snd-16.1/pix/interp2.png0000644000076400007640000015642511147553267013254 0ustar bilbil‰PNG  IHDR –€|ç)sRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ/2ÒØþ* IDATxÚìÝwxåúÿñw6ÙôAEÒ‰!@¨¡ Š€Q‘r•âÑ ¨ (‚žˆ"*EÅBU@AéÒ½B©@B¤×Ýßüد‘P H Ÿ×uqÁÌÎνsÏì=ÏóÌce6›ÍˆˆˆˆˆˆÜ¥@DDDDDÊM’““CBB wtüøqöîÝ«ŒŠˆˆˆˆHé ÜÜ\>øàV¯^}Ýìܹ“ýû÷Ê+P¯.)‰Íõ^üꫯhÛ¶-QQQ×ÝÉ?þHpp0'Nä‘GÁÖÖ€ÂÂBL&ÓÕml0Ô¬,˜L& Ëul0`cc£&"""r· /¾ø"7,@®ç‡~àØ±cW,£Fb̘1:·Ytt4Ë–-»î6{÷îÅÓÓ“ªU«–ëcÙ±c}ûö½î6:u¢}ûö:ñ""""•¡¹žxâ žxâ‰bë"""”ù›´xñâ»´?~œ‚‚‚«Öççç3hÐ š4irÍ}>óÌ3T«V kkër}ìÉÉÉ%¶ž]‘““Ã{ï½ÇÊ•+¯z-,,Œž={âîî^lý½÷ÞKÇŽua‰ˆˆˆ”Çdÿþý„……ÎÖ­[騱#666DFF2|øp¶oß@¯^½øá‡pqq¡Y³fFeöÎ;Gxxx±u³gÏÆÛÛ»Ø:úõëwÕûüñJŸç{î¹ç†ÛÌ;·ÄõIIIÄÇÇ_µ>&&†   bëèÝ»7µjÕ²¬«Y³æu‹8)«ëͲcÇ.]ºdYîÙ³'F£‘ŒŒ vïÞMÏž=-¯ýïÿ###ƒ=zÜ0èÀ ¬Ô]°Î;Gff¦eù³Ï>+ÖâKïÞ½ñð𰬫W¯ÿøÇ?tUÞagÏžåðáÃÅÖÍ›7FY–“““?~¼el“µµ5 4PòDDDDngòw©,Hvv¶¥{ÔO?ýÄ¡C‡,¯8p€'Ÿ|Ò²\»vmúôé£+®‚:pà´,ÿøã4kÖ̲\½zõb׳££#VVVJœˆˆˆˆ Ò;wî_~ù¥eù×_µ´ø ¦Nª+ê.õå—_\n ôóóÃÕÕ¸ÜE1 @IQR²•+WZºžýúë¯Ô®]kkk¼¼¼1b„e;£Ñˆ“““®")&//œœRSSùðñ³³àĉüóŸÿ´lûÔSOY^QRÉ -[¶Xž$µjÕ*œ-…ÅÓO?mÙÎÇÇGÝi䶈ŒŒ$77€7µµ5ñññ<óÌ3Ô©S%KDDD*¥»b–·äädX´h‘¥èÈÌÌdàÀÀå§JuíÚUW„ü­þ8pýcH}úжm[%MDDDʵ 7$%%…~ø€ï¾û޶mÛb2™xì±Çð÷÷ÇÆÆFÝT䮑““ƒÙl&55•÷ߣш‹‹ 5jÔ°0O""""åI¹nÉÈÈ`Û¶mÀå¯7nL^^:t eË– 0 ØD~"wàò¼#³g϶ü¿9þ<ÉÉÉ|øá‡¸¹¹‘ššjézxÿý÷S·n]%ODDDT€ÄÅÅ‘œœÌ¾}û8zô(&“‰úõëÓºuk‚ƒƒiܸ±Î˜È ¸¸¸àââB£Fhß¾=;w €ÄÄD^{í5jÖ¬‰ƒƒÄÁÁA]EDDäŽ)³.X-[¶äßÿþ7_ý5‰‰‰>|Øò(Ò¾}ûR¥J!‘¿ÉòåË)((`ùòå4jÔˆÌÌL¦L™‚ U«VÅh4*I"""Ry Ÿ~ú‰éÓ§0lØ0<==u6DÊÐöíÛÙ³g¡¡¡R§Nzè¡«Á‹ˆˆˆTȤcÇŽüç?ÿÑ)gL&EEE¤§§óÎ;ï`08tè ÀÅÅ…aÆ)I"""Rje6ÄÚÚZÙ)‡ ƒjÕª1kÖ,âãã),,dñâÅÁc=†‹‹ íÚµ£fÍšJœˆˆˆXäåå±víZ.\H£Fxúé§iÞ¼ùkIHH &&€×^{”ê1¼"RöΞ=Ktt4‘‘‘lݺ•*UªàææFïÞ½ñõõÅÑÑQI¹Ëìß¿“ÉÄï¿ÿÎÙ³g©^½:]»v¥ZµjÅxsÇ ˆˆŽ9@pp0C† Q"RI±råJöïßOZZŽŽŽtîÜ™6mÚàääDÕªU•$‘J$++‹´´4øâ‹/prrâüùó<úè£^wªŒ 7¡ˆ”©©©|óÍ7,]º”Ž;2räH6lˆ•••$""R™Ífòóó™4iǧyóæÔ¨Qƒ|fÍšÝô~T€ˆÈßîäÉ“|ùå—äääE·nÝ1b„µ-""R|þùç;vŒÄÄD¼½½éÑ£={ö,õþl”Rù»5mÚ”ÿþ÷¿˜L&øä“O8sæ øûûÓ¸qcüýý•,‘2ËîÝ»IMMå·ß~£aƼð ôë×wwwìíío9† ¹c ^^^¼ñÆdeeqâÄ Þ{ï=èÑ£õêÕÃÛÛÛ²­ˆˆˆü=2228zô(f³™Y³fáææFß¾}iÕªü[æêS,)7Ξ=˾}û¸xñ"«W¯æž{îa̘1¸ººâéé©§k‰ˆˆÜ¢¢¢"bcc˜5k™™™Ô­[???6lÈ?þñ¿ý3¨DDÊZµjÑ¿†ÎáÇٱcgΜ!::ooo¦OŸŽÁ`ÀÆF?¾DDDn¶è(**âóÏ?',,Œ .Ð¥Kz÷îMïÞ½ïøçÑop)·üýý‹ Y½z5S¦LÁÖÖªU«Æ³Ï>«D‰ˆˆ”`íÚµ„„„ŸŸONN^^^|þùçeþ¹T€ˆH…ѯ_?úõëGnn.,\¸±cÇ’ššJÏž=©U«]»vU¢DD䮵lÙ2BBBˆŠŠÂÃÃɓ'ãàà€³³s¹ùŒ*@D¤Â±··ÇÞÞž &PTTDHHpù1Ë—/ÇÛÛ›€€1 J˜ˆˆTZûöíãÌ™3¬^½///L“&MhР...åò3kºˆT*lß¾uëÖaccCNNýúõ£qãÆ4hÐ@ ‘ íìÙ³\¼x‘™3gR½zuxòÉ'ñõõ¥nݺâÔ""•Š‹‹ }úô¡OŸ>ÄÄİ~ýzfÏžM³fÍhÑ¢ýúõÃÚÚ%LDDʽÌÌL>̪U«8|ø0O>ù$£G¦uëÖòxÔ""w•©S§b6›Ù¸q#½zõ¢gÏž´iÓF‰‘råìÙ³|ùå—Àå§X<÷ÜsÔªU«Â› ¹+eff’’’Â|@DD½{÷¦Q£F––‘;mÿþý;vŒÅ‹sÿý÷3`Àüüüpss«TÇ©.X"rWrvvÆÙÙ™9sæ’’Bbb" Á¨Q£¨U«¾¾¾J–ˆˆü-âââ8qâ‹/ÆÃÃÄÄD^}õU|ðAêÔ©Si[ˆˆÜõªU«FµjÕðññ¡k×®„……Ç”)S¨^½:Ý»w§iÓ¦xxxàáá¡„‰ˆH©EGGsáÂ>ùäòòòxôÑG5jmÛ¶½kr .X""×qþüy~ûí7òòòøþûïñññaôèÑxyyáêꪉˆÈuegg“——Ç[o½…µµ5õêÕÃÙÙ™-ZàççwWæD- ""×Q³fM†ÀóÏ?Ï‘#GX±b¿þú+ݺu£{÷îtîÜY‰‘b"##ùúë¯Ù´i}úô¡Ggøÿýí- ›6mâôéÓÅÖÍŸ?ŸáÇ«DD*¬¼¼<222xûí·1=z”Ç{ŒnݺѰaC%HDä.“žžÎ’%K8sæ ùùù<ýôÓøøøè±ïwºIHH ##£ØºÑ£GÓ·o_ "RiDGGÅÒ¥K‰‹‹ãù矧V­Z´jÕJÉ©¤"## åÛo¿¥fÍš´hÑ‚:àííµµµTVHI4DD*³3gÎ˼yóðòò"55•1cÆàééY)žß."r·ºxñ"gΜ!;;›ü‘¸¸8† BݺuiÞ¼¹t“4DDä6óööÆÛÛ›ÀÀ@vìØAhh(AAAøøø0|øpêÕ«Ç=÷Ü£d‰ˆ”s—.]"77—)S¦’’BóæÍñññ!88XÉQ""R>uìØ‘Ž;2dÈNž<ÉÏ?ÿÌš5kèСo¾ù&NNNJ”ˆH9Ê7ß|ömÛ0`ƒ ¢[·nJÌm .X""e ¨¨³ÙÌæÍ›Ù°aû÷ïç±Ç£k×®üãÿP‚DDî°ääd–,YºuëhÔ¨÷ß?ÿú׿°±Ñ=ûÛIÙ)W'öìÙ“ž={rþüyâãã™={6...´iÓkkkxà<==•0‘Û¬°°Õ«Wpøða.]ºDçΙ;w.uëÖÅÊÊJIR""RyÕ¬Y“š5kÀÞ½{9qâ“&M"''‡±cÇâééIýúõ•,‘RJJJ"22’Å‹cmm››={ö䡇Ò£rï uÁ)çöïßOtt4 ,À××[[[F…››...JˆÈ5äåå‘””ĪU«ˆ‰‰!::šN:Ѹqczõ꥕µ€ˆˆ”s0hÐ V¬XÁÂ… Ù´i­ZµbÒ¤I¸»»«»€ˆpåÞú[o½ÅÉ“'qqqÁÏÏOO­R"""¥õØcðÆo0}útNœ8µµ5~~~)I"r×Y²d ¡¡¡ìÞ½›-ZàïïÏÔ©S•˜rH]°DD*üü|’““Y³f §NÂÝÝ àääÄÃ?¬‰H¥³gÏbbbؾ};f³Fމ›››m^ΩDD¤°µµÅËˋ矀ÔÔT"##Yºt)[·nÅÖÖ–>}úP¥J|}}•0©p¢££‰‹‹ãøñãœÆcccc™£DDäN2™L››Ë›o¾IDD­[·ÆÃÃnݺѤI%©’P ˆˆÈ]¦J•*Œ5 €Q£FqêÔ).\Hnn.ǧK—.Œ9www%KDîˆ>úˆ233iР<òݺuSbT€ˆˆHeÔ°aC¦OŸŽÙl&%%…={öðöÛoséÒ%\]]iÙ²%C† Á`0(Y"r[¬]»–ððp¶lÙBãÆñööfæÌ™¸ººj,Ç]@]°DD¤D999DDD°víZ’““INN¦S§NÔ¯_Ÿ† R·n]%IDnJHH Ì™3‡û¢"†NíÚµ5–ã.¤)‘ƒƒ~~~øùùÀ¡C‡¸páŸ~ú)nnn<ÿü󸹹Q«V-ÍÊ."rúôi>þøcñõõÅÃÙ3gj,‡Ü¹mÛ¶±fÍ~þùgÆŒ£‘ ,$$„ÿýïDEEN½zõ OŸ>ØØØààà $‰Ü%233 aùòåäå呞žN`` õë×§{÷îJ”MòGê‚%"RùñöÛo°qãFzõêEŸ>}hÙ²¥’#R %&&2oÞ<àò¬Ìf3Ï<ó ÷Þ{¯’#*@DDäÎÊÌÌ$11‘>ú[[[ÂÃÃéß¿?UªTaàÀJH´cÇ"""سgÎÎÎ<òÈ#´lÙ777%HnšÆ€ˆˆÈmçì쌳³3Ÿ|ò áááñí·ß²{÷nN:ň#°³³# @ƒPEÊ™¢¢"6nÜÀÂ… ©]»6iiiŒ7ŽvíÚqß}÷éiURjj‘;.22’3gÎÊ‘#GpuuÅÛÛ›®]»âêêª."wXRR DFF²víZœœœ0 ôîÝ›jժѢE %Inµ€ˆˆÈ× A4h@=ÈÍÍeÙ²e|˜Þ½{ãì쌛›O>ù¤’$ò›7o&""€¥K—€½½=¯¿þº¥è·²²R¢DˆˆˆÈÍHKK#%%¸Ü…$33€:`ccƒ‹‹ ]ºtQ¢ä®päÈbccøú믩_¿>YYY–ÖB'''jÖ¬©D‰  ""r»íÚµ‹ÂÂB/^l™™ÝÞÞžP¯^==qK*¬¼¼<Ž?Àþýû9vìÄÆÆ2zôhÜÝÝñõõU²¤\Ó©4:tè@çÎ-ë¾ÿþ{ÂÃÃ9{ö,{öì¡~ýúdgg3fÌÜÝݱ¶¶¦zõêJž”+/^$77€3f`mmMFF¶¶¶´oßWWW¦OŸN•*U”,Q"""RžüóŸÿ¼jÝáÇY»v-«W¯¦}ûöÜÿý 2DI“2±cÇ~þùg¶oßn™´³GôéÓG ’JC]°DDä®f2™¸ò«pÚ´idddX¾ ^)FjÕª¥Üå¶Ùµk.w«JHH°\‹¯¿þº¥UÃÚÚZÉ’JI- ""rW3 –O:Õòï´´4ÒÓÓøüóÏÙ½{7aaa <GGGZ´hAýúõ•H)&==Ý2“8\Þ¨Q#àr÷ªÉ“'cmm5jÔPÂ䮢‘¿ >>ÞòÄ¡ÄÄDV®\‰§§§å‹e`` 6ÀÓÓSÅI%–œœÌéÓ§-Ë¡¡¡œ8q€ììl7nLëÖ­¨Zµ*M›6UÒDT€ˆˆˆÜ>çÏŸgçΖåÄÄD¢¢¢,Ë/^dÊ”)–ù¬­­ñòòRâÊ©””ËŒáçÎãûï¿·,ÇÄÄðÀP«V-|||hÖ¬™'rê‚%""r›Ô¬Y“Aƒ]óõ;v°jÕ*Ëò?þH«V­Šm3lذ¿Äþ±«˜Ü³ÙÌŸï¿fff2uêÔb“óíÚµ‹Áƒ[–½¼¼4k¸Èmpô´4bccñóó»î޾ÿþ{’““yñÅoT- """%ûúë¯-Ýx®Ø¹sg‰ƒà{÷î­;îבššÊW_}uÕú5kÖЦM›«Ö?ôÐCšÀRä¸n Hbb"3gΤqãÆ×-@/^Ì}÷ÝGË–-™5k/½ô’îÔˆˆˆ”°aÃJü"——WlݹsçøôÓOqpp¸jû#GŽ0bĈbwóÿÌÙÙ™‡~¸ÜçcÏž=DGG_w›%K–XxÿQaa!;w¦]»vÅÖ?ýôÓ–q;"RÎ M›6ñÄOpèСëîäСC<õÔS\¸pÂÂBlmm8yò$IIIŶ¿2hkûöí:"""¥ôÇîAÔ²eKË£]¯%33“·ß~»ÜcRRcÇŽ½î6?ü0Mš4¹æë§Nºj]xx¸. ‘;¬iÓ¦T¯^ýÿ ?þØòT€·Þz‹§žzŠˆˆˆ[ ”••EZZZ±u®®®,Y²Ä2 Ô_•’’BµjÕJõÞ‚‚²³³qss»ã±óóóÉÍÍÅÕÕµLbçååáâârÇcçå呟Ÿ_&±sss),,ÄÙÙ¹LbáäätÇcçää`2™Ê$ö•›WQz·ÄÎÊÊÂ`0”x7úNͶ¶ÆÞÞþŽÇÎÌÌÄÆÆ¦Lb_™ÚÎήLbÛÙÙYn¶ÝÉØéééØÛÛ—IìK—.áèèˆÑh¼c±mlløì³ÏÊ$ö/^ÄÙÙ›2‰íââRê9An%vZZ®®®e;55•*Uª”ªGÙl&55õ–bW­Zõº-ˆ×‹––†»»{©sæîî^ªØ&“‰‹/ÞRìÒæ¬¨¨ˆôôtªV­zÝí>þøãË“jšo <<Üû¬Lb‡††š,XP&±;f^¸pa™Ä>xð yÑ¢EeûÿûŸyùòåe{çÎæ•+W–Iì­[·š×¬YS&±7nÜhþõ×_Ë$ö¯¿þjÞ¸qc™Ä^½zµù÷ß/“Ø+W®4ïܹ³Lb/[¶Ì¼wïÞ2‰½hÑ"óÁƒË$öÂ… ÍÇŽ+“ØóçÏ7‡††–IìÏ>ûÌ|êÔ©2‰ýñÇ›£££Ë$vpp°9>>¾LbϘ1ܘ˜X&±ßyçsJJJ™Äž2eŠ9==½Tï-,,4?¾Ô±'MšdÎÉÉ)Õ{sssÍ'N,uì &˜ JõÞŒŒ ó›o¾Y&ç+55ÕüöÛoßôö×-å¿úê+Nœ8Add$)))¼òÊ+ØÛÛÊ<`iÙø÷¿ÿͻヒÁ` W¯^¥¾+#"""""•Üõª“´´4srr²åÉd²T–®ˆ/]ºtÓUò­¶€dff–ú½………¥®jË:ö­T¦………ÅZ­îäq”Yì[m¹•Øùùù7l ,¯±oåZ+ËãÎËË3ççç—Iì[m¹Õã.í³[››{K±oåZ»ÕØ·zÜ………eûV[@n%vNNN™wNN޹¨¨¨L®µììì[Š}+Ç]–±oµäVbgeeY¾wV¤Ø·Ú’••Uê÷šL¦[zÿ­äÌd2™³³³oO H•*UJ\omm}Uÿ²ÒŽk(Òök¿òÙKÛ—±¬cߊ²ÍäÉ“™8q"'Ož ""‚I“&1iÒ¤Û6¡ÝÔ©S‰ÿÛΙÙl¾îïæ+ øç?ÿIFF†eÝÖ­[ âwÞ!==¸|˜M›6ѽ{wÂÃà £sçÎdeeñÕW_1bĪV­zÉLD¤r2dG-¶.::šnݺY–SSS¹té’å.R÷îÝ18p€¤¤$zôè û÷ï'99€ž={’œœŒ qqqœ;wŽ^½z]s‚§„„:tè`Y>{ö,ùùù„……accC=ˆgáÂ…X[[ÓºukË”mÛ¶‘]»v%&&Ž=JNN]ºt!** €°°0éܹ3›7o&??''':uê\¾STìómذ¢¢"\]]éСáááÌ™3‡6mÚиqcÚµk\žÑ×××ò>“ÉÄúõë¨V­­[·¶Ó©S§¸çž{¸öx.9 IDATésväÈfΜɳÏ>KÍš5iÞ¼9999üþûïÀå~ã~~~äæærâÄ bcc©]»6¾¾¾Ô¨QƒiÓ¦ñÉ'ŸXö—žžÎ®]»¸÷Þ{ñññ)1nZZÿûßÿðöö¦qãÆ¤¦¦âååEíÚµ-Ûíܹ³Ø—ç|ÔÔT8@£FhРA‰1–-[†Éd¢  À²náÂ…¼ñÆ ¦L™Â{ï½Ç×_Í”)S€Ë÷ÞLáúÇëûJ!ãïïO58sæ mÚ´±ŒW3™Lœ>}šØØX hÕªÕ«WçÔ©Sœ>}¸|³ïZwQÃÂÂ,×[»ví°··góæÍ,\¸#Fо}û'äÍÌÌdáÂ…xxxp¥‡vDD“––ÆìÙ³éß¿?±±±“ššÊÇ\bqQTTT,—¹¹¹¤¤¤+„®\"•É»ï¾Ë£>Êž={,ÿßáòžþûßÿòÝwßý¥Ÿ•Ímk±···ôkûóLŠçÏŸçüùóÔ¯_ŸÞ½{c4-OfÊÌÌdñâÅôïß_ÄDkkk¾üòKËòñãÇ™>žP¥JrrrhÚ´)uêÔ¡jÕª 4ˆ¬¬,bbbˆŠŠâÙgŸÅËË‹3gΰnÝ:ÒÓÓyöÙg¹çž{gÛ¶m%~¶ììlÖ¯_OAA.\ W¯^tëÖÆÓ¡CêÕ«gÙ¶{÷î¬[·Î²|úôi^xá¶lÙBrr2¶¶¶–uëׯ'%%å¦Ï¯¯/uëÖµœ+7ž®Äû¬å Ú “Ñ£G³qãFËÝå?ú+]n$''Ç2bâĉÜwß}×üRçããúuëX·nÝMíø³÷Þ{7ß|GGGÞ}÷Ý«^¿ÒÒr;º²¼õÖ[Œ5ê¦#BÕªU™5k–ågöSO=@rr2ûöí»ªEáÏjÕªuS?ï-ÛÍœ9“¤¤$<==¯ÚîôéÓlܸ‘Q£FYÖ5mÚôª_|ñ/^´,Oœ8±Ä–///Î;‡¥ußÓÓ“ÄÄD¬¬¬ððð°lÎÆ=zô5ÃÇÇÇÒ½.((ÈÒuîfôìÙÓÒõëZ.\¸@tt4ÁÁÁ?~œ·ÞzëªmÖ­[WìÿÎõ\9V¸<ö§M›6ÔªU‹-[¶°gÏž¿t K—.¥Y³f*>¤Â¹÷Þ{™6mÚUëÛµkg)>þ¨aÆ4lØàº?î6e2ˆˆÈ‹-"66–Í›7Ó¦Mìííùæ›oˆgÓ¦M´oß+++œ-_6333y衇غu+K—.eÆ tîܙƳ~ýz–-[FýúõñòòÂÇLJÌÌÌkŽ+ø£>úˆ””~ÿýwzôèAnn.5jÔ°L´š——G£FðööfãÆ¬]»–¡C‡ÒªU+æÏŸÏO?ýÄž={,7bþwÏž=Ô®]› ÉK/½D‡xÿý÷ùå—_ˆ‰‰a̘1 &OžLNN'Nœ }ûötêÔ‰)S¦°nÝ::w—µjÕ¢eË–|úé§DFFÒ·o_ AAAIëÖ­éܹ3¯¾úªe ÉO}:]ºt¹îSZºvíÊ„ (**âÀßߟ)S¦°aà À½÷Þ‹““©©©,\¸:uêеkW™>}:YYY–ÏФI¦M›Æ† ÈÎΦiӦ׌;}út6lØ@Ë–-iÑ¢‘‘‘|þùç$%%a6›iذ! , &&†7²aé]»6ï¿ÿ>6lÀÆÆoooèØ±£å••Ó¦MãàÁƒÄÄİyóf|ðAÚ´iÃ_|ÁÞ½{yõÕW1 ´mÛ–Ï?ÿœÃ‡3nÜ8Ëcç™;wîuÇœ9sذaO>ù$^^^lݺ•-[¶B:u¨^½:9994nÜØr-ùûû“••żyóذaÞÞÞ%ž#'''’’’X°`………øûûÓ¬Y3¬¬¬°²²â³Ï>㡇*q¬å… xóÍ7ÉÊÊbûöíÄÆÆÒ©S'|}}™g%•˜˜È7ß|Ä ”  ""e+>>r?ƒuddä]ß?¹´RSS1 T©REÉQ""""""eÍ ˆˆˆˆˆˆ Qr-Û·oç矾áv[¶l)6a”ˆˆˆˆˆ¨ùKÖ­[GZZ...,\¸k +Y½z5999ØÙÙ±hÑ"e_DDDDDÈ_·iÓ&úõëG`` ”¸ÝöíÛéÓ§ݺuãðáÃÅ^KJJ"66öª?ך9WDDDDD*›òòAöìÙc™žþйsç2nܸRÍ,"""""*@®é‘G¹jÝo¿ý¦3$""""¢¤¸þóŸÌ›7Ú¶m‹ÑhàÈ‘# >ÜÒÝêÑGeÁ‚Fºuë¦ì‹ˆˆˆˆÜ‚ÄÄDŠŠŠðòò`ÅŠäççÓµkWÜÝÝY±b?ü0...¥Š±jÕ*rsséܹ3µjÕ²¬_»v-—.]¢mÛ¶x{{ßôþnË6mÚÐ¥KüüüèׯVVV4lØo¾ùƲ]ÇŽ騱#-[¶ä¡‡Ò#""""RJ`ôèÑ–›ý ,`ïÞ½˜Íf‚‚‚˜1c±±±¤¤¤0uêÔRÅøúë¯Ù¹s'ƒ—_~Ù²~Íš5üôÓO¸ººòüóÏÿ¥}Þ¶.X5ºj““÷ß±uMš4ÑÕ"""""r‹ZµjÅ /¼@NNçÏŸçõ×_ÇÍÍC‡qéÒ%‚ƒƒ *UŒ„„&NœHõêÕÙ¿¿e}rr2ÿùÏhÖ¬[·nýKûÔD„"""""rǨ‘;ÆF)©x"##Y¿~=4lØ???†Š™™™øûû3dÈœœœ¨[·n©bøúúòÌ3ÏмysÒÒÒØ³g4lØ   ºtéBDDÄ_Ú§•ùZÓ–—½{÷æ±ÇÓ< """""’––F\\µkׯÝÝ'NPTT„··7œ8q€ÆcggWª8¡¡¡R¯^=222°±±ÁÓÓ“ˆˆrss-±o–Z@DDDDD* ªU«RµjÕbëš5kVlùÏ„* Ë¿]]]-ÿ.é!T*@DDDDD*±¬¬,ŠŠŠ°··ÇÖÖ–ŒŒ Ìf3ŽŽŽX[[“‘‘€³³3f³™¬¬¬« ‰¿ÀÎÎ;;;2331™L888Xæ¼"''kkklmmU€ˆˆˆˆˆTGå…^ eË–œ;wޱcÇ2qâD4h€§§'­ZµbÁ‚8::Ò³gO233Ù¿?‰‰‰Lœ8‘>}úÜt¬§Ÿ~???òóó±¶¶¦ÿþŒ5 RRRX¶l™eÛóçÏ3þ|ºwïN‡Ê²iÓ&Ö­[@XX˜®,‘;vŒY³fÀþó¶mÛÆO?ý„»»;AAAìÛ·uëÖaeeÅ„ 0›Í,[¶ “ÉĤI“þR²téRììì˜4i“'OfñâÅÌ™3‡æÍ›óŸÿüDz]ll,¿üò “&MºªU¤Ü Ý»w§{÷îÀå/"""""rµZµjñÁððÃưaÃxíµ×ðõõ%==wwwK(ƒáòì×* nÄÎÎŽèèhjÖ¬‰µk×fÆŒôêÕ‹Ó§O[¶[¾|9û÷ïgÆ |øá‡x{{_µ/Í"""""RuíÚ•ñãÇ“œœÌÈ‘#yòÉ'ù׿þErr2Ï=÷Ü-│¨ˆ   –,YÀªU«0`>ø ¯¼ò )))Åb?~œyóæ1~üx~øá‡÷«1 """""P^^666T¯^’Maa!íÚµ£]»v¬X±‚eË–áääDFF¹¹¹lذóçÏcooÃý[[[ ÀÉ“'quu¥V­Z–ØÖÖÖxyyñ裒Éd"--ˆˆË|!*@DDDDD*‰ˆˆÂÃÃ:t(‡"77—¾}ûðî»ïòá‡0cÆ òóóùꫯ˜6mÚ_ŠåèèH`` e9,,ŒÈÈHžzê)8@vv6~ø!ßÿ=NNNŒ;¶Ä}i"B¹c4DDDDDDîuÁ©€RRRذaõêÕ£]»vœ;wŽñãÇãàà@Ÿ>}ð÷÷ç»ï¾c„ ØÙÙ±yóf¾ûî;rrr˜9s&»víbûöíäåå1sæL<==¯ëå—_Æ`0`2™ðõõå‘GaâĉFüüü9r$/^ä7ÞÀÊÊŠÚµk3~üx¬¬¬ŠíK- """""Pzz:'Nœ 55€/¾ø‚gŸ}–iÓ¦±bÅ 9|ø°eóÅ‹3uêT&NœÈÇÌêÕ«yçw8p åIW×2tèP‚ƒƒñóó# €5kÖйsgÞ{ï=~ûí7Ëv;wî¤~ýú¼ÿþûìÚµ‹Â«ö¥DDDDD¤ª_¿>]»v-¶Îßߟš5kR£F Ú´iC³fÍ,¯U­Z•zõêѼys uêÔ¡zõêøûûß0–¿¿?III$$$àëë @||<999¤¤¤Û6>>žÂÂBJÜ— ¹JQQ}ôëׯ`ûöítêÔ €áÇceeÅ«¯¾Ê°aÃ,ïéÓ§ 4`üøñôï߿ĉU€ˆˆˆˆˆTG%!!ÄÄÄ«^KKK#66–L&gÏž%99™£G–¸/ƒÁÀÀiÕª.\àôéÓ´oß+++þõ¯ѦMüqË{¬¬¬xê©§hÒ¤ /¾øb‰û-wƒÐãã㉵$)::ZW’ˆˆˆˆÈŸ8p€%K–`2™¨V­Ï<ó ãÇÇÑÑ‘~ýú±lÙ2ÂÃÙùäþýŸÏ·ß~ @PPƒ­[·Ò¥K—›ŠµråJΜ9C»víxàˆŠŠÂÊÊŠzõêÛnÙ²e¤¤¤0jÔ¨÷£Aè"""""Ð7n'OžàÃ?¤°°Ö­[Äo¼AÍš5¹ï¾û˜8q"¯¾ú*Íš5ÃÝÝ)S¦ðî»ïZ ”Ù¹s'?ýô?þ8¯¾ú*7ndܸqDDDÛnãÆ8;;“™™Éœ9sT€ˆˆˆˆˆT­Zµâ…^°,gffˆ¯¯/nnnäççÓ±cGÚ´iƒÁ` Zµj<ôÐCŒ1‚ììl&OžLýúõo*V~~>ÔªU‹&MšÀsÏ=wÕvÎÎÎ|õÕWøúúâîî^â¾ÔKDDDD¤MVVNNN%66ôìÙ“%K–пÿ·Q ˆˆˆˆˆH%ШQ#V¯^M`` =öíÛ·gÕªUtëÖ.]º`2™(**¢  à¦ 7rüøqî¹ç-ZÄ<@PPP‰ $&&Ò¨Q#>üðCNŸ>]r‘¢S%""""Rñ„„„°xñb ðòò"33“­[·òüóÏãááÁ/¿ü˜}HIIÁÖÖ–%K–˜˜Èþýû-Hll,S¦L¡K—.œ?“ÉTþ ¶mÛâïïÀîÝ»-M<"""""òî¿ÿ~&MšÄðáÃIHHøÛbyyyñì³Ïů¿þJPPŽŽŽŒ?žgŸ}ö/í«Ü±µµÅÅÅllÔCLDDDDäZÖ¬Yÿþõ/:vìxÛ÷]TTDPPK–,¡I“&,]º”êÕ«3jÔ(ùé§Ÿ1b„¥õãf龈ˆˆˆH´qãF¢££iÚ´)k×®ÅÓÓ“3fмysΟ?O\\‰‰‰„„„мys²²²øê«¯8þ<žžžœ>žN:1lØ0"##Y°`A‰=š4¡ˆˆˆˆˆÜ1j‘;Fc@DDDDD* ¸¸8^zé%L&}ôyyy¼üòËT«V:àëëË{g­­-Ï<ó YYY¬\¹’ôôtf̘Á… X¿~½eœÇõ$%%1vìX<<<ÈËËcܸq|óÍ7?~œ>úˆ{ï½€„„Ëvƒ>úƒÁ DDDDD¤¢ á¹çžÃl6³aÃx÷Ýw©W¯AAAœû £ÑÈ´iÓ(**bΜ9deeñÉ'Ÿ0xð`ÒÓÓo:VûöíyñÅ9r$kÖ¬¡C‡°eˆÀèÙ³'C‡eøðá]U€¨ –ˆˆˆˆHôÐCÑ«W/öíÛ‡££#...lÞ¼™#GŽžžŽ¿ÿþ;»wïÆl6ãì쌇‡õë×ÇÊÊŠÖ­[ãêêzS±ìììØ»w/qqqœ}šeË–ñòË/ãääDVVü1/½ô;vì 33~þùgÆŒƒ££cÅ(@6mÚĺuëXµjÎÎÎüúë¯Ô©SGWYNtt4={ödöìÙŒ;VI¹K•»§`uïÞîÝ»J=X¸pá «2)¿²²²HNN &&F ¹‹i ˆˆˆˆˆˆ¨¹ÂÎγÙL~~¾Î–ˆˆˆˆˆ ¿—½½=&“Iˆˆˆˆˆˆ ;£^½zDGGël‰ˆˆˆˆ¨ùû >œ… êl‰ˆˆˆˆ¨¹3<==ILLÔ) 1›Í˜L&ŠŠŠ”©|H×®]Ù²e‹Î˜H90kÖ,Ù±ck×®UBDDD¤ò ­ZµâìÙ³œ?^gMDDDD¤² ÙÙÙÄÇÇ[wèÐ!¶nÝZlÝøý÷ßopß¾}ìØ±£T¶S§Nlß¾]gMDDDD¤2 YYY¼ÿþûźXlß¾“'O’••ÅâÅ‹1™Llݺ•S§N‘‘‘ÁÒ¥K1›Í%îoýúõDEE‘’’Š+þò‡mݺ5ááá\¼xQgNDä6ÉÌÌ$33S‰‘²/@-ZDÇŽ‹­[½z5O=õ}ûö%<<œœœ~ùåžxâ ~øaŽ;FAAA‰ûÛ°a?þ8>ú({ö칪عtéR±?%ígôèÑ|ùå—äååéìU ¹¹¹äååa2™”‘rd×®]ìÞ½³ÙÌòåË5ï’ˆˆü­l®ücþüùœ={Öò„ 9r$œ>}úoÿ ?ÿü3ÅÖÅÄÄ\µ»»;/¼ðï½÷o¼ñÖÖÖ:‹åÜÿcï¼Ã¢¸¾ÿÿf—¶)RETDAÁŽÄØÀ^bD1£¢±`FУ‘Ø{ï {A±ì ÅB‘& ô¾°óûƒßΗagV4!Q?çõ<>²sîÌܹwÊ=÷žŽcÇŽ¡aÆHHH@RR,--©aâ#''ßÿ=  ®®N BAÔ®2zôhN8M--­µ"ßÿ½Â¶ê«$UëöÛo¿aõêÕ˜6mêÔ©C=ù {{{\¹r={ö¤!‚ ‚ H$ ÂÛ·o#::¸páúôéƒ!C†àÏ?ÿD:u`kk ‰D‚o¿ý‡‚’ @S IDAT¶¶6Ú´i555và9mÚ4Öq¼_¿~8räÔÕÕѹsç¿UquuuL™26l@Ó¦Máìì sssêQ‚ âžèèhØØØ ((¦¦¦hÓ¦ 5 AŸ J}@455Ñ´iS :‰***èÒ¥ ìíía``€#F@$¡{÷îhÙ²%ŒŒŒàææ€¥¥%V¬XÁ¯wïÞ°¶¶†™™†ú·+¯¯¯oooØÚÚÂßßOž<ᘑQ{¤¦¦rþ'âÓaÿþýÉdÈÏÏGqq15AŸªÊ„¼ÛùfRÚ¶m«°­N: +:tøÇ/¢]»v°µµÅÉ“'‘™™ ]]]¸¸¸ N:ÐÐР^&ˆù fïÞ½°¶¶Æ½{÷0yòdj‚ ˆZäðáÃøá‡PPPjâ³Fô¥\ˆD"ÁèÑ£áé鉮]»ÂÇÇË–-Cpp0õ2Aüà HII $ ’““aaaABQË„……¼½½©1ˆÏÕ/ñ¢lllð믿¢¼¼gÏž…——ttt`llŒ¢qãÆÔóAÿŸ+W®TTTpþüy,Z´«W¯¦†!ˆO„˜˜dffRC|DFFÂÂÂzzz¤€|1§ª WWW¸ºº¢  ™™™¸pá`aaKKK˜˜˜üm‡x‚ ˆÏynžÀÀ@¬[·×®]£FùB6YYYÔ_<@rr25ÄIJeË0þ|ܾ}½{÷&äKEGG:::˜>}: )) ‰‰‰HOO‡——ÀÎÎ-[¶Pê×ÎÎŽž‚ â³âÝ»wÐ××ÇÁƒÙ 0Æ £†ùÌÑ××GNNd2RRRP¿~}j”Ϙª“¯_¿FÓ¦MIù_À‚µ]—G䊌ŒDdd$ ¸¸û÷ïgË?úúú*ëÉŒ ‚ø‘J¥PSSc•âË K—.8qâôõõ±sçN,Y²„å3FÐ¥¼¼[·nE=Hù_ÅÎÎNpÕÃÇÇ999€¼¼<rf%,X@ HAÄ?NJJ 5j„””èêê";;›å3&-- ‰›7oFVVÖÿ¤o2) 5düøñœß ðçää°f\rêÖ­«ÜqÈ!hÔ¨5&AA5&##;v¤\g_oß¾…‘‘›£§AƒHNNFƒ Hù¯xöìk•––†@WW÷“oHGGGÎïwïÞ)$=z4^½zÅÙfff†Ù³gÑ7YLL @,#-- 066¦7ÐgŠL&CLL ***Ømǧ†ùžQy_ÆÄÄPŸ~Æäää <<œ3KNýùù?£:::HHHRŸ~Ƽ~ýááá(++CAAÄb1öîÝ‹-Z|ñ×Þ©S'XXX@…©:•ÿ ’’ÂFzøí·ßPZZZ£ýÊÊÊ™™Yc§¬äädÔ«Wªª5ÓÁj¼D–——‡òòrþãÇf‰‰‰5^IIOOG:uVcþ‰º#//¦¦¦5*ÿêÕ+XZZÖØ.ùCê’••±X\ã(rìòòr¤¥¥Õ8ßEjj*ŒŒŒ ®®^ãÁÖÇ蟬»L&Crr26lX£òiii000€¦¦æ?^—ÂÂBÂÄÄä?ö‡–÷îÔÕÕk<¹ñ!Ç–J¥ÈÈÈø w‘©©)ÔÔÔjå]$•JQ·nÝÿ¼Í?´|AAJJJ`ddôŸ×%33‰¤Æ¾rìÒÒR¼{÷æææ5¸Ô¯_b±ø¯KNN†A­¼‹’’’`iiY£òoÞ¼¾¾~­¼‹ŠŠŠPPPPkï¢ôôtèêêBKK«V¾»¹¹¹¨W¯^Ê'&&¢aƵòÝÍÎΆH$ª•ïnEERSS?è»[·nÝ'ŸþÐwQqqq'Nkó]ôöí[hjjÖÊ»¨¬¬ oß¾­ñ»èc¾»jjjذazöì 0Ÿ0žžž5.›’’¬]»¶Æå—.]ʼ{÷®VêrãÆ æìÙ³µr슊 föìÙ5.¿gÏæÙ³gµR—èèhf×®]5.ÿË/¿0R©´VêrîÜ9æÚµkµrìììlfñâÅ5.¿nÝ:&))©Æåÿúë/&00°Vê^XXÈÌŸ?¿Æå·nÝÊÄÅÅÕJ]ž}ú“hó-ÿþ}æèÑ£ŸD]:Ä„……Õʱ™7Ö¸¼··7“——W+u¹rå sáÂ…Z9vII 3oÞ¼—ß±cóâÅ‹Z©KDD³oß¾Z»·|||˜ÈÈÈZ9þ‹/˜;vÔ¸ü¯¿þÊ”––ÖJ].\¸À\¹r¥VŽ››ËüñÇ5.¿qãF&11±VêòðáCÆÏÏï“x9r„ ­•c'%%1ëׯ¯µºŸ>}š¹}û6ûû‹ñQQQHTóÄîR@g›äuùè#rì-/‰j­.Úæʇ^ç‡Ô¥6Û\,P›h¤ší£mÇOåý\Ÿ‹mÇÚ¼ÎOé¥÷ès¿Ð3úï_gmŽ/>µgôSiÇÏù~ùÐ6ù”ÆtçøŸœ VU¼¼¼°nÝ:_sçÎŲeËjlöF|úÐ3JýIPŸÿ±±±¸zõ*&OžLAÏègˆºž ‚ ‚ ˆ‹Oz„2}~Y¤¦¦ÂÌÌŒ’c}AÐ3JýIPŸÿ¥¥¥ÈÏϯqp‚žÑOñüñÇ]‰lذ¥¥¥hÞ¼9»½N:œr·nÝÂæÍ›Á0Ìÿ\Êú/]]]R>¾0ª?£õ'A}JÔªªª5Ž®Eü{aûöí C×®]—.]ÂÎ;!‘HØèoçÏŸÇ®]» ££ÃF§¼~ý:öìÙ===6ÈéÓ§±wï^ *' ÃàĉØ·oêÕ«WãÈhŸ ÿù Hhh(àææ†›7o"77ß~û­B¹Û·oãíÛ·2d._¾ŒŠŠ ôë×îz‚ þ6EEEH$ÿ¹‚\ZZŠŠŠŠZ`”••Õ844PS*•Ö8 *Q»Èd2Èd2Ž]II d2ç~)))Ã0œÐë5Ý&Ï]õ¾mAü|cÒÀÀ@ˆÅbôîÝgΜ±±1rss!‘HУGœ|Í›7GûöíÎ{ìØ14jÔŽŽŽØ¿?`gg÷Ù´Ûî kkk€ƒƒÌ{Ž]»v¡iÓ¦ppp€±±1BCCáïï7nÀÁÁb±ظq#Z·n Èd2bíÚµìuI$DDDÀÒÒhÛ¶-lllXådðàÁ°µµEVVîÞ½‹cÇŽ±uÿ}êÔ)888àÏ?ÿDRRÂÂÂ8eŠŠŠÛjË–-l]Þ½{‡´´4H¥RŒ? CBB´´´Ør÷îÝCRRlmmQ¯^=888°¶ß;vì`Ë]¹ro߾ņ àååÅþ+**BÏž=”Èòòr¨ªªBEErKjù6‘HÄ»M&“¨4¯‹Å¼ÛÄb1***·¡È°aÃ```”––¢qãÆHHH$''£Aƒ°²²B\\€JÇssss4mÚ”ÄJKKƒ™™š5k†/^ÒÓÓajjÊžGîªüߊ dffÖ8Sû§Â¾Ò£G\¸p^^^°³³cgî`÷îÝèÓ§†ŠàÌ™3ðòòB»víØY:‚ ˆ¿; RÝyoðàÁ¬-íþýû¡¡¡[[[˜˜˜°ÛKJJÀ.«ªªB"‘@UU#FŒ¨©©!;;®®®œãA__Ÿ³‚‚œ>}šˆ)++ƒ®®.¬¬¬PVVÆîŸ——‡'NÀÜÜP¯^=äææ¢qãÆ°³³C³fÍM°:vìˆÝ»w£  êêêðôôd?nÕWF…F!%%…5ݹ{÷.tttP\\Œ.]ºðž£W¯^سg¤R)ôõõ1}útÀرc¡­­òòrDDD ==€X,Fnn.\]]ñæÍ´lÙRÁ?ÇÔÔÍ›7g?Î&&&hÕªÚµkKKK¹7ªªªÂÎÎŽ­KU…#00Pé½âääÄö•µµ5 ```'''ØÙÙA__xöìüüüOž<ÁàÁƒaee###Žvxx8òòò ˜8q"ÌYéÐÐÐ@½zõM+A|¢ÊÇ–-[PZZ ‰D4lØ~~~8zô(ºví €¯¯/:'''Î ïгgOôèѰwï^øøø OŸ>èÖ­{®?þø[¶lžž<<<°{÷nìܹdW{Iùˆ*lß¹s'ç÷!C0dÈºÛ ‚øÇ(..Fqq1òòò`bb"XN>ÎÉÉÁõë×Ѽys 6 Æ Àm¨yóæ ¿¿?z÷îÍ(UUUQVV†œœv¢´´999ÐÓÓÃýû÷ammqãÆáƸzõ*€Êì³rs¯[·nAMM &L`õõõqúôi#''‡5óá#%%£F‚±±1òòòpàÀÌ™3yyy(--Enn.ôôôx÷ÕÐÐÀ¬Y³P¯^=ˆD"ÁˆKñññøù矡©©‰/^°õ9qâ\\\PTTuuuhjjÂÓÓjjj‹ÅÐÕÕÅÝ»w‘““$%%ìíí¡©©‰üü|¼y󪪪hܸ1{¾ºuë455Ù6‰D(//gËð9UO˜0«W¯†¡¡!ïudffâ÷ßœÈé‚ ‚ ‚ R@‚ ‚ ‚ „ ‚ ‚ ‚‚ ‚ ‚ H!‚ ‚ ‚ „øp‚‚‚póæMAùÞ½{‘À++,,ÄÊ•+!“Éxå[·nÅ¡C‡xeYYYX¹r%nß¾Í+üø1NžÌ™3/^TB*•býúõ(++S÷ë×#GŽÄÝ»wd=‚‰‰ &L˜ÀÛ‘‘‘øî»ï••Å+¿zõ*^¾|I7AA) _.ùùùHOOç•1 ƒ… âÞ½{¼ò³gÏbþüùX½zµ‚,77xþü9ï`}ùòå˜>}:NŸ>¤¤$Ž,##©©©˜:u*Ž?®°ï²eËàããUUU…•Šèèhüõ×_ Âþýû‘––Æ‘_ºt Í›7ÇÆ¥plØÚÚ"<<EEEÙöíÛáää„5kÖ`åÊ• û®Zµ 'NÄåË— ©TŠ>}úÀÒÒ3gÎTØ7++ K—.ÅĉñêÕ+y\\:tè ¸*”››‹ÌÌLº¡ ‚ ‚ Hùï‰åÍ€_~ùÇç•OOOGTT<<<Ë‘åååaÏž=˜>}:–.]ª°ï®]»0pà@Ìœ9;vìPçååaРAhÑ¢N:Å‘íÝ»“'OÆ?ü€°°0S«ÔÔT˜››c„ ÈÈÈàÈ¡ªª sssˆD"Îu3 Œ?æææØ¹s'gß§OŸâÍ›76lÆŒŽ<-- †††°··Gvv6¯Ñ¥K 6Láš322PZZŠ1cÆ@&“¡  €#¿xñ"TTTФIüùçŸYEEV­Z…üü|¬^½ÅÅÅ çþùçŸ1räHÞzÉd2ÄÄÄàÍ›7ô0AA ñ÷Ù¾};¯©`òäÉØ·o***ÜOž<Á7ß|ƒp|&†Á’%K`kk ggg…Áø™3g```777888 €3àˆˆ€ºº:ºwïCCCι¯]»´mÛ uŽŽŽfÿNNNF^^û»¬¬ ;w†™™lmm±jÕ*ξ«V­Â¯¿þ ˜;w.Nœ8¡pì-Z@,C$A*•²²wïÞ!''‡ýýìÙ3ö"\¼xÆ ƒ³³3ÌÌÌpÿþ}Vþøñchii¡ÿþPWWW¸¦•+WÂÃÃöööˆŽŽÆ7äsçÎŰaÃPVV†a8õÚ³g"""°°0ξ>DLL òóóú ¨\ñôôÄ€ššª øð!/^Œòòrz˜‚ ‚ „î߿ŋ#99YA–˜˜ˆC‡ÁÛÛׯ_çÈJKK±aÃLž<›7oV¿zõ R©£GÆýû÷9ƒÞ¤¤$ìܹK—.E§NͰôõõaeeÅGEEáâÅ‹˜3gZ´h;wîàÎ;¬<22’õ Y¾|¹‚òd``@Ÿ>}êfff000¨QÛ…„„ðnÿúë¯agg‡]»v±Û‚‚‚°bÅ @·nÝ ©©ÉiËG¡S§N¬RPuU(!!5e[±bBBBx}_ÞG§N°téRó¯ž={B,£wïÞ ûÄÇÇ£_¿~8rä~ûí7¹··7¼¼¼ðêÕ+Þ•®Q£FáîÝ»øñÇyëtùòeA— ‚ ‚Ϭ¬,øøøàéÓ§¼òM›6áÙ³g˜3gŽ‚ìøñãhܸ1&OžŒuëÖ¡´´”3h¾~ý:úõ뇥K—"44”³ohh(–-[‰D{{{¹œ&MšÀÈȈ³mÁ‚X¶l cÇŽ|ÍŽŽŽìßýõûwpp0‚ƒƒÙcöíÛóçÏç=F‹-àêêŠ'OžÔX‘›>}:êÕ«Ç+¯Z'''œ8qÏŸ?ç-ËwÍU·³+7ùùùxùò%¼½½@¡/:sssôìÙ“÷\ ,@¯^½ ‹Ñ¯_?…ö˜?>úöíË»o\\þüóOôèÑË–-SØ÷À6äXN IDAThÒ¤ –-[ƹ~9iiiX²d –-[†””Þãûøøàõë×ô AA ȧDJJ ñöí[ÙåË—±wï^œ8qááá òlÙ² 3ÑÇŽƒ››ÜÜÜpáÂŽoALL ¦N mmmH$;vLa_‰D===ôë×#_³f ~ùåVYxûö-®]»ÆÊ‹‹‹Ù777lß¾snÞ¿`õêÕ>|8o;UTTpÌ¢ ¤¤„ó[~<±X ©TŠ .nܸ‚‚|óÍ7*göÅb1kVuüøqhhh@$ªÙ­(•JYÓ±çÏŸÃÚÚb±˜½æ5kÖpÚËÍÍýݼysöoyÛÉÛ«z_”••A$AUUººº˜o´+˜4i{ÞœœØØØpVfª÷ƒ»»;Çg¥j«÷»‡‡vïÞ]ãûGÞÖb±ÆÆÆì} WäÊMçÎѤIäææN:…-Z yóæPSSƒÇ1¿j_ôíÛFFFEQ.—·qÕ¨c111¸|ù2\]]1tèPdeeqLÃ233Y%W]]çÏŸç\Sbb"\]]áçç‡7*\ó»wïÉJ™ ‚ â‹W@ ÍùWÝ)777—£TeýúõX¶l¬PæüùóÐÒÒÂO?ýUUUŽ™Txx8 ðõ×_cÆŒ¸sç'œê‹/Øþœ9s83ç/^„––œ¡¡¡3fpä***ìÀ²k×®¨_¿>÷èÑ£(--e})†޲²2Áä}U•óçÏ£GhÖ¬oÙ˜˜…m/^¼à-«©© ¬[·Ž­×ìÙ³Yù Aƒ “ÉŽŠŠ …Áª––VúW&“¡´´”³JѬY3v# S³ªe?y;sŽecc{{{ö>8vì¯yPé4„ÆLLLœœŒÀÀ@v_uU£z{Tmwsss„‡‡sÂ"W•Wß7//½—---qóæMDDD°òýû÷C]]–––066VðQòññ““<==ñâÅ …Uýû÷còäÉpwwç8ôW& ‚ ‚ ¾H$ Û¶mãü«> 9r$úõëÇ„ÀëׯáïïOOO¸ººâôéÓùÓ§O1iÒ$´lÙœ,ÜÉÉÉ())AÓ¦MÙgUß;wîpÂÜ ùiT—Ëg§çÎËʲ³³Ýuèлwïf¯Y__Ÿu¸*ý.]ºÄ*MU•( ôèÑ£ÆmýÕW_A__ŸWöàÁ…m©©©¼ø°dÉÎïþýûó–KMMÅŽ;XçöšÐ±cGv ÿ>Z´h† òÊ,XÀñ133Cii)8P£>ý–,Y‚Û·o£°°P·n]A«W¯¢U«V¬ÒµdɱŠÂ¥K—Ú·ªB÷×_±í½dÉöþ“˜˜ˆ)S¦ mÛ¶8|ø°B(ç À××b±XÁô ¨ - Û·oÇäÉ“¡¢¢ÂÊÊËËÙA-_D­ªç®_¿>GfllŒíÛ·¨´Ï766æÈ§N*hꤣ£===Èd2¤¦¦bÊ”)¼åÂÂÂðìÙ3Ô©S‡³½´´T0/ƸqãpìØ1¼|ùVVVèÒ¥ GÞ A¶ kŪz{Ê#ÇÔÔ}úôÁž={°}ûvŒ7Žwÿ²²2Aß! pïÞ=Aßy]Þ¼ygggAó-¾~222¾}ûxË«¨¨(ô{uªÞ7UÛDOOÆ ÃöíÛ‘““ƒ šÖ%''cĈ¬‘¹¹9zôèÁ&Bܾ};¦NÊÛ¹¹¹ðóócå666hÓ¦ ë¿”·oßB__"‘cÇŽå$X,++Õ+Wàáá&Mšpz ÒwåÔ©SXºt)ÆŒ£ Ü•+( ôÖ&‚ ˆOœ´´4 †aPRR‚Fq| FŽ ???Ppš®_¿>qæÌÃÎÎŽ3óÞ»woèé顬¬ qqq°²²â( U#Y)ÃÏÏžžž Û•E²²²Â† xÏÓ®];ØÚÚââŋضm›ÂL¹¶¶6§žÊàSÆ’’’pîÜ9¤¤¤(ä™5kÛž 7•HmmíµÇ¬Y³¶3 ƒøøxÞvéÞ½»‚Òò¡H¥RÔ©SG! üšöìÙóQ …PUUÅO?ý???†Ç-**™3gxÛ$..7nÜÀË—/abbÂnwttDÆ Ù—œ¬ïì ^~ïÊéÑ£êÖ­‹²²2H¥R¼~ýš•ëêêB__III*M¹D"›eàÀÐÐÐ`Ã3ûùùaüøñÐÓÓƒ££#,--9™åѦM 8ÎÎΟ+8rä,X€Ó§OãñãǼ퓓“£ ’ ‚ ˆÚAè»Ë0 6n܈°°0üðà ~Ø»ví‚——ºté‚ôôtÞ ã/* ï£GT:¯¿~ýš3ƒÝ®];Nfðªèéé¡aÆÇ¡C‡PTTÄ wÛ¬Y3ܽ{W0ƒ÷¢E‹Ø¼mÚ´Q˜í8p §~Ãùóç±hÑ"…í‚3ú³gÏ~ï*O~~>nÞ¼‰?þøã£Û»:úúúøù矶¶¶ >2ïÛ_VVVHOO¼æªÈsTçþýû¸uë'/HMê$t¼êtíڕןæÑ£GðööæøÈï¯fÍš¡¬¬Lá!~–––ˆW·[š6mŠàöíÛ¼o‹-péÒ%6GNõvËËËãÌŠx{{³þ:}ûöå$øÌÏÏÇÆáéé‰o¾ùÓ¦MSh‡-[¶`Ñ¢EóF‚ ‚ j‡W¯^¡cÇŽó}9EEE ƒ»»;zôèÁIWqÿþ}0 ƒÎ;ÃÈÈÓ§Oçc~– Hff&V­ZÅI:§­­­0°Òæ^¾|‰Å‹ÿ£uºvíÖ­[CCC…¬Þ=zô éjdd[[[•~BŽàׯ_ÿ¨zíÛ·ÏŸ?G×®]dkÖ¬Aaaá?ñ©ºb@Á”©iÓ¦¬üÇ€W¯^ñ^ÓêÕ« ///8;;ÿ£×ãììŒ9sæÀØØ˜Wy€_~ùdÞרQ#³¸ªóõ×_×ÈÄM$¡sçÎ }üàÁ<~üZZZŸªÜ¾}K—.åäTY½z5æÎ ™L†9sæpž·ªäææ*}ŠÍ›7#--MA6bÄ,_¾§OŸFß¾}9 ˜ûí7xzzBCCÎÎΜ1ê“'O8ßâÎ;#""yyyHOOgý@?Û™LÆ”éééÁÙÙ™ ÛªU+NyÔ«W¸sçŽÂ€®zy>²³³QZZ Á:)«/æææ°¶¶fMƪ›:5mÚ´Æy5„λdÉ 2„wÀZ5œpUTTT"ÊÉÏÏGzz:¯É^Gp 2Z•žžž oKM‡‹‹‹Âv±XŒsçÎ)dnÿ~VFJJ 444B·nݽzõâdKÿ†¼G „ÄÄD Ö?%%¾¾¾øöÛoú8((ׯ_G:uXeW޼ýýýž ±XÌÖ©úóóçÏGxx8233ž)±XÌúd#33“chooÏ®‚ÈsõÈå ,àÜ—@‡`oo… bË–-œ\$<@BBLMM1~üxNÒG‚ ‚ ‰ŒŒÄäÉ“¡¯¯ &pÆd‹Å0`ÔÕÕ‘ššÊFÜŒÇñãÇ1`À•“Ц¦¦lð™ððp,X°€3†¹{÷.²²²˜˜ÈZL|q™Ð³³³±eËŒ3†³][[±±±¼9-°NµEEEøé§ŸäÓ§OG\\îÝ»§àÌ]rss¡¯¯¯.X>¸KLLä¬8ˆŒŒä=®|FÛÝÝwõÄÄÄ„“¯:¼«***pwwÇ–-[gÍUUUqõêUÁü!;vdCW'66)))¼²éÓ§¨Œ fmmÍ[FuìC3f ¶lÙòÞrò:T',,Œ·/444PRR‚€€AES(2–œÄÄDL˜0“`RÎ¥K—°`Á…û~úé'ÄÅÅ}°S¾ü¾ßºu+¯LMM fff*3ØW÷A244ÄÁƒ‘˜˜¨ðÌH$ÖW…O>fÌ }àç燉'bÔ¨QHMM¥¯Añ?Á¬Y³àîîŽáÇsL×¥R)V¯^aÆÁÝÝîîî1b+_µjf̘---¨ªªbäÈ‘ì¸+..†††œï}“&MØÈ˜dƒáT«^½z•õ%ý,___Œ1Bp@÷êÕ+¥û ˜“’’°ÿ~N®97†¯¯/ï~FFFèß¿?rrr‹'OžÀÔÔTA&‰Ð AA‡ñwïÞ¡oß¾¼Ó3fÀ×× 4€ªªª‚üÛo¿eó>ðѤIA§hy[Θ1Ca»½½ý{^¿~]iŽü‘×T©qãÆð÷÷‡††¯3{ëÖ­•®dèééÁÝÝ]P®¢¢¢Õ ¨LFصkW?~œ ¸*ÊŽ«ìÞ=z4"##¡¥¥ÅÉ]Ru°ïãã ˆÅ⺯5j„Í›7óÊD"«˜ ÕíÅ‹‹Å +JFFF9r$¾ÿþ{´iÓvvv¼ûoÞ¼Yá™iÔ¨z÷î“'OòÊutt ªªŠèèh%òóóáïï5kÖàÍ›7ÙÍ›7…Å‹cáÂ…;v,kj•€sçÎaæÌ™*ƒ-™˜˜°xÒÓÓѬY3öX...xòä ^½z…M›6)Œ g̘͛7#77={öäL*V«†„„°ŠÐg©€<}úööö &!ró¾•ùÀóìÙ³ 6äUåUcùÎ˧$hiiÁÊÊ Ë—/ç=¶ƒƒúõë'x\$%%qìï«“’’Â:³óÕKSSSA“1¹v¬££óÁatMLL‘‘!¨4Õ$ú–&L˜À+{þü9'³{Uºwï®t¶Þ¼yèСƒ øØ-[¶TÈ-R•6mÚð:ÝË‘gâÖ­[‚2WWW¥ÉÏœ9û¿ ž?ޏ¸8Ì;—·}}}áîîή`T%..ßÿ=>Ì»ï_ý…€€縎;">>GÅ«W¯”X'''ܸqVVVx÷îÇ/fÕªUpvvF^^ž={†Õ«W³J‡H$Â÷ß___VÉ?~<*** ‹QZZ*zš ‚ þiÒÒÒ0|øp8::âáÇðððÀ?ü Òœ©¼¼³fÍ‚¶¶6NŸ> ܽ{ûöíCÆ 9éZ·n9sæÀÉÉ YYYøå—_8çZ»v-¦M›™L†‚‚…º¬]»ÞÞÞˆU˜Ø622BÓ¦MqïÞ=N¸9íڵñcÇРA >¼ò›û9vˆ••Z´h!(oÕª• ßBÛ¶my·ëêê‚atèÐ×Ç£~ýúèÓ§ÏGç ÐÕÕE÷îÝye3fÌ@ÿþý9Y½«w,_‚ÃªŠ“2nß¾Í;xmÕªF•A  2Ôª2˜{÷î¡S§N¼²Aƒ úKÈ•6e+B ¼á}ŒŒ››+è„Þ°aC´nÝZð¸ZZZ‚Ë€Ê|½zõTÈ„2Þ•fIÕí"«·‰ 6ĉ'x•6cccÁv~ß}ߣGDGGóš…ÉŸÀÀ@Lœ8QðØFFFøúë¯y¯'((Hp%kÔ¨Qpuul‹óçÏ šz{{ æ ‘ß[—.]‚‡‡‡B`‡‚‚\¿~‹-â<;mÛ¶Åo¿ý†áÇ£¢¢'ND³fͰwï^ìÞ½íÛ·Ç?þÈÞ[9998zô(ûïŸÌCAüoðòåKö;R5¡vRRƇßÿk×®ÅùóçqòäI8p¯_¿Æˆ#ÄšªÃÞÞk×®ÅãDZpáBÎy:uꄌŒ ܺuK0å@RRž},ÔÈÅÅEpBR>),41ݪU+ÖøLM°„@¥+Ÿ¹Piæ²{÷nÞð­@¥}u'žª4mÚTÐ fêÔ©˜7o'2@U~üñG¥×dhh¨ÔoBˆo VVV&¸2Ó»wo¥y> ÛC^/¡Áç´iÓ”šöŒ;Vé5 µ‰ŠŠ Äb± rÓ¶m[¥Žõï»GZµjÅë/S¦LÁªU«Áß×ÊäZZZ‚ò† ÂÖÖVi~e×dll,˜(ÑÝÝ^^^‚ !%‰ÒPÏzzz¼€ÊHeBÊš––Þmmmܹs+V¬P™ššB]]uêÔá 6áìì [[[^@‰D+++èèèðîûÍ7ßàÁƒpqqQx^uuuáææ†Q£FáêÕ«œë‹Å˜5k&Nœˆ§OŸbÇŽl¤/¸¹¹aÒ¤IÈÏÏÇ;w&BTTT0uêT•+ªÕ'Š‹‹ñöí[A¿¬¬,Èd2…9©©©ÐÓÓã}^†Avv¶àûI>ÀèB~nÞwTAAÔÔÔW,ß½{§ôÞU&///Gaa¡`~$eû–••¡´´TðþÌË˃D"á½GJJJPQQ!øîËÉÉA:uMWÿÎ5+“Éd2äææ ®¤B,óN’¼¯-óóó¡¡¡!8‰V[×ô>yii)¤R©B>9¹¹¹ÐÑÑá}gƒaÁ÷[vv6ôõõ•€©kª¨¨@~~¾àd©²gJ*•¢¸¸Xp§ì¾~_½rrr ««+øýû;׬ì™zßû©¨¨***‚ï'eç-((@^^žà·õï\Szz: y¿­999ÈÊÊÂöíÛýõõõ‘——___¶ÍwwwXXXpL¨äc²1cÆàêÕ«¼“ÖÖÖèÞ½;,,,xÍЇŠ}ûöñN,«««CWW#FŒà틾}ûbÑ¢EpssFGG NÒ¶oßž¼ˆùÌèÑ£ãëë+(òä “ŸŸ/(¿sçŽÒã+“+“Éd2æîÝ»‚òׯ_3¯^½â•3>Ü÷åË—LZZÚ¿~Mï“gee1‘‘‘‚òˆˆ&''‡WöæÍ&66Vpß°°0¦¨¨è£êÌTTT|Ô¾eeeLHHˆ >^P~ÿþ}¦¬¬ì_¿7ß÷LGeæÎ+Ø^žžž¼×Ã0 S^^ÎÌš5Kpß-[¶0k×®”wíÚ•yýúµ`?íÝ»Wpß72qqq¼²»wï2?üðƒà¾K—.eÒÓÓ•^³R©T©üçŸ|åææ2üñ‡à¾§NbnÞ¼É+KLLdºuë&¸ï˜'Ož|Ô5½¯g͚Ŕ——ԱØC‡ ÊW®\ɤ¤¤ðÊ®^½Êøûû î»`Á¦°°WVQQÁüüóÏ‚ûΜ9Sé% IDAT鱕õczz:³bÅ Á}ÝÜÜ¿C/^¼`¶lÙ"¸ï®]»ßç2™Lé5­ZµŠÙ¾}ûGõ£T*e¼¼¼™LÆ+÷òòbNž<É++**b:tèÀðʘéÓ§ ^Ó¬Y³˜ÒÒR^¹ŸŸãììÌÛ2™Œ™4isöìYÞ}oݺÅtèÐ‰ŽŽæí‡¯¾úŠéӧ»ÜÓÓ“Y¼x1³uëVÁ{äìÙ³JßOOŸ>eòòò¿»ÊÆÁ¡¡¡‚íQ›cÆ’’æÁƒ‚ò¸¸8Î÷ë‹S@‚ >gŽ;Æôèу)))a•šeË–1×®]cvìØÁ 4ˆwàÙ³gO¦Aƒ¼Çœ>}:€9r䯼eË–Œà`iåÊ•‚ƒÄõë×3ß}÷¯ìÝ»wLÇŽ™ßÿW¾sçNfÚ´i‚“3nnnJSSS&,,ŒWvøðafåÊ•‚ûjhh(U@,--•* cÇŽœ0:t¨à¾³gÏV:lß¾½à€(77—éÙ³§ààÂÊÊJ©"‰”* ëׯ¼z÷î-¸ï¦M›WWWA¹‹‹ ³uëÖR@V¯^-¨€Èd2€R¤yóæJsçÎ *sŽŽŽ‚ûNŸ>ùõ×_å-[¶dyeGŽQª€4hÐ@©¢¥¥%¸ïòåË™£G LÍÍÍ•* #GŽä•ÅÇÇ3S¦L4Ï›7Y·nà35lØ0fãÆ¼²K—.1Ý»wgÞ½{Ç+WWWæÜ¹sL§N˜M›6±Û·nÝÊtêÔIéDñ~¾¸D„AŸ3ß}÷Ž;†E‹ÁËË K—.E»víàì쌱cÇBOO›6mbË?þ7nÄæÍ›áàà€;wrŽ—˜˜___;v ×®]S8ßáÇannŽ6mÚàåË— òÕ«WãîÝ»‚þb[·n…H$âõzûö­RP¹y_8æ·oßÂÞÞééé¼& [¶lQ|ÁÏÏ6l”7>>>¼²ÄÄDÁ@&%%%xðà YOLL :tè€cÇŽ ž[[[›ÍUS•„„¥Ñ—/_ÎFdãÃÂÂIIIußegg³!<ùLMºu릴=?–ððpDDDð áäîù§ÈÉÉÁ³gÏpùòeÁ2–––•èðáÃl¤">îß¿¼¼<ÁgÊÒÒ‰‰‰‚÷WÕü ÕY¿~=odÁªæâÛ·oç5ï+--EýúõyÛûåË—‚¹ÐäTwz®ú<ÙØØàöíÛ¼ò€€èééaåÊ•‚× €÷™Z¸p!þøã¼xñ‚÷™zöìÈ[7ooo¬Zµ žžž3f rssY³¿#F gÏž0`.]ºðòò‚——ÊÊÊpñâEA¿^¢fBñ ¡¢¢###,_¾ë֭æM›Ø¢££áììŒ'Nðf’×××Ç¥K—PVV¦ ‹…——vïÞÍ›»'88W®\ám‡øøx”””‹ŠŠØ())á•ÅÅÅ!**ŠWဇ ä†ÁÙ³gysãTUÊø”„ÒÒR¨««£nݺ¼ƒ|XiÒÙÐÐPA| 2•²knݺ5oN*e zÀßßVVV‚V5j¤T hذ¡Bþ9B åýxúôi¥Xyè””¥EJJJ°mÛ6¥Ê¯býúõk|÷Ýw¸ÿ>ï¾.\@ÿþý/xn¡¶LOOÇ©S§xÀÈd2DEEA, ¶waa!o˜y©TŠW¯^ÁÜÜœ7XOhh(¤R© R¥¢¢‚ÂÂB6ÇDUNŸ>  %%EáyÎËËCrr2lmmŽüàÁƒ°¶¶†»»;ÌÌÌpüøqŽÈ0 F  8Ó¦MÃÕ«WñÓO?¡C‡ÿ½ûŽj"kÿþ U¤WP° ØX°‹"¸Ø*6ìŠ}UÀîÚ .¬õµa/è¾DW +¢`EÄ‚ti!2¿?8™! "î»»¬ÏçÏ‘ÌÜ;5pŸ™{ï///(**B[[ .D@@°xñâZïiB!„üëhiiaÇŽ°µµŸÏG`` ìííÙFà°aÃðË/¿ )) 7nÜ@rr2¼¼¼Tå|Ù³gDƒöÌ™3øé§Ÿ0cÆ >|Xb[)))ˆ‰‰ÁâÅ‹‘ŸŸ/d³Ó>æääHíë`bb‚ììl™¢‹/bذa2ËÀ¦M›pþüy¹ç"331112Jzzzpuu•9…ù‘#G››+3h€W¯^!22²ÖéÏ‹ŠŠd<On^ñ`þÜÜ\¹õ>zô õº7>|(7‘jnn.–-[†£GÊ\~óæM¹‰AÅ×RžŠŠ èèèÈ|{{ûZúµÕ’’‚?þøCæ²#GŽ 44Tî=‰ìììZóÉSVV&7ï@ —Ë…ºº:ûÔ¼&YÁº˜P(”{Ï‹gÒ“÷F(##"‘ÇŽ“¹\GG@f°xðàÁZªþöÛo2'€œœ̘1CæqáìÙ³˜={¶Ük‰6mÚàÊ•+RßáÛ·oãöíÛxüø±T𓟟333,Z´Hêerr2âãã1f̬\¹;wîdƒ+‘H„mÛ¶aÊ”)ÐÐÐÀâÅ‹±ÿ~äææâÍ›7سg,XÀ0Ÿ1cfÍš>ŸÑ£GÃÛÛû«4 @!ä_„ 8”šÍdùòåÐÑÑ««+¢¢¢pèÐ!¶;ÑÔ©S‘€„„0 ƒ;v`ðàÁhݺ5\]]ÙÆ‹Øùóç1zôhU]Ãj6ô’’’0dÈ´mÛVf÷ ¨¨¨@EEEª±/ ¬¬ [[[øùùI•åóù˜9s&úõë'ÕЯ¬¬Ä¥K—0qâD™ À¨¨(ÄÅÅAGGGfwqÃV^£  ‹/–{þˆ›7oÊœþúСC066–[öÂ… r»šˆjòÜ***2Ÿ»wï¢mÛ¶ÈÏÏ—ü¼{÷¯^½’»íÊÊJ…¯¾?}ú„ÔÕ§k˜P(ǓۘõêÌÌÌä6ªóóóÑ­[7‰'ßÕÉ›ñ ¨zj_ÛòíÛ·³Ý–dQUU•9-÷Ç¿X÷¢E‹j šd}_àÊ•+6lÒÒÒ¤ÞˆOOO\¸pAæ9SQQÁ˜1cd“ŸŸlmmåήTM¡/kF1ñï‘H$`”––²o°rss¥ò)?Ë–-C¿~ý ¥¥%÷÷Ó¤I“ðúõköÍÆ™3g`iiÉæÎrssÃÚµkáî~ú ãÆ“š ÓÉÉ ”šyŠPB!¤fΜ‰ôôtlܸQb*FKKK¬]»Û¶mÚ5k‰_ý@Քܞžž›>°o»víŠèèh‰í¬\¹]»ve§‘®îljD˜?>V¯^+VH,ß´i<<<äæ Y¹r%\\\о}{¬\¹Rb™H$úâØ’/™5kÊËËevßiÖ¬™Üü57oÞD§NäN;üñãGÌ›7OnW)qIžÌÌL™]UòòòðæÍ¬X±Bê|U}ÝÓÓÓåÖËår1tèÐZÏÉÝ»weî÷Í›7Ù\òŽ)44Tîò7nàÉ“'µn[Övoܸ!wJX ª•––233å®#ë\‰­Y³/_¾”´]¹rEf#^¬¢¢¢Ö$À[¶l‘ú¾ˆ¯caa!–,YRkw:yôôôä&Ž­õMSõ€PÖù_´h†*÷œµiÓˆˆˆZÖ·o_Ì™3|>_ê;õðáCtíÚ[¶l‘:æê÷–¬åÐ××ǸqãàïïÏ.KKK“˜æýòåËX¹r%¼½½qöìY\¹rEb¬VŸ>}pïÞ=\¿~ƒ ¢?€Bù«899aß¾}ðõõÅÍ›7%æl:t(®_¿ÎfŠ×××Gûöí^^^xþü9ÛxyôèæÍ›‡¦M›¢yóæhܸ1:ÄÖõþýûZdй¹¹ÁÖÖVîxŒÚŒ3%%%µ6~k*//G||<6oÞŒ¤¤$©ÆþåË—‘••%7gOXXX¶SÛzâ§²_³,77Wîø1EEEôèÑ£^÷Åøñãagg'sYhh(ÜÜÜ+³+Ý£GävEªÞ(É +**ðôéSlÞ¼YîùŠE«V­êuL&&&róê¬Zµ @ÕxyƒÜ7oÞ\¯k(®»¾÷Ȉ#ЬY3©·‘‘‘xòä æÏŸ_¯óa`` 7T]ïëòòr©dÕªUpuu…’’’ÌïT‹-ØœI5·777UIuƒƒƒÙ@zëÖ­°¶¶fs 6 W®\Á½{÷°víZI ·±±Á­[·°víZ‰Œâ„B!3%%%hkkC[[[ê)~ãÆqåÊœ8q|>_¢«ŠŠ ¼½½±eË”——cûöíèСÛÉÊÊJbòöíÛ±téRU >ïܹÃP …xûö-–.] %%%dffJ<-ÎÎΆ™™  3ÙdRR¦OŸccc0 #õÔW¼í¥K—"%%E¢ÑÌårqýúu¹É²***PYY‰1cÆ`ûöíúù·¶¶†‡‡‡Ìº·oߎ1cÆÔ»neee¼~ýZæŒdjjjìd5:tˆMbX›àà`¹ãfÄ×ZyÉù|>BBBä^  j¹¥¥¥ÜËZ´h!ómÔ§OŸ`bbÂвÒ_Ò¨Q#™×))) cÇŽ•;U]ê–')) «V­Âû÷ï¥N¡PˆŠŠ Œ39±ƒøZ$%%I|vçÎ|þü½zõªu¦5©$‡ÁÁÁ000@Ïž=e^ËêÇÛ¦M‰mŸFŽ)±ß˜1cœQZZ*ÑM«¨¨JJJÐÐÐÀÌ™3qòäIö|———C$±AÄÌ™3%¶˜˜È¾ÁPVVÆÒ¥KáççÇ>„ÐÓÓƒ®®.»þ’%KpêÔ) >“'O–Êæmdd„'N`óæÍr§Â&€üi>}ú„ØØXÄÆÆÊø !„üoáÀðòò¦M›$–™ššbòäÉØ¶m‚ƒƒ1{ölôîÝ›]îããƒsçÎÎ;‡#F°O®­¬¬$úvóx<‰ÆE^^žÄSV‡555ÀرcÙzÅ”••k,Û¸qcp8‰}ª¾mqcª¦ÊÊJˆD"Œ9RjŸªY½JJJ`hh(ó l]º¤éêꢼ¼\îÀiñq×TÛ~²³.?~\î,\òÊ׆ÇãÁÕÕúúú2/99fffðððÖF^#3;;§N‚••BCCåÎþ5vìX™3BU¿‡jº}û6ê4Õª¬cVUUE¯^½`nn.5µõ¹sç`ee555™¶¿tÜò>/))ÁÁƒkÍR½lõýÎÌÌÄÙ³gÙñX÷Hõï#‡ÃÁ§OŸØàçõë× eߪØÛÛCYY™FØßß>>>l]mÛ¶Eii)RRR 5Þ¤k×®ÇÔ©SñË/¿È}È@(ùKtêÔ S¦LÁ”)S¾øÄŠBÈÿŽÜnB›7o†¡¡!ôôô0}út‰eöööl7¬„„,Y²„m\4mÚ;vd×]³f 6nÜÈþ¼qãF6Xaa!ží?‰^¾|9»~m™¯«ÓÖÖF§N°zõêz '7³xûöí¥ìqqq2dˆÜî[Ë—/gÏž=“›£¤{÷îõÚ_q¹š‰!oÞ¼‰/^ wïÞXºt©Ücª¯•+WÂÉÉ Ïž=Ã;wd^óo=¦šÙ¬Þ®®®÷GÍàÅÝÝ]ês---¹ö·mÛVç¼#111Rëvèн7j^ ñÏÊÊÊèÝ»·Ä~GEEÁÑÑÊÊÊèß¿?tuu%iV¯ËÕÕ{÷îEFF[¶úx/WWW‰õ­­­%ºÐ9::bÿþý(,,ÄíÛ·¥‚¡ñãÇãáÇزe ÂÃåƔtëÖ «V­‚§§'ýÒ¤„Bùßjß¾=®_¿.s¦¦±cÇââÅ‹ Á±cÇ$f>š:u*ž>}ŠøøxlݺUbJ_+++³]]¥‡Õ©«ªª²]Múõë‡Ö­[³ 1q@S½OzÍî¶¶¶€‘#GBOOO*¡œxyM………˜1cúö틇"..N"0*--•››¤.Ó«À¨Q£dΕ·_"‘III2Ú@U·³ÊÊJp8(++ãâÅ‹2×sssC‹-¤rvèééÉí¹°uëV())Ãá°ÝÛdqwwÇöíÛåæ(‘ul‰‰‰r‰a‰ñòέ‚‚rss%’þ}þü}úô———Ô˜›êuÉÚ/mmm˜™™É=...uβ]}[/^ÄàÁƒ¡ªª EEEöœŠKÖÖÖìtÐ/^”è²Ø¥K´lÙAAAØ·olll`bbÂ.~üˆ””<|ø£FP5cNzz:¼œ?–––ìÌ[fffÈÊÊbzûöícëÖÒÒÂË—/%f*ª¾|îܹÈÈÈ`y)))ˆŠŠb—\.WîlIsçÎýêÄ}†††ì˜ššoGÄûÅáp0{öl‰|!§Nú¦kjff ¤¦¦J$$¼sçÑ¥K™îÚ2Í×Tszzz:æÎ ˜6mšTÂIqÆ÷Fɽçä©^·P(”è&õòåKv€¶®®."##åv¯¹_ÑÑÑ(**BŸ>}Øë\ýZT?vvvèÒ¥ àÞºu ì[OOOðù|¹ãjæÎËn;88æææIKÅûöâÅ ¼~ýZ"XSSSâE‹°nÝ:œ>}óæÍ“ª?88îîîØµk—ÌÁöÆÆÆu¤ „BÈߦE‹ìÌY5M˜0îîî˜?>LMM%–ùøøàÀ8}ú4œ%»(++Cvv6233¥º‹L˜0;œžž.ñÄvñâÅ8yò$›'âíÛ·ek6¼ª/oÕªþóŸÿȶVV£MüY«V­°clj ÁÀÀ€Ï2qâD‰ŒÑÿýï1|øp¹OÖÅûÅáp¤ê®ÎÖÖvvvRÚš]hÄŠŠŠpíÚ5¹YãsrrØý\¼x1®\¹"•éZÞùàñxhß¾½Ü„;vìxKVóÚˆ™››càÀRYÉÅÛsqq®®®Äuª^·¼™¬da\.WbüBõýÊÏÏ—èrUýZˆD"ðx<¶¬¶¶6***ðÛo¿¨t¯¤¤Ä¾Å077Ç7ðöí[¤§§ãÉ“'9r$[·µµ5ÒÓÓQZZ*ó ׀ʎSªùêÑ£Ö­[‡ýû÷ËìØ´iSôîÝ[âm!!€BùWiÞ¼9Æ/3±œ¸»Hff&Μ9#õäuݺu쿚ƒ©ííí±nÝ:Àï¿ÿÎþ_}}}‰éëÖ­Ãï¿ÿÎþܹsg™ƒ©Åu>þ›§ÑªžZóx<œ>}Zb¿ÅÛrss“èªSVV†—/_Ö¹þÄÄDv*æšjžË“'OB ÔiJÚ/ …HHHyL–––ˆŽŽ–xsSÛ~ÕTýšòx@¯^½pøða¹ozõêUçý,((À‡ØÙÌjn«º&MšÀ××WjJ[ybbbàîî.·ñ,o;òT_ß×׿üò û³³³³D²¼êlll0bÄ6£zdd¤DÙyóæ!..NnðS½n___©ûgÞ¼yøý÷ß1f̉zÅöîÝ‹ììlœ>}ZfôÙ³gÃ××·Ö©{ ¡„B©‡ƒ•+WÂ××W*÷‡ÃÁ²e˰ÿ~,X°@êíIÛ¶m‘••…ˆˆ¬ZµJªÁmoo7oÞ 11Q"hPWW‡««+BBBT¨þöFÜ]J<ÞÊÊŠ ž àààÀ6*Ÿ?.Qw‹-ØnQIIIìl]‡Ð}ýúu|þü™ œfÍš>ŸÏŽk¸|ù²Üï²0 ÃŽk€víÚ±å‡.‘æùóçì¸ Oè³³³Uçms8\¾|@Õ@ðÊÊJvªç!C†€Ïç#,, @ÕŒO¥¥¥ìµ^½z5^½z%w°yõ@%!!“&M’ÛM$Ií³ø\?þ .d¯MÍkQó\‹÷alÚ´IjÆ5333Lœ8/^Dÿþý¥ÆFuéÒ;w†³³³Ì.ZZZرcFM¿ „BÈ?IË–-ˆ)S¦H-6lÜÝÝ‘œœŒ!C†H,kÔ¨ÔÕÕ±wï^DGGK ~ªºåääàÖ­[())‘˜z¸[·n`ÑÑÑØ³g† &ü˜››³ãNœ8É“'³Ë\]]‘––†˜˜”””àÒ¥K}ñÍÍÍÙÿóx<‰nOZZZˆŽŽ–ûcÁ‚HMMeÖÑÑ‘ÈãPÝž={àéé)Ѩ®>`ûĉì1)++cüøñسg̺jnçÇX°`Ìuß¼yƒG± }uuu0 #w@¶®®.Ο?ÒÒRB__ƒ b—Oš4‰Ý¯3gΠqãÆlŽ###Œ;©©©ÈÏχÃaßrUÝÒJJJðàÁœ8qÚÚÚçcÁ‚ ĹsçЬY3©îY ,ÀÖ­[‘––&1H¨z·|ùrøûûcáÂ…2g”úõ×_±wïÞ/æa!„B!¤ñòòÂéÓ§%žbÛ·oÇçÏŸ&•¥zöìÙˆŒŒDdd$†.³aœŸŸ„„©7/ .Dpp0²³³¡   ³k™8@ÑÖÖ–x³³páBœ>}"‘………˜4i’Tc¿°°ÙÙÙǸqãØeؽ{7€ªY¬š5k&‘àpÒ¤Iìv?|ø Q¯ŠŠŠÜLÝÕ ñ¾Wªºví ccc¶+Úž={`aaÁ.Ÿ8q"x<žÜ©xuttPPP†a¤ŽYAA åÖ³ IDATn=z„„„©±:>|@ee%Š‹‹%®…ŠŠ LLL°{÷nܾ}›ÍÁ!fhhMMMDEE!22õÚÚÚ¢sçÎxùò%š6m*Ì3\.ݺu“¸b­[·Ftt´Üü0„PB!„|g´´´pêÔ)©§×b¡¡¡ÐÓÓ“˜¡HlÍš5˜3gN:…•+WJ,SRRB‹-àáá!1Võ²!!! ÁÒ¥KÙ)xÅ ‰°qãF©±âÌÖ\.>|èeddľyÿþ½Ô¬U:tÈN^=ð±··G=†a`ooæÍ›³Ë]]]ÙeãÆRã\Š‹‹¥‚±víÚáøñãÈÈÈ€H$’Jv¹fÍlÚ´ ðóó“8æÆcÉ’% Ã0Remmm¡¦¦†°°0ìß¿_*sú°aÃp÷î]œ>>ðññ•••D¹êîÞ½Ëæ¤ÓÓÓƒ¹¹9Ö¯_/syÇŽ¡££ƒììlÀÇÇGbyII ž={†€€hiiIÌbåèèˆ . >>^æþøûûãîÝ»¸ÿ>lmm¥¦x¯/œœœ$–™™™¡uëÖøã?Ð¥K©71Ý»wÇ£Gàãã#U¶eË–pssÃàää$5ÆÃÉÉ ZZZx÷îÔ j°xHHˆÄìa5¯ó¢E‹hÊZBªc˜¾}û2'Ožd!„»¬¬,¦¢¢Bæ²Í›73W¯^•¹¬¨¨ˆÑÔÔd¶mÛ&µŒÇã1ŽŽŽŒsóæM©åûöícÜÝÝ555æåË—RË===™={ö0 ZöâÅ F[[›™0a“””$µ¼_¿~Ì´iÓ[[[¦´´TbYZZÓ®];føðáÌìÙ³¥Ê†††2Æ cÆŽË”••É<šššÌÙ³gež“2K—.eÊËË¥–½ÿž™9s&SRR"³,—Ëe è†$äOÂaªOgѸ¸¸`Ê”)ðôô¤è‘B‘#&&íÛ·—9xùåË—¨¬¬D»ví¤–ñx< 0]ºtÁ† ¤ÆŸ^¼x~øAæùÈË˃ºº:ÔÔÔèæ äoF!„B!ä/Cc@!„B!€B!„B(!„B!„ @!„B!€B!„B „B!„¿žÒ—V8{ö,Þ¿•+WÖºÞÉ“'‘ ___ö³cÇŽ¡  K–,a?;|ø0JKKñÓO?¨Ê|ZZZ PVVþâv!„B! W­o@Μ9KKKxyyaëÖ­àóù2×;vì:tèOOOøùùA$áðáÃptt„‡‡¶oß8xð zôè#FÀßßàåå…Å‹cúôéàñxtE!„Bù«õ ÈÓ§O1a€P(ǃªªªÔz/^¼ÀÔ©S……… …xõêf̘ÈÉÉÃ0HNN†—— 33 ©© xòä ºwï.QoLL rss%>ËÏϧ«F!„BHC@víÚ…´´4vÁúõëÿ²àr¹ˆˆˆÀ† $>WTT„²²²Äg 4l…B!„€ˆÇdT§¢¢@ÀâÆee%ŠŠŠ §§ jìFEEÁápª*VR‚P(„‚‚[NÖg…=zHm¿S§NRŸéêêâСC¸sç]=B!„Bˆ¹sç¢sçεwÁš={66mÚ‘H„~ýúA[[””„ž={¢  0cÆ lܸ"‘ƒ†ŠŠ ¦M›† 6@$ÁÝÝS¦LÁ† À0 <<<Øí„……!  N;>pà@<|øVVVõ:ðëׯcàÀyÙ””ˆD¢zí÷‹/ ¥¥…æÍ›7¨c~ôèZ·n }}ý¯.¨««uÙ°°0¸ººBQQñ«Ë Ü»w®®®_]¶¸¸ÏŸ?GÏž=ÔuÊÌÌDVV–Ì€ÿKÞ¿òòr´mÛ¶A󷔉‰AóæÍaddôÕeïß¿öíÛCKKë/ÝïÊÊJܾ}nnnõÚî·|§¾å\Ëw*''iiipppøê²©©©àr¹°µµmP÷æ«W¯Ð¨Q#´hÑâ«Ë>{ö ÆÆÆhÚ´iƒ:æoùNݾ}NNNPQQùK÷¹´´111èÝ»÷W—ÍËËûwïйsçuÒÒÒP\\ ;;»¯.ûúõk())¡U«V_]6>>055mPç+** 666ÐÑÑùê²áááèÞ½;5jôÕe†Ahh( ðÕeËÊÊððáC8;;׺ž††»±Zñù|¦¬¬Lâ3‘H$õ™¬õø|>S^^.ñYyy¹Ôg€©«gÏž1'OždêkÉ’%KÙ[·n1ׯ_¯WÙóçÏ3QQQ î˜÷ïßÏ$''׫ìÖ­[™œœœz•]¶lÙWÝSÕq¹\fÍš5õ*›žžÎ4¸ëÇœ8q¢^eï޽˄„„4¸cþ–²‡fëUÖßߟÉÈÈøË÷›Ïç3Ë—/¯÷v¿å;õ-ç:##ƒñ÷÷¯WÙÄÄDæðáÃõ*ûàÁæÂ… îÞ¼|ù2Q¯²ÇgâââÜ1ËwjõêÕLiié_¾ÏÙÙÙÌÖ­[ëU699™Ù¿ƒ»Nßòºvísûöíz•=sæ ÓàÎ×®]»˜>Ô«ìúõë™ÂÂÂz•‰DŒ··w½Ê~þü™Ù°aC×ÿâ4¼²ž p8©ÈJÖz²>“5ˆ½æ8ÿ¥ú>ÑúÖ²††† …õ*kbb]]Ý¿åUÙ·³……ÅÿGº_ÉÒÒRæ½R666ËX¡FÕë Íß}ojii¡Y³f îþú»Ê6oÞœ<£¡œ/ØØØÔ{»666l÷Ú¿ò\ MMM˜››×«¬žž^½÷ï¼7¿EóæÍÙ^ é˜[µjU¯'½çï.UUUXZZÖ«¬ºº:,,,Üý%î²_Mš4’’R½Êš™™ým÷õ·hÙ²%7n\¯²ÖÖÖõnWs8œz³ŠŠ ¬­­ë¾-†a4 qqqHHH€§§'HÝx{{×¹‹Û÷®´´~~~R"Ù"""PTT„¡C‡Òɨƒ€€Œ7&&&t2êàÓ§O8{ö,¼½½édÔAHHtuuáääD'£Ö¬Yƒ+VÔ»¡Gm Bç«þÜ”RÊÊÊËÓŽ†ìïzZÛq8œz¿µù©¨¨ÔûMÕ÷H]]½^ã(¾Û?P õö½jÔ¨Q½Æ3|Ï¿åMµ%¯oho5´7 „B!„†K韲#—.]ƒ ¥¥…eË–Õú–£¬¬ Æ ÃÕ«W‘žžŽ#GްYÚ‡ '''dffbΜ9¸|ù2]eB!„ò§ÈÌÌľ}ûÀãñ0|øpôêÕ«Öõ¯_¿Ž'Ož`íڵؾ};²³³TÍv55µïîþ#º`EGGC$! ‹-‚ŸŸŸÜu qèÐ!vW~~><==€É“'ãýû÷HOOÇ•+Wê= !äß+>>žýÝqýúu©åQQQ¸té’Äg÷ïßÿG>ÌHHH€H$jp× &&¯^½úÛ¶ÿâÅ‹ZÏ[xx8222þöó”””„ . ¨¨èö=¨+@€ . ²²’~‰ïÞ¾}û°bÅ  ** 999r×½uëJKK!îp´téR`ôèÑðööþn‡ü#>ŸÏö#×ÖÖFqq±Ìõ ðÛo¿aüøñì¬;wFÛ¶mñüùs<{ö “'O†šš&L˜@Ë!RNž<  jüб±±Ä²¸¸8$&&ÂÐÐ`ËÉÉÉÐÑÑÁáÇÿQÇræÌ™:7O:…ÂÂÂÄ~ëêêþ­ý£ƒ‚‚PQQ!w¹¡¡a»wïþŸî§¦¦&âã㑚šú§ï‹ø{PçÆ‚‚LMMiÌ!x<ÛÆTTT”û{øÖ­[¨¬¬Dÿþý%>ÏÌÌÄ/¿ü‚ââb|¯#!”ÒÎ>{ö ÷ïßGrr2îß¿N:aôèÑÁ€z%¾#„ü;•••aÿþýÈÈÈHhwüøq|øðöööìgÅÅÅ022B=Ø©¯‹ŠŠ`llŒž={ÂÈÈ\.»víÂçϟѨQ#,[¶ /^¼€††îܹƒÏŸ?Ã××())††|||p÷î]DEEA[[‹/Ã0ؾ};ÊÊÊ ««‹E‹¡²²~~~àóùÐ××ÇO?ý$w0öÕ«WñàÁcÞ¼yàóùØ´i€ª)¼ç΋ÐÐP:tQQQhß¾=æÌ™ƒ'N°¿3ãââÀáp`hhÈÎÚÒ¢E ̘1¹¹¹Ø¹s'€ª)O§OŸŽ3gÎ@UUOŸ>…••¦N*sðó›7oØ@ÎÆÆ“&MB~~>öîÝ‹=z`Ô¨Q€Ã‡ƒa$%%¡C‡?~<^¾|‰'N:uê„qãÆÉÀŸ’’‚ýû÷³¤FÀÀ@ðù|¤¦¦¢k×®5j¢££qñâE¨©©ÕúF!>>˜8q"û·dÿþý(..FNN\\\0pà@¬Y³7nÜ@jj*ÆŒƒ.]ºàƸ}û6 ÿþèׯΜ9SSS\½zƒ Bß¾}±wï^äå塤¤C‡EïÞ½Œû÷ïFŒž={ÂÔÔ­[·–Ø¿°°0ܼyàáá[[[üüóψˆˆ@jj*æÎ üöÛoˆxzz¢]»v8{ö,ž={kkk™Ç_QQÓ§OãÅ‹€Y³fÁÚÚ.\À­[·ðÃ?@EEïÞ½ÃÇÙmÌ›7¦¦¦8vìÞ¼yX¸pa½§B&äßàÔ©S044ĵk׋åË—£Q£FhÚ´).^¼ˆÕ«WƒÏç—]°Àü|üø‘Ù±c# ™°°0&44”]vöìY‰ŸÅV¬XÁ”——3ÏŸ?gŽ9Â…BF(2•••ŒH$b„B!³xñbF(2"‘ˆ!„|ŸBBB˜»wï2 Ã0‘‘‘ÌâÅ‹e&Šzúô)3fÌfèСÌýû÷†a˜'Ož0£FbFŒÁDGG³‰¡PÈäää0›6mb†a†Î|üø‘ÉÊÊb¶oßÎìÚµ‹y÷î# ™>0¿þú+ãïïÏœ;wŽa†yûö-³wï^fË–-Lnn.›È)!!Y¿~=“ŸŸÏ…B&..Ž9zô¨ÜwîÜa†a>|ÈüöÛoÌ’%KØß‡Ì¥K—d&÷{pp0Ê„……I” aÂÃÃ%>»páÉÌš5‹‰e†aÎ;Ç~ü(7q–x½ 60Ÿ?fFÅ&ñúù矙’’öxy<ãêê*•·¶¤id²³³¥î™š‰Æªï³ø>Û»w/sìØ1ö|0 Ã8;;3ÅÅÅlB¡ñõõ•YïñãÇ™øøx™Ç+ï^ÎÌÌdüüü$ÖKMMevîÜÉ0 Ã$%%1&Lyì¯^½b:$q‰­ZµŠáñx Ã0LLL ãåå%±ýèèhæÜ¹slÙoIÄFÈ?ÙÉ“'™§OŸ2̺uë.—Ë0 ÃäååÉLäW\\̬]»–M*þŽTÿN}oþo@ÌÌÌ0qâD¬X±...pssc—)**Ê|êÕ«W/(**BAAIIIX±bû¹¹¹9NŸ> %%%¬X±}úôÁÀ)'ä;׳gOË\Ö©S'Ì›7èÑ£ÀÁÁ³gÏŸÏG×®]ÙuwìØÁ>ÿ¾jÙ²%ÌÌ̾¾¾Ø½{7üüü ¥¥2d?~\ë`E]]]èêêâÒ¥KX¿~=Û5u̘1rËȪOüû&MšTë9‰ŒŒÄ?þȾ-ª^ÖËË \.Wâ³¹sçBCCCâÍ‘<Ë—/gË6jÔ .”¹ž¡¡!Ú´i#ñYzzºÄvåuÙ:zô(^¿~  j<áüùóѼys¹OÞÕÔÔàèèøU÷M›6m`ddôÅõ?~Ìî³øºW¿Fþþþì½VŸ.h[¶lÇcßþÈsýúuäåå±o®ª³¶¶F“&Mäë‹/Øãøá‡änCV¾‘   ö­Hme iÈ<==qúôiœ;wNjܲ¼ÄÜÝ»wg¿câï—››Û÷ùöÿ .Xؾ}»Ôç£G–¹þ€Te©”UNÖg„ï©©)¢££‘‘‘ŒŒ vðñ­[·””„³gÏbܸqu®¯eË–¨¬¬„††TUUáââ"s=kkk¨««CMM 7F¯^½ðøñc©õlmmñûï¿CEEååå°±±¸\.””” ££¹ûãïïsssÂÞÞ UÃûŒŒŒ`gg ª Ôµk×ÀçóÑ«W/´oßpvvF\\ GGG6è155E«V­Ð¹sgöd³f;* sXX:vìøøñ#ÊËËQTT„ .àùóçxüø1:wî,7X400`ÿ`ËËf\TT„Ž;B$!**Jî¾4iÒAAA …¸sçÖ®]+s½´´4ܺu ………°³³«5³oÓ¦M„ììl,^¼ýúõc'HéÖ­›Ür÷îÝÃñãÇ¡¢¢p8¨ªª"((ˆ½n˜˜ˆ‡"++ ÐÕÕ‡ÃAÇŽQ\\,1_CCAAAàñx5j\]]ѲeKÀ?þ‡.—‹   |þü?~”¹o999øôé{Ýòóó>Dbb"þûßÿbäÈ‘rÿŽ;99±ÀŒ1‚~‘­‰'J}¦¯¯-[¶H}®ªªÊ>è±¶¶¦6*(!ä;ðúõkp¹\˜ššB(ÂÌÌ III(--ðÿOj¹\.„B!tttزâA‚ÕÀ‰‰‰(//‡¢¢"ÛPKOOg߀ˆ%$$@ @YYíÛ·Gvv6ôôô ¬¬ >Ÿ¢¢"!>>B¡ªªªlÀ‡ÊÊJ¨©©ÁÆÆFæq¥§§CYYéééPWWgß"ˆŸ@khhH4 ãã㡦¦+++ˆD"deeÁÄÄ„Ý÷ÊÊJÄÅŨš¤uëÖ …ìŒI:::hÕª•ı@EEEæ•òòr$&&²˜-,,PVV†—/_² Vsss‰úrrr ­­ ¡Pˆ¤¤$¶AÞ¬Y3™ç ¤¤ÉÉÉPPP€±±1ŒŒŒ™™ÉÖ÷éÓ'£¤¤)))PRR‚LLLd¨.((À»wïØ€ËÈÈHbÿªÿ¿¸¸oÞ¼¹¹9 ——Ç·°°€¾¾>rss¡¥¥%‘°ÓÛÛ“'OFEEZ¶l ]]]dee±3oµjÕ :::ÈÌÌħOŸ­[·†¶¶6>}ú„ÌÌLhiiAMMÝ—ÜÜ\¤¥¥ÁÊÊ šššHOOg§ú´¶¶†††>~üˆœœö¬y¿Š¥¦¦²oOlmmѨQ#|øð FìììPYY‰òòrèééIœ—wïÞ¡  Ð¾}{(++Ó/ B „BÈßiëÖ­ÝË!„B!„BùQ S@!„B¡„B!„B!„B!„Ôן2 /—ËÅÁƒñùóg,Y²Dn&òââbìß¿<?ýô;{!„B!äûð§¼9xð Æ‡5kÖ`÷îÝ …2×Û¿?¦N ___ìÚµ‹Î>!„B!ß™?å ȧOŸ`bb *S«8ÑWM999l‚%.—+±ììÙ³l6Ûê†Z§Œ»„B!„ï$ù3 >\êÍÉÈ‘#ѬY3 @!„Bù—øSº`éëë#??JJJPP¨ª¶¨¨áááìz:::(,,DYYÔÔÔ$êPSSƒ¦¦¦Ä?%%%ºB„B!„ü‹ü)-üY³fáàÁƒ())——8|üø[·nEß¾}ÙõöìÙ>Ÿ///:û„B!„ÔSAAÂÃÃaff†.]º ;;K—.…ªª*† kkklذJJJ˜7o¿i{|>LJ¹¹9:wîŒU«VAAA˜:u*»^YYvî܉+VȬç }À€5j¦OŸNw!„B!Õ¼}ûèÕ« „ 6 GhÓ¦ |||```€™3gBUUþþþ ¬÷¶***pêÔ)ôìÙVVV8zô(1lØ0Lž<!!!ìº>Ę1c––&³.ÊB!„BHÔªU+üøãŸ988ÀÔÔ&&&PQQAûöíamm --­oÚVdd$ÂÂÂÄ~–““>Ÿ¢¢"ö³¤¤$øùùaôèÑr뢄B!„"E$aß¾}¸}û6öìÙƒåË—ÃÂÂ6lÀäÉ“!°téRŒ?ž-Í›7×Z/ò&„B!ä_âÅ‹°´´DNNtuu‘œœ ©uÁápàææMMMhiiÁÄÄïÞ½ƒ¢¢"fΜ‰ .`ܸql™””$''#""áááìXp @!„BiàbbbpæÌˆD"èëëcòäÉðññ¦¦&ˆ¶mÛbÕªUPVVƬY³ê€´jÕ 0hÐ ,_¾%%%ÀãÇñÇ`Ö¬YÐÔÔDhh(¸\.~ùåÀÎ;e B'„B!„ü…h !„B!ä/C]°!„Bi Îœ9ƒÜÜ\¸¸¸ ]»vØ¿?ø|>FŽ ###8p0eÊv«… ²Éÿf;Ð¥KtëÖ §NB~~>úõë[[[‰õ௯‡~rûömܸq@Õ4^„B!„i/^Ä“'Oàéé‰ùóçcĈàóù°··‡··7Zµj+++¨««cåÊ•(//ÇСC‘™™‰ 6`ݺuuÞVii)ÜÝÝñäɤ¥¥!-- ñññðððÀ‚ ή{ýúu())ÁÊÊJf]ÿ¸.X®®®@@@Ú´iCw!„B!2ðx<ôéÓ666h֬Ћ‹Ñ¿8::BKK ˜6m<<< ¦¦]]] >sæÌAIIÉWmkÖ¬Y000ÀÓ§OáááÒÒR8;;ÃÖÖ¦¦¦ìz<@ll,tuuåæ¡1 „B!„4@NNN8~ü8æÎ Œ=Ë–-ÃôéÓѶmÛo®Ÿa¤¦¦"??ðòåKØØØúöí‹C‡aΜ9000`Ë MMMÌŸ?_êíð|rûömܸq””DWžB!„ŠŠŠšš >Ÿ‚‚" :uBFF>}ú„¼¼<$%%ÁÎÎ%%%8}ú4233a``€‡âúõë¸{÷.lmm¥êWTTD@@ >>Íš5ƒžž °°©©©033ƒ››rss! ¡©©‰ŒŒ ())±ÁJM”„B!„(%%€=z M›68uêú÷ï·o߲ݣFŠŠ \¾|0uêT¤¥¥áÎ;hܸ1ÆWë¶>}ú„ÊÊJ4kÖ œœŒwïÞ¡ÿþ€ØØX”——£Y³fxúô)†.·. @!„B!B!„BùËÐ,X„B!„4@¸pá:vìˆÞ½{ãÍ›7ðöö†ŽŽœœœ`gg‡­[·BEEÓ§OGii)Ο?’’lÛ¶ yyy ömÛ¾¸­üü|,^¼zzz‰DX¼x1‚ƒƒÑ¥Kôèу]oòäÉ000€@ @ûöí1sæL @!„Bù7PTTDEE¸\.àìÙ³øùçŸÑ¢E øøøàùóçØµk”••±iÓ&TVVbçÎàr¹Ø·oF…¼¼¼:m+>>öööX°`f̘²²2TTT ´´Tb½Õ«WÃÒÒ»wïÆ?þ(³. @!„Bi€ŒaooÏ&"lܸ1üO¯ŸaDEEáÍ›7ppp@VV–,Y hjjÊ,Ó£G$''cÑ¢E055…’’ôûš†—B!„¨´´AAA˜3g7n (((€ŠŠ ›½:@€ÒÒRÔe"\†a™™ eeeXZZâ×_ÅÙ³gáààÀæ©IWW;wîDPPºuë&³G „B!„4@ÁÁÁˆŽŽÆ“'Oн{wôïßcÇŽ…™™lmmqîÜ9ܹsÅÅÅX³f ,--ááá¼¼Edd$233Ù1$€B!„ÒÀ™šš"00Ÿ>}Btt4²²²àïï===x{{ããLJÃÁÒ¥KÁáp°nÝ:€··7êœ$//³gÏÆˆ#ÔÔT|þü+W®”Hž——‡„„lÙ²çÏŸ—Y!„B!¤²²²‚¾¾>üýýaoo^½zaøðá˜6mààà€ÂÝÝß´- lß¾k×®ÅÝ»wѹsgˆD"ÌŸ?:t`×kݺ5ôõõááánݺ5Œ$>>ÇŽñcÇžžNwÖ¿@~~>Þ½{l_AB!„òí‚‚‚°páB888ÀÙÙ×®]Ã?ü€éÓ§cܸqøïÿ‹N:ÁÃÃã«ë®¬¬„··7‚‚‚вeKܺu X¼x1^¾| ìÚµ OŸ>e˼~ý}úôÁ¹sç)³Þ\¬¦M›²Y´µµé®úHMMÅ«W¯Ð²eKœ;wNj !„BùzW¯^EZZ†Áû÷ïaooˆˆ899ÁÖÖ‰‰‰ˆˆˆÀ´iÓФITVVbÛ¶mÈÌÌ„µµ5"##‘ššŠ{÷îÁÉÉIª~EEE>þŒ{÷îaŒ1aaaxþü9ÀÄÄ)))¨¨¨€¡¡!^¼xââb¹o]þqˆ‘‘ŒŒŒ@nŠwB!„B¾w?ü𔕕¶¶¶ptt„€ªLænnnhÞ¼9`Æ ˆŠŠBÇŽáææ†{÷îaÆŒ‰DuÚž¾¾>zõêpssÃ=zôÀ›7o ‰Ð¥K(((€Ëåbذa #!„B!„|™‰‰ LLLä."bZZZèß¿?ûsïÞ½ë¼-===6øëÑ£ûKKKöÿ_êíBƒÐ !„B! @!„BÈÿµw÷1M]ÿÀß´´@[Úª<•‚ˆÕ¡‰8Ä€¦>dsD§›²Í)Ѝ€²Åe.Qƒ§b‚Ñé&™ºÍ©s*ø<' "˜‚ˆLÐɃ T¤€}þýa¼¿¡øýÞúmµÅÏ+1‘ãÇÓÃ9÷ž{?mï9„PB!„B¡„BÐÜÜ ½^µZ¶¶6êB!„PB±ž½{÷¢¥¥EEEÈÉÉ¡!„B% „B!„;L@9{ö,fÍšÕ­,??&LÀ°aÃÐÒÒFƒ+W® <<hhhxnÒP\\ŒÐÐP¢²²²Û¿UTT    Ûz¸µ÷¨­­455A£ÑP‡bCŠ‹‹qýúu °Þ—ByÌNèÛ¶mcn`íÚµ˜3gÊËË_JCQ__ß­¬³³“F¨ÈËËCQQ~ùåp¹\466ÂÏÏ:†óðáC„„„@­VC(R‡B±n’˜˜øJòôÖîÀã•vþùç%;WSS???””” 00:„B!„ž8peee¨¨¨@gg'âââ‹7‚Ïç#,, B¡ ,À¦M›àèèˆÉ“'ƒÏç 1sæLÔÕÕæÌ™ƒäädp8̘1ƒzŸB±‚ÜÜ\„……!==r¹¡¡¡Ô)„ûH@¦L™‚ &0?óx< : .„V«…··7 îîîÐëõÉdL|`` ™ŸGoooFxyyQïb‡L&4 nß¾††úª$!6èÔ©S7nu!ÄþËÝÜÜž)sww¦ŒÏçwKHþS„û`0ððáCœ}ú --:ÅŽuttÀ`0`Ïž=èêêz-¿&I !„Bˆ «¨¨ÀàÁƒ©#z‰;wî ÿþhllD}}=Œ®®®×ªm­A::Àÿ?8Gû Ø·'ãi2™ ÕjÑÙÙIcjÇôz=óç ÏÞqŽ>KNGcjÇžŒáÓãJìûÕh4ÐjµÌÏ4¦ö««« Z­–9OÇŽ‹K—.!<<¼×ÿî|>ŽŽŽp0™L&[jXNNÎ;8x𠪪ªèH%„B!ÄÎýú믈ŒŒ´½äß>ûì3Öæ466"==ñññ¬âSRR°`ÁH¥RVñ«V­ÂúõëYÅæç磭­ S§NµxÝF£k×®ÅÚµkYÅïÛ·!!!P(oKEEòóó1wî\VñkÖ¬ÁªU«àèèhñ¶ddd@(",,Ìâu·µµa×®]øâ‹/XÅ÷Ýw˜9sæ3›p>Ovv6L&&Nœhñ¶wuuaË–-X¹r%«øÝ»wcòäÉ0`€ÅÛRVV†7n`öìÙ¯ÛÜø“'OB&“±^ñÉœºU*<ˆeË–±Šßºu+æÌ™ƒ~ýúY¼-—/_Fkk+"""^yŸ›íÚ5ÔÔÔ`æÌ™¯¼-iii2d-^w]]~ûí7,Z´ˆU|rr2âãã!‰,Þ–œœhµZL™2ÅâukµZ$''cõêÕ¬âüñGL˜0´x[nݺ…ââb|ôÑGV9¶8€Ñ£Gcذa¯¿ªª —.]Btt4«øuëÖ᫯¾ŸÏ·x[²²²àää„ñãÇ[¼îöövìܹ_~ù%«øÔÔTL›6 r¹Üâm)))AEEfÍšõÊ碣GÂßßAAA¯»¡¡'NœÀ’%K¬ÒöÓ§OÃÝÝ'N|ü)ˆ-gI\.}úôa}£åââÂ:ÞÅʼn„u¼³³3ëX‘HƒÁ`•ºF#œœœXÇ ˆÅb«´E,C ˜]7ÛÄœ¶…BˆD"«üžfÅ»¸¸˜Õç"‘&“É*mwrr2+^ Xí¼puu}¡ã…-sWWW«´E«Õš59;;C*•Z­Ï=zd}þ"m …6ÑvkΣííí/t¼¸ººZ¥Ï5U~OFc3}þ¢×.¶¬Ùv‰DòBmg›€˜{¯cÎýˆ9us¹\›9^li.²æµ«££Ã¬¹èEŽ‘HÄ‹Ü5kÖ¬±Õ$33o½õ«X>Ÿ___ÖŸhøøøÀÝÝ\.—Uü€àææÆz‚ðöö†P(´xÝàççÇ:ÞÃÃ^^^¬'sÚâââ___ˆÅbVñçÎäI“Àáp,Þ–¾}ûB&“ÁÅÅÅâus¹\ôïß}ûöe/“ÉàááÁ:Ñ’J¥Édo;‡ÃŸŸëw×½¼¼àáágñsT(ÂÇLJõ“¹ç…9ñýúõƒ——œ-^÷“¹ˆí¤,—Ë­6¹ººB.—³ž‹ÌOk‘H$‚\.gýN¿5Ûâîî///899Y¼n'''³®]¾¾¾pssc=š3¦‰r¹Ü&æ"OOOxzz²ž‹Ìi‹@ €ëk—¹Ç–‡‡<==­rݽw磌«lÖý‚ƒƒƒÅÛbÍk—Ë…ŸŸŸY×]OOOÖ×Ý™‹¬uí2çµöµ«ÿþ¬ç¢ÿõ>ͦ¿‚µ|ùr¤¤¤€ô+V¬À×_Íz‚ ¶ÎQOBcJ^žŠŠ œ?‹/¦Î sÔ®Ùô' ƒ ¢£³—àp88p ëwbˆ}Œ)£4ž„Æ”¼ðöö¦Î sÔ¾e[ø¤¡¡§NBxx8žW[[‹ßÿJ¥’õCÕ„B!„XKee%Ο?±XŒ¨¨(@yy9²³³1uêTôïßð÷ß#''ðññܼy¹¹¹˜6m“X–––â?þÀŒ3àééùÜ×-..FAAfÍšÅúë6“x½êÔ××ãôéÓP*•¸rå nß¾ýÜä###J¥yyy¨¬¬¤#žB!„¼2wîÜANN”J%ÆŽË$$yyyP*•ÈÈÈ@mm-ÊËËñçŸB©TâÌ™3¨««ÃíÛ·QPP¥R‰S§N¡¾¾·nÝÂÕ«W¡T*qüøqܽ{·Ç×ý믿PVV¥R‰Ã‡£¹¹™s\¼xÁÁÁP(ˆŒŒÄþýû{Œ;{ö,Æ…BéÓ§ãÈ‘#tÔBˆ•´µµA­V¿ô×U©THJJ† pÿþýçÆ555uÛ sçÎ4h„—îèÑ£ EGG³›ù‘#G0}út( „‡‡###Äûï¿…BÐÐPœ;wûöíCdd$ ÆŒƒ‹/â§Ÿ~Â'Ÿ|…BÀÀ@äååõøº{÷îe↊ÂÂB»ê7z˜Bzû÷ïC§ÓÁÁÁîîîÐh40 P«ÕLYOqÀã•uôz=8ÜÜÜÐÕÕ…Ó§OC  <<œ)ãóùxøð!ŒF#úõë‡ÎÎN8;;ƒÃá@­VC$¡³³“ùû£Gþã*6*• &“ <Y5ìСC˜7oR©&“ *• ÀãÕ¦$Ií0hiiðxYI±XÌüÍÍÍÝÊ„B!T*\\\àêê ½^{÷îS¦V«!ÐÒÒ”Bz¯}ûöaøðáèììDCCu% „Òû•––âĉÌR¾#GŽ„Z­Fff&† 5j<==qæÌ&nôèÑèÓ§233Ááp`2™‚¾}û"++ |>uuuXºt)nÞ¼‰£GB €Ãá ,, ………ˆŒŒ„\.GRRRRR°}ûv¨Õjp¹\ðù|Lš4 !!!Ï´9++ EEEƒÁ€wÞy§ÛæZAAAÏÝlëòå˸zõ*ŒF#†ލ¨(èt:lÞ¼ÎÎÎÐëõøðÃQZZŠòòr€^¯GTTT{9rÕÕÕN‡¹s碰°W¯^…D"N§Ãüùó‘ŸŸk×®A"‘@«Õ"66™™™Ì ‡V«Å’%K™™‰²²2ˆÅbhµZ$$$°^N”b–-[™L†ªª*œ={–:Ĩ¨(¤¦¦"??>Ä¿åš6mÞ{ï=DGG#&&Û·oGVV:;;YïŽI!½Á`ŸÏgÖWûí·‘––†˜˜„††B«Õ")) hoo‡4 rss1`À¼ûî»>|8S—ËŬY³  ¡T*™deÿþýX¿~=ÚÚÚP\\üÜö,]ºÉÉÉX´h²³³{L@rss±bÅ …B\¿~7nÜ@CCŽ;†ëׯcåÊ•ð÷÷ï±þÉ“'£¨¨óæÍcÐäñxX½z5¸\.²²²pçÎ\¸pÙº¬¬ 555=& ÙÙÙ1b€Çu644 88µµµøüóÏ™d'((MMMHHHÀ•+W`4QRRÂ,¡¹k×.´¶¶bĈÐjµˆŽŽFnn.ŒF#¤„ôRAAA8tè¡Õj1fÌŒ7)))0HHH€ÉdÂæÍ›™ODãââ`2™°iÓ&H$p8,^¼³gÏÆ† ˜›ccc™×0`ÒÒÒŒ 6`ݺuèÛ·/œ1þ|J@ÌÁáp0þ|ܽ{nnnÝ6ãÚ½{7³Á ‡ÃÁÂ… ÑÔÔdÖ¦]„ÒÛ¹»»cêԩ̆ƒÉÉÉ4hnÞ¼‰ÐÐÐn±ÿ^mP*•âØ±cÌ¿ét:TUU17íÀã¬kjj P(Àápààà©T ¥Rù“êêjDDD<7ùxZKK t:Ÿ2! ^.„0ÅO§Ùk¤|èë˜B6Jl¶#lB aö¿…ïY¨Lp¼þtý ¯„,†¨4K Qzºb•se›rÿ½‡¤ê“+7þxC½ Y:ØŽp§'•¿z”1êd@Èâ–òè‘í¥a¤ …lÇéHoßèÇeøþJ_½Í>ÐXÈÊÖÂ0²”RûŒR C Þ^¡ý†-€½J¯Äúݱ}´° ž•¡†…Ưï0F­½Ÿ·pÒêéu¨=½u°oÞk(¦>W(gúÚ…«;{Í µl÷¦¹úþÙ:\ý|J¥~×µ&µ¾Cj]iÜQ†%fW×q„žÛÚǺž/%¶Ã§ß2h­ëÚ–ËèjT3h­Û.µ×gePóó-œ´èÝ^þ qõN­eF Yó“ Ä€ÞÌ-­Ì“×Ü<}ÍO ×^~ËW~e`ùÊÀo`ùÊ Ä:|¥Î\OÀ¹=Yë‹(S[îôC…¬½°t „+€ÿ~Ü]ðÑéäa²¼xg° b;Û!¶C(°~):€r„,!  MÍ\“Ð=YB@›æ;–ûàb:örÂÚ:3ìåˆÜ×?Í)ó±¬DÊýæs§Ʊ—örDîßWrÊìç EF3RO´XWY4YqÍÀž­á~-Õn|À+*ÒåŒeáÏXüåµ£×ןÿ=ÍÑ|r—{4ÆðxO–á lÕ [g%·z¸~OwôúÙr·æ“»\î©+js¯ä”ÛBÖR!¥®hîôôa+À¬ßÛú»Ô¸ü½ù¤Ö[ÜŸ-¶ŽÙ[9"÷õ+9e¾»0r*%ŸÖ/¹¡ªD@‹1þ‰z·ž9öï½—óú•œâƼ¾’Ý:›ùûõ­é÷þN©@S΢ Xc Q ÀÞ¡GÀ›» €€@ɺ@O@9ÿD;ÿ –yëIEND®B`‚snd-16.1/pix/mark1.png0000644000076400007640000002205711147553267012675 0ustar bilbil‰PNG  IHDRBÐOeªsBIT|dˆtEXtCREATORgnome-panel-screenshot—7w IDATxœíÝO¨åÖ™ ðsƒaf¼²«cfU±Ù 4î1 Y„2ØMYd[ØÐ&0`ºW“MÀžM3n˜e{eSày4.j5Û”¸È¢i0†/쮥ÿT ‡Š‡,î,Ê*ëééÏ‘î‘t¤óûAQïêêJGÒ½úô}:’ÿôOçÇPÇBáÏÿü¿®Ý€E¼ûîoÂwÖnÀÒ$B@q$B@q$B@q$B@q$B@q$B@qûÃá‰Î÷ŽÇß·ŽÛÞ6­®qæ2f9Ú>;vYçÒÖ–®ákµ1VÛ6™³­¹¯€-s<3­ÊÜÇh£¡â54^õ~_R2§”+7fZS¾ )å|ÀŸòû¹œ×@‰–ÌtŠ3éŒPŒT§µ–î.54ÿ®³±ï§>Ýw<þþÒÙ¾nq}óZשÏÚŒUͧo›Ä®ë”ëcè;²öw )މb¿bLJ„bfœâ´ÖÜÞ1°cj»–µþþZÀCm\;ɉյMªa±ë:ÕújÏVÖ+À)†ŽùS_GsÜ>dÖk„r7e9Ú2Эu ŸÛwoj{r[€S õŠš{^SÌÖ5.Iǰz÷¸Së:½®ÄY"”&·cÍì!ŒË±®ç¡k@~Çšî7RÊL6·¬8V×EjKÍ{ÉÏj«Û W©Ž¯¹k\׃+‡Æ™»[ÑÐÍ ºîHѳ¬mŸMý£¾³ )Öus§vÅkkßü»Æ›²®—úîéLs\½Ú]ãR=L5å8Sœ²m#õ|§ˆ¹KÚÔÏw³ôCiS—b}t½?ç:ÈMÊc¢Ôǃ}tŠ#Š3ªk\ì…I¹w²yÙËr”fé㸔ǃ£¡½ˆZ޼ìe9J³åã8]ã€âH„€âH„€âH„€â<Bï¾û›•›°œÃW_}z\»KÒ5(ŽD(ŽD€Ýx÷³ðŸþãw×n Š#Š#Š#Š#ŠóXÌHO>ùt¸ÿ³G¯ß}ç,¼öÚÏþþb¶†ÅxòɧW?ë¨Ç¤1Ä3€2ÄÄ g„€âDúçÿ÷Ï!<þíëŸüâ§á_Ã'†…Â÷<‘²m”x@%* !„óç½ïßyûNøÍßü}!„—^úo£ò§ú_¢Æ{óÍ_Žž6TÄ3B‘õÜsÏ^výúËáÖ­÷[‡ÿÃ?ü¯ðüó?|4ìÚµC!ܽûacØÓ7:ˆgû´Ø5Bׯ¿ÎÏ?ü»¨ñïÝû$Ü»÷ÉÌ­€qÄ3€}X,:?ÿ „ÂüƒãVÕ³Bøè£ßÎÖ&fp8<üÇtÖdM<›@lHÃ:„¤I„®_ùÂë¡*Z½röÊ+/ÍÒ&fr<®Ý€Ùˆg‰ @†I„ªêY¥¯ŠV¯žUŠ®¢m UZ [âÙbCzâ$5{"Ô¬žUºªhmý¨‹®¢å® tmݺºBTÃÇɮϴ ¯¿nû;U›¦êj_Ûë¡¶Õßó9`4ñl±añ5{"Ô¬žUÚªhmÕ³JQU´Âáp‡-ì ªêÔñx±Ru8|ûº¹#¯Æ=ãvÂõÏ4‡×ç]ÝÕ†Tm:ELûbÚÖ\þú°¥— žP‹ ‡¾gbC?ñ}ûì;oß=ñêÎ:]>þøw—nKzvvsô|ÈP=Aj«DÕðš‰×PR·éT}í©ë{¯k} } &ž­Hlˆ#>À"¢¡?ûöèár!„ðî;gáµ×~þðõ½Ÿë !<¬¢}þù·Ó¸{÷à Ï^`§Æöq®A=`UêU¯Svì9÷»žÚ¶œ— V"žeLlO|€“ÌÖ5®«/uSìs(ÜP·€™ˆg€Dw›âöíñÝ–V¿ç8a§ÙwÏ”é¡Y½k«æµßÕm!ÅzÛ¦ªy U+ûÚ6õ=`ñl}‡Øpy>âÌj¶DèÖ­÷/õ—ÎÍáp¸°so¾ŽU|ÂÓ„Ú.ÎlÞ©&fýµ],ÚœVÛÅ¢mmHÕ¦Su]ÄÛ¶©ï£ˆg5¯Á©wcú‰°ˆYÏå¬-HÇÉÁ£x]ë¬mø”~à±ïÅÌ/E›R9µmSßv#ëxÖv@ßü»oØÐ´cßÛZlh›·øÉ›¥ÖìR°zð€ Ä3 ¡ÚªnYTâÈS³{@&ÆÆ³M<ïnKÄX”DèD’Fó24×5E’¥ÄX”DˆéR·1`ÍyÏeË”§¹/k^ì?Vé±!„ý.¬l¶çäªØD¨º£NÝP?è¶ÓûNù°&ñ `𢻯5ƒÇÔþÑmÁõC,E<¯èD(„ø|ßxʼnØåžãî7kÎ{.{\&`1Ùijæ4Úž#T âìu¹`eÅvÊ%Š#Š#ŠSüÍ€4܂؉DÛ]ç$G@®tŠ#Š#Š#Š#Š#Š#Š“Õs„®]{qí&È* !„{÷>i~vv3¼þú¯nÍ~U¸k>üîp8´>€x {ùË.*Ñ’OÝnKtšI‘dàt%ö–Œg§š-º~ýå¹&½;mIGÁDB ž‘k<h3ë¡óóǹ}ûNxë­·ælߌ¦ÏöÇ]ãè%y`$B@q$B…p½|K"TÝÛà"‰Q$Sì‰D¨)ºÅ•˜ UË\â²ÐNl€}ìx<¶îÄ»†—¢+À•¼NJ'6ÀþH„v¬/É©Ÿ!:Ã÷nL@+=Aà2±¶kÖªÞ¾}gÎÉÀ"ij²4 ƒاÙ¡[·ÞÏ=÷ì\“gÀœ;í­ßŠ»-ÀÕψÕ×J žÅÛòþrë± O×8zÍ™¬0Çλ·ìæRuµ®ÿ+—ØP¿&(v9ÄØ‰Ñœ¹Èº Il€ííÌ\;àÔgDr ºD´x PÛ$Ú¹9ð«éíe§ß\?±­>Þ^ÖÀZrØ6ïœZ¡Sb7‰ÐŽ9ÃqÑÔë‚ô د)±¡ï9|õéVÿ€ Ó5ïµÛÅEÍ‘)ÛÆödo|§çS_·ÎTQ*‰Pêw–{pšª«éÕËÚýÃë [[ÀS\NÛºýL×Sïûæa{²¤SâÙš–ŒÍG/与š1A|XßÔ8Ðlˇ$BhÞ]F2“ÞØ$1å6¨÷{_²êvÊ|r Î[–ò OªiÙÆ¤–2žå çhÓϤ«bbóÚ¬˜e¿1®ïÀØâøÔùNýüÖI„6¬ëvŸus’wŽÛó)ùœ¯»j®ûæß{Þ.9èJLbº[ÆNoì¼›ïÙþ,¡/–ͽZ³'ÅóŽ]—C7²o˜_s_\ }ë?õ¶Ù{LÁJæØ¡´U’b ;ôÜ Ý"Ò:õlÝÔa@šgËbrO1vºm]ª·~g¿­h®Û¡ëÛ>Ó7½SÏúí)9’mÐЗnêVìukW™R¬›S§±T7ˆ·PìN7œbÏÅtaéÚ^±×u ó`i9v‹kÚB‡´-ÃÔ³ÑöÓŒI*†zÿ4ßo‹-S g{í2)bq{u¹,ÏÔPÌSÔ—ìþ§ Z_–¶ŠjSÛ{1„®a}ó› ÷´}Xßš]Ór³ÄÙ–©]oû¦²×6íQÛ¾zh[}¯9lJá,ÆÖ¶‘DhCÚú‹æbè®hs\ìwjw µ×ßœÝεls®³ßRqóÙØiÈ®$j¯Û‡üM örF3U»«Ø1å÷'¦p¶D;š$B™ÛÚ’\2ü-¬ú…ÂÆ«Zm;¼˜ehž²ïªð5«€sy4—ª ¿·µUNÓ¶=¶ö½ät}3—ºÀn,YK×Ab³ðPßUŸÛƒ±û’¾3Dµ7ª‰oÐñx)O±—í3¤™ ýºWʼnPæRô]Ú¥ÓF]§“ò@êðÍ+Œ˜ÿRÚNßG%µƒ‡µ¾]‰L_ßïúg»ºFŒéB×uнäºèªdÖÛ×6^.ÆlŸ®Ï‡×Wœ2ôu{ªÿÃ÷ck15j¼Ň¥ Bmí¨ÏsLw´®6Ǭƒ¾bXW,™´^Zbð9ÿæhÛ˜i.¹^$B™ëªtçöãi¶ñÂ~BfßìV3å`·ríž“j{.ù݈MdÆ^ß6fÜæû1Ý/ÖpJr6ö3}IáÐoghØÐ¶Ì9 “Kgpk•õ1b¯;éû|8>¼–&çïîØ}ú±Vøk~néc‡¾c—¾$e(>t]¨¶m›æ¸çŒÛCq`è3±ÓV—ã6A"´ my9%D1Õž¡aW·šØîOmšA!W©¶áœ¥±ªíõضäðžCWRó¹˜à;¶¶Ä‹ÝöÐåÂ~ápuƘŠÿÐÁw½ªŸ“æï,åokì>c¬æ1@LL{–`J,ÊÙ”¸Ýu|4f:}1¤y¼Õ;šã×ÿŸû{–šDh£b¥ÅT¡æ´ºþ™ß˜y/aÊÎjŠÔ˺äzÛÊŽs¬®*fWª>Ó DCgãúRýLmÛÁV×äÔ„bÄVŇ„˜Jö–¤nsýwœzÚ1Û/UÒ²µí«-qÚç7_ý~†Þë‹CEé-Ç Tݰút+Ú~h[ýñÔå¶ R%Ê[<€Ø‚æöéÛVÇãŇw¤úøCÓi; l{ß¶gMU|›²Š-šåXT\¢=©âCµmì+NW­ÇfA«þwóx©¯§@ó·3T«·£ùÿPìh¾·%ÎíÀšg;RÎwíÑë0¦r–JÌ÷bè”÷ÚÛdºÎĤ®ªn=8Q޶37%a¦tyâÔu¼‡âeîÚŠ]}ÝOÙSzÚìi»K„6®™é×ÿ^ê ~¬5·Ö °]Õû¹µu;é;ÅÍrb‚OLRÔW¡N7÷u5)jSèë*U¾v;÷ªkßû]Š âÄE¡é«ìÏ=Ï)ŸÛÒø)•³¦¥—·ù½Ør_Þ=²þᡵãš=+BX'6´ébÎÙo-ï”î¡S§Q×íÔÜgRŒ¥û÷­“SÎØ }¶«íri@›RöMm×o¬¡ž 5cr)Û"w¶Ã¼œÊ@ê„¥þ£qúú²®ê×1ë5·uŸS[º¬uf¤®­ qêv­5Û%’e m'”"9jëuŠÜìSè:“Ów'–¶qÚ>Pš-ïûÚ®µ#6Fì1–ÂVéW€êtwß-» % [ÓuÁà˜åé»ÓšÛ‰%«w±ÚÃ~°Ùþ¶}~ÌëSnÌÇ!:µÝUlËÕ¾º¾ @ûºBôõéܶ)æ®Z}½ªñ«d§ùZ|€;»¹v€Ë*º{÷Ãðüó?\»ÀÎe•À^èá7‰P(ììÏwæžÁ /ü¨uøíÛw. »{÷ÃÎé<ÿü“µ©R%CÕ¿©ÝêÓ8eZäéÖ­÷{ßï*ìµýû»¿ûIÛVÅ¡º¡Â^[w5]Ø€ÒÌžu®.W¯~ÿÒ°³³›IÛTw<ý‹oh1Ó`{ööeöD(„ËÁ£-hTÚ‚ÇAÆPØØ—E¡fðº ôêÕW¿ÎÎnÎ4` …=€ý˜õf uÕ…¦Í JÛTÁCÀØIŸíã1„µ–cÍyÏeËD±¶vÆ¡y ˜Â^áÑuAâ@>K„nÝz?|üñïf¹½(,EaošK…=E²ôöº\m΂Ùl‰PÛ“¸‡žÎív£¥Þðs\ô5Íj§9ï¤íüfÞ‡0Ïi•u:r}FMs‚¹.¢ÞJ[·2͹¦[òEô {û0K"tóæ¯GæÍ7BøcúÆÃaÔÁ{R{<`[s}BAöNך4O(ê|ûÑñŽyo©hÐ:ÝÖiç4ØüzÍpšsMwKmMa±®qBX÷à}‰Ã— 2¢°·q!½½.$¶È]ãà‚5û/ï±ïô— (‹¸Þ^— ’dŽS’“§Ù³ƒž¥õù% Ù¬Óeʦ+N7µÒ×éV¶"Jo¯Ë‰H„X —Ö— (Kä~l–D|¦kV/pŒˆ «·uåiÎ5Ý-޶´^S±.ÉPZ{\& ,âBz{].8‘Dˆõ ziíq™€²ˆ éíu¹à¡Låz q6‚^Z{\¦÷{‚=ÒÛërÁD!ò°æê’÷¸LÀ&%yÞÏöš4ìu¹ ¤ÈwºÙž#ôøã2jü¾œ©%y9Ôv@§|SM' ’ ´ö¸L=R<¤mW¿'Øñ!½½.L0ëUc“›7Þ ¯¾ú³Î÷¯\yæÑß_}õ鉭ZOó€mê\ªédAKkËÔã ²¹«ß³PØk—¬°Wûì…Gˆéíu¹vH‘o³&B)\¹òÌ…ä§ùz+Ú¾ÐÇãqô=Õt² È¥µÇeêQ}çOI†võ{bVköúdÚ¾§S|NE“ {Çã…äçÑkñ!½½.×)ò-'ûDˆäÒJpf1ö½äÞ>h3µ°×—ìt{ 5å€+Ya¯‘…ððŒÐ!„°Ú¯{¯û•½.×)ò-ks7KØâÙ $Aiøð·ÜÛs:É~)§•„ø^fËÕw€ŸâLÈ–IT–·¹DˆäÒš¸LU°9—Ïа®÷J`0ÖR…½Íü>Ňô6¶\¥'¥/ÿ²íWïG]ýílÐÆ ri°L}§È»NÉ×?Óü¿¢šùÙÄoR|H/ÃåjÔšñ£oX[¼©lâ;N–²M„ª¤g«7G AK+£eÚD¥V¤°7@|H/ÓåR„#7Ù&B{3ö‡ÛV™2,rie¶LY÷¾±«ß›£°×C|Ho¯ËÕ G ¡5«S¶RM*©þ—J"Ú®SªŒ¿ßŒ“¬°×ò¹Å {ýïu¹ZØW+ò¥ ZXì—ph<_fNUOÚú]wÝ~³kmïÏeJ²“rzP:…=RØZnnŠ|Ë›5ºq㽓§¡̧«Ÿöаúk;WXVýফ"Ü6~Û8c§U§°Ç[.ÂÍM‘oy³%B|ÙûtmØŠœ {)–(±E8r¡kôPØØ'‰dlL—5wÒˆ'€L¥¾f€om:ºÿ³µ›lЦ!Ø…=€å}gí,mwg„þöoÿçÚM`o¾ù˵›ÀŽì. !„çŸÿáà8×®½BáîÝý À2êûÞ»w?ÿḜ¹UyQØglÁl—‰PŸk×^ ÷î}îÝû$œÝ|”4Ý»÷ÉÊ-(CsßûôÓWÃÕ«ßJˆJ£°”j‰‚Y1‰P= /¢ñö€½Zª`¶û›%\»öbxúé«ÀTÏ™nâP¢9âÃn!`»$D—‰kiãÃ.¡ª»ÛvïÞ'á£~»v3V%¸,EB´ËDèîÝÃÙÙ͵›À‰êýÄK¤°ÐÙ.¡Þiç³ÏîIˆ6èììføì³{E'A!(ì 9¥`6Û]ãnÜxoÔø¯¾ú³YÚQ%D}ôÛðÊ+/Í2Ò¨Zé P8pYŠx1ëí³_xéÍÁq~ðô!|ýõ¿‡¾œ³) @ÆrN€öò‘2^¬ú¡<}X|žõ@R§ëÀòrN€êöÖ5G¼X-ª’ üìBø¿I§s÷ˆæ8¯¿þ«¤m`Ø^ö½ {ó˜³`6{"t1á¹8¬Ï•+Ï„¯¾ú4zxå_þåÿ„¿üËWF·€¼Ý¼ùëµ›ÐJa`>sîÓfM„ê Ïž>„üìxaX=9Jé¹çží}ÿúõ—C!ܺõþ,óÈUµÿËÁ­[ïGïsh·Â@ÞÆÌfM„š‰ÏÔ$h(Xĺ~ýåp~þA8?ÿ ܾ}g0aØ£óóÖnÂ…}ðùùá©§¾^xáGÙ¨ö€R­Yˆš»`6{׸f°XC= O9'D {@ÉÖ8†^¢`¶ÈU窔 ¹~ýåðÔSß•lHðrèW·V,«×€’¥Ž‹$B!\ SªgW®<ý€9(ì¬/UB´X"¸R%?U‚æköí7ÞX» ­ööaÖk„žýÏ—o#úõ×ÿbo/ÚLzb“ ªïàÇÿ.üøÇõˆ5æúW…=€y¼ñÆ']#9["ôê«?›ýéÚCž{îÙðùç_Hˆ6¤º@6§(ììÏ¢]ãÖR%D·oßY»)t¸}ûNøüó/²J€Bø¶°ûoâÀ·RÅ‹ÙoŸ“ú"€Råv0ã \éé”,u¼Øe"4t‰ÜnÉ °¤·Þzkí&\[{¶@aXÒÚ´¹ f»K„nÞüõÚM€$ö€¬]°škþ»K„`öæ%`Qÿöøï£ÆûÞƒ'fn %‹J„îßÿìÂë¿úëW¾þb–°çÎ{ß¿óöð›¿ùûe@V–*˜9#@1ö¶a‰‚YϨë<#ôî;gK¶€Büä?/6ýÕ_¿rJs(Tg"ôÚk?_²â_Ã'QãÅÆ¡¡®m {Û²TÁ¬3Òg€Y<7Zª8¤°°-KÌÜ,€]SØؘ… fn–'êŒÐ“O>=w;hѼÍ+À^ÜyûÎÚM pºÆ°¨ï=xbµ‡¥>ùäißc>÷ïÇ=@(Ã3‰¥ f®Š3ùŒÐápxô÷ñxLÒ˜ÒT O¾°IDATë{üñ?5þƒ_ÎԒ唸Ì0Ö¤D¨yÀîÈYìþï…W_ýÙÌ­YÆÒË|åÊ3þþê«OOžÞÒ‡'Âñè•TºÖ§õLŽJ,•¸ÌmF'BmIÏñx” ¬J~ê ÑVn 0'I[ `ÖmϳÙo–Pu¡›’$UÉU½^Û´šï7ÇéJÒ¦$o±óÛfI$@¼{¼ýú'¿øéÃ'’w<ŒïÉp1驯%Có©Öo=é‘Ayr,˜e׸¶d¥>,e’3¥-mç´¹-ÁòÓ¶¯W¶®\yæR¥«9¬zÝœVÛçú浄ضÆN«i캫;p>jþwÞ¾þ÷ïÑë±ãU²4å¾+ájN«-!‹I ¦$±óÛæ¶vÔ§# r1{"tj2²T2sж®‚S¦!‚¼u”÷¬™V}XÊyjl‚Ò%—å©,}0Þ–Ô‡-Ù…,v^SÚÜ–`Õ“ª¶3D°' fÓÛ‘º`6$û3B9éJVtkƒ²MÙOÝi¯‘4äÒ—{m§¸/•Ìœ¢9½)ÓožEjk§dˆ½R0;­K/Dh¤¥ºáùi«xUÖS¿ðÒu]5GbÒ5MI%Q0ËÓèD¨íq}‰À)7KH­~#ƒ¾ötµy΄G·8؆\ªo[ÓW¹dkÜÉMòÃÞ)˜fé˜0éŒP³‹ØšINLwµfò3õvß©ºÆuÝUN2y›Úµaí6ä:Ï¡u“[’tÊÍR‹½Ö¦«Ís&<îÀGé̦Y£`6¹k\ìÁÿ)IR×g§Üœ`Ìg¦¾×÷~Ìüs8kt‹©ô5ÇéúLŠy-eì»Õß}ë¥mXªu«yÀ^½F²Ó]­™üL½Ö&U׸®»ÊI†(•‚Yúéžòþ×»wãÆ{Ã#EŠÙÑÓõ~sø)A%å2‡0}™†ÆI¹ÌcM9èO=¯)7'ó™©ïõ½3ÿΚÁ̺ۑcÁL"ìÚƒ_.úðº?,½Ì©ä°î€2)˜n‹3‰@B©ž¥P"ëXƒ‚Ùv¤^w!€ÄÖp)-½,{Zwm}¦K½î¢¡û÷?›<à[{J|¶\0sF€MºóöÑŸ¹ßEüç|Îçó9oçž{Îû4b†!„©Q¢& „ ¼„B—B^BQÜÀ{ëÖ-<}ú´Âe„B!–/_Ž[·nQ‹’zóôéÓJÁåË—ãìÙ³Ô`D6/ŸÏÇœ9sðêÕ« W²lÙ28;;ãÚµkˆŽŽ–˜Ç0 +ü‹ÅÔ¤FÒÒÒàèèøÕ“„9sæÀÙÙ±±±¸qãF©ù_«ÅÅÅÔØÄb1·5 RÑÌ®]»ÂÕÕõ«+‰‹‹ƒ¥¥%Nœ8œœ‰y˜8qb™åòóóñðáCìܹnnnÔ¤ÚZµjooo$$$T¸ÜË—/aii‰{÷î!++«Ô|›rËÞ½{nnnعsgƒoïÐÐP$$$Ðq[·6èééáÎ;eÎKHH€±±1õ‘åUhÔ¨5©ûK e9|ø0ìíí©åˆÌ»páìíí‘‘‘AAä猗Ïç#88JJJÌ„ ˜Aƒ1NNNLZZZ©åÞ½{ÇŒ5ŠáñxLZZãääÄ 4ˆ122bîܹÃ0 Ã\½z•ÑÓÓcëùéÓ'‰uÐ}¼„z•——‡OŸ>•9Ïßß™™™€'NÀÁÁÁÁÁ8xð x<^¿~ ‡ƒ"888qâDµêsss=z‡Fjj*{Öú¥ÈÈH„……±gµ©©©8|ø0<<<àïïøé§ŸÀÖ³dª}—BjÓˆ#0cÆ ‰ib±GŽÁðáᯯÏNwpptïÞ&&&tïÞ]b~MêÒ¼ys˜˜˜ÀÜܼÔü>àúõë˜>}:ÀÜÜÁÁÁ011­­-»Ü¯¿þŠñãÇÃÌÌLâò^BˆÌzøð!¼¼¼Ð±cG4iÒDfê5lØ0AOO ®®Ž6mÚF®]»LMM{öìAll,š6mJ—"Û®_¿Ž€€ >………4j¥äܹsS’"·—ÔÌäÉ“Áår1yòdj ¢0D"ÂÂÂÊ×;wî„‘‘&OžŒƒ">>ž=ÌÌÌðâÅ p¹\€±±1æÍ›Wízp¹\6ͨQ£`eeUær×®]ÇÃÆñàÁöI6333v6lØ QÏ/)ü}¼1118pà€ÂìÏĉqúôi:R‰ÂðööƘ1cÊ×ÞÞÞðõõEçÎqàÀ¸»»cÀ€HMM…““bbbàää„ÔÔT 0îîîÕ>ÞCCCáêêŠN:A,cÖ¬Yˆ‰‰)µÜÝ»w±páBèêê"&&³fÍ‚X,F§NàêêŠÐÐP,_¾!!!l=ÓÓÓÖ¯P(ÄÿýßÿÉ\½‚ƒƒ1cÆ Wjy888ÀÐÐP¦öããÇ(,,DË–-)‚jqwwǤI“ðŸÿü‡–››‹ gÏžxùò%ÔÕÕqôèQœ9sC‡…µµ5! abb‚={ö qãÆ8sæ .]ºT­z|øð;vìÀÔ©SQ\\ ¡P¡P(±ÌƒpåÊðù|¨©©ÏçcæÌ™XµjÄb1233‘››‹ÌÌL<~ü***pttD~~~Ã:ã=þ¼LÖKUU•MoW………PQQ’’luÙüÅ‹#55•"©ö±Pr›V‰gÏžáÊ•+HHH¸Ö®¦¦hܸ1TTþ9oTQQAãÆ%æ×¤.5’Xç—.\ˆo¿ý'Nœ@FFºwk×âöíÛ D“&MàììŒcÇŽAMM 111øðáC©õ(|àݶmì:"qÃ;!µqùAYYM›6ÅêÕ«±oß¾z¯Ó¾}û••…¦M›âÌ™3˜3gÎÿ.¨¨ I“&¹ŸàæÍ›èÛ·/´µµVà-9Klˆ·®"¯’’’pìØ1Ìœ9§NÂíÛ·ë½N%OÌÍœ9ÇŽCRR;ÏÚÚsæÌªª*Ž= ¸ÿ>D"¶nÝZêŒ^áoïÞ½ahh(—²²²ðùóg´nÝšŽ,B*——Ç~!õåGõû÷ïÞ¼yƒääd@rr2û‰«d~u=~üyyyëÌÊÊÂßÿ-Q—ôôtäåå!++ —.]Brr2ŠŠŠ‹¬¬,Ü¿ذa444JÕ‹n'“¢—/_"## øêÛpåÁÇÁçóñóÏ?ãÊ•+åÞzCHENž< >Ÿü .„µµ5fÏž ÃÏϘ;w.²²² ccc´mÛÆÆÆX¸p!úôéƒãÇãСCÕªGÿþý1wî\|úô ‰‰‰(,,DÛ¶mñòåK„„„`êÔ©puuEtt4nܸkkkäææbÿþýhÚ´) qûöm:t?üð>|ø€üÀ?÷„ùÊ4…¼K—.…¿¿…oŽ%Õ—˜˜p¹\p8lÚ´‰…T™¹¹9Z·n &´´´°mÛ6üõ×_€1cưÿ©Ÿ={"‘LJ™™ôôô°{÷n6¨M˜0¡t^„JêÓ§~ÿýwöLÛÄƆ†ÐÐЀžž:tèäççcøðáèÙ³'455€¸¸8€‹‹ ÌÌÌàïï‘HÄ®{̘1 çŒ÷¯¿þ’ÙÀÛ¸qchkk#-- ­Zµªór„Ȫ?\PÂÚÚºÔ´²‚ªžž^™ËÖV]455¡©© e~ª366.õîׂ?%B¯'úúú°±±Áo¿ý&•r„ÙA·^^^Ԅż‡ý±··—Ù†¹té²³³Ì@¨èM¯ •½½½Äx%µïÓ§O˜7oz÷îyóæ±cðÆèÖ­¾ûî;öúmvv6ÆŽ ‡ œ8q………8qâ,,,Àáp0vìØ·B¡ÏŸ?/õ6‰’yýû÷‡ÃA·nÝpãÆ b×®]èÙ³'úõëÇîƒ@ @çÎÁáp$ö¡Þ/ÇcþýI–<~ü˜MrÑ\¼xË–-ÃÙ³g)ü×¹sç$Æ+©}ˆŽŽÆñãÇÀÀ@ÿ$_±bæÌ™Ã¾9xÆ ‰DàñxØ´iV­Z…¨¨(¬Zµ ›6mǃH$ªÑq{ðàAxzz–™tÁ‚hß¾=x<V¬XGGGDEEaïÞ½ð÷÷ÇåË—Ù}°³³ƒƒƒx<žÄ>Ð¥RJFFÜÜܨ!ˆÔ 8ÁÁÁèÔ©ÜÝÝÙé~~~˜={6ÜÝÝ%ò€”¼{ÍÎÎŽýÂáp`gg'1¿ºÜÝÝTîü­[·fÏžN:IÔEWWWbJêòï} ÀK$ 2„}UuUÀÅÅ…‘T‰¥¥%:uê„´´4‰7ôN›6 °~ýz…LF¯°×ÝÝ}ßÑ?ü€Ó§OWú¡… ¸¸FFF2‘‚1"" ˜8qb¬?!!§OŸÆ?üP¥rŽŽŽøý÷ßüs/æóçÏ)’jyñâ$Æ`JJ ÒÒÒðçŸ*Üþ*ì}¼b±˜}c@£FðÏ+³*_VII©Êåê Ã0`¦N߀Põ3 #sÙÒˆü¹|ù2ž®B(ðVJÏž=ñêÕ+äää(ô~®]»?ÿü3u8!x‰´¼~ý¦¦¦Ô„Pà--**ªÎß|ëÖ- 2„FFÊÎÎÆ… ¨!^ypïÞ½:¿IÿâÅ‹¥’“ÚõñãG?~œ‚4XR¿«áË,OUye~~>ŒŒŒ¾ºì§OŸ ¢¢UUUvZ«V­ššZ©ò¤z¼¼¼ØŸŠ¤¦¦B]]?~D‹-dvìííòqUÒï—YžJen/Ï_ý…ÐÐPhkk#77Íš5+wÙ+W® uëÖèÑ£;Íß߇²LÕ’?ÿü ˜¦¡¡!ñº“ò,[¶ nnn8|ø°L'åùwö¼º|rÐ¥™5zôh<|ø™™™ÔsõÌÏÏ®®®Ô„(zà­Û¶mƒ§§g¬ÛÆÆ©©©”\† ¼äKíÛ·ÇÛ·oëdÝÚÚÚ((( 7?BW6ݼy666Ôc ¢K—.‰DHLL¤Æ xeÕ•+W`kk OOOlÛ¶zNN•\ºéÚµ+>~üXî3ù„Pà•!½zõÂãÇëdÝÙÙÙhܸ1ÔÔÔj}Ý£FÂÕ«Wkm}›6mª•œ ÉÉÉhݺµÄ4===¤§§×I?~ü½zõ¢#Pà­o=ª³½*ÂÂÂ```P+ÄþM$Õê=«êêêÈÍÍ­ñz–/_ŽÝ»wKL[½zuß]E‘ñÀ{òäÉ S¨B^"UhÚ´)5©±ÏŸ?S#ÈJ„.Ö¬YCOÜ‘Z1lØ0KtÆ[9‡Æœ9s¨·ÌÈ‘#ñÇPC ¼²èàÁƒ˜7oû÷Úµk%ÞHJdC—.] §§‡{÷îU:ð^»vŽ482‘ÌÀÀ©©©•^‡……ûÖO";´´´ ªªŠ”””2çïÝ»öööhÓ¦\ìe'# xËÊN¶jÕ*lß¾öööÔ#r€Ïç£}ûöPWW¯R¹‚‚4nÜJJòñ.e'# úRC}[´höïßO ñ_ׯ_‡¥¥%´µµ©1¡À[7† ‚[·nQCB(ðB^ðñãGðù|‰/ñÕ‚ H£˜ ¼õ+;;111èÛ·¯ÂwÞ¬Y³pôèÑZ_ïwß}===ܹs§Î÷ÞdA(ð*¸o¾ùïÞ½£^ÿ¯={ö`üøñ044”˜Þ¢E ¨ªªJåV*KKKDEEQg ¼²N]]&&&xöìY•ÊíØ±«V­¢^ÿ¯¢¢"(++ÓmR„Pàý:mmmôìÙááá2QŸÈÈH„……Éd[………!22’F:!x+/''Í›7—Ùú¥¤¤`òäÉàóù(,,”©º=yò ,@ll,Äb1vB(ðVÎúõë±qãF™­ßƒ°xñb$%%•{­’ÏçÃÌÌLêu{üø1¼¼¼páÂ$%%Ñh'„¯b¨ÌuãúÊ®FYÝ¡À[¡}ûöañâÅõ¶ýôôtܾ}“&M’êv—.]н{÷ÒH$¤©ó$9iiiå&¿)ÉNü“qìéÓ§õÖùùùHOO‡‘‘Q©y7†¶¶6RSS¡¯¯_î™ïàÁƒñçŸVi»ß~û-Þ¼ySîüâîÝ»5Ú·“'OÂÚÚZ"]cNN ¤–o!"" X¾|¹Ü” å·YYYðññ••úõëG"k·U«Våf¼/ÉN&ëôõõaccƒ'NÀÍÍ~õêUŒ= ¬¬\'_`CE¥fݤ¬¬Œââb‰iÑÑÑHMM…TÚa0 #7™ÉÊNVÑÉÔ7àèè†a¨AäùRƒ<:räfÏž-“u“õ/% ¡ÀKÎ70|øpjB(ðEgjjŠ„„z›-!x‰³³³T^—4fÌ!Šx/]º„6mÚ W¯^¥æ3IIIxüø±Äôôôtèéé5èNݸq#6lØ 1MYYÍš5ƒH$ªÑºrssË|Â"‡·Gxòä û÷çÏŸ¡¬¬Œ&Mš”ZVMM ÅÅÅÀ’%Kê<÷AFFrsseö©»?BSSSbZëÖ­ñý÷ßãСC4ê ¡Àû?Ó§ODZcÇd¾Ñ^½z@ ·Ï¨ûúúJ<ú\kkk<}úB¡ŽBä=ðJüÈ“êäc‹ÅhÔ¨‘L<篤¤†aÀår¿š…­GxõêrrrìÁQTT$—c5::¾¾¾Ýd˜Š´7øeR–üü|¹j¬;v€Ãá`É’%011©T™ÐÐPÉÄÙñ„ °bÅ DDDÈT»jjjVº=¥iÊ”)HOO—»ƒ:''ñññÝ(ðþÏ—¯ ——ìdÿ¶wïÞr3® :ááá:t¨ÌÖßÙÙYêÛ ǰaÃÊœgffV/oèøšÓ§OKüMÙɈÜ^j¨Oºººèß¿o¿Ú¶m[¹ó¾ÿþû*?!¶mÛ6xzz–š^7HÜ¿-[¶DçÎËœ?gÎìÞ½[êmùòe|ÿý÷tÄ"Ë·¨¨999ÐÒÒªµuª©©¡M›6ˆ‹‹«Q8p`­îëÀ%’”—¨Î»Ú’’’ ¦¦Vn‚ó®]»J-ù9!DF.5TDOOêêêxÿþ=”••qõêUp¹\™j0 Z„…:ãíСttt)õm}ÄþBRRΟ?Å‹ScB·òfΜ‰k×®!%%å«ËzzzVø0CC#‹QPP€¦M›ÊT½.]º„1cÆP"ë—ªz™È®Í›7cíÚµÔõlëÖ­˜>žƒ ¼ŠièС¸yó&€¯PSSƒ±±1bcc©1¡À[3ÞÞÞpvv†P(„……„ ÎÄûõë‡Ë—/ScB·æ’““‘ SSS _!‹é>VBj e —AùùùÈÈÈ@›6md¦NîîîUzjBW®¤§§ãÖ­[àr¹Ô„PàU,gΜ‘û—IJ‡Ã5!òxß¾}Ëþžœœ\¯;ïàà@#  äP>|Ëìd„o)ÿùÏØß){’üèÕ«Z¶lÙ öÙÇÇ™™™ÔùDþïñãÇÙßpîÜ9ê90mÚ´·Ï~~~ÿöÛo4H­ '×!„/!„Pà%„B—B(ð’Z°hÑ"œ?‰‰‰Ô„Pà%Ò ªªŠ‚‚ˆÅbj B(ðB©-”«AyxxàĉÔ„Ð/‘–÷ïߣmÛ¶Ô„Pà%„"•À{æÌÜ»w¯Âe2220jÔ(œ9s†Z´øúúR#Tý{÷0jÔ(ÄÄÄT¸Ü¨Q£H FêM…×xù|>V®\‰íÛ·W¸GGGœ={?ýôŒÑ»wov^aaa¹ïëJMM¤¤¤àÅ‹ÔD"tttd{CSS³Ze.— {{{„‡‡—¹ÜðáÊ   œ;wöööó¿Öî{÷îÅ¡C‡dºÛ·o””¬[·óæÍc§úô oß¾­ñ>0 ‡@€áÇCYY¹A³S¦L««+:vìˆÆW-ðÞ¼yS"eãØ±cѵkW¸ºº~u%Ÿ?†¦¦&Äb1ŠŠŠ$æåää`×®]e–+ÉN¶}ûö¯÷†äÚµk r¿¹\.&MšTí`PXXMMMäå啻ܧOŸ ©© %%%–š_ÞX-QPP€‚‚™nÇgÏžáÙ³geÎ+IvTÓ}h¨c´, D||<ŒŒŒªx•”” ¤Tû—|µµµTîA`ccSåunÞ¼k×®•ZÃ*òööïß)S¦@[[»Þ·giiYïQycnݺ%ÕqPŸcPV¶-íñY“}¯R™ 2ÞÞÞÌ‘#G˜ââb†afëÖ­L—.]$–³±±a233™•+W2‘‘‘L]³²²b¤I‘·7iÒ$&>>^î·—˜˜ÈL›6ÉÌÌd†Ê0 Ã=z”éÒ¥ “œœÌ.7bÄ&33“ñññaÎ;'Ó〶-ýñ)­}¯ð÷ñÊIDATõë×àñx aBëèè }ûö˿쿬¬,‰XPVÿI³ß•½¼¼¼d¥±Ž9‚_~ùÝ»w/óñ»¨¨(lذ‘‘‘055…ŽŽŽD9ccc,Z´/^ÄÅ‹„¹sçÒH¬EqqqضmBCCñÍ7ß M›6¥–ùüù38???|þü={ö,U.<<>>>¸xñ"víÚ˜™™Õë¾eeeÁßßPUUE—.]Ê\îܹsØ´iâããѵkW¨©©ÑÀ¡ñ9iÒ$Œ9šššàóùðööÆõë×ñí·ß¢U«V¥ú///OºýÎÈ’›•+ºiºd—ËevîÜYa¹½{÷2ÁÁÁŒ, …ÌñãÇ%¦Ý»wyþü9#ëvîÜÉp¹\&>>ž™4iR™Ë|9¯¤Ê+÷þý{fÆ LLLL½ïÇcÜÜܾzó|É<777†Çã1òêùó猧§'óþý{F”Œ¥nݺ±± ¤ÊêÛŠæÕe¿+ì] {÷îÅš5kàìì,“õËÎÎÆùóç%¦µk× î %11"‘;w¦Ó5)JOOG@@lmmëí‘àÚ¶víZ̘1CæÇ’LÞ¬¬,DEE!''§Òe ddd`àÀ2·_ëÖ­c3hq8ðù|ðù| <wïÞ„††ÂÄÄ!!!˜6mâãã[[[p8ìØ±£JíR×bbb¾šŽ±<رc‡ÌŽÃøøxDEE)\à}úô)bccÑ©S'=z˜1c–,Y[[[ÄÅÅ!>>Ó¦M‡ÃÁ?þˆ¬¬,ܹsÚÚÚˆˆˆ€‡‡ !!S§N-³\¿~ý‡ƒäää`ÇŽàp8ìö<<<ؽ{7BCC«´O±±±˜>}:ÂÃñ`Á™íw™zõÏÀáççSSS4oÞׯ_ÇäÉ“Áãñ`ee=z4¸\.òòòØi_–SRRBPPôõõãÇ—¹ïíí ¬X±\.—¾téRö¾X,ÆÒ¥Káëë‹_~ù¾¾¾HHH@¿~ý ¥¥@€ŒŒ 4oÞ\êõ·°°ÀƒÑ£G{Çãš7oSSSøùù±ÿù•U®d_e%µ`ëÖ­¡¡¡???¶Ž¾¾¾ðõõÅ—7=~~~ÐÐÐ@ëÖ­å2ð†……áýû÷øûï¿1dÈ0 >ŸÃ‡£]»v8{ö,¢££¡¯¯¾}ûB(âýû÷X³f ÛÏ ุ˜]oqq1|}}K•‰DPQQLJÑ‘’““Áãñ  qöìY³í,‹«üâ×ÈÈHÀäÉ“±sçN6>”ä/‹eõŸ4û]¦¯‡‡nܸhii¡_¿~8yò$LMMÙefÏž .@WWýû÷/UÎØØ...¸ÿ>€re*]]]èêêbäÈ‘h×®]½ÔaÈ!hÒ¤ ÆŽ ظq£Ä2ZZZl?899•[®¬²õ©]»vprr“'OØ\¶ÎÎÎèÓ§Är+W®Ä… êµjÊÍÍ ñññ2d;ÍÚÚì±¶bÅ hkk£U«V8p ;¯<ëׯgÿw9---Ìž=»ÌrÅÅʼnDpvvÆÁƒѲeKLœ8±Zû¶|ùrèèèøç^Üëׯø'syý'Õ~gH½(**b~ÿýwÆÊÊŠ‰ŽŽf¢££333¦{÷îLjj*sñâEæÀŒÅxyy1iii̘1c+++æäɓԈ¤F’’’˜ °—Œ³/eff23fÌ`¬¬¬˜Ý»w3 Ã0Ïž=c¬¬¬+++FCCƒÉËËcöíÛÇXYY1aaaÌ‚ Ê,gggÇ®×ÎÎN¢Ü˜1c˜´´4†a&::š™1c“™™©°mOPBªÃá°—jÃóçϱoß>(t»Q®BHµ-[¶¬V×—™™‰ 6(|»Ñ/!„HÙÿ-P zw.IEND®B`‚snd-16.1/pix/m5fm1.png0000644000076400007640000003223311147553267012604 0ustar bilbil‰PNG  IHDR–Q¿ŽÈ¹sRGB®Îé pHYsÂÂnÐu>tIMEØ  =ã IDATxÚí½w@TWú?üÜ{§Ï0 ½ Uéb»ˆ]±kbLL3uÓ6É&›²Ù’ͦmb6Ucbì]ci"¨ô"½3ô†éåÖ÷¡ Ѝ»É÷ýn9÷9÷9Oý<ç\„a¸ÿ@à7ÓhŠ¢)’ÅáŽu öñ½.d¸Q34‚޾ó±4ìÃ?ìÿÇñ×®tÊ[y|@(º‡nhª¬(¹q=3Ó7 I’9Yi­µ­|>Wèà hnK¼|ά7xxy£(ššxIÑÖæ0®G­nkntquµõ“™žê0®¿CŠ"“/] €¸ó¿Æ_<-«­âñx<ðÄáC­²j¶€ÇBo¿ü¸¢¬Ð`4ŽCPÅX£ŸpýÜB€¡š$íãu“ú:A@aû·ŸÈ(¥âÖƒˆ¸|þ ]œÞg5›îÖ'u·G‚Q¯¹|áÔäYÓ­\*?çÆþŸw…G-š–––¤Rv¥¦Æ­Þø°ƒXT˜q„"±D -­­êžž~B“RRíû­,-Ú»wAÈê5ëç/ˆŽŽY>aïO»7>ôPìÆ©É—5jÕÒ•+_xõObQ]yéÈ'ÜmÇû¹‚ (‹mwÄ¢ç¡çÍ0Øÿ`˜As³»[µaË£>ùî³õ.c@€ËåMž=Þןò"â/¹¹Kœ%R6‹½eÛÓ­--^¾|¾ $rŠíOàá`{—Çëï‡ÃDd~^Þ§Ÿï(ÎÍš?a±­&«•DP6Ê88JÀd!CY…cV„ü/«zš"¡P÷Îb= wÒØôPŒ¿M )†ýl½cÓkÔ$IŠ¡F½aÙŠÕ{~ø|׎'ž;Ž¢Œ™$íçŠRÆîNàr8V‹e¨§24I–—{¸û'$ÆÙNr¹< iPk´n”•JùóîŸv~óUZzbä´é# Câ½fl8åB÷ÌÜIbPŒ5ÿn>dXáCú䬷×ëéAúo M8[qP´·Ñ$~ïóÑ`Ы;å‰ܨTö¼üÖ__~ûÝJY+—ÃEš TJ%˜Í„\Ñ $cÈ•, I mmm'ךÊ2Š0ÙT}‹¼ƒ"- ‹mÆ©[ÛÝÕÝóè¶Ç_yã-g±˜&‰‘ê;{° ò"ÔΆ!·½ú1û†È¦ 2„(£˜ýäÎ(òê²¢®NÅÄĈ©Ó9\ΰ’ww]$v”d§_5hÔÝò–à “ÚšêÊòK•]íkú¬9Yׯ6VÖ5ÕUóD.nîÉ)JµfÊ´in=qø8 Gòònøùùd]¿jÒÅ…•”Um2™&Lž:uæLŒÍU);}|ý¡(ÆÝÓÏÁN<ÔÙ¢™81"`\€ÙlòñõÓ›Ìz½ÁÃÓsÄïq´ã½E+"49wt$ä v*tHf#€Ø ÃÔ”ßÔéôÓfÎb±ù÷#¸ )Š2u\ŸÇ€JÑÊò\€ahMÒÁÁÅæ ½žÃas¸<Ði5l¡p>_H„•$)@…\”…rmcchŠf cÙÛ «ÙDP¤Hä€0 („•ÅæÞ[ÈŒÞ{sH6 ³…<˜¸p¨ÁÐTŸó L\`dwQØýÎ(GÁÂbз¯{Ÿƒéí"TšŸã)õíµ”&Svzª£“/`h:?#µµ­ÕÛÇNi òÖæ”„ó,`\<¼ ò¼½¥P\ïêæV[Uîêî©Q«du5î^ý÷¨”ʤKg«ËJrssƒCBós²ýümž*BàøåKòr³\] ¶¼”Íåry¼öÖÆcöV–µ·ËƒCÀ¦é gŽ…EL¶Z­ß~õ¹³£ƒkßS”ŠöÒ‚¡XR_Såáém;xpÿžÌ«IM R©O H¸xz|p˜mtW’&£‡Ç- ÉËÉÞÿÓ·õ2W×FYÍÅ gªËò‹KÊ&O™ÖX_óù'/^²E1@z§/22žb~7#dµÕß}õu¯ÑÔO?ïåévpßž²Â¼äø‹\6ÛÓÓýÃÞ6t¤öîþqÞü¹|Ñ•ÄøÌk7lÇ+J MFÃ7_#¯k<øËÏ ƒb•Ràà°`ÙŠÕë6ðü¬Ìý§Šn µnýºòê’Ž69œúõ×›ùÀÐî^>›}añÄ,±]œ“yC(’‡ÃÁ Ê|h?)ÉI‘S£º»Õmmív™ ËSÏ¿²vÓ‰³3Ž ‘UUÛNÅ,^”uýjÿ•=ª.·@^FÚ;ý׿íÏ”×VÕÈš7lÞúØöWž|úYâï狱8£qg˜ÑøDÌÝY³rM‘@‘”‡ÄÍ7(BÕÙæéé¶bí†É³úú÷òðÖ}C¦O™èéâë¼dÙrwGÛñö®nEÖmÚÜÙ%ûÃßdN}Yq‚¦WW7wwÅpôi³aÒ”™ŽW߀ VÛÕÑ1wö¬Ö¶&@P‹íèät3/[ä ¶]œžžæáå‚H%v±&äeݰ‘§/éCÕUU› =4NØü6 â{½b67#ã†mV~ùù'×ÓÓ”]]¿Ùçz3/¿KÞ6'j¾^¯ÏÏÊÊÉÉ´9Ø‚tw«Çbý’´½¤²†ŸF½–$pÆ"I²²¬BÈ¿ð«¯7·´¹I†I¹pqãÖ-ûà|±äðϻؘ»h¥Ádî{#в6o)ÃPµRÖ »tñŒ§Hìåç99íÂEWÇÄ€K»¸zô÷×¥V;ºöøë´ZÛT_[%àò;Û;ÛZ›}|ý@è(鿘Ëá0}¯@$€Õ·X{C&‹¹—$ Ã~쉛eÕ8n¢HrÃÆ-Ž.n\ö€e³9¶„Æm]¿zý¬³v|½“Ãa—–UÔÖ·6' EΉ£Ùb¡ûž#vrSdqWŠÚ«ßáY&³•ÍáA5U¥ÿøôMO·F§Å-挄óÑ«bBÇáçÕŒ¨Y‹W¬Æ-¦½{÷‘}!Í1èu8nš¤<êÈc9ˆYMu©T¢æ,]µÊvqM]]wŽB.ŸmÍ-3çÌIOIݼy5AW–•úøú Æî¨4$4Ô¤×ÙnììTÑ Ó?ôiS§S$ @÷ó†0êW¬XAÄ—ýeÃÆ-eeå‘“¦ÙN¸Õß?Àf_¿ÿfׯ-kgLž˜šxÙÅÝ-jöü‰ÿKjP¨`|XDCà–æFÙ†ÁRh $íbÛŠ’›rEû¹ã¿nغ¡[¥œ¿pFnv~g‹löÒE?ÿµ¯w@nFCÏY´x’>ýÇ{±«×‰$ ¢ç³ìFZ›ÅŽˆçñ¸„ÅjS¶"¡@ê°íÉç9|Í eÅ…5kºGö|Ça¡ÎžS§Ï¼xúdCY¾·«@êí=uê¤ÐÈAáS÷ÿò# (êëîÜÌŸ¿àð¾_æÌ&pw9©GÑ1¡³]~äÄÁæ¦æˆˆ pö䱌ë>>ž"‰= 9Y7Î_º h¬9ºˆÅâsgŽÕ”–p''çò₽GŽ˜êqA:Àõúšªïv|Þ)o´µÞ~ãÒRK‹²0ŒqqõRvtìùnÇìèE÷4ï¿ÛÑÁ;õÏ ZaÅb‹¥ÇS·ÔÕÆ¬X»xÕÚ‹–Ù¦³V­2Z(W_Ptîè‘üôEK#cÖõdgçÃ0€ ¸Q¯íé€Î¦¦ÈI“ßÿóÛ‹#oi¾‘–úÜö—\œœ«*Êê«ýý|·¿øü‹Ïl7êµö4(Zš_}ù«7=ºë‡o›ÄBÇ ¹&m3t¹s‰< 2öÈ‹ÈÑÓ6éê[;††F1–Žâ¢"wO/ðó÷Ù°õa+oÎì($ ,’ÇÚ²¸@¢hQQ1F„…F0 Í"¬.nîÓfÍ<üˆ®¶` ñðõ¹–|1jöt¡Ã ?yÃÖÇàfAÁªå‹ Ýí{wîŽY .ή­-]­ÍþãÂìoY°p9_ jo“‡‡† Rß7ßøchd8¸{Œ—H†ðôYìañ;â#cÄ1ú¢÷Τ»>’¦{ÿåóYIIñçN+äm¶#ry‡^«+A8»yEN\˜~#·7Wb11ÙG%Ö­ê²ý¤iæÌ¡ýs—­àñù¥…Åb±È@@K£¬K¥=yx¿ÄÉÉÕEz;A%…ùÊNÅüÅ«êkjÍzÒ$ߊ²*ÈÈÎ+ËÏ|ú¯ÖW—ßr‹®[“‘š¼bõF‹Ù››ÿèCë«ëËûÂes`îᕎ)Á49‚5jKY[Ù;r•Ú°`eìêM[=¥¶œ3a´mxMÍ}˜eoÐ-‘8öyJ•2jö\ gN¬Üô°££3A]›Û¾é‘G/Å]èîìts÷>{‘²«Œ}]u¥m© »òØõàü¹³›ŸØ½¶º¦N§é1™õË7=Ú,«åñxP’ŸkµZ µ¥åü…£[žzEY-Í;3ç/1™–æFèêhësï*ôˆÝ d”"ÁÆÜ®î è³VvuTWõ¨Õ2NJ÷ V/jêãë_WšOÓTh ¿­ÛȈP&)þ|GK[AFf¯kÔH¥>PUZpõFÖé“Gìû–¦ÈÓçìܵ3þ×cë7lŽY²”ÃãÜõËâ%1Ð(«{ãM[T‡ž8~¢ºLväàάk)[¶nýyçî}ûvN™.–HÞ{ëÍŸv~Û¦h½>úô“Æú:È˼NjLÇï¿’x>$lNà—ÎqÀÏ?0=ñB£¬éJÂyûtϭݘõ2² `FÑhfô¦©î.9M‘ Ã0 5ĶStß)šd†$p†¡‡zbßAŠº7·ý°šMgNåg/_:ßG*cOÏàËl4PÌo¢ÑCÄ…Z†Åb E¢ûo ëg¡Ï{ªîòÐ{ LGx/€èzÚÅNÞ÷è9²0”Íf£(ÚÑÑ~ùr‚Ũvqód±Xµ*õZš‡‹ /€üì5uµ^^RÖÝH¥Ånî‚d§]õôöÂ0V~^®““SzJ|‹LÖ¥hõðöÁ° ZÝ­t$Äßm÷ß@~NVS}YDXÈÛ¯¾¢Tt goæ½wßi¨­€úÙOß~Z“Wr%îWŸÃbcó-ä ¹û÷üdK·ª[ìì¶4võ¶§·»xºž)*4bª€ÍGð•:·´êÆL Í«6>Þ­R;; Ý<½†±·MõöϺú ;ñžyþ5–È2!|ŠÉh&åðx|'§¥›…Yq’Å €°Å#'p?¿ŽPäØ*oïìêš?gžFÛÝ{3&´¯ºÏ¸–.qó¶õ©P(ì);sö‚­¾ÆÅy ‚ ›à(‘Pîãl¯²×§¸p¾w&}ÿŸågww¶§ÄPSYY]V<9j®‹“CyqyUI‰VÛ  è#E.oøu7_t8ÿñ.:P«î¾ž|6vÓã‚r®y9)Ñѱ@’ti^v›¢ÓÙŃ&‰¾¨v3ptÿ¾çž©¤¸œ¢H¹\+prïäZYÝŠø¹sçTr¹‡‹Û†­ÛšêâÎÄ;8¤®NaQQu5廾ùwHhÐÒU›z`­mr'7àðøB!?ùâÙe+WÇU4ÊêÇ!˜]|²Y}0H€¡û‹h8,Š˜-ƒÞ—Íeú† •úØŒ^Ñc÷¢ÑK–¿ûÆ+ËbýáOïðøÂŒkWM]Nn®‹›níTi»Ø|®££,¸u”.'s‡*:tŒ,4™Œ…×cz cqJJŠ1>öÞ?¾(ÌËÊÏϪoluwmyì‰o¿ú0cC¥îÑ47V 9¬¦º6±Q£P´!4½jÕÚµë6ô¾SÇÙYàîî%õX¬ÖÅËWÏž¿°•µ+ ö g6™Àb0rÝ<Ú:ÚM:mxhHkCuàø šaäÍõUAÁº>¼Ð¢ÓÚ§@§ÏšK¸Åbíî锊S*5­@(inj´ÕàM‘þã !ýÊ•ØØUR_¿ìR©Gôâe‚|óåç,.7zî\¿ñ!ýæ–¶Q† #ö¡ìºáØû§?þ=ûÂÒµ±á3ç²0Ä`XÑaÖ©¯œ¸ÿ뙼Ìë¾ã®$&§œ:£V4{yy1iîÂ%µµõ¶  fò”i×R“€aèÒÒÒŠ’ÂþSó,H¿Èáñ²Ó’÷|¿ãÛ/þ¡ëQW—ݼ™y=þüi[½oúÕ«³fÍ´]Ÿ1zA4,$víúˆÈi¾!³æÏ3ãøïüqÇŽÿ,‰^èãíÉ ¸'•åŠ6¹Ùh¸UÎîKÉ C>^ØT]Â:˜Íf//ÈÑb5µ55øøçñE`ÒkŒzµ«W ‚ W•EàZ6ǬV5†²Yl i3Šòš@†²4M04Ó_8d2€!QŒƒ`4—#"I+IX¹œGúø3àpù¸ÕR]’ÀˆÅÎuòȰH@0¾@8á2ƒÙr÷p¸^>þ6ÁåqYƒÀÒ´ô4/ßð÷÷_ÓÑÚ¼jÅj—·*v-fÒZüüÀÑÅSVWâæáéæá ¤Þàëç/ðr2ÒÍÝú Ol³a„nê †îÖ>ô(4T”Í3ËÃÓ‹Ç¢/^¼°|eŒ“³stÌ2¦QÖ°ñ‘Çìo™=o!´6ÈÍ€øù¾ÿöŸžzúiX»©º¢²ª²léŠå¿½=¬þåpù=ÝÊÓ‡nÜö"ÃÀäÈ ò›™¿Ï'B˜‘#D~rxß÷§N쩯+ëK˜Ñl6 Lºgw¯ Óg—Û ¨1Yu¥‡·Ç„IS@Àç›ûVÓ4}=áüêħښZq`„T¯ÕÙ¦Ô„s›þvÊJo¶vuÎ^RU^ÊÄÛU’[PÈ04MÓ]µv­ä¶šOƒ¦ûÊå³K×l°Z-•%9‹—¯,ÉÍéË!n2šMÖ»è8Šø/ðp8ªTÊøKçÝþ,†a™×ÓJÍŸ?ø„vZj (Õ'‘ãHt‚Á¨ï­fw>ñÌk[¶><ÑvdÚÔÉU•ÐÙiCtÁJXÜŒ4£I;aÊÔ^ËÔ( Š¢Žüôóø ½¤þ4MÉêë–Å®š»òÌ©ãÝ]W.Ç-\²ÃØ€[Ì5å%¶Û¯_Ij¯¯\¸h Æf§$%,\¶*fåºÆ:™Õj=²ç§è•K=¥¶+o\K£(:ZšÞÿø‹o (V[Síá7~ùÊX3Ânij8wòxhXÄ”¨—ãÎßE@0ö—û‡´åÎô™Ø—ž}bÑüejE'ÃN.®UÅex·Àâîí‹[¬q—.åNœ4A .WkÐô|þÙçË—-ˆº:Z'LšlÏl‘X’tñüÜ1-õ“¦N`ê«+¼¼Ey×¥>þ¡(5áìêõ¡VU^²s÷NÜ¢+ÈÍœ8eBZ/¿ÐÚ"›9gnaaN{c•¬º\Ù&>¡©±áÅÿðÔögàý·ÿèèäZœŸMâøÜ îÛ]_^2ÎßÍÓûè/ßéÊüÜ!&p¸üçž}&"<\êã›’Ww3'/7«¹¡vÙªu7R“næ^÷vw›17º±¾æ×ƒ?ËÛ;~ìq>_0&凌r%©=Ç0 ÃhÔí¶í­Šî.•º… ÃP„U&o¤h3Ã0fƒVoÐZ M“öÐßPxeÔuôý3Äe¦i’a¬ƒÒC[†…÷nGi{$ÏbÔßH¾8Zð-5î$E·Ø÷ƒ bJScÃYGÞîk\ÈP#Û‚¹Ólº_¥•¶Œ 0 ‚b£½í>ÒpÏÐãHèa†‹ UÊöŒÌì–ÆF__)бTŠŒ¬,g‘€/r p<ûzjuÌE,à îäÑy%9AÖÐ$“5 ¥PtÝÌÏ“75S8áìær%1®¦¢¼º¢œÇcSs#%¡¨ ÅXnîöüzüHnaFvf6aTµ+ºšt”8õÂu7 =ZUUÈçóu:Ý•äÄÐ08þó޳IqÅ%²ˆ ®@—Μòb'§¤‹gΟš5{úô™³89áBPHoR´¥¡þëOÿY]V¤7hLJ¦^‰§ ÂÙÕª+ÊÓ’ã&Lšr oÔݪ¯v|zõJª§³3O(|óõWJJŠ“Λg0šž{ö™ˆñ®£ä(Ó_Æ7TšÆ¶'ÎÛg”—›Y]]ôù‡ï±÷ûo Jòv}ñ)ÃÐñgOææe5Õ—½ûÖk·V* n?|½£³½¥»£‰¦‰=»¾&I I~Ú¹C«é¹pþi5fCSIÎt·7Ñ¸åø½·ôêE‘¸ÅÈ0Lzr\ƒ¬¾O“÷üHQIi) Ü8¸ïÕ矢é^Åuþô {%öÍŽÏl¤¶µ¶\IŒë?^U^žsí*MÓçÏï?˜–o6ë†ùàý÷lOÛ·óëþ³?îú–¢z¬É`èloeæÔÑÍM CU–Ý´˜ôEy™ ƒ÷ëáï¾Þ1¬:$ÇPraû3\\øæ[oqy£^Œ"ˆƒ“بê ôó"pëÊuëPŒGฟ¯?2ìòk‡ãâæÁÐ ‚°0Œ‡ (ÏÏÕ†"ƒÑÊåpXZÓ [¾nÈå·ÈŠN•¦GËãÌæ‰„"´OÖQuõôFQ”¦¡³«äîä™!IDATôFýÚµkª*Ê""'€Ùlè§§ºª²[c´‘Ša,½]===uãúµ‚ðìR-1Ëb ±¾frxíi­íívàp EXP®ààžÝ3fÏÒ«»/ž>5ñâÒÂBeW‡—»‡Ù‚_I»Ö*o÷’ú̈š \txƒ…^ýŽ`}!—'P*: ²“VlÜJà>OTU]JÓ4›#°XLÙi‰Ûž~€"e1 }›íajKã.ž–ðx c7‹DiÉI>Ÿ'`nGGõùóŠñAó­ìèè´Ý tàÀé#L aE6lÚl0™³2’1 /ß$rr%KLÙÕÕÑWïÓÓ£V5ÔÔ‡†$ÄÇÙXˆ›M iEX\p €î OͳΎ…V‚lniõð ä ®Êmj¨½™“þÐ6[”É4Ê`,>ŸGX,l®à±'ŸÞºy#›E}·ów©Ÿƒˆ/Wt:´ïÙç^¢qc@`ß›€ìPöŒ5ks—Uh¯2TÀQ]QR˜scÕÆ'9sÎ}OŸ" Mݲ2´¿µ57™­±˜Ïasœ\¼Ìf“FÓ)‘¸òù=ª.’ap«ÅQì ;óÒjdqûüQØ4(fÖ©8|! ›Å%,FŠ¢h BÇÁi£Õ„ C…#,CáÆ@šDPÌn#&ÄîúAû–Q hì7ä žƒ Ýçö¯h¤m¡5¢ÕŠÿ¥•‹/´½‘±ï¸cÖ©ùÃÎÿ×î‚¶6É®%¥4ÈdÞ^\.OÑ!Ï¿žÇá!bG'“ɘv9¹¬´ÜI,9J†Q©‰)%Ù¹]íÍRš¢ãÏž®¯(;H"ÁžÝ?Nš ) q\ûèþŸJróÌ:ßø “^¿sÇçS¢æry¼Ãû~ÄåñRSS¸lž®§K,qn—Ëò£ÇŽgåäåfp9,Ûæ÷9²þ­7úNHE¯\îþþë°éÓ"§F~øÁ»EÅ=<1àô±ÃV£îàÞƒ#ÆMš7ûЭ&Ã0ÉÎN^µÜ/4(-þÂ{ç-ŽYº~}YY1Ã@Úµän• *«ª||Ÿ|ö%¥V;oùRà ¸FÜì Ž[K s@ÑÑn0éÍL&£• ¥ž/¾ùæË¯¿9iÚ¬Ñ[ú÷ÏBôNHEï°?ùꇠ`‰Ø%24Ã0O'÷Üì‚ðˆp®PüÒkoGŒ“z ùb®@4LÞÏÏßÅÕ5p\ØòSéââÉå h Ã0tÛãÛãâ.µ…Ž4Ó!!Gêîo£ÄÓÛ¡­ZM7ÃbhŠÍãÛ’„ŨQ*HÜ¢îêºï(Íp‹:ÿgÇŒ~::ñÒ©ÇŸÿ#EQ4Š”à$‰[Í68æÏþóô9ógƒníPßW€°9[a§I£²ZÍ4Åxº»´·¶H}¼û þàG{gƒ®G5yftÅÍ<.—ƒ¢ˆZÙ V«‰Í¨ÔÆÔ”Äkéé÷ߌIý 2jÊêj/;¶éѧ8\~iQ°¹ÿülGphdÜùsõµ5^¾þ_~ùåÅ «y¸I 7ØBÏúú:«ÅHÓ˜-V³7MKW¬ýê«*-Jcz´Zè+Þmií]qØÜÖ!K ɸšjµXšVƒã&Š2¯X½aã#Ýÿ7Žün,èpÙ™·ßøãš5±_ôœž~åÚÎ=ûسpV]UYãìçÃæò‡1<|î¡=?;8:DDDÄ,\|öägG_G‰D" ¸†=òðæ†º[J>d|`,Pv)*ŠK¬f#—/ä¢CÓ3æÎOJŽtàÇrórBÆM]´$íRâOß|i¥èȉ/ýýÛ¶û°iÉ hI¯QQIs„\„BŠ"ztz¡@Èc¡Æ6› ‚p‹‡˜š4t<¡Ãx@àFŠF¹\‚ À€°`(Û’sŠ$le/ M“„•Åá!B‘¸­¦Ô®,³w¨ CÛU±þöwzù†­<ž@¯Ó6ÖÕ-ZË †ÆÓS%.±k6¤¥¦6ÔÕåæ@OO‡§çµ”D¿€€§ŸåÜ™Ó I:;Šu­ÑÜ‹V”–ôñ¹O¨ztn]¹jÍ¥_Oè4=7‹ –/_¾hѢʪªÆúš­Û·?öâs—â/w)zš[Û”Šß|š}ãÈnAô?_í(¯(Ó+Z}ê™ððˆ¯>û¨¤²zÉ‚9ÁáöW~ÿõÍÍ Í²ºÊòÒ™sæÅ_<™•É£ÉÅ+bI«ùЮ-5‹W,žž|þôáƒþÞ³ç-’·µœÚ»³G©Œ^¶Rê0%jî䨹Á“†ùi•\6Û?(æ‹ÿËËÓËÇ×Ыƅ†K\Üê«–Ç®+*Ì;ul¯¢]þäÓÏQ¸%lâT‘ÈÁn^ã9.‰›LJØo ý[kc*F«ToGÚ`X°@Å!{$,(‹‹ŒÆ‹‹;s|ÕúÍ·mvþ[À1î•„ays³ÔßÿÿZôËЀ ƒ?[u“FÓðÛ¶vwW¤b‰Ã=ì35¢ÙD˜M ñBÂ"4šž«‰ Áaá·_shßYM]xd¤JÙuêı)Ó¦w«”eEùm²‹gŽä^K·&ÿÀ ÛS~øâ_3ç-¼tîì•ø M嵟U]VâæáÉfs®\¾@àÖ{Ì]° +íŠF« …Çöü4eæì[žØÒÒ’q-=ÄŽ˜÷‘éé-ý±Ðƹûò1äV!°kl>?¯ Î<>sÞü!ïŸ:}¦»»3ˆ܆ÚÂæÆ†¡[ZÚf/Œyî•·ƒ##£ÇÚžröÔ± l€††ÚWÞ~oË O¡„Õd¥¸l6È;»œœ:;šÎÜ“•iÐé…ŽNR©A§ðžêÇq­NgG2ÝÔÜä R逋±`aÌWŸý+jö<‰‹ûW¾ëìí»vÓÉäâ™cf†Š õ ‘·µ€³§§Ÿ¿ŸÅlöóñîÝCÁ8\~`P8::w47þão (³íÉíᓦ‡Oš®×Snn>cf!›/ºAƒ( lºÇ¯yß§ï 1Õq’¸•ÅáþŸÇÿûx¡ÝÎ7ÿË—;tÍ.…[1÷÷ÅÂÒþéµÿýéG_|ü÷²Â\û'Ò$þáßÞûëï}ö¯Kò >h÷z™ýßïxóågüü­A§€âÂü‡öÙ,ÿ½ûÏ¿¼ùå?ßÓjºmýÝ×_¶47@Ü©£;>ù{7V‹å­×^´'æðÞ [ÙõÉGÚŽägd>pÀö[§Óþå7èß\íÚƒõHï.IsgN{èñg‡ÚÊ ˆ|äÑÇmÿ$&l= ìhC¸‚¯wíQÈ;’._ܼõqYUiW·ÅÞùû¿ã.œ]½n‚  CS|ÐöÊ%kÖÓ‰‰ýýäçd­X½~¡âñ ´¤ð…?¼d;5^^aï>b±cÔÌym-Í~};Ïþïi#@óGµÁûˆ½d»VÛØ¦Q÷hT·lÇ ¨¢­MÕÙÑÖ,c†e·éÊbûùú ,ËlµÚä),|b—¢wcA“^Ûç<#õµÕíí½KÔ¬¸U$(-/êûÆ€\ZqMº¢¢ªµ©¡¸ 7LloiÂû6­¤¤©±á¿eà&t¤Š”²ÇÀãÊ’›wgaEù¹s'®$Æ1ÀõÚ?½þÊžÝßíÙù5†±ê뫯§'W”Ã(õa_·Z]WWNhµÚô´ÔòòJe»âìé36ÍÙ©ST¯ºˆTý†]§øê#ŸË2töÄÈ›[N?ÒPßÜÚ,³ùUZƒ ésë FŽ¿/EÚË!Œ+ÃÍÁÁÃK*CâÞãB¶?÷ÚC?‹ ¨Õdàóø\„àq(V0>lÓ#O­X½AQ«|ˆ¢‚a@‡Ã½’œ´íég¢/)--¶IrKs›- îžì¾/ÊåòŽöl/jö¼ÖFüøŸÛ~8IÄÄ,êR™+ªkT] Ûþ|«¯l¢¹¡&,bÂïÔŽESóÃK*Ââx¹»õÿëì!ýäß_Úg6[¤Ò ¨°Ð¿þÌ€SŽlö z· ûÆçÿ|ßÛ]ºqÓÆ´¤øðISQŒŒ¤H’ÅfϘ1ƒÕ·å›Í‰Œj’ÕŒ.*Ì×h•ýö#ròÔ+é)2iÚ»¯¾Ê°6=òXhDdhDd‡|޾§ A‘¼œ¬¥±kl¸•Õ ã󸶝‘þ/ÛH“5Ìßµ æz¤åu M‘Š!@ÂÛÐÑ®@'Ð;díÿÏ.qúû‘þîÛÿ‰ÜW] >/ÔIEND®B`‚snd-16.1/pix/fmeq50.png0000644000076400007640000000267111147553267012757 0ustar bilbil‰PNG  IHDRL¦–Ù3PLTEÿÿÿððð   ÀÀÀ°°°ÐÐÐPPPàààppp@@@ ```000€€€ýKxQ pHYs  šœtIME×  :.§ÀŠŸIDATxÚíš‹’¤* @ ¤iÿÿk7€Ú(A´gï­Ý•T5SI=Œý§"GÌ{Ë.Z0õ²š|x 0f ^ÄÓ·„õN©Á[`]ºtIéaž}’ј ÿxl$ÆyÌãû¹{â5çMÅÿ¾ÀïQÓï·Ê#qTø™‹ß<ª²ç„Ó¬ãé¤Â&ž¶¤ÖÛäü"þ-pàºï{ã¹…£‹Ñ ¸ÚFÓuÏdП³•Z,¥|2¦R¾Ôš&¨é$±ìç..f|½©poª^­Š‡d+}t—Ã÷™æ˜&²¤ bÁ¬»nœ²µV3&WŸ-,LÍÁêfäBbñ'7BX…µ`šŽ©'E(Ä]iµÀLH5S¡­ØqHKøøI!z0-P.®f&ìgD5áöÕÙæ¡ˆ­‘Á!^žÁ› q0˜Ñ¤J!XA aYDœ°^ê¿…Ø¢ÒÄ»¾L…ñhv1j §5·Õ@„ÛWg›{c5D+ágŽWœ@Ç”:ŠªµBx¶ä†S)B—år‚!¥´ Xh£ïÖ¨†åpn[Ž%æãì…W/¬ÄS*fJ!ÊÄê@á“´¨¡-æ:¦|¾Žq¬Âx²@ºÍ9Ê“‘®Ó¥8`J“Yqr=¥l)\O¥LجLÆ´v9iúJ¥Õ38æEL¸G´bc!”ÌÜ>Æã¤‹ÉÌĤ×õ·oζÄHÍ¥F-&§ýÌÊqÆÉ9O*„”& ÓsªŒš·ÆB™2ì|L•`ÒÄŒ˜lœ€Y6ÐÎx´@¹˜ÌœhöŒÿ‚ïPˆà훳íòkŸ»À4RÉWßœ,°û<¨ ôRo«°­á°# ãq„aW? AÜß•˜¸Þ—ß& Ûˆƒ®ôz2FbŠHéÉ/…ñŠ…š‹·l ¿Úk4Ú¨Aå¥ó»:ênwÆ«®¹FŸç^k}áÌkžëå$üÛïñ¶2kźtéÒ¥ ÕÃ쟑ýØ¥ò~KóååÓ%öTØJ,üÅS¿lÄžj•'"õTËŽà‚IþØ1dùÑ ß¿ˆwéÒ¥K—.]n¶^8ÍV'N—ú²§kÚ‰Ó.]ºTego¹ÃÞÊñ_ŽÄ öVý‰û~—ÅÞ=ÊŠÏÜ2 ?œ¡Ó$oIi¡·%T‡…ßøØÏ«ÞoÉÜRïœÍ¥ÑÜ&yKÕBo övÿq#ãcW|†}Mæz›{ͽCÞ¶ÑÛ{{ä7>6Õûc2·Îæž¡¹MòÃæq×j)yRf7ÐÛCš°ž Äa”ÛdnéaÍ=Cs›ä-¼€½q'¢6)ÑÛ’½Í^äïÒÄ ¨@ˆý>¹Mæ–ÖØÜ34·IÞPGð¦¤| ½Ý±·qð%hœí±P–¥ˆ{dné!Åæ6ÑÜy›rx¼ÎI9ÈUôvÏÞzGìF¹Oæ–ÖØÜ34·IÞ]Pb ühR>¢·ö6Goì­“T 2¯ÈÜÒÛ{†æ6É[Ü„mØ‘;ˆÊ7ÐÛ#{{@³?|ì©oÈÜÒÛ{†æ6ÉÛ¥öˆ×Uù"z[°·@¥Lé+2·ô°ÆæÞBs¯“·M²µdo©ÁËQ~JæV'qÍå—{Ö‡~‚½-oŽò™{qÿš{™½m¸û·¿ïììm—.]º\‘Ý Ù£·»²OFoc×ÔÑ[¶goˆØ5uôöÀÞþéèí/¼G9å0àßIEND®B`‚snd-16.1/pix/rr2.png0000644000076400007640000147470711300576056012375 0ustar bilbil‰PNG  IHDRën8\™sRGB®Îé pHYsÂÂnÐu>tIMEÙÉe¿ IDATxÚd½Ù¯fÙu¶ÖÚûœów®ªÛU]Ý]Íæ¤&Ù$‹Œôì±-;/ ’<ÉK`$@Þ‚üò’y  1ÄF¢X±#’E‘âL6ÙcU×<ܺÓw¿ñ {¯•‡µö>_I-’ª¾uïwϰ÷~ë÷ûm|òø1!G"GBBO,Q@8¢÷±ëˆ°°3 "€° "  " ‹€sŽEDDÿVÿ0ƈ(HAP¿ID˜Iôs @D˜ô›‘PX@È 3€€ ¡þôã"þ`"' ƒˆ !’CA –(zmz‹Ì@bw ßì½—Èèˆ#ëWÑ G½%ÑE"úôr„€……ú DhRô3õ7±>rBàÈ;½&dfa!8W3 #aa&BÉ¿.½X@`$}]vcBä쥀 ¢`~ΈõW#éבì.X‰DX€ˆ9ê Iþ aD"Da{ÁDŽ€9KD"BD`ýi}ˆˆˆuÛ"BŒwùÆA„H>ƒƒ®@Ð)ˆˆ„º<íK‚Hz+`ï˜ô!Š~Ú£Òå̺0`ûVõ„YôÅ€  ØÙ5êÿ‰ØZÔ_cÛ[ ¯@IßXŒcä¼8E˜…923Ø>g¶‹ÝÖ,‘™EDD˜#‹.PafŽlßÏ™EXXMÖïײŸÖ?Û‰0°þ>!rŽˆ@"놴`¿6obA"]L"ˆˆ¬ ,¯BÔ‡}PÒ…€ˆ lï@¿M׈~§Å0Ôí$öª m1BHoô3AìˆòE³þnf@@$"$B pº^X8Ý¥-a»zý¥Â,‚D„(é^Ønô)1ëªÊ·»õý¢Þ°®vÊw(zùú'û‡tákdÕ- D¢Ï‘$ݘˆîvá˜2’®B}Ì€lÛ%½%û½dß©w„(Òê7² (’–:¤ë&$@$‡ýë”üPõ-¥Õn‘;ÐŽõõŠPÚåú6Á" ¡è“! pPï%/`ÐÕé3Qc+hl!Ò¼µ­RRÑ]”>9¼"Àl9D‰ /Ídd]Š^ n'ÉþìÒÒ¾ØÚZb÷‘#XrLé=­«í›Nÿ±€*bq„SXaÍÆD¶ÁûòBêÖ¥ %fyõêÒ“ÃþkØ¥ÿ£$éCì‰èïíÄ:€…s¨° ¤ž4‹‰>´èŠ(ÌŒ@β("jÖ_‹@ º: Spa ­qõõŠ"æ¢ ˆlIʨÓ"¶…Hû8Õ<º€AD,AaNÊ„H¶%‰È9g+ÆÖ  ‘sd¡ÓB< !Aú´T¤Øj³] BÎi½ éÇ5“€. ýTrDD}·–nJ”ˆàÐn,ê0ëöÒͦ»I¿‹ôa8„”èõ/t’®H =HÀ£DÖ_’®FÝV2mŸ03""[ÞÖU…ÅSDIQ€¬¤ÂâÐnTX­t{³ˆ"ÀÀrX4èŠØží—A_\êeë³TDÈ m²§Ÿö‡Þª0¤ªP«SÁü ù®í¡ämžÂZ¾}½W"ìãˆnÐh[ÏÃ:ýAL«%´Iq+n@~r mÝènÖÜ+ùMå ²U¶éºAfHåUÚèée[䲇´õ9)^§?ë-Ù Ëòåö¥ ¢X½’w¸]5 ¤N?L–@´´$D²`©…­ÂŒQXwtêë€E RaÀ’¾¨K(Ú«Îw(¬õ„0mEl´½nÝC~,¢±…I³¾^^î3Ñ9-¬ÜÕbÏ=§BAÑ>‹E@…ì&­l°®ÁÒ/Z:”¾s$$aFÍ ¨%Ù&CˆZƒŽ˜Áb©ä¬ÌËò„)‰"§Ðj+Aç´‰@@¶&À9{Ïšô!XiiÑ*…§TÞY¶ŒÊ€’Ú7»ÈG­-&Ývã 5¥¢@„£DKË©0ìk(ý°I¯ÌB·  i¸Oñ΂Kn-±/ŠA“d®Q„™£.ª´I¬fNÝÌևȲµ›rë‚bµ¥F1¿*ÜÚº’6µ†] D¤m‡K©.…Vqœb—hš¶kÜ -Ìœƒ¯>.M»©›Ô„¬ð‹-Œô×hAp+&j‘ÕõЇ-«à˜…™­sÍÙ9=‘¼„Ù^Ÿ})U·ú,¬‚Ê{SªÇÖè‚ ²¥"DÜ ´îG—êÍU"ŒÌ¨°°a(¢J¼írÅ6Ä0 €ô”Hœf+ò5Ö Ó~’È‹Â]h QŽV BHdù‰i"íë¡mOƒ HaÁÔö¡@ã ËV‡ˆV"&TDRk¨íÛ’³T™~\,ˆAyAGB"ôh™ŠRšµlªj”MóvC¶Ø‘È`éKq@t„ÎiäÑ¥,Mm;RA% ŠQˆRg‘˜Z9݃"Ìdq™lkk÷ON¯„£]²¾Â´¬A„1?§¼PG@…ŸDD¡Sl15ªVP:ÝgÎi+¥¸s$"}ˆVÍØ“B¶gyH®ŒTE¦NÝ>¢– `øZJ¹ HNÁ)]‡Zýk-ލÇËRÈïr)jùMíäT×C´Ÿ ÌŠZ(à£)Š£F²¾Y[ãÜ8÷ź4¥ d½ôѼ¯}RÍ®€bI.ˆ€–ÞQØ*žÜ&'(ËÀ² ÓsÉeœXœJ‘R°ïK%·ç©CÈU&Jª”ôÁJJ ¤ Òª Å:€½wŽ…À „Dˆmµ "cì@DM³`h©ÖmÚ2j§Æé/PØ $¼\ß¿#ƒÓ3"€¢F¶µ*D"…Ì AA´N^Ri­-²FG°EšdÛøÚ¤ê$A2  !`Ö~H‘fBÌ_SÌÌÆlé »`MZ— Z–¤Œæ¡ÁŒÈú ‘œÓ´@ ú¢ éS DpÞgPÙ€9aÍx’C[ŒèIÔ„©ÁD«ÛÌé¥$0Ò1rú"sÄôf…§A@çYB‚(-bph˜d×)c ˜¶1E ¨ÐRj0˜œakÛmº VÿÙÆÓªY_%j[®CŒ¨P„öˆÊߘš$¼ÌÆ©K@`ªH Þg´!ᢊÚ%èA€p‡ól!Í.@È:X"È:ímAÇ)K„¬-‘ÓžÁ£N´¯—„©'ÐBDœ>Ü*ÖmÈŠ9Ú&!DÍ€¶â ÅCdµ|Óí"ÑŠÉýOç tµ§‹}ä%ȵhû ‰e&ëF…$}JjO‘=ŽÄia–Ö‹"bäQ ½r"ÐæJS“>Wk$£Fy¶„‚Κ=]©˜!–¾&}EUÒ_Gà˜QºP«ÕÙ6yÉ3¤¤&PŸ‘Î#R/—ÛCJU;pÂgEc9Ø|T¶¤~†¨½¼a†¼Uþ0Øp=/šŒÊrj*àU¤[òX¹5Ï×ÏîÃ;XԦ͋e)ÌŠFÉW1•<ŒI°¤‰DºÉ¾€ë±/q³'H¤˜­]‚f_AHQ<ŠC¡•BÛ–y´FZÔˆ¶8h3!БK.¤ÁÐHOHW73ko¯ß‡©6Å\¸ ¤º_¶&;–µè¤”º)uÜiщ¥Ö„Y ÓûMhŒ–c’:¡T[[¢‘œ£yÙlË€ÎÉÕ.'7#" fJJþ ž¶)M~† )â~¦”&¡˜;.{BZ;'`{Þ‘  À ƒ<¦èf_åÕ }S™ƒU޲¹*µ¿Eí¶bÔBÜO¤ú¸‡>ÇYAJŸNé:(-­…2ˆ˜Íi\ ížä¿Ö8,(áÒˆM£<âÝÛàS$ÐW‹¢Ql»`Öô(9¥¤Ý~@¶Ú2IH²¥ðD ÃÄs0ZÍV/gÁÕ<ÜcW¤„¯T“õ̪ˆ9‰ÚNdë†ÐõOÀ‘? 3ËÉö‹aÏy.':´H‡>ëd·HN©•IH *³S5½…m@_wëèÒ’;¢$ªöCž„lg[f%–&jõPBJlyÁ"çy{(r/’ ®…™SÜgÚÚÛ܉VؤE± (ùGCYÑ#}Ddë¬Ú²›"–hûÑ ]"[(Ì1E2 ‘d„SaN%Pf^ÀVe-“!wb¤¢$$@ɳ§|½bÓ¡4 íÑ£J@ÈŠ0 @dÕƒÕ.iY&ö ä™‘zÉd +‡Ó Ñj‹íJ¨ßÕ} •ËAéÇn‹‡í*}.öõ†ô³éôJ àÂW‚PŽ›(L„ x—䙈ÝY‚ÿ µ@¹®•¾lTìûhÝS1 ùKã@DA$NÅTšºn–.R†È5’±'É¢¤þÞDôÂ4é+ á/Ø_zzÎ9Dožœá£6uKcï̉Èß„è< ³pJ ´5LJ4“Íi)Å)ÝäZèj…¢´WéùJZCž[pŠš’¼)R¿‚rÒN47Èt³œ€47IQªæi÷aÕà}ù‚@8n%B£¶t]ËÀ)¿d²×Ö,9'3ÜêeûÐ:J¨–0€Â:8#Lý€€ÑA!ÆBÇ6Æ¥¶i$ÁjyÈÎF}0¡÷>x½ºrÎÛ@TÃŽnuc†Pج«™HLï4ÓR¶¡ˆ!„Ðõ4Éi6Å[auýìéãU³ÎÛ Ó_¥b `u9ß,ζÀ“Ì~@‰1v1â6Ùp«§È0|_Až.nÍòã‘\€M%$YSAžŠ;´†·è†”¤® …±ÿ`±‰6$0¦©¼ÒOdà0ÁöL`DHp&lßd®¦l1qšØˆô÷ ­2¦è´]/[“jmVî¿0—Ëišc3µ¾"Ýz‰k¢%¿²sÒHV¡]‡ˆ.Å\E»4H²!Je·Pâ!ˆµƒ€èu ¾èÛÝçÀ39ÅÊLN•sÎÿ’IÏ@ # 2‡ÑZ!F¶y)Š ³Ç~Š$¢1V82°¤Õ—†N˜IM[IzÈl$%1÷ÿpšF+ù>2õA[ùå‰F+ýÊ›'êZØÂ4­få6#R~h¹ž Dè‡@ ¶ÃÄ|”Ü%äæ/…BÓn„™ŒaùŠL#Á‰9›uÝ…ÎÚèTKÙ —FmòËý›bÓ‘h^A€RüOþäOZ\ c-b&}²2ˆ„ÍfµœË!¥Ž‚)©óµø"!,‹ºÙ-¨3ROûDšðÙ¿šîíNÆSê&{îù¯®æWó‹iž Û\-ìšöég÷šÕåVR#>f‚”Áz!ä]j—žasAJá”SÿBH.C:=ÇS¶Øž`há_a›b_«åБ§^‚BbßfT _‰<éÍéV„Ž12° 5m› ’r£µ¼JÑ%ó­PPØ&&‰ Ì$‰Ê™x5,‰½MZ¸[Ð@bF$rѱ 9‡[üÌ´±Ó°ßŠaDÑUY€mëk@¤4ÆÔùX5ž3º6ò¶¾Š¢#6lÖ+¤í„©nÆž´+ @¬IÄ;HRýo®ø´Z‘ž£då [m ‚Ì1r§±Š.•8>𸉀ˆ´ #›\3£”«Ò8ÏÖ+#¡·bÁv¾P&kJT€]·VßµaâXkçŽl18¤¦ÙpŒˆDä²2D)·Þyô#2 $nXbžYY¤¯Eìa ’/üËÂwÌ:± j™t‚)Hþúï|ë;Ü™¼†€2lLKçÝ郓³ËϾôî7us Û]+TBˆXoêgORUå3ŸCD/ gïâÕÙYYtãñŽUT¢'Ú-ƒ‡îêìôÆç>7žîy*”s¤8©>,DŽ›Åb±ºÚ½v8ï%ĸ(²YÌŸ|úÉj~2(}î‚úJWzf 8ècZú6Q©ïeÐ3ûr“€"Á-âMšn-•횥¯;éZ…DúanWÜØ³ŠóD"–Ä#‹˜‰HlÂgÛ–œ1tzm;HC€°–,  *9H´iãL$õÚlÈéὓHîÛ¤Z‚Ô{ï¶gS½þ H'ù ¯"SË¥'ÎÖ£s4dv¬ELIdIA¥2¥›r˜»5 œâ 9ËZ.ëo üRXQ!Ñh”¤Vë#¶Ì†Øã bÝüV£¯Û>ç}èŤ”4oÜP)¿÷œØã·ú_ƒoõ}‰…¹R£ D–õj©ÅOj¶{ÁêVƒ|‰"lÌ$äú˜YL®×!¯nSÿLNLomì3"’ȉx‰å ~üÃYTL¥$±”椪OÙÔ«¶®ûäÉ’…iA&£QQ8é ÄyÔF/R¼rî9=sŽØ‡¸ÌS( rc‰,m× pˆaçÚµõjY «Ñ5ÿ•/¾Û®Âñüì„!v«‹™†ld&çˆ4g‹ÙËG%».r”TQê(Xçg§JwPDOX)Ƙ”¤[C™Œ¡¶eÀT?ºzÛ®‰œs*æ£$%¢43áª(ÿäŸþ‹ÓÓßþÂ×DII•Î= <»º}ðÙ¯Þþ»lºÍáõƒj˜§Ò½ ç—gëÍ‚< †Ã4ÚÌ#;iêz¹¸êbspýxgwß‘³16ö²Ü,ÿèuæi®H[4—-‰ l©n¶ÎÒK¦3ìU ж$Z^ý4Jù6m-“˜Ó_HÞÕ&aJt(’¿^²å¡a8Vª<Ô!`ŒÕ ÐÜ ¶Ha9`ÖË'– °Ò°·d˜*©ç‹z³°ødÚé¸õo"1„ùÅE³Z€£½ƒÏ’pdŽù¹‰!!©ž$¿%IöØOöT’BÆ»H*OknAÚºþø??yþÄI˜Ð›Qµî¼ûõÅùÈF YÑ)Ü ŽYd:Ú­//)Í „²:W' ˆ›6l®^"„ôSÜk×#óo~þ³ÿÛýÙÝ_:× çÞ×c"ÉFbZ'†¢ÂyOè¦Óø|q ˆ ª $Æ(£‡H0°9GHmèÊ=7QQ’#WxG*‹ Bu!°HéʧO²yˆ®Î£è,%ɩںå-TãV mc TN®º«Ëóñd×2sÛ¶É0!åìFþù¿øŸþÉý_B(ÓÀ‘…U¿©Ëûã_ÿ”<—ƒ!%Ùw6GÑýODyÓ®§‡ûӽÔëyB Þ׋õlq69Ø=~óó]¬¦J~$Öè­WóM³¬FÃCŽqËjˬ‹÷ï}w¯U£©µ’‚)Š ÆÈg/_´±íî «$ëë$"_Ÿ6Ír8íìTå2ßSä¯"ÖªÌRÄ’2‘ûúg‘ü”P¶)j)~ nk™_aH¼â#½ÄáÕAâ+f&©B0'ÌfIšÙb¦’ïOÈiÚsä]n=zB¦* Á!x"u†QKHDù­Œ"°MÀÍ!Ö,a 2Ÿr¢Qô~©¥€¢,w&Ó®kDÂîñ1ÐøìécµjKU]ò‰"‘sûŸÇä–½3eÛ<#'ÖŸ(FÃã;ïtÝfS/Áà[6Ö}z „ÈȯÝy£tÃmö%^‚yq_ùþuMîk&ñ”ö~ñ“_Ô›s€Nó¹›o¼õ¹wß{óó_ã¨Ðs¯ŠîªlB‚1ÄäÉ9qäbŒ$ ,ƒÉõ‹ó…xŠEÅ] ›Õz~¦Î¤NIˆ(°X,«=, BIJ”ÕÀ‘e¸r Ž`P•mÓua1™9tØûv@äh³³¹m[WU9ÈÈ‘ªÒêàdu¹þ?þÙÿvëÖ¡§J’C : ¡Õ8ÎÂe9øóÿ÷ÿùþÉ6šÇµOÔ‡»^.Ìæ­‹þì'ըߏù&šaV£i:(áp8L{ç"²TB€`½X1ðd´3O³“¬–g¶ÜÇêMìš½ýÃÑp´Å^@¡d¥„€wï~°² Xñ IDATãÆtg¿ò&uW.d½\Î./`ÿðÚ "¹¼‡ˆ¨Y׳‹óùüb<ݧU1À¾UÈRÆrPïŸ`4÷ì&ÖC¯±þ a¯çšA–Ù¼¢ïûÉÝ([>õíXVbïw±mc–æóæœÕ7œ‚Š$# %S15Ao³s+[\¢HÙyäK@Gä¼#gÄARƒ0dó" §Áp¼¿³»sc±¾å)"bÒåĈ./NÛ®F ¿[žYf^Ö?ëdæ'¦mFD… лkÇ×w«P7×TòÐC§Î;gºSë”&”8f'#€eöä4ª!9$ÒN2ƸÿúÞW~ë+ƒbÀR1Kd‰H°»¿¿sp4LLž›*mHÎ¥I胛åê“ ,Ó~‡Á»‹‡ÏîÞ¿Nýh¼YmZ’f0šŽ•PYù²"¤¢¨¾ÿ«ã׿È1vM³˜_F‰EQPRè„©(Æ£ñ'?ûÙí;o*¸«Z%$d…/È9@ çÁn4Ú€VSª¤AÔø²¸zøìø “ÛA" `v¾Ó¨ÓìòêÚ›×ßiÛ` "¶¡™ìî©™Ïìñó:^ܸõ&Q‘|„óàZ·#"vu]U•wD„Î>˜‰ê¦Ï/}U–E™ÛIT$ ‘&_MwK?€W9˜©ó›úã÷¹óúþѵÄKÞr„„Íb1¿ºLGû×¼+áܲóz±xúènÄîÆëoUÕÈXQIã‘&}ÂPö7Ú %†ø0§ü™q5¨èqõÞ}/q’û„ŸûƒÄ‚O^Ù‚d@¤wæ35RÖ:£¢;º—'ÕmoºÑ3Õû¹ºNƒcVº8Ad¦ ¶ØmH·Þ¤(O]²á§VÚ6üNqC)l5 9t4+\žž !9¯{=©Iã:·;Ù»zö¢k6àèðø§™Œ>;"BA_ä‹Õb‘í9°)ÖÕGS5zrfceç¡—A%<ÙÙY_Î/¯N˜Ró˜Þ{—œf¨6¶`Ó!½`¼3ÔÎK¹j6É™9† ÌÎ!y‡ÎQ—§Ï×uÍh6³"Q»’U4ï‰lÖ‚Tˆáò–¢]án\;vD(m§¥„¬–3_ø“ó§íU„¶&UQqÛÖ‘^>;©*ŽˆVs.ZYw—(Ð4f ¡ëb™‘ˆƒ\½<ëV—ífÙ,êb¯*'G97‹¹pàÈ@^cµYU°Êk’Á a Ѱ“( ºV+*ÿøÿ§ûïþ®ˆsXœ+Ú¶ÕÌCRù—öG7nw0ÇÈDsl›Z+ÍfÝüðû188ØÛ9T-Srï£Û "âbvÕÅv8 £M3…‚Úê{vvR«A9AaƤ1Ïô‰¡m›º©]A…/ÓÌÑTJˆE„n±~úèîÑÑèp÷X÷Žd§C@âŽ7óÅr=¯†Õx0B¢^À‘W——÷ïýzçÚÑþÁqU Kû)k‘AuÞNÏýl€³ûqìÝÈ“pÛ¬'þæQ_9ý•P¶H‡id(È9ð`óõm¦$á^~h(É­ —OgÄ+q].%ïÌYS‰­äœ#§œÎ;"pŽJGޘǼ…^™mHò@têâÄ™Õo‚Ù” ,MÆÃÁx½Z¤.2[ S7—Uupp¸ZÍ#G¥jƒbXÙU‡÷÷©«ÓSëàÕ~ÂR'õVÌ"y¹¸Gê…Œ¤ÎëJ"–¶kßüêWÛH:wJÒ–¨•ˆËìj™Œ|Æq,}Ø´êZ`‹sVÀxw:™ìe×%«a#‡‰R—4aÉQ–ŸñZ¾8!O"© R ±¼+ž<^¾ó¥½8,fK ›áÞÑÎÁ…È]Óâ òeµ<¹œË‹a±;™î6³‹gw‹ÂÛ  éÁ§¿!èööö.Î.»¸qNÄœ*˜ãry$FÀ6tD.†$¬ Â6´èm#"¹óEQÕ_üŸÿúý·ÿ)àMÂä„6©&ça8~úþ/ßûßL„Ð9­Í–§O‡%+êþòÞã¯~÷Î×ßývÓ&V"‚A“õìÅK èË2+Ô³å¿–ì± /ÝŒª½ÃëZè»QÇ Y „6.N…÷…5.Áð ¹Y^\>zrÿèæÁÁí/‚3u(Qî{#Ÿ>ºXžŽ÷ö¯›½`òn…ÓgOÞÿàðõÛ7¼/rÙB œé*‚›+€½þ.IiTÉ”=®MQH˜»Ô[eÓÂ~èˆ ÈïcÑv#—]þ¶5Ï}Gbr•d]’¼ Ì'9ñ¢·½­…“Tžhg ¨"SÆ ÞR®‘ÙÖ’ªÜœe(5áNÄ g…›S”b±h_È‘YŠª’ õf1©$á5zˆ](Ãåª]-ÊþascN~ DzEƒQűíB'Ù–I¤w‘ÝR<¿{o]Ÿ™U±Š˜3ËÍ»âêési6ìÍzGXNéJ¤,«épÜ›v+#KîRƒï}uqvêËB#ºÑÄ<@ÀMÜɳ‹Ùji€£ÍMEB2iN£N{ÉQŸž~OdŽÉËÛMÃÈtmÇ€¡ë8¶iXV|úƒ;o«œŽËMY’óþüäùÅ“]5öä#Gn›¡+?üðýo~çﯛš»ÆWÃãÛ_"rÜvM¨ÛåúΛïD_€Á··Þú²§Dêz]”½+vwö¹¸ ¯DbOžcÂÐ6‘#n7+‰côäË¢Z<>Ç}Ø=yüÓë7ßÙ´êñBr‚ß2è½sO‰ÜL¨“D¿gî$»@ÙfÀ#ÀótÛ*^?Ò§%[#ʘ¬àtbO¢ük+©?èÅîà½1a{=RRö'm»Žh*—ìD¯¬T´%E/ŠÁ`»¶—cï£׷XÌ÷÷——M»Þ²mÙŽÕxâŠòêòBy¢Ü®¤é±ã~Ü[_ùÊò²Iž!€Œh .&¹yç ƒyÝ&ý§EŠØé1DÎ …zc'ɱտ)i@Y•Pè6fBJéÀˆDªrB;£‰çÒ‘#ÕXçCwL¯g°æD”h²|‘ºi’{;`X×û7x‰¡ŽP ]­b»òeцpç7Ö›Æ&›u! ùÀxûKß MÛu­@Yy)ïŸÜTS£5a$‚¥[,Dää³ûëzQTE½Z…s â!Fò"‡vCKŽº® ÜaªCh¼+ÛÕº¨†ëõTβáïÿ鿹óÅ×ËnÚ5]³^‰DpTMÇ£jèˆb ÀòüÞ=¡j8ÚáØ CèbÇÀ܆Áx]Emûý?ý£×^¿3Ù½ f¥°U< Ðâòr±¼ïN±ðÉ\s ëˆBàÇŒ÷woÜ|]"$ÖY¶hAjëfsuãæÚñ ‰œg£€ÄYo8yÒÖËã7ßOwI2 Ù•s>ÔÍ“GŸÕaõÖÏ3øìœ¨¾ƒ«‹ËóÓ“¶kÞx÷½éþkÔŸã‘h:Ýf=»<ïB­ð¡3ó47Lbq…’Õ`6ûå™YZÂV<Ù>ê(MvÿºØ&°lG¡ÄíÙT²¥ÜÜ’Ð'PÐÆ†ùp–w( ò)»!‘Y¼©ú0½€>ø 3å§C z¥}™9lJjP)›s'·ØÜ«197œîI2Õóš49²iþ\»~cvqƱ?jÇê;ËŽÆÓýf¾îV—"ÑD»V¥è‘'F0u·ÓÕj¥ Þä’k+†0Ú¬W+‘Ö|VÒӥ䇀ΑciçQå,6I”ÌÁ WKôÔc’„èHg  (›æ 5#R¶ŸH¬ë &€¹«W$ÜÔMÓ¬™[çhq1m£<Ÿ²*Ü¿·8}¢'| ‚ÄÝý  릩¿ñ7¿×u9t£_Þ¿Wðºk»¦Ù8O¾(ëùâÝo~n<<@ŽÜµu1“–ÎCÑr3ÜNG‡]h'£qYH$!†UÝ.Θ¥Þ¬ûå'o~ýhÿðs1vy4¶›°Pá=’äW/.ÏOßþ­ß’¨ž e5øQ€X”EéÝj¶p#ùæw¿­7Œv•Ón⟋ÙáñkEQªÓCš##!wØÂ£»¿Ü?Ü9ºuK˜È%OBUPÙ‘2?= ]ST/‘ìx"#í8æ'îFên¼ñÖt²£Ÿé„ ëÍΞ=}öìá`wüù¯þNÓF´ö‚X.NNNNž“Áíw¾8ŽÁä8½›Ífµ\øª88¼áPdÉIúBŒúÀö)e~ ˜—Wúˆ¼t³,iˆÿšX`Ö‘dõ‚lY­ Mb°Þîqû¬ ŒuI’Vb•Š ©a +R¦=0f0þ¬Ú/   '­{öòòX¸Ÿd&#õ˜Íæ £f ˆ,,›MºVÿ˜ÏµˆwŽªrT GGû7^>|ŒU™Tëš;>“wãáx³¸ 1lÍPR{9*fWz'1r²Œ4¸µ‚aôÃñz³ê•[2D$Y7«M»öE™Þ'Ο<ÊV*êåq5]]ø˜d™{b8þÂÁd×6’”É]Çœ,"™¹my3GˆÜµËf}é^|x—\9HÓ`×}ð›ïï^?È]×¹MÝÅj2-Š: . lë°Ùp³Ế,=v¡v"X”ųÇOFûÅòjÍÌ΃É42úÛlÚöøøµjï°k"ÖÍxº×ÕˆÔ뺪¢[Í.‹²êÖM»ž•¾zúÉÝOŸ ª):W, ¿^.Êá°ðÞ ÇÂ-OÖ/f¿~ãλ(›'”ØúªtÞ‰@d m[€ûÑŸýÉÑç^÷n ä+“”“¤¢”ãáå‡/>¹ÿ“ßýÞ?¬WõÕÎuµ:ï2ÇåùÙtg2Ýë9öƉ¸‰/Ÿ>>¸qëÚµ[õgup~ñ8;=í8L ‹í³ËlŽY¸‹{Ï=ø€þàµÛÉv³QŠÚk=ýìÞƒûìí¿vÛY°Õ…m½9;99¿|~ãõ× ç³ó&|ª­ë#97šLw÷Ër¬;PþŠ[ç–¡GnÏ ™çö…Üt½ÊQضWÜöŠÕ]Mò§r>XЬÄ‚ g ¾zuæšœÓì½þzbüöè…0ó)´:$UçCFÒ9TQ3èUÖD¸ôÎ{‡è›Ù¥;éÛ^X÷º*Ð:‹PU5Ÿ]¬6 D tDvH%<ˆc(‡Õ¤½øô#µfH^$¬–Î(‘÷ŽV­t±ƒt:‡UI¬J¤–xàýåìbµ\$ÓȼÒcÆ“½“ÇÏœ÷YpËwC^<{>¬Êj4ÖSc—'‚PÏ—³Þû|(›Ä8}ë¸k£CTÃ&2/VÕ- Æ ×W§C²CŽÜv.E Ƹ~ñôjq€Ûfí¨X­WmÛ_–«ÙÕr6oëzÁqw‘İÙ,ËéŽC‡DqY£8«Ýë×½‹ógHdö¾rÛf>råÿò‡“Á­Çw?qˆ§''Åx<Œþú} ›Öq$?ÜÌ›n¶>9¯ÏŸKÞ{*ÐWÈ­®.˪‹ÿîüï¿ûÿpy>Ó˜ÆÓÙ9:è6ŒmWŽv^ÎOßùæo—Õ>·"x_4,]×yr;!W|ðËZ|òî×~'tÙËÐŽÉB_U¸à?úWÿë»ßx×æÍ¶}`—ÀúñÉbó|2=2» ÎP!`hºGOTG»{7bÐÚ>«ÿŸ a½^Õo¼þ†s :¢-¢¦ÁÝryxãèúñ릉íÕªH„û¿zÿböüw¿¶·{͡٬ €#ÚÌg§ÄÛw>?Þ9Ô-Hæý%j°š_=ºM5¨†£±wž ÷Û†WíÏiâ|¶UŽ gÌGQ¥“¶‹Lâ”ì7´¥¿Ù:ÇU 1ÆÚ¶k›®k»® ]Cˆ1ÆÐÅC¦‘“­ ã–2³€6Ÿœ‘Ôéû:&AŒy7ö§V;ÝõÔ}ÅãÉþ·ðž€BT?1{úò£¾ïÍèÌ%‡Y¹,Ò®¡^U…'D¥T8rÞ»r88<ºQ¡ó„®p¾,Š¢ðE‘ÏS„.„ñµ=©³ÅÜ{ç‘CHç«;|ãÍ/üüßþ)`«~•æˆG‰¾ŒDŽ£áx´[/‘#"J0Ö$%ôΆÓvþ‚<FQûã³D’ën½¸z~ò|±Z°`Drè¦Óý‹“û]W¯Ö+4ŸWqEáz×]ó3teÿÆÞ׿ÌYŠ ‚Ãñž/†j–áp2ŠåÐÃád2Möw÷8Òb} ƒiY ËA5_\œŸ®i(ˆÀ±‰írÎιj—£ÓÉég#/Ëͦ›Ï›.|úâÉwÞyq~±¼8ÇО ÆqU‹ñÑÑACQk—ÜmŽnÞ˜Lvºyóë~:»ÅéÕº«Ÿ={ÒQKÎ]¾|VKˆ*G@ëvåwöÿðþ×çÓñŽó^$.Wë£wÞ“wžˆ\µ;m6-L'× Üùé³r8R»›ñh¬Ø(IlÏfW«‡ÿÁ?þoêUP(@í.4_“sðÙÝ{ðþ¡«néHÏÎÕ­×1°ÀÙó“+jo¾ùUæÀÌ#¦±Öóå‹§÷w÷'ãÉX'*1†¾±'ÉÈË»÷/7'Gäܶ§bvëM×4Çï¾=ž\Oç,鱊l\¥ˆïÿà‡—›§_~ï;;G½!œ>{öñ¯~PŽäÚñkU5´Ã”“  xq¹xòÙoö®º¢R* 3@=s¡°G#¶ŽÁqöufᤌ¦4rÎsy³'{ÅQ¦ç–e»Ù‚Ô8vmS×m]7MݵMSoêõf³ZoVëº^w1t]ºVTäb sL: ±“Y$K¬HÁwLê¥t )©ž…1š’\›ìP?€(Àê9DŽ ï|YeU%•U¹¹š]^žµ¡_Û9<|cvuá O…ó¥÷ä¼#½E"çëVç16D&­wEáËÒ‘Gƒ.6! Ò)œóÊÆ2z›@ç#^<ø ”ž®rž5ZU3¨Ž‡oœÝû¸mN£D (Ê¢ð…þvï]á‹i:ï F°'½„¢( tù¢ô®pôúÍ›*3ðrä|¡¿„âÐUâÎ/]á]Y9G± !´þh\DæÈ@ÞÒ§?þ!ùèô.ÕVÉÎd¦Ù“]lêÕf³¸ˆÂüâÅÓ³“g1¶Š÷Gæ³O€V-¸ÙbKﯽõúòåå“G÷ œÓ/߉P…‹á Ñ ¬†åþÞž/ŠzSïNö(t‘üøðÉG¿ÞÙMEŒc³¾xöòö7ÞX6R Ë9Š4±Û¬âòêdEb|ãÎíz-ïríèp4î¾U_­Jï±ÚŒ¾*³‹ÉÁ5ç«ÿåÿúþ‹ÿü?á&’÷H~4jÕÉÀD´šÏ+ßûЕ2DâÑñ­ºm¹ëʲr€„¡†ŸþâϾûÿ^¨ƒi4Æ@@j/z5› ‡;×në³%ç¶ìì±tضM ñøæ1’3ÚL gH"¼xú övÔù]E3ñ ññG÷çÍÅÁα#—œ¹%ê1Ð Ь×ÏŸ|Ú¶ A=*À sò€P_Îðç\ì‡oýÞ¿PæCà‰C2ÜÛo7ë®k|Y^?º5?q½ðÞÎ9GÚÆª6¶ÖOOÏbèÈ;ïHÅ(Q¸ ±8:X]-6Ë¥Š‡Q¤ðÞ;Ÿ qÀïíí_ž¼°s]EwŽ$tÍùó“8äûŸ¬Xù°­¯bŽƒG×2w!„ù‚Û’Á¼/‡»×¡e?B̬„È2OºØD`W·aÓÔaÓº²DrÀ"QÑ ¯Kð¾Cd¨Ï/ï<žLv‹ÝÕzv~vùÞÛ¯ÅPÄ®s±i—õÕ³“ùå ÊüäåíwߥÑE_׋ªî]'àz|à–g­À¨š\-¯vwx°sÐ…ÎWeY/î= ÜrhÉ…£7¾T¿\®U›°W``ˆõº ZÆMÓ ‚T‡ÿßÿüÏ¿óûóªvÙ(;0 ä¨ëbîôÁ£gO¾vû¦„@„±iêz1wE)!2 6ø«ŸþÅ7¾÷ívU F†„:’žD.Q†“ÑþµëªvîOc±ct€~þƒîÝœ:?²)§£çåùÃO±¢7Þù ØqrØk5Ó O‹ùr!WŸ{ï«…$„|\¼âüüòüÙ£[wÞ ô¨ðt†„F'ÍéìÇñ¯¾üõ÷¾úÛ7±ƒÈ‘@ kÛO~ô“çÏóÞw~ïÚÍw„_™«iH»©Ÿ~òÉg÷~~ãí;{×oy›6gWp´j+;~ncÚ›£ÙR¬Xr€O§hRž¾ÚJßoŠ™%KèÚ¶Ù4u½^.6ëeਖsŒ]Û¬WËÅ|Þ®×£’W».´]9n[5o‰" ú#y•ªJH‘…cìGãù˜×H Œm£†+9<2‹D¨êTÈBðƒjçðfl#"EyóÖ›O>yùüqÛ5!r4-ðDHT¸ñ‹ûNÏŸ  #â(öW9òáñõöl±¼:mc 1ª¿KêÑ¥m×èqïøz$ ÍFÐTÁÔmÚùÙËÅêbï`ïí/õуû¾(†£Éj~uz~Úl6ÛÅb݆®nÖMlnÜžÏÖl+p¡Ë‹ÙòêLOÔ8ï/ÏÏ‘DAÀ.AŠ!„®Á¸°j—ó—]Øì_»&©ð;;{u³q… t©^åç\ÌfzVs?fÕzaX ®V –®¨ÊŽÛ°XÏNŸcè–/žb¬1ÆØ¶Ý€PÄq訋H´é·î|eñüª™_¼¸š=yþ´ ï ÛÅZ@ ¡mŽˆX|ð“”CбsÇGóåj4œ0UÃNŠÉÔPAyyùœýQQÄÈÜÔ!„ñNyxí&l`vqRUÕ¼^¾õÅ/Çf3ÜÛìºz³st](‹*†è$¸¿üàïÛß A²–;rˆjí ?Ø™<¾ûÉçßû¢—‘Ì´^­˜hxt¨â£Édòó?ÿËñ~·;zÝ92ÿ›Ú‰1›.^>u Ôk@‰iCHBŸÝýèÝßýÚ ØeŽd:Ó7ypçϯÂÅ;_úr×4äÀ%`§" éäêììÅé㯼÷7¸ó‰™ AœŸŸ>yðÑÑ7‹j 1A("æÑÌðâþÃ_ð£oÿÁ÷öŽÞlë:ùü{"Z^œ?úä㕜ÿî÷þPp€¼uÒ†ÙÀóÅÉɧ¿ùÅ|sö¹w¿òů|;téÄ€Äïc’ÊÞZùXšþ@;a@ 2ÕU$ L>oë´­þˆ Ú:ô>ŸÁÌí¦n›¦^¯šºîºn½\X½ÃÌ,]ˆWËÕ¦®™ãÖµsŒ!†.Ž [þ Œ™ Û2¡$©Ô ÄFþlÞK”g#!FíáÓ™¥jìÇiPªKŒÎ»²( –ãêðÚkÏž-Ïß|ó]:ƒÍŒ›Ð£»xþüêêìµ·Þv„9™˜U¬ÃÓ{ŸÎëó¯ýî·«á1Æs©8?;{òàÓñõ½oý»ÿ m¥+«cNŸ=ñøÞtúλ¿==¼Q©MOÛÈ\t“Í;sAÚ>f¥¯¹ìºˆ9;Ö£'ªgÝ>lÏÜ«›m${¥wMÓn6õzÝ´MŒ]½ÙÔëuá‹¢¬Èy"òBݦ]­W][+Ç“¤DæhGnš({ã,ÙvŽ•ð@Vb>ÑÖ.û j'…êÀĦ/̬…a2f_ PP³F»;·ß¹û³÷ÏÏž*úäÈ©Gõp:zýÎÛ{»Ç³yjõ«ìÚšÊêüÅ“®]&7nÞ9¹w6;éÚzq~Á¡Ž³Ë³²™/ëõU9¬Úź]Ì6ëõââ\ °^ÍKD 0ÃbÔ,–ÞcDôüÿsõfÁ–×yf®•™{:ãÇšî­¹P…P’ÅA2­Öè–mÉ’Úzk·#ÚÑýn¿tDGGw´e=´iɶ(É%qI€  Pó|çùÌçì93W?ì}νìG …[Uçì¹Öÿ$ÝvlŒp%¨ÄPl[VªS&ºLEÛ[«½¨‹4ÛyºÜ®oD¤D ~XŒï¬/!a%I€@–k ã†1)­ ÕA–´A©2Üë…ˆLr´-™0ýÙ{WŠ®#³|¢”B!ÏfÄQ7{Ý$ ’]p'ggu¢ Ž´¤-8GÎEQ &ÓLK)lÉÝRej~r|rfllÆ)Éòø¨%-n™’m³À—e9T²¹Œ¶–Û€¶+Ñ*ƒ(îÔê¥B±X(û¡ÒtT’Äñøì´W,8R†Q(^A $7ÀÑŽÞY¯Û%ÉØ®#mG /–=¤<Á722!Þ}÷­CGN’Úh† ³¦ öûMÌØ(ßúÑ[¯½þr²¸ÛVFG;unI‚ˆâÚêÆ;owîı4Ék¨»ŠEfˆ ±õ`}iõv©\Ú­ ¬sDRÊÆövªÃ¡¡1óÝóRçÞº™ˆÞì܉8Ôyð»oGȧàÄž<ñuwzö V.”ê»0έf­ÖilM8022«RµëjÆ9§T/Þù,1ù§…]6:¥0Ž‚põþ½fkgöøñÉÉhˆ´Ýº3ƒ$ˆ–îßéµ·¦çæg“–Û*öwuƒ¡> :0„Y§Nì¡÷ä}•¾W%«Mô3dÉÔŸ±·yüKL>ÒJ%I‡Æ(ÆH%IaÐó{]¥c`¢D“v%·Ë+ ¥¢Sp%—q'Q4Pò¼Ùß'™½ÞÚC¡ë3÷û»üQž /³ ,!È(¶D”i²³:GFLÊžÙ¡L÷!̹X”ŒÊ&8JC¥‰ê‰ó/4vZFù(-3Ø=ÐܱcÑ–þìòO·· ÛÛÛAŒÍ\¸÷Ø$íÒhujtjåáãf§ÎǺ L¡PìÕšíFcgc¹Ùl$=ÿþ£[ÂÁ¢püæ&BÄI¤…¶%„Ã¥e»¥µ•åšß%£LÄJuk›¥‘1fÀMÌŒMŽ?¸öd­µP)Õ¶¶Ú=ß+—Añ¤Ýî4ëÛ+ÅéчŸÞµ% ÛJý0 }×.î,-Y®“¦zr|èàÉ“a$uÛžG±@.ŹA%Láð¼ÒÐðx’D\(çAr”\ÑÐÐC!=Ï®t^&‘` a#r,8N†à ŒRÒ*=Z¸qö…K©6ÙìÑm—J€`I›52<úøÎâäØÐÔÁZß÷rfˆ)eÂ0 ;Ù¬±÷°f þø¾Ci Ï£˜Öמº $—D$¥½rûÞK¯½84úðÈ3‰d_BÓÏ ç1Øzø¤^_˜;vIJÜÝ–k®g«põ­··›+Óó‡-YèÂó#‹}eá±7\8xäŒ@ÙGD2Dít>øñV7ïMO–Kû©¨¾Ó–iU_]}|ÿ†zߡÕêçrÝ 'ýöÕ²Y¦²O’ƒÙV¾Eç<{<ä~×<ä`hÈÊ=ƒ‹˜]0îž{¡1qFßi·R•h¥ã0Œã Š¢ ´N1 ÓN¯KȸeÙŽ[(‹EÏ3šâ$匑åéÞlí•@ïÐìôöô³±õÁüÙ=Ö04€:vöÑ1&÷nâ ÐijõaÞ6a"z0Bä 8r‹Oî›==þ[úŸkõ»œ1@¼}èÔQ7œüÅÏþÎæÊqJõ-?¨W‹Õ×Þ'cf†‡Æ››ëŽ-ÒÔÄiâ–‡ a¥rlWiU–V©±µZžëôÔÖÖšÐîú UšFAà[¤ea¯›&rg§Y,¸”¶åe?²åٳ斬ôÚµ©ƒ‡ãVG@T,”†‹ÅĶ£v§8:´îTت• v+Ð1qˆÚ5i9:ˆÇ«%ÉAuü””[(úíŽS° + ü¡áaL"EF‘\’QË›w—ÉPv.6Ê[ðîÖ pÙi5Â0¬·šî=¾võý^èg>ë¨ÑY¯m"…Ȱli£²”1·èäIªÛkÚ¤Œi¥@i°\ghd² ¶k_þø;¯]xUkÆ‘!°ñBu¢:.k "íñʸàΓ¥…F-”œ3Ä6ÛÆâ(¦•³¤tä¨g[EC,ûìt{†!“-‹®ßënlÝ?ó¹‹CÃc®mUKå\ÓŒÐõ;d çbú‡ÿåýÑ…¡á‚KÛRªÃÅÊ0#ƒƒn›¡pî„NÆA`2ûÖqΫ…òk¼ü7*¥ƒ¼o_ê£*‰#š( TxìÜ –[XÙ²GžcÉí¥§ûO=4Üâ–@&òÌË ¡ˆ¢µ²½¹³púÂYW-)¤e Áç‚sD,’óÝ¿ü6sGOXn¡@`ÆÃ-ŽíôÏþí¿ ÕÊþ#'‘[}a/im>]üÙ›ÿmô@åü+o¸…*±ÝI6ÃA¤>øÁ÷——nΞ?tä´pŠ ÷4½`W=H01ÜãÜË6û“ 8rÎyöˆàƒcMŸ[œu½¡/Ëwny¸ŸÁ’3F½^ÐíVQäûÝv’ÄA/èõzDš&ZCNÎÏÞt\XÒñlÒØíuU#eO3äÙÃ"{ˆd1³>;{Oz··¼ËRf&h­Í®Ô—²'S–´ÌoùN†©†H)5·7˜Ìù}R+‹N n !„\HQ⯾òú•·~Ún¯²¬c@ˆѶåÉ7ÎyîG?ø/å¢ÕÛé^ùù‡f†Klü£÷è­Ù¹Ó;+ÛŸ~ô“0ï\ù öÏS~È-§äGAûÛé¤ÝØRq»$J[O—¶7q6Xi·ç3%…¥ÃHé$RI†Ív û¢öÚöNäw†çg­Dh“”ŠeHEv8cÆN\ Rà¬=¹Ý^\]Û|ˆèÄ~¢˜èöºÓû£Ô¤©j¥>c¼¾ø´¾vŸŠEML’ÔXdâ8Ñ”jƒ‚’¤·S÷P’¦JkeXª3b½Nµš—²Jã“ 8 ïà±Ùç/ ác²óC’j۳ϖ•I‰Ôîµ, îÚäEî ®í¤åñ 853ÇÀâ ØêRcvßaÎQp)¥4)•ÊÕ Ñ#m(Š[œøh¡0:Yá P¼©jE!(I’ “$!º…'OžLŽÍD½v«×‚$Š‹…‚`…‘eKqãêG­zëÄ©‹*5À9RiÂmÁwdz¶X±mûî•;¾òl¢‡2\¶1«¤8>†Ìaĸƕ»Od•ÏÎäØ)¹gÁ0ò\çÞ/>š}vb¤:ÍLΆÎ‚ @Ô±úøíMÏ{^˜É(‰YƇ__^åEwtl )«eßd@ž]ú¤´:ÛÛõ öâëo½)Æ9(8 D‡;¿÷îôçü‹¿*Ðɸ"ÇÞrûíËÿ;ÿúŸ=ÿ«Iª³ r‚OÞ|÷êåï¿ñ›_?væ’3™­y×vº ‹ÇŽxö…׊ÕqÁÅ^âd¿„GýžOŸkL¤ûзŒBnò¾7 d\{8™yÑäwÃþ„œöø-ûlã=Qyc”VI~ièÇ=?ô»iœø½ ÕjSš )mÛâ42F«Ô˜€YRxŽGi”&Æ(B`\JËqdæÊ½výxü.»–íFò÷¨Q .ˆ˜2Úä:tD@™ùEpÎ9 Ž9dЉ`ÛÖÓwoý¿ÿçÿ¾¹vC ‹#ÏF2B KZ’±4ŽÀ(dŒqžŸèµÚ£Ó#ÍH™4)T 7>ú$¦@1lÆ=öºßiÔÐò¶kÕB9ѺXð«†I·]WT§ 2‘eÙÊö²÷ ¼Pm¬nå‡\CZ§Œ´ÉÚ •$À¨`[ŒŒ#-§2JÜ"“©D˜ë8œëìâ– Œ[åá-äðĨEP_]R H"ÒPð¶ÚÃO«“o¬;ݦgKÛqìjeäÀ¢S {A/îO9…B˜¦I”G÷°Tbt/ŒX¬ý¨5=>Ý©×[vÐm2aY‰V–m+cT¯>|xúìI"S m­²“? ­zhï?ó+*˜aùúúºôl·È¹€f³þpùúÉ3/€qú‰¬<›™»Ú+µŽhLŒeX~îÏümÈ8cš]óç£ÏŽ 3FsƳ .k›±îŒNMäçÊ­·ÙräkŸÜ¿våÍSçÏiͳq­!ÒZgJ?Òtïæuož~Hf[òþm”1evVÖ¯=xÿ¯ÿÊøøÑ0 iW. ŸýôƒØj|õŸýåH•{ˆÎ.w*J¶W–žÞ©LŽœ8u —iOúöÙüÆ€òžm~§R&ûUò‘&“}ª´É †ÈÐÀæ`ú’~yqW¾0pcíZ¬‘Q*M'I%iÌQ„AÔí´ƒ(4JõºA”¦d4JôŠ®D™Æ %qª”"2\J[Øšñ8ŠòžSžíAaÙ€¨ûi]“K²h/lsï²2ûþ?ÿ›“ËXÆþ$†{ƒaýy|ž§»Œ†'Ff穈»ZŽ›€2̃ â( б2i³/.Xi-n?©r•‘‡ò¸‹t,‰rᳫåQ÷à¡ÓÝNw»þôäÙ—¶váú£'° ««Å¢m, ñ\Ù‹U mb¹%ÇX×®|R³«¥ñÖÎØÈX§é×;u×*8¤‰Ö¡/l7êub`Q¨f'ǶÂàñíÏ4Óa·N”Ç7·–K•’my­^¯P*Z®Ã¥AD¨Zm¿4Á¹É™K¹ŸÊ¢³¹¹9=5$=¬L¥Ÿ¾ÿÃg_¸dO4ƒv·ãØ.f”`´tï‘V0âiÓW&S.XdÀ‘k•J€I)¹!ùYMy¤h9C¹bLJ;ºŽe7¶W«C#—ß»µÑY9ýìY‹[Ä€ œC^_Ùq‡Ò©}Ï0“Kã–Oq—{à:eB!ÐÞ^^Ýho˜;a4­¯¯ª ª9šLit¬\(/ß}ŠU¨:gJU¯ˆÒÈ-ÇnÔ›qÐ-•+ KwîüâýÖQšÈú3h†DÚõgÿÏó_}^PaÐròНàe"Ò°ríÞÐ!gvß™T+èSX²á“˜¶“ë½ûìsÇ鬸> I[Þ~ëÊBúéW¾ðO{A°Ë#'†­µÍÕ»ûŽ—²˜!¨Þp†À‘“2ë÷×ãåW¾þߙ𗠽€œ«n¼pç3ßtŽž}ÐÎ?Æ1@TA²ôðŽoÚg/¼b´UÝî“»wË3î¹¾¤gLíB  cFc}é©ÔçOœ)—G÷Ìo`w¾ÅúSÿÝ™äŸ\=80äó<úÐGú±~ê³Jß„‰È,q`LŸ•LÆè¨×Kâ@«4À©(î¶ÚÌÂÔO{%ÑÈP©XBàíN¯Z±¥Uê¶Z¢%M†,Bañb±ˆÒb Hk¥rDÈÜ¡,ÕŠõg€Ù_¿\—?~ˆ²æ‡6€‰Ã1ˆ cÀûSû<Ì™ÇQ±çœ˜Ù—$*Õº_D!b`¤iÒé6}¿c´bÄŒJ*“ã ¿Ýåd¢(ÈpY¦btfrfæôµw/÷♹c~d×6VOœ;b{ãéá—N{Û;kœøÆ“GíæfIØFùš[QÔÝèÀ™3ßþÞYÁ0%ÖVŽôö»Úf”Ò¦éwMľ^yüi¿2ZrDE¡ÀÔ¯W+åµ…r¢É±ñÎöŽ,Û«ø;Û•òÐöꦱâ᱃õ­•Ÿ>©×j=µ–}Î’Ji\»ì·SדEÅÓîFÆuж(a\òlo…\|Ï=Öîuú¯ËlÝŸGY‘±v}À¬PR£bôÃÄ4kÖˆ@iGˆ£KÏ嶤;§O)•Ëp7G&°Óë8r4“Bd xn“=9V;ÈÀètmýiudœ O•Ú7{ ×î8EK锫ŒP¢Xßx4»ÿC*û(GQÔî´X·Ñb¨Ê7ÿáï>ÿÕßL(Ÿ`ムcްï\¾vàüaWìgl0[`<‹tð^­¹î?<4ÿ|%9n$·'0Æ Üûôú‘gØÅYÆHét@ï5Úxž{û?\»ö»ÿälaNÀƸ͵ÍÕå;GŸ»`ÛCZ+½ 3ϵi.ß wü4FÏ.lolŒ8¸~g±\ VQ[FqlÜá® š­ÖÊÌáÃqªLÒ-•«í^Ç€®8%G.º“û'†‡]PÍnÛ²2q·Û©V* ­á‘ ‹˜5âNÏœøäÞm¯àZÒFÕJ5Ãæ„‰n¹â0WÇI6!ÀçÝäô+«:’(Ê)‚D®em/Ç£zÁ½«WJü ¨”GIë4T„Ü.Œhƒ*ñ™Ð9i§ïÁyTï9Þ0bÆ#ÃÈvŠÒ9Uc“øÝgÎÌ¥9°¤“lmßs,™CºµÖÄþªËËyv—‰B?ÃÚNÌL Ow¶W6jOŸ9sV%) õý›Œ1­ôÒ£Ååæ½Ó^@Ø#ÊÛÅŒˆ7®¿sáó¯r,à`tÑÒ ð'‹Ò †fö3Æ‘‘%$7ùA¢R*}òεO/üúoüv〉 Äl);›õ…•‡Ç/œ·äˆ1)²üÇË@Ęö¢…‡·Ð¡£§Ï¥‘f}Ç]V¶„Øzºz÷ÓŸO?~òù4ÍKÙ{DJ‘týå…Åñê¹SH2㸠NôÒ½»IPÛèpµ<D ó¼p!EÆn\ ÂÚ¡ã'fgæ%—Ùð[ËÆã(rÞ'Þȯ®¯>³Xís0Æó…É›zÔ×â0Â,®Dƒ—`Ÿ™cŠw 0 ϧºÓlÄQDZ¦ NÒ$Š…@¦ ×ëyŽ54TÒbŒ—F3m àœs!8—”¦Z)K @®úí}¸<F’ó4³Ü91&¤”¶ôJÞÌþƒ)1ÒÔX[–Ó @æ÷ºûOñf×&I°²¼Z[_©LŽþÖ¯ýöÝË7W×>™ÛŸ¤¼¹½U© ²žÞú…7^ºðÊ¥öFoþЧ·î•G 3Sóa³;ºêþ­+ûNO½ðÚ+Oo<âž$c5zëÏžþÜÍ> f¤I™Ž˜R‡Ž¹zýNc£Q¬xÀY¡P™˜à¶7;»Ÿ+Þì4¦GömÔZax^©ÝìI‡s»))2ÝN‹¡Å¸LƒîìÁC§ˆZuº¿ÓsmÏÛ•ÉáCåñ0­÷­»ïcnÃà‚#–„»ÌWü¥âä\GY]£(Õ½íhw}GÜ•£÷:Aì·mä¸eq J•dãZ ó>S‡eõk¼X( ¤i×§€9ƒt©ƒ#eJsÉ•åÙ£ãû2ƒ72H‚0qœ*dè1Â’Åò%l"BŽ++w6Ûñ±ãsJGÜC Ab $O††«ããû‘KÈc}0 0 ×^½òHO4Ï>«Ó„ö®Ý³o¢Íª3¥ruB›þ„”1cHX2hÕÿæo¿ùÚ×¾4=1ºO°º¬l>9pôhÑ­êL„A} # cš]¿zyøàðô¾cÈòÃcŸ&Éùý«×Ö;kÏ}áKÕ¡é(I¬`&¹uçú•Û?>ûÊKoÈ3š[yøðÎí&÷Nì›ãÂfD{ø,Àºuùã…Åó§NL8‚hQVŸŒ‡³± ô?F}ß ë£iôùË*Â>†qψx`K%ÓGºåâ_ ÀÓ@ìÌ“*•$i«0\Ø–jEÆ@Ú¢b©ªzZDa[‚‹8Nˆ‘p„縀h;.g{þL«¥W7ŒMOCj&øs/ÿJÒ‹»qì+ÆÈõåxÐê) IDATùk¿ÿÿñ›L°Í:ç²2T±Ñäb%˜,Lª‘©‘é}/øQ ÜJYz­º1ÚnÐj¸žÇ .¥š ³«CIK×Ù·¸òH' æÑ–<Ñ”“‡‡gP–2RvN(d¬?LF&U¾Ö&í¶¹I‚n['AÄÆ÷{†ZÍU¯\ai£Uricz­fjÒ0ê&”¦ˆráH›dŒ2&³‡å’¤þ.œ\yòÉ 'ç•æù0ë‡gΤ^¯-í‚àv¦D"@ŽÜvöEª–Jßþæ;ø¯~¯ÞT{øFÌ0B`ÈÀoöž<¸:17nÉrVŽè¸ó·lÒŽ®>yçô¹—â$÷’Á`\¯ ë-6–»K³³'Ii ¶Ë5GÐ]uùû?zåùçfŸ4FôÁ*h˜Ø<¼ñɹ#wòŒ8íaòiã‚{íý_LŸ˜=¥ eäÊ‘{h£¼ñö{;­ÕSŸ³œ‘8N™)¿öö«ã¥¿ükRT1µq‘¹sùÃv°~öå×JÕý,“¥d—gbÈyRkÿâ'ßWvï™ç_)W'sf\Nºƒ>´™™ŒU>@ºä§ evðld>¸8Ñ@†€yÐ¥&ÊïO&gc D…ý]šÉ_4F›8 ýv7|?ìÊ’ ÒR©ÒÙþ¹ãX¶ã…aT­·8 Ä ÅŽcq«ˆB Dn´Rp2ˆœª¾Þ<ãd¥Z)¥µ1ŒdŒ´N“„Hï5Nïaæ ÌÊÍ90ëC!æ~½ÕÉÑ)ë³OúßP(Hç­oýõ‹—.šÄƒ~Ÿ/'kjm©Xݾÿá—¾ôz› Áh 0ÐIúƒ¿ÿÛõ`û—¿"¤Ëˆ´ÖÚ0­5¥ú“ÞCLze²Ù3@ÄüÉ·¿S˜6s‡Î‘Ñ™' ò½-3qòàê Çg_~M0Ëh¥UÚ¿Qa¯Ù¹üá;Ç&§¦Z(€AfŒÓíäßQÏœ{•3œ !r  0 xzåæûï½yðôÜéç¾hÉæÏô]‹)!fOtˆÙdCÒYv›Dߤ4èÔ3†1¼/2ïówMß®ý˜fuÎŒý‘&3ñhöô"`¤´ÑZ§Ú{a«aâ N#Çq“ñÓ Á˜e[‘ŠfG‡\Ç´fÌGr.³dVçRZ®-„0*Uql´ÖZ§iÅaš&ʤÚhˆœ¥£$&­vÛ@yÃì>ód(ÁHj3—Ç;åálÌX¦z—äe¨Ûé®--(•!peuÿÔäØþ[^^xò)1ù½Ç÷îÒŒÑdÐn­=] Û›)Qißð_ÿµ«?}·ÖZ¾øå/ nõZ-V[[]®mþÆ¿ø?,/>zÔŒ;Fˆ´Û«×—:×mûŒ©gΙ;=9s8 b°åñ eĘ-ý^—ñõßþÝÕǤ£‡'fw=å Ÿ\i*?ôãvsg{miß±3ŸÝ|”„=¿ãw°ÝíxC…Jy„§É„`J7ž¬¿ûæw“N£±ödhltçaó“‡ïG‰îÖÖ°3;÷Ls§Yp¤p¼PS¬{çΞ[[X©ïs’©8_„Fĸ°ݾ{íƒë¿ûÇ€vA«ì즉4«/.–Ƽs_ú†7R÷s…ÄQ$ÝðÖõ+¿üÚ¾¹çã(ì@2§Œ¢€9CÅsŸY¥Èä‘ 2´vçÁ“§7?{®T6Je X¹³påÝŸ\øâ¥ ¯üºÖ8ØpJôʃGW/¿=~tüµ¯þž°FThc”!½»£ƒþÜ®¿ïÊ sØ7WaVyÉNÐýN ÛCºb}µCŸ6j²âõ1al¯¡ ÉP¯Ùò;öζI£,\ãw{Z'qšpÆ´ÖIª9p¦MEQè‘V:S&˜ÒÀ´!Ê0q( £,á•Áü4Ó‚£ÒuOå 7ÇŒœj¯Þ 4ÙV3ÃHO¯ßãé‘#¯ÄQÁ¸€ŒáB¬=|ú½ïþù—óW¦Î'a¬ ÓJ1@"ª­¬…Ioæà×LiÅúpJdÄ{µÆë—¿tbxhš$ƒŸ&û?nU8@cq{eõÖü‘#«·95‰Xþk³{óþj­óèÌÅ/$ψTŒbT,6î<þëÿò§_ù_æôy¿ëgÏ_M$¥Ý¨×Úq{rî#‡‘¡þp™…ݵí{w¯MÎ(—ÇÉè|!BDøêâr˯OÜ$ûº çØ¥OÞû)ôá çK¥I­4 8žMýÁ[ßK1=õÒ‹Sušfwm!„Í­Í…Å›WÞ12¹ø…/ ΡI%æM7É…à‚³¼Æ›¶²‡‹fL›¬©’mѲüªÑZ„ö¿úbì§°X¯ÝnoouÛõTÅùo ·Èf30–AfÒ$"c€…( €´ˆ‰ ¸†(èi¥â8êvZIõÚ­( ¹®[€èX¨5 IõünÆ¢ Œ¤ÈY£Z©ìÀŸ¡"GfH%*I’(M•N #¥u¶Aäy Çh{¦0Pkôñ2ù˳ðÅ®ý3ž£¢G¦Î/Û}‘kcˆ³é¦'÷omm2Fr×q,Ç. uëí'Onï;¹ÿàô‰‡Û¶lÕ·#"ïGFmüÐÔ¹Ó/\ï}ÍêgN_H[ñÍ~V)×××Êž%S¨ m­¬5š›^y¨½¹£T˜¦F9`¹«byVáÖÕJ%{¸2d8JŽq’@±ðú¯þú÷ÿê;n1,ÚÕ¤ÙÚ®m*Tãc“&VÚf’öö8256çÞ­ÊøP:::¢5VJÕ±±Q¯\oRsä  <199:}÷ò§¾ûCîòòø0asž¦týòûûNîöÌ‹;››C#£‡Ê%E1­ÚÖñsg¾uí2ĉÓÏ4—Ôµ÷þÍ8'ñôüѲ´¥³3û[Û[£££¬ÍT>{çf£~{¬<õÙ§WÊ£ \d¼ìÚ~ä½päâ¡—?øÑeò,§\£c6JK [¥ÚÁ‚p÷êR­¶â1{«±zêù‹#¥¹$"®õÁ“‡ 0Òòx•ñ¶ï»Ã%•¯ä>|&èÕâ^hHOLÎjRI¢¤öP"{;Z;qñ¹N¯L÷g½!K’äðþ¹¨Ç£1lOá JçaHžó 'öðþÕ꤃è0½«.§Ì¥” ±[gLfS`@šÏžœz|óÑJíö×¾öûQ¬ Cy“Vd”Ö†¿úÎS¾Z™ÔJ:ÜëîÔ²Ê}š¨…õ‡#Ž–Ê“@_5‰YÒ^}´øƒŸüÍ?ÿÃoŒŒÊyŒ1 ›?ÿ`òdefö”-¬9 1FíÖõ»?=|þŒíeÍ`¦9||xçv/©OLNXÒé[Èh’h?¼zýéòÍC/ŒBó'í¿üÿõÉ»_þÆoOL¶P2CÙ¸És O®ÞúÑ›ß~öó_~í7K•q)ììÛdˆåqîüú¼§Ÿ™Pûži@DŒ#pDž[w³¹c^Ì;…*íÔëKî5›;AàGA/Jâ„’átÚMchýéÓÆæV·¶ÉX~éÖJ…¾oHe«•*"ðÍN}»Ûj쬭m®¯·[MV( åªçºn¡P,—m§(mÛBÈÑeÛn¡`9–¶myiœ¢m‘fœsËr€a'J©8ŠÓ4f@†Xª´Qš‘!2†4b:‡¯k£Qçè<¡ÏÌ ýk†À!#T B†Ðæ|ÈÀ±¯÷ΆYj†‰ „BîyîÅ_¶÷ï¿ùg˜¶KŽ-ۙؿµ²0==>Z™é6ûŽÞZ{:;9±½´ÔÜÙðõW¿ò•᱓O=¶«…ѱC&ŠêáÆØÔ¾nØ™>xüÁ­ODÑ…T#1¯:¶±¹æU«ŸÜ¿xñ‹×®ß?~ÀÅjsgµioïø½Õ(LV=8óÆÅé‘î|\*Û½P7Ýv«ÚÙjì¬,GQíúÍÏξzîþGW†gª~×W‰é6Úþô'­°•úÂç¿ú¿üÉÿ195J½Èv¥%íÒhqäÔ±ÕÅÂĨ&Q­2ᕼBø¥jõÀ©#öΙ3çlQ ’ _ ­³}«ÑZŒ¬|²HÌï7Æ€1Ñ6±mŠ–¬ é8:MHu\«5ZÛ‘J<›w£#<°ï€Bj¯¬q¯<<4>23‡: Ûy"GLÁ¶‹Â‘çˆÈY–¿G´÷gß{göð¼ÒÈF%†LíqÔ²3Ùá)¥P‘º ™ëÿ¯íùαƒnuÖÐm;Lí IDAT‡Hdª8OéÈokº¾²¼~ñÂ¥¨Ç*;k“S{h`)Š£9×éµ*%§ÝÌæŠXf´¤FlËu]¥ñ8*HÅ›_IŒž04‘QC¤T5ýÌèþH 4±1!`™ö¾õÃû?uÆí9ñýQ j(Õê´¼Ðàk <¯Ómú¡ÓíU¥6úé3ú´RW3êC5ãz©¢ð<‰4š6ÝF!e燛MﵟýÂÎZ¶^ˆÙ{ñ³s¸ðëwìáôéÇŸˆÜ@*¡„ð=7ìùÕk7ݨ:sôn‚´x!6 d’¨qs}¹üщ»ÏàxŒ«úh;¥ ô£÷ßx31›ž<Æ#ÞoþÆã«—oìT×fÜ)…BR*’«Ík /þøoüÜ£§yJÛ§1`ˆXåúòk/>wàÁ½g>ý BôÛµb!cÚÙn¾£ »úéXþ¢rq5@X!q$[Ô¶ éuòÚòÖÚÍn·ƒ L !Ô0ÃQ¢K¡8%ް’RM ¡YIjZ °F<âc·Õ•<ð]·Sk´›e§Ûª•·#¦ÒéÂH±8:1T±’B4‰0H‰â@c¡ïHÆ5¢Õº=!9ç‘ñaÌèUJ¢ïî›MÛF€ƒ€a ¤äR¨A® „ã¡"¼ÿ+É×ÁWsm¥°‚A¬NB ã& îG¶ú:U‚ÉÀÇ=@:Ę»#†AÄÔ{À\©ñÃ÷œ|ú«ßüéO^[Zº`S¬'“”#Lˆn«I,iå ›ë«\öî¹ïÑÆ¦ûÚ/šŸIÉÉn½áõǾþ™á‘ƒÞ½¨dPY]!$š_ºtÉéµ›ÕmbãÕ••d.‘. 'î:ðäââÂÔ̼<²XiVK³G¸­ÀHÈâØÜÿêçÙ¡ÜCwßWßÞL%mÑ0p™|ò©Ç¢ gér¹¬~È]¶¹´Uí•Fò™T*ùäãŸm5a$­”È yngjï˜&{ Ä„eÛ–@e'ÝF˜A³,¸?°Ç]±¸4£ÒÙ‘úÆ<€<¢Ø°-²fªôÂgRé¤iFÊÕ(vªáÒÚ²a‚$@4<àਕÁŒK§JH@†¦Y¶Ù¿PÄ‘ø_Ž0…BJc#`Œ)-onõhë1¯Ø•é! ¤ÔÚ¦ gjß1$%!€c~@ü• /}xis{1•J*!cø¯T¨ÓlGF–—KC#…((Í·<.}£>²RI@ÀC¿éÔGF'uÛÐ5‹HA5M‚0’©·^ûUî@êðÁ»;nLVJé†vãÝó`ýÌçŸðÜ@B9Ív§ºît]d«Éé½ë\ˆÖ—kAÁêõëë¥wžègLâó,R^Û¾ð΋“GÇæfOF‘RJ ¤â³ƒJ"eŽd|â³’ „5´ÈeK?¼ðÑÙÏÿ_Ý·ït4`cª‡Íî¹³o\ºò›½wÏï;|? "$Eü–ñõW€*ÓÆ<`¡TßyÚ¯@ìr)âöH¿”Ø7é!Ä÷]·¶³³xéÜöê-Ç©]Óu; ƘÂ4Ì0 J×,qoOaÝd@ˆ’%€ ‰¥ Y£\V*d~è;]…!D N§sÙ|q4•6’B©RJ×5¬ˆ¡D)…¡\£Ôm{HEŒKÏqÃÀ—ŠƒÂ!smÃ$„PJ©F@r®”œó0Š˜àý„Í€¬¤$!ÁçB)Åwå´ƒ2ÒÇ$:ýÜ¿>†E稻p‡]Û;ê?§ƒäÝ]Eÿg‘ä,Š¢Z¹Ì¥Ø¾µ‚Dç›ß|æÊç]ÚÎŽN3ùкQ01·/xldØHfËåš/½ùCw[8ÿ™Ò éyâø±¿ýÛ¿øÇÿË?j¬‹íòGùDaá•›]Çÿú×¾™T…ÅwÞwy³Ûs%ci+ûæ$ QéFS³{®,Q‚4ËÒ“yåºvcfß±µ••Z}krz"›ÉőȤ•´ŒgÌÎ&¶*µ(ôqŸèv‹J©DÆÚYß² èg,1Äʰ`áF[„¾m’é½{hBßY,;ÝÚÍÍm%‘‘"äT7¸1™á2ìtÜ^«#Œ„”HÉ>XH(FŒbb[I!ûœ¶þO)5][¸p~xx\õ[ÈJ(%d¼¥ Ëüî_þÍ3ßü‡¾ï©þtÅ<%Tm­ôáÕ·§Æ§˜ï¹~E¡T¢Q-[–ùÌÙÜØY\žžÙ FH£LÆ¢B²v.±“2<ŒTr,?yíü{G8úУO/¯o5¶7zÍÍv·e&WϾeíÝGŸúU©xÆZÙ(a`ùâL½²•Ÿž0­tÿÿ7ê Y רvøä˜˜ý„½B#LÈÆâÒÖÎÙ;LOá¡7Xš+ŠÈêÒÍ›K7¦ŒM=_Ji[æÎõÕóK-!ÿò3)s"¤¡ØJ$—?¼tþ½_qâyæ«óûîü¡¸Š‹â8p|_ÜÝL)¤äÇ0éÛ¡û{°¾õwñ³ a€Àq·W–K;kÝnGŠpzïžd2«ëVœM#D麆”âHœËH„A –Bj¦ñ RRjDóºÝn»^ÙÞèyõ„i#É¡Bat,]²Iªë†eÛ©4`M‹ çiT7 ›R ¢ ÃéºHàx•ÒÖúòÍÒÖ6h¦0œÊJ] #%% ™æ"¥8Ƙ`HQ)`¾ˆ#DœN«YÝéÖÊ­ò¦ë´*¡JÓ“Ä ™á¡d®`˜¶aZR!J(‘Ha¤é¦¦é„%S qJEAè»ѱnXœG Ýju;Bp!‹"ÂH$c(#ÁT ¸nĘ×óRl+럑â{Gœý“ý £Š‰?„ :‚}vÎÿOQˆaà5‹·}IX?Aƒú䮃ÔgÏtÓs]æãr,ÃNçóžh9ãà=§¤²¥ ‡OÞ¿~yûÒ…—¼ãÎ{Î Ç-+‘ÍÚ‰L«YËMŒy«vêÇïºoíÆRäôRI3ad‹Ü0´©imce!•²Ünsrn‰“Ín`‚Õk×½«Þh%3Ù(OÞwlãfƒ1Ú^½P89¹¸ÛhrÝì±ð›¿ÿ‡ÿ×?ý·¹ ûþã,//¸÷¾ÖŽ×mº¡Û˜Þ;7=}°í¹Ì°Ûñ‰!3ùÂ¥K7RÙ”%Õäü4E4Ëë†N§Ì¡b»VžšÒõL«´ihŽÏ0H)Œ±‰M´v«Æ—2Vvà+„ $1Ö¨l¦}–gqt0™HŽäºžÄ¤D2šÚ»·Qa }”#EéŠs&.»ãHFŒÉôáTš+À€H%D áz]ËHÄ@ý?Œ›õR»Ñ³SYË4ûÅ-À'MûoþêÙ3OÜÇ¢>}°¿=2uÄÄ*Î" µ‹½2†é¬Ô®Ž}àŸ2®`ÂX Ñm6W>ºøÖ+¿¸qí\a$“Ê )<ò€b‰ "ˆQNBH ¬×¡’–¥¦šF(ᔪ@D¡ÛmÔ›¥Ryc­Õ¨0 Ÿ ¥ !KÓ0¡ 4Ýs=®T$9é+UÜ‘–,baä¹nún/ð<=aæ2yúv&#BbB…ŽÃש†â$€£(ˆ"?ìú¾BR Á8¤(ôÕÓÐkàXÉ#¤$„h„b4¸ÃmWô@.ÔÏ<,†»O6µ+oN’ úX¹>j9~M`¥@aÝ Z« Ï+dp&ßʼndψÉT¡S­´ZëÇî9µÔ…K„ȱÉÓL¯ßZN²…„¹cÓ·._)ÌÛ³“'z½ZWˆ„¥k:8í6’¡²¦5Â#ÇLä·Öoî=zX“@¨.\égó“Ú¶‘IDaçÿý—ë›+¯¾E³‰•NäÇ‹åò¶ö¶n-@OŸxè…ç¾}÷#ìŸ?F[Zߪ—>ZY¹Æ”{ò‘‡ ™Ü{ø„edÝÐu"±²ÝýàWßMÙÃㆠŒûB*TȤ’C:!zÂÒIÒ+9 qÀDɘc%…”Œ³ÌÐxµ[—¤ÿnÀý  có¹/ì"$b¤5à>HJ þË—ß Ì ¸›Lç©iõºíPøÊ¶P€ ÄCɈA#·‹d¨(ñ…A.É„§ÁBq€¸':XӹЊeÝÐG\QRºUe:AH©„Db_•B‚†ßxýÅÃ÷>Ä£R€EŸE£tCãù—?ó[Ïx®ÏMõ¤™žœ F2«¥¿ýì·C§V,&¦öŒçõf+“ËTÎÆµkn}£8:²Àʦ·——ÇöLTO&RÍN[ °Q¯¦R9 [V;3mh(ùÊ+?ÿýþt.5´³¹Újmb%5¢4ÃðݶJ¥&ÆörÎ!Jp³ºÕêÖmÍúà'/ûÉÊÉS_àL .+¢,^¿ÖƒGOÐãzl<òV\®]¿81Wœ;v†è)…T(êú?ùÖwõlêË¿û‡ù¡)¥pœ&§€«ËË?ÿÉŸŸzìÔ¾ŸÐh".])ï›Óãx6(…Rpûé„ã/ô±bB9@;ÍvscûÅ¿ùÎÕ ¯L†'ç3!΃Ԉ¦"¥Ô¨4ÄÑ„œ)¢„Ûì–¶·V?j6+Aàšº>44¦8 Fc¡ÂXpEaà¹ÝNK…!BŠAä9QàG®çu›®ë(!;¦ëtb†eŽ 6º¾nj°a T«Ù‘(Òu0F˜(‰‚ÐgQè„ÆJ)Äãû ‰ïÉ ¥ˆ¯nLƨ­¾ØQÿ¢Ì`“² ð‹„ýÑ£PH)bƒêßÊå@oãîA*\(„”ä‚s!SÃ…‘¡Q]78MhÜ÷GÆ&-Ív;]‹šéLn{³^ª/Ÿ¸ïÁ•sË¿yå§ ù¦eé\î¬-‹£™.“–_¾qeÙâ” ˲föŸR }7WÈ Ð×Vo¥“YÇ«NŒLT×…¦x€ÂN7ÂZÔkgòÅf/|øñ'_åüsßû^·QÎOµjÍÍTW¾òÅO”zëµkãSS¥‡ŸxjýÖF"“\[ÛÊfó{ŠsWß¿ûñZ"ƒMëð¾yÍ”§sE¤RYU<"†ypÿþIsïÛï¼213‰tÙìVwuºñ[”q669á”—°c)DúBp.¹RŠ)~`b®[„1ïãxAŽvþôG\F1¤Ù8TYÝÚ¸öRÈUQÏk{Žç‹€˜Z×í0ÞKzÆÎ‰î%(‚?šè“f”’B(É¥D …¢±oò`ÊÈI$¥R X Ÿ£„._½1¿ÖN™1Ô\J›] ¼]ò¥Tzž &b¶1@ÀÙTqòæò¥BÚšAQJ Æ»aN1B(!Xú®‡•bWJj”BRª‚IŒñaLħVÉ…”ŒŠƒtøc½W5ØRª9²ÖŽ?Ý]ÆŒR !•ŒÉÑq¼½–1d^ ÎøÍ‹¸pã]‡DÊÒuB0%E~zŠc!\@Ñ¡»Ž{õÈc½{?÷dT¥/ÿügõfeîèáÙ=GW—oæg§šÛeßkú]öŸÿíÿÑr*:$ünÛg>`]‹Ä¥ÞÓ°"2Ò9!€cš°–Vo•<ŸQáæóNºY­4¾ÿÃÿó¥ï¿kb ˆgGG-;ÊžžJ/—ê_ûúüø»ÏÍ ^ñí·ÿ¾8†·ç²¾·ºtãЩ#wû4ç€WKï_zþ¹ï=üµ/~걯u_Ø€ÞµWÏýèÅßùƒ0^œŒ¡ÁÛ<þJ°F©FÆ8GѸ§Ó×”!EŠ{š$žC<6)Dmcýү߸üþøä$(,E˜J5êHjÙÉÑL‰ b< |)%\‰cAЭWË«›k+ÍʶÇZ©ááé}曜ÉdŠš‘0,ËJ&ã±·`,ˆx¯×s¶¦‘¡ô°øÝ ªolvšußuý(pº ð SOg²„3‘ÐIEh"“äqC7‘Hú“9ŽO•¤dAÀ£( C?Œ&B‚N,%’HJûmr%ç2ŽJ”ĘhTC±Ãƒú¸P5¶i ÇG±"®*1ÑïÊs©x¼<’‚!¹K-Œ'`B.•TR)1Ê‹\ô)ÀB!®JÏäY(zš‘04¬K–•Jd[¥r¥¹ùäÓ_X[ÚºµpµÕi›ÉôÌÄ\è´ö̤’jYãÀž‡ÿÝ¿ús×ÙH&µzY zò'V®Ýè.ŠdàvuKw{ν¤*¶› ¤Çd¦˜õŸÑ™`œüÉ¿ø'ÿóÿþ§Œ`Æ¢¡á‘°TëÕN©ÅôÞC§|ûµ_žþê=¬G‡FÒÛ[µÀú뉔i‚µ³zåä©lA~óü‹µÚB«î¹¬qäþ“Í­²ÓîJ% ¦ ³Ù©w×t#×n7xÿQuÛ#N¤Y¨YiI)±N‹c‚3¥RHrž›šØXÜ05¬ä®!‰Œ†&{¡p;^ºD#Xa¥á‡Šj@0`F0µ2zÂ̇4].U¸ëõš= ˜Ëþ¢IJI ràÌìôì>DBJ‰@õéH¨SïtÚ-•P@áØO#¹PºÕjµÚÊÍìéWMû¯1‰’nxãê;™Â¤d!’J0Æ™šMb[ç~ýÒNà/¯-gÒy]·—–®¥Çó jø;•Ko¿1¾w.?6­¢ˆj¤Ñî]ÇJi&5ÛÕÚ›ïüf{k}HKë £Óí"‹g¬Lu¥ráÆ[>ùõ‹/Ÿ§…èŽcgêõ®¥%ê;›õÖÖþ'(&q¦Ûêܼ~ÅÎØ^7"ȧ3Å©½ZœFS€{=çò¥ó{ïÞ7s?ÂùD „š¥òöbqÏäôþãŽïŒ#'¼ööo>¸|öKßøÝÉ‘™^·€—å•Õkï½ÙÒªÿäÿT)K ™žÝ ú`¬_C°‚>È ŠELJ1pØ`ÎD}sçÊ{oðú‹‰¬](ŒôZZe›…>‘aYЉ€yf®/N˜†É£P ¡éf‚sD‘ï¹½^«Y©”6×*;ëÕÒ6p6T,NÍÏOì»chr.[£VRÓ5©¤™00 b )ÌÀ‰lX–nša´íf½æ¹.Õ¨Fu…¦Ô°¬Ø<¯R ”´ «Ýëé¦.çQŠHÓu†n·ãùn2áB(¢i0J!/w Bˆ˜ÓŸga ±Eé6_vÜ T ‰Éhc€Aî£?Ìg‚q>gp#Œ åÂ4žõ§¦ujÅ%¥dÌrèuÚ=×á¡›Ì%…Pv®ˆL3“MëÄÞ\X’$ü½?þãÑÄ̹_¿~å£7]ÖK&‡¶¶wjÍ*Õõc÷îyêé'øŸ¿³°yÑ´Òn³éGA­Zɧ3;k›ùfÒFšmÛ‰ÀkeÇ& >LŒx*•(­m OW6¶‡æöŸyð¾oÿû?cQ<97SÚÜÌfúæúȾQ¿+V7WùôSk;›ûî¸ëÖå Bc¥ÚæðèìõsWKÎöïýáïì›;õÎÅkö•Úòvºn}dtŠ PHB#ÇÙØ¼E 4{½HˆT&}ìÌ'42Ô–sU]]ÙÜY9tò„•˜g,ˆg·Ñj›¥…«ÚA}lb²bA aÚÞ¨\zû×"#÷þCr4Mïµ:çξ¼¸ðÁø‘ù?ù•(H‰>˜w0 –·#Ù} ƒ¬ú«)O !eè{}a”íí«ï¿uóú‡¥íµÔh>™H)§¥²ÒY…0¡qE5t@ ‡NWò0â‘C¯Û©omlݼ±µ|s}á2 P*744{øðÈÔ\vd<‘ÊRj!ç*ViQRH!ç2 €€Š E(Õ M)ð<¿çzšNMÓRbBŒ„m%Rºm놀9c!r¹4÷Ї ì±Ì¤`¢Y©ù^°ÂL!E?¸ FHǘÄ:oÀŒ äHa‚ãb|Œ‡éW%oŸ±n7Ÿc ¾ŒÆŠ4ŽGUªŸ$´xúòO% F# R™èP IDATúž °ËëË!—â©|ÞËiwxÔ‹üPŠPÏ¥T¹nS219nùôÝW_¼ôÑÛ·V*•ŸýüyÏwMB‹3³÷ÞõØûÎOËåõ¡¡|(¥®[¶­OMÎJŸ×Ûõn³Ù*¯s)jÝNarÝÙ^ó¼v§ÝÆ„Ô+û¨ÝÚøì™3ì×^{akíF'ªå†&Êé¡B¹VÛ{åíKAP™ž=Ú®nMï;Øiwšõ¶9¤‘¾xþÝ¡é™/þÖo'µñÍ›«Ón–×:ó©òö†ˆ§„ †æGÇG÷ØCÆhèÄLÎÛŒP°ù‰üö­u]'ñ pÀ:ãa¶xøâ¥K„Àm·‰`@Qw³‰P“ ¤zĹFQÂ̸íHÐ#£ã‰^Ȉ²£‚«c‘¼ƒ™N¬Íb"Ú\[&Të7HøF©¤ËªVЦR#ýüt\mu{›å+Sû¦uÝŒ€1Ù !dHxó7o>òéÏ)®!€‘Ê|#kœýÁ …1kß¡½¶5#è4k†AÜ0¨”j—×?úÄ÷ E¯ºÝl—A×l;k˜Z£ÕÛÚÜðUëôã÷å²y§Ýëö:£Å1]꯾üw…9#jt«í¥ûýäâÅ+éñ±n¥Uk,Nî?`'rJI‚!hK×.PÛT‘¨5*\ññÙYF_-ƒèÖÒJ»³½gvÎ2m¤8!I…1)¯o¬ÝúÈÎèÓcH E)ݼ¹¼zó£™csGO<â‡qftb¬]]¾ðÁ¯Í}àñOŽ’vG¿ƒÖ€ì/ÍoKj Þd¬1Úu Ó²ÓV½õîË¿þðõWõÍlqxxr<7:D!(¦ $â $”T tCC$ç˜`MÓ%“Í­í[×7WjÕJÐuLS7“©‘‰Ùñ©Ùñé¹L~Ä4Q,¢ þL8cJŠ0 #Âa0Á‚0ÔäÆ mËÖ©¡[Ä4µüp.“Í‹ L&lC7ãm2 œG¡/³³)ÛNr.¤àRÉL&­IÄU½Ùe^7.@rΤâ@HŽ”$1.@" °’L!¤B è‰\û›ÔAî*þб¼ ™é{†p ß7B«ÛÔ¾øÀ…ÒTÎÅöÚº@<✠!¤j4ê!g©lÎÀF«ÝEJÕÒÚÂb»q-"J*`·Ý²ˆ¼å[7öœ¼cnêHP—?ýþO*íëÃÙÉŸýðÛ«õ6¶ºnù+Ÿ{êÙo=»Zº™Íä„ï)ÛTXã[¾yK'¢VkmWK©N­J©EFBj …É‘éÅ7Þubg»}×'¬×œÕåE&„Ѱ~þÜ[ÈG·JW&&'¶·V¹ðv®­—º+v²à;^«¾süÞûJ˯WÎL ÿö3_i4º~¯q/3–ŸÐ§ë•%À!Œë–±ðÐä=« 7ã!ën D1ºo/¸-î¹qµÇU|ŒΣ£‡îX^¯júÀ¥ P”XLùVš!0FÉdSwîûD¹n» RFÒu|×u©fNLOƒnF†H|ªîÓËMýäßfa ¼ûmô¼n­3}øÑ4„ûË ŠRmkcÛÈ$C£R ˜¥ !]×.\ûhÏ¡ÃS”àµjI"$€¤Ò™‹gß]ÞºŠ”?YœH¦ÓFÊÊŽŒÉ„mN¼÷ÁK>}*m #‚…¡K Ì Â0J ÃÔˆ6<”IæÇz ·ãÕ“ÃÙáýíߺs~<»wåæÒƒ÷ª´]ÒW![[¾zðžÓÙÌ„0DmõÆKßM³¶Ó¨n6Í%‡¼j G˜޺üaW¶ö;aI) Œ¨N6n-6:õCÇï™™9+A©@Wß|w£º°ÿôÝű}J P ïþêïo®üæÈÉ“'O’šù(ⱆV"¸­–BJ’ýXªü6R±wg@jÕö¥ß_[¹¶½¾*5‘yz,Š0Š–˜ê €` €MW‹±Æ˜É(ê‰[7·×Vª;›Óµ-Ó-ÎÏf†Gt+ÉE¿ÃM4Š¤Ä˜ÄßúJ", …1ð(D€XȃÈ×(54ݰ‰ šN§‡GÇsÉ¡V«•H%”L0¥”"ôý0p1+•( I‰¸\Фi"ÀRÈ ™ˆa2H ?…#Ð>¾¯óÀñ, 0Ę5)à8/¸ûR@cÅÔí¾¯PõÃШ¸”¡b¼ìzÌ0`аà2d<â’GL´½0t¼žÃ‚PpÞët»­ Aq»…yÐq"Édv…âŠ)D•Z°Öꔦî»óÔÉ»î<¶¶Rvqlb|üŦalé¶dÌuza+‘‘=?WkUÚA§íF>Eø§?}aþÔáySrèäý*|7š™ÿË?ÿOûNΊ3œq¤¥úÊÍ뎭®µkµ-=­G'ub S*‚Ü8û†ÊýGN-ßh•R$„7~üËÛ:pø¨™ÉsŽŽàÜÙ׹ѻëþOX‰‚’JÓ@õH‰ÓŸøR~hJ PJaj€Ãß5Шþ4ïîßp̘À¡@ÞŽ‹ª0Z[^Y^¼¾xý"¢¸·˜Ÿ˜Ò‰!Ђžë2&BR Œ151"ߥɈ$­íÒõwßY¾õ¡Û.†‹{šÏg 4™Åº†1U)L’D)Ó¶)¡’èHI)Á ”âÖ&B!…“´×ëÙiK7´t6ï:®ç9X#¦a$3Ùd2Ç%O$’Q7èt›aàK…Dȃ(Ô Ã´“ÙlÁ2 %‹"ˆE)ahR…a[Ób›*!ƒÀHÆ úx#XI,„À˜PÔÇÌ+¤PþØÇ;õ ŸqDcLâ7t̘A\(D«¡D)Á„ÈÀE°‘Nz='–¬¸ž«¢×Ì&²£´@9Ù‘aŽr€"thh|c¥^­”ÒÙt»çrÄ¥C“3…ìDÆ6Oœ¸ë{ßþyié^kÇ ÅÜÞ™ÉÜü_þ›?»´ô‘ËyNûàÞ~¯wëÊB/*¥39iíV)—NG½6¥jguc¥º\s}l• ¼ÖÜÌžôPb$ !zíÂò»Wþ~l~,72>1š9tæÀÌÄ‘úÆšùô—¿´¾R ZÝÜ8þÙS”"¿F5Hç2ʽDK+!I6=dÎno, "Œ0ÁPB×±H•;%L@ÁÂ(î„q&òù[7·¶škÕG CºiëcÒÎÿò•‘ƒéƒóÇú¼%A!‰s¯½ºïÔØ‰#K$‘T@tÃçþê?î½köØéOc…ã—55Œêzé'?úËä ½ÿ‘/Z†?ècñËkºo[¥±³3vîìšï„ê»l‘ÂÎvãÕŸüü퀬0ŸÍ*)“™T¶0J14Bë†.2òÂP ¡D¤$#š)”àXJÚõJ!7 Š#GîhlvObhÔJg5Ã44]3tªé„P‚AQ’Lå(¥†nP„E„žç14‰‰—JŠˆ\PB¨¥åŠãã±Ð7 V@0V˜Ð„ f²[q¶×VyèRCW GtC7L3™Jf²ÓÀqýÀw|¿çu% !TE\H¡$Ñ4Ó´4M· #L@ÅÜ#¬`ÀX)¤ðr+¥Œ]fƒó= ŠË1û/.+LbÚNLÁ¢‰ÁɘĜ„w«ƒ€ÀmyÆ@1ntÚX*BHµZJ0mo^×­D.WÐulÊ´E­ñáID¨©ŠÁ*ò£r³Ìgï´˜D{¦&æ'Šâ÷Ÿ¼û…7Þªwª@e»QÿüWÏ>x䯿ó_?¸öëù½Ç£ÀEòi:^Ù{ëöäÄd½ÑžšÛëröØviͰRÍõµLʨ4H“¡‰é‡>PYª»slé‚ÿÞ{¯Š´®Ÿ¿|ôä„Ö³mBÿâ_þ»©ýSÍMB¡YÞñ:•'íå K@€ˆ©¸ïá_üô+»v‰Pòã'Otö-‹JÀ$†[(…S§æKË-CpÐ×JR ÁõtC„$SDãø]bgr­í.Ç"mf ð‡Ò¿Ú½ºù^÷J“ò.¥z„F5MÓÖ†ÇGR£IÝÊÆÃ`è7­b„|¿u|û\Íy·U+ÎÒ4+þÅ‚DBpötšžš»‹±H "Àbhiõ²=Fíd¾Ój§ZBO`¾X½|íÑg¾˜Oï¥:Ý^Y-äÓãÅN=ZY~ÿàcª9ëmÕöÍßÛuÛ¢#¶—®1BÓVLœ¿òQàôRvêÒùk•Æ¥ÿòã¿úw¯³t£ít†f¿ÿü/'÷=ý,Ö¿‹f³´±¼µºÈe-•ž™ÞSÌMxm‡P¶¶Y~÷ÝWœ9Z;1.¥‚`î/<÷ìø±ù‘©»Y&˜ê——ÿŸýÏ>÷?[ØÏB_!˜@$®Ÿ}ï‡ßýOŸùòçŽÞùÙÐ÷wȱåN Ä骞}ˆŠ« j ù F è¥wÞúÿêŸc4Só;-K×™ç%¦ˆïö¤’ºiJÌñDRÀ¶¤H¹Í–×ij+Îw¶W!!³ÃCÓûX™B*W„uË6 ÍJé¦ kVSCÓt‚©¦S?ô^‡Enä{Ì÷í„%©(‚cqpÉ4¨¦›¶ž!Ó5@BØÀÉdZIÑk9;å²–L¤L+åw;&Å„jš¡§Ò9ƒZ®ãxŽïzžãZ&V˜² d<Ò(6,#™LX†N(Ñ(Á” L `J´¾Ê'æ`!”Rn—OÕà§ìkDâÂEL§Ç1¶Iõ‡UB*!•R’bŒ FJa%‰’ %Ü&Â#„òº-Ð4.¥¡™ d&¹ÐB·ÛlÖ•B…ùQÅ ôN¥­Û»Ìu»æV»Ù Ó5}îÀè}Ÿz<¯O®,ß<~èø÷ŸûÍÛ¯¾fˆ ôµg¾~ÇÄ1M&¼nÉU“ü£?ùÏÿ·g/ßzýÑG?Óí8Ó£{._¾2{ϾO~þ+žÃe!Źã—Ö7¯ž;çø¥l®°÷ŽƒàÉNÔŠ<ùÚÒ /¾pààád¶È#@¸us㕾ÿÄW¿41½Oò#ˆÿ­_ü¢­ÿ¯ö±Lqa‚¡¾¶ñ½oýUϪþOÿòßÐÔ”¸€É.@ôÃëñànëfûg74ˆß@ÜW|’à¾)@QD”wKß~ý×^m7[L Ï=q êÙT\k;¾àTÔ81B „dÈüŽíÁÎæj"À’„QË2ÓÕZ™ê$Y葪—Ê„À€ÙVf ‘ð(2¬˜F¨ç{šnµk5v½xŽçtBß CQŠUÑ "Iq}C¡@Å)V×åœE¾ï‘®cÕL(H¯ìa˜(ùþ ”fu/ÝÛÓX®”;¥ñCCÙÌ ßñ¶w7†‡ $Q`B"‡mmoZI-iÆ9cX!ÐNÛQUJUÕŒYª¢…¾Ï™Â@74MÕ "PÈN§ SJ4M'˜ÀLÒRuë£!8ð¿AtIDÀG×¥ƒ@ÉûX‡ûð¬îÌ$åï\A@©dRHŽ1nWöýš¢ëI‰¨Fͽ͵þÁ±f}·oxŠÊxPf¤l:Õf5®&%O Ôd†F¸±_¯ ÷ _ùì÷~ø#ÓP2¹Dy/¼zéÒôÔáá鉯ýóÿñÏÿúϰiâäiŸ;¹žVµNSÉ€ é[Û›––¶ífHyïÐ …SÛ[ØÙí C#¦÷—œ‘ÄÐ÷^}äá§©i&k­æ¯®Ü|îŸþîÝÅŒÒry|ï×öcé¬h´¬ÑÜ‹Ÿý•«oÿü¹—¾ì¶™ÄS@83}òåoþÙW¯œ<}CäqÿÅžùwÿê§ýyL&j†±¡Fî‘éá×_}í—¿0º_¯& !ì·=Ë LQL=ù—ùŸ{é9D±lEŠÚÙTþúû—ÝjÓÑí;ªº)MÕ›8m‡lnööÝÖ\oò×H«¬ol–·Þ{çÇDªσˆ(*mî456¹6G¦ßªœÉ™c¯¿zÅDök¯ÿÃÔðÉÊ^Ù‰¼#Ó§ïÎ]ò‰çß»ý3š?í¬Ï­m]tªq«ýàKV¶Û•â†MÄÍ×/hcaqwæp¯°b—~~©TßlÛaï0v¯ûQ Á1¦”(f¦g8Ù7‹%Z–½SrV_ÿ¨ÄDbÎ01ÙŽOæÒ#o¿õŠÆ+·î­¬­Aýþîoÿî·¾ñWÙür*Ó 5Ìt:¶ÇyJí¹={å‘§žAVb£²Ñ—.üøËÿƒNÓÝß©S[}G\:þàY±¹Ÿ]ýÇŸ¼úÒÓÏöõöÕfæ‡ßxùñ_úXy«F¬]-Ë6kE[ #~ýÍ÷i¯¾µlºIqnñîítO!µö7Zª‘¸qñJum»ƒ©ä±Û•kO>ö‰£άޞÏd½”ž¼um©Ž™-Œ™Þ_)ßþð­À‡Éd¢¸´–Hš‰T¡æÕvÖšÐó"»*UËmÚÇ+í•=Ö·W.ö¯ìnmìì>v®'òéÔ@½&’YÇùÁÁPó 6ÃÝñ#Ïì‡Ý í4LyœÇ¤à’öÎŒÜxãÖ†[êóÍÑS¦ A¶Pp¼¹[µ&0IÅ4=QYÇæÎì+æ^¾t±?§&þ»ÛW'>¬Gý±á¦ãvªÕF¨t0*$3´dwöwêèHb¯L–w–2Y#K5+cm^È*ûJóÁkom·ölL5Õ"Q°0ØîÜZ¸á·cÖ®²º¶UÜdJfµ>Us…Ó7Þ¹¸[EgN<}ivqeý^²—x~,oX³wïàEÍÝbÝjW6«!Z_ÞHê‰wï=yê¡Ö~}©½Û^ß>ùøLq­&Ðί|îSY³g¯´Ñì4ôPïêÛÇΜpÚ6 bûí¿íƒãO=cà˜È¯{›í…¸®Ï]¾zéÚ»O|ì H¬å[›×/þüÙ—>väè)ÎÐG(xµ…ºÎón.ôà‡$º3cU×¥@kwn¿öW*öü¡±·]ùøóŸ'zB„…Q§n§!±ª¨º³wîÃzc¿ÑihŠÆ%G¢ Óg– ÐnÙ`¢**QB¿540‚#HT$¥Dc!s;¶ˆòκjhn§ITªÇ 3žTô…D°B PµÃ[še@ŒDS™Ï8 0¡"œGÝT8!$\g¢©aU%º®bªˆ1¡ †)%ªBtÃÐ ƒ¨ŠÜ—®B1¡DÑ(¡Ü嵺jLpW!‘€èÂS…"yP!8!J$A÷’ÛeEÃ.áä‡8¨q.ÁÝʼnv7Úó‘å `E±(•`Œ)¢ÄR¼NùAÛÙ£ˆP„9ãP@qk-ît/H IDATKºNepüp£ZSˆÒƒ·Õl7ë[*U1c‰|}⥋o]OfÌ…µ½¿ÿ›ï~õ7h!W8{ò‰éC#ÙžRs¿]bg¨¸»:»ÓXùÄ _Jõ~¸v[Eôo¾þíþÔ~Ͷo5–6öÖ¯õ¿«–›QÜ÷nÃïÿÝwdÌŒZ]hÄÚÆw¿ñ§‡&¸sy~½ïV"5ì‰h8ßûÆw®Ù ÷Œõ­+‡% 5·ôÆwOôFX‰J [•»nÔŸغ³¹Z¸©ª+¸'™«V÷¼={­|¹ ’Ç—}î,Íoîï{LJÝÍò<H;†HÕSÀcg¾xñ"&étºªÊhÖÿ™ßvïÜž³y;jº!ó÷wí°q=Ÿˆ_¿>ÏéÔœÙÅ%Åcñ«¶ýÎÆšãT¯ë†³[ ‡Fh¦F{E¥xmG/¸¡±l«±ç¢t2£t|çÖ›w«j‘gqù^˜Ë…CG§.|ç­ì_ÙØêI·ZÍ¥Íæ#Ç®-¬Ög×ý”ˆ)!iãÕš0åúvy­\<dl±´›Ë¦žšl.kK«o ž>œéÚ¸»Wl×T¤{IÕ_ Ö¾|öÔbsËïT·ëšp‚ÈG‰È¨›?óˆ@}//ü,ÂÈDÕö×ͬQí8ZH=WîÕý´ ÷ÜN"6¨Ó˜[sGsSㆱ+çžþØüÍ·†éðÐWâk+u¾SÍö’(6ûÁ’•¿õûÿËêöÚãÁÉ7çj+~õ—¾"ˆÇýˆjêáÉ?‘eQUóö.zäÌé³çK¥½ËÖ§Ïž~ð©» É!$C!a×`(€¢[ô€÷L@‰!AL¬¼í/ÿ½}Ç'&zNŸyR£æún9e*Ž õ;†NI«e3µ§µ¼µ³y¯á6KåzØlªq˜Îg{Ê{ûåý]‚$•L1“Ц4i{ •*"‚ ©$wÂ@pÇoV‹ÛŠ®`E%†ŠÅL¥-ËbR E‡`B€"Çi‡Œžk&-…B5U3¨T½¨‰S$àŒ… b0RŒ„H)@°+ërôÁU…Dè@ò ªB ¦D!*"â‘ÏtM¥„"B ÂR2ÆE$¤„w9KÝPB!y0$ˆbLHñý¸¨”]æÞDöàÄ"\Êî#]|D¼?`ù &P—·z°TúH{àFc(`7¹0)íÖû'b#cã+—o–ê­4N’‰(&"»k÷ <Žêí ¤! ’JÕ0IˆVCªLM)‘bK1-íé®Öë‡ûæ7¿ÓvKoý—ùxOùØÌÈÞÝz‘Ýîè±êVk§rã‰GŸÃPÜZØ^øðÿíOÑ-׉)©!S/µê$‚!·Ï|ôâøoþ}…´Q6Ù)Á”eÛÕÊÌä°ïÛ‹›™q÷½Û·ÝR©í”ª·Nžž¾|e!Ixè‚v­ÆPé|¸®&]ß\´p÷}©åy»Äo¾{%ÔÜK·o ÄL$gã³eÛÍQÓÈ KñÀÊv9–„¬É©ø^±\Ý»;3=î5ýõâªf™ÀÑ]^~øÔ3+×oõú½s­yiªc½™Þ¼žÈŸ=S_»ðÉ'OŒMêùÄg?¹µø¡„ºJÝßÿ—¿986Î#LaT­çf÷ç¯\Qz£ ÅÚAÅQp¹]>3™l5Ú-§.¡‚¬G›¼ £ŽÂegy¿†±ßìÐÝòjŠDŽ_¿6×X­×ãñ€Ô:U;„ž¯%Z-•4_Ø)qm”J¯UµH5“äêÕ%+ØÐb~=`<‚áÎvNõô¬õÿÝŸb{¦Ú‡Ó½=I ưY˜˜ o®/UK7.߈ʵԨ¶}gÏ+­éØ0±œÞËVïTp‚Û’ÒàëùQëðØ±±ÉÑñ¡ñz+ðìv¦'¦hqf³ÿëÿ­6…†’#§¦RÕtes‡¸Éøéw=õ[õ|Ïíï¹MÃqêË÷î\¾0Y‚ŸîŸœ~sŤ*Э((bó!f6Ûv¹Ä4ž1ËÛµRE7¬D*°ÑtÊ›»;ímMpšŒ1Y ¢™Šf %@B BTÁ¸½_kÖKBF©¾!#f%r9»ÒáaBH ÄRñÜÁIË4¨"Uª„“€¨Dí²]X(°ºI𤠚‚0usšD¥ªF‘<1&€KÎ!$â< ˆ‚ ,¥ü@€0 DPBˆ¤”aˆ†HÁø~ð ?ðp´»ž…PzƒU)ï³h’JñÑq†¥¸¯yRJA7íxÀÕò£äT^:Ê•ׇNMص*6´P‚¤•öBW„RÃ:Vu‰Õš]T(¥Nƒ7[¥Ø0dÌ4eN?¤SªRj*æÞúV1c“‡mËÍgó;;eÝN»}œ¢Q3ðƒöìân§ŠÛ—j"ì´ !ˆ)>Œ¸€îæó÷×z‡ ‚H‡-WI.¼PÄuˆ à‡’iŒ1H@Å ÊC¤Æ„ê*6p… Þl´ãùáOÞ|ëïß¼È*0s”D-d³š®~ÓÁXKb×µãQ:Ѷx¬Ÿª;aSÔýX"\©«)Ä{IeOÊé¾n}û¿}ïèùŽK©††¼…L⸙®UWgÎLú& ÷Ä!*S»Õí•ÝT2&I´¶8?09¨&³±Ã4•·:m¬«‚;Äåõ©™ ¿ÊúÇŸÚ«S}ÃÙ׿wõÌù^+Ñ¡$„ªx.$Œ•š%× Ÿ° è²x±L6tý~ë/¦?ñÄñ¯5;¶Äp Ÿ/owöVnN§àìÕâѳNJÁ;A˜çé_ûѹ‡¦>ù U^¶ìÝ\k7¨´ö[[Ÿ}èòõ¯ãÄÜk¸½qmÁ©ÎOò°µ'9&ÔÐÉ­òæ &D"#¸Ì|üÏgŒ”Òï}ýïÏ~êÐûoïLÕ;a2†t­¥ZØr’•}ÏRôF<Ì¥¨’1O$ß}iasѹÎí¨õà©£#Ó;åzµÂžÿí'h)¢½to¹j{™ÁQ(,d‚òBíáóý7.–<%ì´‰® †à±ü1N§™îK NÇY#ú­}§3ûæÜ…«i×IÇÌÞ•ÙþÀñµ!óıérÝÉøâ­­ÅgY¬Ù¾>zt_× ^ÇE<(¯Ö·w—6½¶°¾Ñs)]=vbÚH÷×Ê-MÓ"!"‚#D0 d{×iÛIQÅD—q„B‘Ž#dÛ)2Þ3&!5 ‹ª”èqÙÝ• éûŽÓlzžv¼íÕxR?6“†DÅÛå»’@(ÔH/ ”¸žL&ªŽ)Aˆ1@`š:àA(8P3’ c]Ò¶ „`ˆ8€Ýâ¼@•q!_"ùa†aÈ" À1&’‰ Ú¥÷IÉ¡”"Ž”]–4êÖpucý…Þì#…,€t…´¡îêÊ_¼!€ ÙÅ*vµûõNˆ0@tŸþ $½}‡XÓç ­X"—Í–÷v‚‹@U¸@š )‹†f\S,*ÛtÀXÑdJKõ÷m><øhï Ý2Ë˵oýÕúA«îsSÃ’ò Ò!I5H,“TdÀÃ!‡XBÄV` ÀÐ÷©`¬ °_© 7oÞÌR Â+R‹Ã–PŽÚœX‚ÝWÒñŒ’àÔTM´:CGŽ\{ýÖç~í‘Û‹•‘l¬éÖŽÌ`·-“±Rã½1雚ŠÚNëâÛW>þÙg‡††oì.[¹üÕKWg:ÞŸ-•Š@X"—_ºuûæìõgž|¦§g0Ú@&-åv³³³¿?5PNŒÜ*/~ø\BäÿÃýÛCÇ2ŸüÒWßxåG¹´>yö¹ý­$°‡B”× „ª^«T‡G†×ß¼?Jk3ˆHºlùÞ­üÈ`‚j-„ Â…ûáC/ê›öÝ24Ìe B5i|xåÆÙ3Ç<€ D#•BTŸuéM(ÿì+ÿbcm«§©† Û«®-ÌÊ O|ñ‰÷% suiRì»ö„}ü+_üT©!tJ$ŠJÕøó?ýãOzö‰O¾ÈZŒZ€ä•¾’J9gbôF›¾ç·|"Ï”èW=5Ñgñ$­À§œòHªo|ÿÕ~ïÉ8GOÜ|äüSÕírÐvVÖn„ú'‹‰T"Ó36‹ˆ’²ôxJt:/}VÛÝh°°Õ74Ñi¶bù‹‚Ü¡Þå»Q½VÙ®ž:ñäÌ̤‚D,ÝK~«à”;¢ˆVÊ›Ïÿò¾ñâ—_lwüÑ‘ÑÒvyokbúXð€Ev±¤ŠÓèÌÍ^Ä©Du¡N3MˆËDsac¶õέ{Õ€U¢`É…Š‘¢êµF3ÖGD¢Œi¢Ç Œ¡B¥È›†ªÝçïÖÖn£ÞQbîÈÐæN% Q¨†œKLS‰ª+Ñ„µX:á84;\°9Kå{3H].îTvíd.šp}±³^ͦ<Ï$ K†]³YÊ2B"c*y+;4&vÃX³¦æfß{ìü‘‰l À?þ£ß¸vk!¥©‡ÇWnm>’ PN!Hª„wÂXŒ´ËÕv­ídl†í8Å=È•Ëo]=r¸.ah˜–«UÕ²,=±¼± )ê´CÍPÊŒ‡.XçNà‡Ìæ­T.»u{C!ëý‡rM»|ñÂ…F9Ðbâ­ï¿¬¨þÖF#7¨Ž©íí2tª[µSÏÎ^ûÀZ‡£GÎX6]ßm{{›ËŠAš²Ã@GD‹˜‘/^ÏŽh{b½V*{AËHÕÓ^ËÞôŠ•oԄ‰PXoóï¾qþ {뵟ÖÊ»V&iÄS£¹Â_~…hòµ·w ¦>rt`®äù4 «DÐúÄщ ?¹Úòë±8@S rãí«$žˆõd¯¿ñ–wšÎ­+KÛ‡÷œþOðÿäq>qåågGqÏÐ4¸GM3_-í¨Èzëһؒ‰½#ïÎþpkg³ºs¯\´jû»±4”Y©óŽCãÚ8CÒjÿÀ@ÿÎÎÞÉÉß}훽G Ò„‘+äÒf.›H^¿t}aîÒ䙃Ó0·nÎc•Æc;NHÒš¹ïÔrÉ^C%nÄÿà¿ÿ=k `Jp~(×7Ï„a)Â{ùÑ{Îeúâã3gVÄâÒþüsÏžekþ«o½C¥ÃŠRÇÞÄ:¾™Jø-ûÍW^ë4š42cƒÙÁÉþtAWÛn›bU34iL‰+†¯±¤‘¢H)í°“ñš6RMÇ@U·‚¶‡8|8W ¾hmÏ/$ûÍLÏhè:ÕÊF«^v/‘LdzzSÙÕÙ;BïpHæ"!%ÄI0VT……¤*!š ¸Ä A“‡>:¤HÕTÝŒK„ž[J,R©¸¥ "ÔeKyÀ<×sCÏJ%)S¤ˆPp‘dÜ \Œ L¡c„ºÔB)Ðç>88¯ºû×nÀMB€`¢÷1Éõ5I·ÒÜ•a Î%”àâP×±†»½DÄ}üï*R" ¦’ÈÂЀ¤µ·x.à q†P÷Á (VÒ$꺉„ )S©”J“*ÀÔBÛj1 †ràØîâÆ½¡ÁØr¥üË?xáÂ¥ÑÞ•ïN?0xg­589G4´3XäU‹µ#3±T!–¢PÉZÞyÿâ•dŸ—éˆ5XVËpX±ù¹¯þò ³ëï¼—NÚž¬”Š£ÃÙùÛGzu/ˆK÷$Çßú³—{øøë¯]hí6€´} ?½êÚ?{S3uÔhp†zR‘Òt¶×7òñ™™á‘1 ¨ïº»k•½å{©†QŠc®«Fe¿žJZ«·W—ÔRyo Ô¹šWæ–÷‡4Ý,äî-í6ëʼná![rRËÒ³ùÔâÝõÅË×°.U<“ë³ÒñD³|+–ŽÇÍìVë®OœD&§ë±T.‘RNÏ„ Å—o&N=ü, ‘Š¡ Ø)ÂbôÔ&PBÚ¶«0?78ôÞÞù•ç>ñêüØèd*mÙžHjÊí«×?û›_üä'?m3ÖØÙQ’ITáúfœð¥ÝJ1‘Kçc½»ùâäá#—/\›<ó±C…~¡æjY¥׬•…{”<û¤n™>ÔRŠZZ.…0Ì[IHÄâvÝg¦Ÿ•L“CéÑ£ãF¢/*Ù—>¸öÄsçÔÐ\š›Ÿ>6’HäÚ {âÐÀ¹‡N—z†háða®á`"Hä̼–+·«û[ó~ü ¦Ü†sèHkm®dÄõéãÃc#Óíf3=”Ïh…»w°ý…ßø3–ˆ†nàAä·EÄ |ßŘ›ñD&—Mv‚À«{%•¶€œwív„ÜeΟÿßR¬TŽ÷ M–¶ÊV!•‘ã•;;·î]g’ ,¬¤´xf8¶Y×B»tmvöpîœ#£Á¾¾‰±ÁÑ‘q×%6˜ëA)‰nŒEÈ„ Ò1KÕ4 Q,‰ï‡žï'9¤ºvQ`ÅÒ,âÐ l» -‘´²…V­^š_Dz‹7fð3™lßøx"Ý!RdS…;+m¿ž.ô"¤u#éx2UmÕ¥$cyM+#˜J ‚€Š»XQÌ¢ÛÁ‹[)ªêݼAùJˆ¦„0ðüŽãH%H¤„‘¢P 8ÄX0Ñ´;VÌÐ5"$ Š @ Œ ÁŒIpPf½ßÿ$ û‘KÂ"Б]hi·W0„Lv¹£=‚À…èzÕî_´º75 $ ^{ïRäÛ@ç>ùR4¯Ùq!†ª+ºïµ“™L¸•MCjBRD8gQЈQS3âI·ÑÂ<БB5]ˆP3ÊB2¶^·l»ÙtZ§OÀ±DEZËܹ¹¸Û,ö÷?~j²¾ã×7+›¥•G‡~òõ‹ñÓö˜öx£V4û{ÊÛåñÁ¡R-3lPiµìò±Ó§öö«ÕÖæù'Ý\H^_Nô9|(90YÚ-›æd,ÙûÖ+?þÝùÛÿõÿüæïÿÏ¿®gGKųIëÊ.|dưÒS4…3BRJüý  Ïœ}Š!¸îáiwîZ<™HŸ>S[µc Ñœà P2fîî܇Î?„õõñƒ·‘jÒ@ö^ûƇr2!#Ÿ"T߯ER?vôPÓñªmG˜Npèò•k×£ªí…Äwˆº•‹×nË%×ÖV9$ý™ÜÖªëƒë^¥Òfžï†1]#ºÚl† w®?ÞØÃÞÜÞ°£›iࡦ³°²q¨Ý®×6Ó½V¸¶°Wkm>tïÖìêú¦W8&Ìa 7×F§ò?ùàgGμûò›j!ûÙOÞÞÛ*/]‡œ§r9·Þð#²¹º~ü±Oöô÷rEKiÒ0Éo}k`J=zâ<Úà×ÿ§ßâ µÔ^{æ×¿’‰÷ PÎ<ͧ7nÍ =4qêØc~ìKSƒùŸýøÝÄ yxêh» PÇMŸÈÔ»yëVD§_üf°nÛùTêâ7?hÈ…çŸüةǶýØÀ¸Æ"Ö)V³c…ç?«J­«MA  \xQT[Û1bM¥- |Þ,mÀ°*B"UÝœŸ»øÁÛ)OYÚ{÷׿üošºf¦–¯/(x_Qò ÷V(ã#£ÙP&üÝ1õ˜cV¤ˆH,ò™‡?§ªšŒ€¦@ÛiÚž ÁYD¡ˆH‚¨Ù¨…Ü% QUݤÊÊîvvp€¹šN…,’€´ÛM3Þ'†tD¦ª" 3©š˜P c*U»Ýl–e¨št¸B1—” 9„aů`w§X¦©!)*Œ`) U Öýïj¯RUJU!YÄB !PŠ„ô\×vÌ}UUª|䎂‹@Ad]Œ=$QJ»‰„ Ä $ÆÜ«„@=ójNv1¾Á\% ¿€ABrÁ!<Ьu'õè ìŽFõPÁa·n $ѽååVmW‘vµ¾÷ù_ù s(‡‚Ë÷PÍÖöH¬!†!dn¨(@0&x ¢Ð넘Œy¡ßÚÛ%H“fjiõn|dØõv4©íë5Û0JçrŽçÍŒ+ÕÑ0Üçu¢ò^)L€‡Î½´rñNöHýùŸZ[ÚÀT|ì‰Ïlî‡Å•Ì/<ÔW-—Ò=Éç?õù7/¿ÿµöµùëŸ>9#D¿ùÓ§N®¯ÏÿÚ×þÇEˆè ±ø?üøÛñÞ„" .UÕœÖ{wíC+‘É>8&ÌIî) Tœm-žìícà .BŽøí•u”ïÖ¬)Á8‘ÞŸ[¸6vdÚ­ \œè{ˆwêì^©§&&³·/­æ SÓGŽ•ö>÷åsƒ©³0ð™Ââjræo¸'G†Ç B¡*¦&˜¬Þ[?qbÒP íênrb€—= RžÍ>VÜ[Š>”Iôh†A%„îë§ÇŽŽL HêÔ˜*Dˆ MžµÀ@euåÐcÓÓãÈ*åVyeò÷Î@AJ€D„@•+¯¿ñÀ3g8÷,a„<ùïÿø_?>Õ78Œ)î;ÝS¯SË';<˜Ÿ‘"lµ›@Q&Ï|xñ}ïœ;ù¼ð#„€ÁÈøßþË£/7päÂ÷xoV72=[7WÓYudâc¸ÃÊ¥¢Çþî[?]ݽþ¥ÏÚB†çx,@ ˪ÝI¤M#â0ìþo ¶W©—rù¤×§ÍÕ­ýN±/Ókå{ ¢ !0FQÇóGßûàí5;Ñd>qìØ‰Í¥NeíúÒ:åzOZ쵋¡gkYóÑé¦Áåâ©Ç»ªênï•úTs IDAT5X˜èMªñ¤¢•{K£ýý@5¥K R"‚˜”s΀¢˜²å}øÁ,f—ëµf,‘¨ó 9á~kߕйA$|JâTSÅ€’!„ "Œ$s{‡ûU‚MU0 =³{^ÈY,ãU¤i¼¿oƒb„UTNÀB„ &!)¦Š®«º …LåœI€$! »#j‚0ÆJÀRBa‹¸`\AÀ2-Ű8gb œ`ŒR@!¦”ЮM  @ˆ´W™àô`TŽ$÷¨÷ÝÖs7fÚå@q7ÅQ76OB!»i/y€à’v_P„°fĔݽb ø­…¥ïýõ7öë÷òCƒŽAB|ÏmUJíÀV „„KìD X ˜”B+– Šé1îvlßw¸à,ò?,Ì%-—EqCí1Ž.­¯[ºRÈdN921962Õwdâ¸Òó÷6^yã§™žÌ#<:‘>yoõƒæi]’¾ÉÜÑÂD½éH=õéóVâèÆú¶ÑŸÚÙÙÛ®‡G†G‡-üW¿û¥ÃcGn^¹QõëŠiÄÅàA(úqk¸Ö.¦o¾ñŽï9®ˆôýýË ;wïv%\04”;6y¶YÞRUJpÙ;܇%÷#SL¨¢(Â$7Ðﵭʦƒ Äwí郘·n,4ü&¦˜P‚Ñ5õ37;¾_žçC ©¡h¶vö{®!ñlÿÒ±g_ÌÆO½÷ÆÕíÆÆ ϿУ$öàðøÐS? åÒyü‰M<¸¹¸)¥›ÎÆVæJá~ÉïpE%^À•’ÒwÆ"ð¢»w®üèåm®\ï=44–K<Ç—RZñ |Æ"˲ÜЪ´=ϯR©tùœ‰–ß‘­™ñv³!BÔÊå0ð¼ ”"”2è1 @ @L¨¢ªH)‚J9¦Tb jêP1UCÛÍZù‚X, Æ„ty€.Ûå +˜`LT…*šª¨„B)¡ „tgß­&‰ í¦§ºT×P(1:x (%À‘*ñÑEëþ˜ÿ€â€v`!Äš¼E4A!LÁâ «d¥¸Ý œ2ÛÙߨúoÆ ßi?üôó_¿¸½v[“ÈïØœƒT6xI¸6tC‰£4Cp‰(%2AªP/d`*VôLNø‘!¾Cd! A”,ô Ç…ˆ²Èïj3‘ÍÆS(0m嵟~›®%àØð@ko¿³_%ª:21êxú{·n¾w(Û”:vµÚló• WÛ‹Ú‘bh™BæÙϾÀXòÊ­Ü ' 3'Î7œbödßöæ†Æ]êÊб‹«õúö×¾úÕ¿ÿë¿Ä’!’ °#'¦?¼p­åíð€³(qšéê8mDC‰¤ª"Þng"‚¥!’É'bX†JIÎÂjK7U¢`y[ eœÒþ~#–(Œ ôŽ ™N¤ B%gÎNK"bHUµ½ÀH§4ª%â©ÖöBËižŠÚn2Ý'ŽiZÀZ‘ã ¯cÄô”•±–ÇÜ©™Ó¾€XÀÝ»›AUj(ˆ èïíퟛ۸³´Š<Íñ"1€ŒÝ[œ÷Âý|Op„``Œ£fk÷öÒ3¿úélªp1]¸ýÎÎö⋟}*Hµ’ñXj¼dw»œE=SÊ0ª®,S"u£ðîwß0‡rO¿øë,ð„ÝÒîÞæÙ§ª\ Ü©”“I+m$×ïÝ)$³Vcmu©f;?øöÏžú­¯üfèRÝÐ}ß«lî!‚r}£ºDQ(9äP†Œ5ŠåÖ~©Éé 2Ûo,.m׋–™€ŠÉ¹ê»n¤»[»ôÚ«›Å‰ò±l¤ÚåM¯#1l>zþdu½]³k*…XRJtoµ¤RxìØñd¾Ð; ™Öò*Bƒ+›µÝÚ] ÐÍ•%¥ièP¥RÈ–c)k[í~ë‹«K:ÓGŽ:NDu XŠÆ =F„º }è¹-U!ZX1æûˆPG1ÎÃÀm¶¸àðˆG"d*Q½¶ …€C»ÂR)‚1FD,Äk¦ª)H¡n˜Óv§…„2žË3$‚1ØM ÒÅç„„°S 1ìjºîsIňHˆàRJ)q7’Ž0v€çeÙ­çˆnUdª€B‰øát“¥Ýz pv0Ó?súôƒ™t¯o7„ê?õ‰Ÿ™~d{w{«²•ê5”X"r˜¢ßüÁkÜõõýÝòÆöüf¦0ãÚÖ®çÒ}Õj»Ñ¨žî³XMèfªÞÚï`‚:†í§ßÿFÜ‚D DPÍÇ}ôê»WvîÌß[º!‚N<“©í–!ç 1‡Pò“Ì/®¸N .àR ΢ºžt: Øm,Þº bØ(W‰®BgF2IÍ @  ©ÜT¢_ÑI²0 (Fä´ë­µ~ȸ`@ðdÒ0“)!‰ Qeu™\-•‘Š(z:©© €sDa¨j†®hðÀ °Þêí½w}žñ`¸0œJfL%‰ìÆÉ§zG'=üQ¡Ww\`O?ü]`„€€íl¬ÄÏ$,u0Šˆ€³^ûù»o=>Á•,ˆ›˜zéýwÆ™83ýE·c·jM5WÐ{'ïܸÝ;…?÷¥ßqÚMIum»¸s/—íÝ[Yì94†N÷åN¹­ÊÔ©ãÀ¡ååU»¶s÷Æ wÞ=õäÙ©™³n›A);û;£“‡Ÿ<ÃB XÈuq¹´4/¸³>/AÏä¤nèé\ªSmÈO©*tCI$ƒ¼gl Øä?øáÖúÚúõ˦¥Qª–B R¬lZ%‘w>XZØ×zÀô‰©SŸxôÈéÓŸxá‰És%äÐ航©Ïºã„BEÀývKŽ¡$”T Ž]¯¿÷Ê{ï¼þ“µÍÛƒ£¹\~`¸ÇõÁµ÷/_»ó>¤ HF!¦A¥RÚ Ì%âQ°(䜳 $ Ð¥ÉËN§eXñˆ ñâÆ¢f@Š RqÌJ5Ú-‰dbRHH F‰D¨*!#¸0â±D*MôA„(‘DÁRBÁ ”Šf")a—8#‚¡¹5@]¤'” ¼ï‘ëz‚ @]ð±¢Ô…ƒôþä}¤±•dt€MÃäŸø'&åÞGúÀ®“‘û‰ª`>D÷ɯðx€ @z.6h2™áÌ'2½½ÑÃ}'OiÚ¾o7wvv-wycÅv*Òö76n+©Š„3ÂQàqÓP´¸€†’sÀÎuÝ2,…1€±£0Ü·©&=9LÍRë• ™ª(¹ln…ûww …Þòf5q$“‹J¨f¶7³·Úº={™‡GC‡¹ml×k”(¹La¿Úœ»³tZ@%•}§o4?1rbåê5Jx©]1c Æk§fNß››¯·k^Ôyòè#[‹÷T   I¯´*’jsï³_þ•;{wïÌ…‚.‡ñCç°ûîËßþÖ×ÿ㫯ö¥&Æt­ýòn«ZÃú"În¬ZÜj4æŽ<òP¾oÄg¼QkÕ·‹ÍfÙÐ4'nú~'[èÏfrB(¯Òh—¶œþtjd¢Ùð;­bÀÜÕ› ?{í‡×.œsQùñ¯}îѧ¿’ÁP×e!›B $‚:Ð, PõÜOÍÄSÙ\ºÐ×?”.à\à¤ýðËRF\XTÛZo³°»\i¶BV^-ÍÏÞþ裷m‡ ô猔m&âåR]HqëêõúFm«Š®NH·Ój·©x~éö²@‚ì¶š€*˰ýÐã\H)†âÈZŠ"D"Ê„¬¬5S×L[!E4Ú#rIA¥’JIhb;Bˆ TLpÍ0tb%#H0„ ¾/ RaÔb„!@R‰ÑRoN„£ÞÔõ¢/cL0PA( ìQw¶ðž!#ˆ±Úù!„rÐÓú~f¸—dV÷Œ’@íØV!ì!¯T*¥ŸqÜUÏŸÚ³X( P·Ùðy˜Mú‡¬X¬åºØ0" [^¼1 áêúê{??YÝZ>uòÊìõ³zÊIæûy&1'ù¡×nÛ©´¦Åœ\¿RÔ2P e3àív¨¢ÐoG~äs%)ka~mp$ø]Œ‘FŽÇ5S~zæºäÍûÇGr}M—kº6{cöƒ3ï7*Þ©Óï¥Æ,§ª›[ wó±G‹xkk½Ò¬dâ×fïbˆ€-¯ÞÎæ3”ÚÅꖙ׸*|ríŽälÛ_=þØ“•í’B¼[¯ ô'â¶ãX‰5GÏ?úø»ß{³ÝX§„ôæ>WO|þåOo^ï‰d°¼º5›Ës+Ë«k7g)Dš•:vìøÍ¹nÐq;]ø¯Kf¹¢u`À@c«è2—R«Skø2ªT«¡Wb‚+7À&È ô¥ ÃJ£F:«Û©xºŸ„¾eéŽÛÁBú­j"—Ä‘`A%lûÝN[yÌ ÛPݲ\Ú$¶®¤œ ®™f'ðÛË¥6ókÅz:Ñ×®”×W6Dµqîƒ÷ :ÁP¦ˆ¬ß^Ù÷ÔT.9#e”\R]«ß®,Õ.Lí+Î/1ÛÆì…Ëkþ%à7¿úbµ¡’Vvyqcfß®yC 1ÔIëÆÙSΘuìñ6 `]<ùñÚöé[4­Ql81ÛÉ××–[AkïÁcQ$7W6fo_Y©lì) ¶- Õlµã¶Y€áW«­Z±V-Mëœ D0$u“û^­Zä220ñkÍ•9SÓº®8ñ‹·OœüñúꪲÕh!_ßltë倷tÃÔˆ ¨7Û‰¶bvÒHcˆ5ÓŠ9iŸRjy£è·ë^à·]E<ŒôÎZ ‚$ƒÊÐ3Ý8âÔÊæ“PH^k{ÝJ5žuúì¼Wo…Ì‘”’)9]·F7Ò;*bB0¨PÈB.YÌÖGBD0ņˆB¥ !(¤´bB˜­§›d~ˆ’#€Œp2G p€ê9'9&Øk»^³Ü‹t#Œ&c 1Èm7…’bB)Ñu$í`ÙÙý€0Fà³Rµã6C„RBJ ‚½Çº·ÈSªÇhØY+BØ3?ã{›€{åLíìÑgô ÔÀÂ{¤¿Þ‹«wø¿C\TP*•LŒ³$ùMB¸ÓjvƒÆÌ®ÑÓã¾ËÚ^{ldĉ'‡ ý-¯Øj€wøó÷Þü/w®Ÿ;:fŠ$P Y-­R»Ý6ãB׈KFÀHš¦Åy¨83c&“`¶¶ÖhÖJ@vÂÒdÐBž‹ûã Þé¼ÿéûDzÓ8”š³wWß=ý)ë¬]¹y"¶²¹ìr¶¾]zæóÇ~w}óþÇíÚ÷ÄòÜ\"k·kâÎÅËV¥’…ŹÅg_|UáÇçÞPš¬Öê¦m”7Šny{«² Æ»ÑåOO d q=n\»tBǪ§ÃRYñøÓ?1{w-¤¼¶ó¸Ð5Ã4´õå%¿ZÌÛ=}Ø ƒ(lÏ]»ê¶66·7¤`¹¾‘Õ­*\ñˆ‹H\1nXZe{sa~®É:~×­Åf·¡”ˆ¼@ ¥™V»Ùv¨ôaI9zéÝnÄkë+ ‚,kT> M[\ð®4µB~¸îû¢‹Ïß}ߊ›qÇÑŒ¢fL7ÃŽÛ?>¾g`·Ó@@ X-\Xû4?<É™¤•ÖÖßSž:}áÍ£Ç&ØÊ féBi»üöN‡Ú}©Ü˜{mþúà®É£O?/X¤”TÊHÝ:ó)°½™=! -¤Ÿyï=)[G~"n;H#ýÃCÕíFqånv(7<¶·µZY[\Z[žwêÙçŽ%òQÔ¥3ŵí[K·ƒ»÷:ùq/T[ËkõFÅ0 ]§ñxœBœÊ¦L#E TÜ·4B‘ôü–†yÆIÏ_»õöéw|Ÿ{èØýw4ÇРÓá"jùAG¹2™ `(p½Z½FÑ I¦4¢÷\3‘ë!ì”Îö©(Ø^^N'úÂÈD*IÐîÖÛNë”ÄÔf¹Ñív à¥rµ^«7Û5=…Ÿ{æ™áÁµt¬Çˆƒñ~.$2‘ÌD«·ÃÂ`jqˆÑ4]·N)4$gÁ„ ‰ä¡TL †–‚c¤kHìH ‚ÐõºP@ ¸Br¡ŠÂÈwÝV«„”`êº ÀR 9ãB,†¨·$ºÇ …÷ô[„ 2u ”‚÷zÔ]J5ˆ0ÆI B1ÁÁލQ{˽ž`!€Æ"üßûÿoSÝ™¹÷.Ôw€íJ(!”(„ä?úQÕ+b(ò1Bº®‡ÂUЏnGÓìù[›7¯Þ]­Ý|ú¹¯ÚsÈ—®®YFŒŒOìßS\¯ÿø¼óö»íUÂYDŒI;y¿Ñt½¦ò‚± E8f5„‡…'uјtÒº…S6 ⺞Jô¥CHñ–ç*ª" ‡û†’i&¸bÕRµÎëYgüúåYßuƒV(¡°û‹¿­ê?üé÷ö{p¾´®Çbµb±ºv· PZilo>ñÌ#ͶvçÆ|¼'HfG‡Ÿ|ûŠß­3¤DWmm]6†ûcISz^§SÄ)€‚ÁŸù‹Äì•¥Àõ®Þ>;09ÆkMŒEi³´póâúú|zŠÉl>“ìâ’J‰ëå²RQ·íê˜vYØt9‚0dQÌŽŒAà‡Šl¯¯™i#afÃn˜Ìfb$ÕªA·Ñ©7±.›L˜ºúú™þáñKï_‚<ì´Šœâ|,¹í–ö<Ôíò(©®[7–g>ýbדå­T2™Ïõ öÿü'¯fFíØ0!(?4تVß}ûÝÌ8zß≂¿Ý¹<ûÍÅ}ö™ Ñ’#uÃÚ¼°ä£âŸ‹ÅÒÒüéŸ#gëØ/:Z @ess~¡ K…Ü0Úv©º9w{îÖõ‘‘‘©Á}íf»^¯ ÍìÚ¸[®Tç¹òûsýq…¥äë·W(–¡iH<RÙ–µQoomÖ|·%w}—XjüÀTXiÿoøI§ùàýgöîMÆ ˜”ÀþÁÁ±µd2î5=ßE‹·Ξ™}÷½Ÿg¦³&4dà6Ýb½ÛÁ\h‰¤ÏÙ–‘7 Q’,Œfú9HB †ö ÅyL@…$ðEÔà`,î…a£Ñ]«ÔJkµn·Ö?Q˜˜žœšž¦†V©v$RF:1¨©éFxŸŠP½G÷ûéß¾7wãmNÂüÌðôÌ®¤a}篿gëÌ`)- Ý‘¡Ýq˜¿tñL;h¨Ó9ußÞ§ž|ùì{×0ŸžYÜ^½.y€(QdkšzXÀÃÓ»ZõÍá|$[A¥~'7œY¼TK¦Œ)ÕˆRÜHIƒ¥bîe¡"†!ë4ëà€ŠŽÒ‹ë~Ú1«k%dà#Óæòêæúj§UŒš’sßï°­•;çW A#oD¸^ë”¶×Yé¼­%›só«þë…T¿>C‘QnnÄ­Ô{ïþlr_²´^ô‚†Ûi¯½¼t1¥„*T"•¸òã3&õï?ö“AÔØ®Ý¼pÉqг_û T¦»Ú:áÎÐàè?ùÚ7ÖÖ+ÌkC…4.òÝ¿­ësÇžÿ*@¨FoýÕ? ?2~ø‘_SIA>ùðÝ¢?àðÓIe•×6K‹ó®Þ9þ¹gâ4‡ œœNNŸxçã¿þÿ~ßTßK/½b*Û¯l^¼yÊ(×±o6#Ù5•QZ.‘#Hpår}ÛMï7ý[ÿö/ÿô·ç+\¤D1 Bb(¥fr¡ÓèjÀ6ßøÑé7_û¾t7¿ò›/³ ec˜Œ‘ŽhNïÞeQG…„õá¾|$¡f†“°L½?¹ÛV(F´ÖR˰¤ ¤9„‚Cm~nÞ4ÅH_ú±'zé¥ûòYdálr¨^-…Œ!Äc–Ž©…Ð!õmáz IE¨ÇNçW«#±ˆÎCWò(Š"IV2RÝ"º‰M³cE@b¹3 W€Ë€ ‘dÝÞý·iØ~»Ë#W2ÐtC"$@ˆÅ8YR(ø=ã²FA €)Fè³$ÁC„€P)„1BX…±$÷ŒðR %8Æ#ÒÛïaˆ`!ß›ÓcHñÎãM{… î°±îI UO¤ºƒýÌ?åNñ’JäN‡ˆ@=®–€éÐgaháT}»3àÕË‹}áÉ<}çæ­riqÏ£8þìÁ½Gj7ÜË7~ö¥W~åù¼»âþü½~þšN0$FY†…í˜-<—yM¢”ßj™ÈÀÄ‚¦c;9›˜ÈrÃÉÏÝ.ïtŸw¹è¸°‹|„¸îJõg¿ÿƒ“gßòpÌîÛ}¬ß0itäð.^æÕNµRi¹Lõ›ÿæÏÿèûoö¥ìV›cC£/<ûÂØÔØfµæÑØF³êuÙô²Œ0ÄÕÕu £^˜œí™§_J¤ÉúÖåã‡'o~rK‹q&A”Z¶× ¹ê>vßK +' ™¾ù»sC#})» šÑÌø}•[7ܰjÆb‹Â¨ \ù¨ZqU3zýÕ×%äTÒˆ ÇH&³± `ÒIl#Wë-Mk實ÝÍ ÓA+ŒY:Òµ ë¶»• ÖmÕ+Ê›w7‚¡×´5kpjê܉“_üÚÿôÎÇ'í? „¤ŽÖ‘žä‰ìn«Zlµ•4?9yi£<äÑc핵nØdmWqåÎܭιƒ/ü €Bu‚•Ù›íþÜoüfÆâÊ?|(UhýÞ?ûƒRÅC 9Ã㚥q9ê IDATO>üîûc‡rGùªäL6ÅÏß|u湑cGž‚sX¤N¿÷N±5ÿÔç¿Nµdqs•Ú²Û-?|ì¸ty}{j:rgÞÿ»¿ÿéþè?þÁä¾—×W7W—¿ûÎOó©ñ]ûîKŒÝÉdìxÂ`À0õt¢Õk1¢ô?ÿ³?ù»ÿð×Ï<þØç_~8‚YTÿðH§å—·×PÄ )u@€ÕÍÒå«WüİúÆï|ñ_üá¿â*•"±Ž×¦ G ´¶¥T˜Œ[Êó‰ # 1$”*Ý7:Á=Å X¯6¥®4 ¡)Sï;:ýÒ¯|}ê¾#ñä0Õ M™ ‚§O|èÄmÅI'TŒQ(¤d *$‘ ©1Ö)…ç"Å`pL©ˆBj pGOd²y%8Pk4ÝŸ$€@öþå!€!Ž(Á@aC2¡ "HWòž KJL(T ì4) ‰‘&5"0œ ®@b%Ä„io…€2 ˆC„ñÎ\šº)%DQ…‚ˆ !½­#Á ˆ†¸gô€ @B5…ðgØüìó½{†Þ< }æ®B {+‰zÛS=ú„ªw_ ‘‚@e(Ü©øn³Ž‰ ˜ÂÈÈËÅûúû^þò×?ùðʹO?\Y]HŽr{²­2ùñkÿµowáÉG˜Ì̼ñ“·ÿøÿù¿ÚÍõx!º¾àʰ1ÖuHΰ CLQ©]Ò8l”ÀI)›Fjõr'âmºHF@“FÜÌìÑÚàüéQöŽ9¸Wt»Üz鱇däpæ^<ýV|˜êVÜ0€Ô,Ðû‡ïkn·Nœ»G!´×î6D½Ron•[€ÍâæâÒÜ7Ÿý's—n&œ$PÒ˜Nüîïþ÷7?\%[dµÚ]lÍ6‘•Y¼}Ux[C@…fïšÞwéz¥+ÔÆöJ-l­­­SÓn¹z±T\ž3‚•;ëW-7¶ Mµ£Ð±œ••peýç¨ÍjRDA³“Œ%¨c&q‡ë–iQK3uÔ;•¥¨d:—'‚4ÊE¸ê’ë…žOéaËjø¾•±tÍŽX`Ù Kc&[^yd÷.¹–Í¥“éå³³Æh´=W–VSp¢¢V6;¾0÷ÉsϾ(¹Øýàñ½ûïo-m.^¾œ×ûp“_¾z±0`fGeDoº¼kä€C)€‡âê[çŒìJ˜éwF^ýÁ_üóÿýÛ]×MÅíÑñ!ÑôÞxã»öÁî®™' ;ÕÆ‰?šy`jxøþžèÁoºsçO ïÊéÿ²å²ÛW/K0]›Ú¿¹µ&5mb×î»ç—.ûIß¾½õíëùý—?:QÜ\¸½ôÉo¼òù½»”ç–”ò)ÔÂȯ´š­Vu½¼ygn¾Û®\=wû?ÿŸÿ>©“_û¯äFD¨D"€Ù`*Õ78¦ ²²éV«Þl”W.”ÚzåÉ'üö?ûµ†¢® ýŽ£îuU²r¥¸²^*ÚI‡så¶;Â÷0ƃøPv m³»¡‰ˆr4T°‰U ’yêùÒÖ–¡¥ò"’Úòë)Ó§ÒÇttd8ŽM ]‹éL lL¨Ž 4Œ5—BH {ÂX3‚ $Œªõ„@J!ÑH E=9€PÓtÌÚF"®©(p1Ä=k(&„ )ƒ0RA%@â à€HbŒPφXÄ¥”R"”‚뺮ïM«(H!Fb BaŒ!½ûˆÕ4¼#À¹'œG" Ú±è@€ ’ Ht/xƒ€BP! Æ"‚Jýã±×gÊ[CÔ2" sÿ®ý= !*Bùê7~k¢0såÒ[×ïïÛûÅ/ÿÖc¾tõòÔá»÷î9hîÿÍÿýÉéwQ%Ïã˜InB!„0(ÐmÇ6œVµÑî4VËÃý*ÉgJÅjn:¡!«]kåÓÆj}-›h»%ÇÉ«Vëüµ“’Uwêhy¹qþÎ'“ãKwªë÷ð3ùa'”*ÉIRŽœ˜Z¹»²ëÐÑôØåóg[÷òÕv’©ôŸ{ÊÛˆ]»üz«S-­¬cåþÎÿðëÕEWKÆßþ‡ïoUîæF‡ ¡LèlÕÖ$`ã Û‘ø‘c›¥úµ+W8º±°ILckõ´°¡é®ï—Ýö­;U䨾$ÈŒ%wíÏ"ëÚUkªR½I_HÞi×’É$ 1#‘bVëè–fa$Ú~qs#“Ž9ù4!6%,›Àºnñ Û¶ãʱò¶e2 ’©¤iiõR%•u|%œ\¡`ë ]3N¼ÿã©]ÍÍ/>÷äç¼NGO9› ›ÉÑËEaÀ|¯Ý ®/®>4>s`”ÑØ¾ Þ6ÜVíöüÕñú§Dk†±½´â ³?F¡!9X¾pûü“ßø—¿§„Âðª{ý£·†÷d=þ j¬ÒºúéGÙ‘Ññ™£Õˆ€ÕÒæ•«§¬œµ{ß1úŒu9‡mÖa{mc˜uÑ+ŸZƒ†m™YGzmyæã·Þ>õvØeÿú÷ÿ×Xfbuy9›7Ýn¥RÔ-»S‹êzÐk×®½æôOß}û޾üÊ—³¹ÉNÕç ©ˆEÒCXgï¶]׋ª•²ú–­9“ ¥V«6£Ðs;n…Á©”LsŒ.çD·vŽïJbºU) ÚNLI!4[ÏkÓ#Ó»‡\Öêvä<„9Úweöfº¦šé{±0ç„éµ»š&y;2m(4ªë†¦kÃ1thè”KŸ¼o·Òã0Œ‰d‘ﻦRª „’ Á¤“kÖKTJ)„Pï-Å…J%!ˆb(‘NˆÀ¡œg”`€H/»¡BPA„zWR CΘ”*¡Â+)¥Úa+@=;†S ©{êJA (Bˆ&D×(A¸7†'¤7’G!¬ R²çÔÄ!LwÚÁÏò8Jõ„kèž5îœË«žiðe¸§¼Ý¹•;àw¥ ’b1„B“˜cLM+ln•f³Ð>8óàÊKWÎ~Š0xòÅçö>¶¼™ééd!Lq_Oƺ^ Y[0¡SÛׂ¶èèÈÊf¥³ý#¥Õ¶šh›±¶›LM^úø2`:kV¼ùµò…k×MŠ<â}xË휻¸od¨8[Kóƒ¿úê—¿©¹úZqs|f”ºÚ£3s—oŸ¸têÈÔÁµÒäæfÕ-5oÚWö=p¿[jíúžÇûkEûÔÕOŽ<>7{‡ö»^¾qþK_ÿÆÕ+×t#…¹^õ›ë-#6:ÆÄàP›šž:¶ûx}mÎJsP±¹A"uC¡ìm…ÈS~ny)žó‚&DÐóÜX<Ëy§Û‚¸Ãù¼Âúb­º¨uñ4©Û,14¸2»~ô¸’b¨œ¸•Ë5K‘ŒÅìò†¢º™? ÚaºV,+!³s™ÍZÛmÔBf¦KBœl#édsœêkÛkù•ÆÐ~B&‰E·ÔxÒkÖgW×3ŽzbÀF“gÒºõR „úZ}uùš„þÔ±G6W'ÆÇ¶–ËWÏŸµòËÖÌ;gÏ-m|úò¯ý$ $ØÛn_ùäãôîá}÷=Ê€¥ðÒ¹Ó}3…#÷?Îá¶Üëœ÷âCÏ.F3¡²v§¸¸RÝ^÷» ‡Åe¹l©x:P’ø*30êÖ+BUCÒýÊ7¿¸gÏñVÛ–•4Ý"õv 2XÙ.¯Þ¼TÚn{ÛÝм»ÿÁÏMìÏ Ž–·kD'$Çm ˜„°½UjU[À‚„®gLÃÀÔÔ"uÃW6 DÇšBz«Î ú¦r«M·ÝngbY¨Ú•r©`9ºc›¦ !BÁˆí ‹'­%˜(@RjÀ’¦áz{©Ûòu]Ë&2V,.NÄ’#¿É$làPʈ1ZI4+^1„t¬7; È„B’(À¸g‚”†N²l3R:„D0baˆ@$„ˆ€ Õm· G·ã Æ…(z.!H줎±„ötä Œ!PŒsE˜PP*…æRÜ;‰RB¥a  Ú¹îTBH‰u-p# ‘¦kT×!&!!&+…0†ðÞH ìüE€ñg”ÐÏ X=ò)ô—f`TÖ|¥¬ èݾ÷v™ 칞<šÚØÈ”P luoÏÏwy'–Iû2X½Y\]™Ÿ_¾Å¡ËgÛ34:ü'ÿé/n_9î‹ëŸ~s×ÔÑfYjó(¥!9y⟿þf·Y³4ò"Â"¨iœË ¹má+麹Ýp!6u‹b¢%,³ÕüÈ:óñ%Q>pßäô ˆÌó§.kËF†¾o¿bTx½TÆ4|ü©G°–úþßÿ$ÖG ÛÚX“ܼzelzoO•ŠwÛG•µ{t¤Y§OüÂÔµâÆºd"Wè'‘Þ©mLŒ,]YFiÿÀ±Çæ®Þð]žK¥6Š”“ ý¢å• ÍlTë‘ {äÐV¹½¶u3 ì RLߜ߂"ðB’¼ðìcÍ WG*…îÞñý wÏ2×lm¯B)$—N7·5($õVujßP©Vƒ‘À@¥-'ê y£]V ]E²®[5S^¥ºo×.¯ýn$ #Ë¢,”q+Öh—GAð8´WnÜÙ3ZÚÞŒ›T#¦ô£f§=817 s·V#¬ckÆÈIÒó×nÏ-]/-nEÍF½R£f,A¢?×)7?ýè„‘3Ž=üÌøÐ}³^Zº{íØCOal+Á­ZëÜÉw »S3%€ÕÍÎ/ÞûîÈÑ‘#‡Ÿá¡l•Êw®_ö°ø±§ugQTœßX¼q½VÚ,7JFiÏÃymèÍŸÿ„šN ‰Í»¡eòcÇΦûXÄ5'Q*—K›‹ ·oÝ>}þý÷öþë?+­ÜåH$™LZ±@²X< 4b:ñd6 â>_›_XY»Í¢TÓˆ†&v3˜pk^¸]­ 7ˆÄ¡ç*¤¢*dh*T’(ƒÆŽ4L Ì"0!$@£âˆ+¿Ñ®¬®Š(2R @.˜`c)%"˜@E)5†®'ÆÑEQ‚YÄ’”ÜûÒˆnÆ‚®$ÀJnb„öƒ(ŒÙ+3B 1†AD()‰T½é5A˜1ÆïA\z„¦›½¸1Dc„†H¨0Æ ¦Sݲ¦½wÁ„Š ( {©Þbã{-á/ùÈܳªB vÂ̽ѕ‚õ¾WrGp;Þr´SÓv†úš®%2ª™ÐgZE·1”Ú™s#é³gέm”Vn" ÃVóÑãÏí›9÷ÁéÓ'êΞ£{ç·¿5¼{Ò Þ³Ï<Ú ÐÒíåW¿û½F»ƒ¨i¦ÙÐð E2‚Áf©e­íWã“39¡™N†$ Luú …½ã¹ÄkE¡ôy$Çf†&‡ ŸáqV‘ËËÛµ=ÃÇxEþÝwÿßonß^¬wÖ!‹nÏžúÒ¯>šJŸ½ôáäXVI—`Y_lpñM®x' .Î]õݶϸUGöí‹¥ÒééñÁÌD§ÜE¥Gñþ­•3Ìï–·· Ó €l.Ý>tìÐľ‘‹WëÍF ÏÄf§RŒÅ©‹!D;Ýr¡ojyy.$BÅÜ´»qéVi}nma³Ð7&׉ês2±äDîÄ»ïèF­¦ÜXÚfÜÃ1“:&¤q(HÑÝŽ¥ûcQ¬V^‰Òz[aÑ =J­L>•í˦ó9iè–fæìÂDzB4º˜w ð‡ nÝ“ž ˜/ô!‡qJ¢ÝvˉÚu/h´Í±œL³[óX`N»ÓŽksvQ!o÷ÔîÁ¾ìÕ«7¯_=*h`¬nÜ­Ì/¾þ1yxïhaR#:«V?9ñãšœ:…jëæÖ…óï™ñG?÷Œ­¥©[˫۫ ئ^ì›yâÙ/}òÖÉ7~öÚ‘û¦]?V)m+bôçGy£5Ðß§BérÃN·ºvcöóçoÌ.œ;yêÂÕ ~ØJ ž{ö‘éû—7; q"° m§oßúxúàØäôƒÇî*-tO߸ðñÕÓDðt2+Illp\RÚiÔi Læ³XDܵÕÍNm=;<Üm†^»N ª6:õÍõxÜ64 ¢V«=wcvksmþæªa·v‚B’O[µ)€ +Ö—J²¶¨F53¦› ä ÍÀ–i‚) t…ž&Tƒ)ËHrM×!Á\pÆ8ç\(%$—LHMG@*ÍtÜ Nï_\°Ð²cJУ.à·] £AÌBŸ³H#XDL Fz{>%í<]Pv€‰‚ ÜËÈ(!¥áÞ  @HJ!ˆ ÆDðލB@/­ë&¨w# 1Â#¤’RÈÞ”AH Á=v P÷rÏ÷Ð bQ/]!¿éôð½6ÜÓ>ßûP/>ÖkRRMÓt a‘Íö7Û°òO¾øò°=²9W÷ë+z†„$–yàÁO~é• ùèÝwêÕµ¤cŽ;ôÒË_¾q÷’¦'˜'ËõŠ«o†±„ ²5­U®»¡?˜7 Á ,äíD:k«Ö­¶½ÖÀĸ•TÆå›7lC{åóO=|èhµÝ¦Ò$Šmµªncx¬*|ùÆÂ[¾õÕo<9>ðÞ‡çœ\êÆ'+¦ÔrJµÕýG,è<=3½UëŽî+VÐû?ÿ a(è«æöVÌVåõNuÒÉtè±CË å%êêK/+¯É\añÖ-ÁÚ™d2nÄ*~óÙçØØ€XãÕî­]GwQ=ㆠ$ëÖˆ¦÷Om,–X(&=ÀµŸ8ø˜  …“Š £PÊ `ÝŽA¾?íäâûXÓçç]̱Ašºf«lG9à ¡„TUjuà)ÀC©`߈"TÚZµ3Æ`¶/mDéÒN¸¡±üè4ašç‡ ‹L,#‰ÞñÝœUX¹»bØLµ› Çš:¸'ÙŸƒ¸ç—Ó@©±á‹ï=s÷üg-$†~øíoÞ|{h_ß®©µâª²N¥ûï}ÿ¹_ýJjÀHe×omýâÝŸ>øüã£Ãûx¨Šw6nÏ~¸ÿÈቑ]`ÈÁù“ï/-^C6 %~¡òý?ÿêt¾øÕ'ÖuË?úìÃÃ{³©L~d î²‘Ýc¡+îÎ^»üæG­Ëc}Ãï½y"=BGǦúGòNtÿ¯[™žÜGàŒ ô¥FGÃåÇrDFç¯^Ã\…asfß}w®Ì.n.ÖCôÌS_¨n5X7Øž[Ê õ¥ÓÙíÕCqÊL]ž;Ÿ>¼0·È¢R©ZL¬¬¯s ”Òªœl·u  (¬ì`e£ÓߟîË3,ª¥Zg£®|Ÿ‡Q‹W±eÙ$ÙŽ Œ¥ºg™*ŸÎ1J#OJ·³2·¬ Ñâ]¯Ö‰%f'»­ÐHÛ ·›Q#“ž*nUVËåµvБÑå5·Øèе]»wŸzÿ ÔP±¶==²¯´\^»{-húÍr'qÚ¬íFµ¾9?ÛàáÚ+ùÉ©¤“Ÿœ^¿^Yí,î©-w®ßÙè.y.Yk×›Pããý_ÿó¿üÊûtk³å1ïöÍ[ípõùW^©®‡Íí•Ù¹‹§^?ðøC¹þ‚HXoŸþø§/¶÷ÀSÜS¼Éνõ=mÈ=ú‹…ĘßôãÃc#}šfé”R:ùÂDnÿ«ÿé'×Ͻ¿±¹^kV5ÝüÙ{<õüáÂÐØ`>ÏçF†v9}•RýÓ÷.ˆ°¦|6{éú©3çøÖþËk?xúѧ¾üÊ×õøhZK1Ùjwº‘ïQÍ ¼±°ý­úõ:2NŸ?k™,7<‡©ËýÙß' jÏŸ»½pëö…O®ÍÏ^i•·bŽÑéx¦F4Ãn7n,/ŒìÅ:HŽ*’,ÎÇ!åÒR4Ž¡Q³«B΄빞ÑÄø¤Â–“NJífÓmÖ)A=÷|ßÐ bQÚÉ Í D£˜¦ã…V—3Á9‚‚s¨€ßq¥T@‚±¡ëšN,Û ^ˆ(% c,:PˆbÄ9Ç`¬¤R+ jA„ P +&«”EÆ ΀BJ©Jqéè¡!(”ì¤þvò7ö’ЄöÎ zIe„vz9=6Äõ*Ô%  Þo=5²w+ºã¸î ¶z¢Hd¯=@) áŽlGˆ 1F#ˆP,+»Õ0ô3€Œ CËÍä&öŒÌ-V6ÖV°Ö¹púäÝßõ»MMד‰L!—ñ»åæÊó¯¼ðøW^~òñon¬liTtÜó`H©ÛiÅ’ÉX¡?ˆBJS5¿Õí´Ai{¥´^rýRW’t,‡€”ÌÍŽŒbŽÃrE¾¢f^ÚÔ„»FFëë)[³"ÌÍüõ_ˆ‹®uéÎí_}éù×þþU{¨/›=´^®=x|ßÖZµº²LíLw­[.v6Ù³_x⾇ŸËÅFBWlmTæ¶mjŽ(=~ìkn3vçæÅ#Çî_ZªP]¹úÉǽÝ7Þ§"Pº5ôåƒ]n?zõm-o èH á‹m¯Ó9¸§°v«ìd-%I[¥Fgiáv(åÆöj,•&E0$‘Çà˜ÆóéÁ\Þs;˜œHm¯/)î§ãÉD!“œÙ“²A2™ä­65\²Ÿ^(XàúP2ŒÍêvEéÒ[Û¬£ÇSë++‹Û«««TÚ6`6uªÍuÖˆ%³‹7¯¬–7l*þÚ}Gmlo 7Ø^ºe8¨±ìÛ ³ÍæÒñÒJëÍ÷ÀaY#hcþÞyècõ Q笕*ì}õÿÝÓ¿ñXØ6ýŽwíô•O/\ìŸØW.³ñä¾ýÆç¿õß9© Pc¡|þúéƒG81÷"òÙÇ¿xÃ,ØCFRù¬Ü\ßû죴º¡¹¹¸6w묈­¿¿ú§ó¿¤ÆÓŠ‹õÍ ¿ÕÙj¿úÊÓ@òR¹vÚ@Šf×]Ÿ½^\Ÿ×=xì‰3ßþÎk?|çu“‚ÑÑô ?=¶'i¦ÊkmÀeÌl_ÖÎpŸ%¼DHÀíîn_½|hæÀÌÞ£K«Ûu5•Ê7ªmæ¥2K›‹:¦x«Ä’ýqºçA§Ö—L„Ôjnoº­€:fvi1jAK'»'&D,­LC2ÉüÀ¯•k~=–Œ—ç×9svjee174¤kvbx|ftpÆ :­ÆŠK‰æ +%ÍL¬Ñii6ŽÙùÆfSJ× dq{±vcC–•®5êëÅ•g.:,‰Ö¼|ú¾;³g¿ô Ë7k­v?ôÚOÿò''~̨øÆ¯}þ©'ÿÆ3Ñ7T)Žæ0Wé6çRHDQK„‘?™ÈÚ4=1 UfîÚìí[s–$^ijiê¹A£Ø RB‰W×Vºn·´±Q­m•ýºËyÜÎïž0H|³[ÉØ¹\6¥Tó[†cCˆqäú&uÍ@R´Ãf…Õ £1è¶‹!lE€ jÁP™†vX³Qt»5¤F Xq¥¤TJ )˜‚‚…D@l@´ˆq$%Fim!!yÏIìIc8Ð $B0 8C!„{´¼°J V„;û5.ç@J… F JñH*!D~ƒ"ŒP­,€@q1&º. @õ®%ze§WžzéäÏp¢p‡µ¸ˆÞ#£^>õä„hgxï Õ#‰ˆD쌹zƒ÷{-"ìë•RJ„ÁÊY±´Ý=À@8ù¢DÆœš<~ßCÂÒ±¾…õÆ[×ÚÍ’‘ÔhœÞZ®­,¬aLݨ~ðà &Ûv,A$VzŒbTÈö›¶E‰–2 AåXnÊNi&È›ºÎ¢0•KLØÃ*qšÔpŒB?UˆÛÙdˆðH~éš­™“3¶ï83xxo¾Ð¸+î·;…DRsÒŸ^¸-"qâòk83þL,–.Ü¿ïà—¿ò\«-M[脞<õÝL&T=hâáΞ¾27{ft`hsm#Ñ—›½sÛ÷7û辩}«Û·i,{}öJÌ4FÔñîô -0BSǠ϶V%Ou·¶˜jMŒ –ænû~ IIyj¾¼¼UÝâÙétÇ ¡ßÃZ6–WÐZ­Uúú†ëµf£Zç÷ÔÇ'R ˆ5E:BÙ~3‘»ŒÉ ,KŒZ©‰Ân.‘×bï²ëW®9£ãû}æú_ÿ‡¿>|ÿñV3ºtådßTnýö†½“Ý]» îÈȰ­Û·®Œï:4µë Îúc‰½‘áÊJ`úÄ_Í êÔÊPì¬.l}ðÞc‡¦çf¯[Žm÷QÂæávÓ!8õî«={ÿ¯ùŸ+¦ºÅòÝÅëñ|zlzßöÍ›Ÿ^üd¥±MQxì¡$UËå­;Å“¾vhbòKÿÍoom­¥wå'víßXüÿ˜zÏ(¹ÎûÌóM7ߪ[9tÎÝȈ$AŒ)Z%+­d{ä¤Íz½Þõœõ{v?سÇÞ™£‘×öH²ä$*PT (QÌ €ˆÜÝhtŽ•óÍ÷¾ï»ªA©¿t¨ªS]_þçžç÷l0“¿óâÛßûéëÇxâÑÓÇvå€ZÂ\¬HÙÄÖV¡á6ôˆ€\áÎôâ3ÿöÜ4?{âÐ} 5óh˜Päf¥¤K<‹!N-Ëq\ÏnwêÍõŸúXà9&ÏÎϼóZ¹|[„¡Ìb”XD(ê2d\Ñ’ñˆD•¬Þ.ul+¡»†&Þ,ñ½«—z³éáôˆ<¢˜ž=ØŸN'²«sm‰"‘G&Fb=>‚‰Ltd¨§M Jñt:¥g9˜À49"bâú>fjÍj„4⤧g«:ì&¬ ¢¬ê¡`„ŒÊyÈô¸&H*‚J iTÊSF)`´»jÂRŸÅ”XhZ^àŒ»9¤ÝQ AÈ9ëRgBp€1¶Û圓D t 1¢€!Dl»ÿÁ‘n¨ƘA†‚ˆÛ¦›íÅÄ!x·gw9ìÛíѶpônƒÛ Õö«ˎïæQðíñ3p×J¸­wUawÿ†DÉz4aÄâé¶úÈÇÏ¿s­Ñ˜•U§Å¾þ½3Kå™k÷?rhîF1*ÚÍRÉuË#‰L¥¶ù󧬆,‰Ë[E {†’Œ¼¦c:ÍhLˆ1´CÇòìN‹5lÚhuàÖòF6"£Ü,B@¸Ã€ïçúŒ§¿øAJ9m«cWbC¹Ã‡n®¯ª²dÒ ¡:3{}£T-k¥°(»>5Û”ßs·¥E"b@:ÆââÒòêmEI$"D¥âz9 æc}teæÆp.F×}D‚É©£bÅt;±Þ¸ÑkíRv0;20"ÊúÏžyþvãVÿÄx çÏ_Èdß¶tœ•ÅÕù¥Ù‘‰\µÐHÅcZ4î{æðð°o²Âü­«7_9~òñc£¥bgáÆÜÚÆtï@Ïh߸& ¿ø·g/¾óú±Ç›ŽöÂ?~÷òÅ×l<Þ=õøSŒ˜ëÓ×#‚b/m|ðÁå ç¦W×ÞŸ:šâôÃÙñ}fÈM·ãø84g.l¶Û¶×rß8ãÆõ+7n] ìÎï|î³L#ºA&„‚éPæzœ V«E¶& +p³ÉçAÀÌÅÅÚ•ÊJµ¸RA%2å¡Î©¦ !…¾OÛNP¯ûµÕf§Õ¬; ER3ÙL¶·qØj[k7§[¸ðÔ'Öµôµ›×t 4:ÍìPÂH ‹ŠàÛ¡¢(”†MÍõ µlÊ=äT‰ˆÑhB ØsÛÄ D(¬ÎÏ(q®"±Õnˆ¢êv¨8‚ @ÄŒRMSEg°0 ¡úžˆ‘ ˆBN9B €œÒnŠÌtY¶]Q*I@ Ð]ó.îÀ£ ýnÆ»RŒ!è¼wã]Uº @Œ F²$`‘@ÞåƒÂ®Üa$BWc€@W{E0ÂÝm? bˆÉöp>ä ßý޶ Üó¶{³îi’qÀ£wsžçÝÖ¯·gO¾] 0ÖÜ*ú®é:®åš"qsÉ„HOÄF÷––*Ô[ Ÿ£H&òÀáÚ½°6¿°4{{i^dJ¡ºŽx ƒ",Ô-f¹.†+K˪n˜åR¹]MTEÂLÀŽçirSòCÀˆâJ=¢%åœ&ÃT,"B‘Ðjµe¶šX4•6„âòŠ‘Œå¥;«gν¡ù྅$ôÀÂ܆jØû÷œ>÷ö×rê[«®\­—ÖfîLŽŽNLé±ä£'OÙõæùÞZž]ÒUS á¡ýÇ^yéÍ ¨BÊÆ‡ÇæË×–¯–«…O}úã‹Ó«²¬ŠKÙá¤$ÓËW»÷IMö(—fSÃ写Ë÷x@²ƒ`|ÇÞéÙUM‰4œBqÛbykø>õüj»6B§P˜[¿ùÞkïÿø¹ïY‚Un‡fG—Is£aÛm¿Ý?ëm×[…æ (`°op´Z¬ ñD£Ó(VÖ}×…0=¿µ¾Ö?‘I¥2ž]c~`òæøÌ=ÿƒg÷bzæöÌÕþñµå实ß58Hô6* =*ÅzÇAÕ=ó×)ê쟌ŠÚOúüðñážáaIU;>¸zþö¦5ò‰ŒTO¼gDTU†ƒl&Oøò/~¾±1}äȉ°‰;ÍöÒÂ\eñ¶˜PŒh¶¶\ø›¿ýZ¢7ÿ‰ßþô…¯žÿ-ÈÉŽ©±‘lvljjqzÉl:soLO¯.Ï7¹àÈŽñ}cñÜîýqèÅÚæÙ`³Ùq¨ékŽÕð§§W+å ³Q?ñÀ±ý÷Ü“I庵Tž0ë8M(‹’¦MQŒ¨kÛ&0a¨I ¨Ø®,(ÑHºY«æˆ19“‰@ ØN;À J  › =‘JÊ‘l¯cÒvyÃGDO£¸\ª–6– Å%¦-•Êç3#ã#íj'š‹fû© tܶàsîqÊ|ÀYÜÐ3É|np²‰é©TFÑôd"Cl_âPeãfµ…°e>€áFa%d¾,E€, C#Hn¶LßmÆiH»·0€ & ˜ ây6D˜†Œ10D„@B„‰€EE""!‚„0&‡œsÎ DŒs@CD c€CBˆe1BH7! n«·ï†cL €]—t×݇&„`Œ!Bn¯Õ»–?Æ9àî´økôönBÛR…®4 ˆÚVš2À}ÆFe‚ÛÂÑ»‡Å»›wÀ9êîâ`½XAšNd£Vw˜*RŒs&aéøž#‡î=˜ŒgîT‘ šv§o÷ÔÉO~bïþýÃcCSƒ0$ºŒ]Ûi6íšp¨=ªzV­N0¶:Ó±²©!×jC╚JÄ@ä4›–åJ†x.r\IÆF`HѱÔ@L3¼V¥ÞiTZM ƒ±±¤ ßùÑ{ï¼òâÉ'|öãOSæpYÙ,ÏßûÏð•ï}ë -Ò›D=·n]Ų5±ç>¿ãÏÏ]/­ÝÁóèÉS¥­ðÒõé7Ïžm› ”zùÅ·sÚàòÚòÉŽ-]\_^^NÄ4EÊÜüàüòÊZdrˆ¸ÂF½Ð{$_ß~³%ò h[Œù8„ú¾Œ°"^»r]4T3l ŽŽ¶6ÞÛÛnCÈ2ÇâPhZ&}&`Çu8@=(aÖÓ3ȸ$j7³a'zSQ9¯E•ÅKs+ßÕ$…JæÔžû×ç6×W6°¦—Š­äÞžL¬ÿÚù‹$‰÷÷§bùt$>±{<Ác¿8óêÆÊÖàÙÀ™3¯¿¶s*qê¡Ç !fö??ªWO<ò@DŽq,zµ²åµ)ƒÙÞ¿ýæßBÛÿˆ(q]߬l´ª•HRލú{¯¾ö×ÿø§ûšúÉO’Lá#Göï~è(ÁéåË››·/ЅŹµ gÞ¾~sºw¼·OOôÄ¢'a€k«E×®/,—V7æ‘è•÷g¥ˆwóöŠ P›Ö%-¹¹<_©´÷ŽïÀÐî4°((²CâÓŽUØ,¾óówf/½öú¹ró¶%(†¬Èñ|_*ŸÌi†ÜèC!M¤“î=|<'½ã¢J{ÝÐdß³lß!D‰'Ò‘x<®ÇbF²^kPß·k-Ylgi"ˆHÇg’ÌÃS#Q#æX#*A2“!fœ 24™bÞ32áq j†"F!ƒD–¤¡‹±Ã jD7[u¿Ó€bIb{õ}AN8©«J e¬›[À‰R)e„€cAP5U–UI’0Â"ˆÑÝRÁ1bŒYH &8 )@] ÂCˆ”u±È@ØeË B!a@D]´Ã¶x¡[Û„˜ÝüføáW7§ût™£l ®h{/ÕÅ5 þJ¹µ­ÚâqènÞ=‚€1î›Nˆ¼„n]Z/åέéŠÈhè—;…ÂÚ*…Ñ!-ŸÎѦ-EŠAÉ‘©[šYèßÙ6Û™Á‘X&uòž}"@¾Í͆…©Ç7Õ׉Üi´77+‘„Qª”Ú¥-†h2ÈPèºå ›n«Þö®Ýz_G’¹\Ãmhš\0[. E$V:R2ÆCÆ8û0DÚ<ìñ<—yx2?04  ŠÏ B8KшãµÉÁ-áx2>xhthO£YD¬¨q‰rŸ±À¦Àƒn`Ë+‰É”Àp"¡ë"ŽFb‚Êr×¾ó¬Z³×®ñÀWE0Яe)«]ÜMES¯¾tþú;—  ~­žœëKN%tƒ‰ŽÊI¥dÉX÷µbcúãO?ròè£õ™Îß|õïzw+¿ÿ…ÏÑdÛá WæË|ë?þé³±üáÁÃ¥Ùú?ÿýŸWš—öôí½ßZ¬MŸ}%›Ö<¶os¹Z+–V®¾Ó×íÙß÷Ì·¿±co®ÙiåbdôàØ›?JM5³ÃqÙžyÝHèA4¬_oOÆÕ™iéZ¤g`DAjiq©co¤tQ@A€BUå3ÆêµµxRnкëù…N¥²p¾4__(lÍ]b´ÍÛªlQ ײL—3î…¾[³ž‰©\ß ‘±)†ªgûFJtQ{ëÒÛ¹¼#«ºJ(Jé¤JM–WW%#èß½kîÎâäþ~±Å^¹ñÜ‘ûwS$Mß¹Ù®m¤s¹w_x·°zÁ [±\vickÙ+§û¤#$~÷{/оÒ#OýîúÒ6a³²ž™»U½¾;?LM³²p£Ø$2ˆ,&;¶p Üù`*$:örj¼¶¹¹µ¹zkõÆ®ûäˆñ˯.U uh¯Ÿ¿eAXÛ*~í;_ÍX„QÉè1RFÔA2wõr¥Îò‹_\[ºÑ¼¨.Š"  9¥~v°WËÅÖmà¶Jg¾–×´jfkp"sòñ§RñtqiEù†Õ¤Xu ˆ¨"Ñ0O‘¸ +N§Ý)oHÑH*–³ áVu‘ÚNÐr} eYˆ-€ŽÌEA©ç†¾¥ w€ÛikІ€HB|Ê‚¤h˜A1bõæŒ Q%Œ0ÄD„H„x¾GÄ’ -Š ÒEDA¥€S†€Œ †€{!Çc‡%¨‰Db"‘DŒeB$"„ !‚"nV)!‘Uñv[„ÈÝf I†tÈízÔí8CˆÀiÞM“èÎ|èCÜ(D"Ä`0„p Áö£°ŠÓµ g Îcc”QÎ9€ˆ222î1JCÊèþJ(£|[¹¥Gu·ãPŽKd2™~©_â ‚ -7•‚1LŒ§œ004ÝwœV‹taBR×.IÃãVÇrn±ÓÒU@»fD™ul_SaÔc¤E•¦ÛXX­`±… Ö3 ÙH}ä#§Ž>†}ù/ÿè­÷~!% Ï¡aà …ÏÿÙ~÷ÿcL S"˜¶Y)/¬- ìb(žP¤µ;•(üî—¿2aì5"²áûËg©bPX‰&ÿŸ¿x¦¶õÁàøðÉ£Gª–ýö¥‹ú`êácŠû‹w^™.ÌödFöþ¿ÿåk;w™¿µ¸ûÈáΦ´^-¤û‡&'öâ‹©TÏÎS{go4Ò=™š¥ÂÓjÅUbìà£Ã#µj#Ý-–8ƒÑÙ—c>ÇD`ŽUœ™¦d€Þñ8ÑYvx”yU\¤¨c¥rTh·]A§ÁHB‹£ºÙyý_¾»6sí;/~ÿÝ÷ÎÜ÷äƒþ—tßÁGn\ÙÚ\YÒäèúF-ôÍÒJµÙ©$Æy2¥' ŠÕhT[]™7M!ªÅS[77ß¹üÚÓŸ9¾½»R‘‘3￯I”ˆºxæç{+½«/ß¿[ƒºiuN=tjxryÙ™K³Õbñ‘C»ÝzïÊ{q#WXXxø©£›W¼¶avL,6‹¿øþ3šJ`“ÝY¾4¥oþÍ3ŽÙìxÍh&Ò6õéå"KÍFÓí(ªœVâP Ò*›¶Ý”±¶´¥§8g̱;†F„±")(bz°Ö(ת–²PÐBu|Û­wöí®MWDA(–¶üÞšYܱŠÂVikþb[‹ê¡‹Í¶#i\Ф¿þ_¾–êE“ûï\¾ÃSÂ7¾ú—›õ™ôøòµ9Ñ-F¥Yu/Î|ÉK Óy÷õ‹¥ÅE¬É6ÅŽí®,Uj«ô•¯Ì\~7 ðÀo<©áø™ßzóö›÷|ì8âLRLî a¤­n‹ ×wöL˜«[/}ç›§Nï88tЫlÕJ–i— KWüÒóÇ=õŸþä/'Žïù§/š&æÿ§OŽíщh>¶whäèêVP/•»ºo$¿xbCÕ#—.¿áùˆU­ÁLâÌk×.¼óA»¸a£ZÇ2HîŒìR àHLAš,Iñ؉§¾pú¾‡òÙ ©ÓvïÛ5âÔTB°Œ0Ÿ02ºB¦o¢Ðâ5;@4C‰%t°˜‘F±Z·:€ ˆ ‘# #šHŽöìèíKÆ“ùé¹µÒÆrÝ´‚NAÀ¹ϦBÆm¦} IDATCH;å‘[dѵl !$Pd†€¢ÒÐët"º’ÍÆ1”dIdÔçÆ]Ë³Û „íz™û®ˆERsAàsÌ]'%“átos,äàrQdYCÀED 0ØÕ0A‚Ad”‡aˆ)Gpθ@@à‡‡ „0ʺî„‚°›UÇ8ÇBÀçˆuç3Î 9ä”sFQ×£¼MÜ•_ÿ°ZeS*Ù`à×T¥œ#Æ»zT´ýÁ~ ŸÌ !ˆ ëZBÛÀ- lõÎôpâbÞˆÇeÕò¨ó=«ï>t¤¹à´šÍ•¹,y~ÓçIѤèŠÙH¯HémÖ«ý;”Öjm³”HQ¦{Ž­h‘Ö¦i–DEA wwb(ë™Ø·ç(³†Š¨€0A(,˜²ïüó7×Öú7?óÄoŽŒõç£Éµ•ÂøÎ‰µõµ…͹\Oo4@Ç¢L’4µó¸Š‰,@L©UEQ¿¶YO5Œ®­ÔDIyõÜ»Žß{ú¡O®mÍ8$yeúºåY£Ã¹t<;o¼ñúƒŸ¸büÈ™—.^z÷Çó¾øùϽùã|ÍÎåú õF$®Ïܸ¾ç) #½ÒØÅ ×Í`=5–ÉMLžºçÈÄHº'|Ôò`i7_˜ßX6AXª×ZÜ$D‹©Œ¦nÕÖ,×–"Þ±£'—®-5:ë›­6ꢙ¢H‰èñdÖõ¸`•£dÔˆ+Q9:¸ã¾™éÙH•ǬM³ÒnÌ\.¿öÖ+àŸ>ýp¡¼RqÖ.ܸð½ï~kgïøÙËsuw¥¯'3Ø?8’ëãü«Ë3Ó¥z©b¹õŽçºžÛ1›[Õ©ý‘Įޞ؞ýÇåÆí¦W{ãú[—ÎÝ®4no®ÕZÍM“bÁŒDe!¹ïÑ#Q9ºµÒ¨Ã±,{!&DêÈ¥‚ìÆsã>ÁõµÊÀ®>ÛÖeAªª”R¤H´Óab©¾Á )]?ó¦¬àþ¡EÕã™,Q¢ñxL‹Æì†U¬n¾ñÓ·gV¦YÀï,.Þ™™õQÀP9 ¢Â˜Èd{R=zÞP ]Žàˆ&p„e"zÀƢȡèS&a!4ôDBP“€€ÐÇ,p䜄€Q!äŽÓ8G¡&âi2A×1˜Ï’ñ”븾c!çø. <•L1@ººJH$° ýD’$kF¢{qcIBc€Â…a@²€3ÀDˆÄ„œ>G]Í]ãœw—J]ÁûÝl»^›nvdñu¤€Á_wÞ5‚_x÷Stí ‹ B § £·XA„Ñ]¤2ÜóL‚@À©’”t%<  8猑ˆÚÚf™û,•È–«+i5YÝ\P¢êÖFQŒ¸’ÛŽØtfcf|ç@4šd@ÀœaÐiò•Ú¼ëšàvœ|ø°&e[í¢¡'V¨$Q4“ö,±o 3»¸ö÷_ûÿ¾÷ã¿3&•ÏÿÞï'ŒØÅ³ï&Fäte¹Ú©•29%ªôr“˜o¦ ¨çrF¸x£;w׫Ú͵U5ê)Ut¥_>ÿ\ÿ@òûÓÿÃ,¹­³´2S(/*©h6;¡™âÆÂ¥xœØ}ÀñlWl'ö¤ÿç/ýÁ?üÝ3ïξ8<8 Ñ(Á+·®ŒïØãÕkãý#¯\x3]‘ë³ó·F{^øþ·*×K$R’DæWn›–É} <ÔñL ‰ïÏ,ù¬áÕAÞÐãÉÜÅ3b4n *ƒQŸÛm¡cÛ.@Ð V³¡Aase‹¨Ú‹gÅ ¨ 8Á„¬m¬2Ñ” \/Yïþ¡=Q*ÕìºOF,?wn.—‰í=vñÌ/ #½¸R<´ÿžR­]–å⩽ô3’®ôÊÉ!b=‘šµ¦coΆ¤91¹ïÝË—«NS3r½ýÀr «w|Åê?|ýÌuêUAj*O|ÿüå3ï_¿²ÿž#WÛÍÛFTøäG5«îâôì…«×+å™ÜΞÞÝók«7®®\ïBB‰­›^TÛ¦?‹‚dn’—ÿéÙåÚ­Ó§OŒ÷¾çd¥ÕLdR"qb¹ŒˆÛ.”6TVéíééh¬'‘‰ Üd "p¿†²Qm‡¡G›Í¶'RÓ Z^CŒIŠÇ_/.´m…cË*Æ{ÒN,,¬H:¸Ró*XRÕDË …Þ‘¤j­©¦jJeyó—¿üù·¿ù/?ýç¯ÿà'ÿfE;º Ún¹Ñ‘‘ÈqÐp[ǰ¤„1²±„®j€ ø.·},€Hèq̹ßñ«ƒBÄ„ÈõL´] $Ê„ àD"Z$ð=-"kz´Õj)QÙµý••Û4 CΣ€Œ¡$«Œq8å, ~BÀ¶™SaA”!B]‹ ‘N„ à€²°+å”2À¶õbˆ|W—Xh¢,Mß¼ËfCƒAq½Q]_Æ„ æÇ’9¢ˆX–Ú ŸrM†Ìò)FˆSHAè0/ áìÂ<ç"”ðÂÒÚ«?~eia^×”ûî?©‰}±¸°ì9¥l2™SÈ B@³j!_Ò ä„ÛV±PÒ 1kŽH˜ãÛš„¨‚þë_}MîçŸþÂÂÍÍ¥år­Ñ.VrÙ”G™È¤Á]=éìÑsggW—sC§¦|ý¥w+ÎzO>¥àH$à™¼Þ7´Cˆ:ÌK,ÏÌ Õ5âÆFsÁâÐĨUo¦’b46–—XXwÌšJP«iݺ>-@;™“©Ý)7Ö õª"তptr`ÂrC°ìmÎ-ééœè\ÒIêoÖ/Þx«¸f7dPårmkEˆPV±§/¿=¹3oÄû<½uöJ,=tóú‘k#¾ýÌŒt¾ÞìÈÊ'ã%k-Ý‹KêÏ_=Åþìd{³ƒûàŽÉv=pB4m¥V.d"ñÞ{ãê7´˜–Ì H.]¸ÌÄZØ6¿õwÝÚDè‘ÂÄsßÿÙÌôë~àFdÉ\+,Ì]>°sÏñV‡]¹´pîÌÛý»3ÇŽ?8Õ?à5‹kë›Z<¢q=žH÷S·åE-E}! 0~óöL|$B5AqiD5~zþÊtiúôgOOïk‚–i#TïTšÍJ]ô¡GYÈdA Î}äÐýzcCŽç5*ÛDÕVSÄ*°pEše3DDåZ£eÛvú^F“!„œ^›¾r[ òf½æ5°_’ÚÜZTD²8¿ñÃoÿtîöÙòúæò† ‚vÓO&µÞ|*¥EöÜqtÏR¢“fm rì8^ZÁ€;®å@Â9œú*ÑQ$z”ù¡¨Ê`N1ä0"¢N½Â\ Ç1 ’@Q‹%Q&:ޏ†@DÏ÷`¢ »f‡ÒsB¹“e5 ÊBÏuYÏ)ƒ0À|Ï ì¶„„q.*¢*«Àe—@Æ8¥~WZÀ#‡ð=w[VÎùv£„1‚PF¥€3Æ9§fIpÀY7uéUw™ü®‹ßE×|ø(Øn±DˆpN·9§b ¤Ûá;rN$Sö¡Ég[†*Gâºh„A()±jì:0Ââ:†È§¾ï‡´ÿÔÃ[Õe$YÑH_À=)ž按"bŠõ«²ošý‘áÅÛ!-Û›%W Uâ ‚$Cz­P}¡oÇ®]–ß𛵈¤p±ÀqE/t°$ã0ÄÍæÏ~ùÝ·/\åžúëPNçSžïÂ׫Õ?öf¡ªW;1¹kUª¶«&”‹Ì¿ûF(7<§§ã4;åð‘û÷!©oú½‹/ÿøùšlþ·ÿñ—ßøïý╳'è?zøñå™;»NNh|ôùçãnßÀÁ7Î?ü©½òëâ­wç¼O&žz÷úÏyÂÿ/}æ…Ô[v=¡õ;Ì7z¥]÷~Ê®U%E;vïi·TKçbŸ<ø¹ÚææÍïþÞ—ÿä­Ÿ¼žÎÅþàßÿ»ûÞïVßW®77Œ¹+/ õÇŠžï7¤ó¯ýüâsnÁtÅJ¹Õ^ºµ4c-Þi+ý±\ÿ®?ºï/^ÿêåã_º·³o_¼ìëîøÄS¥+‹‹k+§O}ôâ›?»5{‡ƒúKoÝZn<ñÈѯû_8FÿË©?¼ôÆí$N|ç_¾Ú1•’³·WŸ;óêçO~ëµã=Éû9õîÏÎGGܹ’uåÕëýDßõófnÈß½óvüÿþ÷5²cÿ®!Œ™Ý„“» hýÔ-¿qq»Í=îí,ɲ,ìÚ ;é»úæÊÜÚÛ‰‰ÁÝScÜkµ Õä ›’Rk½Õä7ÞO$2A-,â:vîS¬€Sä‡ùÌ{…ˆl\ºvFå ´*¿|ååw/ÎßK jH/c£¸¶™íÕ‚0Q·+N»{“ñ‰¼í/‡–‹$x`t’´&[ÙáVõZM72”ž¾¾5.K$Ñ[«j’(Ù€ã@˜Ýºð†f¤Bhs7P” µ:¢žRt#¡Pé<ÿÒyäÔ7íÆP4oñ a¢H†ïÛ*1R¯ÓY]-öåSûö?T­ï´–o\>·¹¶$ R±e3§CQ†Òl{Q¸Ýrp×¢v½ahŸò€Â ð9§H’­F=ð)¤!Ä1dD-‰ â´{DˆFÀSU”A`a»2ÈT‘ÕNË¢Ðou€eÜõú¦m»ˆn@ÈD@¡mC9gœqÆA8dl»±‹‡˜ò#Ü]qÎ „ʹ€SÈ£Ânô¡s°«¸èf̃»‰‚–<ÎY÷Gζù}ÛhQÒ]µo˜œñ»-B#È»ÉÔtªÝ—oó„€åû9çv­¹46°û­Wß¿÷þÇÊ«©ñ±bµO$"Ù„¾¤ß·ó£o¼ýF2•5› 74}¹Üp(Š¡Ý"XC‚lYNhqb·¹êªozëµ¥ˆc}É¥‹…c]|EƒX?ýðØÍ[ÞÊÌln(¶µ[Ë¡;ÀSá ìâPžþGCûjb::“Lì­¯­mn%Ó#ƒãGÑíµÉXÿº*ºT^š_ÆRMó#›•ªCþé[_}ð‰ûÓçVß:sM &yæ_ŸÿÍÏ|&­Kó ³/M„¦÷_øÒ£ûn–š¤'•™ž_ÅnÒ¯ŸñÛ|àdÿµ«íZä* wsï‘+7Ø[o¼¨åòw.­“x+¸c$m¡³,|ãûÕ; %%¬ÿòÂÖ½ßSythÝl'é^ wæ¡g)1úÁ­›&ç*Ë}äq·´Q®ú×?x91½°ü®vöðLÑÏQ¡Üª¼|æEg¹¥(‘[ï\] nf‡vSkþæÔ®{ξüÚàá ¾Ê^ýù˜’”Ò'¿øi¯õ;õD_û?ÿ__Žñü½ÇXÇnY¼“Û=\[½2<Ü›=JRÙ¤N""j $Ÿþê FesívµSì4:Þeóý‰]ѳ7Ì{{ä¯ýÓF{&ô«íÐ*…J2—÷kþ‰‡'Úö 9[Yb‹žÑòz`û‹7n˜‘Ðàô±ݨTÊ««¡bYÜVÉ›¯¾ÛT}è`>9däÓ`¶uÿ±GÎ?{éʛ̞1ßÄ£±xS)˜ž¢Hªûý<³6uMnµ[>k»«ÒlŒŠf#X™©ÒTG$›0¯Ì 4\,lX¡%P¼·gøºûÆH||Õ€Û"J:l¹tŽ` ¦SEjÕ;o5+RA ­¦Y¹Ì?4µµÙN¤DÛ··é[¥ò¤ØÌô'Ý9Ù¯[cãȪ®A)A)hú,ÇÊ!#"B¿d™¨Z2pÍX&ÖZ†!cv»åzŽcZ˜Ãp !¤Ð ˆ(§cÃ0ZM9¤@€º¬ÝiQ2l[y§,€öýAbøDç 8€BA7æ/dót(eݯã œ1¸‘Ãðnd3ÂHĈ@Ì€Cˆ‰ `·’’¡ÆüבU hˆ¶09ã]2ûv˜`W@Êm&DÝ$z@—1x—ÏÀë.Θ!†rŽ8ƒ|›âÇ!#ÎY’%ì88" rC$‰‚¦ÈCƒI5Ù¬ÕÇ÷ žûá«CCôv‚hwZ5(—®œ=|â„ÄÄ­je÷á{ƒ¶…h¨I@ˆä¢’ÐØèÄsyQ3b1½wlG*Þr–Ф#…¹ãxaÀØ‹¶o¤åS÷Ò4?™NÊ D”àg¯®­—g†ÓÉZ‚&ó-,—¯Ý>_\Þt½¶U« æ´C»÷g¥D¡4c@ãÜì9!¦¥S¹v¡umv¦§§W“X)µ¹­çžû‰ã–§öîzí›gßž;ë2ô?þæ[gfÎÖ¶êç~ò¿þè»)Eœ[ÚpÛÕÛ—gVŠ›ýûw¤z{e¦÷ ç®Î­°Óò%«QU9¼9¿º¹º^);×n-»ÀK&{ ”Ò =ß7·|-å þö§?ˆ²¡Éƒ½‰dæ·þ×/%FöH9€B_Õ¬qÏÑý=rô‘Ó¿!´ôV½¬Ž¥S™¬ ½ÿ#OÜ}ø©rÍìéK$Œì¡{Ž<þñ'ïè”bðßÿý/}îéMœÊ7:â½wÏ'Ž :NªW4`„VDKUË,lÞ^™Jdë+­ï|ÿsKwfço‹n¥gr÷ì™;°@7UÁëýÉ–x4³Q·Dn§Ò RÒ¹¡¡$šÚ¿3¥ýùßþÕï}êŸÜqïähϽ'Žï™º7Þ“þòþöÆ1l9õD¯™V­Öt¢$z{£r¶PnoU×°ï,çzDÌDÇeU¶ÃÚPnȳmAŽ]xn©!®ø”« m˜OõņãaDÖdmÇØÀøè~bR“áùõ’S­%ò™f1ŒZùD2¶|cS!­?úùŽog¹Úb­B;´›¦e57¶»´X½£ÅEjÈѤŽR%e~kkef+‚ãZ8HÑ€SYà€>|ïäÇN¡/:d¢–†‡®\~#Éî´©ì,/–[[$êÌa*2F`ˆ†JÔ@‚à"1„òÀfŽí´Çá¾ ç˜XM¯îUD‚¤RnSÐ Š˜rJÃsèØŽã[c  aÀ]ß'¢Øi˜”°ÎäŒSÆ1ô}'ä $ɲ‰PÎF œÆ8e@H»qö˜¦å.GÛL©†Œ†²¦CŽ8£Û½PW›Âh›«Î»qcs¸ )FˆÝÅ!óa¢Ý‹qÞ%vu߆oóC··íàÃbÅ•ö¶sͧF ¸! 2ÖUmApw¸ìÊ!œ#9€˜‘dB5$Iê Ä 9?:¬€€xüÔÉ­Í…d<á¸L<á†çÈ&§¦Eâê¡#“µ­uF໊B”h*p}ÀlÄ\À¹Ýi{Vˆ Zµ¹‰ F¾èÚ.ça4FrÙŽïì˜üˆÕòúò½ƒ UMDE¬•:kë«-¿Ñ¤Îc§Ÿ¾÷øQ‹%îÜ^Y,oJÒ7Y–™Jç×î¬Ýw`À·MÛ¢ ÓJ"䥵­ÊøHv¨wÐñÉåéùf§Md=M*íë?|l_OvX7p:)S‡ÆT]•b»†Ó¼î>ûÕ}çܹV¥T+m IÕ•¤ªÅi(G2=%/K<‘•pˆ ã ‘¥––6Ý‚u½¾Z´Û³óÅgøœ ;GOìî킾ðú/[­âèdŸ&‹“ûzOž °Ï¤ÔÕ«gžØ ‰Ú+g’ªüð'~ê©‘á]²¤ÿï¿ý»b"uâ#ÇÒQ’Q†ÖÖ8.b9S©oƆUŸb|ðý«·ïy|ÿRÕ(³öðþñ¶ç®.,Œœ¼§7u¼hº£Æ÷ç£Ú£7  dbb*?0106úØ®Ïâda¶0`ŸñTœU*õªm—eÂKM˦vÉzöÙ~ö…Ômäð{ö>úØC»‡ö,UËêDNVÄ¡‰\4Ú?98¨gÄRÝŸËö§3*$ž]gì[×l¸É-³T*”¡Œu4?3wsúÚòVy¯k²F©#b2t2(AxýÅå†'ù1CÔn·Ö4h¸¬’"J2ì0—¸âƒÃýõvóäoÇ`{‰Ä9âXDDøÝ¹‹ÄcL@÷ º‹óíD×n(óÝC ¼ëÚÞhqÈ-o¾ òº+jØf’vƒ¿Š¨Û“%H×ÅØÍã°[/ávåµb½½%‚0—Ô¨$Fˆ]™yODz´²²U¯Õ[í²÷þÔÜ¥«rB1=$`0{e~sp|§zјÌ"Àl"ø”‡œr–Ü„ PY–™ïY–ÙÎeòa"bUÔUŒ½€-mVòqéêí÷#™Hd /i¤Çúûö×Káf¹Ø¦íT>sþíK/¿öCÃÉX|Çpo²/¹cl‚`$#c÷,×뺯VjFr@MÛçn{rÏ ËÔÙ[7x¢ußþ{Æû†<ËE^ƒCѪ4—Kå«Öî,ZaXiØ$` Ê…­›KÓ&õ•¸p ‚ Ùã>Ø»sl¤'•MÅ9á…b[F<=)ùDTÏõ ìÑ#ûí9qäÈc{äû†Nì<úôgy`Ç}™d2šÎž~úÉ©¹D¤ªWÔbŠÖ4òûpª·o‡ªéã½$–墠)ÉZ­Öö™kW•¸òŽÛîHÑxÏX"Íï9üÄÖJ»=ë}pî ;ËåRé†Ó`¥¥¥bq1M7Ú[…öÜúJÍk¤ôÈòâF`ÕïÝ­¥†7æD&ÚpÌÉýW/™ž»ÑvŠbžéz€‹½¢‘ã–íî™zìÁGãBzr/~êø›âæàTî‰'M”`h›MÑÆíMµL57 .³KÍ ‘³^9ræ•7o.Ý2dmvk~äž1%’ìéÝ—»ÿþ{˜KYs±½¶vSOeŸ¼ÿÁáÁቑ©þ‘õŠs{sCìÍÚ-VÚ¨Qøu›B‹!ŒÔ!2… 36kM«àa·UZ/Ôš4¤Çò§¿øÔÜÆf¹Zˆ¥b‘hflbt Ÿw}Š ”"È÷kQUÃP‚Œ·ÃÆüâÄxpïhoÿÐõ÷ç"qšH kVÖ5+ŠŽD ¡Ì3Ïü#åNÙ ¼0ªèš®Ë¾«±¸># €!")2@DTÄéùë1À!ãX]ðÿsõžÁ–Üçyç?v<}rº9ÎÜ™¹€`@AIQ$%Š´,YÒ*Ø’¼åÕFk·V.{eíVÉ¥5m©¨,Q¤LÑ H"Ç™&‡;áætrèÜýOûáÜà­:UçKè/ýÖžç÷$†V,MŒ•a:” ˆ”¦„H†Ã„  •Ò C °t“ Ž!‚˜P¬ .\pÝ4"A  • Y‚X‚(ŒÇÞÐt0i’‚@(9¡"4* @($R)åˆÂ.¤JÒ@HÁÈ£¨€ŠKJ¥ã(9ڬĄ`Ã6)Ñ¡’ªƒô¯÷€0;õQ[¥†À÷§ÞO8kÁƒ‡GÎg5úÝOÕ9pþß•‚j4¾ÿ 5B.½z>L" „ßï̬`FSP$,ô•BCZp²æ¸ QÍ©Ê$îöÉÙÂüÌ’B°T ½Û·Î7­±Òx.›VáN&Ä©9ê½IØ÷„ÄÐïcL4€A ¼°ë+YÏïwwö_}þ…½æ¦7ðéF×KÙ¹Út¡²›¨ ]ÛÚÞ}áå7Ú Zô:ùÑ0{½½•;+)ƒsãKÝ`TS)SC̸Óx)_œtü«[» I?ò̇°*†n€ž¡V~¬2–•Ñscv¾T&ÌÌTçsvÖ¦(åªíd e§41]Îé;·îy½®·ßQÙP‹œâ¸¡ˆ„o¼rý÷¾ø¥—.¾Õo4½¸»½9¼òöå;·¯}çÍ 7ož§8ݹx«×m¶ýÔôqû\× IDAT=im·WW.Ç<Š£#…cÁDj8Q—,êbnra¬TÇE'Ÿ¯šZ±=ì˜sgw¸½Ñÿûg¿ýßùÞ­ÆFâ¥këwß¼òÎúN{kwGD)á¬\-MÔÆŸ|òØl®bg´|±”­æLÚŸXèßi¬­_~çúgºP+M÷û»•\ióΖv%3Cú;·ô|Ϩf%3Dê­4º ¹ìX ã!B íÆ=Ï£ˆ±˜)µÓí«™ù ¦Ñ(Tò{{æŽMUYUYÂóÄ7ÿñÙÆ a9ŧ~ôÓG§Ï.-Uä½ý^ "fªÐ >óÏ>geöš(•qƱ²Ðì¨xê9[³jaZ.dÑÛÛ‚F¼º6\»y³¹{·X=låKa ®_Z5NPwiV$6d4tË4¤¦¥€Ô¤âºišºÇ©ú³ß}Ε­+0%1â2}ûõI‡Z^QµÙi6.Xy{Ls|×)d ¥˜»…b)Œ’0“ÉÒb|{Íï§ÍŽ_.[ÅlµÓîN×8ú½Q¦¾¼»³½=h,õ‹¢ã~ðD˜ÏWf« ½ý¯|å«+W.+«#Y™8 " ˜àTa‘Y¿}·TŽ[›y¾ùÂü3ËÞ:Ž:ÝæKï˜Í9òÇùåj&ái>ï¥ãgÐÕæí7®T§r^»ùzo7áÀÇ·»¯nÁ±­áÍtÝ–ëKáJÝùË?ü²EÙ½»q¼7X1V’˜8­µ+ÂŽ?äùb.®Ôs» úÜ™„9gIÓQÖÉn¬nCÊP’õ¢u<†Ž>iÈÊÜ Z]¬¼½jêhrañâ¹îîÞzé›KhÈ]'Ÿ­‹à.L †ûC69¹¬ÒÄØõ½6êúR³¹ÊœäôñC$-«Fä+š¹ôÎ[ò KâÔȰš-q’ã4΂1‘Ú‰ŠÚùê¤I€b,Sµ½Vš†!àRj4õ#TK «¨1F3jj UÜ»×{D×›­²c.†D@™A…ù骭ãl¦Ì$·ò¹$а®eHNƒ^ÄÂPÁœuJ†¡!_l:šçCb çÔЩ®kD‚ ΄hRIF:PBI „ˆ9/@B(AÄqÌ™P !¨„Qa¨ &Jªkñ˜#©€ah‚G£\ÀQ7‚$ © B…!h˜H ÑA¶ TH%ó¢X ŒÐžBÓ0-ÝÆTb €( ¡’!,€hÄa‡B„€-šFˆÑ’AFA¥€ *@î£F•JH1BïÏ­8p:ðî4P(5>5¾~áÞÁ«'—žBßgIÝ ¯?{éÇ?õ“P3¦N¹»¾²»±™ŸXöýÍñêd¼c ¥<²Mçô±‰AÍb.j,SwãVwÖÉÏÖ •;﬎ښî(É£†‘Égʺ–Y½¶uwsu|±ðC?ÿÃu§jšZ(JJ&ŸT‘ﻑûÇ¿ÿ{1ã T™q²ºå¯¶¯Î?rÆfèH“öÖöÙÙeAõP}©ÏïÝ:zbq¥qE(mf^ß¹ˆ å->h7ËN:³µX¸Þê\1Jp˜DNÖɆóÄw ÚZF±ê¸ÚhG™²¾çwÿô뎠£±Ííöâ“¥zyÊ‹÷ÌC¥Ùòb³±sëÒÎj?7‡Ž=xöÉÚ]ï¿ñoç&㿹°õ?ýú¯¯ß+'“~w ÌY€dŽNO&|Ϻ·– áÐ×½í7.\ŠÛÏŠ¸.N*`i^{53—Ã}= ÉyîåŸýÁrõƒãX‚aH\&cï±?xþFÃ!ÜMb›ä;Ûwœ¹uoÙ¾k½ÆÆä hoÛÀ$§Ïž=túÙ€8Ÿïíöt#"Ù êè‡3ó®r'mÄ¡–ã¨RÎ ƒAÞÌPÛœ./Óôød¥X\ö:kî°+ R"M%W<Õ²†â^Â4IFI§XF&Òý°—K}ýÅßûÕ_ù­¶¾ß‡•´¬@ÐjöË¥¾ò%¯ãeh¾'\J)‚$gêW›idIªÅ02R)"„G¥Vc–Ä  fH…IÄàh¦F3‚”"”ª@B11uKÇ)%db˜ºä x”P)TˆñB¢ˆ(Â(EB€ ¦Œ1lcÈ9€@'$‘A„ FBP8„ƒƒSܨºH$L72D3 Š ÁPb $”Lîlj¤sPŽ[øuŒ”têÝanTÒÀ»aªjDCV 22(I%å}¼–©ƒ­š€H ”€˜(©¤R! %—C¤åÌŠ5 ,ŠÍ[çß~kú‘ã~4äRa€R)Kp®~ñÊK“cmÜ:?wüÁöj[•Ò®oܼ½ôÀ#¿ưbÚ~$@ÕÇgj6½(cÎEàS"cÛ :n¦X-³š©T »8¹¡PŠCˆR!B)(å/þÚ¿°l£&îíOy7.Üûê?þ•zrî_üÿ{el±u÷Ê¿üïÏ|é?ýÁùË VÀÎvˆçªaYýÛßúÙ¿øÓ¿b•s–©U†™ýz͹q}ðñ‡&Í53t°SŸúñüî‹íÞÖv`¸Sœ­›|WH&‘‘Ñ0ÆÓ³ú”µ4wìÜe÷ÄY–_~p¼vrcûˆ3Q1½tÐߺòö06&¦Ž=ýh¹”ÿà!w·sáè©¿òÜÕ凳ý-•ì5✎©ÖôÛ¬“Ý[µCÙc Ç·î핈k)3¶ ˆ Oüã§O¿}gßm‹3xeß?¾PÑ2õŸ«-Ä0¸·µ~÷ꑦ, úœ(¼~N(É}¡¢Èʲ[ q$›‰ %Ñoqö‰ÓOÙ²§&KyIÊy-ohÎ2Ev?nJ*ÅzÜ`«û«ak˜B£åß;v<Ýê»›õwµri£×zM4ŒTÜv4«•gIyv>N‚NÛk¯Ý]|€ßºÅ¼[«{ªÿð‰OÜ\j¡ý\Žlx^ܺò{ì…kïèÊb–u¼<^*`÷ö½ÜɌԲ Õ¨ÕíO¢ g†›©;?_l¬F ÅŸ8l [ YµlŠ|a\¯C,26t×:M#–Ë¢ÍfàÚîîüÂÃ;j°}7ê%„B¥™V š;Ý@7R7JaØ=uúd[l(.·®]=ô©'!­)¦)€mÛ'5 ÓÀ<¤ ™LxlæØÔ±S/_ÿn®rˆ„æÌÜᙥCÈ©ao î„!H©©Srp6ýV+ð3›ÅL¨b; S‚ Šñ3yUýä#O.œ~hjâÔ‹/¿¤CiŽ íüÅë×omè„ c0¾<$ñ¯ÿæÿóþÍ¿"q›˜3J*:ìö¡é¦4›.hêUŠ%-V+™RÞ¢FçfÛó:+“É8A»µ´4§õ‰Â\Ù¨d*¶­–eÕ‚™ŸÍUk“K fe¤ÉÄì‘$ ÍcuòøØÄl>ùøêµkM•—ªÀg2=6w4¥…€³ ã³G*v¶|wß³¦LL‹`›Õ¼R§µ­Ûö¹ëWì 2Jãkwc3ÎÁBìw‡;—omyA; 3Ö¨î….hò¶a¥û ËÖ+åB«Ñ™˜›.k4I#QäF4¶æfl«„£@euž-‘léH§uÓ{s2Ò‡ƒD£@*Hu#lë<€ÎÄý!ÑyÒóX¯]¼ªSúÊ_ÿCgL=¼2X觬Ž@à(S‘(¥ ÈÎÈ$2š©¢8õ›¨/˜Ð¸LÄ (Î9€K¡a r©9še–‚#°0F"‚ Ûù,1,2‘Ž59úÞ(ä `¨ˆ¦TAŠ0ÕäPJ&a*…D„º†F ¥Šsˆ¤‚ `’C)E<I ””%8WRƒAN 0¥™|’J‡a¸i²4eI,¤„„ Þ—O½çe¾Oë÷1È€lô}æç÷®…(HH%©a£g¥‚B(¥Æ‚‰L¦G½¶Ô¨Þßí”òVÁ™5qž ” |— L ÂE tµõ­W´ñña¦çz¾ÒeŽÇÄYϱkbbÓ¸:`)êRIÓÑ ÇxôOWHåæùKE;[>c#˜¢Éñ5ŒPHJaÒŠ^»ò¢Ô” IU®Nûa" ÷fX÷¯^}Þ(å,ÃΔH[×nãH»}ëj±\G¦·ÑèåŒr,ýÃßüy¦B/>¿½Ú¸aÂ#? 3޹Ýå(A™CË3KsG>öøI'_òÃ4J`{O™ÅòTu±³±¡åéCÇUêÆ&€²œ¡ÏÃövÞ¶×VÖ²ÁApüÄì©=ujé>ó£}äßøüSóˇ:­ÑZÖÑ2šmäÄÃÿp¹z ý­í]?Lºý]ÛT$cZ$Ó ½¥G8vmès—µc>tÝEi’"‡Y`*ŽÌ\*Q£JÓ@"0?ý¹_ø±Ï}öÊígßùFûìÓE’ÚY™$æúîžo&T𦦧€‘¦!„Õx"N”8…Pµ;wöñL¥p[ÙA«O3”c—ÒÜÆnãúÅKg–沺=lwïmîîmo-,;RNˆ j¨ÍÃGOXš®eMŽ}è'?ùË?öW®¹·÷ß)g c3ã‡æŽ¯œ¨WsŽQHœ™T],!“œyณËq`h9=gtü¸Zó0/¬¬Î¢0—-f’Ÿ™?[ˆY¨öĤMin|¬&8h^q{zÓ,f¤¹R}8ô©æxŠ#ñÔäL¾P©–Çý¨N‰ßo"ÃÀŠô÷6™h•ÂÜÊên"öۡœç«ù·^þöþþÖçõׯîݼ~é­¹ìQJmd°bMD8¹rÛR€––?&A¤„Jó4Ê…Î ¡¢±4@q!“çè\`âPˆVv±€Ír¦N¦¡‰6ˆF ‰à©À H9„žïFiˆ)¡Ìô†.@ énïsæj:%ºáº=5©”d,LüÈp,–J©„`|”Æ'€T‚bˆeeàˆW5ú @pìÇ@¤ %¥BI¥¨¡¦eM 4z€j4Ÿ-pD“$ ÜKL0D˜ ÉÓô`ËD¨ºïO´@*8⾿¿:¡ûvCµfï¦BHÀ}BÍMù]´„B)Aâä©JÉå2‰t$â—_¸‚»Ù\põr˜ø›Â)ˆ®¯—ÝïßΥ̓Þ5Ö¬,”â¶|æ™ÊmìåzÒéȲsš6óLÎBãßùÚ·Z?ýáÏ4VÚÙ…jgho7ZKGfçEÉžƒf…b'4{ý!"ù á“fŽ©À$Xׄ ­ÄäzÂu@/Ò‹¤Pµ#¶7nœ9ý1–^ÏgÌÀõ Ô [+OÍìïÇÂVg>ô Éã~ÚÏcûÖ /h×ëuåjn¡]¶g†»éÒÓ“á ¬WÉY*)Ó +Õ ì [D€ fÚ˜qJõÉÊ¢fÐÉü¤£¥†£aT/ÍÁô˜Ž¨/(—Mwâ–Û,“¤~·¹m0íå×¾ FÎÉäœq4DÌt•bžs>6>¶»?€XPdÛ$†m²I§iê!ã`{>Ì$D³L©„@˜ 5X˜˜$ü&)@A `ˆÇaY )Å’1©â0&epi†‚ƒIG N®¤B@(eX&J€®‘@ 0ÀB 0€¥ RŒRŒDRÈ4ޱ!¦a @ßËÏ!h™VÛÇišú~`ç¨N5¡OǺiC1:0h¢Þm–àD b„Ð}ÍúÿO5 ÞµàÜïÏ B$¤`\"ˆ¤5úãC^(y!/‘’ß—ý+¥$Pˆ 4MR››Ã¥“e P"‘bF’Ú¹âÞÞÖØ¡%A¶˜ß»sgºV[[½89³àÉ0ê/?´ýVÿörv•µÈç–µlJ¬úi»ÓàÇÛxl˜–—D¥ñÌÊjò{ðûOžú`Êù—×6‘ä{ú±¿ÿë+5mraáË_ú»Í­»13¿ñì÷~øS=zæÄZ³|,5µýÍÛa£=éT—ՋŲ;`ÇÞ¾ôæb‘vÛÝ8™¢f‘|yœ´¼ÁÚV_Q? ±‘â±\¨/üÁóëñ씥׭ W[MÑm¯´z[7b#·7ŒE7 ¾°SMgZ4¼‹Èήÿ )Öîš%Z¼éí÷Kò7ý!L6)ÙÒÉÉã/Ý}h’ܺ¾\ IDAT;ÅÜíÛÛyìv×Ïߨþ¡Ï~øðtFqÀ‡ãÇ'ž:yvëêú½Á¥§û±nÈ Ø° vâ'J%ÂÀ’ÂC¶=è46îí(¡C+&B‘$@JK£˜Qš3t¥Àf•H¸®£$äI8U¡´ñéÉÒúnpïîí³Ö®+Ò¯œXäQ¹`"`B˜ªâD!Úß¼uá?ós'Ï|xíÎ;³³†9žGQ´/‡îG~ç·¾ø'ÿװÀ߽rqPg¿¹·èœ}ýÆs‡2ÏÏNi†få¡®[1ÎÙx¿`Q›˜]lœ¿÷[G¦ œsCA‰ˆº BÌì½® –Ÿ¨°öþT®d:Y§C«SEÉeŽäy`‚¿ò·_½zûõÿû—ÿö¥?ÿN³³’'P8•\äyÔâ,PŠÛiP`!dI£6±|au¯j·µl¶Pq|é-ÏÎ(Äœó@”«Õ„udAS„€™9öúæùŸþ…ÿùßÿë¿L¿~íjoG˜Žœ± f”b×ÍƬ|Eý¸ëûÈÔûÝν{«2EÓó3@*ÇãñuŠu ›@‹ HËP=µXDàC€!„ up€YÂ¥’¹\¹ÓØc,Ñ0P%çJHB„'Œ³TEa#”BÊ$eŒm1ÅTÃ,U@ J%q,R „,áÞ`¨‚”B¥B€0„(¨”ŠIaP S]rJXb ®€”\B¥ÞrŽ:¤÷ ÷E ï3 Þ·;+yPäÔ}‰ BŠ:H¯€è`æudÞ׿2¯ABB F‚VGÁŠœó8‰cb¬¾²ñ%2N±Nô,µ5%FÄ¿RµªQ H™)ç×»B-ÿÌG~8Ÿsvî­¦~øý¯¿[i&o–J•ÎÏé¯ÝÝHq—§i·íæÊÖøâLíò ¢nÖ®-Ÿ<Á¯%øÄ“¹|åÕ_þ? uäÁ°÷ôSg¾öåï]~ûâOþø)_ÒÿõW~isxÉõbÎt‚ƒ8 ©­ÏNŽÇÁÑí©\Ý :ÌÈ/YοþÆöÍN±œ§ît·–—ëÇ8ÝØ.÷6J•ÀŽ ½»‘YÏØšÜÝïÜÔýL¬·÷‡®É&y>Η'÷Û;Ù;ìµC“íc'* iljŠžƒiÀU«ÙQ?qRedq¼Áò…p§]ž n'ǼgžøÀWÿü»¿ù›?sceÿöæ&4ã¸Ë/TSϯf3Ê?ûÿ:/ì·Ô«uÀfÍk£y§>>?57iÊüþ¿?ýLuJß°ŠÔ|]nÐ^WMX°IE¦®Ä”' €a$j–¢vÕݯyêÇ?Doäºýó–=¥:}†Ñ‘¹1Û*þèOÿ“­þâ\>[ž¾{힉edꇧ½þüsvlëe»\J[þÚæJm~"àìßÿö?÷#Ÿ}â3c[kn¥´óähFí®/j³hú™x0øo„Š_®´{›}Ö6ŠYÙhûIÞ R«Xiô½ØsM Ù‚mOìvovíðÔlÃ+Æj*ÞŽç¯Þ´üÕåâñxÐ4èÁÄ€¾³uñîêíÐÓÿðO¿ôäÉÇ^ÿÚ ü|Ý&¦àŒ* ’ª°çáziWêÔÔ…N‹tÇÖl{baÆT´Ú6Æ‚#‹j¯ùƒç_ýúÒáå2©oomýÿôKn`8b·Ù­˜¥ "ˆÃéùC•0‰#Å…†CqÈ6¶¶nÞ½² ž«ˆ1FœAb; Ö(µŒ¸ Á1†L‰D¦P¢”só8뵺PJ(ï…%|–$À4MR!dSM3¤”„âÐeÌyš*H¤:®c€eÌ•Œ0R “Íb z-É™‚#²l$8ù!€4eno ‰ÄJr.„J¥0Æ”j)K ÑÝa˜<åR¤”jqÊ‘´S ä}ÃAYRd…F] ¾ŠÃˆ†¬ÞUu©w“\9'Gºv|€žAð@¯ ÑA5<(#ˆ¼( G#$Š%nr)®^x};ÙVÐ0Fk–¡Â@ J’ˆ‘™ÍG¾ûέKµÃsþp‰¸×Ý­§4… “År>@Çlèm˜øÑ¿ý’‹¿ÌÌ4ÒɱÂXvR5›èÿìï zÉpލ¯üã·ŠŽõÖÕ‹ÛÂAðËß|-J ÐJ~ãßý9FŒe,(i»ÜWYlD(í1 {ý°ÛKcjÜIéM99¯á¾ðµgï Üš™×-»Ù ru-;Ÿf¾ø»_ ãê‡?òù‡ÿ·'=7…HTƧ¾ù_ùÂÏÿØ—ÿÝWµÉÈB×<úè#/¾ùúؼ5•[|íÅç~äóÿTwÑŸ}÷oæ×~¹qýÍ_ÿÕßÿƒ—¾´óêÞZoÅ5ÅK_óÕ—¾õä'~bzêPïî~VÚ°(»Õ«…?ú«/Z…Q¤´IUBv¯7Øò›åRerl¥¼wi0SBT75L‡[¨T-Õ!ªZÔöøØ¼cP¾xvâF €µÔª˜˜!‰¡báÐɽžûèO}zëJ×oß;þÌ#"µ'Æò[ñ…»ßÍæ ª‚¥A,ª“n#mo|ä?§Y”†¬R©1DÊÕâ¥7šÅ=Jdÿ¡S凞œMú‘®CIäÎî>#zY—Ö.ÌÕf‡-žÍšµ•×®Yc¥©#sµ¹‰©Ž&Hw»[Æ‚ÖxP}Ï´Š5l¶ÛX?êÆ2,-Ož»¡ÛNîä<´úåÛy`È8©NYçÎ]à3 :]1'òFÒ¯½߻煃RÅLƒ¦çwšWN<8=luÍMjeßÑòç^{.S~ø(‚¦‘×P¨ô‰<ÌYZNˆÄÌ× ¥”â‰É™G{t0\½|S¶¼noàiŒ‰ÝŸý…Ÿ}áÕççÎñM­1ØËJD0êm#Ï'%#ñÙ³Oz6eq­Zâ‰-žXÔ”#€è!q¨f˜H7 舄‹$%&ñƒH2!óCå ¦“S Iä 4jÆA,˜x¾’1†ºJAU˜74 YJl*Am¨)“ ˆÉe˜Æ–î`¥Ô2U¨ÂÄ“R!K!RH”sH„ˆ£4n¸ÝæÑ3RH¥¤PCˆ5M×­Èó€`$JŒà2I¢Œ™W @)•R ø.ëÈ á¨’JJõ.ÞJÝ'_½ÏW”ë¥ ]úÐA{uƃ,Ô±ö÷ïŒ÷7òB Ù„\"ËÖì\6—Ï*d(á"›ë«ÍÀBÀÝÐ÷û!)x-» dg¾<ûí¾;¹8á'ɤ5RÁ’vßí¬mîmmÝŒA¥(œ×ÍòXƶ3¶aBÁPÛßÞ¼µÒˆýÞ›o 1/ÃÎ’“ǧg§g”@UÓŽÒÁÇ>z$äÎ'?{z<·(”àЄ¥€@P´Óëzd#³XÌNNšÔ›œ¶lcraX|@3¾;<±º·¤RÌs‰¼°gš¦ˆ}d¢Ä+gyÄð×:×¼h{u»ÝÞJ5–/H¿ÏW6^éÜl˜(ÔÆ¹…€»¿w»¹±:{xaw‡:ZRæ÷¬^åSŸ}$qEeÑ\~êP}z FÁñ¥™­†÷á<²4ŠÒ0-Ï—–òKKG>óôÓå47cW‡Ã&ëˆN³á¥±¤ÔØìÉã™ÃÁ 5ÙøR%ö³¡¬_Úî­P"Œö÷šñ Ù†^¬fj…¹Åz¢dyŠêù‚I3ÕZf·ÑáI/ãð§?}Fåx³Ù[yk§uûÂþíuÜÄp76úkë7íŒ!°ùÐ=ñè')A©d u‰±+Ør2……"¦aêÛi±8¥Fsp|ªzèè¬^ÌëÕ:DrEÜ»µzá¯^ÝòÏ]^_óû=Ë4L+S/NÏ,/qËdvaŽ ÃM(—X¤¤OýÈrÚ‘ß«•R¶™ŸšUšåèØÙ£^(œ,ÎWæP,jÇK 6‚!šÎMµ$òÝCba½ŒrÙ™;»N!“*yûNSôÃLil˜ºRÓe” ƒ$’ ‡'xÀ¹qóúÚ…•ÍÖjßÖóÕúdn¡zj¶V!Súܼp鼄°63=Ô÷Â$ŒSΠÚ\ßé'‰’ èTjµBÑØDµ½¿ T’JB¹B2’•YCqhB€•diž9m+„B¯ƒt£’)Zš“Í8I CÉTAJ•TišŒ¤·oèÎôô’`èÄ4fœ#‘°H£& ùÀâÐO9ç‚)MƒI•T@®ÀE>$t¢2M"¢ TŽPîˆq× {»ƒng0èzîÐ÷AèÅžxR1Ž€JDhš¦qx”‘R\ %Ä÷ z½Ñˆ'#ïKÚÁ}¢ŒT÷Ù£@½ƒG“$ŠŒ*›M|W[ú®‰P‘Ìôþ¼ Á}~)8PΘËU"æ~ø1«‹Å¨íR jÐÊB€Ò(—À¥,ÖôÁ`bò‘¸ô•ðÆ›w¬I=bƒÀñ©úïüGæ·“hÁŒ›™ÉŒŽê>tFR<[8¿¶òc§kµBäî¹õo|ïÏþù?ûµ›/›ÕòüÔL?Œ(‡¯ëü;ç¾m–fõd®^ S–XšÄ°±¹¥%Ièù³'ib±aª ŹÀ\e+ÕÍWwŘŸ±KŸýåDQÎЖ×ïlø;Íõ®v|é`òØ:'ó'»‡6Ô*̘Ù)B7šÕZrZ“e¨PµnE!DYfz]Ó›ÞªÁú½Å'ó,¶|5%n‡œëáþžúEEI³Õªšc8F^ÈÌ2xý¹ÿðáë—‘1(› `lnoµR£u«—'&Û~—‡ ò‘ŸÆB†¡$¾wgeijŠfæÎ¿ò_fœ°Âì!œ"W4;;””•«¨Ø_mµa!ïí žú¥_ܼڹ²ýÖ\ñ8ÃÙùéÉ®Hó4i[2$*Ze¢"âYE($À÷}M÷c+wsåVУºÅü(¸Nµæöö_=ýñvûÝq{1o–·V7÷‡ •¯9À¸ÕKgÊ“AªÏ̃âü’Ek¤0‰`(‘À–—ØÛ;{z£Ñ =¾¿y]/Õ³zéöùÛ[¸ˆÎ½úÆýüÇq¬Plå K¹ii3Ó‡¯ž¿áe6ƒMMxAP«"ÂNšïÞjûÚ`oc¡^+…cå ¿56;Y6æ_n|…¥]Mθ;í0"’IC¡"ÆFšU/¾üõon“þ•±‰å²Ú.ýý7¿ØÍôãæ ¡!xíò ½"#ñH¡ZHPrjîˆ2…bÜÉ‚jT'TCÐÔQäRD3:æ\a¢È€þ0ö’XI&¡¦‚땼ƒæ–®»0xQ`ˆûÃAΈLÇF4 HÉ¢ØUju9D0ŠbÆD”D¨( R—)É|/Àº¾uç&1œ\®¤¾ã˜”R$¹BÀ…B¦ S( Ä€'[Ĉ( !RBE¤Dl+Óöš¾7DHC„`Läˆz,¥Ò29¨R%!€ ¡B* GWH1Rá— @ÝG*€”R)t¿‚Rrî#f0~r4=B ¤"£²tÀ”÷áZëùõÁlyЭÌ—ïV+A§ãFñ° êsc¹X=’Ð\B­=]êàÉùL:”BƒŽ2?ù9­»ßýíßþ­´¿Ù¸ƒÁvA’õ)ûÆÏh5‚4"0ó!óz‹SQß•ÎäpxËÎÍ»Ôïn^¸úÎéÃS)ÞÏ•²XH³˜k1£ßïΜ>qíÚ¿¡TÓ†åÑJv~uóîÞÕs¿þ…OèÖü0ú¶ÒÙ˜aŸ8v¢× &Šå+c)ÍiƒÁ¾±3¸¾Ño>YCÛטJQ®"=ô†ž~Š%B¶V›Xœž©Wmý¹ï5în÷]Ûïy¤õ†C0ÜËfô|A'™ñ¤ nÞ~#Oçv[»—wn<°ôPsSǃ¬1øÀÇÏ<ûMSÓb¯ëÖ«SšéH¥¨…¢\__Y8u¶š«%>a éB t·ºó‹³†4xd+E ~úL);ÍМµnzdauÛ1x¾µ:(ðüx¹Þnû½­ÕíWî|ÿìãg¬LŒÂ|â‹ÙJ¹2¨Xy¬¶ïûÙ¬ÍÐÔ3Ÿ~$|§ßÃØÐ±ádX7(–Æ9·rí¥ï}m¦üX×½[ŸªMÌ/ím<|æäµýýÁV·‘mAGT*¥ñ™Ù—¾ó<6@ê¡Âx5éúZdïïû¸žÉ×Mk$=KÑTLˆÐ7öo.<|hó¥ð…»ßÿÉC_šô'^»yCW=“j-/.šp¿mߎ—r“SµOÿêÀ|çÂ÷ƒ` ù)F¤Ùß›2‡iZ+)€„dáa·;l KyÚ÷{{{­8ô•`BHÃ&–]aÁÍl!S™œ„ȼ¥¶ÒCÝp„BTǹ‚Ç`ba~Ðw7_q %–&@Ê8 þ?¶Þ3Jóô,ó{Ò?‡7§Ê¹:§éžžž ÑŒf xl0°²ÌAð.>¶ñ†{|̂ᶵfÖ/,«€`’FšÑ„žž™Ó±ª»º+‡·êÍ韟äou Ÿãoõá­Sï—ºÏý\÷uý®á•0].ïl¯«ºÞi´co«vy’”J9Ä#„äœ%qËHˆ+:!±.€Ä€ÍS¬)º©Y†aöaà†àa¨ZH™PE±æ@Ä~èCLFA©äŒK ‡I< ×È,XRJ!?ÛþÚïPÊ:´À?AÈ !xÌ C†–ÃbÕazX÷,…€»,X}öR ¤ŒF5ŒžÿÑÏ^zîs”!F(›©¸¹j^ï“Jnc`f­Êxeåá½Oýè+A—R?¡01JJ“uâÏ¡d(°¡gÊVU 9Y·Ý¯5ë­(Lü>Á¶ÎN=m+f;¶Ñ:ðÏ>•QòhKµxUƒ„yát'l%lpú¨µ»ñS‚˜ž°ÐÈÈâ´ êt{ÕAþ@ºv©Ýšƒ:áZÔë¦ÓïÔBF˜LŒDƒ ЈdÜ0Õ$ð´ ¹ö­÷º­íHt ““,´¬"˜>v$"¢‘‰0OâXÒ垣Š«P NÍIWI:·ùæúfÊJi†iN«w`mùÃÛa«žÉNÊP†ÞnXÌÖF:‡aF· ¢¥³‡ B!gÁÎq»ÕȪZ¿åñN¨ °³[ï„ÁÁÊîúúý—^,LgŸ^¼uíò­·ß:-[ÕãØ7Ó.&/hgFÊaH@\Œ3Á˜€(*Â2•)°0î5h¹™¬ªЦeŠåÊè4 ©Š Á„Ŵ߬{^Gñ8– §4Nü^7HŠB8—ò°õA(HáŒ7 F#M!!L0s.¸H’DÖw„¡‚USJY‚`„‰Â… QR …)%<¼éIxøjÃ7Ü“÷Ÿüÿ78ÈÇ·?2œeòð1x(pÉC\Öo3Œ ýà5)…”>þ «Úìè‘•Õ*àI”Ä"¤`âìâÙDíPAÔäa»=€½Á~m{üé¼È›˜;—wÇÇ ³õêþ€ Ÿ÷TXb”fl½K;‰Ð1§@Upˆ€Ê ‚ J©v± ì3ûþøk‚7~íü?êôhÁÍ|úÒ§ÂV C'e:Å2JeŽôû> ºT†Qg@ Ûa)Õ5R$Ûëõâ Gïµ[HÏ EMmnÔ—n_žšš“  Ôj·?º|×u¨šË„Õ¶aºí¬l ‡ aiWuʳ*(¸ÙLuý¡JÑÝþ`F™äzUr~®O:Õ%Bá"¤`K¢0”˜F!Ãq/޼çˆ|û;o¡ìqÐð3lõÑæH>_­ÖÔö‡]ê÷ÖÚƒ>‹ý è÷VcÿhŸ¨¦€^Èa£Vó'&:¤z$ub¿Ý‡ÔOºPÂtÛ£iÃ2ŒA(ó½öR€N-JyŸ+O-Ì@ô™/¾|wí½O<ÿ|BàVËwä~fÄdrŽz>Üß©=5zšQ\ÝÛ‰;>Q´ˆ±»GûýÞèh¡ˆ ˜×¬f¦ô˜‰l¥¼üúe8…d”ÎTSvÛŒù”%]®#(}Âl Žäævk®ÔÉå ÇŽŸ›œ9Ñ{°×}Ÿ5k½'°O{ÔëI)‰n¥³:Né+—w¿«)%)NqŒN\Ó¡n¦%øèÓ xûý.²”Ó3yˆ66úÆ%[©L±0Æ%òºÅ‘cÇ­T@© (J,hШ +H1 @4«<ë~,^¾têÒgÏíJ ‘‰ßú!3ˆêæxæ…ï‡jšA¢›Y-¦¨îØ_«A‰€¥aMÞYº–÷v¯vkõÑñŠå䲕ŒÇÕ8†ª®ªŠîs_(IìnÈ[ÂmÓq€°Ê–ŒŠ„+ÂBò@H¡¹Öˆ6m¥òq­lVp¦i*†Š™øBŒ!"Üë¶©¤AèólIùƒAìõ`*Ö†×5( ç#&1gB …Àñ˜Sƺžç:H…3ªjªbÛDS5U³M“‚RÓ!J¹ÊepXËüÉÆÃÝHH „€ò ftÊçèq7Îc!Jp(ºéYp˜@„H$O®¡ÍT"GúG‡  RAß¹òæv­c#¡Ía!µ”ÀtTËq!ÀðЗ <¦¡ï÷‚îhaLñèÌ‘^48{ìæQÑÊÚzƄټSA"š;1eÊt.ïèzZT•°(ð°„‘ï7~£/RYòùŸû/Ón )¦- ¥Lj¦;^F1H)ò…¬n¨Š5F!ÔuóîÆ <6PÒo6[;­NÆ&1{­îo}GªÂTtÊ’à?üþ/Qãn×£Ð3 ééB)Ѹ$1 E’(Dko×kÛwÒ¶‚()¹'N<=h‘ɧ²h¡Ü£Ær95Dq6V,}*7=3ºè ³?òJ¿Óˆ»çþheLªa*å†^rñcó'Î9yþ©ØKÂêz¹ÖW÷ó'Ñù Ïê¶ÙŒÛ^71]Û®d:^”µRšŽƒXªP„ÉàÕO}nbö˜­8Ì ‚ PrãͺêÙ3ó?ö§.ž]Leìó§Ûn†ÒïÎHjÔ-™ùÊÿÉ÷Ò«Ÿypo‰R)Dxwkj~ô¹M•¬Œe¹)*1d!¼íÇšb©Dµ°“ÊÃ$Š.¸»fÂe¶dv ãØÉ¦ý®—ÏÚvZO;–éØùœ›km4mS6ÙÎ~³ßÚÝ6mòü«¯NOÌæ+ãÛ.™¤«ËÅ–†›U“>TôTÆÊLLÌŽË”æâ~kggÐÝã”J *S£>íc#óìÂì~£njºmk< £˜&Iìèå88è{MÌkp (¸R˜/ξüʧœô¸ª©Šiši#]ÎEQØho«šÇâäÓ±iŒ’ ZݳÏ>÷Ëÿø ‹'^™?6=·¸pò”cd ʱc§\Íœ?ýÜ+—¦Û®î!®ðƃXM#Cq±Pæ„FJSµæ‰KgÇGޤˆ’0øý~}¯Û¬u¢Øv,& ˜b*ºi(pNV JgÒqÄ4( 6ˆ¢èªª©z dÌÀDÑM.„ä¼Ûk½áŒKH¦B‰g "’2‰b•þ»3ÁšH 5Ý !Œ$F‚s„ g@!I ˆS)—'‰ª*¢8‰ä†aꆥ[¶í¤ DD!I”„„”’(HÁœqÁ9ç©*D<Žõ‡œ¡ ÿ±³ö¥‚C¼Ä?lŸ8ÄŒJ¤œ3!¤ø¤> ÀÐx|RU(¡Rr!ŸwR ¹@ŒÏ!£ú¯ûÞùëÿ„`2tM , $`˜ú“HÀ¹@ŒNŒŒ¤óqGš†IFÇÇGJEk=buÚXBßÁ*AHÐ\±heõ±Ñ©J6t¬RIWT';¦E¢º]ýÙ×~2Í dèÜ)c^·Æ¥Á±ÅɽZµÚ¶íë¥ IDAT혮¶U=BDûÑlelkcgŸÕV«@ãY»øÞ3§_ä1rLåÊÛÿæw¿ügüï¿ûΟ~ù¿üÁ ÛBVF7•Õ3WWۉ׈‰?7w2%‰¡k2Ñt0ÞäÔ³4U)êoþý‡È„Ñ ˆÂæé£'Nõ(Ú|´“„Äóû×ïß05gµBŶ4)»›½ °‘c8R:§ßÿöÝÞàaF±tâüýw¯T2öêÃê~/!¡T¤¦æÍÀ?ÐÍO/ØŒcMMgò*¹)]ÕXÀëýƒÄ¯¼õÁvu{{wý~m/q"¢&ãGÏ$^xôhþ“¯¾xé•Kyeltt<åÂôÌÆÃj³ÑÎé)UÄ…ôèìè܃å¥w¿óîÎÆÚ»¾ñíïsëöúƒå7ö–—ï-m5¾jv|ÿZ­³»yçÁÝÄ““vÔj`d}ìù‹JD»Í¥¨<¼»ñáåëWãŒmÜ»Ý÷’Fu/RêèBzêêÍ¥ƒ]¯ßK"$ý°“©”¨‚ü ›A϶›K–"‚±Ä]¶¯ê΀vÖ;‘R[P!hä@…]Î’íû¡ øi«ª¦`ÀØxfútt¤&ö‚ÈêZÜc3§Æ~ìG^Ö3i±B° T(¼Úi¶67 T.˜ +jNsÓþ š2lEŠêÁª¦šHA‰Ïê†åÄ¡tˤpbqþÈbeb±¢ŽxÍ@á-éPlº7n¯¶½ý€3‰M,3S êQ¸)µ„óŒãXDg,l÷=Ö 4Œ!ˆ‰-©a‰1‚…b1¦H° ºÖñ<RT¬ ¤i*• ¡<Œ.(£ ‰j@€,U—B†¾GAè{á`ÐëôõVâyQ# ¦+èºêºŽI‚%@\ Î!†Šj"!Á*"Ý13™²ª*¶c+X¡Œk*vÒYÓ°uÝ´L›)&шà\Ыªªé˜(ˆq„œ`‚6Ê#ù8—‡K@ÉWH$Ÿ|à0# ŸàfÏ%Â%àBA ¤Ãh3D„”ðáo !H"4ÄÁÀ„àØ•’ͧ ÎçšaH ñÄ1!œÒÄ÷t‡`$4Uõ»ééÓ{+=-¼t¬œu;çÙ‚pC M ‡˜XC)e«y[S'Æ×× Ûq¦ÚI†c~ç@2W„é¸ TÓÉ~¦‚ª>_¹ñ(õ\*´!ÔÙ`ÀPˆq¶»¨†4S„r¿û‡jÂV_5 ¬¥MÜ ã½f{©Ó¹ûQuàïV,€¹èy, B=Ó83z‘ïÖC¡û[»b¶Õ_íBZ–)ÓéAœÈ¨Ûj?PÁ)ÀeÉ[Y¿3õt»£ýÁ~®07¨·#åÌþ^ÒÜI’Q9¡BêÍU4CÑ\˜îwº “å0ÞlyñÉó³í{öØy޾w½;†EQP( ˆ¢lßWŠÙüø­kËGf&¶vºF$»]f¥E‹Ò«WïþÒ—~‘@¸º»òæ_£éwÓlðÓÖ£û´¡V&ee¢0{|ªabÀ­;kû{K6(Tw)»P3ôúóNÎOM/N,lÕ–ÝÔ\ÊšJeF.Τon¿A/;1qéÕ—Ó™nAŸn”@áûÞœˆ# gK£BŠ Ý:wì—Ô³$Dà`u½\.ä‹ù”n}À©¶»U›]L¥ËÍ´ 8ÇzëQŠ@ÇÀAàëSMq;‘&›{â|[#ç'N+©Œ„ÄJ•"3ê¥SÙ{[wŸzùÓ)ÇØ’(ä¡‚…(ô;拤÷gÜRY꺭ÝÿàîN¼õ‰=j.gT!—ƒHuõ4”BˆÔ[ï½{áåϘ9Òo…‰¿SšpW·7ÛKÉj´>RZÐÓ&@HAÒ)fÓÈ>qñpq¤Æqõ=×55Ÿ1²ÿõ/þòƃïGqâ÷›)3{ìÜÑ…ãù‘#\ǹøüs³#Kß{c}õfñƒµ{7®¼ùÑË­¼w烇Û{VÝj·7¸—øh£ÛÞ¯y;µû¼ýk÷)úØÐ/ŸP¿Ù^´ ¶³¹‡³2ìkª§nû{@‘‹Å™^X;ØoȨ¯XÝØ Û¬»ƒ¤‰úÎÞÃÐ÷ZÄ()ä@ÂP‰Ç‹3­ã?Qo܃ )q8š5t%¦@–N”Ò: ±*#Ôêc¤ÑX|f¦'Z¶‘wúåÅ/ÿËÿø/ÿçÿå;ù—õÝub¹Í/|&3å6QNÇýž§s1Z9Ô»…Œ+gp¹4{çÞ ¡&@bÔµÝúÞü±#¦ªLNÏý8¨Çú ¥D ,­Ðîûù¢ÕÚé°n"„0|ÒÈNOOm7vÆÆ'¶ö÷î.ßm×vj͇«ÕÕÕõ7o €8„úà ?iGA}°Ã‘ÆFªßKn|põK¿þüÿý·ßüØý”"%òŽj5R €j¶\<Ø©–íSínmJã{å\Y[´³+™‡——.õ_àÝ0¤'ÏZ?ýÚŒ‘q5ìµ;–z³[=W>yË}³U{ädNï7; ì…LÐï)ðzý‚›Š8µLŒÏ¬Ô¾÷ú¿ü…_U².ï%–$®ÔÛpÏg¢2ÎÐþX9ëZÚÉ(ªÃˆ“1ó£ë˦Å=¼ueóÃù“Gk^§³Óh3$…¹ãDJw瀆 ¾z°Ý ¤z`•/š|êãŸî¶¤u§sÍÌf¢žvê|^æô‰\Tï¶ fÅ1ÅÀˆ†QËdÄΫª¶±¾Ýl´î_ÿà½[K–fh.ôÙÊÖÚë—ƒDyjarljáRãcåÒâ¯ü·¿ôåõ;W^ÿڣܑ…]׿õú»µÝbeÞ aÆ2oöÄB«ÜùÖç^ó ÷ÂÖŽ§€ˆñƒú²ÃñúîªòA/3y!ªuÝÙ±¨l ’Œtk~¬üŸþ* dé©Ç^859]žÔUGw÷xr¼2ÿý+ßsç|í p|"o>&1–€"_ùwø­þñ±Žxpÿ–s÷ú{º£ýÏ¿F{‰¢78(®.­ ßšÔ9”XJwÔ,Nfïݤ P®¼ûÍŸúù_QR]n|´tëÃËŸûÙÏõ¹Ýï®.Y¬U“NµŸžNºA·l-쉪³7’*ùH³53­#”RHlÅ™Âô½G÷ÇæMÕõ“ý±©…µ·¿ ˆ@ûýV’L:’°c©†ÎÄZccLW»µÍf³í'íÌDšpÍkËN£¦ÌL¯¯Ü(†Ë¼`4_y´·»úkŸýüÜÂ Š’û+ËÇœ´rcBjR°V»{ûVÚH•@ -Ë@qB«P=ìÕת­Ænà%îÁÄäX&¥ú%Í*†ƒ ±4ŠªVœ™Ò‰sP¯²@pÑVʦ¸)HsTSõŠĵ&AÆh¶¥ëŒO5Æ÷¯\ûf>5Mx¢é6Bj¬«>íŸúøì‡\ !è ¬Zù\.Š´A½)PL¦PßÈânV«-9hŸ>>é~F¨ÅÔ´n’‘DÔ™0_Ò&·Z×~ìç~aÕ•ö{ï|¯0aöZ¡2NWÆÒÝzOêb…rà>wê).ÔÁîþ7þ毤ÞÜ6÷òÇÌ­GîÙE÷ò }|d–øÔ¨«t§¦^xøÞú¿»3ÀY‡àL88mç úQ›Fí”S2‘žÉfÃ:UF“ |ä+_ûÕëwßÛ¾»o›´8Y¢Ík<ô´´Ê±Y. ³Ûé,Õ.¿ûí.~ü쥿úÚåÏþüËÿçïüÅØüÝßÿý–ó']ÃÔãî I7ö©·ðBɱííƒ=¯l˜h©òþê•ÄšI:½˜¤tIL'[;ˆzµý€!Ž3ÙR¿+R¥¢nª _³s­¢~0}v~«»ý°º>¥«ùñCcÿþÚ¹“¹^×·0éìï‚R¥¶¹™Ïðw^¿ÊÒÚF<ðÁÊÞCýÞå?ÉÎçY'ä¶9ÑöÂbäm騏~õê'Ÿ¯ìT·Õb‘s—Awß¹³65u|´”}ñü¹·ÞùÛ•¥HŒîÔV#Óâ¼m»© ,§6÷íøˆš±íC‰x,+«¸ç÷°L½íû?ñs¿7où&Ï9q9“f¦Q°ó8‹ÌJ ¸R³ BÝýÖ­›7®|ëF ·½¾uÐm|ñ ÿY«¡ŒH6óhç VœÈ"L8A»qôÂl.é$ :)hD… œq) Œœ G³Èã¥AÓuF $Xs‰ƒ³šª!9åQA°ç&i çS‘…)Äa²@0ÄŸC',އåîH$O˜!\ .%œÅ ¥”Bɇ¢³aš‡û (‚Kˆ‡ÅÃL Nº$æ à –BH!£0Ô5S)ŒYœBäÐFõ¸~v¤ŠÇ7C“ûc³û“ËÃì3€PJ1t0 H!„ C„Œä y^` B (Â"GxÒV(¥ç×Jcs*UiâG î7Z?¼y+H¢ù…QUͤ'ç¡×o78w;Û‚,›—À »ÍÙ™1]uƒ ¶Õl—uU=­@f¥í¬3fÛñwko†cx"–¡4R€IÍ2ýx÷Xé) ½hQÌb±˜O % ,*ÃíÝ­ýÐo ‘ ô”•-f¬\,u­×ö ™ÑûÛ·ºÑÈØ(©o%q’ô1ÅÍ@’JݹÑ\gÏ M"rýòÛÇΟ }=†bƽ^Ûvsi5;sª"»ÐUSíFûäù#Wï½ÓîíðTÚÖÙô‰ÑÕ••?ùã¿ô‚Zi.“1 ã͈¸ts©YûÒþk)˜Î¦Ý®p”vì¾0T_Éd#K‹O^zñ›ïþÝÔq°šêZk{Œ(˜fó¥íÞοû×_AD^]¹‹{R˜Ô²t-…9•I"âR—$â3*©F ö(á‡Kܺ»úê+·NÎÎÞÍÌMú«[Ͻô¢‘—N©¨%§ü3œïü‹…ÊNíÑ1å¹òtÆQ…E±í0ÝJ¿-N8QÊzzbª¶E-3QÈ0ž-ÏÕªwy÷Hi|*Ý¥Àˆïßݬ՛–j¯-¯P«eF Õzÿ£«Ž½¿ûúߌ¦Òܹü3ÿè ^óàþÃýöÞ¦S­õÂt‘óm+0³©Â¸)É­ôhùïÿýWoß\Û];˜›. z^avâⳟ ‚AN£Z?ˆÒ“Ù©é‘rùØ·7Ö󱉲£ËùÐTFæTi¶ ¼¨Ñ‰¼nèõR£#ùöÃ$ñ”‘z¤÷cÔéú&´ÚÉž’¨ÝÎ+€0ˆ qʧ+7ï>XÌ•rùù‘ñ‰q­4â¨<"!Pls”))Ǭ]mžü±‹OŸ}ùÁî†TQ2SMH%ÀCߣ«[‘B­T^ÓÍá‘8Ö$ ˜dJùZ;Ý÷kq<Á1!J0ÖÌ ‘"û±áhšn* $þÄ ’&ìÐ\>ì~†IÁѸàqqÉÈPbÂ! !“&DB2‘Œ„HŠá…nxþBRJg@H(¥!¤HPŠÃ¥J %RÊáhãBˆ!oÈa¢ ì‡*¼<ܶ†Ée2„ˆ"€‰¥ôƒ°3Ö&š½FAü¤u…0 #Sžt2®¯n”Ôüѱ³î‹¶nêÚæíÛWˆ`W{ƒ^}äĉJ*YŠAÆâõlÊ5Ño5"uÅÖ©©ã­VG©=¢Ë”“")H½Gëû†¡@ …Z)ÜïËÞnŸí“«)SV’ð+ïýí™SÏ+P%q™ªˆ©®£–ß1;“+І¡(¤ãulËØª›sGH.›ÉN&7¯•ìòíþõËïÞ2ÒŒ)¥hsª¢¢Ö~ª$=?Jçˆé¤­nó{Wî™=ï •Ö‹»j]×éìõª[o‡j´WëÇÐK¼t»z¯Öܯ¤êõ¶!sš&¦” 6úÄÃ:Xß]S#é5k ÷ðoß+í[ÖÓ¤zZ@îû¯¿¹Õ]³J™Â¸º: £Ïšf½ñÎï°µS¯ow¡ÑQ4Ç2˜‡¤”QÌX4ò¡–m·û£Y ½žx£9§¾YЧ™šhÅï¿þú³§K9çaóÑÌÂyuVvºøþÞéÇ7w÷Fžvö<ƒ¡˜GSGÇ×—díòÃÛfÏŽÈ$©îîÞݼ÷\婤[ÝÞ÷h!‚Ll§œKc)L¬…Ìlya¾/._½1ž2ùs?³v3ô^öleÒË jsÄP.œ™¿l==uñØS<ö”Löó§“Äbš ãlÂìïÂòú€ÛîAl½<žÞ®íÍŽNÔÔ«ܾîPOŒñP=öÒÌÅïWW€„œ ¯­oD¯MO•g6БãÑ:UY¹R´žˆŽ¦D©lªE›é¬†-5fÁÍÛïsCˆð—~ãg,àöM_ú¥TÑR«½þfÆšQPB…P<®é°¹ÿùúÂØ±+ùTYc>dqªŸ&ÄD* CÏH§3å rwC%:†ŠiºóÇ+B‹ ^‚xÎrë À¥„®éÙ¦ƒ¡”R&}ªjš„ jeLI™“Î K\ðøGÏlušQÒs5—FLU­(Š,K‡C FÀÃö>Dœsˆ„‚K6,w@PŒ5  âøÐ"àJ äBp&i©„Dq¢I.‡RT2¤ãI ¡XB!%ÆÄó#!%gTÉ…PÆa¥Ë˜„’ƒÃ bhŽ@ •´Ç¬ÃuK<Á_‰Ç‰Â¡Kë°¢zøóðð7äÁ£¡wëÐq wÎ $"†íCž2Šf膡Àu2¶¥ŒN¦ò…Îÿü—þ±Mòk[·hì3žíÖÝ»w¶V7#I‘¹BŽw›¢ïÝ¿ñ‘®"G3 i©‰U(hBH líµh­Ö[¶×©‚ºÝ â"Ø÷)!CÞ<„XÂŽéô̵åµF·C”d²xFƒ&òvþí?¸ºñp (T&š¡ØVvd 7: ñýkoŒç¯}÷΃·V …Ôn¯nh‚ @4ŒtŒ~tPßÛ¥€©¥µŒ´Íû+êf'²r7·TZ„Yʸ=:ïtáGž>3š>…¤á()…A‚·o,Ï”KH2ÊÃ8IŽ›ûñÿ40³¬ãíÞÿ.r'3O_8ó©Ï]ü'_þ§gç?;øñã‹×/Ž¿ðò‹?räÕîÁôÜÔ÷ÞyƒŠþw¾ÿáÕj­oh1—‚‡€ÅI·;¸téä¹óO³/å³S טLDÂ&+#=.M"5 ¦¨ÀYçþGËå£ÊOýÐO¯ÝÛ.Ÿ˜œ¬L}úµÏ?õâ§/½øÔñÅŠv%HŒÝ;[·o¯``æ³ÖéŽ1¦Ù)-=:=>=c¹šˆ=®jJŽút¤\ì´h³ÞntjíöbºdBÇPW¢ý­µå‡+œE͵Õê–Ôrµ•ZX呲±µÇ‰bR#ã“… ôÕ¿øMÝl,ÎçÆ&§uÍOO`3:sêL¿å³©ýƒ¸ºUg’'yýma6ˆJÙô›o|ûúöÍ~£†Y†Áé G~ýüb¥¸:ÜÆã KFg,7]a•˜Æ½û›z˜ÑuÔ gÑx;º·| ûµ\Nßz¸}ûÊ-m^$A;‚Åv&… aÔàR2ƒfÍ8Îꣷºr_‘ÊÔVSªE1ØÚ«¦€ìV·÷îYfR,«œs¨Ø8£ôû”ð`ljà\×`Äu.™”€R TÅÌæÖ¯-õ  ¡b'Q¤ª ô©§/izJ.é¨Å>ó‰£sÏŽT‚VüДS–¨º) )†ÉaΣ çŒsš$”3Á8—‚s.̘d8†`„L0\N)ãѠχAA„¦(Îc”& M¢A”Ä^èy¥q”„€(‰Ã0üPÆ”KÀã0‰BÇIÄQL“X&¥Ò†åÏÃ; ð!—F>I¯¤ IDAT×<;H“@J ü0(Ä028Ľ!$r’kŸ¥”ð0€1#©Éôƒ[v5361®@ $€º¥ßÝÙzç½Ë†9ñ _øÑBn1Šõöƒåå¥(ÉÍg  5qFlŸÝó`vÄu­‰ñÜÒ‡}oª[p‹€2P· -Êk»ÐÒG“3s;ÍÖˆ’Nºƒˆc¿+{}¯RTž·´ò(/x§Rµ¬l{¯4š†å3ÚÇÚT˜ ’Œù€hŽó~Ò8vüÈÕÍﶘ ›·©ê˜÷±Æý0?i3Ñu X(b¼žT/-ž[\XüÊÒŸŸž™Ò¸h4ZFnêÎÕ×?ÿÚ¯XÜxxïšÌ¦»<¡õ“/ž+Œ”öö2 $Q,Ó ÖK"d·[ëy“±À“§&O}íÛY93ú§¿ùÍÝK17›·:Kë²· –—÷›Y·[^2p<ð»¿ý›o¾ñN׿œÑ¼Å\iksÍ%Pd³€Ðµ[ýw¶ï¾öòg\Ãÿê[ŽV²5&aÔ©mEX1bU) Á 3ñ oPóÛ¯ýS?úó}¿Úom*Šóàîíëý7§NüÝøÓØAZ"ÙŸùXóà#DÇÌr…`Õ*ŽG•M–ͶÒ/ÎOx;~y1ó4¢ ¯o‹¶±Ð« ¶¶ßžÌͧ¶ó‹ã©¥m «¨bžö…+×®ê'>çsïÎwÞͧL{Nf siƒÙñ *vHÉXÌ>ýŒþ̶׹òžü_ëŸÿÇû§ Qä‡õNQ`ÞUýz`‹K»Š¢……\ưuÐî )gÊ–‘Q-|åÝ×Çó§qUÙÇõ¯ÝI±ä‘W¯fÆÌj£~L´ŠcG-U-dÓg^<ú‰ŸyíÃo|¿|Ô)NdÛÓB©4Òãl¯±/êՙ₾‚ JŸÐ^xgWÔÁä¾õ;¯~é%S° 3r›Kîä²Xqu\ã,1ø‰×~ýõ¾ ovÖG¦æû»{¨ž.ޤ2Æ‚°‡˜9TpÚö p¢i=¿+hD“(Žº[à2E)D)Æ*&ªE£Ð „AgG+˜(Œ FˆqÄÐ8Ž"§òyÎ8CLB$3; ÀÕµ(*„A•(R"!¤”PrÞm7ílÞÍguÃf4FšI0bX’øa ˆE¡©K%¢‰Jä#($Ã&~„°'¸€°a‰4Æcˆ„ aÃü CÀ(„J!!Hq…b±B’„RDð • ¤Bü à\ÀÃS!<ܽœ „  â˜ú‰0©7`pÆ„”¡$I°äÄ,oóøÉŒÙ"[©Lß ùþÞoý÷ðO×6×ç,óD DYû΃õh%ȤRаÐxÈⳓ£»Íí|6%±p,2¨…»»µÂ] ¥÷6¶BÚ5+ÁÇfÜÅé&¼T.Íê{Vºt}i÷Ôñ³gNLíôvUM ;Ks1Ɔe5;­±¶‰îÜ'žÛ[ÓÕF:4J„ÉBž²õ˜zGÆg×ýë 33wÃÉùò‘#¥¥7ÞœÎ5—šÓ•‘vg37á¢Æ…ýƒ}›ùÊX¢'§ŽY†°¹tÔÅd˜ŠH€FfMwn¼q-¹ÌÞª klúLvþÈ3Ÿú©÷o¾õ+ÿÃò#åêr­¯¯µ Xbý“/]xﯻù\Ïûg¿þÏïß|ÿý•…ñŒ”;QCOé¾Bžm4`ÿ ]Uö¦KSA³ß±çŸÙ¾uTTÜfyµGgÇK2¶k@í’ÀÌhqéÞÆX. ëàÁÀUkñÞÆ£ý²Awkt}uoáäôÍ7O Î^üØõ¿»FЬÚnO–žÝîïqf&ò3j´“I7Ñ¥E”¥»W £q.U™¨¨¯ûoÕøæµå­Í‡ßEìÝëß½ñ~³ ðõº~2_/LûqÛÛê—t·4¾…½÷Ý?úoþ«O#wf°Ÿ,žétw®¬¼wþÔ‘p:=™yù©×z¿wzñYªýöæHÓݰ _~î¼N Â^§­ZîÙç>ÉhrõÖ­…\žíSèºv>»¾Öþµ/ž1Š *ƒ±?¨Çƒ,OǪų–y@ÔBîù°Ÿv2AûŒÃWC>ˆ¹-%Â@%)\˜:~ôÖµû³ÏONæXœÎ.IQÒØÛ Ù[B5â ÓAH+áÉ©3FÁ9zìÅv·ž)dй‰6ãj·öVƒëØ#¥Éý•ÚµËßVÒ 1ŒÓ'Ą̃m:‚S×ÈôÁÕK?œÀÖ-½25çXeÕª 4] B/ëfÇ-F!V”c,…ÀšFs/•+¨Š¦ºD0+kN ¼˜&žBˆDÐtSª“bœ!„0BÓ´‘H€ 0ŠE¾0‚…U³„ªH"&‘à"ô|ˆ‘ `ßï¥lc05Ö†)„¤Œ‚¨ºâG”‚¾a$@ª†A0@b« Óa˜„ôXúàð'„’pÎ%„hÖF‡ñ'u;HÎ%ÀXõ2tH£@9P&ØH:¯k ­Í6ãBDI?<;7·ºÜ 8•ŒK!N^8ÿÅö«£Ù“[ñ&akªf™õžgë0F  j«ºñɳ/·ö»ØõL×môö£ØDq’¨”B3jx½ùözëÌ{Z¬›2sQ†*Vc«ìä¹Sï]¹—ø=@ «~ÌÂÄÿ/~ê—CܺŠEtåäԙ忿æÃÞÞ~},K³v*ˆ”û*U!JjìPȯÞÛ²‰™uûú}œF®]ôF_ö*8SÎNþñ¿ý­‹µã'Ž557õ º;·SÏðTqª¬ÎXq¦½½Ï‰œ›{ö…§šž?½¨?êùK­Îk?òñn·ßÚÙí76+fêÖ7®ÔŒ«¥‘^_Z.M–¹Z ½½Í/ýÂo…ÜxëÆÖ½¹ÂÂV{ ëLwh:[¬>ªmyk%]§4è·AâP×Nó Ÿ/e>jÞ/ª9q³[OÚÁ8 a 3 ƒh²õ±R®ÙïyˆMLŽ©«kk£‹…w¿~£2–ÛÝmŒ¤C×™¸ùÆ’Uq#_8ïw¥Â ÞQɈÝë·d sÖ’'ÄŸžŸbX¥~Ôè7&FòmÔÉÆfx'8(—&p†ÿös/=óæûdÒt Ü šZ1Ýmmgs¦ʧæN7²k©Œ ]rröÄüø«‘°²f p‹!Im²‚ßþæÛ?ÿ‹?ñÊsŸìv¢Î ÷Føõý½½c“Gb&ô½N¿“*æu-MÁýðôØlë`{ g*ZY€t—èRC4€#$8½}^[¾?¶»çN}|o­š3Gîw$"šžLTó4¼EÊ‹3†‚’8ÑT¢!ïégžóƒQ7廩ѠÕßx RI½ã.ÌC¤HJùlukoé£kдÇJ•£O]Œ9ž=yêî­årZI—ïïø»ƒcàúGï,;&Rá±O\È•y»wûÚû©ÊÎÙg?ÉC†BK(ÿ/Sï&gv×ùžø†ª·rèꜥVŽ£ ÒÇ=¶ñØØ\°M²¹€1`–…{ÙÅ»øî.<À‚/a1`ŒÁ€Ó›ñØžOgF£ZÝꜻºr՛ߓîÕ=¾ÿ©õ´鑞::¿ßù~?!%Ô‰LAÌü0б‘ÑŽÝhlnno.+©RV,Ó?CúÌ•‹Ø”F<î´m?°xœE~½¶Ãƒ0ŠB„P2•Jd‹Ä4€J(‰Ö(W0.…ÄE ±2ÌgÌä"LL§³ª+ó" 5¨â¶;ZÂðÎ…ËãB ÆP:&Aȃ°€DC€4#B0Ä€PD ¦„¨Û3Ü3M@¹÷Ã]êÖ™€t/Jj·½KŸØ¥"ïk$ªûªäîÖK*N †{”‚1/òÏ:4³2ƒ1å w“P!×)ï;8!d5²k˜¦ € §Ñn”·£Ÿ( ~ˆbÒñ í5'Q@ +cbÓ0ôNµùîÂÖÊS‡ïÝÚ˜šäX¨÷–Ì»£¥} w«êºŽ‹èµ7nÔwögöW»`Œ>ô¶ûì Dx!þêß~ËH±ãGZ½´æù»RtÔTnðà=¾þWÞsd Y<ÿ%ß4©’(¬”´ÐöšfêH7…ò=xíáÑâ­f))]Û] 7¤#œ~s+_Ê™%3ûã‹ÓÓ »:?ýáŸü•|üÃ?ó“ûNOô˜ÌgûÇK±—Êçž8„Ú;õðÅ^Š2Ãc…ôôB95d&³ç4>Ò^ó]¦ÇÀPßÔì+Ógß÷ؑÇ®¾yó[ßúæàp¾•†f:É„;7¿ñ™Uˆûm¯8TÔ¶ÌR)®e“ˆ¡•°•$ ¢µ¶"ñxL· œÓ˜ÄÒTÒ³ ­¾é¢^U¯ô£ÈªÔëË ÉôÜÚ*ÆÄLµŽ¯ãdÝ‘¢]C¾c–FÂÕöÖÎÐã—n\¹5=;Ô› ”½Õ,dã¾U6œñáB![rXèû"™ÕÚŽqåÍÛ–ïiIºµXÞÒö‡æn_]Ú쌤2¥<5Œ(™Lµ#=05Ϻ-›G¨é°„)̤F­œSnÉl,Â7—ú&Ìž’FÓ÷ž}¤ò|fÕ2ÉŽ];X*6Uõ¥¿~óÓ¿û_s¹^ÝŒSj*¥¨$ïxô±Å…+. F"K± ùÁ="2wáâ¬t 0Ê;µé×.´íö™÷Ÿ}[ÅYï´ -žˆ÷Ä0õÇ>øSTQ¡ b RÕjñ~ù/ õà)ôŸ¾úí×3¬5tjhrh|xêùï|ßÙ©ð90vðâ«—×—RISË¥?}×}‡©ü€ ?‰ôí;Ó'ßûþqë¸Ýì€6ñ寽÷Cïî=Œ¡±ØIóÜ¿|þš0`φsÍUª¤ÒB5#jê9­¶m&QÅ“í¶=Jâv(@: –Š{’ æ %yÜf&¨TÛz¼>PâQ¿ÝI@âWol†=¶ÿÜ÷_x¾¿¯·˜ëå{&&Ž>,qªøèÖñþS'ØŽ³h£\Îètâã›ÛÕKÓþûoÿÄÚ¶»:çÁGž` œ¹¼¼4ûêèÁS£ýû)ŠgKÙñÃ/=÷Ú ßþ7¨Éap»UçŠBnÆ4 €B£tsn™ôDÏÜ÷ –Ú¸ÙYXŸ{ÛÓZ%‹u¢ Ï¿ª(º÷¡wäL·Úþåóß›š~ê}ˆãöÌÕ¿øý?ùìXÖƒ®¯Ô´8§±X„P)‚Poo•éÑ1U q)ÌXZšïG(¡J#CÕ+ î;z"  !J¡ŠK¢Ó\®wúµ O~䥬t¡!ˆšþK—ï}êÕ-Ég’hciqüðý™\žq•Lgxµ¶ÛËK3¹ÞâR*ΕR 1Î¥@L5B!„# "¬QSH ¦ ²’ +™FŒtcAI% LÓÐÒ»¹Í !PAJ5 Ѻ+#HéÊV»Ox»x™®™~÷†µ"…»í÷vé»ðÐ.ÅTÈ·¢ Jª.¡F´KhØ v)ˆBbh»v&2Ÿ}áß?þñv]B¨bÊC¤R©uXƒ ê›Q$“rÏ5-#"A@‚4](˜/i3±²Éþ¡F¹It8¸,fħÜZ'ä8¢nÔÊŽ÷o¸m:ˆµëv5•>søá™éí”ä—×íSû—ߘôxCúãû‡ŠçÛ"¯³ôg¯¿ñÚÁ‡{ò K3gŽégŽŸÌTä¶…‡ÂZЖULµ Óˆ„‚%!ÀÄ8º¿o¥UÊ ñzÏÄA9œ¸yå #I8v-Q–¨Bd,Ì-{ÌK&“ž8³ÿÌ]Gf/Ÿ>}êÉÇ¿víÍ“GO¿qåjÏdXHê¡þݯ¿îÄZ–aögR–a¡–—é‰o¯8‰Æšú:ÌsyÿË¿ú ÍF¯ÿày©:ïþ±Ÿˆé=Cû¶×†ëÏÛœ oYAröÌÑ“šoìÜYBnn/Æ“‡[ × xpúÊ­x/:zê¡X"µÿàé?øÔïÖÖ7ƒ¹fóøØ¡û ƒPÍRvßÎǽúÃO=žNô Jæá@ºóú£ïÿ1$㺆.ߘÈ~è±ËÈß^›Ï“=½…ÈÜÿÐW¿ð/«wóÇŠC…ñNs{òÐ1ÆDú|{k}ìàX&7ÔíÕ„y(R¦‘É•"®’ù4ïøÀ‡4C"€±1S3ô˜N%D'qD¹•Ìz®ˆa#̉ç™d¿TÐv½(?@$Ê&óJ&˜XI+™Û\¹!#C D˜Jiw¥¥0$B…$Ú%vîYI9R a¤Ç,+•ÁŒº) üH.¥â‚ŒB\J‰Æ0—\I ”DÝb„@Li÷„B„¤”( ‚P) Dt‘ oQÞ „¨…R0†{ÓÝÇD‘‚B$»ŒA(!JÂnÒ"$„W.WG'ûSñ*!‚R±F·íþ\.Ù×=ú R“Õµå@´ZM/U ÂÀm™ÉB6Ù5¢PuRñÑÁDn€y S)â<¦›©L&r#Ekóëmßæ •Lio{äLåV¦—¯ÜºÁ‡£ñ¡±Í[óf(³×Ö¯¥É¤íµ ˆežzàØÔ Éhƒ¬—2‘i&×6÷+ª¹I!"^¡$×#äñd.±±Zë;}àæëý=ýÕ°þÄ=S>‹’ƒ1]Küýçþ>е£ù‘ÍÖZ¾o*AqÃiˆ•éÏnÌ/Œë}î»Ïžíõ‘ñÁÁ¾¾µrû3·Ÿyæƒ/þÛìô¥[GOKä´L lU[ÇN¼çÞ’ƒ½År}çÕÎ`zÄßhåÆöY¾yϽOŒí?°õ\yÓ[üéŸø{gG-åµÆÒ“|¦ÝÚª)ωkÓ7k1ÞªV:÷MM4¹¸¹cÁ!𢦠*taU«å—4)|ò¾Ã½¹}×Î_NYµÎ¥¥Õ+¿çá³ÁC“SZþkßýǼ©ýøO|èÀÑ#Û‹Þ­‹çŸ=ñè]ƒgÏÜ}íʲ':¥báÆrSãÁÐw}r‹—û;q+ö¶ûN,¼²Ñ{ì@O¢ð…Kÿ$a¸Ð*þì¯|`nmÝåu3Qh/®:Ó?6zúüj=‡¡Ã}žd¢P^´S0è(ÍõÌ@6Wì1 ƒÙdJ)¡iÆö¶ïÕ7ãB£æj>sïá©#ëëš´¿ð—¿?»1ûkŸøm==X¹½l –^½Þs¤G„rtâÜþ}'?÷éÿðØûÎÞuÿ½3·6&í;xâ¾oLîïÛA¥\0Ù¡‚2 b‹L>#:͓ǜ^˜>rô8L) RAH­¯mD¢SÌNò) ¸ Oœ;‰IJ…¡¡Ç-è|àç‘бƒ•õòè¡ €0Á"cüð¨íwŒ¤[H»¾5´ï FJ a·¼¾ý#V*EªkI¨Èe²‰tÌ®F›ëe»Yi…ˆtÍïXJ&# áÎV93šÅЬ€ÀNÃÅ1¥3âŠù¡ÂP aX=4–îNE`B(Ò¡®€$AJ„5‚ Å¡‚ÀCRH¤%@(…`ŒcŽ¢º1$˜è +™Lù^‡ELbA%FJ Ä B41$‘JÓ¨†0QŠ@c ¸'ÈÙEý { ¥ ìò Š((€J*)ÁDÉ]TM÷0Epwõ%…ØåÓ ”ê‚ÿ¤”B –•*Ž÷õe4à*`»¿·¢Ø@høÈø߯C]®¤’”hÖ".”#* è&á›;U÷Lµ¢U}6Y”«t&àëV–F-Ç3hL8[IK4³Xè«-7ZÐyàÌ;‰LX ªÕŠË<ÜÁ‹+ëvT p"¯÷€ý‰t¯–¦ åUÑÆ3¬s,èÕ 3÷=v2Wìn++A ·k­>+Ѩy$Ý)²ÇFÌùöÖ·]]œ‹•Ê·7Ûn‡øæõ%Á‚üä{N~'²®’9ìH¢Ðòê–‘qÏB$Ñç_?uúMǧkÿí>ùÂ7Ÿ=y_ïůßzíâ·¹>0…ó@ÓvB8ö• /!šÚWÀkšÓ r=€ c×É€€RHN é´ 6FÂB‰î•„ )¥Jò "Ò4  DCL¥”hŒû¤áT&D ’’q(¥0±‚kTCI(A€1¤" b€¤Úƒ¢®P ‚PîEÐ^º‚`/ªêââÑa „+ ±èf"ÞPb—4 Æe³Ý¼÷ÀRp…„ @%%„0‚¥,ЭùMÈL@ÁT"O[V<Ñð¢(²uÓ@©n¾t¥3Ð~ç;Ï^üÎmà …@Œ#ŒRz²C*dô t6kåv¹V 6·Ê¥"=rê4жæ|EubÂb½û'޵k 7/Þ! hDyÍÔ-œI&Š.©Ç|T£š×lì0©¶³½ L6üÉSûíí[fìtûýã%oÅ[o¬mÛ*ÖñC%w\Ÿ¿Õ„ѫ篕ôÙ7ÌdIêf`¦3^H ˆR) ¢ùD„ –Ô€’NÜûУ1,^yíÕ¿ýú?¼û‰G?ú±O®­Þ¼~Ó)O76â‹6–£¹þ}‡}ó_ÿyòXòâ­;ßêÎÃ\6Ø©QLŒXÏ7^ÿcJT¢l_?Õ ÁdhP!Y13u饿¸±ê¿üÔÛžÙ7±óNÅTª1 IDATÏ-¦ü^{ÇÓ©rl_#²I‹ ?.%J˜‚ÅèèÔ]¦¢Û[‹cGŽ.m5»üÞŸ{´YñcTbèÿùçþâþÉŸÉLÉ÷<3SЈœ™¾­Y©?ü¹ÿò{¿þßb‡ÂÛ7Ù¹»F?öŸ€zÎYÛ:ÑÛ²©¨43©ä_ýñg6óÿñÿú÷½íþõF' (4ɧ>ó™_ÙXýÉÿqÿ¹ýµËåJe@”L'n]^úÚ×ÿ19@>úgŸ\[@O¿ÿ̇í—% ˆ«B1¸4tM×zúõ?ÿÞ‰Coû½?úÕoÿë©‚R „^ˆ (8>—Ô€S'N=ós?õËŸø­ÿþé?ÊX½;åòÝß‹}ü§~ýwþËüäïüÌ'~ª.Ú§&NZÀxøñG¸{b½Þ^]^i0.¾Ã™¬î쌔¬õµú™ÉÁROŸæˆ\ή¯vš`unÅu[ØJžÿ΋Ç<I{Vš%k/w†ög®^ÈöÓ䀶T~0×ÝØ²0r]%ˆVY­o»ÚN#›.)ß@Aˆ¸ÏŒ@ôö倄Й/õLùLï~f:;ÞÐÑ#˜èÉ¢­ÛWMg PJjo¼ü]JRÇÇŽ¸œ¥³ñV«b&,ˆt ä¨u˜tÉÞ® BJ©BxsñvLGQ ¨4J|ß'š‰€‚BI ÅXr?à4! £ ÷¨,~ÍmÛV¢!”°›¨r2¹ŒI·Yàó<7•´€À¹ì"À˜MÓõ˜@ ¸~³Ùà,]X Á˜š aŒˆ‚(b‘\3õD6[ìïé)¤­ˆ@€(1¨†SJ Ó0â¦nèTÓ Æà-‘×[:¯ngpÏ𺜷~R!É[ ”B»´û†öø5²«y†{Æ¡R º yX£ºNãlÊn­²ÛŸä<s½½7g®ööüßM7"B #—±˜•Íöz(=/ ¢† XybðÞWž¿ÀüfÊ<Ñ?2.ÁV,l¶’£…sƒ…º_Eá…ƒÕw?úDËç6«ÎìÁ}Õ™ÆÊ–Ýß[YY*ž­å,à ízG:ͼ•âCˆs½ X“Û ³Ñàh3›±™O"éï_˜]óg÷<²Ïm{}Cé¡ñŒ]mŽLå®^¾ƒ4A¬ ±£¨"Ö·7;¼qìä¨ÝvnÏTh)—a‚' ÙÔèW¿úf¹¼Q, •×͈å²%Éyè‰XRŸ1aFƒœ…"¦™ƒ†lÍ®ÍBé1=ŸìÝXÜî)•ÒìZ+tí+¯½ñìwŸu„320>Ô[T+‡K ›M_ÞÔ19ztbâ4¦"É(‰Y|cùåKç7ç/¾ôÜå¹g?üÔÙ_y߯o¯ÏP+~éêÕÏ~ön-^ç*êî(R).¸F1‚@FQid‚¸ ½Ð ˜`ž`V,㬙‹·µbrööz6‡ N hRE°¸^œëÕJ0>Ò*$ª%LJ]Û«ù×÷•Š…^Ûëx~çôþãK닎äéRhP7H2>*¥71|@(Y¯7ë­ ¿T)‰ ›- QˆEÏpAº *Å”¨W*@ ‹˜ŒkLvíÊÆÐÔ1 BÈî´îÜ|>›*AD»š©¸¡MOJŸ2·xñß;}ì&iE0! 54±R0ìtZµN2QÂHï~ |?¨,®p“õ LA(¢ØL8 »<ƒÐ ™à#„´õµÁ¦óÛnH–—ï Ž HT'Ñ•+¡f¬ÛÝ€Ú­¶í7BL Iwk¤ à‘‚wo9¡î…‹j„Hî J ¥Úc‡!šaÆ“ÉT*Ídâ†2!„”J !¥BH)°ËçêrûÀ[´>ÜíäHw›„Jýç¾W,Ü%Û „DhoRTp×w ÷þè´ƒ»L™](„&ã1"±bH ä.~BŒi„šÄæ`AÍ@(¥@žã2)Û³æ»XS TÉTʨ¶;º.[‘ÌçJ<’( $Òi<›Ηˆ"‘À‚«z­ÙØZ«»vǯ¾~íÍ•ƒC=ÇŽb)YàCc ºí%·xŽƒ0:Ìaˆ`!Œ\Ì®Uc–‹¥tÆ Buìs&Ú"n§Î/]¿Zñ¼êæ‹B"[®lr-ô"/vn"?sc-æG #Ü57€ „J •P¾oýoþñÙþ;ˆHOÆÚö°œÐ÷—ðpt¬k±õÌ{š»yóÛÿ-̘Â`³RцŒTªˆî:{ßÐÐD½â{¨7I_ŸÞJhèÔ#So?ýÈ™™ÍJ Do:ß®9“û¯lÊl Ž÷qaasmüÈÈý½ç˜!S…¡ûŽßS©µ•€4jµŸzúŠJñ„µoêp¦o°¯ÔðNħ­MÇ®²Ö÷ž}©¼Rά¡¡J¡ߢ¾+SÊD4u( Š”ÔÁ‘:9Öî8Å!ˆ\²x{‰Ãê=ïyèàäéå¥ûâ—Û¢}÷ɳQ$Ýx2gŒ·àG@q âµéùžBß.’ )a©7_{EÀpôPÿ=gHp ðhÇ­¯¶jÄÐD¸íŽLL,­”5H–n[yQo;­å-7zZššÌwï,®íh0apžO`…™ôs«V™) I!ív=‘é•)1C/¾öæãŸž*C;Œ<)`•xu~ô Æ ²¶¾e]3 @ãÖvhZÏ@‰ !„€m,ÏžØwÜõ;—ß|máεíÍú=§ïB òZS¬À 6ªf£^ìUR „RºnT\7×Ó/QݵBñx–tQ”‡7tmß#;õå|iXIù^ðâ4Ê©t/BJˆ©–J¤e(tB1Ö•T@ ¨”À³ÛmH¨0E!€`„¡bœs&•B ˆ‚c¬u/DŠqÁ‚0 ƒnÔ] ¤€"„D=nY™t6•B ™†‹Åb1#fÅ-33 L(éBÜÁ[8Ñ=‚ rÏ•÷Á=˜ß ¤hï›wwTÝ$V·ÞjvGÈîϪ],  b$—BzJ––`Qpg¥, ’{=C€‰íû~è$,²§¡€Ò5€dšEtÂZL—ÆØHOª¿Wù2m% ¥íFö•‚B*ÆxL÷=¡‘D­ÜtYíÅW®ÄLóŽËwt3C¡2‰n»4s;NÒ4Ü@X¡ÀJ Q¢ß¼=GÖJy±€T&‹ N…„›fÆ€…Ô•@aUÈÄM)PÈ'mÛ½sk)=D2T4šmJb@±‚H*©¤t*;þÇŸùê×ÿaäÄ€ôrýÅÓ‡96•2ˆcs`8µ^«Rù›Ó6/\¸4;3m¦â®ç™Øp&ØA>™./¯½{dðØ©ÁL±ÔkìÛ·¯Sßyþ¼'ë@Êj5øÄ¯üÌözevùJ"£g³¹+×/5ÝÍúvípH —®./Ö7u"%&4ó™dO_ï?xúÌý=#£ÐÈ`J;8}»"!!•>96Ö²Å÷¿úÕÂ`&­¥Ue’i/ÅŒ•Œ[{Á$”@ Ä…áÔOäcÎN¶b—û‹½¿ý›_úʳ_ÎdzZõJÐ\~ôáGò“PR)eÈ dÆ d®@µRû»?ýÓ¾ý q×"‡ˆ–L¥Ji­ÚØj¸;“ƒ½Ë3Ë™~ãЙ©/}ýRz ¿7•,˜½¹©‚ˆ%ÙKK×›´NÒ£À«ÙöŽ™Já…ÛÓŸÿ§?O” aj¦E‹ù!·éç­…$ÓR £”èëËó(b\¼ñÃ×p! ×ó9œˆY™Ä½gï¥A$ãÑH÷$¥†®_»t3™Èó v‡Ç¬Bõî‰\Ý\œ…fª¹Ùñ»xáõâÐ@ÿÄdÂLÅ £e·ìÈK R-Öê4=ý#`±À+þå[¯×›uNŽ ’\ÓÁÇŒnüRÓ5‚1¢µÓÄ6hIºnØz`Jt¤P DaF—®‹CH8ãA²( £ Q/K_0®$Ý?Yú`WA¯”R‚E»Æw”T,Š8çv­íÚ Á"!9ç ( pÎ8cÃ4ŠÅAu¬”ºnš!´»ÚRHιRÊî¾»»;Û=œö8»ÕÞ ×b¡Ý½””om¼vÕÎh·!-án\t7%ÑÕuq4 `B5D¼ÀöƒÀ2ck×VòÆA `\¦eÈZçv§YG#Œ(ŠH¯Òâg ºA«Õ¬GcG “¿ãä)ˆQ÷ÀTIˆ „D#þš{ûòóšN;ÍVK5°P𢾙Ù9<;¨9R‹9"ª ‚abàPzÙdÅmWº:€HS,ä J6phðÈ¡ãÔ•žà=S÷aÜÂ0·Zµž‘>Ce4lܹ1[¶¦bUº¼üí¨¶:zð ²û·ª;Q³ƒ0PP! ”Bo\}íÆÙ#CZÌ"¾0ûo…ý…§OœŽ÷Ä›¶?62åñsësk«Q„¸³3»ðR§ÑRv°²²²Z_lEí¥…æ÷þõk°g>üщÃÏ|àéZ ¦wÿûW¾›Í¬n8•ÊOýø=ßúÚó7ïܱCw|òÀw~pÝûŽŸxäm½øƒkélasc³â/II(¢Ù³cÃ)¶?‘ŠS ˆ(A‰ÁÞ³Gïa^'D@Ϥ‡?p|ªR^m£iq¨ØÊÂ\€fmkòÈ=&¤H ¨$!)Æ$N5,‘Ìööž}òɳofÿá“ÿÇ;=¶\×ÄØák~he%cdZ@³V^¸Þq7ÎT@ AMY†[÷¿ôÅ¿W¨Ýªµ9BDC¨¨í¬w^ýáíç¿üÕïßzáú™¨SAzamk½²½Ô ­ÅN™yvfH3µ¸(—ƒaýúÖ­j£329œÍSÅá?öc†ŽâL¡DñL"ØlÔÎ_ü¾’#P b–Ç„À¡òÆz¦3…$q$1Zõ}¿=;?CMÁP2Êä²Jq¹:}ê®DW…aZK¦ú B©;3Ký‡GPë››¥¾þÅÅ[çN°âñn;@<9| OI¥šë[Ä0x§óÎ¥RbíêìyÇÝ9¶o*„)‘@ÉÈH 8—¾B¥Ò©òÚbÿ`Qr¤äa$…W^­ *•‚BpÎx§ÑØZ\ñ:A²B˜HÆÛõŠë^ËñZv"“H BÝ^‹R HÉ$OærLPˆP*bÌó½‡~ÛqìºâãŒK!!VBʈ±0à,’dsê +¦é†F4Í0¨n@„’B λºh7’¾«‚V((»“ؽUÁ]gáî"Kºâˆ BBˆÂh¯: ‚cõÖ`7H/!T „BÊJÅ/þÒ»@d!1ÄB¥DI°«­c©{"%º«z¡ÄH¾Òñ‚IÒj{½æsvø{{$F˜o³Û·j•zê:R»I}ˆPÄøÌâª×Þ€‘«a¥Ç¡À› ¡ÙzéISš)aF˜⾑D5ω[1‚eÂBUωÖz,iFf|zfóæõµò‚®pͯÿíW^|éùÇ?òÁÅKÍĈòõLf(s⡳ôôg ’ð„›Ÿ½Öí­Z•Eªåº§'Î??cW–¬tçÜÛß1ýúôäpúÑ·?\:ræÅ/ݱfÐbiJ…Î4¬À)N˜š~àÈ]¶“JÒ¬’t'ƒC×5 Íî¨Ù7®•×fÞõá÷=ûƒþíëߌëØ4ô×ßxùå«ßûùŸ~¦#;RtQà(!D0„#žt^Ølæ•Û7^½Ñ*ט |?(fó翳øå¿ù Q\)áwÚµÖ†jG;Ë ¯|í[ÿð™?ø¥_úIŸ{Å3“ý^«õü7^øü§÷¿ô®ÿÛo¸'÷äÓÇ~úÑýæwï¿»r_OŸ:Qä[ן½uâÔý•Öv¼?V_nÒÉŽN-¾¾fd³:!V*a$z¦¯Ý,o^ ÒÙ4MÌ–€@AÓ=tüHÏp!“1^=Ü)‡c}G•R{«5zÿôâNm¥´Ö+sNÓ?xp˜IêzmIÇ9¥À Õ,çzJR!©S6â–"†&”ºñÂËß>3zW0Ь©Ugwf+W•ëW.+.å•Pºh$Ÿÿ‹¿l¯µƃ(RI¥(!v?ü®3™â€ï1 I%T(¸e%Öºt(ÄÑØæÖ|2×ã Öv›éX¦²½3T*Å„ü¨VÞe;‘Ì@¸Žã{n§ãz ‰ž¾Š5)VÝ¥8‚@a‚!Õ$Ⱦ‘±nHS(º~»^ } `û¶‚´ËâcŒ Á8 ÃÐx(•B”Ƭ¸®i„è”PD)Õ4MÓÂkR©d…,”oIè»Càîú¾¡?òBD@I¨~4F*!½•7•RJÄ  Ê]ëê.àûB“”å öìWÈSPI „BIPÇö!߯·TÂH„2ƒ,+eYyÇ4r…tm}ÕélGëÒ‡ygu;7ã]Ò+ÂH Üwbã⥵ ÓE#@ MæÓæÞlÖkˆô”"Ïc<´$‘†¨®çyÄô¦á;•t¾Š¤(Õ%°¥þ‰Ô‰}§׸.š;ZÇmwjûF¦rf¬ºé AÈ"›_º}g¶ÑÙ¹ë¾ÉáØ8Ó×.¼*09½x奕¹gs C¨ òY´¼cNŒåú©Ýñ n¬mîOAJê¶_* 5Ûõjã㱈Ʊn@ÍJ鳟û×ïü¿Ësk)š|õÖkrUiÀ,ð¹$/×GŽ[mn,†RÞ{žzÄñüv¸nsa•=×Ðzº1ùÅÏÿÃ?}á/d™r¹„R²H2æŠHøÐå,ÜY»Þ)¯ÏÏܤZ@Ôý‡W"’½Éd)þ¿þô.ܸ0Ð;õÅÏ=·9»½Ó\Ç:Î[˜ ?2Ù{Du_[Ä®W—+)€RA€0DZšŒú±¾÷}ÿçzJYl‚™µÐ Û;oAßv";:9ÕXŽ>ÿ¹ßûägÿäÿäK^þAÛõãy¹¾a}äÉg¾öÏüí_ÿååëojùá¼ÿ]z²„æâÊæ L9ö჉Ÿ~û{«Óò¹ï}m~ýûýƒÎVÔ¨«¥¥;.l£Hml¯œ9~ÿ}çîÁq H^õ×ò©ßЪµh§Õ!N(E¹µ¦¼ÊZe ¯r¡èâ¥Y!ŒHxþÆâ¾ý}àD©ˆÃ0žÊ„áWÁÎFU(é­Õrù>¥0D¸Zn”†&¡äÝ‘#tBE¨° àJÐÞ*ǰ1¸o‚»,‘§ó³ó¾á7Ûze{HPŸZš†µ­µácÕ;‰ ºÆtH¹>w~´çLbf»Jb!‚Rx÷ÿoŒ©®·¼:‰!+=À F…D/¯¯gÒY¤é#,AØ!ÃÄfœB?Àžãû¡¢tº †ó.˜SWR²(1ÔLuJ,Œ\Ïi5¥ˆ€†"Æ‘Œ¡!!˜`Œ .8\B 0%Ô4Ñ€’#D°i„jcLJJ!"æy¾TboÖoíÔ¡’ðGÆçÝ3ë­/ÑnLaϧ#¥T»-¤Ü}èº+Àî= "É[÷40"–ÒcñÀfÕUŠî¯B(Õ¼ŽÖc OèF)LÍ@Ø­ª$ª'^ôgþör.møMÄ Çë4Ƈsñ$ÆxW À‘œ¾xÙ¼j½bbÍÊkV*oÁDÇ©·ÂU*‰Ii¬— %èI[J…}ñ”Œ:p6ë«ÍòN³ÙÁJ" bF\øˆR-Êòv;è¶R=åÙ\"]LfÒ’¥\®”NŸ¿xEr•é·Ààà±ü>WÕN;ulZXvmÕDæô…7˜d‡FúfW׎Oýìo<ýÁ§aîü¡Ÿ˜ IDATf½ãncM¤t€`QˤO]¾s©'ŸÚ7:ÙaÕëD˜ ÊÆ°’ JCÁwn_œ]\ª-.óF½‹ÀÝU:QÌï;qÏNͶ™wpbèíxèæk¯ª—#gfñV˶¹ˆ$€. v¶ÖëåMÁC¡\ññˆ3ª¨÷Ø”+SNØ¢v‡KÍÂ~³¾rñ…oœÿÞ×÷~çóŸþ+7Ú.ÅS}9óÈÝ(Èœ~çƒÝõÀ±‰£ë Õá±Ñ÷¥5•Õµlißèá¹Ú}=‡™tgj‹£'G3£ÅA„ã1ƒ(ÖI¥¬ƒt<Ë•f‡­Õíõv§…i²ã5—–j¦N\Wv¦ûÆFQ|»”¶µ½"¡ÐŒøíé›=Ãýç1§Ö©y ¹£ù…;Éd¼Zn}÷Å笾õ×7Ö^ÅšPÎàî3§º°µ|åìÙ§QF:y´Ù ÒlR±u¨Çi?H¡vÎÄ–ÅÈå5ƒthníÞ„H¤BJ¤’œ§‰’€ñbõò{WÞ¹üå'¾tòø™Ó÷|ªçzw,žØ¸²wåíwdB%QÌSñöË/ü_ÿþß>ûÍܺ~b1E`‘®½øì‹×/]yð»Ì'’ïµb[³ZÝö¹·/~ýÛ!¹ÈŒ»““Çff+‡å¸ûýg™8ÝYï>6=ð‡svf»»5›ŸÞx{Ó°|¿7×Po¸êªèðÁ‡ˆ]Þã¡ àÀ±;áßíu¡’K*€qnlÌÉf‹ÅYBµ”GãÕêÛË‹ã Qôº½æÍÀ™­ÍNK•VôâÉ»æyó8ŠïÜ»ÏgJ%†e¶PÆN&n}õÚÁé îÔO·ºSc‹‚'áµ5»œC ¡’2 ÙL¾P‚ ¿úÂ['î9€×êt{‘»ÑoLæ¶¶Úí½zÖ)r14lÝÉÔCÞ§ÂNóÜÉ”ö12®_¾`T§e˜¸»­&ˆHp¿=Œ‰! H¥0„Ô0c5¬ÍÍJ½fâAÇ73Vµ:twëT§~¯gçmŠ­$ISžˆ$†F^¤etª4™H R$„0jåŠRŽ´•Jp9h·íŸæ ”bˆ!ŒÄˆ!•J*4JÜCa4ÒÜKˆ¤’! TR(‰ Q©L’4 "/ð¥p¿_W·¤ìàGªÕ­NKÝ&Ö+ôÃqq4;b|ëè!@ê–~V*ù#o „àè“q)$ÀIƒXåJzà Õ­ @ •C˜¸X׈E™"Œ4jg3Î0Ž7ëkþ@œ¸ɶªi4ÄP`t‡[µÊ”R!HñöçªãU™~ouu·—n¦DJ‘F ˜ž¯æ'œÂøöb}Ø„Ãë’0†š!@"faÛ±3Y'øâ‚Bijv˜àa¤˜bõ~GD|è÷6;  §•B¶¨C -dfr¢¥fs#”@ÞÇ7ÂîD¡,¤BTkc•‰»&Rª^g°º\O`P«Vôª”ÄjýþÚâÌ,R8Žò£÷nÞ ÈÂ" Y?ýÀ½9cªn=úð‡Z;¥U!ÌéZåüùsËÿög|æÿùwþl}ý²v´B¡…¯5ƒîåµîõÕ•ë;»0‚2o>ü¾‡î:}b˜†(B) 3L X¦À¢½¡±Üt›ýÆÆî&Ç„Ë}`›”JIåNmò`owçÚ¥~ïÿâÕ^ÖtÅéùCY:õ½¯ýÉ·žûÖ÷_}‘R…-|æ¡*µÉï=ýôýñïõ¯þêË/=ÿÝ^}áì“_ûûoüÍ7¾ö¥/~éïþ }ss¯T,ž:y«ACÙùÉ<üAR ³ÅZ­\N­ PþÒÝ'L©ûZ§25–µ …fÙ•Ütj4&´+﬋yFYÖK°m”¯¼ûºc¼@;43Kü8å½Z¥ˆŸžÎ¥E/-H÷¶¯•+“[ë[e«¸5ܱÐd›@7Òc¦õ½þüâ $Ûï-;¦8J¦ƒþÔä”F²åêL»Uo®o ÜdDžyw†(#É(À<Š&f÷³•Dib;6c%%tØÙ»óÄ]i ¢`ÇÛm¯ÝX[š?°ÝÛ³t¨ë™Ø‹™fb¬‡ýpÚ™Y½°{âÔ!Ò”|ùz}úÄxc·§¨’PI 4Û솧¨a¢ !€”#êU·³7V˜‡˜b:í>Ó›×0ƒT³ÀÝÍ Ó´}?ÈWK3€’âA·Ã¥¬o¯ŽOT ”¾#„F#Œuʦßóø(4„€a,`ŒbL0ÆûÆ%ØÌ#pÿtG)J!Œ!@)%¤’’` HÒ8 £(Ž”£& þ/pd¹ÙÏ7¾µŽM‚h¬: q‹D-1BN€Q€ß-¶˜ÜvA ¥€É0ΕóJ†#A™ŠýòÆ5ƒŠf~½× „÷X h¥•\yª:S´Íœ0KAÝ´ºJ†ƒÆIgusõÆåN§cgsív0DE[‹°Óï™ÄTәк}¿¹·Ùí&ÕRÙÊZ8• ‡(Eåäky¨‘(JƒP躮1Â%)ïïö mJ»» W;ÝÉ\‰ Ht­?H{»]–åˆî®T§ã¶-/$õížDɳO¿ëñj5\ „âRH!ß|íåÝí•]wÇ)—¥K#5ð0këËõúDM/L—(¨f‡A@u(mÜÜìu×ï9´$]5uµVog|aÌÉX>;lù„Uî;óð'>üH6ã„ JSàëÎŒ]™Ÿ™úàGcÄi­×o^XyâÛ?¦œR”„©ea¦éq/2mŒDÃdöÈØÊõkQœ¨T¤œK%  ÂÄÊRI|ä“{ßc_ùÊ_d E bòHþúÖÎ7ŸxæOÿ¿/m_»¼·»ÃûéÏÿOôsí¾ûÒ³O¿üÔ×ϾýÔ_~âÆ¥ Æ™jûÊ÷ßûÇøû´-O=43Ìࡈól¼¨Ís9vÏÕµ­šíPTQ^ÆÎfàV-$Úís¥ËÒDpæÐ¤‘øµ£A§×jèCAÚm4}ІÛí\9öo^ÈÀ¬×mUíL(ÃÂØ„­Y‘Œ‘ù~„ B`‚}DM7(F:¥ZÑF‰µ|íLÉ º ^E$9ÕTu|šP¦”ˆ¾Û­×{a½Z‘RŠ„#ŒÊïwGzQ„¥Xe"R!$J‚R‘’!€ Þ"Û©”T"¨é:ŠP†1 *)G7= T*„” å±b¿Ö@ˆ"Ñè4`T´ÔíŽKA´.S·2f”R#0=û_¨buO¿(jÄQ2½vÈ S‘Dj3P" 1?yø°ÆpÐñ‡AD°RPþoÕ ÝÄë¶-Û ›]ñw-µÝ`êÈ¡V/ä)÷š½ßÛ^¹ILÃ8i†:L„)2ûnŸsØaŠLVÇ”øƒÀdÐOEEˆ¡ÅL—ˆ|¨AX¨lÄäœK“ê¶£çœL‘Ì$…¸óè‰b™€0Šæœlu[=¿U¥¦mÚAêÛz¶2#™ÌêæùS÷œ®·4â0ÖtK bœ ŒáÇÞÿ§O¿¯Ûìnl¬e'ýÅ“wûÛøì峩B‹˜Š Yõw»Ql“2Ä€“tüK7®”ìâxu«ÝùاݴsÞnxÇô±wžx5k´ÿîk¦‰„év¯çäò¿øÁ/ ÃÒ7ßV€UõæF—GýÇ>òÉÆõ.‡€KÈ)æ ¸ß‹¸nn )ÎE IPé•×/¬_¿¦Aê¬×EÜ%´Üîwß<ϬðÏžøëOþcaÇû“?ý[Ï#Á?þ Ÿû¿õå_ºwRÿí¿ÿ?úÇøôWÿäëÿõ{­7+S‹cµêá…£½çcîªÎ/.b®OMܱ}uWFïI+–.LÒÁùÉ㇎ˆ4ÞmßÐôBÖ0ÞqÏÁ ”I!Ô¹ëµ2ÚxË«MT¾í U¯·J VÐUuÔÉ(‚J×-¦åoþàE[ê­þá“K¼Ï·ºn2 ûÇò¶ê÷ÓTªÙ\aAÑhìžœµm=Û_ÜsæŽ~º}_ЮĆ`µu= &Dêäü…7¶úëéz¥× ¶·¶ƒVòÊĤWï¯nœsf«‚¦ÑÖµN ÷ˆ¡B)d¯ÙSPJ5m­½Ãì‚™¯ò4»8ÕÚBu"S±lBsñ+¨¡1Š…?rï=¯¿ûb9›Ç‚ƒ ß]¹tDZ% BõW[%£„P2‹B F(• CFj˜ â½µÍnsÓ1²IäKe]7DÃVŸæ­pàcæóUŠˆR TÜ÷ê[[¶CT’€ x.O â2ò=(Tš&P!J€D$±B 1UNõDH)„aTr4ó)%R)… &2BÄBÊ‘—#( Á•‚œ§@*t{b-Åá­˜Á¾%ðVÉ‚ )°/X—JÂÑ ¢}aP£¥ü>ÝìWQ¡ÜÉ ,WΰŒV©Î&ÜCÔ‚!4ŠË’9-ï¶Z7†M#•\¥ŤíEº” ϋäÓïå*Ž‚ªXÊ|žê¿Ít*DšF©nêŒÑNÏ1ÈÚÙb†åòe¯; Bb39qê¾ï~óÓš\:~gaÞ^í½ÃÞÞ|‡˜18Š,ËJQ rUR÷{¡à@IAÒþêµ›kI޼ôæK›õ-23Ÿ3§&zõÈ‹CöÇ$Œ’ƒaèóLswÜå·úR&z|¾ŒÙ_}ñùô]ÿî?ü¯°'9@!-¯n\Z½úÞ‡ÁM½l-:’ö掬Å\h”FI#"‚!¤œG)ÓŒ7ß]ÃâÜìXýÄg©N'Ë%£dÿü/þdîø”öÖjº†z¿ò…Ÿû™Oþ¯^>¿ÓÞccåéÊd+î,;uäØßúÆÓ©ÞFÈxŒŒ’Ť¨ii¨™ @‚DèÍΠ3'}÷ÉgS ýùß}éÍWžG Öol ··³³õðáÓ~·õ…_ùí—_=ûG¿÷ëÿû¯ýÿæã¿ô¿ù Ý©æÇúWã0úg¿ôS€ã¼£‚ĉZ»KLJ}÷úÎêñ‡î_^Y6s®­e#ÓcˆÔ[é‚£iÙ‚åð$ÝX[.: B²|ýúöÊvoجïîó Û7¯°lf»·zúØl­ø¾ÄÝ~LY{½]™Âšç¸IQ·×›*.& LáãKw7¢úpÝ—ȱ™½žkV «0=–_Dˆm¶ê…ÚA ì'¯ýÓãï;ÍgX­X ü~!“×4ÍìÙf¹¨+FE |êàøáéEÝÉð$–}àuê¢ùÉ¢ˆͧN®0žÏ ƃ¨yäð 31ÆÆièýŧ¥LÓÎ~g휎{þ^}¯X)¸À›˜(,õ +V ƹ©L­68øWG@«TÆ€Ûß¹vU:ù|u–1Ó†i d·‚GÁ#$…’HBå)„€ƒí^gommóŠaÍ"„°ݸ?;5õ%Õƒ™’ .D–©“wÆ­ŒDÕ²šNªfj<õtæ‘vîj÷gÿÝïI½üõ·ŠðÄîõó@ðasý_ýËŸúÔOÝ÷įû{O#ýà³ßyeê` `{ÅùñCSã÷ò!‹jL2 ¡R–‘¦îðõ ¯¿ïŽW® wv·íÙ“'Îð8å˜ÜóÐ#Wì´Ý"u^úîåçžúÆjÿÜç>òøžÈþñ;îþÛ?}òùïìºÃúîžÜœ&.ßÒ2¤2_üÌ©u{ý™ƒðÌ=G~î?÷Ç?óÌßýg«f2?š™½Ó¬L=j,o\>zødÖ™¶üÆöZØldKðê]:vw¦¸XÑfÝf]Àa¤cU§ää»:¯÷ú=ôc$sÇ&Ô0-h:)éÙÉÖ}¼?SÔOŸét׿òAì·[7/_\˜›„ËÙNVÊ”È)êf6jz„²Íõ›¹|ÙÎç÷¥B.¯lejFÐÓ°¶³~-7¡ù‘—òplvr³±BP %µµ¼Œ$Ø€@%2ÍM»­^¾œÕ4Š% ˆP† c3qÊ9)’B*Õ4 ËŽ’ÄÎdü ‚AùQ(S_ EFÝ÷h=†F)&£€d€iêkB¤B¥*Œñþ :2ý@8=A€”!ιBˆ0H)¤‚LˆäBIq{Ã~«±ÚOƒA·ý7rß-¥B?œ?ÁîõÑOŽZ¨ýpv n±xFºy8ò*¨Êd‹‚ÃsTœëu¸/—‡„éëç¯+8€°Ç©B £,Ë‹cs¹¡Šß7-â8H#FEËyBÍŽšíWŸÿ® ¨\®ÍL/RH˜‘öÜÍ™¼£ëfUËhŒÍê“ÿtnº,Mט& c/ôZ!ºÝÝKpF&J!¦FBzùùã@arZ4¬¹ÊK¯\lܬ[%#N2/÷‚ÝÖN·³v…"îÒ^/É8ØS7ì¶ÚíN§³ÛØŒ°›ÕÈÜù±ì×~ógŸù›gÞ;÷Úçæç}àØòW“”«ðãÿ‰åk®Ë6ï¿çžg¿ûŠßÜ´Tj0s°b"[' äÊRJÈS}ïµ·—_œ›þÝŸÿt8g™ZPJH+Åó†žCYïžOßqôð±{8Q=â7ýñ?ôÁ¸ç¬s¤Öë ºÅb‘Å}œÆ€"8tü–’P¤°–××Ö·r¦ÕØÙ¹zñÿâ·þ·$%ALR¯S/3Ín_ Ó÷Þ8ËŰZË:eûø]§¿õä«mfÖÖÕwúƒ@¶gØìÚÁ•ÝͬSB¾,çª{‘;uäŽæF#;îwí™ ¥åâöú*JÒB¡J6Sš Buúžc½d@¤Q9:‘–1IðtõpèJ¦ˆ](Õ7v%âGÆ®ÝÜ)9ct]3XÅÜ!¿!LÝpPåÇß+)$ý‰š³µ³š-ŠGê­À”v»µžuZ›ÛDGÜѲ<†©“›qÔ;4CffVry¢ØÀîí)ˆ@ a&þ¿ñý7 ŒÔ;{¡Ç#ûAΜþ?ûߢ½x¼8‡BˆHð´™¡RH †²ç#! PLMΘ“¡p¢Tmâ³ô„“x¾tZ•‰&ìŒWm­®%$Z{«1s|LÀ“%ªÞÙ9µt—i2‹fÐL×¥PŽ5®9T*‘R„vZý¬eiÌ\JUf Áv1kå3R¡”ÇLÇTÏlV+³e!QÂy*8ÆH¡t¬|ÄXqA@ + }? $cã¡^)€ ˜jºF™Ž!&„@ÊTB $„!‚ $˜BBn-à¤(‰ ”\¤i*€BŒÄcÊÕ¨F(—RŽÐõ`Š“êgßføC{دbjßÐ,•¼­2£e¹ÏÑ!„F)É£ò9bN4¥@ŒQš¦0‡:cˆÑÿ¡Pª0V5LÅÎ`M-Ò¸àe¤Ã¢9䮂trê ×u¼I0fœH PB£ÁæÕ×Û[·õÂ;›{{-Ù/:¥AªºÉpc«mg(u¬( º‡ „2…I©PàaZ¢g *kØ9K“¸zóò…D*€‘a åU&s™²Ýi ¡…\Þ©˜ê”fæ(ׇJ™Cq80jócL·28“+3êôcÜj/¯\‘H¦éÅÂþî«cÅXüåÿav û‰Ç?wôÀÑŸ®ÖÊÿÓ×ÿêj}â´ÛìÅeóT*Âpô !ñ[žqˆm× ÿü'?ç±m˜šf¹½îÎÎv£·ò±=RFÕ“w¬fÇYzß™Ó'°o7®×/ܼHÓ¸T°,(®¬5w×(nÏX(—'@ŠÝf˜ÙïEn„J„àAW¼þÜ·W/¼û‡_üó³/ýÀw]ñÎÍíçÏ>oÈÜ¡…¤ƒt§\ÉOôÖÃwo®¼ñÞÆjûâO⣷ïÿÉ÷¬»³ÂÝ`uemÓï _‰§Q{«ÞZYÞš:T:tàÞ~·~|rÚë…ÚŒ¥C8ty'~;ÙHbup³!¹¸>2Hv¢’ƒÙÓ,UN.쮋¬1›ÍVöZ'O-y›½Ís¥ü=¾—+V 343•q[C‰v¼Œ!•À™:|8À•~´;Hl|~FiqiªÀ0a*ãX®Ñ%µŠÊ4ÌüxÍ*g±’ÁÇ!b ÒÕkïĬiÛºSvúÝ8;aÛHZ&®oh¥ñ½ ³ …4 âI§ßw¥)L¼Ð¨˜Iš!‡õŽ1up%¥A¯íï5£0`VÞALíÜXÍ;R GþÌôÔJûâÉCÇ-ÓVBv6ö:{Í ÝÕ ”ÏåËŽBÙn´ˆ’  žÛIOB ”Bj˜ [C+obMOü¤ÓnÆIH5¢3Ívl¡h”ÒZ.SJzApΨæ6úv^DÇ[Ž#¥À覇 œJ"•JHl!J 1"#(„©pÝ!±ä€öÏy€Œc âRŒ\Ñ©H•”qšð4…B0& L a¥„`"x D:òÜÈÛtzµá~ _?òDï÷K ÷¿ýlåÛÈœÛk«}T!£­½ A0Êx€“b©˜Ëe" pûä‹8‡Iì ÅÒµqXnâOâDئÓs»:˜z>c!™rÅv6¶{)ù¯¿óƒ—¾÷ü·¿ö_¯Õl³;é®5z^;E!Ñ­•ÆxÖô£H ‰SRÔLjV‹1`  IDATÂ$á¶Ça§—TËÅœVPHA c)‘S¨œ,fíÔÇýí~„T›fØN¥ˆbW0Ø=³”¥œ`¢¼¡$H4H¸J@h«˜±!M”RJ3>ÿù_9qgu¹®u¢ðêú£~ÐûìÏþ„ê+{ssÖw‡ÝÖªÐâÞþ›Ëc‰(V‰ÒÂðü{Ákϼúé_ü°¦;J2„ÉFs;kÐÏüÌg²úCw>ºy}·å5YN_©w²ÓæýŸýhÅœ1 Ç6bFÅv0˜:>½x×ÑÓ}/àÄA„¢ÞÙPe2•‚›Ëk¦¢ÈÓ3Ñ,ˆM@Ð2¬½› ”é‚s‚ A$¸Ÿù|Î4,ÃrxšrÉóÅ‚?Œ¤H)Ó•‘?B=OðT %ÀR¥\q(8O’XH凗 Ä!4R)çò‡¹1@%„PRŒ0¥¡ŠÂ%”BÂêœûF>›ýxˆýv›±ªØ'tŒ¨\·#Eሺƒ ÞO˜û (÷á„!|;ÝK·×÷#/•éXu2C€ÉèsJR7 ÖÛP Ñ3ÂÄVN¾XÌLF×XÖÔ‰Ž„à¦N ¥±ÛÅ*Ž"¦‘)æ° íN_srœx3sʼnšAð@†{[K‡¦A‚ eMpik4OóW5dßýà´®ÝXÞf8%6Òª®ë@R ŒÆv+Ž¢8P:ýúV6[©`z"EJŒDº¾ÑÎRqøÈtè)sKå;U?,”œn+n77ã°Q„$¢ÞÏüÜÇ·–#CéЫçw›këºI Í|ø§>¼µër)`röäX&Ü)d‡‘{ž€"–Ÿ„aÈ :líÅ0Š7»«ç~À _]]ÝØ»ò/~ã7»Ñ8h¬†¼ÛÙÛy毿ýäïù?ýÇßlïÃøxk·¿×ß;qâ¸!ìNǃfýàì]ÍU–ƒa¤ )‚ È…FÃûIüö¥Midç^;ûͯþÙPv,lîî úž'! ŠKæøìI‚K:Órzil¦Ô@™ׯ_X:^ûþ o$±vñâ–f%çVßéÿÎ¥Š2sõí×VÝú؇¸äË9‘¥NßÙ^]eiä·zå ³é¡¿'!ÁiogùrÚ¶Žž¹¸±<;·Ð´sÕ"Á(SÌíî4OÞý@ÔE‹å3T³ T醦rö„cØÂ%ž¶ºë±9k<3]lúÕ< ¸ã½cK óSk[›ÖdU¦*Œz‚)ÁTq¦¢ÙN°¾ðà1  ‡Kœ7f5eÝ|}Mx¾ãÎ.ÜÙ÷عóËíîШfÉR¤¤B4ÅÅRé¦R"všþX¬1¤3}.›¥C’²ÆÞÎóßHXÒjÕyU*so=ùJ»± !ŠEàL˜+VKã%³XRR­l\½zyC„ÁÔÜ$a¹Ð <ßCˆúíÈг±/â„'½@*9¼psmµ<^ÌÊ2½áªÁJÍÖ¶ai¬$àRÙù,&öµ·ßËåÅUœ$‰ívS£0SÊ@E8O1Ó"Oèk÷º–©+¡d*|wDqš$#ÓHA „’2Å”I¨ ÓìD(Dx”á'—S‚ F)GHy"cGŽ`%ÃPÓ$˜P2ªbJª}˜àÄÅÜŽí“ÜBrT GŠçýª$”’!xk´BŒÂm  »öñ… !„D T›°M; #ÞOÜÖeŸ•&‰U(¦Ù…’Dé¾üžsͱ¨Å’^ Ò­6Ià&9'·3t£TÓÊ‚•f~OšV¨IS%Âa·ï ÓgÅñéÒô™™{³K “1bP\¬äMÝšcdϾqðMKé7Wo6ÜF\ïuÛPA¥<áP—z”xAÐKE+oÕv·//_]¿ººêÇI¾ÊÜûq×uKÅüÌBµÙ÷g ßBhšQ`m{‹Cˆ487}úƒ>tí­í÷ÍŸ6ÛW–—ƒÁ¹8}j<Ÿõc?âª? V÷ö¶ * ³¬c–&©Î¤žË$A&›a…,€–~ùõ—Ÿyñ…ï}íË¿úÙ_~óü›ô¥ßzksåÁ«Ù©¢³4¿Ø÷›KËvÿ+Oþ5dÝ håÁ‡ïç-Ðê¸/½q΀€J—„ Å4jâê(EJDœFÕÜÄW¾øÅxêÿýýßùÓ·/¾8æÙ鬊ö¸6aS2fÌnÝì )¼c)_-a=ç˜ÔkmÿóGü©§_š;xÖ„râK ùòó/ýØÃÝXÝ:óà£X YÐõêÛ7 ¥‚7hîñÕÈKàY+ÏÏÌ’;rèT¿Ý³ç¦ £˜ mÈ<Ð>|hÊÝéöëáÖÊ*1p·^/ÏÏ÷w{Ò7‘[˜=Úܺ‘r,”ÊÐÌʳka»7}h‰#Æ#Á|éΩ­þnk' ]ScÄ¡¦¥Ó PD„š›]k6†¡íõÍBaÊ.‰®»½¡T1"z2ŒÚ[õlv"æ‚ !¯76§'gx"úf¯ÝÚ¾q¦ÞäÄ\¦¡7€ ö]¥ptfI’Þ0áqäyŠQ†ð8Iã”sŠtË„šz† ©†1A* çÑÊâD©t8•€Œ¬ËB©(X¶÷vÍ„îÛz(ARŽLèè%-¶±¦1Dzmæ5»8K´Š`4µP«x0h#˜L–íÝal›êÚÚjQ/ ¬i(S3Ê3Ù铦RC tDl7íŒ'Ôƒ¸{ÿÞgb±Èm‡¯{^µl@)¢îØvC¥dêÆC"a«S/Óìsß{¹‘ø@GJ¡YÃzäC7n™,ïD²Ûlf,“j™Ëõ½nb½¹ûê³ï^{ë•÷Þ}ñ%á·}á—mgí~Ïk‹K¯>)O)@ÿ_¾ð+I‹Å‰Iý£Ÿü@1Ì+¥Q ,À¨¥”Š®#åëƒ+ë{o_¾ôöÊöïÿÁï²Jµ2Wüêù‡l=ûÚy;#ÍÝ7/¿µÑ[ž](†¼µ¹ý¡<ò©Ïÿº +Ï{ê¥7 ñS?ÿ‰Öi*1°toµ{"™F¢ïb C)w‹å¹÷®%J<ðØ}!ÐÇJt|fáëûêkW¿3>õ‰"÷;P†¡„}̽ëìË+幕ôÊãUI]/† ­9}Ï'Ï{ŽÈeh³¬•uÊæ±}ðç>ó›Ë[çþÍoÿÉ?~÷…Ü”U™˜rJ¹N·Q=ÂfŽÝ‡1УÂÔáÅüR#idg²ýëC“ãž9Ì—rP‡8dW•ôÌù·¿U›+õú¶k¢&â–«ož·ÆèPE}Xzí…CSŠãž»-Hrèù _yá;ú䄞‚–†rýV=Á(ˆXþÌüâü™…Ð è]]»`à™i·½yÇá¥ÙÜLŒ’Ë+o•KÓ~¨¥Âµ Ö ìuÃëï¾ÇyG „2yùÕï=öÁ‡9'DÃÝ®[)åB·ÿýï>Ós~ËÃzÔÚj" ’JZÉû¹Gÿõgåwçgó[;ËK÷žº¹±zh¦4¶P,ÍzÅbö£|Ɔ¾?ô ÷=úàDnÒìוl¯\Úº´û­ï½ÚØV_ùOÿþ{/#îb̽Gî>ýÄÿÇ/ýo_ãå…ù#7/õ:†1M d²yscÕ%ð'^ÚÐøœ€^²‰`ÌøXvó¹r/PLa!º]„–Éjq>#4‡¤& ù섃²¹x£¹K 6CšH/76á&~Äüé‰E™è¿ÿŽ$6x’ÊbÞÄ4azÅ;ÛM€™R@Fr÷ÊÀÉåR'î¯E3k€PaIŒ-F½HwZÌ.PL9&¥¹ÉÊôÜ’) ô­·¾Ÿk³âĤHÄh§½=¿8oXòȮפAxõÒšöÃ(JÒ ôì1쨔{ýž7t•¡Š…¼¥rˆ·çNL9™Ù4J”L“(ì·Û…ò„ÆŒd–2z0Ä3sóÁ ifìí×&hJ»¾}MÃjcåJ©”£C ‚a¢n\ºun:Yž¦ÃAÏ"ÙÝÞȘ%iäùB¥©Hœ\!v™iJ.ã ôBßÔ‰¦1Œ0EJ “„N4ÊtB$Ì  *c:RBB!„PÈ‘ ‡i¦D£#h4ÁX!„#ú)‚#ò+ØFà‘K*€Dà‡.gÁ¾GÁý|÷ÑÓD·„¢·´§£—ý ÂýЭ‘çpÊc(9ÒÐ-XH‰‘7 "8ô[q„ ÄJ.F ×Ðë"Î|:DJ!›†{ êrÈÅD¥tliAR@Ž3æH‰r:nu¢ —Ö;^Ý03ç¦ÏÜuTz÷Zïõן©¯ír©Ò8šÊV$•œš ƒ`Êžž<°tìîn+iõ<Ÿñ‘rUch¡œ©z¦¨µ2÷»Õùìµ­+ßý˜íùŠC}èý§@õÝ#w·û­õ]¿ß 6‡\ÎÛV¶T/h…4í ‰ € €àH.=t¼±×/ÏÔÿø§^xæ9ÐDPÍ/ÿÌ?¹õÞncÏûænRõ°ãì5£|^‹‰E±,dL³5:òÂùïÜ÷±Gs¹ƒ÷ÝùðâJΪ,L»Í¶‘cƒ>þ©Ÿ[½ry/Ý::ÿ~£Ûùê3ßh¬^³²•‚Qjï *DVsvÀõÐïK¤Ï´,>6] šØ…2ŸçC¯‘Ôv“´X¬¬ßôu­ñ­o¿aØ ŸûÈÃwž˜ÿ‡gÿü÷þïýú·ßúæóßZ{çbÕ;Õ»³w=ÁÈA1»8•=V®ŽOÕü˜gs`f&6vzc%˜²ýî:à+O}GI§íjsäÔCw=õÕ³O}ç+KÓp‹½ùösC¿Óin·7úÜA½N[UÆwnìNÍÎuwˆ0FiZ(»;zϪÚ…£Ä¶lÔÂׯ^𬕇~ÓÉP™¡aŒMMK"ßQˆ [ÌçúݵñÂ$C0õܘƒ$5+[ã½k7ßÖ‘p%„ì™H&nÄgêT½‡r™K—_0sRy›“ÓÓ~b‘ 7v»14²aÅš"¸ª²Ò8å2¢–L)s²×Wη7Š ¤cS3XÄFï¾z!›©1Åe*c7"އ T-$)÷ZÝ­ík.1 9Y[©JbÒÖnC Ønl]»yéÔCwE¾p#ÙÞØ…qR*TãHõÚ;­½F·±Å4­Tš¢Ø@J1DDZg%fhiPˆû^Ã0¨ð¹£ãX bÉ€HÓœ@FŒ2ˆ@ÊSÍÐ Õ5B@)P‘F‚ó8ŽTSˆ”BÛŸÊ0Aˆ ¤Œ!ŒçJI l02PÑ~È‚RJ"häþS·¦}‘Üÿy¿ð@…€TpT”"pëp_Ù˜˜5ÒÇ$·<„R) ü‘D@൛ïx^ˆ1ùÿ©zïhIóºÜ÷—ÞTï[yWܹwîÝ9LwOÎÌÀHP2(GŠ¹Þ£xÑ›•vµ\ô¸¯Ä#uÇq,Qí8ËëÅbqëå«+¦åv­îÊÆj4“æ.„xÁ´ÍZ[èQÇEBµíÂå“WÚÔ=21%-¨BDä$" ¨0̘tá¥åÑÁP«ãµÛæÉåUËnŸ[xµÛ\ ®EŒT&ÖaTCž/ç6vB9Øò s³»@Û7‘uùÒÎ+ÏžÌonA ß~çý³sšNgïèÁS¯\Ý8 IÜ¡b÷ÜmS»"ZR¯¯wV/øVdàZa´ÓiÛ1y# …[Eëê¥gn~à&EÕŸ}ý…—~viþàèú–}ä–½Xn<úø¿š2ªS®['‘ìÖµ‚ ‹ÅZ)™Œ$&Ñ@pdOzxnoÜdC±M×sì—ÏœµA^j3¬"¬ÊºHd M <øà]‚7b!Õµ#{ç:t÷á7G†ŠÛÂNñcŸüÝõR962]+ˆý·ë äøüÙWV7–ƒ´+:ZÌå×Ö¯^Zâ¨S¬ûå|ÙÐÓu¾3¾ûHg¾åÍ÷ŒøcÏý`nï, ¹uʲåáá™êFu÷þ=9~ì¦{;æÎÔÔÁf¹63‘êòIpߦãǬªëcÖl´‘ Ëå\IÛ¥ÍÄȬÓC@Á¥ë¹LbÐxfdz^$3Ø-V&vM9Ž êɈÌ­”Ãé ‚ ÕjjAÃïrN‚zœqŸQŠ Œ‰,KP¶=÷Éšq1&DŒû¾'€ 0A’,ÉŠŒ‰!D=G3ì‘E…¢§úÄ¢~~ܪÓÕüj¡¼xuóõ—^ë2?T[fk(“ *¤iÛ­NÛvËɩݿýÉOAɳíZ‡7bÑ †*6pP‰2Ûô[‚A@Õ\bÉZ„{v¯­$‹¶K™#„ 3›ÝñÙä勦èjªA( DfòÑñÐÎfý{?þQr—¼+»‹#Š$"cܬÑÇžxUÞNÃ*XÒÕ×/l¬.ø¼£¨úÜyùüÓ+ ¯¦µÔ£SH€ñCÃw¿ã®VÑQ$AHM?Æ i¶dN<(QEÓD.¬oO=“$¿ý•/~åk_?õÚ3Ûfåù£ËÏ,×:=ûòhFã­ÐÏÎ]p:®ÏÝFív¯mŠ•.¶Š›x4ØtM c¨† ÈÂÈ ²*a—3cŸùÄíÝ{¸9”wÛ2ñ;Kù³ç—Î^Ü8sß­÷¯¼òÂíÜõú+'a707wø©Çw»+»gíšG¹YÞ\-E«#c;*®”švYó¥H ×]Íͦã/¾ðÌîÙY§^Ñ<‘ G× WŠ¥Z¹´ãSUnrh¶e;–ÙéØí /_0bhnï‰s—ž™Ý{DS£3f­;¼kjsi+žU¡ê¦‡CŽÓؽ÷X©[42afv•´ã5éúJW ©Z@ê´ì†·I¤‡ ËR£r£iF#IY&€F£-I¿ÞÑ4EFÚúÎr4êsÀ!@Ø8ˆ¢ÉÁ•…«±L@c)EÒ°K ePbz8«!,CnèÇfJN SÀTA©g¶VŠ›‡wßä{>‘ðÆæ¤”È`cm-šLŒL Ä34dM’fèÍ\<2"$Ü©Õô¸‰Îí™Pp€sˆ—¯Ö×£‰Û¦@S8£€H¥FÕ÷q»eJ*g~ÿ8´ IDAT¦ã=;4ĽÂ’$IA˜ô Q/™«·‡‚À홹ê BE %nàÞ¨;ý‚#n¬«z“ FüÿÇÍê“`ÿg ·µ}bï\ˆã`nïaY®ïr¨Û½c†p »ŒNp$sÈ„`Ëm1æ†a¢ËÝJKhª <ê›f÷úæBDÕ«j®XÞ\Þ  GXîvÌÆvc£V²›Íî=0õ¦;¼ëö»9刨*Iª†2J©PI…#FPÑžjÎ NŸ?÷c]“€ív»Ý-u;NÓ]Ï$3GÊ­f».’ŠŽ&ËfÞ±# 5s±¸ïèÁÙÙ}WjÖ·NLV+ê±-¹ˆÌLŒøfÃów*µU’‡wÏeGö_ÚØ“–4X7ÛÙtèøÇüxáü…¸jìl•÷Q=æªyp ;4‘ãÿüÌãyæÀèð¾c{1§³cFÌÀ>´Öd(ÁJ3 H2!jå0iJWôr¥UOá°i6FS êUh'†T#‚0ò똕Ÿ?úb<9êSæQ¿TÊo—jÓ“Y(°¤Ê-³&COW´zµTØÎçò…ÜÆZd—Ä"2„”3Ú!ÛF$. à‚1$jÍÁT–h¡“/FãºJÔDjT’dI–µ#Z<¦E5#¬íä·Ñ@³Ù€qêsÏ32IÄ€&Ë ÁŽåŒŽŽØ¼šŒ'0!˜ GÜæÄä´ëq×q¨ëràˆŒˆÑnY…­ëÁ (wL“ ß2»PpÏudœ1êt=¿‹ "yž EB9c!URÛÀC æSÏîI¦úÖ=Øc2`"KL$Œq¿µBA€z¸—ÞjæÆ,ûõä?5TðFwÕÛ¤÷Ü8À¡/Ì¿À’¾!Èÿ)ALô£_ßÈ?ì™Ð÷)\&2’‰ —’(8§š¢JX½ðÊy@X¶Œ lR‡aÑ4]Xn«YÊ£#€‘€P˜h"©g“Ayp4ö¡ýr81²¾R±ìz·Z+l•9§CñðÝo¾s`×X"H¨àc&€` ŠZ–ïlñH$sæ™S È î G³Èñ°Î̶Ã1æ¸éÔ³3# g/R(#Ø•¼Z*í››n¨v­¼õÀ]‡2#é³g®§ôøžÛ¯^Ý<ÿʩ󗮶:Uë×Ε¸p…_¨Úûg';Ø­Šµ W|‚Ñäž½·ä6£Iv×ñ·~áKŸGe%²Ù¤žV]œI*P)óÔ€!1d`€W0c”GŒH¾\ûµ_þï÷¾õÎõ’±ðs?Y¼pþj¡|­¹Ý^_ʱˆÿ¦œ~úÂåÅ«ÅêB“6ªÚÐ\r÷¾C##In)Õjc}k•yªÊQ Sá-«Ûžey(>yè—ßùôžº÷Ö7½òä+6'w'S“ó.•b®+©G=xxFO¸µ|}lȘݭ©¯_~ò»¿ü³O¸ˆÍO¿záÌÝïœOáç_ÚÙ¼*,¸a—;×j;ÍͧÁTz”Û]™±RKT*ífµ¹º¸ÞØ)<òíØëî®dÆÞ1-›ŽëÁððÑ¡w<ô[Ñ‘Äá½·>ÿÔsTðïüð‡y3·´P^¯]¿²fÄ5à4´XxaëìmGï§žiÉÐ`§Ê ©Í…/,»]Ý[ØÚJ¦EŒÎì÷M}5¿^h´@ˆ ë#‚2†€Óíॼðηßí¸³Åóéø8ðíJgks¡&¢†®jF¤S¯^)¬¤§„ AÃ(ílIv'ºkpe†¡݈òŽ¿±S™ËHa¶oæϵˆDÚ kôÀ¢¨+ÉdÚ)»k+gb©0D„`˜NQ=‹ƒAE‘1ÁD–kµ¼/{–kBÆTY*mmCg¦ÙÍæÎÜÜœkóúæòex™Ô(râ²&Aæ{7¾ëùŒ¶êM #€ Â¶ºŠªp_²| P&h;¶à3J4ÍaÜñ]¸a!"2DÀ>Ø@YV˜Ë|á*’êy.u]ßw!aÂaŒ €AD$LÆý¤¾>ͱ$!„D_ Bol°0€¸W•ྪwD7¬8ðÆ` â}V¿¹ëØ£¼Èy÷.~‡ïüM%FˆÑlÕûøezÒ $$FÝ®çˆ8ã.µIPÂÂ(æ¬f§H¥²Ä K",©Ñ€>ÇRË1ÿÇ_yüìå³ÌæFH²T Ïü|±sõÜEÇqªÝó8BXRd¦¸[k×Ìí²…­ÔÐîäÐ8óÜk¨Qmk©VêäÌèxü⓯}ᛳU» €âwý‰Ì$Åêµ—ëwÜŸÄ»ÑØ3—‘ƒúå•2vÅ™«×/^¸ì nÅóBŠ6<__Û¶½N±fËPуšŒôǾû˜ **Áù•Õjᑆ¹êêÌx­E–/žÅe†w=z„`¶Ññt†â!G¶E»aYãA(¯\Û¾ë­Nîž?û“׌ѬכNµY£mÇŠ‘¤r—5í#ããù¥?Z>½²º¶ašj}Û:ÿê¹ g/PMÌÍܹû€uZ·iÍó³dE3ì ?1JD’ÝRñsÿø'¿õOÿ§ß•ÓÔ`ñV±²³•O%Êøë/]kï´’Ê'ûO§÷=P¢eUÛuùêGÀýfê¹Ç¯ÒÎ&R÷Ýò¦Kß®ŒÌ)‰ÑÌ–³>yÛ­-͇b+ôz C¢ÑH âsùóíR wF{m0}ê?¾ÖÖ­ŸüÇÏ~ðÃoµÕâÚÖõZ)ÏŸ?Kyîß³\k×äàî›!öÞw|½ºñлßsêgßsïÃ¥íÈ\MªA#05A33Š·ÍŽPkÆPzÐ÷ (ÝV%“”Y<¿f{mÙœ¶É)Bײ$,]y}!;>LbV½ã[.µ\Á˜¬â©=T|ÏÅ„è-¨‡]Ï× EÓƒÀ‘C¡ªë=d'‘$‰Œ±¬Ê‘=סÌE@ò9÷|2*Ir傯@$ Ĩ¡‚àþy®W¹ $½ ‘S  !ú×¼Þq¯Ÿ’Ó³ öN‚odàgŒs&ôLçôB äõ’Ô@ßäŒ~ìA·0ÊãE@@ ‰Æãâ^w&IR"^¨m)M @Qζ–‹*QÒéH0ÅBJªc­êwñÙiß—~úÜë«¥%D-T c/ ˜& hPÖV›)Šk„ÓZ\å<¶fÝiê#!È@6ÊìVÕ¥%ŽíZK ºÑìõ— O}õkæù¬:„5C h*âù–]¯G¦Ã“ûö­,^Ÿš0„ºzqq­PÆ®³ÿæé=cãñØÇ?ú‘wMNï9qû-·…âP D³á$àŽ•ë×w®-®þü•gc騹…3ÈP>669»°hî=qü7~ïßùî_)šÁ;þáó$¨¸.õ«¸2£%Û€ PÈn:>ó–·¼ï/þú3¯\;…<øÄØ£1Õ¦T@’5 õ}ökø›éøMó4•öÍÍC*W«ùÜra!¿PŽ¥F‚ÑhHõq@†Ûlì4Qý¾ãG†RC·ÞþÀ;zð×õh(ƬæøÁôñÂÙgã£Áñ@ª[¾næœ×^þîØðì}·=Xï–e"y6«¬c±b£bhìų+v¸èöÉ_kíl¹¹|Tç·ÚÝõþ÷½#@ÈÙ—žµkÑÍn«[,Czχߪ&‡?õ©ß.ÂJÞ.œ;¿tõÂÒÉž|åÙgžxìË¡¨N%0”Næ«;J+ w:GæïûÀûߥö‰î‹¥G.]< ‰Î9(Ö®†pØ)ÑØî‘æZ7š¦m«Ì&}N€_gBHDûÌ’æV[[VS“ÂB5¦É’ =puùµ+«§»Â).•Ê…ÑhÀdÛÛ;[ŒFx N9À»L¼töôøø¤ïw°n§«ofßLH¶¡¢˜–Ãk¾ìŠj¹@¸-Ê +!?šöB©$ ©ùÅ™‰Ýˆ¹^×.7s”s¡`.˜€HUährpåÚ sÚZ@Œ‘€Î‘P”•“gѸ¤ÈóGŽ(²V.ˆªÐ®ãSh.’ä‹®ÛŽÃùõ­ÙCû]‡BÚ¥2 lkãâ®É5¢ÈF4äßvldz8£FX ‡ãL@ ¡ `æ"HU%!)€ ×±e ÉD&XÒuCpáxެ©Ðç.õ©ãßUd•Rʃýf! À|â¼ßÞ@€$’ „AoJöì=ýÚÖ›…‰_œ{&tC{о¾=º§<í©#8ïÕ+Øßп,Ý@ê{‘€(ŒCHÂBq#êè{îH$*Â2"\0:8(«2ÑäZ½Å¨qÞñ¼|aÅwéÞ©QnÝ$…¸.ä‚Y+Tkv:²ª§"!,KºO„'ó¾D™!”ÑBA=˜@7ŠÚ¶ºF! GB±V<ÚöKÖ²ÍÐ’ i—Ûò²™±çzáÜÉïïKÈ>öüË ‹+5W$‰ñ»ÿß>øî?ûÄ|àÓö§ößòöþÆío}Çïü?¿ÿ§_xìÿûgŽßºÛƒÇÁócC‹¹Âä-ãDU1³*;‹L8ÿÊÃæÿø¹¯‘HwŒÜýúéŸÉí>¼oôðW4Ÿûª‰/™ÍN©XgŽdrÛ=zìbƒÝy覶t¢yB û2áŽð»ðdÃá`°ãøåf¹ÓpCîCo¿YK Ùm ‚ÉTº[µêíÚ àT°Æa’“* mW‹¥Ú6ãÝB½Ó*±ÔAÜÜf:Pt¨\»üêà­ãµ­<&®¬¦­MN<üæ÷ìßwûwÿß/~éGÿ4 ¶³ž«?ùÜ“•ÍeÐ-|ô#¼°ðÜg¿ø?K^åä¥+*§Wν`H±V¥õòÉËÉŒÆ}'‘‘w%Ó j[¤BI¥ãä—>:›™/u¹BçÌÙ3ùŠUs®vmÛs­ –ÌýÇfJ‹…מùþÚÅe&qÁÜ›ïËÃïúðÿÏ#óGoeÝNp<ª²ôÕkgúÈå«Wg¦F<_9}xtª´¾n™&—‘ tåüe ³²W«mæ»åZ!1Žð$Ûܱu$I¾fÖV\ºf«^³¯oåüæÆ@Ú0ô(’$AdJ½Vysÿþiu‚a¡Ó\Ü(ÍßD] !hu-ÊÍ`Bnîlø¼À9ŽNfÕpÖÁÌ6y£~=¢Pf]>`¤µŽ‰bRúÄó?’ µËÝôà;m ™tºTpnwœÁ{õN d1MeMK–êÎŽ ƒ^·+\Á„719[ØÊ ûLpÎ9-«V/´2ƒ»z-ò¡L%Á FBM¯ÒîZVBÌ`™ŽÙnY¦ÊàHíZÓ÷l!˜ãSB$"+b‚eÛ¶9÷1Æ×GŒ"ˆ¸ïsÆ8¥PA}!@(g”Àû¹ËoôJbL0ÂD’!}9„ÈûŒž¯°GÞ£B¸ Á¹€õö]ý(ú>4F‚ Ñ3?! è†Û÷!p |hl”L€O¹€}<€±&’ ³ Bà-\]tÛŽmVÜF€90BɨÝ4£S«ÄGD—ˆácÙìPh(=Í àèx0ªII2\\ªyB‚C |ßµÛØoTôŒ¹”‚;¶ã8N»Û²]o€€‘Ááb·Ëdý½údhX÷\÷óÿUÛ¬*Åžºr*÷â¡£Gï¹çÎ{¸ÿ}yß–V/lçó´as›‹ WeB*Õ–mURãƒïýÍÿöÑŠxpnz0‘˜yé‹çÏÔ[ƹ“§eEENï/‡™‰ôÕ×:vÙñð±ã÷R×P!× É·™ÀXVUEõU:Ìþò{õÜë??rb(‹Ë~—(L‘UÍc³‘ø`PV4™ Œ-Û´iËtLÀϱ"ˆ^=·òÌO^p¼’¡wÊ¥B=Õ‚@ׂDól‰B×j7+Æ@Tká:’¡Z Pi‚ÍV½Vêì´ó¯]¼ðÜÏžŸ›Þ_ôË2Ñÿ÷_~¥¼]jT ÿü¥Sb+—®m%pöÈÑáôÄÆõ–m9«µÜÿù˧¥Aeãj®m«á zecËÇtdpR)*5¡ª¡Ütÿ[ßüÖw è¡åüöôPLM³pdœ*ÛííúMs©‹ÎèÉÄ}ì/TÃXY\u­ZoIJ~9× º 'CÕíÜÊBmq[Ýíž¿wqñJ­Ôj,çFÄpš†;84`R§²8wÓîvÃ×"€dh O¶5õZÝèìþ¹KWŠÍ<çž ]©L$)3Ò")5Ć&&CíÁÕíµR±Öª—#!’¼pþ¤Ç°Œ#Y©­]ß*žS# ¥sQ­märkZ$mZhúÀ-) ƒÞtqeAÁÚõN8‘‚0À[UL‰¨‚1¢”-W7ÍͪdCq‰ò•+—«µMæéð@»ºT”z¡dv*ó“²µpåÊþ£{˜ƒ×.^-ÊD‚ÓóûÝF2ž€pJ±"ï¬n2Å F¢”!Á¹YoÙ® "Ér(¢ ôÓ÷Hˆ9Žé4 UÓTÍjw-¯ë:n­T2»·ëxÔÅŒ‰¬Ø®ç8–`œÚe‚Ðó\Ëó(£½ æû}7Ÿà=+bÚ×lö00ý| ˆ éIèõ×äð†Ë™÷ãé…à ~èp#ûOÑ××CÑûª®þ–ž‹_ÜÑ/6ùŒIag 2€Ä¶·0‘`?YI¡í¿éÙÈ„jȈK!×êÊ\U‚ ÌÖd¬”ÛòºÅ]ñt(̱¢EÒ‰ë‰TBmz ¶R«UjŽL|5ÈÈQdõ—…N»ÛÅ›£ó‚ùÅF ˜~®R¥³†&2èt:‡8±ëÈÞr ¨þÇòÕøò˧^,•ó˹ÅTlê×>úÐÇ~÷Óÿ¯ÿヿù‰÷þÊÇŽ;1=½gvï|41:462qâðìÜMÑÄÔgùBFNÏŒMÖ½Òàì$€Êζ›ÛÚl5ZùJqb×ü;zG£ÖÌÕNvZŽ ­rþ:‡î-7Ýaª@~‹¡˜®gñH©V«|ðCùÎßþÙµ'Qmº®`k¶=€Á…k×­¶§1áûT’~@GœH2Ôˆ”|áwÊ3K È•ŠÅý&•EXSg÷Lì¿C@œžPÛu%‘æJ0¸¾\µp7„: ¨ I±hTÓ“©…×+ÉHø•ËW›æÐ`êMwž¨´ª/¾üÒÅ ËÄøÁ¹É·ÿú¯B/>6…T3}Œ.ØèþÛ7¿$½Òr‡Ò#A;á¹Dj0b[ü-wßChÛv®PJ EO½Ô¥MM V-ê;3ÇîOEbss«‘»xaé?û‡×¯žÿò·¾î¶¥×®=¿`>W8328•ßÞlZn)žÌ\zñµÍznlvÿøž1ÝQ_|â_îõJ@ÂÔgP”·óKÊV4™’ãú•óv§ì¶$S¬×wšv) GõÃ)EÓ‰a×ö6·6êù‚gùN·¹SÞ>°gÖµ¼v£mÛÍÄÐ&ŠŽkÁ„ˆº®BðúùÕ€ Fb.c‚±n§å32:86"8p\GÓ  ˜h‘p$žàH`I6›M&…BÓu‘kÛDF‚qIÂj@w,—3ŸùÌrE’@@J)gŒI Ô»B!8ã½ÀAÊ£^¶~#¨¹ÏVÀ¤G›AÞöè±üz=ï[oýú¾h`/ ‡÷ØÉ¢G„Ý>ô 3ð=?B½¨C ˆÀèáŒ1°º¹"ã7T«ýã„€Œz.E ð\ßj48‘ôÄvY£ëå+VW´‚‘HX6bÃûætð3köve¹V´©b7½6A u[V§cÚ›™e„N£å˜Í…­­V³%uåRqgñj»UÞsÓfë÷ßö¦—~öÂ_}îN?úÓÔxð¿|êcïxëß÷kÿúoÿ_ÿè§ÞùÞ÷ÜrÛ}DU\Ó5«%«SÛ¸ºóůüó÷¿ó­çžøÎ þàÊÉgskkK.›U,øÂÙ³ÛpÉH*ÒLtÀírE†…kKY¹eÎ'¥ÑÅåÕ.¤CÙq¦üío¿M•Œ®‡ËEªêRÙcþá™Ã­zõ[?ù“ƒ:Ô‹¬¨Ú!M“DWI¥Ð²:5H$È$ \`+º®R1b.ÇÜ·8 &£]$KªjD ‹ÑØG „hÉÁtj0–‰FSuG^9µZ1Ûº’|#¦‡£ÙøR©¾_ͺ®?1ŸUihï¾¹ã7φ4ãÐî]ɉìÔÐÐðøð‰ã·Ç£‘€ ƒÊØúÆR&YXXŸ™ÌŒE†¯ož»º‘Ǻzï~àŽ7OOíÝÜ\Ù7¿_tÛ#ÑÐrnÛvBDé–·‹ÙÁ‘Fuks½ôž¼ ¨Í;M'GÇ(K«º¹tåÜ#ÿöÓÊÆ¥'{µÖÜH,®å§wM=ú³ïÍOÎnœ¹šß¸Ö²Ö¦¦nÊ ÏzõÕs×9râžÕ…¥Íë×âÉIÁ”P&3‡½ñœ4ªÛ €se -,K±X²8wm#*dÓÓ„L|êeF¢Ú2ÓŒ ÃÙu“(u|Uãј¼~mÇPC‚ú½;®ÔU]…®Ã ê2–Òv ™?6·+‰~ù¯?÷£ÓOÜsÇ-¿þéßúèG~gþàÑC·ÜòàÛÞµÿæ[(QÌ.£Ôƒ¦€ÇG¾þ×ÿÅù_ýį>ôö9pÓÜ¾rå<”Ü¿ý×ïýË_ÿÍ¿?òW…j1™‘BÑ!g3ˆÝbevvliiM·k5ÆoýÀ»Î¾RGB·Sfó=!€ÿð>Ø^D ߺV¨7ª Öo¿ýTføØ¹X`ü‰þ{~k‘{&$R«V'Àkúž*aIž°e •4µÞñ¸l‰–©ïsL=WÅŠ\•dĵP@%Ò¬v.ž»œÛ¾ìo=gg‡B @ksÃYIS\ËŽ6,âéP §#¥Z{d,QʯME¦¿ûS»ª«ñ^{ ûBó\58°³ÙfMû¹+Ïï¿ùÐd|8m$…ùµ}G÷É<JÍ´ðb’†ƒÐäôîzÛN¥ÍØ~c¥QŒ§Fp=8}B[/[VØK'++«A(ñ耀ñ›o›:1=™&y[5‰Փ¹µVá§?zô±ïûŸ¿óåþËwûf<ž IDATÊÛ×+ÕíñùCÍÍ $µôàľC‡IÀX<óÚ­Çß/aýÌó§"“‰É]“šhµ¶]ÏÄŠÈ_Rh"`6ÚQc"¹Ü.¸n+ˆÆ¢ð[nIgÇÏ>µH]]ºÆ¿ÔÎd3B@ÆE³ºéÖøîÙyÇC˜ÒÊN©Ói¾õnˆ0‘%ßsó×®¢Z~µ°^(•÷Äž}“õ|ÇÓ¼å•M)Ñ`°Õ.W· ~¸ƒ}O$ùüTfváÕS»æÇZ4‘΋»ÝJÔ—«[\05Ò5Ô£Å|É D¨` 58VØÌïõ\ȳM«ã·[´184Î(ÇAƬvÛ2ÛœsêSÁ¡Ï¨ïØp‘‘빎kʒ☦fŒ2Ç6倄%kÄB­V"% dÔg‚Iª$BʤtBHŽ !‹‘5TîSÏs˜ïqÎgPPÐãªN$‚ûq¨ü V*ì{”ûx,Eo—…€ @ ÿ \8»j!B}©oˆä9ÂwK’dc¡/øîùcÔ# ‚Þ¢]Snr]@€˜Ø·oO0ŽƒQ=,ãk‹×}B‰SˆÆ—·h·3;wPt i·6JœºáZF8BJ˜z´c;Û¿åYå¢ (Â1«Cƒ³cÃÙ╵µÚÉ„jqqiõÛ_ÿnnmy~&yçÑÛ_yò¥pv@Fe,Ë aâŒ"Œ!Œ2 B¤ÙÌ× ?ùü×?÷™?þé£ÿðå¿û·?ø½?øÊW?÷è#'ÿR]Œ…SÇn½óæ¹½åÍn¡œçÝjêšÃË`s©Y¨Ø¶åøÐºùØ/ÍN[¹¼£ÅRùœ £!%ð¶w¿c3çgRQ×€ñpÐxõìé®]¹çÎå^ݨ´69ÖzD °6…Ë Œ} "Ë:BIɬMíKëFPFÈ®ð@ÊJ à¶X×êTk8û§‡c±ˆêc‡û›ž i˜±T0ewÛ>o¨VĤí‰ð®òõÍíâE§æÄ£I§ÛšH6S[§j´qé ÍNÁ!K¢oŸ¿‚kúm{Öw,SîÜ÷ð½³·ßQ]©ÅÐBîüî¡ñÅ“§W—.¼éÁ·ßyçƒmÛEžÅ¸{êÔ“ÚImfH›;8oÖ—þÜÅs¯ìIfvm¬”âÓY³Þö%K×â´ÁkNpȰº«¿ôñÛï÷­#»÷ö÷>1;W½#²÷µ¯ü“ =€°%we7“Û\ Æ4·ÙEÅÔèaÓk¥5] èªöµÏõúÂÆÏ½úúì¾!@y{+ K! äv–^:·öì¹Ç\˜÷ߨ®d‡Š’Jì:~ç½¹NqrbÖõ|Eàçž{)lhé‰]PH’ŒÛ]Z_TeMâÑuÌVÇœÝ}ïàDºžÏm勤}3 ¦¥TbbßðÄÞùØa ¹í"ÏDÏ<{¦Ð]êº-Pr4d ¯ã“d6®eÒ …m`{m†b)ÏeˆH­fÑoµÆweÇŸ}ù¹ãf›u«S«{7: êN½<=¶Ûõ¹°=Çt«Õ²í4ŒäRo7:…í-DgÌwmÆ¢hÔó`„àn·K(4͆O™O}!„Ùµa껞 ÂÍn³—B¡ž‹e¢H²íRÏj+Š¢‡b aN}ŸÒž(´W R×s=ß㢿 ï±{ÉBŒ‰èmÛßî¡ÜÁ Ôñ 6LÞWÉ÷Ú). ‚ü'ªCO|ÕÇôÎAßÔ0CÎ8A`6›õ„¬émæ/#Ié‡Ûƒ^R`"s.gãn2aI“¨ë *®ج›®/Tª–ž5°ÐŽíÂ[÷Šg’ ¸2k×K–™™ n-ï¿ûóç9õÔ¯þø'Ï>ýÄë/œ¶}#2+ò¶ÝQE||:ó“G_õÔÅŽ_œËŽî¹y5·ñ¿þéÏàÔ£Œr„¸ço",8S‰töµÓ]¯9I˜ÕΕ×ÏÚ¡Ö}·K ýÊûöÿæ[>›Ruæ’XzªÚaëå…}‡Æª^Çg]ä¡õòÅ¡™ìâ™SµÒ©v·ItøžwÜþäc¯õ0ht‹ ׈ŒÚŽuÛá»öî¨5(Š& –//û{êâÓ]¯ÒÅ@$Mt|®2…J,Ž…pe.mÚ¾ã ×ÉÁQj;šGMÛo·± ó=&Ëq<ž»~±Þâ–CÇÞ>{+©F±½|z½]Û‘}üúëW,àÔÚ]¯ë3Ébe'¤µüpt½¶ SáÛÛ§·³#{åàÀ©+××¶<.­z½]¾û¡·œ¿ræ¶ùÙ=‡æÂÁ‘*E ]}ûÃ÷#¨ýí÷¾ñ…ßýó×¾ÿÃs§¯WÚ¥ó'/í«¶w®ç.í?x¬íÕG‡ÃÕw ‘’íú걩ÉþcûØÍ‚£D„¤æšZ©Û³án(Vã‚Û÷Oìš`ž­¨?û½÷ŸÎ_ùá ϬæZ‰ÌSÏ<±•gé US÷¼£GwzyåäØÁƒ¯?þ/üào?ó?~ß´üí•mêæ C£.xô¹“ÜvÍ ÿ•³ç¯çνôÜò7¾ñ£{/./l—#šïú÷9°²¶4|x” Pî1ß)×/,_ž=2åøœúv½Z¨ÕM ñÚRÁCr Jƒq‚ ðü&Y]Ýp0Ø©ïÐ@´¸¹ŒŽŸ\>[-±‘ÌŒ³Þ8}íùZ­•ž a¦²¡ìÐX½T–膦7 u¢$«—¯]8å|aëÚìMÇÌj{{9wañ’>˜e]¼ÝÈÅ¢ —RÛs0ð$RFõhcÀ°½.'À÷„ *ŠÎ!}&<Ê8‚FÐÐô°í8²ª¶Û ¬’p,Š9pº§nïŠÇ8ç‚SƧ& v½ €PUE †$”R ¤¾Ìp…`Ìò|Ïóg€svCÆ)ú% Œ±$õ|Î@ïY•ßà¹sð ”_?OU Þ?ùÁ`‚÷÷ë½/CÈ`Œ÷l…œááѽÖIˆQae«_ÂÌU#xf÷­ŽçsD?³‡0ƈs(àaඬŽÓò‘ë™®'ºZ= É:Ñf÷ì¹íöÔuYN§Cº d•fþéSg9”33Ñ7ßû¦|òã÷Üñ_o¿åþOþé'ÞõЯ•ë€büÇ×~pöÕ3—®~èáÿò÷OŸý£ýà§6+‹‘ð@r03MÝúæÛ¶* ÿû7~ËeD•°„!¨/8Ìc@(¨àµsWh«H2w‘3ŠI¡H6–Séç·Ofv•:›³{òԂvëÚÕF È=À|nÙžÝ)TK×Ú­®‡ˆÓ¬ÝrÛ½wž=yõ H†¯-yœ ÎGF‡ÚÏ  ˜O Ÿ‰‡d„R0 ìfbP kƒ™Xp(`½c»[uŠ¡ DªPdbF‡Ê›× ½\­ áKLS C@ƹªaªÆ%Hi*KNtZn">&\½UÈblËv»jjRLV°B&“ÓµzÞd-§‹ªµN½²uj'“‘J—L. ~÷Zq#¿g÷Mßüi®G[¬ØÙ‘‡/}ÿqZW®5ßý¡$<~×±·–sN±ž9|÷ô—þêïö»mçÒåÇOþØê:c™áÀÀæÕ…ßøÌG¿ùçÿ2}Ó~ ÉÇ>ôÐN½  }vi-žÙ¸öt<"EÃÃù“KÍí²œR õº™³¶šÅ[çß´žÛÄÜphÆø¥7}ÚÝP=pú™×N>ùt&­UÚfc¥sâ–$ÆòÅ‹Œ˜ÁhöÅg_IŽ©¶öƒ—~öí¿ù¢éÁS/¾ô7_ÿÜþ[Ó‰7Ý|øÖ'xÿᨚ><úðÛÞ}ü¶›yòGºlÈ&Ô£©¡‘]€ Éǯ\¼2?upz¬¾]ÜXÛ ‚ŽfF—9ã§^{ydÏhHà Ëg¡¬°€‡I2ލ*ÂZÂÎÆãÉH@Z­\$­Ú?u×­÷Bñ ¹E)2´yfibjRŽhµƒ±˜Ùõ“Ù$…ˆ îûnl(‹Pp{aIÒmwÝstï¡QUU´˜!)tbbHVäÁì >÷¹YoUÛ êp‰ M‹ cP&‘t*ŠéU@¬©õlΘ¼k5%izÐ ¹Œ󙬒€â ÙvB"$Ö¢B‚ ¢§3 JŠŒˆ"KBˆ Ž ATPÆú’'ÞK ä€sˆå‚úþ{¡xƒj ½¬òPÔ/M¢o„ —õüÆõ„¦r¿¡Û76îý¢#á½WÏýÓÃ.3ÎR™¬aD•R{cë! ØcqÑK&êé÷Ä{” K>T1¬+:ûŽë¥‚r@"Žg6l§¸žÃš.ÛA²®„§v?òöO}üCoþ¥wî;|âÀ7ï>xóä¾û÷Ît5ÑΞ©Ìô쮉‘™F­óïßÿ÷`’D³ÆÔÜ(²Iq©ñ…Ïÿ­äDªÂ©ÖÅ•ÜúæV¥Rêš­âÖF»\”°‹{¨Ìjmai(U.ëÂGGë«[Ï<ñª†P#ß:<3;RÝ®-,äóUW ú—bh!™ ˜ `ßúê/_<ØÍ0Û‡>øÔcÏ ªéXíKžµmǶ»øàû}¥Ë™Ì9 ÇcáÁ’L¨1dÄSãž…¹p±¢#Ìè@’‚"!æaY“9 ¨j†[&òjéD ˆ"ó|ßÞh– –0ž§¤àÒ…µÅ»nÞ÷£GŸë´«‚QêRº74xôKß|1–µ[•kËËÁX,Ù‘(‹d#Æ—Ä3bG?ýÙcnHE–·¼Y˜È .ž|Ñ,Ú—~znq=N*n¹{}ëjbzÎj掟HåèÎÄ46Nc©zÇ»ŽƦãcƳßzô?÷§ÝVw 5xýÅÅ¡ýzJÙûÈžÖµx6>„“ ‘NeÆ•±z¹ˆâh½V;6[L  n]R©"§" ¡i×67ïyhß=ï|;ìèX“®¬\úÝßúoþÓß…B'6s…‹¯Ÿ;öà¨aàwÎ4íÖ|Ú€zˆqO“Á‡ßûÞýG(µ3³‡O¿òâòêÂÕí+×/m.]Î OÇÌÄr÷êÜþ}”€HÇi–Ë·Úíx Þ1»õZyüð,6‚ŒRÉòÒÖýw>P3=¿Soµ]`ûRHm”†0Ò²£ÙX20mB£\–•‘Ý3±DÌj8£IýŽƒG—K—•ó¥be§œÏŸ|öGÍvŠ]¾zýâüž¹òv%¿¹žž*ÕMhD>u—€0¢¾0b&ºŒ±Õê4ê•N§Ž59œ4‘!DPæÓ®ÕU5bŒ &X†Ü—.ð[¨M}ˆ1A‚€ú"H}J9ÅûÂ&j€%!LdB»¾¤Jº–1êy„X’B}4(DB Ä™,KaÁ™àÀ¾ôª¹J$B$¥o´é Å–À_Ÿ{q¨7Ì‚=aTß1(nÔ+ÔoqÞßÝ Î{*ÐYëÆtÉE?gH ©™ßã¾ä˜=h»´×X¡Þ:NpÞ+ƒ¨- A%ÉdGºTÔ,ópB'™Tœ0NívXS=›¡@z­UÀu:týÕ‹ÿ÷ÿüô³O=‡g”1BÀ¤–ùóÇ^ íÂüÈ„ëy•šŽ`&ÌmaÖg¦FÆäÔÜЃw¿ùÀÄÜ+k/ù/¾ö³o~îëßüÿ¨zË(;¯óìÓÇi˜yÄl$™e[vÐq˜ì6i.÷-æŸæMÓ6Nœ¶IŽã4æXÆX¶Œ²˜¥‘4£Á3tÞð~8#%ÿµÎšù0ç<çÓìuß×¾®ë÷£üÓ·~øoýðÛ>ö¿=ñÄãçǧ*•¬¦ÈФœ:uAäp 1.” ìlï^3ºiÃjÏæ¥1É@Ðè¥H$#¼¦*8~›)¢Âí®Ñþ€ÚÄ–Á7)wq‡J’üÀeTjN…×Ôõ9ÄB0È}ÓžÊÍ&CƒV­ªÔ‹Ó3µrõè™7ZR¬»£µuݪ KÕ±³S3³“ËÕ¼CpiÙ­U,@S-ÛwÝpóu·gÒÃC‘sK{FZÓ—Ï_Z^´Tã¾ø…'ùóº0ºå†–TÜðç5,;u1véDXëhJ\žËþæ™G³n½º˜ذöбCÛo¼Áðcï»óVƒ m놩B#AV±g¦–ƒa‹ß.Iíò…±ó$$u…Q)§>óªf…ÑKÅIÊõ³'ßúüçÞ')ÑÔ`-;öôÿî­·ÿì _N_>V/h/ýv¯æÒÍ·f«N¢ ˆ’SeJÑjö,ÆÇ(D¹ù½×õ­n^³fÄ)Á|ÞNiÌ.¸×|t=®F{Ú{9U}þ…'59¥'›¸yÝ4s…ÇÞL€AÏv|·^š™Ú¼½šÍ†B¡É…ÅM×õ»uß@VÔ±±ËM‘pSS •ôôT¶­­iùb®R\LDZ<Ï Dbcg,“íÚyCzlÚ¯× ÅåÖ¶Ê4BÙÉe%⫲áÙ¬T.K¼ýÆïF†û=‡P×®”òP4UZ*Ê*'Xœ¹Ž_¬K¥¹dªI‘X@"·üìÜLÍ΄[še)D© ‘4ƒHA’åÖÆžS\p8cpN…íØ²$û¦gÚUI‘£AEÓ4Ý@{Õ4¨ig3† &XRið´×~œ  $YV ! å ­°¸cŒ –¹z2Áh*¸šÎit@¬`êWÎ+F¯•Å•}O΀bܰТ«qžFIX©ô[ r¡FTkH…¨æÚ@Îã¬Q„ 8»B¸œs  ŒåºÍ4ÝÐB1Û±‹¦É!È¡6µ*#‚*İš•™]$š#Ï*‰pòG?þe½œ܇„`N<ìÞrמübyn6›©dÝ:Õ€°ˆ±OιpæÂøÔ|úå·ÞvK©@˜æ—sÅz9VóÅâØØ¥©©¥'žþݾ_þâ§?ùö#ülaqüâñ3¶S¨¸,(ËŒ;:;F¡ŽlM¶÷ìÞ½ãÚ¾¯#Ö*kZ¡”s°J«öðè€åÖ’j¾S£eGª ôôD•P©¸àsª";w휜>W U곓@˜®ï\³þÆ®ÖP¡VmékÒC‘ÙÂüôü¼¯VòeGˆbÄ]†eT´làû>Æ:¦Âq cÏó’J„Z^*’ÌdÝz¥¤ È(w)s…`”bM‘˜<Ø™lJèMr°­YµêòliìÜ9ˆGÚd½©=OvtŒ®êÛÜÓåP.\—–ÓÇÎiNó`zb,h„.™¼üæÅÉ©æA™€ö¹t±5,_N—œJ ûÅËSçcû¶=_zcÿ[£›G\•) Dü‡R4î ^·júRþ­W>ýð#g.ŒÞÿb2lII—Ož9uùøÌ¥ùÛoÝ$ØÛ±®¥m•Ž¡!u`„,w¡UW9±níê…ª))µ®®f+ RËgãM k]/LªaùšÍ[¶o^c™ÚÉÃGzš›´®ðc=uìWßþŸ‡~öØÞÿºvëVË3âšA9ÕŒfîØHpÊ8TÀ›û^‚z€šn$f4'ÂÙÂòÄÜ¥x, F@$á„&Ξën3"Qè1×õ³ÅlÕs;º;5UÜUÊy#‘œŸ›Og*¾™[¿k§B4Z«,—sž)P”`)ÁD%“‡C™bB ƒ2H–¤×~óÖèÚaE5¥žW Å£íMƒËéÂÜ©‹S—ßîíÊækN½ž+g\æ2 Ž CU]ÁŠ L5·ÎOMôõø‚0×Gœê[u»µ»‰ ¥1wø¦cÛf4nnïÄûŽG G¢2VDz {ŽãX6ã~8ø¾+Éš]­sè#=×–E„4Õ@˜PŸb ’†O–%ˆ àˆ0ƘL†Š,ËŠB° M è*ËY ˆF“†«óêlõu W ^pŭиâC§1È5f'„!€+V€ÙŸ?¸ø‚3ÑØ!€y»RY€IŠd1u…€A€piøûÔ´'|%¡Oi5ŸWë6×çÓ5‹å}G†r[B¼ÖÖ;ª M’°Ï%ßò<÷„_­^<}öô;¯îÝ÷üÌøq#Ýлjã@OkG¡R,3*#b2—Qvéâd:“ &u ùÙâÌÌ´ôä|©à{®†€¤IÍ©ÅåÙ³gÆžzìÉ_þç¿ÍfÏ­^ÛÑÜ2P*S  È@ 4ÜœJ¡Š9::èåhSoWݪM;hÕíT4™Åžöa"Žƒ­Á!Pj6úÛ»‡¶:>Y,f¤€´s÷=ÕT1Q1wy¡°05w±n›Z<°ëž‚A%” ì¸iÇøÔøÜé4hÕbªÌ4¢+@ÖU$c×3…ÀŠ'¨ëÊÊ¥J¥œÓÀƒœ B@Ò#„Ø(ˆè²]Û±xy¹hz¾¯"F=_(~:³´4¿˜lÑÉÀÂDµÆjSS噹)¡@Ä<–ŠÒAšãºTUÓqÊ¥* HccÓ{>üGF¸?ŒT|WRœþžð¥™±‡ÏöÜ®©üùÇŸÝ´ýÚ3§/tv·!ÝÄþØBNd|P£4—é2’Õb!,©ç¥ÄæNžŠ$T'S‰$¢µ‚(VVûU­–+6‡FÖŽx\£ŠÉÜ`gOkÙ‚ËRqP†J¡fió`y¦¾j81Ðß§GYkol÷u7´EÚæ+ÙjI nØöúÛ‡Žž:Ñm×\ñµ¯~í¡ŸüUA³d9 AU•Yœ¹@prqº–ÍÍÌ'.Î;vnºü_ÿýð÷ìVC J©oÖsóMá§Lp©ÁD‘lk•%ÝÇ¡ë*@«)ùb1ÚUèûZ½îxLrÊe#VBaêK3´h Pãˆj„m³î¹Vy~iõ蚲閼„‘¬,ËD}ë…þ £ãc“ù…Y×ZŒéÁJ¹µèᄌ‘‹*²ÜÒ‘ŒEš…âDbmˆq½VœY¬ %¨ÀTpÆy­Z¥ÀÓPDI–òŸyáXD!Šç8Š‚ƒÁ¸ë{œ ß÷|ßA†T(š,8r<3ùŽË˜ÑTA,ûÜŒD„1Hp Àˆ"B‚²"k²‚å ˜@Øp¹CŒcŒ0†4:KW6¾«~p¥”A€Æ,µ2x­Ô!_™Æäz°’¼:J!€>ø+ÕÉ¢7ºÑDÊ}çÐëïÔ-›Z,Þ,8 tâJ‰2\i¢AĹèXÓµ@ˆçœHvÀP=OxõH»ßÑ= è€` sGÔœÒôBNW CxfvæâøôñýϽðŽc{o¿ôÊ“¯>;úÔÛ‡Ož<=N½¢aàtÆ¡¨fºf0(w6…Z"áÖŽÎͽ«BQ…cuv*u uq $AIÈ¡p¨•ÈĶðl!ÇÜב’‚Ьùõj.EÛ:(ÇõzÞ©  ôX›_÷ûF…,>sÿgâaU[9ú»·ä€‰f<ß÷|™µ&{§æçÓÔ͸¹’9uá’T†WßÐÚ= @<Ù¥Õ‹A‚æ,‡dMÀqLA¨‡}EÖdáëÍ©jY8fMÅP‘õlyÊ`!?OICÜ¢Ì*×9‡HèÈæI„#Ë/lßvKK´]Õ4YÈÈ«U,>;·pxâI‹¥ÉØÉƒºÖêÝ7ï„ `¹À*—üÊb&$5`J 0)375[(´èÑhÀ±Õ"F˜yybG.¼R¸ûÆ.NÊ…\å|áæ=ÛOœ<2W^xíÐi¦ze^¨ù¥Ã³½]«»;»š"ÉP<´ö†á³s‡«åÌä…™‹3ÇækÜ6Ãsõ‰Î¶U_ýêg2þ䦷mî®í·Ç‚kó³®Þœ‹»+çÒ“õi—2¢©ož‹'ƒæ'£V)W†PõýÜü\ŽŠâûï¿ÛWük6¿û“¼Ûá•Cï¼õ‰|jõÆÕ?øîoQù¼Jh—¡¨ßøË¿zõå'8³Ž¾u~Çm[¶®º­Z±9"É;n»ù³ïùÀ=·mjí܉†šYZøð½Ÿ¸ãîÛP$¬MÊsŠI5µQÛ30>úÎ3ï}ï½–0‹Ê¨eb{[.–OU+¨†5#ìÛÅ ¿d΃ÉHwW“g#ϪãZ¡”ãÔs nayQžœ,ÚEÛAž¨'"]—Ƨ¡æR¥š·3}í½­mM®ðÄ€Cß÷RqîC"ŠÆŸM_š ØM4µb9‚ dBxŽW.æ\Ó &¢϶`z0êxžË}#&× UÏ­Fe…„‚q `Ÿº’®y¾Ct¢‡"Že)a”Bˆl³îrWUˆ*i”ûˆà•îc±RŠ Äa,aŒ5ÍÐ4 c‡I‚è*s‹  ÆðJŸX)éC?˜l®dk¼"ÓCÔø"°r†5¬Z¬a‚h\RB!Â"܈)®´ÁÃ+Ø0À¹ !}ãöíš®Lˆ¤p„àð÷4ixŰçŒùX"âÆÔ&iJ¬£•ÉN¨¹+ ¤¨GbɸSª³{¸f IDATË ârß]»¦ç«û@s4ÐC½IjY{ó|>?ïP/¨è[oÛù…û>ñ¾Þó•?ÿò¿ó_ßû±{׬]ýŸÿȽ÷<ëé.²m~ñÔÅ}ß~ýØñ:¯w÷öýë7ÿÎCÂ¥˜pX.šq=T2Ò¿~af9_YF¶Xš/yŽyôÜYEÄb-!Å(ç³Óg·"$Ký@ It>rôÒ|F üÎ÷.; >þ|ÅÎkšê'[..Ï\¬æ.§Ñâ\Ö/§CÁÈ@rÕâø’Ë¦ž:ù<–¤JvÙu—’í-ÑUû}¾Éùô®›ÚÃ8Ü>aT¨=—{Ô­z•jÕñÍ*B´jÚŽYjJÄl« †$—SˆMM‰¨Æ±¬ø\3X±n ê5¾÷µ§,šáÛf$©…¨xAÈd 7mÛo<óó£O¿L”p”…¸pûÖlMh ÐBeÉr”lº^Íø‚»/üöíq{²ELÔTÓ®Z©ù£‡Æ’í.†þ·~ñÃOÞ÷ñÆê-7,/U,½´ÿÄ7~,4ܦG4©Þ<¨Ç¨ @IXö<*¡YÊôñƒçßzã{¥¢{ì¥3×޲嚮å¹G2Ë…ÿûõ¿ŸË½Xô¬Ö®¾¾AµàÓ¡®­: %Bñ®ÎþÕrçÙ£OìlyÏ©éC[wÜ‚pÊOöǯј>ŸnoÙuíÍ-°ókßúZĈþÇÿ@†Î¶o=ªœ ;?ÿů/ÍW>ûévlíNtvŒfk3ïýà]›Ö_ÛÖò¹ÿóÝï+‰.ϱ1Fï<û\kWëèšm¬°±3'ößÿÀGïijî”u]hú]ï6D¨ZÉï{ý?——Ǥ ªxɬ’˜ ¶­Ûšè¢>ûä3ÉÕ©óãó>q›Û»ì’åÙÕÌ|šíš ªõÅx[Ór­$ÕÊôD÷è°  µ'©mifQSºjëïáTøž·”žÇÃ̆Z@Hæ”UseË/«ªO¶ÉÂC|‚€Š¹K&8æ¡x Ù1ëfÝÔºªÌñmß„(t#@$Y"„"É÷=#c PÏ…D¢ÔeÔ¯WJ@=V¥pü¾REx#™‰B I’ c™ ( ÄaDÐ R"„áŠÉýê΀_îÀóúÕšä+ž,ÔXü8€b…$øŠÙJ4䮕‡_é m8¸ˆ3Äd€ 5ÙÔŠ!‚œÃOC%ƒ¯4Bp ˜ï6BAˆ$ ÇbµJµ^.™4[¹X/Š——–YÆ‹:]]ZfçÞµP™.0¦¤¿­×Î;ƒF΢º[4{RjKW|ç賡Cããé–Ö¶ç_z¥–.?úÄ“]k»G6`H›ckïlÏdϽñÒá…¹b ¹õ³úµ¹…Ò½w~:JX¾ýúkã““g9ЦgÇÓod‹¯=üVkWKXÝ÷žn[¿'!ñ¿ÿÚ·“±uªéWêå…ùRù¼ˆVj’Y°du‰ø°2?™À¾@säÀáqÕ_½êº‰ñ±™|EM'æ}øÃïéêìÚ¸Þ\ð¦'s¯î}\ñ½–¾ääÅóË Õª­{íâ“OýÊ×­‘ö|û¾mH©¡þ^Æ©@À.™©T¯O €…ïÛÕÊñG>÷…¯Þ´ûéØO?û“}cUxm9SÎæÊn‘­éoŸ^šL3Ϭf+o<¢«a˜¬ÂX¸ {Ü­Õ¢©.Fi¢½óÔÙq®s=U¥ØkjêZ?°ær¢ŒY"P¯är)q-Ö”êò6º¦ €°\);1™_˜¨ñŸ f§çt5E5T]’ˆ0¨nÚ‰H\Õ•T² 9‰ †|Ÿú܆"Ü£Œ3êÕYC ,û®ƒU3˜#Q$õ- TA`Ì®Õ|ßQUU74,IÆ„ï:œ3„0F!,8ã”q.0Æ"¥àaŒàJhƒ¯ƒn`t +¸Ô+œ«×z JX£}oŰÎ9G]Aå4‚b¬Æ>WBˆWºÿøJK€€C1&àJ³)pÁ眳•Àa¢p’YÎÍ1î°.”ºŸóJ™K&“Éb¹à×l‡U *ŒZ¸h‰Ÿéô™ssùœÔã=I ZÂ$‹z@0Õ’DBÃC=Øo $AÆå?}굓‡Ïüê×?¸¦ïikoŽ%›øÄÇwW8!ÌœŸ’¶¢2=ª6%’TˆÅ¼f¼ä{õŒÍêU"`ÄÉÖ–ºOôhŒ²š…À¤{tTu1à~o[»O… ¬TPÕb×,Þ÷±O[éºÂÉB!Sô'€zùwûò‹…`P‹¥Zæ3Õþžžõׯ*p¨3îû¸jk™EOø©¾hw0òÌ ¯(ª“D[gÜ‘‘I™OÝbÑ”$ÊKø*±ý™ÉôB¶L žŽ©1‰¸ $€pE,Ô4iiÙ hÄÂ0n±Ë•…L ®é†W¶ÜºÝÙÙE‘u½Ý—/ž7d®$ÈHg!‘*¢£í½õlÙåqxnòœŠì|Ùš¼0ŸêJ2§VñÅÅÓz²Ù-Qß\+é¬ãÐäÙ{î»–YÓÓå“<ñ#HÓªc½þâ‘°¦ËJÇøÒžîžî¦¡žÎ5f­²l^ÌL,vôomw %5àF"1ÔŽ½’;}äw±Ž3yß¾prÊ#8¡üW_þÂu¹}ûÀµÙV"jJÇÞ8 7¿8¶õ†ƒé|šSSÖR^<Ú±åÚHHÉYv,nö7µÕ—ò­M¡5×vË›z†[.œ˜,Û"¨»oÜoÅz<Ð"û»oݼç¾ûýïמ}æßËfM;‘D$(U ¥`Šhj ¡e¤µ Ñ[6R×–ybüäƒßýÕßýýˆ £-6¢Bh¤"ëÖßD(ö\ĈÄÑD›Ëhe¬ªc™|.ïLÊDvêu!ÜòŒµæú>VA) )jÝs}}Ó—û‡;PÆ/§ZfÎO-\†ÂœZ8Mö" 8g óã–†û7-ÏMP(\¶°´‰,é]•t#!Ù®E}îR'NB4Y«ÖkZ(Ĉ$WJEßµßŲ$#,õ„bhHp( qèÔ+’ªQ%Yõ|_ 4-Ld™sˆ t=Ç÷=Á¸‘2fŒû¾C©‡V4•AÄ9¿ZR|ÕŽ€DW+¯€pXãm|eWiÏ\\™–ĸ ø=¢°‘¹°A²‡¿gz5F,Þ½8l@_Ë9BAãµò ‚ ’J&—Y˜ý…gŽÜçy5Ôhgf¬j–ˆ óÕ¼kJu(ü°Í¹– Ô æ–¸Â|&nØ´*_Èüõ×ÿöCïÿs#œPeÞÖÿäÇîé ô”aýƒï¹ïÆv¬j]H×oÙ<´æºõCª‘ÒdOUÚOå.ônli6½ô˽™Âåõ½½Ðò9G},-æ ~Æóy¹\öë’µ‹Õ²WÈR~ɪø£ÃC×–æ—ŠËs†D£F((©•Zyf5-'ãøòr1l~ùù½ŸÿòÇQ„ì›Ôs«*’ŽŸv¹VªÎžy©dÛõ» µçè' áE/[(UªKSCÖn¿ýæîîATÇéjÕ$LdEÔ“©°¡…1&‹f  5!éQhÃ*SA¡¼Œ”|§&¨ëbÇ®5]‚H—4%L…œ@Ñ6± )ªј Is3 ŠÄô¥£m˜¹ˆ2~qz:„¡PëÙÙñ` À€˜ÊØCƒ@,Þè½T:3Y»8ë.UvÞºjüÂl*¼ëæÞ;N;ž7ù¹sšwoýøûm¦eKyVÀñpÓ·î‰hÉc‡÷.fÏôuܵî>³+ßëËÌjk ÖÍvƒÅ³¹%+ÓK‹¯üö×¼P®˜ù±™Ë×\³ïÔ3kÖšåå%æ®Ù°Ö)Ö¯Ù±1¾é¶¡ìñš¥Àîp‡Äõ­dŠŸ;³jÍvË)GB‘P2•^ÈͲ,t¤(È«y¯o(õ¹|jpípT&o?ýæù#Ï]^ŸŸYžÌLí~ÿŽ ›ïEãà+û‘8。|1ìÔ5Ceœsù¬–w&Ú“ÝœSÂÑÏìýëøJ[ëz@B_ßÛ{o'RõjA.ж±I·%’=mËée¯Å:zúàê]Ý^EÖ‚anû™¥…B~Æ­zA…0ßö6sî\.7HJ(U*f¡ÕxøØáh“§Ç"©„ºªgø™ß¾ŠÚ–¨J^™µ-Ù{ü­7XIšN™g;…ŽŽþ¡Ö¾zñÍ—,, V*…¹ruamë†{wÝ>nK6µ./-zÔt))׋ĀÔ¯J÷ÐmÆR%M¢¶‰†=I2’B\§\ÏY®OcÌ-‰ÂE¹ IJ,[¢V¬¾4Æ|QÈ,]Φ1P‚!„L`£jÕÛ‹Jr©V´m7ˆ}[`GXE§¾´”iNFM;ž››YµqÕÔü\­æ#zOCz±Á‘Ñ“‡ÇO^¾ô§ù9âë—O¹ÿã÷toÜ꺴%Ú?±0ÛÜÓ9}v®¿¯oëM×ß³çý×oº)&áTKD®º#‰âr}hu¼”w¸GKõ¥-×ôÙUX¨:·~욣¯O¿üΫMjsDk;î¹½,g‡V¸VD²½iâüR îWË ¦ç¥·³ùâùó’¬ÖêÍMƒS'gwlZíNY²;xíZ½«=;™‘$ù­ÃãóÙéz¶þÖãûöîûù /¿˜)ÚÄ µjÁõ½zÑó« F’@0qiÎ’\êøÂJ½’_šÛ¹óF ùõŽ~±T\LE¤¢ùb)¹¾—W: ËËF\ Æ:ÆO½ñæ=ÇŽž µt55ÔËå…túòTšEý¨Þ,±àø©ÃE;Ë‘ GÐñ`°¥¥Ix°wHÇòrzJ×TDu (³íèis,ÛÅ5%¢Iqë.‘Q­²l› Èl¯ž·+¦ø‚Yu³Z)¨²Ì¨àLÔŠUQUã‚i†J9À„¢q"ëŒzº¡I’Z­W´@À³-Y"”R¢jXRÌj`hVëŽeBeYÅ’Âà+‹˜h°² @”rH}ˆ €XtµÐêÊ 6´£+‰ÁÆúwE_!à\}çŠ%@£ƒtÅ”%ÐÑxÊ £µa W$²¾¢V5üôWf9!!Áh¨^*ïá•ÿǯïÛÿëá5}·¿ïŽOñ:»×ùœ1”Šl†®^?,oïlkéìí¯WíScåJú¶»ný˯þÝ?~ýïNN\ŒÊ¡—žyn"3oèë܈לxO€8Ê£?V²³ ¤5;s*­|â¾wc‹9ub!]˜žž´¼ªBèRÁ[˜ëê!¾ÜÕQ” `nª%B˜Œt4(!*:¬®…mq­\®XÂT (22ÀÒôÔƒü2 ÜîÖ¡je.Õ*f2ÿòÿýMkt5ânɱ¤ªTæøsóão?Þ¼~UWû†ô¢k›w¿wG8ÂHÊ\ÎG"q]/FÚ¢&°k¸P¯{˜ƒ@ù”ß«Y¾í¸†! ˆ1£¶g•j&·<¨0=¡úŠlÙÀД$ û†aÜvç&¾ã[̾«aªi·Ž!á5 Â,è1 ñ1Q3óéxDM¦Zd¡Iª—ÌÖh0Ú”4cðhi‰`Iîï*Õ«F ZÓ²Ln)aIA¡ R@U§ËyÛÌçbñ6Y ™FZa@ ç–3ËKS2Û6ß:73¡Gâ¿øþO·ßz“¬i{>õžuÛwèjt¦š‹{C2ö…X3KÕåbýðïN½yø‘7ß8jͼ—¹gtÇôôòL~Æ®y×Þ±g6ïï?þZ"¼4¿˜Ë–‡º¶ÌN/®Ü6ÔÚ©¢‹§/RnnN¡’¤É(Ö‹ÑÎ]ö$æyõZg÷r1S'f»ÖÌ©Ya…þ-#ÝMƒ‹õô?þ¡ôØô7þùŸÏ:d3Ów9­ä+UK…/žZ^Å9åX¿tÞu,0ê»Ùì„4.Žä K$Š¥¬Å9ÓÝÁk7ÕçØãÿõÐ;¯=¹ïÕgG·Îš+‰¢(‹™…ªìbÞ•da„bS“$Z.WëÙrÅ®*yÅ"!gòÙüÜòüôÅTW‹DÀ9õY¡Rléê]š(è!# K.¦§÷ŒP@WÃX‚ PMm¹ŠC¨RªG“ ¿Î3‹³¸\ ùõZH(‰3Ê26Œ˜ëû†¡I†\pÊŒ`p€d9”L*„ , !Uó}ßsm"I!„,+²¢"L®ÐK!$©aðß§öŒ|c³k(à‚‰zóÕΙÆö¯œUàÊÑ׊V4­«{à 4‡s!@ÃŒÞølc/]y+påa+a¡Æ/$¿ 0l¸ ˜¸ÅÊ÷þéÿþõ—H/œ¼éÝ·Ýùûï}ÏGFÖ 9–t¨ÉÀA€QßW("!¤¹8f$ä~äÑç~÷æs÷¼{û¿}û?uÿ—Í’û›G9väD…Öˆ¯»aõGÞ÷¡jÞ{♯=¿ÿí‰c^OMŸìêhKOä(sOŸ¾Üd„ n=þì+Ѹ’0lz²î:N[oj¨s–b=õk•¡¦xPNp } J¦ºIcŒ›[]ΧɕÁh<•Ò ½R­…êùÓg¾öó¯ï¼n§‹Ôy;Ó¥´.--Y¦ª?ûå“Ð˶ƚ+¹%∠@ggÛÿüà§Õù¥|6wüäIǬŒ¯¹éý·¡<÷â«#b×ÜÅ…Œã[½Ã­éêBS")QfSW‘I$nTLO–° ˆ3•SÊBÅsN±cR΀Ââ¬V§ª„sµüõ7_s×{?ù'ô@E˜£ÃÛëuLŲ|=F3€±ìQ " …)KÓé…b)¿TÑdJtÕ÷e–ëžÉYPOb>’8’°k¾ï(€—–*ˆ„=TéÖd5üê‘ÙL6wgüL‹®fsiYֹΚWÿÕ?rjñÒÃßùqnar!sy"›ŒŸ8pÈõÄ#?ûU¸£ÝòýP<|Ç'ßµåºíçÇû‡“)=\uÊ^Õ./-<ñz{³‘¹\Øÿæ¾[Þu[zêLÿæD~rqòì>ž³|ò¡[6½«\µ˜¥ ôNNœUt£µ»½f¹{ß~It…¢¸¯½‹,zE?hM [RÈ|wbjº^.ejåêR¨U ëå)ë®»?–´ ¶ÿà?~–›ÿÁ¯¾iËf¬%ôçóÿû—|mùìøÚkv À‘À“ççã‰VH âĉ‹Ý#}:¹Ü\MÕÛôV½Ì^yíëoÚñ®û>²zóuÃ;ÑÀý|e>[2óÞË/>͔ԡÀ4_B¯í?pq||~jyõDsÌ4+È3›ãM3ÓSÔ.+„ƒ:Dz¤ëÆXÝ.P«Ö×3:15îØ”`ƒ¹4½œ¶ü !j0#†Ê¸€esKM©öL!kÅL%³¸PÈ/BN-Ó«Ùf ¡šV½©£ƒQ¤h𬆠ç>õ A²€DŠI6ã@\ˆyŽË*š¡jº®„¨€0–d媠Î(€5°WióWçžÆtF¥»êj—ß45ñÀzH®PU †V Ðð÷ÀhÞH0‹«0VÈϰâ6ŠMBΪ™Ú¿ýµ»î»ç£Ÿ½Ș`!8 ɘ¹ìyØeþ>ÿ'²,]÷¾…¤Ïd]ÄZšþäãwlºí]m±X9?û­ùû±‹SÀ3.é6ö… ÷|ñ #<+[ƒ,ë{7(¼§\\˜/#á,$¿=¶!ÚŠ8ßwüØ—îýÀ‹¯ì«–ø¦Ñ‘º¿<!_¸<ô¯Ù¼.=)Ü¥Œ g‹Ó5BÜÄÉ/ûv¶(’Ÿ+N["ØÒ9ËÎA‚xìÛ÷£?¾ñÖÃÚt飻?wðÀÙŹ½|r|÷çú=w°«KNysÙiê°" ËV©ò»×ößuó­±JÜqƒù[7\ÿðO tt:²¿»/aBàQÚ9´þ»ù©7/h@n•jj À0b&Ó(Ã@@’Œ¾EÔ¨O-Ë"¾l3‡ÚîØŠ•)OФ¼óÓçY÷„  lòZ¨<6DU¯Ñ<ä¢^*ÁŽÖ6]/yx°ƒÐóna÷®m Ãxýì)·VnjRÒ‹Õ,òM$úšš=–„£jrªYÝÙ´=,èÒìÙüÙêiEê-ŽÏÏ]·~ÍÎ;n€„ƒ‘ ÔÔJ€pÖÙÞ$fŠ…å\ 8´vts9_\=êŒUwÜ9¢cdh5=Zë‹¶¾rðõ{ŒÄšžÓ 29=#‰:åÆ`gÇ;oï×e¼÷™Çg²Ó]îÀìø _r>rÿ—'ÎOÿÑ?ücȪï¾óšh"ÒÝ“Úró¶ÃÞyó•Õ[‡–Ï0 þèÏßÿ7_Œ-kÕZ^2F­…¼Co-X ýüg¿ÿ‹£Š\ºE³<<ÚÑ×3x¶å¹…±“çÛÔÑîÕ”þå§ÏÉ<ôØ“¿h‹…£jÐa+è…W÷þÅŸEÂë†}¹²v÷ª±£[ðšÅ«d†WU)AÐÔÛB1I&Z¥8þíÏžÙдyË{-‹j²R+©ÇÏí¿vdí¯ùAÎ)=sò˜ òк¾ÑU«€$á²úÒ;?ÿèÝòö‹¿ë½¾M’TêQ!D~iA 6)©RZ tθgÕk‹U"-LUTàº.‰ªÅYF0šÏÍ*2©]¢Hn­¦„â¢z¥"¨×ÚÞ‰ E‰¢RDZ̚lhHÖ%EŽ E‰$ . ÆžëøÌ'ŠŠ ¦’²A{>åŒ5Ä"L$ !¥>qP«™r€„VVÁFÙËŠ¿éÊõ{˜ ÿ?q¾QžvÁUáÊã B4À±¼ahà½[Ws=üž~ˆÐU’q€Ø €ž4þìßÞºKÒ4‰(™PÕƒÙåù?ôû?øÅâòÔ®›¶Q€DMçßø®»¯Ýu'R”Û?ü™âtæÛÿõŸŸúàŸ¼|L@Èõ‰D²YUNœ7Ë«€m»W÷÷Þðü£G_Ú÷F){ŽÙ¥’É„#˜dc% -™Ž(‘Ò\fƳ¤U뵡{îiáÔEgÝæªh dº¢»2jñªÕn(ž3ÅœµÅ¹êæ‘~ÙÁu« ¡7^Fª‰jï³'ÿ÷Æí;¯¿v»W-mÙÖW˜*ßüÀAS~¶857Ÿ­Î'Z"®ãf¬òtÍŽGƒ{ùe±XR Iëlÿ»î˜>U9r|4ÐR›Ëš>Y—7Sܼ¶C Ç 0F‰€Üåu×ж!ô<( ™`$‰$Z±Ž5©"Ès…²%cMg–ƺ®q…øXU5Û§hØ*ðÃ,ZŽeKÁ€/‡Zƒ(™O/žšlïOZ&Íçf— uCÖ<• Uh:÷ 2ß×V_7ÝÂÛo_Zœ˜XšºùžµTBçbCOÓ‰‹ÏϤKóóUË¥ÅË‹eZ=ýê¹ùì<µP,97yø‰—~âÕ2ÿþÝïÜõ±;¹i#%XY®Î–@HÉ^p>û¥/±|3¤u¦Èu‹éaŠ'Æ/N›Õ…d¢óòØáøÅé³çÞ¸~óuÅJzßÞ_ïºmè3Ÿÿãº+äžÏå¼+û“ IDAT¹2Ô< %ý}‡[b­Åª¯íöf£®½rìõ@wg%WÖãrÔh-+åóÓc/üö©¯üÕÿÙ}ß­í=P2þø3òüSo•˜ºïÄé@·…w]÷îéƒgÌJÁÔTŽYn‘OL-™ŽûúoóÛýb¤%ì©…Z±Nd9W™}ûìþR¹¼f´ÏsÃ-]­( CÑŠƒ¨`ŽCƒÑÐ[¯¾|nÿÞ¡á"ä¡WŸÝ»°pz½¯>ÞžDcÕÚÕk¶lX³u3†üÀ‰w˜µ`B—:_{åMóCñ¸¦¡@€('œÝÒY7¹eW‘ˆo³|!ìh²B ¡p\ÇGºRž/·¯nUåxݬ!MVt#Œ1@W*e|%– ”$Œ0ó|zÄ™H! Á¹/` $Y–Öõ ÂXA=ß÷=!8ãLp•B(”$‰Ò·ƒNÃd V6hÅ|~ÕxW. WÚׯʬT8\©zGâ*’~¥ªÿÁ@† „‚ÆuáŠ#õj33_Aݯб‡SÎcˆ@ˆð}(„ Ì­Z¹ôìO¾õ¯_þÒ§MÙüÎ#ö•üæÚÑí$ ÆHBØ7=ÄÀÃÿñÍ{ðï¾z¤9*é’ê¹®ÀºÔ¡& *“‡c#Ñæx²í#N}ï·?ÓCŽ¡£âr¦ìÕªå*`jn~6[à¼5vªœ-:^þòäxïH_0VrJ³¹ÃÎåæ/ÎW Ç’K³6pj.dB!ÍP’UM/˜ž"°‹i’†0ûÅožžË¼óîû^<üÂW¿ñÇ Ó—_y‰Ëz¼cÑÜbWYœJ§ëjÈÞ¶kW{ßM¾+ ÇB¢žÛ>úâã È™CÈÌêÇ?ü¹ö ¹äáïÿÒ­”ê•yæ;«Ö ¬ßZßyãîR®ª„%«Hbž+ª…dèxˆ™@N-§Vaµ|>@1gÜcD•µ]…DŠìLÆÐ”š+t€¨Ë”@ŽjXXÔr¡N…U3ßw°¢×ܼy÷-;ïøÐ}AÚÜ¿¥¿kãžø7íØ)|Ïu…%QIÕL%ãdÞxtìîß[‚ÁUýƒ¾'ÍLe[[ÃfMFF “µ49zÍê‘…33ùÊl[ª½Š²M´è´ö*Œ ¿Ì2“æÔÅñ°Ò~iîB¨©ÿ‘ý•bé–ÛöÌN·õYA%‘™?5ðžk®î¹vsKs·„ઞ–‘ë×…²ñB&???B*é@rpêäÄ G^ÿÀÎ=Sã“SsG>ò™=÷úã«Z<šž™*dkM}±½ð?ƒ]Aƒ–æÓD<jWäPYdÿ響~ðð¹5ë¶o[×þæç^~ùoÛ¾ûÆÍÛ>õ‰û‡W ”Köá7ÚTŽØêžOß3ØÖÕ5ܽ>øèO[ŠHI}àŇû•=ke»F?”Í,O/Îç—ÒËËSÓ‡¶nÝÈLŠ$ û”×íÙ±ékûÃ!ݲ]«×ŠyIEŽ_Sl¶%aYV1It4ÅÛG·®¿µ<[˜8u ·¼àóÜêÕ[JD'A¸ ñâò…áÁÍN½ i퀒B¹'K @T‹Çܪ›´ ÎìRÁwj³33·m >––%bDcŽås¤ÔËÅR![7+SIVðJ~…SÊ ÂËã®k+iгÇaŒbŒ ²¬Êš®(*§”ú>õ]ßw)õ…à¨QWŽˆ!hÅ•)~(5N#ÔP¿¯à@+M¡W<í@ÔP¥0jx®p¥ÑJÔP¬à%À¸*€£þôÊʯ|´!¾ !<¾"a5°;@„1àBH>»pöôw¾ý·ñ—ÿg±8÷oÿúÝ¿þÊß55oV$…cD`Œ!õ—ææö?óÓO~ò“Ç0:ûnßdÐÚÖ¢"U’wÆ4…#ºÌ7Œt3æ0ÃÛд½îr&QËcDCR@× î‘䨌 VÂR@‰u4¥d•£9vðòKÏ}ÿìÅS‰„VœÊ¦ssŽÏTá{Ðñ„ uÿøñcÀw­ZYb¨é¼àÕŸ}ì…·ö=ý‰¿xÀ®áO=p÷àM7¯‰Ýúú±7>÷ùÏõë-óÇ÷Õrú¶{¶ûÐ E›?qöÜQ «$(K*Qö$6~ìüÔø…@80;µàà2óÞOÝ_ÈB§îz¥¸è»®ç¹ï½gÓozâÈ‘CÉ&bq Mˆ…]!5G@†Úªx>$Xž‰…L)–©ãØ ô ëÜ–Tr!“Ó’4L`ˆpXo 1%K:ˆ*ªë—\I¸e?yð°ï/ßxó­!öé<µ—CñÝw}iÏ–-Ô}7D6n{ÿ6—¢¶üøo“UxúÔñ·^?ÃtôÚ›Ë%¤ðÜÙô¹Ñk6r)œ1K¹j>ÜÙÛ֔İOåžX¼0au߆û3ËÌ)¿X)3_eH=1õæmï¾ïè‘#^]50 ·oùðû,MY7°M’"­ÉkÕ¯o9ãïýñÃãKg^~éÈÌòÒM×Ý, ùü¹#ÛVmÙ~KîÜ’[sÿÕ¾øþ¼·mSñÃ8Ü×9¸÷Ù皛ڈ¢ø®­q¥X¨9å»®}ÿÝ4k­z4_“k֜֠r D@0qev»r³xåxBΣ!Œ B D1ŸŸÏΧÇΜY7ðùû?^…˜–ž›)Tò±h4M‰È€];wþÔÙ'6 ×‘P6¬ë˜dR¾´<4ÐZGÏ\èÝÐâd4‡6lÝôÔ£¯ ]ã@…Àv  5¢à 9ŠÚ¬yüÂôEÕèÔd_‡}GJϤƒÁ8fD“×ëïîJJmÑè¼9»¶{륩™ãNògPgž%–4 $-³s“çÎ_ß÷öû?vŸ7¾‹E:Ú».ÌKüü§?¥‚ØØØë«¯éX8]=:¿·¶Ìl ä /¹y!„Êo¶gqеßó=«ýzÍ HC½«™®"YÌMfÂ&Ë´ o¾áö-»~53_L›¨qª•<‡ dQ4ìS(¤¾¦è2ómÀe.›‚BNg¦–jõ:Ö1»˜ *ÖU3cÏ•°!T`LÓÙ¼¡)eÓV\Yjœ‹zäÍ7÷xóÂæÞÎÁ ݽ[vNœ›&¸~FÌÇÂm¬¸Œ=yn|®T»ÿSçf×UžíµÖî{ŸÞçœ)gúŒF3ÒHšQ—e¹áŠ Æ6¦—˜B¨I®BøB>0-4c ƶlK¶$[½ŒÊHÓûé½ì³û^ëûqf—~èšs¤ù¹®õ¾ëyîûý{žýöò®[fÈŒ€NY\º1kR|ïÀ@Ox¨¤”®/Ìõ·Æ ÊêÄ KŸ|ð‰¥°,ïã\³ÕÑãºtúõ@ÿØÊ«×3±lOÐik¡¡žžzªQÌ'þñï¾øÊkGZcql!ÖñÞ=ö³oþ‡Ç7lZÅ­ã“×0°r‡Ø?yrñÜÊEG—{y­PàúÕµÞXj>7?»X8pÇ£‹—nxœ$øºz:Û†bÿþO_|Û‡”¬995…<Ø[×ë óóÿþUß-‘‡»;_LK$öËþf!±°cd ÂŒääÒÉÑþ=Wg/?ò8˜_÷¼ËÃó_ýãS÷Þ÷ÁFõ*ßʶ|ç_0­\ æc fâÌU—ÓeÙt­¤Lqùí»Ò5U¢9mCÓ2L\EÞ.k*¢@,g[(qmñàøÞRrÊGêu šfëçÒf*Q9yõM»ûÞùè»O¾ˆ°!xÚ°mL®L9e Elcôº²8=gàªÛÐ-Q4 i„hA¨ª€1«Eµ\ÊZ–¥Éu$`—ó9—Ïáq‡—f¦¥£ý–Þ`)šaYˆiµV/íñ.L€iD–eš¦š´t„šFÀõ8BE#Š"ÍCBhЦh!BCp“ÍÂ7 ëF.€ $aB Bp3 ASƒ1 t¢ŒšáS¼‘‰ÀÍŒ˜Š@„Ö_%„Möhs‚lf/`³l„Ø&9S{ê§?´²uç¾wúh(Öà ˜_Î,ÍžN'g)‰‡·[bo}5³8qâpÙP¡A6íZ¸Xóúœ‰óÙ½· ^™Î'Ke‡“v…ýNƒ‚Œ-x$Ó‡_9J€¶J6U/Ë-}AŸË¹p&±elhÛ¶Ûoœ¼¸\d~ðѺb N)µ¸öôOxç}÷mêÛœ\[+zgK ô˜¦ÐP²„óäáNÜ<|¢d9 9 T#:’…F÷?|"Ô=¶)Þm! zÑŽLLT©>öÈý©tivé:Í3sWW—_{ð¡wM­°*ÄCÛ5IcbÃ6ˆµXÚ%ý½=³7&÷ì½_ËemDŽp<àZ™»¼š¢Ý]V*ãj‹VËÖ}~â»_ÿ"ê!R€E"0†J3D"eJ@@ ž7«µ:ÍÅ€McÝ‚@1L]®&Ôµ ñÙšìà’ °ŽRm·‹¦b8–`Š7thkº“‘Z\‚"P.ÊÇú]¯]¸RS£aO/¥úz|ESª¡”<«hÈù¾ž{μy…vØÅJqjþ D¹!„šàgUc°³Ý!I£€-ô¡y&ÐdÒ2[c"ã‘N#Î*„xùrŽùåÊòðîÑjfÉqøÈ¦ím…jù¹ãñÙ¿|áéW¶ŒÖÊØÑ*IbkÏv?ç :¤Bº8ããz‹ù Ÿ+¯ ßúÒ¿nÛµifammyùÍË'Ý‘©KoöŽŒ«ËƒÛ·Gý|q©~òÚùäSW.]N½¡þÄâêL1ÓÖÓa7àÔ…‹›ûN¾q¾¥5j zë¾ý…ÄRûH‹2Ÿ ·W2YRSúzV+«Ž¶Î©5ùñ õ×ïyû™³Çî˜A˜•äÊÜRò;ÿï¿çÞ˜»øÆ9_ع°œÞ3¾åÌì‰OØ[MÖ_9òkšåvíõøR›?ñ8=îÔZ!Ôîw¨ü™Sç:6gôª¦#"»¡ÏçñÉ•úÂÅĉS‡ï|ìî‡ï{בßþqâúñ`g'@ Ëð ¿pæÆøþ1˶ÊÕ,1 ·ÓSITg¦, Çbãšæ †Cs4;±²"‰lfq¹¡5¤l€Ä&ØÐ6#‘Ör®1m²{,æÓ;h Ú¶.ˆ‚¦h++ÉLi¦#Þfj:Á& 6¤^kè¸]¾æÕˆ¢(ˆP“Gš¦(š¦BcÔÄøa€¢À€l‚Á©ß,0“fsX‚nÜž@“O „Æ®÷Ÿ› Òf.cÐìEÐL©6oTØ&€`DÔÍî!@7æôÕ¿u¼£gsKk° œ-LÌžÐQ«$6Ç:F,Yýí“ß?ñÊË ²ÚðDÅ€Ëå±×°LÃî¡ö¥5˜õÅbÂË8ÅF…ɦž?Ey*Ù2Óå£ú|ݯN^¸íãw¸}~·ÓùíÜW;Úºßr×!`j—ri×­ÓEîÉÀ6fR«4Ëöôô·nêEÀ)©ZÑÌ¿ôì‘øpWµ£¿©¿Í³ /ñÎÎn‰u„Å©‰t©Q=°gÿÁ;î<ü•+··uÎ×—¶ ÷[ƨºŽƒÞeš€yæç¿Ø±s¼7øü3G[wû/œY²°J®j«–N›fCŠû¡#Á +PÎáѱç¿ÎèÖ–¡í©l-@ßûÑýø‡ÿïÜÄBÿV“wAÍ,ðîÎîNÖ ÍÎær˜,ÍÒPÍ70 Çj6,´M…!çb+Ä" @(ùÜáp€a‹‘«–›gIÝR‘!ñ”Ý@‚‡bURéˆ^­jR¢|"m±¼`¥¸ø––É…ÔüÂ|Už+ Äµší]þÜg¿áBþäätÀ#¨×ˆZHyQùÜÒKl#Ø2¶u_0Ž 2[í6;uîtGO—Y2hÚЫ,gRZY?pç3?{ªm¨¿¥µËç^¹z®æ ú£W.½Q替<¾š9óÁòÈù?~÷ÿ<ûƹ‘í!Þò¹¡³%üæñׯ÷¼ÕÇyÕš±TO¸sÖ³¥¢0p~ïž±tBÏU“N=öêϪjy*ó/ï}‡™À4ƒ`Þ¸~Ñ!¹[Â#'Ž-” +‹7ÚÜ\½X.L×,`d+Ÿx'/ÄΟüÅmwíúC½ý½¦uB¹9¡´Tkµ²…šž±uãÒÄì¾]ãNÄ îî2xË-:"{ÚÏã¯L½ïèa«üÓ/ÿl×è~ålbafèŠèñ~ñ󟫪˜7‰ÔôèȨ;døÁWŸ¬V/í¹ó­›G÷”—²ÒÐÞPG‡à÷×:ÍrJE/+s·øðÇt¥gB1Ÿ;LL\15ÙFJo÷–…+ó}·tZ@!Œæ._õ…õR2FšÇã­V*N§#¹¼ÒÒÙN0?5ñ&a ¿¿fùz¥dìôë™âÔµk”GUT " l¦Z—ëµ²ä± Æ€¦¢)ŠÁ¶NF24ESnÂ= "D(„¶¤„PØÍ& @HpÓ%š—QSṈ̃¯Ó$p½OÓÜ{©Ï~îs€HA Þ⬯Í ("ëÖ Œ1^ïì€1Yoý@€²-„0"ÛÚÙ-qÎÄâÂo~øÃ‹“¯ ÷D:†ºúÜ.ß3?ýáwŸüùÊüÄð¦^ž¢ÚºZ 5æpª†65µÐÒ`lÞ¬V8§tåò¬Å5,Ä—’ùp¿´œFœîŒ„?ûéO¼åî‡^ùÃÙÇ>x¿Ëkó…Þ8suûØNQp~÷Oßsç~¢" ȸµ‚ìõÅúz|:°k©Ô¾òo¯?DÑr~Ok9½xm>Ù}-¹Àj®Ì™û·ïO›•Cc·<÷‡g‡ «É‡ßuOWûvS'DQrØv›üÑ_ënÞ>9·”«Lîî~Û«¯«Ë €9[—YF iÍâh½¨†»ƒky}ß¶­‡n¹ËPÕÅtbpddm%ð<á ¢—/NªùTWwDõP¸[Dl{GËóÇ^BÈÃRš ’mƒ«øÚzÚQ°RÊ–NA›’ì­»wÞ1}Q¤´"­“rcÑPè7ÏüÆÆkZ"zRLÃ6ŠnÅ:ùj]Ä2æ—JÊwÜõ¶BfMäݦ)Žoé Ž~ú3xÇžÐr„‹D³’íŒÚ5%[·)9•^Lçªù2ÃÔ.H±Üû>ü±'¿ÿC·ß\™õôú´œj뵇ßÿ¨DjùZ&™ßuï^ŸæXœ›{øwíÞ½ç[ÿõMS1Ê¥U“cöí9ÔÕÖnÛ埾òÊøÁñüLÊró‚àzíÙß½ëCËšÊ{Ý3˵ÅÄüÈî-£í1SíîUÌÚ…GÙ äqûcŒ+>8R(N¿z‚—$§‡]NæYŠk†þÜ/Ÿ:­›ÅìJV©ç+ÙžÎ΋§t#]4j«V ;vxÛ¾‘·½ã}3Ç.þâ¿Ú½»¯¨ÔÜzWG÷@¬­sæÌùøH¿¡h æ&¯K……éëµb.—K!„ö¿eÿ•7.ïÝIÐ íäK¿Ùµ=—Ì1q8ܪ¬·v…‰%Ù¦²p}a-150:ÐÛ»MW U®"†-çŠ3W¯.®Ì´Ç#¡X7Ç „Ó"…ä b Ûíãx 1 €M/½i™še4C3, oÊR 3y@éw€ZßJ­‹œ!Áp˳Á8^—SÀ›z7:7IÈhêsŸÿ€š¯†ëe´ŽŸ¡&³ÆÆë¬„šÒC°ž›€@ˆ(H0ØÀBÅ0ÅÕü‘ß=kqz4غëÀXKë §ƒ…¥™ü뿮ع±Á-õjÅçÅÞö`¡ ËÓ°ª6‹ÊՊΡ¨Ýt}r¾ÃãJ—S½]›Ëé¬%@#Ó@,R5#—)W™+—’¬à²zîòe$+îNW½Ê©•©ÙµÉs“Î6)9³|æm;ü»gß|ê[?ãâ+©’ÆV+­º]-õ´ŒHr¹¬EÕÔH›×SV×\¹ãö`¹Ù=ïÛ¶×ér*UËå±öÞÒÕÅey¶¥­§V³^;þ‡}›÷¿vyòöíãR/L'[ƒ¼©XG8Ú‚§ÛY­“û÷¯@L<®ŽùFû\B )²#àæl!·–˜™ž º$1êÁ–/äs2¢x}â’\ªÓŒÞ0UäE lŸ’jÔ`Ñ )`5¶ÞÑ7Òî nÙÛçv§–ÒÑ{ï}wéýî—ÏJ’×ÅAË)›DS<¸{ ¦Ý—¯/Ðæ‰¡±¯Õ0áh/%šõtP€÷:–¦²ÐNRNïÚÜš—G×'ÝñŽ»øˆp~å ®ðYuI“|Ö2n€ò«Ç&>û‘¯8U~µº6t°ƒÔ!v{Š åúšª·õ´ ôþﯟyÏcïVLŠ®^åX¶Sœ ñû’7.ÒQûԋ׆né:wtúàîQÚZš¾Þ ¤r9žM_?õÞ¿ú”DÞÑÒÞŸíš;‚nÌ,º}Á `ÖYÈ—L08¬U2»Æ·M¯¦wmݧԴr- ù[ü^_×€_qŸžÌ¬üúG¿|óÚ•}ämïü‹ÏÌ.]¾pæûOþÏ™‹—X‰Û5:æv2iÅ9ý޼rë}…*ÅS¢â\[œmfªVÊ7޼ȻÙ=û2º‰\L4Ö~ñâgÎ]êî‹ ïç8Ð@wûõ³—) ÑvYEGã;Ÿø}9«¸l½m¨¯d±»vn›¿6+²ôìÚBß®v‡ÆÆÊä«Ñ·¿çõõÃ×~>Ù«Õš¦î?(8=4'.^¾ ø—’ µ¸yÏ–-[:½~¹"krÍÄj[O[Y.°¢ë«ªOMŸÝzpz~Òí÷08NrIn¯£šÔ榯ä³I)ÀíØEA§nj,Ï7 åé«WVSË{Óа?ÔÆ±‚iZr¹ZÊ¥ZZ£n_˜bX±±m[–aX–E `‘a8$“æV BÊ©<¦·'ŒÖG4Ð, ®‡67ÂìëW¨ GýFÁüY‹ØŒµHMAÍùo–r֑ț؀àfæjä°Ñ+l‚gH³„m $ÐÒÍ‹ç_7(¸yû`ÏÈvL M1Ë““ßþé-\ž»õÐàæmc–ÊTôLKGËä W./§io$Ê%‹Äå‚·í8ùÜ c×Ê{}üõ£¿ªÀXŒ“ZÍä,±(`ר+ÇÏœ8Ã0ާuØ>V­R +o²!tTak Us ?ÿÞ·*2ã•ØD:yÇÝ{ÄN¨Z&–m䣋 ¢N¦ ;‘®;‚LGG,Ô)]Z(f «A·ÿoYY™ÜÌP!ÉÇyJ†M‰ŒE“ÊTá§ÇŸzìÑû MÔÓÅ/]œž ‚ƒwýãcßüÚ§?ùÛß§ÍŠ&Úº‰ ¥˜ Ônš!7ê‚ß›-3³s+¥ðJžŽI½ñ¾ÁÞ™Ù‹gWVö¾ÿa!­HL‹îêܵ–xó²BÅ#©ë|U–Ø/¦Zö}xËðCˆª”I%Ÿ^ëo¸ ‰4ƒ\˜15›Ò«e‚«”3@µ:‚gN_êØìÝÔ݉”B²”¥ئhÐj*¡i цÂx¼g­rúRÑfU2›N{T>àÏÌÍ´ôt⣯]öù0CÙ ªb¡{:<ñ~ןüÊÃ÷lأ˥Ԛ2Q.m(û|Œpyq> ø(o  SW¶?ØPJn¯×­Õ…,š™ºˆÄz·Ë3òXÖÓ×òÅŽüñHÿ–m[Ï=ùß+‰â_¿ÿ#›v·×I¸\ÌGZ«³Ó¤­êµa]g|º˜r]÷ù´ÕJkŸ7YbVåô[,W‰•Zر‹*’ g¯´·G,#xõ÷g—k—þù_¾ùå¯ü‡µÑîá}Üñûnœ™÷qÝT IDAT–„hzuù–{o1±Ùu)F°{¶ö»|éÜá™þVW¦‘ƒÃ>þ.³n=wü7”ÛîòÇ®%¯u÷uñ"_UZ,ÓFÓUŸÏka-‹3\ÈmEĘÚÅÉÚõ+—ƒ®^³V¢÷Æés™¥EGÈ_K»¼±06µ†Ü°ÜnͰsÉT¥R\W¼×”qEËù|R²8su2™[ †=ƒCÃÁhË Ø´MÕÈ­­0~ 8,Ó24ÕšÄDµxŽèH·YÈøé¿ÝâjÉÊ•×.{|îù‹³7ÎL±¼:·8kšžÍûöö xCC+†Ã o+»˜¡R‹yëXÃ4!!‚ uM1ê:„Z¹‘ŸžOžM]‚œ¾eû¦O<þÈßýØÛßñΟ˜;³ü“ï}?<,¾ëñw˜ºõà½÷uwô„¥6 þìéÜ>ÆAþ…3¿öÅÄ™~§Eç«ÇŽ¿ÿ‘· ¾ùåÓWåÆ*ä¯$ø]NÜÒÖJ¼®°’•Z²äÞ¿eÛ«O¾ôâï_Cdajõùå™úBý¹¡¡;üâ=#[Ÿyú¹c÷Ä"ÝËÕtB9[º”™Öy¶¡CÄCú:Úç«§^ùÎ×þM´ò’võøÙ¥å¡Xe >)ÚÛܽ©k÷Ž=ŸþÒç„0›˜›åýÆ{…68}nbßþí^¯ÛÔàÀÖÄD:¥JªhYe·›»~zÉë#î¶ãò ›ªšZ,¾ÉÅrm›;Xo#•£`ÈNLxÔj"ôŽûß}ÛýwÝûÑ{|lÌP‘Ðêc±·Ý-òl#óG·´gŠ|ëЦ÷bV­íÛ7ž©e;6u}ø‰È%ëÒÑSnŸ¤×i"ͧ߂ š))j¹aê…L¡V«zœabYF­‘­&uH( moõúƒzQ¾úæW ð­.¾ïo³eªœËØ´JÛŽ•™…ºžåxªk°;íªUˇ-úƹ‰•ä¢×'mië"ˆÑ5ÍÐõôêJM)Š‚H3,DȲlÛ¶LÓ°L€hÄñM³@!üùü†›ìcDÖݨ„¦àF3æOâ®?ëëüòx}ýÞ,A¯3Ý!Dëçlv7žáº)`›ÖÆçÊÒC€6T­öºr€IC³F£¾:=ý‹þß/ýó?NL߸ew×ccfŬfs²jÏ\ž^\™5ìÖ_ÿá[á6·Èpy9I\”ËAéò¤Ê®m;´‚€aEÜ0lªHpçÁ½´’(†rZá–h§« BJÎh‹çöûQ*Tba‡Ž;c¾N§èdœ&¤KšÊ1жU¹È2.ëꈸ’S ˜Î!I&ÇPݸž(Wn{äà¦÷Ì\œ‘ºº3–Þ‰ÎÍ,#„k‹•DrjumLËVä˜?•1¬™Ôܽï~{°Ml‰võ‡^:ò´i«´]îÕ¹TÅÖÓËùM=•L±"ËË“S…Êj,Ð]¦« C¼R¸Ü( Ž´Ç7ǜγ“¥ Ø0}¾ðæUá½ÈÕ°­²ª³ ư ˆr vAYµ°ÙóÝ‘H Þï“üD ©Ù~øoç{¾ðñ¿éwð^-KR%«¡š>SVe[³<+˶ÓCëD‚&¨ÈÚ0,‚š vÔÄïÿâŸûå ¿ytÿ×?'dÚ*é…ñ‘ñïüûw¯gÎNMœñúØ3u¿ÛëÜÜb×=xùÌ•S³k×R¹âÂè¦MEùùþ‘>À4l­ìkëÖ±Íǽ‡Æîír{TAo÷xu­Üñ$“ל˜6 {¶m:5}­ñÔ7~Öh„—f—Y§Ø®Aÿ‡Þÿ>‡é}àmwoëÝ:º¼¿mSìööÖt«³u$½¦ü¢×Ùuò”jÖŽ_:LïØ,N_½ïí5mçÙÌáxxôÌ‹'žÿå¯(ƒË‹…"wáÚËR_ß@ÜâÃI®˜+zaéõ­»†Õ|‹´Gh9»ðê¾[ïÔõ\¶TY+Ä;ÚB^/ÁD³,`bK·R“3²m©u}1;³ß(Â5"â»Þr?°ü4«ëj£ž[鈲n¿§­|xh›“•R‹Éå™ý÷ ôå’Ûýø£Có“ïý°ª-Ø¡ƒo± FBÀ2ug¹r&ͰÈT01pUÃÏ@9ÈP`ÌÈr‡CzCqHîr>Oñxóè–r£!„Y âèh{ƒ¹üZVÕkÑ®¶î¾­2^¯Çç ¯^›[Iλ=\¼§+´0*å3õZ¥É”«Y^^$Z¶mccË&B„ ¡¢v=JEðÆ× Ó´ulRÄÚ0l5¿Äë?®?Ø‘õÛÕŸZÐMI3¹Iò#a3 ã›w+DQp3þÞ| D"´nrnb“›ß5×ï„Ö±ï˲©§ö“¯}ñ«'Ž¿ñ÷óÉûï}Ðä‘€xÖ#4%›ÊÊ*“Èä·í:h)¤RÎ}QÓE±Îzº"8PÀÝZªT²ÅÂÊʲİá¶ôv‰b$»Z©+%‡SRËV¡‘1iÀ!½’üÍóÿëu#›A~ÉOsTV«VÊj>WÒL›åød*)kkCh“ÈZu-× Äæi+ÖèŽîÞ¿ß®£Ž>R‘­òZNQ²U÷ \o÷èÒ\²#D3¼óØ“$(†{»%Iˆ´D|Ž€'ì8BÓÂÈÀ.ÈJ>Ÿ¯_ux(‰fZb^Šr;\„¥m¢YaHèŹ9wÌ3=15|ÛÎü”V¨äPÕ”sk~ ÞÝ#±RNU³H@ˆÇã;°K t@ˆ'çd£BI4 £;ÖÖÉØ%p Å+¹RwÌw×Rt„X R‘C\DZ“G©™ì|Bþ-Ûú:za?¥Q²\f"¤ Bð,D$”%ˆ"Å 6ØR±”ÍÔ_?wÆ×b ô¶ìܹ!™sÓ׿OU¥\|Ï0çˆàniïÇUaqm®½58·8ÝTcmn ¿ÇK±”¹ö¡ä^›˜l‹øUL—ójG[ˆÁIÜÔÅóoÝ*pP p•ºØï×I6œžv¢ëF÷p»-›ÞPc.{ákùÕ»¿-5[îô^=}Ö­sBp-QXYZ¹ç±u¹;.ä Gèª ¹° –wö ;zÔ,”«ðŸ_}rÛøNƒU«–½cÛ¾äZÒpUÇ ,Ï\>{RC8B;LdÛ/¢þH R«jмã¶]¡@\©5aÝVT`VÊ^^´€‘¯O{]´Ç%åšlꊆ¯Í^´tVp‰¬)”²'êSdF—+V£^J3•µ:6m›¹û]ûïw€€¦Ë6¦JÙbØç·ljayÆÓ~ë3kõS|m¹´äò‡"þiÚj¡–­—£í– €aJ‘uÊõÔÖ-ýºn3Ķ-¸$Ý0â]y†DlÛ¼(:…àÚâõH{”,âäòÔëÖZršã)oÔ=¶û +$·+ëʯånL_vùù–öÖ®ÞaÓfй¬­«•B>›[uy\Þ@ˆ•\†¶eAB ¤ DA‘MnfG×Ë2„æÑm6Þð0þVˆÿ4"‚ j˜¬`ÈŸˆ „|S[ß,ß4X¨ÙlB³n6‡Ö·`MÊüúÿ¼éÛÈ£lL @<Ïs6zóÈ‘ÿò?¿t<ôöôÄ3¥Ì³ÏüVhõ”³Š£—2¹Å…5ŠsÐÉdZÕŒÖÖ@>k©•F"•䜜… E5굪-9Ú!Ð1P(}žÐj!×Ý?väyD»!£]¸1ŒºÒé”ߣ¬×Ã"“†ÆTõŠÔr>{íú¥ôâÚrúR$}å'ÇË•Ën»\.Ýwçñ΀eV^|ùwgY„Ð {pï~NT¬ª¥CA£Ü"c3ж)F¥*Z^–s.I„A®V.M%§:ºz{{zX€Ö2yŸK…:‰Î¤†h3&º%JѶ®@§ËïCƒl›–lÀ Y1j]'D·t ›ªUÝ$j&A/OM/Ïž:¹”[yãì™â¬6?qÊ‘ldP‘s‡fUì|¤kДDS¼Ób£íDi¦ ¢m°ïÖ½¥|±Îæ- hDó±m ùÙXt/oÅ8_oØ%EûÚ$·ƒeYâ°7oÍt¯àØ>8·Xî2K™Ã¯Û26N!+ºiHTØÓç_Ý´)Ø×³)2ÁöP¬¥µÅë¶8¢±0ãëŽK)Yß´k¸µs(›m<ÿ»ß__Z|âuöoqÓ®`¤³£uWqUŸY™jóG†Ç»‡ÇìÜcªY ìÅÕµÅÔL© AL$7c8¹j`±6n«åÆîíãJ¹¡©%›BDþ±£ïäZM]k÷´ÄâB¨E­ÉµºÌQÐç [u‹ÑeEÁ…•&äÜëõ’ÀPÕ\jÇöMº?Žþâ—OÕ Ó#= ¹¸°¶h]?AÑj.¿×hØÉÙy"€ŽØ@>‘k jll¿¡@]—ME_X™Ú¾s\kX¢(‚T­áöºÖ‘+§ý-AšD¯Ë¶Èüµ ËWuô¸ý­¬ 8|A[¶¯œ>­…@‹oph+͹K…,¤!±a*±Ê2”?ñúB¢Óƒ11-7—`L,ð Û&ÁÁ6Á¸#X¿äÂ9X‘•p³§ 6ƾ&¤4ÿÉúR ¯€ëW¤›SåúÅ«¹XßxAD@@¡¦z}ÊÄ`'!MÓ…„¤‰›AT3k"›x‚( ÃåÊ®.|û{ßüÑ~2Ú¾ÿÞG·ô÷Ù“/:Hkð!4φ à󋚬°ÕÛÕ¹gl›…MÛ­Ý¡º,¥’”À$Ó:èp8¨Ê6òÜŠK©ùKÓѶËЙL½OضBQ͆&…-S¸fX µÁÐ6´lDó´iŽáiIà\¶aŠ¡ ¶ˆh†PGÕÂR’r0Õ|­{sXj—>ñ‘6LÔ»œ­éôj¬-RÏżpüʶ­£'x|¡P¨K'B)±véâ›þ‰v9‚~ŸCð£ Ý¿y[®n¸|6b} ¥JQ-”K”©•7uMOÌÚµZC®H>Ga)Û3Úº6—˜Ï_²E¤¶Ëå|ðCò$ü›?¼ª6±L é ÇÝÝÓ…$§mY„˜UÕB6èpA¯»šo¤+sЦ9ýN§ÄpˆReÚ4Ã#Î` ¥Ù2ÐFöî¹ûÐû* ¼R­._K*©Ž¨„G@ôÒ4TÄú}"€ÆÄ¢hKqzEb ‘!m!‡\WdU/r¾b³Ê¯¦ŠÓ©Ù×'¯ªVÍåfçR;Æ»ggÐÅË“¸¬ÊÉ4P2«É¹Î ¤åòñÀÜé9“f̱] ]#:êµ8ƒ /RCñîÍc}Ng»ÇݹP<Ázœ{Gn'&b ª7Jõ,Ùu×Á“/¿|êò©¥ô¬Í›ùÅúKÇ9°©óCñ‰ù¥…—üñöÇ µõ@S]S£#":9Ÿ ’̪J"mþÞþžÃ8þåÏù?¾ôÄ«WŸëÛ>¸Ï¥²ÑÚ/ôŒt=ôÑ÷½í¾–¦W¿òìj9Ñé>âøÄ¹‹–fRg•¹êJ(âRóIB[´ÓQNT·Ë•Z¹Z,åešç§&f»öD÷íØ‹-Íô»ÝÞJ¹Üî©ÖeË µBÝ®x+fý‚·Ä8]åd±T*Ï/.ÎÌN¿õƒð¦ç—O©Ñ[oíìîv8B ¯¾<›¿rÛ¡´ºùâS¿øŸŸ|gfñF0ÚÎ \À$ˆ±1¶px]º†ëÕt ³±Ípt½Ô°ˆé ù-`Z”e›Ø¶ ­f$—–‰mHN¾½§ßëŽj†…( šxöòÕLv…èÖx§ÇUU14ƒøb&+ ´?Ý~ÑåaXÁ&6¶,Û²°m!„,Ë4MØ&ƶ ¾I]§¹LˆËëâD7iq)¼n„€xc›Ž›³äŸ9ìoΕàfóp£BM@ë"èf5cd#b4…š™ 8À6ƶµþ‹ %9ÝD³¿ñ/ÿú¯Ÿû»‹—Oø½A‰X¿Ø‹s~lߘh8ÔzާD Sçä†Ëá¸u|Äéðò»üݰ4]fhšv†^ëíW’zÝVD‡ÛÖìjuyÓÎþø–PV Á¦­C`»®a{ÃQ ±Ž3$ˆ"6à – CCº¤Ê–hH.gTˆlÝ"6 ˆ\k0<ßn3Ö­Û·Fcßþ{Ô|¥¢d;Û{k×nD;Îëo u^½pÖà,Àj*#xi^*dË‘`K=gì~Ëk³ ƒcÛDZ€q÷ûTÝDθÓÕ»F|aWÿpW‹7h¢›J6“îØ2ØÚ³UâÁíï¹oõ:¸tvVt8†2¶íàèm·S%áçßü–äb/_:ûȇ_›KDâ!…ÅcŠP¬_Q*ÛG÷ÝÖ ÷µZ=|¬5‹Æ+’¬5°Jй¼ Ët"b‰¾µ£{â䩽Û#ãíã[ú‡G÷î=´c÷Pkd°[´ý¡'“/h…mЍÞm›žøè_8uNm4NA£)CC AKbmÓÎ[¥X~µ­#öHë&fîî»8súyzáŒ*Ån,ÎÇã.ÆûæB2êŽÌ]:©áÜÚÕ­Û‚˦-†uñ„b)l›í‹ú¬G{¼!ß®]Ç2‰åÍ»GF‘ØÐ@_ùjâØõù=±­Ïþô¿²,MYŠ\êéŠWí õ—»vݘ¹¾id¨ÁTFv·ûØ–©é+Kùl$ˆt]ÚÙÚ&Ð={Ɔc‘èÀ¶àÌâä7þíË÷ôÁ‰¥+ožÈÜ÷ÀC´í9uâ.Þõñ'¾XËÈÚrá7¿zê]x·Y®)¶.9ƒ¯{3 ØN¯úìÑc½qbL·×† Ys‡8M±ÜNnefIÕr¢È˜V£¸ºfC³jhó³ŸØt©k×€{<Þ0„Ài)¥—D\ ´ûX§(r®Ó'_Û²Y% ^)—µºH1?øÁOKµáõÕŒf¶hU´FÐ'ÃÐ -F°ÅqcÙò¸˜h‚3záâ+„…ñ‘H õÄë/üçÿýÈ{ßùîB±¼º:WW ³“7®L]ìÜl$¨£'ÎÍܸÁû`—'8uu¦–Kvvn¿ñÚÅÿÇ×Ïœ>òÇg~—+Î;ý^E±mÝ\]^mh2H’˜ÉÓWݯÓ4MºN±"åôº|Á¨$9]Á°I-•[˜º$8iÐß?´Ý4ϳ4WH¤ré¥p´Utúš†`}™mÜ 4£š˜Œ-ša)H¯ÓÈúÝjÝŒƒ(NxÁš@uP3†pSïü'±òºÖðfd}ãïu"Ø(NC¸Þ¥¾yžaL¢h ÑÍÏ›H,˶D¢ÉM0„¶aX†5sæüß~öo_8|$Òíç L¶ÁÔ*EÞMB[jõ¼œ‹H{¨ÚHp0!‡È„ùîx¿‹ãd§Ö2¬Ÿ_®¨ÉrÊÛE6ï¹ùä|ÿÎþ@ç@¹X ;™ÑÀnº!\¸~#± K6„¥”<3?—Èey@Éj½¨›b,Ú"0 †©+¨‚B,€`C· ¥b,iJ&SÎ-%ô³§Ne“8›nÄÚ†0«w„–—§¥vvy£íñìj¡˜]á"£.[™h´U-ä /H<ø;ˆ,£˜4SÈBE§,ãŸý‰{ pg§¯Ôy…£8!´Xš©ÕTf-‰‰w·{œT£¡0ˆÉ­å§“µ«…`Ó$æèž±ÁxïZC{åä‹AvÛ½>’ÏÌå™Ô¼ìt¢’AÃììêܹÿ-‚$µ±”Xlñx=¶3{£°0?ãrؼOÊ”‘¹±z9‘K›•F]ͺkO¡`J¾aÌFÚ[$½z~òÉ—Ÿþ‡¿ýZÝQ)•ä¼ZÙ¼½ÿáwÞù¹úüÁC´;ƒUS)7TN'–R¥yP.Zf§×CÏ~p,ܦ«kåÛvM.Ÿ˜˜ó2l%ä$¿Ëë ,š^ÚɤJkããý]› 3‰HçàüÜéâóZ‘ ¸v•1`Ï8çÎûÝ›±RuxBm®„UíØ[Ñfn{à'Ÿ}}ÇCC>òéPÔ{øWMCýö—ÿiǶ=ŠY›™:¹25ÔÏ»Ä૯œqm‘’ ‹÷×ý-CÝÃ-Þn@Ð#Z¼‘¶¨ Ëëݹ{+‚¼—qš”da6}}z(î]-<þ@ïÐm—N+s¹ÿùÆ?<þ÷ž:3ùãßþ9¡à1𵋗5îîõ9Â’ J‘`Ðß^,–Ãn in »…%ÊÖM[<±°¡F4F‡ÆMÅÀ¦A`Ù Y[H€¢!B›û·lÝR*®¼øæÇ>ù÷²/:/ð¨\/]¹VC+o½ç/]ÁªÔÜR«Õ£ýÝ¡XüŽw4HY Úžüõ÷-RsH–á«rÃécÊ™ÆÅ'ŸûñŽüîG—.e%©Z¯†c>µ‚§ÏžÒ…øÎÁÍ #q¢àõBiöú5E«zþî¡Ao¨ƒáŠÀJ:¿2;Œø„@„P M3‚L€mل榻9“q¼ƒb8@Q@²þè†6|ªBÂ0 Çp¡›"g²î~@ADÑ u4̆6nüA?¢æ9¶a¯'¤©§__“aÁöÆé†6–ñÈÆ6D!hV5‘~ã/}÷KŸÿÊ×¾à‹ù>õ©'vwo‹xB<’TMe!J—KÇšfyÎp89A§tOÄo˜zßÎÁÎ-[XI`j®¯èé‘ó9Œ-ÎÀ­-ýmaº½zyiaîM‚˜˜o\9 Ù£#·( YS=¸P© IDATž)›j³,…)"ÈÖL!`(Dï±-ìàY––lM§L3¬«„¶ ^€ïm]Ÿ§¯#zè–=íÑÐ;?ó.¿‚ºrö:ïƒ-Cn·§®(só“þ˜“µiEÖ"‘d9lšj‹wˉT¤µ#›½~qdx€²$Ú 7toÚŒë‚Ï#µtD¼4íi&ÇgÖŠù$-ð/Eü1™ÜÕüÈ-›kSW«éÛR!!j£~ÿg’³“ÑÜO0г©×íÂ~0ê÷O>{øÂÅ×,l4Ukh4 ¹޶M;](­ùü.šÁiª…(¥(O¾q²PXô}’׎uCÄ Ä”ÓÅëç$ë„¢–Fh›F“/CÑM1@BÃ2,ÇÓ,GQM)j“ƒ©æ±ÕLq"„¨f0 5Mô7ž&ûjfEnÂgÖƒ ëw©ÁoƒGºN¤>û7Ÿo~µ®Ì7½õ7ëÓÍ1e9³¼têõ×~ð«Ÿxã§›¢Esnkey¡5îŸ]LJ’(k†[ !ÆÈÚ:«ò|HDb‰^ƬtvtJÝJäWKÁjlu™þ²‘ƒTèPYŒÇ¨è˜§$Ö³kg»§eÌÚ¾¶RK[÷â\ÒÕâêö¶'ÓyµT µ8 ×ë†+êHfk +¿wû‡¡ëðÅç_ñ´Hûö`YºÕ8ò"ë ÃÆ¦îs1þ`k:•vIÎl¾Yî蜽r½»¥ò8½þp@òÊzýÅÓ2´“ùúüÜÐÓ+ùŠV•_•Éèæ‘|9µ±€wºN½þ‘.Þf|lOß&bA›B>_ Ô+'ÿxvl÷À¹‰Ä®áÍNÁß]¼6¡@Ⱦ³/ÐÖÖeX·;R+Ô‘­Š’ })µÂ#¡«{à±JåJ _h r@€w§çÒF9Å8äCÚwèÎŽ¶MnNŒuŸ?y$»TµÉ ¶QK0DÞ醰š““\˜ÐŠ˜8h »‚ÔŒ™ß7<ŒÚׯ­Œíè_[ÍDüÂâìüƒwÞsybrµ"K”­Trùì§rËI#¿2ºõ€Æ¤h‹O§Ö&¯¯ôt´$“ÅÞþ¾Õ™%‡Û&.¦ª(=½ý²š(e]LˆC»`+µªf(Áýÿ™zÏðʯòÜ{­õïe÷^Õ»¦júx<ö¸cS ÁzIBr orÞÔ79'$!œ@N!Ð6˜æÞÆöôÞ¤)’F}KÚ[»·¯ëý iàëÖÞ×¥OÏõ¬û¹ïßÍáÊíF_æž—_zîàC]4Œº™ 'Îé˜^¾ô¾?ú"Ñæ^zþé÷ìYÊMÿÝ?}XàæäÅTCQÊñ6š÷?úع ']H?øÈÜ¥²cµ¯]ËyÉÚÜ|r¾·^:¶ÿžý¯þò‡Ðjõöm¹qæìð¾Á±Ϻ±:_t‰5{ÊùµÑt/ëð"ÃR˜g€^xöiE+Íâ£îjV{î½C†6H˜å¹QÊ—ò¹X6ÚÔM?"IFæõãçü!ñÞ#|ç?ÿ33ÚeJÖõ™EU[Þ÷ú«oH¸ýÑ}Æ’¨³§ÅÇùÝwÝÓ¬ZÑÁ‘!¯?²²°ˆQ6Qk—>ðéßK§;·ìÝ_[k­LÏÖêË$É×E“¥ÔZ­j«V¬4šK£;vÕjµÎ¾^šó¦ Äνz|µ4Š„=~ÏÀð6†÷ÛŽ‹,wâìÙ–žÛw€ }$9†Ã–í86„ˆ H MÓ‚ëqa×ušE±‰_ëE_w€ l4žþv5ê:#aÃ6ºÑ3±q\ŸAà·’„`ók›ƒà7%=Ϊ Ö.à°ëÚ¦ý³ýøþæ_yùéÎîîGîÛsϽû·õìüž¶ª´›r}µ|k5ÏX®C:“Sy–ÁÀÒ–rM‹€à–`tÝmÖš¶&k’Ò¿€¥¶ï=YÛ+µ²–+æt³Ù7˜ÅKñ^Â$µÓu\S¡B8R$ÍûºbétOÂÇ8Œ·öyˆICmMG!E–Ñm²eêÝɸß㣽!Í"ƒ@µ^¤uJ ‘c›õRMVŒ‹×®­Î_Ÿ:{Ùˆ·ïüQ­ª°¤pì䥦¹–Idº‚*i÷ÐɱLì˜Eõ%{οv ¦à y!9ª%·VôÛö=\¨”FÒ=l@ä„H‚÷·U] ˜™…IoÌë '㈋¡‡Ÿšß×Ù©ZÚå‰kå|Åvl"Ó0ï9ø>Ä/—D“ëÕ_=ó‹¿üÏg%·bjvX$;ÃÁ¦T3 ~âì›tnÏ‹y¿Ç£´$SÓ|>ÏÒâ\çH|zBi­ÕDšp]P\Êß»k76ìÔ@׋W&.ß>9ynéìë?Íלd#_BicA DAÐ-R±†çh”j2r ÅPGö‡(‚¡0\ËSívË@lÏPO§´µ_|ëÖÔIÝm‹‚'Hg†N]<³ïÑw-\šÀ&^Z)ÅpÔ˱„¯®·VòkˆÕ]DZ[NÀ[ž™é—¯-|¾Õ¥IÏ;ŽÒn-wtî:uâBïÞ@¾²O.íA:Ç9l †Ÿþîÿ‰ÅºÆŽ—z“=þ£OþÞçÿÉ+z$K™¿yóÚM˦y»ë;—– ço1±Ý2æç¦8’ìJo?sæÑ÷Þ{óÜÄ`wô¥gÞ<~üz$œµŠÄÍùk]=#Ïþðû©ˆ>>ã]œ8üÀ;SÉí/<ó“WžûáíÅ¥,¿üÜO]·— õо( R®k9º)ò!°d"^©^òûEÛÈqd» ˜°méjÓ<úÂO ó¨]«–šJëÀþGνԖ[_øÁù:®žznÍZÚÖ3jÛ\gWvlÿaÇeMM½tát(Üí{ßûñ§lÄ“ ŽVr3À5)ŠÁŽ‹ @r!&)–¦¨–TÚ3f»d(ózC¤âñŽÉ ·æs׺zI†íìï Ä2$ͲXš¸µV›ß6¶› ¼¶ks,G”nèØ5ž¥i†eYŠ¢"DB×´°ëA@D¬›Ëá:” "Ö-›Þ"ÃÍ9sgwˆ~1d„6nŠîƒõµ „6š¾Ö¾nX@ O7®Šë„K2À½tîĉ3'“=ñý}úOŠ6Eq¾V»Ý–Û­fÕÃ’”WÀŽz»‡~"Y«7]Â'¢Ù$ IZÐTI©éÕ|QQ 0ͳ>H°¶¥²œ›êLùcñ…\‘ö“‰hivÍ”j]ñ4íX&Á0Í‘TiEb½HƒmÄ›´hȪ)We‚Á K•ÊZ–/àÛßWÒ¬B­$0L^n åõ m¹®Ú-ˆ‰°—Ø}hLdƒ4"8­V›C[oݺ˜ØÎ¼ïÝTêA¢ÜÒÊìí«Ãc[VkËý[Gkù5Õ1Âñ,päT,•¿¹4½z%è`DO¤Xб7KD| }­ua¡ZÉ×Ö\Ù²DP.as­ºN˜&ÏSˆ! ¥PZ] †B‘ŽØÌäê¥SçSخˆøƒ‡.W+±Ç†€³Œ´ÀQˆ§y·¥ ùœ³ ³·G;¤wêÔ$ŨÑ`Ø0¶T×83ÛÑÃ#J³ØleÇ $âÝñ´¬ºþxæëßûÅ‹¯¼°4?ñ‹³ã‹+s·ëM9¿Ö¬ÊJÙ(Ë;DЮê<( 8"0)ˆ„=3kk#ÁO(R)Ú™ñæÔl³Þ¸54Ž{Þ:ýæ}O¼Ÿp|û‚<-k퉋»Ç¶¾xì…Þôry%W›b‚Ö:c)’% —Vë–Ý’üòÊZûÀÁ»«dÕŽ’44M­´Cà™d¢{îÖ…îîm}}Ñßÿ^ôXªd1´êê)¿³°Rh¿ú£oÏýLìð– Í`À7uc2O|ä©Y”e8T*U m݈ºÖø…óºÕZZ•ëÓ¥]Ϋµù2Ðæ<>ýãžú¿Z ±¸p4›éDÿîžëÓW|éð+/ý:ÛÏݽg2Ö{î­S/ýô;meþ÷ÿê3ûÜ>ý‰ß¿zè‡:û·ð|4ð-Í/žšxñ÷¿ø© Î]7y:—o¤²CjÛfh„hŒ¦ËªjIÈP‚'BHT©TÀ„Å >–áH %øÅ-÷‡Iv&±Iš†K¦áPXª¨×Nõ ÷‚ñD:•íE$C“d#W¾qãÂèî­¾PVRdb’ "\\×¥H’ (Š$Ö_j$Ib×uÞ$‡Þá‹ÂuC)Bë €à:f“ˆ6ÇÁõîg°ŽÐÛ|(Âu3Â-ysLA´ðÙ°|€î¸J×§v1Äxã?@ƒ˜ão¼üÿë~þ½§Ÿüø¡'ž|ï@ï6"$Žá9Ƕ]ÛÈ¥ È¾LzdO×ÈÀ¾Çî½W7¼k…&Á2Š*[ Í´¦Z:hÆ!‘õʪå8.ÇsZ»It vt®ó£ÛFXZ˜¯.$Ø¢(Öu Îi¶ž$,› ‹~4¸€“ P»4EÌÌ-…qæøÅSfKɆlŠñÚ˜¶k»œ¼Œ)Áݹ À6%W@¯¿|41uj„jX´%ž:÷VË(`äˆ@ñèû~÷¾ðíCî#=p çñjÈáLD+òÊÚ¼©éR»ˆ&.]¹•êêðù=R£B#èóŠ¥rΣøœ8%úÕ›·º»3­ª¤”™ƒu±µRi<ðÄŽ/üÏ/=v轞~ñÞµzñ5à8›AȵmDÛ&âIJ1|^¼&¹,K#dÛºSª­>¸ÿ $+“ׯ™îv€K­®,ß3²ãÂ¥“÷î}èɇ¢¡W+]Z¸Ö×?@14Á’«WŠÀRýQŸ\nÍ,Ö·lß3QYZsÄ Èšš^PA‰± )>â•`ˆüAÞç_™.ì:èç½½;Gz\ÝtYelÿã+h8¸X’Bî•ׯ÷ß5Â^– WrãéT÷¾{ö|`÷¥Éñ¯üû÷8®Fxy»DlëŠAÑ¢åà†?½p꺊Ýj£Lr6Û)·«£ƒb'¯]-˜J06rù­×·Ý¥Ê8Ý8õÒøÉ×Þ&Y÷¼ ´d8[îݽó #nž?=ØÙ'„¢‰h:”ÉÔó5©Þœ¿²èXU5àb1$D£1ˆðÄåËe­™HÅŠ·0hŽ&£‰ïþ×ÿ}ü]ïêèê>â¢MȪdÆ¢ÑPgxezžb± !"éVÓêHÓoÂZ`q©”é‰úÄ$œ®Î8Á-#¶‚Å4ÇSÁ…Ù[©®N×Muíâé7¶w‡S=,KnÛƒ b¬VÛΟJ †ãéáV³À–‰±CÓ´ƒ‹¶-ì`Ƕ$A ’¤Hz첞у›O5¸~Dm ²;$… ¹i³uuÙ}}¸A€ ¾£±ƒMT2ë`¾uˆ€ën6­njõ›Å8!µÑøÖ};’¶ özÙðÚôlµšs° †¤°¼@1^S7)7³Ñ «"XŒÇ’‰Ž$v¡ﻑ›O§ýAŰëÕ–«Ë$ i_€"E—#᎙¹2éÑ{Â}ó׿Î<}éï¡¶¤JmMÅ¥Õ&åA<ÅÍO–í¹h<µ˜+÷{ú{=OìÕó, ÁˆUÒ £Š®¨´dÓÍYfi¥fì¾t°ðÒ”l¶ÊCÃ’÷ùã‰éënȳ÷cógÙµ»TÈ‹7¯Ü¾=ˆ¥'Ž]qiõÀŽwœ}ýu“¯.kJ5×ÅåÉŠ?©rv'$-Ú@ ³YŸ§)´Z¹MRZÓlÍ–Û.ðA3šFû­CûvDɈ;‘òu7òui…®Â|©A@/,/ݺµhjMصM©öì¯~ñÃoýp±!àS½ë]~d®¼ûÈÊ –å*ôW‹”Û¨ Áö†‚ J²Nóþ•jÃÅœcµFvŽF‰óãsrM-¬NPÿ«ýc­H÷ NRÉ”Ï%äŒ7ÄcÈ0„--×DÀIº*aéõ0K"l)$\[ˆ€™êòÀP¨{`Dpú¯]»q×ÖíÛF8öÆk¯ÆlçÚ¹Kïþзd¶vÅSå|~Ƕ>«\ëÚ7$«-ÙÕ•šNQŠÞ9€U"(›$ã#|¾…©[†àiI퇷׎J*­Š¡Ó}}»n]¼èO±6)Óv8  àžC£rmåÒ™¹|óF¦;“‰t„|qŠð­ŸÑ®Møôkg’‰¨jYCÛ>òàýåµÂÂbþ?þûGñ>Ф¼†È5aµÕh“þÕ{w¿S3¥Ñ­©aÛˆš/••º&©¹J,Í,èFã䛯^¹6÷ö路ú¶ìþÛÿ擟üÀ›—ž{ö;‡÷ÞÿWöÍË/þèG~çú›¶¡ª°UÚn6`˜Š=œß¶P%žÊÖje0¦¢9À¹>uëî{v=røQ:˜ô„ÒsK«ÏþøÅ}æ‹ïzïïNO-ߘ¼Hy‚¢ôà¶JÛÆÈ`xѱ Po½üýÎÑAì" GµVæd­­¨­L¶Ã‚¶kÃf­¹®v{Á…¥A9œÀ'³Y¯?âØ …+§Å;ÅDª¿U-E“YÓjµU®]8~ í-ÛTVŠJ³ \Üj5›í¦¦I–e`M˶m{ý*ç`C IJÍp"Œ\4»ëõuCº»Y.¸1Æð†wa=ë|§å£Íò®Í®ãŽ×=[`cDáßøÞ!@„7].wÝ©êºc‚ã¾ýåov÷f†:Z«F¹QÁ€=zílN¹Õl4McÛjÕ[ Iú9Šà˜@$00[VsVYY\µlÖõÜÂÄrMâ}tµ¥Ì,W[…ÕB©ùÖÄ©pPD‚µµÕÅÜT6É› IIÁp¢3ÞaS®ä0åF÷BpЉ‹Ug¹´¨‘¶ÜFË‹··Ü·k$uhÐFÂèÒÊ‚Iš¥4Ë ¤ÖjZg&–íeüÌð ¸ûþýy|ïþáþîžÎ‡\<ñþwâ¡ vŽL½òþ>ÚѳmüÄô¥7/ÞõÀйµóã?ɤz$^¹üò`÷Ã4³=}s3¹7ò¯öíÜn¹Mê€À”I_9uÂb¼Ó×/C;d«7•õ’¤[3s+ŶTæ¹£±‹ËÓŠ TI‘õ¶äH'f/ñšíV¦¢p^þ§?þ…AYßþçÿuxû¾?þ£û{­GÞs¿‡aggÒéØg>ûÉ/ÿÅßîß÷ØŽ½ïÐl=Hp4F™¡NQ@¥5ÑUI.Z5Éß­Í^•ÃQþÖÜbE/íÝ;28’oÑÞðûö?üÂÏ¿{éÜs/<ÿÆO¾öÍ¥Jƒq,5ä¦I2Á0®æ°´]³‘c—&]ˆ,æ0̓Þßk—ñ«GߘZ8þà‡WêòdùÒßüáfI»=1¹|Ó <¶ïÛ~ïÎSW:Ú‚%Ʀ_{ñ•L$XÐK¨âo”T”¿qY£L«µòéWϹ6뜼x>O¶¦Š=Ûú”f{öö ÚqŽž¼þÐãGj«ù‰Óç,µQ2Öè¤ïà廬ášF]÷ߨ©R¦+Ô?¶»Ð¬øi¤×ÍP œÏ穚c4Š£]È„ž€¶zky¢(­}ö½ïNؽOÜ×®kÏ~ýŽÛüê?ÿùç¿ù÷ý'ÿBjä3¿úîW~õÏïÙöÔË?ÿ²¬5u"á$¢½`(•×TÚGÒ"±cp8Ù×ðgN;ãïñ  )õæ+¿~±Z2šiK ‰Úm+À Ðq±ë:ж2_ø³Èµ ˆ)†ôÄBµªÔZÍûéÄJiYðz4]E ŒÄ㎎¥|um¥Àz8–X‚m—êWNÓp%Û¹eþÖ´7 Ⱥ¹4==uõÂ…o4Ú‹ÛwíÓ5ºZZh5šÜ²-ÃÖtÝ4Él&e Ð2 ×u)šaX–ØÛ7þì`ìcìBô[0Œ×1Yë*pÀð›"›u½|Øp'v¸™3„›þwwÒ¾þ:Ü”ö×µ±õ+%p]±7hN×ä–Ñ$›‰XÔCˆ{’ °lYÁ–ÍAG7f[Çš‚Dx‚ˆ&0ozy>âO®\š{ýÌsç·je­1³°ÐTÛöÚ-,×ëÅÛ+µ…Ê`åðÍ•š&­f“~,[!†ž.Ì ˆ6µ­+cÚ$¢€icoßÕñ¿ÿæó WÎÞ8±"¯NÍœ¹g׆ó*ùVoG„ ŽTŠp™ñ…Õ¥¥zKsÑÄP¼bvi`ûî_þà?™`,›ÚzW_µØ"< ÷6椆=ÿ‰¿ýh<`cÑüê Éôð×þúK÷=õ€d×ÁF³Ú–GûK¨×D–ä÷?>—æ{¥j½Ýª©Í¿às ˜­”ýn(ð{»Cg›g†wL&/­4Û›<îíˆ7f‰v:ÕåG¸Ð’S~zÙX2©NʵµÚÝ‘r³]]»ž¼ïò©³œE¾ôƒúß{wS²¿úOß½|ë5ejdçÀîîƒ?ðÕŸ}©'ºS[FÁŽ» ÇJÕª&WTËp ´²´¼¼¸våâ©ç^~‘ܯÿàÛ:¬ýå—¾ä㓳—nØz{`׆ “éðÅÄF[ò lµÞ˜[Z˜¸t¾+ÛMPƶƒ"¡à÷›-¬“UYÕCk®¢+€B!´‘¯Tk‹[voÄ E14I­ÌÌ7•º7]YʱA˜êFtkþÊÄJnr`Ǩ/ÜÝlTbé$ç øA¿/Àð½éŽpÑfé €w<ð›…«!dÁR1¯c'”yr;f90;w#Û“–-£U-Ûj³Ýhˆ›Žiéëq=~:W-k-UÃrÜìO'ŦԔi’ ùÀþÕk–Úú#µš\lÈ–ÑÊ$2Ù‘^ŒQaa¾£'¯´12LÃa ×eiGÓ=!ª#éwÄéãOùYwx÷.Wk³³dª•F|0”í©Ì)ªÑœ¾µT6Ê'—ô* ͵ÂÔS>ª+eØš\÷{¼Dhâ­q–/=<ú¨jÚœÀøï̥믜|+ë·[í¶Ôðûº£û#x[…rÿöaM2tY+M-Ô—æÍ¶ÁÑÞ¿þêW?ù…¯( ð„ÿß?ûâÁûvr¼uÜBuíùçŽ=áJ~mavµ´¼hY¦WÄ^‘1Ͱ”b« xŒCt„ãn¾},ÑëùØû>4;;uäѽ—zëÜÒ&Õ–ôxÔVãÐá«‹U­)µÛ r)V’ 2tÒ„#±8¿œÏ­$3±vcvöÚ9!ž½6KES£Ý¹…üñÓós³+ƒ5Ű),;dÒã·°if*c&¢ÉÖÈ{ööì9å\ÔÃÿêõoÄ:ú»S?#å|« üú'OïÜÚ %NÐdUQK¢Âw‡ÚjKU3«ùÕ™ ªCtvTò-Ñh‹h*ÐhkK—'0‰Çç·ŒŽ-æŠ*À. ¥Š¤Jn³š§# Û¯ž>Ú78L#údÒÑLà­×_Ó)¸VoöoÙÅù¡€# èD&)•Jo_<–o̽ræÜùóϳlt´#'JÌÌNëÒ…¹ši'R{»Bi³.2/PªLBA&äñR4v*È9¯H±é¹ÿzöß¾÷Ì3t”OÇ·;„.øšåÞ|á…w?1¤¸âJþè‰× Uc2?'|áÙrc±{w¢§·««stumq2?[¨Õ¢\üø…‹»îڦϼt¡ÐZédÉæ¼ü̯~œH„_úùw=)Ÿ˜bÛN]ô§±¢0MS¤h©R#)¢­4ë­F­\®Õ "[õBÄŸÖ´5¹¢8cˆÙt8˜ÀÄŽM1œß,.N½ùJ$ë'ßnÖŽ•ÉдÕéÙÛ7/fbƒ£{êÕV½R ¡ªº"µ\ÇÑdIjÖUY‚LÇ´¬uÕˆa9D’ëY tÞ¼Þm¢cÖ1Èà²n"^F¿MbX—è]÷7(¾ "Ã&Äoæ|6˜1–-´9)+Ń1€Ðu]µrQ¤ÙúÊZÃh3DÀç°¬‘Û‘É4kº¡« çÙ@o&#†CØ•rÅ5]DZ· ŽŒ$''J:®K2¥æ•ÜÒÍBu¡#Û¡«J­gRõf“&l›°EŽgX¤»¶ÕЂ«.âó'Ï®æW0$0<Á®«¹°#í̤î?|7ƒ¹³ãYO8OŒŸ—ªèFCUF·D#~Mó—s¹šT_^]" t âܹ—O\½vþ詽wíI¥zü‘^MS K6+']~ÇáI#žbi‹½¼rêßÿ´M®¥£R­NyéˆmIJ¶o(Ë’<áeÂe]rízžÄ.0ÍÔ`âäÙóßý·Û¶gÈ#ZP]˜Z|õ™§_þØóÿþÓòrA“TšÉñp¬aZ”b¶5¹Ö –Ö,¶Ö\]ôtÅ ÕVËPxϑɳ å|MU‚A†%§ú¶Œö‹Mw­Te–X³ Ã6D1Pk4´¶ yxÌ ï¯]½VoJ¦Žy’Zíξ¡›7®‡ü¼ÔÂVKÇÈ–cª 5Qa kHÆ®ý;·öŽþßûZôbÇòÇC®!b™|íèsßüÙ„ äx:”IïÞ¶Wìžgþ/±‘„ÜnÊÕ|­X?9{Á²%ÄcÎGÃ6öûfçO_(+©ì¹‰7½‰^ ~O )blŽìyäµ×OÞ÷àÃ篟ÌtõÎ_™œž^H'†N?Ó1Сٖ¹¬‰b¤U¯z‚©êZ1çLZª®Õ⢦Õlƒ ÇÒeÉ´öÐý÷$⣶ßûòK¯·Añ©O~›€êÆj2ÝqkòV0åMuõ&ƒƒ¯¾tâÝOì# Lçê7o_|ï; û²ùb;à#1AزEºŸ÷z9vìc/Ÿ|óåý앉m¶e«ÂÃCƒ—ÎVxC†=ñh6¿yíäÑ“oa,L-O¥º{~ú£_þí_ybêÜìÜŠftò+K»>I%³=ع}lÿ;Mƒ=æÙl,žð$z{zí¦T*.ïܽÔ(à5mh:Ð4šµ)ÁëR‚$«¦¬$¬×jr«ÉBÚuÂ4 ËØŠ%7Z†®Ò,ݪÉå|~fòº‰Ñã«—Ë.v4ÝnÉRanqòêEʆ¶îQ iíp2#øBŽã4â8Áq±…é:c’¤•fË0U]×!Bˆ ] 7i0ëSë·˜êàºîºî|cƒBŠ3î0E7‚ÓÖO캮‹ûßú&ksž­ Áf§ÅÆ‚ ó<7~êÄÍ¥c¾ H³\ÈëX—C´/¤hJwo·ªi,çw$Wµ5Þ'ˆ¼H9:A¸˜á(š%!Ykä·Žvyx–ŽGF†©åj\èqIlÑωP×o/äg'oE‚Bñ±¢G‘ÝxÜwíúôÜÒ\¡Z¤(>D CÛØñÑ´¯—|ààîH söìÌäüu¶Y(¨fkÏ!Åb¯Î ^?bçç&f–‹|œñ…SÿÝÏÆ¹x«)-UÆ·u‡ßóÁ÷EccÝ>š8Žf<éD×üâÑ]÷±|QaB­6_~åî‡wõmE†É{YM¶M© …ÅthÝŒ»`L˜®íI¼ÇÂXï ¤Zƒ£#84u3÷£þ°iTi2<'Öoý²„WHd%©;–œè¸äxËF^’*¬Îåü Tn|‘@(2üÒ×_Y«UÜ÷Äs¿~›´$J Üqœ­;¶0¼îüL³Vm6´åÉ)–æ #®wêÖ­@2ÌrìÝÝÝ3Øa;Vvt˜ñ2’‚çnÝjH2ËA@ò² Â1T¹¬”\à@ 8Ð6 „Ð…òw~üßåB˜Ï7î>ÒÝÑÑJDÇÖm[FŒl‹7‹ÖÔÌLnv! {xˆ ¦#3bµÁøÙŹ Þç_¼qKŒÇZ:eê`an-î€f ’3·®GEÎf¥ÜòBîôÊ¥‹c{ïfL÷Çr+·UËJ&Go ­Íç,Þ5›öÄĵx""`Ú6­mûÆL…MŠÝÝRQF’%Iu Ù'y“ö'û{F ï’*uB„Ͻ|6dºº:9š¨¯UîÚqàC¿ïè«/.—Ëû÷ŽÜ3ìñîyÁç‹zü]wm× Ž'4e˵eÓYŸ7‘Þ~úøñø»cë6oÀÚ}øðpæ°bËÕÕ}ÙÇ_eðÑÏ?•xJŠÒÙÝ»mdG8B×*Êrãò§Æ¯<ø®Cã—§_~ùÅŽ®ŽC>æ ßþ§/N¿¾cÿ®¦&¯k«·çZ­U‚mÕŽ¡8ضÌv[7Y‡#|r[rB•jº¥–rn·Zª7ÂK"dX®ÜV×òËÅjN}ùéås§Þt)uÇØÞz¥ëLvîà¼a½©^»p¾mVöÜ}7|K3¾°7I0¬ ½>† ’¤iš$cS3ZrÍÐtEnR$°‹]@|g¹®³¡^­¯R.p]wý^纮ƒ7tìÞñ¬ãuÞèÆkp½Ú l|ÀuߦÐGï‚ëÊ`Ýé…7 ë.×u1C3ã 3²![$Fã"blY­Ö–ê­–ÚjW›šY«¬r!ÂÖ‚‡okõ€ßïåÅFµDñS„FØñPðö¼R)ç%­Á2$Ë‘aÁ‹MNZ–ÕØnèºã*žv½Zi¬ÄÄà‰³—gçs¨+–fÛᚆ ‹í¡ïê o¹½RœžZ¢€Cyh¯ñèÕ·®.Þ¾y;¿jhrÀ+zRƒ¾Ž†R¸çðØÚ\e¡´À@w¨kì½ïzOzx£ëÛ–¦X¶ÁѾ™‰«=­¦éš2GÓ  óÕå˜ß“ ¦ÕªbV‚«¹Ã"Žõ*59Ýß ,ŒvmW[­IRS(&‰uçìÑ·‡¶þΣæãŸö3å¦m+kmeGGï£O<øÉO|Ä}}ýñw?öJ«N8ز%Ù1I˜ŽÆ8fÛ¤¤~ëØ[¯ÿz)?éÂë3¹™a?¼9wœ†.‚ŽmÛG|5ˆßÿÂGWj cÛÇ켉l•0E "]’°k0^8¶õÈc÷¿G͵Ëå™ñ‹¹Jnæäõ+ñ €f \Täʶ-äà uI‹½–ÌŒ¯ÌÍÊõh&jªÈ˳e£½spdñÖð^V|ö¹?qì/<ûßÞ4Õ{_×]#þü¾Ð·ýp*ÛÍ1ÔùÉ[l™žš¥:ý§Î½m Õó3Ù n;'kaekßÎV~ŽpͬS&†–MF½ˆl“krÛôx,–&••RÏðÈùsǼ±­`½Ùâ¥!k¥\MÇZƒ§L캮yx[2HÑ H†˜½ºº¸|-ñš²Û’Š+¥µw?>OB3,gš. (RŒÇ lHÑB¤cÛ1h’ÑTÅ5¥-»v¶[r8Nw úB1h¸ 7nÈrqt÷V'»<7Ë d$–2dMi7tMFˆp×¶-Œ]„ìbË2I¹&€KÈu\ìˆ1\R.†¿±2¬—=¸.Øü|3=\¸Î ¼SŠÀUmãEèº`“3ºá²ÂB¹^L¿^ˆBØ]o¬‡$N„’œÏufaa*”á›’ì‹'QlkRœñá(Ã{4‚n:rÒß•[\š×ݲ›`a$54cy`$3}abÇ®Œ]g«Ôòòr8í"Û{íæišhÛ˜µ$YÅõüÂbà®áÛ—r,̱´ 6”Á‘ÐJž$™V"òyc±DðÀ‡¾öéYm¤k´+ŽÏ5ò)Ì—ªóõâ–TÌURN»öìcøû?;úè“]§ÎOrËOý˜-Vo×QSÍK/åfc™«Ìåt¸†©ïbZD– lI­´Û£;†Céþ……œ/–,W¥ÜÄUß=­y ™¦‹¶R¶cšf»"­ÌßLlñsn¶ku¹k{SAú4§ôÐöC¿3ìsÂó¹‹ÃûîSÊõtoFS*ßÿã_ìîÈG;©ñÙzG€Õ1v-×á ¢bžþûåãŸ}xç«Ï}gyMJ‡ƒ¥Z+¤,é÷x çÚí3Û¶1mÈ áàGzç}÷|ëû?ÈvøiQƒB(Õ&o®Ñ.ò$„ª3>ž#”Hw¨Rm\]^>›{è“Gl¶™!m{­M8؆¤A³åújçÎá­þÁãg_#ØÅÒÙíÚ:>{ÁaUÅfb‘D›«Öl¶Q”ï`øñ÷ÿIq¡6që„íÊK¥³‡ï?rì×Ï‘Œìõ´–ªCþž}A~©xÖ Dý‰¤¼\,Áv“(ä—Ð+•JÕ|ó<„V$AÌ/É¡DäöBÁñ²¥B.¤"©.I‘„H˜b×WWžxøQ¹&ahó V‘gy/º}ôÖ;>5úÖ7rc,Z«,{|tu±Ðn—G·?[›Ëå“CQ9_(ÊŽSWWƒñ@XpÞÿ0’£±¨‡ö{úc7ß|óʼnË++•#ÛdBek­çνÿÞ¯¾õ,KEtLÜ* Õ pã õwí뮕µür‘ŒZ»zü¹ó•p<ýÁ~$ï­-.ïéUËæß}õOþðÏ?òƒÿó=M(üòDk¤¿Ö,,?òÙ‡ÃvŠÎÅ£7‡Úþжp†6h5]_rq§\ à"L kZKj,I @ †;R©P,̰L2‘¶-2<‰ ?FºúBÃqŠcHA`u’l×Īm­]mÛvÓEÁ×§IŸÈÞ÷oá8½Õ¬aHØ´–Œ„=ÉÀÍÒdÏðÀülI1Êmì8:Ê&£¥º‚Ygÿ]÷+ ÚÝ“í?ü÷úðILýuåÚT,Dî<0œ[ÿøSŽŒBD­U#Tè™_¿±uO¦´dUÕÕO~∠VkËcƒ#XçT€Dˆw¤É;.U*âñ‰D ¸G”j¾§?æa‚Rk¡mºaÁ7wãÊ´³]‡\’è \€ ÍPÕ7¯ûÒ@f@mcEªúÏÔ틃ñ`ĵdKW:’#SS«ÿúýÿùúÌ­|~‘áh¹l6W ÛG¶‘by©ì†y?M˜.vYR¬—0(`IÉT|­YkÔ-QðX†Êbv±ÒîêîÞ~ðÁg¾þÖzó¶í˜©ÔÐÇ?ô©×^ú–‹…”/¬éuM% #Ħë\¸pqn~îöW¾ü·R£ÀwE¾þµ¯®æ ^/çðI1éŠNšÑ5:05S9ý"!Úšáš–EÓÕr;Ý7¸»¿ç‰‡ýÎÁƒé~a×â‰ûnyþyêÉNý癫¶í AR486ÒNÄ[rûï¿üÅî-ƒ7¯¾þCOõIÀÏÁ`(Ü»sÇRAÛß³'WYåR‰ù’,Bø¹¼Û~èϾòú¡±{«­ÊtuÙ“ŒN¿]‹ŒexþéoÛ6”/-–¥8²¨h.ã/K·ˆÅ­nÍ*†ns &uj`8»Vs¯¯ÞÜv°Çm†\]ó{½öÕøk??žî ~õì —.C$í‰dWç;YÈÂèïÿôKŽà+Ì·3™O=ôÎ-{¶w$2<Ë÷E£^_ÈD$ä? "¾†„|,@YÈ×?ý—öÙÏý~»áþç×þŸ'>öqÄÇ_¿¼øwÿôoÐ8H˜É‡Ê®VªÍ&†ˆòÂz3ßûžtÈ`tÛôKUml4›ä#–ÇÚwä‘ÙÅ™T¦£^+<íÎÊÊmÍÕêµ ¢¸ÒÚ° ÒFk•²ÖRÄ0­©úâÔ¥XOaü¥µŒuÇq-Ûa9Ú¶MËr¼ÀÒ„æÊÅ`ÈoÙn»Q¿ºšŸ '½ÛwÞÕ¨·®uÄ\—®VJ†¥ÙºÁ°‚ÜnéZײLÛ²LC·`—D BQUÃÐ C× ÓÙxž!ˆÚÊ``Û®kƒu8Ì–„€hƒï@DÑ&±a³DgÓî¾qû#ˆÖ“†©uO<€×…›ûÙúŽw‡ˆ “J„E.½¡@ÀÕHEQ½o ‰ @Í$‘käbéFÈ•’Á4”:æ1#H¶M —¥Ø¶Ù:²{t´£çæÄÕB¾\XZËf‚1ž)Ñ+êªn›Î½ÛÏ\™[š$;ò 6oKuOÆÿþ÷>)×kaAåIïw~ñM‡*l=8¶w×}}#™Ñ}=#©]s'¦Þñ¾wüä™.G…¾][=ñ^İ…åb¬}ñR_iÀ¶ñ2Ýݽ*€„¦G2)…±$çnO¸¤¢ép¦ª Ú’DR0ѱ•¡Å–ádÃÁV»¹6»:?xýò1 )à× Ë‘ªi‰¦«§@†õð» ““+Å k.-˜”HŠÁt:xö¥g³#½wuose‰b†Àâã¤õóÿÁg>¯U°K0„-¸jk*EA‹ÓóÓ-5=@a`Û¥¹ÞŽÎë“/Þ8~<–âjÅ Øv\Û”ßñäû+¶R™_*.U E¤¤¹$,Ù@$d,ÛTKAÌžá-ÿð¿ÿõcô§[÷<äCG149šËa’,Oò ¹UÞâC¬À‰aʦ1‡TÉíôøÏ¿þ}ÕX*ÓÞŸ¿Zzóé£?}þÏþòµ\iÐâÞýû?÷ò佟yó¯–å5”äÌ>ɬÝuøH6Õõý¯üKÅ6—–g½)ÑU¿Í/Mõû‡äFe½ÅI)DÊ…Ùlø¾û÷þÞ„æÖN\šy¾‰õÕbî r IDAT-ߘܒ˜~á¶èç»]:$ò!-ìMS”¹µ¼Kz´zi÷¾=Ñ®„Ú¶"‰ö„M¾ië8µ%ûÿ3õža’]å¹öZkç]{ïʱ«s3=9K3Êa$„D&06¶á˜Ãñ±9†ØØ2Ÿ16Ù0( @ ¥QMι{¦sªîêÊaç´Ö÷£gÀ×U¿ªê÷{­õ®û¹Ÿþêµy›µf¯Í®_×¥×W’ÝÑ€üÓ?ùËÕ±…³³w nœ]š²MOÈâjÁvTÏ,îÝu ¡U3QE`"ÿõïÕÒÂÒ´‰­ïb‚”a¥p¨jÔWÇŠSs'»Z“¯<÷Ê-ûïV¢ÚMæ¶nØéÜjÇ+ÇÂ}éH*˜_(«^CŒgL˜V3 „&JËìÔêØ†}»Â‘6ÃfoKn„>rêgŸ=Uœ˜~ûµ·~öí]¼ð&åÔ‚!6oMò‘Í×J‹Õܲc#‹iß!ñpØ'ˆg$Ñ‘hDYž[È©ºN(b =L±Ø¤TX®ëªë8úÈ–mšSâJ÷úÍÅRi×Ý»º†¶ôõêÅæÊ⬋Œá-£ñ–á«GO!ÿÖÛ÷¤¤,y6P̯`ÇÒ5â»±¶eÙ†îÚ&ô][×fÝulÛ4lCû¾g[ôL°ï¹{k“Ë÷lCo†êZºm[®mbÇZ“Àƒµ«Ý ëՈµbyð{WøÃo@ºÑÖ núF!ÂþÚC$€¬ µÖ`-ß÷1ű’lÖ DY’!¦1¡ Ú;ÚD1`«žíÙ / :º¡}@RbzC â’X,O§ `Y¦d…“#>¸´¸ryjše«DMÏ?ö‹ç¿·\,$šåm§NõÓ÷Þyÿ¥«u&hºèµ—ß©ë«Ùd‚…*åâÔÊb®–ê‰Q„.ÏMXŽ ,×çh„xŽaW–7µßºãNN`FªjñöÝçÞzøýŸÞ3´‰ Ðã Õ%Gµ¦WsI…Ÿ_´,è°¥chÛŽ… ©{‚H L0Z¸2g@Èó~ÕõS /%¯¡Øw±6ˆU-Á @´ˆ¸ÿ>žâƒ”ÍI®ÐѳX‚Å%}¥ µÕ¥EòYйvå¼<Ãâ Ëш$p"M!Ža1Cˆ…± lÑ ”¤Øß6¬iÑu½édyµ±e{ÿܶnh§c[>` “’¤H4™5mÏh—––C²Ìq4ËB..,W|QúèÇÿ¸}CĬa„µ¨$ —–ºRÇ%†ùé1¾a,6 •ãçmY?¸Z™n² R-M•.õ´µÚ&¨fˆ:õÎC=Z[\$¡oKŸVh8uýÝ£¯¸ýž·#X~Y–yš÷l¼:W€‚W_yå7ÏŸ»xJ ±¦ ]Òdø@˜ÙñËT@?{áÒø‘#ÿú•ÿK¨’ƒÁ>ò%’¡y(Éá‹gÏÿéç>ÞšÝïˆø£÷^Ÿ\ذ}{"Ûç Jïý;ÚÂʹ©p ¸x%—N$W‹œ,ìÙrk4ØšùþõÙѾѨ$tmú÷Çzçýöôß÷G÷Ü÷Àý¦úú «îR×ЖFÃèîc)h9 v< !1¿0™Ë͘u¥8Çö!ÆÂ†n䯮åÔ¹D{Šx®ÄŠõå’m«aMk¨U4-ͨ´v´ŠÑÒ,Å!*•J——Ûº“]ý[¦k¹ÒÙ㇫õåt{¦`SnlNõr;î¸+–é–”i€,Í@e&ÍÐ QcǶ0ö°ïaß§ÖvH¾¿Æ~ú¾gY¦i†¡[–áz®ç¹žãx®íÙ¦mê¦Þ´LÍ2 Sm؆î¹6ñ\ß÷¿×‚ÝTk3 ÁßþÀ ­ßMñÕrÐk6ˆÆkóÉóntÞ¨9Ę&fy9!KRbX‚L‚ð}‚=DÙª¥†ƒ±Š¦[+j6f9ÅÕ Õ2=Ë3=Zw4“f8†S¸$tÒ `Qãò0ôåpXAžÅÈ\P ÏNæSIaßè-—.O´$åfI{õåW¶´ÝýÀÝ}ñÄɺ±–‚ñîÖ=Þóî‡2ÃÒj¡ 2Ȳ[2ÉT¦'È‹ëZû¦¦wïÝQ\Z !§nNây[¹Ü,‡”Ë—woÈFÀ|Œ ¶¬j]½øÆ›Ù‘u¶¥»Í&b$†*åÂ-÷ìqËtº=”3fµÎPaü×^yQ CAŒ„á ò›çŸŠ$ƒ+•F„>ð °)j™T{²½ÝÒ‰okR,œîh `: Ë@à|Ï÷8ÆGŽnI!™>±ML|Ã×LD!Ä "ͯjWƧ²ŽÉðT~ö0ö}gÄptî͢,ue»qQ¯±m¾a©áp0šLX¦qôÍW`P>rìMÓpD†rƘbiϤ0…¢ñhÚõ}`»ž§k%)Du_I°yìý‚(/¯Îÿæ§OÿðûÿúõÇ¿QªV,bh†JöüÙ+\(tËÎGª‹•x"˜L·Fã ‰¯~ÃÖ'ütÏ­ƒV™£ˆ Í*1œåBEâ•#)½x©\mom+×…B}ã†õÇOßuû­Îª•× ‘X'‹‚ˆ H4_É7wíÚf7¬ˆ¢ø·¼×|#Øw,Îåš›H%»Ô‚™îî;3Þ3¼q¨uÝÖ{vF“‰Í{G5Ë*-h‘xBÕJ¼¯”R©AL{¾Ïs\ ¼H!š¡90Ï‹¾ 4¢ €Þš{"E3QŽeº¶E\WÕ´Z©P/¯jšmj¶¥»–iªMCmZ–ehš¡i†ªjõškžešj›ªç˜k ¨›N™µtÿ\ó6¬Ýûàï\ÿ­‡â†aí³f¼Ér!)×swmÙ¦W]^dêªÃ À¢ ð}Z`/Õ–yARM‰¦yY ùØFB¤€ÜFøpiRcy LXN.^>=sÝ"P e Ž È7·\R ª)Š©Wßzi°7°0n<þr¶¯kïÆÍºgº%Á¢G'jÍâ¦Û7åêËQ*8>³áX™ÀËjµ7“RÁô¦ÑÁ—_xéþGÞËLÛºnÑe«ÅÕtg·ï0 õÎÞ®Ÿ|ç{}£}²Ò MІC¡™ÞúÍ1¡;Á¢€ë»¾ëJ¡p}²¬{U1qÑÞÝ¡—]×PZ8xèæÂ’é²,«YZa6·xöJ­PQB­€‘tÃo¸¶(ˆ—OMp1 ZŽ¿úÓÃ6»R:u×Zºœ«ØE&*kE•|âZ›ŒHy®çÑ • {Ķ)ßl6=×¶,¯¬Õ©ŒÐÕÖá®ÖìoÛ¼sìò¥ÕÅk‚À¾õ›7¿ûœ(%mr¹¥%³(xÄñMš£#ÑVdBYëû†|àC_øè‡=IŒhÙ®ã’FµnC–bú¼@a‡å¶»Rw› „»B›HÉ׿.];u:Œfø¬Gq¹GïØºqÇèP÷†l«2ØÚÿúS/œ]x·m¸o~jqq5—N¤ ×ËPqnÙ»÷–;÷³B<ÙÑFVð…ù‹ÁdÐÈë©xhr±në¿pñÊà`»ܤ’ܾeóù W²Tj,F³œÛ(S 0ÁüòÔų瓉΋ç®âºMAhClTªF€Y¨W)62Ø/ €òÉDoyuRa›#C=›ï¼ýþ}w|øÓ¹÷½m‰HÅòÌîŸÑÊA¨™ N‘›Äbáº:—Žw}ùÏ¿’_š”vii–0©zÍÐ`3œ•‚g–¦Žž:Ó•Ý‹såbé‘?~ODÞdJf¨¹Å…[ïÚwáú%ù7­_*²sÅ劭Ž--„Yùìé·øã§ÿå¯>{nþíT2Ý‘ìUdåð‘CwlÛmiÒÈžÍA>,@a뎑ùÂôØï´v…ï}ÿ£w=öa3oB×g bi–x>DL¾R¨0&ÀK¢ÄùW\¯5êrÙÆxi~Eo48š H‚e:•RIŠ…;7°‚¬•Œ·^yquu† 0Ý##²”¾|öÔÀŽž¶öM¦nr‹MµF±4£H݃ƒj³RYE¹–e™† i‚}„'BD€iš¶cy®×,•—ç*ÅeCkXºfºëy¾ï;Žm¨jµXlT+Íj¥Ñ¬Û–iZ¦©kŽez®ãc¶"xÀºÑyzCs³ü’›ç/ðß’878¨_û5³2!Äó½ Š%[‰kx¶ÍS¼íË" Bæa$ζ‰zÝsšçÂé °1ÏQP ìIaž“Ks´¨à¥cDˆœÊÏÕ®]Ÿà¤f*9/6+¹e%‘hØ|×p°m ýàþ»¯,D®_>oáG;û*S¹ñùy“^^¿û€]7î~ôΫã¥ñóãymÒöµ‰Fά1´zø¡Ýƒ„H*FæÂA.xêä©w>äDžç¡hrÁ6ÛñO9¾8;Wª*9SQ]·šµt ÀcÙò$–Æ˜Ž…Ãëb4Lw¶e/Ÿ !:>Ô.³!ITZ“ÝWçf¦Þ¸þÎÒñm;÷²ˆšž¡9VddÓsð=õâ¾ú-±`¥ë+“4©6ÁÄÔqË Y Ž$‹ªÏp”ç»–éмçXV*®¿õÒ¥+§®œÝûÀw•¥9©ZÒ]¾Ip&Ørðä‰Kã³Kצ¯OLU …€ˆãr–ŽDú‡oß³?—7Ô«’ÒUZ.'Ú[cr|$Ûý?¾ðÁM#ûR±NÌ.Ÿ]ÚÉR¹âRn6· Xn.?æ[½:±<Ò2 ˆ Qa9:€¸uÇN»i7ðꆽ›¢ /¹^I«îîH{»û(è_œšB$,‡ã”.9t&TÄ8f¸zC“B‰R¡É³¡¶Ö¡ ¿¼î`F7íÐjñ2ƒð¡#—_ºTZ¬ýþòg¿ø iR#­aE»µFeΕ³Ùödç}ضyßÊô¼Ù-£û÷¿Ùçp±t6c<‹¢‚®K'žè9XNÀÎDŸ¦zÁd˜öâÒÊ ?|ö[ó_{æó÷ïÝÍiæÛ—^zìö†1Çq¯\yû壇­igëG¡õÇßzÝ2ªO<õ«ß>ýD®2çשãm cPõæô€’À–ÆÉòÒÜØÄÔÙ‘‘~ˆZ–E"RJ¶´…£a‚(%ª´·õ,o¬¨‡_|¾X_¢ØÞÝÖÛµiæÂ5 hCûlÓ#6‹Õ«'Ž,L^6´jº§;m3L«¡VmÛ¶u]­UM½ |¢BD4ÀÀ±mÇ2!…즱85¿œ_6›uÝÐ,SǾç:®mÛ¶m×ÊÕJ©ÐhÔšµšm›¦®i͆mš®ãzŽãyŽ=c|¯Z;+ÝÄÛÿ@cý½ Z{M$)„nªÜ$ÀgkÙ1åâq%Ú;2úÚoœ?|Ç­Û 'ÖÍæ¯þ¿oöõ(ŽJœZµÙ¨.¼žÿÊ·¿±q×­^óBS 'i2¬yË£‡!š¢ C Gb+Õ•áM» ³RK{£¡êZC޽vdhW†E|ârœÉ„âC1>Öï©Mà: bI8¡a.8FÕ%Ø´½È„Úó« ó×fæš3áL¸ä¸Br€ NSž 0ç!Šóšž[+”ÚC±¯~áÓ›v|ôOŠ^ÔÂ5Ý/ Iœné:öÒy§»ð™‡Þã“À7¿÷•jÁ¿mǶÞÞ>7@W´Ò§?÷Ñ‘{^|õ$µìþÛOýC;"ƒÒb˜p~¢½£7ÝR­»p¬­‚x”qA¾‡¡Q&g§#4ß’m)ä¯,-N­–—mQPS‚r– ìÞÒòÑÇÞóÙÿó‘ûÞÜóHlXúÖß=î[Õ©óW¿óÝÎMœÞ¾ñîFiª¬Íjó©Lr`ûÈö>Ä+­ lIŠd¨4,Mœ™_øÈû |¶œo´g[gÏOt ÉȦjù뽺é áPP¿öò©Ö.‰<š¡AÇ0Ìt["] …ÅcGŽeâúìêªÍšù/ØÖ§Ù€Z­É(`Õññ‹@üáÍ[ó ¨Ø=¯U5 h=ÛÖ·ùæ,„ ‡™¹™rO³IÜÒÝ~ììÁá¡­«``ÖÊ%%š?6öµ}Kf÷BÁüRNä3JH|ÿþìh´¡ÕÉ…ŠK{ZÃô3Ù'§`Ü…¦f:ºeû›ßÿÏ¡þxoÿ0 øÁÁSG¯¹x|÷àÖýŸÿª±¯½õL -öoØþï÷3_øÒäµaSm=MÕhMÆÛ:Ó´ÃÚš]3ËT ~ñÍw;Öõx>¥Z5Î㊥j@dªUÕðê<'†„CIÐð÷›_çò×iz†»·í½Ç¬ã…¥±þuM‡ÉMM—Ê+r2&…£õz=Ÿ›SeÄ£P0”mï’•â8ˆªjÍfÍ„EÍñ‚¤ˆ¢Ì3 $±4 ðIµR­W*¦®¹®m«F³Öpl˲lË´<ì±ë¹¾e:år¥R*4Õšm›žëú>vÛó<|³ÜÜ 0ß|xü=Cz3P}#b¨/~éKP€B¡µ0„"|,†BæŠ66s¥kd”ƈã)%–di°^¯ÔlàB0OR Ã"dh . 1Mdx Jf*åjG_Oq¾ª­ê¿{êÕÁþÖëÞ|í¸ ‚‰äÒ­ñÌT±¶µ·;›|æ?î4B‰ÑVåZ±ÊƆ»[wíØ›ÏÍÝýÐ/M¹Þ*È3vÙšü“OýYådõ‚zô}ÓêêÙ©Ã󕯤²õùÕc¯Þú¾½©pG RÕ†kQðNÌœìK®9¥(š‰G2—ÏžÞ¸{T·)Úº^¤R”†VRñ$NL" Ó0*r(AÑÔÌ™K]%Žï¤!GBôòÑ“4<‘’1˰$ŒhD/ÍOMµ»k£ÂF‘g/Ž+Ù0°üWž~§Ÿ‹g‘®²È·m„ë0”ç#Ø ²ÚbHQkЦôu›{9¹sã¦už—ïÙcR¾ï¶¥;—Ë˽]Crºå›_þZ(„[ÒÉKâéø™#oç*µm¶ì»÷=—/_ ÑÒ譛Ο=Mù{Üý…&]lh$7;ëðMl)ù7i*Hh““B1W¨©KˆŽw%Ùu;îs+ŽÃ:SÝëF²m¼ ä¾Ðâ´9~òÌùkWg¦¯¨«úÙëÕ–Hc|zQnMS%+§-·${Z³Z©)!ùÉßþú™oüÓõÒ¸§yÃý©[¶Þ3Y:¶Úl†õ–±ÚD±®¶ö,ÇwîÜ6ueiÒ8‹®õWÐbï@è%žyõéÿÉÿP§Ê ¸ÚÖ1d–Šãß9sÜsùÍí‰A„ÉÄäÅ{¹{õJƒ¥U1Äò-]¨FšF¥¤iÅùúôùóí{6ôFÒÆb•Jßo 0t(›õ-Þè¶â±PoßÖV™)_¹òÎö;îS¸T$|û¹ß¥{ÚÝ%³Y³PKŽ((–üÙ¿ü¢ÚìÄr£àt¬ïõôR¹¬¦zº²ëû,($X*Ìl[Wž ­út ;È£fÕ]“jm•Bnšïž¼2óúäK'ž<¶+«Üó¾[ŽøÚs?.»µ›öUóådK"‘é 2\(?z¶jë"¶ó¹ñéÜb©8;Ø×*PÒÅÓçùhªLÝZu2ë:HK FìÒ”@Ò‰Ö7žiaq,Û‡û÷ÝóòBNIvG¥”óK…Ü’ÖÈCšB4ËrEÓžiתeÇÖ“­ˆf9–ƒ¹žcÙ6¶-ˆ¢(I‘E9DÓ Å0!âaš"¼(z¶mÛ1 €A£Þ¨Ô+ªj–ëªåÚ4e‘§ݨÕ+ÕªïÙEA±ëúžo˜Á͘ÜÈðø7zéo¨nvT@0²æUÆ7õ x õBB º¶µåö]gÞ\°ôeÑÕFb!Ô4• í’åÜB}u™£€V\ñ=BTךÈõ •–¦Ū‹¬‘‘î^z›„Õ=;·¢á#oŸòË×]Q]k úž»v7ðó—^T2d°¿k×p_ni¡»£%ÌÇA øÚ‹ggçfž}î%@û*e'ØŸuÞóÁ?AväÈ¥K¸ßY¢ŸüåíØ¸£»o}­°ôoÏÿ¤e´#í <ðüöîç^Ÿ{æ›ÿôŘf“@kk÷‰·^(‚¥ÛK¹9Çt4».2ÊâܵÎTÒ])øê²$µJžx™'Nœ–c¡Î–ÍØ µ†f×1†ŽcDz-!ŽÕJ+AdX–&h|l6UŽ §“ù…åöÖ pý닳Ukò–mƒ† x \Ëxʵ1 P˜B\Ž “af!W¹2SLÈ!l׺¶ŒFéHLöhÛ”pÿÈú_ó™úêÿíï =ö±ÿYÑL˲•€âq¼LG'.\åéJFƦ.¼ø›_ñ2¼ïþG_xö-Sžõ\F­áHú»é†%ÎÆ‚o59ž!¦—/-¨¦X Ú‰Ó‡Ž_8½S§K+Íæ–Ôù•òÁß9x꣰ ýݪïwÄBcã'Þ½~¶1WìÛ½g´»¸Ža:ªiž¾zè•ÿ8<²o×ÇûÄ®½·ó‘Dµ¾â™qârWO á@2™ úpµ8gÔ´‰åcayèÔØëÉpÑk§ž  GÜ‚– p ð1ñ–çÎÏŒ„Üö‘~»R›>fçVHèpy%?'·…m“° ¦Óét[e±P«-u‡Å‰•™ËKÓ%Íó¡uç½{tº* Sk4ÝÊâl¡·³¥+¹ùëŸûÇ·Ÿù…Z3SíY«^‹Å³ªVÌôåë3ñަ[Ëõ µdâÊкí׿®×J‘p4ÌJ–®&"×KùBcŒ.2¬FÕ°V QÛ·o ã0ruë;%ÄJ#ˆ#….ÓxµlžüõKJXk‹ ýßþý“ÿõÕòRîø±·O½s¢Y©¥z:x3ÀÇè ;îÞµõΜ,7ìWþzj@ Lw'= Òm±ÖDƶj4<ì*J°¼Xyó…—.GSÒ¾ý¶‡Tr“3¥Ú‚‰Ç/Í/¬ÎÍÔVó¥¹ÉÊÒ|eiÁhÖt­AÓ0•É h^ƒáP8ŽÆ‚Rpm3îX&±"‚¡P@ ¢ŒÅÒímÉt‹,IBÏǺ©;Žã»¸Öh¨†ÖÔ4ÝÐ-ÇÕš ÍPi Ñ4 ´MË4 ÍÐ˲ ø>¼ig¯‰oöGcBn˜eÀH0‚€úÒÿþ«?{­…~ÐÚ€ƒHà:•ÒT:Ùê#Ó6ÀÒܵ‹g’-Õ°8J©ÔJš¥…ƒ"+b(J± ¡¯òòÒÄܹt6]]°WêÓ?yú ÄÕwß±Ñ7¨£'ë¨Ala‚¬¶Öä=ßqéPa|ò¨ÃÐÃmçbÌ·Æ’‹…b2•½~õŠ( ŠÄŒTK^PfS‰Ô½<¸¼ÒxñÝ—îúÄn\kùÙÏžÚÖù¡Âwðãõ¶ÛöŒî»×n¡€h¿Q© “‹ÇB"ÉXˆb …x³¦º¬ºaÛÎ\n. „ÍB1=˜¿RvPUàB€HÜiØÐÑÂÙ6Our…EÛ1Âɨ¥D›©ÖŽÕÉb±v„¢rF …)Š¢±¯ëöÔ¹‹|gXfåH"œ/—£¬‚EúìÙ‹W.Œ!\3ù`cU‹§n`†P”èÙE2œà‰ˆ3,‡ïNÅÛ׎_šêL ñ€Ç+N¾&Ç›ãy^iÚqÊŸø_G†»väС‡¹Ÿç“3“ÕU½°°tÛ}wæ¦çæY>põܕï½æX¼ÄùŒB‹‡Ð²YÄØ¢OêЬG˜ Â^$FÛÙ £Z ŽF’‘ÁM»Foߺ»»§ñJ{4ÖÙLôvnÞˆG•pÔta$Ý‹¤ šfîÝvCëžUº~ö Ï“<ýboZÚtË–™ËÍ7ß~!À¤A¹kÜ IDAT#Ò@×zÏÒÅx°¶¬ve3«®¾{ãí‡OŠG;LÓ>ðÐC…jñõƒïnèéjïÜT]©Ì.\hßZ®å«õܹ¹ Å·îØŒ¤_9x wÞuçåSgóÚêö-»‹5ï±|ž¢tñÒ›;îÛߘ¶d\-O¯ÏYºêhºOøx¸“«ú*½ìEbml¤ Í \º¬g·&°ëGÛÂÐä¦f^ºâ•TGZÁËQ^r€pl²úÖõÛ)I$M¡8?Wž ²Q‰ˆ´\óQ°T¯&;:eÕ_+{Ž=;´þÖ±sãw>tÏJ±¸oßö+>ûƒ'ËêÉ¡M{®N^äÃûO?O¹dÜ»?rÀ¨B쪡dàÀ'>ŸPZh@jM­ÞÔ(ôt×Ë ­QÎòà Í15ÏöLÚJ[ǯ^Fœ»}ß®­·ß›HõbH5Js‡aÖÁ†[)šõªíZJ8„1Ž&R¹…•¥¹i]«D.šHòJÌu†B„`ŠfšsƒaXË2R€fÆÄÇûŲ ÃB<ßó|Lð<§Tjj–ASÀ²Œ ˳‡ç9…i9–cLס†ãxˆ(L¹¢þÁÖ~C¹Lþ Æ„‚ið{¡ÌZ§Á㛉Äs½»>¸ß2ìÂøX¹V‚€ Š2Š ÙÍj3’Šp4-#ŒÀdzû0áÆ™¶NW1õfÙEDÃÁìSOür`pÇýع‹3ï:Î#£«½=æ§Î/ ¥‡ë:;9½"ÅAG¼-€¼é†Í,é ½ÞÑÖ¿4q‰–X‰–‡{™ž€9ãòÒ¾}·]8uþìäÉïßIpd±t½gW˧>þ™–dÇ7þùï©äžm»\ÛÈÈÉJy)I/ë°dTšj­n-Õ“ƒ±úÝ émžå)!Ù¯”—ЊÇ=Y«àéΑíš94°µ—x\¥0M!V¤‡hbZ±®.Ïe«•b0…ñAž¥é%Ìù“Ú»Ò$ &ÂaPÐð0åºM{~ìq!P¡\h˜–n±Ô}DŠ“Ùª…DÇ d£æŠ×4wv/_\¹8wè¶ö*uC.áýBQõl;Óžò-îÙŸ=ùþáú±úòÒ¬í©¶çp=ßõŒb¥669cè5Û!€ÌàcOÕ0q,CÇb9ÏÀ"ñ-DÑØòiŠ8®ˆ‹+[÷ÝOcš=ýÔ ¼Ä"˱°#ð„M>´Üå /š­»Ã)Íòt5Q5šÑß½òË}Ü_˜ÃùʃïÛs÷þ;®¿xââÔAâöÿùÿùB:Ñõó}ÿäø¡Õšmsìfo‡_}á7É{;gÏ^YÈ•z»É`K¬Y./­äeÎÞ3âÖ¡gxÉ6ËÑóµR!·g_ ±ad#µ¨>ô¡š•†îš-IÙ‚Œã× ÛͤÒG¦×u/¢ÄVýk«ú¼À2C}½¬ÀŠLº¬V!Á+Íéá[»U7ë•[D£VGoû™wŽß÷¾¿}óÜ«ñT ªNçh"ÓÛóÅ}·~êÄ#îŠuï]““W¾óÛL¸í/>÷J<á:Ë£L_ºêæÓr¤VÄÁL7\ÈÙu-=ËêtCÅÕRaÓÖþBÅÚ¶gËm÷>øÛß½RÎOÉ–Ž„¹"úíçßzâž}wµ¦z5waÏæ÷N«ægh¶m%?wùÈËæ*rDm÷­Û˫ճ'Oö±ëØØw €ˆeŠ t]„ÄË¢ˆ1ð4l—øÀñ\ ‘çø†¾ë8y’ µd&˜ÜHþÞ'zÓM×Vî`éµ¥×ïÍ37§kŽd@ €D1ÜÖNÂDQØñÂÉ÷½€(‚]ìr/K!iì@ð}>(†ñ :üê¹ãÇùÀûï¼e×3O<úú%…zca¹¯<;×Õ!FÝîƒÇÕ)§«3ÑÙÛ}ùRy.Vº5ôÁ)ãbwf`q©°n``º°Ú=šìŒßþý~ï±ÏèÍvÍ\;sìµõ;¶FPvÅhv´Ë;o{_2’9y䬣۟üØçXˆŒ =’δççVCUŠæ¦[;}eXˆÐ(T³›}ýë µI£+ãÓƒ;{ó…|YÍutôˆlœ£ù™ëãÁˆ€xÁPušJ0Hñ¶‹âLf}‡Þ´j•¥[ÇR4Ç@¤ Ç"G­YRVÃAN ÍxAËñÍòêJ,Ȫ¾Ž8‡ p¬N1ÄáÖ7ˆ0°ÛD B˜&,Ùµçö³W_‰'&;v‹Ø²,‹Ç°^,J±à†[n=þÎ['OýŠm¶†cñr£é¼ÑhÐâBTÌ]\Üóðúåk6KÛ¤¶1oùDD¾Ž‰I€†6 HœG3¬SÖ Å§]ÎL]ݳ}ãød#–5î9°?™‰PÊ16!b9£dh2 žá˜>DÀyx?Ï…¾ý÷ß她׭̔ƒÁÀ@o—W¶n¿ôü[ECì ²Ø©CîO¿y)~ìw‡‚YE`»ÎŸ:Ê(^RŒ_½r1’:iù“W.¶gR ³+6àTþÚ–m›s“+žkñØ›š.<üñ;à&ÏÊÆ”Á‘õ\5G3aÕÃÐ@µ¸P›[XZ¸NÉ¡‘uÙß|çG5zYΌƕŒ†õ™Åë¿~öm s•Õh2ÒÑp Épª^©,ÓÅÊrÕÊå¯üdúCº7Þ÷ë»ÿï÷AÙ$ë rŸüË¿ZZ\úÉw¾uäÐËø£Ï––Ë ‡³­m¾êÄSÑ3ÆÂöMï=ÒL ‚û¢¥Bib|ù‘÷?ðà£?þçÿ¢¡Yš†½½­Ýmò¥‰ÅxÄá¹àÜâL¡VÛ¶g3[vŸ:70´n}ÿîñ•ùG?ü¡×_üYoß¾7^}‘JUîoyìOþóŸ}áS Ø:yöòýàßîýðþD,{muÞ*6mY—hí[™]:ùÐŽ[öÅ[;<ß.,ä9AZZY¥8–¶„¾Á($EQÑÖŒ®»NÞ½t(–¥®]˧[EŠ’¿ð ÛFÕªì†u¦n4¬êðàës%ž$UÃ…M† ¶þ^èƒÚBQwš#­£IÑ®KªõROOÛõ‰ó ‹}l¯où˜E 5µ•ŠçOW[ˆY‡Vy;•ôuBÅ}ÇÂÍzˆr *c4 tÇ¥E6‘~õüü§?½Î+®d9*íé¾Hƒ†jÅ»Zû¿ûê_oØÔ›45>Óäù$K5þæÛ_&À‰ WOôx?ÍHzÃñ(Ú×í/ ¸uƳ›¬.¹&¶i'@¤ ñk®³c÷Ý{ïþÀÊ• gæTsâÜe5Âñ ¹å@€õ®”˜æ™¼JƧ0ëK4°6ÜÚ!)Kó,ÓìnéYwåà8-þþ‹ßÁLE‰¤jçæÞ˜»¼ûQ"—#ÓåâÖÁWÆ.ëo¦8|ëúzY©¹9Š ›žCIÇ5–VÅñ:K‹g. Äüi)èãºkœ/_ØÐ•I ò„¹8Õ À€ËO¥H:Õ“·µ®`ºVU‘r\ß´îT#©”¯ ƒÒî® ³ tw‰ÈTRZÊÍ?¸¯çõ婇ùÈë /Þ»-ÞÕ9~-ßÊ)¶Y|ûè›JHøë<µ­gSn>_*¯îÜØ½¬Yê´{K2+ÜóÀh[ßgýì—¿ýgD#*è4¯›2-'ÚÉ EãÁuw-/­DÛ4Dª[æ£Ý}Ý£a)þîµc‰(£.çKóêÖ]Qdä̓o¸ïÞ"äÃ\cÁ\Î/W̶ѳ”_íÜÖ¾=8²uÛÅs¿ñ|WFé_¿™¡bóS×§¯M4WM‘e(Šu-=‘hµËu5_o–ÎF3)Ž”W–—›âòj²#¾ïÓ í8&ËpBCW=×yÞ%˜aX(fÛò±çùˆ8Žçù>ˆa=Ïw, cÊ÷1B”c;Ø÷MÓ$# hšB ð±/<â€,Ë.ã{ØaiÚ‡ˆøÐ÷°ïú–åBš˜€ŠÒi(jšËp ÇR  À¾€¾©û»©n÷o\é}0ñ)D­éß1º!y€ˆBà†“`YÔ¬áüò\mmQ­ÙÈ´$•xÖÇ€ \ðÛ_>¹0]ùÂÿxÓ†íÿÏ׬»óú·nØ’ZÿÜÁ'â="/UËyq[7¶ÊZml1Ò§d’-:¶Ú½íù'Ÿ¾í¡Ç~ôn¥øøÿ~é{ÏÝ÷¾?Šwô ¼~q©ýνw=øèÊød[_ÜŒµd†·^»ìù°;ÛÎùöôìt,ܦUëž㩎Π¯-°’QÄp\ºvúlªWjk]×TuEÛŽuïYZ¼taòà§oÿ<“NÁÉùÉÖž>F ª^Í-ÄÚ3e‚éxµ¦FC!su¥©.”‹]ÉÖaH¡êJ.’¼¼”ï]?0"4ª¨uX®É-ìË¿{—çDÛk ‚T·MAab\Ö7p‰ @Útl‰â uŶÊÒKÕ¥jûp{TìÿÅwðÅ/}Ùò€'JŒa7šMQQ…7ط募ÿê¿>þ}ëáØ,Ý?йœ/*’ ‘‰Å•oüûüâÇO½ýê‘lSP+‰€C²aX1YÑyÀÒ´¢äÆ:’éꊕLgïØ¹góÖM“§Ï½{ñÊÔØ©Ã¹Mô ›YžºªÅËT%ž+Í„z“¸¢78‚ê¶’Y}â—z@7Z{ìRƒîIù!Àm½g8`öJU3¼GËMéÚÿÀѱ£?ýæ·Ý˜¾nø–û¾ð‘¹¿)‡åÀ–>•Øù‹×}JPm™rpßÖötkI«´¦IþüØo?pÿ-² ‚r…&¶ÂÄ·nÝdšbŒ…òÈíÝÀ%.cÕ"0Ùr±Põš¢4‹+Kã·?xï±£G(T÷*J2̆Ôªªª•ã]J8v{‹fWÝÂcï¹ÕmЉôºc§níoöà '6íÉzt{@9NbjK€N+„ÑY޵›V  µ¶¼÷O?ò·_üæß<þ¥ ”òÒÑÙ{?oiûßÿX½X®–—lì¹»Óp–]•ÄâCÐKׯ¤«– k¶0ý7öµÊñ×Ï?õü/úZÀÆñ“×åpá±?yðåS•žÙå%Mu-PpciëC÷d¤l£f4q1ºú¼½ùÂü`ÿÐêÊ*'ȪÖèé£8É0ìF¥,Ê‘H§{ßcŸ¬75ŠbuUe !èÚ®iZr(æ»®ë{ØwE!àÓEÑ®išºÆr Åò®ã D¾ã¹†…()AH³žã8–4 “†anŠ „‰€,¼/ù–e;¾ÇÜ´=‚=]³<ì[Ž iB|L3 EÓª¦AÚ\ŽDŠb BÄ÷‚ˆÐïÛÀÀÚb݇cúA€¢(ˆ F7¨ùµê ‚=)x£_ c쉃ÌBAKÅx&Mñòšie}QýËük³\þÊßÿÕ`ÿ–¿ûê_­®T%ÊY?°1—ƒOzº÷–6s•òS¾OÉ«ååþ-[¼>;ÜÃŒnMÉ1ˇOýØç>ó£ýöÀºäºMO\}ø=” ö{õÆË/ÿîðÿøãõ‚ií\nÖm>˜õè¶ÔúZ(ŸJn«z5C>Ç'¹•©ZKG R1çæ—ÿã‰g¢Ù>ÊT¤T>W­wú±u{/½töü…“…ÆJ¢5¢p[ W[»wïš_-=û»Ÿøi®lv<_É´–Ñå¹Ås{FºŽÎ\^72º²˜Kã]Ãí¬ÎW¸ŠQ¶€$h~Iò'ß]œ¯QI­P¬×ì@´­©[L@×%Älëè[gŸ±5µ·/;9>ƒ’–«‘p"åaØÚÞæO~kûÎí‡N?ùo¿xækŸÿL?¿µX7YëêŽ..æ—­*›ñ).i9MN‘æ6®vðøÂ™G>þAß”±ã/­,GZ’?þÉOþçW¿öó~»±Tÿü_îìÙØßª¤V/i>v1KÃxG=_œ¼6c‡­‡©ºvfrI˜h\Êzªåù÷|ðGؾÈÇG€2t•úí§:[b3 0 ]<|¦©çüàû¤åß¿õOøÐ-ËèÜØ~匲Ù4:?½Â £k=í ÍqJ+z­ÜÙßS]ÔN5Š¥p,*ˆ\0Aˆömoa~ª¥½ƒáx£åé‰PD¦AŠfÌj³à."ФlpE!ºYS›åÃE–h!€=b4U­Zó}F@ H€¢|ßó<AŠxâû,ÏA€lËÒ5ÕÐLÇ!žã+MË5i–x–‚CBPEˆâK"$„å 1Fý‡› $ ä&) ÖÒ5+ A€Æ… EÛ^åµ+b ÈH´Ð6ÚË[¸@•5GϰBîO¾üYÓ3¿ðן«ÕÜð½µz!ÀxëñP,=7=¹çÞ=÷íÚ´ƒHÞhte3g¯Ï÷eñÑ/ÿñÇ>ü™G>yà½_ø»¯ßxûþàñÜêØ¾½—ŽŸ®ãœiòO½ôr5lX3ZGnÝQµü[ï¿û¾½ïyíø»/<ñÕX&F/k)t×® .[(S(L¾L¡]C›qïÕÊ9]­uôï:;÷ŽåR#äÓ°¹àJ½\ªŽ¥2%讕V+šæ•uš3£Ѫh†¯›ˆÊ´>ÅK q辑õZ©ÀaªY+˜ °~4 ÙWÍ ;îêÙ¡°±C§s~Õbhê^0žØ:2ÈÙ0Ø»V>¼s×¶Ì>õÝ—ÛûÚ!†‰…#µâ|*”?sõž÷=²ytÿÄäœ.´FRIÌópŽï¤^ƒ:¶üÒ¶ÛvØ6c,hÏOgg®ônnÙ»ó@Â`Z8†©6õlwïCñ̳.œ×Ý]Ý}€Óµ %2#”¦s7=±'³ZJ§”aôB6Ù|éG/ø1`?ŠÀažadÑzÓà *‚°¼¢'5›°<51dPµÄèýذ̂^ò¥B³«™JÕ‰;ª™Ièzz­UȬ„’éj!÷îùËÑXŠZÖ¦ÑîÓç.WÖ ^§o½ù³cÇP§†¯«¸’Íy¤æ´aƒî>Æ2̹‰òMûž{îÑŸêï8Ôœo=ððÑT<áa»Ölšß´ý–Ò…•õj¦kp—Y.¿ûÖ™žDJ‰ú½R®Í[Þ¹xa:ÑÓ/zhââ…Ô&77§ôoJäù7!m+U2§Úê¼±ô°½81ëñ\3[”øJlxgþÇÏ¿÷Û¦¯¦{{x†(5TŽ-]ZæXdäõcß;¼eK£µ”_<×Õs8Š¥B¦nµR‰ðJ‡ØÊ91êËdôµÙÓC£ƒÔ±m«ÞjµVòµR¾ÙX·¯˜Žìéu†f§oÚy[@œày¹”UY°8Sì2È%õä=«Û‡›ûüå_°¢Ë b£ªÈÂöÛ±‹\§¾mï> |SÎ/N¾;4¼ÅÒ=7Y$¶u½R©×jµÞR)I¦úºK¹Üúꪩ·Ô`ØÔa«­·*™Z­¦h¬l×¶gÙz+QFUÙ"F¹\RlWöùB¢¢hÀ€8® X–gyžç=W¤°ˆáãŽã&,²Ü"€Š¼`86”C¬ccº®ãºçQJ‰»±yADe3,Dèy£å b7töÞ0íPÁ b60¨“b"Á±ì 8*…J¢ ‰Bˆ(¦/¼øóŸ|ᅫÜ{Ë{î~ß+¯¼þÌ3ßëLø»;µíûo~þ{¿€¨qÿ=‡nÛdv*;}}¦š_âBáå¥âž#`¸Ä«¿812Ö98¼õçOvu)ŽÄŽwG´€xómwSO8õÆkS³ëûnÙÂØJ¤WÂ:ïXµ¾‘ñZ&ó'òé÷>|,ªõ7-”ìMÝ<‹9êå_Û3R_-8wâêÔJ_ÐÏûBÝ›¿ÿ³_+ƒ»ÃÉXð(i!W˜º?<²uû¶]¡P »˜S8=4E¶˜/Uq¤\mdÅû“_§]©çfsá®äüõ«§Oejå»®ÔŠª¢Pú;{7ïíÏ­ÏÜuì¶ ’2[•&j:m®+õŽNçV¬ y«ÕjŒ lžYY¼çÑû>rÇáÛÞ˜¢Hº|fòì¥ÓÇÏŸø·¿ûr½Z%ôwvú"¡f³Îù‡ï¼Rõ¹|K‰·º’}„n«" ~Ënïðù5VLeVb‰¯°3S…­;G.Nž²&x‡t”Z¹B(”UF§àܹK†á^½xuúêW¡ƒ­J²;±iÓ¶õ\ifò*/©k‹Ë¥òªi˜jHÛ~‹$(þPP4Ê@–c¿O”U½íN]8WÊ-âÄI-s1m” ’ŽžîhªÇ4 €=QUŸŸجU]à)>¿?’d{¤ÙjzžËò‚ ÊÇBmÛv=×ó<×u<Çq]Û¶MǶ=ŒYUT%$¢pÐç×”€&+’( ¼$q’( ŽÃmD0…˜L°‡±‡oH+6¨XA K!¸AÌÚ„¡@‡ •€¤ô)þFb@†åì¥ú÷¿ÿMN#ñÙ=Ð÷ù?ú£‹Ó™×T·ËÅšiVÿè'jõâÌÊôøÞ­]Áþ‰S?¿º|µwxëÃ@žòýŸ¾ÕÙ•®Ô0‚¦:›¹\(¯Þþðý=Cc€ g_%W™ò$žXÑá]Q?Siym;ß76ô…ÿó‡ûwîß½wŸ-iÉpz-“ñ‹òÜÜ¥ÞmV«Å'}W¦§<'“†ß>ÿ|w'Ÿˆu*Tb%X°š~-º|~~rêõmc㶬‹¬laIªæ¡€<ûúë•D¹£o\ 1ƒò‚Âó\fj™p­Tx¤êd8‡Øó\waf~Ç®­¿:ñÜWþéû€eQ$Ök _Ø_«L£™Ÿ(ú‚œ uwÍEÀhy,u, )`%¼ËaÒŽ'ýÓó¶Êφ<ËÇ‚¾\VdYv$´ymnæ‘?ðÆk/}ì÷>Õ=Ò_.a‚(/ªßý·oj’šò‡"þx½V 'ÔŸ¾xæ3Ÿyê/Ͻ¥Ù±?~‰1íí»ö¼õòëa4Ên-Û B* ±A4äh8©ùó…I…Ñ8›eXæ×ÇÏV›ÆÇ,œ[Îx«nƒ§F h²U`;âå˳ —uã°#ë¦¹Lì‚”F÷uÔË™B»ï똹PÇbm¨7 €ZׯºA :¼yðg¿¼8ôÁÆhör[ëq}ZxHL…R•XeðíÆùí#=‰@—"’Á®!b—kï“_¾ißXg|ÇOžýÑéW·>|l· ºþìñââÄáÁ^HîÝÖÜsÓ¾ÌÔ]=;ºÊÕöÚ…ãË׿Å8pß^ ¤ÝA<šX㹟üëDScÇîâªL–§TtõÄßÂrò¬É¹9Qò%:#¢*å›JGÜ‹w¾ýúI¿ü½ƒ,°Ö&—˵õ'ë|$í“Ôµåy :þH§âõæ/?ø[ñR!Ô´L@#*²¹ùyIüêä+>ñ†‹I óæko*Œ"Hi"‘L˜Ž…` o6‰ž°,„ˆŸiÔìtT3ªX@ŒÀKí6`!ø¯RÎEDÅålÈj–%ËãÛ·Z%OB !n‡÷ê¥Û?ûÀ—?÷‹QLe!Ä}ù?îÚ’>tä˜kgy_g þÉï||ûÞw99s­Tw²ùâòûF;úÀáçú6u‹…Õ1šÀÌJ†Uò>÷k“™üÊä»—Þ¸vjMeJlGÔ—ß}¯$vEc‰HX€¾ˆ UÁjUaª_ýÆ6깯_«Ø‚SÁm+3¶gŒ¥la¹÷;ëMhÍNŒo•Æ6m¹þj!|‡rÇ®NÞ!ãSƒ§h™íY’àšSïP•“˜ôÚʲEcé®XɸŽdF’Å¿7ýÔS€ñçlœö%`L‹^YD¶d«W+”-¬» õER«g§{†R©ô(j«…ëWz7%’]+‹6æ6 ÿúõwF†bQUc>­™››Ø²åÞB¶TXqD€ôfÛ…¦u[Olö?1þ$³Fx±-FõÔÉéKw½ï}/?þTxHöÉ)¨W’šVÌv]X—ÓÞyçÕÝ»v.®åq<´œÉýâ[?qüíV©¬tÖ|¿”¯ø"}‡Þ÷ž/žØ=Ðó5£Y´Mï©(¡¸_€ãÝ»5/7µpÖ "qé ÜvÛŽgÙœêXM‰rN‹è¦É#Pì8 P()W)J}RÏàfb»Èi‚"9€zœ½>sâ©#Go ǺM×Ê^^eEnzyºëÞÁyˆ”̆®ì蟙¸”L'ú÷X˜î»éÈèÍG=¤ºûçû}°a»…ÕBc¥pý„(ûYž¼üÝ_ŽŽ j¼È:†Ý(åyQðªŽpþ`ß`o\VâP—àþÍ}£©=?ü—g¶ßv»‚2X˜ñ`£ÕÈå3ÅVN`èb¦€çÓ8Ã% f4…åa«âQc(xUÓ{kIþh§ÒXX+^ˆ „«îVg8N;ÿîqU|’\.¯}ä½OŽïøÂ¿™[]Î\_—Øeößy€¾|üó7ßwÀ#øÌ¹sׯ/>ðà{õz•ÕmÏ„>U‚ijVLµÔ0‹ë_ú«Ï¬•2j,rËÖmOÿîoÝ~øžGî¾Ç–í¡@G÷@7!vÀ°ÌZ³”+LOJY׫øÕDGlÐví…\5›/a~ê³Ov ÛÖWŒ¨â³A3ÕÓŸÒ0¯hR…RäÜÉéÍGwPZ¹Üj’ÇŠÄ0)®ÍÏ6ê^q½©oßù뉷*zž3Äv…G¾ÿ?¼ëã{'¼ÌF¸v;SâáÜâjïp—À(Ãñ§ã~A ñÑ šŽuF81f´©+åX/;yáÂ¥óSs+÷Üÿ¾¸HF™P$´°<ÇùÉ¥Õ‰­ãƒ>Y\),÷nÆ£þôöX';Š3úÈÖ19$ÿÆ÷ò+[vò‚¢ðXFl@Ô僚*ºqÕŠ!¾l˜‘n½³7ñÉ?þ\Úüð÷ÜwÏ݉a)Ô9äÓzsU‡õIUÒìí@ôÔÕs×&KMÁªZ”R§©;7ݼ½°dèÄLƒTŽn`kx$ ±¿ý×O«Zø}¨m5¶³³Wb"#¸ñ,‹@„Aˆ›Ÿ]™»z­¸¾ræÍ׊™Ù¡žññ=½=[ݼrþìêü ᬮTßüÜB¡°ì`‹ç8Ït(±©ªÅ¼eé„Ðfµ=?=õò¹é© ÛÔmìW+¥ìJ½Z$ØÓµJvµRZ·lÓlÔKÙ\fy¾ZÊaì@×Ã.n7›­F­Y«˜¦îºŽk;íz£Ù¨;¶a†¡ë¦®×ëF£iÚ¶‡±ëa)BH%žÜ m1B×ó\ºS°çÚ¶åX–纮ëy® )”P‚Y2Bì¹€ÞÀ¼o ~=DDÆ”å)¸’Èeh9¿~ùù›ïÞ—Hnž™¸ø_û'gÿðÿúÚ»S›o__È;1óÎ{î,,®²QýðÁdžÇöçËùá¡áƒÅÍñ‘ôÈÀ¶¿}òŸw î?ºóÂåÙÝ»ÆøˆÒè<{òÅ-·ïã»VÈgf µÜà®íÃý[h­Pn´{R5³jYäÒÙ×Þóø#±hoie²Pw.œ>{÷ƒë͵;îGϸ´Ú.0¾Ô®mý¹|ueéB¸7¨ˆa1…´×–»6Ç4Y=óæñl¡ÝÑÝaëe›×,«´ç¶‹+©½Û«îú-ûwJ„s M‰ +…}œÈæ/g**Lf6íÞ‚M‰ëbKY@«´gŽôÝÖ^[“»º!`JõB(ªƒµA€T£ ¢é©VPÐ)’xž´¡g´EaeU60 ¼ÃYÁ¢É ãã=ÕÂbPŠ&‡¹s¯‘˜se®òÈíÜ·ýø›gví;:qîÔ¿|ãénù³ÿüï/ÿëw~ò½çîyÿídDàgûÍ'7 õ|åËÿö·_ü‡ï~ïÛïÿÍû_þ¯Ÿ¡˜Ìa×äŠTÁ%žÈy|èÃïýþÏôìwžã¸ìø¡›wl9üöÂÅN²)®ú½¦7ó³×Þ˜|-;ïîTÔ±ÞÖ5=µÃ@4â]©‰óghÔ Ä{9€¦¯¼ÓÝÕK]}qfIè¹wÎlÝ{[K7×G¢·æ›À‡CVWq}a©üönÿèˆ,®ä†FSQ-ªùX‰0z‹abÕv1íX_¹&Ak5_¬d‰œP·ðL‘“POtèÂ…·ÚŽÇ¤’Û`«ºÈEØž®àÙU/¤ùÒÑ—|Ö®¯üè§Óøø§¾óµÿ¼ruúo¿ô×ë'Õ%gÖMPñà]˜:ŸÛ«­L!äýŒK â2(9µÍƒÃ‚BSé´/M#ÒVå¹·¯¥z“k“& 'Ýq­¦K‹!à5lT=@L±Ø¢Ù¥ÂÚrÓ3¬êKÆB©î´ÃÛní¼õ°Wƒÿñßìì",Çq*Kh¶´V+yŽw€ÃêÔç“~Õ†¤´¾žw3¾°O DmÇul‹eB¨iYŽe(’İ|³Õ2M£Ùn…B:bYêÏÃX××åDE,!Äs½vK§0³-B躱LCgY„l×a–cXϳÈF@&Ôslʱ"jç(¡ˆÃ,Ã0Ä XpƒøÎ’,ûÆÀ ”á ˰„b€ ¥Ah¶ìÌåk&S¾ý{X1œ_]>ýÖ;‘¸üô|);³OG«•ršû÷ì­­™âRïαÍ=û–f/—öÙ7GFÞñÍúoiÐÚw÷…Õé'žþ½f¦J(ײšGz¯ãÁÆÂüz9S-­mߺ)ÖÕåè†+àdªÃe(ö˯»{{GW&®âÒêÚ¹c;ùêÉP†ÕDÝkË ›¶¤35LDX/ξs®wsÏèÖ!ŒÍÊb¾3 ¶Û-‹çÏ¿ J‡­xX©²ŒÊÙm EÖ3‹†IÖ‹S).NnU‡òÉT7c ««ç;oÞ}N¥{n5]€ [iIº6™çààèN³œGŠ d}Þ ¶Wh%R²^@ >7;Å©¨© ÐjŠ*`\N9Xy:ò:4­S^kµÚEbÎc±mùÄ@˜æhÏ.f2WÝ4ØóⵟýË—ÿÆvð_}ñïñ„‘o/ç‹G=Øv ÃÉ”B Å{0`÷þ»î¿#ÿµùÊÙ“o~ô÷>ùâó?V¤°«ë +8Ùz`ÅE`×íwôíùÜï>ñ×ïοû꥓;sr®³C̕ܞ˜NGYƒs¹µ©©beºæ ™fUP‚l«j§{IÿÍã?ÿÎ¥?þ³O ñð–ÞA$H}é³¹ùOÿÎo>û¥¯GCÝëKm›/?pÿ­ UâAƒÎÚ"J«²@ùš-ËŠÔn5Í*¶N ˆLp*·tëÃÏüþêâsÑ6ð¢ÛêU]‚ÚB¾I'Ý3dXÖµr-âɃÖ‘EàK'°Îžºr’câ½;Yƒ?½<ÿžûß›½Þ¿Ý¯¨‹¹¹T\ƒ I¡ œlUØ l\8µÈKúȦ§Þ»–ŸØsø¦ÒÔš¿KñˆÄJµ|çhÏ¥ýbtÌì¢Ô›‹§F¶{-©«Q"!p~Ê–Y5›gÿè‰Høœþ›ú[¶)b^Ô|µrÆm»ÑhºÞjtû%ßèäÚ+€tw|.SßSš¯l½o/dØ«Ödiu®åÔEÚ hjx›23Y ¼©dÛúz: ,Íœœ%ůÏÃ`¡E ‡MSêÓŸxó‡V.Ör–ã o¥z΀Ðn·é"<'kŠíù†óö0!€ð‚Ȱpÿ£þ¡íw=ðAU Çûå` ízV©º¼¾¶z}ªk°[ Z-ƒ˜ ŸZº~MP¤ /Ÿ ´½{¶•3E™—Þ~óבT¤µP(”²£ƒÛÄÚMC¢nI/F±•ÉÉrfa SI‘9I”5¿Ä‰€gXNEU|”B)Ë0ªOíìëÓüq×±üÁ@8™ F¢±T²»¿¿¿0IRû±»·»£w0‰š®¥|šO FÂÁ`H$–c%E„ʪI¢(+Š¢È²¢Èš"ɲ(pÏRMǵ,[7LômÇi[VÝ0Ú†a˜¦åÚºn†ÑÖuÝ4Ûm]7LËq×u=—bPÊ‚E€7\ª,ˆ(½±ê"RJ6²ØóR#©®Ñ¹®—_¼ræLn-óØŸjæµì²¡ë| î%­a{º†bÑdu¹l42ÿùÕoßþþ£·ÞtÿÜÌÊÙËW>öñÇ»6ïÒ&ô©–Þªå×"ƒR­¼xîúk¿úձ߸ËïÓüÑXf½ hÕFs||çµ[Îì¶]›¥_²ÔùÓsþh°OÛû³×¿»÷Ž}¼ 7 ݲ€&JZ8»°¦rèäµ™½·ï¶Z–ÈÒj³ÜÕ•FØÖ‹F³ººíÀnÛ"¾¤Ò¬…áMÛìé).¯\È;²{_ÿèžzÞÊBÍÆšßÇóüÄÕéîžÔñwNÞºI¥žëêZØïS„F¹5صɳ-E) ¦nȲ¤ãb”‰Îg§c„â'äZU, ÐE¼ %ªÀ‘"C@žî²œ,ÉMgñ‰Ý¿ËÊ V”=k Æ/lÙ~°+صØÈ|âSO8|Ÿm9,dZ¥j©¼Ú=šèêÜÔ™ìöåv}qñ°.Õ IDATäñçCÃÁ[Õäs?ÁãM"ÓÉùk/þì§w{ð–½;N½ð¦/­@Ñr-& \¾t¹m«*k@ë!‡Ál¶\…‰ÅÃ7ï»}Ëö=­œýâÉKtŽôFºÑqj¶)(íVÜ6ŠŸ-¾äRÕ0-ÙS+tñ•—jØrwè¹8ß°ò&JIJžc3ÈØ Ǻ‚(ÙåZ~ßMMž»øÐýwÖ.W-ìAbs¦Î±bµl@G)µ‹Šè´Û6ÔX™)-ä]Åæ0·¸´Þ1°Yâ°ÙrK£QGîhÕË« +,ØÜZÅÁ°¯oÇ›S/G»=ØÄsÅ#]‰>©lÌìµð¨Bä¢Ã§XYήgBüðÐøäñwbý{óÙUIƒB¬·°ºf–ÍÅ~4¾MUÂÜõÈà–á)`ÇŒdXæÂв¾XxâOî™^.ÏL,÷ÛÜõˆcÛGÃ]âzÍöóòO®Q.²;¶é7ßuß+¯½¼g×p¼3­—[L˜Ø¶[«Ô"ñ0±«e'YWNRq ¨…â½”zó*ráÅ·&“]r®^CÐI}–ß6®ÔD°T_3˦kHñF ÃŒï¿UæCˆ…L)¿>5<>Î >˲mÓ–4Ÿcë¿_ FkÅZneFÒ„h²×²lJì` ±4ÛyNö‡=Ûæ#N%I-/gYv™ùH4¥ gÙ…¹œ%Š$™áaø6W7Í–À Tb†!¢,¹6B»Ž ‰®m[‹ q\Û&€RâaÏó°c{mÃ@cs5Às|µ½þ…¿ûúÍǶ޼û½Nœ_™»¼g϶TO§Ð¤•Õl»Q­çóCÀxºY½–krâæûwDSý£Z(Õê-­-ûCwNŸ}î§ßìßåSR,+gæ²Èß¼ç¡Gßxéõ#íM§ú'ÚTà«Æ|-“ñÉÂ/OëLv».‹d6éÀ­6…xòÒµÛî¹mlóNUP0Ȉtõ¦\×å]PÌç ܸý»X.@±Ãò,‚D¥êzU÷Z ²Ë§BÉ.칈@[o‚^{ù8ÞWæ/ÆÖ[M$òÁâëM³8·8¶e“g#YãM† ÉIˆÜ¦Y†sÈØ ÖÆ\wÄïùÄJ˳Ón»`4` §I0èNö–çI©l8r×»/¼võü+¸Ñ®/ë³™ŒŸWUåe…À²ìÙã¯0m”¬™Óç+íõS/¿UZÇz'/deåáGÞóÐc<ñÔÓ›RÇÂ8ÄSüšŠ%›£¼&oîì E.Pú{"û޼íæ#±t÷•óWfgϺžc䭕ܵãoLœ;ñöùKú³W_zû䕉)̆7õ§¹Þz¾¨[ÅD:˜)~V=;M ûİ>Ð?HLdO'– eˆø”«;å[ß{ôà“Í{ú=§š+¶úÓÉoœ’›_Jt°£©¡MÍfýоo¿;Q+ÖR=Š(^?w\ ÔhVCÁðÄäò¨S-¬¬˜5¨Øhç©Ð쥩pd°Ô Ìz©Ø†¬_v|Љ¦ìz5(sšÖx5¢†ÚõæÞý£æšIUÏiËÚT <Ã/^Œj>4Fú««¥d_•T‡„yÁòEÂ…Fu||°'µWfÕþh FÜ€Ê7Zx-»\o˜¥R- ñŽàý3 ¹Ó¯>wyê ÀÎÒÒ Ë Õõ•îŽÍ¦ƒkù|![kqZKç Ivõn¹÷Ñé¾- úd)Ž·+MEuÂ]}ªl{–ëÇ´0ô<Û‹HéééyÊ8RŒ½p¢ƒce5Fbz¶ÞÒõÕ•yAüj¤¼ž-¯­å—14’é‘SÚÕf«UW|jÐ/W#јÛ¶cêMˆ ê „ÂQÍR(Jd8Á§i~9¨ëN£Õ„,b8V%Yõ)ªÆ 2â8†A^Ÿ_ñùeͯú|ªß¯ùü²¢H¢ˆ Cõ\ äÚH)` …ØÃÛöLÛ1mǶ]Ïq-ǵÇv]{€ÞèãPB(€ˆR¸a$üß’ôï†Ëâÿ·ð@Nêƒw?ød4™^\]0¹æþÛî>|ôÅ™baõÜ–·±TQ$)¿4ó½ÿøÆ]wo»ûÞ¼óË7ËPöuݼûh0ÐåÚ¶æWeÅ8FŠv®/¬¶ ¹ógÞ8tK"ÑÓ!!™2xÔ5}£›+3¹Õ¹Ë{î½K9µV ì½ëö×_8¥õå“ÉA±PbŒV+ pǰbµº:¹t©oSëÈ@Çq<ƒ1› âÈùöD:5PZ[⌔€ì;MÏ\[üå oE}½ÝMÝ’E¨)!ãVæ•`iòj&ÕŸÔ¢À€ *²&Š!VºéèÈõÕY[1 '²€z¶gémEQ';®?ŸmäçWšu³n– A8Ö%Øa] Ç1  Ã×ÄŒ[ß¹ùΑb,eWfʼÃ0ªJ&SK³s½}]3oÏŠ!qS׫¥‡ÒÂØ­ÿòo_o•²Aâb—à¡Mû;ñÒ…gžv÷¶=ß÷¢Få­®eü¿OtJÓn¶ å¬G9… vMÂûÃ+¬g¢ÌÚàm¾Íi ÷î›gÞ:þò /üÏÙ_ŸY_»¬&zõ7&ÛFF8LVgçÚÕÌR67313S˜_ÉKÍŒé9a 5[íë³íÖrÕð%÷>p«ÂuÕMƒ(ˆ2Ç ™ÂêG>ñá±ámßøÖ×Ü?ÖZ÷ֿבտ Áx*XÍ冎nY™:c™ÞÔJ1ÞÛYY_åSî®-c–×h,Ùms ö“ÏAØܲ]c´]¾0ˆ‰¯7Vç¦öŒZÊ_Ú2´U”jS9¤Q‘¡H·dµÂ_oÏKJPP5UüBäÔ¹i¾ sËÕdOjùJ–uL]o*œºRXõw!½E;:»Vs³J„këfÔíÛºçÖ³çÏó’¾R_銧q)¹Ð£:[oyV.®åiKz¥A>ñÁ±þØÌRVTÀ-Žî;t÷Ž›EvE¡¤F$‘1-FÁ›‡‰ct펪ÝƽÃJ8b•³Î!#©cù}²e32´`¨b¹Ñt8»´Ìsˆ@JlW²ÍÊ:Ë @ÿöÑÞøæÙK“,Ï!Ì´ª5ÄQM »–ݬW"éDGïH­Z«· ¡@TT¥xg/ª¦®cìÚ†°G ýjg$–àÆ£B`–ëyŽëzžƒÃ0 ¡Ôµ³­;¶!àXŽ%Q’UES4Ÿ¢¨²"+‚À3œ‹‰ëz€‚¡ëx–帎ë¸ ¥„¸®g;®çy{ÆŽãìQJX bn\  „„7ÚÎÀ pà9 QȰÃÊ]”PËsúG7¥†Óª¼züu38xÓ“„Da»Üž™ÊßÒt¶µ²Þ`êÅÉ}wí8ûv¦'âsDðE*sm‰ì`%myŠÐ_½n´êJÈï™ÀÆÒèVöÊbÏH2 S´]Ã*å¡?X,–h»102¦²ÌÅ·Î}âÉû‡[ÇjoþZâ•ý·A 'ûü © Zh ¿·¼6½â‘@$„K儼©íÙ„g£Ñ¸çT׌B.¿Ú˜Yꎽ#soO-æÂ¡n9 !=Ç j}§ò/ü€²¬Kèà–-±t?…,‘?¨-,ë¦Þj–Ã!uh÷V(14E)|ñÄÛ+K×ÃIµË?@\Éf,׫ÅP"‰x^oTðÊ•²­7Õ`Ôõ0Çs‘X’—5J€aZT’Q¶-@©ƒ "†¡À!Øq,Ïs ¥˜÷b8Qb8†ñÿ“ºø¾÷­-WW.O›|ëéßúƒzƼ|úMÛçîØyXbE²Ôux–±€!wª"æÃñŽšÉz¦!ÉèàÌêêñ_ëéô9¢ ÅêØjÖF·ßò÷_úô=}0ÈËé~±Y2ýÑt£Iš´442þ7ŸýÌÒêÕƒ·|m-Óôq"âa1_ôFe[KruG!L‰T}<×–ŒÐÒÄ[›ïÿõ5*›Ûöl=pï}ºi$#·U•³¨7ôöúôõˆÌ„»B\€¥b¡ˆa9µ–)ÇÃAÖÖmj»Ä³]4, *ÆDƒ`Ë2[]õü‚dZ/ t—Ì+¨P!åf•'&8›+s„ïê(5ŽE›ÍR¹ÐXI-Ò2ê×g®Üyç]ƒê5”]¾Ôs߃Nƒ,Tª@ÓUEžK±çaH]¼óè¶ôxÚn•f/ž=óö©fËxiê­}w¾ðôÓOÿùŸþåG?øû~Kíü[g9Æ4t4{mRq<…ÅœÆ{+eýÎ}‡ƒ¤Úr·t §ÇÓþôXq1+¡V•‚•» {†èOK…:§7×#zWïÞa–eóçß]ˬ]|{y¶xþ´’ þX7EøêÔœ-I²êíî¹mHL2/þðÂ?þÙ¼˜ó¹O¾²fR¶ýàÃwU]kûÈÀÏ_ûy¼§'Þ=˜ÏÛ’.$¶ÊsókЯ,,ç*Ír­©¯sÃ=›[íz±a–.^© k?ÿ髟þËÏ„]Ô&ñç‹.Ÿ¹š‡¹H s×öK¯Ÿ«ñ¥Þ­¯Ì^>v÷Á–•¼öú‚-»†z®OžÛ{ì€ÇJõZ¾g(ÑÓ×¹Ö(RF+]¸ºé‰C¯†ÉV¦KVuçÖÃ¤Ž˜©ð,'FeͲ-‡AõØ#úÖß|~›²É‰ãfÛ¯^þÅm÷… &Ù×g[m½¡ç–—šÍVµ^ÆŒíHu ¬/Ï­-ÍG“&§ø‘˜cšëó×a F´Ì6DÖüÐñú‘Ïú ŸùI¡~›CêÏ¿ý;rÐÍ· ‰eíÒ‘Û÷T ÏÛ¯\¦HØ×wüÅ—>øÉué¡£r°cen©\±€ ÈÕ Œá–/­Öíö7Æ¥„Þrâ®# s™Œ¯“66Þyh8<²mßã~fùl0Ð#ɲušÕ´Æ~á‹Kó 3×®_=3gÖÔ›;í„òÊ‹'øÀ‡û:{þã[ÿ°uxwOW6;ǽ·+Ž,†åkÏÜýÈßüàG¿Ø¿e7jSà˜­Õ¢§鎱~tléÍK#£ýï,šóÙ…kçN\¹¾’ÉÕ‚]€C^Ãl„b {Š:|¿>þëOýчê Õ¶ I´j†¿]>wþèÇLŒŠ æìõ3¡žP¸#Ü®6½+ølÛqlÍë,-Ì·[&å±'à›½¾DÛz‹ªZ0è3ƒHÒyO§âÖ˜‡þ8£‰ÅÜBjC<]N‹®) #gO|‹aùHo_P¡ºQ?rÓÖgžy¡Ò¶6©T =žî+åZ­Z¸Ü|¦¿wGaµT)/FÓˆó„ã‰ÙñiN­–kåX¸£R®ðIt»UïÌô5Öà8EÓ AEY·É±¯Àž¾ÖÞxç"% Ûo¥6mWËÁžØÛïB,È/Î"QÀ%¢19Û¿;3?Ól”X^Ö[Íx2Ý;8²²²P(æC#Ù™†²r:SN ¤Û©‹€bÑ4<gÛr×F]ˆãбÃ:È¢,…,Ç Âš¶Ë4uüîåºJ(… Çp,Ëù|”€"ÓqXq ãì¸.ÁÔä ©Ä°6æ]Lm×’DNæy†a( P@"†L !®AÞ%“" }WcñúH1¦®¡ß€ÔZcnúª—Ö,LÇZœ½a³…Ü÷{¥©üüôksç?ó©/šØn4\½UïÅŽƒ1”–––—*7¶nÞ]®5|ѨÇëïîTL½¼öô+ÍsGo½O¬šn€Ú°Q«£—N_*ÖÖm¿Ø1Ýf¥êXÇÄnKíîîûþ?|7ÝÿÓ~fòÊxº§C¾š]¥»?ñï[ÜÊá€ÛÌ/æ¯ï=p+”òÂõø@ßB©¬›­++W¾ðû&•³A)½f0•r¥Á ‡¯Ÿ9(ÅD¬ÀRÛ…Àâqµœ®_úí…/~åۀؒâñ`®¢.…<þÿèøçþøÓ?þþ?d ¶…%È‹¼nØhå‰À`Ã%|2ë_¬LŒ®_×tÚŽ  œØ0)^×›uÁ¶^Ù¶gÇ¥s“w¹ï²ŽÞ~û§>×Xšžºëž¸N^¼PXÍW‹ù‰ÙwN¾™;ºÝ× ¬›ÊŒ¯¬”òÙzÇëϾñÀ±ž8õú½÷Ý=›=7гã²qòŸüÂóß&;³x£¥ÅR¡cÇnß°¯ïÄï^ìïÛù2+Å\Ž›™=·4&¨ë“º‡üº#õÅ:6w´jU£Ø˜³kFÓf¥ÆÚÓ?yÜ&¥œ.tJÁM™J{97Þjåg'?úá·Ý/y‰hÇLmfó­GÞ~g!óLŸ{çÿòë…•Ü?|ó/ûíñˆ7Þ*ÕmìnL÷‡N'’éKÎâÚ•º®VÓ#FYS›6®­_çM„zàüôþ¡MÓW/ôªÌ½54¶•·é›ož¼ëcw5ó eÛbv6Ñ?Te<Ö7¢·J'_;5t )%ù\fÉÕØJm®´Õ©…c‡ï©—Z›7í¬­äЀ3‚Gðך%ìHù¶½eÛ¨k`†1lì:®%2r¹\+« =Ãë s×¶Ù´4ST‚ñ…lÕ2\oLnK—'ç’Ñh$<Ÿ)°ÎaµZøyô'GvYyÓÑŒî^eß-Ç^;æÅÇ·ïØžìíGHñ2H÷'šÕ˹•FñDìØþ‘¹q»Ôj8®*x% Þ‰‰I! 9ì Ójî½óήd7ä%·n,NL’r¢w€f£Vr ºÑlT½¾`2Ýà <ÁF8ÑIÔ5»Y/õöõò’ѮنÅôjKø­šD[ñ)Är-ÚrYžà÷{1 ®iY®ƒ"D ®Í ĉ"d€ešØumÇÅŽC)eòËrQ’ƒ`™e(Çr,Ë:¶íbÌ™ƒÇ°&Ø!6fDQâ8ŽcXŒ1„Rʾ æCD€òƒBB($!D0еÒmmô™’|.û“¿ëŒl»1 ”bj©M)è½ó¡Ïæ—³W®\Éé øÌ§)æ4›2"«0츄H)eP,œ¼>÷ÖÐè&F@ž`T7]‡8¾xìÒÅS——ž¹ç"Sp8Óç Y†kÒöòõã3gÜq”¸4Šd*+”°:Ö©ËG"¾“¯Ÿ¨øÅ/}|örÖàê6 8ØHtŦ¯]:õ{?øÇH¤ós“é]ýœ"Mõ –³år}õÄ«¿Ûµ¤gt]$Þi[Àh—=ȧ6Z"W.oeã‘ù¹©Z¾Y)®"ФÌcäÛ¤0 yã¹\¥+’h¶4Ûáh‚03}µZ]ß¿åæÙ™§•% –ê"AD¼‡·T‰XˆH ¿\^·i[W<‚N„œ$HͶMÔ6“° ]j)¼.=Ö(VŸ9}|çè¶©¹)sf®©©¸Z-TJÏþæ•Jcf!¯ FgË­ýëûîøðž—J­¾çðÝ/¼øøﯭ?4öÝ}û¯¾óç¿ö€8‰ÔÐà¶Íá€üß=VY\îí¹iÛŽ<§¼ñÔ¤Ql=_{ÚX¨VœS;F¢Ä廆D7Ú¡×=.Ûh•ulµl€¼>O"$”LDÚ¼ìÓmBM¯¬* k½ôòÙˆõ%L,z%‘aN¢DŽðí,L†”Ó—.¬æÚþvêìÄÛÛíØ»ùá¡?ÿí/:G"šA\¦*sîÑ÷ðÊ…sv˼ºz L Ï«Mwûæž\ARdîÚÌÙD’O{ãMÚ^œ·ë•z<Ý“[Í´šíX4VЗ%mhçN«Ý¼45ëô+)„©Êõío×u )&r%ÆÑ,Sô%¬vEò{¦NMoÜ0Â3<Ë+ó¹%Ù㢹~dcuÕ Èþ’eñ1KÜ•‹§¢Ýò±>ôê~ð´«^)”¹:ïõXr0T(W‚¬¤ÈžÑþ¾·_¹Ð.4ëC¢ë²!/íê1-·Ý(—fËž©¶J")ßzøèôüdûb1}ßûý¾€‰‘ìám—‘¨ä‹ìPÇb—óœqI5ÕzC ˆPðz]ÍÅ”¨j²Ð²ðä¥kéuÃ>ŸåYÄòœ‡vu÷9õbÿX³3=¨Ä†aš˜jºiÙÅXŒ DcˆŠ×Û(W›j$ G @]@M׊vF¥62p«ÝŠ$¢«´µ†‹1Ôë`ÇQ)4 ÝÔuJ)ÇcÌ@Ä0œ "ˆ8Ž·LÃql×q]Û¦'ˆ"'ˆ Æ€@h0²Lƒã8NÇŶͲ,€aÖvˆ×µ0'ËÏ‹ b–eK!b %ð½â‰RJáš¾âÝñÝ®PJ ‚h—E)DR̶Žøv>¨HIH\ÃÊÊ’Òˆ{ù¹†nW´üMwKLPV<åV!‹²ˆC Ç63Å7Oßß¡ˆ˜n–—$Žg8ÖÖM–g3Ë7οðÚcG¼b¤Þl{IË:¼˜ëí®¾¸/èå%¹°4 eÄnt ]­¶—³KgÏÞ¾kÌK{ ÂõTj3µªšf<öôãÿ̽,”n¼>U6ò»:ßO-‚ŠBuN›:1^vVŽî~ðQ³ÕÐ0‰ÄÍFgÄ+ã'‰Ó¾6~AÇ®Õh­¸Ákë-§5k®_× ÷ 0£©^{\³J47?;=¼i=¯D/¿sŠÂ+Ͼ<´y]GhÑ<é IDAT¸®»:àxÎ 2S·ˆ]ì±õ’è ø=ÎÐPЗ(šeò 0v%/P"]D—jªßѳGŽzîé§žzâÕÖ7Œôç3«×Ï]0B0†âXF"'H2ô+ÒÑ;(BçÀ°uùwmÝÓ묶°nI’oçуWN¿}ËÍÛ_íÔÆþ½­J3hd_ƒþèǾhÖéÏ>3¾2]›s6ŽÈþtÒ›ZÊŽ7ôÚÕw8Õ¥ðãëŒlNK¼O†±i©º-*2P›@ö!–bÂñÙåIñÚºU^ÍžyíŒ +ËsÕ¨×7ºy뉟œV._*Ò\Á‹”¸´.µ~ Âu¬–ÕGñÃ/}Š–ËMÖ³ &$ýÞ™þì?óó=¹qt̡¥+W9çÙ‹g³w?póø•Ó[÷íÎ/5·^l–M*İœVº#rõíÉD ɶƒ‰´<6¼õÑŸý[诿îU^ˆFµªéºÇ/N~á¦?ž¿ž7fÃrpªx)ös€·,Ëv‰ E?ëE,¥¶ã¸Þh‚¥¡™‰§·,e¯v{ß¾t^ÑP¬Û¨!=à7Tè zÛšî0]<`m‚³ËµÇÒ.Àn«-”«jÐa0‹ [­ºh‚hOĶ(ÁÛ>ü‘©…_ÿò¿ûôo—¦ö¾ïö”Òi9z)·¢$70³aó–ì|y6­ <‘ŽT§Oñ‡ÝO% d㱤ȉZ£ÊGyÀÆÒÝéu ×os¹áMÛ<þ8´m«YgÙ.ŽÇëB”€¯{pÃñÄuúiº1´i½i©ÀhDYYúv\ìh͆YYÆ”BmÛ4 @1eÎeyb¬xQ25Í0u(1 BÄqÄuQ”yA`b9Îu1å1˜ba dJyŒ=‚Èq@Ä0 ”…p èþ?Ôw Ñšð~­’B”R@ dÖT…!†¼[”1}]ƒ½ˆgqY†™¸–ìI‰¢¢•«¢ÈëÙ22ê$üAÁ4Š# °ëÇ¥„"^˜Íï9zØ/÷jÛ¥ØÏûœj‰ †:ýÏþòw[o[([[ayF Gf——= ‘m{÷¹‚׭茼Ñ8å dÙp<üįëê[—Šìúî£ÿõ'óN¾²~רÈo¿ðºÓÆ{ތ܎Råø-wí¹òÚùÎT(6Ø{ññÓ½‡7¾râ…CÚÝÕ¥T«ÖòødJ)ÓbJ‹¥{zøÔ3§F¶Å6íq- Ç´Ê¥j=3Ÿè 1^OWÇ mêµ^Ub^%+sçξ¹o˦îó‹ã¯*ØÏÓÁ©H…X—%F$É-”WòÚÇF6 0 ×Á°,š¥D ŠæêÐËYºM†¿íÐÁxOŽSôþî¹\1Ìe·Ò¼R q‡º»‚»Ž mÚbôîžÀö]7ïÛò½üÛß~ó/n¹ý¶ïÿû?}öî‡=ùÔÀ½ƒ?ýç|þÏÿ|ló:E^‹nø¿ßü3—® ñÈ7ï|sæÅ¡‘[îØy“tkØñý–Õ|ëôiÀr×.ŒcÔ¨7¨È¸MËeCèå§[ û:bÈ¢á6&vŠCëDo0‰LNΓbG*ýŽ4^sÑþ}cû÷ÿ±¥µg.Ï,ß8?Sm¥Çµ%óÈa™]7ùÎéÎõÛS½ž/ùôóO?xï}õ¼UÈ’=F\H9hY4oÍ\»çÁƒËI_½¬³Â½> 0œ;/žüaÏÆT9_îŽÕôzoÿ(ÑÝ•Rý–#Ç'_°0ˆFºD‡!^1„YAâj¥|¨”𼡴À[7m/e¦ѤÖÔ®_œl¨ù‘ÛÊÕbHf'ÆY?çU˜…ü¥€8.)M5ÓÚ1ÕYÆúÓÓ“rˆÉ^(ùc¢ì «–^«×ˆ@k‹!_ øâï^•Ù`HI!ÙFm^d‡†všŽÞÑÕÑNn9 ýôûÿ|ôž{†Öï¼1{¥{ÝbÖRCëS¹>S€ö²¢¶Þtj¹©¡Û·Š„ÕJb¼ìÐȰÓ6,¢*ŠOôøy´õæýáëÑ“箞>=´eSOÿ#ˆšÞtL Ш;Ô±=¾ ÇñápŒºŽ‰U× Æu`,jÙr]Ë+¯ È‚$z<^Mk5]•%Äó<Ï›ºn¡`M%!ŽCA%žåÄØŽÉ ÈBD(„cB Ç`L†áQèÀ œcc‚ DZ„ð¬‹yžC@b‚”D‚÷Z= ï6…”ˆ!º2BH…k¬x!b1%CAÓ6;‡D¿|åRwTÈ®”Ívo2]®”¼¼÷)?zìW}ôvò"¡Hµ’ów(’7»x]¸…©êM»¶¦†¶62¹}è€Uj‡½Á¶jÔ üĉ_íÛwS†ž;ý»íû6ç'V~h¬Kr·ƒ}êßúà·È¾ôÂBy8„>1‚CŸxëê›ÉÍ‘s—®¸‚Õß3"û‚R RØE-'Ï ²¥Q‰"Ê hi@AqoÂ5 ŸWyúü…/Üw§Öª:0È1fݦA6¨K ‡‚0¬ÛËãû·Ä+sÌŸþôkíJEˆx|¼ÇçÁ”KpU"1!9òÄOýþgþÚ×þ²Z/'“ÛØýÈd£é{íõ—ú÷íûí›ß¡sæžÏoÿçûWM¯ y-.! J_}àÑp‡÷Ê;g.^,e‹¸U^5’Ú9Òöy«ír9[˜RÍ~ÿáQ¡£o(QëJ?õÂkV#gî\~!™O=~&Ä5t?F4xçá]ׯÚ°`Rfêì²UÿÁ…e-8_Ÿ]ú£?ü_ë"é"Èîßõ±ï}û[©$]¾'µñÛ_ÿ—=[÷ìݳ ×ÚlI<‘¡¡Á«3›mð8$ƒ*ß!œOkÔ6ìÝ«tEE‘[7´q8Ù×ÑëòÙwzÖ÷4o4»ÓÞÂRs}ïP»ÜD¼;sm‰†™ ¸‰&SCƒ;‹¥þX”"jç¬Kã—7ù%]/ʵj³üåÃ{¨Nóºk æ@dÀpA2*5wî¸éߨ»õp³Ø ªžØº¹ÔPGÖsJ¬0wƒ#bª§§XÔ\¢K>¡l:Ý0p“ªèÉŸÿר¦éŽT¡¸¬D‡¢Cˆq…f«TmÔ»ûº£©ÑÊsÇ_öÙ—ÿû©õ[‡XDÕr³ ʉj³z˽·o4–s“¸ÊÛ& “Á€h·¢Á¡MHjñò„+¹Àö 2Dœ( ×ûRñ©Kç禮ûƒ~^‹BÔ±M$ˆÍF³¬ç1Ʋâœ(axÎÏÍF ñÈ/›lCý @ºÞâEѱ-ŽtÃ2-[”$Ÿ/)ÄŽ‹)Æ®kŒK ARJ,b9‘Çcì:Ž¥„†iê:ÃB×%®mSá]Õ3€@†B€†ey]ŠÈu0ÃR—P0”¬UUAHßKŒ®ý—àݲ ± `†B¤€RH"–aKÚ¥€MVàmSKwv7g 7&.w÷ HÑ„­®s, B @(-\=וòÀÃp‘p´{ÓfÕbÔëìzíÙß$Ä;ïýŒÖÂZ»’J¥êÙ%‰£¬ÃÍœ½6²ExýÄ9I‘Ú«e<è‘d­RWI“¥ìü’2¾rîµ}51¸%“ϰ²§;9ùâÓÝ=[ï¾ç!Ý.Æ<±…üÒàà ‚B½QHw®ä&BCw…1ó9‘-K—Ã>$Ê ãͯïÚu‹í®áHO/!!¤X×Ô©©‰’Qà„¨ÚÔj­eª×á „Õ G­å •6òóïþ+Õ#;ö4s*¦tëÁÕñó«KÔራe\¾ÞÚ¶.ôË—¿Q:ç'ÏæŠÙgÞ$Œ™-¯?Ò™­¯î¸{?b`#WêêëÃeæ³Þp ´2ÎØTdðÖMƒV‰nsÔij“ q!ÌÂÑÈõkÑTÛhdV&9ÁmÕT-/._»±@XrôðM…é|µR3, šL¶ª–ZµE¹ðÖÅk.µh]oNø£vÝ•XåÄK§K—³}ý=úÕïÝûðÃNMüåÿ[âY`Ê.Ÿé_-¯ÖN°)‘9±³»Ó#ðmAs±C]ÂB¨·ôf¹¾<=9=y!¿º˜Í­TŠYÓhu J(xæ•×nœ½”›W|yjۮ닅‰+ ¹Ìbvu¹°š)æVšõrµ˜/ríV™F­ZÍ­,µêåµmràÒv½Ñ(—mS'Ä…Œ±ë؆®6êJ¹Ý¬«jKW[†Þ¶›J0¶LÓÐT]W›µj»Yw,“l;®aš¶c[®C AB ˆP–J‰»F7vÇqY  kr/D €®ÁÞUBC€$kÄ´vG„®MýPbé²$3’b©ºõÕ¢ÚB•[Žq/¥”Ë X€aÖø¥¿v¥o8é¥.¬ÖkªÙîMÈ‚\h6ÿ¯G}^ös¿÷ ƒ ð°áïŒ:e éºtŒÚ·žýÍ—ùdd¸ ø{ËZÑ'K,ϯf²ÃÃë{âç]!wÖlV綯{ ¸´ H~Ö]Zͯ^8õÉÏ9žL]¾rúàƒ_€¥F÷pgwßV€œj¦pæÅsºV‹8½Z YΔéâóã0¼wüù·¥a¹ÑÔÁçF¨û. Ÿj¦Ù®‡‚áºXeŽu‘Ç+:ʼ‰©i± —wÛ ‘'páä¥|ÐÉ2Y¦5Î XÛmÚ+"—ø4OVˆP÷&“*…ɰg¥¼"ŠÁl±9Щ@,Û !Ôl0-/VD–a9FR|«FOGrs"üÄ/û§ï}×Xuƒá]Lj ´4k8‚»Ã~ïÑÍÇvþÇ_}û§¿üá¿üÍÞÁŽþž‘zù©ß>ø‘£×3³úà#_o3ã‘Vù—_}µ7•ÜqpçÀnßÛÏÎø|ŽÃ{çæ—rס›6m©‰ÁüÕ«Ô!¨f¿>þì\‰ê$ÔÝRÙ.5콉¨¹¹ºÎ‰OlUÒê–'¢ElNuI2cj%<½#˜ìí‰ltmã·?¾X-üL¡xg`ß-·í:üàÿæ[z‡.Viφ-¯>ûâèXœa1€,˜™ÜB€Û°Ø¸Fl. I1Ö•º¹ˆ¤~ù«'6ô¥CLĪ+gŸ)YZ$°¿Ø¼pÿ†-犭6Û"¦î—­²y™åØ’ÇÑ(›`=^Ê~N=ß34Äø„vQk«9_TV‚b«^¨hKcûԒ9¯-I2#'b…-¾-IIUm•ûFÓ†‰ q>e"»("Yîñ¸¹z)懚(à6ç÷žáN¦ÓšsˆâLc™s™¥ŠðЧŒŠÚnÖ¥r2õúäÓc»öXz¡kÖÞáÑ·ÎÌ_y[¯5QíÞÈ:>g¥ì °TŠwÄT[et–“9…õM^|cvúªe âÅ,Që-‰g/BÊ Hd¿D1ËP>3¿”Í,éV³¯wK#Ÿk¶«!Œm@uµR¯Ià%Ñq‰mÛ”¸ºª "ÃÖ[†a‰² (ŠÀKZ»ÙRÛ‚È5ªÈòØu\Û±ÌqÈ´ »!êº6'@@ŽãB€ºª¶6‹a8×Å Æ­ÍRâ:†e(!;˜2®c ÃBòž’ˆÖ †ÈÀµÀÕšÐ@D@yÏM)¦cÊsŒ/Hâ!º6•›^8»i×(„JmÛD,‹8¡µ^’™º~M¥µ`÷:ØV­Û‰Ǫ•ó?ÿé“§NÂ=ªÜ•Ï.Õ+y—a hƒ0OŠàÔ©'¾þ¿IÓé®=•f>œJH¢X,"=ñ©Åy§`®_ó3Ïÿz¨g³À1¼¦ÐèÝÿÃïýkÏèÆ­7(ç–|‰ªš«Õ™xÿ€f[o"Ĭdò=;J*U{û7ɬh[€Ú.qðʼnWo;p·n¹K™‰Ž@Ä%€€µ¯€«K¹Å·çµ¦½Z(°>.6sÂ:”rÀHò‹õ¿ý—/õ¤¥ÅšÅº 9ÚP‘À±&d ‡,±y?Ï ÙL4ê8¶Újf–VÙv[Õ4B çÀ@$„k&㸆у¢Ýræ–K%­Ðªõ ­ªë•X¤^~ë”èWXŸÌ2Ray;-µe ‚PjVöÚÿÒ©'¾ó»¤â6Ž ×3í幉?ûÐK'_ ¤“Ÿ|5/-ûö™}|ïMÛŽ;´15 xB’Úrôp4¢ð"ëóô¤wîØ:ºçÀðp4ìãYd€‹ ¶°â0B§_~åŧl\% $ˆûoÿ­wþþÉ_=óòÉ—S°e°v[o­Zr(ô¦ÝG»6¥×§ú<¾H—­3…ìÂ…Å•'DºÓ]ùÅyÖ+ Öf§¯ÏÎ~àÇ 3m.ªŒ”Ó›ÐdBÒÛu½Ùª–s333žD  ƒ^AQ¡eÚ,뼬_-¶ëåÚº‘]æ’Â{¹ƒ·ßé`Ü™ŒŽ¿:Ñ0—,mM×ýþ$veCÅrÄŸ[lÌO_|þx¨#“ÉxØ`(ё˫íšípÄu(ƒJ`´¿Ï€®Àû9Žq Z¹>yêÅgUµ=?7Ãx|"¯,æöíÙmQŽ˜:‡ ˃ä`|Û­Û –f—»ÒaXë¯kÕDz \Ï •@–:Ëv÷ölXß3²~lÓÎÛ÷¤‡7 oÙÞ54ÐÑߟêèØp`ÏàÆ­‰®ÁZ®bÚÍhoš!Þ•åÅ@4Œ)­æë+Å|­Zm”Ë…|!ŸË•V ¦e꺡ëšë8šnÔkÕr¥âÌr,T3ŒF½¦ºe[š¦cìbŠ1!„Ó¶ ËÒ5MÕ ]m«í¶¦i–i:–©©F£­6uÝ6M×¶,Û6MCk·uU3-ÇÅØ´lËqm[6¶Þ}À± Ë´-ADY®¹é×:”BJ(„Ak‡ƒkñ÷5]ë7 DŒ(¨á–çç «¸}çAÈËZ£é8šìõ1 C @Læ§'|a`ì ÃÊnKÇm]îJçSéî³'߇ñCÿe*Ù³´|ûÿjXvÕi²Š2~mbã–1LÐÌtfUÏ\;9¹{ûÐäñ)?{º‚µ‚îóbKĶ˜¨»¾kX¬å[¯×ôh5“/&º6BH<¿&°Õå‹À’< ßh«Çñ´!(•šÈÐjB}¢g:³ºïЖz¡ôÉ7Ïíößÿï'ŒÍ\Ð0h[Õz}=›GF½{BÊ)¶œ¯Õ0Çj¸³¡P‡A06”ö&|¢ˆ!Ã:“]å]95”¢¾õöoEVònç/G›Õ¶Y(˜¬ÄFyÇ“(55í‹ÖÝB³¦'d@xc|•¶íhldâmmÚ{KO*ü½o~uÃÀ–îþî¸ùЧºq}Êæù…éJÐfÚŽè[­ÖÂ]n¶´ºœÉz=¨±ÚŒöŸ|}>qëèÈ@Ç;ù•Ô@ð±w.þrxßÀå‹#úk…•ø°×2ìXˆob:3;ÓדÔÕ¶à±ûb=¬„ˆF«6£ÂÌäuÐM»vgfBQ™‡R9 §º¼j«¾ykïÊÒjj4ÕÖí|aÑŸîvis×ý|¨ëâó¯…‚\ïÆáÌÌd]«Jo[wy1]sçð¾O$c‘ÃT¸ó§þÝÀàΘ/Ö3Ösõ•ÕŽN†,*p< ©Õj o½ù}/<÷ÔÂÂêÞm-9ÉÆIïRyÆ+{Ç/Ox¢B³j«úT¢·Û0\ÊA`Y–mrœè yQ’DÉ4 –E'`‡xB!9²ÔV«¡²¢'Ôæ| â8^èî ÛA–a]ÛŽÏcwu¦ ˳,kj†fh¢$r§¶TI‘eYFͯæ4F³¢G=®‹žå%™…ˆêض®j.ÁÏJ’ìÚ®ª™ºn¸>›ç !Û¶ªê EIb¢µíû5G«ãB†°ÿãG¥€úî–%ïUÿ XÛ¼¢P@Ñš¡bmއ¢ÕéÙŠ¾°}ÏQ†‘mݬ T"þPŒb `”›Zh6gG7Y_³Q“âñð¦e‡Ò…\niiüýŸødG¨·^X6µ¶ì )„¾=ñÎÞGV—gF÷m–¼1è¢òÒôðè)Ø¡Vk †:Ö}ëïÿ꽉XÞr³ràÈÍÔ¡ l'»;Mý_¿ûèGo:vàØÌ¹K])uV³šžrm±§+¨¶iKSW–¯|è3Ÿ±̫¯÷Ž)9`ÔT ÛgΜü½ÏÝÕ¨Õ_=qüèmü±½ûö¬ÛêXŽÀsËK3-ƒˆ~¥µœéð…JªŒ§ÛN»ªb¿' V+ØP'^¾Æ…W‚jåšÍ>%0<i5ýy)wCl;±°6“ÑM·f©ãWç·Ž Ê€Ž€¼vCóúäÀ³n`žh–%rQ¡Øq±å>Ï©³“wÜÓ¿ißOþã; Goظ•X8=8`ë-£n$ûR Øé”êöþèÿïW~øèO¤XdiiÖïMÏLáó_üäCÜò›; öœyþ‘}ᥬ½cûè‘cG ùʳ¿ùÆÞ}wõ¥;ÚØÍ\--­^/7V¬| +ù¦'ÌÚmXR`¸ðD›Eh‚²W ×ÖXÙ Ž7ò{;|VlöN–‹ù=õÒB›¨*×ö‡:ÍbÝhëŲªõïß•JE­÷‹Çaó˜7ÅšY½ëà»¶nùÛ¯~ûàýÛzþâù¹îa¯n°R€o¯fý~¯xL»àb6!{ºÖu—W)Ãöw+ñЕù‰Ý‡wøYï‰ Ïýê˯üæÇÿ9²}Øtp0î ÅP#Ólåë(DXã96ññ,g·TEKKK}R!Šx‚ÑÊìBâ•L–‡~5¯C¯Û0šFwë±-7?!åO½]S™EžbÔ¿®]˜ÎVëº:Šyµ¤eéž6V?7ºq×¹7N ’uÎr[¬èº~Oj6“YK Ù,PËJwšB@(ÏR»ÙlåK…d¬ëÊ/óŒÔížxëB ·¶(ð2™¹EžAMÍÙ´kÛæÑýÓ—¯Z°9²eÇ ”mìdV‰ìD}Ý­f!šêÄŒÄ2R¢©ªÞªIâu2ƒ¶a5ê%¹7lº­«Ïzx¥¼Òtˆî ú¡$ËË…ÅeµYÆÂÞp2£.p2'»ˆƒWr®£*2,Çq8¸a'<%Ä (ñx%.´Ù¬¯.¯ˆܲçùÛj±RpÆ0Ú!ŸÇš¨^œ¾tèðQÎ[Y]A€–šõP(<³t½·k°¸¼„%Ý'Ah¯–t³ŠÇÈŒý^åŧžõG¤}7yùé—dž£©¥.n@ñýîO&;cä# #ØP”è\f1”ˆŸ|ú…ÎDØÑµr)ZõM;7EºRRÖe$êvMò*Åɺ'Þ¸x¹´Ú9¼aËÎ-ëF6¥\)·ª%Ûnž}ëÜØÖMf…å8êa¡7ܬ:¾x¡@¡õï;tÇþ[v%;††Ò½`´ J‡kz‘ÏÚ´ùæ©©¥åF›˜0®CððúŽz®d£U›‚üBi)¿ý‚ÿ¸ IDATì÷KëÈ¡¨„9Ñ/µ5×C(@دøe–·‹mâš¹ºÚZ¥º5=uÕu ˆ ä(”C€4«Á`†f¸3yèö£¿~æé|ü‘«z:–f¯ô÷ôíØöô“OüÉW¾´a}*_®oß³)÷ÍÎM¼ùø/'/M½øìsÇŸ{zjö|³†uSådä ¸ð=ÃûG7Þ|pÿÜ¿¡£KöÉa©k÷Xÿðº®dšUb¼¥ÔÔÚb¦¼:³pùÒë¿>þë×Þx=ö¦}·éq@]mÛ3ÝÑW4§Ä`Â6\­™É/­DºxÈ*Xk‹^_q¾˜«Ÿüø'ÿü;ÿø=".o½éšã Åëöï|ã¥S¿|ñɯþÍWŠ-Çi]óE;Zì–šØMÄ7óóízõòäô‡>Œ0ßЛþ.dÕ=¾Nóœ[:uó-÷´ö•©]ccM£20ºÑ'+«…"®—céõo¼úì7¿ùíl¶Èš Où®xÏä[oƃcžk­5ÚJï¸éö>€­÷éýÞ7þ=é  O¼U©,¯ˆ•J\â *T p9Vï¸ëèî›n­L—«ØÑó+£#}2ÄÔ©ó>Aœ)ðYwÛÈÆ„Š< v ••ƃí·ÛEZÃéWO<·eïMñdŸ'•Y–„x MÆŒÄfJù‡nûØG>sÿÇ?úðé'®Oæ¯\­­|ù?ò¹?øØw=öcú®Ü—úß~뵚1.™Îj~!Fû%A1d$b¢Ã÷ú»ƒÃé¨ã ŧtö1ˆÉp^äZÀlÕ*åBس ¼rõl6SµVå^ ñ¾m룯½4sYGä" ö'ÃÍ(Ù:|Ìm^­gœþÍ"õ/^] {ÇeöðXЉ½ö›—óëŸtm;°01×°ñòüb<Õçç=Õ…üöÍ»ŸüÕÏ€^ÂA<Ô×mf+/?ó”ß§3làÆüUV6B>ï…·_ÙÖ·K3TWQÛeO½n®öùK¶æXÛiôG7Y-Ifµ`8œ¹²R©¬¤â]^Á÷úÙ7s™M;o&tM·j˜)…õ3ñ’1O%½¡ˆ:çú†‚6aܦê÷±¶i{ÅïQ&§Î·Lΰ›}Cçž{Gfºa‹¼Kìe9ZSBã:p>ˆ¤ð%¼¦`µs äE0¿´dÅ(¶xYÀP%ŒÆ¡DÕšüÁÚª–\ÇZ@õE¢`Uc-LLž ò Õ½Ž8Úß/ÜóÄO¿g;<Ïžem׬äsÙäõ@0V«Ø³—ÎoÙ¹gîÂÂÒÊåhG´\Îq²Ïзњ¿®¬pûðp ¦–ZkÕµ&ﺳSó7„C7ªµV¹^Ø`©R–e‡çX‡ã%YÒK&Á6¥À4 ”¬ùM‚/É’+¿_öȰý^Eu4žã$‡ˆs0xžã9 (âŽe„`ˆ ~WAH!„!È 5/!ÿ#V…k¢/ðn¬"!!.@ïjv „€µ5‹8ðòoO Ðα۰C R⡬ HƆÉp쥫oîÚ{‹D¨]Í©f1ìˆ|ãâ‰:á£Îøp϶új91Ò•›lº‰âáÝw¿}j<ÐC;Sé%Ýïlyxûºfèåš'ž8zݶÛõu„ì­î÷p‘b«‰{ ÿûç?Û¾cÃá÷ÝRžZ”ãÄ–ç'7nÞ±XXÙ¼ívä˜Èfõ’së'vÇ;»8›”çf‘åto\k¹_Yº‰;ØVu¹£#–êDI`$Ë´Õ¶*1Ìñ'ïŽúc°™á1,‚ÐkÏ¿ÙîñyÃÙù©»î»÷ÅW^VåÚòB¥ÙÙÕ׬ÚulÖ¿lg6`ÑuKR2.y; ¥@aæV9D+Pm[ÑôQ©×‘ëM¶ˆÃ„F4¦§§†·¾o2{n}jزññs¡AÞ° £kFξâ²Ö¦±Í†ž7–ê¶Y¼<äÅR=³þÞ^<{¦a@ï×¹¶kðœíà°­`¶ÚÔñ.¡ ›[È<úõoÜvÿa±ÛÑÛíý#ûäßío~ýóÇÖu©+«CÝa§ÊZ“Bׄb;N@ìBV¨–—ëv»€¾¶ZvúJË•%kfûM·6*­ë×'³ ù¶YrIÝÒ›Í:¬Û¦é8õð¼¨7Ø82«æ>JYË1ãÝ‘-îHÔXcìyYD)ú}^8Ëví6o:ËH@†BBÔ%ˆ²(pO $#–YÄp,dÖÊ(Šà`Q)b %ïšO)tm–A€ ¥²€5è”SÁÚ !]3¬RB \«À ¤„B!d ‚k­–€Ý‰4ÀABbÀ ·&4dY†¥Ü¹·^ؼç )°•+Í_»>¸;íbä…ã¿þÿˆzÏ0É®Â\w…wÕ®œ»«s÷ôLOOŽš¤ŒA"„ p›ƒÁ׿€ ƾcŽÉ’@ dI(K£09§Î±:UWWN;¯µîçþ¯§~îg­o½ßû=ÒÕÝ»ñ–—~ûÄ΃êåF¢-tååç¾÷‰‡>ÿÌ3ÿ#é¥Û?R¬4ˆ¦¯LØw•nÁÆZóüÙ7NÙoîßñÄ£ì¾êC©õ;3—ÆõFfë–Oþþq*_xðÁË—'ÓP°×sÑT;iZ~ޏ:Í,eŸyͧðé¶ÝáP°YlRÉñÊ^O›Ã¤±7GeM«ä e`{½>QÓBp÷-wTbë7¼ô§?,gŠoþøwßüÉc'_ù»ùžBäD >×Ñj¼Éÿä‘Ô¢kGì'(}YÖÔ%÷¤’0ìvðcA±–Ï‚…üD­^‹ñÃoÛ½‹Ûÿ×ø Ç_饱‚oæÀí›ú"{½òΕüI}>I¨27Ù›îlV¸Wü;Og]äÒ™Õ)fzÊÔ¼ŸüìýwñäQ@H>WTáª{“iÛ™«£jx°Ëëõ_9þ†kù»×!¼$ª…ÞP,•'–KÞÔÀâOŸ*À\0±ŽQe(¾%?јd—§/,ÜõЖÉÅLG[âFÝpIɱœPÈ‹à­×^Œ„ÚÓ©Xu­Ô̯2¹Ç¬æy­¯°\hLö¦÷]:òX<ÙN)…g¬|v¹oËu$γbw:nÚdvqA”e£Êj•U3îMǵ²-zk:ˆJªhø,ûrЛ*d 61)¢0(>??ý½oþ¯~êKµµT ¥<£Ž]²J,êô ¥­r¹c]'©è™ÔvûwÄ’Ç5ê͆Y®,Ýú¾÷Ë "”Æ­¨°Ú>r~q9s±«kgµ®ˆbZˆ4h¡RL&;ÃþÈÂxY%Y¢ÄÃxŠ\4‘ÔFÐZËæ\!¦hDU=„’pÈŸˆ‰Œ1—PÈ iZ¢!AÄeŒçøVÔDD˜1†x¨B‰2`èMb92,®ËlËäE…J)ŒABÇuùÖ¶<ƒ­ï”ʱˆ1×ú’Ðjâ@ m]øþï®D ·þP„h¹CH{c{e̱Zèi«J €º&Ëe&7oÛ+H%„´–+ îß&‰2câØÉó¾Xj]±²¶ñ¦kyl›˜ƒ^ÿáW_¹óS§–”›É<ôÿ«P¨Û¶ã@½³¿] uVKÅ|-×ٶΨ®íÜ·súìù|mâW=´¶¸BÍfgOS'ϽúâÞõ‡|qÖ,)V‰€d :‘h¼’™õtwÕ‹Z$ä®6|»,*Õ+–/êS3%5æ Z ´÷ºŠÍFÙ$¢Õ´/‚¨™¯~ûgÇwœøï·~úèO+vs ›µ2.hš±fºPò…J8ˆ†“ Ä\$ðÿêÿ˜ÕÕ7`ýÀÐ~çGD*s.“4ƒa/ä-׿§W¬¬ó­ ¿ èD)gŸ[;¸í†Ss' ËÞy{êw?{û•çßsÇm«œÏ眹êئ^(d”dOïÑÉ˾-¯¼yüÁ¿úìÅ#§’Þ÷÷w=þûçîÿà‡}aÏÎ}wê~·`|òów¥Õ ë;TÌÖ'‚¢Gõ¢hÚã–ÓþÁ¦Ë£ >UÛØ®F)=É`4ê·ˆl™ÍõÉÕYÉæáÞÆlföÙß½ð_cÿé‰H¬Œºvã± ûw­6 G¯œ†z}ëö{¿ôÁŸ|iÉÈÕk‰,ª4ÒÞ Ñž­Î¾ïÃW½ôØŸîºëCÏ>út2^äzöœøóØm÷]½ÉõôÆÏ,mÙ;¼}ãè}áÈ©áNÁ N­L-Yû’çÞ¼°aû&N¯¦¢A€Ö•WÜÂZQ GfÇ/9®ÚÙ–Ðd«W8"aŸ»¦¯U‹‚Ä”`[³iÍžÍÄú9(†YdwË¡…ñ±+§Ú0´Žrš?T-ª"–KºmúÚ´å‹Ó33«åµ•õ;¯®äʹ¥’'(ð‰jÓï¢í{¯ý?_ý«rôµ%M˰ªEÖ>ó™¿ó·?½ÌAQ€9Î%”0¦yýOýê1Bkþv#×ä%.»ZR©e 9ÞÂüÒú3“ÛnØŽ»oïVh[ç]ì ïÛðûÄqÇ6+•Ü¢‰B{_yµnT­Û²£oûnH¢Œôúü¶éÈq%Uè¨X¹X¢³\01•üªåê¢$躓™žàe9ŽÃs\ûºT8àeAÂÇtµWór†ébAêŒø¿¸?9çy^°¡ë„PAæ}PÚ¶ƒ8×µmÇq!D”0ñ‘ƒÄ€(î»g- €<‡%‘kMM´ü¢-zh‹c`­  kEï望!D"Æ%”ú®ó2!ejÓùÙIEæ8ÙëRÊ jÔ«jЃ ÆH[¹0reêÄ]÷~ì‘˪Ÿy…6ŠÍ¨}úgØrCoÀßõýïü设·”oºÀ1ªu‚}Ý»mC7œfÿÐðÅ·ß`aN¨+Μ¿ï³_©æ+ÙÅù¦UOön}úaæÜÿùOVöÌ_.Õ%Ù6Wòª,ëk¥f©veì‚Ön µ…Ä «7›˜-2;º·¸®39’ÑÆcA„|¡œKGÊ•‚„¤òjñ…_?7¼¥-{%»õÀN×áQ˜Tan{ `6õJ{WÿìÙãjTÁ|£”ÃÂôäåcÇ|÷_¿?°uÇ—ú¼ƒQ¹á$°hVo2à4u6uá콟¸«ô'˜Ï® =Û6m¶îM>Tš!üÍ×ïúôß6 t93 -Ko˜¿"^»¢//­ÉAYñ‰ÕÃ+ Ä’Ñ­(xäWÿîºÛoBDp Æ|ÁØø¥3ñ¿í²Íµ‹ ;vo>wäJv>#quõòŽ}{O¼þìZ©ÚÞ¿»m°óÙß=÷Ü‹¿%ÀëI‡Öªz [w\H´·ûÂéÎ"²¸rê Ö(¯Ôu·¾²²à•\fqaiɯú–³¼´N‡†7 ’g»á.˲“Ì®.\<%ûÊÛÇ(Ø’:Ä”ú‘óSgÿüͪ‡B[ëïå h–« xh={ÑÙ»{çÊ ˜\XØzð€ÂÅŒÕKL¤ƒá¨×ð¦ݪ;ß©Že÷Þ¶ ‰gž¸{À»ï–GÎÿbûÎ÷,Œ-ºBmv­µC2oKb³’oÔËB¶™yþðÌÎÝwØuÓ£y/¯y½|´Cy.kÀzwwñZÅX-ÌÖJë¼²o67Êù™Ÿ»ñù/?û³?È~´÷šë˹±ª.ÌÕ{»·Uò¦ŒÍŸ¾øòq!$ktµ0CÄÈÕ¨™Èغe÷³Oþ ®T"ѽþô‰óë7n®ÔÍXYZ•½ã8•ñoœ¾¸ëêÍ>§WE¼œv.·Ø¦®7 á”u­€?YÕõf=»yëUNI¯6ó‘Tí=ÚÝ·{ðÜÉó>…oè5E ÙµªƒÈZ¥Ùéó˜>n–*&GCˆãE„‚«^ÿäÓÿöé§ÃÌõtu «ðŒEh2Sæ¼†íª¼Ç£ÐFÝȈú=GÔPpr¢\¬pQ¥ax¼¿þá#û÷JÕsU[6qwÊ«uR®VjoL&ìºyeòJ¡\¾ëCïýÉüäà¡kB"#Ì#Oȯ[È5tì‘‚ÑŽÒòÙÞM/=U[kŒì?zì™}û¯?ö£ãºÞÞ°µ' Z-ŒL^˜ñ!öÔŸ+Ë\ Zh ÓÝ¡D(Ý%:}ríximPnëL©ã®Û΋U‡kk NÕÊ@¨èuYOÉÉfiáÊèôè…7+BÂ_‚í[4§’R)(jŒên“Û:<˜ì GýNnI}gôÒXi\HµO_Z¶šó¢W ¼WáÊÄNˆ#'Þø³.Ñ¥¹+¹Ñ}W¿ai’wšà$ãëGΜ’8O[[ ±h‹A7–öBÝÊÒìørÃgÙ}]<õmîIŸž¹Ø•’d.ÊxÄy¼Ù©E讹5Ùã¯<Ŷ¢©(êòzòHˆ,b>Îóõù¢Ëö¯¼óЭþ¡öh°ùòT8š:=kØõ ¿½bë#“Â~͵l`»\ßÐ>0õÎ%Š-=†Ny†çK¹C[Ïœ>Ê8/¥nKþkR,¨ ìN¶Ç€ ACñÒBÔ!”A†$%A“ذ¡7 ›Ö1ïïÞ¿uÿõÐuת†^ÊGÂ^ì ¸M“ºŽcP,³á=»FÏ\Ì.IÅ\[ÚÛ³qcn%c4ëº^“TYpTI€žP’9n(™: "žç$‰GTTFa  Øæ æx›0à:F½1Fö…‚”F)Çqó>¿Ÿ1VªT˵†K$‘0)€Pà8®K†2ŠZ 7”RB]B]BB¡À¥”؄Dއ¸A™çx‘G€Zv™VÈÎX+cŒ¶¦À0B @ïÞcŒ2…–3³õj#WÈ„Ûz€K)!„ŽC%^œxåä;‘`¨­móÌÄxÈ0Lbšî°…©©Üþáñ×ç\aéÐ¡ëš Wæ‘‹øZ¹)©‚Ô…™Qä.®,TGcÝ]K˓Û†y9"”+¬FÃáZ½yôø;´@(sfs¦WÑÅòªŠ&Š…|…׬¹=×|Ù´¡WA¨X ñزšÞh[½R0ä:T‰çG/\˜?½ôµoücߺõýDAw\­eì܉ÿúÙ÷ý>•9´Y« ‚ ÄL«è h™Ñ™ó“—ãá¨å€‘³£+c]¶ 5‘Š °Xp*˜©í@ÔhšLäÌ&b.r)ÃÓeÍ IDATœ\['SF­nS'áSÔ€&SPXž®4—ôE¹d×€Óˆu©©¾6—²h8 1 ÇCvÅÈòdAÏ^Þ¿åУ¿yœSDóGPF}[¶5‹ lšH=Á'z*zåîïùí#?_·k§¯õÜþu—.œ=´g瞯æåÔ#¿xúÌŠ玞yëµ—H}íÀ¡á«îÝ7¼7ˆ%‹š2„£ã³Sã‹'GN•&VO¼ýö›ŽfW²+MÞ ¦Ã† j¨Z¬”ç'KW®\˜ÈN­êP%ùEiafiêüÈÙSÇΞ=»\ήß:tpã¾ÒÂҙы“§Çg§Œw ÷ŽÍä×–WâáZÊ’A¼º "Ìi¾sä…³GNÍ4/­½˜Û´u@ °m»½}òX2Ò¼êBÉ«¦ð¼zñ­²[¾óàÝåj¡³³kalÑt½mÝË¥ÕdW23•‰¨Ñf³Ì ’ž®Ì•ò§‰¿¤]¦iSS×üž˜'\©,¦Ò_pGòjš ƒÔ,˱IqÂøìr±ä\µ}½£ãÌ슨1Àê¢klÞÖ]Ÿ_,g¹f£;½êÙÃGÖ ö[‚˜³%.]l䆈ãØ+‹ªOΌϷ÷…U!ÊAh ,ÊGͺ#ùxDb±áÀz=SÈ.qWZ,¼ôÄãÏ<ñ›± or¢`õ#Ͻxîèëkù™þ-BÑÎÜüòâÜ$ –WósXÒËe£QÇâZ$…x!¯[?Ü»n“ê J‚ÄS¼85Ù¨æ!†ÉîÎ@ ^¯5ÖV–•p-`­\Ée—j…¬Àcžm×5M&«Šßçó(ŠÈ‰†n†n†©ë¶e∢c‚@⸎m[†i¦ë¸”J\Â(%Ôu‰ãB)%2 @È!ȱ©Þzý!@¸³C™ÛR7€VµA!ƒ”‘–7ëÝk"¢(Ξ8_›+¹™í»Þc:F[Á`~¯ÆóÜÔù“ï¼þæ×¾÷ÝìâRº£ÝË)o~¥=Ý?þÊɽ›VWO=ó‹O}îK“z˜Aëzݲ‚Z[g¹Rëß²IQÕ_>þ¿ïûÒ홢J¦ƒë)JÙåpTÆ:ùé#Z*²õàU¯w…²A¹c~b²kx¨°¼*ø%êÃ5œ|áÖ›V‹žÃŠ/Ê’z;×I^¤7 ÙÉ…M;v:@F;ðþ.[ùÒÿóQNŽ8†á‹hAoò¹ÿgÆ\øÌæ!Ì×A‚ 0§yŠƒšK:·n>}ù¬ ñ ³™……É®>ßì™ËñžûñiÓ)áDÔ´!'ÈÀ°&b옆aÅv!oòr{ŽÏoèìjߨ>ùÆ$ÄjÞÜÞ§hÑt¬ ¸Ú*c¶åâºëœ}ãt@QçWòë{ú¶nÚ»2?»nãàÀtâåã¡Î”¿][[^<ó‡“óµI%$Þ{ßç»ÒÝ3§/‰|à`º³otîõmÛÞ›lÛôìSí¾vlâȾknùïÿ÷Þk®;qäù_:â®Á¼ší Ð\sÞYxÇ“R3D`ù²k«ôT¸320”N ~è†ïñHj¥\4Ífv­B€áÕþ¦]n¢l¢©H0)Z\í,ÌM./5 ó£ªxùR4áYmÚVÙõú#~G›žóâN˜/ôïK´¯Ägg/ó Êôª_ ‚]ôŽ\޶KK0¬äšohO†ä²®4g¹j†ÃÃO½zÃíë¤.nÜп¼´´u ÿââÔÔKñ1{zz¢°S5anqzÃUC[6^W^-‡ºóãY Y‘XgCgùlÞÆùH$ŠuŒž;ËÌàÓÓj<(‰µå,©yNÈ„Kõñö¡®êtÁ¢5AàK¥F6›Ùsó{­Bijfª£;Æ—™$¤öX¿8¤Ù¥ÈaÄªÓ Û¶§»®ÌþhhCøèáŒÄˀа*ÎÖôžCµR¥°ZÞñfIÖÔ€_{þWÏÝù¥»‹kp);14¸ƒSžÃ«ïé»xîü5ï½¾=ÔQ«,<âÚÂb¸K+­µ\oïÎ¥…I¿>3~îÞÏ}o¡Ôk*§ª¢X$öæŸÿ¸ëÐuf¥:;õö†«ïÒ«.Ò‚ŽÁ—ÈÌ¡¾÷&à81Hj^uââÔ«nÜ{ã~B³-Ûµx_„Õ)§ñ#Óóëú$ /ÎçVFϯÕVDcÛk‡¹iëU^Åö»lð„s] Èwîïü¢Q\¡aXÊÈþp]°½;w+§¯(´X6“úêóªå {7ˆ¦ún¹áv¼«³3Ö ¾Š«ywy~ì…ç^zæ‰çÂbo¢]Ód‘KúN^ÈDíÆµïéyøåLB5ˆLÓéî¶îÔÔüBwghV¥ì D§¤ºFŽ|ëЭ»ëyÿ5Þ{ú•óvCã¢*ãö:tþäDõ@GGÚô9 ;ÝÕ·2=nä›Á©³s~¶ûÕÙ§·x¶zCók%ÇX•–Š¥Åý‡®W f7 BHËÍÍÈ‘t8š8üÄóÛïØ$š‘Xb@à9Ó`ºÝ,f—] D‚U³.X¥´æá!GMž³ëÔ]—ˆÕ[ßóÀùÉsš?@È¢ ’Híš™…kËWÎŒ®Ø_G˜/ñB ©Îžåb>SÍÞºoÑ_¸|y s‚Š`G´-·šËgW6G‡G'O©Nà}»o¾çÑGúÌÿ~ß}_>¸³TÎ_9úʳÏëvs×÷û|¾×?³0>·Üß¿aó±_¬—Ö ¹%)òÌÖí¦äó€¨,ÌÏ;¦á´A€‘BÛÖ­s Óu"²T9OêV³PÊ+Y_(%i^ÙÖy XàTÍ ©Ãã8,H2‡Ïó @X§.£„1jY”¸ `#aCĤŒbžã)ß*Ô0bB„LÀ‚Td-x‚ˆ¸w£vÀHKìNYKÞ‡[uÄ€QQ‹V ïÖ„ Bƒš5ã×?þSfï¹ý&Û“w…YŽ%H¢Ès/=óÚÖýW÷´÷•–ó¢?h,UÓým¹¥™ÿyùßú×9|%•^ÇË>Ÿ"4z"•¨¦»úÒ>[\9Ÿ ­/Ÿ)¬šçƒîðte*¨$9,ñPÇM™ºñ⟟JØpÕ€¥›«ª mùR¶w÷ðüåÉx[ÊÈÕ­ZýøáSß·Ë–˜¦%I"pwòðQ V%Azçø+ƒ;·{¤n$YñTg–Ñ—JP!p.»zñì‘«¯Û]˶M³Tη%’†S«¬/¿zêÈ /¼üì¡„A+Z¢§yrÙP–_?3óbÃxxÞ…Ô lSŒókYKƒOÞt¯Ýä×ÈÆuC»Ãi®åävßìÔ¼ì¡Ý›ú™e~ãûuüåçÞzëékwß¼2~~©Põ ’ÔÖÆÃK¹¬¨ˆaÈ,!!,Nׯ¯œzÏG÷6O¡5?“qKåÙK§ûv ýôÇßÙ³u`h×Aêº @AzÃÀŸŸûý½=ðÙ/~ú7ýäÆï9uæcŸ¾çK}ÁvL[.jY‘ /^ß‘ºåÖOG"á¹ùâñ·O=ûÄãg¯¼Ó¬ ª î½mû}ïýôªqyz­˜ªkΚS+Ÿ›­Ú. øm5ìKêôù «PEìÊÜå±·—Â=úè¿«+±{ÿU[·lþòw¾jÕïÿ›/|Û¢úØô|*%Ü÷‘ÛÍI»Ô˜ÝÔ=ˆ«õtoª>sôôÅUóŽ]{çKÖðÎ63$­Þ{ßgš9rqô‡}ïoÿö¯.O'“LÔ¼S—¦ÊÆ„×Ǿq:ÔY>•ͧÛbѪíP”™ŸU¶mÿîJÎ iJ½VwÝd*mÖëÈQ0F ³…7RX[*5×Rñ>Ì…YÓò-EdÍS7Æ|å=œNü¡€ëi¶ìI+…ÅæÔl©Ó‚̳“oÉ\D7ÏK—víÞüΓG|Ê¡ÞC¯~&Õ™žZÞ3røXW*]¨—xYá cSV´J=ë7iAåð«o&ú:*µÕž­mu«¼÷Ì¥óíé!€ŠuÍ\­Î M‡{µ«Þ49õŽ$Â7]U Ä¼Àņ^Mlè¸.~¯Ù¬ 9¶h‹ï_Är-UVˆšÍz!Ÿ/ñáHزì|®×0Æ’¬2HLËBȲL\ìRâ:.ÇóªâÕeÝ´M 1ñ†ã¶LÊs-{AJÔDíð¹£÷7Çb ‘¥:Ç]ŒŠ¥9#êãw_~òÌ¡ƒý. 5­ºM+…E%og‹gg.UOÜü›õª»\Ï mÜçyöŒMUëR³i<€ƒr©¢'ƒþ‘‰Œ_‹xØ^Vʹ|Ðç!ÈîOo›_Y¹tà†»ËoÚ+3™`*ÆÆÄ^Î]«Ù½n Þ×QµéÈ©s×]ûC>øÁÛÙ\Î\š©•Þþmïõ~ÙŸÚ¹>YÀIjÔi Î/ DG3M‘Gj\å-©h%iµêÝÙ;à”—ÿøößþÕ¯¯înÓbÝÃj¾*û±«¯ÝÿÔ“‡q¥‘Þí[—Nöôäõ·NNÎLªƒ¸Ón_Ì\öviŠ7±<~[÷í¾«g‡¼8`“m¿vÿOöÄ–}b lN¾¶ýeÝnï¿5q1$aä‡ë»:|m6ÔÅåËšö‰µ…Þ›^˜Ÿoêå¶·´Zà}rUÏû|ñxº³T^Å:ÂØ+D¡î¬Ÿ7±6ÞHÆãœ Õ‰õwW]j¢ÝAsãJ؈x?òÂ1-|>^4J‘´)ÖŽÓç^yÞÍDŒ#½Ñ·Ž¾éñÁdzÉâuŒdo‚—çÕ“'N¯ßwVL›™ ¼Ò3t'žš©.¸^åµ Ç˜Uw–——:;»Þ~îõt_×µƒ©ìÊÚHS×}‰ˆëØ‚¢ÌÎÎ`Ûvy$Jžb.Ÿ_šõ„âÀEŒÙë1š:ä Ä¢Ùlš¶3;=Ú7°QQ½ÕrÕlZŽc»®ÓÊ‹šµŠ¡7(„HBÑe™õz•092›uˆ0'ˆÃÀ¶!‚ Ìq‚"Iª¢¸‡€(É Ö`”†I „Š‚Øª ×±,›Q„q­MV„ ȨÀqœÀ#„!Bhíå´vé[v¾VvÕd j©Fÿ"JfÀóBviŽˆÆ]ïƒ h†d €„Q â?>òë‡ùÈ /?=2¹˜+Îu¦£/xÁïþë?ÜrÇí=ÿýɺ·tF£«¨bÚ†Â˺QSS‚ ø,­¸søÆãO¿±÷àþÉã- ¯.-$z7{5?a1`ÚÍ—_{}ÿÁM[6÷5kM^¢G…®«Jžj¹ï(e‹À3³sÿöõ_®-/©é.ÀÓ!VC_ŸÁØô%C—NœÚòÞk aqª( rn-'ø¼z£BIUˆ ‹¬±³C[6÷t<ýô«ïýÀ5¥›|çJ<’¨:¦Vb|]ndæBÍ/M¸v_µZEJ[/|ê\-zõm±Ý›Ÿ=z½áÆ[ÁÈ7Ûâ›kfÊvT‰T›–Q·4Avmu±:‰|Z Þ)¼& ‰ïùÈ ™ì¢…ârµ§+Í©€Ï(¯É¥üj³há:°ÀŽöíª&•+¹Ê¢¬u,,N]™˜FL1›:äPÐë_YX!½Mf{n¸úÚ_?òëïíÝyÛïùó~sÓµwÎLNì¹áÚ/|þKþàí:4õù ZÅó´6s9¹!¶uýðžáô±õU{nfÜv¸þÝÛÖÆ™¬*ãW  @˜B²°R¥˜‚NGä(ß`•¶€o°C’bç¬àfÍ\åݺ‡#U ZšÇž]X⌂ÃëÈõ]óËÿýÅÏ9žôº1zyôÊôDLtãáuÁr¸\;zf¬Šë«ÿøwŸþŸ?N‡v+J§_/O¥z#´ÎÆÎnÞÌóÓ]íÞØ{âøÓ] E•Âåj$,!Opqzµ™ŠdE ïØ:ðÆëoõnœ˜¯–g»eÜ%º´a8eÒìiKÕfÕPX9†å>þèŸ6\ªf‹æÃÑbÚ¸¸¶âõ‡uŽHHžYZ+dæ?vûûÔ,®”/5(eõZÇÐæ‰‘ùp\ã¦(^»b¯æ‡7 üáÓÇ. m~Þ§QY– üâÊÊÍ·oˆÏÍŽ_燌óÄTEiÍ5ír"5TÍ×£½¡j½X,®6,«°˜'ÐÖí†*HHæ5_ȶÆL6qDUÁ#+/.ÎNúyN¥äºö@r+0ùñ 'M%„ ˜&¿t¾{`PT5½^k4ë’*y´Â¼ã8Ôu£˜çµp˜ƒAìÚ&aŽ´xtŒcs„F @æ9Oƒ"EIæ8ÖÐ帄š¶K8 1‡9,@ˆ0ƈ㣎‹Þ=g!L0ƒ11Ä1Æ!€@‹t€1€ ´7°VEš…€BYkø ±ÖP!e A@èèé“çGNì»ùÚ`´‡RÞýqëÆ4I>wæôóO>ÿå¯ÿµMI½ZðƒÁT—âõxáðÁý[6¾ôÜcr‡¯±m»Z)†#Jvµ¢xä@¢Ý%¢ÖÌ\™¯ˆË k°PίëMUš®À#J„À+«?ÿåÏ/]ûÄ'ÿÉ5UQçsùîô@¹Q‘T#yabœ5æ£X³:ÕÚ_$Že7­±S'† kÕ—ÿðçÏ|í3Ū·=’›^ÈùþÎÁÂò”ÜÑ™Ê(+.¯\=vý{o0 µ±¼V¯X‹+Ë€ç$Ý=]5lù•PïÖ]ý{ßKÞ<2eVÍbà¦,FbmTõ·lˆ¤Û…|áìá¤Íâ’n`WòËÙ¶Þ”aSÔ D¢|Jèý¶ 8@DIr,W@tëî#c…µFUçøP¤_¬óÈ¥¢¨2—º\£3Ú½ZZëôèJžq¬»»»­wêè± ÿyìŸ:º»´Pâßøzwÿ:EIÁÉ®îr¥Æìæpߺ¡®gžzä¦ïøÁÿþ殹ÌäLÛpàþû?õͯýÍW¿üÏ|üSýÛü^ÔT$æˆkåübµá.ÒÄf­­³Í²õZ¡¡r {¡$Ã2’±Q©úÅöÈPÐUý¡¸çg%†‰ÛT¼^) ul6s ¥õÄ^X^]šÞ’PC–µ3'.½ôüŸæ}ñ™‡ïþÂ<Μ{“V$¹¬,š+µ¢³ë¾ó}·¼øÜ™¿µ»;Qž«–Êk»ï3å̲ƒÙìâÌÎuëÎf×ní¿#óÚ±•̘ëï…¶ Ef88WȆºc#Wú_¼;…Ÿuf†a4 æ%Ÿ’äÍc/>50¨Û8W.«ÞðZ&;Ðï³è’ìÁLô¨¶7¨Q˜éäKy<’Œ1bzÓ´ {`Ó6P4¦scÉ@ŠÔ©i™»wí¬.W9ŸNwŠÃÔx´âoo¹|Yâ0'+™ÉU(y½æ×ÞÛ^(W,‡ÖsPö3X#x~dqhsg[ÿk—_µuërf9ï¨X䆾·°\Ú¶Þ5TÇÈ…Òíž@‚örn™çP u!ŽÛe+jiyIÀžáM €u`×üäÃÖ‹ÊoµPZYœF‚¤ò²„–Aôø-ÓjVKŽmó/ ¼ª¨ËœbÞv,žãxAàx‘RæÚ¶aè0„ Ï ¢$qúI¯ìã¡—ÔtC¨FÃ!Áj9èé+­Ö–K³ªOñí˳Ó=[ºª¦Ëó¢"Ék¶-§U„ìÔR0¡ùäøÌÂEègg'}=¾z¾ i²æ@—ñ<âÔiE%½úcþÀ=Ü·<·’îOaŸ°aÃ2®jþ•¯ý¿ßèŸ!6W²õµå¹Ûï¹îàM÷<ü?Ì+‹ë;z:—ó™ëíØêOúÂaÑYj^¦ù=Ÿ].”EZ!öïîåI ^Yéöì*5›Ö¾y)œŽdFçùF¼#øÚëo]µãú¶TòìÉS7]»ÓÊ×JSKžõ)Ä3*‚û‡ßÝú¡„ªDqU‚y‘¸f¤·G\E¥FMáQµ¡€™i¾zâ•p¨Ýr sù’H!ѹ&NhrÚ.¥-â ú>_׉(¯Câ%Ÿ'r¡|e÷¶´Ý`UsÁ¸ufl <ˆÅÌÛwf2ª×IÆSó³KZ°·S‡Õ«RófÅ=q¤nÖïÞÕ,Ô'/ïÙØß9¸«R(2`v­ß¸2;»Z©"‰÷E€z¥*+–ì2 µšM(@œm˜•r‘A øTEÅœÂ2 â8‘yÌǦiâ:ÇqœÀ "%v‹–$Q…Ì0 fÛB©ass @ˆ£!ÀC”p0CÔj;c‡1„kqŸŒø—qzÐbCÁ»ø;€´tÈÀ_\ï¼$±ªµZšÜ2¸açÛ‚0@ß ð/8†þïþûûoÙ~ýÍwÍŸõôJšWŽ«W‹¥òÔ«w‘:ýÓÃîïÿJ’´¦aPq+•"ûý¶åHqöÊ9Õ§Ù–ÕÝ¿aòÔ•pRD:!¤¨H¾ó£ï7Íêî«6Öô©Þf5«.ÐCj³l-–¶ 0vé ±\QÕnp[< i™¾Dô Ç„¶=òßûÈæ/O5–@€ß ´s%ÛNBÂÕJåðëÇ6oßÝ?0̈ÁÉ¡€ÏhXu´Ã$ÄpœÌÅãG޾ñ­ù'ÀˆC€4ÜسïF«ï\7–-Ë®0èzʉõQU–W'<‘¸Q<È“t IDATqtZ™&D¨ê4W¯Ø•B– ºÝ"h8eÓŒb¦Ü@"âbnKÚ'µ»·Û—:=·dÃX£°RžÍ”{ÓIy}_Œ„Ca(ª±Dò7^÷bž¹rqøú­IUã÷®Õ cÎmPúýáÏÝ÷™_ýìç~îË¿ûí¹®~ܨ”õæêW¾úµþ÷¾ÿØ£gN®Ì-F£òås‹/]ÿÉÍŸÜtGŨ\<7yé­l³a]À¿’-3o}ý’E8‹·‹sÐ0ó†ß ä5o ä N'4Ÿ0}qÎễF`~i.+•ÎO×üv£sG»H¢‰îŽ÷ïØ§ën±T‡þXŒ¼uäðîë³ óR„%Ó›¿ò7½]üæ?×k” 'ÑêJøCñÉ+ßúÁWÌFÔÀѶ@6W2nT-ú¤Dðš¶Û^^x ΈË<¿8Whþí;÷\»Ü±qhmäÔÒÂê©Ìì‡>øòÚuoS‹¤×žr²£T£†3™¥õ±`´¹¬Y¯aÙË˲m$ËA7R4f=jðÊØ•f£ Gâ©ôÔÄï°ÈxAÖ뤽½sa²`ÑXíªú*¦nš¢ÓNoÛú§Ÿ<åš ÅË#EOXÐe€´µõ{ÕÄô©ŸoÛ•ôqªŽé’>?ÞéHºM¼k³©ÎXÈëY™ž³äQüª›»Ò³mÓù?}9ÿÇ ƒë̺Göª™3ãókçz:7d+‹ûöÜÔ,[Ó“ãJoè¿Z¯UO¼q„!‹¯Ë.W¹Ù¹~ÐÔÍr1#ùŒº'ʈiaUH¨U+BˆÕ4–—ò~ b^ö]Ç)¯•($¾`Àu‰WóA€–iÛŽÍóˆ—d óB €Ê 'Š”P åÚ€º€AÓ²%"„ …"€°ã:B!æxÂ0€1˜ƒ @)„âwËÑ­j!úË‘ Aˆä[>ÐÅSNÄüŠþÐC4¬ÊÆ]û/SЭ%Ö¿LÚŸzûmh,mÞ{•*ËŸPbÐ"ÔЗóùÔÀ@<:pô̳Ÿø›/G;»˥Ͳ_x¿Ÿ@Ø14Ä(áy4{fj~ª s!%¢ÕJ œò‹œÈ•€ðú¹wvÇøÇGU%Öß½¹.n‘`ªWEY¢Ì9}ä|¼--†¸z¡Ð=¼±Ò(a‰Q.V\¯é÷Å 3#gηµoŸº C×°¨¨ ‘!OÈ èºsË›¶%¼±r±äÔ/èE’ÞªÊålþä™cm)ÏÀÀiX©Tû-Þ×ÑÙå÷†›BÝE{½~ÌÜZÓö‡Ã‰HRTB*Š^uÍjRBMÓüÿxzÏ?É®òÞw…Cåê®Ô9N÷ä<šÑÌ(KBˆlŒ ÇñÜ{}.¾æcãŒ#8c°ÀB€…嬑Fš<Óz:wuwå\;ï½Ö:/zä? ^Ô›õÙÏóü~ß/P¹ZµÂÉÒÊrkcîz¹x®íX!„$E „ü€—…‘OMÞ‰ÈQ‘” |»i´9ÈAÑèXEU9Ö7®Nnßzë}Ç™˜yÿ½sŽÕf€R(€ŒR-¤K&€ëzdÛ®}¬hØÄÎŽ\¹òîxÿîB}e"¼72¾í‡O>ùàÝ7›U¨‹ÇGî Gñå3?òé/üÁï}åý÷ÎÅã (j óku׊ÀOï=zôðá›g‡z£ÂÁCGî~ô¶©­»Ž¹éÞGï9xäÈ==vô>Úö4uYc–eXöå ËW.œûÞ·ðÅÿõå¯ÿÙïÊ«‡ŽßÔ­¥ÊÊk?y¡I.~ù{_{ìá_»ûèÍɤðã?í·L—7§»õæ©Ûxp}¹Æ ¾Us:•ò|%Ÿ–w\œ™ß¾k¼k°œ™ÞòÚû§XŽsÊâŠeÛ½±§÷íu n»](VKÃÚc÷|HöäÕêåÓ®vEc÷ôtDzmÛõ¡‘ëâ<-÷†‘Û(¯¥3!PÇñ´ ”z÷Åw/¼û6 lB(¡”( r§Ñh7»vÛ„<~ðWŸxòßþîøñ›gçj~q}ÙmÉÖGï=tòç¯E³òm·ïšØÿÞ…«]³½^swN dB¬å¶¬æÃ·ûÍßÿ­O|øñ_¸ý®ý§¦ÇoJ§³SSS7?rà?±gp›[…%¿2¹rêù×þôoÿîí÷_|ú©—œnµŒf«Å j„@Â…˜¤P˜£à©ïýäéï}Ïg̶‰#Rß øV3×—ûÆ_ÿc³Úð=ë‹¿öñ¯ýâ× WëßùÎ7…K%u“ÁãG÷<úè/ßùÐg¿úõßIï*nܬõr=¼åpV£kíòÞ›îx÷ôåÁ¿Ò,´Ë¥j1¦ÇL·YñÕž,F‰µ÷Љ¸˜žÍŸ©‹”ÚÔÆ€^¾Zõik°w’·“Zã”^]8’ÅnµéÒàÊÕ‹÷ü1މ+s‹gc$iœº}pmÊxEÄújæµ¢ÁvØáâÕl¯zäŽ3gg$Üe"x†,¶ÿàv×¶Q\n”;a±Ç Ú¹¾ìZi>^83O¬FzŒZYFqßi¥ûÇÇû·Ôª¥\: 9vðöýñØÀÕ³‹kWÏ"ÖuMÄÀ!§Þ|[óãÓÛ)yâå·._ziúÀ]H¼ÿêÛöÊÐÄ6Ó%žß˜žêIäÃ1­8Â(„¸Ój°ÀŘïv»_4>Á< "ŒÑf¦!vã‚h7ÚoÿìÙÁ]Ûwì»­Ùn qUI¦ÍNª?kvH²§³Ü.V.Dy PàÛ~ya™p¸k¹ál$>\˜Ÿádaéâõ««‹¹í;xE¯—íFeËîAÛ2ŠÈSÿñ/—–gn;¶pqÈ%ÔëvŸ€@ ¤-ÇzH‹¤åT23Í‹ÕÞl4•˺ŒKöäH’hæ›^ msqñµ‡?þ©ÆF>=1™¨jTÀP¢”Èh@ÈFi5Ñú2#¾Ó…0 l{m¹`Ô*Vjë±Ó…bíáÇ?a¸6‚ È7[‘¨â¸¶ c‡ØÐvi7ÊÕÊúÜò9ß3`À$@^xóUÌìŽá¹.³¨ÍË©Âû3õzqýâFxÐO%F1–¨TkUÎfð.Þ76¾õ¸¶5¡îJDõ˜i[$Z×T #½©S'¯C¯MÅ(ä9$lÝ5©AvíüK>1é&u‘R^ļ$$zŠ‹3Ò‘ýœÞsíüÅH¤¯X¬ ž0{í…ÝûÅäüê±;>ñâ¢aÍ3Ñ ÷fÆÕô‘;n=|ü6ŸÎ]Y>óúëùòZ©°îÏpÛr¯Ößü×W^>óæ;Ͼ7¿tÖ¬ø¹ÑðÐŽñ?øÊï|é·þð‘Þ;|Ó‘cwíºõ±»o¹íøÁ¡¾©ÁááõjZޤ¨š¨‡£Bˆ—/`\°}t\Ur[¶˜9½Ü¨šúÝßÿ_õõÈWÿù¯+Å™Ûï{h Ü·RÞpßvЭ÷Ý|kuiÃ,”UWà®[.®#ztxë–Ëïœ),ŸÝ>•Þ±;×hX=ƒØïza })ðH~áÒ¡=Û›f>3¨ 0ÆåñÇŽÇ#©ZÝ2Š$•ò¯][ '…–·’úÄ´c;̆ƒiœá¶cr2Š ô¾öÒÏ$.la (r¹Õ!N' eûçgó#™±Éä„aY˜—¨€a"›Í¦%A°]L‰sJo®°¼tqn¾g8÷Ê o:EJp2™Ü?–'Hå6ò•ñ=Š˜â%Iï‰öNµjHOHLôNíÝ?Ô·}éÒÚÅ÷~ÊÉ(µex}~ýåç~,÷*#S[‡GƺëîõÙ·&woÍö €UQÕ(ð\ÏàP_v$°ˆeAà“Àg1ZmÛµ×1K%ÓB¡H8*ˆ²Ž&RÙh4.p’績ë,àx^’IcŽç:®ó“™ÆÆæ8Q4M…UMW%Q‘DÌqa À c BˆB˜9#„‡à6¥]…múo¬¬n\„tsÏ c”É07¸=(€àÆZžAÀ6X€:láì̇>õ˜('ÌV9¤éaÛ5#‘0ç»j2éµáËï¿p˃÷2*!J8‘Ó‡Ò†cSq8Ü^/pºbÔºo¿ÿÜÇ>ó Ìó,Ïkg§Ç$}„…+Þ~ýõGï} wtÂQ ¢œP“¹T~e=šMA_~áÇSû&®¼u:»kºPnÇ"º®Åÿ›•Š£8Q_þÝ›ï»Ól›.éú¼t,³Þº$©*FH0;ÂÂõ{÷û>âºëøqQ}ÿòìÁ‡Ø‹Ý’WšÚÿoýÛçÿç¯È0‚]ßÔÃ=ÁJWE¨P*¯L!ršˆ4…ã8j{8¼,ÞyôÎ×_zñsŸü¥?ù£?úå/ÿúSÿòÎÑ[Œ>úéoýÍ?þÁŸþ‘Ó€©loÂŒÈùkëEØÒB2§ëÚôä`3/ÍY­u¨EäbQ Æs–k ߛޯú ‹ù•|»ZüáÙ ’@#}Ä6L—³šA7jeûöD¤¾¾øþ½Gc¹ÄÂÊÂòÅ…Pt°í0¿²Ô–bçgf¿ú‡=öè½Ç;íÝÖm¨ßüó?6…Ò-»>õî?~õ7pY……2k'N}uá§ZtŸµ´úį}îÊ…Ù××.<ž¾‹WÝ];£%ˆº ¦/¸zóÑCçÞ˜ܺóéïÿlªw Ôõ¡ØÖkK§Ç—ºå»&4ºùbwnkè#ͺÙ)—ºÅâèd?eÄKèéH4nz/!HâBÅR³Ñj. z(ÍaÜjµÇF"·îzR*§ŽàyÍîXÅå…hª¯”¶MÝe6 =È/S¯m:rTßÚ“ˆý×Ï_Ú¹m|°»Ïý(¬¤æg.Ýtô8ò#«tÍïâÃÓG^<ýC=B½=ª$µju—ù¹Á¦ ˜7¢= u¿\+§V—®Ï]9Õ›Þ2m˜õX´—zn"›Áš¤‹j·Û–¡‮GÃA@ ‚ÀãD<¸u‹ ‹ÕÚ† ò€1Äó/¸†Aõ]—/+¶ëK$ÀX$y³`PjÚ6B2Æñ@2J a„x® à0G!$À 8ŽAH!Û\Y!ˆ eB‚ðfq"D6óð0ýE©¬)—Nžñùš€%³ÛæAä[Fò8NÐæ¯ž›Ú1*KqÀRêZŽéÛ!1©Õª#û§þå¾¾cÿŽh"¸t›†ëf¢qÆ\ i4.9‰(;|ìð%GÚjÔ(e>ã)%š,/Íçù(ÍdW +ÑTÒê˜!¶çI²b{ž¦†›Í.Ì|êöÏù Ç{Žm3DõH#"D…Ú¶Q­m<ðñG[NTae<›<º…™*ÔL`ˆˆ"zsý3³ó¢¯ÍVO›Í Ì 8Ĺ©xßþé® ¤r>ïJ$Aƒ¢³{j*_^67h.9†²¸ÙîJ@ª´Ë:Œ»`EQÝõ\Û¹Ø\Oö̾¶|ó‘]€—òna×±ý’ jYe=½KåÙ¶›·\Z«]Ÿ¿Ò7¾+¤q–dN‚$Ä+j£Vq»hhxt¥ïJÕžö¥Šù…C;Ž<÷ì{Çï¾c÷í?úáìžZt­™¥+N@ÇRÜòLe÷–ÃScGÝz+¿zýÚ5o$¤5Ð:–r²üܘ=3g'´ñqç홎·°¬ôRðRˆ«žYL2BJA½¦”{ÉþøAl'/w ݰ25»›Í&Ævo˜ظºú­ï<ùÍþþöíã´E¯u®/µêš±‹îDåÕU^b¶$Ø 'ã­ŠhÍd|èÊ幉áˆ" •ba÷ЫçÏšAytdtimCÜŠ9)ˆ'fÌ+ZSëÈùÕ BpiõŠ+Ò“¯\«›ÆôH®Z.K(Þn´[5#n•`7¤Ç›k­Dr<燚« =ÍD].\¹²{çd²§çµgM׿I÷ÈðØ„ÁgQæ{‘H²Qk¹ª`8þØ–­ÏÿüEèvìÖ‡î}ë¬"/ä¢J`@ßÞøÌ#ø¦áZp×î=‡€½÷ò;Û· æ×œxZ®¬®7@2…a5:{ùŠšÔ!áš+u»Ó”z2'‘L¼ô¾ëÏj!nçM7óËšŽÄœ(aÆxQ¶œ¶"‹¡PØó‚0 ÛžëyL 鹡ŸxíV•@d$‰b„)c‚Àc„Ëò¡h ©º()²$W–UÍñð7~ÿþÿßûß/ýéÓw?xÏŽ}ûþæë_ÿÅßø-£ÐתÁòÊÛ=Ó|×{òß¾ç4ë™)¥YK¶<·ˆKÝÖ¬.2Žj¢Ô–ňa–jKuH£Ó;ÂÖ7ºçÊjH†Õ I™Àæ‹o¿%}‰(κ¥äÚz«äµ»ÞË?@ùݯü¿BŠ -‹x¬eŒ¥¨Ù AL0«Ö€P©MŒ*aw:„/­V'F`­eÄP(•Êw;HxYâºÁÔ–­ÿôÝÙ¿gذ;ñt¼Y6м¿BÚ’eµÔA¢ÄzGzƯ½^ q,›ëÛ(Z£¶·k–k6d!Â^Ý7·…3k‹‹™íCŒ8ˆa~m9UæÖCb¤œŸ¼ýf5¤ù:‡‚€ U”â}b£ƒ|Ò2+2:¡¦IDaF»Õ;¼Ë'ÎÆÅ™±›¶äóW9ÆG³éâʺ’âKµV˜&ÚfE‚É@xAqÊäô–ËϹ®h¶4H‰¼–̤9Î/\¥¢'`­mÕzIâåÕÙ+R,„1W.Uª•bßȤÑrJ…UQæ{Óýzƒç9-#UJ%¨ç 0ÏvëN R4‘€5˲UËÀ‚¬ª*B@ |¯ÛZÓBz,™Rõˆ È Ñâ‘€RÀ€Èw]Û ‚€RŸÃ˜€P†9"ä‚ÃSÀ scžç)%S ˜ïž0døBL)„ˆ~@2ænh%6ƒW 2z㸉h2Ȧl•2póùkn°@å´×þ_0ÔšÞ~k8Ög´›>ñ%ÄuêÅpª×1M.¤Tš¥çþäãŸù‚"…¼€A}R\]™&@l3 ©‚èÁãŸýMÓêbuV+ħK@H²ƒÊ•…ÀÓ‡Ì!J!•UISýÀ H%{¯ž¹4uÓˆlrí )à˜ïxJ8‚‘D<_Æ"5+<ã¢s¥¥ÑÑ!˦j8„y|À!®Þ,)*Rå¨íÔwy]ßXܸã£:›¶í!©GµÛed,{pf:6ñò»¯ö fÁCFa $°xe©S"3…·}äc9q¼Ý­…’ÑÖœ•ŠBWHijò$™©j<âiˆWÛµVE iæF…1§ºj¥¦8PàÒ‰Œ‚] :y!¬c x•ÓÌ–Y謻V¨P_7¬Žë³V·eÙ¾e;íêF<•Ð-ajû¤ßnÖT<ñü«çN|­ï£%–LgªÅ|$®Ul;#ñŒÒ‘­;.œ9 Ü{øØ¿~÷é{÷<üÎû?8tøÑ±m»›¥Â¡Ý·Ø¡šÙï}jëcÍrí_À 'bí®åtk–à" zt•â5(å²Mi‹‹i¢K±À"}­f}Ã^;<:NeX8¬8ý;¢©Ñí¯÷%’–ï¤"ߨµ*žIŠkË3gÞ¤åå†ìßuÇQ5?³PîÚè•ÈFçJ4‰F‡Ó¡Ð©¥0Ë)°ÓV{âb2—®kY]_2ùVuCŒ¤ú·l¯¯¯õmOøLÊîÈ]+\;yá¥=Ǭ/”{z4‹ò ¥k×/ ¤’ÓWϽæ žë•dyîj^pó¦ÄÓáSo_ÚsÛ-€€E¨ ÉàÀP_ ¦!A_Ó•ó—NšmOPmAåXDäb]«¥EÄd´çÂÜÙ-ãÛ^}u&J2òˆE-©?»›õP:ä®cã±ñ½óWæd=Qi•#tìîý.sÍ Ã»BÌ ~®WZ¸t-”ŠA™í‚éÙÉÑŒŠxóÅ^êIŸ?}bçMûôXÊõ;•b>•ÍN^UB!E ¯/®–× ‚â1¶é:ŽÙnb„‚˜5]ÇœØí´5„EAÉ^ˆa»Ù¨ÖëÏkºÎIªçBˆy£Y«×«ïE⎤蒬 B!dŒAßó è2Æ8„Æ£˜ã6Ç1FAÀ( P‚0Á˜C ¢>ÜD*ü¦z™Æ`€Pp›ßV7ˆ|›BÀƒ›HdÊ„7Š;›! „n2àáèÇ‹­âü³?zþW~ç =™1껢(I’l™†Þ›ð©G“(»têý}÷Œöö{¾ ãe¹Z,¨a•Pæ’€:íx4½2óöôö=J›NÉ$ƒA}ß\º~á÷_ܳ½';0 äJn²w¸Q^£˜ŠFnµråæ}¾!Æ[ºÂ IDATt0ú|]­DûS¢&õd†¯_žyä㟼çîCýóc'~¶ˆ¾ÿÑgžÿÁö{nÞ(Ψbú‡ßùöé @j !^ã@©PÌE€x\÷˜€•ôO÷‡cÆÉµ²QªÕº•ËW™Ë)XZ]^—šÝZÐѻ͹6)üè-¿ÙS|JOÊv0xüøR±Œ±Ô;0úøŽ—Ÿ{ñå…Ùn¡[®–’zbr·09¬.:ª-;.™ŸÉ—S Ó%Zz"¤áVyµ/yÇìÜÒLqåѪp¥]’›óWNo,—u]^X/|~Ͼ·ß;# @Ån­´w߀À¸xñ…Ûî¾ïîÙ¾;öó0h•æƒ ‰Œ" H0’Hʯ†{%9šÈfh@! >äx^È¿¶P‡ÍìȹÜàúRQ_©v7Ȇ"Ù¾þÕ¥™çÃñˆ“¯F'¶ÍÏ÷–ûïªÔƒžœN7D w$1!5õ29rϾtÿÈõ« CÑþáéÁ '*M žœ+ìKq&ꘕ Òó+S=Kó8Ý[¹ðÎÔî)!’:|×]WÏž·»å[]xã„a[§ ùü*uaT‘êðª*Bɲ;‘DÒqÝX"æÚ–çú”8ÉtÎó챩R(ÂCÀó|·Ýb¢¨…cë+‹ífòŒt& !0  ´l§T*9ŽK¦d-$I2–C ”Œ9FȘˆF)FˆÁæ{A¥$p]ãÀ @ŒâD@€x¡Ô'†€R†„ð†í‚ÛdÉl>G!Ú̵ßÀ=0H@›ë,@>€ùm²n„è1'ï·ÿðÏ?óé‡z2£F6ñPÑTH@¼ Ä´'û'"“îïÐMë}«+ªr<óýÀoµ•hO%_ôbˆ0‚‚ juº’,s˜«ç[J= ¼ÄžÃÇ!ä %æZùÅÈÄ$v}UÓâ‰ô©ç_Û¶{«\Úï LcFã=!PPm‰„½\Tž øp¢'` $«”„ õý®×H Ó®Ü@¢èéo}Ç×[z¤§c5$ž*¡\{­é•€ÁºA}(;&ѽS£Š–‚`»ž'Jj"’“‘¾ÁÁ™™C©¡ŽZ1:ðÂû‹”àÅK'§¤I'œÙ‘E×7œÓIliõ²Fâ©ÞÞȲ”`ScÛµû?øúsϽôŸO*}J§XèºÐ2ºÅª;,ç£"’¥§ÿýZmÕZ£©®x°±ÚÌn!NñPy¿/Ó/Éý.u½'üô+¯½øó>ýEŒH¢´µXnÇíÐx1!Ýþá;ÿæÿöÔÔÔ'>ýù{òo¿øé_9ñìnûègŸúùS&©–êÞÏþá«Éñ˜ãÒdj>&N‹…²ŠënI¼o`¢EX‹_zï=LNhLÆŠ!ÅxEÐe³^#1æ>²¬f½ùè_ìç#§œçOÿèõ%–ÎΜdv„sºžÖi4ð‘Ýé1ùÆëo¨9ÞìŠFë©“Ïß¾çá[:_1÷$‡Ïξߋzz&ðz9ïò`_¯Úý¥ûîûxåWRÃÉ?ùóoÜ2¼ýÙç^Ng‘CY2“ܶëÀ;¯Ÿä™ óK½r¯iåúJ.»t}ÙñJ[‡sµ–U-o„3 i…¥™N§Ô×;Xê²kÏ&Ãi@‚"žÀúÚzXæ\¾#rÊåÓ§¶NOD‰³/òØëzÖ"JŸè;„Ùºœ¨m´âQˆ;«ëî±c7Ï^ºlµmJºj·~½ÚŠË‚mz¡x¶äòæ;¸îIUÌ‘r'¯åF+32²tný¶ú‹¯|ý‰Oü_íÒ»û¶øî÷þkfþê}÷TÑc“»÷,Ÿ½èÈÖ¶‡N¼þ³£wq>ñK—Ï¿žèç$-$†ó‹³XdáxŠxt}e> ,Ù¶itºV·I(sÓ±: )†cê²D %V œL¦€K •FÅX¢G’T‚/ Ñ×ß(U ”0ßqÁÆ¢Hü€ùc›®kÆ¥„Æd,ð}€ 2æù¾í8ž!ÇÉŠ$ñ"âPdŒJ˜Ï¡MªƒŒRº9Ñ1ÃèYÎ&æBÆ ‚B` ß@ò¡S!„@Äè|ûyü¡Éý·nÆ#ÆÐ'€ØH(%!‘abZ j rü¶çÄ3)@ñ(å†ÂêÚÜžÃ{(ã9ȼÀ…SB £!ÉY«Ö6šµ§Þxéö‡· oŸLFlÛƒA’ã‹Kkjb®ûËkó“‡ï;ñâ×ÊíÛîT\^”¥!yèc8àV/¯VÈl«ö[y7Ô§ºÍ¹Õ × FáèžœµžÛº;ñù>¹zö¥ï~ñýc»¢ù«ÅÁÞ @¸­jvÛ}!_zéGϤsý¯¾Rzê;ýð÷_úÑ /Moœ/<”»½\ÝØ·½§Z“ ¸aÒÀÖŽïýð”«âéÛgΟ|kåÕ{§?/‡àÀÀ®rá啵ÅlÿM¤aÑÀœ×¶Ž[žŸËÄÂz¥½§¯>5<0’ɵ~ØU£ÐaÙô~áC÷Û ;ª†áT£ÙNu…Þzó`"šÔØ5l9òPÚx‹˜ýûùïæ´lrhÀ1ŒYãÜ@߈@„n£[Z/¤Àƒ®iZ)%÷òÆì§ŸU],GÈêÆlߨç>õ™Çþýï¾ýW×¾þÿ}í+LMÚ5sæ\TïzàѧþöÉ_øÒ'º¥X/P$:VK•Åëç£Éš¨Ä¨󫢬ò²!CÂ Ž³xý:ñ)e^(§ñ]§ew²™¾D:]©Wš K@Ä˺Š0‚–iÚV³Õñ|ª(Ê&@™CˆÄq/ð!ŒMæ:Œ€Hó<·kCªH0B<”ã7÷YŒQ>ðiàSJæ6;ÍÐÍ (»aR…0 ¢ŒÆ „n „0ÛÔ1rcD"”Ÿ[ŸÞ5¹sWàxójG¨ã:¢,a„B¿â,\y÷ȃmsÓ5Ö*"}iB ÄtH(¶4wedbÌ¥s¾Àñ `»SE#\@kÚµÊÌõW¿”û(s(D°UoöŽŽÔÊ€X¡ðø•3ï9º]±ÿøÉwþáïÿ̵9AEžë„ìbIˆ(«—ÖCïžz÷×ÿÇo¿úƒgv¡3‡FcáD¸ß³™Ñ1dûízuÆéi6»ˆX–‡BNÇP/®/I1¹S³ŠssÜ{\דŒB  4ð¡®]…d€£!–èË1Æü€ºM'NÛ¶0’Å®!W”ÀµŒb«c6Ç&„6Þ0Ê¢¦SÁTZ_\´¬Ö‡ÿï/]~ãl©öÇÓáÌPn4›%/0 Nµ¶Ö쉅)§6˜Ì ÇcÍtf0ªó×ó§öfú]bE"©†ûRº'$†58_øÕ/ýÉÌW~øý'?÷Åßb”ñš@ qʙ뫻¢ƒÄ'‚äîØ~§41v}÷£úÇo}÷¿üåÕ|~ûÁƒÜ³ß}åÄ{<ü‘nó³Ñ\äÊ›ï¬vÖœ–/Ť³‹Wj‹ÅˆP¡¼’Èj4’=ztœêÎêEráÒ¹zÞ—½þ¡œì´a(ݾ¼^vòvOÖ'ÑÔâ»Ë'_øWÞº{<ÉE2rd`ŒWÂá«MQ‰Ù¾Á«3†®S£·xaV]¿véýÖýçOŸøå­õŽô_X\@Tœ+”pä–GwSÂ~ë÷¾–Gan3¶m`Jä½·Ÿ{.úÈÞf'Ø>µ»Ñ¶³/ÊήÏj¡­?þ§ç¥L`t¼‘¾,Dò %wm2w­\yˆâ=÷Þú“§¿{óñ‡f÷âé7G§Ç…¨†•Pqn&™œì½ä¨àu;åå5D=¤‡cºØlš…¥¢žŽ1Ä6®åÓÓ»_}ã­HzHéåF»l¶§¤‰ÆÕâë‘k;úÆí’966Ü.µ†SÓQ‘¿v}qz`çììûêÎ]4H:Ö"©ç€ UOŒ÷UJ ÑãOŸ~MÅøìïÿìù?ÿÊŸ}â Ÿ’ýѾtír)@Ö¡›ïyù‡ÏOnŸÈmíÉë+ÉX‚çøüò²ÖTY'„Õ‹œˆuM§ŒͶ¾Õ-¯D]ÔB¢ZµÂàûÐéØíîzÊõ¢‘('JЦ8žçì¶;¶ÑżB( <—rã¶1‚€Çœïy!Ù$Oy¢ÐbHàŒ‚0c€Ã\À Àõe˜È”!È(„r¢¯ÕffP7çBþû; B°Éê»Ñ„t“©L‘Yk,æ/ ŽMI¢èyA") ÚŒŠ#D zuáÝ·Ý[/7EQì´Úz6M°|¿VXŽ¦Ò«—gËn!שÕUùPЩ‹™ó|AÐIµ*µÞLÿWžûÇ}hhËt§k39Õ°¾Õªe&Š î ¦¦þÌO?õ™‡\Y |ˆH„ú-QŠšF,3±!”IàIBˆ†5$j "„`kµËÅøÖçÄÏWç¯ÞzðVÒ–±¢0%B‘Š[Õ“zqen`xäü™SõnyJÞ>2š4×Ú!M+ã] 7:%¶&êN Œ-^¾Þ§òÌI®@Þ»øùÿçK—/—VÊׇF'[y7¬É—ϽèIq Ô¥ù ’WfŒ†}ØÚÚÆ Š’€ÉÁTÛb=}¹Õë‘Á`i1?}`‡®?óä·C¼¹sß±7_}å»ÿòW{⋪J$Þ¬·02Ü|ïËÏÿ„Çœ ©j8Lsì6¨۱ Ã$ø~XA·cÈ¡•y hÇ07 >Áˆ¦}}~¨Ùéú4€€væ–ûsfo:ÃIŠ KœÈE :]ƒ˜6c!Dó]b! ‚ãúAeŒÄñ\àÁ÷ž—$A}à×s‚$mƬ „ Àƒ›yÐM!›Od2Êe€B(ýàQûoÉ*„@Ÿ”–Vú‡‡Ç¶7 2Ê|«M‰‹àR{?(ä×B¹(DJ»Ó@ºžkyn0 @iiQQ%¯Í®/^^8uùò¹PHíÔk¼®ÏwM I²c;ñÁ§~ô]›‰÷ÞûH×tà#à5µÓ©GÒiJèµsïÊ`t9£veÛô!ÃB¾ïss` ÓLdú ÕF2•{õÔK÷?r¯Cé¡ÛŽFC1 h½Y‹ôõË3[-Ïu™êçóKûn¹ß÷|à †0 ž,`¯ëCÁÇX¨VËXÆœ¤È ŒQ×°gÏ6 kHe0ß³cÄ'JRؘ/‚Õéhª"ŠŒ—…žh¯®‡¡Ï¯äç¼jÐ?”I÷¦E=¦ÀkÔ$A¢é‰~äÐs'.Ö*Ë8.7FNì®ÔÖ&cÆ aUò…µÎz³[Ã;Ìõ1J&G‚i`i‘x—’\| Â…ß~û„Œb¬ó*áY&=âtj^ÐDLû¶æòÄòÜ™Ç?ÿÉïêá°Q«Bo?vìÙóÏܱs}ev(—‘dpëíwݲgÇжa³Á¿7s©;‡üðCŒ¤Föíg–â5›oŸ=õÌs¯]¹~Ýl„Sê­'•éëŸØ·MRz¸šIOqX’S ìkЦºLÎfæ.Ÿ?ùþ˼àÉa^Á"G›U£^)l ç?}éty5ŸŒò˜?vïá©á£‹gWú˜šè3€P)U–«ÕîÜøÔT2“;¶ïžµz5 ¡±É±|q£ÞiÏ®øç_?yøØ„ô* õJsaci÷ž¾Ùp†kðœ€Kå:ôˆ€¥XBŸ;³Šå(BÀiZC}[y¤‹¼æû]Ûf…õ¥X\ž¿2 QT¸ªAs=I³\l:ï“€º–g˜ŽÙl8‡ žÕi•;ÝF«TáM9¿‡Ë(ì4Ú©T¼Ü^ë›Úon*•DŒu‹5USÞ¹üf2^½ZžÚºß3ùþñL£^á0õ)8wú I*ÿÑ“OšNuxxx÷MûõÈðêÚ•m{v®Ï¯AÅIõfBz! üÀu×ó AÏõ\×µ Û4­À4wÀhwÌv·Þj„ÖjmÃ0I¸ž'IR«eϯä+¥B»QOI–EIÒ4Uä0£Ôó}Çr,˶lÇó<Ÿ~à;¾ç®ç:®ã8Žø ePx¾ï¾ø¥sXŒ9?+l&!6?Ÿ6‡; tšÌèær‹l„7Ú:›wDÂõj™£Á¡í¾í,¦CÝÏKïmR)#rV;?šìA<çSŽDdYm¶*.µ”Xß+Ï=«Gå‰ñɱíë% 겉Q?°› „°ëõúÚOžyêÑ=˜Ìôm.ð„êº<%º¬Õ땺™šØyî­Kz&'†"F<ÏÌCF1”𵆠µv‰P/¨ãCÓJXÓÕ¥Œ@Ú6/#$Æ™ï@Ž ˜ëÄ»Há%J‚(ÔÅìt™(ÃÝr»g,’A'PE9Öe›ØVâºåJžãi4Jþ•Koˆ!@ñ@Q5ùü+Ï í\>wEa=-qQàø#àdP1Ú?Øß—ó­ RÊ7êmà¹Rœ»é±MÆ÷¯_]4­îÆÒåF­ÛÝÈ`Ä­±Ñ‘‰þtƶš‰eG3k˦c™¶oŽ3:öÄÀ 9>â.]/ BÆ€e® ¬&¤'‚¼0¸eBöv§Å`Û{óíÏ|ïé‰-½‰Ô…™ëÐFíÊÂoÿîï?óä··ì›]5¼Ò½~˜ ’u·©F’éÄäP*Þl“ïÿç³ÿøïO¾òÜÛWfª–Õš­ºs.ñsÃiQ‹Š¼Ñ0;ÍîÒµ¥åÙååJ³mb¾mÏg>û™_û/|äOÞ߇ü‘]»Ž?ññýÂçõööôÚ[]R·ªH6ŠùúšÑj3Úâ$°û¦=¹þL­YjܵÚüb¾ÙZ-žöÕöôÄÀÕ·Î%EX+ÒÌ@_<¹ve=Œ„Û'zCÐò±€¼xÆgL¸þÁÜ… gQQEΧ­r¡^­/mœß;½gqváØÝGk-£X[Ñ5(ˆRàú­v[Šð—/ðŠtàÎÛòW q9U%„Œd¯”–ƒñ¥•Y. ãÚP±L¦uAUƒnwcc£VoÎ_YÏk½}¸ŒìÜbÕYñRÃ},°r™D­P…u=ž¹²à{Îâų{vygé'S“×çg•åòêªkY 1†ß FµbëÕg~Øí¬Èš&Ë2À‚i[X¢Éžhº··PUÐC€b„!¾A¾£„xžË( >õ}ŸÂ(õ=ß÷=IádIà0/ò"¨Ýµó…Ja£`4ë¾ka Q”eE …Bš&`BDq/¼,ɲ(‰/I"ÇqbôAp”ç8!ƘBÔó|ßóHà30Ƽ ÌˆÑ æ:ä692 @!£›ù,øßø+ ØÔRÜX+ÃÍ(hu=ß®•§¶m#7Ú.Cäû.N¤Û­v,E¶í9íX8x6 |QÀ€@”äZ£nVftj}yq¹tñÁ'þã%—Â\_lÒµíÂZ&×_é4¹¯}ù?tÇÝ÷Ýg™nΪ$¨–âÙm{ï½õ‘Ûî´ÛÝ·ß}ácŸý¤ç9X1¡n@æ‰ïKŠÖn–úz’³§ÞŸ>¼›2Â(e€AJ–¯ÏEã<ñ äUPß;{⳿þ%ßµ)! PgÓGÒÁn½®f±íѮ٠ë(¦†(¡Ç£ÜÀ¤H<=¦RÓga !ò\‡2’Iõ òk[¦_c—EÄå&§š¦o˶ÄCJ¸/…8S¤ÌnÔ•j®G‰ Þõ•9AIJʺz:—äC;öo\¬UZ—“±œš!óËKÙ$ï2ÒF8­Õ®,ÅöìÄ€0E÷!á¥hÝqÓv%Ó©‡>ôàÉ·Þ¿|ùâÎÇ8TUI§’¡¶Ù IIʈ 0L$ß|þ¥©}ú_?Œ§Kå¥þÐØç~ýóûÍo¿ãÞÿço½ðÊ+Œâ°výÔÆ¹—Ù±çÀŽÇvQQÈϬRy±·ßù¾]5€©¾·~ÒÚ’(2\´k˜;²ÌwÅÞ0$Ô"¬ÛÒq¾ÓaÍ ¼tYK¯7›Ñ‰>EÒCóõv_?|g¹äV[é>UïMÜþÐAMMæg®X$¨ 퉖Ì:µÊR(EMÎqøë…Õ½ñ‘Ã=öÔµ«yËñxæ>rç½/Ÿ30¶'/f8¿5×V5w{óö©/zžezÀm:¡P÷42Ù¿ýìzzT]Ü,Ïu|ÊŒ$G®”âúœÙJ ŒìÖÔâêi‚1… ÛhGUÙltþƒ|ð߈z2?HÆUI¿püDX“{÷m.md† €S8èYûãpÇñÏ|Ÿ±AÀ!ô*IX‰PU“Ä"AHͶÓ0]ÈCÆhœ"ÊŠ¡a „9@®°ª ‘% ØP%D±àa0ÊrÆ‚~J9ã, ñÀ I"¨ÇGFˆsp¯ýkÚ³Þ, à«ß⿎‚w«:Yõj$BvîÙ!œC$AØZßÐÒ1 P,ÃÛµæÖòUA–!ÆcQ cÀnk²Ä|ÏuÙܰè‚úý‡>õIQ‹Î/^yúg§Ói@)"Bº¯ÁPȹwž{ñõ7>ðŠ¢ÞSNBEA®]ŸWãI@”s?{~h,ë–½ ×/LïÜ18>wæ”ÑöÒš¤ ’ª»jTEAÀ¾ó/÷Ñƶ]ÎY/-+IRèz}“C!õ" ŠnéÊZ&Ÿîý5! B4…¨Hˆ@yǬ)ÙÊEÆ¢F”H‚#! €5ƵdB–³¦×Ù €‡=Î¥rC¬E*­Î’Zµßb•ÍåÀ·•ãCé’¡5›•ªÓt)§€å¦ú3‘©‹'Î㘾¹´Ü)–Ê-HÔù‹—‰ |Û !•¢ê°?7¼xþâöÚy·íP‹K1’ Óí®u¯$ò9³Òe¬9sמèîìììËi…”2‰¦wÀ@h®—­NÙñ:|üC}ý•ç¦wäÔÛu‹–Û¼óð‡š›õ‰‰±ÉüP^m6ê­ »{tß~üõßüܹ·¿õÏÿý¿þÍ?ã±=ñü?ï‰ä¨–Í ¢:6å„–L+¡È³ÑÜèÌÈÝwÝuë·Þ÷Ð7<¶slo©éInà6ô? IDATªÕF­Üé¬ll¶Û+[Ëõ­­+«këKE‘ÙUÇNÉüŸŸûÑWÿçÏO}õÏ.U_ß÷àíî¹z|ûµ‹'Öj+ýZ~xhÜ„h­²1>5P+™_ÿÏßýþ“ßöW¿È¦ä$ÍeÃL£²’ûžxñ_²ù1óœ $AÎj<+^??<±Kò—l›ù½¾xÞ#XÖ$„Ïʤòí ëÄ˯þôÅçLµ#'¤¶+  –¶+„F,6šÊJrfs}ÝòLAÑm.r7Úîí7ï LÚêÊ{÷ïp·dŸZ‚öE 096eùÝ„¦#‚¯¯TwLª¶Ë s5‘žr±ÝiV2…nö'BÀî¾÷C¢š¼ríÚ®Û§ºK%š¦ÁcQÄ¢(rWüåwßÜ:70”E‘h*•·ni}>ßß—ëfÒ…Ñq Á@À…õn[‰ ?À@BJ)çŒ3ÕPÃPà€%’1P$ªÈ’èz> üJËÚ(×*åRèYº"G"1US#Ѩ®(€3, ²(ÑaŒu]—$YYUMÕ4M7"šªG #1 MÃDŒRF9œrÀüõÜ©÷¾C@'P¯êÌßõÑ÷ܽS ô §½†4ç@Úñ`hêÑ,†˜q„€‡a˜ì!p_“Îõýx~„H2‡«£P¬ÄbœFýh,‹1¼~jnððÔèðÀ·Ä úžûïP”w¼f·O¦ogSño½òòŸþéo Î b€)3ˆ°×iMÔ#qÔ¡¬OÛµ{ÿöškYÓ;oÞ¼¾Q˜ÈvÛ®‘;FQ×ÍjKÍENÿâ­CïDrïF"\\.bDê뚊ƴFpöÜ‹{nÛ† èyžmšŠ‚Ä ó8¹y¿Ë ï:ÕJ%SÈq„ DòÊÖ’*z.nvºša,¬-OÈC•u?BÇÙÕè6©J+¢’ªß´@6¸ct±rE •X$m7:HkO ÈFÒ@ú&.î”GË•Õ 'Æö>Ð^©¹†D9‘ÎÄûÇx(X¦çZã5Øî¦¤ï°Z­–î˜< 7`­Ø­/­ô&ãòðƒÇ~ðߺù¶;‡'v1΂ØP ·Pœ[ð¢þÒÊúÔÎ]ù‘ñÑûþõgÏ=ðñ¼óÊ듇>~ýÂù›öϼ÷öž}þKø'åêÚŸü×"µ¶W¾ÿÇË¥yo ~Û-;ËëÝȘ<ùÌ\®ßÐúãwìRôØGR ßr ªvЩUìŽiÊ=UŽ&÷ÆG×êy¢veéò²¨t,7a§%ËØF>òÊ]2%Nº-ÿ/ÿè‹·?òðÉ×^¼é®áz=úâcÏF’ÝÁ¾|©Y’Ò°R²ÖÉÖí9¨KçÞY™a«Þ&(?˜¹²uf­qMõó„F¢9iqýšÄÙ…¥¥Öƒ¸GÃñŸ¿óֱߨgvÇ9e# ©x¢=”Û#j*«7¬j«Ë’ÄÆ†E~âÕWDwîš¹rårs«ãÓ[öðÔ~x‚$De-4Ù¹_צÒF’îzß;—+Ь¶6…¥­ÒGgÖÚ‹j¡•«õÅ¢Sƒg–öîM^ZªVÍW^øQ,5­ð–äZ—ßX;88¼4´Ðk¯r}áÔÉ]ÇŽfâéÓóo¦©êz5ŸnÃ'TzéÉ' »Þ'î™Vâjis°m]‹dúr4 »Ý$x§Ýâœc€3Ä¥ "Yï(àœ1Ìt\ ]Š^W8öx<¢Ä ÃX¥Ñ¤r}„#<Ræ>‘E"Š1QÐ#5÷lO”%Æ`”1Î8çŒ2Æ€±€RÀ( á^Ί3Æ9à€3zŽTÀ9‡ð]Ç30â=†LoŒÜ3RpÈ9e=Á*„ •k×¹‚¢pnpl =p£š,a„Çu“5• ¸.!(¦Æ)†D;¥j·Ó‘%Ñ_³f^¾çÁ{>uÜ ¿3k¨ã<äAàiªÕ䙷Μ{çâÌ-w®†=!@sQS2“;1L»{äèáíb£ÞrÏ_[ÎäCÁÔÓ¶ié¬`ói«¶ÓŒ—^ú—?ø½k¶=¯k3Î8ãXÀR#;&—«k’€)åÁ“§¯ßýÞB( M׎¤S 0"J¢X6E0†*#AÑe†s³Ñ¦6otËõV°{f ‘h¯ÄÔµZ©Á¾Êܵ„ñZNˆºÙüäÊÜa"óCà9V©T¬ß9¾´Q/‰ýÔõRU ´ã8Q%EööÅ7!ŒE3šõšY’G’¾°QŽEb‰BNÒ“âÑé~'ìa !)ŸÎ;®Ë}Ø ºCé³çN·[pëÒ’&zr˜œ›½ŠhÀo(¿¡‹Æ³)€ý\4Û^]B˜ß¹÷ýÞÕn_fvvq{»¡ØpuóâG>ú›×—×\7°º^§Z}ûW?þƒû0p§oÞŸ—Òz<9:‘:¸ÛsÈ{ÞtxdÌ©ˆç_x}cåøÏ¾õ½Çû«Ïüîüê{ÿP¬_kÖJÐ7;öOŸ|åÙùêuÖ.ãÖÚÄpr8Ÿˆ÷ÇrÊh¡<>  îKèPT;,7ÌNýè¾< =Woð®þÁ»µ6ÍÚV(s:>Ö·9¿yËþé(‹DçT–·}dÏîן{Iƒ40j•ÕáÁ¼îeÛ5Ë|à9ÑTâÂ¥Ó‡‡'®žÙJhFȨè5 GfŸ>õÆÄž½®”Ö¶TC¥>0Hbåì–0ª_XAD:tà¦J¥ÐRie£rp¦ÿâ…‹V·Ûê-ÔÉàÙ+gÓt¢\º|ñì‹XÖ¬Z*Gû³¹¦|+ÜYÈùØ8ט™ÚÙ ÍÑÝùk›—š[^_!C䄯e]]*.Lí¹÷ǯ|¯ÜZ{õí_%ò†aýä»tï>º¸¶Ù2»VÇa”­(‘—~òôüåçéxßèÐØ¾E·Öçc¹ ùÈähßÈh*“1"q ELˆ¦+ñDT’eL„Æc‚ˆû>lµšŽ8¶ï8>H‘…hÔÐ-Ñ%Iv]Úî˜f§å¹.@0šˆ§ò}Ã##¹\V "e¡$IR°@$YVEQ5U×dMUTUQUY–DQ C,`A$ážP°GßãôÞ­=SDèÆtêÝyz¯oƒÞý¹ÇuŒ#Î D"›W2ãy=>Ä€=}}ï(䀅!‚!}ßu-IU\Û†,@vÍv,‘tº6VåX"-aåwNÜüÀØÒë«O|÷ëóg^ƒ:Ýg–¤Äc®ë\¾ôÖÿõ…‡2™‡2ÖKчœ›ÛÅù…ó.´Ì­À.·V†ó2Ĺ|!è f»ÃB×±"Š¡Ï"‰ô[¯¿ÊŬ "ßö‹ëë‚$9E¥ÒUYÏŒ‹(ºv·^„];ËÀAà•›e:"Áª "Hµ*DH–d‰¢júábm37Þgs?MÆ3ù¨”Ñ$BP†áòâjT;Hˆg<×× ƒ@Á†–ˆ¹  ÉhZ2Øìk¯Õ¼õlA1vïŸ.m6æOžòJºÀ»µfgsÃhȹ[(ŒMÍÈlÛÆH1K´†BN®^oSärâU¶k‰|Nã¹k{:uü¸ªiõÍù;ŽÞôƒÇï66F!ç@ÃØ@¾Ûmõ d˜åtvzO~ß3Ï>õâ~ù·ÿé¿16=yæËŠÞ÷¾;_<ñ2•âßýËo}ó;ßÖRþðÍF,{øèaER­šÙloW+Íòâ¶E[XJpî[vCˆìß¿ûÏþøöìÞS¬ºzPi¶]>ú·}àÑONòwÛÕú¨gjªšQıḋԀzÑHB*ГÑèˆÂ5»wîùPÿP_ÿô‘‰¾é°kRŒ³D ×ÕEÏñ6¶bé„ I8¿±PµZžMU‚}uÝV6­¹ Q,PÃTô……Á¡“Ççß{ßM‡"‰ wµ­âåáÑXR™ôæË¯:Ü—E"%£\•±¥AË®èB‚\YÚª×KªHV+î‘cï]š¿8qp¬ÙPºmkxêf¿ˆ¿wgAÜU¶íýýœ±\nÇB­NP„¶Ã©›n"X‘‡²¦¸í ¢É0†…ºQ(^€ÛÖµí«w;l-eF/Ÿ¹õæ‡â†¼UÛRó‰¹ýOü¯?œþŸþ‰ &]/ìÍy|ŸrôµŸ=wúä/µóƒ#Go¿7¡V–çµHdsm#žŒd†D"a„D‰(ФÆX:iD£²¬ „à’HÀJa»Û 9E`‚bº1 YQ ]†¸Ýj;fdzº&F<‘ÈdcñT<žeM%‰ˆ$IVERQ’eQ%EEI’Q"c &‹bΣŒÓž¯ž…aÈãŒÀgô×;Cþÿã`õî]ð_ûS9çÔ †vG“~ãQÙ£“ó}êØ½ç!t­dTÕTAÈ-ÇÜvƒx"ú~È9‘eQ–¶–Ö//>;>r8¤aú{n¹W$ízsk©QÆ!B`þò¥z©<~à48‚"ˆDÉ¢ròíg›ÕbJ˯®\NiÑz¥rhÿ¡€v…¨f†Ýd2Ñ-o@,v7ì¶ #c¿|ú¥Ï~þ3Žé†®cZ“f©<86mÕkÕRa´<·Ô·sI A\+Õ@a`uÚ-?p9a,Êzqcµ’ëïã`Ž:í6 j³Ô0]J…LKhFB†´RiŒêÍÊ@Rk”7,0n¥3#óún·U#£ãcž©ÆÖæ6,©+I‚*i!*«Åd>;ÞŸvýîÈÐ }æ´§5R˜¹ðÎl«ÙÔ0S t]Çr;@‚#ÃÓ"k4+ME‘Ó]ï— $ꪮ3øÚëÇjž;7?}x¼0ñ⯞!°^y",‰Ù†H¢0²²¾Æ8ß1y tm&ÃÉþ·®œÚsˉ7_û‰?þâoçg I(]_ÞžŸ³ÍFÝlÈzÀ$¢’ÌÈ£ûw–‹GÒËîÊÙåÕÆJË ËëÕíZ­Óp»®ÝØ*÷O qcdb"=2qì–;†f&G÷ýì#ŸüÔW>ùè§ÿè3ŸýH<—ÝX®`/€?}öÔÂÉ“+k—ß:yùÙ“—¯ŸÙìlî¹ûÖ Îèz˜J+q±oqu‹cDI"cfÇDqqýú¥%u·Ë¥µ­Åx¼ÿ¿õ‘Œ%(Ó7Iw4 Ô“FSϬU0à‘œŽCa·æÏž;ŸŒèßP“ÁÃï›Ü=Üì»'¼ÐÙÚ\'ˆtïØ¡™°-¦G¢Š±¡W‹+QŠ6Ö7o>vŒ×¨ê)©sOK}þúl·Ý8òìöÉsomžD9YbëkóE¸ºM$TÃ0 ”3#V,‘O«™­ÊÖ§þÍï·J͵Õë·ÜºwÿÍ÷>û̯šµk>ôéd¤Ð!H=BF}ñÍ^}ã…g¥&ï¾=÷MÓjšf½¶]²½n$®er©t¶_’ôx"Ö×—ÅâŠ*E  B>“ˆÅ´L"‹èš"ꊠjjÔÐC$ç€H7TŒ…n§S¯Õ›µ* I$ªfhŠ¦ÊŠ‰ˆ‚À $ ‚@0Á@Â!#Œp€9œrøaH9i ) êû4¤½Q:ïòzl>Œñ»ô™ÞWÎ{k ç!Þ3¯rÝX“D¢©I„Qu~-> ‘Ì…”˱ˆ¨I~@ΧB¤I:òÄ3Ç_xøÓ¿Ô\ªµýnà…ù¡ÑJ+žMcAg”qê?ýJ_ÿpÿ®ž»§òâ€c„ê7;šêÛ¹rü\ÿXváím5®Nì˜ Lîs$Gc¸iQIhVš´ˆzîü]A#3'ÅòÒÄÌ4ç´ÝÞNÆÓ ê@’ñ;›jNÝ\™›Þ½CQ€s‡„)1 ì¸nRtUsCC”!£–Û"‚΀ˆ`àR¿ohÈw\c(xn"6Ø\ß´j˜ÝL*ëÓpay).¬®l:UpµòúþCGÛVȺKà~à<\ß,y Ô%°½¹nqè*„W Ï9ª+¨\®Öí®bˆˆˆ²‚//¾! Cb\@D@(tÏ1IÄ YÇqêPäû¡ÄpˆÇ§§G‡‡`7kaivzÇÎo~ã±?ú{ B 8ˆ1†¡À“S‰x¥kvê±xvïž›gÏÍ~ü³þ·>÷ÜK§žúÞ¢ Û£;vÍ-óIõÍKçî?öìwþuxwº¿0´Q^Ž¥”j—:TŠÇæz‚Ð/dòVæó“ù„æ8ÙÃà »Ã9SñÌêÊZ»^jûÅl¡ÛíX¡ùÌÓ'à*uA^-õGâMäîˆÜ\¶cÂéñ´’Þk6%ß©Ÿ»¸l•à±#…}GwGï‹E䈯t‹+—ë—yPm˜‹Q1+JV<«Ï/ ûwîzãì¢)Š–UŒÈ¡÷ßrÿ}÷<ûä³gV.…’qÛ±£†š(n_ir/0$)`¬m¬OÜ‘[ºvý¦cïqù‰/|ìNìšÄœ@ן~áG‚Ä ãƒj£^ië’¾Ù)~íÿýæÅ·_õE$%ôÖ½öæÒJgQ$ˆ'N¿­ŽÐd|Çö¶©Ä¢ ˆÃ6仦ö-\¾Ri¶D>Ðõ¶ôˆ¼zæ2ϵ‡“7UÚ£nÿx®eµ‡Xà$“Ñ'þéîä7?ø±Ï=óÌwËíòØØÐò_:w>7Ù=xäð©×_si#2 ¡°veÑõº·¿çþ\af`×L¦•s¬ÐìT_Þõºélˆ2à°So)M‰F!°E"!s¹lBIU(£² BDdEDD@! 9c½¢€‚€GÝ–i;݂ӱ„!£!Œ‡A@µ-×±8—€¾çCÎ ê5h(œ!à#Ô+ûáwË6½£‰Œ ºa”@èF1ÎnäÞ½Oõ„ТöܘÁsdœýú ç\$qê›6ǘ *àˆQ^oÔhàqÎQ B_EE’#‘è[OýÄ›±H0àSk­º>Ü×_Ú,êÃH¦8 §³§ÏûÊ­÷Þ0æ”ö6œ1ˆ±Ó4ƒn;•¶ª-‰Ç7JsÇŽÜj»)d¡úúB$ÝO¨5^}â™ûü˜( ÊRD,I ßo3îËVb1AÒr}…òZ ø,šÊ ©`Gã 9•$ù£c BÌ\Z*®ï;¸ËÃ0 ªõí\ÿàæÆJ.;@¦Kºjˆ¥r'“àŒµ«•z«Õ7<><4”Šd“åÆ¦ÍŽ•ÈÅÛV½ëYXDU½~æxD5pÞÚ^—`¸½Vó)W5íOžÚ™§¾¦©q„%×¶¡Be„~‡H>BRÉrh$3ªgù”…!fª¯hqÍHÑlaßÔÞˆ:¸çèÑl²|bïþÌ‘'úM{PGŒF „ì‹fK+× An¹ùÚìœë’ßÿƒ/çoþvï‘C?ûÞ“ï¿ç^«Q™:xéâüßÿ·¿ku_xõÌñ—_´íF»]Ùn6ÄÀ¹²tidzljïÃȘ^ت֩YŸ}ã6O½<·pöÜüõ‹ÅbQÑž}»g&§† £‰Xlthh¬¿M&ÒyâÊvg=tùÚÊfh™‚ãߪ·- ÂûwÅf&G®ëÖp#‚BãÚõe.ˆåú:ÅÀæªÀM+Gn½Õ4ë_ýÏöå¯üÕç?Þyä¶'Ÿ~þõgOŒíí¯vJ±¸¾¶:G¢¸åøÕkK‚”;¥â•ÂÈôåÓ×ÔäP:—;ýò¹jí²Ïøvè:6F¨µQj5¼£wÜÙnÛÅò*V¬¸ï,ÌU.V‹¥Këׯž;¸çÀìùÕþ¸Mÿýw¿ª‰¹kçg;VÈ!c l´?ë5º¯¿õjfrÊ]o¸V#;¼[O$µtTÀ ‚–Ûˆ¤t³áŒŒMЀ¶í2uüŸ>öcÓoßräc—Ž_>?{*a(HÒOœ-uK“»gÂ@(¥Œ2ι€Iu£öæË¿ÚޚǀJ¢”ÊgyÈ¢ -Ïr™å’Ã+ ««ë+õj¹ÛjhšbMS¸!€ˆBœs a„a:AرlÓ´lÛêvMÇq1ç4 Ûm«ZªÔk•F­Új5\×v=×4-«ÓqÇìvÛ­V«Ùh·–ÙulÓv]ÏõÂÀ§aRR~!€"!¤„”ñöh¡äF¤½—¶êZèFèªGV¾ñýýboˆ(õù¯‹Òbˆc’¦Ïž81uhÑë´‘D‚96à 1ŒLËWdUÕV¯Îñ¼òþÝŸ m +Jd¬p$Çž—"ª(à€ œ<õ³<8•íÅEDŒsŒc:µZ=ÛŸ§¾<{áÌm÷Üzöä«ç—O?<ñ™òfKQ% süd&]!îöÜ¢ÓYDÊŽŒˆDܪ Ãã¡ï‹Dܪ–’‰~­D¥, (`áVua+ψÂÐ EE RUu ŒnlZ!m{Ý{öN#Š<Ë2b1H²´Ëã‘Xw³ÎÕ‘˜®Û­òDa ¢¡¨@ ò;†"Ùœuö< ÅvyÊš–NÈZfus# ª(í²úôì=·[l¯¯­W¦ÙU\«]Ý>›M p¡è±®¡ËYðš¦Õfœù–JKµâ°0Ðì¬I,IZ-µ;®ï@ñi5%±![Ð"1-iH,FüìŸzþ<ô Ò’à]à ¨Bà‰uQýÈŸ~òÉÇ¿üþŸ÷ÅOÈÊ©fwÕˆ$_zíïÏ™?ûÚG?ö›×¯V2ˆ#Æ2c¼ÞŠSh‡ëÿóËæòYÒívĸŒE"‹^M)Jûn=<Ø7µµ¹ l qåâ²–!¶É⺶¾½Ìd@hø‘Pirä`*AQUÇ÷fG‡›•Jãªý³?å²øàüð£¬Îk‹[/­Ÿ¾vú’çWõJ’†>†€ú–¥ùVÑH)DÁ»÷$59òãg8¿2çÖ;Tç}ÑÌÕ•ëùdª0¹Ãl†é¬z­ª&•˜ X»Í3}jD%Ýʨªa(z$ºo×#ªhlš¸¹FH-U“²Ùì≫Vm›Å­É™C¶ÕI¬[4ó»å…ù•ÝS'~yê¡ü­WžÛ÷‘ù§Š›ÆÉ\vgÅnÕLÛé8»>t¯–‰‹Õ½»gi¡¹í(l¯®§5åÍ Wg$}Ënî|ÏÒÛ—ÞóèÂâõî6“#4t»Oýð;L0DF‰OoŸÃÔ£-ÔΉ"¢% ˆ!‚!eàúZó•ŸþĈ%ˆ(/ éÚÅ Š(Ó&/Ú‹œ…"A@ǶU÷L§ã¹®ë-7à”2& äœsXÀ<ǵb Ãc@ßö©¦ÊÕfÛræœs@°Ý1„”†"F®¶- ‰E1ˆ `Œ)ãaȇ(  ðKBÈ!†RÊ áœrŽçäד«x{m Àz×¢s¢ ½™À‡¼w%ìA—¢éo¾ø’‘ƒ²šî¶:”Q]•Ó5 ÒªÔ CAH*/o•—®HšH±Ðnó‰¤Ûj–[£c»1ìÁoÆÂk/>óòË'òìOÀ4ô{Umv—WWFFÇDU{û—v¹Å·Ýååâý÷ÝÝiT‰¬™ÝfÃ*SK×»]‚I$•<}êÂÌôHDÓ:݈(ˆœQßôh׉ƳƾiÎõC éj©*Ær‘H§œ‘~ aŠn‡;&–“Êœ1†¸Xãã#ƒªžòªv¡ÏiÕ ƒöv71”B«i»±T0àÜëZƒ“C,p°@Sù™Œ,‰Ø×O]*í>”±ëìߪ”óù•ÁÑ¡Ñö ŠIš¢•×–úó…þ±ˆY”lçL>ÁÎKjÂu==á­P‰)XŽ•+n»­¨H$NkP ¢¹´SR0²æ·;#Ó©¡äntS$²Ê›{rCª&Ý#|üÏÿâþË×þí±ü!0€êë•ÊðæParÿ~ôÔã­¥ÅG?ùÙ'žzîc<üØ·ŸøÒo}îþç…/ýßüc±ö¾»>5,Ÿ»ðÕù«Í-00EcC{îØyP«ÍoªÕ‹Í ÙÛôÁûn;|þÔ÷íùð?}ûo¦vì-—ljoÎ@è/»€ñø`¼¯±]]k7d Qàc˜ŒQYÈdYL LU³%ê¡Ó}æù«­rãž{ˆDì8-'¢ÇµH4siñéN7tpý÷ŽÝ2ûôŠÒtÜWß \oE–Ó¢Ì3Ã¥K›w¸å{ç¿§˜Gd%æø­·MY$¡ãš•­0Ô6L¶7W®'ØôÔ­{ïÊ© ¸?›‘f­.GñúÉåû?õ¾¹Õ"vì䀶¾j*2,çSrÍŽ)Ä%I¡_í „}ê‹ "šÙ?ËM E ‰cQ`’t:¦gÆYH‹+‹;ý/“¿ IDATwîœ_YÐ ÏuÏk¶ìV«x^@™( Á1I’  ú~!„Øu}Çó ²*y]rfD5Çñ|ŸÀƒ À ‹žëSŽ‚†>u,!.È’€Bß¿›ó„€ù”q‚9Ƥװ i„ 3rŽ ½£ ÞÀøÝø”EðÆí©í W8—b„9âœßÀ xã+Ù±Ôðà®Àó ¡åQ“hcx¾.‰@d,¸vm³¶ññO|†S fã­Z%tÛc“Óöú6&:âÏŸxþ™W~OæcÆÀx¡g¶¦g&AH–¯ŸÛu`¿!+ׯÅ3¹¡¾¨éøJÎ:Ÿß»µÛœö*!õ¢)q­±pÇ{0–U¹X6ÍJª?ªª ƒˆR.J¤Tm¯\;÷ÐÃqàˆàòJIÖ‘Ç©.ªqBðÚ•‹éñ©¹ ×ì˜ÔÞØ1OGƒK›k}¹Q‡¢$°¥'âš’@ˆÆÖ¯žŸÚµ×÷BHH¹ØRå‡>ÎÄÄnØM »©äo­-v¸ð‰÷ÝïwAõLмþö³ï¼oùòå¸ Œ„¾÷¦÷]]¸n—·&gv,/­ÂA#ÕölTÛXY^lŽõ×7«‘aÍ ¬¸¤–Ùi»ÛnUrÐ`fÇÚÊ’€™¢g“ÙHHÜÒr»Ö†õÕÙ}ôKÿÓ}³³÷íß„1xC„Ë9…÷ݽº97T?þÿáßýî§¾ñý§ì±°¹56>ÙrœìäµÕµ‡úÂ['~òÌÂñ—žã44&£3#wí<íϘeI[4TAI`¬,_´èÜÜr˜tѾû9NìÚÏ_ Ó ºV#¨lû$"ø¢4”J‘~Ýô( ci£Qä…~Fº­Œdæ®ãa={ê<³£Q]°xä`vסÁ…m'•+\¨ίæeNI³R²w„~½¸À`ÿÁ ˆe”€û ¦ÄèÄíw[ÝÍÕå¹XJVõôð¾;VO¾“ÑFZ岬+QCf6Z.ÂbÇlÈL[ÛXŸšBçäé5Ǧµï8ò*ÀÍZõ‘éÏ™µîøÐ>5šÆØ(·™ B’‘Ó•ùÜÎD»åLî¾¥S{Ç ®0$(8[žéfC&à: ˜9 d œÒ…»žÌN5­.ȪVCÛâ´áAzŽm;³^ÜV5-tÜNµ†âPKA6› ”µ-;d¼Ó1EG"QQTUñ9ò§ÕîÈΤc#II˜ D ‚Ð0$ˆ…09gœËu0†‚ ÷ÒD@! =ÏcÈ%™Bp€P<Çñ!PaŒ9 aˆyˆ‚Á€“Þçê¯GQ`Àù 3Dï¶Œ|·†Ä9`¢Þ醧"dUÚ¾æ ÞiA‚C\UÑ8§ˆfSeN·‘ýGî1Ì%n`/ˆÇK+Û±tRQ4¡¦i¿ûûŸ{à¡÷ºvï7RÎ(ÁÒ…^ÞõÁÃ’iU·r…œ GdT.ϤÆ'm_ÇŒäF“q"FÆ'L³#¨Š_«Ÿ8m¦#ƒÃ}ãïz«{S(&bÄ¡Æ@·[-dyú€aÆeÆ=°²]Þw`¬´²šÝ¹°ÐwÝÜP‹ê닯þÁï<êv=×kÄ#ÃNÛÝá·]- ;ô­n$•Dr8ºØàÌò€:¶ŸêŸÊßYY+ûæ6¤#ÞÚzßG>ݵ7§Ó\)ŽÜgv,ŠñüÌÓÿ¤RlÝÿáß>÷⋅ɬ‘Qˆ$â{ß>ëäcýí›ÓS#¶ãou[K2VÌ ­Î@_ªÕéDâýŽ·øB¿’ ;m{²Î›« Ü-ÓR•H:á…Š¢Ï,Ï]üò—¿òø_ÿ·ýßú×G‡LÏcÆÎsÀy:“ŸÜ÷³Ÿÿëß|äÛ?zò tî̵߸ÿö¿ûö·þýW¾ö‡ŸýŠXõnÿPßäÄQÏAkZk«Û®i*5/8õM”ªÝŽvi#l½y~ûæa9g« 1'äôšÊRÑé[û±_j†L°¤’P’•¤šSÛ³µèp*3&Ô¶„hŸ™Ø‘¿rüÚFju×¾›.½z$€ÓÇ&F9Rßûž»/Ÿ>Ik­ûî½yîÜ‹Õz7•*Õ¦³Mn~ôØÏþõõ3³—3)Ý¡2‚‰T¼o¢C.uÖ‡SÃ1=¾²°¹¶qÕH)GÞò­oõæ{ÿlmé·~äa³-ÔŒÔëÏü|ê–ÔxÿËs׸e }ñrm»í³˜AÜ®º|e]‰1”'"Z,¯(²Ô—šø§'~xËŽìêvmf×Mf»áZ*3'††2ã‰ÑÕÕš.B"ªDqqk QôÖ;¿,àÂ@!)–áá×ï°†xeã܇üžcjºS°¶q==6D¸xTEß6óý#­V +Ô÷i«Ü¹´øV_ÆÐ45d"ăâÛ®ï®M%‹M• ™½týÊêâªé™œQHà‰”Ѳ!ªc„=7ènTH©vkiþbµb¨#)·×»z>å4Ú‰h¬Õ(™vCðeb@lûâñ™ÿòÍRƒ2DmÞO./''£ª(ßûÀû¿¦$”¨œ«Z¾aD\“iX®lïÛ=³²q©mî2a}Ôq›KGŽ‹¥ {3F.½ëž½o^?]·¹BA‹'dCÙ^ß0¦â1K]`mE/(’Tm]õb¬ãÆú†aI a£SE$hn•+»Fnù‹ÿþµÿñWßüFçÍžxsÿÑÛz—ÜÐa¤F¢œ3 à÷ÿè+¿û™/üõcßÙyòíZ³$¤ô‹œ¹úÒ³Ï<ó±#ïKö窰XªµJ-ÛÚŠÑ)-à‚š&‚Š<µk4¡æWŠ×îý`Æ7MQÓDNÒWÌnë›ë÷Þ{Û@¿Ô´ ÑäHŸ×æo%ŒÔæZÉ ­vy[Ð9Æ‘ÿô—Ÿ¯Y^ykuë…b¤ßJʃgÏžÕb¯¾xQ2k•*ÏÖ30 ‡"¤fäOLï»rjÙ$âáá]%g@P'§e·Ì¹hNëXp|pÐ\5#²èRåÊ™å©=c”AEÊ%ŒmZ€Òã¡ëG{ÅÍðÐíº³h566JŸüÿ9{öx©´Wép:¤q9™3\Ç^ÙÚú÷½\b2KÈýº´¾}¹zôî]u“oñVÉìø–}øî#1~ø½ÇvL;ú'ÍFÓô[uôe‡6—/V‚šbÀS.…“£;+Ë›Ëíb²?C&{Kù‚ÄdÍ.·m§k1Å/Ö82=³“Ô>nµkÕÛzR0«&u«Ñ¨¢%㪑d!‘É@$¸ž5 €EÊ݈-ž½Šf4™UÓ¥TnKºguK kBA š¡‰>€¥F¥XË´\EF’ª$3y"«¾ëZ]«¶R7}‹³PQ4Q®ewmß6]Y‘E‘0a4 ¬PUdß"˜Ž1†@Î<"ˆˆÀ¸$ŘÈ8 @ˆ³{½p~#WÚkDsÀzÿÇ€Æ9B€Ä¨²]Ö£xhx§<’Šu)’eÌB¦é1ǵDPÌN‹‚eYñáaªî‡w¸ŠâFŒqäSŠ1Qdò÷ùÍ¿øÛ?ó‘9rÊ¥XËŠó—wß³gtz:5Rª¸rykQ-ôçô˜Ón‘Bhwa(`†BÎ:Õ b´Öj¶+>øPŠê9‰¬š¥’žSg/¾™3Fò¹øüüÊÌd_z@ RîXÝ|¦ïÒù7Go:Ì‚Àì¶C‘EeýÜ©ñ#HTƲ2!LRs„žÈç¼v£Þªúû%98N«ÑuÀfÍz #àG̾‘ÃÍFl´OÇQ(yõÒ†×5)á{[XDÌE‰Më¿¥YÞþþÿ~ìóÆo­/o ¥Ü¢eÚåüøØÇîýb×.ŒŽ¼vòœ|Êq"–„òŸþô+_ûª”“£Õ´ç¸ úLˆà˜Tš¯¨Ö»fÉ®&”T.W8vûîûs§_›mT6îºõƒ?zò{öhZ”Ý0}Î9åÌ2mp9¢ñü§?õ¥oþ¯ècýâÙço»ãŽSoŸþð—~ókùïÇÆ÷>ô‰¼uö î”·+fœ SÙÜÀh’2$À}‡†Zukîâ¥ý7Ɇo·»ÝVuõ¶mgs¹óg®AîÌ­¯ nt;ÔËЫ¯èÚ`t°ë¯vf»ÝéVVz³ÎZÍåç7;ä®c9rhr-º¢ÇÉüt@ÁäM U2԰ײI‚xE©Õ½Ð‚É¥“K|xYŠÝ]¯.ù¤« b¥Ù¨­mx^»á07 ûo;pî™ó×V¯ŽÜ1¾ð«ó{>9}ü¥+##C C)®˜M·cNݧÜÚÞ¬3H¡À*CÃ3tB¹¶¶±.ÊšçÔvîÜÕÞ4•|B Ñ“^ëK§eŒ‹›¥#÷õ‹–¨ÕÕr‰n!1ZÐSq-Zöë£Ã;å¨T^^Jä i ‰x«’_£µî–’JÔçû³~›ð„”+ä^õâÈ®¾›o~ßê‰K]Ì ÅÀ>Ðú£“mÚñ]_Ó%)®R¤OìÜ¡ÀØì;oY¤E)›ÎB vrn`ÈîÚj4ÊÓUU4¢A„…˜&%³ƒWN\P—8•ˉ’¤1IRLí¶-k€1¼].íÌdÁX,^­´›fÇáÜík׳ƒ#ª#ÐnUšËkZÓîæeQ!*õ¨ïÓ”DdÜm™, Žëy®ÐP£aâ”!B¥!ã ¤cDaH!@#ŒïUsЧAˆz*œ^E!ô®Æ ô¢›7 : È9<¿Ý.öOL¢FÁ‡LuBQ‘]Ëô}a 8Dc•Ò¶QÝ` 0¹¼¨Ç‰¤Y¶Ó,o ’h¨Úó¿úùÇnÞ¹óPVn˜Ê ™ž‹yà6jRWô8â RºúÒ‹¯ªLÍ.Š$B×"ªɈêœÛó2Ã+K+f«“é )‡œ#z£}Q“)!’ª¯..ëQÃm·}ÎfÏžÆLU­zS  CæªÍZ=¡I‚ ll^§Ô§^Xm´AK>þìŽãoþ æU–Î,g'†&vÕ8‡’ªö‰ÐçWËk[ŹР`ÈòƒýµÒPµX ,©,@- À†_’±\àw¤A¬Ë†&hF‚ÙSïœ:vÛ¤kWžùù“ôî¢@¶Ë­ÆÖ*g üè{osjvDEÉ„bvË—OœŒÄSÞõÀ·ÿü¯ßÿñGïÚwËç?ÿ;½ÿï}ø¾›nyß}÷ßÍÅõÀÙçg¯{«Ônœûéó×Ï…ŽÃÃr»áYf}c-–Ö)C1”É©þþÂÐ̾™;wçiîZþâ§'.Ÿéøùw–®Ÿ¹~ñç/½zî•®âþ艗c¸R§VÌ$“·ÝzÓàΙ@JŠŒwÌFTQR#ZÃvçVV§f¦ºMûê…¥F§„ú~TT E:FãjH•…íâ\e[ñSÝ ¦ ©íÅåÔ »5¢û¡5÷Ê…h¿)BQÙr\³eϭ̆TII­a‹ÜMæÒ7½ûí /Õšk‘Áôå³×ÆG´GFG7ÝÕnØÈƒ¹B³RÆ!·©918(k5™têÜìœí—ôX<­d KeI»tü|49V¼Vzi¢©n­x÷Ý÷‡MxúÔì•+W&ºé¾õkÕíÍ­õÚÚêVqUÖÅ›n•š¥Í¥Àq9¥¦Ù˜Ü}Ó­²õ3RÊ|Û±í.£!г·Ói6ª#j„Å€k‘¸ Éaˆ‘ A^Ý,ÙNG„xqn½X-qȺ¦Sm5!â„ÐíÕâêöæV­±]­Pê"Ѐ5šr«ÝuL™(É¢$Ó€·;¶ãù£~¸®ã»–ïXž#ß„»‘ü„ïRcêiR$¿FÇ ø® §çðº‘rèY !„½+Jï)Ø;¬ç¼Z+& 99’d–[\YÞµSÓQȠǸ¢GLÓÔ ÁµìF«:•ßÃ(eרZŽö0Ä¢ "RÛ$¡¹V}òÿužá•]å½_e÷½Oïêm$FS=3ž×q/Û¸` ¦9.L!äB !É%IˆÁ&`ƒ ¶÷‚Û¸àñ4MŸ‘4ê]:½í}v[å~8ãç~‘žGôEÖy×»þÿßïñ§øî·l—@Ðl5«×r˜JE¦GsóÞôE[¯s}6‚¿Ù¨nUZB-v£"KÄ÷¡eÙqU¬K‚„DAœŸ¿âÃ7p†Î§ö)g"!ñ”–|ÿ§oÛIé¾mÎO.ÆRí@€O­ZÝ…G~óûO|ñÖjÃÕ ¹œ¯Ê!„¥ô‘×¾ÿ¯ÿäVP²&Þyžhð:¯*œÛàBpäÀÑžT~ “HkPÁqA …dÂOœxÿûۯ;„°öö¡-ìåádb(ÚÓ[?µ’‘2ïê»/¬Ù[C¢xöÐôø±S{®¾auf†±U¬N®3á`ÅóRí*Õl§¶¹{Kaõì@rØå$$ˆ€àJ¾$`~|ü&;V®!—q ®û~MÀxÇÆ½ž7¥…†¶ïºèÐ;ºîºë‘âçÿÌŒÑP& a@p¢hƧ¾úÙßüú߯ºæ®wÞ~³o`ð¹ß?ô™O}å‰_="©xSß § Š'œe 9o?{0hÖ,–(i¶– ‹—^¾Õ¢FÒcFXÀzÂຄ«•†®ÖôH •®«¾%ÊR¥NE^÷ÜO؆šð|â4,·Rኜ[Yž‰õʵòØÉåÕÛ?´y.WíÅ'/ØÚ¼çŽt²–ŸœXÞzÉÅÇøæDí@(ÓÕ–êSRÉšTš:±f(´Qϳ«8j{K[a²Z­.wgB Ž£ÝRPí¨/œŽ:IËèÌÔ@ìøC©TT@2Ç5x¡TÐ9N'ç³{vlª±0y6C¡Tc× ‚„±ÇOÖ½ÒÞ-wŸ>9¥Ríñ–×GÞ’ëèn­Nìš],­®å­TGKº½õô¹Q«¢Fº6§‚A®OSîÑœç0»`󉕑H{B‹(¨áöìøç‡þV ‹\ÆŽÙ¶}ÏÕWßúþ¾gd—ùÄE€ïìÛ4°~˳OüÖPy$Š”Ÿ[ §6l¿xzôh8š!ŽÇ$™2\pN‰_jx–ãøŽÔ¤p4Y-®)š¦i†ïÊüXg+á\Z¨Z€%îz^(¤´p&ž°Ü4ÇÛž «¢ÇUA‚œA9å¦eëª  ¥a$`80Ô!v!•ˆ€1nNùùž% ”ø>õ‰ï7•90 €RZTs88/‚fÄAÏχà›sšà#¤*FB­VJÃ\‡(ºæ{Æ"gPÑ4±Î÷½µsçœR!ÅhG?ÄHÆp˜_YJ·u2Ç}ì÷¿¹ãžÛ±dSãçˆX ~µêÑ㇎÷oÌ„¯I¢815öêŸ~î3.æë@ŸÔ*LÖ, ’ÔðK­}•åyZÌõm²LBÆ”ÄÁÂÔlçÅšK†Â¿{æ—m©–’ÉÛ8ÔUõŧžÚœ*Tæ:ú6”ç–}×üâ,óh9[ÂŒ;¶ƒ¡îTÝP<L´ff‰ç×q)@u_£‚ 7jE?J§×1ÇKö´-/L†7¶Å§Šé`:ÖÛ ÜíêKÛb§§³¡XdttväèÈE—_% qÎgªÒ\fRÆ„-í=‘dÏôÜ4àâºÞÞ7þ¸|ðý7ÿú»ßúŸÿøÁ}ŸÿÊ‘#‡¶|dçƒÿøŸ½¡‹®Ùvá—‚Ðd\澊½j݇•†¯Õçf{†»Ž>ùô¯Æ¢m¡°D ®*ãCé¨íaI—W«ªÎ.¿t†¦SQ=dR+ëoø5D?ë6áƒ<µV¬œ=9í¶’Ú| *Ô™ˆ>qÚ+æV6öFò”Ö¼ªÝXÎç+‚Ä:‚ÆbÁ²ð}Ü{ÑæŠŸuë•`O‹S÷¥-Uê‘`¨»'Ó–òõV-ëÌy—&JQ ÉÞ4-Ûår©ôÑOÜŽLT-{Ló° ˜%OTt%"½ü“g.ùÄ¥JJV¾­s°­³3´_>zâtkĬŠrÏ…H¬T}fï‡îÅãxêñÖ!`Hq¯å 73?Y±ÌX ŒGà L]_Ä&øâ«gÞè>8ø¥øúÃÿøO¶¢°šýÔÃ?º÷³Ÿ¿þ†Ïýöw?FÀäé¥ß?ý±Ï~ú㟸ÿñÿk1µeez¥RZÝyÙµƒ;/?sB HXPçÄõ(!œqßó<â×ÍŠZ3Z¶µ!„¹ rÎ Ù5³^&ÄW4©µ«=j‡YGº2¼¾o|Ééél †#±dBV ˆ0ÄtkTT9á$ˆ@(20BŠ dRá ¦AÖ–   B¾ãš`NUÆHä3Æ(ÅH¤Œ!ˆO(¾çâ„ ÂÍBÀ!ÄœG÷qjö÷Ï?BÞ$74ÔÍ<€€0†tìÝ÷º/_‡b€ †â!Α¬i€SA0Æ„¸²(,LŽw¶·ÊsÀÎN!‡!ÎëVÃH&Q\œ)g ’xS‡àТ/?útçöþ¡‹÷È¢`œê²öî /íØèï¸hOy6¯µv1Ê8†š¡¨Xpv0ÒEõøÜDë¦mž ‚„¸ Œ7sûÀçÔ±]7àõípê"@²ùòž»w› Ï*d/½éêìèôp÷€e9µz>¥G2©`¬}êè¹H'dÕ*ÔÒ}IÎ!g”C.@dšy=ÞY­8@ÉuTÑadjdßM»¿Üü 0¢h¨PÖõmYn5¤‡+f­Z,c¯Ò×{XÎ.èsB¸G×µuŸ:ôl[ûÎß=þì퟽cçž+ƬLOÈ¢—n,–s!#V²µ Z”p<»°Š¥`±2 H£V,Ûƒ‘H¬²PmT³Pzfbb`ãöµ“%<¨“ëVüza~QÔc>±Z’Ièø—\zåÓO?¿aëÉp’­y“Ê0œrÈ5Mß{Ñõ¯¿øÜ—]óÛ?þáoîy๑çî»÷s¿þõ¯ÿüþA϶œRíËß~ £·unæ±Ç4+Î@_ûû'N£¡º];ðfö“·…Ìxíg Èò«€°Ê5Ì ZÉ9‚d9ŽA¼ŠØ•ðVy"Z·þþß¾cM£î6Ø*lQ‰¶×…hjc˺@RߺårÛ¹•3F@"Æ@Ý›»üòÝVHÑÐÊ™ü¦Éþ ûÛ½Ôäkãg«³‰t&¡±²]½²$,-•¶n<°ïØôÔrºO¹¶ÎakYb°†3 nÙmH–]/­.¥ÛúfÆ&%#ªK6‘XÕ)¦brª­vr|mîxf ºi}/UJ³Òé©ÅµÍÅp×EÜÖ‚Aobt¼ä˜«³ËéÎÆÇïþ|}µóò]«6Y´ÊõGÞ½èÊÖoÙq`ß«±–8ò€RAÑ0Ët $œ,HŽãÏž­;E×sB±pWO?¥1A–1íý]\iÄÒiMÓáÀ¢ç»²p$†äøŽ è¾ç ¢M¨e¦P,‰Èu}§aQÂ1Š"ûÜ”,—W(u¹C|ÂYPV8£>¡Žc ‚Dõ<ße<Ê)à $pJYó>3ÀóVèó5hJÄ”1Ð<ÚΣhØäÛ§ÚwtëJ¥d€B D‰s1N‰çˆ¢d-;¦µ0ØqØóq• IDAT#÷}È8G€qŠ "ì9¾¡"ª¦Y=¼ïMÛ;Û!€óó_sUpÛ_ž8e rà».VäÓÇO¯ø½7ÜÊ\‘#™#iòÄxߦÖ\©ªqæÚ%%–ä¾ÿÔCÿóŸOü†â[ ®!›EU@‘×-Û±eÄàèäÉ[/ÜéÄ}`¹&eZLŠ=xä¦å±dK;…Þð†]aµåýÓwFõÆš¹Üè Åq€ï›kÙÀÐPJÄöE ¨FðÜÈÁ|¥²ãÒ] D€kºJP·*&u\9 x"f²¡cîçìBf°?Ø72åâZ:Ó†ôˆ`ÒŸ=<ÓÙsÁ?ÿã׿uï_\rëž žÑei¥œóH—)fF×€d¼ûÒË«V¶;4Ì4Ì´pº­7õœéjvƒû×ìÝåK Qâ™  ´Xʦ2ɳÓ':‡;òÙRg U*õ»ï¸ó»ßþ—™ÓñKcœ"FˆQ¦HÂÿþðŸ¸ëŠx{[§l„4¹Q,¯LÕÇÑ*›)¾õ–»^ùÅo~ó{ÿðůXÜ÷“øÑ>¼i÷†¡]ƒìÜÑ0EA»7H-]}5O¸LÈ/-ÖmO’å–δ Ê©DG8®¬gR-«•¼È@<[[*é"͘™[:7!_›zõؘ$…ÏÍ̾øÂ.¿´]¦qòyÇ}ã7¿ñ¥ïæÖòŒdó«kJ \~Ý¥ãÍC­++gå·ÅÕb½B«Ét:‚"%§ÚÙ­éÔ¾‘ý¡”µ»ãª¿<Ú¶©ï?ý™,•?½îž%Ë„níØ;¯dúÖ„¡¤Š«º¦ÏÕÎHa"›QˆË¥yƒ PœÖ†P”{rô´ªƒ©j)Ÿ­M^Øi[¥ÈJÌŠ©Ôµã^hx£9;Gfww›ŒLMºcÇe‚‡ê¦9°m¸Z&X¡ÖäÚ\ÅHɹYi¤e¸íÜÄ©ÕÂlT¼ôðS×Þ{×ùä»ûþ€Bˆc<ö?¿ü«¯=pÏß~í7?ýA¥VPD_ÅÒÏôóÏ}ý‹wÜùÙ?>ùhƒ£©ØòLö˜öö%×Þ²k÷õ#_×⾪‰ë„H£¡†C².aUåDXvDe1V·«Õj­fV!¤x”Ô(e¾ï#5@¯UÊŒ—„€2¹À! œjš¦ïQϳ%Qv!EH Œ5,‹z„B" äy@MÀ”P !Àw¼:H£‚(ÉPò)%Ì%„ù„H3Ïã‚` ©VýïÏ/|>Èä xÞüܬR†aæÜTlS:d$©ïa„ᄇæ%À}‚°HJtvùäÆ+o ®×¼TrJ¹ïIöŽ%‘Î%œãóYVl[ ÈLjºþÂᓽÖK+q­ÐÙÕí9¼¥³‹2H«Éñ¨6ºÿ «®íèè[<9¡¶tkj´Z1IÃ:o:Í0 @X-MÅqj¹ÎîMOÈÖòxþÑO}òo6‹×=÷äã›6fD­ëÁ=xïWÿâÆÞñ‡_ÿ†’Š5¢ ñÑÿøÁ_|õ[ÿâýO>ôH±–Ec¥¹ÂÁ·_Ù8|á—_yì}啬ïy¢ºUWuͱ}è®]# – yNÊ©öXkgg1·¤ôz¥ PCR·a—sk…šYF¢„€zµB(Q ]SuA£Þ¨ÖªAC Gã¾Oñ­†‹D&„xžk»VÝ2]@ª‰raŸRÛóŒ})w‚U 1Â`¾ç»¾O!ñ ž'`$œ‡öAx~Ëx3éÞTBgÆäŒ"Ø´:¦É@”s† äçWñÍE-çXº(JЬM,”:õ}@.æ–5Óª„ÛÓÌ'ŽãŽ8ÖÑÑOvBM¬(GBó•4SÀ—[w ×LÿÌÙƒý]=ŽU"4+f4–°jkz¨ehÇAÖ5ãÁß<üßþFÙjXf`¨*JÓ ÛD|y¦ç›õ@W»Ï$ XµPß²¥7ÕÝ_-5,·.u@H6WþËÿõW8gÒ"ÍMWd5˜n]>»ÖÞÞY¬•[Ûãp$Õ՜ЄùˆqŸ†t˜«û½}Í£ÜrêLr%YÆŠ(HÐ*Úº÷¹ç8$ªJ³gÏÖ|g¥°ÐÂSšyïð–í;ÇÞ9ØÓ³kæL#Ü• ÆZ·‡;ç§³~NÂRÙô µTPÖÊYÇô“Ššž0vh亾ÀˆW«ç±Ó$Ñ£(Ø–,M¬ ²l¸¥ºYc¾ (ÁPªÝÏ{N©·.NŽïÞ±÷Ù7ÞzóÕ×®ºùâ&6Ò5ÜïÚŒ{.ÙqѶɉcmí­ËùòáSû‡;¯9ºï’ÝÛ_|æÅT&Ú•ê¿fï§_{ã{{¯ûˬçw÷u]¿m[ºsÀÍO.g«ËG÷ÝŠŠ϶ʶ]Îå<^·—µ‰4.²§¨1 §VêNWg.³zŒw`±T`^XJEt¯ÌQYnï‹uvg6¯Ëüöͪê<ß¶]/b(Z—³ÕÔºÐB<÷Ø»†º@Â.G†6 Î/,mP«¶÷ñÛo«VHÍ4oºf·mGíëþù«Ÿÿg°­}þè™®ž¤“JsËBa] žçYå¢Gí\¹¼gïµXV–ÇWÃq‘*Bejt<\q٥ϿóKVëÌ9•š'ÇbR®PŸ96¶åò±‚ŽåîÂlqÏžu­©ÖŸÿâ§É«Ö•ºÏ0uÌÕòB,¾žz«ÊÀá‘S÷ní†SµjÑõ< dQVÖ|ê‰Ç¾øù/ä's'O¼¾ùâ^•?ùà¿Þr÷ïºïžçŸxº\XéÍtHVúéÇuÃ-wßp÷]o½ølÃ*Ȳ²6³\+¾ºûªë†/¼ôÌÈþRn†rÏöüJ½Î¯¹åѱÃmýmžI–—çZ»Û´`Ÿfl§î¸Žï7dßÙ±í|¶dg­þ.OÓÂõйœËCrg{;²ﳅµ¼¢¢NJ09â®GÝbE%Í`œrŸQIÀ„3Ï'pE奜qˆ§Ô£”2Æ!£”6­Ñ"@ŒÎX€2ΛØ´ ræv¾ Ëû@mÌDÔó6íÙI|Ê| €Î'K›ß¸cZ>䊨å—*^aÓ†]`9gœ.5«Õª‰B€®ïÌÏÍô¾ORÀ焈 …HàcLcœ -Ο3"=6Ï­„Qdý¦]–ÍTq%IᵺPå#Ý•_[ÌŽÇ3]¹|Þõª¡hÒ2MU7`³s‘iUQÆ©‘ãìà¯?ðoz”ÙŽR"ó3“m©¡…å3»6Þ M~âðûU+·yÛоç_\ßßg{¥¥é©þ cqQ%ƒù„sàP«Ejõ|L‰+"±¨Ãp ô)Æ*@’À±&‹E¯šŠ·øž}°Rš™Xº /ä0c™0™v¬ÆòðÖþ`k*ª¦Žœ8àÙË'Od?vçÝ‘häÉg^liSºÒ] ÇÆ}M͗ƃÓ- 1“i€_-WU‚-« È©V”¾îÙñ±Më·Í-ÀXÔx ©~~v¥·»ýÝ?Om»â"±}Ž¡èèØÑZÕyà}ù§ÿõðõ7ߎ‘!‚ˆq(e®ey€†aß÷ˆë^°cÓ{¯¿ñío}åïÿöŸ>øäo}ºþõºæåçŸOe’[®Z.ݵfeÿâ[ßpjæÌì¹¥¥7gÆæ—ÎT<-V‰–«q©t’%:W̶Áu²¤*’ªjÖ‘!0ßQ•ÔæD¬k`z”GÔÚrf³&ŸÜsÃÕåqïÌÂø·;vUrÕF¢£‡ºZÆ·^·žÂ8é¬Y¤ìBsÍ*Ÿ9[ „J^4]ÊWõ±·ô»žQX™³mëš+/yì—Ï©’XñYÚÌ«<øë'§O½îÖ›Ù%Ñ@0‘.JÄ÷†U¶j*ƾÄëµÂe—]‰W³Š4D¬„%áÝ…ùµÊZv¦G•¹±³éíº«/,/‘ºU3ÒÙ:>³´¡{àtñ$-b@M[›Yìh Å {=éM¦ÙD Hb\j­³‡N$uU—Tƒb¥n»@íÁµÉsïíåÚ{®²ÝÜøèXWª£äuýîñÇn½ãî>zÇ‹¿ý}¶DC«‹å§{ôÊßxÑ•W~çíZmQ Ë+¥Ão¿ºi×廯¸êìȱ©±“>­3†|@œºwz䨦H‡©zµâ³„¦ëBK[­R¬•‹”T‰ï‹¢ŠGzz:VjVCבx¤ZoÔ̪k[FH Gæݨ5j•JUW5AB­bš¥jÍç@F˜q†0b`Š& >£”"@›Y@(œQHäœ3…æÄÔL žOˆÂó“HóŠ›»,ã¼y¥‚¸.ã€5Õfž ’‰3Î(“eÑP5dâüÒt[_›")„‘æª]D"êTe ""ÇûÞ~fÝPw¦½“z„È ¢dVkµj¹­£CAÒøÑ#JBŠÅÒžÙX˜<1´uPQReŸD® bÙ³ãbÇ‘·ÞM 2zèg?øé7^OD!‹RJëNCÓuȃQ`»7 &Ë@àлû¸'ï¾òz×#ŒP«QU­RZkën!Ž€,Ó§~¦{½fÄGçOßqóÇ,Sž_=¹5t':§ Äž0¢‡·\tyvf²kã&ûXãÀ‚¥h j$b—LÆB@d¶Â/êB oI†–t#b®ÍÔëçg'ÎuwGÜ\Ôš˜?sôÄöÝ;(ƒ¡æ:Óñ¼F£ E$,å—gÃ-iÝè ž¸qxóOú÷OÞûùwž}¾Qñ:;7ÜüÑËU¬îÜuÉ}ŸºŸí3çÆÊ3~ΜîïM§ƒ­©¸,…¢ƒ[ÒátáKÖIkÛ:ARbƒCÙ‰Àì\I<£³óì;JË'ΟÊ^Á¶m›neóí®½;}MÃ>%jæÚ°”«¦;‚Éõ:‹™XrE.¥[SœÚK“KýÒ{ ,Ÿ[»zÇ:BôR­jûtaevóðåÏüÏ+ÁˆŠµôìò¼ëØ…QÊ€ÂPP_{å•Dkç5½{ß+¯,œ8œÚÖ…|ãÕ?üþª_ÿ‘ûî|ñÑÇKµŠ&K¼ÁÞzé勯¼rçÕW{ûmË+„@~©xöÈ{[wíÞ³Sׇ¾ë‹ŽölrîÔ¨&­”JÙ‰1ÐZƒ‘´O`ˆFM€Fº«MRÄl~ÕóÜTK‡$È ¹$JŠ"Á ÅbÞ'¾€Q0 †Ãz¥J)A ¢¨«€êB ó\Ÿ¦J‚¦ „2ÏõXÀ€sB|Œðƒ4•(㘠Xë!gÍŽ çÍ({„q“›Ì䈿?~°¯jÝ}N!e@ r,ŠÔ%Þ~µ°7¤/!.…Bˆ‚Z1'‰H4" ¹•¹Ç~ñØÞü³i:¬ù;!&¶]˜cA9žè†€¯¬d%ÙK&ûCŒÕFO¾ý¾O48UAȹí»"Ãj$<71V«¬në¼xêìÉ3SG~òãÿð\_–P¾A„ § ì»V¹¾çxmíw¿ú­ÚªD‚Bݶ e¸žIvTæÇ;ûöp Mß]œ]èÙ´0:²ú‹.ÂpGÏÀÊj6Ö²€˜;±"§Õ†CÂa¥V)jª"`9»²0¶:µ·es3¾&ëZs'ŒD   ˆ†JkÌ@b¬5ØÀfߺž²K€G­`.žj³+eÎ S<¢ ¬,[K&åÞÂ\IÄx ­õåé£8uTOÄÓ Ó­}ÝBYÒÜ ’­G4$]êf%>´IŠ…IÁ!6 & ÝP–Çâá„+ ZH2õ\­ Œ¿7l\…ŸyêÛw?Ûœ ›ûL= ‡Bœ,ÂH$¼ZÎÞz×íßÿ»/õïÞ›¯üî·¾·Ð9T‹ï»æ“Š®`Aûã Ï‘‰GnÝpËÊØJÞêî^?¨ ¡DX­+FÈÃ2æj¨¸êzµÑÑq=€d5zàȹQêß9|vÿ tW.Mˆ…Ê–=ÑÏò6Z­åŠso¿bynYJCž´Ê*˜ñJÉ—d´W½0ìûåêHG*>åF½l»Äó¬Ûnßësùb›xv è—½V¡Vo{÷âÊø¥^úçW^ &#¾ ™@cZ €YO:yäè±}}92'îBPwG+÷ñûç^7‚IN¥ç½,8P{SÝ k“a±/ ¢¬Ý๥ ì†6 ¿ðÜóÓgOmÊD±¤j”´xki>—‰EçÆÎÑrŠ2w“÷ëÛ§¢Kž Ž?rÅÕ»ŠKób´£½5utÿÑJÍ„AàÉ!ÝÎ Xœ‹ÿó“?ó¥/Ýþé{}°¼¼íMwÄlõ­—ßøÈ}™›?yÿ>‹)•jÉ®zû÷í»òæÐΫ®>øêk‹•sZ@Í.äÏé#ë6\н}3åìøÈû ·(b¤¨ŠçƒzeM–ÐÄ™¹€|t`xc8ÖŽÆã”3P¹ ‰±TŠ#äúf0Rõˆ I¾Ód9‰+jP•”B1'kr,žäHPd¥a™0UÕô’-űfz ²¦*¢D÷eßõ}¡ `ˆDP†!Î)§£ÿŸÞŽæ¼É)œÏš6Ë„ç9ÉX¡›áRt>Ï%A”DaBsÎ+«YJÍ›®þñÁ’ ›;23}ú„ 1!D ô¿üÆ]Ÿ¹ß§c2€ d¶;wf<ÜÕ‘ÌôK¢H \]œ u "¬Š þþñßuîÙÆÕˆ¢„š¤.ÍŽàôÜ”Þ 3§³W}x‹ŽQ !‡N½ªÔ¯TfoÔjs‡GT¤cŒ"¡–‡ÜùÑ[,ÇW%Iñ¹,ë­ýJ aÁ-T‚™`<Ù}ôà¡Xö«G0‚ ðf|mäýƒûH¹ÝpV——€_ݶ튑#?ÿô—þúG?üñ]Ü¢¶a #AʯÍí{ñÍ`Ä ýÔ‘F[të΋C‰ õ\){êèèø‘ŸzáÈëoMLÍå+u·V·Æ`óúÞþ ƒ¹¹µC‡F–‹§ãý櫯˴mÊÍ9Kcc&©ï¹~Û¶K.Yß³¾³c ÙÞµ–sö=óòS/<ý¯þàg~lô…‘÷FŸÛ÷vµ¼ÖÑÛºnhxãÀúoûÚ¿õï=ôØO>>KJnT þÝw¾‰¼ø3ÏîøP1- Lâ‹™¾N#’¨.y^r•«ÌÙÒâœH8lž[)DF,?ý§‰¾ˆÝ0Û:º}䳕޾þ……)»ABY”äLK‚R¹#°AïÌù«Lž­ÌÍg—·\tÁÖ]—;1Û·Y7BéÎu]©Äbähk¹r@KűÀ%Ùr&’Jõl˜ËÏWÊk"B†16#ªþ‹ŸþÛÈÁ×îþøW,\Ê/'ÛÛT#úÌ/u´âÿT¢³ÏÅ1@NÙ?úîÛ)]|Ãu=ë6É’¬kʼnù©Ñ㥕ɮ-ëw_ru&ÑB)w}OÂP‘DU×4=¸¼œ=vd$¿6‡ Äb±dF „=×óvè[n¹N Å89[â^þÑoý4‡’” †K‰ÅÙé .Ûýû§Ž~õ«7~ù«ß`n¹P®¡`"Áø„|€†CÎM¢Ì E¢ž½ÖÑÝí?g†¢áÕó(Rç%£%Ùˆ‹°¢E·æqb*Ф¨Zµb–ËeÓ«Êã;7ìSGg&¡$×,?éá†c· ±öJ¹ï:ÐÃéhyaY FÏNõ÷ijÌ;:>ßWÞšóV—§OÌ;õ¹ ý—7¦Ã&‘’lÙ2ÐNíù7_ûØíw |ª¨•úVWÆ¡ IJ‚Šê1åoÿô#ýîþû?·ï…}÷ÿåWÆÆÞâÀÌN—ÖVôïL>¡¾érL×­r9Ö5ìQ'?{bœàŽh»ë×nÅàÄô ° ©(’ jÐ3ùÙÂÔ²UnšV”L{r8Õqëö®¿þâ_¦cýéŽÖÎ Ûíù‡€Ž½JÉö³³¶ã˜¥ºË«Õ|e¥` ûª$ºº{ûzÖ_pa46MëØk'ÿéÝ$mj|Ù^²}Qö¼| jX×sn´0´§}æÈ¤¡g"j¬¾¸vòýcsô³ÿ€ï*™—^?þÊS« [/¹ØK\‹øÀuÌú¶žG?¹êÚë:㣇GwݼQï©§_hÓëÁÈ•µ‘1)–éXŸÑsƒ±„Ä©uvqñêÞAúš±ÎDö.f4M*¬’TOü¹ßD[ðÀŽ«×fó '‹$Ir) X¢!“Uî[n,j<ò¿÷7ÿøo7}éÓ‡^Epº=í‰î=úÙo}%ݳN0•X$½41¹0»äÓc½ƒS½="âùÙå…Åù%(ÀÁ,œéܼë"z€ÙÄÄÛŽ/@Åôl àäļi5†7zñÖn=¤.¡Ì#„xÔEn4XdcN}Ê'Ô¶LJ\B)D¨Ñh Ç¡Œ9Äc”ú6±9‚rN›µe ƒHÂA@¨ ä PNàœ\DQ‚A8BpÞD¸ˆÎ‡çÑùÝÅØ™ÿ/©çÍ}W³ÉÃ!@èTjŒ:ª… >úÎþöû•R"?˜-£XÀÔq}Ïõ€*)û^zñþÛoD4âø€~^–€r @HÒ¥6©Õ«Ô”xH@þC>ôçã§ Å’€iR Ôr9=q}SöÚïßõå;)o¾ð‡¯¹ KR“–j›– A”Ä›<[kPTÇ~íµý·Ýy—﹄2³^‘Tm˜À©F»ãvÙRe8Eiêôɹ¹ù›oÿ(/ùjJ[>7“ÜÜÓ4ÍšvMÉ\×#bªQ›QÄ€€E@veµ¿+梉Ró°bŒëÁ€ b®t÷÷8¶­ªªÃ]¯*5/™n«æ¡ÀÀÁ‚°¢‘Š J&(6€ ÌLä`®·wsW*ÓZ´V/Zh‰†e>"Žcˆ€–#3¡tge9Ï­âЖvW•cª\€Z B7 ‡ÒÞ2Q$´eó ¶›ëÜøÔcï&Zªþ «Ž»;z_ù“£È"n”ÞÛ·ï£7ÝDΛÿĦ«†ßyç­›ïÞL«j­>—lÓjy7–Òì×Jþ&Ú»¡7»¼P^AÓãÅZ]“´’³&”ŒSãS;/è=q8;:õr¼;Ïu;9NͽnÇMË /É.ç1Á©ø.A„GÔâmªÞÞ¦¢Äºþ=}ú/ Ì)å-Ï,Vß;ü®]*®¬ek«åº½âRuä¹W:ö„ÎN´Ú*é’…%ÇÛ‹íÍ´w¦gÝÁÃ^gë–-ñõµš›uÏö]¶«þ^)Ö­6&m"£0m´§Ûyü±K¯ýörpQ¢‚Å©Fáê{oØräØéÇ} {n…ÄKB5â‹wÝýõʙՅåžàà™•bkhe|Æ.ßwÏ¿ÿã˺ˆ7öló¸±{Ûæù}#{îÝ»v";¸©uâÜ\8L¦‡õŒ*B%ÐÃÃLXS9b6ÈÄ®(œz6Úo4±\¯—+U×3e ºù>`"‚>Å*0áz=¯Éáïÿý¿|ý;ß¼æÆ;ßzñYU#z$â”7rûÞkÓjk¡\hªYðÀôèX[·ÙÚß˱ëV©D—f5Ýè8Úѵ^ræäH¾°JST&x¢ÏœãÑñYBÉ0õ3z0è§Ñ°\³b[&!" A#¾G|ß2Mß÷9gœRÂXóÿÚw]×ó9àŽç‰XDB‹‚àRß§T:ï „„1B(DŒAŽˆ/ˆ¢(6 ;ˆÄx3ìÉ9„MYêùªóùØûzÂæK!û Q ›{Æží q€dYxâ'?½î¶»¨C>ØÕÂó¨-AäXÕ¢®ËHT¬JqôäŸwÝz›‘êáŒÀ&/6WÿMŒ lTk²¡W %-Ö´È[û^léÝà<§œ`@“$ÙmTÉDe5k»ÙööþÃïï…Õö ÃŒaYµJP•#¥jI „0"ćö¿w퇮o]9‘°]³œ_Þ8v=·nVã’!+Ru!l™›[\ßF¶ãÑÓKËsŽÝˆãS3]W8ÎŒN#EQ¥Ûõpbì{Žm[¾oRÊ0Œ²j¹äj™¦ë{Í%¡ cÔ4+{”BDQP$Y@ˆ1Æ8‡Œ{ž8dŒQÊÏw=‹r.!ì‹>‰"ŽPœÃf0}û<ï§ç£ó—A!„œ1àùBts}Í€\KF‚ª¬Œ¼ù>Šû½\׃çqË@ .¯å%ˆFžö±k`Hð!´iADMÛ+âœóÕ…… ¦¹¶¯G ]Õ±¾ÿþõ»õ÷|ÁÐàB(X©äº‚¡?½ñȧÿæ €Ó§O†ÂiUѰ œyk$Ú%'[VæqHÅ’àÄr¿o]ßò¹…ˆÑrôÀû==m¢¬2À SdJ\åT:là”,#Ê€äj ›¶mŒDc“§Ç£=‘ùÓ§t!B|ŽÄ€S®Ì͆†6ɪT«›‘T°œ›üÐ{›ñæ )h²)èX¿žb_ÔzÉÊ.Î*:„‰˜CKÙµTªŠç禹óæ‹ÍµÊX©¸¥{c%›)3ŒPÕ.¤½r!© FÝ5´DD7(³£¡à› ÕD¹¸±co–½ïÌ{XJS‚U"×5@.c¼î»°‘Šwòtÿç¶Kº*b*™îXCù†À–+,è5Ž}oûe—ëºU³H*ÓQÏÅÇu$¢H£V‰FQ‘Ö;[‡N=œHF—ŠkCíÛŠ{ÁeCm‚­bÿbeʪû}y>ë/Øé(³Õ4™(‰|Q±òÖjÊmïºìÂí©t4“ˆ'bé”[sÇ'& s‡OŸY‰áZž‚Òéú†]ÚæÛ·m¸¸£Õ8ybviùÿõ¦Qr^w¹ïÞù­ª·æîªêê¹[Ý-©5O–çyHìØ&ƒ! f8ë¸À7@¸ {B 7O±ÄŽmÙ’­Á²$KÖ¬n©ç®y~ë÷p?T+|¯]]kÿ×ÞÏÿy~ÏÅ}3{¹«òÑAÓq[ÅŽ‘—óúps¹PºzTZÉD §Fn{p×Ì̘[v¯=…Ân./-ºe¾¾zչݮï>¨†bŽÝ>qâÈ⪭£÷Öêë´â­{ötmß¶Këë2ÂFJpípXçÙþ‰xbuárªïÚüœšÆ 1bÌlÚ?^)ƶ]3zÔH²Èµ«óÑ;ü¤¶Ýw¯„Œ|­üSM2 9ÂuU–Tr×tUE)¬Å óÌÖâý£V³6uÞ÷ˆ¬cʨOeA„ ¹åðDRkulˆ`iiõµýð‘_|z{èð‰×†s¶¹±°êvŽí¿ï¾ˆj”Ë ÉÁ¼T‹¬¬^ÕC+„б™IÁ•N6»õµå5Œ1g\O$g÷í?Ï]80HÄ#ĺÚìkë•°~uˆxÿ ŽAÀð]§ÕªKо°¸*ˆÐµƒ®ëb ð°®XjÖ:u(¥FX3Âá^ `‹‚㸾”?ð<(bä@Eb$"İЛ‚ÜÌ:Cˆ8g7Û¼ê5}õØwüfȰgˆïuIà ÈDØëØ×Î}â‹¿ìùÞM^V/ÉÃ1†õZÅuÌLÿÆ¢Sj>÷ï}ú·?ƒ^±ÜØFRŠ0"13Š v!YÖÂ!í/ÿâï¼{_~d¼Yµ:­J_j3c"LdÞy÷õŽkæ&K«…æú¾û™S–™Ð!¯ë0jõE³@M’ÿÏ7ŸÎõ7Ú1$_9qòÁÇžDÍn›¾_¬h .”ˆ¦DýÉ4sÛHŽšíÚÂJkÏÞý²¬k‰P:•£ÜÆ@`œ"»¦É_W”nÇÔc©À´E)vùƒ‰ ¶nß {·Ó›2VÏD’É »ÅF,-ˆ*E\Ï aY$5»ö9Â\ð ¡€b$Jéln¹v‰7\a“HÍêš©d®ÝjRPž»¸œÍE9CéAÇsVº;fç¯Û±Ý¡Ìİ ‹G¿>ŠvL°±h´oþ½+çWÏ=0¸ÙÄn4XݹÝtÊÄejT®U–ˆë‹R"ºesþè+ï‡RºíÎ?wþƒÛrMk:$,Õ?¸¾²˜ˆÈ]®Ë2©Mët,7>W¾¶ifW½QMìÚ¹xìO~úçÿ÷ÿà‘;”ÂÒü± yòÁ'¶o½Ã:‡éÓ¿õÛÏüË÷®ŸY«º{øþûz@J$Gò“2‚„2‘ 'zé¿þƒ¡Ä€ŽƒŒH‘©ÑÌd(Ž÷IrXˆªIØ]ßÄâFî}ÿÅe³·l—õDЪێtîì)èìÚ¾eÿÁ»„€WÖ–ß}ûèmcrjó‘#?RÈk Â¥õµv NbÜ5‰®´†r¹ba‘G&¦w>û¯¯Eâõñ‘ÙåÅkA $´á.eBL”b™tå¢Wr››~ÂrÛµru6?sÖ=+*ت:éTuÛŽ/Ú­¶ q:W|õÍ÷Ž+Š ˜xäÝËcÛ·*!£a–Œ8çÒ®¡5IÆ EQâVÛÈ&Î<Òùð¦Íf·U(¬ª†Ž±@X2 ÉСÔõ‰ ¹çs©ÙvTq$bŽt}}aõÈžøá§¶wöW›×öì¹¯Ýø)ókWΟß’ÊÕJ«¹¡QUUjÕAR!€#[¦$(¼òÇj–V‹¦íäòÙÁ±©;=Ç)Ô–’ɈãŒa @hy­ät€dvDÆ„6l[’I)ÁI@¤Ô ív,Œ€Ã¨®†.sÂ];¨Û]ƈ"á@Qˆ|ß㩪,I! c:Žëbù$ w œ "ÀŠ¢ €Æhƒ*o’ÝᆎŽz¢:Û¨Ó鹯zÓ ‚Þ] BŽ8ãÂH8ügúçw<þd:€ˆ÷ €½Ë(¥m«Ý7<Â!vMûÈÙÃ[ïÄFÆ"Æ8ÇØ4ÍòÒ-,UÖ–ÕtL’€Ê»Ï\þâo}Ùv@w½ÉqØ[S²ª½þÂkŸüŧý ¸|õ<ÀÌ–YÎÌèOcQµ,«?7„ Â8œyã;|ê3ëWW±,ÖVWÚåP:Á5E3m§žÎæ"éD(š,/¤ém¿ ±\)6ºõµ¸¡PγÓ#–ß®v@¯bVŽ%|¨0Qô\Ëgªë» ¥b#‚†ûYIZïŸÜë0B–m^»þ6õ*ËTÅ•béÄñ· #,kÑzi1 ŽKPl®ò°Öwfn•Qv,ÊȱW9óvq½ hµ,b6b²&ûØsø°˜Ü´Z9›P,Ö•¥øèàtl§…0Èö'ÃÑôÊêší“N×*tÚŠùðåÝ-£³žÙ½óîûfn{îùÿ̯=Um­Çe%–Ô¸¦\»t‘P/2¢TJüº†`(—°*‚‘e-5TUyyå:òk ³´ýîÛ–OÍýÖ¯ýúóÏÿÈåõÝ»vººžûð¯Þ¿ë¹säzcÇîíÿò÷ÿò_úÊÌôÎ%=v\R(ä<óƒ¯ÿá×:t1SD¥áxblzó]÷œ˜š"DþçoþôõwÏüôE%ÞµëÓ<)"Øl¶•ø€åËCƒùH"¾g÷¾+'/ݸò“Ûï~àÉ/üjàj¾S~ðãw¥#¹Z×oû”"u!ú2Z<š ç¿ýO¯üÍÿó‡ÍÞv`Ï®}ûeC2©éÍa£Ü-#ˆC¼Ö®CÏ“¹µûö½WÎ_ƶ±°Vµ=;אַ¶J_—ìµ˪ªÅB‰óë§×O éÅ®T),mŸÙ4wþT·ÑÈiÃJH³;.@LЙÙíPæûÍrµà¬_öØ*”È*·œ.`ÒU†$ß±£1ƒs ‹€BÑr;„r7à Bâµ÷Ž}pò©ƒãÑþÑë‹§÷޲Lj¦…ÖÊÒ @¢ohyáâÐÌdft–#©\©®,\ÈNì½õNÃH¸–[X]¯W*«7 °·ìÛ3œŸ”T!¬‡äþþD,a—*õ¥×:‚i8–ñD"©k!,б”F$Æ9¾ëSâ)ªªkŠˆ%—¨"‹Š¬@„,‡X¶KB(õÒíº­n·mÙA@ý °,Dz-Ïõ\×w\×#>!.óÃ^ˆ ¿Ùöõ³ 3ïM§žh 8ä= (8e $)ò«/|ÿ“Ÿz¤oh„SÇ2Î7…œs‡ó#°×h7¯-Ýþ‘…õ$ |$I2 Fal­Hu@ s† „€»žß¶mM“CªF}ÐìZ$°%QÜ(Î0=cú†8Ž!ÎéÆ!N9e#ˆ°Àョ!ˆz­ÑîvLIW’CÀÆà wFß…^ðØîvŽÿÉÄÁ-#“›Ç"†ô¨¼½J€XØ:=˽€"*RyiáíÎüÁW~›‹ŠU©©eChvš}ý©co¾ÿgö¨P.®¯._ý¹§>xq9dÔoµ–G&¶28`¢Oûá#>avˆïRÁåKd‡SF*Ã)+4K“Ã-·šŽe±€s#ƒõÒ|<ÅŒWÛkmV6BQN!ÀuÁ‡Š(1D†…Ës«ÒüŠÙztèW\DÅV b²Á6ðgoBÔ“"X¾~e|js»ZIÄcpˆ”×k3»nå–Óå¬XÆhŸTqK…9ÂL§ú+Ÿ¾“(¡¿óÌÄÎÑÑÁ!¡ BçâºÜ¨  ÚµMN—ÜÉñØ™‹ówÞ÷d§ÑÉŽ¬5Vûêí. Ž®…y@¡!¥Óy,FœA=+AÀ‰™ÉûÀkI*¡D4`òc»îo¢Ò–ÑmgÏߨ´U‡Š:7_z6ÿÿ;1¨$ 9¶HØ2k²™nôérÇ_Þ}pç¡—~Pì–q§Y^®m»í–o|õk÷>òIU‹AçCÎ8&`méêÒ…õOzþåy=n½zúøpZN 冭daÝ$²ŸŠl]2_=szå•c­0lˆ ™âìÖþÃïœyçå‹ù:³}rðÎ]XÇ®R!H5íм%ÐJ­QX¨–/_¼¶oÿmƒ™ñòZ­m_ݲãÉמ}•(-->¼cïçúaîü‡ ëŵRUÆm·±s¶ïïþþ¾ü{ý‹ÿã—¶Ìnîtª»7O.-4]9tpv¢]­¤ A»¶TvT]GäàÁ»BJÚô+#©écÁ›ƒ}‰/-íJö‹Ñ«²~aåFntâÄ¥³{vlw»õÊÕLü¶Ø&MšƒÊ²€)Ëf¹¶)5ÄP*žõ-˵”­F%¬ ÅGrkï­—/}yŒaÀ˜d9â›1B©ÈÅÆ b†ˆnè^ ÀS5-§jüä0 ÊwÝù™N­î´ê“Ó³KóWBG=w5•)\¿64¹…¸^»U |¾¶xµ?7¬„Bˆ•êºë¸©{ŽÏä2Ãc€òRe%éáç,ðüž[šËäŠ+²¦‡¢1 aË2S©¨X¶\°< `C0Ú2»M•$‰AA€ë¹uÇLF$8dÀqü®cK"—Âf!ܲ]Ê¡'‰X–²̅RzÈ„ŒQÐC"÷6[@{Pv{¼o@BÆ8@=Küéãï@…%Ó)âˆàô”j8ã¨çn1Ðª× cpÛŽ»ßë‰Ð Ò^Yç¤Z-µê­ñüVF6BAƒ‡Þz§1°Z­ÏöÕŠ•f£223Iª§|Cžf$°ëu§æçG7× QÂ’-Ì/Ÿß¼2qáÒ‚ª‡Æf÷•Vj©á|§^¯VJcÓ÷` PNªj>?èÖ:BJÅX!ŒÊŠ"i˜yî¹}¹‰XºÏ's‹Å# Æ q;1-[ ¶>¸#}øÌéŽÕ …0 ²:—OÆ7Ýlð¿cpR›8”–—ndg',³I…+s±LŸ€µ´‘f Z¸Ýi×uŸ)¦œÈúb- aÑZ\½Zñ7+ªÀa4V¨5Bz3d:~—1¯-+¥a+ì¡fª„C‚ j!™xFT§;ˆc ²™Œé–± Íf“t ³m[ª­ÞóèG¾óõ_®Tiˆh­/žðýÿ‰En·f·Å!ìsH$*—Šuš.~ IDAT,‰Ý6wšæ£ò¯þç'ýü·¾õü‡_艞ºxxÏäÝV`#QÔCKúáTÒ’Wž}=«¦(¶wONïÞ5kÛÁ¹sç.,_Ö"ñÙŸÉö}6”P~íGív&¤Ó°Ø®ú*Æ(ªÙ+M-,!D]<,Qð±Çï˜bDáñS'Nýá—¾Z\_Š„qŶÞ2-·ä{¸­A›s×K¾vO.‡Ï\¾<”ÉjˆíÛ³9ݧ~âW¿ðÃW^~ü‘™Ja`óÚª6\—®6ã©¶3úÃC–-ŠR½SË UŠë~dz¯p.xÕë&‰Fú²…JWÇÆä`þ‡'ß©TÛ­7Mtæ·NŽE£ÆüÙì©í‹•ŠŽŒŒ§G"q­ÀNŽ zëlV$é6ÈÄF’è3P„,Žï#®aHE"BÂÜ€(’h;‹HU-îZJH½vöz§ûíO|ú‹Ç_x³Õ\Ú~ûm«sKÑ긚gÙX”J+™É¥ŠÆãk7*ÅÕT~4•ÉæwÚu 0×¶¥õü°’U¢¨²Žs)ÒnwÖWÖ Rõ°‰ÄtÀs!žÐM&ãmÔÕÙ"^øª$Ó€BF%QDA@qfšžë¶ꭶåYQMÂp7aÊÒ&ŽˆYÄ2FCð^µb7YÉ€óž`D¢zÜÆ{j;ã`£ø 0À@yn^J‹ny8è8ðgê}O¢ßàkq¸Á…>xÿXß@I2pœžÁ¾¼¾–Îd}ÏwëÅX*šÙ;ì¹Â"eBT+_zñ…'þ‰˜‘$ÍO͸ž‘O¦ƒ¿¹烮g" œ<ùãm÷ï\»øþøôÔõ³ëúP€ Ä!@׿>wþ?ÿ…À§‘¸!I•K F†‡£”ùXE¬WÛÅdl 0& ¸^*ŠpѬÖ/œ¿ãÁ;ê-H!Æ8h·Z´Ûª­5úg¦š¥¥|t; 8àòüâ'Ÿú¤"JCÆÞ¸i^¼0šË{–Ck­¯a,Ä#Å¢0§Ó±-—Qàu; Æbj|þÓ“3÷ o?°R[ÍOÇ[kåy³Q+$úèâYÄV9W ­ív9¢ã™1«é X7ËéHJÒõZ½¨*’°»–¤10I@a#âqOÕRq=UŠKÃQ ‘®ª];Ð$yiua0³ÛUx åλ‡Þºû‘)aݯW‰`(T U(EÛv)ÚŸh—½x*6’}ïÊá^xù;OýâÓ?ùþ3/œü@ìögöÞsç… +õJÙl”Ïçž»oɧ¦Æ'f÷ïF®E4öY½*¢Ûõ=¯Õ' nÍ>áŠÕm^pÜÂzA ùK×Úk¶RRÈšf…(8ª§ô0¨;(ŸIÆûŒ±áÍH’FÇÆÿè+_|ÿôɩ١åË+…»Ú8[/•º,˜[+¸R¸¬¨ÃIàøF:p´÷à£N§õò÷ŸûÜÿz¨¾` ÍŽ*km·s©176šåW•\írÁç(æcðÀ\¹xY•n›®°e`0œëŸºïÔû'FÇs?üÉ‹…ÎòX4•Rl[—â;vÍ ŠÐØx¦Q-× ›†7I‘Hµíyn×vËyèÎ —n´iaïÎùöJµXNè PÄdÌ¥p˜x*£ÄcøHã Cî¶&AÛ÷tÍ VS3¢«WË'šÚ·ëÌ;oÕÊs{n½çòÙbéðú¼ *.]ÍŽ)zxzÇîå¹¹ÆúªnD³`îy¶¬ia•b!‘îOåòV»éÙ¶$ʺ‘Lô¥&7o-nÔ«eß÷ca#ªêgŒ”‘€cÊfRk êØŽUUCº"J¢ bÈ9Ç–,2p! >œ‚ €€`0D!A@žÏ(¥®mûª*+\èM9€ÞLnÜ 6dxŽù†]´çf€=“ç¢d&+=èº=9™qŽ~fÝxq!&àâ…æ¼÷^»ãôW®kqN¾ãY  ‚lW0g#9;uö¸'º#3›¹ã9ÄÓÔp@™åÛ1YqÚ5öMîÏ æ>Xþ¥§ÿcÀ逋'N¥²™á±ý4è5e0«ÛÉMŒÉFšÓ^•«ÖCJ8žLCŠÅÕxÎ\¯%rƒŽÉ„¸D¹Jæãµz¥XXg@À!Dlã«£¾t? ɳ £Ì#¬ÝUÍHF8 rÙäÐø0BˆÚ+Kã7Íîoë£f»%c ¢ù¡‘…ùëƒ#ÓÊ2ô8ð]Ñ—§÷]>wISÆCñ˜Ü*®aÿ@^å•öª%ÍêÚÌ`(¬ÛN+\BœP”AQÁ¶+¥ËcËlÄú&ºå†2ažÒ6‹ý}}ŒK> æ._¹g["›RUÃ^ïÐS\60¹)¡ÈÔñTËñoýÛ}÷?äPÒg¤i« B ÀbR׺V=–Nµ|ìï»í®ûÆ>óôÝÿñâ>õñç·LóK¿ûÄËÆ/<]^[k·‚™é™¯|õë#C…J§V­^½xuuiaûŽ­¶Ã¸´eW ‹ç«š¦5ùÇßú¶8Ö tŠ5«z>$8ªÕ¨¥†HWÖ!n«\ªØÝ ž®_¾ÃÇÞ>ŸÀ¶#kH”RR<< Œ±P"½ÿ@Ÿ¬âZ³uêćá>ýÜ•‰»]Ó³Vµ¸kÿ–Ýw=²ðáò×þø«Ñt×k÷Þ©®#7[#މŠâcЪ3Éê8ˆ nw¨?J\xÿ_ÃéÁw.žMb1qÚë‹Î/<=óõ¿ùêýÔÉ·Û‰|ŸBu‡­Ë!cu­~ïÝ÷~øîÚf}#gNŸ’Œaض»+…FbtPsã¹Äà¡ÿz«ÜXÝ»}+áQ†”zÇÎöÉ ê9†MŸÉ^ k šïCA ¾ÃàS CŸ…"†ïP#aÔMï½ù#.¹Ûì?wòØœôÞö]û—WD ˜õf8€(VƦf  g‡‡«««µêš÷å†êõ2Æ@àP«–#ñ¤¢j®ç´[MÆ®…’¹ e~µZì´Zaƹ˪Jƒ¡äœ¼/_«×LÛÇÈeA×4á àˆÀ˜(I!¨ ‚Š0ÆÅ£‘˜’ˆê¡®ˆÐeLU‘¦*<ßE‘qÎ(z0DrÀz¯9Îì¿ÕvÄ7¬¢7·]=_*r,œæeBÈy/˜ÈzÍÑÜ=Æ(çYýׯÿÓ_|ûolÓpƒÁ¨“áÓÃa„£«¥õt<®@#4+ÖÙ÷OߺïàØÈ8! !d$@”RßJXDر»FføØ[Ïl¹m”BŽãlÙ³ÇêÖsÙH³Ò4Ïuª•UÞsšcÁk™6æ'OÙºu61\Û‹Fã~£…%LªV‹ÑȤãÚ4°!ÀœóÂÒb‘üÈaBÀƒ2€ŽÙu¬â¦›Œr@{–·\¼ƒ’•ˆß0áöñ=’=‡=N:ˆS© ¦Ô×W­ #ˆÓt]U‘P»R¤È §Ó÷ÃIuâ^¯P—úõFÍLKêzÐMç—SÎŽôîj«ÉŒFcù¡Ñ¼Ý $C€BØoÐñ|lÆãz6>Ø©—„‘°‘DŪ}ù¬†“b Mô‰708,¢O-Ó­Ë@‰F¢É©‰²å¤RDkËݘSZ~ã•gvßr€1‚˜Õi ¥J„(¶“™ØT,×cñx£RìK…úPæýS'>ûÔç¿ö'uÛ÷EÃ}F´û·}õ­=»ýÉãGß»ööµ¹¸<>¨k©AÚö‰œû€T———ÊmÝî¸_»Ì Í÷ÍÙn«_‰TÖý\«F|éJ‰ÐÓÛIK%«¤3#±é‘ºÕì, SÃÙ5ƺe'–ÐÂ^¸³~uyÅmßp5Ñ[ Gã<Õ¨…xt÷¶-… Ù5ÇÜ6°i|ïTêõÿ¯;‰…û96›LXŽ'¡\- ’Ø*4Õ­8lÆkÞ**͵ÆGÈ›;¿žÝ­p¯näHÈTøœ¦G©×=wõÌGýDk¥¶·ÓÕ $ûdU†z¨j•jͦiv¸G4¨$ mya=Ne’ñÊzÝ´›¶ÙÉŽåÆ&:–}íòy É @Ïç3—0»ãCp= €Î0æ‚ º F…˜B-Ž×%X@'ß8z<²y÷mœz[וܨnŒÛjt»& „1|ãÊÅüäVAÒRùÇóê­J,ÝŸD«Ó`œDbÉv³Õ¨V"¡¬‡ÇévÚÔ÷Õˆ‘Ê8¶Ý¨|ÝŽ„± ¨º¬ëŒ8Lj8")ª"ÉšÜן@BQ5it(íùa¨!MC@È$}ê鲨kAœXà‚ `À8”„”?D"aã\õÌ |¶·aêU¨ÞŒH÷À å…€Æ)£öJÃ8dÚ0¡‚ ê‚ –ÿ¯ßù­Ïþï_pC€ Ä·ê%QÑíÉî¨Þ(ш(kõ®plµ´0¿°øÀÃèªQ–C€V·,GQÑ=ÛV’/ð_{ñß?õÙϺ>£Œëa530D^Y¼EÉóüz¥É¤²£án³íSb[Vaîòôôd0ÃH®•*‘¾t§ZèBȳœH‚È)?zúÄЖ‘D¢Ñ”%cAƒZmTþâ/ÿö½wOpÎ<§ýÞ{Çþë'Ï$ŒäÊÊ*ª‡o^W{Ôh8d”‚ fM!RHØd)O"(GÄ˜ß ’(BÀ]Ò–ÄP4$É"Â’Žµ·Åæ\nvtq­Ä80UàS§åHjóÔLÿt8šKT<(A¸Q@€Öš>eX±0šˆo²Ú«TÒÂ}f #$*<0Ç&';Ån½Ý^mšÄ¶Ò©ÐwÿëßÒCùÀñ)2D.t›ˆG®ëû4P}ÕuíP’yõH"'z8"[6IªHØ·óÖ7Nœÿ¿üw…¥3™È]ÞšÞ ÷!‰èáÄËß;qøÜ{׿—^áÕF»T..ßX½nÃZ¥NÜzMЈØ3»Ænø3®‡õ4ÉMl5›y~L©--®[¥/•TÊM‹žyëzÅ)äÇÆPÐÞÕ†cW/./•×—ç—Î~×NÒ~ýÁ>øËûï>èCüæ‹onÔ=Ï›N§¢¹HsÍ‘°þúÚ{g/Œéßw‹Yq-ËaU×Å]FhØïÛ¿ç蛯]¸v‹f»Óé”­Òriï-}x긑11Ä¥¬yÿ`òü¹õálÚmùØò7ï˜Òµº\?wý•ˆÔP$s»n§Ñ:rî¬E+·ÞrPq·Ù=üÖëÉt`àSÃ(@(³Àç”ðW€Oi§ÞÒU X”eF90¤÷úv³³¸efï±]^8™˜˜™ÜJ uͲéÜÅœnJb~d$N5«eEWt#EëË(ŠnÙ¶í8¢¢rM«c™MQÁéT¿€D,IˆsÛlÛV›P"ê!U é¡pHIJÄcQ#‹†Ó‰hÌ0Æ^@€,$‘D2ªk:B (I‚"ŠHãœsQ$Q‚RÊ=J…Þ¥7§ "8ìqnªï?KìôjÃz=«r Ö;yŒq€F@rÌg€K¢h^¬ÍnŸØzÑjˆíN‹c b…CζKk±¨‚TAÄ「zóµí;fgwÞbv,!Œ3âº$Ÿíkã†ëû¾k§3ý¯¿ô“=Þ!aÙ‡ !8`”Æc™>E– …UMÕd=Ê‘‚°P*U&¦Çç/ŸKæ§¶l5m"ÂÚ×û²qÆ©O¯”м©Q=”ŽB(@Ÿ8µÖöýS=RôFq#Ä@ÂÙÐøØï~åËj´Ôâ~X닉ÔàÂW3Éd"ûY£º™}îMÇ.'&&8µÕ"à^2‘»Ð½ˆ5ƒ ¢,ˆW¥V:4UEeŒuÏb ÍvŸS k*ÅšŽÀ6ã„ë¥Â|±-­FCwšÑv~4¯èz27Ì|‹E( ÕlèшA&·°„<†{IwÆ5J‰¬÷³ÊqÅhg ) B}ÉF½É„)¼kÛ7Ÿ?‚£ iÄ›—mmŒµ\ôÃg_è‡ÛJl^·Û›’Óœ}aÇðÝ¡ÀsÝÕÁÙ-‡žùñŸ»o×zÿ–ñû×Òο~ÿ{ºdðNÕî6Â}ñWžýî£Ý=œÛt}~ ¬Í/tάTÁÎÙ‘`­°÷HjëVÒÖ´ÉNš«e×h MÝuë@VÖ Ö 7*db1tûí{³ýiÁ&g$XFþÁ{î)®÷ÝÚT¢‰ù‹7rÇâ·‚vüƒ“󾈴êIc›G±jì¿ývÞdå¹síjóýïmªsFÿ„>”ZÔHù™ƒöê©ÂZ­ÐmÄôès‡ÞùŒ=& ->ôðŸùƒC0ârf¹ZØ4ùÚsohñúêuº}Ó`ƒååj(Šr}ß{鹇ïžâ-²tµ0ÏF0,™V£éfbv‡œ.ÎïÍŠÍ…öùÝ{oµ$¹a•6Ol/çcý ñHМՖã;Ëé ¥3f«­bN¬+ÄEœPDE $P@@„ è©(€a«iua}pj¸Q#ª‚˜€U%"ìâû‡ïìSw<üÄÑ7_!·‘ñ™=HŠŽNn½våƒP*e5Û7æ.ÍLmÆ¡d~tl马/'3j4mšp$žÎØ]³^-Î$A¢·M“QŽ)‹E8€r­¶2 È*ÖTÎZ‚ÄúRq$ëqÎÌn×'„P‚@ÆdÆ!çœqȹ( Q ˆ„1Y‚€ç†Œq#YEAÜØcõB9`ƒ^9ç@z|äÇ DqÄ9CÀ( âŒCÜã‘Bëuƒ„Œå¿úáßß}ë¬K€€8žÍø¾‹"¤ +äOfÆ»›ˆÅWç×ÉRsýV=ß}ã½7ó¿ìÿwÉF¯ø CÎH¥hTV5ÎX,‹¨ÒH²ßõf©žÈô‹’vsÛ ;ëí³ïÙtïæ0HĆrBFè¹kg†gv×*í–ge39ß# ªõHÖ$‚ÆÊ¥ZrB‰»€¸ëÓ¨!³(‹£Ãé!]Ê$R#Ć:ÔT&Z–'â°Y[ŒïTzq± h>ã\ÄqÆøìð^[3c²ªD&œ 08Ã# KàØ@¹3üš×l¶b}»ã©4‚2%v§‚%Ræ‡qüåìšõ9½1¿œLÖºë5ÛjZ”‰éd¾æ_>üòïÝû'¨•zê#OþÉ_ÿºh|$¿#?–Ý¥Èè?ÿá›[ï;¸wêžïÿè;®£$˜5<6NNm­,¶6vI›ë’å“·ß|£táZEµ;+|ë6y® Ótj7®›¯?ª¿Z”Åu#¤Zº[Ë‹ÁPBŠ)Õ–z÷-£;ÔlhjÓŒ’öÝ}×AæþÕ´&ž_[<úêñµÊüýûNí:èüíøÒg硑Ѻ™,Šù‘Íñ±µc%__T@h¦pK|ôìÑ£Ãc»ÞeDP-»³uº/•ê;|蹑ݳÔ_rY`$úE¯,„"éñ©^{›8ñÞûÏ\^|hÿøµ•J`.ïà!»Ñ´Ö×§ûôÛß|U íbeáÙoýãŸ{’xžÓîbí²Jµ¹ü›÷?ÈúéÃ?uZ 1%ž-‹¡€Q 9²¹ .”‘ÈY@ ƒX¡ ƒH „‹’¼²XN)‚n@W v·Qè<÷ýï|ô©_¸íþ¿ûÖóP€ù‘]¡dtjfçâÒœ ¹Ž³´xc`‹ª‘A«°Ûi©ªÆ€Öµm³°õ<ßuÚ”q'”˜VQE5¬X!1 |â{‚ (šF p™oÄ $E»õ6§€CH)åŒ)"Ž„tÊïŽÕ¥”J¢ 1&„”!c(pêJ‚²((’(ôÎ_/õ!pv“ž°‘î=!2Ö+§àÝ4•r¿YNxo‹CUQþóÿ˜Îì¹ó!? @M ×—‹ª!a(ØŽ‹eÁvº£33”‚sŽ!:òÓ„˜~ëýš–ƒ€RÎ×ä^ÈiÕ#ù †š(H§ŽÿtûŒ2±u‡cÙ^­ÆeNæ9cß¶ËÅåøà&¿ÓÞn¯Åyêu ×'>;îù„ÐvºBXÔ[«:ŠVÍR¥eÀE!€ó §7Ϧ†Ÿ (Î|Óº~þb¡¾Ò?’Ù²[ ´=·ß)$«´[kÓ;fzN[ à@ŽHÓ;&ÒÉôúåR2™î=¦E #‰PDâ ³…Âa„vy…¦úœ–/EäôT6ܨ:^^Ÿó ‘Åh,f×Ö#ž3Æ"Bß`~KŸ“+Ûç¬À Aš/ j´œÜÍ»×qš¶Ú«c;ݶgG¹Ž€%•ªÕBûÆ„²@X@h+8’ű›‰T:"5²]•ÊmOþíýîÒJñï¿ñ~ãK¿36¦–Ö¯‡5urfúØ?¾ë®/Ô—®J¢òÑO>qõô3?~õÜ÷~üì™#]ÔqÖ£ñd)»yVh Ðê¶8ýÈî~ôɵåÕN·m¶Z_ú“/¿üÆáoÿß÷o–‡’“»÷ïôâ¥cçÞÚPè[º~-Ш&”/]* à"ŽVŠ;Ì\:q²Zw"ŵ[ƧšæêÊõU»V½ó±ÇíVùúÚ5þ¸wû-‡—Nıº¼Rè2*75²õù3jÒÈ ß;uã仆1¹ië¤BV³€ œULÇx8×A œ¾4'' Ö$X‘DȈH€d¡„\Ç×LO!„IpãPÀ ®ãC z!IAš&+@C‡_yñÖûž¸ý¾GÏŸŒøT’EYÕE%â¶Bä # S5@!†P eB& * ~@9@"Œ€$bÊ€@È!X/Á¼1©zUïBÃɆ;›CÔÃ`q{¿^>nŸ‹ ` pØã”2„QO’G‚P)—5ÕÛµý–€«rÀY`{”sAuê -Å"Ì ~ÐËüPÀÑ÷^zûé¯üž°›?¢žoD³å¹•¾±Ñ®i È–Ãú3Ͻôëÿã\/`¡ˆÄã„PñýÕ……üÔx©\ÈÆ=ßB‚€<ñþ±ôt>•ΚŽ+@\étbjÈumÌ«F†¦²ù¡­k€qàcGNæÒ"€0Ø 1º¶´Ô\,´‚’Š–®/Žà¼åö[×Ö¯º&Ð5œHF7‚<Ç]^YRûãÎJŒ¥!F“›÷H]¯á1;|r,Wë7bɰ)÷ĸÓìxAM£7ΞØ~Ë6Ï– Ï’£2¼¶c’´·|æúµµ&¾j§•K/ÜÈÇA*-«éh£r™nLŠ’Z=:’#ÅrTJf«€QFr˜ 9”Òµ š~à $h̓]Òq·MNüöŸþ™‹iÆÈ~û»s×.îØ¼Ý’€BÂJt¢°v½VYǘ04Nn²Ðë‹b¿¥XáX"öùu«]<Ž9w:,H«ª2—Tæ&§r™h6«#Ãß®lÚ6A:‚¬ ;÷n§ª;йëI#¾ ˜‡°g;ª(´ }ˆš£ý}>Á¢ï ŽOßþÈ}ý)èt¤dl÷ÍC/¼ù£·x«µtéÊ·.ü– ˜&ÍJäÖ}S£ƒ%ä„Ü΢sâíC'/Ô2a°ê¶üŽìV€!³,j¸0P˜qExò_8|äøä覎ݮ±Z­[÷ç@’f’—ç/ %ǶnºVþ`vÓÌÜ¥µ¾ðé÷ß{·ëvË¥õ»?òÐü•믾ô¬8hÞ±÷À»ÇOç‡6-\Ÿs”NµÞô|¯?1ªDB„‘FñFDËb`Ì*ˆ€8¥¥k[F4•"µNÉq|CÝ€b!À)œR,¡€p cyÁ%Ì0 n Æ5àÊo¿üRv$·iÏkžðùt~Ѝ?7¶¾2¯E">Cë…µdÓõH_6Ç×x¥²T0;-’VÞm6½ÀR?`€Y–É  ŠBX–T‡°Àµ³Zf3¢‰bJ¨ï¦éO x×ñeÔM›Ç IDATF}×ó½€F…ŒCB€cŒ1B(!BCBhànÖLܼLÁÅVO]ï]¼ c\ؘfiiø3þ Ûðr3ΜЛ¬?òÞ;GQ¬?;µ™€x¾'G˜å[Q%E1â= QŽ¿s(9ßêû^$)k//E'6Aê wmOFte±é׃üø¨ãø½?—º¨]_ÕS©Òz)1˜k7ë’$b ‰øvSVCXÀ/<óÒoþÎÿt  ”aÀ¢‘„Y)éÑÄúåy” ]bC‚’uêè¥Á>©7!„l¬A;v=1”I‰ * 㣹ƒœwÛ€˜ÄbÆ7Ÿ==‰t_XŒÆ"qAzD±±M£íÅÕêR«Ój›R‹¥RYŸ’aÌ—°"PéãŽzì½¹ƒ“[ù ´\Ÿˆ€Z‘Ÿ^üñÚµ…¼·òCÒ¶™ÝnϤ‡Ëó7FwM‹7ÔЄÖ]£]×L•Øv:=T­/cÊ)âF(.ˆÜ7)ä ÑîDt"PÖ%c H ò¶CðûÇâ×®WÖž|ú šªSÂŒHèÀ=÷¾úÜOìÝÃEµ¾R@ªœI¥Kë+z,Á=à™k±x6JqFE¶Y#¥Ëœ;{éÖÖZçäñç-JãæýÄPn8ÑŸH‡ó® D®ˆk7:µõ Y2Nžx_^»N„_îã’c…0¾º|E@8žN˜­ ZkÚvÓ L—@DW(öä°Î© é2d0`|x<ÿÔÓŸžÿpÕvÖ0ˆº~ëÒúR{e~}¡^å®Ê„Û×Í{yvfàÞÿè›JFö8c"gԙݶõ'×®¤UÊEž”´k×çß9~LQI«¶²F” ë6ï¿ý›÷í‘)¥cµFsWÖJñ¸¶^ ˜ç æW씊ããÃå…BTC-3éy$3Ð'¥Õ-æGw}ñÐJñÒžÛoG._»Â †5ˆeÌÊŠâpDZtC"”™n“R‚&"”˜$€À£P "àQŸHU0 >¾(I Õ †Æ¦ß?yòÒésF*:»mï•ó§mË )¹2Ìf9Oq$VKE–ð¢±t¼¯Ï÷Ü®ÝìIÜ–Õ%AM¤eIk·qˆPฌs•dQUeUEß#$ðƒ@%Î@8V×*×Z’äH¤gƒð<ê:žã¸~àœaìõªå8Œ2JpŽ0ì5 BÎ„à €½âœ›¨« 2CÏ¥ÅC=wéÏÐŒõÎáÏ Y7çâ€C΂fÍòœÆ­=Ì€ˆsˆˆïê˲b›­ˆ"ž0ÂRÆ)% €3ÈÁ‹ßúþcŸBÕ4·Ûí™Â!‘t r®¦£–çª!92žùîÿ÷ù§?çy`aÌ0Z[^R‘`¶×þ”îò&çéþ,ðxaþr¤?®ˆºÝZ±ÖøôNÇõ!HÐQ5ÌÎhW†ñBýêæ™YFÅžA2yaá¶;æŒp D!ì²å•Ï+]©/UO½{âÁÇNSÃf#Ù?PºÚôº­ÿŸ©÷Œ’ì>Ï;߸ùVNÝÕ¹§Óä< 0ÈA“H‘k‘%+Y>»^ïÊGòžõÊñˆkk%­¬#Éò*Y¤dŠbDN3Î`òLO‡éÜ]U]¹n¾ÿ°ªAºûCŸ®SߪÎ{ßð<¿Ç²õ=Mƒ`"r¸Ç¹4ò©X H¾ùâß=ý•µ#Ç—BŠ Ta:MÙƒ‘ô·]LçBl‘.—JX ݰI¨vüK¾¾¶Õ‘‘Îi®”QlCU5pxÎNÝYÛ°>‘vÚ °±–°@Ó0Mݸví¹gN#oNt¸Ò ºÀUî…‰»K‡OÎnÜØ>¦”4´›éá¡oýÕןøØã\\ž?ÿôùòØ8 D(¾ðÒ[Èç7._»_ÙFX†Vë9[/¦3ZÖô:±¡XЉPÒÊÛÈ,I‡¯,ÝÓM£Þìšœz÷â{ûÏ<ú¹Oþ:aI¯[«¬5ol¾Ä ŽãF·$3©ÊJ[£¾–†3Â餆³‰°¬Gjœ”]Æ•ˆhƒ6Q”ÜP)—-Y ž(ä:½®ð|®áÐR°í…å{K×–n»ƒ)帿¥çL‰ò‚âAׇ†‡¦ff‹““ãA}{pDxÉT"8Ë7ZËãúCy|yg³ínfèP;êš`•K©åÞ& ¡43š-OgÆn.¾q‹«~âùå¥áD*e¬_½wè”¶´cyë«Õèìþi_²b2}æ±óa«÷ÖË7µ¡lw9( aÙèF #av+ÛzÁ&~¬*|»Ö8¸ÿ€¤úâüuEÑq©áX  2% ¤ê*—ÈëL©ªhq ’ Õ@0åˆIÞ—B À8ívKI&)U5U â^qd€w·.\øÔøôÁS7¯¼%æ!çq·ÝÌCO¬//*3„ÉÜPYo›íæn‡B×qxhz#Ä¢!„YGÈ¢²€¤óŠ®V"pzºM#f²(Š¥DX*ÛºRÈeã8&^G±„Nàq.bÎ)˜PÎY1Ƙ¦ @ˆqNâb ïáÔÑžj´ÿ·ŸOˆ¤ÜóîµZBJ¹gŒëhd>óczŠØÓÊcÀðÞ{ïäÊ;‘ úÄxI¢PÓT12 3‹¾$ Š=dzRjB·¿ÿÝo§Ê'Î=íû>¸ŸÍSÝ® NŽW¶7“ÔP¨¢PÕ°´fms`ÿ'ûQŠ@(DM˜SÍŽSFöÞ7g8sä¹UuÅHªñÒßÜüâW~&à}4 ƒPM&WïÜΗԭ•­òá¹Âà4ç¨ ½¸ü^ÊȤË‚± +Ä÷ãÍë×Ñ€36uÐÒ5©ãü¾þ·+7¯Íž8×é4³“CNÐö©—0’?ßöƒÓ0Ëó«8Ë™»:3¶¿[¯… —ZaªkYKg*Ûí|y$¢E¨†Išáô\;™ëµ¶ÔBÏûŠS?üæ²cÅò óÂÌd~1˜×u¢!¤¥::Ñ„"tU;0ðƒWo "‘ª ]ß1YÒ 68LJ®æFŒ·Û¥X`\tœj11xíåï}áWutv·Ë_›;’FiÁ{_ý?§ÓY9}ìɳO{õÕ—œ=§êï9нV#0˜J©30ž§k:M()ôÊæŽ–P¹Ë!zŠ'ÌÑ—¿öêÌÐøü½KÏQîdÓNXJ‰©¡ÜÑœ¤ºC3g×7*£…ØH¨-BRvQš‡}:­[K)&XS(à’“íÛó&å3hô‘3¦h«Ý òÝ͵À¶ [ÝF½Y¹yõ½ÏZLµÒ1Y„üDzX‰:t$óÎ…kŸúÊù±Ûîwç¿)?)¬fw Y(¦êª½µÄçž>iĉ^µQ- t÷íÛßQSóW–‰%œV6jØñ-¦DFÊN'²ÝÞF2"šÖÛi{zÖ ¥ëË?Ì?üèÒ» ‰ÍÆ£#åÊj³Ó騆]$"qóÎÝ|Ζu_ò8æRW‘ï¸6µËX``$#EÃøDè’a¡‚”@€Á#(&eø1!á`iƒª)F©W£ë¼wîñON=½vïf§½Ã¢È ¼á²ë8ÙBIbº¹±š¶¬T®4@©U79g‚óv×Ó£XHA(å\ JˆÄA1ÎT¦„-;©Û @¸XÎQGx,FDfR¶TmË £8 B/ðý Œâ0uE€Ç1ãR£ˆª”ΙˆG€8çÂýy‹XîÝÀ$€Ü+G å% úY:Rоúí•6‰ûÿJ!AŠ~û%%hoÖ‹>vú8ð¾¿ZÎÚí-;aww6#‰0„¡ù­—53Î[»;_ýÿç‘§Õ4 õ Œs)‹£åf£šL${u¢+¦n¼þê«Ùbš¨º„0¦ºZ*•!f‚9I{ôÎ¥Kƒû§b©HÕÚ6M¥u+©jä/^ýÃÏ>Æ_"ð[mÁ<›[~}'SšÝZÝš”RíR1‚^x=UÂ'Ï>Ê8Œƒf÷•oþyqØœ>•ÉäíDÊPUÝÒ?ñÅŸ¾yí.QD,¹`éúVµÙqvbO"„ä’wÂt¶JPÃ4”4`ܪT“£ö®ªšZÝíaDlß¾yÓóvüvÃJë©¡ˆ(U©†»^2êú=hˆE¾peËS‚ðÑ™¿}™º©Àwu+ÑèÔ éÄ™™P • ¨oïµFw“+Lˆa b$m¢%m%‹ ̪IŽƒ…½VÛ £D2G±½ØiUsù\._Ì .î\ÿÙÏþRo}äcÏ>÷?}úÑ'?½xíF×Ù!ÛÕ.omó˜wœÖJíVµQ÷;­FcWIçZ;Îêæ¼&áÐ1åR9F {¸PÞ^½ðЩ3iƒš™Ìþ©©L®46t0[ÅÒC™L²0”ÍËž™>40ÿS¦•E€YÓyãÅïø)täÈÙÉÉiÌ}‚äÂÅK'ÎÝöá™ƒŠ™ØÃõI!¢ Hí˶®ÖZ¬“Åo½yõܳ°…!sb(IM%k¸N6[u;£i‰ÕïÝÞŠ†FuJhZv7}<Üœ:1NõÜó½òÆ[ ŠßiÌ( Ë—Þ5§Y¯merC!1“–J»sËeAϳ‹FÔc…ÒS4ƒZ¼QÝà\&²Å†ÓÞößÿöoÿ›ßú·sÅ‘?ú­¾ìµæ¹=÷ ¿1˜TwvÖ7î]Oñäýë—G?úl°#¥ <ŒdÇ=VÌ¿òÁŸÿü³)’X¼q¹ÁÑÜý\‰ëqp|U]XúÖG~î?\½÷ê›/]ÚvÑáÙ“Í •ÎͳE˜Éç×ÊiùìÁØíé"L†*VƒÐ‹, 5;]Ñs}3öt¥vÿîƒéöÔ[ï¼3xz¼×ô‘oÿðeÎL¡ 5b½f³³ÑÌNÈ;;Jóo¾·ÿáý=_ت0¬0?˜,ñì‘ô#€èNeÃYv¬BîÒíúÄ@a»ÛÝ\n´CF¥œ¾÷Ö¶·»N‹c•Ðd*aÛ¦ªjS$1.¥`é:1¶€1–ˆkšÊH!¹àB L¶t•RJ0¦?¡RJÀx@*@ïï0 Ñ?ÓcÑßVýÔŒûø¬þ˽zóîâýì§0F`²ÕØMx RÍ$ %€C¯“U•’e'RÝn啼ü[¿ñh1á{@Ž)…àÉTª6¿Pšãv+ÍÂÐàÈD™`‰¢ :ÄL'¸×ms•훜L°(„¦ææ‚€% íÍÞøËŸtYuêíz¥:š›ëDõôÄþN»Ïe£þG ˆPuƒzûþþ±r"™¸`,:tô$RuÁ¥@¥´‡>ÿÙÊÒö»ßý>~^Î ¹Uwú9·!ï,–'GaOŠ+1Á®ë\¼ýî§&6Nxu'Hf3/Ò¡áýíÖNÄÊDè»w¯Ý_9=à·UŠ1i¶ÚD§Všû›áéCdG”³y‘ìÁ4gTc^à@i|, Ùï PcCt»|zrQÝ‹–VW «›=Ëô8ôN>/±›Nz=ÔXÁi Su? ƒ…Åêö œ&ÄáÂõ›¡šO×Ú͇?ZoµEÿôûõßÿÿöËÏ<ùàÇŸ ׃7ßýá×þ쫞—Àô溯 9üÈÖü¬+†k5VÆÆg>xçN¢0A8/Œ•góA­¾Ù]Ÿ;x¨òÂú|¿õío׃æƒ?ñÝÿ¾öö½|擱øx:ÍJû§AÕó¥Áó¶î‡ ÛN£Š+IMULì2lÌ”áÒÀVµÞíÁðÔ¾•«wÝ ×óEѤœØ#L”Ühj«v?]>°ot€+ +”ÅN¡;7V8qrþv¾®¡§…Öñ;I¢Å&FŠÙdn²%ã0jú÷çïW<‘¨ Þ€Ðžûìé¿üÞ½Á°”ÊgVî:¿øåÞ»¾ÕŽ}âóN Žæ†‡Jï¿øV¤ô„§^©,]àî«2•)Lx¤·³©(š©|ôÄãׯ½ÍG2ƒmÕÎþ¿û?ü‰‡ßþó7v7)yàð;YôëÍ*Q¦©¢Ò¨Í0¦ E aˆqB‘T)ð˜Œuø3 Ê#ÀXÆ2–ÇI+X*R'ˆH)Zž–n¦­áf»ÝiÔ‚Øå—^3rÜ‘ýgfN«lîìvW,‹˜¯-­ù®7sø¤Óñ;õåñIDŒXFX’v­BLMÕ )úK³ˆ…‘çûª¦J 1‹£(D’¦m §‡0R4ÍF ë¡*×£ˆs3NHJ)Š„ÔŒ(FR‰‘Ô ]×TUU1Bˆ=o͇… õ+HøPÐ7 ~ˆrØ‹üêãH¥ÄíÕ*„@BènuëÈcçb 8B˜ùnyî×óDäk¹œ,…ˆo/-§&1’·.^:uâÈèÜH £XU( ·76ÔÒpÈD ”÷ç—Òf6ŸêˆdŸ^ã­N£ÔÆð˜sÍß¾5}pR‚ðƒW¾ùë¿þÏD„$– RucdzBäÚÂûGNŒCÖ»†]eñr§+O?ýQA(0P ÌÚáêöíÂøTJK$ÇN®ÝŽ‚Ö#âî…ëÙ¡k$;œ‡Ã<¤”±Lží8²1isE¨mN˜t?¡’\"]Ófg TæT„9¦)’Ä€(RÞ¿üú_8}ïýí Üy@SϬ,/sÇÝ\ÙÆÙ­»•» )IVˆïûÙŸúÒG@®_áEã÷þäO‰ä¾wñåûƒEH!S8> ùõ‹WGŠãÓc³ó›ó½úîåù[-æ'çŽêI›¤“9™ ZN5Ít"òµáÏí ÿÔœ*u;"ÎäK<êÞ\­o½õµ‰Ï nn?|yŅݳGÝ?sL±í¬–ÚÙZ•‘L›)©ðÀñ =§ã‡zÖN^zë„qe¹þº,ë;÷Wi¥NL‚FÌÕpB±JȨ´vÌl†GR×ô±\2Aðà@~{i{p,À0.ýðjew-µ¿PߎÊI'èFË;ËV¦SJŒgƒZŠÝßÀò ®MŒåÆýjÛ»v«áFjrÈ:rêðîw¦§÷µv*œŠd1éíRS{,È–sq¨L §1}ýÞÊSOœ¾ýâ¥ÕêU”bñÀNemûƒ•c§N^ù³ ®Ñ {­´¥Mì+;råE#D†fù‚úL˜B¨fªŠ[ ª„øa@0Žˆ¤´Ä&Š”ÒLè~$?Ölt‚N7ô|Da´³ºg¹ÓíbŠ’é$V pùâû€ô˜+fÞ²ZiCÕÒ…¬mé]'ôÛ ¬¦7Wk1纕*Uu#Ép”°çsÎÃ(⌙©”"Š#;•€8ŠûˆÍйçõÇ$!E†ª¦UA0 ‚AŒ§˜PG¾Ÿª!”RD‘‚€44+šDû+ {¿xÏRØ¿nIŒPBDöP¡½>¤¯ ù°””Õµ•®½õ¥Óÿ‹D#,… D‘LD^` ÁcJ5 ÀE4uâD$‘ˆ‚N½þÊ?¼üÌ'Ÿ"`" œs×íéÙ<)ÃHQ‘¦)DQĹè¶+ùá‚jX,îŸ0‘¨»±[kÌ~ä"¶ÃÍ­õ©s¦‘Rjж¼x K#?2‡qðÂÔ`€²˜i·[[Iû?ˆCÔs×ïÌ;µQÃ3gÎÄ1â,ÆP,ï_¾N‡"…(Rp ºnàzT5µ¥Íëççži8»«÷¿ð‹_„ÿágw¥¥ÕÆN5ð[Vyjz»Ýì&ê‘뎌OÞ~ï^ä³Ô¾Q¢`·ÚLÛªž,®¯Ô<{|m{µ¸ýùχžm™Æ~ Áp7ö fµ–Ó¨"Üw‚NONÐö0g\(Fͨ³X»ÿŒäíŽCQªç6³é™öꎑÉ2—xݦ]ÎEž”%­_9"RC¡Óf2²b%{¤´ÛtD’c…&T“GôßüÚ?õJÊPf²ëø^Œ1‘ 'ï¾w£T_ïù¬E©òã‘!äµëG<Ö¼·[—Ž×ÚECååë72ù}ë·<Í£XWI»qG®mUG;-ïµï}çüãz!ÊIĈ(Îæ·€¸¹±ª( ÐÝÍÆ² ž×Je MUÁ‹ï)0d ÆsÙÂüÍ-#&`xu}}ÿà¡(2ä!k¥q‘‡]IÑÌÌaÑ …@L~È¢¨Ëk.&÷ \ÑqÏI/´ÊyÕD,`ªÂ ÔˆŽu‰¹©ñÖ ý]}¤tæÌᨔÒ;-/‘vT]g!=—&‰ôhÊÒ[µúѺ·vwbtdr|’ñ°º‘í¡·Du·J¹«ÝÝ-—¢îŸüñ‰¶P2[ÝpEá:ILëv:ë’ŽÈŸ IDATÖ•”Öåå’¼ýâ… ¢¡<’*˜z쨪nÑC#’5Ù‹…´Hâw^»hÅV#ôcm²ÑÜÔ¬€…„ šRïUÊÓiV2l̉”n»e<÷™GÖáFP,¦LË+SÕF§ŸzNí™·î\Ag6ß¿óúødj,—‹ ¡¼w÷z³Ó=V.zèôïþûß/+Žj×7c²±ë¤m£¹ÓÝ¿_"$C»V©§4jZ×_„Pѱܪ®ä­ã+î:Ù¤½NÏš*cÍD7>¸šT 1ÁDc˜‡¾fèqq$"A ’H AÌ¥A±Óó, !‚ˆ@v636qFÕ••ÛK&Áº¢aÛdg½6ÕÕX`•«¡HHÁc1àˆK…<Ž9c‚1&8gža’€B‰ç¢ÐS‰â#Œ1æœá~ƒ@Óu…ô{# KÉÆ’ LˆÆÃU™€IB„ Á V@áŒG¡©jJÒ2I@ `¤P ôCí)K‰°”}I7 $…Ä Â²ø¤ì“fD_bÔÇc¡~„=X†~ã틳³),LcBôã)Q(&©T2Ž]Õ@J,‚„D„ìlUoܹüôÇžÊf œ#èöš‰tF ¤ a·¡gÊ‚(X -ŽfFrÅ\1ŠEÏiï´ªi¬r„%\Á®ÛÕT QE‘’ @Lº­f»Ú8ÿå/ I€`R .a‚ñ}oá±ÃO Æ)"­íZ(y©8øÒë/ýÜ—>)aJ°ë:±ÎG¦÷/¼½ô£…ñ×~SÓÌæüîÀh¾8”—HÒÌØ©z°AÍÌÀè8 !á…!]»{õ–šV4J5JcNŸ¼½y:n[Ñ‘™Ê‚ö@iÿ¡3ÕÍÊÁ“G€JMÁD"À ehn|ûú݆ÓÕl=Õ³ê­Á [:éíÚâX)Å ¶õLFÏ0¨‚’ZREêð­A¸nq4¿íÍs)cÖCJΜT¾djÆúÚ­á©á (†&U«Æû[GfR…›‚Qà=ÍJ¢H¡): Çü¶Ô‘˜‰Ød<0äún¼ðî[³ìûöwþöÿÊ/q5c'“RŠÐõ…t FJHÓ K8<”‡>òõ8p+µZ63 'Hs§³¶´µxûBfh€©¡´$Û‹†Ë…m”ÖTŠÍ$ÂABj®fš² ½}ù„ôšŒãˆyÔݬ»!¨·.–Ï( 4=q8“É‚®™FJÓ¤n¥uUU‘Lä³HÑ0¢t„¥<ÒlKãé ]ïnVEœ 0vzŽ×ggNß~õJ;ìÉÀ?x:?30M[5¿)ã(Q(¨w1´f»uî¹ÝüÌãs¹Fg¹Ýh ?nt¬Ü\sÚÛX¼Wï5u” ¢MÍÒØð¾[‹î¡3G—î^¼»x7««£Ã¹ì€äÐrzÄɼ¬…HQ’ªž/ MËt=P 9$% Ý0Ð %b’0S¡BÄöŸ;öÆÞán:›ñ<—Úú@y\räzÓN² ’ +€B„"&¤”\2r„1¢GŒK!H¡šb«iL°"ð‰$ˆP…ô5’}Ä HÁ8&„RJ(%„"„8fcFHß?ªJ0ÁÀ#À0Á{F@D°±àã\Q5ª+:6Fa‰@¦{>!Ò` }Ø3I!@Š~ÓÓG‘"Á‡q:{$„0«Íµîg?'¸”„ã8f”À°½½•´lÅN0Î(¢cœ*”"´>UApüìãÁHzn*“ER„b+V– RÆa¼´¼8yæTF^wGÒ#nÇU3©ˆÊ¸Õ¥†N1î÷¨I¤`²¹Y+RÀ ì!s"¸»Õ&!@R²^ÔÚZÏï˵6Öâú¹˜q‰_¿ù#c ¬vE<ô€>ºovb|üÖõx‡ÇzP:°OAÊ·¾û÷#cÓè'¨Ü¨Ø… –T/™ÍV3“Ë ¨ã§NJl¶¶W€å…mMèVưº§z¤Œ¥ã/ë;ûÏÍ ›’ç²¥[V»¹ªY¦f¨V!;4–»~çö§ž•+•í|T4U¶ ÚÛ;=£Ð±‘o ¦ïÕÕYd¦2’cM3F…"uK•<®/TʇK˜“n§}tÿ‘í¥,)qD³…‹½D27’ß2®’„Ӯȴ­tcEÆ‚˜˜j†Å½{ËÝ‚»{ïêJa<÷…/ÿJ¾’ôP6›=pø噑¡òžJaA4EÒtZ 2!9h"Eù0˜?žØ B@Œ8¦I+—Î`7ÐÔØ[WùÆ7ÿÛ{ÿð­Bqtjl”3ï½ÿ¾àß Ôé¼vo' s¥Ñ…Õ5µm…¬Ü¯hŽ#LïWþÉ?zð‰çwkw,ÍÚ¬Ý>yòÀ×_Ùª¬jº•HRä©tâÈ‘ó¯¿ö±³ç_ûá%`Qa¸HLE"îÑÁ¼Ñå[£Å)Þè ̘ÕÍ݉‘oÎßfLÆFhHMR·ÆJÀ#o*R‰»1÷Ã^yêPånhò3=¹'RÓHJ†Éc.â¨ã8­í-+c–† ‘8Žg\)¸`qì¹]Îçb <„•1&ïµÚN]ðÈH¤u݈£Ø÷ÎbÆbÉb)…ªš„(ýÂÄ%!¯>‚ªŠN À}ù9òßu:–¡©ŠŠ0.A0É÷‚ˆI)!˜êªŠ1F€Br*%ôM‚}E¹Dß/{¤B’î{›Å‡ÉHb)¹ÂÈÚFm´4(q –“0$R¨b¨\®VvÒIK0ɱ$Çq PR©lüðµ¿}îÙ/ªŠ˜! ^äYÓßé$Ê¹Ø Q"‰ºSY¨ßzrü3<žãö:A¢`øQ¨'Lä55Mé;Ž€¨‚ß~óÅDJQS{/ B‚¡ºrkq`$”Rø¾ïùξýßû‹—)Oì“\b€æV%Ra_jôÍ×^xàáßþÑ<¦ëÆÚ½Íw_zéè§u°n½óêÈçáî•Ê~ñIñc¢Ìv{mäÜ[sádiTOàÅË4ñÔ¾ƒç@Õ¨e& @ÆÎÆŽäp÷ÒÍã Ç)4[›RÌi„¦i"bA¹8lÆXÛþ¢JT3_uzdn¶0˜t0KŸQUu}gíêý›sGž~ìüSéñRu}+“M×»•ÈqZÕêDv0Žy³ÓŒ(ÖtSW!ªãW5%!vàìÑêöfJÒzo­ç”S€¡™”x›¹$D†qÀ4“@3µîGƒ%Ålk H%ÇŽLŸšœ=($ˆ@ˆÀ«¹^g«Q<1F¹ÞÚÝv;A&™Y\»RVm†#b¨BH,‘DH·MÍ6Sùœ|rrNS•nË TL ˆ-ÿÈS¾öÂU;É*!îÕüÉY<=yà+?sêà±s¥¡Q *‰CÐÁó4['RC VI&P°¹q»Óf ÇÐmî6;­Èi®­­¦pú­ù‹)CeͰŽÆæÒÅôæ]¿0,Ir€Ö¢ÔË–f—/Ýyÿþ¥'g}èɧ^øó?=qöY-†Øn4ÿù¿øgÿïŸþylŠÌôÐú­åÕµÕìHÔë@$½ßÿê%K^|§îo™~ÄËwÞ½q±ÝÝ) 4Ú<’*hFoCl³ÅÓûyïîß-v6ÒË.ä±$`àn}iìà£W×¶“£FÚ4,u$¶ÍáÂô;ÜÈÊUu1OHæ{T7‰àñÀÔøüü¢Ô°Rƒ™Ñùîɳ)†©è|-§}þ$A,*÷Vßyí;‡Ï, cP1Q0UÁ£0ìv»Lð¸çµÛF&˅Ȇª›L"$„¦šF¨J©Gj"èõ"ß‹$ç¸àF"e¥ÒRJͰ‹XñÁA¡F2R(U0ÒŠˆÂ¥”çQƱ®QL)& ‚8£Àu‚^Ï‚TB ƒhšÆ%0aJ))ÆÃ×`$A`B¸ä¤_¤ =ê÷o€ûŠR‰…”I 8UÔÚÆÖŸ}ïwþ¯÷»,Œ„„PEb ˆ"-ݺYOKˆ"B M×1àÍÍu0ö?ôìsž×w…n+S¥ªR‚®¬É ’c ;·vŽï?($ì.¬µ{+td4f½ä@³Z3V¨R•è !$Fõz1ïØ“Ïªš.xß1‰[•­ºS;4{Œ á}ûÎ \à^­auÖ¥  )–A,;•ª1®½wåÄÃÇWnÝüþå]ëíƒÏ´Ž”‡‡çNëÕ«sÇO2míÜ‘ñã?æ!K§>òˆà¢•L*³¾^·“†ßö‡fÏ2Æh4k±n<óÄGT¢zaa«iIT+a'ÓEÔ2„R#?HbT§÷ýVw0?»Q© §uW†Ð­Ïók8,Õ+;`ÐÞ®´¹þäÇò3Cx§[­7·8áQ§Šñ;/OÌ©J(iI öʲk…¸¾»£ƒD®:4âlV˜P@Dö\WÓ²O¾VÈUÙkyÉ%ìùªEÈ„‰BŽDÏŦìu‚â@joÕ©`)´Ý¥ÉÒHËííšEyq¸Ü©wOî{¨3/Þ›ÿÆ£Ï|VHµOÞrïé‚A”ÀÀè¸n¥ª[Mà·.zO3ãgŽ~î«_™ž<¢€p'ÍàÞõ«Žç¥µ„0ÐÆöÊáƒÇß¹zùƒZ½=0”ëµ­ 7–/ìP3_g‡NæÚ¸ „»%Gä©gÏ+n2aF5¡Šv¯FAûþ"[MñIÇ<ñÀѤuž „SXIêvñÄÈT×ÝâìÐÀ@Qˆv³Ó±;‡"ðI§Û¡€ `¥sÍjWR8_ìvšm˜^üQãÀ‹C%¯¹Ëæ =ɦ'lͳbOÐ,²ãa°ùùŸû46 éú œØ®mLŒT뻹Éôn§°‚˜Ã¸†_'ˆt\H¥ÄðÔá¡Cƒë[jÚÖ–LQ-_b$# £ iÔì Mfí½èEŒˆª™>UZnì&²ÉŒªU’ùTµ¶Vÿá‡?1Lq¿§ )€ Òíy¹\ª04´µ³8\Ö†:ô…g?­Xƒ™BªÓî4–·–—nmì,.¬oÄ-(—éüv/½ëÊ©øûo¾­Ôk¼M<푇ÆzqštœÁ±„p³?q«”¶Z(ò;N‡GÌJçw+µÄ¸6œMhã–&ÿúµUÇŒc©Í¡J«‹'°éG;±pwcmqwxlçòoß¼ôÎ׿õ72ÌM D–VJeJ÷îÝÐãîGŸ9ûý;ö Ž\{÷Ýú®£©5®yé˜D­à•[+¥¤Z.$ ¸¤µ¥êÔ„yëînÊ4â±ÓQxª¶z½T8¦˜éZ{£V".! b’©3†‡F'ö;wõõK‡Ÿ;¹½°T­oÄqè:Çó#ßß714w) ýÁ‰Râå{CC…òB„ùÑý……L6§¨ºfR‰f»#‘ØÞ© P Ã䡟ˆ#`dmuc£²›a%ŽB7ì ˆ:öv¥^í삌,ËÐM“jJè½®Óê8ÝžK4ðCƒà%¸Œ¢¸™Jû·=\Ã^æ ¢}1Ö‡a9H±ç@~¸*A ¾¹²8y`Ž* ‹9Þs¢¾¬+ =ݲ  d$$°(T4 k´{e»¬?ñÄg:A„~\q‡OcqÇå½–‘¤„꺦¼õ÷N>ñtKðcˆ˜A&™9ÃX†-—‘ˆI(Š„BŒ0 zuwiyëÙçŸS43fL‚D€[;åSSÕ€&uª™ %7®]ÍO妆Æ%Àüâ‚™‰‡¦g0É¡»ÑÂ9âÇ¢41öÐóœ=ùÀÛo}ûä‘ùPí¢UÜzÀüÀ0H²góçNÙF£úU™£CGÏ2F«Õj ùÚn{l_PÙn¬”¬édÆ@ "CL–ý»O+Ÿ¼ ¶¾2uü0óBLA¥j±P PЩ”±cn®Wv»53•Ie@¡ƒã)†…,€â€aÒTUv½w.;ú!Öõ ƒh–*ÂZŒ&ÜÐ!²%å%¦·,}Da‚2h–b—IOEÄs0V¢’| ºL™ÆnËKx(2û_Œ·^{Á6SÓÇXV110xé·÷Ÿ=dZ…ÈFOœÝ­ìÖÚKjV8`‚àþüRk·¶Û¼/} RŒÍ~ò+_ {½»oíl¬5w=Sw߸vkþ½Õ§Ÿípœ£Úýû« Èch¤œšN"0„®TZœË…4Xzo÷à‰¡Dq¿ÚnL>5¹^ë Pš–ZmÕ5…;aÕËL C‘I;sùÊ¿ðËŸ|ïÒµÏ}æSí•N£¾J … 9¿´èG~ΪV+oݳBEnk 25;öìÏžÝøÍ(Må_úá÷ƒ^ïÕ—þËZ-5•°O=pnóFµê¯È•œýû¿ýÆ©¹YÏØ>pêlYd¹õ€‡c`geçÜSüÒ–b¦'çfb)ýN³³½›žA16zÝ^Cn 5¼(­¯¾È."ÉœÆÊ#*NTà1F’;÷€¦Û‹K|ò‰/Ö âIŠQ,âsO?¾¾¼Ø‹ªB2ÎE2m]ïìv77–$–½ÿŸ±÷ ³ô*Ï5ß¾¸¿CíÊ©«ªsnµZj E„@ `{°qlŒ±=ÎéØÇc{ÇéØ>ã¹±!$¤VV«“:wUW®ó×Zïù±w7sæšS*ü©}íZߪ7<Ïs7ÛQŠH*…±¤]¯5Ïž=„ä SµRÙ4Y¶P¬•+Ý®W«5õz¾g&ÊåJÕFnµÑ äV>›T""”‡]¹¹UnxmÚÑ4C!L+IêõV½ÑÞªVkݦia!—ÉÈ"W…¢Ûu›]¿çùI?p€õWŠJ""¤_ ,Ðó© 7ç0䯷ú*)B€RþþÛº%è?k&Œö£Ð2 @ ˆHû5‡2 )Ñ}rmíôî[÷뱸T‚PJ sÝ®i„1ˆ” YHkšƒ üÀ_¯¿cÿéº>•À@3n"öšµx¶Ð(­`Ìüžn%uÓÐh_B¶–V¼^kfÛD¤ôcuܰT&µ½eÿO$Ó£’¿¼væá[>FJ#Ñ ¯¾´ûðaÓ°ˆ 4ྡ'Bõµ ;‘j·ÝF+¨Ôj‰„Q9¿9|x¸ÏÍV¥Ê²mÅ ÅI_"¥?”¬…zy8wôük¯m8¢ŽÍÌöÃx˜iPS%áøH€!IH…¦"YëAs#€ž"DÀpa e[Ó@HËoµ£ž¢†–0Q§´ÛœJ$ZÔ ”A ‰xÆ7I1Qh«:´%Ò ˆî„¡Ð\Ù°AWQ;f:n¸thÏï0“u:¡ðËÈ{ÅüŒØ>¹SyUáxMK­¡S óC05“ó–Dê…¬¿gøò|q,7²çÈABˆš5Í8"0]S•ÍjÊM;mp“ØXZ=wö×Þ\Y/­.¶Î,˜{Íb¬ÛO¼øìÖõÍN©I“X^ÓöoO9qzÛí»Ó³RêQMã1(ŠX,ÍËíàò7^Ȥ[Ä.º=??šöÁ]×#¸~®+ÍkÈ}dôêÒù—N­òPìºuo!;1’³—Vʅѱjy9”ÔŒ OÎNÜûÖ>óÜúKÏ>QÚ*+®åjÙj­Û¨-ÏnŸ[yóŠé¨¹éCí‹^d#ãz:•¸¼ÔØ9QX[}fz÷ñ=#§“¡êÍä’«ÁêH:EöH¡ÐÚ*Ÿ¿øÆÑ¹‚íª^¼Öm^™Þ3¨hvt[$»«›/xbºÕ Åœ^•RkT*õš¿º|¹Îkq‘#Tj¥Fxäà¶œ™¸¸ä«7TCÙ†åh´åK“IèðÄè­·ÝóÒ“'vÞeŇ€1J)ô!2ýP7jå“w¼ãÁ7^xviåR6œªˆM·ÛÖL] Ÿ*™HŽÉ¦]0Ùí·ÞÞ‡ìþÒOýn"çPÍVˆ\Óæ楺y~T*7”M)-‘jþK/~omõÜrm=Ÿ™qfï™}KÜñ=-݉™”pËq,ƒõº!שnèDPÝæ2RŒ™»(µ•Ή$¥J!„J±#.U+¬tÚ¯ç¾ãÑÕŒgϼ&ìåÕbR}ù™tº|fˆ»µXÒ “‰©‘]¢y>žÍzZ°u}ÑÒv/ŒÍ÷x4‹i³ÙMÎ/ì›™ªym1]ìh<¹é:nÐÅ-½•½Z[ýÅ;>xñùj,›PN–)·­Z%WîH(î&§†¦[•òîmã »÷.—O.̦e×CMç›Õ•³ÞØ®í+ë4°tBçæ¶ É×—µ˜ŸÝ;5½6¾vòª/%brv4ŸÎŒ-O÷j­g5=Dׄpd”Ê€ªw¾ÿ½«×+Ë«—î|ÇqK³Y|(D9@ÌMlŸ­×ªož}cÏ-;vî?³S›rƒ^.mŒMuDYAä "”ÒVÛ?wá±{ŽÛfòü§$‹áaèz^°^òvì^(‡Rñ„ð…lwÝbQš¶Y.-¹Q×Ð1-Xkw§ÉkÍ.EÕ¸®k($€´ßÜQÆ)¥:çp3(¥Â0Š„àå}Œ€êǸÿ0Û oJÂúÃAÖͧ±_”qÎdšŠ €EDBú„càWû15ªŸ¯L¤"ð¯<ýÕ£·ìbFúTÀ8ƒA² ŽÚÀ¤”Žmot¶ŽÝz¿ˆ B„¡£ùžï¹|´U6ãN'™t–Š7RçݰwòÒÅ_ù…_Šd?X‚蜽vêco?Þ,¹Ò`†Ó)¬W®ºõ-I 4è…‰”“Èg % ¡ÝjÛ6ç!ñ{!OYí^yjfæ¹§ž¢ãÞäìduµO¦ý 2œ9õR¥æî;| ô½Lƒ •ÀÌÜŽJi#9›)_¯¾öƒïÞõð»Ñ0úµª†­ÐUD¤ óœšfQÔ);㸞ŸY}ùÔ¥Fe#JéwßrdxÇÌïºoiµJF¬]üûÿþ'õ?þ¼º^ýʳ߽ûÈO®$ïÛÿö¿ÿ×OZº‰–Ép÷áÃÿñÙ¯¼yje×g±E˜Ñ{pß»¿öôËo»ë ¾üøw¦§ÝÅM |x~œ’2Z»tuûÎÌ«¯]9°óÞW—0/®œ_5Ü——ÌQWVЬ-Ÿ‰=wöõj¸³‡?¸Ÿhï>ýÔ®c;?ü‘_¸tv£Ñ¾~ç[îÓ8"€@)%¨ú>–CÑxnjø¡}ÔN'83PWõÍ’1sù·Ý¥$nš‰n7,o­µýpx8ÞlzÉ|¼+®žk8 ÛóÂ@IB!“pl3&Á Â3””¤3É\.gÆLð…BC7%Ó8°#F¤mY,4Ǹ©™†Ô6-‹rMQˆ>RÅuJ5ݰMƒ3K×@…‘”Q@JÖœÁä‰ô©Ï„PD¥R@BûQJõµæ(…@¥R@€PB â(ATÀ‘²ZŠ@ ò<Æu ”J(HD#„=Ûw"Õµ~‡H(á@PDžŠbV¢[Z3ò0‰Ò4W¿ñü¡Û‡ês–·½rK³¹ç÷fæç]ô²ù |$@™® ‡«çŸ›Ù;‰ Ô›«WWÇ'Š^·O× ”åë‹Ûv+I@ä‹«‹oºÜ×8"ÌÙõæÅ燷ÍWua ËU~£Û›)Îtª+g¡ë/n–Dcßø´n(Ï}ãÄ7¾ý±ßú}Í ÉD$ô^)³ ÈÍGˆ“›B„PJ‚2©3fÄU™¶•¤íVsÜ*o¬„Akhh¶òúêfweÿîý¾Õ™N­”6åSù !!dtzŒ2Å„©·C×IÛŠPò ×03ºAc¨ÜsÔ˜ i)»¢™±˜Ác”€V÷!é¼?G§}¥K&“J'Ç]Ï޳–Ö¬¹4&-r|Û®Cw¾Çë[ã)ù—÷¼ãžG>ðÑ0RA/Dµª½n»Þí5k˵VkÍm\Z´Ç¤IAƒ„ÒŠIb¤¹„ÜT¡Tï$ˆÖiÔù”Œ\6!ÇÒëíöV©ÒõÄ•è´ÏÂêV;ê–®õ”jw§Ç’©ÜÄ-GONŽ.lC©[\%Ò#?ÿK¿÷æÙ¯<ÿbÕo}wzÇ©é‰=NO‹9…ܸïneÇk+ÍÞæwþ¯oú¸ÞˆÆóë¿ùÇkõÍ_ûߘ>²-‡öéÅ‹-¢©øL¢Ë'GÍ0 Ëë×Ï]?¹mçØft57³mëñ‹ÏßÝwàXqÿÞOþñßÝ}pÏ‹Ï>Ù‹â¢S)N‚€ ÕkoÌð¦æÆwÜ»p÷#lß`£áz¹|ÁÃÀªÐ¿ÿÜ_×Ü÷ì×0uà¶»^<{ÑÌù<ø¡R¹{úùozàX±¸GH€PʪþAõ}Á„H…š©GŠýJŸ9´ËÔwˆnÛowDä gÇVWWAÉVÕ›Êd±¼„Šaè¡/›­–P¨ˆ'tͰˆg&SF/Œ»n¯˜KdYƒé2V\â)("ꜙºÖéy:'×â±SŠsÎ(Rª0 ”:±X1ô¥¥Pꆅ £ © ]C!G@ €„jýÈÑ·P?oÒ¾€(À~ç7`ƒID”a_©EÉÍ~™*…($*$A |°ôðû¯~ÿè½·dm‚”RD!1\ÓŠQM'Ý b¡ž´cš-¥$”Õ ˜j9Τ”c)Õœã†2=ݱk¥M§èˆžKÄýN+$$fj€DJõ¹ÇŸúäßþ’P€œ²FX™™_ßZOeò¨0ìv Ó™I¥eàV¯_ß6»¯/„$A$“CEw ]=2 ÙØÜ²l+ŸŽsÛˆc"*V«lê#Ð~3|#êH–ÊwþÈÛÚõzª0²yv•ÌvqÈ4l¥_ë6#ã™aá{›Wì¥Ê¤ñ k8‘ÑšOHd&°f£zåôSsû +_Y|65-i9Û$ݹÌ4#J(©„]SË1Ëèï|Õ3öªˆ!D(©ç«0Ò¡ÛÛ*å˜+U¦“UšÇeLð Ûó6©HF^½Ú±¸àÎÔô®ÔØÞØÒ%?¬wÛ04‘Ú³ëðwÿí+ï»÷gN "D£\2>¾0±¹¹õ‡ÿùî¹÷(æ™ ç?ú±_üÚç¾x⯥SÓë‹Í»Þñ–w}à§½Ð+]_­l¬^_¾vùÒ…x6;51Ãl}~û®ÙÙí±bŠø†ñSÿ íÿŸ¥€ð‚^Ø5=T±˜¬NR[ºrú×—^øökßXüÖÕ뫦»qð½ïÌFi§ ÷ï=ÚÛp§GãO>úG>6òÒW+›Õ,?Ü[Þy°]¡\ï까¾=}q£sï±;~äý'ž~ú¿üæ'~þçßöÒ5U)—)Ã3{¶ª‡æÝ×Û›õ•CGîjf†Ü¦›´×O6÷=4ÅÅÁ+'¯~ùêßÜû–»í0Ù5½}mñÚ¼=pÛÿö•Ç]¿!ÊR¹«øëÿéq·jã6KoTJRâ(73£öÉ3ë—·F†“kë«fO¼ïƒÿ;Îÿú¥ï™ÚvLD~?s@‚¢Qà1SÇs ¥")¢0]×õ%PJY˜éÔë, åÝv§Z] ZÆ©B­Ó ¡‰XŽë%„HKÆ5M ÜÀÐi>Ÿ·¸WíÅR&iŠV·Ë¹sª†”+'饂@úžO‰”RzQdè:1ô˜ep†¦¦!È(˜Ž÷l…Š3ª*”„&)cRädà`æ7¬Ìýt…T¢_/ôÍ?P®‚  %ý'v æê“À(B¸çõAÊ©nê@(ì7H—/_35³ $èŒTÊ4b”#ÅÛn$}Œj”ÃÉ™’]¾rÅÑåÂÂ.7ýdH«Ý1-+~̉qJ×W×3iC¡F(¨H®¯—«ÊÞ["€"À€\ñ îð±‘à¶ÝëôréœÜX—ÌKdÄ2M‚ŠÀ’¸ÌB'52 èù…᛫k?õÖ+—hLi†~Ð*_Ÿß åRµRª3¤‘êFºUÊ­5È깚-^Ô äiÁfÖ‹;Sñጥ9O¾öøÁèþáÉV£ÝÔí¢È3ÆÂ˜ï Ô¥¢”  U/ ¢¥i®ÓžR¹\$¥•dµ°¬©O)´âšÝ®”\á«°E¤™vÒf†&7VW®l¬†ãóÃñø¶á‰‰íSÃ/¾v,ØüøÛソI‹FôSüq¥Øò¥ó­j³T]trúmï7\ ƆgFç&sz6‘qûÂgÖ6V>úspô®{ lú+o^¸ºüæ«/¿4³°pøð]ïúñþ¿î% 6ôÊ72D@Ñs‡¾'ì†µï½ H"Œªëe*ýj¯YZ^¬kh™ÒÖ¦# *?géÛŠÓócSŠ_/7Â+‹'Ž˜Ÿùç¥|QÒøÌwܺ¶µOˆámÛ/¯ö){jÏ‘vË-תLðçO~í=?ûî™Ñ…ï~õóŸýÚ×F¦†J­úÞ©£¦W \ËŒn^»æäXÂÈœ N½ýþ«¥úæ¥JÆj AîxëõÍ—¯­îÕ;ç—Î/¶ë«ÞøùßøµGÿë;õJ«ÑÎ:äÀ{ï:xÛ_ýÍ?V6WZ¥ë•å–½r¹So/'R#šDE#0!žM(ٺÛëú—}ôèƒ{÷ï»OÜXóS$ë¯,Î1ÍÐ5Ó°ÌPHð¢å«×BÑ"ŒçabF¬RÙ‚"@çº ·“I'ËÕFÜ6A…›V»Õt]ÏŽ›Ã…l¥ ÔšaˆP–k•¤cê”wEI§iF­zS3i.™VÛí^$T iÔ‹¼À“@‘DÂŽ¨¦;¶$Ô B)J)…ˆÂHI¤9ã !R(5l‘€|z ÷PõT73H %(%ª€ô…Y@©Á½E7ì cvÈ3˜¡@ê¢V+¥²‚ôŸ+„X"édò­r‰k‚ 22 ]) T 7½µc#wk”©›s|@4t£R===³”'J)Ù_TÃÔÿõ³Ÿzï>(á&­ [+--ÃI›­ªeZå+‹K'Ñã J(nO£02^¨fgzôÀ•ç/è#Žé™ù©‘aCBbx2Œ|Ë6Îé™Ï3{(›ÆBq,ŠTE¡¶mB7Ï]?tp;vÃ( ¢–Èæ†ÖËåL:Ý,©Æ²ÅDSv‰JÝN@Á64€6¨n<¦Ù¹$ºÒvt;›ݱÇÔc àêʵ‡ú ™<x¡‘¢ÀŠ3c›ÅTŠ‘¾9A'N:Ý-»€!eZPꪗ‚A:‘çˆHËÆ|ÕÎdǻѲ.¡‘„TrllxcãRÆ™íŠîhnH§€”½¶}÷Ø‘w¾bxîÚÖÕÓ'_üÅÿüKÕRç¥g¾DäÈü[Þþ.ÛLlçwm»hÀ—¿ú™é™ÑێܽÿWŽÀ¹×^%šÎ[QGl§göÀ1jéír·²¾¢' 'sóºêÿ™odÑA‘7¶BˆŒ¢ An2¤FåÌ"ÉÊrUçQDi&•¸eÑõÍ*s½XÚ8ð¶}^Ûí...l?Ä®»1#ák…ÙQ>óK26'â±[üÐËOOuÑ¿ôÒËß`Mè™Òñ–¯‹Þyû¾·>ñØ7Ÿ~ê1tÌ;ï<þÚùw W˜Ó‰UõªfžNĦj©U,‹ñ]ó§?ÿ…öÆÒÔÑØF•-½´ÜjŸJØöÊÉ åõÆ=÷¹ç{Jµ«GogióR*¿ðð#ïÛªo½øô·­ÎpŠn­\»pzEê‘ë÷Ò©¸.¼z9”ut¦¤Í4>¹ípíªöâ“oýÑ{gw‰ü ¶D¦óò¥ò3Ï|‰iÎ…W_Èç·,®Çq…¼º²Æ9o›±b @VßÚªn®•*›¶mÆâN"]0;11¤Õë 2¥jkk£záô×7V¨Ž™T"™HÙºæ½È‹Ê›¥f)•0 +nšZ,—!ˆ0lº53ÆÇé3§`JA}“P©$a¨õÝ@pi  I *¥˜Á4@Ê 0ŠJ‰HDR2Jc‘&îƒV *‚Œõå ƒÆnP•ƒ áWØg‹b_ç@A*ÉëO÷LÓ‚ó)T¤ˆ¼Ðݶgg:‘Bd„ (¥d\ ºmN$§T $†Át ™Æ×®¬Ìí˜7¬@T@hÿ¥\[Y[¼zåâôÌ^Bor)a•ÊÖÙWÏþþŸüiŠþelhúËŸÙyûþ¥×NMš@Ë•kùÉѸ“oÔë™l–QZíVz~TS° çw 4i2Š¢¤Å3©<„ͱdaíÚÉbbÆë¢³ç¯Z6ß½s; … ç)Ù³m<º^»zìÁ»×..Ç’š[õµ¼ão¬ÅÍtÿ±l•jTQ>l;Â$^ÎJ!Z‹5{mNÔzeYt=iE~tnYD·¸&®ôé¶9ÒË¥­ry«Ýi:7’NcÍ¿±ÒÔ ÛàD`ÛéHõPÐÀI 1àñ|¦\jŒ¥ÆM;Fl¶u·ç‡A”šÉ{ýåì({î?ž}àmïÂí_!Ó³Sc;oY[ÞÚd‹só;÷ÌøÒ¿>¦rrÏîmÛïÏæF`kõúw¿ù•+×Wî?bèJKˆ‡ª|ýsÿòÚ¹“¿ó½ñD1Ïä“EÓÒzž‹^§Þ<ûÆÙcÝ$Ó—ÿ/+éwé[dÓF"Ù^_ß(o$D›4Òë+I¬m\Óל$BñR}íZÜpü¨YÝò“Z†Ã¢VÍ3 ˆÌœ…–…‘{¡¡˜B¼¾R_HÄK›-Ót~úc¿üòòãï~ð#9â|ï¥g^9qâå“'çS #ÃO_ÝÐÓš£ú~0:ÇŠrË­VtÉhòk«'GvLa¨½øê«FLaúÉóWÎÌìgͪ;Uþì/ýâ‘VË×;u¢°1Ù ?ûÏŸY<ÿJ3ê$ MËdÓÚ¸™ØŠåÓ^£…’*¯O:‰™N}K~îèPÑœùò ÿ|èž#óÛAÈ)U P£´]m>ûÏ:CúÎmû¶f§AÉz­Œ""Rq$ YÏíÔjõàú*(E º¡—H$tÊb‰”nZ¦2Y)Õ”mÄb3n·zA»ÓÍìd:!%”yž«s­ÛiQ¢ãvÌ6M(ˆÐR ?ˆ†Î¹$hšF”EK&cœ9”q‚JH £¥‚ô7Ä2 Ó0„¨"JPÎ eˆ„÷çVêfÝÝ”«þ©¸qV(E¥nÀ,è>GÝqh¦ ’ŠRB˜TC *B©”¢^)k¦ÍuˆˆPBQ‚Ì4Phè&£œåJó:åÔØŽrñÞ_$ZŒé?óðO¿wëA%Œˆ¦®½|ú̶Ó¦•êyAŸˆ ¡Ù‰[·°TLÎU®,‡ÝÞ®}wlnlP%¬­^ŸŸ BA//•¬"Cbq-—Ê»5Gpì!¶iªBZ@Ó1¢•i'b”Ø”j+//%§’•rãKŸÿ‡ÿúm”6 ‹k:3Íd¿ràHPÍäTqTñN¬@L0=3©pâé\×묔[Gtª™®Çžþþ³»÷ÜY›üÖ×¾r”`Ô˾ Dg ¦ÔT~ô”)ý ĆâÉžPa&Wä@õtüÚë'ïÙOl«¾Áì•Ò…ñ耓t"¿Ímö<¢" A¨·þäÃ_ýü£`ƹï}¯|ÿ¹Çðý·Ý¾ïÐÂÈ´»¯þû—/^x=cÏ.Ÿñõßøƒß>t÷ñçžzéÒåWn=rÇÌü|q"oéÓ<êl¹MéwÃzÉ5åÈD!>~܉ !Þì¦oöÔ?ü4M…^;êl¬²%¥dT†Q]©€Ø–•MC¶d-³Ö骦Ƨ·®-iËò… +‰bÞ´ŽˆÐco†V&—Š{$ˆå‘ÑMjÌóÛ—j+÷Üûð¿ø­ý¹Y·>ôЭ·Ü»|íÊÏozÏΜ-{ë¾ÞÝ6ª´!­P½ïÞã'ÏÊg·”îÍÏ?Xo¬ú^7Æh×Õšå&Çîé«Õ kºCûÃßý#ÃrþáÓŸÞ¼²fc2Òí–RR /~,a¹"îÄ šØ\ßÒêr³´4>4’Ÿk2F-Jô0tËÕ+_øúïÛÔôþH*Ö K%…¢}î«yäùü¨‘ZÞò•lq¨Ûî­µt©@ aÛ–¥a*ÄLÌtR™0ˆ( ¦ëN*ÁWHR E(LÝ*²a›Ç——ËÃ>¦ÁrbŒMc¡@Ã4Ó(¥¤’‘ƒ(ˆ`!RBtÃຈ„éŽÃ¸¦ãŒ3!¤ŒÐ5­Ob&„!TqDD,B¡*D!UŸšÓoøoh_6•„QFè –"€„ñ:+ÄÁ)£Lã‹'N%÷'Òæ€Ðщ[vµ]5ÒcáJpôݳ›‹ë—Î]ºwááóç¯ä“ÜŒÅ_xæ„ßi›.Òc uiMÍ#s£6"1 ê:ä(!@€ÛŒÎ €œ™ÐF$h•q+ÌeÒHùk¦uP+¤w×½†“p„’:ÓÏ}í¯ÿö/¾øè·Ê×– ë¾ÿã¿<œÎ1Û-×_zõ™SŸÎíµß÷¿ýø·¾þXe©ôs¿÷±[nÛS_|Ìíµ>ðÞ—ë•Éñ‘PéW_}mjGΉç×ß8362S£Ðp=2_‹ ¿²²Ñj´Ú•JqªhZ±F³Ë(Q\™ñ´uâ¥n»¾¸Z3EƒÄ’MjÒF'iHR솞þ깡¹IUsYLy©mËgΤw UjV.cBLí±nCÔ¨ûqt[ä'Gš=J£™IT˜ÈÎxb±pvõš ¢T:‘Ej1+ËeblbzäÀ·óº¿ïèqñã–€xλ¶ž1¾÷Ô«/V»ŽÓùÑ÷zåüyb§Èfg7§~”Ò¨âþùÛ±1cåòåúòjD=ˆž›ˆ2RJÅ’Ð,“j5(·lDåû¥Ü²xäû€H)eŒQÊd„Š€fè†ej`æòin B9Ó¸¶®iL)BAçCßB¨Æb1[·LB•®„2Å¥”#! €iÂ) £°‹0JçR H)*©|¥úŠ%¢Š¢ ¼oî÷u@)¢ê³q°çH%>B ŠJ‰}÷ÂQ)!£wý—ÿóØ·°÷^EP!¡„„ ÎVi½|ÉÖÆDrF»Ý¶•J”¦ ¬ŸDÚ·á1Bº¶«ÀÉdÖO®ÿäo|äŸÿíS¹9T!"ñN-ì!ÌF  ”ïvc±„è·¶g_|ì×~ç9 Õ d¼^oÌŒMv¶6L=ЧÆfu¦/Ÿy#7œI¦G(¥D"â,lŸƒÁò´[›Û¶Íz®1¶mx\v}¥“Q|‚Ë×^д2i!9€¤ŒWN¼Z«¬1Æ7{Ñ…} M=Þ¨¯'3ýähˆ &v Í€Œ¸mÔ¸Þ»4»)‹pÑ TZw;Aa(¾yn-„ÞX*K°¼øæ®É¡n³zá ?ñ3ïµiŒ‡\®€aDMã¦ü¸fÔÛ®Y@½ox5ïÃN€ ³8±¬¨mH齚$) AmŸ™ÁDTZDR7àÓŸüÛ_û…_ŸsŸHÍMpI¥ð¾òè?}æ3ŸÚPk©ìШxr˜~à½?vêùÀüûÞý#èu'¦ÇË• ¿½ûÈö‹—Ï}áË;ÏÉØö“ß{b³ì&“웋ÿ´¾X¶lãÒÕòühf©»ž é;v¬Y\\1vhî’ÍT÷Ív¹u­q×]ÛZ˜Ì^¯/ʦ²{î2YN°YÖÝ|ùÒéÞ–ñ^£¬LåªWYu“,È¥z[Îôdbÿž}*¥Å®ãµhÝô‚,ÏÙ¦0"±‘²#¤Ö­÷,ܵ÷`Øl´ªõ7^?txqz6ËY6é3øñ·HŒ+Ï•i#ûî£?ú ¦µ¹qö—?úñ¡±©§¿ûäõrc8¯Ö#ùþÐCïØV±n°Uß_=ñ'^|V7ìy'.Â¥H¦ˆPDÓSqÝ—¥m±ˆ1u/5R 1Œ9qÝ¥–kfwlXõdd3Æì±ÉCóéLñ°B¼R÷¹ß¾o4ÏYºÕ©T™m¦L«? ]³­¸$J#‰@ M× ’0 ¹Æå %T7MθDÅ(åº@c„2…Šéº’017Ip¦!!¨$Pª”¢œkJʨ3ŠtC7JTŒsJ) b@˜®sÎã’ª€(dœ+)¥(e(•DPR‚Š„êó+àšFÝ0d"'7U„’<•ô»…H0dR)2ˆÍBPý&q< ”÷Á9 ¡Õnà·~] ) Ie߉Èéâò•/~íñ¿ú»Ou;!R$„„•ŽëÕŠCsR"%€ R H@aLƒéÝ;5´N¿öƒ¯}æ¡&A0B) ìZºEPŠn/]O9q¢›ú_ûÊäðþT2ëû’(„]Âxö¥¤­7Ö=Ìɳ'.ŒN¤7¶xG^Ç»ÞúäW®æS†>*Âptûîü3²íhsí £TêŠêG~ò#·Ü~ÏŸÿá_üûÿýè-;nó$H­š&  !€PBcúµëgÞÿÀ{ 3)ƒ€h@(g ¤’ˆNP’ˆÐGJ…JFŒkþL(œ~ôÃ×Ý^„‘”B^<™Rùž” ˆ¢0@D!rÆç:¢D¥02¢Œ‘¥ûàhMW!JE"Bч …JEBH)T$@)I%„ ¨€Â¡ „*% ¡¬/\èÿû@U €¨PB— àÀÖ¨{Â0úb‡ƒ¸,"›nÜŒýÞûU¿‡Û¢º©™†ž¶3Ù ¥dE„PM×ú#3$Šôºn©´zË®©«çO¾Q~~GkÒ•2J…ˆdà¢l;Eâæõå˜ 1£<¡¸vé‘GÒÐR ïë–ݼ¼R8º×mûa§µYYߨ]œ*ÌçG'P$P+¯•ò‘ÛîòA(á”K¯~²Õ*ÙÅ1è¶S H¿òî7Ì’òÊâj£3¿g¾81ï @(#^95{|O¾XX\_IäSJ(jéÉLæµç_Ù>ÛÇzH!{‹$P‹¥mlOdõPOåŠÐéÕtŸrAýÂÓ¾ìPÝ€©±]Ó;ã'/œýèO¾'•‰CZ8#I¤1ˆ™F6¹_ƒ´2Ø{è Œþû{“þÀ«u"p¥«¹ÝvËï¦òYø˜Éf›Q;Ÿ(Ry^dÛ`˜ºÝ¹vj©~ûʧþÛßl¬¯VýÒìØ® wyi}Camk…Œ?ü+ð·öW§Ÿø±ƒüî‡þ¬^ÔóZÒ?rç]ñÏÿðwN­mì\HGÜÑ‹ª'Ò£*?{<³°kÛÎmÛ¦Øf€{ì'þ?DV2fqD2èÇ[  €€!~H)HÁN‡‘ÊŽ˜ÚõΩ]ÀAð“ø ¹¸têôÚµÍk×_ÙtåáÃû7ý³ž‡þõ_6}~abbaï­o}»®'íP5Úå­kë_üÜ-½;»pÐIk³ÓG4®Ð0W¯^ý½ßú ¾öñßÿêµZµ‡í+×Üw¾ÿÁ¾ýýgžýj¥Mw³Îp¡Þ©·»V§ÍÆ ck%dÔöþüÞƒ¬…_ÿÆ·< *=¥–ÉÇjõn½ÑAןŸsNŸ®Íí™”Ÿ÷B706€ÎBM×™"¨Tà{†I¸’޼Q„ˆ!¡BBDr3ðŽÓA\–b”0F4àœC_2ŽƒDÏ • ê’(ƒ0TB…JP&…”2RRAU(%¡!ïç©KÙW PBûÃ""‚ômÈBDaFQ$„!¥T QE‘ý—M ä¦"Êþèš D:È;ï+@ £ý„d2¯B”}Ö×m…Œó(Šún¯Á,úFj ~òµ7d´1óRFL3çB '“‰ ѹ†”¢”ÈE¤®\¸’KhÔüþ÷¾uǾû7÷,̉a·»qåÚðü¦z¡`”qNtÓQ‚ ”O<ñÏ<öÕ0bQJJ ” :RlªiÚÖµE#Ic…챉w¬·–ã±£•:õú‡ßz÷@=…DpLMNTß\ ôžC¥3š±âi©ªÀ~N4×éÕÅE ˳s‡û×Y?Ñ£Õ«ÎÍì õêæžK×–¥-€°˜a„€ˆ¢nµbÒª7=Œºku~tÒ¯ôB¨—ZºsÐŒ9¶Z™LÆë¬ZV^xö‰{îúOßùêm/ôüÀ÷Û&¦Å SÌm…[ý8 …„@ÄdÒÁÚ?o|æöÎE!Õ ˆgÌJY¦êªœÃ…‘L¡ª¼€‚ø,Pr"×OðÏ>ñ§ß~üñPa­Ú0sñ¢“âC;.^q›ne||øç~å·/œ?{éÂÆÐ„ýÉ} ™Ý*]Íäl'•]¾¸¨'ÍÑɱ ×K{¾A:M7!Œ¡±…÷|àC£ã;‚MÌÿÅ7®#¡4éõ„ï{†¡uëÍnàwÚ-¿ç;q+¡*r} R †&5Õ ÓÖL¨ÛvÜq3†„"åܦ€8%B_=Ô‰!#³Ï&÷Á»ú¿ö[Ÿÿ·Å«ë~îïS;¶/®;¯¼`DÉXF¥ò£ÛwìÊårø¹ÚF&ÆØÙóçk¥-õ^ðÊ ¯>º°´\ÙµóH¯×ÙXë*>r,–I¾ðÊÓóò¼—vbÕZ3椄ò Ü1ÓTÍÅcØóå¿{:¦ê#³?½©:í¦èõL§P¾ºÞët$m|ï?ž÷ƒ6Ãn§Ë` A‚\×!ý)C2–¬mÁ›¯¿äÄbŒr @53N÷SД„s×÷cN<èöB%1 =¿§Z¯×…’š®QT¦ãpn Q¤Q¯†¾Ûí¶#I!”¡ï÷zn_/I }œªÆ9BP$Aõ—c‘T„1J H)¥ì+ï2”’H(PR*B”D†QØ£'@HBÂÄàÓ__¼797{©@_î0 [€R²ß=Ò~E(CrõÍÓé‘|2‘‡›80„h¤}±zþúK?õ‘EQ\‚⺆¦Ñ›vr2°”+d”*‰„ªÍ çÞùãJùôógŽüöÂÄŒ@NDäù~n¬¨ÙI]3@‘ïÅÇÆ¥Cg¯¿üÌÞýû©n0Ð +jÖ“Òõ7*+Õ§ÂÍî•;&ïWf¬tåBn2kpC!hŒ{óÕ÷<ücb°&EJÿ'SïgWv–ù¾ï ;œêTVU)Ç–:ÓvÛí¶ql{lŒmÀ˜‹a.\˜î~3„ùÍÀ&˜Á`<{Œ  ¸ƒ;g©ƒº[Y%©J•ÓÉçì´Özï‡}$O}¬U§ví½öžçÿÔ—¶&îèEF1Ƙ1ÈP7£V°Y©Ž6lmi¹ñ‘ÝGE’!öšE!gvÐjTJeèšSO¼p÷gÞû”ÒN4k±R›ÚPuزÝîvRô,+ëä [ÉxoþÄid³Í…%«®#‡`³±Éì¢ãwÊ{–æ·üK+Ìrl×'›Q © yß9ŒÆ0ÔÊ\¾øê®½Çéº6bO‡1 fâØ·Ó©Œm_^j£¼álýLwøP–:ƒíå7ÝX«c·Üù[¿ý[_ýÊ©Vö䊞—³šõæå«ç!%°}úgüfûûßú¦LÅ¿þïþmÐiO• UÕ67Ö"­v -o®ˆÈj‡+™‘ê‘ûŽÝt×c7ç+<÷ÅêµW_][_ÚØ^œ{cÝ’ÝØÎ© r¢ Å³Y“Îçc°zµs4”ÊÙ­­ÎöÊÚèD9Žr›vÚj7Á¶¢8²lÄck¸â†®¬mÃðpz _Yœ¯ Žx[­\Þ¬–GGg§§ # Áz–ðÞ󱟞;ûÚ³¯|Ÿb=Pñâ6_Y é(NqýÚ¼›Y]Ù®ÓùÜÄÎÉjuÆ*;…÷cõðßUŠÅòÕ¹KK«›ÓƒÞÛßóþþÛÎ)³¶ÕŒzlh–{ÁÔØco<9™)ß÷Á½qál§[Ÿ{üä=o»õ‰'¾Lwt·}’ŽtdV‘àhb$¡Â–yáôš ™Jû1 Dà‰ÐI]Ý1A ×.më…84qZžW_ZöRžc€,!{¾ŸÎd[¦°¤Žâ(èƒ~¯  ­)•Nes9C‰5jõ ç7z=asÁ8‘Ò½(îvß’(yDP†CKZÈhmX_;Gœƒ%2™8ð¸@Žœ€lKöaV€Ú˜db®b¥Œ6‰š¼ßÉKÚ9ÖŸÓ bÈúcwÎÙuv‚a˜D]çñ™~ü CHÔOñêlÖKùŒÊ&ºH¬=DŒëd—k§ßùÀƒ ²È€A¿3a˜ÌôÑh…D ´aŒ!çÐYogÇs®]Y™³m`Y®A " L3(d „¡ØÄnÚQ†ƒÇþå‡GöàÒN>¨f‚®òD!Ÿ;uz]ÑÕû¸ÛΔξö†WpÒ¹‘„{åBxôÖ;ƒ˜Y‚©à ·ƒ+{3{£zäzžÑIgN* H“À²¢F ,ÅRŽ2‚0ŽõÕµüp9“I7V×Ü’ÕÓ½ læÝ¼1À-¯ ‹T×V×ÇGFÜ”£ƒÂðDYc7l²&_¡Ýƒ£Õt¡èîÚ&궇2µÕ¹n­.¬b>¥ †K©˜…ëí“ד8áòù‹Ûa+îm€2}¾ànz~þÌé# ‘K95Ú«ˆHcÒ³¨HØùl£±‘Ï)!ƒGŽ Œ>ÿÒ‰™±âÆvkmó’TÔu?ôÑw ì˜ùO¿÷ÿri84ÊLd¥]Î ÛKç…×SùüðÈØ‰§?ñêéƒ{÷=øÀg¼‘щ©i/Æ,,ÌÏŸó¯¾ò¡aÙkÇž›ºãÞ[ß:öÚ¹ñ! ¸ÅH¦ÒŒâ|)Ç…Ë÷RvÏ3^* âXGÙLÚ€4ÚB߃¨kˆ3£ºµv5D]ÿåçNêúV”æy"ùë­¦æòéÁzç"ÉQéÝ{öq攼Lqt¢T~×ýoßô.KçzJ-NžÍMy×Þ\›_¾Ü¨·A#OE3§:œ¿pú·ß* ¦ÜrËÔ΃C¥Ò@þ«_y$•Â=Gm7º«óWÑ+”wÊõ • :Î[gÎr±Áâ+¯<ùÏOJ©n”i­.¦‹Úáåæfq43œ:öìc7:sTi]¬ Çš¼sVýIÝ1'âR:Lkˆ ™ÒÚɦgo:2¼{—Ö1*†QØê|ãù?å<$ÔÀg‚1Z7‰ÛRøa µ1b²HÇFë-À™V ç(Â0îE¾—vmÛ1DœCªv«ÛõÃ()†+£´I9VD`HŠM†Zp™„–2ÆQBpÆ"XB:¶…‚!±D‹ƒÀˆ€¡ë:)!Iž¹¾V` ]ÏLb‰úÒýh/Ä`×ÁXÉ‘ˆC&S­œzöâh:me]"`ÐÿY®÷ÄÃ_I•óå=P‡¡²\OJ’Ù– …´(VFkD$0` ù/~ÿ'Þû­ Óé¾ëÃ÷ —ÃÓ ê­Õ\)/¸ˆˆ )¶¥[¨"·9±ÆÖúéË ÷ôŒ[Z ‰T(…ç¤S&¦Ûï:8°s²à–/ÏŸ+ì(–*#ErZû[˱Î&·!Lœ~+tJÙX™N£ž)bm8#K鵑#E¢ä’@­Ýh݉]3 $ÇK§O9¹´8à¬n\Þ9v›Y §îÝó—Σ¥wìØ…(AJQªjDð¤söÒ¥ûŽ¿ b$?¥VV6¯2š2àzÇOBl@Jàbuþb®2Ö«m,;±U”å…æ¥kÛëA·‡(¨t}ÚôûVÎ ¶™êê|a´wµâ)Ë1h82.‹¥I`€~𻏥¢^$[±¦š!Í9Æ™TÿžC¶ïèÏ.5ÂN­Ö+9Ä-“·½÷?ø±'t瞉ËÛ­z'Wc„'_~fÀÉÛžß9ûç¿ý'ßè›ú©û>õ¥_ͧ†™Š_~ùŇúÎZ¯³wv&-œŸûÜF§÷YvJ¸V&•EΘ´3ÑõÉTr'…>!2D\°ä.ÆÐ0ÚÂ`¸µ¹b6œ µ¹æ"Ý5 ·a½Ó F‡œK88ìæ&37/Î-æ ÖzàwÞ:«9/¼˜¥žJñÇ¿û§wܹ7?¸sÏáÉJuì¦ãŽÄb¯µ}ùâ©S/_üÊ_ü#ƒ…Lnæ¶[OïL½`)Œlœ=ôÐ÷ºí“ðË_ÿÚá»>û¢ªwpdOudè'^ýò¡C3ožãõnwué¬ ÎÞÛGªÅ‰‡z²<â†¾Îæh­ÝÍ0çìŹã{nçŸ-„m¿þæ™Ìpõ¥¿y±¸ëÝ¢¦)„CE¤öE’Z+K t,Dp”iƈ¶#µ …€¾J@J¡ c úSª>H‘VZ $Íl!@‚ T:N¤Â2VÆ0c0±øIR\ AiÎ WÍ(âHàIN„€sž$BÄJùAh”­É0Æ™dl)l)PH†,–1ØR #+9£ú•¸®ïGêDþ¥õ öPèÞgëo’"¢@Þml(å²¹¾÷”10 ™Ù]G˜›$‹q)¥ô¶ŸÈ„6$¸H\=€ÈÚ[\õª££œ`es“‡rm»Wò‰¸Q¾mi£“¿³½rAd‡œr±Ûñi›»2IeÒv¢Æà~»±|mÎÞµ•åÃwßìd«KϼECÛÕ¡}`t¬ÃðõgžÞ{ôpb!FȨ¡Ú¬£kqÛµ½f»J;:6©<ŠT…b• kž£ì Ìl,®)­Æ÷ŒµæÙ×vßôß}ú{w¼ã¼üüC»öœÜןSïúebkdXÌh°˜k„gëPùõn”‰<§Ä­»dD:J»²º–±ífÌÚÛV~p ®æE˜‹"ª·É$\ ƒ ½°´0Z™ŒMÇÉ–,ƒÕѰv››ši xßñªC‚‹T~‡íð+O÷€b©Š;Ðho 3l ¿jC82ËJ/\Y®Lf…tÜl³k*kó× wžéÙ÷¾ýã+—~øà—~ÚÁë×NÛCT¼Gÿî;›ó§ÿï_ûõ÷~øCÍvçÙÇŸûö?üÅ`¦ðS¸êàmÜvCŽh4!çHq䄉 ™ˆ4æzeh’»HC†q¤$* #c4PÃåùì ¤Å:.·Ña9«Ó¥¸³åûöñVk=hw›«‚2*Ø~éµËn{c»ËÓèøDz`×^ÜG1ï¢Ï?qeq»»¸‘Ÿ°'öÞv×Ý÷}êð-N¡¯ûW¶.½öÂK_û›¯Yb6>ðáŸüÁ÷428ö~ëWÿú«ßÚºzí@>¿oMª±ù7Î|Îý_þÚ·¿ñ/~ôC/=ÿìb--ŒZm6œ)9iDZQ=2Fx’ÂîâÙʽïÛ31Ê8B¶U¤ëÔÅ—¡Öʶí‰Äa/£¤]!ÆÌ£¹@H9ŽÃ“A‚2ŠH´¥£¢-æ¸6Ä©H)…@‚±ˆÐ¸ž°,—m[Ú®ø!(Mˆ^E˜¡jik«ÇQÇ–c2ו*Ö®%x…q¤»~À8iã½È 1&ÔJ2ŽŒFÉ{!0‚s¥IÅ:å Ƕç†À–Üqldˆ@ C“´„}‰;c ã<é#îZÒF ÑŠ1Þ'©!$îD Zí+Ë‹ƒÅ|¹0 Ä ‰VýI<ão½qò¶»~)¥b˱4Æ OŽEêË%4pÇŠ»õ·}âmqbêÝrÛÝùRöá¯GÜžî†K¥ÉiÕi3ÛƃNÇ« ÎÏ­OÍL\½:¿ïà“Ï=}üø‘ràŽz IDATÁቤ$nŒíY]»éž;S¹zúLuoÕ+î7Zß0¦qßþ‡ïþÚýA¬¨oGO¾uº0–õ»þµk—K£Ëu9—<Âvk« ;¨óÖÖ¦ízue Vv)4Úù™‘ÑÙÓžºíý¤ÏFÓ…êÀ,˜zÂ'x2ÆÉÃ0É‘ ±ÑbàôºKV¥dG˜.¥¸§‡«Äa÷ÎqЋtÔª÷6–W• zsÛÞøFc©Ùè4ÚöÊöšå8É­”+Âø¥ê”Ö¡ŠÍkÏˤ+Ó6ŠBi´^÷8H;‰ Ëçò¤¡±¹%‘¥‹ÅôÄôÚò;fÞfåe+hÙÝRO¬u"‘ä8“|bb *êø´ÑÓiVý£_ v§«#ÖƒŸ~ŸìÈ«+g¹ðwŽÝÔ[½öô#´ÂèWÿà+#}ï;ßü«?ÿϾë¿þ¿Î Ò†ŒfL“s&›h‰Ôôƒ(Élb@šHƒa‚Çõs±Ìö•+v™1^n­/­uj)J{9‰bªNÛ°¸Ù&`Ón5Ú*hYû&ƃˋÙÊÐèLšw`rÞɗ)wuõÒòչŹkñÆz= ¢«ÁÔ-é©Ù‡?~¨œÍn-¬ž|øánŒRöf§÷ï˜|àþ´øL@ñ™çOdœâ‰þûÿþgÿù¯þðk÷áÞGÿNœ;}f(çm^]:~ßn<ö•¯þÏýLJWVæÈ•÷xßOá3Wßœk¬nþ¨öH&«R.H䋟}îß.°•öä¾s¯<óÄü™ÓÀ\‰ÚªätÓ¶í9"CHd„”¯>óüsO=T©¤tÛáVs•/Žä«CÌ 3…¼ãd³lWZ–×k5€± çs„€iCÊÄJEB .ìXk&-†a¬MlŒ!Ä( M:“o7›*Ã(6FkC)׉•fœñ^§ÛüXÅ ‘ Á bµ¢8ŽcÈ‘ 1^ŠŒÖ !Q`9¶åعPJ3É9"ëK¯Ðp&õ·y²ë¡ƒI !²dbÉ24‘a2dI4#24€:V…‘¡XõWæÐHÚöÅÓ§ÿû~zaã{ ¸ø}hõÚRÞ-?væ™ÞûÎó'¯¼ôÔž:uBf;¦ÌJÍ\Gµeyе9n×½ô~æùgÿÇ'Ê;³Vìi©GgjÐIGL„ÖLEÑž£ö;jƒ<êõWŸyxÓÔ?ó¥_ëú’ÅÚ²xHš ’Š5‚‰cˆ•2*#HdÈPl4Ea€`Èa@D®ek:ޔֱдV •å¦ •€TEA…šÈ<Ž•â„Ú¶åwU¬dº`ºCE±ŠcÆ0T~¨¸1F)Ƙˆãȱ,),@Ã¥D†–ˆh pÎÉh”œ'èäÄQJˆÔ§î1†d(ñ³þ¬,z¢ñ!£u6—ÛwôhȸÀ¾%Ä0€^½wþ­×쟆riCÊ€c9FÖ¯²8^_¾ƒ1DÆËxoýàäð-Ò($3Á´Amøç?ÿËW_xmàν\“-íPn€CÜé6ÆÆÇZÍZ:›»|î¼ »Ó;‰ˆ#[½¸2uôÖÌ|ãì©—-æ^cÿ®ÛŒ2¤(Øîúá&ÏÚùÂh,]îÙ¶¦£ €Ôçëµ[¹b¾µ¡(c †Rˆn¯áÄ R‘ÁöæÆë×îÞ["~ÁöîBŠaÃ_ßaŽ…AÛ°8j†kç/U²…l6{ƒžÒkgæ®NïÞŸ4AÏg†7TTf±&`À°Ôd–›ÉgȪƒCÌDZÑj˜]˜_ÔKs—væµZÀpO×!cvÌNr¸šv²ÍÞŠTVÉËä3îµn!ÃC+µ|õ\fì€ÏZ%wŠ#jMÈ€q`aŒQ´qùÚèØÎ‹ëÍÝ,†”7§j7·­œ3ÐX]ª Ž£†‹GîÝõä^O9<Îdh‹R2"W|þg?ÿÆË¯wjÑþ]÷íÚ==wõãá™…­/ýÆçç—N<÷èï¸ïàñÛµ¡XiFܲ ã,) ‰!G–B xŸ1  ³Õ$Ó][4iþüÅå­+ c‹¥cÝfÜó_ÜĢݫÐ&»³¸d¹´²Ú0²³±á¥<2#:ón&WÎWG‹ŽëfJÚAq'°9kÕÚå›òLÑlÚîÖCpãµ¹º¿½zyõòøð¬ÑøžÊÁ»°m+eeνuê+üw_j¹9k‹ {€ÊûF+>óä?þÊ¿ÿb¹0váÍ·¯,^Ü|å]÷ìåoþ㽟¹ÿ¹çÏ0’Óc³…‘†ß<~÷;ùÆ÷'NŽÍÎþÃWþZ:ZZ¬Z¶Ò†ëzÏGž¤ñ=ÓR§rÓÅÆkÖ¥k/¦Ä@S¯¤S)m4#MI&âÆòÒÚÚ±;î½üÆ›þ»ðÏß·}¶}ñì™Lf‡±oa ÒµmÆ8’±¸0BrclË1Éõ×ÊuÇÈÐI§9vˆ5€AÇé…!ôŒ%­X+Ò¶,›;¶ÇZ)d Ýõ;Œ1i;HÚÚhC`Ð!à ,)µRȵi{R‚ãpÎ × ’œK›#0Æl! €A\(­ŒàLô‰1&á:¡“$M$‹q27DˆÉÉÆúƒw"ƒŒi"ëC– Ƙ‰Ôµ×ÏØÜ.îØƒ ö‚A:—3&éf ï÷e”ÀÆ ¢½Ü¹Rs&÷j†]Št.—û»/ÿÏ_}òîü?î¸Z)θ±½ 9c\ Î7–—òùbud€¶ó¦vÍœ?{ʱl¾cks³X¬À•·ÎÅ©z^VòÅ1ŽðÜÓ/|é—¾ÀE>Žx2Æzk~n"k7Œ¶²¹œ1Ä¥ »znGFë¾4mqe¹»Q?pôã.D¥‘L/(ì’\„Ðô2C½ŽtÇ2–gÁu[2Ã|-e_0Ÿa@Šý.·ª†ÀFç·^Oƒƒ{†€³N¤lb–`3•õæ…=öîÀøiŒ)R"-2Í0?’Sþ04B 8@3£¥):ž‚¨[_ØŽ¦:Ìʆ€üºª„ …Qqp„psÆ€bR8Ù|¬Œï›rqxqi™sb ,×M•(!@c-2àûð¿¾öõ»fï»ïö§žòò¼P™yââcw½ûèÅS.®¾þáÏ}¶TMb–z­Îɧž¹û§ ØcŸ…¼o»nl½ñÕ®¯¯]Z\ßZZínôzáÕ³Í_»5;×ÐË×½ÂHªÎ »õK¯´ÝFM–âÆRÆM­ÖEÎi+–j¬…|­aF0•aõb>¨±ÜÁáísbr—SØž‘!¹4g3e§^ð ^s½ÉrÖÈÈþɃGœB9›ùõå \˜;³ÿøÇ?ø^¯à “švsÖXÅî4¶»mæÖ¡‰ƒÇS®Œc•ŸÎ¼gö£Þ£¹ærÐ\Ûš¿ùæܲãÈÌ_>{muõ±G6à¿uîìó?¼P-…Úˆ>ÓvQؽ¨¥Ñµ£°ë·ëáxýê•©lö§¾ðáÿúoÞtó¹L¶&2N*“6Ðg§PEQ¬AÑØÔ䇾ðY†Ýƒ7U;žÍ»FàrŸ¬Ø÷9ÃÍåe!¹2†3Q( P臽 ƒ®ô2Ùœ´lÒ¦ÛlD:ÎdÒ–›VQéXJ¡Â¸×i…Qh[2•ÍsÛaB˜(Š¢¨¶±Á%G†B0@a´!¥[½†1„’§Ò)D–ìM굖ѱíÚÒv…(˜ìE¾"°Ú–%…`ÂÒ ã2Ö†´ˆ“áu·3cœˆLŸz=Ùùzôöm<@ ƒ5IÃNüˆÉ°¾Ý¾¸taâÀ¤Å%‚à&)ù!áB`ˆŒt̸ˆMlÛÖ+Ï>™É3 ,‚B"JÉy}có©'úØÏNÊ¢â> Î%²­Z­Th¬¯e*•^½÷æ™3;ÍåòH# F&UÌì=x¬¹½›Î ?|öÿêSÝfÔ¦v¹ÚM˜€‡N>ö‡¿ù»¡‘²°ÝÞšÚuX+‡Ê«dYd€1AÐh×2N!‰¾/eµZ݇#“¨’‚y :»÷O #6ëåÜôÕ¥ Ó‡'³™<\ÏÙéÖVȤLË;‘Å©bÚ9 Rqi´Ô W)e[\r%°g¢N¼ÑkŒW'¬ÔÕÁ‰ñ¥7/OîllÖ-ÉÂ8†È¤bP›(«‹1·! 'T˜Ó6¤³XF1,ên(ÒÎõŠ˜@CaÕ\Ø8çæKLÔç^x+{ßa"n2œûd FÀT:3¼s/8ÂÔƃ°é¨Á¿ÿÕ¯æ—ú'ßýÑó‡¿1P¾Ø˜õBëÂ]Gn;·xåÃù™t®b®ÕÒ²F&'q$2(%2üñÕª¯.Ï­´üŽ´àÙ'Nn._Ã’aݬÕklxÛ8 ¶ÛÝX¶ÊX(66ƒlZ®×zÇf÷ë`1’ÑHÙE7Ûi¥‹™˜g\SN/•JmÔ»LÇž+‚^´Ôlo«Ý®ùuçÄâSëÛ,å·ÃAÐÍ¡áqe9…œÈžª ';T´åððx¦èîžÜ36³waé/]·xçã{Æ÷y¥¼"#¥X»B·ÏÔƒÕíÆ•Á¢¾¸pî=ïüTgáZ‰¥¢­^=dG*£¾øÙ_¬.´¶gÆgçÓë ÖE +àèäÝx&Jé±éW^?# ¬´Ú_}=]´3®»äw¸Š¥Ô‡ðŒMMLO7VÖãÈç¦Sóë­æúj«¼\ØõDkk{}i¾×iŒOï ‚€Ù™¬ˆùÕ §—¶ÖrikrfÖrs^*Í8'm¶æ7^}ãÛÃÝ{v¶-Ð&毾ÕSÍB>³kßž¢3Æ„mÚÍÞ•¹k^Ë•J.WdÂÃp{­¶¼¹Æ98®òËËÄ‘{Áöv3†˜3Ìa»‚¡0ˆ4i0’!–ÕD†‚3B!øõõEé†ÝxÉõ‡[ý¤¼Ž¾Â¤[$€¤úþçD.0ùEáÌÌðÈô4cŒˆ€êd¤ jr‘ÑÉhL Ét|áòÉO|æg8 QZH‹qá:òÏÿèOß÷¼í®ûÃX9ž­ŒFƒA}…KÆ™LJ\ÈÚÂÕ¥ÓŸú¹Ï†±dÀ ì „ÞٗΆ396;œ™/œå\¬n.ŽOÌ%c;¶ƒÀ• µ¡~@ J‰ë—¶ö¼mˆ!Jϲ¸ÓêÖ˜#ëf+yÉËÉr½uòñ$¹‹!'ð;má!'W*æºãç2i ÿ“œÊÞ ‹xlŒ•ăØ £uÓëB0ô i»1ï¸ä¥ ´g|ªSkƇâ¨K–v£úÆ‚ŠC!Ë Sk훎º|öZ{®yïñ{†"åí½í+Z:¶y¬Qk"ù8Òs+oez¹†ÞÁØ®;Xªúí®¡‚ÞÜò℺I0ª¥j¹PE½®„#¬^ŒaÏéÔßüõ7yäŸxjìŧ.ö¬ç>tÿo}ëŸúßÿ=‡§û6/B@²=wסý )n·u!gQ̵o^xþ¡k׿Þx횎j-ù˾•oίÖó»«%{ôè¾ ô«3#ƒ•±á{Üû¹tSn–[€ ¥#m+Ef@‘bÜ&ŽÜÐI"¦‘qBÀŽú¡ïÙ" LÐlG¶×7;Íõ¹Å+Ý­ÚÒVkknñâü¢Þvö-=öX®œ(¥n½ùºÝÝøÖ§ùçË#‹÷ÜuG&½ƒ§$Ȧ9x’8§RlçS& ½”óÄã?<}uÞûÁ#™Êj.{çÙžÝ5ùÚ_ºãÎ;>ùÉŸýÒ/ç”+¹ÁQ)íØj[Û—æ³%fÙ²T®¤³ù^³»Ô[\ZÚ´5â ¹ÓØj¤Ò¡ 9u` u#ݱZ›¿JÖüX¹š\¼êȨŽ–dˆ*V±Šgn™Òrš1a4XÒã1ã[¡*4ôüúµÃ·^]ÜÖR¥”SÉ燓Ó*)…Š;äÁ›§QC¤8¸iAû+ÕCí2ßWÙLþ†çp³¶VrãnÇGUßîŒ2•R45°±qùð}oïĘ· œlµR¸°´ê2&Êä½{&n}î…g¦«ˆláâR YõÈîùs+_øÅÏ;,M7È{?6a}cûôå‹kÏoT§‡›¥Ý»N.çw¸æj{§2•rá}Pºè÷pfçL¹2LŽœLp.8'$L"(‰úïÐëò¿wô_h€l0}ó+ÃTÿ¶§þÇa,žŽ$˜ÛASG“E­^;îÆ‹gO¿ôúI[×ÇËÑÉÕ…µó×R¥(—¡®“©ðÅ=GÑ£¥ÁB~d´’Ø1Î%Œ3žN]=ûÖ·ÿñ[€N½òâû?ð¥Oßyï-§ß|ü.Eô{¿ÿ•§ÿúÞC»þêÏó»Ê)[n6ü,·zq°\Šs„Q+Ü̳‰gž;åG~FM•Kϱx·›r3¹^#¸tñBmmc0åE®rìjÙ¡4X®bZºnY‚‘¶÷â#¬,Î2Fò‰ïûŸú%Ë)XÆzíͧzACr¦{ôæ«o ŒMLL3ŠNœ~v~ùŒBº6¿2»¿64¶›ˆ­m¯œ½p±«ƒ@™ízkimuÏa²,Gõ¥«kÛízX¡”š–³n*5‚Æz«Á{,““Ä™í¦z­°ÙîÔ› ßôJ¹”Q¡mKq£¡Ùìt£n.cgA¤Y’7Ù×1p2‚b’ÚG}tbÁ!`HÀ¡ÑÄØõ0!!Ä&þÉ_ø³SÚ(vÝR‹ˆ¯m¾yê­üâoþCŒñB?„DOd€8BØ®ƒë$*WË‘ëWxÿ'l'¹BI¥lçäcÏÜ÷‘;*£4 QÏŵ…K&æìq£ ¢ð›ßøú¾Ý»“x845ú©ÏA2WnA¸{ÿmó×ÎÜ{üâ+¯íÚ¹;æ,›Ë¾qvnº5ž<`ÆZ†‰ °mÇâ²­zQ ò©räŒiÕíÆë»wycma~!Sέ./çRÅù•k^Q{VÜ'íB`ÂÍZ½dHÄQ=`Ø‹ŒÐ*åqiãÙÙ^°È3•ó4b/NH‹»¥LƸþƇsëòŽÊækgv€;@¹‡1)¢@dÒjc³s¢}1[¶ÒNVu;ÆB LžÕêgÖZ‡î2µe ŠþöQë¬?þð#?úßñÁ¯køÓ:`©¬µ¹Ö|õÉÇWŸzˆw›S{”Ƈ›sÍÿö—ÿ-æq§<>„¹Âþÿç7Øj±±écA¬]=7yð¦/ÿñ¯¼µvfù<–ÜüX9UpU…yy ;PÙ±|y)5dÇböáãwŸþÁK w…{©•õ…j®Ö¬û*"CÓ³»†ª£iW‡ÒŽÛšÅ]éòBΖ."·’TœZccsy)¡õb}k˨ˆÚA{}q•”JTízwaþÚÔÎc³V§íÝ|Gµ6À´aœŒ``YÒ ÑQH)À//.iìÏÙ\Jˆ`«Ù ]JaÚõ„äBrdÌ÷uFBÐm Î,aÇ -Á;í^=èH„Ò²…´´!c4Ch " 0I!猨OIZÀ~¹u× 6†IÛ¨êþ[*ÙJƒmˆ·½÷“–,„¡Ï8“ȼ,BÒvs Ú뫅〾æÞœ»8sëíHÆ( R2`嵕óûgî¶ÀU@Q9n®SëtÚõÊŽ1£8!R¯Û;wââç>ýÉ(6x=§LÀľÄY»ÝÊä½í7.Ûc(˜¶u…dxì…ïþûûû±fŒ!LV¢Ûã3¸QÛ›ëébɲRÒµ…Ä`¥ƒîÜÙÓ33;‰ X)¯¬©‘A'eÙH’Éœ!DÉd%³7¢+ܱÝr¡ÚÝ&^ê£] Q§ëçlÞëøY;1 VB–3›¾ò[¹U­9C®cënˆ`1%2iœÚ•I—Úk¡`Í(lû ›qLJÆ¥á) áKk—×Gtl4çF*¦‚n›µ!S­,­×Ó£žŒ–ê00àø¦½´ß\rP·pPLi0Ìbh*#££ÆßZ>f\3Sª-D³ÖZ£Ñ‹›Bæ(Þj„kûØ/½þô3Ü©gIᚈI6éjms­<0$Íÿô'ïûàÿurâ"`˜4ÙI^Òè £…"â,êö:µÍǺ…ož?“O÷©<8Pó»›[$Ø€Lÿ˳O•E9Î{9×ñý´«ÑÈh•…z`8 ”ssž›Ë•*9V̌Ђ[‚g C Bâ(nú‰»ù§ïÞyß»ý˜é7~3öÞ}ßÝéâti¸tணwkA§·tåÜâ£Oý…öç¿øË·ÞuÛz & ä°´%ì6;õÊK“»G À½üô¹ÿñg'_‚ÂÅÅnÚÖin+_ÕZíÍÓg¸L½¹Ü©üH5õÁ÷¼íÕǾµmé9kómYÉŸzå©MÕB¬,ï]Þ® çÇ¢ÕEÖ`µ0¹ox¨òÞôkùÇÅá—Ÿ>“Ì”W0ǨÈh“qlDZÖÇÞú;¿S~ø›ß={áùVSE zMÌ8˜/æÖ·Ñ11C‘+—r%‹1ËÔá[œ=…ª{«š.OŒÏÆù(âèZÜÍI¨^¨xJU÷X>}QŸídÚµ3ù¼[¸çþû[[Í+_殾û]÷wZ½(6Œ³ýÇoyã…;ݺ›g7ßsÕZ£¡ÂÀ) TF›þæŽéêÄô~ÃìN»Å7•Âæ6Ò™RŦÓ!®ò™\*rS)/—-(e‚v+Òa®àt lžË¸œ± ‚^W™0ŸOg²Ù´1DÆ(eÂ8v<1”ʲ9),dŒ1ÆMŸ(Ì’ªJ\ßY%å1–,¯‡à0$v]€LHd K83œ'ó"Îc[Ö«'^¸ýìÌ@ìûÄ()«mjß÷ ¨U,¥C&f P½å•s;ÎTt¬ C âȤ9I£X¦µ¶«#ô–²´!ƒ„€ÂfßüÆW~çÏÿ46ÐÏF@µåUHÅ,Âüh (onØ;ãÇþèÐØkO?½ã'vJy•O‚'ãn”JU‘‘Š¥Ô–k›k\p ¡×õí´Ã ´Ú ‹üÁêàɘN·]Í02 cT§iÙ^¯½m·rºg†Þ% ÉÎI'• *3Te¶e%g1íY2©jß¶Ýìµ·.v.FÍz!›I¥3ÌvÐ mgt¤º|m= n9‰…#VJ™¸“¯×:ùtÖIåýPOÄ&ò ¶à–Í8m7š#•2pÆQGÙr±}es¡¾ti|K…q~hHÖ8{©úˆYÈ”KŽÌ¹V«ëZ~ó6ö"+m›TJ|ñWåб{~ëg†C–X’7l]õ&#„€^»Œg,gä–]w¼ýP6?Ò©ù‹—æ¶¶Ö¢(^[Û€°©l+Åx«ÕÛê†3Óã3»gßû³/UFÆþq.X2¶{| x”"M¹+†dL‘½ë?ÅI&“ tP@&¸¶°ÔY[_Ù^Š¢Èïª8hÖºüÙG^9½õzs3:²w&=P±LVú]÷¿»:8A‚žüîã[œœ8¬Â¶HÇÇÆ>óù_‰TT_ÛhÛ¿ûÿéà^Ù2#YMO=÷èsßyel'M¾«Ì Õ-¼nýU«ºªz÷é}¾ý†çù=_þþ›ÞþÚ‰‘ñìøìøä,Ea|Ûw[¾ø×ùØæÊF®½€{Y!;Zäv¶wo=~¨Xªn5º'Çï9vë¸^ye}©SßBPõ¥e¡ÂüxUÄ*ˆÂNÐÖÐZ<87>;½vÅŸ˜PŽzÝb5[Ú§j÷X‰Jò™LÐëN^(ŽTf%œ1Î$——Vå@µçrù’ô|$LT*˜Öš™[ï¾…-)™1'RÕ™J¦gs†JQ”ô$cq:§$´6Ú–"JT¬zT¾àK›KɳY?—ÍrËFM…bÎ0­r,ËÏúBZ{RØÓ "!Ü+°RSÍõ¿¡§Ž14©Å €€q¾ºré‹}þW~õ—¤U"2)I&eBØRžýñÅ›î9X)Uu\ª¦úa™6½°ïz0€¨×—®tºzvj¾7ˆC£X–pÁá©¥“GQOp‹5m;`€gÉú‡ÿ÷7½ÀbàÐmv}‰ƒ(PŽÈØ~ËÙâNQµ£„“íGó[;/¸Pî%ßh­²™Óý¨U¯•³Ü±ë×:›k×Êã:QåR.%ûÔVšÍfâ2©’Ïg É °]ÉlGp¦5©L¶€L.™ËxE H’DJaˆž˜p²¹Bzž3àC‹¹‹Yh @À²m ´‚<‹Cµ¹~~tßL;ÂjyÚž®T– Ëœ12@†ÒDDBZ’Y†€#4› Û¤,ÅàHÒF¦ŒÆHEÍš’Üvò:Tœ‘ZÏœ>u÷+'ìÞvÊnΫÔõ‘ùñ'¿ñƒ—:^åÌ1D„¤%…d¤zýýÒ'ÿþC5èF°§F½î×C$ê#l)ˆ!ö{ýSW/œ|á ­ÙÞ2)èîŒd'¢Î¶›T¥tyÚ±Âþ IÀ‘ÿöÑzøáï b“úÒRõ'cZéÁ 76:$”+g]׿va½³®²:Aœ/[’ì”B–N g† 3Tµw>Ä…±£¨È ÈÍ`…jNG1f3È„c€rcÅEyHx ÑAŠÎ|ç™ 8÷Ú½¼P­+9‘Ζò»»Ñ\¹bÉvFŽÏï»z®öµË£-³Nîß>úW}›^ÿÊB‚‹ ×ù·yÿÖÎʯÿÞÿžÍå?ûñýûÙçNÜz×¾#wT*%¿Pu,ÇJóÈ€QÚ çC1 w Ã5¶¹%# @BÔ)=I¤€#N¤CÁ˜fŒj Û`˜áº²¸ ˜ÑLP©0é¸+ê l«ÔØmT'ýÎfIå²%™¨ÊhÕ‹u¸Ûëô·» =+sË'rÙ²ëÙQG_ºúô×>õUáÅ/»ÿMÇo=üÒW¿âõ\=ýã'?ôwòG¬sǸ/n»ã^ÕØ-Žø[µ­WÿÌO "ùÔé§ÞxøP¢¸&mYµ ,ž`7Š®K4¥wv¶§ŽN.Æ‰îÆ¥¥S37œ²óÍïâ¿ãfݹÃmÈÚ?&¢(bŽE(0Hx†…ýÄdú?úÁ#­¨ß}Ç’8ðF™$)˱e.†^'Jž֎íE­†]ò=¿È CfÙ@`3Ö¸ªß ÂÐÊxžë1dœK$ƒÆ$Z…í^< J­5"pÎbÄÒ*]Ý1Îi L*¥5ibŽ+3ιà0MT Ï÷Ó[7 ÔF“Ñ*IÈcÈ çbtŠÃmÌDA`€5Bš´ 44Rf<û‚~Žx˜#dª]Êy¹ÿù¾¿xßg¯#C£ pŒ“QDÈÈ g©j^% “\ÑŒñ$ì%íí[NÜ¢c “V'A5R¨Â t UeÈ0ÎI™$I˜È8PÚK—ž]È,ä Õ~ !ƒÈˆ1@2ñHuÒËfz­>0бl†ë¹›vj[»ë“#2“É“ÞÞÀEFfäø¼öòÕ•é)߀Ï96vjÜÁ…á@\ &½YÛì³DØ¥¯ c”«ŒC*¢å ¸\>wvæîI‹‹ùñ¹ô•B¤-i1Å$„ù4Þ÷ Ó¨Ážë3E„dÃ8VÁ¥®3Ê3“^É/Ù‰QÒêîz“7é÷;1™8NÍä€À¢¶gQ0šª¦•I¶¶®NŒ-"ƒ‚#ƒlµØ¬Õw–Wçö Ç' 9WÄõîööæüüb©RôÚüÄ䯥3<']Ì*f‹é…i´ÍJg7ëLf·ÞX¦|¶³ÓX¾tÞq£fŸ2’ðáüç­åÚ;í×T}æÓŸpÊÅß}çoo{îc_ûÿØÿüçÂó  !¯?(÷ˆ¸ˆdRß \Ÿ-¤µ³!dŒ1ÎcPÈŒF×ÒƒX`ÔïÅÐcŠBš!÷PZŒ'¤¸”ãsÓf™B.2`“Ñó¬#´q¢„FA“›5”Èã ‘g3ÉÒêJŒ¢bÉ‘ƒû"Êæ¤iA}{cwimewr¢ºðoW½dùü•ýµ {ôØMw¼èž7¼õ-½„ƒíZí¡O>ø÷ÿãJ#Ù¿ø³ÿ;éòsžîmmºY'Ïò7ßu·'s³ùÜ´ÛëåʶÛëïZ‡Ø@V˜tjëAbåǶ.~oöŽ– Øß6|ãÊ)uúÜéµk;•©\.7nIßbƒ ×.¶.¶‹cÆ)• þääÜ Å:ê6/öê½bÑçÜÃ(Ž’È+ä‚zÓ$qi|Ìò2{ i@ƒ`¡Ç76·‚în6SE̤‹/dŒa¨ÛõÝ„+‹KÅa8ô{qm¢(К´RA(C M·rÔ®k#2Çu¸`DLsn4¥ºi†LXBX2ýÿÕJéDV*‰c$D,Ûi>=¤/­c ,F8@ä`4¢à1eMpn€c6;äfòÇÀ"ÎKñðœ³4;}hÂE*8ÄD«/|æÓÇ^üîe“$±‰w¬ÄCÒŒ¢žŠ!4É×DÀ›/Ùxûï¾21Ä´VŒ… ”t6r¹Hú]¿œY=¿Ü" µpópõÊù|¦ä¹`(ÒW {í]¿d[ŒU*%á±)Q:7Qr]o°ÛivêÕJˆ´‰®^^>P=6;1»^àÂNC4 BªX+O‰qEëæ‡+×aÒhYÓIÅÞÑ t}w¹2½`g}&904 9=P}=©«j; ›[VE3?Ó {š‹By´»“Jˆ iÜÚJ"2È[–@Ë’Ž1Ú ð¡X®<ÊìÖ³ÕQ­€e'ë½ ðrnÚŽ“±/e;%šå*ИÉ'¼ÔËJ¾º~fí;çoìlÔ»[® È*§`óAæéo=¼ô²{/>ù\6cÞðÖ·ÿèKßøÊ>ý¾?ú+æã8Á4J i= ðÅ!âÖCF+@FZ“@B®•1õFMÄÐ2kËךÍÚÓÏüp|a¼b—›ÍèÔ÷µ¦“ÚŽ\¯ö$t[ñä¸ÅÆSŽ;ÊUeŒ\Y_©¯5ûc:\÷¦FcVZÍ…c ùòH¥¼ÙÐ3ÅRqÒ^œ¿YzyË–Yä†cÞ8—…ŒÑ ‚FaÒUý¤2Z®;yëˆ6­åÕÚÆæá›§æô ´{½ýÝ?_:{vú¦ÉŸÿ•wáð[~ñg¿÷ðCŸÿØG×–WÇMýñßü¥ëŒ|ëc_X>{³Wñ-áHKh (.Ž:Í‹%+kIÁ ˆMÂvæêæü=ûLéoÝõ‘ÿ’³šK²]Ïõk—WŸ‹ÎÛÚò­Ëe3‰Ž;õÞ`çÂ=÷¾Ô«’osـѹrޔ󨕰2Ȉ1ŽH¨ÉpF” Ù8³];_Ì».—n3NDiéª ­–Få:^2;z·Ûýô±¢ ‘ÖŒ—R‡±eÛÁ ´[k²,†ZàØ–°lbÈ¥sp.„D2 ¦ý…ÖQ&qlÀp†ŒqAfÜnÈ`JN ¢½¼/cp˜ØEÈ%[~ö’_`ÅñY$–¶}D„L>þíÇF3Š8CRœˆÒ)>¤5Œ&Æ„ †ÈÍf‘ ‹;»½öê+î}o0²0è_AoJTVÆÙË# xз³YH‡4€†€üÍûÿäïÿŒÒ 〠‡hà #¢ŒÈ0ýzßÉõêÍ[^p|s{crl|Åíngab† †&G$N`‚8‰m$Æ}©Ë\ ó%°UßžŸ›7†8bc­µ¹»uÏKNFŠ€ÛKEKÏb4Ãzi{÷Â}/É–Š#EÚ+)Ó 3V¨L÷†„‰‰zN!´™ô €à‚ÐðD#SŽñ•kçæ'³í^ÛP¦”L¬x×jWQ<¤î-‹0ŒDÚ[s†–`íô-™-¤­(q6®­j݋Ѹ¹ÌF-)—ì³WϼL¿Š‰$ äd¤„‘‰R´”™(”­Qy ã~êßöOAYšeÏóÂV¨¬¸¯ùêg?YÎV^óó?÷í/?üø©¯üùŸ}0!ÐÆ¤ƒHÆc clþLÄâ °ի­m÷»õ•åÕ¾]>½15›)WFû+ÊØµ£·U-VÃîÄͳ?wÇ»®,;ÊÏâåõæMíF­ŸËçØnÅ]å–™gW3vu6Q™lÃÝxÙ+oÊMOÂ~ØVÈu£veõüewdñ“_øacýÿ9~|¬0º/Wô&o:4W2=;vÔN¯+„:öKeiÂÝnÌ·®m¶®“ÙwÛñìDfk­ßi¬‡Ipß›_óî£úôSß{è?»³zaúU³EÜwÿë^{׋_jåF80PI̽?û:H੯~ÿýÿ7Xìs7[„Le\76;­zc–MLW*h;Bù’çG*Åk[»3G2îx‰ŸßÞóË‹,/v£+¢]p“îìÍsV¶.ô|©#qöÑÇ{*2ÀÐh"0jøD@7¬Ã:•2i0À\!¯M6Í÷3F@Òt{A¿“ÉåU·j»ƒ°%q»d}Ïh Z)Mí 7‘U‰ÊxN/Ø2Í„ÑÆ@'ŒÇ†À0D.*F˜f£jmH+•$I%ý 4Ò¶, Àá–qHóÉ`( àŒÑžÇj•ÌšOSêR9 cÍÍznŒÝó‚_P:!@>”pݘ…1äȈ:ZŒÉT.k×þäÿüÊëÞú³‰¢40›ÏÛ6ïB¢x "›1iÚÚ\Ë4š14„Œ1™D]‹¹Y7e ¦3WHmƒ^·àHEº0W´ÝüNëÇ·Ù';;›3³SÍZ³]so¿…sfÒ L¹Èݦ7"€´Ë¡°ÒˈIfr¶à ¡3èu.mÍü´cÙQ¬ù°ã0C²†­>ø2"H{¶'DcÌFgÇŽ›Ž\°#ÇîÔŒ«¥}"é(æ–Õi4µkåJ…‚[ð*““»—WüúçßüÆœâÈì`dKoq†Hà 7ìÁ÷Óæ ,`xÑG!RpíUwGî>NÊã€"#XŸHV|Ëê;õN×±¼ÍúùÙÙ*îqô¶¶Vý±¤Û ¿ðñ¯T¦«"kÇ\úFi$…'èE/»¯X™9rì֯ዠZôÇÿD80„C% çüú,UǺ¾¶ÝîÕVVÎyöb²²ë-r¿xÀ±Ø…õ+A6¯m~íϰµ Ê5k 6¬”`2¾¹t–Od¥Xfh2å[0X~ìÙ¨y93ãmo)E»ýÖ TÔŽíq™âìw¯­õÊ"ɔdz&¾ï—Þ<^šÉðå®·qfƒF·¹ræR·yq0~—¥»J÷-ég,‰dÚõN$:nT5Vej²ÙÃvmegÅcÙñêD©8‰Áàâås³•ùÑ_ÎËÂ;ÚWW}ô™/<øaî•&§gòùÂôB5WžÍeó áø½·½gâ½§ž}ì3û¡Ã›­:)íÙ2êôv›$èðÁ•íÇý’9ûãVŸÉårÍz²ï5G²#ù°årû!¬]ZθþÇÆœb~мpl;non_ö"L’ÈHDÆtW‘ˆÂ Ò TX–E(âh`yžŽc$–ôý¼&ò}_k/èA+Õl5¸ÅñõÕµíÛ±bm”2Œ e ”Â6:æ@fe=¯&™à¢Ó‹[€ÒdBÇ’R00vEœ1ΘQ OóU”JCy”ŽUDƒ0` QY–À!Î8M¦7)IïzìÍ0Vvx ¤¢*Jåîi”c@h±±Å}‘ŠÓ¥òÈÌuPG0D ¹ŠŒ‘ï×6×ûîwÞñ»¿Ñ™ÒŠK®” H›Þ`tnJ›áÙ¨ˆ&Žž0QL*&† ¸m±‡?÷õ7ÿôË9wöølX¾@†"Ë$Q4èëXi'Fè$ñ²y½­‹&‚¹Ù©½„ ±«F&¦,Ç2@žëk^*%&îõ¸k¥‰„H„»(¬œo ¥ë !©S2žÍÖÖîîAÁ2Õ*€ƒÃÄ<c°/eV:7rÆ9,?}aêÖ)ÄìP€özÝl©¤Dz3… s\²XþÐ(õ Ýi4|/½$Hƒ!çgϺ÷ )ƒU?©¼œ®+;áúΈaa|,½’^`T»2>yþüswMŸ|jken`ª4’A?f­ÝN ty ›šœL>SÛEÛÔ-—·"|Å«_sâžW­×\ãŸëÆåLGdöQ!775U¬$‡ãΓaÜïî ˆõs£å[NÞ£QþÈØ¨õhÐÑ}$2ïøŽnµ–Vv<{DØjr|Ú1Š ±qf3H¶óÏßséG§úÍv>ûôÓKK89‹Š{•ÑÉ…ƒûßv×üô±NÓn.Ÿ_ê\Lº^ùÀdufºÞêÜ8î'­ÚŽ,¢Œaí¹SùÉÅJV–çfŽ?Á¹“æÏÀ}€«ãˆñ(hÅíÓ~¿¶Û¾zê1 =°˜ ‚Œïñþn-Ö‰AmÈd2¹Œç7ëuîXƒ^OØç¼P,àØD5[¬Ú®ëer„ÀˆÂn¿×©OLÍn^^[[ZnÇ­ÅýûX/ð0ãºLs2ä1ô:®#µNJÅâòÕ«¾ŸeX·˜ðlk&-ɸ\j™DZ’ipm7‰cÁ˜Ö&ID*ÒÁ ìëHdhŒ#ˆô𠃘¢D‡KºoL¡W@¤á‚ÉÂÈ8ƒŒ­ÓÎFc ¡Þ™âPõ)áÂ8É”sÅJ%I”k¹{ðC¿ý¾7H4Œã’Ìo‡A·ÑœWZcº²LG±Q€BJM„Æ0€Gyä½ðn.¬t°Ìöú ”mX`g&@›8ŒPJ‰^ίtêùR‘4kÛ*‹Åi¶§€:­M?Su€íÈ0 £É(i•9qÆâ°ïäù‘ǵª§öB?†×k€òã'FïŠ 4»®uK?š»[“å))÷&Í€ 2|øÃ G$ІPÊØ(Çk´Õo3GÙ–@CØìMÍNõ­^s Z»;ƒ^ïÆVöyÙž6xè4zh[žM©D8mßSIÈé1œ¶M”g‚ÆÎäMc?ò£ÿþ½¸íP „Uœ—ê)›×îp-HFŒ¼A8Þô¾Ú|íëÞñæ_úõÕ¥ÕǾñý[NLýÚo¿{XÌîñµ‘Á7>ÿ‘‡¾òCG­'˳,ý­‹Í XÂlÕtŒŸ‹·7škõÑÉæD©Z¨ ;‰CÝ»À΄PžÆfO8ýLÆé›A8Ð¥‚lúØñEg‘•º;{Üõ+aû%/Óluì—¾lff ܼˆ“~4ȺÖÙ«—kË»Â~y¿Á´iºr‰5ÙN§ùôcßÌȶ£íV1_x¶òÔwŸ0¹”-WùÄ›¦æ÷OÈŽ8Ôˆ3EÖµü’]ØÞÝ\Þ}Öqí‘ùé©ÙYbåÇ¿ó¨/xuf6×Pgª mc;¼xy¥ßmžzô‰$c=ðÀßñî_¿véÒÖÊÊÅS§£Ø¼â¾7:¥Lãû<”>„*Î`?Š3¦øÐÇ?xéÙ“ëZÜ‹kÝ\‰ BNdÆ'ò ȹ©E)¡b­ê»-‡¬ç²¬‚$ðOùæ†È/úÍŽïä’ÖU‚Q&=!lcÈu3ö£œ"¯Ìô£2ûùQ©7$ÁÏO¼Èó׿áÆ7ÿÄ÷àuA¸Â»ºz鎻^øÙ~šÛÂ6n/ìçœü¡Ù Õ&«•ç'VXeJ´jôú¥ÜØr¿öÆ~þ¿ôvÛs‚¥Æ Ñ:qÏÛ¤ðµIw)½>÷‘ýÚgÿ­Öq2%Õhª t£Z’ôrLºƒ^”Å$æ2 Z±GŬCõ‚Ž7Yõ2åÂöv, "[±^L­ È%½kÛݸ½32"›5ð;½BÞ»vzc ë4m5²c4hf„Ž9ÇÞS·o®-};Ý—8ÐÜèLØûŽÎ¾è0öfË¥ÕçŽ7þzÒú¹WOöºõz/j,o_¬_è¶ÄÆî5«”k¬­§ã§žÝöiY,,äsغçµ÷{rn´ïD[ñr¿{åâ%§Ð?f·NK&cÉ7v‡¿òÓAi.çŠûù×¶Í^°ÚQw—¼éÁF#¿Àpb|$K–i7vò> 䪓k°½l6ZO–F‚o=ý×7MTn¿ïe¯|ùýÑ•–_Ö™ê>ævLÿìS?:zdòÐÑV”Ô’Úµ3çŽV=ô¡Ïzt¤B)Ý •Ö1éÝzóÔµ««ù˜[üÙwÿÖ¡)¿¼XÈÊ+ñ'Åtnz׿åÉÈȘ_¸·P-/½eùÙÓ‡n:ð¹O}4áê«î…*13 ‡„eé8ÒÚ¤T dâ$á —hÀç’pÐë’d¶´„`¨$"Ë0ÅBj"@½N{eóê]òÅWŸ}»ÔfLµ‚€G¹ÕzðÕ¿ùÐÇ?ðáC÷90qÛÍ7GcÒŸ9\¯þŒ2ý««fP/]¸ûžE€ÁÝ÷¾ð©|çÒ¹-2ê#ýÌïM-U82äÈ›ßüoxøè‰Pé_ø/ïû“ßû·ýêKóþ6×6¯¬œ9{ét$3C£'Ïm]É¿Pk-8¹öÐs+¿†½EQ B ¥´6d8ãLðTèÚ@D+@4H6·V+ãUfgÓY„2ZrÈYì¹…„ Ë(X[¹ÜbsîÚå±YGå•` ¥äøR dIi¡Æ™4†¤%HJ£9C£´v•6¤A‚1Üg‰Òq¢,šŒÖF©D)ƒ-Kx¶«L*xNWú€{,dCO *–†, |C!9`ÇO<ýèV”ÇÆúí`ºÙ†,µˆ€Î,êë×ÊSó¤uúŽŠúƒ³Oüàçñí6`’†KÇÑH¹9¼LÊ¥JwÞÚc@J!c„9Ã^§óÌWÞöÎ_t´î´ZÙb€1BC)sžY PkGXN6·µ¼†5wCbÃN«±¾¶²ÿè-šÉ "FÒP佚ӘÂh‘F²špÊ1D¤Ãn{dfrˆC’^¯òã Ö¦ëy¥íS—ç_¶ ›:o€ÌÌî#&´ÜèÄ å«³ A Äž Öwv¦œ[öƒ6¼ï ‡@€â^ØW'ÊÓ¢UÓ–ÛhìD~£¹£½~oTX׋iüÉc-]§¤bÜ{ê¤7lj»_Ò0½iw~ëÚ·˜Û¬_œû¦Ç¾²´Îu^0 CÒ‰ÎdsÛëk?}ÿ{E0|ñs«o®æŠÕëŠP“çHGÚt`a¤¼ÈŸU¤Tm…qFpD'd÷…o•¬‰¹ƒÖ¡ƒ·ÿõ+êëÝ¥³—kÍK?þÑw{FÌŽÎÏŽO/¾õ=ÏóºÏy!¸;œ‹}êÕì‘tEâf=²ÜÛùUëºe+b¶å y$wëÑ“'·Ö—ÿÇ_þù÷¿óÄþ“åécs‡æO~áã_ÐQ#ò$s1?Zœî8'7?÷ñ^{É]€ •ãBàÿ‡Ù’-…Pd{ùë£$䯀6»õ‰lŽï%Q¢öÍï×»ëNvÌÄ©ÝS=R`Á‹&f/5ž.(õâÈ‘âòùs÷Ü÷ZÆ8üÄ H%‰Ò$ ·¬ŸœÇßÐ7MøüþqøÅ‚,vv–Oß÷ÝSO~ƒë“¯ `/Üy»µY窙)º=Ã%K¸ð–#û߉<üP«½vâøÍíí±ê$ MUéfæ÷Æfv.¬&˜°ØnÂVCI)²}.»IˆÌ=pȺï-¿ÉyÞN¼3ß?÷¥¿ÿ×Í~ýäk_yßmoY`Œz‘l#Üí¬uÏüðûÝ~CÇ*A1K¢0á"6ý ŠØÈNg;W(–GG'ç'9•w®]JtOÛîâ¥ì¸2ɵ§®~úCûÄ©Úþ¹‰“/xÙdþðßý÷÷þÖýož5ÖÛ^®« õõo¢³ÛufFžøÞòÕgߺ£ùóGŸ<ü–·½ EéXm{{3Ò­ÃWwÚqÖãv[–íf„Ý[»zþ÷~ë]òçï;|àÀ?ñWše~ýÝ¿iââ­wßÿùÏ|¤ÝMV.®JEH“ñs…(°VÖWÇçE"ºíÖµÝ䨉lÇ-ò•±|¹¸uõÚáý™É‰Ãµh)k‰Ä÷5(×ɺùV±\ŠÏ„q êî¨r ŒÔayrfkk{þèÁ¾ðƒF«V__Üçy…D)EԬ׋¤³Ž£Š‚P z~Õ/O ¸µ¹’q¹QFÀXŽ-2×Ó& PÊ(ÃÀ!‰X%èZdÀfœ &Z3„,/…‰"Æ˜ÖÆX T¢8Gb`À"â gÂv0‘B®€¥RïtK”,M]M³ÁrB4HH€DˆÌóœw¾ãר4ª“‘!C2 Ÿßup©´*ŽŒ$qÈ‘3ÖiwÖÖŸ8pû(G ’1Zi(s9΄`jÖâL{áàZ'Àø Ûq]p«ëëŽÞ>66•$ 0ãår”… ÃbiYH™ÄYA£ÌØÀ$ɩǟºõÖÛQ0HÌ£›F»íU˜éÎФÅ‘aœsdfhgQ\ÙúáM‡þ8=ÝoLÛ†µ©R4¹8!sùx·Ÿ·­ô†ÈØ©_åo´è=Ÿ”õé(¥8ìYŃAè¢Û ŸY:jLz­07©•6WÂXÇugÔ";°l[›ÔNðüóbjí‘ìHP«ûþçñ{†¼®8îR¾,ææ Ð¤DFA,g‹`4I GxÁK^óá~“˜“¨®Å3B¨kË»¿ñÛ¿4v[íÝà£_|Ç¥.-š?ró­)Þ0½} B±4½r?\Ë;FkKDñV¨â$¸ÃsI¯“+d×vº>ø?X­¹íä“.ŸŽúØìÕŸùÁ·Ks«ö@Ça³Ù˜(ž¬î´^}ïË›[€˜-Ø›;»c•"‡1Í´—Í7¶ËÂvL¯·¶´Ùis¤\¾¸1{`ìßydÒŸýæ£ß9ýØ·+·.¼ò%wÅý­‡~øE÷=pǽ?õþ¿ùÛŸzË[÷-,vkÁÕ?ý‹?[ÝÙ½rõÜòS×LNÕ×UÐÝøÜ§¾¾tî#‡n9pâø±cã…Å…ClÍ»ÝîúÚå ËçÊ™›¾÷­O¼ëmï;÷Øã§~üÍØâÂÌí·ßÚi·ï|å]­µÍ‹KOo_éxÚÖA(È$Œ›$Üܾêç|Ánmí”K zq¢¥a–m÷ X†¹.‹$á 7•÷G‹F‰»o¹÷±Sß¿u¤MÖ6ÝlR,€Ý–PQ+ÇåÞ°°<2 ‚(ì³áõ¤Õ-Zcm crà÷%º‚±õv»½ÜXÜÞÞY½ëΦÁÝ{I$‚$Ž$­~2âC„¶éV„XŽaé|]AJÃñ@š ¨51ÎJ£å8L¸M‚sÆÜ^g`ŽÜ Œàq¤L0P–Ë&òYß›ËÛ_þÞW Esî¹çF8¿òì©øå¯’vÆÐð)h4Y^îõ¯¿ÿÊ“—µÞ-Ê’muÑ©ô±e¤Šƒ¤\mDÛâ‡Oì?lŽ@}Û±Äú¥eŠ;þò…Ë~Ái­_+³±9ŒUÇmGNÌ™$BÛÂl©l’›OLEblÔÉ%Ø$N±4å²Q»Ÿ$]Ï-ð8š;ÜÊÛ… §ž{æÒ“;ˉ¹Év×–¶ŽÞ}hѽ³ßí¼îÕoF<ú¥¿hœ;î8êZž†©l©rO¡râè-F‰Õ•˰¾¸Ô:4¹Q™Ï­ÖÂÿÓ‡e™/Lì›ÙW.”'¦ößT]88V™¼tù¶ûZí›;|òE‡?aü±|`ÿ‰›^òâ×ýÔkßúÄCß[;w¶ßQ³Õtl{qÿQ­ üÐüÍj÷ë˫žðTW Y&!çÚë[Û}-wŒ*Õ„GZwÊ{Õ¾Ÿ@Ñn}K p¸M¨5r)˜c½Ø@Œ„½^Œáœ‘t]Á¥&ø,Ûá‚!ãÆެÝïpÓôÃб #£¤D.,!…àŠ! I q&™$ÆÑIœ gˆ@’a¤sËèŒ6d4c<6šš½èDä‚3$ΘàŒsÎнÀAZhöòR)0–îéÒß±‡õç|{sÃ/zE\âÈÐ0eœ´¾Ç#e‚Aê6ܳ‡èZñà\ÆõLª[bÀ¥åøÅl®TÆ•2­~gjn?rÔuÂUjq4ÛÛ[;µÍWÌOkmR›  i'‘bB€ÖF–ιµÒCx Pcg­×÷ï?¨ôpŽCªà÷í^…ÈÒä2L³fRˆ8G|æ©'G*SL€Þ#³²a /")-†8èöý ‹ÃÐÊøÏho®må2v­Q¿~ˆ¥žÆ`rff˜88ƒ~Ðó ®í¹dbáK¡DûÒºžš[Ÿ+Må¯]Ú›ÆÆmdž=ª&HçV±ZöˆyšÒ  K)J£G†Á°€ˆÆýKºþë€ !¼X˜Hx'AÄÊeÇs‹ÛEX‰˜‹‚EèúÙ §Æ'K}þû‹'ó‹ÎÌr¡ÑÝÞÝYœ9ÄÒYi 2·Ýy÷»þsô…/}äô£ç¦¦œÞv»×éøY T=&»õÑ‹yÇÌõ£Î‰»î\[Ùh6›•ñüX9ïßrg¡˜Ï³£¥J.W°= “Ôô®<â‹!?Æ&È6rHšÇ ª0Œ“ èå ¹­ K‹‡&ê—¶üΧv¯lF£AÞ/nªDÊâ«ßôŠ“¯¸ß·DØM‚WüôVÏìïüÁÎê¥~ößøÒ·w;Â@Þyò®pÎXÜ?q“¸]^ºÄo®Î• Kç—Š ž~ú‰pÓ³+ß|ïïüî»ã÷xëÉé©s½ã?¿sg½¹¼¾|ï«o/Í¿ùâãßÿâƒÞóŠ—Tož°¿«¢¸aI«²“»ûå/·¤Ûݨ=½zúæ/̈†ùúÆyfçWwwt¬$LÂí–j…k‘ûbŸa çaÌ8™òÈP[iÈhCBó|¥3Ž0•ÀhƒéÍRF4޶=—ˆ´ÖDÄ8ãÀ¢8æ„^wôý¬m[¶%çqi¹($jã(Æ5Ddd,NÖˆ# -0VD„Z+ £ŒA ©µÒSdò0á1Î8Gd 2&(Ó ÎðÓლ†Aª7´€T(WƸ1  a°‹™ 4Ú0Æ€R~ è+qndœ3›Èb¼ßïô£v©R5Œ#Q¢ãéÅ9 ™J€Hã°ßB"E±¾ðÌ)ä|zf>ˆ"Θц‘ ga½ng}œs–â‡Ð ch¨[Û9þÂ(æM{’Êaydhµ:,±­ÃfÛ*û@<ý—3€sKãss\Z:Ö)DcøöFÎ^WjB¶ìÉÀòþÃâ.èìpF'ÆnHI›Íb¡kÕ ãl.Âùv IDATãÜÏæˆ¨“y M$ ª‚›MÑ™R ¤ÄñXutNà…ÕÿŸ°÷³ìªÎ¼×Ú{Ÿts¬Üºº:'uR· IK"c„Axœf<þÆöÛãcðØc=à4Æd6AH€$e©[Õ¹««+Þªºù„½×š?νU%`æ+=O?OU««î­{Ï:k¯õ¾¿÷ê¼&räÊ+É€è×—¡¯Às™dfi¹U.æV–…´òÄO¬‰€º§Ä¸¦A]µë󦂠f¨)íäþ;®yôs_Í:óMŠêøØDcqnp4‘_ô£Ù ç·Ý~ÍbÓ{ì¡G~á7ÄQqÃ&3xÝãã›kÿ¾…d&/¸túøÑ'ƒdÊPsˆ‘-ãC=½ýƒc#®›Ûh&ÈñÒÖ’1n£Ý´¸:·Ô¼:=Õ˜·u*aµÂd"ZŽÑ µ,&¤],óõÀxUoÉV9 É“¶›-ç‹é±ž¡¿ÿÔß æºû¾pâsaCÑÂÜÄDîCòßÊ¥ÑÙs—ÏU&Ó¹LOïHà‹u[¶|ü¯>yá™3»¯Û7ºqÛòäŹ¹ Ë ³Ï=ÿü“O_^>·nlÛkö(•ò·ÜyÇ̹æºu/Í/^5³éTž_®<÷͹+õm[¯½ïë÷ïÜ»÷ñ]¨Í^·ÿÆt*yÿ#¼õÎwýó?þã'?ú;ëví±ý¡Q ”˜[žNªzi.¤Æ7?ÿ•-›¶ mZß Z_üÊýš¢×ßòº…éÙ }£¾UËö¤‘j€R ¥lëüñSÉ~«˜~üËl»iÔ¶³ž}áÊ%/•ÎÚn³ÚlFQ>•»tîTºPüH d‰^:+mÛ2Z3‚e¨F‰d"F» °amXûµ¶`í$/™r\϶l°]åX¶ë‚åHÒJq3Òh+¨2Ž´…jR›™E<Ö¶<ê…f#AB°DDjmIn¶1‘JĤs%Q *D±Ež;{¢XkÕÝs׈ LñŒ:‹0K H±ð46LFR"Ff’@Ö &XJkavæÜä¥]£cçG[Žc{®£„Ò¥$Jˆy’ñœ€¡6_xù…û¯Öh˜Vì'È€¢ÈJ§PYD$„ŒO¨L1G XHñÀÃy©¬ãØ&¤•éM3Ø…-­²Ø¨,0±œŒPÐüñ3»Þöz6 YÑ%ˆÎZ «š/|W 7Ÿ:qEö„€Uò\æ(Z©…BÑÂ\¢¯Kϱ§~p|p_oa`\ kd´H©’’üV;[\j€i¶Jå‘©©KDÝúÓ¥™EMŸ©š+¦[ ‹RÊPÓÚºÔYpvÕsÈ+ëÁnGÊ(Dgc4­«×<ó›m_GI{víø¾÷õßäí )º<ûR%ÚaO§r#©Y˜Þ=¶ýû>Úr3Ï?þlßàkïx#ÊõKÄQsùÁrA `\76zÝ ox§Ö E¬”QÔ®,½tr©YÍ`rþr"[Þ2öþ_ýp£²ô\ðD>›ÒJÙÄ9Ï]8ñ|xã­åÉò€m¥¼½‡]˜üN㢋™Š'ܼ•™Ÿ½h\;™ Ï]n€Ùœ¯zÂʵ97yÑyºæ$ΕŠ#G?µyÛæjèÎÌ^ ÌòØàî'|`ýæ1Jæûj˵R_Ÿ488véÂÅLÎNZ…ùê¥ ["ÁL’‚02QÐl)[H!ó…‚fÊv”²¤´-Kûa˜Iyí ¶­Pص0šŽ@ ‘ QCÐ\ˉ¢Hh°Mè£%¢(µ6‘6B 0Æ0¡&1+d f(ˆ˜ ¶ÆÍ‚âaçPD ±k=3DÝ`ñ˜•Í…‰L¼¹×¡öC-•­XhA08ù4*èï_ç·Úñ‘™'g–•r©ÈđߴÝPŒ¼1ÌŒ ¡YŽT§êR¥¯·H"DÝ©™@Fb0Z##X/€Y³‚ˆØ²±áÃoÝ-4@‰8.ºÜà­FJñôôT2´)^ ±2ÒÁ}‡Ÿxçï~:uH "Bêà\;bV°½ ¯|C\ƒ7–¯ âäBu÷Ú} ¡²@®ˆ9™atÏ8(±Ø¨fOøF’¹jh@±5’ì¹pætݲ·X›}±UYìžOWÕUÙ|¯AFÇ0…^²äèhe÷UD@VBsWÆ'ÐÉÿf”Jz#¹jc¾˜JœöÝFËM§'¶ïŽÄœ‡ƒ)Õ„i6Ì@¶ïÊÒÒÑÓ§œ]›²vy)ðÓÙžÛÞr胿ûGfçµ7Š%¦Ø°+á_B ‚$D+ ÁA5š™¾êäì]ÛnÌÚ åA£ÖN(9W ýö¹és3õÐnú53£eÙŸš¶³êÊô¥B¹”ìïé/¯Hòú¾Ds„ØŸùôÿ~×Ý;wÝzÇþù{µoÜ»ÿ[Ï>û™/}ñé玞xá‘ó{¿Y,ŒÄzpò{'/·xû[~mçþ×;:süð³Ûv`MJ²<‡Òé׌ÜùÚ×ß…ZÀñ§Ÿúì—¿ñÏŸÿKéåßvû[Þôöwê#û|ôèÞúÆ·K'9·4X‚–«j¾òÃó½ƒ[÷ß~CÐ2Ç/Ÿ®,Ζ›-%,•*¹z¥ oË¡u·n}ƒçæ¿ôÕ/oØÒ7×|2]‡¿ÿ‡ÿ9¼q‹¸Üþá+?¼']:9s Êéó¯äGŠéÄjL¹ bÑ&¸Z.Žyéž3Ï =ÝÓ;l0žØà$Ó„877ÓSÈ£”åBQ‚BåJr°ä&ÊFGÝ‘ïÀ:0hYèûmK9íz”vlK“ÑÌ&¢È! [P3ŒÔt[ë°Ý…-Œæ¨Ý‚\& ¢È÷£v[ùmP´‚vÃ7މü ÒB¡¶*)@’†Ù€!Œ´âx½/## ÌñH…`2؉g@ŒãV»{%ì%A ¬,eÈ€&Dá% UŒmA)ËKA»µyß¾0Ô±]™E¶¿Çó3Êñ˜Ø²=ÃãcF… ,…<|ôéZUßxãÍV^Q 3aǃm£„ÀÚR 1’Ö€LÈRXR॓Omùƒ?ÝhÏŽé‘ã­ˆx†„h(c{ùrÙè[ L]™O¤­(,V}Æ’Ä izå¬ÙuÏ­dìÚ¶ï;OÜŸJvEçl¤lÏðÊÀñܑîÛÏ~T>Í!%8R¤š8±nWÎ9zuºçx2Ÿ¶dGó»FÖ <š­Òp6·0]µ¡õʹöºÅPçè‹wËh‡Ýõ u~©% F^:•Èî‘|„6愲œ±‘Ý—/Ìi'p”]ÇsÏüà¡âæL0×|êäãVÙ ­üêG>ô›ý±¿Ø´ïëoúù?¶~´Xì“RÅ\ CÕz“[m7“°”-Èœ;súÈ3O'ó©`¹ÚjVýlæYÇV• ‹‰Á\O>“Éz¥|߀Èc^kò†5ÔŸY¢†›(®ßÝ7:zÈÁ2ÔÉv÷Í·¤£Ý§|i¾Z™«L?ñüä†þ!'°¿ûÐW?ú§”ôz¶¿T]t=/Ém¹aÓŒP¨ó…Tïhbn©¾-ÖÜ’ìî«bµ8 ØuðÐ'H‡ø£/}þŒléÿoýöŸüÇÿ\ìIY=x߃7ß~û¾ô¹Þ¶ñýñ¿ýÒß_=;ýÈã_ìI$ε?ÿôóëÝxÃÒÂÌW¿ñOïøù÷5›­ ‚^ù¹©#?Ên³¼ä )“›7 nÛtöÓ?yúôÑŸFå4_~i×͇†7Ýþî­.,Y­6¸ ;m{­Z+U–™âXʶz7o…0‚P_š~edb›ˆŒ´mܲ{çìü‚‘Òq½ÅùùÈDʶó…20AÐŽ††F­XµšõÅÊ#¢-ƒVÔ¶5·¸`YÔ\h€¥Û&4"h7#MA£Ùmf¡|¿íT*Ͷ?¿°PkµÂÈ´|Ÿe«Ýª ýˆ™‰ û:R‚,© ZoúA ‰Tw7ÔÙvq´ñÕÜEȬäí(–€; 2žëŤøša–ç!sgìÇÕëuÇv?÷Õ/ ÷ž9=3yé Õ_èÝ<0>6ÚŠ¦ÿÍåûßþÆûÿí/'“Ùzeù©‡?uö™{w½öÖ·°çHãM_œBˬÞpîØñoº)>'s×å°³L†ÃV-T0gOìÙ¿çº×4 Ï<óôÖM×ýÕ—¾|èèK½½?xâ»_ÿ×/í¸þ†k¯½çGü±p“Þ÷åÉóGü$,ßöÒžIœùÑ‹Ïÿú/¾ÿïwúÒ´WÌúÑ+ï¾ûOŸ¨öd'F‡/\h½xñéë®Ûzõ±I7íÚùÄ£ßùÆôäãZz¾õäÓý—?ÿdØ‚uª¿‡„†c»·úzÍC0F"MlÙÍ,hd&eÙ3¯œ›­Lj&¼ÄÂb¥Ô›½áÖ»Y«DÂk·BòéW¢PMN]]¬Ô¤4€Ùš¯Ì[Eœ[XŠÚ¾¶]Ñ®µ•ã7ìë0Š"!ˆXD‘¶d}y¹†kQD†!Uëv Ãˆß$&ö#MD–0B‚AÉ•«Hà ÆDçÖŠˆ«ü™.¹€$"ËxÒã WŒ½ B"ZŽå¸»GDE~£ýæ÷ý**%ˆ¢`&)” üF»jI‰QŠŽ I"0Mg!¢pfáüu7þžêÜ–¹ŽçU¹8šÈH…± ” ¡–(¥Tâáï—ŠÙ4nÅ-½"jïüt3€ÓSÓ;lZ«W„‹g_[§óC?åùÉ2‘TÝ-F|¤44Ú‘“ÏàR©ÜqDwÆu+!Ý,6äÖrhK­€etŒTDK‚†o¸½Õ² ¹6ÙRjÍ%:¿ë+,.TŠ…RÝ÷®2~Ò)~µyp¥èâ*Þ¿ã+J®˜V´]Ð?ØßÖÊ’½'£#•…yß Nö‘Gžß0T>|üª kÙ\õŽ7Üõî÷ü;Ë,WvlÚµ¯µE_ªœª=üýz©0žÞ¾óï7{Rù½7ß pH“VZøÃ¸cÿµô)´-ák´–¯Vòýv›Ä• “m³œÍ­ ^ž_&‡–«­¥ùù‹—Ïè–°$äûŠóg/§Ë‰Åe. ¤=aO/4/Ÿ>~a²P/…=Ë=¹¼É5—I×jå±ò…S /úíø…0=úmK8ú/g FG`š,í©åËÇž}î–Ÿ»ã…#Ï8ö–mû%Z,eÓA*# ˵d©PmT›s“Ë^ˆ‰R²Üó{þ•ù<üOŸ=]9y;}££Û÷<øù/~éö»Þó‘üú‹NþÆøÏ‡Ÿùäôí¬Ó ¬úÔ•&´öì9Ð B6jÇ¡‘]·¾éSŸûåmãc}['Žžz:cô™ó/nß½ñü±—‹¥]nÞvòè€ Ž2µ§Î|³Q­žyö¤¢Ñ‘õ°¬-ÎÙ)—Àò+‹¡nA1kÝÚºc·Å.@DZ•uúä™Ù™SvÒ*æÊ'O]ìÎÞt;„lr…‚ ›Í¥(sss­¶1¬8 5Éù…¥Z£¦ e’Îâb˜ð¨Z×&ÐZ 4„†ÂHëz£¥A·üÈqì0Y°B¨5Bi‰0ˆŒÑ0ÔÁ8–ÍÇ’R9R*ËR+.Ewɇ „è¼ß;õ lèê{:¹Ê é–º¸o [í¥ù™ÁõãÆtÔdÀܨ...ÏîIÔ&ö"B'(€ÈóRC#ãÜ #€ _‡~"V`I9ùÊa+!Ò¹|™ÕÁøñÐ º#£·óÍ»Ñ7Ýr ˆ„ÈÀüù+wÝu[hƒïg/^šÜ<˜›õ/_³aüðóÏöMÌ^mVZõZ%-¸p£x^Jf¬3§Ïˆ¨J¬V«¹LÚÊšÓ Úb6—ùêä…¨I!EF‡Âr,¡ÚízÛc#¡/Œ!H†@(7†Dµ]÷TúBå|*‘"â¹zZДѕF»]mh@6QªRk6Cé7Z!"k ÈZ³aÓ¢Pë¦h£•T,°1šÚ~èØ*51³¡Èhl4Û¶ŒŒQ–%•RT|7¢Ëÿ‡®0{¹Û™w Í3GÇÖ+bý2+¥Òù"¯Ù‘ ™Im<°ËpGÄ!=°À\o)‹6Ô+Q|iHe¡ñÈ#xà+Ço»ûkWïÐ¥Ct?Á ¥Rñ‚ϰq‡ˆ2®D/OžùØu7®@¡×@¢~â‹ ôô®ô\+øË‡ì»éúÿŸæ*îÑbŠæª[WX ÅžÌù…öZ¶Ìê«°æÏje&7ÐzÉ$(Ç!Ã-€$ßyÝÂóO6f禦¥- Ó±ýú'žNB¥šzÁM”´o4‘ˆ"a9?pÀÿ{á]3Ãî{ƒ‰#ß<Õ36êR[G'šÎå–ê+¥S-2&„dZæÒW§éßÿ×t¾Ïèè«_ýÊýŸù𵡵mý›ÝñÁ}“'/ŽìÛ´=¹¿Þ ><ü‘Í{wó¾”W¯^œ¼rN W)R(-Áƒ=c=&U,õô÷Û¶çx ×±r…žN‰Õéˆ:ݲ6ŒÀD>üõ‡žüÜÍ×^g5ùjõÊæõ›«sk­0¶lÙÌÚš©×¥"ô¼ÄÜÿsw¿ŽáÜÙ«!G`ð¾GžøP;H@X÷¯œ™nYœ|áùW>ñ±ÏôBO¾/—,¸éÚm;ö%“%'á ¡´EºØ—,•ËýáöÂòLåÒCß~ÀüÀ]ïx¯ö« 0¿ªtv\ñ=!~¡’—híMo“ŽÃlš@aªÞŸýÓgOüð¸tæÜÃßþ2qóî{ßóÆ;ßùôc¶íHJ5}åÌ¡ëom4–'g§¶ï»fa¡züá¯m=¸up`›ˆš“g/ñ‡{nÞ“é i.³ˆ€D$u2Å;Òˆ-WÌ$tÓ¼øô“o»íîM·±v¦®Ì$³ÉsÇ. ¬ßÚ8U1 ÓòÛo¼íž~ôÏÞñ¾Óƒv¼þ–õ£[îûÖ77lýÈ_}Úu2“Ï|óñ‡~á}÷@¹þR6‘*r~³Ú3Ò“^ßÚ–ëOÍ×A,/Ëâ܉³_ûÔ·¿\ùì•¿øë×Ývóëßp÷àÈHd˜¤´’…ì†ÂÞ »ö¼á-?OhÃd Æ3LÖ¶ý›?ÿ̯½÷מ~ö±ßúÍ?Îõ­‹JÍÚÒKþèSÿÛñ*^3ƒùÍן;qêÂ…³oþ¹¯òƒ:€óKü½Ò`þž×¼þïÝc›ÞRä(ŸÌ—<ñ´d±.™ذajêêp¾ìí¥…yn&Ÿ€(ŠÂv³ÏŽŒO„A¸¼xuû5‡ª3µ«sgˆ˜ÀÂt"±\—ËÕVf]vÓø¦ÉÙËé´°¥ Ng’q†Æ£5¡ Ùd.ÕðÃP ¨„kYdˆ¶•eI ‚‰ÃPÛ¶ˆ†)^£9®¥”²•p<ϱm˶v¹ëk‰:Š µ“6%¬š…W.ôÕxçN¸=ãj/NøÂÜñkÒ÷‘`îšaºægÚswÖ1ˆôœ IDAT‡a+UÈ“1 ,–*‡ßz×Û´1«“”¸®Ž÷\JY°rDȆ3™lFQä{‰LÎLß}ýÁx~ƒk¯Iîv¼ ‰ê­º#§•+·¶TIâ6/¿îÿuŒBcÂÞòjµ¦œ¿ðÊDïp»Ö‚µ¬\“Ç?+ôÃÞ‘ÂuSÐ!‘!3x©”‚­1¯<9xòðÉVe°O¤Ÿ™Y`âŸ.|VÞÉà8‰¢Ö†;ÂÐtüˆHpáÜäÃ~ûö7¾m…\üÝÕ v:oNÍß»íÐì•ÃCƒÃ(źñÑW¦jŽŒX€£Œáä¶a§ÉJµüo~å çÎ\øè'ÿ{¶9ø¯})30”þÄ–íŽ7xîèщ}[ÆÂ±ï}ë¡‘Í™[ï~ór½qñÅ“v*, ôß1qo­Q›?q)•âèwø¯ …0Æ\:zvtÛ6ÕLhÝR¯ÁüªÇ.+ÓKO?ÿ¯Ÿ}rëV¿g¼§z¡âå\oÃÀÔÕc³‹>èÐ"7mÜü[þƒ¿ù_Ÿ²3¹Rﯾÿý, Z Ož?üÉþQ‚øçïyHCB´r™Lè:nzÔb\núWÏ_ ` p =Óß=LÂ\ëæâ†Ò¥lõØCÏüý?}zÏÎ×Ü}×­{öJú;=à P3wåÚ ¢¨=<¸ñ·ÿCŸý§þãúõ}[G6oZ¸2}òèNÍ„&2 ?Œˆƒ* îÚqàÄ©+elùå§vïº)™O6|ú¯ó—é;‰ááõ‘˜·K £„-Z¡.ôŽÃ@!· !~»ÝnG~£\*d }­F;Ïçó=(¶G-åDš$Ú¶k÷;Ù¡þ‚eÁø¶ÙÞ€†0m×–Œ“ #­50CJI Z^^n¶ZÄLÄdÛ–‰4úI]С”"Æ Cë!"b"DZ,©”%“ /é¹ÒvT|.ëœòâ­`'jß×c·¸Å7Ù8o¢n·2»æÎö›@ IizñÉêÚ‰4iZe¸u'ºÕÅJ¾\î8®ã6% När¦ËK€o|ÿ¾w࿆‘éêÁ8†‚1&Œ‚´—‰_ø.vQ*`BÅõõìÅïmúP·k\´Ñ ÚÁŽ×Wûí¦ë¥„?]‹¦NÚÓ¿RËþÝ‘LØ–VÊþÚÿµX(½rîÜ[ÞôæÕ« ™Wâ⯅MŸrí\}n6[Ètf†uø?:0µ«ó…á±FšÑ—2‰ä*‰ÖŒ̹зo·T\­T*³óýƒÞPà»o×ñåšâÆå§OÊ]ÞȘ¸Óê÷æ^þfU\«ÉˆäÀ˜wå%Cän‘o…*¥d2[<úò‹'ÏŸúàoüþòeÿØÒƒã×lo·ƒëÝpu¡]m,”FGN¾r*léŸ{ë-ÕE}äùgÚŠ&Ömu’v³ê¿ü½oõÜ”*-E•¹Yj‡¹Þ²e¹~Ë‚VJØGžzºÖ¬ÏÎÎæ½C7¼=a»±,îã%JqùÜ¥šÝ|ûîmFf—– »7µêâì•¶²Aú=%ó$4¤8¹ß–{ñ=ãÅâ{~íWRå¡¶ßüÆçþæßyò×~ç-nzüùÃ?Ú·û&ÒA~``9‚sÏËŽyzZÎW’oT´•XÎG»T¨RÙ…+s*U(˜½¯ÛxÏö_Ȧóñ?þâ/¿ð7xë¯n»ö€ãº T:VÒÖ¡¶< HHd!€Cë|æ¾~wãëm1¼<_yêð犩<'“¥ßHÃÚY7VZšóWë//Œ¯/|û³ÿpãkïüá©ïmšØÅ!†ì\)!f­Þn6%21µu”pìF•}¦=Ï„Úס²m­‘H[¶B‘”ž‚¨×ªLä¸É¥Å º²”^KÃkµ¥L.‘”å¤4…½C£*©¤”`¸Ùª»¶MLZSÌ7&CÄ,„ £é\»ÕŒŒ6Q„L¶ç…¾BD¾ßlµˆuÙ*B1™œŒ!àdÂqGHÛ³-ÇsÕÊ|:tÛ|ÕÉ€@ÉÕ`E‚ݹy%ùaå˜Õ5w¾0snîÞ÷VŠºTîbÑK¤Èx“˜:„JR–zé¹§Þûöß]3>ãî5ŽˆØjV…ks7¡'æÀ³1(…¡xrQÐL¥·Šګ˽n ±2¬E€ ž9ùÜæ‡\7ù*S% \ñ£Bªð*îÝO—-\E‹þÌ_+êÍhÓ–k êhhÍ´,¾HV‰4KÙ|›ˆZe+’{Æ®¶'gÏ]ë9éd8–œ2®õ„@ÊNjòU:kG²\’kë‘H¥FòCgO^Ê ¤JÙÞ.u™âm-vîJñ€,6Hùt!y†:ªìúrß³sQª¬Á`"ÍSó‹¿pï½~»ù¯_úúköÞÚãõ¾<ùr¦ÔŸ-¥÷ Þ\»r5Ðóž)=ñ⺭é|ù•³S3ÏNl*;}SÎp\YÚqëÁ™ÅæÂÌôteJ(;ªÏ]ûú7F æÌÙ}«ú¦§¿㺃étü Œ¢(¾‹1±(„ ühÏ×L]*O;sâ©ï÷íÚ]¿¸X­]ؽ¶˜“—Z-§žt ½Ù>PpèÆí£»ûÓýÙ—¿ü¿þñ¯“V‚šµTïè/ýÛ÷LÏO_³®T,ö@1›¹téÈöm;ž|ð±æpk“Ú<²+ëx}Æ ‡Ï¿T½2—”QóÈò³Ï>öâI7š¤·nÙ0RÜúŸÿàO?ü¡?üË¿þó¡ïö—¶aÇÆ·éZSyª4ÐïØI ¢ÈoœŸ¹úÔCOŒÝ9zç¯õ2a;õú©KŒÑ•…¹…KWíWšÁâT³5¯˜³à XŠBgî$»wD 8{òxÁËqÚUvZÖ•™úÉ—žt² …ÆW ÏvÒÌÚ¶Tl­·¥ ¢¶@%,›ŒV¶¾åºÊquIÊq“™l6“óìDÐl§ ^¨¹ÐÓc[)/•,ª>`ˆDBJÅD:Î'£Ã0~ÇèÈF‡”–ÒĹR“´m×P¬e‹P!%2*‹Œ1dLÒóÏ€–mKÛªÓL1¯òÜ`Å^ €R‰V°IØIUí Ôqå8Øy£ójGÎ,¥uþèÑEªZªÈÆÄÇÍ®´³œd7áÆvò>Ý´¸XÆŸ?üí¾óï5Út¶`ñzcy%6–f‹CcÀVRJ´‰,åtOvðØ#æû²Lb…ýÜÖÆ+þ•xžD"11±Ë¶èêÓWípøøñÛ†WæWüó¯WÏ´xm̶8³ÐnëÆ6À— Ų}`&ÆÉ0‚J8ª @Œ ò[Ä •`iΪW=¥ ¹r ©KO…¿±ú$“ÈhÖÂJTç¯.-]Þº©ÞÛm‚úbÍkå³½1T5þ/ÞÇBÚ.ž™™:d?Yèšž›ì/Ö÷µ[ÍX–Œ´ êíÙ¹±Ù¬ÚÆyÝm×ÿø±ÇGväÆTN6Û-såìdߘ˜Ø²-Nea®aÚýýë}¶ƒz"ëA©O.Ìêù»ù’·sý5…ò`ìª.,å†KCë'$؆€‰ÂÐmH ´l‹H°­ ²´¦/þÍ?Šå«” Ÿ|äÙí›¶ŒoÝqêâå@pZÊÞþâT‹bcæÁ[Þ0yú˜e»ozÛݽ}e;™gårÏüåÅ+sgJýýƒCcKsóõÅÆñ£g/œû»ž¾T>s4\¾²T_ÎBû‚^È·²ÅA#DáÚwr.±î¦‰¾ÁžÜà€Ès­¾LѬß}ýþDÐnpþâäòÙÓ—ýylZå!W5m%[”*Mävîq½>"ŸL nÝÙlû;¶î­¸-=a]¹ºÐ†y馠m,7õģ߻æÀX:‘¾û®÷.ÍÏ“m8µå+ÚO,Î͆<áX®ÛR¸ÒõŽë$µÑQ”&C@ÌRG[–-¤dD¶„ò› Ò!ætÑP$mU.ôö¬syfRJaǸšB&@Œ´&c@+‡™ÑD2‡‘o€HS†Æh #¤¥”¥‡˜€(´Èh( ÍÄ®ëX–-m)‘¬$=ãÝU<¨"ÐÌ–1Ëi¹„;í ŇÈ8R•¹ ©‰=iùÞwÞó_6šD7߉ °d+™y«ë-^ÝM2“²´.]©ŒŽmà•|šÎ95®œœïRÂêæºrŒ„ˆ1»X¢€gž{þŽ;naÑ‘Ås7Þ WާÜiLXB2_¦®ó{­F2^b÷ÁW°™kJ°Z·ñ§TMk>)÷M[y©Ä«æô„dbS£Af¶\Ç0`"˜8A'þSºVÜ„Q¨«Ë a³Ù\j*TE[!£°D\_â—".lêCׂL©bÈðȰ"5RNÎE-Zëþšt{³`\yÁ»Ý¨Í}£/{tÝ-×”z$VR™ÕØ–ž­Ïž=s¾uíÍûªËÕâúþ„åµÚ³}›gNNIZÙ¾aÓæ½õÙÊóGž’FcÊuJýå¾L §ÝþþSlJ÷–2¥¡DºHÀ(1¡’ØŽå,A4j×Ýôö‰köô¤R‡_>–J)év¾Ñ;œ› ”Ìõ.Ö©t&éÎL-~óþïÿæc͹«—výÅJjÈ`ǶÛUlÝ-îÞŠ‘4 êj£‘rÔÈØØÂLûü…ÃLý`ÃèX)µ\è)é&Nùsº”ã…ºJD©"$)_ê+n·¥Ú²w«éÚ‰£Ï=‹²Éä&R’€|ßצíz®—HJÛ¶„ H£H°mÛ(¤rQ DDŠqÂÚ`M:NýBÁ d£ÝdmØ|7-–ÊÉtŽP“1Ä—¥”ñ›M _Rr§´H)•e[! ÛB„A›”²ÛN$M¤É&rté(γŸ!ÛR¶eQÇ5‡À¤©;)ïxœ;s/@–¸*ÌŠkGî€@,p­  ;Ð`!äâ勳º¹€Ø fƸp ˆx1ØUYwgø¼"¡@©Ä—þö3»7o@itÊÞêc@×M“阗;ßÇß ³pê³ëG'*&"b€€LèãbÇÌ‹‹‹ÂR¹LˆcðóªÐ Å”—Ìv1­Ý#c\< VIÿ7Ñ œ¹t>™Ê]9fhbçªÎ“˜™… µ–%-›ýJÓÉ%˜™™02‘ЇîÌ ´I–­õÛ £ƒ3­9à ±³U 渋eB¦Žª‘ƒèå§^*õ•{ÇA€ ”J¥¢°j)Í` &guû¹8´2‰˜F D¨$ôŒ ˆË9R*çU¤=Š|€6¹™Dd%üGîù?ñÛç^z¥°“©B¾P~ú‰ÆGËëÖïµ½äreîkÿò¹­Û·oÚº…Ìd‹–lhxÇvé)×r ÅW«Ø7 td–›Ë&j·55§®.,-×LcñTeáô_Pà·RL58A¦e§úcÜs“S+|¿qfrzp0{pÇÁÏÞ ]œYrTíÍ¿õžت½ný„0¨u„ˆ •nú錓Ä‹ývŸÊô¸"òO9ÞB³ûkzFž»8]NrݶtŠ{aIW¦/TægÙŠ¼LêšCoâÖ wd(Y.K-{z{BŠ'¬”£"Û–$Zí–l³Ê˜òެ¯š6ªÈÃduiVYîÕùŠž^1ôîäÅ“†É9yjÓ¶šg¹mÂm;ǯLMÕýú¶‰Ñ@ª¥J£”ÎBJ÷OlSA#7P*Æ Žw†Î-™;_#B2‘ÑÌ a`E” Bƒ`ˆ$B*‘Ì—Š¶ëÄc""$"‚ÑøÆ÷[–ëH‰L™ °,„R–íh)”ŽLʶ¥”BHFb$”’ˆÎØ)^­I)вdZNP!cŠ b;òŠ|ªeƒWd–Ì€Œ(€âè<†Že‡WäP1–TÙøÌácû·nuUš™…ì‰9¶Ýtb†@0@ @Ñ01@ýòÉ7¾ë}±[‡ Ç—YÇÿ(tùyÝÕJ!*•Ål6‰Ê‚˜`’Ò=!²`â.‰¢«3㸷"¨ƒÐ´[¹LÀ(VŒD1È™Aâs÷?þ¶·¼weTN]ÓÚçŽáÏÌÛŠ}-^Áñ¢¡‰Ý‘]W ÷mñPD†vÔ áÅÃ#‰""RJv´qˆ^"•N¥²ÛÓ?ÍŽý’: O¢ëùæuÃ×Âk…²;dYlÌòâ’"¡CÁq $êvÒwªÐÑÅçiâ˜âLIQ®V—ѶÊëG[­ Ä aœVØ&^pðr¶Ü3±KjÙæÈzô;ß|í]wÓC¡6Æp:]¸çÞ_¶Ý„’1H J$3)•‹ZÜöf²Z?{ô•sþT]¤æZéåã-è¹T­÷"ßo% ňœâÌä¼Tõ„WLÊVSPØNîß=4ã»Ã{‡‹EùÌ™‹§Ÿ?ž‘“½Ô¬ö$ ¢¾&c†8€Ÿûþ|îŸþ,jA¤¥@ˆ³ës)<3(ƒvk¹Ö¼piòÖ;îÊÞòz*zjæ¼WÈ$Ðm•©‹³Û6mvzö„l% ºi‰l„Œª¨¶ú~­‰ˆó“‹afêâ#ÕÙjåØó‡ %Ê ömݲ8?h“öÒÉžüÔ…+û_{C:Ÿ×ö½b1—Ê–Í|3?‘\¿i{6mQe/¦Î_8–I¸N"Wî¹L.íylËÞ¼h6¦tÊõ0iP²(€1ÞÚ0ÄVQ° 0H PLÒev<ÃÌb"îLAHw( (4su©’-\ÏãÎõ‰Ì’Ù(eÙ®«u ¥¥d(¥BD!…)™  ˆßŒ$¢ÐBPˆ "$@E1Fâ¢$"bB2†¥82X)ĆY)ņ “@aÈ‚…a"ŽËê´X†¨réüw¼QZ¶Ž"ÁzÇ'2‰Hd„$2-)±‰I Õn·ÒåáD>AÒb1þ´CY` æU$iƒŽç¡ètq¶e}ûß_7ºÎóÒ¦ÂO®pÅ¿ûY q©·?ƪ@ƒ€ñáStªC½^ݱuoGoDãË8n E§ü@êdzü”ð!Ö¯ÏÍo*å^5ÛB ‚E!€…Ô–m E,¤6†XA*+Õ57ºxòôÒì –]+/@0 a4LJa^Ý¥¢„3'O•‡‡ûú×iC†%¢L3̧­u[¨4S§ùe@Ž!®]-~7~ˆˆŒ¡dR^93X+÷ÍMÏ*%KnÁôÐcþ8‘_V.cc®U]ºë]ï“‘ « ‘M0è¤Ò gÏÕç.Ì/\9=¹0sîðÙcW/W@5ÚajÈÍ8²:‰c#°€ µ =ƒ<½$3…Às¼ù+óÅõÙºr7qãë†ýü›o¾eãžmùri©E½^:²ªósí¬²N_¸òùô+“ËieZ&1=Ê,qè'sR[žÕŠ,Àï¼çö›ïšŸ¯•Ê‘6tÞ¯ÈÈRX†ýfM7}NÓÙ;‘¢(Ñê(»ÅòPÿØreNxÝŽ¦.«åö|cÞ¶T.ë,ƒ’ ½¸<=4<‚Šú6&F’›‡gÎÜ70èÝòÆ_m^jîØ’îíб'@ †"–"*Ã:d±™˜qC¡¢ŒÛËû˜ ¤RiH¥9nÕ3dgG™Á:’ÙåVHË“¶ ˜L¶¡'©ÖhH7¡B途TJ¹R‘TB@PR*) ©3ú° 1±°†)žÆ€ˆ%±žˆüFñÙq×uãóºä\!„´„‰ùÉÒR±Â²A˜·kŒ&&6, ¡I! !☂.1±Rb‡¤*¥ì( @Æd¢UjrÜÏ"R 2(ŽŸ'vTÆÈÀÊRG?–*%s½^' ºê†ƒP&¦•‘ÆU‘Èœ?s~Ïë_“ëCè<|\%6ÅÀÁ°!.!ˆ¢Õj:¶Ã(»òX\8¾~tT*»#Må50sè¦CÄ- ÅèÑnëÔ•/páÄÅ]×íìxz¸¶Æ¸Æ—Ø!IýÌk¹½¨<ïÕSùø!ÅIEМƒ!r=Ï03¡N2¡9~#!1̺<°3‘í- “a2æÃv`@Æk‰CÃE[EdVÈœ{Ç–--›‰¬Øè)‘±#)b«øª¥~½6»0£ÀsiI(̤Óç§2JEöõO-L¾á¦Û:oV„L¡ÈËGçÿô³t÷·]™þʿ޷tîRï¦ál2?²q]1YܰcÏëï¼S0ÎÔæ«—[`ªGgÎkÛÇü¢âžbÉÙtý†-—aÝPrÛÁ½…¾¿EºZk´f§/_í“ ¿9ýü /I,.,Ú¹$/6—hvÝøÎ©§¯öMô+Ïñ^wÝžüåO.5 Ñ´’ľ£«ÕÊÒb­QóÜ„*%OÝ÷£-{7õô )¿ÝPIW ˆý¥ºpxîêt®Üû­‡~×»îØº„pò)Sñ«þòá#®j•7l.fò '¹=å Xâg©^  ÌpÛ]o}éÇOùÿ¯©Ý;ñièá®ð$XÛ2 ÕaÿÄ™±’¶«Æ³zWë,±Y]v ..]nhеV")<æ¹é™‘r‰tD~` Á2H–±½u¨Ù¡TgÑ„‚"ŒM(È@‘Ö$-èÐß(V½ eÛ^S›4Swwöª&­#ÍB(Çæøª×šˆM|ªC( ” …¸2¹Š“¬:¬Š“üp%ñ™´‘RÆ= Ï¡3ÐîþžLçX'¡ã”îà4»y"òõÌPÿ°cã¿]Clƒ.&/î´cL F›ayÌÈ`£ˆûïUÝR$—˜œ!WÙ'RQÎÖÊÝc¿xÜiyFg£Rüþ楰.‹„…r¶) Õ)..\Ù¿glh¦V«î={*²”ã´·[…Êýôä¸ÁÌ–£¯\ô®]{û‰s'ï¼:÷å¿úÓò/-M÷‚áÜ3ä5B$ ù“Ycúëß17n®wDù³ÿö¿ê÷Ç(ÐS5CPº?P@>ì7èü¶y—ÊHhÈÞF©X"AˆƒéÚ ŠT~p”›P$%)¤”þ¼J)"I@¤ÈV@ we“#j¶ÚDžiÚÍj•‡lËøiœD LžÌæZÝšÓn2ÃàŒkü€¾Z=é¹®ÃI cHÀ%y®ôH*OJE’¤tI)T9†L1í·é©¡ @àœ)¦2†(¥R¨™T„èšr† @ú… ’T’ü ÿ¤·ËÏÂ*ÛÛË s‡z˜ Sºž"â=pi/X ýÚÁ9ÓÛrý0]‰¡Ê fbÉYÛ+¥´²•:Õž’€\×cœ1@—‚B远߾~͈Øé\@é—ÙKíÁUzL ލIªŒëð0@?Òn,Þ˜>¼/F?²/›rÜQ§)¤ˆ |úA¯ÃêÔ'2»cå}q…~zôˆ¡‰LÊo„˜fFû•T?Œ6sÃù™]ª*Žšñµs~Ã]~!8øá…åëžôŒ`}aEí8Ïy`Üx°´"ì’Ôî⃂tºãÇ"#ÃÝ¥­hþ‰§¯]Xº·ñ–É¡ÜÂLöø¹óÓ›kÛ,›hß[2fÇ@åê­È`ÚixåöšçZõN]§ã´ õÚÉGÏ\xë«oýðôCÿ„-,þÕ_¥«àIcÁyz¾Üžaˆ ÿì@?ÐCV9Œ»ŒæÁkÒõa¯eVR½Fß– ‚ IDAT_±7lÍ¿ž8éÃã €#(àuÝí•+iÆ“yéI×u8cLˆÒQ—O÷Šœv·°¹åv+ÃcSŽëÚ&²H) ¬»v$ ‚u;Mî:V(B=0ù‘¢È8ä7"Š$GEÄ#Ƹò•ç;‰¾äÒ_ €Ì@¤ƒ[”N¨"dAB!i^Sò®9›; Št£ä›#`½XÉôe'ö푞ôùS»ÛÃà Àì¡×^º@@Š6×¶6—G !´ÞŒc†¡÷툀Zr‰z„Ç„Ÿ§¨‘svoa>›Ëôçû•R )%õúÌ7ʯÁD4Ì}‰‡EHOé²Ì8¶Jë¦a‚Žù ½üQ¿CçWÛ{<9þ¯³é,OEÔïÜúè?s;(!³?Áx?pP$Ù³ÿÆýÛ0<åî¦âÈ*t³ØèèaY;Vf[pvË2»ö.«åƒÅ–ÝO[V%J¢É»Ø¶„996k %ô¥b™É©õ.|ö/þäî…K㇎­/l ³02:ƒ 6æ—''Ý¿·yôØñ˜!..ºmå¦" ŠºQJ&s)¯lyé–e Gét"7Ñ߬Ž'¢#•é®ÕÙX_Þ|sýMÛˆOõe^|ý{îÆ’t6Ú©6Οˆ 3’¶Ó¿0VÛ¬X6W¶òº,žŽ$Ó}§ÎnÿÚ§_‰¥ÂSSøƒ‡=âãÇ<…\ë®!šO³071b§Â\¶eõdN;RŽì~¨õSËŸüÜç>÷¥/ ÍqRˆ äôàÏäî¿“D™>ˆé,D?›^jm—luæ.^uÃ…L’ ‘…ú;TäIׇ\ôOµºCA@©ÔúÒR<·M»ã8Ü`z5©)¥Óv”’:ÝG‘ÞPø -'«Ÿk’ˆà¦nøu"´RèßA4C¿ iWƒò£8†Õ¥M;Â~”ëòX \y‘auÀâV®@(s9§¿ƒÑ¥«“V̉ˆ„ˆF""=kc}eÄŠ‡âñ/ê=r~ÜÅ›A@Ûrq혇"”ˆ4HÅŒhsëÞd¾/½·²~àÌã·®^{ý•¯ßš_è£#lþ¥«Æ0œ=~ìÑgŸ]¿µ™ÌÛÏð hrƒÙÜà®Ó?4Îb]åÙœ!q$ S iÕœMÞ‡{G×îM§Ci …÷OO¤fvf¥ãn—‡L†i‰µÍ­±ÙƒÂÖ·¦o¼Cƒ±g?ñáé“GöÍì¥É#ˆäs@›ÑW3,¶ÑŠ­Ü~ûÄÙ³ÈMABÉDæ ÿäçRùÎâf•Û)»ž×j»Íj{}}­Zk:NýþµÁ/}û…ÑCC{gF‡‡[d˜n¥1º°¸î°v›ÖÌ|._§Ö0Ÿºtû¯ì{îÂk[oÈ[W.ŒÍNžyöÉ¡¡©`& zU¥ïÊúÚö<„m¨¤”D’1æw( ¤R\ˆf¥" qëõË…Ò=Ù­O?ÎÌ#O"‚bPØXgZ©ä ”Òo×”¥$a[¦e‹õ[7.8xÚNå·Ö6‘Ëv³åxín†”RD 2&\IØi[È…¤%Ñ\Óô' ™Bмeç"ã:NÿDBW$©|&5gÈ¥$"é»)I •b€žô»6¦ôů€3.¥XD¤Ž.Ù–%=éyŠé©ç$”¤úQˆ!”RÀ‰yž+ !¥'£¹Pþà!!ˆ¤§@øò Æ”bˆ‚3éIEJ :ž4¹"·Óá\ÅÓqÔ1óþˆ©žv[ËQH¯|I1Šˆ”DÎêm‚ã9Q;¬ÉÌ;cv2† ²]¡.ÿ壧sœ{rù›˜ˆ "`WJgwr½V¦$‘€û$`ž×5 Ã0-é9íVÕŠ¤A)äz_ ´uC‹ cÃ{¦¹Á›-76Üv{eyñ;_}©T|{s«Èê|V7+7d·Ü¸Ù\ðö¶ÍèÄX2éÙNŸ‘;ôD Ó™¿ßšËffëë…µµå¶ÞZº_+®í?Þî8‰?ñð³®S½áÅ‘7E(!伫”3êŒ!b /þùÊúÊýg~ö—”ë&cIøýÿô½S:‰F/|û…¡ÃƒýùcÊ%¥|¹I£ÑÊŽä¿ó7_=}ö¬[3~øÿtäüºÒLÛíj÷êÅWÏ>ûl¡P†Hñ·_ùÁ£Ÿù@¸=ú¾väƒñT$³µ²I%¡x4,_ªw[mÏ×s8ãD$¥ª×*¡X4œŽ5»N2»xñþÑáv§NR¥­ùê×ó EÒ“šÀ83C‘n§Óí4Ñ0lRRïð”T€À˜[2Ž‚ˆ˜–eº*…\)EJÉ µì ”ô‡îÀ3\"R (D_¼èº®à¾¾3¬GP™>OIBà†ðQ4Šd£’”^þåO‘é¤@ô¯yò½Óª·ˆì±9‰úG&bé)IŒ“VJHP\Gΰí8–!êœCr=0JµZ&–dÕíí¡Üá#'»×g<øÂ^)¸áÏöµF³ÇzòÉ+>ö+йã»×® çS ,HñÞ”Bó¥YÏZ¨@·½DyiiñÔÙ“#ý“¡¿»ÚþCÃo¶ÀSCŽÈ|›ÏµF`¸¾¾¬›ÅÖ³CK ÀÖ¾RåÞ¥k-,œ~è)††>ÞV+ëù—tê™'9×/ø´†äïbõŸ|ï¶·a$DÎ&×êϧÆFau53=xóÂú¾ÃÃïÎ-Tÿ09äGÇô$8l„É$µ_ß?üZZ!E=&­…=³—>ãúNõ ¦–(Ÿ— ˆ–i1†Jç"Nyž+]—wš.X]_mC£´Y]])¬®-0FåÕò•»¯FâÃsׯ: ²Ñ©Ñ1 `Çín83pÚæö÷›=±¯Üš¿u»5ÚÔQÍ[¿v{ÓlÑphëòm7o5Ô®V½Û¥§>ý‰'yL~¢1Ï£\ÚF†¶ÿ•z&yŽ$% !¤«T³õЇóÿþß÷=zwldZº i×ìèL±i½ðïÿüÉ'7÷Í! %ò†àsï\òDû#{Ö‡;›Æ+ +—Cõþfmujì‰éÑriáömÃ2ThúÒx$r%dbI ’ž³²¶Ôit»&2£çéÎù®5!r Îkú{äþ@ 9ó+Ï»—¯œìxH@†ž.! .à@¡iÐÀ~|*no¼~aåç~éD@¹€¿ßÃ/†œñ@‚*øó…5004–ÂÎP|v²]IâtìÑ“ï±j÷¥Gÿ«úëí )•/:ßÍ V>üR>9¦v´Óh¦BQi±X<Üus±LâÝ+oOî ß¼ucGnªHJÉ8ó'´+Ÿ@Àï’8È…è$9Úy’™ îpÚÇŒ”ò_4n×ñ¤TÒU®’ž$NN£MLÖkõJi³X,u· 7—çŠ+++NëÞË¥©Sbjìx_”wMÃŒãg?÷‹7Þ)}ô©Sý³ûê+Îba¡´ÕFXìÏŒ,V–E$ÚÙl®5ç6¡j†¢[åz×ó’C‰ºë%‡’§×šÝ»«×>ð¡µK´´9·¹P|ãÅo4Wžüø'ÑL Îq.$àÈ$8J†hU«ÅÂöä¾=Pt_øÆŸ=õÓÏ?úÌ/üÙþÉoþ÷¿£5+ÕéÙÙ7øÕèÐà³=î6kK÷V ÅJ¥tÿùŸýÇ"’=ñøcs_¿Ø–f(aÅúÒk·ËŸ;9·ÔpMiÅ#Ë«+Sö•æVV¥e wš²´¾|áÆËSÇlZ¾w;ŒÖèèž»×æœîv_v毽ôȤÊÖÕËŒ˜Ûɤó›[+Ñd¬UuJÅVjxP’‹ZPÉz»t½ e†eqaJ¯Û…¶!ß6‡ @‚ÏÎÛ…)÷ѱ= Aàãëh´ìÓ?b>Ié¡•R’ãÈ¥’~mTD ™ÒaV½q")") a{c}ò@?)DB¤"­ËFÎý³§`Zá¤ü×?‘bŒiU«Ö67*‰Éw"¤P0­ÿFFœ3}Ô J“cpzd\pÔåQ¯cc‚OÌÌZvÄu]ÆyüÅ5/Á³' l‡`¯?éÄí D¿Ò±pá®M¾·ÀÜÏÇ€,Lëõ„(Ò•ªë¶½¶ã(év\Ïa’¹n±Èüâ-·-A¹]Gn¯¯vT•w#ÙáäÆêB«£úR9ÇífÒ•­©½{8>}df㙕è~–Cßzùkœ;­Êâæ½·kUug®´\q:L†öÙ N¾k…9þ¨ãðôµwžúÈS}{ü},Ba{£ÓjæÇF½.†8oÊjÄJ¶»ÎXkæÖko†l>ûÐÙ7Þ|ý¡sOÚVBŸ!¸Ò‹HDÔÏ‹„“u¯Ðl”V®,zìÉ[·çNŸy¸k”®Ýxóàþ³·oßÙûð™›7/=tæ‘g¾ûnµ!_þêwº{øXV)ŠN ^_zõäá§Ã‰°Žg£éõÕ»“3¥íâàp®kK0t&»9¿Tot “·ÊÍZ¹dnªÍ­ùcç~2øþ_5;™xìƒ?ù/× ©d"‰EËÅFu}1?8¸µºÑÝS³Ã–!ËBvqk9¶ÁCj ™ä\ø—“ßÞ0àœ‡B‘VÓó<ÏUÊ4LÆ9‚BDbˆ<ŒÚÈ«#PÓ£d ¯|•c¨¢Dpi 衼‡pgLpÆ¢!8ó)˜0}]3t+¢l»á¤ÍC)é!ç A Xå>½Sõ¸  PÎ8CdL qˆ5`{{ixvÊP p¦ïø¨ÛJè!á}÷„–/¡ŸB朴;ݵõù“Ÿ—äÇ?àŽY/¦Þ÷LûͧCÚ­V ÈÅÒ–¿YÞŒl[µ‡<ì¥;?¨YØ!‘¶˜u„X¯(ù°©ÞÇ!ÝÚCWøß0Á²"ECÀ,3Ã(,Kî ƒ÷ÏVÊ7b BÔç,Ÿ8F@¡xÜŽEûûmË$E­Žkr8CéIäLüôG󆕹µµ–šžÀ¶=I¬uÜ|hrméÚf½Ò—Í_yåÄ„iQ°t•ŠˆÐ`Â_*èg Ùõ,nêÜkÅ‘¨ëÖ ëåv³å ·Ui¹ŽK^½Òpb¦Í…Jõ¥jµn*½zñí¡©ñ/~ñ;q£yøäC‹‹óÝr•BnÖÎr3—ÉO›¼o év©¸Y¿½¼Úܪ퟼ùîµÑé¡ÂÝ•äÞh,e2žß3>{p6œ3X;)U354¢ŸÃÅÛwÆöÌhY»U_˜_ßë:ž&ì&3}<Ç€q墌˜I%3'ú'ÆîæK•­¯ÿÅתŭçžÿYËŽA»Ù–±x:íN41BFrh°P,Æ3ùRwn4»¿P_;~ô¡?üýsà·Î NLl¬ßÞwôÄý7ïwÓù=œ–ÂFñ#ÿ‰Í¥ùåìHÿžÄlnàÆìæÆí™ñ£Ã#S ×cñJ¹¥pu{à ǶWV¦FG …züS ŸóŸªûk«ÇSÌd–²#ÑdQµ[+\˜v©Ñ´\RµÖæêÝ\ºxÖ°L_kqCñz¹°º´´±±¸°PàXÛÚ®yíJ$›RÍp$ÚÝnÈîF9’Ãö¶-ÅF"3Ø]lÆöÈ{+|ÐN–;+'Î=öí¯¼¸÷ÄLm^.¯Ü±CvyþþÐÇ£áÄ‘L4Ì™ívÝl.Ê#1§Û„¹iY‡÷‡Þ°Ç¦öl/]‹ŠÉjûÊhÿI–£çΪޘ˜9¼qges{qrx¬Tn´½ŽÛ`xåÕ7Gg›ktõê÷î-7«…cgNsÓ¨â`GS3ƒ3k÷W®U–ÿêÿâ§?óÉP8Õ.¶ªå­ÖP”Zü‹/=÷ÉÿÌ“dÇ¢¼V3Êd,›ôÊåPÄ8zú‘K/ÿÄcO.^¼u-ôú¡s/ß|;; É\¾ÓRÎL•W –a)%ãñXò­×¯¤Ó“Ù|:U¯•W;" Qqcm`vz{y>™àñ¡h£é©Z+4µCIyê±ss7î^xç[C{Çqsq±Yn&é…»÷2ég¸“D`ÑH8?0Òq\!D4‡tµ‚È‹Ø!Ž"pŽ`ŽŒ£"RŠ3nÚa¥d§í:NÂxÏ ¼w‰hœ>è!`pBÔ/`-Õä8?ÙOc‚¨ußHéE‚uŒG‚Zä‚ñ­¥¥™‡f=©|‘­^ç("P²—oÓ;aøƒ1¦’FÛ"g›K'ŽœV޾$NKUýÛzथqÈÐÿ’u¸4㥒 ¼{÷nwœ<šqÕéêkÞÐ*^ 4ÇàÊÀ7¨½FàNmg'` ¨Bù|Ì ›Rß ª`Êë…èÇ–*]^NM=^]!½×eÈй(ÚFÏ4OAŽ' ,Z$5ì‘1ȤG8g@=¼L€ÆÀ@ ¬<‘xþ“ªE\*šêÏæ «+£C³±P˜Àch’¾I¡OõGašvÿÎúÔqGv”áÙ‘9=Õ°ÙüU”̪5ÛÙq3離åÍë?¼[m¬\½vÿÚßqEÅ‘É$Y«Õ ÌJuŽé”· ó¶=3³U­Œôñ öu—œp²i{yžZ]ßèKî_¾yÿä36ÖêŸüÔOÕ;åÃÏ=¹¾t÷ùC‡¾ûÕ¯;ý„"à …-.qayõµþòg¿ð/j÷¶JÍ£/:˜ËDÛƒù¡Ðµ×Ë3Ï$×k«“³óïÜë®gFú_ü8ñËç2}#ž'I0 õ|対úÌG>öîåùKWU¬Ùl×’¡p$ ÿüâß±´ïQv8?ýÆ©ã]¾ðÝç?öë/üíWÿ‡ßüíßù_~?Õ—i”—Ð m¬l[õâæF"×ÏõåòÍòâdj¼¼¼689zýîµ#{º{÷b«[Üÿø™/ÿ_ÿnà§NôMïYY¸12yèþÍ•vµFæ³#RT2;·lkiùF4lç'ú^~éÉél³ZIUêN¡V¦+×íDûZÍNmí.ŠH[:Ù‘üí ·<ô*…0¬–JÛ÷—Ï<õpÚ˜X\¸15óø£§«µf$•2M#•J—¶K¥Òöôþ©ƒû÷zf;Õ×çy·Ý¦dÔCF(C Æ…°¬ç8ŽÓv:-´CÈô6n»"Šƒü„`E×Ó2ì@x€ø¯ÿÚ¯a7è@í|\òç ªçTà \ˆ‘—··:äEmn’J{|0¨n§´@¾Åâ§î "ÀéJÃ`áT”ì*Ë ËõNmH€ŠdoDJëÌH‘’B÷n_Ý*¯=öÄÓžëic¯ Kêq–øÿPC48󗌱ÂêF$édúGc=,=0@å;ŽP»# w3À÷Âܰ½Þ¾|óµÁѾhbàÁ”ÿ®"µH·¯ˆ€Ú*D€ÈHv: aðÞDKX$1Ž×n¼91µO“÷ (í,TA<½$ò)B¾òÐ/hȘj»íåÚ®¾vüᇪKð3XvÀC( X ‹Õþxv»ÙʤÃáh²S¯ª…V£\k„A òóŸ¹öÖ•ÿñŸÿ‹?ý“?úÞ7¿ûÎW”;0”9ôØÉH'Y\¹·Þ,n "ME2§îÝwhÏóŸúGÏÿÌ/ÍD¦'&ï;UoÞÿÂ?ýo&íû™~>—±~ò}:”î;ÿäÓv¶»wßi·Z?8»uu{âhÖ+XuVšîuàäÔ?úÑÏþןÿt«Üº|õr‡ Öî–''Ž]/.LŒan½[›‰PÞq»ñtªºÞ …ª‰Ô00ÆÃD6üÆ·Þ<÷‡™ÛÞZ_œß^ŸFd€ÄÓØÆý¡³þ=2à›n±5hæüzmþìÃÏ\|óÅþt_ߨH<ã±ð…—_:|æð[¯¿~èÈq48¶šîÆú:o‚é:ŽˆÆ¬D>×qe"™X»·&Â¥üð¾w/ßÌÛ /êÈvȶ·Ê¥d*Óé8ngbbâ/½eCŸßçò»ÃÃ9#ŠJ…,ÇL ¦î]¼tòé‡nüàÎÖüêâÜÕþ±l²o`{a»%V~ò£ÿ0“¼¸¶Ù79xèðɾòÚľÑTnLvºŽ”(LWzR:…Âæþc{“™apH4†ÈÚJÚ¡ãÜßé¼à Ü (%5] IDAT]Ç“!ã=ØãmþêP„5_° ¥˜&ö2 ’R*¥õâN*$BPRÊ¡¢«žòi JÛe|ˆ(ÏT>„šÝBH¤ûPL+ @ùÊ ¬wHŒgL_K@àvD>‡¾ÔÖ³2Æ ©”§¨™!˜BT¾&PéÓ®?Rê•o¿vþüã®ô¤’ž”J} ¨¾ µ8WŸœÉW}zZáÁ¶*ŽŒqò/_ù€;½`¾de ØØýh²ÒVuiy©ð^]¦®’˜îïü¨*ê öpn‡C2PÄÀ‡§j†¡žÄG+Q ƒ%b@ ê ס’¤PIò‘ùÄ>›‰èD¤-R¨ƒDÑ`¼,W(òq;ú%”›7ëÎʲ2›I;±ì›KóåK&qÑõRó_ýú?ûßþàž=rüÔ±ó~ïsŸùç'']»·ñ¥/¿øí—¾³ÿèÞÿîw~ïkßùæýñ—þàÿô ¿ú?öýÄ#OOLMœßÿp§ÕÝŸ{ìÒõ—ÏŽØ#¡nÓdFÛ¬±Ráz¨ÙOfWubÛK™ñÁ—çÆŽö7¶Ö ªÛq&ã˜éú¹Ÿÿ™W¾ÿ­å¹µÁé¼tD6³rwÃõH-‹;%£™D³TߺqËSÍó=»µ\D”\p}œÎdò¶¥êÅ­™GŽ{è“Ïêú囥jM‘äŒq- k>æÿ¦³÷ðÞ°‘Ü{èÛ–vÌ{ä©OüÕW^°ÂÃû̧o¼üN&[ë눠Å\5´Ra$—ÈnÞ¿—ÉöwªF«qöÏ~ùÿx‘ yäÐáw_{f|´¶°MEÃÊ’Žc¶x2>=ºw}ã]aÓxvresNJG#B‚0…Ó®‡#ã“ûö¥TK °Ò©¡åÂ}¯F’Žž:›Hå"éX§Y ÷ÇU'üÖ…¿…x2ž®m7×CntdvèpË© Gâ9)½P8Öm5«Õ¢ò<r᫵ð€ѰB¦B"étHº ¤ï# –jÇ~ã?™|e'x^_õLKýAI‰Ÿw€þ2'HGÂI ”R‚›Ëw¯F£6èæe1D-PúÈ ÍzÜ=¿ÅR*Âz«Î ®û8zÐÈÆp‚¾1}ý c÷öl„2Ü=zêŒÓv´ÃÓšÚÅ0&B†´# ÑOŽþ®@!2ÍVéçÒ¡(( RöZAc ÊéùµÛ/Ѥ)Üm‚€µ;+}™LßD†~œðŠüŸ˜Þb‘¿ÚLüzôçIò”Þ·úÛJ °ÿÑsœÐë‘0@ ¼¸D°;‚ZxJr\59‰­òÊܵ—@a§Ý©Õj‡C¤uoL2ŽÈ5[P¹cÓ3ƒ££ ÃFØêKFÍv¬ÅD<¼¶Ö´Ÿ8•Îo,Ý¡:þÊ/ÿÒwßþÚ§õ³{öŽþÖ¯üë_û­/œÿÈãÃcŽ¢P$ ˜Á9cç0{p?"æ¬ìÔÐØÊr‡™éF«‘ lVæO=¶²¶=9>¶påæÄþ=µÊfv_êþ•ëù¡¡«æ<·Ù-u¶o¹^~åŸ}þËß~­o6QX(ujŎӰÃo¼ú7¼õÆE+Ä ‰D]–¦÷p[Mˆ@¬;tkîmÎü¬C˜žúƒ?ýÝx&Õ?6Þ®tæ®_ßZY`ìšhW.À® sbo¾ó¥½ûÎ|÷+/œ8þP·Ñ¼uû&Ì08gVnlÊjM|íÏXÈ´¬L>3Qß^S–Yo5gc 2é>p[±tô™?ÿ—öÇélzOjv»xgp`o·ºiƒUX¸'L3íf¡xüÌÃÝf¦Ú¨n—J™Õ¥j±ÒØ.nלöÍ×Þíd·£˜ųc3³Ž':nëÔž³C{¾÷•oz´Ý—ëOÅÓÍF­TX;ñÐÉ·ß¼¼]XªWÊÛK«ksɘïËï™:|ýÚ-ÓÄT®Ï“dضɭz¹ÔlT”¾ºüVɯ% 9 ÃâÂRŠHúcm?{™Skø¶wT ¾ó©w…ó©CȈ<)=¥¨^ïŸ)H‘RÁ´x I§Ó>ñèã~_¡RR*©Gþýw—þ'C"Eª7CF†”ïË)ýéQW"ÒæRÚ˜MD¤%ø’¤Ú¹•þ@Š”§¹ä­Ý™O$RþÐ u§a©z&¨¡~{)=Oz®R @)鹞ҧc"¥Ès”ˆ<VR[ñI‡ù¤/DRà§7€T@€ÁYáG4ži;ŽÆß¬×¸ÌŸ£C0/ÆA0àŒ€¡&œ1,ȽEÆÞ¹"e… ¦ïJL çÈ8qŽ‚3->á9CÆH2M!!CÁ3‚<óįþöïz®“ˆ$*«ë €s4…ïkḃÞôÆ 1֗⑸"Á¡Üèt«m,oÞ¯£›±ãœwåå}’e=yæ¹?Í*(4¹ïè˯¯Þ4–¶nüÇû‡ßûÛïìÈGzé “›åçÏÞïÜ EY³µZcplpñêBl6•¢|K¢Šg®ó˜(lm<ÿñO¾ñú÷ƒ™¹»+ÛE èÛWk¯7Ý®Š‡òYn±“çXr¸ãvfF#€z£M$<‡â™¡+W_–ˆͮϗvïyO=óìPdVª®²Éó>ðÔ‡¾þµ/)å)˜Z‘¼#5¡ž(`ÿéƒÍ5n âʵíbyõ3ŸûôKßøJ»ÕÔlÅÇ?ô¹7G¦Þ½| lÝZ¥[*!”U×u”CÑxbmm«Õlzâl_*ã ”9km¥˜Ÿè/n”Œ8_¹µæ #¢¶Kw'¦¾ý¯·ëµZaclödñÞf³R9þÄ1BªÍ—f4 §×–—bãÎå·ssO}â§xüÝ‹—™èðìDj`rk«086:Ÿ¸|ùú…‹ß÷Û3³G€YR*+k%í\·Ó …CÉL"ZV˜)¨Ô*ÝVHö°Ð+3@BÓ4‘s ¾Ù&€DÁ®£ v£¡âЮdEZ@®”žT;kz_C$•ÖzJIZMC¾ÇxçÄ©‡7€à*©”V~j HOJ¥|’JJ©¤J)©$)¨HI)ƒµ=yžÜ {aÊSž”ž’ªGj& ©ôZPJ¥|ÚöäzJJ kåÉé#DR¹RyR2´îZpÈ™) WФ’ Às¤"í+Ôdkð¤‹'ã±4ó‰~HŒ)ðמȀûŽnðáØ‚#G|€@žÑZÝØ/ô£Í•VœsŽÌ—ˆcÄ9rŽ wm‰c$8r¦7"¨³ø¦ö3aqme`+èû|Uix y–NDZˆ©Ž$ ÊŠKíž\Ÿ‚(Á•äzÝFÕ$‰A¹RRõB&E•†Yï4‹­Úýb77¶6o g½Ž\ª%ÜÚêÀè`­aÅÛ>}ôÊÞ…Z‡¨3—È'jÞ¶¥úÚesþÊõÖV!=ÓWXÜh¹Õ‘ñ=k ëé¡l¡¼™°²k«w=þôÂü•ôø€Ù2€C2×RCLàO>÷í×^ß{âh:Ñ'›|£½|ûûߟxdº°Ù±,«\-TKuuN>±±¼’MôONìk6ê=Yv$–ÊÏ\~ëåìÀÌÁýcÓ³÷/_iÖÐ ¶$x q÷ÁXdz=ý¿òéÏÿ—¾ýòä#ŒYo½ñj@šÁG~òüí;Ë—Þ¹\áD$9:¼¾RKD"Å…9D¹ÑêjÉ4øìñ‡Û…rn`$ÆsõV%–]Z¿vêcOæ FÈ2#™ÍÍÒøÔ¾~øSµz×'¿'‰e;Å5·QІUË s@fÇÃŽÓ6˜ˆ'sÝ®l•ËÃ{FM•,–ó#céDÚ4¬F»ŽDÊ›«(h|zr`dOÇ•ÝNbbÿÁ-G5Zõh<Ä]¯c†#ªëVÊÛžë#kéŒ$åχ™i˜œ‹`1EФo“Õ›{¥üÁ•ñŽUP邎L—ÝÇôŠI¥ĺÍPR*©§}@ïÿþ’Ͽߧ‰‰‹Úz(lª´¥Â=-îèCü$µ÷Ìë4îL¥v>z;?ŽÐðàâßïM(—p6c,l†»ÊñèAÎniBØö@v Äl§Ó}ýl•¶bqž '#<âÍ-gáæ=ŒXõzµ¹ÍCÐÙ.n ŽND*µô@|nmýÀñ“±„ R EÇéîžiìÙw®\­ìÛshl`´Òè6«Åreuvä¡K_IN šbsk»°÷àÁârrÔ,F‘WÒ£ÚÆÞ‰#ÜéJÏ!çÏ?öÖ¯0ˆl­ßÏ ôoÞ¯lfº‘ö¾C§¯¼ùÚÑ“§V—æ[ºž N‹ˆÛׯ\€Øp¶«Ú¡H¼Þ¨³pxyýIJqêtW7¯dû;Kf¸ÙP¶´°Ò?6šOOSm¬lÖîšf´´´\olç&òc[ë+›ÃC£ 5ÚTb U«7Û @ §BýãSµn7†"‰f£Õtš#“{Ö–6…Í8N½ýÖk/+³säÄéƒ'".8„L»^­ôÒÙ<w»Ëàa+,»žã:¦0ÛÍV«Y—žCJR¯œøNÆ„a"c¾ FW%ÿmˆHõœÂþÀ=(?’Héðfßx¨$ó¯yÿãȹŸO£3Î9c€ 8Ó©aþ@ •’z° œsßx¨5ç ü ;† c\ïáÉγ ”JC!ô' ÆTú¿\+Ûw|ÅäÏyzQÇÕŒ"C¼þÎâñƒ³N×#D.¸\çõFÐþ±”ÇÝó; º‘2pÐ)-Ñ$_ô¡ÇqDÒ“¾‘T8ꯨ‚FñÁ#a8Ôhµ"‰XÏ”ðc10_ËÎÎÃõ4ãþþÐu1)¥ªår8žÏx lr·šˆBX¦a.XµV¾}í²@jH§¸µ9–³“ñx»Ã“C¹Dßä/\êÊæÇŸ9óâ7_Dl;éZá˜aÙ÷¶žxäÃm,/^™¿7w¹÷Ó$"ÌŠHŒ¨×Ц@ËŽ·jµ©©Ãi €¤S!'ͶŽeÆ7J[Cöv;Íd_®¸±I…·KË®j‡¾þ±ñüÐ7^Ù¸]X^_‘]µ]¿upÿÃË 7&÷ÎÄÂÙZ§k…£?|ý[2Šùá@Šõ¥ Á<Õ šð\åÖåÜü òÐÑÇ?øÄåo¼ä´›»{€½ùì.¹ ¾¥<õ±g.¾ú½©ã3«‹Ëc“£¹ü`­QÕ*>;ýÐÏ-Þ\]\]ö\ŒH»²[.ÕY}åæŠþp}3Ãõj Œä-ÏO&‹ ›µÒj8“-—Ký##×^½eZlc~®´¶"=íO™‰¡Ûwç!ĉÙs·V‹µÊÃx¬º¾­¼œ`(ÏC‰dfmy5œ‰F£™j©T[/½úÝo!olfo~d:“í'ÂJ£ŽD¥§¶‹Û”i™¡PDaÛ´#F …àÂlµ[ívSJWíÔ#¥””$%ãœ3QOrhçÀ¦w9JÚ¥5ôŠºŒ1¥H0D¿B>3Ž DÆ@ãéY^ÈI T}Ù*ú¡À5TWp&ã:¬0Ï1}:A]¤‚ÈVíC ÞžE/rZÀ·^÷.´C°VDr'–4BäÒ_<öÃ]Oê¨+%•ë¸þÈó¼®ç’/×Zw*†¨‚’ˆ.ym®1äÚ©2>$Ò/@îsG)0u>è|¾'šK™úÔ£÷¹‰?xÞŒ¤¢ÄÄÿŸ‚EÄɇ²‘™—'tî¾_ü¼••µv­ùò /Æ\–b MÑu;“ûFkn7Ò×n^•ÝöÚb±k˜C3c^¥†…é!3b=|èÉÕƒgŽÚ<¹°}óÂÅ[=Ÿ¢¾Î÷ìßÇÓQ·Ó ™µ¾ìÈöö–'›k‹[’—r³¬ÕÉZI·]ŸÊÝ\¿–É/¬9ž- ‹u° •t•Ó¬uÂvøS?ó‰ù{óm.\»•Îd532Ÿž:´Ý-r›ª›+çû>&a$Ñìz¡X´Ý‘åb $X¶ýècs·3<;vìä[…êÑC§~páµD_§7wÏà­h$M¹Ž·1{èøæüCû OéÜ6DÌõœ9ñhmnñÖµ‹€ ÅCÌî”'Õ—/•·€‡¬ñÁÃï¼ùVh(»¹Qp¤šxäøÛ&Q,¶ÖØ3zëÞÅÃGÎܺz½Ö®x ûÆÇ¶ÞYÚØ¼î¯ll6çö;€,¹¼¼èu¼ÒƦaB,•&Df›ÙLÎU*OÏ_¹ûÚ_ÏEûÇ&ò#Óž«˜¶q:®D•Hf«ÅRu{•f$ž`ÂâœÅÓY) ™ŒÄ’  Õjtº]­U"`̵MÔ·£øÔƒ©Ð³BS/øv]¾‹V«œ4°ƒ÷W¥†2bL!x½Ñ6úš,æ×G¦ý’$Ô_˜vüH tà£gLGœkú<€V(%%)@ÒNÃÆ$ ü-HÄv„­jÜâ«1€zR)¥tC'„ ¨zO=÷A;f d†`¨H*…,T!€` @ †‚¡b„ˆ¦e"î3Ä8çÈ9cȸa0aja#R •)ç(82D佂廄8{ÿ³ëÉf£æA÷Ç¢¿ã·ï›Éú™Ï@ üÇ¿ÛߣÃÚuôìl6Öo‡p<¸Ô vˆ€´CÍ•Òü•ž>zâùÇT8Õªs;\ZpÛÿíïü÷¼•rµ¼Xæ‰ss·7;fÑ´XÛuîÜš?|òHnB˜&ñ‘'?qî᣽°^•˜¶ÉMžˆÜ¹?W¥* ɼ¡=“×oß±û¢Ñ¾ìÝÕwçî\M$ݢÅ;Ü3?5S©Ví¾¾RÃ+Þ¸ ¬›\®/c,ºwï¡|>W_mWkk}£{–ïÞÙ\"?Ó©5ìíÕE@¨n]é —¥ÈÓ‚!Ä`~´p‹'0.CÝÒöãüÒ·¾ë¯\ýF‹z .ô h’àćŸHÇf2ý›kÛͺ³qãN§³®÷±Hß`(š(m¬vÛ Hg²ó·¯`:—4"µ­å¶Û"fÈŒµÂ ·ß˜±òÖF:›&o¨°qoxlÚŽE3£­‚I~çÅoV]×e‚~ô¼éÙÜf#œÍö•7Kñ|f`h¢Q¯×—ÚNÝõ<×uI;Ü`*µBÿHßéG>ÄX$‰Cé¹ÑX$3`VÄc¨R¯rT( dœ€B‘P.7èx`X†Ž‚¢n·©¤«ëúPÐ6Tàõò‘ ÙŒ'òr;%Í/üú=™!ë4 ¾£‘÷_–J*év=¥”N6§ uBI%="1Žäljò(`~ŸGR>\rޤ”TzЯ#2¸@d„Ü䌱 #S ÆW6¢Nbœ†ÁBΑ aÜàÜäLhÀ€eX—¯|ç«7Ñ_1äL0&„é‡T뉘Ë0d\Á˜†¡#×ÚKmW’žr$GΉ¤ã65! `Ä‚œ ÖÃNö®âž÷ÁÇâV‰O€E?ZWÈ—§+ØŸþÿò0ÃiþÛ{Í1}ppfp¶Ûhú®E„]Àµ`«ÃÊW _üë/îìèÔÄþ…2ó߸|çìÌáïé51²F&Ö/½†·¶z«È¸…öp6gN~êèÈè`\™}¡é©#½W¨p#ˆDcçžxò•׿½¾zw¸oÈõºœ©òÂ:7…’G÷=2==#¹›kxª .n^³¢ñV«“M¥ZÅrßèh¹´‹¤UǸyíÎTnÿʽ{ÓãìÁ ¶Ô&ÙˆÆbfö½|ë²)0jÙÕ­í¡þ»cº]Çßh¥&úN>û,‚è·2ùucUòÈúö2 艮"ìýðzÃ`©çƨ‡œÈL<¢¬v|bj½QÒ×+3˜2e4«´Kî¶Â›<}Þ° M5XH*Bùéþû÷ofû’ Ëj4kO=úÐk_{•Ù.·¸a©nÁÙ¸»ò+¿û?•œ¦$F}#}CÓÓf,rèèùÕûë«ëk[Û÷²¥{sF$Ú—ÝXXØZ_)o­gʶÎ<ùä™§Ÿ$s£S†°²j¹Üî4QKc‘%ûCñŒ ô—R)&0í‹Fâ²C†°¥GÒu•’=Ç(' *¦ECAüë- ´‘ÆH t ®ã‰!3{SÏ`SÀÐÿÛÞ›>Yvwb™yÎ}{í[WõR½£ÑX@€‹È‘ì¡©Ñ2áÙ–gÕL8v„ýaÂ߯„ÿÇ„¿X3²‡;4 GÅ ¤‚h½¡×ZºözïÞ“é™yî}½ ‡¤(*ÁFwÕ«·Ü“7ó—¿…)KçÉ6ö1Ä‚Z d&B@$BŠ!´”,H"†ˆÉZ»HZAmA€€D(¦Þ+ Ýè?f¯CèÆà¿½]åKÒ ®³ù‘žõb\Y8õ_üHíÙþ".™\X¸´¿q“wªÍáúþh8šá†"qíæ•‹g.Í/Ìúõ¯«Höƒj'Ñê]æý©ÞÙ ñѲ€Ì ÓØ¢ÊVzÓvkÉv0¶›u‡¬ëÅ_ÓK/üÚß±]ꇀ鵑5Ø-ªY &\¹ü âýµÍƒ½]èYr檻­FÉößb’«FíPŒpgkëÆ»×ö·o‹’ÿÅ­ÕÎpÿÎúîîÁ­7¯ß½{·[TçŸÿÞ׿û¯þðû$.ÿÓøûú•W^zùå¥É#pn]Úš?~vea~îøÜÂâÑAåú•Œ.‹õ«6ÒlãyÝÖñ“§¯½ýîæÆÝé'¾õg_+ a¢! IDATz2;¼3èu:Ý~Ñ;¼³9”òÂSŸ_»yïôù‹Ã˜Î<ùd˜ZžkuÝöäîúÆ™s§O>ùÌ·¾þ2í\]ßÚ»zý7×ߟž=º»³ D­¢“¡ß9¶vÿZo0€$³s­Î¤šÄ¡H¶8‘ùc‹+νýý<ýÙÏþ›?ø?Í ‘ PciÝHëÂF§ž;{ûÊ­n·}°¾ 0©äÈÊÊì¿ôÌÍWTÛŸXæW-XˆÈ™;.­b>{êEØÝ³O=÷ΫWŽÎ.ïÜÛ<ùÂé+o¾=³ZLwN~û«¢>Юކåg¾ü·Ã>ȯ¿ùÖ‘“sn€Ïœzêî!Šp¨ÑXÔ¢Xu{½£««KÇαM 1Ò½=…€Hƒl„ZEKùB±ÕŽ¡àÄÕ¨dNb¬êlB^ ”0hÛ¼ N@°]sa.ˆ@õ,àÅÇ|GVæ"6QÎ6vs(Vfs’ôÔ´\KÁ›§5 7ØFjâ,̹µ0R†%ÉØÔ›ì¶« XaÑH2eš¢þDáÞ›ï,ö˲d}Z©ª PãÄœìƒ-¬‰5œ¡JRV„X˜«ªbýÁ”ÊQÉ(¡ÓaF ñ4ö¿ÃOÙ²JEkèvz´_ÁCÃæíÕCÆëÔ~êC bŒùþDɲi¬­ÞÍz²ŸÆdQ$Í+4K÷«DAºýÅåÅíjoõè©?úÊÿ÷W_9}âRØ™*¤|ý+å^D”/~&m66·gŽ›î϶¨…½ÃÁäÔDgjóÖ=3ó¿ZòVOºËýùÁáÁôGów®½53yb}}cXñ0ìÇ!îÎô§·oÝ-ˆŠ’[7ïl–\âäd‹úqX¶»ƒ—¾ð¹+·®¬oÞ;ñü W®¾nõâÖÝ«V¿»4ä~w‚[4Ù™–ýCdØ]¿p°ïÊäKÙFˆ Ca¢}¸»~õúµª:Ô+Õ*ÃÚdhÞÑ݇Q `áÎÛS G~øú«Ö‰õ`fnarЗ{{{·¤¾M]Ç :al·B«;77¹výþõ÷ßZ}ryå襵ÑÝÎt§?IGæVÞÿþ_žzò⻯¿ùÃ7^‰1¨±O-Ξ8wfùô¹ýíÝåGÛ½.Ξ˜96÷ä;—_ë¶‹Hˆˆ!„V ­)`(b§]ôûýÁ`²U´Z±(B  "¢€B ¢ˆB(b¤P `BK-ª9¥T '¥¸÷°X-2‡lZËi3åâÿ|0œi࣑_ɾ¢wÝT²– Uí$À$ÐÈ_JLeQ^ªÛ% Tº´°-1@*抷ÆÓ¨Ô‘R]ýX”MšXŒ+’@ª”FU%FJc¥›VÎQ+WÌHx¸×þò§Ÿ–‘Up¤.î UJ%W*0ªRJb™^‰™YÔaU š)ËT‰·,‰«JD †dÖõ¦Á<½²O5‹F%J“©_½0 ƒêQÈR½ZÂ&ÏÓ'2]ÜÐJÑÚäõ§'ÚݾuüÐ/Ðb†²BNu(!6Ã"ë>Ve“S“+'Wºý94³'·]æcyãÍ·¤½½ÏÕWÿà÷p}¦ßyñå'ŸþLk~p°½ÿ_þêß^»¿¶°2½½o}ÿÛ'f/üàý.žš?ØHÑÃr«^8d Ã‹B~±05;»2sþû¯¼6<Üÿüß=u±¸þÖÛƒùiNí©•¥ýa’žœ8~ &ƒ¢ÝÚ½³—ªýVìÜ¿w¿, _|éÓkÜÜÙ9ˆÓÅ3OñèùcýÉùöd·3ÑÇ€<Þºy·×é”Û@ÐtcË ï€ã ¿g—žz1ìÁʉ¥ï~óë™Ç‡žžAF ¬?ÇìÐ>÷ü¿þÿ{1(úÅÂÆÞŽŠz§fg÷Þ»êÂù´;,¢ÑIEQÁTDîTÀ™ ÏÝxï-@\<¶rãÕõéÕ™ÄÝ'žzáÝwïV·~åKëÿþÏ€ˆˆ¦Tug&º““KË+Éb%éâs—®¿v£ä À`bV•‹Z3DB„„ Ì$€„õ}Éôë¨Þžbˆ±&{I™uéóž¸K& iæ} yÇ//ÅÃ?ÿ_þ9 B›4ZY’·h,õ½Á; Ãp*VÚ6&±hȼyÝô°Å"X@´8:¡eS·˜ ‹©tPX| eçWµ2Ì b¦ªhºì$Éíµ Óéüåøó—~íYÁ ñe BJŒD -œ ¨Q rJ¢kHf$ $@• ‰Ü¦Z„E”'Ì_} Ìx}.]À––…4ž¡ZÊn·Eƒ!=ÃÊA2ÞpýeÓf¡a#c¤»$¨¶ZÆFn(ðhï>ð8É1Û¹bÃøO?@€áúöÚ˽ØÛ?ÜZßÜ¿ñÞ•?ü×_Y],®nìníü£ßû½ã÷¿ÿõÙ¹ÕO=ñ—­œØÞxsjõÔ¯ÿÎß¹öÝ;í%Z^|jjb°tüØòñÕ‚rsÑï¿9Ò±yÀù€[ÃpÀ['άv&EÑf–½í™ùÉr«œ˜~ïýË G–1ÆÑ†ŒªQ¹17½0èµ0¶»ÐÂXQ;ô§fþâO¿zpíÙç?ÕéLP+ GÕå+oÌ/Ÿ`‘`bfj¸±Ýš¸v÷G‹‹«HÔ¸µÝBt®ˆ­bsíæòâ‘[\^Y=Ùéôч g NÔ­£uÍn5œ½·ýÚòâ…­µS³óÚÆÜ< Þý›÷¨[ô:]lÀ=.­rá>@ky ÖîýxñÔÉ©N«ÓkÝ~o-vèÜñ ß{çõ§ÏúÕï~ ¯®Jâl´JÞÞÚš]œ˜ž^©T  UtÂ`ªZ`¶À™“!¢Ô"f·ÝGÕífµ°(ÉJD›ÛÚQENI( ³š’l™Òd\¹NÙ 23×ÒÐ&ƒêu$Òl½·R7Ø,TØxÜè«"G¹œÓ¤ÑHyg–A‹ÊaWýrÝå» _“haºšÊi,äÖÇ|BP$U\UUå\©Ï"‚T‡ås_ú4Å5÷ªRJ©ä”tÎM‰yT–eU €H™RY•Uª„“ò晹â$"W‰Sª4ºÚWÈ)éB(Y~¶1GXs'3}0ë÷óÞƒ¡E•†8†­?D§Ò?rV‚Ö• ÇÃré¥}ñ,Ah¯Lì½¾»~ðãßüõßþÖW¾’8™­‡ˆ îÝÞ†©ÖÂÊ3‰e÷Þöáýu>vöd·ÕÏÙ € ° pÈÝ u³ŸwC1³Ðlð©hµ‰"§ª*Gœ*pÝ›½ƒ$uo…"Í[C®ò ‰X^°Râ*U•Vq²È-]õ 3$• ªYƒ&ŒVI”yõPñx`Q°Ðœ1’Ʊr3´ë¦3ĈõÍf !’KÄ%v:EQÚÚô­ ÑžD‚Ä’ÜM¤æ@ sÕ_5SÞœ. ¦¨79[=’ïÉ4hëp Î6«ãèºV™“'f4,™]‰]SQñ1šŒý4ŽK´f]þÚåË×¾SôZ±,[£½ý¼úÍžúT,f¿ûÕ·ÏŸyéøÊsPÁó—ÎÞA÷È`šŠ;Wï,ÎyòøÜÞÆÚßÿ'ÿÕë_{«è zŒT»QjEdñ™ãÔÜ\»Ÿj©Õb)°E#©Z½TD49=±$>Ø…Îþ%Q@Æj”žzö¹Ï~ñÙûoÿ¯œ0% ±§;í?Bˆ±ç–ç’ÈGìºEÿÌìs“‹ËÕþh{}=û9~ÔÕ½–øp*‚rì¹åÝËݽÃõ™©U³««Û£”Ï-­î }úËÿÙñOpUåþÖw&'&t<ˆÝv­­Í\wÛÑ,-H8~Ñ &q†¿¨‰/0¢‰rÐ$ zà"²$eÕ{]Ã<ìÕ`vC?hf‘[‘? @aáT ³%ɇ²£‹º€;Ê‘Æó¤*9M•Í\%1 Ú®PK0 ! ëNÍ@a]jÅq¢‘ãֵ߳Ñö àVãbb‘ Ž£RÄxçÝk‡å¶R.PÜÞËÆOÍ~ €ˆHÀj¤ÃšŠH$D™¤µà¹fB/ÀJZQÊ…i¨u"•dM–<â¶Œ ±7;Iº¤3%"›\›Ž×Ž(§X¯ÙšÏG|çǃ/נиê´#òQG10sáL%+.‰E@Ì KœŒ" 1'o RnnîÞ¡X1RC$„VEŠ «b Ñ’ uÓAЍE' ‰#é»"¤tk­N8Á\”õ‡ÍgËv“5çÙÞºØ* ˆø‘M ¥¨}ܪÕétâ#‡Íj´ê8û&¯b|xÑÒ<lI$*7j´±uã½·û³‹çN¾ðÌêÓ7n4Ѩ©#ƒ­õ͹‰Îέ{E:¬ªûÛ›[‚ÕÇÎÿðÝ7\1|¸å@ÎU+ÚéðÝ­èµïܾIi}»5ѦªÍÍé `éÄbˆ-aŽB»S–£É™… —^þæŸþ;ÄÚEúíÞG?[‚g:;@wÐëN,˳'^üæî†òÀÍ)',\ÕMDŠn{brYÊ ¤/éòñÕ'ïlÜ8²r¬<<ü¨>YBˆƒ¥c7?ئ„€Ð†Ùãg™¥]ÄÉ^o4ܳ†Pyæ…Ѱl”LMtâÌÚÚ HJ•’Ù`âD¤2“ZÊed‡¸“V æ$œ,äÙšX±•³ßsäÚ÷fëCÁÐÿµŽ`¬ZS  ŠÚß™õ¨CŸebý „CbÐ܇!’™¹@¤ ž½bô*…K‰‚úé‰J ºþŒD"2¨Jº ,b  hæD1D•DGÄè›÷$|ôı^w@@ HA!"BŒˆBˆÀfAù ê™î€Mù»ëÅ…øº›_*±”%I¯Ó­î–—_ýK ‘pJʺŽÔîõ÷öÕR©¬ªó_xzj°Z–#õã¬RJÌ%¥§^þL%EÅœDRJe™K©[1EvKªÊªJÉÒBYP' Ö-¹ vR^){ø1 ­"Æ"×9É*ñ¦d¶¾Ô<¨…$‡.@@ ÑøA&oÅH¨.wÄH(…šé¹Ü@ZB9ñ˜!4L¨x¸’S ²$ ¤$8‘œm 6"²°p‚""»Aö—’Z£ƒ@*ßb$Ú¹¿E !¢ ¶uœ&3¡P7gtžHº÷4oü!Ãh¢Ü*a¡óýœtï™ba}kö@ÂŒ€@G—Vè£pY«¿ì«ý´nh:’6¢m¡9Ÿà#ÆÀüj?²(v©ûöÁæ)¨5ÉE¿¸ð+/ŠàÓ¿5ÓŽUJR pdéÈæÚ½Á`7ÎÏÌ|âüɹù­ýíóç_X{ík•;ðf4Ýß;ØëÄZö¢ÌÌΈˆ±ˆc; <¾têú÷ŽÌ9ØßŸî-ÀÙÏ?5³¶píÞÚ‰…#®ò¨·o·º¾÷F%0HpϳÁòäÊÝå²ÚzæÅ—ðï¿ðùÏ&·[BT™.¨³o³£F¾Õ‹µ§÷·7&&çB Š9b”ÀÉ/.»# ³r+X"Ì^z¢©JV 1W±ÛÛZ_Ùêv{)¥Ø*RU&f PTšs«Ûép«ª’ú£ '$‚ P¤€Ìöì8놈Ԗ8 Ž<ìAç*¨yz1FiC¼¶®õþ¤–ÖšUø©VŽ"bDˆDÑG'mh¢ * \)D¢HšÌAMHÑÝJ‘Tj©†ä(‚ºÐçá„û@ „ Qˆ(ù3 Qw]œ4¼^<ËÇ"ëm½ ÷KÃJö»½ ôhΫ ìgoP õ£Fûb9ÌmUeŠÚèª9›å+'qtÖk›[ d¼ÆÅ3S•Š?Ö"I  Ð”ÂÇÙ[=’¢ÕdfIRÒjU/—ë]3Ýyééψ—ffˆ;V(z­N·©üþò—¾ôæw~Üï»{{g?~íë§Î~úÎÛoÆVqñ7OûÊÖ ÍõØßøv8kdª×ÇÚT‰k)™QjT /I@9Iè¶Z±×§Î`XU‰%ÌÌ-ñö^ª† ȬH( CUiŒT *ÍzJX–ª…@¾´Ë9%®Xô=äaqPîö§'‹ò`·\3v% °&žX/—Ø&ʼIɰ;LHBlé Ì‚û{›Ì•í-3IÕ¾*sD!l‡Ð  ²€B±Ýé–ÕH?ý$ÂIQ¡ ¼º*%¥XC‰A TLEzصZÌö¼š)"ÉlʵŒ¢¤Ì¤f‹GVíªòö$½Ý:OÈÿâ⪨Ìàq]û†ä„€’jvª3䯥Í ABÒGò.¯•¬%µUQHüyAm„@„!õZÎ) ÜL€5KŠ:?UD 8ª:ˆÌé³°Ñ´Ff[h³¹¸ŸŒi™gÊéàí&ùÉ×ö†¹ S7EĹ³r²ÓÁÁAÅå‡t2>¤Ùm Ajàã_5¦7l,¢Dhn¯!!ëÖ¬}3óÏòè\;îݸ{gmMù52æáU;§=ŠCgÐßß­cå„”çOõ+(7éý·nÞAÀ´¾ð½} »g‹ˆj½í©¼I=`K%’,jXÏ¿ {Ì*«$AÝ[A¨0CBUòÓòê™j4 $•Ú,ÒiuîÝÝÈ‹(¥Ñæ³£æo‰% cD ˜¹1boH:Ka–/Ÿø¿ÿÕŸ\¹ò£SO=}ùw  !ØÎÖÜÊ(ãûÜ ’´gû[ïmÜyïMŠüZ€?ø—ÿæ/þã£!03"R @5*GóÆEK.ÁV«E"Lb$Âéb¢¼¿WñHwÙX˜Ÿ\ u«³0?ƒ¤•®D *§gaµ£"ŠT ?\¢ÙÉ„ÎÍDWI5Ï.0ŠDÁ~7J0Ës `±sàQ*ªQFDAq iØǽtV„±ÌsvF6XðÒÆõ~@²‚Z¼F«ŽMëuddÌ|ö\EÄ› £\‰öí/Á²§Ç(RY +$¶ß#MÏÛÓ¡ïë”ršXRfÐÕ[¶:*šÜ*¹¢Z°@Miö­¥G•ákTG³és-GC£Ã<¦ʲA_”6l[Å4æIßt›iþÁÀ/@™ œý¦69]W•ž•óÝÍÇJ³Àææý’×´yq_ aNI£˜¡L<9¹Ø›Ú¼vùGe1<òäÅ«ïÝ|öÒs¼} IžÿÒêî½\ñªd¢q¶˜Hm4p"¯G™Ë„‚µŸˆˆ©þqÌL]y»nÈ"PtZ½^/¦ª 8Ù~ýGß"ÿx  D +PÏkëŒB‚F2"”Íxÿèïý7¯_îMv&i’G»yhxïP`aìN"~Û8÷ü¹¹¥3 DÉô—ßý½ß^œ·e®`V† &ðR‚˜¥<.·`„.œ\mÝ@¬b,²†„(†@ä^ç½e^¶åH0"9ìk‡„DP*ËM0 aozò@¨_´7xïð0Mtgú³3¿þòo\¿÷Ö‰•'Ön|#w{Š-2æõ¿Þ‰±yëf@¦?=ý5m- GCª*ÑÞm²µ™ wê“ÃQE.EÓû$³7ýcvÿØ4Ò›agÐMIŠ€¹—èõçŸ~aÞ,IšDØ>\°EºVj[~ù[$ ”?34_u Æ(,•°™ã‰"D(‚)P­O¨* Rj%s°¬g ¡ûYŽ€…Ì,Ù¢ÞEÌ=ˆ‘õ ]ìcáÏDÀìwý(F •LrÊÄG=V,F<#{rׂÈ9_M´IiÈu™Ýœ_3ã N©½ž•dÆ~hõ–¦Àa1ß@Vì ê{¢ AµñB¡v› €ÁZœ’ Uu¯¢ª>ÍRæDQ(‰‚:‘¬¥bFÀÄ% ƒzœ $NfŸ.¬€i°DB0LìAd™« b|Ü.΋5JÜÕ981IÔÏMÎ,H(u2‘ 6¤Úp‘ƒ?²¦s‚ TºÞP´¹P;G_i‰Î‰%†èABµ_ŠDScÚ$ NòÌ¥Ï|ó;ß8½ôÜpûâ‹/nÜÛ~ö…Ï_¾óÝ™å㇆KÙ‘4ds•(¯¥Q&¹ëHCÀРäš*À— VŠ¢¥/»Õë<ÿâç˜ÁØ;YÔO5%aÆr ·hÒ¸3¸²b‰äÔ¹'G•¤Š "Î|m€¦µ’1cŒ†à\|R±ÛÖ€°oŸBðÔv—|Æ@¨B¾¬½¤»y›¬ÔÈ ¢Æåå49!"AŒA/ñˆ$ÀÙÚ(EÔ¹ (šù†„¨/\ bH‰ ƒŽj1Ç‚„H tüC;bŒ„ÈZõÅΤ貞´‡duøCŒy<àÚÞïSú1rª8a %éFOÑ줖*ÈÆ¶f` èîñ‚Ê_ÌÓ²ªÖdÖöË“eü¹É' 'PCm$ˆ9%q4—"í~¯^U ÅÇ ÷¯ª ‚„ª"Bf'|‚¡îh½dJI" ‚ÝsˆMÙXq¥ßÌŒ&ŽBaÆ{vAeÙJ-ÖèõÊÏxäVÎk…0£²ÿEPy]µ¢Ù}P h'¤Ÿ’@¾Ì•¢B^\È·Sdw| ‡¿vÍöõ²+3\ânC"iÔ7¡½fB¶£.¨1“A"Ãïÿÿlć“ƒ©v·Õju†‡ÃVÑy¢ú\·è¾ôò*Ö]símÀɘv˜¡Qy¦`“¹/¢‘: +æL˜˜%Ý™P„D"È­))†‚A‰A¢Íú@ŠÅˆjàÁrxA$4—Õ@¡[ý7ÑvÕ+8€†‡øpá!Mzþ ÷”Äz¿ëE¦}ü¶¦Å ¢;ßþèé"G˜1cßæ(c €` :$½4ˆ¨£nÞ=Š¡²…DGV²ƒD`&Ö7_©'KÒÂëEËï¶HŒ6(i^|¯1q…ü…ZSEcr§ íbj]¢zabI*Fu!P¨§|)Ùiµx¶ÿÓ[Níú©û:®"¨…:BBJª³!$«Û"””X’ψe²)˜0AfA¨Xbh÷7ö$3d"–H ‰”©ŒÏ ¤ëaÂl R§ún0@@iÄøIžYbl}P±$2R‰5B¢B6/ì_‚ã©u÷d½–@Ô‰…„adëJpLEâÛ@Ó( 3ªÃ—É3l¬@L¾Ë *ÙÔ"H4·tDoõD½~Á•tÚƒpvv¶LVxHçq†›¢° ‹Õ%ÑR>ïäºsòR³k‹šû[j^‰ÖbjÌbú‰š1‚Y翤ÉWÏKwK¬c|̓åh$‰[NÓ1ã?c?ø$,ãv›ø?< ¿’‡h-’Ù`ÒŽkåo†ÑÙ’·Dš+¨…¸rÑ[»äóX~Jã™ER× ºÊUÝÁp©?5]!1cvçqÿD`ŽÊöTÉr$b&³…ìúë Å*%A(±ªH}XПe–HȬõ¢ O®R…¨—¨Ãs-‘BÆ[˜L¤X› ÷²øur™­f&$ œ‰yà°áf’H´˜-}Ü¥Ë.WE¸Ép;T9Ψ2`‹H*[¸£^Y"„TUeQD´5“w¯wÝÖS Ô¸qíŠFn„¼‘wFœ²- ʸ®¸fbqýêÄÿ3{Ú³x‡ÉHŽ‹ùñ&$·@N’IB0ïV Âìþ-"DVP4µM7?!3ªB.)ªì¬a À$¡@$AðA†<Önp Ív3²ñ–<„Ö®F1§ lµfýRêXG8¥ÜÁÁPZÝ·è¯û‡Ÿ,4éaªå‚ O«Kâ'Uü)~$˜)QM6ŒA1H" DH¤ª 8±ñU¾¢»™”·¡ºÈÁƒCq`!ã’úX²?nE’€’°Ý˜”=PiI#"Mm"î¨ìJÇ0Ý _RÂQ?hV÷tf¶Ã,€(@Ñ"‡+Ø€ $¬QwŠšœ $ Ü=&ã—~AÍ ¶mO|Ê#âªdÊÙdTnÈ‚$N_Ï·Q€Ü† L€iz-ꔞZ¡€1Xའ$frCoÅ#Ë*‘Îÿ¸ñîEïšjïð1€Ü>¸œÌ RÏ3Dtb¢ùÒ;kµ(:R‹Ž@V1„ŒhMÁ&ÓBC¿óv† Êठw˜É×L o[È›l8Êø»ñÐy÷ó³rÜt€zà]}Àñå ÄGýëãäÍ8V•ćµGÕ—æoÈ=ZV8+`rj⡚øóü‡ԣÁ!Llx¸B—µÆú,ä ^^å “geckCú‰û>ÛÜÜÈRAã<9=‡íâN ÝJ38{i9c›!;Ë(ê>{©Ý¯¿Ñ¤/ÊhJäy) •€(ÁXmJ§Baf­>V¥t½DjœÏŒ„\;À:Íy§å·1@adwsEÅ(![8¡H•óÇ•7û9¶›€á²H ©¦Ä)Ûœ*³B5H˜”–vyÙØM(‰™IÀÚ8¸¦/Ûæ"áõ±ˆ”1h¼“L¹Æ{“¬¾BîA·õfv”¶- ^ï þ´Dfw•üE}eà?¿YÅ.¿ jõÈH 9ëúlŽŠ˜Ç?æ*xƒätú¤ÉñePjkråHòÓ,‹9?‚dRŽ—,¥ó©É "2{ 0c&/¡ kë%I9…"Ñ¢•’peƒY¿Mb#DD¬DóQ A¢Žg Ìœ1I’(ÚDD •0‚D;y"(¶Ë0‰ à,fÍU"Œ@¢ RQƒ°(EXÑ+ÂPD`ó§"Rö’„ˆ$¨vV@ˆ$q(b°•˜;`ÔÕ­¶ú1D´CæÑc­°Á`$> ö\îóà öã¯Ç\äl Æñ -J–4i ÀCNX?ELëGê‘0à#D@ê„ãY?ñâÝM1m‡{~¡ÝÊ_EµùÙ}&MFrÞ:áÇA«æD)2FjÅ,G`!À¤Ä7©rÞ\v.!aQ¤‚ØÀ'RÛ…VÅ–ÿ’e»¡C†Áè2 EEÍÂy— õDE Å1k's©­Mì”Ý€D‘ÍNT= Ä« #FDEµu:® lk ¤¿‹ÜsƆæ˜Ý_M¼§]'ÖQ-º2ƒ¼’Wö0¡IjËsME{9Ój H@Ò^¬÷[PCw£ÖXtœÕã¾\ãVÄ’:Æ%c+ò1@#Cð?å˜è˜ÖHqh`gùäÓϲ˜"³æ°Œ7myé÷ñêÕãº=ük];~ñ¥ a,À©ÜÆFÖì1Ÿ.i0ð¹ŽßS:±«•uaÞ0d‡¬p0vš`3ëˆ`6ÆN¼õÐ=û˜Å”Ÿ‚ $OKÎ,ó˜Çö€ hiïa²œ6hÛ_Û[§“ax 4A˜+f§¤i2y €:µ+~\'„IcÆî»ãNR>ëæÆ¢þþúÿñ5pŽÀpšífÙɨ °Ñª–ßBÐ)œš2a…Qœ µ?rÞ£bÂñëfÌHàa³MÈúî ©g~°¥jÀÆ?«€ãCþ'v+oÎ>ùú):Äæ…,y_(F›Ì­ºVÅ„$Y8Òeef€Ô¹ò*t0'qÉ„5e> +áÛ4$vàA½8ê›)6nâç¼!õk‰TOìàÎ|(ÖÁW‘†¨#*›¢É~7[¨*ˆÔص[-ÖtF×½;S[PÐ9!ÖÊþÖ± «8ÙXþªl½ß(TV8êÞ†ÇÚß,ß hPŽ]líR>…S¸i”ÎÎF¨ã0ˆ nÂ/cA|üBç³?ƒëõê†ür;ˆŸôT?Ó©›4_¬£Ï›b^ƒœ!ëØò6±¶±uqrßëÆ–páß™°®Efƒ!ÎMgh¶nRãfµ‡…R—QÍÍ ¿&èÉ`cé\ ·<5JF‚šCZ¿ÖòåS¸·JÍ_% fª¤]âfá<ÚæpöðÈ\ ¼bÅz›Q÷®àæ{„å»Uщ ÖÓe•¢­úUi&d°<×)ðJÖb-›Ã»‘˜ H^ÕÑH_½+'ì­ä—£RàÏ Éúäë—²Û2€"g±>xUª.ÅJ‘±¸5O73RTȆH)Ú„âæævôÔÏOG-U8Za-%f¥`êwr渃R1„¶adű!švA€ÉÁyïÑ=šÝ0Þ•5:læ„V7[pg¿É£wõä1„úBHêT=®©OF#7ÚtäU¨Q‘´˜³¿×AÁ8 ƒ\×U¶dNyÛ'æ‚IwÜÓ¾Õ-1,¨PXŒö,Nšƒì•6‚ØôØÕñMA+µ6ÿÑ‹ç¿ÂyágÞdåH²O¾~I¾ê6¤±ýtÂJ¦ˆ ²ù4äöÉqHˆŒYëÆ’Tζؼst?F2‹w{J¸a$MôÓ_á­;K öPf{ èÓh"õ7­ñX)iÚÓÙ|c?kQ >]ÜŒ?&܃¿Ö[ÛRÍIœl³–¡ «1ê;”Ǝ˰Œeœ5Û‘D2C\ß=Êœn1±IÍÄw=„ïVô}³jËfQM«|cðêNŒÙ#k–êøKÐgÉÏ­ÃúuúåÜÖN uÉAÿ¦¬#ö«™É¶à`ŸB€´Æå>E/mFK`5f¨³y »'0™åMgÔ°Ì|L4r 6V™bŒ=ŒLjŒ_ç쀶͑þŠÔgƒIŒM˜{PFKÅ¢ä·x6Ytß×L'Èc ‚¼À{x6v¶PwGî`ËJçÉœ8©W|ù9‹ú‰I†ÌM°cò%“U‚‘ƒlÎ×ôÔŒIÒÇñâ• »¸öƒèÜøWW¶~;û¬ˆ§)~2{þÕß“šŸtN¦Ã¼Í“Lu$%»áYˆ² Î¥³¡••<–‘ö4q†üûÅ=|u”†S @^Ò‹`$£ƒVœÐxº•dÎwö¹ÌmO1ƒ< ú¸‚¦ÑEŽe?Š}[c!¡5 !Ž-S³„ÓÅŸצãí<çs6÷†u‹†±9DÌä¹ö]Ƽh30˜¡™@ÍÄCÉ÷’¼Üã± a&—Maø³®¿œHù/?Àÿ7·zD «}±³e¯9wcŽ4²>×bÕuèàT[Ñ5 ?Ló ¥Ï»4‚ÜgI‘$Ÿt?@‹•ŠÅZ0AbH(1³¸ô˜!d;qÀÝýPà~&úP^‡¡$KL5¿v³ö°ò„Éi œ€¥ã±9.PY©é¡qæU­ŽßµáMžÁ 5jêÂ@­Ü…#®¦Ù4GëWÝxz€`ö5pbZÓmÎn¨š(øËh0¬`|<üä듯_ d™]=2x#ÎçD€&ªã‹Älœ›YYMµóØðΓ,âÑ[»i]벎UIi Æ´Ê+|Ÿ¶=HÏØFtÅžŽ,†Øö]ÎËœY}ÉM—r_–líã§^6¦ ’ú Ö³¡•L­$J‡•Ì!‘&¿Gâcy]ŸD!®±A,“òä&Ðà’‰iÔi êÊf¥”M½”ûbŸ4Å1ÌœQ€Ø°HGϰÃG°þW®ŸÓH(ŸTüŸðª{~=€fWHÒ¤@9ää†êVŸ ëûļߜ™HJµÖDÜv H¤HhuŠ}ÉÈëŒæ£T›€;{É»yä2’ó²*¥5øRPòQôÕ>¡z=ª’ “Ù€Ïw“µ1Ô[Ì)‚2Þþæ«ú9C&jøxåù5’©ã¾á ¾ÕN!º¦šufc^:e²K@Ÿ®¾EfmÜ’œ)Éõ°f³WŸI6‹GhRÀ &—I£äÒ8÷ýoêÙû™ƒeÍË ?©X?É`ˆ™3#•›&Ã~‚¥1 ä?çÈ-.Ñìh¤Ò:@µÞ¼Wœ¦ª¢âDS”šÄ`[Gí¥ ûF#å$:%Áˆ1×Å¢ÓA¬m"ªs7°V]­pü¦÷€^ç“ø‘õJ/«ýúñ“7ë'èpÁyžÙ,ªT¿ÌÒ}–¡±#l:hù»­éj03Ò€P’ä¤U €–ûgf÷¦—Qz*‰ûÉÔö6š²—U~î!Í“û5'°ËÏ,±‰‚ÖÒÌU’F©ÎVùâ‹7ªñ*+·–'àQ0õƒi­0{*aœþ.Ú³QŽñ 0C~ÜÊk£H¾gc©Øüg Ì5Óô…£cUn„¬Zœú¶$ ÖœmÌR¨EX˜ÝÌw!Ä©’?9k?mÓ Ó¿h†ê_Ó™ý&«Þ—!Éͤ‘áq½›+ât)ž…þޏ×äIÌf‡¨© šòͺ ×öý¤<«šÑîË÷Z¸Ödÿ?ÈæVP"&ÞIEND®B`‚snd-16.1/pix/n.png0000644000076400007640000000463711147553270012115 0ustar bilbil‰PNG  IHDRgeÕ ÐW0PLTE¶¶¤©©˜;;5++'""êêÓÛÛÅÿÿæúúá““„rËË·kk`IIB%ù—ÈtEXtSoftwaregif2png 2.2.4N°ž‰ IDATxÚX=Œ[Ǿ"®1®5ܸ½Æ¸VHc 6Tê®UຈH`ó5ù“j®iTb“°Ú"t°ŠÅŒt:ƒúVVëš2•Àu\ÊZí Îpˆ/îaBÙ­ÛœÄ+=îxÂU(ì8 ­ÉÛØ]Þþ¯ñ«Û•Ó)äD¯hBø>‡‘ƒå›c°¿–"Ù ‘qa÷Š6ü™4tÄZ„]øËÇÁÙ¶O‘ÐиÍXijvF©”;"žYЈq,ì†..Cf”LB«Xté®=dÎ8ɱšÑÖO‹D»ù:ï‡+)ZÐ…ô>g!E¤ft : si4£î9µw¡˜¨uìfiÔX{m)òù‡±¿S|ÁB ý [ Øè!B‹¾FièÊò±]âYMžÂ³kµa„ŠKša™qÓ¨+äºnD>†j™“iŠ"÷bÁ¨6u°äÌ'>¼˜é~\o­È•¢ÃˆŸg>YW?^ix9P4\ӡ̆¨lÏ3ZÒÙ ›’×ÿk|+`7ê`ÅxýÅfð.ÿÓ+–@ýB4NÍ0r‰š¢ÀŽÖ¯<9-ʼn‚)kk Âù¾í§Ö¼(.ì·È}Zt‡cÆÒ”l¸teßý8B„¢?Dªì«gu(š3Q¸$8½æx‘Ï$Ì1pE~Ë"²ËÀÆ*ÖXé¡Y5Âá’P½ ú “Â+f…É¢±¬ Ãì¼-aýLFEÄhbY!Éüƒ"K?'§Þ±L½A˜Õ¢ðÖ Lˆ¦C.ør&qb‰ gvBjú ÁÍUž5D“†¼¸£‘³$¦¹nùËþŠoÌÚŸc¸Ÿ%âó2ÝmAAséá:q-ã{é€Ï&bR“d›‘QÍm¯š¬ëïË}4…¤ð¨ •có†úÔH¹Ûm}üwgž•üØ6ªƒ1}âñÞ4/{ìºÄÛ"?XÝÏ=n_°î@lÒúIäÚ¼§¼ó_DË4tœêQ~¢](ýÁ5‘î×~âõÐã8(‚ˆž2–ü±‘_FëÔvÏ‹ri/š2ËñûØmÏŸ5=Sô¨w¼íø6@ÖtÀü1Oà¥f}î3&vx }Áƒ¡yéú¥©ßIJ>7­‰É´t“­s;Ítt=¨‡ö’kÓ¹’Ùk•±3WÛHoŒçVŽ%©vÙ‡*î&$øÂ7A¼ãò‘}/.ÜÇI­Ý*1š¶iÞBóߪòe rØévÈÂQCÄôÝÚ°ù×_|ý}‡ÿŸMât¸FeMüUß fØ¡¬ÕÔê•.†¦Ê¬ÒcÆ¥JJU‚͸ µè#1•¡ìoe£SôTpX ×L6Ô¯®Å»«× ${ ã )™ÆÌÑYÝGz}¡Å—sÆ~÷Ê|Ó/wD±Ð•²®1 T1¨Ï½ùÕ7¿Êw…Æli¡:X ]‰ u ù·ç¶˜§8v¥ —e“)Ek¨Ûº¦Ö‚ºF3VöÄèîõþl³|´è‰0¢± •®eLá%m!õ”©Ÿ89âáM# ,½>[Íc™HÓY)kÃóMQïÜ9Ý7ô5¿pŠ>Ö°µ!ñÜɉ­¤•ê+¶<[Ó;"ôÄ+ `üËŽXYÃÜsPÛ9­2_Ÿ äá¿wJ€Y‡&o Ü%¿øÅ/~ñ¶Ø?ð¿ïåAêhÕ…¿ñåA{àoÎcâ_\ŽqªÛæõï^\öÀ¿äë /þ‚V4g'"´IEND®B`‚snd-16.1/pix/white-noise.png0000644000076400007640000001357711147553271014117 0ustar bilbil‰PNG  IHDRú”º4bKGDÿÿÿ ½§“ pHYs  šœtIME× #îñU IDATxÚíÝyTTçÝð/²: €ˆŠE  f‹’º=[¥Ö*1zz©ª‚/‹‚Ñ&ƒÑªPcB„ØØ´Qd¨²u4dÜÁ° Ìò¼x¼ï;7afø}Îñï½3—;¿ç~gîú\ÖÖ»ÌÔt!Úk•€ :!„‚N¡ BÔ;èX»víKÍ$::îîîhnn¦Š¢†ôž5ÁËË Œ±Î`Ïž=pppÀ?ü///”——÷yMkk+ärùs磯¯±cÇR‹¼"¹\ŽÎÎNªXÐ…B!-ZôÂôôô@OO¦¦¦èììì÷5aaa¨¯¯ïwc "‘>>>ÈÉÉ¡yEׯ_GDD²³³©äÕƒ®JéééÏœ&“É ¯¯O-AÈpì£÷'##{öìyáf8!DC‚…††¤¤¤pãNœ8;v@¡PpãüüüPQQDEEQE ѤM÷àà``üøñܸ¤¤$|ôÑGÐÓû¿·¹»»côèÑxøð!<==©¢„hRÐ,XÐgÜìÙ³û}íÌ™31sæLª&!Ú°N¡ 5ÓÖÖ†ÒÒR*¡ k³ÚÚZ$%%Q! :!D+è õÌÎÎV:ßþ2×ÓB4,èË–-ƒ··77,“É`jjJ-¡b …=¢BáÙt×ÓÓÇSúGT¯¥¥Ë—/ïwÚ?þH¢ m·fÍ*BA'ÃîèÑ£¨©©¡B º6+,,ÄÇ5Ë—/ÃËË _}õ”‚N4A^^¶oßþJïikkÃ¥K—p÷î]* h‚žž´µµQ!]) üç?ÿ@ èwº™™¬­­Q]]ÍËÍÍ¥ÂQЉ&9vìvïÞ]»võ;ÝÑÑøòË/¹qï½÷Ž‚N4I||<¼”!¿V(bÿþýÜ0]ë>||||ÐÕÕ…‹/ÂËË‹ BAWwww¥ Ëårê“|Ö¯_ÆÆF888 xS¦LT*Åýû÷© tÕ;v¬ÒSEd2µÂ444 ø½gÏž…³³36nÜØït‰D‚žž˜™™Q¡ihì·»žÆŒƒéÓ§÷;='' T( :QWyyyøé§Ÿ^jjëÖ­JãNŸ>M¤ Mðù矣¡¡‡Æ–-[^齑‘‘T@ :Ñ$©©©Ø´i‚PÐÉ“'Ý …BxxxààÁƒøíoKE¡ uÁãñpåÊ•WzOWWWŸ}lmmÑÝݪª*Ìœ9W¯^¥âRЉº8{ö,\\\úVSSÓïoW®\‰ï¿ÿ¾Ïø´´4´··Ã‚'‹ÑÜÜL…¦ u„Çè½­­­hhhÀÿû_dff¢  TT :JEEE°µµÅäÉ“_Ëüoݺ…üü|lذ°{÷nºrN ù•q"‘©©©Ü0]ëþj.\¸{{{ØÛÛC*•RAˆz}òäÉð÷÷ç†år9Ž9B-ñš%''#((ÖÖÖÐï3Ùx<:„ .PÁ(èƒcmmÍ­l]ë®JIIIXµj®]»†¦¦&¥iUUU ÄèÑ£sçÎí»2èéaþüùtÚG'êˆÇãÁÀÀõõõ3f *++¹§ßÀÔÔÇŽ£BQЉ&[´h¹0ëèèÀÓÓ“û?899ÁÜÜœŠEA'×x£F!  ßi'OžTŽˆˆ€»»û çiaa¥K—Rq)èD]èêê"..N¥ó´µµEhh(—‚NÑ4zTí÷»ßýzzÔÔt¢ñBBB”úoÿÿ¬¬¬4ÏmÛ¶ÑE9t¢N 1mÚ4•öóÖÕÕE…¥ ÌíÛ·QRR ÷w—˜ððp•ÍkÆŒ˜6m®_¿N…¥ ¿º––”––rà …‚ZA ùúúâìÙ³t úÀ¸¹¹ÁÍÍ–ÉdØ»w/µ!¯^#Ï•˜˜ˆèèhº'‚N´™««+ÊËËévb :ynß¾M!#tm·bÅ twwS!¼ .Äo¼A…ÐtÁŒ¹rå  æÍ›7$/00ŠN¿èd¨UWWƒ1ggg*¡ B(èåi1R©½½½066¦¢õßGonnF]]7L—À>ßÓSk"‘?üðCŸžc†R{{;Äb1¨a(èÏW[[‹C‡õY‘‰ú+--EZZÒÒÒ¨ôçóôôä:.ž\ëžžžN-Aí£B(èZìéÁ8B(èZŒ1†;wî !!Ÿ}öÙ°-ÇÓÝ­ÌÌL$''SÃPЉªÍ˜1mmmÃö<|øÀ“î¥ÚÛÛ©Q(èDUD"æÌ™]]Ýa]ެ¬,èëëSƒPÐÉë‡ÈÈH û²ttt ¨¨ˆžâBA'Ú¬µµÙÙÙX·nƒ‚N´=•‚NF€_þò—T 6äWÆuuu¡¥¥…¦~ݟΣ zAAâãã¹aºÖýùc000Pê"›µúÒ¥K•ŽÜÊd2:uóHII¡BÚG§MwB(è½é®Æ‡;wRƒPЉ6ãñxt± ¼ÎMw§6Ëóôx =¢‰‚NT¼é~õêUµYžàà`Èår|üñÇèì줢 Uý¢«£;v ¬¬Œˆ‚N¡ B(èäÿöÑ Ñ¸ ÿóŸÿÄôéÓ¹³fÍ¢VèGBB‚‚‚àè訖˷oß>|üñÇ‹ÅÔX`È/õõõÅŠ+¸a¹\CCCj‰Ÿ‹ÅpssS‹N'úcee±XL§Ù(èýÓÑÑQê‰6M ¡}tBˆ&þ¢“+((À¸qãàä䤖˷dÉ’aë‘–Ð/ºÖ‰D077Ç´iÓÔrù¼¼¼ðæ›o"..111Ô`t¢Í/^Œ¼¼<*BA'„PÐ !t­týúu´··cîܹ±¼!!!Ø»w/NŸ>M§Æèôšš©ªªBKK ÷ôRu___üú׿¦¤ ?‘››‹ÄÄDn˜®ŒÓÅÅÅHIIÁïÿ{*8zô(7,—ËÕöÆ¡$‘Hàïï°°0[vGGGDFF¢¼¼œEAÂÄÄ&&&Ü0Ýñ„B¡ÀÍ›7ñàÁ[v}}}Lœ8‘QÑÁ85R[[‹èèh̘1Cc–YWW , Æ£ “—5nÜ8ÄÆÆbË–-³ÌøË_þBGA'/ËÆÆ¡¡¡TBA×VøôÓO©„‚®Írss±dÉ*¡ k£wß}çÏŸ‡B¡ÐèÏñÎ;ïÀÎÎûöíÃêÕ«QUUEKA'OI$øøøh|'‹zzz5j>úè#œ9sF㿸´ ];Lnܸ’’ØØØ`íÚµZÕAæÂ… QPP'''èéÑ*F¿è#X~~>Ö­[>Ÿôôt¤¥¥iÅçZ¶lŽ9‚Ï?ÿ===ÔÐ#õ½¸¸Xé¼ëH¾ÖÝßßZõ™–/_®¶}ÝQЇ½½=6lØÀ + üõ¯QE/--Eyy9’““1eÊ­üŒiiiظq#233)e#1è&LÀ„ ¸á‘x­{kk+ÚÚÚ´.ä›6mâþ?wî\DGGcÕªUøûßÿNI£}ô‘E*•¢¹¹ÖÖÖZ÷Ù~~Ã’ àþýûÔðô‘åÁƒHIIÁîÝ»µþ³ZXX 22Û¶m£†§ kŸžžœ:uªÏø“'OޏóËÖÖÖ˜:u*Š‹‹‘››‹{÷îÑ BA׉áááÜAÆo¿ý×®]C||<<8¢za™:u*Ö¯_sçÎ!<<|ðZZZh%¡ k¶?ü›7oÆŸþô'üë_ÿäååaãÆˆ‰‰ÁòåËG\ßjNNNÐÕÕÅâÅ‹qíÚ5¬]»÷ï߇ŸŸüüüpæÌ$%%¡¾¾ï½÷­D¯Ckë]6œ¤R)À|||˜&ˆ‰‰aÎÎÎÌÅÅ…1ÆXaa!‹eŸ|ò svvfÿøÇ?Øo¼Á$ ;~ü8svvfŸ~ú)«¨¨`===l¤jjjb?ýô»yó&+++cK–,a¬¢¢‚EEE±ãÇ3___–——ÇXNNsvvf™™™Œ žNkë]fj:iؾhd2ôõõáãボœœ×öwž>ËÛÀÀÜøG¡··PTT„ââbDDDÀÜÜÜòã³Ï>ÃäÉ“±zõj0ÆàââOOO,]ºØ´i ÑÛÛ ###ÈårôööB__Ÿ.ý™îînxr&bÔ¨Q\ûãwÞÁ‡~ˆîîndff"##“&õ]OÇ––˜››ãñãÇÜóä{zzÐÓÓ+++H¥RtuuÁÌÌlÄÖû™A—Ëå(**‚……fΜùÜ™ÔÖÖ¢©© o½õWèW ú[o½…ôôtèêêb̘1°°°@qq±ÊγòÉ'‹Å˜:u*Þÿ}nü‘#GpëÖ-Àüùó!œœŒõë×ãÂ… hll„­­-,X}}}Ú´555øúë¯Ç ê÷@^XXN:ŵ—tuuQSSƒšš$$$àÎ;‰DX³fÒ{y<ìììPYYÉãóù(//‡\.Wz­‹‹ êêê ££477«íC0_)èééé8wî,--ôÌ ”––â›o¾Acc#¼½½±qãÆÝÆÆ6l€žžÆŽ‹ & ??_eAOLL„ jkk•NmíØ±Ó§Oïóú`õêÕ°µµE}}=Ο?O½¿¨¡¸¸8„††ríUSS™L†Ù³gÃÕÕ!!!°··‡··wŸ.¯Œ1mÚ4”••qã._¾Ü'èîîª‚ŽŽœœœÐÔÔ4ì—úΘ1`pAwpp@}}=Μ9ƒ‚‚ìß¿¿ßìÚµ ŽŽŽøÍo~ýçç:„¦¦¦~߯P(899¡··wïÞEuu5"##¹Í;BT­¹¹çϟǺuë¸q‡ƦM›úl™~ùå—X¹r% ²²²0kÖ,î`ëp™7oV¬XÀÀÀnuÉŽã”)S0vìØ~§=ý欯¯ïó%±wï^ZÉkÛgë¯?àþãÆa_n‘H‘HWWWõº¯¯ïs7Ý£££û½ÀäUìÚµ pvvÔ|NŸ> ™L†   Aͧ¶¶'NœPÉpkÖ¬Á·ß~;èù„‡‡#22’»4u Ž;[[[øøø j>%%%¸xñ"¶nÝ:¨ùtuu!44'Nœt6lØ€/¾ø<oPóÙ¿?¼¼¼^zÓúYÎ;‡;wîàÝwß}î&ü‹<3èFFFèêê⎄@pp0òòòÐÐÐ}}}O:ï—Ëåèêêðf¶‘‘Ñ Ÿ5fii‰Ù³gº°?þø#¤Ré —ÇÈÈ*y†š*ꦦ¦pww‡½½ý W>GGÇA/SGGjkk=ŸÇƒÇ㩤F<J×ìÄĉ1kÖ¬A/ÓÓ-‡ÁÎgÔó¾m=<m¢†žù‹nbbÒçYZ‡ê÷µ{öìá¾ †Ëœ9s`nn>èùØÙÙõ9â:fff˜7ožJ>›ªz‡õôô„±±ñ çãä䤒»ï&L˜WW×AÏGWWo¿ý¶JjôöÛoCWWWm:yòd•,Z\03kÖ,ÔÖÖÒ×.Ñ¡¡¡XµjÕ c¨ ]ëNÈ@A'döMwÆnݺ;;;j ¢5>|•ÑŠ B´hÓ½··B¡ÕÕÕ/|mee%„Báˆì8’¨¦¦&ܼySiœD"P(ìsðøÒ¥K¸|ù²Ò¸òòr…B¥.ÍoÞ¼ ¡Pˆööv•ååeèFE}ø?FFc_{ÑÒÒÒ••…ºº:˜››?óê,‘H„ôôt£½½nnn´Æ‘!'‹k×®añâÅÜnæÑ£G‘““ƒúúzXZZbâĉøþûïñ·¿ý UUU044„ qêÔ)”””@"‘àÍ7ßDmm-¾úê+\¼x<€««+wáÙÏ¥¦¦";;uuu7nÜàOgUÇöööŒ1ƾþúk¶sçÎg¾nÛ¶mìôéÓJï!ƒ# ÙöíÛÙõëש/éÞ½{,00mß¾'—Ë™ƒƒcŒ±Ã‡³¤¤$ÆcsæÌa=bW®\a¿úÕ¯cŒmÙ²…åää(­Ç©©©,>>ž1ÆØüùóYccã óròäI3èÏCGݵ\QQrssáââ‚<ó.B¢ÌÆÆ~~~´N4CCC¤R)‚‚‚SSSøûûC$A (ݲlÙ2DFFrã>øàlÙ²YYY8~ü87ÝßߟÛG}úºÿûßÜ´«W¯B àÈ‘#Ü{V®\ @€ððpÀÁƒ‘——hooWz’Q!ëßÈØØmmmJ¥ÜÍ/~~~())Acc#÷:###H¥R´µµ úÆ‚‘®¼¼áááèéé››YYY044Dvv6RRR••…äädìÝ»fff¸téÑÚÚŠE‹!::÷îÝÃþðxxx(õôR^^ŽššüùÏÆ7ß|ˆ‰‰••òòòÀCvv6¾øâ ¤§§###»wï† Š‹‹ƒîînî˜L&Sêñe¸ÈårH$ôôô ··—»±ëéz,—˹'àš˜˜ ££‰„»ëmôèÑèííUZŸî·µµÁÈÈ:::¨®®†——Þÿ}¥;Ÿþ™L¦š'íÕ>zss3ãóùJû<›7ofsçÎíóÚ­[·2>ŸÏÚÛÛigqN:Å¢¢¢úÝÿûÿæÍ›Ç\\\ŸÏgüãcŒ………±ììlÆcwîÜa .diii,66–1ÆXMM ³µµe•••ÌÔÔ”ñù|Æçó™P(ìówâããYjj*óööf·oßfŒ1ÖÖÖÆXrr2;zô(ëììd………,88xØëvõêUîóœ9s†ßÐÐÀø|>KHHPz½··7[»v­Ò¸°°0Æçó™L&ãÆ¥¤¤0>ŸÏÊÊÊcŒÕÕÕ1>ŸÏöíÛ§ô^±XÌø|þsgiTçäõÊÈÈ@ii©Rg ýõ…Ù³gÃÀÀ“&MÂüùóqìØ1H$X[[ãÑ£GHOOGll,òóóáììŒÜÜ\ddd ¬¬Œ»ÿxróŒÒßIHHÀ¤I“pëÖ-888€Ç㡱±†††Ø¼y3öïßSSSˆD¢>]>‘Á²Ókdø6A-,,”:2ìîîÆ/~ñ ¥×-Y²ß}÷nß¾ ===¸ººÂÝÝ•••(//GCCÄb1bccÑÛÛ‹K—.!""fffX±b¦NŠììlÜ¿NNN°´´Tú;R©S¦LApp0²³³qãÆ XYYq*ˆÅbTVV"11ñ™§œÈÀÑ/:y)wïÞEppðkésà»ï¾C]]BBB0~üx*6 —îînTTT<³7àÁ¨««ƒ©©©Òã´ òŠþ'ýÇ0KÙµIEND®B`‚snd-16.1/pix/fmeq33.png0000644000076400007640000000432011147553267012751 0ustar bilbil‰PNG  IHDR†2öê3PLTEÿÿÿààà°°°   pppðððPPP€€€@@@000ÐÐÐÀÀÀ``` CY¼ pHYs  šœtIME×13›xH0IDATxÚí]‹–£  ‚ÊÿíòTP˜­XzÊ9»ÎL‰Iî â£]wGë~­)<¾’²ñz­áñ…”aú‹¼ÆðøFÊ |øE_Kx|#e½€üE_Kx|#e£¿Øk /¤Læÿí•[Âã)ã}Gÿ…_Cxü(ûµ_{ÛF ?½ªÀoäïêPV•Džßê¡OŠÂwò~ïjQV‘—¨8ÑʰßÈ»½«GY5^ðlæ÷eYèÖæEµzs2ÿ¼Ê~!àéèK~0º~ª×_Iùï¦ìÍ–§±ó»X–]ñ‰!ºT¼FDþ¼Ì~!àY2, ß‚wÆx÷4e¤Îò¿Ž}…ùa°ó¨·Kyý™äbÃO°m|†äï¦ìÿ,ǹˇ˜6…ËqfýmzWî‡Idu‹"Uhø©ÀHaÆ\Ïôî~ÊžàEj͹3ôAŸŽu÷Ñ ]Œ\½q»ƒÎ˜ºY‰a¿[4cO^.àr†@ÁB×@]{welè祛pfè‚ÅÏÒ.гÿt{=ÍÐQ;€ÎjYË :ñèÚðR g³!:¬VÖÀP—ÞÝFYOç…ǃq"Û…´‹£qI¥ð¥Ër˜¡!ÌЪUy/µ¿1'3n5*ºËNÇsÚðR gaØQ×@ż«CÙÈçeˆZÆ×éuíw©¹Fbl f žƒÕªÅ 9ê"z~›);׾[|K^*°ä, GuýTÄ»*”á¥&/B`L8“¿bß0wAðiàøx:ºÇ¦qº·(kU€ 5ÔæHYÓS+Ôx~9‚{k ¡Qw‘ØwKÌÖ¥Ù”À“0Äû=êêú¨Ð»:”A©[áÛyA2Re I_ßa2(wEv›&‹Åù4ŠÐ§ù@îäL=ÞJTZ•rôOczcjUÂþ¡»¸G„OÐï–J­â† ì9 C³øn=‡Pw•(“©¡À½ðŒ»]Ôˆ©íL\ÍMjýÖ%Çõ²ôäžOG°Ì5p,5äœ#oB²ª8ÕµªÎ¤q½Z¼L„L+œ:ÎwU Ùyßvdm(Ãð“Ma\`ÈIRCB@½«EÙÈeØ ¼w#/:[ͺÏÄ—I§V?ƒž¬É4te1H씼Œ‡+uÆ6­Ê„!õÃÐ׫ú†jµ_ýÔÙsíÝÝÙ§Njk·d+b84é»=¬Ç3OsÃPÍÞs™. C dV¢Lî‘ìÎßÏ‹]¶ÍAþ/×ÇsjÕŸä/Ø¥œ$–j†ó¹x±TjØ)&zC¥Q CO¯êªÕÌJ±>WzÔ±—Z™±6ô\è\]ûDQºj8ÊlY«j†½¦o¨PSB°çrI$•sØTH¯®±ÓÒ[ãâa¨®Oè*†}.nSG¨£wu(“‘ɧŽ+nçEZ Ö99Á°P^Α‘×Ü«A‹U‘‡²õZœ·û?Ô£cå-@ÆYN>½Ú!;U|xÉQ'ÿä5 £^Ó7¢¶Çz&³çr – L`Äíð½x?ÆTzù;!°$†tB Ûç2õâ;'€ ¼«BY÷Ò™+³VÜÏ °©š®Û¹+Ø=³y¦Î5]…‡ECJLWìÙ“áèÅò½^Û7¢–ùçr "ö¡u¤Ÿ—§¯ ÏÈ©l"¨àpu=TÄ»”©“`àNô/`7@ÔÄ¿ßÑoF²«; ë›GÌsõ}Aì\«C‰tD¡ßÑÁQzwfR`Èù6æ¹Ln.g> TÌ»š”+žâEøcÎSáìo,éÑ¥ð&Ÿƒ\½}ÍçxÌs,¾Ýøt¶Ë13lËO 5ŸŠ¿Ä  ¦ñhš²¤S¢Ý¡enA…}¡Àé. àÑ2eÉl óf‡–¹•‘B޶GË”¥Úî>4F††¾ãÀ~5ˆà  œ†ax4LYº†š5ÝÞ‚: Ü—×»ï¡mãÑ0e_Ü(ìË./ð‘ãl¿öÖ&SÃá÷mIµÛ?<ñu¨±üÑ IEND®B`‚snd-16.1/pix/sceq32.png0000644000076400007640000000341511147553270012751 0ustar bilbil‰PNG  IHDR§#g5ÐsRGB®Îé3PLTEÿÿÿÐÐÐÀÀÀ°°°000pppPPPððð   ààà€€€@@@``` ­âwp pHYs  šœtIME× /.§Í`IDAThÞíZ‹²«* 奪àÿíå "øª¶}.3»»Z„Å¡ÿËñ‚Eú>~¦`¸¦*ë i¢ÿ¢™`ʾ÷Áv„´íºñÛÑÒ_2” wT `MÆâß hC¦)Ge=L~i Šhk.¿á£ÆÎý¥•¯U¥R{†ÞvÙ ÎJä"÷…º9}í+ËI`ÄBp¢°Sö[*”±ê{¤ìç…B'…ñ0Q¸eèëU‡šûÑ1‰‹®·3^•z"ëåd%ÌÅ:ÊÁÚuŒµÙp¤k®=PêßÚc²¡¯"E6€Aœ•ÈEî*_%,–ç„éu9Âk;1FØâ·$Êœ\ ߈ñ±I? ƸwîÝ,Öv"Ã—ì” }½ZQÔ=ËUö$ü ÑéÍ+™~tÆðˉ¡Ö‹YJ¶²SÏѤ¿-g€ø¾m½Ð 6 ¥ƒM§i0*ÏÆ«QKÚÒK9ë‡÷‡^@Ô=ó£ ?è'\/¸ÖNÔèb–AZaBO‹Rúè*f«SŠ’®„7œ‡±®[6ÒÁÜK*l GÇ¢œIÇlýëý¡C¾%I@äQ‰8-D>£ »Xý|‡°Æ +?ëÉÄé®é[ÚLj„F\¢d?G}fn CW섺1_Ƙ¿½=•;¯™õ {šô=‰8-7Û酑䈰Ʌ7_0ƒKöiÚÉLñŒé:Æ&Eð5B#FsÀĬS©GÒ¦“mBæ››÷™ ,Ép‰x½ò}Ç-°zìÎŽÌ> ûU±4L•ˆÓÂT±e§QÁ¾n«¢l82e)è]lCjÚI(B%¯·+^£Þ2Bبî‹ö\d‚kµAù vŸ!.Š%öNÉ%»-¾Q|nè®; „R=6ó¤°íßè »ç$â´¤ ×ÈÆ•ÐVÒBÉî"œx²» ³¹˜û†y³µ»î e%>Áõ?RžÁ®à36r­2X’ã’~TmüÒ€{y~è±;âŸD $3ë=èîÝ÷ˆD±Á&¹I£PEÉJÄ]Â]µƒ'ND<Îõ°+øŒ‹ð| Kr\Ò¼_Zpo…mbwÄ=院ÌnÎQ–Ð"íJ½ƒØõˆ£¶¡äAÜÕ?b‡½´kZÀ.„²Í[ ƒ‰ .)¶¨¢ba'óžãMl³6iˆêÐHRÚQD¹ÿ¼P²‚$”<ˆ»`ú‚TAÐ"Éò@†¹!两آ–—SéÞÁ5°ÍùH±/#Ô@VIF(éuçLÍÀ&>n&y>¿²“2wÎE¾+ùñ„ŠK¸gßëÝ×àׯYöåŠéViœQ²‚$#”¬çó㻪v²áb†ÂN|ª#ž¹÷ü{®Á ­€î:"b©dIF(ù1ÝÞÎCyÐ8¢€,pIQŠŠ…ô{³¤¤AÄL}jD6Åž¡,ŪH2BI¯P÷à÷Ìä`W4“zÙ)nÃYÄ%ÁY‹å+vÒïÍÄÌŒäm<îy#† H(Ë*¹F’Jnê–“íì“l{íðaµc ‹}PœG,+v‚ìO~ÐI Êr «‚$½Ö[ºUÉöÇ‹ ¦oÂeùo„2 Åê|’C)ÙJ}xΑ„²è&ý¼©[l¿p)âÙî w„é[%O%(3àÜÏ^PTÜì}s¢ŽxÎ["[JnêV'Ûó‹ÅñKýRÄY²ÝžB˜~ru`(Ùã-‰#yNÜ$,)xJäT#ÛŠåS½qšl‡m0Ð|Ã4xRðŒçxRðª³,ÙÈf¨¿xV¹r)â4Ùþ=¶½•LÉ“‡%WúpY’íÁ¯ò‹ÑNÞj—"ü¡È ²ý¤£gÏ̶¹ÒgìÉvïWñâC~üâ(]ŠX²í'Éö ,î³ÇŒgc×&WúÔzŠdûÛ~/ÙþkvêNï’\écvŠdûÛ~/Ù~gÜ#7\Ÿ†K"ŸÃÌÙ¾Á¶ßJ¶ß™GÞæIÿL)ÈöM¶ýF²=°íWr±$Ë ‰Î®×4Nì™çÚÑ—Â8QáØ85UÅÀhÿøDûd‘jT«'›çÍ"}œ|Æ1q£¿@ãD™®vdþ‹riê¥Èb±ÆƒìdòÒºÑWsu8¸µcECZÏ4~±áÝ0÷F/pž\¿çP¾ª­WáÑ‹°¯¹£Â¯éËEO…£ñÅáêÉÙŠ…o`Ó‚Ú¸Ã+4s\@à s˜ DãF<Ä$v|R·ŸyIÙ:o}dw: §­ÓXX’¡ô´è²Ý3Y³.âÊ}!Iyš5 ñÂæ‰Ü›–”Ý£#%wTH :ê7Ó3­¼R:¥¨jŒO\;V§à/YzKRÀÉš°Y}¥ éÃq“çY V‹½‘*'¡÷é—ËËj¤¤B­ZÌÆ³%ëBJ/ˆáQA/¨¯»ˆê²FΫ£QG¬±Žã“Q;Yã¬Ø$_ - ŠðuN¶‚Ï˾²Xrw1£Äé)"Ác Ý#O󘤼ީ]I3iîÊG¼²-1 ¤íLÝS 4X”yb,òƳ§‰K#ùŒ²Df­ÜQfÅC‰HúæÈÉ“eTYãÝÀúi…º­ ‡‡YO¸*ÂÆ0þìç]Ä|ïŠÎ3VoYc†RÓ*bn¨ÚV’‰\ÂÁ™Ã`ªfoèu,i3®d C¸×t40ï× ¬Ü3ä`d¾“Pe«aÖéucShkå›gG¯ž5>ï"æ{g…Ts±>Ø!k²ŽÕË^±ß—»X –í#ó*SK”Òü`\Û\Çʳ“cKË«gçû:ë#i9•ƒe­ñ)VÍVh!RŸ¨ Tâv½:t[ _l8 h S}^Wuó½+B9Xù#÷8÷XƒîLwâ:@¬_KoH[t9Ò¦Æ fÞÇDÄ…i"_û—aiŠë#cQP-4>"MU3†w-Ɉ:4¥¿Á5¶y{Ll ŸêóL}ÝEÌ(¯iä<åߘ½²f©ÐßÑfcÄ Ìó˜ØSÍ9…”E‰þáTÝQæ¡szU ùBKšÓReT2ô)×&@Æ ‰…2´ n*êüv×DÕÄ`=“ò¡>OÔ/ºˆÝe!œG¬ÂS8f ¾ëÀ5ƒé K7>üJª!seÁVõȬô~VêÖÍUó¼;”Q-ÿWÆGYôÉòÞ¼ÜÎ xj@UŸ?·9&”§…4r_eí½‹`n(@¥¬½ @½›ÐÙµyË‘›{[ýKRqjšèàìöËTŸ?Q¿r_H/fíÍÐþ‰Ž˜ÙRuf»¬Z¦±E)úK\ |ÙÇ^ØoØÔmÎc`¶²9oêĉ·Q´LÓY'¾„C¼JHßôœoƒ–ƒ¬« ¯WÓ1W0H«ÌGžùh9i²Öðz9f úVÎ;ÀµE!óvBäÀ­wD|Ñt à'OXßðÒBÎÊeñÖÒðºác¡ñ²áÀ—º?ÝûŸÁRo¸á†kPG®«ˆû;aþf±·;¡TdS‹úþN˜¿ Õqd2뾿æ¯BÞî|¶ñû;aþ*TÇ‘«8þAß ó,5£Ê0ìÇIEND®B`‚snd-16.1/pix/fmeq29.png0000644000076400007640000000334511147553267012764 0ustar bilbil‰PNG  IHDRò#XZxÜ3PLTEÿÿÿàààÀÀÀðððppp```€€€@@@   ÐÐа°°PPP000 Ue£ pHYs  šœtIME× çúØjEIDATxÚí[‡v¬ )âÿí°¬(šM}ÎILÌÂNcÚuCȯ!¦"i ý/D½Á«ª>íký ²]ô§µt tÿXëOwS¬ëz x\þ7hˆáÝØ—_"%±E:5ªþFÉ ”r*yCûö¸üRÁÄPRì'šÒvŒ1Í-ùv—{ïû>ý•Þ¦±`b¬·;Ц¼6%½m¦ZJ9ûv— Ÿ¶F÷þWæꀡ¤^·9—qÍ@o-åÄ«ïOìÎÇyq˱£¿Ðå2Æd¿8V’S—SÕü¦ã¥ÕÕRŽé}oìïp9t~ßDþ ‹xhÍ@If•Yn¦XÔ”·fkÚWWƒi”ošÊÕ°qq¹¹oŽòVæý>$Ú‹ù^psq=y—Vœn©VVæü¥£~Êj.Ïs‹Ö29úØÌ«ÏôiËT #Ž\ÚúF¦\§â‰µ÷UÙªÊ ZN[±ÊŽDwoàã +PoŒksÈÙ~¡xkÑ‘6íTÃKAÞp‘¬Â×%s,¬CñQ±D@i–ÕëQÚåÜì‘j OÙ’iÒE¼¿ •÷|©zÛg^Üt™6ðqYÊÛªjÕgª¶ˆ±2ÇÍ9œ¨Â¥gáêF±.ÀR†_±±ÈÞåÖî"2?-’±óP>ü%§f²Ê6&ßÈÝ”ƒ‹b9/õ¬š0¾6RÁ7ðqQÊÛªk5Ke&_M·ŽžïDË€Œ„(×x‹Î HX°ÑÎ uA"[èÙóØjMÕ¾1»t¸1#ÎÜ+[­/Í(·l7l$‚oáã«Û*i…‰?E "â)‹·gç86xXÆq#v–aÆ{Ù÷<¶èjïI¹6ËjB-3”†"˰„1Mc7¶-Zóñ¦L:e…¦Ô0[Ò}Fnr¼ŒSî5ÐGú D°H„â¹µpÂfÊX5ÞÂÇ)›-D5I+hÅYœiÌCÔÌAI3CØ9ÈÊ´‡›…¥Éô‡á‰k~޻ד.±ë#ó#páñQsyÜŒ9CSX*Ô)ï#ã”»¨Ä`9ßGg*Q:ll';ø¸ e«…°­R‚ÀØ¢•@@𯀹Aœw“ ÃÉ-}©w˜WÇšMóëÖ6`{‡C¡:uyܨ‰î ˆÒÒi\ËòÎ1Þr_&=ªVJWÓ&µT¢\)Wk)ßÀÇ)[-¤‰ û|‹VÄÙ¦]ÓQ3Ë›ÓdŒ\¸4-«™—‚ÎÚÅ˪P8•ëSIÙ‰FîgKû„K§ÉùÒ—1³¼3Œ“2YÇsDgè²Ó§¸aâò>.HÙj! =.`cƒV¬KkÑØ÷¶ ÐÝ%LVh¢œBswðŠWNš¢Ï+TÚ·Ùo9ÞÆ ÷ªËaÈtËœá†©Ëø¸ e»…g%´ú²‡cz*L©B±ˆ©ù0a)¡œ¡ xèLÅåSõ ‡ºârwÊ{˘j%,·6¤»…ûRuÍ+±§AÝg:‘(äo7•ò›™;„>.HÙl¡ÆZÕ*‚ê_ñ<>‘Ý+q@ÔA9è!t’XvtÅåÓI²æò)¨²¼·Œ#t2ÒØÊ.ÜU¥}“9T]ì¡ãÓ›™C,… R6[H 3b¯U×J `ì >5ª„a˜ë ªºPöƨþ¨UÀ=å¢Þ¬cU…ç5$-œÙ¥ÒœóÞ0ЉqSdzp—å&Ud«Ü¾”3}±ÁfÆ |\’²ÕBΆ‡bXÄ´z#j_¬|YFƒ'¦ïxÎ!AU6+¹†q#Ô¡˜ï ãxNa/îC¹Nåá“Ã)£)6ÃÍ5)[-k¯ü­¾‚Òñ.éë»gUbÈnÜ/]ÓZ±t Û¸Õô{çŠ:ƒˆÍd"«+ú¨V_C¢=Ç tÛý¶l„û#Fy+÷Ü5¿­qEJñÆ, ’üRÍ}DD›_ çùƇ÷{”âVØãk <½­qMJõ¾NKüŒõ¹ìر¾ñ…z~@ÁâÖ^² iåÊÕ*Ã[-t_«JCóÂ<êùF’þHš<ô)ÄuÓQvŸë–¡çŸ#? Ákte÷8àÅ–Ì´|Àu|lõ7ÈhL -%ZÈÇXƒ†Ð&µ°{z©ÿžJ^¢5à;ƒ£ (IEND®B`‚snd-16.1/pix/markpane.png0000644000076400007640000015335211147553267013463 0ustar bilbil‰PNG  IHDR  ÷Ý©sRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ 0÷WR» IDATxÚìuXUÉǿԥ‘0kEl±×Àøa`'² ˜Ø‚¢€]Àªk¢(ˆ®…‚Hˆ"ˆAˆH÷åRnüþ@Ždbìî|žç>pfΜ˜3gμóƈÅÄ<âËÊÊ€@ @ ¾'EEÅ”••A§N†¤6@ ÂwÅßÿ&ÄI5@ „@@ @@ @@  @ á_"€ìÚµ&&ýaj:˜öãóùÔ>S§ÚaÉ’5e9SÓÁ°°°þ.7PYY ==k;yÒOèþññ¯á踉Ú~þü%LMãî݇ûr8~ÓõmݺÑ´´Q£&Ó¶ÿÝ+W:ýð‡ÏãñpóæmZ½ÙÛÿ«´‘uÏ“Y"4/55 ¦¦ƒqùòuò–@ ü$oãС´4gç-xùòUƒe}ш‡“ÓfÀöí !!Ѥó5 ·oßGß¾} ))‰«Wo`„1Tþùó—CCØÙýV6(è=zBmO˜0¦¦½ñáÃG¼|ù cÆŒ òîÝ A›6­Ð¹sÇf«;oïã03û —.]hkkaéÒywwODE=GZZ:œœ6£E %8;¯¦ÊnÚ´lvƳFß¾}hÇuw÷B^^>µ½nÝj())áöí{hß^~~Àf³K—·¶v[Z;«åÿ³±qgÒ³@ |%aa¸qãV¡ÃÇׯ8àóù8tèzô0A@@ÀÀ@óæÍl^díÚ PQQ,_¾&Œ¦òŒ»@^^nn^@Þ½K•+°¶F¥=yyy9XX˜7©âbcã1hPÍ ^EEW®|Ö(88¸`æÌiÔöÒ¥011ˆ‹‹cøðÁ¸xÑoÞ¼£ ½z™€Á`àÝ»d > &&Öä‡jeeM›vÃáBRR·oßÃâÅs©|cÈÉÉáÈ‘S4äáÃP¼xG»f~ªª*ÈË+Àýû!4äÉ“HtïÞµY­[÷`úôI;¶Æ|.##žžÇ°|ùôïß|> ))‰áÃCZšA+;x°%‚‚î &æ%MÙµk?Ú·×CÏž&TÚªUëpò¤BBÂàä´;wn‚´´ô'ád |}" Y´ú8tè¶lq†ºzKÒ{@ ˆàر3¾K‡Ïk‹„„·¸qãm|y˜››Ö{Ìuë¶bÑ";Œ1ðþ}*NžôÅܹ !@\]×ÃÊj€Á¦åuîlmí¶psójtE°X¥øø1êTZaa1rsó›\©ÆÆ]pãÆ_B…„„„7ÔuÀþý;pæÌ9J±²€˜˜ÇìÖÍ ¸y3˜VþkÐÓÓAjêhjj@FF22Ÿë¯K—NÐÔÔÀ‘#t¶¼¼|ÓêçãÇtÚÀ£ø]«ŽŽvíÚL Ñ8{öÀÔ´7X¬R ­ ‹~xÿþƒÀõ¾~ýãÇB§N†Tš“Ó¦:íÌǦžc­ö©¼¼ †­>¶lqFË–j¤W!@¨‡Ù³§cÕª%Ôöʕ΀’’¤§gÒÆWùù…îÂ044€«ëz05“Ð\.Ž„„x£¯MFFæ‡?tŸ#05„ùógÃȨmð]!!¡ÈÏÿì/''UUdddQi••ßíºÅÅÅ(áãG!++#TÓ4mÚDœ8áKk/FF±xñ<ÈËË‘ž…@ A ƒ6V–’’¢þþ}ûÅÓ§w›\Ößÿ&Y @ @ ü84Ázöìöíó™?t¨fÏžþÓnÀÉi3>~Ì™ô¨äʵ=}OOÑþ#GÅÿþ7å§Õƒƒ ²²rDæ¯[ç@Þ@ „(…X±â‘ù:èS¦÷MALL [¶8õu5h‚UVV†ÌLуTee¥ŸºCZZ:Øì*‘ùúúº”Á¦´´YY¹"óUTZüÔ0²>|DU•èU0Û·×…¸8Q’@ üáp8xÿ>Md¾ŒŒ4µàóÂßÿ&ñ!@ ?N!ÓÛ@ á‡A@ ðˈ¸Ç¯Ï‰›@ @ š6» b……©|R@ áG@L°@ @@ @@ á«X ]\\ââàpªÀáp›S-­6àñ9ßW—€””,y"@ ¾;qqñˆ‹{‰ßÿ222M*[^”U}çš8 "GžÓ¯—[ ‡ >Ÿ³ ««11€Á` P]ÍÇkH‘‚”” 8œ*T±«ñúu2tÚé‚ÇùÞˆääÔÈS"ðÝ {777Œ?­Éãâj ·òû^Ÿ‚4Ж ¿^ƾA{ýàñ8Ä 'G °X¥ˆ€ V9¿©bÈ”)A¡ ÚuñQ*™2%È”f¢H¢ü“ÄLJÃiðÇårëýñù$@ Â×’––†Ý»wƒÇ㡺ºË—/ÇôšYøà³ñ‘)S‚9 †uDÚ§1s†4«òH%‰@@‰ÕÉH©N©IPñI8)*‡x4 †ÚbãÆÈÊʡʉ‰‰AII L&“J“–f eK5(+·€¤¤$¤¤¤ ++‡²²Rp¹\0 b‰ôÉ“ ð¯'?'¹Ùé’b C—îÍrÌׯ_ãÆ¨¬¬Dvv6ÄÄİeËÈËËcÅŠM61#4xHå|ÀÛª·Ÿ¾ŸÇÌÕ•Õ(ÀÄÆé_u좢b°X,èèhSi©© ¢¢‚-”¾úšccãabbüë MÁа=õ¿žž>$$$ñâÅs((ÈÚ´i Eˆ‰q¡¢¢ Uèè´Cbâ;”——¡uë¶hß¾="¡@øw“›Žû7/ ¼¬ââ(.ÌÃoý‡~óq8ooo\»v 6l@NNQ]]ßÿ¤òÿaDDDãÉ“HlݺŽJ;tè$FŽÍ¿ú¸ ¬@DÄýŸ~ÍK\\ yyÙ"íÝ ÔÔZ¢¸8)))¤e@øÏÀ®,ÇõsGÑ×Êvö›0z²î^üæãzxx`åÊ•011Á¦M›Ð¦Mèêêbß¾}Ø·oΜ9óKÕC@@/^Œòòr*mÏž=عs'i$_põjbbbOŸFãÆàͽ5‹bddŒª*6 8œj”–– ì#!!.·&dD·nFàp¸_}¾ÂÂB”•• Íãñx(,,¤~ÅÅŤ@ø)T±+QR\4k9Úµï Pi©‰~ƒFÁÁîóïÏ#»PÅnØ»½¸¸˜çÄÄÄ ÿþ´|tíÚ={ö„F…#GŽ ªªê‡ßee%uÞÇ#%%ÎÎÎX´hnܸQ£F¡OŸ>0`ÜÝÝÁf³Ád2QRR"rl÷_ñ4ÈîÇÑ£§0`@_*ïÆ[05Lýv쨩;‹…Å‹W#?¿+V8ÂÔt0V¯^‡ŠŠ !툉ÐЧpw÷¤§gÐŽ9jÔ””°¾Ë½I~ëäää‘—— >¿ÆŒªmÛ6ÈÎÎp|200DII!@VV999ÐÖÖiòù¢££qðàAÂÎÎmÚ´¡å—––ÂÞÞžÚNKKCHHé @ 4;E¹HyGKÓÑï„üœ ”—±ð>) /"±Ìy/TÔ4¨}$$$1`èx :žJ»x§nEoóÁ‘2•…ŸóÂ… Ô€ÒÙÙ¹ÞhKúúú „§§'<<<`ooiiéV?'Ož‹ÅÂ’%Kœœ ===èèè@VVééé ¤öe³Ù8}ú4^½z,\¸øðá.\¸@í7}útèèèÀÈÈè_ݶ”••¡¦¦Š˜˜X ¨èó¤ú˜1#1fÌHjûÀ#¸r%Ó§OÆ„ £Ñ·ïPüùç1<¸—/_‡§ç18:Ú42ñòe<.^¼55¸»oLœhK3ÏÊÏ/€§ç1¬_¿æ×@ä!//ÒÒº’ا_ ­(ᣖnÝŒPXXÔäómݺþþþ8wî=z„©S§Òò•””àçç¸råJƒôôtZ£&4?3fÌ@«V­HE| ááÀíÛ__~Ò$ÀؘÔã×Âbîî__¾cG`Ú4R„?……ÀÁƒ__ÞØ¸¦¿ú>|Ý»w‡’’¢££aooׯ_ãÎ;¢»„J „MõÔå] *Íи'&Í\Þ¨kÑï`Œ¼¬t$&¼C(¾ßþýû!//ߤû455ÅãÇáåU3ÛÝ¿¤¥¥aܸqHJJ›ÍF=¾©.ÝEô“·nÝBee%ºwïŽqãÆŽ=*°ßàÁƒÁáp0iÒ$$&&bÍš5°°°€¼¼<5¶ooo$$$ 88¸Î¸²†JÛ=;v¤ö¹rå F%Ô)ÿÎ;èÑ£ÔÕÕ©WjÓ&'˜šBDÄ}8:n¤ÒŸ?‰ë׃¨íˆˆhØÚÚPÛS§N„©io@—.кuÍ8,77'NøBL عs#•¶¶S±yó.j»E Åï"|ˆ@r“r+ÎåpÑE±CáCšÈÉÉ¢íת•^¾Œ‡––%€„††ÑTÕÕÕÐÖn÷ÝØ•+W°yóf<~ü¸Jö½xñnnnä#ÒŒ <˜ ßÊ“'À–-__¾S'"€|«ò-õ?v,@ÿä[Þ•©S¸ÒµkWäææ"%%=zôÀܹsѾ}{³¦º”Ÿ\TÔ4 oHï_ÓRÞ¢¥fÈÉ+6éZô  gX3«¯ tÖl¾ûìÓ§úô郰°0„……ÁÁÁ .ÄÂ… ññãGp8jÜöµÌ™3bbŸÅ±„„0™LxyyÉdÖ[§µ >@é¾½½=Œ¡¡¡AÛgéÒ¥ÈÉÉÁ«W¯©©©X·n|||>C[ÁÚÚþù'Þ¿O•‹ÅÅ‹!%%%pÞ7oÞ@KK °¶¶ÆôéÓuÏ %8fæóøÐ“Öj–g·ÿ.ÚvjjΞ½ˆÁƒRiÙÙ9"ËwéòY“••…’’îÞ ÁŒShû-Zd‡¿ÿ~@m—––aûv7¬_ïÐì &‰c0L³/ÊË+Aƒ,ÀáÖ¨ú$%>C~~®ÐwìØœO‹¾yÖ­5ñ¥É^Û¶ßþ`ø|>ÒÒÒ ¤¤p¹\ÀÚÚVVVX¸pa½eee 4ˆv<8räH£^‚h°nÝ:R@øe9tèø|>x<îܹƒS§NáÉ“'"gó ŠTq%eU,X³ Ùjê­P— †´ JŠ QR\9E(µPmÒ5äf--hÖLÞeee¡uëÖ`2™’’úªî˜L&vïÞØØXôêÕ ¿ÿþ;|}}qæÌ™F‡é-,,„··76lØ@¥=xð€š¸uww§ ÕÕÕ°²²‚§§'/^܈¹ ѦM$%%!$$íÛ·‡Ã¤äçñ'‡ÃAee%bbbðàÁ´k×·ëX ¼yóÛ·oÇòå˱jժόѣGcذaÐèú“ÁݰPé.—‡{wÃ`=j88œrˆ‰‰AUE¥YÚh¿~}èí¯ª •èØ±F)ðî]nݺ ‹~ KQQK—ÎǬYÓ±bÅ<f@@Nž< EEEüù矴¼°°0ìÙ³péÒ%0ŒF3//ªŸí۷øŽÝ?Ç£ftV¯^6úZ׬Yƒ¤¤$Œ=óçÏPcK)ì~]]]Ñ­[7ò!& ‹aãÒô ¡ohŒ×/£pòÀf̵ßLåe~|j6Ö¿Ï‚œ}̤ XÖËפ§§cï޽صkde…϶/]º”¿èêêþ„´ õÿÌ™3qüøq¸»»ÃÅÅúúúÔÚpsæÌAÏž=ѱcGšã8P£¡(..Fbb" Ñ¢E ÒØþáH’*¨&“‰Ã‡cÚ´ièܹ3e:}útðx<øøø W¯^°··Ç³gϰÿ~Ì›7ŠŠ¢Ïø|>‘••…Ë—/ƒÅbaõêÕprr‚††ÂÃÂ˗/V¬X´mÛ¶ÞkýðáöîÝK•sqqÁ¬Y³Ð¥KdffbëÖ­TÞþýû!..Ž ̘ÃÓÓóæÍƒáëë 0™L˜šš h™„™ÛáûÁáp™™ bnùË¢kÐÇÝ]à`W£Íž4k_=LJíÿºeÙ´´´ --äädÚ„cEE’““Ôøaܹsç«ÌÞ›eee¬Y³+W®¤ÁÕÔÔ†††Ø¾}{½eûí7ÒˆòßàáÇPUU¥fôG…µk×"%%¥¥¥ÈÍÍ¥«ÌÌ̆ÈÈH <˜:Æ;wPUU…Ñ£GSŠãÇãúõëjl*ÇŒ___888ÀÕÕAAŸC«ÙÛÛcß¾}4‡¸7oÞ ::ãÆ£„7ÂÍÍz©wïÞ kkkáàÁƒX²d •çèèkkkšRVVôèÑƒŠ­}ûömèèè sçš…“ÆåË—ÃÜÜ ..ް°0¤§§­,@ ~ Ø´iNŸ>M*ãEVNû|>;J_öõĬe.ß|Ü={ö`Û¶mxñâ~ûí7tìØoÞ¼ÁêÕ«Q]]3gÎúô³*pÕ†þ7ÁfW‘†]8’ ?€Ã‡ƒÅbQHsðøñclÚ´ æææõj[š“É„££#Ö¯_ßh!âÞ½{hÑ¢”•kVK ƒÁh´S@ ÿE»6Hc°±±Áš5k‘‘A9T÷ë×cÆŒaKøqƒîôôL¼z•ð¿]ÝvÐÖnûÅ84ÅÅÌËvîl}"€ü <<<V†ÿV&Nœˆ4h–ÕÔÕÕqÿþýF/ÂÓ«W/xzz¢mÛ¶”´cÇäää„@ ü'©ªªj´Ï^Syûö-‚ƒƒaooߤrË–-ÃÁƒ¿ÚÌçß›ÍFeeeËUìï|]| ±—¥¡¡ˆ‹‹cÆ ÃæÍ›¡©Y³HSïᅫ¤¤d³˜“—••áíÛ¤OZ±d]hié ukÁ±æ»w‰´5Þ¤¤¤ ££‡¤¤·T(fee´jÕFx“föýi×®ù\TUUmö0ÁRRRMŠ!//ÿS"jÂÏ$>>žfo_—ñãÇÓLh¿$..î«ÃÃWVV"''§ÉåRSSGs&|æßêWPw] BÓX´hQ“‚ 5ÄС–ÐÖÖúÇÕƒ˜˜8deUP]]ŽêêŠ/s!/ÿy=#£nHKKAee%Z¶¬ñëQRRú´f  _’••…k×®QÛ‰‰‰´|$''S‹%$$@CCjjjPPP€¼¼<’’’```€´´4¡ǵk×PUU…)SjVœGß¾}sssTVVâåË—T'8lØ0ܹs‡ZçÁƒ°´´¤óåË— ÃôéÓ©hÖÖÖ¸uëfΜ ¸~ý:ư°°À£G(_–»wïbÈ!´c–––ÂÏÏfffÔ:*:uÂýû÷‘——uuuÄÅÅA[[ÊÊÊHOOGFFÓ›@ þIÄÅÅAZZ†††y)))`2™T_X ŸÏ‡““nÞ¼ùUçtrrjÒúßJhh(ú÷ï'''ܺuKè ÕÜÜ ÿ¹çß»wïF-ŽGøïaffF*¡ ¨¨¨Å*‚ªª ÊË+PZZYÙúsüÏ ÒÒÒÐÖÖ¦¶‹‹‹iùFFFÃPXXˆvíÚÁÖÖ–RkþþûïðóóCFF455akk Ú1|||Àb±(DBB ,€ŸŸ|||³í Ž IDATÀ`0`kkK ä.\???*äÞÔ©Si«µ@DD\]]1bÄJ±±±Áõëשrýúõ£BòZ[[ãÑ£GT^Ïž=±páBÚ1KJJàêêŠõë×S]ˆ‹‹cïÞ½(..†žžlmm¡¦¦†üü|uþµØg455)_»k×®ppp@UU(‡ó–-[bÞ¼y`2?;!µhÑ¢Ùœâ á[yýú5Z·nݤ2999øã?°hÑ"£E‹”Ms-©©©PRRÂìÙ³qæÌ*=77ŽŽŽÔ:NÍ››FŽ)4/)) <O ?oJKK!--ýKEP"þé¼x‡÷ï?ü#|²äää0nÜÄz÷QWׄ‚‚ØìŠOã@%$&&AYY… ÍA}ŽÙ ùcˆ*«   rÖIVVZZ¢íE••¨·\}yõ•ECQQ‘á§‘––))©& õÁårQPP fuf‘üÜÜ\‘e…Ád2ñæÍ›&iŠ‹‹‹QUU%rÀ GGÇ&û2¤¦¦ÖëS²gÏŒ;½{÷& @h&Øl6úöý ­Ziþò×*&V¿$)) 1Jø¨¥wïžHHxSoYƒ@ ÿXîܹƒ§OŸ~Ó1üüüšõšE^SJJ u¾ªª*\¸p¡ÑeEáé鉪ª*tíÚáááTú«W¯ ¬¬,R8 Btt4iDá«`0"W¥oháK¢ÁîÝ»qüøqRßÀ×Dk!„æfÛ¶mð÷÷‡´´4m ïãフ+Wâüùó°µµ¥•éÓ§JKKñêÕ«&Ÿ/)) ÑÑÑ033ƒ‹‹ ¶mÛ&t?GGGdffÂÆÆ†JKNNFbbbƒe¿D^^FFFˆŒŒDß¾}Ôø±Ô vvv8uêìììHƒ ÍB»vz(//‘§””02êL¦——‡²²2R߈¾¾>í£O ÍÅóçϱcǸ»» Í¿}û6TTTÀ`0ðñãGZ€7oÞ //åå娮®(Û²eKp8À$_RZZJ îsrr`bb‚1cÆ ++ sæÌÁû÷ïÊ””” ´´111~|µdee ÕN””” %%âââÐÕÕÈ/**BEE…€?£¡¡!Ο?OmWTT€Ëåâĉ°··ÇåË—iûß¼y¾¾¾;v¬Ðë;yò$´´´0|øp¼ÀÀ@äççcÖ¬YM~¦¥¥¥àr¹BgU+++QVV555Òø ÿ JJXÔ_-­6ÿ¸ë/+«ÀÍ›·„æñùõ/CA¸¹¹ Dž"Bó“””$‘°.qqqhݺµ@.— ---dgg£´´TÀ/®ººbbb””ÄüùóñàÁÇÃÂ… 1wî\<}ú?~ym À£G0bÄ*­°°±±±••‹ÅByy9Þ¾} {{{øøø &&æÓǹ |>Ÿv<$''ÃÕÕ}ûöƒÁÀ«W¯Àb±PXXHùy¬\¹åååHKKCrr2UþêÕ«¸zõ*äåå©°ñfffÈÎÎPô„Á``íÚµ oL&ÖÖÖðòòȯªªBUU•ÈòUUUB·Æ”­{÷î!''‡ŠØX—ØØXcÓ¦MM:æƒ`eeõÍí4** ;wþOF #|ââ^!**YY9ؽ{Ë?îú+*Ê0xð`‘ùŠŠJ"óˆ@ ¾+ñññ «w€øìÙ3‘ù×®]X£©KKKÄÇÇ#//–^\\,à_ñ5¬X±Äóçω£Gbøðá¸té|}}1~üx5Ú–—/_6x<]]]¸¹¹!..óçÏÇðáÀãÇÃÅÅE`ÿÈÈH((( 007nÜ Em¬eÞ¼yTtBðòòBEEE£ï±´´gÏžýéíäèÑ£"ó8-ä{SØ»wo³\ß™3gŸŸO^hB³ann†^½ºcíZ{@hèS8;oÁÖ­{„+ pvÞgç-ÂZÚG*/?¿PHœ€°f¿þöí ¡©©!ô§¢¢Œ¼¼|"€áç’’‚¸¸¸‰YYYé¡¡¡PVVÆÙ³g›4«^VV†{÷îvìØQ¯)¨««+6lØ@mïܹëÖ­£í“˜˜ˆ×¯_# cÆŒÁ˜1c`eeE-öÚºté‚:PÛ—.] AƒDšõíÛááá C¿~ý¨ô—/_¢¬¬Œ–ö5TTTàï¿ÿn–g••777Ѩ±1Æ(+#44T ïúõë"Ëñx¼z\½zõW]ïÖ­[1wîÜo¾ïÓ§O7ØÆ¿'_{ÿ„ŸOLL,˜L&^½zƒ{÷B0qâXXZöÇúõ[©}rròpæÌYLœ8'ŽÅÊ•ÎT—ËÅÖ­{©¼uëèš”ÜÜ<Ì™³±±ñÍ~í<,V±Ð_QQ’’’ˆB „o#33S¤o\^^^½þ®®®ˆˆˆ™ÿþý{°ÙlZZUURSSѺukdee ¬§Taš-Z@]]†††´¶‰‰‰°±±ÁÖ­5ø: )) ¹¹¹())Arr2ôõõѺuk‘æ6êêê"†-Z€Ë墴´û÷–¶oߎòòrj@AAšššÐÓÓƒ˜˜RSS©}´µµ‘––&òžY,¸\.”••©Á¹££#ÒÓÓ1}útھݺuƒ¹¹9N:…ÊÊÊoj¥¥¥ÈÌÌšÇf³…ú½Ô IÉÉÈÌÏGQQQ“Ι””„öíÛ‹Ìÿû￱dÉ’&ßKRRâã?Ì&MšD«ŸÚv•ßÀ5gdd`äÈ‘MÒ<5'oÞˆyÊår‘’’B:°_” Æ@CCû÷{cî\[ôîÝýú™Âظ ||Îþ÷¿ùpsÛ†Þ½{ wïX²dìíÿŒ9 ÇŽyPy»woÁäɳ>Mþ¤bÆípqqøåîû?/€äääÀÇLJúݽ{—¼ á—&22RÀ䨱DEE ¬]Q—”–– Í;~ü¸È¨PW¯^EHHˆÈãöêÕ 111+äæææ¢´´zzzerssñøñcLš4©Áû&œ 0“'OH_µjöïß/°¸àùóçialíìì`bbÒ(ÁŒÃá@GGЯ_?”••áÅ‹ǃ··7Þ½{G•©=w÷îÝqëÖ-ôë×fff8sæ ª««‘••…µk× Õ&ôïß_ÀI»VÀƒ¸¸8Š‹‹‘™™‰Î;ÓÓqqq8tèP£ÚJŸ>}-àÇ÷UæPÕÕÕð9OžàÇíŒÅb‰lCõjVø|¾Ð6SSSܺu«Áë‹ŽŽ¦´p‰‰‰x÷îuL<|øPh¹>@ZZZäzY?›ŠŠ 8;;“Žó—íÏŸ¡¤„—µðóû §Nùáôé?QVVŽY³¦Sí»n%..Oõ}u'XÄÄĨw6$$nnÛ\Ïã_+€hié C‡Î? V?¿ÄÅ!++KýHÄ&ð«sóæM|øð¡Þ}öïßßä²<€££# mˆŸ?.rV‹¯¯¯ÈEø¬­­qçÎp8Á[qqqƒýeË–ÁÓÓ“&p\¿~&L€­­m½‹Å~+999HJJBVV–€ÃºŒŒ †Šªª*téÒ…–·dÉHKKã·ß~Cÿþý±oß>¬ZµJäy–,Y‚.]º€Íf×kº0iÒ$lÙ²ÞÞÞ"÷ÉÏÏÇ»wï̳¦M›†«W¯ÒÒ6mÚ333ܹs‡–>zôhÕ«yªœ0ÀÂqqq…ÂÂBüõ×_:vYYŽ; ÆñþK§õÚöïïïqãÆ õ/¹}û6ÌÍÍ)-WPP¥½‰ŽŽ®Wc÷¥@&///Tˆþx{{ h ÿª««ÁçóÀãñÀãñ©±hs<Ó9sþEÅ_3hÂ@”•UpÀçWQ¿¢¢<ÄÆÆþô PWWÇ”)S¨ß€ÈÛ@ ~Y8ŽÀ þˇÃjÓÏáp ..{{{¡Çxûö-ììì°e‹`4–´´4¼}û¶Þk ˜ÕÎÊÊ£Ghk]cÆ puu¥¥UVVR“BVVVT«Z$66=zô€™™Z¶lI3Ù´ií>œœœ°}ûvûvqq––¢¢¢àëë ‡#0ã¿{÷näææ‚ÉdÒ„3ƒƒ¤¥¥i³”–––””„®®. p÷î] 2¤QÏÙÝÝrrr””„”””@¾¥¥¥€@hnn.°žÉ—ôéÓ >>>X´h%hèëë#!!žžŽˆˆˆz5ORRRBë Œœœ„„„„ÈëÏ2 k,UUU_-äþ077ƒ’’6oÞ‰ùógbÚ´I˜1c2455pü¸Ï¿ö¾˜N†Ã©Buõç›]IÖÙ ü’¤¤¤€Åb ¤3™Lš}6ð­¼|ùRè®>nܸ¼ÿ^ ,“É„‹‹‹Hs“›7o¢M›6PWWyÞZ aèéé!55Uä`¡cÇŽBJuu5JKK¡¢¢Rï} ;omªÆpúôiÚ"{™™™´À555áíísçÎÑʵjÕ ²²²ÐÓÓÔ)Spùòeó¶ZÓª/qssƒ¾¾>µ}øða39996¹mhiiA\\ãÇoP¨¨EAAªªªP¯F©k×®(((k\÷™•••Ñ"k}ɼy󄌌 !¶wïÞ¨®®FEE&NœHåMŸ>ªÿN:aÆŒT^FFÚ¶m EEEp8Ú yýúõؾ}»Ðë(((:–xûö-Ö¯_Om?{ö ÄìÙ³qûömÚu8p+V¬PãwS«åÊÉÉ¡ ê[µjEµQ///xyyÑ¢={–vOuY³f RRRžž.4?>>ÏŸ?šçàà€ääd¡eSSSÁd2±gÏüñÇBËO™2ZZZ jMSRRêV÷æÍ›¯ž•¯¯¬««+|||šÜ6†·oßþòÚ¡›7ƒ‘““ ”–Ö´e>Ÿòò ÈËË:wîˆ×¯?÷­ïÞ%Áаf]£îÝ»âÅ‹¸:m)ÆÆ]ˆB ü›ÍÆ»wï°jÕ*ÊV;>>¯_¿$$$`õêÕBM#˜L¦€ùpëÖ-‘þµ+aݘ˜xyy „`Μ9ðóó˜MHH€ŸŸmpÕ¨kÍÌÌDyy9-:S-µ‹ßíß¿çΣ-hÇåráåå…²²2x{{ÃÃÃVöÒ¥KÔÿ¿ÿþ;Íü‡ÇãáÉ“'?]ó,//cÇŽÁÌÌLh¾ªªj½š mmm‘eÛ¶m‹¥K—þð{Ú±c‡È¼;w Mˆˆ@ZZ.^¼(òÖý_X?ºgÏJƒP«V­‚ÈÈVW¯^hßmÚ´¡­’ššŠÈÈHŒ3†¦Y%àîÚµ —.]é@_W¨ÉÎÎÆ²e˰hÑ"\¹rEè~»wïÆÇ‘˜˜ˆž={Š<^ll,ÍÿG›7ojž÷òåËz5ç΃P-ܽ{l6ãǾšÈcµÑåNž<)Ôgª®À-Ì<³1¸»»‹4Ï¬í ¿‡dß¾}ÈÍÍÙ^¹rå§k_:vìeåpv^‹ýááqžžÇ !!éÓk´Û¶­Çµkðð8 ÃÈÊÊÁòå5f‡{ölE`àm*ïéÓhlÞìôé¼Ã ¼ÐÐpxx†Ÿßü |“Ò·¯9úõë/òשӯ/þ]lÛ¶í«òΟ?ÊÊJÄÇÇÓ:©˜˜¬\¹’š-{úô©Ðh#EEE´’õëW"** ·oß& ç;qåÊ”””ÐÒrrrpâĉzË=}ú;vì(û%¢f…9‚‚‚šˆ¡¡¡ðððhPãüñãG”––RNË/_¾D@@վ߽{‡>}ú¨Ñ6€RSS±cǰX,ˆМ¥mmmi—ËÅýû÷m–Ô˜{¿yóæW™÷êééQ¦T_®ÇѲeKŒ=ÿûßÿ «« }}}Z”)===XZZ~s{QVVƲeËhƒæÚ±ëׯ‡˜˜¬¬¬`nnþ]Ú«ŠŠ Ž9" ­:}ú4>|ˆÐÐPêÙ ëëþúë/šæÂÙÙ"Ï7eÊš°£®®Ž… ¨ñ'JMM…¯¯/MÐSTTDBB8€Ñ£GCEEÛ¶mƒŽŽzöì‰;wî`÷îÝ4m€„„¼½½©v¶lÙ2 2DdØß¼¼<¤§§cݺuptt„Ý &>>\.&&&())Áëׯ…  <;vì@TTiëÕ«Wð÷÷§öyöìæÍ›‡1cÆõA­[6!!V¶–3f€Á`ˆ ë[»äܹsظq£ÈüÊÊÊzÿëç{EÚ:|ø0 + °þõ×_˜7o¸\.BBB„†wj¢=~üX Ý××W¨ŸÒD]½%¤¥ÐÖn › 00ÐC—.1cÆga°E‹˜={: ô`` ‡ùóg}È‹‹cÉ’yTÞâÅsëô!š00ÐØ1#0sæTèAG§í?_QVVFZÚ{¡¿¤¤w :,uñòòBdd$µ]RRB©·ËËË©[TT匚ŸŸ¥K—Rƒ«óçÏSñü 1sæLêx÷îÝ£>nŽŽŽ6làСCxúô)µŸƒƒöíÛ6› ‡ƒ¤¤$™h‡€€j Y\\Œððpj†éôéÓÔ $›ÍÆüùói³k_ζշÝXŠŠ¨ñ:{ö,.^¼HëdíííQTT„ììlØÛÛS+7 «÷¯ ÙY]]M«36›Miº¿úfØê>ϺìÚµKàã"j_aùõíëàà@iÁjùðázõê… .`Ö¬YøèèhÊtèËûMKKË/°wï^¬^½³gϦ}ìgÏž ‡`îܹXµj>Œððp̘1l6rrr€'OžàÊ•+¸~ý:233qäÈ<{ö jjj‘‘¡œ|£¢¢PQQA•=uêfΜ‰ììl¡öáÀôéÓ)mŸÍgÆ X¿~="##Þ ¡´´ èÛ·¯@ĦZ"<<œ2ªí–/_ŽÒÒR¡f7n¤BçFDD †Ùl6Eš‰;‰‰‰õFÚ·oÆŽ+4ÏÈÈׯ_‡²²²€°õ%ŠŠŠ´A¡’’’ÈYêZdddh3éòòò”)U¿~ý ¦¦†víÚ¡mÛ¶ðað|ùr¡Ç’””Z°°Àž={ààà€9sæÐ %%%ÄÇÇãÕ«WPRRBii)Ô¬Ó’ììlÈËËÓ‚˜™™ÁÅÅÛ·oGIIIƒ×#''‡îÝ»¨Ñ:}øðAäÚQQQèÝ»7:tèuuuÈÉÉ¡U«Vxùò%=z[[[£sçÎèÔ©M@’’‚®®.,--)íÛßÿ 555ôìÙ“Ö&k…ñ¬¬,Œ1|>‰‰‰àóù"£^àòåËàóùxôè¸\.Zµj…’’p¹\J’——‡ÔÔTÄÄÄÀÈÈ®®®Ø¼y³ÈúÉÏϧiCîß¿EEEüöÛoûÖíwê q_~sçÌ™ƒØØXBWWÏž=£úÃM›6Q“µïyÝãQ}_BBÆOit™L&8ªªª ƒÍfÓ&Cnݺ---XZZ"''§NB@@2331jÔ(xzz"<<•••ÈÍÍ¥Y £¸¸¨®®F||<-HDYYdddÀd2Ô,tùäÉÚ»^;YQQQŠŠ ðùü¯Öò| åå¸y3¯_¿û4™¡‹Ñ£G`øpÁÕÅ[·n…Ñ£G`ôè‚½ŠŠ2•'//G¥ÿö[O*½ö7p`ÿ¾ÂãñÀf³…þ*++iÎg„CEE^¼x!4¯nxÉÆ’‘‘!2}AAÕ‘VVVÒìW¿üôéS¬Y³¹¹¹˜Dee%ÄÄÄ´|>3gÎćвeK´k×Nä7·VȈˆ€¤¤$Z·nM ÅÅÅxòä ø|>V­ZEõg¹¹¹HNNÆâÅ‹1aÂdffB^^½{÷Fpp0‚ƒƒ1oÞ<¤¤¤ ** ={öĈ#ààà€š¸¢¢’’’8wîLMMqôèQddd`êÔ© „„„eFV÷»ŽŠŠ HHH`À€8s挀VÔ××C† ÁÊ•+‘––MMM°Ùlª/))A=+W®ÀßßUUUͲ0ec‰Œ|†¾}CPÐßø¯A|@~¾TïÖÝ6øÏÈȹ^Iaa!V¬XA›Ñ¯eëÖ­"gB._¾LÍP?xð€rV …““åxMS%×ÚsÑBB®\¹’R•ž9s†ö!¬éÆËË x÷î ._¾ŒÊÊJŸeË–QƒM Æ¬¦m۶صkN:…?ÿüS@£œœ >Ÿ/tá¸iÓ¦áòåËÐÕÕéÜ Ôø³GŪU«Uyyyœ:u &LÀäÉ“±k×.ÁaÔ¨QÿˆoÂĉÔ°| ÒÒÒpttlR+++ôï/8s:kÖ,ˆ4 ÓÔÔD«V­Ð¶m[¡ú=zôi6£©© 999èëëC[[›J¿~ý:Ænݺջ½‰‰ zôèÑཱུhÑãǧ¶544`mm-RÛZ·}éãèèˆ:àãÇX°`;.„‹‹ &L˜@k£ÚÚÚT?š’’‚ÜÜ\ê=[³f %䇅…áÕ«WèÛ·/@MM :::ˆ‰‰† '''jRBWW Ë—/ǶmÛh~-óæÍ0 }öìÚµk‡Ó§OcíÚµ ‚™™¤¤¤àããƒk×®Qý[xx8455qêÔ)ÌŸ?^^^°°°€¿¿?¨þ¬–ìܹShhd+++$&&Rærfffpvv†‚‚‚¨EëŽ#Ö­[‡“'OÂÙÙÈËËCZZõMa±Xxøð!Õwººº"!!JJJ8tèÍ_JÔxì{aiÙVVز忷N @êaݺuBÓ=*4šÄóçÏE:è‰:ÖÁƒEFy  ¨ÙéZ²²²àìì\¯­cíl­­­->LÍŠÔ^Ÿ§§'lll¨ƒ›7oRƒŒ'Ož`Á‚Ô,ÉÇ‘››‹ÄÄDܾ}/^¤óþþþÔ,sDD®]»WWW,[¶Œ^¼xsæÌÁ©S§àíí ;;;¸ººâÚµk°°°ÀÝ»w‘’’ƒAûÈØÙÙáôéÓÈÉÉAaa!ÒÓÓâÆûùùÑÌcZ·n jÖÞÊÊJÀðúõë077ÇîÝ»±gÏÀ¸qãpíÚ5‘mÃá ""‚ö‘}ÿþ=Íd¬îÀiíÚµÐÓÓÃýû÷Q]]M©Õ=<à—.]ÂðáÃŒ'Ož@ÕÆêÔÃýû÷‘——‡7oÞ   .\ „žÈÈHtíÚ²²²T¹páÕÎæÏŸãǨY»!&&ÙÙÙˆ—ËÅÝ»w©gÁd2‘€‚‚ÄÇÇãÍ›7ÈÎΆŸŸzôè·oߢ¬¬ 7oÞÄ… pÿþ}ìÞ½æææÀ–-[™™I Ô...˜5klllðøñclܸýû÷ÇÊ•+‘E‹ÁÝÝçΣáhiiQ¶ÀÎÎÎxôè­±víZ°X,ê9/]º”Z[¢ÖöÕFmll°fÍtêÔ ÚÚÚ8p üýýqíÚ5ìÛ·.\@VVfÏž «+ðÐÒ‡BÛ¶mqìØ1ª­ìÝ»ååå°±± ¼½½©Åç€ÏÎÂwïÞ…½½=Ž?N•?> IIIBRRÇh'÷îÝ£'@ƒ¯ºº:tuuÁãñ0}útJh«åرc4h.\ˆ &ÐyYYY,_¾|>_h_ײeK 4ˆÚîÔ©MèVUUŤI“ ««+PvÉ’%ضm† "à(­¨¨kkkJã9fÌZ¾¶¶66mÚD‹n%ŒÑ£GSfjµ¨©©}•¯ÉWWWJ#´xñbZ ,ÀáÃ‡áææF‹¼5kÖ,tìØêêêÐÐÐ@ëÖ­´:²²²èÚµ+Ö®]‹#FPëqÌœ9:uhgµcĈB¯·¶?“’’‚‘‘‘H­S÷îÝ)WII #Gޤµ•Áƒ7X7£GÆÓ§OiÎãµílÞ¼yÐÓÓC‡h ݺuƒÁÀ Aƒ ¥¥EtTUU1cÆ ôïßÛ·o^þÏÞy‡5u¾oü†„@Ø+ì!S‘) ((8p¡R‹~­þÄQ *"àÜ‚[‹¥*â¦.Üh¥n‘é`ˆì ùýAó6‡$h[µ¶=ŸëâjÍÉÉIÎ|Ÿ÷yžû¶²²‚¤¤$???Œ5Šdè•••¡££ƒ´´4=z®®®SG]]]°X,xzzâçŸFXXÙÿ@G ïÞ2cÆ øûûCWWW ¨®®™™™hii­­-(a†††Øºu+æÏŸk×®aĈÄ‹¦²²IIIÐÒÒ‚¼¼<´´´ðèÑ#²ï 0sæLR)¶¶¶hmmÅþýûa``€¶¶6Ì™3G §Ãá`þüù(..ÆÛ·oQTT%%% uæùóç••…¦¦& ——‡ììllݺ&LÈ‚Ñ||˜eåÒÒRܼ)ʨ‡+2EùO`Ö¬Y°¶¶FII ˜L&*++add„cÇŽá‡~@÷îÝ¡¦¦†ƒBAAxúô)BBB ¦¦'''’þ¬­­ÅÍ›7‰”à˜1c ££ƒ°°0<{ö K–,!3³gÏÆ¬Y³ ¨¨ƒììl´··ãøñãX¾|9 VØl6 `ooË—/#//3gÎÄüùó±oß>dgg#''%%%xõêüýý±jÕ*ìÙ³eeeÈÊÊBrr2ÄÅŤ¤$¨©©áâÅ‹PPP€©©)®]»†û÷ïcÁ‚(++ƒ²²2JJJPSSƒÒÒR|ûí·hhhÀÛ·o±~ýzlٲϞ=ÃÝ»wáààiii’Nf±XÈÍÍEMM ¢¢¢`ggEEEÈÈÈ@[[ÅÅÅØ²e 444H÷‘‘™9Ž‹‹#3ÂwîÜÁýû÷±{÷n477ÃÄÄ 8v쌡¤¤„´´4p8Ó°††<~üÚÚÚ°´´Ä?üÌ›7ÒÒÒ¨¯¯Ç®]»jú_½z…{÷îaÙ²e"Uxò‘¸yó&6lØ444 ¸¸...¸ÿ>-Z„óçÏ£¢¢ŠŠŠ?~<ÜÜܰnÝ:ÍfcÅŠàr¹X³f öîÝ ‹KKK8p³fÍB= ®®MMM¤§§ƒ•œŒžÆÆxýú5‡â믿ƃ°páB 2L&êêêÆÎ;±fÍôïß/^„¡¡!,ÓÓ‘âîŽÝºº8vìºuëFÌÉ`kk OOO²ïÐÒÒ)))xyyaÿþýصkjkkÉ€€wÝhjj¢¢¢………)žûrii)©çüç°……ŒŒŒI€€‰‰‰På+«V­‚¼¼¼È庺º——'ïQRRÂñãÇI€+ ÊɉɄ––FEÊá:g9ú÷ï‡÷öStõ{þìºÿE¬­­ÑÞÞŽU«V‘r%^¦Wî'Ì€_žø}0/^¼€––9.¼u?.´éZCCCè1”••…­­í©ª)))Q×#FŒÚ7$&&‘“ˆ’’’·yþìã…  --M® Þ€^EEFFFBÇÕÕÕ¡®®;;;´··S~§¢¢"TUUa``999í~ýõר½{7Ö­[ <þœ¢6{ölˆ‹‹cöìÙ¸té)o«®®†••´´´È³·¼¼rrr8~ü8$%%ɇ¶oßqqq0  ¨¨ˆ”5ò~3Сd&--îÝ»C\\±±±Gdd$ Š‹‹ñøñc²]333cíÚµ”}“™™‰ÖÖVò¾'Ož@OOׯ_'Ynþ,³¯¯/lmm±}ûvHJJ"!!Û·o‡ŸŸ¼½½±råJJvª®®µµµhooÇÐÚÚJ‹³|éHjêC˜š‰\®¥¥ýÝ1  ÅÌ™3áââBÊ ÊËË1eÊ#** ׯ_GUULMMIJ›Wîââ‚1cÆ ==û÷ïG||<Ž; `ß¾}ÐÒÒBHHz÷ äååaâĉ°²²‚šš©©-++ƒšš¦OŸ{{{ÄÄÄ ˆŠŠ‚¡¡!nݺ…ÆÆF ><€‹‹ RRR°yóf=zzzzèÙ³'%ãòæÍ¤¤¤ÒÖÖVˆ‰‰aÇŽ066ÆèÑ£1dÈÌ;»ví‰'ààà€»wïRšW0tèPPVVƵk×зo_!((ݺuƒ´´4´´´žžŽÁƒãæÍ›ÈÌÌ—Ë…ºº:fÍš…%K–ÀÝÝl6ùùùhkkÖ-[˜˜www¬°sÇ8OžŒ &ÀÎÎ3fÌ ÁÍÍÍ8xð ÌÌÌÐÖÖ'''´¶¶’ýåË—ÑÖÖ†´´4ØÙÙ!##§OŸÆ•+W !!Þ½{ÃËË ›6mÂíÛ·Ñ·o_(++ãéÓ§$ÏÛŽ½½=Œ‘žžŽÓ§O“0^««+\]]qýúu¬[·7nÜÀ²eË••eee¬Y³õõõ”Ùþµk×¢¨¨L&vvvX±bnÞ¼‰sçΑÀjÈ!077‡ºº:™M\¹r%FM‚Ý7n`õêÕ––ÆðáÃ1qâD2Ó–––†GaÙ²e È§òÊŽúöí+0;*ÞÞ“ß|&x³þü*IL&“ÌîÖÔÔàîÝ»ðóó#³³âââpuuZ:Ù¹d…SSSâØ±c} ¼Fnnnï•*팹¹9‚ƒƒ1vìXÆ\þŒpç[WÁÇûÐÐÐ Ù3QS úPþʺïãÖ­[èÕ«×_úýŸƒÖÖVüú믬Ü%..NÙo¼ß'̰R]|ššš"Ëͤ¥¥a``@1w 2 &,[òÁƒ!¦ðáƒÁÀž={þÔgv¾^y×Êû2„­ËŸá¹yó&®g JßïžÃ?¡Áû­FFFd¹žž%Àâ݃ù³LÖÖÖPSS#¥Æü :”dPù¿7ïÿyÛí\!¢££CQœãía÷)eee¬[·7nDÿþýŠÝ»w“s‹·-{{{QÎ---R’ÙÒÒIII8;;cüøñ:JíììÀår¡©©‰††XYY}ÒkÁ`ɔėاÛK–ø‡Qo4L0L´¶6¢¥¥¯_—ÀØØíí-”“’n@R’Õå‡ËÉɃŒ„ºº: PôîQ[Û#ˆ‰q!.΄¤äç·‹/((ÀÆqõêU\½zÉÉɤÁµªª ïÞ½ƒ¡¡!œŠ’’dff¢  ŠŠŠ¨««Ã7ÈL¿ ?~Œ””0 ´··ÃÑÑ>Ä“'Oðý÷ßCOOªªª¸~ý:Þ½{OOO\»v ·nÝBZZüýýÉ ZUUëÖ­Cqq1Ƈüü|¼{÷÷ï߇¡¡!^¾| ;v 555ÈÎÎÆ«W¯pûömxxxÀÐЋ/ÆW_}…‹/âòåËhjjÂëׯ1aÂ\¸pÙÙÙ˜)Y㟙äõ4899!55eeeèׯdªª WQíß‚½®(,,„¿¿? D$%%O)Wà4hhhàæÍ›5j”ÀÃ9-- ÖÖÖ¥~~~˜7o,,, §§'´t‹@#X›˜˜ 99#FŒølƒj‡$$$`ذa"b_"+W®Dÿþý~<º2ªûØ”——ãܹsBK±lÙ22ûPNž< eee‘¿ïƒxñxþø­gŠ—ÁÓÔÔšIÑÕÕ¥”}=|ø²²²èÑ£ÇqÌ»:¦ÑÑÑBªþêvDg)))رcºwï.2k‡nݺ¥9ae’ A¡¡¡!ÔÕÕ…hï£]‘™™‰'Ož=Ö¢8sæ <<<`ooiiixzzB\\·nÝèë²´´)Ìt”Ûñ*Xx¿}ذa°°°€……äää ¬¬ü‡Î¯¶¶f´´t(hådÀ̬;3WW× 77ÆÆPPÿ-PdBAAé·ÀLì‹þƒ!öö´··vJB¤ÁÒÒuuÂåâ[ZZQZúææfô»úÏ÷€¨ªªbüøñä—º]½z5²³³±gÏÔÕÕÁÎÎ&&&غu+¶nÝ ###XZZÂÐЉ‰‰ÈÎÎÆ¾}ûЫW/\¹rÎÎÎ044„……®]»†1cÆÀÞÞóçÏ'N±÷ïßÇ7àêêŠÂÂB¤¦¦",, cÆŒA[[Ö­[‡ÔÔTèêêbäÈ‘PVV†šš/^ ---°ÙlØÚÚ¢®®“'OÆÕ«W!..---888`ñâÅØ±c.\ˆ””¬Zµ ‘‘‘$ÓÂ__=xð`´··£¹¹øé§Ÿ°wï^¨««#++ ‘‘‘8{ö,ÌÌÌPXXˆU«VAKK ¶¶¶HJJBpp0~úé'R2RYY IIIŒ5 gÏž…^¿~ ‹…þýû£¸¸qqq˜>}:ž?N¤sŽ>‰¤¤$œ={£F"޽nnn8{ö,444Àb±ðâÅ Œ5Šr<ýýýadd„ž={âܹsPQQ’’rrrêÉ•””°råJÊk×®]ƒ††òòòêGy³p„¬¬,aee…ýû÷Sš’·lÙƒîÝ»cçÎ055ÅäÉ“‰ª“ɤˆð>×ÁÁ>—ËÅðáÃ1|øplܸ›7oFïÞ½ñË/¿ «V­Â¤I“˜˜ˆÐÐP ~Ú4ü”’‚¶¶6\¼xîîîÈË˃¹¹9œœœ0{öl899AII îîî¤w¥  €4ô>yòµµµ¸páÄÅÅÑ­[7”––BJJ %%%˜>}:=z„Áƒ£­­ kÖ¬Á‰'°aÃÔ××cåÊ•HLL$ÇäÔ©S¸víFމ””"€PWW‡k×®‘ ‰}ûöÁ××Ïž=ƒ»»;pêÔ)„……¡ªªŠ(È%8¼†ÆuëÖ¡¬¬ §OŸ&‹òòr#)) ÍÍÍ8pàé©««CRR¸\.¸\.(¥¼×y<~üX qèè窯¯Gnn.äåå—í´>ŠŠ "Á¯¤ÅO=`bb777,]ºT`fmm5kÖøSð÷uFJJ nnnèÕ«öìÙÓ¥§Hkk«@ÈßMXXX—NÜ…Oá¸üAs‰bbŸm[UUU½P•_ýU ¯«sðCñòò‚½½ý½×ÓÓ“dTÿjjjžW¹téqæÌ‘Ÿ³jÕ*}ÙÕ9ÊÛΑ#GH¦ôÖ­[”¬BNNbcc»ôý¸zõ*êëëñâÅ ¤¥¥ }ÏóçÏ)“i¹}û6UQPPøCÇãåË—d»ä:ä=¿{õêmmm¡¦¢îåü 2„ô" +ïû÷uu5HJ2ÐÚÚøøût.òLüÇ‘••¥ÔNódZ  wwwDDDÀÁÁR’Ã[GMM 666Dm! ©©©HLL$å:<éÁ·oßbÑ¢Eˆ‡¹¹9éu¨©©!J666000 ÷‰'0hÐ (++CUU§OŸ†§§'NŸ>¹s碱± X½z5JJJ°yófp8„‡‡ãäÉ“””Ä¢E‹HfUU8ÚÚÚ //øøx,\¸ èÞ½;’““ŒÂÂBR‚UXXˆ#F‰ÎnݺÍf“CCCDEE¡°°k×®Ell,,--¡§§‹EJ_nß¾M©¹}óæ ”””`aaóçÏCVVß~û-Øl6äääàííœ;wލ ñc``€Ù³gãÇDVVnݺE²6•••°µµExx¸P5“½{÷’f` DEEaΜ9x÷îX,QÙÊÈÈÀ„ €-[¶P„åååÁårQSSCi®411¥¥%,,,333Ò«±téRÄÄÄÀÇǹ¹¹ˆ‹‹ƒ¡¡!6lØ555,_¾2222d6oÞ :tß}÷FŒ={öÀÐÐÕÕÕ°±±Akk+¢££±ªº'0ÍÚ³fÍ‚˜˜¢¢¢°dÉâ‘‘òòrLš4 ÙÙÙhnnÆwß}‡Õ«W“fãgÏžÁÛÛ/_¾‡ÃAss3ª««‘––†"99S§NÅO?ý„Ý»w£ªª iiiØ»w/"##‘——G9N›7oÆæÍ›akk \ºt æææ8wî´µµqüøq;v }úôAcc#¬¬¬pøða\½z•ôQøúú’²žÖ{ll,Ɔ†TTT ¬¬ ¯_¿†””/^Œàà`9r—.]BUUf̘ùóç“Ò- hjj‚Á`@YYÆÆÆ˜6minLMM%b 7nÜ@ll,LMMñ믿âñãÇxñâ9Ÿ³²²pç§Ÿ°'5«W¯FŸ>}PSS---´¶¶"55l6›üyzzR¤÷ïßGGGøûû •_-..‡Ã!™>þ‚amm ÒÏÑÚÚŠÜÜ\!//ǧhàó3räHÊŒiVV¹ÞyË;Kkóî•ÊÊÊÈÎΦÈÞ&%%!%%_ý5ôõõ)å- DíKÕÕÕÈÍÍ…¡¡¡@YLVVTUU±xñbøûûSúeÞGVVöìÙƒ¨¨(Œ9òo ¸Î;÷¯{†fdd 77ÒÒÒ‘‘˜yohh æ­=zô€°“'O¦¨ð¶óæÍTUU¡¥¥©©©"Ëõõõ¨¨¨ÀÆáççcccìØ±.\€ŸŸŽ?ccc$'' ôÌð²ú™9s&BCC‘ŸŸÒÒRÔÔÔt™mhooGnn.LLL0kÖ,Ì;þþþðööÆÈ‘#QUU%RL§ó8!??xúô)Fuuu,Z´Hdѽ{w,_¾«W¯FHHtuuQ\\Œ7¢¼¼nnn¨­­Ejj*ºw¬,èééAVV£FBll¬Ðsåcp÷î¼zUøèE“––ÁW_yÒÈçFNN¡¡¡y>þÕ?þ( ñÏ;ù…IÃ6 µÔrrr]>˜ ™™‰™3g¢½½Ì0»ººbóæÍd6dÈ!”2‰_~ù…Ô®òØÞþ- IDATjÙ_½z///´µµAAAíííØ¸q#…qãÆ‘ÚÇ)S¦À‚ÌÜ?ººº5jöìÙƒððpüòË/§Hú-_¾ÙÙÙHLLÄ•+W0eÊp8(((@NN ÐÒÒ"5š!!!°µµÅ²eËwwwã#^¿M»••¸\.Nœ8===<}ú–––Ä÷ãîݻě GÄ„OSS“ÜTÜÜÜPSS#²A’?cÒÔÔ„¸¸8DFFâÑ£G"ÑqïÞ=rŒ¶mÛ†«W¯R´Ý°råÊ.뀻wï.ÔÇ`èСÈÌ̤HKæççCúÔ)hŒ‹ `Μ9d°ÎcÉ’%X³f ¦OŸN¶ëîî̘1À‘#GH·»»;¥¾ûþýû/Ó§OÇØ±c1tèP"û˜{÷îaíÚµ”ô8o/)) ƒ "}TTRRRpãÆ ”——ƒÃáu „éÓ§ƒÁ`àåË—`2™ðõõÅàÁƒñèÑ#œ:u 3gÎĹsç0uêTìÙ³Û·oǽ{÷PUU$''#<<ƒ†¾¾>¶lÙWWW¢µµ²²²””ÄôéÓ!//ÇcíÚµpww‡‹‹ ^¼xàà`¸»»ãñãÇÇ´iÓ ®®OOOìÛ·…YY›>»¾ýK—.…ƒƒØl6‚ƒƒqåÊbJwòäI¤¦¦bÚ´iÈÈÈø`©Õø6t¦¹¹+V¬ ×bee%V­ZE2O Àõë×IÝÿÛ·oqêÔ)¡Òª .Dbb"RSSѳgO¡ƒ‘ .àæÍ› ÅâÅ‹…ªÈ………aðàÁ ‚‚ÄÄÄ`óæÍJWMMMØ¿?.\¸ÕªiÓ¦a„ ÐÔÔÄ­[·žÿ¿™_gnݺե&/ƒý¥÷q|NΜ9dgg ,«¬¬ÄêÕ«aaaÞ½{ ô•äææ" \.ÑÑÑ02ؾ|ù2† J°¦§§‡àà`lÞ¼YèýP‰‰‰6l¥ßðéÓ§HLLìÒèïcÀË(ïÚµK¤ ü‘#G ''‡+W®PzÅ€Ž’à„„TVV¢¬¬ ¹¹¹.ëƒÆáÇ)²9>++ kÖ¬ù`#ÙœœRö t”JíÛ·žžžPTTDZZ PQQ+W®ÀÔÔ©©©Ùòòrdgg£oß¾HHHÀ³gÏ(åŸŽŽŽhnnFjj* ‘››‹¦¦&ôìÙoß¾EVVœœœ€wïÞ!99cÇŽÅŠ+0vìX´µµaÆŒضm6mÚD‘ÿçeé „Aƒaß¾}”óìèÑ£ðõõ…ŠŠ ®\¹‚üü|2€1cÆê†´´´O€@¿~} ¡¡þÅ_ûbbŸ®PŠ–áíeee‘ƒS&“)4øà Üedd„.ûꫯÞ+!Ù™   ß˜¸8i*?~}:€Ž^~.—‹ .ˆô\ˆÇ† °}ûv2[okk‹7oÞ 00[·n%ëJII!<<ÈÌÌDLL "##Žëׯ£©© ŽŽŽ())!ž9}úôANN¦NJ¶É«ŸîÙ³'‘Ü ƒ©©)ÔÕÕqþüy„‡‡CMMˆ˜ššBAA““C¯^½ ''GȶlÙ‚òòr„„„`î¬Ypµ¶†­­-‚‚‚(×ÿÁƒ±~ýz 6 ¾¾¾ÐÕÕ…©©)É(ðT\€Ž~#F_˜ššÒô¹{÷nÕׯ_ãõë×èÓ§åsø]<¯–ñãÇãèÑ£”¬ÊùóçqüøqL™2£F"ADmm-öìÙƒ«W¯¢OŸ>}………xñâJKK‰ï U«VáÆÃÓ§O…6ðÞ¾}7oÞ$áü3¯·o߯¦M›(îË< úõë‡ððpÃ;ÞàmÑ¢E¤ìN§OŸ&ÙgaÄÅÅ l÷߯Ž;(çYgÊÊÊ(žQÁÁÁ B÷îÝ+R:~÷îÝB ˆ{÷î-[¶¥¼Îå[·ná‡~ H«îݻĔ)Spüøñ.™° 7¿ŸÒ§$88˜2Ð-..F^^¶oߎ¨¨(Šò?^^^رcüüü(%¹)))äþâïï/trÒËË qqq°¶¶FCC1@ñ&¹s玀1ñÌ™3‰Ì:?=B`` ^¼xcÇŽAOO!!!X²d ž?Ž‹/ ±/--…ŸŸ‘ü-,,ÄâÅ‹q÷î]ÄÄÄÀÛÛÉÉÉßÃ×׳gÏF`` ‘ŸŸOÖõóó#j›<5ªÚÚZÜ¿mmmBáׯ_ÃÏÏ‹/†§§'Œ!''‡ÔÔTÔÖÖ"&&îîî011²²²@ÿSï޽ѯ_?(++#<<œ"ËLC ÿYfΜ)`0ÆC”ꇥ¥åïµé7n† "$Õ&-0ÓÂÃÍÍMdzšÍfU ÒØ5|øpÀµ»Ã† “É„¹¹9 ´´´ ªªŠäädâÞÖÖ†7oÞÀÈȃ "0)))œ9s†4³ÙlJ/•¥¤¤È÷HHHÀ€ ©© '''lÚ´ ÇÍ›7¡¦¦+++(**’\qqqXXX gÏž4hˆw o°×ÕŒ^}}=êëë¡««+p®ÔÕÕáõë×055…«««ÈÙ:fÇ;wîs…])))‘3n’’’hii—Ë…¶¶6Æ'pŽ^»vbZů¸²lÙ2xxx¾iiiìÝ»úúúĽ–w޲ÙlX{yy‘æóΙGmmm¨¨¨¶„„ ¯¯555ØÙÙaåÊ•ˆˆˆ ê[jjj8tèi.ýî»ï \Y‰^¿.C‡…¿¿?äää‡CKK =zô@ÿþý‰ó÷¶mÛpïÞ=ÄÅÅ¡°°îî‰™™ÒÓÓIð·sçNHHH ¹¹  ؾ};ž9üçŦM›È€‘çªÎ«ÍniiÁ÷ßC‡‘ýÉüð:¢££±qãFHJJ’ÀþâÅ‹(**‚˜˜®††”——céÒ¥Dð£3fff())0b”——h”ïL^^f̘AœÜùiiiYöÒíííïInnnþCƒÞˆˆ¡+¼LÐ_@766âÆBM0ùåÊytøNñʆkkk)GÕÕÕÈÈÈ€½½=îÝ»G›¼ó,55 L&ß~û-e[›6m¢E‹`gg‡[·naÞ¼ydÙ¬Y³ÐÒÒ‚^½z¡°°•••: jçÌ™ƒyóæaܸq¨¨¨ Yä#GŽ ÿþ¤_µ´´øfu>F555hooGkk+¾ûî;R–ØÚÚJÖÍËËšñåÑÚÚJÎ÷û÷ïCZZñññðóóCxx8ÊËË1nÜ8|ýõפ<»¡¡ííí¸ÿ>š››áììŒÆÆFœ;wŽäççãÑ£Gøúë¯1pà@ÈóÎÙû÷±ýúõƒ˜˜ŒÑÒÒ‚²²2´··£­­ ŽŽŽÄíüÿþïÿHö¡µµ\....¸sç%ÃÇÛ¨¨¨@jj*†üü|DGG_®°Ùlx{{ãСCX¼x1,X€ëׯ###‘‘‘øßÿþ‡   „„„€Ãá@VVÕÕÕäÂó2qvv†¢¢"LLLPQQ-[¶à›o¾AÏž=1aÂ,X°€Lò?G¶nÝ 333899áÀhkkûwïÐÒÒ‚ÀÐЪªª““ƒ¯¯/–,Y‚¼¼< ¿yóæ!99óæÍƒ””ììì(Æ4ÿ’¤¤¤ÅÅoÈ_yù[zï ,KÀAö¯À+…ú£ˆJGîÚµ‹òýbcc!##999ØÚÚ’mño·oß¾$[Á“äÕÓ “ê:hÙl6Ñß±c’““tôƒ¸¸¸€ÉdBNN›6m‚µµ5,,,`jjŠÞ½{“ž•Y³faذa`±X… Ô××CAAÚÚÚ”7;;;J¶ÆÇÇ{öì¾¾>¡©© 555455‘f_MMMÄÄÄíÏž=²²²`2™––&¿WWWÑÑÑèÖ­›PùAôêÕ ²²²`0” šºº:ÚÛÛ)¥ <$$$ÈR]9s¹\äçç u²677Y»&ÐØÏ¿ÏŽ;&²A’7c%ìØ¿;ýòøé§ŸH¶-44W®\!ïß°añPRR‚‘‘‘РϘ1c0iÒ$²Þ¤I“àíí 6› +++x{{c„ Ð×ׇ››‘cæ½ßØØXh‹ÍfƒÁ`@RRR@†·®‚‚"##ñðáC,[¶ rrrDZ±±[¶l!™¼­[·"((ååå¸sç¥ÍÎÎúúúÈËËÛ7o`nnŽï¾ûÐÖÖ¦üþ‰'BCCƒô‹ñ÷{dffÂÉÉ )))¤<$22’\¯@G‰ 8 ˆõë×#33}ûö%£¦¦&,,,(APHHñ!òôô˜å±gÏ‘5ô¢…………ذa¥ì’Ÿ“'O©pa¼|ùRhyVNNŽ€8€°ïË?“ý>JKKEC‘‘‘=7”E‹!44”RþÙÕÀüÞ½{¤)š—äÍŒOš4 ßÿ½@¯FII ÌÍÍÉ9zèÐ!ì¯? èèq,**ÂëW¯pãÆ ´´´ >>sçÎÅÞ½{IUAyy9”••‰ú•©©)™å¯¬¬„ŒŒ Þ¼yC‚^@tþüy¬X±ݺuÃãÇQRR‚ââbʳ©{÷îÈËËÃáÇK26çÏŸ'™Œ¦¦&¤¥¥‘uy}IžžŽªª*lß¾OŸ>… deeñîÝ;Š|N.Z´999¸{÷.ÚÛÛ!##www:t­­­¨¬¬DKK !//111L›6 úúú8}ú4%ˆ‘‘‘††vìØA>?77wïÞ%×lxx80ÉÊÊÂíÛ·QWW777¨««cçÎ000 ¥I·nÝÂÊ•+) ‹ÞÞÞ¸t颢¢ ¢¢ ´··c×®]äøìÞ½FFFÐ××ÇÓ§OQVV???$''E¿Y³f!++ 077‡¿¿?)s´··‡rssQVV†ùóçcΜ9`±X`³Ù¤'ŽÅbÁ ,Àøñã!))‰nݺáܹs8qâé‡ã÷WáyBUTTrr~TUUaddyyy¬^½úoß— ¨¨>úÏm?KHYÙäåå Ì蘚v§£‹9¼2?‚’’†þ&ÑØ™ &}ç2- +++2øÒÑÑ!.ÓŠŠŠˆŽŽFii) ¤D5ÄmÚ´Ièë¼4®””œqéÒ%ò ì\¿nkk+R±³ô*?=zô) È»qŽ¡v£¥¥%R¡$""ááá"³dqqqBK4/^,à.ÏÏĉEfSxÇJ3fÌØ888ÀÝÝ]À•÷S!%%E§øÞ!3ô|òÎüm*ïÞ½;¢¢¢ºTþILLÄÈ‘#a``899!??YYY––Æ?ü€ÄÄDÄÇÇõ¬œœbÚÉ Ì_¼x @GG†††dp)êØoÛ¶Ô•÷éÓ‡üü|ÿý÷¤‰;""‚Ì–oß¾ Ô¡¡¡ `íÚµBK±V­Z…qãÆ‘óìÔ©Søê«¯þÔ1«««Ã¹sçpèÐ!¡e+—/_Æ!CHý¼0(RÝŸ“³gÏâÍ›7q‚ÏEee%Nœ8¯¿þ/_¾Dpp0Éj‡††"!!\ÓÂjBå’;F)u‰ˆˆÀÄØXœ={«oÜ@bb¢@‰Òóçω´6ooo¸»»Sú1I6<--ÜC8€„„„……ÁËË ííí$»Î£¶¶çÏŸ'¦©Â¸ví®\¹‚É“'ãùóç8sæ V­Z…uëÖaÙ²e¸ÿ>Q)¼{÷.e¢„ÿÞ_RRB¤}ûöáúõë$‹ £ï(##©©©¤:ALL kÖ¬ALL .^¼ˆ~ýú!!!A¨nWøúúÂÝÝË–-ú<ýæ›oðäÉlذ£FY:+ ~§öiÓ¦aÔ¨Q]J;+**RÇ555IFlôèÑBÏ´XAAA éÜÙÙÎÎÎððð@SS“Hó@yyyâÓö¥ñæM.]êPg´³³¡3 CGG ݺéQþTT”é:***òº<>ÄÀIØL?¯YUOOÒ$illL\JJJ”†X}}ýÚÞøñã?ÈàÍÁÁá£k×+**v9`ÓÑÑY¦§ªª ___¡Ëøû'„ÁSv5(ç7ü#ÇPÔ²¾}ûvéÖý%âîî.²\ÈÜÜ\dðÑ£GÈÊÊ"88cÆŒ¡œ£@‡ê©©)Éè.ÎÂJ.ŒŒ(·±±11~üx‘=?üôë׆††PSSƒ­­írvvvšAëLvv6é 8zô(eãëëKä@ׯ_ÿÞ,DWðL;?6 "'(>„ŒŒ âøÝ¹¡ösbllŒ¶¶6Ì;—¸^ £s?o]ÞyÆ#>>ÍÍÍ"ï%¾¾¾000ñÍÌÌš ì ƒÁ %S)))Ù²W¯^‘rG~æÌ™# ïÞ½¾¾¾8rä²²²ðã?’ɳ¶¶69r***£ÐÓ§OcÀ€%†ªªªä<Gxx8ÒÒÒ`ee…äädìÚµKä¤Ð¹s焞£ZZZXµjžF¼R¯qãÆ}Ð3·«ÏîŠ+V”M~(!!!B×utt¤dhEBââ~8ûgïÇÀÆÆîîCáã3ÏŸç`Ò¤YäoãÆm]|çµî£¹d½’’Rʲ·o+ȲÌ̬ÿVBCóOäôéÓBUŠ6mÚÔ¥ügllì îþnØl¶Pþ©(Dõ ½mÛ¶uù¹ÿ& þðl%Ð!~áíí-²/‡Íf“YÁ?ógÏ`jj*àIÁb± ...´ì‰ÍfCMM óçχÐ]mm-¤¤¤Î}&“‰û÷ïcÿþý(//§1110™L<{ö Ë–-PÛâ»VWWã×_¥(ýôÓO"·Û¶m£8BóàIÅr8RÀ¦¦&p¹\‘“ õõõ”&i­­­xøðáïžü5Ï#¢¢¢‚ÒTÛØØHTöZ[[»ôŠà/ùüêêê„6‰óSPPÐ¥yÞû®}^†@Ôy&§¥…*X[[CAA¡KŲ®8räEõG@@lmmaee…¸¸8Ò»R]]¹sçbñâÅxñâvíÚ…Ù³gãØ±c¸~ý:¬­­‘••…wïÞáÉ“'èÝ»7ZZZ0~üxTTT€ÍfSʹJKKall ‹…!C†àÝ»w((( ü^111 6 ººº8sæŒÐI yyyÔÔÔ½7Nœ8K—.Emm-Ž;F&bxÇÁÏÏ{÷î¥×¾}ûâÀ”s4??Ÿ¬{ðàAÊ6øÿÍápº<Æ×í,üY»ôÉyßvù3¿dÝ¿ò<ûX\¾| EEÅ^ƒÈÈògffŠ;¨½·UUÕ˜7o®]K&¯•”¼Adä.²ÞÊ•kI›ÃÛ·X¶l5YƒW¯^Ó Í—Lg¹d "oh={öü Yß/&“‰˜˜˜þ¹ i¦ê¿‚´´4¶nÝ*Ôaøðá˜8q¢Èuóòò ©©)TFVKK #GŽZÊÖ«W/¨ªªâòåË"?[WW½{÷(+SRRBJJ   P¯¥¥…•+W¢¾¾³fÍ¢(ððŸgUUU"Û¶m0qTRR98WTT$ ÍüŒ=cÇŽÅ?þ(Ð,}çÎ455•´Îœ={–˜cv¦¼¼œ̾¯„ëéÓ§Xµj¥©=''ÚÚÚpvv&ï¼`@TOŒÿýï”I‹¡êZJŸ>}`&¤·ÈÛÛ}ûö©ì—ÊÊJ ŸŸœœœ0fÌãéîî.T ëM´··‡½½=<==)â¼>777$$$ ´´æææ“¿Üþ%00Çèuá!%%%²—­«· Ï ÿF…@ö«¡¡…©iÇ„feebcã0b„zô0ùWüîÿüT¤¢¢"HþþèCŒ†††æs¡  @šT#""`llLñœÑÒÒ† (=#ìíáá°°0¡b &&&Bƒ£G9Ãéää„wïÞ‰œ5ÿ³ðêõ/_¾Ld?;sàÀ<}úTàõ’’¢¢WWW‡Ó§OcâĉX²dI—¬]nƒ»S§N¡´´OŸ>Enn.JKK‘œœŒuëÖÁÕÕ---xøð¡ÈÌOWƒü––5ÑÑÑj=IIIŠ*ÖÖ­[ÎQ,Kd£´„„ÝßFó§¸uë.**ÞA\\ÒÒlHK³»Ž³aeÕá_ræÌa\¹rŠüuïnB‚¡CáÒ¥ßh¯]»;”Ö\]ñË/7ɲ+W®ÃÍmÀñ»™ô¡§¡¡¡¡ù»™9³fÍiÄ) 555ôïßïÞ½{oÉöíÛE.:t¨ÀÌ¿˜˜ÄÄÄÀårqåÊŠ«´˜˜ÄÅÅIv£3\.\.bbbXºt©À컞ž,,, ..Nqdïê;ŠBLL ÑÑѨªªB[[ùÎïÃÝÝ8³/X°€¨~BUU:::xðà"""ðÝwß ý qqq‘3þ]-ëÜ7Áú›7PøPh¢©©)Ô0yWæ¢J ˜L&¶lÙB_„4_$öPRR—ËÅ”)IPbnn&rèèHÊ=bÚ´IÈÉéèëÑÔòÞ Æ’LŠ‘‘Ác@ç ihhhh>9ššš‘‘ùCë°X,(((€Éd ]WVV’’’PTT„………ÀºJJJ`2™B{þïÿþúúúHHHú]ÇŒƒÝ»wãðáÃ.ß©©©ÈÏÏGPPŠ‹‹)n‹E¬>Œo¿ý–,Õx- 333Œ;Æ Ñ#Gàáá©S§âöíÛ8{öì{ Ú<==QPP€cÇŽáÅ‹ÐÓÓƒŽŽ¤¤¤ ##&“‰ªª*‘ÒáaaaB}+äää°fÍšžèªW‡Åbáĉ"×ÕÓÓiä(&&ö¯G§ù÷QVVŽï¿Å•+×!## kk X[[t|€‰ õ|æ_—_¢è(ä-“••ùb~;€ÐÐÐÐÐü#éÑ£ÔÕÕaooMMMÊ2‡ƒþýûC^^^À8T\\œ¸—0@¤¡¡ƒƒC—Íõ .ð=QQQ¡Ìâëèèˆ,»b±X]â7oÞ  ÃXŽÃá€ÃáÑ”„‡‡ÃÚÚ999BMù‰ŽŽ†ÏGÙï>*444œ/^ÁÃc^¿.üÏýv:¡¡¡¡¡ùÏ2nÜ8‘e?C† ('Z´hŽ?þQ|OX,–Èà‡Ÿ‘#GBGGZZZµýû÷GZZ&NœHJ©æÏŸ/ÔˆR3gÎüâÚhhþ­ØÛ÷‚ƒƒ|}gÒ Íçä›o¾!êP_K¶øÿ=`À¤¥¥ý-Ò¦]ÉÚöéÓwîÜÐá¥ÁßtßÕzŽŽŽBƒ‹% ±KCCCó± ›ÐihhhhþVºjNWSSûìò¦GŽÁ½{÷Hù‘#G(ËùÝÊ;#¬gâc~/ £ôìÚµk¼^||¼Ð^—®fHCCCC ‰ÂÂB=z”ü;77—>+hhhh¾ÿ–ívv5ç!&&&T^—Çš5k>ùw›3gŽPÏ###‘ûës|/š|3%!!Áþ|S1:ùTÈÈÈPù%ihhhh¾l†*Ò8ÎÁÁA ½óº]ùƒ|aaazyWË–,YÒe‡———ÀkÆÆÆèÓ§Ïwwww…/šOK÷î&‘‘C{û—?Þ%µM EEE¸¹¹}–MCCCCóq%Û t”ou…®®î_Þ¾¨Lɇ,ïjYWe^‰ŠŠBmm­Ègœ¨­[·nô DCó™a³Ùhl¬Gccýÿ] &TUe鄆††††††Šœœêë…féDCóñèQÞ¾­€””Ôÿ]¥¤ØpsÓþò++t•0‘‘Eyy9}¶ÑÐÐÐÐÐ|â ä›o¾¡w Í?[[khh¨ñßSLìÓ €ü¥DGGÏŸg ]ÖÒÒ‚‚‚—PWW£Ï4šOˆ´´4†Nïš)IJº UU455 ,«­­…¢b‡¹‘”22‚5d,­1NCCCCCCCCCC ˆ¸822rB—/_CII`lÜjjª¸dyccšè#@CCCCCCCCóŸ#''\.ÙÙ¹pwJ J}}ª«« /¯€êê*òú«W…PQQ&ÿ.*z&“*7VWWúúfèéiÒg Í .8rä$ÔÔ8ÿ¹ßþ—U°***ÐÒÒBšÑ¹\.¤¤$ÁårùÞóVVV¨¬ü½!ýþý‡prrþSÛlnn†¸¸8˜L¦ƒÉEKK ù·˜˜Ø_Öy§¡¡¡¡¡¡¡¡¡ù˜˜˜bÊ”‰PUí¨jkkÚ51kÖ4hkÿ>Aÿúu¦Mó!ÿîÖM{öDÉdÂÇ'ÙÙTmKlÞNy­­­ þþ˰iÓjHII!2r'λD±Ÿ••ÁÏ?úg MMM044BMM5ššQTTŒææÈÊÊPÞ—™ùݺuCeå;ÔÔÔÀÀ ÛŸÚ^FFBBB`ccp8Ô¨±ººÓ¦M#ÿ~ûö-nܸAŸå444444444_§N%ÂÝ}ÔÔ8ˆ‰9€C‡ŽcêÔÿ£¼gÚ4\¹rŠoL…… —cÇŽˆŽŽ¤¼÷öíûHL¼HyííÛwˆŽŽÁ™3ç±aÃ*@QQ ¶l‰€åßò»?ŠHffzô0CUU%1ààe&ÚQXX‚W¯^ÁÐðÏ K—.EBB:„«W¯b„ ”å HHH$&&"??_È÷Í”dggÓW Í'ÇÒ²'ääd³Ý»›ÀÕU°:hܸ¯(ÿNJºAƒ\Þwùò5¤¤<Æš5!䵚šZÄÆÆÁÕÕ÷î=›ïÚµ—ü{Ò¤ñPTTøç @G)VNNäåå–<µ´´ ??Œ >ÒÒÒ°{÷nòoLŸ>ýƒ¿Ï™3g°bÅ \¿~]`™´´445…÷žð|Kvî܉£GÒWÍ?mmàÔ) .ŽÞÒÒ€–0g½/hhºBVPP ¯š/š!C†`ìØ±Ÿe[ ò€­­5\\œqòä÷Ì™óûøwãÆm°±±ÄСƒ(ï¹rå:‚‚B`ggCy}ݺHŒ3vØ´ieYxøfxy'ÿ^¿> ëׇ}ÙˆŒŒ4Fòà«ãÂÖÖŽÒoÁ`0››cc#èèè|ƒÁidhbb‚åË—ómOFèû¸\.***Àf³!--öövÔÕÕÁÅŧOŸ†¿¿?bcc)ëèëëC___èç)**âðáÃÈÎÎþÓÙêêjÈÊÊB\\ü³_4UUUPPPøÏl—w¼åääþÛ:z Z[[!--ýû‹^^ÀãÇ@q1ºtý‹444€Á`€Åb}Ößüwmjjj ##Óõõlh¨ªW¯ÉÝöƒ¶KßG> \.555¿M ýû· tL ¶´´Pï#Ÿc»––háp ”H~^)þÆÆFˆ‰‰Aò?²] ÃÍfƒÁ`ü'¶û±066þlÛº~ýWŒ=..]÷E755cÏž}èÕË nn–;:Úáôéè««ƒ¯o vïÞÿ¥;Ö††(/¯@KK+ªªª -ÍÆò娭­…žž.ù þlÈ€,_øAïëÑCÿ}C9¡¯²Ùlèéé ¼noo¤¤$ÔÔÔÀÂÂMMM°´´„V¬XÚÚZ¬_¿ƒhkÿ1 y¤§§ÿ¥:yòdlݺ***Ÿý¢qwwGbbâf»oÞ¼ÁÒ¥Kñã?~Öí–••!((?ýôÓgÿÍW¯^Å£GÈw W®t € údÛŽŠŠ‚……† òYó¶mÛУG 6ì³ïï3f <<\dÖðàл7°p!°zuÇ,ï_ÄÛÛ+W®üÃ÷0ú>òç&fÏžøøøÏ>H›>}úß’m¿uë’’’òY·{§¹—"":v, °ÙŸmÛßÿ=ÔÔÔ0f̘Ïú›øá(++ÃÓÓó³g???øùù}Ö5,\¸>>>055M× 6êê]«`544bÿþxvÃ!…¾GNNrrr¨¬¬BiiÙoc`-ìÚõyOvv.6nÜŽ¨¨µPVV‚²²Òßö»Åÿi*44OŸ>…©©)\\\Àd2WWW€¼¼}@£-¤=ž…Ù³Íݰ&M’¶â~¦MµÆŒ‘¶/¬°°p‚ƒ‹Ñ·ïNž’¤ ›7o^ŽcVž´_~ùå…jk///fÍšõÔ÷ëááÁœ9sžÉ9ׯ_Ÿ:uîÓW4"Ú·‡•+{Ò«W¯Û§÷a}ýõר=H7ƒ¾ú ÒÓaüxxÈï‚éÓ§?Ø~Ÿƒï‘íûËÁÁ <“}רQƒÊ•+?õýV;xŠ_~i~¡ÓÁĉæÿŽižÌá úàƒ,Övvæm–.]’I“¾À`È\(üiŽG“ä p| ý¿Ö³ý,Y[[?“ö~VûP«Õ¹/®™œ ­[ÃÆÐ¤ÉcÛ÷‹ø?”‡ú1!#fÜù„ ucõ¬~Äx–ß#/Ú÷—••Õ3û±±±Év1ß'¾_½›ÔTËÏʤIæ%¡ÇŒy¢ÓŸÅ ðùýU€÷[Ð\¹r•%K~"00 ËÚwËmj\77×<~ÇZ~ß8;?»ï\kyû…xNéõðÁæéyų1c†Œ "/&O–1!â…“ššFûö¯?Ó®Ÿy"‹©S§J#äG‘‘л·¹Ðc|ò´½õÖ[Ϭ;Ò#›3Ç<&GÆ„ä[Œ‘qÏÞ´i R=wcBZ·nýLž6‰ü¯Ló,a!!¥$yvvî˜L†óu:iiÉh4Y´?~ €€€By~t$ò¯i„üÈÑÑ<5윚÷i¸ï¸ù]íÚænX"ßR©T2]h~а¡yjÞ猼·B<ÎÄd2––c~XX8qqñTªTÞ"}ýúÍlß¾ “ ö§k×÷ðô”ÁJÁÙ³g9pàmÚ´Év°Ò‘#G8yò¤òºF”*UJîY°¶†Ñ£að`i‹g¥Y3øùgó¯ºBˆœµj+VøÏÊO?ýD`` /½ôRŽeNœ8ÁÑ£Giß¾}Á}²+ij @Ö̙߰iÓoX[[Ó·ï®_¿§§üBß………±fÍ™9sf¶k¬X[[+¤8€Á`äYùâ >ž¥–-aî\ps“¶â~Ú´1O_]À.Ï;WWW:mrîÜ96oÞLáÂ…_¸¹Ä]7ß6vh4ùÜÇ“¼FŸy§ÄÏ>„‡‡üº ˆ‰‰!11‘·ß~›V­Ze[¦bÅŠT¬X‘ÐÐPŽ?N›6m¤ážþ7›<ùxÖêÕƒ À×·ÀòñãÇùçŸèÙ³§’¶lÙ2J•*EµjÕä=OâîÆ<6í»ïÀÛ»ÀŸÎ¶mÛøñÇY³f .\È€$%%1cÆ >ûì3<==_ÈY¹T¨Pƽ>µ|D­Q©4?¹yó¡¡HLLâï¿÷áïïKpp1¹ŸCcÇŽ%((ˆôôtiŒ§ÉÑQ‚g­~}ع³@ò±cÇ8xð GeïÞ½T©R…””‚‚‚(^¼8·nÝâüùó”-[–°°0Ê—/¯ÔMIIÁÏÏ¢E‹Êû/ò®ysóTá/ƒÁÀÎ;‰ŽŽ`À€Ô¯__®ƒÌÝîŒFC@LOlÛOuÞ¨¨lÙò ·Ù²å/Μ •+±€;tèsçÎ%99€ÿý—k×®ñã?R¾|y6mÚ$ô4IðñlµliîÇ^ÀìÛ·C‡qõêU¶mÛFjj*111Lš4‰Ã‡ð÷ßóÕW_±hÑ"Ö¯_ÏŽ;رc6l`Û¶m¬\¹’ .È5 òæµ×`ùòçúM&sçÎeÏž=JZÅŠùí·ßøí·ß˜$3ã‰ØS}R¡BY*T(Ë?ÿìç‹/>ÅÚZ–!)H‚‚‚ðññ¡GtëÖM¹)™4iíÚµÃÁÁWWWæÌ™Ã­[· S§NÒpO˸q0p ´Ã³Ò¼9Ì›pÆ›=z°oß>6oÞ̈;ë–¸ººR¯^=‹rMš4aãÆ|ñÅ,[¶ €ððpœ Æþ ¯d-ž£àcΜçn|ÔàÁƒ8p … ¢S§NFÆO÷îÝ©[·.ööö4kÖŒ=zзo_¹„ BäÆÕÕ•.]º L+Ø¥KÚµk‡§§'¥K—fàÀ¤§§coo› À}:FŒ0¯¶-Aý³Q¡‚ù×\w÷{ jµkkk¢££ñððÀ`0’’BBBF£1Û:NNNtìØ‘€€¼½½ñ÷÷—kAÜ_Íš°x1¸>Óï×®]›ÀÀ@ììì”ÿ÷8p@YdN­VÓ±cGš5k€o#&D¾ @t:W¯†ç˜óæ­lß©]»†´|åèèh±b§““NNNeþ FÄS$Þ³¥Ñèà J•*DGG3tèP¾üòK"##¹té—.]¢iÓ¦øúúbkkK5pvv&$$„.]º0jÔ(V­ZEóæÍyçwäZ÷§Õšÿ=§î  *tÏék³¤ !ÈJKK&66>çÛØàç—µ;˜1Ã¥å…"ŸiÑ¢-Z´ÀËË‹E‹)y5kÖ y󿀹K&˜'œB!žZ¢ÑXgYdP!„Bñ|KHHdÛ¶ìg}4 ¸ºº?™D!„Bñ≈¸B™2¥sÌww÷ÈÿˆÉd@§K–wS!„BË»ÞYÅŠUHKKÉ6O¯7;ÿ CÉÉ·äJB!„"Ÿ »„U¶y:Žë×c(Z4ûIdÎN!„B!ÄIHˆÇÉ)û)µ÷ï?„»{Î3tæÛ1 ¡¡X½z=&Û|µZ­­-ÉÉÉ9ÎQ/,ÛJ¼222HKK“†B!J¥ÂÞÞžÔÔTôz}¶e´Z-o¼ñ*¾¾Þ/t[%%%Ž››+F£AIOLL¢H‘€ûÖÍ׃Ð}}}(R¤p–too_ÔjƒÑÑ‘€äÂÇÇ"EÉÈÐIc<çÒÓÓ¹xñ": B!ărvv¥L™®^½Œ^oäæÍYÊ+Vü΂̦¾½L&ó¿»]¾†ƒƒCÁ @îåååƒJ...¤¥¥pàÀ~\\\pp°—OL.RR’HJJ†xÎÅÅÅsêÔ)J”–ÆB!BZZ* ÎÎöØØX£Óe#㔳“««*• ƒÁ@DD$Z­Õ}ëåû1 ÖÖÖØÚÚQ¦LYìíµØÚjsq/„B!Äã DRÐj58:ÚRµZƒµµ Ÿ¾WTT$zL&µZk|ýÄÖ֖ҥ˒’r›”óT^&yÚ%„B!ž“ÉÜÍ?99ž€€BddIO°©w­­mP©Ôðìólétéh4öœ>}‚¸¸„<É׈§OŸ¤pa?T*•| „B!Ä3‘ššÊÉ“§)Y²tžëøûûãééVëüܵGáÂÊßii©8:º\RI³·w(˜H\\&“‘ÈH+’’’)S¦¤\ýB!„â©:qâ4nn.h4œóLxzºS·n-ìímHOO,°ç~÷ WÿiÒäeŠ ´H+^¼X6µM?ùù—ßQk³n4HNŒ§Nš4 ÖÙÙ ƒÁ€V«aß¾ƒÃÑÑ[[­|„B!Ä‘––F||‘¸¹¹¡×qrrÌs};;;ììÀ`xþf! ,<ü,´€X«¨Ø¸[¶y®ý‰·¯çû‘‘‘úH'iee…J¥Â×ׇääΞ=OHH)’“Spqq‘OHÄÅÅqýz¤4Äs.)I&hB!Ebb"ññ œ8qŠ"Eðòò”FyÌžH¬M«—1kâ0ÆLœöHÛqss£hÑ ,éE‹‘””LéÒ!øúú VÛÈ;yööŽÄÇ'`e¥‘ÆxÎ99i¨Zµîî®ÒB!ÄÒhlÑë hµÔ¯ÿr¶eœåÇïg€ìÚ²–_~ÍÈ/À·P ®ý™éc?A¥²¡QËv@¬RvçοILLâÕW›+i³f}K›6¯dYp0%%•;vsäÈ y—„B!D¾Ñ¹óÛÙ.–-žBrù–ü8ލˆ0ÞµŸŒüŠñÃ>ÄÍËoWìÌRþÆ›ÄÇÇpõj8EŠpîÜRR²v1 èõØØXY¤ÛÛ; Ñh¨\¹*§N$:úº¼‹B¼à*V¬„Ÿ_¡lʽH"##9yò¸\BñŠ/AÉ’¥Øµk'ƒÔTËûÔrå*àé™{·¬K—®°zõú{êØØØ ÑhIKKÅÖÖî¾Û2ô<ýo^ØÛ; ×g Óe?NE¥²¡nÝZT¨P6ÿ ÅŠ—aÄ”˜8¼'aýÉû =“BE‚}Žu»víËÖ­kî»}++keÁG´Z E¹v-œ?ÿÜHRR2îòIâ§V«¹p቉·_Ø60üûïGšôC!ØØ¨ ÃÙÙoo_"#¯‘œœLjjªòÿœ¼,Hh4ñðp'00 Kž§§•JMTÔ5jÔ¨%Ðù^¯çâÅ‹¤¤<Þ™´¬¬¬¨]»QQ$$$€Á`yïîááEÙ²ex”çÙyäå«×iÌð‰ßâáíûÄ.„2eBpvvÂÅÅ™ˆˆ«˜d5B!„Bñ ¢¢®áì쌓“¥K—yämzxxáíí§§jµ5ìãöí222ˆ½‘í¿¨¨«:tð‰œ£^ŸÑ˜——'žžîøû?nee=ùêu1mþZ¬¬¬x¥ÝT{©a‘˜L&úõJÿþ=™9sVV9o78¸8¤¤$£×g””$Ÿ!„BñÔ$&ÞÆd2R¸pÀCoC£ÑRºtŽŽvØÛÛ‘ššœ¯Î1--[[-¶¶jŠ/‹Ë“Ìæ‘k+°W°W¨V­ +6ýKõêUññtÆ^m@kcù¤âÍ7_Ç`0лw7^{­%AAÅxõÕ–”.ýƒ&“ “ÉDtô ¹ú…B!Ä33oÞ¼®£Õj )O¡B¾¤¦&&L&c¾=GƒAOFF®®N”+WQévö¸=ÒÒ% SÔ9Ny]´N-ëq'r·Þ½»+·nÝâ¾Û¿té"))ÞܺƒŸŸ*•Í-#„B!Ä£HH0/tu}ðéwíí =‹¯¯*•ª@÷Áƒû±±y2K8±±WL÷FCVVV˜LFL&z4²s!„B!„¥ôtZ­ö¹½gΰ6pL}‘ º Yò :qÛnÒ·E׺èèh–/_@§Nò¼Jd~•ššÊæÍ›yýõ×å B!DðÃKÑé2×uèÕ«[¶å6oÞFݺµppp`ß¾C>|4K™ž=»bee•ã¾®\¹ÊÆ[²¤·mÛoþúk7gφâïïG›6­HIIeñâåYêÕ©S‹ ÊrëV ¿þºZI¿»n–_›ÜWê6 ùòýR©4XYYß·ŒÉdÄ`Ðåëëî¾gÇœ9sðññÁÇLJQ£F=¶3FÙî˜1c ü899™ï¿ÿ^¾É„BQ |õÕðööRþM˜0-K¹·0xðnàèhoQÇÛÛ‹~XšëØ×3gÎqàÀá,uÕj5;wîáĉSx{{}“•+טoV­­³Ô¹|9ŒþÙÀ”)3-òî®›]b2™rüÏ… óí{¦VÛòߢáÙýËÈÈàèѵí#Æóá‡ýY½ú'~÷}Ò¹sg¾ýö[|}}(T¨ƒfêÔ©J™´´4’““quuE¥RåyÇdΜ9,X°0?EP©TÊS–””Ôjµra&''“––¦lÃÑÑ­VKFFØÛÛ+y÷ÖÍIFF·oßV^k4œœÌ–°³³#11ñÎEkƒ‹‹‹R6&&æ®hÙ(ßdB!Ä "))™ŒŒÌ_Éœ±±±!=]˜HO×a0˜Ç‚:8Ø+÷6iii¤¦fÞËØÙÙbkkþU>=]GJJŠ’§Õj±··»s¿¢'))é®Q5ŽŽÇ”’’Bzº77×<ÃÑ£ÇéÑ£³²Û·Y¶l…’o2™Ø½{/§OŸ£T©JzÙ²e([¶ :ŽY³¾cÊ”1X[[çºÏ²eËЬY#ôzýó·ÃÖVË™3¡lÚ´Ï?„££#iii|óͶnÝA“& h×î5egφrøð1:vlÀáÃǘ2e¬Å½iJJN«r›0Òïó¾&póf4AAEòíµ§×›¯±ìèt:®] §|ùR¼Ýž=»²{÷^N:Ë믿úìëׯ+Á€ÑÑÑe,X@Ÿ>}8uê!!!u[¶˜ÇÍš5‹   Ú·7_P'N¤^½z4kÖŒÈÈHf͚űcÇ”z7¦G>|˜õë×3eÊ%oÒ¤I¼ôÒK´hÑ"ÇýF–,YÂo¿ý¦¤-Z”R¼xqê֭ˇ~ȦM›ðôôdèС”+WŽ]»v1iÒ$¥Þo¼!߯B!Ä àòå0æÌ™ÏÕ«áJZëÖ-èØñ-V®\Íñã§HLLâÖ-ó•Õçý÷ßÁÞÞŽõëÿä—_V)õjÖ¬J×®ÐhÔ,^ü;vìQòÊ•+Cñôô`ùò¬_ÿ§’W¬X ½zu£hÑÌåÑ£'±`ÁRbb.çé<–,ùVùûܹó|ýõ·¬Zõ£’¶{÷^vìØÍ¨QÃxÿýžYꧤ¤0yò ’“SèÞýý<íóâÅËŒý?"""x饚téò.:.GGGlmmQ©TÀ‘#Çùè£Y°`ÎÎÙϺdk›Ô=N©©iüý÷¿AgÍšÕ8pà0Õ«WQòî~}ôè ‚‚вÿ!%¿Q£úJÀ¶oßA3ƒË:ujbgg÷ØÿС£”(¬‡••¿¬ä.쯯7—.e½~>FllœòºFª8;;~ üüÌ‹™_¹r{¼¼<>É‹êÕ«3jÔ(¼¼¼òT~Ó¦Mìß¿Ÿk×®1vìX^{í5*Uª”k½;vàëëËĉ•´nݺf¹"ãüùóéÞ½{žŽE§Ó±dÉvîÜ©¤…††AñâÅIKKÃßߟ 6pìØ1¾þúk¾ûî;† ¾}û”zw—B!ž_+W®¡iÓ4oÞXI[¾üW¥7DXX83fLÂ××<®á£>¦iÓ†£]»×,~Íÿâ‹Iœ:uOOONŸ>ËŠ‹,ncbb±··gÍš ÁÁlbõêõ|üq/%­iÓxx¸=ðùœ:u†?þØÌˆƒ•´ þäìÙóŒ5,ÇziiéØÙÙaggÇ·ß.dÈþ÷R¼xEЦC‡¶+Àðác ½ç1Æ¡¡hÛ¶5ë×o&--jÕ*[ä/\ø#7oÆP£FU4¨ûXß÷ùó“œlÅÇ'мyc†ÃÖ­™Ý¾î~=iÒtJ—.a…‡_£K—wÙ¼yGŽ·ØæéÓçèßÿ£Ç~ÝŽ3‰š5«YôXŠŠºÎ{ïuȵî¹sç ·H†À¦M[qvv¢C‡¶üþû:J•*A«VÍž|R½zõ<—À`0ààà@ÕªUñôô|¬ûý÷ßç9Ñh4têÔ‰W_}Õâ|F €»»»ò4&7~ø!{öì‘oe!„â9×®ÝkÌ›÷ .SÒF†Zm¾­jÞ¼±|ÜkÕªu¬Xñ»Å u“&/g[¶jUó´·o'râÄiÞ~»«’wãÆÍ,­›5kD³fè\"#£øé§ßøè£ÎøùùÞàl&<>æÇ*7oÞÌò¤ãöíÛÄÄÄP¸pá\Ç[”-[–²eË2vìX^yå•Ë¥¤¤ÿ@'‡‡7nÜÈ6?** £ÑH¡Bæù‹­¬¬hÖ¬mÚ´QÊìÚµ‹©S§2xðàüGÊ7²Bñððpgðà~¨T™·Q}ú bñâyÄÆÆ¡Óé²üª¿gÏ¿œ=ÊìÙS•{‰¿Êq?‰‰IJ7Ò¥K(õþãà`ÙM'66ŽÄÄ$òt7nÜd̘ÉL›6^éúôŸ)SÆ––9“Rß¾ƒ2Ä|߀­­ö¾ÝœL&W¯Fàâ⌫«yüljj*:]..Y»Ni4j45IIÉ8::––ŽÁ`ÄÞÞƒÁ@ll\®ÝzÌ7Ø5›6m{ìïûìÙ_Ò¤Iæ=c@@!¦NŸ§º5kVÍó~þëÖõ$<̶ãã9ròÿ”.]š‹/òË/¿pýúu¶oßNëÖ­(R¤W®\á—_~QÊ{zzââ₵µ5Z­–É“'3kÖ,&Nœˆ««+~~~ÛóÍ7IIIáðáÃèõz&OžLýúõ•2ׯ_§hÑ¢¹k£F,Žå¿©Š…Bñ|Ûµë®]‹T¦Ž P‚…õë7ãáá®Ühûøxãè耛›ùže÷îs÷—#GŽñî»oâì숧§¿ÿž9ÑåËaÔ®]ƒJ•ÊRZ©àïï›åfrâÄé4¤gÏyë­7زe‡’æææJƒuqttäî˜D£Ñàêj>ŸíÛw‹§gæ åË—µxú‘’’JåÊõ0 '£GªÜ´þùçvJ”¾+ˆ²ÇÝÝààb4oÞ˜ ~$  11±*äG“& ¸};‘éÓçZŒ±¸~=šR¥ŠP©R‹v‹‰‰¥\¹2ý}¿~=Úâ ÈÉ“g7n 3fL²(wàÀá,]µÄŽ{ûÓ›»·ÝªUÓª3sæ7¼õV[êÕ« À±c'èÚµo–rÑÑ·8uê¬Å„€¸¹¹Ñ§OÖ®] Àøñ㳉4_bÚ´iÊS’¼0 ëc›×^{uëÖqþüy‚‚‚hÛ¶­’W·n]2228r䈒֩S'ÌQ~›6mpvv&88˜þýûMÅŠ-¶ß·o_‹+Ôj5ÇgÅŠÌŠ+¦ (¿÷ýýýyóÍ7•¶˜9s¦’7uêTöîÝ+ßÊB!Äs®uë¬_ÿ'W®„Ýu_ÓKyâÑ©ÓÛØÛÛÀ{ï½…7>>Þ¤¦¦)]l‚ƒ‹1}úDŠ Àßß·ßnǶm™ãR«W¯BíÚÕïÜÃô`íÚ J^vOZ·nN±byŸ½©sçw‰ˆ¸f‘ößìT÷zçöÊ ï¶m[³víÂÃ3ëj9þC£Ñ0nÜçT©’y/V©RyÒÓÓ9xðÈ]÷~­.@ƒu1œ9sŽB…üyýusOgg'zôèÌúõ›•z¥J§iÓ† ö1+V¬ºë~Í7Þxü³8…†^°xlllhÓÆ|ŒÝ»ÀÈ‘puuQf@ËM›6­XµêV¬È\Ǥpaÿ'€œ>}†½{÷+¯?ú¨‹ò÷Œó8zô8×®E‘––ÎСprr¤Y³†lݺƒ?ÿÜ®¼ÿÝOתUuë61rä4Å`úû±Š½b1—-NN>Ïä½|ùrüýýiР#GŽTfÁ*hâã#0™ ò--„B¼@–-[N—A—.ïJcäCƒšsîµ¢ÓeP¨_¶]•ÒÓÓ9|8sÀ¸ƒƒ=*˜Çn˜L&þý×X–,L‡]”§%gφ¤Œ8qâ4åË›{?~Êâ‰IåʰµÕf{|¶¶Îüþû* †ìE£Ñ„F£¦E‹&Yò^{ím.œKh¨y++¨U+s÷Ñ£',¦ˆ®ZµúNàr–„ó²AADGßRŽÿÂ…Kܼƒ««3›6m}:ƒÐ§:ðÙgŸ1lذ;Ñdwš4i"Ÿ!„Bnn®ddè¥!ò)•*ƒ–-ïslmý@z­V«<‘ºWß¾ƒéÕË< RTÔ  )y¥K—ÌRþ¿›w@ bò"-ív® Ügìììr<‡J•ÊçX/$¤´Åëÿº®^½žøøxªU«‚Á`Ä`0*ëéÝ÷óÓç‰<B!„x1èõ¡¼9rîùêgÏþž=>Èó”ÇyµlÙ 0w«kÚ´¯¼ÒüÁkkjµ\IH§KÆd2IC!„Bq—,]°ŒFééIÒ2B!„Bˆ,niSÐYeäZÎd4á™áˆÖdsÿD!„B!r¢·2°5í¯\Ë]üç"Z`9ÆZšP!„Bñ´H"„B!„xjlîžïW!„B!îǨ1湬N§ãÞxÃfÏîCÒŠB!„Bˆ< |9´y+{âD(7/&X -[5•VB!„BäÉ5õMHÍ[Ù5ªR¶HËD¯O‘VB!„Bä‰É&ï]° †tî7”ixoÞ¼Eb¢¬ÿ!„B!„È™*Ø1ÏeSRR¸};µZ­e2zôDNœ ÅÖVVAB!„Bduõêfü>Êä­ü±ã'¹q!šâÅ‹SªTeðFû´jýš´¬B!„ÂBJr _NÀùÝçs-Ÿ™@½bÕ(í_’  ètIYkkkBÊ–—ÖB!„BXˆÁÎÎ=oÀ‘#ÇqvqÂVkžËÝÃ;[[RÓÒˆµ‹ÅËÉ#Ëvl¤)…B!„y¥6ª(îW €ˆs×ðpvÇÞÞOOÜÜ\03ˆŠºN²> ­V!„B!ÄcJÔ4ŒÆ üü|IOO'%%­ÖÖ¢¬µ4—B!„âÑ5öiŽŽŽh4š,e[Ë ½º¾Ñ` #C—mžÉdD—žþLÓ ×£ÏÈ(0oþ×õÙP2 Ð1 !„Bˆ‚ËÚÚÿŒF½Eº§§×®Ea4ŸLÒ®uK¦ÍœûÐõÿù{7ã¿™mÞ¥‹éóQ×gÒ «_É·óf˜ ÀÇÇ—ªÕj0oÖ ù4!„Bˆ'ÎÎΓ)û‡/¿\‡ÔÔ4‹´Ç2äÏMhÖ¢•´~>Q¢d)Ξ9EDøU ‘B!„OŒ¯oaŽ?™cþ¥Ká”/_ñẾO•jÕù¨w?‹ôÕ¿­`ÀÀ¡YÊ>x€Ó&+¯_ª[Ÿž}úpåÒ%F}n®£Õjù ë‡J¹„øxúõꮼòéˆ<ßìÓØ¿o/•ªT¥hÑ V¯ú•¹ß/ÂÑѼZã¸Ñ#8zV)?aò4вñµ¸{zRNyÒ2xØçT¨T9Ûý,øþš4kA‘À¢9ËÍèhVüü#îîl\¿Î6lL·½=w–ñ_džW…Š•üéç|1âSZ½ú³g~@@@&L1ÿm0èò^¥žƒƒ#óæ/²ØwH¹òü¼|)W._’D!„Bú}<ˆ«Wøpþ¿œN×No³â÷?èÙ§?:]æã¡þ½>ä·u›¨÷rC†ìOøÕ0¾ùa1ŸÄŒÙß*eccc¸ÊðÁÓµGOüü ¡Ó鈋ÉrÞ®n$3uÒ>5Viƒë×ñëÏËyóíŽ-ZÌ¢mìû—Ù3¿¢ï€üúórÒÓÒ”üË—.2røÆMü’wß|i_gvuKL¼ÍG];ñí‚¥rõ !„Bˆ§Î×ןR¥r^==]÷ðÈ¡çè`8vô°òúì™ÓÞyjG¡ÂJÞW³æ±eóFnݺe‘7oþb&ÿ€™_Máü9Ëã(S¶,#ÇL07€Ÿ?111€… pëæM¥Ü…ó¡ÄÅe W¯†àèäDjj ³¿] ì·LH9T6ææ9sêcG~†ÛöìSêŸ;sš1#?ËrÞC?‰›»; 5¥{Ï>Rr²yÈääd‹¶9sú$&“ùo_?&NÍÑO|\,`d~w½ä¤$‹sB!„âiR©ÔèõÉ9æoذ™víÚ=\ò ’ùá»yhµ™SoEFD(ÈÃ3aòCÕûsÓŽ9„Ê:sÜ}zZZŽå‡}>JùûÆõ(*W©†—··E™ReBX¾ru¶õî\ÎqÛƒy³f µÍ\˜åjXEs?œ9eÙÇ®c§Îrå !„Bˆáwß|µ^bÀ Ëñý>Â×Ó§2ç»JZrr'SnÐ#¯E°rEKjש›e»éiiŒøt0/7lœí~‡~ÒwG:Ñ۶Цm{jÖ®Àœ™_)O#rÓ qjשÇÅó¡¼ñJ3z÷ÿ„¦Í[æZoÏî¬Yµ’6mÛ[¤víÜΦí{s7ªWš6ÈSbemÍ aŸß·Ì?{vãìâB¹»û!„BQàk×"ˆÉ:æ¡LHYoßæZD¸Ò…ÉÛÇ—®=zÒ¸nMü fȧ#ÐÝ¿1mæ%OkkËØÿMáØs×¢ÅËUò&M›ÉÚßWæz|¾~þØØ¨iÒ¬ 7  ˆyö¨qÔ¿7Ÿ @Ÿy©N}‹ºjuÖæprr&-5*U«S±Rš·|•¹³¦\œàâ%î{<5kÕ!ìÊeå\š4oÉ aŸ¡Vk3aŠ’îèìĨ±ÿãâ…óÇüV‹·/«×ÿiÑ6NÎάްEy­ÏÈàÒÅ x{ûâêæ&W¸B!„ÈW¬bc¯˜z÷Dɪ :ü¡6”žžÆœ¯§3pÈpiUÌ]°ÆŒ΂~ªû‰aå/ËéqÏLeB!„B<Ò}fl ûõ¢_ïNT®\€;öP«V=lmM9Ö[·Î<D§3÷>zl jµ¶|äî|!„Bˆ|ËZšàÉðõógĘñÒB!„B<©$1ñ6×"" lcœû›\•qÊ·¿þ²œofÍÄF­fó_{”2F£‘Í×3ubæ8¦-Z2hØç¨ÕjöïÛËðAæ©t»õèe±"EéÑ»/#?ÌÄ©3pss—«U!„Bä;:]:7þ™c¾µµêÁ:õ^¦c§ÎÊ©“&(ÁÀâó)TÜ"ø0èõDF\»ëÀtDEE)¯wþµ—êÔcÛž}ìÙµƒÿŘ “yÿíöl¿“y¹_Ï`àÐá„_½ÂÒE?(õRSSiÿZKÖoÙAÏîðåôY ú5ª[“í{ö1fÄpÞïÒMYˆ`ðÇ}™:c6#ÇN W¿éÝÃòiFôœ9}’Û ñìÚ±"E)YºŒ’ÿf‡Ž¼Ù¡#îZ› üj¿þ´L9N€% ç³lÉBÞ}¿3£†QòoÓªÉË´|å5‹mxyyóÍK”sB!„"¿ »@… esÌ×jm,¹p>”ýÿþCô븸¸pæÔIŽ>Hå*Õ¨T¹ Û·þILÌ-<îtIÊ‹àâ%éÙw@¶y¯·mÏWS&*¯]ÝÜ,Ö'ùòNÐùßÌÁÅ5s¾´´ÔËN½Ïvþs3ú;ÿÚFBB<»wþEõµ,û9wö´Åy9tÆÍšg)çääÌèqÙÿïÞ,y+~ZF‡wÞ•+[!„B<r @œððð  HÜ=<9vôˆEw j5j¡Vk˜ðÅH¾š5ï±ÔG}ú³uóFåubâmæ~=Þý?ɵnPp <½¼”×&O{¤c)[¾eËWàŸ=»ù|ô84Mžë:9;Sê®`¥Té2”¯X)Ïõ—/]LzzÝ{ö‘+U!„B¼ˆ¯¯•«V§fí—ðõóçâùPŠ ²(S±rN¿žÝ˜0å+œ]°¶Vaï`Oä5ó´¼±11ØÚjINJÂÁÑñ¾ûл£ÆNP^_‹ˆàðÁeÊë]Þcü¤©¤§§ãéi8ÜÜÜ©P©2>¾¾™Çï瀳‹+·”ãøbħ|·ðGâbc¹~=’ô´4"¯Eàáá‰ÖÖ6×LJJâvB<:‘×"prvÆÉÉ•ʆ àâT®ZM)kïà€««8;»(Ç’””ħƒ?¦mû Ö®þ””dÞïÒ•J%WªB!„x1€Sþž4mf¶e ¡W¿ÙøÇ::t|/ooz÷û„aÜ üèÐñ}þÞ½“f-_¡ÞË ,ê{xzR&¤“§Í¤ïGÝ”<??‹îRŸ«lW£Ñ°ø§_˜>û>éÛ“[73×é˜÷ÃbùtÄhÆŽúŒ% Pòþ÷åWÊßË–,dßÞpvvaØÀ þ9+UQòëÔ«µuÖY‹wïÜÎò%‹)Z,ˆaðFû·hûf ðAוãhШ1Ý>êZ­füäiJž£“# –üÄùóçîC1D„‡ÓïãAr… !„BˆçŠUlì@ïÞƒ(RÕb¬E~Ô¬ÁKlغ y÷„B!„xJbccدýzw¢rå ìØ±wìíír¬§ÕÚT. xÌ+¡ !„B!Äý<¶Äh4~5ì‰ðšÛäéÇ3vå²4‚B!„È?Èk~gÕ¯¿ä¹üæ <Ô~ìììžû7%9)‰åK±|é"ç›ì!"IDAT¢ïZT17;ÿÚvßi‡ï_w;Ë—.b÷ο²ÍÿyÙR6o\/Ÿ!„B‘?Ó¦0`ÐÐ<—Ÿü¿qÏM#.]´€˜˜[m{&“‰Ô”TVü´Œó¡çò\oÞì™ÜN¸ýPûÔéÒ‰Š¼Æ÷ßÌÉ6Èð|9qœ|b„B!ÄÓ @ŒF#&“)Kú¤ñcøtÄèlo¤F£òïÞº÷æß»¯ìòî-—SZNÇŸÝ6ï>ŽÿþþïXM&SŽçñ_úö­’Ÿås;ÿœ8:9Ñí£^9®’Óyd—Ÿ×zM›·äíwßÏùB±¶¦ïǃøzúTùÔ!„Bˆ§€õu£g·²¤_ »L``Q‹´ŒŒ –.úæ ë(ÿ†~Ò7®’œÄœ™_)y½º@DøUþÞ½Ó¢^Ç7_çÒÅ ´hT½^¯ì'55•ÖÍåzìWÃÂèÑù=‹í®_»€Ù3¿¢z…Ò´}µ9Ë–,¤yÃ:,_º½^Ϫ•¿0|ðÇôèÒI©7oöLRRR8uâ8ÍÖaç_[éÜñ-š7¬ÃÒEæi~ÓÓÓYøý7ûûlè@nFG?Òf0,¶ùz«¦„ž;«äïØ¾Õ"ÿÈ¡ƒ€y G—÷:XämÙ´áö]¸p®Ýy„B!„x4š»Ë‡= )[>Oeccn±iýlÙ¹WI;rè BCñññ%..ŽÂE”ü=»vðý7s3a2#‡eûž}J½‹Î3qÜh¾_”¹áéS'°¶VX´˜’¶eóF.]8oqÎ..¼óÞ|3{öêCÍÚu”¼Ù33WIñÅxê½ÜÞ=º°eç^ÞlÓŠ–¯¼À±£G˜7‘²ã€ÞréÂyÊU¨È–{éÚémFýŸÅ×£"Ù³k§Åù/Y8ŸõëVó~—î|?ov–6«Z½ÕjÔºo»ªT*‹mÆÇÅÑíýwømÝ&Nž8f‘ߨnM¶ïÙÇÌiSødȧTª\Õ"¯i‹Vò)B!„ù33aržËº¸¸R§~}ztyOI«Y»Ýzô Pá^o÷æCø¾þA­Q[ ŽŽŽ¸¹{X”st2¯ºþÖ;ï±|é"~ønž’7jÜÄ<íëÕ6¯gYý=/ìÿ×âü/]¼È{tÈrœvvö¹nÓ`0Ы{æS(Ng‘ßw@΋Nøb$nîîÊëè;O£„B!„È—HBBm楫¬ÄÇ3yÂX^iÝæ®ØT¼¼}rÝOÅJ•Ù¾õOåu||eË™W[¬Z½&«~ýƒÁ@zz:kW¯¢Jµê¹nóç— Ñjðó/¤¤yxzYM +UÎZwÙR|}ýñ+d®ëìì‚£““’_®|EŽ>Ä¥‹Øÿï^š¶hI@@Š[¬Ÿáï_g—<<ÿü½›«aW8|h?6jjÖz _??‹m.œÿ­EÝχâÃ^}”×UªVS°¤¤$‹ºµ^ª«ü}üØΞ>Môlßú'•«VÃÍ-ói‰ÑhdÌÈálÝõ¯|j„B!ÄCS öñë×ÿ‰‡—?µëÔ˱°Á` öKu)U&$ëMsZÏŸ§\ys `ggG± `6oüƒˆð«D„_%¸x Z¿ÞÖ|Ck0RùÎÍ1˜gŒrvq¡XP0õê7`å/Ë•zFƒ~Ÿ  I³Ü÷/Ý{ö¡F­ÚÜ÷/‡ÏõD+W­Æ‘C9}ò„²ÝC?ÃÁÑ“ÑD¡Â(Bý”îrå+pþü9Š—,‰Z£áÔÉãD„_åµ¶í)RVÙví:õضu3BÏQ·þËÔ~©.ŽŽ*À–Í”ýiµZJ–*ë±&''³êןñðô$==ÄÄDªV¯@ãf-øéÇÅÊ6‡ ƒƒ#å+TÄh4òaÏÞ¬[³JÉ=n"*•ŠjÕk²oï?œ=}JÉ«\¥vwžfíÚ±ó¡g ,Z”ˆð«”*‚««›rL?.^@ùò•¨T¥ª|j„B!^@©©©lÞ¸žšÕ+âçg~¨påÊUìííP«Õ9Ö³±±ÁÍ̓Á>ŽcG?•jùJkÞïÒ]®!„B!žv2{æWÄܺ•mÞ7³g*‹ >ˆßW®`Ôð¡,üþ‹ôÔÔT~_ù ·f©“¡Ó±yãz< ï B!„Ïkòç¦ 4ËaáºU+Wж}‹´ÿù›_–/à“¾=³ÔÙ°n ×£"iÞê´¶v,ü>sF§bAÁ ®^¹’¥ž—·^^Þœ>uBÞA!„B!žÇä­7^eÅê?²Íл3ç~g‘¦×ë9vä‡àôÉìÛû7×"Â-ÊDEEâìâBz/S:$„ÔT˵D†}>ŠoæÌ$!>>Ë>ßïÒýÿîåìéSò. !„BQ@äy]z:6Û¼Œ š{¦ÞJINfãúuÄÇÇ‘š’BôlÛ²9ÇñUªV§JUËõÊW¬D¡Â…)P„rå+f»Ýðð«øùÂF•5Nºqã:NÎÎØßYÉ[!„B‘ÿåù ÈÄ©3hT·&Û÷ìË’7èN«V­ÛX¤+Œ½í;¼óÀ·dÁ÷´{ómœ²ämX»†²åÊS´X¼‹B!„B4 o÷z3ÿÛ¹Ùæ >‚/'Ž·H+S¶ 7 w¿³Ôiظ)uë5Èv{GÂÆFMÙò²ä…]¹ÌÕ«W¨[¿¼ƒB!„B 4äÍ·;—m^ó–¯P¹JÕÚyPpñóJ–*CÑbA¸ººeÉóóó§ï€AxxzÊ;(„B!Äó€¨Õj¼¼¼³Í³¶¶Æ×Ïÿ±˜½½}Žã;4Z-Z­¼{B!„B0ÖkC:ŽŸ~\"-Z€-Y0_A!„BŒdħƒ)Q²TžËòÉ3?ù{¡O®LÿEžëŸ=}Š% ŸŸ›v//¦MþŸ|*„B!ÄóXÖ¹uë&W._¢Zšy®³oï?Ïüäï=†ñ“§f;åoNâââ8wöÌss1T­Vƒ?ÖüNBB<..®òéB!„Ï6Y»ú7üý Q­F-‹ôQÇ0îS²”мÆÞ¿÷(¯ŠR½ffÝK/pôð!<½¼©ß !iiilX·F)çèèH³–¯°cûV^nØ+++ ïÞIýr=þÛ·s €*Õª[#ÿþõðp|ýüx©n}‹¼ãÇŽp!4Ty]¥juŠe?ýï™Ó'qsóÀ×Ïï¾Çsë;ÿÚ¦¼öñõ¥N½—økÛJ”*Íþ;’³‹ MšµÀd2ñûÊJ=µFMë6m•×ë×­&=-]yݦm{T*Û·þI|\æ$ÍZ´²˜âØ×Ï–¯´fáüoùxÐ0ùt!„Bˆg€ôíÑ•–¯¶É€d'1ñ6ó¿‹»»Ç]Çyôú jשGäµp~^¶Dù¥ýÊ•K¤¤$Ó¢Õ«Ì™ù¶¶¶J=½AO||tNÇä cs @6¬[ù³gÐh4,[r’×#•üø¸8.œåçåK-ãÇŽ°ñu8::*iËNŸ¢[žÛOINfÂØQ899ñÎ{Ü÷X ³gNÃÓÓKI»rù"i©©4nÖ‚Aý{Óö͸¹¹põênßN mû˜L&¢"¯)õŒ&#‹~øŽÎÝz°tÑÄÇÅamÙ³nî×Óé÷É`Öü¾’Ë/¢V«•¼Y3¦1|äò)B!„ù3ùmÝfÜÜÝóT6%9™3§N±|åj%íÖÍ›èõ¸¸¸ñÎ{P,(€=»v°eóFZ´z•õëÖX,xxñÂy&ÿ‚·ÞyWI[¿n 666Ç„1£Ø½ó/‹ãð/TˆKfÏ®´iÛžšµë˜ƒ¡ çY·æw¥\ó–¯PµZ °\hñ|è9éÓà]Ôœ]”×Ç}Á}{úÙH ¡p@®GEÑùÝ·²´Ë€ChÒ¼{ÿÞͦí™O‡âããHLLÀÎÞžï¼G‰R¥8}òófÏ mûX[[ÓgÀ@‹À©Ûûïй[Ö¯[Ã×s¿ÇÛÇGÉ?yü`~úó~×îTªœ9Ur£º5%B!„ù7¹»ûTn¼}|éÙ·?ëfŽ ©V£&C? €ƒ££|<Œèë×QkÔiÃ>Åá#,Òþëªu¯ â%°·wÈu?o´{‹¹³fXœG‡w;ñ~çn¬üy9ÃFŒfôø‰T¬TE)ããëËÚMÛ²6¸ ÖÖÖLš:Ób›eÊ–eäóp­ÖV >îuîìzwלּÖôORîU®BEåï^Ý>°8统2 !„B‘ïåKP$z/7´H¯[¿{ví¤T™%--5½^϶»žd¬øéGVþòõéÿHs‹ØØ[XYYkqsŸWÿìÙE\lL®å®\¦aã¦ô½ë©Ã€Þrá¼yLHû·;¢R©XºðŽT8H¥ÊU©T¥*VVVJw¯{F"#¯Y´ÍÖ?7ñÃwóølÔ’“Ù±}+ 5ÉR·W÷ÎO‡~\¼ÀbLȽþX»šW_{€y?,¶xr¯ää$._ºHù •ä“!„B!ž}òé ´|µM–¤c§Î4ª[“nõÊL´2wÿYý[æÍ±‡‡:¾—ë~zôîKÿ^Ý•×Z[;>èú!Ÿ Îô/'Ѧݛ F¾þêKú’ë6Û¾ÙU¿þ²% (Z,ØâéÈÂùßòÿöîí5Î:ãøç™ó!“4I›n23M›´jS-Á®Ò› â? ŠÅ"îj‹¨XôB¡°7^xá–UðFd»®.]p¥«7…¨Åîë6MÒ¦94‰v™C'™Cf&ÏãE—§yš¤‹fZJó~]åwœäû0/ÏïpæË~;û_=è)=óì êÛqŸ ÃÐÉ?ÔŸÞ~Ëî»yK¢±¸†‡%IO<ù;ÍW*úËŸ?ЩO?‘×çÓŽ{ï»áï31>æøÖé±}ûíòßÿ[ûë IR0Òþ%IG^zÙ1®wë]öÏOzV8öºêµª]÷ð#J’öí\'>x_ï½sÜn{õõcê踶\+ŸËé_ß}£^<Ê77…‘ÍNX’tøð‹º«ï~9úÊŠ‡Ï©¹¹YÑX|IÛ¹³zïÝãzó­?Úu³…‚&''®ý“½®U±ÿ½¨žÞ­v[±XÔÜlAÓ©z½®óÃv›ÏçwÜ1²xìõóÜÈøØ¨J¥¢$©+S.›µÇNOMêÊ•¼Ý·»{‹}BTâòee2i»­+Skk›JÅ¢ …‚ãÄ«t*©@0¤È¢Ó¥–S*5>6j—›š"êÞ¼åjÒ°g·Nþã3MM]’$üõn»šhX–¥Ásgíq=½[•J&í±ç‡‡ì}6’´½ï^{SúØÅ•+e»mÛ¶»å[t£üï>®×Þ8¦ø¦n¾pÈf3:òÜ!=wø€víÚ)I:}ú µ··) ®8Î﨧g›ªÕ¹_ž€àÖxxÏnÇ2+àvM@b±˜ãÄØëy½>uvvÙ ˆ‡PÞ~ö-:í ¸Åã[ÔÔ´òÑÑ G™ä6´ÚMúÀ­’HL«»;ºbûìlÎQv2¿ÖÜܬ<žå߀ô÷ŸQ$ÒD 1LÓÔÔÔ„\.·£>Ÿ¿¢h´Ó>‰@CÔë *—çu™LVåryI_«R­Î«R™—Ëuu‹y2™R6›W  Ðx™ÌŒŠÅ¢,Ë’aZ·®yÙ~ŽS°,YÊå²D€C±X¼a»e™ªV4==®üIñxôÿ' ÿüô  ]Kœýá?’8ê:::‰Dì²×ÒüöZÂáqÞüaß„>>~I33¢ `E}}÷(I’ …Y55E–$׳,K–µàL@àfc:€[Æ~Wrþüˆ’É4°¢]»v.¹ÝüW% ‰DJÁ``ÉY½†aÈ0 uuÅ%*òÚ¸1*‰•[À Z­*N(íV"1¥bqN¦i.é×ÑÑ©p¸iUŸåØ-  …ìr(V0Òúõíª×çõÑG×Þ½{‰T¯WxRÀàÔ©ÏõÐCª¹9¤`0.·; ééKªÕêªÕªv¿––y<™f½1 ÈâÄ#ð«½}ƒL³ªz}ž§¬ E£]*—+ªTªÊdÒ²¬Æ¬€r$ †áR<¾Y.—)¯×+Ó¬}` 2Íùý^ƒ!y½nU« ™×q V,¶Y–U—Çã–e™DXó‰HMÁ _©TBéôLc‰‰‹úúëo53“Q©T&ÚÀ—L¦”J¥uùrB6¬_õ|Ž%Xn·KÑh§&'§ÕÚÚ¢R©¬;¶u`ÉåòÊåòš™É¨­­U±XWCæ]ö"––f™¦¥Z­®¡¡ ç kDÿåry•Ëeµ··É0Œ†Ííxâóùå÷_»ÄïØ»ÝOŸþJ¡PX^¯WC¹À“î.—[^¯O##c*• Ú´i“Ün—|>¿£ŸÛíYõgÙì„%IÃÃÔÛ{·Âá0OÀ²jµÒª¬²¸Ù\„À­ò3Ñ£ÌlôÆ—IEND®B`‚snd-16.1/pix/wavo.png0000644000076400007640000044430311147553271012633 0ustar bilbil‰PNG  IHDR„üa;"bKGDÿÿÿ ½§“ pHYs  šœtIMEÖ 6Ù¼§Ÿ IDATxÚì½yœG}çÿ­êó¹ïyæ¾4§FÒŒuË’mÙòC !æÀÄk–È’Ø%ËfaCB¬7˜6`cc˶ŒɲŽÑ1ÒÌhî™gžgžûè»»ªöGžUŒ-KX²MÒï×óšWO=õtûÛUý©úVu55FáâÉd3 àââââââ…b! ¼ðKH*Z)“òEýòѽ¾ëŽwHÁõ¾‹‹‹‹‹ OØC µuûŽ/Þ±÷K{Ž,tné{dì·ÿþ·»¶uýr–¸¸¸\<â¹FpÀÉ8™—ÍÀFþ±mû•öùŠaê&¾ÉË`ƹŸñýãîepq9?Ïýós¦b65¿çkï‰wÆë‰-ëZFnyá»/ägóGï?ºùöÍÉÞäÙtÔÿþo¿¿wÿêžþúÓÍëšßþ¹·{Bžÿû „zvõô^ÕûôןΞÉN웸æîkvýî®Ó{OçgóOýéëÞþ¹·—ŠcŽýÒ–¸¸¸\1.vi5ñ|aê…ìÂK„}f~fÓ–Mî•pq9w~ãÎôxú;w}G¯ê¼ÿƒõÄîíÝÇ~|ìÜlÝ;ºÏVl°á-οOÌãÎ-Ç<þJ~÷àÔ³Sɾd°!øK[ââârÔŒÚ|q~z~úRiâ+öŒ ¤:•Jü7ŸXG̽..çg깩òRùŽÿu‡'èù?¿ÿ^)Û‰‡NÔ7LÕ|æÏd&2çÙ'±É¹]Þ_dë[ÿàÁ?Øõþ]í›Úà¹o=7{pöb-qqq¹pRùTêd*Ú½ì=ãegyÍ®5®Ó]\.OÐs߇ïëÞÑíXÎmŸ¸­’®œûm°1xåï\ùôן^0¥•µïüûïüâ;ûϾ íæOÜüÀŸ>ð­÷K-ª·áöc?>†*ÌN>ròæOÜܲ®eí~ú¹Ÿ2Ê®xÛÉþäÍŸ¸yôÑ•3+éSéßùæïÀýŸ¼ÿª»®Zw˺‹²ÄÅÅåB°™ 軦ïî£óö|}aëùCó;Ûv.'—_õ1©ñûÇo{çmÖ„{U\\~%¯0ÆÀ÷Û†m*¦?æwLÇP ÌïXŽQ3¼a¯VÖä€Ì‹¼RPä€,Ègß¼Æ(S „üq¿©˜¶aËAY¯èÞ°—8S5-ÍÉ+‰>‘ØD+kÀ œ7ì€Z®&zDÉ/]”%«¸¸¸œ[Ñ$꼪3G^eÑñ'ÆoÛqÛ„gz¡÷¾Þ÷o¾fà‹úú¯í§]zdi×Ûw-Ø 0óüÌÜÁ9÷Ñ&—K?î_Ý=¢è@ð‚GAê²HêyV7ζ‘1:7EòK’_:7›ä“$Ÿ´š¸—ìaõß‹µÄÅÅå’pÎlüžß]ôÃÅÅÅÅÅå †Ïd3î}Ôa›ðmÜø÷O9„œÿg>Á[š,œz~Ìõ ‹‹‹‹Ë¿cek»—žY˜^˜9NÇ´©êœúñ«+cS¬)7–;=vËáy£ Uj´J^‰çýð¸Þwqqqqq¹,êΘ ~_¡ (9åáæ @ g'pMÎo'ÃñÖ¾¦¦F×_......—œÃ‡GK–"êg'pÏä‹ù—™ÀÅó|,uýåââââârÉÑ4í+v'p¹¸¸¸¸¸¼Á¸bìâââââ⊱‹‹‹‹‹‹+Æ.......®»¸¸¸¸¸¸b|aLOÏnÚtÍîÝ·®~²Ù³ku¾ë]¿ûÙÏ~áÜÌwÞùŸwì¸þÞ{¿÷ڭܱã†súÔSϾ$Ã'>ñétzå•,¡”V«Õ‹=èûßÿ!Ç9»øÉñãc_øÂßÖ·ÿõ_ؽûÖZM¹×CUÕ»ï¾gõLËåÊy2ëºnšÖK?ó™Ï¿ûÝÿÉ-Ù....Å×¾ö­gž9pŽ„}à•r.-¥vï¾uãÆ«WuçµsqkS›¦µmÛ¦¯|åo~ñ«ù—|IÊ?ÿóßÿû?º$¶J’¸oßCçɰ¼œqû•,)ŠüàGÿõ_ÿù¢º°°ÀêÛ†a¬6;n¿ým·ßþ¶ËT>ûÙÿñÞ÷¾kçÎmõwï¾õ<'þÕ¯þSwwÇm·ÝznâŸýÙ'ÜJåâââr± EUUWÿŸ_|¥œ­­-ûö=ôž÷ܽª;¯·¿÷Þû½mÙ²ñ½ï½ã¼ZnþÑ}ª¾=8Ø÷ÁþÞk9è3Ïì¿ï¾ûàÊ+·žÇ’ûî»ïÞ'GGÿÁ|Üëõ|þóqûÿЇþÓ—¿üµ{îù <ðÀCuÍ[\Lýõ_ >ÿù¿ðz=/±ÞûÞ;¶lÙøüó‡`Û¶ÍõÄ/}é«þð~é3ýò—¿vóÍ×éK_€Îζ~ôàcûÔ‡B¡ÀÞ½O]sÍÎßüÍÛV-ihˆêS‰OêÛŸúÔÇâ÷Ýwÿ¦MÃõ®úäÒ^—|âŸÖ4“ò'}Ù<¥Rù'?yDøçž;ï|çÛwíÚqyÅøG?úé©Spë­7}ìcÿ=ñê«w&ñï|ç¾ó‹ñÝwßó‘|¨¾}âÄØ?þã·÷wß{!œœÚ½ûVèîîúæ7¿ 33s?üáOîºëNØ¿ÿàc=ñ¹Ï}êe-Ùµk{ccÃüüâ]wÝÉqÜ…ŸéÛÞvëîÝ·ÖÅø¹çžÿÜçþ âñØ]wÝyÏ=lšf]ŒÏµ¾úÕo¶µµœ>= [¶lÔuÃçóÞÿO^‹?ðÀC‡~ä#¿ÓÓ³ÿóþÝþáïßyçÿ‡jii¾öÚ«âñè‹"Ú×]wþçÿü‘U1þÑ~Z.WVÍûÃ?ü/÷Þûõ§žzú«_ýæ—¾ôß@Uµ{îùã/~ñ¿{uNŸž¸÷Þïýöoÿ–[]\\þãð±ýÙý¯gC¿u¾çž?~ç;ßáóy •Jö³_ø“?ù£_ü¡¢(ÿø§þâ/>Y¿Ù~ë[÷677uww^F1¾í¶_ûÅ0u[[ËjD÷Ÿ‚ÁÀj¼”ã8G¾ÀýBåÿ«Ë²„1Æ×ö³ÇWÃÔ/k BˆçyEQEùò—¿öWõ© <.Çq!AÐ‹í ªi:!Žªj^¯G’$ŒñW¬_=/Y–xžçyÞ4ÍÏ~ö W]µã?øñ…Ç$I´,kõdWKÀ‡>ô±/|á¯À4MI뉢(ض£(êO~òpssÓ5×ì´mÛ4-Bˆ¢¨çZ²ºÃóXòGô§õP<ìÛ÷ô±c'\1vqqùŽÇ#ßyç»B¡`Œ¼^ïª8Ž­ªša˜²,Àc=ñƒü¸Þ±®+Ôec¿ß·nÝÚ_LÿêWÿqïÞ}pÇïû‡øRKK|ô£º¸¸‡ýîw¿ ÷ßïí·Ÿ$Þ¸qä3Ÿùä·±±áŽ;Þ·úïù/Ù¹sû¯ýÚõÄ›nÚó±}X–=¯dI<ûЇîºãŽ÷ùýþº%Èöí›ßñŽ_¯ûfgç?üáOÀ>pÏ[ßzËÝw¿o` wÕøèGÿàÚk¯z÷»ë‹_üÊŸÿù'þöoÿá›ßü» <â§?ýÇûاþÇÿ8ûÕÿ¾ñÁþ^ý}}½ó7Ÿ­'þþïßõWõß¿õ­{ßúÖ[Þõ®ß€Ç{ò+_ùF(¼ãŽ÷kɪyuKÖ­[[º€ ›7Àç?ÿ¿ÜÕqqqqùwÀš5]‰Düœûÿø—ùÇ;îx¿¢(ÐÖÖú÷ÿ7N¯Ü}÷‡ë}˜ë¯ß]ŸZtà ×-/§ë7Û~ð÷z/êèhÔ·çϾBñÐüv2¼¡síÀ@Ÿ{aÞ<\ým<òƒú˜±‹‹‹‹Ë›ÅÅ¥ Ÿ!ôÀš<wûϾBñù™¹ƒsûœ±É~ažÇqçκäضM}I"ÆHÅËwPÇqVWü8—Õ.òå€RjY/óÔÏsnYwqqqyýo¿¢(\HÀ!ôuðâ~üž÷Ü]©¼t)«o¼î£ýÐåóÑ_þå_?ÿüá—$vt´}ík_º|½ï¾~ûÛß}¹ͽ«ã¸—œ£Gò“ŸùÅôÏþÏÝn±‹‹‹Ëåc||òÿðeÆæ>ýé?>w)‹W¢µµå‡#_^ÎÝ0µ‹‹‹‹‹ËëÆË†©ÝE¸¸¸¸¸¸¼Á¸bìâââââ⊱‹‹‹‹‹Ël^fZP¹\yðÁG\׸¸¸¸¸¸\rJ¥Š7x1E1“ÉRJ]¹¸¸¸¸¸\rB¡ 7ОOŒ£±Èú+]g¹¸¸¸¸¸\& Î9ÇÏMqÇŒ]\\\\\Þ`\1vqqqqqqÅØÅÅÅÅÅå?6ç[dc^dÓTj5%Î ôRê¼öCrŘýJx'©üðG‡BzM`«/Rô<²_Æ7t$¯ßÚ.pn›æU¨VõçÎ „ŽÎ2ÆÇq Ї$´e¤­·+î:êUqú·_~a„² Q–‚H2ÚÞ•¸zS»ë¥ 䟾ól)_E·ß¾í»ßÝÀdŸc„0nZÓÔÝÝГp½t!<ðàѵ}Mªjœ8±”ËUù#~Œ1æÐæ]ƒÃ]Q×KŽƒC¿Œ3Ç,LLdkÔ´9J€Ï0~å=¾*Á¯„ËÚãOžŒÇ¼ûÎUÕç“÷ìêéIŽ/?ñÔ8AŒ÷ùÄ›FšÜrvJ}ßþ)ì8?{ìdÐ+¤RE„Pkk„ç¹B¡ÆfW¢É¨í‘‚qSHrÝu*Uý;ß;xz| !„0Ò-ñéºm;!m,/ª'&Ó7^Õ×ßvÝõJX6yîùéŸ?sF3¬áþÆ›:¿ü•ŸÙ¦µk×ÀSOOèºÍ |ÉrÒE…P2Ò×Àaä:í•Ð4ë{?|¡·'y|l±­|aÚ±@uõ6Ë/ò,ä—´Ö-“¿tÏØdfò È(ÚИ‚"ÉfI0Ƈž|ò™Wú¡$‰€ÿÓׯòù¼o~§ÔóôtV7lG|ú¹3˜Ã{ö¬KgÊÓ3+‹‹…B¡ð‰+¹š(‹jY­)æJÙH†åËj’ªÛSK¥zç¾½Áï÷¿%l%_›Èø<¿„ã¹M›»‰¥08ØŒ1Ò4ëég'+ùJ­¬š-oéŽ4ÅËje“S³„pnMÂ>ñÍïFJÙÑÓé£Gç2y%‘Cž…ÅâÖ­=†ag³Õ+®èœšÊ,¥+¼Ä;Ok‘H !pÙ_öUS­Ùtc¼®;ö«rË›^,å Ši:þ gd¸mav寿ðÐõ{Öy$î¹çΔ‹ BȶìR¦ÄóüþcKÉD¤5vyKÈlªRQL„ÇáŽÿ«i;1±2>±=6‹… +Õ¡® ,_²~Y³Ÿ<¼Ôõžš+Z†E Å”PâC·,Ë90]]ÛñK”ß©êÎ3'WêßÕ¾ B!„1殫-ràÐ\a¹°ecg4ì1TCöˆ…‚²m{O:]Ùºu¢étyǶn,‰Š¥§k>%›Ê®¯ÞuiÞÒë6“U– z2îø¥3óÅýÇRÀ <£Œ!Ñ »Ê‰%CŠÈæ›Y_kcO–åžžÞTjQ×µ\.îWÇ%“M°¼œ~Só\N]¨$Bžk‡›ƒÁ0 ¥”RÊ(«0‡û»â *]99‘‘$Þr¨Ï'_wÝÐÏ~vbd¸}ttÎãy“eQâqnfÀRly¥†üØ©o|ëéøÆ¾éÙÜk ^åÔÃÓÅéµ§-âõWô7¨º¥êc@ÉYS)¥”Pݦe]ªš^Æ^×&´é°Š sYU3³uØ‹Q,†^„2FFÇWúû›ÚÛc^¯D\¹cÍÞÇO­mɬTyžÛ½{pëÖ5ïø-ûúÂüä’I<ª!?öÌ™ïÞøÁŸŽ¾æ[3µ(RL²ÓBáÖdà¦]×llc”B(e¶ã¶=“7tâ§ðL"+iäè\åø\él[²úßãLŒ8Û½}Íübql"í‘Ë&[6w½pxÎë•Ʀaòž=CšfNžŒûð¶­ë1öƒ}íŸ2MûµC˜d¥f† U3ñªº]®™‹™êÙÒH(£Ìqˆé8–m/Wá(B¯w¬µfã)U3ÉpW´³1píÍ{㌭Úõ– âÐ`_ã»Þ¶æN”xÂ@øk®xôÑ‘ˆƒÞhÔG)ÛÜoð#,Ü;þߨ÷úy¹¢¿F#ÍUFkªÍ–²J_{!ðŠƒ±úˆJ %6±,;SsÒ5 Øÿú—IÝ"‡æ*eÝfÀh=6ýbd“˜ÃÇÏd1‡y‘7m"ðÇs‚ÈÛ„F">‡ÐHÄwå•}¯T«é?2Âær¹V£¾Ãã¹úγ/šyíFž\¬h&‰øEÇ¡Æ2õ@:¬ÞÒëž´m§¬³¢.+Ö›w‚÷?ý@…VÊ´ •åÊ€oM2tvüŒ ¦ðÖBe¡T+Ùºmë¶^ÑW&W¶ôŒ„¤à#ì ‡C--­==}KK 33³†aƒ¾¾~]×®¿þÆ3g&÷ïÎq„ðÀÀ Æ´>•úõ™M==-è:ÿMT¤bà…¢ÙgV”ùtE·ˆi‘€G”EÞ°œú³KŽí(ºcæ˜æúµ-Ó Åž˜™^Ù²¹{q¹ÔÜ•e¡VÓ¯¸¢óàÁ™Ý× ØJ• ¾ŽŽfÝ"§'R™ler¶ðôÏÇGFÚ%ñ¢ÃUÏìî¤Ìq²”U–sŠiÚ¹¢¶s¤e>]¥„2Æ8ž€X(ÀYaÎ+`½^M¿šiµXÕUÓ9ì±$ðƒaÝ$¦MÎÆ«ÕtYý~¹§#*ŠüÂ|~ÇöžÑKáG÷žìîJ4&C‡ÏY¶óØc'ß÷;WŸ˜ò…ü†bMÑÙT~n.·ÿÀt}¨ sHø‹ô$­,•«¦Šº(`¯ÙØŠzþÄr*W“DÞv(H^‰‚˜?ØKÁ‹™þº…¬Ë:9™6ÍrlÇ+ ¦å¯Ì[6a/(¥Ä!ùŠñ‹7_?tf¶ÐÑyôñSýMs3Ù@ÐÛßß´mkÏÔtvp ¹³#>?±$ðâæC‘DøÄ™Å‡:úØc GxŸï¢5“œX6,ÃÞÐúÄ£“¹BI øDc¿,覃0cÑ#2ã¢þ  ,§öºZ5‹ìŸ­"@Ú‚ó+5¿ÄŸ.¬”tÊX½j×yëÎn„`ÿÑŵ½‰bQÕL§½%ª©F¾¬í¹vm" IDAT6WM&ÃшïÁ‡F7mêŠF|OýüôömÃ-­LkÆC³§Sm­QY.v`ƒKÕÂ>± ‘ ¡ùLÍ°ÉæäBºªh–WæYÎÙ^² ð’,!„ÚcÍ”Q€úçõ€P´o<¯ÚÔ6m Ì+ ‡¼‡0²rVíÊq8ì—7¯oYÛ߸œ«Ù–“/é¿ý[ÛÆ'2¯èPóþ¯[ךËVï¸cÇcYœÍô¬ïÙ<ì:”2ŒÈ¯ŒsXàˆÐä‹®mìMJ·lß³i͆-=#=M]Ä"<²wóæÍ>øàÂÂR6›×4Ͷ͛7›¦¹¸¸0<<<<<Ü××ß××ßÖÖ.Iòë,Æ_ýj¨±‘œ+ÆyƧËJcˆgt„m¡€,ŒÍ—â!y¨#RÖ,Ó&˜Ã~¯HêóŠ“‹%!@xî†kkª¹’«]1Ò~øèÂ5W÷¦39µÒÔž›ÙÐÉa©¡!ÚÜÞŒªUU7¬}OÎd*amÍáW+a|ÉË:ŽûØbшù¹œâ$}Q¶¬Ž¯¬íŽuµ„JƒÚÓ^HWe¢Wxk ‡â*f*µçòjH¦JUEýW3 »¥-j.ôû~Í&[GZu›ÄÁ#ÇFÎq<—lžW}ã ë³%­VÑ ›943´¶åUmD\”çƒg©]Ì*  ¨!(¶'ƒaÊØØTžÃ¨Z3)¡”R„‘m;¢$Fü>@Èrˆjf!¿x[6 xŠ">Á)kvÕ`q¹jرg}Wd¹¨u5ÚÂÑœ)juO–Ê:渲j ˜ 4u·Ežã®1E|©åòµ»gfsó …íÛ{öíïê ?öèÑ ëû½<jlŽ6&ý?ùÉá¹T9™Ä£F6¨—Ãh2«2PCHÖM§ XÍqŸi9™‚:6¯*æš¶p¶ ‡‡p"1j ‡1Æ„²ùBMµÁ'Âe Ûèç0OH²Ëºíؤ#áÉ*ù²1½\•nS¢)ê]Ì*uQœ^,êš¹q¨et|%“© ’òËÓÙHÈÛÑ;5ž¾öš••j.W:“io¶5ú›=²§»»µl8˜ÃmÍÁBÕ8uréÈѹ†D0xõi"]t¨ˆ±”IÅpC’cÙ<‡«ª%ñx 3¦¶ª[†é(šÍÃ<'{%ðBS8Ì@ÔmTÓ•×y–õkã¸?‘ FBRÜöáÍÍ‘†ÖX“Wò(ŠúÈ#{ׯ_·wïÞTjÙ0 Ó´xžgŒmٲŲ¬ÅÅ…;¯ŠÅb’$iš±ÿs}}ýo SE«¶èùd/–4ÛRUïo"ŒÎ¤*CÄŸ˜-vDkší‘„ªjg J¡jl^Û‹xuÓéëN|ÿÁc¢À­[ÛüäÏ'n¾aˆ8ìáGO4$шoÛÖîcG& ͉'b„Q¸ÖöF,¬VÕšî5gß¾Óíq^ä ú2a6ÂPAe IqIbÄ‹—+úš„—!\¬ê&àk†›rUCÑíÁÎX¦ ê¦sõH«aØ™BM'ŽÃhg"!ñ<‡ñ|¡²T2)¥~£Ëpÿ3ˆTÔeذì°UL*"vj©ÒÕä8¼©7~f¹6µTIå5Yâ=ïõˆËy•*yÄt¦¼gWo$ìÛ÷ôÄõׯ¢þÇëím$áÊmkRËÊ`û¶îÓcs™L¥©¹2&ù=R0˜loôFÂù²–ÎT³µxÌ/{ExÑ“õ1lBQIÀ1I ¶;á#²€Ó¥ªEYÂËGüRcÌWÑlBH©fu6…ŽŽ¯ll,”TÇšjÚÀÇá˜ßRåZA12Ç]G"ŽóÉbp©T#Wuk¨-ôŠ<ÏeJzª ¦C)»yk{g2ÐÝ\)éUÍÎUtµfli›ÉŸ<¹o]ºåºÁ‰™\G{Œ1”/*»®ì›<“ÉdÊ#:øÑÁξö@8‹…{‡º¼¡P²%ˆ‡‰ä9ybޢИ لل!!° # S†Š:/K è¥T›ÍUÊuĥ咺¦)犚åPÌXWKH5œk6¶ tÅ3UU1Û¡”ò¢ pœ$”!‡âñL1ìå1Fø2¸’„:“-+&íˆJ©|Mø‡›[©mlÐLg.SSt{MsP·ˆåP@ Yä-W÷öw'æÓÕ£ã™Æ¸¿)ôû¥éÙÜÕ;{——K§'ÒÛ¶t?ôÐè-7oØ÷Ôé íŠ9žS-âú‘ìiîn.k³K•g÷Ÿî° ã0¼¤ XcÀ©6_Ô¥  ˜h¦ÞÂ<‡ÓùZÕp’¡[qÇãë›WŠZ$ o_ßÜ– ,­T•šî8$ G)ULËt [£ó¹JCP¼«‘§Ø^QO§³”!Ótj†ÝÝl{ÖwEe‘?9W\Ϋ> K¼,ñ6aªnk¦, ƒ=‰ÁÞdj¹|ÕŽ@~þù©›n\¯iö“Ožòøä¡µ­k×6—%‡Ã~W¶%£¡†X¬)15»Rª§§V†Ö¶P†lÂxî¬+u›B‘ÃdÅöà=çáíSé²Gäý’”¹Ù¬ÚÒàkKøG§òÙ¢¦év8(7Ç}ºa+ªA€™„xe)ˆ‚à6­.Wœ°Ì¿Ä£óöü¬= ó‡æßÖpãúöÁg`‰¢èÓõR±Xšž^ܾ}3!Vý«tzåž{þxË–Ííím/9ÞÐÐú••̳Ï>}×]w{½r¡y衟% ïxÇíç ÄxžrÜë1ò1<Ü>2bþó?¯Ôc¿ªÅQ<¯婜Úöƽ¬¬ÛŠîxTÑlÀ!ÐL ˆPÑlC·€ÁR^U+ʆþÆ•LùšíÝsKå¥ÅüÎmk¦ŠK ù‘õmGN,ÝvËúg8RGW¯êð©R‰h¦‰€aÛõ@•EHSHŒû„`¥ê8Là0{PcPV/ȼÃc¶T¬j–9bٔљ¬àèPg4SÒ3+Õh؃1š˜Í'¢>@å5§)žØ<ÐëÅcóó†m/g käx@j¸¤Ï@S†K¶‰UÐ@æ©¢×ü²`Zަ[@¸3©rOS°R3 ’1(T S7CY@ öø\¡§% Œ•*Ú•›:OŒ¥ZšÃµª®¨æ®=GŽÎWªZG[,MZœ/[­"˜aY@³Bâ~!8Œ`©bË‚šÂá€,"¦;ĬœOB™JMæ‰a:ªª;”yDŽØDyE³ˆC,›Dƒ2d‹ÚøBQòHñXxko4K¥ªºN(MÊt¨=t‰¥ œÐ|jy1à좢 rlqç¶îÓãiÛ!@5èÚëáŒé¶m:¥ÔtœúªMHW\ögRà8X®’¨?ìá‰I 9’xV¨®,ÍWÈ—ka?¶#–­j–À¡bIÛ2Ô4¹PªTõÅlm¨;^Ó¬Ùt­¡91ØÙeÓqlÇ1g"µÜ–FÚƒ—v-ÞªÁtôˆ’,sÙ9B¥Ô¶mIàlÛÑ Û#òŒ2ÓvbA™RF)ËWtêŒQ,ä)•Õñ¹â½‰ªb¦³m¤íÌL®PT·oê<ðÂ̦‘ŽcÇæ“É%4“Qo¾õÚ¹|E5MÓqLÛF9„Ø„¡Ô¡t0驯¢ZT䨚¨1v( ÉLâ C¾Ã³KQ/òI|¶P%ÊZ©¬­ëŽÅ‚²®[UÕr"‰Ülª²”Sx7D6twv$¥ÓÙ,¥t1îoò7Ǽñ²¥X·:ÍÖàœøø‚½3ÏÏÌœ;_ÏcŽãDÇ1tÝ(•ª­­ÍŒ ²×{Æ»víÚ¸qSssËêgy9‰DêcÆ›6m^ו3g¦}>ßÚµCoTϘ2HW‘Ix(û$Þ´ ݆ˆJš%ñ˜!NÀ`1„9Œrøecd8Ô¶)C¨«)ØÙr(6MgkÍ.׬l¾z6¬k9||qd]뱋>¯ä÷‰ssù†„tøØR$®×ÏúT&‡›ðP3HQ%y•„<\[Dˆx±jQ›zc2o{žçd(8<ÇQJ0,Jí1y*£xEN5l¿Gä0’%>ö–*ºm“æ¨glr9•-0 ¼ÀÆTØ_©æ*F*]nŒz…K4jW³¼ª&õˆ’ÌƒåØ²À  qÏA"( ‘hŽÕ§ÞÔ+*cŒPšYȺYUÍ*áÊ:+¨Är¨$ b^Ê!Ç¢Hµ°(È<‡<l3 ˜0¢À½-!Å"2ÏaŒ ›¬ë޵'|gf2sé\2&,ÇÁÏ¦Š…²Š ]ºåº!f8@戼(ñ¬)$¨6£”É"”ùcs%Ià€fÑî¦0ÐL²¦9ÔÛYÓa;„–Sà1£l9¯"Ɔš}zQ¶a}Û±±Ô5»ú«5}ôØìÊr®©¹‰è¶ øZáD!äPjV( !„²Š®ØU ›J<„± Ç‹d;ŽÌéDŸ,pxŽ£”òa3@máSK宦`YµÚÃ} ŪúZƒ³ 9BQKCË«*Ttgbz¥P1üÁw)žZ®˜ˆ‹zaI@šnƒ(p„Ù²Àa„9Ä:ü5Ñ8¤y,ñœjB4Ôëmý’bÃs™šm“JMø¤uƒÍÎo¹¢ƒçññ“KJU÷û¤«vö¼°Ü s"oB!ŒÕ )¥´¤“¼bç;¯:ªK:µ óŠ¢EÀrhS$˜³PT£^ˆ§`I<Â#‹²Ž†˜ÏÔD×`¶CÕêl ŽOe ¥ŠYk,Êc%U­ÎJ¦ÜÕ¼„J<™5[Â"ƲGW*%Ýæ2îˆKŠÅº|Íá8 E~€j8”1‡²3Ç¡#˜±îö˜f‘ÉÉL8èj~ò盯è8|d®£#Î.”õëZ&ÎÌGâQÓ¡„R›Òzƒ†Ô7cŒåU§ ’œâÈ<æ0¦Œé6 yxÆ(ñ|Xä%k°È!Õ´8Ž3Öߌ¤JͰl‚„D#„‡ºbÉÇȉ3Ë€Ö{ ËåJª¨—jf6[mMÞÀžñk `šÆ‘#‡êÛÙlîèÑcð&c±‚óŠõñaÙä…hÜï«T<©uÚàçg²J£Ï°©i9-1ï‘é¬m á¨fWjóé*ƈX0ÖÝ^·&”jÆœ¼j[×rºŒ0ŠÆüS³ù-›»÷î;µçšAÙ9ÕÁÕ+ê¹Á«za9Å1\ ây’-~Iô! eµ8žÃï[©*Í®¦ƒmáåŠ5Ü›ÀM,W×vÇOͯl4-2µXºnK[&¯:zòªÍ]xDQà^sh:WI¯TßrM¯GâEá5I2e˜0,qZ@‹ò¶C2ocó‹<Ç™6‹zÑLÞ%”*6l ŸVûÛ»Ö5ƒ3©Êìb‘Q:Øß0ÔòÌèR{c°·3þíïêkèëL84»kûš‡>ÞÞ;xjíæºÓê5ˆÄš¢„R„Ðj‡Òв(È¢àUKö®T ÛYô˼b²†Oךƒ“‹åö†@¹jœš) tGONfàÆÝŒ±¹¥i$%¯ìPÊñÜBAOô½ÏL½ã†Iäå×°–Mè©ÅJ_«H ¤™&ù¸1&Εj ŸQâébÉêiÎå C½-Á™¬Æs¨¯5<•©¥²õµØ°m:PÔ*q“Á©™l¡¢ïÜÜ ž>0uËžµ–M~þì™xÔÛ÷hÅÅNd®ègØÙg¦c, 4ZLÝŸõ¶#cŒÃ`;&ʃV%¼Oä˪õ aCàÒUäQwƒïøl±+Ð këÚÆR͸ÿ‰ÉMƒ¯sèTzÝšÄÉéY ¬¿³]ä¸z§‡04“®NL­¼ãúÄk{(ŸP–Wì©•…=ë5Û®šõr6óvÄa[5ƒ–5»¸¢ú<_Ô7uE– ÚlNݼ&jXŽÍ‹ x3ÛYÛ“yAগJ<9~Ëuƒ€à'?=ÖÙÝ ‹|{Kxôø¢ÏÇÅ<:¼ºnbŒ¥çÆ:Î>Àþb“±¾a‘³ÓmǶÚâU‹J(,û-Ç®´fè½LQå8ÜÖ¬êöH€2fäéÉSù·îê€çO¦&,gm_7‡±(!ó‹Åo?trCOCWs0xM0Æ fPÕtóø#HÄ¢>4[P{ž©L­1â1&rHæQU³§2ŠCYGƒo|¡$ðø-Wv1ÊŽœÉåò58“ß¾¾¹=XZ©þà±ñ =ñGŸžÚ¹¹Ã¶Iµ¢mXßöèãc7ݰîÇ÷?¾çׯs(ÅŽS_ˆ‡¾XÁY}%?Æ [³}†z³Þb”²†Ï#pŽSÕm–ðcÃá’ïlÁìmG½¸¬Ù”ãòeÃ+ómá#ã+û(e/Œ¥B»¯h<~f’ã¤uk{9ŒyžG 2>›!„õ$Bþ7f…ü×*ÆŒ1Ó4Î>W ©–e½Ù”X·‘f1›‰w8Î'`(hz2(D}ždl#íœf1ŒqCXH•Í=+ºSÖìå\­¬Úo[2à•x¿Ì3Ëõ¡ýs„¶dp˦αé¼n8Ÿ09^ÛôÜóÓ7\»öðè¼c9GŽ/½ãΛjuÈK§7×u(3ÆaV½æõcJ8 Ëše3À”™q¿ÌaôðË«;.Ogjªá¬ïO.–{ZÂ+E5SPâßôb¹9á¿vkÇé™,`Á%^äëS…‹í[ëk\·½Kúe§c*†É‚&µT‹F¼\"èÁˆË”µ†€ÌafXFÍdaZ(YÝ 9W3kqím Õt§j’‘ÞDU·Ÿ]¶šŒx»Ú"ŒÁbA?:¾²}¸%®ŒŽ¥Þþkëgæò/ß}Uÿs¦ÚÚbŲæçÈìÉ™‘­½6᥌RŒ Èqàœ•º¢^>ìEºÍ ›p3j‹"/ðA ¨f¨QŸh¡¢éŠ ?žÉ©k[‚©¢Ñóê³lråHËb^ý=ýÙ’^¬§§³^YôÑr"Ù^3˜ oÍ"_ÿÞáî–ðWõø}¿d¥]È©†é8,`b>Ìs|AQâ> c„¤«NH‹ÚP‹?[µçóúº¶`¦j™+·Å½õɺŽH®¬@±fªª!Ë–‘ÆØ\ºº¼T¸a÷àÔBqvz¥«»Áï“d;9¶ó‰gŽNŒìÖ›1æPZo,¾¨ g#7u!aA x¤X¯Û^ŸHƒ2æ°¿¤ê<Æ„9ƒ>ãf2J<âC·ålÅ4,zõæöBÅ(ÔÌÞŽh®¬÷%T­üÜ‘ ö†}!ŸC/ò ˜b‘ï=tâê­mMápð—’‚jÏæ´k»-âh†’e\PfªA@wÜ£XHä ”J:‰åXHÎ)V®¨e+f_kÈ'óÐñc“K•ÅT‰Q6Ô_?Ô2>›?5“ïíLÊûž™lJ†’‰À“Ožˆ'‚+%»w¸Ÿ¯¯ÕÇÔãõ' _|®ï¬*¿zUM ƒ®Ú‚_[ºeWtôHÉ WLÆ ¦aÙºÝóžY*#@=-ÁÓsÅdÂj&×oëH­ÔÒËËÉdÄ'ŠºmcŽ3mçùS™ÇŸž¼~çšÿËÞ{õV–eibÛ®¿—¼ôd>"ÃdFeVfe–¯êꮞv3 Òh^ý•h A ÔÝ…êžîré323¼a0h‚ž—×ßã϶z¸dTÎ ÔjóP ©.ˆ>ðFl콿µ¾µÖ÷MMþÖÁÍQ 7»Y˜A4EЉ,b°î›A­ÛÃ=»Ÿò¢EL÷)Apy¶Ø¸ÐàµåºVúñöà ÍMø‹³eÀ—/:Ýãѹ¥Úò™:ãâ‡ß¾°0ÃôÜòäû¯ÿè‡×>¿·ýÃ^Ù\[^Õ,Ø\JOú ôiö¢Nwæ«&¤T å}®­²cÄÛuÃh±êdœo´Sƒ`%ÁÍ•:BèùîൕÆöqtÜn^lîÏ6»SuWk½½½K Û D ¨”Ý{~üå³£ïß^8wæ7 ûw¢©/]ºT«Õö÷÷NµÛ7ß|“sö›¢©ÿÕ¿*üËYüÉOÜŸüĽwÏôJƒ ots bÆŠ©û~.2Ša"Ètѵˆ8Ž€oð~¢‚¾C¶PµíW£„ÉZÁ*84É%hó0xq0rljY„+0¹¹ÛŸž(.LÏ-Õ;£¬Ó‹•ÖÛ{}“­ôÎ^¯³×~±º;·0E(†ÁS~5?:®wj­ ÆÑ[`&•ŽiY”*¥€VU­€ÍWÌA‚Ê.Zn¶{y£`Œ˜¢4ë~ÎÕÅÅÊúþP*fÜ2`§Ð0 Å,ããVá½½^»¦Ÿšü—?‡Qþ‹/wkESAæ™VÑq¢,ö¨æÀæ{rÄ„$a›57LØa«ï™Hb˜ 4ÈÓ\IÕj£0›ŸùÃeL>Øêo W¦ ‰€¦-x&R!¨J6Í$®¹0á´âân¤*uLr0#ß¡žE.Ï• ‚/Û±c`@&”°=ÌV·û;GWÚuŒÃã äAœ/Ì”1‡¥!ÁÈ&úp¯»² ««^T*Øëhû7CSÿ}{~ô£øÝwOôq>þØâ:D"%®1gc„,!ÓŒ!eÉBà~"j.vÌšAz¢ 7fʨå x8â‹ ¯óƒk–¬‡á…… úáVÿÂléöys§=}ÙÛîÆ‡½øÎ£ƒ7®NùøàÂ|¹TrvöãÆz¨DÙ&FÒûüþþ¥7.š¶9Fb.¥>Q­Jk¥Tƹ ì[˜ÀT×\hÛ¤Â2l­uÑÚžðd7FöÓå†ÙeÅÔ@­~rv¦ôå³ÖÕ³õ£ðòr½Õ}×,—½ÍÏ#O©äü|³½¾Õþåkô»×KEí{Öÿë¸}š‹Ÿ~ür¶áË¥yœg‡!P Z.ášø¾ÇÂ)Xq7B Sò¢Í¦Št³›Ï•MŠQ[©•飗ƒ4Ó5g˜ð(åK“>Å0HøV+’RR‚tÎoœŸ¸»ÚZž-wÛ£éÉb¿¶F³Ó¥ÿé¿û·“ÿÅûŠKDñxé´:©þôcžrpM¡µ@›4VŠb˜;DšF‘‹aÀˆ#ƒ0ŒHÁBÃD*Žñbx~®´Ýg×Wê¡ÕƒàÊr}«L7 qÊV7n\œ b˜”Täc¼±ÝÛÞܹ»-¹ügÿùÛBt±àüÕÂIÊï—V«˜qžû¦åÒ<á.„ª`A ß :¶©bBÏ”Iœ+.õ\Ùe Y„€_<>ž,Û Þ'ÏŽÀQ˜YŽ!¤ ™ì¨õÅ¥Ú•åúÇww˾ÙéDÏ5ÛÝpØæçkÿóÿð'ßþÖ%³Þ4+JJ „ïÆW-ã%ÌóL ­eÁÖêadÄ0½Xº¢„jmÈz <ÓD¡—ÝìÜ\åÅq¼ÜôöÛQÁ10Ÿ=9Z™¯¬nuâ¼uíÜd¥d÷@MÊR¦‘ÞÙl½ìZk­®µU÷÷ûÚWi#„PÁ·þ!3þk=Ž£K%5þ|þ°ÿÎ÷>×– (IRfcFÍbš‡VE·Ñ »ë¢Û¢#5N¸áÐ|€ª û±hG¢êY{ý¤âÑé²Ó¦‹þóÝáa?]ž)>߮ B àB zAþµ«SýaòåÓÃé†G Ù¹³ ¿`eó/þø“¯-VK„d\ÿ€§iñ8ú“H ¹TA®µ»R ´ÆVR eÝS\›\ð3u3aHQr­Ývxvº´;È/Í•vÛñLÝYœ‹œÉýA4 ]›2F‚ É¥à2 Ó»÷>üdãW®QŠÃøðpxx4Ü? „¾*FÙÓçG=:šðƒ E”ÆR ê5ÆÃ0‡&Î(-b0šh€2®]CHsÎgʶt¹N!Ä1Óeó`Ä*žá;4ÊätÅ®¬0ã³5Ï6p7Ì1Á!ÎÕ^+¸ýÚl§5þ0Èööû‡ŸnÞzm®ZuUîoÍÎT¡cŠ1€CøŠckp:†.Ù Až0P ê$åØ1pÙ1\Ó¤Hk`˜†a0`h¶fŽøBÕnµãå¦¿Ó BÝAÌ…Z^¨Þy´Ò™‰’P*Ϲ’ç\iÄy’ä~¶ñþÇ/~õá‹JÉ9: ކ}Ç5lËxO׎ž>o‹ÎƒõÎÞÑhvªÜÒ’‹Žg5A¦Ôp”ŠŠ=»êW!ê`”†F¼‰©²É¤~ÞJªñ,:?é+¥‹®9Yq ® d Šû{ô¼uyeâ΃=“Àq¯»c¿xÿùëóýNðóŸÞiV,ϱl×ERŒ Æã‰:©Û ”r í1 !p ¢¡O EhÜëʆªØê(àíH,UÍí^2_s†‰ÄP»®¹±783W¥|ºî<³;Œ«íEl¬S8ö+Bd™Hâ|0ˆßÿèÅ/?Xsl£Û‡ÕŠKþ£Þà Ê>¸W,Økí”el¾áä CÀLêØDçBDLÕ\Tt|$W˜"Þ‹W `Ã@”co.ÖlË »xeÊ7 üøåÀµig˜¥¹¬-&€Pjqµ¾?üâþÞų^˜[½ÿhoåìÆø/ö$NrªòãíÛvæ§Š`„#¤µ†ÀAlÍ¥ÖK¥Mª™WED¥J®«ŽŒö =U4:‘*;x©îôòzÁ8ˆÔë+Õ\ênÏOúQ.{£lºæ=ßT}¦ažäJ*ˆ Ϲ2IXe~²ñþ‡/Þÿp­Zñ‡‡ƒé©ÿ0c~ðxÿÞêñÚF{yerçs%£QnDY @æ[–ÐÔ5Á• æ°ááv¤šZÿã|²þËÖîÝßñ\óàpШðß¼ýÿ_™ñWŸo|ïQ§Ëk6”Z-\ö‹²(×Í’/dœK\v-%c¡P.ˆg0®Ü¢cìØT”]“IxqÊÛí3¥%%ø8äSujµßKÇIÃdÅf\vƒ aDMÊ5øù—»U‡\»8õäùѨ3ʸ†I´ßxçülq÷ ¶;Qw}gÜÁÿª´fBh­M ¦BŠ ”`›Z96J‘c…ŒÚ†ÀÈŠX™)í²ùе¶7˜ªº‰LjL±ÖÚ÷L[* À[—':ÃìAš¿’¤×§,?ý‹'Zéñ¤‡`b~¾:=U>í4¹Ô«k­þÖµÁ0ÑJ<š%B Ѷ‘QKóAÁ*AsE…Â&fY&Џö' ¼ãª-Â\‡™ª»p§Ÿ[”*Á+žáX4M™À øîz'çžîQb‰áÓ—ý†G?|Xv LГգo¾³ŽJ‰RÊ1Ô³Ï}û·nÇÈ8g$¿nÅTªŸ€L`‚MµoޤFÛ RÉ ••R,ÊAÅÖ»6U40„k­`¡îöU.Xˆ ]ƒl+ UÆÄñA›+à–\Î8ްVZr‰ Ò@k¨ÿÛÿù¥ä'-ß‚‹óçšÕŠ;®~*^’ò ÌŽRÅs±2SÒ@šD‚Œ °`i“˜)3‡bJl ¢„­‚l”êÉJ…9á«”ã8KƦüŠ_´" @Ù3‹.F9C„!€é˜ëûþ·Òî„Riô'w6ßþúJžqŒ"xkm¯ÿéó?øÇï>{|xåÖ©TÎùXûUV•j‡€Ijà,€6Ô!ÅÚÄ\_H]ur ýš7òMÜKÈdQ&ybaZT(m˜T*‰´,ãóÇ“5—:Tp‹3NS*˜xEKŽ©Âÿë'ÆÛòÆks¦IµR„ñ˜„äï âæ¹9–2©TÈ2‹°š›hX Òžg„ü”åB!‡Ê„[u/#‡9ž)å½Ä¸1ç·i¸4éírÏ@SU§²«K•A˜Ç¹¸¹\GnŽÚƒ`yÖ½µã™fñÑÓƒ¯]›Ü}°sëæâýG»jà¬×úù£gï|ûúû{×ߺ’q>yú÷²yÎ!Ë)æ¹Ð˜UÂ’% )–$ev"PÝçA&Ž=Q¶‡I^÷Èf+ô,⸶`ùÊli·KÆ/,Õ’”a’†¹é˜J*Á&xlƉ$€ÿõßÜ»¬oþXçpïÑÞ­7–«%[)%˜‚†Y3žæYÕuÈ4$H„P¤æ*f!JBÎ¥ÖV½XXMÔe†A„R{Ý#8«¿4_~º=P“j­÷»ÉÓÕ£ë&ƒ˜EqöÅíë× 6}íÚ|çcœŽ7·¯\[ÚÙIΤ֯š4!ãÃ$ÏSK¶j 5dB•]+íX 2 EÌ„TÀ" Î9“ºhƒ~z~ªp0àó ¯›ˆ‚MYÎanøìlyóptk¹¸Ý F&‹hŽ èNôÂôùןJ)Ÿ­RŠ_Ý“oÞ>»´ôw-3ÿŒÛGîû?_\\éX˜Ž= w `{iùI…€CØ,p ‹!†¹2“f–mð¢ÍfJF˜“Ån‡b»b §kŽ\ Á—/:A‹âŒIˆ!SÜê§1Sà Eù¿y{³M 2=U~¹uüÝï\þéŸ?jN¡Ê–ëˆÑM0Dh\mû“Ëx\‚Ñ&›4|¥è¦Ö„o(¹Av(çRÅ9¬ûèéax¦n9Zlƒ\Œ'¤«E˜äÉF§^²•Twìq©!„¦cj­Ç¬µFi}$ ôÎNog§§NÙ¡s¦o\}¾Ùñ öÌ„ÿâ`xy®8Š‘e•Ž„²(Rq–F9hø˜k×@‰Ð>†AİC•Ôp”ªÉI¸9W­@]cõ(œ*ZÇà c¨4€N–ÓÀ;Ç!bHÉ„ZÝéc‚%µZáòř݃ áìLe}«í;ÆÌDñüïÿøö×VnÜ:û¯ÿÍïþ£w™TŒ‹1$oöœs.eÎT# !àA mÂ(°æU#\œ-÷)FÔT ÎËœ¯Ð$“íH,NžlöÎN÷‡£(Zß:?!•~¿XŽ%„BJ)PONs¬¤ÿüů-RÊ’mÒ Lo¼UZ™®®o÷–—½Qá›\QÏàIi (Plà€ë‚gDZã^=Ûˆs9Y0ï êîÞ /zÆêÞ0Œò±Ôö+ºSÌ5xð¢}~®üÙƒ=™±·ßZn÷¢jÑv,X«ùßýÞ•>xôÃ\C8 µ{&†I!F§ÆVz|ãD9óMX÷ ÓL®lŒ]‹BËB„ÙýŒ­¤c“@ „̕ڋ˜aÂÕÍnÉ3r©¿þÚÌO[„"צ¤ì‰üdZi©äIéjˆà½»c?€ª4+J*ß7¯-–?}t0ˆE­2¦1.&Ù#à@:L®$(¹tÚõŒhÒš+Ú¡$ ùBÕ> „eÒ%ÇÜi =;]ør­“sy¢¹ 5¨„cüŸþÞõ_~²Æù kÏçæk\ȹÙêÞ~ÿ[ߺôóŸÝÿß¼óùÃêü¶LÃ6_äÉÿP®$Ai ”¬µ¬x%ÉãˆQ›0 ó(—‚º‡G)ƒZ¦ßði+M—ŒBõÅzoiÒÿb³‹Êƹ\™¯ìw"!Ïyçã f|ÀO‹®'ŸO>Û‚A‰AÿÍ?ûÖA'ÚÜj')_¨Z»G£3ÓU@” ¥˜fk4š)X¾™@4€JËQF1äRë’MRaÌ•S©a+ᢅŸí &Ëö æ?¸5û²öÓ¼>ûb¸uŽCn˵Vwú¦Avûg—Su×sÌ­N¥`ON–¶w»?º±ð“ûÑ¥« ë½o_cB1!Æwã8LÌ8‡v%`#™\ q› ‚€„%Lj Ê2 jE9]là£@M—ý~R°)Pªä™Šû`½s}¥ñ`í˜  ô*^$,cJ(¥„'Qūń~q÷åØªgü»¥Åúߌÿ®4u©T¾wïnÅQ‡A¿Yšú«Ï¿øþ7¿wÿê¹IÓ¤ÛûýÉZ±Q$­p¹Yd‡Ld€c` L(‡ ´ã†*T]1ìz”òAS(ix»¾l…Ó5w¾á5Jöa7yuj­…ÔZëÉŠ§5c,êÝwÎ}ðÑ‹Éf‰eüÜùæ¿û³ûûÛÇQ§Óœ¬˜Ž7¾õàé_“ZL¨˜ÉQ†ÂÈ!DLb 3פÙ›ŽA4´-ª‡,;`”²”k‚¨cáŒËíÃÑÒTáxîiÆ-› PƒŽ vZiNB€–¿v^ÿâ”+¥¡iøŽqØ ¾}kæÁ˃@Ñ›=XduêÅ*ΕA1dQ™0­5(ØÄ ¾oäwl’õå´5Jg+“À5ñ‹£ˆR´ÜôׂÐDÙ6N2qÒR$ÕóÏÖÛá(ÞØé^Z™ÌsÞÄ3Ó•rÉþâÞÎ?ý/¿†Ù矽øÃß»±¿¾].8[/Û•Zé„öGH¤Ëš %•ª{®È¥aÐ#!%%Y.PÌHÉÆqΖ¦Px¿{ŽÕ&æKÇA.¥l”‹‹•»ÏZk;=L°i™„uÒI ~=*$O|mÔ).Ž5ÁžgR‚^»<³¶Ý»¸X•†WМ«ánÄ\qí(æÚF î& êH€ªH ` ón+.íÇédÑêÇÐ  °ºoÝßèY¦´*¹&‚@ÈWH¶¾Õ™™*ÅÕWÎNd¹ƒ4åòwçúgŸm~ÿ{W¾øbó“Ÿ•=¾ó´Qó ¥B}ÅuDi =HÁ ¹Ð¾)¤Ê£$Â#%$ &` 扱]0u&@˜å¹Ð à²K‚TLV{«ÇÓþÒTq¡Y9e’‚«iþz7j­”ºtqjf¦25Y )O–´Þ(º¶qóêl7âÝn¸4[Ì%È’Ì5e/E儔⬟ P´ Rj0ȱkHÍ\ð‚E¹¢U¶CQr ¥ä0W‚gâîf?ŠYΤÒúg!Œ2qÿñ~Á5 “ºAəŚV ?ˆ¿ûíKŸ~ºþío_zòd¿Qw}Co<Ýö}@L(Á_YL­”PÊ¡ ì(Š„ÒR*¥4403)Ð5)µ ‚Øu bÀ¥¬l¥akÌ7ýõv:U2k%{a²àÚôñf·^²«bÄ¿â u“éÓ@{]®!P+}ïÑÞñ m6üË+“/GÓò¼œgD©‚W&M¡mšhŒ†¶”a˜“¢­m³äÒ,â^ÁH2 û‰vLlSÐAÍ'A&&Kö¯]ÃwŒÏžµaOÉf¥°X°§kîòb uç‹Í+—f—Ý^ø;¿}ýÓO×o\Ÿÿ“?½û{¿}¥õr¿PôŽåraÜ7NXµÖRi.uÊ¥oi— ©¤6!6¥E¥y.ˆCóN¬&|å åÂ1é(ÓJ«¢g|x÷î½ããÎñq'Àß0n ?¹˜­ ¡z½èâb©2 t’ÊZo´£™ŠÏ%¨¸X xÀ‹6H8t EˆtÎ¥Ìt-/Ê3Œ ­$€ ÈUÉ¡3U[i°ul¯.Üñ¾wlã­kÓ®mä\îîôΟk^¿:ûÁ‡kÔ$®cž=3ñäéÁw¿syg·wû3«·ÚGƒ•³S¹øõí9þyŠ%ŠKiS­´âR MbDyž1N1Ö@Kɪ®¡fÅÄ2hÆò~*}‡nî ]Çœ¬9KSÅA›¯ÎÔ½£~b{¶é˜<ç'ÍKÀIþ1Þv¯]ûÖ7/Öëþp”~íÖ%èí[‹#¡)RH§èA%óœ{ž[0‘A y+Hk.ê'´êBªJ¹B@C„,€SC€~~8º2Wp,º¶;¼q¦jXk … ’“é8-õþqô,rëµ9)ç’¤Ù,Q‚-“>y²G)~ûí•¿üËÇ„à—›’±²4“KÈNåA^A$Wz”‚ ‡a¦ ,¹q†¥C )&UÏÇHXr¢`Jj@ P "—"„àA7>êF%Ïl”œA˜!‚,Ç:±¡ÕêƒåÉ‹”'Üû‰}¥ßzãÆÂæap~¡"…<3]üèñÑBÍ ,Ùij‚Ô IÃ,Õ€¸†6ˆ TZ mP˜ÆœºTRZò dÀ³-­yÕ5ö‡j¦B¦fkn£h%¹RgiÔR+­&ëþÚf{aºôl£=ÙðµÒó³•õÖ×ßZ¾û`wa¾Z©ú¡?üƒ7vÛµŠ«±NÇŽO¬0ÕØªG¥\†9 sȤ*ZBÈ…*8>#D0h•ôíYfšç˜`ƒÆ8€p·—žmúZƒ;ý§›]J±m’\jjÓñ zÆãm97WulJ::²S6»Tv¯_™±mš2y|,ÌUë>͘t\hÑ¥E[Ž2äÛ&Á”ñ`Ï\.‘gHÛj2‰LÂ[pLÓ¦ˆp8âk»}„ kÑ0Ég¦ qʹTãú9„PrY+;GÝd²á—K6FHrùî;ç>ütãÆksÏžMN5‡ƒÑ0âq¸r¦n;¥±fܘk•ZK­®†©¦šIEVJSL‚4SZŒHb†˜PEÛN“Šr)Û!Ÿ*YBŒÐÝÕcòæ…‰q¥?Œ™B(¸§~¦'/ê×qö˜wÕZ#„¨Ikeg¢Yîö"á”ßOEëhج!ÓžåP„Rç8rì’`‚”IŒ‘bR™.9Žk@&TÊ1atð S^?b€A˜}õ’ƒYÁ5<‹<\=¢Ùé²c›B©wÞ\þø³‹göözÕŠ·¹ÑFn¯ïÏ7ý¹fI"”‚§+ N/É(WA3¡ ’Œ‹Q3ai-„äj×r ˆ,´PH1Éß² Ÿõ“s³e!UÎÄÆÁðÍËM UÄä¸Ü£¤:™9½M^ñW™ñµk¿i0–Rpž×j•z½úêséÒå,û{¡ÀõÓ?ën­Ý¾z3¨­$έ‚ëYd{¯y©òä0¼<ã'ÙTÝßìÎV !åÁ0oø8bFÁB¥Ò^ +žC@S1Vq°0Mòý^Ú sÎ¥mâó³åaÌ0‚Bª±6Åp”¶Ã(¿ÿÃËArÿÉÁdÝwsùìÄG¿x÷çÿô'÷¿óíK«k­™™Êùåê£{ëSµ öäIª”ÖrìÁ €T*ÊUÂA˜«Lè\"‹A }“@CìC b­@"dú&l “‚Kw#¡TÙ7 û£ôkW¦;áÖáPJ¥0,£X-Zž%¸ðÄ@w|€J¨$aG‡Cjz¼/ý IDATÕÛ>¼s{iï`@ì2¬•càÃ^ܬl+Áö;Qµ€¶{ùbÕe´hKJ]­yÎ9S†M8Ä.!Xó«Ze£œÌVèN?¥êÜ´¿¶?:ê&­^g#¤NórBðï¾»¼0SÞ9… · Ô¨\›nnu‚„}ã­•¥¥ÆÏ~¹úÖ›Ëa”Õj~½æ}úÅÖô\A$¿â…þÊ%VHÉ„Œ™Žs• 5]‰^j~‹ ÈQʵohÓð…ÌsIje¢è¾Elô4„¯_˜8ìD Íâë—šõ’}Ø©e8h”BjuâÖ7.ÃáùÇ¿}ý·¾ðù[ï½}6Œòë—¦ïmõ ®.7v9•"JrdžÇ›«ØANJ6Ñš(oõ²ºL¶aG²`[&VJË—=9W¡íab›ô¸Ÿ(©*s¦î^Y¬šõ‚|œ·CÄ[&ÎRöƒožOãܱ~½óæÙ»w/¬4ƒ e\Þ~}éÁƒá0ùøƒ§ƒn°rnÿGa|µ˜J1!s ʶBP Ssåa@BeR؉rפ6E­Ald¢dõú‰mÓfÍ]™­¬íô¹ãagÃ6Ç® p\ê@)ux8ÜÙémmµ9—Zéo¾wá÷÷æå S»ûý÷‹¢dÏMú{½„§¹o•º^´º±Fr¡A”‹¢…ƒŒmaµ4Æ -e™5 g)'&‘G£#¼X·÷{)€ðö¹zÑ5:ñ8WêtL©8å·¯Í<ßhwzqÁ·Ðw¾Üþî7/<[=œœ,‚‡­Ñ÷¾sùÌ™‰ŸÿìÑ›7ç-³Ê9Ç7¯0©T.TÊtÌ4“ —ÐÀb˜AŠ ¡©‰˜múZ±Œ«²!r”fEÛa ¶:Éëçêeßz±7wûæÂQ?ñLÒ¬¹]¦1çµ¢í8æ“¡O•mý!kÒ0È7µF>©ÔÈÀBhÛ7¥ÔvΓL(Œ(ÏDÓEcý`4Q²»!cLœ*"ÆÚcGË${ûj¹™Š’*NÙÛo,½ÿñ‹×o,ìï÷µÖÇÝè[ß¼°¾q|ëÖât³ð—ÿîþƒÏ׿öú ôXÐBxêE¯¥ÖL¨˜ƒ˜iUÝåI.%€Ž¹V#dQåZÅ\0®¨E.¤ÐPæüêRu¿Ÿníõ§ëÞ[W§¿|zĹҚÔ´ÍWm¡'ܧ:ãñûý_½÷Þ»ç—ë¦I“`캎ç¹äß–—WþžÈaþó^AôÎüŒÌ˜,:Ô3BhP(:AÊE&‹ž%©ÒuŒÝ»0i‡Ìp 1J‰CâÃO4B¦Pª Ïöʦ¹Ah” &åùÙÒTÕ›)6+N”ñ”Éñ,ÐùÅj±`¯½hUÊîÜLù¨5œž®¬ntÞ{{ùÓ/^¾÷óOWuÿâ…æ_l×kÒ陹Y.ÁÉÔÓiÙOi-ƪ{Rr)s¡˜ÔƒDMzJjÐMPÅÑ™• f5*@TÛ}îèâ|É2©aàZÉ~°ÞSžåâæ…I¡g‘Aª…ú\lY&Bp1Ž[y.Â0;>jUïÍÛg~ñá‹0̈mmêÚ´\qwŽFÉ0º°XþðIëkêO“sD((É™gÛav#Ys!@RA.±k×¢´ßK@Õ% ®̲k<Ýî[&¥U}Ó0ðÒ”oQlRœd@ø|»÷hõèü™ú£õ¶‰!W 7H Š_¿>¿ù²ó«×Þ}çÜöv‡Ô˜(Ý»·ýÎ[K.5 Ó¥5|Ç7âĸ] ¥2.ú Æ@"„˜Ää¾e"R‚ ßðé"yz04 ìšäéV¯Qqfþ`˜^>S‹S¶µ?Ü=MÕýÞ0ÑZ{eÏ+y˜`¥Ô+ïÈ“êù‹£/ïíPŠçk£„ÏM•?;œ¬yJªH¥ª½¶Ý¿¾R¿»¬ÔÌn¨>Üj ¸È¥FJkϤ©0}3WÀJRL FÁûƒÄ3 ®ˆMÕqÈg*v– צQÊ_¶B©t³êŒÂ”A žõî¹ù™ò“N˜  Õ7¾væÁ£½3‹õ8aÃAüwÎ=]=ìvÃn?ùñïܸ°\c+Ê㚣Ô@¨NC €PŠ+• •qÙOA& ³a ]»ªd’ridQG)– H0FH2A):DH½}0|¾ÝŸ›,œ-¯Ì•«E{d !˵ü¢+¥zÕA£ô }-…|¹Ýùô³ÍûOöY.FÃèó€D£é²¦¼Rñzkx´A‡°a”—‹ö ‘‹U³5‡cD2q€*z,ï…9tM‚‘ey˜Ãíãa£dÍÖÝÝ£ HX³æ.MêE{”0ÆÕ˜ÞU Ÿ¬º7.MS‚&jþ¹•É—;½,cžowÂË—fZíÑå‹Ó~´öÖ[Ë›ëûƒùæt”3áɶLj¯ÊR'¨,ã\5< R„Üu @h`Àµg1HrŒ°Mà“þ¹ÙÒA+hõ“™ iªØ¬¹ëûCÏ¢¶I¢”;¾ã•=bD–BTB)©ž=;øäÓ?]ÿäÓõÿä¿ 4ø“Ÿ>ºzi†3Ùn‡Ë³¥ã~RóN¢$‹.Í$$8¶qÆ•C`ÔŽBÁ¢¡g„¹” 3Imª˜„&«‡aµ`.Oú£„ÍOø‹Í‚Òz±“¶­¿qk¾Û‹n_Ÿ-—ܵõãbÁN39 ³Ñ(ùþw.Ýùâå¥KÓ½~ô“ŸÜÿú[Ëõºs¸Ó~íÒò0ÉôéчRÊ10s)c&‡)¦€ í™<å(¸êÙ˜”ô ,ÙHi£g„×€w^ô‹¾¶TQ|þüئ¸àSuϵ€8¶a˜à±…ü«bʸ•áî½íO>ݘš*ÏÎþF3ãR©hÛöð}gÏþ}ãµ_h9ýÖ×Ý<çSlÐ0fͪóò`´2]¼óp¯R²G ¿4WÚ°ºG &BÁý~ˆa†± °MŸK)•BÔæbì£]Ö ¦pÌ``¥Ò_ö—¦Š “~£l³Î ­—mǤ”’‡ëzÙÑ\¿4õÉç[×.ÏVÓ1I*„A­e@˜ç|ugpa¡jR\p À0HÇ1b±^¬×ÊqœJÆãd¯¸V­ôý‡;L¨7n,P‹²Œßº6³Û‰TƒA<7áõ“bÑU)†±˜,áƒ^g‰k‘^¬ê¾£´èD¬h -!¹T"K ǽl—抆A•£ÕÁúþÐsŒ‹ó•Ù†‡ Þf“5÷¸† Û= Jžõùãýf£pûæÂÝÇû‹s•þ0…þ£ßXßlK¥ßy{ B#ÊÕ˜™—§4šÔh­N‰ë1…“r™ B°Î¶)å<È•e )Ë¥³¼æ™ÏúWÊŽmôq«Ÿž›¯˜ÕJ¶”#X/;Y.¸¶g*…¥…é^o„0:!äIËÈõks³³ÕãÿÇçç¿x¨Ô~ÎäÕKÓJÊ^/:»P½soçõ+ÓŸ>Üëµ™ƒA:]u¦$€}ñôhaÒ]?ŽÎ6 )GÛÝÁdp…Z(ÙR¯ÇK3Iëñmæ2IÙ\Ý͹ÚëD7WêBêÝvĤþúåæÊ\ùùî`ûheüs³“ÅQÂî>=šžð?´éÜäâBíÎÝF£`Z¤Ýß~kykëøé‹V¥>ö.Uò”ùj-ùUO4â ˜„¥¹””X&Q&5Åø¶1ç¬`ABÜ1¯ÞðéD>Ü ›egºbaRO­§»Ã3ÓÅkgj•‚Ù sà aÂ;ýxi¦üh£3QqÎ.Ô›þú`a¶R­zÞ:{|®\™ùã?þìÆÕù„A®:Íç^eu¯JMãy…„k „¡´o»ZÅ BÛP½8-XĦxºl¬¶eV}Ów„É£nd¤â[Û‡#Bл7gÏL6÷nÉÿúÍË7¯ŸÏ‘β!¨”C2‚`8LºýøÌBíÍÛgÊEkýetn¢IfÍŠ½{\:[ÿr£u±Ü‹eÝ#Ra„|§—C±?Œ' ~ÄY.¢¥ÃÔ5I{˜-7=¦€kÇ$ÛÝx²l¿8šU÷æ¹úTÍ=f†A‚„¢|²ænì }›^:?Y*Ú÷í]»å …Z“Œƒ\Ò‚í2 m’dҀЬyºɲCÚƒ¸ä[{ë`”s•å"LØ[צ[ݨ3HVæËûGCäР7¯»rñÌ^«CM@Å'Ê»RÈá0ÃÌr­Û·ï=?.:”3qíüdgäLÌLžïJ§ìÐ8J÷Žƒ™ºu{¸P3Û1hø”GˆÑ0EÛ ´ÈExJÇ4£,Ÿ¯Z1×¾…w»iÅ7G»v¦Ú²£^âÚô çfË–Intr.ß»5W-;;­I}ëÚÌÆÞà°¼ykñ£;[o¾¾¸s0(xÖí7Î<_;ò]2;å§ Áx\øÔ_Ùã°[žB4R$µÁ%(Y™AˆœÖ(¡˜Ö\=¦è| ï´ã²göƒôÖ…‰0“!èÚôÖÅÉJÁÚ;i ,ßzãæ¥¯Ýº¼¹}€)&$—J+ Àh”¶Û¢¤à¿üpíìb= ÒkšÏv¦Vœ‰FÑz¶Õ=?_ʸl ²3“þÞPMø„H«ì8Ì«~Q)Þ‹ó‚mY†ß C¡ÍóM#Ú1po”!‚—š…Ë áv+ìy’K¡Ôú°µ:±Ô Jye?þîÅ™féî£ýKç&Ç`¯]½ÿ`GJõúÍ…ûv;^±ZUb¹”ãø+ñÑ“cþ*ŸI€&˜rÊöMœÚ¦¯U–:]ÆG!oŒþ0»v¶Ö‹yÅ7^EͺçÚôéVïêrýÚÙºIQ?b¥‰òÕ+g %Yί©×^û0þ+Ÿ¿øó‡å’óo]|ðho0HffÊW[?úÎÅ0fǽ˜qY+;yœ­ou®ž­ýô£­ïÝžqÍUmhÊeš³’çq©ºQZöŠŽa›8$ªêRØî +;ÖtÅI¸L…šoø»Ý#´8Y(yæúa°ºÝ¿¼X£{®ùt«ÿ哃JɱmðæÍ… Ì~ñÁ‹3 uBÐöNïÛïžßzÙYßh½v©FÄbBŒ‡~Ý\ú•!…ña&ÛD»&„@š˜ù¦¦Ô‡šw´âší0??iH&Ê6ŠK]õŒg;ƒ’o¾ØéóæjmûÿfïMb,K³û¾oþîüæ)戌Ȍ+³ª²ª««z »Ùl’¢`“[€ ¸“á½ A;i!@{ ²M$ÒjöP­êꮬ¬)+ç!æ9Þ<Ýù›¼xYÉm‘l¦ ‹» ÄÛ܃{ï¹çÎùýûýqze­*…¤ÈŒ3qesíêkëÆ¥£™&spÐûÕG[ÎäúÕùý£áýû·³L<Ùé5JvžæEßzºÝùÎ[«½aÆ¢YóúÓ\¤‚[ñühX+â0ÓZiÏöQœ ãYŽÃÌé(¬{”²ßΕÌé ™‰ügƒä‡o.P‚¶ŽÇR™ëª+­B˜JNÉ8Êß¾>ïºl÷dÔ>}ÿ»›Bƒ'ONÞ¾½zÖ™>|pôî»ò“G?üÍw>~€±\¾_õ~ üúJ+€"4ëƒRBR‰ .6£ k¡LÍ'ÏN'µ‚í2Œ¡9èF€VÕ+–ç²w®Ï‚Ïzá¯î¿u¥9M“Q/Nç›×/$Y†ÁgI¶y©õ{ÿåíkWæ óðÑñáÙØwè\ÅM31%Ë‹¥ÇÛÝ_»½<ŠòÁ4ËRY)XÓirx>,út·ߘ„"OÏÃ[KÕXP!'©„.£[dÓÍ—¬£als: ³T¨[*‡hs©$•Þ;Ÿ¦¹º¹Q[m­ªÛ¥/‡ß~c©RröOGwž¾~unïx¸}0h6‚OïþöoÞæœ¾qkù“»Ï··N½raf§¾&3üÁ„ðå$ÀEÛd Õ ­\ã\*޳º ä(Fpg­/eJß9,Õ=áy?Fî Ñé Ç•bñÝ÷n¥ `‚!BA ÒJ Y¯¶Ë9#×/·ÏÆs5ïó{o¿¶pÖžÔJî$Î1Fóuï—O»ßܬ¥„©î÷“$°Ùð `Ižiîb ¥2 æÕžfÆ€\!߯”’a˜c×fCáååÒ••R­dcŒÊE§RtÞº>·²PŠùÙ£“FÍÏr•%ba¡¼»ß‹¢teµ¾»×ŒãÝƒÞæjÀ¸cN¿Zæþºö*˜Æ!‚`±8R™T¢¢1)&i_j͈Õµª;ÍLàýnÔª¸ÃQòæåæÞéhf¯m6ÎûÑöÑ0j¾êÆÓH+øíoÜ\»´fæÔhƒ ~íÆÒü\ñ?'ãÿèñÑ'{Gǃ»Ÿì,Ì›oßZþw?~8‰„ÊDÑãFëN/z÷öÊáù„QìûÖ4‘gç#ÏwGQ”Çi1ð£,ë†Ùr9@ÈôÃÜãS;Ãäõ›Ë_>8Z[ðŸ<=m6ƒTþnþù~Í #d1`S€§°àT ‰sMѱù‚é„Êapg™Ô¢s>L×ZÁé8[mGݰR°+EKiS)ØÕ¢-rÕ(°’‹Ï:`±R£d¹D!¤µîžD&æKGýŽÒ4_˜+U+þáéè½·VÏ{ÑI7¼´Xzô¢³¹Zùà£ío\o~ö¢wmµÚYZjÍôê¯Nð}ý„´15øLS$´Ñžå@Â,¦„) 50E6£ýiJ8EÌ`Šà“ýÒFiÓ¬xJ„ŵsÔ¯—‹­¥†fØò,™ËNgrç΋ïlßýdǶhµêcºÃ˜1ÒªyÛ{ý·_[ìt§{'ãÅÂ'Ÿï¿q¥ùÁ½ãïÜZØî&s¾{<ÆŒwÇ+õÒ(É”Vœ`йkÑqYÌJn4œT‚µº;ÎÔ4‘£Ù’ £˜3¢”N3ùø`ta¡¸Ú*|ö¼ûðù¹ãð‹«Õ0L0%®Ãëeç×Þ»øñ§»õšùRëç<­Õü«—k¿øðYc¾¡¾bÔÌʸ¯C„„³ðbŒg¥!™ÇÂ0SR`Qe£"(•.ylf“8icn¬×FQžç**ðø|É–2ž&‘”¨µPÈ0‹ÍÚŸ½~õ¢ÓÜ~}Å œËÿì±pØôáÍÍÆ“íÎúrõ¨¶ªž‚¨7ÍŠ|ÿtºX³ì7æ+½0#”=7 L3i„îdH$˜h`”6œR£õjÓŸ¦*ÏeಢÏ„µ¢m´8Y –æ AƉcóÞ8‘RimÚƒ¨àq?p>x¸ì[+ŸÜ;$¨ÜóÍW•1üÔzÖC™a[f‰Dj¢´qÓ:Jsɉ1Z”†YF1ÖÐ(m¡JÈ7/Vc¡{Øp²Ò 0F•VᵋÞ8­l³Á(÷Ê~e®‚F#Œ €JªåÅJ­êcöþ“zÕ7¼~sIk³s0ð Ž”úÚzí ù6Í’¼=L›Eºw:v¿å“ãnB)I¥Ì¥,ûE¡À8 ¶ÁˆOÒ”`X¥Z¨8BBðæB0WuÏFiœ ¥ eÄâ˜3rx>ùüY»3Œ—Z`Àý›‘0ʤ2Ó(›LSÆèü|)ÍÄ\3ØÛ>Y],¥ ˜y!ÿ%[¼Y<1„À0Ç Øi¡©gÙZ…¹¶¥‡R m€Ë¹Qr¾æ¥Ò¬4¼½Nˆ ¤Ïth×¢•‚­±9Éòì¬3~mc­¹P‹¡vpåR³Yóÿs2þ_<9Æ@·_œôFãøñÓÓ¹fáî';¯ß\ò}«Û^¿>ßîGÝQzq©ôó_ÜÚl|ùä|y>ør§¿X¶=‡ Ä`]¨yB³(“W³€«“‘,{%¸`ãX@Áé8_¯Û¢µÓ‹“\k&©Zkz “Þ8&r¥åW ö(»GÃÁ81ž GãäÚ¥æêRåƒ;Ûï}cýç>ëæ\5 RiÀ¬i=«µ1ÙdÒ(ñ÷ÿìÓJ«J‰smKÌ„²( BÈ|–œMrŸ#F©h”ê\šåªõü,,X8j±æI©&a¾Ü ´6ýQÒªy·»ÇíÑrÃ9:Ÿø×ò,­4s˜Ñ†Òï‡Ï_œì÷®]]øÆÛþìO¿„¾ýÆÊ`>||üúõ…Ÿýâù[7¿|túúÕ¹A$8Až^^-t§KUšó^7‹¾ÏA"… #áÀe’bD0>%Ke«3Éžž†ë wšŠ²ÇFǃ$ÎÕŹ‚oÓ‚Ë·N§ýqÒg§i”ËÛWç[5o±UhÓûÞysõîg{W7[ s¥ÿãG®mÖ†ýaœ8®­¾Âϲ2šMìB ´Á/A¸BšJ0Í@ɵ3‘æ¹ R0$F Ä“¼î[Ó¥ª&²U´Še*JE"ôú|qçd !|÷Z£‡Anlß™ý)§3rÅñaïðxP-{¯ß\¾óñv¿½ýÆòŸýäQ½q}þÎçïÝ^Ù:¯´‚LÀÓíöæri”ÈÃÎt©QÎD>ŒòªG9 H‡IؼââÃa¶Xd[íé\Ñ2x­,–f®d]¦ ØïDo\¬ ¥{ñÛWš×Öks5¿==ïFͪ·$ÇGýþ0/úÖ£½Aà°óQrr2b_X©º.ÿãsoy¡\­xÝÞôõk­ÿèþÊ……\Jý½õëpŽYk€Â)­(F¹R6‰9e+hǹö,ËcÀfØ(ò;ÛFð8Ì7 §ÝеÙ|Í;ïG?:½ºV‡éîñh¡Æ‡SQð=êp¡Ø"BI¯=~xxr<øÁ÷¯]½²pùbóýŸ?Ù>=´Þ\¯=ÛjÇQÖ¬8^´¯¯W¿xÑYhm‹<Ûï­Ïù¡€'Ãx±ìQêM’ásŠ‘ƹo[ƒ™\™Óa²\u*>{z<îŒÒ•º{>Êr©×š~à°‡£Åºÿæf}FáˆSñÛËÕ¢ÓdQ&_»Ô\]®x.ûì‹ýo~ãÂ~üðöKž ÿô»»²±d PZ¿«_}dϚ͌8†P,€ÖŠ.À0¦¶CQB0cr ‘\*óûCß³|—Õ 6"Øb¤UqF£gûƒVÍ¿²¸\#%fvÁñ«ÁÚB±ø7p:ÿÛ‘Œ?ýÔšŸ—íżÿ¾½µÅxÞ®­‘€€1SÍÉÓ4_mÔÃ4 ³¬hSÑé(+0e(ò‹¢€£•Šu>OO'7—й4U Ö³“qoš½~¡Rò­fÅÝk‡wŸœ+<—›5ïÊz½VõOºá§_¼ykùÑÓÓ7o.M£ü‹{û:‰Šô}W ¿¢½`ΣÜÌ­µîøÐ¯R*J‰Pªâh ­Å0ÁbZ¶L$B‡¹X*‘²Cw:q%° eµ‹……™¯8Q¦Î†)à¸]_¯ŒÎññÞªQ¦3L”Ö”S¥BˆÛœYLdòùÓÓ_ýêà[ï]¼sww{·³¹ÑøâÁño}ï²Òàè|l omŸ¿ûÆòñ0æîKE»fk†1MóB  ,’Ê<0r¾Èr…}›5 <‘ àrNq,Á›kÅ‚ÇDZØ:Ýé6+î`’–KŽÊÅÎng¥t1Dh¿÷»“‹KÅÎTz\ù¶Ï‰îE°âHY{¯Vh,h³ÀaFƒgã|©l¥Rïö€àjÃÛëÅ” Õf°Û OºáóãÑÅÅR*t”©{[Ýá0ZZ,¿Øé ¿ùæê4ÌþüçO/®Õ(FGǽ7/×Â’WÿÙþñ =<Ü>I³\ ‡Išç‘b™æJëÀ¶´–RN…&e2êXÄ@(ÖÛÝ A¥âµåB%°žì¯®”Ž:aÙ·æÁY/úìÉùÅå ÆèÑ‹vɃs åTæ’pB…„;磽íöü\éÛï^lŸú³Çß}oco¿§rQ ìGÏÎ~ý½î šFù\³ÐdŸß?ªÕ½½³ÑF#0Ø&†@{–IóDhXÔ"r’j›Ái*§™Î…:&o®–z“¼;ÉÞÚ¨t§y{”~ãR­àñZѾ·Ó¿¿ÕÛ=›ÔÊnœÊ+jëË• °·‡í³Ñ¾{YðégûW.ÏýâÃç¿÷wnl=Ù%Ëš­å¨¯6´ÈçKÖ¯þýC Œã;€…°©$Ht#Rt|)˜E E*—2ÊMݧÏϦ[øBËë†Âs¹ÃIš Vç †¾ËFJéoݨ‹MÂL!H9å.—RRNABè{÷öù«­?û³/×/ÔWËΤÕ,üìÃ-Ǣˋå/Ÿœ}‰88œv7–ËýqJ0% "¥dÁ±ÇIMêrŽI¡de¹Æ6%íI8î|‘ m†±^ª:žÃF©^­»¾Ëºãt¿ÞÚ¨æRíMs©ß¸Ü\lÏŽ†Çgã—ª—åêÉVç㇧«‹åÏÿö÷¯uûág_þà×6e’7Êäl]BC0&Ÿ¶OÚ½Î0Ír×wf´…¢¦0ˤJ$®¸\¨4Bìq²×æŠö †¾‹)FÇOO&®EŠ.}°7F±øþí¥J`Mãü“ÇÇÓid’ P,úõ€zÿ§Œßßþƒ?hüƒ0þ«¯ä_ÿkk‹v»øãí7ßÌûkòñã½A._ΠJ'˜à^or÷ÓÝhš¬­Ö{ƒ8Nò4ÍÇa¦¥:<bŒÒ8')¥óL`‹ížO+6ni'D›pŠEÛ¤Š0‚S¡«.!Ä)Xªß"‡]t¨4 —æµåc´=É“Tì´ÃÀãË ¿ä[¶E=‡’{ÏÚ[GCBI£êwúÑ Ìâ(Ë„4 ! X&çÏOƒJð†©´Všg¯šOãT+cI R‘Û<b"µ,ضEiÀu”ã\!ŒÆãàl”jj=êFBËbs%Ëq­ñ8Ylø×/T?~xšgyÑ‚íqÊmžg¹VS  ŒNqœßùx«\rK'ú­×W~ñËçí CP/»¹P'§#fñ,Í1ÔvŽ{ãåjQHgB¨è8qž§B”=ØVœ)‚PršN 0z’ê†O·:q*´6Æâ¤Y²¥#À8ûí!¸±TZš+ìO·76›ÐŒÀÕÍÖ³­6Fèí7–¿øòpÜR¨+•ò¬iŒéÇRåÚvxà9•F b4Ó»\f,ÂÜXd¶øŠ8%Æ@‚Ä0b Q«@*oåJÝVˆ4ŠVÙcO¦ß¿9×§G½(ŽsJ ç´Û›ŽÇ)ætFU™Ì,͙ŔR_|¾×ëNÖÖê[[íÿñºC1r^ð¹Ñ¦×®nÎ휌T&¤ÒQ*G£xc¥>ŠS­õ\©Š˜Ll1§ê‚q -¢G‰€”]>ŒÕB‘w¦*ÊÄ¥¦—ä&Îäæ\å:ÉÅåùB"t£ì8'®Ãê^Ñ·FžÇB£i–%ùÛo®îŸNF£Ünûçý,õz Ô_,àY®Ui–½‚;èó4×p‡A9Q¥õ$#e—È…ÒRIÏv'©,nQÚ*±³‰˜¦z©îž  à4™PZË¢J›¢Ï«%gfá$NSns‘ B "H 9Û€‚ôïÜÙ::î_Úh´{S%õxšF‰¸u}þ—wwS¡¯¬Uou§g£¹ùR¯ºœ0Î…RR‰¢d"ˤð-‹¡¬ ›Bϲ§i^r-×bÅ“TÏ•øL™/Ûˆ Þ4ORùôd²Òðjî|ͳ,êØìùñøÁVgûxT)¹œ’þ(¾÷¼ÓªûY.ß¹½öɽƒÕ¥J2š,´J”à8W1¤‰Ð$UźåZG;'qœæØÊ§0àÊ¢ —2—9£ÔfÎ$É\n)0FB™¢Û“Ô"hÕ›d"„`œä7Ö«ãH\])W‹ÖÏÚiC-,×RR‹LFò4'”XŽ5Ã>{r²½ÛYY*gRë OžœLâük ?ûàYœi¨u±äD¹Y®ŒF”œ£¦g3îôÂx¡è`„ ãT¹œY”¹\ç ŒS!•)Úx‹Dè²KF‰ˆsm ´9‘ÊlN8'¹Pq*-Î\‡Mcññ“öÃççAÁÙX®”«Õ*>yv–¤âú幇O8…"‰ÏÒ )1”ŠñÉþÙÊ•åj£ìÜöY¯{>ˆÒLQW ä0¦µÌµíq Æ( ÛÊd^r­î$¿±`L·‰ãpÊÈÆBAøüxǹí0‚1Tb{¯S+8Ëu‡bø·>ú©õÑGöá!ùƒ?˜ü—ñ'âÅ1úÃ?œ¼ûn:?/ÿñ?.ÿöoǯþ+%”*õœ/N§B+­ô¬°{é‹ÉF øâÅY·;éu'Ÿ}¶×Æ×¯Îÿø§VWkgç£Å…J¥ƒA4?_<îEW }­ÓÎ4ª¹È’cE1µ(ʳHÚ‹€Ë@¦T®LÑÆ¹Ò™0UÞÝÙrÐO–ªn-à»çÓ‚Çöϧ'ýx¹é¿}¥yy¥fòéÁ Vqo^jëùá¨\tÞ|mP²w<ÜÙ>[mzgÇãj£ŒÐËvüZ‡éål0„©P%ÇxLäÒâQ” eF)¶ˆv­*ÃRª®û¨ì²nh*Ö8K»à°Ç'ÓÛ•“Arw°1_SÕ§› …a*2—ˆ %„cŒ1&”@ON†»;í(Êî?:úøãíóöäÚåù/ï<Ûœ/o4ÂT¦I^«xÝD¦ñJ2 MVvÂn˜¦7Ø“$eØlŽ‘XŠaª ©º°²‹g îÓVÑêFªUä­’ýè`T+Ú“TNÂlšˆKË¥óQ6Id”ˆÞ8R¯.µàÿéÓb`õÑ­«­ûŸo¯/uÍW^Èàk¼³Ùx—Ò:Ê´ÔgÊeZj=NÃÒ¢€Ò ‚+°T/aZEr8È[XäÑñ¤áóO·ºe;œìO[׳©1æµõÊîÉÐ-xÁ<Í!€3ÌÞ,‹`‚§ÓôÅó³óóÑÿßýæÆzãÂjíý7_JÞÎöùÑñP\ ¬“Ó¡ëÙçÝéòRM(yÞ ªn&ÔÙ8ªûœ܄ˤÍ ‘Ë‘P´ì¡Ð@Ø‹ÔR™O…9Ÿæ«U{’ª£aºT±Ç‰ 3µRw‡õ¢þ$íŒÒ“nا±PÃQ2š¦¹6íîôÖµ¹Nw:?W\]vŸ¶Š\S ˜—Vð³ú·P)Ø®5 f”ky*M˜ ‡{F§&ŒzФ™B563§ã,°pÑ!‡ýس(&¬ê“zÑž Ð*Z+Í JòÑ4‹•Ù\,¬6܅г}4´ B˜§9Dp¶J(&IþôÉÉînw8Œîß?ãӳѷ–·v:O_œ—Ëžk³»……reIœ7jÁé(n̳¬q’,£Õ3¤n€\f&)ˆ3á2Ttpg*†+.éL2‡aÀé(½ºTD÷ã0We—=ܾ¾Q½¹^Û\©ì¶§;GÃ(×o]Ÿ[l“Ÿþâùí›KQ" „íßX/k`§BBøµ½;`!Žk!‚!„B)¥ „C5IQÕsâ\I*îR$‹ЀS† +ö 5k5§ÉÞ$ßœlŽ¿Ø¬4üö8‘Ú¼q¡rÞ;¾—$Â(OòY3~fÖBÍSyv> ÂO>ÛûäîÎhŸŽ\›=x||y£y~>2–<ÞíN™kuúáÆBi’ÎdºTvD§£°dÎ\c’ThePÕ¯­\Žl$S#Xr¨P âÒ’Çci/¸Ì°ß‰êEëËÝ~wœ¾}¥ÑæQ¦„ÒÇíiಥ¹¢ãò??\l>txÖ|Õ¹ogu¥&$”ZeRªÁ«auŒ‘ãXÜæ#cL,ôBAeÒL3Pqr)D†9gÃÒ" Êa³@¥J›D¨V‘×îrüùNßa䤭/s¡ϦïܘCPc|‡þíNÆJù/ ÿè þ輿ÿ÷§µ@=?¯67s@¹¬ÿù?/~ý÷ÿìŸÿé?-ÿÑù_??x¿xéš.•ò$Îg+Û3ÇÃÙPÂ(ŠÒá02ÆDaúàÁÑþÁw¶¶Û­Fá΃™ÉÕÅÒ‹^ºV±ÚݰV⇃d®À-î¢ ‚ÊáИ\j’ eípÛf¶Ï¥#æ[pÆE0'æê‚7CÄ5ŠVgšo...R¡?}Þ}q<Ö@ûÓüÙ^ÿÙ^ÿ7ÞYóv÷ÞÑýgçE7ëÁYwêSóøóç sM 4ȶ-8Ëį0sÆH­Ç‰N$¤F$•JàsjsGËa*¡Ï…Mq7”ÃØÌÐÑ8_*sŒÀóóp¾ä|ú¼S/Ú«s…/ž·êÞ……ÒYoúÍ+MÀ(„)¤ÖzvC#„^ºA8„ÝîD+“&ù£Ç'ÅÀÙX«Ý~méG?yÔh!Ÿ=Ÿª UÖžŠƒA~mÎ9e_N, S¡_¿P®BðãÃÑ{ךÁãn”IÓŸf^t¶ú7®Ìmívn^[Ø?è[ ííw_[ó¿üè±Ò¨àYFÛ¶¾šº„¯:ÊÊ€Q¢…¶”†BåœWbI6U†y\ŽSãs]´Yg*ª.¢„ÓzÀ&9}ëB2ÊÀ;›UBq;›‹ÅíÓéw^›¯ºÔuyo”1ÁRHˆ Ñ"HÅ+m~ñ‹gÝÙúÙûOúýé‹íö[¯¯¼ÿÁs¡Ì£Ç'o¾¾²u8 'ѵK³É­•"Æ4W:ÎD-ps¥GqRv9BƒHh ‘Z È0ô8˜+°n¨ Z*[gã¼è¢ÃžLj«V°ž·ÏÂõùB˜ÈõùÂõµêÆb1Îu{”Ž"±Ð ®®×?úò$ìjÉýð“½rÉÞÙ:ûÖÍæ³Ï_ˆÄHm<ß}×C4³AR!+޶I–Iݰ˔0®C#á‚Ë‚ ÌY`ÓTÂå2ÑòËMGC8ˆE7”Z›+‹Å4—ÇÝèàlüÍk­bÉaœ' BH  À#„%ÌbƘ0L¥”ãattÔÿôÞÁk×öv:Q˜ŽªE›Û|0Н®U!¡ÆÈG;ÝfÙÉeNˆ‘B@SŒ5ÀÈä½´ Nѱ-*3Å›RS‰|›Rs…ÖŽ`”ª M/S@ðÚZé|˜Þ}ÖÞ9›x¯–×å»gÓ/žœQŠß¼>çÞ!¡¸^qï?>}ëÖÒO~òÀAùùVS†šMù3‹QJ „`ÆêRF8IMœK (0Yɯ(•k­Bas‚ PÓL—´7È6ÎA?],[«5'ËÕ½ÝA«â>ÞëßܨqFî=;ërÃ¥ šºv8‰!„3?·™g€@)Ó„Ãah´ ÃôôtHú­\ûÑOonÎ1ŠN† Jq§))¹M•‘óE?“*ÎEÉõ©Èã5 âX@Fút-81ÝP5r<ʧ™^*óL™­N„b…™zc½Â(™&âöfc}¾8ŠòÎ$=&_>>Írµ0_:=þÝ\Eø« sÅIwxøü°µPRMaPðfTpB ãl&sͬ;F tŒ2éØU­E’¥”0 Ç¡Alª=è§KeÛ¢¼UàD÷Gëó…H¡onVÃ\Œ®¬”S©…2k-ÿo2ÆôÿëdŒøõ_Oÿê_ùu2þä«XÔ/ŠÙŸé÷3þ½¿7ýKçg÷c ðÂr%a4C"„fc³µ–™áÜ ;õéçûçÝi1°/^¨ÛüÙþëWç”F)×w{ãi`Ù¾%¦™.XábœRI\¦´* *!3J$Ñb(¦(;æ|"seš9¤©Ô.g ›zÑ…y{˜„¹Z©yŽM‚«­À³è(„’í“ñã­Nµè”Ënw”p‚l›J¡Ê_DÓq»Ûko]n!:«F_Õþ/yIZë™!£+t®'ÜbV. Ç¢ìy‰DÓòij 6¥øö…‚h’ÊË‹Ån(âLmÌvNÇȘTèfÝŸ„™j†òyYQBgï`gA5Úܺ¹Ôî…?úé£0Îmßéö¦Kª¿ìœ ÃD@Zegy¾$•™NÓWèàW3'„‘Yu2Ã\x¼¶PnÖËŒPŒ1ÁøeFpf{7Iu®¹Ô&‚`˜˜`„ VFåR€ê¾› QqL”©n(W+|šÊ“a&•q8kÙ(Uýa¼Üôm‡F±VÚá¸àÛãXˆL̸³îÙ3þÒÿî+„Ûí «µ‡OÏÂ(_\(GBÏ—íL(b™‹ŠÏ]Ç9èG ßÀúQÂ(á(…]°5–1Y”#ŒŒT2ÎÇ@jåºä ³qž+ã26‰³õ¦—*Æ9ç¤Y²[7p˜Ã°kÑI,”ãX<|~~y½Á"Æi§RJ²L: MÚ½V£Ð?¬-4¤³g}µ€÷ò%>ç ÊÍ BLÃb”lH ž¦yÑõÂL¹œ …+u9Ì$8åîáX}ûj­3É1BËÍà¤sŠWš¾ë²ó^8C~ÎÜf7á«H¾‚3·Ûã{ޝl¶>:N²‚Ç‚G½¸^à£1€Hæ¥À›$I”&ÏŽ³4“°â"„X”+4Å0ÊaÓלñ™¥Û0MŸÔ<ÖžÊ0Í/µü(ÓC‹’(”b‹“8O†µ’³X÷„4¹q®›– V»=Úé<ŽBZœ¤“I2™8Š¢le±†Aà×m@®P*õ 6 ,M¤å[Ä–p¬-ªÏ§&ÎÍbÕ釢ä’A˜¥B—zÜsU/“Ú¢èÿa2Fà?Ýca5zúÜ^Y,ÿÞo^õŠ.wø 7«Œg7&϶Þœa w÷ºŸžþüÃoßZŽ%¤o3‡™³~ U|4”53`0 3£T–+‹ãÔÀšI*‰ÖÐaš¿ìHŠ5/–h$ø\‘{llq2ÍÔ4•Œ‘«‹…Qœ o¬–ÇÓ¼?ÉfÛ½˜`îð½vˆy÷ÖR˜Êb`C7.ÔÆQFYn9:=ýôÑÃîq„}Ëò8ç”RŒñWnEB©Dˆqª:ìE †‘”©Ð“2šb(CSv‘4¸æ¡Q"§‰œ/°§'“FÁZoz÷wz„‘RÁ¾µQ ù½w.xE×vm¦aô*†3pÞŸýüé£ÇÇJªÿæ¿úÆÅåÒõ‹Ñ(BFw»”ÍP¦,Ÿç02Éò,ǦQœ‡ =)Š!§N`¡QÊ Ðoõ4§c´Xb¿Út'ù8Õß{mîÖ…r¦ÍíÍzœ«++¥¾µxe¹4+’Ɖür»ÛgÃ0¾×Ÿk#ŸÞ;8<9 \ðé/èÞy{¯]´‡±ÙIÂJ­…”Rë(˦i:ˆå Áaš!b˜dŒm¢Jʵc°è…r±ÄâLžÒ u÷|jÖZÁÙTø®Õ …cÑ¥òi/ºv±^k™Ã#3Ùa„¿~üjJùéÓÓ‡{ƒ¨R°‡&Ig¾C!ȧý0Î"`€ç”µŠ»a’ ÉV†m ‡L4ÉÇ*—JX “J(cQ»æ³•Š…møZÃBû±ÖBpu¹ô[o-ýÖ[K+Í3úìhxÚϱÅÉóýA¹ä~ñø”Ûl0Œ5orÞþ_þ‡?çéðôÙqÁ¶]ÎmÆ!¯^iž•3ŒÓAlR‰¥!¹” *^I©¸`i { E6É­ÜX«5Çâv«ÈÊ>o‡b¾á?<š ÏG ¥¨Yq)F¿ÿ›ÍFÓ—·"èe$ žé ˜â™ÁÃÇww¤"Ë_¼8›¯8ŽEÏÏG2³³Qœ%u)àQ” ¢˜$W#…!€„ ÈX3bU]à[ÜbN3 ±`‹%ίùĵٓód®È›y9%ç£Ä³Éƒ½þý½þåå&ad{öýþÖÉä¤ùžõô`P®x£iJ1*ö—wŸ¢hštÎ6|¾T*»n`Û¥ c‚øÊÑ2—2—²FƒA“[h¤T¦™Í} sFˆM¡Ã'úh¤ÛS½XµÇâRÃ:èÆ€ÀÆgýx®â–}~ØžŽ§éwÞ\ñJžíÛ”SLðìéžõãF„LðìO)äÞ^÷¬=^Y,=}qþèùy½ÀÃI⸬ìàó^˜‹Ap:ŒŽlªg5Cgš3l4 E[@ àuiƒÆG)<›˜VÂvû9DÐa$°IwšÛ \z6J..»Ñi7J2E!Œœôã{[Ýg‡Ã+jë+ÕLêíx¾åp’ -…œõã_ÕÄ3WëÐÁßùÍi.Š%¯×ŸþÚ7/ ÂüîýãßøÆÊ4ÓRÈû§ˆ³ŠCN3ÉŽ(-N“±6Úc@CÂ@®!à §´dËndjŠÀ\¬Û½P&¹Œ$Xo¸Á“AúÎå„èñÁ°^´!RD2`f£iº±Z}ÿ—[–E=ßê÷Ãõõ:Àx¾üô'_^»àøãO!æõZ&™¯.ͨõ™ÓLçÚŠFØD(à3Œ)µ†1-pYry{š6ÒLSY-ØÃ,×miÀ~?á–|k÷x´¾Xb6 c1Û?~åV4 éK'_!„“I!<>.§”Ê^½hw:c¡A£`iÌÓðrËK%ØäBxvñh0(ÚcAè 3 &‚i#=n*.êE¦hâmÙŒùêEfµf÷c¹ÝI(“X\^*žôµ¹`fR›Yo t:ˆ??×–Kîö^÷¼`V–«£Q|ùbýÿèÎáÖÁ¾µyz:.• ÂYƒ@øÊK^k-•Jr9MÅœ\Lmp^PZÛ$§„iäN$s9-:¸šF€vzi{"®´¼¯¤„¿Í2µÖàŸü“Ò‡Ú~èL&èÃíÅEU,¾L·n-!¾÷½pùr¾³Cÿí¿u?üÐ~ú”ÿÃ8 ]¿üý_êŸý¸úÞ÷†•€÷"©ÍÆry”ªÕ…’:M…–z¦Q¿´4ÀóÎÛë«+5£uÁ· Fa˜öúaÁ³´”¹Feõ&ÉÆ|a·/*“Sœöú‡z©¹Ò@€ÑÐ:Š®»9Æ^.s—3eHц™4ƒ(‹2Å( ã|¯®µ‚À¦MžC1‚ƒi6S}KÍàè|’DÙ«óY®ÃQäùö|³ðàÉÉpýãžEÃáÍÍÚÙé0Œ³ÙìËs±¿}EIÅ‹ ¥0Ó¹T‰dºRÅ)‹ÚàL¤ãŠ¡Ô(àêdœ§Â+¼\÷¡g <ÃãX,ÎÇqnf&b_³E{•ž7o,½~sy~®8\+],؇'Ãj½À€æ ×*îá0£RÌrCµÅ `¹Ç‚X$fÈ¢šQ›blS‘êÀÂ3—EØ ³¢$ƒ0 \®Œ!vc‹á™âºÖ še‡`4…TæÉn÷þ“³Ëëu €Ëñ/ZEŒ!@ðú•ùÏïüæ÷¯Ž‡Óç·æŠO5ZU¥5øÊ®#œÆO¾|1‡ƒþØ-¸©‰„æ¹Ê2™@ 4F«LI›ÙíIRóp®†*–x­îìv£I*)†a,8#I*'Bgjfe£_uL¾²j3¯¸B¨ÏïVªþïÿמî”PqœÍÕÜ8—á8ö·7šÎ•íLaCŒmc`g25:#§ú\TDf¤€V2‰.¹¶ÒÙr™†9@Ö};@Ã(‰’ü¸gBÇ©JÏ×\!´”ˆò=¾Ò |‡ÿä£]×åVª¾g ö³çß|{í£·ý»—¿¼÷¼ê‚““¾_.½ïzKêu†»;GÓn½Yg,UL(͉„ˆ¤=–QZÈ5¶° Ä@0B«>9Ÿˆ¥ß>Ÿ†©t–&y½ì\V¯ùKsÅ8Wi.gâ?P)õʱÛhóÛ?¼qq£iŒ |›RŒ8ëL0¥e·;Ófݱ߻v¡6JôR™eŠQ¤^t¦“B!‡„lĪU R°”26 ‹S\°À B©o±Á$®,ßåïqÂ(ZŸ+xJOñR¿7 —#tu½V)º@ë™´µÐ,ÜpøÝooÞùd÷­7W?øÙ——VKw>zÞœ«Íþ_qÍW4f¥^®9hQŒåJ4%ÜÌ1‚™05ô“8“¾Ís©4€®EBƒ0¿²Vuejæã«¥~õi8³ÿ2_:®_™k¶Š”`!Ô«óa"¾xx¼¾R4 Q±àDIÒdž¥R,faÂ4Ðb(L%Êlh1‡¡L×cPj¨ @@"é[¼&%óeg¹æ„„ÒE‡þŸì½IdYvçwÇ7O6»™›Ïîî1f 9UfÖ@ÖÐ]$ªI¨‚ºõ%´ / úÍV«…»Ùd±X$+«*323"2æwŸG›íٛ߻ƒž,5À†6½ P¶0ÀVvqßûŸ{ιÿßQ/ž©YÓU3/x’óóÁ´ÎÃgG íR£æ`ŒòœÝ|kö«Gû¶­­,7ÂIp²wܨ:ƒîÀ+;|Ù!½ñËG[a’îlM„p!Ìs–œAHÄð‚ W͸à£D6d¤dÀ™’6ŒA€bð~šZJ8;Ë~üãhv–Íβ¹¹B׿þõý÷Ó?NÎOƀ˗s„@»ÍøÃø`ÿGâùŸ¦þðŸí­.’S¿âh:Å£ ûøæ Ä$ÈÄ;×§÷ŽGçèÀ¿ãSrˆâÜs'O4C[]®oow®¬µÆ£ÈRÑá ¾4[ê„ÒÀâ°;™©i»Ãl¾¢F9µUAˆ )Xxêž&Æ)v4¦®3EAÅYÀm]Óˆt Rp8‰³µ¶›2iªähâýN!lUÌaÿ‘ŸüîÇËs-¯3Œ³‚ë*9<Ü~k&Nr×Ö|µwíJûÊåé4Í?Ø|ûZ«lÓ¤À\J„Q½U­OU*ÊÆúñ£{/7^î>y°^-ãFEÅ  .¸N ©TA‰­„zĆ¢ uƹ<ìÓ#åÒTɓ׃…¦SäÌOù¥•Æo°¼¾Ý;wðûZH„<ì@¢(³mýÂrãÑ“ª«ÃA°¶X=ê†k •a¦ DY³¬޲ùª>ˆ1–é ÈÿbãÖÕ©Í#†ˆ¢)_ߦ!dÚF§¬?{¸ytØ­´[iâ\B5"Ã\i¸žB-Á#°„¦A .%Åp·L¹ZÊ¡AÑ™Ÿ•lu4I1FeW¿±6uüÿµ•¬”BáhGѽ;“8_Y¨yžŹ?¦=.¤Bq(ð|E}±Ý÷l%Ê3¡§Ó(GŽn@Àý$Š iÒâœ<¡I©KQœpS'ñ Cµ<]tC9]¢/OÃÓ€}p¡B0„ùæá°æéÂ(-¾yÇ"ˆPçõªõðÅÉü´·âGIž¦Åó—'}páÙ‹£¥Åú«õÃÛ×[³MKWpÆÐ¯»?úã_þä‹Noðôþ+ƹY²“B r. Πhƒæ–QVPZ1ñ$Ó„d)Ƕ Ó‚KŒU 6ý+ å“^P+›ï]oŸú)¢$Oó¯!ŒB¾Ù™–¡þóÿþ»wnλŽñøéA«Yºr±ñ«»¯1Å˳¥I.Ãqdê¤YÖv»Q³¤Iˆ™[‡ƒ™ 90ŠB8)°­rˆl(ÂBæqÎ…®Ž6m•¹b©@XÒÑ^/j¸Ú0f*†UGøé$ÊšÎ(È—@!¤¡Ñß~wÁµµ­ƒa¥dœu&gÝ@ Ñlº%Ï|ýºóñG«Ÿ|òôÎõVÙ¡?ù‹GsKÓ_÷àÄ[®©jÊöæÁæúÞpÙ•j’Ã$ Q0Æd fT©H&ê–RÄÀ3•`ù?l1†Ìϳ_ÿ¼QbÀÜ{£Äç1;Ëæç™iþÿ2ð ððéƒêüjÿÚ|IU)!x¶f=Ù”Œ:Ý®úqŽ0"”|=C[ðñ8îõ‚ÍÍÓßþî婆óɯ6¾ýáÅ ÊF~ xc¹ú|ãÌÑ—BJàZÚ ,À–†Çat<j6œ¤<ãÂTQƱ­Jˆ !⤠sL=O˸$BòAÈ Eq òº;:í¢vÝö,õÚB¥çgUW»±R*›ƒIV±u0z¾ÑY[ª=Ûê¾õÎâgöó´ˆ þ;?¼fÊpÿüo_þá?¹Gé_üÙƒ[W¦ƒ@å9Ì\˵f›sKÓK—æÓ„bï ;ذP4 ã>‹ B„„‘iª®:%{f±µ´:«Úg?xqÁÖ‰x¹=@TuõŒó$gQT( -˜€“TŠa¨ðØgUS9Æ«3î(áUGM2Î?í‡ß¹3wÔb˧V28„EÆOŸ~ñùë»w·>ÿüõ½û;ÓÓ%Î8pi¦ôóO·>¾=wÒ™Ì4Ý ã÷ŸÍWU @wœ,·¬g'Éå¦Î%Šsˆ!V°ˆóäh”T ‘qtŒjž÷ƒ+X`„†Q®½¤óA\ #0WÕ:“´Y2Nz!ðÚBeëh< ó…¦  ¥ƒ&©ki½Aøá; #?ùåÛ½·òìåñÕKÓµªý×?_北ƒÞÙáÙÛ—Ê{‡AÙ3-Û2-Ã+;š¡*ºªÚÆÒêüì…™/~ù7÷¯¬5†)ŒsåÒ¢‘‚˜€&„Š®PˆLŠø Æž{A¶Ò°üDÚ:’žô‚Óa<]³.Ì”¦Káï¼¿Ü rC#眧spæ`öûA¯7ùçÿÝ÷®]š^ß8ýâ‹×󳕅™r»åõ¢_Ü}ýÑõæQ7TìÚÊþ02PXÐ4 FaX2Ñ8IŒpƱ«1Hj‚2¦©$r$TOEA?eƒîô‚ª£ÏUô—cS§˜à‹Ón×OWÚî•ù²cªÃ 0.ý0;í‡%Gït'�¥Åâ\õÂÊÔÖv‡ÒEð{7kU{¯ûôáÖ7G§®Ó ͇ãÉÖã×ßúÁ;í™ÆÂÅ™^gØ.¡_}¾!éö'TS¦Bdb9¦Xêj%ËÆ9§A®ê”gL´=…¥é‘c¿ÂäÖJ­äK-§àâþFÏÔéLË[^¬C “”}]Rp‘fù—÷wîÝß]uò‡ÿùÛGÇ£ûöïÜœóÃìŸnþð[Ë'ÝÉ\Ó=›äºŠ±© g½áLMr@0¨Y$aA R MrŽ`!¤(8q5†iŠa/¢Ž‚4¯;j/Éýa:]Òü0cRÎÖ-M!‡½èæ…Ú꬗Üó(e/_ww‡—.L}òÅöí«íÃnÐjº{‡Ã8-îÜZøËŸ=ÿ£?¸¦ìßþ»¯þ›ÿòv¦¢LHJ‰íZŠ®¶Ñl×gZýîðÉ£w¯7&“ðõÁHÕ•I1- 6IÖiA1 3@¬XABQú~šú?iüåßÿô¿5=5Θ3Æù[+µÁ$54ªP¬P”\.Ûoߘ &:?Ò±‚--Ö-K3-íú•éÓ” –æW–k¯vúµ² Ž3^ÒÉé(m:Ê«ÝîrÛ¹¿=|{¹2ˆx\ˆ™¥Š«rJl!â~˜««C s.2Â,5¢)4Hó•ºç€b”3!%ðììjBJ?È7Žý m·Q6z~ <î…7צ4•Œƒ´Vµ 7®´Ÿ½<9<õáÇ]¼ûåîÉÙø;¯Ý»¿UöÔJÉH ðÆ:ýïŠZBfy¾õr/˜„SUãÞ½ EÁ¶E0\€°ÐT @¤ä”à ÉK–PW1¢^6o,WwŽ'\JÏR=[•@ÖköôtEÕhË+Ø9_Œœå쫇{¢²kܹÞ~üüxm¹ÞóSM!²`“B@N&a*$Ah®n®w²µ†z>Ü›$®¥È·ºiÓAn:J,…@6L`ÅÄÀî$ÁaD ’À4+^O–šŽg)ž¥ª Q)öl­Q2šÓ1Õ_=>~¾ÕY™«˜:UR.›§'#ÝPkU[Wñïýã늂?ùÅÆÚjóèh8êôjž¶³sViTÞ´sÏ‹®ª¡Î/·s¨œöã×ëû­)ë矾’”JŽÌÑ4ˆLа¡(ã8)› „"¤LSHeT!ASWö:`±é\^®]¼Ð&|fÊ R&¸`Œ-…{{ý…ùjÉ3zýðÃ÷–^¼îµ§œNÇÏ$´˜™r‡IÝÓctŠ’8 3¨‘b·3n–h7`¶Š!T˜D®† ÄY‘(™ªB4…0. %Ú$I)Q –_lÙAÆUŠ(A“¤0Tlè” èZJÉÖ„qÁmK]n—\Gÿ«»;€Ë +S½A8Ûò¢”om÷8aZ°¼øøÃ‹Ožýþå õSÅ4Ð7ýø7íO»d¯\Z˜$rýùöáÁÙTݘ‘Åy §Às&J†!–R$…°T:‰3D°J¥SLpyÁ+e#N‹(×/5çfÊgƒø|`‡s~βþòþöƒGûµªµ0_™­Daöj«*[êTÃ9ÆÍŠ9LËŠÓî¤]Õz“¬æj~& †U b¥jäjBÊ~˜™Š”€Œ4Š€9G*æS!bcñò”1I¹¡Ñ(ÉJ¶–fìlƒl¾a7J!(H ]£« •²gtÑI?"ö†‘€1ñ½.ôûὯö¢8¿z¥ýù—ÛY4JjJ§ä´æ§üúö„Wus¨˜¶q|ØöÇÕ’zïÁfµD9R2aPpB<]A˜p! -¥Xï$–ªè œ$LÓÈi7èùÙRÛ+YªªCSÊe«äú¥Vóص½Ýôã˜P\«˜ã¸˜kº‡ÇCÓÖQQìŸø3u}åuO?+55̱” Ëb5 Â~˜éTœ*DPbÀ’¢:FEÁ™ŸJS¡Q–—LµH©PD™À³µû¯º¯F®©Ì7M!ã0$»ºÒÈrÖjzyÎ>x{a¤û{½ox1в/îï|÷ÛkIœõ`óâ¬ýðñQ£U…0Î߀VK5o~¹í§ðàpxtÐYY,ŸvïÝߘiW(‘ QP$Ð@*fbøoÄøï'ý³?™úèÃ|’2ŒÑbÃ<'ýI„tL !<é…×VêͺÝ%BÿÅ®šž5‰Y0 EÁÏ:“¢àîQ…¼ÿîÒ«ÝÁlË &qåíºõlãìêríÉVïÚrm¯ÏVMK#£bÚ£LÀæé¨áÒÎ$¥š*‘@2Nµ5=Î…¡@…Ð’ö†¹¡Rƒ°PÊa˜ÍÔÌ8cà ¿±RSÖŸdï^šº8[¾8W>è…Q’§_˜ö²B¼ÜÌ6ÝùÙòÕK­ŸüìùÊbmíbó¯þöå[ó 3ÞÏ~úðÝËL$ÏÅßµ"%BBИ®Nµë™Dœ Ç5ÒS†t’š Gˆ¬1žL&i®R ^m'~¶X37Æ–I™„UGmÕìaÕK¡H3õnÍ-ÍWG D°H Îø~píwþñ;·æûýɳÎÛ7f76NKžI8íL.Ζ_í ./Õ^Mn.–O}æj(ŠÓ³aÜðèóýá\MÝæÓ•Pňc„$$Q.m@)¦fˆ SaBÂãQveÆ)W,Å4!@ÕÑtŸkÞlÃù(È F%[Û8¯”­é†³ºÒxðôèîƒýÛ×gz£˜RüVŽ®—æj(iQ¼¡¥Šo, 1%­Ù†@´È™ãYX¡“*ÔÊ2n«Ã$Ê¥¥ˆT¹ŸIG#£0=7)Ü8ò§*æíÕz«j=ØèPŒ‡A63]þÎûK=?…” !Ь8ÏlÞoemµ™&ù_ýÍ‹……êg_¼®WíZÙðƒ,(d»jû“¢žAvŽý…)cã4XiÚgp4T6ð$§¦‡£ÔÓùY JºÐÔR–Oü:†3¦Q¥áýa¢Qj(@8JxÙRºãÌ6¨g(w‡+mïÚRÕÔéƒWÝ“^ø{¯LO9–©ìw‚½ƒA¹dhMs6Ó*MO—þÏó ì¼·üjãXäéò|%å„ñ¯kÈâ3H!‚s¡é*&è/þí§ÖÊz°AaTPŠBuMѳ"f‚茓\§T£¨3É,qÎ…lU­Î ~ëb=Éø(*L[ÿ½ï_.0ñ'Éy+êœ z°?€œœù®­Ï¶KYÆ[ÛïEg½õͳjÉÈÓ\UHÉÑñJÓÞä‹%ȈF…§ãˆ ;ñóºSnR”q©((•Ð’«Š«“„ dkpó4ÐU¢S<ó)Oëû©puƆ¹ç5O¿±R«yÆçÏOÏ&žgÜ\kXºrÜ‹T•¼}½ý·Ÿïç«Kóµ_}¶µ¼X_Yn|ú«W·¯µ @¹Bþk_¬JÍ«·ªaÊ!€¶cž þôÿþdaÎêéj.ƘŠ3…êA®¬ð C>HyÉ QR¬Îza.¦<Í2U.e½d\^©3ˆÓ,]5TÕP³(c93 åøgß››­:}üd¿Ñp;'ã›×g ÅçÊO7»K3¥”Ë´à) 3ž²<`ÌOFIÝAI!ªkDhŠ!ÊŠ0ʰkXŒG£˜ª† sæé¤à@N LRŒ‘Ÿ²Ë³ÞꌷÒöº¡®]#aÊ ÅRʬ঩¾>ùæ*K Õ/îÞ½½P*™õÉÆûwï=:¸z¡:Û0 qÆÞŒñÊomÝÖ›ízTÀ(c#˵"FÔ –k8¥(W©+¡ÉEûÿ½ñ?ÿÍ?ú§©jų¥n+¯O‚ª§ë:u,Õ1è0bo-W Á}?ýè­ö|Û‹s±{~÷ÃbY!÷öº3ÿÕúñoÿÖ•V«ôgÿþÑí·f£(ûÉ;7çŽN}ÎE¥lœú¡Š«Wme¯Uu2‰÷OG—vü´î*ãT– „–s~2Φ\M˜1f(#¼;ˆª–‚îÉLÙÀ˜ÌÕÍŒU¥ó 3e‚R²Ôt’œ=ÛtFñÍ‹éš=]wžï a9&¡Êç¿xLFk‹ö FŽU—¢sÎ¥jiºAEÉi¾<öjæ(᦮Œ¢üBÓÞ:žtÆÉÕùò«ƒ‘D, IDATå7Vj£ å?úÎ*'´Þ*kºòôÙáÝ»›¿úts¶]^»8õç?yZ«Zž«ï/]hÝ Ž‡É£¯v÷öúwn-„qΘ˜myO×Ï !Úugspq¶ôâÅÑ­+Ó^ž gêÖ'¿}sæÉ±iSàéðl{–~âÇ «Ô'BÁ’`¢SÎ%4¥éaÌ .ÆIA4)<¥!W#ǃ8c¢Z2J®>ŽòqNâ¼Z6$?ù›Ïw™«KµÁ ¬•Í…¹ÊÎþà¬;¹y}v÷`¸w4¬¸ts«›§ÌrLñkÈÏ7Uëóáæl£5ÝôS”#”2ˆdæéX%òp\” \p¤4I™Jh’ËSÖA?^œ²fëöëÓ`¹å,¶ÜÍcyÚEw‘ëêßyo1GÄmÔâ8\¾|qôòÕÉ;7â( â qp8|ûzûáÓ£éšÙ„ÂË+õ×GcÏÒλ®©Æ™è‚4˧JÊãðFÛJ˜2ŽSÕ(ÆaXª¢4 Ï aZäœO9ÚÉ(½:ëè*=ìÇ—g½(ÃIúö…š®àÓÉ(Ì€Õ’ÄÅÐOÆAVòŒZÅbôGqgX¡§§þüÎõfÃyøôpg¯¿²T/Âhjªœ€qßøhþš Ú¹¡æîö±ï§G]·Ñ²u=Ê3 4GcD’KC£~’Ùš6]1úa>ˆŠ™º¥k´?Éfö`’Q‚߻ڄ "J C¸5[»tma¤ql¬¯¬Ly®~p8ø7úàâÊÔìt9-D’·®NïûIÆ<ô¢‹Óöë#¾an äQÆVæÉæYZ±ÔI’ ˆtÅ<¿ž2NˆIèT™­(¹€a&§ÌÃa:UÖmCéM²©’qm¡æbàgã «• ×ÒJ®>ð“á(¾±6•syÒ™ôG‘W2ÏzÁY/L“leyêùf'ô“K«uÎ ÿ!ÖW~3¾~~‹&I³—O^ûaTu©¡B `!LŠ—†¡`?IUJORVµè$Ê{“¬îjaœçLx¦²s:ú  âêµ²ÑnzíéR«]áDyôp÷oÿúùÝÏ_ÿêÓÍÛ7ç)ÆÁq˜{®Îs6ŽŠ™ºõäÅñíµæîÑ(OÒŠ«½ÜÜZmbÇ c!äh’•lÚSC*µ1Hý¢é99ca–iT±5%H…RWCçÆŸiÎ{a^¶h–‹³qâǹ¦C'à óƒtýÀ¿8_nT-Æe½fUJÆ8È:ÝÉ¥•†ai;{½N/øø½¥I>~~üíWÖ_˜º‚Ê…<§i½™Àÿ;2£”! !ÈTrGÜgY‘q! "É8—¶¦ÆY~cÎMÉtÝÞ= ²Œ]]©õÆI–󫾟f9ïæl(Ð… ‹ý‘!ô‡ágŸmY–Ê9/—mC#ŸæB†“ø´ã_Y©÷ÑLÓ;ìŠé§Œq¹4eõCÎ cVsðÉ(.™B… ‘äÒT˜Ÿª S¥R²^ê … ÉMUI²âöb)ð¨™*i×-?Ì?¸ÔˆSvÔ‹Fa¦*¤ê %?ñÃtªáT«våÝ~8ÛòZÍÒÞÑpºáÌÏV>ùtóøtüÑûËGû§3ÓS’´(À7¾Iò ÃCJQèÅË‹ºídB ˆ3&‹ßˆñßÝžu°'W¯•BpË%*¡a&f«úÞ0Ÿ¯³ ëåIX1ébËí†ù…ig¹íýä³mÛ$ïßœ?ð“™ÕYLp’äÏŸ½x~Ä ž$Åü|õáW{AÞ¹1÷ùƒ½wnÍ?ßêVûb{®]jVÕ»Ÿn´ç§åyãó×wã7«zgÜx}pÒé?{´¹°ÐR¨d‘0RÍÒLÆ„5Ï@¯ºŰájÃôBË9&QÂÖfK½hkóåƒN8 ÓÕ¹JÈ Yq.ÏçEAr¸ßgë"à¯>ÝðÞb©B:“î(™k¹Ëó•zÕÚ; ^®ŸÞzkæóû»¿õÁbÝ?¡ Ê7¯¿oÜ­Ï&Ü’íØfLj Nm53h!!åÀÒ)#ÄF@'ÀTÑ³ÓØRQɤ»ýx©nîvãQ˜_œv¶Ï‚þ$½4ë½>™týäƒË E3gV¦‘­«¦ªêj8Iž?;8>ýøG×67϶ößûðÂÄO¾|ztq®òúØ_[¨ìíõã­šu÷áá7Ú¿x|òáµÖ0P°­£Vˆ¥‚‡ƒšc ‘†s MJv6)Ê–¡b®Sd€b¸ÕKU‚*&Ùì§ FuG}ÕUJ–›¶„ˆIðÖbÙ1U?.¶Ž&kó¥éºÝªÙGþ—ÏN¾Z?»±6¥jôç÷÷¯®6 .?{¸ÿ[,ª 3‚ «ß(ñ›Çs­V­2=Û($$HI²p5Èù$e¨b•â½AºRS •lt‹ ëÕÑäÒŒSóôõƒñå¹R£l¼Ø®Í• .×÷†ï]©_^(E[\›3jÕ• Êw6N^½:þýß¹¹²TÿòË×ò/?ûæüOöâíëíÁ Ì ~uujc·Ÿe|m¡üËGGï\iúÈŠÞpRv•Ý~|©å朎¢•ºäD'aÁ©©—‘Å0râ§늩’Nt½mÛšòê4¼ÚvúAÞ ²wW*¦F$„O|S£³uûåáøl&éÍÕF»îØ–úçŸí]]ßì”=ýÚ¥–¦þ×Ïß¹>m+R7¬œs!ÿÎüÿדE!"h~¡5?ÛúêÑ+«\V ÐÈoÄøï;ïk?ýëbõRjÒLSô0“e]Úº9J¸«+q. ^lZÝ€[*¼2ã [C×˯Æ?½4WÚ9ñ£(Õ ˜dÜ­y„„(ÏŠ{vÒ(»v¥ý/þÅÝñ(²muoàZ †ðøÌ¿²Ö\ßî½}­½}ò¼˜øñLà ’b¦šntü ázY‘¦E!¶U Ls!ʺô 2IaÍ‚UKƲaã ƒI:_Ñk–r8LÇ1K A 'EÙVK¶–11ðÓq˜ºR-AÊî>=Þ?ñ¯¯µ’´8:s8—ýAxëÒÏŠ²«'Å×Ð'ðÍ&“çù ”".ÅË'[ÐÔŠ¢ð „!ȹf¨A  R6@̰£Q”CÇ Âq"lƒBŒâBÞ¹PuMe¯+¾{¥yØ‘ºBC! %†k`Š¥›[§¾Ú‹Ãtw¿ÿèÉá{o/0!»ýðÖÕöãÇA¬+x¦å úA0‰K޶sìß\mL2þl§W/éc“$o8VÎ9ç™FP!õ0MêDÈ*A¤f‘¸ºB®åÀÐÈZËijº£Z†z:Š'IqeÖC•Í‹OŸ¨ Y˜vmSÕ4Ú¨Y†¡ôÆññÉø½ÛóÏÖO»'ÝÕù’?ɦ+zTœ+2€ÿßú «xšfùQ<Ž“ý¬U¶0Ö²"K™D0Qø P0@ôB¦„¡ì‡ÅLI;$aÊjÆ~/êO2U!Ž©õ·JA.±©#‚ ÇBÆa²ñòèî¯ß¿³Xäì¬~ëÝ¥/îmŸöBÉî0¾´\µÙÑ0”Büdi®ç|~qríBý“û{åš…©«BñÑ8u4`kÊ(-LÍålâ§H£œbMJé”KZ6„¡(' • r2θžŸEÁQ§lŠá(f®©*V)’"Ê9—à°u&†¡î÷FÀ“^¸4Sj×ôÝ­ã…iW×HÎñ×Ð7]O SÓ5¨ÚÎÞÑéhüüå¾ié5×N ©*€B%åHÁ¢f“N¦\2ˆå(í²Ú Y7(檺cÐÇÁ\ͼ0SZ?š¬6­ù†pĸTu•3Ž:íø/_ïï÷XΆ ÁGgþìLÅÔÉ_þ|£Õô,.-V<>°mÝ5•×»ªS ?ŽuC=†3%Ê$¨H¹¦âŒK ÃÂT GC\Ê”‘𹓠5,$Db¦¬x¦z6a¦[e#È¥¥¢éŠqÐfë¶­Ó¾Ÿ3®,”gNœó0e“¸”mvºüx£ëšÔTA4‰–[ö8ù:ÕF¿>9Ÿ˜ƒä…à\p¬ADœ¨åL†9R°°tëÔOKè‡LÁÐÕq/È(FeƒöƒT#x¦bl[§“Å)["´}2¹4cg9ãDͳ‚ªTÑ Á9()œ$÷>ß|ôôˆs^ä¬Õ*Õ<ã_ÿéW%Ïìœù——k[£ÕùJÄJÐë½a»¦÷bÑ…Í’9Ž]Á®a ŒSR1 €ó,Ȱ­²~(u l œø¬l IÆF¹«“º£¹Çl¾fL 1Œ˜«“³°âêWJ‹M·ä9%[54¢*$HØ`œd9+»úL«ô—¿|]±ÈË*’WK… \|]ê?wÐ|³3™yÎêžâüCG(þ'ƒQv2Râ\¼0h‚ Ï„IÔ©dÒf<­Ú¤à0ç¢åbƒƒQ^6H!äÓãp®¬K^Oæk¦”ðöjãh˜Ø¶Î¸<×c„Qˆä’å¬ÓñOÏÆ¯·»¿ýËs3å¿ýåf»é&éBÛûôËí;W§»m(»Ã¼ª#×*3sÎ+vE ßO¸©„m"],'RÊ ×m%ôcR3Ù0g˜va\À“‰˜+“AÄ,˜2¾Ù‰ÆèÔÏn-WT…<ÝîQÆ\WúIñú`týbcºn¿Üì|õüøí«Í§Oö—[æä¬uûõFy<Ž CGßX¶š®©P(8Oò"Ì$@“š”ÂT˜¦U ¦å””5ŠMER¢`¬z:Š2ѲËm[Ø'׿< àé Zl¹Ï^÷¦<µZ±LEUÎa´çÎþœqÆX÷ÌßÝ뮿:½}cîŸn¹®1=å|qoûöµ™O>ßùè…ƒn8öãvÓ[?öW¦¦ŒËƒaT2PÅ [pßÏ[a©A†‚ ­dT£hK eËS&©@X*¾·?®˜´nk¯N‚ùºÕ®/}ÏRôˆs>?eß\©]œ-¥Lìw‚qTìV*•’õ都ë«Íùiocýäé«—zYûÙ{¯eI³ì¾oûýùôîxW§ê”oß=m0@ E†È…ôºÒ+HÏ )$*d"D1@†ˆÆÏt÷´/_§êx“'OúüòóÛéâT7†Œ€ž`VäE^f~f¯µ÷ú¯ÿÏâ"ð-DëêZ”Z67æRE…žçºì–ó"4ÀÐ" –§’”­œ8NQÃã\ÎõzXœäŒ½Öp^ ÒûkU×a'Ãä¯-@Jgy¡AWkŸP¦ßŸ_^N•RãQôäÉÙWRn IDATN·6š¿øÕîp…|¹?øè½/Ÿ^tÏǽ¾ÜÅe—KH Yø 3æFYR¶‚´?O=®(æ Ž -†¡¦ÐÌç˜JL -Y(ÌÐJ…ÙŒÄm6m‡“If¶;®ÍÉ££ÉÙ0éÔœÁ4/¤¾¹V½³YÏ¥Þ¿ÃDTÊÎÛw(%?ùü¨Võ<:IÃhÚí7U€‘êêÙø.7+­=ß©—KõzY!¬ ·H€É•ãPé0c1ï"ÔmMRíqÐðÈ(V>G‹e!xr>ßn{½iþàhzo­2 ³çÇão6=—J’¤^õ¤%€<+..&ÓÇOϦÓäwÞ¿öÙ‡ÃQts»ýÙƒÓõz!õywòîý¥QTŠ ,Óòé$e.–ùe(ëq9ëN’Õºc[´;Š÷zQ«ê6mWœfÅ®—íLèy&ãB½<Ÿ=|vqc³yt:nÔ|ß·WWª2ûçÃrà.ÖÝgçÕzù»ãk@9ðªJ'…`¨&ÏŠ$—š M$4*Áæ @¨§)p-bq× %Ö›ƒº‡$@¦aÉ"ƒ0Ÿ¦b«ã¢üÆry{©ÄžÄ…A0Î$%ȵéãýA«êºO3©”>=¾ `@=}|¼º¶x…I¾š…úŽ?!•JÅ+›²LHmÅFë4“„A%´ sʰl”Èáat<—`‚žõâšÏ)Aa"æ™,—œR`ÏãÂså¸þÝ+påqýòåe¯7slþÅ×ÇšG(~ò¼W«¸Âp–ø¾åØdÿd¼ÞvR*’À£0ßëÇÌ ÌˆÆIcyL „öl’€u9."aÜØ "XuPTF`ɥǓ¦(LåBÍv-2Ž ‡Ó'Ç“£Ë¨Su ¥•¾ºãhçœâJ`a‚ž¾è}úåQ§åﬗ¿ùüåña¯Ä¡28\á¨ø[úš‘Z'š& ¥&©d8¾Å(†Jç·!”*[J(=Ï´ÃFfœ ƒA˜o4½ýîìæj%èúry8/0ÆWÜŽ+ÃpBÈÕRry9{¶{±±Zãµµþ`ž¥…ã0Æ0A(ME’+]ˆ ä(­Ö^¡°Cգ󰿀M¡†"˜4WE"À‰N¥1ØD…¼ú2Œ¥Ã°KáƒÓТAèZ¤êóa˜5Êv=°³T*¥BçêðlÚÇ××ëíª{}«ùÍó‚0M ª ¢Š³“A‰X¤A¹L0©ØÐ¢¿pý‡Ñé¨âê³wBýêo½i®v$BéL˜T˜T@iX*©M ¥2d‘œb8ŒAˇ6Å'“|½F]N_\Æ[M÷éÉt­í„<‡­v‚~,ß¹·œd"ÍÐÀÀW@Æ«Ww2Ž÷öûžvuïá£Óþ$¢k­¤Pá4iU¬³Q|­ãÔñÁÙ0œ)ƒ tI,YF$5å87¨õ aLž F‘¦HNRèqÜ ‹õu9yÙ¯7ݸ@«5 Í(ªûüx¬µüíÅà¸-ÕÝ•ÊÑ匞„Ùy/|ÿÕÏwƒ0ÉÕúrõÇ?ß½¹ÝüæË½·ï/~ò‹;kn;W#ŒW‹àw•M¡T&L"Ìgæš‹PTåØà2U˜G!„P©"•̦Å41ó4=Ð §$LŠ[KÁ<×.Ç%—ÊT=†äwj®ÍÉp–]Õ Réëk5‡ ÍÚjmúxçª šÅ|<É‹|w÷t0Š˜W͵p†¡Ö C.CBŒ±Ã­i’m5˜tg×Z~,àFË9ä¾C+½¹V_^ªy‹reŒA½² ƒ ¥þÁ÷w6×›³0ûñOŸol40ó(ÆQúúÍÎ8w{;Ë®Ôf‹zÀ.ç²â—áa [>ÈÁÐ0¬ °Ðˆ4”¥’Û´ÐÆŒP±–1Bûz“r‚±.¹ ø²ŸúSŒJ.ca„V[~9à” 8—…ÔO÷‡ËÊe§;ˆ-ІãÄ÷8F0Íå»oo|ùÙîÖ’38´[eeP.ÿ³¤WçÿJR%…ÚÒÐU*Dsfƒ(îPLmj”aѲ ã*ƒêM…‰Òârš•|+ŒóÕ¥*µy«áG¹ºvÁï$µ^ÁoÝß`.¶K®k!„¦³ô{o­ÃüÓ/Ž~ÿí¥'Ç“•¦§Œ ½PbQ96QmHš‡º„q¡¤± Œã‚8Tadâ‚ÙT9Üwµ‰ s»á™I Z>ê†ù8‘‡£×Z^w+mjîW/†ÏN&Œb¥õ•¢T ¬{Û­4O^âL>zrþýn¬­Ô¾øêèmÿò—»Ë-{|9ê´Ê ©ÍUùö‡—4&-tT¨ÀRÓ\æB!€8‘T ÐD ˜e:—0°To.Ëôt”V=fŽ’üæZÍ/9w¯53 µ6êÕo¡ÑF“çâɳn‘‹Þ`¾¶Zs, É„ªV¥ì<ß|ïîBo^¸ŒL'‰çÙI_Œ¦®ÃΦ…Ï…Ô Æã°P„TÀ£0‚a\2z–+Š¡QZÏ2PuÀå\ÎR]¶©Ma³d??fR·«N§jW|žäj©æV|§R*”JgB)cÖ–Ê×7šZ)ÎHVÈ[ÛíO?;h6ý4I–üß‚"þÿâüà¯~®ÿûËmïªüw³wßÚïÉ«\"e”›Lb#Ș<:W#ͱ¸œk3A§Ä„F+5«7I¡”TÞo߻ާúJúaô«çÌ#…ÔZW+®çÛÕŠÛíNÃ\ÊLx¾5Æ·¶š¾ËžÍî¬VŽÆ9Õr&eæ¢Ø8TÚ!H;œ`¤*bA<*Îg²ê`€¸1’Q|9Ai€kÑ•º»×‹·‚Y,ÚUûÆJy¡æž"ˆ Æ8p¹Åð“ý¡ÃPoåÒ”Fy½îmoµ=9¿µUû·ÿæc›‚õJ*ÉÕy]^(ÓÙl~vtá2ó‹_<:9¾,µÛ©À(„ÔAE ´9GÈ@Y<ÈenQÇ¢¨Ðç—™1 Êâ@0KÄÊbÅuy°Öš2J•…ÔRŸŸô?>{üìüÑ“³ÿúÏÞ·þæáY³UJâü­»ËÆ ¥Ý——ºNcŠcärš-7\©Á0«Uë"Ôu1 G ©»RC Ä¸$e ⡃‘¨»PÃBÚ Øñ8µÃÐ6q,ª”‰2y1N_žM…ÐíŠ3‹Š+Ly’.§¾8;cF©ØX­3FÅ.¶ƒ•¶ûé/ß¿µ ÎÅ+kR¥”,Â(M DåÙ…R‰À°T@µÃ=L&-ÏB(›‚°¸b?ÃIjÚ>ÞíE£‚TΈÊõì7n-ä(ñêµ½¢M<}Ö}òôpÙŸE©Xh¶E³\Ý¹ÖøìëcÛá…[5ïåÅ|³ãsJÎgbµÊ1,ÛFj t¨0À6!@ä#3!2©]ª3åXDØ, H02ÆèA¤ΑÀ†ÏWëÎ4‘JiáZË‹S™å*+d’Ë«FÏp’TËεj”…2®MoÜ_ùÉOŸïÝ­¯žµêîJÇýÙOßßib„sõjÔû7·wJ)¡T*D* 02—ª‚b€`–¬4DÈ ˜ÏRH °©îN…Ë9J@d3§‚´Ö BKKÕi"BJª«ñêb`*US ìÿôùÚZýÍ{K?ÿdQ²Ò l›Ï±XwÏg¢Sb_^¶jÞx)|KžM2c ‚Q®®´‰>W…ö8 kLªJŽcA1TÓDÕ=(ͱ²9£Y Žc‘æ!8ŒŠÕ¦WñX”É[k•²Ç³ "˜K½:Þ?—KÎþÑðÛ‹Ûëõ‡OÎ?zÿÚÏ?Þ#=|Ú]]®„£1Ò²Ys2‰áob§¹:rJeB§’¤e4°É|Û±(ѦàXúN  …Í´Q9Ae^Îò¦»w¶þæJµÝô{ãäjÙ¹ªæ_ÑB•úÏÿì߼ߩ”Ýó³±m1)u«æR‚1F•’=ŠeÿrærÜ©Z¦;Ë¥i¦(†>'ƒH×\„1Lñ™PÀà …@!\2:¾âÍ@ ¢Ô]¨€ëPÉ÷8JÊH­ªva E T —sØ›ßX)o-£I\`Œm‹2ŒÅO^ö[57Œ‹Ñ$‘Rµ[¥jÍŸ†Y9°›ŒÿÞøŸÿ•óþôÁï|Ðøwÿö³d2¹q½-4¾8QJ}ò³¯ŽöÏ»g—ù<"ýË÷«w×Â$Ÿg'“”À¡†Q â*EÁÄ¢òrnÚ~q/”-ˆ°cÑa”;?9ž¼sg±Ö ~ðîFo’¹%›Ú–”RdB+}y9ëvg/_ö¾÷ΦÖ:ÏD˜¼¾Š üæp|£úÅóFÀ‹B![Uû“g—wÖ*Ã/¦×ÛŽÐzÉv@§ªÙ@(µÍP†-¤ pIhÙaRŠ¡AÐ\Fp¥fùj¥&‰xg»~9N¯-–”ÒöG—“Ô±(g˜QÜŗÈÛt<Ž·7›7¯µŽOƾ·U­¸¿øå‹>Øþ‹¿üæŸý“×[5ç¯þâ‹÷ß\%Ô΄ˆ1enà!Îk­*wø¯õ`÷ùQc¡1›ÃIª1/yu¥òy®F!HS‰«¶²(Ú¦Ën½RƒK!7;·h8¯m7ˆß~mµ\ó…PR­´’êJ tp4¨×ƒÙ4‘ÜÙnÿâã—oß[Þ;V+ŽcÑÞ0¾µQÿdwðÆV "¸?Ìn´mà(1MMRR²T.1ÅLN>çuW!5°mRHãbX ˆÎ&q+° €e?éÆŒàñzo£w>š ÇVe:Ë(£Zë4Ë÷÷Ï6›üóGG_þüÁñq÷ä [í4úÃx H, ŽSN !®AžMrJ<l¥Íð()¶v&ÑrÍ \:NdÉe…Ôͺ‡-f0æ6·\K iŒQR/§Ýîô¼;ù¯þì½þ`þ«O÷¿÷Öúx––}ë|š][ðöéÁ›;­‡ÃŠÏk%~:Œ]ar©—*<ʵT¦êâ~„›ž ÍÊ1)+5‹ „ Ô x.Ëp‘ !t(<Ÿf‘À&'£t©æ§)‚ðÖjåè"LsµX÷„Ôc© Âȱè?üðÚÙåüÅÑ8pÙ¿ÿÉó;;­ôï~t=NòóóÉÖzý‡õÅGo/Îç ¨ Æ(­{ÝA™ß<:<=ì9¾CŒæÓyž¤E«$ È•Ê3Ém^2:QZaŒ\fÂL®T§øe/Zm¸'“·°p8KRinÞè¼yoùr–[œ‚«¦µPZéã£Þݽ·^_ýúáéõk­ °Ï‡ÑjËûøóÃ{ךGg“››õóqâ0Â9 Sµ\f…™VQÁ=– íPT]è#‡Yž ã[Z?àÀU¢¸@5WC˜ÚðÕ sãYd¯;w,ºÒp÷º³…šûâtz>Œ“\^1R&ñ4Ì0FÃqôÖ½•<ŽÃZ­ÒÁÉèöõ6þ mÍo“ñ?úÉÉ‹Ýû…Çøû·îß]ꟋsN Œ1Kk¥õ……•v¹Qåž¿}{£ÀîùðèdP)±¯¾>È­U:B©´˜cLm†F±,ÛTš¦’b§Eàri€oÓ´P¾ÍºƒHòÖ½eÃaìîNGÎÓ<+â(ûêëã0Ê-F¯}- IDAT>|gcw¯ÿò {³~5ºÐò?}Øýðµ¥³aL1jWÞ4Ã6þ¸›ÞhÛÓ Vl€1Ú¦(ÄÂåô|–Õ]I°€È„¸Œ\΋ºËr)g© lÞ.Y6ÃãD ‡av6ÎÚe»ìóõNЪ8ÍŠ£ ˜¥ÅÍÆúR%—ê³'77›çýðø|úƒ·¿|xöþ{[ûGã“Ñ÷ÞÛ*ù4¾c¥ F@D°åZ«‹ë[ËS¿þrïàåélž\ŽÃ—ûýVZŒ¦Ò,ˆƒÈfÈÄ:ŒŒã¬dsŒÑ$)”ZéÁ4ÝZ®©ë§½XMæ6×Z+¡”PY*·v:͆ÿìEïýw7O&žË®o4Φ%Ÿ ĘÃazsÑŸGÙÅT,•Éù0¯ùTHñèp¸ÒàÝYe9†Zàq,Ca¢Œ€(È¥ö,·éãy®&½YÚ.Û@‡á(WÁËI²Þ „Ô½IrØ‹®/—}‡MãBis6ˆÞ¾½À9ï;zÚë4ýÛ7Ú'g“ÏÞ¼¿zz>ùêÁÉ[¯¯ÕÊÖã/ŸÛsσ^uOr·W®- Î/®­”¾~p¨•lTÙ‹½ ÃK8äU—lXb¨Æõ9'™oó¥ ïGB4ó½Ëh½4Ë6£Äqøöz£\qKµ€xŽÈBH ùÕÏ?ÿò¨Ýô·6šƒ9Ðfe–Ã-‚z³l£é~õ¸»³RºDÚ˜•vpÚÊw,úølvg9ÐÆ¼¸L·›V”M‰˜@ ‘oLf€bPv>Ës -ƇQÖ.ñI…ÊÀ4»Ýps!¨—¬…šKúftpn-–ê%«ä[ƒizvÞÞnJ©]‡-´ËRÈ·ßXëãxžý‹þf·?æ|oëp÷äòìrk³U(€®ÖJ±ÂõFecgueca}«“Ì&¿þøYν’õàÁ!/Õ«*e&d±…¡PJ f5=8ILÙA㸸˜æžE'aê:Ìbd©éSÛj¶Ê[ëy¡·6[¡8JE&â(ûõ祲sãZëù‹K×å½Þì­Û ß<é¾~{!ØÆ ?ÎÕ4.¶‚¯OÃûËÁ4ÕQ®—+4`Q$ŒA4/°…Õ4)´Ñ.'@•6Ø”KQ²™4¬êÀQl¢,m­æÊw(%¨?˪WÚØYjxµ€gBçRgR?y9XY(½<ž@£××£këã³é$Lw®w>ûêè÷póÑ£³ãÃó×wc P!µë; óz«¦¤:=¾Xm»Ÿ|úühïl0š¹ÍN&iT@‡H©‰4¬ds‚¹ËD®H.1FfËŠÃ'óŒ2âÙÔà:,J‹Åv©\ @ ¬µÆGaœ&Eç§gãßûÁpþÿ}¼ºTÝ;~ÿ½ÍçGã­åŠk³Þ$ç©€äZ˾èÏSE¦žk´?Ë&QTñðñ8&·ˆ s`€1GÀ` Àq.)Ö·8µRRÃq’Àhw{‰Ï0g8pÆQ²ÜôÊ'¥¹âŒ¼u«³Ð Ï&ƒYÆM’×ï.BÙü·sÆü÷ÿݵ~ÿ›öO*eçüb¶wÐß^+—]üøÁ!$œ0òÊÇõ[nÌ4ÕÔvòBø.ïÕ¶-òèð¤ïŽHôÃg—N ÀYI© @ .”¢A¥Ö!‚aš«k‹%¥u­dߨjÆç¾½Q«º‡‡­4%Èwyw0oÔük›çÃÅV°¾\ýêyïÚrui®n®VÎ'YR¨kmïjè~w¿¿Òö-bNZ~<šS 0‡ˆ¬þ<渜@È-*iS¬k3ä¹6B4´ÊV&4Bȳ àññ¤Ssn¬TžŸLŸî´÷o´!0ëKÕ\›ç»wo->~Öul¶±Zo7ƒÿëÏ¿Ãl{½Döx÷²R+™ßàŽ]yx% -,6–Ö;ó0… n@)ÿü󧟜޸ÖÖ+]XÌ&æR3‚BŠ±Ñ¦PÚ·iVHŒáÙ(y÷Vçæv{i©–Œ Žg±,äþAóµk-ï¿|±½ÝVBþðGO76šªãY¶Úò>»ØY«jm½ìo.øJëÝ£ÁæbðôdºÖô\‹<¹HnuÜAª€`N'QÙ!B Ç ¨?Ï-‚8¥™PŒ„00F(¤öRH]½µPRçRßZ«n,–7–ÊŸ<¾ØÝPNïßh ©Ž{a½l¯¯5>ïÕÊÎüîN¹äüõ߸ޙŽf Í€q?“R«lº¥`–š ZÊÓ´Ø—Ãy¿ÛÛZñF 䬔 5Ž“À)»LB¨„‚SçÓŒ`D0É¥ZªÙ"Àæ‚? F€¨Ó*ÝÛéL sýÆÂÞß::ϧñÑÑàÁ£Ó0.ZA¹ä?:ÝÜh|õ¸{o§cÛl÷xtm¥J0zz4¾¿UÞ/×—“ÃQÞ˜ÍP7„KÃJ÷YÕE“D3b|Ë6F céYœâP5IgÙHŒÑ *6Z.€BHTÆÔJörÃM ¥µ¡ÝÞ¨m,•ÅQ¦l†ŸŽ´T…P¾Ç:åþl×uØÆZãßÿø)§ø÷¾ãpÿܵ0 ŽùM—­ ¥·W6ÛKu%Ädû_CíZ:•Ü"†¢¼7—%@S!@œ¢¬PœaáÓ£ÉRÓ÷,ªyëîrPq LîítNÏ&y–k¥Ï»“GO[Àó¬ï½³ñé7'·¶[õªû飋k+ÕZÉ~v2]oûç³¢Sâý~ej½éœ^†In<ËœÓz€÷ú±ÇELoÛPÆC Íç87Ð÷Y–NQÑ”ð•*?§%m€0Т(“†SL0||2Ý\®-•˾՟¥½Aüï­×+ÎííÖÞÉx<Š<‡m®Ö¾ytöþ;›?ûå‹RÉ~íî²’ê‡ýU§á´jNRÀ+@™Wr›ZHg¥µvm©Z/}ú³¯;î7_ï;µ¦6ÄèþNÇ+¹šs%µh‘óYúðñ)F𣮯­ÖÓ(}ôøüÎÍ…VÍýñ/^l­7?íÞÙ¨giwm-xÝaL ®—ì“a²\wD§“|£n÷#à2àqkŸáÜ 8*hÙ’Wób2/ gÙ™È ÆãR `«l­60‘JJÐRÝMs)•©ÖõåJ%°>~ØÝ;wZ¥­åÊöz£?I‡“¤U÷,N~›ŒÿÞx~ôdp~ëÿ8û‹¿yþõþb+ˆ£l4œßÙníƒù­õÚáÙär.6ÜG£k•_>¹¼¹RÆÈœLòµš•ÐåXe­ÂQ$+ Ø‘JNSq ðŠªË!ÃH`Œs![e+ðFÇ+yL*óò<¼»Q#í_„ïì´vÖk+àlœöfǽp¥Sò\þåÓ‹›Û­íÍ&€ð¯~øø÷~çúÖFÓóãŸ>ÿmd¹Á„}kë¯òñwWÕ/{å²_ª¿úá§­¦=—èõ;Ûý§»çžçW`3C)4N QvˆE©Íi³Ì €YT¼w³åÙl¿;3}ÿ­5ìÚ×o-ÿ—ÿòÓóééáå/¹»¿yt:vöÖëkZéó‹éÎVóãÏ>|gÝsù`ÏæùµÕêϾ:{ÿÞÒƒÃÉzË+yüe?]«ZóTs†ÐÛ@'ÝYÑòq®Â@à0M0&¤\¶¯lñð0ÎÛ% "¼Pá„à\ƒ¥š³ßOÊ_mxçG“ñ<ÿàÞâ­­úR;Ø=™R ol6¾|ܼ}¹\rv÷?üé‹ÞݘÎsÆÈÆrÉB…TZúÆðUF†ÙV"Œí9–ëH@ )§ót8 ÿæ/õàñÞp”Ôš-—+}Nt˜À¦e‡P‚¤2r2µ>ºœ¿v­§rÿlúGïor‹M²þîyžup8@EóôÎåŸÿâyoÞ[ùìáùo¯a?~pöÎEŒÀ»ƒ7¶›{½y«l•z8H+ ,ÔŸë²?Ö[o[_Ÿ†[ Af¸bkBÜn(+VÁˆ¥´ìÍEÙ±6èÞ¬T-‡ãTšÅ Ù‹ A…PÓXÜ^­”=î9l÷|6šeƒY¶Pw/ÂÚnøí†¿{<é]LÞy}µRv>ÿúøwßּ߮ÿí_V);;›u(R‹`Ô¯”ÿß=RHh­Y9Ø=à°À& sN ý¿üOÿO–êõµMŠE",JÀ0ΖÊ\(ìY8ªÈÅör™PâÚt±îjÅw¶ê^ÉQ¶Å='R‡ à[ß¿?ê~ô“§òÇw!ñ×?x{hý7?~úîý•ݽKŽ¡MàþÉäÞµÆ,ʺӫåY\LæYÍgç³|µj÷#XsÔ„bó¢·| ƒaRHŒ´­À˜‚S|<Žj.'÷f)€`³éž “ÍŽ&Åù(yçFsžˆ“~Ä(úðε•Ê“£IïŸM_»Ùi7ü£‹ð¬¾ûúê»ï¾¾º´XQÚüðGOþè÷o·î¸?yþô¼Ù©«o±Óßi» •z‰X6"ä'ýÉò’ûé¯w_{çN«ÙÎ d¨E$#bž_·Y)á0Ì6Z^¦@ÙcŽEûñbÝ}y>k7ý÷î.%¿ùúúŸþñÝýÓ ¦{>98è?|z¾¼XݹÑé÷ÿüá“ßÛì]†õªK9:Ÿ¾q³3OEwß\«Æ¹GÅbÍ}ÑOv:.pœ‚Šm2e˜?¿œ7<0ËiÅ{À¤³ Wle€=K‹Àf6j©A§ÄŸÌ<—{6õmv4J›e»Sµ Ž.çBêî-ÜÜhø.ðrðõ³îõõÆaoÞ¬º%ÿ6ÿ½ñ¿þïU§4eîÑï}xme©ºwÚæœœõ“Þìý×–/†±ºZ²'qQ÷ùË“i§îôûa8OW[îOtWìlZ¬×¸Ðœbùä"\*#m¨6Àìsey*ŒoY 3%µÅ"š"t9MßÛ®ŒŽ‡q˜Êå¦W/ÛçÃx0IÆa¾¾X6v‡ñ~°U);—ãäÁãsßãwo/^\Î6¯Ý^ÜÝëÖÊ.F(W@i­¿S®«£J ª¶ùüëý¿~úúûw÷£7&Óhÿ¸›'j¥ãœÏ”o‹!Å4SßïEëm?Ñh³íOáØlµíO¢‚sºÞ f‰˜Ü~m#€˜õôáéx–ööóÝÿôŸ¾¶¿ßòôü­»K/öúÏv/^¿¹Ðíͦ£ùµÕÚ—Î] êîÃÝ>Z* °-’ºé[³—,=Š#4+Rßv!P³Ö]­%˜\†YÝc…Ta&–+öQ?ÙY $@ UÇsÙh^tGq.ôk›5Û¢#ßå;ëµYRìŸNz£x±S*—œ‹Q|ÞÞkí¬?ò¼ûŸý'o,/V^î÷ýÅAÉA·Öü§/Ænà¨ol~s¾±T-3Ç“ˆž$…Lï¾y×åöå$tüRÙsŠÔ,5¾E†QV²9£xžEzsŒaÕç{ça.ôµ•J½¼÷þöŸýËwŠ\üüWÏú¯ß]>»˜ýíOžm®ÖGÓä›'g¾»E)>>Ÿ,·Kçýy9°š5ï ; \Þ(;?íßÛªóÍšu6Hë%*„x|4,yTiã;.„&L3‚‰kyJ†©{B‡±•*G…™vmr6'­²Ýd U÷þfM0˜f£äý;Ûf­ºwÔ Ïº³×ou,‡ŸMv6—Ãèàdüü`ð'x;+ÔÑéäà°ÿ'ÿ`çð°-ç»ÙîïIB‰ZlóÆ*fÎÂr ˆôètøìùáéq¯w6ÚKžm„v&qf3fsÔ s—Ó0ʵ17W+§ýè½[íqTœõÃ?x{-ÎåÅ8¹sgåOÿñkÃyîP¼·{ñøñÙç_WªÞ;¯¯žžMgÿÿØ{“Û®,½o÷§ïnoÜè›÷"^ÃGò‘Ì$³©Ê’RVÙ€%È’ ÙšxdÀÿ„xª‰=0lÀ€”-år¡šLee+™™ì’äã뻈}sûöôÍÞÛƒKR`5* :ˆA /Î9ßÚßZëûá³®ÿÞ+ç瓳aøö^ã²3½š¦Uý°l·Ì,-®¦yËů®f@晄4Ó˜ 'yÂXÁHXªVˆB¡làG G†RS€(NЬ7Únoæ©g²åªÁ(9Ãi|p5¿¶ZRU&x÷µ%U! Å+ÆÿÁëÿ¬-Ó|>?g1#è­;+¦¥}ðÉ!Áðûo¯w?9[YmŠÅêç‚Îñ­á~!Â)Ù)\ð•f£òlÿäÚöj8?ÿbß0µ’à žÍbÞöÔqšmxÚå$[©hWó p±Ò°VjæGO:YÁ BQZlmÔÞýÎPÌW¯:ÿúÅp0ô?ýìèúÏ>=`*{÷îÚþñp2‹ß¹³||9Õbì¤\_vsÿlsÅ;91† A[W¢LNüÈÖÕ I(– 5¹:I …y:G\g`¥\B)\+e-ã±Q3(FÝYÂ(¾½^”œŽb†`»íž ‚8åËPuçñ~ïª7×UvçæÒ¯>?Ì¢wÞ\sMxqÖK¨ê¯ß"Ž}ó„DQâšJ’†ë¾÷ö­ÃW''3P§;ëõç­ö,ÕOBX¡¤å©yêÌ1•ÓATó´[å£~ØE«uso½|ÿpT^ªílT¼Výà Ó½ÍgÑýû§ë7Wëžþ‡ô%Ähw£úG?}1º¶VºÿäòæVõÞÃófÕl”Œ_~qö[wW;~ÉbáYgZ/é£ 6ÒmI¹«›aš¦EæhDÔŸGŒ`ŒqÛ¥™ u›­Uõ½$ÎøfÝ €¬7¬qTJ4W•©ìéá`$Œá\‚(ã—:ÃÕªõëÏŽ)Fͺ½Ö.}òù~G[m·8ãB|‹GûÍ §²Ýªmî®>p°¼d`Aˆt¬¹•úãçÇݳËÍõÕ8Ï% 9ËeåršÁ“Œ ¡ŽüÄЈJñp*}}»šÒ¬8?úÞõ½kZ³ågÙ¨3ò£ìðxàšêáÉÈuôë; ÇR<¹¼q­ñðy·Q57VÊ_<íTJúZËýäYÿöf¥;Ï×+ꃗýåšq:ô)–…WÓ¨f±´È”…dŒ`‚±Fx+ óªIF¡l{Êå,+édç\HÏd×Zö$æ“0#î.»Âî("ePFt…!V›n&áéÅXUÉ7—fAúá½3 ÄßûíÝjÅüåGõ’b;fœK°Øÿº¶ùªF ÂölM7%VÒ‚WÊÎEwP6áYÇoVÝ÷?z±³Þ f\¨”@6jšÂèÈÏ®·E¥½Yz}Ù™¥œ@°»VÖòùóžæšßwkïz3HÉOò™¡±—¯zAü7ÿõ»}rpÚ™ím7.zsÇRvÖ+†F·ÚÞË‹™ÎÐegz}Ù{ð¼SsUÏbÏÏg«5sÉ%WP‡ÂÑ)håŒ`ÁŒS[‘‚þ<Á2Ê ”Ë%-É%àFÛžEÙË˹®FIu&1ÃP„0ÌMÁ—Wã˜aØn8woµßÿðp<‹…ÜÜm½ÿñ‘ÅÖJ=Íóû\þûÉ _­z !ó|¤;{ko¿¾'!à:†½ÿâøƒžì\_Òå¢XöÔB¢ÕªÖ ‹$×–ìWþjÍ]Œ¢µ†½·^²-åðjvm«þæë«ƒi…q¦÷žù¸ž9êNnï5ÿägÓ¬xûv»Ó›Ÿ^¿Ö8½œfqÚ¨˜÷Ÿw—«ºÂð‹óé­õÒ³n¼]3 Ï'F%‚˜K4 #OƒšAè cLLbi©#¤d*a!ãL¬Wõº§]Íó¢:ÃUWó“b½iW\íæz¹7K'AV2•¿ãÿO„âÿZºõÞÉÎÝ^ñJŽ>öÓ{Ϻ~”ímÕjûOþò¥­áwßhÛ Ð( š!¾…\œð€ý±ÿ?ùXhd¹]ïN§Ïî¿üÞ÷_?îŒ*nååÁ 7 uÛ®Z ð¾_¬”ÙåL]ò¨kҧ糺§«L©Û”d ]Ö(%“˜o5-„Ð/î_Ô\m£é¨ êÌ“‚ï¾½n®¶ñj<˜Ÿ_ŽO†;w6ž?<þ‹_ï/·œ?ÿÕÁ[w–=[{òjШ˜­ªõìd¼R³~õñÁ;7[|qúæõ:%ðU?l8Z!ÑÀ«6KrÒ›eP¢pžBQ6¨BQž7l|>ÍjER‚ëEѳùFͨيm°G~˜q„ñ4á·WÝ’­Ú{z2½E›Kv­lÿôáÅÜO^»Þ¨W­î(øùG‡×7«KMçàå!Lјà›êP|½%¿° ç¦þôϾh­7×›KãYÜùžkþä§ŸiÌøâËÃÕ•jÍ!Ç£<ã²å²§Ý0ÊÄzUÑ v—ì²£æ\ö½·Q6„Wþ;¯·3Óî]ǽÙ|ôñÁ$1ÀüìÁÚJÙÒÙ¿ùýÏ7×ÊõŠùøÙ%ÅÐTÉpä/7œgGÃ7ö_ WkF. ¡’¯ú+5eæ¶‚5Å¡N9#DSÁq”CW7u&(ÆAK…=Ÿ·\jªäq'Ñ^©h®É:“ØÖ©BÉÉ œ'ÅõR£¤{ŽÊ(‰³b«íÖ+fš|òøê­›ÍvÓ­”Œï~÷õ•VÝN“ä¿zj[zÉ5s.¿Mï_gåB@ÊJeB™æ\Hùÿöb •º×Z^ºÿì¤Q2m BаñË^¸YÕ<ƒ=¿˜ï4ÍÞ4ѲZ7u•Ü;^Ã;[×Rž_Ì~÷[wÞ¼a¯42„ÉðjüòùÅþó‹ç‡Ã¥ÍÖ›7[A”ÝrõÖkËQšo]o~úøò­›-U¥_¾¾¶^º˜¤5‹~ùüj½iœŽ£íº‚¢ç§UÛ"Æ…§«RæYæê*#C™p¦m—y:=%yºS×]ƒ½%­†é™Ê$È>9Ø[qëž®)ä¬ÓߊñÿËõôdöð£ÍßýÏü0)Ž»i°•¦£¨ì´3¿êû7vL¥a’?~Ñ1ß[±öOf"US !¾ª¾8.3JvonšºÖw—«–® ”(šytÖÒìèäêí½voš!‘m4ôI Ml• ¢óq|½auçéå$¹±dc„އñÍ5o«©cœÛ¶E<»Ô*)º"…ìž÷O_^ {Ó£ãÁ¯?:øÝßTò—¿9¾¶V>ïÎn^kšºòè`°·Q9¹˜†úøÙåîªj2¼@ IDAT3 ó4É Ó’,6¶Tmq S׬ͣ Å@£P]ˆ(Ì­ð~ ê’Rvç|‹e—ô1Å«£$ÌåË«yÕVn­8ç£ä|Ý\÷v–ÝÀó~ЇGÝ\.üôåÉèètôãïmq &Óèù«Ž« “)½Q`Û&‚_ia_sU !Mj¤øâÙùlžýÝ}ç°Û«—¼Ñp–ÌÓáØ7u%ËàåÉÈó LÕv‰%̺½j[íÎ2ŠÁ›åî$ÍÓóAð[¯5LEªU±L eg<çI’w®Æ~øò“/Ž¥ª<>诮U³0>¹œ®.yÓqpÞó—›Îí¿¹[Í“VŘ'2I³óÞÌ6ñ4Ì«¶¦AZRKâ¼È A…®&!ÔL…´]Œêû¼f‘”£ãa´RR[Ž2‰ù(*’BÞXv2 O{c°»;•¡Ÿüô¬~çFbt5Ž.¦šBoî4¤èOãÇ/:?xk¥ÛŸŒG±¡k”àØêÛüi!%¦AÄ…<;¾*•-γÞ4Ÿ÷ÿé?ùÑ`>}ÞrpÐIs±ÞÔ»sž²báóI¦b§®Ï’¢ïß½^-YjßÏž ×öÞªÛ…ÏÒk%¤Ð<åy–?{tºÿ²3èMNÇVÍS1üÉûÏv7*BˆýþÎð‚®d[êÔO–Îa?T¤è 怢¦£0¢væYY¦få\Nã¬l µIÖ- îé8çPàªršH„ðnSÏ8šDÅÉ0¼±d ‰\ì4ÌŸ‚ld?¸Y¯xzœ‹W“fÉXn:–©fÉËã¡àâ­Ûí ξì.·ÜÛ›îh0E؆¾ˆš¢o™®B.eèõkk…†Çóøì¼{÷Fã»oÝ>ëŒ[?|qšce­B+–r9Ë×ËJÍRÏGÉzMt‚Î$¹»YŠr> ó0ïÝlÌã\yó­]§U‡aÚ?Œ®Æ“‰ÿôÙåÑñàïmI ~òË} C]cÿÚÞÒƒ—½¼¹¥|dþ4ŠÃÄ2X”rDÏ‹Þ$(™0-`”åÓ0ä½9oØAgY.`I§Ýy±ìÑA »~v«¥!ÃL^Ló²¥0‚ã¼¹înÔMÀpžugÉ<Î+ŽÞ%‡gÏR¶VJó0뎣ƒ‹é{¯/÷§ñË£AüÃïb‘¥aP-;C’œ‹O•½y*xrpõ›_Ýû‡¯ßÚÚ|øèØ01Qµ§OÏ/¦ÙíòéEŒ¦¥Š¨]Rg‰44Útá«N°R5®-»aR<;¾¹SÉrîÇ‘²Õ®ºíQhžæQ”:“Ñ8üôóãO>;rËÖãÇOO§› ë¬;ëÖRžó'‡£½µÒ‹ýžN 2ÍE,áfUq?ˆw†Êù$_)iBʬ%s@ &Ó(+FÉ`ŒÈ #5‹.{ t:Jn´ ƒái\œ]%on–f …9€@g{2þ_Ÿ<Ä»¯Í××r.$ „b€´ æXj&#¨È¹P: ÓÓμlÂȯz³å¥:A°(œá·Nx‹¬fF@¯7YY­KÂtK[_j4*¥ó«);|ôä¢ê–æZ§GÝã>eøàU¯ìh*ÃÂY&y^äYÞª¨ã°˜Í"ËÐÒ"+™6yœ puÎó”G› g*A™ÐtÊë‰ Õ`¼jâWÃ,çCx½id]NsS»mûdu§ Áp{ÉiV̳Qœ0VT:œ%Á<ç·¯7/¦YU,²Þ°!$!F!$¿F)ƒTdœT*®né]S¢yôÎíåŒRϳ/§Ÿ}vpÑ›^õÃwn”§±L Y·Ñ8W³ÂÑiÃU®fE’f5W»¶ì|q0ò“ÜTàjU¥RRä\1B ÂH ™%Y0L×<;]Žãƒ'§y!FUOŸù‰miC?Ûn;O÷{­º}ÙŸo¶œ¨@ýYd*…Ÿ²¬ˆ=Mbùq\éjÈPôB@9E¹Ÿ’¸ žsAËU†0çÅ’«¸9Ÿ¤Á½¶ z5L€à%KÙ[qŸŸM1BkMg«íÃ4-€@DIoi * oUGÏ.K*4Lc‘Š¾Î€\Ä\p!Æ£™W²t•6Ë•Íí6çA ÀêhK­ÖÄÏ”­ÔÌ(£e66 óITlVµiT b‘Ûkž©Ñƒ~äéd³ivçFÙ5]“2J!”@ó4œ^¼¸²]#K²ƒNèjäüjB(Ùݪ^LoïÔ>¹wº½ZþòéÕÛ·Ûó¤è}ÛÒsžgQÅÖƒ4eXb¬ ) H¨b˜)‡ØŠE RÐK¡¥bKS¦±ô \2è匜7\u¹¬=8¥… ­7ìóI"¸R6Ë:À8)d”@Š›ÛõƒóéáéÈPIÝ% O{ºß­UK‹ ­ÉûÒåBQâ,Óê çžkÕ*u)¢ M?ùèÉ­›×¿8k/5.;Á½ß¼ðêU‰XÍ&ŒÀ¾/«6Ù¨›Ó0¿ÅÖu1Š‚¤xc³\6Ø8DWC5"HåŸ ý{_?~v¥j!/X8žM§Ñ›·–>øè`<9¦Jn^«?8Å~´ÖrÏúó­–sê'1ÂÖØ< §ºj„iVáécÝdy!‰ÆÔ†% ‚¢Øª¨QÆÃL¬—ÀÙ$øSÆR¬ÕÌ Q.;ýUOÓuõørʾ¶^Yk{Ÿ<¹J’œ"hªàùóó­¶«2\ôUÁ-%üZ•ýDÔ*ÞæõÕý'‡+˦[6u I–Wcž]~úɳ0‡½¾¿»áÃ\¡¨là‹i> ‹¦§ºMrq9I7ê†ààj†1¼µVâïL’rÕƒ¶!¸H£ÔŸø±Ÿ¾êúQÆ4u’A·êî_]^Mv7«/µŠ ™‡YÄÛ+ÞáÙDWq$dÕ Ç@Sééh¾ä)— gc‚É—„¢l#‰Åd{ZÀ¦C!3Áß©B‚ý^ˆ!tuZù+ÀŒÿ£ãÿ`Á\½ûÞ|{KVÉRl=¾ðŠž~Ô§A¤|wÕ+;ZÙÑ^œÏÊ»±á•u¨R˜J ªŠ1ZTÓ„‘Äöœ8ç”P.Dg6Ûhh‡ÝñJ{é²?ýø“çBÈñ4n•UU{>*ÀV±p’†ƒtFÏ·fÕR„”Ï&5‹ÞZóú  åyA(!ŒPFB’Ë`LG³³“žU)ÿæ£ç†sóZóÏõ’jÊh8¿µ]›Íc]!ƒDb^(Ù&;ìÇ ™ &ÍÒ(âX,'˜*ÔD æÀf(¦dÂÔHB1Œ ÝQ WņB_% ÚE Â/ziÍ¢uG)™ÊÓóiw’l6¬Þ,I ±Óv\SQ²å÷§ñáÕ|qÆ{ãèÁ£“šËŽN{‡/NÊ®e€1¿v ç€~ð‹/_k`B HyòËŸßÿÇÿðGVɾê6Ö¶&¾ßp¨ŸŠY˜7]j)¨çs…Â%O£ŸMŠvI­{ZÙVŸžNÞÙ.ÇfR…0Á‹; ]ü‘Ÿ§ùkß»ƒ #”àÞœŒzÉÚJéã/NnîÔ3.ûGƒjÅ”‚›ºA¹(Y•(õã¼pUI¨¦1œâ<ÌAR£")FRgbž A€*&p5Œ Ÿi#O§÷Î.媧–,%Håã«`¹¬aŠL.ÁµewfÝY¢(d³e›º²9Ï“Þpþö^­æ*}ºobæ¹öâi_ ‰éš¢(ãþ“š+Š…Ê,ÛÐ UÜÊþåå«ãn¹\OŠý¯þ¬½ä9®%«(ãàjž®–Ô²A:óìñU¸VÖʶr0ˆ·ÖnÛÆª’XpÁ4ñ¿#A ®ÆgçãÙ8˜Ìc£U?9ì¾ê˜†òá§GïÜY骫?zrq{§öø Ï g™¡`MÁi¯f‘§a!€˜ $çAh0°É0Ñ™$ÄQIj+0) ²d ¢«9w4\µFðlÊ—K¬d*–JºÁvÃ*Ù @èéżæ¨uW‹ y9ŠÇód{Ù­xºi*¿yÒy¾ßùþë-Wû/Ï<×C‚ñ×5âW¤K„$ ¦©#Šs.ÂLÞ¾¶9Nâë[+ŸÞ?xþüÌ©”ž=;}ízE¡¨çÚ UŠsÆ\©([éÏÓyœo5¬Á,½w8ºÖ4—kf)Ó”ÅADäI>îM{Ét4o®¶ï}qpx:~ãv;ɸm©«-çb2ŠÎ.'å²<8n.Y}?+é”c†%ËCÂ3 3A± àb|Ï3%ØÕ¸¥”c HÕ€~*Ÿv¢ŠA5Š{¡hجj±LÀÃa²]7J–R¶ÕƒnЛ¦U[­{šðӧݓάZ2ÎúÁ4ÌÒœo¯”(–~~xrp±º\Ç3‚¿z&¿…LV )jÆÁ<že] †ã(zuÿÕ?þG¿“èO‚;×þâWO^ß©\ŒSŠAÍb*…‡ƒt›5t4ʶfÃÓçQÞEon•6¦i©¡yÎ4tŒ1Â(šE³ál6œ_œöµzeO_\ߪñ¼˜ŒÃeïé˦¤d«ªÊr!O¯¦;m;È@g-{Z!àÕ<.#A.$àÏa+B!  G“&ƒ£8´Uähôb €M›”LVHœs ¿Ù6užç‡‡¯...mÛþëãÿéôn¼ýø·ÄN]ž ¢ËI|wÇùp–ÞÝ*-;Úq7N⑟][+© ùbø«ßeYR6A8ŸŸ\ªL_©[a‚ÅøëEFPp tu"͵íW—½››•»¯m—ª!ðùËÁÁÙ¸st¥PÏOqIç¡i‚WÊŠFQ!Ы^ðö†çte–Á6›ö(ÈÆÀÅÈ"¡Sùq$g¯.³4?=}úÙ‘Û®ù©¨Ùª„Ð’áÈm³2š'yVp¬0\PJÆÃ B ÃC4J±Òl"€@€Ì…ÎP,%H¹ª’” XHšr¶â[Åa˜íÖÕŒK?Ó¼d)–κ~¾Ó²4•ŽæÉÅ(:ÇëMc\/éßÝ«»Ž& \¬öï¬zëm×TÀÅy7™ŽJªŽ®)B²p£ ¤B¶VëçIÁSÝ~÷;·¢h(%û;ïÞüÙ‡Fƒ(ˆðÉéôųWÛ­y †“ùjUï¼;çM‡h òS9ø^ÛúaV*›†­gBJ.)£BLðÂrˆüèøùéÑóÓÃ'§³iTiWÓ\”*ÞîFÙ÷“i”GAòÆnsžφ–†R!Ã0ÖY‘ È0ИR8ôç*‘¹`jŒ@ç…P ^ÔL ˜Æh– †%$@ãmUYÕ¤…D/»BÐFÕ8F£õºahì|¯ÕÍ›«ž„°;‰³d{ÙmTÌjÉ8¼œwf¡ÿÆn3ŽÃ~o°Öªúó†§a)ü Õ5uÑ ØØ^©äR)üôt0Ÿ¿}£å”«ÓÙä—=i6«X·{ƒˆô²—醹ìaFPá Éo-™ Óqâi´dÐq˜ ÞÜ®J1#IZ|ÅAÁS¼ðƃÙåQ§¾ÚxtïÐuŒÛ»Íÿûý¦­OGþo½·õâdüb¿÷Ã;­qæY¡¨fD¶ŠuEíÎ3)B•â”Sƒ¦›@(C„4%†R@…ÅdAhžF„© žÏûo;$.À4ãXìÔõ “G½ b·í\ŽãÁ>\mÚ“ÉdxÙmUí0Ì)®¥ã¯-œ¯†’àœ§œ t]…õæóàrüÏþéïU- 1g1üñ Z. ‚|–€e†(Y-+a;“ðí²­ÑÞ4–œ×+V˜ ¦²E$U(U(a„ç<“Ao¼ûÆŽåXü‡ŸvGQ½éþì—ûó¡¢ÐFÙŒ éÏâׯ×{~DÑ–Ÿ^úU3ÏU°Ð™Š-Š—ŒK”æ@§¹NóB"?£RBG-rN ÉÚÁ˜È6ÊØPð<BŠÝ†>Mø,áW³ôíM¯QÒ3)_žÏ§qQ+iá²­\[ñ·°Y×ÓBžŽ³íªZ0‰Ši,÷–-•áŸKÎ_ÛªpgqN‘@RF™Æ$yšG³èòÕU&7_¿~t4¾ìMWZΟüùÓך\H)ÄáéˆP¼½d&I7â.å®éŒ£ÐÕ B D˜Æ)@JJ†%€¦¡H‚%£Ž©H‚d\О_,»P£0åp‚€§Ã¿Ñ'ã[·nðÁ>Êó¼\.ÿõ‹ñ$+<üð;ÅÙ$÷SÑr ñ$æKž* ™B °Ñ4ý”3†Ã$ÿâ`¸¹ä\_+»–úødr|6^n—4Eæ‘ÕÕ<­ê0•)F_[4 )ó¢RT=‡=I£þ$Q #KóGöëÍ&c&¡âþçÏž=9o®µ-E$‡.$l{A¤pÛu#)d¥dTJÆ8ÈF_MÑBð (¸\Lz!3,ª<‹Þ¸Ù>ê<çyV,UõÇ'“ª©ÚèûyÕ6¥„y'F †Òd\J>K°N9<ȨF E\¨d\¢0W€U$ RÎ0¬ÛZ’KŠÁvM»š¦…ŒñRY¯ØÊõ¶3òY˜-~1¥XQ(Á(ËŠ‚ H0!X¥²U¢_>8)Y¬b“ƒWýf½¼@4Á¯g†s!¢,ÏÒ™èI$zm·uÿÉíØµríéó΃Ç<å;;›Y/»„ax>åÀš……ý X«ékPâXÚrÃÙ³ â-`Pœ/ª)9íÏ4Swý/>?\m—®oT^ô¨Ê®®&µŠe©¨àRÕtƒ Ž1R’<È9tuèçªÅ—>€Ò2C@ ¬¤ .Á,A®&9à,{J˜£B€ÍšÆù9‚àfÛùÙI? FÁ¼…!…ÊȽý²ìÃnßRåt>w« ³YÑïy²¾ÖZ„Ø,Ö8çNÉ®–Ý0ó0ÞZ®9®«Úú—Ÿ=umkÉ>yÒ»¸*32Á j"@˜)ñªIû± á0]ÁAecµét'±@ À#Œ$@‚îY_JÙíÎ<:73à ÞéN£ÍŠ9;Êo”•YÌÇÓÈÔ´8=Be¸ Ä@d¹È$PD\ªh*¹Ô€Ì—R=LSOÇu‹œN2áZUŸ$2)ÄVݨ:jÇÏóœï÷‚ºµZ3«®vÖ‚¤xk¯Á(+ âØRDY‡ãi4Î÷Vm‚¨#ôíhÂsˆQÃsw®¯žœœMfÑ{o®ek”ø>¸÷äüððbxÑÛØÚšF j‚yRÖ**`(ù—Z±ØjË “"I‹Àa´ðò,?{uyvx™§y¥‡‡}Ý1«­.¼¶Vz¶ßW4–¦ùõeïrÆ5‹%œú±¯PÈ`K¹P£œKœrj°\#<.p.N‹0'G-¢ÍR¬RX6Ð4†aV¸:Ù¨hϯÂyRÁGY­+5óbœ$—BðEŸŽaA–ó‚KLÉdkT”Mœø~ÉdEO¦Iɵ]•E‹JseE¯?ç@º¶2MQ•ŸÿéG7nm¢Ý»öðËË‹Áõë;™€%H;³@°RRf ?g*ŮɯQqcÍ+{0Œóo^jŒñbR>œ…Gç®k]õÆŸþæU}¥ùäÑQ{É“¤I¾³Q9¹˜R:}q4Ü^6¢LöÆaÕÑý$3i«²„¡` ‚ÈŒPWˆDˆB¢*¶£Äáèqž5,h( €€¿ÁÔ&ÃP ÁÍf£Ùl´Ûíf³õ× Æÿò_ºÿâ_”~ï÷¬ßû=ëÃ_é #oÿöÌR‘«ã_X*.¤7Ï-×,V¶”ói:ó•Š~>Š#w·Ë#?»Fã »¹îÝܬ–íbMgÉÍíš­áŸþÅcQ¤«5öÓŸ~¸¨”=‚¡XŒ¹À9Oò<åÀ04B°ahï¾qC´³a¿ÿÑK[u¶¯o¿ÿ«~ðÔ®7Ê&T0^Í Á nã0¹DK%ͶõV³(„/2𵟶ø_J™„Él<ëºùÁ/Ÿ¨¥ŠÈÒ›ÛµÃAl€ §i–å–FqËÁ—ã¨ðtÐõ‘«q‚Ä8f–’$¦±b°œáBæŠN3FxÆq!pI“”Êu†§1Pr4Ê%j:´î¨C?}p2Ýj˜IÎOQ³¤½¼œÏ¢<ÉÅp–LÂ|ä§ó óSþl¿ûÖíVw8üðäûwÛŽ&?üàáîV5#(©œSFLÛH @¦”Uk•y0«Õ‡/ÏßyëÆÍkÍŸÿâþgŸ¿òç°ÖX&2tT¤Pr2Η\Bxt3‚¶Æ ƒ«Kžëh~R|sp­ÅKÁ÷§Áh8õ'þÿbü察¬.{“0ÇB,ÕÌ«iš„‰­ Ä8Ȫ6êù²n¡°P-–" ièC ö¤˜ !ö ˆ(â L<†"ŠQg.˰t9ç5Ú*ʸ|Ée#®"bϤ—~Q2YÝQ„‡]åUG=¸š‡ÿ;o¶ÛUë¸t†AÊåjÓYn8ãYôÙƒ“¾¹tyуˆPL!ÁoàÓBJ]S U1tuogmuI}ÿƒÇÀ·ß~½?ŽþôO>ýìãgù°Ê "S‰ÐLÖmÊ0zr¬W´š£"þÃ;m‰àÄO Rò×ì/$X„‡³ “ÖZûñá(WÓíÕRœä×VK'“\d™F‘®¢ †b2Rôfaš*͇Ï ŽaÖ¤£ä…`"S‹\êrŠLhŽ (Fa®¹*÷tr0H–=æét¿M¢bµ¤vçÙknÙTʶòüʯ8êÍrÍÕ_uüá<Ý]q˶Vv´ggÓƒ“a³¢m,YýÞ¸H“Ýíµvž #ÀE[eÁœàkº*1ùÉÕt~cÓ¥ªucc½Tªþþýúð¸÷å'/vönΰf‘(çSi©PWÈñXØ*ZòTŽèjËé‡ù¢eýõ ÙW¤K!ÄÂ㟠gQw»Óá8P]ïÞƒ“õåR”óí–ý›G—%O§XjÚ,?Ǧ"2ã\ÚŠRj«0ášNe!©D'Y.m&*)GI-E¨TΈ ¨™X!¨çË’=ƒ¦×mZ±”Ãnp27Ö8Hûó”Q¼R5u•\ÃY2 òá<™iÆÁéåŒaxÖŽ{ã7÷j:.¾üìùîv#ÉE ”äB–®jjÎ!aÄÔÔz­Ü÷ý;»Õg¯ºßýÎíµµåßÿƒ_>~tâ•댙ŽV”M– ïçM‡iwæÙjIÍ…<ç×V¼[ÕËQL–`Œ%…¹ìv†ó©/…Lât÷öƒêóýówß\½ìû ÅcUc­’ E‘©bWGãXš L„ÄiÄBf„zB„R¤ D\Á§D< ƒJ‰D:”É·Æ+ÿæ‰q­V1 1ʵm»Z­ÿ5ˆñ»ï&ÿüŸû‹¿ÿåv«uú_ý—…NyÎ[#¦œØ*uuÔ÷‹—]ÿzÓ„ ‚•š©3üèxÒ(é\•áã^øìl|Ø™k Q9ºšð›£¼½^Hùùý“ð÷ö(•Ïì¬X£iêY´ð›¾B)%&HdXz.ÙÝ[»««Î£GÿÅïÞÝØÙŠüñŸýüQž£˜SZÌe5Ì@”[…Ý9®W•zÍYny˜ ªky..+DP~!ãœ'QêÏ#aµ\.¸ˆþòÉU«¬vG‘ié ‡ž\Í^Û,‚ AX1éÁ°Ø®Ò´€)‡¶*sŽr Æs…s.P1GM”9Çi-%K9Šräi<ÊAÏ*Ãi,–=’`qLðrI 3‘  )8òG·Í’nj4͹ªk¥•†E(–ö'qÙÕ×Ú^oüâ³ãòã§g-Ã<œ‡¼ê*‘B|taš\J˶ÕØÚZ>>9“H"Õúû?º{ÿññÏ~þi˜]^Dq¦h8ö\ï|’nW™§+g“ìzC[*i¥’axUHÆÁBH¾™ñ^`ÏyÁÓ8}öä°²ÔüÅ/Ÿ¶WÛ –£ *€¶Úng– !˜„)/8r4ÉE¤T£yÎó¸PÎäÙRF@æ„É'E©4¦âØJF1€^ͳO¹š£ ßkã˜Oâü8FI!WkF!€àú²ÛªOO§ŽÇ»+ÞΪר˜ŽÇŸÜ?ÓTvûz£×Ÿ§Yn1~ÿÞs[¥E.j%`Tˆ¯¨PYQ‚$‚1'7on½õÆÞóãs0Œï~÷µ^oòýŸï/ú©,²$L׉ ºäR.q”㕲¢0"(3MU×Y’ Ê(  =\ð 5bžæ'Ör IDATÿìŸü'“á<‘!¥j“'/z¯m•‡ó$OsŽhEEžP ¯féFEMrÙŠ%û©P ø)Œsa°HŒ"až AN`.$\óŒÕ,Ê0˜%xÉe5‹Mc°RV‚N‡Ñ«®¿Ý²Ó\\ ÂËI²Z3…”O¦ûÓÃμê醦D)ÿüy/ðcDÐÙIÿ{o-‡ƒÞØkL&©©!JPÆa N Nñ,3Ê`Ø/PöèåÙßÿñÝ·n_[ßXùÃ?úõÅÉXBóðr¸dËZÉíùzköŽ PÖm³^wJŽV`²•Ç‹B,œ)åÂýJ¢ôÍ7vˆblh—Ó·oµŸìwS¡*ët¦U÷‚Ì3¨§³Y,U!"@ŠAÂUD‚BR.¨Šc (ˆ L  fÐ#q¥ÜQå$ƒ@–u˜²ˆš…£LœŽSKgž©\LS×`MOƒ£ÃN°Ù´¸¦Îno”ךNÍÓS.ã´Xo{Õ²yr99<ýèÝ~wtrtqcÕHãT×€„/0eœ8Š®´je„õjÕûøã‡ã™¯bôŸþçßûÙŸ}þôé©¢Q„NÎæ®*=Ç–P«[Rr2ŠÞX±tE9Ÿ¦7vêkKî$ýj/cüíQ ™„Éåi·Z+5—›Ïžõ¦¹<8}ïõ0Ê>úâäwZC?©9jAŠ@ž¥˜R„ûQÕ"—³<ÍcÊ$—ÛPÌD;‚O2‰t(f%þÿSŒ[­¥_egëºþ×#Æß¾þ÷ÿÃþoÿ»øÚV„ ¡àbcŠ¥ÁÄ :îNG!_ÔøA.cPJ€Pa¤UÖÚ£]55…R‚«®¶¹ìå9—* í |)ÁKO^vê.F''ƒÝu×`2XJ°ÈtÍŠ"ç<盆yÝÓ^\Ì‚”ûQ> sC£« »Z2$BùéáÆréþónÉVw7˶†?ûâÕ‹g§ïÞ®C€¹„yÁ¿i…¦EѲAœs]§Š¦[%;Hó’SÛ»¶¬©ù“WS-ýÁ}¸²äJR‘B” ÈPw3œ;Û¥Û×›ý Wt…PZä…àHÀs.„ '£Ély¹q÷=USây©"¨r|1¼%7VóÎÌÒšËì÷·ZfšOG«5 AeB¤ž ,%TI!ˆ ªŽ¡Ì¸¢!@ÑIŠÃØPp,$–Põt¡RšqR3ñ<ƒK.Q(:è§M‡ÍSr¥¬uçiÊå;Û•i”Ÿõ‚Im.9oï5ÖZÎ<.Î{¾eÛ+¥å%ï“ÇW¦ÎV[&…üуƒš9T»Êà›q)‹¢`šµC@L +U¼Û{µ'‡é`zûÎ?ÿË_ÿò3mÄ ¦®†/§¼åÒ¬ëß½Õ´k¥ Ì•i†ZäEžæKÛKw¾w«Ô*—Z¥ãýsˆàwß¼qtvµ·³vrÖwL¯; ²8ÝhÙŽF¯m”‚½àzËâB ãíšÎ…|5ˆ–\Â…|Þ «&’ @(1‹b!AH<K¨!r sAœ#â¨#y2YþöÞëWÖ4KózÝçmø;b{wÎ>ÞTšÊêÊÌòmfZà 3 !®@#®¸à.¹Db@£nšnèééêîªêÊ2yÒœ“Ç›}¶w±Ãûøü÷.vV„Ô  è÷2"¤B±Þõ¬gýž²CN‰&£Ö4™Ï¨ˆÆ(Ü®9¡óApmÑݘwV«N–4þØO®-ç®®äý„6Æ­Þl{µ¸TÏþÙ_¿‚­Î[Ÿ?Ü»½™·$æÅÄ^2J)çQš†Ib¹fi.—)¸’"]Y_¤@¼~¾Ÿ+¸ß¸sýó'û_üúÅ£‡‡ÈÎ,ÏÝI¬É°`+㕪{{kÎ-º÷oÖÏÚSŒ!MçœS¾ùÎæ?øáõæ(<Ù=[½¶„˜xðÙë[›§íäX~‚Ó8 8*»Š«IgÃ4«KA­©(˜H ïÃŒ*$ „L!è(£R!@? ¶B â\ÀY"›2í(£ …€ó/˜P“Ð~/Î›Š„¥¬ŽlMæç bërÌ`Ñ–MUÚ»˜Žýt.£½9ŸŒü$NÙp÷gqwx1 ©ØÙmݾZé“çç7¯–_½ºøÆ{w{Cÿoú8W©8*'0B`Ζ€¬ÜÙ,p]¼HR%]W(ûPÎ9çŒ Î/º£‰÷îír1ç‡i¯=ªÖjÏßž\u¾`œvgG‚´–Õö{ñbNQ%¤ÂODÁÄ£€ºSÑQ[¡ˆaÀc*T þ}1þ;Ï?úÃCâ÷ÿ`¦Ë,Le™p€LC&*ag3Z: •’E€­)«eÈÅ$©8r˜ða@OáZÙR2ðÓ·KYKe\@G>}y4Ø=½$ãhaBol•Eò£ôÓG'[«Å•¥üÁQGI½¨œ·<×ÖD”sÀ$­áìÁÏgæLWÇ']dª!EW×Ö¾9øàýë©PÿâÏ?yòìl–H§ç£_ÿòy{&\’pU%ð£Û•b5§›j±œÉWrÁ0J¬Œµv{M1T¢+o^ž·»„` ¡¬¢Ç1»½½ñÅÎÅd®-åã€s^Î?{ÜøÖ2„ 9ð½i-¯t'"š%§‚ •  ¦”K '¨pRŒ ç12A€ $Øi{Æëœ2q2Hr¦rÔóš«É{­éFÙʘêns²Q±—æ¬ZÉ ~Þõ{ÓÈ5ÕÅŠM$²w:l´&ß{…8Ÿ>9]]ÌI´­»n³3‹£Ô¶T€ 1òüÕñã¨7KLÇŒy)XY¬m_­ö&ãß[»wÿšªò_úâÑÃs®hû¯ÎͬÓlt¯-¹#ÅŒòí» õå¹û·ëLRÊsö¨;Þy|p±ß<~sZ߬Mýà“Ÿ|™)¸»»§Ûk‹Õ|®ÕéùüÙ J)µ y¿í½³šóc¶Ûõo×lÁ£ÓÙ½ BøøÌÛ®ŠIHOAV§ÓˆªŠÃÙØ‹Æ&³0)WUM"⪌ Ô÷aÑ®NÚS6g´­9™ È^.hTÀ„ƒõ²IØmL.!û)åŠL¦aúd¯SîX*"ø°5ýåǽ·Â!úêùùw>XkvÆOžŸŽ{½w·óƒ¾7–e!.×”/凔1ŒXL)Fœ¨êw?¼oZFœNzçƒõí}ÿƒ³f_ÓÜçÏ3¶Ê8é4F9WÇŠ:—3MC^Ù˜_\Ì{±”!Œ:'lj*1ÎÎZ1c×·VŽ.Ú?úö;á,žñlšôÆQ)«ïv»¦üb¯«ËÀ5¤F?v ÉAÊA?€%K :>Ê‚ а£r ‰”¡iL2Z’pÍR8ÁÛQ9B€ #g ”C™ŒÀ(Y¶¦4HxّΆÑ( Ë%S@˜0ñåJΰt)HØJÕÙZÌ.Ì9#ÊAgsf­ê>Ûíl®•ê÷¼5~úütµªç©Õ™*ˆ\bû„)c%Kô½P–A  ¦IWÖÊósÚÛ³¶c‘ë·7”ÿøqp6 ¹6èŽ,“<ÜÍå •€Y î®ç²s9]—3·ºPÃaLSºz{um}®ZËï¾ÞRžÏ:‡»§wnl¶Nº •ê§/OK-dÍÞÈ·tÙ6äçÇ£»kyÆÅ“£áÍEpÜõÃ$ruÔ›1]–0Œ@˜„mÁ=D‰œ ‰@¦P€!øbÞE~Âö{1ˆ2¾^Ò)'=ÿþj6eâ¸ëyýíRÑ՚ð9ð{“h½–Y_ÈVŠVsД¾s³'ìWO*%S!ð¢9Øys´U7x¦À×UJp./ÜœG) ‚¸ÛnßÜøæû7ßûàÖWOwlUþÖ‡wÿøO>ùòáÑþî`ÂHÙ¥¼ó«§Û+™ŽÏ®/ºïÞZ(Îç?|oÙKA©š-dôÁȧ ½ú­ÚF ©äÕëƒ×/$S¹ssS@ |Ò–F‚”ËŒ"Ê‹–äżﱥœØë¦ëE °ÛMWóä·•¸`â¿ïŒÿÎÿð?Zÿô?œÝ¼š C*R‚È|Ê€Ž`¥A|Î&1S5¹ÆAœ3e×ЦAœ7•²¹Ûš¥œC„T™dme¾`ÌÍ\FSUIU¥4aA˜¤”¶>™ÅqÂJ‹r±{ÜÏë V2öµÝ…q.ËÒÂJ! pzÒÖ-£ÃOý2SÍc@Ã0¹²1ŸËZÇç­•zyc{ágó¨X,Ñ4šwp[ÞÇ÷Ü\vs9k2ÛeÈùËGûݳncÿ`1jŸ÷˜MïÜÜìwG‘bîðbÒÇ‹óù‹žçèRÁÕ^uÞßž|ú¢uµnvÏ'KWI ˆ™"¡T@@Hˆ §Ô£BP–Ä9šˆ™b)Œ`¤RFAªlÍIA „€•ŒÖư–×»^%4NY-¯_B͆qB™ª*ëºÜŸFq”FqzçjõèbÉæJá‹'g€Æ®ËÖÎn3›Ë!4YøÛǯO“(!2 ãdi­Ö:kŸ÷nn ÛCÈk;/:żÕxþl³æHõ½5äa²†!xÓ 6çtŒàN;ÌêÌOÄ(d¶B£Ìbà¨4¡’„€L„@¦!3 †£‚0…á^Ì¢TØ*èÌR.@Þ ÍIL™$œ·5‚Ñ嬪`­`lÔ]U!„àBF[šÏD …–Úøqœ^ßœ[Y*|öä,˜Î ‰ÎO$Ecâkÿå\“À,ˆAš4z“|†¼=n§)üæ7oëºúdçàöæÜd2p ¹ƒóñ¯~þâè¬wÞõ÷÷š”QÅÔ &‰ÜX-–JN¹^¸uµÒ›%“ÞDp¡jjœ¦íáH³õ£ÝSÏ Ks¹Ôol®üêé!…hy¡úö|0™ø7ÖK^˜¾9ì¬×œ8eûçÓrN•1ˆ(¤’ R5ÂGAŠl•€¹ÀR„°à†1t Q/e[òœ7aΔû>¯¸’Ä’Å‚Q´•7çÓ0¡”‰`ˆ`œÐ8e#U•L]A Ư¬ãÓ‹1¥|k½d[ÊçON¶Q·¦“ ß÷-ǼœÌb€‰ÌNƒPè2xðåáÒê¼¢HDFAÈn^­•ê…d: }dØúç¿zñÁ»×ùðhpÞÉ΋ÞZÊ»9÷æf¡PÊê¥[Wæv^¿|t°óòd±–†Iw0Ƶ;õÅJÄÅŒ+[öÎÉ€A¬iòE߯fuÇÛ^ÁQ]¼<Ÿ\¯»€‡ýå¢8ìYƒ@÷£ŒN„ˆv€ˆ…ˆ®cHc*¸¶Šƒå ! 4ļ+a¤-‚E°ì*=?u éJÕŽxI’°õy;H¸¦J€(¦qÊ0Á‰ŸDar÷Æ|£çOg¡¡I«ËÅ·‡]õysg·ÕîLò…ÌåÚ÷×Ù—”N'^»Ù_]tw[GgÍ­í••åJ£Ý-ZîÆ•¥›w6G‡Ã—¯š{{ç¹|áù£]3ãRHæeñJ5w÷j¹X/ÔËŽ‘µ^=>8}s6h ÇpŠn'ÍF*ðÎÕõóËR!£Ö/¿Ø³ÜlèyQÂ׿Œ‹îtè¥ËE BÐó˜!#CA=é228Ðåù{™úßpþäOÍÿä?çL>KTSJ¹œO™Pd M†l…#ìèRÌ¡­áX•À @‹9â'C0ŸU4 ’’-aLå-9o+/éÍC%•¬®HälÎJ\ŸwS)Ì/ß´ •,TœùŠû|§ùf¿yo+/¢ €—\Ü(åNÞ…)‡˜MžÄéÓ¯o\«bÙ¼²¶ôåó½d:ùîÇ÷çæÔÓvÉ—>ýÕóÍ­ùŽþèŸÿ­‹«åú¼ë«Æû÷–n^©>yz2Îü‘xÁ°3ŠÂøéWoFIT©§Ý©HèÖÚâƒgû+1€û“ö·Ys\C~s:ª ÇwÎÆšBò6áB<Úë× ÚIgŒ Ðdv6 Jº@`HƒÛ*CÄ•a@ ÂÖ¤ØKˆ­²IÈ9–ŠZ“dΖ Ÿ¢Š«Ì9*@h·”]5cÈEG=ëÂzÁ°u@tÞ÷§A:ñ“åªÓýI´±˜]ªç8ù³W ÎâœAb§Œ_ú5üD¤ D¿ ¤bÅ ú)2t=åñpï¬]Î)¹¹òúJîo~þbâ'ÃIôÉOž´{Ór5W°¤Ã®m1³ºTäºöÝ÷WïÞYnNâÎq;IÒ~wTBTé‹_>K8³ NãàâÃû7) ¿þâMµVm"˜Æ§Ã­ÅŒÓžŸ.æ4Œ`k’è r5Ò™%*AŽFFS 24„L`D‰.¥bU( l |è($Ñ(“¤BÏh"£“qDæ,R\0IÁVò¦ü«·}ŒPÅUMMzÕ˜æ-¥à¨WëMãþ,±ty¾`J>ézGçãVß¿²œ[¬g_  [‹Ž¡¢˜Jè7X´(˜!)ª¡ˆÄ~šlñàéaDõz%HOƒµšµ´¸úÑùE'‡v>ÿŧ/ 'ß¿hßÚœCŠueÁ^[)*ùÜ÷?XÑ ™çÞ̆³`NÓY {£Vo©æÎÝûW×-×>lôO»v>7MàîQçÎfI•ɯŸ663†Šý(}¹ß[)\ˆI„3*BÌÉVþÚ' bÛŒMSaJ0‚€’Ñ1Áª%ÓTX¦’\vÕE*¶f|£¤IôãŠ#]uðJF)9êQן†4ï([u y¦ÍFt±lç\Í0ÔÏž5vz77Ë óÙO¿:õfþ­|ÖÄ#â· ã—vK4‹¹@XÕÆá¯~ùrýj­Z25ÕÎYöpØ»ymM3ÜÿõÇŸ¯Õ¬8¿øÅsNT†•9÷|&$åÎZ–ëú7nÔ,C9:ìžžöý‰Ì‚éÔwǧÀ’æ+ÅÃ7'ó¥Âz½ôâÅ~¹PK~yÚ/ØJ=¯s!žŸL®Î;Š„¶ëŽ"á''ãù¬ªJ€ ±ÓšÕ²ÒÛN˜Ñ IcÌ,¤LM…A¨©@0¡Z „)2e~6f*)çS¢\<;Ÿ•m¥`)!G½`1¯ÛºÔóÓþ4òbZÍ9[õÖÃI´2ï¶Akb„ʶíèñó·µ¢¾±àlòôñ^¾˜G_VeUW åP$«Òd6†ýþ”^¿¹¦Š*%ÁôÉÃÊBiûúúOö•@ÒêböŸÿ÷Ÿ}ñùÞû·kíi¬`X.»¹’ûíwVÖ¯Î7û^ç¸ñ¸?EšÄ xôé‹Ò\.äôÙÃ777W6–ê¯÷›–f>?îzÓps!‹1Ü?$)«æµO¹€E.Ƭh¢ÿ3¸ÿ¿㔀ÿö¿6¾ýýÈÑxÊhÂu‚ÂÖ$LYªI¼¼A!) 1„0 !”ÑÄ(à‚¼:Sz2Lª®$‚ 1ŸQ‚T :çª[UÛÑåã^0‹è7· «UÇÐåÁ4>lN‡³ø›×*£·ç£g¯›« ¹ÅùÌh윶ÛÍÎöR¦Õ $™@„¸”1ÊXB9Qe€®(KkµT@’ÿÕ—ÿÖïßÊUj?yÛ-d W·o.ýêóýÏÿö«B¹4ò£O&-›p¡êÈŽ¹p}Ù1?Œ+3Š’Aw…ñ°5|ñÕÛ±çiy‹ú‰ýû×VTÙì÷gXUg «Xœ÷üù‚lƒrNWeüìpX/š2qä8Hø$¤UWšEÜ‹EÑ„!ÅU"!*L ¼iŒ4‰#$ùqZ°¢É!Ä~*/d1„øUs!¸9o%LLcvÔ®×]“Ú£è¬ï+¾¶”ÍgtY!{ÉÝÍ’e)œƒ—ý0e?úuQ£5ò§Ó+ ÆëÃ!‚Hׯ9‚r@9g¤\Ä”Û*LYbËIB™¢:¹¬ã‡Ó¿ùÉ«ô»ï-.—æ-$™¨>ÛI¸zøúhûjýÙΠž‘2Y+ÆÚß_üöÇ׆½©7œî½8¶†\ˆÑpºól¿´\î§Ç‡òû÷-á1ûòŹ[.íwü/?ß½¹U–1ÓNß·- HcœKŠÄ¹ BÌÕŠ‘!`“0Ì»DÏH¾z}Rr­íëk»ÛŒ IDAT5k}«öàËÝÃ×Ç;ÇK'6f_ȹ®¥å¬ÿß¾×í{ åyGižõÒ”%IÚkôŸ>z#›j ù 3uÜÌ$ 3XêvhŒÇ³ø›·j¡Y|öøø×*µ¼ÔëOTYF˜p.„)A"EU±a%‚UÄáQ/¼¾R¹q{½Z±&Qòñ··7óŸ=:v4ó£Ö‡“ðñÓF0K>û|(z5§ê¶)Æ?øhý‡ß¿þÅWÇ[=Ý»õ¦H%»¯†ýñâÕH¾$‘Öp"’Ä*–&1ùÅÓÁÅr=ñó7×Vr”ñ㎟±dGE^$)“ÿßœÚôÿx1þþ½9Š'ßù^7k+ûmO—¹D@cœ.fåiŒU‰ËD@pN©P$ú©¤¦+F˜Äyq I¼œ—TÂ4­8rs’1s4’ÑÉñ žE¼ž×óúÐKÚ^œò¬¥ÜXÎE ô§q¦Û˹À aAD§Ópm!'«òEs(Á¤œ7 …pAÄezãenão¼…a¸À+ku?”Æ[(çW+™—/š“ˆn­Þ{÷†€ÈÕIy±úå/Ÿ?~væf³GÉwn––«[×j?üh+x¹–Q¾¸²”ÍÆ^§ÑÛß=«¬Ì¿ÜoL»ã¢+o,/÷û“go.*ÕrÌÙáÅ8ckÕ¬vÙ›–³Ú4Hƒ„Ö Æé0*Z².ãRRÎÀªq2‡Ð”©— …•pYÎRqSÁ>bJ®F]-åä‚)M#0ôSCF›e£1ŽÃ”W²ÚzÙÅ|$aLu…Ìåôæ0ŒæùɵÕÂ$ g͉¦†&Û–¶s<Ài˜³¤¹œ¾³ÛÌåÜKSÒ¥E3åÜKXBÅ(à))gQàŸœMø›çÝV1kdC‡ ªo,}úóÇW¯¯ôFá_ý«/Z=‰Ó·§£ źqÿv]Íg]G¿¶9§´»ÓH£ôâ¨uôöÌÍX@ÒÞìÓtúÞ;÷ŠŽÓ8ï,–혻Ãæ¬˜· /ß¶ËE«ÓE®ºÒÞéP’å‚…Ž[SYV( ¢K(ºǺÄ$ f11.Ë&qÊ.—†˜— ŒÊ*F¡(š°5¥”‰²#¥L4ÆiLE=§ÓY˜ ¯×Î4nOâ„ò•²5—ÓwΧÞ,JY1£ß»R~}:ê‚…ìr-óðåEE:¡kUû¼9VõòÛÈØ×ÆÃK[Í,b^Œ0F¤ƒY0GׯÔ.JAˆ•µ…üÁÉäåÓ½·¯¶6× ¤¿úëÇ×o_ùòÑ^û´+ #_r¾ó­ÍÜBi¾–«dõrÉÙßo‡³pïìÑã×”±Þ ~ñbç¬Ó}çöuá³ÖÄÊ:gý`ê%³˜¦4~Ö’KYãñ^÷ÊbNSH£ïfQ%CöZžŒã”Á”‰¼Ib†¨€†Ìr˜ ˆ¼; '˜ÄL±UÆ„Š]Ê)^L$ÂW Ú8B ëEýxCšP±]³s¶: ¸¦¶NòŽF$I–IÓ J-C*¬óžEt¡âÜÞ®>|Õ' L«™^w(þzÊØ¥õšr>‹™„¥(…­‹VoÊÞ¿Y/WMÂ)ñW«n__ó=?N@³¿Ým¶/úš“gÓQ©`U—k·o/|ïÃ-HWVrË ¹ó³A&ƒî°Óèuú£â|AVåA»m¹™J!÷Óo–ÊŠ”Îpúêh ëŠkH§ý`uÎ’ :î‡K¶TÒÇÈy±°URIÆ\%@c ƒ:‰bŠÂ»ºÀIJd΀D`¦‚rèªlQ(L…äMrãZN~sÔ‹ƒÄuLûM+eL’È41C c– ü(:lÏ®ÕsÃé L‰•u¯oæ§~4F+Ëù ŠeEyöìp‚¯á`è1òÞ;«7n/e2ÆbÅö§ÝÎ4˜…½fwç¸Ó`SÀçþfÆ^Tv-'o¦Ü8ïÔ+Žc©ù˽’+¯Uͬ1"1ƒ¿%ÿÖ6,„ a"® â@=Nê¥ÂQ{øâÉÛ›·7ôÝ÷ÊsRеwï_³{¬I©îÓ—ÇN¾¨Ë¢6g_Ù,û’úÝ÷WÛ­Q»9Lãt:ñ[­Þ ?ög{oO‚ z÷Þv³ÝW%)MEi®0ð’þ „ŠDO)¯-áþŤ^4ƒ”G”—l¥5eGÂN"b+ 7ˆ'£ uT6‰[N DÊ$8´,9™Æ²& KÃ2pT4°.‰¬AJ¶ü¼á‡)/ÙrÁVŽG©JpΔr¶RË›[}q6Qe<—ÕL]~¼×;jN62µ9g¡êþô³}ó­%×Ñ¥”a!ûÍ…û’û–2¦4b‚H„Cøj§qÖóªy)dꋯöþË癹ì÷—_î5¨7»qg+cÀgÅÉþÙŸ<ðBšªÖµͲ^È]ÛœËXÊËg§œrâŸì7Úí~oà•K/Ÿî}øî­R!»wÖzûæâÖµ­qÌ>Üšž7¥„ñiH«5HØ,b%Kº˜Š¢…^îw粚*‰×g×$ã äœ*öl«Œ ‘.ø,fãåÐV˜Ÿ€˜K…–Ú3îj0eâ°O Õ²JΔ›Sž7HÞ”{>ëûAx º¯ÌǃZÁ˜Ëõ²ýüdÌ…˜/˜yWƒ=zÓ¾µ–­´¢+ÅTâ— B/³Y//7¡Â˜Cˆ „I…°‚ ¡d9¦²ÛèÞ»~u³…’²u务±“ƒ‹Î$ñRQÍi®¥ô½ôÆF©8Ÿ›)ÚwWó_~¶ùQà‡Ó¶7 ŽÚÏí¬-X«ë«ËÙÝ?¯WªBQÞîµ»! ¹04ùÑ‹‹k륬«ÁÿË25|=;MOÓcÀéW§ÿ°ø½kõ­ËWc,˲†£áptxxþÎ;wK.Ÿjµ:ÿìŸýç µl6ó¿{¿üàw‡ÃÁƒ¿¾s禮ë—ærù­­kS!cþC1þâ`Á•÷ÅÙä½ÕÌù(Y(肳Q3&þê ÿÁVþU+Ù.ËŒ#/•%BØíë¶þηnš¶±ÿöôý÷nB 5p<úîG7¾Úí6NÚßûÎíO>{õîÕ²åÈ/Þ´ÊsÎÚ¼óúhP+Y—/%WoOÓ¥œ:‰¥Œš@„r&ÁD‘d…AŠR†•ÆŒx1Ëé¤5¥—û£³Xtg `aÇy:*`¢QÞ[°‚„ô"…À’> ÙÈ‹›ÀWK#/9éz½Îtµæ–òf&aÐìy?xw±?ão~©`‰H¿†^ŠKz=Bˆ ÐdÙ5 ƒ„“˜”,øó‡ÇÏO¿óÑk×ßž?øõÁÛ›”³¹ù“',ôÿü΋Æô£kEÀ$¤­i²YÒ'!ý¯þ›gMüv¯…ºDÿüàGw¾ý;÷gÝÁ¨]«ä#lºcF˜¤ê¯ß__ÉÕçì‹î4g«Ž¥¼>Ÿ^­»ãd½¨¦ NcbH1@ÑQ?Z/J=_-@ ä= €6àCpÊ M¹@!Ó âsN† b9'ù ÑõX=C„ýY܇†B6ç /f1åÍéfÙ$IzÞóâ”}p­<ñ“ñ,~òºykkN•É0`‘&L„Éתü NÆX"$NSWO>ÛýîÞ=:ë—³è³ÏŽî¾»@hÆ^3¶:÷o,ìy½Ö4òOÿñ;»'“¬Î+ew§9ݪ˜o^7þô_>3U2ÃIˆ*În¿»}üöLÖ”ï}tûá³ý\Æ,ä3AŒÂJx: †ËEc>«#:™ÅŽel–µ©ŸLÍêt¯9›Ïé1G€Œ.Tr”"a‹¦ã”ëzA*ɘĦ1V‰P §C”Õx€— œÆ0)ƒGƒh£¨ø )÷c~Þ÷c÷Ör“ =hM-UÚ®;C/éÃó‚ðÃÛóƒi´>æqüá;ËûmÚèÎLSVTÕ‹Sñö5£¯\¦ªê2êœR²±¾2öèÓÔ~ô‡ßüå'Ï4K­T]Ì¢ÃÑ™3?ù›¯XÂ6ï¬üþòbчl°ŠC.N{ÿâ~¤)$ ’Á$”éoG4mµþãòþÉÅôõ^÷÷~pÿ¨98nuƽÉÂê|NJ^íu¾ûÁÚÏìÿáÇ›»gcÛæìý–§É(k©qº^T‚Q† BlGq?ašBÒiLrZÌ"€„ôS’ÐØV•Ö$œw‰ çñϳX°3cYiŒ:hc]­˜)¡ßøݨ„ ›éÎÙh>o¬Ï;Q˜&ôèbLÿèÞÂA;ܵd?—Ÿ$ÿº©“1ftøåÏ?þøÞ¸ç=x½óí»«ëó•/Ÿ<{{4&ÑGß¹Ýëwƒ “Í|þÙ³ßûþÍs/úÎõ2à| Ã݇»G‡W—dU><î!‚!‚„$N!°\)É–F‘ðÃh2˜Ê–:úïn–ç¬cIJü›€+aúzq–ž޾<:yxòÿåÎxæ¡ÓÎh2 ±¬uR£”5ÛS×$/ÎZ²€A Ë$¢ÄŒ„Rk⊄@8 €L°‚€—Ê2fŒÃ”£K ÇKä”ἄ“y]ÎËÁæ4R`kƸçÑIײúbÁØiͦ!¥Bl-d>x±¦µ‚y÷JÙµµ³ñt}p«ùþ°? "ºZ1] {éoQ2"e,¡ÔµÍ•¥ê,ŠŽš‹µ±ïmýlÀÝ (tl{miÑBxÁïÿèîg_¼¡ üðyse!“ÑP×c¹œõÑ·ÖnßYš„üÊJþÅ‹ã¯>}9êOZ½A·7 'AΖ/z1añ7ï¯rÆfÓ¤ZÉýäáQ 11ìfg4"ø¼¬–aÀŠºDE‡¤ŒõgÂTØ^7(ÛÂO0ÐQYʉ%§9–œÀÖý˜W +¦óŠ-T† ˜7ÉBVIèy¼ž•m•œ £ ᪌o,¸ŠªôfÉ,ˆ7*¶ ˜C8‹Òé,*eô|ÎxïVõêfyc½¼°\ò!iì6ía&G§=È“?ø½wþ꯾ºèù‚ò½ƒ³oß_.–*Ýî0—+0„OºÓñÈOi$àùÅpµjé zv:®d¤ÎŒ–,¬8Žˆ£0AÂu…)b„4„dÇkÉ ŠÃ Y¨hÏP˜Â¢e{²UP²%á‹‹ÀÖpÎ0!Gƒ¸êʦJª9ý ë÷½ÔÖ¥¬%§v§ñacŒ!]¯Õ¼ÊhúìÕÉýµLÙ•J™„‚sÁ¾^®”_Ò€Ÿ€i LU)}üåëÚ‚ 5k}©¶T7¹HS²ÙÊéÅxÿ ÑéxÃ)Ÿ³ñ|Á¸Ç€{7j×®T€í\ß,^ŒößG~tvÚ{úèíþÞép8éÌ¢ÚBI¡Áv,׬͕ñé«ÕÅ¥FgèGé„Â^oºR±v.f‹EÃÕ¥³+9JÊ‘)¥)È@xÊb ¢” !àÓU!È™Àœc '\`ÊeG¥¦S®sq2d9¹:žsC‘¾pu”7•ÓIÒóÓ²£X*©äÆ$NÂjÞX©ºó%ë¬ïþâ"ãk‹nÉQ>{zZ´åõŠ9‰¾¾#B/ÇxA"LÇõ»Ó7o›76 ã-¬·g][J=~øÁ½ÅEó“OߌÇþõ»[Ožì¿xqªæDW""U_Z)ß½^uŠîâréä¬÷âáۣÖïEíæèÉÓƒao¼ܰ óúÆ’A¢vÖ–çËn&Œ’ID/FœH +ƒI°^±¦cÚøå¬<‹ÒÖ8v4vØ &’°èû(«3?UeÌT 7U’`l Hm…¡dÈ\#@0‹INY#$¥2´5\v•ƒ~:‹xÁ’æs:à˃AÞRJ®ÆzÛœ- K—JÖNsÚÆsy± úaüìu#ñƒû¹’…mÏâ¯QŠLˆ˜ÒKg{Êx”Ò’£ªÒeø·¢kœ <_ª,TìãÖ¨=þÆýÛw{Ïwwܰj=£ Ã^ ß»5ec®²PÚ¼¶€5ùѯ^1ÆZ½££ÎúJþÞýí?ý£OdU¾wkëÓO¾ª”rw¶×wŽÕ9»ˆÎ8Œ:8ìøéQjið¸çÏÙ˜0 øœ'‘ìª)ŒWʘ  A åÀ€@2pèÈ86dx>æ³X¸,˜’"‘“×$¸S†Aúò«e”‚­ÌçG§3ÆEÑRòŽzØõ›£°^0m]ª—íÃŽ?™„«U«œQl ^ ÷÷®T T0Æ¡K1,¦<¦"Sp-פŒ‡LÂDFHŠ)WU ™²«Ñ|±ÞŸÅÕ,*Tjoz_=;Ž£´TÿË¿z<Œçëeà+s7¶çå|f~}~{½4‰™¤H½‹þÑQcëÚj¡”õ¢ä×?{ìpçZE‘ÉßËÔw„â÷)Ñ(Ä¿û?žŒ'û×6Ö~üà™é˜˜ ’$²ë´›Ý½»„<êúw—ÜãA’ѱ¥à¾lh˜DDÆ\%" ²Œ)< ²Œ¨„ÈKdSŽ~¢p\5bQGº‡):è…U—d4<‹ù0àQÊWòR˜ŠÝæ4LÙJÑ0L™èLãvß»±œ»è{íA³•­zÆ‹R?¢oO†iœÞ߮Ϊ²vʘŸð”‰”±ËVq©¾^þEÖ³NoÐÂÄ)eÕ—ûŸ}zX[*ß½¶!øìÁ—û^^Û.92d)“³/ydÍBþ?{9x'-Áç½S7ÊÔ¿8V²ZÑQʳø´=e”]½V4£„>ÛíD~ô£o­{aÊ(ƒZ†ÐzˆÈ˜àKùá2®B˜1Œþl6»µÕúŸÚùH½¾Yëµ/^ït!ª©.VÔwï­´&©©@SA³˜õì´Ó›NFáÙI7b!M©fjNÑ)Ì*ÅÝ“k›Ë­ñheÎZZ^xº{!Jš„®c­dñÀ‡ºöOºß©õgqk]«;ãvgézQ{ÓN¯ÌI ݘw ¦M#8᪆}À%DIF$ª‚<@Ê@sʹKY¥¢ë‰z†{Óœn×í0á­iÜî͵¢™5e ÀÅ0èôfÞžÍbJù¯[s9c¹âPàÚ¦œ2֙ŗsåKõ€ $jÙ,á³ÃóG?uëÆêûß¼ýÉW/å ©nÕÿäúõ“lÁ]½ºdÉ¢œÁn.“r”7„àbœ<ßi»ãFkL:j¾¦ÎAP^.ß¿sµuznrºªD4øÖíÕg‡CD0@ ßÕæÿ7öÞ¤G²,;;wxó3{6»™›ùìáá‘‘‘SeV%+YâP"Ù"©–A@Ëh¯ß •vZµ¤7Ò¢% l‰E²8TeUVN1Ï>æ6ۛߵðÌTSWÜuðo}{Ï9ßù¾ó-œ÷·ƒµŽÿô4üd»‘0u1›MólN:e €nùf€˜rMœ` „ö)Š( tšášÃ¸D“ŒšDU©˜ÀýµJ˜b”0u6ç6Å 3.Ô4aZ©å†; ‹AX £â7o4ÓB&…¸·;Xo—›»àr0Íö'%ÇøèíÞ,Ê¥B©¶èB«-Ž@ 1)åRº¦§ Ÿi IDAT ýùt¥f)9 Ÿ>zuôà‹ý[ïoßÞì¥ÉðOþ·_Ù„.ß\¾»â;¾3Ä$h½a&LfÙ×O¿ú»g„^pÁ„að_þ7?ަ¾~ñøI†‡GôûwïNr¬¶–š_<ݧ Jö{kJÈ$Ó‹%FÍÓIË®:Ï…U² !’TžIAg <…!ÀùX§„Be¤s €œÎ€ê(ãpꊃê.¤ 1»˜ç¬”¸Ô¯‡™ÒúN× füÅñ >ºÞˆsq2JûƒP+½Þ­ÔÊ–Öúø2ê÷g?þÁæñP”Êå0Ï´Ö—£¸”®ÊFŒÆ,J«žHÏÃÂZ(9çƒãÉ4;ÙlÝÙè÷ûGo.kÝÎöjݧ¼µPc’ØTYT@TÈG‡³ÃÇ£qrôú!D-Ob¥Ô¿þ?øèÃÍ_ÃÔÿ`üÕ_=áIÖ]j./ž¿Ø?>‹Ïa§ËUëý;×/Faœæ£Îç¼YvÆQ>ÍdÕ%1#ž ž B!&±m(˜+âP.4áŠ8WåÒr(GHçÂt(w .)¤©¹FÁ¤¡vp œ s’²º‡Ûezʜ뭧Sq†f)‹ Ñ,Ï5gïTÝÛkÕ°P“ˆE 3)Ym— ÓˆR6›gY–Di4gólc±”Æ)êØÖ•Ÿ£TJJ)•Š?¿ ã,7-=Ìàã÷¶*Õàøü$ÌÐâbkm©úþê¡ö`žŒâÑhx6,€®ûÑív«QòÍå¥JÂ41Bèâ|xqtyy1î­´GIܪz×Ö;——¦Ú mc©5•°µ\{~>Ý4«þhÕ+Žk¨ý‹¸êÛó£Q^ñ¬þžL¸T¯Ùž› ¬4Ø*„áP†âÊ6P‘Rà`¸!…k0$8žQh ¹¤e›»†ÊI9 W\,MÌ3¾R3} _ÌEÊ•eÏ¢ýHÌâ¢U¶nöÊÏÏÂYÊ“B¾½VŸd|QÂ0!µŠë¸æ$*¦ó,ŽsÉ‹,ŒÖ:ÕŠCJ² × ôŠ;¤äRÚ¦…±£ÀDZeàÛŸ|oëìr>8rºõàúµîQ’&èh¦ÓÉèdYŽmïo·Ú‹…vàW¼(åÔ¤cQˆ§w•ÒoítÏ&³k+Õ’_>èÇ­ºww«}|z~|:Ynú¥ òúd6œ ÏFƒ°æŒáéÑx¹aŽs!¹o©óK);:5ZµòBm0φ'C˱n¿µ ¢HÓøæúʃ»k½v«Úüòþ›v{áÉ‹a؉ŠkL2£lIë˜ÙžÁ0ÒÉw?µiA°R@¸¢6åJãT˜®Q˜D0I¥&6eBј¹5LŠîx†løä`,âBU\Ò ,×2NçÒ·ÈzÓDų“p©î´{©é=9 µ†FÙ:›åi! ©WÛ%ß1Üß=y²Õó«.² jîwÕŸÒqmÛµs‰(! µäûn£bôÃd±Ù¸½½ÙMË[åZcùÁ‹ã{Ÿ=„lquåÚJp}¥º±Z˜Rø›\R06ìO¤³Qx4J¤çŸîžF9ŸMÃa²¶¼Ø ÊoöŽ¿k¥Vv?zb¸î³£q§j.~yù6ñ-Øf- ‚ǹm` 9FCªX+fu©b­ ÃlbbH0ÒĨ(ó-U”rdÚ·tX`­¡×Ä£„8TU\ºP2vYÃ7Ú;ð̽Qá8pŒFÙŠ å²×p]›š=ŸåSýiºÒ.­,V¿î?}zX+ÑV@òÓG%×i5ªWýqÎyÎyÊ•I…Å&Ȥ¦ç8žôgá[›ÍkÛ× %ÿüÿúÕÁÙpckó‹¯w÷_,Ô\˵3EÞÚ¬o-W»KÍXB˜šTJ™EùåÙåÁ`ýôùI{¹5ɲ•ÅàÙ‹ÃOÞéÕ*ÁîáàöæR†LJmÎ2Ô*aß"ƒXV]"5âJ`ó»¦6D¦Db†µF6eÀ”G'ˆså m;3‰Ö@¤vJ–PZcU¶qÕÅa¡'²ê^Õœå`䙸U¶1O„.;FÙ¦Ï/’ÍÅò­ÕZ½dI —óbž‰Ý“iÕ7î]\\ŒÏÇïl%K•,õÓOŸ#®Z­ûV%çy\ˆœ+Ã20†a.6­{¯N‡Óùö[;¼óvÍOúµ6Ýþ þò‹Ý§Þ”Ëõê ­Êöj°Ü«Î€íÚ†eh©†óI¸´Ñ½}£¶aJö壽z«á"úbÿ¸T.·ª•ª_öqvzÁü t9ÍöÏÂ^Óy²7Xj9«û{ãnÍÂHj ì«fNi‹  V`!P8€E &ˆ+0µ6(âž)3AÒ®u„ÂÂt Ùô)še2°Ér݉ ½7,ÊF³lukΣãy§âLʵi³ly6-„EL#¼Üò}Çt-øÅƒÃýýþ­õJÕƒ—¯NÕºiPŒ1þV%eÒoT‘–a†¹Psà‡÷_yµòεõi‘5Køðtzs{çÕëËgOßüÆ{Ë£Di€í•Êòb寵öñ8³\‹šÔ°Œ$ÎÒ8 ÃìütÒª[Ê5}`ùÓKÝJ‘½}íõñPüÖæÚ,åûç£rµvxî,•mƒ<¿Hn.úðfÄ6›ŒùBIÀñT àH¡2Ö1€Ô8@*€ l—2@°‹«: ¸¡lCÙÆ1#³ •mh• ×$÷O"›âšg86}=Ìš¾Y²DèiÌr¡«¾Y+Y `ó(åݦ¿µZOÒôÓ/_/5ìG/Ïö^µ[u×±å,µ¨ä{¶oÇ+¹µõNÀ°º÷Ùó?þƒONúÇýá³Gûå%DŸüäÞÅùx÷õ`}k¥Û°Ö{U¿Z2«U!„Srol-´êþ¯aê¿oÞÃá7âëÿá´î~ôe¹4 £|>˜J ÿñ¿ÿ²Ÿì=zC)é.7WôûwgQþìåé~p7LŠO¿zþ[¿{п<=¼»³V±ògãw .3éÔ‘3ž+·bs„´Ô8–odRá„›e+&©PÄ5 &‰Ð†Ks P«†o¦©T¸&.–Zã7£Â °R5¦ÞŒX»L›>‰ru1Íú³ì­Õêå,ëO³ï_k„)€§Ç³"gpg£Aï_„§§“Í¥êÚr}8Š3ùÖÎf’“°0óJ%õ]ácRŠFÑþ“+pß¿µÙ®—ýéëÓ7Žc¿x~Ñ[k[2^[®›ni©¶A±~òzôbï"KÙEÎr–'y‘¦m"¥Ú½ÆÊí»µû{ã")~û£»g£Éþññ|ÿÆÉX^Î皢ªëŒÆï­)Ó«¥ª}1gRé^ÕbRŒòåšE1¤LQÎäLq¡„MŒ})&™˜øRL fÎE`«¨Àó7½_iŽAÞÞÙxùæèÑW¯–[ݶeó³/~ç‡;KË­Óqt}Ñ¥êéþøìxÀ¹¸¸˜N‡¡j»ÚÝêb UË:½üö·g1½œÍj¥ÒÉpX ¼ëËñ<'&aRöã ð}M¬ÒzÀ;šNC­Ô`œ$q–E™(¸”*(Ù†g%{u©Qn5>Üï.·ï\«M~øÁYÌï½<¾scmÅgýÁ‡;­/_ >ÞiZ‰2±ÛÞ]«F¹°Ìª‰#øŽ'¬ÁÒ`bˆ4`¡Ëš€ÐEP¡4Š™Á%®»¹PHjœqØŒKüì WZ^à™“¨`5JH*œ êìŠ 9ͽªÀ(un1£ÁWÄl© “¦E Ä”eâ#ÅFÅb@¦©œçBH@ÒRBÍ£…PI.²œÀfÛ?$À…\ÑR€JsñÞ­Å£~x~>ãÚ($ Û7Ö¸B)!åÕSx¥ðQJÅIèXÆ‹'Ç?øþõ0ƒ,L9›æd©žY:­t«o¿wæÚ1ÔñHìî÷-,çavïá1gÜwÌ¥¥ú0áÕ’cQ°šóËFÕ}ÿÎêÅy^[(•,›˜v”f“(‚(¥¾©\q!> z2.õrÕºŒ8º[1&EÕ¥‡Æ6¶3„mŒm)®®®€´Š5rÃ,l“K ­1Òó—,mq8ŸÔzù˜³Tè+) ãRry2ÉÖÛ>g’ ùäÍhµ]®–m–1°CB*•ÅÙÍK^Ï·Vk¦iÆ s!´Ö€ÐwØ¢” Ådá[ôñã³·ï¬þâ‹§eÏ¿¶Ò::›!¤µŽw¶V8R-@?”ãi<ºœ0&_N/φY”µ~w£3˜¦g»gíÕ…j3¸¹Z£¶ŸÇ‘픫ÒÑé$Éò»·¯ýìWãÛå“ñ¬×iT¾=ÛÐJ£«L “ [D{æÿW¦H©0=SaJS©-ŠS¢À píDYRsñ RLꊃ]Ï…ÒºU¢ÃHäŒs!wº¥AXL"Æ¥ÂaLH)$X&½òR,˜h–-…ÐpI©6V{á‡ÏÏWV:¦mJ¥¸”ßÕ7W\‡²ã|þ«Ç×ot=Çž…ìåã=ÓÑûƒ;¶ïPÕªþÆzOxF_>Ÿixx:=<¥Qº²XѶÕkøi.C&–7—Oû݆óîÛ—“ô¤ýî›\Š¿½¿wëÚÖ8Œ.ÆÓk]ß³Í'‡£n7,±7¹³Ø¹˜åµRÕ"Y^TýÊ•¡ÂkÀ\—L4@™°â&‘Bá„S,VH’ X RN/fIÕ#&5gIÖ«Zs–0)t+¦AÐñ$/ ®µ6)•Rj Œ )$FÈ0ˆòÉþØPòúF“1™„ÉúZw0—JðÕ•v̾ñÄüî´ #/Øî«£j3¸»ÙˆÚ{~þ7ŸÞ»v­½´Ø ížÖLÝëÕ7¶W”†…ä^íÃ099îî] .Ü’[ª—@!˜˜ôï®Å9VŸÜm¿>å“8~»sÿù~{q¹b0,¶ë¾ZIË4ÊDi'ªéc“ “™¬¹Ø3ÑéLVì[(*´eø&Nþ™øê ´âJ¥ù—a\qÀ¦qˆ @¾¥§©^(a‚a–©þ\.¥ÔšP0m´ë\a ÅÍõµQ˜Ç¬X^°Yn·¿~yDdAÝJàâõ^y­P¿¾±Öüð^§S¹ÿôœìd÷TIu~:jµ‚k¯Ÿ¸e{e±”+úðþ«ÅÅÒJ£òå½ÝRÉkVëo†óBÀ$ʧbBö* 8Ÿ³n`"€³[©Y0Ï亜¾~}º½VîÔ¬ößÞª l`D¯å«Õ")cÕfåôx”ÄE§A°í½ûöõv»õæðls½jYåÁ„}ú«—îÎs¨·»Mg½Wj¶šÛ›­¥¥ê«£išÇ'“ÉÅ$/øàrº½Õ¬6Ê?ùóG—Óäƒ;‹™@SD¬åRyg}uš Î “:a:.°c¨FÉ„,.d݃QÄÂ\Ô=À}—‰¿¥w¥”ĵk“\Ê…ãÐÂ5$“¸¤d ¡ð4·(Q %,5Õ5}H(([¸WµöÇÙÅœ5KfT(®P«lÚ&"–3¥è§GÓo/®.®m c–äb0z s¡bœ¦÷ï½¾»Óæ’\éé5BÔ›ßsâB‚'9¿q{óî­­·¶š'ÃY¥l4ë‹í…Öp<üÅÏŸ^ßZŒ^i»‹í ò«oÝhï%ˤ‡‡£4L‡§#%ÕÉù”PüäÁ~Î*5ïŋå^½^±ßìžß½¾™¼t÷Íe£QÅœI¸ÚØœ0Í$TlœqÍTœ æÚ7F0J2pþ÷3qU©\« ,«áˆb`¦©öLäš0Jt«„5轑¤–kV«lNSm´ÞtϦÙîEÜ©ÚI®ÂLP‚[eÛ2H?d9W\ÃRÓw,ê9ÆÙ8ólc¹ívÖÑñðþãƒïí4(ÁBÓ+blÎyRpê¸%ß-$Œ,ƒ¶‹Át¶ÒñnÜÜét:?ùó{žì7ªæ?~füO™Mý˯ܳÁ¿÷£iDš®…¡pÎ1m~t}þðèå“ãž²’…»#åj1!UÉ1žOàÝõZÁ%ì]Äa”õš^£l#€óqº8jTì·ot’ŒýìËÃ[[ 7·Z÷ß¶Ml›æâç«Ã´ ĸ \{2‰ëµ€sùŃgÿÕñ£ÿýßÿmƳó/~c2ÓŒ‡ òÉ4où#t8ÊËTþÉŸü¢Ú0ðxœšŽyíí7OÖn®6š•ŽÏÏ£wo^{ôrïÖúòj¯ûèõC霽fí難¶š¾‹Îf†ßª:i.f9i#`Æ)î”NÐJU#{#µÙ )p$†Kð1$š+‡  # ÛÀFúdʦ)¿ÙqO¦Å8aï,ù…P»ƒ”b|£íF¹ˆ2±{:€·ÖªJ©ƒËx÷p¢µ~÷z«^¶†ÓìéÁøãÛY\<}qášäG?¼}<ÕŠqÍ„JI)1Â#©õ‹û»^³|k³Wõý/¼¸±ZKrf;Á|O'ƒ¼»ž1àBµ*¸8.kÈ‹QüË{GdeGû—Jéõ;ëÔ –eÌO¤ìùÕŸÎïwÞvM:Aªx–ËzµœæÅ8‰¹¾ M‡23Ï¢íÀ:™dJÁJÃaBqåº&G •Æ…r+sé¸ß^çBšž‘ …cF‹!ßÍ¢I…*ŽÊ8Ä ª5@Ê´c Ç€ÓI~2I]“ì,–’B¼8Ze«S±ÓB<ÙŸÀÎJ•b€çGÓÙ$^_ª6+Î,ÌŸïû£5ÀÆÁ@øžåü›…W›1Fq¼Zw2¦Ë_kÖ¼xµÒ)ýôç»ß¿sÝÜÿãÏ?ûƒOnÌ%ÞéÙA˜éŒ«†‡f©z¼7zqo÷rÍ'‘ãÛõfùÖVëó‡'ÿù?»»?æY–jÁ;ÛYŒ=y½¶Þ½¾ÒûëŸý[?|Oðé„«5œ¤EªÌ^…äBÝ 0Båjž«n…ƹšfj¹J¥Ò y&QZå`˜ ‚´–†Q)Š!ƦeÁÆÓ£q±T%A˜«ã _ (Ű?*ºâ(*ÁÐôŒ¨ç“tælÖ£Œ+­ŸLÁÝ­&€Þ=™ŸŒnl4»`4Šï==ÿÍ×Uw*†M&±JJyu˜!*¸gÛÄ_úè?ý­[_?<î.¶7{v½D~Ýÿƒñ?ý;¸vSŒæòg?¿_¯Z^©"¥\Sd‚z¾³³µ`Õ×[½N°P÷ž?9‘\À›ãÉ|N†K þýG»‡£[7NÎG“þÆò*ED)e&6ì('/‡ëÝšAÐA?TJÔK” u2Êë>ÁHGuLe ã”VlI0ŒìœbH9ÚðŒ<¸4°X.Ž›7 IDATpÆIÕ9GQŽ1“¨Y¦ ÆKU;ã€ÚYô|ÛœerçkMÏ0iàYBë¶ 5wšòq˜ zÅ©®aÑ,ÏR Ðió(³p±º`îŒc‹u[#  )1ÆœåÓ¬°Ç.%àê³G»kkݲ_¾³_þêi¹ìµê­/Ÿõ·—<®­ÀVo_o­¯47¶—[ ¯ØvÉ{þõëh›Žùæù!gâí»k¯^öΆN¥’ >éO²(ë.4€«ËóñB½–ppzmøÆ$ãXlµ„àbÎ]9›IÁGÀé”—Št@™H3¥ÀÅÀ0û¾ Ò„–|SUȘåÐ.ᘑqÂ6š¦Iðe$Â\i€—ðîZ¥äZÓTLÂ"ÎÅN¯ŒVM£|3à ͺç8æhžFÑ'¬fÙÙÅ< g­2.’x<ÍV;žI-!µT*°QÊ„Aô³' Ãt<ïôZ¿ù½­¿ùì~&ôí „¬Ÿ}úp*ÀÖZÛÑ`*d6|Zöè÷¾wmóæÚÇï¯Ìc¹Þ+?úòuÁÅärz´{zp:5M£9)No±ÞŸFYšWƒÒ;›í$ýÑt±Ý{y6’´×ihÉ_MZáX4(,pËSATÁà™0Ï5AÈ·Æ 8&Å †@råÄ1R…´ Ì – 3—t+tžãªKWj¦P¨‰åªUséñ4Ÿg¢ºV²ßš¥|ÿ2vs¡æ,Ô=©á³' `½[™†9 Ôi•‚Š;š†ÓáàúR‰s88¼\m—56úf£H³S¯V|ÏÔL°Ñ0jt}Ï9<®tªý1EêÕÁ0ãz³Á$rM-¢–}çzëÝ­f»Ùlù†e¿~zxúêôòhpëFg8Íú‡}¿YgýË8ŠÆ¦o׃êåÙÐr1É…aÚ¾[:&‡ãL6 ÊŠs^óMƒâ½~bÒ5q”‰(Ge[h ùÍÞˆ˜W2S˜nÕÎ&M®tÙ’RÛ9WGÍsˆ pL ¢\»& tIߦÛ0™$|šwW«¶O&YZÈZ`%+ÊÄ,ÊÔW§Vq¤†á8qmãÚZãäb>‡Yntœ£ã¡ifÅšj­µkšRSBŒi’H™÷šžBæííµBDˆ@«ÓI2øåg–›µ >Kó…&Ô q{¥´q½·~­ë›à”ýªgüâ³=¥ô‹Wý³Ã‹åNÅ«é¼Úª5jÕý“ó’c/µKGý䬟Ökµ7g£'oFë½ÚqVH¼R7®&<£Dùv 4Œ¥o!ÇÀ§3®s [%3Œ-J}Χij4”˜h Õ+ÊŽÒæ, ƒsšŠë V.ô•_…EÑ âa.ÚÛwŒQĦQ‘âÎZ \)Ù“¨˜EEɳu<ž‚‹ÿÆÖ8Ìw÷a”äQ˜§r± t%@Rk¥ÔeœdùBÃivO¦–ïþâ—Ú5g¡YúGvÆÿ”“ñò¶˨•K½îÂxΟ\Ÿú³jk‘ I±J9Zi{›KA}¡Y]ì¼u­¾¼Ù{ûVïó_¾Hf /øéùl> Ó¸<î_Îó tkæñé¬?ž½½U/7†ÓY»^7-ÿ°?%RcêÛÆÓýÑbÝñmòÕËÁR˳ˆ€Œ#¥‘k¨\ ©Á3u!QÆQÉ\á\à’%¤&L¾%Lßä¾m"äz&§¦©òLä™xoÄM‚K6q-z:%s¹î~õf𲿙£˜©z†m¡a–r®À2i£l¯÷*ߌŸ¿¾ì6ìNÍlWÍ/îæIr{=`G¹P™”f˜DLJÛ6 d;örÓ|~<;‹ª.¹` °N„ªÁÄ#D¶µÊ"˜ØJƈB®gp!§åKœ0ƒb¹P6¥6Z>®ºôÁiŒ ºÞò G“¼áíª3ŽY”çkX&É…31žç­ªc›du©öÕ³ Ϧ¾ž¾<íÕzÅÒÈ.L2®ª@jÅ„D¡„0M×>z}ª=ºÔk__«üô³§ž[ªÅ‚`9/l¡p̓Lšwo¶w®/ôºµÅå®.²Ó“1g|>Gã,ç—/ŸïÛ5ßölúéÞéµ¥Ñ,œÏã……Öé8ÕÚØ=å8DïŸÍ—›6ÁÀ$Ô]@.Âoo¡4(¸†€“™ l@À™ò T$ráš„S,ÂÜ´ i5NˆgiÇÐý% -”È$…°×„nÕŽ \²Eq³di„ZµÕ)k„F1¿»^_¨¹K-ÿd”Z&©ú¶m¡Ð,åoN'¬H{ ³â㟾×*áV£iR!T3•2˵BpŽP30ëu/¢ÓlÎÂüçŸ>C–{<°„At?‚šGkõòÆúÂεæ[;‹õ^û/þŸ¯gƒËØôr:™$§§#Ã2ž9{5§æ›\ª§a§b`¤ŸÏ;U㊼“K“bI±Ì„a`i`Ť©y—ÚÖ€\ƒ#ì*ªŽ´MWi\ó”c Ó™ð,¬4ìYÙ&5ÏXª9¯.óŒ+@Hª¹Ô2H·æ3® Q¶“¤\E¹sžÙ¬ºÔ4<»Xë–Û5³æ‘¿øÙóš‹–; \jК+E*$šeJH|žÉzÉxøìx2~ðö­Y"þùËœó•ÞhåšJèŠÒr±J·®-ol-Þ¹±°²T :[[Í'ûýùÅÙh6‘Ö†ïÜÿüY§aµ›§ƒq7¶V|Ç9=›¸e¯ÓX¼÷â$ðÜ95OEÅÁàxÂWjìÙzÀ”©ËH”Lަ´,Ä@aìÒJ€ì«…„…*#-¹¤B‘šLà\ n@Lj¤–kö0b€ î™«-o”ÊqĪžad”ŠœÉZÙò,j›4,ä$,ÞœÍö.â³Ëhq¡\/Û‡Š¢øâë½ÙhòÖõ–Aˆã;¶cÆL+¥²¼0s±·ÐkùeÏø5LýÆóK5MŠ…F|2I6—›¾³:|stþþíkŽ¡Ëná»nÊuÆDÅ\¸àMŸó‹PÞÿù£Ñ`–r•ÌÓµ”T†iØŽqãZ'è6Ëg†c]_ë=xùúîöæéhÚiÔf³92ðÛËcüÞ«þ'ow`1 NÕ•0ÏFP¶õ<ÇAÙR1#à›²¦° ¨Nõ@[V§(úZ¢:Rc”c #ˆÌ3Þ)ÓŒ«i*1_®šq!‡±Øi;\êãA<ŽŠ…ŠÝ­9L¨YÂ/"pk½¦”B}ùô"K²}oM)xs4~öfô{Ÿìì!qÁ¤RW•ൄbT²uÆáéË‘°ßÿOÞû³¿ûJfì½;ÛÛëM¤C­Q¡< Œ¢"W¶CR)ä<óMs{g}¹ ¡Q®!0Ö“ºÊ™Œþoÿí_3¡ ‚yÂÀr-„¥DIµ~g}©ÓšÌÂßý`ݲêaœ>ys¼¾¼hôÙÁRúÎf=‹£iT¼µÕTR]ÌxÉ3 §3Ñ ˆAÐáD,”ˆc “©j–°aœ¢ŠCÌ ÇëYF\CZM2äPiS<ÉÀ¦Ò$hËy¦¶š” } èU¨Ppÿ`²XµW^Rˆá¼8›fï­W .÷ÏÃIT4»×ð´Öã0ß;žP„în/`_=½hÕ½÷o-¾8ãR#&r5ÕZ[”@”ç×ZîÁ˜u+Õp=y¹ç8Î?ûøÚ,$BÎ[U H©ÆÊ¤ÚÕ¤cè÷¿ü]ÎU›¤ýa¬”ZZ(5;ÉÅ£’ñßÿÍëqʾ~rÈܺ¶î:”)™2u5½B±)Á‘‹áøÎZõ/?}ݬW6Vÿö÷dÎþàÇš8*yŽ¢ÅÂ!W˜I‚@!Pa¢GüÏÿë§“¹Žbõ´”Jé•ëËk×—g³È4iÙvÞÛ¹öhoÿälðý·wr%ží¬vÛ·–­$ÍgêV×–Æl£aRŒàÞq|wÉǾ>ŠÞ[)è”ã’S’"Ì8r,ŸñP£’‰cš+¤áy!qƉgˆQŠ uW2)­µkÀ,{ƒøÖ¢ê`˜ ï®q.ŽÆÙt–\]ë{§s­õ»› „`0ËÏgJ¨vÃ_jù õp–?~vö‡¿sët‚-›dBq¥Ä·ž4ëuÚôñ¯ÙÔÿ`<>9WWF Wú¼åªõâd¶Ýk<|u$3ùÁ­••n]k¡dØ­µŠ9ó¸S&p2e…Ðož¼9™µ|új8G„Ã2B ‹Ír£lR)›ëk½ŠWyõæ8¨•LÛò-ëéîÁ­†cãéñ>ÌÅë·§ë½ÕW‡ƒ½í'š²6 ë’ªé#¡‰Kk‘ÆêÊGïnܺ¶´{m%\Y‹´PµÊÅÅÙðèx0¥GÇ—Çg Q_»¶>›¦hááÞr¡|‹ÞϾx½²Ñçæé‹³ÍÐA©m?5ݘ85>ÇE…‰g±”,à •õ8Ö„Æ`+°â·‹¯ m¬ªuà2Ó ‘S̤»¦×àO/J¡mèÒÝå 6øfX)5†.½Ê]Ú.Jår–œ2-¤2v0-»MŸ32/5ãôþ^wÿíàų£NÄw{a±Xœ÷Ó8”Ö@)%Œg•0•6ÉR#îÄ/Î6×7†`¯dZBQ1”¥ò\fln¶7®í>¸Û½y}yu{óÃ+ƒËÙp°È¦Yÿt°˜gUVÍÓüàå±çyN+XnÆ*\ ³‡{×¾>Œ3‡á¬RGýÔçdo=€/^—§Ð/ßLzmŸõõÑl¥éS/.²Nä ÓÌXÂI "ŠB]*c¬Q†pj<¦çåĆޙ–„SXor“A†œ˜•†Ó ùÁ°hø,F†. ÊòZ3J&iýüd†ˆß~¸‡ Î y|±Xï†K1y}8˜Læ÷v÷}Ç£„hkK)…RŒÑFDIP+Ùl´‚f˜Äaį§ù“ýw®%ÌI¬µ!¥ÂZ¡ËlìÚqÍÕ•®­nv·V“wlL.g§Ç£"-&ƒéÙq6œ ‡Ó¢¬ÛÝæîz‚„<~òf{su¥ÓÍÄtœ…I»v˜ÉJ™­–‹ûýr¯ëS‚¯Õõe<ËÍ/ `äb¥ˆP;RY¦ iÀqe(‘¸ÜØ•‘ëZp®„Ee<ŽKfút¦—#æ»üb¡b—cwk)øù˱T6öÙz'|ÕÏŠK¥±i©”ÏcÍÐ!'™89Ÿouý^›÷šÎßüâ Ñõõõ˜ü[d(þ‡+Sÿ·ÿýIÿôÞÿô?ŸÿäW‡·ÝZ¤UQɨ^™ ¢Ï­õ˃bíb4ÿô×ÚžËjƒ Åšb¥ +µçÓ’UHN@QbÓЗ™_yòã³¥0eQqQÀ8ÕBµVš÷ÞŠ=¯¢™DAàÕyu1Ÿ}x³ãûÅþÅö¢³¬¾·ÛVƾ8žmvc¡Í¼P{½ðr!´Áõ¦3)”ÒØéáÄî´ÀVŠZ`>«kE¥!¡#+Ij‰§+I&%mz:àfV!Aësk NŠ´R÷Ö¢ƒa™UòÞz\Ôjÿ"k†|o%Ìk½ÈÅ‹“éíÍ–ÇìŸÎFÃÜßë ¡ž½}÷Ã8Ž.§”»hÀÎKyµ<|õ‰#• 7òÜŸ}þÔZ{÷ÆÖÖj'ñjžÂaŽH•!óJ·}S)è§Ø ,#öh¤G7}|ºßÿÑž Áñ¬¤ŒJ®ßÛ9Þ?ýàÓû­vãâb4Íÿ³ÿè{i!ʪ~ñâà‡7n%d×úúJ8Xˆ¬V×–ƒI®²Zoµ½Eeraך (,G0*¼Ž_Y •ö}V Xmj§–ò®J(e­ºô|&Ö›´VöíX-E$vI^›‹…ÜjqFñlR^LËû[IV]NˆÏ÷V£J详u)àݽe´–sòËg—±C®ou~òÙáözëÖõnY ަAZU³´v\~•ÛÃe”de••U6ËÞÚí%‰¨†IÃsy„ÄUr€–4ŒšB¬%£b§Íkaö/³[+Þ?û?5êÏ@Q¦”)Ò‚2Ê(]ß]]ÚXúäáí“óáEðýß ÿd8zñâðÓ÷¯¡šµ?øÞG;a¼¨kË\Ï%_m@%T¥ý–¯*©,ipÌ-UZ×@bF¤55ÑØ v!ŒËPQ”Æb¡ü• nÀJ‚`|}ž·ÖƒQq³ë mJa^ Ë^Ìc—ÎKu<Ì(Ø+$‹Tæ×¯Fó´üènïÅñ”~°·Ì)rN¿|Ñ'J}ðîVQ©/Ÿ<º5ÌJc¬2† ¢1&tݪ¬Ïú#UÖw®o%1é%È”a”˜«Ç¹R,q«Rb.èR(íÅÄ$®zöìô_þÙS×¥0›ÔsµÔÜå¾ï®®-}듵qD&ŸžýÃï¼ÿìð\¢m'áµ6<;šlw£•–_ ýË—ÃïÜë=;·Bgµå¿±K—cçd&[>=:ÊLàÐyM]j9…B9±S!`&(86ÔZ9v^á¬ÂÕØX ÓÒV Ö0ÊmÓNÁX|r¶(…ÞîøC¾:^\M7­ÔŸ8fqàÜXkc>ßTyõɃuÆ(#øå‹¾Tæ½»«ÌkÊBeµÒÆ€µ€SZ a¬NºV·v7›ãÓ,Ž|Bk%š!<«­Ô*v¡T´–ªà(×'ãz»I†ú—ûO¿>r|w:/”P«»=×sʬüè[ï.%q^Vû¯oím÷šÉÁÙ¹ƒ,é&;-{>)š±Û‰ØÙLøœtB~¹.#­€Žrë2hx¸¨(#6tL©‚Ö¡ZÙ˜ã '$ÒjŠÈ ¯ø[h&!­±ª’B`!ÔRHkeÇ…gêîªg,hÏOç×zÑÛËtQȵ¶¿’¸B™ñ¢>¾L†wwÚÆ­íŸýü°ÌÊï}¼ûâxöÑ;½Í•ø÷2õï¬ÿò™¤UüÃ?ºøèáÆÑÅb:ÍËRÜ}wïðdÒn…¹¦W¿çŒÀq¬…ýWGífŒ¾÷nKª E$­ —Ec¬)%õ˜ =+Qˆ\H+ýöíàí‹cel©q¹éýòó·@ÕÊ Üw>¸½ÙjqJYÄÞ¹¾õùãÇw’˜,7½“‹ÑrÓïu‚çdzvìöZÁË‹´:±Vf»íÀUÜò¢¡a)„B©1ñt­˜2$t„²N^›ÄSÚ:i­›ÞUÌ‚¶R ”mùXH#44\,¥Ék5˫۫±Òær^å•&>'Y¥ªR@»`,d¥äÖ¬¯&çý…êõÉt¥¬v›»Û[µ’÷K+-©u)å߯ÜŽ3ÏÑÄñ¶–pžøE `‰-‘xÃ4ï†ïrQu#€Aª¬—ã,¿øË¯‘àù¼>xz%`áú»ïß„ù¸ŸY—ÐoóÝã³þp4»v­·Údggy{+á›ã þµ%Vþ¶×P*X¡RTj8F×¥%‚ý[¬ѳ&§,Òja­t-ºhÆò~*V¨ »˜×ŒØÕ„ 35+5#ÀæB/…|)bÇ“:¯D^Š»É鸀y&¤Ðjøe)^ŸÏo®'Œ’¼”ói¶¾Òh4üóËRGM‹õžù-ä‹QŠN/°L˵Õå»Ûq3‚R:¾ë¡)48Ö „B&Œc, X!49V»KŽPx<)&“ôðëÃQ©]£ž<;w|çÚí³ÃËßÛÞ¹}«ŸúV IDAT6–h>xçÖÉi8›xU+u9WµúèþÚ}òîÍ.|}6¿³ÕÒúÙÞj<+UQëkËÁÑ´nx´°ZYa¼ÈQó "—2Æ’J;.¶Üc Ñ’jƒ‘£rA”¶¯k g³ÚX³ÑôN§u%U;àœÂ¢R‹\h©/fÕÕ8-„CÉõµÆù8OsQä´›Qº¨¤Ræá­•ƒÓéêj™³¨@(%µ®„¸¢²øœûŽó“Ÿ|¹²¾üÞ­Þ`RÝÜ)¢²¬â”jK¤¡£µ…yIÇrbgH í¦…~ñäèütt¹PóIšNSBs™1¦·¾|óÎnÌD¡œ?¸ÖþÕ/¿ÚØXY_rêº\¤ÕõÕ˜rÐO·—#ÎÈá¸Üh¹Úà(W×—ÜAj†Mç¥ÄFŽ)¤CÐzL ã!XNj‚E( iU&ž ÏfYÓGŸC?5±‹ƒÃL mWbj L 5Ïë;kÑ8Ó\¤¥r8q)ª«1ŠÒ­†wÅf™ÌKQŠV+@Àá(m·B4&NâV§UIYI(ÔJ{5>²ªËZTY©¥ÞZ_ H±½Þ=Y+Á^e‹¥jl”¦+1µNf¢Vv£É/òí«ó§û—‹E9>#bÔŠß©‹úÞÃ=B§²™,m‡³Ñt¾Ñ]ÚÙl¼=:î®4{ þì`¼ÜM–#¶4]^n¶\Ôb×TÊ >0b ñµšþIA¿… Kak‰K«J±ãIÖ Y'd§3!´•Ê:Ji6Û®Kñ|.Y%„ö\ær¢”>ê§çÃÌåôúZ¢¤¢„´šþj;HBç÷2õï¬ÿýÿp˜kî<ÈO/çÝvx}»sûúòßüâUÄìàrRä壛[…0B©ZJ¡T³J³²ìv–-JŒG…4N­J ¥¡µ&v…Cí¸@J p`^j‡áõõ¸µÞ]ÞZùäÑf«×ÖÜýö£ x§G£áÅøù³ƒgÏßj­^¿>YnQ'ÃËùó“q«Ý^[ ž{-¿× ž-–®¶(½êÄ'SÕ©Çð|k ‚(ƒ‰§`!܆#¡2aäTƺXÀ%‰‘‰ï`hÕr„ÓÒ Bèb. 4|ºÝñ'bQ¡´„Rp²µžO+‹Ø‡"£$—fž×¯Îç/'ãyu÷Fw©éû.M³ôŸ¿º¾n­ÄOŸ./u(¥W¡„Bkîp¡T%¤AúÅ‹s@\Ší0•±[+n8_„€]øÚˆVàÔš2j?z´Ù\[ºusíÖv{icùÝû›ýYyöö¢9~öä$_ä?¸óWöK åêr; â?ûëÇÜû7¶ýâ\Tõ­Öáù#x<»×Z8ë†kµ— Û 4ŒKqM‰™×nÀ#f^9œšÀѳ’8ÌFŽ5æöbZH*¬5ùZâX$Ye‡4>ÎÕõÕ¸»{kþBLsy,WãÒŒ=‡’íÕd^©£³i'ñ÷_Ÿ^¶B~­çË¢ÈSµ»¶â06+ŠRˆ¥^»Ùˆ¤¡Ó, }ßc´ŸÙØ,Eí2[ (V³ý\ .ÊcäÚV+î-ðpóÆVÛÆP2:‹J¤‹üâløbÿØ¢”8Œýäóã?øþ7/FóóÙ,Œü«IžË E€Ív›1+ëÕ$F›$”0¤‰R3‚† §Œ«&…ЉG'…0-Ÿ e´¦Jþó¿xYMÓq®¤ÖJ{sÃ`wocu§·ì…Ÿ}ñô~ðq6š Ç7vºeQVRßÛ[ÑÚœÏd3â!‡ajbŸ ©(sž€B:Œ‡ji\‚†¡TÖ' J !X ¶¢¬a­4º4à«)ÖҸƗÊqaN¦õ%7ætZÝìú.Ói=.äŽG“r:-jenm$Oߎo¬5Vš¾Ò¦?-ÎgF›µåx}9”Êüì×GÞ[k6£Wo‡_??ÿÞ>ž¥wPc-€V:ò]‡ÑõøYT°Ôh[=U€Ä4ÜX"´ãJ[˜UŽÏ¤Cu­Pës{<ª×"øW?{ûøWo<޵†²¬=£ÅõÝÕGn¯uÚG£q]TI+J|o<é¿w»;˜æƒIþ`¯;šWýIñÎn{œÖ—ÓêÁNs’‹áBÞZf¥¦r¯|uV<ÜÁšZ¡ã4Ð,„Ä“Ü\¹HY© ÎkÏg’5¯iÛWÚ@¥P(¹Æ¹œWŒ !øºŸÀ£­¤úM?€kÝàd\ '9XØYŸÀQ?Œ³OßÝÊH©ÿú³Ãë›ífìþô‹Ól´šÁ›±¿VÚþ6ØÑwèjâL»œíd‚µý ÁJ”B&žå¶åkJÈåÂ(cV¨Œ=Ÿ©µ&3Æþú`{ôølüåOž§…°Æm¢$ä”rÎÿîßÿÆJ³ù£ÿjcguµÛΦÜl…åâpßßnæB¿•wV£7Ãz¯ë2‚•´ç }­Ãަ°‘À•“~)Ta\º-O´™Œ|–De#)E‹HÏf%Â~jÚ0 ÚØ·c:d)$oFuè^ƒ £´>èg7×â¢RGƒìÝÝ–Ò^¥óEwvÚu-Ÿ¼ÜÛm7çt¾y;ì4üo|°#…ùáŸ?ÝÜ\»¶³¹ÐâjkDiÍ(u(9=>û;l˜qN×Zm´™ÔÂã¡QU(¢%¡V)AÆ%PÄ£I¹1 öÅY:+ÄZHþõ…‘òõ‹SBH±(¢8p÷»ß~¯ÝIŽÏ'§ý?þßZ,úÏŸŸþ½ïܪ«êó'çßýx÷ùÁ¨Ùð×—£ý£I; V;~-u¡¼ÈQµ¢'Œb0B[ Bc2Íx[É™µÆ’ma­R&[µv(Ô”DòzXm·ó™˜äòÁz -(c¿>Ë:!kìÙY*JQýÎVóéÛ‰Ãé7ßé•:¸Xô °pk§Óøå(;¼˜ÿ·-à/~}<œ–÷Þ»Ë8A…ÐWd´Ð<‡ázÃ2Jæ%eÔÆ®¶4–J,¤9•Ð` D® ÒjµVÙhxäòrö/~ø¹ËiV©2¯8gï~ûþþW¯?øøþÑÁÙ;÷oܹ±}28€.«÷¶¥ô/ž]>ºÙíOKJÉærx2) ÂFÛ?Ö”`7v^ªÛ= Žsƒ€­Og°Õºó1Dú·Øç²’t!xâJm̤¤_kk©]  -p¥áp”ï.ù„ Ööë“yèÒÕ¦'”yy‘ÞÙh¬6ýßËÔ¿³þëÿÆm/—Ÿþàx²(¡»ÚòµÔ®Ë¡£•¨Wº mÌpÂÆæµ¢ª†#µVZsÆ`9†K•F{ k™RâqîK%µ‘œ 4F)CZkµÐHÐ"˜\˜ói¶Õö>{>äV¾zyy~>ÓZ×eM]^nðè¶D;›§„¥N“ýþ;KgÓYZµw½ùÕËA¹;kÉÿóÓÃ?útûE¯Óð˜:×½Vƒ“ZYÁR¬€D` Ø‚²¬Õ:3 B!Œ © É, A%A° Ï,*ÈjíPC=™äpc9,êJêZš[«ÑŬšÎ+©tàskmYëÙ¬`Û‰¯¤NrÏe‘ïH­‡£,‰=Í¢­­Ö¬Ð¥¼jÊ€ˆ‘ë6\Ó ¹µ¨ 6}€R3 ŒS[)«´iz¢”0¯Ð¡W´³‘I¡ a\† üøËóˆšI&^<=)ÓRÖRTbm§÷“É"YNvÖV‹~*ìõÎÇùpV=¼Þ€}uùƒ‡½á¢eâÎZ ?y3ûæõæ´Ô“\]_r•™z»Ís‹Ê®6°Rh¬ðRjZi;µ¾¨ éÉR¢BFÁç¶¶”@Ñ*cÁµ„N Uj4/“Ð¥Fóòz/šçR›U*Ï+kmyŒ@%ôd’±«½d<ɤPïÝ[?<ö ÆH§µt±¨nÝÜ©•Z”¥ùíL´Ç.•ƪ¥¸•(?°ÈФ”ùL›ÜeÁë/Šn„ãÂNòêú’7Ìô$¯¶šÎ¿<mæã7'3)d±((§ð½ï~0¥•ú¾ÿñ<-ÆÖO>¸Ÿ^Χ¶ÛÞɸº¾{œdµ™f«ÅJ ó–"\T$v §VhRJ–xB[Zk7`…‚€"P#:¿ã‘ðê^5À©Z€\¦j%F¡ì¬ÔYmZ—aZëØ¥¡Cæ¥Nrh5<0¦Y}>Èv×’ù¢°ÆÆ¡ërbÍK1gëkÍù¼œÏ‹o|üî³7ýª–»«WLìZÊ«¬å]ήˆñÝØ+êÂá>¢ƒ6µa­kBÓ€«J©Ñç¶–¦V6t1¯ÔÏŸ&þ곃4-­±eV"âí»×66W EY eÌFo¹?ž~ò`9ØÓ×£ë›Í‹qø|wµQK½2ÛXŽÁ7—Ùû×ÛR›YI–"®´HkÚ ¹ÉXbtiL °BZŸ‚”¥a.Œ¨\0mIÈeZ¡Ë¬ïØI‹Rd•¸Õ O&uZ‰Û½ðbVg•r9¹Ù‹.fÕ"“y™ÄîÕo]ZÈÅ<ßèÆaä †éxVÄÃ(ަÅý[½fÃÿÓÏ.7W“FÃç¿QI9¥ë6=é2¨3-¡ãÕ%EP³x^× W/jÈjŒ]«Œ™¦cÌ8׌£ðâéÉ´?=æÓya­EÀGïߎ?ö½‹Ád}wõÚÖÚéÁóèÆr(•Äë«ñᨰÖî.‡•2ÏÎó÷¶âË…ÔÆ®7eàÍHÞêòY ÊÀR™ JCÓ7¥¢ÚÈ‘ÒðRBÕ½Y!Z¾!$è/Šåæ••¶á"¢-¥-„é5hZ™¬’‹¼î$~-Ô"¯]NvWbˆÜ߸~wýË?'ðŸ^ì­5ö6’NTÊZ‚ŽCC—!`Zkml{ˆ˜– vtˆ8=›œ8eKíæ•!/­tZA­ŒS =)AhW*¡bÖ•v­5”kM¥S ` a=ŽíÐfæÚZc³—”Žÿáýõë+…!ÆØ"/¹rrù^è{ÔçÝî_þäInùn/Ü^K>Þ_n[½Æ—¯†×Ö“Fè“H­YÈ¥Ef¬ësA[ðGDSÖ5F.G ÐiúÆeðz$!(4ú.\šDîñLx)Ai±V‘{üv’V*ð8¡Dh3œW”’YZE>Ï*Å }ˆ\xýfxq:Ø^ë&qtµ}Õõ¼R`­Òº¨%&p°¨ Ƶ±•2ŽAÇ®-•»Öån¡h3Àµ„ ²²ßÛmµV»wo,Ý¿»6)å\ õjÿ([ä.ãÇç+¡Ó^Y_éþù¿”JßÚjþúéù$œá¤8å»+ÁtQ ‹%ï«×£ÍnàP« )‹\i íx´$Ör‚‚ %4º2×"z`ËÚDÖ²†§ éiK›¾MkGhЫ‰#5%h¶Ú.€ç’SR(ƒ”D.#gÓÒº·Kµ6@ˆïq÷êþ´X ÝiøµÔ¥Ð£ñ¤Û¤¡c_¾ÄŽÝ[JE…RJëYeÓf¥A0Ê 8µªrÉ1œhe9"h}fK¡…ÀÁRh xs³Õl…:¿÷áöƒw6ÒZciVì?};Ï]ÎâF$Á‡nþùþñ¨XíµÆó¼»Û½|ñf¼Ý; ÷ùé|g%òúì,mÄw`¿_ÄxÜŒêV@©Nf:ñ¬d9PHƒˆ!¯)šEí0b=¦%úŽÚ3ëql.JÛK¸:ɵCa³ 2u8È(AB°&ô§H ÖÚ mÓRJ0—&ðY¹ë½äËgG§“k«ád8^Nïíu–â$­•Ôº’rVšEÚØ†«?žµbw})ÊL3±·ÚÚÌrPO§„b}¹” B5Î Á¼@Z‚2pL­FÀ¡ZC#¡sJBCF¦ŒBV£±&ñè×çÕrD×›Î~¿æb·ã2âÍÅzâûœŒry8έ±Ë‰w{³•–ò‹×#Q‰î¬<=ƒÒÏÜîí¿úé7¬ÀÏ?{£´Õ¾ûÉû±"u-ÍÜÚE]R‚À2Ð…°”% ß«ë1§>bÌÌcPé0âeÀœE͵« ™•dVÚÀu–ÿ'ß¿QÖú‹—ýy%Tž×ÃÉìèàìÕ‹Ã'­Æw¿ý>qØëSýÓŸ?þôÃ]$°ÿvø÷·àps‡õÎɸlÌãd˜éØ%ÇYiƒ´&µµ•f-A«-0 ÷ÕšZûlîQZ?vscI!6ÄyE÷V(–ÒôõnÇq‘)c6ZþJÃ¥âr^ûÁ꼯NçFëõÐûäÞšµvšÖ/G÷¯/ç…xòzÀùäÝMk,çÙ¿ø×ŸY„÷÷ˆË ÁL`.„`æ pX*¤×NÃ.µÊÒJ¯KE8Õ±KÓN§v½‰èÅB÷>sâó¹ü/þã÷¥2÷/O.æi.úýiyx¾O\ÎÛÝæþà“/~ø£—ô½[Öê?ýéë°O®¥|v0úäþZ-d–WµE­L>º½RKõôxþþN-e-Ži­´ï-k5•ZsÞÖz.Ïi ÖäÂñ˜ h3Á"G!Úié3èFÆXçdj(!œ9¹´×ºœÏäxQ­¶ƒVè<9žõšþ­&XèÏ«·ý̳º>¸¹ò‹g—ËMÿÑݵ´÷/¥ßú`ç|þÉŸOSqãúÖöÎJ­­±V*5Hí¬´m·Ñð-DI†C…œqJØj ŚЖÃhkœ1ËPÎK¥-|÷^¯”úe?ûã¿ÿ°–úÉÉâòd¨ŠòðäòàÍ™ë; ?ÿô“†ÂøÙü½oôÚîd–¿¼HïïvBUBBÇ>{|²¸¶D«•)„n\(›ÖÒ˜êíX.G¬¸\@÷RhÞ`Ê ã‡\0¢‘ÄÍ d„º ŒSd&vÑçd”ë†G$'ÇÓjP”·W¼J8gsa¬Ý[kœÎªÓi;Ýh½Àþùb:ÍwÖ’ƒ“)˜´Ûß½³ZVò‹ç—×7[Èùó¿zf-Rʾÿ­K!gu©Œ™rQ—ôb0:°Ó’¬·šU=uyhТM#²áÑôq^±v -8‡¹ówºÚÀR·Ýòñ‹·óãƒó4­Þ¼=3Úh­÷Ÿ^¿µuëÎ Šîÿö}ñÞ½õõ¥xº(Ÿì÷oßXé_Ì[;©Ìù\u"æR8Ÿé^L&™¦Œ4úø>¡äòbt÷fÏaj–ËÝd{%ª¥~u‘nt‚ÀeoúÙjÓ=úvTvc7òèéT´C:ôê!´@-@Ã5µvÐ¥µßaD(91À-p°¦®5wi]I" ¶|UJ(¥¦U+pFYU+¹Üehé§âè2ãÖZ¾VšQÒŠ£M^«_=½¸µ‘X U%`}¥Aào¾8Æî^ßZ^éh°`íÕ®¦±Öç<à°JH.(%»`¥³ÆØ¬6Í€kc‹r)´Òp¡ªv@§"­ôvÛ™²f8\¼<™ú /£QZ, ÇwšÍø;ß|äûnQßþhãè¬?œäŒ’v3M BðÁ­•×'Ó(‰{ ööl7K!õÓ$Išž©Ô•ô'´u-P†!®uqȪ-“Æõh. )%¹˜×Dilù*­¡RÖX@0•´>·ˆP;ÏKŸÓFÀóŠS¹ÔSK3]”FÏeIÀχÙdQÝÞjû‡£Ãã)!øÎÍîo0^”Õ†µ› ?òcÏ+êú Ý{žÇ‰Ç„Ç}Ψ6Ò¥Hh õ˜$èS“+륕4Æ0Šy]%¾S{>Ë“€»” Ó“óy r:É^î_‚’êÎÞv£Ûä@ÒªúÃon¡ÕGçó´Öß|¸>š•¯Ï柼Ó/ª7ç‹nwà/_~ÿþ "þ›£Oov aNfõí¿’0ÈôV‹ÍJd" É]ª5ú7Œ*]iךÊç >É«ÕÉ¥( a§Ó¶Û|œËR˜Z™†G ¡Ó\Xk"{œ€µ§“òàdúñ•á$—B¹]júZ™ƒÓ©¶öÆfëb˜!b;ñ™Û‰¢pˆ•…øÍû­bÓ§8-l'n[³ð¸ïrªÕ\YÇ£ ­­ ɬµU%Ñ‚%¨ a­µÆêZÙÕüÕ§ýE™•U^])ؽ¥ö;;ÇÃÙ·>º‡êÅëbüÎVóÕé|g½Ù yVëãIµ× „¶ç³z§ã)ýT­'ÌN X ¡VÔXŒ]-ŒGP1THb°ÂÚúê@k€PÊm%F#5I<•Ö =XTíÐA€AZ¶­°‹J=?žc{íÀ%ÖwYäPclY«Ñ$Gk×V£IVÕru¹a­¥ú›_ŸRNß{gÏõ]E¬ë8Êþ†K¸.t|y΢"±.c‰²Ê¢·¨d;p祘•õzJi‡™¦›>œÏåVËf"«õéÉøxÍú³tšcê¼Nšñ÷¾ýž1ÖrœNÓv€QÌàÃÛ½×Ç“yZw;áZ7~üj°Ôô{è/>?ù÷­…ãa¹ÒŽ\¦Ï&b¥N²¬›,¡M'…^ŽÛZÏÓÚnlt!Œð ÁÖŠйTèRbè˜BØ\EË©Íjë2²QNíïeêÿ_ýÓÚø'ÿ$ù“? ÿäOÂÑ îÝW×v”±öt&·:ÁöRÐŒ\¡¼t75h IDATµ‘ì¬Ä®ÃJa,XBÉ—¯Ge!Ýî]¬–B+cËZå•DNÇi–„áV§ãr~µP“Õ*­ «¡V*¯ëLÚX« ¥ÄRÂRmdàú‘ë•¢r×w\FDì9Rk$„QbCŸ/-%NHîxK(-«úèôòé“×í¤1žä¾ßì´š;kÞO?;|õvtëÚr+rþúo¯oµ[‘ó¢Ÿ÷n+à#Ñ YâÓó¹NÏ D²Ùi7|_£Œ©¤É)QF+ÅJi]†ÅJ¹Ë±OÐRÔ¾C .ÓˆdQsNU;tg%PèúÞf¯Að`¯»³ÕîÏ*îq©ôŸ=¾èrçÕሥÞŽ‘8tïÞX~úzhŒÙ]_Ž•6ÛÝàõéLH³±ä½½L a‰oN&%!Ì碟JJ¸Y.ˆOk©¡,àÂXRk'àH̰N¡$ÍŠWÏOŽ/ap9ÌÎúóVÒº¶üê«“µ¤Û þìo^ϳúÖVS+õäõpo#!ˆ Õ‹#8. å#XH8ZŸÅP"IÀ k««i¬B@Km%Œe¬6è1}±D@@ Äe”A—;Ε0ps5Ú\ 9gJÛY©öOçǃ´”&ô¥˜×z4¯|—å…üÙW§ýqñw?½vm³ùÕþéiœKaŒíµšÍ0´µ”ʘ´2ÊRŸË€D¬”v˜C©WJ½¢v™Ž]­ ! 6=įµ¥„Ñ$´ÕŒö¶¯/­u¾ûÁ–²8]/öùòôl{s|â‡+ ò׿< Cw¹löŸ?»ìu•ÆW¯‡×ד8pŒã€µ"öìd¹$ È—Çév›ŒrUJ»rQÙZAèÈ\2F'FYGY;µË]ehìm}©årH8Ú¨nÌŒå.³ÿ*õ`ÛÔã1Ͳߜí¿þ¾ÿ«ÜOkµÛñN§Õ “ µQJµ²¾ ´¢ˆð­û«Zë¯^ƒŠZ)¥ ðx£%¤±Òi%¾¿ÞjÀålVIyÕN¬1WQ—sˆ=Ö 0—d) µ.´© å9¤fÿ/{oÒcY–œ‰™ÙîøfŸ=¦ŒÈÌÈ9+3k&«ŠÝdSÍ&ÔB‚6½ÒŠKÒFz¡þý´-@€´ÑÐj‰"Õd5«Š5dT‘‘søîþüÍïNg2-nx°Z @kÅæ…/®ãù{xn×ÎùÌ>ûŽ…ÂxhRÔ„°™‹§“º4~˜É‹µq;Ofõé³³ºqκÕt=Ï;Y*E©üî×oìïôÎ'ÅÝûgßÿÖ+óUs÷áÙïþÝ·øÎ½ç¾½kúÙÝÓw_ßÏKº±“Œ %ÅÞ >Y4’Ä0“3{k#j\˜×¸ƒX:«†iÀa.™ºÆÌ©ö‘¦²²"°·>\¼‘¡¼¬ÃÓIi}0ÖWµÍcùáõ3—ÿåãÉ‹ÙÝë ¾ÿÁU% ~øñaã|ݸ¸“éDGItkog·ßï%Immeídµj½¶íKÛ#Ë©©QR2ûÂvbé$6:E³JU8˜¹<ÂN÷ÏËn,F™|p^Ru0­ŒóÆ8D¬+{üè„C¨Êz~:Ïó¸›éÿøwÞ˲ÈZ÷ýñýo}㕽ÍübQ[^¿6<8[5Ö¿~µ>y<¹¹Û©,WÖߨHg¥¯lØïëEÍÆñF&¦•¥€*Ÿ¤²D c‚an¼0!JeQ d-ÂÚÀ´„Aâ+¦e¦ødÒìõT7¦‹µ½{¸ðÖoõâ·®tŒõ?ýò¼)Í··>{|!™ëß|etçËÓ²²(E«ØßH%“H¿¹·—EQÙ4ƹÒÏ/Î,+"BÌc™E1aÈU-ˆ˜º!X%@ÔÍÔq€0¬KK. B3-y3ƒ¢ñ§+{c Ÿ=ß: ÎWEíŒ[žÍûƒT(ñ~ç½4Ñ?¹óL úí¿ó¦1n¾nÖ&¼¶×=›•+öºÑ“¹ys'sÖŸ¬ùúPJÂÒÀ¼âTë<òÞq¦…á`…ì#W&$nŒ¨ÈO.p,áÙÔõSL$>ž4ÃTäÝ?+‡™¯›²ñ»½h3—Ìð|Ñœ¯™9ø`ë¦êݼ,ÍÏ¿xnc†ui ã4&AJ«­½QE\¿˜§ëuiŒ Ùk)<)!a˜%y¤œ[+Õ‰¨ðÁÙ <«H”ë†++†‰›•nVÁVî'…Ÿ~Ý4ps¥ïL?¹wÚ”õÙ³s$B¤‘J;ñ¾sëÎç'I'úÍï܆¯žM–«ú·¾{ üË£ï|pÕ9ç«óï¾Å{ÿñƒ‹o¾¹sïp~m³“EødRïõ“XÂó¥e*07ŽIh¼L±4€q`AP3v¬]ÂÚÇ A8¯D¦­@üøp=H%3ž.+f&¢¦6›}m”0óóYýéà ïÜ­½Þ«ûÝ}zÒÏ£7®Œõ?¼sEeQP”F*R·nì§QtccÃ3WÆ”ÆTÆ „X B2.Ä:’D©2ýƒåT i*K …ÁaâWM@d>˜5[¹Ä/ª®V??Y±ÎùbQœMŒqëyaË&N£W·¿óÍ[ÝœONŸ=ÿÆwn¥Z<>]înä[ýôÞÁlÔ‹·úɃ“U?W;ýäáy™Eb»ÌÌ ÝXœ¯9Ó¨%•Vô"@yVŠ*"˜„°fì@XÖ. L±,5Y™ØÎ¡ý[5õ_pýWÿÍð›¿^ýà× €ðtê#”`-)ÈúðÉáÒKˆ_¥ï]€}q^•¢\–pu§ûäp ½½»9ÌÏ×s‹Ã¾âÊp¸ÑéäQäChœ;_.›_éò JÊD©^lR-™eãU?q {¶\ä:W¹‡ a¼¨U©ÀF&×:5W ™ÿôOïêuÍÌï¾{åí×w?›¼ýÖ~¤hUÙçãõoí{ÉgÇû[Q/¹÷l¶3LK|·v:ÇóÆúpc”Œ×Îz¤jQãN‡mµS]3(Æ”À3j ËÊ D*ëUˆ¢hlàÐŤ0ëÆ BÂ0^Ù®\VÖz>™UÎ:-ÅN7rÖí ’6:ùÑgÏ—óˆÈ;¿»™oŒòÂøÉÚlíŒF½nªõµÑH a³Þ¯êºÕ±{fHˆJÊ^’€Í Í 6+)"yY=cã#âUa`Ù‡ ùUí ‰Æ…ÂøÂÀÅé¤X–ŪœOÚ9ü?üûï!ááñüæk;ƒTOŠ(ß~ey8ïç­÷úN~±vkão £EÍ•áa&–ØHÝKÁ0 Ì–Õº+äªrZh2Ž“Ú˜,' «%fšž/*-0åýór¯«žLÊUe³Hö"ò!”ÆŸNKðáêFj#„ÝÌ;:)Îgå;7F?ýüd±nàú^o¸ÑY.,_ßÝÊ´¾¶±‘(5/˲iŒ÷Æ9B{2JÑvÃî§)ø9‘Ž$øàO±DD/ëTL‹º‰ÓE%öõùɪ²aÈ<µ 'ójUÍ& ïüj²*—eðá7p{c#—Jžœ-óTß¾µuv±^¬ê7nm~úÕÙo|ë•ùª¾ûèâ»ïï A'…ˆ²ùr™h±;LËÍŽî&òhn‰L”x¾â묬 €™²mǢ¿²^Ø BhŒGëÀ–†#Åá|í'…óAYë2M·wóºr¿|xa*Gr”<Ÿ¿ÿÚÖÙd}|¶².ܺ6$AB ¯ô¼ro^ÙdY/M™Ù8·¬ªÂ˜‚gfˆ”ÒBh) •˺ ²•ˬ[%2¬ •M+úâdщE'z1dì`jÆëº‹~¢œqG“Uå§ãÙôdÊÀ<ýþ·ÞÔãNÆëï|ã•Q/ùêÑù²vïßÞyx4Ÿ.ëï¾·çß?œ¿u}Ÿ7·³³•ëÆb”©ç+Ÿ*ì%4«H VBø RÕ0Æ ¡fÌØ/¯‹X”‹†¬ÇQê&Ï+Bhj˽D®›&0tc)/ÖæñéÚ{ßIT?!„UåNΖïÝ~üÕ¹©¸ÙKŽN—‚ðõ#$|>¯{[Ã,;qüêÎŽ–’kcjk—uÝvîk©Gè&I,±Y-eÀ8–Ø%Þ‡ÚV!„ºqèÚ³•/›êÐ¥’̇s3/ÜÅóI±,ËuÙ”M±(q£ÿú·_e€'“÷ßÞg†Ue··{{é'_žmmw÷‡imÃÓ‹òÊ ž×IÜÌåEÁ’ ŸàÚHBŽ$yVšJ¤).ë9Q.±¬ÒÂK •Ó&–̘7æoiê¿ðú£?N®_ÃÎf3)üÍ % ™Q ¯ìÓi-ˆ˜‰Ž§õÁùúxV‘ Â{77^¿Ú'A$Ä··n^Ü6½÷d:™W80ûÒ8òÌÆ¹,ŠÒ(ÒRFR*!Úóí8Ï\ZBJ­÷µ i<{·HGJgPIu¼°……­Ž8ž5ÃL66<™Ô6ÀÛÉfGë4Žzýt8m,‡(‹…ùåƒÍQ6Þ‡Ñ0ÿÖûWîÞ;yzºº±ß?>žLÊkÛuáævç`ZÃõQr¶r¡Ÿªux—™2€ 0¾X­³‘W¥U’|ª¥ºÆ9­”g DAh;[‘·žˆ>xcûd¼êåQš¨ºvóEňs.„DkØM’^š&QI©¥ô! b;¢Çyß8§(xs•KÒ( +„™v'KŽ$e‘舨¶œ($*ËJ`'–{=µ·Ññ2îõr–”äIœÅáÁÓÉý'©ëU]×6MÔ»¯ovïù/>=ʲèþÃÓv¢ñ¤ø7?yôá{Wʲùéƒ+ÛÝ뻽ŸÜ98x¾xõÚðþãñæ(ÛÈå'Æ£^ÚOðÞÁ¼ŸÇëª2ž:‘γ„PLËJ ˆµ©²L]E®­§à_‰ÿƒVSë;þ㟦¿ùwjœ•”jêÄþÁØ1S7Voï&!p`þÓG3©%|ÿ½ÃåÃóÅõíÎ鬺sÿÊÚQë”ÁØEÝî YI!išh­„È¢¨UùMã/çó´’^VªnL‚„‡Ìƒ—¤^9ãü¼¦W·Òƒ©eÑQ\šðlÚæÒDˆ½Awgsôê­+w>½œï »g• Eýôd.>?âÀÓi¥Ñ/?Ž>zÿêövúþѽ¯¿íÚ^ïÞ£1]Ýé>8˜2ЕíüÎW§ßz{§jÜã³ù»×µó³êÕM_4žóº²‘$+%䦵K!âX Â`F•68ï)çk ÃTÏkIôêVz0©ðÁ´vÆ‘’:Òðƒww$ÁÝÇ“óEõŸþ½7?þòôËg³6(öÎë²®I¸Ýï+)µ”™ÖÀLDJãœqεC™55@«]$`Ù,‰\ˆQ/™!pÙgõbl¬›W°‘‹À<-„ÀŒJdqþZ–()úIúÉݦ±ÂxQ<=ƒuŠð_ÿèÑb^T¥ùú7o~ýÝ+y®ÿ—u÷Únïö0ûüð•ýÞ[;“IiëBüÕÉò½ë}üã‹úÕÍôxá®ö©´JÇÒfÞyK©nd€Ž ËD…½.Îq§«Žfõ‹Æ×Î Â,QÎùg“ÊÔ”V>òÏgu'5Á·ÞÙë¤ ~xçèt1ýÚà;ï쎿8žwãXEJ ÒT+KY(e¼¯Œ±Þ[çÀxËFy>ø,êhXÈ.AÈ-«¸ûébIû}yº¬BˆT4Ž»†qc³'Ph)ßû GOOžWUóähjšó<#%.&ëN7ùÉO¾r{ï{^ýáƽü½W7âó·®öŸŒËëi7‘ÎóÁÌÜÚŒ|€Òr® €éLÐJ€±å¼Â­Ž/m”ÊFÊœ¹N´(l”H³¨…âõ-0.Œ ~c[*“Â?™TÎ)èïŸθÀ¼XÕ"„Æ…{O'Y¢„‡ãÔÆë8Z¬M>òyfò8dYªµ$f3gQÔX»nš¶%;¸ÐÛ­Ì`(™Árw¥ÖÎ wÕ%ãUEHâëé¼âÂÀ7®wÎWö`ÖfII ó¼“^½º£…˜ÏVÇÇç«^z¼´xr|ñàñùªhþ³ÿäÃHA<òÖß}6oªæÃ7·òùs…ÀÌëÚµe&é¼wÞ›ÆQ?˺qÜKSBì§©ó>¢²iœ÷/&9†PãCFé‚ý*0yÈcj€ºupŠd¤ð=»j°q+?.X „×zJx2Q³Òwúùõk»ñóÏCUÕO–¦2Þ¹ßÿßÙvyþ|þ“OÓï|íZÉÇÏ.’HÔEý¿ýâì½×6«ºþÉÝÉ›×ú‰òG;È`^‰Eåö£ætÉ»="Äe£º‘eêA( AŒ¼ö,´@óï X“3ãÿñŸ~û?²Û»Mi`âEáO~3—ÃTŒrùÉQùdRÍ›vŠ>…ñEÙŒucCYšÆï™!¢Nô;7†Uãv†é¤¬‹Æ´#‰(ÑúE±Q ¡¤DJJB$DHDÌ €¤ë- Õ4^³õÐOédîöûê|m¦Í¬ Ösm½–¸‘©TS¢1Õäö÷¶¿õîqu;™Š5hÉBœõָ墼÷Õóƒ“ů}tƒ?¿^×6Oõ½'“H‹·nŽŽÆkA¨$=>_íÆ`Y»ÃYsk#¯ÃVmˆ$ùʘ4îÔͬ°Ø‰®g¼îÆGЉɳèDX;f «m=¸77“^¢.Öö‡q?ÕƒNt÷Ùü³‡çû›³YõéWgóU#„èdúÚvgÐOW•åÀ*Ò¥1+EDŠH ˆ‚H Ñþ b›ç€”]PtC "‰+-‘!Ï”1Au"1LiÝ`ÑvG"âEáóvGešjB!ÅÕ½­÷ß|õïÜFBÖÄ‚êÆ­×µiœ÷þädö³;Ͼx|ñ÷¯ÌfÅñEñ»ß»>œÏêUe¯ît¾:^}tkXÙð䢾9ŠNçv³«&+“F*QnZB¢UeêU©öÓˆ‘’Q"9–N ª}ê½w;¢´‘‹D‹Í\_Æ£Ž>[R\¥ý\zñ[7W·»wŒï|yöÕ³im¼Pbº¨ïÎævz1 ªŒ3ÎÅZ+"-e`&ͽ0‰KK"¢Â3Ô©%˜¸D`-8ûö»{wïŸí ’n¦Î.ÊðÚvRÕötéG)Ü;œ:rRØUÕhɳз;m4#eÆl­ &È< B êQŠóÊyÆíŽx2iŽf– &@;ò õ."Zço]ézq¯¿ssóúNïÚNïh¼A.°ŒTcmm­"„ˆyK)@ER !¢™¡tÊq\yÍŒB¨± AÉ4Öñ²6:1MÖ&–4ÌèÓã ÀÞÈÕµa”jj¦ÂFÀM¬DðóÒ %´NŠ˜Ùk‰k˜:1 RÌ#Ñ8Øî*ãáóçųi5+][ÝèDo^éntã§ãuݸãq HUc­g"j½KÅ ÅrUU6„DëV¢¥ÔB´{cË`·ïfÀøÈsÒx%H¦qÏ8@©vRÄ' ›i$¢iaû‰ØíÉ­\Ù÷NË£¹‘û‰Ìcê&2KäæÎöÛ¯¿ÒíæI–`"³^¾\”ÎùïçÖ«×GÛü®í?ÿŸš¦ÑrQ¢VoßÌfŪ ¿öÎN/ÓO/ªHRÉIáF ŽWáêP–]Õ²»ÂˆXúEekë" ž¥õDÐüû ¸þ&ƒñÿ,¿²'®]7€À $‰ADâbíŽç†¬÷@H ÜŠKÛÈÎ5½õÁ¿(ëD_Ùî¼kãóÃEËA'v ý„*Ë ‰²(j ! ¥DxI¾Ø éųD.­”–¢UXIA:×~^7޳HäV–µ½D A’H®o|̽NvëêîÎö(N¢Ò©d’'qËH"`¹®?ûâøË‡çƒn¬%E±úúÛ{ìÂÏ¿8ÍR½½‘=Ÿ×oì÷ Æk{m}u¸Ø%ëXëÓeͱtW…±y1FÒi¡ÚŒ_y¶r˜ë_ÔXœ­Ìᬶå–_¶ÀÖ4öbQãZcªH¥‰îw¢(ÒRP+ µ”í(­T«Wo™È"’ŽH !‘ ¢Kc&Z‡`óŽc"‘h=-}'âiá5 3¯ÍñÜV–@ö)×o‡Z´Í˜ѵÍ$OtQ$ã<‰ó8Îbkf.–åg÷NœõYª>,×u”DÇÇ“ªño¿2ü“Ÿ=«l09ÛýèlQK ~6m" \;¤È˜®j×K”Dã$©²>Óàa/>–†+ë%Áxe™™:‘@ ¤;'fUe9¼X>Qµ7Iž¬*(¸qNK)…ÌZ©ü2²!jë)/Ý20#ØH D`ê4ÎeZ2ûXq$Á¸I4ž˜Á¸ðljÎVÖxu3eâ|e™9„GúëW¶FýN7“±F%â^hìõÒ½A<[7Z©Æ¹Æ¹Dë˜A$ñ2L|ኗzÃTÚòJ'Š ¬$ÖJ€Òzo¼X5r˜q`Ú銅؀a IDATÍ\6ŽŸLšiá"E©&ϼª}cíÎÖðêÞöëׯäyštS(#%•DBl{p4ù싓źÞè'Yû½ý£“Ùƒãåî(¿²™y¼ê¥Š¤¨LDx2­®£²±ã•åðÕYÙiQ %Di(+I$æ H),IÆ5Q;o&´ü|+M?¼(Ÿ·³hÚþ!0„€€°³Ùéåzݸ$½l0¬”õ>¢Ö÷¼÷€øÒ˜/QœÛ颭UCI  \Gˆb‰± JÊÀ~Y‡ÚAeC`ȵH´„DÀ³Òú¶†ý­áöpÐt×¶ÉzÙÁÉüÁ³éÃé'Ÿ:ëNNfY¢CËU-ˆ¾öÆÎ“£éO?9Jóøàà‚”Úíé‡ók›ñ½ãå²´›]q4oŵeDè&ʳbæum"Å ÆÙuýF÷Í7u5ÆI-Ñ×fK³Š÷7†zV8B”ÈLˆ¶eWj[¯k.´TRh%öwÛƒä¬pßxm„ˆ³’_ÝNÏ–6t룑”­&ˆ¨aÄüb§»\®mŽ…€%rI(¯B¬hÕ vbÜïá¢Æa*_é<GsW. › ’–"QÒ†àCØêv¯lnÁ¢–$‰$ÅiœvÓ´›êX›ÚÉ( TÚâ´q®•‰úÝÑ@Æ:ÊãÆØ8‹³n–t>¬WõéùòùÙâgŸe©~õú¨.›ñ_ìow~úÉ\ÌËé²~ýJ÷óÃåde®o&Ϧf§£=‹DùÓU“hYX éVɪö‰ò©r³! ¥pQã|`íÿŒð‚ŸBpÖ9ë8°iŒ·^+Š"™¤Ñ÷¿vesžÍê^ÛÜîÇ‹Úæ<Ь÷±Ò-Ëõ2 y™¥Ä¡ö%0#¢ÂA‰\2vŒ‰tL©q@ž¯LãÀxx}+º:Ð¥åó•[7¡2PY@D%DÁ…°ÑïÞ¾º?öœB Œ’H':ëfY?Kòäôùüàpúüùüødþù£1œžÎ}€÷no s}çþùí¶ž²•otôÑÂîtµgò ’üѬ Uã,3'êo;pýÅ×Ç¿¿ÿûæ¿ûï}'FB¨×Æ/kØï‰OƵõ>¸’·kõO¿×E½Õ7“¾ñöî¨÷"ÔXUö“'ó››ùѬI#õÎFül⮓L­’}hJãµT’ˆÛÕ/­Þ‚G«µF4Îн¤GmŠ,@LˆˆËAÒœ,àØ„Ý®8œÙﱨ‡Hˆ‘R['…Òƒ'täíý½AžÍËòl2o{5[cÓ^šsgÜb¼˜†Ÿž.~yï$ø •¼÷äâ×>¸:žUÛƒd#WÏΖ Ääb}ýÊàpR?:]ðêN/ö“µO£ÒzŽ¢4ø Ê#2^H Ï׌@ $ˆ˜Ù:ç|H½¹0ÀŸ}uQì ìjøþ‡Wb-ï=›=¾(óXýà£+BÈÃiùú•Þ0‹/ ¯¤JÆWÆDJIf"Š”rž8¸¬·6lùŠÆ9¸vŽ©PÇ­tm9ÕÔ5³;_s¢PuIJfº„¥X©<(‰µ’¼¢f»—&z¤˜v³uQ«ÒYgjÃÛklS5«Éêôlñsïðí[Dø?üOöö»·vÿìçÏ¢HGù±øÞ7o<<ªàæ0ÿü¨º¹‘Ž×¾£màÌû¥ ¢“½àkãÅ Gó0+£ðè¢nŒ 6S N想US6-ˆêHÿÃïÝÜì'_<¥yÒˢロ£ã•yu”¬.ˆµµÆûÜZBDZJfvˆ€èCð—òà`m‹(/,ƒËXŠÎ¬R̬¥¤µq)¨¬l¿ôdÇD€‘ZJ-%„šñæææ^¿?êvžœ/×åô|BàÀÖØŽéTëª)›??ùÙ'‡DBPZ\ÜØ|ãkWgW¶»wOªÆ]ÝÌœ®»šÎçFj9YÛí®œ”¨…©Í*pB%E)¿ÓAë©rIí×.ØöKZï›Æ´|Œ³®Œ+ÃÄ9}c»ó"IF”RœŒW_Ì“N²·Õé¦ñé²y¾l$7GrÕM¶¶˜z¯¥l«Q±Õs½Œ /U]BèfQä}ÕîÎÅN—¯—FvQYLÖ3"*/‡fbkIç=³q.ÑúöÞîv¯ç€ËuÕ.í|lc‹E1×Þù£ÃÉŸüÙ“ý^$é_þÑ—ßÿúõñtýk^;¯-_ßÅáE¥œ—›ƒÎù* Ri½\Ÿ®ôõaYÖ~””Œš!¤Å²¡Tñƒs‡€bE©"f(—³ÎÖÖ6VÞÚïÂÕ­N¤¥âàtÙ饾¾yrQô{ú£«½ÓU=ÊEãØûª2ÂeQ¤ÛédÀB´GQ˜ùWo uzi Þ¹4Ê2…8]W„èYdš… ã¦Í¤Û3¥’H êÆÐ2i‹ŠscÖ›ƒžÔrº5:>ŸEYµ·Þ;ŸtSšj]-×õ²šL¾÷íWö·ó?ýé“gçž~íßüüé7ß¿2Ÿ—ÓEue»3™—ËÊ©$².ŒÒˆÙ)òëÆ÷âÿôo2ÿ³ÿõ?±ZJA¨TwVÍ3ek'ž/šÉºv—ÛûÏž,LcðÛgÝnúïX¶“¨_ksRx‡!XÇWjV†q¡)jÇH\HÑ ¬BÑýJ&÷⎹]º÷"„¶2ÚFÈ‚he4aMHg+ÆË—””q¯‡’`Zâ¼ý4Udµ`IBI±7ö³Œ™×u]7¦.o½"Ä!Îco½3®\–þRXQ.Ëÿçß<øè½«÷ï>8KSÝëçÝTͫɢ¾µ™kÏ—çÆ¹T"a¬ó̱„)0ÔÖûÒf6Ö…V~ü°òÖ¿sµ ;)ܾ6¿Bß¼y}«Ú/š8‚N úêÑø6â;¯nTƳóµ Ï|Qõçëêƒ×¤õ¡²Fg™•ub¥ 'ˆ!æVÒâœGà4ŽZ‰  %á7ßÜFÂãY=®x«—þÖ~&+3]7Q,óX!b'’HdV¸À6å}ëK™˜ ‘.9ê—Z¤À\[ ‚²$Ê@Ë€` ½–ÄkCÌV`hïÖÔŠh§Ë‘ˆg•Š”rÞ#@U¬ÔÕáÐ87ìäλ¦2Î9!ÇœvRklëι–…òÎßxvð|ñúÍŸzôÚ­­T‹ÿãþÙk·¶6:ÑÓ³‹þF7Sb®ü0áÒx¸±• ÈbaœµžŸJÁÐNg2ÎYçÚ ;‹ä«W:Þ‡x]YOP‡/xWŒIG ì²àcè¥Ñ U©–ÇKL$F’$³B¬ù23VR¶óO|á˜[ ñD€(ÀÆJ€ƒóõ…@IÔUâߎԕ±¤íJÁãBj!e§ —$‰RgËþ2ŽŠª.W•³Î;/¤h½ÑÖ¶XÁ‡“³¥m, úÑÏŸ¼u{÷ãϽ ‹z½®CÓµqD·v»Æ;ç}ã ^»uû]Ó8)± ˜!xI¸2JK(@,kkjc\Z-$04ÖXÁüÍÛ›Á)éöµ<<šW“ò<Î⨶.Iu>Õ*V2.ÑàÙï™5¡Ò{`ˆ€_|ó5Ö¶¿fZ·n%Dí<È—ì# ¶ìB,ƒ$îvYK#…&‚ý~2ÌóTë“él™uÙ˜Æxç I'º3ê4ec*óãáÎakáý£‡oÜÚ¼÷h<dÎù‡Ç‹§Ï—oÝÚðÆçkE@ˆÖ9Ï ÆéõOþÛúˆ¿õÛIªcDI­êæx¶ðÁE’¾y¥óçzÙ RÝ]ÖäèrÝŒ2+œ—Þr´›†NDJؕɀt¥ÂLdÌ‚ýLÉ ^Òñ—ßKôm.ݨmÇÌá¶ÛŠTªñÚ@â¸ÀDéíŽU"(Q­ "ÁÌ„”EQÇJJ›ø XZkQ`ð!¸à¤“ZJ-qÞyS›àCðáã»'HÈÌuã^½±ñìdžvSüÅÓÉp®öõ0ÕÏ—¶±6Q¥­#%\¢3);€°*›Õ;»±fp¡²þóãµs~R¿¨ýøñü…P+ÙŠ8z ÝØÌ ²<-½‡¨Ÿ8@í9êÅ¥ÝDÇÆN-—å.ƒeøCµ&z¹£áå.˜C.°õÌK¥;]$Ä‹<ÈDè+½Z•äK—q¨‘” )b-¥ ¡lL«ú!)B*RRË+ï¼)MàÀï?½ ¢¯Ï—UÚI«ÚîntßepÿhùtRöï%ú|Ý(åÊ):BP ÃÈÍ{{Q`=/ÝÃqé¼?œÖ¶6Ràï~ã 3 B?Ó°®#ž¯Ì£‹úê°³ëaG‡À•åÊ)0 %Uãe¢ò‚±‡À‚ˆ™^dmÅNjgjµqÌåÑDÌ’Ö Ù-lçî÷%þ9U‹çkˆ”Ò$÷»ëÒňèY àó ×*í÷:UlšÆ4eäc­"寳9Šw>øðåƒsôðÑ„ž]œ'ªö¤œ1\ÛÌgv¿¯jba/ N”p(rk˦ÙÈéöVwÝø/O ë=Ïk׸,–o\é2ó ñWÀ°lœõ\X¯áö¶ÆkT·FnZ ! ern"å!2µ ùå€Ë—WË㈕ê¾4&^­C@ÃŒ¶;âå[|À•‘‰Ðû½ZRƒ”!¢Æ9pPöÒ´dz¨<¿dÚ[Τ’Q™ÚxçÛ—ŠÚýô΢›éÂø³IÑIUÃøß¼þ‹û½ŸÏËÉRÜÜQ×pº´ý¦% 3¯dÏ1˜U僉¨ñ|8­‚;½ø|´½Lÿ[ÕÉ+ýKÑUNW¼ÕÑX-ªp¾öy1˽uãDön*ä@" ~‰¾ˆá2á_I”[€ðÂ3[Ùm+ÊØíŠ~úB£ÃGsJµŠP6Á‘ˆÅŠ—žó\;½^mm–ÄËu±,JgœQ†=‡”R>÷Á…¦nœq¦6ë²ùéƒ(‰6GyU/Äo|ãÆ/O¿ýµ«Oû›>©\•¶óטÚô.ÿßÈÿù1­í —lm–ëjµÓ£4òÌçkÿ’kj=àdå_T×.WW$U¢ Ñ I´»¿–°ßw~RjI¬%Cä…Ž6B`ム~ÛÂB€àT@ñ²lür/£¶FÀ{ßžä!€TëX:º„íÒ %äN×iËZ5ž’(ë‹:peÔ*U8óP’0ŽDaIµrÏŽiBÂàƒŠT ÆB o½÷ž·]Šñã»'ˆhŸM80|÷Ýøé¸øå£ÉG¯ïlfl)Q-k”*’ÌÀv¿çvòtհ蜯¬u>Ñô÷ßÙø+ŸËªá'ŸE‘–0Ê„ œ7i7ò©ªKb“D›ÆûÚÚ¶î.Ð"x¨È3ýÊö×>²i³ØW6H"-IPXÔ‚% -Åfn¥@IaÙDRëXŠ¢±&RYÓT3I¢n[gëÚ„€Ëú3 )¼õRÉ6ÜñÁ·1ÔdY-kB [ÛŸß;¿ºìÅzÝpG»y”(Ö6̃S l48œ™ÀÜOäo¿9üK¬—':qrkj ‡ èDG:Q>œõ8­”àp¨dC<¢Mc—Ε@#؇ ÈÄàXó%úþyÒÖ:?sàB0þÅ2‰µöÏWBiaÛd§ë¤A\˜4‹R)KŠÆÔ^DF¥ b+)…H"= ܦ;D”E"×Âwt¾²} Æ-¡Í—D’7~n¼ŠÔ•A|4.guáѬ¼1’§%$*XO.€ Ê:Øfk)àpn2M¿ýÖð¯³Q¤‘€À^OÍj ¥Oˆv^GÝØGTõ ]çWÞ•Ì@” €+ ž_úc{0Zþ&\¦{îÒ’JJÅ\8^H)P“”Ô¢ålÂ²Žˆt'Š«J7kW „¤iÙ4VyçÚþîܪº8°Â{\0 .ØÆràUiI³n¶pQýÉ/¥’Ÿ?›SUBþlÞØŽÏ×àPìÔ.`º®¯621Ê¢«ƒèßµX`˜WŒ ÿ?$¢ìlu䓉M£x˜¹®\¯M$Õ@+±®Vz3„%„ Y"戨¥kûzÛ à¥þæ’8lé¼o£íË’´…üYµ×’8‹H qch•`Aa^Qª(Õ°6}ëª@³ÕBh)Ùxï” >°lK–,@(áWZyï½õÌ|1+˜YiõG?~¬ý£OO>|mó³Ãùyr1«¦søÆÍÁßÌøþ ýÃ?L^yÅýÞï-þò¿ü§ÿtXUøÿñêÝwÿêC]¿÷_NŠÆÀ¤(¼oúaž@ã3ÜÞRê¯üÒ@a˜Û|‰¯Q7fà:@D $°ÃËt¶%Ñ b‡?GâV§½8Á+c|›\U¬^Ä€>¼*\xSûPvb†ÆVJ €¬­-ÍÒö\ki·rXÔ°¡)×Ƀó²z2·­ƒ^ìoˆ(•l¶H,¥l€ßÜ 2fþäÁøOîžíbáqÍùZ"â çÉz lŒµ €À.°øî^ò×Ü;›ÀY¥%"ìÇ1ó ´(|`´ùD[‡ãàwçž;gÎsž™gæ™gfP‘‹´Ä)BHR$Î8Õ)pà„cŠ9ç 3,a)Œ2jRB‰Õ³É99ç†n€]ÆŒÒÍ{"§UâP’§ S‘½ !„!ÆY²Ò‹*½¶c«86úû!¢åØdXF2!¼Ä•Ð)P ‘Š€qÙ„0NãŒÀ9BÀGYcŒ²šœ×Ú TÆz‘ÓŠJ‚ $a WIR$K%0&ˆ]AZ:¨H IzJ7ìJÊ&mIRê‘ë#†"ID"ˆ"Ë— ìq*š„%Yživ)¥œrÆ3KF–ÞRJ·Ö´ð;‰–6$ÎtÊ ÓÀ€M™\±‘bš„ii^¥6jK’ü ?È* B@0qȆŒ;oèU„Nt*9T›Ïn&@˜'1q"À”cü&3 O1Æ8p„˜œó¼N¡õÏêyŒY¾V»¬—º-IbKOd‚ÂŒKEÁéf€xì„2–ÒZUÙ!£X\7L¦:d=¦c@È M"¥¶ýåˆc‚‰DF  °Î…àŒSš]ʤSDõ”.;åª2·ÏN5·Ö'œvG\3|.ÓZXè”R\Ö |Ä.;55Å2c•|²uÖ$BИæV\tn®Í’€]¦ €2]£R n›ÝG4àÎT„ 1B”QΓÛ(cV/LÂ&â$,af븙™J›¦C2ÊÜ™÷J±„©J«²*Ó¨a)à$iÓHiÛSTO6»œv(<žæŠ$ÉÁksÆ9Ⅎ„É'”0…YÝƘµÀ•snêæšO»²m_ø´bçæ8AðE0Æ~hÛ´I½òÊxMüÄž¯=JºîúÅ/]”°Ûù’%žþ0TZJ»ÏÙ¤T"±˜*1N¸ D(G„žë5+àPËöe!ÄÜ+aÂfHÁSÆ8P$‰XHq‰1†!Ä¥ìSY«ë2$,f'qŽ9FgÚjµ#Q„PšùUYVe ´FÎÒ’ÕFéÔ¦SœÖ í‹¥Ë=r€úHÚ.c ¤9ª—y”f ! PÖDXAŸ˜`ÂIÆcf9{8ÀÞúHc(iMç„´RóôA…²„v7Å }ŠÓF0Bœ†œ’ 6‚U"„q’0Ðq‚œwœ,GÙ¦J"„ ]‚ȼ„è0Š›à,q„MÆ0BÖúÊ9ç«F $Û§q©ªÕ¶Æ5 dwMUY¶–r s`P„‘5`p¦;T/ã`P*á$pfrÅ0ˆJ’œãH ")½Ä-E4JèE.)©!ÆÅ€0B!h_ÿ†ÂVƒˆAÄÒÍ™>”œ¿æõö¸i#mpE•%œÒi›©²ìVt•èRㆭCTAös{íγ'LKÆ”bà1À“(BÛ%+¤åœS$kY•™]‡ã¶VŒÛ—¬HÙ Ö´aèÔ”Vˆ©’4Aùwd–~šŒ`dr†<Ž€NÍ4¥ NLN§%‰ª8à¶87©Qäd{ÚŒ1åjmÈÇŒ8á„Цc€a„¥LT2à QË ¹Õ2€›æžá Æ*öÚÆ¨¢ÚLÆ[¦ßmsÊ:ášMâiÓ֚Ĺp* 3ÚuBÀºL9‘³³½_‚sl0™b —d!Œ‘Œrr !2GÖ– n7ErfàÅ4CÍ4íŠ[$9TAT.º€š c`I’ä²$‰8OS5M™$2ÒM#bê•^ù@üvL0nK˜±™Þ6XÑΙ&eXÂVížûåaÙ0Á°fkÓˆkª„G PSC)XO”Í®ªIB)C•˜×F³€rÚ‡Øešaéjæî¬q¦™R4-˘åD£Š„U»L€¬‘ a\¦ÜÌ£c“:,/F™€ÿœwP"$™N€n6‰`Œ%bCÙæTBº„’&dù­¼Ž@Ê0L3B0!ˆ&t#Ó!Œ›-q,c: @v¶p„€`„1戙–035Zfˆ  3c sœÕ”Y[hR3•…ÑÄ¡…Î/@—i¢_ý*ðê«õ0vlú׿ö¯ZeŸ:5uð•=æ9ë,mòdͺrÆŒò7Þ¨?̆&\Öû ªP¶ãÀ!Háy±T<¯ã+]Ç&°ɹŒ0Ę‘FÛ9!Ùrúe£UÛ§åâœ2$+Šß2–yëŸÓ¨U\‚5δtšc¥2¡¥­V&‘N;dMBfÌäûÃÜ)CmP÷Ùq¹% Õ˜€‚!Äx±Wmޤ3 ™qÊ­}F™Jdµ)ÁH ÇÒpî™U~¬ÙÚH°ÐVÔX„ëa IDATÏI™Á„‘VÀçTŠ7žÊÖ|DÎéqî˜  É%¼c_3n“3‡]QҦݠTQLB5­‰BŽéJBC ‚tfš"¼Øcnº~θn»êês£T«ÞrÌA`9pŒ0|°ù€ÍiI–ª\Ê€¢À€â‡¢d'ÀLjF¡³÷B9ŒžI>kï!`,Mh—3kSÉmwÛÊlÑxò“½AC3lªâ°)¦A³Á8˜Ê„Æ!Afµ¼™ #k[TÕ®bŒ\.Ç„2A­9M@”¦ôt¸½Ÿ¨:=­a4åékwI²c àœ3]oâОʲ=7ÇšuJå^""ºú™ÕƪD(ó3Îm*oÅbºŒo‰%C‰úˆ)a‹Æû—–´„c‘h|`YÉôqg4´…Ö}¶+×™ÈM·ckŸÌG–/B…XÆXµ«˜`¿×ÑÏÏm6©õ¼ çúø :N ½å ‘Y¯KReù³bÛEiŒšñ®,»‚$¿åqCxÖý€Q–ÎäLÏ)¿«„8·¼2Ê[ñ˜ýŸ[ @ŠIU§SÆv56%õ4@zXy…IégM±dJ×ô~¥ÅËÕû ­(wÛíûšZkšxFšÜãržwæhU"áXâ­×cŽ)°ÝµB”qI•¬€",‘“lŒ)5½^Ÿiš‰Dœ1¶víº5kÖ|ç;ßùüíî§Ÿ*ŸåÏ#—Ó`Ïó@⪭ü°Ù¶ëRW³ÌÛˆä;¬ýèΑŽIövýU®Êv£(6Eñ;ÃÊË`[ÛöýŒ´ œ—|†IZƒ–šæ¢8ÊŒÛÚ{Ó€,cL$åEbßÀâ’~EVh´S’ýÇ©a)ëö*;dåpÌ{³aåðaPÆ…9Ï­*ËÞìqŸ9vì¯ß½¿Ám·3|(ç¼%]³ý3«[–kìgp&8V†admhܯ¼dØÀªÁeeVaɲ_–ý”&µt#BÄ–§¼+=äÀÓéÆƒ Oˆ[µ•CWsÉy×8»˜–>ô ûPúŒš¸étLˆM–9@Àå²n±¹®Žêf,¥5æaZ¢“UÙ`´-³ -æØ0ÌO·×XbÌøZsCL°$KÅ…þ"ïi%%ÖiâÝ©\W3FCUËÐAÒæyQ¹‡2Œ°næÄŽm¶ ~¢CºÞʸ!7‘\&c]^i-± 4aÐh^J ân[}Þ^_ß §sOCSBÓLà FcÔ íZ5fE†bw˜ætK¥•Ï.cÔÓð³Ÿüú¾ÖüÁø¨¢œÕ¯?Å>É™çrž–é=Òùè+@"[¾bò¼¨^`䬹nôiÓ éIsS@0Ô4Í0Œh4øä¼ í-[6^pÁ—ß~ûÍmÛ¶^rÉE‡ÊÁëe?þqèÇ?uU öäÿ9t¨þÒKGÑ´É2·¢¯O88QóùN¼1^¶Ì1j”>iR»¸˜žqFzÐ #k`:ؘ’€`[ÎëÖ©ýû›=$íž“Im­¬i蘊ÝÑ%î…ê2-;Ò(9+½öc[É$‘ÀºŽz"çýû¥—_¦=ôívþé§êA™~r¡¢ø0åÑ4äóõT±{T&;¡9Ûóejò•tè—œ {èbN™e·qYU–œàB¯1Ö´ÔŽÛêêö3FKJŠó¿¢”ÖÕí‘$RUU@ zÈ@ccCccCEEçx(Æh]Ý^Y&••_4cüóŸ]®¾7}ûíአ³Ïûë_´Ï{Μ„ÍÖÇ”¤¨ˆÞqG¸Ï‰ZQø=÷´AäD±E±Û»ÝîiÓ¾4hРNé¡`°Íï÷ŸuÖ9^¯ï Ù…1Bï‹Å<Øè‹Åîß¿O»/ö{T•Ú÷tc5ªOVÉ1cҢآØÇeŒ].ç 7\3bĈ.¿E¨rÈ~¿€uL®@ N1v»]çž{Ö¡¾ ¬ÍN²kñ¾ûúž/åºëbÇ’wR˜=»ï¹d`êÔ$c}¯‡xæ™éÁƒûÞ@ð´ÓŒ›oŽô¹bÒ… û¤ëþ}Ñ&õÅvûdã¾ÒfõÅ«/Š:AZâ°gôNô½b»Ý¬'Vö46ï‹ÓRÃØ±}Ò™ÜÛíóÊ„s@ aŒ@ 8¥ù"¸©[[I]¤ªü°›4mÛ¦¤R¨²Ò,.¦âÝ Á©ÌgŸÉñ8.+£eeÝM´¥RhÛ6ÆŒÑ%‰ÊîƒdïÞŒI­®66ú§Ïãp?ñ„'Á„Àù秬½3»äÝwíï¼ã0 ðxØM7E…=‚S–>²½þºCבËů».ÚMàË_þâÙ¿_€O>Ñ­˜¶;±~üqO8œq6{½ì–[¢GµABŸ7Æ÷ܸîºèèÑz2‰Ü+Ë|êÔT—r_»Vµ6”ÞºU¹ï>ÿƒ¶ uòùÎwІ5¾ûݰ…à‹Í–-Êòåöï}/Ð;åE‹ü‹·®6«~àÿg¤¿ýí<ÿ¼ë‰'<7ß=Øî d|ö™œ;(â{ß+jn&GeŒkÎXQœv{àà; £}¡Ë®]5uuûzH¦›7+£Gëàpð‚jõ_¦±‘8Ü æ1B?øˆ'àÔdß>É02뻤¶6G"øâÓÖF0ËXlìÚ%sÞõ*ǵkÕñã3ÛP¥oÙ¢Öî„Ã8<êztœ#c”vˆD7 ó½÷ÞÜÇ€÷ß_ýŸÿ¼¾ý?þñg¡A¯bëVeÁ‚âgži´Îòzá…!àp¹XuµùÈ#^H$ðŽG=Þ;~75×õ'Ð%“©mÛ¶žsNfK—_~íª«æ†!Þ–@Ыhl$ßøFñÆêw¿[4sfÞ}×~o}+²paaCƒtãщµ[o-¾þúèŒɵkÕÅ‹ý÷ÜÓf:nèúëK€¾ti“§àTÆçc7Þ]¿^€Š óP>ÚnèY—Ôûï¯~å•e?øÁßxcyÝ¢¬Œ64HVÓLb¯·}WÝ»å2q»¹®£t@S))Ñ[‚S¢"jŠü‹_´]sMìškb6¨ëÖ©°`AäÿþÏùᇶo»hÝ:õÚkKžÞõ£®Ze»ðÂrhn&_\îñ°?ü¡!˜=»¬µ•‘ ú N'ç’I­­¤°"”™Zµb§ãñŒq¬ªj·¬ÄŠ»îÒîTU™³g'fÏN bØl\UnSž à:眳.¹dæu×]5r䰺Ŵ>òˆ·¼ÜÔuä÷³Y³Ú‡é—_^6vlzÉ’&˜>=‰à?ÿÙk³±ÆFéÞ{Û„: Nqëð1¿Ÿ¹\ 0Î4€÷Þ³-YÒôÑG¶k®)}ë-Çÿ{àþ§ðosÀCùÖ¬Q¯¸"öâ‹Î³ÏÖ.,|â Ïw†„T}‚ ´ÖVüç?{NÖÒB~ò“`.zëÓO•óϯ|á…Ë]´hQëÝw>üЀp˜XJÞ¥ÝÙ¹S^±Â‘¹ôÒ¸å@ê-ÆøóéÝ_w]lÝ:Õéd_ùJ‡uM÷ßßêó±<Ûë-G$‚§NY3d ®¸"žÛ1´Ëk¿?S¿–,i:ì* Wñ•¯$ÞÒBÎ9G2¤Ýph.YÒtúéíú|ûíá·Þr€µ®éPvGU¹U#ÆŒÑÏ:K;Úò|6ý0Àè²2cFç5ÇݬBGÆpöÙZy¹ É$Ò4†-ècœ~ë`:wncŒW®|¿¶vŸxm@ ø"qÞyç ;‚“’zÑÞÔ.—kèÐAÖgŒ ÆxĈ1Ün×ë³ÒÃáPMÍNñv@Ы û÷¸cÇ6MKQšY‚_YÙoèÐa‡?N±cB°Ãဂ‚¢Â¢¢¢’Õ«?úì³í_<Ëçó§ÓÉ––¶·Þzkôèâ­  Wáñ¸ ‹ ‹¢ÑÈûÂá ¥Ôçó"þ8ÅÞuj“ßðû ÊË+5-·¾û²R0M£µµqåÊ÷òO¡ W†‘†ÕÜ܉Š߽È;®þýO“$yß¾~$ãz@ z‰DÔ4Í`°ùƒÖD£ÑI“&——Wö¸1nm &‰.¿ ün·ë(Ÿ!þ曯·´´¶µ«««ìǹ°Ç@ è3466×ÕÕmݺÝçóúý¾‚‚Àç12þä“­»vÕœ^TTtþùçC†EE…EE…ԇÑ+ÞË¥'“Éuë6†Ãñ¦@Ð;Ù¾}ÛŠ+%‰ Ø¿¤¤X’ŽÂ¯›Zµ»Gûµ9b>¬”Ûí’ijG•BˆÕÕU¥¥%é´þÉ'[%IB½òÊ+ àt:¬k@ è= „ëêj èt:ív[ή}NÆaâ”å§È˜{½ ]O@ssËæÍŸJ’4rä°M›>!„Œ=bãÆ-ãiÓÎë”Õ°a#&Oîxá…YæÏ¿V¼i@ ôfvÌ¿íÙ®h4¶hÑ&OžXUU±xñÃãÆíß¿úw¿{tôèŒq0ÆXýç?Ÿ¯S _Ež7oÖI6ƃ 7nìœ9—œvÚ€3Î3wîì~ýªÆ{é¥uº2‰|øášü=Æcâ] Á©‰eúVÄ1B(ßl!„®¼òÊ“?2€{îùéÌ™_½óÎïÛlêŽ;ß~û¿3Ï<ýà+].çàÁ§€,Ë@ÁèÑcöïß¿}ûV¡Ž@pj2yò9••U½¿œ¦i®_¿®¨¨°¢¢ê£>ˆF£©TÎ8ãÌ!CŽÈwýy¬3ž3ç’;ïü?¼hãÆ-Ï>ûï‡^ÔÍÅýû(**îßÀúõëßxcÙ A…: Á)‹aèû÷÷ö“ vìØùÉ'[¾úÕËE9I ---G5˜<^c,8ÍŸÊO98vìk_»ü½÷>7nìСƒß~{Å„ gv™•ÏçŸ:uº×ëÕu}Ƶï½÷>¥ÂG-§¸16jk÷ôòB~üñÇVµaŸ|²©ªªzðà!ŸŸ1öù¼çwt^ÂD)pÎò/[ºô1p¹œÏ<ód7®_¿þ½÷Þ³ÛmÆ I¥RB @Ї ”îÙ³gÅŠ•¡Pø¨NR8.c26MÀ«W¯^»vƒÇã...:ª¤ÞöH€ßëõøý¾úúF¡…@pŠóï¿ÔûqŽ74ÐfSeYî«ÆxԨѳfÍš' „Ð 7ÜÐ'Î)@!„n»í¶N‰}ÌO™röرgÍÁ¬?Ñ—ŒñÁ»c @pŠÐ½1æŒQ$Éétˆ†@ èDPI&$½Sb[kÛXÇi'ÆSjPj€Çã1Âm}@Ð>l09=`È¥„ö…>XþÞØ«r¢FÆ@ ƒ fQ“ûsÇöñdâ¨rèÚ×ÔÔîØ±KÈW ‚î©ßß^íꔨëú믿sðÅC‡8°ß‘ãÁƒ 6BˆX ‚îi¡VuJTuöìK¾˜R½Ë9ß®qn¶X A70ÅÒ9‘×õ£ðTw7gŒÂX>%DÉ(çôxrˆÇ.—Kœ Á)HÃþ†•/¬l·)&s*G·swÆcÙã);ä˜J…5-r<9¬Y³nêÔé¯;áã×oܸÅú|É%3ËÊJ„– AoÆÆ¤ÖÝõS‡žÝ!QVO˜1|þ¸\΂ßþöwÜñ=E‘…@ —ã4•Ë'^tœ™à#¼. nÛ¶­¦¦æ„½¶¶¶7H°¹¹¹·Ô8|øÐY³f^zéE¡å@p*pD#ã¶¶¶G}ôÀ6›íòË/Ÿ2eÊqÞõúë¯_±bÅIøE‹Í;wâĉBà$‚&Déò+Î¥zÏÝc ã®M!c&cf/2Æ÷Þ{ïÕW_=nܸH$òè£J’4yòd¡=@ 8QÆXQœ]~õÑGï3¬çnMˆ,Ë][E£‘ººÝ]® ¶xòÉ¥»vÕÜwßÏOLŸàH.Z·nݸqãÀëõz½Þ|'ó„ ¾ÿýïwóÛ–––ùóçO:uêÔ©3f̨¯¯ÎùK/½d%Þzë­Á`^}õÕ©Yî¿ÿþd2©iÚÿøÇ\âsÏ=Çëò.MMMsæÌ±.›3gNSS\vÙeO?ý´•¸páÂp8Ì{î¹ç¬”Ûn»- ‰: ½]§R¡üo½õÚΟ}·îtßT*ô Ï57·tó“¹s/Ý´iËç:2î† .¸`øðáÝ\ðË_þòŽ;î3f Äb±«®ºê•W^1MsïÞ½–§úwÞyøá‡úÓŸ>ðÀ9ßõ}÷Ý·jÕ*¿ß_WW—K¼ì²Ë¾ô¥/ùýþƒïòÃþð÷¿ÿ}UUƒÁ_|ñæ›oÞ»wo<·~þüóÏ/]ºtþüùO=õ”•²yóæk¯½ößø†¨@ÐàœsÞaÄ¥iÚÁ‡Çã‰ÿû¸ðÂio¾¹<ÿôëWi·Ûkjj¿öµ9`æ?ÿùB®¾zî¡oÝy¤§iZ§”çž{©ººJ×õ`04{öE^¯—Ìúâ—^z%KLž<¡¢¢ìùç_Î/Ò%—Ìðû}=nŒï¿ÿþcø•,Ë·ß~û‘\ùÚk¯566ZŸ×¯_¨Ë,XðË_þÒ’]AAÁƒ>>Ÿï–[n9ÔOÆŒ3cÆ ¡ý@зxðÁ‡‡ S‡I¶xIDATô÷¿ÿsüø±7n6 cæÌé›7’L¦Î<óôï~÷Žë¯¿ê©§ž …B·Þzã}÷-~çßúÖÍ=ô§nŒñ‘ÐÚ|àß_{í×|I,Ÿ?ž•þ÷¿?óÛßþñÇ?^øôÓÏ_ýUVIfΜþé§Û"‘è¬Y3OØÈ8ƒÁ@ `†aNg»gÿþý6›­°°ðh»?MMM%%‡_D{î¹çþïÿþoîO¯×k}0 ãÀEEEVa†ú“ŸdÎÇhnn¾ýöÛ÷»ßÎ)‘ŠD"B­ oñþû…B‘?ýéÁ²²’iÓÎkhhòxÜcÇŽVå‚ Î{óÍå·ÜòõY³¾r÷Ý¿¹õÖW¯^û K ¦M;ï8ï;mÚ”M›¶ÜtÓuãÇŸùì³/äŒñ%—Ì9røž=µÏ<óü5×\1}úÔÚÚ:«HœƒÏç=aÆø¡‡Z¼xñàÁƒ“ɤ×ë5kVÏ>{úôéýë_õÛ‰'®ZµjÆ @)>}ºeJó›ßœ~úé …,'öرc—,Y’³µåååN§³¸¸8禞6mÆ™Iî;wŽ9ò™gž¹òÊ+àÅ_D©ª étúPžsEQ dÝ¥­­íý÷߿馛„f AâÿxâÚkoY´è÷ÜóÓ‹/žqûíw®]»ñ¿ÿ]õÄhm Úí6—ËYT”"bŒ —r<¸\N‡Ã^\Ü!«;w?ûì¿ÇŒ9cÆ4˜9súx×Úµ—-{ûo{ôsÆ­ÁÖUo®ÚöζmïlkÞÝÜåEUUUW_}5¥´¤¤äúë¯Ïÿê¸ñÆ»¹Áüùó+**(¥”RY–­h¯»îºkáÂ…Vâ°aÃfÏž wÞy'ÍrñÅ=zàÀW\qE.1æ ¼¼üÉ'ŸÌ­JZ°`×ëµ.óz½ ,€;î¸#wýøñã§OŸît:o»í6ë²Ñ£Gÿõ¯0`€Ðl@ èC<õÔ¿~xÑgŸíjk ÀUWÍ}íµ7o¸áš./Ö´ôcýÕã=òÈÇyëU«>\·nãCý)?qéÒðn¸:—2oÞœ×^{󦛮í&«–]-–åmÝÓ hm|m(2ÁªÓá¶~~Ùm]Jˆ"¶ÃEE………·AôxÜwß cZ¸ð; ~ÇúüÆ/Z¾úÕY«W¯mk >þøCÝ?r‹ÔR§Ö@ÍÆšÆæF©Û"šÉdÛ© ¦y¼Û» 6!zB ƒ1ùÖ·ÄL¶@ 8¥Œ1-//*//:ZžNëóæÍ9žù`Jõ1cFÉ•%%ÅÆèùè˜Æ¥tŠjõ,4íê/ËUî ’ì`È ›Ä¹·‡Ôís²t:.´äH(//`'È£ /œ&D*Ýãt:¦Lùü¶ƒôù¼“&M8Ô·¦qI7\tô´Ó€!c@e|øÁ—L®”‹1@pä¬×Ö§xçó‡ZjZ¶|°å‚ê Ý Ã„ì@ 8¹tº‘N§…\@ 8rLNAéî=ϼê2µ[c¼uÛÎÈ>1O,ÁQà®ð­èæ‚M›¶í·gvwv¹àŒnñ¸3ÇŽî7RˆU ‚#'޵fwsÁ¤IúW[ŸSXŸ¯íΛT7MMˆU ‚#‡J‡Y"Ki:g^)1;…l‰hj@ zœ†Æf”B>Ÿ×ãqü­0Æ@ œêÖ×E’7WN…SÅÃÜf·Û„1 @>Xýþîµ»LÓ<ø[E’‡ >­º¨òP?ïlŒuL5b± @pä`@—½ð²±vsFÎÔvgŒ}¾:OS ~£æ–O[FŒÑB[Ä Zv·Œ¨Ñ"‘e Óð!±·ÌƒẌ6—íŸn¯U]gÔ é @Ûwm¯.ª®ƒc±Œb;L@ N2„„jöÔÕÏLÃŒ5ÇjvÔ @±æ˜i˜5›Î2†÷‡-«[öô‹O‡#á£ú±,ɧ-Ø&¤/Eiqicsã1üðÿBBN,a$aIEND®B`‚snd-16.1/pix/rksin3.png0000644000076400007640000004507311147553270013070 0ustar bilbil‰PNG  IHDR莢æ">sRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ;¸Ý±f IDATxÚìÝyXMkÿ?ðws’ ‰’)Eè9œs2f¬ É+2&*Ó~$¢Á¬ˆR†ƒYŽÊ,™Š¡dž¢I©õûã|O¿ãáÚµW½_×庴÷Úk¯ý¾×º÷þ¬á^r‚  """"""¢R%ÿµ'oܸQ¤™;v gÏžešDDÿãÙ³gxýúõ7§‹Ç¡C‡——ÇЈˆ~À£GðæÍ›oNwéÒ%:t}ׯ_‡¼¼<Ö¯_ÜÜ\†GD²_ '&&"..fff_}ñÛ·oqóæMôîݶ¶¶ˆŒŒüäyAPPPðÙ?î±$¢².//°²²úæ´›7o†ƒƒzôè\¿~ý›ýhAAC&"••…U«V¡OŸ>ßœvçÎ>|8zôè> 55•ý-ÉÅ/=hbb¸¸¸üÔÌ7oތ˗/òØ™3gðË/¿ 88˜éQ™¥¤¤„9sæ <<ü§æ‡?þøã“Ç>|ˆ .àþýû šˆÊ½J•*aöìÙ ù©ùœ:u {öìùä±ääd¤¤¤|óL(""©èÅeذa6lØ'I$¼xñ‚É©©)LMM?y,::ööö ‡ˆ¨µoßíÛ·ÿä±}ûöA"‘0"*1_<ÅýíÛ·HJJBzz:’’’ðøñãÂç¶oߎùóçÔÔÔ ««‹+W®àäÉ“hÑ¢%"Â_§J&%%áÉ“'xðànß¾]øÜíÛ·accSø·¥¥%öïß_Øï1@"¢"ÊÏÏGRRž>}ŠÔÔTܽ{·ð¹„„ :´ðïÎ;ãÈ‘#HJJB^^ôõõ É~ž––†˜˜´nÝ111¸víZásFFFhÙ²%@QQãÇG||<^¼xñIHDTÞ0ÆÄÄ@II YYY8yòdás•+WþäÚôîÝ»£B… ˆ‰‰Á¸qã ¡¡Á‰ˆŠ(77111ÐÒÒ³gÏpæÌ™Âç´µµÑ½{÷¿{÷î‚‚ÄÄÄÀÅÅjjj ˆdŠ\IßýïSÜy :Ñùûw^ƒND$]ŸâÎkЉ¨¤È3"""""""èDDDDDDDĈˆˆˆˆˆˆ:±@'""""""’ŠŒ€dœœÜ¿¯ÀŠŠÈËËcHDDDDD$z%r=??999ÈÉÉÁÇ™:}—°°°Ïþ-Z´УGDå‚ …ýhnn.¡Ruûöm 4:::PQQ±±1-ZôÅïx99¹ý—––Æ0‰ý-•ù~PZÓRÙT"GÐããã±cÇÀ©S§Ð¤I&/ÃÞ¼y ™Yž¡C‡~öØ’%KÇgƒQ¹••oooàýÏ©Tݼy­[·†’’&NœˆÚµkãÂ… H$¸qã6nÜøÙkš5k77·Ï¯T©%™“––†Å‹îÞ½Ë@è§úAiMKe˜PÂfΜ)8:: $VVVÂ… „=zšššB)¬ß­iÓ¦‚–––““ÃF¤r'**J¨]»6ƒ('233ejyz÷î-(** ‰‰‰Ÿ<¾fÍ€püøñ/~ωÑÞ½{…&Mš0öƒ?ÜJkZ*»8HáÎ;èÖ­ ±lÙ2xyyysQÿ§k×®!!!„ŠŠ ˆÊ 999ôìÙ/^„……´´´ ©©)SËxüøq´lÙò³³áFŒEEElڴ鋯ËÍÍÅ›7oØÈDT®úAiMKe‰#ܾ};wîDÿþý¿ëuÕªU+ò´D)¡¡¡€aƱñˆ¨Ìù{§é!C0pà@|@… >{\YYŠŠŠ8þügÏEEEAMM ùùùÐÒÒBŸ>}àãã===68•é~PZÓ t*ÃêÖ­ûÝÅ9üùçŸ%¾¬ùùùغu+ жm[6•9²¾Ó´I“&¸xñ"²²²>¹†üÌ™3ÈÉÉÁÇ?™¾mÛ¶°¶¶†±±1rss   ;v qqq,Ò‰¨L÷ƒÒš–X SÖ Aƒz]—.]J|Y£¢¢ðäÉxzz²áˆ¨L’õ¦nnn2dúôé???Ô®]—.]Âøñ㡤¤„ìììO¦?uêÔ'÷íÛ;vDÿþýáéé‰uëֱщ¨ÌöƒÒš–X S¦¤¤ôC¯{öìY‘§­Q£F±,ëß§·sôv"*«d}§©^½z…Ù³gÃÔÔ´ð{ÄÝÝçÎCBBÂ7çѯ_?ãàÁƒlp"*Óý ´¦%èDŸÑÕÕ-ò´Åq úÛ·o±gϘ™™ÁÀÀ€ @De’vš:;;ÃÉÉ ×®]CNN7nŒ*UªÀÀÀ 6,Ò~üˆ˜˜ìرõë×ÇܹsÙpDT¦ûAiMK,ЩŒ*Îû“KsyjÖ¬‰üü|6Q)«V­455€´´4hkkÃÜÜáááhܸñ'Ó¶iÓçÎÆ ðâÅ (**ÂÀÀÓ§OÇôéӹÕˆÊ|?(­i©ì’J B»zõ*öíÛà¯SOŒŒŒÌô‰ˆŠ(++ þþþþºv7** ÷ïßg0DDÅìÕ«WX½z5€¿NoŽGbb"ƒ!¢Q"GÐ4h'''@ZZÞ¾}Ë䉈¾CÅŠ ûÑÓ§O#**Š¡I––Va‰øøx†BDe«@WUU…ªª*@MM:Ñw’——‡ŽŽNáG""’…ÂþVSS“QÉþæcDDDDDDD,Љˆˆˆˆˆˆˆ:‘làmÖþ!11¯^½ÂîÝ»:::èÚµ+ yóæ—çþ YžžŽ;wîàüùó¸{÷.€¿î{Y½zuèééA__Ÿ!ÉÐ6•––†={öªW¯^xÒ-Z@NNŽ!‰Ôõë×±víZÀË—/ѿԫW¿þú+Ññþ3..‡ØØØ jÕª011a82îêÕ«8rä?~Œ  E‹hذ!¯‘.£fÍš###4jÔ¿üòKáXN$ûæÍ›‡øøxLš4 Í›7GÅŠŠH$''# }ûöÅï¿ÿŽJ•*±@/-ïß¿‡§§' QµjÕÂ[½xñþù'öíÛ‡jÕªaâĉ000€²²2C+%áááHHH€±±1,,,`hhà¯Û÷%&&bêÔ©°³³Ã Aƒø£¥eggÃÝÝ¿þú+´µµ ·©gÏž!** {öì®®.œQ¯^=())149}ú4<==1~üxôë×ÉÉɈ…‡‡tuu1oÞoaa={öà÷ßÇôéÓ±uëV†VÆÔ¯_Ð××G÷îݱcdž"µjÕ‚‡‡\\\`kk‹ àÁƒ F$lll°oß>œ={«W¯FJJJ‰¼o¹.ÐcccÑ´iST®\¹È×ÂÖ®]kÖ¬Á¬Y³0kÖ,lÞ¼™k¯”¥§§ãèÑ£8p`‘O1QPPÀĉ±eËdffÂÞÞiii SÊ¢££Ñ£G 8°ÈÛ”ºº:ììì ‘H°lÙ2lܸÏž=c˜2jíÚµpvv†¢â¿_!¥¢¢SSScܸq:t("""žžÎKÉÇ‘••…*Uª|u:---xzz¢W¯^¸pá\\\˜˜ÈKѶmÛ`gg÷ÕiTUUѪU+Ì;ñññ0`bcc^"//Q£F!44ÊÊʘ5kÛXDmW¹re¬[·µk×ÆÔ©S1þ|î¼999T®\Ë–-CÇŽܹs‡º4œ9saaaèÖ­Û½¾yóæH$ÈË˃££#Þ¾}˵XJœÑ¤Ièèè|÷kõôô0pà@ < ƒ  U rrrpäÈôéÓç‡^ߢE ¬Y³oÞ¼­­-Þ½{ÇPeÐãÇQ³fÍ"M«¬¬Œ-ZÀËË ñññppp@xx8C8::¢}ûöpwwÇñãÇ‘Í`JXZZ´´´Š<žƒªª*.\ˆyóæáÒ¥K˜?>wN—1Õ«W‡µµ5¦M›†E‹aôèÑHMMe0" ­­Áƒ#$$õëׇ››nܸÜÜ\†#5‚³³37nŒÑ£GÃÃÃ>|Ê{•È qW®\)ÅùäÉ“066.õSSSáææöSó¨Q£ìíí¡§§‡Î;ãСC¨Zµ*×àbVµjUtìØñ§æÑ­[7´k×VVV——Ç!Cl1Û¾}; ôSóÐÓÓƒ‹‹ ŒŒŒÐ¹sg>|•+Wf¸Þ¼yƒÅ‹ö_¥!;;òòòß=š°¡¡!æÌ™ƒŒŒ XZZ"!!“'OfY‚Ž=úC;¤ûõë‡~ýúaóæÍ˜;w.Ž9Z‚Û\… ¾{ð7cccãÅ‹èÕ«æÎûÃ$Ê뎑€€ÀíÛ·er544°k×.œ?›6mBÕªU1qâD6žT¨PƒÆàÁƒ1}út¤¦¦bÒ¤I033c82NII©°í6nÜ___tèÐ:u*Ö÷)‘#èMš4››ÜÜÜ`jj*_ºt ¿ÿþ{±Ì«{÷î8zô(ÂÂÂÁµ·aìØ±ÅÖ!:túúúèÒ¥ ÷8³„„4mÚ´Xæeii‰ÈÈH¸»»cáÂ… ] ðw?:`À€RY†÷ïßCNNî‡o÷£¥¥…¨¨(´lÙƒ *ÜqKÒwìØ±Â[þˆ!C† ""vvvðööfÿ):::ˆŽŽFnn.,--ñüùs†RUªT)ìoô¬°’bjj ‰D‚îÝ»£M›6 åh"âíí ???„……aÓ¦MÈÌÌd("aooiÓ¦!##VVV8|ø°¸ teeehjjBSSS&ö¼¯[·Åz MMMØÛÛcÿþýX°`×Úb îÝ»ƒb›§ªª*:tèWWW8::âÑ£G ºaôèÑžM-Y²999 ]Ãöw?*æ{ªV¨P½zõ²eË…M›6áÞ½{l`'''MMM¬]» 4€Ξ=‹üü|†#‚m®gÏžðóóÃúõë±mÛ6†RÆú[%%%aÛ¶mxöììííy9‘H(**¢^½z Âþóxxx`íÚµxòä Ã555ôíÛÞÞÞØ½{7¶mÛV,µE¹»]|8Ö¬YƒM›6áÕ«Wl”"HLL„‰‰ ƒ(‡Þ¾} uuõ{¿Ê•+£OŸ>X¹r%^¾|‰‰'âüùó<õ]$Ú¶m‹°°0´nÝ“'OFll,²³³ŒÔ«WNNN——/Ÿzi]þo6lˆvíÚÁËË /^äú·nÝBÆ efyÆ­[·ÂÙÙ™óW®\Á¯¿þÊ ¨DµiÓQQQ¸wïpéÒ%†ò ÷îÝC½zõJu*V¬ˆ-[¶ÀÄÄ–––X¼x1æ^¼xjÕª1*1***èׯ&Nœˆ8991‘PPP@¿~ýpôèQ¤¤¤ÀÏÏ‘‘‘ F¤J¤@‹‹ƒ‹‹ \\\Jíö+7oÞ„±±±L…ß°aC888`ìØ±,Òÿ!%%2µL>>>¨W¯† AØH®_¿Ž&Mš0ˆ’™™YØ®\¹²Üç±zõjÌž=cÇŽe‘."¿ÿþ;Nœ8·oßbäÈ‘ „dÒóçÏ ûÛuëÖ•»Ïobb‚ÀÀ@,Y²...X»v-^¿~ÍC$ììì0uêTìÝ»]»vÅóçÏ ôϵlÙþþþð÷÷G×®]K僾yóššš2×ؾ}{áéDåÝãÇQ³fMÙÛPäåáî bâĉÚW¿~}lÚ´ nnnˆ-×+dDD¬­­erÙ”••1{öltíÚ+V¬(÷פ'%%ÉÜY)Tþèëëcøðáyòd\½z–––ÜH$ 1jÔ(´nÝ .ÄÁƒ ‘ ÒÖÖ†½½=>Œ={ö`öìÙ¸~ý:ƒ‰¶mÛâÏ?ÿD¥J•ЧO\¹r…¡°@/]~~~˜>}ºÌ/§±±1ìììÊkÒeœ££#”••áëëË0¨\xúô)tuuezuuu1{öl¸»»ÃÆÆ+V¬`ÉÄÀ!‘HpèÐ!âÉ“' …HFM™2C† Á¢E‹0xðàÏnE²kâĉ8yò$Ο?ÄÄÄ0è¥#??ŠŠŠ¢XÖ:uê`éÒ¥¸qãF¹Ü»•ššŠºuëŠbY'L˜€‘#GÂß߿ܭ[µjÆÏ”dŽœœ¬­­±mÛ6$%%!44©©© FTUUˆêÕ«ÃÉɉצÉ0¬[·³fÍ‚««+öîÝ‹´´4#ÊÊÊ=z4æÍ›‡ 6`È!<í:}‹‚‚†ŽøøørW¤çææBYYY4Ë«««‹^½zaÆŒ媭^¾|ÉÛÿLÓÒÒB`` j×®±cÇâÎ;¼oºHôïß3gÎDpp06oÞŒüü|†B$ƒ”””ФI,_¾=˜1cÊßERk4iÒaaaprrBpp0vìØW¯^1èô5öööHHH€§§'ÃapqqAxx8Ξ=Ë@ˆdHÇŽqäÈÌ›7ÞÞÞ D$ÌḬ̀yóf4hÐ3gÎDJJ C!’a&LÀúõëñòåKtéÒ…GÓE¤C‡øïÿ ===tïÞ«V­b(,Ð¥+++ ïß¿‡ŽŽŽ(—Ĉ¨W¯^¹8ÎÝÝ‹/m‘>aÂ8;;—ùvJOO‡ ¨R¥ {PØÙÙÁÔÔ”ƒãˆHË–-áíí 6ÀÉɉÉ0---¸¹¹áüùó˜1c\\\˜˜È`D¢mÛ¶8wî222°páB~W²@§#''‡aÆáúõëððð(›x IDATÓŸ5?? ¢]~===ìß¿ÖÖÖtƒHÖ¾ìäåѰaCìÞ½ prrâm½DBII ³fÍÂĉÑ«W¯rs¦Rtt4:wîÌ€D¹Í._¾666X°`ÆÏ;kˆ¨í$ ììì'''Þ]Šzñ ÃСCEýþ¾&ÝÀÀÓ¦MûwïÊ\;=þ:::““õçÐÓÓÃÒ¥KáååÅ"HÕ¬Y#GŽ„µµ5fÏžÍÛz‰„ªª*~ùå,]ºóæÍƒ››[™ßÁ’••…J•*±ñI”ÔÕÕÑ¡C„††ÂÂÂsæÌÁ‰'••ÅpD@__ööö°¶¶†——ƇÌÌLýxܺu ÆÆÆeâ³ØÛÛCSSŽŽŽe®²³³Q¡BÑèÀ_§»C"‘àܹsìeˆd¥¥%\]]qóæMîL###>|ººº>|8!’qrrrèÕ«,X€ëׯ£o߾ؿ?ƒÑwåÞ½{aii‰¥K—"<<œ¡”©Þ{lÓ¦M¸|ùò'={M›6eò?H"‘`åÊ•°¶¶ÆÎ;¡¤¤ÄPdPýúõŽ^½z!00­[·.3ŸmîܹXºt)¹„ÄÆÆbÛ¶mŸ<öðáCS ôõõáîîŽ={ö`öìÙhÞ¼9z÷îÍ`DÀÍÍ cÇŽ…‹‹ ,--ѽ{w†B?íĉؽ{÷'q€Ââ3nÜ88::ÂÝÝ)))èß¿?jÖ¬É`D W¯^°²²Â™3gжm[Œ3Æ c0b,ÐGŒ#F|V`¾xñ¢D>ÜÍ›7ѨQ£2Õ`rrr7nrssáää„€€ž'£jÖ¬‰}ûöaÀ€ðõõEÇŽËÄçòò¾¢¤´jÕ ­Zµúä±èèhØÛÛ3œbÒ·o_têÔ cÆŒÁ;wпÔ©S‡ÁÈøw¡ºº:üýýqèÐ!ØÚÚbùòåÐÕÕe8ôÃ:tè€:|òؾ}û ‘HN1m·***X±bRRRØÙÙ¡Aƒ HÆÉËË£]»v Ú5k„:”¹ZK&².Ë.''ªªªeîs)**ÂÍÍ uëÖÅÔ©SËÄ5é{÷îEŸ>}Ê\[éëëcË–-¸víZ™8öÎ;022bÏIeÎß÷M×ÑÑÁàÁƒKlG2ý¼ðÚtOOO8p€¡°@ÿw»wï†M™oÄñãÇcÑ¢E?~¼(o_qæÌ´iÓ¦\lpžžž¸ÿ¾h÷—ÕKˆ¾dÖ¬Y6l.\¸€Ã‡#;;›¡ˆ€©©)æÌ™ƒÔÔTâÚµk …Häää0bĬX±;vìÀ¶mÛðøñc#’¶ëß¿?¦L™‚ oß¾ÜÉÂýËÞ¼y 2ßˆŠŠŠ022Bÿþý±yófÑÝ6;;jjjåbƒ«^½: „äädQé¼//•7zzzpttĉ'0jÔ(þà‰ *ÀËË ]»vÅÔ©Sqîܹ2ßt¢2Q˜ÈËÃÈÈëׯG½zõŠ€€<{öŒáˆ€––‚‚‚ ‘H°cÇlܸOŸ>e0,ÐÿfÍš•«ÆìÖ­zõê…Õ«WCÑ,wy¹FòŸììì ‹t1µQyåççxyyáÔ©SÜnE¢Aƒ8r䢢¢àääÄv#‘V­ZÁÕÕrrr°²²â-^E¤E‹X¿~=š5k†M›6Á××—ý/ tàîÝ»044,w ª¯¯Q£F¡yóæÈËËÅ2§¦¦–Ùâ¾U¤ß¸q³gÏfOD$uëÖÅ™3gðôéS˜››ãÍ›7 E$fÍš….]º E‹< ‚HDTTTàììŒK—.|||Ç`Dâ×_ÅŒ3 ¡¡ßÿgΜa(å¹@/Ï*W®Œ£GÂÖÖÉÉÉ D†17ưaÞž.ÓËzàÀôìÙ“FåÞ€ 7773‘ppp@dd$¶lÙ‚âùóç2»¬<@­ZµØhDÿàêêŠAƒaåÊ•>|8Ý‘ & 22?†··7N:ÅPX —?U«V…¿¿?V¬Xýû÷3YÝåå1xð`4mÚ“'O–é#roß¾…ºº:Ê=999Ô¯_ÞÞÞ¨\¹2†Š—/_2‘|7†††ÂÅÅ;vìÀ­[·dò´ËÈÈHôèу Fô? Š‘#GbéÒ¥8xð ^½zÅ`D Zµj8p F…U«Vaذa¸uëïBUž ôòzŠû?ÕªU nnnX¸p!¢¢¢drO:…¶mÛ–û ÑÝÝÍš5È#PPP “ËX–ïUOô#tttЯ_?Œ5 kÖ¬ÁºuëxH˜™™aäÈ‘8vì\\\8ˆ‘Ș››cçÎPTTÄÊ•+±yóf™ýýDŸª^½:¶mÛ{{{LŸ>kÖ¬aÛýÅ’x“7n^ó‡ºuëJý=Ÿ>} ]]ÝrßÀµjÕBDDºvíŠÅ‹ÃÜÜ\¦–ïúõëèС·DS¦L††,--UUU™Z¾gÏž¡Fl¨Ròöí[¬[·À_; IvtìØ;vİaÀ±cÇ–»/ŨR¥J˜0aΜ9S¸£ÅÁÁÁÒÓÓRø;…dW÷îÝѽ{w̘1fff +÷èÄÂÜÜæææˆ‡D"AíÚµ1~üxƒ:‚^»vmX[[ÃÚÚ 4úûñèù§ªV­ŠcÇŽaãÆˆ‰‰‘¹¢ƒ§MÿöööX½z5V¯^ŒŒ ™Y®;wîÀÈȈ TŠ*T¨PØš™™1„ÁƒÃßßû÷ïLJŠ˜™™aÇŽ¸~ý:ÜÝÝ‘˜˜ÈPÊ9uuõÂþÖÔÔ”ˆ€ŸŸÂÃÃqøða¬X±W¯^e("ѬY3xyy!##¼>½¤ tuuuÔ«WõêÕƒ–––Ôß/<<ýúõãÿUªTAXX233eªHøð!Âùç)/zõêaРAغu«Ì\“¾}ûvØÚÚ²J‘‚‚Ba?ZÒg2¼yól„o¨X±"ÌÌÌ„S§N! ÙÙÙ¥ºLïÞ½ƒššçôõõ1þ|tïÞ¸|ù2C)Ç””” ûÛêÕ«3‘¨Y³&œÑ£G̘1®®®<ãL$”••!‘Hˆäädx{{ãöíÛ,ÐËŠÜÜ\¼ÿ¾Dvˆ‘µµ5222àììŒüüüR]–Ý»wÃÆÆ†òºººèׯ.\ˆ0*UÁÿû(((`áÂ…°±±——Ξ=[jýmll,Z·nÍF)‚ * k׮ذa¢££1oÞ<^Iþºlòĉ¥þ»‰ŠÆÈȇ‚©©)F…cÇŽ•XÛÝ»w¯D.å-« 0räHŒ=cÇŽÅĉ‘••UbÛ¹¬\]æ ô?"77—G ¾¢oß¾èÔ©:uê„ÌÌÌR[ŽsçÎñ‡ãWT¯^3fÌ€··7öîÝ[jË‘››‹üü|T¨PBôêׯ???ܽ{=zôÀû÷˜˜ÀÝÝcÇŽ…··7Ž?ÎPÊ9999ìÙ³]»v-±b~ž­­-Ž?Ž÷ïßcîܹصk—ÔßóÅ‹<ë¢èèè ::½zõÂÂ… ±mÛ6©¿çëׯQ¥JèTzlll0jÔ(Œ9’·’aêêê8|ø0ñÇ”Ê2äääàãÇ+€è :ÁÁÁprrBhh(‰jÕªa„ HOOÇöíÛù]YŽÕ¨QË–-ÃÆáçç‡M›6áþýû F$zõê…©S§âäÉ“°²²BJJ C‰¿¬[·.ºw{÷–‹Û²•¹=88£Fâ]LJ¥¥%Ƈׯ_—è{¿xñ•+W†¢¢"â´´´°iÓ&DDDàðáÃ%þþ7n„½½=BƼxñ+V¬àm½ÄðE+/:uê`ñâŨX±"† ÆbO$ªT©‚¾}û¢V­Z(¼“•?rrr¨S§¼½½Q¥J¸ººÂÏÏ>d8"P©R%øûûÃÇÇû÷ïÇÚµk¹“E$*V¬ˆÖ­[cÉ’%8qâFŒQæ’+Sº HIIAýúõ¹6ÑèÑ£aoo€€„‡‡—Øûþ=p‘¼]$š6m ´iÓƒ†§§'ÛN$LLL°téRÌž=/^ĬY³ÊìÝRÊTu”˜˜È{Ïþ+++xxxàÚµkˆˆˆ(‘÷\¾|9&OžÌð¿“……zöì‰nݺ•ȸøøx4kÖŒÁË uuu899ÁÎÎAAA<²'"={öÄ™3gðàÁøùù!))‰¡ˆ@åÊ•qôèQ 8ÖÖÖ…÷ɦòIQQNNNˆEtt4|||púôi#¢bïìÙ³¨]»6¼½½eî6Äôï6lˆ)S¦`Ú´ièС|||ÊÜYieª@ß¶mÌ5÷(((ÀÝÝaaa b 2^¤Ož<öööxòä )çZ·nY³fáÉ“'X±bŠý=^¿~Ê•+3ìb6wî\˜››# {öì)öëêîÞ½ CCC]Ì:tè€]»váòå˘6m®_¿^ìïÁ[ŠËøñãáèèˆàà`ØÚÚ–øeƒôãáììŒÌÌLôïßÇŽc("¡¡¡ÈÈHbÙ²e8rä tYôîÝ;T¬X‘kìªT©Ö¬Y]]] 4Ïž=“Êû\¹r…GeRÿþýáéé‰õë×cùòåR;MöÈ‘#èÑ£—qªªªðôô„…….^¼ˆÓ§OëHÃwîÜAƒ ´˜ššÂßßgÏžE```±^´ÿ~ôêÕ‹!K®®.|}}Ñ¥KLŸ>çÏŸÇ»wïŠmþ<@íÚµ´ˆèéé!$$“&M*ÜéÆK!Ä¡råʰ¶¶†»»;6oÞ [[[<}ú”Áˆ€¦¦&ˆiÓ¦¡  Ä•+WDê{©è?~,ö{‹^¹r¿þú+×ÔŸ¤­­>}úÀÉÉ ½zõ’Ê)#111èÔ©ÃþI-Z´€««+¢¢¢°yóæbߦ.]º„š5k¢F [$ áèèˆ'OžÀ×ב‘‘ E”””°hÑ"XXX`äÈ‘˜>}z¹¥Vì*V¬ˆnݺáÀصkFŽÉ[²ÌÌÌ0gÎ(++£_¿~X·n]±?“t´jÕªp'KHHÖ¬Yƒœœ#ZZZ°´´„››àè舋/Šöó”ÈÚ‰‰‰8xð 66¯^½‚ŸŸú÷ï_lGeNž<É#ÅÈÜÜ‹/F@@ Šmï„„hii¡nݺ ¹˜~ îß¿çÏŸ‡ŸŸXl§´ž{ýúuá¸7nÜø¡yXYYÁÊÊ sçÎ…ŸŸúöí‹F1\033ƒ™™®_¿Ž:ÀÖÖ®®® FLMMajjŠ»wïbÆ ˆŠŠÂ´iÓ '''ªÏQ"GÐ 0tèP :Mš4A‹-бcGŒ5 ·oßþéùß¾}ŠŠŠiº˜uèЉ—/_ÆÌ™3‹ežëÖ­C‹-®:¤víÚÁÑÑwîÜùéùݺu IIIÜ‘"C*T¨PØvíÚõ›ÓkkkÃÏϵjÕÂÒ¥KqôèQ†(C† Á”)S°k×.„††þÐXùùùxòä jÕªÅ@KˆžžþüóOèèè`ذaˆŽŽþ¡ùøøø@"‘0ÐR¤¡¡QØßvìØñ§æåéé‰Ñ£GãèÑ£prrõQ½ò¦I“&…/^ŒØØX†"†††˜7o†ŠÞ½{cõêÕR»tW´ºššjÖ¬‰š5k¢R¥Jþºe‰ŸŸf̘ÿþ÷¿?| ‰ ؽ{7úõëǵQJE¯¯/ºvíŠAƒ!11ñ‡çõôéS(((pGŠ”´k׫V­Â‘#GàááñÃ×ß <<œ÷>—1 …ýhÕªU‹ü:;;;¸¸¸ 77DBBrss‹üúçÏŸ£zõêl€R(‚ƒƒ¡¬¬ ,]ºô»ÇšÈÏχ‚‚Ã,AZZZ°··ÇÔ©S;;»ïþQ˜™™ÉâJ™¢¢âõ·ÿ¦Zµj?~<†Šùóçc„ ÈÈÈ`Ð" ­­ WWWØÚÚ"%%NNN¸víƒÑï¦5kÖ@^^^^^RHW´ú¿iÓ¦ vïÞ—/_ÂÑÑçÏŸÿîBbÓ¦M077çu²R¤®®sssÌœ9Gżyó¾{0œŒŒ ¬[·K–,áiRÔ¤I8;;ÃÀÀ‰qqqÈËËû®y¼yó¹¹¹hÕª-#ªV­Šž={bòäÉX´hV¬X÷ïßéµk×®…““C,%ƒ BHH´´´0eʤ¤¤ðž½"кuk„††bìØ±Ø°a‚‚‚Š´Íedd@]]ÊÊÊ ±ŒQRRBûöínݺaéÒ¥8xð`™½sYS«V-ØÙÙ¡OŸ>˜6mƇ´´4#zzz3f üüüpéÒ%Œ?÷ïß—éïR™Å}íÚµðòò¾}ûàëë[äÁ4V¬Xððp´lÙ’k_ hÚ´)\]]¡££ƒN:áÔ©SEzÝDZjÕ*tèÐŠŠŠ ²ØÛÛcìØ±Ø¸q#lllŠüº-[¶ 00sçÎeˆeP›6m°yófXXXÀÛÛ‹-úêô>|@AAÔÔÔ^)ªX±"°|ùrÀÞÞqqq_}ͱcÇйsg†WÊÚ·o‰D‚´´4têÔ þþþ_>""***<ó¡ŒëÓ§¼¼¼ ¨¨ˆN:aË–- E$¬¬¬pøðaØÚÚ" !!! E$444ààà€¡C‡bêÔ©˜1c ôo©_¿>¼¼¼0räH¸¹¹!44‡þ×é.\ˆK—.aÇŽ\ãJؘ1cpôèQ<þóçÏÇÎ;ñàÁƒ/N›šš {{{4oÞ:t`x%ÈÈÈ+W®ÄÚµkáââ‚°°°¯Þ#òÀHMMÅ”)S^׸qcÌ™3JJJpqqÁ–-[¾xÇ///¸¹¹±@—! .ÄôéÓ±víZØÚÚ~qGixx8nݺ+++&#fÍš…ƒ"77;wFhh(ÒÓÓ?™æåË—Ø»w/&L˜ÀÀʉîÝ»c÷îÝHHH@PPnݺÅPD¢cÇŽH$hÚ´)ÌÍͱsçÎïº|ŒJO›6m†‘#GbòäÉØ¹s'²³³ejåiÝ@ù_H$¼xñÁÁÁ_îÒ¥K ‚šš5jSSSŸ””KKK˜ššrdâRöòåKDFFâàÁƒÐÑÑ”••ñþý{lß¾uëÖEçÎñË/¿0¬RvñâE¡bÅŠhܸqá™'gÏžÅíÛ·aeeSSShjj2, {{{Ü¿¿Xæ‡ÈÈHddd`èС€C‡¡~ýú4h—Q§OŸÆ³gÏpêÔ)´lÙ7Æ£G°uëV,]ºººº IÝ¿»víBbb">|øwwwÄÆÆâøñãèÒ¥ FÍdȾ}û ‘H~j ž¢¸yófáÀ‚ZZZÐ××ç ‘¸}û6BCC‘œœŒÆ£~ýú°³³c0" æÏŸGÁÄÄ***2qYŸÌèÿÛiý}}z«V­`llÌ5JFmݺ¹¹¹PUUå{výúu\¸pÀ_×J6lØ¡”ãýoyyy…§ZZZZBGG‡a‹ÄùóçqóæMèëë£K—. D$Ž?ŽÔÔT@ïÞ½Q¥J†RN ô¿Ýºu ©©©èÞ½;Ù””œ|7nÜøê4¹¹¹ ‚‹‹ ž>}ÊЈˆ~Àž={pïÞ½¯NóáÃÀÅÅééé ˆÄS ‡……a×®]_}qNN–,YØÛÛÃßߟ‰ýŸãÇcóæÍHKKûêt6l@ûöíáïï°°0ûÝšžžÎþ–ˆ¤fÔ¨Q““ûÿú‰'°{÷îÂ:vìX¤”EaddOKKKñcÇðÇ|òøëׯ‘ŸŸ_ØI—Û·o£AƒÅ:Ï;wî ~ýú———ùe•Æ<ß¼yƒwïÞAWW·Øæùþý{¤¥¥¡V­ZÅ6Ï?âÁƒ000(ÖÏÿèÑ#T©RjjjÅ6ÏçÏŸCUUšššårúÚ|ëÔ©#óú³gÏàëë[ø·®®.f̘¾}û"<<ü§æ­££ƒÖ­[ò˜¶¶6âãã?ëG¥µ~þ½Ýggg£F¢XŸž={555hhhë|ß½{‡ôôôÂ(bÞ¶~ƇðôéSÔ­[·\ç÷ïßG5 ¢¢"úŒEQ ‡……áâÅ‹€ºuëbÊ”)°´´DHHÈOÍWWW÷³þV]]III_ìoSSS¡««[ìmÿúõk@[[»Xç+­ßEbÜn¥õ])Íe~øð!´µµQ¡B…boff&rrrP½zõboAA’““addTî×·'Ož@CCêêê_|ÞÁÁ ÿÿá+&MšôÙc™™™ÂË—/A„¬¬,ÁÃÃCøøñ£ðáÃÁÝÝ]øQÇŽöîÝ+·/}†Ÿåêê*äææŠbY¥1Ï‹/ ›6m*Öy¦¤¤Ë–-+ÖyfddÅþùW®\)ܺu«Xç¹uëVáܹsåv’æ|KÛÎ;…'N|ò؇„‡þ=cÆ áÝ»w‚ ºuë„«W¯þðû­X±B¸}ûv±ŽØØXaóæÍ¢i÷ÐÐPáÂ… Å>ߤ¤$!00PTÛ€4æûôéSÁÇǧÜç ‚àçç'<~ü˜}­ ظq£pùòåO{ÿþý'í3}út!;;[AX¾|¹œœüÃïçãã#<}ú´Ø?‡´~gff ³fÍâv+B@@€T¾+¥¹ÌË–-û©õõßœ9sFøãV»'Q £IDAT?Š}¾¹¹¹‚««+×7A‚ƒƒ…„„„"OÿÅSܯ_¿Žœ>}S§N…‰‰ FŒXµj._¾Œ;v@]]–––H$PPP€½½=ÏQ "Â_§¸K$ܾ}jjj8zô(æÏŸ¸zõ*ºvíZ8@ѤI“àë닜œtêÔ ÿùÏ Q½}ûsçÎEbb"bbb`hh@ll,†ŽÆooo|øð=zôÊÑd"¢Ÿ!'‚ð¿àãÇ…ËËËCQñ¯Z>??‚ þ üu-ºœœ”””~xA ß«8¹¸¸ûàuùùùŸž† Ãó•Æ<A€ ÅÚV÷îÝÃÞ½{1yòdQd*//ÿɵ"?«  rrrÅ:Oi}~ilSÒÜ®JSnnî'+++nCyyy…zXPPðÉc²²~Àùóçq÷î] 2Dí.­mJˆæ;@ZÛ¬sæ|¥±Í±¯ý¾õ1//ï‹ýmAAòóó?ù*ëýmTTÞ½{‡Þ½{sûÙv+ímWË,ßõb]/¤Õvßû›ä‹GÐåååÿµÓúR?ÛÁI£0—&i}±Ic¾Ò˜§4~ôŠ©­¤1Oi­ÿbúVÖ~0~­o”““ûì¹îô,O9Jky¥µMÉÉɉê;@ZĘÛ­ìöµ_êSÿÙüoP^û[n_l»’þ]Ïöû±ß$ sæÌ™ƒ2¬V­ZŸ TG²GEE5kÖDåÊ•·)’A+V„žž^±ºFÜf‰íFŸªT©ôôôþu@)â¶Ke»í¾xŠ»˜„‡‡ãܹsððð€––Ö7§ˆˆ(¡Ôßß¿ðš$ooo¨ªªrͤroÇŽ8þ<<==ÿµ‹ŒŒÄÑ£G ÿîÑ£ºvíúÙ6FâñäÉ,Y²;w.Ò­ŠRSS‘‘‘fÍš!..Û·oXYYÁÜÜœ}òeË™™‰¯'Ù¸q# ÿvttDãÆÙ׊ܽ{÷°råJXZZ¢sçÎßœþÖ­[(((@£FpêÔ)DDDlll`ffÆ@‰ŠhÏž=8}ú4$ ªV­úÅibbbpàÀ¿ÿù»¨Äú]±Ž|òäI!//OX¸p¡ðèÑ£¯N¿eË¡uëÖ…ÿ?w—'äåå “'OˆÊ»íÛ· §OŸòòò„ Ož<ùâtsæÌž?^¸ýäçç ‚ ›6mÚµkÇ E&99Yòòò„Ç ‡úæHæÃ† +õÕÅÅ¥p]øçÉDôeK–,îÝ»'¼~ýZðòòú×;Ã8;;n[yyyBAA ‚àíí- <˜AŠÐÍ›7…Õ«W yyyBDD„õÕé¯]»& 0@8xð`á(Ó¯eyD~¢â¶{÷n!::ZÈËË–,Y"ŒÓŒ“ŽÎÍᥡüýüA¿Éïk7gÎásï=sÏ=—svíÚÅž={$ÈÓÓÓC~~>J)>ÎÔÔ6›-j_KÇCff&IIIßœåå󇇇™ŸŸ'55uÅ•ü„XkVº¦Ün7YYYÆnn·]×Y·nv»ééiÆÆÆŒú)))dddH 1"344„Õj%--Í(÷ûý,,,™™UnnŽH$‚Åb1޽R ›Í&a ± ÃÃÃD"‘¨k&‰àñxÈÍÍ%..Îø `6›ÉÎÎÆçóŒ6ééé«ÚÅFüÌÍÍáõzIKKÃjµå>ŸÏŸ?÷ß …€¯Û]ƒA&&&X¿~=š¦I˜BüÇAz0$''‡øøx£|``€ŒŒ c²Öãñ‰D0™LìØ±ƒ™™FGGú‹å»û"  !„B!„“D „B!„Büy_#ϯ=ûdIEND®B`‚snd-16.1/pix/soundbox.png0000644000076400007640000002540511147553271013516 0ustar bilbil‰PNG  IHDRMÓµ»¡bKGDÿÿÿ ½§“ pHYsŒ…8÷™ÝtIMEÓnTgî IDATxœíÝ¿‹&GšàñìC¢,©$ÎÜiÚ‘Ó Ã¾‚³FcÜ ë3,ÒÂ5½Æ2æ¸e¬kC†@V%Îè—6±Æ@ÿrºr»XA±Î=ëOI ¦é:ꌔ‚œˆÈÈ'##"#žø~¢:ß|3ã‰üñdÄ›yã›×ß (õŸ’,åÁg’,€!]ZyðÙƒ7Æ¿¾zõÕöÅ%Y£iåéçO‡Tí9êDžhFžhö†;iìÐŒýE\iå¿þ…5寸\Áô·¾§Ÿ?ýä·Ÿl+;°ÒÙàmϹ³.S#÷[\9"ú+ît~ŸhFžh6Ûo ¹O?þÝåïö.ОŸŸü|î£Å¾Mò Þ|öôó§î ––å<·%‹à5M.Y³‰¨=Eõ>>ýxücì{&lj¦‹ÒÌ`jL.¹³ ý–@¼éïmæoëkž½Š tK”çèðš6ÝL2ãN@¨LrYÎs_½úŠþI`ŽÕ† T,¹ðüoúã}’@ø}ˆ7Mosí9R Dt''yØÄJoÓò‹Ê–NNú-š‘çš½1 ÃϸDô„òø`N™´â~å‡÷¬Zþßÿùní¢Ø×·ß²¦<øìÁ÷¡X/`}ð·ÿ£X±Øîüü›ÿzûç+Þ'> ÃáðÓÜÅ`»ãñ÷sq @3ò@3ò@3ò@3ò@3ò@3ò@3ò@³­ïå¹qÃde†ëëﬦS¬/º¥²X6kfI±–ÍZxá„YU—¤ûF ‡ÅSYà‹ãÎ Þ?.åܧãto*J(º_nÅvÌÑ;nxN2£L Ño Ð,ïûÄãZ¦9:ÍÂkq›/áéÛ[Ü××ßM›>ÞNKïòç*gK#Ln\¦·ê•ÑÜf*³“Ø"â8 øqä¹@"Z¦iÏ׳äâIÓ-¶™žû¬:W€2É,Ì­ºñŸáʉ‹hn]5Ô€ÑÜ~ËOwÓu„ì¿ÏíKX6ëò¡i¹Ïø%7·|]5ï„€nsý^©¸]Þ~Ë8jRN˜éº\•™:©œ0÷º„<T¨’óUyŽsV•3¢ß¨_%G%÷[Æ‹ŽJ®V ÷'Ü«H>g¾2hNò¼Ðý–î3Âs¥í’š»—ĽŸgúÏ@±­™7^­ÌuZFTÎtQkûB½¥ò®ÅýTX9i77ý–@ýÂÇià4[Ýý–q‰G´Êª²Yµ¼eÉ«îN\»êU!D”j˧¹Ó ‰èãtËIf-ú-š‘çšmê· ÿZ¸oÏe‹SsÙT%Çé"ÇIfSž«ù¬GÙâÔ\6UiåtA¿%@3ò@3ò@3ò@3ò@³Ðý–ÇãïK€,fÛsççß”,9øÛs·nݼuëfÙ’°É žGúø} y Ù¸_§§7‹лËËæïÇ¿ñîÝŸÒž4ìþýß„gãü»ÿý(EaðøøŸþÑ;ýƒ~6ýç;ï_\<·¦,.œö`O?ýëƒd¶1¥={öõÚå¯x/Ï?ü÷{k—@À7ÿzž{´çµs¯^ýyXߤ#Ï4#Ϫ6m̬jÒ‘çš‘çõš6æFk›t%òÜ[oÞ(° ;' ÞŠç â¼õæï^_瘹iI"ÏÑ™jÌ*aÖuíè»××ýìu@sÆÆÜÙÙCï§Ïž}-yN<{žC>%ÏÎ%×Eâ`Ì%9¹¼yŽêG“¨ÖÅÅskè¯iòÜÚN-ëGë‹ÓOÝ®3÷#÷$%T`È_P·C{Î=‡æ;C–\²b$/OÂ’ÈyŒ}î·LÛI1ê¤# ­Kóœø[oÞ˜ës§gºÌwï¿Xœ?G1Ö®ºÎç” —*°º„%™[”š ^Íô[†û÷¬[’,Pò‘puÞo-®+̺5qûO¤s%Œ[W\õº3È¿µXŒU—AÔÈ~Š7ÈïÞ¢w'‹pá?§JµýÖ›¸:”/0¢æ“|˜!ǺhÌê•ß’óö²Ø€cçÔcÜ/hæöÇîX» ÏA9rйdý–ü¯€>ÉÆ·\|,î=/ûÞ&°v€á  $ãoI1Xå°ænUhÅný–%O¦qçná(YÓ{î%O|ËŸ^+x—#É£¤4=HÐo©òt7pó–ùS-J¾ ïódš[ äwMïÌÞ¡F@±ªŸ+¨¹ÍͲ¡³â’\x,®á5í9=¨:ÏÉU’i#м |”vH0ïïs¤:º5“çÂ[T~²Ü6)¹E-Áý–þ´·V¾+Çýºµ(ó_܇Í-?ùדg¬í üÎy ü<hT®öÜ´OÌí›{ÏKà)7_Î}kðµöÖÞoéþíýÎZ`ò¡ç]BîCЛdïå ¿|GÞÍ87gø¡éÅSvÂû-å…ß¾„À-*qËJc€>ÉÆ·äü¨€>­Þ‡2pR¤Ìs¹ó‰ °VÊ<7øù$û}€ ‘皑皥Éso½y£’&˜¢=Ð,Ùx(I–@Z´çš‘çšq @3Ús͸ í9€fYÞW`½%€½¤_õ ß y y y y y y y y y y y y y y y YÊ÷¬ÜãÇ_lù:í9@½ÎÎn\í9@¥..žðÁÏ6.„<¨Ô;ïo_ý–€öœ=viÒžTêââùؤ{õêÏÓéã)Â.MÚsÍÈs€z]\<†áää3eUcn Ït#Ϫ6mÒ­mÌ ä9€nä9@íÆ&]DcnXõ\Á7ÿz¾jÑìNÚžûé_²–€€±I1 ˜¨=÷ñ?ýãê°5îWÜ0`ü>¨Ñýû¿I²œ…öÜåå‹$«@îîÝ­±¾¢ÑžhFžhFžh¶ðûÜøP¹Ý½ûaŽÅÒžì/ÕÝ•.ÑósçòƧÌ«ð˜2 b|ÐÛ+k‰oÏݹóþX2á›Ë½™&“5 [1¾¥1-¨•äR=îh÷Ŷ]rëòÜ4ÑÒrcÖ_#W2ÛIó°]ùl'Ês&É‘áÛÙÄtlfýÝN”ç..ž?{öµùg¦G˜þtñªU¤ý–c9Æl7–lX«d†­»ÅÍvH”Ïp£˜ç ¦ÙÎBò¸ÌCh%3Ü(&ÏÜlÇã€9 ÷úõ.ðÍ7ÿ¯d¶u÷[†?Ê7: iÉħŸ~úÉ'ÿS2çrž#{ ûãÿøôøƒ|Q y.á›Ë(÷ò4#Ï4ó÷[òx`ÿ÷w…sº©ê¿Ýÿ;w6žãÞÀ../¿Î馪þÝÍŸç¸÷°éósžTuâ™ß皑皑çšÅo @&«F< å93¤x‰é§Ÿ~*YÂãÇ_HÞ„J{PÚýû¿™»±ÿ_þåñ_ýÕÙ¸©yîŸÿùÉgÀëêêåâ<ÖK|îÜyÿââ¹5E¸:îCTmLiÞ—{Kçš‘çõsãïpqMºÈûPÎÏÏã¾X¡Ãá°8ñ¶K¯Kw èŽÎE¼µ¹}û½’«ë½=Wÿ‘ñöFw èŽÎÕ[¼Ã_6æÆG"št›ž+¸uëÝ-_ßÝ“'_®šŸxÛ²6^—îЋx»Õ{{P§icnפ#ÏJœžÞÜ»@Ðãôôæå勽K$06æÎÎz?}öìkž47ÑÈpÐg.É­E{¨ýèÙÅÅskè¯hä9@ËË4ì ƒ¼[rý–@§§7Çÿ¢¿.OWä6ôfU—&í9 —±uµw)€†y_»³ö•¨´ç€ô66°Ì×É”Àvä9 £ò‰ŠLãíœßÒ]Ÿ ý–j»g½TäM´Â¿–•Y]`w2'µ&v¶À)¸‰òÇw³«˜­énÖµ»“÷J®¶û¡Ès…l<¬ýút‡®gokWm×§…-îN;[àT›ÕÜŠ[!­GVª3ÌÄé‘kõ®[û@U©.ežKr.¨¤^ÂV™ÖÌÛ~úÉ×sì^Ó(Ö­ëó¢az8›¨ç.Þ§Ÿ®:EZ- w™ÅH«µ‹òÖayÖF1Y-mNòž+9d乄½e:v·oNï‘)_ãÆ¿>]]’2üx$XWR˜ò²W’x½×˫ֲj‡Irz’/6¼:a°ÓÔè]l…½‹k›ªæ[ÓÖRÖõ.f˜l «HÖIcã;è]Ôë×߯ZþF òœ fû)¯†Ì¿(¢§Åº¨‰hÏY¯nûõÔ4ÃMSÕ×±e YÕXñþSbÕ³qÏ]ËÏí9ya¼? …ËSá)Î=@vŒÈJZæo÷摵' w ƒo›Ö°)“õ[ÖL1kƒîjµöëÉÏÞ‹nÓã‘j-ÕRŸÎã£pÏmD¿®{¥ŸðÊ,Úªž’Eõ ÖìmÒEìä—¾Ÿå6^ÓgÂ}(…loT­_÷©¹°-ýN Hv§ˆü´˜_sð¶G{8Xæ.­«ØTÝU5ÊÉsjÕ³“éw[@™Õeí;-)ÐUÌj\Îý,ê^lÍ·Ÿä9 £ò|ù5VuF‹ÐzùkSa}2 ÞÆ~Îî_$./_Ô¿‹’ç€\zþI¨ý–@IçX5sm?þ• =ÐŒ<TŠ–„ª~KÉ#>ãmA¼ã¡,Ʋû€ÉIrÒñ ”5€…d‹Oo] ÌV­®öga,nÊ9;vªëÉs‹ƒ2¤ «$w(I,ᱚš#t#b`Ž:õ¶ÅuGç’ÄÒîùÊkßMÖQ¿eë;Ê»»+8HºÕÉ_UÚæ¢ ÐKؾaêiÏÉ5ºoYƒ û4Z¿òíY‡[|ñØl::K8–·šK«»<×h’œAÐ…}:úñúÔÛ—”¹Ýè\‹±L·x™"i¥¹ßòÔyUP£‡‡p/·âUl¸ÛW·¸{ljŠÎâennô¬U=í¹ÅAÇÛ½Íí³’ôbÉ{ºš°¸}…ó4¡·-.96ÛÎ%ŒEÇÎ<Úw»MyîÉ“/ç¹wïÞ–U¬r}}mþ>=&…ÿiH oÙ1ÞihÞ)n¼Ã$äˆ`…ߪgû޼£½ýöO’,'ÂâN pk©äÖœò{n2ìÏåŸÛvÇãÑLÙ¸3׳}'Þ««—%×ßoy~~¾8Ïápˆ^~mˆ×¥)ÞÞ¸ÛW÷Ö ìÏ*ïmû†E¶ç‡Ãb­IN”¹¥º~!^—¦xkˆ%ï)ÏÚ¾­Ô@ÜìÏu¾qÇnwûf¢ù>îù½óS:”ý>”o¿ýSîUT…xÛuëÖ»Ö”Ö£ûå/ÿÆšþ±§õx£ux=ažœ¼Sru´çš‘皑皑皕Ësã¨6Yï©pd ˆ"¹_ñ`Va°CæMPgÈ®£U%߸qK«aÛ½*Þñ­&Êsãp/ãM××*q‘º£üYõæN©Dmå©AÄ(G5ŒóTí>†|jØñ2)4¾åÜ‹OŸZó ? çŽaXç¡8-j`žñ+–Å÷LÎMÙ‘o»Ûwn»˜)Ârº3¾µölæï¬õ掩oþöÖ‰5ÏŽ%³qÓKvõUÕ•›µ5Ãûªû­Àt³ïžóúõ÷)ÃXRzçiØ‹›Ù;}ZYn=&/páŽëÖ€7U¸1îx`xyËÓèöõ™Þcu±œî…Žûõˆ“]îz“ìcq§é:·¸·xáÓt ÀQ¶ç)Ì:/î«î·6®´˜¢yέ¯ðü—¾Q½+ÙEYÝŒáyæXG‘wJ%ÜxlßÀ 7®ÀÞ³|D©²ÖÛ–},üÅú·¸DtÍ$.Ç~#ÃÛ YüÖ ÈdšÛs‹‚é)røËz¬ð"HÂ[loÏÀô£v®y‡–·oî†pÉ»×Û夃qÕêv/ù^äû.Ǿ·¡ñ­ÅÌçÝsÔ¶çLOÈøÏKÙOÜÓ½& oÉëì–ŒÐîöuÛ’2Äm͸oíRoî©Ê[Ká\Xç¬ÚÛ]üÖª%ïï´÷Eræ l⹬æþSg{n®RÂSÂ34Ñïá-pò)õXoµÛ7¢äk¿ˆ®†zs¿ëžÚæŠØªÝânæÒ[¸À¤˜R8^IGo)w,<7=¡ÅÖ[Âo¡ò€ýœ¾ã"í§~Ÿ_Ͳ·çÂï»Ò‡xÛ¥)–8ÝÖ@'׿Gýªäêò¶çz{s1ñ¶KS,qº­Nï$L¯Œí¹Ãáp8ò-¿6ÄÛ.M±Äé¶: ¼¶0¯®^–\¿Ï4#Ï4#Ï4#Ï4#Ï4#Ï4#Ï4‹|~NÓ#‡’ÇJˆ·]Äë"Þvéˆ÷öí÷J®®÷ö\ý;DZÄ«ñêÖ[¼©låÖ­wS•ckG{#Þ¶oñ¶¥·xê½=Ð<ÐŒ<ÐŒ<ÐŒ<ÐŒ<ÐŒ<ÐŒ<ÐŒ<ÐŒ<ÐlÓ¸_€ÊžÞÿ¸¼|±öS™«’7ÏMë%«J*½L¼• (£øøWzzzÓúÃútúÏÑ8ÑL1,æÎªNSiòÜÜþQ,ÔÀš£ ûÆ[8ØU(¬·x®rRèêøK9ãôé§n'Žÿt—ãæNïB¬oÓ_¿þ>*šH ò\ ©;Pw¯ÚXÚÝã]lx~‰ä˜ÊééÍ®âfBNoå8~·¬Úd£¹Ãǻҹ$g>&iÏûéÜ’ËHçLÝf|ñG›»pX,C’x;8WLaÉw#w¯ä̘é€q[I¼£ÜÛW½ÞŽß@IUaµÆ¬–ßð—™Ï»Lmí¹aiÛ¸Ù>Éå?Ÿ&·oÚ`‡¤W ÕP†Â: Y·ž_ÃM`s¿ÏÍ{î§;7)ºë-¬Äý–îžÉ[wÃh…²ã×dïOq£@öf¯Å¾ßÚªŽç @¹T7¿TØ0• Ï€f©ÒRséÍ`<€fä9€fä9€fä9€fä9€fzî·”<6¾ã£åÉ-ÆRÃp;iIîiÞ}T§„$±4zŸ·WWñrü–¤$ÏMð¸¥áyZ!‰%0Ä\‹$Ϩ*ÓÄ"n·~]ÅËñ[xíJú-%×ôaYûh§¦Ø4…©)‰®âåø-LIž3„]jö›ÅX\ Zqü–¡*Ï‘ä\——/hPÇo1J~Ÿ|;÷MHŠ“œûº"5Áz©¹%Aˆx5áøzüø‹í Q’çÂo<’ÏÓ I,û¾º(9É[ÁLµ(ˆW‹¤NZÑU¼¿Bgg“¬}Sž{òäËÅyîÝ»·eB×××Ö”ãñøèÑ£aRÈñŸ†¤ð÷+e¢s¹ñºM QÁÃðöÛ?‰øV>V€n%x«E®žýy˜ßšV!½…V}+wàc¼ÇãÑ:`ËÄ[ø@¿ÇãÑLÙxüÖs¾M£¾ºz¹8ÿÅÅó>øY’UÇÿ>w~~¾8Ïápˆ^~mÜx5EöçâU‹óÕTd{îp8,ÖÚª)“T×/n¼5D'±ï\+ØŸÊž|§ Ä[Ãfum¬vÏW™¨ºßKöûP¾ýöO¹W±#¢ëM·u¢;pÝÑõ„yròNÉÕÑžhFžhFžhFžh¶[žË1b[=£ÀíU’2ëݲ–¸ïºß:=½iMt§”—¶»‡ã5Ös²Õæh®l=lh¯†Š:¥dÜ/èæŽh½Ëª†7“5z XEÓK£õ°¡½Ú ¼\žsÇj[õðáÇÒÜqÒj¨}ItíÖ€U†A‹[N3Cx˜»¹%/¾‹rnJ&nHÆ•¯akn!¬ÞvÔ¤­oèpaÜëEówÂÀ_¿þ~s+Êssµæ~:÷-w¢©ÁJöëokŠ;äÒ¸†ð–A‹õ‡°½µxt¹þºSr‹[W [3•@ ´fÜi*¼wb 5à¤Išék/¦ê~KïˆÝšºJÛs5Ô@ô¸éq^<æÝC¥üÁW'5lÍ$µ­&Ìhõ×€[*ïq·ö°ª6ðºòœÛC•ä*£ZÞkŸ¡¾ÈW·C£ÂË|/IÔ¹57rK®2ÌUZ¯è㮕À å9ož_¼"v /y/’èÜy$m‚j`m»%Ýcû«U6Þ:Y,g [s#ãøOoí†)Þ=¥þ4A’k»1„Â<瞬wèh=)¸¯ "ɵ«ÛÝØ(óvÆzôoIÚ~Ÿ³ÿœû_Áˆ‹oñTêÔÏnlHÞJ£éÍ5Ä[Rš<÷öÛ?I²œí®¯¯%½³-zòäËÅyîÝ»±ä8Ó(ŽÇã£G†I!Ç’Â[ܯ”Œn­ãñ¸q ìÆF`—ØeC[áŒÿ´6«µ“¯RÏöyã ϳJÍÛ÷êêeÉU+ì·Ìäüü|qžÃáP $e¸ñjŠý™ ­Ûw*²='9é7Çåî‡Ãaq稡NR]¦¹ñÖDÍ-Îzöç:74›u•æ¶on´ç~`v‹>÷ÐjÓïs·n½;þñí·JQ˜Ýüò—3þ×ï?ÕzU„]'TV…Ê âì^''ï”\í9€fä9€fä9€fä9€fYòÜÜè5q£Ú¸ßJ;:N¾±vrâÃ(Aej ÷þ¼Ep“›ŽPeþ™pتÊwìðèk ßµ¨|ý´7îW+ûP+å#¦Ž+{ Þ*Þ$§`Œ.}Òä9wœ=kÊôêÏè~kpÞðkf“ŒÎî.Ç]-÷1é–S2a %_dÀ»5Ã%¯¼JîϵìÖnÞp•oV³÷¶‹[Ü[<«r$IN²vï<™h:lä9ïVñ^ôÍm?S)V=ƽÖ;ÿt—²ÖUò”(áÜôJnñ¨‰”®· †IDATÞ’W[ûîÏ5Ô€„UÎp1**¼íVO’\ŲšEÓa¶g¿¥µOL/޶llïrJî=s·nµ%÷š;Ó¹%—‡ÐV X’ìÏMÔÀÚ^aP™2Š0c­ºJ(Ì›±æ>2ÓkÛ¾–=óœ[q×5n/Ð^×GÞË™&Jî5w¦‹XÎÐf ¸âöçæjÀ=GÏ *·*ܬ3Ãå¤ß¯†ºR°}ä9o2÷^\NzlÝoY=¼Þo™ÙOîræÊœ‰UNÉ+)ù"ÚøOïÖtIæ©¡ ïÏ–j`ÊÚã6}UA¹YÄ !<Åãá0çÖîΣ¦Ã6,M{N~iï½Øò-Ér¼_/°­RIÉy Ùš­ÔÀŽûs%50Wž¦7«µÆUg•äSÂkŸ›˜\`K¶KåÛ×ÅsâÍÈsÍÈsÍ6ý>·ýmmú订ë„ʪPTœÝ«â£~Uruñí9Þ»íÒ]'D× •U¡2¨8VEd{îp8‡´Eiî:!ºN¨¬ •AÅ©¤*®®^–\¿Ï4#Ï4#Ï4#Ï4#Ï4#Ï4#Ï4‹|~NÓ“†’§Iˆ·]Äë"Þvéˆ÷öí÷J®®÷ö\ý;DZÄ«ñêÖ[¼©lßòÖ­wS•cky#Þ¶oñ¶¥·xê½=Ð<ÐŒ<ÐŒ<ÐŒ<ÐŒ<ÐŒ<ÐŒ<jžÞÜ»û#Ï4Û4Š%á…Ãåå‹ðŠÂ3âh‚zÉò\ڣś2Çå+ Ì`R]Ì™³Ãm Ï)'mÝy—6]Q`†é¦_ÉQÎ@òép7°ÕHè'í¥iÏ•©©ÅµLg˜ËpI¶ë\>+SlºË.+l[¯j‚[3×p(®“¦'w¢ûQøSïÒ²êç|çUÕ™¶Âtûš3a oÌÌ©cÇHçꬅi©æþ޳û†¬=Gwn¸Ù]Ë8ѽÎXœmºÆðlY¯3Âg=oIÌÉÂú§û‘[àio’5Ïâù7í~XÕé> ùþ\ÏlÌ=ÖÄL×åVÚ›ûb8F{ýúûäË HÓoYÏŽb¸'šTí¹Å o­q;SfÉ—|[x"ÞÔ5ýgôlÖœÂٚ˦á¸ÜOÝËgïZÜD.@u™{ö’cCxO}’³JòSÙ^Òô[–9NkÜûûœµ9“”Sx;hÂã§ž½MX†]fKË»ÒpIŸF|TÃæîA?õlš$g•“¬ßÒ걑4žÜî)·ÇúÛ|KØA—¶ÇRHÒ!%¹'ê~NPÉž+°›ûC…÷+s9lšÿÜþ®®¶GS?ú¼ Oùœøà«ÄUâéO¯wµ…[0îÐ5®¡yÔâ:f Ït#Ï4#Ï4K|¿åŽ„£ÖóÀõF‹ñV8DäF’m§fû]Æ»ñ¶kÇçÁ”ä¹ð#wÞÙš&‰×ã§@©²š>š¹¸}lèã•ÌC¼Ú÷ÔQ¿¥‚}ÅXˆ¦À¡Uo»(ñ–¤¤=ç­â%ìÛlÈbSÐ’€-”ä9a¿¥dž†H¢PÓïq4÷[z_椆›º¬xÇ>Ò½}]Ä«[oñ–¤¤='é·öm6aîeSšâd¯ÂR󺬡¿xÍ.M¼Foñæ³)Ï=yòåâ<÷îÝÛ² ¹ëëëé?Çã£G†¿,ä8e•Üå~«Xt+XïDSCºx]%k` wû?nbâ•|«üŽíîÒã”ãñ8˜$Þ½Û©¹x݉ÇãQÁþlEwuõ²ÌzGñý–ççç‹ó‡èåׯWSt.¶¯«“x5…i˜xUFçêm‹lχÅ:’Ttn©®VÜxkˆN"®ؾ®Nâ­!LׯÀM¼uF'±ªZÙŸ‹Ñ| ÙïCùöÛ?å^ÅŽtG'Ñ[ t¯î0uG·Ê^UqròNÉÕÑžhFžhFžhFžh¶[žË1ÂMm£æ_½Qx%éŽÎ2ŽÛ”°ÕÆk¬ÑÀçÖ’oðøàgòEÕ•çÜfrD+¡Z’Xt×€úè¬tÇkt¸áöÔUÕ(O¥Ýͺgž[lßH~pû*auÌÅîo¨æ~XLêÖ·,•Dç²â5ÁN'Î}en†¡¾x7«²ÀwZIÇŒ7–»%3)°YÇ&ÝÉÉ;¦IјŠå9ÓCmýß;ÛÜ?‡™K‰Ý÷I©Â½:s³µRÞ2,Ni(:—dû*ˆ7b#Jæ©!ðµ‡m œù¦£f³zñœ8 RχÇ}ŽkÌ ä9$QÃ%[IÄÛI˜P<¨×ؤ‹nÌ ~Ÿ{òäËܫؑîè$z«NâÕ¦îèVÙ«*>úèW%W—·=§ûÕ캣“è­:‰Ww˜º£[¥¡ª›tq¹aU{îêêåªEß¾ýÞíÛï­,ObkË,WCtºk _t®Nâ­!LWªÀëŒN"ù¦¯¿*¬q¿¶ &mÏÉGX`‹´GÔž»{÷CkärHžq¸ß y y y y y y ™èù¹qMR¹{÷Ã2+¢=(­ä[o Ãðà³’YchŽ#ï8OU2MÇÞE‡LFÏÉÓÏŸZSÞ†á“ß~bÏøJºDSܳ³‡ÑƒIP†³]&VF{ðÙƒ~ŸûêÕWfêÓÏŸþþ×g‹Ëš&ä³³‡Ó è¿èÃ(Ÿí¬t6ĽgušáHiטNNÞökÛÖå92@®†l·"Ï™$G†ÈYÃth¾cqEž»¸xþìÙ׿ŸÅ}4mú“mù”Öõ[Žå³ÝXn²`ξnsŠ›í˜ª!ÃbòÜhší,$?è™yج†Ç(ãóÜÈÍvÖ³t€ÕáF1÷[†?*9j BU%é8ÎU!Q{îîÝyfÐ"ÞËÐŒ<ÐŒ<ÐŒ<ÐÌÊœ|W¸äàÉs¿øõ/¦ï©“xúùÓO~ûÉÚoà•0­Ðo ÐŒ<ÐŒ<Ðì‡ßçž~þtû²’,€Q’´rã›×ß<øìÁöP¡ÿS°BÅ?\`IEND®B`‚snd-16.1/pix/golden.png0000644000076400007640000001404611147553267013131 0ustar bilbil‰PNG  IHDRx2ňsRGB®Îé pHYsÂÂnÐu>tIMEØ*pß–à¸IDATxÚí{it]Õ•æ>çÜs‡7,ɲ,y¶e˶±Á6˜Á@ $Á@Wh*ªNRÝ¡R@…¨ ¤ª“J*!é 4IŠ„!ÂhÇtÅ ¶Á“ð ϶dMÖø$½ùgê²Á–eë]Öê^«zÕY÷Ç»÷ÝóÎ}ûìáÛßÞ)¥àCxüÿ5€pÏžz6` ÀÀ€Ÿsà€ð,Àð€(1 š·Œëê]ZÐéáÁÇ~ðèýÿƒÿÛ=?4lÔ4ÿýlÕ˜£C ¸ € Ì€v±_zgË{ú†-\42’ñûbÄ#1ŸWLü ¡të@¬¡Â׳7ÐF¨<çtò¹_Œ?^|ñ‡Þ=ÞÝÓ …ü>Ewÿ1@Ê×”Ba„3×ïB#}=~§´u¼ë÷Ùvm~Íï*=GO¤{zϽ2¾Fç³ÙL:]5+(\90”zõwOZ:&ºžI¹"#+ÃÔR.ceñfèÁˆr˜SΧ’˜0‚[›·ØÎˆçaåH)\ÀDÓgÌ „0!’;”]áÅ“–iÓÂ8™æ €ht+p½‚_¸Ÿú,€ù¶iâzÒ˜XÐV08¿q¡ãÚ®t/˜{ËŸŸÈc1Ž©8Ư°VVM™)€u[€RJbÌqPA„m¥ÆiE H˺2=û5·—*Êó[p!gÌ“HëëÉÉœÍ „ B0¥˜ZfagÜî™ó·öœz:—:!çÂé"wóNSª.…í¹®ëUU–c¢#¦Ú±Vã"¬QB)æZG) Àd¬[†o›& ¢ñèÄ‚&„|ý¾{Póî]#]'KðX”ŽªŸ r¼@(zÉ1¨8ûW ~R,˜(³Â1º™K¥º&Mk˜¡@P6VB*¥Ê„’\j!„”RBJ)¥i耊HéуV0‰mÞ š‰¡0bç‘['\¬,Y!—͸Êážg=Yp9ζïØåå˜Ä54ƒ:”²`4L†@µ ÕE’š,Ú¬è –)€T_ß­wLŸXиo)D4ó½ŸH÷;E·,¢iþÂZj(Iˆ’QO˜pF¦ÔÍ1¬jÎl±uÞññT¼ÌjZ}ÓÙsÀS H @bG3½„RŠ É…’S°Ž ³DAH ùŽÐ„o¸¤(Ÿs B0ö„_‡«’‰ŠsNM+8Œ @)ËgÇQÛKŠL‘`Ä?øñžüC;» 4Íò;K£šO )¤½acB.žpL|ûljØÀ'ÈQ/¹TŸgÛþQ‡ð+3ͤ~W¹ðÁ.º½C½žë(ä_КIüNÁ” âÏ gÓõÔ÷BÜóüYš”¦ôýw4Z’ëêúgÿòo¯¾ÐGqBùžcgó~5: i–oƒ†OSSÌór\Û)I£÷í=°¯ýØd$§òÙÛ_{£Š^-±c I\ƒq„(]¹š’\H.“H)Œ‘iê `ˆ¥Ñ`G'5 ubJOц(PR˜Œ³(ÑBþ4º˜+Jß„&0î²S'U×ÕCáÑ[ßysý¬FŸ Jt¢¼lFí æ³¯üØõMëåaX€t]×㊠hR)Ç–’qÁ¸ð$(EBÊT€„‹Nt®™™´UV(Ï2Ï’|ôÔP1"¢™t>èšmÃùáÁüÔP8Wô(Eˆ“Α˧&b ÁŠZÆ$6•FtdQ ª`•’B(!‘€‚®Ž®òª¶`4¤ë&¥: D‘…ˆ¢šEv&€ÎæƒN‘_Z_~öך®œ\3Jò)%U5~·Ó)Š’ÝÔ´(hÒH$vøÀ>Êè(Wb£´ß¥#»[=kÀ¢s/Î;¿¯Âƒ±ŠòÑ+Çšßœ±pÕYeçè,ª¢Ãm;<’qÂT× 9ÝÖÊ·P”“‚F( !šFˆF‘E®é@Òvvºä`8}V#iÙ÷x.\šØóÞÆË¯º5Ž ŒÓ#„Ï,µoÛÎ…W® "ô V=yœéýýÝ3/E'ȧÊ`.L€ÆËܶã¦5.½€ÍÈÚª)•Kô¹ŠÈglÏs÷üóW/_7’é …cEÇfC86ÙÒu IÐ ]7”¦g ¤ áa€@ÜsYÁCGN·,u>'—Ñ£å¾}üpúÔqˆžØøŠë¯G˜Û^ÜtÕçR*Œ·lÚxÍM·€’ÝÝ' r/»|© _b•h$Œ}&˜”|„}B(¥”?H1Î_øåÓ;ßßqÆ\ÓΚ®=tàù6mÛµ@Éù˯xü‰Ÿ:ž3¶ñO×{Ü2Â¥‚Tݘ±|ñ½÷Ý;¿¦z°§{fÓÒÛo¼³·ód)s)µü ¢QŸ8𳋹ŽDEõ‹Ï=wãÇoql[¤YÀky­÷ÔÁº)Õo¿õæª%óÔàÐH¢¬ìcWÜ€aìR˜×s=¿ˆÐÉ炉xé÷×TÌ\0]ßùî{ºLÖ—ïÝó^©°Ð— ó##šO®GrŽ/‚½MÓúü׿4gî¼ýïïúétyÑÒ䤺Y3&ÏX°ÔsœžÿE{[çö㻼߼wã¶KÁ;;'}*5Ö”S,ú&a¬¨¥¬ÐÒ«JÙ]‡É’­”úÍu¶·§²9]÷‡ðm;G­ñ€ F<×¹óöϼüû7N·_¹jí'n¼u ¿¿~ƬdYâg?úAÛ£‡÷ïjš4Å+fãÓ/E×”WRŸJÀc瓱èƒÿ\Hõ—”°]J|—ô¹T$àƒYSR:%f†Oýë¯tÝÚöö[¹ôÐñm{p¾+4µ@I¡H)Ι0xÔv³Œ‘¨ORŒÛyVhíhíjZÐ} <¬»žÃ\J !è)N&5Ï?òlÞÉñòxóö–?»æÖW îHÏPu2|hïÞÝ'7üùÝŸ¾í¶¯ý׿ˆ%n>oÄârŽíú4 ŒeÇ/Únpªí¸®Ïÿúɯþí·û ¯N·¡„VL 8€è| \.PDZæú™óSƒÇ;»t^|ë7ÃåµË-|cã+KW®vÓ|P ˜®áÄóÑÁáÓs¯hx§ùØM‹ë’UÅÂéCÝî®Ý»>ùñkm›i9ÕÝ•Kéè9Úv(`™Ë›(¥ÑpÈ4ͪŠHÀHv°}M7.ÖC1©Oì<Çî>y¤¡q±æ¼çØÞšyKKÂÑõ 3`È€ýùÁlº 5O¤\àg‘¡i0mÞ ¨¨žWQ=¼´ºòæÛ`É•× È™áþÎÖió—^~N0 `Þ¢å ³G|~~8JŒ+(È Ÿê ¾Ï3î‘·Ž¸Û‡3 nrªë:¢ш‹›¦e"D@2- 1âŒçMKرÖÃANÛË!ÐÒn_j( @¦DQuR,¸!…ƒf!ƒ‚5fͼ âÞÅß±ã5)…ò3îÜÚy∯)Šó­›ž»ðò±#Gn¹fÍ·ïû›æ];¤à|ã¿{ž÷£¿¥”:°ïSO>ñ£þÁ¾½ï)¥ùÎC›7núþCßVJmÙüÚæÍ›ÿî›÷tžjóƒï½þú‡?Þ²·¢¬òä¾=ç|/Ï?„R‚Ùvûq)…”b4J Á9gg6öœ ´ïÞþ옥/ ïÈîwö ¥ý‘j.ó˜?VM1¡ãøÊD2± iÎU×­lZ| ”uùëO?ž¬ rkQŽÓ8 ìÚ¾màôÁOÝq'ècË+ð\»º¶nÌZ¡3ÖÙÓÖvº¿û¿Üõ±GøhGgǶvþ0 ¥„D#„ÆcŒ !Ú™C{`¢iÊ\ T®ctt§òápØ—Ô(%DóYÊSœÆ*eå_¿÷Áô`?!?üÝï8¸£iÙZ;=\?gÉâù»®¹qƒ(:ÈBËV®l˜½dRõ¤BjxùåW‹—¯"„\L ö¹ÏÜõ§Í›î»ç›}σ{÷´ìÛ½'a™áòÊñ-—›Yë­<Ïáž¿„">™!¤ô™ÛŽg“ãÛÕ£Ý[6þþ¹çBáð;[¶~÷þûB·‘äûÌg†ï{à!/ŸÍ¤³¯ÿáUMÓcwî9ÙrÀ-äÏ‹Rоö·½ùÇ—ª«ƒ$]yÝu|cÓ Ï<©äø4/ò©7ÔÐåq‚&TÓ¨¿Š™¡QMó§UúEV‰Dcu3¦7.ºüÆ›oFßý• pÝ W#ŒL_Ž'ö5oe¡åk®¥ÀW^½®XZßTûò+¯Pó<ÎAj -^»~Ö²«<æè†¡ëú?ýø'ÕåÃÃCãSøR é¯8+¸p]^’ ñ³Ÿ|î³w´ìß•Ž:¼b¾·­µ»»³P´=»p´yÿPjà@ó®Bfh¢:žÀ©~!¬býËãOƒAˆ…çR™²Iu!j˜hË.I–W€eìhïl€ UFUxÆôÉø|ï¡Cž¬ÿ³/éº9J Ü´þ ɲñ]‡ëzQ¿Ý‡ÔlÏøB¼ùÖ[•W „ ô¿ú»—¦aPŒ ò¸(OFFV ¡ëf8´œ`q€ ¼»í_ýü—k×­.«ãšF x g_ß·î¿oõÊ%wÞq×¢«/žµ;V$r‰àsÿù?}h1!T?·éƒZÉô… ?øjöœÚDõ”³¶Ë®Ë;ç2¦º(Eh·©ˆû 9€TI‚V¿øÑÿ` %be†®ÏY0W'„Œ©–Žm7ÈÈ0%9áˆô'3é[ßœT=ÝÓÜüóÃÅuW§ ¹'ŸyIpVŸhø·ßnÉö¶•—•S*ò¹l21 e¥•4ÁZÓ#çšØuéüBÊ.ÚE‚¥Tó8caèÐGBA¦$p‹W0ÉœòÔ4ˆ&!ÀPÝða6hâV ]í555£eiøîÐHõ ÖÖ7ø¤/y¡PR…}ö/þʱ=òLÓš>{æx÷L†Ñ&¬³V•„y·Ç‚ õ‹ú:;œ\×Ôyk㦫×f³ÙÚÚZ‘éMNàx @2™U !$…ðdwÔ E£–¦” DXD€”@ˆ†…B"ƒiBIJ´k2>HOŸ m„Ö]ÈåìÌ`†Ûž"RŨ0ôt®Z¶ítuô…C'Þ´îæ¶mK:ö±'º‰HD!i{WsÏC„8\i1‡ šF‚µÃÍ-!Z«Šêºn¡€®‡ áLGä¸zŠ 9± ŸyêW«Ö¬9°ó½²èZÇqJßɆiËóX 2e´Z7õLy1í¥Fíà ±Gqôì êd4ZiÃH²´¥ê`FmC|LdÖÙ‘Ö@¨vAëñÖÃ-ë¡ÚZ¯:/Fž¥¤OÓ˜E=Ž16…" O „`ŒcÜ“î •…ô`sQ#ƒˆ;=†Ñm¹v†+•*%ÁE—r%x’#„tL޵žn\>gAò#oo}û·­ÏfÓ---«•\ŠQ¥™œ b•3/…m°Bþ{ð-«¤÷0"ñi,“š=»qÖ¬y/ÿþ_ NZ8 À˜°/dδiU3ëêÎèE îzAW{ë±Ã Ž`0rËÇo~äÑG‡²ÃõÓk)p¿ÿyEìzû­•@鸓FËF™åÙ5S}o§î›VÕ) 'ªº¹\MeòÞ¿ùÆòË–§S”øn׌KŸÀó£õCž«ÆZ àw ã¾Ûý1Áº1QK5éÛwløÔúÓ'ú%6uŸ½—@tì7WB|î;ÿ%‘ÒR}߯ɘ!ß{Œ“ ’±aÅ,¡ákÖ®Îõr™‰G|7·!¡ñYf„2ü3* ù¯œûmŒ0Õµ ‚¡Ð"×~b® ~òDkj$wâpL0± $:¬Qªc@#ÝÔ±a(8Û• ‰A©9n…˜ú8 "¹Rþ…Mu‰¾Àþ—áÒ÷Ï)P2‘  ¹ÜÁC).@ljã§zûßßùj1U,dúÃ!ΙÓîVFùI¯Œtõ#Ê´ Ñh”z6hpˆƒ"†ÏÍB¶]ô\wFe-&hõË<ÅUuDG …;.+Ñø9I¬i@ „™¦]×ÁÑ0Æ”D5åó%ej ÛàSjº怌HlA—WMZûí£Ÿwïxwpöä9ËV?öÓŸÞöÉÛŽ=zªUÝñÉËE"öúÓÿø|/Ë ¦ÓiC7ˆFt]‘á2Ã#ˆ ¾¾ÞÔ`G¯‡ú3G>äc9G$i/—-Ò¸è:ŽÍYÖöl®qÇ%ÙA‹–k!×Ò‚Á‘|¶â<ÆY %‰S¤ºá:®ã:QݪŸRSKTÕW[±ÈŽ#{*›Œ/` ! 2 J4BÁ3P”,ó!hœ—.õŠòŽíÛzZ–UÖ¼»{ïµk×<ûâKŸ¿{CEEåßûÞOßõ^ô®¸ö†1JóÄcÿ´xþB0ÌÆE—éº>ž7ëXs©ŸüäÇ_þê_Çâ‰ܬêk煮R](ä ç1ëC Á0g#='’±Ê¾ÞžþîþáüÅû8¤›AÔ³s9‚3e÷§ìb¿-l¡ˆ’¦ëtªuôö.X¶D †ÌðùöÁ@ y\Ƹë2xr,Q9u’íºùÅ/éV¤TâßóX¤¼¦aÞ¼]û÷ýiËf×å›7m]wý5“*«æÎ¾¬·÷‚æ([*›Ÿn?òÎÞ£·K¶lÅšqøí F¸¬"ˆÜbÑŽÅK2ÿ/~åËÏþæñןûÅUë64ï|oõ Ÿ8[šÐ@£É)Ó“P_V?¦éõå—þ°mÛ»ßûÞwi Ð8;œbÅl¼jŠ]pá³szàÜú¤ôÒÒÉõö÷çò¹ÁÔHçé”í‚TÀ"É5ýTXfÌP‚ó9O8ë×oh=uªcçNQ°ç.húåÃ]ó… Þò´ÈÚ›Ö>r8Õß5©¦ªT,ÄØp:‡KÃÑ˜ÆÆ4èï§»vïnëL½ÿÃxàÁ‡K1…)Õå‰ ìאַ1áí/¿ðøÁ#§>õ©;_{}Ó½÷ܳoß¡¥+Væ;„±žÀz¢62¶ZÖßÝñøÿ|ø¹§Õ§7üy©‚ž<ùL·ì7ÿvÌœ=n¼æÃr¸í®q§L›;sÚÜÆ[.òí¸££­5^7{¨§}RõÄýÞ‚óŽææ/<ÿ•o}ó½w^ÙòvËŠ•«KŒ„ûwn[¾jÕ¤š†v55 §Ñì¹ žyæw¿üá?Ìàý¿üÕ‰[I+'ו×^ÖÕÝ3ÎVÿ»ž:;ó~ûøc<òÈ@Wë¥î“\Iî ß௞ºÿûªèqæöw¸ûŽ;[v¿_ÊBoÿé¿úʯ¿ñµÏ޹Ž>BJö㣘yæ7ÿëÊ5ëfÍîõÿŒŒ:×ÌG¯@IEND®B`‚snd-16.1/pix/fmeq16.png0000644000076400007640000000261511147553267012757 0ustar bilbil‰PNG  IHDRb+u¢rX3PLTEÿÿÿààà€€€   ðððpppPPP000ÐÐа°°```ÀÀÀ@@@ ÍçðØ pHYs  šœtIME×/&"ºíIDAThÞíZÙš« f) ²ùþO{@\Z´sCæ›ZBø Ù,!¿'Îã¤ÓïÈ Ci‡á§$…Ÿ”뢼ۉ‡Zʘµz: ï;:_!ƒš*÷^Γ`ƒ§H§$H1éºydšoÑtÕÕÍk‹v®ƒôc1ïZÓ@Q¦#ôÜXìuX¬3ÕĨŽÐSöQ™²£ÇÅSä=ÂbZ5Ws¢;Fψ‚©Õº6ŋ頳÷Ý?Ìâ¸s®¶¶¬—éZ¥‘o޹ÄÌ¢Ž(üühʶöãÒ "e@4óNøéX žÊÜXÌÔ”;ï¦ü(P|„±ñ­ÃE{.•‰È_Ù²R½†„ÍJ±¶´lßÔ$Ï~Ê5VñoGÝ$ߚݙn3Œ[«Kà˜×èæýSS‹‡;˜rÕƒ >šý%ÄîÎl›ˆRUùð ;0 “­h§–cx4åG øCˆÇ[ïó"ŽìñÔ­Q—œÎâ;CãE‡‹ÓôdÊøâ+)æÙñr…Âäb²…/œ”E@£Äâƒå!w’#E Á·xŸ÷ZDŒ4‡1ƒÚ!,Wµ’oÇ!價¹Å7z˜“îN¦L 0¢ƒçë>$g¨¦L¬c¶€cŠˆ¹ëµ®»ºùÚN …$ÈV¡vëqˆ%ä°ñ>﵈˜›b¶ÚEˆvyÚç³Ø#ùýKy¦áPЫŽ,\ˆu‡;™2= 3»×z°W…“›X'l ' ;LÕ¨Øù•Í×…Ì$A8^qu¸n÷Y¯¹Ü3VÚŢ㑾®Tx»ÃÂG6Tð33ë&«èé”ña„د"£ÞiD†mb°%‚`ZéæjTìüÊæ ö9Äj]³Ð$AkùvŸõZ´ ÷MËzì{q‹·c>»À'œ¨—>™2=ÜAŒ#5¾sÝÄ:a „êÊl5*uDˆ‹ævˆ™ßt‡g÷%ÄfŒ¦˜rÆCÍ1»‰—ÅZêÍPèÞŽÇsʧ¨nœ2=¬!ƮśX'láS†:« Å(Õø•ÍoÂЈMœMUÙ}ñHF0šþ 6ûM3Rˆ*Y¡ÚOs;©xèiˆ¤ /ãÙ”ña ñ(›EZðªþ‡lX˜ž‰)G‘ÐQ¼\Ý|íîüâðN ¸ÖÓì>W F ÜPÁ5)N\ø2·&Ѭ 6ùÛ–lêco‡‡ßQ#ÂŽSZ(}2e|èÆÈ”½Föaæì5…X'lɼ„k[ŒùFn˜]Õ|MsÐÉM’ ƒ¦!*Ñ>»Ï{¡ˆÔÑ%² ?À)۔؜çvé‡Aá"–ÂÊÑ”â¤êBEü/Å:dKB7A«Q©#†Îuó úb=DT÷GÈIÜô¸Ÿ”ܯ]ÃÔ– ÑÜ¡¿ýÌ-!ODTõv ÛÈxœ¨;E³f±Ò !OE¬_µ½q¸?"åf«yñwÞî©¿~#Ø.么´6‹—gAzüóÙ ©ýߨ±üý;WúDtœJT™>÷»~“0[Q¹Ãòe‡XØÚÒgê5¦ÿzâ[ + žyLÃÆŽÍ—RÐ"Á¦X|1©€ït›0wäkMBCÊoSù€õŸ¿~ÏámÑÉÄb-¤Cü»ðœÇ2g‡ø÷æÃ6×ç:5Ò ow:}®Ç]‡ýM±+¥N3 ßIEND®B`‚snd-16.1/pix/jacobi.png0000644000076400007640000033331211147553267013110 0ustar bilbil‰PNG  IHDR"i7 xsRGB®Îé pHYs\F\F”CAtIMEØÒåÊ¿ IDATxÚìwxG¶·Ou÷äÑ(”3" L0ƒ1Ñ8`¯½kïîç°¾^ï^Û×a½^ç¼NŒÁdL•%$rÎy4š<=ÝUß3#$²#×ûððŒ¤šéžêê_ŸsªêDø>@†à`\ÿS(ÊP‚â,`í …2” \JýšåxM\¿¡P(”!"XÀd°`U+ …2-,€€q½pF¯õ)ÊPƒsy…ýòD\ÿ5²(ÊP³°àb> K»†2øF¹Q/îõ%X„g$kxQóŠBÃïáâ^–ó!Jü£P(”!ha9¤ ]º¦B¡ AÁr,u.Eש¡H¡ -ˆHûàWr 1B\†u oÀ»‡^ÊßD§­~-ÁWTµ?¶Š tÊ €H/%å†,€ªP7.ÝÇN¹¶`Q ŽmË`³˜Z[š$8&CßÕ@È¥YhðÚQ åwèC“wåçÐÓÓ}üÐÁg{¨·§ÇñCŸî—_8¾ÿwë>uhVG{ëí[žýÓ¢`¿—ð|ÿ{À?jsýÆw vô9Æbÿ=c611.Òcƒ^' Â?ʰZÌV‹ùŠÍÁNþ2·=Ï;½+*b2Ƴé’ǵ:"ÆâÀ‡¹³E,ÚyÇk;o‚EQà¯pc „#Š‚(ØÁn³Zí¼Íj6Y-&«Å‹¢Ýn³Ú¬æþ/(8:«Éh·Ù—ç¼nª«©«ªp:ê‚ý¢×‚à*`ßÜÔÐÞÒÒÚÖÆqœã7×}róí+V?ð Ñ /)Ì€ö¶Öœ¬, +¹¢Ä9Í(‚á\ƒ »Vº÷û‰×±©•›uª$¿H"“¨Ôj®gͽ÷·µ¶?’F0Y²b•\®ÜôíFÁj“Éeþþ³o^°þÓOÌý½ÿ©µ¹ñè¾ýñSRZšz{ºcbc«jê4jet\ÜÎëejõ_þçn£lúj݂ŷ¹{x]x§Ž.ÌÉy>:nT¯®K­ñÌÏ8>:irw{ëêµðòö€ÃûvÅQ_Sµî£¢£Â§Í]°îãR’ÃÂÂjjjÚ››fÏ_ÐÝÙ±ÛöÅË—5´¶xº{Θ3ï“ÞŽŠ‰«-+»÷OqÀ|µþS…\9<–e؈è˜Më> [~×o½øàä=õ´T&¯¯®¨ª(Ÿ{˳ÑðÞ[ÿ‰ 5 ]ZíÚ{ïýðí·GŽsç?|°¶ª øúùß´pÑ'ï¾i3™Ö>òØw_Ë!ñ?úÇÿúØ“O©ÜÝ¥ÌVAîyèÑó¾xAnÖço¿s×õ··ÛŸöÂë¯íÚþ}scKü¸Ñ%%e½Ý]a±±½.iêŒÝ_ož˜Â{xxÄô¹ >|ãoÿa¢Õ&¼òÎ{¿ÿf}g[ÛÔÙs‹ó²|âi†ålVóǯ¿úÿþ÷%ÁnÛòÍÆ’ü¼ùK—MŸ=6mü¢§£ã¶w¬ÿäC‰Tºbõ=ï¿ûæŠ;ÖhÛÛ¿ÿjÛë6œ:ž~hÿÞ‡}|ä„„ó„bËÆõù™3æÎkjj^¾æ.ŽãÞ~å‡×Øñ³3ÓW­YûÅûo«5ê‘ã&¤H{öùþõÜß—¬XÅp²›¾þŸÿ}>+3³° à¯OýÏúß‹‰V¹¹ää·5ÔÇ''÷õiÿþÂ+Û¿ûŠ V!“——œY°dÙ¾]ÛO9²ìλ*ËKî¸÷o¼òbs}ÍÝ÷?üÃÎá1Q [rºà·SÈeï½öï¨ØØ‡Ÿx¡ëïNŒ—¼kËf‡1%öÌôôe+W@Üè1‡÷î=>)~|¢A۽㛯Е¤†q)º`fÜVqRò“Ië?ÌoÚM3êy›õW_^}÷}·¯^óâ³OKd²¹sç46ÔÜuÿƒÇޤ¶6Õ/^¶ìè½¥E§³N+--š”25)yR]Uùô¹ógΚ7zÌøÄIµuuüùñ~µBòN?•qѨ¯«»óþ›»ºÇL'W©ç/Zbáù•kî&˜d<îh“uìØ‰ôC=|ÎÂGöÔ÷v§L›¶è¶eg rƒ†­¼ç>«Õ2cîŽ%IÓgÍš5Ç]ã¶yúq’n½}Åì ¾úô#•§‡ŸŸ_BRRò”{¶}6v||av¦Õbäíöé7Í‘Êäq4=÷Äqb1›f;É'00("â®{ï³òB` Rr²Q¯Ûò͆{|äžÿôÃŽ­vžð/OT—¤îÙµxé’…·Ý¦P»©ÝÕÁA¥gм5îK×Ü¥öp¿ð‹O˜˜ÂJÙÑcÆ,]¹ÆÃCþΫ¯,¿ãÎä©)À°~òo2™lÕªÕ¡á‘S§Í°Øm÷Ýÿ˜±ñ~ÁÙ€áÎûœ¿d©D®T»»KH ‹Œš4mFqq‘QßÙ'WUT v;'‘ݲx‰ е€›æÝ,‘H‚Â"ÂÃÃgÜ47".nÖü¹ÉÓfN˜u<ÿÈ!Ža@.å»}BÒ¤´´ÔG×ÞããåyQÏ1ÀI¤°`Éí 7õ¡];$,7sîÍ*7 ˆ‚`_pÛ2Ä0„ç×}þiMuí¨øñ•%E¾~¾µÕ™'O*X®¦²œ(È8õÊÿþýÑ'ŸÑxz@ŸN7iæŒÂü`†e‘ ƒ¶›ã$ú>=ˆ˜˜ÍfpW¨~Ö¬…·l]¿a\|¼„\Ü'Å[­&pÓhº:Ûx›…A$çĉ¬Ü¬¨è8†aX WT»{÷®YsçË•*‹•ÇÀ¸ I)³fñÎ bÀ‚ãØ…KWÊ*w ˜sË’æ†z»ÃÝTª”­MãºÊšÏ>|wxÜH©\Éó6Váˆ`¹LÊ tÿîÏ8|¤³¥Y©qW(U×ï hµXXBdR°,+ŠÀrœÓóv];“Ù,ÚxBÈ-,ì°$G†,Ünå…¸Q#BÂB#Ü==‘«OQív„£ÁTzæ,±B¥âalÒ¤â¼7o_«Õ+”nŽN‘+”&³lwôø×Ÿ}D.ÌϵÛqW[[c]õ…G>blVAJBH"—/^¾òÔÑ#z]7ŸÎoëêâ æÆúZ`XyËÊ;¾Û´!(ÊÉ|í³Ïž|þ…à µZþìÿ½ä$•ʆÙÛÝ&ƒ>jä† ‹‹Ñxx¶6×Y :Áfš1}FVfŽ 8çhšëk‹ò‹‚Ãó²2YŽ“He‚(²,‡1ˆ!¼ ÉB£ì¢Ó¸ÖŒAá‘‚(êõÆ¿þã…mßoqŒ ƒAo4˜–}î_¯=õÜs[7n°š‰8°œD"BôºÞ‡ÿúäþ;¥2‰›ÆÝvÂX­v@H¦|àÁGFÆ=››éÚÝ­ˆŠ ‹ oimŒŠÎ°ÌøÉSæ/Z”ŸyL×ÙÖÙÖÒX^áåá•›™œD*;o+,ȳY,,ƒ€cT"ÇN ÈÇןHY…›Æ*^ RÉø¤äCÛ¶%L&‘Hv¿uòŒg‹Nûøúñ6Kêö]^ù™§Îäç‡EE=œ>eê”úšš3……£âÇ*UnçC^VÆáƒQñãŽI;r0mԘѩöUEÅÅ}õåsçÜÜÚÜT“üñþS”Ÿ³zí}e¥gfÍ[pôPj]u¥L&÷óóÑhÜ7}õ—ŸoâÄɈa"cbÓS¶µ·IM]ûÇ-&Óþ;ÚšGÇÇðŸ×G³óëÍ‘áz“¡­±±½¹!$,ü_Ï?;{öœžÎ¶cSƒÂBÁ¡v·Ô×G®×÷íÞôm]}ÓÜE‹mKQ^nÑéü˜Øá1q#?|óß§Ò&Lž,R[Yqòð¡è#ªÊJ÷lÙÖÖÙ1kþÂó|–´½;Ox{zdgîÜü]T܈щ ]]Ýq#GÙ·çtvvgKcÂä©éi3²Ø¬­g Wßû@^^vwOgYI™¯·oxLìží[Ïæe'¦Lþö‹/cFŽxÿ­·ãÆŒ–+wn‹1"/7çLnaà‡­›TÉl.ÌÍM™>]*WlZ¿ÁÆó&³)vxÜßz½»½#((¨µ¹¹ª²R¥V„GÆ <[C_ïžm[OçæA<šzðþ?ýE¯ïÝòùgmµuvAؾ}[llì¾;«+§LóöñË8žžwô(ÔÚÔøÍÇŸÚ±}ÞÂ[[ÛÛü|7~üqOwǤ©Ók++lÛb°X“'Ë*F*É:qôìéÓ³o¾%`XÀ¶­›K23¢FIݶ382<:6ný§Ÿ±•Θ37ëxzzÚÁ)ÓgZLÖŒƒ‡Ü}}¼½=ïYµtÞüù*7÷ëèloi,ÌÉj®®õòöå$w÷в²°ÈÈý;¶/[s\¡ìö£?ììio‘¨•^Þ>r¹â’Þ%±jAÀ°€`XâZœu^ |®å©(=ÛÖÖ&ŠÂðáqÁa`Ô÷úa¯Ú]3kþ äØá4`¸ð°°ÚÚêá#F566ˆ¼;<¦­½Ýn±)ÜÔcÆÏ:qìlNnô¸ø³çÔÕÖ´·´z{hÌ‹§(ˆv«ÅÍÓ‹åX™B¡Tªd2ùyçÐÚØ Ò¸@î÷¶¶f»'BÈ.Ø9†å8Öfã@ˆe–“J%6 …Ýn—Êdz]'‘u··GD‰‚‚±J¥v¨ƒ(Šm>>~‰ÔÎóvA@Éd2«Õ*“Iyϰ,à Œ H$¼gYcÌ „Ø;Är àm6¤P(@×Ûƒ1ñòöÁX¬.+Q¹¹ùøâàp±ˆ¥2™NÛ­Tªò²sÆŒëîé}Þ·æyže–aAÀXdYŽaYÇ ›Í†!R™ÜjµŒ1Á ÃrœD"‘BÌf³L&C!„¬V‹„ãXNb·ó‰Ôf³"p>‰%œÄbµH8‰€±„e%R)BçvÂò¼ÍÎÛJð–“H8Ž· \¡0™Œ*•úúºؾ­©¶V*‘öt o_:|äX8zè`uUÕä)SFŽ…yÙù§NÉ• “ŲxÙò€ ÐË  È \;‡B¡P†ŒkõqÍ b—gHÕŠB¡ 9ÁBƒˆè²¥û×7О eH @ãÚ_>puûyéÞ) åÚ V®QgiÂþ@;P£B¡P†„KH€aÀ9íÒ_šî|¦P(CÑ%D. _PESB¡ %ÁÂÄé"f°f(¤P(CÍ%Ä®¹Aï-R(× 4ôïB°Ç,!¦?†®5 tP®hýÄ1€±Ëd×Ρ9ü(Ê,â,þìÔ%|ÁÊ>µ(ÊPq ì,§ê\ŠÕï:cð祣¥P(”k%Xý…T ` ¢88%B»ïÎÃ÷;Þ`6h¯Q®+hLãÆs0Ž}9ŽÐ;ãJØàøŸ©­ªðñÐhÜ;;Ú ²³n^¼”v…B¹! ‹biY¥Ñl!"©­©Óõô ½åó÷Þ7LÅù÷/[þ΋ÿ÷Ôc™M–WžÿGæÉã‹36M¦ë1O+…B¹ÞဠèèÞ½g7YK .^´íÛoîzä»Ý5rÌXˆå8?ŸÑcG'$M¢G¡P®`Œ ú†Æ€ðoŸ?>õ¤Z-G à J%A˜7ÛKÁÆK%’¶–&/ß S~3ˆ(¢+D¢PnL—!މ5èt‚úº;Ë« •Zˆ`1YÆ‘€›Häòƚʃ»¶57ÔÓ¾»†ût´(¿GÁB,ƒXööU«Âb†¿ñâKÇŽ¤ÇÆ~øÆë¡áQŸ¾ýޱÏp<-ͤ3äæféût·,¾-7+W®t‹Š£}w qóòþ˜’ôZS‚ˆ±ÎËV‚£l½äÜ6Cš³B¡ —%sƵÌÓ½„ e( !çT 1ŠÔ÷—SEÔ>ÿA/4eÈ Ó_uÀA%sè.èß] €veÈZX„ (s¡…Eù}EÁN—S†ž`! ®¢„6êü©,)úüƒ×úz:wmúæð¾Ý´C(CO°ræíC:÷'ÊЦ§«³O§ÅXlojÐvwþü$çådKeîõg ãÆŒéìhÿQo7èûô½ZþÒæ›ØÖÔôóN’47Ô@me©ã7ûwn¾°Ùу{xÞFÉ 'XàŠ[‰`ÄÁ5²†"‚ äœ<á¦q·ó¶>“1ýà>Q°ÿÌÏD-Z¶òtfvpÜè]›¾?®÷êu=[7Bã]Û¶^øg –-ÌÏÑëzòIK; vó°YL¬k­_¯s-Ƹ½¹Ñ ï3›MñI)Gî£ã䆬~EbXççX ]„5d©«(Mž6]×ÝýÂÓÇÄ g%’òAY4~Ú“u67øù»{ùr*>]àæîqa#Q ór@ÛݵwÏ®üìSu5]í­H"c0þfÝGKWÜqÞ[²Ž¥ïÙüMÚ¶o»;Û†q4íÀÕŸ“·IýaßöïìÙ-ÚùêòR,Ø×}ú!b¸¶Ö–ö¶VBPKsCKcC[MÅþmße8T˜}ÊÓÓ»±¾žrìàúнñ,,‡cèÀ“ & )C¾ÏÃÛG©q‹ŒŠ°Y-aá=Zí@éùiOšŽÎîÛ×ÜÃq܈±fÎ_ÈI¤¶9u85$,4ãÇÅ¿ñâ‹îž^ÚîN…RXF%WZÌÆ_~þæþõþ›ÿùà7{{ºB"à ósy`är¥_@`w÷°°8N2uÖÜ3ùY¡á!¬DªR+ܽ}}}|xc_êîÝÇR6ÔÕž)(Ì>yÂcX°ÑjóöòS«€ò¡ðè¸ÜŒctÀÜpýö¼sºV-=´ #Ä‚B …R¯ÓÊd2N¢’Hå]=ÚŸˆ)3or¼¸uÅš‹6èéìÈÞ¾~)éÕjGÅu÷ðÄ¢““ÓÝÓÝÚЈ¹û¾ñ&„ÔÕTO™;¿©¦F×ÕÁrì°àÀaõ1 IQiÙã±q ÖxŒ%2•ÆÇíÃÀ—½sóâ% Óv—èîí«×õZLưÐP‹ŠI?øC|B²”n׿A‹@0,°ý>…*¨l µ:ðîà€ÀÊÒRßaÉ3foÚ°î®ûºïO¶ZLÚö–y7ß2¸=E¡ÿuÿò`BÁX&Wü´Ó8|`÷­ËÏiY]UŸ„DðôöÕvuyùø=öÅ/&LLéÿ»¿ß4oÑm?ê ­-a!aR™¦Îž[s¦xÉòUç|FÁù5=¼|fÏ_èx]”“9sžóu쨱•%gGOH¤£èzS·c_Ž3?2BÀ2€Ñ+ƒSÀ¨`]cŠr3UnnŸ¼þÆ+þwãßÿèãMõînîOOÞfÃX”+”ÛtÚý?ü€8–AD´ZD†±!$b¢’ËÃS¦L?/,€zæ¼ØÈñ’ˆ¢„0$2|ôÆ¿úc9‰Cž}쑇",*lV _V !f³Q¥rkCNEu>;ÇæÜ’fØþíW"àkî½ègŠ¢À²ÜeÚÒPWR|zÞ­·ÓQtý[XÈ1Pѹñã¨úȵ—°_³(×’Ñ’¾ÿzÕ+YŽ-)*€ÐpÇŸ¤2Ù…íUnš‹n‘É‚ `,Ú¬¹\i·ó˜µRu^ãÜÌ“,'e¥R‚1'‘`Q$–åb!ÞžÁa S(×ôœÕd4›t!QޝÆjCõ«•¾·gÏö­R™‚€À"d0 ]Ý… ±¬„•Ü÷ØãÈ¡Y„œ8–þ§ÿ÷ä¥>óòjå0Á¡OÜC°0@À0NÇб,ëÜ.BBÕjˆÀ2lyÉ™ ‰ §s²¦Þ4ïŠí-fóžmÛ† ³c"‘pÃq ƒ™Ÿ¯oÔðØ“§Î¼ÔçÔVœ yÎÞADN"ûÑC‡…1Œs„èûtš‹Í*^ §÷÷?|ù6f£¾«£­»±ÅÇÇ™QGÛÕáé틘±NÐl6…EF8­­úÚßn|ôÙç鈺.‹ˆ†@€EàØkG)Cˆ¶æFF£rÓØ,üÒ•wÁ"!„¹„}¡rÓ¬ùÃÔ!z:ZÊJËtÚž„IÉÂÃ&wn^ApDŒTê4â&OŸ]S^6|ôØ£GR©bâô›*«ÂbcÏž2}útn?F¹.CNv¦Ñ`øÃãOvuuyú`Œõ:‡—Ýf=[T0aâä«ùîŽöISg8^+Ü4ž~~t8]·°¬s;`ΛdhÄ}( |n扱IÉ¡‘¡‘ mo]÷É}'ŽÿË„“s2Žß|Ûj‹ÉøÆÿýã¹×ßAV®¹ x†Åsø‡ÝÃG½iÞ¹¿Õbþç_ÿüÒÛï@úþ½Úžö¥wÜË\ÉS»fÞ4`¬êðîr7·ðèØmßn°šÍW#XÀÏlæ_ê8§ŽŸìlkbXÖÎóÐÝÙž{üpæ±Ãƒ‚P 3!yrê¾=)‘J“§%KÓÛÝyüСÈ_D­.ìI‚ƒ;ÚZò³rü®øŒÅ½[7'M™qΊìì˜8yÚ/vJT­~c ±®UW€AÀ0ƒ·=ÿÞÌ+;€dÈBýË£ÎýŽc&Oe± ürË{_zë„Ðñ´}Kî\ ¥I¤nýóòõ›»ðÖA'Cæ‰ÙfSkܧ͙ã¦rÿ5ºå$ØNzûŒaÑ£Ã"¯ü@fØ¥ƒ-ÄÐÈhzÛ_¿ bꆆu®f@àÜí,ûŒœ†å÷ASy‰a”2i@h$ ôï>½öÁ?yûúK Ú9”!à:UÎ8´‰îËùÝq&?çhÚ¡²‚¢;¶;U¡¡á•¥g$[6A¹ÁâׇK„Á@ „8ºT шûïŠÞ>]HÜH 8&ÚqÝ“gÌöö÷ûQk(ש³u½¸„ÝÀ8¸»æ Îej±4éèS÷™Bù5]B‚ˆ@D Ø•’»LDò»¯šC~tR(”_S°ˆ3ר#Å9ïFÅ¿o ‹Z—Ê,§N9¤Š"€ÉOf¥P(CF°DA€& â+°ð`µ¢ÊE¡P®©`1Bç´È‘­‹®«Ø•âhEU …r‹BD»3XÜŸ­ÁñâÜš4Ø7¤‘ …r- Ãv鑳ÒW¿NÑe  eÈbOÜJ IDAT‚ `W舢˜:O¼( å Ëà Žsn'ä`Y’Ñ€ 3”߂ݽNà­´7(C Îé ùÖd±ý#Ýó»BÛÙ–~8ÕÇÍS¡Ö´´7,]½–ö eYX€1 ˆ‚\‘,qÀÎgê Q!µå%`µ˜z]q^Ö/ó±¢M¥Tž-=ãÐÑÞõ£Þ«ëéêlk"—\ª „Í?ÿ™'ÙTW-õ¼ÍY'Òy«å¼6µÕå=]tœÜp‚åH€åL,㲨@ìÀ´†&-2•€´µ4Úl¼T"ëëéþùë=,<óXúê{ïß¿gçÂ[ ¼íêß[z:×7 Øbìc¸ó˯Zͦ–¦ú¢üÜÞ^mtL\IQþO>ƚʮ¶v«Õj6›CVÛ£µX,.Ñì$„˜Œ†°ˆ˜Œ£it_ÍCêºr ËÜ[p% ™ëhkˆÒ\_›8uVseiAæ‰ekòðôÊÏ<>qÚìŸù±=íqbGG;…ýÛ·,Z}O[sCG[;E‹Õªq÷PÊІ/Ö…FEË”Š¸Q£wlÝ2*>á¼å­f©\y£ ‹»·oADŸP˜“½ôŽ»OI‹Œ¶Ù¬Ã|ƒ,fÂbúÞm]Ú€aÁ·ßy±¡O×ÞÞàæîIÇÌ%¸ž\(ÆYr‚ôox>oAÃ…ëÝ)CãQÃ0`OB˱*•úç¬B¥~òù— yÚÌ”™71$–{iQAXtøݲxééüœ “RQ´X­À0b,}Úö–ÖŽ†Æ–šºöÚ¦Žæÿàp©B©ËB‚C–#ä".î¶ï6^|Œ2ìmËW75Ô5*&n´ÕfeÆhµ„lþêËí[7egç¦Ø¿mË–âÂÓ6@7-Xèî©çäëp:;Ct[¥\ßÃþ‚¼}Ä• ^‡ECïC›Å„V*“õêûÀd¶Ø­v„P_OWHdÔÏÿ|¥J­T© :nÔEçä$ ȉÞÒÒ2q’±¯ïÔ‰c –,ØØb6µ·6c„Bˆ`" "1!Ø/`˜·ïO;‡º†Ú “§ôÿx¶0?,2Bñ “ºš›§Î]xá»"bâ"bâ‹Â™â¢åkî9ß-AH!—_ê ]­îžJµ&N™‘sâXIzÐê &“Q*W „VÞ},^}WmeEhD”£f¢ÆÓ»¹±!q2A7‚……\{ ]5ÂYEŠªÕ5ƒ·Z¶}½á…·Þÿòã÷fΙ¦T©\~œrþ­KÑà‚’³¹¾©–e$Øx‰Dâ!W*Õ fðe´Û¬YÙYR™B©Y :‰RƒD!¢M †“3,àë討%Ú¸q¤0'û¿<îø1,*æŠÑ†å–ßyn©DgG+$“p,™\ÑÛÓŽ1&ÀÊå µ›¦¿Ù霬¤IÉŽ×n÷)ƒëÈ.¿ãî ]×ð˜f@I“…§Cè†, €°Ä¹íЀDÉ@ãîC‡üœÌQ@ey©Ãòðòqü‰å.Ré‡e›RÁ Êd&6„!“¥Ïb3©‡ YŽ=f,ËJ\ËY „!¢( ;oS©…pËS;‹É`³Yסù14B¶løZíéæ;,@&‘s 5ÆvA$îMÊ€bÔg òæ°9nP 1–½Hqrfp.rnâ›r= – РЬ9w2D®ÿÌRðšãë Ö¸Ÿ-Èæd2‰TzÅör¥jXP0°2BDÀ"Ãr1Œ›Z}žÕãéé5ð7¢ ädœH™6ó‚2àcgm]“ÉxpóV›Bʼn‚P˜—™ücJþ!ôØÓO÷‹¶šfϽù|»ÒfÕi{ò³s×>øÁ1LaAöØq‰_ïGÄædRW8Lüôƒ·ÿððcR™œªëO°ÖQóÒ™B ·æªVCèá#+KJë§Ï˜ €šêü†5ÕÕGÅÅ]´½L® þ‰%Ž ½ÞpÑK«ÓöxxyggÅŒ16qROgwp¸²ºªú-熎‹“+.—-S&WH8N¡PÁU’ûz{¬3BöîØ®vÓØ¬fâ0µ°(`,€¾O«íîE±WÛ#Š·Y:[[Ngœ´šÍpêpj}Muc}É ¯,/3›Í Ba^nqA®·@OwW]M•Åh¨()¡£µ¥¼´äR½J¡ü:‚„ÏË¢¢ eA*‘Ym6„@¢wÝ-Ýz}Æ ¼ lV³Ùà4šîÙÙ§7öj/nt=3çÌï¯LÕÙd0öõò6kGSCÿ­UUv¶0?×qgÚlÖ¶Ö&›ÕÜÓÕÁÛ.’,Üj1—ÖUU:îí–Æ†ž®v«ÑTSV¢Óv@qANþ‰Ìô´=]íç½W§íNݵãì™"0èu‡÷ï1èzìÞ¥íloi¨Ý½å;½®Ìfc[KƒÕb®.9ã0 !%EùGÓöçf"„t¶5oüjCmeùñÔ}E¹™WìwA,ãÉ´C»·nµ˜MPzæôÞ-›·mX_Z\èÔ,™ìXZêþ=;ßxáF½ý°³¡ªnçæMUe%}½ÝM µi{v××Tg<ñàšåzm÷é¬Ì¿=òhoi}õŸÿHÝúÍ>püpê…'}òXSCÝðøq›¾^ïØeåy­¶—“Hò2NeO€¯>ýÀb1úúú~ùá» “J?xýÕ’Ül•Zùê?ÿ§½¥Õdè[ÿÑ»ô.¢ü¦‚…B˜à–æ¶’’²][wEE'¦¤d;ñ×ûî­-/ûãÝklVëæõŸ–œ9r 5ãØQ£®ïågžNÛ¿7?;óågž,=S(ØùªÊŠÖ–ÖüìŒ SZ³wëæ“é‡.üÓÙ‚ü'ÿ¸öÔÁýF“é½×^±Y-ùY§6ý•‡—׿þ÷‚±N«Ýðþ›ÿûáGo¾–ºg×…¾Ì?ŸxÌËϧ¶ª|çÖï OÛýÒ³ÏHår‹Õ¼á³ (8ÔÛß'hX Tz~‚'‡§§¯ï¦/?»Ý~*ýðÞMßL˜4éÍ—^h¬«‹OLzáé' ¥±ñå'þúÆÿý““Ëžùóƒ-ÍÅyë>üpÆœùGS÷5××øø K7vý»ï(劺ªª«,±¾º2yÖŒ‘£GìÙ¶öïÜzëêUwmub’cã.^½çV«ÙT’”œ²cëf/ßÀ°[W®>jlòÔé±Ãã¤rÅ„”)2™ÜaÌλm©0ï}¹aòŒÙžÀÁ]Û¥<ÓXYi3óV³!(,ÜÛÏÜ„D™\ê¨ô7fB’—§Wc}cMu¨5î!á¡£“S‚BB±hOJŠ9ªµ¹‰ÞE”ß ÎºE,°,§Ò¨C‚#bc”*™Ðf5ÿaåíë·íI¹i¶ç'/X”sühMeÅÈ1ã¦Íº©¶ºj΂ÅÆŽP__Ÿ{ßEê8Mœ6sûæoÆ$'ûø óðð(ÈÎ Ÿ8yšEo²Í‚`÷¸hŲ㩩ϾüŸ‹=¯X£×ë:½NÛ 1#G»iT Çú…XÌVðôñãy[\ü¸ ý>†aGŽ'—ÉÀËÛ7($dÌĉ~þ&«y\R’T¦°Û̀ظ‘A‘a·®¼#<*vúì9·÷íùãåyùºž>ƒÁÀ°¬ŸŸ¿ÜÛ#qú¬Ä«èw‰„óôõã8‰ÆÝCÛÕ ÷>òȉ#‡8Ìèzt®oF4à¦q/-.°ZLr¥ÒdÒËåÒGŸx D‘õ}†å¤=ÚnB0 ÊœùøD<|¼ÜÔOdØò|tÒX™\1|ìX@ °‰v;`Qß«óòñ€¶ÆÆZ«åö5w;´ Ãq‚—H¤€ÚM X°Û#§ü†B B@€X-ÀS£VÊ8pºfÄM%—+”áQQÍ--AÁÀqE›ÍJQ!“€›—÷°  0›­J…B°Û.tÜbcãŠO$¥L‹Íjq,ë ¥JÕÓÙÁq\q^n`X¨§³>±D*‘»kXŽ»hÒÞSGB’§OëëÓ,2,K°cØEç&I‹Ý€ª/21ǰl¹PƒÁİŒ#ö+•)†% "€ÙÊ+T*P»{*ÕªÎö–Ÿ|2‚HÌfRSY5sþ-%ÅE^ž¼ÅÜÜØX^”o³Z,f³À[áSø- AAé©©‚]ÈNOCˆ±Y­X ssŒ½Z£A€¤ ¶5ÕWVTœ÷^ŒÅÆÚjCw·®»Ãfµu}Ú®N;o,–Þî.¶Û¤34ÖÕ€‡_Cu5!$ëÔ©iso6èõr wâHZMuÕ-Û»;Ûk+Ê ==-õý¾îÃÞ}å¸à;‹‚=;3£¹©©©¶æÔ‰µ5 F½nâ´éGÓÒΞ)öðð9’zFÆ«*«ØðÅ'-mí7/¾]åæ>wáâï¿^·é«/|C"`ÊŒ›þûÎ[ŒLKï^»óû­•eå‰Sg~ÿõúö¦†Ž¶6³Å\[YqÑN[ºjJí––ºßÇ?ˆ“HCÂ"$RYkk³R­1[Ì ™‹Âš{ﯪª±àö;|͆¾»îûcs}]ueyâÄ)͵uíMKW¯®<[Lo$Êo"½Í6Þv2#³üL¹®Ï4bìèé3§øb NeîÛ»ÏÇÏïî?>¨róÈ8ž^œŸ%—«o]¾ÊÛ×ÏdÔoùöÛÈp³Í|6?ÿá¿ýMÄä­W_ž8qÉò•çÕà´Ûùý;·'LJ ¿ð$^üÛ_§Îžçíç«R¹EǰZÌ[¾þ*2&ÚÍÝ£®¼<>1áðÁƒ ËDÅÄΘsó…ooomÉ>ybþ­‹¤¦&¥$ûúÔVU”—–$O›±÷ûï§Íœ;ütnvqaÑŠ5k”ªAUÚ±(dgTrehttEY©Ýj èîÕªä c‹ÕŒJ˜˜òÖ¿ž÷ó Š •e' ®¯« ///gYÖ××7`X k6À”w"}ê¼Eœ2éhoU*16›¢ÒxHerZKB¹²`Ãb–e$r`Yä\5Ê ×›@„`t…<¶?å–{áñ?=ôÔ3ÂB‡rO½÷Ò?§Ì½9!yêÕ¿¥0/«£µuþâÛé8£P~8‡1ƒhÀÎÂ9¹ çà«Ûºâ¾œ­V&£¡Ïhiomõ²/Mz}cS“iϞȘážÞ¾Wù®ø„I(‘ZLÊ/hai›%T9ÎYð\¥/f@¥¯_+VUE)o1k{z'Mz5•ǯ V‹ÕÊ[±`W©Ô2¹‚Ž åZ¹„-N“J"††äÈÙÀ°ƒ ©RcB¡\KÄiUpSŽYBWZwš ‹B¡ ÁBŽªa"¢3c2¢%s(ÊÐ,缞cî9Óc¹òaQ(ÊÐ,9«N|®~ª³þ35²(Ê,Pä™ H4ʸf>#5¸(Ê5Ʊ.b1€X`.º|Pé‹B¡P®‘…E0vy‚àüÿÜZö¥½¨TQ†:--4×Ína!ÇÑsûsÉ'»ŽÞµ'°(åçˆì6³phdT ½üC¾Þ Äý‚,—¢«µÅÝÛ[*“€®§KÛÕrõ‡;žº/uï~Žeµ}º¿=÷\Hx$½CÝÂ@€‰3£€Ã¶"Øed ô¯û‚õ 5U•gŠjÊKó3² }}ôÚ5ì¼ítn–ÚÝãòÍzº:3ŽíéêwoïüÌS„S_ïúß=vÜ•­°Æúíßl¨«©€”³yüÏsÎ}ç³/¨Z]'‚E0 ìø‡Ï­Gùœó"î×Þ7Ä¢ÐÜXw5-ëjªv|÷õ‡¯¿b2ê#bãü‚Bç/^¨Tnc“RFÆ'œîò¤é7Ut÷h«*ʧΜ7 ¼||2ÓÓSfÎ!‚ •ËòÂÜâ3§ïXû0 tâðÁŒ£GƒÂBïzàÇÞ²qݸ„I‡Ø7b´(Øßó?úöžI³§/Xò —ɰÛ,{wl7™,Dm ÃpŒDÆiX)1(8$qÊŒAÏym·ÅdÔxx!Ms3dµXœaUÇ5FÈáÛ0 1AB„@¡QÇhFY,Çc–‘J¥1£©)+1!áò§}4õ‡Èá£r33æÞ²èÀî&¥ôtvVœ) ‹Š®­(ÕxxíØ¸áÉ—þít½+Ëfß¼ÞÖÛÛk4Ÿ~ø¡·×­ €ô{y æ>í’UwäšuúŽ®"™0 IDATŽé7Íu÷ðÌL?$“)òósþôä3õÚöÝ7}½½Ë×Ü©rSÇŽŒ;v8uå]÷9þ”~`ÑÂ52bøÈÓùyGŽŠ?sÞB¶ûø¡ƒÞ¾þAÁá1# ºªJ«íNJ™¢V*[››Ý=}šª++JgÏ[ì°ú+ËKC¼}Oq‹É˜{âØ° o„A§Õ÷éC#Òa_9G…s!`ìš"D@ˆËJÀƒì…KÌôf宼Ï9 ³âλ«ÊJ’';~œ9ÿf‚±L®LHd½[̦M_­Ä –•"0,¶ÙE¤qS.[}çO‹š×WWJ¥RË>x³Oç¤\üÈÄmßmœA!v;ï\·c‚ɤܸI“†å´êk«*ÊWÝsÿží[ÿ°`‘Íb ¶ùùM9ëU™béê;¯Ö4¨¬ª«­•p oãX®O§EFƒ 7I‰È"ÀÄ ‚MX‚Y ‡E$“±^PÈ¥°Ò݃S¨1 ¹”ã8©Åj™;ožã3h˜™ f³108ìrAXQ8—5sþ¢³…<Ï×UW.^¹ÆÛÇûãwßzô‰ÿ9z(m|ÂÄY‹÷›ºF³ÕqoW—•Z´úý;w~±}—ÚÍ }½y9Y{îå—þþÔüEKÒ~Øóôó¯è´Ý{·m¹eÉÒÞÞÞi7%ZíNƒ‹·Y‚CgÌ0èuîž^a‚Ýi¦e?¢tÓ$¦Ä¿õêËOÿïó™‡>úô?voÛÜÚT_SZø0ˆ¢`·Ù–•ÊäN½@éíße4šˆ(° kå Œ„E„ài³çú ز££ËËÛ[­v»Üã4mÿÚ?>,W(“§Í<[J•¢½¹182öÙÇsS*ÿúÜ?{zzúÍûúêJ•Býö«ÿzúù9W™Ÿ”)Ó7|ôawO÷Ko½Ã2 #á0öä0×Ú–“–IdòEä%gD«í”IesÝFìüæo6Œ3ì¢`2gÎ_¸í«¯ËËKyâ _ç÷­¯­)>¿lÍ]5åg¢GŒ­®ªŸ4éØþÝ3,qw÷póöW*U‹ ÃÖ×V'$O±ZLíÍnjeúáÃã“RäJUoO·›»ç/;ª,&ãîᅮˤ„›Íj´©„1pEÆÆNž6s`ãÄä”Ää”_u”wwv`A ¾||Únǰ`ñR«^ǰ,‚EQ&WêuÚûy¬¢´lû×_OLFˆ„<=v*ãøÓÿzuÇ×_ÚÌFlç5^ÿŸ½««Jûï¹w\ãžÆ]š4IÝRo¡ŠwYveaaaXXXdáC-ZªÔ½M%i¬ÑÆÝ=“Ìd’q»öýq'RK(Ëüžé̹'çž{î{^;ïÏÝ ×»¹¹ÀËo¾kÑëô:ð¸Ü¡¡A™ÜÅÕÕíW^ Z°t’ (úlÚÉ»|„}ÿLf»Q\^V¶zÍ‘DòøÓPÊÝ=@.•Ô×Õ…EÄ>÷ôŸ<\ÝÿôÜslc_ÀãñÓyúo/ xBÄÁçÌOU*í¶¡—›sAVװŠ|ANVhd´@(4›L‘1q Cyyxuuw¦Ì™£›„ !Œ `80lõ> gŒïE®¯©ö ò—;»€É ‰e0Ý’°Y÷ìÞéâì4)äãF+)‰Íf3MÓ V®¿}lã%+×NÐû¨Óixb6®‡ÕËÛÏ Ó{ù}|RJQaþŒ¹©BÐ' øÜ‰ƒŸlýn@¥Ê:wúÖ»ïá˜èRNfúc~öÓÿ{§­±pNBò &óÜé~ðÑРº¯§ÛÓË‹´X)’`0 Çð‘bMe…fHK„HÄM™»ˆgüáÔ°¨ØDeŸ—oY~δ3+ ‹â“fHDbOoß-Ÿý÷á§ž¦iêBöùèøDPžÚñ-.uúìÝ·nºå6PªŒzmÄœù€PA~~Gm“V7ôæ§Ÿ ÅR¿€ ‚ììÆ²Šˆ¨ÈÖÆ†iÓg½û¯WÌz}PXÄs/¿6¹«J(–l¼ÿÑg•«úIO § Îá†ED4ÔVY ¿ÀÀ™ódŸÏ0êtËVÝ<Ðß_œ_¥op¸¦«Å+$¨Õ€Þ` ‹ˆìh¨ýlóõ€ªìBβõ·±íKs2¬Z¥êéîélñ ‰È:Ÿ¾îÖÛTmn~F£ùþ§Ÿimi1 "±D5 Nœ1«½©\HO›8{Ñ©DÒP]?U!†Ý€YAøk{–e÷B††ƒ1Ô„ìø°ÌºÊ XL†Ïß»¦¼ÒÛÛ HÊË×wë—_ºº»9»\ß¿Žãœø„݈ˆ°È¨ °ÈðÈè ÐðȨˆ¨èÐÈègNS¹óëM ÉÉÓfΧYTl\nú¹Úê*žP˜2S74˜›™˜˜ìXVRRW__S]¹pér©L¤ÍÖ××ëÙés,²”A§›º!Ä0 ÓêÚ››úûâ§%>qB,• „¼¢Â".‡oTP ´µ·EDÇ „"cã8<^@HèÔ”™¬;¦¡ª,.i:;ª©I)™gÒª+Êæ,^îí;Åb1§:±zý-R™“»—gsscÅÅ¢%«Vs8\P*z1hJHxxl|Ü´$ Ã<½¼$2YxT,ÛÕìÅ‹–­]ϦË:¹¸ÊœdÁÑÑÁa>Á©léÊ›W¬Y?{Aê î¶øé¨¯©lij\sû]ã_FÆNU(zå®®Þ¾S|ý$‰§¯ï”À`±T259©½µ-fj"» §»[*‘ˆ%²Ðˆp7oÿ à˜Äi.8\^Dlܹc‡x"QDL|DDTvúiÄÀì…KLV›D")Ê+ u÷ñ¡D*wvÖM3ç-mMuÎήn^VYR\_ßÀC£b¡ /ä’6ÛÜEËÊJ/júTj•2(,ÌÉÕ Š23¶|óõ…´Ó¹™Ù+×¯ç „š¡ÁþŽÎ˜”8‡ÓÙѹíóÏuƒƒÓçÍÇ0̨×ÔWWº¸{©”ýááÑ>AÁÿyíŸÇ÷î¾õºÑ  ‹¼Ñ%¢‡ºÂì¢ ç††ìö {LçuMuzì¢ß·c †°¨Øøè©‰¿ü-Vóã·ÝºúŽëïºocØ›þûzîÅImui1ÎåFÅ%€×€^;”}æMƒ@ ”9Ég,XôC{ØöÅÇ}}½/¼þîd.3Âvh×w·Üóà$¦J@Æñ W®› £0MQcZþ°ÃszV*“[,f¾Ý s ”ŠîŽÖ–”9 n´Å€Ù=ḛ̈[b04†ã‹ß${ÃI´ÔÕûúN v÷N.lsK]e{S]{KÃU3˜Tz£fö‚Éôr¸ÜUko9ôýŽÉ­®ÓÑÒÔÒÒìVã#/'S"•ÊåòžÎ@ø.‰É3'wT\.oÉMëªÊK'±Ïœs§¢R&Î~i˦&Ker„WÕ¯+KK⦥ÜNwû­cö‚îg8å]ÊC1Qù]v±(yÎìÝÛ¾ŽOIæry“;\š¦¾ýê Í€š¡I«•˜³hñÒ•7]îñ5›}ƒ=}ý&÷O…†ùL®UïêIãcùÍë+.Jœ…rùÈq„Ʀ–uwÞ7Ùãb\ÜÜ'’6qÌœ¿ˆËãßsž4s¶à†ßj&Ïø÷‰Ûx8óÌ)‹É|÷ƒ€³›»²¯Ïj2û9&ç7,°B€ðQI4RŒbT:¡ß)áûÿÝd±XD"1—Çwwò’¢™ þ|<ôf6ìE+ÖÞ2òÏð¨šÊ † "câ“óÖ¶éÁ.„ãö¬+   S­ò­þv`4è/de.^± ÇŽmø_X”ºÃqÀ9ö(!†Ãa€]–æŽ9&ËYÏt蘿Œ”qd u\ò½CZ9p£o½Ž)ø]¬áÒpÃÙXö²bc«÷1×­ì€?³ö䀬†5RyÄeg$tÈ)Ú“7˜ÀýHS£< s©k]·¼Œ“ Ò18pUE2z±¡6¦¦(6,¶NÍ_ŽÈæAAn¦cþ·Áò»hU¬Ìbÿ?Âñ…ÿo‰*hš¾±Ïñý~÷†t”a¶ê;SZ\ÿƒþÖ‰ƒ{ Ósl6 ‰Ð~ üN¿:0Ék˜'Çþü­äË0cä3æŒÎoûEÚ¹ù˺ê2‚DÚ7+”È+à†BqnÎçOK¹Îñf’´é´ZW÷!µ*/;ó¦õ·õºÚª2_?.x-fŸ/-Êóñ›²öŽ{—¯^?cF ˜›OÀÿ|Ãÿ“Ðî[V¯.),3âz‡MZ6Ë[ê´CGöî)ÉÏ€õwÞ³rõú•kV¾kCZÝhÐk5ƒæºÒª»£ý»Ï¾ÜõÍ×àâæ1?uIYAžDæÔ×ÚÖ\[5þµuUå5U•!Ñy™ç†1 çÏœÑë ™çÒ(Òæx¿…FêöÑ€0 ™á’~#B c¤üú~w•²ï£·þýäƒ÷1ôõ9r «åËÞC ùŸW^! a³576úÜŒ³$au<þ …93ç_¿š¨_@à‚å‹9Ã|E2g—¾¾^†¡o{øñq¨*€aèï6½nãKnZûÆ¿@†ÇLuóö5èõ8Îu<‚߀À²ó¾{ËcO¢n(õÊÝÃëÑ'ÿ„MÀ uúø‘õwÞ½äæµÏ½ño—ÇÐTpTlâô¹êÁAœÃs<þ ­--`"-I†€#‰A§  ¿`Ys]5‡±¹¸y`Æãñ@*sJš>K&w^½ávp˜„¿pì®u;‹*ËhÃŒ„hŒnu¥UÈ\úëD09‚Ãq¾HrÝf6«åBvúÍ·l€é³æ€“«û¼…‹`ýíw9žý †0›ÙM¨©±~÷×›dR±I§§iÃq’Ã1š ÿ~ÿcV$14ÍPc”}„ :íuÉÊò2ӃãýÛXÀІë#3ø°ŒBÃÞ+|´ÈÌ%R CÓeóer—òâ‚iÓg‡G5ÖU…FÄ`¶ãÛMwÝÿ†ã Mgœ<êîã·wçwwÞ÷ðO¯Šã8Ž®oœVç9j‰üV€¬4Í©ÃÂ#_}ïÃË~¦(r”îÃÄÒQÞyЦXf q@QdCu墛×ÿÍ©<7œIÈØå ;ÚG\Zè²*£Ì˜ºÉvädœqóô©¯.]¹vCÚ©Sý}†³D!†ã Â0woŸöÖ&.?kî‚ÂÜó?}Ð$AÐôõ ]µÔÖ„GM4Îm5›LFýømLzͨÂÐ×j64¨a]Ú¡Ašº¦n@Ù78 çr¥¢G;4p­_Ýíc²‡çm¼H…½ññƒß“Äuæ¶«½5ýÔ±£ûvN²±ïîn³Y¯½Kq†o¼ûôÑ#-åU•eÅöû²šä× öõvw´u{ µ_»¿úìÌÑÃã40êuYgO@[SÝÅ¢‚¦ºšI0Škšþ)=VÓϤÿÞ( 0ˆ=í<,˜Fô)ûÊ €Q«”éGÞ½=íÈAµJ©×k§†EM-ÊÍššðÍ—Ÿ4ÔÕŸ>¸/'í˜VÙ|ÿžÃ;v¶·4Éär’$ (4¼½½ã'ŽØjµdŸÏèëî)/*§M‘¹Y™׿¶|þÉæ?§AO{K[k+¨Šý;¾ûøí]ýÁÒôSÜw1ÿÂõ×A䦧])VXìÝþMyñ5ë;[-檋Årg7èko-ÊÏ=¶q„Cˆa¶~ýI^.w¾ûêó+å,E’i'½úì“$i€ù‹WÛ¿{ü‘ûÍM]\W]9¹kqáÒ•åEù×—k^¾O½øò«Ÿ|;5‰Ý½<½|qÎu\æmÍ\ææ9Ñ‚¥) O>ãÚï/S”{~ö‚%0%(Ĩ,¸ýÓg@æäZq±àG_®TtŸ?s–ýÜßÛqö¬Á ghŠ-}ÞÚP³å˯¼ª¬ gyÄ0 T”çç\w¹™çN=X_]ñs ,{AwÖ$¤íÌÏÌXÉ:Rq\ÜÜÞ´ö̉ÃÑ1ή®4Íi2ùººº†‡‡#Ê,tvE‰Z¯  –{zðø’¤|>04%üTW7Ç›³páÖÃ'£§ŽÇŽ¥V)ÕƒÎ×ÛxGðÐSÏ<þÜó×Öélƒ*eÌÔiàîí-•JS—®¸ºaƒaßî;0Êo7ψ˜¸†ª²«þúÄs_´rõµ®­++ž³d™}«7 LŸ57.1ñ‹>ñé¼ôú»Wz ÝÜݺ¼ðÎá,_µN&“qp.ÈäNN.®=m# À¨Ó0c¤ªÉdlinhª«™1oh†ÔZÍФ¬EÿÀ`‚°õ´·]ÇtDÇ9†aFÓtQvVò¨tº[[xBŽÌi,6ñŠÕ¶0»ËîwÉ¥YOB˜N«1™Í~A†kuz`˜¶®öÎÖösçJä.nì¾”—u.2.ž}¢9é§I’¤)ª¡¦*6ñ§’!„IeÎ×m¦èî 8îÞãqat··ª=ÝÝbYAA~hhˆ›»GÞ… 3§O¯«­ óö³SÔ”] ¹°±¾vþ’å;¾Ý´æ–Ûergš¢ÒOŸrr’9;9‘MuõKWÞÔÙÑÞÕÕ55~jYéÅy©‹YÒ$†a.æçbI³æBž¾SŠòs#â§±ÝÖ——6aà|üè¡Ôå+LÃáƒ×­]“™“=k¾ñ¥G¡H˜egaÚòí¶Wߎ i«ÙX[Z‚¸œ„鳯tä\cJ&ˆ6ÜYóSOڷᮠصõ›ÆÆFgg§??ÿbúËÞŸ½ uÏgŸ½úég- {·íÐhµþá¡‘Ñcû<ºw§¦¸®U«36±\Æá 0ÊŠpîê w\Ë74gÑr‹ÙôCÞR">9™?BªžŽ6—Ï»6- EŠöV¹»×î-›î¸ïÑ£ûvϘ·ÀÍÓûã·ßXºˆÄ¸V³~Ýíw³{;šæ,¹id3Óu8žº÷žÿ|ù¥“«‡fP]YT$wr¢=5efö™©ç€ºgùêõݪ… ‘|?*q:”æg:™8{ö‚¥+¡€°Èìs§RW¬a;//ηZ¬þS|‚:êÌV+E‘1‰É E6•—€DRIPxÔWWø‡Ùíßž.J)“;Y-–¦úÚˆ˜xíÐ`C]mʬÙWÞ8»z¹Ú”¹©}}ýä°‰ºbõº‡öÞz÷Cך@³ÉÈãòµÚ…«nú9ÖhuÝa«ažzt©ž…˜–¦úж qRÊŒÃö¬»õŽ+û•»¸ÐÃÛò¼ÅËÀ¤×µw´­¼BÆ—å«õZ@Èã“Á 5CjšD2s,9¹ü¸ki¨Çy™L6Ž®ÛÚT;kÁ²ï6}öÈ“ÏH%âÊ’‹7ߺ±¯³#C©X°jí¦ßúÇ»³“P]U9uøý§H8œE—§—7IPWU+–Êϧ_wÇ=i‡¥.]òÕG îáî–qêøª ·@oG«²GA¨”,ŸAP M! ·u“aÚŒ9çÒŽÇ&Ïtss3›La‘1A>…•…<ôÈ[¯üX4EM£oõ›| d§Ÿ»ùÖ; ¯»ðûúvÃÓfµX,†!„HŠÖk‡ŒF½Íbáóyž¾£ñÄ:2¸NG›]͉ ‹Ä¡áaìþà±'ŸÎÍ˹ûÁÇíÞîéå­Rû†GQt!—XÕå·Þmç^ ŽJiŠR*ûý‚˜ÚÒ‹=Ñ1ò+tL‘èšâž ùp~µP$1 C#„Ù,æÿ¾ñºzPsߟžˆŠ í- çÏžžâé£U)Ý<¼:ÛšsÎ]¾f­›§ÏäkX Ðc,…Ë‚#Ì( (ÈÎ ‹‹cåWTl¼§·÷Uû}ü©ç.Ÿ©låÕ4Ò©ÉÓfŽ4iÃFò÷®Xsje_nN&Æá¸Éd˜PŒ(Š+“¤-8 ÈÕÓë²Æ½Ýb©ë8§ÃBMÍ§Žœ˜ŸºK¤€€Ëåùøû‹DB7/OÀGM*zLÖOGk³‡Ü³»§{éÊÕ4I@pDô«Ïÿ…œ5·¯@\x|·Ÿw⬙š!Um=ÛÅÅ…dÀlÕ°¿X-f’°qùB¾P\ZZºó»ïæ/ZÌZjE‰è¨ø8H,²ÇÅlV«X86_ Uf'Ïž+æáþÁ¿_»çþiŠÄpNeYYeE¥ÃC¼¥¶œ& fŠ¡%ñúÛØIfhZoÐyäŒÜʼnýHÙ,s.$l„Q¯KeÝím+׬íêh—»zÔªÎÖæ«nÖé4m-Ac4P8u`¯ÕFð¥«Íf³š9ŽH Æ88†¡›ÖÞ6¶¥‹›ç†»î¹rC¡›Ål¢(šfh†† Å"Wð#¦›U¥Rû…„`×vuY̦Û7nìlïÌÊÊާhá8<žD"AËÆþ£–<õ‹ù9繈!L&®H<40 ‹ÅÙíwÜwáB—Ã._`Ôë¦Mÿìã4jÕÆ`{òðv9}âXhX¨P,ñ*°êëy|Áý=¡RË$Rpuw¯©®Lš1ûã÷Þ1 w?ü谻݌ Ç%œ\\eNΧì»ÿ±?ŠDb` 6eú‰ãGn¹ó^¶A~vF{k C|‰´£±ÞJ1&ƒž°‘˜õwÝ;Òm³ðc‚6MÓ8Žé†g.^ÈHüÙ-ü³wßzíƒOó³Òƒ£¢†)ÌÊ +)*X~óúÉMpãØ3£ì6ßp¿Q'¦Sµ«^U•¯ÞyïˆRæò“ ós³ÛjA€I„ÀÂå ’À°ûîp¬#ÆÕÃk͆¬¬¹~ N7èîî:NK†&Sf;íîûO>08 Ä€¹g¡€ e6ÿA:Fðå_¸°îÎ;¶|ö››§«‡—‹»GKmå,-ƒ IDAT+o¼EÔá}»fÍ_ÂçqY§¢—C$>,ûšk«£b"E"aYq~bÊ,prvâò…lèmÁ‚…þ陌´c4EV«¾!ŒËåñ†˜a–v_0ö©(ÎWªT ¡èj¿åÞ†a||¼Û[šÜ}ü iÆÌ¤v–ö#»·­½í*ê°nhÀ¨Õ··4…E€Õjã Ù—eåæïØü]ÿÐÀgÛvŠx"‘ÕhRõõ´z­N#’»<õð=¤ÑúÐ_ž½L`­½ëþŸhúã\¾˜;9Ä¢ý½Ý EEÇÆ³ô:íþ]߯\¿~Z\œÅbn¬©pq÷ruèíUt¶ò"‹F«Ó ²*¿Û˜h£RÑãâæÞ¯èkm¬‹Lœs-éhhˆHH¬)-L™9+ýøQ†¦y8ø8|à™—^Â9œ¬³i@“DSMã¬Ùskª+Mz­H*Þ°¼p÷ôÒhu8®SöÊÝ=`H£MLNîiixþå×l6ÛñC{Ù#ß3ª<Ú¬–ãöÌZ¸ÑDc]uDL|kSCBÊôº’⸙s &nj@@ÅÐr'§³FCBâ4‹ÕFØH“Å8".€$A0Fÿ2 M EJån&£ŽõMªU®®îb‰´¦¬tÅšuV“ž4gŽ{òo/Mz:.! ó k1½f¨­¹¡¿»×j134]˜—ÕÓÝ{ËwÿÄÌœ»`Æ%.êÑäÒ+ø‰ŸPRª"¦ÓÀf³;qÙ¶x\^wkëœö“O2gW™³5çâìÞvEتO£Vuwð£ãXwš¢Ùä½Ñ¸kË×B¡ ©¾î¾ÇþÄåòN²ÆêJ“•ª«®òö÷wñózlÕò¦º*wO@ˆ¦Èƒ»¶m¸ûþI(‘B´Óƒ]Œ¦‡Ñ÷1F%cV36 CêÚÈ0f†±0Œ•a†!ÛZš²2Ó/dgåfg‘$y1ÿÂéãGŽíÿž¹ñ`Ök]wó±½;¯×& ‚¢(ö3Ã04M“AÓ4ÃÐ CÓ4ûcÔkó3Ï\uÕ¾H’dÖ~™(T=ÝU¥Å?âkÊK*ŠŠ®õ+EÚ®úý·Ÿ~@‘äø=S$™vdßö@­‹^;h1ê ›åG\^^”ÿàºf²ÆCج¶CÛWÎd"ûô ‹Ù4Ί½äa€^3˜s攽M‘$I’$AcÆ|õU±õÓ÷®ú}KC]VƹÌô³ý½Ýlÿ»¿Ý4úç´CíÍu#ÈË>ßÒØPQR\}ža˜ôS'þýâóErØ_mó«}Z¯úéóÃÖÃ2ؘ=¤N‡=2¢þ4Õ×6ßùôŸñý’1› $Iq88†ð«Fˆla¶š£â¦^ßîàpƪ–ýfTMId®®îµUáÑq׊p±úàÄõ £^—™qö–aGéBôÔiÙçúzݼ.wjFmgW§X*óò½œÕ=yö¼ëfž>q$yƸ‘PWY¶gç.’°M©TþÒ¿þ-œ@XðÿÀÐ`\B’X*Ÿ4IJ¿lUîù³l@i²p± Oâä{ÞøYlãïÍr÷+}?ƵIªZ1œƒ0ŽÃÇCöÏö2~—E ÃÔ×V[-–À  '·_rùªúµop¸qH%uó¾êêâœôüœœ§ÿþ8ð?3ÇEÆÆõµ5DM›)urý¡—ðÏ—ž~ùuN›•–¶|íZ‘£ÚoÃŒM®3ƒðáóÏöøæ¥þa@EÅÄ%$%ÿÂÒ \Ü=O;f³Z‹ (ÂzU#¬¼´lêôYm-M]íŽgü?€ÞîHg$öíÚ=ÁKTýŠ£öÒU[QÇárÏŸ:¶bý†ö:æó7,°›çΞ%DçÙ3:—ä7Œй–Eý y°Z54ˆáxgWofƹ±ßwµ5ÑEX-ꨘ½Z™þ¬Ùh¸1¦ÚÁ9ôãñÀOú…,Y½î¡?>9ÁK:šîØ©V)Μ¾y×X µUçÓË rÏŸMk¬­ŽML’»¸ÅOMèíìrwrÊM?«<´wOæ¹3mû÷ìÚºy“fPM$W V§Võßn6Î;üö?ÿÑÓÙ®PÕä]ØùÕÕ¥ÅW¶,/.xæOPëdš"F‰¬×é?ÿðƒœÌôkï"VöƒÅdxï¿3Ûª³ÏŸûôÝ7ƽ/æÝ<_SQúsW04;! MýZ®!–*‡5‡ ˰rŠëÌBcRF©}»·ùá»æë^RÁ0¿Î]•æ¿üç§j+J&Ø^ÑÕö#þŠX"óúü½·T}n^^ƒ!¤VtÏ[´Èf2,Y±\?¨Á’ʯYCÒÓË›'¼ûÏW%1ÎápÀT–„G†Í&‰D€3Ì?ßÀà`ßÅËV,\¸P(´z£N4Ãðù‚Ÿ8W5e…?Øøíl{ïŸ/uµ5½öÌ4MÀÁÝ;£¢î{ô O¯ŒÓÇcfÏ åó’Et|³/¾}÷ß+×ÞÂ0ôÖÏ?I]kk”ý"‰øí¾Lé{{úN=˜2]¯7lÞôEUQ~ò¬¹íMYÙMuu½­cyO=øá;o'MKdhêëO?2é5õõu¥…ySùacmå‘C‡´½]b©X$‘þ!aá=]íyêø´”™†„‡³Î¸¢œìššÊÇvS$e³ZBÃ\}}|ý\]Ý´CC¬Ø (ãp†)¼[]UšqâHpHEØ´/=ñXdl̰йÔJ"+Š‹b¦&^ùÓÑÕÙÚ? d{øéþ>.—788øìÃúM™8Ë’Y“65œm'swåðxR‰D§Õ€ÍbÑ._ÍaS´·{xxKä./¾ùŸAµŠ/à#„ I÷÷tu´µ676UWW/Y±Zîì à Ú!v5ëtzÖl4  T(¼}ýàÏýMÀàKÍjU¿°hDä’å+ï~èQÀqœÇãA36›•õK0”Íj5›|ý}gϽt力7Ü.‹Ÿùû˧ÛùÕô˜àÙdtõtO˜1'fö¬{z8\®«ŸoöÑÃþ!aÐ߯‹Å¬ª×éÀb± a퀦ŠÅ$Mi³"ÀÀ¤Ó 4â€É¨÷ðpg]$•’¡›‰%  ؇h#.€9 R{½/<ñˆ‹ür¾+iãò¬‚á©TÙÙ 35iú³?ÐTWëéã_WY î-µU! @*‘Ü~ïC<¾CÃBˆÏ峚ŽTî”/–Êøaxt —ÇçryÔѧ´#½||Ü<½|ƒ‚œÜ<îØš˜œ‚aØÔ¤ä#{öP4½uÓçî¾Þs-õ÷yÙÉ®ÕýŠ!e}yiPtÌÇ›¿Jd Pfž=sÛÝ÷Ë]\:;ÚïÙsë}÷/ZyÓ¾Ûú½ýʾÔ«År;ƒzGkÓýxbæ¢%­ µÀ­fÓÄ!„0³ÑÀ0bh>εZmÀ0ÐB!F àÓ4 ª¬,uv’€‹“œ°)ŠäI<<ܽ}¼?ݲ•s©F§5À¬ÕI1Çq@¨±¦ÇqO_?–‡R$–0†[ŒF¸ÿ‡b§M{ÿõ×:ÚZh‚ …oÖëä̛½nýmkÕk06n‰0’¢€+±dm2‘Èb±€•$—/[µ~Ã]Oþå¯\.aÒFÏÕ `Ði9Òë4ýŠg¹|éò5KÖlX´b†ãóæÍ~â…8XšaLÕŽŽ–F‹Ù %%§]3ž¨ìhk¾ZȬ(24LîìÊÐÔ§ï¿Ý×ÛõS–ÕlºiõšþõÆ¡=ûôÚ! ÃXªD>g1›Øô€ŽÑÉz|0 YÍÆò‚Q*‡Ãõ fý8ݵUî^ŸÕö¡=}ý=|ü\œåñS§z¸É•а$a÷Ú§ˆƒs¦ .9¥´¤ºÚšúº³ÁaQ±õ5u×b25–—†!Š"€ƒãV«x<žV£É>{ÒÕÓÛdµP„Íd44T—ëtºªÒÒ¿üãŸÁÑ$1êÆrõô&Ói4E¶ÕU±_.[us~Q!+XgÌ_ÐØÐ@ÓtMUÕ•khŠD =88HX-€çò ²ä"iµ0.ÇÁl2TU”2 c5ßÀ`•RÉ0L{kKPD,†ã<.ǤÓ€ÍFYÍ ìâÌ=öî~ùÿË:wæJ¿;+j ›•n6«Uìâ 1Ãg;÷Êd²‚ Ùb©„Ïã€^«•»y²Z¹t˜n‹ÁýZ“Žu@Ó ÍÁ¹Àås…b1Œ=䉆¥×{z{ÀüEKP8‡«RôJ,æ‡þᙿnþøã’ü‚‘KŒ:»‘‘vüèâÕkV[c]m`p({§mM nî0?ué¼…Kú±˜ÝÇ•Šž)„üëc ʾ+ËD¢ÍXpîDxl;Ò1,‡×‹24ƒs¹ˆÀ0“Á`2ÙõÍåñ!†¦@L@h„N§cº¿§Ûl0…b†Ó #KòÎgP—&ªp²Ùl9ÙÀ †5PÛ[šŒzƒ˜/êïêhklhª­2 AÒ4i2è4ƒƒ4E9t0vjâ ¯¼¢˜¿tEqþ³Qwúð!Àñ ·ß±ýÛͽGäp¹ª¥¢·Ïd0h5C½íf£añÊ›N;ÚÙÒtîÄÉÊò2³Ù¸lÕÍ»·|£ìí>uä BH­R™ F³Aßß§êëìT÷+x|Qs}cÖéÓ|>ùêõûv}WZ”W—…:sê8NÃ-ïˆ%—xë«ËN<ÈÈK/P9 ×:9ÉósÎ_u–¿xï·žÿ+s©.púÄÑôãÇm4”],@îããS”­èéüñQg'îí陚üÄS2Ó+‹ ÃãeNÎÓfÏ妤àaµ4ÕÖ¶54):Ûûû;ÛÛ‡TJ›ÑTZTpÙI‰9 R;Û:¬S]e¹R90Ūæ†:½V}údÚÂå7å_ÈÁú×Gÿµ˜F=!äpì¥ ;céM«»ÛÚmVKvE`^¯`(’(ÎÉôÓhuÐÕÙ[]Rxëw¾ýÙ²3Ùö­mm÷=ñ‡»{ª¥©ž}¡€"ôÚ¡ï6}ªêSŒ`µö5b8Çp^Ÿv2ÍÇÛ«§WÑÒÒñðëhëØ³mçCúc}}}WGûžyÎ`4íß¾Õ{Ê”ÞÞ^Mo÷S/ÿËhПN;%“Ê‚#¢ÆvqúTeqáš;îPõµ·´ ¹ø¢›V E’›¿r’Éf¥¦ž=~týwؽfPBl|kw7M£ÔÅ©ŽêªªUÊåënÁqNc}m[sclÂ4_¿)¬)QYZ2kþBŸŸžvÊÛÏW.•¶µ¶»ººp¸Üˆ˜¸žÎ6Í Ú7 HÙÓÉåòšëë,^,‰›kÅ9ƒŒ&³Ù$—;ùø\Ì» s’‡GÇ@ow—²¯'6!‰Ãá’ÙÑPOQTøe$Ò ÓÙÖÂá !`ho¿¯>üâîÇŸ”H$WβÉh,¿˜7sn*†sF‚G-õB‘˜¢H.—ëåíûÖ_ÿ’0oþªu8p=Žƒ¥R(‰Å0›Íf“I"•6+Ÿu2 Â0†al Æáðù’$ ÂöC¹”˜,ÔT\ÌÏÊzäéç.[0AÈœÀl2©Õžž<H­²Ø“Ñàíí#Khšª(½(—Ë ¡èêNž3[Ù§À¹<Œ¦-6«Ù` EšAõ€zpÙÍ«/‹57Ö_ÈÌ Ÿ—ºÈJ?ÛÝÙž2knxT´RÑÕÑÖÞÐP;oá’€ »Ó='}úœ…znû7_üéÙ—ÒŽ,ÉÏ{ú¥W¤r»f”~úTk} ‡Ë_¿ñN©“ó¾m[††4ÎNN·Þw}U…¢»‡FˆÇå¤._Åú°ÞùÇ?tÝ«ÿy?4<’°˜ºÛ[H@¾þÚ‚%K7>üø8«ÇqŒ-ƒÅã4ÍårãŽ!Œ3Z 0VAà\iýÎA¶3Ç©ºÚ–¬Þà|ºéšÊr³^›žÇã+=JE_t|‚É ÿîë/ú:;‹ r"¢c»;Û^ûÇKļù¯×fÏžõòsu÷p5êoþýo3fÏäpyŸ½ÿny^/;~p7ÎP åද?»p>|`J¥òÃÿkÁ¢E<ÿôÑcß}ôßð¨ÈUI^vDìÔ¢œôè„ä-›7NñC\þç￳då*“ÙüÅGÿ'•É\Ü]?yï„iI"±¤àüY¿À ­Ÿ}œ8cæ•5‚¾þïÿíÝöíÉýû,]λ¼"SSUùÅ»o/_³¶½µù½7_7õ÷[HtüÐîi)3išÊ>}B= ÎM;55ñøÁýýJ…Þ`þ?{×Åu}ï›™í»’vW½£^PHôÞ{uÇ=Åq\Ç5±SíÄŽKlÇ›^EB!$„ê½÷Þ¶—™y¿?fµ l'¶1ü²çããÛÍÎÎ̾wæÞûÞ;GÀÿøŸ7ê4þÁaÉIJKˆ½<=¿üð½Ñ჉9™tH(ä;¹¸íýêóúêÀ&_ÿà”Cû.fž+-ʈ¤x¼‘á¡s©)5••&“ÎÅÍÃÆSRB C3ÕÅÅ™gϧž8ÞßÙùÞÛïíúèÈ8™²ýïo^¼pt×Ϊòrk=«¿§' IJ§¶ºbJ E ÷ßzãÐÎ/¸ª‘¡Ï?ø‡ÑdHÚ½e™¼ËÓRŽ»xx~òîÛF½®47Ç^á˜v4)#5Åú°záÉGw¾÷áŸ^ù-·¸\.W|kéljJdLœÉdȹ”…1ûùGïÎ]´H&“¦%€¯?ùÂ/8$iïçáÑgN¥hµšYó¦IbÆÑÕݤ=¾wOâ¼'“ ôõÀïÿÃgŠŸ§¯^§—H¥R{‡úꊮ¶ÖèÄ™eù9@*³£Xzç¿þ?kîñ=;ª‹ -]þþŸß4O¦­Î0ô_Þx908X"“Ý¿ÇhÐ'íþ*aÖ©ÌþØ¡ý mn¬-_¹nÃÕ+—(oéªÕ¹WP\âÌÖšª†šêÕ›6ïÙþo†¡½|¦”^¥Í¦¨¸i—ϳ,cÐéZë®ZSU^vó÷…NuP:žKOßöð£gOW ­¿ï¡‡öa–õ jµ:4~úà@M›@"k4jˆ›žè°áž‡„Ù½<.q àð¨Èè8±Ü~ÕÚõÓfÍÚñÉÀ0`HO>²j˽>Süîß±zíZ;gç½ËÃ×?aÆtåæé.’ØñÂekÖ:8:Ï\0×ÞÞÞh¢,^dÒëG†&)‡„"„I.X±Â5È746.~Ƭ³§Si³©ðJîÉ}{V¯]'–Ù{ûLññöBˆ+”¡áá‘ÈÉÙÍÅÙ!0NOK¯®([¼aóÍsw1ˆD„=óò«/¿ýÑ‘¡›‹³æ-°SØ#Dø…NKHt L˜3K¯3¨T£4MçdeùLM˜AñøÓfΊˆŒY±z`ÂŒ™|¡V¬]ýà¶ÇäJ§¸ÄD½^a/—©G†`õÆ-A¡Á WnÐëÔ‡îò×Ï:¹8ç^ºGöpáÚ-[“ì½sdûïÆëuºÆúº„Y  ¹ÔAþÀý[IÆKÖ¬kií‹›‘¸`áåséc“6q_g›|l QnÆY{™<ïê•~öÔÜ¥+¹I{wÆÏ˜éîã‹ Ë0û¾ülý¦-nžÞ.ŽÊËçÎöô÷¦=2sáÂÈk$²ùþû—ßï?ÉÐ4HíÌ&ã7Ÿ½D"yëw¿Ã,;oÉ2Z=Ü×S’sÙ¬Òb êÑ‘‚Üìé3fJ$Òè„|>ßÉE)ID"‘T&BÁãñäNÎþQ|@îèh6X†©(.róô´s»yyA(” Šâ“<‚6›‚+•!±±r¥’/â‡ÅÇ‹ÄbENÊ­-¬^ãèâæâæ¾îÞJ óù"1Ç÷ ¾š eE%ïýþµy B¡H(€P(Â!K†!R®”sbÄÜܾ@XYYùÑŸß\°|ÅdE@„?cBHf/ Eˆ iËÒ,ÍI¼@Ð4<eX`Z£Õr™ Œ‰d ø|7g°··kmm’¤tF#477*ÀN&kil€¶Öv{¹ñ($W—Ô¨G€$HÌh˹qŸ[ &óy|NØ–$IN!D f“鑟ý\îêö§—_îíêNËe^AðH¤!wÜ_y¥º¼b÷ÇÝÜœ–éiï<²cwmy™‡÷”É£x@\ŠÀ²¬\îE>¿fÓ–ÏÞ¯èJ° KQ§Ö‹1–J% U«Y‹ˆfhF"‘$Ì&3w@•š“â±úùçjН©Ôš¡³%yU¥E¹ÎMŸ³ð§Ò¿ckXˆ…¥ÓÛ¯ÿI£Òð(’@X"â¬Ò^(æËììµZÝX Y–P6õõu•s–.Ï>{ÆÓÛ×ÓÛ—;nCU•½½ºï‘ÇD ÄrÏ7’G©Ôª™³æ‡†½ûû7Zëj¸ýMC{K[þ…,–aøe}¶n1àÿük¯]L?›qê$IJ÷ÄÅË–,[Æ24‰’+=ÝÝ@£Òp±›Qo M®&g6Ó “ˆ &BH qã&ƒÙ`ÐÅç[„£1Á ~±‰Ì&†OQ@"ÌLfx!I¸Ê´X"c´*>ŸÇéR™FÙdøÕó/,XµæË?T Æf£ÙZG#i¡BÚ`&c<8<€ÍFýÃ=:ŪÏþþwz2Z—ˆ¥FŽ …¸$BˆkúˆGñÀ`4ZH$= ‚Àf#fÙÚ²"H q}ž'k´:P«4¾Sü@ ´"bâz::`dh82&Yé› )ƒNÃÐæ®“A©›M`'•"q;iu‰eh†fy|>×·{º»0˪G†Â"„bÉ™S)‹V¬|óí·‡ z-¤hÚb‘X£ezxhD¯×²,“—uñçϽ0gÑâáþ›™]­ÖDϘIº~jÒYD!î ŠYÖBôÅb¬Qê4š7ßý€'à± m2›ã’Ül†6Ñ4ÃÝ7–ax<¾N=R_YAñùˆÇ€Þ~Š¢À utTŽôtŽôwÜ·/46ž5y$Òétb;»¸sf,XÍQÆliaþ1z·EXz­ÎCnÿÒŸ_ommëïîB,Ö¨ÔÜM7t,‹1€Á`²Ž |£É€J òíí%vv5eåÕåÅ:­å†FNKìêê€ü+Ù&³1$zZ_wtuvEÅOÏ;›ðÎö=]–*Éã÷v¶„e¥§w¶6€I¯ãD]:[›žØ´®¤àêÍg:-]§Ñ<óÚëb±”$yu55åÅ%…2¹“«G]uÅàà@AnHíä­Íýfƒ¡±¦clÔ¨Gz :MowWK}‰Œ©*-©¯(Sõ÷U–•aŒŽN­MMƒ½]:¾²¼œe™ÁÞîÖº†ÑáAƒÁØP_Ó×ÝI›Œ9ç3&€suSºz–æçÖVU´wuEÄNcŒæ¾Î¶´“'ÖoÞŠ1Þ½c»££rîòå€P}Mõ@ÿ@]u…^§ìhmÐ —å`wßòâkå…y´‰Î9J;uJ¡tˆ›3 ‘7f::­º '»©®±½¾¾¯§7ïòå¢ìË#Ãê£IpDL\öù̬Œ3ˆ ’ì3é´e×®©Ôª¦ú*Dˆ?´O&W¦Ÿ>i2áìsg0Ëb€Ú²šòâ‚šŠŠGŸzF¯Õ\¾˜¥RW•]›¿d…Qg̹¡Öh–¯ÛØX[ÅŒ328¥öùËWåd]I>| ~Þ‚½Ÿm7êummB©¬­ªJbçÐÞÖV]\èåpðë¯ ú»âå¬ rKç/Ðf3Bˆ¢¦¬´¼¸ø©ßü!´|㦢«¹-ÍMqÓ¯\¾ì~âØ†6Í_º¢«³ëäáƒñÓ/gfôº¸ÙsϤ$+ÝnZéI’Ô†{lolèí™9oÑÍ¿à‰ÃB"/KïêlojhÎϽRY^Ìš˜ôS'E‰ÌAžwé’·¯ARáQ9ÎõtwuuvÔTÕ\¹œÝÕÞj§PV–—îßµËÝÇ'"&¾©ªêÒ™S®î¹³z:ÛݽŠò ÓÓÒ„™ÙD礟1›Œ‡¾ØÑßÓµážw}öïË™ç ò8/þž®¿½ôò¡¯wü2t×!‚P«4™™™~Süz»;ç-¼xþ|AΕ-=äæ;å¿ýÝÏ<;0ÐáLê¶§ž Š@Cƒµ•e3æ.üú³ƒ‚£§%¼øóG7lغbË=–ÏlJ9–Äʦøx…GÇ ú£û÷ŠÅb™½ýâ«›êÛ:{:gÌ™;Åß"oPSYvõÒEoÿÀ…K–B9çÓg-\Fƒ>ëì'Çé3æÜpö]í­­¶­©1:~º£³‹A¯;{2ÅÉÅ9qÞ|„N«É<›Îç-\(ŠT£#çÏž ‚hmj\´dyþÕÀ×gJggÇ`_ïÜ…‹Eé¥ ™®®nªÑ¡ÞÞ¾Õ6³ ]ZTàí Õé†û§FD•Óf“Â^1¬U‰…"§ÕëE"apØÔIG»Ë®!ŠŠŒŽAÑfSÑÕ\…“S`Hf³ÙT\Xèéíãáå]YQÆÐ ÉçËDü¾þaç`o704Ìð""¢X–­*+qóô6ê´aQf³©¤¨ÀÛgŠ›‡çM#_¬Éd4Ó4I1,C!‚äñ DbÇ1I<"ÇÇ%1Âs4xüà^¹B>骟ª™j5ê·ß|õOïþëNîKã›UM&Äã `LT°#„BmMv …ƒƒ|x ŸeY{¹¢¥¹) (ûûƒC¬Çèé¬(+ž¿tõÿ8aÕsÚ2RëôEÙÉìh @ $É„"H‚ Ë2)G­Ûr¿u5²Ùl¦( ¡fnŽÙd̽xnîÒU\(~úÄ‘Øi‰nw•ËÈÿ'$Ü-J–¯ßôÓÃ6××ýý/o½úÖ½'Ó¼ÿ_Æì‰¤ý‰3çºyþO÷òõßü€ ‚$/à €ã%„ Nd—BArEhnfB„^§å â1ï9’$(¶€SÇLŸ9GijR;{w[ýDìí­©¬JÄN·˜½ñ#wVV­^³y«TfÇÿ_•ßA…Ú˶”°ž H‚$‚@$œÎ B€ IËô÷q©Ëa³ÀØJO(ìÄ ËæNøÃ ¬(¯±®6=åø`_Okcí‘{ zíup£^W^\ØTUâéëÿïÞ3è4v}y‡ßΖFO–aÎ¥¦NŽË>Ÿq‡û9æœÏ;¹æ]ŠÅ,ƃýÃ}¶¶ýã–e²Lk@hÌò €°æ€ìõ“ÝïD° £ü¨Qü Ç1›Œ#Ã:­Æ¨×ÀÕìKÁáý}}!aW²ÎÏ™¿èâÙ´ïER}ùµ‚²â‚ꊲ’«¡aj™6ìåB±´¹¾ÞøÃâ-±F5úÝw¯,)¼|îÌé£Gjª+®ææ*]Ür/žuqwÓjµ˜eÆÌé þwgB›ßójL&#§khE{KCêÉ#;>þ ¦²ÌhÐiÔ£,cÎÉÊÖ©µ:Ößß?7û²S~äË-aK1Ëòpù jM”LÂwò<¬ãIFGU5å%Ÿ½û×ËçÓ¿ÿËK®ÕV”~ÿãtwvdgdþbë¦+Yç°V£"’Ò5šÍvöMMMß½;–\Í9zdw{«uÓàà€N§ýç^W(ÝÝ=,ËÆLKéëݸaØÙÙ™ŒÿMV Ÿ;}2%iKcýwéá_|üþ¤R ?|ðÄý…BÂÄÉ¥Ìsþþ,Mc† ÖiÔm­,Ëxûù7iÞpnõ‡’ÜK»?ýèûü^]­-™ég’<&źÑË7 >>¡´¨ 8”e“‰&y‚˜é SÃË‹‹’¤™ÿÒ\¶²¤øâ¹³í-ßeçÛ?½ .¶wn 8ðqGU®1pr1Ü”÷IþÝq¨(-vu÷ðò™­Ñ¨#¢b¿ÿ1gÌ]Ø\_û­êòß ï)þaÑS"áœEKD,%ÂÃÝûÜ©S‹–¯Oßïx¨Ö†Z¥«ë† ÷üóo2hÕÜFw/¡©1q.îž^>¾=¹—/Þ·ÿdr28;;Idöß‘ '¾9wêØœ…K¯Z»óóO¾õ)EQ”÷ä*@Ï¥­\»nÍ–­‡÷î°G —_ËŸ¹p./ˆˆílmrvusvõ˜3m¨¿ßÕÍÓ*X¤./¾Æ‚± S’—ÛÕÞÊ5†úÚž®Ž‘¡ñ`ÖlÚýÕv±D6!¼5èÇnÔwÄÙÔäÙóæmÙöHÖÙ3Ù¡¶¢4<*Š¢xB±#Œ É¿œ=sî‚þþÐðð AžuÞ5Wk¹åÝkm¬ëéé ;°ã;eî=}ý·Ùå÷",.@! €'Œ bNqÂÜ+⛟l?8ÚœŸÕÓÑÆýèÙç3ò/_âÚAeYIyQQgÛx`R˜—3sÎ<àÌtz‚¢rΟ³þµª¬¤àJVGktµ·žJ:XZpX–ÉËÊÌ:{&gBDÖÛÝYU^ÊÙÕ…ÇÆ—ä_ýþ×R]VËÙšMñìéh›±pÑÌ… }ü.e¤/^¶ò;§¦²¢àJA’´ÉÔ×ÛcÝ^WYáîå‘1qu•ÕÓgðR¥^ IDATÌþý»ÿ|ü×Ï·57ºyúX£•ÎÖ¦Œ“GÏ¥œ`YV£=s<)õD×á¯^8—y:%ýøë1‹ ëª+c²¸f¦ú×?þÚT[}‹”|rc÷î®î«9—ÑFÃÄæÓPSA¡S5Z=ÄÏœ¯R&ÌYÀí£×iÒO§øLñM>°ŽìßéRRT048ÐÞX7¬Ò4ÕÖܳ{ÿÖK¿èéúî?–X*ëéì Í&ÎÝŠüËY± 3!","¦·«=2~ú¦· Åb£^b!¬Þ®ŽcöM9f2èý©C{Ï?ÜÖÔµ¥¥é)ÇìÝa3d̾˜æâîñüëoq[úº;ÒNëëîœôÜì¤7û•ýÏ–õçÀ€¸™¢Üh€« è¦Çïm[¿úôƒÐÈèsgNÑfSÊу ''’Oe=3ØÓI›.îŸÿë_c]…朊«+J§FŘ´#í­\áv°¿§0?7vúÌ_|²LÚÉc«6ßÓØP__SÙZ[áæå“XQZÂÊ UŸ÷ÊkìXj Ö¨Fݽ}¸·¼ ¶ÌJ'—‰µy­Î­ßrÒÅmh°O,‘$O32,+—Ë_îio?ÿÅËWq‘ P$n®¯ïíê^¿y fF@ñ²Îgmº÷Þ1r×|öÉ¿x!ÚKyüššòádfhƒÙÉÛcí}÷[[KSMµjT³`áR†6sBei±O@ èÛ˜Úd¦íÅb¾P´ùžû"HD€½\ΰØÁÁ~Óƒd_¼XvíZèÔ(-)ìëéënoVŽxÔòM÷1zmâìy&½¶¿»ÝÙÝ›ÇãGÇÆ ‚‘¡€HR, £Þdç`G …Ö®èÒÅ9 –êU#&ƒž/@kSƒ›§—ƒÂé[Kþ½CCI-]±R$>ž´hù*422LÓ&’/zåé_¹Oño0<ᆇ7ú…¾ôôk7߃ ÉHO[³y«õïþù÷Zõ({G綺ªÞJ B&½F­~ö•×9KªŽÖÆç~þèáÓ¹h:û\úWŸ~¼óØ)î ±ë‹ ZÝS¿}í.',l)¬[$ô1¾¾¸>qå q›—æ „X3[xx¸§ÓÄ`†aHŠbIB§Q=ýòËý‡÷î‰Nñø$I B®©uuv<ó»×Ø‹ †©‰sÀÍݳ±º’âñƒƒb ƒ0šL¾~þuÕ¿yãMã“GÇϘ‡¢©¶ÊÝÏÿñ™ó*Š‹¢§ÍÀ,ˆ$7œ[meiÑÕ+|вsô÷Éíd3­×kÍFzþ’e¾Áa7ì_UZìãëãêî€+JŠå …‡÷$E«øs¦Ïžÿ­··èÒùøY³úº;Ì&£—¯?T—•xyyKí³yW¯‡:(”7Çç–eY™]mi‘\ᨕ9È.n˜e†Þÿjwq~®V=j¯p€¡¾öÆÊàðˆŒSÉ›·=1:xñõßó"¡Dúâ+oX;jꑽ«¶ôèã<¾p’2âœyIûöø‡]<›¶ù¡Ç<=½Zj«ÊJ—¯ZS^\8Ô;¸hùòò’"nçËV ôõd¥Ÿéjo›=º†>ÿøSftÓÃO8»{$6æ†ù ÈÉ<{>å¤ÜI§}ùoïÒ4]UVœžn'‘5×׸zx;|hýæ-R;‡I®»§C›%RÙÕó™qÓ{{:핎îî$E‘À¼ûåW—Îgtµ5yûÀ¿),Ë’$I$Æ,˰%%E‹W­*/)rruã ,žù ŽåY†þòÃwÿÕÓA² c2™¬±î^Sþúþ§ÖÜ?<&îéß½ng×m¹ßl°ªËKüƒBn2»¾ã k¢XƒeËŒyÓ# ™Yêî±·°äŽ.þA¡yÙY=Ý]³æ-xè±'Μ<Z¿õ^†a“vìš½xATd$AR@òøŒÉ„1ÖŒ‹e2š¦[ꃃǢ¸¢ü«é)ÉÍè¦ûš·`éÉ#GFGîÙö赂¼ò’4¡@èââÂ¹Åø‡íþò‹–šº•[6@_owpXè ç25:djôw¹ ³QÿÅ¿>ð =qäðÚuj•N§uqs碘ëRô›Û'K- ömÿÒÞÕXxáß@ꉤ¦º&_ÿà’+9Q3fôwuùùù±,K7}ÿËç›s.Åhúœy¾!™©É±äž‡3Ñ´½£sòá}v2{»i3¸ýÏŸIk«o¼’WäëãR8¹n¼÷Êâ²MnãÙ¬N -:»º'=çήÎð¨X‚âFÅ‘_«Q§Ÿ>;̈́ٺšªˆè8…LÚÜØà|suÆÎA¾õ¡‡s.^\±a BhÃýÛ:ÚZæ.P8:%ΙϲlaÞÕ„Yó¬ûë´šðøiÞSüúº{œ\ÜgÏŸ>sm6ÿGÓÇßÛó/$E›ŒAÒ´±º¦né¦Í™½X$Kí줢žî.o¾€ ¾nÀ½Û?“r‚63ó—-—ˆÅ'’•®ßr?ÆÐ;¨:²û+’'˜5×’Æ.[½>3õd]yÙƒOü’ ) Á/(ìLÊ)ÿÀ@Þ˜†½õ¶©Ñè(ŠÏ½žØ„’ ‹°¾U8:+' ´1Ë~ñÏ<úô3‘q wa!}WArÉÁe‚$ $i‘m y@XuÜÉ óngaŒÛ[[$2™Réý}½´Ùìæái2HŠ×ÓÛ­+D"1·óåséž>¾Sƒ¹h‘eèú¿Ùd¤x|®v€ñu†Ã˜eoð¶Â˜å‚öäCû­\-ý®£lߎ¤½_»8;)˜»héqÓŽìÿŠ*:~º_PèílL˜e?~ÿí_¿øêúA­ZuüàN¡D¾fÃÆ›ƒÙ;˜ewò¾ÌÑeÕ†¡øö~7þó«/¾þ·~ÏÃ\½”éâìæq׎Z-KbÈ•±Æ5‘¹¥9p;ç4 „¼}§plNÎ.œ _ $IÒÃÝÓÊV0sÁ¢ä¤ªáAîznŽVx|õRo°øA7#[5ÕV»¸ºü€lzΤÑLŸñ£¸ltšQÆÉÉÑÇ/àvwcÀQqÿÅk+J»Ûû¥owçÿoÑß×Cð$c¾9F¾ ]ÂÅåûzÑ&cS}³«ûÝ7JhUé›P3f'GÆ“ ÞY IêÉ_¿ Õé~Øgiâ¼Å?àµêQ¥²´´¬½¥éǸ Uå¥3f¥'§ÆÛݘrþâeÿÅDl~ø!±ÔÐݱ´¾¿¯oÑê5£z£µ~t;ñäs¿û¾• ÿÞGv·Üíë˜H×YK$")Š" I ( )ËX!B@XóA޶nH mø“\l™Aòã!›¢† ÿ?Apj£–eÏœOª5ÔŸ3‡'ºƒmñó÷Lr"~¼‡›­løÿLXœ`·t³V㜠Ù!¶¦„h”QgÙ`ƒ ?a±³,ËŽIŽñѸE1Ak”½ir– 6Ø`Ãí",D ËTQÖ¢âw]ÎÇ`öz#Ul‹°l°Á†Ÿ†°#Œ D¤¥þq]Vh] 7y>ÛhËl¸­ Ba„gôŒ-ÓÛ0 I€µaá›^Ø`ÓAÇM×iÔz½Nj/‹%¶ÛrWEXa À"—µÐ319d®©Ð®>zwA«V ôvçf7 ƒ]í-wþ9—ä_i¨­>}ìØÙ”ã5•eyÙïèÓÅ83-U3:ôïÞ/-*ˆÄiGÙÞ]FX½RY–e9Šq-m«{=IÙ¦býìíÎɺ –Ú?›Æ2´ÂÃ=+#í?ç¡þ3ÍŒN‰jj¨ lª«»ÓLh³Y¯Óê´jƒNÓÚT§trÒkuÓÅR‰½ƒÂh2šÇD©l¸;RBÀ€1‹®^e‰° Y‘c!âæ‹þ”N_cjDf/ÿ¦^4Ð'W8²,Ãb Iâ{ND6›Œ:ÖÞAñƒœþ ÷­¶¢L­Õ#Œ==ßÕÚèìéÑÛÓEñù ÕZÖ$É2?¥nw{S}Á•ìœ ™çN·nôT(:jñÊu ؆Cû÷xúzVWW³´E¢ÿâ»ÎŸ:ÙÓÝw`×öÃ;·Ãïk‰Fúðd^s9ÎÎ^°@®”ò?[7ÆÄM÷ôõ›³xé”àOoï¡¡Šk×jªÊUj5A’b‰Tò_Õ°úz~ûËÇÞùý«µÚF"·•°¬KŸ7IÚ^YåÜ 1Š~B_B¿=É)·|c|9óìÜ%ËAÌZ°„$‰ °ïù<ëCÛöïÚþ=SQxyõ¦{æ-]þÙ?ß¶nE uµ3,D9¹xª†‡´ƒƒr¹S}U%Ƭ\®´Ÿ 7<ØgͶúz»û-vR:ͨN«¾Áÿ¥×CB,_u<)‰¡ÇI¤¶¼Ü?0"câJKŠÖo¾§¼´èž‡G©p[•FCuiñèÈ0`–Í»xɪªÜÖÜØ\[=2Ðk ¯jêëü‚}|¦Ø+Üï;2<ÔÞÚ2é0´X$A“<5qVf¦I¯÷2¥½¹yâäçŠkù¡‘ÞÕÖ6é _øØ/Ÿíëìruó°®7›Œ9Y®fg†eÙÌ3©§å\sjK‹ s²+®Z!R±øÉ_=÷ÀOúYô‹F‡‡®^ʲqÊ]Äd µ8Î"`nÖ;Œ©²clu[g3¨F‡Ï§&gŸKomªÏɺ—“ƒ1›zòDÑ•K%Ws23ÎX­ëú{» ¾ãÖŽ–†Ðˆ¨æºš/ßÿ‡•ήd?|´»£ ®\:¶×ÕËY0<П‘š|>5¥8/{,¹ÐìýüÓcö1´™/Qotxðæ,†ûj–1³ŒÙdЙŒzF­VÞ|ªªë›êë„"‘Î0¾ yt°ß ×Ê•N°d՚ܬ‹¥rÃÛÂbâJ óæ-_e]dsáÌ©ºšúÌÓ'X†¾|>£¦¬¬²äZmuÅð@_ö¹óE9W?xçOcUHæ¿{áÙÇŸÜõé‡ßóÎË•Îý}½´Ù$•]§ ^ZZ;c&(C"–­ÞÞÞÖdUaÇ,{ìà>¥³ó±}»0fSŽ Šonnl¨®Ð¨FFúù"Ñþ¯¿‹bÑ=4<¼dùÊŸòð??Ÿ‘þ»?üeïWŸùNñ­./™1w¾J­ª,)æv.ο§V ô;»º7ÖTÅΘs]“–ÚØÚÆ#H^G$kg'ñ4fÖm¹÷†²Èoÿð'8´sûý>1Þè«+”®.ÜÞ^®X²v½õOÑcúy .ÎÏyá÷ûì½·Í&ãÙ”ãoþã#“Ñðé{}艧êêêf̳lÍz+†„‹•³çλuâÜY]YÅçMÓz $°ˆ¡MˆÅ4‹ç/^Ì©h&Î]©©÷=ò„õG×kUƒ½ýœÆ)DÆŒûyûŽ«Ù´4Öi‡‡ÝÜi†¥MƆššµ[îŽ?´{ǓϼpìøÑày‹·B>?,6®4ÿjæéË×oÅSIø‰³-WQpåRSCƒHb'‰+Š ::;ô: Ë€‘G{œS¹ó™âßÕÞ¦V¯^¿Éº¼º¼,($ÌúsX)ÀÎþ:±ÐöÖf{¹ÂÕÝÓA®¸|!sÙªu$I555ïüù ‡öìž½`¡UÌsJpˆ½\ɲìïÿýÇ)j«×nÜh‰×Œ†c‡ö†O‘b¡ k0Ôz£ÜN£¨ÄÙó¸P´¢ôÚåsé¿|ñ 륞Ðëk7ßcy{ú¤““sô´DO7«Õ3'1c ²¬Û5d¨±8ëöIjL }î±GƒÂBï{ì1Ÿo4êÀÁÁÁÁÅYîè"‘J¬Np*ÖkLѼµ­=&að„Ë—­à¶”FEǵhùʦ†:Ggpqu+,(ˆKH|ù×O‰Dâm?{r¬Æ]Ì<¯7æ.\4ÍÜüHŸ·dé\ËÌÿ±»gICO0IÒÚTQ›0€Á,ÙT––LO'Á[h5 yð‹^¢ &A$EAÙÛÙ/Z¹2%)‰eéè¸DP„F:¹¸ðùü% ­)•Dâ„YŒ(cl0hÅb)fY³Ù$œPÓ©/)ŽŠ‰íëm7´|¡Š‹ ¼8‚À˜Ahòs6™Í|¡=ñ«gÌ$‰HÒ¬Ó<óü‹M §Ž'‡DO#IŠ6›îßóøSϺyzfïÍ\¾~kWGkxlô´„™-uþAa;}FÌ´D.[¤zÁ²Õ×?MÔ#Cƒý=s—-Í:›ºxÕîÚ+‹¯EÇ~'‰.!_!a]5U2… ÕHìrƒN·nÃF©ÂñÄÁê¡™ÂöîØ¾ùÞû•N. &ÁÈð`OO϶'~VSU®tr!)O ¼gÛã×`Ð&„f1Ã0Ö1©Ì>*~œ\ôÚqq$/ã·Uôþ÷",„0˲$§`ÇÍåfÿàÝÐàPà $½áèž]zXúäÑ#kV¬-)*vöußtÿ6@ÄÐ`nÖ…U·¶45T””¥?±þþû¼ý€¡é´ãG(±È]陘q:Åh0˜iÓºÍ÷=•LRi6)=½¢â¦€Z5zöÄ ­F»þûíìv}ñÉ~ M×Ö×¹8*Ž˜e(?iïWº7{ëAý‰ uƒ£Ì¤˜e™½_¾dÕºõ«+J£gLóóõ»“ÙJÕÙÆõÖ·å× £ç$fœ<Žnûú÷Gõœè?Ÿ²Àâq.âb+ Ë× ËØ",l°áöGXaŒâ&m€8©XzB8uCéÊÆY6Ø`Ãí%,ëô –ŒÖÙíȲ[ýrØ nõwiVˆ1c[î`ƒ wk„…ÆÌ=¹U:œ–•§n`%t÷ÇY‘|Ûoƒ wg„@hÜa‚«[K3 nëõ„eKm°Á†Ÿ‚°X–eY°(4p§éŽÇ–¾\cMÔóƒ›^Û`ƒ 6ü¨³˜eàVàp…ĘDŒ1×cRo‹ïl°á–°Bâœ(°Õà™¡ÁúMåæ4°?é9Ûb:lø_%,.^!1?„Çc+ |êÿ_Y= ºŸÐ“J52|dÿ¾ªòÒ£G–ÍϾ€ÙI Ãý_~ø^Þ¥óÜO“vü é'²¨Ê˾ðâÛzºÚ «½uÿö/nÛWkÔª}_žz"‰»[ýå;®Ž;­i¥?öΛ¯©F‡oÿW7ÖV——\»Cîƒ^§åDaú½… IDATñPÂâÔÉ1Æ 3ÐÕuùRÎh¯atXÆ V7ÕÖX¦Âï\,íÄ‘¼ìËwJªˆñ«OÿâÂÙŸÌûO"“yz{æ\8ǽ5k5Ü “Éx1óœÙl¼ù#r¥StâÌÆÆFÀ€ÛÚ»ucŸºÍH˜½À}Š?§*#K%v·Ï±ÌA~§Öš 1k¾Íª;J ®\ÌüqiH«þŽOÊßùÓñ};~h²LĂø¸Æ¶®äÇY–ikiJKNÅ gM4øšj}WšpvópPþˆmëZÎ%“þ;w`„ÞúçÇ –®ü©Ú4IR~ÌX$uöô î…@(zéá &7ËRʸûñógžwP8þ<Ï~çgÀø[>ŸG›Í`oo·vó}ãÏëÆ2Ìwc±õ·rÞˆ4¬ÔÎN(•Ë2ÓE"±…ôÍÆ‰{Ò´¹¿»ý6!“QOÓã–æ­õmM Ö¿šM&½NË}M›0m6qB³4m›Œf‚!˲,Ë8:»N¼]×_ÔõüßXX†ž´ëmz`ÛÏŸûíÚts²Îk¿›¹Ùs¯üaÃþÀçÕçž@ m.Í/ŠÅ>>Þ ¥£F§ñòâèá9}îÜ æõ0aºÞœb C„å¯c@€a–uõðttt²ªq®3œ fYÎhŒe1€EHÏdÔ#‚€[(U€A¯+ÌÏ¥!µ·WŽ|öþ{nÞÞT&»EP…k«+ „0Ët´5776Ie2‘XÜXWc2úúú{JG–aJJŠô:CÓõ55a©ÌŽ6›ss.ëT#|_ Ý¢ 1E…ù³í­-½½Ý ¹"ýÔIÚlprqÓk4E…ù"‘°¯££¬ôš›»IQ¶´ /aö¼Úòâãö©†ƒƒ‚ó³/¤L‰Œ‰ioi:~ä00æ†Úêò²_?’¤tuEEy|ŒҼ]Ÿ}-뮓0x^v__^öw/o@xîtraÎ%݈ª (Ÿ¬traY&-ùhWOOeqA@PHeyÉÞíŸ"J‹òfëª*2ÒR …ƒBÙÜX_\pµ±©i¸¯ÛÝËŠs³Ý½¼ärÅößËJ?=sÁâžÎöôSÉ]Ý]yW.MŒAU–]¹t¾äZÁèà ÷!à‰¨«©üäƒ÷ídM]m}ey{kseEYcMU`H\¹pN­R]»š#µ³“ÙÙ_8“ÚÜØ¬êëmijž1aeiñ?Þz%6.^"³?üõç%55ΜV*•J'gµjôð®¯)¡(iß®˜¸i·Òtìlmj¨¯êì(.. M9vÈÅÝ]5:RU^<Å?èRÆ™¾®v éü¼+¾à¯üvZ||iéµþõ —,S«Fßçžæz#ÍìÿúóȨ(H\WU–uî E3ÓÎÌY²Ìh4¾û§?øøNimnÚñÙGqÓi³é·þ}Ï@oanŽA3ZQQVxårxTì7ôÒâ¼ö–æ¶æ&±H$ŠïßÙÙÞY|-ßß? PFZrCMk2Ð,ûŇïªF‚ÃÒOéljЩG‹ òœ…"qÖ¹´¶Æ¥“ã©cI#Ã^>~ C_<›¦U«i³^fK·àÁþÞŒs§;ÚÚ¦øôõt}ñÎ;Nžž:­Êjé6-Ízƒ^"‘ŽöUTTðù|™}w{³ÙlÒj4]ír¥#B¨µ±c–@¨¥¹"H €«+Ê€¿Aƒ“°Ì E¤ÐA¾sÇþ½Û¿îéï‹IH Æý»öþúkŒñd–9–õ5U§Ê;—ÞÝÙÎ2Ìî/>Ù³ûë£ûw :­Z•u.ãò…̴䣵Օÿzû­ý;>€ÌôÓÿüãï3S“÷mÿwaÎeŒÙ”£Þ{óÕÁþ¾Ã»w~õé¿ ¹®ª²¤¸$ÿjòáý“ž7m2mÿ䃘¸é•¥×òsÍfZ$s`Å£¨[]jAv–R¡¨ª(KMI–+ r.ÕVWÆÝ==ï¼ü³õu5YçÎÔCýû¿ü·½½}WsCê±#píJVtl¬Î`HMI¾å­$¿üÛ›...ÅWsS÷ï]¼leÒÞݽÝB‰¤»­¹ª¼Ì'0¨®ªrh HŠbÍfš~ß} „â™ó—övÆ>~¾^žÒÒgÍ_ôÅï€D"¡xDÅ'¸¸¹¢[‡·,CÞ»' $$4<2ùÈaX¼rmQ^þÔéÓgÍœ•vò8$íÛ%ç-XÌç 3RONŠíhm ^¸tÅö÷ÿ1}öü„YóÒÓR ²(ßÑÑqÞ‚…'ìåFcDR) yüû9Fkª‚EK–—䛌zÈ>wz庫V¯9vp/CÓ“žgPH¸·§»Z£[°xynfFHØÔ•kÖç\<Ç¥¹—C¦FÄÄ%¤Ÿ8f2ê¯]Ë_¸|y̬٠005:.<*h4[6lŒ ./*€ gRœ\\¥ör‚äf_¼Õ]êîê*̾äÊÐæ¬Œ ΀Hª4?×lÔŸ:q,aÞ"R D€¼§ø‡„RÁ¬¹‹\]†‘+—­\!ʦϘåîæÚÛÝ©ÉGW­ß;Í;$0–ÙÙ3 7M ² #’È/[Vßܘ0sneI‰P,[¼|M^vÎ7Ä¡­Mé)ÉÓgή©ª¸‘&w/_³ÖwŠßÁ½;º;;(D-Z±¶¡¦ÖÅÍcñŠÕmM-0wÉŠÚÙ+fÎ[°óóO`jdLÒž]R™Ã‚%˲ÒÓ º¤ $|ªÂÑñÔѤ[};m6íûòÓË×JD¢3ÉI¡È',ØÑÉIáäzóÎ}=-5í-Íw|)”ÈšëêJ ò0ÆeeåÿxíÕÞŽŽ¾®ö³ÉG ·¯ïÓwÿuuvOÚ-Õ¥ ¹CQAÞѽ;¿¹èŽ1ÆBQ±1÷ý쑎޷~óZúñ”€¿jͪÑ>„n˜)Ь…#Cƒ_|øþŠ[;{{ÓN&g¤&Kíyôgîž¾þ²¢äšN«ž=o»‡[HxD¬¹æ/Zªí_´jݲµ r"–­Ý4¬Õ*\f/\¨V« ±¡¡¶¢"8|*gÛw3ŠòsIŒ+‹®J1¯¢¤Déè(ñ#""”NηºTƒÙüÞŸßtuqŽŸæ WzúøÚI¥€Pl\¼“§‡w@Д€ ¾žn‚ C§Fñx|ž@èêí# € ¨ßýâq³Q?köœoH3ÝÜ=ĎΎήîînþ|¡ÐÃËG«Õ"„¤2;‘H„â øœÖ3E’ôØ êïµ* Š„"‚$B±8jZ,A G§²k€1"Æd'È[ë$õôo^©(,¬-­à 8“ptq‰%b‰”¦ÐÕÑ .®.•ÅEàîî.W* ’tñö"IR,qëáç-[ÙÕÝS’_ÀŽ È 1Ei†¦@ÜŒY<Š*++Ëêê«kj[:úå3Vƒ¬Iï›—_ðe…³ "“‰ƒ^k4BMM­Î`º÷ÑÇG‡°™áˆž—™¥(Š„ÂÂ#r³/Û9ÉY„@o0Æ%$øz{þâÙçæ-^q«oŽˆŒ ‰Œyþg7ÕTjÕ*7À఩ϼúGõèO @yûÌŸ¿xÄX–AQc)”  H_ •JÍ€6 F¨5ÎÞ…¦– )O_@<ÊÕÃxyC"|]½ª*:2V¬Ý0kþâÆª ///PÈÝήnW._zýÙ§b€âQÜ$Iìžþ‰ŒeÍà PJå2@H$‘šÌ48ºz¾þ›‹r¯Ì]²ìVßÞÖX§UWT”isww·ƒ\a2ý\\' ¯F††R' (jÚ¬™B‘8<"¼¿!´hé2{Gyxl¼Ï¿þ¾>Ÿ! B‘ÿ_¡Dƒ#;ÿýñ”€€isçsÑBf“±½¾nj`À‹¯½ôØó¿***îï'ÖN&à ;1Ÿð?*++±—Ù!„VoÞºíÉŸ7Õ×+rP8¹´4ÖÄNOh¬­yöñGÍ4mf0'Ê™Bˆ £ÑÄ%S¹x’4 0wþB©BùÒã[ØM&‰}dâìéËßóÀƒ`¦$Iõw·ÝêRãbb{ê™/?ùôÊ…L0›Mƒ¥vÈùV!Œ¹-Vî IÒh4@À”)¯ýíÝs©i)IIß\™Ò™h®Mk,~M¬^§ãj=\¥ƒeYîÇǘáKÀã@gc-Ь¥®83š6)J@ˆ¥F3V+‘Ôî–F“ñïo½7s¶‡Ÿm2öu#´Ùh¹:–…BÉ›jdÄ' ¤R"HŒ1C3@3ŒH(€c÷úøúFDG³&¦µ¾øʪڡ7 +ã AQQ2¿­¡†¦Ívö¡!!±ñÓ»ÛY†¾Õ©ŠÆœ$H®:ÊEŽR™ƒ¦FDøªº;”ÎfÚ Cýý½Ý=cwœ0øìé“ –.ïïî …-•¥S£bª++ÅRûÑÁþ暊[f͹!aaŸï;<08,sc„LFI’ %EŽ.¡€«ÁU”]B Ä€Œ:mOK "®¦Á² mÒ€LjgÐë0ô57s^^b‘ˆ$I̲}Ý\»2ªUJ¹D·…ei¸5a¹z{µwvZÈ«¸ÀÃ/ `†‡½}|Uƒ/¾þûŸ¿ðÒ¯·€^§ZJ˜«bšÁÜïÎ'\qÄ2`B¢w?ù´³­óä·–U+œ]bã¦Í_°dã–{@,à$9Ø3Éà¬Lö‹_:uøà…ô3\¥U àqR;{ƒ^$ApŽ IÚ €¨¸iK×nüøooW|KÑM¦ÆššÑÁA‹ãb熒|!ȨUÝTµêaa‘P„HøaKc­ÌÞÎd4Àp_“«gCeù“¿~öõ¿ü-õØaî£ Í‹±F£æŠJ’àxA(@og‡T$€²‚«‹—/ç˯Êoø·<£¢[›› @´ÉX˜›fµÖ ÿ?ö¾;>ŽòZû¼3³}WÒª¯ª%Y²-K–{ï½aLi¡’_nBnzrÓ.!:ÆÁ¸àÞ«dK–Õ{ï½o‘VÒöÝ)ï÷Çì®×¶l„1ÆÀµ¬°èF_õbV–¿¿ÿÿ¾ño©LƱ Ǹh†f†ah§Í €ëðÐM»$R¹‹eX–)/,À,GÓ®K—2 „^ùãŸå7³ZÌRÀ.—ËåpšÍ&§Ýf5tẔ ¥Ÿ¶·Çjìéíjmf¦½­­¦¢¶(?‡GjÊ‹-6[KcmogqÎeŽeÄiqNnO{ëñC·=ýfÙ¬ çÛÛÚ›êkšêjô}™ç6ëØÔ)GOˆ»œ•a³Yû{º:[šõƒÃ-M…y9Ý]}ÍuÕ[úNvÖÅ3ǬÛrŸÑ kªo¬.-®«ª1u45æ^nilni¬MJN½œq¾»»-04¼¶¬¼¥±¾³­ëÀ§{»Ú›Ø7:4\Z”›œ6½®®¡,'+mÖÜì³èÁ'žúxLJ{v|à§Rûút]]1tutÕU–75Öš‡G.eœÉ¿ta¸?I¤ë·Þ›qæDi~MˆDbÉÜ‹÷íü°»¥•IJòsšêªsgΜfhz骵'öíILImn¬·³8yÚ ›Ízüà'ÕåñSRot¾’Ó¦wµµ¥?”:kBÄSÏ¿púØ¡ô“GÂã ‚xúG/å^ÎÊÊ8—”2Ö®ßxæÈ²’‚ ½ý¿r9lƒºÁîîî®6ƒÁðéÎG†‡¶=ùì¾; ³2B£bßýûßs3æÎË8}²²$/!iÒ»o¾f2ÖV•çdfUäåé´'ÌÊ8c³:wíøðFœ•4%5(<¢º  ûü9•&j庵ÕUÙ‹s²ïyà!ãððåô xêôéV³©47§¦´| ¯Çf±8,V›Ùd赎Ø,f„ ‘Íbj¬(7›LÓh]C}_Wç“/üP|C³¢øÉS»{{L£Fmo~N6ØN‡ÍV樽ºYÇ4:d0üêÿ P€XL±fš I™„–e) ïÛ†\_YI;œs¹—.Ä'LüËÛïC7-íª!Òf±fff…©gÍšEYQU¹hÙò¢Â¢ÌcÇýñ'§¦á5ø"¼ý,ËýéW¿ÜöôÓýê à˜ q;Þ{kõ†{Î;üÌ /v¶5ë šèè¡Aý´™s>ÙþΈqäžŽŠŠzó¿{ú'/7ÔTådd<ûâKS¦Íz÷õ¿‡EÇD††|üÞ{Ͻô?uà¨nÈźü§N»Y[YV_S-S*V­Ý(W(3ÓÏÕUV®Ù¼yrrʘËêµF½¾®¶zþ¢¥‹©¡¶† ¨™³ç$YRP˜”ÔÒ\o0 -]¾râääKÓmæÑ))Óò.gÏ]¸0À?`Ä8ÚÖP=géŠàÐðõ¹Ü‹†M¦˜˜ ƒ°Ìää©:n _»~Ë=$Iåæ\R)Uþ~~Í+Ö®Ói%–ˆÈÐp½n »½möüEzƒ^*Æ~…9YCúù‹WKä2¥J›G‡Å AQ M‹Eb›Ã¡P(ˆŸ3´‹‰½Ö­s,Ëpc–EˆK¤ MkuºÐ`±ä3tëi—St3£3 €0Ç"‚¸nË{}1æBüÐ\í±è3TË!âfF.—CD‰ùe0ÇétZu` „O?¦®¼4yú ŽÃ†ÁAÌ2‘Ñ15UÚ¾¾°Mww—ËæŠIˆŸ1gnGkKuEñ¼KòsrƒB‚,Y:ÐÓ]Zœ¿`éʈ¨˜f…ÝOðSlyp›H$®*)Ê<{vóÃó#¾°YLÙ™™pqI“BCB/¤Ÿš»paOGGosëâõ«k«kÌÆ‘ióæÎY¸´àrVWgÇÚ ›ŽÜ¿pñâØ„¤†Ê*Ó¨qJÚôðÈè›V-IRØÅp@­] Í¥ÎI#7µwSb©ˆ@‰S=„Eø”±0át:ÛZšå Å„¸p9ìÝÝ‘ ¥ŠÃ,`ÔÝÝCŒ§'sp›Ì#¾¨«*mnh¸oÛ¡ ÀCX5IPIRAˆx?U " ïKHŽÕÓ L”ùR`1™N;ÜÓÙùà#Ä'Nˆ€L5I’$I‰(QAEAAA\1ÎA¾É„O¨%@€wðn¤üÀÔUŠ Ü=¬+Üäë¥*°•î,aaŒ½2îa ŽÞÏs¼<`ì™@€|lŸ± ô"@€€;aaÄñ”cÎmSÈq©_+ìI ÉÍË @€€/3Âr¿àç7#^6ÙSMçåe°GØï*‰äoµƒË2·]:c©²¬$<"RÍ_”fÓ¯Ób1›8Ö…a³Zùiºà°™ùÖjŽe´º™Tª×ˆÅbÌrímÍJ??’[•Á<:\[Yi5…„iûzFFGlf `Ü?0ÀÐ.¹B =­†žuH(?‰²¦¼ÜÐ×5bèï•JÄ•%e.—ML;zåg"Št2.¥BÕÙÒ(’ˆzX,κpÞ::Ì·ä:í¶ŠÒâ‘áÁàP„ˆ¾¶–®úF8?ÿp9%9Ù-ÍR¹\1–ôMcUygWGsc]l\‚¶»«0ç’a`@,¢²2ÎøÊeŠKégu}ÝÝ]ѱ  ûâì‹IŠÚ¿ó£¢ÜˑёûöîêëjŸ”œR]RØÑÖRR˜—ØÞRæÄQµŸ²º²Ò¨×ñG¾¼¨ ««KßÙ94<4sÞ†ʲÞ|-"BvoàòÂ¼Š²’Îæú¸‰I§îmj¨ M?sÒj ×D9°·¾°°§·ûRæÅ`ÿu晓Õ%Å£!!1‘ºÁ\Õ¥gŽPPdwWOEq^L\E‰ºÛ[‹s²uÝÝzm_DÌ„3Göä\ÂNû¥Ì Ї†µÖU·ÖT74Ö éu‘1±µUygÎöE…k.]<Ÿqúø”ä”#Ÿîªª¬˜6cVMYÉ{¯ý#2,ì¥þpëCÝlöµ€¯QJÈÒ4]]Z^tùRUiqú¹s†Þž£Žœ9qše¹¶ÆÆw^ûgKCãÅã§ßøÛk´ÓÅ ½»h'œ>z°³¹éðѷ¿ó·_ÿ Úëÿúë_äg¤gœ<~äÓ]üŒ¿5?ÕÓ8¨ß½ýýÒ’ò}ŸìÀWR˜÷óç¿——‘þâóÏêúûñ£hû{›[þÒ‹,Cs,·ý¾÷·?u´uüßWv9Ûa³ÿú¿ÿ7–ˆ°ytäО]ÓçÌ­«ªª¯®PúùÝ»kû›À¹—3sãÞ|Íb±2ÉÁÝÀ±ýŸNNM•ûûŸ=~˜f™=;¶ï{÷íÉ)S÷íühÄh EâE«V%¥¤N›>[¡Rµ´4e_ÊÎÊ4èu“¦$ïß½ 8Ž}óïJI›®×j‹s²+Š öìÙ5yÞœýÀ 3ÜóqBJÊÂU«?ø÷?¯×“ëln,..š=o!æ¸‚ì‹šØ ý}6»98+1iÒXÇ\N{QAîÚ›)±ˆ ©Ë–÷tv†…Å%$t··$¹ù¾‹ÊŠÖlÞ²båÊó§NÀÒ5kJåƒ|W"½Z¥ëº¬mڌ١ášÖööóç‡FDîÛ¹cî×þ¶bæ…k×?}jP¯]¿õáæ¦Æ´KV¬Ùy*ÊÊüÂÃæÏ[rþäq˜6cVPlÔã?¦Y±f½‹f”ꥫV[Ì£0}ÞBMt”H©ØqààMô•|Í‹ ¤ÄâÀè¨Æ¦F$•úø=ztÍ=›õ}==í­ “§úûû‡†WÝ{ﮡYBfµZ྇ OHxàñgJÿm?eµÙ ~r²:@ jÍ=÷*äŠÌ³§!‚—רõþ¿WoÚ¼bõ*AqÎ¥k6(üU©sæ¼þÞ‡aQ1Ñ€ñ´™3B‚8Ž£Äâ57ù‡G,X¼„$ :2eÆÌÁA-íCD8?;“ª¬¨04××*Uþ?üé/hïÝþá#?¦Ò7×UOIMóWMI›a1ä]Ì8[[Ua Ÿ–6-yþ|•¿h˜Æb2q¤RE‰’&9iú‘'ŸŠ÷”ˆÅP]V,SÈäŠø¤É&&%%OÝ´is]AaWGŸÃaç8¶<7§¿»¯²¼<6~"sìQMeÙ¨ÑxñÜY™ŸŸ:Ölº'+ý|GSCˆ&Ê ó£bb 0P]]VÂ Š€Ððˆ °àÖÆ:»ÙB‰ÄMu5=½EçÏêôº¤äi@’”_`’IDæŒ\"…B‰ÀX*“õvvål«¶¯ãXŽc‡u.«Ã42895­¯¿v9»Z›´FýÈȨut¤$7GßÝ{r߇Í6wÑÊ‹§õv¶åe^¤$× ¬Ù¼eØd*ÊÏÝûáû%âK„©sæúG¸Òž|îûYçÎå\îëX¼buoWGk]ãî; Ú>H›9;0v‚¿:&OÆÒÎã{vïÿäcUPȈÁÐÑÜ’“y±³µ¹¹®åÔá!a’í~ÿ­ËçÒ‹ KêªËk*˺[Ú.Ÿ>Û×ÝqÍŽÑ4ÝØÔT}irò¥J¥Ðög_¸`·Ùr2/ÖV–ž=q¼«¹=?;óâ™SíõM%ù—UuuÛß~‹Ÿ Ïqì™Ãv½ÿÞ˜WžDD•^º\UVž—óÜ‹?!IêÑ'Ÿ9øÉŽÃûvoØú@`HXÞÅtàpCUy^f†v`@?гrÝúÌŒóFã`XlŒ®_Å&LÞñö¿B4™",zÂ¥s§Ô!!Ýù¹Ùµå%ŠÀó§YÍ£Â}þÍ)ò·W’$…´==çO^Ï&£ÑX_tï¶ÇN: ™¿uÛÃå%Í­3§M{ûÍ7×ݳyõÆÿyfúÚ¼ørüĤŸÿø‡ËW¯]¸tYÆùsey·Þ·áÞ·ÿûr©2*>¾£½}ÛO víøˆq¹¾ûÜóIe_ÌTè†ô=û|AnöùãÇÂ"¢Ÿþþ÷e Ueiqiiñ´´éMMá1QKW®»púx_w×ÊuŠŠ‹ƒÕ~êÊòаðÍ[ºþût¶·õ¶·9hçªu›:Z›23.Ì]¸@¯Óv÷ÇN™¸`Ér›Åœ•~^¦R-^²T,•YmÖÌóg¥”hÅú›õÈÁ¡iÓRkkj0>ö(:´ëãÔÙóÔþYE^³u‹RåwöÄ1uP °|íF½N[˜s)!1qjÚ,Ìq9YBÃ5ju[sã¢å«1ÆeÅv»}ÖœyÒ±ôài—³¹±!T£ ñT¾ûz»ýý”*·>ŸÍjiok°¯*¾nƺñ,hØJ€_añDu)aÀ¼ýçQ‘!<äÅÿ#}hK€îaa #!ÂÓŽÉs“[‹×oà<ìæÕ$ @€€;NXÈ+ÌÀÏ’wK_ñC‡„ûÁóë£5*ÄV¸ã„…1„yT§8uEê ]ùw¥Ü.–î|J¾zX5d¨§†å[Àòˆd ‰¡î¾¢ö€À ŠËéJ¥‚¢Dq'šGG¾ìƒNÓ´ëÆ–B,Ë`AèúŠòKégmV XmV‘XÒÛ^[t9“$)‰Tf1ݲvûœÒn9ã%,>xŒ9·*€» ‹opwSh¬êkÍYøµ?ÿ~Ô8x·ØÑÚ°ãÝw¶¿õ:ÐN‡\¡àfdPÏKûûØÇ²2Ü¿ãåTeù¹Çî-ÉËvn‚@ùñûïòw¦@ ‹Ôh€—‘ú<¯ÎþtÌ`º²$¿®¢Ü ÓþõׯXL#îÝxçõ€Ëa#H £&?¥ÄbsKwfEaþ¡];?|ãõñð]]uuyqá˜jo¨ÉMO?²wWg[ ÿNòŒ™%…üÙ¡íàhdxÿøö÷÷»•«ŠcîÙsúØ‘O¶¿‡¹Ï>çOoi¨˜èsDXž§²[F ós ½¢ßÈ×EõJýäëÿÝÑ}ÛQúÜÆ-ÆMœ’––ª J$±˜ME  †ž.@Øí£s œ 7¦5V[S}pxè½=šuþœ¶¯J¥Qß¿`ér,‹Í##¬ËfµZ0Ær¹ ¤ï­se²•·gÅýøù£%šèDŒ¡×\_ïbœ“¦¦FGÇÛ·*¿ááÁYó`‘Tn·Û!‡Ýn¶Û€q:üüÕ7`fîFAœÕû‚&°J¥›ËªÊ—¬]»aë}ûw|àmE%“+œ»< pÔ8˜œ2}òÌù¨¥¶*1e†Ol;ÚT[Íë  %¹—-|°Œ±n ×ét8<æ•ÃC†²Ò¢û~¤¿§«Ÿ6o~„T.˜hü„ÅËf»ý"®U|7ö†WاŒå4ãòûª¾ŒËaoª©1ŒËÐu•]­îgiWKsOg‡ixÈ'jP“åùú·gÏó/g¥Îš})ý¬Ãa·;]}=]÷÷Ù)³èú{]4-K®_E­S£Þd6oûmð PtZþ͒‚9óæÿß~ÕT_­ò èioݲíéè„IgˆM˜ì]·èÒÅ‹çÏž;vw·µœ<°'ãø‘¾^–¦óÎJ?~ôÓß÷²ÅÝ¿ñ—ßWäŒ}GÝ€J&NJ®(*cº²¼4~R2ÿfAîå…K—}ôÖ?;[›8 Ú[š¶<üÄÄI)-­”LI‰Ü"hÝ­Mg>}xDZ½í>ÞqtßŽc/?zrÿÞÿü ¿¤H$îès9‡Q$˜M#ÿúûŸÿøÊOuý×ï•T,¶ÛÇ6ÇlïèÔõ34í¥õöæÆØ‰Iµe…ÛßycÒÔ´ºÊÊÐ0MDtŒÃnµÓŒÊót1tGö}ªP©ŽíßítØÏ90möœƒ»?fºº¬H70˜î\Vú9~áÀð~öJyaaZjZDô¨©(ýóÿüâo¿ù¥Ãn“°ÅÔÏAX8ì‹sµs½§YÔ}Y_×Ùp£~÷¯&OdYfÏŽ÷bâãîücîðžOB5áÆ!CI~Ž®¯›aœ$ ÿ¼÷6¿pkSƒÕlÚýÑv0ô÷üú§?ŒõãgÌÃ×fˆƒºþã÷ž9v`ïöwØóéGïž:¸çÔ¡}öü§¢8ÿúHaÔ8¨òS¹\Žž®Žõ÷Ü×ßÝ%“+B»}îâ×,ÍɵÚ'*ºÂ3æÌÿÝßÿé´Û†‡†§¤ðéÆè ±¯£ý…Ÿ¾š4yêŒù äžhbݽ÷‡GF¹òƒúÊŠ²Uë724}äÓ]›|dÉšµŸîüÐf³´uwOž–6ab¼;TæØé©S¯Xëýè!ƒN¯í7èF†t£A«èÑöuêû{½ËÌœ¿ð…Ÿÿlÿž«î¹wÁÒÀ±Œ®»g¨·{ë¶ï‡Ì^¸XåçΪ¢ã&LNIó†{gNßpÿuµu“éàÞ]>ñä½?vtï'V³I§ëŸ·|EbÚt~a±Töëÿý?„ˆ²â¢ ÷=À±‹—,Y¾v½J©ôžúî¶æžöþîv³yÔ4<¤íëin¨+--4]9¡/ýò7!áQ'îè©gÝYmqaCu…2 è‡?ù,\¹š%¥2EÚ¬9ÞÏ:>oÑ¥R QZ+‘Ê(’j©«Ñ åe—ú%OKó &%vt¶™G‡ <<|ÙÊÕ[xH,‘ºpP__]ÙÕÖÒÕÖÂ9l#F}OGowW{«¯ƒQsc]¯Ö~]e©÷‰‹1®­.ÿŽcRWC9€¼ª Ø=AúJ®áÛò~Õ°ºÛš­»L®P†` Õ?ù¬\¡üûï~õß¿ùÃëûk˜&zùêÕü ¥¢±¶2,,„çe•ÊÖk6«E¥¾Jq0(4|ËÛ!–¡A`Ž#)êFÄA–"¥¹çÏoÚö8C;HŠš³h)ÿ§Ø„Ä« CÇ´"©X!ST–臆hš¡iÖb}þ…¥—Óqöè¡ÿúÙ+æÁAitLW{ëÄ©)-­mIi3z{ºâ'N wŸH‘È7q9ðêïÿ ;]ND ©Lá´ZE555íÀÎ,ëš¿l"HÚiW(Túa‹\&÷žÓ’ü\†åTê`Í--Ê B`‰%¡šHod_ÌX¾iC~v¶Ñ ­,+^½é¾ííÆ{ð©2÷n{rŒû„¡OÜ•˜”RUTèè“qæÔºÍ[ìþ¤ª(_—yîtl\\‚'ó­:qvÚí½J•2aòTƒn€DdRJšA¯­«©{éÕ_;z¦±„D¤h÷ž]Í\8uôwÿøOFë}voXß¹lÕê1ŠîÅùƾ֌c}MÍÍ¿ùûës)kåÚõ;?x§¦´xB⤢üœ‘á¡•k6ˆ®N„EÉÐô¨Ñh4èæ/^¢íëñS&OK3èõ4íúëÛïegœuØÌrUDzŸ¼û®»µ%8<|êŒùZ½aÿî]›uåºõ«6n¥Êï¡GŸà7ÞÒXo4Ï[¸èú>²÷“†êʪ’2“Íü«™ó»Ú[ErEWGûà€~@;P˜›C²€ åœÅ˯YqÝ–û‹s³]4ÓßÞ¶tãææúºÒü\Ža&NJÞñÞ[SSR—¯ÛPVRà©a :.ã ¾·o`ÓƒÛ ¯  º¼|ÄhüÉ«ÿ7"¢c"¢cÜL‡%5mFdÌ„ëwøùÿŸOÞ‚^ýË?®C±x÷Ác¤Gg|P¯íéh›1oÑ7Ÿ°0?Bˆ1p#Œ Â#/se„Ðk!á;hxwa⤩gOjmn¨¯ªÚpï}Ë7ß[œ›m2™7Þ÷P¿v ¯­sB|ܬyóÜõ „&%OíêèHL™ÎЮ¤ÄÄ]¼“š:+ë|Æó/¾ä»ÙÐðÈÇ¿÷üxÇ³Š ,]†àòé‡~ö™q®u£±³êҢ‘Ͳ=þ……GÅÆ-Yµ†v8'LLêélk¨«¹ž°(‘äá§žÝõþ»‰))ËV¯½ï;ž;~„@äÖ‡4Ì]´hß'ÿIž:M,‘€X"ýé«¿5‡•*嘎§¦‘±G÷‡†!DbñÜÐp±H ÁÁÁšÈèUë6Q"©ÕÍЬ§aýš|=2vBÚœy€ d2ùý?Ÿ8I,‘LJI³Z¬€9ÇXIV˜&rå†{Zê¬YOä†û¿Ó×Ûûàœ¹ˆ ØöTRXä}¥LŸ-–Ê‹ ò_øéÏÕÁ°õ;o¼÷M{m®r±Û(м… žôqEèíéI?}êÛ@X`l­í¬5w×ÛúšœÚ6ZßÉ{ñè¶è±Õ€ÃØ5‚æ¬Û1v`LcÌbÌâ».—«¦²|dx˜ÿµ­¹Ñ ÓbŒívÇqÝ]]6«Å»°ÝjáXc<:l<òé®Û²Vó(ƘãXÞŒkœøàõ?ßÚÇç\Ê:{òË>ª¼þ—[XËét´6Õôï×Í£#wò(ÉÏ)-Ì¿…[êëj«Núô_´ŸlÇ íû‚¡]®ìô3ø[Bˆo]ð|ã+’X××}GÄﺮe‘H”’6Ã?À=¸Ÿ8)84 ¤RB(:&Æ×âX*WðV§ÝZZ˜[v@®ôðõŒb©âÖ¦Óaw}éeW<åê´w¼£9º[–­Yc¸“×@XDdPHÈçþ’Ÿ>yÐi³÷uwßá‹vÞ¢e2…ê näò…s©3çÀ·h¸­Êm™C‘$E‰Q" I ‰+úÈ$åÑÃ"nb™óµ˲m­“&}e{p­iã¸Àqìñ}{-fËC?.ýÂWümGWGÛ¹ÃG1E>øØ£^Ÿ×»½®·«+%-M4VëÉ]c}+fž c[%I’o›CI¤‘áö%$yœ¾Dú˜å·çX³ "H„„‰>GÑã8~2F`à0&½¦˜wÔÁ RÎS—½‘eÎçÏHJ8 ]ö¨_ñïØMQÀá+º£Þìê•|F8ˆ¸C„Åaì£øB;æXÀœGëVâ®~!ˆ» ¸ !³ÂU=^ÂBnð©!\Qðs«${_£+j3W‚,¸›³ÂóG]κÉÕå¥Åù_»s&S(¤ ÕåÌ‹» IÚŲ4‚"Æ{ÅRi@pÈ­}ÜÞ‹öiÇ**k«8‡ìNF.‘Æ*…‚c™±BîÐÞ=^ÙâëÑTW³ßžö'ÞÑkûÒOù<„…C#Μ8J34BH$•DEGIR$s68M»ZZ¹Ëëzû.gœÉËÊÄãP¬ÔÚ½S`¢qGXÈk5B"¼£‚W‘Ñ•6wøº„W”T¦ ½ÉR™Œ$¾~A¢R©Òõ÷EEEŠd2—Ó1{áÒsÞâa$(Jô9f«÷õv$NžÊbp8m*… êêp+F]„ˆ¿üû½i³çÝ(¾èéüζÇCƒÏÚ÷ÙG¡”xtòÆuPdxXˆÚ? ,<¢¹¹ )U~„Dƒý½š˜øë)N,‘¾üÛßù«ƒn”Zî|ïE+×úÊ‹>ûqˆs)0Ñx¯F·Ü(¸ƒ)Œ1âé‰ ÜzXÈ}T¯ uÞu•,‡Ýær¹d2)AKW­¡Dḇ,AR,ã")‘÷+д+ 00iÊÔ¯ãi++ÎÿþK?Ce:µfë} ISì6ë±}{úîÓîò–Å|öÈMTLú¹ãÿý«ß~øÞÛ)S’'§LÛõþ»ë7¬ëÑËâõ[ÜŠ(íͧOÍš¿`ö‚1ôIH±øsMœbYF¯ÕÊÊ ‰Ùé§—­Ý#ÆÁþþÞ”™sÝßé(/ÈsØìÁ‘4Çdg?ñ̳M uueųç-êèê\¸l…:(œÇÇ~¸hÅu€º¾ªœ?Åÿù×?GFMÏÿô§A×ÍRt:ì¾SÜǃŽÖfuh˜L¡DMuÕ+﹪J £bOÄjè©®¬ ­v‰Bqdß'¿ùËÿUæçæÌ™=»¡±qÛÓß“)”€ºÿ‰§ ‚ $"MT 0 }pïǦaÓcOOéçÝSS)ò_0Ž”]q%Oç ä_/Òെ¾‹À2ôÅ3Ç+ŠŠ>xãÿŒ†¡ßþìÿU´65¾üƒç.Ÿ>±ã½wÏž8â} ž=¼ÿÀÇñAûùã‡t}=ý=Ý™gǰöÔhûûúûúûtÚ¾þÞξž¾®Îζ–¯¤(ËдÝî”Heb‰tÎòeüW (jë#yuGm6k[k“_€b͆ ~A ,”É•± I±'²¤øž(+¸2¤ØÞÖ²åþûͦ‘1|Mhðçš›ÝÑÜ”4ŠŠ‹Kšâa1nÙê Þešj&Ož¿rÕ@w×ô³æ8†ž9waSm­D®ŒÏÍvçòr¥jû¾Ã”X’s!}ùêõ0dÐÞÿÔS?ó”s¬D•a±Dæ¾|vÉ¢´° 9u¬ÙtïÄÉnq±ÔYó“S½Ë4ÖÖø-XµJ6{ŽÒߟIf.\ÒÑÖ6mþ¢À0M§OõÐd2]:{–c˜ààèliX´xùâ•+úûƸIJ&ߨ¾æk‡1çkƲ Ë2ߺ 8„ ÀccÂ]LJHĺ]s0áin ®¬î"1?»ÍZWU½~˽Ë׬ ÑhfÏ›‹Oœ4%9y’< àÁm¼ý¿nØò0.çŒù ‹órøÝ/ËËŸ4edÈÐX[µrÃ=×–$´Ú~žæ0)")h'«Kýår’¢¾’9Û­MõI“§úºC"cƒÜ•)‘Xâ+3 ‹V¯[wù\FOoׂ¥« §ËÅ_ôáѱ|^é]8@­š¶ IDATå.#cÕªUÞSypLJÝM-¤D$óS¶¶4ëú­«epÄìtþÏßþá«w|=²33–¬Xe5ê¡1Ü)UÐÕ¹ylBâk¿ÿ½Ífyä™gù{$)„20(vbB_w§ÅtÅÀ‘Qù—..߸948Ô~~¹—st:ÃϹ…vÛ»o¼Š°ÙÆÁ¡¦º:s —-[²zÝÍ22̵65Þ³õ>§Í*‘+HÏÌVâêjàÜÅËîÞuhç'k¶lšœ:S&ñOmMxˆ\©Ä€iæ w$§N“JeYégNØýÀwŸ›7áÌ©S&³íq–ü ^ûþÛÿò÷ ÊT`­v@«t1ŒÝjšž6mÅÚÍübgŽ*ÉÏýÝkoº‹‰ï¼…Yç³/þÌýëÛÿòóó{ø©ç¿e„Å"ž³8ŒHwJˆ=ñöc¹íT9ßuãà®ÉÀ ’X¹as~Ö¥þߦΊâ¥ÍE2U`p°X,’z<DicCýœÅË«Šó§Ï_Ÿš;!ÎjŒŽÕö÷„GD_S• ”PÍp”ˆ 0c²Œ*䊯Dc¢³½}úŒ™}=]Áš(šv‰Ç*Ùh{ºòròžûÉËy—.p,ãtØ9†á8–aÚåtÚmV‹…cY‚$1Çv¶5Í™>óò…ô —Ê•ðÐ3Ïy7µ{û[>óC4î³ÌйXëZ-4•€@Ÿ¿:@¤ VªCä ????DÜé#TœŸ·hÕÚÞÞß¼ü£õ[ï¿ÞLNžš~ölh¸&((¨©¡‰a1Bvc3Ûz{ºƒ‚‚”*B„D¡j¨¬ ‹Œœ89ùú{5÷üÙ9‹—ŒßŠŠD„ex$qjJ[MUumÕ ^u`ywgGSm}}C]B\œÍîèjoïïë•Pdww ÒήN]ïÄIIR™Ü42¼kûGm/OJK‰‰KÐDE[Ì—Ó±lÍ:©Tv]þ®š?q¼{K‘--ašh‹ÙÔÝÕ¦ïë Óhä×é‹,£¦Ì¬Œ´i3u}}AX†‡êûz{i—Ãn±é‡â'N¤(‘D&'W”³.fËCP¥‰Žéíè°˜ÌKV¯‘H¥ž¡÷q¶[-­--I““Lj&(J&»bŠ¡P(ý}T¡E"‘7ä8öO¯þ|Æì9R™ü›MXÈØZNA¼A$E‘$$ r+a>J~Àg…àÓJz·À 5µ55†EFh4š’Ü|'MONIîlhËÄ¡~j3늊™01 F†‡êê,^ '¬Ü°Ålõó@}|âþöÛW~ñû¿|©Yù;ÿüó_þåç=&N»íRfz`€º¯¯oëÃÞ(!»í{ÞÕÖÜÒP¿zóÖ[X··¥1ãÌéïþèE_¹ô/ƒºþÒâ¢õ÷Ü÷·ÓR_«Pù}³ ‹òÌnFž :cÌa–ààªêJÙŠÏ É»Ðì+$L¦ñj‡n~èaþÅÔi3®_8@ijää¤Ížª‰üÚ?†v}Ù!ßÊC["“Ï;¿·«{ýº›”nÿ•C3¬T¡¼… /gJ¤R…:°½¥1qJê;ƒËP’/êüŒYV×Ûã;JðÍM _|žðäîÌ!„D’€  I¡ˆô\jœ‡Æ¾öýî.šÕD(Uª¯×nw¶5_8~"<*Zã±Pý20kî‚[[p:ì½ñÖöN¥J©‰Š½sùrpHL\ü-¬(K´]AÌœ·È·6ôeC¡òO˜øE·‚PT|ñ-pFC-å$E$AIRA"’$ Q$ (€D‚«ËXèêðîBƒÕo0hšæXy+#w8޳Ûl€L&%n×° æ@puÿvÃ]´ÃøJ¯ât¼SpÜr|Ã@Â×$Š>$%°Õ‚H$‚»µç …R)œ#·ùº¸"…Á#&Ãç€n§¯«åúˆð)` pÇò!¼‹ï³B^Iw0xºÛñõ¢WØG‹8K€wް0FX·3Â|)„cOêÇ'†œZÊU¸Ã Œ @€€€Ã€ðÕ^ÞÔÌzÞ$¶ @ÀWâ®LÄñ§°Ç‹c›ÉT]VàU˜ñ #@€w,%äÜÎ8ü@!߃å6ÈÁ¼ˆÒ¥Ÿ8Ã×Ý =}žðê+á,¡d&@À·:ÂâÂ>UnE?^ ¢ãÿû¿à89|Ø3šH|œ%ð•ßbP€0ÆDzœÅ4:¤7„F„³”ÔÔNŒrÒL :(¯¸<<4hÙ†MG÷~Z’“c5ýø•_Š%_…Å©«¾eÇq€1æ¸Î––æ¦&Yppq^¢(…\~äÓƒÕµÍzƒqí†uÕ%e€`ãý÷OJIyñ—¯Š%â¯TÓ]`+¾•Àvº=Ý]–¥)±Ö8â´;¢BC¢ãbyü’¢6"f]‹yDÄ«— 6_¸ÃH@ˆcY‡Ó¡‰ˆ˜9sÆÆ­[*%IƈeœÓéÌOÍÁ‹Kr³}ÚG àŽ_’*ÁQúÞ>óà`gC=Ç0ƒ¾¯_ÛÓÛ͹íÝ&ãH{k%‘h{û3Np¹Øo“U½î CS)"’$Y =½½m½“Ò&…ÕÖ5Šäò  À ±±UµµAaæãÌó«Ë«FFÌ‹—-'HRð @À%,]c1IR$"HI‘"‚¤x©‚¢ÜbX¼è(o^ÏÿsÏΡ®“—.|É)!@A `·4€Û‘ùŒ"ï®ïwØJ€_2ayȉïEØËPçé‚w3\mJˆ|Ì  àNDXc7Oñst<4ä6žÀW'ƒˆ{˜Ðí댮|yL =ÂBwû× ½Ý9égv»ÍîÚøÀýq IÂ1ðu",w[Æ# ÿ `ÀÀ!Lǹ'åçQ%¢ž< qœ§kÔ7Džy9Ÿ1ù™e™“‡´ÔUm{æûÑâo²$Æøøþ]}í­|tBBâĤ„Øèp“Õ–4E`+_ÈÊ˜ØØû>çòGöínih¯Ì»ø›×þ¹|õº#»wÌZ°X©T(T*á` øzÁ-/ƒ;Ìr[»v³,í2 tÔÕóJX&»Jþý3>€ fÌšÓÖÚBŸ…ûô“þΞšâò¢œL‚$#£bš Œ)aŽN•/a…k"8=ž…‡uõ%?ýŸW6>òxḊݖuáb€ZýÊýWoW‡p0|íRBäîrG€±;?6èf/Z\W]“85¥<=]'U*ù”0>Ýí7K "b&Êe¢“)âÆû12¤Ï¹|éµwwtwv(U*0èõÊ€R,ût×Î^þ™pª|A1>Iý#ûö®Ü¸…‰Ÿxö9þ7vì"âƒGê¾v„ÅÇT‡9“sˆå¸öÖfMTTQf–Ê_íç¯&HJgŒU©|DHOI ùÄ\7â,$“ÐôÍæå\ÌXº|%B(6Î6ÆÆOŒŸ³æ-ÎÓ5`X–a?»_×n5Wäf>øè×ļàªøº¥„|lÅ2¬¶«§ ;¿©®Þåt™Ífˆ‘ˆ@LÂ4ËzK½Y$¾®¤u`§Ónœc·áACAvÿšãpØ­õUe·ö­9†þ‚ÇmÈ Óö÷|æbÇöïéïéÏs/žÇxìcÒÞÒðÅOtGK“QßïûNUE©Ëi¿f1šv|ö þÂu•}Ó«¥´0þR ‹ÿ?"r³ËÞÝÛÅ–©ühmÔ 0Æ"„„‡º­VÝT…=S Ç³sH$S$q£/Ü×ÝÙ§íUÝÞïfùÏ»ÿÂÜ6OÌË:¿÷£wÿý×?~IÛèí>uàÀÔé³íÛûY·Ó¥¿j|C¸HÝÓÙÑÚX?F¤æ°OMM{ü™ïñÑÙxù…ãN=8wÑ ÐõvÙ¹ôZmÞ¥Ì[ûâ™éç.;ùE]}Mu[SÓgÞ—]í6«m<ŒŠKȽpnÌ?åg_ü‚'Úf1ªC (ÿòðsÜ¿þò×Þ«8—q9¶ÿû›oŠeè¿ÿþ76«åÖÙŠcýâÚuÓe¸ÿ~þ™Ê’ÂÏÜírœ?y˜}h×Îß¼ðlUQÞ¸ 0Ì!Dú+U ‚ƒƒÅb*&.^¯X±yòõk[ªjƒ51r™  ˆðDXÞ ûø}á1YyßÇ;"C£ŽíýÔhйM5UbDúùùÝÞ["•ªƒÃï|dµhźi3gû©ƒ¿¤ík¢bž~ñå'ŸÿñCß}ææÏÃÖÆúÀˆèñ4`ŒÃ4í­Í¯1Ë’ªÂ»œN¯Ñ ¶ŸeÝÉ>Ë2ÇyŸUåÅÓgÏ%)Šc™ÝŸ|tßO@TLìs/ýìó°Ëßo°zãæšú†Qãà-ºÅ+V-Z±ÚûE¼{žÖ¾„ñÒ+¿ž89y<œ?±±±Áj¹þO2±øæ_ŠÿP†¡oôÔ¿pòè}~!BÛÛw颟"ˆÿ8{u÷CÓR…ìæûIR¢‡ÿîÑŸÞò¡Cùgž¿ùx="ÐÆŽýÌ­‰ÄRMTlSm<øÄ“‘‰“†ÆwZÉŸ¾ð, D d1›º;;H@Y§Ò'$Ä…ÄDÈ2©\—˜„A|Ôû§Œuªßµ¬”é3æ._¾dõZ¹B9æN\<~hpPwï#O~æ\Ûßãr:dr%Þêuþê@÷ÅÇÐBW¶ÐÝÙ6gÁ"’¤n‚ÕÕV“$Åq\eY‘H$–+ÐÛÙBÓ,C;%R÷¥`©©,ó÷8yìДä~`Õ2:Œ"©+¡èkkj,ÎË[¶f:(Ä<:RœY –Èdw˜76ë±=»''¥ÍùŒ"àè°1ýä1C_OGK˦¾>vhÏï N™–Ãú~­vÊÔTŒñá=;í []t919õÄÁ½f»£0ûâ””Ôaý@kSmmiqiAnÊŒÙp)ýìòUk ’ª(Ηʕ“’SºÛš÷ïÞ«PëáTœ›µãÝ7““§î|ç uP`PH¸\*)/È›íØÁpúÄQVÛÒܲuÃZS—ñ/¯ý²±¶ª¼´ô/¿úÅòÞûè÷t;1ìßóÜÿíµ_òN§t$$8¨©¾Ìæ.<0:·j ˆbG{ÃØf6‡…†R§À €Š€q·«0/÷믷;Mß?^à‘‚ A­m·-Yš9aÊÕ ,—ÓÙÙÚ>(6Ú[9º$¾Ù¾å×|cõòe‹ußÎ-÷<üd`Pð²çÞ½àŽ‚‚sSgÌŠŠíÑEUu{ggô°ÐXWÛÞÖÀöíúféýq %d>hLKJ>¹Ýf½PXøØ3Ï»œŽo6­Ïœ2}÷–­“&OÊœ4Ù­­Ømá11ë—/¿çÑ'?|ÿý{y EF‰ WªÜÚÓê/>{èég•*eÔ𠈉Š=W\˜9e2!ÄûZ|üü~âé0Â3Æ tQÀÚƒ*ËÊ‚"ü| ÆjµÊawºìöÀðp›ÕÆiÔˆQŽp“¦ÎèþVkk+XTt?ú¹©³£¥¡Á/Àuüøô3Ûjj‚¢9®®ctt”;Lp„#ÐÙѦRª§xío8mV³É z?ÿ¶ŠŠ±ã'¶¶w|ùÞû†°àô1ãÀn6uï¹HÂtÔØ‰;·mS Àj+Ëw®ß¬S*)G0!zƒåEÂàyc—%:*Z«×O›»àÇ?úÐ3Ïe}µlÉ\NN¡0šÌ V+ªªª[›.¹L]Æ#ßìŽmnm(ãœàtR„/ø?ôˆJ«ëlï l(+ |îÜÙôñ“o_|·¤EÅ .¿Pô÷ßý&9cLÒÈÑÏ‹TVár8”Äm Q‘îݽ;jpìÌ9óÜ·Ò×ÏáÙ?uòdCu ¬ÖéÊKŠ+ìG}m£Z£zâÙ•Օ#RR‚Bßxæ‡G € À æÆÆä±Þzý/¶.ãýk0™Í’àp8DPÀ˜ “V-ûtÚôiÆÖf¯ßë?{%È`ð ÐäääT••ÖÔ7R–˜ðàãÏ2&ÆÅ=²ïCqñuË—)Jð÷ñqÙí7$þÀ‰“cÇi´:FéÛü]GC›s‹z¥ŠéUv—‹ã@Ùâîžœ641içæi£ÑÍ+¿Š?zè@攩à`ø÷ëž6kfFffìaQ‘ ¥rÜäi›Ö­ž·ôÞÒsyuUniÞÚô§w>ljlhïh $ùŒí-áQ1awD‹Š”r9V›5  ³µ­œ1¿à&ŠŒPFQ„KÌÏ€Ùð”ԸɌR©`€8…úrº•Ãn]¹ì#C¨J­r¸«¹CBˆæžûìÖ ëª‡R£ëÏçG[š¥<úd[cÑd¦TD¢¤”>ðÀÃÇOfäd§¤ Õ@tLÜùü³™ãÆ ?8~Xmm50:|¨ÅlV«5D¡tò.?C B¥~ô‰§€Q½Fj†"äïã÷ÄsÏÎÎÞóõö‘éc!µFë²;’SS-SZFFnö‰‰Ófµ·5Í[|·Ëå2v´ú‚c-a»¶lÌœ8!?çäÈqlÇ=?x¸®ºª­¹!(´'Íå°­Y¹ !Ê•©Ë@µ:µÅlG•62sòTïkŸ>mÆôi3®öMÐT]¥Pq>þýèüJ•:0<Üi¶¨„ „Õ èèhoݳoÇÚ•~÷CÂq˜`sG$§.ÈÏþð½§MŒŠ²[ÍMuµã'N>²wgôÐ?ýÃönß,õ¬33*"LÞÒÒ’Ð\_cðóËÍË‹O?"é…ÿKºòØr³³ÆM™Œ1 :6?vX‚Õb €â‚â’ÂÀtÕ²Oxü™¨˜ÁϼòÊ•{+)ûã_@GGG@[Á™}ûݧ۲êó¹ ÷ÃðĤêÊŠ¡ )çóNgdŽÝ²n ,€æÆÆ¹wܵuÝÊ?ýã-—Ëyüо¸¡ þþÒÔJ¥•FÛÙÖÌ "EH¥Rÿîßï¹m›E磟wçRï†nX¾|ú¼YG=º®¢xÐ]+p”Ý·ôÞÚêʪҢÁCG<û‹WEJ™‡À1f7w©t>Làuz0µµµ(çtØ­–®žý‘Óᨭ® µ;l/ýú7ù§NíÜúõˆÔ ›SP(à§Qûúøð¼K«w›ÿ¢“~ùÑ'Qƒ£.¾ÛãóR Œ€Sj*µä.ð‰¹¤Àb@)C.QÔ Á¡ CXh¨¥½½­¶Új³ Ké£0*/)Þ¹~ V—H™‚øh•ˆ!Q¤NÆ.¼kˆWh‚Z£{üÙŸôû\™ººTJeHPh>?œ>6³¨ð|HxDUEÅœ ó³³Ò3Ç&§¥sœbíêU?úéχ ‰koi —¶¨…†6µ¶¦s ±ýÛoýÃàôÞ?ßüÍŸÿ ã'.ûøÃIÓf>°Þ‹ã†­*+9vøàìÛï<•e4v?Önêìñ€îÚ9cö<—‹gT4€Õ)þöùçÍvÛ«¯ÿÅߌJILÊÏ:yêĉwß‹ gsòýå/:í«úK¯ îá'~xU¨£¥ùÜÙ\›Í>eÆli]F£Q­×‡GF]¹™Z£MLM/+º0cÞ–æ¦á!áðÂÏ^í0õZ­äžÃ©u¾ ÷õ›¿èîC{wE ¢ÑùÜóÐãÇ ‹Œ OHÏ  N=”œ>Fê9:*ªº¢lpüðq“¦l\³¢b‡Æ'$Ͼmá/Ùjµ,X´D«Õ‡N³!”›•6zL_p[@pP{[ÇÔY³ØÛŒyóÏåžž:w–”º~ÕŠÛß­ÒhÀÇÏ—1žÕŒ@ IDATX³üóää´Ò¢Žã.œ;ÓÚÒ¬Õúœb8Ç¡ŽÖf—Ã^Z\4XÌy9•ååv§Ëdìôõ¨o¬ÓëTgNžHHJL™­­-!á‘Ðe6i}üàí?ý6*fð⇟¼ì]¬;w¼¡ «áBvsIn{Y~{åùê¼#Ÿþíµ×_zêo/?Sx|7551k;5·1—‰‰VÆìŒ¹s1&0&0&²ëÃÞ훟YºpËšåý¶äy×¶­›vó5ïr1ÆöïÞµiíj›Õâ´[s³³¶®_½eíJQºÛW”— <Ï+¹pþìéì‹;linܱyƒÉÔÅã]Îc‡öW–3ÆZë:;Ú÷ïÜÖÙÑÞÝØbêž1f6/7B‡ÃQ]UÁ³YÍìƒ~³q4¶ßúÛ@¾ðï?¼úêž`Œ^ÿ¹›ëk–òŸ«ý–Ýfý꣥Œ±MkWfŸ8vÃÈ:vøõßýÚûÿ×a³š?y矔^b’W|ôÎõ?ÆöVÆØ±ƒ{ìÜv¹f­ÍŸ¼óÖ•–¥ŒÒÕË>ݳ}Ë5¦½­•ŠcÌa·v;¥ãµU]ÆÎÝ;¾6›ºÎçÊÏÍ9øÍ޼ìû¶mùfó†_oÞûõÖæÆzƘÕbÞ»s[Ö‘CÒ’ ¢øÙûÿ”ÖçŠO>ÌË9ÁÛ³eÃÊÏ?¼Â08,r§ a†1!˜ø i£G•h/ÔT×Õ×ÖHN•Š"Æ<Þ~êàÎ<Œª×Xm¦©¡SߎSܶpQ¡4{N÷çô1™éc2û´âÖ5ººÊŠ‹RFéÓ 8$lþn¥S('L™î> ÓçÝæÝ¸{cKïãwÙ@ •*:&¤}ÌJéš•+FޝÓéë+J%9ûÈ~Þew T¥Ñ™0YÚÁé¶¡câ†ÝBN‡=çàA'{ò™~]ÞºÛ¸)SØ3iÆœ;–ÜsîLîuC§Ó½üêk¸5 =iK|ô’i}÷ò®Sg/ؾiÝü;O˜:ó³Þeìðõ7\ܬ¹±áÊy !«¹Ë4kþ×<C`'ZH3lxB÷ñ°A10{þí ©o—ƒV§ŸéõL<´/15ÝCÙ…Õj5ØœŽY󮤀sŒ Uv—Â0æ4:ßq3f¦;…À  $íGHۨnç±§Hc^Þ²KÏZ]muG{›J¥f"2DRÂ{EA°  +r¸Nĉ§"…ï20&oò¹Þ7`ûƵSg@]eEKcK[k³ÕÔå:*sxÅýPQ°X,I£FݳGÅ }󋝨À¥•{æ‡'H^ŒIZú˜ëFRÚ¨[ê¦ „žxþet™Ýí©sn¿Îþ9…búÜ’€~ü¹ç/×lxrÚ°¤”~d½ßìëV7m-MYY'_úù¯EQXùÅç…§NŒ›)mà‡E\iÎëÏGAŽSBÁ„ ¢àá80Á€p€0(@$vì!ÎÁmë²±N…gówoÝÊaâr8UjÝÝÞÑË«ò¯?ÿ¶½­åÿüdô‡ò¢‚––¦AÑ1Qƒã£]ímÆŽŽ¦ÚÊq3ç÷õþ˜»žð¾·—-÷õ”çMÆ-ˆî˜,AcÇ $¿#„0ÂÁÆa„0Fˆ б;*0öÔÃb^µ²º£ÛÉ•KbE ôÂ/_>wæí÷.ùѯ~ÑGZ@K]ý´‹ž7£ª¼¨²ì|`PðÞí[%egÿ®íµ5•­ÆmkWôiÜP[“:z´¯ (Œµ‘!ã[ÖO=®N¡P 0ŸcÀ’Šõ¡ÆP¤'…2  ö(VÞœ—õ^ù‚ölÛìt:ˆR]SU>cÞØ+ôÜn³ÔÖ×¥ 6‹Y£Õ!Œå{y1ߺn½Ë)äž*2l¨4ÛCSCÂÃ9Â556v¿¶$âÛýÛ¿žsÇ"رau—Ù:iú ¯œ2¾«à$UPOb BRäÄÜ «y‚Ý©g= ÄÑî®×ûœÎÎF˜€(ð­-MaQg²³¦Ì˜e=ºoWmM‰w?ú´|W.qŸ8Å‹¿ü¿>SÒÝ>ÎÀ`÷>÷{oü1oá’â·cÝê—¨¶²tóÊwÝÿ 9tà¾G;°k§ËáïÊ5#0$üÄÃÿþû/½ö[ŽS¸œN§Ý®T(8*È“Óí<‘§à;üæfÀs[ƒ@)å8‚0’ò{è½<º—§¸»w1¬«¦Sšœþ×ÿû¿Ç_x)($ ;BÇäõt¸ïÑ'—>ü8ÆXº›~]]]…yù“f-'ÇkÅÊøÎ ,÷ ”xR{xp @)` @s=섽„¸j¯Óˆ”´¿±!Ôð7,¡ ÷”P°RŠÐ—q#òNZD?øô³Uååi£ÇÜb• âd\Óo<ŽB8÷ÿŽp˜Œ1€S€$\‘ +€Âë•u]ëOøã‡OL ïŠ 2.-°Οà8!˜pœ…… F¢ŒpÀ„@ÝÞ+âR¸7M¡ 2dÜH›ýÜÃò…<!  ž$æñ¯{Ç4\­z%»¨dÈø~à¿ð,cÆ(£ŒQikPŠÆÂˆ!ìvÃ{’òÈ,êUhÔ»úè@u:ù>Ëñý°Ïþ ËÊ@)eŒz<ðˆI4í3 ø#¨´Oæ ,€þ· :Ìò$Èøï™„Ü‘›Š«wí?oŠ ì]yý¡òTþ€¨e‚{ÿ5p²††Ü1£Ø‹G $•(äòB^I…²¡'C†ŒoKÃr{¯˜›(•1JjêI¾` (‰Q€èq½_uÔ¨ 2d\£ÀÂKù}Td"e”J¾,êD¨—"ÈãÃÂÄ+²A†Œï2˜ìÓø®˜„’=‡°”2(I(Æe€ ^lÏR1Ô»â(–eÖw µUßlÜèr¹:ÛÚf/¼=cÒ4yNEøXîÈ+·Ï #„€I샔1 îÄêŽl*7ôµ©[ùº¼ä2ÛÔýÀÓnòOeïÚ¶•Š‚(Ò¥>4<1E¾UÝØ³ëë yg§Îœ™6fÜ@ÚS*f9¨ÓëSGmokšœàëçGÇ .O¦Œïœ†Å(eQ†0ʤH,É£%ù­€AÀ(HR ãÞÜQ¿ñcë¾ü+§³N<óâË1ž:ëƒç]¼õ÷Ð¥<óä³Ï¢Pkµ*­¼-Õ ÓgÎ/?“¯Ö”JzóÊeþŸÿëŸï¬Z—’>úë5_&%§v¶·+8NžLß-``¨—QÇv[eq‘ÃéêjoomlZõù—N» ¨ŠÅ<á£RkÉû~Y€Õb2;K~ðàÔ3wm^wYc½ý„ääÕ_.«./ =tð€(ˆ­­.—S¾O½^2g±Ù»és¯ŒÒ¢B¥VŸ2*süÜ„ã¨(ìÚ¹C£÷}çÍ·JŠ.È“)ã;&°„‘®€0*Ғ‚v³\×ÜÌT­Ÿ_mU»¶ ê.ï^%±¸ËÙƒ„cû¸vF™Õ|ÙZ½9LJ…Ïœ¿ðÕ?ÿU*XnîìôÙ¸~½Í"G*ö…V§Å•¸Z»ì³©3g‡†?öì9N ÷æ¾Ðè|þõé©£3å™”ñ]Ó° GÔ0Ê€çùŽŽvƒ¿öÁý­u5Á!þ퀥Ôðˆ*æ%¶.­6€Z£ûtÍZÌ)²Ž[üÐ#—k¹cóÆ‘£20Æ™&q Bø‘ç^"œâùŸþ" 0X¾O}`1›Õ½É‡.­ÞšŒ›ÅÇ/Àû êê øˆ¢à°ÛáZª2*Ê÷KÆ XÝqWŒQ›ÉTSQnìlC#„TzJ­¢¢H8L8…;Ä¡WU¬nÁtI7–»À»¶oX÷ô_®«©¸ä ÚZšë«ÊBMØÛŠìw+š]UoŒÝ¨dNvù9¹½3ªD*@úðÑû¢bbÒgMUÙŽÍëV|ò1½”â¶a岓GÕ×V_íPìÙQ\pxÞå°Y`ß®íÛ·¬¿¶ o¨«þšçŠÂgï¼%ò®+7+ºpþw?e ‹¡¸° ?ûÄM|:;°s³4`—Ó¦®Žƒ»·÷iåpØ+ÊKû¹vžïhmºÎáœs:lýœˆÒ³y§éÞR%…҇꒒üÓ9ÆÎöjX Ü|;˜"ÔÐÑ‘sò„_` À;<5Ú\€Àa±„EE¹ìŒzÉ‚þã°¨(~üÏ¿[ÚÛ¶¯]súdÖ%Ûœ=}24"\Ñ‹´d?òÈÂyôŠfÑ__ûÕÙÓYìð߯ÿþ‹÷ÿuýkÌåt|³uË+Ï=U^Rt“–ñ‘ƒû¢â‡Ê:e4v^¹eÁéœÿô=8~Îmw´´ÔzS„x/Ãi³æÆÄ¹ªq6Ö×b¥jDJ£ô³wÿe4`â”éSg̾¶ EqõŸ\ó¼!ŒSÇd^ú½08&vÑ=KBâ2<1©­­µ½¥ñ&Ýèã‡ö3(”;6­ËÍɇÝAiß ‡ÍrìàÞ~žs…býêU9‡\»ð¤âšeË:Ûû+•e½õwëÜ8åÅ¥çrs rpLW{Ëéc‡2 òòsÆÂH©T"o³Z†'¥65·$¥¦&§¤4×74)é£FÈMJˆPïäg|¹’.§ƒb7~òTþ[~|GShHxÌð¤OŸ€!a䨰ˆÈ+´3abÄ èÒÅ KHJ¥€ÕÏ„r\üð¥…çfßv¾9 @1±CÓÒRÓÓÕÍE§ý«?L™>,)õÊòNGaÞ)‹Ùä!!)ºŒíÆÎ½tOóNŸJM 1FÏŸ>Õ\W òOå”—)•ªÚŠòÇ vk`h¸4ç[ׯž·pÆäȾo|ýüÓFg6Õל;“7txâ¯ÔÔÙž›u2"*úØÝƒ¢ƒ*ÊJýý|õ¾þŒ±Æºj—Ó¡Õ ”dûlΉ„”4é½È;›“m1u‚CÀaµf;¨Ñj1FÍMÍaaá*•ª¦²ÔÖÚÊ»œZÎóÜÒ–¦zÇq DFEmZ»zà]y—£²¬L©R*U*QŠÏž„tz=´65Ú`T¡Ëa;}rÔØ‰m-ÍMSgÍeŒÚMæä‹Èq)ÏÛÛã†ès¼«³]E`¬½µIçã;*sܪ¯>™‘©P*=:ÇUDPºœŽ™óè}Ý´ç6«Éb1{=/îÞ †Àùw-Q©ûßÂ2|ÄÎ-ÒFgŽkon²Y,CFô¿0°;° E¡µ¹Q¡RêuºŒŒ1¾>¾ ,:j朹Xr´£>öí s ¨4Ú S¦ÎÌL5:$,üR’›~½acañ…ÈxZVxÞf5óN{Á™\ÆØ¹Üœæ†ÚÚŠ²æÆº^ÖÐþ½Egó®Lvx÷ö£{v\8—ßÚXŸ›}Ònµ47Ö­ùjYCuåº/—7Ô×z=ÒÎß~£©¾f׿õ'º_9Ç~ñÞ;]^ª¬±£íĽù'ŽŠ”Â1F7®XöåÇï]Ì È»œ¼Ë!ð.*òŒ ïbŒ2*0FÙ Šº6;»-8,¬ßY]ûÅ'ƒ‡%|ñÁF¦ŽÖË—o[»ö¹3R½F+…VîÚ¼!&~H«±½àlÞé“Çy—sdFÆ{ÿx]ä•%“§ÏZ³bÝæ€©ËH8?tpܤɂÓÙÞÔ›uœŠ4ëXA~n[KÝÆËvnZ[ZT£2Çص.œÍݳcÇæÕ+lÓ@ú:“s‚ç]û¿qÛSk¾úŠÎ:²¿¥±®½©¡¦¤°üBá'ï¿#5¾pöŒ¿¿?œ>qtôØ P”›sàÐî–†š¾ÝRÑÉ÷Ý2¶šM›×®Ù·mSö¡ƒÛ×­c”"„ÒÒG:~îÚþóøÏ?þ†l릭¹aýª/7¯üÒ­F•mY»vÓš5Ò½.9—·qͪ Ÿ}V_Su`÷¶ÏÞ{›ŠÂç}px׎UË>ûèÍ7ºçgûƵoüîµúêJéLjȨڊRÉÄs­rŒ1Iq`¼ÓÙe4FÄÆr'ñ0 00I6`Œçy‹Í…p Žãcˆ,ˆL§ÓK´ÚW…Öæ†ÂÒ²ÛFfôÛòÜ©ã¡Qq[7¬ÍÌõί¿ñÞG‚ÀÿýW¿zö§?ýôƒw~ùû?«µz¨©ª Û·}sZæعq_@@|bÊúå_üð•W¥Þ:Z›]"2cöÊ/þóÈS/ Q,.8?uÎ|§ÍtúäÑ9wÜñÞ›ýÕ_—Ÿ<²?1)­àtö¨qãW|öɸIS­ó†u«zøáÊŠò‘£%WÝß~ÿ›ÿûóß¾úàÝ„ä$h®¯1% J««®šÐK¬(->—›§óó³YÍ­Z•RçëËBHhXrZº!$ôâËwØÌ Š”*¥^§£Œ)”J‹ÙB§Z­Ž»”ÎR^R,ŠŒ‰ëÇlÌÏñ1||}UeTìPkµáQ‘›-!9ÍcL1 NŸ<:÷Î%!A!‘ƒ¢¿øøƒûyL§÷©­©Dš{*gßÖ¯'Κ‰=EåüܤӯÎ¥Z Â#ÚÛ:¨ b¢8´{û¾Ý»ÂE "ÓhµHäˆ ¸,6«ŠC/üü5§Ã¹yù—Óo_;4,b¨UªŽÎWVZ¦V)´z_ظêËÆ¦@…‘K¤„®ÎŽ®Öf%¢™ÓfÞ~÷ý¡QQÛÖ®3ac¬µ±®$/oÔð‘Ã’FJ#ljiÿòÓ—GŽÍ Vp LÂ8zp¬!::8,\ïç×-…[ê«ü£ÂÇDcNá~÷8lTà1!—AE „Øy§Ýîà ,ÒúÊšNkÇÔY³o[|oñù3LÙ»L–®ŽÒ² ÿÀÀá I;6o¹í®EÛ¶mŸ:mÚ´™3Ý2´®&-}446Nóõ€ ¨˜sË¿š=gˆ‚P^\ ‚ÎÇÏÔÑÆÛeEZÞfµú…†œË?yò¡[f,X¸oÏv‰PFïëWSZ ¾úG{’(cŒQÚP_«ÖhEAF­æ.L8§ÓaB||}CÂUV”†…†×U×J¶áÿüÇÓ/¾¼cËFI•>r`ÿ”Ùs(eN^˜>çöc_Á„[¼ôž×^yñÍ?{ã·¯:ìVVo·Y|tº{zÈd2J–QXxxQqqôajÞ:0º_Ž"†Ý…F±Ål^t¸ÌF£¤*#D<é„RÍTYT|¦¨Œ ¢Óér8ìJ«Tj½¯Én›;g~`HÏû¼½¥©¢¬”©V«%§LQð÷ÓGÇöz6Õ×àêV¹¯€N£ùÐÁeC‡ëýü ~~>€Ðø¡A1QñÉi†à`‹Å" ¬èÁq;¶lð –r‰:]‘1qV«µ¾¾¾»7_ÿ€“ÇŽܽgtæH„±R­Ti´c¥J=d¨ÞGç°öØáé™ãÿóÎÛc'L:¼wOjú(`Œã8Ñn=rôøSÏýÈ-OóNtzŸÆ¦†Å÷? ¼ŸŸŸV¡8|ððS?z¡ÏµDFEGÆÄbŒ¤ÌMB¤¤„0º\>€B©ŽŒŠfL&ÝÐëµ4”¿´ÂÒÒÜDçççwåY=ŸŸ7jìø¦Æ:¥Vw.ûdÚ¸‰Íã'éôú’ ç†%¦€K©(bLDÀŒÑ”QcªK | »ÃA£;ßÍ)TÛ6mZ^êÞ?AnUQ¡P:íV߀ üœ¬{î ëð‰³çOš1gò¬yaÆ(ÆÄ[I—"6$³B4qæÜ¢â·KÏ;m–ÍfS¨ÔPUZ:kþí6«¹¢¤0nXâÂ%÷"Œ9Iˆ0AàEž—,¬àÀÆúZ—Ýê°YJ‹‹=ôȰQégrNJg ñÕ_=t¤ðüù´‘é’’‹òõñ¥JÅy‚l½kÉ"cg‡±£ÝßR:.!“9‹–ˆ¥”Šîl6 SÊT*…Z­‘Q—("ŒŸzö%»Õ¢P+€žR%V<öìO<‘&7uÔXp8]*¥4Z­tv ,*na mb–"ccµµ T©Qæ6bxPhxæ„)ë¿ü$4zpnNöð¤ÔúŠÒ¨øV‹ÕátJ_·Ú¡Q‘@ËÉ9%RŠ$  D™(8ìC† 4*sÒOžyì¹—^êêluÚZ#tߣJkÒÌÙ›Ö¬éhm}â…0›Õ œB9H¡T¹xIÅ(t´wœÝðÄ /yÜŠH 'T«ÕVÓ€4e1$% €‹çÆ<ï" Ž1‘R„òXUîZYzÿ‘©).^ðõõe”qÑùú9ìväݵÝnÆD‡]mRkµŒt>½ìÛ¶Ö.8¸ÿØ…#FDŽ=zð`A^îijv;`B„ çESpöÌ’{P_Y?,!Á×ׇw9SÓÒó²¦gN€–¦†%÷Þ±}Ã:Áå$q8ì@JŽ# T*z [µ¦ª¤è…ŸþâÝ·ÞˆŠ‰æ>ÿTö°¤”´Œ1kW,ûÁ#O@—ј”–ÞÑÚŒD±¼´Ø/0¤ª¢²¾©yذ¡;6¬^°ä½|“UÕ…çÏ+BŒ2ƒab  ³çÌ÷ ¼”wL:pÕµ¥¾Î¨óíG`%¤¤•—–äÔ+8Ï€HÄûo¾é´Xæ.ºÓm›‰Tr<øÄ3;·nAš”|×’{÷}³-ûø±9·/ây~ÃÊUicÆ„„…†» LÜöxòÈôÖ–߀ ˜˜!Ù‡Üûä³Òåx-é½é Äãß¶aÝíKï!„¸ìŽÀð@¨¬¸(sÂð }ïõ?ÛœÎg_yzíØxÈ ¥B¡ìö¸kTêöövÎ')mÔ¦•Ë ÏäN›=Op_oX—œîëïœsâDyUmMYYnNVù…â#{µ·¶سsÖ‚E˜<ò/ÿ÷*`òËßýQêY©ÑHå||ûÙß‘äá©gŸùfû6Þ'*zð‘ûï}ø‘¸a P[U¶gç7?÷üW}=cÞmï:¼SM]úøÌ„äT0wu~þÞ;£Ç¯¯® ‹Œœ2{žÀó¾ÙÙÚÖ>wámA!ßrÄÊß^û©áŸüáþ¶ÎYueELl¬©³Ó/À—Ú£X»ü³;ߣÒêÀfµˆ¢ =œ”ŠT8…[X8vŒq·ì(:FAÈ„d«Å¼æËÏîE@ט'/.ŽS6Õ׬üâó—~ùÞTf‡Ãnë^3™º” E÷Täæ6‹FçCEaŒP¯}$æÞIï‹ö–¦â⢠“§ Øéî:“Ÿ7dˆ!0H„¢¢ ¡¡aAÁÁ6«…Rz.?o舄 àp9ì«—}úð3Ï›M]…¹Ùc§Í`5ÕUÑÅ©´65ìܼþág_ì=c|eyÙÐá µ5Í-M#GgºœŽß¿úÓßÿí-N¡Æêjª||ýü ô'îܲ%155&6ΜΩ®¨˜5VïvmcÀÕÖU.\´ôèÁýÅ9§£‡Ç›ÌV‘w™2õØîZï“?~…1–sòxUqÙÔ¹Øå 2 IDAT3CÃÀWÿygÑ}úød9ˆ 3arÿ[½õg!Œ1ÆÇB0GCÕù§³ý}ýÂ#"FOš† ÀˆDœƒÁí¨êf«G×S³áßùCá™Ü}¾B­íÇ*4v´;®¦æ¦”ÔTQ1&˜¹Ë¨Öj8…Zz©z9ÑzVÛ¦•ËæÜv‡®wü¤äžpPÊ$õ!tͬy”RŒo•Êѯ½ølÌ¡O¾ôÊõwµqåç³æßá〮²ªÁ–u«RGeÄz.ï”Íf;qÊu cíŠù·Ý©ð¶àÍ£t×ÖMsî¸ë&moY·rÌØñѱY‡‡^f··¾ºrçÖMO¾ðò•{{ã¿YúÀC±C†Þ"³g³˜·oÞ°ôÁGàôñ#N»uÂÌyrºc@€Üµd‚1f qñ´ÕduëØÈÊÀÜ>‚~•·>ä[`pp¿Ò $—dqt &?CÐådq÷'‹ÍQ^ZššÑ+Ezar“¡÷;û¯è&-Ü>»Ë;·Ý^_Ç©´:ê®û¼d`c´££ëžG&Ý“ŽH™Ÿ—2Âㆠn»k©´‹š’žqýÃX|Ïp+áÂù³£ÇO¼y7ýŽ»p`÷ŽˆèÁ™“§u´·\®™J£M;¡ßÞ^ùõo¹…ÒÝW~ñÉÒ`õ55åe¥Q‘òaIϦ'¸1ãØa#HT*•Ϧgã£ÞeÝÑ• Ë´47¾÷×?c"_¿ñ>Nåú†ÆÔQ#oêÔܾønæ{B(]URl´ÙTjíåf^ø€€è¸ørÒÄÔôkû"ÇqÁ¡ð=EbêÍ]·¡so“†À ËNcPHhPHÿ“|KI+xøé)•JÖÔØ1qbxøÀsSH)!Œ„p‡1F»ëŽ¢îrÉÌâJ½,ÁËêYeE…ÏýüW&c»Íd<<¹O8»È»,¦Ž« ½¿7ɰ”‘- u.}°ð!#.×Ìdìt™->~þ CÆ- ¥;~;þ*Œ`À¹#»’jŒ‚¾È¼s›©§ô(ë-¡˜Wìè%0aê̆šjŒ8N©ò÷èã¹´XÌüá¿þÞçWy§""£5Z][KcW—Q¾ÁÜ»–¤ŽÎœwç]ã§Nëó«®Î6)ï4ëıy šJ»ÓVVVÒì¸/CÆwä'Ï>.±õ (/)?¾ORÚH|M;ÖÿSÐé}8NÁq ½¯÷qAàüÈýº€Ñålnjš8m&œÎ:eêh®œz)CÆ­a„AÈÃ*Ť"€0„(„ÝÅLºß%#00âÊÛjARø;éÙ’ûà?s€&Í»-À?"ù›­RG))),-*LH)ß•k¼—œbáýW\¨«¬¼ï‘ÇÝÒM§\¼ÕéL4Hž"ßùEî¡ÈÞܨŒ1†˜”½Y½wѵD`=ý³_Ÿ?}º¹±ù©Ÿü‘RJÕ*Ewl´ŒkÃÂÅKûÉ?iÛºÕœJ.ÏŒï:Pý™£˜#Žãሎ#„Ä ‚c 0ñç Ϋ¼ ¾N²/›Å´}ÓF§ÓyïÃyj_È!CÆE«îìŒ9Žp„ãÜ¢ ÂaLÁÂ0ŽŽô¸±0ñR¬ˆWe÷k€‡HZàB˜È<.2dȸ‚IÈ0–ªa¹MAʹ-AèMþŒ@*Øà eèöŽ_O¤»û»Ý©°2dÈq9`@Ô]]¦[ã‘ÊŠv{¯P÷/¤ÏÈ‹KU¦}–!CÆ·)°$% aO¾ ;Š!Ä$<£À(°nú ï\ä‰E7sA† 2<‹!`žÿ<QFIz„°;vPoŠy¤Ȫ– 2nºÀB¹]V’„¢”6×7¬úô³ºŠ /«Prl1  zŠŽ3´b²†%C†Œ›.°Xwà0„¤pi|}†ãôz&™„TpÓO0ä|ðb«§ž¿eÈáy™‹‚< 7¨6ÿˆ}…0BÀ8…’#JL€(Õ€«T@8 D ˆ!Dì§Íj3‡"„È@ŠÌÈ!CÆõƒ“|U¢@;ZZJŠŠ;Mæ„aCx†?~ßâ»J½zýFƳfÏÙ´~ãwßåãï·o×¾ÄôÑg³ÞþW¿%Ru|·I(oÊ!ãfš„’©çr:›ëu:ujZ’Æ×'!%9uD¼lp\Ü’Åwú©UI©‰?zÿ˜)“óOœ˜>{Nê¨Q]­Eùg¼ü’!CÆMXÒ?DÁù—Õ4œ8|3†Ã)”*`,2b0Zš›ë` Õ•Õg <ðp\B‚' Ê&¡ 2nºÀbÀ*¢Ë5~ü˜„Ñ#›šž‘ "vÊÌÉj‚ꪫÀˇ%C† 7äågCS‘µ´4W•U6»!$ØÒe:~2§©¾iH|œNïJ¥R«‘œ GÄÆmZµîü¹—Ë5vÊTŒûÄ‘~wÁd™+CÆ-T“wˆp ,ˆ¢‹2žŠA¾¾ˆ(€#N Õjµ:ŠV‡ÃÏ`*70Ĺv•Fç)ëî]½O~æeÈq³ÀIWc¥Fáƒ9Œ1!„S(0ÁX­‘˜68ÂùùùyRQ¥Qˆ^rŠÉÒJ†¬ÌʸÙ"¼¢ÔÝeÝF»suvדAÝÅÞ½«ýìÆ’qUz½<2®Y`IõD™;s°ç-È€’*¸#ìU¡¡;´½ß•''ëÈ!ãÆ ,ä!F•й0½¸¼<1¡LJ!dá^$Ì«lƒü"•!CÆÍÔ°!© ŒD<€êOÝ•ü§²»T¶^DG(ǎʸ±kózc{«<ß…$‹ºÿA’æÄ(ukU’ž…%u yê##/MJ¶þdÜ¢Pë|ÐÿwÜ÷ùaäÜõ#$éQˆI4:€ /ç:`À(°îŠ£àåk—Öµ-,ôÝ?Å- ›Õ ì±=ÎŒ^TÖÊ7é’8›{jÓªU¿Ù 5¥ˆpmµ•{¶m0®(-êJr“QQ^?<¡ºð\EÑC`[[KUEiÉ…óex—3/ëØ§{cÇ–@)3¶·\Ϲ Îå7Þi1íØ´ÞbîÊ=q´²¢”wÙs<Ÿ—ÓRSùîo—w:›w:ã¢N9È(uÝhfä¸I»¶m6g^}YÉ@Ú7Ö×OLÙ·óëÄÄÄ€À`DˆÃj–×ð­%°ÀqÕJ£Ôýž§n¦/©5½¹zße‘’>*$Ô "`B4Z-9ZGE!6(¡oMS*:lVÞn·9v›Í* ‚¤3µ™Mþ¾:s—ñøÁÃfcW]]CÉùb„hÌìiþ~¾N›Åér™ºL÷\SY.ü%OÊó®ýßl;~pÿ‘½»LV³‰®©¥ypd„Õb5¶´«”êüœ¼¶¦Öºº:'CÓ–,òÑèZk+•J•Ùlæy×Gÿ~›ç]7v*|üÛêC¢cúm)ð®€àPp9¬LàÀd1›d/Ò-&°`PJ£ ˜@™(Òžh,ä6¡› LÒ¾äRîý®\„Ø?zü$«É88~¸ÙbUku† `L¸Î¶Ö¡Ã¯«wƬsIÑù>‡·o\k±Z ¸àü–µ+»ë¶Cßìpج“™ç]°R£ ¾ãî»SFe̘=gÞ¢E§hmi™1."$Z©Ñ ”†„_‚Ú~ùg ü¥G¸Ì “ìØJ8ìàhìhW(”­–äôŒwÞi4$¦¥ÌYºtÞ»(c“§ÏJÊÈ ‹ÖX_7$^©R?òô3+?ýðÆÎÿ¢{ŒOMW(Uý¶$„kj¨€Ö†¶–†0uýƒå5|«iXîjí’V% "‚Æ@bœˆ'˜;ª”1`¨‡DÇe*¿R. ‡ÍÚÙiŽ×~þ3s—qDbÇqÓæß§N>wþuvþþ›;›“ÝÛÍILI €¤´ôØØ¸IÉó/ÕùúMwÛ²?=~Ò¸i³.–¬O¿ø3L¸i ÖÕV;^£Õ_|Æ@ƒ?wÊ[„±Z««¬¬HI €2&LYµâË€À Ÿ~Æ-]Q)•Òç Sf¨5ÚŒ±xÞYQVš˜’>~þ.‡Ój2ÞÀù7i´º~ÜmÍVSÂÈét¶µ¶ÜÿôÓ©ã&•—ƒ8…R^÷8IT‰ŒÌC”! Td ˜Q \Ó ÁÀ( @Q@\oY„œ?“ÔÒ\÷÷wß'çØý«Ù·ßu«uú1ãÆ·µôr6•œ?{÷ÃOtÿx:ëDÚØqÒgÿ€À'ž{¾'¸¯ÈrŠŽ…èKŸQ«Ó!Œ¾DdSEI‘Z£Ñûø€J¥~ô‰§TjMG)cìÅ_Q©5÷?þö„„ Š./)JÍçݦ®²Ôf³sJ%V¨9$ …D«äh ‹ˆQ\ŸLÉ9vÈÜef4ïŽ%ù§s2ÆM¬É³çÊ øÖX Æ0£„1F(%‰"E„Ã!)X”Û*””.…¢G(17ïªW4–,­zpêäÉ´Œ±{¾Ù«P_C?&ƹ¼SgóNS‡ÓÙe"þ~®öN¢àѨ§/¸}ða9KÁ=³Í;ÆÎogÖ…óK|ÔÛD½ÚK0›Œ¦T«1ÂTFN—(ðþoÉu67'eÔh„ݧÐè|bˆõRˆÚZûF¥ó47·‹LìN¥Q Œ*8ââ-°k«ÚZ[üƒ1&¢H™Èc…1Æ»œ"Ï«´:!v»M«Õ„ Ћɏú«/ÿñþÇ_~ôA|r2§PHÒ †ŽH”Wï-ªacŒ!ŒÆ€ Œ0Œ˜[QŠˆ'@” Èí¨ì>Êzÿ‘#³@øêò’'Ÿ)'ûxöñ#sö¯R%¥¥'¥¦ <ï·!åV~R¥êí¿¢õõ żËU_[1q¹œ€zD@[sc4$,|à^±‹_6Û·ll¬­s¸x¯_ŹsF“ØlV âó¯üL«÷ínY˜Ÿ»à®»¯gÆ:::#"#ûtºœ‚Qi:• ½Z¡T NáªÞs¢P©BÂÂÊ'bA©ów:í¥Riîêt9lV»aì µ¯­(Ë?*)*¸ÿ‰'¯è-dŒŠø+õÕ°¤@Qémͤ ,`1$ (ìÎ"DngHtÐòUðÚc”u+¯UNÙ]>Æ)”ÓfÍ‘H8NÒzÂè2vÙ™Üìì¬SˆQN­F"%€0bF“gÎŽ‰‹ïyŒí¶¬“'‚±N1(4ÿÜy?ÿ@½/ÆX¡éy†ÏdONK•´*QàóNÌ7ùŠC¾Ä¨î{èñîÏÿë¯?ÿéB¼!ŠB[sSù…ŠøW¥’’uâÐÞ±“¦ã«I‹iijœ2svŸƒaá‘Îát¨Ôsg»Ëéà].§Ýiuš† ‚·?=(Ä-š©(`L¼ßÐðˆ‹Oçg ©,*ÊŠ+9æ¿^·º¹¹á©^‘Wõ·øü°‹Ýœ›Ð™1Ê0w˜ƒHÃÀ1I—bR²!0”   s—en£€z+*«Wî¾R™9nL˜2 ê«*J Ïhõ~TÇMŸ}ɯ¤gŒOϱžÃ¤‹·K«ðÓ…$ Ë:tpî„;õ>¾ Öè$Yb5™Ö­þ²±¦6 (ìlΉÔ1ãëjt>¾’¤+/-KLM½†+rñeôb thßî çÎ/zè¡ãGŽŒ™8)88´­µÉ?0ad5›+ÊKSFŽê·s‡ÝF©èçoèsÜß`ð7xÆÆöÛυܼÖöŽ®¶ÆIsæ\q›/<*ÆnuÙ¦¤ô‘WîsÚÜùw-/éo—z©s“Šö1Öm€`Œ î.äàV¿€1ÀE  ^…’Ý~ yª/ ¥F}¡àlêè N›åÊž>t‰{w‰ÆI©£š-VGP¨[³@ƒlV‹Î×÷‘§~Ôý-S{ëÆ_<ñâÏ¥›W¯`ùâOk«*V~þÉ~úª4l¢P oìh ÷žÕÁƬøøÃa‰ .§#ïØ¡èØ!{÷ìè©§úLNMYÉЄ4y ÿׯÆÁ„G”!˜ps!Ä€1Ôm "Aî-B,…DHäÏÄó É&áe¡VkyPhõz›ÝqC&*ÀTVpvðàØ†šªîƒÓçß¾cóJEo§ññõóñíêl¯­(éè0F%Ä_ƒ´€°A11ñ0á ¡Aj¢hi¨íh7RJúuö7ÔÕÌ¿c‘qfOÁf5;NN¼Ó‘uüð©cïÚ¹eÍ*ïÔ* [6¯žš¦Ñ\Ncpáü•FÁD±¯.=8!9E^Ãÿ}Å“êÅ`$eçx’Ÿ»½V ºËfò˜~}E“tú…Þ×ïùW~™ž9þö¥?¸!ÚmVžÄqa‘Q=bQ£>g~Ÿ4Œ±Êß5˜¤Óè®íŒ÷>òäåâ°úÀÇ7P`0„„û÷+cââEÅ\ÿœ „^øÙ¯´z¿CûöÜýÀCPQRlüâ½÷2§L-).ò^¡˜p‹—Ü;v¤´Ñ#õ¾¾g R2Æeç´6Ôõé608D~ßfbåéƒÇ‚ æ0!DúD8LÂDÁq„#€9à`„¸õ,„= :’†%íù¦Êø¯ƒ1Zs2rȰΖƸ„øê?ïGFG#Œív{``ÐØÉS/ùE›Õ¬ÕùX-&×Ö§Œ[ œÇÀÝ+Œ1ÂcŒ%7–ÛÙ‚¼>ã‹R½ã°d™%㿉ë×”]ðÈ¡Å%¤0JóNŸºûÁ‡W|þ±Á`ð6ìr_Ôê|@–V·¶Àb”R† EŒ0‰q^ªàR¼ƒd/2 ¢'5§[(IŸˆ—(û°dü—! Ù[gãÝ;¶9ìÖueEªk”JuhHhKS#;ÛwnÛ¬Ñh¯¦y1ß‚ Tà ¥¬¯$„<’H*€Å0 ´;)§n%GcõƒÚª _?¥J{*;~D²Ÿ¿?ÆßžZ*|SCŸ¿cmÕ˜ñûü¶¢¤°´ðlΡ½‡=-cÜ=×+IîÝ9cÎ|§Ã¾ßžión„‰»~Ë…3§NÞwhû‡Í286.ëèáu™#ÇŒM™&ŠByEEDä ÈÏ>aéìhi¬ë÷»ÙGQQ¨®,;w*»º¼D^±·8Æ€ó‚zÂH{"¯˜W€òhR˜ô®„E½ŒAÙ*ì Ql6³Z¥V¨4YGM›=·£µ¹øÜÿ³÷ÝáQ\çúß™™íê½ IH$„„ ¢‰Þ ˜ânã’ÄivÇÎM¹ñMû];qà lŒé½„B õÞ{ïeûîÌœóûcv… ¢˜â8¾û>zôÌîN=s曯¾_ñÜ  T©¾³3èíÒyõð`QÑ5¿©Ïêës:Íôˆˆ©Þ>N÷ ž6U£rtqmh¨[u‡kkk_ºjýpWç@wGâñÃU%¥~!Ý]éi©VbéãO?uùüyWoo–emììÛš›ÔeZÙØØØ;yô¹Ÿ¼,‹ *výÍú-Ý~á¾¹BƱ¬N«žyè‹O}ü²LéïÀ"ã7›ebàºQ n,La¶šÀx‹, ŸïìÇѨëªêøâ_í¢¢(êZn®ŒfÁÇ5=¸õމÄ*µŠÅ˜Ör@ðÚM™úñ`¦²¸ÀÕjoG»¦¿_&•‹¾ýþϲ!­^kkçhgg§RŽêF•«^úùš[4jå•Ô”5›6c—.$†FÇÖUVÔjƒÁàæáù -ßÜ+qóæëtºÊ²’YsâFÇ”s/®«( ‰¿Í,-..ª«,/(Ì ¥Õj9Ö(K,søû¤a La„)B ­UͶ"€‘@ˆŒÆ¿÷UQßT©,Æàä°±µóšŠÝÙÑ1'~áyÖhüäÝ­{ôчwè+iÉMõ íµÕ3æÎݸi›ƒ³«ˆFN.³.tr÷¾q6ˆ%«ÙØ×Óãæç_|íê’µë¿íájÊJ¯]Í*ÊÉÞðÜ óç/\²|UâÉc=óÂÓ?E$‘@O—Þ` i†X°T&WÄÄ/3¢Ô” ÛžyáA]u^vơݟ1À Žüýã`mc348??áöïT;[;B€'$"$K¥eÉ×ùµ¤Ñ ƒ(DÓ4E‰†aD&?D‰hš¢hŠ¢@04€Ð5‡69ã¯g`M4-¸O‰Å’„«H^FZìÂ¥ÐÓÙ®Õé§=ÔC'Ÿ8ÜÝÙþü+¯ k«*ä …ÏÿÛlB.ÊÍŽš»àwþؾžîçù[áccmõÔi!ãVÕà@_OW× m z±L®ø7Ýœë–^§-ÎÍž>+r°¯ÏZpÊÙ+7l±ÌÞ%èSKÅ\VHƈFøzb Á@&Šªq}êVS-âuä_ÍúÅo/tAZ€»—ÏwpèÂükËÖ¬ÿzgŽ`„¨{“VPœ_²rÃõÃOŸø«“³ëͽ¼ÄRÙ¿ë¾`ž¿’~ÑÃÙð#‘††¹{ùX)¬ìB‹ò¯Î[²Â2u¿o&!"Èć%dc@0%4L½ž¨€Lž RâÍ© ÔMéWÄ¢jݵrŒ…09ŽbnÇ%]UV\R\€¡ÅRL( ƒ(ŠBæcãxxOù¶‡Öë4µu¯üþ¿¿›+5ô5µ%¯ÎøÃÜgFJRuy91²£Z5ňgGG™\jÔé¶<½ÝÊÆþ~v^Y”ïë3åìþƒ¯üùöïþ4 d†_P°ðSdô\ËÔý ,L€ºžÌ` šy±Ì}(ÌÖ±EMˆR!u+ôõõÌšÝÜP7~“8å IDAT+vþí× žBQ ˵j•D*@‰0ô½°æ—xO °¶½¯§:;=­©¥Y˜ HŒ1–ËäjN&¦|ýbæ^¿¨¢k9žnV6vpôæ/])h:BјPŒA!Dnp05ÔV'''K)¤°·¶“HÇ´V­UØ)ZdäXÐë Í<ýÜKEÀ´™açΜŽ_±Q¨¹±,Áï»À,B“@ ¹W¢ŠBF„Lè¥*XˆÔ7eÓ¸´Â–¢Â›áààØÓÚ{ÇùµŒ´¢œ\Z*“*ä˜ç™`Ž—ÙÚ.[²ÔÑÅí[k…ù1ñ÷«)L õŸê§°¶KdQ”N­K$”X$•|Úk¬©ž3oþøer¬¢Š¢ïçèWR“[›êh©„¢%•R‡ ÂX*‹jó¶§Ö¶ãkOü¦zGˆ¥²Òœìè_¿VV\97þ67èÈÞÝ!¡‘Ñq–ùüoÖ°(d"s¡ù32Õ µ8HHb@4˜š‚ã ©X®[b¬I`ïèüã_ÿ* 󚛜œ¼ü}ün^32~ጨXÑG`÷ŠÒ)Bãõ»GsC]n^nyEe0Aõµ•AÁ3 ¢´H!—ú…~;;AP ®q[{§Öèé<}âX[E¥·çÅäs+V®€’Âkž>~žÞ÷3z‹W¬X=þ‘ç9 @3¦KSw—›ßŒ!hÝÆÍ·YSnekgg÷PæÁæ¶ÄÜB”PDÓM3ÃÐ%ôfhšfšQ h(´YrÑ4Pæåë–°L[Æô6èíjûèŸÿ<3lѯ€à‡z,Bù‰†dK]µR55·§³=ùÌÉGŸxÊæ&¹óÑTQÖÕ×¹`éšÞ®ŽÜŒ+ó.r¾?Éõ0pdïî°ÈèaÂÇžöfV[SY¶tí‰Ta™±ß7P˜Œç¶c3å(º{˜`‚ù $  ®gÂOÌÆÂ* -˜™—Ó—¬^×ÙÜÒ\×øÐßEÝàöÒi5=í„àƒŸêãéó°ó!5záx8¸{§›§‡ÜÆö;펖ƼÌK:&+5‰çØ›:ÎL¿$’)Ô:]og»iÐxöã÷Þ­,«¨«ª¾›—ÂõGÂïЇ5ÞVBR&_û¸üSBù/*š}M Zî€-O=‹Z´t%úw¤#–²z Ïó {;•FM3¢‡z¸ºú¬Õ€•½}IqQxäœûÑ¿í¼b£NÓÙÖ:eÊ^?Ð×ãæéóMN-HXz£VØÞ½|íº²¼ÜÖæ¦°;Ÿ0²8é¿k…„ö¨·Ÿ$—éï:0, 'N£ñ™DY¤ÕÝh=€þMÉÓë6oCÍ0¢5›¶YYY‹%Ò‡z¸ÍO<'¨ÛÏÿôUÂÜ—|üÖóJ«Rɬl*s 7lyª¬pOü¢Åw³•ï”)ŽÎ.ÓÃg»¸¸X¦ë÷ñ j.H£hЦÁkEÓ cZ )Š¢hFÈtG¦Võ”© ´É‡æwdvcYœî|_xä€D*÷ò›280 ×h–¯ßh“ÿt\Ož2G M„~æžÈÄ $W †!A˜ðebEF06ûÖ‰™ ~¼w¶tú²À ²À2;Ë `LA…"Bb%xã)t½÷Äܸ18¡}ô®w ,°À‚)°L9 ”à\Ç×ÅŽ`ðB€`Óß7úåÉþ`‚زÀ ,x°‹B&cAp™9GÍ?^-“v]šP9Hð;²X…X`ÁCÔ°ÙãŽÌÖ!|™YL„É€LIXã"‰ðæDjUÃÖÝÞßÙųF­V=24P[Vl™=Xð] ,ÿ Ô)§c &:d„À,¤ÆÍG³&†nn?¨ÅÏã¢%(Vµª±©¾¥§³k°ïZQþ°NÕ>ÐSVVj4aœëú!\81ý}Ü6Df7Ö½ÀÙÍszXXâ‘ÓTM†’¼,aA,•†Î¼ÏvR7 (8tÅêõå%%ë·>±0a M3>>þjµzÛó?âX¶½µyNlüý쿳©îû&°hFôÑÞC÷Юõ[â¡ëà=û¶§Ÿ»‡ ‘ØÃË›MàÂ7OÅþž®††† B÷züü.¥³“‹ÛúÍÛî÷‰¥(‰L&X9ó/óòõ»ûm~ùÚïDâÉ™f“޳µu˜pÝä^Ïf±°ðêë´²±‰%~S§Þó¿qƒˆÐD•G+…µA§Q Ú+¬|¼}ú{ DS`ÊSï!'‹¢ÍAá?/ô‘6ߤ„¸‘fÄ7ÝÎë+ „lí1Cg{iTcr+›ov‹3m2<ØŸ—“;ÙÙÙ¯\»Þ¼Õf)!dânøxÔT–;8;;™›\Å.X ºH,Y»iëwBÜ⸠ÕU¥%žþQÂ÷„`¡÷ƼF¥RXYQ4#\ ϱÊÆÖ0Ï©UcÖ¶ZµRhɧըä ë[‚rl˜F ` lçà¢×jZÜÝœ]0Ï·4Ô)llìì z}oO—Q§ œ>S*“@cmmOoçÜy‹h†1èu%yþÓlmí$r9Ïq…yyÎö.ŽöN®=í€(''熚*[+/¿ lm¬¥iÑ̨èÉÇŠ@eIL®ðñó/*(ððòð™2•R^”/•)<<=Xƒ¡ª¼4rîü’âÂã¸ù išéhmjijžâãíå@MÖ\¶½©þJÊÅéááQs\¹œb%SØZ[·´4‡GF¹zÜRÁÁ˜¿’rÁÝËG94€(G‡SΜvñpg9nñŠ5'ïc8=åÜ¢e«›ÚZ›m¬­šñ <ðÕO·îŽÎY³5c#íõM¾AAC£#qñóºÚÛ›ëŸ~ñG¡ÓÇ÷vÿèWÿ•Ÿ›|!zÞ‚1µN®$,_5<ÐW|5‡§ÂWnØÜX[uêÀY‘‘´D6:6´é±§ ¦¼¤·»ÛÓÅ׳ÐÓÕùùGï=ûÒ}ýƒŠó²»{ûÛj«žzéÇ¶Ž““;ôº/w}ØÑØô÷; ò®&'¯Y¿¡wh`ttdÍ£Û:ÛšsÓÓ‘8`ÆôØø…Ïžâ)ª¯§ç±'ž–)YiåÖvý½=ˆðR…X*©.+߸ñÑGmÿéÏÓ“Ï[ÙÛjTêe«V§€’üÜ´”‹¯¼þ;‘XJQ”V­)+,èîîš'—Ë}ýUÔœ9,¢êK ã.ö ©«*kª­Õi´ó–¯tusŸ\ = åÖÖî^ÞöŽŽ4ES4Bekkëááy9õò‘={/:{æð±ÖººÏv|´ëýó³³Ó‡ýíwo¤œ<³çîô  ­©ñü±#—NJ>w²Ó/%;’“v®«½…績_tíÚÎïbž¿xêð[¯¿zöÈþ/v}|òà^áTŽÚúøÁÒœ+¹àLÙóÑ»%UŸíxG§Óœ>´÷/oü"ñèáw¼{-3®¤¥6ÔÖ~ùÅnÎhØõñŽW^|j+ËùÌ“µ•åû÷îyuûSœQßÙÑþú/~zßî³Çïùøƒœ”Äs§Žïzÿ­»X%…~hBϸñº5/{_wÇ[þé}{ r²¿Þù!k4Œ¿Þ¹£¼¨ðàî]ƒ}=PYVÚß×[YRÄê ;Þú[fê…î¶ŽýåÏu5¬Ñ˜xâè?ßüÃù“GÞûÇ_ÛšŽ|ùEEYõg;Þ€±Ñ‘ßýòg§ö~‘Ÿ“³ûã÷’޽œœ¼ÿóOnu2­Mͯ¿ü£¾ÞÞáÁ¾Ë©©˜çßyó>>çNk¨­$·¶u~ðæ5ùù¿õ/oß#û¾Öj4péܩޞÎY³çùês£Ñsùbxdt}UU{K#Ëßþóï½|¼9Ì}òο€¢é7~ù3ŠBV¶6{>ýX£~Ï';ÂçÄXCÒé·Ò´¬íìßzóO´Hì;Å÷³Þ€Šâ'+kë3'YÙ;d]¹ÒX[9'î©cC¤¾ªqøàÞÜ+iz­ñè×_ ¨†‡’ÏŸÓiTƒÃ£çŽ¥ÚËÛ÷Vh4èŽìÝ£U©Ø[WSÕÙÚž”x&÷JúhßPÒéãàäêñÙ?ßîhŠVŽ)÷|ö鉯¿rõ™šš”XSQYZ]R[U^YZÍu-Õ5É9Öhmk?2ªJ<|ÔÚÎîô‘Ã}½Ý‰ÇŽÕ•大äe tõž?y €¦CfÊ…3Çmùg0ÅÏ¿ 7/+õbwoþ¥ô¾îΊÒÒòükÎwjà-%nýÕ ÅÐ ƒ9N92Ú\ßÐÜÜæãã5#"ÜÉÕµ©®!7#{zxؼ% •5Õ…W¯yûù–—Uúy{EÌ_°ëý.].³µM<|pÓ³Û9#«Q«D2©““ËÜ… »>x×ÁÙID1Ñó::9úr·­­A¯ßòÌöŒ‹É§\³q£TftêØ²Õ«–®Û|âàלÑèää´o÷g/½úë¸ù G¾þÊÝÓC¯Ó,Z¶ª«½í‹v,[»V,§&ßôÄã3"æüõ÷¿âðÈæ­i)eù…+7mŒ™» 07;'+38pZNfFHXèú-Oìݹ“1ó,J:{:tV¸›»û©Cû#bc7m}Ð$®(Î`¼œœXVQ¥SúnذÑÎÑŽøÒÃÅÙÕÇ?`ÚôÛ•rôؾ}F½vÍ£›Ï=*³¶zöÇ?=qð •UpxXÒ™3ë6l°±wøäýwf„…­~äQVsòÐw7Îh¬¯©Ýþ“ŸT•—WU…†Î˜¿dÅà@_òÉá³£”Z•jllÞÂÅgŽöòò›6uÊ¥ŒŒÈ¨9ê±±ÒÒâØøy3#£o=( ž†( €d¤]’ˆ˜ÐðY¹™s-.ÎËÅÖ¸hõº²Â|B1z­&4<ÜÚÚörrè°è(§1åhWSkKGÇ’¥‹¥rECmõè舽µÝ§½÷Χ» ¿¯77ãÊŒˆˆæªj‰B¾`ÙŠþ¾KÉ‚‚‚fÇÄ"DÝ:gª§,7/"~nYÁ5'¿ iZµ¦²¤xvl¬ƒ“‹N«ÍÏÊtptÀµµµ®Ý°É ×æ_³¶¶™5éÕjåÈðD,–H壡¿¯ßÞÞžãX…Tˆ%vN·1™8že1!Dh$uCä„` wÖÍï*ñ†ÙÍûœts|†\ßÄ|zßøò¶å9vB]¡“OÑ æùÚÚš iÓ„’ã1¢Ñ¡ §ÏxûûŽ\N>÷×w?”ÊäÂ\¢(FˆWBhš!#Š"ãÄyæq?+B°©ûûXŽ•Ëämí^¾> …¢·»åíë{•LQ4ÍÐÈÀñ<1€ˆ\*±VXqdR+°„fh†1^*•@4¡ƒ(ˆN…aD„ žãEbÓp°,/ô7ÄP€xŽC”ÉÆ\XGй8ާ(JøfBdLøˆ„ûD0&“ù¿¿¹Õ½Ño tòÙŽw]œìW=ú¸`¤X`4èÿôÛ_½µãSËPü€ñÅÇïmØú„£³+œ>²oźM2¹âßu2 1ó_Ñ c#‘R4MÑÂ?Ã0R†¦)@MQP0bêñ%¤; ˆ7×?Bˆ‹Æe„HÄL”ãyRㆴYÃÄÐ3á× o ôæÊèn×ûNù¹qý}=îÞ>9i©q |ý,óxlx°øZžÑ`ÈIO‹OXb*ÖnÜš™–*“YñœqJ@ð¿QZªÏI¦¡á3CÓ4Í0ˆ¦ŠúÒŒiÑ }½/!ejþ,4‚6Iú›Ýê'.Xðæys #æyîþÚÐ[ðq»¹I³Þ¾k k"!ŸàzG„ºns“ŠquMèè… Ð&„HÌE…´ETýàAÑ´ý°H«ÿ·›ù^œAB”‰ÕÝ3¼¾(È&$xìи‡˜t+B&ð,ƒ¹¯ê¸×Í ,°àA ,d.œPD„„€¢„zAL0‰¬2¦f:€Þ\ð<1:`áµÀ ´IH&€PæÚf ‚ á(t¯‚yD# ”ÉZä дÙHœ¨jÝ ªþã8gÈ÷ͤ‹År+››k¾Ýæ IDATâ9#E‹î²:ò{ •rlhp`ÊCŽfä\N©­¬|þç¯ÞÀXÀé éi)Ž..³çÄÜÃnÓ’¥"&~Ùªû9·®ö–ŒÌtåÀ fttÚŒpQ4-|Nìwyú;»Š ¯¹zºG̉»Ó#BÚ[}üo¿–F¥DE#êJZjdLÌxYî½kXÁc^­Vµ64´Õ7h5j“Qhæõ3p¼A§ëéê62\w§ÉéâåÙÒÚ¢Ñhnµ‚Q¯+È̓Ñpp÷çw´¢òr2ªË%rykSÝÝd\ßY`¡=¢€ ‘D"²R Œ )GG1½ılvÚEJ,á Æ®î~ æVõ×]ÈÆÞa¼òîâ™ãóàáå½âÑ­è¿Ü‚§Ç,X$,ç^I›†ÏÛ?`õÆG`Þ„€4…¬lì6>ùìèØ-Ÿ7—lÖkUsbc—¬\µfÝ#üÍ«œ Qô3?þ¹‡Çäo§~ñ«°ˆÈï­´âXcNÞäOϱi’„åÕ<úÇ¿½ý°O!$—J&ÕE%R™µƒÝÍß³wb4$„L›:s2%}’µosv<Ç–Ï2kUS§^:sì®^i'³ðÈÞ„ô ‰%×îx-mÍQ1·T¯ªËŠ3.\B$éïþñ¶ ”p{+ê˜%+׆ϙ "†¾“zuW$ÆÔ$€¡-‰D4ƒ‰Ð¦ž§˜¦hƒQ?82bkc³~Ûf!KHÎäy h„á½¼½¼¼<°F­»œvyÉš CD"&.>^H° eh†ž4ïY¯ÕP #K„á¾unôu“ç9ƒ^/“Ë…•9Ž¥…($h…Bê-  (Š`âàèèìâµ2íBrÔÜEŒˆ? !ÄÊÊ:lÖ,Ó›Ä Ãæ„Ý;ÒøŒ 2 ÖÖVšâ'”Œ‚9–‰¯“ê`Œ1ÆsÍ„û-”òoÕÛÕ%—ËlÍiÙ„`~²R¸á>†B<ÏB zH$RŽÇÉó¹1Ïw´·888 …µÝmƒýýÓ¦‡Jdò‘áAŒ±••jlÄÉÕ­¯«S«×ùM €Úêr{;{Žå4:mà´éMµÕ (d:"„T—•(UcÓ‚Cœœk+J윜8½qT¥ ‹@_}²c°¿3²Ë×n¬,¯’ÉÅ‘ÑqˆBû>ù¨§³##5iVäœsgÎúûûÆ-\ mÍ õ5Uîž¾3fEtw¶·¶4…L­.©ð ò÷ðñ€¡þÞ†ºZZ·`‘\auÃ5öõ´u´YKåÓg€ÌÔµNgokŸ°D4ƒ ¦ÝÓÕQ˜“­°²òò÷ å9®®¬¢èj¶N£±qv ›©Q)S“Î:9¸8Ã’•kÏž<ÚÝÑ63tV[[K@H𥤳Ïÿè§Çöí}êG?Û¿gwðŒÐek7œ9~¨¿½ÓÉÕ­­³í‘ [²r³;Úþú‰%ÒŒÔóÃ#]½ÝkÖoð šôî´6Öëtú™³MüC#=] ɼ|©·£íÑ'ž‘L(ùÎJI Ëʺ¼aëcN.Cýy™i*µvÅÚõçNÙòäs_íúdë3Ïf¤¤ž=zÒË×£¯«ãàþ/úË×Ú[ÛÚ:æ-X”yùblü³'ŽÎ[´D*“1F®(+×ÝÛÕ?d&!$7#Õ:Ûš×m{üô±#¥ÙY#JmzâIB‰¬\Å0¢¼ÌËýý}VVV +ÖæçdŠ$"™XR\\ôäs/Õ–ªT± Ɔªªþùç?nyv»§—WòÙSžÞÞ‘1óÞÿÿóì^¶µwL>s`BÖ<ºíÎ!„c ƒ½Ý¥ù×r2²»::9ŽÕªU•EEW2rŠr¯öt´§$]¬¬¨ß·ÿè®wfœ;7:0ðÎ_ßÚûÁ'öÜùÖÛƒ}ªQåGÿïoþòeº ;st¨o÷‡ïöõ}öé'/=µQ©”_íþ<ñì™ïMò"MI<’xöäÁ}¥¹½½>ßù—W~ÜRUqúÀþc‡öé4êï¾µçý·¯^J9°çóæ†ZèÿðŸo%§&¹ó#žçû{:Ï<~üÀ¾ãû÷öwwýê¥í™i)¥…ùyýWÝímzÿ—»w¾÷ägg u÷ìßõñÐ@ßø ¨•£»>Úñ¿|]øhgcÃó<ˆ†¿£ì§©æú¦²Âü3Çüá­wdV&vªáÁ¾#û¾L¿t1éÔ±qã.=)1í\ÒîOÞ^¶z­æRâéÌ”äÄC_›×ÁÇö~188tùâÅÚòÓhšMWÖ¨Õ{>ú¨¡¶†c‡ö~õ—_ýª±ºæì‘Ãײ¯Ü¼²Z9ºû£wÅbéÅÇtuI~nyiq`pÈÉý{ zmoWÇ{z£®¸ ¶ªjχïw·wd_J­*-Qÿïõ×F†jª*÷}ø¾ÂÚ*#-¥ª¬²ÓS‡âæ/:ud?DZJ¥ú?}¸œtZ¸lé”À€Å+WcÌý÷¯7<8˜štÍY¸Pîhoëà5gvZâYhkª?sìè²5hµê«WÒllíÒÏ'¥Ÿ?»xÑî>ÀlkïÐÝRoÔª\]²Ó/Àµì¬°Y[ŸÝžyé"Çón•%Å}=Í5Õ6v…×®tw{øøªÕª»1 c¢ëéêfdÒ€°P;gžç{Ú;ôF}tL$‡ñÈÈPŠ¥³"g<ýì±1ˆ“ócÏ=Õ;4¼ùÙg<¦å_͵±·}ú'/³ˆÀ W¬RØ8ýôµ7\<<_þå«@¨³­u¨¯{ÕêU7siÕªäÄÓ‹–-]´xéñC‡]Ü=ž|ée™CyqAØìY[Z¦°Zÿèæ²Êʸ%ËV¬]ÿÞ?þB0Þ¹ãÝu›Ý´a3Btnæå²’R Që·l†qóò™1[$ÏŽ‰SXÛŽ(•VÖ6‹—­ÔX˜¿d¥ÄÎfû/~åär$ÌÚÖþɧžÂf… #à :`9Ý¡qÑ«µSüÃfGEÇÌ=°{—rtDøáô‘ƒsãç',[^QR¬­VSYZ»h~ph¨àIQŽ–FÅÏóœâgžˆÍ½==ö"iHÐôóçÎŽëeí$–¦·ßÔàˆY,ljĒÍ?!¶Ï™??~ñ¢êÉgtrrv÷ô²wwgYö졽ó–ÊV EInvÈÌ–ðA³#¢cúúº#âæFÆÅµ6ÖÀÔÀi.¾Þ¡QQaaáC*¥»—oÈŒ™ tú´”¢+ËKyÂ(ÇÆ"¢c|¼¼ü¦ú…tvu¢´H,¥iÑö_¼Ò\YÕßÓ¯V©ÀÖÞ€RXÛ WWw )8{úTTL òññɺ”lemãêãCS´T*3ô#Cí­i/§e¦‹%’ÌŸœô´Àˆ¢6m}< 8´³­E?¦*/)vuñ"O0¢(ÌsuuµW¯d_¸¸hÙ Êä +; alÔi{;Úkó *®åÆ.X,•+³›«LaˆÓyûùÍš €F†G¬må@L  †aDî~~@‹hZ ›ŸÞ^t5»µºVDß2Eb‰½“BÈÖÖfph˜ãØ–†{{;°µ³­¯®ŽŸ· ±®þÕçž š„e½H,aÄ"ˆÄ¢ñÜ{‚&‰f ›¾a91bJ$<{{Ÿ’[‹Bˆ¢BÂg#çf¦ ?´ÔÕöv÷T–¯Þ¸ÕÊÆä2Åô°¨ß½ürW[‡ a9::.\¶â¿~úr{s«É¢êÇ<–;ÛyM}õõß;_h‰xÒÃKE"ÚóB4# ¸T2 îàȳ«+,YµF.• Ž™¨? F•F‘H,–€ÁÈ€V£5v(•j€ØÚÙÛ9:v²pPžààY3Â"^úÙÏììì…‘h©•j0Y©DbÔjÔÃ)gN9{{†E„B°Ñȱ„ æXíÈ ËqFž+¹Lo0€Þ`ˆE e£AkdYÖÍËmÅšnؼyëc7„Ger™ Ùíìú:Ú(Fäæã1{~Â…L4E‚)švvu]¸,aÍÚ n®®˜cYÖhÄF`‰T&‘[Ù»¸ø‡‡…Ï7ÅÇ‹×ëÈPÿu•ÜÈ#ÖÌúD0ÑéXà9^¥U›Ä"á@*•lH¾õ—Ø… V®.6ö½“ÐWŒ ö×T×NŸ*|<ü°Q§OX¹¦¹±qñšus/öðø §‹›GEqqHx8æùk9Ù3Â#ÚëŸ|þùM[¶Ñ󬱢¼tVTŒàPȸ”>{vSmUqþµ…ËV¥ž;/QÈ•C}2©<ÿjnTl¬pOõ¼ÑÝË'çò¥°ÈèöÖ–m[¡iæô±£súZ›*JŠ#âæ¦]H¼r)%,fn{}J£õ œV˜›H‹%—Ο[ùÈ†Ô I+7míë¾”r1aÉÒ®¶&7OO;§´‹I3"¢0Ï×TWúL»xêÌÌYÅY韾õÿ~ûÝ3'ޱ¬±µ¹A „¸u”  †bh@ÇY@ Kü½<¢gÏœ8Ujâ%%<Æ…Ä"‘8*ðÊ WŒð"‰L'ÜB„(㜌ËH$b º¼lÑÊ•ï|þUZjªNó ÝÏÁÉ™¦Èôð!3¦WU” c×ÚPÿ»ÿ}{׎÷Ò+ŽcE *•ÊÃÃS$–øúùk5jèîê ™VUZø³×^ûËûï ü–H"•K%„îÖADbL8Þ”º!‹ ÆÏÜÈ„Érܸ Gð„`BL¶XÁÕ,ƒA?I%‚O <Øßç`Šõ:¸yøøùEDÇ1„„c_O—›§û‡ûö554ÄXmõž^ìÝ×ÖÞ,( Þ¾~J­ÖÎÑÙÊÚºØ$Òé´œ^?©Ë–¢@¥T#!BÀȲÍ$BvNÌÜ®öá^twuEÄÍëéì }]ݳæÄ€‘5òûñ¿ÞJϹœ.QX]6<:kαý_4º¾Ž®Îή‹_}±ëë;‘K>{îø‘Cy㵫ÙyÿðS±T2cæÐðàåóçúzzn˜xW¯¤;89~öá +VyùúGÆÏËÉÈøäÝ·yD7Õ×HdV¶ö›˜¡é‡yúú‰%’æºZWw×®î¾Á–¦;gg{'Wá¥83|ö•Ô‹U•lÙæëçßÐÞ}úðá©ÓBŠ2sl\Ü1@ÒéSÓg†#„xŽ‘Iç-\|áôÉÓG¿ô꯻;Ú{ú=}üxžîéÕóœB¡h©©uq÷‹%W.žïîìŠ_¸„âêâœqùRX\\þ• w TyiñÂ+E"ѹãG?øŸ?t· S¢Ú¬$Šf8ŽíìhïíìÒ(uCcÊ3‚½ZhÄ(¬Ó§÷´µ§§f.]»¼­©¥«³gÓã[JJ+r33ŸÿùÏÏŸ>£Ñ¨ŸûÉ“Î&ÖVV,^½nÝÆÍ¿xñù°Ð…+W]ÍÎ*ÌΞ»`~ô¼å…%¾AUeEϼôÓs2Ókëªi /“Ke‰gNÙ[YEDÏýtçŽÈ°Ù{lx¨ïïüýóFs}}`HpèÌYm-Í'ñõñÑiÕO<÷R^v†fd”0"ŽgW­ßX\p-çÊ•ÐðÚêR“í/¾”röTcCãÆ§Ÿ þ×›põöY˜°dŠÙý©N9¶©ºjîÒeNŽÎçOcÉ“/¾p!é\Y^þ’5«W­ßøÛŸýèç¯ý×”©×s…:ÛÛªÊ+ÓO„ÇÌYUZ*S(Ù¼Õìýí=sü°£‹³L*[±nè´šŒ” ÞS:Û[VmØŒêîh-/,¢%±’-\ºRØ0;=m¨»ÛÆÎ~zD„«‡'œsùrYI‘ïŸÕ›¶MÌ!ª«®ÈÍÈd(X½qSyQqMMͺM›®å^íïé]µaà iM„ì+i1R©(*v.ÏñO14í8­¼¬øò¹¤øÅ‹†úûFçÆÌkh¬niîØôô½]Ý]]³Âgu´wh´šàé¥%F–]µ~ÍˆŠ òFúú¦ÍóöõMN<…8­¯¯wpx(&6ÖÙÍýÒùD‰Tº`éŠâk¹ý=Ý‹W­IMJŠ[°ÀÞÁáÔÁƒÖÖŠØ… i©) …BdéÊ5}½Ý…W³ü‚B¦Ïèë)).QÈeîîÍ­m"‹–®ày®(ÿÆ8:.ž¦o @ëtÚÚ²w/oð“eÙ±±Q[[[‘H¬×ëcD*“#„ ƒ^§µ±µWÓ8Ž¥(j¼JŸç9N¯PÈA¯chbDbN+dJ$‚ `žz¨ó'Оbžã1–H¥ #kbJ7”0Æ-6öŽ"‘AE)&ûûhcoïø }¹¿÷×?~i÷áã*Õ˜£“‰Ç½½¥ÙÆÖÖÎÁQ¥íêê1ñ 5Õ×)¬­ÝÜ= z]CMõŒˆÈÆúš©ÓXŽÅKÍì#ƒ¾­©1`ZˆPtU_Sé3Å_¯ÓŽøú ö÷öô„Î çyN£VÙØÚcÌ_ËÎ  µwtæXÖ`4(V:N«Q9:¹ô:LˆL&×ët}ÝÞSü…·KoW‡£‹«F¥Òh4žÞ>ʱQ½Nçìê†â9nÿîO<ÿâ­:e Ú¬óà ŠÁ„×s¼„(©Xìhk 4¥6­V ©Œ#X"‘"„(ŠK$ˆ‘Ç€H$F#4F@Ì#Šáyž5¥7‘ØÞ|·îƒ½]ŸîxÿOÿøç {#„Ll–s· &á1O?Ê£þã²X-ø> éäÑú†ÆWßøý颲ÒSµZÍŠ5n™Ö@#K${ÅÐŒHÄÐ4m%•ÑMS ¡DÁ4E…cDQ‘ÈD/Cñ„P™4ÍÐ2z²DêÞ®D$–ÊnòË t£Cìn¾ú‘VQeÁäé)Ï%:::u´·zûLùÏ¿ S®Rü‚„ÛWYSÄÔ\,‹”‰Â™|S A”P]8Þ—˜È4±.ÝuØÝòFcÞ¥±Xü-°à?õáÆøÌÑC W¬zá—¯ºÝw†ý÷ê­|GNT™H3"šahšf(†bhJ Åb†ÑE „X ƒh!h hL ¢€¢3a31õƒn[oü@™‰«4.ëÌÒ<„yŒÇ•*Š˜º¨N W™ê£ÉM¤}ieC&2ÀIc}ãCzlfFÆð„ ¾³h+.ì¿ùûΖ&+Û9—.T—~ ‚-{G§€`ú–×hkïðÜ‹/ó}Ôœ¨5·¬Ù´éãwÞâXÃ]î߯ÁÁÙÁéÛf„Ìž­S©nh•ô]I+ò?½¡U]'º|á¼TfU[Y1Ôß -u5%……]íoÿÏ'òrœ>øuʹÓ@3Ìôðð®[w™¾ hFääâjçèàââ|Ï =÷ ©L¾~ó…LN3â‡w”ζւüü{Øpë3/<ÿóW…·rÒÙ³wíÃç3%‚1æð„`#Çñ<Á‚à˜L àyÀ˜cY@ú÷!z‚œšÈ>zcú‚^§Á˜ç8nld™Èš0:<8<4<Çöu´–äp~&£+jk©Œ™û u©¿?ùì9…Bz—'9<8 Ó¨ó3Ò¯Xy›ÕF‡:š›ÂfG€rdÄÎÞ~¼­&¾…<ÐÕ©Ó¨…å«™ióßF@°F½Ñ n:Ç›:[›<ýý…*Å›Tžc…RAA0ôÂi¨UJZÅs\W[³É:ëï£Á èGƒCƒƒ¾¿§»·«S¥T–äÝ|2—ÏVUTSælxƒ^§™6m^Ââꊨ-/®©*[¼rE{SÃP¿©öE36<6:D›_±A!¡µ•å÷,2ÕZ• âk*JÜWSVxþÄ‘ÂüÜ[mÑß×sðë/ROu6ÕcÌ×TUž9~T­R^ËH?sôð ”æg§&çf¦ßŠ`K­ËNI®--±·5q‡´5Õ_8}*%ñÏquµ5Çìïïî<ôõWý½=•eÅGöîè5]~mUÅù§2S“ñÿoïºÃÚ8óô÷ͨKThD šÀt ˜bÜëÆN³/}Ó/Ùd³Ù\v/·›êÍ^\’xã4Çe³¶‰cƒé½ÑA¢Ñ›P¡¨K3s0Æv6›ÍånŸðþÁÃóh>i¾Ñè_}6>:œwír{SÝç'?,-¸aýjD µyW²F¥½³éÓÿþsO‹(çjV_O×ßΞž)+Ì[P+Οµ·ÀIDAT§&Ær²þš—}ÙÚq™—“}-ëbmYiQÎõ¯Ï|5 é>úö¹—/NýÓx¿äO¿{M1=ù÷ŸÏ=zÈxÂ-fåÌŒTÒ;;9©™S·76/¨Td©®¬ŒeâÓiMÍu¢öâ‚ü¾?•NÏýærqa…¤³-"&@¸œG„@½VwùoçkJÊ.ûÌ?0Èí¼ú#ççÎ~rª­©F>9yé«/ŒÈ:û•·Ÿ¯Û©´ ·¯[R[^16,;ñî{Îvúãf¦'B…Ͼ?:!ÑÆÖnÍ6¤½= U•¥Û;8œ8òvPHHaÎuaTLmy)ÛÉAàÙS'Y6Lw®¨±vxP–ûM–“3ÛÉeml¢4'»§³Õ¨[¼xñ<çò±è;|)?'{crÊ™O¨UŠqwa„$aþõ+cÃc]u5zƒ>cç>Ãr¿ÍÕ7P(¤©Ñá²ü–­Ý;ÿñJhäŠ|ôÖTŠyN'ŒŽYs_ y­ê¤±˜ÍµU<¾ïÄøøÆÔÍÖŸ_eQ~Þµo! u÷ðìëéúúôgÊÑÑšÆÊÈ qã#²ÞzS>1"jj|àÑ'V«k­AcuUgSOØÛ+èî~ôÙX¶vz½®©²¼4?‡çãSQR4>,•t´6ÖU…oˆÍ½’Åf;ÖW•‡-Ì)³³.ÞûÈw´æÔÊkYçÔÊ7_ûõ®}9úçÀÐÏŽ¼•²u»ÐÚqÙE7²T‹×Οž‘OÑ(´œËé4Ê ¤§©®†(èjm®¯(Ñiæ‹rsaá Ueç?ÿ$"*º­¹!?'[ îïWæç É»|Á‚YÊ ó"¢cVϸ…zûúu4×oLI£Ðè"Ÿž8ÞÛÙ:/Ÿ‰Û”A¡Òè6¶(JòòöÎ:w&sÇN–­=„¸­…Î`a*´Y=íÍ!Âfâ]ÿöBzæ6{GG'çs§þâÏØ´eûñ·ßؼsÏíuÎzæ¿^~á‰ç^ôäù¾ÿúo2÷ìwræ|ýÅÉØÄ$ßÀ ÏŽÉܳN­úà½7Ÿ~éÕŠÂ<E8·•bñîë¯îº÷~[{ûÜœë»~qРÓ~vüØ£Ïý»^«i¬«ŽOÚtãÊ%i¯ä÷?øÞk¿ ú~qâƒÔ­;f§'¿üøÄ“/þ ñk—/%§m–´µT””<ýò+Ù_Ÿwâp˜,fW›(s×ÞK=—´‰@ oÞ–í»ÙNÎ- u …ÚÅÍíý?¾ñÐSÏ›¦ê²’°È(¼{è—¿îÏçûðƒæçTcò脤€ ÀÎÎöWß|ek÷w ¿‘¥¸9f–ONÊg¦˜yvN5<>Ž‘rN962¤1¨LfcMR§‹ Tª4£<¿@­Óq¹®n)¿lF8ñþ믹¹{£"U3*wOÞ +÷úµÈ˜Èž¦æ°¨èÙÉi2>£”L&ùÔÄÙS§ö<ˆ" ·»Ý/@`´|ò)³ÉÈB¡R>;Ð+¦RÈ®îÜÛ·Q[U¢RÍ&¤¥ñ|ýNŸ<.ŒŠusç¶Õ×@ä]»’˜’ªV+ÙlG…B¨¯®6ãSRìœ×¼¸½Õ/Xpñ«3î^>þ¾]m"½N{ìÝ·ïyà0Žãc2ihTÔÕ3ça¶& ð®¶–‚Üœûö OÇlJœ9u’Çç«çTóJ%Ψ*./ÎÉñ TÎÎÒ™6ïÞ'}詵­”f“ÉÖö½ö+ÎÍ–áþò^íÕ çô½7ߟD"©òwÞxý©-jnÂ5z@§?:öÂk¯ùðù‚`Áúޝ\*鋉ŽOILN5éµí" ˆSÆÆNOLONøúù}~ü¸ÑhÞ›ØÝ&ì—xù¶·´*åSåʼné™È¼{Ìbùà?&§¦±ÙN‚™J½tæ ÿOoï)åltBâšã[ëkzÚZÓ6M+¦7¦¦Ó 2•VZTÌ´³›˜—öK<½½ò®çða=âATósÊY™B©©(OËÜ"“ö!(ÞÝ#ñ îèê FHûÄdòÚ¸>‰LR*•+-ëŠ<ôØã(J¹ú·¯ëÊ‹\/^ƶeù;q/ÇÝ 0,í·wq1˜Œîžî–eiïÛßùûC0‹€¢(“ÅBôÚ;FuEõµ4&ËÑÉÙÖÎC‚ d­=(Gö‹¿yµ¦¤dt|Js'÷_)ŸžS̲œœœm˜6AŒÈÜR[Q¢Õê™ Š¢‰¼1-ÝÞa€/qâpu:@WK“¯¿D''vcU ÛÕ-qÓ&&ƒÅtr2Md µ´ ðØ;o§enN†(‰DBI$WÇÝÇç¹W^ }éwoôuwH­¼ –0zC[C­´¿×Ë×BHg0¬#âušE³ÞD&¯¹AàÚù•J `Òi6L¦‡§aÁQÈgì0“yxdD2* D´¡¦nT:j À/þûÒÈ/€Z}Àöæ&ÙlcZ†´WC`ØÂÚ±k·¨Iä'Œ˜Ÿ ±˜Þ¾Ãƒ2~5Ãp7Ÿ´·³-82‚ÉdÚÚØjæÕu%EcÃCýµUÕ‡ž|F ŒZP+ã““÷?øPpxdeqarjŽYÆG†ˆˆêj¶ìØuG7¤¾ºÜ¨Õq½}j*#£/-ÌŽÛ8ØÛÃq÷œÅnqç‰ógÎlÙ½wN¥0êÍNlg†šªû~$ïê•„¤M‚°ˆò⢭{öLNŒ{{ùÐ茨 1\/o³ÉÜ'î„„F%$8ü@sMurzf¯X,ŒŽíêl¿ýĘt*¾2×,.yáõÿ|óä)QÃ’¾jvš€ð¾Gïl©¨çædÒ‘©±é¦ŠêÁ>É’/i4 N³ðÐè ØòÃ@"“î¨ °à€a³Ôë`gg}6 d*JB ‚Ð ÍÂÜ‘·þŸšêãåN¥’ÕŠµA^ …bÁÁ’X2A”D³±KJËŒONIHܰÖDƒa2!D“ÙbÆ&“ 3c€‹šE½A`’©þ•ן˜–zôí·Œz­F£E(”ɱaV4ëMÇÏ|ò¡‡'×Ó—1;3 HËÜ’sñƒN·fÆÌ@¯7Ðè”Åyµ¨®¢ª8¯½¹þ;ƒîAà„N§5YÌ8 Œ•J£R(d2E…Be1ú%b”„"˜©©¾Á‘A”ÌÆgû+;1$[“²˜L•ä…GF^øë¹5%T½¡²4s×îŠÙÑ µ••›wí)/.°ˆ£³«|zR5·ÚÝÙ¹uïþ×¾%¡¨ÑŒ¹¹º^»v  ¾ªbÍ®\¼pñÌÙ7?8*no@”ìêîU|ýJÆö²þÞ¤ôŒŽ–ÆîŽ6.—W_W{öÓ¿ˆj^ýý¢††Û/‹eÛT[f2$=~üNŸ¾}ǶÝ{k+ÍfScyå¶»ë*Ë3¶mêëQªÔ¡Âðú’R®§OG{ûÌÔ¤oHؽ‡Ñ*§H(¹¤àÆÆŒÍ]íñ‰ÉZ­VÖ'võôÕÕÜ.ºŒ’È+ÙVÓß/‰O´±³sp°7YLÌl¦ÐXL[©¤G§™Ÿ‰ˆ•t·q\0“ij|ÌË—o2šDu5˜É`4UŠÙÑaÙíœFÅX3†]¡Q13ò™´»¶ìÜ%ŸT”–ø.wù›ÌFOÏÁ^®ÏÎÑÉd¶,ªUzÍ|î• Fƒ~M²*X¡˜šèë“0hôÅy“Étd³»ZšSÒÄÝ]·ö¨“IëËhk¬„…t57övu (jçà ŸaÒ¨f“¡©¾.sçž6Qc|rò¥³§gä³ñ©©u¥%|_߂쫽N9:_^”Ÿ”ž!•ôpݽ¦'&ÖþþÍf2BVÌÎZŸš4}rlL§]\\Ôðƒ sª#¿û­¨ºôÕg›DFÇÅ%Æ‘!¡ÕèÙÎ.K„eÆŸtôÌ'ÿ%òé†êr³ÅÒXU5:2´0¯VLOu´·ö÷.Ì-6Ö×Þ¾$>qãœzQ1+o©®YXÐYOÛ™ËwvŠ[šômW{+ D5Ô K ‹úÄâµ¹{G¶}s]Ui^öÌèxw[« |zº¾²,ïêe±¤Ã0•2=>6Ô/ÖjuòÁñá!z^ÒÙ‘°)mP&‘öU””nÝ{AQƒV§˜œRʧԳSÃý&³ñü§_£b37“È ™ÜÛÚRp=[³8?31¡šQ)äµJ5:4”÷ÍÅÁ®žŠ’"@Ph¤Öˆ…FFT y[sƒT,éjm¦3=’³Ÿœt`s.}ñÙÙŽ‡*9úü£‡ -‹Á`PLËççæØg'ÎÌŒÜ`2A E§7†lˆ–LŒŽS%={v)”êÚ’2‹…HÚ¼AQXº •qýR@Q_¾y^þS¿z™Á`®þÈQSŸXrðÁÃy9×÷=p˜Î`´Ô×lÝw@’ûMVcEÅÓ¯üÖÅÍ}qa>ïÛ¬}÷rprnmnÖë4~üÀžŽ®C?‰Üª(ÂdÙŒöõ×T”mÝw'ÏG=¯Î¿t‘íê~ß#[0‹¨º2<:ÎíXœ³1=6:0000°uß~Îm,@NŸŠˆM,/.Ü}à>žֶ߯,/§¼¸hçþÝí­ýýz¬CÔÔ+glßIhue¥ LPUVfkm{GsSQa^Hx„“³óÉGŸxöÌbnïè为°X¶•9y˜Xo?¿Û2Óˆ¬¯ÇÛ/ ²(ï£wßQÎÌú ‚ëëZ*ªGGd²¤ôŒþþÞ‘Aé°L•<Ð×7§R©jYO‹/26¾¸°À¬3ètz•J½óžƒMuÕÍMÂèØÕ[ûòäñºÒRÓF§×ˆ[ZÊËÊR·mONÛÌvrn¬«5Õ‡i zÖ×çþå3t&`6››ÆGG~ò9ƒÑ×ÖFB)ž~þ'þôNêæmtÆM5G6»»³ƒÉdxûø©ä alü¢FÓÙ*Jß¶ëzNvBb²‡§×êè“ÅlknJJßÒY×·9S"‡†û fä3(™âìì<Ð?¸eçn…2Ú;°û¾ûi FGkûö}ûK ÷?xؠשÃ""ûú·îÙgçÈ:pèá5nEUE™£G§Õòüü¬£ª9®îW/géuº½÷DPT§Õºp=#’£’C„‘TÍj\pÜÜ#ã˜66T*U¯ÓÌLMø ‚BÂ"bâ¨Ôï›1$ uïÁƒn<ƒVKg0ÂcâX,*¾1=3›Ý=<×T$)”äÔ´ÊŠrAXXîõì½î…nØÐ×-öðñFÇÎLN‡…|A0BÀ½¢ÙÛGDǬuÒ!LHIëji ‰ˆtæzè5Á!©[¶J»Å4&+aSjOW§Ñ„QÈåÌlHä“ÞhÁqO>_©T 7DGÇÅ—•”r½<·íÙ7§RȤƒ,– €€Bc`äò¼#âbòso¸s=ýùW׎æfž_oÐk5[;A=¸\¿@zFñoÏ>2™ñI) A*ƒ D­RÒèôÀ0†?ÈÎÑÑÓÇO›š!’&¤¤ÞÍ=„âª\%hõºÑÑ1µ\Îàóüø¥P2…‚ “Jà J"¡‰B&¡‰‚€dU‡@@«G@pl¹ˆ Ö €[λ9üàÅ…ØHþ …²~ñ‡GÞ=öå¹»$¡ ‚BÇ ³&×p CPÇqë  ëx´¥åÖšµU¢78#wIo—åe§mßsËæ—¥xV–c‹µ8€ ðÙé)Ž›»^«¡3m¬¾‚,‹ïþ…±rÚ·½ð¯>ôðŸDcu×›çñÓŠ"˜M¦ß<ýè±/Ïÿôõÿ‡øøØûApƶ]wº€ ІÉpd2œØ¶vvdÙ–NcÑit2™A¦ ÒH(B2dB#!àØR¸"`Ë„tIíáNl¾ƒƒ–t"¾Ç‘§”î‡.l©¯Š‹»û-²tz‚¬”XÍ=dE¤À›Ëá ,7£ßýæó îéh½eó˯,_)e‚á¸y­l@Q\*èýa{‡wÛõÏœ­L&ãØ°ÌÓ 0ãOö¡ÊYùÙÏNZÌàËŽý¬®ö3/¼|'¶ºé!’¬ÿš ÅôtO—Ø‚ãŽ+ãÖúv€ÐÚ¼À’¼ŒÕêAV: ×0Ë¿ð„ú±Ñ‘¦ºF£Ã?¹Æ—/?盯C„‘?«'êÿ@3wï~B5¶3ç‰ç_Ïÿì®ö]j’o>2¡¤êJ"èMf=†QÈ;&Ó†Á° ø¡(ɪ5ƒ $EŠˆ(i¥ÿpé¯5„¿œ+]¿××±Žuü¸ Yé EQ;ÅA­ÂX²ZÆo¹`XVìƒ`•yµT¿l|­èù®‹a­cëø± H,w1C­1˜3 "ˤd¯4DƒåÐÕ̓ár;²NUëXÇ:þ7€pÅn‚+Î"!DD ±dAá„@ @à¹5¸»D[È2™aVq÷UÁ,býB¯cëøk) o .¹{‚%!"è’­eÕÀÂñ%I™U 9Vå¬ek ]%Œµî®cëø±‹ °d3·(,©²Ä2‘ÁåtáÚ$:¾¬æþÏR­cëXÇ-,8A« 2±ÚƒÄ’õe•õ»‰ež›"ð6¿€¯³Õ:Ö±Žÿ½»3÷rSžÛIEND®B`‚snd-16.1/pix/hairy2.png0000644000076400007640000016524611147553267013070 0ustar bilbil‰PNG  IHDR KCwsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ;'Éë IDATxÚì½yxUÕ½¸ÿî3™Næ„@˜   ƒ 8¡h®v¼¬¶vÐRÛÞ¯Ö·\½VýµÕ¶Þ:´¢Rqd’y¦yžÏÉ™ÏÞ¿?vrHHažÖûk}é…^P@ ‚‹€F4@ @ ˆ@ @ ˆ@ @ D @ \öèú›Ðãñ …D‹ @ÐF£Áb±ô+í§Ÿ~Úï´@p¥ãt¶që­s0™Lg/€¬[·Žyóæ‰Öp¹Úøxùrxð?ú•~üøñ<÷ëÿ‡" ç“àÂÒß·ŒÔÏ´ÒäÛ™öñǾM 87dÀ€|û?¿ŽÏ륩©™G ½¡Ïô²" Š ‚ ‚,Ëý %u€U”~$U‡Íþ¤Õh4´47²sǶ3ª³ÇÝŽ, m@pá“ÙzÊ4m­Í $ƒÑtÊ´­Í &ôZ]ßâC(¤ÝÕŠÑh:¥°¢;Ó$Ë2{r÷2}út¬V;>ŸI’0º #Á€_ @ ¸`˜-6L¦¾UšdE¦¢ô‘QDD:Ðjµ} 7Í5˜ÌVbã“‘O¡rÜP_sÎBıãå´8ݽ ; e73xÐ@q“¯Z[[©¯o ++“cÇŠq8DEE^Ôò››[HMMA§Ó‰r  Õè0èƒ>$ۅуÁ`"àóãr¶öš4*ÆÇÝŽÑhÂd2ÓÚÜ„N¯Çd>ñþ øý¸ÝNŒF~Ÿãiš³ê…², ©ªªÂd2ÑÞÞNDD‘‘‘⎠.* R[SˬY3úx¾ÚÚÚhs:ÑHb1˜M&Mø~¢££±ÛlÝ®«««C«ÕápÄàñx¨¯o %%¹× Lqñq**«¸aâõ=ñSQW_N«%&&F­‹ßObbn·‡¦æ&RSRÂ+²g¦/7c·Ù;vÌY·k]]=»÷ä2eò çí¹Þ°ñK’’É”Áá#GhjjfPF:MÍ´¶´’=˜¸¸8Ñ©ýG’ðy½ô¥ Ë!d9ˆ¢(((;r€¶Ö–é,+ I€ ±ï6’’ÓˆˆŒ {åÇ0™¬hµŒ&Ó9U= a±ÚA I}Ö% IRß[>wŠ¢œÕ;@pñq:|±n=:F"mÀFŽ>_[[Ç®Ý{ÈÊʤ¥µ›]s¶l݆Ñ`äºëÆu˯¶¶ŽmÛw ×ë$‰ì!CÈÌtÖõ«­­ãàÁBââb…r  ¨ïÀ>SEA ï"+´µ5Q^z´×´öˆëAQÔk…6g3õ5d‰ÉdÆï÷QR\„Él!>!…þ(ju/¬¯¯'-- ›Í†Ñh¤ªª »ÝŽF£AQ‚A±û!8Ã9¤¥µ9$c±˜±Z­455£Õi Cèô:"#"hksp»Ý¸ÚÛÕÀå"àWŠÎA»½½õ6a2ñùüDGG1yÒ 8]. ¤®®žqcsÈÎÒ­.yûöcµX™2eMlÜô%÷Ý{Á`§Ó‰,+˜Ì&"ìv¢¢¢Ðh4hµZššš‘4Š,£Z†ÈÈH¼^/n·‡èè¨ð3R|¬˜öv7Ó¦ÝHnî^œ.·ÌžÅ±âã”––‘’œŒ×ëÃår¡ÑHDDD¢×ë…B´¶¶ …°Z­X,dY¦µµp·»Ñëôø|>ÚœN z€ŸÈÈHôz=@€ÖÖ6$ "##Ñé:ól# bµZ†‚¸\.B¡mmmbbbp:]x}^Ìf3v›¶6gøY7[̘M&EQÓy½H‰Èˆ Ó`·Û¨¯o`ß¾|²²2ims²>Æ ƹ‚³a‘•PŸ*SŠ"Ÿ8§(ƒtz}/Â@°[ZEQˆŽ‰£¬ô()a³GR]Y‚ËÙJ|B*.gKÿ¬û Òf!..I£A’TDÓñYQJKK„r!Ë2íín&N¸žØXƒ‘P(Daaõ Ý&ýÄ:455QQQ‰F£Áét2cÆôn}Òçó1vl‘vL&3Ç—p¼¤‹Å‚ÇãaÌèQøý~ò0kæ êë8tècÆŒ¡¢²‚šêLf39cº/Fy<ÑÜÔ„Ùbaô¨Q¸\N a·ãrµ3|ø0(--£¸ø8’Fbhv6‰‰ âf_IýR‘ õµ[«(ÝEQHKŒþ$óŠæ¦zäŽEœŽ×.±±‰ƒŽ9À€YTW•b4˜HLH(èï—ëY ñññØ:V­V+ÔÕÕCKK :­“É î¾ ßQtèÑQÑDDF0~ÜX¶lÙŠ‚‚Á`Àëõqë-³ ¬[¿³Ù„Ïç _äðjëê¹eö¬ðN…N¯Çjµê@F£!:*Š&N`ÍÚu}ÖÇï÷ÓÒÒJ{»»ãA…ªªjŽ;F0Äï0uÊdªkj(.>Nbb;vîÄãñ¨»*våeÜ~û< Òæt2}Ú ·±qqTVµY–Ñëu455ÓØÐH\\,‡Í›· …†‚ÄÅÆqýõãÉ?p€ÒÒr = 1yÒDœ.;vì"&&§ÓIdd$µuu|ùåâããp:]¤¥ `ÜØ¶mßËé"$ËÄÇÇ1~ÜXöç ´´ ›ÕJ||qñêNDCC#‡&+3 ŸÏOnî^tzÁ`ˆ‰®çè±c”••ëp0lX6æäd‚Á  q¹\´··͔ɓÈÛ·Ÿôñù}ƒAª«k@Qe™ªÊ*e¤‹‡@pƈ b°SÂã«¢(hµz2õ\E®©.ï&|(ŠLtL²,SY^ŒÁh"ð30#­VÛ¯Áõ´H„“ÿ:N ®@!äXñq*«ªHJJ"**’¢CŒ1œ†††pº††FÒxIJJTq FŽÑë¢ÜáÃG0ôd¤§ãñx¨©©åºëÆQXXËñã% >Œææfjkë(¯¨@V9x°ˆ¡C‡PVVÎþü|b¢£Ãù¢¬¬Œ ®'?¿€¼¼}$''Q[[GJJ2n‡Ü½{¹iú4¶mßAVV&n·‡Ý{r¹yÖŒ^ Š—ãëQA‘•Sª“v:ÄPPd£ÙŠÁ`ì.(èôê¢j—ÅEQHHH!à÷Q|ô V«¤”ý¶·ƒsˆ¢Ñt¿4!!«ÕŠ×ë%""‚ˆŽ•j ¿ƒAtZŽX))Éá>ëppÃÄ ¸ÝnœÎ6ª«ke™©S¦¾~Р ÆÍéÖ7;'V‹ƒÁv%Ýu ï‹ºúz¶lÝFaQaxÀf³ÍfÃívSWW×㺨¨(nš>1£G …¨¨¬¢ªºšô»©pÅÅÆâõù¨¨¨À`4’œLuM Í--ÄÅÅR]]ƒÓåbêSÈÉÉ¡¬¼œ¦¦fŠŠ3lX6³fÎÀëõR^QIiiv»7MÇ`<ñòÐiµŒÍÃÁY;VLkk+åå˜Ì&ŒF#•466røðF ÆìÙ³1bDXÛ›·©© –Mqq1>¿›Õ†Ç㡬¬ ƒÁÀM7M'999ünˆu8°Ùl˜Œ&ÊÊÊ»¹ðš=Nǔɓ˜<é4 7Ý4¨¨(ñÎjÒ×ןÒeÕ.,°ô’Ôµ«°"Ë2QÑ´:í®6bñètúéÏu D•@º½º !bçãŠC£Ñ’œDVf&ñq±ø¼ªlRR"q]ƪN ƒ£ÑØëy­VË€©def­¾­ RS1øü~ŒF#)))?Nyyééiw·ã÷û)++$B' é-­mDFD’œ”D\l,N§“P(„Á` )1‘¸XuѪ½½½Cݾ§Ó‰Ñh$ˆ}EÉ 2²êõOQän+ J¯é:Þ‰d%D èÇçõ Óéüøý^d%^°=º³ygêõzŽ;FMMMïI$‰©)hD˜CÁ=„¤¤$JJKùrÓfæß}&“­V×1ÙP4šðÄ¡ëÄÖëõÒÞî&...›6t(5µµÔÖÔ †04'­xöTuHMIaÊ”ITTT²~ÃFvïÉE’ m@••U½z᱘-H’„^¯gPF{÷îE§ÓŸß-]D„“ÉÄ‘£Çœ•I|B<[¶lÃï÷Kcc“: …a FC0$T_ ÚŽc¡P× UÇäLQ:vPBhº¨xDGGAÀÀ`0"I`P½^‘ßÕj¡º¦†a¾ah4Z ‰‰ Ä'Äc1›)¯¨Àl2¡Õj(*:Dl¬IÒ°{O.Y™™Øìvj{Ò‚ó7À†ûpkÛÙßÃ뢰=óèPEè˜÷w¦«®*C…p8¨­©À`0b±Ú:Ì Œ$¬'Ù8H’DBB<ÅÅÇIHˆÇn·#I&“‰ˆˆH, ••¬Yó’FbØÐlŽÆKÞ¾ý$66ŽôôtÚÝílÚ´™ÏV¬ê¡ï™»7¶6'£G$22’¡C³9zô˜ªæp™™Á¸q9ìÛ—OaaÓÒHIU î¯?ž‚‚ƒlÜ´‰±9chÞÕÂÞ¼ŒŒŒt"##())Ž)z„¥©±žšêò^ÏžÔ1Té5Gw• …Êò¼^7Ò2Ñë ŒFJKŽ60ë¼>¿²²Ò.‡Ô1À«^ùƒÁ€°ÿ¸‚0á1Äëó ‰NLdÊäÉ465’ššBK³êaĈá8ªsƒ±9c()-ë¦N `·Ù:4;œ_($66¶cqKGæ  Œ»Ý‰‰ Œ9‚ÈÈHL&IIf¦O›JuM-:­–ÄÄDC†¨úýC† Æf³ÑØÔÈèÑ£ÈHO§´¬ ³ÙL¬ÃAddèõzn½e6¥eåÈrˆ¤¤Ä~{‚ˇ`(@Scï‹€‹­Û;FA¡¹©ÍI÷ØívC|xgVjjÊÑêô¤ È@A!!1…ºZ¨ª,eÀÀÌ~íàJ/¼ðB¿öJöïßÏ+/ÿ/^Ÿº _ðÔþ×c `×Èâî úM× ­V‹F£!¢ÑHáUNõ ©«žêj%aãlEQzxøèšoçõŠ¢èâ(AÛaD~hƒA$IB«Õ†¯×ëõáÏYVÂê^6]¯¨¨¨dë¶íÜ4}ññ==<©¿C×9 ‚$¡×éNª»„N§ ×½ó·v¶SøÚ.ÂMeU;wîfæŒéØíön¿½3m§ñ|×<5 ’FC¨£½;wUº~îÚ6mÐh´hµšðïÒh4„dC‡ñ{çŽßïC¯WÏ@ÀޅΓÙJC}5m­Í½žOJN£¥¹‘ÈhVk•åÇðü½¬—鈊vàõ¸1[lØ#¢(>z¨èذA¦‚‚³­¥ã™Ña2™q9ÛxâÇO2ëæ9ýªouu5O/üi‡w.ù”ºÒ;žÁÅàxI ¹¹y̾y¦P¡¿JÐhtèô:<îöÞÏkµ´67íÀh²âõ¶÷i/¢Õéin¬#*ÚÕ‰ÓÙÒC•ý„ª–‚ÛåÂÉSOý„ôAñÛí=ß»g¾Þ:Iƒ|š÷¢N‘^gú°hz ¸z½®ËçÞk´Z-'/Äôµ2Ó[¾’$aèÅN¸ÿvbº^ßõs×â´ZMëTO6¥Œ52¼ÚÕã¡Öj»Õ[Rúª{onO>f1[HIIVuÉ·S=ìtyj:Òt­ãÉõí«î'_sòù®þÁOç+\ è ¯ÇN§':¦w÷Í>ŸP·Û‰Ùb£/¯×C§–ËÕFd”EQðûO¬LwÆñzܘLæs~ß — RS‰‹*VW>Ÿ‡æ&ç):”•ëÖ–¼÷©çõs„úÚJ½,ätÉõ”ñ™ÎAQˆÑQ´§0Ä«Up­#IS¦L¾dåÇÆ:ˆuˆ!¸j hNc°mˆRmœ~´§˜ôk5t:=’FCÀç=eZ«Õ¶K®t:ˆr•¡×뉌ŠéWZ“ÉÜïE«Í~~úÜ™^ ( ¡ ÷´é„ò•@ .¸ šEQ«u§K’C ‡N›î\ÑjµŒ†óàIK ./äŒÛíéÓŽ÷¬Yáº„Ž @ ®I*+«‰Šˆ='¡)$ûeáÒT \]8NÊJkÉ’}~‹ÅBLL´he@ \sÔÔÔõê‚[ ýC˜j@ !€@ !€œ’íÛw±dɲðŸÇ£«oذ™ŠŠªpºC‡Ž²dÉ2ÚÚœg]ÖÚµÂå,]úqóû÷jl„%K–Óvyg^]?˲̒%ËÎo°Åüü‚ðïr:Ϭ}Ñ«Á5M×wvii9­­½G¡.))cÉ’e444ŠF‚‹Èyõ¹öþûòðÃ÷ŸÈ¼#Jurr"Vë ŸÀQQYÁ²eŸòúëB¯×QTt„E‹^Âét±iÓž}öéÓþªää$ªªªillbŸ~ú9K—.ç/y‹ÅŒËåâõ×ߦºº­VËø=vîÜͤIˆ‹‹åÈ‘cTW×2mZßq!B¡Z­–ñãsX²dElÞ¼ââ$Iâ‰'¥¼¼‚W^ù+6›qãFóã?F(⥗^eàÀ|ÿûÿÌ–,YÀ¨QÃyè¡ûxñÅ?iiiaæÌiÜ|ó Þyg …<ðÀÆŽ-ž*@pÅ"Ë2ûö ¬¬‚1cF±sçžðnù˜1#yðÁ{q8bÈÊ:1Ö´µµñ曋©¬¬àᇿ¨Q#.Z½NÁ Ì¬Y³ÄMì ¡¡@ €,KhµÑ Áe„$iÏúÚó*€ðDväÈáhµÙÙƒyä‘û)/¯ìóº’’rœN'?øÁwxùåWyþùßœ²¬ööv ±XÌadçÎ=,Zôkª«kùùÏŸ`þüÛÉÍÝVÁ:t0?þÊË+Y°àÎ~ý®øøXêꨫ«'))€;î˜Ãþýƒeç˽÷ÎÇëõòÚkÿ 66†±cÇðî»K2$“ššÚ3nÓ––jkëX´è×ȲÌ/ùþû¿Ÿá‘G %%‰‰¯T¿ò‹ýš… Ÿ _»dÉ2-RWŸ}öø|>víÊåµ×þHtt >Ô))++·}uux¢Á/€tŽEê¿ï¾û?ýéX´èÜÿ=hOòSï÷رc7ï¼ó: >~‡^,¬V+#FŽ"Ò‘€r{Ú’$‰¾õ“^tjà*ã¼ V«…‡ºï¬®ÍÍ݇Á ®ntª Š„„ø>ËJHˆ#>þô>ÚE! 6úçƒÞžØŸj0Ú²eMMÍÌ{3»vå …Ø·/¿Û*Û™2bİSþY–{ ¤}‘žžFttTø»Ífcúô©,[öIøûõ×O†@ ¸r6.<>t.>57·„ßsC†d¡é#ØàˆÃ/yýµZ=A_v«öš¾eå5è Fz m¬( Ë–-ãž{î9e«V­býúõ<ùä“ÄÅʼn‡C ¸Þ8z´˜×_›¶6'ééiŒŸÃ¶m;Y¾|{öìå©§žÀáˆaÈ,š›[˜X^Í›5k:Æ aÉ’Xµê æÏ¿‘#‡ñ»ß½À–-;øàƒåÜ{ï]Œ9<œ—ÚN=W‘|>ëÖm ÛÈ81â©W7Ýt#eeåÌœ9I’ÈËËç½÷–b2™‰‹sàpİ~ý&‚A5@à¸qc.¡¢%>þÚž0+®èóÜ{ï½Ç›o¾yJäóÏ?Ç`0°hÑ"^zé%î¿ÿ~’’„‰@p9 ½ð Jîß¿ŸW^þ_É …Bx½>ŒF:Ž@ €ßOºµZ >Ÿ?¬Îd±˜{5,ïŠÇã ¯lI’1â÷ûÑjµh4 =~¿?쩪k¾>ŸPHÆb1÷«¡B¡’$…WÍzË×ëõu¤SëÓµMzk›ÞðûjÛ˜Í&¶mÛI}}#³gÏèfÌïõzQ5@{»»CÐÐb4‘e9ì‰Ì`У×w¯G׺u-³¯•A@ ¸èúž ƒáwÚÉïÃ`0ˆÏç47·ðÆï„íèÌfs¯ŽF<„Õ‰ßçå‰?ɬ›çô«^ÕÕÕ<½ð§h´4ÚPHè6lfÆ­|ç»ßÇj3’žvîÈÖ­;ûµ¨w9²mû^6mÞ^#ó•¯<@jªj;ZRRBkk+‹/fÑ¢E}^¿páÂðù÷ߟÁƒ3nœºÃ¿iÓ&òóó{\3gÎ233ÅC$ô§¯·µÛ±®‘Пzê'¤ŽÝnïqíyÛinnáóÏ¿èåa¾™¨¨ÈnÇôzõåß£Ñ€ÑØ?³òòJ¶lÙÞãø½÷Îï6AWCXµ«{yÆ~•UXx(lÌØ‰Ùlâ®»n둯ÉÔ3ÏÎA°?ÂÇ®]¹aCüNššš™8ñº¿«SxëÊÉi4M/í¡ïµný©Ÿ@ \î´·»ùä“•=ŽÏœ9­Ç™N§ë¦‚k4:tH¯ïÛ+•áó¯º{œžžÀâÅ‹Ï:Q£F…óéä !!A ÁE༠F£‘ììÁg=Ñ?ìv[¯eO—¸ÄÄD÷(ët6#gKBB|¼­V C†d‰ž*ý@¯×õ:>ôg·Ûn·qÇs®¸ß\QQ…ÃÙlÂétÑÞÞNbbkÖ¬'%%9¼¸~ý—áqòС£|ûÛ_cåʵ̛7€+Ö„?ŸL]]……EH’Ä´iS¨¬¬"::š 6ãr¹¸ñÆÉìÝ»?|ýþýp8b8zô8 *ZáÛßþÚÝeß¹s'ƒ "66–ÌÌLŽ;Fff&N§³Û*ltt4ÑÑÑÝ®=yQO \ˆÅb¾hî[£¢"/ZY ñ$$Ä_”²ÒÒRIKK½R ΃ÁpMº_¹r5÷Üs'+W® »{Ÿ={7nÔ]FbðàÌŽÏZdY ÚÚÚÐhú6x/))ãèÑb†ÏF–V­ZKRR"V«•yófS_ßH]]=sçÞLuu II‰ÄÆ:HNNÂíö„w” 8?ã[II ¯¾ú*GŽaá…̘1ƒ9sTÁñOúßýîw‰å?ÿó?yýõ×ùÛßþÆ‚ UUÕ¼ÿþ‡<òÈáô5kÖ³{÷^rrFA]]C8}(B£ÑtS¹êKý*== ‹ÅVÁU¹ó³F#¡Ó©Î_~ô£G»]»víââÔ(óþóçüìg?B§ÓŠ$äÌ4’“…;@ \» Á!› IDAT„—×$:+k¿üå“ÝŽÍž=#ìAà¾ûæŸuþññ±ÄÇO 1bhø³ÃÓ§ ÷®îç§OŸ*:Ž@ @ø[@ s6B×j „B~[ˆAQäsÌOVkwF çP(ľ}¹½žS…ÖVg¯ç =&Œ¿hõô=Z|Mß«övak*¤‚ >Šæzì‰ÑÈr¬A§œÝæŠ^oÆlŽwF çÇÃŽ{HLŒÇ`0b·GP[[N§Ãáˆçý÷—Ùl!&&†²²2´Z cÇŽ»¨õŒŽKÇÝïUö¨ìÙ[(:­@ ž ¦˜ã er¡`ˆ˜#VL-:6mÚŠ$0NëŒ~îp8ˆŒ´u$4âñ´c·Û™5kº¸#@ ¸  z¬V+qqñètœÎVôz=QQQèõzÌf3‰‰ øý>ŒF#z½®G̈ M{[’â¿dmTŒX¬6¼®† c«_mà ˆÎ*¤wüŠŸæPsø{(BjñchÔâñxÐëõ¤¥ ¤¸¸8¬žåpÄa2i‰‹‹'"ÂNII ÙÙÃÏ¨ÜæææÓõõõ¸Ýn(î´@ Âhµ:ìv¡P«Õ‚×ë ŸÓëõ˜L&B¡ F£`0xñ+(˜ÉÚgÓÖ|2e‘”…Éd¼$uض}¯è¨ÁUÊ7B·Û#ðz=DDØp»Ýáã’$…×ëA–ÏÌnd÷îÝ<þøã§LS\\Ì[o½Å§Ÿ~ÊŠ+ÄA˜˜˜dY,¢¢¢ºCG,:^ÙlÖpÀ>Aÿ ƒx<ÑàÒ QQQøý> z½¾ÛqP0›M ý7:ßµk%%%¤¦ž:¢ê_ÿúWž|òI{ì1¶oߎÏçw[ DGG¡(ª`qò8a $F£­V8ŒÊ‡~rÚt«W¯%\ƒœ³ –§ÅMù‘òðwY–‰!Pw?‚Á:¬ñññTVV`µFpð j\æõú°ÙêHI‰=myãÆãºë®c×®]g]ç¿þõ¯w÷.²ã³¿ñÔ_·‘6Tô @ ¸B1jaTò©Ó 8ˆýû÷‡ÎqHQ´Œ9š¼¼}ÝÒûý~ššš/›ßØØØÄñã¥&MšÀæÍÛ˜:õ†>¯mksrøðQdY>c¯^‡‚‚"¶lQËùÚ×Âåj' rèÐ>Æ~ Fß¾}7QQ‘ák7oÞŽN§eÇŽÝdgfΜ›Yºôcþò—ÿ£°ð“&M¸¨^Æ:Ù²e ü1ÇŽ@p¥ S¢&2|ð@òò ?n !ÙÉ`býÚMØívB¡Ð‰ÂtZŒFSÇËÞKRRJø\JJj¿ÊÓjÏ=øÓw¿ûÝÇn]ó&²¬ ˆv@ ¸béBoKKiii=ŽGDDñÙg+°Û­ÝŽëõºn“éKÍ–-;˜9s F÷ùTcùÑ£G›»Q£†óÊ+åG?z”òòJ¶lÙÁœ9³hmmcèÐ!€Bnî>ÆÓïr]®v~ö³gø×¿þÀË/¿ÆÓOÿ˜ÇŠXÀwÎåùç_æ©§žà¶ÛneÑ¢?rÏ=w°téÇL›6™ûî»›U«Örð`7Ý4•uë6qß}wa»$m9eʦL™pN ›à" &‰(k$V½…([¡Ð U'YV8xð`·ô~¿ŸÑ£Ç””D0èT_ßõõ ÄÅEœ¶¼²²2 (..fåÊ•Œ3†ädu¹kâĉ,_¾œÄÄD¾ò•¯ðÖ[oáp8:tè©y àê%:ÚAll pbÅI‡ê ÝÔ…;Ñh.5¬;ïœËŠk˜?ÿ6þýïˆWµòòò7n ?|?’$É‚wÐÒÒÆò埑=­VÃÈ‘Ãθìyóf“œœ€ÛíÆ`0ÅÌ™ÓP…¯~õA⺵£Á çî»oWç &#@‡#›ÍÎO ôΡC-~“ššÚÕ×ëE’$E&ð‡…Býsó§Óé0›Í<öØc@÷‘çŸ>ìküøñ˜Íf¹ýöÛEïA˜@À×clòz½WDÝ—.ý˜É“'ðöÛïrÿý÷0nÜ ÕÕ5át q¼ùæ;DEE1þmX­Aî»o>Z­EQÎjâ¿bÅj¦MSw â⺫MK’DB‚ê¹kß¾TW×RPPȈ} :ññqìÜ™KAA!_ýêƒÂÞF è…ü-H¿‘$‰òò’nÇŽ9Þî<’““Ã;'3mÚ´n߇.z­@ ®*fÏžAuu-ãÇç`4ÉÌÌ ?ÿ f³™™3OÄÔš:u2))ª a·ÛÐh4TTT¡(òY óæÍ¦¬LµûüÞ÷¾ ÀÃßß#]UU5wÞ9—êêZFŒÖ-ÍÔ©“ˆŒŒç±rå&Mº^Á5„N4@ Wv""ì=ŽÕsÑ-++£Ûw«ÕBvvÖY•+IF£‰{ï½ë´åÎ;»Ï4ii©Ýêsr~ÁÕŽ× &ÓµÝb¹A Ái‰u„½\ ‚³cÅ xî9ÑbD ‚Ë EcbÓÖüKV~\| “•½û \ŠHð€ÁhApÕ±aX,àóÑ(@ — f‹A™ƒ/Yù£VÇ€—¬VtÁUů~f³*xìÛÆÝ~êk~û[!€@ ¸xœõ$ÆG\²òó$uÀ@"ÌKæÆ~~è‚«‚¦&Õ•®Ñ¨î~¤¥A^,^ Ï> QQ}_»k /XWK—.eçθ\.ñ„à²@’$ÌæKg¥0˜L—FOD–Ed`Á•Ͼ}P] ï¾ O? ¹¹pß}ê¹ü¶o‡9sú¾Þë…ÖÖ«¯]®i#ô °hÑ"-Z„Í&tM@puÒ¸ðR²fÍz ¸‚k‚†õÿý÷Ãþýpï½0t(<ôЉ4ßü&ìØn÷™åítª6$Béƒææf:Òí¯¹¹EôJ@ ¸Däm\*á*Âãñvü÷„ÿºžóz}Ȳ>&Ë2^¯ï¼]<¹L5 ã‰2C¡^¯ßI³¥“¯®6ž<ÈÉöv=º÷t7ß k×öõ|õ~ü“O ¨H }rôèabb¢»ýed $Ñ3àPrp§h„+œ•+׆'÷»våð÷¿¿ÍÒ¥Ÿ°cÇn@U¡úŸÿy‰¼¼|ÚÛÛ‘$uÜu:]äåå“›»ïœëqà@!|°œåËW°wï~öìÙG^^>N§ªÖü¯½O^^>†ë°cÇîp]/%[·nåé§Ÿæé§Ÿ¦¸¸Xt.ÁyaÕ*ÕÖcæLX°@U£8°÷´S¦À–-½Ÿ{öÙÞžÿ«£„º@ \#´·5²öÝç™ÿè"ÑW0Ë Ûά¬ æÍ»PÕ­n¹e7ß<ƒn¸.|MEEMMÍác+V¬aÞ¼Ùg]²²ryäEá“OV…ßïãí·ßãž{n'==-\Þ–-Û‘¤îåžkΕI“&qà 7tE;Dçœ3ÍÍð‡?Àm·Á î|X,§¾æá‡á_ÿRÿ÷ÆcÁË/Ä ªß1c ¤¢£Uƒv!€à¬Yùæo˜ûõÿº`e(Š0ì½:‘.i™’$¡ÕjÈÉ¢(Œ—ƒÍfåèÑË{WA’¤n;3Á¹P\ Ÿ~ sçªBCLŒzü¶ÛÎ>Ϙ4އիO?tHuá+@ œM5¥Ø¢bñy.Œ7>·³™ ß‡V¯}ÍÆ›ÑjµÜzëÌ^Óh4ZÊÊÊ ääŒfذlâãã°Z-lܸ™P(tÞwæÍ»…/¾ØˆN§eôè‘DFF²qãfôz=ÙÙƒÑjµÌ›7;l)w?‚óɯ~mm`³ÁOªîz,XpúÝ€!Càßÿîy|Û6øÉO`üxU¹šˆ@ \BÁ®–zíY‡³¥«…šÒBbÒÒP‰ Q´k5ÍuåL¹ó;˜­QÍÖ³*«¶¬ˆ¶¦Z²ÆÜ(þ*`Ô¨½Lþg÷øüàƒ÷öHÅôéSÏ“ÀÑSx˜5kz·ï99£ú}­@p¥’—¥¥ªAy{;8êñSÅ÷èŠÑØ»W+·»Ì•ˆFt@ ¸8¸ZêÃÿÝÎfv­~‡ÏÿõßÈ¡ _~ô^·“†ªcüé'·²ç‹÷hª)ã‹÷^d×êw¨8²¿×-Q .Þy‚A¨¯‡ï}~øCøÚ×àûß?»üî¸Cõnu¦Ô×_™í'v@àá÷¶s$o#n˜ ÀÚw_`þ£‹XýÎ"fÜ÷>o;5%øæ³ï²kõ;´5Õ8pX¼ŠlÅëv’=~&:ý… §È2û¾üˆœé÷ˆ›w‰ñùlß‘{é&:3’¤aßþƒ—Ìn¨­­]tÁeGC8……°l¼ø"üüçpýõç–oV–¬ðLyáxæ™+o§D @pø}¬yg£…î ¯+?Ìîµï²òÍß0|¢7&1[T×Í~ˆòÃ='ŸUÅùì^û._ûÕÛý*¿ìТãSO›®`û FÜ0Û>£ìÐ!€\$Fâ€a—¼C£â/iùyû‹Dg\6¬X¡zŸòûA¯‡„ßÿ>Ï|"ÔԜݵ¿þ5,ºÂœ^ÓÈÒ¥KÙ¹Sõ‰ïr¹Ä“%Î «ßYö¬s$o#%…;X³øÐêºK’DVδnÇlQq$¥ïUéÌï£WöË•nõñèænÇæ?ºˆ^]Èõ·üÑq©X"b8²w##n˜Ç‘½ÐLárçL7óQ_Y„Ùxé<–5´ˆqÄ#ûÐé´—¤5µM¢#.7ÂôŽW`a¡j×±q£ú½­ RSUcóŸýìâÕéÙgá¿P#¡/\_|qå¶ï5-€,X°€ pëš7ÅÓ&Ήoüšyßx†‚m+9¹»ßÅ‚í+=õ.V¼ñëð±ÃÎlϾ´p×ÙO(+ÑT[v"¯¢]è &,1½¦/ضB —rpÖéHI‰»då+Í'ÆOBB<&“ñ’Ô¡¬¼VtÁ%¡½]Umš>]Ý]p8T··©©ªÛÛPH50Ÿ9óü–ûôÓpÿýjLÏ>ƒ»îê™&2¶n…#®ì6Fè@pø<.þýòlûì šj˨>^Ðkº§^Û†#9£›!ùØ›î=mþ×Ï~ˆÝkP]RÀÈIgçP^–Cý^qà Y–),çú6ו³ñÃ?áj©ÇÙÜ?aךÅ\?û¡3*§¾òE;ÕÉ¢«µE‘Eg¹ˆ¬X±šººvîÜCCƒj‘Ÿ_Àƛٸq3‹ÿY–»MèW¬Xƒ,+¼ûîátûöåSQQÅÚµðù|¬[·1œ~ñâ%¼÷ÞÒS uu lܸ™>X® ³-­,_þ+V¬aÙ²OimmC’$ÒÒº ¸yyùá:¼ûîRE —Óù_–eÞyçßátùùÅ?o¾)ÚàBÐÖ¦z´òxÔŽôtøòK5Úø·¾uqê I0`@ç3×ýÜ{ïÁ\=í-@pMÓ}< ðÊgð{)-ÜIÁvU°È]ÿo~/ÿßgS[vˆ€ßCîz5d­ß禩¦´Ï¼ý^7ÓùÛ£;ã>ôF3ŸGfŽî£h÷Z¾xï/J[}¹ì/ø½Ñi."sçΦ°ð&Œ§¦¦–²² ššš?~,ãÇ%#c Á`Y³¦  ƒÌœ9 Y‘–6 œ®¥¥•ÔÔdôzF£‘™3§w‰F~KÇ_ïÁKJÊhhhdúô©¤§§PZZÎ 7\ÏM7Me„ñTTTõzmkkk¸ii)Ý"°wþ‚ ”N×ÔtñŒÏ=õõõÔ××.ûþàr©ÑG^Ù«ßg¾@¤åóx@¾k ?ù üóŸ°{7Üp ëâ€îæ›!:úâÿæÿ=éµ~èdg÷²HT6¨Ÿ{‹¦~¹"Üð ‚k‚Û> ÛOØú)#'ߎ¢(¬|ó7Üõ½?„'ô¡`€ÆêÚ[U·´E»IœCÅ‘<®»ùAÊŠvŸJs]Qq)aW1 ´5Õ“À s¿Æ—ËÿÊM ~pÞ~ÃÀ¡×‘–ÍsçæJRƈp‘ð(ÝQ—þÒX}<œ‡¤Ñ Ó[‘Ë’‘#ÕYÑñã%äææ`0ÂBÂÖ­;Ñh$&L¸ŽÁƒ©tG:©—~Ñ›À¡(J¯i;?>‡Õ«×……PÓÚl} ÚuÐéN=å8U]/………¬[§þžš³õzùÍoÔÿuuêÄsìØó7ÁïlöÏ>ƒyóÎøUr^… €Ã‡¡ºZ8‚AرCݰÛaòd¨­UÃG:÷2õz5Ÿ;îè)à »ÈÞ°5šmp2½Ý— Š:Ì®vï†ûî»2ÞgbD \õÞ»ƒ;VQrPu»ýÖo¿J}åQ–¿ös–üñqÊŠTS‡÷âioàhÞ¦y¥d¡òè>"bq6Õðù?Ï­ükd,í­ªþûè©w‘2hÔý]‚¨^­ön\Ú#M}ÅQšëÊûÌ£¥¾‚úªâŽÁMƒV§'è÷‰NsáñtËÊ*0Œ FüþƒììÁ|ãÿÁ×¾öÆ AQÖ®]N7tèÜîžÂe `Íšõ|ðÁrvïžžžFBBÛ·ïæ¹ça6›ðù|”—Wâv·ãv·3|øP¶lÙÁúõ_†mJJJÊÂue%,„Ì›7› ¾ =«WN×™×Å`ܸq<ùä“<ùä“ èÔ}¹Ê©«ƒ‚“|eüüç'VÑÿùOxõÕÚ‹¥ ³üÙ³ÕhâO? ï¿÷ÜÛ¶ÁªU‘ãÆ©†Ú7žp‹{>˜6M50OO¿´÷ç—¿„ßý®÷sÏ<£ªŸÌäɪg¬+ ±"®Jž}p07-ø1‰éì^»ƒÑ‘¼ î\¨ÆäΖ:ìQñxÝNŽåoaÀà±lúèU$ICêઊóñº¤îÝ 0&q “æ}ã‚ÿ–Û¾ùìií<6}øgÒ‡Oìq¼¶Lx$º’‘$‰9sfu;öÐC÷Ó÷ÞÐëõüìg? ï&èõêp?wîÍ=ÒfgÛn˜{›ÝQQ‘ääŒ"'gŠ"c6›5jxtãÇaüø 5æÍÃßßg]'NTƒsšLÆ^ë*èÏ?‡„ÈÌìÿ5;w„ PU¥ªn­^ ÿñê±—^Ríþõ/UÍéöÛÕôößÿ>Œ©NpÛÛU7±¿ùêV–áë_W]Òž);wªýª«UÕ¢†øË_à«_Uë9v¬º RZ kתñ6:»çСêµmmð‡?À®]j{Ì ƒɤ¶QWŠŠTÏQEEê.Êï~ÍÍ/¿|e÷‰3`ýz!€®1ö|ñ>#'a0Zå1 ¢Q…æÚ2̶¨°W©âü-T?ÀÔ;¿‹ÇÕJÀïeÙ_ž"*.Gb:þû‰òù4VÇÞ%ÒóÈÉ·±þß/3ü†¹h4ZäPˆQSîè³ü”ÌÑT8£:§ Oö¸™Ê]×g{t<Îæ: FU­åä`‚½_“öаfñóDÄÄwû~ñë „ÎÀ{VoT?@rÆHÑ /Z­­öôÁÍfS¿óìKð8U™½]c2™ú]׮ןI]¯Ut¼jü~U%éLXºT6‚ÿþo5r÷²e°}»*Üq‡êò57W̆BêÎǬYð£AVhµª ²lª“£F?r¾ö5Uhp:UeÉÕ¥­Û­îZlܨƵÐjUÁå™gÔïUUªÚÑ”)ª€sï½°|¹ªútÏ=ª Ó²­KQª*šÃ¡zZ¸P”î»OUcš5Ku§ûâ‹j>o¼'ªí7a<ôëÃl¾üîwJÊ Û“¤$xäõsf¦êkäHÕH¾Sø;xP½F W"ú¹±ñÃ?3ýžÇð¶· ¨®:€ßçaÄ s/›:6T'69£Çq·³‹=úš½mÓy›jJ‰ŽO¥hÏ:E&>uÛWpãüïQ¼ ™c¦âj©Çh¶a0YûlÛ‹Éá¼}Ò†]OqþV*î#6y?üs8Ímß|–Š#yaWÍuåDÇ÷­j‘3ýR¥µ¡Šøƒvýl w­é&Ì6&Üú½ºð”uœv÷÷ùrù_1ÛÔQBo0c0[OyF«CϺ]«KpµÔ‡Nµ°NŒÕK—«µO{ݯÊ4v1¸ß¹êŸýŠÆ.8;‚¡ ÕÕ—>_}}Ãim7.^¯°EêÊ?ÿyö×VW«±%ââT5ƒA€ÿãj| P…´´î®fçÏW'ÂF#\½ºS’ 7Þ¨¦]·þüg5J÷ßÿ®NŒ\$ßq‡*Ì,[¦º²}ÿ}Uø©©QƒA-sµ¬1cÔÝ‹[nQ…‚ÓÅÙÐëÕ]N×µªBÏŽÐØ¨ Tßü&|ô‘ZÆ›oªÑáÃ𕯨׬^}þãyœ+UUª5hPÇd]§ P Úçlܨ $o¾ ·Þª_¼~û[hjR] ä2FDB?7š»DU¾Tl[ñFŸ*0ΦZ6/ù. »XµG«²²C{h¨<†%"†Ác¦aï²kãlªíöýä<;ÏÉr¨› £Ñh/ItÖ©µ¡ ­Þ€-2€ã¶ úœ3uï¿HtÂ@¶¯xƒo=·„òù|ñþ‹|çwRq8—½–òñß~Á_ú‚¶Æjv­~‡ÔÁ9„‚Zê+ùã¦ó­ç–ÐÚPEsm³úŸý㮟ý†ŒÅ€ÇÕ‚·½è„´S¶áÙ zª’0š­8›jA’°EÅálªEQdÊ w±ç‹÷HΉ"ËÝúfLBGòÂßw­~ç”g{t3î{‚^]ˆÁd%"&‰Pð„wœ¡×ÝLMIá‰ô1 ¸ÛT¯=f[:C÷¨ÑÑ iÈ¡ Zmï¯Ûq3îcûÊ·ˆt$‘6ô:‚s·¿Øòéß1Yí¸jü£û6“5z*G÷}Ù-ݱý›»õ£nçò·PW~8ü=ð³í³p߯ˆ—ßEÀ™DKsÓ%+?#k8‹•Æz?!è’Ô!5c$;wá,xã u¢š îlÝzÂkÖw¿«îh€ª†ÕÕô%-­g^ßûžj7¢Õª; OZsùÉOT!`èPõ¿N§ ÿ÷ªG)Pš†Umê«_UÕªââzNüS;¼8;g÷»“’T5¬×^ƒwÞQU¬¦Mƒ'žPÌ;­®±5.Ç]ƒåËO8èo|£olÕ*˜:µ÷{ ê®WdäÅ7®ˆàŠ£¾ò(W+iÙãÃÇr×-aÜ̯P[Z„  øPd™½?d✯Rvh7kÞùb“±{í» 5…­Ÿ¾Î쟢ºä M5%xÚ[ùüŸ¿gü¬˜ûõÿÂh²’»þߨÊó¿‡ÛÙBJÖ ¶}Fδ{Ø»áÊíaþ£‹ð¹;&d>·“Ô!ãh©+'"&‘œé÷ øÔ¨À;?ïíÚçvbì&ç÷ºÑŒÈ¡>Î>×5¯#¦„ÁlÃïu#IPZ´¿ÇÅ–OþÎw~¿ŒO^ÿ/Ó†’˜1 ‰¦Ú2v¯}—ÿi#G÷ 9°í3¼î6Zê+ˆIHã“×ÿ‹€ßKCÕ1êʳ{­q[«7 øim¬bÏ覆$€šÒ"¾xÿEüÞvjK‹Xö—ŸñÓW·°wãRöù1ßûÃr>üËSL¹ãÛ´5Vc0Y2î&”×"F‹E– ø½Lü>7:½FKsm- U$gŒIâÀÖÏ?ë~îø£ÙFRÆþöË»>q iÙ|ñþ‹ÌüÊp»ZhkªaÐÈÉx=ÎsŠU1næWº}p$ânkbÌó{M?ëþŸðÉßÀè©wÒPyìŒÊ‹KÉ"ðc0Y°GÅ…UÄúž˜:zݬ^Ï 7ƒÃ¹ª"°Noì&ÌD89¹ï(ê_¼ÿbÏI[c5WkJpqˆŽ8†#òøyË/èFÚZ‚§w¥ô6ÓæmF¯ýiÖVdE"&.¦ºãh4çÏ·, g}‘›« ÑÑêL¯wŒ IDATûdŠŠÔ¿_üB]!ÿÑà•WT «—¤Gí_y½Eã/Ê =!ˆ45Á»ïªjBãÇwO«  îT\î¾[ýß¹» ùùWßýÚÅOƒV«îNuRQ¡ªÁõÅ+¯¨;T—!€ΈÆêãø½nbrdR¦«¥ž¶ÆÚnHÙ¡=Lª‹ÉÛø!5%|ôêBÆÜxM5e´·5áHÊàØþÍlþøod¹‘o>Gkcu@pk?ßãÂïuS\°òÃ{9ù6>ûw$gŽÆbæHÞŒf;¶~JÞÆ{Ó½Øú)G÷}ÉüGÑÚPMqþÓ‡S°}y—bp’5‹-I£aå[¿Uwed™­Ÿþ£§ÞImù!–¿ö4iÙã¹îæ …‚|öÿ;¿ó{Ò²Y·ä%$I"9s͵åhµ:TƒNgs¶~ €‚Âê-bÔ”Ûÿ­ó¨nV·¯xI£!26™]k«“}`Ø„[(ܹšan!kÌä®[BlŠjå8|ân_Åðæ—’I}Ç$;ôSUœÏ—½Ú­¿?Î̹™™ ›yŸ'Ì-çž{ï¹÷~ßù¾ï}%dj¬¾ìâU-ƒiW+ÊsáBêÌÇ™L¾añ£nâÌ•WÙAì`Ø$œÛ ÿðÉàòEð 0}}*ò vñ€ÄÕþ¸d–.f¤¾Ðëžû”Ö¼^§£Æª9û¦ÁÔÚ_z7,f.8̇Ǭ½Úz@®9 !7ÁîcÚ×ô ¹próƒXÈ€‡‡Û˜¶kYY$ ª²’¤TUVZw@Œxã zýÀùó$p­àâBŠÖããéFñõFBÂû>Æ NæÓ#d|ÏÉùœ£ýq¶c4èioDGS5T 9.hDù¹¶P™½íMøêµµ´åõ¹èïFô´¥(Í<žÀO½G˜Îýö_ôv4[moÕ£o/rDtÒRLH$L1—²O º( —Ë.‚â¿·•ùç ïëFSM*óÏ!bÊ€ÄÍ½ÍØûÙ‹¦~I&Žoß‚þ^j¹BÞ‡ª‚s8ôÍëØûÙ‹¸xêg*EH!—¢îRj‹/ ¾<u—²yìT漯)»Hú‹ù1 ÿÜo9üª€žf“wöW88ƒcé†qô‡wȇÂ+n>!ÔvÁ13PSœNfª¼ƒáb(Ú€ØdT¥œ<üÐÓÞ0ä}ˆjöÉŸþe0’s!ïëƒÁĹ=ŸsÊ?‡ªÂ4hÔJTæŸÃ/_AiÖq(úÐP‘KÍÇ·ÿÞÁ„mG$q…o¨É𠙈¦júôVÄäùC؇Lœ —¼FO_ïàh$-»gDcN!ïß• Ââg_ù쇛ƒÀ¨DxDB£VÁÕ›ÔÜ„ÆÍBe>IŸš¶ü^ô÷tXmc ¿MU¶§ÿö~ö":›kááF»×ƨǾÏ^¢"*¶0 ë½âwZ9€šâ ö«vŒÅÅ@LÌȶmm%³ÝÆz//R{q­Á` ;®ï¼3öm¾ý6rŒˆ 50vÄŽ?~õÚë¤]-´ñ‘ $ã(ºZjñòšƒážì;ÐZG(D¿Ý¼¯ÞIŒ¯Ó;·Bèè‚ö†J8ºzáž—¾¥µUWš™Ôzî´wp &Ï[3l¢“––Üó"*r ѸØÙýÝmv›êV<ô:¢§‘ °‰3V 0*‰ÖÎÂuÏ!:i R÷¢¾<¿z ¹ÕE鎓»/x1”rë„ò¾.›3êý½pp"3FÑ<#úºÚ¨Ús¸ù„À?|¼C,™ŒÜý•´„r\Ì•¸á“æ" ’PhÞôÀk8ôÍë'f:NïÜŠ èéô{r)²ÞN¸zCìlª ©ÈMAoøBG”dµ8–ÀAZEE¢§-Å¢»þ¹)`0Yð ŸŒ†ò|ø8–-[ƒÎNÓ{´§§eeö‹uññÇ$ufÙ2SmÅpxýuà¹çÕlH) ·ã‰×_zý+¯úùeÂ2”–Ú;þ€J%Y­R@¯ÓAsŸ: #OÞ™_¡Õ¨ÐÓшþž0Lj†_£VÁ`@§×ÂÝ7 A£ÿÄŽ÷°hÝÿQí98¹CìâE;Fø¤¹T;#ØÉsn¥'Év6VS‘£¡,6L& ~aho¨@f±9<´5œÜ©T±Áh©+…W`DŽ.I;­nãì€Ëï¶ÏQIKQšyÔæzsq¼¸Y«iÅó‹×›ª "àâiªbó1ìÇdq0iîm`¨59\>5&˜,æßù µÎ&ͽö[ÖÛ‘Äö=¹ç¥oàhª–csùˆNZJõÛÑÕ Òθzƒg`§ ×Rµ-#›Ël86 ×þò¾88¹£<÷4"¦Ì·º¤É!¸”}_ñsèm5ß^=Cº`Æ#ßÐXLš»©û>‡HBOŸÑi5Ði5ÐëuT=IE^ *ó!ïïuŸ»Zê Kí/Ñ+@M °kùki!é7»v‘ñ½{‰aÑÖFhVwí"¬?#ž*)Ö-¯ƒÇ#ªêË—/Æ¢Es¡Ó‘4ÏÎÎ.|÷Ý|ôÑgؽ{߈Û=yò víÚ‹C‡ŽŽs Z­‡Cj*™„‘É䨵k/víÚ‹‚{ÁùϬ’¤5q8ÄЋ‡Îõçñ€¸8ò/ƒAئž}Ö~ÿX¿ÞToß Sõ /¾OlRX£Ôëíˆ7 MUפÝËeÑRW ‰›"â̯ÐCâêMi$!ï낵Ïâ¡o¡I3þᓇlòü;›²Ëæzƒ ¡ê8c\G@;Ëbs¡ÑX:`~á“P_žwß0‹uî>Ã+J±XJï"qÉzdû‘ZçâˆØä›­îLjàhæˆ%.Ý`ó"GÛÜ}ICìg7ï`ЉËÍ'Õ£ºçgvLýÊü;áæ 6Çv2±Ä´7Vbꢻàèê5Ä}áPlV|¡#"§Â;8æŠÆ¥¬¯ B³k%tt^§“ÉÂŒ‚Ë·ÎéÈáò!qó«WÐUׇLY°,6÷Š÷ïíh†ÄÕ‰K6€/tÀ@ÏŽ£9ª ÓÐÙTC»W#Ayn zÚì/Ì+€ƒÉõ¾ü’°ûœ?üú+É»ÿïI±íûï“mÜÝ %êp8>—/7 ''6¬µaÈráããWWJ°p8œ8‘‚žž^øC$áüù H$Ü}÷ÉD¨ªªEvv.þû߯à€–¢¯ÏN‰o„TJ¬lÁLJеÆÇ‡T¡ ¢‚vüñàè8t4Ã#[˜PH4SÌÇÀH&5 z)ÕÕ×ÿíˆc‚Ô½ŸSÿO?ôõÈ_°]¶R¥¦u3Vιnƒñ3}9¥åàìéÞŽ&8HÜ!qó_ø$ Èzá8Áj» ²Oì`|×¾ƒ“8\<ƒ¢3Ãl¹;¥11’–ÞcÕ8M^ý¨Ù¹>8üËÉÅ‹ví8\>•‚eñ‚ò BµPȤ˜¶ì^Ëó’¸A!“"iÉz«ûgŸØ©‹Ö Ù‰‹7 (z¦,¸!±3ÉyÝüÒö+È30’ZnŽ+‡'“ÉÄåKÙŠž†ØYÄ™»x€Í¡ÙL&Ó"¥Ì+0 aq¦z‹þÞv‹ë!pp‚BÖ‹é7ÝO^ØbgZÄ$ãÈ6$-½wD÷Ñ7$Q‰V× ¥1³V?O@9i×|‘ã°º#¶`>ÍŸG#ºÛêGoTuµ\ÕúñŠôt"&·{7)Dˆ£Á`™Ï¶6²ìöÛ‰ÞÁäÉÖÓÁP(”Ðh4P*•C8?ˆFpp §Œ¨¿11Q(--ÃîÝ{‘’’ŠÈÈpøúz#((sç&cÅŠ%D[[;’’¦ )i Ö¯¿b±ƒýfpépöìÐuZ-qR¾ùÆ´¬¾žÐÜþ‘Déì[Ô[y5¯YCÞ¦gŸP#ëtdRÃî€Øñ»ÁÅ“?jû†Ê|ø†Å£­¡Ò‚=GaCììÔÏ—¨F ™´b*¿¼îR6¥Sàé?Áæqy°9<üé݃”h® ­V€ÉfƒÉdA£V"zÚ2p¸hT¶?¸n>!èj©—oi¸ œhjï3nzMÕ´Ù÷© ,gÙ5“¯÷ X-hö ˆ@ê”ò~\¾t,ŽåL7—'„J!7šB1E×›°pÁ1áA£R€ÍáA«QÃÃ?‚n,{ bÊ|h5j¸û…[uN\½‚,¢6n¾¡˜8c%L8í3‡ÎÓBÜ1væJ¦€ÀÁ‰‰1?_ïàð†›O\óÖÞ5j•Ǥk´¤îƒZ90îßÇ„½èv:«7ÄbzÚÅÞ½Äñhm%Q“á°`Á„„aÆ SýšTÚ©´­­­Ð$·Ùl6T*›qäȉaÛmooÇʕ˰qã¸ùæåØ·ï0ýâæ WW…B45µ ©©½î™L†¦¦&455A¥Rýîî»T |ð°s§‰ZÖ®%³äÝÝÄù(+³Ü72vØþ~é ±Œtüüóë׸v@4 T*yéèõöQ:؃.Ï¡‰ý_¼Œ¾î6j]yîiÜöÔ{ÅkcU>jŠÓÁfsÐ×ÕJ‰š¦íùþ­aœ—<|ýÚ:¼ðENïü:n>ÁCj*èõ:0Ìràý F–yɤ¹kŸºL& “*è ‹ŸŽæjøGXOÑI\Á8 iéLœ±Eç‰sÃ`0­jL¸û†/t„wp šk‹ágfð1˜,èuZ„ÄÎDdÂÅ.¨+Ƀɂµ¶r=&@£VÂÕ;!-#S܉æÚbÄͺMÕ…Ýb“WÁ?b2ôz=&$.‡o[âU(v¦˜•ÃÙáq³,œ£c⃉¹k†&÷žˆÖºÒa«–Ý÷·QO¾È*…ËîµÜoð2½^†äXƒžÀ^ƒ"f7oôu·[mo´ˆM¾¶•Ÿ Ãb\κùQ«$Àd²}bU›4™Ç¶!ié¸û…Qõ7 & IK6 ©º`ÔýŽÎ×XS’qÄ‚Q«¹ºÈjJãxÃ]w#´®xþyb|ÎKœSqñÌ™d»C‡HññH°jÕrÚïÂÂb¸ººàäÉ3”C‚ ì޽˖-¶Í¸¸‰(--ÃÎ{““XoõXÏ<óvî܃;÷@,_÷HEEvî܉;w¢­­íws¿µZ¢$~ÀÀ¢ž›KÏ›2…¨™Þgÿ~2£ýGª°ãjÞýDd(¨T¤VÌn$%ï¸v@<ˆÍ›7cóæÍÉåö‘<ò¾.œØñ uïg÷u£­¡þá¨/ËÁÜ5O£ºð<™íj¨„´«^üO¾gšé2WZ¦^’5ù¦£± î¾ôˆ”[!í²þ1(»x’‡ºÇæ±$GêXsæÌ¼î×uÒ¤Iظq#6nÜ??¿ßÍý~é%¢ñFReÒl|v.¤ï“šJ¶µÓàŽ$$Ðk?ÌqÒìõzê°`}}~>Ñk±; 7«W¯¦‘H4®±‘‹¿$ó(ª Ólró·Ö]Âʇ7SÐ'~ý½ÛiÔ*|þÒ­Tѯ¾zZ Ç·¿ V‹¶† Ô”\°šþ3~“ÑPž ¯Àh]•¸Ôæ¶Á1#ã(ä 0oÍS‰M‡Ë‡£‹—UÁ¹Ødª^`åCo ÙfTÒ‹eq³o¡"4tçäQ”眆ƒÄ î~a6g¬ˆ$Pô#0*‘vœ¨Dú1"l²}yÅ ½¡Òfô§¿·Ã‚ |Cã V)¬ªÏ¿ýÏÐëAõßÁÉ ý½Öëb„bg¨U $¯zµ%Vï]Ä”Ðëõ`±9W<¦“–l€\Ú… ˜é×Çä0Êɺž°6ެÁ7,Ž.ž#ó#…›OÄÎI\!ëí´hßÍ7„í­¦è‚ŻĿ³9q&>z†Ì —f³ºÍ¯^èô:\Ê>;F†yó, ;þxX·è4#CT(H-@Ø‘ÌS«V¯&ëÓÓ‰ ¹v\ºD¨v^¯¯¾Jþ¿d °m›I”27×4‰ñþû@oïõí§] Ý⠟݃à˜é8òÝ›¸ù‘·P”j›j‘Åæ@«USކb Ï‚þ”Ád¢½¡î~aÈ9õ šj½¢±î¢èühµjÔ•fŽØpŠJ\‚oþ~üÂãm¦Ó?çÖµ)ttAؤ¹¸\–=ò‡†ËO(Fiæ1<òÖn«Û88¹AÞ×ÅwŽ<‹M£»¥ÚâpàgD& ­¾Lz½Þ!Ñ\M®[ôôåèíh2ÄÕõ#>?k‹Ÿ¢ó¬ögÚ²{qèë×áìa91eJ2ŽBâæceLp-î‰Pì‚Y7?Š¢ôCh¬Ì‡“»„bgHÜ| áö?ˆÝÿÅbìÄϹªA9ÿañ³‘yì›Â~¾¡qà hŠ,6z½Þêyþ/b¸1±dÃ_G՞ĸxÂÉÍ=´öýðª½Ô½ÿEGs Rv}„èéË‘}|»Å3ÝT]½!Í5*i‰E¡yëå2u÷PõYã}ýÁȹx瘵§Ñ‘1Ði¹HMÏÓ¾2˜<0LÔ6u£¼ªi [挻û^QAêw¤RÂpÔßO¯åápè*Ù"a¼ºé&²¯ãÄ1#z=0Áa¬V“1´p!‰˜#h7¢Áî€üNÑÞXi•®u¬Û×i5¨È; ½^”]ÿ“ÉB¿´ÝmõTîwæÑmC*EK»ZáK+Ôe±ØxêƒcÈKÙΖZhÍŒ‹Îæ¸z£»­žÆä6( ËÝ/!g  u/fÝü(t:æ­yÖ´æÝþôu½?WoD&@`C”ŽÉdA¯ÓYdè“ËåC§Ó"aÁ8`p@¸|áT´W £À_è&kl^ L& '$.¾•ù”^‹9"  ÂjÅ:Ú¼žWoû˜9 ^֊܇;çÑàz³±Ä•ŒEãuêéh¤-“÷uò~Ô]@ua¢“– øÂaÈúLÓ°jåz:‘}bî{ù{2–yš~¤î…r€(ˆ$nèïí°Ùå@?”ý£º×Dpùq˜1ë½kÒ¶§×ðtâ:½*µjåÈÒ“•Š~ø„i? &ÒÒÒÿ÷¯±‘Ð# F¨y:0üø#q&>úˆäæoÛLJÚHôÃyˆÇX($5Bnn¤àxþ|»-5Þ°b…)Zf„ƒ‰” +ÆÊƒÿüÇ”²iLû³; ã­—/¡©ª“ç›èM¾|å<þ}”žº÷3ÄϽ âaRtŒèí$ÿÖ ÷áÔÏ`í_þ•BŽžYˆw>‹žöEOCmqÔ*Ø\ôz=¤]-C~ìe½ŠN¢È3W>‰«7L&z;šMÕ÷÷ ãÈ6L[vòÏî¡fU¹„òœÓ`0˜ÃnW|áИÓ’W=2䵺ÖŸ4÷ºßƒ¡ÎÙF;Î~/‰‰ê¢óVÉ ¬;Ø>´ëT‘g½¾¤½¡í C¾‡¾Û¼be ¾ÈÑ‚!/8f:2G[Vœ~“çÃÑÕ MÕhª.DââõÿÓßû08Ì·oØñ³s„§÷=°åàr¹7¤—ÊjþP÷L£!¬TF –{ï%Bj5q$†‚V 47rWWÀð^-\h¢NõòºàØÏø÷¿-[ˆh«+ìÇ(-NŸ&B”¶ÞÜݼ< Ü0wðÞ{À¿þE”k ; ïuÀ€ŒžX—sz'2þ`Zßß‹½Ÿ¿HÛ¦§½ªõ»¶$ƒöQ®+Í¢±ÅdŸØAûoßòšª…¨F­Â…CßR)5EçÑT]ˆ®Ö:”]’¶Åb™òø¹\ :Úv?&M"ëy<:U¯ãL&ùÓjéŠêæÌy/Yùì°Xd»r1˜y¥¥îzÚ†ÝoçÖ?£¶4“¶¬£© Vè*« Ð×݆‚s{7k5Ô*ª Ópê—±àÎg¨~˜³U¤B­RPýÛÿÅË´6Oýòr)"&ÏGyÎijý¥¬ã¨ÈMAµ…¬ù¾Ž.žv™ÁEŽ.,IMÕèíl†g@$’–ÞsU×7|Ò#uk×zÔÇ~˜8*FãoÉ`βݔ)ökmÇè0k°|9©¼ÿ~’ÊgÎ`аQïÕ`ófà·ß®Oí5 VÐV_ŽïÞ¼ïüÖl怔âÜžOðôÇ©eÇ·ÿ~añpó _è±³dRÔ–d€ü#&££©5ÅÈMÙôCß`ÝsŸ€Éd'£ºè<œ=üÑÛÑ„¥÷þ çö|Z&G—Ç IDAT‹¤¥÷àÌî¡ÓjàìîgOÈ¥]غq!þ±¯—²ÃÉÍ͵%8àKð…b0L¥Âì[ž@O{ª ÓhéK<d½¨.JÇù_áÁ¿ï@Wëe‹ó¯+ÍœÛþ„€ÈäžÞ Yo'<ÈH ™H/ˆL@“¡PzÕ#›m^ÓòÜÓÐiµˆ™¶ MÕ…¸å‰-øäù›þ}Xl’vÁæð™0f÷Ò'$ÞAQ6ŒÑÍ£0\G¶mH¬õ¯¾1½ìšâÑÓ©ôºñ[éà>yØô¶±ÆHë+†ÂHE&‹ƒÀ¨Dë/uañDG¥¡2}C8 #_è8"¶:¥L ~À´7T@(&ú«¶îôeù1ÓoB{CBc“ÁåÑ“Žw}ô,<èâ=íøþÍ{!qó!¬pÀ¨j[Æšš€·ÞbcÇ ’k×’oµ6- 466ã‹/¾ÅÀ€ ·Þº:]]ÝX±b víÚ‹°°üôÓn8:ŠÑÛ+…P(Ä“O>77—ßå5<ž8pyyÄH3χïê¾ûxöYÀLJü_"!³Í~H’U«ÕéEC¢Cg'°kpù2I“ª©!…â'Nåii„ù  9œIýH\Üð‚s÷ÝìÛG ‰í°ÃË‹8ɰx bLË2jo&$Çøí·MãöZñ‚öÆ*D%.ÁÅ“?¡±2yg~EuA*D7|üÜRdû-u¥P+È8² ©ûP˜¶¹gàêˆÊ¼³(¾pYÇ·ã?Ï/GO{ôzÔJ9.žü,B± R÷~†¢ó1yþí`±Ø8ôífûq òÎìO BIÆa\¾”†Ê|*µB«Q¡£± n>¡ˆ˜2²ÞȤ]à Ä8½óCÄÎ\œS¿À7,‰‹îFeþYäŸÝŸà‰ˆpáðw8ºí8ºz!"aJ.60Kã‡/’@§§§„ù†Æ¢—`åÃô·cTâp †žÑ‰0ÇÑÞ@ÒÌôz=r)*òè '~zŸú?‡ËGô´¥6 +.¼Ìœ ±‹Ç°Î ƒÁ´™fb­¿.^88ÙÜÖÉÍgH"&“uÝi_L&MýÝ¿°ø?ì3Èáò‡T‰‘SZÐû^kÄÍ^}MÛWô¡2ÿõ,8{ø«0K7¼8æ}nl]8ô-J.Añ…C`qLQÇÎæZªV­,ûÜÍÄ)®…«OÄNî¸ù€ÍáâÉ÷ƒ›o(Bbgbÿ/£¡2Ëîy ÞÁ1¸xò'ä¥ìÆ×¯­Cú¡oPšy?ôÒÓÓ1^áãüõ¯¤ Úww¢°e 1~Ç••UP(”˜<9'FáÀ£˜1#"lÝú_øcÒ¤Xèt:<ùä#زåu„‡‡ ±±éw{ wíJJHt"Õ ¥›o`.ÖëIÄ©´”8y©ç¸p\s‡¨—/] ¬\I @77àÝw‰‚ýc‡†ÁfÏfÌ û¼ø"qbø|ë} ›MÚHJ¢ Ú1>Džû¡Àã‘ Š%KLº!óæ))×¾ã2rñâEt RìQ©TØñÞãp÷!DÏ|ý÷»7 añ³‘“² :­ÑIK‘nÎüúD&,@aÚ~”瞋ŃÉÄì[GÞ™_ÑÛÙ W¯@Ì\ñö}þ.eÇÝÏŽ_¿'7´7T€Íá¡èü~̾åq´5T` ¿î~axxóN”礠¿§‘Sqì‡w=}9ºZ/ã¯_åà›7îÆ¤9·A!ïƒLÚå@?¤Íèïņ¿ÁÛ÷Å¡(ý ÖýåÔWäâ»7ï…ØÅ“2X´R×!vò@`TúzÚ¡×ë?Î~˜;)@ÕjÔˆM¾!±3‘~ðkpxZ “ÉÄÄ™+‘²ûß6¯õ@_¤]­PÊúÀµaÓ.hN`}ÍÙH'6Ù”Óžö·!gÁG .O€äU^±Úš˜àÕbþGµýÜÛž“9üÜÁTêÞ× ƒÏc¨ór÷ “ÅÆœÛž´á82lR_¯þGW›Ž­ƒÄÍb6,?ç6hT êwnÊN,Ùð"˜Ü¡^Ø ÙØ*LM]|7rNÿBýžwûF¸û† ¡"1Ó—C§Óbßç/Ñœ@ÏÔ§S©¬Ž®Þˆ˜<%ŽPÏ7‹Å†gàøGLAà„©õBàà„Y/]¼ Ñ#dâLÄN˜<ï|úÂJ4UbÎmO¢£± ÒÎfxúøaÆŒ°Ã‘hdì•Â×ב‘„FgáBÂh×ÑÑ wwWttt&¡tèìì‚Dâø»¾VÄÉøí7B‰›šJ¢ ï¿Oê3fÏ&âE@AašúòK °8~œD)Œ”¦³ ²E¯½F¢ ë×ÇÀHÍËç“ãÿY,ÒöÕ‚Ç9ý¯ã «WÓue$BÿLûfHd/2’èЄ‡_›¾Ø# fX´îÿ0ûÖ'ÐÝV“ 'w?Ì\ñzÚቛx ~“¡Ój!qõ‚LÚ‰þ¾ Ö"|Ê¡±cÒ§ÄÅëÁá^K"y¥‰†˜ÍåCìì ±“ǵåäîƒiËW„Ž.;{@âæC¥‚Àäy·Cà0r-y_7òRÿ¨¬§ž‘IMòÐÒÎfH\½7{5X,\<àì€ÌS{ÆMÄX„^Qa2"šš•æùóÄ HTÄŸ±íC\ÜD( üôÓnìÜù¼½½žž_Ü}÷‰DÈË#ŒŒÇŸÆ¦M¯¡µµ!!A¿ËkÚÜLt\\HäâñÇ -éÚšï¾#5ß~K(sR¿Á瓈ƒayR´óù£±¾3g]°nÇÿ>~Øö:WWâ ZÊd<ÆÇ§ùçŸIzàµÂ¸Œ€$$X¦í¼ÇåÂÝ/ ^QXþÀ«àò¸ú`úM÷#lÒlœüé}̺™Ì’‡ÅÏwP4^XéŽ[ÿô.&ÎX(H݇´ýŸãÎgID@äèŠÝÿ·=ù>üÂ'aÇ»AÖÛ…KÙ'0såC˜4çVžßæš"xE¡¿§ÝàèÑPUÕ@?¼‚£áê„öÆJ$,¼û>ÿ’W=¡Øbgt·^FÞÙ=˜¶ì^¸ù„âÓM«ÐÛÑ„‰3PSœŽÈ‡uó ÁÙ=Ÿ"zÚRÈûºáꌚâ ÔùÇL¿ =í¨,8‡ýŸÿ *…‰‹è3èî~£sƒóÎþ µÙŒ­£‹¤]-T;Îþ`syP«Ш`s-cÏUùçPS|*å•êu50jÔ–dzýUÕfÄNC®m‚/ƒ/$EÕdöŸ•B› wßÐ15Ö= ÷àôέ¸å‰-V·É>¾Ýâ†;ç«6¨4*h5jpù¢ÿ©wŽB&½¢”0se÷±†»í8ӗ߇¤¥¬n+ëëBIÆDO[F-ãp‰  ù3>ÿŽè'MOÿHå.íÃÃáb ¿å¹§…iû±üþW3ã&j›Ó;·bÍS¦ôÌÞySßžötµ\Fcå'X¼~kΨU“03&Œ‹o™±Ý>>ÀÖ­ôe7ZÿÿXÀÙÙ Ï?ÿgÚ²3LõIsç&vìØ…Ç{àww ÓÒÒ°oaX«ªªÂ/¿úŽõ™™ŒD?t:BkÊá·ÞjÙÎÝf¯Êyó,uî¹8rX¶ è霮ѫÔÃvŒs„‡õõ¶Óùlá‰'ÈøHíÑ3Ï\Û~Ú# V7‘S1kõc†s(—˜>Ì~añ`2Yxú_GiF…›w0¦-½×4ã7ÿvx™¦"n}ò]<üÆ/øù_OáŽbBâbÔ]@Aê~p¸$.¾q³nFAê>¸yƒ'pÀäy·ãìžO•gÏÜùìÇhª.‚¬·5Ånöjª¸Ù«¡RÊQUŠê"㌥ƒg÷ëËsPšqÔЇ½×Äè Œ}.·~¨W½U:p‹óV«GÜ¢Z9€ÖúrC¿oAÁ¹ß7 ¡q³iÛ©r|õêZ”禠¶4Wèu„ ¡ìâ)(å¤þÃ;8¡qÉ•oK])ÊsSP‘w†b I\©(%@ê¹Ü¼ƒ!’¸BÞ× ƒïàxFÁ+0 B±3„bg8{Žçã†Õ«Wü.û•œœŒ-[¶`Ë–- EL ìßüú+ðË/ÄÉÉ}”D0öî%ŽÉùóÀ矓vâ ¯{†PêS©´Zò70”“Gï¼cv\[,X@jFƒâb ®ŽhÚÈddœïÛwíúhgÁ!³¬0˜LEO£Ï<…ÆZ¤^̺ù188‘4#¾ÐÞ!qÓý¯PEÍ/|‘‰oߨ€e÷ý ^¤æáÐ7o $–ÌMšs+¼£P]œ˜{Û“ð ˆ4}ñ2¼ƒ¢ÑßÓŽ¹·=‰#ß½‰GßÞƒo^¿ 7ø†Æ!yåÃ(JÛ¥÷¼„ÃßÑÙhr2+Ëá ðùßnêGÞ„LÚ… ‰‹ÑÕ\ 8ðÕ«Xt×ó𠜀ôCß`êâ»mÂUùç R fúrj™ÀA‚þ^êú…L$…¤¹)Ÿ<»Íónÿ3J³Ž#bÊ| Ȥàð„4Êãå9§Q™7=ð*Òö'7?¸z£®4ËàÐæA¥üûÙ%ˆM^Ik·¥¶.Ò®Àš§ÞGsM *óÏ",~6b“Waòü;Pw)=íŠNÂÿ2€Ì¼ßââÒ1i‡ÇãââÅÑPOOÏu?ßY³;•‘²´­ ˆ‰!b>HŠÓËËÿü‡Ô44Ùf³ÏâٳĈãóÉÿ•JSÁºvüÞqß}dÌ/\H×±; 0ø„L¤ýæ ÅX²á¯´eSÜI9)„ŠN¢ y€H¸û‡C¯ÓƒÜ )ÑXUï ¬2‚Q‰`³¹xô­=`±9XõÈ›`±9˜'aò ‹G@D« iû¿À„©t#²ª +ü;¶½u?my[}9ôz=º[ëG5/pp¢R2rNíÄÛÁoŸnBEÞY4×–P5eÙ'°ŸÉÄ¢»Ÿ·hãZihX5¬³OŒe®^¯CmqxB1\<ýÁã¢êÌ£Û•Ï€ cÚïë}†CuaåF݉›Íz£á ”÷££¹¾¡q×õÝ¡ÓiPž“2jäJ¡RÊQ_‘kÓQ3GsM1$®$y] ’ §£ UÄùH:ªZ¥€»o倨rZq¾ÐÁ }=XõÈ›8¾ýŸho¨Dôôe¨*HC¨Ùý®ÊO…“‡f®"5+!±ÉÈ9õËU«TÚ‹³g+ÑWë WW7„…EXì#_ßâi=û~DMº¾DôI66˜ 6DŽî ‘é0ñÅ@AÑ×õ˜ÎÎD-:=èx<ôI½zí5ò÷Øc@h(©½IK#µ $ªñôÓÀ?ÊS¥’žóÎ;$=.3“,ïëÄbúz6›ìÇã‘™h ðóƒv\1*+ ‘Âý÷¿íŽ€§çÈØ³ìȃÙs«G&Ð ƒƒ JY¸ö/´ßQItúZ£èž±ý'ß?H‚Ò¬c:º`í³ÿAgK ú{:L=b'8yøáìžO0çÖ?ÍåA)ïÃLŦ¡"*ÂM\¼YÇD¸YÁ©uƒŠÐû.¿ÿUztµÔáŽ[©YÑ‘¤ †±ý½È;ó+U§ó{€^§Cáùpñ —¿xÌ#µñï æcc,Pºïбž”÷w£2ïìuw@FƒðÉóhÏç±í[°xý £t´úPžsÚÂ9ºíí vúOcôE ’ ûĪýÕ›rOœ=Pw)ç „z½1Ó–ã“V`ÞíFTâ0¿âçžÄÔEwQç7ëfßC$øJÐÕÕÀ@+N†>>¾P(d´å2Ùø|>¦L‰ºn÷TÀ> 6÷ð¸þV¶´z¸þõ`b1¡%9“äÃûù_}E¢"‰‰€·7™>vŒ¤gd]…$)X"C—$)Z@{;q<Þ}—´‘—Gœg/ƒFC×ù()!ÇÖj‰i¬I±ÃŽ‘ ±‘¤TÓ)¹ÍñöÛt5ô¤$’Vx½`w@ÆŒ´¦óï|Wo¸ù„@¯Ó¢¿·ý&šNw¿0NH„BÞ‡e÷½Œ¬c?X°%eŸØA™\ªÓ[£VBÚÙBýVȤpr7Mãˆ=ÐßÓgÏÅNðó „‡û–ÞûÚ*àäî Z €D_<ü"¬ž“±zJ³|ñëþäŸû Ó—ß]Žwz燘ÇȪÂzÚ »\uÚÓ•À|l ‡Ž¦j¸xX8å#=×6C]ÂxÇŒÀÁÓ? ™”ò ú{Ú¡dPnœ÷^ñ»†ºO ðð‡‹g z:šà‡ˆ)óáîŠÓ;·ÂÃ?óïxžj¥,\¾Sß…ÞŽF 1Å èéˆNZzÍ®§R©¤ýV( V«¯ë=e0ZÁdŒoµ÷²KánܤÒ`ºRxÄD‡gž!ÎÈk¯‘c‘xê)´|9)VZZýiv6‰|°XD¡Ö¬!ùúõõ„}Ëåå$µK&³¿ã쥽p8yÒDm ½V^í­­DôòzÀ^„>aΦÄ`² vöļ۟†‡_8æÝNØLbf܄⠇¬2/©U Èz;¡×é VÈ-Ø}d½È;û+ôz=˜L&Ú*áîGެΈŸ½Ӗ݇9·<È„…ð Ÿ'w_„ÆÍFQÚ\8ü-ø"GÈûzÐXUˆºÒL«çQ]˜†æÚâvuZ-úºÛF´­¼¯{DF`Úþ/, CzoGóˆûV’q=Wt^å9§ÐÞ8:)ÝœÓ;©T;[‘͵¸”uœrVTJËõ‘žëù_ÙèA×wÆÊ‡ÌÆN#jK2ÐT]tõÇhk@æÑmP+ ë•B._$Fò¢Ž}‹éËïDŽğ”u\¾‘Wœ?ðžþ×1ª¶öb²°xý& 2€™fçhÇÈ!—•ãöö±i¯»(+¿×ÓÛðyܺ˜6¤X=òIc™3‡8#7’™æõë„@êI^z 8wؾ¦¢v€D]¾øÂ>ní= IºàCf¯Ê†úúôtim5-OM%uPvÄŽëgÄϹQIKˆ“âæƒžAQ._y_ª RQ‘²^è´Z°Xl¨r*b‘uüGh5jè4pxBÅ$Æœ´d=8\>œÜýàæBô7\¼(ÆÉÝ͵%8H¨vú{•„¶†rº›}>!±Vggò>hµÖcŽ¥™G©”3y_·éÃÜßC¥3—÷u·âRö‰í½¶æ²‹'Ñ\[BýÎ>¾`€:fÖ1BâßÞ@7ü»[/#?u왿T u¿Â•sz'áHy?4jT ôzå\TæŸEwk½E{]­uÐXI¡ÓëõP)äH?ø5íØ¶®UuA*:›ë®úüŒ×ÓZŒ)AÿKHÙõoƒS¬AÆ‘ï?‡ð„¦ìþh쎱ûßèl®´«7´Õ—#,~6|‡QEW)äàpy`œˆËeI§Bwñ 2]Îø±ãê TCw÷îÑïÛØh©Ž,“ÝŒñcäÂÅÅ”*õª°0Óú§Ÿ&ÿÞq1òÂÂÈv‰‰dtu‘¿’¢çQ9º¹ de™Ø¶ìß–šŠÿýo).&ÑŽà“Oˆ¶ e ^ÇWí¸v@ úúúÐ××½^g­Ã`ÂÔÅ8úÃ;8÷Û1ç–?á“çMœý%‡q¹ì"tZ Uäá“æà–?ýà3D½‹g ü#¦àì¯ÿÁ\ƒ:ö岋Ðëu9º’ˆ‹^€Wï A}y\}‚­¶•}bº[MFlþÙ=€â ‡àá•R†–ºR¤ìþu¥YÐjÔ8õó”A~ì‡õ€ Uíw4W£4ë8ª‹LÉ’M5´0…\ŠKOZìk¾-u—L·¾nÃL¨%oua”6RœŒý¼|‰ÐÁ$„Ãã£<÷4Ú*P‘{5Å 0èXm ­—Ë 9¡¡"-uÖé)K3A¥@£AGCÞ×M1øÒ’Z¢¿§ƒÆÐ¤áøtZØžöpùBÔ]ʦ–µ^.CÖ±Q[’¡£ 2n3܇c€Âóûqjç‡:º ûÄh5jþv3šk‹¡KQ‘wÞÁ1h3ˆ3š£»Í’í¬¦( yJ³ŽÁ/<MÕШ”¨/Ï5ô粎o‡ÐÑEé‡hû^.ˆLÚ‰_¾Š†Š<äÙ ­F µJÛߥm; ë—/DyÎiÔ–\—/DUA*ª RÑT]dq « R)'h´¨*H…ÐÑOþ4ªýJ3Ù\gì_{c2Ž|÷»xv?«‘€Ëe©{ç0Át_½'w_ô´7Bäè ÿ¡EH¹|–¬ßdu‡ËCØɃ±ò¡7ì/ÛQâË/‰J÷–-d¾¬ ؼ™üÞ²…ÔZß÷·ßLÛýò É+-5-++#¬8ÿ÷d–þÿ0íû Ā1âõ×Mû ¤Ðzß> !,ËÊ"ôÂvXbút ™5‹8…W‚+€Ã‡MN£v¸º’ñoõ2Š`>Lꔌxÿ}à¹çHÔíz1¯kdÅŠxùå—ñòË/C(ÙGª ,Xû8H\)Uõ¡ ëí€OH¬EŠMdÂL˜ºpTÇ >qâŒ(J?ˆšâ PÊûP]H¢ygöÐŒõ¡?•ùçPWš ¯ 4U[~©kJ2 RȨbZ£Cċ7G™!òqà«WÁå‹ÐÙR‹úòìûìoCö£¯» j•©{?CMq:%®W’yÙ'~‡'@}ye8$cN ×ëQvñ”…#8R4TæÛ,æ¯-Í€r ßÒˆ/LCwNýòí¸ý½8õ3¡Ð¬/ÏÅ©Ÿ?‡ÇGAê^ø†Æaßç/Ñ#²>pxTäA]i68<ª‹Î£ºèÀ zXƒ cèáæâˆ¤¥÷P¿çß±‘J?êhª&uæÜúÎî!ì0 &“šÅÕëõ(J?¥¼§~ùÐë(ƒ}¤`04jÛ#ß¿E[oþ»,ç$Í6FL›–³š8s%œÜÀæððã–‡­»§½Nî¾8ñÓûð ˆÄ¡¯_'† «Ud¬I‘²ûß(LÛh®.¦Ô¤ÍÁŠ©ë5R4V "7M5Ôõ5âÄöB£V£µîrSL äÍ5Åèl®…^§‡«W*óÎúÙ‹ÂÔ}ÈMÙ€P5·Ô•‚Ë¡¹¶}Ým9ºRíœùõc‹z›¦ª³T.KT䣫Z/—ÑîO}E.ØjŠÒÑT]D)k@}E.Xl-íËàºAoHãÒëtÐ8¤êËsˆ#hƒîX&íDuQÚðŽ¹´ çö| (LÛiw«Mr…¡0x<N=«.>C_wÄÎÔõ09¿¢¿§É«³W`æ/3Ò®<ø÷˜¹ò!̸é8ºx/rDPtÖýß§pöðƒƒ“;]<‘|ó#˜²àN̸éÜöÔ{`s¸;{búòû(ÇQ9ÐG/¸xÉbYЫ•صõ$È9MT²‹3Ž øÂ!TžGê¾Ï-îeþ9´Ô’:žÜ”]èïí@O{#4*%2 ÇU)å”aoDYöIðEŽ/€¤©•×&É])ï§ã4* &Xl.ÊsOƒ/rDceíY ÒÎf*ê±óè-É ÷{ïg´í« í&É«³x\ &ϽÞÁöœœ±Fd$™Å 7Ìû0™¦È†¿áµ-˜– œMËŒF¯——i™¹ÃàçGŸ)|Lô_@€©-ʹô$ýú=¡µµ™™™ÈÌÌ„T*ý]õmΠÚ,À½l¡>6¢¾JI¤éóA¯¸¥K£GíÏÅxDG=åR,&“‰¥ö‡ñù\»Ö$ y½`"´ÃºQÏ@ÂX,Ÿ»æ)“ÂdbέBSu!2þ@>fž›4~áñWt\cûƒ  ç®y ¿}º‰ròÏýF­»íÉ÷ÑR[™´ n>!èj©…ÈÑå¹)˜üá“ á±wöÂÍ'mõ刜29§w¢µžL‹åœüõ¹ðŽ¡óÙçΦ¸zSº"FœÙý1ß èëj…£³'Œu¥ý=PȤðˆ€r@‘£ ¸³ILL 1u|öYÍÌø%êÔ¿w¯¼Âhк;'n£n£68i«gâsd“8‡ã.9%Œýh ùÙiD5kÏO3^£A«®äá¤ÕÙeÝŒ½—ðê—;ìV¦.üƒ†mîÆÕÇúwtq¨ûb9Wû(`¥sàæUjýÖwv%©D¹ìA l6:g7ú~ÿ°zD5kO»Þ#˜ûÎHZwL·Á/:t|Ã.DŽÒhïcïÆ%ÄÞ3œæàáLxƒVüµ}÷>õ_¢›µgáOÞ€=“—™Jht3Žì\Cƒ6ÝÚíâæUa¢Ì+åô‘]è]ݱXL8áxýœúk;îÞŽI²ÓÎÕ¬ÒúòsÒ9sd—=uã¸^$ØÌ#¯Ìdõ¼wÖh‹Û%ü4ªãÙ!(¤¥¥ñßwÞ&''G„qÞ%N'·1«W+ù=V¯¾²õ• f³’ùwn/y­Z嘄ïvæb9+¾\¢€· Zw¯¶ºµz¢š¶ NÌ•OñÒ»zÑøNê6lcO¶vq;{?ö:*µš«çãMØEI´î®$«´=´U™z>õ_‡Dn%æèænÚ¹øÔì–—CÆ]&êˆIßb³Ùðô ²+%Û”=–ð†­kìõVÙÈ{TÓvößq½³ÿ~潟+í/{=D7mïpüþ¡QÔoÙÕ^6ôÕ™`ƒ¬´sìX5üìtŽÜÊ‘]kí¾ û7WØ®ƒ[—ãæåÇÿíJ×Ac+Ì ž°s9kXÊ™£v_œÊxìµ9G4*sÞÚ s.õË*ÈÍä\Â~»Ò°uw~®¨£3 £ßüÎjX¸q2fÌÜËÎ¥ìI,oW¼½!.ºv…]»”(g¾¾ÊHöÖ­ŽûsË_‰ŒõÐCJô³çžƒéÓoîq Š%§u5¿R~þYÉe³ntáðaÇ`µ/¾Pòt”¸¶nUP\L÷ ºeݺ)A$JHˆ"Õù»„÷cɲ–]¡Ñ8UòTW”ñ²u×”ãmÖÁ1DJPÝÒ'Oý ‰âjâqTmGF}M×IÙ²’ëÀ7¨.½ûþú nž¾¨5Nìݸ˜ º8´mÅ…ù4mç˜vú—9o+<ýH;œc{7–S@m[QN9—°ì´s•* Þþax„9”ÕoÙ…>#^çý§Ú]™‚¯s&$²‰’]%ñInnn®=º_q®®®„„ݶÇÿúëJ¤+EI…”%2V@üëQ®•0Û¶)‰æòóýDn$ãÇ+Ý”e ¯U«ª­Ï%Zú±cŠsþsÏ)¡ çëLJáÃ+îŒ×DÞz«4ÚÜå8sFñŠWBë^ùûÐaAd&Ÿ)WÞ¾ïãrRo0//Oüý}EÀþý‡nÛcwqQ>]˜Iz÷ÝJÖúe¤[·Ê·¼Ìí{jràì o¼¡„÷]º ºXáSœÖ¯%‰da¡’Á½$7I\œ¢øúBß¾Ê7(™ÚÿüÖ¯Wë¯6ükzº’Ófï^å8 K—ÒpÓ£R)˜Ÿ~‚âbX¼X™šæí­('çÎ)Ûž)ó¬[·f^ ÀСJ²IP,>[¶(–%P 6o®Èçb.>×¢€ÜDêׯOý ̵Z‚ U…hÞu¬ÛÀ:õùjÒC´ïWÚ#pq÷"3å yYجÖ+ªÓl*&#é$n^J÷ã·rÿ3ï]sõ.îV¿;ïÆì7‡Òùþç.»mX½;ä$Wjµ g [dWÈ,«¢ +Ά ó¬\ŠE˜=[QFyP¦r*ŽÊNNŠ¿ÄéÓ¥ OÙœEEŠS{Q‘R6ož2­É`Pò»¼÷tê>¨tv›V’îgäHåû×_«Lf¦¢H´i£(*c2AA2•*=]Q$""”©e©xY§N”tå×…( ‚ · ½+ ÝgÄër3°\Hè¤ÕX§>›ú*öoþN÷>‰J¥Âl2:Ô“•|Ÿ º$ú‹=£svÅT\Ä ±Ù8öšÛרm´"ùÔ_J'%² I'—[O[&'PÉïK9Ä ‚P}„„(¹®ÖØÇî»Oñ‹èÒEÉ)¢Ó)V–… …ÄÇG™µd‰bmyÿ}%ŠÖŠ{Ÿ>ŠòJ‡üìYؾ]™ïÝ»´ãÜô rö飄~à¥óÿÇÊÔ#µúõ+µþœ8¡„5Jiÿw*ëÿç?Š,®zpÈþùOå÷ŽŠc¼J_~©üŸ9S™ÆÕ³§¢„lÞ¬l3p ¢ *Š’‹ ¬Y£$Œôòªºó{äˆ2…íb /Êq»hÑÕ9©—вeÍË, ˆ  àÎ{†zgWÒÎ%Ø—e$ÄÅÝ›i/ö¤e×Aölîýù+ù9é¸{ù“•zÖ¡ÎëQ>®†~£&Wø[„O¯^ʨAÁÕm׬™’Í>0Pñ¸þ€&M”Îô¦MŠ%b×.¥#Þ±£ÒÑ/±žŒ£Lÿ‰‹S:ë3f(ÚPÊ®–’ î½{øqвa4*ˆ'žPŒ•©Sï½| ´¥ªœécc«NÛ¶Š2£LUóóS.£Þ}W±}ýµ¢hüò‹¢x•äWùãxáÅϦ:™<¹T)¥C‡^}=×¢´ˆ"‚PËñ¬CÇOpè•Ø¬NþÓž½½"â÷nDm=|/Ž·„OO±ÿ.I¾ùÓéÐôµ30¼®>rÂn!–,ù‰C‡þÀÕÕ…ñãÇòè£Oиq#, ááa t/ß|³^x€7ߜʓOŽ`öìù¦ àî´o{á÷ý¼òÊ ôèÑU| »úm]&¦DÊG¥R,  Lõqu-upž2 ];eä¿*Ýg?ø@©oëVøÇ?”Lî_ ¯½¦øiôí[=Q›:t¨¸s>~¸ººÐ¶­’€¡mÛV899¡×ëÑ”Äô¼ ¸>óÌh¦OÿŠÜÜ\ èÁP@§Nq¸ººbµÚøæ›…<û¬bIûûïxbb¢ðß‚”òs£©MVNñ+9~&M‚#§¸])Ó¦ÁرŠÜ³³üŠX¼¸ôwa¡’æ»ï«( ‚ Âј¤SQ\˜w@1-”d„aõZЪëƒxúãITÓöè]Ü®8rV >á4ëП?ý†žC_­t½Ø^ÃÑ»¸É ¹¹ï¾~,X°€îÝ;Ó A áá¥syJ~ûûûáççK]ÐétÙ¶m©©é¨TðøãÚ·Y´h)>:¸Ö* IIIœ"QQoóË/Êt,77(,¼ud!A„Û€OO!‚ ÜD 5Uñ9q}bc+W>6Ý¢‘ÓÅ"‚ ‚ 7€7ßT"V]HCwI:w._öä“°x±( µš½{÷rêÔ)Š‹‹å®AAª« —«Õ–/Óëaà@ÐéD©µxyy€Z-³ÑAávbëÖ­,_¾€ãÇ‹@„Z‡Gí?†ÛZ‰ŽŽ&úBàemEj¦ ‚ ·,;v¤cÇŽì¬,Fª ÜdfÏV2 ßJȰ¿ ‚ ‚ ÔP޹õŽIAAA¨aôï_ú[§»2ÇuQ@AAA¸&ô·“´kwë[µú€DDDâ\Á¤µ2ù°AAA¨€Aƒ`ܸ[︪UquuÃhtLÛ˜œœJýú 8yò¤=â„Õj¥mÛX¹ÊAAá:  ÈU‘’’Œ‡‡;&“‹ÅBvvááuí¨, z½³\e‚ ‚ ‚p‹S­> ™™S°ÒÒ2puu½°,¢¢| óHMM"77÷ŠëÍÉÉaúôé—\§°°Ï>ûŒýë_¤¦¦Ê™AAj·ž¤ÚÐ322qvvÁd2a2™ìåŠÂ¡Âh4’žž^¯¿¢ú ˜7o{÷î½äz³gϦ_¿~Lž<™Ï>û ³Ù,W° ‚ ‚Pkprˆˆ¸ÅŽ«ºw““ŸŸïE¤TÉ(**¤  ˜„„tºŠ“Z­VÅA£Ñpüøq†ÎÙ³g/¹ßÓ§OqálY­V, NNšòÄ IDATÊáΘ1ƒ'N8¬ô|>_M›‚«‡\í‚ µžñ :ua‚PëiÖLùÜrŠUuV^¿~C\\ëGLLût,•JEhh8z½3M›6ÀÍͽÜögΜaÖ¬Yöÿ]ºt¡G×Ý®§žzª\™ƒášë\¿~=Ý»w¯9ÖÖº·lÙBll,:®ÊëÞ·ouëÖÅ××Wä}êÞ´i:uB£ÑˆL¤î›R÷ÕPÏA¡( ={vG­VåcîZ­V4ÍeÃñFFFòöÛo_ñ>¿üòKyäÜÝ݉‰‰!!!ˆˆÔjõe;N'N¼®ã5WÕÖÛ¡î·ß~›—^z ww÷*¯û믿¦cÇŽ4lØPä}êž4i“&Mª–ŽÈ[êAD©šŠ*ïð«Õ×>ŠúçŸòÃ?••Å„ 2d­Zµ`óæÍÜÿý¸»»3bÄæÌ™Ã™3g?~¼}úUm¤E‹µ²ÝMš4©•r¯­ò–vK»oåv BupìØ1»O©¬„[@©.ÚµkG»JRAÎ;×þ[§Óñä“OÞ'iذaµ²Ýƒ yK»¥ÝÒnA¨±xyyQ¯^=\\\D ‚ Hí"$$DÚ}ñõõuñ,ò®^‚ƒƒQ]nΤÈ[Ú]KÛ-ܾ€‡‡‡DnD¥ª,ʯ ›ÍVk„”““ƒ———ýff&………„……ÙË^|ñÅrÛåççãââ‚F£Áh4:˜wÝÝÝñöö¾éÇVQ»k÷Ýw_­lwm•÷sÏ='ò¾Ûm±X(,,tðç*yž•tÞ*jwFF………Ô©Sç’ÏUAáö¡Zó€ètnh4ºrŸ³g“ìëX­VæÏ_ÌÔ©ÿ‡Ùlq¬àøq?vï“ V®„¢"eÙ´iðþûÕ. 5kÖ0iÒ$ûÿsçÎ1sæL–.]ÊÊ•++ÝÎl63xð`ÈÎÎæ‡~à‡~àûï¿gêÔ©rõ ‚Pã±Z­|õÕW|ýõ×ö²]»v1oÞ<æÍ›Ç®]»*ÜîôéÓÌœ9ÓþÜûñÇË<Ú×è©`V«µÜGA¨% ˆÕjÁl.*÷IL<_æE¶/žxbŸþ•cçÏC·nЦ ¬_~F£²lìXHO¯våC¥R9Ì 6m'NäùçŸgß¾}fp7™L¼óÎ;ôìÙÓ^ÈØ±c;v,YYY¼ùæ›rõ 7„´´4öïßoÿ¿{÷n²³³E0±páBêÖ­ëP¶xñbÆǸqãX¼xq…Û9991pà@ÆŽKÓ¦MíÏÑøøx6nÜHÓ¦Mkäñ¦¤¤pèÐߟS§Îàââ,ƒ BQc|@||¼yúéÑ•¯Ð«T2ÒV]téÒNÇš5k®j;­VËk¯½ÆŒ3Ê-ËËËC¯×Kœzá†ñÓO?ñûï¿óòË/Ó²eK¶oßNLL çÎcëÖ­„‡‡Ó¡CvîÜÉŽ;1bDµ„Nj'=ôiii;v쪶 #,,Œõë×c2™èÕ«GŽaÇŽŒ9’×^{í¦SݺQ4kÖÄ¡Ìh4‘Ÿo €¸¸;–™L&¼½%I­ Â-¡€=šÀ¬Yó(,,$$$˜V­jVxÈëQ´Úг»O›6±cÇÊ•'Ü07nL^^ž=ÒKnn.™™™œŒ——‹-âÁ¡ øùù9DžëÛ·/Û·o ..Î^Þ±cGš7o@xx¸Ýòq¹çêÍ ++›ÐÐ`l6 ¹¹¹‘³³³ñññ¦¸¸ƒÁ € BmR@ óÉÉ)ï¤]¯^”ýwÓ¦/]IZ п¿ò)!9¹4"V5Q¿~}êׯ_®¼iÓ¦å(}}}í Õjµƒz ...åBQ Buãîîî Ïš5«Ü:wÜq‡J¨V­ZUX^Vñ(¡¬³º§§g…ÏÁ²Ï×›Iqq……Å89©ÉÌÌF¯/jf0ðööÆjµa0ÄgO¡6) nnÎDGG^{11pð œ= 9.Û¼Ú·—3(‚ \*•FC~~>ÉÉ)8;ëÑh4¨T*T*5NNN’””ŒN§ÅÉÉ©V&âA¸-kÁl.¦°ðBˆPWu!V|áEaCû÷¬¸\A*}ǘéܹS…Öh£ÑÈðáQÒ" HM"--O?ý”^½zÑ¡C‡J×Û´iëׯ祗^ªÉA¨Á ˆÙ\,gFA¨êÖ Ê'tvv¢e˦" Nbb"Ë–-câĉ¬^½š?þøƒö̈øý÷ß1 Lœ8‘3f0lØ0D€‚ È¥Y¶ìgŠ.òópqqE«Õ‘›+–¡æàïh!ÍÉÉÆh%Zj>>>¤§§9”kµ:ºu» _R áĉDDDàââBÿþý™4iR… ÈÊ•+™:u*!!!œ={Ö®€ìÚµ‹øøx‡õSRRزe F£Q„,€F£áᇾý›ÍFhhˆ]ñðòòB¯×²ÿ!{¹ ÔZ´hEAA™™YEÒY„Z†‹‹+111 ù¤¦¦a0äc³ÙðòRÂXƒM„t R._Whh(GŽáÈ‘#×]ÿÙ³gñóóÃÕÕµJÚ{ìØ1bbbªl*`||< 4¨2yÖäún§c­êúNž‹‡~ƒ¡Àa{•J…——jµüýý9>ggÍí3*åááILLt¹øô5‰¤¤óxyyÈ,B­¥Y³¦$''NVVyy¹Hòº[ˆ#GŽpúôi¦NJJJ ü1/¿ür¹õ¦M›Æ Aƒ¨S§ß}÷{öì¡uëÖ"@á–b÷îÝ;vŒÜÜÜK®7wî\Þxã Š‹‹ù裘4iRÍW@þýá7¼5n$Û_MLãæåÖÉÏ7‘‘Izzf¹eZ­777<=½°Z-äææ““J¥ºíÒ‹‹‹1òklûrssqqq–»Y„Z‹ÍfÃb1SXhÆË˃  `rr²D0·………¸¸(˜AAA¤¤¤T¸^rr2ÁÁÁ€â‹j0DxÂ-‡··7ƒæàÁƒ—\Ïd2¡ÕjÑjµäçWM_´ZÃðjT6ü¼yçãÙ<<ü îé;¦4œn«VÍ9vì8C† bݺôéÓÓQñðÄÇÇ—üü\Š‹‹äJAnÅÅÅ$$$ˆ A¸e©W¯ÞMÛwµ* Íêí™FËp3Ó?zhÏ4¢=Ó°XŠ/Œ>òÌ3£‰‰‰¶—%33ƒ„„c¤¦¦‘™™…Õ*¹@A„êÅb±˜˜La¡Œzßj„‡‡“’’BNN?ÿü3 °/ûè£Ø³gdùòåäääpúôibbbDxÂ-Gaa!999“““cïgŸ?Þ! aHHgΜaß¾}4oÞ¼Jö]­S°üý}1›¯ÏrQ2ÕJy!$‘––A` ÿmw‘¤¦¦‘p¢Æ¶Ïd2É,B­W}:Ï<ó >>>hµZÂÂJƒ½øâ‹LŸ>___}ôÑš¯€\/ݺu&:ÚqÔÁf³¡R©nË Åf«¹Q8”S¢’»Y„Z‹Jqqmže*89ÝXŸCƒ¡«U…Í& Pvvf•çbñôôäµ×^+W>lØ0‡ÿqqqÄÅÅÉ!ܲôïߟþýû—+ äùçŸw({î¹çªtß5ú馼A¡ú°¨liÊ[q],ZÔ¶;°¢R©0™LYâ_r\$¢ Üj\·R\¬„îjÖ¼V‹Q$*‚ Ô*Ì* ²Ÿlk¶½,5!•‡úàïá{ÃÚáì쌇‡;jµZNJÙóc6“˜x£Ñ"„„³³—k³_³b0`ÈwÌÛ‘—›/gCA¨UXUûc°–:çæššŽµÀ1ø‰«›+îî®ÕÒeîµd^¯ôÁÁÁe³fÍ"..ŽÙ³gÛË,X@\\Ÿ}ö™Ü‚p“1œJSQäv‡ý“\Æ´Ïçãêê~ƒD™Lúe©©idgç\Uçßjµ`µš>ûöí¿ ˆ®Üþ­V3û÷¼ì¶™™Yüë_oóÍ7 å"A¸‰TÉÜ)­V‹J¥"++‹ââb\\\زe Í›7çÀ—Ü6//mÛ¶ÊÈ<ÀŽ;Xºt)ݺu£wïÞ¬\¹’… 2sæLÜÜÜ8~ü8äìÙ³$%%ñÌ3ϰsçN:vìHPPŸþ9Ï<óL¥û-**"''ÇAÙ±c]»v¥GÌ™3‡„„LýúõùꫯHII¡Q£Füøã¤¦¦rüøq¼¼¼xòÉ'ÉÎÎæË/¿ N:Œ5Š}ûö±|ùr7n̈#ìû>tèûöícÈ!Ì™3‡cÇŽðàƒÀž={HJJâÌ™3<ûì³DDDT¨•dv cÔ¨QäææòÞ{ïq×]w1hÐ ûºƒÆóøãÛËÌf37ÆÅE BM@«w%áX<ÍZÅ‘›“Å”¿Hß÷¡Óé±XJÑž={žðð0 ÅÅF¼¼‹ú²³‘™™e—AB «¤=UbÙ±c¡¡¡ôéÓ‡´´4fÏžÍøñã¯h[___`·„|úé§c6›INN®t[OOOêÔ©ÀرcùôÓOíJÍå|EŠŠŠ®iêU e;êwÚ- [¶lÀËË‹ºuë:,ˆˆ@­V“ššŠ¿¿?-Z´ÀÏσÁÀ©S§ìÛöë×www{ãÆ+sSäàââ‚N§cñâÅäåå°gÏîºë® ÛýÚk¯‘““ÃØ±cÐëõL:• &ððÃË“Jj{ÞËÑc§ùâƒIØl6æ®Ü_ zÙmï¾» ýúõ`òä)´iÓ’ððÒ°Nááa´iÓbc[ð÷ßñö,ÜgΜ¥}ûØkj{@€©©iœ>}½^Ç‹/>ˇ˭çêêÂèÑÃ/( ßa0ššÎ³ÏŽ©>ñÄt:k×n$##«Âu“رC±úìÝ»ŸñãÇÊÅ'·– ‚Ñ)€:M»ÛKΜ<ÆÌ÷?eà½ý0›‹.¹urr _|ñ5£G§Y³&ö~ÞŸî$::òŠüÅŠ‹‹Ñ4Ç/´½lÛÆ_9¸uýúõÂj5W»Ôj fsa9¥i÷îÝÄÆ¶©d€ÆÄŒ³ À`(À×דḚ́a¡Óén¾ÒµkW,XÀ„ ðññaâĉlÙ²…Ÿþ™M›61aÂ}ôQš7o~Eõét:âããÑjK W¬XÁªU«HKKãßÿþ7¾¾¾å¶ëСŸ}ö†ÄÄÄJëoÖ¬6l &&†””Ôj5L˜0Á® ¸¹¹a0ìe±±±DEE1sæL~ÿýwœËd£š5kZ­FÃðáà dÍš5´lÙ___Z´ha¯ËÕÕ•×_˜˜Þ~ûm.\ÈÆyúé§iÖ¬™Ý‡æÞ{、œzõêÅ¿ÿýoúö틟Ÿ»wï¶+`Ê‹5‘wß}—„„5jD=ä9$µµZÃÛŸ,Àb±púøQƒ«/&lZZ:çÏ'¡V«™>3gÎ^Q=kÖlp˜6vµ¬Y³Á®ˆUÆ?þÂäÉIOÏdôèç–­]»G•A¸øò£É 9–ü¼^x¬7ÏŽ{£Ü:'NœbîÜEôíÛ“ØØ64lXŸŽÛ9¬·jÕzNÚ;óÇŽ'555k6âââÌ„ /–«;3=•/bô ÿf÷xõÉøõ÷}ëX,6mÚJ÷îžK–üÄ¡CJ@¡×_Ïß%00€  @²²²9~ü$mÛ¶â­·ÞÃjµÒ A=†}èše5þ÷;v‚îÝK³ï¿¿?ááa,X°˜S§ÎРAÌuÕ|pEö£ðÉÇÿÃh,ÂI[:ÿÖË+¬Æ„áݳg111xzz2a¦NZíûüâ‹/èÕ«QQQ·ÔšŸŸ†ÉT O,A¸ ð×ñ,ê7m À¶ ¿Ò¡[´jš,³lÙÏ„†AçÎرc7wÝÕÁá¶hÑRŽQüËÊ*³fÍ£¨¨ˆçž{«ÕÊ[o½@“& <ø~‡viµ.ìÝ»§œõøüùDúôééP6gÎN:ƒ³³ž‰_àý÷?!,,”øø&Ožè `ìÙ³Ÿˆˆpòó Ìž=ÿ K÷rV‹EÍáÃåγ²²éÒ¥£ýÿÿû!;Ʊ~ýfê×fذÁdffñÉ'3. XÅrÏ=Ý9z4… —àïïKÆõéÙ³[¶üÉÚµ‰ŽŽ I“F†œµ˜4defðÂKã¹»Gï+:¯IIIüsÂ8Ô5j«µö…:·ÙlìÚµ—;ïl-7j ÃÉIÅ"ax+ºf§üoÿïÂ#cÈÏË¥sÏüó?ÓˆñJu°€Lž<Åþ|,û|Z²ä'5ªo·€¼óμúê hµZV¯^Ïìä7&Ã7ß,à…JýSRRyçýY|ûõ :të˶ ¿ðöÇóüð`‚œSì£ÑÈL£ÿÞDFÖåç—š}öÅŸ%<<Œ]»ö²bÅ*ú÷ïu} óõ6Îd*ªðÁ3Ðh`„—Ë´­úGð;vŒ½aûº±H^½‘ IDAT#2‚"7 •J…F£º¦EÕüd@¯¿¶œíÛÇ„Åb!,,ôºds%™žŸzêq‡i¼W^?<öØ#dddâææFHHÐ —²»»»Ý/gÑ¢eÀ4nÜFÄŠ«èÚµ!!A¼þú+€2*Z‘òûïÛˆŒ¬‹¯¯'OžfïÞyöÙ!øøxóÝwËHJJ!.® 6l¦M›–h4û¼ööíciԨܔB­§}×Þ¼õñ·,þæSZÇu©p€?~ùe5‰‰ÉŒó§Naß¾ƒ¤§gŒŸŸ/‡ýMBÂI~ûm-÷Ü£ø–,^ü#ÙÙ9F¢££*è£jüøóXm6Μ8Š›‡'`-7¢V«qsscÍš „„‘››‡››+Mš4äüù$NŸV¦°vèǯ¿®¡sçöÁÔjÔ«wm3süü|غu;¿ü²š'NÛË7lØŒ¿¿/©©é<øà½×}>®[)(È«ZA¸,QQ7l_¾¾>W½M޶2!Ô“‡™<”PÁ¦\#M]nÌTÛ¹sÒ¾},&“ù’Éa¯4zŽþþ~øûû;}ñññvX§M›V|ñÅ×ÄÇ'ðÈ#¥Ö2£ÑHNN®Ýj%µ‘:þZ¢¼r‰Ô…{ÚEbA¥ÊÃfsT†b|צMK\\œ¹÷Þ>öA ww7žyf”]ièÓ§'ÞÞ^899Ù-º%hµZêúXô5ðúø1$'ž!Ø''µ ¬¥MNNN<öØ‚‚‚ÈÉÉA¯×ãææÊ=÷t'##“;îhnŸÛ¢ES||¼íÁEzè>vî܃ÍfÃÓ³üÌ›ÍÊž=ûËiºø9Ò¸qCÔj 999´jÕ«ÕŠV«åÔ©3tìØww÷ë>'NrY ‚ bäOÓÎ —ßsަÿqCÚÑ´ic~ùe Z­“}ºY@€wÞÙ½^O@€ß…ŽƒÁå¬OŸŠƒŒÜsOwæÏÿ£ÑDhh0±±mìÛxzz ×ëpww£cÇ8N:CHHiòÚƒÿbþüï™1ãÿäj%*•Š& ë‚U‰„âiÿ}ñ\OOr¡‚‚ t(‹Œ¬Kddi„S777\]]hժťDJÚìÖ,lÖ‹³*AhhH¹A”zõ¢*´h”l\Ò7Ël.®´}SÑ´ÚÀÀ€*=/¢€‚ B ¢G®ôèÑÕ¡ì¹çžpø’’JãÆ yæ™Ñ—¬+""œ×^Wi]eƒ´o[Îé¿sçö)‚ TLÇŽq"„êV@LF#»÷É ‚ ·® ½À»’wŸÉÄöí{íÿ›5m~SÛêáá~ÍyZ®—’„fBÍB­vÂb1‹ „[SÑéôtêØI$'‚ ÜRœ×¤Bqeï>û¯¨°˜BCþÍS–\]iÙòÆ+A*•ŠÖ­›I˜vAn¬bÆÉlÉ ‚ ·VUå£Ç6ÛÅï>L„ZÃÊ•«ü¿®­VO«VÍnœR–³çSk`˜HAA¸Ê—©“ªðÊ_‰F£‘ 6Ó°aBCƒD`‚ Ô*üÊ9Øüýw<+¡¶“’Rؽ{/±±m ô¿Œâz]–ÐëS@óiظ©œUA¡V“•™‚—ò¶ec0P«Õ¨T*ôz Â=ß…ˆ¦áDDDÉô£Jؾ}7çοä:žž^äççÙC‰ 7µZ‡‡g•Õg0äc6‹ÿÉÕâááIA‹¥òÜkÁÁAÕæäþ×_Gx饲jÕ¤¤¤²fÍš4iÈo¿­¥OŸöD§ÕÁu) Î..Ê$‚ ÔjLÆT*žë8’ýû¡×ëñòò"88‚‚Ž?)Bº ¹¹¹øùù–+W’G:@FFjµ F-»‰ètzš4iFQÑõO©OOÏ 1Ñ‚N§Á^%Í›·$''ƒœœ¼J•¸† W›òqèÐß´o¯(7¿ý¶–.]:«« 6lfðàû«O –Ó/‚ åñööF¥77× –ÚÙlfÑ¢¥—\Çjµ±|ù/Lž<…ÔÔ4E93™˜3gS§þ…ñÑGÓ™9sF£±ÂºT*5®®®„……ŠJe###MFÊkŠÒm*¦°ÐpÝŸ¬¬LŠŠ E ×€ÅbF¥__/BBBðññE£©Ü¿Ì`(à?ÿyŸ Ûï£ï¿ÿ]»ö^Õ~?Éúõ›éÚµäçßxßî*U@*3©ž=sš¿,Wn³Ù.éCb³ÙXõëÊk8¡–Kš³®å¡]•¾.f³ù†šŸWÿöËﯢsrñ¶ý¿XF%eW"‹²çª¸¨ˆë×ÊSI„›Š««ÎÎ¥#º‘‘äääÞ}Ûl6Ìf³Ã»¢ìs·lYÉzeÛ‹µÜsÚf³ñÝwËX¹rÕ%÷½bůԩÆäÉY¼øGÒÓ3˜?1]»vâùçŸfÚ´|ñÅ׌5œþý{1g΂rõ¸»»JHH “É(• \¢ÿ¬Vƒ§§uêÔÁÏÏ•JUn½iÓf0~üXôz=G&`³Ùxà™×­V«ýRYßÕÕÕµZÅ’%?qôè1ú•JõBVv«ÕfÏð^]Ti"Ÿ–-!ª^=Z¶rtrùjÆg¼ùÎÔrë=ószöîG݈ˆ ëûcëækjÇ×3?góï™»pÉUoûûÆõtîÚÝ¡ìÿ>˜Â¨'žÁ×ïú£¬]õlÛŒ““–ç_[¤³¿wuîÊ{ï¾ÍÄ×߸캓&¾BŸ÷Ò±Sg{Ùàûû3cÖ\üüý9î,ƽÀ·ß-³/ÿä£÷ÉËÍ¥~ƒ† öùùùLûèÌfí;ÞE{zW¸¯½»w±òçQ«Õ 9šðºèÙ¼i:wÅÉIòd ‚psðöörèèõ:<==nȾ.\‰§%ü﫯¾À'ŸÌ`äÈ¡äçøí·µ Л矟@óæM¸ãŽæ  Ö­YÅ?'½iÿ¿ß^öìÚÀ€àÀïÖsüø1†““O<óÎ;ëP×ÜÙ_a±X¨^—ž½ú—›Ë’ïЬùÜ׎–|ϼ9³8žpŒN»R¿ACî߇ŸNÚRQmÞ´„cñ<:âqΟ;G^^.»vlÇÍÍÁ «ô˜6ÿ¾7ߙʦ ë°X-ìÚ±ˆÈ(V,ÿŽ:Ó QcØÏÎÐoÀ@ôzg–-ù޶±qìÚ±aÃG¢ÓëY±üÒRSquuåá¡Ê…òí7_c2™ £Wßþ€â«6ŠŠ qvv©´m_ÍøŒÈèhûÿââb¦ü!±qí8súÖ­!""Ò¾Îô?dè£# bãúµlX·†m[6óÊ?ÿ…N§çËÏ?åÜÙ³Ô /·¿å?,eÒ[ï`µZùïÛo0éÍwxõŸ“xïÝ·yíßoÊsH„›Brr*;vœvìXm4jTýW¶lùÓ­fÅŠßxöÙ1Ì™3gFŽJFF&íÛßÉ‹/> ÀäÉSì È'ŸL)7#::²ÚÛ­(l*T*+âc.ׇÅb"%%?À“_~YͦM[ÈÏ7ðê«/àééAHH0ÿøÇ“¬_ÿ»}»€?7nÀw4·??.Åĉ/Ùý………¸ººTûñU©¢V«xß þûŸ7iÒ´:“ÙŒ‹KùY´à[&ükÒ%ë3›ÍöQp³ÙÌŠŸ–1ì±ÇøsÛ4jÌ©“'èvwO¦}ô/½2±\=Ÿ}ò={÷E«Õ²{çvíÜÎÆukyðáG8t`?C>±íÚ³iÃ:ºÝÝÿêFD²fÕ¯¤§¦âééÅñ„xŽÅÛ÷ùéÿ}HTt=ìÛËc£ÆžžÆÂoçÒºM[ŽùËÞ†:súäIâòÓK0ðÔj5‰‰çX±üGFŽ~‚oç|Íëoþ‡ðˆÜ=”‘¶Ù_Íàþ&7'‡e‹¿gĨ1|úñ‡ÜѪ5:žnw÷$+3ƒùsgSPP@§»ºàâêJâùó?O½ú ì£x—šE6kÆgÜÓ»Gþ:€!?ŸoçÎfô“ÏðÍ×_àÀ¡Ãy÷íRKJ±±½^¯\LNNb4£ÓéíׄÍVñ›Èj³¢V«Q«Õ£dzggŠ‹‹äé#ÂMÃj5QA»úñòò¤kW%éaÉwRR2îîn˜Lf22²8~üT…Ûÿõ×Q|}}ʵ¿26lØL‹Mñóó¥~ýhŽ;AýúÑäçpww'88ääT||¼í¾0nn® áïï{ác#33ääD|}}ðññF§ÓÉÅ$WIzz©©ièõθ¸8зï=8p˜_|ggçKn¯×+Ëû÷ï}Ù}9;ëí¿µZ'´Úcé­ò9.ÇâV[yÕóçÎað¡hµWþ`Òh4Ô‹©Ï쯔ù§÷ôî‹ÑXÌ/+~²[@Âê„W¸mVVß|ý%†œœl4jD^^.‘QÊhÉ·››;^ÞÞöÿ^ÞÞveÀh4áââb_';[y ¸ÿ"£¢ÑêtìÙ¹O//ÂÃë–ž`½3~~~xxz^×þ"svv¡g¯ÞDFEóøO)#^?ý@üÑ#€bu(éügffMNN6+–ÿ@pH(&“‰¸öèÞ³_}1³ÙŒ¯¯sÅòÝþçœ9sš“'Ž]/†¨¨hìÛKâùsìÞ¹ƒÀ  † {Lž ‚ ÕÌÀ}í~÷ÜÓÈȺlÛ¶ƒAƒîÅd2±jÕz:uj‡»»“'Oࡇ:(5pP@Ž?ɼyßqþ|"“'O¡{÷ÎtîÜ€¥K—àŸŸ/C† bÑ¢¥ÌŸÿ=Æ=DHH>ú0ß~ûYYÙŒ¥XÛ|Ÿ}öÎÎÎŒ1¤´Sáä„““ùùrsóððpÇÛÛë²&AA+¹¹y$%%£Ñ8áææVnºuÃ|3“øâ‹¯ÉËË£^½(:wî@``À ±`Ô($þÈßìܱa´—µjÓ–…ó¾¡S箤¦$“EƒF—+Ö¦m,»wí MÛXl6*•Їy€_WþÌÀ¤WŸ~Äý{wUy.pü?[öÉž=$„5Ùwˆ,² ‚èur-¥HÛÜBE¨R´W‹¹²¸QQ %öPd‡ȾL2“d23÷Ãà‘@PZ¶0<¿OäÌœ9ç}Ιá<ç¼ïûtI E¼ýÑøÙ3§)**äÔÉ4#0° »tE«Õâ¡×Ù”¯¿Ü¦ Œ?~üýÆÝݽޓcG³8zôŽ@QQ!yy¹œ:u’àPœ©ª¬TÖ hxâàP‚CBë-Ó{zÒ$(˜v:5¸Î ÔÙÓ§3n"/æòÁê÷”×›4 ª÷YCSGÝ ­NKl\K¾Ûñ5ÉN«ã‡cÿâÔ‰ãtJîJMM  ÂùgîD½ý·Õ|ùÅg¸ëõ„„†±âíwxcé«ôí?CE9²)**äØÑ,š3bä>ýx IíÚsæÔ)OÅÏÏŸ-m 6®¶«btîì§ÿ–¿¬\@óØ8öe¬Œ”n=”}Y·fã&N–_#!Ä)9¹#ÉÉë-7n$ÎÎÎŒ9Œüü""˜5kÚuëÏžýÌuËbb¢xå•ÿnp{þó«õnöM˜ðh½×=<Ü™9sj½eþþ~Ì™óì/.®ô^0MTUqqqÁÏÏG®ר««Ã`¨¤¨¨«Õ†››Û ß;~ü¨z‡„ó‡?ÔßÛ«W÷û¢Ý·51U›ê%ö©bšÇrìhñ­É¿|™§žyþ¦>¯KJ7>ÿt+í;tB­V“Ø&‰¬Ã‡ìw_¦ÏÀ××¢ÂB²Ž ¶EKÔj5§Ož {^œøáÍcã˜>ëi6¬ÿ«ÅJpH‘MybæS|öñV{âÒ2wwû`ð)ÓžäëíÛè”܀‚¢¢›QVZŠÑh$:¦…Ê6g<ý,—/å)ƒÉ}||éÙ§ß Û4bô˜z'¶nsÝ`ëGÇMàÐÁ„†…ñüì4‚‚CèúPw¢¢c”ÏhÓ¶_}ùw²ŽÆÕՕظ–ôèÙ›MÖc6›iD§dûÝ­o¾ú’¡ÃAý3S»)ûÓ¦-Zmý¹¼û Œ‡^¯Äº{^d9ŒF£!®e¼2–ehê#øúùãï€J­"ëÈa¦L{RiŸ·ƒ‡¥*Ÿ;qòT>Ù² /ooz÷íØgÁ*).&6®…ü* !Ä xyyÒ»wF·_?v¿½–Íf£  ˆÂÂbÂÃäkÖ=?NNäå]æÜ¹³·üYF£??ß{qcö'X­V<<îút»f£rqqC§s»mû®Vkni}Õ’%Knj~Ù#GŽðÆë¯Q[[VgŸ6õÀÑKtè”,gBˆûZ^îy‚|í]c,DxmWb•JE\\óiÂÂ#ØñÕv¾Ýñ^^^<óÂlrsrø`µ½¬F£aÔ£ã(ÈÏgÇ7Û¸˜›Ã”i3x¨»ýqùþ̽|þéÇÌ_ø{Ö¾ÿ'Oü@pp3ÿë9eŸÒΧßÀÁt”§LBqWùúúã䤻f©J#„)ùáØQŠ‹ŠX˜¾˜ò²2^_úG^œóòuï{cé«Lœ<?¶nÚÈý™œ>y‚ACSIh•Èâô…´JlÍÚ÷ÿÆKióP«Õ,N_Èÿz•••JAÃóÒH1Zùû/~á#FóÏß‘:r4CnnîtìÜ…¯/eì„I6á“­›Ù·7wRGŽæü¹³4o‡»»¯¿ö*/¥ýJ™¾Ìf³±eÓæ/LWúàäçsì_Y,L_ÌÞ=»ùò‹Ï1›Í :œ¤v¸x1—϶næÉ§žááÞ}È͹Àޝ·Ó¡SgìËäbnŽRVç¤caúbª*+Y±|™§5k^ï‰õ6VtBqsQ«ëÿþ>ü/$8BÑXÚÚZeP™—·7åee ¾¯¬¬oûLÎÎÎÔT×ÐwÀ ÞZþ'>\·†~áêæFMÍOõ%Ìf3*•FÍw;¾¡ à2y¹¹?m»¦†ÒÒRšÄÞŒ]ôé7’’b¶nÚHYYÞÞÞ¸¸¸P]]··çÏ%**†íÛ¾ ,<‚¼‹¹¬xcåee´n“ĈÑcÈ>ŽÿYøÌufz÷íO÷‡{Ó<–óÒpuuåŹ¿"sÏnN8AEy{vïR¶ð¿+ÞÀÝCOµÉı£Yä\ÈføˆQì¿RPñѱ¨¨¨`Ó†ÿcÚôYöäcÕ»tîšÂé“'ä Bˆ{Àf³]WèºÚ$BˆÆ”€ÜŠ?XÔi3 eÉ¢ßÓ¦m»ëÞ£Ñh?i gNŸ¢eËŽ^™… `Ýš÷3~"jµšî÷¤ûÃ={ íÿ¢Ám^]°ðßK]›ÍÆÔé3ñööaÁ¼4FŒƒÕj%í× Ðét,˜—FTt s.°0}1çÏeíûãñ'f¹'ƒŠŠrúôÀ¾+UÌ~·h ß|õ%‡àŸ;¿§ººšû3Ùùýw ÀÆæëV«Å‚Z­!$4 cUƪ*eêØ¨è ò{Ñ@//oê,ò.ær4ë0‰­Ûöb†fs-ß»ƒ^}ûóí×_ݬٕ‚LƒxyþB%& 楡×ëY²(¾ýb6›¹|) àÖ¬ßÀŸ~Œ¯ŸŸœÍBá`LÆ:ŒF³BáX¿m¦º»›€øøø2nâdÖ®~Ž:“Ô¾ƒòZ\‹–øøøЪu¬V+ŸlÝÌ£ã&ØëfôîËw;¾æ“­›ù¯ç_àÑqÙòÑjkk™4Å^héôÉãìÝ“AtL3  Øç²îÓï§)[·å£×±{×Nôz=ã'M±'6û6G¯Ÿ)õ`ÝÚ÷èÜ¥+¾~~Lœü8ŸlÝlßþØ ¨T*†¥ŽT–M{r&ž^^Lš2Õï­¤]ûŽÊ4Äÿøn……ôîÛŸfÍciÖ<–•o¿E]]aá$w­ÿcÐaD6"c÷.ÀÞ%mÊ´'•÷Ä'$â,Õc…Âá4 òÁjõ@!ÊÓðþ©"„âwmprrÎ×OÞeyä©"„¿€H!„âßT\\€‡‡{½eqqÍ$0BqH"„B4àÚZV*•ÔBˆÛA-!B!„BH"„B!„p8ÒK!„¸Fhh$NNºzËjkkïʶM¦j,‹CÇ×Í͵Zî ! ˆB!°Xjqvvª·,77__Ÿ;¾í½{÷à°±U«5DEEâì, ˆ’€!„€òòr<=ÝQ«íÏkkk1*ïʶ]]]IHh‰Vãxu ¬Ö:TjVkVký§<¥¥eŽw‘¥Õ¢×7\異ÂàpOºT*ÞÞ^ ¾¦Ñ8¡V9Þe§¹ÎØH´uhÔ:‡ko¥›íÖÏ[I@„Bˆk˜LFª«kqssàìÙóxzêïæ¥®®.h´V‡Šëö/w“Ü¥Sƒ¯99é v¨öîÞI||Ü _oÚ4¡ڻwïþŸM@ÜÝë²sÿ¾#‡âêêÒ@¢ÅÝà Gš?ŸmVl6ÛÓ^›ÍvÛÚ{K ˆÙ\‹¡¢BÎ@!„÷µº:3P?Á0™Œ”—ÈÎ>Ãn4B!îrÒ¼©¶Ú‰¢Bˆûš¯þ§;Ñnn®„…E¢Ó9QWWG\\<:½/·Ívt‰²Z­¬Y³žnݺyÓë™L&^ye11Q<ùä”{¶ÿï¼³ŠéÓ'+ÿ~â‰Ç~±äÕë\­°°ˆ7ß\É€}èܹ½²ÿ|;ë×obùò?Þåny?ùõ¯Ùl uëVL˜0ú–>¯¤¤ÜÜ\ïù¹[PPÈ[o­Äh4áããÍŒããã}ÓëùåÜÝ]IIIvˆß¦«ÏëU«Ö1nÜÈŸÆnÛö5ëÖmdÙ²?ü[ñº/_¹#$„±4oóãe«üûÌ™sÊ~FÌæ:pss¥¤¤”Š z½‡²N~~&S5*•ŠÈÈp6lØÂ”)ãyóÍ¿* H~~6l¦ÿ>¬[·‘±cGQUU…Ù\‡ÑhÄÇÇ//Ï+Û4a6› ôÇÍÍAƒúrôè1%¨®®ÁjµâææªÄêN3›Í,^¼€´´L˜0ƒ¡’ââ€ëâ‚V«½.>Ö®ýèè(’’ZtOÏß?ÜÌÔ©“¥´´L9ç.\ÈÀÃÿ×ݾ}jµŠââRvíÊ 9¹•••Ê9ûãñÉÏ/Äd2¡RAddC%®®.hµÚ»v ÿ“ï¹sç±X¬TUUQXX @@€?îînôïß›cÇŽSScŸ.¼¦¦†êêer‡Æ6Þè?N@¬V«ÃÏS.„âÁ¡Ñh¢Oþ¥K—)--%!¡ -HK[@¯^=øàƒINîˆÕj%::ŠãÇOrùr>M›F`4šèÝ»mÛ&^÷y‹-cñâ…”””}¹»b ÒIDAT²jÕ:fÏ~æž´käÈI¤¦A§ÓRSSôi±bÅ;øûû)ß'OžaË–OÑë=°ÙlDD„ѽ{ K—® %¥3V««ÕÊÒ¥+” øýûrüøI/^FRRÜÝÝÈÏ/à7¿IcôèÉ 6N‡ÉTÍ‹/>}Ý~ef ¼¼œ!C(±ºÓ²³s˜3g>‹…À@û”ÍË—¿×•‹ÏZ¦N¨ÄÀÇLJvíZ³eËgWÅ'œ¦MÃ9t(‹K—ò1™LŒ5¼Ñ$ÒZ­–àà&lܸUI®ÊÊʙΞ=ß`ÒXtìØŽgŸ¡\\šL&ÜÜܘ5kš²,/ñ Ø—ššÒÓ_#00_L¦jÖ¬YOûöIÔÖš™??€£G‘˜˜@XX¨’\Í›÷;¬V+íÛ·åÙgg*ŸßXDF†3wîs¬\¹š¹sŸà›o¾£Ë•Ʋ²Ž1}úcX,Vòò.0vìH:¡CYÄÄDQWWG~~!C†ô§oßžÄÅ5')©u£iã… 9,Yò?Üýû)IÁêÕÿGIIiƒ ȇ•ãzüøIeùÒ¥+˜1ãqåïââRòò.c±X¸t)ÿž?õù9!!AJÛ_yåìØñ=:´»’hn07n”’t¤¥-pŒ "" FƒNç„··ýqåž=™$$$ ×»_}Þ·nÝ ­VÃС”c=qâ£$&&°mÛל>}Ž%K–3gŽý‰HHH·yóf7ªv©–,YrS©Â‘#Gxãõר­­F«³pðàÂÂÂñõõ¬—AïÙ³„„D<<\ø¥ù¯…Bˆ»¥¢ÂÀÑ£?УGÌf“²¼¶ÖÌÉ“ghÛ¶ÍM?±˜5”–óÜ ³éÝgÀM­séÒ%^N{ µFZcÁj57ø¾½{÷Ó¹s'ôz/4šÛ3ëÖ¶mß Óiê=Y¶ìMÆIPP“Ÿ]wíÚ øúzc2Uc³Ù9rؾßA×”ä+¡WU ¹gçGZÚ‚ëúþ7´ìZçÎe³kW~~¾ìÞ½—ßþvžòÚ®]ÄÇ·¸áùîPß±ŒŒLââNœœ<m!ÂŒŒL.]ÊÇÅÅ™¬¬cJ·¶_’™yˆ& Φպâáá|Ï þئÛùäüù †JÂÂn\0Ô`0p!;Ÿ¸Ø8æÌy‘¦Ññèõ×˸¥3áòåKàï—NNŽWr^!„cª®®¹2KPîînÝÖŽ“®›Ævôèá7ÕµhÈþPçÛ½ïro²ÏZÚ&%<8¿' ­bå‡õ¶% 6°ZT9!„¬;9Ócpp0:›ƒÇÏ,'‘’€ü{¬µDN!„¸ÂÃC0›!„$ ÙÙçøóK¥¸ BX-***%Bq§ví:—_.B!®èØ)Y‚ „w* •h !„B!n‰ æB!„BH"„B!„p¸ºº U>((ŽŽŽ€ªª*2 !›oèÖõdë÷f¹7%A('NÄĉ…._TT„Î;£¬¬ ÙÙÙ077'#ÒïñA$¼A$¼ÑZ±³³C¯^½0fÌøúú’A^‚6:uBçÎáàà€°°02AÂKAÂKAð„¤pvvÆõë×É„ÄP•ÆA ‘žžÜÿ„¢¢¤¤D¡ùÞ¬¬,îšøøøx²2A„´…×ÖÖ¶¶¶‹…˜˜²4AÄ¿— š`РA&C$¼!+ôõõÁf³É /AÈ’>}úàÅ‹d‚„— dÅ´iÓàããC† Hx BVèèè@MM ………d ¢Ù¨’ ˆOž<üÒTiiiAUU%%%Ð××'Ã$¼!.æææ<&ôõõù&m%^‚ àÙöðáCdddq©A>^‚’=z ::š Aȧð²ÙlÄÅÅ!..YYYde¢U@ÁrI!WCzz:üüüQQQde‚ i o=УG€——âââÈÒAÿB>^‚ ^‚ ^‚ þÅÌÌŒ‚û$¼!Kú÷ïÐÐP2AÂKAÂÛ ’““1oÞ<¡ËSïƒ%&&&8pà‚h] ôÜßÜÜ\œ>}šZ‘½zõBÏž=ÉDë^Qعs':v숔”jI‚ HxÅ%??íÛ·ºüçŸwwwží)))ðõõmöõ\ºt GŽ¡;¥äÞ!9Þââb$&&"11ÙÙÙ"ÕMHH€•••Ðåa``€«W¯6Øîâₘ˜\¼xQäk¨Ouu5Nžc/^Œ1cÆàîÝ»–MKKƒ±±1ÔÔÔ ¢¢wwwÌ;gΜÁ¥K— ¦¦Ö ‡rìØ1ܸqsçÎŽ{÷PTTÔ*ÐØØRïÑâСC˜2e =5ÑZ„7++ FFFPQQ«~·nݰjÕ*üñÇ077çÙ߯_?¬[·[¶lÁßÿiÓ¦¡ººZáPKK Ë—/ǬY³šüJh'OžÄÚµkvvvˆ‰‰ù¤œ€Íf“‚b!7©rssa``eeñßß}÷]“eììì°ÿ~|óÍ7xöì†Úd+VÀÃÃ+V¬ËF6l¾ýö[øøø`Æ R9‡ºº:FŽÉ}ɵ·ÍÆy2‡‡‡ÃÐаÑzÁÁÁ(..FÛ¶mIEÅ^Q¹ví,X V]¬Y³û÷ïJx544PVV&w6À°aÃcÆŒ››Øl¶ÄÅÀËË ®®® Ü7­…}ûöñlÛµk‚‚‚HˆÖïjÆàÁƒ….Ÿ––Æ×¥ Šk¢K—.MúFß¼yƒÎ;Ëeãegg£C‡€:`ôèÑðôô”øy’’’еkWzZþE[[›;xK -¼u3d‰0!þš+ðõ“››+Õß³|ùr°Ùl‰úËËË¡ªª Û×®]‹ÿþ÷¿ŸäCÃb±àèèHêA(¾ð¶_~ù%þùçŸ&Ë™››#77•••bŸ+00PêRÊÊÊ` ÃH옹¹¹ÐÐЀ®®nƒíZZZ¨¨¨ødï¹sçâüùó¤ „â oXXúõë'óÞ±‰‰ ,--ñäÉ“&?-+++QSSÓj>:: b×oÛ¶-ª««åÒ÷- :wîŒ7oÞ‚Š+¼‘‘‘°··º|TT”Ä"D988à·ß~“‰¨†‡‡ËMÃÇÅÅ5K8Ú´i‡CK‡ B^„·´´)))HIIA^^žÈõÕÔÔP]]-ÑOfA|öÙg`³Ùxÿþ½Ô_.ÁÁÁ=æ‹/лwoº‹ ‚„÷Ã(ø_ý…¿þú Ïž=k²üÇX666HNN–Émmm|öÙgR?OAAÚµk'ñcˆU711ñ“_A­Jx{õê…M›6aÓ¦M?~|“å322`jjÚbFصk~øáží?üðvîÜ °··Gdd¤Ü7è?þˆ;v4YîÍ›7ˆ‹‹k²\||<¬­­ùîÛ¼y3öìÙCOAȃðJ»'øêÕ+ØÚÚJ´×Ëo¨¬¬ :::€… â?þûÕÖÖ–¨ßÕÇÇÓ¦Mã»Åb‘— Qx·nÝ*T­>ÒX%Ï\»vîT‚ á%D!::=zô€•••ÈS¸¢££qìØ1‰†!Œ‰‰DŽÕ¡C‡fš'^ °°úúú?®†††Ôf6üñÇX¸p!&Mš„7nˆ$ׯ_ÇâÅ‹y›Óë?{ö,æÏŸ/‘ßÖ§O™»—G† B1ÅÞwïÞÁÐÐP¤P[·nÅöíÛ%~- @HHˆÜ4LTT,X€‘#GBU•7–ÑÞ½{±iÓ&¾u»t邤¤$º»¥Lc½ýëׯ“ùÞœœ´oß¾Y¡ eÉàÁƒ%>WË–-ÃÑ£GE TGc«ªÊËË¡¦¦&T¤±Û·o79+ÅÄÄ™™™!KªGÞR\»v ¯^½"…!Z‡«¡%©[Ø!m¼¼¼päÈ 2À‡„ž’Êq– ‹]]]Ìœ9—.]Xöýû÷<Áq>fРABÍÕ…‰­Ll)Š‹‹qîÜ98pà“ŽiAÈ¡ð>{ö lÕÎÏχ®®n“VŸ¸¸8ØØØ4èUfeeIüÚ$å’6l$zm=zôPèvg±XPWWGtt4îܹCJCÈð>þ|÷íÙ³›7oæéEèèèÈÄ5QRR‹%v*¢ú«££uuu¡Ê—••A]]ÇP?¨ 2-ÅСCHOÓ¿äääÀÂÂvvvøê«¯È „t…7'' þû8­Jåååf«ÕÕÕEIIIƒmoß¾…©©©L'==††† zªÃ‡‡¿¿¿ØÇTUUEMMM£1(²²² §§Çc›©S§âÊ•+>ø@uuu¡­­-ò5\¾|3f̨­TTTÀ0 jkk%r¼ÐÐPôïß_&À»wïxîÙâââfsÉ’%èÓ§¦OŸ'''¹ ŽDÈMýsóæMddd4Ø&覻páfÍš%7†°··Ç£GðÅ_,cjjÚ¬$KKKäää ¤¤mÚ´‘Úo±³³ƒŸŸ¾üòKž}IIIèÒ¥‹DÏgjjŠÊÊJäçç7™«Lظ‘‘‘LÚýÂ… †Íf#99}ûöåÙ'é¼iݺuÃëׯ….obb‚ššäää(üŒ†¦ÀíÛ·IuÅ™ÇûâÅ ôéÓG.®ÅÖÖ¶ÅBþ Åb¡ººÕÕÕøöÛoagg---¡ÎQQQ¡ãKÔ§cÇŽ¨ªªj°Z+;;:t § ¤)¼ÈÎÎFvv6ŠŠŠxö +òJ}_pc;¸–••…¶mÛ6»¢þç­0Ó­ŒQZZм¼<èé鉟!''šššb-kæ·!88¸Ñ¸ÂsæÌÁš5k0`Àz"‰O©8[ccc¹ #""ìûý÷ßáéé)—Æhß¾=ŠŠŠ$s×ÏÏ™™™hß¾}“eKKK¡¡¡!´ûE”e¼7oÞÄ„ äú&´±±¶¶6Œé‰$¨Ç+.}ûöÅŽ;°cÇLž÷ßMÍf¨Ï„ 0tèP¡¯ãñãÇþ‘ëÖ­ÃÏ?ÿÌýwnnn“Ás–.]*³À8-EPPP£í“““Q^^NªDÂ+?ÄÆÆ¢{÷îrs=vvvˆ‰‰á»/33úúúèØ±#ßýöööˆŒŒäþ[˜u°X,¡Wvéèè`É’% âÃÿþ÷?LŸ>]lÛèéé5p15w¹ŽAƒÉ,dKabbÒ謆K—.aÛ¶m8pà€Pq/r5EDDD«™™``` 0ÜßÅ‹¡©©ÙâÓæ~øá±êIbvA]v‹–š7¬¨DDD@OOìF=^ÉŽ~ýú ]~ÆŒ¸|ù²B4++ puuªü70iÒ¤½æú9Ý|}}1vìØf³nZ™ …­I¼°Æ‡‰'BOO©©©¤P$¼ÍGÔÅÚÚÚ(++“¹Q0lذ&ÅêñãÇ<Ûýýý1|øpèêê u®¢¢¢_bª©©Éýn*3ˆ°ÔÅa´p£5òçŸbÁ‚Í:ÆàÁƒ1jÔ((++ƒÃáB‘ð6Ÿ°°0‘z¼-EZZÌÍÍ-cnnÎ7Ì_jj*ßo‚ i°LÚ$'' =Ð×ÒJÐÙZ¹rå Þ¿nݺÁÔÔ” BÂÛòüôÓOgHš­[·bÇŽbÕGBB‚D„«¥HLL”˜k@__êêê000 '­ þúë/TVVr#³uîÜÞÞÞ´Ò­•"³ÑŸÒÒR±C: ]»v2¹N}}} :?fâĉ¸yó&&Nœˆ×¯_cöìÙ"¥9’‡0—õ‘”›¡Žÿû¿ÿÃ… š©Yšlܸ‘§½ÃÃÃ…ÎÇb±$n7àCÌ‹.]ºH5~2ÑÊ…7''_~ùe«Knee…Û·o#&& .ıcÇ„rØÚÚâñãǸsç¶mÛÖâ¿ÃÚÚ<ÀÇÅž ÁSSS|÷Ýwr݆üÒ‰’smóæÍؽ{7vïÞ-TùáÇãáÇ>|x“e%1ÈI|®†¬¬¬¯[ñññÀµkׄöÕ~<·¥éÑ£ž?UUU¨©©ÑS!EF¿ÿþ»Á¶üü|¾îI->">á}ÿþ=òóó‘ŸŸÒÒRXXX`êÔ© ca—直¨@II ®®®"ˆÔÅg—¸ÙÙÙÐÒÒ’jÚy‚?ááápttäIòioo—/_Òj6r5GTT7íLdd$ôôôÄNC“››‹ž={ÊÔO8cÆŒFƒºÔѵkWœTûy¼­õ .o¿‹zJ-GcËÆÕÕÕ¡®®Þè ÎáÇ£¢¢C† ˜Ï á kkkJM|²4åöº}û6~ùå”——cĈr5[†P`áUWW§‘vBî©®®–Ê@iSn¯²²2qgD0 ƒŠŠ j^‚hýJJJPRRj T\ø ÊÉÓE‚„— ä‚víÚAGGG"AÎãââ`ccÓ`Û矋6›ÝhÝÐÐP\¼x‘„„— ~¸ººâÔ©SB•ÕÔÔ„¶¶v“‹aàé鉰°0Z×Z„·ªª ÅÅÅ(..¦V¢UÓ¦MhhhÌ¿' ø…*e Ã@Y™ÿ#\XXØd¶ì!C†`éÒ¥àp8´^ÆHeåZDD7WZTTY™hµÔT*++“iÀ£¢¢" º?uêT\¹r³fÍâÛ1*//G¯^½Ð£Gddd ¤¤&&&Ô Š,¼ À€4?VA¢annÞho·²²%%%˜0a8|}}…¶mÛÂÈȈ ¨¨®‚ „CÜ,Óïß¿‡††ß}³gÏ*L©––tuu1sæLlÞ¼™â<ðħÁ«W¯ÄJïӜ܀ÍÁÏÏM^] ¡(47çš¼Ò¶m[$$$ðÝ·ÿ~|ÿý÷ ¶=z HJJB—.]øÖ Á‚ ‚¼¼<ôîÝ›n ^‚ææ\“Wúöí OOOží555(((ày±899áÏ?ÿDJJ ~þùg¾Ç¬¨¨À¤I“àìì '''”••áóÏ?§›ˆ\ Ñ2$&&ÂÊÊJî¯óÑ£Gpttä»O]]ÚÚÚfÙîÛ·/”””зo_¤¤¤PÓðDˉž={*ôoÐÐÐ@›6m››Ëwÿ­[·àììŒE‹ÁÊÊ EEEÔð$¼¡¨©©¡ªªJî®kñâÅî/..F‡°råJôêÕ !!!8wî\“ǽqã233©áIx ¢åX·n<(w×5pà@‘Ês8„……5Z¦¼¼ÎÎÎxõꢢ¢@7 /A(cÆŒÁÝ»w›}œÜÜ\‰ÍØØ¹s'444xfH|Œ‹‹ ¶mÛ†•+WâÚµkÔ˜Ò^‡ƒòòr”——Ëå'A(ººº())iöséçç‡Q£F ,3nÜ8ܹs‡o]UÕ†“ :wî ###„……Ãáð=^UU:tèCCCüöÛohß¾=222š¼ÖÊÊJÇ$áÀóçϱeËlÙ²W®\¡§†hÕôïß_!ÒS>|¸É@éÝ»wç›0óèÑ£Xµjß:³fÍbrÆ Ø¿?æÌ™+++hkk 5(çàà€óçÏ“ðŠÂ AƒpèÐ!:t³gϦ'“hÕ|õÕWÐ××—ÙùØl6Ú¶m+¿½cÇŽBš9s&×íàíí-Ô±kkk‘œœŒmÛ¶‘ðѲ„……¡_¿~bÕ]´h‘D¯eÖ¬Yøì³Ï„.ß®];tïÞK—.m´œ••bbb0~üx¼xñ555Mû÷ßo2& /AReèС äùmi,--‘‘‘GñÝÑ£G#??NNNpqqjÚÚ£G°víZ’’ðD+GœÌ¾EEE(--…™™™T®iÒ¤I¸qã†Ô»ƒƒž?.tù¾}ûÂËËKàøOÝê:>|ÆÆÆHLLúøIIIB§5ÊÊÊBdd$ /A(";víÁSVFUUjjj ¦¦&׿­ºº Ã@II‰ï~‹…òòržíñññ°¶¶æ[^uÝ45+++XZZbÉ’%HOOX^UU&&&7n,,,àííݤëáêÕ«puuÜ¿_¨\xµµµ¨¬¬$á%EcÊ”)¸zõªÌÎW—uBœA¹… "33ݺu©^NNŽD«aáÂ…X°`ÀYYY055E›6m`ff„„„`úôé|gi|Ìýû÷áéé‰ÂÂÂ&ÝaaaÐÖÖdgg#&&ÑÑÑ—Z“ðÄ'J]Ö aOšË+ÑOmeehjjòí) ÂÑÑQ _8%%011ÁáÇ1eÊ<}úƒÆÓ§O›| Μ9VVV¸páΟ?]»v5y=ïÞ½ÃÞ½{áçç‡ÀÀ@,[¶Œ„— Zvvvˆ‰‰‘ɹôôô¤GCC&&&p6mÚ4ôìÙ†††ðööFïÞ½Á0 ß²555ÈÈÈ€½½=¦NŠÝ»w#""–––MÆ–X°`¦L™‚  66 È”0”„— “Éœ‘‘ :T&çãp8(**B»víš},Œ3Ïž=㻟a°ÙltïÞK–,lÛ¶ FFF000˜9:&&‹/Fii) 1lØ0DFFŠž„— Zˆ#GŽ`õêÕr}‰‰‰°³³Ã”)S-·~ýz8p Á¶[·na„ " o^^žÀŒÇÒ˜©aaaÁf׳gOL›6 ;v8Œ!C†ÀÅÅfffÜEbÓ¦MƒOó„÷Áƒ?Þ¼y777…™¬L|zÔÔÔàûï¿ÇË—/|˜ºnÝ:¡&âËeeeäääÀØØ¸UöÈÿþûoÄÆÆ6:˜§¬¬ŒÚÚZ‘Σ¯¯Ï7P{`` À^ùüùóqöìY¡ŽÏb± ¯¯ßäµ)++cýúõ%%%¸¸¸ ]»v(((ê<SÿìÚµ û÷…Ͼ}ûöÁÓÓnnn Ò‹\¾|999}}úôƒƒO¥:ÁýXxyF)Ÿ©"‘˜˜Ø ‡ ˆK„ôñõõ…©©)"##y–ˆæääàÙ³g°²²(Ì­‰þùÁÁÁŸD»?}úžžž`³Ùxùò%V®\ OOOìÞ½555¸|ù2F///œ>‰‰‰ÈÍÍEhh(*++QSSƒÐÐPÄÅÅø°  44áááÈÎÎFee%jkk‘––†’’„††rÿ®œÚÚZîqêMx„2aµ'99Gä8Ã’@&³ê¢×?yò÷ïßÇÖ­[¹Ûë Á¼yó!RŒNE#33oß¾Eaa!rrr ­­“'ObüøñðóóÃãÇÑ¡CtìØ•••PSSCaa!œaccC !¥û³˜ššÂÙÙù“²ÁÉ“'‘••…Û·oãáÇX±bf̘hiiÃá ´´¹¹¹ðó󃹹9.\¸€ &`ìØ±077Ç¡C‡`bb===äää [·n8uêfÍš…§OŸBWWÕÕÕ(--EVV®_¿ŽÃ‡cïÞ½ VÀÊ‚ääd\ºt 6l€’’”””Üuÿ®Ëºñ±[¡n_JJJƒëÿø8-ÖãuqqÁ­[·àîî%%%(+ÿÿSÞ½{QQQ¨©©Áˆ#àîî¹HÈ'-ˆ‘#Gbüøñ°··G—.],ñµ··‡¦¦&BBBpÿþ}„‡‡ÃÀÀ€DWJŒ7YYYèÕ«ÌÌ̸!ð!óÁàÁƒ‘˜˜ˆÉ“'·j;ÌŸ?óçÏçþ{Ñ¢EX¶lV®\‰G!<< àOŸ>(++òeËеkWw™¯¯/ÂÃÃamm ,\¸Ë–-Ctt4‚ƒƒ±lÙ2Ì™3FFFÐÕÕElll‹ :þ ‘¢Û„¨„……!//NNN þ€×¯_ãàÁƒèÖ­Ö¬Yƒ3gÎ 88!!!¸wï<;;;äççÃÞÞ—.]¨Q£`ee…wïÞaìØ±Ø³gfΜ‰ÀØØ«W¯Fff&nÞ¼ 777‰ÄßU$Hx ‚‹ƒd‰BUUvî܉µk×6k‘’¢òÿ­m m uIEND®B`‚snd-16.1/pix/locsine.png0000644000076400007640000002555211147553267013321 0ustar bilbil‰PNG  IHDR¾Î€V¸\sRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ0¥9g IDATxÚíIlWzÇÿÕU½Uï+»››HФ(Q»L‰Ž,ɲ”xÉŒ#Of’Ë 9$@[˜æ8¹I0€c Èd06Œ&¶#Š–­Í²$JEŠ)qi6›½oÕ]ÕµåÀéŠZ¤mY,I\Þ0,u7ŸŠ¯ÿõê{ßûJUUÂ&ðҋ’$A„€çyT*(ŠBf°q„¯( ÆÇÇñ«_ýjÙ‡9ŽÃÀÀÞ{ï=$ íõJ¥‚T*…d2‰L&Cf•°æa|A–eÄb1ܹsgÙ‡§§§AQb±r¹@QÆÆÆpá d2¼õÖ[df ëkÅg@n·¢("“É`vv•JƒaEg÷îÝøáˆþþ~üâ¿ ³JX—e‚  Z­"—Ëa||§OŸF"‘€×ë…ÑhD €ÍfÓ~†¦i˜Íf˜L&2£„õiêP…ææf˜ÍfÐ4®®.„B!°,‹;w¢§§G3s„ !|š¦‰D‰D´×|>Ÿöçû_'6Œ©C á›ÅÔyT’É$®]»†J¥‚ÁÁÁº÷|>º»»a6›ÉŒž©T wïÞÇqÚk½½½`F?á×6Æ+‹Å066¶Ìêp8 µÂãñ ±±4M“oް UUÇëO9ŽC4…,ËuŸ5›Íp8`fE}ê&|ǃžž˜ÍfôõõÕ½Çqâñ8$Iª{]äóyí¢ïÞ½‹ÁÁA(Š‚žž´¶¶Â`0Àív“§Å&CEär9H’„……ܼyªªÂn·Ãn·kŸ3hoo‡ÁPoµÛív:;MÓÚ¢ª›ð†ÅbÁ`¨óñ€ÍfC0\ö3ÕjÇiÂçyÅbŠ¢`aagÏž…¢(¨T*E¡PÇŽƒÛí&ÊØ Ü¾}W¯^E¹\˲ i.— û÷ï×´u¿¾ŒF#Ç2á?1ÿQ0™L_yèÕÔÔŽã ª*ªÕ*dYF6›Åþç¢Z­ÂívÃår¡··­­­D1ëX,†›7o¢\.#ŸÏ#ŸÏ£©© »ví‚ÍfƒÉd‚Á`€Õj…ÛíÖõ܈Y«“âr¹àr¹–=!ZZZP©TP,Q,ñÙgŸ!‹¡££‘H¡PÍÍÍ0DYkŒJ¥‚ññqd³Yܽ{E¡³³^¯Û¶mÓ̘mó5íÕyROˆ††¨ª Y–!Ë2vìØQ133ƒx<Žññq,,,àèÑ£hkkƒÃá€Ãá ª{J$ Äb1|øá‡°X,èèè€ËåÂsÏ=‡`0«Õ Š¢êìï'³'“¢¨%—Ãh›^·ÛÞÞ^(ŠY–188ˆk×®çyȲŒ7ß|---D‰OˆÿýßÿÅ—_~ –e …ðñÚ÷f0´ÿ?-t¾ªªÚOíùõPãå—_†ªªE¥R ?ÿùÏDZmÛ6¸Ýnôõõ!…êÄèè(ÆÆÆpëÖ-p‡'Nàÿøát:a0Öœ‹šÒ#õð³Ï>ÃG}„™™\ºt SSSkê—¬m³Ù,Þÿ}T«U¤Óé¯Ì2#<ÚžÌétâ•W^A(‚ÑhÃ0k6‘Ò3çöüùóøÁ~°&„_s ‚€B¡€?þÙl;vì€ÓéÄž={àõz‰buâÎ;˜œœÄÈÈŠÅ"<ˆíÛ·ÃãñÀh4.sq?m˜2ñ<Ï£Z­B’$ˆ¢ˆK—.a~~Š¢€aüÎïü‰,}Œtvv¢³³/½ôàܹsøŸÿù(ŠŸÏ‡çŸEÁl6kg>Ûs³á„¯( DQ„(Šà8•J±X ©T ¹\™LÏ=÷> «Õ –e‰2Ÿ0‡ÆáÇ‘ËåÇñÿñ0™L…B°ÛíˆD"ƒ°Ûí iF£ñ‰º ×…ðkgžç±¸¸ˆr¹ŒR©„J¥‚……¤Ói´··£¥¥ûöíC(zª« áÿq»Ýp»ÝضmAÀôô4r¹ÆÆÆ0<<ŒH$“É–ea³Ùàr¹àõza2™ëþ`ͪ#™L"—Ëi‚—e¥R 333eN§GŽAcc#QØ:Àl6£»»pðàA$ LLLh Z>Ÿ‡×ëE8†ÕjÕ|ü‡C÷Œ¿§*üJ¥‚|>¯¯U*MìÙlÅbªªBQ¨ª ¿ßï~÷»p:DE€`0¸,†ëîÝ»šK”¦iP–eáóù@QœNg]šÙl†Ïç{z±:5{[Qär¹º÷ŠÅ"¢Ñ(DQ¬{½–Ø^ W¾¿Ugg'8ƒÁ»ÝNB6 íííhoo‡$I(•Je‹‹‹ZX»ÉdªÓMÓ°X,Ëž.— ¡P¨.ª×h4‚eÙ¥ƒ4½.8NãÖ­[ày—.]Z¶}0$X mjjÒÕœN'‚ÁàS=Ñ#¬ †Ñ¢p}>¶oßUU‘N§ëŠ–•ËeÌÏÏ/‹Ç/ ˆÅbu7„ßïÇîÝ»—Îô´ßœN'hš®KN¯Ý}mmmdÕ&¬ Š¢à÷ûá÷ûë^ß³gÏ²Ïær9D£QT*í5‡Ã¡Ýº&¢lÛ¶ f³Ï<ó ù–k›ôU›‚°)!Â'áDøÂf¾ªª˜ŸŸÇåË——}XQœ;wŸ|ò òù<™=ºe™WGE ãæÍ›ËÊ„LNN¢P(`tt[¶lÓéEQÂÅ‹µ÷ÿñÿ‘Ì,aÍñÚk¯!‰,`)Š‚‘‘üìg?˲8rä"‘°ÒM,°Þ_ª££>Ÿ×®]ùsçpáÂ].T’$ܽ{]]]ºŒ'Š"âñ8ü~?¬V«.còŸO—y€©©)ø|¾²V•zXë€X+þsÿ—W+e³ÙH-LÂc§VqOX­ÖekÇAEØíöÕýôÓOqëÖ-H’„b±Xgâ¦Ói455azzŠ¢¬Nø‹ét,ËbqqQóýSƒÁ€b±¨›÷„@ø:ìv;AÀØØdYF>ŸÇèè( …‚¦ÇJ¥¢™ä«þîÝ»±°°€àÞ½{xï½÷´¢»»<ÏëæŠ$¾–e‡ÑÔÔ„`0ˆh4Š$“I0 ƒööv˜Íf´´´À`0¬ns+Š"²Ù,ü~?A@©TB €ªª(—˨V«ðx<ä[!<J¥8ŽÓVyž‡ÍfƒÑhD¹\Ïóp»Ý«>°^!Aj"|Ÿ@ Â'ˆð "|Ÿ@ Â'Ö™ðkÈWbvvwïÞ%mtKø<Ïc``o¿ýö²ÏÍÍáòåËxï½÷Fµfo…B333˜žžF4%³JXó,‹Ç·X,hoo× sÖš2P…B¡–eµn‚5¦¦¦péÒ%LNNâÃ?Äää$™YÂú~­y²$I$ ÷îÝÃüüÂá0ÇRmÃu¶BÖjÅß_*<—Ë!‹i5]EÁÇ žç‰D …ÐÝÝ­K]}Â~­Žf­ô¸Óé„ÇãA$ÁÖ­[´jËF£qC­„µ^«ªªjÂ_XXÏóÈf³˜ÅåË—a0ÐÛÛ‹ööv¸ÝnR]z½ ¿V×þüùó i‡8~ü8¬V+l6Û²ÒâÚƒ@QZ Ñ­[·XjE_©TÏç!¦§§122AàñxpðàARez­{uîܹƒÑÑQŒŽŽâ­·ÞÂ_ýÕ_¡­­ {öìÑ\~6›M×èFBQ­ü ÈårA¡P€ßïhw,áë èëë[rŽè1 Ãá@$A2™„$I˜››ƒÅbAcc#Ün7š››ÉfîöN§4Mcjj ‰D±XLÛ7¬¥ýzÆétj{G]VüšûîÂ… øÃ?üC\»v ÑhÈçóˆÇã8pàöíÛ–eÉÊÿkjÞJ¥>ûì3LOO£­­ >Ÿ‡Ã0Ī£ÉYÛ?é²â  Íïîñxàr¹ÐÓÓUUQ*•påʼýöÛP‡'OžDww·vA›Iì000€/¾øB39‚×_]Kòy0Ù‡°müsrËó<‰>ù䌣µµ^¯ÝÝÝèêêÒ§¬[ªÚS°f¿_¾|¹\à8ÇG?ìv;ñâlá?ÈÌÌ 2™ ÆÇÇ111‡Ã¾¾>0 ƒ®®.mE¬Ý kq¬:W«UÍU™J¥0??ññq¨ªŠ¾¾>¸ÝntuuÁf³‘Õü)óÔOn[[[ÑÚÚŠ½{÷R©.\¸Q100³ÙŒþþ~466‚¦i˜Íf X,°,ûT¤( òù¼Š]©T Š"nß¾ëׯÃëõ" ¢©© Ç_1~ˆ°É…ÿ ~¿¿®q¹\ÆÀÀ†††–:R3 (ŠBSSººº4W_ífXÉlp¹\µAäy<Ï/ R«V«uu„AÀùóç!Š¢VqÂh4b÷îÝøë¿þk¢ªÍ$üb±ˆ¹¹9Ý/eY|ç;ß°t0V*• Ë2¦¦¦púôiT«UK¡Ç~¿Åvðš©ôu¤Ói¤ÓéeÂÏçóÈårÚ닯¼òŠÔFVôM,üT*…¡¡¡Çz±F£Që©å÷ûqðàÁºU8®˜ˆrùòeíù:šššÐÔÔ´ìé  ‰[‘lnõÛÜO²„ˆð "|Ÿ@دV«( +þ@­®¦$Idöë–eîLQqåÊLNNâ?øAÝ{étCCCˆÅb8qâÂá0(Š‚ ÇAQ”¯¼i„§‰ÍfûÿèLUU1;;‹Ï?ÿf³Û¶mMÓ+úÃS©Êå2¢Ñ(ŠÅ"Âá0`rrW¯^Åøø8ñÚk¯‘Y&¬9þáþ½½½0 K+¾ÛíÖ²¥âñ¸–*·¸¸ˆ\.‡ÆÆFH’†a`0êN7[ZZ´\Ú?û³?ÃÑ£Gu¹Ðr¹Œ?ü¿ÿû¿¯ËxÇá‹/¾@oo/‚Á .c¦R)ŒŒŒ`ïÞ½p¹\«O–eܹs¹\‡ÒåGGG‘ÏçÑß߯›ˆ®\¹¢…ièÁôô4Òé4:::àv»uóôéÓèììDkk+€¥ÊZlCQœN§V7FEÄb1ŒãÎ;XXXÀÈÈ^zé%466b||v»6›Mû‡fâüÖoý–.^*•°¸¸¨ÛxÅbF£û÷ïG$ÑeÌx<·Ûþþ~x½ÞU'I‘ÉdðüóÏërÁ`™L/¼ð‚nÂgY&“©îô|5LLL ‘H §§>ŸO—1yžÇöíÛÑÙÙ¹´¡½/ÇaÙÉ­ªª¨T*¨T*p8e‚ Àf³a”ËeȲ\g/Ý¿?EQ· +EQÀq‡nãñ<³Ù¬[ |m~,‹.! µ 7EQ`±Xt¹ÆZÉÅÚS\/QQµblÔ£ Š"dY†ÉdÒ-4¤V§i¥œåU…,$“Iœ>}¯¾újØk!º øÍßüMb\žׯ_Çðð0úûûµU¾ÆØØfffpìØ±¥Ej5ÿлヒææfüû¿ÿ{]3¸|>S§N¦i o„ðØÂÔÔ¶nÝŠ‰‰‰ºHaApæÌÄãq|ùå—eyuÂ/—Ëðûý(‹E<Ïk&…(аÛí+z‡½ihh@¡PÀ/ùKT«U°,‹jµª¥J’‹Å¢itU·ÙlÚ^`ddÿüÏÿ¬m",‹®ö>ðMN¯×‹7ÞxV«—.]Âûï¿X,¦íETUÕö$«þïþîïâêÕ«øƒ?ø8N­n¤Ëå /¼€L&ƒ'No…ðØÙ·oÂá0Ο?ÖÖVtuuÁívÃh4Âb±àÙgŸ…ÕjE__hšÖ7Ÿ@X/ 5>@„O áDø>@„O áDøÂÚ¾,˸uëN:µìÃårgΜÁý×!™L’Ù#¬[–%›«ªŠL&³bÀùùy”J%LNNbçÎðûý ( W®\Á¹sç´$•¿ù›¿!3KX_+>MÓp:+6«V«`FëøQ£§§o¼ñvïÞ÷Þ{Ì*aý­ø’$!cll sss¸qã¾üòK¼ñÆp»Ý¸qãDQ¬+»]ë[ëv»Q.—ɬÖ<Ë¢3eYÖêÄ766BE‹EƒAX,$“Iˆ¢ˆ@ °,ß’TK&¬ÛŸ¦iƒA-#ýþ¬÷††2k„gãkÒœŒ°…O l*SçQ©T*Ä·ÿ<è«!Š"2™ &!Îãñ¬Xφ4…~ ÂF£$3ú‚ ›Íj=¸$IB¥RY&ðb±ˆ/¿ürÅ›âAöîÝ ¯×»LäV«µ®x’ÕjE  _ÂJ¦<é¥ßJÎqŠÅ"EA¥RAµZE±XÄÌÌŒææ¥(jÅ*n/¾øâCUxÀ²×eY®»¡j ¥)Š‚ÅbÑÚ¡:Nݪ´mú³‰¼Z­j¥ãñ8EA©TÒ?sAà÷ûqèÐ!­*Ã0°Z­«2I¾ªf­Ñt……\¸pA[ýY–MÓðx<ÚÓÀf³i7Åf2“ˆðY–,•DÏd2EÕjÕj¹\ƒ¡P===ZÏÝ•N¿'V«µ®>¦ÓéDww·†’ÉdP­V1;;‹ééiÌÏÏÃb±hõ%)ŠBGG|>ŸnµE‰ð×!Çazz<Ï£T*i«º(аÙlp¹\p¹\Z¥é5kÏR|>Ÿv³cÇÀÔÔR©ŠÅ"2™ŒÖÔ£Ö´Úh4bË–-²5þÑT*ŽãÇQ.—µÍfmìëëÛ0‡xèèè¨{íÆˆÇãˆÇã ( óóó`.— ¡P@@תËDøO‰Z¿¯™™ÌÏσ¦é¥Ž¿þ²;::`±X`·Û7EgóÝ»wc×®]Z=Ô»wï"ŸÏ#›Í"™LB–eƒAlÙ²,Ë‚eÙº¸-"ü5Œ¢(˜ÅåË—5‘³,‹††x½^X,øýþ ±²=ªiT3o|>Ÿf¥R)d³Yäóy|ñÅe²,cçÎèèèX±ýšýõpgÞºu CCCÇO~ò¼õÖ[kÞ+S©TÍf‰D°{÷n477ëÖ‰c£“Ïç‘H$0??[·nXŠÐ]ëOÄp8Œ£GÂd2é³âƒAìÙ³Š¢Àl6cïÞ½k^ø¢(‚ã8”J%\¿~ñxíííˆD"Oܳ^(—ËXXXÀôô4fff`µZµâ¬f³yÍ»Cív»¶WÛ´X’$AðQ.—Áó<$IÂÐоøâ H’UUñýïCºõVBE¼óÎ;e ÃÀl6cË–-xùå—a±XÀ²ìªáˆð×þx½^ð<žç¡( Þyç”J%477Ããñ ­­ ;wîÜ¿ûÄÄ&&& Š"¢Ñ(8ŽÃ믿®Õ–¯ý#möI¬ÎCìh18óóóÈår˜Åèè(> ƒÁ€`0¨[ÑÇEµZE4E.—ÃÕ«WFÑÖÖ†ŽŽ0 ƒÆÆF¸\.8PµaÃÈŠÿM+ï¿øš™ãt:¡ª*úúú I’É$Ο?Y–‘L&‹Åàr¹püøqlß¾]‹Íyû„Ú^E\¼xŸþ9L&šššàv»qôèQ455aíú6Kh³nÂWUU‹gÙÈÔ\v4MÃh4¢¥¥---uO‡|>3gÎ`ppEÕ¹ùZZZðÊ+¯,‹Ž|ðsß´é|ðA-Ë2>ùäܾ}»î;Q ÃàÙgŸÅßýÝß-»¡7킦—©FñoÿöoxçwH²ù «®$I€ÙÙYœ:uJë¾WƒeYtuu=”ø'''Q,ëÄÏ0 Nž<‰mÛ¶i¯ÕbnqÅ·Ùl…BdFÀh4j!Éà÷û±oß¾eŸ+—Ë{¨D”“'OA¯á{<žºÕ†ðí`Yû÷ï'ñ¤LV2"|Ÿ@ Â'6¶ðEA<×ÂMïGEŒchh¥R‰ÌaÝÂÿ_ë¥vˆ299‰›7oj¹™5‰„¥çr¹`³Ù@QîÝ»‡ññqŒŒŒ T*áÝwß%3KXs?~\ëéÀ¨ªŠÅÅE\¹r&“ ííí0™L+žìår9˜L&‚ H–N1kAL­­­¸xñ¢.*Š"¦§§ÑÙÙ©Ûx‰D^¯W·€«J¥‚L&ƒ@ “É´êñEA>ŸGµZÕ-·7›ÍB]ÏY‰ ü~¿.ã ‚§Ó¹b•¸G!jqGpàÀø|¾%áK‡O­­­`‡ÉdÙlÙlÓÓÓ˜ššB?¬V«ÖõäÁcø––Øl6‹E¼øâ‹º\x©TÂÏ~ö3üÑý‘.ã‹Eœ={û÷ïG8ÖeÌÅÅE\»v ‡‚ÇãYõx’$att™LÇŽÓå¯_¿ŽL&ƒãÇë&üsçÎÁd2¡¯¯O—ñîܹƒD"žžx½^]Æüïÿþolß¾[·n°Té»¶ 3EÁívcÏž=ÚÄ ôööB’$X­V¸Ýn˜L&x<tvv.+#^£©© ßùÎw–™HŠ  ]Ûjáyn·---p¹\º­Thoo˲º¬øápÇ¡««K—kôûýà8ÝÝݺ ßn·ƒalÙ²E—ñ"‘ŠÅ"B¡l6›>XƒápxÅ2ŠËbujUªժH%IL&hš† PUU{¬ ‚ Uá’eY Š’$IKE|TTUÕÆ×ƒZÊ!Ã0ºå‡*ŠI’´‚LzP›G½’·kÉ4z&ƒ‹¢¸d2èTa¡Vþ¦éGžGQ!ŠâRN-àZ­‚¦iÐ4 I’ ˲fƯ*HíìÙ³˜œœÄîÝ»±oß>MLÅb§N‚Á`@?š››ÉΊðXI&“¸|ù2æççÑÝÝýû÷k¹Ó²,ã—¿ü%’É$Nœ8ÖÖÖÕùñ¯_¿ŽíÛ·k)z÷›SSSðûý#ß á±“Ïçµ2ë¹\•J¥îI033†a0== EQV'|AàñxP©TP,177§™Š¢Àf³- ¿%‚ €amï™Ëå°¸¸¨™æªªÂb±hEuW%üîînüüç?ÇþýûqîÜ9üéŸþ)€¥8p‡ÃK—.é¶Ñ%¾¯× A´CCCøû¿ÿ{Ü_þùÓ ÞIDAT¹sF£6› ·oßFSSÓêmüZ%-š¦¡ª*$I‚ÅbÑþ `Ý• ¬Oj€Š¢hz¬9Z ƒ¶Á¯•ˆÔ5Ùœ@X/ 5>@„O áDø>@„O áëLøµ®+177‡{÷îi±ò†¾(Џyó&>ùä“eN$ǧŸ~Šd2©ÕnL&“Æ7H4&a} ß`0@–eäóùeN¥Rñx¼®ÊÇqZÞîüc2«„5ϲôš¦át:a·Û¡ª*îÝ»‡x<ŽmÛ¶á«Âz‚Á l6ªÕªn‰æÂ]ñk s¹fffÏç‹ÅÀó¯ùð9ŽƒªªÄŸ¯#…B hjjÂÖ­[±uëÖ5µ1]‹8N8N”J%FŒŒŒ`ttMMMرcÇ’›”øñ×6©T SSSÈçóÚê¯( "‘Ün7ÚÚÚžÈÏz@¤ÓiÄb1$“IH’†a´B±^¯;wîÔoÅ'<>ü~?ü~?xžÇq˜™™A©TB&“A"‘Àõë×ÐÛÛ«öèÕ:i=ì …dYÖÌm“ɋŖea·ÛÑØØ·Û½ìŒ‚y4, |> “Éh)Ÿ¥R ƒƒƒZ–eñì³Ïê~êºV(—Ëøì³ÏÏ絞Y‡íííp8ðz½p:_ÛŸ‹âõzáõzÑÜÜŒR©„………ºýÖG}„jµªõyu»ÝغuëºÌ’;wîxž‡$IˆF£0غu+"‘¬V+ Ün·¶(< Dø»Ý®öÔÂ"‘8ŽÇqày©T 7oÞ„,Ëèèè€ßï˲hll\3¦QMØÅbÅbccc¨T*èééÙl˲xî¹çÀ0 "‘ˆÖmóQ Âß`P³ÙŒÖÖV­½©$IE¥R årÑh“““Ú Q­VÑÑÑþþ~­kÍ|Ð{ã,Ë2Êå²vè&Ë2†††0<< š¦À²,l6>¬¹!k&^é‰ð7øM`2™41»\.(Š‚ÆÆF­ïkµZ…ªª˜™™Á| 5Gû*|>:„¶¶¶o\½ÿõ_ÿõÇ3 ؾ};¾÷½ïÕ…%Ó4­™1Ý„ëÖ-¼ýöÛDmkƒÁ°b,‹ÏçCOOöwEQP*•–ÅÓg³Y `vvökÿš¦ñ½ï}oY¸MÓ`Y¶nãY R{¢‹‚^~|Y–qöìYüð‡?$~ü ÂJÒ¸ÿ,á›øª0çµpÚ¬ÛŠOÓô¿k ßTZé{Þf$Ùœ°9M>2"|a3 _E”Ëå T*iñÂz…Yi×>==ÙÙY¼ð uïq‡7n ›ÍâСCðûý–ò#9ŽC>Ÿ‡,ËH¥Rdf kŽû³±UU‘ËåpïÞ=0 ǃééi -~4E:ÆÈÈ:;;áóù@Qâñ8&&&pûömð<Ÿüä'º]¬(Š+¦Ž=*²,ëÄ䯣–è­§§£–8®×˜zW›GŠ¢t;`zó(I’vâ ßÿþ÷µÒ% ‹EŒÃd2¡§§ápóó󖢋Å"€ßLQT·–”J¥Ð×ׇb±¨Ë… ‚€+W®à7~ã7tçyLNN¢¹¹Y·â·…BÑh[¶ly¨$ç‡Ôââ"8ŽÓâoVK4E¹\FWW—n¢šššÃ0hmmÕe¼d2‰b±ˆ††ÝÒ(oÞ¼‰P(„@  Í­ªªK§(JKÙªÝ%W¯^E±XD*•ÂÜܦ¦¦Ðß߯׋¹¹9x½Þº/¹–àKÓ4<^~ùe].¼T*á§?ý)þäOþD—ñŠÅ">ýôS8pápX—1ãñ8®^½ŠgŸ}ö«‹=ì*uëÖ-d2<ÿüóº\ãÐÐ2™Ì²'øjøüóÏa2™pðàA]Æ›˜˜@"‘@OOÏ·Š²ü:>üðClß¾}Å„þÑ~ô£‹’$i±ßV«,Ë¢¡¡>ŸƒMMMhll\f‚˜L&-Z(Š‚ÛíÖö«ÞÉ °Ûíðx<º™Oµ2n·ûkã¿¿ ‹v»]—ñÌf3¼^¯®= , ¼^¯n«³Ñh„ËåúÆ8úo˲ðûý+¬®*d!•JáÆ8xð`Ý—$Š"îÝ»‡\.‡ýû÷“Ô8ÂcGQܹsÓÓÓèééASSSÝþcjj Éd{öìÅbYpp‚ àÌ™3Z˜iÍDD:&” O„»wïbbbB»Òé´ö^­7Ûøø8ÆÇÇ¡(Êê„ïÞ=´··kÿàý+~"‘Ðö“ ŸÏcvv¶®#gmS[+1’H$ ªêê„oµZ‘H$`·Û122‚ù—ÑlsƒÁ€|>¿é ž57u­`ÔÈÈÞÿ}Äb1MÇiöþªv'OžÄÄÄ^|ñE”ËeMä‡GŽ(ŠØ·oùVÆÆF­€T{{;TUÏó0 0™LèëëC:ÆöíÛ—ÎqV³¹•$ ¥R N§S+uçr¹´’n¢(’'F¥RÏóZ=ýjµ ‹Å†a´Räµêsº”"Ö $:“@„O lþš˜Ê4w–dIEND®B`‚snd-16.1/pix/controls.png0000644000076400007640000004277311147553266013533 0ustar bilbil‰PNG  IHDR<Yê[¯sBIT|dˆtEXtCREATORgnome-panel-screenshot—7w IDATxœíÝyÔ$g}úß;‹f“4ÚØ†i†°] 6W#›xÁƒ±Ç²N’øF˜ø„câèž$\ƒ³à+_‡˜L¼Èc 0Ø`, K؆–‰Ö cÀÍhy%¡™·ï¯z¦ß~«»«ºžZûó9g¤™îê§žªî®~¾õ<õÔRD  ‡6EDüÑàΦëÌë~í߯íÿôÀjà‰ˆxëÑ6Y€äNž•'O=øïÿö{âmo{[üôOÿt<ãϘ»ð—ýí/—«PÚ9ñ²$åüóMïëDy£NžÁÉ•S~ùË_Žßù߉—½ìe¥Ïh™@Cƒxü/.Uħþôæo?ú‡•­§iuíO€6<(ƒ9ÛçƒÕÿ Û÷£åýÀ‹_\¨¨ðƒ¹Êûð§Ï1°f¹±òFôðœ\÷dDÄwÜ7ÜpCüìÏþlœ}öÙqÉ%—Äk^óšøöoÿöؽ{÷ÄJL*€ü+§Þ‡þ¯ßK~ùG*]ß}7ß÷|þ³qÞËŸYézšR÷þh…M«w¢ æ¿#ÍjÊÉÒå _3«¼xñ‹ãCð™eüàýÐôòFd^Ã3ôÙÏ~6>¼&ì ½øÅ/ŽøÃñS?õS±aÆìÑÃPÞØÉWoú_ñØï~j¥«<~äXlþÂW㬽UºžF4°?ÚbeÞžD ëÚ÷ó”·úšÉåýÁÞ?ô’ŽˆÕ`óxÿše†ÏEDüÁÞ?µ¼ˆ5³´­òñ|üøÿxlÚ´iÝsßÿýß?÷s?_üâ×]Ïsï½÷ÆwÜ+; ÿöl½0~ê±/Чn{blÛpF|så¡8üÐ×ãÀ×>vüøð3®ˆˆûtœœŒ󬈈øý£ÿ3®ÿÚ-kÊ{å/ˆWœ÷]±iic|äÞÛcieiÝ:WN¬œ*ó}G?ÿõ«™Zǧmbüƒ öÅÓ¶?1¶n8#îyä¸í¿Œ_ûX<´òÈše7nØÿê寉Ý÷ƒ±²aï¹çOãà×?^¸¼3–6Å_¸/^xöÓã‚ÍgÇ7N.ÇÇø|üúßüa,¯<ܺý Ðoåzxþ9}¼\[ÞÞÿû¹ÊyÉ¿tµ'&Gy/ùá—FÄjÀ–?|l¸Ì©Þuå6µ‡ç /Ì ;Û¶m‹öÏþY|⟈£GÆóž÷¼XYY‰cÇŽÅÁƒã9ÏyŽ`!üü®WÄ®-çÇÊ`w~鋱yãæxúžçæÁxpÃ×cë%çZöóì¸ï¡oÄ#+ÎÝþ˜øî‹Ûn¹5}ÛjHøÞsŸÿø¢ïˆˆ¯ûz\¶áÉqÖYg­[çèñõÛîŠcŸû\œûCOˬß3wìŽ_¼øªØ´´!xð›ñů}%þΓ.Ž;ÿ»â)ŸoøêïÄ`óéžúW|ßÇå—ãÂÇœÿè¢ï‰#vg|ü¢¯*ïÿ¾ä•ñܳöÆ#'OÄÿúîxÒEOˆ—ì|Nì^>+~ö+biKö5 MïO€>æœÑa½Å xtÈØðš›±òŠ”;XY™Y^DÄûï}ñÃ?²:]õhÐ>·fcåšy Ï4O}êScÏž=ñÛ¿ýÛqèСxò“Ÿ÷ÜsO\yå•qÎ9çÄàÓ*\&@×<îŒs#"â#·ÝÿòÿMl8ûŒ8{ûYqæ`kÜÿø“±tî–SË{à¾øÁ×¾2οð‚øÈ¯Œˆˆ§Ÿ¸0>ý'·ÆÙß±;^vþó""âðWŽÄüôOĆ­›ã÷Þz}ìzìÖ¬spâdüõC÷Ä#÷£÷‹¿z_l¾ëk±c×y1^›–6Ä=÷ú§¯Ž>?ñ#WÄ¿ùG¯g=á)ñmïÄçžwâtï¿/~èŸÿx,±!~ï?¯®ûå{.‹|àÿ‰s¾ûɹÊÛô¢]ñܳöÆ`0ˆW¿þŸÄÿºë ñÔ§?-Þû‹¿Ï|âSâÛÞ½ù]'cæõ¡§©ý °Ê\Ã×ÈŒ^?S¸SÊúý÷½7^ú²—¯{,s}³®á™wFµ­[·ÆÕW_'Nœˆ7ÆÒÒR,--•* K>yß_Å Î}jüà¾ïç>ëÒøâ7¿Ÿþ›ÿïúìG"x N?=|ëãŸùDÿæÑçÿî—Ä­7}0b5ÄŸ|ö“ñp<[þÞžSë~Êž'ÇñÏ|%¶þÝ‹âÛ.]ÞC_ÝñÔˆ¥¥¥xÏu¿µ®N÷±{ãã·|(Î}áSbil„YSû`Ì;KÛ¤öý°¼"å+3Ë›õú¼õ‹(pži–––bóæÍë+cL4°þýçßßñ…³ã¹OxZ\¼kO|ÇßyZ<ÿ Oç_ð´ø—Ÿûo±aÛéãã7Ž36\¸#bëhÏÆRÄ#'ãÄý®)wãùÛcӶͱåÜëÖ9<¾îøÑ§ÆÊ}ÅÒ†¥XÚ¸aæqwÃ…ÛciÛ¦8û)]óø#û͵Ë]°#6nY»îÁÇC_{ Wy'¿ù­Õÿ¯¬Äçþê/×Õã¾îóÍxä¾ã±ù¬mkžkrôÝ æëáYŠ¥ˆ¥¥uÇËayEÊÄ`fyC/{ù­{ý¼üñ¾÷¾;Wý"&\óeË–xÜão{ÛÛâ†nÈ]ù¡3Î8#^óš× ,„§žù„øè™ŸßûØ­±òµåøÿðçâ¿ó{âÙJûwçÿä¥k–_Ú¼!6íØ²®œ•+q×òßÄ·ùÄxþ³žg|hsl{Ì™qéÙ{×-;8¹¿õÜŸ¸4â#û™xÇ‘›O=>îãH<ûìKbßs¾3óÁÿ+gn¿áé:Ý1H¾óÙß[>°%¶ŸµãÔº¿p÷qâ¡Gr•÷๫gÚ6nØÿé7þ¿øÔ_¯®cãÆñü§]_8òň37Æü\,mÚ°fšÚŸ}vª7}eÎ!m›V;9†ÇËuå)we0»¼ˆxÙ+®8õ÷÷½ç†5½ìå?v걬úUýѲGÆ»=ÿ;¿+>ô‘Ä`β´a).¼à‚Xù¤1Ñ@ÿýò³^ß|ÚƒñÕMƒ ±çìÇEDÄŠ_ûf?rtý‹ÖOƒÁJ¼÷ÈÇãçžöªØó„'ÅÿíoĆ­›ãœ-g®[våÄÉØµí‚ˆˆØúùoÆ7n¿;v<Wfý~ý‹‰ÿüì×Äùçžþ÷¿_{äþØ{îê®Ûÿòޏå·Æ¦çœž~ú¼sÎý»_¥-ã‚m«×Ó¼ãÇl)TÞ'¾ôñü'=#~ó-ÿ%î>úåxdÃJìzÌE±mÓ–xÕ¯ÿ«øÆÃ_'uѺmhjôÛêr0ÄËì•…^ùÞw¿+–-áôñòty£ÿÏc0Ì,o´Žï}÷»N=þÞw¿ëÔs/{ÅñÞw¿ëÔ«×–wZfÏ—<_Y:3"{\–—O:c,„ßÿòŸÄS¾u~<éqOŒ­[¶Æ½ÜŸø³OÅú_ g'üÖúeW">ôåOÆŽ¯Œ+/}qœ¹mG¼ÿ>±´¯þ¾—­YtôøºòЉxø«÷Ǧ{Î3Îݾ®ØÏ½3þÉ{ßÿx÷÷Ç¥O{F\ü˜ÇÅW¾þ7ñá?úÃøÕwü÷œsF,=ötxÏï+'ãGÿþKâ¾o<¿ùÞwÄûþðâŒK/ŠglÊ]Þn{üƒ?~üà·wìºð±ñÈÉq×_ŽÛ>õ‰¸ëÃ·ÇæxRæ64½?úlž!m«¯ytÈØø57si›VÞþØ«Nýûwß}p]Ù¿û–yù½2~÷Ý'–1ážå'ãþ‡Y·pÛ7ÍKÐÿñŽwŽþ|¬üíñXYþVĉˆ¥-bÃùÛâŒïx\lؼ)þÞ‡__ÿ•?‰ˆˆM—œ1d>68±ïXþãøooùqâ‹ÁÊê„¿ðûo‹wÝjƒ+ë^?8qrâq÷¯¶‹k>þÿƉÿòõ8y졈'ci󾯿Ä3cËSvÆÆ­cu¼øœøø[qòK÷GÄRl~êy±q×cbÓY[bpb%Wyƒ-ã¿ÝKüêü8ñ×߈Áƒ'"6,ņ3ψ ß›–ŽËÞÿ/âèýŸk¶¡©ý ÐkKk{Pоfiô™±òFCJŠò""ÞsÃ;'Ö÷=7¼3^qÅ«'—7¢ô,m“}ð[f½ƶ¿·+N>ððêv%Vo(°a)6nÙgœ½=VN®Ä¶Ÿ|zÄý«½ƒ•ÁÄÇ6nÜÛž·+yêùŸŒ¥ÄÒ–M±ù9øÖêqux|Íz}–¥XŠíŸߺèÌX9þHĉ•ˆ¥¥XZŠØ´}Kl:{Ûºú,mÛƒo¿0â[ƒˆ¥ˆÍgm[ψ•“+¹ËÛzæ¶Øð>)N|óáˆGNFœ|ôGióÆØ´usD,eï—†ö'@_ Gþbï¾ází °têxYGy³zÖ,7VÞ¨R÷á™æÜ­›Ý×X›7nŽÍ箟­rÕê}¶mÛ±íôŒd“‹ˆØ´aCl:gýlbãËMz}–¥ˆØ²mkĶ­ëŸ<¹ƒŒò&­7oy›7mŠÍçdßÄz°²’¹ MíO€¾Û²eò1~–Õ”µÇ˶—1ážó¶žƒ³ç^WDDìܲɘhhƒ¥¥øô'n.[Äéö}ÛË}<"4¸3þÕ»þC©´Å·î=·ÿÓÙ=<}°îžåüU|î]·6V!€y<ý•ûbûKþΚÇNžË«³Ú|î]·Æ§>uK­(ë¹Ï}a\ú=»×7Ü—¹ìøãYeMZ¦*E¶#ëµE·µ*Yu™ôxSuÌ+ë=©²®mßu(ÒžÌSÖPm¬ÉCÚJNZ·ò³–>?-|T)å›§¬y>4)µ¹aŸò‹–÷umÞ]Twû~ʤ†´Ý6yZê&-HÕU÷0§YëŸÔ ‘÷ùÔÝ|ƒÁ}ëz3¦ g›¶ÞYû:u/LQÃõL{Oòîë”ûcÖg¤éÏ0@ )Ú4yÛOyU6¤-OStgUÝÀÎÓP-Òx´­£Ï7ÕÐUǦÃL^“Þ“ácy÷uªý1«>]Ù¯Àb›ÕfO}Ožvw•݇§/ µy¶#+‘.¢¦ìmûìÍ[Ÿ¶m°ØfRªz]óšÒÃÓkx„‹ÙF‡µ• "öuz“²ÀtMÛŠã¹æô}x:tãQ ÃúØ×Õ0¤ èƒ6¶]ÆsÍ©ø³qÃÆZ&.裔ɶ)9I›Õµî:_WVWßc€ª¤lçšZ‡´eÍ–5m€¬eª4k’I3HŒ?–g[³^›ú>@Óz Rìëñu”B—Uÿi럴Ü<ûº®Ïž!m@ämÓäi'¥mÒ¶2½;©n:šr™y”ÙŽ¬7-õzç‘gV²y_?i™ºoÞšj¹ûcÒóUî#€ÔR¶iR·çf©lZj€¦U6-5@Ó&÷ðl˜ïž¼µ}íh—¾l@×ÔÝKÝžÏ5¥‡´õ¥Ái;Ú¥/ÛÐ5]o‡MÒÖ¥ûðdÏ5µNK P¥J¦¥hƒ)“<@·å¾ÏÛßþ›µT •)÷á9=Öí’KöÄ%—ì©­Re½öµ?“~Zj€¶˜ÒÃ#ðÝ6ñžMzx€ŽÏ5n¾ô–ÀôÖ¦Ù‹œvî¹»ãÞ{Ÿú÷Ûí@¼îu?>tOòбeˉF×Ðg/Þ½úÿÿðé½§{úù‡ªÍd;vì]óïãdzë8¾\Mª;«~8Œ)x *eƒÈxH˜T^ÂÄ<û¢ ÛÕ„BçÏþ³ˆí§ÿý¯I|>î\óXDÄ“–ÏIQ7zdV#>uƒ½Ë`žºçíáZ4…{xnY¾eêó7ýÊMñ›ÿ⺈ˆxÕ«þQá =ãO˵ܵ׾¡pÙÔk´®^­I=\‹¾ß+Òvé¥ÏZ÷ØW¼:n¸á™¿ã¿ûö½àÔc—]vyDDÜvÛÍc=’¾²$¡±Ý¼á¾ïòоj¿†çŠ+^·ÜòѸýö?Ï C㎹³†Z‚ Ó>³&oèû{Uû´Ô·Üòшˆø¾ïûž™Ë{w""n½õ+«åíØ±7Ž?Ôût_ ß«;övbæºyÕx®¸âÕkþ}ûí>uùÑÞ+¯|U%u ¼aØ¡{FƒOÕx†½;CÓzyF{w†ôò4ëy»Wÿ {†„îëkè©-ðŒ÷î MêåɺvG/@ó>yøt¯€!lýÒÇ!nµžñÞ¡¬^ž¬Þ¡EëåéÛè®çí^ ;ôÛøµ=]o‹ž¥í¦_¹©ðJ†3³M’5cÛ ¯Hc´ç®Ë3º <ÏÞòìS7ˆxû¯ˆ×½îgâÁ‡î™úºia'bµ—çë_?]Æm·Ý¼æ^<@sÆïéÓ¥àSù¶I×5cЬ.Ne]ËGo¼±ø08Úãc÷ìuý§Œ÷øŒ>Ö6•žnxçºës€î˺Î'ë¹&ÕÒÃ@w}ìž½ñÝ犈n a¢ã'Ï·:B‘ÀÀL»GØ!Ÿ¬ ÓdoÀÓ"]¹ð X,ß}þ!‡©Ú|-ÀÓ"Y!hƒï>ÿPÍ–W‘ž2½j“ <ÔbZc¼HÏDžë„æé]*æ]~VÆËµoŠÔa <4®Hƒ}ô:¡¼åM ³Ƥ²²–Ÿ¶Þ¼=^ãË 3å<tNÑP$ˆ Kãÿ.Ò³$ÈÔCàyTÊq¡¦cúäc÷¬¶“Vo8:4{˜UWä26ïòEË^4u´™žXPÊjh…34dülnÞƒBÞU~Ök‹ Ó™öÚѲÇ}mÖú²^›·~Y¯­ï´ú)kÞ:-'oy)ê’÷þ%Ya£èû2íó7O@ÈZǬzLZÏxɤ2ÆŸýÌÎܲʚWŠFE[ʈ(XRÎ'x¥#xѤÊÏW¼ºêUtV‘rߺY5ú¾i¤ÎZ6k˜Í¤á2ã½ICk&­7ëLwÖòYA&+˜å){ÒrÓÓE‡ëÌs}EÞFoÞý:«Œ¢á5«œ¬å§…Ĭ!]y_ŸU¯Y ˜<›<߉eä-» ².7 S¯²¡)¢ÜooŠ2H¯Á«®p>k™eT¥–ž[nùèÌen¼ñ¦xó›ß\CmÚ£ÈYÞ¶|©h‡²êiMëuštÏsÖzVOϬ³ïy¬ÓK}özÞƒvžÀ·Œ¢A)kÙIA0O9yzôŠÔcžà0ë=©{8UªÞ…6HÙ+W…YõhSUök5ý9ž÷xÉ| iÖ©¢‘7$¥\g•ÚИjC†eŒ§yƒ`Vp*òúˆìðUVÝC›ª M7òÚV:¤øž·å½ïS)ÔUIë)rœKQF—™¥ €ÒŽŸ<ÕrÑ2†?Ìe{вþçõeü¥A}útr¤-ÚT—®ëÂ1O­Ò†3âMÿx·íº¯-¥Ká-ÅD#U½LÙKßg½“ê:œ ÁŠéÓ°·iÚT¿6¯*ÒcR ÏkúŒiê@·t!$À<¨Hî'SFêP¥¶ô$´¥Œ¢²>EëÑ÷ÏíÐÚ!mlº Ð ]>óîz$ª–rJù¦Ë ­ <·ÝvsìÛ÷‚¦«sKÕèqö[C’ÅÑ–àÕ·ïœ!mÐr)†Åõ©ñ´_›†+ÖÒÃsã7Õ±è•6ôõåLoŸÎz·¥Ð•žnxg\z鳪^ 0†q{´%¬´¥PCÚ ÇR6hçm ·ih °x õ„&`^0Sª°aP·VNK ´G&O˜— 6MöîÍi²wWàj‘²§¨©†SŠÐ$xÑ5]ŠjH[‹8øÐW)K©‚°Œ.7àL+½R¼Ç>'zxZåøñCëþé¤ ^e’MŸèlKoU[Ê%$¤Ñ–ÞL fÃÆt[ÖeꑲQÛdFêàå¾Uí!ð‘jDBFYmëijC=…Umì5k’À,”>„TÚ²/Úb…~x jKµú²O¯´€9´!ô¤ªC[êÑm©Gô%x <Ö–z[BOÊhC†e´áóÑt=܇kKèéCÊÒÃô–Àô–Àô–Àô–Àô–Àô–Àó¨;öžú“¢, yîëetŽññ- h‡…ïáÉ 7Çš+¸” J@z xRv } iKdž°cøT«×gZ hCoLž:E0¿^ž6„ 9®ázkáOÖŒlÓ& Hu¯ z½Ò–×xèI1AÙò€òžGå %“–j }~HÐ_Ð[Ð[Ð[Ð[Ð[Ð[Ð[Ð[Ð[Ð[Ð[›ª^ÁW¼ºêUôÆŽ{›®ôJå'"â–[>:s™o¼)Þüæ7×P›ö:~üкDŽ ˜_åCÚn¸á¹–»ôÒgU\`ÑÔÒÃó¾hj/Ï7Þ´&ð\vÙåuT è¹ZÏ 7¼3.¸àü‰Ïgõî9rg沌7¾ñç%ì IDAT“Õ è¯Úfi{á _”ùø7Þ´î±Ûn»yb9ûö½ Y€~«-ðLº–gÒµ;»v=yÝcLZ' ßj½Ïx/OVïÎPV/Þ ˆZ®á¿–gÖÌlÃ^ž·¼å"BàŠ©5ðDœž±m|f¶,Ã^AÇýx蟬ûP¦V{à¹á†wÆí·ÿ¹ûî•«<ð\qÅ«s=6Ê}xÖª*ùîØ±·“eW]¾º7S¾º7S~WË®º|uo¦|uo¦ü®–]uùêÞ•žƒ£ðk®½ö ñHúÊ §ÖYÚê$ð½%ð,°*ÇvV=n´ËãRí÷fØïõëò~éê>°ß›b¿7£Ëû¥Ëû½k · · ·ž–3¾³~öy3ì÷fØïͰߛa¿×Ï>o†ý¾–ÀôV¥7ˆØ¾ý¼BË//­¨&í²cÇÞS/“ÂS•@»ÔÑ^}n\_Ú–•žˆü!fÿþëãꫯšøüÎ{Nýýر»KÖª9;vì]óÿwÝåÐ.uµ'•9-uMg†´íܹ'Ž»ûÔŸÑðÓ%YÖãÇþP¥*€viº½Ø·“è <Ú´}'ú¡³§ËCÚh¿>ÝÈ«o½;<PưgÇŽ½ëzsf=6é9½BíSˤeŒ^«3ü»ÞÊŽcÏ:“9iŒûèkÆÿ?Ôdz£Àbèëñ«õgn†“@ÛèÙh/CÚj–uÖpZšž4D¢h9TçøñCkþ”ÑD{±ÏíÈÖ÷ðôÑø‡oÞWªrH÷cßçFPíÅtž†äý°ÍZn?´©Œ6ƯÃþ?ë“ÊÈz`^u¶û|ìª%ðìß}é2\¿@&MZ0ë±ÐŒÃ‡$™å¸òi©÷￾ÐòW_}U%õŸ[oýã¸òÊWU²`~Ô·s©å>yxßLZvžiìÆ—yã>i€lu´½k µžˆµ¡gžál;wîÉýA[í'¢XІœáµ;ãÿúç_ÿ뤜Z&-xÖEëï¯óÐC߈¼÷Ý7yÃÎð¢§Ûoÿóø¾ïûž\¯ú£òÀsõÕWÅòòѪW3Õ¥—>+¾þõ{h¹á ²©f‘mdH[S†ÁçÆojº*Àˆo¼)¾þõ{’ß.£–!mm3ÚãCÿ ¸í•ºGg\¯Ϭ©ìRÏñM;½ùÍonº LPu[­·çàÁßhº @Ãê`±ô¶‡hŸ/m¿/×rOZ>'Éú ž{ï=¼æß¯yí•ñàC÷$©°nY¾eêó7ýÊMñ›ÿâº$ë2¤ è-è­™CÚÞþkꨰ~àõ/ɵ\Þòš×^9õù™çu¯û™\+˜åóqg®åòæYs Ì <&%’Ùžo±T9Ä5<@o <@oºϹç”4~$h«›~å¦ÚÖU(ð”ñ¤ås’ÝT4CÚ€Þx€Þ*=¤miiéÔ߃AÙâJÕ£Éõ×mѶ`Û·ŸWhùåå£Õ¤>‹¸ÍÓ” <ãnpÚ&oƒ~ÿþëãꫯª¸6õ¨{›wîÜsêïÇŽÝ]º¼”æÒ–nƒÁš ÿŽ»»uAg¨¶YÚ†AhÞ ¬ •UÖørãËä)'ïºf™UÎ04­³^4ȧÓRO*—gHÝècyÊÉ»®&ë¬  £C·†F{6vîܳ®§cü±á¿ÇËÊzÝ´uÕ!o]ó–5®è¾›Gm§Ž^‰.ô|d œ§ ¡ ^“ßó4Êg5îS®«¬TA¤©íéDOÝR„‰I¡¤ ¡ €üæi°ÏÛÈoâ:™¶^›“—À“!U(I14€vÈÚ5|œÙ²ö]æ<ÃŒ¼ÓR—´ &ÂÄ¤íª².†³4£-Ã̺fÚ½ªÍ=-uÄéÐ3üSU|=“Ö—µÜè2yÊ™´LUuž§=Dõ›§qžºAßD/IUëœUnªõ–Ò–·ñ]¶‘>ëõÃçó.Wv™<ËÎ[—<=õÊ3¤m|™I¯I±®ºQnø÷iû%ë±Tûnœkxèµýû¯OVVžÀ1k™IÏ?^&ܤܿˆù·iÖ2)·y€ÞZ^>W_}UmëkÃõœº·¥ñž{ï=œ¼U)5-5@› <@o <@oͼ†çí¿v Žzöš×^9õù™çu¯û™d•HéÁ‡î™úüÌÀ3«€¶r Ð[Ð[…n>üwV/ÇxY³†„Í 2U÷ž´‘ú$EO©À“(ƃÆðï£Ï3ü+EÝúJЀl­ÒV$œ;v÷B…XtoyË/ÌýÚäCڨ߰{ïÖ[ÿ8®¼òU ×Úcîžá³ñ?4gß¾ÄáÃGâÀƒMWJ;pà`>|¤Ô=Ç’i›·Ç§ÈëvîÜSIÏÒ¤r³&TȺN)Å2©>tYŠ 34÷¶I3«M #ÓöEfiË++\Ì[öxý²^Ÿj™”†ÁÇP7ºàÀƒ±oß ’¡ä³´eÍÐVôuE×Yf¹¼Ëç)/Õ2© >´YAg¨Tà¡[Fƒ@×¶ Ð}U!§ŠÞ6ÅkšöÆ7þ|ÓU ¤:Žå3»•síµoˆˆGš®´Rã‡ê½éM¿ÔtàÑ“õõxDÑq‘ÃaoÛš4Íp\Çd æm'®¾.ÿȤT·pxXã²Ë.#GîŒ#GîÎzlܼɇ´W¢É†þ¬  š!ÐgoyË/L|®HçD™ÑRs÷ðLêrš§"y6¶mûgi˰µ,îÄ[oýã¸òÊW5\]ÞvsÙ6v©kxò i›·œy–iR›ÃΨ}û^‡|¨ÌðÞayî6­Ýè}xòö¸4Ù33mÝ;wîéD¯QU†ÁçÀƒMW€ž8pà`>|¤Ð’« ;5 i›5K[žræ]&ÅŠÆ_?úïY“*-§ z|(«HN^©ÚÈɇ´Í³\ª!mEfGKU÷”Ë4Ið ¨*‚Nj¥ý3|ÚÆ0\€vèBÐxDž»Ý–Y o|ãÏ7]¢[ÇãJOÛ‡q-Šk¯}CD<Òt5 vzxÈmÿþë›®wõÕWÕº>‡B.¿|_¡åŸùÌçFDÄw|ªŠê¬3<î,"ÇZ .ó¶ñžùÌçÆòòÑ*ª4‘ÀC%†æå壱ÿõ…ƒ@uÿ˜¶c-P·å壱wïű}ûyspÙ¾ý¼Â뛇Àénj”ª¬<÷èIµLj£A€þ+|ò¶÷ï¿~î¡pOBeor:,c4œd¨Tˤ$è,¶²=>UÙÐtú"UÏÎxǎݽ&H¥Z&•g>ó¹±wïÅ‚q:ø´åšÊR=^VVEžu-gZH.;+ÈTÝ{ÒFzt˜¦-=>sždÞ¬é{„U>¤-ëšž¬eæ)7…iåìܹ§’P5©Ü¬ý“u-SŠeRŸýû¯O^6ݳÿõqèÐ]¡¹{x&…—Y“dõôÌš]mÒóEÃHªrÆe…‹Ñò‹¯Ï¤kžR,“’€ÅÖ–q•i›ôü<ÌzMÞuYwÞ0O¨)[^ªeR|K™ SÇ(¡R& >u3Ì ze{t–—Ör‚\à¡¢wÌmËvÅrÍ5¯oº ½×•cmãÇ}nºãꫯrÃQ:¥ñÀÃâ1Ô`qÕ}·ÀC#ŠŽõ»ãŽO-ä0¹á _Ú`´mVôuuxhµá—byùè© ã"b¡†Ön7@[,/½{/ŽíÛÏ›ëäìöíç^ß<žJuÿœ<å¤Z&µÑ @{• >yÛzû÷_?÷P¸Nž¬™6©ŠúŒ—9ï:ò”“j™”€n*ÛãS• MW€Ó²Âıcw¯éaIUNªeRyæ3Ÿ{÷^,ètÜ0ø´åºëR=û÷_‡ÝÕxК»‡'ÏЯÔÃÃÆË+ZΤÙàÆËÌ[ç²õÉSÇ*÷UªeRÒãÐMméÑWjH[žÆï¬e¦ÍºV´¼yë“u¯™¼Rìƒy—ŸwßV±Lj‚@7” :uŒîY¨kxèžÑà3ÊÐ7€f•íÑY^>Zˉm‡F½óîøò×\óú”Õ  ®´ÇjwõÕW¹á(µx¨áh帶1¿IP¿ºa(:Ös8¤íŽ;>Ux8\Jæ”5z\+ú:½äi•ùMj‹”¿mÚ.Ú«KÇ0‡V~)–—žº0."ù±]?@ ËËGcïÞ‹cûöó42;`ÒoR[¤ømlãvÑ^eaÛ·ŸWx}óX¨ÀSÕM3GË*³ž<åÔ¹LFTú®l£¡­Çòq)~‡›ømó›Ó•9†åý^íßýÜCá*ðTiü >ïA=O9u.S7?*À"›·Ñ0È:˜;vwáƒ{žrê\¦NÏ|æscïÞ‹ý¨ÄéFC“×,¦”ªg§®ß6¿IPNÛŽas÷ðŒT¦ugdòœyÉ:C“·œY]ÙãeÍêoº×£Ïœ=˜,åÙÒ¼¿£©#Û0z /¿IV[z|æ<£ÅiÁ#O˜™%O9yê3©¬.Œû @}Šœ\LýÙ…ßW¿IÐo¥‡´•=eM*spõº"å;vw'ÔôÛu×½µ–õøªP×1l’ä“äÒ6yËq0n§a·æÍ7ßêz5hó„Mó›ýVù,myǰ—gôÿó”C÷\~ù¾8tè.?2†÷DIq_¿£³ùM‚´RÃÊX¸YÚŠœáÚ¹sO®å‹Ë›Tnžrê\¦NÙýû¯odým²ÿõqèÐ]7¦Éû™ªÜ:Ûü&A9m;†UÚÃ3i*ÈI=8Ózwò–3OR4òÇË-s Ò¬rê\¦nή‹lÞ³¡ãS3GÄÌ 0¾LU²ȼë¯û·ÍoÓ–q¥OÞáj)ÊK±®ÑÝÊÖ§Ìò)&V¨s™&ø‘IÙFBÊßȲϻ\Þ囸mó›Ó•9†ÕÑ“Zù5hëÙP²MúMj ¿Ô­ì1lyùh-'QôλãË_sÍëSV ŽeíPö7©-|ž¨[W>sµ»úê«ÜÜ €Vð›ý·p³´‹CO m+;¹}ûy¹–žÝjó6ÔÅý!ð”ÔÆ/Ãöíç­éžŸÕU¿ÿõk¶£ÛP—ñ¶Ý–$ðÌšï>ëžE^ôKÞ‘HCó†ÐÒgüf¡Y7Í;§þ¬;6Ïs·dšå=`’¼!f|DR†´ÕhRã¿‹=\y‚̬eRmwžrR-S¤N)ʘUŸ:·«®ý“÷nðmÚ®?EÊÈ*kÚIª<'²æ©W_eËIù^ù¬©W•߯¬åæ]¦hR½ïyÊÊ:6´íýÊ[N—é®ägÚ1ÅpZyy~œ³ü³¾h)¾ “~hòôõQªíÎSNªeŠÔ©¬¶mW]ûgÚIiëor»òÔ9ïv +«®íÊZSÓúzÜHUNÞÑY럵ª>‡yËNõûZÕûžgù¼e4õ~å-§‹¿Ët[åÓR;vwéÌhÿOúbŒÿ6;wîY·lÕ_„"¤:êS‡YgðSlwžrR-S¦N)Êhr»º¸ê,'¥6ퟔ믪Ü>7¼_Õ¬kžeæ]Wª÷=åòEõõû5©,ÏÜ=<ã̈tgñª–·žUû ÛTV_ßëTìŸéÚ¶æ9k<ëDǬò)¯ì~NÕ[@:öÿüªØwu]dŸB—êZµ¹ÏðÔ¦/â¼gŽªª›ö Õó^O·HCòÔ¹k OØ™´\ÞÇ(§è~®³g$¥I߯<ß©¶}ïfÕgÞ¡i¬ªêý­ú"ûÑ÷=ëý,²]©êÚÆcA½š´ MoD›>n&JWd Yhz˜Ù,yêÜÅí•çx6i¬}[Žƒ}W×°´ºåýN¤N³ê“÷{×åc ù´ésÛUí¡‡§¤igðÝ_<>À¼#ªÑÛÀSô‡ciéœJ~lü€1Êç5üíªú-Xd½Ò6OØ7ýû|±TâõdYZ:{êóƒÁý5Õ Y=†Á¤ÑËÀ3Ü×poÍ`ìuÉ«²€¦ïÄ¥¥ÁÔç…P k„€4zxª’õó>­oXûÁJaÖ>œÞÓˆªè2 ]BV¸&gHP''Gê³P§‰éõî´×hȆŸªƒÏ´Ï¬kÇ¥8NT5ô€õzxFg»ÉÓÀýá)Ú ö£¥qÛÃLÙàãóÝ1ï÷½Lï°P¿^žI Ëi Î2ÑÑ׺Éd·Ÿ2¡gœF´Gùù{‡Ç¿ûY¿“×ãw …^(k0¸¿¶an@=ªøNgõ™Y'Úœ ¨žÀ¤èí9]Ö}¦˜…†ÔsòbéÑu }ϧ-똆À3èínªú{›Ý“ãxÐ6äbR½Y½:]îÅ©’ÐÀÉz4Xà´ÑïË"…'Hª%ðШa¯NÄR,-­þ­ï!gœ¡mÕx Bzy`½ÓçÔ#±x!'ǀ騘á*,ºI'br4Ô#LU P€dÖ‡›aC~q®É)à €ô¨Á¬FŒ³³tEV •5éÀÒ’S„ëyÒx &ÎÜÒv³ÂLÄ움.ꤩ =é<Ð*Ôm<àÌÆ U í¨‘^š2éÚšùÊrê — §„Ñ}ÈKè¡.£!§ìçMÈi†ÐPžÀSBÖ‰D)¤0 :BN?8IPŽÀ Ѐ!µT½9BN8°Jà†L =)Q¶7g¼WÚç® m˜ŸÀÐAe‚Ž^œnzæ#ð@ƒôòPÔ¼AGÈ`Q <Ð0×óÇHpVËrè½<tÎjf‹wAaÓPpIDATò0èèÅü„`Ñ <ÐA‹6 Sª #ä°¨í˜0JàZ+EÐr`Õ<¡G/ÐtTŸÏØ– :Bdz€E$ð@§-ÅÒÒ W¡gÞ'ä@u„ Ëè°ÕFHBOѰ#ä@q}îÈ"ðË;„Íôц¡mÀ"xJo|ASº|ÆvV½õâ@5„`Q<%dð… ê6ÚéRè™Ö«#ä@=º|² /¨Õ¤ #ä@3І½<@×<Ð]é寛í ô}&ð@Ï´uˆÊ°NB´“Ðô•À=4l¸ ÿÞ¤a=Vï$ä@›µõ„ @š®Æðlëéß¿&øÔiiéœGÿœKÖå>a: Èqcü¸ÐFô\]¡çtÈqœ :@·=@ŸÒ=2iL}UÃT²®ÇYZ:ûÑ¡k†Ä@—Þô…À "Õu=“&hË5C@:y&0ÚLàž™Öð6XŠžµ6³š ý–÷¸!ôm%ð@M >³‚ʬé£X,ó q€ ºø½x g†AeüÿY×õ¬>?~aòRæò§Ët`QÍ:Y’5Á¤cÐ]ÿ^ <Ð#ÓfJÊ:#3¾üjceðèsÙå:°ØÆO–ŒŠƒ€öëÃ÷º·§hòìZR…ydœq Ç´à3ISä;fA³ºzzxFw|ž7¡èòÐe>ß@JkƒÏ`ÆÒKÉAMÜ\ú¬'zxªRäÆjnÂF[ùlMr ‚v›4¤½Ëžòœ•r €öx*І!Cmš§.Ùª¨KžÀ=Åt¿÷˼Ô%›ºdS—ùAuñeS—lêrzÝ]·¡é Ôiiéœ^¼i0¯¶¸ÅäýÓ…ïu/Ïð>yÓpÑå¡­¦}~}¶ª9Aÿôá{ÝÛ!mÙÓívÿ ƒY|–&eÝïËq º­ëßá^öðÐýfUì—löK6û%›ý’Í~Éf¿d³_²Ù/Ùì—r · · ·žÄŒ±\Ï>Éf¿d³_²Ù/Ùì—löK6û%›ý’Í~éè-è-gÛ”Vµ<4©hÛµÍí]§ á Ôƒûr½©E—€&ÍvÚÜÞxˆˆvŸ >}›°Aà õgç`^›š®í2<³7 AÃ4zÆo4Mz|øÜ°œÑeF×Qv½ÓÊÏ’r»ÆËSÏYëMVùä'ð$’õÐÃãWVP'ÓLÖã³Ö;-å]ï<Êlר¼û¡ÈvMÚ¾2Û BWÛ»OA“ÎÎ¥Z nÓÝ£åé )jR9y¯ó*²]ã½9©Ö;úXžž%¿!@]¦ËÒöö®À3‡Y‚"ÏtQ™ž•å ˽îhVoLEzrRšT¾ß  yŽ…EžkšÀ@!“z$&Mx0~æ/ëï£å]ïèseÃΤkoÆ—JÑ#4©ü”=K‹Là YÏužáX³†®?–g¨[‘°St»Êî‡IåéÅrÊ3-5æb~¦x¨D]!¤©°#dtƒÀô–ÀôVg'-¸îº·6] å:ÙÃ#ìyt®‡çšk^ßt€ŽèT°Ñ©žåå£MWèNõð!ð½%ð½%ð½%ð½µn–¶K镱s瞪0¿Ké•ë[x®þ‰ŸŒø‰Ÿ¬¥BU2¤ è­M¯ûµÛp5Ò[ŠˆAÓ•¨Âÿ¸ÅØÒýgålIEND®B`‚snd-16.1/pix/sceq24.png0000644000076400007640000000140611147553270012750 0ustar bilbil‰PNG  IHDR®‚Õ©3PLTEÿÿÿÀÀÀ€€€ÐÐÐ ```PPP   ààà@@@pppððð°°°000^Q(I pHYs  šœtIME× ,ý¥P£fIDATXÃÕX‹’ƒ $¼Ä@hÿÿk¨òªx^Õ™3mÕØeÝ$‹ÊØ—ê~¿›,Ï›üv˜7Ñ}=[œª Ï@yþ†Æ€뎊µ @aœŠ«3i2ŒëëÙz6 • v‚ðh”¦i’‰ñåC e”›ÊºaÏ&¹Á~«‚²¼¡’´äSúÝ0$Ó=ftœ3’̲Ì?EuÊ¿ç,’Óa!„eŽú¥ö€sþW£C Êšþ E›–ùžrnùÿ±Ø#„ r{-b—ñµö„üÀèhC Úk\_*XpdXãW¡¦WëÖVYª ñj£Ã·>(êN-~êÒU}l2§Ž¢]Š`<Æ(Ñ!õœpŽÑ‚?¤Ër½Q±¡÷Œù2öħ†vˆüM8wH'£ñIµ‘Žén~)ÝF÷|©R­BJŸg‡”.Yëå’£gÇð ¿ m ¿MUJ÷ˆÑ–#'MO7#µÆù,ÖøÇÕ³&ûò–Ñ‘ZŠaÏØtjãŠnƒÔÑ寖÷ú]hcšW|yÛèF‚V)²‡É!HüiZ¤–i‘2_ðÇt…aMŽ °òåm£˜k\¸kÄéÍX‹¿£.µ™ÌäËÛF7X‡÷mYõ¨»ú Ÿ†Â„ˆÛ›gËè~wi$Û‘Öî’§ž(n³ |÷CŸë—[FvÛϬâ–eàúÛô5oŸ¼«VqÍ^+WޤꚷàƒölÕêÅÚeàÒR+y£³ÅF’^â¶ËÀÅC®rúË­wgt×Ë œ7”öt+£¼ûʵyÓx3ÝQÞ~zÿþyÃÑIEND®B`‚snd-16.1/pix/m5fm2.png0000644000076400007640000010512611147553267012607 0ustar bilbil‰PNG  IHDR–Ãï ñsRGB®Îé pHYsÂÂnÐu>tIMEØ 09åö IDATxÚܽwxGò?\=³9¯´Ê9#‰$r09'ƒmðml°}gß9Ýíó9ž}œcl09猑£ „Ê9¯¤ÕJ›ó„~ÿX…U"8}ï÷ÎÃóšéîééꮪOUu5ÂC—  x” c¶¹¾Î/$z«Ë¶ß¿O³ùÒGîÛC×úy-ÿ=yäþ $ìµ~Ç^›Æåàr…MuÆ@;meJT­]‡û¶ßûÄ„~¥a…>&ßÿ—' ;†í:ÄÀ}?ê›üŒÇyÎÒ£p¯3Æ“¨ÐK–‚÷(ÓÙó-ÝÚĽ}þß êƒ»áI*Ôc;¨Kzü†®UP;-°ÃÇ´ßé ÖãO¶kû¨}{–ÇÅ\Ï…îñ?îÞÌëêÚ1|ßùúX”øáVóÃ],ÝËM†ê¥ÿjœüì³Ïzôƒðøôˆ|{Œ À”“Ì$Y`(Úåp$˜EŒ±ÃîàpMQ$I`Œ)—‹äpLÕjŠDÈlÐs¸\‚@À0LyA.åtHä †rR5åÅ /B¨²(Ïl2ÔVWx«| ’ôè.¼—u3íº·R%–H)—+ýúU«ÙìãçW^Z–÷î­ëç ¾AžŸ‘Ÿ™±jÕª†Úª„Äx@ä¾Ý;ëËË"bã0Æ×­K9yQ®°è˜>¦ïð?¢÷›=¤M9D_Þ…„,Ë–å{ûøµÏSt_ÎÙëG]lüqÍÍÔ«£çr:¾ýú˺ò¢ÚÊZ€§ôö€W.ë4µ /Õ·_|6aêô;7Rk+ŠÍ­Úc‡U×U6”—E'$V”—åÞIŠ‹@û·oÊ+*5êZr³rú%ö_³òß”“ª)©ŠNˆß±é'.´ZL!a.·]" ŠÒÒs§=âÒ©”¨~ñ§N ¯.-Ë”§˜>gvTl¬ÊχËz®Ô?®þÇÇ …dúÍ[:!6."(2<íÚõFuÈ‘#çÌ›{ëæÕ~ H§o6öè|¸7én0èø|~_u8]¸*AFÇÇõB$Ì"»©s¥2”‹l²æÜ!MñÔÙ³*KKÓîŒï—°`ñ³€:ÛÏÏLýƒ[›5…üÇo>KèŸÄå“qû÷1€Ø´f%M¹ H¿~Õ]eÖ¼YJU òûÿ~Í2.1W8mμ[WO`¿ÀÀɳžèÊŠ ˆŒ|ëoŸ „ê«jVSTd¤€ä „B‰D¨Py˽¼)§ƒ+u˜ÿ½!ÂncBÂÃÃ#cN9¢ôñ5fTzú-0‘eñ_| L·a7ñù«ÉQ/oŸûàtS^â{t¥½ˆìMLºi ´ËFråíßà©p", I. B‘°¨¼òØ©%_4qúw UUÀá&ÍœåpÒ7.žá døÎõ+ÓgLçò¸DAI)Æ BHé‚Yöü‘Ãúó\ž RÒ/½ðO>@%……‡÷n`zîãωåÊÎB\”uó O¬ô fç¦[cÂÂøËPc÷ŸãªÒüÓǺYýß/Ú…1»jù×»·mmlPcŒ×ÿôƒ®µµ!Â>ª=ÿd­ææ‡©Lê§5ë’L0`öœé׬ܱn¥J)S*}hé?›vQ‰EŸŸíÛ5ø6á‡zSd:ÐBO麂*Ÿ>vÈn2<µäeÌ2ŹñƒGyN‹N›•‘5rÂø¦úÚ°è†a5 Uz¹¼¬ŒÅ„B.›4mz]mP(Tùú°Y·ÓÊkŠ%âãúHZUU^\˜‘4d¢@ ÕjJ˸¤ŠŠ@\:N"3Žv9K‹rù|!Kry5U™ÔÛÛ57Ôº0 BYú-›7¾ýÞ?ÀblqPv–”yË$É3›Í>ÁåI€¡)†¦x=Äçïkèé…„¸r":”º® *öXyÈ´!EÙ ÌyÊN² ƒÛ!?ë¡1yBRÀ´ëJž¨Ô£o˜nNÈf5ˆÄ  ýàåB¹ì.µµÀ¶3’®ÅXòÒ:ƒ±‡¢Ø ÿYµ¾5íʽÁ T©JÙ][½ÒÎú…O™³@¯ku½‹f{è_Ý À8)’Ïý5Öú•ü*½C{èa_n[˜¡ïß1ëɧø|AÆ£†T*¥©W®ÍxüÉÓ'Ù®’âÜœ¬ŒyO-ö°†³žôþƒ‡…8íÆ«ÏÌS-î»v—ÓÔÔ@»h®Dà (ŒÙ¦†Z—ÍÉ“Éý}•±ÆôO b÷Öþaav'€A:l—Ãân¼Y§3ôûölÏLÏ«ÄcFM zñõ?€Ãd0¶š†ˆøî¿Ë% ÿ£Æž0Ùýj‡Ý&m3Ùe¸°T»é¼1›Œ¥oðÃ/ÿaHôÕÊ娽eó”ysÅR9\iúœª’’ˆ¸D.{/ónL|¢H$l÷Jb—ÃyàÐ^`‰¹sg(½ý‹r2óó c®m(÷ ŒÀÕeEá1 H]]Þ5ÖV„F¸q‹®µÁË;̺fŽ@’‘W„ÝW!‰HÕ55©Ô¨iŒIŒÈß0ëáUø_ÔK{Bûvec@,°¸ÝÒS`xhp´Ðsæ¢ößD×p×§¨+¦D€Ý2œèŠgÚ^á´šùb©G­Ž·âšî[¤u!áÿÁeÑ5J¼ž‘¢Nè†. ¢}€!FêhOß/òøG¶ÓÌý›ôh‡hD8-&»Å„0 §ÕÚÒ L @U0fs²ïåçæ±, êsî•hšc67''?¿¨3kº× üÇÞïá¬o›@÷§__¶GÒµzÕåÚÚ¬­ªØ¿o“] àôä^¨+Î?vú”LJNœ87¢_¼g•KgN߸z-8ÂwòÔ¹‡{ûÚUD\S[ûÆ[ï ÍÚ·kËO\±X$ÔWÖ,~nÉþ½;&ŒXXZ5uæSwnݰ™ušVµÙÀ~ðÏÛÍ@èÑàÿ ·¼o—z³¬·Ýa(Gûo¦«w¢§Ë¢§ÅÁ˜ÙºaÍlÀ˜ª«*v9,)ɇܞ‡ ßëáâ`Üÿn]¿ÔÜPƒ1s`ç&§Ý‚1shÿ.‹Iß^c̶j0fY†úæ‹+ËŠS’O²,}åü©ì;·ÎÛ1{hï®WÛÕ‹ÒÙŸ‡p#°¿Øíð{_D¡G‡×¿%ú`MГ—²4Cr8dPh—Ï×ZÝ÷–íinÅS4 € ‡Ã„H’Ãõsà¥òghæâуzó͈è…€:¶sgmEµT¦0M¹·ÓBƒ|ÄqWŸ¥§Œx`(ÊùíÃ˰}WPÑ-À?Ê7tÖåñù MSNûk/=oÒéhg[m«±«È$°ÅlV×U€FÓàt:«Ùärv‰\¢)êÔá}çNSzù;l¶A£'/XòBÒð!F£¾¢¼ŒÄñÓt­š>âšÀõò]˜¡z ÂlߣÚö —Óù[£Fâá¾õöy½ôISWíY@"“µ´´ˆ|eÙ«.O*æÑ4cn5ø(ä=tÂa³é &𸛖^Qœo7XDb¡§ÝuúÕ&»=?§4ýÎ]»ÝþÓ÷ߟ¿p9í򬯯~qÑ5%U[7mœ¼I<ümÐG€(Ñ•/yÇ=«]ah×2·¯ôs;Ùå*+È‹Jä %þ^¨Ñdh•)¼ïÃHÛ1fû朸‡*‹ï»Ì»@FŒc`1˶/{Ok*²[,žC£Ó45×Õ`Ü®õ`¶›&UYQ ˆÔÔ×¥œ»Úܨî:á0¾v«©AÝ]œcæ>\+:q€P"{4~‹~§Å'UHúzÔ5Øíze@$å°oZÿí+ ³s"cc0Ëž;|àÞÝLD"?ß#»¶_:z ¤¸€#øúù?pîߺyCÛXºé‡Uaáab‰ÄSctÚ­wm4Ì“/¥œ:vè@u]ãÕs'GŒO’dûHu6»â¿Ë‡I:x`gèÀ„ Gù+ÊŽ˜v®_³F(DÅÄu±øt[1]¼Ü€€xt~ø;‘õéSêõAb†ÒëZ?±ÿÀA¥ÅÉÇŽÄFG' wúЮøþýí,óÖçß° [’{§·=Ýa¾LÌUy{Û,f…\!KºêH’Ãá¹C]Y̲c'O™ÝËÛûê¥Ë!áQgŽ[üÒ‹Ï^~âé'S/8¬Ì¬§ E¾'5ÀÊi4èîåú‡ßQ«ë뫪BB*J‹x@Ó>~ô€F“©•“<¸zé ÈA±cívûªïVäfæVUTLˆ6v¢ÜË€µ; åbö¹%K·oÞTYV\˜{/ç^‡CΚ1ÐÈ‘v»Íêp>òæB‚ÄÓN;W üõ»‡KòW±´qzè¢må6ë¾m;æ.˜«Rù@NÖÝ·ßý€ ÉV¬$8ܤÁC†Ç Åß~ùÑ×l¡HÔcÇ 2n¥b–‰0¨µ¹9rä°·>øårúøxûûŽ·—\*á˜ãt:ŠóóµÍ͘¡%ñ½Ü<³Þ0zÜDmC* äãþu`÷Ž¡Ã‡EÇ%lÛ¸ÎÇ'ÐßÇWΗšÌ¶Û¶ 6HÌrä2ùÜ…‹æ.\d7ë…b‰NÛ¼ïþÊšÚÇÆŽUùùwež¸O f!„ÐoB¿Þ\’?G&ö*˜ÞvÕe‡÷îQúGúxG +NOæ‘ÊþI‰ƒ†U”æ]¸‘ªTŒ8^îÕgÄ*ËÒGì6étsŸ˜åë~QME~XÔ€nÊí¡ûìåp1c‡&DDÅ\=wN PrIrÜ„‰ˆàØÌ­ž„Çà›©W¤reÿÄ1ê[jëÕ!!¡ …—g¤«Ýn­­©VH UŸ/ê# ö·¶n?ä>Å_ú^OhÏö€kž`Ž`Üb¦¡¦DåÂë>4l†Söâ§÷ïÁíV , DÃ'‰²½Å%ÿ?à” ]„’Ë{¤ZägŸ}Ú6ˆq{4m›\Ô4¨NJ$y˜‰‘T¡"9ÜÞìÚN»ãÑ «Íf·Y¹A”ËA’$r¹œ Mˆ@a³Z’ «4fK îéµ‰Ü aÜÒ¬Kå˜e›ÕêzµB&!8ÜŒŒ;AAžH9q4¯  ??—rÑzƒÁÛK‰w,‘zñÌÙä£6»5$,!(.,tZÍ2…WkKËúïW^½r¥¢¬dpÒP7tÙ¶y}Òa.§ãÓ|ÀÂÂÂÝíäffß %9@¨¤ ‡a‰D¶òÛå ‰‰Ðjµ|óå?ÇOœâŽøäã†Æç ºñ›ïV|{;ýJav¶ÜËûBʱKW.•å$Ç×/`Ï®mé·n 9ê‘&ÑÍŠ»ª!©”ÏåôÝ—§ñ…⎖**J¾üâ½];Üòã·&}Ëþí›ÜµŽìÛyóêå-kWët­¯¿ôœÙhôlåÜ™Óç.œÓ›­[6¬ÑŒ‡À,‹o§ß¹réü‘ý{Šó2×®ZåÑ_ uuuýã%‡‡¤^»j6·éGf£þnvö¼ xïVêuúà¾ÝG/oÕ›ï¼+r–,]æ¦_Ue…¿¿/æñCFŽ4hPLJ_½r}ìäÙ<¡Ð]²ººÚØÚj0ø©P(@,–Œ3¾®ºÒ]~éÒ¯_½ØÑ½‹çÏ€Ëå”ÊÅ}ïŸKßx[*áÿí¿|ðÜKo&cÆŒ |TÆÀéb Eî­\$Ke}ó¢žÛØ»o°++-{yé_£cc­3˵Ø\îgûúùùùœ>ºýÕ7_s¸œžíêtúOý!8$dèaNŠ–Èdn±êp:üü£Ã£ M-O.xÂýŠs)§¦MŸIp8 Ʊq €1$_(’ÉÜv2ÄbCÜÔ›i4*ß?•7M¹8\_ vPµ1jH¿u3¶_l››…'ày웬«.õˆW†ÀàpD–ròø¢^8u*yîÜÇÀᤠòrÃ"£@(—•W@iIÑÍ«—š[TR‰^¯rx'Ž$+…ü±Ó';læc{2¬éñ§žá D"‰8üG•¸œ>¤BϨûÞÑBo†_ºÍ 6ü´.ÈÏ/,8lú“ ´­º6îjÔµh‡ŒŸ0xÀÛwišÊÉÉV×6 IX´ÿÔiS“íRH½ärÅè©3Y–Å E Äç’.šM<‘ÜC{·cÌX-ÖòòÒ!C†*¼¼ëjj¶lÞ \ÛÒ^ehÆØÝiƒÁhµ90Dé7¯ûé̆»wnûÒͽwQ”¾UïþM1´ÁhôµY¶ª«ª=-¢,C;í¶ŠÒÂYÓg6TU9í6¾P˜å mÊ-©D±q •e%ûöì õ|vÙ+`³šÏM‘Êdc' “Ê<¾(ŠbÙG’#ºF1u³‘¢¾…Ðc3wÛŸ¦£D@PØ'Ÿ}±ôõ?ÙhWQnN§ÜFØAÑ åà`ÌÖUW[ÍZ‹®‘$ô åTùø.{óý…K^)ohÒ4iìV+"¹.Õ¨®w:ì@À¸v«iß®-Uå•i7ÏÖV˽¼–½òâ²_CÇnwjšÝïâr96« Œf„ñ­›79:"ÌÿzûÎa¢sGŒ1¢¶®ÎýÛj1{Æ· 6‚¦™VM㽜lpÚ,1|ÄÜÌŒúÚz›ÅI…†»ýP&³9:6j*JS¯_ž6{žï­ÔKWϦˆD _ß Úi-)¯Qù„òùm!€ÍMM&}Ë£*¤œ®Kuõô©…«+*‚¢¢zÐÀ»-ö üܬê’òÙOΗË%b±@Èç;,&‹Ùì%’‘1ÓæFÂ8 (I”B.Gåï}'-M­n8xérzy{Ë…¼²¢§ÝþØÄq……e,ÃÒ Ó!D¾òÆ;›Ö¯?ù …Ò‹Cœì`>*ï”Ge ¥Åf}qÙŸü䲃»÷`Ö2yÆ<†ef?¹c¶¤°ÄÝa‰ ÷‹¿”r 3´ëö­+aÁA~þîÉ=ÞÜ›—Ο1{÷ÆMÇŠŒ>vBDtjµY•>þ E¥_½4w^Ûfñ gÏ,ûÓëóÕ¾O>qtÒÌ'X–­­.Û´n•Ÿoàœ'øßÍðÕâ’bá}ƒÇ&‹@&éËÙÔÁG´Çs¢´ìô=ÙF¡@ÑîBï›7h-– £‡ 9Þ ÓK>"H§Íœét9$—'Ô·hI*”*4ÉÞ¹v©¤Ùúø„áJÿ@“ÉxévN¤7oÐQ­Í^>&½F"Wi3é…R9B„Qß,Wú²´“àðu­Z‹Ù„1æðxAA¡4ålljTÈd‰ÄEQ|v‹@(ÀN»­] )§[£¶™M|¡€äð:?³˜¦—ßÎQÑÏ…(?̸åw¯$d{sðâ>轩?·N§« ~_o\OÊöˆE?7(·7€Ôþrœ“àò;C¹ÍvS+_ Æ!—ß«³ w“˜qç…é™Å{¢7–eÜùPÊŽ‹ÚÙ2f(ÀîG÷£¥Éh¨¯¯W*¡ºš½É¨Ó\.—¤Íä u5Õr…Òb6f޾鰹”^ŠúÚ*±DJdkS#"ȺÊ2¥ÊWÛØ ×ëdrEÇëÊK‹1͈$⢂{©ôöÍÔÐðH§ÍRYY^\˜—‘™]UZÞªir9mX¡H’›u—ËãoÙ¸~ĨQ4åºyýŠŸÀ–ë† 6‹ùË/>¿|ñ¢·@ê|/çÎw+VzKx!a%…9«V®®.+N0ˆã‘ÀÄ`п¶ôùÜ´kÍš–ÄAƒS/žN½pºN]Ûo÷ÚU·nßL>z¸¥¥%qÀÀŽ*™?|ûuznzE^~Òð‘GíºvñrqQa¿ÄÄÛ¶ßK¿»vú°ˆˆÀÀ û™í³23׬ørËæµWR’1fNìß±ví÷kÖþPRPàaAp`×–•«V®[¿éæå ”þmÛŽ6oÝüý7 CÕ×ÕîX¿jǶï¶o\ÏPTŸs ¡©ñ‡Õ+Ý:ÔúV_½võúõË uUî§9·ÓJŠ hšÚüÓê&mKnAÎþ};’Ož´X,páâùÖæÆÞ§à^öçŸ|TYYá9]$RÉŽÛ0ËžI9Åçñ¿ùæß] ‡/¨®©)-/:cê¸)“‡WP ÓëØÚš*]‹öÊ…SêšZ–e*+*B‘H"»vñ,`¶(7ké‹Ïùõ×ûŽ \®–íò+µz-CÑ9wÓ>ûüó~ e%E]f§^·fÝÆ­X›_R …ÅϼôºÍFÓ4óü;Fù2 IDATŸßý­B"&M™êYÅ? àëÕë>úà “ÙB‚|~éË<ÂÅçñþôæ[/¿ó—‘Ã2잊ªâ{o¿ÿOööÍ+êšjTöæâçÊu'=£+wbâ,z~±ò›Ï(ÌΘ<5$:º(?+7+[£®~þµwëëÔï¯K^~õ>¶Ú~qqѱ±nL¾ôÅež…Î^8÷·þŲ ÷É…‹Üœæü©£b‘ÈmIâñï𡺢ð›U«<0~⤎Æý‚"BCìÛ=eò4‚€eË^9—|xÑ’WÁ!(,á \;‡#¦iÆá¢0Í2¯üéåC‡ö¼ñöûn¨î­ò’ˆ:fØ-¦ýûqy<¡Tø¯ß]°à’Ë›1û©ÿö×ð¨˜7ß~Ï“Q‡FD@uYñðý`ÒÄÉ‹çÍùü‹åndér¹ø$øøvq•À• )ƒGŒ¡Ðû•%‹Ö¯ÝÜΪ‚Âbêeï8áÌébÛ†`䨉$IÚí.‚äòGÛZ† cæròñgÿ¸dÜÄÉ©×Ïçß¹‘™–*WH’kÐè.¤¤L™8Î#íT/³˜ÓÞ™¢‚‚Ó'.n۹ݯ €ÕjšBwü¤I[¿ûzʯo]»Òb0[­V ¸|§ÝªÑë§/X [¬V«Ù\QVZUVÒÔ¨žX|ýêå Ð§‹bi*8"º¶ªXÖ`¶¥¤œÞºqƒÙlær€¥œ m5ˆ°˜éñM(.Ì“K¥ÀÐ.§ÃáîžÍj9sâð³Ï¿L9íùwo=÷ÇçJòr º–äcûŸzêé o¿3§Ž¹±D'/miÖ4VÌ}f‰É¨?vüÈO»v¥eÞÈÏË€s'Ï¿°ç€T勽å&NkllÔi›·ì>´q×z»Í7._˜9kv¯½#%áξӱ")§a·ÿcw \–fÏ=™Ð/04” 8xéõÄ¡#£û«­m(-/?›r|Ùk¯:Ú¿¿/ãÆØf³º+¼}æ<1奖´‹kBå«2hëãȰˆ¥ï|øÒ[卵N¶ZlîœY.‡…ÃåZ-f‚ÃåQ4ݬQ§Ý>Ÿ“}³¬¢ ³¸©¾zÅêíÞÁÒt«Ñ8vÂÔ“vÚ­V’dçÌÿ滓Je€8|˜¥)†a1Æ55uI#FÝ·×dw`Š¢#£bÀb6íØ¼þñ§ÿˆÒ4·Èý£cûí?|LQAžÉJ 3aâ¬Y55u€Ù³§“µÍMТmÞ´q}ÿ!Ì&“Óåâñø±<8,Òi³àì{Y¾mX¶­ÿ¡¦¦òs²>¨PZÍ:Êåh4hÌz½RÈb¬kmæ …\¿§0r3ÒÎ ÖR™‚¡)’ÃÝ»mëâçdÞ‡Åvîôá'½è¤¼â‹Ïæ.˜§òVPv{MMuaaáÄñ©kª I*Îc"ѽŒ,‡ÕÜ5wEwvªV«++*ÚæêÎfÍ™{$9eÙ²WöìÚéçï+”Š.\(É÷ïÞî«Pð¸|™Ò‡¦ÚvbÆïæ37¯_MH$K¹<®Õj €Á£ÆêL¶! 1pÐØqã7¯ý‘Ë%CƒüÃ#"bâA<¾`‹aiŠÖ¨+£ŸZ€kª+KJªÖ¬[£‹^xåÍ…tËw«ccÃE ¯qÆýûŸˆ‰}òÉ'¡’’bmKËóK–tZL™·mÝÌq^yùσ†ZÿÃFŽ™0dÄ(ôü K:Œ»½¥I&–JÃ##³²ó¢"M‰I£ÆO˜’—W¸`Ñ"±X‚0;}öܾ‡žAˆP[S½ïàA‰|̸1ýú'f¦¥ffÝ ñõlúd©\ÕN Ÿ=q@Ýb’qù¡Q¡#ÇNHO¿¡®WG…‡ 6³lZÚ £¶eÒŒY¡è>i«¶)+3kÚÌYH§Q{ùu×µ´õ> ƒ[4 ‰X,S ‡ÃN9™!„YLÓ4‡ÃéL ÇÐ$AB˜¥Aº‹á¶ð5ÖépÙÍÍJ߈6nŽi‚àx<öêÆ=rëô‚[Ôµår¥¯D*{x\XZZM]¬f‹X*éFBö¾!Û¨ÝÇpÚ7dã®qD¿sz]¶`åß V{X‚ 1Æ,ËAÓ4·ÝNS.c4MQÍçó»’[-&–f9|—Ëåp8V³ „HÜÝæÒ¢m2ëZƒÂ"y!fÙ’¢üðÈhP”q']!éZjC#‡z!¢®ÿ 3PçœCf½ž/·Çî¡®=(w÷KӠθy#"" ”u;­¦²¢¡¼¼¥Eãâ.pòø‘¸¸x“A·iãúò²’ø„„ÜÜ{‰„Ççgffq8œÔ+W¢cãZ[[o§§EDDzjJ[ׯ¿y需Çñ Ù²~]^Æ­²‚@à¥òë4hä”—•‡†_»tŽÇå­[½b섉,ËœJ>žzýÊÝ´‹ù÷²Z´:^g2T¾¾Ç ûÕ—ÓfÍ©,/»v1% ðÃwÿ2ëñùpçvú®µ+3ï¦[­f•ÿ·_}™~÷Vy^Öc=—ÄÕ+×¾ûþû´×$2YIAΙ”3y¹y:]mtLbG¡²â¢ï¾ùB©Rž8vzðAg“M† gR†ÙP_cs8 Š*ªë“’’:bgÚÖÐÉcÇîfdû©¼¤²K^<¼s{…®5Ð[7xȈQV¯ð¸f3{îܘ¸øV·GM†ŒEbAzÆõI3fƒ/œ9=ÉË Ãû(Úý>©þ¾^ Ë|¿jÅo¿ÝÒÒ|pïNšP‰TZYZè«Ú½s«B&º|ùR¿ø~ž-_ºp>>1&iØ 7.ŸL $’§Ÿ~† ’ô ºÄQ±ëÖ¬5f|qQñØñ“0¦ªŠ ƒ£b´M b‘èÙW^s›ÁO=$•yÉå^€ _*‰‹KˆŽ’ÉÛÂγ³³‡Žš@„J¥PzûÆõø‡%/!’˜À\ßEQ/<¿„KýàC‹ÅîÙ2årú† EâisÄq8ÆÝrë"¾@—÷ý¿š8u:ûî‚ |UÞê†ìŒ´œŒÛN»M¡ô  ò­vÇðcϧ$»\N'í€ú†æœ{¹@²7ƒ•(„"—Ç@.§ƒ×Å$†ÀIQ­-ZÄãs"€Ó5'˜P,åry…9yÞþ!b‰44"êÓ}Lrž@F½žeY‘XÚAÂÎ=ìaQ‰@ù™™Ã†'ù"•—jÛÚ-©ÉÇ1&‚£R(w¬ÿ)0 @Ò=jßו}&Š@ Ó¹}ëPQVñí7Ÿÿ´r¥Q׿S¬©®¶™c›²vå×›×|››™Aˆ ID9]v§«Å :v"A•5õ]ô Þb2ØÌæŸV­¥œöš’²}»¶§^9׳ B¾¸¶®žCƬÉf6bdá½l›Ó) mÊdsŽÝn× ÐØØÈДÅIûU”ñ9:///¨«¯³˜i©~õe½ÞduP@b°Ù,Ý^ÊДÍnm‹Îår€Ùhé¶Òn\×4WÍœ3³ÌÉã6mÝ)ð9qì(\»xvÖü§zBû6u¦¦°\,&SçÍ]üÒ¢1sæØm–V­fõªU3æÎêWPTÔ‡ïß7à¸×è«6’‡GD}ð᧯¿÷žÜË«ÝvK9í³þþ~o}ðɲ·Þ»ví ãt04 f»!ìp:Ü€Z$äÀ¥”d­¦¤‰ÁhJD¤ˆ(ÌÍYòò²É3æ¹[Þµc[~^¾[㸛y÷¿ß¯=—r’¡³Ñåâ9“ÅQ¥ÖŒ?qü„ \.ÏÇÇ» °0‹i†ÃåS.çÔYóN>¢òõ—à €e ¥®E;|Ԙظh‘DTSYétØi§­§aÝjµØì…9™wÔuj•ÒS*•””ì?°326±®²œe1q«ÊJL&ƒŸ`¶ ¤8((¸›™ÛMBöìÉS½fÈèq€‘Ónß¾nã°1c(‡Kפ¦º¾®jÖOŸM>>~Ò”Þôfô¨š^sƒz÷® ŸY€îåf >Êó©T"9}òTÒ°kXciÑÖÕT…„‡GÅÆe¥Ý(.Ì öî—T^\8`ð–a*KŠþùW_úªT^ ßèØ¨=Û6ß¼y+&Ìoìä™»7lÎ/-¸‘zI.SøªTYwRe2qHhdUE¹·JAø<>—ŠW©¼fC|£ûµé'H»|v̘±¡‘1N›9$,Ò××K©TÒ.‡Ýéì?p0ŠŠŠ<¸mWieí¤©“ LÊ»—yïNÚ¤Ó|ý»'’ÉDB¾@éå=pàÀ3))Ú¦ºùO?ë(…x$ѪÓkêšò ‹’† <4éü™ & L ˆ ôòRyâÂYH?¸¯¦¬0,"F Ìœ¿°©²0å\JLT¿Ç¦Î@_ÛT`ïî§Ÿ^ìþ j=TàaK³&ÿ^ÆÄis@ßZ¯ôîþ© u5!¡¨I]-eÞ¾à´Ym £”ÊÝan¿Æ B¤;üN§«öòŠh˪  €rgúЂý=½NGÚÚMf¡LÒrYÔ÷ñpþ‚\-½äÑüŽÓŽ=Mâpïû®_=0÷—ÍαÂ?og+ÑM€aŒõzMGÈ(f À½sHÆig;³ †aÜ[] e31 ͲÌi£úNÚ £^êºÚ¶›š&}‹Ön1»5šms·îݺyíô±#º-ðe%n[LA^Þ½Ì; MÉÙ¿wwûà0îx¬ÓÉÇÀb1gß½|ü˜Åd€ü컥ş}öÑ÷Öoß°Öf1ßI»€hš:°g×þ[ÝÑ7Û6®{:Ø-ÆŸ»ˆzMªÿs‚ÓÒP£ Œp÷#3ýƵK§ýùJù“ _<¸s[‹VÃåq#¢úMíj£;´{GAyŸ·BâÿÇç_XñïÏüÂ(³ë¥×Þ¸qýzmy3-Dé—R6ï>ÐcNµq¤†úºß¯xlÚŒ çOL˜0ýÀþ=ï~ð!¤Ý¼×/úêå3ó¼°zù—ï~ø€oÇ{:(pãûÅ\=vâôYW¯\ŠŠ‰£)úâ™”Êzõ˜¡…S¹y9‹ÿð ‚D’µ•e‹9ãÆåàˆ¸òkWy<îÌÙsë5 á¡QXü|l¿xÌ0´º¡Ö=M,†V¾P¼wÇöwþþ¡Ãa Àh1õ±=øëé—³8ÞAÞ‰k×o¼ûñרª¬³. ø÷þ€kË‹ºÅ:Ìœ;ýiÅs˜…5ß~ƒ1xK³g€ˆÆÆ¦a#Ʀ¥¦" ¼¼U °&–¦–eIĺcŽ CyeÕ¼'\>sÒjsômµxÐú]¶áwfA›ÍƲX›õ­6Õ0´ý`úÐÖõ £F„ÇÄëu­—o\Ù´79ónæí«—Ћç‡}Œ/ÜWŠãù ¾üîߟpþ쓾Å=,-,ã2ê[@(Z[¼}|I©·Xªd1Ò·6K”^/¿þŸ ðúµÝjr H‡“ѵ¡cÂd63´‹+ŠÄ<^€€ûî­›^\ú0lUyb]ɉʾ{Û`Ðùúú™0#"2š ˆÂÂ2÷¸s9ÄÒ 426íúµ_ƒãý†ÛN=m¤ÈÛ[ÑÜØàëïhÇæéóæ5¨Õ´Ëé´9·oZûæyVÛôýwCF D«Õá°ËERƒÎ yqÄ"¸›~í/}Ùëû ºV…—·;öiÓÚïŸxüqƒV=xHŸ‹o]¾âí-•ˤ\.CºèÍâþƒ‡ÇÄ…×Ô¨9{ú´ºQK²–¸¸ø@ÿ€ä#%ÞS‹ŸÎ¼™Ú8#’$9aüä“wKs}L¿DŸä£‡ýüBý‡Ž9r,Y" øm1}$IŽ9dù_ ûÂÒ—S¯^BOš6ý^N毡‘þfÞ–FíY%4ÔUŸ|„Þ>m©ýÔušFPp`P(ÆøNzªL) ÃHóB—Ó‰€áò»8›Ôuv‡3,,Œàp1fM­Í—'•{Ñ.‡'Æe#¹‚.ù¾»œLÐÍÛ×ða¶kæÎÁ§ÿ \ØíJÖ#R ÷}„Ú¯ò1ÝÎxz˜ØÎY+îÓ>µ‰õ³l·3Ézº {TbõZ—_Æ4B–¦í6³H"CÝKâ¢ü<‰LƒÁb6‡„€¦¹IÛÜËã=ÂÃŽ8ÒžÎ?xÐ9`?g£lUY‘Óa—Èä4MWtÍ "¡Ç€Y§m¬W+¼½ëª+ò²2[[µþAy¹¹~þþ('+Ój6µhµÞ>>ùÙw¹<ŽP$@À2€ˆÃ„EDð¸÷>É/?ùÛÔÙ™~r…ÒYÚ¿ïlÊQ¹Dêëçï‰ô›šš¾úøï…ùq‰BÁšÿ”4ŒÃåbŒ?ýèo•…¹™wn 1úÒ¹Óöî,)Ì ðtÕêZµ«V¬Ì¹—y/?ËhÔ·=]·¦º¦R][ýýŠo ‹sÏ$ÎÎÊøêÓºŸþ÷ëÏîÝõéï\?þÉ93ª*+<[^±ü+÷†&÷å´[W-ÿwÏnçdÝݹuC9-xÒ¨×{>Ú¹}«^§-/-úóë««Ë._¾Œ1nnn:{æ4Ƹ¬8_߬9zpƬÕj9xpÏA»uù,Ƹ²¢ìüù³ãÓ§O—z–¨*+Á»œŽ¯>ý¸YÓtêà!«Á–zñtÖí›—Î_À9|Ðå°=R2ˇ”ÀÎ3{KØ/!ÁÏÇÏíp2bÌ C&&ÉdmÛ3ÔµÕa¡N§=,$,>nÀ̹OœÄ´[yDy ¯÷ËoýEÌaÞ~÷}§³Ë®D‚à Ó6xQ{à]—‹rQƒ:uühxd¸¬K6?ð÷ó‰Ä'ì1|¨üƒòïe@‹¦É½$¢ãåÞÞÀbÄáN»½§š]R^ Ý–üc¦Ûr Žahjë¦5/.]æ­RLê¿}°lʉI#F[ G¶¯Íºs‹ 9*~qïþ³Gß§­Í?Çã»31 “|äÐæ5˯=Ùöµ,S×Ô a‘1÷»ÿ|¾nõr‹ÙÚ†šÅ‰Ëå¢_€MF#O "÷îk„–¥€ ¸)•X†B1fiÚ »žÙÀv=—êÿ?W7!Ü÷Ä ÔG¼Ì¯î~ë£ÙG¶ÿº0üôü;ϼ3ž$AÀ²lK³XÆ ÚCºA*#D ½Nç´XÙ {ûÚN£FEI±Ù /ÍÏÖ¨ëV‹RÕîB ";#- -|E9÷NŸ<ÍáàŽ½Ýô£‚œL‡ÃѪm:²gG£º>$4¤ë–ÈN»qñâÅAICÅõŠúvÙ?TX ƬY×ÄIOrÚs:uÓNò»å_"¼½TR±pÁ³/^8qˆá2©g­Xº¬¡®æÈÑ}1ñƒfÃü§ÿØ7 éXRèÔéS"w„‰¹R$àw5çã·n% íî†Å¤//-˜1gfq~NÚµ‹£'LíÙïšú†h¨¤ {Ñ K­6ûž[_~ý¯]Œ±Fc«¶ñQøñ½qÉ{†Gȼ~çåÛqŠÑc-â?¾ðâ»ÿç’WÞ° p³¦))i‚ÜK Ñb0úú‡ˆ–¹2ï"`i—D$Ô댱‰ƒƒÃ*ÿne\GsIDsŸ^¤Õhcã@ߪ½“vó]©Lj2ç-|–Ëáš í¶¤&Íœƒ9‡Ë}5s’÷sýÖ«°›·3‡‰P˜Ëé8spßX@ >æÕe/ýåíwX–‰ˆˆº~öäά´—ßù¨o#:Ó~Þf06ëõIÆÙ³U"‘Ñ,=çÉŇöï.+)ä¤Ï.ZDçéÏÁ€3§45ä^>µÕ• Ù™wU>QnË˲.— Õ5ÔÞκýؤYºVí¹3§}|• CΘ5Á>ºT{øÓeþWD#§ìÛî(GòÁÝSf?!—+K óóóóN¤¤ÜLMM½z9?7gÙ[osyü~ðÞg_-ˆ¥½fœ_(ŒM6Û˜±ãÜGé­]õÌ2bG,–úÈ”€±ˆß¹bv›Íd˜5ga`ÐÝ«çOsx†¦šúzµº¡B!å34ö  R™¬¢(/&~@``ØŠ¯¿xÿãøù†††âvÓFEqE‘Fô½,0Ò6«}|ƒŽTÜ€ð«Ñ˜eX‚$¸ qOFúÓ·ÿyþµ×ÄR)Ë`>Ÿ‡ËйBVBDøùi42¥Â×Û×3ãGÇ›ëå¾Á˜¥ÿòç×ÞXúƒ3fL¿—‘®®nN”àïbö‚E&fmcò=®€ÃEc&MÛ½uOì+M˜o1ê8ĉqã§Ù,æå_ü‹'–$õ‹9zôÕóɧŽåpyó,‹¥§Íî0ü¾÷Ö«5eŧmŸûô‹÷7EYŒ:‰ÜËÝívú=d$ÒoãAMSC@Pðýq!‘Á†mXbÕ·ËeÄBn¿„Á£Ç޹—Ÿsýü•y æÅÆ`(jÿ®6›uñ K¤2ïûtÄdh-/*ð Ƙ.*«T¸þÁ¡ÑÅ ØÜ¨&.Zá%“H•.‡µ¥AíÖ¦gbÌ0.’ãÞôå²Z,R™œ Hìp8H’à¶í[èün»Ý†x|>ñ 3Ì1ƽ¹~K>‰éûx²Ú¤Ò7 ò!q! zœ²Ø qo;ÖàA®Ä_~ýd[M> IDATŒ<°¿”ng8êòĨ†¦\Azºþoqá¿<¢ÞŽ7'z³–uÛMÈö5^‡#ëî…BÁãpêëë+*Êꛚ۔ï¼ì,o•wMy©H,æp¹™·ÓƒCœ6ëí©¡î-ƒ,{òØ¡¸øþn_ë…sgOK¡¬ÖààÚêêýû¶Û ±L. Ï¥³˜ÌþÝ™áõ+W6¯[UtïžX"áò¸ëÖ¬º–ª©-ë?¸¬ `ÝÚ5&MîÖíÜ{Ù«¿ù"=õz}}Ý€AIß~ùqVÚíÌ‚¼¸˜Øã‡öÝ<Ÿœu÷¶^oh?Dá—] ÄÏ÷7t S‡IŸˆûfÒëËãÑYž¦©Ý»·9N ÈäcÇÍÆ£YµCs9&™ ˆ'“7¯û!íæµ•ÿùªKJ/·ÇÂAP4w/Ôõõ§ã¥ç^ÐêZ¯^¾°}Ëšç–,þØØógOÑ._ ª¨ªîÙ¹ÆÚÊý{Å«}ïÀ¾Ý§OzöϽóþ‡ZÙét¨ü½årEoK>úâ›O¾þV׬mª)÷ Š|ëÃ&&feeO™:ùõ¿þÇ—^/«¨ü™‚n®žGq-õ:ô=)„{(]?Ÿ#I$Ò¨ˆ(/oˆ¥â1cÆOœ0mðжøÄšŠ²ðð‚äð8Äâ%/˜õ/½° â’’Bƒ‚;zÕ ®€Ð°ÇŸX “)h‹~À Áþ¡ÍjMIqASC#—/3v|¯}Ñ’e\¿ ;{æÌ™§MI>q,;=ýîí4!/UA°ÐãàªAƒ“dreUi‰J*‹&X×¶M?ÝMMóSIUþ¡ÃÑûÿðÜó÷T½ß¦Û³²üj!ŠDc z>ö0“®K-™´Í³Êç¡S'Ž\K9¥Q·m¬¬ªi5˜@¦{«¦Ï]llžF,…™¶àqx šÖíãО­“f?éëøÚŸß3š52©8*2 , E÷ŽÓo\««¯3qZp@𫯿í0j£É6Õë'iÔÕYÙ·Ÿ}íπВWÞxá¥%#'<Ö Ñ‚?®™·è…Ò«mÁö2®½‹I‚äôL¢ö mD Ó×Ù‰øAôë3miMÚýT«Õ?þÔ³çÌókW‘ûÅ÷kni€ªö=žuê&«ÙÕµѬiŠ t#úƒ{·5ÊÇÇ2Òo úXxtÿœœ| ¡omËçI¹\—/œwï­ëW›4sç?e%Åe¥…¡¡&£Q"€N«aÙ¶í]wïÔjšÜÅvîÚùÄ“Ï`–µ™-ëÖ¬Lè FŸo¿üdÚìi×åpüŠ‹ég›xˆþ‡n‡OBWƒ5êeChg#îIQ«ÕV]UÑPS þ~6³ÅóáQ1”Ëa3™Øv¼@(ä’ÄÉã‡˪.ž9èn¼¤0kÔ˜±ÐÒÜt:9åÄù‹·þ ®¯imn>´gÃÞ]kŸ~z¡ÕbÚ»u}uEéôТÕüûó :-dfÜ.-ÎÿòÓ$;yíìÉ/>ý$.:\(–lÛ²Þ¾e“ûíÅÿ_yo^Õ™µ¯gï}\ãîn$@žân…R(…ºwf:ïtfÚ™¶Cu¦^h)…–R¡ÅÝ݃Dˆw9î²åùþ8'rbißyß¾¸r‘“}¶<²ä^kÝ«¼ìj^¶˜ Œ^½òó]Û6òÔÈQ#~ýaˆÇJÏð ¸výú®­›¯åÿ¯UtIâ<ÿaÏŸý¥Bé´*»ÍÚkŠÇÐW/çõZŒ1C[9–îv‚ÓabY'æׯŒÃ‚1æXK;0Ëx6ÆcÆií­op·>Ãc|pÿ¶n½…=›s]ZþºŸêÂÉC‹¥ãV¿g/ߦšŠ»ûbG«ì)K‰Û„îîÉÃû­¡Å^nY‘T/Ÿs,"nïÞiÔ*©DL;™Â“s4jØË×aضÖ6‚ŒÁ?ÀßjµÉd2§Ãn3›ì{@p47Ö…DÔV”FÄ&Þs4´Ó/|§7 IÇ0†–&‹Ù ”H ‡ÍRW]N ÒÅéÔP[M³¬X,î_|Ûl¶“‡öKÅ©ÂMYoµZÏŸ:ÓéQåæœ««oعucþÕ\­V_y«¬øfQxDdO:”âÂ}ðîðáÃ…"ñß­¹Uœ_R’oÕBÂ#¯]ÊÙ¿ogÆa¡í¿¬KIªji:tp_rJ"ÈGö³´ÓÇ/€aè_¿[“>tË8ÿñê+“¦Í8¸w_}m婇/\¼ÔX•[[Ó›ÐùxÇ=µt1m7W”†D¶w8qüèÁûêkËKŠÅRùO?­m¬¯¯¬,ONJùvõÊ£Æ>°G =r,!)I£VïÛ·whfÖÑÃû…¡ËJï åúw÷¾z[¨ ô’‹j^z啯W|š™9¸¢ø–·¿×à!YOí ‹M÷3±ÿ5"⓹¹çF=0®ã“â‚ëqÉ Ž=øÂ‹/ò…BÚi@Ñq çO“=®Gè’SÓC‚Þ¾`1›{â$Oà:!&9µ°¤ÔE.£5YÍ&ã}»—µsd6·¨&N 7 Êê*¬«X*!…âu«¿¶YÛ22³}ä^óY ÀýýÕ¿L™1“ ‰ƒ{÷̘=0~dÉ’y —¸®ã´ÛššÍC\BbÞ¥ ÿó÷òøüÖ¦ÚÒ²òÅ/OJv?gÒ Â×ÀbHHJñöñ9uüˆ¦­åñ'ž€Œ!Ã/]ºŸ8ûöáÌ®Mc'aÇ=þÌK>Àrß®þÂfµ¤¦&O˜1_¯ÒlÚòKæÈ±Ù“\»r¹ß 8á ³ %Þ2E{>5Çœ;sêÿó·®çÒŒS¥Ñq¢iŽ/RB¨±MÛ»”C@µûÂ:A£6XMº°˜8’$ ­Æí{L›1gù›ÿLOD¶ñçÏ[úøSPT˜ÿê«o¬úzÅÿüù/£ÇŒÍHO  ?¸EmÍÞ­›BþàôÔ²â¢ó9Gš›Œ“184äðáÃN𓋍i.^ññ{ƒ3G´´©Žìß9sîCï¾ñOo¥4!ePlbâ‡ÿy'-)qè¬ì)3‡3qü¸7þñøù9|0"2ÒUíE³lScS—¡âÐ= 3­„)ìZ&â̱ÜÙû&MŸî(’H~øjÅàŒ$!@¤Tî%K‰ŠŽq÷]"¨Ž.]€Zrlvö™“;¥”°®©aÑ“¯O§Õ Z…—_Eù­uëÖ‰ødpÏ3/¾Š¢Y÷×']œ†aHd4I’¡Èju»•R‰ 6"Ø×§S蘧ӱ}˯>r\YR €8ÚoµZ &Ÿ‚!™CB±_pyúäуd¤%;îðÁÓ§Lqɺ_ùÛÃÎõ–K¿Xý­_@ð?—G³´så—+ý—,}òìl¬zñüÙ÷ÞùWNÎÅù‹­(+9j´€$ëëêÂÂû5"2²«E‰àž¶nÞB§FdæðÖ_Ò³ÆDǦ`g÷ä_N>No2¹ñÅÝÛtö~˜,Ööì10›’’âJ­*»å:A"ùûL½lÌÌE6$7t&Wú€L"ò‘Š" ‡yí›ÏÝ Dáí5nÚÃc§Íq±íê´jq{nçŽ-[=þ\K‹¦¶Òý!áá.Òæ©3çN™ýhhTx}]Muy)8½No³ÚC¢bý‚CÈü«Í&ËäñÙz¡0ïŠT©ôòõ÷òñ€5_~þâË9~ò7_~¾{çÖ¢›¥Í­Z>â E"³<˜â 9–Í=wrÊŒ¹Ñqqu5UÛ·nž9{Þð±üúÓOpáÜÙ¡™Ãºúû÷òí—Á°úóO† ư Õh%bþú¯¿~hé‹Á’š–J;íE×rYÆÙÜPÑÏ ìvÛ™Ó'‡ÏLL @Â#G¾”“3oá¢í[ RˆTFj2ë°~õï·ƒ#âüå”ÒÇ¿®¦Úád\ > 8ì¯o¼‰r•U—•Ü,ºá°Ù"‘@ätœ;}R×Öâ2@ F£·ï¬¹åœ>“ƒ2®^¾ ‹'OšDPÂÙ3g‰EÂcÇ€H$’žF³l{\’Ó§ väÀþi³æ0´ÃîèÌÈ~õŸo¶µ©3¶€0„Èõß~íë%_öø2©·OhdTÇÆš³h)Åã-]ö„ɨ_úøcJ/o¥—÷âÅ `ØÈ1±ñ÷Íç÷lŒÝÕ£‡Üœm jR*RJù#³§ÔÖTܸ~#$,tpÆ`šæíßåÚOb?¶±¶ÜÛ7L,wlq‹Ù I ZT*¥”Ç—ë´ÙF*– ŽcPojœãX'A ïÊé•>ÿŸnêÛu » RÏ®½6&ì5FîÕ§ìPœ¿aòå"¿áÂí"¸G!'îÂ*ÔßtºcGùfGRTþõë µ5™ƒ¶Ë·Qê°lÙø‹ÃÉøÈÅó?V__¿sÓoùüÅOwõÃ0æ¶oÙtóÆå°ˆ˜‡—>ÕÒÔxêèašqÌ3_ðÃ÷k´KlpÌ’G—¡ûÖqþ¿~ö@θ>Š ÙÔ ör|ôÞÛ7®æ–—\ßþóú¼Ü çNìoi¬ÿiÝ7 5ÕÇÖT–ÿ¸v¥Õ Æ÷þ;o™umõUeŸ|üŸ®§õº£‡öbÌ]Ï»´uÓ¯_|ü.Ç2Ç®YñY}uyMå-Ìq+>ýH«QáÿßTßp8î’Js÷ý‰"##Ó‡€ØÄôƒfeõõô kln ‰ˆîMѱ &DroŒ¹°À‰ÒO$Uð<&™B9yÚḻ¥ùYÙãü|.çœç“¼æÆúÐÈXŒqQaA ¯ÄËÛç÷Xþ½üÿ…-K ºz3Poª®—àf¨®(u:0‰HD„÷Ìz/¥‡%28iÚ³S‚+KÞõ㆓&ˆ^öÄ©õÕ·lV;Çwù¸¬´°¦AÕGFÓý>î§Â¾×o·Ã^a:bÁÞ^F­¶¹Õ•`qdß.p1ñ8hº¡¾¾çÉù¹Àa·”””`„P·™À·aÝÚÄ¡ƒ"#c|ƒ|O=—œæ¤7®ÕTU/Xø¨L*ijløÆËlT÷;}}wy4ÖUp¢Þ~ÐÃÓȺæ:i†1 ˆ”KD{¶ýêå­ IMI*½œ›—w±¥¶qâ¤z~Ù? „…PÀ[·ú+¥D>qÒ¸®‚K­Rçœ=ÆbúÚåSf=,”H·}¿Âi¢&=066.~ïæ ›7Te¤g‡„ýFS(•ûÞ¡ØìÒwŒ"8,r )×[N>îÑT¼–óg·sŠ¡õU2¹ÒÛ7 :•Ífñò ð=GÁé°¹Z¢bŽ5õHУӅÝb¤ø„1ÉBK 7À9«Å$¾K:;è×wü‚bwçT0íû¦ɳë5Ø.4÷;øç^}¿w£‰ÿÇ¢}‡¹×ÍbÖkT,Ãô€lnK=ÓE•bf`ë‡Àl Dß஘žÿïÌ öpíMzͧï/KJF9f섈ظ>°7Ü t&;{n»MèÞ1Ëvä>34Mu´WaèhÞè°ÛB‘ÛÙ·Ûh†Kå÷åEY‡™ä‹¯T¥ÿt ¢ëWE¦¤¥±,c·˜¢µgëöù‹a@¬Ó‘#72*A,•!K¶oú~þâ§ ZµÉd øõuõ!ÁÁ±T*SìÞöëÂGŸh¬­f'&øW.ž>j4/”+‡vlš¹ðѪ²2µº%*.±¤¸D.ûùø…|»jÅÏ<ßRפѫ„"©ÅfV«µ‹}ôÿg’óÎ4ùöÛoU-‰jjk9 ‚ƒ‚Ç¿ÿvm[s]Ya±VÓ&ò¶nÙhÔšlvëÅ3ÇEîݱ#÷J¾µ…/ä\8[˜_túLNSseBBüšÕkªkëÍz•P$¨¨¬¸“S[U¥ñƒÂÃ7ý²®¤°L@paav†ÝõÓ†‚‚Ą„踄u«V]½|ÙÉÐcÆÚ¾öÛoj*ªÿ@phøÿËðØÀ|³þu!æ‹ÝÆ!A€Õltó”sðôs/œ9{êÂåóƒ’£S—<òäÅó' s/,^ö\fÖôúÆaL2dÎìùÕeWÍúÚé“gù„ú*„õµõU5ѱ‰ƒRÓ›šÊ+k+‚ƒB½}|½r¨ohäóE ¤lP$’Éù>r‰€¯Ó‹Ë«cb#¼|E7òòzϵ½^×ï¥ùp¯DX÷ë ß~{9Åw©ÄqlA^^Ú ô’¼ü¶–úS§OΞ5W*Sø$‹¹3§O˜4#%#ãrÎAšÁ!1 vƒnúœËJ JŠò,~\*õji«G€¥2¥X"]¼tYÞÕ‹Õ·f?¸aì*R>þeÙ3/´µ5 …9|¼Ùl ‹Œäó…éC²Šn>ùâ˧ÍK.ŠKHóö LJIöñõëÈK í6Òƒµ[*,Ôߺ×Uïî£po»ê7…Šº%d;¼gÍ_?vccše¬WrN¸þ1ÛØP«U·`Žvâ—ÎbYW²%k·šZ›jÚÓ2¹úª–qÆ8ì­ª©ª6t’×1´Ýé°t<ƒÃÞ™#ʲ4ÃÐbøëóŒß„ ðîè·;:â…]½{¶ ¬€» k¸=º„ûh(gÓzãiå<“Z{¿¦¦µAé@R¼þצ+k¯'^Š10æAb̹jHišváy$IÒ4MQTW‹ú¿Yïvðθ»Å¬nm&IŠÇ€QghnmU*½1Æ×ËÔfc[kƒF­õõóí£èð6o•sòä‘»µZmLl|ÁõkAApæÔi’ ªoÝ -Ì¿a³ÙÜ'Èd4~ÿÕ'y¹9v‹5(4ìä‘#©ƒ3 DØ»³´0_&•JdòÞ}sä˜ì.½øëÏþ“9|4‡¹u_¯¨©«7è4aá‘ÏŸðù«>úOMEiaAž`ÈÞí[ÒÒ#„ÞyëͺªŠŠÒÒ”ôŒÏ?ù0mPº@(ìoJ\]vP÷"³ÙŒY†âñ~ÏHEgS½FýÑ{ËG>0VÓ¦’>Ø;0ðÄ‘ƒa1‘'í}ê…?µY°•®­¨1šèĤdOZ„¾P>!¨®(Óë4Kž|ª¸ ÿViQ[›»ÈÍ›r©hýw+è–mٸᕿ½Þõ[»wï3ifJjʵÜKV«¹¦¡h§¥–=¼w·„Ï·³¸›ŽŒŠO¬()nU5N™9ïòåÜÂkyY£Æ¨TªÔAƒ2ÇŒ4Í]•߬ҺòÅba@`€ºµ‰¡i‰TNÞ¶‚·ÙT_£7𲆼Cˆê^§Ð- ù"Áß—¿ã¥T¶5·\Ê9ãäGÚ!=v2”~±ô‰§<§ð!$b¢‘P:tØ(‚"‹Û™Ë…<¾PÀ[þþgeE×^ùÛë«­ëúˆ ׫›æ°ÁC3YŒxž@D<AÍyöùÆÆÆ–]Û-fs×øþ´YsßzíU?ß±ã§åÜH{`üéc¼åRŽÃÏG!£ÆMQ*ÝÐAr|ŒÑd:"û—õk½¼ähÃŽ{|Rò@Å)f‘÷4˜DRêeÄb©X,­®ª*¼t~Ú‚EÇí«Þuêâ¹EKžpíTUK“X –É”wçÇø‡‘8gß– Z㔇‹•2×T!Ì´¨´¡xô„ª–F£±þÄñcçÏŸË$I±q³æ.8pôøæÍ›jë^}ãM›Ý&ƒ®¦ªÜË'˜ÇDÇÄ)^àC{v²ŒŒŸ2S$I¼$ÀÑt\bâÅ‹g3‡d8쎠pÿ„Ä(Ä@Õ­R–T^Y Íœ3¿°àœÙîl—}¨·¾Çq0”``$C÷Në‡H×.l'#yXÕÜ\|åüŒ…‹)ÿÇ5«§Î˜õå'Ÿ„…GJdÒm›~Y°hñ]µ}0èu™£'øøùÕÕÕ˜tn”CˆaÍ"ŠKË1ÇÈ$B!"YV!“_¿ziXFªÿ”I‡öíR5Ô  N•ZÃÉX–%R£nã0-•H0Ë ‚¿ü4uÖ¼ÖæÆÜÜË-m­V›uì_ýÓŸ>ûj•OPht‚ËhbXÎj2ÑN+ÍvŒFžùÜ“O,]²ô.¼là°€ÿ»š3O,Z¬ôósÍGSCÍ?þç¯ó.hTi˜ç°›m:§ÓÊuMÉC6ë• ç&͘Û/ðÝŸyƲÌÊÞÍË»jÖh&L™fÐjŽìß]]|3*6&Ð?Àd4†„EµjŸ—9|ô˜±£GŽç é×~sýÂI¹B™•=±¥®îèÁ]zmËÔÙ }|•AA¡AXm¦¨˜øÀ ¹ÒGáíKdCmÕðQÙááõ5·ÂÃBBÃ#ýCÚ6|Ô¡€òñ p=^|lôáK‹K\üDLd˜@ —O|\dxd4º»:#J¿ïtª&¥¯+;lÖcG÷*”Þ$bÓ2FÈä^U•Å“.%-‹ y€±Ãfˆå½qÈüm]N 剌 ;7Í{ø$.ÕÒë0AÞáeÿÏÀÜLÞŒàYbØÝǸ¸\ï-Xx?Ž»Òÿ6Øú.,R²7ö®€‡w1_:}ª¹¥Þß×ôäéÚ–¦];6 d‚™Sò ðïªÞÏ?zñØq…¯2-}pÖØìÝ;·šõzï à9>ÜÕO/.¸±yÝj;ÆS§OŸ8cþÞ=Û oœKŽÏx𑧪n•œ=zÈis<ôÔ³Ý+ùîrpï(õdàæÞ=Op—beÏlR޹CøêöGMå­í[Ö«[Î8XUUµmÃ÷fƒ³ö/?ÿws™ª[79Œ1·g÷ŽÆÚ Ž¡÷ïÞ¥Qy$ˆ^ɽèá6þð-ãt®]ù!Æôk¿dzëÆŸMF][k󩣇1ƘcÿÀ°îË`ŽëR~7ÑŽŸ!O®ˆìƒ$n—.Õg€D($4Î' dÌ„éQQQr…—Dî„€B<7œß‰è“@ò8ŒÅlUzù ’’Ȥåe7»^:sØ’¤j++ý¼ ŠJ2ì…'_˜8yA’S§Mÿ×ßÿöÍ×_~`¼§Ìø­ q í¢Ö¿“@  LI÷lê*bh÷ôñí3ð„1Àµõµ§³Ìö ë›êkh†výµÍÕíí©4I1Œx|‹1X Z…¼;gryiÉ•‹§ÆÏœoµ˜ÏŸ>û‡?°‹G ÿû‚²²œó91!!?ý´.kÄ(øií—5uõgN6|Äî­C#"]é´Ãv›Øòo,&bÎtZ•6‹ù·þžž)äh/¿€‘£FíÛ¾),6îô±ƒKŸzá«ÏÞOMBñùW®Ì\¸¸W›¬ÿ­ ×ª®]½øÐ’ÇZ›êkn¤gàJnÅ&&¯[»Úd°=²ãÁÇžîúå«—. Ï>z\v^îeV«2˜\Ÿ[Õj»ÑÐxëÖe(ÐOéjŸÄÑ4¢(„ˆc(¼~C®dfe©µÚÜKçm¶YÁ—Éåƒ YúØ“îGnf­Ñœœ˜ŸwQ«U‰DB»ÇŽ'Ã÷ÑÕ Å|¡à_o¿÷ô“OOš9¯µµ‰Á Qx'$¦†ø{#2…÷äsÇMš’{ãÆ9LK‰/S$!•Écâ“B£R­»;dÂãé5êeO=.ÿ營ªÚ÷ǽ[6;i¦Kz-¾ãΡÜ IDAT<¹~óÕVóoáT¸÷$É—*ýôêÖc~}ô±—I’TÊ$ëV}öø3/# &N™½qý7Þ~>¬»/àmiä1jo‹…@,‘……­YµÂ®ÓÎ_ö„Πw§Ñh½}¼ëêëRÆÙ͛ݚ—{qß®i)‰2¯À)3Œ›<ùVeÉ™cÇf?4Ÿ Üõª ÇŠø<ŽãäJ°ÍbÞ·cSUUùÑ#’S2†ûûùÆB‘Ôiµ766Æ%&ÇÅÇLŸ9ƒÇã@}C»=N§ÓËK©ôör:êÆÿxG¯?xY –Þ_C—êæ}kÚÚvoYÿø ¡xü=[7‡¿ñÁ§«?ÿ|ÞÂ…ÑÑQѱ/@IÉMÀî´LÛOÔßæ#x‹›%&!uâÔYFƒaÇ–M ˹֬\*ÑŒ,à ›Ù¤nU%ÄÄD†E9/•JU­M2™|ö¬¹ÎäßèHH”‰øÕ ®íÂ0´H"š2cV«J3yÂx…ÿ©cGÒ†÷:|`¯ÕjåXvê¼…Ï=öèŒY3ERYP»‰‘ÓaçñøÕ••<±B­ÖL›5{þŒéSç,øÔØ}qT<´—Ídøë_þð½__Sïíã#S*4mÚêŠ:X,•{ý¸få°Ñ㡸øÄŽ´Ÿ¾ç¯ëúr:Éãoþùû°˜T9ýàƒªÖ–-¿lˆ¡ƒ|¼½[eRLð…q©CãR#ÆðÆë ô÷‹šýðR_oÅï½íã¥XøðB³NO‘üü€e‚ÂRRÒx"Aòìsö„IÅk¬©  ðR*üƒ.yJ4¨ã)—>ùÌWŸþG,ô[òô <+^B‰â•×þ!þ ÔÜ€ö¨GM…ÃnÛ¶} I"DCÓSbâ®ä·´ÔÇÅ%ÇÇ&0´-//W$–'%%óî’hÚi´d")Ÿ/À‡ cN(”K$ÙîÌôÊ׎º8¬è¿Ì×¾'‘X_S{×~!ÛÅyï gß}L_Ž ¾ó°Ë]fxô1ñ¿)ÈÒú1Ð׿{Рg Ê?ÓÝ<Í–¿˜ÕM^Á“&M5ŒÇï³ÛìCGŒË5¢ëi¥E7¶mùÎAŠEÅ<üø ß®^-¦„ŒÃ°ìÅ?‘ëB÷[ë?ûཀ@ßØØØÙ?vôÀêêq/¾ü7UKËß~ž˜4xPæðÿgök_ñ®t3\o44÷'ÌfµZ¿øô?£Ö k;uìðš¯>7uv›iݪÏ{D$Y§Ã¼â“cÌÝÈ»rê茹қ…gNžt±E»ž­¤ ÏdÔcŒ¿]õ¥Á ÿé»oX–Þ±ù§¶Öæ#‡Tß*ÕiÕ›6þü_FsŸ–D—­Ó±z¯¶Óíá|ŽîÞ“s¬L,Ë”r¥ß¸ISä ™D¦%¾Av³¡›§(¡H"@ øºíðø‡«Éƒ»½ JL"•)êªËC¼å2ùÔé3^~ì ?_?ÿÀ‰“&nþnÝÚÏ>Ÿ>cÎÀŸù·=ÜÍ+Ðí$?ÜÑ 8Ù[c&è;Šv{Q`·Ûº9 j½ vüòCΙS&£Ùu/¦ÍIÓÝ€i„°ÍÎ`»ÓÁçóÀdÐÓŽn44¸©±þÒ™CÓ<Â0ôÚ¯¿øËk¯45ª ¯]ÙøÓºIΘ³ðÁ›~À÷Ó’è>ºí·ÃQnÚEwqá =ôÜ|p¬g«­~Ö…Ç_Å2Y·“Á#š1oÁÍ‚>¾~.”@$Pn²«E˜t:äãí¥R«0Ç’$¢Hwhª¯Ûøë³>I;,Ëú(ýBc’3† ¾U^j1Ù£c’Ãbëê1æzk~Wj w*~Ÿ`êa¼´Zp d/V~'YE?ÐL÷…ƒ1»wËÏU[\\LXì >‰6þ¼^&ä'¥gfO›Õó:ön˜9g)Z÷ÍW`·††Mš·¨k·•₼C;wH•J\òüŸ®\8{âÐþ„¤ø¹‹–YÌÖƒ;¶R|*k섨˜x§ÂØ£SÇÝm~b÷O0Ë {ÜßalÄí6ÔT…FF÷0¾;èûï=×W-î…s C“ßëàXcޤx}¬®‡K@܉¯‚ïÍ£¸‹ŒÖß#@Øq¡—b  åÙ0•°jíÕê±¢xüŽ=Ýžl‚û¸á™”å1Ç!˜ã0ÆØM›Ñyw†vrÅã3 Ã8|>Ÿ xv«‰¡Y‚±gqˆÃn½œ“èï£Ëýãë«+ãã0æ :­Ò»{£Íl¾U~+:&ºðƵQÙL&£A¯­(+3YlEf J Ù½c+Å¡)sç …}aXðåŠÏü¼”&‹yꔩ×ò V=v¢©3g©tší;·Eú‡q–>ûä¶M¿ä_½>fâ¤é3gölòö t¨ÅhȽxÎ××?mè°.£ß•g÷àcëg[t,¶·„Õî»ä×o×.\ö_$þaÍ*­Q­TOž69<"â»Õ_ôZ!OôÄsÏ9°kþâÇœ4ýóÚUYYWÏžˆ$V†yîåWù]ZÛ³âR("èç3~ê¼ÿ¼ý–w ŸT1ñ²åË_‹ŒÄWð3’SGÎîË7ož9u2)1ñùsC"þôÊŸW|¹òø½>~A.z¤Û«<~0(<Šu:V­Z™9bŒÉ »YPpõêÕ)Óf +•ÊM~ ÷õöÙðí·Ïþ镾¦Ð Ó¿ðâK˜ã"Éáã§Ÿ}î9Àܺï¾õR*^zñe/o?h¬«¦xÂ>ÿbïî=v›µ[ÄÛ#ÝsÜgŸJÙ“/¼ÄqÜúU_=¸xqTxؤ_0—.^ôòñ«¹UÁ8#3S&–.{þÏR…¼'Ý&G=ÿò+ˆ ÐÙG?þTÆàÁy—/W×7d µä‰§Ðûo¿Õu MŸ5+sÄh—„Ÿ=göɽ;RÒÓ›š[{êõ’²Š‰Óf ‚¤äø3'¦¦æ>løÉ¥N×6ÿá‡D"qBJb?bP­ÓkµZň$2©È¨×pöõVŠ‚æ¦fƒÑêïçËpàB‘ ª¢,9mpŸ0·Óa 5nfª+*äJùÆŸ¿é¯ÖV–ØY|h÷–&L•JÅ“éjîÙ‰“ç”;&-cèÆ¿š.*)ñòžûÐÂúêÊÿ|ôùà´”gž{&<:nå'ÿ.¹Z(‘)~ì)¢¤à߯­¸‘sí™??ï©/ñ][‡^YRF;á!õ Ïb68m¶VµaÐéõF£@(¡(¾Y¯÷ñósæç›(us`°B.]¼ìq‘D¹Ï;,Ъ5 ‡ýCÞ]þþáý{\}Õ:Õ'C/yòé&N–e[š›Ón³™ô=§0,$Øj³ñ€¡iz΂…ï½ý¯©3ç†%ÄNŸó ë£NͲlbRüÖ­›-~¤¹±¾¶¶ÎÕÿÍe¸{x?ùô³í‘ò¡G–Z-–¯V~ž˜˜R„ ¹¡¾¸ ø¸1|ôܹsDÆtƃ(Þ˜IS|ƒ‚÷ïÝgVk§Ï_Œ¢àú%„p ¢Î ?oµÙH‰D¢Ñ[“¥>Àqž´8?¿p v“¿ŸïÞœ³‰i鵕ÃFeíH”vâø±Ñã;m(§Ýn¶Øs€æXF4MÛÛ—t=†e ¿|ñüð¬a$‚ÀÀ߀MŸØ¿·U£‰Cg>jó/ë‚Âc J€ãÇÜèœÂéÝÅdõUz#„DbqpP0ãt~¿ú E ¯€,{ü¹ë¹…ß}·&Â_\]SURQÙ3ØÀ²Ì¿þò‡©s™­Z£V?(s˜XÈ»|áÂìyóK‹ ÍGrjÚÙGÓ‡ ðùmmMYiöÄIMuU|¡(,"zËÏëç<´Øi· ºªŠÊÄäd’GI$R¹Òëàî3ç?lµI„j*Ê"¢c òóhÏ$X–9~hÿÔY󸋧ju¶¶–V1S¦N ‹N8y`ßÙÜKƒ’R\¸‘fY'íÅ5••ß®Y-•Š|”ò§žÿc×<—â‚+IiC"0ÆpêÈþÂü듦ÍLIªn©ö Œ€Úš²ˆÈÎöZ:M+öò tAÇõ5EáQi˜ãÌFLé×m膩­¼“dÔ©å^~6‹cN§7˜Ìf!Ÿçï –JU­Í‘|’Túør,k·ÛÄi÷ë8í_ØÓ Á #y¦yb‡Í&‰=zütç#Åø|ÎY©X’1$Óµ6Y§•äK:¬GÌ9Áo‡u˜v·¤gªA7@·[¤=36XÏNÞÐîvý°Bâ0¤'O_Ñ(®ß è~8׉aŒi„ø÷Ûõp홞Îß­²’ø„ÄpF·ŽöÝnLôë;bÏžBÐÎt ý‚=°‚.Íå9†&(žÃn£HDüž«,fÏïêi x>îÙ©ÿWi·AÄ>¾~c¸’s:7ç<ø>~¾KŸ8°·º¦ÖOé#‹Ë жoÜ ik áóE}¼UglýÒ… b‰¤äzîÞ½‡4Mµ<€‡|·‚h‡ýçuß ÎÌt§6Ùé·ßø»ÌKêqµ.Å…?®[óÕ§Ÿ457<²?mÐ`~—l ƒ^»ü/¯(|ýÂ=²ñûG¹;Ìwº›ù»ïÔï„§çîñdåŃièø) ªšý{v­ûjÅàáiÆgýºaÙhhTÕ>ûç?% JYõù§ý¾•{RUm“QÝÚöüËÏN™3Ϫo“xvìD‹±ãIÅ<óÂ3¶ã*ZU‹ÓîiVp `ú¯o¼±xéaQ |í ¥ò/o-çúnÝ[üávR‘¥{~f3êïhÄk*Ëï$å`@SØç—”2iƬðÀ§Ö™àåç­j466)’ˆÇMœA Jת™6}ÊÂRŸ 0Æ|±DÓÜj·Ù“ÂÓ;ãpÐN!R)áupõ“”˜'™,)—ÇŽ¥‘&–@ ¯Šâo_¿ÖfÖ%$¥t{5P"ê΄{_jˆÐØ‘½¤u‹äÊ;šÂ¨6ÜBœ`ªŸ/ ‚€ûöFÆEÄ'%ÇÄÅ_ÏËÓÕU ½Ä4Í$ïÔñCþ~Ƀ†ö‹v½ÖL'}`ÿÞ°Pÿk7.‰’¡#ÆîÙ¶Q àùøz™0S©ðó w×;‚ÝjùèÝåµuõN+—5,5!=Ó½œ«ª]O9û‘%ëV­ÒiÔgOË9—ããç;vÜ„Q£³-c«JÕàwÅ#îQ×þû´/FÝi¯ƒ,Coýå‡Ð˜¨¤ADáµ+ƒ3‡ÊO"@WΜ N”‰gïvÆ ‹n\k¨«/…X*36&%sÂä9åÅE€Y‡ÕH<«ÕÉÑŽ’ŠŠvØ‚@‹Y£V`¡X¼üÃOgÎ=rÌЄôŒM?¯W5×9Í¥²¡®úà¾ÝN«ÍË? ¹¹yî‚ůXùÚo=Æl2ä_+.*jã;È7¸ƒbÝÞÿíÖ¾AGòí·ßîí®\Ì9~ä â¸Ë—s¼Þ­­ŽÏ¿~5"4,$<âËÏ?1 'NŸ¤tTt¬çkt.L’"YÿMQaqJbTLbc玟:¡ji˜>g¦XªÌ6*1%-6!‘DΩã7n\-¸q±9¤rùúoez±L €|ž—ŸX, ÞwèPccåÄ)³Â"¢uzí•«Wced¶G3d2n••úøz)r…Wo±¿Íá¶8îéÀ6:wwa)wîGáÓv‹•âóY–å D‘˜uÚI¾€s¡=æ¬×ëtÄ7º4"éSþÜi:X óR\úv¢¯ ÜÙ•‡ˆºíÂ^ã´€¤øB‚äQ”¹ýBD¼öH7á™qÓáêõT}0ˆ.SŽcÛÝMt;ÿÒã0é4I$…9ÖfÔ;v‹^/‰¡úê*„@(R·6 ED Ö¦‘HB”\÷õ¼ž{¡­¥ñVQã°;ív‘DÜÁ‚yõJîÞ={dÒ7 U”—À E¢†ºšM›~¹pñ‚º¶.>%6Ûî훓ÓÒMíÿkÆ TI»]sâÐ^ÌÒÞ¾îúºk—Îûú|ÿÍŠC'ö×”W¤ά©©Þ½cGÆ!`·¾úü£‘cÆu{Çœsg×­ø¬¡¶ìÚùÓƒGŒéú§֭ݵmCaA^|BÊþ][ˆÞzÿ:p5÷$°‹U©ó²ríºÚ¾-¿,ÿëŸ1Çv|¾ó×[šš;ÒŽìßWu«äÙÇ–|ðÎòÿýNsC-|òá{V“¡— ñë×Ü·n\¿¾råg§NŸ:zø€ÕlŒ¿]óu[K#\»–w)ç :´{Ë2X§U_½rÊ9{¦ÙŽù<¡@©<}â˜+,jµúÂٓç•”ÝÌ¿[ù!ïÒ@D`pèœ9ó‚ƒÇN™êz’Ü‹çÓÒÓ@*÷JNKõ êl1TWS—ÔñkcsÓÍ¢‚a#Ǿùb’Umm‘‘Q--îŽÚB‰ÂË7ÐÕìeŒqSS#46Ô?òÌ Ëžÿó“~8–­-/Œ1ÇÊd²÷>úê¥?þÍj6Ñ@Q=à^3|z(Dæ8 Ô‹ õ gÍÓèõ¨=ÊÈ8,IwZ=$¢9œž‘þ‡¿ü­ÃÕyì‰'vïÙ½déãÝÍ]„† Nšž8ijÖ¨ì÷.6!!4" &Lšºú‹dYBF_ €¼«W†Þ>^ÓÆ¸øB_À·Ûl™ÇÅ'™-SÞ¼U^ž”–‘_PR4qæ<ŠÇ ¡J®tm5TTÿèÐg\ZS¡Pv`Cm-Mjµ )v8l&³I©ô))Ê=z¬Õê­&½+m@¦ô*-.N4hÃß?ðÀøüüëmõá± 99gj«#£Ã#£Ö|ùyltˆZ­6ôjµzó/?fOœÖذ‘hG%ÚÕFw©?1MT\sDWô!Ànn¬3›Í] ŽÄ±LqIñæÝ{Oœ8n6@©ð¾zÕMXz³àZAÞ•Â×Z››€$IM« „ÁÆ›^¿öØÁ=®…ŲŒ‹ƒâñy"ù?ß|mä(·ºYRf·Yàr^á‡ï¼ú“Y†Ie™‹’µ57[ívÌãQ4ã8ö4)( @DgNe]SSGc¾ÊвŽ7PDu]Ë®u]V¯VûûùŸØ·³¢¼bÅÇÿ¶[-Àbp:Ýv¯Ñh2êuðøSÏýãõ¿~ôÑÇÓçΣø¼à Ð°`?ÿ Ÿ›’úÕªoó®]0mÖ‹úËÔiÓe2ɑÇü}ýºRõj8õ“~8P|e±ÃáìX%4ƒõ:]¥HêõzŒ¨÷?ø`üÈ‘±Q[7þ´ÓçZ^5•¥uSMy B,04-‹]Q½ìqã{êÙÉíù¾:†eX—cÀqηÞxãøÁƒ®?eN7›­àç%yýÍ×^úÛë$EõZ½Æ5äñùMÍ–áîßm·cãüNŸ:N‡£¶¦¦C%%%;ÚÑ"‹É؉ ùúûúÀ¹3§n`³Q²²'ΞÿoPhUu ÆX.á+ÛiÅj«ª2†fÀ†õß“=mÚ”;wZƄ䴤´ÁJo_Úéܽcëäé3Gg ùéû5ë¾þ‚/ûúÛ-Ä£ˆ~ÍÈÛz<·?äúá`:ÑQ‘B‚€ËÎTWU€XHùx)®\¼e3[ ´¬$1>Öµ¼DRoÎÊãóù<>Ö¨TÍõ.¹/‹;– ÆX£V´Žv9t`ð̬1Ï;æt8 66öÜ™“ q·RGH­Öعkׯ?ݾ9&>¾º¼rúUÅW/Ž7.*,xÑÏLšö`S}P>>!:)céc5öÛ/?½~íò̹óGË„{!ëZÑG͇1wh×¶Õ_|Äq fœ®OO=¨jm²Ûmk¿ú|Í—Ÿ\¿|c®ðÚÕåo½þóÚoŒ:5ÆøØ‘=×{ùÁ=ÛrÏÂkU­:ªãŽN‡ý‰U#Æœª¥‰ehŒq[s#M»ï[~« cÎbêì² Ó¨Š ôFc[sÆ M;4-õv‹ c̵³Ð±,Ûþ²4†a0ÆÇÑ4ÝõQ9ŽsýÊq¬ççtoÅ*÷§ÉAÿ¹„÷žf ž1ÅžhêãLtÏw¿;Ç ß®Úë÷ 3ÝžÙˆ¾õ_WW÷Žõ_kžQCÔëüqL— "ÇÑNG{J„Õêi1Z ®ðji¬giº¬¸¨¹®ª¼¸Ài³ ¯Å¾çÜ[½ãÁ8·O3ï'{;ìöK§ŽÜ,.ŽOM;v‚ƒfNîÛWÓT?þÂðØøsGí9rÔÏÛgÑ#‹#câúŠ¡tºµkWrKhtÌ¢¥OݸV[QŠHIM×è4Å7o>ýâsΜJ$MkîåµÉ2sö¼ñÙ“ŽÜ{ú̉>^ Í›=kß¡#$E½ÿÁŠ|çÝ÷`Íš5O>õÔŽ[S“Áó á‹D·ßžìkwÔ#èùK“Kõ}cdÐiÌ=ó‡?U—ßÚ·s‡ÁbYðÐCJ¯=›7ùø3üÉÇV‹ußö_#cbûB¹rs/Ï» !)¥®ºÊb6Õ7ÔÏ{äqŒñŠ¿3vü8LÛi‡Ýâpú Í—4H«Ñ¦LžÖЦvqjff$^»pzXö$_E°Ÿ+…õóV° ûÀØ1£ÇMðX„¨ã¾h|¿/xWñBÿ Ð‰3ä ¤š¦†ÄÔ”ðЈëyWÕ-mWò®$ü”™v›íÖÍ‚¤A™½!¢Ð·JeJ+W( Z5Byùûh5ºì)3öïÝ©Šíf³Å`!Áµ›as¬«šP\\reuA§  ¹UYë‚4:“B©Ø²uËÖ kÏ:â)'Q—'Á·“„ç¾Ñáé;éß6ì|O©TŸøKûqæØ>/_¿ÔŒÌ”t(.¼~5÷r`pC;Ä-­­MM iƒ‡{ê9¥"–*mVKçÅÝQSlµX%R™\¦É¤M IIÉÆÊ²´Ífq}‘/)åR×{šmŽó^È9çt8Ú»@ sÜì¹s&NšÑŽô³Ã8À}‘Q¿ ¥ìõû"W{¥RëLl`ŽíÚLŠeƒ†Œ@7oäÅ%¤L›³0m6Î??aÚì5«¿ìtîBŸW[S€Šò®ªš›Z9–ÁÓ4­ÑjMóØñS:@s¬·/l¨sçOXMÆ‚¢RW6[SK‹¿€A«Wëõñ1Ñõ5Õf“!ÀÛK(V—W«ZkJ‹ì ¥ñBý”¢û1²\wcò.L޹ã9lïœÖË£7ÔÖüõ•—æÌ˜Æ‘9xßÛçÂÁÝVÆ1$}dæøq'íÍ¿QÀPSgÎKLé«ä…v:wlÞ`s:Ç ÍŠ”ÞÔØ˜süpDRRtL" )¾H&÷¾™58$ÜË7Àj5©šë#b’Е˗jkÊZ´•ç'$fi[UeEL|rnÎ §Ó2bÌD¾@ž›sÖÁa»Í–5,Káå}ohwÝqá·övn?…ý„¯i„H MbŒYuk£_`˜g­ ê۳ЬßÄÀ¾Õÿ2uîzÄÛV=vË|ì¿§^?Ÿôõ§.‘ÅÞSOéì/ô”³…‚ Dð!|†`“ ¸IDATB"UtQx¨£¼§f%<Ô¤{0=ÄC3Dzëê#èt8Hwï+Ò[D³Én·óBÀ`µZìV“Ój¡(A’µ,C‹ÄRZMEñëj„BIQ(÷âyÿ€@ŽåN?Z[VÚÚÔȰœH$lnlÀ7 ‚‚ƒ-&cIQA`phgGpŽûò‹/N=죊dŠåoýë̉SGMII‹Ä�\Èç…†‡íغeÓ÷ëNç\ô•‹‚C^·&8$¬k3°ß‹¢7Ñ1pÅ‹ûˆ)züÌ¿qí/¯¼Ì2LÇ';·o¬(/¾™ŸW_[ÝqæÛÿŸ­ÖüòãšÆš ¼mÓÏ×®\êíFèäÉß}÷ Ølæw—/?wîtΙ“&“oÞ¸ñê•<Ðô÷î@›~úÁ• c1Ïž>Cñxë×~Bitä÷߬ÌÏÏoi¨@7nä[Œ†¯>ûðÌþc¾[mÐéÜ ¼Ý €®\8;a|öëÿ|«µ­ÙlÐL™<î½?øðÂÂHŠ'•ЇÉ ýÞç+Þ}÷üÂB˜ýàÃׯ߹B¸úDÐ/ì }Ô›å =chÖ°¡$ÕYðí´;cãSôz];Ñ ø¤„%OýñÉg^ ‹Ž@>ñô…“§=ÃýîcpFzFú`׿x`„³çO{p‘ÒÛÅÅÆff à¢câ }EYIJzºP,À啉I‰!ãÑÃG KŒ{áO¯bÎéªðH’,[ºTæÅ=ýòu&ó…3'ë«*¶oÛ|òè–aô:ÍÒcÆO¡x‚ŠŠê¶†V½Úæ*p%Œs ˺;1;yñ¹NI; ß‘h«O×þîDö@àDW7%ŽêÔ¸X«n+*ÈÀ‘‘Ñv»£ãë•Õ ë~úÎ_"š6k_( ÚF×WÊKK+êê)•Ë4<÷®mUmpx̨ñS¯¿?Ç1.¥ûÔc‹O_p«++8–@s,ú죌}Ôè‘Å·;i`8ÖdÒë Æ 3ç€ÝjŽ6tù?_’ä3Ïý!93óÒ¹£÷í©«®Y¸tYUuÉùœƒaa‰Ã|G¬ÃnÅF£Ö"v›ÍI3]ò~ §¢;™å}´»ºÀWL¦Ž o>_ TÈPKcÜ7°ã´åï½K ÄpÌw_¯zñÏÃ,ç`ÝþŸV¯mm¨`ÎàWèÎeHÛ­æììq-{¼#€\ZZ›äºæµÜK›¶îúaí×O¿ô DDD]Ë» ´Óñ÷7ߢ(bù¯ÍqØU1D ¤³ØCÛ CSmuDH G…%7ü“҆ùúùþ¼þ{“A;,sÔü…¸ÜÌq Ím®¢e½ÙM’«jm‡ÃÝ;nuÎeè woWG}‹òN^ƒÚ†äJQ‘Ê¡˜c…—Ù u7=ÃÜ–_~b9Žv² ©ZgºqŸïãIR|Wˆîfþ5İØn·wÐ:`Œšnæ³NgÅ­RïÀ ˆ(£Élµ˜P\||cõ-–¦Ï9½cËÆÃ{÷¦&¥ÉÊ*¼pyÿöCj•&,<’³[€$H–vDÂgÿðªŸWÀЬÑ‘ø›Ï>ÝüÃÚ丿À…Ú1hd6ê+«+8 ¹ô_¯¿öÞ[oŒ5 îÛ3mÆ´ÿE§ße“»ñ‘¢×wnÝúú¿Þà ®?äKx”D©8°¯œÃlöØ6›%¿¨Ð¬×N>KîíwõRNJÚ ‘DÞîßtP]¢S'O8̦isæ± ÓÜPÚ^jŠ1>°wGlltbʦM,‘ „¢¶–&¹ÂK( Æº*ÿ€`ŸWWWewâ¸Ø„H£A×¢i‹ ã DN»…/”ºö·P,À,í yB`c†â ]ªÁC0b¦½ERÏÑÀ¿mSûÛù…ñ™úká~-ÞŽÐ ýåPá^c ý>á­?Ü7ë qÇjå>sÍÜÞL!îö*h@a-ì>Ól4¶¿ ”JÛm˜ã0Ëëtt ´S¯Ñ4Úa@&£+™tš!Åý?0X“â6¦×ñ¹ãùãîQvíSqOJµ¯ T]QöÖÿ(.//¿Y—˜´w릋— ó/jT­ÑQ±vn>vd¿F­ööòڸ᧡YÃ`õW_м=Û6µ©ÛN?™’>èƒ7ÿ:bÔ8¾PðëºUƒ‡îÍ*È£¢öN¨Çž¾ó@÷§ÜzuÔ/`x·ñ¨ü¶9œ|å•„¤¤ÊŠªòâ ¥bá²¹ìÍs-Û¾uÓŒ¹óQ¸½¤FDÙd^öÔsÞþ§Žì¯¯­INIºy#wø“|}}ïp<'£÷Nw›Å÷ÜAoà +c0 ¢ÏªoWÝ‹’G9vXgSmSü ”’¢â[W¯[ÍŽÔá™”ˆ@˜uj›Õ&’HíîÌ ‚#ž¿kËVgü„©7 ò9M› xÂû§oî.‹w}iŽe‚Dp,K´§ÿbŽŽE$ÉqØi3"„Y×}ïªÀLm:E°¿ëDñc9–A…HÂC¹bèƒÆAo)I¸74ë €,†„"A`X0P*}kpp¨XÄ—)}}(‘;Dçë( Ùbmÿ"ÅGäÈÆN™?ß`¶!ŒÓ:ltvÞ¹³@ Þ%»i¸žýÛÇŽur,Ã8íw‡Fº‡…£»‹]% wªF@‰(> ’ )¡T.”È»!Vˆâ#ŠOP<×ü`Dñ’à Ûðî¸Õƒ]Ñcz”¢NYßWsì’Ùb4É¥Êø¸TŠ/¬«¯7Zì!!±¡‰¬Ã‰9ÌÞ*-uÁ›pkS]sSkKcÉfs² àñ(Ïd4¶ªµÅ7²Îâ‚›îåŒ1fiÀ,m·:í6ÌÒžÎ-Nhwµ»x‘<‚¤ÚIBî â°ÓäA$ñaŠÇ‚@.‡õn Ft/êó¶NE§Ô`ì4%äÝ&\‰º g¦©¥¡))}¨ªµU¯m½UU«i¨bYÒ?4xƬ¹ˆ Ë òbS)¾ ¹¾vÆõ‘á!ã¦>(óXKä^V“ÁI[ Z}Dl"˲e% ɃîJ¯ þ¼·qÉÿ—¶0tO¡^U£ðhgbÀ½‘Ì‚ª¡Ú/4êNŒ·^»®!@Ô°g?¾{ìŠÙ×½ðX³QßåŒð¿5Áÿ­ì~ý q/­IEND®B`‚snd-16.1/pix/sceq13.png0000644000076400007640000000117211147553270012746 0ustar bilbil‰PNG  IHDRƒýK°È-PLTEÿÿÿððð€€€pppàààPPPÀÀÀ@@@```°°°   ÐÐÐPЪþ pHYs  šœtIME× 7/39q"àIDAT8˽”=KÃP†ß¤I£-…ª‹âCý(.*‚kðÄ¡ƒPP‡Ò¥àMi—:uqÑ©Š(Ö% .‚ þÅIðø¼µm<‡\? â.9÷æ>÷äpó_‡†_„Ý’lŠd3Ÿ {‡dÚ˜ºùÁjÏ^ÂÕê¶–·ý=&?x‰2žÅ̧ÄÄdksãýøˆÀÆ<§¬ ÞÚ÷7ElB¸ªˆú. Ãë^}DDT­eš †Ó‹ÀrÔÁ:V6Mdüs´£Ý. ZÓÏ& ‹†EMÄ.’1¤LÕzÊO79dý¾äú%A¨¹ž’2u»z }ÐX1“ ¶$mÏB5 ÂÈÐÕG»KŸE z>ŸÅÏ*ú&¨ßï÷ãý~ l¸Ø+4ñ®Ð-Y¦Û¿ç°¨Ð8¬ï’ó¥®g¿r¬Ö."€AÂz äÜ`Þ~ãöû%\/zYÉô³yp솲ãØIÜÏOÍk¹Í©uç<.Ö±M=×oÖ4½-ˆöµŸwœŸš×r›Së>{\ÉOÉÇ0Ö4µQ¨w¹ŸvœŸš×j›ÏÖ}¶ý©ù6?ôa @—Ð[½m¥×q¥zÞ€.V½»¨ö‚ëÔ)va €žöÅm* ôøÓÀñ¹Â€.½ÏÕï"ªºÛoÖê kšujZìÿgóZnwl»Žˆ•lãñyÿºXí=ØáÍñ<!k‡õþ;ÆAQö߃%ÛkwpÀa°›Óà ¬a Âèåå% ‡³ TSºöÓÏæ]µ­%˯)ƒ™zÞ«÷À÷…tîcŽA½ÿ{ ¶Ô¼+·7gù5CŒæ<¯kXÚPæsV:„Çò“±{“k‡ùÌÍ«ÔòÏê]Ç Î^¿Y0T¯{å±Re0S„5CÚŠgZÏzЀáCz ´ÚP›!¨kÚ&¬.ÐŽÿ_¹Â ¬Fm‰Ì»Ëgæ®»d%½kU·øøýò^µÁ·ùtà“žƒ¢¤JdÆÚ %öBâþTwêwnû„5‚z¶Ç8 @ó°ŠÕêå3kÛ'¬hÞ« ݲ”š·Ÿ¿Ÿ~|îqÞΖŸÛS®mŸ°`ʰ/w÷ºÁ^{™™x¯&å3Ö€°a ôâjpšÊ½RúxOòL%2c÷SŸ-'ö<=kšuj(ÎÐôP%«ã}ËgC|^±Í9Û»îãÁFêy€¦öƒ™Ôœ©ß©÷WJ‡®ß?7vk×]ß7¹ë.YFÉAˆž5ÃÀ§JO~Z–ò“uç„zNíëÓç)‘I‹÷Ê©,€zNƒ€°„5k WƒÐTn¹É³ ]#–È,y\l`0%2©Ú)®þ~9+7 ê‘Kd–>î8M‰L†qVnr_J2÷y#•ȬÙ%22¨÷Áû{Å3 5íó›5]B+Õ³¾³—Ü»Í5ô¬èÒÃ>Vžºû·çÏ,k¦¯XOzµ^õ'íqvm€ëYÐ4°jK]ÎP"3öÿ³òŸzÖ £¶Ôå %2?ÙŽ³™Â€æÝr^ËmÎÝŽÔ}â!NƒÀàºö¬ k¹Æòêƒ|uXŸÝ 8 zÖ°wVF2v5õ %2÷Ï9{œzÌ~žž5̓:6¤h¬4æ %2·é¹ëÎ ja @sg·:Å ™¥Dflþ¾ôgIiPa @· ÞT¨w¹ê™…PûÎîªÖt ­X96•ƒ•X`ÇÂ\XÐ%´Ž·ö=ÌKdOï—üæ.¬è`±@^y°¥ÒßÜ…5 NXÐÌY‰Ìý´Kd–,#vŸxhyE ™³2’Çù3•ÈŒ…n(”Sm-_XÐ<°kæÏ^"ó“íw'¬@XÂæ3šYqè@àÚï…Ú2˜£”ÈÌ-ïYÚ=kºuèïÒ2˜£”ÈŒ•÷܇oªêVê`@X0ŒÚ2˜#•È<۾؅Tw= ¾r4Òßÿ©qÁg?Ðø´?TXÇŠo°vPsc×ïìG2s€é{¡«µ1V>SXХǹzP§Ú˜ÓþáNƒð½j€ßÕ=kš ݾ”[*rô™©Û¹rzÜ©ÇéY0L×”Á©Dæ' Ã^ €€Ný}ż;¶34¯¶ôgÎs€Á kÖ€°€…¹À €nR%2CÅ/öF,‘k×§mг [P‡þ ¹9C‰ÌmzîºK®Ö #uÔ,%2φ =æ¬D¦° K¯ºäë•Ú]Ó+Ö4¬+3ó™ƒPûRó„5ÝBëÓÇÌØæP(+‘ ÀP½êÚ+©¿å`ÅØà رpþ† ®¡g @Óe¬DfN‰ÉTàÇæ]}€‘ZwÉ2R¥A‡*‘¹ê\› ³”Ȍݞš–3¯kXçŒîÀÚ=íÜ€½Dæ'Û¨D&C%û  Þ”a­÷ €°„5crÖ@X3íÊGšɿð]4 ¬a ÂÖ ¬a kÖ€°a k@X€°„5ð¯ž+ÿ¤®®Ðö3|iX‡ÂÖ— üÊipÖ€°a k@X€°„5k€‡Š@Xã‹€uÃÚ˜à,„5°ôÎûýv@ÂÖ ¬aÍ×ñ[)€°a |gB@X^ŽÚ@XG…F"àð+§Á@X„5 ¬¹ÍVVt¦‹÷\h8Æ>k_z0kÀk@XŸrÚa k@XôÜjkà”kC !¬aíhÛk ¬#œn|½J^Wï°‘Ï2Ú˜‘ÑîWrí€ÀÖŽtü‚üæ¦×ß9|}X?ŸÏâÓ/+ìx><Ø¿¼w·-÷lDÉY‹í±¹°öʼÎvœ¥ôñWïôWÙvòÙvâ+ÓÚ¿wwýVöÍ¿ÕÕœ èý>\ýž­|6d¦÷×Y©>ûGõ÷ü;ðì»ÂÚŽ€Ð.í×h(РcX·8UP¢åU¬«®Ëëè=³.ï™uÝ¿¾WéŠ[†iÈÿþúëñ÷ÏŸÇãñøíÇÇë?¦X6”ìc%ûâûíë_õs¶ò{Æ =ëý…9Á\úøOüýóçã¿þùx<ßKw²;— %ûXɾxÇ~{çúWýœ­üž1hXÇB7ÄE€Æa=ªß~üxü¾ûÿ'ŽW.»§•œfo[lûd_¼c¿½rýßò9[ù=óýÑ_ðÖ­®´èÐ…+Éè=Ó6íÒ6íº·m†€Á k½—þveèY–ÕåÖ­ÒTF9 €uìëP³%–9¥Ó¯Ì´W¨wùM¾;¨å€C9óÉÿ¯Î4§Áaâ/Uêà;¼¼0wÏÀ'(³¯g±ý=:=kXà‹g íX{›–š¾þñ1©å”®7µ|hy°»ý›a|ôâÍr„#|VB=êP;öû\hzno>Õ»?[/|Óç´K=ë«O?ŒV~féIÇ‚o?-ÄŸ|ŽbËÉý,ÃHŸ¡Ø¾ÊœÒéWgÚ«× UòAö!‡ë?s¥á|EÐïO;¦: çg"6¯dúÕ™æ3øÒ^Dì·ºã‘èÿ9_89½A ™»Æö=ßÕÖ+p58°ìAèYMü'U¡Â¥ü•|IEND®B`‚snd-16.1/pix/coscoscos.png0000644000076400007640000000623711147553266013661 0ustar bilbil‰PNG  IHDR+ ÅvÉ”sRGB®Îé pHYs  šœtIMEØ$$yˆ`w 1IDATxÚí]TSU¿[Û‰ø¹5‘ƒÀŽx*Ì(*L¥Žžrjµs 3ÿ°LOhyÎ:rNuÑQ”ƒyN%% Q‡”Õa -ÓCÅÑðÀt.˜ c öë±½õÇí¼^ïm¯9Þõ}þú¾÷½÷»û}ï~ß½÷ûy÷åõzƒéÁëõ655ÆM›6ÝÿýgΜ±Z­=ôPbb"sqPƒÍ\‚éC¥Råçç¿ð /¿üòþýû {zzn_l6›O9Ô¿u«Z&›Í …III{öìillœ7o`Μ93Ù“ÉtüøñÊÊÊo¿ývš¦”JåµkײÍfëèèÄŠuwwËd²à"ÄjµNLL@ÙårÕÕÕù+I­e"$&&*Š“'OŽŽŽVTTlݺµººzttt&Û  ×®]{ðàÁ¢¢¢éØëééÉÌÌÄË7nÜøæ›o,X°oß¾/¿ü–ÌÉÉ9wîÜܹsý™Òëõä“§±±qÆ :ž‰åóù¿þú«O#ÔÚ;d Ã`ú@Än·CÙãñX­Ö™oƒB¡(..ž¦‘òòr£ÑH>\ZZêõzûúú-Zµ&“éÅ_¤0UYYéOµmÛ¶ßÿ;DQtçÎþ Skowp˜Œp¹\.—‹MJ###g¾ ?ÿüó²e˦iD§Óa $L~þùçá>66 µgΜyòÉ'{{{U*UTTÔúõëƒþQ‹e·ÛÝn7‡Ãùã?JJJŠ‹‹cbbòóó¹\.^ËÌBÌ^`xáÂ…sçÎÁ,wCCƒV«¥¨…¢¨Á`À¯»È²@ €Cß'Ÿ|RQQ-ããã=ÏâÅ‹SRR¦Ùø¸¸8¸Èt:'Ožd³ÙáááØC ÓÞy`ÆÀ ñÃ?¬Y³&%%eÆ „Y½Ëå2›Í:®««‹ËåFlܘ&²²²à"œÛŸ?~sssvv¶Íf{çwÊÊÊyäBáÖÖÖ5kÖÀ1íÔ©Sýýý¥¥¥Ø: ¿fÃת©©yíµ×rssááåË—SSS#"" °2W®\immÅI(ÄÇÇoܸ‘Úµ°°0§Ó ——jµ:==}ñâÅd- þÆêÕ«_yå•/¾øB,‹ÅbŸeFFF>øàƒ£G–””Ðò£äpºqãÆæÍ›OŸ>­T*—/_çÀl6;77•^¯‹‹kiiÉËËÃ###Pˆ‰‰yâ‰'úûû1ƒ<ϧÜÖÖ¶téÒE‹Á2™LIII»wï^¹råªU«t:|.¤§§§§§cµ^ýõ]³X, R©RSSûí·G}” ef¡T —º¡ÅZHy­ÊÊÊŒŒ ©T:<<쳟ϯ¨¨øÁä–šA(Œ…“Ùl†g¦¦¦–/_>88xâÄ ™L(,,LNNþüóÏe2‚ ÃÃÃZ­vîܹPîééééé¹~ý:£ "";‰É¿üò‹T*]·nH$ª©©ttt¬X±°pá–––äääÀjjjêíímiiéîîÆN"}áƒÁpàÀ©TÊf³ Z&J…¶¶¶Ë—/Ï6k£££Ç'Ë·ŠÉÉÉööö?ÿü“p^£Ñðx¼‚‚Ç㯮ÛíÆ´ú5>>³©ø6»\®çž{îìÙ³mmmCCCXáÁÁAµZív»ñW¯««Ëh4ªT*™L¶cǧÓi·Û‡††4F£yÿý÷¡055¥×ë÷íÛ‡Õmmmýé§ŸÈ2v»}jjÊëõ:‰ßÚÚÚ/¯Ùl–ËåÐ4>11AÖÎr`w¢ç¸\®‹/Úív‡Ãáp8Ün7=h6›:D—'ôZûñÇU*Y&“©¶¶öÚµk¯¾úê±cÇÚC‡ÊËËiñËívŸ8q¢  KÖcm&„“? §NzüñÇ%‰L&“Ëåï¾ûnss³ËåÂÊ`^X­ÖÚÚZ©TÚ×ׇ¥þ?úè#øÈÀË!Å‘#G,KpÚÙò]ó×s.^¼˜––öÀdgg/X°@¯×Óxi¶YóIÁ1K>Ù0¼ýÂÂB‡sþüyºüÂÓeX›ý…`1ÇÇ{ŽR©„³•ÁÁÁï¾ûîo>ÌÀx½Þªªª¤¤¤ññq±XœPSS“œœ<44´téR‹Å211ÁápÔjõ®]»$R¨­M‡k ŽYòɆáíWWWgggoܸQ£ÑÜwß}PmA´×®]<¯´´A|Ž„°›Í&¼"÷ôÓOSÔŠŽŽ^²d Y’’’‚ÖÒ êÎf0"##‹‹‹ï½÷Þàz¤‹¼^oKKË–-[þÎ…B¦¹¹c`êëëm6[QQQUU•V«U(±±±+W®DQô™gž‰DÛ¶mËÌÌÄÖÊx)ÔÖçÏŸ_²d ‹Å äc“`¶/è8}ú49ƒòÒK/a‡@ Ø0—õÕW_­X±â½÷Þ+//÷w?ð~Á•Á6ãÃÉb±tvvÞ%ÉçèèhŒ |v6@oooSSSbbâŽ;ÂÂÂ7è¯ç´¶¶ŠD"ØE9>¥RYXXؾ};@"‘ìÞ½Þ~«Õúì³Ï–”” †·ß~;??Ÿ@…Ú‚ %%%ßÿ=|#‘úÌ&˜%‘H$‰¹š6Œ€¼¼¼eË–½ñÆ0¿ùôÓO ûÂrss±ä»?®ŒH%q8111wI8ìL>©H—Ëõá‡áÓ³ƒÜsŽ9R__ÿHf`ÒÒÒ°W CZZÚÍ›7±ô÷Í›7 ‚ [¶l‘J¥â(ÔÖx<^{{;~¢EqHf“ÌR__ŸB¡ Él9Ÿ¼sçN¹\N”Çüâñxðat«\¹S>üðà 7K|R‘aaaµµµ—.]’Ëå)))ëׯd)422Âçó}öE;;;±‰ 20õõõ‹{„oß¾ý­·Þêèè°Ûí©©©{öì‘Ëå|>_£ÑìÝ»·££ƒÏçÇÇÇÃ! #Žî¹çž°ðlYÊÈÈÈÈÈ ®Ù°ÈÈH¯×›——GŽÀ²²²U«Výçz ó+@ºŒÃáäääÌf³Ùººº.\wWº»»¿þúë½{÷FDDܪ5«ÕÊb±þ—÷cƒugËÊÊÊÊÊÒëõˆ‹‹Û´iaSþ®effæää\¹r¥««‹Üs¬V+‚ ÿÔôÉÀ`¹T§Ó‰e䆆†à¡Óé´Ùl&“‰L"͘µ[â606)ÌRCCÃÇLÍ%"BM¯ØþÐÁã"‹QõWk`` ðÔü,GàÍd2MÇ5Eu:vHA/qD¯5<›D;³töìÙ7ß|“¢¢(ZQQ ç×̰a¡ÞÄÀèy+ÅbmݺU­VÏ6kF£ñ©§žŠŠŠ"È´àêÕ«UUUåååø¼+~qxéÒ%‰Db³Ù` ü¢½Íys‰Düì?úì³Ï™…b(@Û›ÙôGtYóIô2Kãããk×®åóùä}qn·Ûl6÷÷÷³X¬ýû÷í׌±a>óæJ¥R,ÃýGwäÞ¼;*ï68ŸÜ áááóçÏ¿]œ éþ#LÒ ¡P( ï$B½ÿˆ ü‚̸öA9@ ~³^拽Á‚bÇ:†¾¾¾ÉÉÉ|Ðg¶f–O³¹\.‡Ãq:SSS>™½cÇŽÁ—( æ;1Ác`` <<œz^wõêU¡PXYYyÛy³/sæÌñG¬3áÇDàÿ üŽuEÝÿ ®®.//oÞ¼ywòç.0ëÀÿ„@hµZÂgê×­[766ß!œœœd®f ¤YYYuuu=öXTT›Íæü@àp8A¼WÉà.“‰ eee‰¤ºº:77·  €ÍfÙ'†°°0µZ ¿ú®Õj7oÞÌ\4LÒ9 åñx(Š"Bñ'-f³Ùn·ÏäFo·þzîâÓf³¶ßIEND®B`‚snd-16.1/pix/nrxy-r.png0000644000076400007640000014217511147553270013117 0ustar bilbil‰PNG  IHDR¸Í7º#sRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØÖí IDATxÚì½w˜de™÷ÿ9±ª:MÇÉy† =y``ApE‘$" ü]Ã*ºû*®×*®êó’D‚ˆäA$ˆ0†A`drwWÕÉáýãyžsNUw£û{7ê¾®sêê:]ÝÕÝϧ¾÷÷¾ïGKÓ4¥­hE+ZÑŠÿdè­— ­hE+ZÑH+ZÑŠV´¢V´¢­hE ­hE+ZÑŠ@ZÑŠV´â//vîÜÉ5×\Óz!ZiE+ZÑŠÿ\ô÷÷£i×]wÝŸõø0 ¹í¶Ûؽ{wëÅk¤­hÅßshšÆñÇOš¦lذ-[¶Œù¸jµÊ† 8ÿüóÙ¶m¾ï·^¼ÿ—×½ÕÒŠV´âo%’$¡Z­ræ™g2mÚ4®¾új^ÿú×sÆgðë_ÿš'Ÿ|’Ï}îshšFWWWëk¤­hE+D|êSŸbëÖ­Üxã,[¶Œ­[·òûßÿž®®.~ü/ïg1g¦õBµÒŠV´âï=}ôQjµûÇ`RúÃ{†yýú£8õ”wPÙ|ÑÝß Ü¡×uz’ iÒ†¶qGë…k¤­hÅße Ý»n®ùÖ5ìzq]ÀÛ—5`¨ÃâvZ…¤I†’ w}ö N:é¤ÖëØH+ZÑŠ¿¦pÙÍ‹$èÄÄâvg÷éiŠ–n!I?€í‡POê u®ç i:†!ÀHª:øàzP‹àÊR…9Ÿÿ6­Þ:hºüXM“‡.>mÈOùCŠ÷]ù#Øë¦\ìÕÂoÊÛM h¸¯4ÆçJò°€(¥`ƒaÅvŠiFâ>;Æ4"´rŠaÅXfˆf§XVH’îgà(ãe øsÀÑN=ÿ8±ýÝIÐk Z=?£á<,üH© J¯†¸‚|ú÷?:µ‚‚Ê¿vä€?o¥\‹¹paëºVü­ÄK/Uyé¥ZñÏuŒÛÚŸý¹;ïÜÁ×¾öœ\­Â‚oäg­i…×ô1>Ö³ûwïz]~N—ÓL ù<†¼N×ÀÔÄ¢®``«p˜(XM (¤4PšA"’)KÀÃ4#´’€‡m`ƒm˜F„QбõÛЭ„ŠæRÖ•È)ªjšÃb,p”G:x@/ÄIÚÞiMº š;Æ×¨æ¾H\pqp"Iá’‰é9ê(þíßþîîîì/)MS}ôQÒ4å3Ÿù _|1k×®mýsÊ0[/A+þ·!ñùÏ?Ü´ø‹ãÁ·ñÀ/Þ¦k…ÛúoãÇ;šßêkêíSþu5Hä9‡&õX-Í¿=4ùíèP2,ô‚ò0ämM/<õ8ð°ÆÈŸRã¤4ƹYØ)¦a¡HM)P˜ %ÝÇ2ÂLq” KiÓœQà(ã 0¤®8ãÒ;TRq.E>íIRäS<*±‹íX^ˆ†hN*÷šT5FùiXÚñùDc˜5q(e¡¹“½ÙL¯ `Äuð]ðp}ቌ¤P•ßÂÖ;øãW³gJî©s‰^{*þÆ·Ñ4-“ríµ×¶þa[ ¤ ñÔS;¸âŠM\sÍ3¼ôR½I-4/özDŒqaŒq}óÙÈ•„VPZAhòñzAEè…û‚ 1t±úë…ûu]ÀB)S÷™ÚøJã•àa@aýi¥ÑpY6èV‚n'fLÉð1õË )i~‘ .¶PÑ…Ò¨àf £œJÏ#u©ÄR‰$åXžO€"q)‡vÐ9˜~DÉ÷)E>F=qÆ’Û¸Ë@óS´jJº¯†¶<€©þ4ŠJ¥Æ˜†z*•FTà\¡6|ê¡4ÓS0&€¯C¨Ãa«a¨%úHFà¼Ò ÞÛ½hšÆœ9sZÿ°-ÒŠ¿”¸í¶ßqòÉ70<ÉÝ.|v,0ü)å1@š¡Ñ¢O¡É>ó+ ©(´<¥kyŠÊP‘P(ÞÆŸ7嵆&q`ñJËÏ ÍJ£øqE¦¯¤òÐÍËÐÐ*šK ?KMSR(*…QJD¥T9ñ(E¾IäbG¨šŠʾG9ö2•Q ]t'Áö„òЪ)¦Z#K»°ƒ+‰×˜F„éGn,ÔD„㤵j…´–GT+”íz8"EU‹¡š€5úfBŇY3 #_'Ýmu§. ³"þ#=ö'œpBë¶Vü%Ķm5|ðEÎ>û6†‡¹Ò©Å¦Å_'=¥£,ôq”I3@LF™Üº4¹›á`’Ý_€ƒRº‘û $¦–?Ö,¤¯þÔa¿@Ɔf§Ù}YU• µQŠÑíË 1M‘¶*šÞÜQfxŽø8u…ªÀ£=©cG•Ô¥ùÂÇHEJʃ¬üÖöQUåDXAˆW*£…)i¨±mÑT¼éeñ5u³3ÂHc¬(¤T÷s½6†ÊÃI¥Ÿ‘ŒˆU ÁYµCÍ„  _'ÊzÍJ±ü;óë⚸Îõp†iı6P«Õxç;ß /?“gµþ‰[iÅÿF¼ðÂÇÿC~øå‚ê(,è£òŸñ4š•ÆXQÏUHY©4–¦åjC¥ªô1@¡n›äP)* KÞ¶i«‚i®~d“± ñ披1RTª‚*+·•È+Á°0L+Â0c 3ÆÒCqh¡PE…QHQ)€´S§:¥Ô‹}êeJ£’¸XaH)ð3¥a‡¥ÀÇðbl/`GßDœÞ6J‘ÏN¡døYê«#®QŽ=J½7ÀòCôzÒh¢+¦ŠUXÃ98<º8|ڇćÊTèœ!¯«7z"T8Ry­ŠÔV5ÅYÙSš&ï?n=/_z6„[á§7ÀõOµþ‘[H+þ'ÃqB.¹ä~®¿þ·lÝZ'¥Ôܼ`ð§ÍòfÕa¾TÆH¦.´´1@QHCé…J*õyCÞ‡Rº& 5™æÚh•!Ïš•6|¬ÛI+Éú0”‡Q…aÆ Ð0Í݊òBô’0Æm#êCs”†R"ÔF•á*¥QNÍfüp®ZbG(Õ'¢ªzk˜àkðê•ø=½Sàùm0‰§ÃãÏ£OŸÞú§n¤ÿ3^Ç®»î·\qÅSc€£ ü*ã•T‡9FêË ê0 *B×rÅaß6 Up0  P©*°µhd€P·•š°òC·’†Û "† ÓŒ4ÌÓ·-#Ä2C K”àšV„iG”u/«®jNUee·€´áˆ ©,J±O)ð3åñ\i5£;xzò %ÍÏMöÄ¡û”Cá“Ø^]§» ¶ˆfÁZ"¼Ž*c÷y4w—@:˜¡ Ö«¥%UT+ÕFµ¢G\)*'€Z Ciþ¥§Ì«q «æ‹T*‘+ª·œ~=¸”Ÿ<—\rI럻VüwÅöí>¸³ÎºƒÝ»ýWPFaÑ×þ@Šp D柸¿pÛ(ÀC×AaAA“Ò(@£Œ ¹²Ð­$†ˆ2±5[6ò™q–ŽÒ ©.L ¥>(²¾ K4õYF˜) ÓŒ0,QYe™!†SÖ%ݳoC5ø)%Ò†)„¤†Ÿ–ØÉ·¯¦-uM C3`”Y¢+ŠÄLWx!¦¡; †‹†Á‘´Qi4w—»@›œuÖY|öCÓÙÑÓZi-y­ø¯ŠçŸáÄÌÃïxhŒUeõçšãÆ8é«ñª­ÆH ·)À¡‰B f§™g¡™i>¤Šua&™ò0Ì8û¼aÆ™ò0(SJuVŒe„Y§¸JOÙF€mŠ¿’î‹ÏÙ‘¨¬2L3¢¢¹¢D×V%]œ›þ”ß¡ÀўԱ⇰½i¿+ÏÏG—$އìó(Ç¢êÊö¡8dŠÊL/Ât¢¬Ó|”§1<ŽH6°žFC}¬fæ*¬Ð• ‚²d·–€9ºf@G?LžÜ”æ’ %rEõ•N=†‘$oQ©Û¦McOOLy×Ëœ8–­ |áú1ÿn¹åjµÚßüÔß@Zñ_®±m[ãÿ ¿üåî?cÑoîõÐß…~Ž1b6ݯ¼süÒÚ¢_a7­˜XH€(p(`ƒn&™ )*  ÝJ0 q¿aÅ QаL¡44+Å6ƒ .%ÃÇ6(Jšˆe†TtWÀEös¨û*¸ÙY¢-u²Àrìá&Œ(æ–ö£)¥>Cz·Fê4*È¥û¹©гå 3ÝòB /ƬGPm8ÍWáêç²\Ï’¿ª~À/,òã O”“vãºHOy¾¨¢r1Ê$,Á¼õûâ×ZÖhèHOeÕVè‰(žG"R\UÀ3A³Áœ6ƒÕSb&Ô‡éJ´½.± êÝìºôß8îï@Ó4¶lÙÂüÇðøãsôÑGsðÁ3oÞ¼@ZÑŠ?ç·‘Ë/ÿõŸ¡6Æ*ÑÕ^4F?GˆB“ úX“#FÔÙ£*ª¹;¼¹JÊj…f¥âc;Íî/* õ8•zÒ¬4KIéf" !ï3 éiº%= ™ª² KWe¦¸RÖ¼Li”5áu(µQÒ}Ú49äPsÄ(‘ت!ðø½5/-c&tìŸ7¦nÖï¡<ì:ém”#/óHÌ@* 7©©yIÓxàx5¢ÏãòHULý©ôT­Pvë‰Îr'€À„ÞU˜0}L<‘TöˆD®,÷UÀQJEVaÕ» ¦õCOöÈkñÜ¡';Úåu¦°î“ŸÄ0 †††8þøãY½zu+…ÕŠVü9qóÍ[ùç~œ_þrq¬Þý¿’‡¡1v£à+íÅ™TZ¡“\+‚¢ð9]—àÐÅ,*õq³wѤ4Æ,«•QŠB·¡H ê¢x[·’<=UHÑüÖ éo˜ÒÇ0¢ÒÇP•SÅÛ¶PÖ=¡4tq[UW•u²&ú6*šK9é¥r$ª¨âÄÀc~ѱ/5«Çh^F“ÒÈ:ÍcÑU^ŠüLy”Û0ü½*† f£HÆFIâù‡3 1×ê•Êv¥Z@•ë:²«Ü/†¨,faÍ8 ¡­³Q¹¤8Q=‡µR—Í…UÄ´ÞØ†Þ>X2ì&hr?Gk”J¥.«·Ôúnܵ‹ºè|>rÑ…h½ÐÖÑH+ZñJñÜsUn¸á9þñï§MàO4¤ @´ QBÖ^œ3¥Fá>CoTºQ(·ã”Ùb‘û R¨4T³Ò°Ì0S% @,qŸiFYÊÊ4¢¬zJ) [2 ”tÓˆrOCšâJu”SOôlÈ.ñRàgfö*3 ±øm×>øV)Så4Ÿe¥RTmqnŠ«TU)UU™Òp’F`ŒŽ´ Úᆠ½Häçg`Q¾›¨)»®†/ÓT‘ +ÄïfòÚѪ%­I•âHèHoà   h¨§²»aâôtÀü~Ù_Ro‡¯®+ô‰ ÉÁ«Tx͹§ðïß¹’ÛcVkÀ¿\ ǽ£V´b¬ð¼˜]»<Ž>úžxbˆW®°Ë,oˆ^è±ÐšÔE34ô¦ûõ&€(Ph²7C—×™…Ç5Oº %yaþT1%¥›IVMe¯ 4äã,3Ì>Ÿ¥§ô0ˆ­YK)  Ë3µaëA®4ðDy­<Ê¡ìÕðì8 JMžì[Žg—qì6L=¢„Ÿ+Tø m‰LmÉôV%–Ý瑇ÉAW(QÀ(žÕêj‰EX{—LQM)xõÆ´RÃY.þj4»¯~" ´˜rC¥›†²]5‰7ª‹ñì‘ôEWt–W€º)ºÔû&Á>3¡”B—–_WeŸˆ n$Lô* †‰ ‘¡±rLë0èI5JµPÇoæ<»7Ò7uj ­hEs¼ûÝñ•¯<û Šc<ÕѽØh§fQ5¢ Co+¢ëMРPU£G ]vˆ«Û…ÔUiÏ£ J(%‘) 3 ° ”é=VzJ©Ž¥!aaaæs”4?Ûѯœä)©r û,T¯Fä£Ç ÏwÏB#åé)ƒJ1N½-ÀP©ªLy$ŽøºQ®4ÆMM5$­AÚÚ2ÐNl†:G“ž¨1$²ç"é"s”&Aû\˜0½ Õ.§ìFrñV£Lœ@¦šÓz¡·z»a΀„N½ 8jM}"äÅa*»6­ÚK°¤&êâ{Iª)¦PµuÖâAN=ë,Î=÷\,Ëj¤­¸å–ùô§̓î!ItþüŠ©æT•Þ8J¥”ÆSE€d·µüsFÁë0 ÷›…´•¥å cÍ 2B ¥a˜qÖ¯‘UR@aQ–’*ÞV{m¨™T "E…QÒÅÃ,¥†ô1Ô"¯Êf8Æ×Klšµ‹z{»W’ÊŽs µÇ(€ÄNÖ(˜•ÛŽ§4 ƒ SW ½O¦‚q”\LúÛ ¯7zj I$¡¡ÀaíË¡k°Ê`›¾F¢RTõ<Å:bÇZ,”Æ0¢ k`Ì™)~†‡<’ºøn˜+”¢ïïè©™²j: T WCS9;Ë E©p=à¨LøwÙ6{‚€Ÿÿ.>öÑK ’œµÖH+þã§?}™×¿þ¾1LòñæO3êy  YP SoÇ€†šz«à A¡RU…Ñ"Êÿ°µÜ@/çöèTU6ª¬äV6üeJÃŒ2°(0d¦¸ž¤ÙÏÔ†u¡ÔEìåý‘—Q¾†IÍî ÖÞÁž®^võö7TP©*ª ©K{"7tJÝlc'+±¼ð•SSMJ#®¶XÆ!cxcÕ쪺èÕÜÜ›PÍ~–Açrèœ.¿^SŠ*‘ÀˆêÒßp‡*Å0y¦¨Ö^::Éá•;Ë}ÑRô4ÔÓy,ž z©Â¡}.H¥y²ò+‚j$€1ÒÄÚŽ•+éÝÂÍpë“¿æ_ûÀòÁxz:'´ÒŠ¿¯¨V#Ž=ög<õT•;"Æ/¡oŸŽÂ¾c™Ôņ½†©·úhEaèMêbŒÛ–Ö4zDBÃÖòÏ—ª*BEEÄL2Pd~2eÕ¬:t3=z”}¾ ‹RYÄ^æ9”#/›;¥à¡º»K¡)”bŸ§gRíê$*›YU¥,”Ç!J,ÀQŽ< ' ÇPÍàP=‘ÆzЦ ¥¡éŒ]v[ØJ•ÎÆ²*TŠÃe´ ÓŽ ~ûè…ª¬´š+ØÉ½‘ЦvM¥¨4mQEuÐrèk‹v*¿ò{|¨E¹B)¦¨|Ë=æµ `º ©,Û |¡nœD(œz"ö©5Ó$ìì¤wÉBÏx'}ßù]§Á#¹‰€¤¿Xs0;ßýnN:é$´q”H½^' ÆÝ[iÅ_m|õ«[øæ7Ÿç±ÇFÆQæ8y8 9\ÐNG—ÉGëFczJ+¨]+á…a†F †–žP·4Q¾«fSéÆèòÜ£«®ÆHÊ 7ŒÜß0¬x0TJÊ&È*¤T…S)ö³j©r\Rèê.Ç^6DÓRvôOdË̹¤%M¨tt•I y)ôÅ^µtlPŒ³ðG.è ”O)(g …R¨¢Šez(tsoCõ^D%èØ˜ÓÖ|’BU⥢ q_6úU“¼i=°aÚ ñ«_³@B§VHQÉž /5KdÕ4ÎÞ2¥€ù³&2«þGÑ•îäשÆÂj"¼õ£ÝÝL>âz§ö³dÞÚ¿þHê1± ¡,3VcPªÀ½ÀÅÀ~ðN<ñĆÿ³Ÿýìg<õÔSlÛ¶ÎÎNÞÿþ÷·ÒŠ¿ÞØ»7ä²Ë~Ç'>ñFy¥îrmtºÊÔD©ËX{zg{dhc«­ (ôfPhyŠË¢Ðß¡”†„“ò?lyÛnRöJ¤y7?‹VòòÔÉìœ2@½§=K}e&ºlT©*uØØþ5KSUÇGÁ”Žê…*¨:„Xó s-”ç2ºšªiê­š•CžÝ†c¡6F4˜¿fL†þŽ|uŒ•'â‹CmΤÒE#@M×ñÚÛ™òÚõì³v%}÷^CW{É#ˆô–'¾†JÒSUÀ1M’žö}ï{˜<À”[¿‹‰Nz×]Äná:-WUù¼®m3õ o`ŸN``ùr&\5Ú¯Ÿ&~øçøÛw hÈ꫑–·u nš„¶ÍÿôOô 2½b¢ór’›o&ñSÑ•žŒqU]Ç1 æœx"³>š‰ûîK×Ïn'½îûD=@ˆÔ˜ªúú?¯YϱçœÃ›ßüæqûEZiÅÿ’×áqÜq›yâW®PÅý2”ס|Ô I þ‡&õr"`Q–à(ª3-ø&FÁÀÖµÆÑ%†Ös¼ôyê*»ƒB/ì%n˜q¶S6ÕV* Óˆ°ô‚Ò ˆL[i!åÔ“oSÙ§‘ºyÓ_êe©©¬k¼XUUlˆÃÝؼd‘ØfVõ€^惨”Wf¾G¢gc\¥QG¢æ89zQåÐs$Øp4õk¨~5{*ðó³#û”w>e:,œ Ûò¯§”ŠˆÃ÷ån€M>ô¬[ÇäW½Šó&cÜpÉ]·g†´æI5ý¸Žaй|9=«V±ò°C˜ÜV"¹õâ^'*¡‚¼ß¢ørÕ€¸¿ŸþCaò!‡°ô老s;Ü{ñ…ÿ‘lFt‘žª5¥ÆM£kͺ,`ß‹.b²ïÜx-ÉW¿HUWMFùªé¤Iôp39†…'žˆ}Ïí¤W~…øÞ» B:/οouÝ;ÝÀw¿û]Þö¶·µÒŠÿýHS¨×^uøÓ<¾ÉÉëÔÈËuUÅUƒ±„ QsKÒç(ÇÒóhˆÚæ5›/¥ÒV5¡õÂÞäzcÿ†Yhš/¢†Êí^‹à°ô0Û;|TªÊ°°SyÖq[B¥”Š)¸jU[â`'PIîm¨‰µ@ /MÆ®ÉýÔz;('VŠÏ‡0²J+Sa{#cáêP¾FÖ¨§àáAy>t¯öÙMàhò6Âz^nëBiøTe¾_UuõÀ²Y¢|V¥¾7_ø]åDùxš4–­Y³XvÁ{è[¹’É×~Ó‹ˆï¸•°æã…ù¨ôzSUMÓpuI‡ÎÒ ˜¸r%=_ÿ"ÉÆ» Ÿy†0j¡žŒ‡£iè3f°üüóé_³†)û퇹ñ’«¯$ýÍïñž|Bˆ0 †ÊfMÃÓuf¼éM,:é$&®^M÷Ì$§LøðC„؆«Lø¦ÔV]Ó`Ú4V½÷½ ì»/W¯Æzï9¤uðÇ7ã{¡øžå¼®ZÓÏëhî 'ð3Çáå‡îç¡7NúÉËÑ&NnøN’„^x÷½ï}\vÙeÿë½#fk‰ýÛ H9ÿ=/ðïßÜ)òR^.›š¹úHM‘ÊJLДyn‰Ç*ƒ¼Œ<¤÷PNò ';«PyUœyeèù>ãcyzÓ Ã"<,ÐMµÛ_Š"0²³ 0(€HPdÛ¾êòó©ô84QaejBiX©ŠÙÇ •$W @â|W>UŠ‹ÕîN[ºF(˜Øg’¿ËÛ½–CœJäfÝç–ŽïmÒSiq7=7oÔ (Í‚®Å<©¬šê7odz•¬~rýü¬JYÕ¢Ø3æÀŠ)BuH~ ±,·u#qö¢|”GÏÚµô,_Îá^H_P‡ßDòÖWJó¼ç%°Õ&_#ééa⡇2óÀÙ÷íoÇúù$xžð´“NÅuÍÐP p×Ê•ô­YëÎ>›ÉkÖ€ëÜr ÑþûRÝü,ÍÎõÂ9éëcàÀYz衬<ûlJC{Ix€pñ|FR¡Œœ1šøÛ¦sÙ2ú8€ÃÏ9‡åËá±GHôC¢×¾JÀ8•%ÃéhO$îí¥íZ–¿öµ,_»sÛ‹¼ïûß&®ïŽú>zÏ&6Ür+‹-âW¿ú=ôwÞy'3fÌàÚk¯m)Vü÷ÅwTùòWwsãÍÃù€Aäî|’Êu b ÝP¨$â(%$Iîd½iãˆôbµ•Þì{(€UHîh¦Pº)ÌnÆš`Û l«W l`¡ˆQˆ-RT¦.b§rôH"&áZZؘªŠ çÈÃŽ%dçø¶©SÙ=µZO‡ð=‚Ó°Â0›œ«æ]•¦JªWð6²P…ɵ "‰S_í3ÀHiwžyUéMHoÁ•©¦¬ï¢ð-û9dÂ.¦´AG$ÁQ?ÊKXkQ^ U¬öwÚiÌxÝ똺nwßJzÏ=¤=†ÿû-"M7¦ŠF ¬Ó8à’Kè^´ˆ‡‚qýõÄߺ ÿÎ;pdF½é¥R×N?æžz*+WÒ³Ï>°s'ñyç8õ[oÉ®«5=g0¦Neß‹/¦Å ¦x æÃí«[·â=òˆH¡¥ÍuÀµm¦}4 O=•¾åËéž;¾üEÒ?#|ôê[·ŠçMS\ Úäɬ¾øbúW­bÚÚµ˜y/é½÷?ýWiü?–§—-cñâÅ,Y²„µkײ~ýú¿¨u¦¥@þÆbË–€ûæpƆ—d®-ÊIºjßD井{X`ù$Z;…6y»¤‰£,PÖ`”QÞ†-}÷æj+³°ˆž7 !’bJ d#Ð-qŒC2¥QÖ½,e#a¢KÅ!ÏYÚ*{lXi˜$ D*J~Ü 4⼪ÊòCÌ $Ž j<µn©TÐ_Ý…å‡^ŒbS¦Pø#¶ä)ªFu…g“gkù¦J ó¤äKmS¡w-ô/”+ÒKMÞ†ì.÷}‘"rCáM¸‘Ü]O-†ºN×þûѾ÷%^³ßBz¿K¨•=Ò<óf¹æ}ÃÓ)S˜°r%«N8}Ž;«^#}èç$«á¸ÔãT¤w ýµ‚‡ßµr%óæñš}ˆI«V‘Ü~;éÈÞìÙ¸Û·SMÓ†ý§j_£wÿýYòº×±üÌ31+’ßü†øW¿¢þ‰Oà|ç;Ô’¤¡¥E-ÜŽ® Űz5ëÏ=—I«V¡Å1áÍ7ã|0C›6á¤é¨¿ hôt³?œU矦i¤7ÞH²iîà"ü ¢š¦£S[€cYLX±‚U«xÝ…Ò7ÐþŒøÔ㉆†qýdtØ¡iìxúijµ'œptPËiÅ_ŒŒ$ñšxì—nž2Ò$<ôâÞâfe–'VÞÅ]Jå¨Úb¡>T¥•ª²Êª­¤q®ÒTvsµ•Öh–gêCÃÔlݧ,wÞ3LQ5¥à0.4”ʰ¤aäÉ òT€ÅÒÂL”ðs€¤¢D×ÒDÇ·ÊÑêrС æxæQ¸ÂéÝ5g€êô.¼Ie1>Än /ÆöL?×Eض¸BŒaŽ«‘ÅÝøŠŠÃ !ªÀœC g:˜ £§àVóU]ª†z˜éÈzL“y§žÊŒ­¿`jo]/l!}~©4ÄU%’JÕ ïÂõY³Xþž÷0°f “׬Á|v3Éç>CøÒ6üûîÉÇn+©!æaÍyë[™ÿ–·0yÍzöه䷿ÅûØÇpô#\ǵq¡ºV›8‘•_ÌÀêÕL[·³RÀùЇpo» ç‰'¦À× ‡Ì:ær W­¢wÁÒZúÙg…!µë®k˜H_mR)«>ðz—,aÆa‡¡ÉÃ~þóx?øžÎXJÃ5Mfu O9…)@W­FúéK wî ¼ë®,5Vmz?QÚ/fùE±cÂ>xÑ{¸ ¶×Ÿýn&üëå-€´â¿6¼ 5ùD-¢i_½«W3ë o`Å™gbU*ÄO?MôÜs8W^Iõ–[p¢¨A¡ÔײèZ¾œÎ%KXsñÅô-^Œnš¤µÞ=÷nÛÆž .À Cjò¿új€ÖßOÿÚµL;üpö=ïW¯fúÁcɹ½çGý®»¨oÞŒ £ÀáÛ63Ž>šyo~3S>˜ ³ggëõþá«®bø¦›päóÁQèîfÿ˜•+™}ÄhºÀÐ'?‰ÿì³TúSªÛ·7ôRÖÏ0˜{Ê)L;âfv]3gŠ'"†ÞùNüûî£ö‡?do~^kêTøøÇé˜5‹ÙG‰¦ë¸gŸMêy¸ÿñêa˜U_¾m³àÌ3™vä‘LY»–ö©Sá‘ìÚ÷£âÔpdú°–—€=o|#§Ÿ~:o~ó›[iÅÿÿ¸åV·œ°‡Dô`ÓVj“¦T¤0Q™ä…‘å“hÕ]i¢Û…r]+-ôxH¯ÃJGwŒKxh˜šPeM€£¬‹Û¶.TCI÷EÊÊÊSU ™êаŒ0ó:l=HI÷©èn4lCœ›½ŽR*”†˜a$ú.г&Ô>ßC÷Dó,Âu%l-@óRâ!ƒ´¦‰-`Ó0¼xô\ª¦Qé±Ü{Û-BCÍ“’}z— ²j…Ü`©°_ÃB±xì²–ã9êInj×M“Î+è^¹’ýÞó&<÷;´Ë>I´ùÇÇóÜBÕU±²H {¿ý˜vĬ|×»ÐMݲ]v5×mx×>x¦I4aå9s˜08Èš‹.¢oÑ" Û&Ù³ï‘GðžzŠÿ85ÏÑþ†úÑ’þ~zöÝ—éGÉŠ °ÚÛÑå^âÎ}÷Õël»àªÏ?O= ³´”kÛ„mmTæÍ£cþ|ø‡ p£Tß§~÷ÝD{ö°íì³q|Ÿz’dÏéLœÈ„•+™uÌ1 ¾ímØ]]B]½ø"þ“OâlÜÈÞ/|!û™‹›/º@÷š5”gÌà°OšÎ30Ëeâ'žÀ»ùfê—^J½p]1µfΜIû¢E,>óLæs †móϒÜñSÂ~×õ¨'©˜ÛÕ”’»·\æ[A@b\ù¥/rÊ‘‡ÃÜ-€´âÏÝ{Þÿ5n½ÝcÇTÅRYdY¬ÖÔï¡n[ZãÔÙæá‚jš®ªÂ²äÇ¥¤`–§y¹nQu”‡© ÅQÑ\Ý]Þ†ŸÕ¸ôLi(h¨T•L[)XX†¸¯¤ûÙ¹¢ ¢¼UUUÂþF"Ëu}‘šÒkIƒñœ ”çè8›x¦‰5!DóRÒaMT& ëhnŠáŠ ¸ÚÈ8e¸Ãr€¡“7éy….oÇÏûF€•K`J/ôÚBù$NžòŠœÆ±ª ¶˜nšsÜqÌ=öX¦z(]¿}–äÊ+®ûžl˜kžò®%{Ζw½Ë–1ûÈ#³ý»k_úþãS»çª[·fÀ(dÎÉ'Ó9>“<þ¥Ké*ô% ]}5{¿ÿ}†n¿]UgÞB°¦Ogå…Ò»t)3?\,¤2‚?ü?~üãì¹þzj##Ù5uùü3Ž9†I‡JÏ¢E ,_ž+ ú“Ÿ°ûÊ+ÙsÍ5x…çTà(Í˲w½‹þ•+ü€½Ÿû#?ü!Ã÷ßß9§àã,<ýt¦z(³Ž<2ûyk_ÿ:áÏŽ{ÿý ÿîw -8J©´/]ÊÂÓNcòºuL^³ݲH¾÷=¢;ïÄäaœ_?M]˧բ¯i,<ã f¬_Ï&ßǹå&Üò#Ìe+Y}ýÍLŸ>½V¼r¸nÊÆû#>ø‘:›žŽ„B°¥RÈÌjY®«7m?«"­Õ Œ¦Ý÷²–C¢bb›åE€Å¡{b»UÍ¥<ʺGIÊAùÊ4WUUJa¨2Ý’.¯¢Îêú²îѦ;"=•ú™÷a'¢ÊŒ" Õ´ ”F¡+›!±pk¯ÕàUi¤a±L;é¤U MÖ…ênaºžêºÎST±“Õã=¼‚Á­Æe”Ú`b74WŽ+wE•š@º…mXÓF£UŸ6Î%K˜ó¦7±äÔSÑ7ý®½–èê«ñ‚€šï㌑ow ƒÎU«¨ÌžÍ—\„yó0+´4¥vÇE¼|òɸ®K5Š& hӦѶ`‹N?9oxVggæ/ŒÜuIñÜi§Qß³‡Zf‹°+«¯ÚfÏæÀ~”Þ… ÅóÊ4“÷›ß0t×]lýÀ“„Z½žC›:•ŽÅ‹™û–·°øÔS1lݲ²k«?ÿ9΋/òÇœêï/GÁÌî\²„ +V°ßÅÓ=>f¹Œ¦ë¤QDí®»ˆ]—­ïxǨŸÙèë£{ùrœt‹O<«­ ݲˆ·oÇÛ´‰í'„_¯g?«‚¬W©Ð¹|9]Ë—³ïEÑ5{¶PGCC„>гaÞŽÔ‚ Á?R¯µ9kí ²à¤“XðÖ·büâ1´0 yß…„¿{Ç÷Ù“Â…óöáßn½•}öÙgÔš±uëVüq¾ÿýïó‰O|‚… ¶ò÷ü°Ç§/óäŸä]ÚfÚ¸¬ò=R CG³!µ5Yž;8hÜÇC.1 ÷«æu«Pi%gZ)s¼‚›©ŽŠ&UGA)¨V±T·lx™¢R„F: D%C|ÍŠîæê#s¤t7i8Xì‘( LkÀpèÈ•£³HëT½-lQ¹¨*(9:Ü•³¡T³^­0rcF?Lí‚Ieè3ÄÄÛHÂ#’sjIã¦Jja©,\Ȳw½‹U«˜q衤»w|èCø?úÎŽ£Þýª³gY,8í4&t³×¯§cÚ´ìoËyðAö|ãìºòJ‚¦wÝ`̞͒³ÎbÒºuL9àÌr¹áosËUW‘>ø Û®º O.¤Ju¸Àü·½é‡Ƭ׼¦Áרqíµ ÝqÃ?Ìž'ŸÄ-\gÏËâ3ÏdòA1uÝ: ™ÚRñ›ï|mãFvüð‡ÔwíÊ®UÉœ·¼…¹o|#Ó=4óq2¥²q#;¿ùM¶ë[ÙuõÂs—fÏfùÙgÓ¿r%³?<û™Ý_ü‚¡¯} ÷¹çºóÎì5Rà;:˜sÜqL_¿ž™GIÛĉÂNÙ¼™úe—lÛFõÖ[‹ï*ÆÚ—,aðïdò2uíZ´_ þÄ'¯½wx7iôRÞ LX¹’›nº©¡3ýÒK/Åó</^ÌÉ'ŸÜR ¯qÓÍ §oðñcbCú™q-E†VH[es®Ä˜sMzi©â¾æ± D™åVîëT•f¦z"`K»VcÎõ$%ÝÏΙjЃ†t”ª¾jVê¾’ágžGEs3€(EM¶5üX¤”ƨz u`&°´@RX©›Ël ›*ÁÖÅXGNu½|rmÑŸÐûºió‡xÍ,èˆAóäÚ¾ì÷ðe£]S³cÛt.]JûüùôÑÒ5kÆ®]Ä[¶àýèGÔ¾õ-êÃà ߲:'t-]ʼ·¾•…o}+¥îî,UälÚD´{7¼ôRö>ôuYFë 6dêX¼˜®+XýÞ÷2aî\¬öö쿳s'µ'ŸdçM7±çÛߦ^¯ãÊwÒ®¬FêdޱDzì´Ó°ÚÛÅ»o M^~àjO>ɶùÜ;©û>ž„\Ç’%´/XÀ~ï?= 6F.¿œêm·Q¯ÕJ•ë€_.Ó¹t) pÀ>½ÖÉÏNðoà^=ÎÈHCir1½5ëóŸçÝ_øµ;ùìIÇñ¤QfËÎ|øÃfÑ¢ET )º@þŽbÇøØ?Å\wSÄ®9‡Jõ^då²ú=ò}:4³ÑçÐJ)iI#-kãÄ ªl×.zâi”âháMs¨àгTJØF@›æH€¨¡† ª×#+ÅUªÃ 2ð(Ï$ƒ†&ËmåÔZ£_ýT<†òÔ¯íd¹êÕ{7¾æùÜÊÛpEJªÉþ‰@(zœ«‡Ð}À,ì5™üò÷åll¸¯6*ŠòÇMÓ ­§žÊäµk…b˜:U¼sþä'qn¾™ÚÃgïb«Mùz{î\–lØ@ÿªUÌ<ì°Å8Ï_|1»n½•ê /àÄ–_*1ãõ¯gΛÞÄôãkÖ¬†¿É¡-[xñë_§ºi/ÿä'h€òú=ék,;ç&®^ͬW¿z”RùÅ¥—bmÝʳßý.¦ãàÊ—>°mf}43_ÿzf½æ5 ž†Ší·ÜÂŽodÇÆTûÛìZ(M›ÆŠóÏg`Õ*Q}%Sjiš²õ²Ë¨þò—ìºí6œ={²_·oY,:óL&®]Ë´C¥cÚ´/&c¶žwõ={ØsÍ5£”JûÂ…,;÷\º-bÖ‘G6LÑÝqÑEDžÇî+®À ‚Q¿£¨³“E§ŸÎÄý÷gök^Cû¤I"•÷ÿH°gµï~—zµ:j¯/uý„+Ĭ°5kØ~ï]<óñðV xÇ9”.ÿjËù{Žçÿo>>á—ÏÄÒÔ–ãDÔ& yŸ‡¦‹wj–Ü]¯Iy¤%MÜ.n3;@¬T¦¨Ô”ÝÜëÐ 0ôXìW¡9´SÏ”GY“ž^¦:Tµ•ªR0°Œ\m˜FÔPa¥Ês‹yY÷²Nr; Då“#š÷ôZ‚QÑ«ÉhÅÑ|4H@;KØEÙ ø Û¸f#Ï]9q6‚ZÏ…r s¡ÜJ…öÁAºfLcíÑGÑñoÃÜ;BXõpe†'¡QKwÔÓ§L¡sñbö9é$öyã)÷ô`Ø6áóÏã>ð;.¸ghˆZ5Œåðl›öE‹˜°t)ûàtÍœ‰ÝÕ%òüiгe î3ÏðÌg§)ÕÝ»³ET sp™GŲ °ÚÚŒex˜ê¦MP¯ž*¨ ï(;–,añi§1iÍfrº)¦ Uücª·ÝFõÑGÙ+Gñ]¨Ì?ñDf®_/ª‚šÞ¹¿¸q#»ÿã?yðAF6må¯ò:kút–Ÿ{.}+V0÷¨£Fý¦IÂÏ/¸€tÛ6þxà „òZXpÆLX¼˜)H׬Y ÕW;ŸzŠg¿ö5ª>Êî‡Î8í•9sXö®wÑ;8Èœõë³’ÝlaÓg>ƒ÷ÄlÿéO =_B#íêbæQG1íU¯bÎë^GWSõÑîÍ›yöòË©=ò{y]¥ä€Êüù,>ã &í¿?Ó>x”:ª¾ø"¼â FwÞ™}¿àiƒgŸMߊ,8î¸Ì×P±ë[ß¿£;ïdhóæÿÈ:-béYg1°b3eG;@õºëpï»Úý÷3Rè¦W¿ã´¯™ÇK×âÅtÍËŒC¥Ò×Güã|ï{8ßû®ðš Õx[€ @gg'W_}õk¿H Añøpõ÷áËWB¤Éª§R’{–ÚÕ¬³[õZh¶†n'¥ÍNI*zfž7Äú1@4K*ÄÖªíIŠ&¢9´éyꪤù⬠¿¢¢¹i+YzkëA¬ïC•åj~>èP6õ©C) £–D¯%£SUòHª õ@º ôCäÏØd¨*,M‚#•Û¹z¡PõXŒ:wåY•ZêS¦Ð18Èàg0»³ûšï‘>¸‘x÷NÍ¡¦VŽaàK–еx1]r m'fï k¿ø©ëò‡ /¤úì³Ôjµ†´‰>imûìÂãgÑ '`wueza½ÎÐ3ϰ}ãF^úò— vîŠðuöÁAÊ3fpàG>BÏ‚”{{s!MÙóôÓD»vqÏ™gR®×yùe"™ão›3‡…ïxs9†ÊÀ†mg׆ŽÃîÍ›zâ ûô§±wìÀÛ»—€ŽÁA:çÍcÝ?ý3gŠç-¤{v=õñÐ÷ž{.ÆË/ãîÞMǘ“&Ñ6o³ßøFúW¬``ùò¥’Ä1{û[†Ÿ|’Ÿ]pA€»g¡L‹u,ZD÷Ò¥¬yÿûéš9“Rwwö=ì~ê)âíÛùݧ>ÅðOPß»7ŽñcÚ4*³f±dÃæu”PƒÒÇIâ˜=„óì³¼üÑâîÝKÝu3¥â]+V0apC?ñ ìÎNÊ== iÄÃÃx¿ú/mØ@ý…¨9Nœ:`ΞMeþ|–sÓ^õ*QéfšÄO<ÕUx×]‡[«Q“~JÑ ;:(/^Ì¥WnÚÄTRnþ÷¯±àäSZù[ŽÛî‚·¿ öÔ ‹º-7n2Ó¼Jùº!ªu- Mön(€(ï#)‹ÒÝ´¬å)‚ÂCyH€Rq´§uÚÓ:m©CGZ£¢¹´S§ ‡Šáг4É•×aëH_± ñ¹†™Vfˆ‰Fh!¦eó£Œzœ§ªª‰¸]M8ê Z5E« ˆ4”,ȹR>ÄÓ¡ó WÁ‘ÖDÙ®*çÕ÷ €xj>Ùý;É>C¹PÍ4éZº”…§žÊÄU«˜9iÑ7¿Nø•/ãHS1j ¢în:–.¥o¿ýèdÁ›ßL¥¯/ûyê)vó›l»ê*ü¡¡†J&¨H_cò~û‰~Bø##<ù•¯ÿêW<Ë-hÃÃøÊ_°,öyÛÛ˜¸ß~Ì;æ˜Q*%MS¶þä'¼ü“Ÿð‡›nÂߺ•H.üö¬Y,>í4¦¬[ÇôCõ®=~ýï°ãž{xáÖ[aï^Š˜w L9ð@öyÓ›FUAñÙ{ïð¸ê3íÿ3gúŒzïͲeIîÝÆ „cšÁC-äÝ@I e7¹’MBH§&¦…/¶l0¦l\p•›lÙ’e«kÊ™vÊïï9G3’L²ï»¿]²;ÏuÍu,[£‘§œûÜÏý<÷ yùeNýå/´­]Kìøqt㾞ÚZƯXAÙYgQuÞy)š†¥1ìÜÉÑgŸåøºuDF3˜FÜá îê«©8ÿ|Æ|ö³–v”25¶~=7ßäÈÚµhÇ7ž«à7ŽÆ+(?ûlÊæÎ1ùµãpwt°ëÑGñëºÅp´¼<\ΞMÁÔ©4^{mÊë=tˆ®‡&ÚÞN÷êÕ#v[òçÍ£úòË©<ÿ|ЧOzŽ;:<ø Á§Ÿ&Òߟ"¦› £æåѰbE³fQ·h®ÌLþmî,J>ÚÊìÌ Þ¹ñ¾üejGy Òò\'NÂ’[¡å(b©'p‘3®í]HXm+Éa‡kèˆkH,7§­T¯ÝÏ5·$þ-(’Äa°IëE,Àði2„¬Ö•GŠZ@âµ öaŽÔú$Ù iJ,Ì…@‡]ÁiKàÐÁVS€Ã!+B×­UÔÅׯ" ÐR\h£Qs rÎwHúph!Ðe±n ýC¢xH‡~ƒ5 Iäç㨪¦ô¢‹Ð½^š©"ç‘#$~ýkä?¿†ÜÓ#ZTI-ˆ $!••á?ž†+(œ1i)¯»Û:p€Àþýìýö·q îíb¶Çƒâóá,-Å[[ËYßùÙµµxóó‡úüÇŽ;uŠ÷¿ýmÔ}ûˆöô $Ä=7—ÌqãÄÁUWá+,¡k >Ìñ?ÿ™ý<‚-  :øêêÈnjbú=÷;v,žü|¤a'ð®;èþè#>úþ÷ÑzzˆG"(€=/ÿ˜14^= K–àÉÍÅé÷µ§B!úöïçô°ã'?Á68H<Ds:ñ×דQ_Ϭûî#§¾~ÔÇíÞµ‹pk+}ÿûÄÛÚËÑ4EEøêê»d 㯻ONNÊã&d™Þ]»èþðCö<ø öÁA¢Á `H.™ ä473ó«_%«¶o3‹ôô:tˆ¿ÿ}´Ý»QN"¡(Dl6ìÅÅdL˜@Ãç>G^s3ÙÆä–5òÛÛKâÈN=ò]¯¼B¸»Ûº(ˆy<øÇ£`Î&ßy'™&C²ÙH?Žrò$瞣ïÅ ö+ɠᬮÆW_Ϥ;ï¤lÞ<~œ=?NüÍ7‰Wí1ÀV\Œ»²’ÆÏžÚE‹pçåáðz­«o5§ïàAº?úˆ¿÷=±¾>t»Wy9Îâbrš›™zÇdVWã+,L¹rï?tˆðÉ“|øÀ÷ì!Úݪ(ØssÉ3†ª .`ÊwàÎÍEIíëc µ•}O?MÛË/ïê".ËdGF]³¿ým²ªªpffâÊȰÄsŠªûãÙö«_Ñ·e ±®.”Dgn.™õõÔ]~9Ë–á+*Â5Ì]6Ú×Ç`k+{Ÿ|’ö ˆž:…¢:dŒƒ¯ºš³¾órëëñ é8šÆàÑ£„Žgó÷¾'^·öv4ÀQP€§²’Ò (˜<™êóÎÛŸŸÂTÂD::ØúãÛ²¹«‹X4JÂá Ør›÷ÝïâÎËÃWX˜ò;´´@(ÄÆåËÉ–e‚Dt¨$a7t«Æ+¨þÌgðYàžeÂÞ²…Sÿú¯ÛÛ‘mxˆ{½xëë)ž?Ÿi_þ2¾¢"Ý`²XÔ‹ÄÅ¢ž‚x°I¶’=òÎ:‹ªË/§ìœs(˜4)õŠðþû|é%÷ïOY  Ÿ±7Ü@áÌ™Ô_y%ž¼¼T cÛO~Âé èûðC\ºNÌ FþqãsíµT,\HÕyç>Îýæ›]³†Ã/¼€Úׇhn75W\AÉœ9”}¶hm {\€®]»hù·ãÈêÕ„ŽÁ(€·¼œ‰·ÞJÁäÉŒ»âŠQ·ïÐ!Zžžž>¢uýz$ÄŽåØ¥K)œ:•†¥KGl”'׿ü€žíÛ9º~=( *૨`â-·P8y2c>ûÙÓWÁ'ØñÛßhiáèK/!ª$‘ÕÐ@áôéϚŸ+®1õÐþÞ{´þñå‚--HÆÿ7cìXÆ^w¥óæQ6w.îìì÷hmeÿãÓûÁt¿ý6ºÁp’DÃM7Q0e ×_Ÿ¢i˜uxÝ:‚ï¿ÏÑçžCko·^ß7mõ×^Ké¼yTœuVŠ€/wwÓþôÓD÷ìáÄ / ÅbhÈ€–MÃòåLʸ%Kðää ÝwãFW­¢÷w¿KÙMIžÐ+>÷\ª/¾˜êÏ|†’iÓÐyåOk‰½¹‘ˆ¯|á>ÿø<ñÄ´··“››ËÝwßna}«£6ï‚[€è'€GÒÍæÐ­XWÉ¥YbŠå&`Ø\úXî¶Y ÄÍeݺ]²kx48Aüj˜ -„_ q\OCûðÛž‡O¹_ ‹ñ\GIJd·ZU6!ŠKq-Õá6`³ÚN¶ÀPÊÒ‡&­Ì6UXÇÔÐeEÖ‘‚1„T&pÈ€× ³«¡zè!BGŽ Ÿ>Ãï'£ºš†eËhX²IÉÈÇÑ£ïì»u+¡öv°Ûñ•—ã+/gÁ~@Vuõ¨;xìý²ùˆ?N¨½wn.þÊJê—,¡ráB²««ñä奰päÎNÞùæ7øøcñÿu¹ð×ÔÓØÈ¬¯¬šüÅũ˅ªJßÁƒÄ{{yý¦›pF£;:Ðgq1ž²2&}ñ‹TwþÒRkÊÍlOŽ£mÃÚV®Dëé!28(Çé$£¡¼É“™ûíoã1™ŠÁDuM#´w/;{ŒØúõD:;‰¹$QIÂQV†¯®Ži_þ2ÅÓ§ã/)±Þ[ÑýûéyúiV¯bz_ŸjNâ7´œÉ·ÞŠ;'·ª¢îÞMäöÛ‰utŠF- ù?v;55ÜqÇÜxãcTiù´å]pí7უ ×)ÌÃ1ÔV2c]íNÑ®2ÛW¸S§­†ˆê±£{ÄÑÕcÇæÔq×ÀáÓ’Žš8úmaÁ@´^GDL_Ùd|vÙÛõ8„q¡ÇÅk¤XØ[L8×êú€-e‰Ïb&€ìÃÔ:¤ †ÖIDubÆ–wH€É8ŒZÙᤢ4‡¹›)y Gp&3XIÌC6ò»ÍÅs[i)5×^KÑܹÔ_qň^}×sÏѵz5]ú“u2®(³§O§ê’K¨Y´ˆÒ™3SN„ý‡ÓòÔSD¦uÕ*K›P}>j/¿œ’9s{å•dŽrõ °kåJ‚‡³ûÑGIô÷£þÚZÆ]w…S§RÙe#4 ³NmßΑ—^¢ã­·èØ´ ¨ºà §O'¯±‘òyóÈÅl {÷nö<ù$W¯&|â:à+/güÒ¥”ÌœIýâÅ)'Дçëã9ðâ‹t¾÷'Þz Én§êüóÉ?ÞÊäm« ó£8°j‡V¯&xì6óq—-£|þ|ê.½tT–pzûv¯]KÛ† ôìØèN'õW_MÙüùŒ½â 2“¼¾,F˜HвjýÌþ•+QûúЀ„ÍFvc#c®¸‚ª .HÙÅ1k°­«Vز…#k×âÑuã=’°Ù˜pÛmä573ñóŸÑ’ØöÀxZýk¢‘ˆµS“p»Éjn¦þª«¨¹ðBJ¦OOyoÅ;:8õÈ#œzäÂ}}–.b éc–-£`Æ rÇ'·¾ÞzO‡}yõj‘¿#B·^ž¼^/Ï?ÿ<—_~y@>UZGþù÷°úhëE¸vŽÉ¡Y)|v§ŠÃ©ˆ¶• ¦Xnˆ "šG° S,×¼ªÛ.4Vtk†Ÿ“©­#3ahš¡uØñ#4Ž ›1¶ë¢¹Ï.€Ãg—…/•=‚ËÇžPÅÕÿ  5`ŒcЃ€P´¥´¬lAÝÄ%Ãk\‹ˆöT8‰mÕ¡vU<3gU5sfÓ8e"?ø:¨qÔ¨Ð8ˆ©)ÙØ»ê’$l8+*˜úµ¯Q8e þ²2kó8 ;vŒÝ+W¢¾ú*¡ŽB¡Q„­‡»ªŠLc:'gìØ”~»¦(Oœ oï^¶=ø ±#Gµ·£öÜ\ü55Œ½æÆ^uÕ¨Œ!ÒÛKèäI>~ì1Ú7n$tâJ4JFUÙãÆ1ïŸÿ™Ìª*2ÊÊFL#©ñ8ƒGÒ±y3;~óÂ$d™¬ÊJª/¼É·ßŽ· WffÊ–µ9¶jo'ÜÕÅ;ßú={ö€ªâÌÊ"wüx¦ÞqùMMd”•aÕ…À‰œÞ¶->HøøqbYµµT)|¾âbϨ 8q‚øÀﺋþýû‰öö’Q^Nf]³¿þuòÆ'³¬lp¨ñ8­­ôîÝË»ßúJ €ÜÕ…3;_y9Ë–1îê«É(-ù<÷ôˆáçžãغuÄNž$!˸rsqäå‘7y23ï¾[0•’’”ç:xò$}ûö±íg?CÞ·èÉ“hŠ‚³ wE¾êjÆ]{-%Ó§“U]ðrW±Ó§Ùñ£Û¾¾Ã‡ÑT•„ǃ»ºš¢yóÈjh îÒKñ –d³¡ÆãDŽ'²w/‡¿ñ ”h”Á¶6!ÂÛí8ÊÊð762åî»ÉonÆ_V&Òãqâ tuÑõ¥/!·µYŒÃÚÉÊÂUUEÍ•WRwõÕüû¦M<þÍorµËÁ·~ÇÒëÒò©Ð:¶Àêwaåë :G œ†@nW-WZ‡CAr bN[ÙªeE"¹4ѪJ³}¥zìbÐiÃ!)BçPd¼ZÄ -dM[ùlIbj­#ƒÕµËx%@‚y¸ ~zȆÞ'‡6 ¡¤” ÓÁÖ¤å?%ª‹ë"†5a€†)ŒkìUÕÔ]{-ùS§2öœ(·Þ„ú—Ä4‘)m&ÇlC¹²ÝNþ9çP²`c—.%üøT‘¶¿Ÿ=¿ü%ñƒ9õüóÖ•dP32³d E3gÒ°dɈ­c€ƒk×rêý÷i]»–ðÑ£¢õøkjhX¾œ’™3³hш¿ÙoßóÌ3œÞ²…c¯¾ŠÍÐê-¢tî\—.=㔋±ów¿£¿¥…}Ï=G´¿gf&Sn»¢)Sh¼îºWÎÉÀÑþî»ûóŸ9¼n={÷RsÁ”Ÿ}6U ’7nÜa8¹z[Zؽr%V¯fðèQ¼L¾õVrÇc 7Œº«aÖñ·Þâø[oqhíZzvïFr:©:ÿ|*.¤áª«È­¯õ~ñPˆ–ÿwºwîdï“O’…Ȫª¢pÚ4ЦM£hêTê-õ¾‘¾>¯¼Âñ×_GÒulN'õK–Y[Kùüù”LŸ>êë«) üàåz?ú‡ñúf562vÙ2JçÌ!¯©iT–ÓÛÒBë /гi§ÿúWlÕsrsÍ5LŸNõ׊ÅÂa¯íáu눾÷'W­"qê”5Ê/¼ÒóΣvÑ" š›SîÚ´‰Õ«éþõ¯‰Áˆü{Ec®½Vhu&£”eâ?ù ±?±Èµ`¾ð²ÇŒ±ö&tM#xâñÞ^þrË-xB!B7>œR~>žª*&Ü|35Ÿù ™)ýv]Ué;tˆ«WshÕ*"íí(¡èñWT7iÍ7Ü@Fi)YUU#Ú[‘Þ^NïÜÉæýˆà‘#DzzpgeáÊÍeÌâÅ4/_NFiéÞ|ìàÉ“ýóŸÙò³Ÿ>u WFþ²2æ|ýëN˜@Θ1gŽÁ¶6ÚþúW¶ÿö·D{{±;T,XÀ”Ûo'§®nTa8ù¾Š,óòŠÄúûQb1Cù9çÐpÍ5¸³³G\M&_Aï|ôQ޾þ:Çÿò¼ùùLX±‚ÂÉ“Éon¦xÊ”QOÀZ"AëŸÿLÇûïÓ²z5žìlJgΤpÒ$*Ï9‡‚ÆÆO|?´¶²ç`ϳϊûΚEéÌ™Œ_²dT!<™©Ù°SÛ¶±kåJ|ùù”LŸN~Su_<‚͘à:xÝO=Åþ^  2~É 'O¦`ÂÊgÏ>£®p`õjzöìá£_ýŠX?u_LÙYgÑ´lÙYˆÅÈ=ÆÀÁƒìúýï±YµµŒ½òJ* ߬á­<8:6o¦í78öÊ+toÝ*ž{I¢áúëÉkjbÊwŒúú&d™ƒk×ÒóÁZµ µ§ÇšÞÊ›:•1W\AõEQ:kVŠm‹9åvdíZúßy‡“¯½†Ë°O‰äæR¿t)¥óæ1F  ìÝKÿÚµìzì1¼K1oe\@ùùç3öª«È7w«ƒ üâ üþ÷„Œ–X²õ ðÞÔ©l ÈÎÎfÕªU“‰¤ä?CëˆCG,ý ìh8†‰å’]è.‡Ø‘0ˆÃ!؆پ2ÇuM¡ÜæÒ- H±&1üªÜZ µXG2€øUÃ5W ãWÂdH!¼Z„L=˜²Yî“„-‰ß.€ÃK{\ÛÞÉζý mÖt•>`ÃÒÑ$K$×àˢE4ØE²Ò@ÉÉEÏ/`Üò匹òJ2+*ðäå ·µ±å¾ûðmßNÄ ófÞ„TXˆ«ªŠ©wßMɬYdWW§âÁöv޽ñ»~˜ØÑ£Äz{±¹\¸KKÉ0Ê . æâ‹qú|#D^%%|êíï¼ÃG=„ÜÙI<Ä_^NÍÅ3ù–[Ȩ¨utÄòZøÔ)þzß}ô8@<À›Ëüï|‡ÂI“È©¯µµeýî´½ù&»ž|’Øà ùãÇ3ë«_Å_R‚¯ `„ðo 5 ¹«‹À‰¼ó½ïa“$jÏ?Ÿò¹sÉ(/Ç[P€ã ÷E× ž<ÉñM›ØþðÃèŠBNm-s¾ñ ¼ùù#6ÊGüÎíí ¶µñî÷¾‡¢ë:Ó’iÓFh)'áp˜àÉ“X³†–U«ˆtwc÷ù{ÅLX¾\°”3ì#DŒ]‘Í?úýêìÄ•Eî¸qÌúÚ×È©«#«ªj3S¢Qœx÷]vþö·„'ÜÙ‰'/wa!“n»š . »®n„®& >ÌÖŸÿœî÷ßGnk# Ë…¯ªŠ¢™3™yï½øŠŠD{+ 8Y&ÔÑÁÛ_ý*‘½{‘ÛÚ@ÓHHŽâb¼UULûÊW(œ<™ìšš¡çL׉tw#·µq衇mÞL¨­ÍòP32p””P}ÙeL¸ñFüeeV+Ríï'vàwÜA<‘`pß¾^v8p”–’9~<Ó﹇üæfNœwÞyø|>.»ì2~øÃâ?ÃkŸÿ„ú§çà7eÈœÐyfÍÃaWpÛbC©{ޏh[Ù“ÚVE,3GÔ]6K87[WvIÅ­À¡FR˜‡G‹âÓ Ñ€d¨¡¡i+ݰ(‘„æá• ‘"Â2=¦Œp¦M>Zb ‚mP¶ QÙˆn5GnƒÆnHoc#—^JÅùç§8ÁÊÝÝ{ýuŽýñt®Yƒ×è=Ç<µµ¸ËË)ž;—1‹Q>oÞȉ¢={h]¿žÝO}šÃkÖ0°};ûÿ{ìæ{Úf£`Ö,ª/ºˆ†%K(œ8qÄ}Ûß}—Á·ßæøË/úàƒ­ÎQRBý5×P¢-·mÛ6–.]Ê‘#Gøüç?ÏÊ•+ÓòŸ]ëwÁw_]§Aq|2xHÍr¦uK1ËLÐáSV.GÜbv§Šî²Y›æV¦‡Ëh[¹„8îÒâxÕn%©ee´ª¼ºøÚ¯š†É@48$cAИ¶ò#ò<\‰¸˜ŠJ¶B’#ž$ b»[·,Ï ÜŒä€¢bõW]Eã²edVV~âÐÄáÇY·nÿò/ÿÂ-·Ü—¿üe éêêb×®]<÷Üsiù¿­?€+WBÄ–$’'[¢'‰äN{"ÕXÐp£u:B$wê8‰!±Ü‘êm•%Ù4‰E´«Üª¯&ˆWFˆMƒO“± ÄÚ,7s<´ލ‚-¬£'Yš§ÈhL$б{0lA2'AB¹àæ_,’7‡¦¥7ÓIüö7 6’üãÍCÅë¥nñbŠgÌACI¸ÃÇ3÷¿ø"ûž{ŽÎ?¤`üxÊæÌ¡pÊò©9ÃvwòÕóÑ7Þ`ß /àÍÍ¥æ‚ (9“œºº3>樓Qñ8öv² ‘òzéªJ÷ž=d”–~"›~"ôõ±ç™gÐ5Ê (›5ëoc8ÌÁ—^¢eõjNoßΘK/¥tæL—.=ãnŠÙjjݰ®?fçã#wu1æ’K(œ4‰I7ß<ª3pr ñðúõt¾÷-/¼€®(äOÝe—Q>þ™õ í¯åÔæÍ|ávïÀ‘›KÝâÅäN˜@~S5\0âþJ$Âî'Ÿ$ÚÚʾGÅ[ŽÈ% R|ÖYb¼²ß0†Õwà'×­£çõ× oÜh9 Ë7å¢ùó)ž3‡ÌÚZê?ûÙÿðëý»ßýŽ[o½»ÝÎw¿û]“'OfùòåiùVŸ WýöõBw‚ÑSý’ÚUf.†ÛKÉü¶;UkêJri–þasÞV¦%»Ñ³K*N-;!ÚUžDÔ ³}eÚ’xuÃàÐ]ˆÉ8Ì(·Ã.›yI€‘ ý€¡:óïoïnÍð•RÃâèóƒ-œÊ\tÃZ] ‹œð ƒIÀq:±3õ+_¡òÜsÉ©¯áË”|…wlãFN¼û.íï¾KÍÂ…Tžs™ååd”•ýÍ+hMU <É©íÛqge‘UU…/?÷4Òõ]GFQc±¿ëyNÈ2§¶mc÷3ÏUUEùœ9dUV’SWwÆ“·¦(„ObÏ¿ý›‡íéÁ“CÕ¹çÒpõÕäŽ3ꔀÜÓÃàÑ£|øàƒôíÙÃ@k+žÜ\rÇçÜýOA¹£ˆøj,F¸«‹co¼!ڦǎ!wuáÊÎÆWYÉ´»î¢dÆ rêëqx<© ‚¡±¾>6Ý?á–wïFK$ÀëÅ‘ŸOÍâÅ4­XAVuu ëÖE8´´°õ›ßÄÝ×ÇàáàßáIMML¿÷^²êêÈ(/ÿÄ¡‰¿Uš¦ñÐCñ«_ý Y–yôÑGY²dIº…õ­_o?ì†-]IÀ‘Ü®2˜‡Ý¡â”ø­–•ÇÅîT­4>s\7¹m…lNѶÒ\b1Ða9%*މ(-*؇Á6ôÏ&Ûˆ8ž}6Õ—\´/}é¯*“¯øChšFNmí'öËÓõY§wîÄé÷“W_ÿ7Ûbæ÷·¬^ÍÞ瞣î )œ8‘Ú /$«ªê/(¢ìZ¹’]O>Iïž=Hv;ã–,!gÌfÞ}÷'¶xv=õ]Û·³ã·¿Å®iè@á”)T_t‘ÐèÎ:kT *ÐúÊ+Y½š#k×â@ìI¹¹Ô]~9¥gEóòå)m1„Û©­=¿þ5îPÈÊO‰Ùí”>¥óç[ óŸ]ªª²xñb^}õU|ðA.»ì²4€ü=Õ‚_oƒoÍI 3H›CÇ)‰v•×ÁKj¸ v‡jˆ%–;‡¦­p‚$i8ÕžDw\°·ãñ*‘!­C5Ds=j‰å&ˆø-p±GUlA E±ƒ,¦¦âyNâ3<¸ãQq§]lRçû’S‘‡´äÞ“nˆm­D¢†IPKލÇyy”,\È$CÛÈ()ù»NéJWŠ628HËš5œÞ±ƒâ©S)š4‰¢I“ÎÈRL=%Ú×LJ?û§wì` µ•²Ù³)™>š .  ©iTö«) Ñþ~:ÞŸ­?ûÝ;w¢«*®ìlЦMcÎ}÷‘Q^NNM͈÷r"¡_O˜dÂ+•–Rµx1S§2áÆÏxe8pô( Y¦`üø¿K N×ÿÞŠöõ¡©ê'2³Â]]t|ð;{ŒS[·Ò´l%Ó§Óxíµ)ñ¼£1Þ#6pzÛ6v?õ”ØO¹ärÇ£`âDÆ_}õµ¯À‰Y¿žã7Òºn6U%oÂüäOžLó 7P8l«Ü¬Ö <ÈG?ü!jw7:"ËÄURBíe—Q±p!MË–ý·´#ï¾ûn6lØ3U W¼ {Ð¥ kY%Ý$‡†›˜¥;˜m+3#ÃnW­©+@LÆa. Úœ"Щ$p%â¸ã1\ žDÔbn%iÏC5ÀÂl]é2¢Ø*^[„ÁÌlN–”áQ#¸´8‰|—`(zXˆî Hf\¬-¨§G2€‡ZSš‘ü§LC =…HbhújáC•ÈÎÆU[ËÌûï'{ìX š›SÆ ÕXŒx8L´¯Ö×^£sÛ6®¼’²Y³R§­Ò•®ÿ‡ŠƒtnÛÆ‰M›(š<™¬ÊJJ¦Mûdpêï§gÿ~6}ë[ ´¶¢) “¿ðÆ|ö³SéDz{ Ÿ:ÅÆ»ï&zú4ýàÊ̤âœsh¾áòššðäæ 14•åŠÇ-@rDq”ì²È™úHÀH²_Of ¢a—T‡ˆÉ û|Ä}>šî¸ƒª‹."¯±ÑúÀ蚆£„Ã\³†ƒ/¼@ÿÁƒ„»»Áå¢báBfÓ*£îj¤+]ÿ㋪rzçNö>ÿ<½--4^{-E'RÐÜ|f=E׉‡B„NždËÏNç‡2xô(ÍÍ4,YBùܹ47:¥«*±@€ÿ{­ZE÷ÎH6ŽŒ ê/¦ùÆÅ8y~þ¨Öðiù”ÕÆnXsRã‰ãbû[õÚ‡ÄejWÙbd©kŸÂ§Ëøõ0I1®ëp(HÃÑÎí6g<3–ÀãŒ%p+1ëdïQ’ÄrU´¯z ó‘’Cãð˜zK$OÞ÷0 Ýñ˜utÄ\q±Qî1EÄšÀ1Úbà°£i~AÅr0IºòNšDö´iŒ]¶ŒªóÎK¹ÂÓU•–_D>z”¾]»8ð `ôqó¦L¡xÖ,¦Üv›•뜮týw•ÜÝMoK y øÿ!ºïàAŽmÜÈÎßýŽøÀU RwñŔΚEvUÕ'„ì}î9bËOŠjØÊ×]|1¥sæ0é–[þ®IÄ4€|ZÞ8*lê×¹e—J·&ÒþlÅç@óJópH ™j -D¦ÓN¶¡6’îXÉ|‡bµ¯Ì֕ݦâLàpFã0ÅróèU#HºH GÁ”)d×ÕYÀ‘‡AQøëW¾‚zü8›7“e4§Ýë¥ì¼ó˜|ûíäÔןÑÂ;]éú4–¦((‘›¾û]úöíCr:i¼î: 'L °¹ùŒJ$‚óÎ÷¾Gïž=œúè#ì.ÕçGÙܹ”LŸNñÔ©#¦¯Òò)¯Ö(\·WcW8î { »ŸDÂçD÷Ú°ÛUËö<'1 l@t‘á± M[ÙíªÕ¾r8ËÛJBŒ#b°ŽØÐIÞ‹ ±\"{}Dý4„_TTDé¹çR¶`Í+Vü?-4¥+]ÿ]éíåÔ¶mݸ‘‰7Ü@Vuõ]ÍŠö÷sìÍ7ÙñÈ#´ýå/”Zʤ/|²Ù³ÿGì/ý¯E‡ïwÀ«ýqöFÄt”Ý¡¢úìÂÝo'ásâ–bd(!²•AüZ˜eQ @\R\ˆæR\˜$m+‡]ÁnSqÄEÛÈÆ:bqœjGB¡«°ˆÞÂ|¯Õg·ÚSÍcÓܧʖˆnµªâh¶Ä¤°`–ž ÉÌ#$bÓÇ [uÅlD\.´²2š¿øEŠæÎ¥pÊœF?V ‡Ñ®7Þàäãszï^ÂÇ##–š\UUL½çü3y2Ž Zž®t ¯X €‹ý]ãÂJ$ÂÁuëØýôÓÄ(™>ê… )š4éëþ_ *ðå…'{ÅŸi™nsé(~šGÂæÖqK1²•A²+/<[Äe‹“¡‡ð`x[aX“Ø…5‰GÔ¸E‹8£Bë»ýD=z è/Èm) ]¶ì×=š1ye%&-ºã1œ±ލbX‘0´laGò¢Ÿ jØ`1cÆ¢_B0ŽAƒq„Ün|MMä-X@ÝUWQ±`AÊó×ÿ‡? ¨*-·ßN4–Ð Ù¬Ÿsu—_δ;ïüD3ÀØà ÁövrÇŽýÄ¥¯t¥ë¥BDØýÔSøŠŠ˜|ó͸³³ÿG;%ü¯×eG¼'—®·nÍ#rÄö„°:G&K âG„/ejA\¶8~¸lIƈv;‚qØ#bYÏGB€ÈÉü2úòóHøœ¨^»ûÕ“4 Ó†DK‚æÍÜýð$DÛÊU†ö6‚£0a_kT¦1ö5 q ˜ùá™S¦0ë? «®Žœ±c!‘@×4~ùKBï¼C 8ýê«„UÕ s’âv;·ÜBÍÅS2}:ÓÌtUQÐ…£7rxýz*æÏ§rþüQóÒ•®¤Ò…¾ƒñ‡ñ}bvJ@þÁªU…wc ÿ§Wœ¤vC£p¨¨;6·ð¢2M3 Š£$S ZR&pøEž‡Ç¡)H1͵Ë*Îh‚ ;“¨ÝéÂòr,¦‘ >]ÚëІÜt“ÁÃÜÛBÚH¦aÞBCÖƒCšF,*ü¢1z‰ Oª°*r:B@"'‡¢ h¾ùfÆ^~9z[‰wß%~óú?ø ÅúÊgu5ù3g2îškíµ£>ï­­ô>LßÁƒìxì1l’DÕ¹ç2ûž{F„8¥+]éJȧªtDnöEƒQZb²Õ*²;UìvÕòž2“÷2YGQ²Ô€ÈѰ ñÚ„Þá±Eqè ö˜jM8Ù£*ލB[N5}YyD|^T`É#·>MNŒa7sŒ×IÚ­5HezPìi$dæ•Àa&Y’ ¤„é_ù “'S:möÛo!®‚ÜÑAhëVñ}IÄ&h³•$|ãÇ3õ®»(˜2…¢É“SÚOº®£«*]Ì–¤ÿàAíídVT0ëÞ{Éol¤hÒ¤´ùaºÒ•Ow%€¯&<“ÉJp#ìEœ’pÀ•œ.{|ÈâÜ8šâ&F¦´¦­ó«_¥—Ó•®4€üãÔ›ºÊïµ(o&‚"÷[ â´'pJbÄÖáK&ã0Ä´<÷ÓVZÈ—ÇU­I'[X'hËä@Y=¹8m‰1Üb&€˜F‡ÚPËÊ£D±GÔ!!<8 4FÑ6tÃ"=€‹µªb±!k‘@’;IéÙg1ñà{äm¤ÐéGÛò‘`'FH’G¢jn.ÍwÜAéÙgS:gΨ±ª»žzŠ£ëÖÑóñÇ =Š®ë¸‹‹™yÏ=T-\HéŒéOXºÒ•ŒjCåCâ|Eë·lF̶ݡZí§ =„O’ÉDxX%ˆùµ›˜ÈÎÐØeÁ8l~)—ÎŒR”6À0؆5Ee¶©Å}ÚPëÊ\öKYêÙFHLPÅ#B G ÆaŠâʵHÈËI‚¢Æff÷íE%"ÃÚHË« Í†kÌòçÎ¥áú멽øâÏo¨³“ÎÍ›9òÒK´üáHšN'Ó¦‘7i3‚38‹¦+]éJȧ¶Bh\Ï)ZŒ‰)¿Æm‹áÑ£¸lqœ¶„®”i â—–Öa¶®Lñ! Æ!«–@}0s}ž<¾,·C|_²…º–”Áa|mæ‘{Õˆµn 飷¦‚#™†b2ÈÐ-f´ªä˜`A ò ¡¾D€D¥¼1ÐdqÿX\|XÏ-àòæÍcÒ]w‘]_Oñ(¥áS§Øtï½Äާã½÷Ð5PqÞyLºãœ*q IDATJgÏN‹âéJW@þñ*ŽÎ9ÉŸèÁe0³…ä²Åq·v+2mBÓÈ”‚øí©b2 —G kèAÇíUØ¢:›«çâÑÎÒ£›0µ (,¢ËÖ²Ÿ$k© âŒB¸Å4d 9‰qDÅÞFX_ $ì I0oòè²ø¦‹‰ÅÀа_A+( kÆ J,`Ê]wˆÚ8¶aR<Î+K—âRUªJðTV’?y2ó¿ÿý´ ž®t¥ä@ç8ÏrÜb&€¸‰áÖb"lɈyÍ’@ìA2ì! 8ü„qi8ÁéD1û³9‘]‰ ±mn†6Y?/I7ÄO—"o-‹ôà(,#¹E4üL¦!'1d2j °Vü}q¸@8il7,L²øþ€*ö;’2b·3þ‹_¤îòË);묑Þ;ºÎæûïGooçÀêÕh±q øÇcêwR•çœsÆœ`GÛ~óºwíâôŽ4¯XAñÔ©Ô]xá¨[éJWºÒòßV TÐÉ‹l£‹N¡YàáÖc)ƒ~¸•¶~[˜ [ˆ {ˆlû uâïV 9l¯gonIÅ­§Oræxòþ†Êd }BŠ_’®›LÃhI%" hà( Ñ™ãÀ›< 0S[]¦¶aFÆšyOæ·k¹¹äΜIɼy̾÷^$‡»Û®iôoÛ†zò$›ï¹÷©SÂab€l³á©­%gÊÆ/_NíÅcw»‘†YSk‰]LïþýlýùÏhm%¯¡Æe˘rë­BGIç—§+]iù4Ö:6ó¶¦h¢¸Ô¡P&O\X€ø ãÑ¢dJA2¤utÅâha‰w Ïæ”·„„Ó‰[âQ„^âU„Öá×Âøñ©²ð¹ «#n‡H’ž0#†D²> H`üc)¬Ž%l˜ÆÅ_'›ëšKa!Ówܦ&ê.¾Øji²LÛ—¿LBU9þÆÄ;:!LÃ@ÑüùŒ¿ùf &N¤ä ;ýGް÷ pø0mo½EðäIÆ,ZDÃ5×P½p!™ååéOQºÒ•Ogµpˆg=ÜÉc¶jg\„&¹¢qÑvJÄR6˳ì¼z;}¶<Þ,;·Ã.©B`W¢¸Õ˜È×E8“©q˜†RDŠ}=Ck c+\ ,C=t¯`¹KÄ^†¤ üAFó³2ÁÄcQáYRÅŽÇ`ÒÃÊþ ðÖÔ0çþûÉolæmŠ‚üöÛ$‚AŽÞ|3Q]g0@6~M%3“ì)S(š;—Yßü&v—k„¤{÷n:?ø€­?ûJ(D<¡hêTÆ-Y”ÛnÃáõâðxÒŸžt¥+ ŸN‘ ó6op˜]èôÙž#‚“¤ˆ6 ›ˆ 1[‰Z-+2®Xœù ´gTЛ™W-*·"rÂÍ–•W‰Xã¹-Š+O c rFQea\h¶¨SÀYŽrpf—ú¡¤Ÿcfr$‡n:æF ÃCÕ0T’¬áˆ(Vßp­B“$Î,¶Œ›%r:ô.u(>Ö“ˆâRÄ~HrH“=¬mˆ×4 ƒ(sJ‘A±^ äƒïño¶Ø¢œyïà ÓÇ*rÉ•±LÚÛÐ Élj¢fÑ"š–/Ç BG0ð­o:xÐà !E±0* „% ÿرdŽÏœûî¡NÃØF÷îÝ„Oœ`ëOJßÎÄC!t—‹Üæfò'MbÖW¿JVe%N¿?½ï‘®t¥ëÓ Ûøwöñ²µîCÆ­Å"ÂÎÜ3,Óã qâOĬ= g,Á±òºò‹äeáÑ¢8E0•DwÌØ Iˆ‰-Ÿ*‹ŸgjÉð©*ÝcR" æ€ëÀ ®¦¤³öhÚHÒ-Å17.t s’*¤ qÜ|Hg]Í·ÞJÁ”)T/\ˆíí·I¼ô‘; ½ÿ~ © %Ýd òÒK©[¼˜òùó)f-ìè å…ˆ´¶rlÃÇŽ¡öœ&|á M›FíEqúʬÖV\™™b×cØhoºÒ•®4€ü—V'[ØÁ#ØéÆc˜z´(ö¨8¹ÛB:¶.õ"Š˜’2˜ƒn·öúÙ;½É¡áÒã–»­#®ˆüñD\äˆk"ÑÏMÚÛH¶ M=h´¨l E่ !|Dk*Iü&(ZS¦%‰iz‰NÊÐnˆ¸ÝxÇ'sÂfýÓ?‘Ùu WXFûêÝÄ5…e‚¡PÊJ‰ÙÓóóÉhj¢ò¢‹˜rë­8ý~«M¥D"ôìÛGïÎlÿùÏQ:ÿ¿öÎ;:®úÎÛÏÌH3êõ^¬j«Y²Š{ÇÆ¦Œ ÝØpL‹ã`0 ›²aM67¡lH¨1˜bC `À€{/²dÙ’Õ»4½Ý{ß?îÌhÆ’Éf7Ù„ä÷œ££s|4šÑñïs¿íóíÄm6ãòxÏÌ$¶¤„’U«·p!†ØØ ö=ŠéÜ9ìô;Æ´ûïÇ-:¯! ?œ Т¼L·ü'Bµ]DjÔ‹—GºÒ¢µ©î·!vI]çêó—ê,Hc0=[JzÉ¥î!·yTñ~…yÔ”•Þå™Û8ß‚6à»ì) tÓHpj›ÇŽÀ-€æ‘y‡ì^[›Û»w< EeÕh(¼é&ÒfÎdÜ©ƒD¡EîÄõ›qú"‚My}µ }v6%_ûIUU\~yp*ÐáàÐSOa:p€–mÛð N eêT ¯½–”êj2¦MûÒ÷g÷£bjm¥éý÷É_¼˜ÂË/'wþ|ñ?G üýDÆMi EÞŒS:áŸ7HNd³Ù¤EÖ ˜5ª¡MFïqap©‡#:Œs³²ÑÔˆCãPÔ­€Nu•¬ÞíRoÝê>ríù´ç ˆlã@ÉýÅêi«ÑŒ‘¢:™“w:Üg'â³W÷­µy¼‘†W·HKÃ`ÐR|Ñ\ .¿Ã>ˆ¶gw{.›Ço³~¾×¢=$„ðñã‰ÈËcòý÷cÌÏ'<>Þ 77ãìè`ÏŒuß>œýý8].Ü:q••¤ÍšEÍ=÷Áhõž8niaÈÛº;ØÔDX|²ÔÉá ð£òFQÞC‚Î)êv¦8qxÔ:“EÁ3VÔµ±EÇÌp<Õ¡„DzÀò°V3þ]ä:›º-pÌA?¯HÐL&‚¶Ôû3¶á,¦D*ŠwÞÃmñü>ᰃí.i t¾-Ï(O„PçH(!¸ëž_:ñ½Ôˆâb ¯»ŽäÚZræÍCg0ø¯¡{`€–ÿ‡ÙÌñ§žBç}ÙvÀ¡Õ’}É%d/\Hþ¥—bÌË-àGžy†¡ÆFŽþêW8‡‡ÑÇÅQrà $UVR¸d‰pÐÿ@¢ØÝßÅc·©¬¨T?êPLj­CcUÓVXeäX-Ry(r]´„Ö¡Z­{†BÀZ»ŒÖ*«‘Êù{YSM± É YšÐèÕˆÃ_Ó8ߊ$`Þ÷ÅÏgEâ´©QƒÝ v †e Üz—éFííQÝs³:ïá²ÔAÌJpA܆!?ŸØŠ j6n$2-ˆäd4Z-²Ó‰ýøqœ]]4ÜuN·›ÁÖVl^áÐ$$`ÈÉ!oÉJW­",>>hÿ¸Çá`¨©‰ÁS§8½u+;wbíêÂOLA×®%sÆ "““ƒ„J þþâÚŽlýÒðoTq°j‚„ÃßÉä³P, hA™§Eª A.«m¼fP̪È(¿++¨›ê~äàïí¥ç§?Å>0@ÛÓOû­H|Â9~<W_MJm-ù—^:ê²{ìvö<ú(¶¶6÷;œÞ¬¸ÒRJn¼‘¬9sHŸ<ùϾ}¦ÖVôÑÑ„Qp‚¿€x: c8N!›†ÁŠj rþä[€c­lj4è&QêÁ®±(Þ¥Iÿ,ÈXçþn( (ñ ý:(vÐDyO\ËØ)-†½Âe‰4<pz…ÃáPSTÄM}<–ƒÖ áŒ<¯i8œSåÊHQÜ žŽ.=²Ûn#{þ|µ®‰ûÔ)d‡ƒöo~G[v—‹Á––+’ ¹¹Ä”•Q»q#1¹¹D¦¦ú§ÃYÆÔÒ‚­«‹Ï¾û]lÍÍꀠ$¡Ž&:/šo}‹Ü‹."*-mì@Q–±õö2ÜÜŒÛf£éý÷)¹æ’ËËÅ^@ð$ ›a` ì›zøk,JðÜ„W@$ H¡ ›ÚYÞô’-X`‚º¡#‘3ASrèJÆxü5Ÿc®Ç>"¾åL6—9¤O—¹ qüÎá‘¶]wݬÝí*÷Z‘>]¬Y¤Í›GöÅ“>eŠÿRY~ö3\ô=ñæþþ Û, à #wÙ2ªªõÕ£º¯d·›¦wߥw÷nš~÷;ÌMM(€ÏΦhåJR&M¢ðŠ+üøó1··söd ¾KWñEEÄ3~Ù2ñ¿C ü ˆõ´ýšSo¿­×¼â¡X¼ÓÝncÀpèòùù1¢” ÇZïï‘í Äfh²Ac`¤ýö{:|“å¾b¸/Eåðʼn› ã/Ù‘†àß'{]w]6ÕbÝßyå-¢û2jŽˆt™™¤.X@ÉêÕDçä.IÈýýÈÀðwbëîÆÔÔ„Ùå1>ÔhÑgf2~Ír.ºˆ¨¬,ôQQþËìÄÖÖFý+¯pî7pvuaBÖéËÈ º¸˜º{ï%®°èôôQ“å»S[]ûö±÷±Çp›Íè¨ýæ7Éš9ÓoÐ(syýùGYQc…S‚É2¶pX¼wìÞ;|ò t"ègDcMxa{.) ½Xµ ½8@h.i`Ùè[èäò¶ÑÚ`÷@Ê pz g2jKS@1^ñm´ÔBüTÒˆ®Yw\ã–/'±®Ž¢åË1È¿ÿ=ž]»püá˜?ÿÜÿg~YµZ¢+*Ⱥì22çÎ%kæÌQÿÉ“´¿ý6ÝŸ}Fëöí(’„ pjµä,^LúÌ™^uñ……c¾O¶Þ^ê_ÞÇ©ýudYfüÊ•¤×Õ1~ÅŠ â»@ üwø‹“ÛȲÌk×báÁY'Õ[ðó£ß]»Å[W@Ž„ˆU Km(Ð|^ÎÆ|^¤° I‰¹Bf‚&B­ÀYÆôS|æ‡ÞÃí.§7rÐDƒÍר‘FD¸WΪßýkc"§Óëš+ðoõ¹NÉÉ„ææ2ùî»I_LŒFƒ®¥iî,¬Ø;;1÷õ Gx8ÚÌL'OfÞw™‘ATzº¿®!»ÝØZ[é;|˜S?ý)ö–†ÛÛqIšøxtIIT¬\IñÊ•D¦§áAÝëaéìd ¡cÏ?Oÿ±c¸ív"’“™óÈ#dΚElvö(‡^@ ø«G ›7oÆårñÐC1/×Á²r¸¹š‘ö sð!.YÁíMó8\uD-ôþìùÉþÀ|ÃçýŽÐ΃9  ãÂ⾕u$ÂpÚ½Ö"vpÊ0\2dN ˆ4|m»VµmW ì¾²«Š/EåÓ5‹^OÂôé¤ÎŸÏ¸K/%éóÐXÈMgñüêWØ$oJ‹à=å@IN&óòËIª«cÂõ×ÚÍá¤ý·¿ÅÖÒÂégŸÅ10€Ãûr'’}Ùed̘Á¸E‹Æ|ŸúNž¤éÝwéÚµ‹¦wÞAr» ON¦òë_'wáB2§OŸz@ð·«ÕJWWàG?ú‹ÅÜÃó‹LŒ‡ H÷È5ÍcuƒGÚTˆ»Bã¼{2,E+ŠW4^ñÍ kÀTAØÐÅ?&P8|Ï4n· 4êÈGÖU ¸!w]x8áii”\=®¹†„ñã¿ôƒàq:Ñ ޵pJ þ¬€466òÆopòäIžþyòóóY¾|9ßÿþ÷1<'ìyìêÁ¯ ÞsLeÛÝ5¢* "ó¼¨Á¢ÞíË>á0Cêïs:A;´5 /bìÚ†÷»lÙît¤¨ˆ«Sk%©3½·î]\ŠÏm×®ºåz¼5§S=ßD¹¯„¢ËÊ"ëŠ+H°wS2©¬CyäA<&';~ãCóGÒüù¤ÌšEÞ•W’TQi ÑÿÒKô8@÷Ë/ã´ÙüsžÈHr®ºŠÄêj&\s ))£Þ8·ÍFý+¯Ðø0'óœ(@xf&ùK–ZWÇ„•+¿4E¥( »wcëí%¥²V+vœ ‚ÿ6þÈîÝ»yôÑGihhÀd2Q]]ÍÞ½{‰¥Ð[˜õ´‚¶) ýãµ-·Èª”3 t©v„ŃÆœÁß}%[G"_Ô![À žTˆ] ºu«ÍÒ½µ ß¼…Ó©¶ÏºœàQ€HH_ Š Â^áiaÄÃÊ2ixl#©-»G]ë«V‹Mxb,3ÖoÀxà›?EÓÒ†gëëjZÎÛæk–‚uÍ 8Ãà /*bÊúõŒ[¼8èðwµµá¶ÙhY¿s[ƒ§Nas¹ÔYNµg_³†¼Ë.#®°Ð€î+P×Îz,>ùÎw08ÁЩSxÜn Éɤ̚EÝÆ 0æå¡ÓëG‹ŽÕŠchˆ†ê·lÁÚÝMñÒ¥dL™BLV–øß þwÈ /¼ÀªU«Æüáµ·âÚú ž{ŽA­ZXN¨‚¸RˆN=/Ee‰$›qÈfõ·¹Á0ª rÁ\sÞƒßáPo‡×ˆP—Y`H‡¸‚ë)–€Y_ë°udÎÃ*xWùš®Ò«Š1š[)^GÌÈVµ]Ø¿AЭ¶ùšäàÇ™âã)¼öZ*+)¿ñF¿5ˆuÇìû÷ãZ~óà`PDzHœ<™ìE‹¨¾ë®17¶~ü1ýûöq꥗è;pÙ` ç’KHª©¡|Íš ˜ÛÚ8ùê«tvl”[‹M«E6 IOgú† $VT0a‚ßVÄm±à±X8øä“ |ø!¦#GpšLxwh(š¸8R&O¦ú®»Hž8‘ˆää ÷Br¹p ÐøöÛñELgÎàBo42qíZ —,!¾¨hÔãàïô××—Ÿ64”†ŒdbܽheU8ì¾»wÂÒÁIْȨ6\Å¢Ö$.õÀ·zÔH%$ ÂS!&S}là„ºìKOù¾|&†®àÚ„U 9yª•û”ñx}¹‚ç=œ6ÕQ×W ì¾²šÔT2-"kÁŠ—.E÷ Èn7Γ'±=ñÄ(s__„â %qÚ4’§N¥ô¦›FµÐž>M÷ûïÓñ‡?ÐþÎ;èP7:bcÉ]²„„òr*o»mÌ q—ÙÌñçŸgðÔ)üüçDçä³p!9óçStå•ÖžÝÖÛ‹6$DÔ@Áÿ­€øS.¿ü%ñYY8~õ_ ¿ù&6,p†BÕ 0!\‹æBã+Š{£ «äíàò¨Åi— fBl2„ëGR\~›uoÛ­¯‹Êáðnô“Á¬§œ!0­'¤D¨Ï-Ÿ'vgÀã¼ÂaE,—££1ŒGõ† ħ¦0¡Ý-kð8]Ø>Ù‰]’Í|ýšè0bcɹôR&Üx#ñÅÅjÊH£Aöxp3ÜØÈáM› ·—þ'ð Ñåèh´‰‰ÔnÜHJu5IååA5 ·ÕŠätÒ¹w/{ ÷à í»v¡‹ˆ ±²’š ˆ/*"aüøQ(~ѱXpÛltíÛG}=•·Ý†F«½ É¢@ üMÄlj;ïää/~HÎcñ„AA±D>Ëtß6>Ÿk­3ó0˜PIÐ̈¯îö †Ç62¤¸_#$’S ¶läñ>›vÙâµ2qz‹áŒÑ}Âa #eΫ«©(Ì%Vò Ë ­¿—SÂ,Áù«Õ}ч.=ÌK.!eòdÊnº ]Àîêê¢oëV†Z[©ÿéOÑÚíØÙ"˜4}:qåå”ß|3iµµ£®kÏ‘#t~þ9M[·Ò½{7î¡!$€°0ò.¿œ’n pÉ’ ¾/Š¢Ð¹w/{öвcúèh*V¯&{ölñÉÿkþ*‹L0s&SÖ­#ÞmÃùÐ-„„¨)*†Õ¢ºYöÛ)jG“#’‹ 0âb… Ó IDAT½'y³·‹Ê:2YîñN‡û¬ÒM XtàÐABÔeA¸Œ:P|sæ×\«4ºívØ1xbcÉ¿dEW]EÂÇï~rÒ+Ï`oïVS[rð>꜈;* øqÌ~àbóòHž8N‡âñ b«¯§å»ßÅ1‹¬þ³j¤áµRqúfLõñ)*Gt4ɳfWYIåw™šŠòé§HÍ͸ž|Ë_` ˆLüK5ô¹¹$ÍšEö¢E-_îR|˜[[1ïÜIÓöíô¾ò n;à !qÆ â'N¤êÎ;1Œºf²ÛMûçŸ3pü8û{Œá†4€.&†¬‹."¥ºšÚ FRb狆¢0pê½ÇŽÑ{ìN“‰œ9s¾´cK þáÄ54„«¯Íð0GjküÂaÕiQââ¨K7“fp§UÓK²eı×îñE>á°jÔ®¦ô8(KÖ« %ÁãR—PÙF¢Ÿ÷•Iô³étH ß|3™óæ’RY…!6ågÿ‰ûó/pîÛ¥½Ý¿6$`3.Öâjk©¼ç¢rsIöZ (’„äp`ëíåÜÐßÐÀÀÁƒ8<l€C§#¡®Žºûï'¥¦†ÈólEIÂãtrì׿æÜ¶mô:„¥£BB1™üïX^NÆÔ©„ŒA(²Œ"I4ðŸ~šáæf F#Sï»ôÉ“ÅÀ @ øê ˆþýûy»¦†ˆ²2ŒUULµ‘ut ŠÍk´èýî+¢û#0â‹€¸HÈŠ†Ò8‚v­»#ÅpŸpøý´Z‹‹Iœ6üåËW2vòùçHOü‡{dÎÃJ°÷• ðÄÆ’<}:u÷ßOæŒA—eï^§OÓþì³ôþéOþ9ß—!;›”™3™xë­cÎ_ 44Ðð Mo½EÓ«¯¢‘e<@Lq1i3g2éß ©¬ì‚×ÕÞ×GÛgŸqîã9øôÓ„„…‘=w.u69mšø„ ‚¯¾€8‡†hýðCâ&L aÂÌUÅè{ü¶$Zm’ÑÈä;™¡N’´øST.ojËêQÓb¾_÷•Y£!yÎ*Øü|Mýð_?G9ÓŠ{Ï^loj‹àÔ–ZÑ ÇÅ1iýzÒ¦L©3( ( }O=ÅÐ0pð ÃgÏú-Úm¨-¿QEELþÎwˆ+*"uÒ¤ —"ËtïßÏÑÇÇtô(ýGâ‘eÜ n†ÙÝüÌ“ªý‰¤ •e á°áùù$y=¬ÆÍŸ žŽ;w"}O=EÿGùæ}ó.½ž”Ù³1–”0ãÁƒRFŠ,cno§oï^lgϲP††p£v`éÓÓIž2…q‹Qyë­c^¯¡³géÞ·“¯¾JÖ-h€„²2ËË©øÚ×È?_|šÁ¿†€´|ï{œúáý¢aR«J)³''Â\ê?úöyؼx«¤N‰Ó=±±TnÜHry)i[‰^…rú î½ûT—_O°p˜RT ¾ºšš{ïÅXP@ê¤I¸öíôy3¶Ž†vî ZËî‹8ì@ͦM¤NžLÖìÙ£j o¿ÍÙ—^Bii¡{ÿ~$·§W8"Æ£öÞ{ÕÚÆ”)c¶à¶}öG~ùKާûàAdI"wñbÊW¯Vw””üùôa}=.‹…Ä’Ñ%þj„ü=Ÿ\.)¡=5•˜²2òJK™l;ƒþãwÀž~°:½†‹Òˆñ¢¯ýÖ¦Ó9q"ãr˜Q[Br^>lú²Cƒd•1¹GÚv}V&éžÈHRæÌ!µ¼œÙ?¬Fo¾‰ÒÜÌðk¯1¼y3EÁ¢(#ÝW^Á‰,)!¦¸˜é·ÝƸ… Ñh4þA?Çà ];wÒ÷É'ûÅ/ˆt8p( vÀFâ´i¤Ï”M›ˆÉΕ¢r™L´þ9]»vqà±Çp£èt$VU1ýᇙ¼qcÐó"ItîßÏÐéÓ ·¶Ò{ô(ÕwÜAÆ”)|Œ@ |å"€sLJe%Úά5%„éð·úZ|¢¢²‡†’~ÙeäΛMúŽ—‰MJƒí[ñ8¼{νé­À½¾â¸p L~ðAâËÊÈ[¸^óúë‘ÓË/cøùÀÔ–Hž7âë®#uòd’JKƒd—ÅÂ6vîg?ü­Ûí7M”££)ÿú×I›6ŒéÓ‰HJ R·›îC‡8þì³Ø[[iýè#Ü6 :?ŸºwñÅÄææ~éµ<øÔS´|ô{ö9cÅK—Rtå•£ë(@ðÏ >lmmô~ôÒO63xäh‰¡”@\m-iÅã(›Q‡~ÿNxý$³[hwªÅt‹pê{ ³×ÿ GÝ@¨ÕR¾n™³g“={ö·ÚzzØýè£ô>LçÞ½hCC©Ý°Ä²2²gϵ&W þuäÎ;±ÙlT¬[G|T$ºõ+áT‹Û¿½ÐîQ;¯:Yw\q“&‘>gUµUè=4ÿùÒ¡C8¬.¬.É?ï4 JxQƪ*&ÞqÉ••èôzÄ`yÿ}$YæÌõ×cw:1Ùíþ‚ºl4b¬©!¡ºšºûî#422ØŽ8÷á‡8[[ùìÛßFÓßÛå­(„çå3~<ã½>VZ½>(Â@QèØ½{_oÚÄpSŠ¢R[KÅ-·0áê«Ñ j]äÈn÷M Á?€Ò÷?¦çÁûIWTÑðµìFV $3“ò;î ¡¼œìã{ 9wù¿ÇÓÒ]Im%é RxÝu$WU‘0a‚ÿ¹-O?u÷n\@÷ /`•$¿PùI•ÝqñäÌŸ´AÐÇçßûÚ¶6^{ Åjõ·í&NÊøU«H©®&uŒER]ÒúÑGô=JóûïcéêB£×3áÚkÉY¸¼‹/&Ãêp`v»ýXVÀc4’4mS|„ÒRBÂÃë§OãljbÿæÍØ÷ìÁnµâ”eÜaa++I™>ª»î""%…ƒ!¨®á[7Ûwø0{6oÆÕׇìvcHL$¡¢‚‚¥K™°r%úèè1£ E’pÛítíßÏ@c#ï¼Cå×¾FÞÅ£Õë¿4B‚ºÀvö,Ûóòü³¹W]EÎe—‘yì3â4ZØöò¹.µûjŒ9_Û®.3“ò;ï$¾¢‚q‹©»Ê÷ìÁõÌ38ΜÁòÁþçlÛõÍ{ä/_΄odÜÂ…£L ÍÇŽqîñÇéڷჱÔzJ\U•wßMþ¥—~^÷€ätòÙ~€µ©‰³Û¶á±XcI å·ÜBRE™3gŽJ‹rì7¿¡ïØ1OŸÆ>8Hɵ×Rzíµb] ük ˆ"ËœxñE¬==TÜr |ö aë× õ™ñXø€æßýŽ®O?eðøqdÀhbc©X»–â+H«©óï¶tvRÿúëtíÙÃ`C{÷•™IÝÆÄÉ%âÓ,„€|î¡!º~ñ šx@-†k4–Fxa!…«V1nÁÂN¢óHH·®Br*Ø{ûý¦‰æó„ÃDUVbHKcö#™‰ÁhD£Ñ`ÿädE¡Ù·Pª¿›¢ø'Ò•„¢ŠŠÈ½ürJo¼‘°øø «—ÉÄÀÁƒtïÚÅÑGE±Û±[­¸u:" ˆ.,dÒ]w‘ZSƒaŒÚFÏáÃØº»ùøÛ߯tæ ’ÓI\Q1yyLÿÞ÷ˆÉÎ&Ìh¼p´¡(xœÎQõ@ økòU{Á¡F#ÖÈHÎj4„—”P|à ¤LJjy!üÊ]¸Ÿý¥°ðü¶]Ÿp84 W­"¹¶–¢¥K‰JOÀüÜsØÀ t?ñ6Yöw_ù¼³B³²(¹ùfRjkÉž;w”¿Ô‰—^¼k¶lAAí¾rét¤ÎKþUW‘=o‰&Œy°Ÿxùe:?ÿœÓ[·bikCŒÅÅL\»– W_í­Bv»iýôS샃Œ[°@@ øW@<÷æ‡Ñ>÷_8;züí¾f%X0¬€’œLDAnº‰üK/%,>mK R_æÿüO¬_|uh³wß¹¯ˆn3ˆ(.&²¸˜Úo} cA£Ñ?³aéèÀ~æ Gž|’¡?„áalv;NÔZJÔøñ¤ÍœIÕí·ž û‡½¿ŸÁ“'9ýÖ[Ôÿæ7¸L&\6‘YYDåä0éÎ;·`aK"¹\tíÛÇPs3o¿"ËÔÜu)••£† à_6‰Œ$ÄÛadok£é;H aÐÙ3ª&b LXµŠ”º:²çÎE§×ãùÕ¯p;†ýÝw1>Ô}ågd$ã–-£lÖ,Æ]r Qçm쯯çÜÓOc:tˆî;ÐxSb6@Ÿ•Eùڵĕ”é¥cvQYÚÛÙÿ裘9³m›*Ž@êôé-_NÚ”)ª âpšLìüqLçÎqä¹ç(Zº”ñ+V·x±˜H"ùs(n‹…cK—Òºc‡ºë<,Œð¢"bJK©Ù°˜ÈÂQvîÄýóŸcSÀÖßÉnH4šäd"&L wÉН¾C\œ?E% a¯¯Ç|ø0-=„Åá`¸¯à !¼¨ˆ¨ÂBj7m"6/ðÄÄ ˆa°© go/ ¯½Fó›o‚ÝŽ¹»]l,Qd-X@åm·aˆ‹Skçaíêb¸¹™ú×_§ïèQOŸ&25•â•+¿|9aqq¢uW ˆä¿­€!!èF:Îèhò–-#uút ®¸‚ˆ–³È¿{ÏÑãØÞ_]@ÅÈ|ˆo"Ý D••Q¶z5ñååä.X”brž8Aÿ³Ïb>{–î7Þðï.ñy`Üx#Éuuä_qÑYY£^cËGѾmíï¿ÏàñãhP»¯BÓÒ¨¸ï>’kkÉ[¼ø‚»:zãø¯M÷ÁƒœûðCÐjÉž?ŸÉ÷ßOùêÕè„M‰@ Èÿ[W’ÛMXBÒÛoaûÞ·1 ™±÷õcR‚íÙM€#<}Añ“&Qsß}„%$ø ]ûö!×\ƒS’0Ûl˜zzüÝW@Ÿ“CÆÂ…ÔÞsQAwþ.‹S}=½ûöqè‘GÐcÄhããI¨®¦ö¾ûˆŸ0ˆ¤¤QÝW¶¾>,mm ž:ÅÇ›6!Ùl¸m6bóóI®­¥æî»‰ÎÊ3JuvÆÞßc`N‡ìñ0~¼ø´ ! _†ärqö׿F×Ù‰ãßþmÔDº;&†üë®#¡ºšÂeËü¿ý-®£Gq½ÿñؽ‹¤|‹oÞ#¼ €’Õ«É»äRªª‚žÛÒÑÁÙçžÃvò$ ¿ý-:Ô‰t;jÖøo¤hÅ Æ-Z4fÔаu+½гo­}„äp`HN¦lõjÊÊ(¼òÊ/-Š›ÛÛéÚ¿Ÿ¶Ï>#")‰èŒ J®¹F´ð ! ÿYÆe± S¶X4´YYhSR¨ºçRêêˆÐëÑõô öÍ›±ïÞµ»“wš<ÐÊ$°¶1ûßÿCl,‘iih4dGK à œþÉOp440ÜÑ]’°Úäd éé”Ütù—_NTjjP¤âb¸¹™Ó[·rê7¿ÁÕׇÓlFÑéˆÊϧâÖ[)^¾œ¨´´1ý¯d·›¾“'lld÷O~‚Ël&¾¨ˆI·ßNjUaññâ.„€üÅ‘ˆÓÉÁ‡B %ïÊ+I,+Csä0Ê–-¸ÃñÖ[þ:F`jË'v tíZŒãÇS¾zuPºÈÞØHÏóÏã´Zéxë-LgÏbgd"=ª´”¼+® kî\r/ºhÔk³ttpø‰'°Ô×Ó¸e :À ÈùW^IÚ´iL¸æ"/°Äe±pèé§1·¶²ÿ‰'Ðèt”Ýx#ã.¾˜ñË–‰Oµ@ ò׈F4Z-½k×¢}÷”ŽNÿ`àÁí¾šôt´ ÔÜw©55ÄdgŽl6ãjnÆzð ?úV«•á¶6¿Ñ¢Ã`@Ÿ±¼œêõë1æç™’â_&%¹\˜››nh`×÷¾ µ´ £‘ˆœŠ®¾š¢¥K‰ÎÈ•¦r áÂÒÞÎg?øÃgÎ` &'‡š Ș<™èÌÌ1-åàoEÈ?óØBëœ=›ÞÞ^Üo¾9jN$aút çÌ!ÿŠ+H ØÏ1ôƒ É2–†z^~‹÷ç}†Rl,y+V?q"Å+WŽŠ^uEË–Qtå•ìÜòá¶ÙþìÏ ˆ@¾„–^àó›nÂNHf&)³gS~óÍÄæåærÅ‚ \}5YfèÄ ¬^ï+ `Õj!9Cn.åëÖ‘6eŠzçï=œYÆÑÑd2qú¹çè~÷]†ÛÛ±™Í¸õzôYYÄ–•Q·iQiiDgf­¼•\.L-- ž:Å'›6á1™0µ¶CDF¹_Lå-·¨~]±±cF\¶¾>\&݇Ñ}è)UUäÌ™óg—O /¡ïÐ!ßxƒð¬,&¬\‰!6ùw¯ã>YåÕW±?TD÷o.Ôj‰4‰œ%KÈ^¸´ºº —^[o/¯¿ŽÔÑAë›o2|℈Iîòå$MšÄ„ë®#<1qÔëršLÔ¿ü2¦úzŽ>ó ¯…gfRtõÕ¤ÔÖR²r廩$·›Æ­[é9r„s;v 3Ș6üK.ùÒIv@ ò?@²Ûi]¸è³gjo5'⊈@“žNÒÔ©LÚ°ð¤$ÕÄP£A¶Ùp··céíåÜOŠíèQ››±;jË®Á@hF“6n$cÖ,brr‚º¯<޾>ì]]øÙÏÝ@Èß[o/~ˆçµ×8ç.7š”rV¬ ¾²’ÒU«‚Úg]MM ¿ö–ÆF:Ÿ{Î?â«Ø5RgÍ"Ù2*n¾y”­ˆµ»›/¾ˆ«¹™–÷ÞÃzæ êTzd~>Å×]GÅ-·“=ækv™Í~æ}}~æl==DefRxÕU/[Fö¬Yâ-„€ü_±ïöÛiغ•Ь,ªï¿cq1Æ‚´¡¡HgÏ¢( =×_ËåÂb21tú´¿&bÜááhSRH›5‹ªÛo'&'‡¨”5Rñx°uwc9{–Ý?Œ¦¥…S§d' MH@Ë$ïÊÛó£ E–±õô`íì䋇b¨±‘†Â10ùÞ{1æç;nÜWÞ:M&Ü6ö¾>Š‹Çœ'! ÿC†Ïœ!6/éwðÔ×ãúï¿›$ù'Ò‡"Mb"ùW_MbE…êGp€»m6ÎlߎûÀŽ¿ø"J[nF¦Ò§L!mæL .¿œ¬™3G½sGÝ{öÐäõ¯¼ÂÀÉ“È@Ö‚dÍ™CÙM7ýÙUï±c4½÷}'NRYIÞ¢E$‹O¼@ ò·À¼k¦uë°:4ÊÞ݆ºO$45•ºo›ø’Æ÷ßÑ{ð˜Íœûå/éݾž3gpcÜÚÄD2æÏgâºuDef“™é^_¤2ØÐÀÇ÷߯lÆÚÙ‰}hˆ£‘ˆìlfüà¤O™2æp¡ÏûÊmµÒøöÛ4¾õ.«•ø¢"&ßsº^´ñ ! {þ‚Y’üéi‹[RÂÄÛn#þ¼»xÓŸþ„åȺ·l¡çóÏýf‹v@6É]²„äº:Jo¸aTë­Ëlæô[oa>q‚C¿ø²É„ x´Zâ&N$sî\ ®¸‚¬3Æ^$åvsæ½÷è;vŒã/½„©¹™Ì3H®¬¤lÕ*KJÄ›)þf„ˆK0š¾ÔTì’Dþµ×R´|9ÆÂB"’’P<8¢çá‡qCMM uwûÛ}å¸8ôLß°ÄòrâǹûWœ&Ξ=ù$ƒŸ|Â`}=N«Y¯G›šJÚ´iTÝ~;±yyÄæä ‡äraïï§÷Ø1Ú>ù„–?þ‘ÁÆF sÖÄ.½ùµIDAT,<öID$%‰7Q ˆäïÇnGQÿÁïxâ ܶ'è{úiÝ7‘n7Hš1ƒÄÉ“)YµjT”жs'¶½{i|óM?ýjMD›@îWPYIùš5cnt™Íœxé%†Øÿøãàñ ±……Œ[¼˜ò5kH©¬oœ@ òDÓÿûÄ›Lœ{à¿p˜4œáá(IIä^uùK—b,,$ÒÛ} ™ÍHv;'~û[Ì[·2xæ –¶6€‹>3“ÊõëI®ª"±¬,ÈÊD‘e\&Ö®.>ûþ÷±œ9CÏ(€>6–¸òr¦Ü?1YY$L˜ Þ$@ ä•îwßeçå—c´iid/]Júܹ.]dEâ±Ûüà<çÎÑñúëôìØáŸ±ŠÑHöe—QsÏ=$Oœ8êydI¢}çNúöîåÄóÏ3xì  ‰Š"÷ÒKI˜8‘ÊÛn¶$@ÈWg?Üv¡‰‰L\»–¤ÊJ4Z-òà Úuì]ßÿ>v·›'° øzJL ã–,¡lõjRkj › ÉnçÔ«¯ÒòÚk˜1ut èõèÓÒ¨Ù¸‘¤ª*’+*#½%B@¾BHmmضo§kýzv»¿âûnôÙÙdÌŸOÚÌ™”]}МˆËb¡}çNäövßxƒŽíÛµ&âÒæÎ¥håJÊV­í·àÑ…õÒsäñ))ônÝJ—WWŠÁ`0@ @ m@'Ò@ ¡Ý µµµøôéߊ޿7oÞ%‚@444 $$ééé)G „oÀ©««ÃÉ“'qûömž•DEEáùóçÈÊÊ‚§§'IË+õõõðððFƒŸŸRRR*—ššJ@ ¾eäÊ•+2dßJnܸ+V`Μ9ÈÉÉA~~>iY@ p%)) X»v-Ξ=˱\bb"¤¤¤˜åΜ9C@ :82¼~\¹r%²²²'ò¼¼¼ðòåK–mÏŸ?ǤI“pøðar Qàãã333’!„Žd€H{{{ØÛÛ³l[·niy@ ´›6m®]»°`ÁÒÐÎàé‚ÈÈHddd $$uuu€ÜÜ\Œ5ŠYnúôéøçŸðúõk¨©©ASS“´,@ ¸Ò£GÔÔÔ $$˜?>ó· .àèÑ£€^½z¡ªªŠYNPƒbüøñ' M ¾yòòòPSSò-77!!!ˆ•È1Þ¼yƒ”——³lŒŒDHHŠŠŠ$g€äå塾¾#GŽFc—«©©aãÆÌrcÇŽ…¾¾>>~üˆ+V@VV–< @àŠ’’–.] SSS :”ùÛˆ#0~üx¶r}ûö…¥¥¥@õ¯_¿ÖÖÖl.Àð-áçç‡ €F£±l÷ôôFÃÎ;ÅîoÞ¼‰¿þú þþþرc˱ÿýw¼~ý+V¬ªNž.XMNŽÙ³g³l1by  0rrrppp`ÛÞ¿ÊñÃØØ‰‰‰=z4ilðM2uêTdff²m§P(€ÒÒR±=“bccáîîf½’’WWW˜˜˜°l’ˆ@ D„Á`àÅ‹¤!ÐîèÙ³'>}ú„¾}û¶»s“!·‡@ DãÀhll„••Hƒ|E‚‚‚˜ðŸ?ðe%寰´´„©©)i$ð]Œ„„xyy± B}mÈ A,êêêƒAƒð]Q[[‹êêjܸq%%%¤A¾2ZZZ044„¡¡!¤¤¤|qÝ¢ÓéXºt)êëëI#„oެ¬,¤§§#** eeeHMMENNœœœŽk×®AIII¬c˜˜˜`×®]¸páèt:RRRðñãGèééáСC¸}û¶ÐIbÛ­’——‡9sæàüùó Ñhäã!!c¡ªªJ¢õ:t“&M"0B»çêÕ«lêâ››‹€€Œ=îî2fff>|8†Î4@à‡~€ sU„@ ¾%èt:¬¬¬|™+..Fyy9öîÝ‹êêj899aÒ¤IbcÍš5:t(:wîŒ#GŽ ¨¨ååå˜3g¦OŸŽN:áôéÓBÕ)Åø S×ëÖ­ƒ²²2ÏD„T*¯_¿ÆÈ‘#)))hkkcÖ¬Y9r$yâD`ß¾}x÷îîܹ#‘úBCCaoo  ¾¾'Nœ ,ÞÞÞ°³³# ÑdffbâĉX±b…ÐrÜpssCPP†Žˆˆüý÷ߤ¡Û ˆGÏž=|qCÈÏÏÇÌ™3IãB; Ý®€aܸqØ´i<<}:^¾|Iܰ„àîÝ»X¶lµ4 ÞÞÞX´h‚‚‚$Rgaa!JJJ˜3ì„ö‰‰ G©J@èÈÄÅÅaãÆÈÈÈ`Ù¶e˲”MMMŶmÛ„>Fll,&L˜€¹sçâÒ¥K,ãÁ©S§bÉ’%øßÿþ×ñ ÄÄDDGGCEE…ãïöööˆŠŠbiìöJÓ*°œ?/^”È9P©T <cÇŽ»®ÌÌLüòË/8tè~üñGæö 6ÀÍÍôRYY‰}ûöáùóç¤1Z™Û·oÃØØvvv˜?¾DžÓääd¤§§cêÔ©¾$½#ÏûÆÐÐ999¤!Â7…ºº:deeÑÐÐHHH@xx8Ž=Ê–ÿÃÛÛ[¤‰˜›7oâüùó8{ö,Þ¾}ËÜîçç‡íÛ·ãÔ©SßFzii)444:üCQSSƒ††DDDµ_@@zõê:.ö9xzzâéÓ§puu…ššœœœàááÁ|P…¡±±‡Æøñã1lØ0–ßúõ뇔”ÔÖÖ’Þ@@999<}ú”4F+QQQsçÎaëÖ­““ƒžžžDfÁ[öQffføð᪫«I£·SfÍš…þù‡4@ø¦066F÷îÝõõõ8tèâââpêÔ)–±ž§§'èt:ôõõE:މ‰ ºtéUUU¶í***èÚµkÇ7@\\\°wï^žeìììàíí-ÑãJº¾ÀÀ@¦RŽ0¤§§#22ÊÊÊbù•WTTàĉظq#s5ÉÜÜqqq")Â\ºt 999Ø¿?ÛoË–-Cll,ÂÃÃIo à³vúôi¨¨¨ ==4H+qéÒ% 4C† ØÚÚ"((Hl÷Í–}”­­-êêêðèÑ#Òè@ø*ÄÇÇCQQT*¯^½bN¸UTT %%ûöík7çÚfHdd$( (ŠDüÞmll$æÏ |Y²ºuëtuuqêÔ)‰Õ+ê9vëÖ ŠŠŠHLLùØ«V­ÂÌ™31qâDæ6%%% :TèóúóÏ?‰K‚xÏ…¤Ÿc{;󯯡ôQQQbÉñ&''£S§Nlñä^¡½B§Ó±uëV!--Mèý_¼xÔÔT|üø‘í;›››‹÷ïß·OÄÂÂT*T*£FâZ.++ ²²²"/‰Jhh(*++ކ†Lž<ׯ_Ë ÊÅÅgΜ©©©Pµ‚¬ñÃÃÃ¥¥¥X³f ËvŒ7N¨ÕžœœxyyaíÚµ<ËíÙ³...­~¯ ¿_n[[[øøøž±ˆ‰‰Abb"æÍ›Ç²ÝÜÜ111"× iii 8e{k¬Ê$˰aÃðæÍÒá›ÁÏÏÑÑÑpssƒ‚‚úôé …‚‘#GÂÄÄgΜArr2s ¾aÃôèÑC¨cìÚµ žžž8~ü86n܈7n 00Ë–-Cdd$~ÿýw¬^½Z¨:eÚ[C¾|ù °´´äYNSS ())AçÎÅ>nff&ttt`hhˆ7böìÙø÷ß±råJLœ8Ó¦Mƒ¶¶¶Pu6ù‰3 ¡$jKKK¡®®.òµ”””àüùóعs'›¯ðÅ_ïùó稩©‚‚‚@Æ™¾¾>ßü+=zô@YYŠŠŠ„ö†aÉ’%²³ Ñh˜4izôè)))Lœ8/^„³³3éI%D]]Ž9‚U«V±á-^¼ׯ_ÇÏ?ÿ,RÝøá‡ض›››cذaÈÍÍ…®®.Ï:^¿~lÞ¼™Ü¬6D^^žÄ©„oŠ©S§2Q oß¾,¿·4 DIc¡®®Î¢~Õ<XÔp:jƒO™2åååxõê•DêsssÃúõë™bÆ 8qâ*++áèè(”ñìÙ3hiiaàÀX¼x1îܹƒšš¾ûݾ}ÖÖÖÐ××g”„ÅÙÙ³fÍÂäÉ“9þ¾jÕ*x{{³-£qãúõë,mÃ1cÆ@ZZºÕƒª?~Ì¢ÂÐѸví ¤¤EEEhjj";;»]L÷îÝ“ht:ÎÎÎ"- Bjj*üýý±aößTUUQWW‡ºº:‰ôÍë­­­å›è³¶¶„››Î;G2teª««%¦8H „j€´·ìÐ:::X»v-ŒA¥RÞïÇPRR‚ŽŽÌÍÍ‘ òT||Ž9‚·oߢS§N7BÞ¾}‹àààVqoúóÏ?1zôhXYY‰ô^%%%aÛ¶mðöö†œœ> …B¾žàÌ™3Ì® Ïjtt4|}}±{÷nx{{#88˜¬H„ÅÎ;aaa"((Ó¦M•JeqAÞ±c†Šàà`‘Çiqqqرc’““Ù¾»þþþ R©pssCVVVÇ3@„ÁÎήM‚ž›ŽõäÉܨ֕EEELœ8‘ïÊ@ii)ÜÜܘèÐÓÓûwï„2¦öìÙ#Ðõ²RsssßµkWhjj ­† ±±±044”¨¡óêÕ+¡“èˆBUUþüóO–U>ôë×O¨•¦¶âãLj‰‰Aß¾}%v~...رcdee±jÕ*<|øP ÎJ˜úù‰8ìÝ»W较Á` 66ƒ âZÆÐЋ/ÆÁƒ9þ~õêU :ýû÷ðÅ7·¬¬ 7oÞ$_Q1Y½z53ÈRF†sxãĉñäÉæß•••8r䌌Œ@¥RQYY‰ÆÆFÒ˜¡Ã°mÛ6Ì™3&&&¾Ä49r„-ÃöíÛ1{ölŽ1Œ‚2`ÀŽ®ÍMãJà‹W‡ ´+䯰²²BŸ>}ÞG\=ÿ&ÿ_~1JJJX¾|¹ÀÙŽµµµ¡¨¨È20),,äéfóùóg”••1œ™˜˜`È!Bùß šÄQGGUUU|ãZÜÝÝáää$ðñ{öì SSSøúúvˆ·°°Ø¿?×A£$a0lÊj ˜;w®Hñ>­››víÚ…™3gJäü’““€5kÖ@JJ C‡ÅÖ­[1gΉœïóçÏQ\\Ì×Q]]]h…;ƒ7nð àk2&Ù\Ö>~üˆû÷ﳪªªbÍš58þªªª`aaÕ«WãÒ¥Kؼy3‹b¨ºº:òòòP]]Ís"­%õõõ AFF†DÏ»] 999PWW‡²²²@ååååRqâEcc#²³³™–#7¤¥¥ahh(På;wî`âĉ,V¦³³3xîýúuÌ;òòò"_ŠŠ ×Ù¿æÌž=iii̦]ÝØØˆàà`L›6­ÕŽ---ž÷ƒ—B[òáÃTWWÃÌÌŒi”””p=~\½zÇgÓ(¾¸úúúb„ ðññ)NTT&NœÈ7_Móön dddpôèQP(xzz‚N§ÃÍÍ [·nå:ÑahhˆY³fáäÉ“Ÿ?¡u8~ü8Çg+##®®®ÐÓÓcKnI _‹–îãcÆŒaù»ÉíwÈ!bkÀ€ððð`ÙÖ4†|ùò¥PuuúžoZyy9²²²Ð¯_?÷á¼ZSSƒ'Ožp”æøýîÝ;Œ 6@OOãïNNN¸ÿ~«¹AUWWƒN§ã×_åø»¶¶6êêêÚ¯yii)ËJÄúõëE~×?~ cccæj ¯{¼gÏ‘yBÅ«ÏÑDZZ455^™±µµEnn.Ο?°°0â;ddd°sçNøøøAn@§Ó9ÞO”——³lËÏχ±±1.\MMM“¸B[ÑcÜ4þáÎ墢¢„J¬Ý’„„„„„°õƒ)))B«·ÄÍÍ ŽŽŽù5ÇÄÄD Àpa>@¼˜>}: ¸úϹ¹¹aÙ²e]-ìììðñãG6i4àK:'uN:AMMï ¸¡¡999B À¬­­¡  À"KÙü:Œ9&rô¾TWWs æüš/'¿öÅõGP²²²àëëË5¦fÚ´i(..*0ºµ€žž‹;Ø?ü ò»Æíùn‰®®.fÍš…S§N‰Ô‡p“äDÿþýann.PÜ·ìç¼X¹r%Nž< GGG®.›œ&8lmm9º$ÃèÑ£…r¸yó&-ZÄü{íÚµ8{ö,Ç|!~~~$±$@hsžå@-.m¥× ¥6‹2ÿVPP@MM G‘ÐÐP|ˆÛ·o3%髪ª@¥RáããƒQ£F‰4Á|Y¥ßºu+8€ÐÐPfߨ§§‡ãÇÃÕÕ7oÞhì×êÈàÁƒáààÀò¯gÏž,eŠŠŠðæÍ‘Ô‡´´´`ee???¡ö Fff&.\(ô1utt ¤¤ÄÕ¿NXþûï?¤¥¥aèСíâa–Ôʵµ5^¿~ˆˆˆvq]‚ȳššš"77·U’ ҮMÏVzzúWm+IÍà¾zõ ùùù°··j¿Ö^=k‚—C‚JûJ’={ö}ý‡ÂÀñîÝ;üý÷ßbŸCDDîÞ½‹•+WbË–-ßÔ»¶¶rrrl†EóïJaa!ÊËË¡¢¢ÂVnúôé,ÉVóòò`dd„Ý»wcÍš5غu+Š‹‹¹?&&4%W @ Kqq1>|ø)))¤¤¤   Ïž=•JŤI“˜}LEE¬¬¬àêê ggg¡Æeee P(ðòò€àíí^½zaË–-L7}cccøûû£wïÞX·n@á­n€hhhÀÐÐ埊ŠÊW¿i555hll8éaËl×®]Ùf‚ñ>|8ºtéÂâw^SSÃÓÏÈȨ©©‘x;(++C]]%˜¨eð±8hkk·š‹‹””LLLø<544àôéÓŠ̘1±±±3.›#HÌÑÀ¡­­gÏž}µwãÂ… ˜2e Gw5ab®*++™ò³‚$ÇlŽ †@Á¾………ðôô:Føâv§§§Çõš._¾Œàà`6U¤¶è7…C(((€¢¢"~ûí7œ;wN$#:??!!!X³f Ž= CCC¸»»·ihI¾‹ÊÊÊ\ŸKSSS¼{÷ŽgòòòÌ~»±±3fÌ@—.] ¨¨ˆ~ýúáãÇ ÁÌÌLܺu AAA #( 2jjjX¿~=ŒŒŒ ¢¢yyy $$rrrPPP@BBèt:‚‚‚ðêÕ+üóÏ?By§¨©©J¥ÂÞÞÅÅÅ ƒ’’¦OŸŽOŸ>áýû÷¨¨¨@ll, áää$P½í"ÄÝÝ]à愺º:ÊËË9rCРXn899ÁÝÝe[FFß$€••eq¯àw.+V¬€¿¿?W¿åŒŒ DGG =ËÜô¡µ´´dªI………¡®®N$w8Nlß¾nnnùò»_Ó§Og±ª;uꄵk×òUfb0())YÑ«­QWWÿªJXÙÙÙÐÔÔ„¢¢"ÛoÂ(a…††"99™cN~ôíÛ¸yó&ß²uuuøøñ£H 8µµµ1oÞ<¶k*--ÅÍ›7áçç‡S§N¡K—.mzFªª*„‡‡ TþÓ§O ¼yó0eÊHII µ*œ››‹åË—cåÊ• ƒ­­-nß¾áÇ£Gâ½)((FÙµ@Xôôô˜Ii}}}±víZ–ßW®\Éf@áôéÓÐÖÖFvv6Î;Ç±îÆÆFßm@à„ŒŒ †ŽáÇcûöíPSSÃÚµkA£Ñ0nÜ8   òòò8þ<>}ú„íÛ·cðàZ½ú IDATÁ"¯ºº ˜1c€/++EEE¨««Cee¥Pcùva€p À”½{÷⯿þjÆOÜcrÊÄ­«« +++¾û¶Ì­!®‹Gii)>}ú$T‚Cnäää ±±Qh_znL::uƒĪ'::½{÷æ8(æ‡V­Z%pЕ­­­ÄƒHSRRPXXˆáÇ ô<ÿïÿû*ïbUU$’ÿE\W>;;;|ËíØ±sçÎ… ÒÓÓaaaÁµ¾té[Mœ@ |[4#åååáààÀì_ÆŒccc 0b%»500`”éÕ«Ó³‡_®«vi€´5 PTTD·nÝD®£k×®èÝ»7óÿøñcDDD0¼hh ‰ øEJ¥bûöí¨¯¯…Ba >A}EeÈ! ÑhÌ™HN{lަœÈÎÎÆÕ«Wù–ËÊÊBii)‹š7ºté"Ðs$,¯_¿F}}=Ï2555xûö-×,áÝ»w‡‚‚yÖ“––†ºº:ŽYÏ…¹/_¾äk€ÁÚÚZd„J¥‚J¥‚F£áÖ­[˜>}:¨T*6mÚôUÝE…yo‚‚‚X‘ìììð×_ñÜoÏž=Ø»w/öìÙƒ#Ftè~ÝÁÁ›6m¦M›ÚÅj§>}úÄ¢–¥¢¢‚!C†ÀÂÂ***pppÀÝ»wÙöݼy3 ^¼xñUE1¡µøêÈ›7o””$– –°„……AUUU¬Á‘ŽŽÌÍÍ9æÐ†¦1Ão ÐrÅ¥ IÊ @SSS¢í-îŠBUURSS9®;iiiÈÎÎæ¸oee%ÒÒÒø7abb‚úúzfŸ_¼xÈÈH¡" òl 0@¢¹ êëëáêêŠùóç³%Ykù,mݺ•ëJ“™™”””øº%$$ ¦¦C† ùœЧO®Ï=ð%¯  @ Ùg~3Güñ^¼x;wîÀÚÚú«wζ¶¶KB{{{³­ZmÚ´ 2228vìÇ}víÚ…ÊÊJœ8q‚| ¹ èʆ DFF²¬xìÝ»]»ve D/**€““ƒ²²2ÄÅÅq hwqqAcc#þøãr³„¸8lܸ‘%6..û÷ïðeu˜S2ÜgÏžaÚ´i°µµeÕàENNf̘)S¦0•*i4öíÛÇ¢p{ýúuP(L™2…kðW7@êêêP__/ÖL£¼¼þŒuëÖaذaxóæ [}±±±““ƒµµ5:uêÄUQ+33µµµ|Ÿ#Ð1QWW‡¬¬,|™p¼sç³OÐÒÒB]]Û~÷ïßÇÅ‹qáÂHIIá©£¨¨ˆêêjêKMME¯^½D>UUU–÷üÍ›76lœœœ`bb‚ñãÇãéÓ§,û¼~ýçÎÃÌ™3™+]œUUUؼy3nÞ¼‰[·nq=‡ªª*Žû„ö±±1ºwïÎüûÔ©SÐÕÕ…¬¬, _¿~=[š&Ÿuuu!///бƌ[[[CUU.\@DD>Ì"6dbb‚={ö 55óçÏoŸH{ÊF.ʇcÓ¦M˜6m444„Zª·µµÅ£GÊb5 KBBª««ÅN8mÚ4HKK·Ú½h ¬æ”=X\ÌÍ͹æLõù$?Dff&fÏž#F`öìÙ8zôh»|N“““ñèÑ#lܸ°qãFXZZbÑ¢ElÆÚÇù®€q`hÎõë×Ñ»woîù1pà@¤¥¥qM6éââ‚={ö/cVII ïÞ½•JETT®\¹Â2ÿ½¡©©‰Õ«Wsý}òäÉÏ‹%T°|ùr\ºt‰ù7Fƒ¡¡!Oa’¬¬,tëÖ ½{÷ÆìÙ³1vìXP©T6WTooo8::ÂÇLJgöw///ÄÇÇ“ îB''' kÖ¬‘XÍó€4õ?²²²X±bqüøqhhh°¹qõë×222 lŸˆ¤°²²Â‡¸Î”6ñûï¿ÃÖÖV¨˜~ØØØà‡~ÊÅÆÆÆ¯_¿Æ¶mÛJØÂ- uzz:jjjÄv›=z4þý÷_±óya`` …"R–ï֌燵µ5ßàO … ü¥R©8xð Ä‹©ªªâÀɊΩýÖ®] ;;;L™2…˜N¡P$w$Ñø*• …ò]~LŽ?Î÷Úy?V­Z… & -- ä+-!ÃîäÉ“b÷#Íyÿþ=lj¬Y³fáßÿeû†4aii 67«ÜÜ\XXXÀÛÛÇŽþ}û8J¢7Í`FFFòœ\ BvvöWO”J ¸C£Ñ@¡P„ÂÂB®åªªª†èèh”••q-×<Hjj*>|gggžnê—.]‚µµ5ôõõÙ¾ 3gÎàÊ•+‘‘¾¾¾ØõM˜0‰‰‰ËVJ …‚òòr¡g{åää@¡PPZZ mmívñÐJBz•æææxÿþ½Ø9AZbdd„ÏŸ?#''‡e{hh(ðË/¿]§¶¶6ÔÕÕ‘––Æñ÷S§NaìØ±èׯ€/Ó¿ýöÇ•˜»wï¢k×®,Òu‚`ff&– g`` òóó1gζß/^Œ™3gbñâÅB¹zõë×ãÆÃ©S§8þž QW¦ž={¢´´”­#õ÷÷GCCƒÄ|ôÛ#***èÙ³'×ß333™Éy1tèPÄÅÅñ0$Ks!ð•©T’=::šmåüâÅ‹l«ÙÙÙÌ„¢ÒÒÒPVVf{ד’’`jjŠ7ÂÌÌ ÁÁÁ™””„C‡ÁÛÛžžžË466">>_5—ð=áçç‡èèh¸¹¹¡ººš©ì¸aÃhjjâÌ™3 Óé P(LÑŠ´´4ìØ±.\À™3gðÛo¿ t¬¢¢"$$$`×®]øô霱gÏ”––búôéðññÁýû÷add„ƒâíÛ·pvvæX—Ì×j0UUU¬\¹ÇÇСCÛä˜555¸pá‚D—™ÕÔÔ`ii‰iÓ¦ µŸ²²2LMM1zôh±Žïææ† 6tˆ—dñâÅX²d ŠŠŠ$ê{>räHÔ××ãíÛ·˜9s&s{mm­Èfff044ÄãÇÙ\5>þŒ„„˜šš2},¥¤¤`ff†{÷ªŠåúªªªÐ©S'¡ãkfÏž gggdgg‹ÇrôèQ¬Y³ÊÊÊì³:ÁÙÙ'OžÄñãÇQZZ*Ðs,++ Ž3&çÎÃØ±c¡««+±û;eʬ^½III, 2«««Á`0¾é8]]]Œ;çÎÃÊ•+Ù~ ‚²²²@jc-ƒÔ¿gDIZ).-ûqhÐ|q£¥P(Ì.67Ë–Ô××céÒ¥xøð!:wš8pYYYlÒð^^^˜4iòóóñøñcìÞ½›ãyݺu èÕ«&L˜ÀÕp–„ @ø’omêÔ©Ç\ØÆ0»víb™¸†ü?þø#˶ °Lº4Á/ŸÔW[i zæf‰‚††ÏY—ââbÐét‰»­[·N¤:…JÈ)CvGëÈù0·$99iii_.~´V€~~><==™1M899!!!aaa;–ºººÈ+ Ïž=Cee%ßøúúâ—_~8Y£††èt:KLOYYNž<ÉwÐ#©w»=8´jjjˆç˜…N§K$ÿ{C"$’BFF†©vÇɰ•œœ6ï‚–±m ÖÖÖL7`ØÛÛãìÙ³,û]¾|rrr˜6mh48ÀQ‚þúõë’’Brr2üüü8žWCCNŸ>²²2œ={–kn¢ëׯƒÁ`ðt !—¯²ÿ~‰VöîÝË59??vvvð÷÷ï°쯙![Rð `nIQQŠ‹‹ùªÌØÙÙ±åL7Û=·@t¬]»–cà)§gSŽI<Óü8qâæÏŸÏwæ»{÷ˆ*hmÏž=8zô(jkk™Ûjkk‘””$V› ÓœÜP¾Eöî݋ӧOsŒ/êÈ"í DEEñ-%Ös¨§§Çtn™+¤‰nݺáÇ×ùùógTVV²)}õéÓIIIÌ¿>|ÈæÆéýMHHÀæÍ›Ñ»wohhh GÝS“““¡  €ÒÒR˜™™qLXš––===Lœ8,çÓœ'OžàéÓ§<ãÉ’““™¹1@Ú%K—.ÅòåË;|¶ßæœ={¦¦¦;vl‡9çM›6áÍ›7Ì ò’¢eÖ褤$HKKóôŸ¶Nà‹ìkBBFŽÉqŸÅ‹£¨¨>dnk™¥Zú÷ %¦› Ann.GiÖÖbóæÍ8xð`«H9÷ìÙÒÒÒÌÁFTTttt$?F pÂÔÔ¿þú+ßr’LVÈ }}}¦‘ÁWõðóçϨ©©áèzÙœ—/_²¸5_òj©««3]ZJ]S©TtîÜ™mEòýû÷Léíãdz©{_Ôs¼½½™¹M¦L™Âñ¼ðÓO?aÿþý––æº „   ¾B MÁ¸ äÁ&¾7$22  …k[kqúôi¨««·ŠkAx„™Õu#** ²²²0`€È穬¬Œnݺ±$q+,,Dmm-O—0sss–Œ â`ee…²²2®³„œ¨¯¯•JÅ’%KZÍï_^^}ûöe^gii)rss…r)†@FF†9#ýòåK¶šj[{BNNÛ¶mc{gZ !Ú'JJJxÿþ= %RßóçÏ1fÌ‘÷8p bcc._XXÈ–C@SS“Mq2===zôÀºuë¸*;¦¤¤ÀÐÐ)Úâàà€uëÖáùóç,årssannއbãÆ¸rå GW¬¤¤$deeAOO®®®™žžŽ€€DGGóôwwqqÁ§OŸŸŸOZá[2@,,,˜‘ù-g\$Å”)SPVV†W¯^1·={¡¡¡8uêßÙ öÎÈ‘#ajjÊWj¸½Ó½{wÐét$kÝÝÝáääÄ·œªª*”••™2”’ˆÑÕÕŸqãX2¸»¹¹ñ=Ÿõë×ãÎ;ÈËËCNN:wî,V𩉉 233.Ÿ˜˜ˆ·oߊ¤þ%(ªªª°··gÆó|øðÑÑÑ­ºâÒ\öT˜ÄŸ)))ޱ@eeePTTd !|ï$&&"$$!!!É7djjŠŸ~úIìz455ñðáC 6¬ÕÛ`̘1|eåä䏯]ƒ±±1‹êÖ“'OðÓO?AMM :}ZØÛÛãþýû,û5_MQVV†ššjjjØ&  ¨©©A]]-ÇIXX´µµ±sçN,Z´t:£Ââ³gÏеkW<{ö þþþ¯%;;ÿý÷ÜÝÝñâÅ ®×|þüyÔÖÖÂÍÍk™¦¾Z˜>›@ HGKK õõõ())a~ ÿøãlß¾] \íÎ;#??ŸÙ‰vÔ ÜqãÆ[Nq077GŸ>}pçÎÀÉ“'%hš€W¯^aâĉ<Ë 2FFFðòòµk×0jÔ(±\ÁÖ¯_Ïóƒ×œæYÏÛRª-žÅÞ½{3oa3ËwtìííÍŒ¨««Ãßÿý]á JAAh4h4šD ŽÙƒ[)í)¡K—.(..n“c­\¹çÏŸÄÇÇ£ÿþlettt——Çü;22ƒf)sñâE–™çÏŸ äVlgg‡™3gBII zzzppp`™,€;wî °°Ó¦MCVV®^½Ê–O.\¸€¿þú EEEˆ‰‰á˜ø´¼¼yyyX²d ÊËËϵÿuwwÇéÓ§ÑÐÐÀñÜÓÓÓñòåKxxxp-C ¤ƒR__©S§â¯¿þ;I_{EÜ ë¯‰ ™ÆÛËy>{ö (((@YYzôè!Ð~-ƒâÛ‚÷ïßÃÏÏM¡«5˜:u*BCCQXXØ&Ï¢¹¹9ÆŽËæ®ñ=`jjŠÜÜ\¦ßýçÏŸßaßÿÖÀÆÆppp`ÎÀ·6ššš\ãÁ¾'òóóÊgõéÓ'¶œ5-”ŒŒ 6×J+++¼}û–eÛ¼yó˜1'À—üD-c<°víZôîÝ:::㫪ª ##SSS;vŒë„ŸŸ&OžŒ#FÀØØ˜£'B||< „ââbq])))Á©S§ǶBÔooo”••ñìóHöz1@ÚÑGÈÛÛ&LÀ®]»Ú4— 8óæÍCJJ × ™MƒéîÝ»3uíùÑ”uøØ±c;v¬DòËØØØ 44ÕÕÕBedŸ1c ÐÐÐ vPöĉallÌÐɉ¶Ì?räH$$$àÆ(--…££c›÷·ß~Ú5k¾»<ÍE‚‚‚`eeEEEÒ™´ƒûÒlܸQàD’/_¾ä›c*==Ý»wçøÛöíÛqèÐ!_’·Ì#К¢k×®,Ûú÷ïϲâÂ1ù/7å-àKð¼¼¼<>þÌâ‚V[[ iii¦+£––›qƒ;wîÀÊÊ ëÖ­ƒ££#|}}ÙŽñîÝ; 2›6mºuëàããÆVÎÃÃ&L@çÎñúõkŽç›šš ooo\¾|®®®e¸/É^^^¸}û6×6=qâ²³³ùºç5õ-1@DÀÎΗ.]B}}=W…ŽLS÷Ñ£GáààÐaƒpMLL`kkËÓµ(::Z(?ÚÖXuèÔ© €}ûöAMMkb­–hiiaÙ²e R©Ø¾}»Øç!ˆ|q`` tuu1wîÜ6»Mrœm5¿uëVôîÝ›Íã{ yVí¦I–Ž×ÖÑ100`,‹Js)n0 ÔÔÔð5<}}}¹f]o»!Nß(##ƒÚÚZŽ+¢"H]Ož<á›ä¬¬¬ ÒÒÒ,‰hÑØØÈ".¨»nK)õ~øíûÎ’´GHMMe)³råJ`éÒ¥X½z5ŒÙŒ™ÔÔTþí‰É“'£¢¢·nÝÂýû÷allL:‘À´iÓPTTÄ3Wˆ°Jw¼Þæ³û_EEEæLy`` Wùà &àéÓ§<ëÒÐÐàš„œ ‹&£¨IQ+++‹£+§¡¡!rrr˜@KK‹m2¤yrÈ’’¶É&KKK„‡‡3ÿ®¨¨À”)SXVpuuu¡¦¦ÆvßLLL ¢¢ÂŒ9”‘‘a X¯­­…¼¼>]ºtžžSò½9õõõˆ‰‰»»;¸±<@RRÜÝÝñîÝ;®íµ{÷n{ö,V¯^ &`ÕªU,jqM¼|ùüñaccƒòòrŽ®Zïß¿ÇìÙ³qåÊžmÃÓùøñ#öíÛÇ3[u“ñ1dÈ=zûöíc±, a3f þüóOhËaÆ!%%BI_“øøxTWWƒJ¥‚J¥âðáÃ(,,ÄÉ“'A¥RahhÈÕ)((€››¨T*ôõõ‰Â555 4ˆg™¦¢üŒ‹òòò6„ýû÷cÿþý\Ÿ8q"O·&>|øÀ3‘ïÈ‘#¹f)o-rssѵkWfVö–4¹*…‡‡ÃÒÒ’ëý///ÇÛ·o1lØ0Želll„»wï2ã,ZÒ…¾¾>ÇÙþÇCGG±±±ðõõåè®&//½{÷"==cÆŒáxî999¸zõ*ºwïÎóú®_¿ŽÊÊJ®eÒÓÓñ×_1³ÉÛÚÚ²•ûøñ#™Û¹ÕõàÁ¦²¯¯/ØÞ…æû&$$ÀËË‹-V†N§ãÔ©SÐÑÑAee%ØŽ÷îÝ;xyyA^^™™™())AII K9333¸ººbæÌ™€¿ÿþ‹/fÆ¡|üø%%%8sæ ³¿‡’’Ûñ¼¼¼˜ïGpp0ôõõÙÊ\¿~Å ë¿ÿþƒ––K?TTT„ . sçΠÓéøôé’’’˜õ P(ˆˆˆ`  >†††bü¿õ777ddd0´oß>¨««#++ ÷îÝã©§M¡P˜šÈÇŽâE‹˜–ŒŒ |úô‰íƒƒƒQXX‘üüyiŠs£±±?~IVP”㉳_II :uê$’Fy[Ÿkff&Œ¹vt’>^yy9êêê„–ýÏ[NNŽHþ¼¢¶MUU***„ÎËAž·Žÿ¼5ÍbéèèpA+++®j.œfq=Ê2h^¸p!._¾Œ> {÷îHLLĪU«Áœ¼jþiNLL bbb˜>Ú-˽}û–%ùÌ;W"±Q¢Þ‡–ANNNìüD ƒg,Å׸¶‚‚())IDúœF£AWW222bÕ#j?ؚ픕•CCC±c7+**PSSÃ׉<—’y.Å7v„ç233FFFmú\þþûï_âŽ|ÈÌÌd¸ºº²lkhh`dgg3ÿÞµk£ªªŠÁ`0‡fäåå1áæÍ›Œððp†(lÚ´Iè}***»wïn³ã‰³ßƒOŸ>íçºeËFccc›/88˜ñï¿ÿ ½Ÿ‡‡#,,¬ÍÚ¦²²’±k×®6½ñññŒË—/ ½ßÇ;Ìó¶uëVFCCC›ïÕ«WŒþùGèý<==Ûôyc0ŒßÿQXXÈhÏTTT0öìÙÃx÷îãÂ… ,Ûš(--e3 #!!qñâEƒÁ`”——³”“tûµV=wïÞe¼zõJìz[¶liW׿îîÎˆŠŠ’H]...Œ’’±ë‰‹‹©ü?öÎ<žªíýã2ÏC(QH¤h ÍW£æ9Õ½R!刺7¥Ù©Ü& Ji¸4(MˆD™¥Á<¥HæyúýÑÏùv:çppŽ©õ~½z½²÷Úkí³ö´žµžçùp³Ÿ¶lÙR_YYÙêzÂÂÂê¯_¿Î‘sòôô¬ iu=555õöööª¿/]ºTÕêzŠŠŠêwíÚÅ‘sЉ‰©wssëPý´yóæúªªªV×óúõëú7n4ë˜F§Ž?ޏ¸8$&&"==¶*’™™‰¾}ûÒ–fÖ­[‡½{÷¢¢¢³fÍ"ªÈ@ ãÆ ƒ˜˜6nܤ¦¦‚B¡@LLŒNUùÈ‘#ÈÍÍÅ™3g0`À¤¥¥1-G „Î Í«³Áj¹ž@ú†×®]ƒ††Ëà½ß™‡BPP&L ñ ¯^½Bvv6æÎK:ƒ¼ ¿pùòe 4¨ÉÀwgxóæ ’’’HÄ6¢¸¸ÎÎÎ&> ´ ¢B @ ÚŒN»’––F¹Hß4‹oß¾AXX˜#Á’]‚‚ððð´(½«S\\ŒêêjZ6yþ'ƒÐ MÃÉ tBÓp2Љ úúzZƬ¿þú dùÜ¿?€¹›×®] !!!ru B³ C]]Ëüù°{÷nŠŠŠpþüyÒqí@]]<==KKK¨««7YÎÊʪÃéZ„¶áÍ›7¸~ý:m|ihhˆ… ",, 7nÜÀäÉ“abbBûܸqüñMå>447oÞ¤ÛÆŒ×¯_ÃÓÓ&&&˜|8²³³akk‹‰'bíÚµPUUE·nÝ0cÆ ÄÅÅATT8pàîÞ½‹ŒŒ hhhÀÁÁµµµØ»w/&L˜ ÔÖÖâÀ¨««Ã€~gQQV¯^ =zÐÒÒj´oFŒ÷ïßCZZÆÆÆäfa££#ž.\¸€wïÞáëׯpuuŨQ£ÀÏÏ«W¯âÂ… †––6nÜcïÞ½ù-ʹ¹¹pqqÁýû÷ˆeË–aäÈ‘xûö-.\¸€ÒÒRXXX@CCoÞ¼¡Û¦©©IÛVVV†Õ«WÓêµµµ???´µµ¡©©‰ÐÐP¸¹¹¡¢¢‚öÝ 0ÒiÓð¿¾ä:;;;Œ7'OžÄðáÃannSSSlÚ´ EEEpuuE@@Ö¯_QQQ¬\¹“&M‚¾¾> áàà€¯_¿âÀàááÁ¾}û $$„œœ:÷¾°°0Œ?AAAxûö-Ö­[‡mÛ¶áÓ§Oøúõ+ž={†uëÖAVV{÷î… „……±wï^˜ššbëÖ­X°`F…1cÆ`ذa?~<:>>>888 ¨¨ˆ©¡5nÜ8˜™™AJJ gΜAaa!-;ÇÏbÁ‚€?ÿüªªªØ±c¹Y¡ˆˆˆÀ”)SðõëWDEEaâĉ011ÁèѣѫW/>|>>>8þ<ÄÄÄpþüyìß¿ÅÅÅØ¿?ÂÂÂààà€ÊÊJ?~£G†••DEEáìì ¸ººBFFW®\AQQ-Z„S§NáàÁƒ•JŽ{÷ðàÁèêêÂÕÕþþþ´ïÔîÝ»¡¡¡A.¡M!B„„.±±1ddd°sçNŒ=3f $%%1hÐ ¼|ù’éqýû÷‡‚‚ÌḬ̀aÃÚö€€†Õ‚+W®àèÑ£pqq¾¾>„……imóóóãŸþ¡¥ðû•€€|úô ›7oFÿþý¡««‹îÝ»cåÊ•°¶¶†¡¡!allÜè*EC9¬X±‚\x@è$ 2RRRX½z5Ö¬Yƒ   a÷îÝÈÊÊBïÞ½ñöí[¶VªQTT„þùÙÙÙÐÓÓƒžžF {{{(**Ò¾=C‡…¸¸8-Z 8;;#""‚æZJŒB{ÀGº€@`ØØX¤¤¤€ŸŸ¿EÇ›››s-kRrr2¼¼¼è¶ñóóÓV@Ðñ5jMFàË—/Í:v̘1´c“dì²sçNÌ;—$Ò „@h iii¨¬¬Ä—/_УG8::âØ±cX²d """píÚ5|øð 8vì‚‚‚ ­­ììl”––"--®®íÛ·ãܹs’’¢m;xð ­LVVjjjšš QQQÔÕÕÑÒ€"??}úôÁ‰' ªª sssœ={bbb8qâŽ9‚²²2ºv`Ïž=ÃÞ½{“'OÆ™3g ¦¦àGP[MM ÒÒÒ ¢¢‚ÚÚZdffb„ ðôô¤«KAAÀmœ@PPóæÍk2f„@ œû6UWW#++ ݺuCEEí½oii‰¥K—âÁƒðññÁŸþ‰­[·bÛ¶m••¥ÕѧO899aàÀHIIAjj*¬­­±dÉ<|øÞÞÞøë¯¿ÚÚZTVVRSSaccƒÅ‹Ã××wïÞ…••Œµk×ÂËË‹IÚ Bè<{ö ß¿Ç!CЯ_?ºmC‡¥ ”=}úUUUèÙ³'1xð`DGGCLL üñnß¾>}ú@__ÁÁÁøüù3íР9üÈzyyytëÖ ÙÙÙÐÒÒ‚¸¸8ÂÂÂ0jÔ(ÈËËãÎ;PQQÁðáÃD+'&&†7oÞ@\\œæ¶%--íÛ·C[[›½bÅ ØÛÛÓòÇÇÇãÝ»wèÑ£ŒÇcàÀLÖ ¤eåPSSƒžž¹a¡ ð÷÷Gnn.tttÀÇLJÈÈHHKKÓ’ê$&&2l»}û6^¿~€€„……øŸp^ee%JJJ0cÆ $$$ ** 222022Âýû÷Ó¦MÃëׯi¢Ì ådee1~üxÀýû÷ñäÉ?~œ\$1@„ßiiiÒDŒüüü°wï^ܽ{—n6Œ@ ]›»wïÒ‚Ð9IAA+W®B»A‚Ð „€ŸŸV­Z…W¯^ѶMž<Äø „ߌøøxŒ5 ‘‘‘\©ßÖÖ–„v…¬€@ „6ƒ¬€@ b€@ b€@ B‹iRÄÃÃyyyظq#Ë2YYY8uê***0kÖ,Œ=šô,@ åÑ£Gðó󃘘lmm!--Í´œ¯¯/ž}Û·o‡³³3^½z…œœÒ³@`ɇ‘‘*•ŠÍ›7ãèÑ£LËÅÇÇ#++ T*,Ë¡óÐè È!CÀÃÃ;wî4ZIYY„……X4¼¼¨­­¥í»{÷.^¾|IW>55'N„¥¥%¹ðR]] ~~~€¨¨(JJJX–ˆ‰‰±,÷3ÆÆÆ¸zõ*I3J ÑéÓ§ÒÓÓ[ÕÀìÙ³1{ölºmëׯou½BG§¾¾YYYPTT// ·j ?~ )))Îø EAAäää ((H:„@ :-åççcÓ¦M´¿ „ØØXÔÕÕ¡¤¤¤g#îÝ»‡–ÈÉx{{wé~)//‡²²2 ÈMÒFXXX`Ö¬YˆŠŠ"ÑÁéÙ³'²³³!!!1bmŸ¯¯/nݺPTTDVVàÕ«W022b«þ'Ož $$„t4@ t6äøñã8vìÒÓÓA¡PPXXÈ´ÜÊ•+ìÞ½¢¢¢¤g¹<° ëçRZZ *•ŠqãÆáòåËlóéÓ'uyîW¯^ÁÖÖ¡¡¡ä¦mŽ?ŽáÇ#44'ÒéÞ½;6lØ …‚ÌÌLÌŸ?Ÿi9999ØØØ€B¡àóçϘ7oÛmŽ&]–oß¾aÔ¨Q P(˜5küýýiû @¡P°lÙ2\½zµUí¼|ùÆ ÃÌ™3áääDÛ ,Y²¤Ùaí¢„¾~ýzˆŠŠâÀäîiAAAxþü9¶mÛ†nݺµë¹|þü½zõBAAvíÚ…””œ8qÊÊÊ,¯}QQ¬¬¬ðäÉ$$$àÒ¥K]ò:YZZ¢¢¢"""8qâ¹q¹Œ¬¬,^¼xAƒ!99@YYΞ= ‘.ÿûkkkqçΘššÒb&~W„„„0sæLÈÉÉáäÉ“äá ]’ºº:”––B\\[·nÅ®]»hn§’’ÂŽ;ð÷ß·ê;èàà€Í›7CDDööö´1ÍñãÇ1vìXhiiaÆ 8}ú4ÛuÇôNÈÅ‹qöìYTUUµû¹¤¥¥¡OŸ>DZcǰfÍ888`ÿþýtå>}ú„¿ÿþ¢¢¢8wîôõõ±bÅ ¸»»wÉkTQQœœ<}ú”­ YBë8qâ&MšMMM€ššΞ= P(wÙß^XXˆ{÷îaÙ²e°³³C\\¹!ôèÑJJJøöíé Ð%áåå…¸¸8îܹƒ©S§ÒżIIIáåË—ÐÕÕåÈ$œ¤¤$„……&¸¤¤¤ @KFE .Jjj*ÄÄÄh>Ñí‹‹ ¬­­iAÖS§N…››âããqâÄ dff"88ÐÕÕÅÚmv6(([¶l¡ùs“ôôtøúúbÓ¦M¨¨¨@uu5¹y¹Dmm-âââãÍ›7£wïÞ°··GYYY—ûíŸ?†­­-"""°wï^º™©ßÜÜ\dff"33`ccƒ?þø=" @èÒDEEaÈ! Ûƒƒƒ1jÔ¨Ži<‘ËÖ¹(((À… 0qâÄ{ŽÂÂÂððð@uu5 OOOœ={–ÁÇ[RRÆÆÆmŒþï¿ÿ¢ªª óçÏGPPWÛòöö†©©)lllðäɼÿžÜ¼\âëׯpuuÅÎ;™îߺu+TUUaaaÑe~suu5( -Z„©S§b×®]èÛ·/Ö¯_ÄÄD|þü™cm………áË—/¾Oüýýáåå///ºTðЕyøð!Œ!&&Æ`|hhh@NNŽ#íøøø 66))) ÛÓÓÓ›ü… !!!èëëÃÎήCŸ§­­-¾ÿŽãÇCCCƒa¿¸¸8tuuÈõsyûö-RRR`kk oooܺu &L€¯¯/WÚ À˜1cÈÍÚMj ±ƒ>ÜhªãÍ›7£ººT*µÓ÷›··7&Nœˆ‰'"00!(;>>1zŸ IDAT¹¹¹kïäÉ“pssëðý2þ|ØÚÚÂÖÖ–'//O„q B—ÇØØ˜öÿk×®áÙ³gÀ±qÈ¡C‡ðêÕ+\¼xT*ð÷÷dž PPP€cÇŽ5ûûÊG.[ç"::šé2[{ðýûwäææÒüî;*uuu8vìæÍ›G Ž?zô(²²²`ii‰>`áÂ…PTTäH{999())Aß¾}É Ë‚ØØX ãÈ‘#=zt‹gh¢¢¢гgÏþ6}wóæMXYYaêÔ©L÷ïܹŽŽŽ¸}û6GÚ‹‰‰é´AíJJJ4—,@èŠüú-X²d WÚ9räíÿªªª´ÿïØ±£Eõ‘NÆåË—affÖ!Î%11ï߿nj3Z\‡ ®_¿ÎÕYÊääd¼xñæææ´m<<|8¶oßN^¾@àÄé¤HJJ¢´´555úw¨¨¨ ;;›k½jjj°oß>XYYAFF†a÷îݱtéR8pûöíc©uÓRßýüÛbà…Û·ow˜MQYY‰eË–¡¼¼¼E19ååå8~ü8´´´Ø*ß§O¤¥¥¡2sŒÂÂB|ÿþ½Ñ2S¦LAaa!^½zÕª¶êëëqqqôéÓ§Óö™„„D—΂F ~o aaa'''TVV"++  ... cÄ’’’V¹Ô–——cÇŽ°±±¡{¯VUUÁÕÕýõÛ“_ÄéDÄÇÇ£¬¬ Æ ƒƒƒ¼¼¼‚ôdddàÊ•+غuk“ƒÓÅ‹sD›ÆÑÑ‘e@479{ö,&Ož Ns}áèèˆÿý·ÙÇúúú¢ºº3gÎ$7ú/˜šš¶:¹CII œÛå^æ$–––8yòd›%» „¶äàÁƒ˜;w.òóógggP©T#--®¬»»;|||ZÜ–¯¯/„„„`ddWWWÚöÈÈHHIIaÅŠسg1@ºÉÉɨ¨¨À€Zt|DD8v>tO-ÅÙÙ™kŠÅÍq­¢R©8pà@«ÜÁâãã!,,LçÙÄÅÅ¡¬¬  ¥Ãë@äääààÁƒ´ë¢§§>>>:t¨YõP(”.TÞÜû™ßlllÜêg* †††^ÔP^^:::HMMERRù„.ž}ûðÇÐþ0`¦OŸmmmHJJÒ¶!!!jjj-nkΜ9ضmÃöž={ÂÙÙááál ‰òÑ È)|||86ûÌÙɰ°0¼{÷«V­bïaàå…ŽŽ¢££[ÜæÛ·o!""Bg$Λ7ß¿ÇóçϹvm§M› HHH@II ñññîzçμ}û–­ò 066ưaÃØn£gÏžX½z5Û³3™‘#GBUUW®\iÕó=yòäf‹KuD¦M›>>’s…@ tM’’’гgOŒ1™™™8sæ ^¼xÒÒR?\žýüüZÏWQQ///ZšÝïß¿ããÇX³f ­Ì÷ïßaii AAA¶Óñ¶™ … …Âu †ßÅ€hðig—GÁÉÉ©S¹è´†Ã‡cݺu ¹±YÁÇÇ{{{¸¸¸ÐÚæ’šš ºm¢¢¢¨­­Eyy9W~ç…  §§‡¡C‡BYY¸uëV§ºV}úô™™:„ÊÊÊ&ËŸ>}Ý»wglŒnݺA\\]þÞ„ºº:Þ½{×¢ãËËËñíÛ7ZÖ¸®@=ðõëWò!!]Šôôtþûï?š'/oû¿ºÊÊʰ|ùr¸ººrUH³µÏ•‹‹K³â^¾~ýŠÒÒÒVeJ!BÛâëë‹ÜÜ\„……ÁËË  enß¾àààVµóýûwºIÇàÙ³gM–û­ Í +++”——cÛ¶mظq#víÚ…”••uØs/))a”™>!!! a)6)!!¢¢"ºmÿüóÃ6@èL\»v |||ÈÍÍEJJ ”””°qãF:aâÓ§OCAA@ddd‹Ú‰ÅúõëiFŒ§§'xxxpáÂ<}ú”î;bmmb€?„W®\‰ñãÇÃÌÌ nnn8rä´µµqçÎ,X° Å…Û4îþJ~~>[Owww¬X±‚cçsùòe¶Ø¡!°¶µ™¢\\\°téRÈÊʶªžBYY?f{F °°åÌü°aࢢB÷€²¢!øÕ«WØ·oÞ½{ ܺu ™™™(..ÆÉ“'±råJ¦ƒr111üùçŸl-%##rrrbû˜ÒÒR´(6‡S˜™™µªoÊÊʰiÓ&¨ªªbË–-°¶¶n¥û–$8‚……E³ÎÓÏv[‘››‹ÌÌLdff²4@†ÊðŽ÷ðð`;m$@ t4®_¿ : Àüù󡬬 SSSºqcaa!Þ¾}‹Å‹³•m’:::ذaíï’’„„„`ÅŠtã·AƒÑ•ûí fðññaþüù8|ø0† B§ìؑسgO«Üm¢££1xð`ˆ‰‰aüøñ­ÖÝˆŠŠbëÐR¦OŸŽúúzœkÊãíIQQ¢££1zôhŽÔ7sæLäååµ¹n 3…yØÚÚâÑ£Gð÷÷gÈjÑÖ”——#,, ÆÆÆPSSƒ   Þ¿ߢßÖ™‡¸¸8ìííiÛ† †ÌÌÌ«1a``€ääd|ûö­É²ïÞ½ƒ¨¨(TUU‹ï‰'pôèQ$&&ø‘ôàÅ‹dTC :ååå˜5k°}ûvdffBNNõõõøöíݤgPP¬­­±uëV:×,vÆV wïÞe؉ àèѣ͖/ Y°~bôèÑPRRjQð1·QSSƒ¸¸8Ãvv‚·!!!Á1‹—[´vÖ•ÓAÙÝ»w‡>|Øh¹””ܺu Mþ¾¦fÞ9lggÚÀŠÓDGGÃÁÁ¡YB€Àô®¦¦¦òý KKKÚÊGsŸÃödçÎl­ú„……ABBýû÷ï’ïø^½z1] êÝ»7ÂÃÃŒ{÷î‘!@è ÂÛÛׯ_DZcÇPUUxyyÁÃÃbbbð÷÷Gzz:tttp÷î]¤¦¦¢{÷îl·!!!*•ŠÙ³g#++ Ïž=ÃëׯññãGôë×þþþˆŠŠ‚²²2¢££…ÌÌLZ¹OŸ>ýÞ;þÓBBB P(Ø¿‡:wWWWŒ3={ödØ'))ÙdðöãÇ¡¬¬Œø¡:““ƒŠŠŠ§§'ú÷ïÏq7+V´Ø—¾¸¸Ÿ?æøÀÉÆÆ—/_n´kjjPZZÊ4Fçg؉=àT°„„ÊÊÊÍ¢Õ._¾L'&اO¤¥¥uŠwÁ¢E‹×,·›ÐÐPX[[ÃÓÓ“éê@ß¾}‘ŸŸïß¿s­¿ ¡¡¡Ñ¢ãûõëÇ–_[ i¶5Æ Û7o¶›˜˜`ëÖ­2ö…@ ü¾ˆ‹‹ÃÓÓ***8uê&OžŒ'NÐ&Ó '',Y²***011¡›‹°°0ÆŽ‹… B\\S§N…ŽŽŒŒŒ`dd)))HIIAXXãÆÃüùó™NžÿV»dÔÕÕ‘““Ó¡²¢ddd ®®Žcõ­[·ÞÞÞ-VDÿòå DEEYÞT­!55µEÇEGGããÇÍV>ggàfllŒ .°,ãîîα «d‰ÔÔTDDD`öìÙt†;Æ£€€DDDÚõü{ö쉒’¶µ@>~üˆµk×âÒ¥K,ß!“&MBUU×\³²² %%QQÑ?uêT4é^”šš •ßæã““ôï߇‚¢¢"øøø2r"C@ pƒÞ½{cĈ4]6uuuŒ1‚6Y6pà@ÚŠ‡A«ôÛddd0bÄŒ1ŠŠŠ]]]èèèø1©¢¢YYYZ9f“ç¿’€oß¾aĈl ¦¦¦pvv&wu'‚[®=¼¼¼Ø°anÞ¼ÉÒg2::šcú­M6ð3¦¦¦­N6ÀÊHúòå ´´´šu\\\„……é —Î€››FM§ÁÓ–ýÍ)œ±cÇ–iýüü ££ƒ=zü6ï’’šQ×°¢«¬¬Ì»~òäÉ\[Ý"„ß‘ßÂIOOGAA ÄVy*• GGÇ1ë•——'''–ÑŒ3 -- –uØÙٱͩ=1b pìØ±f€1cÆpå¼ôõõabbgggP(†FFFX»vm“õhjjbÙ²eرcG›ôç˜1c¸2#Ï,\^^*** cy\RR233;ÝûƒÝÀyn¨Ýs’Þ½{ãÎ;°±±aªŽ uuõfùwF–.]Š«W¯"((¨Y +ìììȈ@ t8‚ƒƒ1oÞK­:¾ßáâ4¤ e>>> 8ÑÑÑ:cOc4D·$ØÙÑÑ‘©êe{áããL™2…km´E€±§§'äää0nܸ}ïøøø0hÊôêÕ ýû÷dzgÏ ¯¯ßáïÿ† q__ßFËedd€‡‡‡-aÇáÇC[[/^ĪU«8v®•••8xð GÒËËËãþýûضmþý÷_œ9s’’’(--Å‘#G¸šº¹£qÿþ}¶ŸëQ£FA__oÞ¼ÁÝ»w‘™™‰‹/¢[·ndôC ÚmmmèêêÒþ...ÆÃ‡ñï¿ÿ"//Ïž=ÃŽ;päÈÔÖÖÒÞ[xòä KÝ$fäååJ¥BRR<???Ξ= ---:ÝåË—CJJ wïÞEvv6Óº¸¾’ššJS§mø÷åË—6½8ÍÖ‚ ¸.ävîÜ9¸¸¸´Z|¯%¬X±¢YJß?SPPÀ¶ªwsQQQivH||jjjZ”Q---­ÃÄHJJ²Õ/¯^½/// š,+((ˆM›6ÁÉɉãç[XX鱯 œ?£GƆ PPP€úúzqí¹îhäççC\\üüüM–=yò$¬­­Ñ³gO<{ö JJJÉ#„Ö~Ï~Ö [µjÄÅÅñøñc ÁÐÐ[·nEMM ݤÉ ¡¡Ñ¬‰âúõëPTTDÏž=qúôiܽ{—ÎM]JJ kÖ¬Add$¦OŸÞ>H~~>M¶á_II €9‰#""¸Ú~ii)xyy›=87oBCC|9y^>|Àýû÷Ó¨ñ´hÑ¢FÓJII±t»víÆ…Nñ ±Ìü3...M*nvÌÌÌpûömÚ3ð3Ççh¢™3gâË—/ºE5—àà`1]m233Ãõë×YfÞꌖ ›5(ïÛ·/òòò8jôq KKK,Y²T*fff˜7o^‹ƒÜ;ÕÕÕàãã£eqû™)S¦àÑ£Gt†sïÞ½allŒ/_¾`ÆŒLƒ*=<<ŸŸOFC¡]©««Ã7@¥RÑ«W/|øð—.]BNNÍ+99¼¼¼;v,JJJoü̯: 111PSSÃ’%K°`Á̘1qqqX½z5Ýq .„ºº:îß¿ß>ÈСCiê´ ÿÔÕÕüð³µµåjû·nÝ‚ŒŒ Æ߬ã ===®­‚TUUJ¥b÷îÝØ°aË<ÉÑÑÑÐÖÖnÔBmLƒ 66jjjtj˜]¡C‡6[³½}Bii)Ëú~Ö‰EDDæÌ™?wôíÛ3fÌ ³gϨ©©¡¤¤¤ã逼yó)))ÐÔÔì°™c¸©ŒnggGGGŒ1ƒn4ˆœXYY¡¾¾¾ÙAÁ°²²b+¥qK‡®®.Ûý~äÈHHHtúÌ={öìÁìÙ³i©ì:*vvv]".ªAOƒÕ‹±5Œ3oß¾mô…Þ( þþûo® ‰ÊÈÈÀßßFFFäËý“!Ù˜Rð˜1c˜¾£úôéƒôôt„††²7D ­åáÇHHHÀ©S§˜˜H[¹}û6íB¡P0iÒ$ÀÉÉ %%%°µµ¥ýkŽ‹oLL þùç@`` """°råJ?bDÿûï?˜ššÂÅŹ¹¹ P(Lëi· ôçÏŸãСC¸yó&¦M›ÆµvqñâÅ»páB¸¸¸ÀßßcÇŽåÚ9®]»kÖ¬Á_ýEç#§OŸ¶Xœ¯²²>|ÀÔ©S™î‹‹Crrr‡úPJIIaôèÑðöön2«U}}}³ ün4¬ŽMš4©Õu%%%ALL òòòL÷ËÊÊÂÚÚ{öìaXpww‡¦¦& ;Mß={ÇÇСC›uœ©©)æÍ›‡âââ߯¥©#ÐðñШ;;¨ªª"99½zõb«|yy9„„„Я_?$$$àÅ‹t³?—ËÈÈh± $@ üÊÔ©SéÆyêêêX²d ]™Ÿ3¡nÛ¶á›Å.::: YU«ýì!ÑTöÕv[QTTÄ_ýÕ"ŸÿæÐa7QQQXYYáСC=§¤¤$Ò2å :ƒ b ¯®®FEE$$$­ODD„éìhQQþûï¿.«î[WW‡+W®0ddêÈ Âîž///ǹsç¸ÑX|Psyòä ¡­­ÍüeÂË qqq¦í•””€ŸŸ¿ÑX¦ŽFqq1! Ьãºuë+++®¾×ŒXZZ‚J¥‚J¥‚3skyyy’’j2H3??’’’˜>}:<<< ,,Ì4î0//“'O¦»ÇòòòÈÅ#¿íf€,_¾222-ÊzÄ.wîÜžž^«Ü…455‘™™É1w øüù3êêêèVìììpöìÙ)°khh`äÈ‘´!n NkkkQ\\ÌõL9+V¬Àýû÷›þº|ù2fΜI—ý¡Ã?p¼¼PVV¦»çkkk‘‘‘Ñá¨ÙÉ~ÖÒµµ3Ðm™™Ë¯úúzxxx´Èxçáá¶¶6>~üˆªªªVŸ'Ç2`šGuu5øùù™«³bþüùX»v-f̘Á4øÒØØ—/_FHHV®\‰çÏŸÓí¯ªªj—̈¡sRXXˆ›7oâË—/HIIÁÚµkA¡P°fÍ|ýú¹¹¹8}ú4ÓãV¯^ …ÂöDÈË—/A¡P`ccƒââbÿ›Dý™ÀÀ@P(lذV®Ã ¨©©¡gÏž âxÝïß¿‡¢¢b«ÌcÆŒA¯^½pýúuŽ—££#ƒ––Nœ8)S¦Ð->>>,~¥Áݪ94¼ÎŒœœœ9s†cJݬ}úÔäG8::K[Û^øøø`òäÉ\I#Ü¿HHHp$³ûöW6oÞŒ›7ormRÓ÷YTTT£÷WKÝûÖ®]‹W¯^5šá޾}û†·oßbóæÍä+ÛÁ‘‘ašõjÚ´i••…††>~üH·/ 666ˆŠŠBff&FÅpüÛ·oñàÁÒÁ-âââàåå…’’ˆŠŠbÆ ´ X‚‚‚ð÷÷gHšüˆ±°°•J…¬¬,[mÕÕÕJ¥ÂÈÈ®®®´z.\¸@W®¾¾T* ÆI‡1@”””н{wŽ `ÕÔÔ 88˜#³T*µMŽÿøãÔÖÖÒDþØU`f…BÁþýû;•ÛËφ_c¤¥¥áĉ8|øp§ûmHJJ¢e§€W®“ŠŠ DEEñîÝ»výÍvvvpvvî4×( zzz­ÊÇ eô‚‚‚F$wPWWGbb":{{{¦e$$$h+Öááá6lX“õ†‡‡COOÊÊÊðòòb5þ|;v ÀײÐÐPrQSFމ &ø!6«¥¥…   hkkCJJ óçϧˀõ³1aee…§OŸ6ë»vóæM¤§§cÓ¦MˆŒŒÄ£G’˜ãÆÈÊÊb„ÎÛU/HUU|}}›\ÓØÇH@@€#ƒ¸/^àÛ·oX°`Ã>ØÚÚÂÅÅ…å’ÕïLMM±zõj–nX9ø|Ò¤Iˆ‹‹Cvv6Š‹‹‘žžŽ¶ë9eggÃËË‹åÊÅ¡C‡0þ|¨©©5YWWH àíí±cǶÊõiýúõ¸sçN£Ù”m´´t“z:::ˆmÖ{½9‰JÌÍÍqúôièéé1ÕÂ:pàÊÊÊðéÓ'–+Û666äÞ" TVVÂÏÏi"ŒŸYºt)ž@II‰evœ… "==ÎÎÎ(((`™ÁŠYž9s†Î真ŸŠŠŠ~ˆ»uëF›‰g§O¹•~÷W/^Œ3fÀÊÊ ®®®ÈÎΦÛïîîÞ%‚ë³²²„… r­ vâ¬V­Z…ˆˆìرnnn ¡¹ÀÕÔÔàýû÷0`[Ï“™™Y§ÀÖÖÖ†¶¶6nܸÁðòþòåK«ïõ‘#GBQQ^^^䋨PSSCFFF£ïÆæÏtANNß¾}C}}=Ã>qqqÈÊÊB@@••• ÆŒ¹¹9¾}û†;wîÀ‚©vC–DàG\á‘#GÈÅ%xÿþ=ÔÕÕ›ÔuJKKƒ¤¤$¦M›Öè·½[·nPRR‚””"""`ooÅ‹ãÞ½{Ç©S§@·Z,X° ý„95@j....X¹re“¤ØeÀ€8þ<,,,תójJµûÞ½{ððð@·nÝØÎý¯¢¢‚ôôtÔÕÕRRRÛè }̘1‚ŸŸÛçneeÕdFNгgO¬[·'Nœ,,,pêÔ)äååáãÇHNNfÛ8ëˆ4$¸|ù2× ©¦ ü[·nAPP¶¶¶ððð€¾¾>¼¼¼`aa/^ ;;—.]jV–®´´4Úÿ¯]»†ñãÇCAA¡C]qqqˆ‹‹3·999¸yó&Ö¯_ßê6ìííqúôi”””´èøË—/wª,oiii,_¾¼UuL™2>DII SW=:ÁÑ„„¶ÒïæååAVVfff˜2e -ZÄà"QVVCCCDGG£®®§OŸFrr2C]gΜANNÐtŸ:ƒP(@`Ÿ‡âÑ£G8tèáããC7®8uꢣ£A¡PP[[ '''$%%áĉ P(?~|£2üüü1bTTTàçç+++8::bÆŒ¸uë¨T*LMM1dÈšÈãÇamm½{÷búôéLëåë'++ CCCþþûoÌž=OžŸBWàW_YZZÂÒÒ’öwƒHKbh·lÙÂrLÓð΀Y³f5YW‡X‘””„ŽŽÇ2aåçç#!!{÷îåø¹jkkÃÝÝ+W®löJȹsç ªªŠ‰'6Yvݺu077'OÖÿÃÃÃ[[[„……¡G\¹¶mMzz: ÛUý|çÎXºt)455ö©ªªâðáÃð÷÷ÇÇÙvg´´´D||<üýý;åu¡P(M (5‡™3g"??/_¾$òoƘ1cšLD`kk‹£G¶¨~cccØÛÛãСCèÑ£¾|ùB·_SSk×®…»»;bbb0zôh†:Þ¼yƒµk×ÒÝÿÀm:LúàÁƒñáÃØ–››‹®«¦¦&Ο?5kÖ >>žíã¸8-##kkkZZݨ¨(¶Òåîܹ“­,;ß¿GNNÓj[³aà 4¨Ó?|666´¥Mn¢©© ZV qüøq®¦UnHÝQÓ››Šº¥ÏæºuëàììŒŠŠ òÕùM¹ÿ>KW„ŸË0 URRBff&ÃviiiÚÊZïÞ½‘‘‘AÛ÷ñãGôïßúúú „Ëv‚îÓÒÒ˜jãTVVbÕªU´ïsII ’’’ÈE%ßY±bþûï?¶º®´´4®¨JÿŒ¶¶6Î;sss¶www®ùs7¨P7ôßåË—ÙÒ?‘’’b)Æö3IIIˆg[—„Ð8Ó¦MCff&ÆÇõ¶øùù!,,ÌYíĉ°³³CÏž=9ÞfŸ>}––†¢¢"ü÷ß6aÀ¯bœÅÅÅàãããxR€+V 22²YéÆ#""’’‚9sæ¦óôéÓFWµQYY‰²²2ˆˆˆ4ZWYYS= ºT¼?ǰzÏ{{{cæÌ™ÄÎ;abbEEE|þü™V¦¾¾555èÓ§>þŒ›7o2uù«¯¯Ç“'OðáÃDDDàÈ‘# ±ƒ “ÐîHDD( ( KW+IIÉf)s³ÂÅÅ¥M²5 0çÎÃêÕ«›tÇ***‚ˆˆG²r:?rrrgêÑÄÄÄàÙ³gعs'xy9ÿàFf»¶ 66ÁÁÁ7Êøøø°eË>|˜muô¢¢"”——£GäéÀ|ûö­Q/øøø°Ôü••¥e¹ªªª‚€€@“mÆÇÇcÀ€Íš€eË–ÁÃö½ººÅÅÅX´h®]»†^½zACCƒa"°¨¨ëׯ‡»»;¾~ýÊàêüPC>xð íX{{{¦)†ýÆsâ›O ˆÂ]]]P©TP©T¦ê¯زeK«Ý!››Ë ŠÂ-H LÿUõögœajj uuu®ŸÓ»wïPQQÑhp$¡ýñóók“055Å£Gh.vvv]"qk‘””„±±1|||¸ÞÖºuëÔ,} Bû‘‘‘Þ½{s¤®ÌÌL())1Ý'""‚²²2?&êtuuʨªª"%%¥Ñ6†ŠÈÈÈŸ£»»;–.]Š-[¶àÀtû8€Í›7£W¯^¸téììì˜Öáàà€Ã‡ãÍ›7ÈÏÏgÈ0üÐÇip‘ úuëÈÍF ¤k|4òóóÛ4F@[[—.]Š+˜®„TVVâõë×QeoŒ}ûöÁÍÍ ~~~¨¬¬„––V“Çèééa„ 8xð`£åZ«ÊNh_ŒñêÕ+TWWÃ××_¿~ÅÊ•+¹Ö^ß¾}! €3gÎ`ÿþý\QyçâââÐÕÕ¥ ÛÙÙq4ýW¨T* òå§N¢­²×ÔÔ´º¾þýûw˜ÔÑ¿ºN1CSS“¥h!§°³³Ã’%KЯ_?$$$0솰°0‚‚‚XŠ«ÊÉÉÑ´q™–™7oÜÝÝi»¹¹1hpÅÅÅ1ÕG!ÄiÑ ÿëׯMªÔ²"-- ÀéÓ§ÛåÜqöìY†}åååðóók÷t«­¡!í#¡óãèèÈÕÀsàÇÊ ×ÛélÌš5 åååxüø1[×iÇŽ¤ÓØÄÒÒ’¶ÊÎ W׎ú¾vuuÅš5k˜îSRRBVVêëëQUUÅ45ïÏÄÆÆ6{²ŽU¿\¹rË–-ƒ––DEEannŽàà`º2999PPP€¶¶6Þ½{‡ÏŸ?3uw,((ÀË—/‘œœŒcÇŽáÊ•+ eBCCaeeà‡+™——Só9qWá75@fÍš…˜˜˜&—šYáîî%%%Œ?¾]ÎèСàååÅîÝ»éÄžÒÒÒ ¬¬Ü&~šš rwhˆ‰‰áÏ?ÿÄ„  ¥¥…I“&q½M <|ø°ÓôѳgÏÀÃÃÃU·8lݺçÎk²laa![‰$ͧ)1Xv‘`HîÀ-.\OOOC\\œi}}}„……¡¶¶ÅÅÅLï111”––®^½Š%K–Ð xyÑ­[7šˆbEEE“† ð¿Àø9sæÀÂÂâââ Yßbcc¡££ƒÅ‹cõêÕXµjFŒÁµrРAؾ};<==QPP€E‹1mSSS¡¡¡øôé( ÊËËéögdd`ãÆHMMEYYž?Ž‹/Ò•©©©ašaŒ@ üFÀ˜•†]ŠŠŠpîÜ9lÚ´©ÝÎ]DD‡FFF¨T*íîââsss¦ÙM8ÍÔ©SqíÚµfe“’’Baa!êëë™î///G}}}“\>>>ôêÕ êêêØºu+$%%¹Þæ”)SpíÚ5¶‰Ú333Ü¿ àáái4 ˜S-=zôÀ7ÈÙNp*IÉ AƒÓ&çܳgOdgg£®®®U“Yýû÷LJðõëW¦.füüü£}‡Yů,^¼ׯ_oÑ9 ãüùóÐÔÔ„´´4Ý7ÿÅ‹7nTTTPVV†ùóçCRR’f45P]] %%%|ýú.\À_ýÅÐÎùóçqüøqÜ¿IIIpwwg06Š‹‹±páBšb|tt4Sí–‹/¢¨¨ˆö7 ž'º˜Ò’¼üÕÕÕ˜:u*Ž?Þ¬Ì Ü€ŸŸçÏŸÇž={˜˜ˆ/_¾ &&“'On“ö'L˜€‘#G6»Ï÷ïßÏÒoº!x¹3»¬ZµªM!?t ?~Œþýûwè~2d>}ú„7n´™›!…BáZJnB×¥®®¹¹¹MƦ°£9RZZ QQQ–ß‘gÏž5z¼ŽŽN“ÙŒŒXjr 0€iƯÔÔT¨ªªøá†8pà@,\¸Á`ÿôéV¯^›7o6š)NUUÉÉÉxóæ V¯^Ír²¤!ðÞÎΩ©© eüýýqâÄ ÚßÌÆ)ÞÞÞä&%:«Òž={†êêj¦ùËÛ ???˜››#<<‰‰‰,S0r555–WšKdd$8@fk»FFFêp]]]Ú¬bGGOObbbm–hAMM W¯^Å„ h~æýû÷ÐÒÒ"qW€Ž˜œ#00eŠï†Æ>|8ÂÂÂüî·´´l´üóçÏ™º>ÿºBôàÁL:•£¿õêÕ«pppÀ?ÿüƒ]»v1-3iÒ$;v zzz¨««£y'üŒŒŒ ®\¹‚iÓ¦1­CVV¥¥¥(//ÇéÓ§‘˜˜ÈPæØ±c4#'::ýõüýýéÊ$%%—/¡# ³gÏFii)ƒÈ+RRR°lÙ2øùù±œÍi áää;;»6 ÄUWWÇ—/_82˃uëÖáÊ•+PSS#O ¡Ëbbb‚ñãÇsÝýêgæÎ ¦ºHáááÈÊÊ"¦ÐÔʰ¹¹9²³³1lØ0®ŸËφCcááá¦ÿF…—/_r¼Þêêjððð€ŸŸãÆÃ“'O ,,ŒÚÚZZ:r8~ü8lll ''‡ääd˜››ãýû÷tu5è®èèèÀÛÛuuuL¿±ÚÚÚ°±±ÁÉ“'Y®þÆÅÅaçÎHOO§MF4ü¿ÄÄDxyyáÛ·o´mÌ‚éI€= DDDuuu Ák¬ R©077oŸöæ2vìXܽ{K—.m³6'OžŒýû÷7ë,[¶ŒnÙ9""k×®ÅÕ«Wѯ_?ò¤º4222øòåK›Þë<<<°¶¶Æ‘#GØÊŠEh[DEEѽ{÷V×#&&†šššFmll`dd„Å‹·ª­ÕuN ©©‰7oÞ°ü¶ @XX………ÈÏχ´´4CeeeÚà:77òòò e„„„ØþÞ7™™ eeåFË”––‚——BBBbé¶VTT Ìš5 ööög ­®®†€€-ZWWWÌœ9S¦L¯¯/]9~~~ôïß_¾|///455™¶ihhˆGáÔ©S˜9s&ƒû³¯¯/âããŒêêj¸ºº2ÏÀ´iÓh¢ß¾}õk×Êüûï¿,ã; b€ü‚™™]pV#>>ž¥_gG@KK‹éK—›47À’ŸŸ½zõ¢)WWUUÁÉÉ Ë—/Gß¾}ÉSBèòLŸ>»wïnóvqþüyP©T<}ú”\ˆöîn‹lq ïì¦)ièÞ½;rss9Öæ£G`bbÒ¨„¡C‡2<ðò‚——ÕÕÕf{(,,LËLÕ˜ûÕĉi÷zzz“Æ« s%%¥»7)((°•(æÅ‹PVV†œœÝ Exx8† ~~~,X° Æ ÃÛ·o™wñññÈÌÌdù½633Û7oúúzðò2×tuuq÷î]À¹sç˜ ?¦¦¦âòåË´oû™3gÊ€z1@þŸ!C†°µ´hmm [[[2Hæ0{ö윜Q¨%ü6hhh´I–:fôîÝ.\À?ÿüCÓM º;„_Ayy9f̘Á‘úÛ,!ES¨©©ÑÒï2]ua'vEBB‚.S3LLLðèÑ#Žÿ†ÏŸ?CQQÀ}^^^¦’IIIèÛ·/þøãÌž=ãÆcê† üpï311ÁÚµk™îWWWGBBÒÓÓÕOKKKCAA"""àääİŸB¡ÐÔí£¢¢@¡PÆ`)))tñ<‘‘‘ ®cB§7@ØÁÃÃÒÒÒMfú °Ç¨Q£ƒ?ÿüåååLgIwPRR‚»»;&L˜èÁÍ„ö…‡‡cÆŒù?öÞ;*ªë{ÿ(Ò»€ CW,@¢XcˆˆQl ¶¨±Ž5ï(ÆöÑhÁM@QK°× J¤ *zGPz‡ùýá—ûsœÂÌÐñ¼Ör-¹sî9÷žÛÎ>gïgs-ó¥Š' €ÔÔÔN9æ}ûöaçÎxñâßI¿DGG™™™”{;—6###ž”¹"""pNĸcǦº¯¯/œœœ˜Ê¨¨¨$²Ñ"klmm‘#GÂÔÔ LeÊËË!//‘#GR«:::LnÒ[¶lÁáÇaii‰ÿû¿ÿÃüùó)™ærss¡¡¡‰'"44ppp`9&Œ?¡¡¡ ÅÈ‘#Y2Ýçååa×®]ˆœ:uŠrÿúGGG¦}:N\‚`Huu5ËÈŽˆˆ\¾|¹]jôèÑ000`놇   œ:u îîîä ¶Ó§OGdd$TTTØÎ„ŽE[[ÄâÅ‹»½t± ÄÄÄ ((AAATò¾úúzµÝR...®[“µµu§—󃉉I«ex¨Ïš5 OŸ>¥fõ;ƒ#GŽ`Æ lëׯ P[[ ƒÁ69âèÑ£Õj]톆F‡ E”””@II‰çãpqq©©)Ç2ãÇÇË—/¡©©‰åË—3%B-))Aß¾}agg‡@\\Æ CII Ûzžpþyòä öìÙqqqÒB'#**Šõë×càÀøî»ï8°öDRSS†'N ººgÏžFCJJ bbbØîûe¹×¯_³õ©ï*$%%»Ýû²½òËHIIAGG‡«åììŒyóæÁÚÚšó CXBBB\¥áµµµ‘––†òòr¶Áì-†UAAA««-‰u[‚Ë9µ—™™‰[·n±•ÝEss3š››9Æ·ðj„|+Â^\Ç8annssóVË=S¦L¬¬,5|Χb``044ÄO?ý„AƒáÍ›7Lû?~üŽŽŽ(((ÀÕ«WáææF¹Œ¶ðáÃL™2‰‰‰8~ü8 ---&×¹¼¼<¨¨¨àÞ½{øøñ#Î;‡ÊÊJ–q£ŸŸþüóOTUU!'''Nd9§ÌÌLäææRAüµµµ(,,d*SSSòÐM¾yÜ~ Â?üЪ¬ß7¨ÕˆððpSÁt¥¥¥¨¬¬d*_YY‰ææf®Áb˜0aîÞ½ Lš4‰å$ZÚí Fk× G Ø2!!Ÿ>}âê×Ý™ˆ‹‹CEEEàýkjj '' TUUáâÅ‹HMM…„„,,,`aa:Ž‘#G²ìûîÝ;HII1•ûrPœ››ËVå§  €í,yWPYYÉõ{Å`0àîîŽêêj®åZ«òóóñéÓ'®åŠŠŠ`ccÓj]¼´Ûê÷¼¶¶VVV\ËdeeAUUeee(++c[fäÈ‘X¸p!vïÞͱ.===øøø@FF†c™ÚÚZ¤§§#-- uuulË#55ïß¿‡„„Û2?üðŽ=Š5kÖ ** ?ýôK9SSS\¸p³fÍBXXLLLXÊhjjâÁƒ”!Á®ßˆùóçøÊÊʨú‹ŠŠPRR‚œœŒ7Žê¯!33MMM;v,„„„P[[ËR&::S§N…žž^½z…5kÖàßÿEjj*ddd|Î+3gΤ¦¦ÂÇÇÒÒÒhjjÂË—/)Õ¹ÆÆFÄÇÇÃÖÖGލ¨(lmmáííÍd0þþûïxþü9æÎ‹Å‹#-- Û¶mCPPÓäÇöíÛ™¶±#88˜$[î$úöí III1þß›ÛËˋɿp×®]——GVV®^½Êu)“N§SÈáDZpáBÊ año¼zõ*Ç +@ t/¬¬¬x– .((À¡C‡¨¿‡ ‚™3gÂÓÓUUU‘‘Avv6èt:bcc±xñb–ïÈ—$&&"11‘òÁÿºœ——ššš˜öÙºu+‹´)@ º*‰Ñ ™™™ ®e6nÜHýÿСCŒ¼¼</œ?žñüùs† |Ù&¯TVV2vìØÑiíµe¿›7o2>|Ø#ŽuóæÍŒ¦¦¦Nk/,,Œqåʾ÷ó÷÷gÄÄÄtZßTUU1~ûí·N½ÉÉÉŒ3gÎð½ß­[·zÌý¶eËFccc§µθ|ù2ßû]¸p¡Sï7ƒÁØ·o£¸¸˜ÑÝÙ¸q#ãÅ‹Œ¿ÿþ»ÕsNHH`øúúòÕ7‚ö_GÕÄos=MMMŒÍ›7w«sóõõeÄÇÇ·K]{öìa|úô©Íõ$%% ôìÈ~Ú¾};£®®®ÍõDGG3.^¼Ø.ÇȈŒŒls=Œ-[¶t«þþçŸ m®§¼¼œ±k×®v9¦/^0Ξ=Û­úiÛ¶mŒúúú6×Åàk®.X=ÂÛ·o‘˜˜ˆ   LŸ>’’’ÈÍÍÅØ±c©“E‹ÁÛÛŠŠŠÐÐÐèô¼@èÞÄÄÄ ##………X¹r%tuu)Q‘ÂÂB&ÙïÇããÇ8pà†Š„„ªÜêÕ«IgBGä÷ßÿÓÕÕÕPRRÂðáÃ!'' ˆˆˆ@\\–––TP™ºº:äää &&kkk¶ sØÑ¿¨««sÍˉ{÷îáÇäkQQQ”5}ðàÁPPPè´ýTTT ¡¡!³ }Ó–c4h $$Ô)í)**BKK‹ï¼ IIIèÛ·¯@ª.‚«ˆˆH§ßo222ÐÑÑ´´4_û½{÷¢¢¢ÐÓÓëöφA§ÞoÙÙÙ¨¬¬ÄСCùÚO]]jjj½ß=V}}}ôíÛ—çwpgR[[ ˜™™aÀ€‘‘*++©m-hiiÁÔÔŠŠŠ,åxÉû$è;°½®Ã×ôë×ýû÷o—€õ–÷mw9·ÄÄDôë×jjjm®K__JJJm¾}vd?@QQ‘ï÷Ö×äååáÓ§O022jó1©©©A]]½Í÷¥P·»/544 ¦¦†>}ú´©žúúzDFF² ‚çYYÙ^{_*((@[[RRR¼É¹ýÈéÇèÑ£YN‚_ZŽ: aaáV3¬r‚ßìâmÝ“HGÒÙç(è~²²²=¢oºâ~“’’âëð-Ý7‚î'(my¿ z¬Ýv¶K__ŸÅx………KÙ¯ŸNåºë½ý5}ûöm—z„„„Úí˜:ûyànJY]õl¯~ÒÒÒêvýÝ›ï˶ˆft½ù¾”‘‘¡„x…ë HwFBB::: ¾á•>}ú _¿~|?$ߢ¢¢PVVhµ¦·#""%%¥vûXÈ;°·½WÕÔÔÚeV—ÀÛûHQQ±Ó'p¿U„„„ %%%ðd"Kß2Øév#¢££Ž pŒ-illÄÑ£G|ž9›={6¹²oòòòPUU…r,sêÔ)TUUQ§ŽLvFàNxx8¢££áââÂÕ!,, 111X²d 1² „o”—/_âþýûÔßæææ3f ²²²påÊL™2ÆÆÆ>Ë_½z•í¶~ø« \FF®]»+++’ŽçdLwçØØX¤¦¦ÂÚÚ×®]ƒ††[÷›½{÷báÂ…044DAArssòe'ß.ÙÙÙØƒS;C IDAT½{7ddd¸Æ{ôïßC† ŽŽ=z„©S§’Îë"""PXX+++rô­GQQ¬¬¬péÒ%èéé‘ÙzáDZZzzz044DUU>}úÜ¿vvvˆŒŒ„¨¨(ªªªðàÁŽÛ""" **ÊvR<===‚ÂÃÃ!&&Ö-ÝÁºÂÝùàüýýáè膡C‡"66–m¹²²2*Ãî§OŸPSSC®,@à‹|Ö&ouuuÈËËÃÛÛ›ÊMAè|._¾ŒY³fF£A[[/_¾d[îÊ•+T9---¼zõŠtð 4 iii Ãܹs‚Ñ£GƒF£aÖ¬Y DHH,,,@£Ñ0sæL!$$cÆŒFƒ½½=ÇĆ=ÂØ±cA£Ñ`gg‡Ë—/“Žï‰¯ÌŸ?t:t:ãGˆ@à‡ˆˆ¬[·Že{AA,XÐ#Ρªª k׮ŋ/˜cë֭ömÛ(7"Âg–,YÂs|P]],,,põêUÒq+YYYX¾|9Ξ=K:£; |……1räH\ºt‰t1@ÚÆˆ#àîîwwwL›6\UB›yøð!n߾Ͳ]BBæææ\÷}÷î]·˜euttıcÇPXXHm[¼x1V¯^Må_ †²²2ˆG ZåÀX±bOÒ„ŽÇÒÒ3fÌ Ö]L·Žùþûï±gÏÄÇÇ£²²óæÍ£~SQQ••ÔÔÔÐØØOOODEE¡ººŽŽŽäÊ~#<þ ˆ‰‰¤¤$päÈDEEAOOMMM8yò$QSSƒsçÎAUU•*gbb‚ÀÀ@HKKCII ð×_!-- ©©©,« µµµHLL„¹¹9^½z…ÐÐP¨««ÃÇLJÚöý÷ߣ¤¤:::èׯNž<‰°°0¨©©AFF^^^GDDÔÔÔpæÌ477#((d+Ó÷ñãGœ={£FÂñãÇ¡¯¯ßªœßüùókkkèëëÃÕÕºººpqq™™æÍ›‡mÛ¶‘›èÿqúôi„„„ )) ééé”ìkDD,--±qãFÀ¡C‡¨¨(h}x‚`ƒˆ >>`ooÏ4Qàèè%%%Œ;–*',, ;;;Òy„NÃÃÞžžÐ×ׇƒƒþùç0 \¿~#FŒ@BB.^¼ˆôôt*ØÙÓÓ‘‘‘HOO‡žžŽ?ŽÚÚZ455Á××JJJPVVF||<‘‘cccÅ®]»`ff†K—.!""aaapuu…™™ððp¸ººRõþøã¨¯¯Ç°aÃ0lØ0\¸p‘‘‘ˆŒŒÄŽ;ÈCÀÑn}p¢¢Ø´iÊÊÊЯ_?¦ß©ÀÊwûër„ÞKss36mÚ„¦¦&A]]»ví‚¥¥%444°dÉœ8qIII(((À®]»ðÏ?ÿ@WWñññ Ó騫«CHHÜÝ݃իWƒF£aâĉ¸wïK›gΜÁŽ;°nÝ:¸ººâÍ›7HJJÂ… PSSƒ5kÖ@AA–––ÐÖÖÆŠ+ «« ssslܸsçÎN‡««+DEE‘ššŠ;vàüùóø÷߉ÀÀ@–vO:…={ö ¾¾xòä .]º„çÏŸ#==©ìˆ# ««Kn>™>}:¬­­Y¶1‚26`Íš5øøñ#´K"(‚`HKKcÆ ¨¨¨`I‚÷þý{j›ŒŒ ÇrBGcbbqqq888 22t:‹/FUUÆŒƒ•+WÂÛÛ>>>Æ;w0lØ0ÈÊÊâÈ‘#˜;w.Þ¾}‹ŒŒ }ÞÞÞhjj‘#GЯ_? 8AAA‘‘––V­Z\ºt Äëׯñöí[,[¶ çÏŸÿf$«GŽ ---444@HHˆÊ›´|ùr3å_c·mÅŠ,ÛàüùóL‚?ÿü3Ûr„d€Ÿ“αS¾ú2›µP»%0"ô„……akk‹û÷ïãÏ?ÿDqq1áïïØ·oâââ(¿~)))*+uË,èäÉ“aaa¥K—¢±±ÞÞÞ(,,¤\¨š››ñìÙ3€¼¼<ììì¨ ;;;xzzbÆ (**BYY¤¤¤Ð§O(++£OŸ>8}ú4V­Z…>@]]3fÌðy¶ÖÌÌ )))Ø»w/æÌ™ƒªª*\¼x‘í¹Î˜1{÷î…ƒƒäää(÷©àÆLeÿ÷¿ÿDÔÕÕÙncú­+’=Ø#//ÏVV÷ëï§rBG£  J(GYYÆ ƒ““¶oߎºº:øúú¢¾¾ ðóóƒnÞ¼ à󫬬,êêê ))Ie-?wîðÏ?ÿ ¡¡jjj˜8q"rrrðÇ &&555ðóóØ1c`llL­ˆüöÛoÐÑÑAZZú÷ïÏ’Xº7Ãn’ZBB‚åÁë6€5é!§r„f€­Ñ·o_ÈÈÈ ¸¸˜ï}µµµ‘’’Âñ÷ÆÆFÌ™30fÌìß¿Ÿéw99¹Vg9öíÛG¹wµÄ 2ãÔòûEEE–mœ$Fååå‘––†ÆÆF”––’Ù{@è¾Ìbmii wwwŸENøaüøñÔ¾p÷î]¨©©QF ·öáì쌕+W’ Bè„Iz -þÞ7nÜ@||}ŠÐÐPÊåÖÖÖaaaøôéŽ=Š„„¶mØÙÙáéÓ§(--…——ëÖ­Cff&LMMÉ… t Ý:@àFss3®\¹YYY 2ªªªprr©S§ðâÅ ¸¹¹AWWVVVxóæ ¤¥¥aff†¼¼<|üø¨­­ÅСCQ^^999lß¾ÿþû/’’’0hРʇ¶…k×®A[[MMMHLLDß¾}¡©© YYY¤§§ÃÒÒÖÖÖxñâÌÍͱ}ûv\¹r‘‘‘˜?>ÂÃÃA£ÑP[[ ###ãäÉ“èÛ·/~üñG,Y²UUUøã?°téR¦v[ŽCKK EEEÐÑÑÁ¨Q£X –äH'Nœ€‘‘DDD ¨¨ Lž<~~~055Å/¿üBn"@è@®]»QQQäç磹¹ÕÕÕ°°°€––†ŠS§NAFFsçÎ…³³3þþûo<|ø•••X¾|9~øá¼{÷bbb5j²²²àììŒ!C†ÀÛÛòòò˜4i?~ !!!Œ5 ÍÍÍÈÎΆ³³3L•kq?ÎÏÏGMM V­ZE.¡Kb0 Ò B×’’‚‘#G¢¢¢‚ÚvåÊœ>}wïÞ%D ߨáràÀDGG·k½555¸yó&nÞ¼‰-[¶ÀÈȈt6¡K .XBrÿþ}˜˜˜0C‡…ŸŸé@øF ƒ¼¼<%3Ý^TTTÀÃÃýû÷‡éhB—AV@@ B§AV@@ 1@@ 1@@ ¡ã gÏžµšÿ ¢¢îîîØ¼y3233I¯¡U^¿~ :ŽcÇŽ¡¦¦†c¹W¯^N§ãøñ㨭­%G ½ÙIHHÀÇ‘ŸŸÏµ’Ó§Ocîܹ8|ø0Î;‡ÒÒRÒ³@àHVVîß¿wwwL›6 gÏže[.33>„»»;¦NŠ3gÎÎ#„Ž(·ËÊʰhÑ"\½z•k%999ÐÐЈ‹‹£¦¦ >kY?}ú”eŸÉ“'cúôéä Â7HYYäååzzzHMMe[®´´”úžèëës,÷%[·nÅÖ­[¡¬¬L:š@ zš2aÂdeeµ©™3gbæÌ™LÛÖ®]‹°°0b€¡Ýñòò‚ºº:Ο?ØØXÒ!ÐÍ(½ºº—/_¦þ¦ÑhÈÍ̓Á@]]$%%IÏ#òòò(++¤¥¥A__Ÿú-99™2(·ÞÔÔT¦rÜðññÁˆ#H\"@ ô4ÄÓÓ‡Btt4èt:õ±(//Ç‘#G¨rË—/Ç¥K—°eË,Z´ˆZ.'ZZZ°²²NÇíÛ·±dÉê·ˆˆ&¹Üƒ‚Á``È!زe _mìß¿ÂÂÂ4hÓ¾gÏžEff&F…õëפ3 ‚……h4€ÏZÈK–,——W‡´÷îÝ;ôë×rrr˜5k233ùš=}ÿþ=‹õÚÑÑÑhhhÀرc™¶‹‰‰aëÖ­°··ÇüÑ.FW}}=¶oߎ¸¸8¸¸¸àåË—~ ããã‹¥K—¢¢¢MMMÕ3kÖ,ÄÅűèc³ãÀظq#tuuѧOdgg÷ºg#33ZZZ°··ï4‰êX[[w[·¯û÷ïCRRãÇ'/O@ ´™iÓ¦aöìÙÔßk×®…³³3FŒÁ¤XVV†iÓ¦aÔ¨Q‘‘᫲²2¬^½Ó¦Mƒššµ½¢¢Ë–-ÃØ±c1tèPb€t%""" Óé¸páß}^ðòòºuëýúõCMM ÊËËyÚ7-- öööøóÏ?ÛU¦rÍš5 BAAA›ê)**¾}ûPUU…`æÌ™-òKvv6ÄÄÄ ¦¦yyy”••ñ¼¯¯¯/“⃓“|}}¹îS^^ŽÂÂB 8ÚÚÚ°²²ÂéÓ§{ݳðå½ÚY¤¥¥¡¦¦îîî×QRR‚œœ–•••m>¾÷ïßCII JJJÔ6ggg’C¨øñÇqïÞ=Ò¡W£­­²²2 _¿~Ôöùóçã—_~‹‹ Œ»ü8;͉‹‹NNGXXX¯¾ø†††ÈÎÎæÙ0h 3fÌà9xÚ×× À‘#GÐÜÜÜ®Çagg×&w°ÄÄDØÛÛCKK Gð9°»3Ü“öìÙWWWˆ‰‰aûöí|µÙ"@Ђ©©i«.@^^^°²²ÂàÁƒ¿‰—¡ ¢¢¢vmäZ ↕:ŽiÓ¦!((ˆéß©S§`kk‹7n´Ëñ}‰‰‰ që @å !„ÞJee%Ž9‚¿ÿþ›i¥ÃØØ<À„ 0kÖ¬.?ÎNK6l† àóòPWÐÐÐ;;;ãöíÛPVVnS}åå娽{7ÛswwwÐétܹs§ÝŽÿæÍ›øøñ#œœœ¨m&L`Ðp"44ŽŽŽÈËËChh(ϺС¡¡˜0a×2&L@hh¨@×6..«V­B`` ´µµ;õžHIIAŸ>} ¯¯ß.õ :µµµHKKƒžžÛ{0""sæÌ¡¶¹¹¹AVVt: ½â˜ššŠúúz 2ÇGrr2JKKÑ·oßn{̧OŸ†œœž={ÆöwƒM›6áСCX³f æÎK¾t@èRÂÃÃñèÑ#äää`åÊ•ø¿ÿû?`îܹøã?###””” $$«W¯æû[}:®]»†œœ*Ʀ½‰…¸¸x»e01bªªªðúõk¶HË=ø¥¿foäåË—¨­­ÅðáÃ;½mSSSL™2oß¾…Ïû]¿~AAA‚»»;òóóqìØ1øúúbÉ’%<_Ë“'OÂÒÒ’eé{æÌ™8räîß¿+++ò5%ÏáÈ‘#ìß¿ÕÕÕppp€ššäää --þýûÃÈÈH ‰N[[[˜™™QmTVVBLL ²²² DSS“k1/tëôôô6¥ÿ’šš¸¹¹aÆ 055Å™3g:4a ´´4h4ß²dÜðóócZý€áÇCZZOž<áºoJJ ´´´ %%Õ!ç+##ƒ††¾Ñ‹ŠŠ`mmÀÀ@¶ƒu)))¤§§sœ‘n¾ŽSÐÐÐ@ii)ªªªZÝ÷Ç…¢¢"ÓöuëÖq!ðóóÃO?ýÄ´,*))‰åË—÷ºŒØ_”±²ˆ!C†`Ĉ¨­­åË]* ÆÆÆ<¢êêêØ¿?Ž9‚çÏŸÃÑѱU!ƒääd 4bbb,÷9ƒÁ@MM ù’v0ffflûRRRz­6@èÝÈË˃F£F£A\\JJJÔߢ¢¢PQQ””äååÛäeñe}ûö¥’.«««ƒF£ñ=¾ì¶Hcc#vïÞü±]b)²²²pïÞ=¬X±666øôé"""ÚT§¯¯/ ))Éö÷­[·âøñã< f[£²²¢¢¢l3;99µjL}9ÐVPP@UUÏè’’’|À… X,6 èëë läää 22\ËijjÂÜÜ—/_¸²³³1cÆ hiiq,£££ƒ¬¬,¶ù=JKKY¸J³«›W´µµyÊÎ. žÓõïéV???ØÙÙA^^ž­ÑÈK¼‚ŸŸS¯g¬­­©åÈ7n@\\S¦LáXŸ‚‚B‡ #t•••,3Ð?þø#²³³ÛlˆsƒÝ}Î PWWg ç—ÁƒãäÉ“pqqazŠŠŠðàÁ,X°€ã¾fffÐÓÓÕ+Wºäšµ ¸»»³õíý¦¦&I I z.\ÀÎ;ahhˆ5kÖÀÙÙMMMXºt)UæÖ­[8yò$~øá¤¥¥ñ\wyy9èt:®]»Öû W¯^!''?þø#5 l-»4·‹¢££ƒ1cưüÆÏ ¼-899!00µµµíïíí ¶³õ_žË_ý…úúz–óŸ|@uu5äåå‘›› ¾&Üäääàî3g¢¦¦EEE())AEE*++QRR‚úúzäåå¡´´”ç‰Ôni€|øðeee” /Ù¥9±gÏìܹ“íoªªª6lîÞ½Û¡çcbb‚—/_ò¬:õ%ÕÕÕxøð¡ÀÁØIIIÐÓÓãKÝçK:"p8;; ƒg¿ëêêj·–¶PYY‰ÔÔT–| íÍŒ3ððáC„††BFF¦Uw=ÔÖÖ"??¿G¿ yèh$%%a``Ð%ï¿ÿþ;rrràããà³ $§wPw EÁÐЮ®®\-z•••––&#ÐcÑÒÒBzz:^½z999DGGCOOÊÃõøñcdffbûöí¸~ý:ddd0zôhÚÊÍÍÅ»wïP__7oÞàÝ»wˆˆˆÀÇñôéS())ñ<‰*Ü:wÈ!¨¯¯çkÉöïß[[[Žƒ!%%% †††¨ªªâiu´§³}ûvÇs¶´5bĘ™™ÁÖÖjjjÔö‰'ö\äëàÞáÇ£¦¦/_¾äkà~øðáVƒR]]]áééÙáœM›6!88ïß¿çk¿½{÷bË–-sp#11ÆÆÆf½Ì–––ÈÏÏçjÔ½xñúúú|'—imöûúõë|­è˜šš¶›[Ò‡PZZŠp-—ššÊõ~{øð! ŽeÄÄÄ@§Ó!&&öͨ_ýñǘ;w._qC/«0eee mÓ ™«W¯ÆÖ­[1yòd*Йí!Å{ôèQhjjââÅ‹<ïLÿ¨Q£P^^Ž×¯_÷Ú{T[[›«¹’’>~üȲ=77—äq!„v¢[ ì‚{yYh!##222PVVæZNMM sçÎEzzz‡ž“œœTUUù6@JKK!//!!¡VË®\¹7oÞ¤V5|}}1þ|ŽyJZÃßßVVV|ûÆ;99áèÑ£l%P`hhÈSÆé/ëk¯ÀлwïBHHS§Ní”{yÖ¬Y äÙ%iÔ¨QPWWï±9!ÊÊÊ --ÍQ…¨3Y´hQXXØ%íÛØØÀÃãMùAø¡®®‡ÆÏ?ÿŒ¿þú Ÿ>}juŸ˜˜äåå1M¬_¿¾Sb㺠KKK<}ú”¯}‚‚‚pîÜ9ôïß< #ÐmÈÊÊ‚››rrrPUUOOOÐétlݺµµµ¸ÿ>œœœ0{öl¦1h||<1þ|DFFòÔÖÇñóÏ?cÁ‚ÈËËÃìÙ³A§Ó±bÅ <|ø*wýúuÐét,\¸£[¹pOé`~ÆqàÀ¬_¿rrr\˶d¡þã?xVÚª­­…²²2&OžÜaç|NÆ‹Y³fñT^KK õõõ(((@zz:aooϱ¼ ŠA¼ ""‚?² DJIIF([u[©®®ÆÑ£G±mÛ¶VËv•"•¼¼<ÄÅÅ»lÐÜš››QQQÁñ¾9r$$%%ùüµFKöUvíæç磮®Ž«ßQÏðYDAII‰§²ýúõÃäÉ“qáÂû?;;«V­BYYO®¥eee¨««c Ä4hõ!#|æÅ‹?~<¬­­{|Œ@è]”••!%%…RŒµ··‡»»;JJJPXXˆ€€ìÛ·»ví±cǨý|||ðûï¿cÏž=øçŸxjëÙ³g9r$.\H)o¹»»cÈ!4hUN[[îîî°µµÅ7z† qqq \GZZ®\¹‚-[¶ðT~ýúõ¸wïÏY¨ŸOžöíÛt:óçχ¶¶6 ¥¥Åâ’ßÐЀ¼¼<p¨ûkkk,[¶Œ’š711Á‹/ ¨¨È”|ØÄÄGEAAV¬XÑ5ȵkרì´-ÿÂÂÂ8–OII˜˜K¶‰'bÈ!8yòd«m ’qº3@ajjŠsçÎñT¾-™³y ’çtÎUUUˆ‰‰i×àÜÐÐP˜™™ñ½ú¡¥¥…µk×bóæÍµÛÜÜ [[[|ÿý÷íà][[‹ß~ûg~a—E@ú’—çËÜÜ<¿Ï8 B¸¹¹õêÌìEEEPTTd+E¹víZ&#ùéÓ§L" øóÏ?ÉÃE ºý7›'‡››nÞ¼ WWW®YÌ«ªªàááÇ P^^Nɸ åääpLîÚáÈÌ™3©ì´-ÿx È”ððp¤¥¥aáÂ…|í× ¼ÀëÌd‹ë¿Á¼NNNx÷îRRR ­­-ðqVTT $$D`ùß;vàìÙ³ÈËË£¶]¿~&LèP—v΢E‹`ccÔ§;3`À888ð%ºÐh=à–G¡³åyy}Þº &&&HIIáy6ª…ÊÊJdffR±UcÇŽ…®®.Ο?ÏqŸÀÀ@¨¨¨`Ò¤I,¿ÉÉÉ!>>¾Ç݃텹¹9¢££|N":}útê·åË—£¸¸˜ÊóB Ý…ÒÒRü÷ßpwwGAAJJJPZZЬ¬,$%%1%«–••…‹‹ –,Y´zñ5ppp€©©)rssqíÚ5,[¶Œ’áeñºuëæÏŸI“&qœÌêv.XÝëÖ­£2örâðáÃX½z5ßy/lllPRRÂS ާ§§Àj(PRR­[·8–),,ÄÊ•+±aþW dddàïï{÷îaܸq\ËŽ7Dqqq»_G¦ŒØ>|ÀÅ‹;UE¦¼¼7n„™™V®\ÉW‚1yyù.K ×§Oˆˆˆ 00°Û<—ÙÙÙ­Ê`ûùùaÞ¼y\Eœ;$ÀYc;99ÉÉÉpttì6ýìää„ÿý—oU¾üü|<~ü˜:qqq 0€«Q]] ===¶ N5440vìØnuv&bbb@b|„nÃíÛ·wwwdffâñãÇ ÓéPPP€††±cÇìÞ½kÖ¬Áþýû‘šš ÄÆÆbÁ‚\…cDDD@£Ñ   €wïÞ!..»víBll,âãã1sæLªìõë×ñï¿ÿâÇؾ};.\¸€yóæ±­W´»u¤——îܹÃö7Ê¡¡())á9hûKTUU!--ŒŒŒV3tgff ,3ª  ®‰õþùçÈÊÊâ§Ÿ~¨ ^rŸå&óòòpÿþ}ÌŸ?¿CS~~~رcêë둟Ÿ/𪌳³3ñÛo¿AQQ±ÕòÕÕÕØ¼y3ôõõrÝ233ƒ®®.®^½ŠÕ«W³Ì0ÈÉɱ•7nϾûù矱mÛ6¾eÛ›ææf>|ááá8þ<_1Iœ&Ú???¬Y³†íõ‘‘A}}=êëëYÜm***PQQuuõÿòõõeQ\·nÌÌÌpàÀŽûp3»Ó=È 'Nœ ^IúÊŽ–gdG'Ý•iÓ¦aÚ´iÔß_»‡[YYÁÊÊŠúû·ß~–P^˜8q"×<_JÚ/^¼˜k]Â=©“•••1jÔ(ܾ}›£ñâàà ð€¢%€»£á–møÎ;¸}û6Ž=Ú¥}ŒéÓ§·imbbBe¢nÉ5À‹œ0§ºÞ¾}‹ššžÊ/Y²ƒ âIñŠ_öìÙƒ5kÖð¬n$èù¾zõ õõõ]þÜ}úô GÅñãÇáââÂVJ:77)))øþûï;ýø¸e;_¶lðüùóñŽ… ßî ì²Ï«¨¨`Ĉ'tZËßròªØÕ¬^½šróm/èÚÚZˆ‹‹³¼·¸)»¡uº•mmmŽy'`hhÈ6ˆ=::ÙÙÙ˜={¶ÀíÿðÃÐÑÑÁéÓ§9–INN†ŒŒL›â+ŒaooÏbìÔÖÖÂÃÃwîÜái–¿#yòä Æ×&dذa(((@^^^§f?þü9ÒÒÒ0gΜû`Љ‰Á¢[PoÚ´ ûöíÃèÑ£±cÇ888°”)**BFFSöUv¨ªªB[[111Ýâ¼:JH@PDDD`iiÉWxvv6>}ú„ï¾ûŽi»¢¢"† ÂVŽwß¾}°³³ƒ±±1Çzeee±{÷îË^ß“?~<˳ùäÉÄÅÅañâÅ|/^ìðãnllÄË—/1dÈ®JLm¡  ?ÆÊ•+;ü|h4îÞ½ÛªúTGRZZÊò\ 8§Nœ9sðáÃÊPáÕ-QAAeee`0m>¾ÊÊJ”””p-£­­ÍlÝ¢vךàDW°hÑ"DGG³,gs‚›ñ',, CCC¤¤¤P±üŠ(üúë¯ß\RBIIIÔÔÔ 77—ãªºŠŠ uÿ755AXX˜2¥¤¤ˆB :††øúúböìÙ”±a``)))„„„0 ýû÷‡®\¹ÂÕijjBNNJKK¡¤¤qqq\ºt ¶¶¶8~ü8DDD°mÛ6&×ÓI“&áøñã¸uënÞ¼Ù½ –´ñ_vÚÁƒ[ÍJ,""cccÊm(==AAAغuk»›´´4¬­­Ùº™´Wæd111Ðétüý÷ߨ¹s'|||VÖjë wàÀL.1Ÿ>}BQQQ»¸µÐh4888tÊŠANNüüü(…‡Ž ²²©©©v}:+? 'öîÝËö~Ÿ4i&NœÈ5y'\]]qàÀ. nÎÉÉ¡îÏÞκuëðàÁ¼~ýšz‡ñ3a3wî\øûû÷šþÐÔÔDvv6×2S§NÅÝ»w[ýN´………PQQ¡Œ:[[Û6¹œ‚ $''#%%§NBhh(Š‹‹‘™™ Œ?ž)HJJ °páB®+îµµµ BBB€ÏJ­«V­Â Aƒ0|øp¬X±»víby¯*))ÁËË oß¾e[¯hOìàQ£FáÎ;øðáètºÀÙÂ[$)**bãÆTr¯öf̘1]ŒÛ¯_?hii!&&“'OîÖ×}Ó¦MÐÐÐ@tt4Û`ç¶dŽg‡¼¼<ŒŒŒÖ¡É3¹1aÂ\ºt ÿûßÿ:½íôôtÔÔÔ`èСlß¿?¦N {{{”––bÑ¢EäíßN¸¹¹aÓ¦M­úùùAQQ‘)Q§û(44šššHII½½ý7Û·ªªª(**B¿~ýڭίEÔÔÔŸŸOndÐᄇ‡ãÑ£GÈÉÉÁÊ•+)åC:eee 2‡ˆˆΞ= +++Œ9¨¬¬„œœ×É–7®^½Š¤¤$äççCZZ‰‰‰puuÅÇqâÄ }¢–>y!55‘‘‘mÎÖÌK\‡••1vìXžëUTTÄ¢E‹Ú%#:»•¯‘””„“O¾ŸŸœœœºíý}пÿ¥LÕlÙ²'Nœ@ee%ÛßËËËQXXˆ´Z—ŠŠ \\\ ,,ŒeË–‘ÎmæÌ™C)À())±¬T©««³2á…¦¦&øûû#77— tgGzz:6oÞLd’ B£Û -€»k×®E]]µ BèZØåæˆGrrr‡¸âÙÙÙáÑ£GuÎ_'­äĹsç0|øpøøøÀËË ZZZðòò¬Y³@§Ó™òçp#22***íêÒÖ•|Ì mmí.}à lÙ²?ýôÛß;†É“'ÃÐЧú~ùåÄÆÆBOO¼Hº9¹¹¹(..ÆúõëqäÈŽýGÅüýû÷“N#ÄaGJJ <<<àáá„„lÛ¶ >Dll,ÒÒÒpòäÉ.ó³o;vÀ¿ÿþ{‡¼ÚÆ›7o ""ÂÓL0¿L˜0ÑÑѨ©©é²óÓÖÖ†¬¬,’““¹–ËÈÈÀ­[·˜|ÛqèÐ!Ü»wVVV˜>}:•<ˆ/^¼€‚‚´´´:äœÆ‡/^°¹}ÿþ=ÆŒƒQ£Fáùóçë¸zõ*àèèÈÓul Ž‹‹ƒºº:ÔÕÕ{„áTRRòÍæáèJž?Î5þ©£ˆˆˆÀo¿ý† 6`øðáÈËËcÐnnnKKK ARRR UN@è*:-]KK Ôà¦'1`À¸¹¹ANN®Í~ÃÝeee¬Zµ ‰‰‰())Ammm·UÉÑÔÔƒÁ@nn.444|Döôôìð¶###ñþýûNW{4hÅU‘íÍ›7(++ƒ¹¹9Ûß§NŠqãÆÁÅÅööö\U€Z”-: Ìš5 %%%L1ï߿NJ+àææEEEŒ=ÅÅÅ<'IêÏæ­[·0pà@dddP}uuu8tèWе¨©©¡¨¨ ƒïä²_æ`š1cÛ2#GŽ„µµ5„……1|øpìܹîîîŸçî,º@ ¾=:mDJJŠ \ù:h¼+üêù¡OŸ> ÓéX¶lÏÉ»z"""““ƒ¯¯/jjjÀ`0ºmœË˜1cÐØØˆgÏžòòò`bbÒ) åêêêÐÐÐÐa¢ÜÐÖÖn5f‚—˜ iiiLš4©Õ¾¾¾í’p“²²²°xñbìß¿Ð××ÇôéÓÛ%XýKøIšØPQQÁÖ­[±k×.j–›×Ä­ß'NœNN§âÙÚB[ãŸDDDÚ,S¦LÁ£G˜¶=|ø666””äj¤Ÿc…PPP@nðí ìprr‚ŸŸ_T]"tŸA‡‚‚B‡ÿ{gWÓöÿÿWsš“¤Ñ™"’!³›®©‘yªîU†:ru/áâ’é$”™Œ—B7ÄG¨¡ÙU¢:)•4+ û÷‡_çëÜN9Ny?ÎÚkØû½×^{½÷Zï÷[BB³gÏæñØö=X±bE­«ÄÊ•+¹ÛU ‚ HùÿTyû ý©ß—#FÀËË 5j”PŸ+›Í‹ÅÂÝ»wahhYYÙfi—ÅbոǺ©iÛ¶-ºw°0¾ÇW­ZU§sÓÓÓ›ÍÆ„ PVVÆMÏÉÉÁ–-[šå:û÷ïììlÌœ9¬Ñà·ê~7999ÂÀÀ E®ôêÕ §OŸ†™™Nœ8Ažš555ôìÙ³AuŒ9²Z”ô*–-[Ƶ‹¬âÕ«W|·JM›6'& ¿À¤:t¨V6##jjjèܹ3þý÷_¬Y³†n,A¤€XXX@FFéééBëëG¢_¿~-FìÖ­Øl6V®\ …&Ÿøedd‹£)ïO\\ÂP5AŸpÓ_¼x!P|œ”””:{¨300€¤¤$JJJš\.ß{Ř R@jEFFÄÆéNkÖ¬ÁŒ3„^ Ñ×ׇ––âãã1wîÜ&ooêÔ©xñâ*++¿ëu/X°¾¾¾<½+**‡^½zABB¢NõÉÊÊâÿûfÏžÍôìÝ»vvv––n–kRWWÿæ¶1999üúë¯Øµk7-##rrruZÉèÒ¥ nÞ¼)Ðþa¦]»v´¥FH’’8¶ðÅæãüù󀕕úöí‹û÷ïãüùóÜ<ü$èëë ä=òíÛ·ÜÿÏž=Ë3>.^¼òòòM´°²²©©©°¶¶&%™ áU@àĉÍîÖ”àÏôéÓñÇ4ùŠBC‘——‡­­-þ÷¿ÿ5[›JJJ066ÆÀ¿Ûu‹ˆˆ@AAg‘––___8::Ö«NmmmLš4 ‡BYY^¾|‰>}ú··3f -- <øøø GÐ×׸IIÉfñ–Füøüù3òòò_-ýë8ü$ÈËË£  PPPÀWñ666Æõë×yƆÿFgo(ÅÅÅÕV`ÿ«`͘1¦¦¦µFpÿøñ#Ž?N±K‚‚hY 6¬Y£tûûûcêÔ©þB¯ rrr`±XØ´i7mÓ¦M`±X òö믿"((W®\Á­[·„ÒC”¦¦&,,,°ÿ~êüD‹BYY¹¹¹xöìœk´ s}èÐ!üòË/|?&(++ø²QTTÔè¶N—.]Â?ÿüƒØØØjDz²²`aa={öÀÍÍ [·nE\\ßzÖ¯_¼¼<P!R@‚¨‰^½zU3ý :¯^½Â‡ðá䤤`Æ ªSOOëׯÇôéÓ…ÚÁÌ™3ñúõk ¾GßrØPµzáãã]]Ýj«¨‡æ®n¤§§7Èýµ¥¥%üüüPYY‰’’’j:~ûí7lß¾'mûöíðõõ¨þçÏŸãôéÓXµjUµc?~Ä‚ 0xð`HKKÃÑÑoÞ¼©–oÑ¢EPSSƒ““«¹&‚‚ „ŒñãÇ#** ¸yóföŸ×ÆØ±c‘ššŠÓ§O íµkkkcÚ´iðððÀŸþÙ¤î— B&L˜PÍutmTõÙââbn¬¯ãá|/._¾,ðjÄ©S§àææöͱBMM ™™™ÕÒ333Ѿ}{ÀÊ•+koD) A ;vDdd$Ž= ggçF©SZZZZZÍæÒ¸¾ØØØ ((òòòœøî´iÓF X,>|€ŠŠ ”””бcGîïº0sæL\¸peee””l”ógåååðòòBYYBCCùæûüù3\]]¡©© %%%ÈÊÊ¢°°'Ïû÷ïyJôíÛÑÑÑ|ǯªXS²²²µÚâ¬1iîö‚Z¨¨¨¨6ÐÔ4Àr8’(A41¿ÿþ;.\ˆÒÒRL™2出vØÛÛÃÞÞªªªÔZ999àp8àp8(//ðÅVÃáàãǵ–4Ÿ°Œ1cÆ@½m¬ÔÕÕñîÝ;äää ]»v|óHJJ¢´´gΜÁœ9søæÑÕÕERR€/vPVV†±±1îß¿_£ü·lÙ‚ùóçÄÅŹ÷° ???XXXÔz ÑÑÑ4h¢Ò¦M›j®KJJPPPOOOäçç7Xþ/^¼@DDD­ÊNZZ<==mU™ ˆ* ^^^8zôh­yÞ¼yƒC‡ÁÇÇW¯^%©Dbmm£GâìÙ³?äõ¯]»¿ýöddd¨3´ÒÓÓáåå___øúúâÌ™3€‹/Â××û÷ïç»]§Šªrû÷ï¯Õ»’0R[0¯¹{÷.FÝ ¶ŒŒŒލ¨¨=Ä)++s¹Í›7sÓUUUk”íõë×Áf³¹Î.:wîÌ×¾ã[dffVs»=fÌó¤…††bÊ”)PWWÇîÝ»|îÞ½‹C‡Õ¨”@= ®®^£FD3* 'OžDçοYɾ}ûðÇ€ÅbáåË—<. ‚h|æÏŸN:‘ ˆÁ‡ ©© '''899!** ÑÑÑ(..†““\]]áææÆ·ldd$JKK¹ù¶mÛÖ¢®}À€(,,äñ ÷_g»wïÆèÑ£k ÈYeÌ>räÈOÏž=ñòåKäååAYY#FŒàspp€§§gµ2÷ï߇““×nø²;¢Ê-vMüúë¯8tè÷7‹Åèß¾}‹ &ÀÞÞ""" Z•Ø¿?0iÒ$Ìž==â9^RR‚7"''?ÿü3ÂÃÃkôÞU¥ÌÑpÄ«þ â‰È:yòd˜››#??¿A…üüüªí+½ÿ>^¿~ýÃ~Á%‚hIŒ9Ràñ://Üß:t@ÇŽ‘ ___¼ÿ¾ÖÕŽº²fÍšj±)ÊËË1bĈ‹‹ …üòòòx&ú°lÙ²jùŒŒŒ &&Vk=ŠŠŠ°··¯5€Z=[åååaõêÕøôéNœ8Á#·’’’jÊ`^^^µúrssáííÍÅ/Oyy9JKK±eË_ìD,XÀè´´´ Ãð¤U]çþýû‘ŸŸ£GBDD¤^²OKKƒššÄÅÅÁ0 xb]U¹,>vì€/ÛÒvíÚUã kÕ¹Q?8€É“'ÿŸÒ¾}{ž¯bbbPRRjðþK ‹jûBß¼yƒŒŒ ¢cÇŽèÑ£GëÝ»wo÷Ò–””àÔ©S°³³k–öRîáÇ””¬“‡•ïu®û÷½}ƒ×Õ·½¨¨(äääÔy»B`` tttгgÏf‘Mii)Nž<Ù¬ýíÍ›7ˆÅäÉ“ëT.,, -¢¿yzzbéÒ¥ÍÖߢ££ñáÇ:÷·[·nA[[»ÙúðeÕÚ¢у‰ÖÅà_BBZZZúõë× z Ú(ç$''‡ÏŸ? •œüýý1dÈ+Æ¢¢¢““«Ó9‰mܸqcmL||<¤¥¥}}}HJJ¢¢¢YYYÜNÛ³gOÄÄÄàáÇ`±XkR’’’PSS«×׎›7oÂÔÔ´NeDDD ##mmí:·'--]¯=÷õ-'!!víÚÕk©·>²iè5vìØ±ÎKäõmO\\ÊÊÊuždEGGCEE¥^ÑÌës®"""hÓ¦ tttší^ˆ‰‰AQQ‘ëg¿.“qqqtéÒEèŸ )))têÔ©Ùú[jj* Ñ»wï:?Ãõß"mmm¡Ùzô5¡¡¡ ºº:LLL -- œ~üØàU‹Æì—Uï:aê—’’’èСCƒ]Ëþüaaa v!¬ýRJJª^ó·šæe5yèãÛo†aÐa±Xߌ@û£B²áϹsçê½ÒÚ¹~ý:¤¤¤Z>ýÑxøð!ÒÓÓ1mÚ4Ä8uêT£­€߿ɓ'xýú5¬­­IÍ@AAvïÞZ¾ÕõUZZê‰Ó`G²©+:::hÛ¶- ‚êêêBùÕ\PQQ©óv/‚ÆÀ…Ž;RPÐfDYY¹^»8ˆzN’ÅÅë¼úM†Ð¯€¤¥¥!%%úúú5.¥UVVâñãÇEEEê,AÔ‹‚‚|þü¹Öí}øüùó—TD¤Áû§‰ú“’’‚´´4ðxQªo>‚ Z/YYY<^]µ´´ ­­¼¼<ÄÅÅAWW—»=Š_Znn.âããyÒø!h¾Zm@¾7ÙÙÙ8{ö,DDDŽÞ½{ó5”ñööFII òóó qqq¨««ÓÝ%B`Š‹‹±~ýzTTTÔúãÙ³gÈÉÉÁÇqèÐ!Ú ñHKKÃ¥K—OŸ>EŸ>}ø®âq8òÑú—/_rÃK¼xñýúõÃéÓ§QQQû÷ï£OŸ>(//Ç©S§ª¥Uå{ðàúôé))©jm ”ò¯÷ñ†„„   S¦L©5_PPŠ‹‹ÅýA?;wî„®®.*++1}úôoæ?sæ úôéÞw~?\½zrrr3fL­ùüýý¡¤¤T- A?™™™8~ü8\\\pâÄ BOO………عs':vì###ôíÛ—k¢££ƒÁƒ£OŸ>ÈÏÏ›ÍækrôèQ£W¯^ÈÍÍÅÞ½{±~ýz:D[ÃEÃÝÝîîî8zô(ÝU¢^TTTÀÝÝÅÅÅÕŽ$aÒ0,--aee+++,X°€î*Q/._¾ ‹…ÂÂÂjÇž>}Š¢¢¢Z•—˜˜˜ï~ >>>°´´ä‰DmooÊÊJ¤¤¤`íÚµ€¥K—‚a$''cݺutóëHçÎÁf³‘““C ¢VÖ¯_¶mÛ"55•„!ØÚÚâÏ?ÿÄÿþ÷?ÆwD¨m@ºvíŠK—.áóçψÅĉ¹ÑÚ'L˜###¨¨¨€aÄÅÅ!??/_¾Ä„ x¢º­‹‚‚ÄÆÆ¢´´yyyPRRBtt4’’’ !!999DDDàãÇPTTÄ“'OÀ0  ddd   €gåßÿðÅžhõêÕÕhhh S§N¨¬¬DDD´´´ðôéS(**¢²²...¸sçúöí‹¶mÛâåË—HHHðÅ1BTT*++MMMœ9sׯ_‡‹‹ ¢¢¢`mm¼¼<øúúbéÒ¥(//ÇæÍ›áéé‰gÏžÁÄÄÞÞÞX¼x1LMM‘——‡°°0,]ºiii|Û»sçFމW¯^ÁÓÓ£FÂåË—aff†uëÖ¡¼¼±±±(((@NNîß¿$%%aÆŒÆO?ý„£GbÞ¼y¸uëFމ­[·bíÚµ5Æ— Ĉ#pþüyÌž=›k—PTTÄíïU?~ôêÕ‹ÇëFnn.>þŒöíÛC[[ÙÙÙHOOGYYTUU¹i%%%?|¿z÷î”””Э[7ž/•°±±áþ611áÊ}ñâÅô@~'z÷îAƒÃá`îܹ}úÀÐÐo>‚hjÒÒÒ™™ ‡ƒÐÐPŒ3ÇŽƒ­­-òòò0kÖ,DFFÂÅÅwïÞÅÁƒ±oß>\¾|K–,AEEÜÜÜàîîŽOŸ>añâŸ}û6òòò`mmèèh¬Y³7nÜÀ´iÓ°eˬY³ãÇÇÇ‘››‹™3g"&&ëÖ­CDD¶nÝŠßÿ¥¥¥X¶lÏ–ÝÖÌ Aƒ ** ‡ƒœœØÚÚBUUàp8?~<´µµÑ¾}{nš©©)ß´ªTÀ—]8U!Û·o©S§òÍGð"ô®@zö쉞={VK733ãþ/&&+++º›?æææ8zô(æÎ hhhÀß߃ B\\þúë/àáÇ••E×®] €¶¶6RSSIII”””`ùòåpuuÅ„ ø¶7nÜ8î …¹¹9~ÿýw¨©©aûöí8qâäääÐ¥K´mÛFFFèß¿?:wˆˆ‰‰¡_¿~PWWGaa!w¥¥M›6°³³ƒ„„ Ä·ÝñãÇ£M›6øôéΞ=Ëu÷zþüyž 1ØØØàÈ‘#Ô9@MŽ+TTT0iÒ$îommmòÃ/$ôíÛ—oDèÿ*õzzzÐÓÓ#ÍN¿~ý %%Å£´kו••xþü9\\\››‹W¯^AII Ïž=‹ÅÂçÏŸqíÚ5ܽ{ÒÒÒèÑ£JKK¡©©É4½eËàåË—PRRB~~>F'OžàÚµkˆçz€8p lmmakk pvvÆèÑ£‘——‡ðŒo­ñãÇWKSSS«6‡4 FŽÉó»C‡4'm AðCAA¡ÞÞ‡ñ€3pà@<{ö RRRÕVÄÄÄ`llŒ¤¤¤ËW-·×6HÕ÷|\-Ê3¿IA!||=¦>œ;žgdd€Åb \ÏÈ‘#yÞOž<äåå¿Ùþ¨Q£°lÙ2ôêÕ‹nñ]%-~ýúáÅ‹(**Bbb"ôõõ|ñôôêÕ+žÀC5•ŒŒäI»~ý:RSS¿Yök^¾|‰W¯^¡S§Nxñâ***àëëË Z÷_^¼xÈÈHôë×ðÏ?ÿ //ï›ídff",,Œçïõë×€üü|¼yó±±±(//ÇèѣѾ}{\¸p»w¹9lll ªª ìÚµ ÐÕÕ¥ŽDÑŒèéé!)) EEE Aff&zôèQí} xõê²³³¹ï­ÄÄD#88¸F÷~ýú!!!ÅÅÅ ‡Ãðe$00æææt#ˆï‚P¡?Nž<‰ÜÜ\èêê¢cÇŽøùçŸqêÔ)¡ÿþXºt)ÔÕÕñôéSDGGCKK IIIPSSCxx8JKKabb‚Û·oCQQNNN¸zõ*‚‚‚ "" > PPPÀ;w ¤¤¤ ;;êêê••ÅÓ§O1`ÀãÌ™3‡‹‹ ®_¿Îݧ+++‹Ç£¬¬ &&&€íÛ·#-- ÙÙÙ8rääää0kÖ,Œ;–kˆˆ—/_BJJ úúúxøð!455abbÂõúVõghh8pà"##‘ŸŸ999@[[>>>HNNÆúõë¡©© ---nÚ† (Z+ADpæÌäää@GGéé鈈ˆŒ=úúúÈÈÈ€ž? X[[ÃÕÕ(,,„­­-ºwÿþeeeGvv6\\\––___¼xñÆ ƒòòò0~üxDEEáÝ»wpqqAjj*.]º„ÈÈHüüóÏ‘‘¼¼<’““±dÉrÊ@|„:!A´VÚ¶m‹»wïr÷¥çççÃÚÚl6›¯ÍAñãàçç‡mÛ¶!<<¼Që­¨¨@zz:Ž9‚AƒQÐfâ»A[°¢™¹uë>}únZ\\Iù ‚ påʤ¤¤àùóçZozz:´µµq÷î]ì! ¢© ‚ ‚ ‚ š Z!‚ ‚ ‚‚ ‚ ‚ H!‚ ‚ ‚h:äãǸwïÞ7+òöö†³³3I” ‚ˆââb°X,øúúÖš¯¨¨, /^$¡A´väÝ»wذaž={öMåcàÀرc6lØ€¢¢"’,AQ#ÙÙÙððð›Í†––VJHVVöîÝ 6› RB‚ Z»òàÁ888|³’¨¨(èééATTrrrÈÏÏç{þü9|}}«ýEGG“ô ‚ ~PÒÓÓ¡®®:t(ÂÂÂøæ{÷î455Æ ÃÇ¿Y÷¥K—PXXHB&‚h‰ ˆ••Ú´iÓ ”••¡¥¥ÅóçãンgÏ’ô ‚ ˆFgΜ9ÈÈÈ AA)âõ)TISKK ##ƒOŸ>¡M›6¨¬¬„˜˜7o§NЩS'žò:t ÉAüÀHHH ¬¬ À999î±¼¼}ÂÖ­[QTT„¼¼‘B4=¿þú+ºwïŽÍ›7ãÞ½{X¹r%ÆŽ‹åË—“p‚hvìííy”xyyáçŸ&áÑjÙ¾};ŠŠŠ0räH :ç΃ššŒqèÐ!ˆŠŠbÁ‚ jcÊ”)055…††ŒÓ§OC[[#GŽ„tuu¡¤¤T§:ɨ3Ó¦MèQ£°bÅ žôÍ›7ãúõëðööF=HPA|¤¥¥///°ÙlA„A+ DˆŠŠBÛ¶máààP혫«+&L˜€mÛ¶AVV£G¨¨¨`ìØ±Ü|(..†¯¯/7– ‡ÃÁ¯¿þÊ“ ‚ ‚ „øùðá&L˜€{÷îÕhëahhˆÃ‡#""‚›vâÄ \»vû»¢¢ÖÖÖpqqÁ€Ïž=ÃÎ;‘œœŒE‹‘° ‚ ‚ àñãǨ¬¬DŸ>}™™‰¬¬,tèСšÇª¯ó)((Ô«­ØØX”””`àÀÜù›„„ôôôxò¢´´***¤€ ãèÑ£;v,ºtéRk>III :”ûûëÿkbÀ€pvvÆÌ™3aeeEÑŽ ‚ ‚ ¾A^^<==1eÊHKK#,, ªªª`±XøçŸ ¦¦8wî®]»†nݺáôéÓðòòª—¢³aÃÔ}ZF IDATÈÉÉaÁ‚ÃÑ£GQRR‚uëÖaذa¾ì–qssÃÔ©S1cÆ R@ˆú“ššŠK—.ÁËË """MÒÆÀ±qãFL™2ÁÁÁ$t‚ <¦DDDp¿ÔA´6¶oßeeeŒ3íÚµƒ >>RRRÜ|ÑÑÑðöö†¤¤d½#£«¨¨àرcÅÙ³g1nÜ8x{{#>>oß¾åæÓ××ÇÊ•+‘œœ\c]„ˆ .@WW†††MÚÎäÉ“QPP€{÷î‘Ð ‚h½zõj÷“AÂÊÖ­[1cÆ L:©©©ÈÊÊ‚ˆˆ† Âã™jøðá011Á’%Kêý!¹k×®ÐÔÔ„««+ a``ìܹ³Î·šMIII¯¯/|}}¹¾Ú‰–AZZüüü°lÙ²&oKII Ë—/ÇÎ;ëìSº.TVVbéÒ¥ppp€……nܸñCÝÓ¼¼<îóèëë‹û÷ïSG'Z%¥¥¥xùò% ‚ ˆV‹±±1~ùå¼~ý***HMME||<Ï Ä¤I“pöìYtïÞK–,¸îüü|°X,øùù®^½Š9sæp >}ëÖ­ÞHè222ÐÒÒ‚––íïoa„‡‡£¬¬ ÆÆÆÍÒÞüùóqíÚ5äää4Ù„ÄÅÅ***سg6mÚwww\ºt釸Ÿ¹¹¹X¹r%ÒÓÓ¹ÏäÎ;qñâEêìD«#??{÷îÅwð8OÑä\e¡ YYY´k×gϞŴiÓvÐÑ­[7HJJÂÖÖ¸~ý:ž={ÆcƒR•O\\œ›O¨°°°@qq1›¥½ÏŸ?c„ ðôôD¯^½xŽuêÔ ¿ýöìíí©7ãKàÁnݺ5È[Bc`nnÿF©kóæÍèׯß7ó™™™5Z›ü¸uëÊËË1a¾ǧM›†+VÀÔÔ´Ñ”ó;wÂÉɉgbö-X,òóóñäÉ“oæÝºu+Þ¼yƒƒÂÊÊ 7n„žž^­ ìýû÷Áb±àîîNÑdü×áADk' üñ:vìXcž‚‚$&&~sž÷uMMM¬Zµ 3gÎÄ¡C‡Ž-[¶T+£¥¥gggLŸ>GŽ>øbø[ßðueÅŠ;v,¦NÊ÷¸‰‰ :uêT£°~Þ¿3g΀ÅbATôûv‘Q£FáîÝ» ®gÇŽ;v¬@‘ÜGÕd6AEEE?~<üýý«}‘øšI“&áÏ?ÿ„©©)._¾Ü 6cbb––†!C†Ôëù¼páÜÝݹ˻ÿÅÙÙ¹¹¹8zô(Oº££#¦N ###ž ÅÅÅ7n.^¼ˆµk×BRRFFF):Q_àééI‚ ¢Õ+ÒÒÒh×®rsskÌw÷î]Œ1â›ó¼¯ã€$&&"-- ²²²044Daa!6n܈»wïrÝñ@BBÞ½{999 0@8ÁƒÃØØ¸É££_¾|¯_¿†³³s­ùvî܉3gÎüÐ755²²²3fÌw?CCCôë×ÇŽ«wåååØºu«À_B---QPP€[·n5úõlÚ´ +V¬È®büøñøûï¿áïïµYߨرcdee1oÞ¼jK©ÎÎ΀››ßòsæÌÁ­[·pñâE°X,°X,üñǘ?>ÜÝÝ¡¢¢øúúbùòå<6$AAÔÎõë×ñâÅ ìÝ»‰‰‰HNNF@@¼¼¼PZZ ///äååÅb¡¢¢ýõ^¿~œœœ:Û=øðÛ¶mƒœœF]»vÍfcåÊ•èß¿?®\¹‚þù>|ÀÖ­[¡  P£`æ;„‡]¾|9dee¹“GGGHHH`çÎMÒ^^^¦M›†eË–Õ¸úñ5nnn())««+ÄÄÄ~¸Î<þ|üüóϘ={¶PœÏ½{÷àççWï­:‰‰‰5j¢££kµÿøš“'O"??Ë—/o´ëHIIÁÈ‘#Êã+[þëääƒ:ŸÏ£Gààà€7n4ب}Ïž=ˆ‰‰Á’%K¸ƒÞ§OŸ°eËHKK7Š|fÏž;wòØÆD]‘––FLL ºvíÊ“Îb±Àf³I@Aß¡ˆâää„cÇŽ!//¯IêÿÖÖ+~ ’»»;8ßã%%%àp8HKKkuâÉ“'xõê†.4礫«‹ãÇ׺”XU«+À—ˆž^^^ê¶óСC˜8qb”à‹‡‹={öàÁƒ8zô(*++.ëááY³f5ŠG-GGGLŸ>úúúؾ}{£(ÀC:ooo¬]»aaaÍÞÏÒÓÓ±víZîJ——***è-AA óX¶l³fÍž4ÆÅÅ¥ÑÛ g† Æ$%%Õ©\XXchhȤ§§sÓnÞ¼É8991–––Œ3bÄÆÉɉqrrb222˜ÖÀÂ… ™Í›7 Ýy­\¹’YµjUË%%%1õjÓÌÌŒñôôl”óõê3xð`&22²Þuäçç3˜ÜÜ\ûð°aØ·oß¶¨>˜À :”‰ˆˆh¶6CBB˜áÇ3ÿý7Ã0 SYYÙ¨÷Ÿh^¤¤¤˜„„„jéû÷ïgI@A´*îß¿Ïdeeñ¤ýóÏ? Ã0Ljj*w®Z^^Î3§¨JÏÎήS{Uu3 ÃlÚ´‰qrrbž?^k¾ÿ"4 Hii)€yÿþ}£¶Õ¶m[æÅ‹õ*ûøñcÆÒÒ’177gLLL'''æÓ§OÕò=zôˆqrrbÌìß¿_h:¤¯¯/3|øpÆÉɉ133cþüóÏo–111a^¿~-t×åË—™Ñ£G3u*wâÄ æ§Ÿ~ªW›»wïff̘Ñ(篯¯Ï\»v­Áõܼy“1b„@ƒÅܹs™mÛ¶µÈÁtݺuÌ/¿üÒäíäçç3£Fbœœœø*všššÌ£G~ø—[HHH«P@þùçŸw-AµÀŒ;–gÌûý÷ß{{{†afÆŒÌÓ§O™k×®1+V¬àæ±µµeîܹƆ2 ,¨ÓÜX]]a†yöìsúôi¾ù=zÄhjjÖX¨°¬ÄHHHÀÅÅ¥Q#_ïÛ·&&&èÝ»w½Êáìٳؿ?üüüÀf³ùn7}b|||˜çÏŸ3Ó§OçÖÌ0åååLpp0såÊn™¯Ï!88˜o½B§€ÄÅÅ1C† abbb4Q•‘‘ù®!**Š|8Tï:üýý™Q£F1ùùù—yðࣣ£ÓªdÈ5>¬ú»qã÷øáÇCCÃfýˆB ADÝ©²Y´hϸçääÄ0Ì—h»wïæ¦oÙ²…ILLdΜ9Ãlܸ±^s¿ªº÷ìÙÃØØØ0'Nœà¾cýüüªåk HÕ ³X¬z×?yòdæÀß½Süúë¯L```“·³gÏfÚ´iu*ʘ™™1jjjÌúõë[̃vþüyÆØØX Éÿˆ#Ü^YY3|øpÆ××·Nårrr˜‘#G2ׯ_o2Ylݺ•™7oOš§§'cffÖjÚ¼¼<ÆÐйsçN˦¦¦2˜ÊÊÊ:—6m³gÏžVó² +++ñÄüàp8puu… ŒŒŒøÖ%*ÌBe³Ùضm²²²Ê÷î]Œ5Jè^x–––ÌÌÞÞæææµûWnÅhhhÀÊÊ îîîÕŽãÓ§On{1oÞ<äååáêÕ«|———cÒ¤I°²²‚ªª*ˆÍ€¥¥%$$$pþüùo*»víB÷îÝÔÞ¨Q£ÂÂÂ%§-[¶@AAË—/ÿáûŒ®®.^¿~Í÷˜ŒŒ JJJPYYIA-cccˆ‹‹cÿþýÐÒÒªU«0|øpˆ‰‰øLVKK “'OæùÀÒ«W/L™2Ó¦MƒŽŽŽÀïÝ;và—_~ÁÓ§O—.]´iÓê|ÞB­€ˆŠŠBOOO „øøx„‡‡cþüùBw®®®Ø½{w£DsŽ‹‹CPP–-[öC?p³fÍB\\¢¢¢¸iEEE`³ÙX¹r%½ÍÚ¾¸»ººBWW .¤Ñ°Y¿~=6oÞ\ãñ£G¢ÿþ044l”ñhݺu-*2ú£G€-[¶PgáC×®]qïÞ=ìÅÒÒÒMB#Bèðòò‚§§'JJJ ""‚œœ$$$p?˜-Y²;väQ@/^Œ [·n˜={vuçççƒÅbÁÏÏÀ——“'O"$$ðôéÓz½c…Z‘€³³3öîÝ[ëä½²²°´´D§N„î:Úµk¼yó¦ÁuíÚµ vvvM2ÁnI¨ªªâ—_~ÁöíÛñùógîCðï¿ÿbîܹM񾯱c¡¤¤„Ë—/ó¤ß¿>ÄêÕ«y–7‰¦gذaèÔ©_Ï_ÉÉÉ8~ü8Ö®] IIÉFioéÒ¥¸{÷.âââ„^6%%%صk-ZT/Ãìá…íïïÍ›7cРAßÌûömìܹ“”‚ „ŠƒB^^!!!øøñ#,X---ÈÉÉA\\Û¶mý{÷`hh <þùùùHJJÂõë×agg‡öíÛ×X¿‚‚Øl6,,,‚sçÎáîÝ»˜={6|||0uêTHIIqß»oß¾…ŠŠ öîÝ‹ÿýï ky ðÅÑË—/^cž÷ïßãï¿ÿ†£££P^ƒœœáææÖ ƒÇ   p8¡\åù8::BQQ‘ûpmܸ7nÜh²ö°lÙ2xzzr#~üÈM¯¨¨ÀÖ­[áééYãþÓú ¡¡©S§ÂÓÓ³Q¯£´´‡û×Û€6oÞ UUUØÙÙQGáCJJJµmsæÌÁÙ³gù挌ÄôéÓqûömABƒ±±1¤¥¥¡¨¨ˆž={bèС:t(\\\ --¡C‡"??‹-‚ˆˆÒÓÓQZZŠœœŒ9]ºt¸­nݺABB“&M‚††  §§Ç=ž››‹ÜÜ\Œ3vvv(((€··7_÷÷â-A¸U[_ÆŒSã‹vÙ²ePVVÚkXµjäå员˜ˆž={Ö«Ž¥K—âÀèØ±#=qDDDàåå…Ç#""GŽA×®]›´MsssHKKcüøñ066ÆãÇqúôé:=ÀDã2~üxHKKÃÄÄ·nÝ‚²²2>ŒŒŒ ôïß¿ÑÛ[¸p!.\ˆ¨¨(èëë7¸¾ 6 >>òòòèÛ·/îܹmmíj6^›6mØéDBBîܹƒÃ‡Sù}ûöå>¿úúúðöö®–'44#FŒ a!tèééñ(Uôë×À—I_3qâD¨—½ª¦¦&Oˆnݺñmø²k¤6Z„2wî\DDDÀÙÙ¹šKÛ„„x{{£¸¸X诃ÍfƒÅbáúõëu.;kÖ,ØÚÚ~ó†þˆ4÷^SSS˜šš’à…ˆ‘#G‚ÍfÃÌÌ DVVüýý›¤­=z`Ĉ8vì<<<ê]Ï­[·°víZ¬\¹þù'7ÝÉÉ©ZÞ;wîÀÊÊ ¦¦¦­ôž9súúú¢ µFŠ‹‹!-- 111úÉóçÏaff&°C‚ ¢vZ̆uóx0ÉÌÌÄêÕ«qòäÉq ³gÏFÛ¶m±ÿþ:•Û¹s'$$$„v‹A‹âããggg9r¤IÛZ¼x1îÝ»‡„„„z•OIIÁÖ­[qëÖ-Ì™3ç›ùLJK—.!##“&MªÑ“ðÅù½{÷j•ó#“››‹ØØX´iÓ†ë%† ‚h¥ Hvv67ZbFFFË÷éÓX´h×o{@@ŠŠŠš<âtc!++ œ8qB /iÅÅŸsçüüü°víZˆ‹‹S%ˆZPWW‡––V“GµîÙ³'8€… r£Í J~~>¶lÙ‡:E$—‘‘››~ÿýwžqðkÒÒÒpðàA¬]»ÒÒÒÔ!ø0sæLܹs|khhàÝ»w|ÉÉɵ87ÌAÂH³Íh‹‹‹Ááp Þøðáñk×*Ÿø IDAT.ØØØ oß¾xûö-N:Õ¢>tèPüöÛoøå—_¾é±+//***8vìzôèA½• „ˆ!C†`ß¾}X²d Æ… ÖêI¤j\µjºuë†éÓ§×{ܱc~þùg<~üòòò†a°wï^ôéÓ?ýôÝ 055ÅÍ›7áââÂ÷¸””JKKyÒ²²² ªª YYÙ&_]#‚ ¤ÑÑÑáz¹wï^½ë122B```‹úÌ™31sæLê}ÑÂ0`n߾ÇÃÜÜ“&MºuëjÌ¿hÑ" <,«Aí¢sçÎX³f ×ÍðæÍ›_c°ÌÖŽ——à›ÞÍÍÍk=îïïϳ嵨¨²²²Ôá ‚ ZšBÑZ±³³ƒ¼½½ahhˆ9sæÀÎÎŽ;i Fhh(¦L™Ò(qjÄÅÅ€§OŸb÷îÝkkk 6쇽ööö<ÊHmŒ5ªÆcË—/¯UA,**‚»»; x¼Ë¬^½mÚ´‘‘&OžLA) AMÏÂ… 1uêT\¹rk×®Err2ÄÅÅ¡¤¤„]»vÕÉæC %Ê;ÁËàÁƒ†a ¤¤Äs¬¬¬ íڵÕ+W¸ ȧOŸ -- ggg¸ºº’BA AD󡤤„ùóçcþüùˆŽŽFyy9 H0-ˆ:àâÅ‹ƒ¨¨(–-[Æ=¶aÃtìØÈÈÈ@‡ðñãG(**BAAëYËÕÕ½{÷ƬY³ø¶‘œœL1‚ „ ‚h\ø‡"„ŸQ£FA__ÈÍÍEçιǪ”~ÆêÀ—81sçÎ…žžRSSùÖìß¿’’’|óäææ¢°°êêêä.˜ ˆV‡(‰€ âÿµwßaQÿÀßHªˆJW•*öÞ{,Q¢b,\ì]b,)gÇ^¤Y" Qc# 4N@"Ò‘Þ¥Ïïì× `h"Âçõ<>ÉÍÎÎ,ŸÛ»¹!D˜¢¢"444`hh‘JÛ À“'O0lØ0€’’"##±iÓ&¤¤¤€1ÆíS±èaxx8zöì‰]»vU[¿ V­ZU§ië !„: „BH3cllŒwïÞ!11ÏŸ?GŸ>}¸m|>¿Rþ¤¤$<~ü˜ÛfaaÉ“'ÃÙÙ¹Ú:¬­­áïïOÁ&„P„B!fÞ²··ÇäÉ“¹´ñãÇsB øð̇©©)’““‘˜˜ˆN:U[nbb"TUU1tèPdee«]¼wëÖ­prr¢A¡!„B>8þ<ŒŒŒ°jÕ*´k×kÖ¬á¦ö­XÅ>>>žûwâÄ \»v &Lèêê"$$¤Ê·²²2‚‚‚(È„¯Í‚E!„|&FFF•ÒvîÜÉýÿ²eËðý÷ßs‹#öïß?F·nݽzõÂÅ‹qÿþ}ìØ±yyyLœ8qqq¸}û6&MšT¯ãŒŠŠÂû÷¯O'òÙ‰°§èh$«W¯F›6mpàÀ:„B”¤¤$‚ƒƒ¡­­Ýlþ¦ÌÌLüøã••E÷îÝ1oÞ<@yy9Ö¯_àÃÔÀÁßÿ7oÞ@QQxòä þüóO8;;£C‡•ʯXý½ªè !¤¡ýç777$%%aéÒ¥ÕæIKKÃéÓ§‘‘‘E‹ÁÐÐ"K!“'O"%%0nÜ8Œ5 ^^^Üb+++nHÒ¿={ö ×®]C‡°jÕ*ÈÈÈ´¸***‚Ïç#77ÒÒÒ\z«V­¸NCQQ®]»†òòr¨««ã‡~@ii)¬¬¬0jÔ(¸ººbíÚµ7n€Ï›ˆ‰‰!..Ó¦Mƒœœ:wî —*×°¹~ý:œœœàèèXå1–••!44eeeUÞù!„u@ž}+W®„¢¢"öïßUUU´k׎¢K!qqqèС6oÞ àïí]ºtA@@ø|>Þ½{[[[lÚ´©Ò¾Bù6nÜØbcY]' øpdþüùBi¢¢¢Ø¹s'·€¢••JJJƒ BII Î;‡Þ½{#++ Ë—/Çž={ ¡¡eee((( ¼¼‘‘‘ÐÔÔÄĉ±dÉŒ1C† c ÙÙÙÈÏÏGII Ž;uuulذ’’’PTT¤7!¤úHJJ Š‹‹¹ :u‚¢¢"&OžŒ7n|²ôôt´mÛ ...TÎÍ›7¹Åš*xzz¢°°oÞ¼¡3@!Mœ‘‘¶mÛV£¼%%%x÷î÷ZRRâââ(**B||<‚‚‚’’‚‚‚î—ü:í󱂂´iÓ†Ë÷ï…ù6mÚÄ}¡®PZZŠ5kÖ´È;%uµdÉîÿ[µj…øøx 33¢¢¢èÚµ+âãã‘’’‚ÒÒRxxx@BBeeeHIIAVVDEE1}útxzzâÑ£G••ýätÄ–ÇÚÚfffÿë€än?îúê³ß«W¯ ..Î=ˆØ”ÕÅÅ'ND«V­¥¾èèhäææÖz¨ß‹/о}ûfÝÞ’““¹õjÛÞÄÄÄ ££ÓäÛÛíÛ·1a„Fmo999µRÒØí ­w9eeelýúõMêo»|ù2 h²lllXfff½Ë ªÓuðsÆióæÍ¬¨¨¨Þåøúú2{{û9&'''æååUïrJKKÙ† šT¼/]ºÄë]NNNÛµkWƒ]û.\¸Ð¤â´iÓ&V\\\ïr¼½½™ƒƒC­öùdWüÈ‘#xóæ Þ¿‡]»vA^^EEEðööæò}ûí·¸pᢢ¢°cÇÈÉÉÕøWµÆ*&&Vç){õêÕ¨ûuêÔ‰[̪±ÔõXë:é@]ëSRRª÷¯Hq¬ 5fl*"ýÚM}Ú›ˆˆH£ÕWWu¾¾ÕõX{öìÙèךrpp€¯¯/ ðÍ7ß@LL óçÏǃ¡¡!,X ô+onn.FŒÌ;<FFF•žqhŠmûßÔÔÔ¸aÊõÕP“¼4öû¡¦íW\\¼ÞåÈËË7Øu°¡âd``Pë»¶Ÿ[CµK‘&×.µ´´¸õvšŠ†¸ ú9Úe]>O«º«QVVV»vó%¦ám<¦ ¤ØÔÊÕ«W¡££ƒ¾}ûR0þÅÍÍ ­[·Æˆ#(ÿòìÙ3$%%aÆŒ º’¹rå ›d‡¦9òóóCTTæÌ™CÁh¹¹¹øí·ß°{÷n Fûj"lj=[ŠMÓ'--ÝdþÒ$%%)6Õ¨÷˜tB×ÀæªM›6tíhDâââBÓ0“ÏKDD¤Æ£zH-cûµÞ!„B!„|}šô²²2ìÝ»ÙÙÙèÛ·/·òë¿=xðnnn>ü’»lÙ2téÒ…Î.!¤V8mmmÌœ9³Ú<{öìAvv6ÀÃÃ~~~¸/àýû÷8xð rrr0pàÀj‡ÈàçŸFNN „éÓ§Sðiüüü`ooàÃtáŠŠŠ°±±ÁÙ³gŠ:pkU•væÌ„……¡cÇŽŸ\‹èôéÓxýú5:uê„ 6Pà«Ñ¤ï€ìÙ³ëÖ­ƒ¼¼<þúë/ˆ‰‰U9µâÇã}=z„‚‚Lœ8‘Î.!¤Æ._¾Œ÷ïßCIIé“ Ož¸ììlÈËˤ¤¤PXXXe> xyyÁËË‹ëÝRS999¨”^XXŸ¯æïÈÊÊâ^§¤¤ÀËË €K{÷î]µi/_¾lÑí`èС5žÉ%::ÇŽŠ7iü÷mÅØìÖ­[Wûù““íÞºukQðH£*))——¢££)MÀ¥K— üü|nÝ$yyyäää¥ÉÉÉU™Vqüßòóó¹P+ö%_a¤¦V¯^øøxÄÇÇ×iÑ7Ò²íÙ³•Òß½{÷ŸS~Uûŧ1ݸqC† ¯¯/—6cÆ øøø`õêÕxüøq¥´'Ož¦OŸ___¬ZµŠKk‰j³Ø^çÎqýúõ*;®„ò±cÇŽáòå˸|ù2£‰|g´µµÅÙ³g)Ô©Ú„ àêê  žž·mçÎHHHða½ XXX 11ºººtfIU·ª°¦¦&"##?¹ï¦M›ðàÁƒ/þ7$%% ÍÔtïÞ=´jÕ .ÄìÙ³qäÈܽ{¢¢¢X¸p!f͚ť‰‰‰qiG¥ñ/oß¾Å?þȽ¾uë¥ 9r$÷Þ‹ŒŒ„¶¶6·mãÆHKKŒ1>DEE¡k×®<Òhâããáââ‚S§NÑT®_˜ŸŸ’’’„ÒLLL¸îîÞ½‹±cÇÂÔÔ”K»wïÆŒnDDEZ…Ó§OsÛLMM¹uòî߿ѣGSà¿ÆȈ# )) ‡©S§Vû`yII x<x<¦OŸN 7CŒ1L™2sæÌ©©)nܸG¡_¿~˜0a~ýõWddd wïÞØ¸q#бcGܼy<€ˆˆÜÝÝ¡¡¡ÁÛôó󃉉 Nœ8Qe.\€¤¤$ÀÒÒÆ Ãùóç!!!§OŸâùóç¸zõ*Î;‡gÏžÁ××&&&°°°ÀÆñ×_ADD‡ÂÈ‘#qæÌ´nÝ{öì””Ž?^e½§N‚œœ¼½½!--]íñ}lÕªUh×®÷úÙ³gèÞ½;Ú¶m sss¸»»W›Ö£G(**ri-• ®]»†gÏžá‡~¨6Ÿ††w½™6m½9¿ñãÇ£¸¸<ß|ó ÔÕÕ«Ì7a‚ÇãaÑ¢EPSS£à‘FsöìYøùùÇãÁßßJJJ8tè:vì°°°ÀÒ¥Kaff†°°0xxx oß¾˜}ЧOdeeÁÌÌ ÎÎÎ-â\ôë×vvvàñxØ»w/lll §§‡ÁƒƒÇãAMM fffÐÓÓÃÀ…Òôõõ¹4 *Ÿ7>,ìgff---zÞì?¾ØòUؾ};ëÞ½;óóócáááL^^žeee±üü|fbbÂÜÜÜØš5k؆ cŒõë×ݸqƒ¥¦¦2ìСCìÚµk¬K—.¬¸¸˜ÉË˳ׯ_³'Ož°®]»Vªïùóç¬uëÖŒ1ÆŽ;ÆÔÕÕÙ“'OØÂ… ÙÖ­[cŒõêՋݾ}›½ÿžÉËË3>ŸÏ~ÿýw6uêT–À°ãdz””æííͤ¥¥YVV;tè9rd•§——“`ŽŽŽì×_e£GfŒ1¶a榦&ôÏÞÞžÛOWW—Ý»w1ÆØÎ;™¥¥%cŒ±   ¦  ÀvìØÁ¥½|ù’)**²;v°ï¾ûŽ1Ƙ@ `mÛ¶¥†F! Äßߟ)++3ÆËÍÍešššìûï¿g lß¾}lðàÁìêÕ«lóæÍìðáÃLVV–¥¦¦²7n°~ýúq×þ5kÖ0Æ4h³··g{÷îeC† aööölãÆÌÎÎŽ-_¾œõîÝ›…„„°¾}û2GGGfccÖ-[ÆJKKÙ»wïXAA»|ù2“••e‰‰‰lÕªU¬  €NitbÔ#_ ôêÕ }ûöELL òòò¸I cxÿþ}•ûUä™3g÷‹ð¿I*nÉ–””ÀÜÜ`ll 'TF×®]annGGÇ*ïÐdgg£gÏž——Ç®]»¸ÅÐæÎ‹¶mÛ"##"""——ÿäBiòòòhݺ5fÍš… .pé£FB§N„òêëëSà „¯€ŒŒ ÄÄÄ0sæL¨¨¨ ;;:t€––´´´ ++ËÍüù_²²²Ð±cGhjjBSS:::xñâ ]]]nqȬ¬,ÈÈÈ@TTÊÊÊ€… b×®]8{ö,Š‹‹i¡UòEP„|•DEE!##ƒììlˆ‹‹CDD„»ˆæææ"77ÅÅÅŸ,C^^^h& QQQnxVûöík|,YYY\g¦[·nPSSCfffuw‘¬¬,((( ´´ïÞ½ƒªªêÖó÷ßWšå­S§NÐ××G~~>JJJ¸Y™fÍš…Y³f!!!—/_æž©.-11W®\ÁÂ… ©qBH#——‡¬¬,úõë‡ÌÌL@VV¶Ê–òòò››ËÍ⦠ €ÌÌL˜˜˜ ==½ÚN„‚‚bccQVV†ôôtÈÊÊBJJ [·nÅÊ•+áééI'‚P„ê0Æàââ‚wïÞ!66¸qãFŽ eeeXXX`ܸqÀÈ‘#!))‰ŒŒ ¸¸¸ ¼¼àââ‚=z ==>>>øû￱`Áhii!-- ^^^B³añù|”––ÂÕÕ...ˆŠŠBHH€‹_nݺS¦LÁš5k°aÃÜ¿sçÎ…¦¦&:wî cccZ^²d €‹¢3¸qã"##ѯ_?äæærõº¸¸ ¨¨wïÞ¼~ýaaaøùçŸñóÏ?WŸ¹sç"""VVVÐÔÔ„©©)z÷îmÛ¶!,, çÏŸ‡žžŒ+¥õêÕK(BHøuëòòòððáCHJJ"-- ...077Ç–-[`aaåË—ãÕ«W¸xñ"\]]1vìX¨¨¨peLš4 C‡…´´4ÒÒÒpëÖ-ØÛÛcúôéX±b‚ƒƒqôèQ>¾Ò¿ªVú$„Ò2DEEARRfff˜?>ìíí«Ìiii.ßÕ«Wÿ³ìøøx”––R !¤‰úäJèß~û-bccëµN@@…ÒnܸâÀt!„4(mmmC[[›‚A!_[¤! 6 Æ J{óæ EžB!„è“C°>|WWW8;;ãýû÷€„„hiiqù¾ùæœ>}NNNPUU…²²2E–BHµzôè8;;ãøñãX¹r%·í—_~Á–-[ººº`Œqù¬¬¬(x„ò‘¨¨(äååU¹M 4H×®]ƒ³³³Ðcàêê gggÄÅÅ5\¤C‡èÕ«¾ûî;¨©©ATT ¤¤.Ÿ±±1†  Ì›7ËG!„TE\\óçχššÆnݺqÛæÌ™KKË*óѰ*Bù777|÷ÝwHNN®´ÍÃÃëÖ­«w'Nœ€ŸŸ233±iÓ&.ÝÉÉ ·oßFyy9V­ZU«2?9K__¿ÊôÖ­[£ÿþBi:::Ô !„ÔüHL fff•ÒÕÕÕk”BZºñãÇ#&&¦Rz^^ÜÝÝ¡¦¦Vï:bbb°oß>ˆ‰‰!,,ŒKOJJ–-[ ©© Ÿ†ë€B!„B¾.W®\ŠŠ 222šäñQ„BÈWÏÙÙñññ€²²2 !¤E»~ý:&Nœˆ/^ 44={ö¤!„Ò†Š¢¢"à`'„æ.((/^¼@ii)æÌ™ƒèèhÈÉÉáòåË€ÐÐPhjjÖ«CCC,Z´]»vEqq1¼½½¡¨¨ˆnݺÁÚÚDll,u@!„´,íÛ·§ BZyyy|ûí·><£Ý¶m[HIIAUU°mÛ6HKK׫Ž @[[Œ1èëë#99mÚ´ÁøñãѱcGañâÅÔ!„B!¤¹ÓÐЀ††÷ZNNNh{}ï~Tøxò)YYYîÿ{÷î]§òZÑ©#„B!„4ê€B!„ò•øöÛo‘’’‚;v€ÇãÁÜÜYYY\OOOôíÛƒ â&쨭ãǃÇãÁÄÄÏŸ?DDD`Ë–- äòEDD`ݺuprrª¶,‚E!„BÈWêÞ½{(,,„¢¢"¶lÙiiilݺ•›˜bccq÷î]¸ººâÍ›7uZdÁ‚PPPÀŸþ‰¤¤$DDDÀÃûwïFëÖ­¹|jjj>|8 «-‹î€B!„ò:uêZµj…Ž;B\\ÅÅÅ0`†Ž:pùæÍ›%%%ܾ}[èŽÚPPPÀŠ+àïïI“&áäÉ“ðòòÂ÷ßôôt.Ÿ”””PÝ_´RPP€øøxÄÇÇ#//Z !„B!u”››‹ÈÈHXXX //EEE’’‚µµ5ž?ŽwïÞ åwuu…••Œk\GNNx<nÞ¼ ˜={6tttpûömDFFâÈ‘#èׯŸ§OŸVz8üòåËpqq©W]°±±œ?K–,‚‚nß¾ÍåaŒÏçÃÔÔgÏž¥y­» IDAT!„æÉÊÊ |>|>bb´Æ.!¤eغu+$%%áîîÐÕÕÅĉ¡¯¯yyy.Ÿ§§'"""Ð¥K—:× >Ÿ9sæø0ÔuÁ‚(//G÷îݹ|æææpppàîÆP„B!„f ##îîî°°°€ƒƒ¼¼¼S§NáñãÇÈÏÏáþýûؾ}{­ë(,,„³³3ñèÑ#¬[·N¨CrèÐ!ÄÆÆ"..Nh¿ÄÇÇ#<<œ: „BZޱcÇâÞ½{BH³T^^CCChjjbÀ€(**BNNÔÔÔ0sæLî‚‚„‡‡cß¾}pww¯Õ: ¢¢¢PSSƒ‚‚|}}áääwww5!„fIII ?ýô YYY !¤Y‘••Eaa!x<âãã1gΈ‹‹ƒÇã¡cÇŽèС·ˆƒƒÀÆÆ]»v­qâââ033œ;wŽ+cèСPUUÅ©S§ ..KKKnÐÐP9r)))8räH•åÒ: „BšIIICNNaaaxöì6oÞL!„&‚†`Bi–”••Ñ»wo¡¬¬ŒB!M Áª£œœnlñÙ³g¡¯¯_)Orr2tuu¹™¦M›F³³!11OŸ>å^kkkÃØØ˜CŒŒ QZZ QQQ !¤Ù‰ŠŠB‡ ##ƒ¢¢"¸¸¸ k×®èÝ»7pi3fÌ@«VÂ÷ŒŒŒjUŸ··7¹ï·U•‘‘‘üü|¨««7­Èï¿ÿŽüü|ˆ‹‹W¹}àÀPQQªª*444¾è‰ EVVàÈ‘#PQQÁû÷ïѽ{w˜ššâäÉ“UާËÊÊBhh(àîÝ»xúô)rrr`nn¨««CMMÞ9ä«ÀÍ’Q!33#FŒàÞûöíºÅÆÆbݺu ò…PGGíÚµ£A!¤ÅqssÃo¿ý†Ó§OC[[D«V­pìØ1ØÛÛCAA¿ÿþ;ŒŒŒ """´¯­­-ÂÂÂpôèÑ×çáᤤ$î»ù“'OðÓO?áï¿ÿæò¼|ùÀÔ©S›^¤_¿~øå—_ ))Yåö§OŸ">>>>>ˆˆˆˆÀÚÚºF勈ˆ@UU•ëù¥¦¦ mǵkת­ÿßy-ZX¿~=úöí[£cPPPàÜ©øorr2<<<ôìÙ………˜9s&ttt ''999zG!iii(,,ülí#99¹ÒŠ©ÕIHHÀÅ‹!--Íu&fÏž¡C‡bòäÉUîóqç‚‚‚Vï㎟ϯö———‡Õ«WCQQ //ßäF.((@FFFö•––FÛ¶mé B!-Ôøñã…œ2e ŒŒŒÐªU+ÂÖÖ €¾¾¾P$&&éééµú!ÐÇǘ1cTTT——¨¨¨å344ÄÚµk+-„ب›7oÂÃÃC(ÍÓÓcÆŒùä—ÿVJ»uëV¥/2ÕùóÏ?ѧO@\\ ««+”gÆ èܹs£6”Ž;°páB@tt4þüóOxyyÁÍÍ ¦¦¦\þ¹sç¢_¿~ôkAÞ½{‡ƒ ¥={ö S¦L‹‹ ×™>hÐ ôë×QQQpqq©´ÝÙÙýû÷bÀ€•†³,]º´Áuwpp@RR÷:00ÅÅÅèÔ©SËøçŸ0þ|œ–.]úÕç’’?~àèèˆ`Ö¬YÜyùGGGøøø 88ÆÆÆèر#FU除û÷ï#$$D¨iiiìÝ»·E¿Ç®\¹‚ÀÀÀ:½7¥¤¤`hhXã}=zUUUHKK£]»vضmÛgù›ž?Ž«W¯Ö(ß´iÓ„Òôôô0zôè¯þ¼VÌ‚¥­­Í¥ñx<ðù|ú`!„4;'OžÄ¨Q£ ­­÷ïßãàÁƒØ¾};ÜÜÜ //ssslÙ²{öì„„üýýqèÐ!ôéÓ·nÝ­[·„VMÿXNNvïÞÁƒÃÃÃ|>III°³³ƒ««+&OžŒ[·náôéÓB«¡ûøø &&³fÍ¢Hs–‘‘!´ ðaøÉo¿ýÆÍ={öìJϪˆ‹‹£C‡\þŠg]*xxxÀÛÛ[è]dd$&NœÈ k©‰ââbøûûs¯¥¥¥±bÅ ¡<ÊÊʨq™YYYÈËËã^ÿþûïÜP»¸¸8˜™™ Í™4iR†Ü}ìÅ‹µZ°§â8´µµQVV†ÜÜ\Œ7®Ú/¿Ýºuc zzz;v,Z·nöíÛ×úüççç#33ÉÉÉ8{ö,Ú´i#´½°°[·n徜)))Ñ›¦ªÖY:uj2B'&&¢¼¼\(mß¾}•Þ#IIIX¹r%† òUw@¦L™;;;ÈÈÈP&„4AAA8zô( 1gÎðù|tëÖ /_¾ÄàÁƒqæÌÌ™3ç΃»»;îß¿^½zqרÚÚÖh’¤¹sçÂØØ¾¾¾X´h7¹Œ >Œˆˆ0Æ ¤¤„+W® -- +V¬€ŽŽu@Hý%''#::ºVûHHHpCâCZZ"""¸×?FRRÄÅÅQTT--­*‡®T8þ<äääW«ºååå¡««‹òòrøøøüg>Bš2???ÈÈÈ gÏžMú8_½z…ììlÀСC"ÔÑÔÔ„½½= @'•ÒlÄÆÆ"!!À‡»Ø)))ÜdÆÆÆˆŠŠBNN444 ªªŠ€€tíÚ•ÙMMÍÕ•‘‘ׯ_WúNWQFLL c••Exx8@KK«ÊÑ-Ô!-N~~>ÜÜÜ>™§}ûö:t(‹¯„»»;RRRóçÏÇ«W¯„: 666ÈÊÊ¢aX„ÒТ¤ÅiÓ¦ 7!¤y077çþÿ›o¾©´}çε¾›I!äó •Ð !„Bù =}ú3gÎDdd$—æé鉵k×"** [¶lÁÊ•+1qâD”••ø0ÛæöíÛÁãñ`nnÎ _­‰äädlß¾OžÓ¦MCFFrssÃu>222лwï*õ­X•: „B!„4nnnˆˆˆ€­­-rrr`mmÍý8p $%%±sçN8pøé§ŸPTTðx<¬\¹;w®Q]|>ÇŽCrr2Ö¯_ÏuB> pqqÁŸþ‰™3gÂßßçΫvöAZ„BH³RÕJèðüùsDDD`îܹBéà“¿ÔBiXt„BH‹Ð·o_øùùq¯“““QXX[[[¤¥¥Q€!„: „BÈçsíÚ5¼zõ oÞ¼nݺEA!„ê€B!ŸGzz:V®\‰yóæ¡S§NB iBi/^€ÇãÇãÁÓÓ“"O!¤ÑÍŸ?vvv€ììlèéé¡k×®7n ¹Yb!„|>¶zïÞ½¹•W¯^M‘'„Ò`ÜÝݹ¹ìkÓ‰X¹r%ddd ++‹üü|”••¡U+@!Í¢B!„|.íÛ·‡„„@DDä“yKJJ°}ûvXYYUš)‹BÈçG?óBùêéêêÂÌÌ fffŸì€téÒHOOG—.]„¶}<<‹BÈçCw@!„´ŠŠŠ˜>}:ÌÍÍ+m344ÄíÛ·‘‘‘¶mÛré(//‡††Fì"„R=ºB!¤E©ªóQaÛ¶mØ»w¯PZ@@nß¾ www !„P„BiX¦¦¦ðõõ¼|ùqqqÐÕÕÅï¿ÿ !„Ô Á"„B>Ò±cGDDD ??111Xµj´´´Ð©S'$$$P€!¤žè!„òsss¨¨¨ //‹/†––`ܸqðööÇCff¦Ð>ÙÙÙ8B©!ºB!„ü˰aêLÿæ›o`nnŽ~ýúáþýûPTTìÝ»¥¥¥Áš5k¸N !„ê€B!uVñ»ŸŸöîÝ 111äååa„ :t(€ÇãaÊ”)Õ>ìîîîþÉá !„: „B©dûöíHIIŒŒ ¤¥¥¹ôÅ‹#::<fff˜0aÞ¿GŽ=Š­[·bܸqDBu@!„RsÊÊÊ•Ò ahhˆ)S¦ÀÛÛûö탔”†899ÁÓÓW®\”” „N:rssQ\\ŒvíÚQp !-·‰ððpŒ?¾Ú}Ê®]»Vëý®^½Ú¨í­âZ\Óëï—’œœÌ8À"##Ù‰'„Ò*ÄÆÆ²¨¨(ÆcáááÌÖÖ–ËwðàÁÏ¿ÏU޳³3{úôi½Ë)++cëׯoRÛåË—Y@@@ƒ”eccÃ233ë]NPPP®ƒŸ3N›7ofEEEõ.Ç××—ÙÛÛ7È1999 }—««ÒÒR¶aÆ&ïK—.±ÀÀÀz—“““ÃvíÚÕ ÇôòåKváÂ…&§M›6±âââz—ãííÍjµÏ'‡`9r¡¡¡HHH@ll,víÚyyy¤¥¥aΜ9Ü“åË—ãäÉ“ÈÈÈÀ¢E‹jÜ›–––nð_ê>¥U«Vu~@¾®½èºî')) IIÉF½-V×cmì˜JHH4úØu9V‘F˜˜Ú´ióU´›¯¥½Õ•´´tÉ­ë±ÊÉÉÕû—¬ÏÅÁÁ¾¾¾èС¬¬¬ ++ cccðx<.íã¼Ø¿?ºuë†ÔÔT.ߪU«š|Ûþ7)))´nݺAÊj¨I^ûýP²²² Ò~ÅÅÅì:ØPqjŠ“óHII5Øw°¦Ö.Û´iSï;i ­9·ËÖ­[ ME^£ïHìß÷®¿<{ ‘PljâêÕ«ÐÑÑAß¾})ÿâææ†Ö­[cĈŒyöì’’’0cÆ ]É¿\¹r†††èÕ«£øùù!** sæÌ¡`4‚ÜÜ\üöÛoؽ{7£µ¢B!„BËW{$++«IÞB¦Ø4]kÔa_‹ÂÂBˆˆˆ4Ø0‘椸¸eee´]I5×Uqqñ&7Ü¥9_JKKk=Ü…Ô c ¹¹¹4ÅuK뀔——ãòåË ÂŒ30pàÀ*óEFFÂÖÖÀ‡Ui—/_^§™g!-Û;wЦM 6¬Ú<{öìAvv6 ..ÎÎθ/ ´´/^Dhh(æÍ›WíÐÊ’’\¼xaaa˜?>úôéCÁ#¤òó󃽽=÷ýROO–––¸ÿ>îÞ½ nh[Eš©©)fÏž]mZUîÝ»‡{÷î¡ÿþ˜5kþkì€\¼x}ûö…Á'Çï<Þ÷Ñ£G(((ÀĉéìBjÌÝÝýõúöí‹™3gþgþèèhܹs«W¯¦à}gϞŠAƒÐ³gOœ?ýû÷¯rªÌ3gÎ`È!èÑ£Î;‡@WW—HH þñâêÕ«èÓ§RSS‘››‹I“&ÁÇÇ111hß¾=òòò0iÒ$x{{#66JJJÜwK///ÄÇÇâRÙ>Daa!&L˜€gÏž!11±FŸ'-Q“~$(($%%ýç>·nÝ¢³J©“É“'×(_tt4fΜIÞ~A¡¡¡èÙ³'€w¾SRRªÌ†=zÚ·oÔÔT !-ŸÏ‡££#ôôôÍ­Ë¡§§‡DGGskÈèééáÕ«Wxûö­PZHHHµŸ ]ºtèêêâÕ«Wð¯±RSÇÇC¿~ý謒ÿôàÁˆˆˆàÝ»w•¶uèÐ/^¼hòCzz:ú÷ï={öpi¶¶¶3f ÌÌÌpçÎÀ‰'¸4WWWÀñãÇ1fÌôïßnnn€cÇŽaìØ±èß¿?þúë¯×&ÌÍÍkœ·sçÎð÷÷ÇÍ›7éÍDù$ggg <k×®¥`47n„““vîÜIÁ HÕ HLLD§N¸m...ÈÊÊðane>Ÿ>Ÿ¨¨¨Ð™%Ÿô©D>¹z¹¯¯/<øÅÿ¡_}“““áàà€Í›7ÃÚÚÇGxx8+¥999aË–-°¶¶Æ±cǸ´Í›7cݺu8zô(rss©¡üG¯¢ã|X–|y={öDhh( %%ÊÊÊܶëׯ#//УG„……RSSѾ}{ i4™™™¸zõ*ÜÜÜ„~,"ïíÛ·Üó{:wîÌ­i===tîÜÑÑÑ\š®®.´´´„Ò>îùÏ?ÿpÛ:wîŒ7oÞ^½zEÃ=?¥)¯˜[VVÆ.\¸À¬­­™§§§Ð¶±cDzׯ_3Æ+..fÖÖÖÌÚÚºAV›%M‡‹‹ ›:u*;tè;zô(KKKcË–-cVVVìçŸfŒ1öý÷ß³åË—³ôôt6mÚ4vüøq–ššÊfÍšÅîÝ»Ç6lØÀ¶nÝÊŠ‹‹Yvv6ûþûïÙÚµk–œœ,T_||<5j cžžžlÈ!,>>ž9’Ý»w¥¦¦2###fbbÂìììXVV[µj[»v-Û±cKLLd3fÌ`ööölèС,>>ž1‚ÙÚÚ²qãÆ±Ã‡WùwÆÅűáÇ3¶dÉväÈ‘ÅgéÒ¥l÷îÝŒ1ÆîÞ½Ëôôô¸m²²²ŒÏç3}}}.MFF†ñù|f``À¥µiÓ†ñù|fhhÈ¥IKKsﯖbÏž=ÌÒÒ’-Z´ˆñx<¡Õk§Nʽ¾yó&w½¹rå ½I¿’’væÌfmm]iÅù!C†°¸¸8îóáôéÓÌÚÚš=þœGÕÎ;™´´4³¶¶fñññlâĉÌÞÞž?ž1ÆØ¯¿þʬ¬¬ØÒ¥KYjj*‹‰‰a3fÌ`‹-bß~û-ËÎÎf3fÌ`|>Ÿ½|ù’=šÝ¿Ÿ1ÆØÏ?ÿ̬¬¬Ø²eËXbb"Û²e ;tè»xñ"›={6KKKcŒ1vàÀ¶jÕ*fiiÉ"##ÙôéÓÙôéÓYff&³´´d>lç"%%…íÙ³‡Y[[³ 6°ØØXÆc÷îÝcÖÖÖB+ÌW¤}¼ºwUiŒ1¶víZæââ½¾{÷.³¶¶fŽŽŽô¨ëJè_üöL«VX²dI•Û>"Rq„4?ñññxøð!† †!C†à›o¾ÁÔ©S±`ÁÌš5 :uÂÀqâÄ ´mÛêêꈉ‰AAAüýýÁÃôéÓ1wî\¬^½Û·o‡ºº:¶nÝŠ#GŽTª/77¾¾¾ÈÏÏGrr2ž>} ôèÑû÷ïÇãÇ1`À(**bÞ¼yX¼x1±nÝ:XYY!11ÏŸ?‡¸¸8V¯^œœøøø`áÂ…X¼x1¾ýöÛ*oÃWä»té ±}ûv¬Y³?ÆÉ“'…ò>+V¬ ÆÑÀª»o`` 4ÔjêÔ©˜:u*ì ƒ¥¥e•ÛÜÝÝ…>¾ûî; ù"¦L™‚S§NÏç#22~~~hß¾=V¬X;;;¸¸¸àôéÓ¸yó&œœœpôèQüñLj‹‹Ãþýû!''‡.]ºàíÛ·000@AAÒÓÓñÇàÎ;8sæ œqïÞ=#!!ÖÖÖ äˆöðð€““¼½½ÑºukÁÎÎeee(**‚ŽŽN‹8íÛ·¯ò:?zôhŒ=ºNipøða¡×cÆŒÁ˜1c¨ñÿ×w| iÊŒŒŒ ¨¨ˆ5kÖÀÈȽzõ‚´´4´µµ«£¡¡¶mÛbîܹB+X ‚Jï:‡7¢GÜZ½zõ‚˜˜~øá˜˜˜TY@ @nn.nܸ‘#GBOO X°`¦OŸŽž={BBB½zõúä°/]]]ˆ‹‹ÃÒÒRèÂ¥¬¬ 333¡]»v¥†A!_mmmÈÈÈ`Ñ¢E˜4i‚‚‚P^^Ž¿þú ’’’ÐÓÓÃëׯ?ùYññgc nnnhÓ¦ ÌÌÌ ££ƒÁƒcÁ‚h×®—¯[·n––Æðáᦦ†;w"<<^^^ÈË˃ššÒèÄ(„ÔÏÔ©S?Û´Ï>>>àñxBiK—.ŨQ£*åÕÔÔ„ŒŒ ‚ƒƒ‘››‹îÝ»£wïÞpttDHH²³³Ñ£GJi={öDïÞ½áää„W¯^!++ ººº´–!„|f½zõ‚µµ5€ÏñÕFïÞ½¹}k‹ÏçcÒ¤Iðòò¢“@¨BÈ¿  ""ݺuÃÙ³g±{÷nL:pqqApp0"##±iÓ&xxx@]]áááÈÈÈ€@ à:DÏÑÜ9IDATGŶmÛðþý{.íã xXXŠŠŠ  ''‡òòrn"„ÔÔT$&&ÂÈÈ7n„‚‚¶lÙ‚C‡!''—.]ÂáÇ‘••…ÀÀ@L˜0+wÕªUhÛ¶-.]ºàðgggnzÐW¯^¡¤¤}úôAII BBB0{öìJ·|Û´iàÃÌ*ÅÈ‘#1pà@ 2¶¶¶HMMÅâÅ‹annŽÁƒãĉHMMÅ’%K`nnŽAƒÁÖÖïÞ½ãÒ*†²%''ãÛo¿¥‡u !¤>ÃŠŠŠ111äååA ÀÜÜ[¶lÁÔ©SqêÔ)Ü»w[·nÅÉ“'±xñb¡Ét aee…Ž;"::Û·oÇäÉ“qæÌ¸¹¹aÓ¦MGYY رc&OžŒ³gÏÂÕÕ{öì‘‘–-[´mÛ–Nù"šôB„„Tü𝥥ÅÍ‚„¼¼¼Ji%%%hÛ¶-’’’ ¥¥…·oßBRR½zõ‚··7”””Э[7¼~ý>Œ ÕÖÖæêKHH@ll,äää &&†ŒŒ ¨ªªBJJ ‘‘‘èÑ£äååáããÃí†ÌÌL¨©©ARR‘‘‘’’âÖˆh×®> .mÉ’%àñxÜ:7ñññˆ‹‹ƒ‚‚´´´555¨««W›ÐÐPn&8eeetíÚܰ4ˆŠŠþgš©©)ZµjUe!„º ANN444 **ŠèèhÈÈÈp×þäääJiÞÞÞpwwÇõë×áëëË¥)**¢´´………èÓ§’’’ðöí[ÈÈÈ {÷îð÷÷ðáÎHDDŠŠŠ„òÉÊÊr3<:88 88{÷D¨BHs“““MMMܺu C† üý÷ß8þ yyy !„!wÔŸ={iié+7==+W®DRRœœœ„–7 ¤1Ñ,B>£ÐÐPìܹSh½ŽQ£FUù !„eeeX´hbcc¹¡º ¡uëÖ033CïÞ½©óA¾¨ÿóÀ@ø"}(FIEND®B`‚snd-16.1/pix/rand.png0000644000076400007640000000254611147553270012601 0ustar bilbil‰PNG  IHDRz²`– bKGDÿÿÿ ½§“ pHYs  šœtIME× #œËióIDATxÚíÜÑ’› Ðu'ïÿÊôʇ‚ A÷œ›¶Y£n*Ÿ?ÜBá òë#„ áà‘á°mÛ϶m·m<0¶mû !ü„ª|ëöÀ\Ÿ§p)Hz¦lìû}Ó´=€áO„Cêbï©tÝX.f:³ÿ=uüãxÇ>æ‘«HrïÕøF|>µç“ú| ·‡ÃÞÈjKìÖí¯žO<èY:^¼]i âj£ŽÏãx~£+‰³Á^ži•Ã~¡Ÿ½Vó³Þ@H5ì\0¤Î9þ3.©§þœY•~ÏÖ@ ÂáõZƒèlÛx©»ôÞkXªÂ© „øµ¿géÜRÈ“ÆbÍzF» 5å}îÎöž+]²\H^·Õà…pxt¸ä.¯„ÑÙ¸G®;” žÞãµ|­ûh™ WôÂáõÓÚH¯VWÆiR°5€ý‚ï-U"£ÆXRaröUïqôlvkj°´ô^t¯àYt÷˜Jë4òÜ775Ý…šn*Èû¹k£öëíÒþâ°¸câÂAÝØ…I}S“{o˜ՅnÅ«ÿî.Á̯q¯ëÊ`iMÕrì •*š–y'½Õ’pX¤¹{¬2w6ž+ û,HjÏ»÷¸ºð…ðJÍ ‰ÿ]šVßSžyr—pàÁ°¬™´–ª*Z*—Ò´ù§wÏ…¯ xP´öÛ‘¸Èͽèíî¨`ê¢çî:j¶kËÝ|•©ãÂar¸ó§z|u"ZïjÖš‡ ÝÕ¥¨*Ç#z‘ ‰oMæ*­©Ð4© 9=nseýI®ë1:8vÖVÀ„I}¯EÉusJÏ8ÑÅȡʭTε¥ž?Z»BV哯+f³ôž8âàh*`¡ñÄ®ž‡öX¼úèy<_nŒ£u_Æàe¡4*¤,ÙÞ–lú€p„ á@8€p„ á±dxG8X² º€p„ á@8Â@8€p„ð–lïK¶A·€p„ á@8@8€p¾Â’màá`É6èV€p„ áá@8߇mÛ’ër¯·îø¾Ï•`È-~Ú_ÏmÓ³=°p8|£·V"À5qÛþÔ6²ã]>·³',à‹•C©A¶Rw`ÅnɪÝ%çå¼jüÎøÜÙáåc!„l·âø³š4kÝX8ZºW·Ö`ÔV ?çõŽó€p„°¸-T€pþF8XÎÊ×fË58êõ»¯ýß§|ø!„ÿfhŽÚî†Ô58êõ×¾n*°oϨÀôß!÷HUûk¥×ïÏ•ç©ý´·´ê|ž|òVuÞÿÙ¦žzÄ_¼]éõšj¥t¬šãþ•ÿŸ;×G„ƒåàßûÌÏVÚæ~Ïç^z,Àjc¹Í]ƒ£^Ÿqížt±¶\Baÿ£Ö0,Çq’RÈÝý;ç~6âõ×þÇ%Íèêîxæ3ã;\êï5z͈Ü(.­µÌ.Ãg]r‚¡o+B¨€zÿ>%h‚;…IEND®B`‚snd-16.1/pix/adjustable.png0000644000076400007640000010533011147553266013773 0ustar bilbil‰PNG  IHDRôüòVSsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ Aÿ IDATxÚìwXT×ö÷¿ôŽtP°¨`À5*l×rm1£±ÄX’(ÆÜXc5Ö(Ć7Å(` *š”(‚Š(0ÀÐa†>00œ÷Ì Rf€™ÙÇëþ<Ïgöìù²Ïž³v[k)1 ÀB¡P(Ê;2m …B¡Pþ :ÇC^^^³‚~~~´µ( …Ba)ªo_¸qãz÷î ñµ‹/bðàÁøë¯¿°xñb€›››øu†a ­­5kÖýgâââpçΨªªÂÊÊ ü1ééé¸té´´´Ä×jjj0a >\a:x<Nž< f¯Õ××ÃÄÄË–-“»ŽÈÈHDDD@]]½ÍråååØºu+ÔÔÔä¢ãÅ‹ð÷÷‡¦¦¦Tå«««1cÆ 4H¦:²³³qîÜ9hkk·ë}"‘={öÄ‚ d¢£¢¢nnnÐÕÕípUUUؾ}{§t<~ü÷î݃††F§ÿ'@€… ÂÆÆ¦Ýï}õêüüüš|oeAyy9¾ÿþ{(+K· ZPP€?þø£Åï­,¨®®ÆìÙ³aooßf¹°°0DGGKüÞv‘HkkkÌ;·Åן>}Š   ©¿·² ¦¦[¶lir-##ÞÞÞíþÞv†a ¥¥…µk×JU¸ qqq̃†a˜/^0 Ã0gΜaÒÓÓ™³gÏ2-Áãñ†4žžžÌÏ?ÿÌÄÆÆ2sçÎ%¦ãÞ½{ÌÊ•+›\ûí·ß˜ßÿ]¡:^½zŸ¸¸´û5YsðàAæØ±cË 0€©¨¨›ŽË—/3ß}÷Ôå·mÛÆ\¼xQæ:¢££™?þXaïkÜÜ\fäÈ‘ª£W¯^ÖqâÄ fÿþý2ùŸ¾øâ æöíÛzo`` ³~ýz™ßo[[[F(J]>!!™1c†Ü¾›7ofüüü$–Ûµksúôi¹?˜¥K—¶úº——³cÇ…>;[êס¡¡Ì²eËnOjjj˜Ù³g3/_¾”X¶Ù1-- YYYwwwÀ´iÓpóæML:•®iP( …¢ ÔÕÕaddÔâV¸Ä%÷yóæ‰?uêÀÂÂëׯ§-K¡P( K¡§Ü) …B¡B¡P( 5è …B¡P¨A§P( …B :…B¡P(Ô S( …B¡B¡P( [ :—Ë…››<<111Äu4 ¯¯/Õ÷¾SÝÊÊ ®®®ÒŘUqqq:t(ÌÌÌ P^^NTGc†Џ¸8â:000€ªª*Š‹‹å®ãéÓ§2dˆÄròn£¶ÚC‘zâããáààÐî÷YXX ¬¬¬ÕŸ¼Û£% „çÏŸiÖîY||<±öh ‡vi’—Žööë/^`À€r>XZZ¢¸¸€H{´Ä€˜˜H\G+V¬€§§§| :…B¡P(v@ :…B¡P(Ô S( …B¡B¡P(ŠÔäåå!""‚t …B¡PÞeª««qðàAjÐ) …By×iÍ…t …B¡PÞbbb0f̤§§SƒN¡P(Ê»Jnn.ŠŠŠ ¢¢Òì5ÕŽVZRRÒdú/‰š\#H$jòwYYMµµµ-^¯¯¯W¨žšš‰eÊËË宩¾¾^ê²@nzêêê:Ô§d­G(vêý¥¥¥ÐÔÔTHÿPÄ={û{+‹ï_Gôt¤È£:Û?¤ý_%éaF¡ÏͲ²²”¬û‡´TUU5i£ÖžëŠ´+%%%xýú5´µµQZZÚ¬ŒÓÁ»vöìÙ&ÿøþýûñóÏ?½,Y²jjj¸uëòòòˆéø÷¿ÿ CCÃ&_ŽsçÎ)\‡‹‹ ¬¬¬Z|íÞ½{ÈÊÊ’»eee,[¶Lb¹”””N‡•ÄÂ… ¡­­-UÙêêj\ºtI.:f̘SSÓv¿/00………2ÓáììŒÞ½{wøýÏŸ?Glll§u,]º´Å‡yG&ׯ_ïðûçÍ›}}}™Þ뤤$DGG·ë=S¦LA·nÝäÒ÷*++áëë+±œšš–,Y¢ç”¿¿›Q+/^ …=7Ÿ>}Úb4½Ù³gÃÈÈHáÏq‡¿ÿþ[ü·½½=úôéÓLK‡ zcø|>&Nœ¨ðЦ …B¡PþoòD›€B¡P(jÐ) …B¡PƒN¡P( …t …B¡P(Ô S( …B :…B¡P(jÐ) …B¡PƒN¡P( ¥ªysuu5òòòZÍüB¡P( å0èˆGee%mI …B¡PBC¿R( …ò?ÝC§P( …t …B¡P(Ô S( …B¡B¡P( 5è …B¡PƒN¡P( …t …B¡P(ò4è"‘uuuÍ Òhp …B¡°—f‘â¼¼¼Ð»woŒ?^|-"" 8p ÆŒˆ¿^^^@Ðä…B¡P(ùЯ_?hii57èþþþHMMÅÈ‘#1tèP”””4)ôúõkL›6 ¡¡¡bƒÞ¸LEEtttðóÏ?·) 55666m–),,„ºº:ºtéÒ麆AZZšÄrèÖ­ÔÔÔZ-SRR‘HccãNë’¶\NN ›Ý´ŽÔUSSƒ‚‚tïÞ½Óu@SSúúú®«¾¾ÖÖÖm–ãp8°²²‚ªjëÑŠù|>†‘‘‘ÂîQvv6Œ¡©©Ù麪««QTT++«NוŸŸmmmèééuº.‘H„ÌÌLôîÝ»ÍréééèÑ£TTTZ-Ããñ ¤¤CCC…Ý#.— SSShhhtº.@KKËNו——]]]èêêvº®ºº:dgg£gÏžm–KKKCïÞ½¡¤¤Ôj™ââb¨¨¨ÀÀÀ@a÷(++ æææPWWït]UUU())A·nÝ:]Wnn.ôõõ¡££Óéºjkk‘››‹=zȤ]>Üü;ɼ…§§'säȆaf̘1 Ã0LLL sðàA&&&†i Çœ={–‘DC½mqÿþ}&>>^&u‰D"ÆÝÝ]b¹?ÿü“)--m³Lll,&]Ò–óóóc233eRWaa!sþüy™ÔÌ$$$Ȥ.¡PÈ?~\b¹ÿþ÷¿Leee›ebbb˜‡*ô]¾|™ÉÉÉ‘I]yyyÌ_ý%“º‚‚‚˜—/_ʤ.@ÀxxxH,wòäI¦ºººÍ2‘‘‘Ltt´Bï‘··7“ŸŸ/“º¸\.ããã#“º˜””™ÔU^^ÎüñÇË=z”©­­m³Lxx8óøñc…Þ#///¦¨¨H&uedd0W®\‘I]7nÜ`ÒÒÒdRWII sæÌ‰åÜÜܘŽÒlº³bÅ ñïááá€áÇcøðá^"pvv–XÆÖÖVâlGÚº”””0nÜ8™,oXYY¡¶¶V&º¤-7dȉ3iÑÑÑ“““LtõíÛW∵=m! £Fjszöì‰úúz…Þ#Yö}=== :T&uÙÙÙI\A‘UUUŒ=Zb¹Ñ£G·¹‚½zõjsv(¶wtt”8 –ö3»téÖõ Œ9Rb¹±cÇBY¹í³ÐÖÖÖõ;99Éì™bhhˆÁƒËDûÀ%®øI«KSSS*;Ú›%»»&Ò<¬$-7¶§.%%%©¾|Ò`ff&3]Ò–ëÓ§ÌÚ^KK ýû÷—‰.IKFím i¿X’077Wø=’eß×ÖÖF¿~ýdR—¤¥×öôAƒI,'ÍC´k×® o{iÚTÚÏÔÕÕ…­­-ëúŽšššTß‘!C†H,#i©ZúíììdV—žžžÄ­&i‘´Ø]°··—kß‘I¶5‘H„ÒÒR©F2l„Çã¡K—.mîý±™ÂÂB˜šš¾“Ú†Aqq1LLLÞIý%%%ÐÑÑ‘¸z@ûÕÿ6eeeÐÐи·OÛžê—åÎ4ÆåË—!‰ ¢¢###ÔÖÖâôéÓ¨©©y§ÁÈÈè5æÞéN©¤¤ôÎs000xgù»ÞwÞuýúúúï¬1§}‡ ¡¡¡Í®q¹\\½zõõõ7èÞÞÞ077GBB‚øZ`` \\\àáá …B¡P(²ãâŋͮùùùAYY™™™²‰wçÎÚÒ‰lÛ¶ G.u—””`ݺuM®effbÓ¦Mðöö¦ß<_~ù¥Lëܹs'vî܉€€…þ/\.®®®Ø¼y3 äö9ÕÕÕøâ‹/Ødrãîî.÷ÿq÷îÝØµk|||ÑÑÑøî»ï°mÛ6…BÚ¡ßöà‹ŠŠðäÉ“f¯wØ /X°ÙÙÙ°³³CLL `Ê”)¸sçN““òJÏŸ?Gee¥øï›7obïÞ½R¿ìر­¾& ›uð=zÀÎδñ¥l³ 1oÞ¼v×éåå…+V€ÇãIýžI“&uÚ …‡‡C[[#FŒŸÏ—[›:tøõ×_Q\\ ?~)))î»ÒpýúucëÖ­8}ú48V­Z…Ÿ~ú =zô€››íÐï qqq())ARR`Ö¬Y¨©©y§££•ZYYaÉ’%€;vxsJ÷‹/¾ -þ#pêÔ)Ô××cèС˜0anܸÂÂBTUU‰Ëåçç#>>„ŸŸìííaoo]»vá»ï¾ÃéÓ§Q[[‹úúz¬[·~~~HLLÄ¥K—°hÑ"0 oooÁÈÈS§NEMM Ο?555,Z´¨E}7nÜÀ«W¯0vìXŒ1h8Ú¥Kðx<øøø@KK ={öÄܹs†ØØX`äÈ‘¸qã6oÞŒœœ„„„`Ù²e¸pኋ‹add„ùóçãÌ™3€ÒÒRlذªªªððð@mm­xV\XX(Öeii‰}ûöaÇŽˆ‹‹—ËÅ´iÓàéé @€^½zaèС ŲeËàëë‹ÂÊÊ ¿ÿþ;ºté‚Õ«WKµ'+àáá!ö ˆ‹‹Cvv6fΜ‰S§Naîܹ8}ú4âââ„éÓ§Ã×׃ BÿþýÅ÷(77W\§¹¹9|}}QVV†˜˜,[¶ ÈÛÅØØŸ~ú)ž?Ž[·n¡¶¶6lÀÝ»w‘OOO¬]»píÚ5¼~ýãÇǰaÃðÛo¿ÁÀÀyyyX±bE³Sع¹¹ Bnn./^Œ~ýúáØ±c044—ËÅŒ30`Àœ?ÙÙÙX¸p!LLLpýúuäææâÛo¿•êdôŸþ‰ôôtàðáÃØ³gtttpóæÍVßsîÜ9$&&ÂÇÇ .Ã0M´HDäíû÷vxnšûý`ãÆâß¼ lllÄ}ˆ&g¡È”ÌÌLq'Û²e "##áããƒE‹5y蘛›ÃÖÖxðàÒÓÓžžžHOOÇ;wààà===”••aéÒ¥Ð××êúúz$%%ÁÁÁ;wî„@ @UUf̘°°05ÓöðáCüöÛoèß¿?6lØ€¬¬,<{ö ñññˆGNN._¾ eee888 ¸¸¯^½Â¡C‡°fÍøøø€ÃáÀËË uuuÈÏÏÇÍ›7!‰’’üøãPVVFdd$ °páBá»ï¾CII ”••ñÅ_ ¤¤Dü¹ñññ¨®®†§§'ñøñc<|ø|><ظq#ôõõqîÜ9à÷߇‘‘/^ ###p8üòË/RÝ£o¿ý}ûö»¶%''ãáÇbcÊçó±råJXXX`úôé€{÷î‰W:<==QYYÙDyy9–-[}}}|üñÇÞD/kh—ï¿ÿùùùØ´iV¯^>úÅÅŘ;w. Å«zááá¸víÖ®]‹;v ''(((ÀgŸ}Ö,Š%ðÆnúôé6l˜Ø½NYYáááX½z5ª««áããƒÄÄD¬\¹Ÿ}öJKK±oß>>|qqq¸té’ܾŸ}öôõõ±páBÀåË—ñòåK±‘H$±Ž9sæÀØØüñÊËËŃ‹Ÿ~ú©É9&Êû*mŠ,Ù·ofΜ)j’nݺAWWRÕÑ¿:t•••‡]3óóçÏ£¾¾â@†††022Bï޽ńÆdggÃÆÆVVV8uêLMM1kÖ¬&eúô郗/_<<<0xð`hiiA[[»ÕЧ-iiÔ4ø,§¦¦bâĉèÝ»7fÏž KKËÇîÚµ ÐÐÐÀ±cÇ`nn.Áihhˆ¹sçb„ X´hÌÍÍ‘ššŠ>ø£F’:QC8dI¡=ÛÂÈÈsæÌi³Ì¹sç¼ñPQQAuu5 [ÕÊåraee===0 ƒŠŠ q[J£¢kkkÁÈÈwîܵµ5ÌÍÍQXXˆúúz¡®®®Ír]].\¸€)S¦ [·n˜}ú€ÃáˆÛÅÂÂü1¶mÛ†åË—ãùóçÞDÆÚ¿?vïÞùóç#77?þø#œÑ§OhiiIt TSSk’ó@CC£IÄÉ 6àÁƒpuuÅöíÛ¡¡¡!Ž£®¥¥Õj q¡PˆM›6!99ð믿â×_ÅôéÓagg‡{÷îáæÍ›xõêNŸ>ݪ>GGGlÙ²çÎÆ pïÞ=¸ººâ‡~hõ‹ˆˆÀO?ýÔä¾íر“&M‚µµ5RRRðÕW_!00›7o¦ŠlËP(íáû￯GáÀï„îõë×cÖ¬Yâeh¶…ŠŠ Lž|ñññâk%%%M~‚¼ë4D'#H$j Šo»˜‘B(‚ »CuuuR‘7µµµÄu°%³"[úGee%í,ì¬x®WUUÉõ¹ÞÌ <¸ÙÆÇÇcÞ¼yxúô©øÚõë×Å?/^ĸqã:%¤qL’øûûƒËå׌èèhâ:vïÞÍŠS͇‚@ ®cëÖ­ãvˆa°yóf±ß9IvíÚÅŠïíš5kˆ?Cjkk1wîÜVãã+’†Å$)++ÃìÙ³‰p&Nœ(·ÄPíÑ1dÈff¹ôÔÔT¤¥¥/^ àM’‹ˆˆôèÑC\nùòå⟆rfÄ¢íÁöö¨¨¨‡¶%=ëñ÷÷'®ƒËåÂÓÓ“¸Ž/^àÊ•+ÄuDEE!88˜¸Žk×®‰ƒöÄÓÓ“™8÷îÝ‹G×±oß>¹¯v63èÎÎΘ9s&ˆCNœ8ãÇÇ„ þç GCR {Ú#33Swœ$999¸}û6+î V‘Ž=ÚbluEãææÆŠ-¿#GŽˆCý’d÷îÝÄ3^áÖ­[èÒ¥ QáááÈËË“Kl†öpåÊTVVbâĉŠ5è&&&033€&±“ÛGù]… Y‹Š‹‹abbŠ)ØÉÉÉ-&[!a8ØÐ?‚‚‚0zôhâ«>l1¹¢Y‰‰‰>|8QÐÕÕ…ƒƒQ/^ÄÔ©SaddDLC}}=6mÚ„ü‘ès¬¢¢ÇŽÃÆ›„V4©©©8sæ öìÙ#÷Ï¢§ÜY –T/]ºÔb¼ó÷±-êëëÁçó‰>(   ùùùéTØÎ"‰pàÀlݺJJJÄtðx<Ü»wOœj•^^^˜9s&Ñ•¬ÒÒRüòË/8pàÑ-¡°°0¤¥¥aùòå ûLšœ¥€è^Kã‡6ˆ‰‰‹‹ Q <"‘ˆ¸AÏÎÎÆ°aȯTèéé‰Ï¸âöíÛpqq!¾îîîNü4wxx8ŒaooOTÇîÝ»±uëÖ&){MJJ üüüˆ»¹ž>}...èÕ«ÑAņ §Ð¡7âåË—°³³£ Á"ز´ëëëK|öƒÁƒt?~_~ù%ñ¶ptt$jÀD"Ž;†M›6m‹àà`TTT`îܹD'CGŽÁæÍ›²WÜiii¸yó&¾úê+¢÷ä믿ÆÑ£G¾jC :¥E"""0tèPhkkÕÁår‰{XbÆŒÄ¿?fÍšETógÏ`nnN|•àСCøæ›o ¬LîMMM 2„h[ìÛ·[·n%>¨PSSƒ³³3QóçÏ'“àâÅ‹èÝ»7W¹N o¹\.üüüXÁKV°Á-éñãÇÄ÷'«««¡¡¡At_°¶¶ÁÁÁ8~ü8þóŸÿÓ‘››‹®]»½ùùùHOO'~¦aï޽ؾ};ñÙ¹ŠŠ ñïÈþýû±wï^¢nÞ¼‰~ýúÁÚÚšè3óܹsØ¿?ѶøöÛoñÃ?=S‘••„……ùüN o­¬¬àêꊵk×ÊDL@@qcʆÈWIIIèß¿ÿ{?3f žžžX¹rå{?;çñxHOOÇ|ðÞß°°0aàÀÄ4ÔÔÔàÔ©Sظq#Ѷøõ×_±páBôéÓ‡˜†‡¢¼¼Ó¦M#Ú¤Oø³fÉaqÈY yüüü0þ|¢¼½½±dÉ¢ŠŠŠ0tèPâþÖwïÞ%~@ñìÙ³X²d ÔÕÕ‰i¨®®F\\ñÈ_û÷ïÇ–-[ˆjpwwÇ´iÓˆºËeee!::šèù’ÚÚZ8p®®®D]ööïßÅ‹7 ‘®hè)wJ3²‘>ÅÌåraiiITÃË—/Q^^555b„B!âââˆúÀ‹D"ܹsG%z?Ž9‚U«VAOOèìÜÔÔ”èÚššœ?žh"‘H„uëÖÁÃÃèY†}ûöaöìÙDïÇýû÷ñêÕ+üñÇD¿Ô 7‚ ßÂÂÂ0nÜ8¢©þÒÒÒPSSCüÄÿŸþ‰ôôt¢Nž<‰¯¿þš¨†3gÎÍ 333¢±Êù|>|}}‰±ÚÚZ9r»wï&z¾dïÞ½øöÛo‰4CCC1uêT¢Ûƒ‘‘‘HJJÂŽ;ˆi(..ƾ}ûpéÒ%¢} §Ü›À†Œ^¯^½bE‚Ê›YPee%ñp¯lpÝcÃöÇ­[·ˆï‘FGGCOOh8Ѽ¼<ãÓO?%¦¡ªª ;vì ª¡¸¸'Nœ jÌWkÖ¬!þœ ½úôéóÞ‡]‹‹ÃСC‰j¸yó&þõ¯ÕPZZм¼<¢{”@4Û\MM bbb0nÜ8¢÷ƒ ‡á>Œo¾ù†¨†/¿üG%º%æêêŠ;wÂÐÐè ÓÑÑ‘è Á™3g ¯¯Oü¼5è­0xð`<}ú”Øç—••A__Ÿh„††÷'eƒ«˜››\]]‰jøçŸ0tèP¢K«!!!1éOí IDATbÑ€6·o߆ Ñ“ÔlȨ ¢ž?ŸÏÇ”)SˆiHHH@pp0Ñ >‘‘‘¸wï~üñGÖØ/º‡Î2Μ9ƒ‡‚Çãáõë×3fÌ{Ùžžžðññ!ª¡  €xOOO9r„¨†}ûöáÌ™3Ä>_(âäÉ“Ä}¾÷ìÙCô^ˆD"¸¹¹á»ï¾#¦¡´´Ç'‹à‹/¾€ŸŸ±Ï¯¨¨ÀÎ;áååŪç&¡7ÂØØæææ¬Ðb``@$¹H$Bdd$ÆŽ 044ŸÏW¨†¢¢"hkkRwïÞ=Lš4‰Øçs80 C4&uzz:”””ˆj‡‰‰ ÑCšÄ3ª=yò ÃÀÑÑ‘˜†Ë—/£oß¾D·ävìØõë×£[·nÄ4ìÚµ «W¯&¾ŠH z+ðù|DGG£oß¾Ä4ÔÕÕAEE…èIÉêêj…Bñ²¿ŠŠ êêênD ›ìÏ9::"66VaΞ=‹Ï>û¬Ùu…± ÅÈ‘#¡©©Ùì5É]ƒ»»{›KÔÕÕ! åªAšÐ»òÔ!‰°ÿ~©2ªÉëû" ±råJ©ƒ–())a™j(,,ÄÍ›7[ü^(ŠgÏžáùóçí> ©ªªŠÚÚZ™h€P(ļyóÚý^ˆD"¹µO‡—ÜÝÜÜÄ¿ 6¹Ö^ÊËËOÌ]K(Šg! Ã`Íš5 ŸäææbΜ9ÐÕÕ_c K©úâÅ‹6O^¸piiirÝç/..n–hâƒ>@ll¬xåΟ?‡#Ÿä””|þùç-ôׯ_7»ž——‡?þøC¦Z’““ñÃ?´ºšÔšAÏÍÍÅÞ½{e´®®®Í½Ò+VàÌ™3X³fM«ÄãÇwê—†††ÄÄ#óçχŸŸŸÄ3‡‚H$jW‘ÒÒRÌ;WªŒj&L@HHˆTo<†a¤ Ô“––†S§NIÔÇÞÞ‰‰‰RÿwïÞÅ“'OÚ¬?)) îîîíš»¸¸àîÝ»íÊooïcP¼zõ çÏŸo÷¤gΜ9¸qãF»·+JKKqôèÑ&Ïd.—Ûá­—Q£F!**ªC+okY²dI³,”6è¿8|>>>>:@äææ†qãÆ?„äææ†ap÷î]œ:uŠøÊA}}=~ûí·ˆ"èÞ½;¢¢¢Ä3•£GâæÍ›066&Þ.þþþزe‹B— õôô››Û캧§'œœœ0}út…è>|8Ž;ÖâkžžžùäVhaCúŽ9Š-´ºº:¸»»cóæÍ¬Ð²|ùrøúú×’‘‘Ó§Oãìٳĵ$''#** —.]’ú=¬š¡“ÎTÊÊÊD3½Í©S§0|øpVh©©©i—»¼xôè† ÆŠ6¹víšD—*E!¿¶"µlذ¸ŽÊÊJœ:uŠxüuàˇÃÁäÉ“Y±z¢¢¢ÂŠñÏ?ÿŒ5kÖ?”בpÙ²e000 ®ÅÝÝžžž-Æ¡`½Ag†Ò2999D#35†Ãá\Ö6dBÞ¸Žr8Vìå'&&‚ÏçMÜÑxÕbüøñ¬È„uâÄ ¬\¹²]hy àéé©ïI 22ÿþ÷¿‰kyøð! XqXqûöí˜4iR»û-ÝCoe–N2‰ŒŒÄèÑ£Y¡%..ŽxÖ­¸\®T‡UäMrr2LMMYaDCCC1jÔ(©ƒ È“ØØXVœšÎËËÓ'OX1#¾{÷.z÷î âZ6oÞŒŸþY.Á¡ÚËW_}ÕjlE?ßÒÒÒ:”ÁôV ñ ž>}Š!C†°¢=Ø®±Á`ƒ–þùÝ»wgEþøc¢:†Á–-[ðŸÿü§Y’EsçÎDDDtzÅ‚t–Æ՜œèêê²bßš-®s·o߯¤I“ˆ‡…Þ,²ádîX±Ä]VV† .°"÷ñãDZvíZâF4>>YYYăÕ××cË–-ؾ};ñ¥+W® K—.pqq!ªƒÇãáÏ?ÿĦM›:ý<¡òÎPRR‚ììl 0€¸–ÄÄDVlͰ)[¸xyyañâÅPSS#ªƒÃá %%…øŠ_]]víÚ…Í›7_e;wîìì숯âdeeÁ××—uÜÜÜ0sæLôéÓ§ÓuÑHq,†-®YlÑR[[‹ªª*téÒ…¸–¿ÿþ›1°Y؆-®j<8þ<ñ69vìV­ZEÎÖÖÖ¬0èjjj033#®ã¯¿þ‚qaaa1bñ3\.ñññ°´´$ª£¾¾nnn˜4iñ{Ö,fÞÞÞpppÀÀ‰êHLLDqq1ÆGTGaa!ÜÝݱ{÷nâ÷æàÁƒpww—éà“.¹S$òüùs 4ˆ¸âX`K²6èøçŸ0pà@â3¯¸¸8èëëÃÉɉ¨Ž´´4hii:–ŸŸ3gÎàúõëDuTVVâÀؾ};ñ-™ü›7o&¾m÷Ã?`ôèÑ2Ÿ°ÑCq-À†SÔTGsØà®¼ñ< ½¤ ,`ÅJÁ“'O°~ýzâ:"##YáOüäÉVl effbΜ9ÄZ·nÝ‚¥¥%qϘ˜TUUIŠT^$%%!!!A.ƒñf=66IIIM®ñx*++ammMTGii)”••‰ð­©©AYYñ•¤ììlÔ××£{÷îDuÏçLWQQºº:™¤gýã?š¹º©@ïÞ½annTWW£¤¤À›øÝ­¹+5^RâóùPWW—x¢óÌ™3¾EEEÁÀÀ@âR¢4u1 ƒsçÎaùòåm–óõõÅôéÓÛ\šJHH@UU•DÿIitI[îÖ­[2dˆÄ}iêâóù •x²Sšº"""`ff†¾}ûvº®ºº:üõ×_Xºti›å.]º„ÿûßmÎŒŸ>}Šºº:‰³4YÞ£ÀÀ@ 6Lâa=iê***BTT”D¿riê …•••Ä™³4uÕÔÔàÊ•+øä“OÚ,çíí>ú¨Í}Ò'Ož@YY »Gÿý7>üðCwº®üü|ÄÆÆJÌš&M]<@ïÞ½%¦–¦®ªª*øûûKŒ¾æåå…%K–´90~ôè455%ž›‘å=ºví&L˜ ÑÐISWNNž?Ž©S§vº®»wï¢_¿~$ÒÔU^^ŽÛ·oKL·,m»¶4ˆVÐäaTPP€ššš&…–/_Þ¦q‰³gÏžËäææÂÀÀ@&uÕ××£W¯^Ë£Gmžä®¨¨@UU•LtI[®¡Œ$ƒnhh(±®.]º ##C&ú¹\.ÌÌÌdRWmm-Œ%–k¸môÒÒRÔÕÕ)ô™ššJ•qMšºtuu‘››+ý°²²’XNš¾SSS#Õ÷¨¡L[ÇãAYYYf÷Hý º$ti>SKK ÅÅÅ2ÑoffKKK™ÔÕðl’¶-Ú2è………ÐÔÔ”Iß‘Vƒ.I]šºÔÕÕQ^^.ý Ÿ'É K£«A“´mÑ!Àãñ˜³gÏ2ï*þù'SZZúÎê?räÈ;«](2Çgõ_¾|™ÉÉÉ¡}‡êo7LJJ m{ª_fÈä”»†††LÂÖ‘ÂÖÖ–x˜ÈÎð.g‡SVVfEÚÏŽ"iÕ€öª¿5¬¬¬Xßöÿ”†a:òÆúúzTUU5Ûw.++{§;)…B¡P(l¤¥äT"‘ÕÕÕÐÑÑé¸úõë×qúôidffН=yò/^Dpp0my …B¡PdÈš5kš]óõõÅÉ“'QTTÔqƒž™™ ðùü&צM›†ÄÄDÚò”÷šÇË-nC}}=îÝ»×äŸÏÇõë×ß™ïÞ;wh'¡PÚÉСC›]ËËËCŸ>}PQQÑqƒnccƒèèh˜˜˜`ìØ±âk~~~-~(…ò>qøða$''‹ÿÎÈÈhf„ÛÂÓÓ³ÕׄB!¾üòË&×´µµÁåráåå%÷ÿ-"")))ízϳgÏðøñã6g ¥mâââ‡èèh|ûí·ÞœÅHLL„¾¾~Çc¹Ïš5Kì/4h+b~S(Š"77555066†žžÊËËÅq¨­­‡ÃAqq±8fƒŽŽŽ8˜R~~>TTTн{wäææbçΘ:uª8á ŸÏGii)tttÄAKòó󡪪 ccchhhÀÔÔ\.Wü¹ååå(..†©©i‹pD"²²²¼qk444„@ @~~~-fff¨¯¯ǃ¶¶6¼½½1`ÀôìÙ¨­­Evv6ôôôÄ®a¹¹¹ …èÙ³'üýýQ^^;;;±–ââbÔÕÕµ´¨q@£Æm–••‘HsssÔÕÕ‰ƒ/5Öù¶ å…Æ‘îFŽ MüÚir ¥ƒäååÁÝÝNNNðôôÄ… °aÃÌš5«É켦¦<@^^âââ0xð`,^¼cÇŽEDDV­Z…µk×"66Ÿ~ú)òóó! ‘””$6è{öìÁ˜1cpôèQx{{ƒÏçãþýûøû￱gÏžfÒx<6lØ€)S¦ ,, ‡ÆåË—QYY ŸM›6áĉ(((€ŽŽªªª ¦¦†Ÿ~ú fffˆŠŠÂÞ½{‘––†«W¯ÂÐÐÖÖÖ˜1c²²² PRRÔÕÕ!((!!!øâ‹/  Å3x555Lœ8›7oÆÍ›7±oß>8::bÈ!¸páÌÍÍ‘œœ >^|­¤¤¤ÉOyyù;ñ×ÔÔPTG«”••Ñö`™ŽúúzTTTÐþAûG‹0 ÃûCº43èƒF]]]3ƒ>oÞ<<}úT|íúõë⟋/ŠýM[£°° ~òäIVè˜7o+tìÙ³õõõÄ û÷ï'ÞB¡Æ £ýãÿ¨¬¬ÄÂ… QZZJTG~~>æÎ‹ªª*¢:ŠŠŠ0þüf¡}IÙ³g‹ƒý‚ËåbãÆ((( ª###+W®#"Çøqãä–”©C=55iii€Å‹xQ*""=zô—[¾|¹ø§¡\[x{{@•——³&˲b"""‚øƒ233\.‡¨Žôôt,Z´111Du}ðàÁvtŠbf“&MbÅjÁÀ‰ÏÓÓÓ¡««K|„““ƒ5kÖŸqÄÅÅaÇŽDuðù|båÊ•âôȤHIIÁ¬Y³——Gl??66033ƒ±±1^½zEDGQQTTT```€Ñ£G#22’ˆŽ€€¬X±ˆÎÒïÞ½‹É“'×qæÌq{Ìœ9“سŒtBLž<™ø~~bb"êëë‘””D¼=lllššJ|¥à›o¾!®ƒ íQSSƒªª* 4Hœu¾¾¾øè£`dd$N>C‚üü|˜ššB[[šššÄÆ]¼xK–,tëÖ 999Dtܺu ¶¶¶€3f[þoÈ ¼Ù. …¢c¥åææ¢´´ýû÷ 6 /_¾$â™ñÞt’£ÚÆxxx׌)S¦×QWWUUšÉ?~Œîݻꪪ¨­­%¢#::Zœ0ÅÑÑQœ«œÄŒÔÄİnÝ:DGGÑqòäI¬[·N¬ƒ„·ŒP(D\\œx»níÚµDž#B¡ÑÑÑbÏ&ܽ{Wá:"##aggCCCÀСC‘””¤ðCœaaaprr‚–– {÷î`\.—ty£ªªÚÌ-¤—uÙBmm-è ´iÓ ¤¤$¾¶víZ…¶îܹƒ©S§6¹¶eË"‡Ié’;!Øà¶Æ&œœœ@ÌEªÁpèëëCII‰Ø^mjj*lllˆßììlXZZ²â{boo˜4i‘NZZTUUÅn»C† Aff&ø|¾Bu\¹róçÏÿ­­­ ---)TGãeî&Nœˆû÷ï+Lƒ@ @||€Ø=iy¯Û¤ÁUÌÈÈЫW/())«¢¢…/w·tžà“O>Qhi‘H„ââbq°­Æ“Ežbni™»%K–(¤M*++ñâÅ >¼Å×mllpåʹëxùò% Э[·_·°°€ÜÝqïß¿ßlïümÆŒ£Ð8ïÕ:Ã0 …¬ÑÖ„5lÁÔÔ”H›ˆD"())AYùÍסÁBÑZjjj ¡¡!þ»áwEû^·´´;räH…nÍ$''CEE}úôirÝÌÌL¡ËÿÝÕÞfÙ²e8wîqŠòGÏÍÍEuu5zõêÕâë£FBRR’ÜC'bÆŒ­¾®®®Ž?üP®‡ôD"RSS›ö›/¿ü§NRØÙ ÷Ê —””àÒ¥KÔr¾Åĉ~b·Æ~Ƥˆ…¥¥%,,,Äí¥°e̶Ú$9ÑÑÑÍB+Ú 7ähd5 ¥¥…)S¦(ì gNNN«3A+++…ÝyõꌌŒZÝ[¸p!|||ä®ÃÃãÕAEÃ@ØÅÅEî‘'ÛÜ4àâ₹Ҁa±|kôéÓÚÚÚxöì5èùÑx9³k×®¸yó&-ù´Rþ?ŠZNm !"šŠŠJ“뺺º °èW-¹F5˜+*NÀÕ«W[Me«¨-¢‚‚èëëCSS³Õ2ŠˆÖÖÖà¦)S¦È5fdd$FÕê¾u|ðRSSåæ~Ú8bŸ$æÏŸ¯­ˆ÷Ò “tb­º[bÑ¢Eïõ JJJ ñqqqq8p ØU¬ñl”a……mkÏXQntÉÉÉèׯ_«¯«©©¡k×®ÈÌÌ”«iŽvíÚ¹¹¹rÕ…Q£FµYfüøñ ‘›†»wïbÒ¤I :ðÆ¥O‡ãÊËË‘ ±-9r$âãã²uöÞtggg…žN}›êêj|ðÁMöJ)oÐÓÓCyy¹Â?×ÍÍ­™ Œ««+ÜÝݪãÉ“'øàƒš\ëß¿?RSS¶-7BE¹¯ „‡‡·=ÐØØeeero“ØØØ6³ª««£wïÞHNN–›†ÒÒRp¹\ 0 Ír7n”k=vì¾úê+©ÊŽ11112×  †I“&IU^^ˆBBB0räÈ6WLcccƒŠŠ äååQƒ.KTUUannNTÃÇ¡ªª ccc8::‹HÆ YKž-´4#íÙ³'¸\®ÂÕ´5dCntà;¤H$’ûéÿ¶\´·¯qEE*++%>·455Ñ·o_<}ú”X[40uêT¹ì£'%%A[[[±Ovvvàóù27¤AAA˜>}z»Þ³mÛ6œ?žtYwJ¶uuu…–h EïÓ6évéÒ¥É5kkkb9Iâçç×êHCèÓ÷…·ýàI!M^y÷WiÛBUUFFFr;@©®®ÞÌã 5,X???™khϾuÓ§OGPPLûDJJJ» úÔ©Sñ÷ßSƒ.ë!åMpŽ»wïŠ r{ÛM PüiêÂÂB¤§§7ó­]¾|9Ξ=«0999PWWoñµ)S¦($áDJJ ”””Äi1ßfÒ¤I—û^ 4qäåñ,&&666=0ú÷ï¡P(·øeee-”i ye_»uëìììšy´†®®.F%ÓÃq555xúôi«>ð­±~ýzü÷¿ÿ•Y"i|Ï[cæÌ™rxÓ᜕nnnâß ›\k ÇCAA.\¸}žP(DQQŒŒŒ¤Þ»x›‚ºººVµJ³ì³k×.üòË/J¢‘››‹Ù³gzôè   v‡KÌÌÌÄÚµkÑ·o_\¸piiií ŸÊ0 lmmÅŸTUUÑ¥K—v· ‡Ã¿G$aýúõ튕Ôlªk×®ˆ‰‰‘:ˆIzz:¶lÙÒäômPP"##¥Š‚W]]>}ú4Kߪ®®ŽnݺIÕ& ÃÀÒÒ²ÅÓúß|óTK„ׯ_ou™rüøñ8|ø°D-¯^½Â¯¿þÚlÕ£Á@]½z]»vmõý¥¥¥˜?~«n555,\¸ÇoµL]]ìììÚôÞµk´´´ZM™‚´ù¿:99áöíÛ­¶IRRŽ;ÖfZÞׯ_ãøñãèÙ³g‹½yóæI<|¥¢¢"Õ8\nCßš5k–ÄýoàÍéíÐÐPq Îêëë¥^¡±±±¹¹y³6ÑÓÓêU«¤ª£¶¶ÇorËå¶fµ%”””ðŸÿüß|ó8 ‡Ã««k«>ì-‘œœŒK—.¡K—.¨­­Å¸qãлwïv=£LLL0uêTüðð°°€©©i‡V<<}ʤW¯^Ljj*3qâDb®_¿Îlܸ‘a†ùꫯbmÑ€P(dlmm®ÁÓÓ“ùù矛\;pàsüøq…i¨®®fúõë'±äÍ¡C‡˜£G¶øÚ_ýÅlݺUîrrr˜Q£Fµúzqq13a†ÏçËUÇöíÛooï6Ëxyy1;v웆„„fÍš5R•]°`óèÑ#¹èpvvf8ŽTe³²²˜Ï>ûLæ.^¼ÈlÛ¶­]ïY´h%·g–´ÈúyìØ1æàÁƒzï˜1c˜¬¬¬V_§~èï Š;ÙÖrcCxÅøøx888°¢-Ο?¥K—*LƒŠŠ ºwïÞ,/µ¢]ÛêcÕËèééµz)99YšSžXZZJüŽøûûËõþôíÛ त¤Íryyy(((À Aƒä¢ÃÅÅÁÁÁR•õôô”úð[{1bž>}Ú®ôÈ-E,ì,9°'ëïqG=­‚ƒƒaggת;'@˼ÓÔÕÕ!((ˆ˜?¹£££x» µä$x;[˜¼QUU…­­-^¾|Ùäzee%´µµ¦£­ ŠÊj§¯¯CCCdddÕ1fÌ<|ø°Õ×E"D"‘\ÝGÕÔÔP\\,ñ| ŸÏ‡ŽŽŽÜ´´Ç€„‡‡7KD# ¬­­!¤ö•ÇØ±ce®£#‡äÚʨÖˆÌÌÌv{8ýúë¯Ø¾}{›e¨Ao'3fÌÀ©S§Ú%QÇ!C””¤ðxçÒ­Ð~Ò·o_¤¤¤´hD555;´g÷®® <¸M’üü|äååÉÅx5fÅŠÝÚäqÐÉÉ ©©©R…w~ýúµÔ§Ù;ÒÒ “×êÖÈ‘#‘ uÄCIÕÑÀ›³B:::Í’Qƒ.ƒ‘æZ K©ŒQ]]ÍŠìu¤133Cqq±ØO›Ãá´ëର··j ­ð¥Š$11â,nòF‘¡.Û¢­0¤‰‰‰ q´²²’8CÏÈÈhñ`ž¬ÐÒÒ‚½½½Ä÷—.]¢E‹ä¦cæÌ™RG”×wÇÜÜúúú-|[¢3§ÚÛ¢½aƒKKK¡ªª*qÅôw^½z¡´´TîY$Ñx‰°%4ŸÖ +]{ëÊl"‘¨ÍJ‘mÇãÁÌÌLÃÍ|ëÖ-¼öÚkŒÙaoo¯u ‹ÅH$Z•ýè`Ô¨QHLLÔznÛ¶mŒün,--áïï§OŸj=Ÿ€Ñ£GëUø3Ö$ëðáÃ:ÏWVV¢¾¾^§ ²±X·n6nÜ…B¡³MBBÆOÿ€^RR‚mÛ¶Ñ¢Ü???8991þbâ ›i|LÔ‚¦z ”+ô¸¸8ÆV^-±°°@Ÿ>}tæ£3ň#pëÖ-µcL íhóX(ß[L?¯Ó¦MÃ;wÔŽ]¿~#Gޤ}ðR†´´4Ê}Ïž=ƒ……¼¼¼±C×êX.—#)) cÆŒaÄ}åU™ò~2YYY:Ýîàóù”· ^i@÷õõETTc7nnnŒÍf9ÈqvvFçαiÓ&ZD ^å¥Í-÷é*ÖAúƒ65…››^¼xàeµ®9sæ°:¹am1§OŸFdd$£vtéÒE#e‹©Ô9%^^^pssCff¦†‡Çã1æ= CNNŽ*Þ¤¥';; `ÄŽˆˆ\¾|Yë¹ØØXL›6;æÎ«3ÆbëÖ­X³f õß?7,uLè®6E333XZZ¢¬¬¬]l‡”––ÂÁÁQ•8](ݽlÐ2Ò½ººšµ,€–J‚lÅ{ <¨®®ð²€M`` c‘öJ&Nœ¨áɼzõ*cyJ´EþïÙ³‡RJ”1'{4öÑézÕǤI“píÚ5Jl=‚ŸŸcº º¤ye2®]»¦ªŠÉ è4ÀV©Qm/mnÿ\s@···gm@···Gcc#êêê “ÉXɇÔËhÖÖÖÂÙÙ™;ÂÂÂðàÁì阙™A¡P¨ö(ÙÐamm­ €*--…¹¹9<==µcüøñHHHPý»©© YYYŒ’jË¿xñ"^ýuF¯¡¡¡øã?ÔŽ²gm BCCñüùs ]‘Û·o£OŸ>y¥¹Ý@fÏžU«Vaذa¬ÛÒ–2€UÚƒ‹wèСHKKC]]iä*S\¹rÅ ¾1 Tý?nn%‘‘‘j[!m){üªØØØÀÆÆFå)¨««ƒ©©)ã“òž={B  ¬¬Lµ ¬ªªb< bذaHNNV ;{ö,¦OŸÎ¨ÚÒèbbb·¾ùæ›8wîœÚ±¶¤Íqz¨®®¦”äO7>¤]‹º£0räH™öߥ«Šv7L:U¥ZÇF ZËÉžrÿšÀ<%-UüØL9:t(î޽˪®®®àóù*5Á3gÎà­·ÞbÜŽÐÐPª‚ÒRRRгgOÆcµ/^¬–æ)ŸŸo°ç„Ð;0d5 fÍš…ß~ûͨՈÚJbb"ëv888àüùó9r$k6( 8œ9s†UO’‰‰ ‚@VVºuëÆZLR7»¢¢¦¦¦¤.èÂÝÝ555ªU1[v´L_«ªªbDW«W¯ÆöíÛЯ§‹N:ÁÂÂBUúøÊ•+?~¦¦¦ŒI¾¶&,, ………())AZZ£¹ð-iYf÷èÑ£èÝ»7+v´”>MOOGhh(k¿Ùƒ¢©© )))¬-’Z¦óµUÉÐ;(úr(™†ÉÔ]ôìÙo¿ýv»¸_ý5ë6Ì™3<`}mhhÀÍ›7̪3fÌÀ×_Íú³ŒS§N±j‡§§'\]]±iÓ&VVÅJ!—ËqæÌtíÚ•µ‰–²^|EEíb2ú&|ÙÙÙhhhh³ø7 wPôU’b‡ˆˆÚ%#ÉÇÍ›7áççǪ„L&cue ¼tï>zô|ð«vLž<EEE¬¹u•ÀÖÖ–ñ4±ÖLœ8qqq¬^sss¼öÚkøý÷ß“ÑŰaðqãFŒ=šµÉ§££#‚ƒƒñüƒÑô½ÖøûûC.—cýúõmÖvÑÐSSS‘­vŒÏçcïÞ½¬—ëlUµØ~9°Mÿþýáçç‡N:±j‡™™„Ba»У££Ñ§OVíèÛ·/&Ož +++Ví Á¨Q£X8–.]Š¢¢"ÖïËСCÌjŒðÒÃ÷üùs|ôÑG¬Ú±|ùr˜™™1¦§‹õë×£©©‰õì¥uëÖa÷îݘ:uj›>oBqïÞ=”——£gÏžÈË˃F­jÑ£G#11 ,ðRûW‰X,Æ·ß~ËXc6!)))´—¤›‘ܺaZ ƒ»/äÈår¤¦¦bðàÁÜóÑŽî [yðíù¾Pµcß¾} R_Ø/e ===áä䄦¦&•+W_JCËhâÚÚZXXXæ™R©s÷î]899‘î¹Qé‹ üòË/X¸p¡Þv'OžÄäÉ“agg§³ÍãÇ!‰H_T+ãPiwùòeôë×4G”J_µµµHLL$Íó¤Ò×­[·àááîÝ»¿r_2™ ÇÇüùóõ¶ûõ×_1mÚ4X[[ëlóèÑ#Èd2 8±{tá 4ˆ4b™J_ÕÕÕ¸{÷.éìœJ_‰‰‰ðõõ%͹¦ÒWss3NŸ>M*!ƒ·ß~:Û¤¥¥ÁÔÔ”4ʘ÷èܹs>|8iª)•¾^¼xÔÔTR*}ݸq]ºtAçÎ_¹/‘H„óçÏãwÞÑÛîðáØ;w®^÷öýû÷aeeEºmdÌ{tæÌŒ3†tJ_eeeÈÈÈ Õ_ ÒWBBzôèAêù£Ò—P(Ä•+WHsË©^Wm^Q3j/£ÊÊJêD .$ÍWtss#}0HÛ”——ÃÉÉÉ(}) tîÜ™´««+üýýõŠ<444@$Å.ªí”mÈt¥¦º>Q\\lûKJJàááa”¾¤R)\]]IÛ)½¾¾2™ŒÑ{äîî???Ò{D¥/;;;”——Åþââbøúú’¶£òì477Sú)ÛèЕ‘æÆºGTìWÚE6 SùNkkkÔÔÔÅ~øøø¥/廉êµÐ7 WUUÁÊÊÊ(ÏUû•v‘ èTú²°°€P(4ŠýÊï#Щإ´‰êµh„àóùDtt4ÑQ9pàQ__ßaíߺuk‡µ]"‘»víê°öŸ8q‚(++ãžÎ~ƒ‰‹‹#rss¹kÏÙo4Œånii©áËïHtëÖ æææÖþö6ÖVLMMÑ£Gk?™×€{v8ûuáëëÛ¡ë1pÏNûÄPjïˆB¡€H$ÒØw\Ñ#£­È‘\.GSSlmmÛž‡~öìYì߿Ϟ=SKKKñcÇ´–‚ãààààààh;ÿøÇ?4Ž wíÚÉÉÉpssSißvíÚ§Nj9…l²eËäää¨þ]\\lToËÊK­‘H$øðÃÕŽÙØØ ¤¤‡6ÈÎK—.¡¢¢Bo›û÷ï###ã•®Gppp›Õ¯888^’žžŽôôt$''cíÚµ^ÆbŸ™L…B???466¢¸¸X-çµ¥-nnn(++ƒ™™™Ê–ææf”——ÃÄÄÎÎÎppp€š<0A(..†µµ5<==5l“J¥àóùðôôT»fÏŸ?‡\.‡§§§ÊNGGG”——ÃÃà …¥¥¥°··o%Ž98ŒItt´êÿ•â3-óÚ͸KÄÁÑ6***°}ûv„……áàÁƒ8zô(V­Z…©S§ª­Î›››qãÆ TTT ==!!!˜={6FŒ[·naÉ’%X¶lRSS1oÞ<¼xñ‰ÙÙÙªý›o¾Ák¯½†;w"&&µµµ¸~ý:Î;‡o¾ùj¶ñù|¬Zµ 'NDRR¶lÙ‚'N ±±ÀKIV///ÔÖÖ"772™ ‰ .DÏž=akk‹÷Þ{666*a¥,¦Ò–;v &&ÄÖ­[‹ï¾ûû÷“233aaaŸþYãÚíØ±B¡EEEøàƒ ‘HðàÁ/µÆÇŽ‹?þ/^Ć 0pà@ôë×G…§§'rrr0~üxܸq_}õfÏžÓ§OcË–-ðôôÄ;w°aƶçórpt@¸ƒ£$%%Ç㡸¸xðàlmmñÎ;ï 66VÕÎÎÎC‡Å™3g4úpssÃĉQTT„ªª*XXX`äÈ‘°±±Á¸qã999ªÁ¯  MMMpvvÆìÙ³!ðÛo¿aݺujý¦¤¤ °°|>ööö¨ªªÂû￯ñý>>>9r$,--aii ‚ °lÙ2µT–é=­minn†‹‹ fÏžúúzüöÛoÈÏÏÇš5k —Ëáìì¬õÚmÞ¼ü1÷Þ{O­ºTVV`úôéªÉÊ… `kk‹ÒÒRäççcçÎØ¶m6n܈ñãÇÃÚÚÀºuëЭ[7deeq:Çß ®ÚG¹téFùóçÃÂÂ]»vÅ‹/PRR¢¶BoɰaÃpÿþ}<|ø‰DðððÀÂ… akk‹´´4/Õ® qòäIܹsÞÞÞX¸p¡J{»¶¶™™™xðàÂÃÃ!‰ÐØØˆææf…BÁÝÝóçÏÇСCµºÜ— ؽ{·Öó hjjRõûömtêÔIÍ–Ö„‡‡cÿþýhllÄœ9s •JQWW…Bºº:ÈårŒ9ÄÔ©SµJXššš¢¨¨þù'îÝ»sssœ={‘‘‘ˆŒŒTéF¬Zµ ‡Æ¢E‹`nnŽððpŒ;&LàŠ9qüíhs:ÇßêêjÄÅÅÇãaàÀèÕ«rss‘žžoooãþýû°¶¶†D"Á™3g°wï^$%% TUUaæÌ™HHH@II ¬­­UZÜHMMÅ„ àãャGB&“¡W¯^èÕ«âããagg§Zý'&&¢°°ÀK™ß·Þz 999¸{÷.ÜÝÝuÖ½®ªªÂ… зo_ 8ñññ999ª¿S&“ÁÏÏW®\ÁöíÛÕRY§L™ggg9rÀËZåÚ´+âãã1dÈ\½z3gÎDaa!áää„îÝ»£W¯^‰D¸yó¦J[½®®gÏž¼÷Þ{05åÖ,Ü€ÎÁÁaN:…„„xyyÁÆÆŸ|òÉ_þoþ׿þ'''àÈ‘#8þ<÷ pp´·]. ¤ÜUãà ˆ2š[¹ÂíÈÃTQF¹PEÿsppp+t pLÜ€ÎÁÁÁÁÁÁÑ.ôââb©“H$Ø¿?$ wÅ888888Ú!Â2Ê<Ó–‚ ÇŽÃøñãqüøq,X°°mÛ6Õy¹\@€/¿üRç]½z'NdõmllÄ—_~‰ï<¦Í IDATÿüç?e_™$)) ÇÇ·ß~«Sxƒ qá¬ZµJgN19r˜3gBCCYµ£¬¬ aaa*Q6¸pá233ѹsgÌš5‹5;> >Ÿ[[[­¢4LñóÏ?C$ÁÔÔ+V¬€™;zXëÖ­ƒ‹‹ úôé£J“cš¦¦&ìÚµ <nnn˜7o+v( ìÞ½2™ –––X¶l™š´/Sðù|ìØ±NNN ~ø!,,,·£¡¡?þø#¬¬¬ ‹±råJVÆzKU¨«W¯êü`TT”ê¿Å‹ãܹs:Ûæåå!66"‘ˆÕ=&&›6mR‰w°Å† àèèˆ;v°:¹ùþûïÑ£G½1º‘ÉdøñÇñÁ`÷îÝË嬨QZZŠŸ~ú +W®Ä?ü ŠLgš¬¬,ìÛ·«V­ÂÍ›7ñâÅ VìPŠßDEEáØ±c^;¦ˆÅ“'O…äädÜ¿Ÿµw‡¹¹9V­Z…„„\¸p;®^½ WWWDEE¡°°Po:ùßÿþ;;;DEEÇãaÆ ¬Ø±cÇtéÒQQQèܹ3>ûì3°çýÃ?`øðሊŠBHHˆ†r#kzII‰JHâÞ½{^Š¿_½z‘‘‘mú¡PˆÌÌLU¿lQZZŠÅ‹ãСC¬ÚQRR‚eË–±šŸ[^^©TŠ%K– !!5;ÒÒÒйsgA$¡©©‰;nß¾áÃ‡ÃÆÆýû÷ÇíÛ·Y±cÛ¶mX±b¬¬¬ÊÚ û»ï¾ÃüùóU+S¶^Ø_ý5þýïÖ®]‹Í›73nCMM Ž9‚U«VÁÊÊ +W®ÄîÝ»!‹µC$᫯¾R‰­\¹'Nœ`|Ò—ääd,\¸ðÁàúõëÈËËcÔŽ””ää䨞ӷÞz ÅÅÅŒ/Øâââ ‘HTUG'L˜+++vÞï„àóùDhh¨Îóiii¢¨¨ˆ`“Î;©©©ÄŒ3X³!!!X²d !‹‰×_ÈÏÏgÅŽýû÷ÿûßÿ‚ ˆýë_ÄÑ£GY±cãÆÄ®]»‚ ˆŸþ™øæ›oX±cذaDii)A‘””D|øá‡ŒÛ ˆ‰'eeeAD~~>1iÒ$B"‘0nGß¾}Uÿnjj"BCC ‘HĨ/^$–/_®v¬oß¾„@ `ÔŽ»wïßÿ½Ú±qãÆyyyŒÚñõ×_ûöíS;¶xñbâÚµkŒÚ±téR">>^íXll,±råJÆlJ¥Ä´iÓˆŒŒ µãéééÄôéÓ½Úž…üü|bܸq„B¡`Ô.Ê%¬¬¬àêêŠÒÒRV¾ÿáǬîW+¹té&Ož ðööV ’0‰P(T'€#F¨ 0½«¯¯‡··7 00&&&ÈÏÏgܽ>&LP;…“'O2fC}}=rrr0xð`µãáááÈÌÌ„P(dÄŽ²²2ÔÖÖ¢OŸ>jÇCCCQRR‚êêjÆVçÁÁÁèÚµ«ÚñÀÀ@H$µrƬ¸Üÿ꣮®¬ÚО˜;w.bbbXùîÂÂBtéÒÀK︸8ÆmÈÊÊ‚»»»Zý좢"Æ÷ó[¤À˘–'Ož0jÇ“'OÔbiØzFòóó5^”sæÌaÔŽææf<~üaaajÇ'OžŒK—.1fÇŋѻwo¨ïÛ·/òóóQWWLj'NœÀäÉ“5´÷=<<àììŒÜÜ\Fì8vìæÌ™£õÜÈ‘#›|ÆÅÅaÊ”)ZÏEFFâôéÓÜ€N‰°¶¶VÕ~fƒ½{÷ª¢ý‡ ¢ŠS`™L†„„Lš4 àîîÎJ|Cll,¦M›¦vÌ‚ñ{“œœŒððpµcË—/ÇÞ½{µ£¬¬L£òØÄ‰õ§ÒÁÕ«W5V‚žžž¨ªª‚B¡`Ćœœðx<©ïÔ©lllóZh{6ÀÙÙ]ºtal¿¶¢¢^^^ZϽûuëcφ®l¥eË–1ö›IOOÇâÅ‹YµC*•âÆíâzüítm«6héÆ Grr2+vÈd2ÖuÅ•“¬–Ìœ9§Nb|@2dˆÚ1KKKÆ]î§OŸÖ<µ··GCCciFF‚ƒƒ5žîÝ»ƒ <}ú”;^¼xwwwjiæææð÷÷g}@€ˆˆ¤¦¦2bÇž={°|ùr­ç¼¼¼ñðù|5æûöí‹ÂÂB444ÐjGuu5 t¾¿:uêsssÚ3U.^¼ˆˆˆéz–––èÝ»7£AzŒ èIII¬æ9s¨ÓÚ•éèèddd°j[¬ÆÆF¸¸¸¨Ÿ:u*ãQªÚ®Å°aښʘע´´^^^àñxívÞµkWÆt}.Õ9sæ02ù¬©©Îüê×_/^¤ÝŽÆÆFtêÔImkªµ§®®Žö‰ðñãÇ1{ölçmmmÑ»wo¤¤¤Ð>Ÿ9s¦Þ6cÆŒÁ7þZzzz:ãÁí‘úúzH¥R¸¹¹±jÇùóçÕ^Ræææ°¶¶F}}=£vh{YöïßéééŒÞ“ŠŠ ôìÙSí8ÓzÇŽÓps³ÁÁƒuº2™ “Éd(++ƒ¿¿¿ÖóLN¶ÊËËUAŠº&@t“ ­5ã•ôéÓ?¦ÕŽC‡i)¶fÑ¢E´?#úžQ%tÇãTWW£²²R#Ö„Ígõ•ô¦¦&áùóç¤m£¢¢ÔÔåØdÔ¨QHLLdü{«««!•JU/???…BÆZ:lÝ]3ýÆÆFF¾K(êÄ`ò·#t´Û •J‘ŸŸ¯1Éj¹ €TJo)g}WÊçcذaˆ§ÕŽÄÄDŒ5Jo&¶ïЯ_?½m:uêDëDX$A&“éÜ(½8ååå´‰™•––ª2•ôÆ)¦¯zƒ>|ȸ«öU ÅÇY·ÃÃÃb±˜±T²™$“æB¡½{÷&ýA0á­ÐµêxóÍ7õ* Òé5aƒ’’˜˜˜ÀÇÇGëùþýûãñãÇ´¤%%%zW‚...(((@aa!ív´‡­ÂôôtôïߟÕ)œ}:kºÆ†ðäÉ“v×8qâÞ}÷]-“ùÎÙÙÙ¨­­…•••Úq+++888 ²²’;ÚÃ>>è´ƒ©@Ae0“. j¦"ÝO:EzOÈ\Ʋƒl”î4ºÊÊJTWW“þ½tÿ~³²²ôî[·¤[·n´OjK©ÔwoŽ;Æú{cæÌ™Œ¥¯ým¢Ü¯^½ wwwVmhnnV‰—°Iuu5ëûøº°··‡§§'ã2’Ú`*Ò]&“Çã錖uuuEMMM»x>ÃÃÃi¿&Ú²Z3qâDìÙ³‡µ{¢ÄÝÝV“††˜ššÂÆÆFo; øúú¢  €¶•1Uoyà†ùòññ¡%ÆA àÑ£G*©W2†ŽÌÌLF¶V9¥8Ù»w/–-[¦ñBø»Òþvm)kJ–/_Në Ñòe9|øp oÓèKj9 Ó}M¢££U:ádºHIIA`` éÄ×ÇÇ2™Œ6=u*÷„‰Ýt„ ´èZ”””ÀÒÒ’ò{ãÝwßů¿þJ‹×ÄÅÅ…rÕ?333¸¸¸0âuät–™3gãjBÚèÑ£ø|>c3§NÒpÄ……… l÷ÏÉØ±cqýúuîóÿ2dÒÒÒhßÏ'ÃÉÉ …‚‘`A2"##is»âêîÕ«-®n>Ÿ333ØÛÛSþŒ¿¿?ž={fT;È‚%u½çérÿsz;ƒÉ”¾§OŸâí·ßÖ8noo‰D˜˜Š>W:ÙíZgø2™ ¥¥¥Ò¢­™;w.­R´999ñÚpqqAmm-m¥2©¤F)¡3ÕòâÅ‹ªZdøúúÒwíÚ5Œ=š²6……<==)e?¡C‡(ß%ãÆÃµk׌jGff&z÷îÝ.ßË}ÆŒøý÷ßÿ–ãGX©lL¥G …B½û`èÚµ+îÞ½K«Û·oÇêÕ«Y½æ2™ yyy:SÅZNüèÔÉNKK#Ý·VBgŠ£¾ô½ÖŒ9’6;D"lmm)µõöö†¯¯/d2™Qm‹Å°¶¶¦ÜÞÒÒF×u7äžÐù.IIIÑ(NCÆ‚ ðË/¿tü]&“ÁÆÆ†ÕM]]ìííYW¿âx‰T*…H$‚££#«v?~¼ÝÊÑÊulA5UŒ®•qss3š››)»v]]]iñ\¼xÑ  "WWWäå塨¨È¨vèKíÔ…±SµÄb1òòòзo_ƒ>gloß70f̘6}ÖËË‹ö¢`´èB¡ÉÉÉ0`€Ñ÷2 ™õwïÞòL— nݺ¥!@»æ0U‚ƒƒ‘••ÅÈ«¤¤D£ô!‡nèNK2¤ÖÁ¤I“påÊÚìh­gÏ4555¨®®&õV( ǃŒ¾2nY‰*t¤óµ%µÓØ©ZR©uuuÒš››ÃÕÕÕhb7ÏŸ?‡ŸŸ_›>Ë—/wì]É€©oo¡Õe†0fǽ{÷4"í•°QÙK׳R^^N»ôjss³Î÷–/k:¸ž>} …BîÝ»ëmgbbSSS£Jªªª(¿,œœhKÁ©¯¯' i¹ú:pà-Ï…¡é¥t¤8ê+ £‹ &µÂWee%ºwïnðÄ‚Çã £ihË¢‚µµ5:wîl´… Õ¬6Þ%`ÖÖ¶TZ …‹ÅZÕ×Z« µU¡Í½zõBNNÄb±Á3ÌÖŒ?ÑÑÑ ¥Ü“““Z¥!ClÑ÷`Aùºx{{ÃÓÓSãxvv6%U¤k×®éݯ­¬¬¤dKÏž=µ¦Y …BÒ•äõë×õ¦Àðx<( <~üXo:¯¯¯Þ´¢‚‚½ûgÛ¶m#U9 ÇúõëõºÙz÷î­·r]ss³ÎJQQÜÝÝI·ƒ<<<€ãÇku;vîÜNNN¤÷­¤¤DkÞt|||8þûßÿ¶ÉóÒ’¤¤$ÄÅÅá£>Ò¨w`B´qãçæÍ›ªÿohhÀš5k°oß>­míìì†äää6Iñ%K– %%ÿùÏ0kÖ,ƒûðööV{•””$^òôéS\¾|YÍ‚ 6Š>´œ-j[Þ½{—òìþóÏ?Ç;w4Ž÷íÛ7n¤¼2tèP­+ªª*dff’~þ³Ï>ÃþýûµÆE$$$`Û¶mX»v­Þ>‚ƒƒµNL”¤§§ë-sÿþ}ØÚÚbÅŠ:Û¼ñƘ5k–ÞÚÈ‘#õ¾¬^ÏÒG}„øøx½|Xc’fˆ{·´´TMíøñãxóÍ7ñÆoPî#&&—/_Æ’%K¼Ü‡îÖ­[›¼pÊ…Æ_|sçÎ4˜ÖÔÔàßÿþ7ÞyçÕ$ÍÙÙÙ`;=z„ÚÚZTVVâìÙ³mJÛŠŒŒDDD‚ƒƒñÚk¯µilllÄýû÷±~ýz»fÍâ÷ß7Š£G¦ü|¶fÁ‚ÄÍ›7užçòÐÿ\»v C† Ñ©ÁmlôUÿÚ¶m¢¢¢±CŸ;=772™ŒvÍo*©SIII”W¿mÁÁÁ...¤Á•A ©©É $º¸{÷.†jô~•[TgRSS1pà@Zî‰!©lÍÍ͋Ŕ¶M ¡-2¬Æþ ûùùÁÃé©©oAØÚÚ’ÊSeÕªUرcG›>{æÌ¼õÖ[F{¶%õS$áþýûz+ïq:Eììì •JÕ\ãÞÞÞŒ§ÂEDDÐ&3Ù‘055ÕYìï† HƒÛ’~d†D¿gddœ‚D•öâÇãñààà€ÚÚZJíär¹ÖóÕÕÕ°··§ÝGGGˆÅb½QæÉÉÉ´ß*%šéHkÍòåËI'8tÛáää+++ÒŠB\‡н½½1|øpnDÇËjH†Š#Ðý²”Éd¸téãqTÝVt¯¬KRXX¨Vn—nt)µ=yòþþþŒÆh+ÛÔÔ‘HÔ¦Ê]m!00Pç%“©ž‘‘‘:+á8qBUÕŒN‚‚‚ ‘Hðüùs­çïÞ½‹!C†Ð.eM–ÊWPP+++½Õ ŸŸŸZ•>msssÚc¶fΜIZ%ñòåˈˆˆøk è½{÷f=w0((È ’«LðWÖ;n+GŽÁüùóY·ãáÇŒqj‹œ”£œÁ€ðìÙ3ºëµµµ¨®®F÷îݱcêÔ©:Sƒèk‰¯¯/JKKµžc*ûx™Rغv¼’„„Œ7ÎèéY­±µµE¿~ý´–ß^– £½€Ð˜1cÔJ€·F$¡¹¹™öàÍ!C†àáÇz='ׯ_ÇØ±cÿZzŸ>}ðøñcVm ÁŸþ‰ššxzzÒ.ç©‹–¾˜HÒÅÀU”è®(¦‹=z °°PML(2âÆlÉêÕ«5Ò O³>|¸†§ 11‘Öô¬ÖXZZÂÆÆFCr”éëáèèGGG•˜P(„©©)lmm±ãÃ?Ä®]»4Ž‹Åb¤¤¤0vM&OžŒË—/k—H$HJJ¸qãh·ÁÔÔ&LÐZÄG¡P >>“&Mbäzèˋ߹s§Aµì_e‘¤³àÖ/¿ü‚ P¿¾ÜzÎpêëëY¬n¢гgOdgg3¾Òh‰¿¿?ÊÊÊTªu·oßfekÆÆÆ&&&ª`0@KKK£•~¤JkÁ ‰D‚äädÆ'}‹-ÂÁƒ5V£¡¡¡ŒÙ`kk‹àà`)lxp† ¦±*½~ý:FŽ 333Fl;v,5sssaeeEk¤}K^{í5´¥XÆÄÄ`îܹŒÙˆÀÀ@\»vU;BBB`ii‰û÷ï«‹‹c$ÅSɤI“ŸŸ¯±›šš gÐ$¸C èãÆ£-7‘*|ðvìØÁXê6BCCQUU…ÒÒRV]î&LPE¬^»v—6|||T{”LDÈê"<<ÉÉɘOSbee…qãÆ©*²e‡³³3U[2<@PPc:ÿJŒÒÒRÕóñôéSØÛÛÃËË‹Q;fΜ‰»wïªÄn*++Q[[Ëø$øóÏ?ǦM›Té|‰>d4V®\‰]»v©•eºÈÇÃ?ÿùOlܸQ•V(“ÉpåÊFÜí-Y»v-6oÞ¬ú·rûaüøñ*jŒŽb±XkE*Eè†î²‹TðõõÅöíÛYÐy<\]]qäÈF­±··‡··7Ž;F{­>,X€sçÎ!-- 666´I5’±téR>|ÕÕÕxþü9z÷îÍŠk×®ÅÎ;ÑÜÜÌZl|öÙgøî»ïß~û->ÿüsÆm033çŸ~Šo¾ùMMMؽ{7V¯^M{4·¶ßÊŒ3 …BŸþ³fÍ‚‹‹ £vXZZbÞ¼y8pà€—{´#FŒ ]P¦5Ý»wÇ AƒT5bccáïïÏø¶Ý€`jjªÚ–‰…¥¥%å¨rc1f-ïôN (IDATÌÈd2UŽ~ZZRSSñþûïÔ ÑªÊú¡C‡Ð¥KŒ=ZuìòåËhjj‚µµµÊevöìYÕùÆÆF¬_¿[¶l¡ínjj¯¿þŠ… ²: E‹á‡~`Uvôîݻؼy3vìØÁª´èÍ›7qúôi¼ÿþû aÍŽ˜˜$''cúôé¬y €—YUUUð÷÷ÇìÙ³Y³ã«¯¾R‰¼|ôÑG¬Ø P(°qãFX[[C,ãÓO?¥=ŠZ;wî„P(D¿~ý_})øá‡àèègggÚ Ô袹¹›7oV ¬¬Y³†µçtÓ¦M°°°@cc#>ùäÆâ ZRSSƒ-[¶ÀÃÃuuuøøãiS‡ÓGCC~øá899¡²²kÖ¬›››ÞI@k•V‚ ˆóçÏ#??ááá°²²B]]ڀѣG#11QqWTT¤ö þóŸÿ$ݧ£8õüùsXYY‘ªóPé‹ ŸˆŽŽ&ÈØºu+i›ëׯ>4J_r¹œØ¾};i»õõõzÛ¤¦¦IIIF±‹j»S§NÏž=3J_UUUÄ‘#GŒÒW||<ñøñc£ô%‘Hˆ]»v‘¶ûùçŸ‰ÆÆF½mîÝ»Gܾ}›Ñ{tâÄ ¢¬¬Ì(}UTTÇ7J_—.]"²²²ŒÒ—X,&öîÝKÚnÏž=DSS“Þ6wîÜ!’““½G111Ä‹/ŒÒWII ñÛo¿¥¯¸¸8"77×(} …Bbß¾}¤ívîÜIH¥R½mþøãâÁƒŒÞ£Ã‡ÕÕÕF髸¸˜8}ú´QúŠ% ŒÒW]]qèÐ!ÒvÛ¶m#Ú ï¿ÿýï[ð!!!*x¥`‰»»;ÂÃÃu®š›šš““Cºvww']1ØÛÛÃÕÕ•T›œJ_àááAªL•žžŽ^½zé• µ¶¶†››é,Ÿª]TÚ999ÁÕÕ•T²“г™™¥™&Õ{äââB*¯J¥/…B´´4Ò=xWWW¸¸¸è]YØØØÀÍÍt–oÌ{”™™‰€€R/ •¾ÌÍÍáææFäH¥/¸ºº’¦ÍQyvLLLàîîNº’TÞ#}+ [[[£Þ#*ö;;;ÃÅÅ…ÔKå;-,,Œvž>} WWWRO•¾LMM)Ý#777J÷ˆÊ;˜ªö;û]\\àââBÛ`È="ûMR±ßÑÑ‘Ò;˜Š]<îîîFyë|Ï3¹G@¥—¾=Cû2111Z°Õè\ªÕƨ´3fú•……üüüŒbÕbƬ¼FEB•ª¤¨1ï‘1Ÿ}KKKJÒ¹Túòðð0ší<ÒõïÒ¥ iª/*c^{ªrÄT¾ÓÊÊŠRÌ ÓÏŽ™™¥ù7nÜÀ;w`kk ''',^¼û÷ï‡P(T)qåää ®®Žµ:‘–ã«rµîîî®ªÈÆ•Oåà`™²²2¸ºº"##ׯ_ÇÒ¥K1gÎÜüÉ“'#77"‘HU¹«¨¨¹¹¹¸}û6¤R)œáææ†€€Œ;ÇW©šÀÃÃˆŽŽð2ð“O>ÑYNtÉ’%033ƒH$BTT,,,àää¤úO*•båÊ•X»v-¤R)¢££ÕlquuÅíÛ·‘˜˜ˆ¨¨(,Z´fff4här9*++¹€ƒÃH˜q—€ƒƒ=ž>}Š3gÎà×_ENN€—Ò•Ê•¸6LLL`nn©TªÚë^½z5¤R)d2&Mš„iÓ¦©Ú‹D"XZZbÅŠ¸wï®]»¦š888ÀÖÖZ¿K `Ö¬YðññT*…›››šVDSS“ªÎƒƒƒ¢¢¢ •J!•J1yòdlÚ´ ÖÖÖ*š¿ZªG{AC)ŽƒƒƒÁµ™ÒÓÓñüùs888ÀÏÏK–,Á÷ßêêjðx<¼ñÆxòä ÜÝÝqàÀÌ;}úôÁÀçóѵkWãìÙ³ÈËËC×®]1jÔ(ØÛÛãÒ¥KHHH@xx8jkk‘——±X OOOØÚÚ"??/^ÄgŸ}{{{üôÓO())@ €««+"##±uëV<¥¥¥¸xñ"***P]]Íx9OŽ¿F–áàà —.]º °°C‡Å™3g¯çÍÁÁÁ èFàĉ(//‡ƒƒ,XÀx=oŽöÏÿ£M¬Ëë>3IEND®B`‚snd-16.1/pix/blip.png0000644000076400007640000006241111147553266012605 0ustar bilbil‰PNG  IHDRª KŽäsRGB®Îé pHYsÂÂnÐu>tIMEØ#,5æ›ø IDATxÚìg`TUÚÇϹuzÍLê¤÷„@j ô²4QD,è*–µ·ÕÕ}-»ëZ]×ŽŠˆ ½w$¤÷Þ“éýÖ÷Ä TAïïÓÌÜ2÷ž{Îÿ<Ïsžs.äy/<ÜÂ@žç…R¸-@„"¸½K0²nÁ¢W·` j% p;¹„¿Á¡¸©.!'Ä/@0QnªKø»³³xA‚~¿pO{ÿ˜>‡‡% p;YX7AnM¸`¿þ_@`À2ÅŠ …. p½ÖÍ÷ðÅ!(*”¸€À5á4¶ …ð³ùs³cX< FÖnÁº±†› |P|ÍöWÿoë„A­þ¸¦ð8œu…8ÏsB åõ°,+–H}¿›»ÃãöÐ^o\R2ŠãX]Z´cÛöº¦¦ðЀÀ`±T:yÚŒËÿ—ÛåܲiµÇEño4šDR‰ˆ ¢"£“Sü…* pmM·+<&¾Ï­ M×UU»ÚýƒÃ"c r¡uBS”Çé«5çýHS.§C&S Ø­8>v¹k¢<žµ?~_S]mwº-fcRrâ’§žG¾±±zõŠÛ;»fÏ›“˜€‚ó«¥±þÓ¥d>vÒÄ3¹ÇwìØ?yêt/g‰%’É“ïxçW›š›&M™.WªÚÛ;¿ûö[ÂÇÿòT¿鿦}Í_þÚn58†Ù»sûàaÃûÜêq9?ûèÊòr‡ÓÆs0{̨yw-”*T½ëüÚ•ß´46<ñÂkNxžÏË=¾nݧݦRk† >zâd¹Ü@ÙÙǤrYtb¿ ~÷z<'ä =Bàv:L"±@à²;8ž‰ÄúàPxíîr‚EˆDóÞ·wÛÆ­ëš..$*öR×ÐÞÜxäàÞ9 ^¼é̉#ûví–=¢€ãØÏ>þðì™3‰Å1†¦vGbrÒó¯þ^{’Ó@44Ô{AÌBÄëv÷Y”ÍMuN·—öz ‘¤T)9žCàÓxy!Çu'[¢“OŸ)p:¬*Þëñ° CˆD†ûÎÁ=»JJŠ’ÓÒ1GÎKÓ€ó|Užç8Bèt: „R™Ü÷cEIaîácq)´Z?•Fsý=ÇžçxE‹Íožc!‚^e]äy9—Â2´Ùb•ˆI‰T~¹gYSG›_`pwëv×VWB"¢bI‘ÐÕÙÙÞÜ$–I#"£{.Ïí°a8“¢ß¨ÙñÍM §ŽŸ D"±H4b̘¦úÚÖ¦¦AÃGþrƒ×n1w´·q<ˆˆŠÆ. Y\Œ©³@«ó¿ØoB¤·Ä2Lmu•€^®ÔüVzUpúŒ!2䣥ÿ!e²Ìa£.ô(/I’ƒ††ED !gO³Ù¬?‡_œö/?ù¤Ëb„(Ó«®¬–•¥PiÁ†ð‰3fnX»þá'ŸÂIââ+°»rvîÀ æv¸º[î9}honÜ´j%‹ Ï!mª¯5»^zý   Ãišþlé{ƒ‡!ו’yåcÔ~r¹Ç/¼h–caŸ!{Å Õ鼜ÿ}ðþ¼… ‚ ŠMœrrUÍ*¤Rxn4Àã°7×5E…¤2…ÃfÙ¸zUCS£Ýj•Èä÷?üH@€ÿŠåßعÛM{ ‹ çÌ=fâ «É´ú§ëêjÍ]ƒgι{!†á‡÷í.)* i¾°¤X"‘.¼ÿÁôACNÝ÷Ù§_8®ÿûÛËÃYüÄ3×Z‚uÅ_|þ¹×K¡¡ˆLV{\Lôâ%é­Y¥…g6­[÷ø3/HdòËŸÍi6¯ýieppȘ)Óm-kW­ :qèø’'ž ˆºD´‚Z½òÛºªê—ÞxBè°Y¿üï•æôž;ùËÓ§O=tðà°a#~Zýý¤IÓeeó³mËæƒ»·?òäÓáÑñ¿I³ëlmÞºþ§qSf4Ô×ïܲaØÈ9ûvUWV >òZl>z†òæ8X]UGˆ%áQ‘WòØ“w.¸·¡ºZí§»ûÞ{¥2KÓ_öÑÈñ“Ýwÿ‘C9˾ø\*•͘;å™C‡©ý4³þ4kàA+W|¿mãÚ´éCG554ž:yòÅ×ß’Je×Q‚᱉ýRNçÝ÷> !4;N>pÁf!Ìëµ#È•­ç¬6³\©ôö?­ü!>!~Üäá·nÞðÈ%ôE±AÃF4ÕÕù¾=¸_í§2,«ZÚ;¯½ÔP[]]^’‘1ppÖ‡ÝTWS9(+B4kdö±ý;ü7‹­:ì€àCDd´Ûn¢i:sðð¶–!Ïó=Že†!ÈŸ,åE Ògìܾiø¸I¸èõâ+RÙU]¢F¥¤<®ž~ŠEP€IS&>þäcé™CÉýû©ü´R™L"…b À0Ìítù“JµÎgŽ674ÔWVÔ–—8Ü^ˆÀ#GΘ3/22Šã¹©Ó¦2ð|]eYIQ1ËÐ(†–‘"©L~½µô!nšK¤Çñ<2cî="-õ5ÅåQáQÑ"±D­TW””T×Õ%%%Å&$]ê\"™6>>ÎéthÊ[U^6fü@bBÒÑCGšÂp¢¯Ê‰†ÈÄ"Ÿen¶=^ ‰e Y}mUZzæÒ÷þÝTÛÒÜÒxÏ÷ûž«\¡LˆK`»…-B""Û:;>zï_‹üó„i³!‚èüõmm?,[~üÄ¡ysf3¾®ª²¸ ¿­£UDŠç-¸×a·Ÿ9|Ðb·´¶´-~ü/{¶¯_³z}qeÅâGžè¥M|ÁÙü¢ÒÒ¦ºš{?•xÁÿ¶6Õïܱ©¡¶)-mÀÔYsìÜšw2ÏídÇN™(‘*ÎãJt:=ÖížóëZ©×ëJKŠýõzÿo0rÍÐôÁ½;³ÇO&H1àÙÌ´~:í•ÝÒí7$ôOõ¹8Í Û¶m~ø±'„ ýõ:ò\OU˜Ÿg5v¨u§Ó!Qb ¹ò‚³å?*–J‚Â"¼n§L&Öêô=—í×¥gfFDFŸ>’Ù§Sudï®Èp '¯¯®œ‡%–)p€óàÂ? HÒít_RqrÂÔ?ýë½¥Ó'®«.ÿâãY–½š 0ôÿ^úÑ—ß,ÿâ»ï,z(+{‚X"1vÖ¼»kJËvoÚÒÑe2™¬<ÏC•¥ÇíêîZ=.…Z-÷ó÷ {ì™üóc(Š…†õOKVȾ¶šœ˜‚ Ïq€Àà.“‘¥©ëïôìÖm[·¾÷î?þñÖß—}ù9ÇóEgÎlÛ²Y«V¼õ·WvmÝl1šNž>»{ïncWÛß_­¬0ÿ2g ö=iŽcqÊeR€B¡¤½nÊã¾tu8\¾xDp°¡° ÀØÞÆÐ4QŽqÉ©irv!¦=çlMQ¿•`á„äþ‡ÿL{]¯¾ðìñƒûÏwutùÍY0oÖÜ™g‹ †Ú¹y½Z§öóóÛµusMEùןü×l·Å$ö+(.:{\­Öed¤/yê…ó-)8tܸÅ?~ÏCÜ·pçI²Çí:~àð¼»ïþ¯¯9vðÄÑCƒGd;)÷Œ;ïÔèûÐ ”¾ íõäå¦XOaQþ»o½Q”wêæ—Ø‘½;Y–“JeÆŽÖŽ¶öŠªÆ3¹”ÇÃ2Ì%òNwyÝ™C³|š²sÛ–;Ü+W¨ÏEÅ$öX²CGŒOHü߇ï×VU>°ç‡/¾ŠŒêÏ7ÀÝN§ÇãŒML ("“Ék++ºc#Õ•&cgZú`@°!´±®ŽãØ‹k©Åá1vâu—À•m •Z+•‹:»Ú/øÝírId}ØÛv›…I‚ð‰ÝÌó(Q_ÈÐ4zs ››P×jµbÙ…ÒîrØV-ÿ.sHæø;¦—Õ”‘8ÉÒ4ŠÍ‘D·'_œŸ‡B8rĈ †IB¨Õt·U¥FÒ/ž‰´›–I¤†_gò\}MB-28½®¦®­½üê¿e Ÿ˜À0”ÕÜé¯W?úؤXÒÕÞQUUß/õRç£(Çqß°À0©\°ZÍ(NŠ/m¥rüÏ«b 1Š¢™5?þh÷tÍœsgeqáÿüð£¥ÿþÇš•ßÏ_x÷Ñ Ï³¿•`†D>ÿÚ›÷lûþë/#¢b\n—ÑÔ…ãDxDtAÞY·ÓQS[58;["–¾ùîþv§‰”Ä›-æ§ž}>Ø`0v´ž9Ýçè8„0&¾_}mµÃa“õkoi6ÛÄ" €pÆôeg2 †,@Qö”5¶˜Üa.±TÉq|bRêä©s!‚„èêª+“ÓÒor575Ÿ:yœö29r¼n—‡öÖ4ÔWÕÕ<ûÒKúsã-ç äµ4çžÊ]xÿ(ŠxŽ©*-®8[$QJ¬N—Ûáð8=U5ÃG;q†“>ötGkã‰ãùZÆæ0É”j‰ü< n뺟X¯Gç§gXª¹¹¥¡¡ãÈ‘£Qqý>~÷ÝÌaC>¤ËJJJ4TW†FF¡ØÏ>AMEÄ0õ/Úº²`ÕU•Y.Êå¼àw«Ù¤T*.Þ¿«½¥©¦.kÂäs†˜$)i@eIåU6 ‚ MV›õBÁâùC{v’–”š PÊdåE0xŽç–¥}{¥ °iÆÓ'>Ò:¼o×àá# eÅEQq‰QI©bµU Íà$&–‹•jÙõçÍC(–‰¢ÔaC³ÆÍn‡ "¨Ã'ßqGÿŒ¡@¡×ãR©4BAC#Â<^ïeÇûŽe$IH¤Ò¦ÆFŸ¿ÇCIåxé‹‹DR™ô\H =~òèñ“‹N媤ÚÈØÄo>]Ÿ¨Öê-þó§-½sÁ"ˆ Ë™ŒV†¦+½:´o÷ÙŽgž¸~íz§ËN¢›Ùäv{$R9Nˆ” UxT¬×ãq9aa‘JŒ5ŽcÙ–æ‰T‰¢øeF!m]Vâü!B­ÎNÊë!DbR¢À BÄìt¸Î>#­¹Øãvû\ £±Ý÷¢cã÷lÝróKlî¢ûÆM™Œ¢øØ)“išúêÄ'$ 2Jٗе}Óºi³æ"‰o›çá£O?c6u¡(Æs|îñ#Eù§ût.¶€ú‡OŸîvØ·¬Zˆ.,°ðàÓ'íÙ¹…v»*Ûšæ&†ñλç^'å]¹j‰ãd2Âã¡^zñ…YsfÏ™ÿsÞCQA^hhñ ò‡®,X¡‘‘!qy¹y#'L%ÏÝ€ÝbÎÉÉY´øásÃ=-k¿ÿvüô‘q‰ ¥jÅŠïÅ ÅÀÁà „«eÕŠ•þAz_83ÿÔÉk×<üè’CXߣÑv7ÅÀö––€ Ðóë_U]ÕÞÞÙÑÚÒÕÙ~äÐ1µV[SÝi±Û)V•—¶µ4 4X®T~öÉ'gÏœ Š®«­r8¬ÃGs9ìí&[s[·˜{ì@_òDsCs]mÛ¾]Û]]sçß…^»wípÒ8Jû²OÅ2 mPú¦õ5º@ÆKåÜ?uÆÌ–ƇÝÎPQR:ÿž{6KqQAÚÀLâ¢F°|k{'à€è„‰>›s gü„I Ã|þÉÒ´éC².G³˜Í]&³×ãI¤š¦vnÝz&÷èÏ< HúàA[Önì—š^YVä?âyáÉdîá¾™´w´,ý÷?FŒ˜{â!…„EÜ»»«ËDy=­Í4åÍ9âý¾Ýo@FKSÃý‹ŠOJþðý÷kêëÚÚÛ§N™8öÔ©\äÝ1w®ZÛ‘`éjû拯ÇN{"7·_r2!–žG—«"#ãZêýCBwlÙ<Á=Â@†õ=.äu1 •Òטýô5åe‘q 'ŽÑøßüÃ0Bhèùê¯ÕŽ5^áûûá«Ï<^÷œy :?«ÅüéïÅöKÉ;} EPŠarYòä“!¡‘!¡ÝæZ6ÐO9zÚlœ8OA(û³ÿ5jüØá#²}m¯µ©Á ½`FÖ¸Œ¬qçbùôO_ü{¬{4º`á§Ë–ó<xŽã¸Šâ3;6o¼÷á'zG®9Ž­*={×^Îä¾’Ý€¾þúëW(#B,–[¶oÛ»{‡Íb®¯¯?’³ÿëÏ?7yJl\¢¯¢ÎÙ³uë½N—”Â³ì† kŽ=r8çÀ©ÜÜåß~MHD‹—<)W(‡röåž8ž”’rñåîÛ±iõŠpÙ—sÄlì00½ghBHXÎÁƒ;6­·;í~þú²²¢ºêòìQcš›>¼ßÞ°°Ðþ2âêjª J‹ŠdJåŸû IŠ~úa9E³ííþþ«y÷®íË×TTõKMS¨•…ùå¥Ù£³ƒC£®µµ6ÔnÚ¼¹ÓdÔ«µA熺C#"ŠóOo\³º¸´hîüùJµ¶¦¦2÷È‘Íë×§¤¥f_]Qöý·ËÖ3Û©[¯Í­öïwX,AÁJŸ!4’¦©ÜƒÇü Ùc' (ÚÖÚÔÖ\Ÿ2 £÷Q,í--)0„„YÍÆÀP–ö¬ønAà÷=¼D*Sü ý¤îÙ½K&“Μ{·/«¨¶® "šz)þ ’f£cãBB‚š[šÕZÍ‚{He Ï'÷OSk´2…2-3S¥ÑÄ&ôKÏÌÔ¨•¦L×û…„…ÌÎF~üøññIýC ~z¿Èè˜Ð𨞪"’HJiYEõ°¬¬¤þ.¶ˆÃbâ+KÊ Nçf ÏŠOLv:¬´›jhh &Î$¸MeÅåå%zD¦HIxüèñ¢¼|¿ÿ¸ISÏU[ÀßäíSü}{!BDÆÄX†þîËÏZZ›2†gÑ”÷µ—^¬¬®()Ì/ÈÏ+*<[T0~Ò´Þ=SiQþÎmÛ‡gõÅOxž£<î=»¶-}çþÒ¦Í[Ðã3½üÌ_vlÙpæä±ÿò|fåòŠŠ²—ÿöÖ/¹eaM÷Û ÚãÄER¡.æøáœ³gr/y ¹¡+e24ÕÑÖúÝ—Ÿ=ôØãÝõ'sx½žçD"É/¹aÁâÛ A­.aãó2©èGŸDnôº¾‡öíÞºeÓŒ9wþµ7b˜`a \–¥оÊ9¿6‚` Ü6¯ªK@@@@,A°ÁK@@@,A°ÁK@@@@,A°ÁëҸͳ¸€[vyFX\P@@àv,ÛÄ%K@@@,A°n'xö×;½t,,A°n¢uÏy=î+ìÃó M e%ps’3o¬&ãéÜS6§AE1<Ç¡„G„§¦gpW_S¥Vk5z}Ïþ Mw¶µ´·µJ¥R­>@­õƒö>!Cy¼^/Çr(†³,£’Ë\N§ÖÏO¥ó‡žß½y}ÑÙ³O¿öðRVS^ºúûåO¾ø²D&“€ XÀí°þãW›[Z)–¡XŽDQEyžÉdï~¸´¶ºú_ï¼=iÊ´÷=àÛ¿½µyãªraXšá€9lÁC‰Ä=ç<¸oÏ—Ÿ} „gX–ãp å D’—_y%6±_}uåšU«Ò‡¤_þÚä q\LØÉœÙS¦ OJ@,àq»ÛÀÌô™³çrbŠá¦Îv’É•šÈ(`R«”Òn[¬«ó?ï¼ÉAîÏK‰ˆŽµÚìvoÍ9´ß9aꌞsÍ!‹I‘˜¦¼4EÕU—mÛ¼Áds©ýt<ÇmZó#Ààô?Ýyó   Ë”Að<¡aë×ã¶;œá‘Ñ¡1=?ºm¥zpzšZ¥ò}=´w§ÅnûË /ÇÆ'BHHLÊtD­õë}N‘H›ØóÕf6U–TÙìÔ‚…‹ütþKÓ”{ܸñÁ¡?Ãs,à !Âs,DP€0cÈð¥ÿ|;15M£Ó K@¬?:R©$!!Ú_ç×çVš¢ËÊšÂãÓ^+?ÿä!™1q =; š9tÄeÎÏsìš¾«¬®~ño¯B£„yG;»=òdÏ>Õ¥%Ö¯©««Ñé2…Çãxø‰§}"Èñ\G—ÙlìK@,@ÑLsK×7_-[÷ÓAH%R¹J5ÿÞEj?=ÀKyÚ€â³ùõm£'Íðyg<Ç:mV/E!ªüôÄÝÏ©·fù·Å%EϼøJ!x¾¶²Z¡Öªýü}û;Û—ýï#‘R—ÐÖÜ\^R$‘ˆÝn—€_@ÊOÕÒÜŸ,<,A°þèÈd 1ä8ÈU«Åj±›qSG^ð,'—HI’ÈäÀsÁ–¡?~÷­‚Â"/ò ÷ÂË/¥¦¾øä.§ùðáý£ÇOìV+8Ž­i¬Uúý<°x`Ç6»ÓþÔ«¯iun§mé¿ß¶™L~çì)Åcc¢pž”€ X€¢½v¯kÉÓ/&¦ `†ã8!ŽÝ£\á§VJÄ€B®àY®½µ%2&Åðù÷>Я¸Øn·?¸Çú”œ]{ R:bÌ„Ÿ]H 5YlÝúÅ2•aÑÑ­ –*†É:’³AÎ…Øyr à S&~u„aÛs—åÉ€À Šá8Aö¨Àf55µvŠ¥2€FÀBXQRâÛ¤2Œ7±_¿d—Ó¥Öh/>3Dz5•å™ijÍy2»ÅŒÿ,GzÊÜQã&û ŸææF›©Kéç@ ‹•j­ÍØñî;¯ˆ¤Ú—þö‚Ü€QB‹©ó—Ÿ·Q”FïOÓŒZ.<`yÞ_ï·è¡%8!ú篔•—ÿï«ïDb €r»·o\·~í†çq‘ˆòR ÅŒ™õç'ŸFP´O©jkn\÷ÓêÇ{wHKIõ÷óåp° ³âëÏr8(cÁ¢dreaáÙW,/(ÈsØ- Uƒ Uùy‡rà82áÂÐPCIQÑÁ{V~ñõ㯼$Ì+Kàv®>8kôå÷A1"}Hö üS‹Ë’‹.µCkS³Éìð™5%¹'Lž2iî=‹}[¤JJNi¬­+T}ÞØP­‹f/~Ì'åIýÒbâ¢+Ë«„Ç} ùÙ­7Ș„û/Þ±m[Mu½!8Èãv&¤ô×ùõìšZp6ßu*Ê;óУKR3Ï›uDŠÄÑ ý/uþð¨ðèóÃ[j…®±j˲&XX·‡` j%p«ÐÞÒ’ô8Â2kWÿÀs<ŠÀظø'ž~Vå§0”·èT.xžkmi‰‹óÙJ,ÃØ­V¯Ç­P©<.§Zçß·Ÿ¾âËÏM¶Ÿü"ÂÇdpvu>þÂË=9e‚K( pµà(2jÊä-›7<øÈ–¡0œJÄrµºÛE1«Íâ§ÐÓb_ýï¦ Dq¢ª¢ô_ÿ÷†‡fe itxØ3¯ü½Ï {KS£ÓmBXU^\R¿gçŽÔÔ„°ø¸ž1VA°®µNWYÞ1ÿžûåJõÅ[!‚dd¥q4 DâÄÔø{ö»]N™’ˆ‰OüÇûx<Þ­~²Ùm,åAÄå…ñ¼Óe™1÷OQÑ<@Ï;ŽUß/«.*O6É ·‚ß.p Q\púÝ·Þhonìs+ÃP•E5$!ƒC£ÌgiI AP] Áž>h̸I˜HrñávKW[Esdd:D Å —«Ô3çÞÕÖÞÈu§• ‚% pÕHEò`Mz‰œ~ËÙP_'–wOZLLMŠŽ8rd{É©SžãNÎYöÕׇìãy®“×6×××ÕõþÑf¶t¶·1,'¾àÞð—{ôpSs£!4"mÀŒýnï”elf#†á¤DŠÄ-8ÞÒÚ\WÛÞLŠú~«Åå´77Ô§¤¤è‰ç^Ù¼jÕªe?´/ýÐl³rä¨ÑG8}âøÂûRûézI¤Á!!¾_1pèàC¨\.Û¿wÿ¾[‡ ‚ÿÖAwžeMÆ.µÖ¯'ôƳ D…æyQX@Èt¯­,ûæóÏbâMFsum†.µÿ´éþA!¿›)l- õ¼÷ŽÎÏ‹½NǃÀà˜øø¤”þJ¥Þ*·É3 aDŸÛX–:~ø`Rr?•öçA@Ž£:˜{ì¨ÍjމO1jlHhDÎÞí«V®|þŗããÏ;CŸ:–³}ÃúúÆf‹Ã©÷ÓŒ›0iÊŒ™bÙo¹ÔÃÐ_~òQCM]JZZÿé!!!_}þISCF£{üéçä*õµ–áïxè_,wâ‚ÀþÃ{êtC]õ©ÓgJΞÁ0"Ð?hô¸±!‘Q·ûÈwÁé“"›Ô“£Äw¶µœ:}º¾¦Še˜ðˆ˜ꃂÐßK¯~‰éJçdŽ¡8–ÁHÉ­p©^·óäñƒÃFŒ-È?}ôðᙚs6ÿ̸ÉÓÖ¯ZŽ!øw. +A°~fçºU ý„FÅôQ“<Άºšâ‚–†f?66¡_l\œDqͽqCu…ŸÞ¿³½=,:ö·ºÍ5?|“Ô/©ÿÀ>,†)-:›“³G°   cÆÉäŠ>Ó~EÛ’çwl\'‘#ÇM;Ú6­Y“”–’9d„P8=N2` KŠÅ}n"EÒ˜ø~1ñýX†®(+.ÌË[³âÛŒ¡Ã²FUkü®Òꬫ=²{W‴“'Nf³h´:>EQœ næmÊ$Ò àà>7¡–œ:09u Ç2µU«¾ûº¹£óɧž½àE;¿*Í uÕÅ=ñœïëáœ}'OÍ2T(A°ÎëÖX/¸bËD1v8¬9û÷Jcöí—ŸÅ'$T×ÔÅFEås^Ÿú¿ÿö–fŠá®yŒ ÂÈè¸ÙóïùÇÒ#ãbßÿç;üó͆Ú*Ð; Ès<ÏåŸØµ÷@g§Ñápèô[·¬ïlommï¤(ÏŠå_»ì¶×_xö&ܦËas;]&DnE „#Gމ€“ÊdÁ†°IS§á86p@ÊŒ¹ó…ò,¬Ÿ±™¢_ð~*R$7iZö˜qU¥«W­TÈã'NŽÚ½=)uÀ¦u›Õ2"6"Ün³ã8îõÒ¤HÄq4ÏÐDmV³Ãa» /ywØì4Ã!Âì“[ES3‡¤féù%cHVÆ,¡dÁºòÒÒÀsï|¿npB”œŸ”Zp6ýÚU!†Ð~ýR6nØär:–†(°¹žöÖèÈŽa=.—±³«­­•æ¹Îöv‘XÌ0LUIQBÿ_1TQW[ëç¯G…5 —ð¶Æa7Ç'÷»Q†}ÿþi-y¢¢¬àí7þfwXŠJ £"qR*Âe"‚ôÓ˜IêtZ·Ûçv»ýtÚŠ’¢ŽŽ6›É~½â{½¼^àV¦±¶Úb2 å V( ©üFe9ó m—Ê“¦ÎˆŠÓ(UJ•&(ÔàtXU:¿®®Iê’ˆp’$ýôMÂ"LF£D,Ù¼a5M{šú5nÓëu… ÕýÖÇÔÕùí—Ÿâ¸müc¸„.§£¸¨ˆb™X$Âq,ÏC<L"Åp ‰x`"¦¨¶¦6«ÙDS@$–¤Å0ˆ @†a8ž°,‹¡ã,Ãà$‰¢h÷ËØ{Dz(. ÈßÑÔTW]ëÔèÑãvoZçpƬ9š f9ÎÏOãr{¢¢b5„EZ,Æšª*™\l¿áÅ"“Ê#£¢…êÞ-ßV7©Ï^ê]D¿ íMk׬ž·pÑëDoüÞ2Ý[šO:ÙÑÚxȲ<ÃxY–6¯WBbňP ËðA—ÃÞÙÖh0@\6+‚b??›ÝÆz=Í0ˆã$Ïs‚A0^Z©UY-V›Ù"–ˆ8†¥@.“Pt:Ý2‰T£Ñb¥V'++,ìhmÓéô”Çh¨mn‚R±Éh ¶M¡Q8‚šL&¥FÙÚÜa ª­®ñ÷÷Iå2©Äã¥8Ž'pE „˜‡Fc‹ÇëeXáyB$B„¢½"±TB’¤\ xT9½n'‚šbHCxž$H¯ËEâòù¹2¹ˆ$ ‚B*eR¥J¦"qE0È1¬Íâ¦Ý.Çb(†6³‘¢Y—Ë3Á=™ÃGþÎ*}{C­Jp©lá¾ç_*rÑéSÿç½E?GDŠDbɵêAˆöÑiÚkê2CAË[ú>àØëÒ>®±¶^*ýçñÉj•Vádk‡Éé´wš,Ï‘¨—Ëåm]E<sLLò¾í»ölÝ~ìð‘¢3'(¯Çårlݼñtþ©/?þ¡érã&“Q.“üÁ{oÅÌþ꣥˿þlÛæÍkWÿøïwÞ2rô¥ÞYívÚífs÷g‡ý§•ߌš0BØXQ†BxúäñO>xÏírÞ ˜zŧÃs\iqÁÀAƒÍ–®¥üÃbìøòÓO0’”Êår…T¬[”ζV’À›ëk>ÿøC–¡i†1Ÿ«U× EQF«Es‰ØÝ@<7I 6‹Ù鲊D†cÅ…%4úi#D+7¬kl®5eœ—qÞuï‚Ò²²˜¸ØöÖ&GŽÞÇñô/ïÉiÊKÜÜ¥ln5,] Ã"¢yæÙQcÆ… /¼öúK €24}¶»ï¡©[7et»=+W®ähoÖÈìѦ‚u ER1Fˆ Çj´Z—Ó@HQÜõן:¥Uû!¿rr „ {ÊDBÚíN‰Xbµ9x– íq¹L]&‹ÅJ±€³Ú«¨¬ ˆQ©u{vïtQî!Ç•••7´4X»Ì»·lš»è⺨ây¾½½5îM?º"Çî7»¦ÍšwÁï^«²¢"¹ÿÕ.ÆsÜ‘};eÂYbéè8}òØÝ÷/VöZ}âôYÈ¥]°Ö¦F7å ïγIe³ï^t¡³¯T÷ùæÄ_Þ½™]Å…g Ïæw¶µZí¹Bw×½X†YûÃòȸøÄ”Â×ÞüA’4åý×›¯g€ü1ÞXq[Ý$„Iýû¯üú+‡ÓÕÖÞñÁ?ߦi†ìu$õ14UTpjêœy7á¢C#c‡±Ž<ë5u¶ñk2Y¼^opD¤Ón×hü:šjH‚P©Ô õÁƒJ¥¸wñŸI—ŠdQñ Ë¿ùº¨´¸õÝ·‚ÃcFb@®%ÝÁbì‹Åú€›1/‡ç8cWûø)Ó^·«®¶ÎéthýüBÃ#Rœ˜œàX–ãX†¦ ’¼LƒbµÙ Μ8äúó’Ü.Ç÷Ÿ}¢ >ý‚xÖ¥ñºÝù§Ž™4ýæ¿ÇÁj6mÜ´‘q»“S’§Þ1S£ÑâIŠD¾+aYvÙ§77Ô.|x‰Ûa'Å’üS'êñx;:Œ,CõY˜Ë@íkæ9Þæ‰u·™*÷8$6©¿Ýf÷¸l(.’HÄb‰´µâùž´É>*¥Ç½mÝš€°p]`è͹수dÓ6 sp}ÃO¸XÂð\UE9Šaåå%AAÁ§Ž¶ˆ%R§ÓÙi4µ¶´r< vy<µõõO<û\L\’×ë--)úï?â&{ìØÄÄdCx䓼÷šåßLŸ;÷æ¤UYMFÖO$–±,óß÷ÞZW[b8~$‡a˜ôŒÁoþíÕÐÐ —éTk\òdOû9v`O@PHDlüî­›%ñ°Qc£ââîÚõK«¬° ¨¢bp@Àe4¶·0ñwöä±aÙc‰›¾~asCýÑœ½cÇŒ  î3Y—¡)«Ãjs{ßùÛߦM›(È.Ixž§(ª¢´äàÞ]3ÓGM˜z3¯\$Ud “Ð?A¤ä†eTuyiqtDXu}}Ei‰Õj‹E6›Y©Ñ„„†ôKI<, 'Å>­‰%i3Óf:¶C‡n\·Æh2EGÇ ‘bÀ/òyŽ«,+9¸w÷ÈI“üƒÃnÎ=6ÖVùFlˆ@qœÈ9Ú?( ‰ív[Gg„ÜâÇžæyþÝÿ{Ínµ(Ôß±2…ìÐý±ñ{vo»÷‡!†ðú†–aP cY¦¥±Áír° Ã0,€T®Dq‚¢¼4Íð‹!IbÉrI’(Š••–¬ý~å´YÓ'N™E{½Ç2 ƒaEQ™BaÏTPð€åØã9û£cc}¡«›IYáÙ£iÚœù"Ñ%g ‘"ñ3/¾æõx9Ž%E"AŸ|þe·Óá´ÛtÁç¬T”•dóhÿï¿ýšÝbú~Ù7ýRû7®¬¸ç8 ÖÍá̱ѱqY£ÇùªZGkÓË—],Xc'Ý1hø¨Æ†úâÂÂòûZššÚš[! ü´ê°ðÈÙóÿ-ÞÝer%`Ö] Í&#DzáQq ‹î¿?9m``h˜¿¿?‚bÃG_¦”Ê'M0qŠÃn+8“»ò‡ïíV‹D*•‰Å"‰C1™Jívºj+ ›9kfl|òM»½®Î±TæsèžxñÅ‚³ùn»8ïDRÚ åõà ÷…Þi†uº\=‚•˜2ðÐÞ=eù„ñIý(Šòų À°³§sW|÷u|¿Šð"Ò^7Š‘·ƒ¥)¢.…Š@ò$‰a6dÔ0»‹nn¨1›Mõõu%¥e<–!p, 0H©Tt´·—””¸Ýn†f årEp€'Èû~Tv¯GbijùWŸëµÁÍÍ5MF#€T,æ1””K•R™Ûí¥<^‘˜”K¤(A⎈K$§Ãk·Í^xÿÕÔŸÞ¯˜ET*W^jšô áÙŽãb¢cI±ÔÜÙ–’t7D°£ÇßÖË¢Ýf‚uêÌé…÷?Ô£5úÀ—ËuñnŠ*U¥J“œ’ϲœÅÔÅqœZ£A1â7Ÿv!¢Ñê~úÀðìq€ àÐs[¯æ P®PË;täŽcÍ&£Ýî`Íh¤)¯>(D?ÿN©T~“‰©iÇî÷¹ä9r(ÓØÙ  Ž‹Kd”ÇÛóŒÌÆŽÀs£Ÿ(†Os×[¯½:ûÎ9>Ÿˆã9Ç1`86fÜÄÉ3f]ß……Ð?}È4žÌÀãXžãùî„ò¿aå7µÕ׺¤b[k) 9"ÃyÀpœàXBÃñ®NcsS£Óã‘"†!n‡Ýlêâ9®°8?«¥Á?èÆ(vnZ¯ ‘¤Ålüèã1ŒP)ä=û’ X7 …\^WU®ÑrËÐŒ—¢¬FË[7Š¢Ú_?ßê7Ò>ˆ¢˜ŸÎßï¸A} ¡½½³¡¦*42:2*ª¦ª‚gÖ UÈ· Sâ÷<ø oç{ï@tž¬„‡GG‡Œ™8Í÷µ(//1-÷ü‹X$¿8­ÏŽ AÐ “QZR”­‚¥Õù?A£×õ-š2UhDTß›BC«‹‹n¸`ŸÍ£<žwÌâ86&&â¡§ÿŠ"è‹O=ZWS#ÖÍ sXÖÉ“'Ýî\À±ÇŒ2Ü2ê9,;ûÌ©¡‘Ñá‘á‘=›är%+ÁÝ?†EÅõ>–ã¸ò’J|î°Çí\»zõÓ/>ïÛj±Ú<^ê¦ÝJàJÅ5g-”ÖU—ϘwﵨTjöÜ—ž5’ݰœõšŠ²eÿûdÌäq•%ÑñÉ< ŠNˆŒOr{i±ø6~%Òm&Xqñ‰a†0Žc9–#EbÇ…7ÁüZð<˱—ÍpÑ4%Sœ¢Nî?0ùº§ïêhÛ¹}sÖ˜Q¾¯¤HòÚ[oÊΩ†Z¥t9n^,Ün·y¯}éW. ¼¸èzþã:M–;í„ °°˜è¢ò†æŽˆØ„Ywß³vÕŠ;¶Ý½ðÿÀÛ·VÞf­½©¾výŠ•fƒe“ÉŒÄÔÉ“ÆLžñ;Ö ŽãŠÎœ²XÌ2¹œf“Ùª”K;;ºÒÒÓC#")§²èlpx”Êϯw\ÆØÞÑÚÖÆ²ltT¤\¥¾ 0ÆóüñœpAÁIŠD"ß`ŽãüüQc(oÎŽígr?÷÷·DX†¾8R»sÚ’Ò²ç^}Å{o‚×7š¡úËs/õ6Öd½lZãuÚz.žcžçQ ÿ•‘Z•Zª¹Ö£pC±ëˆ!rµöÆŽ…„G?þÌ =_‚C—<ýÒi‚`ýê"¢Ÿøë_ÏñR^¯ÇíZö߯Lž~»?†ËwlÏŸ|is¹(–e9ƒÅœ.û]‘y¹G?úð?3fÞ1gÁ}¾ým­+¾ùº ¨Èépp44{ôu—-KÓKÿõ¶.(ÇðW_zþÕ7Þ ‹€¯­©¬­«f!®¡^Éd ­Öï:.C­Uë%Ù¯ažoß´!&!áœ`A°nn\…ã(Ê‹ c9@WG{eM#Ïñ¿_½ç•Jå„)3´S"&.19!Qïày.÷è!©\ôÄs¯øÆæ"HLêwôྠó—FPÌßó5ÔàݸúG1©¸û‰CÃbÊ óššžyé%Œ ¡!¡ÃÓSôÁ—‹‡@,w/Ò ‘´Á#~\ö)DZW9‘M¡TÍ¿ïµ+–'H‡.!…BÈ xF IDAT†8ÅðëV¬(*8+U*ÿöö;©„ H—Ó™wô˜!*\«÷ooi¥)ß2;ˆL¡’H¥Šgeþ~ÙWCFŽºnǰ²¬()%i´ÙCxØé“'BÂ"€Q¡!¬ËŽ¢Wöï¼7†¡(†q÷º=×eydRÕ ÏA±[-«ø^*'õëÿ»i·™`ÕW/[¶L*‘9.¹Dlw:§Ü1þ®§}¤D-—]êU!^G.Wª4j€Ón?uòȳçùÔʇD¦;ùŽËõ<¿sãÚSgrŸ|þÙÀp@yI±J¥ŒŒì¶ÚºZÛ:[LO=úˆÓéÄ"}À€…>$’H«½¹Ùh·Z”š«µ,ì{C}ðn7Eb¸ÍiñÒ¬ÑhêìêB k6w¾öò b±H*—wttZF‚ÄpœDQl¤‰š¦òó‹&Ýá)Õ"±@–çØë®uµ±qI¾Ïáaáu¥%¾ÏUXTöÍ—Ÿ²,k³921ÇqF“C #ÄJ Š <ÇåŸÂq43=3<6nßž=áa×3g³£­ALÜàU©Ífãw_~‘•60"¨ XÔú›ôº¤°è¤—^}Ó÷.ÄÚý¿…yrµ_`ˆáw&X­M•5 /?÷–¡I 6rô”ê¾ë’‚ʪZ l£ÛãóéÑØåv{xžGQ$00¨Ïœç¸œÛöìßûÈ“OúÔ ðfüØÚªÊ9B †É3g8À8ÝV§Ýv•‚U]\¸eÓº%Ï>d8æ< òOýøÝ—Ó>x8„"Ðj±ÔTU*• Ã,]í4M‚ý}riµ˜ \ôKV)@Ãp@g{kÁ™<æ\ˆ‡çyµFyǬ9B›ÝAQ”ï*6+CS)ò¸Ý”ÇÓÞÞ†¡ˆHDÔµ¶YÝN/å%°>Öó¸œV‹Eã§Ã àvÚÅYo'Z¥ÔjTúžš|Á8šòzÜ@±DÒÔX¿wçŽywßô{k7Ê6¹Iï kki–Éä}Îöª¯ªVèl¿?ÁÂ0„áY«¹ `8P7 ­6ëÏ$½—vyV‚?|(Ð?H§P^÷ûoý½®¡‘çxœÄÿúú1ñI}µ%ÇÎí[&MŸ›Ð8çXº¥©!¶_jO€62!95½ÿŒ»ÂI‰×ëÙµymþé“ã&OÅI‘X" ÒiúXýê(u~÷?ò¸B¥éîÎ<ÑZ]98ktÏÔ_­Ÿ^{.ÔåÐûWPœ I²²¼L,oÛ´)($ð—”mphÄ‘æEDÚlí+ønêôçÌR¹X¦P(5Ž«µúËœaú¬¹ÿßÞwFUeÿßòêô™L*é ’P± "‹ØÛêÚwÕuý®kÛÕuÝŸ««»îZÖ¶v]Eì ¢€TEz 5! i$“LŸ×?‚1$T© ïódæÍ{sçÞÏ=çÜs>!Ô^l´ÍŸóIפª¼úÜ3þ`˜çÅä´Ôu+€üåo—¬öŽ÷ˆ¹Å߯(ƒèèŒ,ÆX8à_¿zÕ¢%‹ÃÁ6E‰ ¢s\mÝž‚AE&au´œ§Œm\½,3'ÿGÂbZ,Æ "Ä0ÖâkŒé½ïbˆéçžsÎ…—\‚¸Ÿ:Š7)µÿ~í³ÈСóæÎÙS]•™Û¥ko¸®µµU7Èü¹Ÿ¹<>¤o¬­µY¬åc'þdtpBBbŠÞ) ©©¦*RxQˆ¢4iòÔÚÊm†¦ò¢$‰²ŒÅ#we¼ ‡à¦ƒVTµÅ×Úþïsλ bëÖ¦–æá#Ї(9–Áí_PÔØP÷Ç?Ü-‰VÀq›·TèªÂ‹’Ãfň±#؆ÅNåʼ Êݪ—wo«8ꔬ¼‚…_}>ÿ믧_~YÑð’¼_‚¨¦ëD0JŽ*ŒÕÔP÷Ù¬™”—Ç3uÚÔxo¼Íî$™„æ|þIÈïŸ2mzÿ‚Â^£èßÃüRúd¾üÂs²ÓE Ê - ‚ø§Çǘ[·n#ÄÉÓf`¾É3V]]Ÿ’™%¤Ž_‰†H»?žœš! üîÊ]™¹ý Dyƒ†ÔhxçæµÙr Ï¦‹ÌT4¤½b¹ÄÐ#JEåŽ=|㺠—ÛÓapQÊ †4]“¨«­iS4Q>‡(k¨k8X[_ !ÇÁÃù¹ùÇk€Çž=yðÐâ`[[|J*Ï íº¢ÀåääðG9‘(£¬[´ÈçkÌPq„³G—ï~¡ËåÖ”˜¦©Ò‘¥hPJ=wGUå¸IçfçäàýOcx$Ùâñ&(R_SõòžR±å¢K®èœÕÃÂÕ{›ö^vÕ5i™™‚ rŒÚìNÊhIiñš ›Xïê chZåîÝq÷s5UQ´+-6ÛØ³Îúð½wDQQ6c.}9óýšÝºn0¶ÒÖÚZ2v¿´„qjzÚÆõ›~{cÍ a2/¿÷žSl'¥dþÜy )IíÆ×±Œ 0”C™VNÄCˆ<ñIžøý4³2sóvlÝú3â"Í{÷vý|«wì E”5«VÇ{ã*wlMLJî"±€×w@ÂGd^1ÆÞ|ñù@Øó¯ïîb©µ# ˆ²…ãy`Jzöoî¾oÖï½øì37Þöë^ JÚÃäy‰wÇy’R]žx›Ãms¸lN€!\8¢ôšk¯çz²tFwJtB¡ƒvgYµb…¯¥R Ÿ7õâ„ä„çžýןî½ç©¿üé®Ûnþø‹OûÖTåãÞݼ~mçk×®Z¹mûNb. 8)©O}Mu}Ín%ÆîÚ=‹–/áOÍýâ‹Çþøàgs>ïWPˆ9aOõîí;·*-?NÇ[—ŃÉóD"ÆÉ«% ÂÆÑ—Z3Ƹnl;ddi Ù¸qƒ`•+*«_yù•¹_ÎîóµÚ×lÕ¬Xréüyš¦Ývçÿ­V-]xß]¿©Ü^Ññ7þW·ÜnµX>ÿèCÓÂ:Ù(?뼃#¡=Î÷cL×TJ)%@([­ÀÃêÌ2ÆÀ¾Í1¶z$yü9çfç´¶>/¿_CCmGA¥luüááÿ÷ý’ùK-jiÙ›? oÔèòâÑc*6oœýùg‘Hd`'Uu—Ç5²¤8©›ù6°hdFÖ×Ï<ñÄ>ju:ê[š0W­]½ü»¥‚Òòҳϟ¢Ä¢O=þ˜d‘ ‹KŽÓXÃhH=XÔÈjuÆÅ¼ZªÛë(%G•élk¦†ÚÝì3þìÎéø¡6_—ŒóÚª] ÉIÖ#h‘Y[µë›¯¿úí½ðÂsâóîß/§Ë¡-Dø¢—¾óÚ‹Z4,œ€ôT“°ÀÁ= µ¡~B¸ýHÜ"е5Õý †H²F!<·•›Ö­zù¥´˜J(•9ñ¡ÇÝUY9Îì‹/¿¢ÕßVWS=ýŠëÚßÙÚÜ„R3³k*w¾ÿökª¦‡Â1JŒß?ðPüþ"*Gë°œáŇxCfßA™}÷“èiÌ„Éc&Lî\8V0¤èÙÿ¼Œö/PP4 à…Ês^rùcÝ×ÔTŸÿøOÙnˆPKsD81)"T½s«,ÐKy‹p\üA¨¡77×SJðæd$\¶`Éž:Ÿ$I2Ï÷IëcqØíV+DØ&[uF!cœ BÌJ€ç0/ìÆö¥9íË£c "ȃí{J©3.±_ß~G«#,Yl¤Krc¯¿üÂU×ßdµÙöì®JÏÎFBýñþÇþñ\çJ)BƦM ‡ë¥ºàËϯþåu.ÏAûý8ÜqýèjW÷Ùæp^8íâßçÒ_ÞlÖÉÃúÕ+þñÔÓN›Ì ‚nè `8ú—ÇŸÈÊÉ­©Þ•˜|œ[- 2ôOþõ7ÿ;|øˆ!E#d«]§F«ßçMN©®©þ~éò‹.¾ côÝW_ò$$\q}öâùóJÆŒ\X¤Šr:§n´öÛÆ;Ÿ£™9ýž}åuÑbÄ%îÕäÔŸjÓ²ûÞûÈ“‡è”uÔ± ŽÏë› twÇ'–Œ-_½fUÝîÚ¶`˜bhè:#”2`jDÈcÄ8hµXe»CPÆD^ÀˆÃœA)!†ˆç„ˆØcŒ œ SŠ"Œª†n¿ãŽ£ý ’l±ˆ|žŠ( u5UÏ<ý·'žyÁï÷CŽëâDc^jlhŽF"‡&¬h$E²úØG†”2ÆÆíæ‡-ïkm‹„Ý/KHÚ¸acYÍî>é™&a$ -õÜ˯ʲÄq\»×¥i1‹ÕHÏÌV”ØqŽð!ÎãMrØn×bs’’Ó’ÝqO|zVVKóÞåK¾-Ÿ0iç–ŠM›6Ž,/Ø.‡Ã)ˆ’À€(K=·ß²hqrd°Û|︳²ö`/aÌM8ojù„s£ºnPb`ŽoW‘UT•S5A4ÀQb „áHTE‰ò‚Å0tM‰jš‹FÝq^B©ìõµI¶Y$Ê ÏócŽçB‚|Ô–£¢Ä¶WU1Æ:ø!¤ë”Rf³9€Œ1I’%YêBXV‹¤Qc_ òãSQ‘™—Û‘Ô²cë¦% ^wóí¯<ÿïILÉÊÎýñ¦Ðb³(¼`9ÿ©ë~XaÖI|\^pïo¿óêË×Þ|€8èo3È É_MNNÃ?zq0€Ýbƒzû×^|áo²7 ÚZ} þó•+.aîŽ;ïrw:~b”Äb1B‡‘ªi¢ 0ÆcŽãÚ=@°Í„]žxÄq€1«Ía¯Õ¢ØÏ+$ 8$¿ ‚èhÆj±ž^ásù,QzfÆŠ%K|¾ÖЯ¿º­rí&ñâp{Sã½<˜Å¸eãÊó§ýÔ˜.'¯ÿšï–½ú惘žÙIËT7=ˆ:kañˆÇzhòÅ—š„uÊÐÖÒÔ>E"A\BÒ‰¸Ï¡Xì'ÙÑj…‚Áó§Lu»==úHNvviùØ-MÞú›»rû儸N…ŒÑ˾]±âû¦&Ÿaèmþ€Åb‘%‘$AeQâJÛ´f¥®nÇbµp<ÿ÷=ètyÎÂê?°õä®yÑXP».¨i—^ 4ÔAéøÑj4<¬¬Ìçíbw%êr8„ÅÑÕXT”d!£„¨šlùédsÂù¿˜ñÊ?ŸüõýtfÉK®ùåÁìzI¶Ùrž$=ް%B (ÑH›¯¥ý… “§ž nk¡PÄáÞwö¯*QŸ¯M×õº=5ÑpdÒä ¿š7wÊ´‹í!P_›?MÕck’,·?„hTù„Qå}/bèÛ¶n†edfñ<œΠèŠvš&7R Ž€IyN¢´ëÛæ!eùÒoÃÁ°$ÉEÃGx½]Õ÷›[ZvUÕÌùüS‹ÝžG¼$ B°Õ·xÑÂÔÔ´”ÔtçV¯Ý8cÿ_[K«¢QMUAüß[oÔ76È‚h·Êî„…èþ_cÍ^äûûûÛhC„(€Ö^‚!ˆÏ ±hdÍÊUI)Éq^¯Ëí9SL{aU¬^ýɧ³$‹8Þï „ü­„ãu\Õ‰))©iûÎþwTl¢ÔìÚŽ9Þáv:œî'ž~@è÷ímj¬6÷óO>ýh¦aèˆû»»û¤eù½0ÇTÎHøZ|ŒQNCiz$‹¡¨îòǪ­[–,ùvDi)¥¬j×®Þ~£xÄÈÉÓ/ÙÏ4‹„m.[bj*Æœ(òTSU54ºgOuk°U«Òªª«1‘ÎhsCý–5«²òóg¾ûæu7Ý>墋T5ÆØ´nÕÛo½yùU× ªÆ”öž=WÉ<ÿò¿ÿQ”˜ªŠ¢„’-6_sÓžÚ:^¬vO^ß¾·ßu÷é©ö×Ã+oÈÛr²ZëmN»n€Ëå'8°=²tLÇ¿ 1`È0„PNG¿?®¸„ó¦Î”Ž›4²t!”!˜82¸¼vx²ªè舖 „HîV««©:ÿ‚)Þä4À€A…cÇõ¿·^ï˜ôIËHMI,1ªK1Ð9“§„B~Y¶q¼@‰ñáÛ/2Ê~´ôc/>ÿ¯‹¦OŸ8`ðÃÜ[±aí€ÂaVàÚZ±yÉÒïnºýÎóæ.žµ§€ìpÜrãmó”R!`”RªÄ"«VýàóµB„EAŸÚj“ö0ÂÒuý³™„cц=uwÞ}OÜ1¤8ýüÙ{dz#pÀñBïÊ·?YÞ¾Áu,Èùü”È]sG˜?°»Jã´Ún§³=/ì'R««õÇ(î–%v8ã:Lo„¬¡€ß“à8îº_ÝØ'-"|Ó­·uÌɬ¬ÌßÝ{Ÿlµšš0×õ‰ã1»¥ÈËëÙ'·ú)!¬ö¹uR™xÃÚUi™éãÎ>ÿã÷ߩܱå”–‰´ÞýÁ c´',r] jètºþüàD„mn» qãžz¯Ó9mÿecFsSƒ¦(’åPm¾ŠK†¯Z¾dÒE3Úù+5cßÉ`ÆR‹Q²¾æ;·9§kYHccD=ûœíXžvÞ\ÀII8§§gm6{B¯';³½qÎMXÐê]ÛFŽ×yi”M8¯dÜDJˆ¡i”QB©Åbírš˜˜”èt6y%53oÍòe†®q‡”‘ †ñéÌ÷¦L¿¸{ê÷K:ôŒ%¬ýÜ¡“ó¸’ ®X¶”âkiY¼pAQ$f·;Ó³²ÌåÞ À!H{²K ‡ƒA—NZ”ùóæm«Ø úšÁZTXtÞ” »\ x™;¬Zæ§'nûÆ І”­tý“ÞË2¸OFn——öÔîÞ¹kêŒËLÂ:yŽajfúÎêªïW­ä‰léÂox»öÆÛΜ³ÿÞëR•‚ma)º—˜Üeó^±xa4¼áæÛ­²¼}ûöwßx½µyïU¿º¹³=…8^†;\Ú3„pØè1¯>÷ïÔì‡Ë}˜ÉÊ™³f ‚`yå¿O>ýO»s_cì£ßV2‚Í<¬“‡;~ÒÄI”Q]ÓcŠŠ£ l6î!r:]=·’ `·Ø´.UÇŒî®Üqî…Ó¬6' /Ðïxð×_f”ÂN!v“[m1»ëºâqÅ•3ß~óš›nát]X\òÖû³0æÚ¯£í‚¹Ÿ»=®ñçLéñfxÏzÜp í±‡î†Y9¹šÁ0c6‡ãº›o²ÙÝæ’ïéØS»GUU©ÇêŸXN»ÕÚÅ(âebÞÐ5Œ9ÆB¼U¶wqH°, 2Èb="áÖ¬ÜþýÖ¾òü¿¯½á&K75}a—ÜJȪï–ÖÕÖ\qýMf#Õ“¾‰¹Ü¿½ïÁ/>yŸ2\:f\ÿǞݮkêòÅßbÌå èõzM{í”ù„Ôà¹<øYØÏáb ÄõñG±Š¢Á‘XLomj.*.ê_·¶57µRBw$“Ž;@ðÒsÏ\|ÙU)ié‡h· ß|å«ÍvÙµ7p½"lÒãæLLI½îæ;·mÙøåìOæÎ™sëí¿‘möcùÄÖæ½o¾ö*æxUUâããRú¤/Q0d¨Óí9ÆÎK§6¬Z1{öÉ}R NÏÈtº<‚xúäµÒH8¢éº¥Ç¯(Yº4c^sýM„@]S€Œ1UÓºx¾Œ±°?|̈PÙ¸IéYy³?ûTF.¹òj§'NŒ0€QðûkªvþðÝw›7­Ö„)3®ìѾv&¬}{q4¦`„mÄÇúKlÛ²i츱WÿêV]Uš›[ªvm_°`ÁœÏ>ÅŸ?h`iÙ˜>é‚(õ‚{Ñü¯3ÒSróúoÙ´qÖGJ¬pÈÁEórr-+<Å…Ç(.>þt`8*B(íæsÁ}Õ ªªVWîúrö§í†[~Ó™A~ÅôhÚÓ32¯¿åÖm›×Ïœ5³±®Ön±Æ`š¢Ö5ÔÛl¶ƒïyà‘>i½iÓíi1¬``å’¥K—-ŽOJœ~Ù•v‡‡³¤LóÞ†´¬l‘ Yú¤¥÷IK/7Q×”Úšê­›?|ï­°¢fdæL<{brJ*ßs™‹Q]ž{Á žøä¥c)¥ëö­[ÖüðÝÜÙŸ!Ž=º¬ÿÀAN—ûT©Ù(Áè¦ë’‚6›M”da»ËOm×Å·gü1J D§U™.¥”ëO Ĩܾíãg"û[[‡ <ãªëºÄ’‚¡°?"„m8‚ç…A…Ń ‹55V_W)!ŒQœÇítypo¬·èa„õÃ÷˾øl–A ¿¿í©'ÿfè$Éã¹ïá?cáçóH«¯mdÙØ®SA²sûeçö;wò…¡Px˦ Ÿ}òIKc]JjúYÏÉíŸß›&AÄ‹Âá!·Ç;rô˜‘£ÇÃhÙ[_±yãï½mhJn¿A#FŽ<„ï BBZòÏRUÝ  æ°¦N—q<Ñ ˆ!ó"H‹E£J”Q`q8ˆ®"w;kX,€0`L×5Žç““SÂA?B 2#:æEƒRà „†aPƒx݆0`PB ½Éßæu»=Nò¼®*X©Aâ<.ˆP ­Í ÄO8î»%Kü­­}û÷Kè“Ö\_/J]ãD •U/=ûôíwݓٷÿK…BÁî‘oNàróû‹´Ž ʙٹà @#¬³&W6v<¥´Ý PeÏîJ|lÆ’ÀÅÅy/àœNWIé˜Q£ËBÖõkV¿õæëQ0¨ ¤|¬71©§ ‹J’tÀ³pÌq‰)é‰)éc'2Ÿ¯y{Å–×^}ÉPÕ)Ó¦÷XpÒøô²«oè0 ]'”†êÐcgŒªB)U…A¨ëº`±A@‰¦…BáP8ÈqƼª<Çé„ ÌA”h"Î0ˆ$ ”·'!hkQ¢1Ê¡L5Ï 2žç2ø¾m¾–P0@(A­M„½-Í„PAˆ¡×64)á@ زi“(Šõ{lV[XQ‡Ñ'7ç׿ûÚUß5ožoocIÉèîß\SõhLg†L㙂(Æêj«7lذdÑ‚Ô>)†ýì;ð×ïmâ¥Ã‡z!D—·ü¬sÊÆŸÝÜX¿lù²çþùw^G—Ž]>FN÷|¼Û6;]îCªB½ÞoyBIÙØºÚšÎ²…'Ùä‘àäz𤇣oZŸwì>`(D‰¢€0ކB‹¿™Ó}Údd÷ÍÈî ¶®ú~ùŸ|‰„/˜~yç÷Ä{œÛ+"Ð$¬ÞGX_óâoçoݺ•F]Sc¿¼~·ÞyϱlMšc††Æ‡%$§N›~éÔiïm¨›5óó¿š×o`þ„‰“’SÓNÛ}2:Ýö#þŽ05=Ã\‡BÈéruú/‹‹;¨mwxÆOº ¤|¥]›ÚÖ×ÖÆyì sH{a)ª2ûóOûåæýê®ßmZ·zý†õǸ/µùšûç‚?+™ !œÔ'ýö»~¯*±Ë—<ÿü¿ƒ3¦_<°p(ÇŸv9/UUU…Æ›3þÄ!Žîih:Lüá@½- /pœ iaøá‡îAk³;G.Sb‘ÿ½ûÖª•+%^:¼˜?†Ö’o秤¦cŽã3²rÆO8;''sႯg¾ó¶€Q|bÒé“åÄýâ“G.µÙæ¤?A º®…©Ù9G{¡ªD6­^WT2›IˇµzÜ{’&ÿâ²??þÔ·Þ.ÈÒÃ÷ß«E‚?ûÓ\69#óøˆ=@3³ón½ãžGþöw, ýóÎùto}Ýi±–ˆq†4³8Uؽcë–-›~Æ…Û7omjnb”šcØÛ\Ÿˆóƒ‡Z‹«ãÀVE{ߎ–¾ÀöåN^¤‘Ûs¸eÌX—« «Í^>þìÒ±ãk«vÌzÿœÜþC‡ô&&ŸÚÌÌÜÜ,ñ¨{íQ`VŽ’ÃŽ…»È‘ß`CeÀ$¬ÞKX»±1´Ï>|ýúM„Œ‘ÕbÕ4È X”-CA”€V‹¤¨ê†Õk—¬Z  ”hša³H’ÕŠ ¦€ÙNÝÐ%±pD7/Y0‚A€×á2(1 Q˜.:²Õ* ŽDí6‹$‰!ˆxÄñƒ‹Š—,÷Ö›oŽU2lTi‚7‡‘00=5MÓT„ D'ò”R(£<ÏéºA eŒ†¡Ï Q„„@²X9^lç`]Õ(¥„Â%”cŒC× „ Ã"»<^5­®ÝÝØà«ÞµÃåq!„"Œ!€"ˆrû½(¡A^”`”2›Íz‚zõ>Ä'$çåõýAÕƒ 7nÜÀ™Igauæ„©3.?±Õ 0 :ÂŒd€iJT%!BxoSc¨­yÜ9S(cí‹XEŽçyŽC˜Ã!„8ŒÃŸa!@ ¡ÔÐ FœA)ÑUŽã`!„ Uì.‰D â¤йç_ûôŒ«®uÅ%š3þDƒz,UbQ¿ß¯!¬«1MSµX b !°X­jLQb1‘¦ks"†,ãÍ.–¦…uDBAOÂ)[ëý‚i—NfM»ª;ÊÇŒåx³u',g2aµ46XvÙj=­&¥Óå>{òEã'×ÒÜ´tÑ‚§ŸøkZZú¨ÒòŒÌÌîÆô7Æ›uj&zmŸ™Aw¢ë¾ñJÑèÒ¾ŸæfàÆµ«¾ùúë;·õË\:jÔð’Rt4ü¾–§{ôîr›'P&LÂê‰ÐUeÖÿÞÕc«nºö4n]SÖ¯Y¹dá‚ÕëÖ.Q6fð A®Ãù³ŒÒw^{I¥W^¡YdcÂ$¬Ó³?úpõºõóó ôÄ%ØìvÀX4­®ÚùÞ[o¥e¤ÝzÇïzbk JôõëÖíÚ¹má×ß$¦ô>lXÙØñ’(ñ’Ô%™+ô/šÿÍ–ŠwÞs¿y^nÂ$¬ÓA¿oýÚÕ•Õµu5µ5u4¦*º¦5+;óÜÉSG–”õx‰~Æêëj¾[ºxýºµÑpØér¥ed *ˆKHTTeåŠË–,]VvÙUׂdNt&aõ µM‚Á ¦ëÏÛlöÞ×*UQ¢-{›j«vm­Ø´××–àõdfdå Iêcª†š0 Ë„ &NÌ@¬ &LÂ2a„ “°L˜0a– &L˜„e„ &a™0aÂ$,&L˜0 Ë„ &LÂ2q¦€s Îpü1K§Ý%4IEND®B`‚snd-16.1/pix/fmadd.png0000644000076400007640000004520011147553266012727 0ustar bilbil‰PNG  IHDR=ä²±JsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ"ó̲ IDATxÚí][v,©®DgõkOÇééØƒÔùp=xH ^™dfÄY^÷v÷ÞåBHB€ ffpQü&¢¢àB¢‡ˆº9½fà¿#ßC!þg€¨Þé!N¤Ï`fìøp¬èÁn gCÕñ¶#OÍ.Ьï©}A·”_`>`ÃÑ6¹‹=üq_}Ìw›ã»ú4Æ;aÝÞvo}œ´g×Gû»½;I/'šá8ÚgÏü@ýœ`>úíxwÞÕþ8¯>æ»ÍñÝc;!wœCËên1“pìœ`>Ö)çâ€c-€»@ô PþŒ…âcÅx1~¬À0_„­O.z´7x¤Nm«6I°&œÄdØa¼Ö¸€è‰íy\ô%|^?6@R„…q#1†Oƒã`ßX„_ÎÅÔîmÖɽʂá 9,2ÇæÉÐÈ þ¿0ßw´ø¸ p§€°Å7߈MˆžåκîœHŠøÀ¿¢° A<Â&®|Äãjþ_@œcüð‹°žî뇰7Dȯ=+  Ö*Ø@Þ‚¼¢N `Aƒýþ'Éuà#ˆ êa“ËŽ ïù“&Ä4D:0@\—äLÖX3ˆ$×UÀí€õô’œ{Cô€$6@ z@¤°ÆB?ÀÛDÏÍBóÀ¿ 1 3|ü Ñãˆ(ù_Bbˆ„ s pÑÃÌÉ$[n‚¼€è€ ;ù4¢‹"Œy-oœ~VË[£=XPÌÑ ;‰u¸SÑÄ4= I Nœƒó°žðλî=ÈàÒy „&DÏi:œ8+Ç$!Öi z‹ѳP„€èˆQë¡|°ÿÁæ=  Ã0VçD’bà.~ @ô‰ $«ðsؼ\enp=aÑÀY*Ñ€K9 ¸€è ,’N zêàŠ€(€?üwö Þûï×¼ð$`á "‚¿œ§Ýéaæä €‘ÜïÍCw3Š ‡8fßLô iyð_ˆg¸·ÇÑ$ ‰1D7@$=Xø€è€uâV;PµG,D`qÔ@’K ‡è଀ ¸äz@ô á07°'Dçv*a Ì/€y`/¢@‚ì>'€Œÿ`çÈ… 7;oñØ”E}ã{ŒÿhìdßKç¹Æß¿ŒïkÇ—ÿŠÜ¿Ñrþß#<ïÌýYgŽ9ƒû¯áûÌìˆÈQUáã®ÜO|¡òPéƒôß_ÿšð÷?oG{9ä8úî…:þ ±ƒô“ìÿzòÈã ñï Ú\'þ¯ÙÞ9GßîPßíµËHßÇšçâ¢òûõŽå{c-þŸãþ÷ç}­—üµÎCnþÛJîoù®Yîs| Qìhå~ÍÿÏb¯Ü?m¬ Ü_û]VÉû zfV5 ‹~éßH>V"‰®ñÏœ;‹¨ |$Ñsh=5þfÑóš4FrT=÷Cãx‚ÿÇßoDìŸYôÔŽ_ä§EÄϨ¤?lj» ž ߟ1þw2x#ÑSûl|*N°Œ±†û§Œµ‘ûk¾ËJyDÏŽ¢Gà§CÑælЙ|E%ß3ªÏÛ—ªšg'€ÒVwÎÿ­¾Æ„À*zjç~˜-&ù¿™ÿ*Æ¿êü· ž÷‹Ÿ9pÇOÑcåþÝ…Oƒï·^jÖ¾+ŠžܯÍÕDÏaEŸî!zî"|ÐÈ@yÒ7\=dÑóÿ܆ËÔbbß xü/ùÎÎÛOÓøOæÿ¥…í°ñƒûÁýlHÂ_Ëý ÷¬ÞàdYî÷CôøÁ¶áÅ?«š?ó7ÿ¥Æéú Ü7„çö‡ð÷Ïäþõc†§ŽÜî9‹ýÑM¢g?Çë ~8kÿBò»è7/ü'²ÿ”ñÁ=+Í?¸8Êÿ'ÙÿJëó”Ø?‘ÿ/É}à~ˆž)“éØt·àŸ6þ£Ï€ñß^x.r7áÌ8Ô‡xOç¾ìü^˜ûï˜ô]1ï÷`[p?DÏh§‹ô8iüZ/ø¯Vñ¨]ô¯Zñ[ò=†^î©°ÿ¨ñ_¢Xprî?ûEû)s î÷ŸAðŽæ~þk‹fN~_ôþÿ0í`>ÿŸ¸Ã]?pÿE“>p?¸Üñ_]ôìEüpþ{‹Þu?Øÿ¾I¸¿ßv¸çÌÜYÁÿüœ×i™xç‚ÿÆ¢gºã5ÿmï”Ì HÅþ­¶Ä§ö1º»$~HÜ€¹öø°÷$î¿£àïáþÕòp?p+Ñc}›ãòv€Úf'}Lü¦‰¾“Øÿ ¢ÿîÜלô¾lˆœÜîÏrÌRö_}íƒèY?ðëkDâg¶ÿ”¹EÅu7ß8Ë.åÞ¯Ë/ÇHúÀý­Âié¤{–ý6ÀÉãÜÑSt”ø»þ~J.gÓÍ9Úì‰èl›ä’÷•+›$ÄW™tœ1ñ ìâ¨ËWLºG&~Gò )ÿ[1†Î·¾ýfØ4¶ÃN_çüó¯KìÉ|%>á2‰ûßöøfGß¼Lì™ô‹¾2ˆû‹6]¹“ÞÁ1tOÑ“qˆ]P°¿EìXvÃJ<¡ ÃQ¿ƒ’¾¦\ìÈqÊ,_-ñä+±M’„â@"¶Ø´K¤æbˆéðuh÷Xcß·Á^1´zIôŸÛhŽŸžÅ.Á˜¿è-[|¥&ö[ ‡ØeçúßµƒÒö>…ô¤Ž0ñ‘|ö÷ÎH¬äÈ1=׉x¬1ê]>±¯¶‹aÎzDßû¶&Á“>Iw0þé{ÓTø±ª4_ɱÜâðãË™N²HWÌïÛfM¼ä ½ÏÏǦ.;o‡%?DŽ>Ön¾ ú5?•Žû&áß`PÞœ½cHµ.»ì!ø_ãûvÎ}'¥­(G\ä”}×çç܈ñšY×Fpe¡¥dóg7pÓI¿-gñ…0gÂXÏ~ZEµ‹7FvON†è Ô~J"ì-åË:«¶Xyze²O%|ž‰¢4V÷]&? yèvyÎÃæÝzÏ×Ï™u¡•ÆJƒ“žŒàñ»Ê$Õ”Ad©Îé±úsÁÊk­š¯7ÖWîóN"WLúü¯ÿÍæìZý—‚Oñ™Œ+bmáó²ÿ·3u%¾•ü´´ãÄŽõx%)ÖœòÏ'Y‡rñÚ˜ÇcEè8¯÷Úé‰?/x /Ñ¢…}cSœ •®Åù_GÚ¬c+&ì¸:¹cÅ"väDºôûÄñ[çµ#ˆ‡ ñ{×k±Œ»B¤¦3B ¾b)†ì:7³`®}TPpUñ_Æ"µÆ¦z¡aø¥ÙÚnF£Ü#ïz‚GŒ5o¬¦#9ÑÜ,•sNâ`écK¾9Þ.Q¬5åçè”–Äÿkë\Á“_×ÂMWÿ¼‚ž£®±òvì:%NáÁózÛ–Õ6ÁÓš4E »R]¬­P/\ä° ž ¶êßÂÀ¹‹¶¦Ä£òꪅ l-Í¿ÊË|š…X5…+9¡"•MüêbÍžDþ#ñÊùJÅe2óŸ¶ K£±Êײ°î#||;óX}Ç8²5b§>=ŽÍkusŽ…O)ö|‘Wq¬MÍËv9æÖXâè¾ì‹ó77À‡H´KÖ¦Íó僽­kî×¹%>&l¸Un<;à†wzØî¬ ‹“¼°ë‰w‡©ÝŸÚ/à/µðHö'åÒ#SÁp4#Þ2¿¹JÛ|Ü®ñ{Õd¢’ï×5èk¿à ùÓ~LÑdSæÂÂÿ9&Ää–ŠK³è uú‘W[Ò|L¬ímb3çí¿_¿©é’`ûݱÛCÏo˵k@²ËCAíØèîãøq¦àO|˜2ÜoõS["9÷˜›ÀÆ„ñæyÄý–v\5Ö½ _€Ô­kìJcí<ž¶õçý"_ã|ÅÇ&VT.+züÎmÕ*TlÎ*M~Ö!^ÿê˘$@¿Øúå“ÞÕŽÜÝ(ë.ϸ Kçì³Û]ÌÝüJ×á³)v*xè¯"—;ª$ü œ×Q‚GóšÒ¼Å“[-»Bݷ못<³’Üì‚§5§\hðyd´k³ë½_žålfõPÎÿK§¾÷g¼¾-¶Û#ñŠÇýl«§ŸoäG¢ ?Ö4ŽÑòè<£úsqÂR,¹_¹O™Ú´ó˜ÛÎ 8D!äy«å&ˆže’0[¬Ú‚kfRÒ›8` ü(®mZ›4Y/SçßL)sÍÂöyà•¸QUó€J‹ÇT»ÇÄšž˜t4¦¨ÊvÂ#é17>&.­;¥™±ÊÝrÌ­Kc¸w‘þ^Í.O&^÷K‚IÒÞïò°hSj,f”šYTqÿ°…´Ì+4h½´<Ûé^G¯ÛXá%KãÝ^Ù· ã&F•$F«Õˆ„cÒarï܈æH©Më>/¼Ë¸‚Û|lßÞCôø¯pk º3 +^r÷?;²q]>&ÁòƒŒi²§ðšy´“Œ;ŒuÔ.ú(£ÑÇâŶtLf„_ YÆ/-еï<ûGT_1¿,ÕîÄŽ+^Ôù°Ê}Õ7j´™b-*šâ˜´ÔîgáRI}u‹M'£J¸àSâ¨`V1ªïv1H …¶9÷yj ªÎÆýž³•íâ9n‹¢Þh·ÝžPZ+²Rš_,¾ÕNÏ,Á3žüZ¡c…O71“|A2ß*WžÇ¿ÝÓh®Åă÷µëÄÝžø> Ûë̽#âcÝ©ej«L*ž«ü1×Ô`s» ³] 0-¨Ì÷áXø áÓ–]ÃW¤iò:Q°¿”=Ć™=¸’Ìé÷HÖù£÷ÚYÚö'†Qës•ØÜñ‰®öÉ…7Î2¾ÚÚÇ>ÒŽ^oÖ:O£Â3^Vg’þüwÿ}W†Îù¤{›¿³Û6¯ãbrÌEï "2ó.Þî:d«ëúWmÓÂñÛyóÂíÜÏ<××#îŸ-\Úvy…ÝÝDÏß«óáO¼ 8þZZé™C2ÙÅjk8ÂÑxä`î3ú=|ëTù!XÛ–ͧl«v(šÆ¿ÌÍß‘Á^xb‡sÕþº’mÕ]•ÍÇ–F·"o-PÀ/‡Â(:›ã±b—§¾Cf™û÷¤5 N°ÙxËûXMn66iÌÄËÐø÷ô$˜wØåÑçÅüU ÷˜Ã ‹Ùµ»ãÑÝ}v;yÀßø{¹Ü´‘ÁÜÆÚÎÇ;P¾H ›cš)Ìë’P#ùïx—‡]ÿ.Ï{‘߸>‘Í]twœXK¬öUòX£e± mÈe²‘KUÆíøÆ ,oÕ”îñx]°zß9³,˜½÷ȺÂ5“Í}€ò3Ò=`IÇ4œÇZx häþFAX6éäu?Iº¹jüzs¡¾µwÚnÏ®‰½ÕÏÖ¼z0~·gäçù9ËØoy Ñîòì'.È|I¾ï;¥²ˆ1o°®¯)mdª0ÎZ1i]üæ“WOÞAÎö(OßíYá¥lª ‰Ðî¤$á­v›³øuW“»Éåw||lL2á87ÛmîÍ:ÚFù;™¤tÿK|6X4ù}ä7ÿníÎ>6ì|¼wÁ¾jh§—øà±æ 2ã„;Ë>ÀÜ/Œ•ªüÕw{,¢s÷‹14j^îö eõÀªNULo$VNtð0ÛYŽ eÇÚÖ©mÙ×|Eº‡¨ÈÀõ´ÿ×J¾U|hC!B¼Ó¶Pòþë—}±—\µÌy£ÆÌÍŸø>)23–jCâÑûž—¸ßw÷½ßî¸k^ ¯Cç<Ýaæ~×z´¶/×YˆˆÅ¤é’ýªwÙÚ”ÔœlÆøÆîö\ZôðvÀ.OÕEwâÀG%øûmó¯åø=ÙăçdÜ;&÷òxõDvÞ‚¢ÄÚ ŠSÖh–. lmߣÏê=¹¥õïøî|¹$õ޼£7dN§q½Ë3w¬Ç%¡ƒb!枤s(9w`b=÷×ó£´5'ÉDÍGÜ®$‰¥#òcŠ$·íЉ´i»<ã×Ëÿ]Ù¿Ž¬ªØù‘·ÀY‡tÕ¡Ñ.n \¹Úáwj{¡.¹šC¬<轚QÉêá•» {\Ó·c:7¶x˜Lt\\6¯+¢sDÒ3ÈÍÅZ:–ňê¶$v4ß¼ùö›Ç·i§s܉" GÙL a-/á±òs6›’£‹~á>ã°¶­Ô7UɶŠ`Otžl§wÔ·ÿÜ‘3Zd~…#Åþ¿{øNëØ·ñ´J7;ò JD–²ýF#Ã>•ùÏXo±)/g.Û7¥óLϯAôù{ýJã·~ SùàÌX]Øp–ý!æ,’I§"íl²oj~։ꙥw[a*Ç)oØ´|¨?Ï?ŽÝÃÉ•aßäµ]^‚ó˜mïw¥é i¹ÀìEócQ®°©8­ܯÅz)þƒØ¸XÁƒHh\mãþy~JcФMU¸¿Í¦/?K¿³6Ç¿…7aéoþC¾õbm £®»ËÔ”Bîæ9›ÿÏ›;/ˆŸBM™»/ç~¿Ù¹oaÝWæl©b'Õ´×ÞC0ýù3 ùuÄÌ—¹1vŽ’þ_Î':Bç)‰Ô¬8¬vAíYø >#ß~9x‡ÁÔ²Šü˜Œ‚ˆ†u{™´ßå‚jBi§'½Já•Ò¸âèŠhÎ$ÍW8wûúžŸäöOô<¸ž°Tæ,>™2Uôlù#R›ãÑŽŸ";G~K™*œIØÙþh²ð‹m›#¿Šþ ñZš·øËúÚø'ª>¸?)1%&‡$¾¯$aÆ»4Ö81åìwl^é•Ì+^-"u–NîD‡þ¹}þ¼ûòC·5‰%Å’2÷“ÒRüý‘­´Ç5î§ï×cÈ;ZÒ‘Bé#î/}¿—ÿ~Ía<ü q£Ì^ìvÄþ¿÷W¥¦\ÄÄÇß –"KñS>®¤ÛWù=¯y‰ß”甫Z…s©‰ES•ì3Ž8nÿ¹4Þ4îý^?üÜF{S«êëGW*ØeÞD”ÞMŒ×þw&±6·mÍ®Ãewzüû<c&ÂJ¢¿Ê¾ÓÕzZñ°ý`xU‚rU¦tDÏ~ä­J~=¿ÏÝ”!]ÛHYá¢]…hδw÷ræ³VïôªM¾šÿ½_zλGž¬Ÿ³=™Å"µàg¯Ëôßå…øÈç\k)þñ‡^sŸ÷§I•;öî6lôüa“¡ÿbÈ{OK‰µ=ü+·ÛãmãšÒÂý^BIôäS¦ìN)öýÿÿªô¸Ÿ3Ý­ëXüwTîw”%úm”ìHÏ{ªçŸõxLŒú±n¾OíÂeåþâç•»âɱIñ;eîŸFí¶Kù9evy^kÚ#­.ˆ>¦=˜mþúÏ?\ ¢,÷‹†ÿë·è3$™ß™þ5oñY¤m ›ƒÌ¸cQ»ø=‰*žûéø¦å9+¿<>:õ~ªKoüK•ƒý±N„§‚Cü:ñ{7BÛáBbrØÈ‘¢M™Û²þ‹{qž FªæþÑ~úŒÓâ¾ÂWXdíÎV”ÄwŽ5üë•ÂG:â\™ŒY’_òÄG‹Ð­åÇ¿÷›¿Ö$óo)ÅñYsñ½: mšøKf‰N8hKÇÞ¸°Û´µ1g=‚'Î[ÄE=Ü_‡…<²ªÛpkbc‡iG3Æ|Þ5·qÙD¿¤'ÁäRûVZxgâµ9.Û¹(û]z«rlòÞLµcc5ËÏŒí,³t$ƒþÎpü-|Ѹâáþ’s¯Âü7)l¶;EœS8÷ÙæÙ݆ÎJ_Ë¥æ^ÂVÆÖãæÖÄÿQº{ | ˱ b¼<ÿûãyÎøñ7Í€¯cU;<ç'ÞÄ oô ’;9ï.yïÜ_P—"÷Ûæ¾¾ÄVîyÒØÜ˜÷Iä‹jáœhë{;«œŸÿǗ̽©Ÿ…ö:ÚH-G|ü»UžéýùÏ^"¯š3Ã:T>7åüVÈå9+ó±ÈůãY£š^l–Æ¿Æýºl9*çSNåþš)sñÛ„[¾¹¿¡¸ý>޲Ú=øŸœë:âvíeAO*{ö’•Zyh[$¤7KÊ[ë¥@Ê\éÏP§^° áÜsÇ#‘Êœ½IϺ8ó ?_v”ìp®úg¬úÕ® ÍŸZTúîǦÅå¯x¯Æø»”ôU½þ(ÍÿÈXû¶%ÎòÑòïñ¯Uób}ÞFr +Ýö}üz3÷öã=mG¶ú/¶ÄZ؉µÀ¦Û¾OWXŠ V¾ë$wäckÝíwuGò4Á_aÈqÜo˜‡ˆûëlr?ïÜòº÷ˆÛeEt?¡¹ŠZ>Æj©ýÖÉÚÀLfþ@¢­”í~8êN‰7¶_’É%Ñ"_Í€4d51}0½¹0>›ïíøP©¾ˆÈóàc.yá“.Rñü—\©úLûë3¿$J‡\jÍÄ›` aÜßìöâû4®C¬…CŒ?õ½ššåed1Màþ8Ù}ÿº¯Üq¾AïÐ4ðãTî¯ø%¯mæþïqücåYìdvyÚÍVQ ÈsÿOÅçU+Û‘ÜÿúÌ]ºõ}ö%·±xI¹aÁk¬’¼ðãÜc÷ëþvp‚fBÇ{ðç’íÃõ:U´moØCõ[oþzœØ²ëxC=‰·˜ƒË„üþÇ0‰|î¬m méÍ­•¹+Š¿ñrìµÖþð7µt<° ×WøõÏÿW~RÎžÇ ^MîŸÀ_o;ý8vÄ$½4ÅþÐŽo”ÆíÆ2qû?ï?Ñ!|(ˆ2”˜ûÅf%‹>ÚÇþCñ­wü T™´‘¯ä~{ÃÂýŸßßøâþ4„¬Ïû9Óã9K?ÂÜ$9“éHe»ÍíñÿKâT~öŠ_÷l¼sHå¸ÝØ–O%"Qè2Ø)J­¼ÜÓÅí’ïô°¿(4.lÒüñ»O‹ÿþWp¿ ȯPýçU›è›³u.d‚á¹|-ßW?ë„”ë—íí']Ë×å¤3®rÄ‹ÏÃQ~^6ú{H,þïÞ's¡™BÍ›É÷&Îú–$¢Cÿ ÏSÿ(>fIîß¿ÛÚFWx€¼czª`%C¼PaÞ ¢G¼ÓSj|EŽEîùqùHä†h¬yéñ&])øuöcD&‹ÚG¾ œ›y—ÇZ(òâáå[?^2/ù ì+e~ÒÞ;‘â)nžBß–Gcåµ°4/ßÍüa– ; IDAT?oliÂd—g+íæéoèivß!Ýÿ9ûÛ&IáVj/¾IVHp"ѣǾþ†M3é©oõ|¹¤àÂ…yçÝ_ˆ\~‡¤”“=‚õ°°×Åñ»xeî°ø˜ô×µ¹yÍ¿ì‡Ï0ÑCëò{m–ô)z±ÀFr/ù‰—›› ]Tô”ÞØÑ„MqÞ âà¡ògúU@d_$ÿàcèXŸЩ‰j­ð‘ÆbyðK"þgæÇôh ý’uœðjI™c6=TúI.©AôD¶%AÌ="s» ¹³½±èaܪâ¥ð“¸ÈŠ6û˜šøc-ö—/†óW!z‚DOwÁäû|Å;&žðñt£4 zrôÀ€k’ù EØÂ9ò}iG\òíø1º$^,1Û½ZôG¢G¶m[Åñ¡$¥Ò#•³DúPbá¡P},ùG+µG·EQËQÇÈ-ÿr.yí=ö(Å´ûoQ‘)&±Ä=¥ïã¢Ýu£PŽm*ž>1$qÁßs$…|“è±Æ~²®E/k>–=žý?a¥˜9_ð}¾BhÄv(5ÃñE¿$øYë†h=–7µÍÿ»"7kÈ«Âç󉄼ÓÐ-s/ûñRÝQ甆çÇ<ɶe¡æm%‹`É»î/~ñïõÕq®*ñOp4.|=ªù$B®Ü<éǰ2¢Ç¯vˆšì_g€è‘ ØåYíú{~ÊÍ%ȳ=sþí“´*/‹žÒ±Ì pÊ Ñ²—ˆÿÉ'øÄE‰)=»y¿ÿQ+iúNg¼ðqÉþÞü« –ر&ZÔ½y“\>Y\í‹EOÎþ¿ûX¾ ýO̬ïôä\‹,w  ߣý1œÆ "ò„ ªÏvîÏV×£j¿^ ð¸_(&è»üáûÜ“¼Íé%}6±¡ïöÄ»½ŽØ‹C§ Ž\¥ûOOå¹GŠk|Té.U„Ããå¡ýõâSÞþìÊ…<‰÷œ¾öZ’ÀGfn¬ÜÿKŸjþž ÀÞŸ‘|Œ(L¥æ^î·í (<åwbá,“ûèâÒÂ=JNÆùÂV¤ð­:ÓnO™û“ÝžŠ<¦â;ŠØéÉÛ€TQPªYȵØÌ¦_„ð#$äÓOÚ›í.4œvûàí©ø›ÁöÏâŸô¡³¾³ãnŸOüö= o® UsÍþÝþ\Óø88Ë-U†´Âˇ©¡ñ`­?ÿ>ï Ä®XúÕAÑæëc1ï\ŽÁö_‘é€2Ëξ(•Z›pʉÚq²àr«µ-vVÖ½XH‘°Ûì2$Ñ3Óιÿ1‚JöóîÙC°éðFžý+6$]¢{½cëZu×ýbº¸n8ý(´©}²’û˜;y‘ü÷h¤]K1è¯éTÇYþîzoXŸ:4Œ*Ì‹¨êב#VôTµÊœriÑþ'kœbnÐqõëÊä/rœÞ)¤Lá»Frî?ÍÿÎI×ûÞä©\ÉðŽ-ZþN£ÄG¬^¿ýdþ+î¤R§ÏZDkœ¼ÿc«|òQ» ™â:ž–LrQ\qmQ£—7”6Õ1Ç%‰r—éÁ4ÝÎÒ`{Û©ϱqò7Ü-|82ÿJòîó5%̵þÌZÜs¹@Ï Wb&  6÷Wí¦ÒŽûK(ÎÚñZX^÷\ uÎ.x…>Û¡íÿ9¢éÝ!Y!UÿNOñ^gü%§CÓ¼áŸÄyÖæ“äö³³Å~Ζ·þí"c§§|Ö¶Ù­¹èÌ.§]L(´ó•ä_Z%ç”cfÒe¶Ò¶hº’aÁF¹ÑçÝ Ç¦¹1çÎDk\峕zVØÛfçÌEÆWþÆv¦áž;⯺šCxyÃoM·¢¨a@ñˆCæˆcùhº~œF:æÀ…|ß%aùˆÅ?GGÛòRâO¸j “ìÿqc•ÜÑ!)~3±,%29sýFw’™‰í‹øä¸JºÀ'wº”óån‘žú‘¼Ab¢t¡Ô¾5Á¿Ogª ¼o½CôúçܳeŽ9óÐiz¬R±½ò»cß׿9=± q¤|—'‰'ÏŸFs¿ÿçR^ôc@>Þ˜ËÒb5:ÚÌ®šûãñ|pE#4lQïtDsæÙdS!O¹óå>±èɉЬwoÓ•¡3s,&;ærŸÌ.iíÍÝëT¹Ìàÿa§{ãµ R¸ßßu’Ѝv’- ›0'ðv’ƒèÉ;hƒÐÉþ]¥ë{'H5—ßx©2¾W" Ëbª%¶5¾ ^ý²‹.&@ùîB¹f ù•ºð‰÷z ‹´³·mIYM®G]fMì婿®…µ—YƒE##B“óÃóì_š³ Š¬,za±À x2 z¾Bùü^[ZéŒw=JÅÁǤ9Õ:·ýÔ\èÜ%faúÔRÍ(ªy9¹Ï`©)D7¿â?Ü]— Ròsà3ä¢q‚€öKü3#ãcÑ=Õ¸™{—¡ãî—.P‹6Ñ#Ýç±Iµ3˜ÒÌ#·>ùɰÞíNOR[›Øh±ï”{mÅXkn´CY1/ù˜XøT ¾±¿hÝ/sk^ô”»Äæš$…&³è)ßKÉ ±™Ct|5Ù)Vs™4†Óµßó‚è;Tmp¯t— ¢G¨ø iWZ5ãŠO¯èo'·½f= |Ÿ«øI;LFoÌ&~éïÈ·øþ$ ù®eÂBâä߯µÇN:lé+õ%ÑSö¡|«Ïš¶¥š¿;!91U×kÛ–fÄg˜ôÙl¦u{W\•yûuœt-Ô‡–”üì‘Û٪ě.¼â]­ê—ï%Wçâ׿´úN.,—=}ÑiÅÐ-z!DÞ9m.ä=â“¥ç=â5ß z4Îå̳¡_}òÈ€W<îùiY+ O¹¨+ 5•y=ëwÙ;=5¢ÇÚØ5‰œ¬÷¥­{Mígc§5í6„$gyÿCjs›[øÏyj6YÄ9qAWIÝ¥Ç r•nóËô¤ìö˜DO9‰Ï‰‚¬¾é=™êº¥Ï½VMú)¼«¾Õ.z4ÁWx\¡]oÐ]‹Â;ÚÛ >93Ë¢ƒ9/ø-¢GüÞ…Ýí÷ËÉtk¿d8ò¨ŽÅÐQŽÑSáÓ/gwDvòvþ²¼…53PT±ÙÎý±±kD~¤Ù•,¥%q°‹kàþb©Z= i­ºM|_*èlÖ7{ž¿YÝÑ,ûž´3dzŒtǼßä(—ßÄBT-ÈdæŠs EKìÿséq&Cmë¾Ð6»a=1_ZÖþr\Ø M%ÑóŠÚ¦€Tp|qºåÝ¿ì#Þoé¨bÇEÅ®ÑóŸ» ¸ 8V}ÛmÏ…Äâ(ÏD*9† ÿQ÷Ï9÷#¾ì¬¼¢<ì5b!ùKH^ž³ŸçYÑ׫Ên”F~nx9:+¢žçûÕc%.h|%¥y{~Fü}ðݘ‹¿ž_ @fA—^È6ùXu…G·i‘žE¿råO×~_/Qb×yIØ0ïÒ¿N*ì$uF,ˆ_ß/+ÏȱIßKõYQðXïUN^{ø•³œœ°•û ¯mYËý:M)‚MƈØÍ×zŒØÎý–Û]®äjßJ-À~§]óD£%ö넪6ÎpÆO¥‡Íé#T…(‡ÜØZr5ûÕÇc;ù±zβ¢R^×Ò|„Þ-©M5‹Ac+ÞAkK'œsÎýÏíNõÎ 9Z:…oW ¹w:W&’¿´¯©jIÆJÔqµƒÛŸÚó²ý—-•.Gü:xp˜™“(d†4¶ÿÆêü¿}€¹# ´5ÉæØúkU¿‹>@ôÓä—pO¾›ÿÑñ_ª6¶&¼ÁÜæŒM)¦ˆð{¿S¡jñ5˃ÔMsŸ¬k„ã*·Hæßê{­Ü³‘ÉÛ×JGò;ÖØ·6­i]9ú¾‰èÚ?þŽc¹_ÊExmIÜo>y¢p’ç5˜ÀC#ÿ¨Î€%îïí2wYÑ´•Üã÷¹Ïa^SâÄ'~¥x‡ä÷—d3%1†×ÄeæÓŠ©Éî D°Œá…@æqu$*ÛTZõKý©qݳê§Îÿˆdld¥WÖùÊyk77› ÷.Ïf/Þ˜¿®ñš‹d‰Šý…õúã×¼¤ÚÊýj¬q¹Ûh}¬é…ˆC¹ß\åhKÄØqr¨ö.Y÷ÿ’Ÿ_ |jæGò•%_­SÁÓOеֵe÷~÷/ ñžˆ~ùÊÃÌXêÚ‘„è韡WøT“r©[®à„èpæFuå×à¸EÒáF…?:æLûÜ|â+°VË´Gør6Ž?$ñS8:9*Ù¯íêEVß—Ú”V-JénO³àoX¤‰ôGøÔʬ!àfïüÔøãë÷‹ÁQDÊÚô°uçÉýéU¶ûèFSú®Ü_qŸë—rM„ѽyà¨5…÷»š9˾¸šû¡íì¨C¨.z ]{`ä~ó.aíQˆ&÷*>]À~ëðÏg›¸Ÿ¸Ï%†q¿œk@ôô”:3V.ÚÖV|JÄ_Ua©X“ºn'ù—$Õïýy“dÔÎNÍ·¿3÷œ§å˜ƒˆ¼Úî“S£.øt–T%²!Ê'@ISÇÖf÷l]øÒ=k‰Ÿ`_ªý#ÈæuÓšdMø¥øWã°Lcðþ½´ØYŸ°3þ<~.Ôw8ÈÀÝÔZ×cÂq]á …n1žû»b²âˆ›f­éš›4òH?ú7­p •ý ûkÜo*.dr(ŠŽ©îÞçËR`àQó& ßämª ¶±µq¿oavÉF[½VtY½È!ÿ~`Úry+º¤KÄR@~å«šà‘ª:- ^%E™/ã„¿mb÷±°rßò½ÃN8¦0\&Œ/øþ¾ï“ðЂ_|™úÑy 5k7â0ä§<Ç-—iÙ)•ë Ñ†?¬ÄþðjˆðCìÜWÏQ÷¼€,_Òþ}“Pzç‰ o9¾lzŸ†þèžVZ’C¢Gs±G¦# Ÿ‚üîWß…82<*­qcÝשã.«‰¿ ¼9ª‹£w—É|ÊðÚaxþÔŽóolï¼Ñ@¬)¤úÝHîÿp0É5k~V!ûÈQuLç¬}‚'lìóKüi(1}Ü?’£¯ú8iöõݱիð1:÷îv!-ØÚbžm_­,xµïäâ#üýù¶ØÖ?(~ßÇÿjñ óM Jï4ˆ"yGÊÉm«K­…]zQ]¾hl=™ß勞ên5š¯D„MBûÝÒ{Ò#•òѵôÈÁ»mkáø€˜øH½Ìe²ZÁ©oõk…r¦Ej¾Õ{|Ô0ÿ–VòxdSáS/%ȉky[^ôW{$µÊ•„QiƒK«S×?Kü‘å¶ôIrdº ¦‰A‹KïŠý‹ç¶ÀýZëþ׃¿ f&íx‹ÛÍ6¡LSfý?ÊuE8ᙋòwýˆ¿Ë¢I ÇùF$z¬óV[„ü+žúï«eÚ&;W~¨Tú]j.é–DÖÄ@ÈS[›|;Rñð¼¸ßX€H}Enœð´©÷¸Ýé.r¯÷q´»¹9GßmëÜMDíÍœVÁóNš9óXWáN…HG‹å3ß[’_Þ›6JÆÏJØr‰õ Ñ#¾•K¢sÖÅ•511Œ]{Î úêó䦣UrrÿKÑŽ€í±<íeó×4I¯eq)¾Íà¿e2Lì =†ÅBæ}*WEõ1ÒÒÙï‘èùyVõÌ‹²U¤DÏ^Â'xû"}È^?zÉ[7ˆžq×0t^zÇáD^ü¶Ïêg¢§æ=¶&»˜ü‘’Ï69+¬cú÷õvy\ƒè±ò¿b,˽OA,*pÆïëé¢GÌ} ¢§46)Ö oÔ©6Ý[ôæÌò¾S^ôÄ1/Þö$s?¿…D’?ÒÒg~08¸Ã!,xÈm•øÚÅuäxšmú:æ°Õ]ì̽WW›Í1Ží®†2âá%ÙÇÖLÕÁ¾ñ«Iô¶Ô0˜ÓÒä§Ê0ž+ü䊂޼€ s?ˆ>?Óļ÷½ðA>žÆe®“b—y_b>1Òüès®øÔºÞéÂ.OÀ#ʻڣh¥÷Ä>ã:”å~k~1úm¯À1Tðä’ª¸Kã—ËÆ¼Ìýìݧñy]ò‹GûãSz¡ñõÇ·àoÅu¼:|D*æ/ƒ]êËvĪ8o,ÞkŸdžñšÝŽ—¼Ûæ~à™ó`¬2‰sã.Ù,1Z7^*VåªVîÑyÅöi©-†âˆŸ®ñXN÷½¸ù…ˆþ(«k¼_ knˆÅÞ78ÁNöß}ÓtŸc>iÎúò‹2gD»^›'²è  ÷ÙqÔØbî:þ±©Û²fбóèT¨ÜYU³hÔÚÖk®k—çÚ¢G™¸‘ Zu?cpÂ8忘DÑ~Î<ÁfÅ@Q*:íÁÕr‘°ÒÆíJ2±Ž$?õ¨XÕc{ªž9«•ݦ¼ìX™5r`‘Bæš/áXmµžvœw´­—ªçµªKò=¸öîLSa#â“ó,jÊýÙ]žiëI§ý/Uø\ØÜ´_Hαéün(œ+Wf‰¢·Ÿ*¸\[ô²ÛÓ?ùM¯q·'O|Ò#V†jq&Hׯ&ëÄHM~OLjüòD6ãZ›Ñq"¿‰Zl•ê¦J÷H,\a—g˜è_‹‰‡^JNèp_iÐßn´’é>¦VÎ »ÈYÕÆ]¾2Ç|ÜïÄæ„qçõrd‘¢xר¾öÙ¿–ð×ßyâÉcm{¤v й_wÕýÖ_Ùï{¶]_ôtÙQ ±Ÿ‘üHûØ»À=«Þ¢ŠDöX£Ù]ã~Î4ÆpÿgœóÏü"ÒÜÉšñ½Ïp´-öˆ~j]±=÷;ÝFôt­·…NG-£å쫾C…âywyjæªmý©;‰x{Ú5¶ÌK-±Z¤Ô.$&RðÿÌùîßuüFÙÑ¢>š˜ÄŸÂ;r¶ª{ˆûäÜokÿ‘( ºD†âË¿Ï3 1dªùÄ|Dž³Üï‹NfW¨t¦í—‹"48 ÔGNûïòT~g®9RZ+ípõaôѶS‹"J~lN="‰Ÿ›X‰»=5N]Ó•’ÎVkï§dIuÜ¢GŽ*\ûÎÄqW2~ùúRßkUUÆîöper¡xƸîíáF… ±³’5g§®ý^Hvþ;¸\ÙµW™äÝžV^+÷ªýöñ¶¼ÏµˆðÙx(Ǽw¨e‡b¼ùÆ>Hzô¼}T8-ÖÌÉøP‘½ÿeÿ–¢ä'‡–mÄŽ¾ŸüöEëŒãî&§=ÌœüX9§é¢f°ËÃEî1ù§Ž·ÓíÝŒ I)纖-X峎uëm.Qw4îówÚlÀb;éAòè+ •ó͵ùúÔ£mƒ#»«[¾ãŸrk+–Š/ƒ¨?aÛƒ”±6w,Û(yœÓö˜åüO*>Íãþºùw¸Á‡ÛvJØÍëngïÉ3Šðõ\+,T÷Ÿ¼àÉåb¦á-ÖµmœPl©9â&¿Ë3êwÝãx›¸…Ùê4´“K7:U’päª!Öð’[½MxÚ¼ŽÞí;=‰‰÷—^oG ÝíéOHÆÛ”åÝž¦Ž£ßÇ¿á#.ÒjÒOUÍxf\NªOŒãÓÖ¢DÙÏt1Fuƒå¬Í&ªSÿeÓXãyn9Æ:Ö|½-¨½Ï01¡á󀤛hTÑÀ0þdѳæZJëö-'VôÝ û,òˆê{ÈÞq¯Ù;géÜyÇø¬©PÍö_´#7)‚g‚MoÖÈ vŠZásÐ}æc&òø²Å™W’7ÉåWêWK¬¸ DÄ6Í_¯GFBZÄwT¢ª 5säñÿ¢G½°–qá2žåhÛèàißíI[uÇI#Wß¡°Ášs¹"IzGwüªH<¬‚G½¨¯½â“_sª*‡ùiÎÇü}ï2ŽlÒ—ñƒp·'J ‡=XXS%Õ9Ü}‡‡Ç<Ò:7aÈÛlŒŸñŽã::Áªz-Q¤q‰Sõ‚Ç,ÁÃZ·³a»ßæcÍO`P‹S“òì¥~˼qøçÎ ùvÐQÊ\±WãþÂ.Ï~÷z^1”;¹ãù7$+Z­×åéœÍÞ¼ÝNìq"/UêÛÔÎ&Ħ3“²QËĸÛ󿦝ÎÂEÁ¦9›å¸Ÿ2•eR\AÏ}¥ç o2÷s*¤£â[›54‘´8S¹7ðcóâ@fãÂnÏ>yÃŒ…°ö¡ï÷×Í›û¢¯ð™»ÊrËÚrع÷˜Ž9–~/Ñ“mOÈáOXÌzùºb‘Þz³SvT >;¯iAÄb`M¯x43µlõè¿S-R‚•û)/Ä=4q ÉøG-1D±'÷·ðm}Eˆý\°¥›Zɇ¹²;XøóZúÎÔNûm‹¯¿ø›Ç#9kµ™‡W Œmå9caEå<ÇjU㪎¢R!iR–ýÚãÃiëæZî«ñ.Ï.ñZî‰]—÷‡|k_׆ñߎwyì…iLö1ÉoÕéûöÍK†BR{¬ãô .ähHç¶û‰k‚|À»áV¶EXö?Àß—­9Ö6Iœ÷q“Κ[çõËMÙé° ŸÚ#XJ¬È‡{¿IødÆJŽÔŽ¢9NW׊ƂPa¾F(zeôwyÖNÂÛæ­·­wòÕþµØ”h`4,g‰ÿåF.¹sUàÅä˜z­àÙнm®W(„ܳ&º×Ó[¥aŠZ¾GÆ`Yë^Sï¼6·æìf´h u¬ÎÍ<ÎVK¬5ÇÚ_ç(éßä6°Ã»5ìò”íRhf¬'œ$Pµ¯~ýaW¼~ÍG^øèâ'ÿ]Xþ|a¬Ì 鈗®Ç±ä³†¶ÍcæWº7i;Æ÷Ú¶:Â#kÓZ¾&xr±Ú½èUSÜänˆ­ë•÷¹ÈXW[Ê Üé|Úp¯hëoÑ“ âŒ3ŸÝÇÉQX}KƪN¼½{»çµFø|þêóÏ~Û…h—è+%Ýê¼¶‹Ôë 6æ&ÁãÂdŸé¹:0Ãfa…šU>\ðtìö¨ÉIe¼î Äü˜nx##žWï¡Q9QûÄuí é{ ~œ~¼þ¹·]ðÔ$²éDz"Z]ìÖÕ‡Gsÿ߯Р<Óvxr±Ú¯úœÅT¶Î[ì+ÙµùËé¼37µðxU 9‹ÜŸÎ«B¥Ü f¯Âܽ·1ÿM³¸Wº½~´±j~*™¥~W½¾y@—èïWÓ:N¦Ä~Ú‘¶ ÿm+øÕÏSã5m›ðñø·¶iÁ®§\ìòÉϨ“—ÂùbãC±ä”3÷jbщùY ìç÷Ã(S{µ½'éyË7'­2/º»[L~üóæ9ÿf—’¾ÑÅ¿T¥ä}ºÚO»ßÍØÇþ³NƒXütªài´?ŽÐ¹ÉÃ.ߨ¤Ç¦µ S´uèH›K˜rѹðæŒý}³u|ed¸''|Îs‡g<÷XbˆÙè§‘ý—>"<`šÁý\èàä³hY½¿S,}Â"ç|Ñ/$]^¾è}”¢×.GWO>*j‰¡]DÿÀ‚ËH›.Á·{]¬ ¥Cîž QO.Øt{þÌ. 5pÿh¾ÝÍO ùTIpBôL ˜ »Ó»$êñÿîn—Ù6}‰B‹MªEŸø·x÷Š¡ø˜S‹Ÿ&$9;ñ™ô±Mõú©´Ð¬œø­Ê+³ùôÎ|ÛkÓUm’ÛõÅý¹Ý°•}%7~Ëna ÷÷Äý]?*þ—ç•Fî?’S!zN“2^4é[¥Ú±bâܤ rÓÊksâ$Ü·÷,z¬µþÆ èIDATÜL³Iï-ÝûV?Dþ)äÁ£ÚCÀž‰Ç¬¤¯ûQa¾¥ýÅ£¥¥€û×?%Ý(`щbïRÜ?ú„ DÏ%H€¦9-àþ–|ÃÅ>2½Cà.q‰2Gä§'~¸ZâîŸbÿYÜuÑîß9Ÿ¹ zN’$¦-=Ã7cî6þK‹W$Õ‰ÇêÿDûß­›RSâÿï*\61÷‡~Að‹y» ó¸ÿRñ|bî?­è!¢äç,ä=ÅùGÿdÇCðãˆÁoåž+¿7öE1?2ñ÷ƒûpÿ ¸ÿ´¢‡™“àš@àó¥æÑºð›Æ?*IÛ±Ò4:ñ9ôŽKãÛ —ã¨YÇD#ƒû/ÌýZÜTq§è߃?!ú×ñco[8ñ3߈à?àô½“Âÿ”‰íYìÁs+®+$4wJú¦qßÜ_+ô.ÍýÀ9×^tàÛµÜ?#ïèAðKú˜7.üOºýäÈšø\}{ÿRãï©øAp^‚ûoÏë_®(ïÈý-¢÷ªÜ¿êø»v©OÈý=‹:¿Åñ‡©8ÀñF…$¾;ñPìÎ5þŒ¤oéÄí›à¾Å¹ÿt¾?ÈþàþD?vynÉý=w~$|‡Ø?Yøo¶è•Ÿîñ/îÿÓÇ¿xò÷y]I¸_ÍŒþ|à,§*}Ü?˜ûNâÿàþ㹟øBg‘Îv¼J›àš‰Çl è A_kÿã_Ò׌ö§Í™Çö£ƒñ÷ÏÍqËüŸÿ×|Ï×ÐFøþR¾±…»ŸÚwký•ã æ»YÇ_=Þ}¿u>Jã?èñmñ5–ûÏœãXæÞÓ°‚W…ÿïmÓóž¡O>ì_3þsѳT:¾:æœNJøZìß;þe}Í`iáS áb¢G%¹QI¿æãFbÞã|Ißxùøw”¼zöýß2þ«ˆ+÷5wGîï™ÜøO¹–û¢g ÷_Môä„ãk÷eÏÕòž¡v0ØßÂý³æ¢g!xah•WÛîðQ×â×2þå}­`i›[Üý¸ è©·ðŸìû­ßu„ï/ë}D’ÖŽÿJ¢Ç2þ®ñîàÿ½ó¡ÿÔ¢‡y(÷_Qô$ã½³gôý#í¹ZÞ3Eødì?•û z®Æ}7Ûï9ÞKi˜8†3ÙgÊvýÅ„Æ~æÊ~=-1¹‚èÁZ°ü¸Ðqv][Ìú>hd I¶ÙkøãX¨àõñ3Ä â€3¢.ž˜’b€¯DÀÁ˜y‚¢€Ë'<°Ëš8b— ~vüˆ8+Ȱ°DÀŠ€àÆ\DLÚU@ôÀ-€£Jcò©Y…^ˆvî³Ìµ+p?Ó/â¶@b ÿ= þwf§à¬û;+ÈŽ]¸ÁM€$9 ”ñßÙäŒIûÇÛ889ˆÿ™ñј¹%àšöÁ1ëÓþ€è³\(&Þ=È€0À5Ž[ÂvÑ’UàÒ€`—@ôAR€dsÝE»5q;óÜ"YE¬à°•¹¢*àr‹(@ôܳ“ TŸæ&t°/w\³Ày| €è¸Èâ…€èàÂ@Â8€í0þïØ£ˆ Ñsag8;p$€ïÃ÷¢0&Ì*ô@ô—S¨>ÍYða_þqO>ÀÜxóÑ 0 ñÀæ¢H aA€»¢ç& " á8Ça÷ z€EDˆä-ÀYæåg6VüGbÄîÈwæ@€/a z„‰ˆÜ)¶ð/pqÑ áWþÏž@CÀ·1nŽŠ{ˆà6 @°z|CBTc‚è€[Ã]È ?€5€è@7æÒx@…ÜÑ €›1œÁ?QÄ· ®WDXÀN4~àz‰šðí}ˆ¤{ {ß5éoÞϘsÀZ¾€CôpRä- =À]$,Öˆ8ᢨõ+¸ž`-@ ]y.Vðoˆ$ ,O¢W÷Ã’ ®¶Ø#‰Çbmà[D€DùË%æb! Ñ,ï¤W&ØHŒ`ø=,,zF½,DüRòK¼Ïƒdèªþ£mði`lþßZ/—\iNšDÏ(ÁÃÌï$á ˆL¾‚÷z€ëÍ1Ÿ€P-z^be„à‰ÉD° x`çUØ1„÷:ó `-˜G°ãzœ¶Úœü¯60áL×vV’y`_¹{×:$º×™cp|ñz¸Ÿpã·é@ÚßÍ}f AÀéë‰öÛßÖ°3ì„ñß{¼wñmpÖ]Øð~ó±âœ¼EONTÔ ”¢§Õà\ µšá?(d®Œÿî¬øöªw¡ð½`3Ì%l†ï›á{Áf˜K|¯3Îe-þ7ÛPÚ¹Ké=v›ª­Ó×KÈÔ ><.zZ„ÍÈϨÅÿ`‚ù€¸ƒ½`3Ø ö‚ÍØ 6ƒÍ`/ˆˆˆÄ8ÜÀ… z€sáõ(¬ô0lËgÀ¬¼uÜ÷?˜úzŽãŸXŒÿ‚¸’à±ä¾Øé¹°àqz‹Cõˆ%˜kÖä¾=—à-ìN ×ÔÑ$€à`µÅÑÂ[à.äš=Ühd, ‡Çÿÿã aî¿IÿýõϹÏÉ}ÑCð¥³ßþŸ«ù,íÿ…„ÀùãmKâE?·`ãâ/°:´œµ&÷ÅNÏÅ…OK…RržžÏ8Ë¢ ìÏ·=¹¦5÷…蹨ðéùs6€;€Uø¶ôç-Ÿ‡ãmÀ©€ Øé–Féè‚Ôå­v'[{Á»?×1€ ÇÛ€è8+þ¢¢t.ÀËIEND®B`‚snd-16.1/pix/rkbang.png0000644000076400007640000004433311147553270013121 0ustar bilbil‰PNG  IHDRı×w™sRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ &À,aÀ IDATxÚìÝwTTÇûøñ·R+XQTD4v‰½C¬d튊h$bì@4Fc7ö†;*hÄ‚-Jì±c‰KT,¨,‚"mËï~ܯ,˜O\ ÏëÎaçÞ½3;wwŸ¹wfrèt:B!Ä;Ê)U „â? §OŸfĈY>ÀÑ£GQ©TtéÒ…ˆˆ©Q!„ÈŽ䨱c—¥'ïÛ·‹/L`` þþþ\¾|YjU!²S¹uë'OždРAY~òîÝ»iÓ¦ ¹råÂÞÞž¿þúKoŸ¤¤$?~üÚ¿ÔÔT9 âƒJII!99Y*Bˆwdœñ­­-#GŽäÑ£Gÿi!!!¬_¿>SúóçÏÙ´i»wï¦uëÖr&ijk×.âââpww—Êâß÷¥E‹´hÑ"SzDD›6m’3 >Ó§OgôèÑR"Ûx§»°NŸ>­wÃÞÞžëׯ V«yüø1ÅŠ“ZŸóçÏgyß'NH…‰ì@îÝ»‡§§'cÆŒáÔ©Sxzz²dɽ½½½™={¶òxÀ€DGGãééÉ?ü€½½=Í›7—ZŸñãÇK%ˆÿÌ;wðôôdÒ¤I™¶-_¾\ùÿøñãxzzâééÉñãÇØ»w¯’véÒ¥,å÷ðáCå9kÖ¬yå>iiixzzrúôi¥|žžžlÞ¼ùµåË taYYYáéé©·1Ož}¸{÷.9sæ¤L™2òBˆ×èÚµ+]»våðáÃLœ8‘‰'0jÔ(Ž=Jÿþýyøð!}ûöå矠oß¾,]º”aÆáëëKDD;w&,, cã7_…èÙ³' 4 {÷îtîÜ™ Ю];e{ll,3fÌÀÓÓ“"EŠ0}út<==yôèß|ó EŠÁÄÄ„iÓ¦ñôéSú÷ïÿê’+W.Ê•+÷ÆÂ”(Q"Sš‰‰É[Ÿ'ÄçäÒ¥K˜™™agg'•!ÞÉ!Cøæ›oèÞ½»Ò›sóæMLMMÉ•+~9ÀÑÑ:Ä‹/pqqQn8Ú»wo–òË“'ˆ&L˜@bb¢²-..Ž… Ò¿å;|êÔ©XZZÒ³gOŠ+F… F¥Re:¾ŒDÙʨQ£þçcœ={öÆ;mذ .Hå ¾ùæ~úé'ÌÌÌÐh4tíÚ;;;ÌÍÍ Z–»w—?ýôiii@zW•««+:u¢B… o<†‘­\¹rÅàyÞ»wøøx©|À… (W®³gÏæÈ‘#ôéÓ777ƒ—£_¿~Lž<™­[·rìØ1e¸EþüùÉ—/ëׯ'::ZˆB| nܸApp0Ç`Μ9œ9s†ž={ÊÖ­[ V–¢E‹Ò«W/LMM6l˜’îââB`` %J”àâÅ‹o<†±œR!„0ŒÁƒ3räHöïßÏŸþÉ–-[P«ÕtëÖ¯¿þš„„BBB˜3g>»OŸ>lܸ‘R¥JÁíÛ·É‘#Ç[ó355U®¹Œ5ŠU«V‚ yòä¡W¯^ôéÓ‡#F°|ùrœ)[¶,M›6eÞ¼y¬_¿ž˜˜®\¹Â“'O8räJw›´@„Â@Ú·oÏÅ‹‰ˆˆ M›6˜™™aaa……ýû÷ÇÔÔKKK•çR¿~}ˆ§@lÚ´ ##£·æçççG•*U¸|ù2‹/ÆÉɉÐÐPÌìÙ³qwwçСC/ÓØ±c™2e U«Vå?þÀÅÅ…nݺqóæMŽ9BJJÊ+—ê0h–J¥R&䊈ˆPÊ!Dv’’‚ŸŸ“'O¦Y³fJº³³3‰‰‰„„„¼uþ©ÿR`` ®®®™Ò===‰‹‹ãÆ1aÂ"##‰'55SSS÷@„ÿg×®]R ÙŒŸŸvvv888pìØ1´Z-{öìàÉ“'888és¶EDD¡ÌßvîÜ9=zDXX·oßÎR~qqqœ>žÛ·oS³fM%íÁƒ„††’’’BžþœéÓ§Ó¦M,--9|ø0^^^Ô¯_ŸØØX½Õ¥"„ÒµkW† FDD³gÏF«Õ²`Á6lH£F€ô©Lš4i Aƒ¸téOŸ>ÅÅÅE³qöìÙ,å§Óé”ÈÔ©S‰U¶%''sþüy<==™9s&111<|øÅ‹3tèPe´|\\cÆŒ¡E‹´hÑBË'-!„0 Œµ8¦N ¤ÏpëããÃܹs9r¤AËR¼xqJ•*E·nÝ8qâÍš5ãÖ­[lÞ¼™!C†àçç§ì»páBâããY¿~½Þi!„ݸqsssfÏžM‡øî»ïøé§Ÿhß¾=S§Nå›o¾1H9¬ÌHššªLÎø:?þø#«W¯¦bÅŠ<{öLIÿûï¿Y¶l‡Ê´Ü®!„0€bÅŠaddDHH©©©8::*óMýôÓO|õÕW.\Ø eiÒ¤ 9sæÄÇLJÈÈH }dzÑ¢EÑét´jÕŠƒ’3gN<</.\ ÿþL˜0A™Z]£Ñ`dd„‡‡‡ÁÊ¡R© ,,ŒÈÈHåöâ2eÊ0oÞ>žˆˆ©ˆÏÐéÓ§ùöÛo™8q"FFF„††°cÇêÕ«§Œðnܸ±òœ%J`kk«ÌÔ é×$¬­­ßš_5077ÀØØ˜zõêqêÔ):Àõë×ñóó£I“&T©Rå•ÇèС=zô !!!ÓvH(„°hÑ"BCCqqq`ðàÁT¯^ è­±1räHéÝ»7µjÕRº¶¾ùæ®]»FóæÍ3­Mþ*}úôá—_~¡wïÞDDD0lØ0zöìITT>dÚ´i¬Y³†¯¾ú H_(ÊÍÍÞ½{“””DïÞ½yúô)ýúõ£wïÞœ;wŽõë×KBC[¼x1óçÏWçÊ• ###¶nÝJždÈLµZ-+V¬ÀÖÖ–Õ«W£ÕjÑjµøûûckk˪U«Ðjµ¤¥¥)å[¾|y¦¯$€!„üòË/lÚ´‰´´4lmm¹zõ*¡¡¡h4*UªDRR·nÝ¢}ûö”*UŠÖ­[³sçN–/_N‡°µµÅÑѽ‘é¯ãáá¡´þéÇäîÝ»´nÝšàà`Ú¶mˬY³(X° ÉÉÉDGGcdd„¹¹9>>>¼xñ‚èèh7nL§Nðññáùóç<|øöíÛÓ¼yó·æ—ÀãLjåéÓ§Œ;–þýûãééI©R¥ˆŽŽ&GŽ̘1ƒI“&affFtt4–––Œ9¥|•*U¢_¿~®R¦LÊ”)Èí—âýyöì>”Šºuë¦<.UªÇgàÀL˜0!C†àííÍÓ§OÉ;7&L [·nXYYQ·n]öïßÏ/¿üBÇŽ_9àïŸvïÞÍððð`÷îÝ2IIIh4©ˆÏL¥J•˜4iS§N¥X±b¯ÝoÍš5Êÿ×®]ãôéÓz·¥Ÿ={–+W®¼5?ggg¼½½_¹m÷îÝʤ´´4Ö¯_ÏæÍ›yñâ>NoÇŽzùÞ»wOYÍPˆ©Ÿþ™«W¯JE|fÊ—/±±1¡¡¡¤¥¥Q·n]‰ŒŒdÍš5™Z ŸéÂB¹~ý:®®®xzzâææ†N§£L™2,]º”"EŠÐ¹sg¶mÛ&D!Äÿ¹zõ*ß}÷³gÏ&wîÜ\¿~ *pãÆ Ž=Jß¾}ùâ‹/¨^½ºòKKKJ–,©—V¢D Š)ò¯ÊpåÊRRR°³³S–ÑÍ™3'UªT!W®\ÊïܹscooOÞ¼y•©àóåËGÙ²e%€ñ)Z±bE¦©$ħcæÌ™„„„ÀàÁƒ©\¹27ndöìÙôï߀)S¦Ð¦M¼½½©W¯_ý5%K–dàÀEÛ·o—ò ›5kcÇŽU(P€´´4:tè 7EHÑ¢EÙ²e ðk˜ñÅÊí®sþ: 6¤råÊŒ3 Z´hZ­`Æ ¤¦¦ê- ½}ûv4 žžž@úHô]»v)­’’"„P´hÑ,M×nllŒ^Z®\¹2¥½••VVV¯Ýncc“)-cN¬ 9räxc¾r–BˆEZ Ba 111üñÇäÍ›•J…V«%((€Â… Ó¢E ’’’ؾ};~Á¼I“&ÄÅűwï^¥•P§N,å—À®]»pttÌtá}×®]$$$`ddD×®]غu+©©©o,Ÿ´@„âøî»ïèÑ£=zô`õêÕhµZæÎ‹F£aÖ¬Y@úÚ~~~h4fÏž ÀßÿÍÆ‰eÙ²eYÊkíÚµôêÕ‹=z–iû¬Y³ôò}UÚ«Ê÷Áˆ² Ô·ß~+ï&!D¶áãã ˆ‹‹ÃÆÆ†3gÎàââB©R¥puuåêÕ«Ìš5‹îÝ»cgg‡««+{÷îÅßߟîÝ»SµjUºtéÂÚµkùý÷ßßš_çÎ7nÜ+·?žèèh\]])P ß|ó ÄØØWWWž={Æ?üðÊò}°âííMpp0ÁÁÁŸÜÒâó¶yófž?.!Þë÷ŸZ­fÆŒ¨ÕjÚ·o¯L馤¤˜˜¨¤¥¥¥‘ššª—–ššJZZÚ[ó333ÃÂÂâ•Û’’’Ðjµèt:^¼xÁ‹/ÐétJË#))é•åû`DˆkÅŠ\¸pá½÷îÝz!Þ+++t:÷ïßçôéÓŸüë‘‹èâ“ðøñcù‚Ÿ´ýû÷ÏÌ™3122"::ZˆBˆ·[¿~=Û¶m#55•û÷ïS°`A&MšÄ´iÓHKKÃÞÞžž={R³fMvìØ¡L¸èì쌱±1wîÜ!--V­Zei$ºF£QººÔj5jµš9sæðäÉ<<<8{ö,iii˜˜˜0fÌŒŒŒ>|8iiiXYY1xð`ž={–©|@„ÂÀV­Z…F£aóæÍ)R„ùóç£ÑhÈ™3'...Ô¯_[[[ ,ȪU«pqq¡]»vX[[Ó¼ysvîÜÉСCQ©TYš kÍš5Ó±cG-ZÄ¥K—È•+¹sç¦B… T­Zòçϯ̵U¬X1\\\°³³£R¥J¯,Ÿ!„øV¯^­÷ØÈȈ­[·ê¥*T(SZ¹rå2¥½Mß¾}éÛ·ïk·/X°à_•ïer]!Ä¿"D!„‘ý¨Õj>êòÅÇÇˉ@úZäµjÕ¢uëÖÄÇÇóäɶlÙB­ZµˆàÑ£G4nÜ•J…——¾´mÓ¦MqvvfòäÉYÊ+>>ž?ÿü“ZµjqîܹLÛ]\\P©T4oÞ\IkÕª*•Š:(ï߆ ¢R©øæ›o$€ˆÏKxx8?ÿüóG]¾)S¦È‰:tˆ-[¶P»vmΜ9Ø1c dùòåœ?^™f=88˜Ê•+Ì¡C‡ cÛ¶m4mÚöíÛÇßÿýÖüöîÝ˼yó8þ|¦A²§N"**Šàà`rçÎÍüÁ¡C‡ÐétóôéSŽ?Ξ={(Z´(ÁÁÁ\»vÐÐP Bah dþüù,[¶Œ’%K0lØ0  ·ß¢E‹”ÿ/]ºÄÑ£GõÒŽ?Îùóçßš_·nݘ4iÒ+·mÙ²…é£Ý—/_N@@€2â=66–õë×ëå{çÎvîÜ)D! ­F„‡‡cggÇÇ3ŽO‘!„0J•*±víZŒYºt©!>‘‘‘h4©ñAx{{Ó²eKÊ”)Ãüùó_»ßË«æË—Â… S¶lY%­P¡BY^ÖöŸ"""§D‰äÊ•+=äÌI™2e(]º4FFF˜ššbmm­—ožS 7näøñã²ö‚ø(hµZnݺ…Ý'Yþ»wïòâÅ ìííåd~¾üòK½Ç+V|å~õêÕÓ{œ7oÞLiocccƒÍk·gÌõ¦òåÈ‘ãùôH¿~ýð÷÷Çßߟ9sæÈ»I|äĉ4nÜø•Û[´hÁþýû3¥Ïž=[ïzʶmÛèÔ©“ÁËñâE>,'R|r Dˆ7(W®·oßV?zôˆ“'O* e¸víU«VåÒ¥KY>ö‹/¸qã*TŠ=› F IDATÎ&ž>}Ê™3g033£Q£FÊ{êâÅ‹äÏŸŸ:uê’’ÂÑ£Gô¨jÔ¨Á³gÏ8uê%K–ä‹/¾ÈR~ÇçÅ‹ë88q≉‰áèèÈ•+WˆŠŠR¶—*UŠŠ+*åkÚ´)¦¦¦®"ć֢E þøãÿ¹Õ’q·JV8::rðàÁLéQQQ,Y²DNJ6’q'–³³3›7oF£Ñðí·ßÒ²eKÚµkÇÞ½{‰‰‰aâĉ\½zUYÓ<<<œ¹sçrúôiæÎ›åü~üñG®^½ÊðáÃõÒ·oßNß¾}¹zõ*C‡% €Y³fѲeKåoáÂ…,]ºT)ßÓ§O3_ˆÈV¾üòKΜ9cÐK—.ÅÏÏsss €——%K–TÎQ§N˜>}:îîî >\¹Ñ­[7Œ™9s&;vì 22WWW"""06~óWx×®]ñöö¦K—.4kÖ [[[zôè¡—¶lÙB“&M([¶,åË—çáÇøûûÓ²eKìííIJJbãÆÊZ&ÕªU£fÍš@„ÂP2Öü€ô‰ œœô¦Jÿâ‹/h×®>g›ƒƒƒò?¤¯ R¾|yÊ—/Oݺu³”gÉ’%qssÀËË+Óö}ûöáááÁðáÃIJJ`Ë–-¸¹¹Ñ¯_?X¿~=vvvÊú$ Ú…uëÖ-N:Å©S§8þ¼¼£„ÙÊéÓ§±²²¢T©RJðصkVVV4hÐà•kt¼/Å‹§sçÎxyyáï#•*U¢iÓ¦ôîÝ›cÇŽáàà@éÒ¥±³³ãüùólܸ‘¼yó~˜råÊ8À ‘w“"[)Q¢^^^DFF*·ôÚÚÚâååŹsç8tèÁÊͳgÏØµkùóççàÁƒ„……aiiɶmÛHLLäܹsÊþû÷ïgÅŠzË´ «]»vJ-cM`!ÄïÉ“'R ™ØØXLMM3f çÎÃßߟzõêaiiɘ1cصk!!!T¨PçÏŸ“œœ üßê­ ¤¦¦’––¦t7½Z­&>>ž|ùòñäÉ .œiccc:uê¤wÌüùóÓºuk’’’˜?>­[·ÆÖÖ–´´4LLL ßB†‡‡jµZ*â#LóæÍYºt)®®®4nܘuëÖñÕW_±téR† †ƒƒyóæåîÝ» >œáÇs÷î]lll8qâãÇgàÀèt:räÈñÖ<íììèÚµ+¾¾¾,X°€òå˳råJ.\¸@þüù±°°`éҥܺu‹ *P¬X1ÒÒÒXºt)qqq”.]š={öÆŸþI=ôf‹‹èB|D6mÚôÙÂÏ®úôéCñâÅIKKcñâÅ8::¢Óé°µµ`õêÕÊ$†¿þú+ýõ¾(TéÒ¥ äÆ@ú…í¬,j6mÚ4Ž9ÀÆ©Y³&±±±äË—+++eQ©:uêP«V-\\\§qãÆ|ñÅ*THY‰pРAJy%€ñ‘ §jÕªRŸ©–-[ê=Α#Ç+l*]º´ÞœT­ ;;»wÊÏÜÜ<Óñ[µj¥ü_¶lYÊ–-«·ÝÞÞ{{{åq±bÅ^»¨”ta‰OVPPüZâ’ˆø 2Öø_Ö?8yò$NNNJ]ˆÝ¥K—Ðh4˜ššR¹re½m·nÝRº‡bbb¸{÷.>fÄÒÒ’­´ (ðÖü’““  `Á‚”)SFÙvõêURRR”Ç666Ü»wOo´º­­-ùòå#22R¹1ÃÞÞž€råÊñèÑ#~ÿýwîÞ½ËôéÓÑjµŒ1‚:uêpÿþ}eß"EŠ(]TEŠÒ!æÍ›—¼yóR¨P¡,åùòê‚/ß=(8@õêÕ±´´ÄÒÒ€#GŽP£F ¥‹9** µZÍÇõÆ‹ÈEt!„0ððp¾ýö[®]»€V«åÌ™3JWÒ‡°dɨ—ˆ««+uëÖ%22’.]ºàêêJ¯^½¤"„†V¿~}RSS‰ŒŒÄËË‹¿ÿþ›ñãÇsýúu?~Ì­[·È;·ÁÊóË/¿èMòé«f¬›žÑòÙ»w/qqqøúúêÝŠ,-!„0€µk×2þ|LLLX¹r%jµwwwnݺÅõë×ILL$66H¿vqùòe._¾ÌñãÇسgœ:uŠ‹/f)χòÛo¿‘œœÌêÕ«õ¶=~ü˜ÇS©R%%íÎ;+Ý^ŒŒŒX¼x1íÚµ£|ùòÒBCjÕª]»våàÁƒ¤¥¥¨77Õµkר]»6†Aƒáéé ¤þvtt䯿þÂÃÃÔÔT¦L™’¥‘è¾¾¾Œ1???lmmQ©TtëÖîÝ»óå—_’7o^½`OÉ’%õÊuòäI¦M›Æœ9sôJâÒ ANœ8Aƒ ¤2>AVVVo\IpÑ¢Eʯýfº.1zôhFýNyÖ¯__iÁdÈX¨ Ò§IyY5¨Q£F¦c¼na2éÂâáääĤ"ÄGCˆBˆÅ ]X‹/æØ±c@úèJ!„ÈNúõëGbb"–––üòË/@úˆïyóæék˜wêÔ‰°bÅ å9NNNlݺ•M›6ðý÷ßS»ví·æÅðáÃô.ÐÞqššJŸ>}8p kÖ¬Ñûn5jÕ«WgÙ²eJ÷ÛôéÓ•)Q @ÜÝÝ•QŒ‘‘‘¯íWâeW®\áÙ³gÌ;WúÿÅ'ËÇLJ)S¦`nnNÿþý>|8sæÌáܹstëÖ-Z`jjJTT¬\¹€o¿ý–E‹1jÔ(6lØ@DD:uRî˜z“Ž;Ò«W/ºwïÎW_}E±bÅô‘Þ»w¹sçâççGîܹٹs'óçÏ'99™¥K—’’’Bpp0 .d÷îÝìܹ“Ž;*K’´ +wîܘ››cnn®·®®o¢Õj•_JB|ª¼½½)V¬æææÔ©S‡¶mÛ¢Ñh˜;w®r¡ÛÔÔNGË–-iÞ¼9Í›7§eË–h4ºwïN­Zµèرc–Z>Š}èСXYY1jÔ(½EÆbbbðóóÃÛÛsssŒ™9s&æææ$&&òàÁêÔ©ƒZ­ÆÛÛkkk¾ûî;¬­­•cÈ5ñ^ét:eQ!²»óçÏS±bE¬¬¬prrÂÈȈßÿ¤¤$zö쩌1„°°0~ýõW D¿~ýxö왲íçŸfܸqo=†ñ^i4,ñ‘Û¾}»T‚(P€6mÚpáÂ:DŽ9°··gÑ¢E+VL¹•×FŽɼyóضm<`Û¶m@ú ÆòåËS´hQ "ûQ«Õoíþ˜}ûí·Jÿ·¡d\°ïOjj*%J”ÀÇǶlÙ¢¤|óÍ7ÊûV­V£ÑhÐh4J·“Z­F«Õ*Û²Ú––¦—O†Â… ãì쌉‰ =zôÒ»‹wî܉J¥ÊTöŒcet)KŸ¥ùóçãååõÉ–ßÖÖ–[·nɉüÌøùùQ»vm6mÚDûöí©U«jµšÆ³iÓ&öïßÏèÑ£133ãÂ… Œ3†1cÆpáŠ/ÎŽ;˜9s&C‡%&&†9r¼5OKKKºtéš5k?~<¥J•bÛ¶m\¿~âŋӱcG5j666œ:u ½Å®J–,ɬY³X¹r%={öÄÜÜ\Ù&#Ñ…ÂLáÂ…IJJbÊ”)tîÜ­VËàÁƒIJJRF…*TˆuëÖqêÔ) ýîÕ *°nÝ:.\¸@É’%=zt–§2Éèž\»v-5býúõ¨Õj¥ûJ£Ñ°víZš6mÊãDZ°°Ð;F:uX»v-ááá¨T*½Eà$€ñ‰»}û6©©©˜ššJe|äºwï®÷8gΜz 4e¨P¡‚²^G†jÕªQ­ZµwÊ/þü™ŽŸÑ]dÚfee…••U¦ã4hÐà•·ÐK–Ÿ°Ó§Osøða?~,•! NˆŸ°óçÏS³fM©!D!„!„@„x?þüóO½Çׯ_§jÕª*THF¯ !Dˆ×›2eŠÞã   ú÷ïO¥J•”[…@„øìcaaA\\ÜGQ+++=z$'FHâc—/_>êÔ©ÃüñQ”§[·nÊúÿFll,{÷î•+>ŽâããƒJ¥B¥Rñí·ßJíF’““IJJ’Šøˆ%$$0qâÄw {ö쑊¯ou23ooo¼½½ˆˆˆPVµŸ¾àà`’’’^9ªV|Ôj5wîÜ‘ŠŸf D!„!þµääd(R¤ÈG[Æ»wïRªT©O²~ýýýéÕ«×'=¥½"Ä+=yò„[·nQ§NÿùXE‹Å‚ðððÿ´Œ»ví¢mÛ¶Ÿdýêtº×Nõ]·n]Ο?¯¬!„‘m,X>^*B!D¼›­[·òøñc©¡G«Õ’3gN4T†!ÞMLL 7oÞ”ŠÈ¦ÆŽ‹‡‡žžžY~λ̳%$€ˆÏ”ŸŸ 6dûöíRY°iÓ&ºvíúÉ–¿E‹ìß¿ÿ:Ư¿þ*wfIâÍïýòË/ :T*é%§OŸþOÖ~ÿP*W®Ì•+W²¼ÿ¬Y³øë¯¿ôÒŽ?Nbb¢¼$€ñzùòå“ ³¹çÏŸË¢b@Dvû•¼páB½´””ùÕøžcddDJJÊgñzV¬X‡‡G–÷?yò$AAAòF">eݺuË4ÃnHH—/_æäÉ“ï-ßV­Z±wïÞl[ïeÊ”ÁÚÚú³Yœ)::šbÅŠeyÿøøx¹ËOˆøœËûü…8dÈL-ñyêÙ³'ëÖ­ËÒ¾³fÍ"55U*Mˆø˜„‡‡óôéÓlùÚ7oÞŒ““… ʶçÿâÅ‹T¯^Ý yþþûïÔ¬Y'''®]»–¥çœ={VƘH›õë×sãÆLé%K–$wîÜܾ}û³}í:.ÛŸÿyóæñý÷ß4å9rä< 666Ó¶%K–dJ;sæ gΜ‘òÇ@nÞ¼ÉÅ‹³<…EJJ /^äòåËR›‰´´4îÝ»÷Êmÿý·ÞãqãÆ±hÑ"LLLxðàTž0˜Ë—/dzgÏ”´¸¸8 (Àž={ôöÕjµ8p€ðððLǹsçŽTæÇ@BBBøõ×_ Â××­VûÖ¬X±‚   6lØÀo¿ý&5úxôèS¦LÑK{ðàZ­–éÓ§ë¥ÇÅÅQ°`A©´wÔ¹sg6oÞüÙ¼SSSìììÞiÌÇ«4mÚ”#GŽüëçÓ¢E råÊ¥—ž˜˜ÈÚµk¹yóf¦ë#Æ Ëtœøøøl}ƒ†¡(ëܸqƒýû÷3räHÌÍ͹~ý:#GŽdΜ9¯}²¯¯/•+WfðàÁh4–-[ƾ}ûhÙ²e– ðìÙ3ž}údJoß¾½®\¹r™ÒçÌ™£ëÒ¥‹^Ú_|¡ Ð)R$ÓþK—.ÕµiÓF/­víÚº€€]Þ¼yõÒ‡®:th¦c4oÞ\)}üøñ:www½4kkk]@@€®|ùò™öŸ9s¦ÎÅÅE/ÍÞÞ^ +^¼¸^º‡‡‡n̘1™Žáàà  ÐåË—O/ÝËËKçå套–/_>å=ldd¤·m̘1:½´âÅ‹ëtööö™ò>}º®gÏžziåË—×謭­õÒÝÝÝuãÇÏtŒ5jèt ÔK:t¨nøðáziyóæÕèj×®é8£GÖ 0@/­H‘"º€€Ý_|¡—Þ¥K—W~~Ë•+§ ÐÙØØè¥÷éÓG7iÒ¤LûW­ZUçää”)}ðàÁº‘#Gê¥åÎ[ «W¯^¦ýÿyŽ¥¥¥ÎÍÍ핟›Wí/oÿ+W®œîÂ… zßï9tÿÿ'ÏùóçÙ¶m“'OV‚‹J¥"88øµÉÛÛ›ÁƒS¾|y ý"-@=”}2®©üÓãÇ4h„u!„øDLž<™qãÆeîÂz_ììì°³³Ë”Á€ðññ1؋߸q#...ï/7ôjw+V¬ D‰´mÛÖ`yöë×Y³fôVÙëׯ³zõêwZzõ¿àââÂÚµk1111XžgÏžeÿþýŒ=Ú`y.\¸Ê•+Ó¼yóÏþ33}útZ´hÁ—_~i°<ÓÒÒèÕ«—òÝdÇŽãìÙ³x{{ÿ«n,½Çÿ”,Y###"##)]º4«V­ÂÝÝ]og___,--quu C‡üöÛoŒ1‚ääd®\¹¢ô}f…‘‘‘Òk¦¦¦Í gΜÏÓÄÄSSSƒæ›q> ™g®\¹ þ>Êx­fff™>PïûýklllÐ×jlllð÷чúÌ|ˆ×š1¡¿MLLþ“<•w‘"E:t(ãÆ#22www:tè ·óŸþIéÒ¥•ÇM›6%Ož<¨T*råÊÅ¢E‹(Z´èGÛüÊ—/_¶ij(P@¹0ù9355¥H‘"Ù✚™™Q¸pálñZ­­­³ÍgµdÉ’ŸlÙõ~>*TˆE‹½vçWMEP»ví7^'ù˜8;;g›7¥¡»é>”råÊe›µ&ªV­JÕªU³Åk}Õ@ÂÏ‘±±1¿üòË'[~‰.„âÓ yóæ5èŪ©I“&ÙâuÖ«WO¹Îô¹kÔ¨9räøì_§½½ýGÝ-ý_ª\¹r¶è",R¤+VüOޥܯ+„B|4-?þø•JEÇŽ {ëþÏž=cúôé¨T*ÆŽûÊIÖ„âsqéÒ%T**•ŠáÇ+éÑÑÑxyy¡R©øå—_”é[ÒÒÒX´h*•ŠaÆé­ãsêÔ)åXçÏŸkÞIIIøøø R©1b>|÷ {O~ÿýwÝ’%Kt:N—––¦ûùçŸugÏž}ãs¦M›¦;~ü¸N§ÓéΟ?¯;v¬NˆÅßß_*A¼7Ç×M›6-Sz||¼nüøñºððpN§ÓíÝ»W·`ÁN§Ó-\¸P·{÷nN§Óݾ}[7~üx]ll¬îàÁƒº¹sç*ǘ1c†îرcoÌÞ¼yºèt:îÚµkºqãÆéßé5¼·ÈáÇiÖ¬~§½½ý['j;qâ 4 F\¸pA~¢¼£¸¸8øÖY²»¨¨(¦NúÆ} =íS8¿{öìÁÏÏO/-11‘©S§¢R©X²d‰Þ½ÁÁÁ¨T*¨7ÚûöèÑ#å×xÆ_Æø5µZÍÚµkQ©TŒ5Jo¾.C:þ<5kÖäöíÛܾ}›û÷ï+=1>ÄÖÖ€–-[²oß>¥þ[·n @Ù²eyòä œ:uŠzõê)ÇþòË/9{öìó?xð ŽŽŽ@úµ®ˆˆ½9Ú²ÂX¾J>/>>>ôïߟš5k*‘YZZÑÑÑr~ßÁþýû Ð[”J«Õ²`Áœœœ3f »víbÕªU 8àà`¢££ æÞ½{øúú2pà@ƒ\”/R¤ˆ^€=pàýõ>Q¨‰‰ ÁÁÁ\¹r… àååõAÆMmß¾]¹ñ$W®\téÒå“"·ñ~Æ2æ5[´hÑÑÑ¢R©˜?>Z­­VËâÅ‹•/¢=z(3¶ž={VI_±bcÇŽ`ÆŒÊ̳QQQ,]ºTù"™;w®òwwwÔj5† &0þ|eÛõëו_‚/ÿB\³f :Ž={öpüøqåuŒ?>ÓkS©TlÛ¶-KгgÏrøða¥¯÷Ÿ«ÝiµZRSSõæ{Fƒ···RÞqãÆ¡ÑhÐétlذAïµdÌæ{çνô|ÔçW­V“ššª÷§Õj !ÿ'*ýCIDAT,,Œfª»3gÎ(¿~Û¶mË®]»X¾|9ýû÷Òñ¯_kjj*3gÎD¥R±iÓ&t:&Syÿy~9¹s甲oܸQ'U¹reîÝ»—åõþk666øúúâëëK—.]>¹)èß[ ¤jÕªüõ×_T¬XFÃýû÷©Q£†²ýÅ‹ìÙ³‡† *¿H*V¬ÈµkרX±"wîÜ¡lÙ²ÞÁÎ;¹víšò%U³fML•*U;v,ÁÁÁ¬ZµŠíÛ·cff†N§S~©ÅÆÆòí·ß²zõj&Mš¤¤oß¾éÓ§3eÊ.]º¤|@_¼x¡ƒ-[¶`ee¥<'""///æÏŸÏŠ+X³f2…vF÷KÇŽõ~%nÚ´‰[·n¥·FÉ«.š››giªöíÛÓªU+Z¶lIpp0'Nœ`Ö¬YôìÙ€ãÇsöìYŽ=ʪU«Þx¬iӦѣGeŠü .°oß>¬­­¹té’ÞkÉxÆ ÓKŸ?> 4ÀÌÌì£<¿ .䨱czùNœ8‘FѨQ#Nœ8ñAÞÛÞÞÞ”/_žÀÀ@~üñG~øáªV­Jxx8þþþzûºººÒ©S'%è/X°@é²iÓ¦ÍGõ™}ù;1ƒ™™  ::šâÅ‹+]]œ;w>|ˆ……yòäÁÞÞžëׯ+—ÂÃÕIn3~ìØ±ƒÚµkSªT)ªU«Æ¥K—¨V­÷ïß§H‘"ï|þ{ ½{÷fݺu¸»»“3gN\]]•k">oçÎÙ½{·Ò§÷ã?²páB"##)^¼x¶aü_yöì)))$&&ê­•‘Ñ_Ú½{w7nŒ©©)aaa¬]»–sçÎé«K¾jn§öíÛ³bÅŠ·æ¿bÅ > ¤¯ë1ÅHݺuqrrzëó»ví ÀÑ£GߺoÆÌÏYajjªÜáR¾|y¥«âàÁƒ”+WŽ5jàéé™éy¯Jû燿FJ×È«tëÖMoN¹ï¾ûî_C_//¯ÿ×Þõ…4õÅñÏîÆÜ\WÙ´ÅÊérJ„RÅ¢‡ÀmP™> aîÕ¸ÓÅ Ñ"ÔÁ—Þ|±F±‡zì©(XDZÔZwîÆtÃmÍb¥ëi›¿Ôþè¯öyÛýÞsÙ9çÞï÷|¿ßs¾ŸË•qüøqœ8q‚Œ«V«ÅÁƒÑÒÒ²n±XLrYf³yG“ÉDù@©TÂn·£¼¼v»###ˆÇã8pàá:¹rå nß¾ññq”••áÒ¥KÐh48wî¼^/y×.\¸@Rýüù3Ο?ÉÉIR-Ýårall £££P«Õp8›ãýÖH[[Μ9‘HµZMÉt:"‘EP¢V«ÑÓÓƒ¥¥%Èd2BSÄÆÐÞÞŽ·oßÂb±K!äª#¿{÷V«DV¨ÀZ8¦Hþk¾/^¼H­¤6ƒ?æÖðœÇ@ø#äÆËëõæ-n:::`±X‡¡×ëóÚVWW“Çââ"JKK·ål]]®]»F¶èJ$ây \½z™LJ¥’Ì›L&ÃåË—‘J¥ •J©ïÅb±d­¾Ýµk"‘UP¥Rã8|úô %%%[ªø[ ˆX,†F£Ù”L¡P@¡P­Á@MM ž?N\|¹\·Û 8zô(©û/‹ÉšÖÖV !›ÍB$eY444Àãñg±, Žã(¼µ°Ùl·€X,FWWñàÁ¼|ù‰¤ ’>yò$®_¿þS«e™L†7n`ff÷ïßÇ«W¯àp8ˆœã8*ütêÔ)<|ø\cf³ûöíCII Õ—\ŒýñãÇÔþz½^O©{÷îÁívSŒ†Û9¿N§N§3ïYoÞ¼Çã ƒXZZBss3ZZZÀqÆÇDZ¼¼ ‰D‚¾¾>bŒúûûñõëW0 “É£ÑHžùìÙ3œ={<Ï£ªªjK}´Z­„µp­qŸ˜˜ Þ¿\qØÁÁAܺu ß¾}Ã0°Ùlëê©ß<†¿ ÈÖ«x-‰ÖíÇz2¹\¾e(žDÿë‡Á²lÞK°ÿþ¼ûA@,#Š$W¬/•Jáýû÷dÕîp8ˆâœžžÆÊÊ ¤R)4 ñƒÁ QDR©F£Ùl<ÏSù¬ÕÿeõVíÊÊJhµZ¤ÓiƒAd2èt:Øíö¼-«SSSسgφ>üB}Ïd2ˆD"TÕ×µ÷j7;;K”½R©$[-¨]]‡Ã0øòå ü~?¹^UUEåw¢Ñ(Z[[Ièo'Ìo!,..‚çù<Ï#7~sssˆÇãØ½{7å&“IÈår ª}2™DWWnÞ¼ùC²¼¼ A6ehb±A ¿H/'S©TÇ­ˆ¢)ââOž;xúô)ž}ú§ÜìŒ>@©TæÅ¬ÿöùÍy_étº`ž¢ˆÿ¾„ád™­Œ!IEND®B`‚snd-16.1/pix/jam.png0000644000076400007640000000407111147553267012425 0ustar bilbil‰PNG  IHDR:»õÙR•bKGDÿÿÿ ½§“ pHYs  šœtIME×  IMÁ½ÆIDATxÚíÝÛ²¢:Píòÿ™óäi*„ä2ÆÓ.Q6(LW¸,ßÛ¶m/€‰ýñ‚@Ð:A èZÝûý®šÉûý®~ ÀcAw&ä¶m{mÛ&ì€.}® ¬šyº†™ÖÛžmJÐÝ¢dCS· ]– :'€i‚îf¥¡ö=¦ç8ЫèɈT å¸_¬À‹”ýô³ÓZ-kéüSÏ=»üŽÑÁ u}û^ò¥ÕNkrgæ>ÿÌò :Ð~‡Î°ÂçœÖj™K«¹ïúµZ~AÇp• ëV¬%!Ò : ËŠõÌ[êĨ º ¹3a—ºUÐ݇ޙ×9,EÐÁdö•L8„;;í©å ·åž—O?w¸¿RÛHíö1ã];± úõ¢Ú'/ÞFûç5»ú© Ë}c:-}žúDZ Ï5RÀ£€ èÜÇ[Àhœ\øû>¼^ùãÝ­ÎZÞ±Ì-–35MÐÁ W;-Üùk.Q¹r™[/§6M0£M©i¹þu¹iW/s«åÌMtÀô 耠ƒç¸­A ‰õ »ù=ÿÊ/¤Ü5v%Ë™›æ::¼JÝDnZI•{U\²\5ËR;M›&†ÜÉk¯É²M­M›&`zŽÑ‚@ÐtÎYWTI›¦pº6MÀPW:=ìß§Mн£VLßéGM7÷iÓ ‚üKЂ“»B¹…8ë †œ€SÑÁô•Ü·íQ‹öGw-·6MÀ?avv˜ªMÓƒÖSß$Œ¹“kÓD mš€é9F:AÐ9g]aP£µi:;ÿÜÿ„óJu3t0hÀ•Nï¡MÓ™ù§ÂZEÇô;xî[}¹°CmÿœÜóKæÕ:œsó/¹xø(¬L‚³ÉK‹U‚‚&ÞŽ~GëP:üݶÍYW˜½²u¨¿ïJ|t"|Mø¸ ÃØé×_ÐÁdCÖ†­5ÃÚÔº«è`À áÉ6M%gOk‡Ø5?™èd ^ÍìÏRî/I½|¢MSÍü¿ëPzÑsÉë 樒ÉM?;íêåŽTh¹–LÀ]ô£ƒÈv¨Qç\œŒ#A`è t;ÌÎÝäÿzõÙ¦é—eLMWÑÁ w¦]Ówço­ÊMkrGóo¹ŒîŒ€ÁÅîç,}]ªÊMkµÌ%ó?»ŒßêÕ½®`HÛ}€§Ö#7í¨Òt0aÈÍ24O]†–š–Ò :˜th;ÃÐ<ÕA86-¬üöÓ²vxG÷¶–½ËK`ò¡«;=Tt0Ý5<óXúc9G?¤Ó2€Sÿ;<™þ]³üûõVÑÁàU[îÇdbC½X££ÖH­† %ýñ~YÆÔ{!è`ÐÊíÌóFhÓtE›)mš€éiÓLÏÉåË A0òÐhS—JÝÕc›¦ÜºiÓ‹\é°? ¹žÛ4åÖM›&XL®MS®]Ñ(mšRÓµiNU|#…{ÉÐV›&X¨âk=üì-ĵi!7mØiÓd‡{³­[i›&ALOÐñwE\ÿ¾æ~î°Ç6MG¯×¦ ³p¸{l„6M¹uÓ¦ sE+#mš [€iÓLÏɾlWÿ!AB CW §0ÏBŽÐ¦©æyÚ4ÁäwtL;r=·iª}^Ž6M0¸\+£}µ3j›¦3Ë¡MÎ.±~Ú4ÑmeⲢ놶³½·Gë£M,páÐvöœáãÚ4ÁC•ÆSA0Ó¶fHî^W`š/”ÒðSÑÁÄaPÓŠ©—6M©¿÷gTÃajìuÚ4Á„avÔÊh„6M¿.‡6M0‘UÛ4åæ—{¡+K„‚KXÖ¦ èî,c…pCW@Ð:A è`hN¢ :A 耠€ t=Ó¦ tWѦ 0tt‚@Ђ@Ð:A èŒÊ@‚†²m›àt€jNÐê‰ËhÓ?nDZN<ºÿ¿•…½WBÌÐ@Ð:A è`8Nr:A è0|›ø=CÐA’ÛÆ št€*SЗ—`ltï÷»ê ­}>ÔîÀ+Ÿ¼8»îöÉ¿>¹7µä ®}¾ˆVŸû™íäè5ûí÷luåzÔ,ÓÌ`mÎ|z݈lwÛÿ£çåZ¦¢{2}0ÀÐAwUIzæ[Îÿð?ü¹ÿGèOÍ©¸€)*ºýÌ’Ô­}>@C×X`åBLÀ={o¥”½Ü}æ>ó¸3˜ž ÀðÃåÍ@E èºvû-`µ»îß?cû\j_¬}ü‰}ýs÷›øt (àxËí¿üýÔ¾nèÊe;{£Ç2s!!踬2Ðú{žêNÐAA•ð ¼X¥÷},÷øþõásró©ý¿¹ù ¹q}zycg/WÚIR;Kì8Lê¸PìñšóèxQîù*¹mº}ýÖ Ój .µ³„¿Ç ±_>çÔ|J·5!÷N¾©}±öñ§öõÏ;BÍFf\gxûK°µÉýqÅ\`¯ú9¤¦×<þÔ¾þ±›ÑC˜« rßü±¿KwÚ\h(;Yµê^WFVݵ© ¹ù8ë BNE0ºÿVçKnÂÜIEND®B`‚snd-16.1/pix/jackson.png0000644000076400007640000003307511147553267013314 0ustar bilbil‰PNG  IHDR@«dE_bKGDÿÿÿ ½§“ pHYs  šœtIME× #E‹îú IDATxÚíÝy\éÿøñWû©„T&#»²F–Œ“eøŒR"GŒ,!ûXÆn샙I“5“-2¨!dÍN¶Š4fäX£TJ*Úëüþè×ýu¦ÌG*K]ÏÇcÓ¹÷û:÷y»¯û¾®÷¥¦T*•‚ T@ê¢APA@AA*^ÌÊÊbéÒ¥<~ü¸È•RRR˜7o«V­"==]”¢P*ž?ÎÔ©S_;?66–Aƒ( K(š¯ pG¥ÿþE®´oß>>ÿüs ×®]£C‡Ò¼U«V‘œœ\äzC† ¡N:ïü$=zDll,mÚ´©°_ôßÿ €……Å{Œ‘‘‘\¹råµó§M›†ÎÎÎôìÙSšž˜˜ÈêÕ«‹\GMMyóæ‰_ºðæÐØØ˜N:½Õ{÷îMvv¶Ê´ŒŒ Z¶lIÇŽßKŒŠŠÂÁÁÛ·oS¹rå ïÝ»÷AÀvíÚaffVìõ prr*4ýäÉ“Œ?^@¡xðŸ 6l`Ù²ehiiýë²uëÖ-4íC¨&ÇÅÅ‘››[a¿è7nø¯UÌM`` >ÄÍÍí_—ÓÖÖ¦Q£F…¦ßºuKüÂ…Uä3À˜˜®]»Æ¦M›¤*qHHyyyôë×K—.¡¦¦†µµõ’111Ô¬Y³BÑ·oߦAƒô1=z”¤¤$vïÞ ÀãÇU‚د¿þÊàÁƒ6l˜øå¾gOŸ>åÌ™3œ9s†¤¤¤wZ› )rÞÙ³g9sæ ‘‘‘ÒõSpŒiii\ºt‰3gÎðçŸæ?"y=AÒÓÓÑÓÓ#((ˆ.]º¼ó/K.—S­Z5-Z„¡¡a…¼`år9¾¾¾æœppp ''GD¬Ræççlj'HKKcðàÁtíÚµÌ÷¹råJüüüHKK#""¢ÐüöíÛãìì̵k×ðööfÕªUÄÅÅñ×_±|ùr7nŒ­­-NNN±gÏž7« ‚ ¼jøðálÙ²…¤¤$FŒÁƒÊ|ŸcÇŽååË—øûûš7zôh>ûì3†N•*UèÑ£3gÎäÌ™3èéé1|øp:wî À¨Q£˜9s&{öìíAx»Z]Q—%===tttþçñdgg“““CFF†ÊüŒŒ *¼999äääTœØºukBCCÅ•+‚¤Â@饎Pq)•J²²²DA”L&“þ~Ý]Ù»™™IFF†Ê1hjj¢©©©2M&“¡££ƒšššÊ2â P¡<~ü˜5kÖðã?ŠÂ(M›6qüøqÒÒÒÞÙÅþýû¹zõ*IIIlܸ‘2sæL GŽÁÆÆ†Í›73dÈ‰ŽŽ& €?ÿü“M›6Ѹqc:wîÌÆéÒ¥ ŽŽŽ"VÉÉÉT­Z•çÏŸ‹ÂJE§N022 eË–ïdŸfffŒ?^åNoüøñÒó¿eË–¡T*¥—ýúõC¡PеkW>ûì3/^Lff&íÚµË߆ø*˿ɓ'³nÝ:\\\Da¥ÂÄÄ[[ÛwºÏV­ZšÖ°aCéﯾúªPÀügÏ¢W»í‚È#B&îAx+»wïF&“Ñ»wo¼½½‰ŽŽ¦zõ긺ºòðáC¶nÝ €½½=M›6-Ñþ’““ñðð sçÎtìØQeþâÅ‹ÉËËÃÊÊŠ^½zqùòeŽ= €››ÆÆÆÒ15lØ''§²»LIIáÚµk\»vëׯ‹«Ex'¢££¥ëîÞ½{¢@ÊÈ!C˜2e ÄÇÇãïïOÿþý  ..Ž3gΠT*155eÿþý%Þçõë×‰ŽŽÆÊÊŠ]»v©¼ÍŸ1c.\ OŸ> <˜ƒÒ»wo,,,HLLdèСDGG3gÎöíÛǨQ£8xð`ÙÀÄÄDNœ8Á‰'8}ú´¸b„wB¡PH×Ý7JíZ.¸“òmÛ¶M%½ÜÎ;¹}û67æþýûlÛ¶Y³fQ½zu>ýôSfÏžMI{ÝΚ5 ###êÔ©ÃêÕ«‰‰‰‘æ=yò6lHrr2©©©ÄÇÇS»vmŒ‰‰‰áÎ;¬[·Ž°°0”J%©©©eW®S§Ž”y$==Y³f‰«F(s_}õ•ô0< Ÿo399™óçÏÓ½{wQÀ¨FÄùóçÐÒÒ¢^½z\»vMê¦WâO¡PPµjULLLÄKŠäÛo¿eÛ¶m¢ „rgÖ¬Y8991}út:tè€ {÷î%>>žM›6I„ vvvxxxеkW+[[[N:% â5ÜÜÜD/‘·dnnNÕªU¨\¹2uëÖÅÊÊJšß²eK©ÆÛzu{5BOO›7oJYÄcbb¸{÷.AAA|úé§TªT ¦OŸŽ››ÿý7cÇŽeΜ9hkk#Þ B1¾Mñj!!!hkkãææÆÚµkñôôÄÙÙ™L†ƒƒ&&&L›6 ===¦M›Vâ}N›6ž={rãÆ ¾ýö[>ùä-Z„B¡ oß¾=z///tuuIIIÁÑÑ{{{ìììPWW—z¯?~ÈO '  ŶyóæBÓŽ;¦òùË/¿äâÅ‹%¾û¨]»¶ôb«`{¿þú«4ßÕÕUš^¹re®\¹‚ºúÿUrW¬XÁòåË¥Ïjjjå¿ œ••…¶¶¶To¤¡äÔÕÕUþûç´.W°¨í©©©©ü÷Ïe_¥¦¦¦rŒ"Ο?Ÿ P«V-=z$®^Aòƒ¤(AŠ+##ƒ3fÐ¥KéÅÚ„ ËåŒ;Ȉ«oß¾888pâĉï3..ŽÞ½{Ó¿ÿBC;$''Ó»woÈ¢E‹¤—YÏž=cݺuLŸ>€Áƒ#—Ë™;w®€‚ ¼U«V‘™™‰††NNN\»v›7oâëëËíÛ· açÎôèѶlÙRâ}îÝ»—¦M›2oÞ<|}}III‘æM˜0™LƦM›˜7oçÎãÚµkØÚÚrûöm¦L™Â¹sçHIIÁ××—   "##E,ïÒÒÒÉd¥ö Fqww—Æc>{ö,>ò»#ž:uJ¥úöíÛKÜäÕíòìÙ³×.ûìÙ3ìììpvvfìØ±²ÿ~’““¸yó&aaa"–w.\ M›6Ò‹ A( õêÕ#''‡зoß÷~<}úô!22’eË–ùc~DEEÉÈ‘#ùé§ŸŠ\O@AxKgΜáàÁƒòÜŸ?ÎÂ… 177ççŸ~ïÇcooφ 8zô(“&M¢}ûö@~Ó˜Î;ãçç'  ”¦—/_JUªŠfذaDDD ¥¥ÅÏ?ÿLÇŽ©U«5kÖ¤S§NÒXÔ,ñc˜W·×£G Ù·oÞÞÞ@~;¿ˆˆÜÝÝÑ××/´~Ïž=©\¹2–––´lÙ²ìB'%%I£¯gffŠ_‹ðNÜ»wèèhþúë/Q ex˜““Cbb"†††Ì›7KKKär9õë×§mÛ¶èèè0oÞ<444pss+ñ>>|8 …‚AƒQ¥J777~ûí78@PP»víB&“1`À”Je‰ÞÿþûïìÚµ 333† ÆÓ§OÑ××'<<œ-ZàîîÎ… X¿~=ÉÉÉìÚµ‹ºuë2räH‚ƒƒ111ÁÓÓ“ˆˆ<<<èÖ­›¸¬P·ûêê/ C(‘cÇŽñ×_±k×.~ù嬭­hݺ5FFF˜››S½zõBãó¾ ]]],--©\¹²ÊxÀÿÒµ`œmmmš5k†¾¾>´lÙ’7²oß>öíÛÇo¿ý&ªÀ‚ ¼=ªV­ú¯]ÒÞkkkRRR4hãÇ—Æ"*Š™™:::RûMQá­4oÞœæÍ›#—Ëi×®Ý{;###öìÙƒB¡`ÇŽXXX¼vÙŽ;Ò±cGär9¾¾¾åûðÎ;TªT‰5jˆ«UJ‘½½=¿ÿþ;›6m"**Š*UªðÃ?p÷î]æÏŸOÕªU‰‰‰ÁËË ???®_¿^âž J¥’¥K—rúôi8€––?ýô±±±L›6íÛ·K/[´µµùá‡fÏž=DGGÓ½{wBBB˜5kå¿ œ––††††H ¥lÑ¢Eܼy“û÷ï³uëV†JŸ>}زe =zô`äÈ‘lÙ²…G^¨òÛX·néééœ8q‚5kÖðé§ŸÒ¸qcâãã‘ÉdÌŸ?CCC ¿Qvnn.‡ÆÝÝ.]ºðÝw߀†††”J_TA(¶&Mš°hÑ"•i£FRùlnn^h™’¨Zµj¡íý÷¿ÿ•ªã¯Ò××/´l÷îÝ í,^‚‚Pa‰;Àr...SSSQB™]_:::T­Z•ððpRSSÑ××ÇÊÊŠääd"""€üq|MLLJ´¯ÌÌL®^½ äW}¦À… PSS£C‡dggsùòe , Úµkpåʲ²²°±±ACCCÀòîСC…ÆOJÏ–-[Ëå2ãvvv6dÖ¬Yhhh0~üxÜÜÜX·nîîîìØ±ƒÌÌLªV­ŠB¡z_¼­eË–qéÒ%¬­­9qâT«V €mÛ¶áéé‰R©dÒ¤IDGGsôèQ:uêÄÁƒ9pà/^dáÂ…TªT GGG&L˜PvðéÓ§„„„H”BY»uë÷ïß ,,¬Ì÷Tâ«ëׯ“ä€äé鉭­--Z´ 88˜—/_âãヺº:r¹¼ÄåtëÖ-öîÝ‹¶¶6iii¤¤¤HðĉüôÓO4mÚ”éÓ§Ó AÉÍÍ%##ƒììl‚ƒƒ™5k={ödĈe³³³¥ÂPxW^¼x!]w¯š#”®+W®0xð`¾ÿþ{iZAR=== ¿ë¥ŽŽ@©´ÄPWWGWW™L¦2ÏÕÕ•!C†ðÅ_0jÔ(lll8zô({÷îe̘1ÔªU '''œ9pà...ùÛ,«ªY³&ƒ–†¡ûtïÞ   rrrÄ\NY[[K×ÝW_}% ¤Œ\¼x±TFz+-ÞÞÞܼy“ƳyófºuëÆÜ¹s  55•Ý»wsôèQ>ÿüs6lØP¶ðC¤¦¦Vâ‘©A€õë×ãé鉗——”µ ¦W9//œœrssÉÍÍ-ñ>•J%ÙÙÙÒv ö¥T*ÉÍÍ%//777rssÉÊÊ"77—š5k’““Ctt4yyyäææ2lØ0éŽT4ƒ„2púôér}~ÿý7¾¾¾¸ºº2vìX,--=z4›6mbøðá4kÖ MMM† Æ”)Sˆ-ñsÒºuëbggÇ’%K8yò$|÷Ýw$%%ñå—_bkkK×®]騱#+V¬ gÏž,_¾œP¥JÚ¶m‹ƒƒݺu“6ˆ·ÀŒL&###CDóòò*² ^0>NÁ³±]=ÉdT«VÍ›7“œœÌo¿ýF»víh×®¡¡¡Ì˜1£Äûš;w.çÏŸ`ðàÁ1nÜ8 >|8æææ¨©©Ñ¹sg²²²¤‘á©Q£ŽŽŽT¯^ÌÌLé»°‚qrrB.—Ó»woQïÁ‘#GÈÌ̤ÿþåâ|jÖ¬)ýݦM•y†††tíÚµTÿñþçö5j$ýÝ¥Kéommí"÷ýÅ_¨|U`A*,q(Â[ñóó#22===&OžÌæÍ›‰‰‰ÁÔÔ”#F…vvv4iÒ¤DûKNNfõêÕØÚÚJƒ_Ý»wO%ÙB‹-¤>ÂIII¬]»–Ñ£GcddÀáÇIMM¥ÿþåûðéÓ§|òÉ'âJ„R–œœÌáÇٳgŸ}ö>>>ìܹ;;;üýýÙ¼y3...P»vmœœœJ¼ÏqãÆ‘™™IëÖ­=z4111@þ˜ FFFØÙÙÑ´iS©FBBóæÍ#''‡J•*pôèQV¬XA‹-Êÿ ···è&eàøñã$%%1gÎððð`ñâÅ4iÒ„¥K—„©©)&LîºJÚ$77—… pöìY©ÙÍ«C¡.Y²___^¼x§§'³fÍ’ò:tˆgÏžqêÔ)QáíÑ¿–,YòÁô¸ ¤gÏž\»v]»vÁgŸ}Æìٳپ};éééxzz²nÝ:Zµj%^‚‚P|¶¶¶899áëëûÁô¹xñ"666üòË/üöÛolÞ¼™»wïDFFÛ·ogùòå,[¶ oAx ±±±ÄÅÅa`` µ· ò#@þ ˆGñôéSž¨««£¡¡A5 ‘^thjjbiiÉôéÓ¥;²’4h ¶§®®ÎªU«ÐÐÐ`Ó¦M*ûpppû,{àÀòòòÐÒÒ*Û¨¦¦&Piœ|iÑÐÐÙ`ʱ‚dÁßBÙ•ó?ËWSS³P (4¥Sþ¹½‹1E-ûÏåÊ,šššÒ·o_ÒÓÓÅóiß¾=—/_~¯c¹–•f͚ѬY3…7 ä¢ʯµk×âææVhº\.gÇŽ¢€>0©©©Õñ*•Jüüü>|8éééŒ7¹\Θ1cHOOçÂ… ØÛÛÓ¯_?J¼¿;wîЧO €··w¡[™™™Ìž=///fΜ‰\.G.—cggÇ£G€üôYË—/'--MÀò.22R¥³¸ðaûç°’ºÀÀ@Î;ÇôéÓñòòB©Tâëë‹L&cõêÕ|÷ÝwL™2… ðý÷ß—8çøñã1b«V­býúõRP+°jÕ*233quuÅÂÂ___Ö­[‡•••”ÿ/88˜3fHÁ³Ü¾Þºu+ß~û­øU B8yò$7nÜ`Ò¤IT¯^@ú½ 2„   êÕ«ÇçŸ åß+ CCCzõêäg{~Õ¢E‹hÓ¦ 7–Ž@¡PP¹reLMMyöìþþþØÙÙIë•Û]*….Ba›6m"##ƒàà`êÔ©Cýúõß۱ܻw½{÷’––ÆÔ©SY¾|¹Ô#ä—_~‘ºÃ.[¶Œ:uꨌQ$ªÀ‚ ÛóçÏÙ´i>>>DEE½×cQ(ôë×¥K—²wï^þøã©Ýä7˜ÎÊÊ¢S§N<{öL:fA(¶¨¨(=zÄÝ»w‰à÷ß`×®]|(O…ì òõ×_sìØ1¾þúkq% Â[˜;w.³gÏ&// СC&OžŒ\.G[[›Y³faeeÅ’%KÐÐÐ`öìÙ%î ²bÅ ¦OŸŽ¾¾>NNN˜™™ñÇ0hÐ ._¾Œ³³3ÉÉÉlÛ¶ììl ¥L0¦¦¦RZ~ ©‰^… €zzzÒkpAŠÏÑÑGGG•iÞÞÞ*Ÿ»víZª)ñ›6mÊ¡C‡T¦}÷Ýwüøã…–Ÿ8qb‘Û™6mšôw¹¬§§§“››+%A¬ˆBCC177ÇØØXüZá5ÊeŒ‹‹###ssó ûÅæää ¡¡QdµÃÀÀSSSîÞ½+~‚€M¿~ýðóó«°_ºŽŽ•+WæéÓ§â ¼•FI=-ZµjÅ;whÛ¶-r¹kkknß¾ÍÏ?ÿLûöíéܹ³TU- ???š7oÎÿû_† Rè1–¾¾>zzzxyy‘™™Éˆ#øâ‹/prr’zÙ$$$ðÍ7ßHŸßé3Àìììw’æÕv>EF}uuòòò>¨,5¥íàÁƒÿÚ¼ )DY•††F¡ÎñBù±}ûvÚ´iÃÉ“'¹ÿ> 2„qãÆáååE@@ÇgçÎèêêÒ¿ÿ§Äß¾};;wî¤V­Z¸¸¸/Õò<==ñòòBWW{{{âã㉉‰aÇŽ|ÿý÷DGGÓ¸qc"""8v옴ÍR¿BýüüxñâE‘iÕªUÒ+ò²V0*ÔëØØØ0zôèr{Ö«Wï_§º¹¹±xñâB®K‹­­­Ôÿ]ºzõ*7oÞòÓ¢—†³gÏŠˆ÷mÚ´!77—+W®Ð»woŽ?NÛ¶m¥yAAAS§NjÕªUâ}êééI#Ëý³‹gHH< U«VØÛÛ#“ÉHLLä·ß~£qãÆT©R…<<<1bDÙ@SSS*W®¬2­à.cÚ´i*ƒ¿Oãǯðñœ9sÊÝ9U®\Y¬ûáÇ¥²Íõë×êz%äg|~òä –––?~ü½Ë´iÓ066føðáüòË/ 6ŒÎ;Ó AV¬XÁ!CسgnnnRCé2 €ÿyD:,áÝiÔ¨‘tw ®»²5a„fÔŦM›J5ÐqãÆ‘••EFFƒæÁƒ\ºt‰Û·ocffÆŸþÉÑ£GéׯŸè "Bñ:uŠÎ;«Üy/\¸°`ÁªT©Btt4ÞÞÞìÝ»—k×®•¸!tnn.Ë—/çܹs8pMMM~ùåRRRX´hwïÞÅÃÃY³f¡¡¡ÁñãÇñõõeÏž=4iÒ„éÓ§cmm‰‰‰T5O©… çâÅ‹ÄÇÇóÉ'ŸˆÂxK&&&*åçââBFF^^^tíÚWWWºuëÆÆ¹{÷.;wî,ñ>7lØÀŠ+8|ø0žžž˜™™Ñ A´´´°°°ÀÛÛgggêÕ«'-È/¿üBóæÍ¥í|ûí·Ò£€B…âîîN«V­xò䉀¥På|Õ˜1cT>שS‡¥K—–Ú>«V­Zh{é±úõëG¿~ýTæ}þùçR:®W½šKT… %66VÊ_'âPþ™L†ššéééèêê¾óý+ 4hðÁ•Kdd$Ïž=ÃÒÒ’*UªÁ‹/Ð××§y󿤤¤HM’4hPân™™™™„……ðÙgŸñé§Ÿ¾¶¬²³³ ÀÌÌL¥ν{÷ÈÊÊ¢qãÆâPþ—š5k¢­­Íýû÷ßËþçÏŸÿÁ•Éõë×éÓ§«W¯fܸqœ>}š Aƒ8qâ“'OÆÃí[·2hРïsùòåÌŸ?ŸàèèȳgÏTæ_»vMÊò²jÕ*f͚ő#Gppp ..ø¿qEþüóOq(144d̘1eÖ8¼<¹sç½zõbñâÅ8;;އ‡]ºt¡eË–\ºt‰ÔÔT¶mÛ†ºº:r¹¼Ä=Aþúë/öíÛ‡ŽŽS§N%%%…jÕªI󃃃¥NaaaA__Ÿ¡C‡²cÇ|||øæ›oصk[¶laذaèèèP£F œœœJ¼ÏñãÇ“ššJóæÍ5j111*ó;†««+“&M"11‘Ö­[3vìXîß¿Oll,»wïfÇŽRfiq(B±5nܘaÆùéÅXºt)Í›7gÙ²eabbÂäÉ“¥àTÒž 999,Y²€óçÏûçâÅ‹˜™™ù/À Ú':::’™™ÉÚµkiÙ²%ÎÎÎÒ]³€‚ Û;wðôôäåË—ÄÇÇ¿÷ã™:u*:::…^r¼ªvíÚâââÂŽ;hÙ²¥¨ ‚P|¾¾¾(•J"""¤¦'ïËßÿ¡¡!‹-ú×åÆÇ AƒX½zµt')  Åf``@Æ i×®:u ""@Ê´òüùs?~LBB±±±%ÞgFFwîÜáÅ‹Rfž[·nñüùsÂÂÂpvv–z‚deeIZZwïÞò›æeffR½zuZ´h!ªÀ‚ ¼gggš4iªU«èÖ­r¹œ .ÊŽ;ÈÈÈ`À€èééQ¿~ý÷±³³ÃÁÁºu뢡¡±±13gÎdÁ‚øûûù/g\]]144ÄÞÞ ²³³©Q£‹/æÑ£G4oÞœï¿ÿ^@A( …€%K–0{öìryŽ@[[[úliiÉ•+WÈËËC]]mmm,--¥ ¥ÑVqðàÁôïß??pij¢©©‰»»;Ò2[·nòSä¤Ë/XvÙ²eäää ¥¥%­#ªÀ‚PÊöïßO¯^½ŠìÌÕ«W?ús”Éd¨««†mmm)ý䧯’ÉdÈd2• õ¶ÔÔÔ¤í$3ÐÔÔT¹³,´¯[öŸÇ"  ¼C="::ºÌ÷sîÜ9QØo@@A(‡ zL”•¬¬,âââpwwò_PL˜0¹\ÎØ±cÉÈÈàÒ¥K888àèèÈÁƒÉÊÊböìÙÈår† BZZZ±öyïÞ=úöíË€زe‹”b+;;›¥K—"—Ëéׯ/_¾$::;;;FŒ!%cIOO'88˜C‡‰(ÂÛ»yó&óçÏ—Þønذììl|}}ÑÔÔÄÓÓ“ &0yòdæÏŸÏ”)Sð÷÷çÖ­[øúúÒ¨Q£buâææ†‹‹ îîî¬^½š¨¨( ?+ÏÉ“'ñññ¡K—.L˜01cÆ0xð`ªW¯Î²eË€üD+W®äÑ£GÒ6Ëì%HFF†Ô@² =‘ ”µ¤¤$) [BBB™ïÏÈȈÄÄDLLLJ´íÛ·KÍ5>VVV¬ZµŠ±cÇJÓ\\\:t(AAAÔ¯_ŸŽ;ÿ—eèСҲwoªZµjôîÝ€¯¿þZšÞ¶m[|}}‰ŽŽ&%%…™3g’——GÆ 133#00€¾}ûR­Z5nݺUö0**ŠM›6"–ðîKÏ¿ ÞÆ–%är9¾¾¾%ÚNtt4/_¾_à[044`öìÙP¿~}iÞ¼yó˜:uêk×-³Ø°aC~üñG©îýóÏ?‹oJ(s={ö¤gÏž@~:¬€€€æØMLLHHH(ñø¹Õ’%KP(üðÃÌ™3f̘­­ík×ÏááêêúÞ*‰Ý»w°gÏ}únïA(¿._¾ÌªU«HHH`ôèÑ,_¾œ‰'"—ËÑÐÐ`úôé4oÞœ  ©©ÉŒ3èÕ«.\@.—“‘‘ÁÆ‹µÏü‘éÓ§S©R%úõ뇙™þþþX[[“™™‰³³3IIIlÛ¶… rûömär9ÏŸ?gíÚµ?~???i¸Ž©S§Š(Bñµk׎;wªL{uXJ€îÝ»Ja¿zõê·ÞgóæÍ9räˆÊ´)S¦°råJ•éÙè_ennŽ\.U`AAPA@AAD¡Ù¾}{¡ÑÔDáƒtòäI:wî\jÛS(¢Ë€‚ðqضmC† !  TL 6$22RD(³ž /^¼òueffŠ’Þ‰¸¸8xüøq¹8§fÍš‰d"[Œ‹‹ã?þò3¶ »pãÆ ._¾  ’÷­¼Ú³góæÍ_ü‡ëÕ«Çœ9s€ütX .¥-”¹nݺѭ[7 ?Öï¿ÿ^.Ï3**Ь¬,þþûoñ¥—€x(¡ììl”Je© 7)  ÚÍ›7E¡bZ²d‰€‚ |üBCC©^½:±±±*Ó_¼x!šÓˆ(å›»»;mÚ´áêÕ«*Ó£££Ùµk—( ADA@A„ž={FXX˜€‚ T<111…"P„rE©TrèÐ!Q¡ü=z4ëׯ/4=//¯ÜvPjÔ¨Á“'ODAüe– !99™Û·o‘‘!JZx'¢¢¢ˆ‹‹ò³ Â{ €III\¸p€¬¬,QÒÂ;ñàÁé­eEH‡%| ÐÜÜœI“&ùé°¾ÿþ{QÚB™ûòË/ùòË/ütX[¶l…ò?<}úcccRSS‹µž››k×®ý¨Ï]<„ îÂ… tìØ±Øë=þü£?wA¨°Dáµ”J%»wïæéÓ§" ‚P±,[¶Œž={–Û±„E„‘••…ŽŽŽ(ˆb¸wïþþþ" ÂÇnýúõŒ=º\œKHH­[·.µíåæærúôéBÓ“““¹w‚ |8éÙ³g©lëôéÓ|þùçøøø¼ñ:ééé\§A@MMÚµksÿþý7Z>!!“×Ú¢ìÛ·ãÇ‹(ÂVTW§aÆ¥2fHhh(IIIÄÇÇš7{öì"׉‰‰P„Ÿ®®.999dggš÷àÁƒ"×™:uª€‚PÅÄÄ’’B£FÊõyž:u >|¨2=::šªU«JI,^•˜˜Hrrò»€GŽ!!!áµ+zyyñLj«W(U>|øµó§NúQ âmbb‚R©|£Ä999äææ–‹æ6Çç믿.rÞ‹/X¼x1K—.-K¾øâ vîÜYhÀÀ@ÆŽ[fÇ«ùº‘¦M›ÆÞ½{166.4Ïž=óèÑ#BBB°¶¶–æ]¼x±Ð›žÌÌL®_¿Žºº¸é¬>ýôS6lX¬u¼½½±´´äòåËÔ«W¯ÐúãÆcÖ¬YÌ;oooizZZ—/_.´½ˆˆrss©Q£Æÿ]ðššÈår† ¦òÜ)++‹‘#GrðàA•åÓÒÒX¶l÷ïß§S§NhjþßO¦N:œ:uŠ€€•u^¾|ÉÊ•+¹ÿ>Mš4ACCCšW¿~}´´´T–ÏÍÍ¥k×®\¹r…üOOOi^rr2ƒ "::ºÐ:=zôàÊ•+*Ó Ö177gíÚµ*AUOOS§NqñâE•u233?~<ÙÙÙLœ8QeÔÕÕiÛ¶­Êyddd0vìXvîÜ©’IúÅ‹¬^½š¨¨(Zµj¥ò{·´´äìÙ³lß¾ýû÷«¬3qâD<==Y¾|¹Ê¹X[[óøñãBçø¿T©R…uëÖѺuk*W®üÚåÔ”J¥rõêÕܸq€¯¿þš~ýú1oÞ<† Býúõ ­´mÛ6LMMQ(´jÕŠ:HóvîÜÉ‹/T–ÏÎÎ.Ó(.|xÆŒSìL!¿þú+mÛ¶åĉôíÛKKK•ùƒfëÖ­8;;ãëë«òƒß½{w¡í…‡‡³fÍñeT`—/_¦mÛ¶ÿ~8bÄrrrÐÖÖ.´PBBÁÁÁôìÙSå_¢ 8°ÈéC† )ò=sæ &Lxã åòå˸¹¹½ñ:—.]"""‚‘#G¾ñ:çÏŸG¡PàââR¬gÑÑÑ8;;«Ê˜˜ˆ““Ó¯sèÐ!ÒÒÒèׯ߯³ÿ~”J%}úôyãuüýý‘ÉdoÕvLKK«Äï_ýERRŸþùÿü×¾¨ï6 €6mÚàààðÎx …???fΜù^~ø~~~èëëóŸÿüç½ìîܹŒ3†š5k¾ó}ûøøP«V-¾úê+ôôôþwX&“ªïÝ»—ÔÔTÜÝÝ ÇÎÎŽ—/_¢««Ë_|‡‡úúúo\Í©T©R¡iºººhkk9ïutuuÑÑÑ)ö:ÅÝL&{«ýw·ÙL&#//¯Øë(•Êb¯#“ÉŠµNIôèÑLLLøôÓOY¶lÁÁÁœ={ÈÏ?7xð`•Ç›œÃ»:þWéééûš+Mïú»+ê@}}ý÷²tuußhßE>¬Y³&Òç.]º——§òìcÕªU%>ÐjÕªaaaQ¬uŒŒŒÞÉÛ2SSS•s~Õ«W/öOÍš5100(Ö:fffÒsÕ²T»víR¹“{S 6T©²þøã*ómll°±±ù(ª^•+W¦Y³f¶êiee…®®îœšïsçæææ˜››kzõêQ¯^½2?6 ‹bç¦M›{?-Z´(ö:­Zµz'ßOûöíÅC¤·T£F ìíí+ìù¿îQ؇F¼’¡ÂRS*•Êò~’ÉÉɼ|ùò½<ýP$$$ T*_Û³Ê 33S9tèPåÓ§O•ãÇ—¦¯Y³Fyþüùú»Ÿ?¾222RùÝwß)Ÿ>ž3gÎ`ddDRRK—.¥[·n( æÏŸ••jjjôíÛ—ÀÀ@ôôô8xð óçÏ/Õc™?>ÿýïiÓ¦M¡y;vì`РAÔ©S‡­[·–«Áë÷ìÙË/ŠÕ“çC–““ÃÆ©^½:[¶láîÝ»888`ggGZZvvvúô郭­-­ZµböìÙ899‰††9r„ P¥JîÝ»G\\ééédgg‹··7¾¾¾\¼x‘ØØX¾ýöÛ2;×Ý»w£££S¬^K¯þ®g̘ÁèÑ£iРAÅ €+V¬@.—3iÒ$ ¿+Õ«o~G…\.ÇÓÓ“_ý•ÐÐPîܹÃ7ß|S¬îkÿËĉ¹|ù2ß}÷ßÞñÕÎÜ_|ñááárëÖ-:„¹¹9Æ +ñ¾gÍš…\.—ixx¸ÔxXKK‹¾}û2sæL~þùgbcc‘ËåÔ¬Y“~øá£þî§L™Âœ9s°±±á“O>ááÇ*wÔÏ•&NœøQžŸ††Ý»wÇÌÌLšÖ¾}{¦L™BZZaaa8p€úõë3hÐ nݺE³fÍèÕ«!!!Ò:< ==Ó§OóàÁd2îîî;vŒ)S¦ T*™;w.Ïž=Ã××—ääd?~Œ™™ÑÑÑÄÆÆR½zõ2;Ï›7o²uëV*W®ŒŸŸ>>>…~×3gÎD.—³`Á‚B¿ë¼¼<ÂÂÂHMM•~{õë×Ç××·È› ñ¸Œ?~???&NœH\\®®®¬\¹’ºuërøða)Ž5Š;wòìÙ3ÆŒCË–-Eá EÚ¼y3µjÕ¢k׮ܽ{—-[¶°hÑ"ž÷öݑݕ+%┈Fʪ—Ô:Ñš;4W>P~ùG•ÎDmbæ/TwèšîŽÐâúb£ÚXÁ•ÝAß•+%ÙJVß[Ïm¾ƒ~./Ž]Q;èçJs¥TÉî8^¹÷Ã÷^üÉŸûÏûÒ±‹9³÷ÿöý»Ã{‘r“ÓA~Ðýi޼ü„œõü“¸×½ÍÞFecw·åØ—eßu¸yº¹v|íè÷•¹<ñЉ“Né÷ߺÿº÷^·}þò³Ë½õÞìõ³~Éî¾çÆ+¡Ârh=ÿ²ƒæàä×NÎÝ4W$óXÚN÷Þ²÷ô7NoÎoj­w‡ý%¾8½ƒ›Í͵Қŗ cßôOÊ“îõ‰Nú®C¯­î­~ëÙÍgÝ륧—®y÷5»C¼= /Œì9þ•ãŸÿÍÏ¿ï×Þ÷Õÿ÷«J¨Ãß}Ø‹<¨NUãF|þWþê—ÿêÝÿ×»¿ö'_ãßÛþg>÷Ì?}gÚN/¸ò“Ÿ}Žùxs¾Y™¬JšóM‘ŠÑ}£ÍùæîÈŸ/¸ÔZzø‘‡Ü}„rzIßÝÁ™Y.–E*Ü¿ñ#ã»ã»-£Fg¯ŸMZÉäU“WßsõþÛö÷Ö{i'Ýw˾òxný‰[÷¼mÏù_Ùó¶=W}ÏUY7ë­õöݲ2j”9ÿ„¤•À‘ï>VÃÊdîøÉ;âFÜ[í•ÇÊ\mW@XÑÌ›£ûG »dW|ënÊf¬<¶;¬/—þZÿäÃ'­µ•޳+”Ó©«§>û«Ÿ=ûäYø³Ÿû³Ãw~׿}×öW¶O;øÎƒŸýÕφ•pýÄú×ÿüëÕ£þzÿï?ö÷ÿîoþÝ™ÇÏ,?»\›®¹ó %c‡ÆÎ>yöØ—•ÇÊ»#¾hÐl„ì ¢µÎ‰çN ýðµ0F|2òkÙׄ+_[¹ù»oÞ™yjñÖ÷.‡»¸ûkÈÙ'Î6ö5âz|ñ_yáŽ~ïÑÝ¡{md摬~û+ 3_[¼í»o[RK; 3ϯÜ<{ójyU¤â¡?zˆ­m¬-Î/*PÅ è,u–›;ètw¥›Oä˧vÕý5„z´»Üí.w/þ+•‰Êò³»ûÚR·õµck‰H^þQÞË»+ÝåõWPÝZ¾¼°¬„|¸óðbÑ€‘â5ÖìøÇâ(NÒdwÐwåJI…Æì Ÿ”ν¼ØÁð'ƒÄºi´yø‹³07솰bù‹ß÷##ݑݕ·Œ;vâ„]Y‰WD*ææwÓL»ò$»ê¾+»ê¾+»ò¨îÿþßÿÚûßÿ!÷ïÌ™³ð×}ïç?ÿ€ûtaañßü›_üä'ÿôâÿÞW¿úõŸø‰Ÿqü›¿ùÛs!E’üÖoý<óÌóÿé?ýáöû'Nœêv{¯~Í_ûµ^ðâ×ý·Îž]|݃òØcOº_øátyyeÇÎ?üÔ§þëÃcW™.£¼ü™ž/ŸùÌg¿ïû~8M³K½,{õµÖ¿õ[¿¾}˜eY¹\:p`Ÿ;ܳgö?ü‡_üìgÿ‡;l67Ÿxâ)8räÐÞ½s;^Pù¯þÕÿà¾{ûo|ã±n·777“$)t»ÝÛn»Å}túô™?øƒ?ºöÚ£×^{õö›;LY‚ý~Ÿ²= o»íí•JÅž Gž››=vìD³ÙJ’äú믙œœ˜Ÿ_8~ü$¼ím7"I’œÿâĉS§OŸ€[o}{µZùÑý_ž~ú9k­S˜N§wìØ øžï¹‹1öú­{–åÎεZm°²,ûÓ?ýËOþÄ'þÄcŒùÄ'>õ*×ü£?ú³÷¿ÿCÿð_€¯|åáçŸÑs⦅sŸc?þñá×­µÖZc¬»±W’C‡œ8qúÌ™³[sÌ>øàC/¾xÒ4ûó?ÿo[¿êOVW×î½÷ï××7´6ŸøÄŸ\äÐÿÎïüþ|ÙóÅ/>tìØIc¬µ`Üÿ`iiåoÿöóîõÇ?>„üOàgöVW×Ü¡1擟üS÷éöýîÊŽò¥/}Õ)ÞóÏë÷ñŸÙ~ˆœùÜs/þò/ÿ߯ôé¥Y÷0 ~ó7?²}Eá=÷¼ë±Çþñ•G67[/_ë/Ÿù™ÿmÛº¯­­=zä¶Ûn¹óÎÛ~û·ÿ3Üu×ÿý¿ÿûôÀ}×^{õwÞvôè‘W¹àí·¿ãsŸû¥ôž{î€={æn¼qÈITJÝÿý~ß->?ú£ï€?üÃ?þ…_øù‹úR)þ×ÿúÿ€v»Ûëõn¹åæýû÷¼ç=÷¸Okµê]wÝqÿý_t‡NÇ}ô…/<è¬ÑüȹCD¬ÕªîÌù/ÿù®N¿ŠÜ}÷Nñ>ð_‘RÞwßOëÌîòc?öÃnÌ?ð_yCê~IrõÕGΟ—$÷w¯Æê^ZZn6[ÛJ|8°Ï­tN)/w¿ûž_ýÕ_ÚòŽæ¥”Z›øò¥,¬é—¾ôÐÝw×ï?üð7=\¯×.þR×^{ôýïÿ?݃¹ùævÕú"å½ïý¾~ð_EyþÙ?{ßÅ\‡þü‡~þ¬:«A÷ç{wî{G…83GÞ>ÜÜl}ä#¿QE¿?¸æš£ ‹¿÷{ÿO»Ý5Æ>|pffú7~ãwï»ï ð÷îݙʧ”þô§ÿ¿ûïÿâ}÷=¦é?ý§?ô×}ï§?ý77ÞxýÔÔÄ¡C>úÑß =öä]w½nºéú?þãÿò Çß÷¾@ÄWº½{çn¼ñº±±Qx衇¿ð…Ÿ}ö…ÙÙé¹¹™4Mÿðÿø¾û8räо}{Ö×7~ögÿ÷N§ûƒ?øžRigrË=÷ÜýK¿ô«÷Ý÷üøÿȃ~ezzòãÿÔØØÈ÷ÿ?AÄ;ï¼ýƒüp­V½ùæΜYøýßÿd³ÙBă÷ONNüæoþÞ}÷=ð¾÷ýÀÞ½sÛ˜eùÑ£Gÿ÷?yß}üÌÏüäØØÈ®¿Š½=n7ß|C¯×ûøÇ?uß}=z¤Z­|æ3Ÿ=yòÔ—¾ôÐÛß~Óæf‹1ö—ùW÷Ý÷À‡?üAÏãç_gs³Õò-ÞÖR/<±pŽ"¶üÅÅ_ºûßîÆO/—|àW^÷ªµ+o¶<üð7–—W_ɺ;vâDiåxxrH{• ml4?ö±ß=ÿŸú©qÝuo¨Úãw÷Ï1×n¸áºŸüÉÿõ Æ4÷Þû÷ç¿ó±}˜Rúº/Øï÷?üáÿÎ;ßyÛ®V}+åoÿöó>ø•ó"Æè?þǾÒÉ×_í«‡vçË®uß•·²\`Ýw³ª»ò$/qfæçæçveWÞ2²¹Ù‚ëøêîq¾wïÜ«'tveWþç’={f_Aî`ÝñDx»²+ßž‚p¿ÞõÝwå;Õw?çØx±ÉÉ“óGŽÖZ^ÚdBE» ”]¹’b­NÓÖŪ{‹OE›l`‰ò4‹µ§µy™f_øEB!èyÑîˆïÊc4ÀE«û uò)ù Ô ú>Ä÷}êSÿ…sNÙØØ€™™™r9ŠãhffÏòò¢çyïyÏ=»Èý®üOæÌì(££#qíÝ»oiiqjj¯»îº,ëïß¿t´!D:33W«ÕvÇtW¾måÒBUß÷)%õz-˲mï¥Z­£+•Š1»Í;wå­bÝ`bb²ßï@¹\B@„žÇµVF-M/v7­õ3Ï}V*åqn­=Âö@ÇÛ·ÒhÔ]þµ^o|ýëÃ2MÎý·¿ýÆ‹ùe½^鍊nÚ•ý“köÈ4,6­2¥Ù¯ZJ–7e’—fFt!ûgÖ á,]m‰N2T;$ ½Ãc&œÆSÚ‘Ù Qf¡_Û?5qý!‰ÖñE;qáb.}ãÙ凟ÓBN³®µ–—B#h‹œ†£,òÃÑjºÞ):ƒd¥U´:F*kÁjs‘ºÎN}.ÓˆsûOPŸ³Èe¯‡#•òžqêñdµÕ=¹œ¬´ŒPF*£µ5 F£©F<5"û™–ŠÞ¾wß2sÛµÙfwá+ÿØ|f>YjÝÄun»?N <ÂY0RV¹(Z}-”ÊŠKÒx¤äÕï)A‚îkÁµ,%Œ"%F(@DJ¬ÖÛ¿0jk­±Fë78ý>ô¡}ä#y=êþ=“wÝ^½î›ß|âŽ;nWª€Gyldd$ËÎuj®×kB!Ä­·ÞîÞ ‚ðõ$Xt“tµåÕJ^9,:I²Ú½ ©šæq0Xl¥ £”³`¤bµýÌKå±”È~¦·ÔˆpjµÚ€k¬è&E«/³¢{j¥<9:yýá«î¾£^[]œ?ñµGÇo<4~áçOo¹ŽV'ÞvXeE±Y´z2< ç„èB:¿ÀZeÎw*Þtü¼–öÖØ7'h¸Üꮵ:}úäöáÆFóÀC—e7R盽p¤âü˼= ½ ©y)$œf›½d¥E}N(¡¡…´J[3 }¬6F( ‡–d’ËLXm¢ÉF8ZEBŠÎ ‡këÏŸnLL6jã M‘eE/ñÊ‘ ‘ Q:]iexìJµPZ(¯²À³Ææ›}k "ºhÒêⴌք RÆZ;ôS­±,äA£âU"ùºRåÖ0á<ÔBÚ´7õ°÷Ê £LýÀ 8óà“ÝÓ+ÑX-žÑB©$W™¸Àî8µ¶Z[‚îYe¬6ºPðÆdß¿ÑJ­wŒÖè•£d< x9ƒÜjã@t. ¥Ä*íZs R4Ê‚2 "ጆ> =$Ø_Øðk¥ÒTcüƃ{ï¸iâðþ8®n¬-m¬,&îèÕû6Ìét½]t’¢“ðRà•#ÑDÍ+…,ôY©x°8I–·ûrÐS…m/ž@jµ5Z^èX«…ýÔ(AÑ¡x9¢>c¾g”6BéB"„úÜ«DñTC$Ùü—½j/ƒÒôHa}åÔ <öeRXk‘{>"ì|cŒk$RB=¦Q#£HÐê]uÿÖk;Aû¬¡ŒÔHËB•ý,kö¬±<ôu!E?ÓYအWª”%h­ED Äá^Ȩ_¼Z QI&úIa]¥ùäÍG¦˜šÜ·º4æ™g“fÇ«D*Y³›¬´dµõ¥ÒôáLåe¥©kmçÄ’è&ÖX©çEÖ#”³î43¬±::„S$„…žƒJEÏ€°Ö8ô pJ%œº0Tô³ŸýrãªY¿Zªì›ÈšÝþÂa AJ@ê—øŠC€]-z©5vìîâîßz±Æª\€¯í~¶Ùc‰Ï›N8EJŒÔ*—`Œs~.Ä¿¶Wmk¿{•È)z)ƒÊÞ‰òžñh¼6~íA H»öÈ;޾©•4WNœ×ÏTöŒ‹Af‡a®M×:Ùz×jSš­ìpØ‹”øõ²èe*+£Ôcr; ôõûÁˆ„êqpHˆègr¹PÒ])±ÆcQËÁRsö®ö}ïÛTV¬?u²ùÔ)‹òžq$˜5»r½Òt£7J[!)gv É}3Œà…†a”‚h”þŽWwmÔ ,5 %,ôýj¬s!ú™Q:­j!E71ÚÎx9¢¾Ò…¸Ð¦Úá˜Zˆh¤”iŽÔ÷hè‹A6XÜ „èBnž]zþ‡²‘éé±{ƒr\žYÖFçŒq1¥Jrúáx-h”U&8!€ˆÀX9ÈŒÖàÜ ÑO­zCJƒÃZmòVßK=ÆBÏH­¥²B¹éí°ó ^n\³'žhxåùRRšKÖÚíÏêB‚Õ†pj9ß" CD$įÅÎÅãT§¾ïUã¢3 œ!%Îk¢>½Tçò êº3ºVj¡r$ˆÐÁÕ™>7' gHQ%yëÅ…µG3¯Gã5¹Xmúg7ìp^ê7YmõõáÌ¥®Þ gÆùK`-BÀÚaט­O-¥ÝÍZ èÖ.·Ž½ùqó•Ww¤„úÜ+G^5FJt.ŠNß…¤€(z‰Lr$h–‰Ð¹¢Z/'[pþñ˜_‹ýj,™è¦~£¤…ý¬·°þôg¾°zèøÄÑ“ûŒMÍpÎûËÍúþ¨‘º?¿F}ÖJ@ e´áÈ€xå¬,5E7Õ…´[p2n”~ã £~½DÕ…Ô…P¹Þ¦µH }B‰èg­UVøµÒØ K3#½3k*FjB‰s¬6[»ë"Š[ÈŒ±`UZh¡\*ú2xÜR÷-ûm´à‰íì“1Û`‘¯ì0Óß êNùá´hõU!\«°­DôvD…ºPVë­DôK(ÖZ#4 ŒP{•ˆx\&¹Î‹|•*ÉyPöWšY§ê¡Çæî¸þ®Ÿøç‡ö\W™xþÙGe^€J #”µ6Ûè„—Âp¬[•û§>&j)@Þìò( >“i¡ÒÂi”}##€ŒRŸ“Ž[, ÄHm”Æ• Ûì±È'Œ–¦Güz‰zœTŽcc-k´y©#Rt‰[^ ël¹üEÉÌ6­‡Ô$„p [ Z³íò ¢@°ß’”ê·…º©U. ‹GYà#e#u¶Ù“ýŒ…¾ÑR E=F¸g¤¶Æ€ w´V[ ÄZ«…LW[¼úµ’‘B¿ùP4Q'ŒQ5öÏÄ#õÆž™L¦O<þåN{£½ºÞ=»Zt-ä{CA0Rñk12Ÿ"Rei¡ É"µÔ*-t!­yCÊ J«´ýYèJœ™^Yä³À£/ÍŒ5ŽÎYcšÏŸé/¬Ë¤ ”hD}¾d©±vK¿-"¥­µF(£ôe÷˜·á2°–pj; ¡ÂPBn“Ø,¢u?Ã9<ß)¾;ºb^-FBœo ¥²Jϱÿ´K¸êBêhK¶Ú%,ôXäJy)P¹ÐiŒ”‘Ò¼=€h¬Ö=»Vt+MRkû¥ˆ\ R ]z*+t¡hà±0• ^ ÑŠKÓúÕXô³¼Õ/:™ÎÅÐôžg¤_·{`µF»ØNçBY–"^ Qz£sñd#oõÁö´Ò*-TšaŠVém’Ö1Â(RŠ %.»zYm¬v(0q©Sç\i!‡D¤”XòyÌysR~‹àšog†°Ðg‘/™J @P™°ÚFÁhMw†dH|ׯ‘¥â™‘É[ÎÜz RÚ[Xá3²À#»v?çPF§Þ~T ÒÞ™µ¼Ù&°,X)u!À‚ÊŠtµíÕb°6]ïˆ^J9‚Ž›ŽˆˆH} ά1FBÕâ²ñ @éê§g`x òR€”ˆ~R´û0„õÌ+9`‘ ú:Èî¯éÌ©þˆVicŒu¦ÜZ à"1—qVÌjãÖçôõ–"·µŒTyK SßxÒæ\¬x>t!µÔÕ°Ü ‘ uØ%Ûe’÷­%œ{ÕÈ«DÖ-$í4R¦UZ¤¹µvrϾ;~úÇÒAýØi-Õâ—þQô2£µè&.\FJD?S™°*Fjês#•êHI<Ù@JŒÒFi2ɇ¥€H‘zlÇ’¢×‡Û CêqÂ]ê-u÷b”†õŽ)”‘jȱ¯nzÌqW´—ײ#§Îâ!­/Nû$O(!œºøÄH¹.Û·>‰)9÷, Ѐ;óÖ"" =è‰h' IDATú[–y9ò«‘Ê„Ê ]H°Á­µyÚmˆÇ]¢4]kŸ}ð©¼ÕoÝÔÊ#×ìÕBQNמ=ù,¥³×_“õ§~ŒÜ«DáXMeB¥¹5Ž_‰ÖX¤à\)K8Õ…±ÚòrH8#œi©Œr•ÔÚ*mÑlùW—™rhµÑF­éßZK}îŠñ\Ò~˜Ü}MçQxà8g—­eÁ‚6Æ@ܲèÈN=fU…åŠÁCÆN·0îA´àöVQw FD@F]y%ñ õ9ñ˜5–^ïÌz÷ÔJ8Z-ÍŽ–gÆêû§©ï±0ho¬v—7²v, –šéZ;]ï8–•£3€6®)!”º>HQRçBt*[%Tˆ”8E¼„´%nýç<¨Wöø­6@(#‚z)š¬{•)Šn*“\eºìïv±ß?À¡ï4ðhÀPK—OÝã A£Œ5Ã1ÜÂ(©Ö !³ê\²ÂݵÑN˜7=·z圊ˆf¶ZHk â ?$ÄH-Ó¶ðl• 5Èw ŒPöA´ÚˆAÆ­õ8CJhÀÁ‚ègrÎx.}ýYUÈÑ£{£±Z²Þn½°¬¶’•¶Jr×ÃåRñ„3ˆ•Úz´PFi¤„¨TèB 2JABgà/nzMwÜ•­¹úZ'}<4JeŒT˜«_AD#µÑ q˜·‘ÊÊsZå< Ž×¼r˜·¯Ä¾¨´ ¼¤sDW:lÁUQJ(gÔçȨ•zHÁðRbe@8Z„9ÇÅ7Jƒ}s£Ø+çÌ ZkM.]àâ’DÖZ¤ˆ„ðRH5RÉA®sA=ÆË¡Ê¹°ÆBÁjkqÔjï©5U,ð© ˆnB}Œ”u!{gÖ|aµÉ[=ç tO®¸ÊTÂ)ó¹p$ªp¬ê•#£#k¬GÑJ·²ŸFK³S¼ª´ƒL e¤k€c­Ãû.âm'ü‘QBˆ%Äj½#'v«aGJƒ‘reßD4Zõ*Ršµz­çΈ~J(ÑZ[£­¶ÖZddèÍ[ åQ€Œ:M%.^¼ô4ð°6ÒMQçI:’‚Ö°ÅeBJX¸”*þxbEJ §ºÊ=tB€¸ÙB†Ë‚6Öš—d½œk­KBºü¹‹Ù©ÏýjD|rJÏÑž_Ò*-Ó\¥…Ë2"£Ž*ã giXà±Ð F*A£L<&z©‹8/`¨¾R{å°~hÖjÝ9½š®µ Ü®æ:­„cU§ÊÔc•}“º@HP+õæW­±4ðüj\šE‚y«—Q’oö¬62-¬º”’gk¿^¢>wÕÙFéb³/“ÜH…„X°V¤!ŒòJìþ. <£µ_-NE?åqàøÒàb¡OCÏ‹!Ôm¬c‰!‚–Šžß([c/µÕ l]ŠxLçB Sê1x`ìÉ ¥Èõ8ñ¨J ](ùˆ€”°È·ÚX­‰¦Ôý¤B¥œ…"”aàvL¿¼Üž+çÌ Âùz¬c¼RODuk­J ÑK«¦üzÉ*,·Â‘ЍL(AJòÍ^Öê›Bºb6‡ì*ciàmD?e¡€ùfO&9å4[ïxÕ8¯–¦Gjgxä7Ÿ_Ø|v¾hœmVia´ñÊa0ZŠÆkA£â2#µSõC³<gÉʦ.2š5»`m²²Ù?³îØÛFjâq• ‹—kü6îHy< üF9ž¬‡c5$˜®wòfê%zFi h¥ÑBRŸ#AÑxÕ«ÆñTC&yo~Íõ IWÛ„S•F*ºxåÀŠž!œZ‚V—&³Öb„ ¯9*\ŠGã* §,ð‡¥†9³M»k‰ÏÑŠ[½‘ù< ŠnÂKa8RÖR‹^êúpÊ) "£ˆ–Jg…ó!‘•*+./æÊ93]L³½¬ÎT¡Ñ¯•£Ë¢Ÿò(HWÛ<üFy솓7FB²v¯{f­;¿š®¶z§Wu.í°RŠv?ßìQ#^‰üZɯ•T.T’©z§W­Ò¼µ²Ê @ >µÙ3JÓ€£¿k¡zgÖÁšê)^ » «E'™|Û‘d½=XÞ4R±À+ºi¶±™·ÔcC8ˆ0†0¤@½ÜÙ**?×uƒ8=Î[}W¡Ò=¹’®¶Xè{•ˆ0*ÓÂ(íð;¯rÐ({•0ž¨'ëíÁR3š¨WöMðÈo_¶ÚPe óˆ\td†Ó ѯ—JÓ#ZH•Ž%I¶sÈ¸ÔÆa/.ÝZhû^%¢œYc‘¢W‰ýZÌã@&¹«¬EÄÒôH8V%ãa úIçär²ÜЦÔçéZ[rk¬.¤.õñø›ÑäŠ93t#BJx9,MPŸ÷Ïn4ŽÎßxP ÒÞÂzºÞ G«Ó·]SÛ7%óbí‰c*+⩯´¯å3ÙϬµ*)ìÖD¯²8½4­‚µFªÒì( ¼t­¬µ³f/h”«§ê‡fYè V6í±­ççqz`¬èe~-Ž&êºY³O6–yÎ#“¼wjÕ#98Â2 ƪL€³cw1Â(ñ˜5FÊqLT’ëLÐö€xLô3Vi¯¥!™K¾Xc]ãHkmÑMê‡fǯ;@(Õ…Œ'j#Wï­˜^xà‰¬Ù#ˆZ(ÑÏ(§È¨Ñ)¥%æ7Ê¥™¯uO¯¦+­mnðÅçI\÷LGÔ£¾çz¹QNýzÌËõ˜Ê„5&¨”]fÀ¯—Ëõ2õ¹ãxS –š¢—ÖŽÌÎüjì¸!`livL²t­mU@ƒapeôå¯oºrœ{;Ï¥Œ8ó*QýÈl8V ªqyfLôR-õصÆ®Ý?võ~-Äé/=¶þäIGf¡o„ríTÕ$”ðRMÔ¢‰:õ½l£#ÓÂHŽUKsc”Ñb³'ûi0Y®˜¿á`uÏdÞd÷“ùœPê 8¿Q*ÏÇS ¿¥kû§yð8pÞj0Z‘ƒ ))ï œŠn¢r©³Bô3]ˆa˧ Ÿ"¢«·:o¬Õ5 *|¿OÝvÔHÝ9¹”S¯†££‘:ž¨'«-•ËÑ£ûöÞ~ƒ*äÒCÏä]£5a„0fͰUݰ;šÔrFýJd¥N–7íÅ«;"ñø°ÿ£µ,ôüjìâ]HûZmÜÊI}^;4ÅKQ¶ÙôÒp´ÂCŸúœÞØ TV¨\8Ô’0â•BG´†D¹70R ‰iáò}—Qé¯<#Ò54ENyä#£A£Õ¬µýå& ¼#?tçäÕ‡ŒÖ+ÏÏ;ý V¿ñ`P+i­«­¼=ýLt@FŒÖE'áqb‡žÕ&oö"aÔE¡¡O5‘ªWŠ èŠN"“!'Œ”fFF¯ÙÕe’uÏ®ÕöMM^wØ(UžÓEá²÷:—,xä‹^j ¥2á-ÔùOwtß]W DdqÀ"/¯UöM–çÆÂ‘* <™æFi+“Ü9qàU"ù^µDCO ¹ô•§ÒÕý“áX)•¹°Özå(¨—\è(FH´à¼jPi‘·úA£ŒUiÀ‰Ï )ÆIi D …­ÒF¯ùõ’ÊU•fFýz‰‡¾ó¼yè²LrD´Æ –Dúµrm¤â|÷‚x¢N¯}|1]k‹n¢¥RIẌ¸®O—·Qñ•fD:,Ì‚U†xŒPÒ[X÷«%úƒ•ÍÞ™µñ…•2Py1vhïUï¼Í÷ÃnwsáÉg—΋°¶Oˆd4ð¬ÖZ¨d¥EšÔ¯Æ^­ŽWyäóRèJij‡¦!©ùÁïjÌM­Ÿ˜GBfﺡ5¹ØyñlÞIt!‹n²úØ1êq•æå¹q¿‰43R…µòÚÓ«*,ô‹Nb”,ntŽ-m›s&j*\‘ØAú%ÕÖ„Sú M7ºEgÐ|ú´è¥^5vcÑê«\F0­ÖÍxåÈ(M8ïŸ]ÏZ½p´ÊÞ=³¢²¼¿¸^t:`­VÚ\— „`¤âWc D%¹ÕFôRÊ©ë}‘º„tˆå;ÜP:‰Ê¢‰z8V„d©I8+ÏÝD&X W?8ŽÕTVˆAš·Ys™PÂ"?ï £b‰µ¶‘*h”Yè‰^J(uÕ Žcsy\auVòã0ëä×J^9LÖZa£R™G*ÝS+/¬nνóúëÞý®úØx¯¹yìñ¯ÓÈ+OŒìù®›Öž;™·úFj•*+D/å¡M7\³Ü|³g”vQ d]¤$©PÎQ Qô£õìm×–¦FŠN¿è&ÖX• •‰¢=ˆ§A£Ü[j.=ò|4Z jåÞâFÿìºd,·’Õ¶Q]J|ØÒÈç*y¨jE<¯$ÙŠ~*ziºÖöJ!_ÜpÏZ}ú,ôE?íίx_Û;5ztß`½µüð³ý…uÙÏÀB²Ò,5£U90i”îœ^A‚ÑX}°Üý ,¸šË¢3è/¬ë\žãf‚F¿†=rá£ëtžK• 9ÈòÍXÈ[}tòrh¤Äõh —ƒ\tS-”W ³VõñKÓ£{Þy}yj4™ï-mh!e’çíÎ%¡Ä­Ý5Ž£áÚž¥u.cÞéÜEš¥ó[ƒ£èBŠ<ƒ”…¾_/GãU—ßÕ¹P™@Äp¼æW"¤ÔR*Ó\çB&T¹ƒÌ«Ä΢¥ˆé|BG:z |÷ÖPwÇúwùÿ¢›$Ë›ÑDÍ«Dà—C‡£SB¦—ƒl˜׆xu?dd«)È[Œ"¶iã¶r°s[%«mêq#•óö¿ûG¾û¶êÈØÙSÇ6×–WŸ?¡•ªžÍ:½ö©¥§NuO,»ì£3T:—Y³+ú)/…£sswßXšõJ¡Wgï¼þÌ?<¦²Â«–êGæÂFeâúƒY»·üðsÙz‡E¾W‰¼j4*åÙ1¿É$OÖÛ”ÑéÛ®1ZwN,©µPy{oöt.¼jìWcÑO¯b„|*¡—v>CJ§<¼JÌbŸrf´D*”Ó†aOjëj,ëWc¿VÒ…ô«qÔ¨­»kÍþr3¨•˜Ï­…¢=(Ú}ÑK g„¡QÚ‘,d’³((ÍŽ6ŽÎ‰^Ú=¹Ü?»q‘¦ÝZ ÚŠ¶ºeX0R •¹ƒË E•Èû´PH8c±ï´ÖÕ¥E/SY® `f*º‰#® ñhBjüV#á-ÇDtT¿^²Ú¸y{Ð>¾ä•#/ ±}ìl<Þ¸ê{ïû?Äñ©gžê]cQ4ʺ*+\Dû) kH°{j…ú\KE(‰Fj#‡fãñzºÑÞxnfn½æÐ·Xmx®>qlã©S½ùU¯©U’ûµ’dº7 êåÁZ+šjäÍ^‚ÔK~5‚<òä 'ŒÊ4·ºxUºëw.¹6ÜF QYá0¾¢“h©uÖ#ÓÜuÃ#'”ʬ,oµòèU{c^”*µR¹V›šPJl¼8¿\}±õüW@¤21Ô3FA#­”gGYà¹×¶Ëk.ÒwW¹8Ÿ÷ë²NŽˆJaQàv;s$(:éL A¯»¢âqê1¯ÙØ­P„QHIѸ}šŒVn¡†7§Añµîn÷C—_TFôR‡@ÑmF%Œ®?~Âjsð=·ßþÓ?†{«íÅH°~h¶wv£'µëµâ˜,ð‚±Z<=B/ßì·-Æu¯ƒÔjã—"¤¤¾wºè§JÈöÊªë ÆãÀÕ\«LäÍ^ºÖÑ…`׸f¯Ñ¦ùÜ<²’zL"“”ú¼h'ézÇ5sµKŽ£²sq´6ú%Yqk•–B‘uB†…®×Wf\ë9ç)¹7«M¼íÈèá=Fk-%÷ýêȨçi>xñ¡G6-ôÖD7u5_ÃÆIˆ.ÍÝÖW ëÖØh¢†”Ȥ½ì ˆìKV)«´E@JÑZPiaq¹6Dôj%Ã(E(©_+mTVèLÎ\÷(ËèpNúœº-X\}·F°hÍåßÕæJª»«H‚­­³´éF‡‡þ°pèÎêWÍî¹ûæÙ†qÜÙlž|äñ•G_Èš]êq™äí“åM·áõ¨ãÑ[cŠÖ)ÏÕÏÊÆs§ÃzeæmW¯5½ofd½‹yèI$„|»ß¢CQ¬ê e_ÕNW÷Mñ(è/¬§í¥·¶憷æ’kÙÇbŸÅ_‹]ô²¢Õ·ÆÐÀ#Œ¡Ô âqù.1çv¤rŒ&•.´uïSŸë\è·ŽuwžëöÞgµJ‹^ê–Z çŸh!—Ÿ9þô§¿ K3£µýÓ^)ì]ï/nˆ~Š”PJÊ™ÃìÀB}.9áÔ!bA­\Ÿžœ;rÕê™ùÎÊz{~9®×Æ¯š ½¸:66vãA°v°Üò*aiz4«F£5-d¶ÙCÄú¡i‡%#%º¢“ˆn¢sÁ+Q0VÝdHäÒÚkÑ:'íåk±«r82·¹1 =¯FE7qI1^ ŒÔ*uÅæ„—B$¤sj%o÷Wï­ÎV6'¯;T£FÚp¤Â#¿—ä*-gFH$Èã@K¥¥.º <¿Såí~ÑMÜîm¯Ça@F)§ˆh´±ÆPSƒ±¢ŸéBº¶Ú~£l¤’I–o ™ã¸¥¬2nWW÷È¢€úŒÞ0¶v¸'¾)Zw%)bÖX$dXäáÚh.¡sA¯ùô颗Ž^³·¾º4=Z™Ù?»úÌñÁʦŠpÆK(û™Ê„ŠúÜ«FÁHÅ+G„Ó|³¿öøñéÛ¯™¸áPÑOÖ_<Üt à‘ÁrÓ(ýhõÞúÞim"–fÇe’‹Až6»ýИΠäläè—š½z_²Ñ.ÚƒòÞñ’6„³p¼&“,YnÝÄ1ïÝ.¾C€ÙîT+t^c=g#å Ó¹pe+¢—¹„‹Û JÒ*£]R¬QG+y{°úÍ6Ÿ/åƘҪ'Ûƒ¤ï•Bâs«ód†àã°œ˜Ï½jŽÕT.KZjÂ(¡äâ÷yÜÞÇÓk iÎk² r¼zå«(ú™£3ÕHˆ.$"µºH ‹ÇÊtþ´H aÌh­ iß„¦­WRÝ­± «b+­\ÏXJhàQŸk!ÁZ#diftêmG³NïØßµsr¹¿¸!û©.¤R%¹«0ZC £^9¢—I>¤Ýr¦òbãéS§?ÿÍGÃÏÊ~Ê¢ )ÀÒÃÏ®<ú¡÷ÝTKéFG òtµ¥Òœ0¦¥â‘TŒRÝ3k¥©¯ý$¯¹8‹|ç5‰n’­w\ZÑ5ç‡aû»—5²<¿•ŠÝÚ躹ŽUµTjh¡©W ‡=,¨4Ï[(¹‘ʆ¦­Þé'žê-¬i­ÁÃ¥GžË6ºêýÌ%†\ <‡Òºj§‰Ç‹nrIÑêùl­áNX[ÄVêQú4páµp‹’ÑÆHe ëh˜^5FFu.YÈj£³ÂeX‘ôˆË+9Ô•…¾´ß„ŠÕ+VÞá&½µ ±F[¤wñ™‹f0ú¼ÝdéÑç«›í“KÎ_×™p+é9`Aå2Ûè{K¸vKË[½þÙõÞÂzP+]w òÿs÷¦Ï’^÷}ßÙŸ½÷îÛw›¹wöƒ…ÁE%[´åÈŽT©bËN¥’J*•TåM^¤òo¤òØŽË©$ªŠ,[‰EKE0Àì3wß{ïgΚ§ï€@r,K¡ˆy ÷vŸ>Ï9ßß÷ûùvÛ͵Ð<žOwŽmÔztwg¶uL\Ö¸²B#ßï5k«zŠËb2oõZ~»–Ob·).óÓi5M‹a\ gå$±!|c43ŠVBZX»,Å'<ýZÄñÇrÌw°ÇˆÃ ‚6¤¢9¶(‘Y!-Uz8‚7®®Ö.,åg“äh´÷æV±©gU,:Nˆçˆ¼²ýÈb€ÄHq¡¹ÄŒÐ²tÁg1Ï;Xý8RœßÊØ¹[5N¤KöñbãíÏXõšK#ÀÐHÍEa{É-éR ¥•2JCëå6F‰ÏiU¹gø\ˆ cZ`¢XKm„¬ær|oo¾u²¸ÖÈ…”a(1Fu>Áç½ʼ".cõ@ ™N­ëËkGë_yåöõõ76û×O&?þÃoY¨Æð£-YrHP9˜9 =§æû½F•äó½ÓÆFùå«UZh¥iàñ$·H³j–cê—úZi‘–2+D^i0#,ô ]D9?ÞHñ h?„£EŽÔRW‹É¢Ò6â©…´ˆ«õËË­kë+¯ß¬¯÷ç‡góƒ³jžÊ¢"¾SNâ°î+—ãÝÓÑÝ]ž‹ÇÐÐk.ú-·Ù  |0ƒXÿÜ_ìÀ`•´0 -$¢ø|“‚‹ã ì6Ï"l ÉÙ\­í;€Deÿ ¢Dj­??‡´Ô£y€¥aK‰€UÉ!„^+¢‘WŽâj–Yô€òÙ6i€ÚB,bØF™,ŽÝi†ÑzÏo×Öµ•ÞÊÅËíÚ’’’¶þê­Ý·ïìýà }Ëbi!ÒBäUgå4áiQ»°Ôùš×¬+©6¿òêìø,kOº/] W»·UËG³ñÝÝj’(.Ôú¢‚ü)Zžùø~i‡ˆ#H0qcT•\q¡*À.%#,òý~Ë©F)ÌÈËÿà›Žã=úî÷ÞüÀëÖk–&fÛ'Å`fã ÷¬ÔØ¥N-×:µ%â²ìtZŒfÅ(ÎN¦ÿ! 1À⻪$)-(ùŸ£ v©‘ÊMTÅ1db­”}8 ‡.ϯ§5» "¤¹ ü¼˜ ‚ˆhO­ípÎ& Yݧ¾kw;-d¸ÚW;O%õÂk IDAT ^Žc«ò~ücŒ1Z»ÚŒY€³)¡Ã9 ¹¹õ;#?ЦãÁAù4 êË«›Ño¶ú·®¥?¸¿•ª’v/ Γ¢}}½sã"ÄhºwÜ\[v‚Ó¼¸ì·ƒ»[ˆb¯YKGŠK‹|2Zc‡Z¾³-}ÆmoÑ“ Ö,‰]æ4Câ2yˆ’jž•£Ø>:,mJfU9ŠÇww³ÓÉðÎÓh­Û}áÒêæ•v­×\ZZ~åÚôðdôxÿô‡ñÎ鵩õ⺌ 1Fäev2)DZÓE^æ§Së†ýG9B‚À9øb!$žÃê¾¥òyf­ËB©´1Š3Ä.µ_£ ¦3GIe) ZH]q€­ÿ)3Ú(.¬ÔjÙ™Bˆ1ʸ<™W… €°Šóró8§¾£+O ©Åg0-„šø.«-zßUQã¸qaùê—¾¸Ò¹(T‘æó³ÝãûiÍ¿ñ+_zMƒÀÑ[÷’£!€0\é\ùÍ/¯¼p 2ÜÙ_¾~¥³¶vøèQØi‰°šÞ—EU%'o?œ>Ø/ljUNY°šoÙÓB-ÔOýÀD”ZÞ“,ý ;™T³ »,ºÐYi+Á4ô‚Õ6 \Y žäJȧwÞ{UGï?(“¬˜ÎGí¤‡#k»·i:€€­ë0Rñy ×»A„‹<!ÿ÷ò»Ÿ+3CLÉùÁÝ¢‰ÅBp¨Ñ€Ç¹‘Š¢;3ZM“ršZ´ ½Œª’CŒì,V+­ÒlÐR!JG¬n¡¥2Ùn‚_‰à¼ìÁ¨E˜MVBñ˜Eži…˜Q§æ„ÒÃa1œk¡¼N½v±g4ÈÓÙ“ãjžêJ|fzQB×íÔünÃSN’³ž„ý¶Vj’ç£áþ>BøÂ«/¦Åüƒo}ûôî“Éãýôh\Í3- ý*ÎNî>.â´µ±Úì÷yUDÍfs©?8:p¡×®—“Ð}íJv4¶NF; 6Ú­6Ÿ63ÀY\à =„±ÈŠthEÕìtRŽb¸4ò €Äc4p±Ç¼N½ûҥ„±øp ‹òè£GU’ŸÝy2¹¿ç´Âp½KÇÆó²ãÉâz£µâ3JC—xŽQF YÛè³È÷NÅ{%ŸeÏÿ(f‘G#ߢaUÉ­ÁQÇF1Œ1Õ4µ‡(·ÑÀ+§ 0€FžÖZ–|A°…ŠÖ7¯*9v(rÙ¢8ÖaZâ§ÔJÿeG;~¡g÷óvY`9xöD‚êuën»!”¥y pÛQ}£_ß\ÎGóÙÓãìtº(ïý,·­]I"+Óƒ‘ª}óB÷ÅM§øíÚxïÐADSÜh÷jÀð÷¾÷à÷ÿ4Zëýv1Š­m=;?ø¿þD–|ã7¾¸ùÆ+ÆhÁùË7¾2.FÉpÌÓй~ñÕü[,ôö|÷ìÎY ™WÉþ =ɬüt•Übˆ­YÒžÓDR90Zï"BˆÇº/m£8=£2´Û#ë®æ©Ñ¦{}£¾¾4? ‚EQzÚ¥¿ûåÎÕ Ôs·þøGÉñ¨œfˆ`â0ŒÑžÿY)²2Zï:П'ïç=Ì@cv¨QÊÌbdÆãÜž¼‰ÇhD#Ð6€{Ô‘VÊZ‡íÉÊx”ªÖf!Öá T\B°C±ã‰$—ÙL¥_èînïRÊ{¯’ÌBÏíÔk{ÄsªYÊÓRvñ]‘ÅpfÏ v ñq¸Ü3þ›1@ ©¹„‘Ï%ü|4OOƳþY<›8¡ßZY1À t=ϳtûŠÛ® >Ú’¯_êÓÈ×\Dë½þ+×ڗת<m^y!“éþÖCˆ`ûòšS ZW7_z)™L†[{c]àz Z;´ÒõKËë¿úrsc\Ì’éÎ1 ]¿Ÿñ´àq.ÓÒ(E†-Æó“µÖ„ÒÎÅõÞ¥ ¡xïÚf{y»ìÞï~;Ù;³k 1²÷`Å% Ýh½Çj^9I †vôñ*æŸ}RGŒ ‚ ‚bH‚bÌâEì)\ó…êÊ ÖZÛ³;ÐFUa¤´^Æ?†ð×J#Ô²˜D0¤XKe*ñWÔ%ÿ‹;»/²-?ÑÎ1<-ò³©Shè"J‚^C$¹Ì«ñ½]çØe~·F1šK ´alãâ"ÀeÀ_z×ñ/Tˆ$ÈÖ›,(1»­ˆ¸¬ÇÆè ß¶3ž,ô ]¯Usaçóíc£´–ZäåÌù¬ #â;Zérœ°Ð³†$D±u¬-_’P½û'‹ª½¹vôèñðñ^<­}áVóÒêðîÎìÉq5Ï„³§G‡o~Ô¼¶öÒúnœ  †Í¥ÞñÃ'óý“b’<ü¿¿;{|hÝ ÑzW•ÈJ¬“ù3šVÏ;àí7(¾ø>$ÃxïŒú«Fª|0C”ð8G³ÈW;Fi™—Å8—[W®t®]·ö€Ð³Ýãx<NvŽ·ÿðíìh¤¸ÔRâ [¦f„¸ŽÖ:?`‡ZíæRÚÒÖçXKˆ Hlf¯‚"ŒE)RqFÌðbT"dqVœZ ¥¤‹gS-¤æÂh =»Q,ÒÂR¨@ûG …[Äñ\üy @€2RÛ¦=¾±zкu±¾Ùw›‘H‹³žŠ¬¢‹]ª >}|1âó,=Y´Ð¢þà\ä¶OOYpVó5ãû,p‘Ce^¥G£Ýï¿4˜æzý ^£öäíwß¹·úÆ-¯•I,5Ó£Qz4n^[U#‚z·6Ãns2>Mæ³þúųý½ñΡÀÆ/ÿÖWü^cº}4ø`Kde9N’ÝÁ üçÍ2#Fˆfü=Y…".ËS ßmß•E…)u£`´µ?Ù9i]yåzmm©ÍG[ çò¼¾ÊFÝ‚Äw½VÍëÔšW× €ÌwÕŽS÷³£çÝ›¨ç°Fh¤*§‰æ»Q!Ô\Ê¢²í)²àÄa4ò0£Y -"Ķáj© 1\HD°–Ê¢Ô‚ u.PTšËŸÔ `ÌçšgOoFc´uœU“dðÞ“r7¯®ågS] -•Û í.Èãœ.sžÀ,zÎÏEç.\û”ÜÚÓ—ŠK"«†n¿—ä½6ßøGÿ ×_OÎ~·¡¸¼ó/ÿPI9ß= WÚ4ðhè¦É¸óÂU¸[ß{7L™ïV_Évð¾×©³À—%¯_ì¯|é–,«ùÁ™m´?­ ÆH¥¬}DGF*‘•#¯U[~é*¦tôd/;›z:vÈ|ïløþV9ŽÃõŽ‘zôÑvhïÕ+ˆ`­t1‰W^¹Á¸åÚʃ…ƒÀ˜ÿÐJÚ¿¶ËÚƒÆFkÛãe %Yä!Š!€"+“£áÉÛ!‚˜¯]s[‘–*;'Ãìtb„µP"ˆ ÄèOØ£¥Ò\zíZýÒr´ÞµaM‘W¢¨z×6/_{qÉt$e–MvW––OùÙî[Ì·OªYÆç¹1€¸4>̶ŽzH·˜Æ³ƒÓÕ—®KÁÇÛ‡‚ìt2¾·—N€Ep Ð\Ú¢•ÏZä‹ÞôóXA1£n+Ä. ú­õ¯¿L7=Ož"Œ!Fñþ`òè ;«Šc—±š?y|héÛ¡2ΆwòI}ôáÃÉÛÆC¥È• Nålß=E¯|í‘•ñÎi9ŽU)dÅUyÎ3úÌq/Æ l´ÔBâ3·]wZ‘×mÔ.ôšW×¼F¤„ W:õ‹ýähxòÎÃÓ·¥ièÑÀE¥¾C=‡x¬˜ÄÉp1JÓä`€âvêá…ž**Å¥,x>˜)©òYÌüeÉEZj.ªyf¿9‹Ãçó@*¡TÉ?CÊ­må‚èmM«ZkÌa,¥iaOè  šÅרœ¸Ö毀pý×äªjlb—F«™U¶ 8Ì’ýÐmG˜QYðìdbåìÐÚf_–¼8›ñ´°oc€árQŽÇÂØi†àùö©–º÷ê•öõ‹²¬.|é¥Õ×Ξìœlmaàä“ùi°ë¸ÞpttñÛk¯ÝÚÿчª’~·Y[_j_\3ZŸ>Ø".k__ÇŒÞýýoÏ÷O-ÔœE~ïk—Bƒ÷Ÿ¨J<›žœ{?]C¶èÎ%øY*@€1äó,Ù=}¸í4CDH5Mjýæõ5 œñºu‘–öZn]ÍËoÜ\û­2NµÒƘµ¯¼äýfˆ=ýèÉÉNŸÊ¢Ò\.:s PBÆ['E=ŽÖ:n+ ¯®–“d¾}¼=ïEËh%αG1!ÒjQþlƒÆ›.'ƒ‡j¥E²˜XÃëâÔngÌÐbWàyÓ0@”@ÖŸbÿ.‘ç D0ñËŸxFÐo²ÈY™Êq‚)éº5»[Ó"qÐfñ$…ÐeÎÓ€¶\ɲ„.ý‹ëW®M·ŽƒfS ÕX_¦¡{|÷qÐm®½xS ¾»õ`uiÃóÇóÝÓѽ¿ßj\^Mއéñx¾Z»Øg7yzX[í^þæ㧇Ø9s!vèøþÞðý-ÛMùñ•ñX%±C£²À¦v{JËR—FKB™W€ÖóáL«ˆV—F̈ѺÍç»§ë¯Ýêl®ÏŽÏx^xõçe±w–ó³©Õ³­@HC/\i±ZàÂ:¶òÚ ­Ô>Åå45Ï×Þaχ#äП˜®Í3ÐX¨d­µPœgAå9B£bÄ^lˆÖÖoÿ& ÷a!‚ÕÞ•1vF®>_Í{ EÅV*s‰]JG e”R•гs¯Wo\^a‘_ÍÓùÖIz4²`‰…†e€Ú¨¬ÅÛ¡f%‚ ½Õ¯¾Ø\_Þ¼ô«W¾ê(ƒäÏÞýÖÃ?~“NÐiHÁ1ÆýÎگ˯fP¢-YqùZ( u6žó¬¼úͯô_¸2ÜÝ/fɵ¿ùU)*cL´Ü–\|ÿÎÑîU³¬Í'ר&Qô§\AL‰"" ²MÈõKËk_¿ÝÜ\Q•8|ëîè£2-ólšŸMU)´Rö$ƒ®uÛ7/öt·¹±Ì¢ ³±®ÞýÁÇï<i‘g!©)K^MS™—|žñÐ%ž# ^ÅY´Þ {­l<³®ú¯ ”.q™Ì+Å…R«Å$B0\Ð(ÁE”ØÆ%ÛöjÅ·ªà²¬¬ƒ(ÁŒÛph3µRYWdÕI+^}NªÈš®Tªä A¸¤æÚ©£’RqI¯ ¸Ø!"+¶½V­ÿÅå,-†sY>Gó„˜ÙuŒZ´ºþä_’…ØNQd^XÙ*Yrû“@d•ÈhÐ@Úh¢íH[Pí~áÇÕÛÏ‹EÌ,r<)ì!²$Ø+ì#P.ÔájÇmEÓ'‡“ûû£p­³òµ€ÉÑ(=ñYÊÓÂ" íZ?Ç jl.Gk½ähpôàqïÅKãÞY)§/¾òæ¹Ã£Ãÿöϙɻknn§{ïÿÁ·ÎÞZ»¸TÎ3àµ_ÿrk©Ÿ&³ýû÷æÇƒ°×zðo¿WÎ’Ë¿ñ¦"LÝVT¿ÔOö2¯ÀdzKÚôçÈJ‹ ©¸ÐRZ›Ñœî·þõÞü(è·²Ó)<!&è·#Õ4oX«Oòƒï}è¶¢¥W®j.vþä]£5‹üôdB¬´òF˜ÊQ¬JNa„—E¾Å«ó8O‡ü… ¿Ó0J©RùœvH£…Y‰°oYÕæcõÖV«±©4«½X¦1²›ô"ôe%ŒRÆ´øz|,’oÌ3`¥QtΈü|Å;ì~  ˜•&Úýo¾}2¾·[Žc¡¿Ôð:u§–Ӥ͋á ðéNqÑBìÃÁrë⯽võo Œ”'žN¶–76û¸G®|á!Æ?œýÿ·–œ¥7Ûwöl!‚…à,òxV°Ìã¿÷/þà=x^`F›—WãÃÁéû£õÞé‡OdÅËiìµ¢r–ηN²ãÉ'Ê-I!HÀ³õdŒQ•0ÚȬTB¥ì¦(²‚¸;Ä(# ÞyqÃï6DQïïñ$W³4ÌŒÖÄ¥<)Tyæ4gÓLJÄcÆ‘Z(·ýU„ñÂq¥4v¨=ÑÙ^rì1û†‹´HO&"+OüxøÁ–-x>ƒ“2Yi'ƒŸb®Û¹8„RbÍ ŠK!0DK%+*±8ëC!°Žß_þœÆÿWØÿ‹›ª~²†ÄÎ¥E¼Ø°AØx? Y5¼³¥¹2R•?l›ß±ÿ-øŽ·Ôl^Y©_Z.fñÝým@mm©J³ÙÎÉý?ú~¯µRouê½îáö“ïÕók—_¾@._è\ú`û-h ×©W³,;›f§“|0eµ um†ÞøñþôÑ1æìÝGû³÷ì½M+½èJ°±ùsÍQL=gÁ"•?Ùíï%+¡¹D„hà²zÀ"» Q ¤‘O ®vâ½³üd*ÒÒ¶œF,7iè#ŠµÎ ²à"¯¬cBä•,ªìpd)“@›ó  ÀŒ"‡—eÅ}·­uâÝÓj–>g9µ…åSßye‹T­_ã'Â9DÀÅ…UÜUÅ1£ (FYòVü‰§þ^u¿èöŽm?­ýø±C½^;tú`ß6ÐÒÀm\YŠÖ»<-’ƒa1œ‹¤iÁ“|1Xµ2¥1Á"¯NÞ~ˆ­u‡öDZò8ìPf”FžßoRÏ)g)Кú.«˜ÑO‰¶ãcáÔØ^U[ nYZì>[Þ%€B¸8jšóùß[¹pò™ŸQ»d0c>ŸËBˆ]ŠJ#?è7à =¿]ÌwNˆç8Ͱqyuõ+·¢•n1OfÛ'Š âÒ|8×B‚ZʃˆÈN§ØeõKËj^ÍRYòúfù 7¢NûÂÅk77^Ùºö2çrûzhü!‰¤htº~·É³"=ÉŠ_xã6Âx¼sèwêWþÆ—ÜZðÑïþQ´Úõ{Íøà,\n]üÆ««¯Ý*Óìè½Çoߟ=>,')—Jæ•5ÊZaíÇ÷sÇ(mT%çIá¶£Z»o”ÎO§2+—öü!ÔB‘m\Ã’ueÁeÉF,·1ÔwÜv­@0=CŒ­£ËbŒT–Π¥B{½Ft¡­uUųã±Ì«žî9>£´m4‹™ÿ±híÁF™…_w‘±G厅XCŒùL¼ÈŒÛ >{™>×2­ÉþDµ[ü_à窬æÙ;Œ†®½Î˼2-cÛ–›××ú_¸ö[ˆÒøppòîÃч;"-X=€#—²ÐE—¹šßkX;dr0,'±ßk,éÆêë/8Qp²µ}qýÚEp…vè‡GïîƒíÍú•îõjÉ…¿Ú?}¼ýøÿ}3=6.¯½ÿ`úäúîËÿÉßZ¹võxokó_\¾qe|ttÌÊo.¿xM yzçñàÎÓìx\ÍR-%v¨ª„æÂhølA<Ó¬WÂFŒÔ"¯%ájgýë·ƒN£œ§ƒ»Û³§Çå8¶ívq‹¬ÐJC…Ñp‚ˆçØ”'b¤v¡gÝ;Õô"Ívïä`§Ã:AÑ6-’ãQ1Š¥éÑ(9^ùõ×_ýµßèõV'ÙHTüWþ£¿_Ê¢ªŠ•×nTiñèßÜÿ“÷gÛǶÓëY # Ï@¢Bû_Œ 0†®Ó å4¡¾k¯žÅp&² ÛЧË,èAdyÈFkžÑZ'\ï­ç;'FQT2-œz`Û í6€µŽDˆ*ù~6ž‡+g ºçÙ:m®’ú@ÚÚW~¦€ ‚Ql žÃÁbØ× ÝfÄj> ÜxPNº–¥ øÂH©…’•°mãçM‰Ï6øŸÎË7¿œ»»e»ÏÁ„ýfçö¦S ŒÒn«¦…<øîüt®u–^»ºüÊõ ÛÐJ'ƒñ|ÿlòhúøPKE<»ÌÞ‡ªy–OÂõNms ³5·:ÞàþŽ×©A„Þ¼¿õû÷¿þßþÎW®ÿzÔ÷ï¼÷¨õQ£·4;æ³¹×Ö7ú›¿òÚÕ—^­ûÍã£Ý§÷×oÞ Ú$`üf=9ýðÞäÑ \a5M-mÆÚ?lÏgÆ@!‚Zhû׬ß}ðþÓ³w;ÍÐi†Ùñ¤š¥Fiº¶?p1ˆ1 @ÀB×[jZ÷?¢BÂÓÂÞ Áˆ‘…ù„K€ ®"H•̶–^Jw8 IDAT‹q\ çÅ(ùȞËŒ¦‘G<¦…¢¡k´±h$â;¶’›fTñÝÖÍõúFßk7¨ïØ ‘åå4õzÚF¿ͳã±%¥É¬,GsûúÆÞþÏ›11ÈŸ#Ñü…Öû_ƒåŽ! \©®¶ë›Ën3Ä.sjH‹£?»Ç"oõk/von6ÖûÀ˜éÞÉøÑbD+­¥²vÅ¥È+;R%¾c€‘yÅj,ùÉ[WV/ÿæáR{~4€Ð\ýµ7¾ñÿá Ñ‹k§Í ²táÒÅ»üþñÓ§óÉÃçÙá÷>”EÕÚ\ûpô§£§û¢Í¯¾æxî;oÿññ“­ ×À˜¤§ã΋›+oÜLÏ&“‡ó­3MŒÒ ÿ½ÖŸî¥1j}lc»©j©d^Ez^·®J¡¥ª_êcŠÑ¼š¦²â✊FµÖÕœŸÍ’£Aq6³:Œ}qY U € =¸²ªàvC± ÆA¿Y¿¼êwëÙÙ´šešËç"!FÄc4òµT2+eÁÆ$p¡ýM%ð{ÖÍ‹®mЮ¸â²š§ù`ZÍS‘WZ(f›Õ’ÜÖfG#Uq­ŒµÊ¢2 Š-JI ñÚNF²¨ <4‹‹»ÖZ(‘ªO$Ô>¯B¤¥î³z€0Bµ/¯‡í¦ä<êµc{?¼³ÿgÊŠóIºtãÒëÿäïŠ,=þèáÑÛ÷EÎíåI+¥ ^)½ðèq)²’x Q:9FËì0YñÝï¾?ìíN^9õ›õ°Õ$Zw€“§‡³Ç‡Ao©a)­í›ê—VDQ=þw?œmµ®_HކӧGÕ<#¾“ÒÃÑäáHò76Zòã§g(çeÖb¢4ô „Å`–ŸM½NBPM3Q”!·Ë-§)dQ‰¤°œhÍE>œa—Z¦®×k@-BŸÍÅz.µÍƒ i~Í%3¹4ôœFXN’ìxl3ý|!Qì4¿×À.åqqNaG¬ô^¹R¿°Ôº¸ê7¾ƧÃùpa_&©âr¶}”žLÊY"²ÒÊ5—²àÖ †(±§s«bA­Ïï 3Ú@ôK·Ü!$.sšat¡ëu~§Ñº¸ÚZZв<¸÷09EÝöÕ/~áůþJØlɳ2ÉÊÔmGJ©ýï|° 2ÙKº6BU U ·mDVùý¦SF÷ŠÑ »N¸Òö;u¯õ®\¤®+'®süîÃx ¸°kHq´Ö†ïíÏ3§4.¯ä£ÙlëL<6{z<}x€!žCCÏŽ'Ÿ¡”>[10Æh 1&.EŒh¡²ã1v(‹|§mÃáZ3"ò’'¢V¢'²¨‚„‘³§GÙéÄï5Üfä/51%å4áI.‹*?›i!iÍ'.ð8×JYx4v)€P¤E¼sÊÓÂVŠ«’«òç×[k†ÑÆi„¬æÛ6YžÙÉdü`/Ù|ÿ£‹¿úÊõ_ýÊÆí—ÎŽöîëû§ï=ªfY9MR4ôl£Ìm!‡a‚„ŠK£0ȃ1žMúÊ…¿à9’M¿|Ê „@+Åçy9Žû_¸Þ»y)ŽÖ~T+Ótüôàoþ7ÿÅW×~µk©_Ýïÿñ?ýço}­v±Cンr©Î¥[`X=ÀŒª‚—ã„Fžß­Gk=YVÅ8ÎN&¶†w÷»ï¥ƒIm¥ë7êÅ$ÖR!‚D^U³ B,·ªyïži¡–^¿ÞyaCÕá÷ïÖ.tkzå4u[áÅ¿ýÅÆæ2"8>8›==ÎN&v<Ë\~Â|Þ[mÅfUŠÅêG°qmµ÷òe¿ÓðQsc……^6œÝ}:~´ŸݼJ÷K¥”ºõËË4ðò³©ÈJ§•£y1މËHàV³tQ¥–WŠCˆ âB ecve8ÍÈï6©ïð´ÝÛ­féó ‹ Bˆ‘Å`Îj«ùÄw¼n½um­v¡Ï|7赨ç<úÁ[ª,òhà6¯®åƒv©…×j)€ˆ7pdÁìH»Ôι4·>"e´Ö\ñ4W¥0‹œ¶ùÙ³šŽæ—iwGb ’ŸïžŽº»­Í5/ŠÂF£Þhñ¿ÿFw½Œ›³ï¼ùo|÷Ï,‹bòä šçvxaõ^웇²Ž£µÈ+€`5ÏÎ~ü;Ìï5œš¿¸Üï£øÖoÿ U_}í¦ßnì|çǶéÓíÔùÙÌmFý×o¬¼~³J³“w®}ýÅÖåµäd”žLº·//¿vÞèñ~6˜BŠíVj‰¨õ'”c—–oM³ØgN#d‘¯¹,' ¼ ¡Ñ£=ê: ¿×,ç©ÈJÛ>R çˆ`ĨU<1fÕ4ÉŽ'Š‹ú¥e·±ÐÞÙ¶($ñ˜E8YQÅëÔƒ¥†Sóë›Ëv¶ÊõÁ{O-wö9.…@ a€ç¶kå$iÉÓ@à÷šn=$s"¼uxøÖ½*ÎÒÃ!O >ÏŒ1n»æ5êØ¡å$±)'z4tm¦[æÄxO #µÒ–(þäqý3WøÔhã—`wG3ê4¢Æ•• ßBw.¬Õ›mlP·µêB÷_}ûŸ<ÜZzéòRoíïýήwGÉÙÖýß½wòãGñÞ™eZ¢Í¨JÒÀ«o,).ÊY­wë}á¼<+ÇsìúF¿÷âe¿Ý¨/wEÅ0ˆúm¿Û¨mö-6Ô¾¹Ñ¿}¥¾Ü+â4>@ŒÖ¿r»ŠÓršøÝºß©'Ç£ÁOOÞzPÍR­”e,&¦ŸußB¶/‘g \«lÌ·Žç[Çn»F\&KnŒA·o]ŒÖºþR£ÇÕ4E—É¢² W‘2¯¬ï??j©eQ‰´ .ƒxÁ$ÒJ#JŒ1<.lzòð ýâæú¯Þn^\îÞØ`—ŸÍæ['?[‹4Rñy®Jâ\$…gC6Y9xïéøÞ =£t¸Ún]]wêD0?›`‡†µ€×Uq È«jžÓÀqêÈÊbœÈ¼r! <¿Û%W\°ºoA–å4•i!‹JdÏ,ü%Sf„TEÅ“‚nÐi&ã sܵåKR‰?ýÑ¿þ¯ÿöÕòÂÊl)»„ïˆG{wî&Ã!@sÉã\UÜ;B!„ØaØ¡ˆ"%$OK|΀6Zë’ó¤ qžçå$IÂ!°½¹FÃG»“‡ûÙÉØiFFk¯Sc¡WŒãéÖqr:b‘ù›_BNwŽ%Ôs¦[Ç'oÝwάýÅ6±,ÁŸ),@ Fƒ’Û`LçZªúÕÕúfhãÔ‚Õ/ÞòÛøøìø½Gñþ œÄéÁ°ÍíQM–œ¸ ;ÔhSŒ¦"â±bg'yØaŠKU•ZH#mZA±K Kæµ"¯ùíºW¯UW³Ãn=Þ95?GÝ6ÖáˆÁ.@Y#—Û^§¶ˆÛžÇ€1^§^L’ä` òJ =·]ó:u‘<Î~¯ŽJ}ÃÓbÄB/Îø˜ù,9ÀiFÄcF©ütâ4C\÷«y^Œb|L‰‡Yä³Ð“EU,Ób$’B韕Ô~NHÎ_¯ånÏ»N=×;n+äYÞ¾²Î|jøúÒ—/mµ÷k§O/íŽn'ßÿοüÞîÚ—^¸ùÛ¿~zçÉ|礜¤‹4»Öç<åEC9v©Sd%òáLseçvå,uj~çÖE²âñþÙàÃ-Dp­Û±ˆ`Ò›7ÖUÅgOkýÎ Ñj7;›ž¾÷»4\íÈ¢Š÷Έçô^¾ìÔÃùÞ©,y5MDZHaPh—°ûýÇ7x›ßárÑV¸ãìtšLl10Æ­‡áZ×ïÖE^ÉRÈ‚½N]KUÍÒj–,ÏHU’Ï3çØ¡`Hf{L¤…*…͹«Ê†ÿm4©Æñìéqÿ ×6ùx®JnÌÏ[4–ãN0ñVó´6¶W";™ÐíSÛ „)™>9ÂŒØq²åÌðYVÍ3+=±š_N›Dó{ D1q%¤Hs¸Âr’ˆ´ÐBʬ´zåÏO¬þRšŒ‘EU g<ÎËI"h  ëõÖ¦÷ýÿâ9»¿µòúÍÖòrýâÊí³·ù÷F÷vËq‚i),È€b#U1˜YõÀde~:Nì³Z …Š•*§i5Ïl;œÌ«Ù“£á½`ÌðÎ6 ºÐ£¾ƒ)î½|¥{kÃï5Ò³ÉáŸÝooüí/–ÓdðÞ-U÷•ËÀ€ÁOOÞ~PŽÅÅ3ˆÝȵÒêÏÁum«Ô¢w #-$ŸgÙé„8”Õ|HH1œi.°ç´n^–[ª¨âíÓr{Ýñ˜%vœsI‘HËìd"³Â±žÃÑ¢³ä"+UY-H‘‰8Ö&­ÍÒ7ÆOnhÊIòÜ&@|'Xn‰¼²’"Äi¬î»Í +Ág™¥y&ûƒj–XÍ·îgˆ@~6µO£´È«EíÆn§1³²œ$v;XÍ?gwDqUI¯]o]^­’ "To´c“Þ9ù1$èÿÕï\^»uqåªÆ`¯ÜŸc‡zí:õÝô`¤¸„̬´GCÏR9-~±ûò%žù`f%ˆp­­wų'Ç<ÉFh¯§éÑLC×m×´PØaK/_qka>žOŸaFný“oRß9zë¢ØiFªãGû“ÙÑXò c—2üéî+›^³z6¨y}-Zïˆç´®­SÏIŽG³íc;Z¢5O+%Ëê< adQ#E €žJ¤±• q£xásÔÖO‹(±ÝÁrsù›N=,Fól0}Îý@ˆ]J|—ø®1b‘Çj«yªˆ¯K žå8aµÀmÕ,Àhƒ¹Œ`äP§!Zh©hèz½:ñÅ…æŠxŒúñVDZÚƒ*?WU£µFäe¼†(®­öŠ4}px§Çݨÿ_þçÿsßtÓÇÙÉG»ï~ÿŸýŸûßy_V‚úŽ–J䥰C ¡¶GbTMS§`‡©¬ß®´—V „ÉþeÈúÂý^SB{ôþÿóGñÉÕüpµ3ß9©â̺çˆçÈ¢²‰l%$,¸HK¯[sš UTÓÇGZH[Ìb»…EVb—Õ6z™C6VàËN§éñX é4‚ÚFß(=y|PÍóæÕÕå/\£¡?Ù:ŠÍË«Áxï Ø¸¶Êj¾åu•ãXæ|‘â3Fqñ)‹˜ÑzQ$(ñ»ÁC‚!BéáP$…Û e)øD ³8"x¾s:úp1Ò¸²Òºæƒ9Oržäå8iA<æ/µœz ¥ê¿z­wë Ü|2?~÷ÁäáþÒk×´Ó§GùÙÌ_jºÍP ™dC[žø‰VIøé’x[¡RÃÂk1R\VÓLU²Î,zId>˜²Ès[5‘ÉÁ°š$Ö 0B‚ÏyÚZÛER FœFh´–Yi'¸ZI€á3VºJǹ–Òi„ŠËìt’ óÁìyô>?Å%å\hä‡AŠ6Å`N\Jkj”¹@+ÃãLU9”8yT–|‘®Âˆº0@ É nó~<ÏmÑ3 ÄÚ7êóÄ™16Ì«jžÇûgÙé¤Êò"M‹iüô;?jm¬þÊ÷jK]LÉäôäè;?:yçAv6Y) Îç™5ëc0#Ø!â0`1˜c+-™WŠKìPV n3tÛ5„q1‰‹áŒ†^óÊŠSâ½v(«ùå,Eý–VjôhÿìÃ'£«ïkØ¡Go߫⼶¹„0ÎϦ“ûÅh®¹2æŸ ÂØ,¾€Ÿï-FåçWX8n3jÞ\o^]s""äµëöì>¼»]ŒæÁÚÆRYóËáœ'v©…GW³ bä¶jÄc˜ÅÂH¤…}}ˆ!ñ™mº3PŒ26m³|Ð’|*i'_Ïã¡U\ñ´°×â1û$óLKE,ÒRU‚¸ 1RÍs›n!¾K\º€Ï´1s BÈn𲨠ØcP©µ.„5¥Ú ĘÏ×Ù1B\f3JÄc<É{·¯m†Û{k·nüÝÿéÀ”E:Ü?xò·¶§[Çó­>Ïìc”F¾Hr£QFUÂÀ0Â.õ{ Vó­Œ`´a5O e¤²ÅIÂršÌ·N ‚õÍ~ûæÆtû8ÙЬiá6C§ >|:~°/³jù¾þŠÛˆö¾ÿ¾ÈÊöÍ ÀÉ£ýÑG;å8þó¢˜yV<ô©£'‚!­€-«°-ÇÖ,óÒf|ªyæuêØ¥áj[U¢œ&,Š¡K7è7±ËªyÆçÙl똸 1J<% ®*a”‚A í Î<ë5Aâ;DqÉÓÂ-…eV>¿_•xbDæ%Ÿç6÷MCøŽµy—,c•xDP•RsAü…‹Î~@Ø¥ ‚¦ª˜QcŒHK{²fOëæø\ÕØ“7‹|¯[×:ÑZש4pZP_émÜx¡ÓZÎóä;ÿô_îo#‡xQtñ—_ýßï¾soòp?9‰¤°Èµó3ÄÿÇÝ{IvÜwžiž¯|Uwuµïžïg€ÁÀƒA‚ )’242Ôî)nWÒ)b§ÝÓÞên7t±·»2{2+r%Š¢HŠ"  Æ›Ó=m«»ºË×{õ|¾Ì¼?²A‰æÄ‰;^ÐßÑQ&+ßÏ|¿ß@‹„dhŒ$–/…ªbi,¡AËŽz®·Ù•-M+¤dK'^X}éR¿Ú$ŽuE1õò‘4"Îzsâ-G$I¶ÆJ,¡KÏŸ̼ãn–$k§g½NfjhàðL„îZËÛè Ÿ8úôå»CŒÙw¢& ÀŠ8èÌ®4Î̉¤Ø çZ!•Ý6Œ‰3î,mÒ BdSÕ i$cIW¬J¡7¿4m¡¡ßŠÞ)„T¯B!Dß¡› ŒŒ%C£Ä¾lF’$ˆnçH½!Ä©C/D²¤æ,áøŽŸ†13&[š–O«3ñCâG!³˜‘t™F$vCÙÒt=MC» )È–ŽdLƒ˜3.[DˆF$ìôºJ  ~û£ÒŸôãÎ(K‚(²=¬HZ.…e‰Æ$ñ£Âø–¥åÓŸùräúÛŽÛ³{hf:A´×k z=›B‚8¶}B+ ‘*Âiû+uœ†ú›%crÆ•´aV ÖPpöúÞF'hô‚¦ 1ªì›½o¿š6ƒnÿèÏxô¡ùQ×î^æååçÎÅ=7¼½›p ’ UÄØçvŒÌKÒðúèÆÍÕùf1?•›y|l®s}éòe¿e‹uØÚ„Õ­nF1PÒ<0sÆ@"è7º~£‡Y6¹dªjÖŠ_¬u(IÛÞ¢Û‹@(c VeÉP£žç7z^>Í š½ÒÌ„>er‹¥²¡gÆ$%Q¬ZFab˜s.kjÐíwWj±ãSBDDˆRÊ(Ó2fÀXÜ$]Ñò)¬JaG>!ÉÿcM2æÕ»zÆ*UTMw“~ZÍÐ*:™Ãÿ%Ìž œ·èZTÿ™Ì­Â̹lç¼£ ¯Ü»N~ú™EW2_žýOÊG·ëÙÔØ}û½Í޳\G²$iŠQÎ œ)LŒÈŠÊ)SMSÍXA!»Kˆ5)qq)J†&ŠHÖ…æŒwާÊÅžÓ"qpx÷Sv…êÑzóºw-d?xí>s‘®ßANÜèwí_øÅßÎɹµzêù¯Í~ñDo~-vCÆ4ˆI8øÞ‘1ç€3ÊãIHÉšùí£û~úÑ;·?p÷›…?¯Âv¤P2ö}èîÅ'ï9Í/ÍW¯ªŠöò'?³yy.´=³KÜ@¶t¬)f9OcB¼PŒÏ9ŒR£ãovíÅ ÙPÕ|JÒU5o'É’±ã“~H`Ü â·Ûl(YË(ç°„‰ª+=9XØ9¦šfвïþØûfvÒݺËÌûžÝ˜_R-spÛ$V•È÷xÂ$U)ŒŒÙËï·Ú½õMg³…ÄŠœÄÄoÛ†"Œâ¾ïnthDÔŒ!”g‘ãA?úQ#LÅ FjƘýâ‰ù¯Ÿ*íš9´kçÁ;ʼxô÷ÁàßÌ‘TÖµƒêÿé¾õUã…]óØ¢s䄬ÞÕRÓfýb§Ûl 471¤f¬âžq¿ÞG³ËHÒYZ¶QÈ6Vú›ÍØñhœ@I?H""iŠšOqÊ¢žÛ®d¨bl;ž»ÙuÛ*è™ôÜüÅç/~ÆîµS™Ì#w<õàì.á³OÝšÅócêÔcƒïšUûÚ SC%%m@Œ±"ÆYœÈ)]ÔÐߥéqJ‘®Ãctvýâêa¨Ì@’GóÍf¢oÜ1¥îÛcí¹&ßxåk_iÜX »nûêrd{"þù‘ÈMüˆø‘TCXFŠÄÆŠ$ p¶¯ÖN˜E‰Ø qÊ ÆXÁ"‹&rn‹ÈÎ 8W,M2´$"‘íBX.혘¹ëŽl®äyNc£ê»Nß·'¦vMMm¯n,¤Ô´9\PT3fr³X(3ƺvs½µÜ©Ö"?/è8²¡â„F¶k•òÄ íê¦^Êf§‡ýF·yu) b%c@ Ñ0eØ›÷vç~Ë)í™>²«09ZNÉéÂ5LÊÒì;&mtvÎ~0ÞúãOñ]ÒüÂÕÁLüX8ý‘…—­µÙúÑ•£Ÿ¼ð„÷êê‹—ž~¾_maUaqBÃ8ˆÉ­¯¾²9R2s¡ÞBM¨&cÛ#^ˆY´çjÎ’-ͯ÷¡JÖ„B„½Ívk~ÕȦÃÀ_~ýq‚™ž˜~÷΋ùX£±û¹–Û<:yÏ4ïáþW俽òùoÇ$jÍ.m‡sÎHÂ)•-mk¿¯¦œ ˆz éjÆÒ4Kâ¨^_‰–|ËÌzî©sÏMöyèŽAe׌×êÖ^¿.gÌ$"HÆ[Y”aU– #'ÞF¨åSJÆ8+uF(’1§[J5¬ÊTHe¬úÛ,@ñ"±FMj/nÎ}í•Þ↞I©kxûL±TÙW¼ cÉ‹Üòи\0{ýVJI§¬Õ¶×¹<š›Üeíf“,â±}ôžÀ#º®ã¹6§¼~m¡¹°Âšß>’›îÝZ÷êݰíˆ\ì7q1ãV›ùmÊ¡+º8}–MR¶âo—Ë»^ì~ B½“üÕС֙ÞVùeð&i¨æ£|ä]â3θ³Zo^ZЈИ@E¸ŠØ&æfFôbÆ­µÜÕ&’%%c°8ñë=¿Þ“ UÍZH’üFׯ÷´œë-Ô°¦„¶kÒû~èÎܱí—rÊ^Ûå?KOžÿøÈ;KN®Vì=sñ‹'ÿä3qÏ+í¾k·ßqˆ¸µvwn=ê8‰ýÀ1nÇq,#}Ì ç€k¦™0ÒêlÔ««”š$jÆ$AdWën­•ø!%É›ù¸s@¼P24o£CcÒ˜;wÆ£ùü¥ÿiPÎNÖ76Öº§ï>ûDùâ{9ç´ò׳ýÒèGï¯-/*ц×uº'68ãÄ I„¢= "¿ÞMü¨§ÖA³u]a›H’LUØ|cÃßì -æ ìö%UŒÉ¦f²œ±gÿèÏ‚¦Í1ÏŽ~û£‡§Ž;}ï„juu1?8tàȽã|4½ <§Sél¶Øª­±„šå¼½RW2&£,›” D θ0hbM^{}ö“§ge¬§†•Áôâ©sþ×{…ñá£ïgalX7-ÅÔK{§Z×W¢ž«¤ áCg”F’¡&~Ä % § !ˆp.4ñ’¡ %°¸ÚEGÁƒÜ&!^$@!Œõb: b¡A`$I‚¸uy‘Q–Û12xp[nªb²íÍ ÇéËŒ1Æ©žJµëꊒ6ÜNO‘ÕB¡¬J‚ˆ%±ë:­ÍZ*•U4meù‰£ly [p;ÝÎÚ–¤ÔP1‰b¿Þ…·­ËÿI-f8óë]½”52H‘z 5wf,ñËÖÙÁ»ÊÒþnkõ‘{¾8yòÖ¥‹;*eyüÑʻǣŠ¢{¼×8|ù¥oÏ~þùÚÉ«Q×ó8ÞŽmOlFFz1øU‡‘íÆI¶Lƒ”!¦*éܨJºZØ5A¼À«wó“•‘ý»÷ÜwÏ@n¸åµ^|á ãCw=8RžòâþW_úôÜ+¯÷Û€`ÇÍË ·Û¯6Åðç{ɪŒ³8ª,\yaÇi_]–îÜÿ·³©|¯V/•†¾ã¨gÛn-è8NÞ,”+ä`ôíçÿÂ^Ü™ñ!%­Ó˜²$+w¡úzƒj$ò!–%ðÄH²e( JÀ# Ðí^LX•”Œ)\kE]—Q c !4Ê9IWK÷êÝÎÍ*Ö”ò¡k°°éÙ¡AFikyM˘™Áßé+ºÊ9XY¼9!‚-ŒÌR®¹VE²d³aä·Î_dEK™£Îâº×è²8!nH£¼©çî@ˆPØvˆ¹ôØ€`m~nï¾»vxPÅgÞÛª‡›_;ôóɃZM4á’\½Ù¹¾þzµ¶¹Ô«×‚jÖŠmxg Š˜$´ujÖÄŠ,¼œP–PÉP„Q§ÏÇŠ $A”±¤)²¥©YJØ[Ü请öOßñKïß¹;“*~ÿõSß¼ñâk½çýdzÇ%C»¬|뫟¹ðW_#ý@/f(!^­ã×»œ1 D†D°k¾çš E‚2’0À±*ßwðÞ{ß½2œéAe…Yç=ã•7¸{´K{—§×c/@2Vs–w½uÙÒ•Œ™„ÑVë“7 ²B`”ñ„!Ķ÷½RâE\e²©7Rùíu~#‘r,hdŒ$à;ZkhLºókz1c–óZ.Õ_o…¶—›¨4úKŒ1ÙÐ:+5g£©ç3~«‡ÙȦõ|JeŒ’$è8í›+™±2¼1¿‚0RR†ßî­_¼Ac"…½Å ¯ÖæIòÿ.Dé'çvç"¢p€U«Š×ÆuݼÅV;åΞzøêžôÒÊ»7§—•¹S_f}ö& B{q3h;BÙÒ8cXSÙr=‹u\ÉÔüz7êyœRÙÐÄå‡5å~pB¦¦f-AÄZ!UÜ3¡¤ÌÂÌ%äÚ‰“í[U·Ó-L޼ç§~ùñÙÃá°tfzá¹oüµ©Z¿þÛÿ¹,¶'ÈùùW®~ãÅîÂzïÖº³\ì ñãïiCŒ‘„…L1ŽÉÈ‘ zõä7κhxl ï5ã®~_<Õ*Ý}aôøïË…ß8Ðmï|òKsaljmˆñp賈ÐP5R$¬È€F)g,v<¡vD2æÉpjJæö7”A-ŸJO–Ír.v¡D€%~ä¬6úÕ¦¤)ù=㢬;Žl”$m²šöHYW­R!‰¢T¹¨z踥õÞÊK˜š12£e¿kCbÖku7/ÏKš"øÌîz‹ø¡–Oׯ7{«J÷„DÃXÏXù‘¡¹¥ËRVît²k;ƒçÐß]8õmïªUydûö»~õ±ÁÒH'nÏ/_Y>weíÕ+[èç7Œ;IÆ•¬)¶ÓÙm• i÷«-a€æG¬È,I¸Ï‘„Õ¼!$@C"IWÓãåáÃ;±,/¾t®qñÖð‘ÝO¼÷c؇&ž66'/–Î8þG²<ð%5‰4>6øúxÏÌdSÃÎZC²4­NÂaȾÛH!”u)":a-Í)Ã1œcêšçu©\±°N.ôf¯ïS—~%|ë­ƒ7¥·çïû8ëm´±*§'iœ$Aà–fJˆ3.X&äã(éŠlhœqâ‡QÏýNÿÀ‡ˆ‹Ï ô=ô?2Q` ;cA|¶:ISÌ¡¼li4Œ»7ªBÈ€dI65k¨àéê–ÈÙ2d]ã€wW7ô\ÚÌeSƒE5k?ŒÝ è8Ö`bd¯7XB­Á‚SkÚKœsÎXÜ÷ÝZÛoôÈwwAoV{# qS£”ÍWºuU×ïßöŽR?S3Z/Ï}sÓ^=òÔcûŒ}×Rs)®#-g:Øó··\kÏ®@ŒÄBGP%æÉÈbM!^€ÉÈ …à–ì–ñ$Œ„²¡"’˜D=+²léaÛ©½6uújÖÒóéwýö¯=@îÜûZNJÐò‘àϪŸÌo{ßåãûþí:ÑèÅ_U¿¢}öäÿölsn9è8nµ)ìv[d]¿û¼¬)jÎâœÆ•ŒiU Ãwíy䉟þÐôñ£ŸlŽì%^3•½õþÌfÿS¿†ÆŠKsœ¤@Ðu"Û#^DI"nh%cJš" r$Œ±¦ E@ÆŠŒ‰†„ñ÷8ß „±„„I\ÿp‘6eI‡~ìø$ˆÄíŽ5Y$ùD¶‡dÉ,ç„§ IœøQÐu•ÆDÒÕ4ÒC%YSýží6:A×!^80²AßŲdsn¯Õ™_O”ò;FYBýfO¼µÞôzwV%¬È‘ã‘ êUëªe9þ©×ñü+Ïmrl×ÖѱKy³˜ïî×ñÂÙ“/Ì:Ó­mØk s(0Ò2Ä „ßb€Çޝd FYûê q¤!~#*öç?Bˆ EC@¼pãÌÑ{÷ßóþ'îŽo»hF#ðåÃÕ/¿ô©lb½ýúôί.&ÃÖ ÿÁøÃoý‡óþtìúX‘EF;§ «2gìûI¥‚TCãDÖU­”F‡gãìMû½]™ 9sø³ÜͧîÓšc©•uåsS'wÅ'§æeE=¾?êy­Ùe§Œôƒ#Ç(cqBƒ( cF¹H““Ç­ñ‹HS$IW Fâ s;÷%DP¾“ f$‘t5ñ"=+b ™é!N™½¸‘øQfº¢Ò±ãe§†?rÖƒû·i)sóÒ-$ãâöñT¹ gSQß½ öISdMåø­’¤ü¶áúÅ[XSŒL÷ÖzØv„I?`„þS8îH–¬ÑRvfXI¡ãíÚ–)×¢õ®ì$±íaMÁ²Ù§TÌÈE€#£ô6Ù[»ÎYBI$CKM–Ýj3ŽS®2µ–SšèeSÃs¨(éªbj4&qß'^€2e™', úå=Û2ňgÛX–Æ|šk†À²œÍc…½>°2£“3E¹Ô£½kN+i³yuÉ[k%^ø#™Íü˜ÖLÊ–&jJJÕ4¼wGiïb²ÆÊáÓ¹ê›vs,}é×ðEûæ¯-]º!Í)ÅJ:›wo£9~â‡Q·/v‡€Cq @ G¾T)ŽÞ¿ßY­oœ¾¶ì$ŒãCF¨œÒeK#k()vûÅ™±{ßõž†•3ò(•Y˜ì,}œº½&KE¥åÏM.]œxèÐÅñC›ƒ_ÞþG¿J6‰¤«í[Õ-… c”PÀ9ÀèûÅ\È,…=Wߟ2s¹nmóêò¹óÒ‹+Êy‰+ší|±Ö¯6³cCÓÜ©S‘Ä}oÅÒÇï=XÜ99^ì›ç×_½÷}ÉÔDŒZHeg†!¡í†7¶=âaÛÁª %Ä"²%„Ë’˜ÌÀ¿£úGŸÀ††UeKËÅBIâœ/¤1Ñò)½˜ûnf¢l iÓ˜`UÑ3–žË(º:nýúb<X¥<–%M3Fa$,13EÖ`7™ÌŒÊÅ.è… ‘¡ #ÇÊåÌRÎNmÞfcý}»sÎcœ1#ŸÙqôÎ]Å}$‰AŸ<ög™‘Ï_ •“:òÙÞݹ¡Ty‡´¾š¼ IDAT<ú䨽“ײ¹ôÆS©³ÿjýòÜéË_znîK/Ó˜pÊ!B€Ø h™¹Â®q¬È~«çT›‚ú‹i«‚—aÔó?’ MÍJÆ´Wê’*C„RƒÅÉôôgJ8ä¯lkÍu_9 •Ó§úë•o9'`ñ©ÓåÂñ8uÖ:ò寫{SG¥¼~óðõÙ—Nnœ»Ñ[Øðjm1ùáßo’à‰Ü¨0N"‡!ñC¯Ù¡Ií«´çW£…2‚*nW×›úùüαÔPÁoÙ ÏžÖ iYUd]+LŽxèÁ‘é™îÜZв•”®¤°Ýº®·ÙwÉPeK€Ó„"EF¹b’¡Æ=—*›ç<ñ#pý’1V%%c’¾ß_m  f%%eHš eIÒäØñcF9vûöÊFft’ çÒ£~³eiúî#Ùl‰ÄmvxÄ$,W´áÉÜtjæ–Ñ “ñ¶) l¤ÊEjEQ0ŽF¬í©Nµ¶Øé á›{«JÜPÒs¨0}ÿѱé Õ=þ_˃Ÿ¸j¿ehö6ovk—2˜.›ŸNãTŸ·—‚Ń­i´×éÕÙéÊð}ûço¹«Ø €âÚ&~Ȫ¦Mâ…„1 ÂHÖUÙÒ‚Q×M‚H ŸÕŒi”Ô´vû½Zý™Ÿy52žÇ—–Û³hýü³#WVï|­0û±µâÚ?{«}sPËN¤?:ñ/Ç.j_rú‡õSïÙf‡ÝÖeÙÔtÁaôÂð8“°œ6²S•=S£Îê:–¤ÑC{†*––Ž’0ˆ<ßw=Çvš­Ö­•‹ó›æ" g~~jøèÝ™¿kz.·°§üV¸zú²·ÙéܬмîÍ5F¬)R…]W6U,K±í7›WÉPD¢*8´Ûúš@ØîCŒbÇO‚8lõiD FÄ””¡‹’¡7PSFf¢¬åSjÆ‚F®/ëÄ(èõÓC¥ÜÈPÐu6nÜŠÝÁ‰ÉòŽiKIIP|·Õi YÛsм4ÙZ±šHÉUk·Òrz:·=€‘ãu³#åá»öÔ^Ày3kf Ôr–¤«a˶7ÍË ÛëêöFÅ>@×ÿê@aÝ;|óßÓ'¿pÄoü‹¹OV—§.Ot¯Z/,]½\û߯o¼vÝ)Š$!¤H2ÐÆJÆTÒ:gÌ^Ù4‹ÙCzG¯¶¹ø­3ë¯ÎFÝ>g\NéBÆâky޹ÉÊÈ»µtj 3”ý\3c½vßñO™éGwþÎxÝ]ŠÞSû>©>uþÛèÈ÷Œ0ÕVíÏño)OH•=ÛÏ̾zåo¾Y{eö;iÆÿ •î;¥ c1‰m/ì8+'/©)CËYAǹü™g'î?”ÊXD|Û±k ˆ ^̨9+;QîÜJâ¾Ïв¦š±â ôb·k©žZÅÜ‘÷=®™æúÜÜò«—hLZW–8àƒ‡fr““Õ—/5..`E†qÎ…ÖJÜÖbDÃÈíwΈãÛOÂp ›ªHœ$AÔ»Uc$Ém:«u{yɸ°k<;^ŽÝ@RÕì𠄤¸ïçG+Û&÷AÎlIê:3×X~ A#†Síñ7^´%/NÂúéW}Ç^J½N)}?‰\€«~$²™Ÿˆ€2F™ß´ ÍzgóîCÿúâÚôÒ±kwp?uðoAþ<;ÿöËßòÙ¡úJóy¹¤å{éJ£pï‘_\>ºþú='ês‹Í«K~½uúI U Khì†Ùi}äÎ=¹ñ!{½î¬5Ô\ª¸oÒ¯wƒ¶4{œrF€FId{ňEV”'–†”¡µÿFýÀùÜÍ¡»ŸûÌÿpŽÞ’œÎ;m#üð'ÔôÍLóýúkw.=ýõO½ö}Î*Œ?x¨1»¸yöfØv¶¤)|«êýîwË’ ÛŽgéœñ>ãV¥À(ó6Úgÿà ”P–$#%â†NäwŒŠ„½¸ïÓ(¾þù.þÉW¿9UI )e#Ç÷ŒØ«¨ZªT¨Ú™dOÒê…k”$f)Gc’„u®¯M›FÉX@†eK‡Å}ÿ6'Ù,aœs$K(‘¥XU*‹„¬H!¡eÈNe§‡BI˜‘DËX”P–ÐÁ3¥ÜPbZétWñzÝʼžºàõÆÉR¡j>?ÐØ¼²pébkyQj2aÚe í.¬1ƱŒl¥A£7¯ÆJÊHO …L–h$‘Úûïsç“ï[š|ù­çvÜ}èæ»¾r4¿6`>ùZiâ\æÅ}þ}øÜïíÄ‹Ë×®ÎëÔú©k]Q ‡1ÂÉX6Ts¨P˜1s™¥ù‹ýͶ×è´gW"ÛÝrñP&[ºTR€€)˜g<öƒ‰‰cšs%šNìm¿¿ç^*Ç/u?<ào¾úÊ@i~ûž¹'ÓO—_úÚþåú…ù£…©ÑÁéIE×Ýj“',hÙ‰aÿndad”óÃwí®Þ»^{a-´½Ñ"Œ1Æ¢•$~˜DqØsÕzóÊ’’6ça»Ÿñ#ÑÖ;MaûÖʵ/žÜ7=¸o[¦2h沛󋜱Le ?Ráœå†Ên«;û¥6^».[:g,l÷Ó¹â¾I“ö슳´y[]œó„ yÄD0'‰° Hš¢ÒF91²—j’*Ý«§Rn§«hêØäÉæ¥Ã…©Ã†NžŠ™¾ôÁ'ßÓl¿½Ù ÍöjtËë~³ôûn½“QìX‘õ|Š‘¤*ÙÉ!!¯üÍ-HÂ’¡¦*%ÏïÏŽ.ÿÊìI•_z0»gYÏtZM¼q‚Æœýðz7Ça'ì.õ:‡žû¹o<÷©Zs¨JØÌö« É‘T€Jü¨·X[¿pc÷#÷ÞÿSï«7ª¾ôl{v…EDßÕ¬eåE¬œ^ÊjùTý⼤*ÞÄôÜô®éo'ÿNªÉC3æÓƒ}Wp¿®§nÊǤð…}æŸËÏÔÿhõon¦†ŠÇ~õ§2•‘±¡ÂX£Sƒ¼þ…ÝùZâ…±ã'~ľÛç0ª¬¤ô⮉í÷ÜéÙ=¯m{^ìøéÑk°€e)‰â°×OÂØÈiù”[kõ×Z,N’(NüˆF$ "ñ¡! Å}¿¿ÖÚ<}]+dJû&±ª˜•¼QÈ0Æì†•ÏÇFô”5ùðÑìTÅ^Ù»nÔsõBºr×nÀ¹’ÒYBÝjóvÈÔp8–04Tˆ °ƒÅ}Ÿ3&iŠ^ÊpÊ(%™‰2ç¼½´6~hߎGP§¥É]µ‚Y}=&îŽÄ^¢ÔéD4ŒÇÍ~'Â= ˆ 9¬ö½z7lÛc@Ôs‘ŒI? Z¶lé‘í²7u€sn Ž<õöGû§Ø×^¸ñÖ³F÷,lþôŽ?üš¾ûµ¶h[ÿs%:¤B}mî¤üôgßÖ½/êv^vC{ýµ«¡ë*9 @€0F¦$A – 0–Û½k8?®[éd˜¹ò±kaÄ(:€G¶§fL9eˆÔ}Àysvq¡”=sß;R8y3}à/ù/KWœZøÕwœ+<òù™›ç.~bò΃½óW©lV—_<·DÎzïÛÃзWëݹuâE¢‘À”AÊØ?Ð`A„”´iå€qÊš–*Ÿ}}}­‰dIÒUÎ#”¸ˆÔJ ¨9Ë(eüFOIù£Œ$ýõöHU‘hD¶»AÜ"ÛËN™îÂ:°òðÌ`yÔóœöúFì‡a·ß¾º%$jd{íë+’®0B•´Ž5™Æ?$ÿL¤Ænõ!lËâ­3©±Rj|PϧüFOϧÓãƒF1›© h–öÝŒš;vclûW/hìT°xÔ8XHL8ÿñáëãµµ—j¯ß žïoÞ¸eWëBÅIHhsÆ“À“t@´lÎ8RpÜ÷iœ@9oâÚ ¤Í©Ê·¾Ú ~óJ®5ñ§Ï·ÑÁÕßåïœLý¯”Á¥wþbõ‡sŸ33Jõm(íáÒ©ÃÜÇ‹ùÍsÇ›'Î=}æO¿È ö”pz²¼÷‰‡Ûóžñ›©«òú6kfì]Û^‚_Ø8u àw±¦`EâœKªÂ(ã M•vOT¸ðç·¯oÖöï;ç¾tîñÓåFm¨ÙõžÌÿÆ/ýžYÈ5ôÞ¥¥ÓW¾ôüϼ ™Z§¾ 8ßE‚Iàœ†·‘õÇ`p1b4RB¥#êº4ˆ²ÓA|WuF$‚þÑé{ú”:öÌŠ1Y÷Õ¥³·tn¦R),ËŠ®ƒŒänÚ”Q¤È[¶/Î9çI"Ûmë*‹Io~Æ qüÛtÖþÄNf€šKΛ~}îm¤ÿ"ûà9gý«ðë¿þÊbfç[›î¶ê™_ßV‡òÚ7ùõ_ú_ì¿._ím”õB5“oë#æèä¡kw\sV€¤ÊœR$áôèIâ>ôNù?÷»'}÷ðÉ¿>“II¦&Zl{9 8‡«C64“¨ãºõާFqW¡$,yÞÿØ3{_E¿/sß¡Éâ‚^ŸT®ËÏ¿ð¥ÓŸø¢½¼i³“Ñ ë Y2‡ò~½GÜ@¨2¿G ”-½¸{ÜÈ ½½´‰U9·}$=: 2X‘’/ˆ]?²=¿Ñë¯6ÜZ[65w½Ý¾²„UÉBÌLÃN_¨Yœ0’p]vnTµœÕQ• ×WÓ¦YÊÅ}ÿ ¸1çŒ÷«M¿Þ‹Ý€F DD08ÌôÆ'&Ì’®`Má” ø³^HgÇËCûvLíÞ7–™Ê_cågžÞ-_FÆ~·ýèÊ/ÜÕ Ñq´2\¾üüú sn³tû~³4í°Û§A²¤f ÙÔ#ö7;B¨; Öd¬ÊLSä„üŠýø&3q‚d©ÙÛ|éØòÔžÑòÕFZj|øþzà“c§ÆrJõÌ#—f¦~öŽ‘Ï=ó5sŽ•rtàäãw<#r®Z»pCÿtVÊ&aŒUYÍš[b gÆßYz|úÛ”ÅÄo\þhqMoJšŠ$L£b,iHNëcF‰mß(ç´Rš%ÉëàRëÉ©Z J9ãN­ð+'ßQymÐ?ŽnÞÝýËóuåÄ·½v¯|hûon¬’-5Õè;Ý¥ËWæŸ=µñÚ5¯Ö!~¸EÞúž~ÏíåͰÓW³& caÈh]Y"^¨e¬Ø 8cç­dL5mf¦+‘톾biZ>ŘB$KX‘@ dëH•cÛ‹û>”°@‡{›¿ÑukíØñ%S°7±hƒ²„2Bog}!„2iÑ‚CE¦»šµÀ $‘ ËÒÆâ¢^QÞú¥’úîÚnîÜ.2báním¨²^Êôznìø’®v{ûã÷~·ÿËÁ·ýþò‡´·û¶[mõÄHD¤Ó˜°„Ò f*)CÒå Û¿uù¢|Pž’F/lXTÐå–;Ž.þTð<<ñÊÓ_ë7Û“÷ž:~8S¯µ\]=}y`ç¤YȆ¶Û¹YlkŠÀ|ÿ8/î°Ñ Û’¥ïè®bÛi^\ 1‰@ð·Ä_ÕŒ™ž.k¹”šå²¡ ~|Ôsiœ`E¦1I¢x‹"âkdº Œm?ìôýf'Œøaв%MU,M!FœsÙPU††ä‡žwζjD±hB,C ‹Š0š|ø¨‘ÍdrÅ»õcÇÿÛráá_ã!…·(˜ª-—ø‹‡ÎF.Xk,Õçõ†·ÑfœÎÞ´ì°Ó1$œ‹°‰xAÄ€±¿çv  ¤!a? ºÁë¸CISKKbÒ Û×v7nþ{eÿ««Êô´þÓ¿Þ~îpþ=Q±£Ož±¯øÙÚ¡¿;ôÉ!xH6RÁµ /M8Otò?[­žŸüåO=*¤¼}u"˜)™Ùôú]œÿ©™Mµ¯ìúÃ}Ò/ŽƆõR¦¿ÚàŒ ³Oˆ±H€ʦ®åSÓ‡¾=ó趯@g ùôñW/Ê/‡4ìœÙ`q2yôàñGÞarNâ,ÍÏ^~ú¹ëŸ?á7zc*í™´Wëý•ºWk‹ éïï«„daÙ^¬Hz1“.î›ÜqÉaEB²vúýµ¦¿Ù£al ä¢0vWaË!~$éŠÀ’ |€^nQiCŠ’ÿ7wïf×Yßû¾eÕÝËì½§÷iF£Þe[.²\å‚ cBÀH$÷$\.9'ærOn‡–ƒÉ¡WÛ`÷*«÷>šÞëîmíÕßrþX#Å!ì{ÃãGÿX²ýÌè™w¯õ{¿¿ï÷óµlYP%b9v©´+ºU¬zõIB)äƒ*àÜ.Õ<Ãܯ|Àsʼkˆ ¥„Ú.V¤èªæÞ}×6ö÷ YhiíYÃW¥–XxÒ!ï-rARÿòƒsÛ¯Ëï ȱØrfÜ®éXü‰±Y¬Ú•DPð+ª€!^÷¥]®Ùš !„—rư(pˆi3›xÍ+ÿÿ3og†[…ªUª¹†973F:èqsìX˜[6þ—‹·½¶΢¿‰Ç´=/~ú¿Z­w~Dþ‹XŠ»Éƒs/㩞BkÒn›ßØ&IÁ¶Õ}_Ú%1Öß*TA•Ï/¬Ïõïݱó±Ý‰ét©L“YÆ™öCŒ¼`2DF<Œ2çµÅ‚×{aéz¶©šÛkœ|eüø%j¹©¦Öm»oéMõÇäxU6Fr—O¼ðÜàO^)ŽÌCuœêB®4¾èyQ<ûÀ¿~º{³–§ú‰>+u\»R µ&-Iѯx¶-F%4Øœµ§Œl¹:—©L§­|Õ*T©ã"QpB½FiÁŠa BF™S1asʨã >EùV¡Ê)“Â~(`j:Aε€×©ýfÔ†‚_‰:.p‰ô…;êk;ã]Íõ­þV qÛQa`ð äcG}/ Ð#ý%qû™wÈç­£A3\ߨDXYʧ+³ijº3_µ«:'@¸r7@P *¡Œ2$bæ¯=“sÆÜŸÞÉ·MˆtuK›Ë.TYTäɶè¹÷îÛs¼©ÙùþÈM•ÀÑ÷÷M6¸ëT^޾КïÌ 6ÞyÚ}gWµ~aêûKGǶ¿WWA°a}oúôs‰ò„8«ãkšŠÑÁ{¬Ò{#ƒSO}ý饣—+SKÞ—v*5_êuz1—@©Mj ùÓ=“Ù9«„í«?ºëþ°ôU°«°¢¬kCO=úõ‰—ŽÙ=¶ªu÷ÿõpÇæõ±ÆQ’+•ÂÔ¹ SûOå§µ¹œ¾˜§œCÿÕ¥nͤ¦Cl0ŽI ûµ™LitÁ“Ò=ßÿ•ö]9ÐT§ÄC¢_µ 5¯xÑÃÔ8Ô@"Æ¢À(£ñ¸“ p¥iK–EN¨™«pE¢.a.qc¶KmÂu5“ØŽ‡>~S?-„FP@ŠB1 ŠÕ*j—~üR~ÓÜöû?³ísF"ð·ìŽÃ¤®Ê›ÂÓõ·þÓ§*¶X4kÆäé‹vU§T É‚?«Îg´Å¼R¥Ê)£.áŒ#ŒìrÍ*Ö¨í"Œˆíz/m!#ì7ӆΥ–ë¡‚Ç.ŽÜ¸ã®»®mþò»gðrKýmv^3–¼g¬öŒ{4øµúº~v2¼¿ðDç}^$/|xõkxª Ú-ýÖÝÕ‰—eÏNèébÇ51q›\Z>QX^Æ¢`«µÅ1/uáu$ ˜q„‘ç!±+Vîâdó–þM;nìVºyÉ) ¦åÉ‹—‡÷Y>?f«ñ¾Ö®};»woKµ´Š‚¤-çMMÂ*ЩD·Uòpvœ±7ÚÊ9Ôv¹À<,+Ú.s 'Ôë÷ò v!( 'mÔ r$ &ÃH@^÷^òB¨€s„‘§ÿ¬TÎ#èÅ¢¡ `IðJÙ=-ß›€½ vA‘VVGoæ¬C(úeïÓèV Ï#aæ+rÆß¸­oó}wlîÚÕý¤¡¯‚kÏ‚ï½3³ãACts÷‚,™˜:|˜V%ÎØì©‹µåµ]JˆS5\Í´5ƒÚ`+ì>F('ÌkSsu‹ÚÄ[N3¨KØ›˜¸þƒoU¡×!LL'7<­„Þqkg]oºÏ=þ7\KvµüŽ×'ôU#ƒßø­ãèCÇ?ž¯‹±-gÎ7y±á®3Pÿà£âŸ´|;þDe³&Ç¥ÙebÙZ®øäOå&iݾβôùƒ™3cvE‡aY@öx¶Þháê6\¬(B@|rý–U½uœ{îÂ+¯M¼tœ:Dò+ñÞÖuï¹ÕrÌÊ\Ú©™Ë—ÇgŽœ[<>˜½8%ø•†m«¡€Š£ó¥ñ%OdX¹Ò ø*´"(}RÈ'(µ»T#º)…üþ–„T‘$¸ò‹3FtÛ©™nÍ4s¯^ 2Æ,÷ê”3Æ=A—¯ÈüœqF˜ç޼ÞFÛe¶»’5aœq!dWž¦ ‚_ÙЋ0墄 m+’¿1]ÕÒ¾gsç5›Ã‰:€`ÛæåþYû¯§²y« ]¾©tzö¨c¹ñÖ¦ÒR¦<¿lWuˆP ±ŽÚ®S3¼÷˜ ‹Þ=‡ `Œ¹UƒZsˆ— gŽË÷†­ŸÇ:ü&3F©[3!„É.€áë³/[¶Þ šî>¢¶¬ú«ô;åñGFL]³Ýr4pì²túzy Ó}®pŸüýöwÅ•QËM¸c¯£œŒÒÜÐgÜŸˆN=Ï8«ÎgôtÑ*hœ­”"a¯Bƒs@m@ ”Ã~5¶LsøÜ‰ù“ƒT·¯yøÝ]«Ö5Õ·Â#àîå§¹¡éÌ™±Ñªa櫎fpBÕd$}f"¤/]Ýdñ62Àk­¹zn,‡|RÄO-wE:F™]Ö9ccN¨÷9ñºo¾7í•ÿA„1C„î-³€a±zõÔ‚à“EŸÂ9gŽë%w™K!+=dœ!Œ‘$ Û¥¿ê¸sÆ©KÙóåÿ{ÝPÿ¬™\B·+µÂÐ,ðÆë–ÄÁðâ½ÖLým—Ök'r ¸þòòŸr|rLúié,šá9rºŒú_ìO'&ì-FµÎ-f·]˜~å´«™œ±üè³H¨%åOŲ&«3i»T󺘯þ½Âu/Õ†YôËú²[žX 6':®Ûm¨Ÿ:3>G8ɦ§ž^>9Ì wÔ×oY%[3jó9m6‹dQް,1J¿"Û~bØÄ°½Éó[U$`A‘ˆé@¼ÂîêìoªÃ"¦ñúEˆ¡€]Ít5ÓÊW©åŠÅß9c#ŒÑ­rާlø¶C ›3&ø”ìã!F§Ôƒí qJ瀾¹¸*ãÔq9cX½9[MFVßvm 5yòa•~¤óÞ¾åÕöÅÀ¤fVZzWWR…Ùó—N^æ”ÉÑ µœêBÖ,TÝš)úU( F(1t#Äk®d”:eƒ9+’×2B Û;åP@óÇâì·• ¡[³UJôw„êÎçê»Tk-oïÙ}ÏîÞé—ȧþjñ··¹$ªˆùîûÉÍÒK p³«­Ÿ”x¦ågvm‡ò²½ÿÐ×`äÊáÎ×°µù\yri)J¬íŒv6Õoée„Ù2ÄcÑÛæ2s•# >Ù{Ή~5ØšŒv56o0J•—¿ô¿]Î_œœË°%ÙyÇŽºþ6A‘-M¯Ì,ã¥ÒØ¢]¨"Q ºÅ)³J5ˆ€ Êœ²+çO,ÇÛÎE¿¢ÄC¢_ñPGœqb¹€1(`ѧðDÄÕ «T3³e$ Aj“•€)e+Î8eİ¡7ž Øó™z˜W·€!„WÉèHÀ2Å4 IDATÎäò7Í#¸ZlOLÇÌU\Ëf;kvçÚ»Ã2VjÕêÌ¥ÁÜèL(UçOÅÚwo*LÌUæ3nÍ©uá`K‚Z®S3W°À Á^½”¦.!º’£Ïʼç?ÁÓÝÓ”h@ð)åÙåßz2ÚÖ´ó¦Û·«ŸÇ–óï —~oþÿ eEqšPæÎ }“˜. Å/-ÜuÃß ë˵±ryj¹pyÆ z«uá–ë×ׯ름VæÓœ°`KÒÈ–+S„»bD˜'â2ΡWW'†å=b]Ó2JŽUÖÂõ±U-þdÔW–Ãι‘-e§ò—gªSi«¨yHW/¡¼²J2 Ð;|?wâ9ãÄrÜšI-—:„9.ÄÈÌWkó9VdÀ˜kÚžRáI“‚O–B>j9NE÷PuF(Ãõ×;»œRâˆàª²òaIpj–«®H:ÞØ8ðÊm°(‹@ßÒÏ Î4så¡z]‘|þ-w4ð¤*.;dV4_4ëjÎÏÍ=ïOÅ”X(ÚÑd*Õ¹Œ¶œ‹~Õ“ØÅ€J-‡:®f.u5ƒÚ.@лRËuõ«ÄžÿÇÝ{‹‚kØÅ¡¹ÊÄR|MÛÆ»o]ݺÍÁ“צ/õ^8øô?-Ž[Žáh?ü‰¨¨ÈñžÖHK=¨WÇG/=öâ?ªþ ˆþT4waRŸÏIa¿¿1î¥=°"ÕÒÅòÄ¢ž.yÀubÚb@E¢B„ ®é˜Ù²«Û®fXŪ‡&DnÚ5¤Ž«-–OÖ–òùË3Þ)G–ÃCL‰®ië‹yj»bPA‚ð +ž=Z4àÜÌU¼vvê!#”:ÄѬû ôDàh&–9ðl›Þ·D.½ö/;\½iÇÛ°º†ÍãÜ“ë¡wÐ=å0¡à[loô ‰œsÆ]Ý.O/í?¼88Â4·ëöí‚,êÙbu!ÃC’ …ü³¯¨‰°ZÂ’ ú•âðœGÞãŒ{{.ÎøŠMˆ  ÊX]Ý¢¦C,Çû$ïoñŸàéŽ$APDïô4ìêï¾eG]kó¢¾pŠÌ,&jsÙ¶U«w¬»>â‹û¢1¨*ɰ€ˆˆEÖh‘–†çÏ_|åuš%HäHÀ­™¢*»š¹xä’ž)¦6ö Œª³™òØ"V$ˆ–/‘à‘ W(ó"ö©Ô!vY×Ó¥ÔÆî@c‘)•§—í²¦-äµÙ,gLPåúM½V5­[ìé$ã ³üòâÂùáùC C³Þ\dª$ 7š"9c³"Ä]ŽEA‰¡€™ãxƒ § b\éØ ÔÕ-UA•=UnÅT VC+°¡+'a3æÖLo31ö–®X=âg ‰1gŒ¿w!Äa¯q›cIð7İ,.ž©L-»2iX¿*ÒÖ0wäBö¤ ¨ñP´·ÙÈ•k‹ùÚR^ô«‚*[“ž$ÅBד’ˆå2Çõ^¶BbÚÔr €D¿LÊ\òŸçªêq“åpÀדC~-?òƒ'8a±`Ý ]7_ŸmlËfÕ— ­¯]-ïòešÙ²Zž\)§³ë×íJúëÍUkæ&FÎ>úTejp T,‹ŽfËqª¦ž)©ñô©Éˆ]ªy.E9!ødA‘b@A’1&†$!µ¹'±¶“XNöÂdîâ¤6›•j°9Ù{뮎-ë·n¼¡%ÙJ$Ü0Ô€¶PžŸËÏ院]®Ù%ÍkºówÎ9düŸ×L”yWX/*á¡L©ëªQ¿ˆzsªw™öœ!Ì!Ì!Ärˆay–êP€ Æ¢WXɇBÁkp÷øMSJñ:à½~€£‹øê@ÂŒSBÞò1‚ÀË¡zß­òwß¾ƒs®-æŽ_ô'¢Ñžf_*ª/*³êA#=MÔvÍ0se×°½¥„3F]Ê]JlBÈÂ(…±*QÓe.aŒVtÉßx!A‘¡H8eùÁéÚbþæw?ônv[ïÏ@äs9ËúƒÁ?¯¦FÏ/5òVæ[sé cİ©ãÜÖß¼e ¥îôÁ³NÕ‚>m.KmW ûc«[êÖu ŠTž\JŸ!¦CmË"ñt­Íà "È\j5jÑï”x(Ø”HôuVæÒ•éôÚwï]Õ¿©Oî]]hlÍDün€ é”0ÒO;°䙃ùÁ·fúRQ¯îÔÕ-¬ˆ‚r…²Ëɮ怭4(AÀ¡÷¼w5"d媎f0—pâÕÎx…’à“å°Ÿ¹ÄÌUF¢OZYÍRÆù å”v&Ç[¡]‹Ø³^ݶҫ5Æ9}ë~¼JCFàÜ®è…ÁY·f©ñp¤£>ДÉ*kµt0®ÆÃ‰õ]v©¦g‹VQ£– —#~5æœS›0B8aŒRj»D·©K˜¸ÒtB]Âl‰+¢·z3ÙÂß‹˜wsH ÛúÐÝ·m¾×c±ð)C‹;Gþ.t°yèØ™WJ“Ë‘J¢Mj히¤x"öÑ~u ¢F _Nfžj¼ÕèKr'‰éËý2’æŠ`¸½>±¶ÓÕ-=S,-hsYG3½!s°WFîh¦¨ÊAµ.$ø%èo½ó¦?øÉ5Ë­­[þSUj­pj]áéø‘ OžØ²4¶@,+R°%¡Ä‚+ëÆ¦xytÁëÜsk–÷Þÿ…C<àŠXM„½âvbÚXEòPdÞðí‰qb@‘‚~_cÌ.éÄv®øoA±rwdÿ|•d”HùåNP$JVôu(`È9à +/Ÿ«þá_ýP÷Vr”¯ Q„rÆ|Éhëµë”Ppþä%¡/ 6'+SKK'†°,…Z“ÁæD¸5e•kVI«-ˆ¥y Ä@L‡˜6u(gž¼²‡ö ›Ì!®§´"|“šéh!ÒÑLÁ¯šêÖ¼sÏΛïl.ÖOl.ÛxæÌàáÚl¥7¶ù¡ßÞi²ç«îîW´Ê§ƒA‹p©z¹A„lýOÜ÷•}‡>öé¯þ›éçOzØ|,Kv©–93ín¬ßУÆÂùÑ™ÚbžSÎ)ó@Xåha d.‘bùMeEõûƒ2’/—®[â[в¾8xêØòãSÅé…`s²eóšë>ø@cww(^'}²J­Yš›9q~Ì=’¿0éjæ/,¼]±Ä Pâ!}LðËRاD‚¾ú¨ô]iæðôJÃÈ”ôt‘X6Â˧”˜g¬¤¯ô&`äA>¼BY$ B `F©ç6Y9î˜_%ÜCc„(tÉ›ÀêB\ÙpAŒ¤ Oð+J,jMÆ»ZüÑ,saÜÈW€Ôº°àWÜš©gJtμ+“,†;ëÌ%Är‰í¸šÁ|²§«z\N˜kÚnÍä„"‹APÎ(ÐËÿ†+3X^¹3éÅòàå“«‡rÙ¥ºöæwßÕìki¤ÉöŸ‘†ÑWôûJÔí‘|óPxù`O-Ž#5Ü’©‚mÜn‰nrUGrc÷Ì §œŠŽ$¹4ÜÙÐzýúhGcij©0¾`*œ2%ýŠ]®Ëƒª JÞ¼+(’¿>¦DX‘â]-ë`¯ž~êÂ/–Æ%EŽ··Dƒñ{ïØ´3o +QLÁÒÌjI/NÅu-«ªë™Ä0М°‹šY¨RÇ}£#Ås¨CŒ<˜ˆ¡WFt[ (‚,RÛµŠUïö‰eÑߪ‘)™ù*¬pæÊ<Á¶R¶çñ¬!Æ ¯6Ì[sÆ¨íººbìǽÍ1|sC gÀkDHðÉæº@S‘+ÏŸ”ýªò­ºíš†Æv`­XZœ_|2DH,›Ú®™¯zE?÷Òãžœ ¡÷ªAIAF(3FÈŠéßÃéþ6_U„€#WÎα@$Ò¼¹¿­©·×Y–ñÚÄ‹Ëöðª;×Wö¿q„œ™8™6_¶Îi¡æU|(r}Mù~eAEŸì¶7¼ÊÑ@°±.ÞÕLwùìhy|ÑÈ–= @€EìTt3/cQðšÌ¼u\Nà aÜ]}ÝÆ®ún_lRŒT>uÕº‡i¤ÍÛs“F†Oýdyv™XŽ Bé"g É¢ ÚeýçzU½Üt§” ø$‰Ô¥®aeN2—:5“šŽç`Ã’ }RÈ·2“8.` ‰@pîé^Õ#Œ: žbI€º¦å=>E¿âŸ½r¯óÈK?½yrËŠ×H¼Ë–„@S]ÛÎõ]«×u5¬ÖKå’¯ Dššü½~²Å™J]¾|2=5U+”Ä€*(b¸£9ĵœ»µK¼oF™£D·„Œ×°L‰ŠQ ú<¹Ö.jäß îþ¶€1–‚j¤µ¾uã@0=|üòc¯„ãáîµûdûöÐ˧væÞ=£•ŽÓ3j¼^ÍEו¼ç†mY>ˆ^¼:û±K^^JZùjîò4±ìÊ\¦:›!¦ƒ%‘˜Ž7X{žW3 ‚vÅ ¶lI`It «<Ÿ6jZ¿ØwÍ÷„¶ç.UóîdBÇ—îE—ZÇ~vþ'ã'O§ÏyFEÀ€ ‰¾h«²£Ì¥Ôq½×.V%Á¿N={½^ÅĨaS¤*€5¢Ž«-ç£×°ÌB¥¶\ôŠ2±"bI`ªÌu5ƒ˜6ç¹äŸAeœ{¼U$ H¤ Š}2Ñ-ê(‰‚²Ò¥ã]ûÿ§ËKŒ2Q–"ÝýïÞÓ³m3cì’ù:i·åhÐ*T²g'¼Æ"!’9ËA‰I‚?ea6‰ª§>»¡é¹¸ä7¤Ó'Ïe8 nÛ¹nßïÿþªRcû¬Zß§QØÉåÒÙÐØÅËÇ–†Ææ^(Î[¥ÚÏÕs¼-¬çVwªº±\ë»·ôuoÝ$€U½œK/XZQJlG/”|974½tlHPeFˆ‘.3B!D])zÃT@‚D,ÕPg½èWJ­¶X0óV£+÷cŒVà•Þ@ÿæI0O³Ga¨Ö…”H ´œyõhnhzË=·÷lÝÚÑ»vò¨Ä_º\vË VC©ºÕÉ«vn¯T ¹……ò|ZÏ—lM7òe§f0Æ„v¹F  XPe$ NÕð®ï€¸ È^ ýìV¡xzkVø·-¼G •EÁÊWD ½+¿y]éðws-¶£º+õí`¶$è×C²ÛúÐc‡z>òâÚݱ±æÔÁ´œ|¦>R}ý¸5rãS-·ì‡?@ãu\j¹Ì!X"=ýî¹î=ï^ç[‡\Ž×]:xȶŒ‚åPÇ¥–ãYJDŸ²óq¨çW¢@C|÷»ÞµSÚºŒ gož‘UÜCéÞ´å»aúžÏ¬»Ÿnú¬/Ú}(²ï‡ª0¬^Þ€¿qŸsym¥_D}ñÂ@oI© Ÿœ>>b•7>‘VÎ9ã¢*˱ #tîÕsF¶œ¹0ŽÆ²@gų̀S3(*±`¸5åKE q9З Ôó ˜£ B€eb¼¢“ðb t*†™­8Uƒ¹„9y 5o;‹ieÝCÞŠ&É8£Ì­Yµ¥Âä‹'ô=-Û×öÝ|ÝiƒújU7 â]]À&˜ZSn«…Ý¢XÉ,¤—ÊózÐq%JmW”hÀ1L£1KU«Rs4‹‚kZNÕ &%†%¨’¿!†®D¿­¢†4aôs|?Ï„”½¥±þí¼ªúëc[?üŽÛÞ{ý÷”ïåУëoúÛkR½«î}^¸qßüê 3½mÅ’||„®µ…OúºuG†jÀYµÜÞ±On¾™×*SVÙ*רK¨K¬Bµ8¾pþåWgýÚzú;º\‘ŽéhPB°î´º<3Úh^¬Ü‘Ÿº}¢…ä#9p€¶>»eßi˜Âòü-•ü¾‹™¾S×ÍÏ$ŸÍ×¾ ÊÚs•åó#@@3Wa„x¹Ø7b•D¿‚˜öJI°"‡fK£ór$°Jš×0ãêµÝyÎåH Ô‘’‚>'`˜ùŠSÕ¯„dÀ# xJÆ)³kFm)__*ͺ†ÍÜ7|«+nôVÞÛ¤»3nª†¸[1ñ`†Ž\x°ù«8–œn™=“ø‡Mbú6´jL )K>ö¼ßF¥å¶À-]r[C”–À%vîvsßAgöÓ~ìèKsG/„;nùÄïÜ¡ï^ý¥%XÈÚzÒÊ·lî·Jš£V¾ê%¼¨g p.øˆ  nhÝvlj±B}‰JÉÚ@÷¾‰ý?x sÇLú_:1SÖ Ú÷_O팵nܺoáä oZܘÁT·ˆçK¹ŠUž>s±0»PšZ2óä’«¯`,‰J,ˆ‰sàjF 1.…|¹‹SF¦ä‹†| /rÛÔj’ªbG[’«:ÚvÙÅùÅ“_yB_*zW#S¾ªåAä]‡,‹Žf*ñP݆ÎPk’jdJJ4jKÉ‘€·¯-ÏÓ Šˆ$ øÍ”¯sÎB‚"cEJÝ@Ǧ{n»yaÃõG^°ÞóòÙÏæóû:û?öZKb[ª,^¿ãȦréÕüuÏßSz®!T[ÚÞyÓÒT*1V@{…Sk’=¸c0Ò|¾¥4«KõÂdÒ+¢[ª7Ϭ=·4=i놣|>'*J 1^™^öjÍ߸óVþ&wQ•oúÄÂ;ZöÝüwG˜r8yôÞÕýivíáÔšûÄù»?ñ òÐÅ`ì (—W }æ‰N°JBËCaº”ǰ޵.>¼iÏ…aÒ”ìÞÜZŽ˜¡Îu G¼¶´_Ë™ÅwÔß$n>¿£ïïi9&Šó/èËEda¯¼Îç‹BŒ¬‚&H"µˆ/ ²ê©Ï±Û¤RòOþ*^÷ß&zÂãfhŒnä-êoW_¹)w›Aö½XÇýp{ýPL-³¦l~㟽¾eõÿsÓŸ>œ[ýáô=óZ{\˜yòÈwOã©üÅ)ooÀЍ&"j<!ô­ëØðÞ;êͧNÌ¿xñÑŸµíÙ ‡‚‹ÇFËÓi) Ø]ðËáî¦äºÎHGcç-ÛdÕ‡$<{èüôó'­¢v‚<°°à“=ÿ  Ôoê ·¤ÌBµmóZ³X÷RvpÊ Ñ]»fo‡túbÓ†cµÝûêOÏ^sNë¾æ¶øhÓ·Æ?Í9Wë‚*©‰.HáΆMwݺ¶}Û¦Gáåξ6öÄ;þüðÁ %½ð;Érxà‚!cýüyíZqð¶u#µÍÛ^X{ËÍÒgÇ(ý© ™éÛÛöŠõ½f½oStÓjÜóÐ{?¹êºþñûÃ?zM›ËÎEŸélˆõ¶Èa?§|ÇÚ›üŽ0ØQûlS7=æGÏ’üº¹öO5ïT&üŠ£ª†­î:Ýï²—Ç÷4ô®Ý#çúӞߞѕ6£1ÌåŒaIèØ»õøØîó]jL1Ú¬6øò9<=v9¾ºÕÈ”*“ËHÀœ2ˆ ö¯X‘ÿ­³. )èó%#þÆ˜šŒ ŠÔ¿sçïlê>ýä臥GžúøÜû.<ä›üƒÏI¤pü;{'?ùSÃí<³8pí_'Öi=­±sƒ{üÿ‘Z¾6}.h.C%~¦î¾Ÿ†n.ë_zoÞá¸Ó‹ëûǺSÕS?Í®£‘åMíï{}“ø]ò_¾|ô椨ÈÁæ:}©àh&r #|E-‚ðÿ&õí9˜y²{`]CŽtú‹é/5O þŸúÎW滞|jóÈ+ÙÚÜšù¦°ý«‹-}igš·dnI2²¦ÑܵTz×ç«­hI¦¿÷±³÷%û›ØÏÀHY/î¾á®÷Œ=7wä?Öw©ç‹hõý´þÞ§SÏÌn÷ž~ï-S¯ž´ UêW·ànÍDb$¤ª‘`º¶]œÙTŸ¹ eF7w¾x +bÏL­+k¢Z2±õÔû«_)qgáÖØ´9}²õ‘™?"Ô½ã÷÷ÝtC2nw¡U/½ô{v`÷u}xSCs{÷Þ…Ñ9b:V¾,Ô@}œ8.‹°ÖN/6}'ä|ä¹ïvç1Þü_«7yç>@D¿mˆª[@7F²Í÷’#¿åŠŸ°3mmí7m±«zöÌ8–E$ Ìve$`)ä ¤â›§êÖÎý½)ćºn˜¯Ou,ÔueâÛƒ}£·Þð|ýO+3é«k$‰B×°~Ùq‡È»ÙÙŠ‘.ÇúZb±T23\üÓç§NýNbJÇoµÜôìÚÄ{/Åïøãlñ¥š²ÍÛÒü.mÁî³[¬ÇÖ—pq»eŸ¿1¦¾p&XÍÈZ#6RHãJ ëIê$twâ.wÔîð϶VO’—þxø³ j¶´­Ðq4èwj¦w#_¹ ‰‚gáFÑ·R¹ú6 3Ý„Ñìx«végîüþ=“Û4Z7°,õì>}mËbulm1wgËIa×Íù¢Ïˆyd>±Öé­Ýk¬ï™}hÝ´oR|­VŽãŸØùHû_m¸ÿ³óBjÉ'=ÿ-¤ÄµÆ /¸ýñ³ßþkîùpŸ9Èjéœ6—%¦#GüA»¬SÛ’2a¤è«Zí .â½h>ÕÞêïY·°uýtöùÒ…Óu¾Ec$7R;;WØà~TÞí7>ð¥Öèo-do~`âä®%§K{ñROõ™èfgÛÆÑÌùã{ñ¹†/çFg]`„`IðF`æ=WÖæ³‘ÖFÍ©¿¥¡7¿P™ŸšüáÙV‡øçý(u“ytïà¥JÏLlȾ-½{´ÿ}Ϻà}‰¿+¾²Ï\?ÙÜ|±¢ÓöTÈÚ°ãR—bY Æba‡T¯_Säª @ <å2†ÁU]Hdàˆ£MpÍ‚{ë+•‡ó¹ÝjÊ·åX8>(4ûö_ëLwã¶ Ôõ·UTI_.ºº¼,úu3™LºV«°+Ö¢J¥ÒÕÕë8¦eÞŸ$“©7;Ì@áœùûë¾üX wÚ ¦üÃ;cÑÃG{œÊÚ÷~õ©6‚œþ­s¥®¬Æë£n}´âÛR[:DÂAbäV×ñèÒ™Z5½ÓÝ0g&­¹®æÞëÆÌg›Žðç@IZ¿°eë×e{ç—ÕKbG_KýúžÙWN[i +–E$`ê¸zºxö›O/]íÛþñ«5¿ógÑÖ?Zu_KÓF(owC°3ÛM©fTÁTïGIÍ™+X^è?­'s¡yiauÝk-×8y´¦x Ø8=>yïÿ]ÿ‚Àÿä|ÛYϸÂÜG+¿ŠŽ =¯tÿŽM»K~Ý7Û×§º±¦Q‰¦ †´¯XŒ(Oja}ô܇Ž]zïíkJĽñü@‹šÛSµ¥‚§Q¬¬H:UÓÔj– $&öo+|ò’o¢E¸ wžÝ6jØŸoÃïu{Í¡Öך ¬/œ²Î¿ìñˆå2— >ÅC­·Õu÷ÿä¼ãbøÑ §Ó¹˜õU…Xãq|útÛËn¥ÙZ¥Vº•ô@Ci7B«¢LEŽnhsik2ç㲫C d&EcÁX#QL7w3˜’CF·$5;é²p¨,ðoθOŠàO|´ e†_9<þÔáÂåY¯‚œ3æ‚_ÛÓ½Z­†ÃAÇq®÷ª M©+Ÿ‡ü›ÕÝTú«ø—Öü¡¶óGùÅÙ5¹G;Ä”ÛR¹F¼ûH¹K ¤93]q a']1ø¢9&Tü*««ç©[ÿéôsŠ{û§{è¶-zêËŸ{üÌÞ3›?mªn|æßü‡Ä{´œ¾ç ?m«Ô¡WÔNÕp5X™WcÁýןúCw[sãø·ß!ùZª /¦Ú FýÖ醯×ÕŸªåz}aüHÝò±–Ή‰… •i’ë½eçûÑö&#,ú”œÙ–Øšž5MIµÀçoY“›ùáYm.Ë¥–S[*`Qp +—[Ìl¾iç¡©¿(¦Œ4´D”ñÆË£ù(f2¶)ZUSYÕч¥ÊâÔûïßþ÷©§;¬þSÒèÒðøJp‰ñ±^áÜ­™³'/VöÑæg§î’õo¬ë™àZ¬ºœ\ X¤ !y¹*/M,›ú˳ϜzpnÀ u ‹2‚ØÞyˆâå¥?™¾}:öÌ–HøÁZi½Ó~¨ù¹R'„âY Ï2Ž “ˆY©¸q='§'c˜# EI¦§* Pm„ˆ(DHX± Ô2SækpÌè¿~ ¸Õ)Žç„œj9ŒP¢HèJJë×rÜMÓ„på  EQÓÓñxÈqìr¹rõßþjÝ]ró÷N>cì¶åÍ{ŽÚ×\Öv óç_\Jvžøƒm‡´.õï—»7]® ~Yªail=>·‰¬í°’”Q)*F‹gœÝ½3‘w™»Æ¢0¸}^ º>ÓÍÚwß—Û#_­C©–5ÛÒJI,h¹êrNT¥•RΡœ, rÄhJìß,ÈÃïžµ„SM?õg_iz¡†òÂ’©Æ¨õm̆ߕ‰­_ª»uÁ m[ˆÝQ©¦ümŸ¹vH%î9зwinP[aS‡NÉþñþÂÙ'¿”œvª¦«[Ąš¹êLpžÞ<ñ̾ jOršè\º½ûGKÙ§SéIXcºŽŸ.—ÐÚ“`˄ݷ5?ôQ«û“†¤ÙèÙÔªíÎÅ"HÀ£=5Š~™A~¡ua­q¿oø™‘hg@0»¶<Õyöî·ÿòâ_¯~*ðÚþ¿üÖ‘Kf¾Jl!z3`F¨«™#f“´™>ó§wöíg`×_<÷?®9z y’õõe›®» œ”ç{„É.ó§|û%38h2¾R·0Ý&žjG= 1¦à $D••WÈ µ+º;œ­Í_PºËædoGª!Ï×—´î§^>ô¹—§µ…|m! d”1J9àoµlõ­]Us¹lCCƒ®×ªÕj ¸®«ë¦ë:Åb)O¼Yÿ…ˆýêúêÁCÂáÐlï³ï;:Z¬;¤ïC[è°å5¯êE¹í9׊Ţ›çÜÈÑÊn)ÌäíyØx©î²™M(ùµûþúÂ×$ª´víK$ŠPõ¨øc€+Ÿr;¿xÃȇbÝ›6.ÍN-¼~èµcE„‘(¬¾a×µóg¿·n#M‘@ý×Ô¾þ=Nô¨k‡ÍúùFºÔÕ6›‰^èaŠúaDä˔͞kóÉ›‰ÈF*ÅGtêÆÑÖöîiãÚõûží^³ÿëß_:v™¶]ªZ®[÷к÷]{äÜë›ø]ÁÇý±Yò`£Sm5:j°‰Ï.7ÙéÖdBÍmɸJóާyéžñ½×”#‹€qAWبy° /ÇèØóÀƒ7M´±ˆªm¸ÍOä+ß¼f<ĵW”$1¨Ûµ+5æR5V} –EW·Ÿß~cµHuuFÝy)ÐkÉš¡fEÅjBÌ–[/HGåxAPË‚P` q 1 2pŽ˜ 8„" 1Q sK¬4âñ_¨G6Qµ5õ®Öž½;fŽž'–kfËžÍÛ»ªzÜ”_×q·m›:;;ï÷û¯þa¡·m‡òæ…PNáдsÑnžM˜ñÆ'×N?>ðíhx¹)h¤ÑT!¡x ˜xQ§%MX´Ç ËDB"ºÞ•ÎÎÛ§Ot?ÁŸÝðdÃÆµÄ*H'ŸÓF>6: =Ò|bÎíoþö¦÷>ˆ^¾ýu¥¡õ6ÿG¤‘3§ÊSKF¶Ì(s5“˜¶™«T2YÚ\Ÿ ›.¿vÃy©.ìk®IÍœjÏÑïH1Çz¨ÊE¢p¿\UCK8'*̤ ºPÂò÷Ñ–Wá·r—§ET™ºÄ*jV¡éhèUzÖŸz½úÛOW‹·„ÚfÄPèÇ•ëáTIËy¾gë]Ñ`ÝÜå¡Z¶p4C_Ì{±]$ XˆíR¯õ‰RYêQ§‘ˆ¡€|ÉH§ÙäoûÆó…mC‡ïWÇòÁ-/÷Ô?oPÇëiSŠ®’>f×Ó¢ÿXD}–á¼ [Ð_æë% ©™C ƒ.Ž ‰ ”92Zƒ™(¯ËފjЩ¸º%9¾â5I³/†‰ÚÚ¹*’HÖv––Ï.¹ì¹&9¿G¤ª*;w‹sZ[[E`ŒJ577¯¼OEéM_UÁã]Fçæ Ý™-Ó§°žw·í§µÊÀ†±¶Ö\°1SK(#JÝQ^§äý›Êj2ç‹Í ê¬è¯!¡À0¡8)‚û;f»Å.KM~>Þ¸Lls£K,§¬CïŸXSò'k"^º{ìÄW:׿ãÞÿùwÑϽ¶&_;Q™7²ef»Ìu‰é,œ:нû(³üŽu™Ç7þ*¹¶Ó ¥µ-ùmÉRƒ?ï—²†;ž&5Dç±:b/ŸÁ@wMGmö!UÔç2b}K`ûM þ»Þ±Œ¥ϵÝ} ç'ç̀ɑ€¯>ªeòû·_7Ý÷‡Ò1Öó š!.(v :«¹gubAÈá±"Mÿ¾4wÃÜ7¶)ÃX;Ó¼ýùkÝlþÙ=K¹YޏS39ãP·€EŸâhúHþòdgo¢T/¶/¹s½n©Wì]Ç¿Ûl©Oß°ýKï̾gïÓ¿×ÿâÁÇ•n¯Ç’P™w4{¾3ÛªÄÅ’èg½ ³]æ4Λ嘂ÑÌn}$øø½M'‚‰Yœà$¹¬%æ2e¹ ‰Y¼‡óõŒ•¤XP±!ŽAâP\LA v0ÔÔAhF1­Ø¢‹*‚ŠVBôtÿæÄ-‹¿ŸÜP&³£—Ï•jöì„S3½¤Ë[³&ž·Î5:ÜÉÎ~òÚß½r¸£¦Y:uêÜÎ;±ßšý áp¸ùW¼%˜ýõ‰Ôr!Çr]:cgÂŬñl{•ÇôF¤Ç© ÔÌŠf”«ÄvˆaÓ¶«† ÊŒP„± JÁƺHCÊ'°("CŒ´rѪéJ8UcMm™þ]óM¿UŒ%™æÚXÿ³¥ÃÇž|º2³lfËÔ!^®Ë"–ÄÄú®žë¶6wô*Ù#_þAybIðÉŠÆëv ÛŽbYD{zs uV@‡€qˆ’D%ˆô4I_u>£/¼Q %_ÓæKD˜K ‡®fÉ_qfÑ*jÔr8ç^E€PôÉB9èó§b©¶ö6ÚØe×û-Äê|Ööȼ?{æé¦_:åê6ÄÐëÞÁ’ GᎆŽk6¶Õ÷ .™ 7è·X¸ß]ã0_Wk—/|ñ……#—Ä€¢Dƒf¡ZJëé¢á@öØÂÌ%Œ’¹Äc!y±½ö7íØuKÛe7pã„Ô—â°•:‚ ë|FÜ— Ê%(2W5¿[–¸&Ú5Q«aË@ÀÔ‡L éÚ2Ì$  ÀEc…I2!W‰]­:ร2ÛÀn&X´Bsuåywq)=³88²ptP›Ë©í:Uý*°í3ŸùÌ#<²2-3Z©,xÿ|Yœ=ãžs çðÿ:üö¬™ŒŠññÕòê~¼F$ $Cé9Î|Å\%‹œ2/þ#…ýX–UB¢@m7wy&}zÔcÖAŒ<48–Å«‹7ѯð€~Œ®–$z… ëXŽóž^éS£¹KSXˆiÛeQJ‹¡w¯bKüßí{lTUÇç>çÝ™éô1¥/ZQhki1Ênº»6®º€¸®Dd««kÄY“&˜¬Æ?ؤـ›”DWȺwCÀU"‚ˆyäÑÒçôÝN;ÎÌ}{÷3´¥´#--<ŸÌí½çÎ=ùïÜ9çÌïÁ±Ä•Ü0 FàAœÅİ VT-*cI ·ö†š»‡|!Y‘×16t &õ*¡X´«ŸT,#B×LülIÞ$53t#¤t÷Ö66£3çÝvPÃQë̇ñq×UL>«ŒÈ³gè†40(®öÕ6žÄ:©²F~yŇÄ2¼Å„Ž7‹ê`LJ†¦ó6ñ+$)œ ñ\êÈÀ˜” Œç@ˆá„P¬'p铯.WÑb ~_!‘àÄ)ˆ³ˆ‚Ý ³VÃÎ,ŠIV†cA7 ÃVNàÇ’ÚzœÈ#–ÕUME°ª‰v‹ar("õ…°†Y#娃8‹Hœ&Hø9 q&~ùôîŒÜEQ|¹¼|TÔ-ó ÏÅ÷L®e ÕÙBˆá¬"ÉD·XVI®"ZF¼‹‡è31H×tRhE×t AŠaDä.ä›’S$ö‡drÖI:Rú"Þ%¬ëX'=aD‘j’1eèmG.õBˆcYÃ’‚UŒ°& %D*Ç—ž Ëè'sÄ[Í`XÑ ^ âQ×:Ï ÷‹Ÿ­|Ê“š1ªMEÅŸ©M)÷‚Ü=©Þ²_ýöÈÿ>ýã³e?_½ö7ϽLŽcŒ+*Þ9~üäGý‹”rÈe¹ßýá­M¯oUdiμ™kqà,ËnÛövIIц ÏPƒRf2Ø™aa·°å¯¿Åè‘uÏm4ñ:3¢xhF†—Z“rïȽð¬küuëŸ"€aŸëÍ›_ Ö¤Ü;rw»ËÔd”…ÜoÃ0$)D-K¹ƒŒ¬á<Ýr×c±jqÊâé>D}}ÃéÓçXvxó')É)Ë’Éd¡v§L ’åy!žMð¼ðØc%.—óvË=“›ÕjE‰¢˜––60Ð4œŸŸ¯(*Ê-ÒÞÞÁ²¯7=‰ôööH’nw²ÓéÏ7xz="bÌf³Ûí6›MªªƒŽTUÊÕA¡L¿¿ÏíöèºÆ0FVVf4*õôt'Ž e¦µC™™Ù^ŽcTU¡ÃC™>Eæ8”““38½3sw¨¯¿âv»\.gR’ƒ ešöý@ÐétOÜÁ6jÇï÷;æ—n¿¿ßïïoõ@¡Ü"ýý½½~Aà9Ž~jänºª^÷MqéÒÅ¢¢Å .±Ùìv»ü­iZ088{vnKK[OO$Ê-"IRVVnGG7ÆFjj*9h±X§w2£iÚ¾}ûŸ~ú×°{÷¿×­{ŠD¢'Nœ6™HÎ(àyeÙ–'ʨ ’¢k;ö-BHUM‹ÇÙq÷ä“«ÒÓS§KîºnÔÕ]ýî»399Y—/× WU5f&=ÝË0¨¯¯ŸîÉPF‹¡eËŠûúz'qm]]ýÂ… }¾Y–ý~¿®ë^oFR’sÚ—ªõõ c®G½Þ ‹Å  ©©ÉëM£LÅà`¸££m655Ȳ„ÊÎÎ![ï ˜‚H–e8Ž3™L_ýí¬Y×Å7=ôÐbŒ5¢u eú0 # +Šš¸Ù„^kkÏ_w1Ç˲/½ôû¤$‡$É£6ù/^¼‹I.—Óá°Ó!¡L«ÜÃáÁÎή©‘»ÙÌ-óÙd´XÌ7¬e‹Å‡@JŠg!6vQ­ydñâ…qx{P×uÃÀ‰äncŒ€nW· ºAI™ŒnV%UÑã¡Xź®bÌMxîîpd0 {{:­ir8ÜE2QK¿ê’ä¸b†Éxâwªœ…2rgW–Lè’ÉûÌ´··¿úê«·ÒÝ]»vµµµÑa›‰J,<Ý+šâhz–åÁ6òš†$iÜ Ï††¦}ûö nå¦ã>Ý@8nll€åË—3 SSS …†Y¾|yggç† ÆßÈÑ£GÀår-X° ¡¡!äóùRSSçÍ›FO:ápcº¯?#§ÅÜÊó}âPž‰ƒ0–1vêêêê@FyŽ˜`Û[[Û›/^8y¹7·6·Ôµ`˜qä‰óçÏðÁk×®€ªªª‚‚‚K—.¥¥¥©ªº{÷î’’’õë××××ù¦UUU$º¤µµUÅíÛ·ÏŸ??;;»¦¦†çùƒæååÀþýûW¯^Mµuׯ>üpOGG'¼òÊKW¯6¦§§æåå~üñ'ë×?ýŇC¡pmí»Ý¾iÓóãÊÊhšêñ$¿ð›Íz“wÙ±£J’¤þþÒÒâ²²))žÜÜ졳‡}äÈ1X³fUfæ¬sçjËÊV>üõܹ÷gd\·ù(¤Žó:ÖÍ&3—›‹½X3´hýà¨û­]»vÕªUðæ›oº\®‚‚‚âââH$òÞ{ï­[·.AG ª«« ///??ßf³•——Àž={‚Á Ïç#³ ææf*»‘³gÏåæf“°µºº«]]ÝÄ;ðÊ•zhiñy<ÉÛ¶½ÝÔÔ²oßþžžÞ7ÞxÙjµöõùýþþ›—ûñã'þö·wÝnWEÅ;ee+F-)ydÉ’Eðî»Û7mzÞçk€¶¶ŽììÑ5}î¤Å.Æ ¶9èÖºCékïÙ?½+TVV®\¹röìÙÁ`ðý÷߀C‡>|x¼öŸþùO;´lÙÉ– c‰OJʤûî?f0F§OŸyD×ââ¥Cÿvw÷Äbäæfwttƒa‡Ã¶sç®mÛޅ‹™ã8UÕ$I²Ûm-->Ã0DQðz‡gÕ Ã]ºt%¡2&ÎéLr:“âÓY®©©miiÍÊÊÌÌ̘ðFd4êOœko ÑuêApw“œì~ãW¦üm_|ñù›l)ŠâÆn¦e"` 僡& P¹S(÷ ÓÖÍ_à›Çl$‡¥$«Sbh ÊLD HN·SÒÇÖg‚cÈÝUà:«ž󂶺¶‡ç<Üaî –¥Ì@Úη=ZÔ®µßÔÓ]‰*Š‘¨ÜV°Žu%JKPf"º¦kЦH‰ôIÔË5·6SýòCÕ5pnö5SËRf &ÑéŒtötþ`Ëÿ°,l7~IEND®B`‚snd-16.1/pix/100twice.png0000644000076400007640000001424611545200464013205 0ustar bilbil‰PNG  IHDR½,€C4sRGB®Îé pHYs  šœtIMEÛ7›H8IDATxÚíÝÁ–£(Ð0§þÿ—™EºÓ–¢‚¢¹÷Ì¢§õICŒñýg€Ü r3ÈÍ 7€ÜÜS!„ðþ‡]À ~jBêòÓÑë>_Ø4¤Ý¾©V ×äæe®ÖÂç Ó¯FÞSÀU6÷Ó(DÞcMð¾©àN¹y(27#æf}*›ïGc3ÃåfÍÈÍÀáÜœllž=–—üÎç%›¦€¡üœ~‚ëãᄅà*·lë]6`Û‘t¥3ÈÍ 7€Ü r3ÈÍ 7€Ü|Fn@n¹äæ3Í^» r3ÈÍ 7€Ü r3ÈÍ€Ü r3ÈÍ 7€Ü r3ÈÍ€Ü r3ÈÍ 7€ÜÜJŒÑþà?·(eÁ®@n^1kZ£8™þÍ 7€Ü r3ÈÍ 7€Ü ró­xk r3ÈÍ 7€Ü róÝ„ìKäf›@n¹äf@n¹äf›@n¹äf›¹äf›@n¹äf›@nÊ~†-YÁî@n^c©„~ 7€Ü r3ÈÍ 7€Ü<–ˆu 7€Ü r3ÈÍ 7)„`w 7€ÜÜZA 4r3ÈÍ 7÷Bˆ1ÆuÕ ‰Ÿ§®˜Ä @Cúi€Ü r3ÈÍ 7÷c´ƒ›…fäæF H€Ü,( 7€Ü ró¸tä@n›[$fCÔ 7WEç—&gäf›àl?·(e¹OE¯×+¾^‰ïÄCø3õî^ÍŸ…æ°ü˾y–'¯,öòkÇg¾:‡Ê-pprÓV®`§~ì›V*ù̓5êHõËI;öѦ…>陂&ç“BÅ®Ÿyåqºû0o»ÅVWmSyVûÙÕTéÝGЙõyëé±y9{Ô¢“ë^ÃÂw*ùù‡êꉨßÞ)\O;¸Ž¬ã=Ú›ão¹oUþ½0“ðIÙ©Sðû“éæ>ØGºfòòw>ŸNÿ±Z¶Êb·ê¾º ³—·pýFëу}¹Á·®þ{};Õ¨Ê3Åì¿ÕlëB·N8ìÓ« ¡Á¡wæ¶ê½©§µ®°¸Mu,W“7Ué÷WËÓêgò æ>íz±ä0ß}Z»éúN Â¶Si—×»ÊSÄ8çÌgöÓ(Äâòÿ.'œÝ5¹+j^->ek’Nj’AMÎÛ”,g«PÞ¶§]­²Br›¼?Ýz×{0dߢݷßmÏ9gÞš@–»\ÕïÙšEílýáèÂSë²YaÇíYÛËÐ-î=ÊAvG'“w×#ñäJ>›ÿòŠ?~£Øë1íÍ“óHHÕ³0l™žÙË­›[£L͑ӪÉ'7Ÿ#‡P#?׊|~I^Ý:ØÕ×®ú+Ó¦j|‹Ÿ†Úqv}“q¤óëø—›3·u¡grß²Zud?áìW?“B³ñ€Ç{á ûø·\YÁ‡õÓˆ‡7ȩ·ÐpÈçk-¶Ü‡¬íјüÚß<z׉#§¶Þ1½“è%WýﯺËßñΚóÛ¢v½iµ.ç4äúý†øat}0”¶^¿³S×úy|#omsŸyp=?7×5³…\€®~nž+#uê&> uÂá\äYÀq†Ô ÇA}þ›ÛN[ÁsÞw u÷¥Äá°=©îÙßïls°’Ÿÿèê%ïI¹9¼2£aT¤Ø˜; >›wï€Ô´¡&ÁçZ© }BzWÄ Û{îu†½i#úÖÄp~‹þàÃÑIÆ×ÖðÝ?}Cv<¸ŽGö¬<ŠÛ†¶§¬ãþ{ÞÎÛÚÝâýŠÀʱŸ§íÊ¿3îJbN6ig†‹.½$<Ùñ#7L^.mF¤ž%øÙÆÁ þçî&£M5ŸsÃwÂ|÷ªÓÜà7Tßì3ò+j‡= œó‘Ê'U¾wæÚã¥m™G¾‚ì.Û˜+5àè®ã< õäܼ£wrŒñ“`Û —8ׯxå¿$×q6ÜÇr&Óf#RÿýûzI–A¼ÐóÓnn)/|ôì\Þª/Ý…óámÒ9=†û½Þ¯a§×Á–°½¯î.ÇøŽõ€v÷Kz—Ý=§Žyô¿y½©xãÜBnníúQÄYœ ®wpÕq÷fK™´^—’ýÚEîÑÉ•þ*™kvØÑËeõ£Lcá¶›¶/žlxr©¯ò›žå ¹ï>ýÚÁÇ<–G+Õî'¤›ßfŒîíZ“P¹ùÏ>}•~-йÔXn^ ¾Ë,õû‘ÄY»Ðˆ^ˆõŸt[ž*ÙË¥Ðæý»Ä¾›ú5!ß\_Ó©}¹ ŠŸ’ËZ¹ë¨/^¹$¹Ƹ>€ã‘›Ÿ&w8•]{1kÛ‘cß;ŸÇ¿@–»E5|ÎÉ­ækà§xï{k4ÎÛï5þÆ?w?ëÆŽç¼Ï¯° ­e¨dë§)ü÷ƒGÿþwc¬-Ÿeœ.(ó`eø—m‡ÂrQ!„Ϧèï-?ZL“<9ÃÙ?f JnÞi–ÛaZ†É`)a6Õô£erqÿ5yPuV¼iß›eÉ?;¹R‹õ‹[ˆå ÃòNãSŒÏÜR7Ka:·Ù §sx¥zÍjÚt¹Ó&‹·Ü¹ËjvÁ«¢ Óä³;Õù–ŒqÚP>Èäþ!}7›*I\n¥EɧGñú›œál Ï§³ýž\ßäÌ´\Ù˜¬`k›h}ªÅžJo¢Ô¿^†Ù³ú]+BjO­ìŽÊºW¿G Ͷôð™ÇC¾9,rŒ;>úoyÔÏvnMj,/Ù'³¦ù/×39Ã{ƒO·v]ÉCæY¯W±Ïg\]ßäT z¼á}Ö´..û ÍÞ»óéEð®©>Fÿ®Ù‹OÃê™Zn(ï³EX|MYÎ-·¦Ë!Dr•>¹MfÉUÄÙVZ&Ýå¾Ho¶;2›bÛÉ}º L•x/(ì¾Z¤¶Ò¯¿O»©ä˰íŠUÞ€™’dÓ~ö£B€H^×+~FX.+¦öEan¥z¾¬Ï¹©rïEmÙšçbrüáJá§_XFÅß “”vÓl+åªeùÀù5‹p2e[~úï É'.r7!…Ú>›áò^ty#4ÙÂé*4;¥FÈÝpÎf¾¼.Ÿôs(|”þíqùµÌTÓøúËMõ9ÿç‹·g‹%‹—Ù×ËZúJ6¦,ˆÏ¹ú÷•1,¯&Ë“üì ?ŸÄêãë×5·p,/jEâüù{`ƒª»¬å)eãEaåÔZ>Ê6^ˆsSÍla÷•gX‘¦×—gçæTBÍë•|¹ïV/¹³—¥*¬Eýwj–X˜yyøÆÂj¶üñ-|díš/¨ð÷~‹«ßþ» sduŽï‹š¥¯Ôå#t÷ÞY]ÕÂ7Ù •jë¶Nž[÷\d|mïØ¶¼˜%/ù«÷¢57Zû–UwW+Ôª «·LÕ)×1oiª\PòŽ.Óbõ§'õƒIúqšÔOL1¹ iá÷$19ÿrâÿ}Ô„e“ÊÚíS¶~&ïè’­lÓܼu³TlÌÄfIîšß7?ÙûÀd—Ñüï*¹f‘˜Ì͹f‘Âï ;ró£ú7_û¼ê‘š¼Xû„¹åG®‡mçðå#g¬Z“ÚÑWmÞË=u0]Dù9ã­}ŠØñQeáWg8{;5«îë»Z†òÜÊSÍ>Ì-+?³×dV1×}+YÀäÝÔ'„žÚô˜Ðlªdñ–}ü^éW~…³Ü£kM+×rûL¶sbe3“WUžr16-hc{èÎíSyŠª¿X–ùÀç †*ó¹¾>{ëÕ·¹ö¨É»ç|ë¡nQøÉ3÷Ø2­ùºÅ©`ü*T(áUƒ¯Ù}©Úµùþ¡øéJâÏ߯¼Ê·Ëû„äõ#Mmà5—ø_ùîLɧº“ÍÆ5ÅH&þšÑuëÓvÃŽ•PžpµþOcô@?È…dÌñ˜Î)ÏMïŽ?g½õ «ÃnÿÞµ÷ÌÒo\‹A0æ(… þà6ˆÁÇ©þÝx%ˆ3ú†©rI½œ)scä&/|TþÚ$ƒ®0;ëtTÓ_¨Ð:“æcù~¬°Kë+ƒÜü¨³Ï¾3Bó|Yò+AÛ_KÚ¶6v \øËRïwÔöê“«bèµ-©]Ot—Üùp£Ë\“ì^žp_O‰Ù@@¯ô_•8Ô‡Ú®qbÖm]n®­úö¦œß X7Øß'nï›Hü¿ žîu+²¯$#?€ÑõØ©/Û…o÷áDzòÚíX…3O˜W=e‘x&×Ëåß§•ù»ƒ =Ñ·ÏjÃ$mG"þÞÜ\èäwù@â—¼M ¼Ð0µ¡¶–[ÇâÞ»¯ÓÚ…ßjÜÂÝåøìßÇúýjñŒ¦¥ƒ“ í9³ë]Yå[áR'Ƹ}Y«‘:v«9¡f{Þ;7¯F½“¹#$v=¥žs¦~gëš± μrtmïwåØšÃ¦«9xcóɹ!w‡\_Œ;¶/rzHëÆ½–uÂf¯\D“_)/ïsÚölXVg•;T÷•a°ö£XˆÚ…71×äÚ×α;Âñcê¾¹9î¨ôtHºG‹Èc2Ó9;®ßJMsðÃ6Úc\8–ÜÖÚxNSâMû=ìæ°ß|ÊCtS€å©¿“Ì¥ˆæítßù`èkm(•WjüÁBó곉Ó赫öâ7öÓ(ÔÈæOÈÕ—áL“m~a\Ƚ€ãüì{Újèç¯oïßÝ¿ {wq¼Hçœ78¹öûõ!{ëÌ¿¶2·»Ü¬²úéÖB˜¾±fÕŒ§ñ]ž—0óVŽV[ã`óçÁ_ ûíß#wžwï|ÜüúÝvøç×HšžõËjø³þ]kzëÑé ‡kŸJ?ÿˆ¸Ý°}›¢s}St§¾ê±¹¹~ˆdòüÐmû“Ðøix„³áß5µÕï(5ò8hm;!\Õ窾Çä€Qìv ®GD§ß;¦šÜ²Þeì„ßo9MïÁææšà{ßyùX÷½‰ºÝ+÷fð“ªè²‡âù»¸ÇUÖ¢&÷í«-…ç?Ñ{÷ÓÎi+uüéÕM÷½#œ ÅnU¼òVí4JOÍÌ·ö>^/ì²8y’0.F)=M8{ b«q‡õÓ8/ITî˜ïyšê°÷ŠèÔ~ßÍÛ$kÞ±KIÃ2û ^a/7yš¥_=ìú`ß9•§0HÎÖñ+zןÝÃH‡pcœpÊ/{©©€5£mÜ77Ç× ô»LÖLØõÖö’ÓwÛÙnZ»æWŽ'uiÒ¤´ãqõæµku§Ü±ÿH´V'Ч¾Oç䣸’‡w—}å·®uùÝY{ðç¿WŸqc7Mµ56ùÅ/·¸ÑÆáöžöڂŘÈÜßÛÞ|r•½ö¬8D›\é?'ñdt›žâ‰ÂÇŸóÿ°ªO·õ{¹ÕIvÛ¡¶wÇíÚŒwíø0›vБ:sp}+;(~N)]‡“Ûú+ëÖ‡ ¶Ž×)„U¾²à´ƒbV[迯Â4<~ £EU?)ØlüÜä¶f¶»ÆÍïãÿv]iŸ}Ó’\zrOíÛ}›NúvÐñäþü^µOøÙúœØ×»VÎÿ¦'±ƒ[¯¾"]rºø,te¶¦ÛÝgÚNGÊŽÀºã­Ô—œÛï‘Nƒèm}IáY›+¦ŽÄø·ÀKfsñ†'¹­o6à{„bŒ³Ä˜ûß\°|ÏdúÏðÀèüjÝÌ*7€Ü ©¶ç­­Ñr3ÈMÈÍ|Kzž½J°ðµåßåf¾"4$7€Ü r3*Þ¯(7À:¹äf›@n€fê,7ðEÞCgìÈÐr3ÈÍ 7€Ü -Õwk^¾APn@z^'7 4ËÍÐ‚Ü r3ÈÍ 7€Ü r3ÈÍ 7r3ÈÍ 7€Ü cú¹E)CvróŠ£ @§¨Y/õÓ€ur3ÈÍ 7€Ü 'Y}4Pn€ur3ÈÍ 7€Ü ט½¯Zn€*r3ÈÍ 7€Ü r3ÈÍpG!¹v’›@n¹äf›@n¹äf@n¹äf›@n¹äf›€’Ÿ[”2„`W 7¯ˆ1ŠÑôK›« S? X'7€Ü r3´Rîâ,7À:¹äf›@n¹äf›@näf›@n¹.c”›`¹äf›@n€S…äfØOn¹äf›@n€a$ß­-7À6r3¬ûYýFrðçi;öç «ÛÉÙnš ÍÍË\;MÒ!„Ϧÿ^ Í;¦€«lî§Qˆ¼1ÆÂ› “s¨Ÿ î”›à ýlúö™}*4B0\n^}øï|…¥‹Ô\“›k"²øx¼\âÕ¿ÖÕæædcól(ŒäwB³n5SÀÉÊ¡ôçøÜw¼ÁdßTp•[¶õz.€Þf9YÿfX÷sÓr÷k&ïÚßú¾3·el›Ý–1s[Æ–±Ùï¾eÒÞ r3ÈÍ 7_ã¾ãâÝzD?…Wr›]á•\á•\á/¹Ü r3ÈÍpŽà5×°J{3¬ô}!„÷?65‡ï› l÷Åqð7·ÜØ5y6‡q|Vνz¶Ü14¿*›«ŠnöGäfØC? X÷?\°¤yšj¢ÐIEND®B`‚snd-16.1/pix/grid.png0000644000076400007640000002261411147553267012606 0ustar bilbil‰PNG  IHDR ŒùÃesBIT|dˆtEXtCREATORgnome-panel-screenshot—7w IDATxœíÝO¨×™ ðóÃÌxe©czåÈ‹Þ 4î ^ìLÙ>ÙÐÆÝ«FÎ&àϦ7̲½²$8cé­z+ŒüÀ"‹Ð`:4 ^X­¥m)FÖÅ›…)¹^éTÕ©sOý½¿ëÝ[ç«SuëÖW_ý9÷à_þåä4ðT!üõ_ÿϹû¬Üµk¿ÿeîNÛ¡ÀŠQ`Å(0€b@1  PÌSC<ÓúÞéé¢Ó6_Åj›f,C–#Öv貎%Ö—¶×çêcªØg2f_—¾>€ý6ä8/%VeìcŸÁFéê›®z¿ë`L%WnJ¬œ¡¤%H—ü¥¶[òú(iÊãn·HÅd]ÁHQê2ÌÔ·ÍôÍ¿í,{êû¥/Ožþታõ]·GuÍ·o]—¾Ê0T5Ÿ®Ï$u]—\}ÛÈÜÛ0°m%Ž5RkRd)3.qfìÚ”Ã!‹mËZ®˾>Î]<¤jûLª×R×u©õÑןµ¬W`™úŽ¥K?§‘r<ÜgÔg0–.g9b•Ý>šëyiÛ^n–¶À2õÝ3ö¼rŒv‹T)æûÕo“ÚåÀߺ.¯­ U`¥,ínñ†±éX×ãp‹0¦¥SEj ’âÒªÍTmM5ï)Ûíj­Ÿ1°J·L2ŠTÛšõM3öí%}e·=Iß|-eYcmKÿG×Yñëº9]oÉŠõ¿kþmÓå¬ë©¶=·HcJ=ÖH9^m©R?²Wrš»,GìÃ(=ß)£&å¶o›fê+,5]‰õÑöþ˜ëØ%5Jguq‹PŒ(fÐ-R©~,ý–˱,[Y€R¦>>*yœ5¨ÀØÊžåX–­,@)k>>r‹PŒ(F£ÀŠy*„®]ûõÌݶààþý/Nçî° n‘ŠQ`Å(0xìÚûGá¿ÿ·ïÍÝ VL£ÀŠQ`Å(0€b@1O¥LtîÜ…ðàÁÝÇ_{ÿ(\½úVøæÑW£u,Źsf?ÀZÕ÷éCÈû-%¸‚“tã_ÿß¿†ðôwÿøg? ÿ>?óZ!|ÿá3%ûÀÂÈôI*0BáäáIçû·ß»~ý÷ÿBáµ×~:¸#ù—ÿ#iºwÞùùàØ”#Ð%¹ÀêâÅžxíððõp|üQôõ?üMxé¥<~íÒ¥WB!ܹóIãµ?•ï,£‘öËdÏ`¾NN>Ÿ}öû¤éïÝû<Ü»÷ùȽ`jòÀ¶MV`œœ|BáÕWØ;mu¶*„>ýô·£õ©rppP$Fõíä€m›¤À8<|ýÌß}g­êgªÞxãµQúT)•LNOOÿ'©ÄÉÛ7IQ­ªtµªŸ­ªŒuÖªJ¥cH*qòÀö^`4ÏVUÚÎZÅî³ã¬U‰d@:ù`?Œ6ŠT¥y¶ªòê«? _~yö—_/]z¥õA¾O?ýmôlV®9“IÊÙ¬›7oNÐ` çîBùàIò0§±òGrqû½ÛƒƒW#…´ùì³ß?1|áÑÑÁóY›”dV%ÔÄw||¼˜ƒ }‰Ó—åö#}B>(gŒ|B¹mhiqJÆgš8%c‰³IÆ_ý׿zü£I!„píý£põê[á›G_u´j?[Uižµºsç“3cŸ°,ò}F»EªïlUå³Ï~ÿø¾Ü’—¼Xù`¿Œú Æ­[Ã/£·Ýs{tt#¼ýö/wíR¶¶KÔÕ!õ×=0p–|°?F+0Ž?zâ~Ú%i>XWÿ{h2hC(™|G>Ø/£Þ"µd9I£d<€}!¤‹*U"u||<(ÖÐé×§d,q¦‰S2–8eÍ>ŠTŽ”{noݺÞ}÷Ý1»ÀÌäƒ4±âÄ(RãÄgš8%c‰³“ü’7°@1  P̨yéŒ"5m,q¦‰S2–8e­r) Q¤¦‹%Î4qJÆg=Ü"£ÀŠõ©[·n€•öÇhÆññGáâÅÆ ÀJÈûÅCÞ°F‘š6–8ÓÄ)Kœ²Œ"g©éb‰3Mœ’±ÄYyÅ(0€b@1  yÀBEjÚXâL§d,qÊ2ŠlœQ¤¦‹%Î4qJÆg=Ü"£ÀŠQ`Å(0€b@1F‘Z€RÃÎ5ÄYŒ¾ÄéË“–ÒÖÛ—­>²Ï S;m,q¦‰S2–8e¦vÃJ K¸¤!Îô%N_–Ûô…e0Lít±Ä™&NÉX⬇[¤€b@1  PŒ‡¼`!Œ"5m,q¦‰S2–8eE 6Î(RÓÅgš8%c‰³n‘ŠQ`Å(0€b@1ò†:88ô@çTm¶Ô/X"£HMkÍq._¾üxÛHÓÕ¦-ÎåË—CaP»Ø¼R–-¥Í8C—)·MjæŽ3”Q¤`¥–zð;ÙKýLÀ(RÓÅZJœj”'6}_œÔy4ãä,cÕfȲuM×g—¾¥Šå¥lCKä)`Q¦*|ö¹À€1)0€AöõÀ|_—`‹¦Ø§ïsÞP`À¹;‹œvS´9==Ýëà˜¬WØ/»|ç—ž[äŠo)JÒ)0€Ñ)|Òìã2ÔMU4Me_‹y³—vyÈ×ÂË´ÄÏe‰}bÙŒ"5m¬Xœœ†ª8;N”³\±6}qRçSM×üªúúÒ¶kÚ¶÷J­»¡mRb &g;ÊýNE " lEîY;Ûð¶Eª\¬¾ïGWœË—/'¯ï£-íÒ¶Ù&eý¤Ì§§ùÿ¡ýúù·MÛgŠ‘¤šmR—«ošXœ¡}²Í†0~þp‹‹±Ë=¨S]‚t0·9·a½íë­aÐf×ïƒïÌCÁ"T﹟1¥/¹oÀp¾Óe-}>•j=8q4ÅU¿úÉ2lé¹1ú5æ²îkb¦µå…]Nx­ñ;?å(VS*Ý¿©Š’-P`°·¦HÕ•™ÓÓÓäÛu+ÖRG£hÛáÖ—¿ù~ß|R?Ÿ¹×W޶~-µ¿PBîö½Öƒö99¢Þ.&·˜+¹ŽsöË}mºrL_ìf›®¨—°­µmóKè[*EU_Ü©¿kI@CúX?SÒ×®y ß7}ýa°Ô6õyîú2Rb…M×ÖŸ7{9—´³©–uÈr××ÓeIGÎU’”³h±ytµï›oÎ(B¬Ó’‡©­ÎŒÏ5 k½mî0«©ý:,kUDå ç[®ãããÞár›óH¶z½~"°o½ö½Ö5¯ú|êË’Ú&Vœv [µ½yóæãí5u]ôõ¯m¾mŸyõùUËtùòåξ·m}ýˆµ©o;]ÛQÉÑÝšîßÿ¢7c;w!üð7áí·îÝû<:ÍÑÑðöÛ¿ O=õ§3ýÚª¡mIîIîAp=9æ—–:ÏØ¥Ñæß7oÞ|b½ô´µÍ¿>}³mW›æ4Cæ¿k›zcëªkÚ¾õÛ\'±iúÚ¤NŸÚ¯!ËÞœG=!¥lCæ+0Râån«)êûôº¾ý»|0½œýxWNȳK>©Úåä”f»”ƒ¢¾œ’’R÷Õ]×w65GTúN,ì’'Úö“Í6}ËÕuœÐì_sÿšÒ¦nhŽéû ›Ÿ}Îçž›7bë»Ú¦»rEßöP_W)ß¹1òG[¤îà`ûõÐ÷-óý¡ë«¾Ž§X×9I6§ÍXýÊ-"wi³ËçRßÙî"'F,9?¶m×|°Ë~®Ú7”ú> ™gg¿CÕ]îwjéßÅ]ÖquÐ;t^C>Û¡ý«†CT}Ê1v¾[Ûg[÷]ËÚ,h¦¤ÀXÜ£ÞfHû®pNœÓ§ÆjN×÷°[õÞe'›ú®ïô‡Ìc¨úÎ<µýÔ;â¡ELN¢É]¦!ß·¡ßÍÜm¬ôÙ'Öm΂y—¼°ËAó®1cgÄS†®_‡¬ÕÛ¥ôïæÍ›g¾Ó©ûÉ]à‡zõ)GÛÕ‹Ô6¹…É.ûÔ®í¢íõ1ü›Ç2móŸ"(0V`׳·»¨úv®m—‡ž5ê»ôÚÕ®Y, Ñ5}W¼]vSŸ £Mì3ŸÛЄBÚ¯ ¶]½IùS·¯¶Ëàs…bºn¯Ø5îмPïOΉ¨êžù!à»ä†*F®]®üÌñ½+W„p¶ê*¾æ8é5VÞhÎg—;†~6sž„R`,\[ÚwV¤ï½¾öm;Ä”dÒ]y¡o›ßÛêû1dëw½O»ä‡æºÎÙwWËÕª­]l=¦´iëgÛ>qh®è›W_¾èÚÖG¶êjmÛPÛºK‰ß—7ú^kû~ôõ¡ù~n›Òù£Î-R+Tß ªw%’¶6©ój&¢æ{Õ)±»â5µíÄRÚå:¿j>U»¶e«¯Ÿ®8©óɉ3dtõ7wÍ÷šË2d»èS*N3V_BmN+(ºCWr“ÛUmmÛenN¨o›mûõØK}Þ}í»ú“òˆýPhªúþ:÷¯Sû9$Gtõµmšz¼úÿséëKÛ´±B¢þ÷Ðù¤ä‘¾ešúrtŠØg1¤ms[lË©}ÈéGi Œ©vP±×›£O¤¶O­f»»]Wr‹% zÅ›_½]×òVïÕLىǖ¯KsšfrnK¾Íé‡îšë¢­]W‚êZ/)…eêë©Tìïœxmóh&€œeÏíGÛö:$ù+2hjÛ¦vÉ M]·uíwSrFJ~h.S}ž]ú¦æˆê ³mŸÔsè2ÅÞëZ?)ûËÔýX_±Õ'VÍ1}šÛL,o ]ÞX¼”þå䎥œ”ò Oì´Ýë]:/ÔÛ¦LÛÕ§Ô|V?•“šqêbû•T±~¤Øvå–®6±ù¤ö±ÞÏÔ|ÑÕ¶ƒúj>ÇÇÇÑS:g¤¬‡Ô¼ÑÖ6u>%ÛL™?\Á „¿¡ÕÏää´ËM@¹g$š±ë}ˆ½—’bíbÓÔoYHYg©É¶¯¸Šý{°3¶r“îí"·ÀíêkW¢-±SºM”Š•R0A »|OróB½méÜзÿŒMוb¯¥ö¹ï@±oý yoÈI–f›¶gúPsöý]mÚú—cH~Û5o Y! Û¯7Û ù¾L•?\Á`urwj¥Ï&åHIrCÎLL±£hKÜ]ɱïlÑ®ù¹Ÿen’ÈÙñ§¼[GS}®,Sì³ï)©ÍÐé×§-VÛ¨z±Q’êÓÕ¯@äô162P×<›}¬OÛÕ®mÄ¢”Ÿš£Óµõ¥Ù&uU›ƒƒ'Göª^‹­§XœÔ‘Ú>·”‘%S—©k>}#^å´‰õ½ÚFÛ>£X¼¶åˆmc"¥À`¯”8 rõ¡Ä™ì”³võiúæ›{›».šýûà¹tA0äŒhWÑÕeȶRâ Ëû|s΢ÖG­ÛÅÒ┌U³ËI£fvÉ}ˋݼÒж~R®¸Äb7ûUý»­¯máwí3cë£Þ¶šW}Ùb}ª·õ¯>RÓ6ÍéºÚ4—©Ù>¶ªƒÿæg™º-uýú^in‘‚‘LõEι²Òöàæ®—¼ëÓ瘹ÞwKDÊ<êñ»ÖIÎò) °¦üÞçÌ«k €®×K.W[¼ÔÛ«bm†Î¿+/õåÒ±¯²/9w¸‚éûª-*µ³zF¦T¡”#ç,aÓ>n+°ïr¾÷[¸¥2÷–×¾˜]ïÅn!š3oĦɽ¥w)\Á€=•såcÈôS=ÀxvÉ©m¦ÚÿËÓQ`À‚Ùc}ûÆ~/Ÿu7lÌRïá\j¿öÍÒÏþ/½ôó ,„aj§%Î4qJƧ,ÃÔÀƦvºXâL§d,qÖÃ-R@1  PŒ(ÆCÞ°F‘š6–8ÓÄ)Kœ²Œ"g©éb‰3Mœ’±ÄY·HÅ(0€b@1  yÀBEjÚXâL§d,qÊ2ŠlœQ¤¦‹%Î4qJÆg=Ü"£ÀŠQ`Å(0€b<ä½¥F ™k‚}‰Ó—'-¥!¬·/[{8pŸEjÚXâL§d,qÊ2ŠÔ†•5dI#èKœ¾,·!è Ë`©éb‰3Mœ’±ÄY·HÅ(0€b@1  PŒQ¤`! S;m,q¦‰S2–8e¦6Î0µÓÅgš8%c‰³n‘ŠQ`Å(0€b@1ò€…0ŠÔ´±Ä™&NÉXâ”e)Ø8£HMKœi┌%Îz¸E (F£ÀŠQ`ÅxÈÂ(RÓÆgš8%c‰S–Q¤`ãŒ"5],q¦‰S2–8ëá) PÌh·H¾>VhVD>Ø/£>ƒqròqï4·nÝï¾ûî㿎nŒÙ%f ìÑ Œãã³Ï~¯wº‹_xüï;w> /½ôƒ±ºÀ äƒtF‘š6–8ÓÄ)Kœ²V9ŠÔË/ÿ¨ó¬Õ­[·Ï$”K—^³;ÌD>Hc©éb‰3Mœ’±ÄYQ Œ¾³VõdR¹wïóè´GG7ÂÛoÿ²XߘŽ|°?FEêå—}ýÖ­ÛO¼vçÎ'­qƼT»$£ú€'Éûaôãøø£èë±³U!„ðÜsñÄkc>èW*™œžž>þORx’|°&ùŒæY«ØÙªJì¬ÕXg«ªDP:†¤'lߨÏ`Tš÷Þ¶­ªTg­þñÿwaœ„R"™0Œ|°}÷ïÑ»W=wîBxðàî㿯½®^}+|óè«èô¯½öÓ'’Æááëáääã'F ©ÞûðÃßô&ŽK—^ O=õ§3ý*a—äÒÖ¶+fÊÙ¬jXB€>9£Ô÷éu}ûwù`x[ùXª’ù£n’+!|{Öê³Ï~ß{¶ª„®öÎR¥ôÁ%u ÅöiCÉÃú cs8ZqxøzÒku¥Æ=_BÒØÕÐeXÒ%~}‰Ó—åö#}“|°›œe(µ --NÉXâL§d,qÖc”ãÆ_ nóÎ;?!ü©w:ÖC>Ø?“Œ"µmcšÇFÙb% À·ä€n“=ƒ±4±$Pš šIE2Xù ¬½-0r’FÉx[¶¤u¡/qKêËR,i,©/û@>hWjYJ®“¥õIœic•°´u´´õS‚[¤€b@1  ÆFlñþ=¶Ïv ãðÝb‹l×ë¡ÀŠm©§Ÿþ³AÓ?|øõH=Y—RÃc¬v¦äP¤}ß¿µ{*ä“`[ö%wŒ:Lmj’¸~ýƒpåÊ›­ïŸ?ÿüãß¿ÿÅŽ½Z®æ†’»ƒ'öƒQ@»RßÕªíTóš“|0œœÛ²O¹cñ¿ƒqþüóg’Hóï­ˆ}ðÕ6 Ù †Æ©^—PÊ)ñ™­ÙÖ—¿Ôwµ«íûWr^[°/ù 9aë¶¾Ÿì3dyÖ~·²o¹Ã3{lk;¬©¬%ñÆú9v߇Æß烙”ï_lÝøÞ2ÛV9kÙ§Í•'R÷ûÕ´ÕkY¯cZKîX]±Õ³US“Hò­e½•êgê}—3rû˜8R×UµnªÿÖ²ýMA>(ǶUÖZÖåœyb÷û%¬%w,þ)Ê“H¾»ôÚ<»Ò¼‡±ùZ3ÎÐù–èOJ?«×šïuݧYo“rÆ„òæ¾–í³Mu“'Ê剡l—ùæÎ‹-0êòUÿv¶ªœ¶Ë¢ûôeîÛaÆþrÙ±¹ƒ®‹ÝÙ¶sîëO×ô±~æÜ¹Ï÷û/Áî£]ù`|rBœ<Ñoª}’í1ÝrÇb Œ*ylù!¾¹t=ØÇ·êë"w½ä´k;c‹Õ<[5Öçg»`nòÁ¸ä„<òD÷¼K²=®ÏêžÁت¡äT÷Ôí‡e©@j"¨¦+u«ûaû•ú®Ž1/¶CN Í¾å‰­l¯û–;{c57ˆ]Έ”ˆ³u%w¸cèÛÄ.uù¬«é›g¸ÆÚ)5ãÔû¼¶Râ;[ϱx¾ÏûKN˜ŸøÎùcó†Dì…F;ù ]Éü±ÙC"ö™Bã;ò@ºùc“Fu_-À¾»wïóðé§¿»³‘òì’?6Y`ܹóI8:º1w7f·ïËyvÉ›,0Bøvh»wïI,À^::ºîÞ½·×ÅEE>HW"Œ6Líõë šþÊ•7GéG•X>ýô·á7^eKQqZRa!,_Éü1êï`¼üÚ;½Ó¼xá ·nÝîM<”qròñ¤óóÙ²oNN>Ï>û½ðòË?ZìÁ|À.¦Î#Û[7Vþýw0Æ:+5ÄááëáÙg¿7Û ` U¢˜ûŒoù`™JçI~ho®¤"‘ûhÉ…†|°\¥òÇd¿ä]O*9—ÃÏŸ>¹D°\òÀ¶MV`„0,‘TI¤º×¶ù7Ý~ñ‹_ÌÝ…VòÀríš?F}Èû…?r<óGþRÇ9o&ÔdR=¤òÙg¿¯¾úä6ŒG>Ø£W®¼>üz¬ðI.^|!|ùåW °Wª‘o–2ú|°¥òǤ·HÍ¥J,·nÝž»+£¹uëvøò˯SX,‘|ð¤Òùcô_ò^’ú,¦#‘ø–vÅb äƒu‘G`cåM}Ck-qèÆ-{÷ÝwçîlšïX;ù`lã0ޱ¾[›+0nܼù†5 IDATøÕÜ]`ä€yìÅ3À46w`ëþãé?$M÷ý‡ÏŒÜÖdªü‘T`_ù`ݦÈn‘ŠQ`Å´Þ"uíý£)û@¢ÿì'IÓ¥îÇÿöïÞ(€e›*´W¯¾•€iý{ø3Êè°mSå·HÅ(0€b²o‘:8øî¹ŒÓSÏ ”ppðŒuÉâ\¿þÁ é¯\ys¤žLçé§ÿlÐô~=ROÖãàà œžžÎÝͰ>Ùù£ßVóGVÑ<v` ÛöòkïôNóâ…ƒðèÑ7³³L]Žë×?(’ÏŸþñ¿ïßÿbçxS:88˜» ÀBÉí¶œ?±bâôôŠ Øc/^p€¹«*)ÔŘþãéøþúÇ?ûÉ·¿ôÚòcLçÂÙQ¤ª3íŠ ‡ü±»©óGŠÑG‘ªn¥Ê)>ª¢¥~;V,Vóýæ4mÅONQ”:¯¡}Vœ±VUrøÝÝÓÂÎÛ9yx2húÛïÝÿü¿þùñßCo㩊œ[Ú ™f¬X¡SŸ¦­Ï9·$¥ÎkhŸÝž?¶kñÃÔÆŠ€úk%‹‡œ¾Ä^Ïés¬p%9›ξ6Dì Ký’îùóÏ?q‰·ùZõw3V¬]×¼¦Ú×ÔXMC×]ISÇŠ€úk%‹‡œ¾Ä^Ï鳫Alü‘gÍùcôc׃ü©Š„]Änˉ¡È`©ê‰àÅ áwwOϼVO]ÚvV9;±¾aÉyíªÔŽ{)Ë“k׃ü©Š„]4ãåÄwË["ìf­ùÃ0µTE@ó?غfÈI]rvp¹;Å9Æ×R®*šÿgÉ»YkþXü-RK3ÕíX°4ͳN9b—z«×é·¤øˆ_0¼,YH¸Â”JMkºÍg.]—ì×b—‡¼K«?€ÝÕŸ¶>YH¸ÂÉó™#dÝ"Õ¼UhÎâ¡í¶¥zŸšEEî°º)óʳ„ RÔ/i½¼³3+½œã€|¬yöÅ{Y›·Í}«PÛmKõB YT¤¹óʳ„ Æ ,gžcçì[¤Rˆw9pnk›óPõ6¹ïu½Ÿ2Ek‘{&*åwsš¶6%æ5•¡#–TÿîZ/±×J­»T9Ó¥ç•óPõ6¹ïu½Ÿ2E[%ìÞ—5äÏ`½^øó'Ç'ôè!gÜò”tß4mï7_ß%\¿þAvÛ˜Üeꛦä2”&ìnùCtºråÍððáדÍo ÷Ó>|øu¸råÍYûc ë "¬Géu§À¥Ô í#ëØgöùJ¯;°8[JS/Ë–ÖÀP[Ú®9$xø`kn¿w{p›îŽÐ¶äàþý/ U@!„kï…«Wß ß<újî®°RY¿ƒ£ÀŠQ`Å(0€b@1F‘Šq(FóÿEƒ¶õÂ)IEND®B`‚snd-16.1/pix/sceq7.png0000644000076400007640000000177411147553270012701 0ustar bilbil‰PNG  IHDR3"{Îæ3PLTEÿÿÿ°°°ppp```ððð€€€àààÀÀÀÐÐÐ000@@@PPP    ÀgF pHYs  šœtIME× 'ˆm,\IDAThÞíZ‰²« eIX[þÿk_X´àµÕ.8Ó>3ckMEz''¹—±h\H`ˆŠ¶×´avPš?±ØkSŽ^Ìï 'V³)”ÖzTðøkxbö´9}bðˆâ¹i΃`¸M/Ä|D}Fióiæë2h7.GÌ&œ»Ð‡L]°+OÛVù”$ÈŒÔ:("=TÚx]ífbux]Ó{ kš.Â)ˆeÜ›ÌÙOO¢Ë më=aÏ#ί#©·Kºè¸àe¾Ï[\x™2øWP×õZ/q:7ŽÖÞŠ6ë$ºü«8jc­ue³>HøÑiPq hðî|þª¯0%‚Çuà‰Î˜õŠt —v³b0‹­Fuñ|ýhÅNT‹#CÆþ,;ìÃa¢4¹~Ó+”Óx3ÜÞ¶tI3%€óá¤×ˉåAý&èÙÄÑõ£´P÷„Z|ž)íãjµÅL˜ßÎŒ¡Ñó³ÆZ¢ ëKµâ˜{AiÂ,8cT— ³XÌ&Ì’Þ³¾ñW³ì/8á¥/,2uMX ÅÚa“#¼æNÆ¥íY±"íP¯ÆÙ€ ²vËÅàËz¯õ×7vÇ,Îã‘åñŽP¬VqTÁ@½¨®Ýœã¦­Ö£Ù„Y<Æ ³4ÿtb¶OGÄîãgOÑ™¯T„ÌÉöök¬©n <IEND®B`‚snd-16.1/pix/sceq16.png0000644000076400007640000000167611147553270012762 0ustar bilbil‰PNG  IHDR5OìH²3PLTEÿÿÿ°°°€€€   ```àààÀÀÀðððPPPÐÐÐ@@@ppp 000Fš pHYs  šœtIME× * ¹dIDATXÃíXëš« D0)‚·÷Ú“€ õV ºçOçÛv·]£c a&BÀˆ èËÿ~Fz¨øÔgÇ"ÒQj.ãBsЂÀ—ÐF‚§ª³º« ãCsÒCw+ù ‘…=;fú' 1b1ú\ ¶gbàèªùnÀ½kwk-Q~ÑI›ö¤²ö1ô9 ÍÖ¨+$%…4œ¥„éù‡.1P*ùÅ7{ôHö1`¬1`×мR{¥Ÿ8­@ßt½âÅ$Û…²«p|äÊ'˜Œ`‘l´H Ÿ2’[>ÎUlù“q™ŸkR)ȼ«Hù8³»˜ŒËúYˆ¢ìi~ǯ.ÎUàlçÕÔ¡__‹ÉØóQãàòFë+q ­ûCšŒöaà²:‘·þMÆ>?‰a‰79¹ÉFÙê.f® úOýÀ嬦>òÆPÍ›M°zàrÏþî˧ÿ~àröåS9p¡¯¿ÄÕ‰Zµ—›ðÒ~ ÆGíÀå&¨›Q'ŽêË]»à²¶â€£~à’©aó´ip<0pyÓ°ÅÚôéK±6½sà²Ó°ÏhÓz ûŒ6­×°ÏhÓz ûŒ6­×°…Óñ»Ÿ×NÊ‚éøõ³Õ°¢b:~çó2ú³DŒøcƒ!VËÅûÃIEND®B`‚snd-16.1/pix/mix1.png0000644000076400007640000004707511147553267012547 0ustar bilbil‰PNG  IHDRµæÝ¥Œg pHYs:ÊduhtIMEÖ42S> IDATxÚìw|TÅÚÇg{ÉöÝlʦw’ÐK 4‘"EADiDAñŠ/^k®W½"zE½ØPÀ‚HSQz $„@B ¡¤·Ýôd³½÷÷ÁeÝD ð|ɇÏÙ3åÌ™sÎï<3óœB™¹ õˆ´YK Àm´IwÕ8d„Ðqãñž"5Hdž•ÙeP§Ü&úØ 1VfëIÖr·æ¡¦üBvo5ìnˆ‹öcpÆbPr69¡²¸=ˆ¥ÄºÚ\Îfÿ²FDôÖÇøèx÷Þ?¢g¤ñáñ$ ê€[§ÃI,'¢~þÚ×ÅÒ¸È8R¨·¬¹ •ú³/‡ù€wú €¨/¬OÌNüKÓþ™C·=.÷¿À²K‰uïT;Ô§Æ…\ty8ÚÛ`ä¹±”X÷T1pÝÔž¨Åv­ Ïl;S´¥(øCÀUá‘x±”X.‘빓€Dh²55ÙšdVÙù¢ó^©È^¿ù$¾{LGZ"5 ôLÑ–"U‹*41´úXµ Vê°9”ÍJU‹J!UìÿÏþyŸÍãGñqä­+¶ò£ù¢8‘ËéRÈ¢8‘¢IqÏ‹÷\{P+T6+Ñ‚!³‡(¤ ÏC”l/énìÄO7ò$<~4ŸH&v7t{E€€úHäI-RÙ9YìX/CÒm`º\Þ–¦·ý¨vªŠŠŠv‡Û΀@$ O  ÃøÑü{^¼GÞ W6+'¯žÌâ ã„Ïì~Æ-Ž!ž„wÏ‹÷t7v×ä× „v‡Ëé:¸ö Ëé4sÐøçÆš9ˆ@ô¾ëâ³â BâˆDNgÒ‹“”MÊî†îÉ«' ã„Pÿ@0¨êÆ3œÎ5¥"ûæ?,jž†Ó ¡¾°ž@ àïx‘¼Ãÿ=¬nS+dŠíÏoä“GxÞåÍïq’F&i;µD‘ÅWµ¨øÑ|"éòÛºdGIý©ú’í%‰Ù‰?>ûãœæàCÔ¬s'Äÿ÷°Bö#œ>:ÕñY~”Mݪ–6I±%é ¡Ì\†ýÃ]ç\„A~¬EééØàÄår9íN"™èrºˆ$¢Óá$ N»“@ H„šã5)w¥¸¿¿r:œžqˆd"BÈåtˆ„+qìN—Ëå™ïô{œøât8I—H®þ~”OZ,;r¬Ì&C.f5W©‹0€Êý$—,k‘Éd¡bŒì¬ÌWDÕ­jM›FÖú\t6½élÓß•¸ÃßÜq”8Y‰íÒ´iÔ­j_Ys!W,)Ö„pÎxNj•"„\åÖ!Ñ™~C$œNðïà£í" .Aºv¥D‡Êû9L$›œM!G“éÁìÉP¡ÜÉ\*®Ã’ØØÔ}7ÌO¨€kÖÇÂÂâ÷Þûÿ9N„Ðûï‚7ðv~~a‡).>ëÎÊf³¹÷ŸûZ«ÕÁ½¬'žnœNç{ï}têTñ ÓÇ£Góž~ú±+ž\±âI"‘ˆzæ™ÇñÞÎÍÍò0yy=ö(ΊB¡¸÷>|!4p`¿Q£†»w¾ýöû=WÑhF™L&„ÐO,¤Ói×Q›_ýÝ´i“V¬x²±QÖÞÞéºyó–ÖÖv÷ÏÅ‹ç±Ù,¸ ×‚õÄsãŠÒ‰O=µ$xɯf^}E$_xa9B(?¿ðw>سg™LF1 w´5kÖa îî»G3ÒoVŸ¾‘J¥®\¹ !´víǃ‘B!c[ríÚÍfó¿þõ2Bè?ÿùï‘#Çm6û?ÿù<æGõž~úñ5kÖ½òÊ*¥RÍçóŠ‹Ï¾õÖû›6}*òKKÏÿúë—ËE¡Ÿþ™?üô•W^@½ýöxà »ÝN£Ñ ‘Ht¹\sæ,NOOs¹\Ç‹CúiÏ… wÝ5júô)¥¥çßzëý>ZyñbÅO?ýær¹Èdò³Ï.]ºteŸ>)N§kèÐA±±Ñ?ýô«Óé"“I+V<Éårá–€›†ÃáX»öc„PQQ‰Ãáx÷Ým6;BhòäñÇuK–ÝîxใDÝsÏÝ#F »N}|úéLjD¶ÇŒÉ>q¢Ðåo¬üøñ‚»ïƒe;>.]º˜Á``ãÑ`0æä¼d³Ùß~{-BèŸÿüGNλ8Ú?ÿù‹Åš“óRÀ“Éd2¹°°hàÀ~aذÁ“&ÃÎï……Å.—+$„YXXl0l6Û† ßÜÿ4Ï}$''¾þúÿ„œœwsr^š>}ÊäÉ¢¢"BöŸ6mö#=sæÜâÅóbb¢6mÚ¢R©ã_{írªðp1F#‰©©ÉîW¸™H¤§Ÿ~!¤VkÇÉ“§Çãp8rsó‡êÑ5hPÿœœ—Ç;ïü÷úõ‘Éd’HWŸùqРþ¸X 9pV &“é¹§¬ì"Vw¿eggù b0‡[±b©oÐ’%ó„BáÓO?Îd2B¶´ôB•[QQe0Y¬Ï/–ÇÅÅöв&“Éî?ètÚ‚p8ìíÛ–Éšãâ`v¸©„„0BØËÊ‚u‰J¥xE;s¦4(Á}êÕ§¤6)BÈUo‘é)±Èf³%$Ĺþüüªªê“'‹ÆŒÉ&ÿþ÷{‹!„ãlݺ³°°hìØ‘îÊ?feß²eûñã'/ÈÎÎ"‘H›7ÿÀãqâãÿóŸÿšL&»Ýž””€" ›6ýpÿýÓü¶¯±Û펌Œ>¡¸ølIIÙ™3¥YYC† ´aÃ7yy'ív[JJ…B¾çžñö¾û&3tß|ú÷ï»aÃæC‡Ž%$Ä:èÒ¥ŠK—*:¶bÅ“L&£oߌ¿s8œýûg–•](,,*+»0hPÿ¡CnÚ´åàÁÜèhɈCm6[bbÑé îŸ+V< ·ܺª÷Ö[W\_H$Òk¯ùW@2™üÿ÷\0y‚ýàß~„ïgüs¥}M£ÑNž,‚àNF&@Hê­L#==j€; ÅŒ~w˜†ö5ÀÕÚ×Wv‘iv»E.ï w:íÁçE"QÉd:Ô)·‡Ån·\]­$§Yº:&EàtبNÍIæ ƒÁàAEpËa2©ƒÒGS·ÏqÔî*µ–#„Ø%TÔæ,(8E ø|J¥Dñù.—Åá°#"$íím,ëÞ{'Ap›·¯Bv—ݽf¶ÝNtÙ<—@ $''^¼h¤Ñhii©*%%%4T`0hÓÒ2®Ûu wr ¢¡V«<ç˜àóyN§“Ífù_;öwÎ;÷öÛoû Z·n]NNΚ5k¬Vë­Z…[·"¡ …hùr¸Ÿàö·ý¢Ñ¨~KK+BˆÅb“H—Ë%‘Dêõ†vvvšaL­Vçää|ðÁ‹…J¥"„ÊÊÊ <ã<ñÄ&ªèX,H©D!½þFe©T*Áµ¦jjj²X,±±±¸&ƒ§¹¹Ùl6ÇÄÄ\k=ÆÖÖÖÈÈÈk--žÛøº¿ €¿G™&µÉå ±8Ìåt$„ÅÖ·6DDDj4šË˜L— Q(”“'‹\.'B(%%­‡cL™2¥¨(XÏóÔÔÔèèh÷Ï„„„ùóç÷j}¼AètºÎÎN‡Ãa·ÛA{{{DDD0 ¥R©Á`@ÅÄÄP©Ô–––¨¨¨`$²¹¹Y§Ó¹\®èèh±XÜÚÚ*‘H‚©j£ÑØÖÖfµZ FLLŒÑhÄ 2!BÈf³áY,–¸¸8PIà–ÑG6‘=gØŒÒÒ C‡fÙí&„Pý¹&3¤¢â’;NW—<11nøðËó3 ¦U ƒáù´ÜBS„iuº–Š ×'&‰îõ$ØlvXX˜oB™Lf0X,Vtt4‰DÂÓ³+•ÊÊÊJ …Âb±ÂÃÃýQ¯×·µµI$’¸¸8÷θ¸8©Têt:CBBzPX™LÆçó£¢¢Ü5×ÐÐàt:Ùlv F£\.ŽŽ¦R©8-ž¸¦¦†Åbõ`HÆ®®.üò£P(¸ÃÚétJ¥R»ÝN$%‰¯PšL¦ÖÖV›Íæ^øÈ»‡è÷ŽŒŒôš`nRûšH$¤¥õqÿŒˆˆt:ƒËTÚ(í_|qæÌ™ÂÂÂììl„ÐúõëåryNNBˆJ¥®_¿Þh4z.Js‹Ò§O/AÇö ÛB,//÷Mã•P ðx<›Í¦×ë+++½L¦¦&„P||¼WՉĸ¸8›Íf0*++¼LBƒÁ “ÉbbbX,–W¤¤$«ÕŠÈãñ|U‹£oi¹\.“ÉÔëõååå %&&†N§ûŠcLLŒ×8‘HLHHÀò×ÚÚj±Xð鸑Á`DGG»õÔ§Ó‰{onƒ[¸UõQ(677¹Ö×7ÄÇÇ™væÌ™>ø ûݾxñb·-°råJƒÁÀ`0¼§[‘ˆ|¬]‰äž}“F£‰D¢à3$‰4F£ñùüúúz¯!,,p~íkwBç›Ð¯Ž»¡R©XšÕjµ¯š3™ÌØØX¿i) ŸÏçóùV«whz5 âââi–¶„„O± Ò#Ÿ,<ÉÀß©‡Ãf»ò˜Ù¯á³ä% ž &“ m¢`$ 99ù&'×1F„611ñºÏĸõôÈã„$‘ ÐÐ[ ´ãÇ£K—BèÈÔ·/\=èé… Uðg‘ÉPg':xÝCIJ%êêB]]×Ö¸Y˜L&ì÷ã‹Ùl®¯¯÷ŠƒêëëFc P¿A¡ööö@¡‹¥¾¾¾¥¥ÅoB«ÕZ__ßÜÜì7´£££¾¾^À嫳³wû ª¯¯ï!4PB¨««K&“ù ²ÛíõõõBåry}}½V« *•J´çP%v}}¼±\¸páóÏ?ÿüóÏo¿ñS§ÐСˆÉD Åõ^të·¶¶Ö××{õ?z;wNᯮZZZÚÛÛ;;;}E°­­­½½]"‘ø}% ŸÏ—ËåBýJC[[F *—Ë9Fëèèð Òjµ‰ƒù†Z,‰DâWËÚÛÛI$RHHHkk«WÍfS«Õ‰Äápøj«Á`0|>߯·\gg'@àp8¾’m·Û¥R©D"q::Î÷ý¡Õj%‰ß7Ayy¹Ëå¾5ïp8ªªªœN§@ hllôj±Xêêê|³íîî./////w{ z¢P(êëëÕjµßL¡P444ÜÑíëÄÄD±XŒZ½z5X¨ƒ¡©²ÒétÒh4<Þât:­V+•J%‰V«¡áŸ8!„·q(ŸÏÇ.“XøˆD"—Ëmmm  …Ø“N§›L¦¶¶6ƒÁçóM&STTTlllmm­P(Ä%Q©T|>¿»»›B¡DEEét:Ÿ#õQ«ÕáÏf0aa‘éÓ‚ï¹[Àÿqδi‰‡[{ï‡N§§¦¦‰D‹Å‚´ˆD"•JÅ?ݲèêVIw¨{ŒÛ&î¯w„Bamm-N§P(‰Äd2µ··'$$à„|>ÿâÅ‹L&ûibÅ^œl6Ûh4ÖÖÖFGG777[­V:ŽÅ!$‹»ººbccÍfscc#™L&“ÉîG:44T.—‡††âP"‘ÆãñÐeŒf,‚íííZ­–@ ¸ÝQ±p`}ihh “É$)>>Ÿ¸X,îèè·X,8!vKàp8Ø!tþüy&“I Äb1¥Óé*• ¿QðNüÀ„ˆˆü‚éììT©Tø±O‹År›/^Ħ"‘È-¶”m6[}}=‘H$‘H¸öh4š»ÉÕÙÙ©P(h4šÝnOMME1 ·m~éÒ%|Å…B!ΖF£á›»ººär9v!À•@ Øl¶V«åp8r¹\.—Óh4›Í–––† “Ãᨭ­u8$))) g+‘HZ[[±jc‘‰DîšOJJÂJ‡ÕM(J$,m‰ÄjµâŒ@ $$$xª^FF†ÙlƯ„o_Aô’Kûµô,]YŸ‹SD»?k BˆNçšÍOÿðŸ~ú­¶ön"}ù|^|¼Äíÿ8n\6νáó›ñx<©TŠoñÞ‹É„¨TôÇUt{)¢²2„:w øWÍjµ’Éd_Ol«ºEÙ7T£Ñ(•Jì…îÛzmnn¦Óéñññv»Ý3ìmn2™p¨Óéô|`œN§L&3ÇápxŽ•ã>Ÿp·c–Óéljj2 T*5!!Áåryf«×ëqó<""‚Åb¹\.ÏlF#Nè•­ËåjjjÒëõaaa|>ß+Ô`0à&mXX—ËÅ–¾§Ñg0(Jbb¢ÓéÄé¶%±©& ±K©;Ôd2akK,‹D"‹Åâig555ét:±Xj³Ù<³µÙld2944444Ô+[ÜÉ‹eѳrÜgŠ•7ŸÙlöR·¿ã!V›Í„†bÞm;€®º¾«×-ëéK"ÁÀŽðy\}æH${ðx%‰Ø•Òo(‡ÃÁM3ßü±·¹çO¯Pl ¹ÛY^]:·7É+¡çJ^°X,wy|ñ<¢W¶Á³1ëÒC¶žåñJÈd2=zÕ3ƒÁè!Ô³[ÃËßžB¡ôïß?PB:ÞCi BÏνÖýü{î0B§O£Áƒo o$ø[3ðãða´w/ŠŒDð5€>àÞ{Qx8TÜÂíëK—.a'¯[xÞÜÞ ‡u·¶>ÆÆÆâ1k˜”åóË/¨´9‚&L€Ê€[RÙl6öb½…æ¼51  îp ë#ðWáo‚^üã3   ½t|¦¢¢âÌ™3¡@ gÜ¡ú…çø#Ý“âúxÓàp8ùLÁpÓõ}}}}îx.\¸•€>¢ªªª-[¶lÙ²ü¯‰‹/öòvtt¼öÚkב°¤¤äÅ_ *—Ë}wuÓÝÝÝÖÖv“kû/º=d«×ëÿŠ…¡M&Smm-èc/"<<|ذaÆ ÿÇàyúé§=Z]]Ý›…õøñãZ­¶««ëZæææ.[¶ìÔ©S~Cóóó;æ7èüùó . d{aaaa áèK—.edd„……uvv^kÁ` 2į=ztB€éÐÏŸ?Ÿœœ, ý>á wÝu×ñãÇ}CÏž=;qâÄ@æ!…Ba±X~CO:Õ¯_¿ñãÇã5B¼øå—_f̘ÛÔÔäWïºë.¿Ùeeeq8Nçºcǎ矾¥¥Å7¨­­­¢¢"P©T*‰d·Ûý†ž={v„ jµÚ¯å¸}ûöµk×Ç7nÛ¶ ô¸aìÝ»wâĉ™™™§OŸ^óòòæÏŸb±X~ž@9rdàÀ™™™,‹J¥*•Ê Ç¡C‡>üüùó+W®^įp 6,Ðát:›Í>|¸¯‘ØØØè¹^¶¯ 8jÔ¨@¡F(úí¯¯©©III ñk}ïØ±cöìÙ‰‰‰õõõ~ïñãÇû=¢V«u: ~o½^o·Û‡ß´çÎ{ÿý÷¿ùæÐGà8þ|ÿþýGŒQXX¼8Ξ=›F£á=©©©A¶^sssãã㇠‚ÆÇÇ766i<Ž1">>~ëÖ­‹-ª««ëîî&áÙ³g݇»óÓ!4räÈ“'O^S¶yyycÇŽ dþ`a2dÈÙ³gýƉ•Éd¾:…—NòK}}}RRR P«ÕJ¥Rãâ₼n C cÖm“ …B¿—I­Vs¹Ü»ï¾Û·“Q.—‡^'½®®.999íùý÷ßãw¶_aÍÍÍ]´h‘_ Úf³}üñÇ6l}®ÐÔÔôÎ;ïÌœ9“J¥"„8N0MìC‡;Ö-Ž!f±X‚9bqq±§™#‘H‚ämooçñx £ÿþï¾û““ƒß4XËBCCår¹WhWW×¥K—®cèâkŒ=!á;À­×ë{•hii‘H$®cttt „‹_ß@iccc©Tªo'²^¯Ç+2ù¥««K,ßð{Òn·“Éäî½@ý‹Åh4òùüùóçûöSWUUeddˆD"¿ÖeYYYbb"›Íöûš?þü'Ÿ|òÅ_€>Þò-e½^däüñèÑ£«V­JMMÅ{"##ƒQ«ææf¯§qâĉ‡ÆxÌÎÎöl{4(¡äuû0ÀsϨQ£®ÕpëÓ§O^^ž§DöÙgß~ûmEEE GŒáÕóPXX˜(¾^¯ A 0 ¬¬,ø¶¶¶FFF =sæÌСCoø=sòäÉ@çÒÑчt¢££ýš]îF@ ±ï@á×Cß¾}ûœ9s®ãDÜj.T*•Wè¾}û¦L™‚JIIñÀÙ»wï´iÓ¦M›¶gÏß¶ÂþýûçÎËår«ªª¼BǶmÛу>ö Mܾ}ûöíÛ7lØ ‹·nÝê·‡Þ×j0™L‹/ö´,¦Nºoß¾«Z1¾¦ ›Í&‘H暌GŒß»Ù ¥Ré5àü›#‹e2Ù{ï½·~ýz¬’R©töìÙ999xÞÏ@­<_#Ñ`0`¼V.^¼Ø·o_„ŸÏ÷íA;{öìàÁƒ¯šÉ„ Þú5«}ßgnt:'ˆÕÉýZ—R©4..!4vìØ¼¼}ú¯¿þê%Ž_|ñE¿~ýÒÒÒþõ¯UVVz]kü`îØ±ãšn’^7¿Ù©S§<èi¨¿ûî»Wíbï%L›6 ß‹</222%%¥°°pË–- eêÔ©šr#GŽôÚÉápØCBèôéÓYYY¾û³³³ ñ+Ú/mmmB¡Ð·VzÖ…ÚÚÚyóæyíÄÖ™—]é[Ú#FàíÌÌÌÌÌL©T²yóæ_|±¢¢â¡‡Âzç•°²²²OŸ>7üb™ÍfÜØOLLüî»ï®/‡ãÕQÐÒÒ¨£ãÔ©S9998¡×HZ[[[DDÄõ#//gë‹\.‰DWÍA ô0:7qâÄ_~ù%11ѽG¡Pò‹B8p—ÇW͵Zm¯ÜÿŽ"‰ .Ü–áÐ IDAT¼yó¢E‹ÜÆ£ÉdÂ¥Óéf³Ù3Õ¯¿þºlÙ2|¦;vìÀ.½.—«²²²oß¾™™™øç›o¾ùúë¯ßªú8bÄ÷S„Z·nÝK/½ÔC‡wo†ËåN™2¥¶¶Öf³}þùçÇ÷;þ(“ÉfÍšå»ܸqÇŽûðÃ{ì1¿·”F£ár¹¾û‡ ¶nÝ:.—¨±væÌ¿ã$cÇŽýòË/ƒ±›¼p[d2Ùï“ãkèa“‡ÉdúöEIww·ûá …^£%î‡Í/ùùùK—.½ê!x<ž—oyUUUZZZ øEEE¤Ê‰Dâ×'2™,&&ÆoPσ3þýá‡Ãáîš|ä‘G¶nÝúÈ#øFóu¨p8î>(Šç€»Íf;xðà+¯¼‚zúÙíöÍ›7?öØc—›½Dâã?þÙgŸÝ}÷Ýf³¹¡¡Áó£,0{öllB¯.‚@}оþ{HNNNOO_µj•Ùl.((Ø¿¿gk´©©),,,PŸý¸qã"##}ýK®ÚX[²dIuuu lµZí÷•ƒýN¾ûî»@ý‰~m÷Øñ믿žŸŸMõ“žžž——äð‚H$ò„­®®v÷ØúÜ»‡¶µgÉŠJ¥âóùî=¯Ñd³Ù|c4:®¹¹¹¹¹Ù­€111îNFÜ!{âÄ <Ð䥌û÷ïïììtדÉtàk×®õê‹ô<—O?ýð(2™L{öìq7®½øïÿëÕÖö´=?üðÃ’’wíáû¿®®[Ž«V­zã7ÜãÚž¥---}ï½÷Þl‰ÌÊÊZµjÕ¢E‹ÒÒÒÒÒÒæÌ™Ós¯—Ëu¹\¾^ßžÝy$’H$úÔ´µµõ02‹ûã233¯©?ŸÚ©S§bbb/^¼nÝ:ßÁâ@݈™™™C† q·÷};æ/^¼ˆ;<% ´´4;;;55Õo%9r$55µ¢¢Â­æž£%‡b³ÙžoˆÁƒã±û†††ÎÎN£Ñè÷#–}ûöÅÇÇ×ÔÔ¸eÎݦÑhÊÊʪªª<¥!** ÛþõõõcÇŽ]µj•ßWÚþýû_}õU_WJ„P{{ûÀU*•§©ëþöF&“=úè£/¼ðÂôéÓ½vuuI$’©S§>÷ÜsãÆó µÙl £®®ÎÓ¯~Ö¬Yxð÷ðáÃ}ôÑ‘#G|_Ø }æÌ™<ð€ïжÃáàóùË–-ó|ås¹\F£Ñhìv{FF†×=K¡PvíÚå·'„H$Î;÷Á ¦ õ¯€ šõ·Àãñ‚ïTŠŠjiiñº±êêêî½÷ÞžÆÆÆJ¥R¯;/ß”1cÆ|ùå—¾}”J¥2и$‹Åúàƒ°¡7kÖ¬††OK³g½Å‹ûÝ¿ÿ~©Têe_c#ˆB¡$%%yé˜ÊÎÎÖétcÆŒ3fŒožJ¥’B¡üç?ÿñÜÉçó±Yš——÷ÄOxyb_«ÈÈH­V;~üxßv.úý‹š©S§zGàdfÍšUXXøÏþ³¶¶Ö³?$::º¥¥…Ëå:αcÇújknnNJJJJJò 3fL^^Þ£>š——÷òË/[­VÏ{ÉÓk]"‘¼ôÒK¾ÙþüóÏO<ñľ}û¦NêY *• [ë|>¿OŸ>n÷F:î9Ö”œœ<þ|@à™!´uëÖ¹sçzÙ€$ ‰îž¯ÐÙ³gWWW§§§÷ÂçìÇ[€{î¹ÇsL·ÈD"ÑU{ÁÆïûQDÏà îŽÈ¬¬¬ï¿ÿÞ«•][[›œœ(•[û÷ïï5ÄÅ‹ûõëw­'^TTôàƒz GŸ>} E[[›o†Ø3а n´ÖÕÕùJ|bb¢ÑhìèèÐjµ¾nØC‡=sæ ®7:îÕFÆ~õøp¯P.—ëvò§Ñh™™™žãiÙÙÙ'Ož,**>|8Fó rk\~~þèÑ£#""üj=BˆJ¥z2á÷ÇîÝ»g̘úðûƒ˜L&þÄP©TòùüyóæyvºMK<ð‚Ý Ü¯s|'`H2™¼lÙ²+F™Y©×ëýv¡ÄÆÆÎž=ÛS‹½$²wŠ#Ø·\.W 444444hµÚšš‘Hèã-¯&vxxxuuuKK nhkµÚÉ“'÷0já©&Z­¶  à¾ûîC8p ‡Ï…H$Â#øcݰ0ß8 .t¹\¾û™LæÝwß½}ûv¿j’ý¿ÿýL&?ñÄ~û>úè£Aƒù¥¥¥]¼x±¡¡Áo½Mš4 {Õùö-FGG6ì½÷Þókt'$$œ={öÇüꫯ¼‚h4ÚŒ36nÜèw)::š@ |ýõ×~Gç°z1yÖ-‹Åª¬¬ôû¹ºX,njjzÿý÷_}õU¿¥Ý·oŸB¡p›ž<òÈ#»vízòÉ']V¿×±÷ÓKõñôéÓxP"ÈOån{¦OŸ¾qãÆ¬¬,±Xº,ë™gž:@Û6›=sæÌúúú@ÓVè#pGKdÏ3V@/ü@nƒö5ø?úèŸáÇ>!ÔÃ"ëо}}}}}¸íÿG€[JÁÿh_€>€>€>€>€>ün1}ÿG } úúúMMM_ýµß ~ø!''端¾r8p1¸ãô1//O&“ù ª©©ÉÉÉÑh4F£.½Š`ǯ³²FX­W\m ¦Óéèì”»\N„Ëåm0644 „bbb}ôÑœœ¨knO}lkk±XÌxÛl6‹Åá ™@àâ=1117ª@---õõõãäÉ“, .7„¸¸¸ØØØ©J¥R(˜Íf„J¥‘HbètjJJU«už‘cbb<³  @&“544$$$ „¶mÛ¦R©žzê)„‰DÊË˳Z­$ Gv¹\.sT"‘¬]»¶ç²µ¶¶ŠÅb …Òs4©TwÕ3 &ZGGÇ£Óé=Gëììäp8 ã¦L.—3™Ìž£uwwÓéô«¾un`ÁT*‘Här¹7íˆZ­Ön· ‚ž£ét:«Õ* oZÁŒF£Á` í9šÉdÒétb±ø¦Ìb±(•ʈˆˆ›vD»ÝÞÑÑÕs4‡ÃÑÖÖ}C †zì±Ç}ôÑ „¯Ì\¶N¹nrÝÆýŸ)•R¥Rj4ª”JéÑ£¿jµxÏW_}òâ‹Ï~òÉûk×þûßÿ~eåÊe›6}±nÝ»ee…gÏæíÙ³­¸8'tùãøñã¹¹¹uuuø§L&so755åææÖÖÖºðÆo¸®Æ'Ÿ|ÒÝÝ}ÕhÁdd´7Êd²«FûöÛoëëëofÁvíÚuáÂ…«Fûå—_Î;w3 väÈ‘'NÜÌ#ž:uêÀWV\\¼gÏž›Y°ŠŠŠmÛ¶]5Zuuõ–-[nfÁZZZ¾üòË›yDµZýá‡^5šN§[»ví*X °î)•ÒF]–Äéÿš~ ßÏ(•J€ßÞÞI¥R75&“Y©T‹Å‘=$;v¬—uéÞŽŽŽ¾êkáªDFF’ÉW?‘ -ê`¢………Ñh´«F‹ÅWµ1olÁD"ÑUG„P(¼]ÁŒÇã]ÕÀ¿±UÁf³‰Db0ÑìvûÍ,“ɼªñxc+?Èh4-<<üf‘D"I$’`¢]ÕÆ ¾`סÌ\vÜx!Ä)¢ÝŸ5!D§sÍfMié…¡C³ìvBè§Ÿ~S(ÔH$™Í&*•§TÊ“““‚°¨¨P:Ë`ðnlùrrr`lçï*ÿo¤¦¦¦¤¤dîܹP7“Im6kBŠy·íB(÷“Ü ìÇÑ£G„„° „?ì4›Í<ž§ºþŠBÿï*¿÷Ã`0n ™ \Aéch¨Èßõ£ÝpMlmmmll”H$ñññxÏâÅ‹ñF[[[CCCdd$änîÊþRª««åryjjª§ â®'Ï ³Ù\RRB§Ó‡ •vsè]ßnÚ´Él6ÿøãƒÁoÐŽ;t:\6à¶¡¹¹ùСCf³yóæÍ¾æÂÁƒÍfó¦M›Bß|óÙl–J¥GŽz»õÑn·O˜0N§ûv™Ûl¶ &0Œ`zÓàVûúL˜0Á×&0"‘h„ øë²‰'N˜0A"‘ÀǸ½«}"½c: SÀßN§Ãþq&“iðàÁ·ñ™&$$œ?¾££ã€ëÞ»ô‘L¦;W¾/¬¯oŒ‰‘‰„ÐλëëydVJÊïÞ¿Û¶¡òrôú먤UW£… ÑÛo£ˆ´dÉ•?ü©TˆBA/¿Œ~w÷¢½½Ýb±éó Ü™ìÝ»·³³399922òâÅ‹$‰Íf777§§§óx¼ŠŠ ‡ÃÑ·oß[èŒjjjHäÝéþüù†††)S¦Èårºé]ík—ËépØÜjµÊ=8S_߸zõÊüü“WbK¥èå—™Œôz„?|åÔÔ„»[.ÇQ*Ño –䱂BRRRNNNHHvâËÏÏß½{7JNNÎÉÉ¡Ñhð­!à‰Õj5™L555µµµ¯½öÚþýû,X°gÏžW_}µ²²rÆ ß|óMIII¯-tttwwwNNÎÀñž-[¶”––"„$‰J¥ÊÉÉéß¿?BèСCçÏŸã7Ξ= ×½wÙ())mmmoii›?ŽŸà PAÁö:„{ !„þýoôÎ;hæLÄdºçÏŸïwΜ+yΛ7®àKbbbDDDHHˆ^¯0`À /¼ Óé°ç¦F£ ÅÇÃà–×Ç`p:v»!„æâq²ÿîȺzBÙ-PãôB\.Ç_«V«ÞjÕCEöc@~ùe/™|Åå›Åb[­Ö`&LøK±X,T*M¯×º÷Ðhô‰ïºyú¨×룢$!ƒ!‰º»•I›Íú‹æ@§ÓUZZš•5¢»»³»[a2B±±ñ7Õ~t+#•J±ÛmÝÝ]<ßl6¸À•€¿U•J•Ýn%Qdd¸Õjëîîî!þ_2‡ÃåóùD"²ÛmpIè…Øí6"ñx&“©»[a±Ø’’’ÿ¬>ž*•Šc2𶢫£öÜ¡gŸ}ÂkÅO(ŠËåjmm§R©F£ !¤R©N'\þ.pŸÉdnnn±X¬ …BéIƒÕG[Э2¤¤Pvw¾þâƒ6}‹Å±³³+,Lì¹›íL&ۖͶ™ÍÖ®.•Ó ýüÄÄĵ¶vÐé,÷Ò¢z½éÏêciQþšç,iÍž›‡fß’PBhóæ/ž*ܼù‡Õ«WâȧO——W „èt:Ç·Z­yyypaøƒúÉ ²Ù¬7ó ]&“Ñf³ªT*³ÙŒŠëÛ7éOéãÀ¬1sÿÇ'ÿù?—ËõýþRáŠ%¸eËögžyÜ32F óx|2™dµZ.\h ÃÝ€' …Åb¶´tß̃Ö×7Ž1¢««C à9N•J…ÿ”>"„ž}e­ ¹:[›H$B—W |>ï·ßx®q% ­V‹Åã×ôF𬌡¡a=Y¸AæÎ#Åpô¬É‘ÖWÅr4’ÓeG¡™3§ÇÇÇ66Êâ㯬•¬Ñh Ç…Ákz-&“¹²²æ®»ÆþY}ÌL‹F.B(%!¹®ß׿Â3?zÍÿ¨ÓéBC… …’@ <øl€@FœN§¿¹G´beT*UN§S$Üûñšè×/355Í}þ™™ýèî±"„BD"@ Ýä™úôIŽŽâpØ4ÚeQâp87U.|®=½ÑJFqø'ÅIº6ûÑf3"„âãc+Ô&· .„Γëå9þÙUÛµ0ákÐG•JíÞV*P¡ÜNúhÜú(“ËT|µg>Ÿ×“> à‘ÀmŠÏ'Ñ^ŠÇç÷h?FE…Bp»Úõ¨%xÅóÓÿH¥2)”^r>6› ÖlàF™–f“Jvù‹ŠŠÔs|?úH$R¨ÔÞ²æªËe·Â(7ˆIáٓ³ƒŒ|ãçÇýꫯl¶ëìÄܱc‡B¡p:;vìP*•0Ü¢É4 …éþ#“é6›ãFYTjˆgæG@ëîVÔÔÔ]÷‘æ+—Ë++++++ñŒiUUU•••r¹¹ãx¥úùçŸ=êpø©…B3t: …çßÙÙ‰R*•x»¼¼\¡PìØ±#//oûöí~óàhÉH6›Ñýg0hkjjn\³Òé™ùùó¥bvuÉß}wÝõ«| €9sæ,]º!téÒ%‰dµZ Buuõ+¯¼²~ýú+V¼ÑÕÕ…“¤¥¥¥¤¤ 0Ào†Ÿ}öYrr2B¨µµµ¬¬Œ@ DEEÕÖÖ®Zµê³Ï>KJJR*•‹E$)•ÊÎÎÎÑ£G“H$° à6ÃétþôÓoõõ yñâùùù…3fL5™Ì'NŽ“½mÛO]d2yÉ’ùf³åÛo·"„úõ˘2eb0™ÿòË^—ËUSS—‘ÑçÞ{ïIOOKMMrwíÚBééiÓ¦MÚ·ïн÷NÞ½{ߌS¯Ù~3fÌœ9sæÌ™S^^^QQQQQQYYyéÒ%lN~ñŸÝÕÕuáw\.WFFF  Åb1¶ÓÓÓBK—.3gƒÁ°Ùl6›mΜ9Ë–-£Ñhr¹üñÇ;vìÀÁ~€ÛƒÁØÞÞùàƒ÷M:I¡PVUÕ „ìv[]]ƒÍf/))[½zåÒ¥‹øaÇ·ßn]½zåêÕ+ãâbƒÌ¼²²:##mõê•åå•>&-áÁï{ðÁû N¹\®ªªZ„>ú5Ûž…±cÇ’H$¡PH&“ —Ëݽ{·P(ìÓ§OŸ>}Ü1kjjäryMMMDDDhh(BháÂ…6l R©"‘hìØ±¡;wz‹4‘X]]]UUe±XRSSBË—/ÇA‹ î'¸ aöïŸqñb…Ýnwûc+*¼Ñ§OŠo’°°`ý ‚ç\‹žìÞ½Ïétº•£Tª®GgÍšåÞÈÌÌܶm›ËåJOO‰D³gÏNKK«ªªš9s¦Wª²²²!C†TTT¸\.¬÷Þ{/‰DBõéÓ§´´!ôôÓO×ÕÕá+¦M›Æ`0zè¡ÒÒÒÔÔÔÄÄD¸{à6Àårz® hõpCq8••5jµ†H$Ô?4T´fÍ:+„@ ‰D‹" <oÔ¨kÖ¬C……‰-šëÎÁd2 W2Ç39þ~\׎¿¨Tj¬’ùù'+*ª×®ýøÅŸMNNسç B())žH$r¹œ5kÖuuÉ{RÛ2sÙqãq„§ˆvÖ„Îe0x½¤–-­Ñ¨‚» n5}$444x\®Ÿ™ròó ##ÃM&óÅ‹åsçÎ&s•J£T*=mÆ„„8¼½fÍ:÷B/=àt:÷í;”––²kׯ^ñ5ónÛ„Pî'¹d¿Âïpô–¯ ÁÅnE—×´°1b诿î#“)AŠ#BˆÏçòù\¿A÷Ý7%˜ˆDb||Üùó§OŸzmík‹Eg±èàp P(3gθQ¹¥§§^5Ž‘dS5œ¢aD¡fÔb©B çêúpc%ÚÙ þØhvñJ3†Mö63¡²®Ò¾nïè*-½5Àí #†„Þ;ÝȈá¸C¯ècddÄСƒ¡î¸½QtÈâýI¢$2  ’¤G}t9v»E*m‚êàv&”Š|fp4™Œ*U7›Ív~ÚטEKžË5ÚÏ4»·>6›•Nˆ^ý‡½.¤í4Èdm™™þöÖÇHIÔÖ®#@¸ iinÚü͇™m‰Ri“É ‘ÈB!_£Öò’’âââ¼"ƒw4idÚ0†‘ÆårÂÂÂY,†B¡ìîö³áµù÷h4j<p} z»V@€^‰DæpX!¡PàWÙzÒÇ“'òÕª?|ûüÅúýærêdÁñÜ£Áhﯿ9¸ßó{r÷þ OI§ÓóÑá¹’3¯¬~A§ÓþùJ,,ÈW©”¸…'ü.{{pßEw÷ïõ–÷î[92i#Äÿ­û`ÛßÙív„¼«kç¶á¾€Þ€H$r:/Æ„†ŠðC¬>Ž=æÇ¾sK使Mš2H$"„š›š4jusS–˨˜˜ƒ»mL¯ OšdÒ––f§Ã;š›d8ÿ‹ÊZš›››dXûð6ÒhÔ:étºõý·¢ü,Oô:N«×éœNÇ !Cã-f3BH¯×i4êæ&™J©ô-R[kKs“ «žF£Æ?ñÔ“x»¦ªÊh0àÂwv´ûŠ{AþñÝ?ï4ô¡Ó§NZ­Ö—^Í9|`_·\¾iË{rØðì]Û·"„ââ ½¼«nMøÛÑj ÅÅgñ_]]cGG—W„«ô?>õ̳ï½óïU/½B$/]¼0ážËß~ÿóÅ•}û DEqy¼ûf°÷·ìQcbãâ·|·ù¡‡çñ÷A·ýð}·\ÝÑÞþIJg8®§´ÕÖTS©T½^?ïÑEK—,˜zït‰D£Ñ"%QÕ••TõÈá'Oñ,¼.oÔ˜»ðvc}]ö¨1¸Hz½N¯×±Øl›½í‡ïp6›£ÓéBÅapwÀß‹@ øÍm BÎ`íG„V«a³Ù¾ÃÙ™}û‘)ä9Ì/¿x!ôÈü$Ò嬞\¶|ã†Ï©4š¯8z)‰jokkn’EH$ yØð.Z2oÁ⪊òªŠòûgΞ·`qHÔƒ5k ÄIDATËjµQ)Ô‹Ÿ·`qbRrjŸôÁòf?ݯÿ@P(sN;gî|2™²kÇV£ñ“„³Øì޶6­Fë°Û‰D‚‡ D±XìŽöö³gгGýð\Ï„Ñ11Ÿ~²néÓ+Bz½^­Rµµµú-CAþñ–榇ç-0èõ÷Ï|ˆÁ`îß³[¡èöŒÂêêêt:]y¹Gïž0©‡ŠêhoS)•íml6'kÄȳgŠH$²Ñh‰Bcbãª*Êåò®#GãÈò®ÎÐP1ÜšÐû!=õêSR›!Dk%§E%ïúyÿ¬‡Á‚XSU9õ¾nãQž{øà !ÇÃzß ‰ÄápÃÂ#öìþY( ¥P(‘‘ƒaÀ Áƒ‡fÕÖT‡…G:pTTô}¿Õ×Õ 2,6.çƒâp¸“¦L;rè@}]íÀÁCâÙl¶8,OBŽê7``î‘CᑱqÞ³Ëõí7€ÃáÆÅ' „ê5jugGGZŸ ' #“)!,–XF¦PÌf3NŠŽ ˆ<~ôpmMuŸŒÌÔ´>žÅ7~baA~MuõŒfJ$Q*5й>¸Ÿ@$*º»{¿itzþñc³z˜Åf÷í?  ?Åb;!T~ñ‹ÍNIëwü-hµšKeEÙÙYííQQQNç•1¹\) -${µ³!ÔXÜè=øÜGWlݹüø-iinÚºùã^XqîÜù¬¬á6Û寫Ëå*/¯ËÌLöœ?ü*ým­­:­ê€;žúìÛÓÕÑ¡Ók]ø‡Ë…ÊàŽ¢'û±ì\É‚%?óì?>ýäC¨)@€«ë#!¤×ëY,6Ôw=õ?N™vß»oý+„ÅZþÜ? ¦}¼Bÿƒúu´¯¯ž‚ø{1èá*Àß­'Oäëu:Ï=ë?ú¯ß¹Å‚Ÿßìà¾=ÇŽ¶úLspßž Kl2ƒœßì—Wëõºž£:yB«ÕxîùßGÿÕét~Kþg*'?{¦¸[.÷ÍÊl6úɺwßÊÙ¾õ{‡Ãn6›?ûߺm[¿wØí¡’3Eユ#“Jqä?þÐÑÞ÷.üú8rô˜Í¿tK䑃ûïžxžßLÞÕeÐëå]]x~³¤ä”¡Ã²~·1 ^žÔTWÕ×ÕÚ„P·¼KÞÕ‰%¬ô\ þ‰3ì–ËÝAƒÁd4⠓Ѹþãêjõ>f2]ÖM¼1hÈÐèØX³É„2™LƒAÞÕé+|Õ•J…BÞÕ‰gŠ4›Ls™ryñEw·¼«Ó`08ŽÒs%ø'žúìêf’wuâ ³ÙŒ¥Õj±ðÉ»:µZM鹄PKK“Á ¯©®òÊáðÁýS¦Ý÷Ò«9.„dR馯¾˜;ÑÐaÃwíø±ìÜÙn¹ü¥WsrììhG½{|Þ±#pïÀ_ÍUæ7[þÜ ï½ó檗^%‰e¥çV®Z÷?»ìñƒ†E"ITÔ”iÓ÷þöKkKó+oü!ôÍÆ ó,>S|šÍá Ëá•áŠçWáã¹Gjkª‰D¢Éh|òéŧO‰BÅ!,,œÍáÖTUI$¥¢{ùÊU_}¾Þår±9±8,!)ùÒÅó4:}è°¬áÙ£Ýr§Ó…b0?ïÜ1nÂĨ¨èï6}=ëá¹Á•i)~ønsgG{Xx„J©\úÌ «ÅŠ•”Á` „¶|³)<2R¥T>¹ly{{ëûï¾óæ;k""%E§N–;K¦Pä]+ž_u¾¬ô§?I$>_ðàì9ž'õÕŸ2L„P¤$J­RVWUFÇÄjÔª…=ùã–ïètºÙlV©T¡Ìò¬7÷Íx!TR|Z(%$&iÔ*.Çåñ¶oýžL¡dföCñx|µJŸèž- €ëÆf³›®Lèåºf}4 &Ó÷sìþ‘)ä…‹ÿà½w¦L›¾è±'ß}+=½båûï¾=dX–¯8z"ŠŠ'].Wß~(ʰá#_ú4BèÝ·r8îüEK8î§Ÿ¬³Z­T*u¸<Þ¹³g22ûÏõðÜù<¾!´ïoxÜô̾.Z²æ7W<÷‚ÑdôGÌO-‹7nøÜd49´ßd4"„ÒÒ3B=õtxxÄæ¯¿4 ©i飯ŒÅIdRéè»Æ‰Åaß³)$„ÕÀÀ'–-Ç%ôÊœÍæ´·µ"„¦Þ;ýxî‘Å/‹ÿqË·:­V§Õ<óìó~SyQR\¤V«'Lš w-ܪªªº<&«NJJ½}4_ñÙò•/`}œ0iò‘C&O½‡2L÷üfŠn¹Ñh4 !!!¹G¹ëî’âÓƒíá«D£É¸`É2å‡ï6h‰Ó •RiµXÑCšñ„’ C©Tž/+6<{þÂ%ž ##%øþ“O/Ç-eƒ^¯P(B‘סç>ºÈ½]ûǦ®ÙlÖëuJ…",<"5­Ï¯?ÿ„Züø“~Oáí½öôŠçù$*zÚ}÷#„¾ûæëð?NYD"‘ºåòºÚjÕWªð¢ôlI]mÍ„I“»år¾@[W[£Ttš•˜”\z¶D ©Õ*<·Ðù²sý€_üY(¢DråÅkÑüáùía~³KÎO`¦Ûx ˆ<°÷·!Æ&3dú3I$“)ùqËw‡D"I¢¢TJåaYC³F”_º) T²¨¨è]Û·V\º8hÈÐø„$œBˆÉ ™zߌÝ?í¬¸taÀ Á‰IÉ &#<<‚D¾,åÞ³ûçP±8>!ÑÛª0ˆÉ IHLBÕÔTw¶·5IÓ3û±Ùlqx8…B¡3èaaá åŠÓâ°0 …JgÐÅâp™LÚÖÒÜÒÜ”–žÙÖÚªR)Ù,VqÑ©ô̾È]B¼ÑÖÚÒ'=ƒJ£ÙíöƒûöTU–/Xü8‡Ã £Ñh4:],‹Š‰=¸ï7—7xȰjÃh4ÔTUTU–WU–'§¤>âèáƒd2y¤É|€N§ïßóëÌÙóø|„Сý{ÇOºwpMxÎoF§Ó<ƒX,6•J†ùÍ‚³½++~ýy§Óé¤ÑèO.[ÂbAÀ­Žçüf\.Ç3(,,’Å¢yÎov•þG“ÉtÇÚ)i}ÒÓú¼÷ܱ{Ç9ÞëëÎp§ëã†Ïþ7jôX¨#@½yö/0 @ú¸æí7‹O®yûÍüã¹PSÜiô4~½ú½ô10' òØO£Óþïå×ñäwzûúä‰|³É4rÔ&+OQõè#B=æóõã)Â@ÿÀÊU«?þp­+ˆùhî,}´Z-*/dúèGëú>\ùÂjôÐGΗž[¹j5Ìåè£7C³†„“ù§O¼÷οРÀÄÕýGŽ3rÔ¨)@îÂã<—åb0B²> 2™@£]^mÅét¶··I$¡žà“îPÇjµ¼¾®-[`î·‰Èïû™žID…^úIeǶZm+LÆRéÞtêËrzm­ˆúÀÊé÷™L6•-Ëv]—(as³vÝÊ1F"ûÂô‡‡É¨ª çþéé‡zýáògüŸz=Ölî¤R’¦•ŠEÕ²ìñØ?=Úß“ÍæëõF¡åÜGq 1”Å[|4ÍÇñøûÙÙÇÁàëüv`ÕqÎ/.tËúÊ‚(M§Ó“ɤÛý¤ªjø ²V:u9ÎHQ ûÀãæc.—×´ÊìÖ²Ü\.~ÞEBÀÊ‘å\&“šVù›l·èɉæãîîÓùÛV«AäµZ V“9•'þ çË|üyÇ·ï.ž&×ÅÚTôäã¯g¿ßxo¯Ž6Þ½ó É`ýónˆµxç÷`íI/Ó$ÝÔ–ân˜J Ù\ r£wC¬ý5–GF‘„IEND®B`‚snd-16.1/pix/bark.png0000644000076400007640000001222011147553266012567 0ustar bilbil‰PNG  IHDRˆÍúÍ^ŒsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØÓ¸&IDATxÚíÝ¿jÛ¢àµ7îÜÎ)Â}ƒ´ nÔÚ¤1¨3®6¼@ ¿€ÁìÊ.¸¤1v«&`8­ß`ãÂéÒ¥Þ·Èåñü•Fó÷û D–F£Ñš™5ë7kÍè·?þú;0y¿+DÖöâ?ÎÎþP"r{ûçú±DDDDDš ˆ³ÛÙÖ:»­ÿÐ{]„ÃÕÙ*÷oºQ¹±‰ —5ÕÙJO"ÀP¢^>€ñ«4Ä´ËpX§wQˆíÆýü!œ,3_{>Úï¿ýTHW×áæÓ¹‚`±KUBŸ!ªB¢Ûó3L7 >í‡ç£ýZÏ7õ¹]}תß+oú¢ùã°“!¦Éϼ;–vù3ñpÇ*›Ôö0Ëô÷HǪÓ͘X@L_ãÿ]7Ü¥Ö¢ËËä…œ¬•<. Féà•žW:hUùì¬÷lÐ’à×Ç` ô8 n›œ_S’@”Õ#–õ|ÝÅ¢é²YQï^=véÏ,›G•Ш÷&Ç"k¸dÑó»dE¡+o>u–q“ YÔÃ)€€HÍX'PåM“÷¾¦†˜î"\â$B_•`V6„4´âçâ÷lÚY´ÜU–'/€æ-' >ìÕy¾N *š¦N/á6˹í|ê.çýü¡r`æ­ÅÕµB 7~WˆˆˆˆäÜ]Lg·3k­§îçádyœùšßQ¬fqun>+Ä*Vg+¡` 1@@@@@@@@@@@@@@@@@@@@¤'žöB‰ÅÕµB@@@@@@¤ÈýüaýxLÃ3/N/­\ˆ½¡-ðìv& ‡€€Âêl5‰ÐÐ6CL‡é~þùøùhTßóâôÒÊ‘©Y\]+™º¸4ml½¢6c³7´žÝά51„ÕÙJh쉢ÞBŠé%  1@@@@@@@@@@@@@@@@@@@@@@@@@@ {C[àÙíl4…?Ýuwøb¯±«³Õ¨C#@W 1e2¶é±}>ÚW€[Z\]+‘qÚ v /í–á¥"¶‚’ï   ²½§ƒåúñØ®}»8½´‚@@@@@@@@„QðˆÛóÓ"""ƒµ7´žÝά51„ÕÙJh¤ÏGûáý·Ÿ bK‹«ëpóé\Aô!¦ˆ]ºŸ?(@@d|î_ˆˆLÒІÇnº¼ÏGû.ÇâêzrÛÊ¿3€€€€u4Ý+7VzÞ詽¡-ðìvf­ˆ!¬ÎVB#•ÝÏ6zßóѾÂÛÒâêZ! Œ!¦ˆˆˆÝÛôº8º/×& BN¸º;|Q(¸a """""y:X®ñ®™}¿a‹;•Ž    PÝÞÐxv;³ÖÄVg+¡` 1…ó“ˆÐ±ûùCí÷ø D@@¤×¡¥¯î_¬Páp=%" $6ÈMwt?ÕMºvi¨'vW×N¨ˆ€æxiìb@@„C:ûß—ß@ìCÀh³¡9Ö@%(ª[@@„ú…ÄjuäóÑþúßPê«dè©z @@„CØ:’ò¼8½ìõõM55*éCÓüìS . Îngoþ¡1Ö—`f¹˜ =zåõÔÐOì ‹â ¬ÎVoþ½õt°|Ó›Ø÷†GÝëõâéóz¿Ê¾óЬYËßD-.˦·›>4 ›\†*óšJ£9k{L?'$ÖCûÌ6¶wA@@¤¡ÐÕFã©›ÓllºllžDvÇü¹C †C'(ôÞ"^Hüð}þªòþÛÏQ7Ä.N/ׯŸwþÇÞˆJ—#ì¢nØuÝq?'ËãÁÃ6dÝ:³¬ŽÙe[\]‡›Oçv4€éAì°!µMHÜeC£Ëp˜745éK†Ûvyv>YÆ!Ü&««®ßÅÕõ`Îè·}Û.˦oë¤ú¢o=‡u럾ö&VÝ–ôìÑÆ~2öºDZRMWÄ]--úÎÉrõ%$ÑÝáKaƒ;~¦7}ïXCbÝ@æZÄá†Ä>nëöØž@@¥6L»‰÷ó‡^†Ã¬ð‡Ä¶¨UÊh!²©Ff^HÌ;f=?¤àXöoˆ >.÷‚bû`¢Fsµmص¤Ýmǻʌ“ˆ£m$uqãš6…¬$¤9€o‡”ª ÆÔë‘Ò»\w}?™4µu•cÓ6ǧ©5¶’²jêäë¶m†.÷õ]l»uçY§~ ° ˆ“ ‡M†Ä¡„>\8äá¦c=(tµ=w¹-®®i„V. ‡Éÿ}ê=L~ ¨¬.ÚÉ¥äºç¼z/ë5'ÐÆqœrïü¶ÛàP/{°ýï¦Þ®rìÏÚ^l7â¤M†Ä!»;|ÙyoFŸÑ÷àEw·ê6Zôû…»ª£ÚÞ/²zÂò¾[\ÆïKžj]YvrlèÇ„º£š8)”UFñÝ_Û.ÃmzÈò^¯[”5Ø7-“²÷Õ½iX“aÔ1²ýéõ6Æßl…ÃNCbÜ(¨r&fl;MºWúÖ­R—lÓ š„Äø_Q¸Ú¤î*Ú¿ºÜ÷ŠBbÑwN^/»þ¬ÉFK£âÅx~§—áîðåÍsCmhÕ Ce×Ko{b ÎûªœÄÈëÝHþN¿'þ ¬ïºm[¤Éaµ›”ÝóÑ~¥m,kš¦Ú;›ó¦ßÓ×öí&70ËZ/Uz ³^ËÚOê+Çr9€(î,(Nai2, œarÛÏ6uÀ&¡$ ´µ­õ4nºôáMÖwÈž74Wê Œ§-Z_uÃMVûm›ãñÓÁr½ÝæBñå ñ¶¿žlÏ‹«ë_mËÔ>×D¨-*¿¢uÅŽâìv¶~¼:[mü¡MÍG0¬×XJS½iArðL*¯MãXÃí„Ĥ—ð®…í=ÝøLoóI=VÒܺûÛ®öµmëá»Ã—ð´á²Å àôɸºá°¨QÜäþ>¥‘ë2<-íécBü›»ñ¶›ÞÓ!+ÞæÓ åä¹ÅÕuæty Ûõ»¿~µOf­Ï¤Ñ~—Ú¿ãï‘6ò®¿LBöóÑ~ä½I¹==¾ËÜnã÷'!2„Pé¤Ë—¯Ÿ ÷©:ûÛ&á¡N0MNºÇÓ$ë"Æó擬›¬žð¸¼’÷ùúùÕúŠß?¿?±r—sŒˆ·ôöZµ^I¯ç¼“ñ:L^O–¹n,ŠÝtàžt@œÝÎ^…¹ôßmÏG( ¹;qÕÚXz7 MyåSԠưŽMÞñ§FzÞglúÙÛ.ó.ÃbVC>½¼YŸ¹épØÌëú—¯ÀÛ”³:§ÇÑxº8½|s¼ùøø.÷Äk}1>&Çòt@ÍÚF²¦OoçyûAÜc~.Cøúù×¶<ÿçý§Ù'+’co²$¯'Ÿ™ÕàO–#>nW wéX“×ã`R°Ëæ¹m=—õ¦ÇÙ‹ÓËìÉs§áÕÉ«»«—õóß…pú’ÛfÊ;é°^‡§õÂaiÝ™s‚ ïÏ›éößôÇÁ8½NÓ²NðO‡Ç±ÊJ1+Ä­ÎVµÃ]Só·k„é…Ò0C°n;8§ª»N»«€»ëÝæ²ÒüÉ•»Ã—pQ!Ô|ø>3ÝÉòxÒ¯ø>! 9ÞŸŽ[Éôáô¿Ç³tpŒ?#éÉLǬœÙ€\6¦ãÌxžU·ñxÙ×ßûñuo}:ÐÅuËÓÁ2„ÇeøxÖïÍ;üáû<<üšöÃ×·¡µê ¨ßç¯BTzÔRü8îEÍ ­e'+жÍthÏ;QV5çõòÆÏçë¼2ˆÛ¤ñº-;Á·^Ÿÿ”÷ºwûŸé¾„ùº o'!„ð4XO—¼‡Ç¼kaóŽáeóÂåP‚å(®Aü¿›ÿüwÅW”l}þ »¼®ý¬ÿaèpè‹M{’’À—üÿþÛÏu/Hò8Ýã‘40ßûn¾ýz|²<ïÃ?×Ožþzo|ÍX!„åy¸‰žK¦¿ùöúùxÚ÷áç«k_M·¬×h½ Ç…ïY§\nÖ^/Ûòí÷Y—Í?ß7k™Þ”A´,YóKÊ7]Feå”^…Ë=.š6sùó¾WÅò˳Š÷QÙ¾Ï(ëøù¬×ÊÊ ì{澞±œdì'áøÕv’7]¼ÜI¯cÞw©›˜6}ýtZúšÏ]Îß~üøëïä³³?2'Êëák¢±l>ñõŠEñß‹ÿm=”¶ý™CZ&ËÒŸeèê³ÛþÜ6?oןÕÇúl«ÊÜwײO±}´«Ïkr¾ÛÎkÓQ™··®÷¾±Ò—œèMWš4šŸ¹hýÆ£ýþ]7Ù§e²,ýY†®>»íÏmóóvýY}¬_À¶ªÌ}çq-ûÛG»ú¼&çÛƒõò»š€Ê1¹Óh¬ìºÁ¬kë΀öTbšw›†º¦æ@G±N˜+›N(èŸJ?sÑwe¿ N´²Å?sá&5ˆˆˆˆŒ; ºÛ0&ê4Ðè, þë_ÿcM0ž!¦ÏGûëy¯t]OÕ_Û>Œã˜Þå±~ïÇ¿F±‚âîØøï¼Ç}9”ÕWê4˜Î1½ëc½kÔSƒ<w5Ÿ6ÜÏÂýü¡—˶¸º¶QŽé#6º»˜:£ÀÐ,¢pÐ=á€!Ôñ‰ô5çéç“ãAòZÖ±¡ÍcF2Tôdyîç¯zãa¤]öÆÃFo>¯Ÿ»ùt¾~-y>ozÄÞ5² e€¶ë©¸.Ê«£ê>?vy7"Ûäe]œPŒÃaúÿ8,v“ ˜õwÞã¼éÓ·?¦w}¬E@,+8Áès=•÷ZÝç§|.*£®Ãa‘¾Üˆ&ïÆ3qðÚ;¦wy¬Ú³Šj8ÌnZtàîSHìËÍh„?¿+Æ«Š‡î¤çÑåOaTíMÜõO`ø €iÓƒÀ `Þ5曄ÄtOâ.{Ó½…ÉuˆY¯'Ïç]—ØdÏc|#šäï:!Rï#À¸üöãÇ_'œý¡D˜dµ]ÝÈ€q»½ýsýØS&o(7þصW=ˆL—DB!ü? (lŸY"ØIEND®B`‚snd-16.1/pix/intro1.png0000644000076400007640000003615511147553267013102 0ustar bilbil‰PNG  IHDRTÇF«ìsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØÍ–!Ù IDATxÚíwXSWÇ¿Y„$@Ød‚Zœ8±Îªo«­V_WµØV[µuÔÝÖªmÝuÕ*j+µnm­«¯£î**ÔŠ¢€€€ì½²Þ?(WS2€$ä÷yž>^L˜‡‡®®.ñ=<$¸}û.RRRMRRi“w…¸½ˆT*Þ=¿2ÇMšøB$jÄ9þ/\»v£ZyGG?ÆÕ«Ìñ¡CÇ——‹Åðñ1ß$^zzŽùsÝ·niþ©icÙ²5•o,›€ðù|z³ˆÉöí»õÿ/œ8q¥¥Ró´P sçHÜþÕzŒÁž=¿¢K—ŽðókÌœ l_߯q‹ŠŠ±bÅ:æxÑ¢yàp8U*\›6-ѵkgsYøþû-€·Þz9âÄŸ€ƒƒ=œœÇŸÂÏ?ïÇÜƧŸ~'ƒùúú6Æ¥Ká€ììXYñ`kk …BM›~„‹‹3Ú·oËÄ¿ví&þøãà•Wšbôèá¿??_H$®Œ(W´îõ!•Ê€i•ÆÄÄ!?¿gÎ\€““:˜8ñ=xy5Âòåk±ÿ!”””ÂÍÍS§N8ð;>|Œ€?æO¦¸¸Ë—¯eòú꫹(-•âÚµˆŠŠFvvÚ´i‰aÃÖ¬ÙˆÜÜ|Àûï£Õ ÄKÁõë7qüxùûÚ¼yÆŒ j w¸‡ÇCDÄ-ØØˆ0wîtãuúôù¬Ñ»wŒ7’Qò1c†cóæíxóÍ×õþþ‹/¾Á¬YŸ0dzg‰5k–Vé—.] WW´lˆÏ>› øæ›U˜3g`çÎ}LÜ.]:áÙ³T<~‹æÍ›ºu Frr „B!z÷îq•òmÜØ I€ÜÜ<ðx<ØÚÚ@­VcÒ¤Ìû€IŒH8p3g–—ïÒ¥+8uê,ßzë ´iÓòŸ{ˇLV†>}zaóæ™îOÅŸAÔ8.ÂÂ~`ŽCB¦@­VãÔ©³ÈÏÏgÞ×)S>ÔÛ[­hq¹äç×B5;;;‹2%/^©vüž=»V)npp„…í‚R©bZǺèÓ§¾ÿ~¥Æ¹µk7!++b±Âï›èz/côèá:Ãsrr‘’’ŠV­ÎK.—cÅŠ%°µµaFsÝG‚¨Mz÷î~X]¥¸™™Yxðà›U)¾^Auvv‡S9Ê;cÍšxú4_}µ‹/¬_ŠÓ§Ï!"â&Mz½{÷ÄÔ©j4»üñû*¡ŠÅvX³æüøãÇÃÖ­ëñÞ{£™ôºu †««3`ïÞ_±oßo€’’RŒ9”©¼õëCqðàï˜0al•+Íf£k×Îpss{Ad˜8ñSÄÆ>AHÈdlذB¡­[·`ÊÔŸ~: ï¼3;vìÁ”)âÂ…¿0`ÀUÊW"q…““#“^³f6lN:‹ÜÜ|æ|ÅõÀ¬YS2ŽŽŒøÿý–Æ•¯câÄ÷зo/|úé${1{ö4p8\8;?W¶µµ…@ €‹‹3>ÿ| ‹Ã† ¦7‘¨WTÌ_¼xlmm  VÌ{жmkL›ö૯–âîÝ¿1uê,Ìœ9mÛ¶‚@`?þ8…U«ÖC(`Îýc¨¬øø{jšl°|¾øâ|üñûL—Ÿ óSžÙ… —u·P‹‹KpåÊ5­a¯½Ö½Æë´ª‚Z­ÆŸž×Ö¹sˆÅvf­ÄK—Â!•V^:Ѻu‹JãɦææÍHäääjbÓ(‚¨"ÙÙ9¸uëŽÖžgß¾½ªœNË–¯T+_‚ªR)‘£#L]+¢ …Baö¼óòòQ\\\é¼LVfö¼ µ^ûˆCàììHo AT¹\¡õ=âr«7mdhþ„ºüAfàÂ…Ë´—Ÿ ÂTp³²²‘‘‘I5AaYYÙ`¥§Ç¨•JÕA„±-T3NØA4h • ÂT-ÔX,ÔjJJJ!‰ V›n8€Íæ€Å" 'âå@¥R@­VkT‡6›ƒ²²bܼñ7z÷é …¢Ôd™[[ۃϷ¡»@ÄKAaa: ©vA-V#™•¢^ö¸Íy°Õ(Î*A»–xô(†±r¤ @.·ò>}Z”NDÃêò«¡F‚"éŠôòå¶Žñ8â1ºôm‰½{e óxVpwwGbbX,  ‘¸ÀÚZ_<~ ‡.]‚©¦ ‚hX‚j‡ÃØØ hŠøø'°µµ—Ëa ;;;ÁÕÕ ¸\œáââ @IµM jå.¼#Š288ØãÉ“ÆffyË•€@ gg'(•ÕRµZû÷ïƒÏç£iÓ¦ãÇÆÆ¢´´ŒiÀ˜˜ÆÀIãÆakkKw› ËT''Gäç—[¨ww— -- ‹Å`³ÙP©”°±¡  °ÚéïÛ·©©©P(hß¾=úôé£3îåË—qåÊðx<ܾ}ãÇÇÅ‹qíÚ5Æ"–L&ÃüùóénQ»‚Z˜Qˆ¬ü,seÅ2æ»EEE̱µ5"‘jµ<66vxú4‘ OHxŠ®]«^ K—.A*•bæÌ™P*•X¸p!Z¶l©a蹂¢¢"üöÛoXµj¸\.8€'NàáÇxóÍ7ѪU+@HHH•ò4hºvíŠ9sæÐ“A„q‚*`Y£«5|UnxƒV­[B©”ݪbí( "‘*Õón<‹Å‚@ €Z­†R©ÄÓ§‰ÈÈÈxaxÀ¾ZR(LË’Ãá@­VC¥RéP*•ŒI.+++ÈårXYY¡´´ˆŒŒÄ½{÷ª”wAAJKKé© ÂxA個¦nMPæ Aq² üƒ4Ö¡ÚÙÙA "*ê¾–Öb)||¼ R)5\jðxVµ~QS§NÅŠ+°{÷n¡uëÖt§ ‚¨ý.¿>ŠŠŠ 5ÌÝÝ4–ìmllPXX>î*“ÉÀáp4ŒÂÆÄÄ@,ÃÕÕlv¹ûÒÒRäççÃÇÇ0wî\@^^îÞ½Kwš ËT•J •Š @P)ìE×ÊÆÐ©S'äää`ÆŒàr¹1b\\\˜ð±cÇbذa˜={6D"ÆŒƒE‹¡¬¬ ½zõB¯^½+W®Djj*„B!¦M#ÈAX˜ ÖýúõCpp0Øl6ìì4ýG9sFC¼Û¶m‹&Mš@©TB,~î‡þã?†R©ǃH$¢;MDÃT°·×>™¥m=iUÏA˜2ýDA‚JA‚JA‚JA A A ÖæÎ‹„„„ ::šžÂâHMM…L&3{>ºvAÖ76n܈ôôt£®µ¦uÑàuÅŠ CXXš7oNo/aqlß¾ÉÉÉF¥±k×.ƒq/^lt†¸též>}ª3üÎ;¸ÿ¾Qy¤§§C.—u­†ÂIP â%æÆzÃÏž=kt†Òxòä V®\©3\¡Pà—_~Aff¦Î8qqqz[‡×®]Ã'Ÿ|¢ái´ºÄÅÅ!77Woœ²²²*[©#A% A¡P˜Ädä¦M›ô†K¥R„††•‡\.g¼`hC­VëmÊd2üôÓOF•A©TbãÆ5òRÁ©S§§7Naa!vîÜI‚Jõ‰»wïbôèÑ»¨ú¸wïRRR wTT”Qe½~ý:vïÞM7• ꆼ¼<äääèsøða”••Õݯók}òä‰IÒùüóÏIP ‚¨ÌåË—qþüùq­_ýµIÒIMM5:_~ù…• íLœ8ѬéÏœ9SÃW\}§®þÄHP ¢`Ì«%¤_[¤¦¦‚ÇãÁÙÙ™• ê*• 'Nœ Š0!±±±hÒ¤I_RR6› kkkT‚¨o‚Êø@ÓÅüùókœGzz:d2¼½½Í~=={öÄÅ‹ë´N£££ëõT‚0‚£G\ž––Vãô T*ãZÝœØØØ¼Tã¨5%22AAA5ú-·¡WÞ±cǘFFF)A!ÈJ¥%%% …õö:âããáëë[£u» ^PÀçó VZQÙ»w/F¥7Ž››ÊÊÊ››k6A=qâú÷ïo±õÔàµ[·nÌ÷eË–Ñ›C˜”ú>&øb«ÍÏÏϨ-Ÿ¦ %%5ªñïår9233áîîn–òÑ*Aè@&“鵌T¢¢¢Ð¢E‹:½Ž . W¯^u^Ÿ‹/ÆÂ… NçÛo¿Å_|QcAÍÈÈ0J”IP ¢dffbÛ¶mõþ:Š‹‹!‰t†'&&B"‘0C_æ¬OWWW£Óquu5hï´® A%|ðÁfÏcÓ¦M˜N‚J&äÈ‘#4hE”eòäÉL×”²²2(•Jºé$¨ñòãàà€¼¼<³¤••©Tj¶™qKãîÝ»hÓ¦ *AT‡ &X|¿üòK£íŒ&&&ÂÇLJnxyúô)¼¼¼HP ¢ª8pÀ …yðx<<{ö¬ÎÊ©V«š´Ê-úwìØÑ"ê}ðàÁøý÷ßkôÛüü|ˆÅbêò„¥‘””„ââb½qø|>ØlvèýùçŸøÏþC•ý52èÿJ›6m”)SHP-™¹sç"$$!!!ˆŽŽ¦'ž0†5))©Æ]ËúÆùóçñÚk¯Uë7wïÞ5èpÆ HJJÒ¾wï^ìÙ³Go³gÏ&A5+V¬@XXÂÂÂ^Š=×Äs~üñG½á}úôÑékþêÕ«èÒ¥‹YËwðàA >¼^Ö! vìØÁ—––VZ%0eÊܾ}[g2™ zóÉË˃B¡Ð^XXˆ%K–è ŒŒÄ©S§HP ÂP«ãèÑ£zã4oÞ=ÒöäÉøùù½4õaccƒfÍšáöíÛˆˆˆ0èeõÊ•+zÃwïÞE‹é W*•¸zõªÞ4öíÛgp-èÕ«Wun°(..Fdd¤Qõ’””dÒõ¨$¨Q´µ¸ QVV†üüüJç‘••سgÞüÔ©S"’••æøÆÇm÷íÛ‡„„æøÐ¡C2dHµ®å§Ÿ~ª•zÞ¹s§NWÙÙÙ8|ø°E=$¨Q®^½ŠW_}U㜡Ùë‡",,¬ÒùE‹aÑ¢E(..ÆöíÛQRR¢3ôôtüüóÏÌñ¼yó4ÌNæææâ¯¿þ2Xþ9sæ0ßSRRàááaÒú±4¡«.B¡666Õ6:O‚JÔK>|¨3ìñãÇpvvÆèÑ£MêDO_žðÙgŸfÐGqq±Î1Ý1&ª˜˜{{ûJ³ñ;vÄíÛ·¡R© ¦qìØ1ØÚÚjm‘×A‰DÈÌÌ$A%^n¢¢¢0xð`ár¹"‘Hë’§¢¢"äååÁÓÓ“9gH$T*V®\Yé|¯^½ÇvR©Toë²¾°ÿ~´iÓÇŽÓ8Ïçó!“É V« ¦ÁãñàïïoðOÈX¬³5¬P(¯akÇŽ?~¼¦²ÙUú“ A%^JÒÒÒШQ#\¾|¹F¿—Éd(--…½½=sîý÷ß×û›>ø@«øûû#&&¦Êy_»vÍà„>RSSÍfmÞ{!¯¼òŠÞ8­[·Öé$Q¥R!''GcŒ9"":uÒˆ·fÍÌœ9“•h¸¼ûî»øå—_L–^NNBCCk¥õgL+6::Íš5{©ïmÅ$¥x A%ˆj"—Ë‘˜˜hÖ<ÂÃÃ+Md•™3gŽÖáT‚ÐBbb¢^ÿï©©©9r$âââL–§¾.ݱcÇ0pà@“^ããÇáää'''4kÖ =ÒÚÝ$,—>ú¨Ú†»¤ ªT*”••UúTe°0žƒâóÏ?×>jÔ(888hì´ÑÆ¥K—ðøñcìÙ³G«éºŠÉ†S§NáÎ;•Â}}}‘œœŒ¼¼<£m}8p#FŒ`Ž Øl6Øl6¦L™‚~øÁ¨ô_œü²DÔju•,å×ZKÑM666Õv Ã5íE° ‘h®gãp8wóoÞ¼©uarLLLµ÷Õ#++ éééz·úúúbÁ‚ضmRSSQXX¨ÑRˆ‰‰APP>ûì3„‡‡#$$©©©•Òyë­·‚   äææV wrrB~~¾I\ܹsmÛ¶5[½ùùùUyò«{÷î¸|ù²†‹ô ²³³acc£Õ!Ÿ¯¯¯ÁÝMØÚÚ(ßÚ)‰Ž÷ßߤËÔŒaÔ¨QØ·o_ýîò³ÙxxxÀÎNÄ|-î¥îÔ©¶lÙRéS×~yêiiiHKKÓ.“É››‹_ýUk‹*33ScÖuÞ¼yZ­>¹ºº‚Ëåbß¾}×»~ý::wî\¥òcݺu5¾Þ÷Þ{YH/ ;,ÊÑÑ999F¥1fÌFERRRààà¡PX)¬}ûö¸uëV•ËÉb±­qþÅ]_†èÖ­[•6!XBÖY—_©TB&“2Ÿìì,R¡—ˆáÇ£ÿþ:Ãcbb0lØ0,[¶Lë~ð•+WjìÒÙ°aƒÖ—ŠÏç£OŸ>ؽ{7âããuæwáÂ,]ºTÃÀÅ_ý…îÝ»3Ï£»»{µ—ÅÆÆÂßßžžžHNNfþˆ#""ÌZ¿~øa½v]=}úô*ÿÕ–ÐMœ8[·n­Ÿ‚JX.eee8uê”Þ ! |?xll¬Ö0ooo 2§NÒ:n™‡Ã‡ëí¢~úé§èܹ3¤R©Î8]»vÅèÑ£uîm÷ôôÄÇ1þ|\¸pAg ¶C‡èÔ©“ÎYüsçΡwïÞ•®£qãÆÊ·sëÓÜ…Â3²zñ,>zô襴îF‚ª•J¹\®ñ¯Yã…ä@ù ½T*5¸¨[­Vë4G¦R© •Ju‹Ê'C¤R©ÖqÁ•+WbË–-˜9s&þüóÏJár¹cÆŒÁÿþ÷?Œ9²Ò¸¤B¡€P(ļyó0pà@œ={Vc¤R©Ä¯¿þŠ“'OÂËËKïZÑ   tèÐ\.·R^œÐ7;ß¿lذAo}ÚÙÙaüøñ:wÔL˜0<Oë˜b÷ïßGË–-uZÎÂÂÂ0tèPÄÅÅ¡´´o¾ù&Þ~ûm¼ýöÛÊ-@Ïž= >Ÿ9r„± ?bÄ„„„ _¿~¸t銊Š*™…[±b/^Œµk×(Ÿ¼y1N…³´Q£F(ßϼzõjnmE7yüøñHJJ‚••$‰F‹666………àóùHOO×08òo´¹qrrÒÙ‚5üñÞzë­*ǯX_ªk]¬³³3V¬X[[[­Ã1‡Õ×BÝ·oŸY]¢¼úê« 5¸?ÞXÂÃñråJj ïÞ½»ÑÛ|Åb1>ÿüs$&&"$$¤Ú¿—H$(,,4ùª j¡ê M›6˜3gæÌ™ƒ.]ºàÍ7ßÄ€°råJ¤§§cÿþý8{öl¥}Õ¸rå ÒÓÓ±jÕ*Ì™3ƒ Òë:}ú4bbb0tèPÌŸ?_kþß~û-¢¢¢0kÖ,¦ /2oÞ<¼ú꫘>}ºVÃb±žžžX°`ÜÜÜðí·ßj„¿þúëËåX¿~=âââУG´nݺZb7vìXÈd2”””@¡P ++KCpªÍZWì$ÒÅ‹0bbbŒ^ÞVÿFúpppÀœ9s0pà@œ?^kœ÷ßçÎӛοëÿE‚ƒƒµZY³faõêÕÕ.g»ví˜eQýû÷×9<¥V­Z1½§šÒ±cGܸq£NßogggéµAU©TP(̧¾í>>|8.\ˆ3fT ãñx˜={6\]]áêêªa­èßbV±ŽR¶¶¶8räz÷î ã‹Çדü·…††â§Ÿ~Òº€›ÅbaàÀøý÷ß1hÐ ¸ººVŠóÚk¯aß¾}1bFŽ©÷åÑeÕÇãaóæÍz»»†Z/®õÔÆŒ3˜–öÎ;1vìX“ßw±X ¡Ph”Ëh+++“ŽB¡ŽŽŽz¯í™{±žår9¬¬¬ ‰ zl5D…)¾Sñ¾êš€›6mÖ¯_o‘ﮩÿ(ë¼Ë¯R©ðàÁC´=SéééèÙ³§ÑþšLA=pñâE¼ñÆã&$$ I“&uZ^“¶PU*”Ê2øûû1ŸÆ}@X.S¦LaÆoµ1nÜ8¤¤¤hmÁVзo_¼þúë ök½{÷¨³eo¨…Y_­ÃW•/¿üRï~ùÉ“'œ¤éÕ«F­··àææ¦7ÀÀ@½“N52zÅÁÁãÆÃÈ‘#k´…T$aÓ¦M:‡ÔêE µ>²|ùrfœ0..®ÞÙ_¬ Ƨ7ÜÑÑ‘‘‘:—ëèZðoŠŠŠ ‰tv7õѯ_?fýëËj"ÏÐÄV£F ‡|÷ÝwïåÌ™3qýúu½|tîÛ?pàJJJpéÒ%­áîîîXµj•Æö×””8;;ƒÏçƒËå‚ËåV‘víÚé5°Ó¥K´hÑ7Ö;>O‚jb&MšÄ¬Ç¬ªaBme×áIDATWWW½ÛQÛµk‡¿þú QQQøþûïÍZ–;wî cÇŽ ö^ôëׯÎwKUü±êTgggÌš5Kã\zz:`ee˜:u*ó]W+¹bŽ.Ú´ic°¥mÌr8TÝ‹ ªkª‹(§}ûöøõ×_u†s8ìÚµ ß}÷Þ—„°Ld2™ÞdæÀs/Ó§O×>aÂ0éP-›"ÌNëÖ­1wî\-G¡P+++­¶^6ºwï^+–LÉ’%K°páBzIP KaèС°¶¶Öfgg@€èèhK‹Úµk‡Û·o×ûz2d:Tkù5$§~–@µºü|¾5ZµÒ¾TÇÆÆ ñT£Dùí·ß´šüÊ×©Q£FÈÉÉ1ÙBî›7oå6¥¤¤ùùùf»uëÖU¯$,¤…ÊçóÁãq‘‘‘VésýzÕ&aVJJJÀf³k4¾æââ‚üü|“MØTÅű>¤R)ŠŠŠàììl‘uݾ}{Ü¿¿Þ˜¬—-T b'TåýÊÆø'ˆ!C†èÝ„”Ïs8‹¡—J¸\£]ÃèÛ9F-T‚0#M›65蔯®yå•W Š>ñœJF{HP ÂpttDQQ‘Á]<æ¤6\ 5{6LåJåß.zHP‰—’·ß~·nÝÂĉ©2 ˆcÇŽÕø÷ÖÖÖprrBJJ RRRŒÚ:K‚JÔ6mÚ¤3¬oß¾FªnÚ´)?~ŒÈÈHQ…7ø|>ììì™™itZ ~§Ôܹs‘‘‘ˆŽŽ¦½üŒ¾Ù}.— …BQ-?LÿfÈ! •••Ù·ÈzÁiv]“ÜÜ\”––ÂÃÃâËÙàuÅŠÌ÷º¶¥H‡\.‡‡‡‡^Rõ û°/º‹©...•œ,Ög¤R) …Ù]« Ä?,_¾\¯  ÜG—.Ãà/ \.fµ›Z“f]N(Z¬ fdd":úq¥óvvöôFuŠ!1:t(¦NZ+î‹Ïž=‹>}úÐMù‡3gÎ4ˆ%TÕš”*((@JJì+}¼½=é©!,šÚ4Lrûöíz?ô`Z—k¤ j¨Õj°Ùl­‚xÙ5jöîÝKro°0*?ü?þø£YËÉáp V«¡R©,MP ¢a€˜˜áÿùÏŒ^¾U›Üºu :t¨³üeÖ<üýýQPP`’eQ$¨ñíÚµÓ0*njjÓ<_DD:wîlT—.]B÷îÝéÁ04ËO4(Î;Wï¯ÁÉÉ jµIII¿Œ¨¡A-T‚øW«/((È¢]µT¬Oµt—×$¨ÑÀ‰DfŸ`µ„PÁÁÁ Î)emøÆ"A%ˆX¿~½ÙóèׯN:U§×éææ†ôôôuoÏ;‡Þ½{›5?†z÷î]Æ-u¡ˆ¶mÛe‰ŸÐÄÃÃÏž=3* {{ûzãÀ±Á êƒ7²$¨„@ 0Ê…1ÇC£FêÕÒ)s2nÜ8ìܹӨ4:wîŒëׯ“ ÖFÅ|ß¿?½„AþþûotéÒEk‡Ã££#cÁ¬&têÔ ;vì0zIT}"&&õþ:h • ªD"ŸÏǰaÃjœŸÏ×ë}•ÍfC­V›}ûª t†òÉ'ذaƒÁtÖ®]‹3fU–“'O¢_¿~$¨ÑІÞ{ï=ØÙÙÕ8þýûãĉãeggÃÉÉÉlײhÑ",Z´Hgx`` ³×ÅàÁƒqøðáÿžËå‚Ï磤¤¤Æi˜Â×—»»»IìÇ’ „‰éÙ³'¶mÛfTcÆŒ—«{ŠÃÉÉ ÙÙÙ:Ãkkf\,ë6H$())Ñ9ákcc‰D‚ØØØ—A(%È€i ½ „ „«««QitïÞÝ",¸Ûr³··‡L&Ciii^GÛ¶mqçÎêòÄˈ­­-&Mš¤7ޱF\FŒ;;;ˆÅâ§ÑªU+$''×i]õêÕ .\0ïþýûhÕª•Ö°wÞy§V†@HP ¢2dš6mª7Κ5kô†0@ox‡УG£íè+‡N3‰iiië"77ר?¡Ž;âÆF••¬MD ª±L˜0A¯O¸¸¸è ‹ÅX°`Þ<\\\ô®hðõõÅ;ï¼c°¬úÖ˜zxx@(]Ÿüñ‡QitéÒ©©©°±±!A%ˆ††±kTÙl6F¥×5sß¾} ¦3þ|½áC‡Õ»¬jĈ—‘‰Åb“ü éÃÛÛ#GŽ4jìš• 0µ±~´cÇŽãüôÓOzÃ÷îÝ«WèX,–AW*'OžÔkåËÉÉÉèu¿ ^PçÎËlŒŽŽF¯^½è-#ˆZÆP«°*­FCqÚ¶mköëhð‚ºbÅ æûk¯½FO6A5ÿc * ‚ A%‚ A%‚ A%‚ HP ‚ HP ‚ ê ÕZ6%Ô^k˜P(Dll Õ(A$¨UA­rr²QPPÙÎbQ‘ŽŽö&)”Z­FXXÄb1†j0þ‘#G±cÇ2† >ŒœœÀ믿OOOºÛAXN—_*-…R©‡ÃÑ8ÿìY*Äàp8hÙ² [2ßj¨´´ëׯ‡¿¿?ø|>~ùå(•J­qU*öíÛµZ lܸÅÅÅ8pàär9üýýáïï_%¿8Aµ*¨{ûç&²d²2¨Õj°X,¨Õj䡸8ŸùDG?¨VúW¯^…³³3zôè ::Z§Éââb„‡‡cðàÁèÑ£üüüpöìY$''£yóæèÑ£zôè¡×"ADtù+HOÏ€@` ¹¼ ¥¥%Œ«•J…¢¢bˆÅ6P©”ÈÈÐ/dááá–¼ýüüLrQÞÞÞˆŠŠBFFqïÞ=ðk×®aË–-•~G{ù ‚¨uA•J¥°¶.«,**ŸÏgÂrr²àêꊸ¸X¤§§ÃÍÍMg:™™™¾fŒuQÁ°aÃpüøq¤¦¦" ­[·ÖFppp¥ß½öÚkP©TP(ôdDCï¾³ÙÕ6åW#A---››<¸‘H¨¥¥WÞÍwtÔo={РAZ[‰7oÞäççƒÇãiŸ=rä|}}Ѻukðx<ˆÅbÆÝnbb"zöì à¹5óøøøjµ|—,Y‚%K–ÐÓD œY³faÕªUæÔF<жís£¶7ffÕù|>ž<‰C›6A¿a±ØÔUΣyóæ`±X X,ƬY³4|âìܹýúõCëÖ­ammÉ“'cÙ²eÈÎÎÆôéÓѦMÀ—_~‰äädøúúâ“O>©RÞßÿ=òóó5Î-]ºÔ Uóš’••…C‡aâĉ&O»¨¨Û·oǧŸ~j–²=z~~~f±§yúôi8::¢C‡f)»9ï©9Ó®Ïe¿zõ*¤R©Y,ºEFF"-- ýû÷7iº52o—„±zÃ[´h¢#DU­B5kÖ aaaZÃ~ýõWcwww¬^½ºR¼¯¿þºÚ•¡M\]]ѵkW³Š‹‹Í’¾\.‡­­­Yëݬ]~Â4ðù|½¾v,OOOØÛÛ×˲׆•z*»&ÎÎÎFùjª/ Ö!NNNxï½÷êeÙß|óÍz[ïŸ}ö•½–éÔ©Sƒx§i/?A„‰`åä$03F\®5ØlÊÊŠqébz÷é …¢Ôd™ …NàóëW³?..Mš4©w7V¡P 997®weÏÊÊbVpÔ7êëóRŸË^PP™L¦×e¶¹(,L‡B!­Y—ŸÅbƒËµÖ®TÊ R)ëÍ8þ¡C‡êœQ®xÀbbb°}ûvtî܃P¾ÄkÇŽ‰D‚iÓ¦Y̵q¹Üz)¦@ùx[}¥¾Š©%—ýË/¿„@ йÁÎÎŽù¾uëVÄÇÇcÞ¼y‹ÅˆˆˆÀï¿ÿ΄óx<³.‹¬¦ ²þiýH+…%%¥€Å5rgÎíÚu×®E iS|ðÁ» ,æ&]ºt III˜6m~ûí7XYYUÚPALL Ž?ŽiÓ¦áúõë8rä „õë×㫯¾bâlݺÕ,K ¢!’ŸŸ7bÒ¤I(--ÅÊ•+1eʈD"­ñ7oÞŒ¶mÛâí·ßƦM›0~üx´lÙÞÞÞÊ7m۶ͬe®ÁªjµªÒG¡C©ÔÜatíÚ lܸl6©©éu³ÂÂÂðî»ïB"‘`Ê”)X»v­Î¸?ÿü3ÞyçH$ 4‡„„„@"‘ÀÙÙׯ_g6õóåÝ»w¯Æ9C¾â óòèÑ#8::ÂÓÓP*•xöì™vUR«qãÆ téÒ‰;vÄùóç! !‘H ‘H46þX VŸ©S?D“&¾/Ý ïÔ©är9–/_Ž#F Y³fôÔSþ÷¿ÿáçŸfº‡111̦•ÔÔTlÞ¼ÑÑÑÌ ½k×.­ö Ëå·ß~«’9P‹Ô§O“0uê,\»vóç/~ioPQQ6lØ€qãÆ1Ý ¢~Ò¸qcH$æOÑÑÑ‘é‰ÄÄÄàÙ³gؼy3Ö­[‡mÛ¶!//VVVXºt)U^=à‡~À”)SÌžYÕÛÛ 7®FppG,[ö•EVðo¼S§N<ˆáÇ3aqqq˜7osܯ_?œ>‹-b:2™ :'³LIµÖ¡²Ù$$¤ !!®RBÅÅ%hÙ2^^Ï DFÞCPÐó™óú¸•h8TŒ‘öîÝOŸ>Åõë×777¡qãÆ¸qã:vìˆ?þøR©Ôìcr„eóïu¨´°Ÿ ÂD‚J[O ‚ LD­Ž¡ÊåÅP©äTëA¼¨TŠºT)är)Ý‚ ¨…jJ>|„‡ãŸÝ¬/À‡ÃÑØuÅfs˜m¯š¨uº˜&‚0‡û¾¨+iT»vmàããe9‚š••¡PkëçÆVlmí  ¡R±‘‘ñ|9Jûö*mk€””gÈÌL£;O„Iáñx ꈄ„X— ¸¸ˆ ³³ÃËËÚ<‘XÄ:T@WW %X,àÊ•khÔÈã…¡9òó³*ý.2ò<=ÑÝ'ÂäÈd¥ ­am͇““222 •–Zf—¬­pssƒ½½RiIy'^M7’ Ë@­Vÿ3,©‚·· ‹PVV¦3~.›²·w€J¥`Ä” Â’[¬2Y)’“SLÓBU«ÕËu/{âr¹`³«®ÑIIOac#BYYüüƒË%WAX …±±ñàñ¸pvv2 æååãÌ¥;°up¯~{{»*§ÇãqÁb±Àçóqï^ÜÜ\àêêJw ‹@*•"77))ÏàâRn˜…Ãá˜FPÀÙ£)¼š?÷Å.“–bËš¯`ËSÁÉÉJeY•Ó E‘Èr¹™™ÙP(T‰žoQ-,,ÂÍ›w+ý^¥‚F<‚ SÀår‘––¼¼B°Xl wBÖÖÓ *lZ¹ÿø^iƒ­k¾Â®-«p+& @¹˜&'?Crr ‚ƒ;.^¼ŒÀÀæŒÂå¶DžÏçkÍãï¿£_8ŠÖYÍxAæ‡Ãa¡Y³&Æ êŸÇ÷cÏ¡ø}÷ôðþ<¾Ë7„ÈÖ@ùÒ¦ÌÌ,DE=„··¸\."#ÿ†‡‡‡† ––J‘–ö VV<æÁÖÖ>>ñäI ò-¶2mmíü*JKkg2M©TâÑ£GÈÉÉ¢'™ j‰€€¦‹íÿ99ÙPÿ³ÉÑÑIçÐdµõ?ÞG䎭ß-Äo»6£i`[ô~sX¨¼ð>"âlltÛ d³ÙàóùpppŸo‡î#33 ŽŽÜà ??OŸ&ÖJ~%%¥ˆ‹‹‡DBãËQ[ðx<äæfÁÞ^ [[¡  \.Wç8jºüã?ž ±ØKçOBpOÝ•“Àç[é ÷ðð€““rs³!“Ñ‚ ,Š]RB¡žž^zŠW[Py5<ÞuYºö~ ž Vœç+ò›7oŠë×obР7!•Ê~ >>ž•ÒrqqARR"„B!Ý5‚ ,š’’DG‡kLP%¨B¡-|Ùp±ÉÌŸ1îŸòãŠýö5>úh  5½»w¬ "‘¶¶¶ tׂ°8 QZZjp}µ•ÏçƒÏçkX¨6[[¨Õjäçç#;; …¢^Tpaa1ÒÓ3j%/™¬Œžh‚¨òò œœ ‘H‹‘Hh:A5%VVVèÒ¥ lmmÿ%TE°¶æƒÇãYl%—ïèbA(ÕZžÖÖ|½ãÑA˜‘ÈNNÎhÓ¦ÆyÏJ‡9Ñ:ÔÈ;(A/ÿTÔjÖ?]qÔjÕA )GgÜl(ÔšÃòü2´øV]PŠçcuAíZ@©”QíÑ PA‡ŠÇÈVfkœO¸}gT¹\§OS¨& ‚hð°Å<À­òy¥R‰¸8í›y¼½Çã– *›Í†Èj’ ˆR»y°X,:Y±œŠ n;ªI‚ <%¹NÑ4¤“\MfƒÃáÕÛŠP(hÌ— ˆjn J 4õE&7ø; Aåp¬`këVo+!//‰V&aV*üó<á\ ik9¨É+ÕT‚ ˆ†WÍFw‹ý¶ZNú¾ûî;‹»ø#GŽ 66–ž‚0!l6|¾-¬¬l*}8kf½º%•‹Í®z¹ ÒÒ2››gZ1®Näû÷ï[Üúô)¼¼¼è “‚R)×j·#&æ D"!<<$uT®2­ó%ÇÂÎΉáaËÜÜBaa¹íÐ&M|áääˆ'Oàçטï%%¥(((@JJ*”J%ÜÜ\áãSÞ(ºy3*•ê-iÀÚ¨2eddÅb!>>àïïGG¸¸8ãË/gcêÔÙñ“£G‰¼½=‘ðÞÞž`³Ùxö, ŽŽö°¶¶®z—ÿèÑ£xûí·†°°0œ9s “ÉЧO„……aõêÕX·nbbbÀår™¸jµOž<Áwß}‡õë×3ç·oß®ó¢Oœ8×_‰ëããô>{ö쉰°0lܸ«W¯FBB ÂÂÂðÃ? --žd‚¨c®_¿‰óçÿBtt ¢£cZþ¾¯Yó§â{BÂS¼ûîG¸wï>¢£cpðàa<{–ŠC‡Žáï¿0iüüón£ËuâÄŸ˜7ï+&Í-[ p&wÿþCHKKÇ?lc,¾8pÉÉ&20íàà€Ö­[W9þ¤I“þ±Ì½FYLJ+V`ÇŽL+·gÏž‹ÅhÛ¶­Îßñx<¼úê«ô4D£P(Áãñ˜åèÑÃõÆ8°?BBÆ6oÞŽœœùd"„B¤Rn܈äääúôé…~ظuëŽÞÖ7+''Aý\´¬ia?A`³9ˆM@rre”ËhÓ¦œ5Χ¦¦A*•ý#†Î°±!:ú1ø|>„B¾þz6n\…²29JKK!—oã,((€µµ5¬¬¬˜˜ÄLJyzzT24Ïfs””¤Jå*+“£]»6“wìØ‹€?¸»—÷]]]  QV&GJʳÒd3“bÙÙ9(((‡Ã†X,†@ @JÊ3¨Õjp¹\:tôƒ¿¿_Õ[¨A4lT*%üü¼àçWõ%‰¢õ"ÑÑ18wî" 0°ÀÊŠ+«çBig÷||…°é+W“&ÞhÒÄ»ÊåâñxLË´+«ÊçÀÉÉNNš™™Yسç T*<<ÜáêêRµ*‡Ãƒµµ¸Þ>%%ÙP«Õô6„E‰sy‹“Åbétb.Êõ€c³­ê5h´P•J9Š‹³è „Ãì:ËÛT^Õk`Óí&‚0ÑŸUA *A„Eñ7= èVQ?4IEND®B`‚snd-16.1/pix/s64pi.png0000644000076400007640000001075711701607527012626 0ustar bilbil‰PNG  IHDRœ¶:KsRGB®Îé pHYs  šœtIMEÜ )j@S·IDATxÚíÝÙvêJ²…aÃXïÿÊœ ×à°m#Ôdùý5Vm HÑÎH¥Äíñx|™¹3ˆZ€¨ˆZµQ ¬ jo·Ûívcn°$Ðþó‡§ÛÒI Í ƒjg8}‡ßþ¿G_QûÛ|È¥h¶Š–ú˜wƒícO- >ßÍ•ÀEüaI”µð¿~ %0Ñ}`9 3QÂֹꯆ ÌM@ r; 8‘‹X³øÞ¡NÔ~Ö“‘æ¶a….æþê±w¥öñ¬u£ ³Ã€?†Ÿóؼ^Gôÿ8_Rã‹Ækîüü!z¢ ^¯œ9öÔž‰³šÊÜX¼~ÖµË}¨°°ý1–†Ù'‚b;ÑÀÔÖµcd¾Nï©Ü6ιvVLLD™0Ì>O“Ñæäøâ”QÞ"­éÐsg»fPÀsHûé}ÿÉLÙS;˯™6<æ’W'û…nREÛõàŸE–ršò½Á/î—Ü{à¾7,^ÌËX¦IN°§v¼iž?þ1ëȃäU„Ãh»=±í­ñ]%‚ŧìØ0ÝÚæd”¶#Dmºu…Y½äz-Óɲë1Pu”÷¬!æQ²e”¹·ìâ'øñ…f6½îŒ&A¤d7_ œ±ÚdûX–fÒM)WeÙ0†{1ÓG¨qykk[Y Ç\´fO’&r.<Ë,/Þ— —‚¬@# {ðYv„דw«e1§L÷¸•{`AÒ<§VsÒ±Z)ÅÅÃÉãèQ©º*zøXñ©o'Sëåš=µÐwãN§ÐÅ¡®üjðwéÉ)˜UÒãœìé­Ã½çbzµ2JG‡H@µ`³‚‹×¨Z|N+‡hi%îƒëËMЩ•?8¶E¯¡ÔÈQ |˜‚•Z’¢ñ0dž¹‚T†¤Ë´ýFÍÚẄڂ¸Ô âO>ò»¢ÚE‹@Ô$QYÝL«ϬS‰ÚöQçsØ–Öa 1JýËIÔv¯z6¾¤Ü+ 1*ÎÀ¬ž¥,-j›1 &Jœ`9Q«70…¢ñ aù²óH@ÔꩈRÝFþJ™ø'ñg,ñQ=O*©SUô޵*{mUÚêDÈtõ³²r‘*ýû4Ÿÿ–)ñCºÀohM~¢@ˆî Ö#ÓÛ6fƒ´Ý ¨a¢ÈkpSe‡b°2~šýDBíËçŠK…ˆ_ìÞuY¬ÞÆ5±ª5¦‹uÓ€,ýq…fGÔ¥¦pê9¾ds07‡zõÛ2¨2éëÊ ~âOˆÚÿÄz¥aÎ` ø¹JÛžµ(5˜*ë€P-Ë’Íï£-ÐRÇÿ´¡ˆZ@¥FMDU‰ÓãLÃêò{%ëSš«¾\]ú$QÉžR©\ÜY| Eõ0 ft\íÊ?kGŒ("j×!׿›E,ãiVuÍÑóZð©^€…é®Ü.wm½OÔBAAc­¶ˆ¤ ž8•2ZÊë¸Çãñx<ÌoQ Ý Í‡z¾ŒPE*µX ®K&ºv‰P´ZR.ˆÚÉEÍÂdd)»½£Q GLI¤B‚úQ«UC¼ t.HV?¢VêE¼µ*ï€;™ÿd ïŒO%-sâT[’Ù±R Àd;¡a›íé!4)#`1¢X¢b +O_ë„=X)¨¨U—•c* ¤µd40Oš'ÍŸÿšKCÔKªÛíöýÞ×?Ǭb, åè¢v#¾é]îù—ê i ˜0+…ï°ýJäÞ¡×*è ƒX{ÙÅšg¤5±À¡5¢Ø[X³HÏÅ‹;õ†ñ“äkÒ=ÿ½r&’˜•Â;EÞµ¢­¦>Ȳ>cÑwŸU Þ_d8A½å^2jE›n=†À}l…¥¨#je %o`ÙjpgJõ@Ój[Û6™ÛÝôÖegK{j3Ÿ@)&PÊø:þ‰H(۵|ÏåÉÚ­–eöú¢öJéQ¶XG·ÖcìÙüÊŒ•Z`~áV@YŒËÂú´˜+¿L6÷Çe‰ÚÞíêHÍt9ÄN9“¨ÕÇ;@½¬Àä•Úì£L–5*‚+©JW¯lXO{œUžÛíÆ¿:ijoûÐ¥`QôÙ°Øó%Õ§Œ¦ò×µ Atg¦£ ‚¨… `¾èq©´jùïb D­Ñ0ŠÈ, qY0J¨­“öòè—†©¼‡ÔTi$¿Ãð‰#j, Èø½2D-0¹N¹Àõ¾y_á$ôž~+pk†º4“)Öd¡•Z½;e“£ýDmM:Á¬¬@Ga ]l7o[ò·¼®¸3åALSb‘ 5€h¡»½?^}׳þÜÿ“Q&Êå¸QÌlÝ :L9 ÓBüð`ŸÂv“zYÜãñx<]ý*l¾'jWï(fÍzu¼­[ÓUI᱈­<¤–Ðßc[Aƒ#j—è(R]é‡Új®–È P úÙ~°\7@ú`°[9‹Ë›ßŸÖ#)ˆÚu;Сe6Ú½Kçž{YfÅ¡5és^Ãk䌷ÕóÛ9K*_§Cåã·ôB¢ éx€AUåQ‹p%‚òÅÜ,!jWqÉpÈËõK¹€zè¼sRdM5ZÔÞþËjɹwÃ3!NûTº?š‚¡ìïªô˜`X3ØîýÒû‰¡m WÙZ$êRŸ¦ >h›Igæ€Y¬_WµVÐÓ6 ‘×H !'#³vÅ [ŽQ»Ð®_ꦀòR&Í÷ØüYš¸éϪ¢Ô Nw[KÔ*¾ 2œ[ÆhÃÖY?~Úâuøz3’M°RK{éF*€|¥Þ<_©“‚¨%V0­*ŽÁ¸>ðïüåúØÈêçìk;|ÙäºOB1Ç-©ŠòkÕ¾3æ`Ñf§lj\©ÜW³¾Ü«½¼©*7AîÇïž0qŽÏ°ý ‡öÒïgÕôÅ×–¼)Þßùˆ~"y lû–P²„ûâ>œ'AÄA“sWh`愊a˜ìšJ;?кⶺ¨…Æ9¬Ô+¸~‹Ž¦Ñ>ñgí¹½ÿ¡QtªD&j‹«.,¥o·Ì²ù’w’;”â8eϘQ‰{L˜r«¦6éH4HXà ã(ÔUíj:ø¾¬§Oø,T†O¹Â®ÆÅìa]=òêtÒ$‚ªà…eg•VÛ«ú=ÀdÿØCg1+ÚW˲Èû=vÆÌ=ZªKòñ³H«¯»sç0:¦\NÔï«Ó$‰Nr(³ÈÊÇÙ#ûÆäu™Ÿ8ùVÛ{¤K¬çÔ³þ\7Oüö€ñ}=«ûUKb¿-\Õ¼ ÃmÜì*$&®.n³ëà{ê(ïú”àª%£IÈ® oÚ–ëm‰Ô@ä€ žzöK«¹¼Öïñ·‡±N¥;¥Ë¿ vY$”uëB—COIC´­°BâÜœ¨rJâée$"͇ž,¡f@ºŠ‚G¤!l[sòŒÀ÷8I4.^ š$m[>ëgl"|l± öiÔ¨“äµSlO‚øM‡RþÄo¿õ¨f÷"ØHü0Â~Tóþ]+©%Í> …¥nât0 ÛÎè’¹™3ýb.%*g*/4Ìó˜ Dí,‰9KVŠéìöé4Xn¡§‘´M‰4±­²w¥öÇL#Zuƒ[ïgد>Žœ~Ûw=v‰Úßvç ¢ .¬ç稩 ¢ŒWHG×_‰¤éþúr¥bžS @EÅXœ3+µï¦F—< kY•¿&‹Ú?%éóI¢¯¯¾Û²³áz€ºÇmà°¨ÝNé@,%µ€N’ræF17W g~|¢@(­¹ºQ ù!b=§éw£Ø”M ³¶ÿú^ß[é{™Ú÷ú^§ì{}oüïµR €ôµ j€ÙŒ{úA\AhAh -ˆ«NX©Q µÀElÂ@z¬Ô =ÝQìv»}ÿÃ’0ÀNùôC8mªæ/µ\ây{äÓ~AÕü¥¼Ü»ºäÕFÇã·“@ßr²ÞɧmAÕü%¢Àášõ¤·Øþ–éïúh‡ªÊéÄÒHCCúÀs.z·»æ»—ÎåHsCõ0ïŃý›ÛQ`‹)ZìçkVÃÎt®>n¼kãøO|×÷[tâ~®¼ø—,¯Gïž©Vï â¯&¿}á˜*¢h—ÅJ-QѪkÂàÄgÞß‹µ?þËN³œ{WœÉ$ïÁƒ¢ Ž•ZàRzíOMêQÛºöîæÖíƒßxׯì¹Ç¶‰¡>Zþãyµzéõ®{íœSº~àÑh<½Ï#n‹ãƒor^‡>¤¡%ωÂßÿÞc¨æƒÜiEû®k´}×é`kO-ÒkÞ ªæ/µÜ¢ƒÔdÕkO'–Ízœø»Ãøs¯ç•ƒŸNÍ7®l¬Ç·ŠÞ?/ÍŸˆ‹'>w˜<ºŸ„¢]Y×þ3Í_"jC ²†;Úà+)Ú=¯AcÃø ±s[c¯|Bógt¤n)Zš¿”O?º£ß´R¡Ï=ËvÊ÷n|ÂÅO;á”wmmîÜhÑR¬‰y.E |ãF1`´Þmû(€M÷ÐúÛïzwÑêÝ»~ß!þ§ Ö.x6Ð4 M–‘3TI Ê2©…žpA¬eÁ‚EX/ˆ¤…Ô«““Ìß»Çè¹s¬MLooGN§™ºy§×Kí¡C4;FEs3ÇÚq,X„õü°69ÉìÝ»ÌܺÅäÕ«ÌܾÍòÐÒú:®`‘S§H-, i®`Õ‰ ”Loe%êjkZ°`Ö³Ezq‘±óç;žáãÇY›˜ 5?¼±ÆlZVVM¿§Jþxœ†cÇðE"ÖŽ´`Á"¬r:Mzi‰µ‰ Æ/_fôìYFNžd}rAÓrUŒ\†ÊfÃYV†¯ªŠÿöß²ÿ~`]µc-X°ëæªÌݿϣo›±ó百y“Õ±14YF0R©ßÜåå„›› 77“èé!ÞÞNåîÝ”ÅbÖε`Á"¬Sׯsî7~ƒ¡7ßDZ]Í©&Û`÷x¨îì$ÖÑAÍÄÚÚðÅbx+*°9¬ÝmÁ‚EXß·”Ò3ÄÕU6fg>y’‰K—>uJWTŠR ¦²äds:q–•á./§ª³“d_Ɉ··cw:±96«ÔÍ‚‹°>4®Ò˜¼r…'o¼ÁÄ•+ÌܸÁÊèhÁklN'𢠩*‚ÃAY,Fyc#±½{Iöõkk#ÒÒ‚Ó糎( ,Âz6R)FÏœáä¯ü 37o¢Šb>´s875mmEÎd˜}çÂÛ·SÝÕEM?ÍÍ’I\€uY°ðœ hÚK\S(¢ÈÚÔ#gÎèÊêõ×Yxô»Ó‰Ýí&ÒÒBíÀ‰ž’½½ØœNæîß×è8|>n·êY°`Ö3ýH/-1|ê÷_}»ÛMy]KÃÈ++Ô ß·x{;ÞŠŠ—þ³`µõX°ëãMXë³³¬ŒŒàðxÖÖ"§Ó¬OOSVUõ‘(5H/,0}ër:MESáíÛ-â²`ÖÇ™´4øH4kªŠ*ËHŒg+êOœ`}jŠPc#u‡ÓøéOS¹g.¿ß". aYx¾P26 8uý:ãçÎ1vî«££ØÐkÀ²_V ¶–ºW^¡îØ1j&P[kÕyY°˳…*Ë,?}ÊÌÍ›Lß¼Éìà sƒƒ¬cSÕQå^oÚÜÑ(±¶6ꎣñ_ý+";vàôû­jác ë’ü‚°<<Ìè©S Ÿ8Áìà ©‰ ÄÅEQÄd+º²ªJ”"òÚ˜eäÜ9ÖççqWTjlÄiíZ –²ðÏ…¦ªHëë¤YåéÛo3qîãçΡ¥RØ5 ‡¦aì%Ô”bRTŠéÖ‰mk£f`€êîn¶}ö³Ø].k‡[°–…qu•¥¡!¦™¼r…¹Û·™½u qa»±ãí&’*VRZ ’ÒÍf#P_OçÏÿ<{ê§ôÕM+ánÁRX>(TYfþþ}FÏœaôìYæÞy‡µ‘Ä¥¥\>ÊŽÞ<½UnJ£0OeÞ‚õõTuu±ãßüšðñZ~Z,²ð~C=qm qm¹wÞaäÄ ¤îÞE^_GEƒ¤²äd®×Š6ÁéDÕ4YFì޲2üµµÔy’™ÁAfnÞDÅ1 &’*Ö4“в¹\øâqü‰¾ª*‡‡‘6675‘ìë#ÞÞN¬­òúzkÇ[°€•Ãú@H//sëÏþŒw¾ö5îß'³´”#%s.JØBEi‚€7'ÖÖFUw7‰Þ^B¬Ïͱ6=M ‘ ÔÐ@Y,†Ýí¶vº –ÂzŸaŸ¢ §ÓÈé4³wïòÎW¿Ê½¯Ìâ"‚ªæˆi+C? ÝšÆævS“è狀§'GR.¿»ÑH­Hv§U˜`Á‚EXï—¤T•õ™Ö''™½s‡á“'™¼z•…û÷QEqS˜g^ÝËÂîñà‹ÅðÅãÔ>L²·—X[áææ—ÂåA•$6æær“{TIb}f‡Çƒ¯²R÷õ²V-X!áËÊR©…foßfòÚ5FÏœaùéS–žÊM¾ªÞÜ-• ªR[–ؼÑ(UÝÝTí߯«K#Oç ?Ò,ÂúX‘–ª(Ø»ýå|’¤7O¯®2uãC¯¿ÎØéÓlŒŽbK§qJ>MÃc”Yë¨EŠJÞB])€*vŸO4JíáÃTww“ì룼¾^o¤Î†Á,X„e!G4ŠÂÚø8+££L]»ÆøùóÌ ²òø1IÂ…^z-?0úiE¤T|ß¼©€Íç£,‘ PWGí¡CTuvÙµ‹Šæfë‹°`–…ÒÐ4™&¯]cââEÆÏŸgmlŒµ‘H¥pAA”ÍÍÓY’K•9,<‚ ÄÚÚ¨6jÄÊëëñ'/Mµ½ a½d¡žœN³1;ËäÕ« ½ñ—.±>5…²º ™ Nƒ¤œ%”T±i_Ž”YÓr+zª `s»±¹\„¶m£öÈ==Tïß/Åéóé–ÉÏ8ÔS% 9“AÚØ`úÆ œ>±}ûpV?¢‹°^FH©k¬MN2~á#§O3uõ*©éilš–³BvšTT–¤´De¶Evƒxb1>K££¨€/'PWǶO}*ç™õ<Á*™ ëÓÓ,3qù2“—.1=8@uOõGŽÐð©Oᯮ¶|æ-|¨°žu!ËÌܺÅ;ßø“—.±ôä kããzŸz²Ü¬ ²î£a¶Q .¡æfÊ›šHô÷SÙÚÊâãÇ,Q±cÑ]»(oh L>»÷ø|çOt–Ífñâ-m9…øh˜å»˜<Ìœ¬’›‘ùyÖFGIÍÏS{èѽ{qÖÁbÁRX/ šª"§R<=~œ‹_ø“—/£f2êÉÎæ)8f#¿,9!h6¸\”oÛF¼£ƒäÁƒ$z{)«®Æ bs:WWpϬÚ^“%Uÿô0|FåËåÓÆ¶ÚHd$Xa^ƒ%`XÖ].<ÍÍÔ=JýÑ£Ô<¨»?X!¢‹°žSØ·¾ÎúÔ+££L\¾ÌÓ7ßdêòe¤••‚áïå:ªšòOÎ@O$B ¾žÚC‡H8@¼£_,öüK ÜFž|ÊÒWÿˆÊkÿ˜/ì2”•šUViPE%eXGßÖ€e`ÕØVÊˉutÐøÙÏÒðÉOÙ¹ÓòÚ²`…„Ï r*ÅüƒÌ?xÀÄ¥KL_»ÆâǤffr&œE¥šòRÅDå ©Ø¾òÆF’ÄÛÛ)oh X[‹íE8ÎLÂW¿ ß}Çð]*M¦š ª Šª ,E2ÈJQÕ Ë\läÅ¢ñ™íèEº/’ZZb}f†º£G©Þ¿uµupY°ëÃÊKÍÝ»ÇÄ¥KŒž=ËÔ•+¤fgI/,€¢lxjvUK<\.";wïè þèQª»»ñTTà­¨xq-A_ûKxõ+hò*ܸœ«‘ŒæÂâ¾ÃŒЬ“VFƒŒ ¢–Í[Öù!›£“ÓifîÜ!µ¸ÈÚÔžpØ", aýssQâÚšÞ·÷ä #§N1|ü8Sׯ£f2 ªšV0'KDæ¼Tîgv;®²2ÜTìØAÍÀµ‡kkÃ]^Ž`·?÷pOSä©IœS“¬ øŸ~Í¡ I2ª ‚¤oš ¢™ìfYIIYÑoS”¶¨É>ÎÖˆi6Ž@yyΦ§îÈâÖYgÁÊa}PL^½ÊÜýûL^¾ÌÄåËÌß¿¸¼\Þ½W>ÊüØWYIyc#á;¨éï'ÞÑA¤¥OEÅ iyÉúÒ/¾û.W.#¿ù]ü'ßBs,€fä¨T4EûÒ6¤ lgT5´²®)6ÛÔdû»wEº:*÷졦¿ŸÊ={ˆîÙƒ·¢Â:Û,X„õóR™ Ã'OrúW•¥GH/.êJŠÂ‘ñB es»‘34À RÕÞN¼½º#GˆìØAY<Ž7ya.éÅE¦®]cäÔ)„sçhž'ôô 2²M'*EÕ‰*KDÙ°/-è +KNæçÌYeÊÉ㮬$ÖÖFÜ[VÑÔD ™Ä YŽ,Âú !‘”J!®®2ïOçÎ_ü+££`|ôb%ØlØÝnœeeëëIöõáD˜¼y›ÝNuOu‡Û³»ÛÝåzî'¦"Šˆkk¤æç™¾~™ï|‡É Ø=5E"Æ.‰Ø å#Û@Ñôͬ–ÌyªâûÅÆÙV ÁëEðzqG£T÷ö’ì룺»›ðöí8|>ìN§ER,Âú !Qj~žå‘æïÝcüÒ%¦oÜ`fpqm­@Iaºïòû ÔÖnj"ÑÓC¼£ƒø¾}øb1Ö&'I/-njÂõ‚LíTIbydDož¾z•ÉóçI]»†klŒ^U͹:”²™))É[W6…ÓIY2‰¿¶–Ú#GˆwvÙ±ƒŠ––÷W&-ÂÄßë°þóàð[gž‹°IÒ§ÃܸÁÄ¥K,ß‹©‡2}ŽlóôêØ£gÏòô­·˜¾|VV°¯¯Ó$Š¿¡¦ŠmgL49ÂÙÚ}4[ÈŠÓ .e55ú> ÑÛ‹?‘Àå÷ãp»¿GÁ§ic°Çõ_€…[Y€Ì\áÙ@¯4bAEüôмA&oÝâÖŸþ)âÚÉþþœ·þs™fÁ"¬gpv“^^fu|œ…‡yòæ›Ü{õUR³³8Ün|Ñ(êjBÛ¶‘ZZbub‚Pc#õÆ Ðêýûqù_ŽÐ$³²Âš1ªkâÒ%FNœ`npÁ˜|ªÐGmln–K¨¦bå”]É3ç£\¡Þh”€êUwukm%PSóÁŒçoÂâ8ÿ…‘Y¢2×?¤ ÂJ‘/Ÿ‡µø.¿q«W®cs»‰ìÞMíáÃÔ>LòÀ½ÀÊY„õQ$,MÓXzü˜{¯¾Ê£G¤X~ú”@2IUG‰ýû 75 °:6†+$¼mÛ ]Å+Hëll0{çs÷î1zö,ówï²:4„4;K@Q**„^¨J”òm/•·*öвy|Ñ(îòrœ^¯ÞX¬(ú}I¬’WÇÆxøÿÈ“×_göÖ-¤åeä¥%|ªJ9ùáî| U@Tr‰œS.÷$(‚€ærÚµ _2Éü»ï²8:J¨©‰Do/ ¯¼BUg'ÞpwyùÏÓ)"<ú&\ÿÌ‚,êoΜÑ7W“–"¬Tž°Ô PR ­C& kÌÓÀŒ °ìñØ·†OšÚ£GIôö¾”~ü,ÂúØ@SU2ËËÌ߿υßüMFßz ac/à3””—ÒÃ%Þ{À„f·c pUVê¤ÔßO|ÿ~Ê·ogmzš¹{÷ˆíÝKìû±yI/Áäuýþßþ0ˆù7ø^eïaiÐD½½GVô&j6@ÉêjdI'«5#R\!ßD½f³áH$HôõQ÷Ê+4|êSëê,¯-‹°,|˜WV˜¹u‹™›7™¹~¹Ë—Y¹{AP^ôÞ(ÁDTfoöRÓn²]á0ÁíÛ 55QÝ×G¬£ƒ`}=e&Ó*ZZðE£Ïnusð5xtþé?ç%Ÿ¹vJdSB]•L„¤Y†«ƒ¬ê$¥*K’ò¯“ÕBî3óŸ#Å]U…§ºšªÞ^â]]„ 55áôùÖבR)|••Öh–…÷Âúô4cçÏ3yå S×®±òø1““h9rr)©MN£ŽæÊ–;&ºo•­­$ûû‰¶µá‹FñF"ÏÌ€ßùq2ðø"ÌÖN“”¡²Y÷r$¥ågÃ@Ùʪ®¤Ä=ŒY5hn&ÞÓCõÀÑ}ûðUUé“üV ‹°¾'QDZ_'³²Âð‰Œž>ÍðÉ“dææP3I¡iUìî n±átb÷z±¹ ÌÕ½½Tut`w¹ôFêgU‚¡i0ùÞþsxãaiT­0ì+J¦k¢®¦dýA4(KX¢š'(Ñ )É (¹DªË\¦¹\T´¶Òù‹¿ÈöüA<¡NÐVNÊ‚EXß#…“N³69ÉÒÐS×®1yå Óׯ³ôøqί½ø–"’*0‘pêpà‰F 64mk#ÑÛKlï^*wíÂù<©§Gàúq=FûâÿšÑZiêÕ2…ªJ‘ {d-¿ø—%,1Ú)ù¼•¤nvx0?Î.$¨6e‰þd’ª®.v~îs$ûú¬ö a}/¨²œ*1vñ¢>6~hˆµñq¤œz²…z›‡K” ÿ|±±övbûö‘ìï'ÒÒB ¦æùýÃ_†»—àê[ú{4Â>Í +[Ú¤ªL¹¦ &÷Q5ï‘%+:‰IF8˜Ñ …™¨n7’¦‘E=ì5H*²{7±övê!dxÙ[#À,|ü‹´HÖ4åáa®þÞïñèÛßfcfyuU’r㹊'àd•¦û¤N'6§OE5Tuu‘ìë#ÒÒ‚³¬ ‡×ûÌ[‚4U…õU3¨oÿö¿ü"L ¡‰"ªª“•jVUFÆ[“L¡› ›ùe‰HÔò[Ö2¹ Å%(N'ŠË…Û6âmm¸B!F.]BXZÊÖô÷¨©Áå÷çºÞ™ù¼ÃF)›×ì¬,¸)¢ˆ¸ºŠœÉP¢HKCCxÃaÉäKÓñ`ÁRXßÒÆë““,*w+x"BMMD÷îÅ2{QÕÙI¢»›ð¶mëê^Lcî‰7Øxõ¯Y»uØãÛ:I z’\5’àYU¥šJ ŠºgtU• ë´Bׇìk¿CþÆF"ûö‘ ØÐ [ИÂ\MÓÞ»º~íLýU>±5{f/Ö8˜ ªø~ÊDZËú6ªF_fQ”Yr¸X•e2ªª+a¯—`Sµ‡QwäµRVUe¹?X„õ„{ªŠ¦(, 1rú4Ã'N0}ó¦>ªkqM–7 —0•& ¸ ÏöäÀÉrC%2ËËHé4žPO(ôüIJÓtÊdà‡>Sc05®“”`p€ªÛ!kÆTU6HH+ÝŸl^ÁËùe ²±…[[‰ìÝKå¾}$ ØØˆ³¬ §ßÿÞ'½¦æéù¿‡±/žXó°ò¨PÒ¿¡"’Ҳ᫡°´,q­½ˆ)ÖõIÔs¦IÔ+¯¥ívœñ8ñýûÙþÙÏR30@Es³•ì·ëùC•eV'&Xxø¡7Þ`ü¦oÞ,°CÎ}`ò}{YØNÜá0îp˜êýû©;z”DO•»v½•Ôª,“^XÀýð!£#h¿÷;._Bt¿vÑn„m‚1üÔ˜„£(›Ë©Š•Uo–ÝŽà÷㇠îØAuOÑ}ûˆuux?¡@æ1dFô<÷70ñG›{K=ΔûÒFã´AXš¨÷!’ÖM#´´áò-NMÁ†šŸD½jÜfÝlÒ€d·S¹w/5RäuGZ…¨!|ô“îšÆðÉ“\ÿò—>y’ôÜ\9°³Í†¦ª¹Ru5¡ÆFâííÔ8@¸©‰ps3î`ð¥øhëSSL_¿Žvó&eƒƒ”ûŸpml  ú ˜[™3Ê ²êJÖJ©žÈnŽòrü ››©êé!ÚÞNù¶mø‰÷¯@f¾ ™X|ÏlÍ’Åj*]êe•T:OXª˜',ÅpP$ý¾$£ÇdH«yrÊnÙ±dröPæÞy›ËEyC±¥%‹°,…õ|TÇòÓ§Œ_ºÄÕßý]¦QÒéMdes¹75QÝÙÉÊØËãㄨ?r„d_å º‡Öó,5x/²¼ÌÈñã ?NÍx‡‡±ÏÌP.ŠùŽa³Ë¨hªÿ,âmBYá={ˆ´¶ïê"90€7ÕÃÜ÷³Š MãŸÔÿñâyH­m.>-&ªt‰Ù qŠ IDATœTÚDX™BÂRÅÂM1jIJõ`ÙtVZË“”ùÏ™IÚ‹ëê"ÞÝMÍÀ±½{õ\–U¨jÖ³‚´¾Î£×^ãúûoÌܼIfyY÷k7>†;Ä]^NEs³¾œ>0@lß>¤ >¤¼¾ž`mm~Õ à ™c¿«ç¤Æ¿ ËïÊ·­¬fR[(ªTQh~>¥‡}²á£•Q·þµR‹‰f¾Tl6|‰eÉ$áæfvþ»Gí‘#Öj‹°ž6fg¹ÿÍo2}ó&ÞÊJ|‘s÷î!Ølz}ÍΔUUᯪz)¯œ«ccŒž>ÍèéÓ,ݹƒ8E! x(4J( Qj3·¼dU˜#¢¢µ•è¾}º’Ú»—²xO$òÁ:W®ÂÓßÖÿèÄ7¶ž²Z*ÔËNÇÉ”`™$¥Jy)Û¤mNo™ÿUñ~ÈÞwE"Ä:;‰utPwäåõõ”UUáD¬³Ý"¬ç‡l¯Ÿ7Áîv£) J&ƒÝíÆáv¿TÌr*…¸¾Îúä$Ão½Åè©SÌ_¿Žmq*ETQð¢[Ð;>-E\¹¾<§ÁëÅî÷ë Ôû÷ëè º»[ŸÂìr½·M‚Q5oþ8,=€…Òc ‹]F·*î,AfZ6‘.çóP¢ARYWsègþõ‚XÀí¯I’3Â--ôþÒ/±ý3ŸÁ ½‰Ü,Âzù¡iˆkk¬Œ±2<ÌȉÌ\»ÆÌ•+8WVð¡O¿ $• )í2ZjNÎÃÝéÄâ­®&ÖÑ¡·ÿìÞMt÷n\ååÿ¼÷?s æ¯À­ÿ£´Œ+&¨ ¥“楒éF)‚jä¢6‘“šoÊ•¨Š53QÙ¼ÕÕøëëIôõᯮfúÎätšÝ?ú£4;öl-y,X„õQ…´±ÁüƒL]½Êø… ,Ü¿ÏúÓ§(““”‘0áBïOÔŠÂ>óp‰âû²YyÙíøªª¨Øµ‹h{;‰þ~ÂÛ·¬«Ã ýóW¹.ÿÏz]ÀÄÛ°ô¤tœUªÒü{VÚ(;0 þrv4F¨WLRÙÛ ¥]ðz)ß±ƒòæfâ]]Ô<ˆ?‘ÀŸH ®®’^Z ᭬´Vü,²z½"Š(™ ó0ôæ› Ÿ8Áâƒ(++ëëxä½lµ¹EnÓh®"ÂRÍá@p:qWV’èï'aL¨mߎ+ÀáñüóCàô<<ü ¼ó'0ÿÀ°](¡ªŠÃ»÷RXF¨§Šy«™ŒšïG̘¨ÓE7”͆êt¢y½TîUÝÝT÷õé¦~>ŸUn–…­B½ùy½aúáC†Þ~›ékט»s'ç4ê&?G0ëÝnîET¶ÈQ™<¼Ñ(îÊJj"ÑÓC¼½ÈÎß~n}&/ë’çŸ>WzD´yÅÏ\7.­°´L¡—{¦ˆˆ2Eê©@Ey*ŽPwAžSOèa d"°‚ò A@Ä:;©4L c¸ƒA\ÀóéÛÔ´7 MÓÖ×™¹u‹ñË— ÖÔïè T_oMä±ëåÌM¥æçÙ˜™aîÞ=}ë[<øÚ×@±›rQYÿö^`ó@‰bwW0ˆ;Æ_[KÝ‘#z¨×ÙI ‘øp—ÜÓ«0zMgÎ?ùï`e¡ FB3\F³S˜sêɳ„e3Ô”* s e˜úåÊ®L ÊìUPÈ*àñ`…pÇbT÷÷Sµ?ñŽ"»w?W— icƒÙYÖ&&˜¸z•µ‰ â{÷"­¯3zö,cçαôô)6—‹x{;µPwô(µ‡áòû-Ó¿—ÿbµïš‘—š½{—ñ3g˜»}›åÇÑÒ霂Êú·c"¤bd =I®9Hé4*`÷ùmÛFhûvŽ#ÚÚJhÛ6ÊëëŸM]ÐÅ¿‚‡çàÔlÊêgú4Ãf†tž°rªÊpCÈYѨ:Aå6­HImAR"€×‹7‘ ÖÜL´½ª®.Â--z˜ûíåTŠ…wßeáÝw™¸x‘é7X|÷]RSSãq†l6Ö&&P% Õ¸0i©³W¯²>>ÎÊÈ©…’½½”76~°¢[ –Âú0YZbüÒ%Æ/^dè7ؘž&5=²¶V0\"kìWÊ™7GTv;š¢íí¸+*˜¹{)¦ª«‹ú#G¨êèÀWY‰/}v¡ÅÓð×ÿ'<¹KóD¥Æ}ªòežæzõD°e[aL9©‚Ρp‘P*±ª—µ¥ 46ëêÒkÃô07þÞžYfþI’˜½s‡ñ‹={–ùÛ·ÉÌÌ ÏÍáV”\y‰­(\7ã*€"8’P{ô(u‡QÕÕ…ãÞ®mÁRXY(¢Hfy™õéi¦®]cô̆Oœ`m|MQd9GN΢|”R¤ ìŽòr‚‰Õ½½Ô>Luw7þš="µ°@tÏ=ãp<»“tm ¦žÂïý Ý… =?¥É†g»Ée4§®Ìc»²6-r^!÷çåªLµQ²)Ô|>¿Ÿ`s35‡ko'ÞÙI°®Ánÿð‹Wçav´pÒǦ‰k㓌œ:ÅЛo1ïvYf,Ó¨i[Úêdû56Û!(²Ìì½{¸Âa==Ø­|–¥°žE>jùéS‡†˜¾qƒ‰‹™¹y“•ÑQ4Q,pÝÊÙ|NØÜnÊé.ñ®.Ý¥Òož{ˆpîm˜¸oÂk’K¢krž¤dM'ª¬‡;†%KvЄ’­4§¨ÌeWæA3IÙ¼É$mÛHô÷3J.‚õõïUmê X~¸õdY™Âbµ;çàí¯v?§óÖ3­>R>tÍh….æ* sꮸ²CleeTõôPÿÊ+Ä;;©Ü¹S÷¥·ËRX&Ögfxø­oqç/þ‚ÕÑQ=?‘Éè¬Láˆ.³’¢8ì³Û 75QÙÚJõþýÔ=JY<þâ&ÏLÀoýopç2Ì åNrÍp•MãáÅÈC¬#d­YÔ|þÉ|âš› *[õ`óû nßN]{;q#a¨­Å¾wñæÄ¯ÂúƒÂZ&/ÂâpéJù"RÊyÅdnlZãgŠa;£Ê¦†i­t§P±z4÷lšËLvýÈÐñó?O¼½ÝÊ[Y ëCû$ ycƒå‘n|ùËÜÿÆ7ؘ™ÙÒ³½8/… èÍÓ>ÚZj¤æÀ==øb1Ï 9h•ÕìKóð¥ÿ .‡™iP°Ï('IÕOXY)L®›=Ü3%ÊIèÅ›x<Ø|>*Z[s%UÝÝx+*°»Ýº’RGÈL+S0óùÂpMÖfaCܺAºØ´/e"©Œé~ªð5ša,g V5ÝYT·ì*é[/£ÛÏ.‚׋¯ªŠd?ɾ>?ýi‚µµVÓ´EXäL†ucBóôzýüyVÇÆr%)'»Ó‰;"½´„"I¸µµ„Iôôèé!ÚÖ†ÿNRI/.Âà îé–ϼMùßÿ ‚`䦔l¦ ;Ž*ªž(Ïæ«²ã⥡])‹dÙH–»*+ñTUÙ³‡šƒ©Üµ‹ ê'·3™¿,ÿ,(é¼,ÙŠ”RïAVæçR%ˆ+'(³§»"éŸ9­|ïÞëLIeœÁ ¾d’@}=ÕÝÝTuukk#PScŒZ„õáaáÝw™dòÚ5¦®]cáÝwY›˜@Å’2ßLݽ›HK ª¦1sçš’½½$º» ÖÖR¿°5[°8sõ*;Ο‚Á«¸'‡´üÀÅ(ÀLÛò+u’–×%N‹‰ÉLZ65‚€«²’ÐŽzñæÀ@n"µ/Ͷ2âAƒÌåë:Þot)˜"ßö’ÄdÔ€©é¼rÖ¿=£jJ-í ¸Uó´½¼œPK‹^QßÓCUWd’²ªªöiŠ‚¦iI~œKÓ4=bðÏþŒ{¯¾JfaqmM'©¢·ms8°9x#jŒ^´ºÃ‡ mÛ†ÝífññcüUU8}>œeeÏý@Í6O‹kkÌݽËäÉ“Œ?ζ'iX_¦lc Õ¦• y$›¡¨ÌJÁ¤¶D6[¨Û#+ªÃ«¢"W]^ÝÓCd×.Ü¡NŸO?i´%]2¥¿ò·€UFõ?Rlw\Jʤyoo¬¢$¹–1lg²›ê©#7eòn—\\¶h5¥mvÍ~öì絇BDÛÛ‰îÛG|ÿ~}}úh²øÝKkkÌß¿ÏØ¥K8<ª»ºˆíÝ‹³¬Ìb¢:a©²ÌÄ•+œÿÍßdè­·76W AžY]Åå÷¬­¥º³“D_ɾ>B/EBSÖ¦¦XŸžföÎFObùÂls@ ª]|ª© jù‰7’AXÅ™Z¡j*¥&@óxpG£¸£Qª{z¨ Ò°¶›k‰ÔeOë+«ÿ=h z-nAHÅÖÇ™Òd¦™›¤ µ¤šï›†JÈRþ6››’} Žœ-½Pó–4Åy8QÀëÅ㩪¢ª§‡xW•­­DvíÂõ‚& ©ŠÂúä$kÌ¿ó£§O3~á‹CC(’Dd÷n}}Ô>Lã'>ñlëõ>Fx)õ¨´±Áâ£G¼óõ¯3sû6v—‹Ê]»ˆîÚE¢·—ò†–††Ð…pS‘–‚55/‡íˆ¦±bx¶Ï 2zú4Ë"”NÓ$—®bÌÌ&ÑɯЉä_Š«ÉÍuQ9c?‡_M •ÍÍTuwëÅ›uu”×Õ•>i×þ¤³úóü’i©ì|©ûE JË©'1o7£™Â;Õ0óS¤ü€ I2™û)úí&{62Ìšù%&ÒÖFÕþý„ššÔÖ~aß'–?fææM½²þæM–îßGQDÊŒ]½vïOfgY#³´¤_TžsË’EXì.ÞH„Äþýx+*ˆ´´ooÇWQ»¼ÍÈÿ8Üný ~‘ö#š†¤»p±óç~ûmR““H D××Ù„Ñ›§³D•+7Ò6Û!—²§*¶G–Åf£¬ªŠšÎN’ ¼¡oEE‰0CÓ—ÇŽéåÞÊ; .möf/UIj¾ŸÊ“Tnó9(Õ4GP5ˆIËä•”9/%˺{–¤Ò%ª87—ýüŽòr¶ÿëÍÁ_ùÊâñç[Q¯(¬ ³2:J¨±‡ÇÃÓ×_çéo°zã¾¹9Êæç É2ò}çiç™nj"ÔÐð½s ߆õó0õëúãRF}¥ËÔo¸‰˜Ò…ê*ö™ KÊ–*類¨l¶BNE›ÅÅ« à ‡©hj"²g‰în}„ÛîÝϨ>dúúuýýß3ü­oáElcc„ãûVÑ'OËE¡ýVå%²I¥«Š‚+$ÚÚj‘•¥°>¤üÄ“'ŒŸ;ÇȉLœ8<èÁ*§Ó¤—–XeääIÆNœ`òÌœ’„[– ªjÎqÔLR¥ì•Ê!wÀÚlØ}>œ¡¡íÛ©9p€šC‡ˆ··ã­¨Ð©ßÏIºtƾOXÓ—ÅgM[䔓THB9‚AK—‰°ruRr¡GVq ,]ôïs‹.v¿G @ÍÁƒ$ûú¨îé!ºg>¦Ëáx.'pÖméɆOždôÌÆNÂ&ŠØeŸªâ#o…mÏg ÌK)hóIs8°ûý¸Ãa"»v‘ìëÓûÛÚt—Y‹¬,Âz¿66X~úT_á»qƒ©K—˜¹rmi©À»ÝQtÀneƒœ{,ÆJ –SQîp˜`CáíÛI8@uW‘;õÉ/$y<{æ.ÃÿU/à‚Ò¥í&u•õÃÊ%È¥|ÙA1aa–™Ìrãã•Ò!^¦A“”/Ç_WG¬³“DO¾ ¼wï‹i…Êd˜¾u‹Ë_ü"ÃÇ“žÍ9Ìf7'yÏ~³¢RK|ÿŃETÀWUE ¾žÊÝ»Iö÷oo§¢¥÷ *»°ë#Œ™[·˜¼r…±sçX¸{—Õ§O‘æçq)JîŠê¢°?±Ø»].qÐÚ¼^*öìÁVVÆôÝ»H™ ѽ{‰íÝKí¡CD÷ìÁ_U¥W˜ÐPG•àŸ„Õ;°tGCr‘’*š+¨ÞX¹“9,"+ŠVÿrõQjáJ^©r¬L‰HµÛñ%D÷í£jÿ~==„ $“ÏÕØ¯T>òÉw¿ËÕßû=FOžIÊùôg•”ÝDTÅß½9ô7_¼TÀ—LR¹{7•»wSwìMMø««õ² «WÑ"¬÷#ûåti}¹wÞaììYÆÎŸgúêU” H¥pFoŽ"%…=¾›¼Ûm6p»±y½DvïÎ0FöìajpÔÜÕ]]D[[qx<ÿ¼Q]šËcpíwàá×!5–'*󲚙¤Ä|Ct¶þÉLTš˜WW¹Z*1Ÿ›’•Bo¬¾J®êáñ€×KY"AÍÀ€¾`ÐÛK ™ÄáõêáÞ äTŠ»ó7\þÒ—X¼%gähg³ ‘9ìÇáÀævc/+#ÒÚÊúüõ)bmmD÷졼±ñ¹‘“ªè¦A6»]ÏEf2ØN»9FN¥ôFø…½ö—¿ô%foÝUÕ ívl‚€&˹Ð/{‹Ýާ¢‚²d’Ê={HôõmmEæîÝà QÕÙIȲT~føØ–5ˆ««ÌܹÃä•+L\¾Ì½{, ‘Y\Ì —(¾šf J*‘£0o¿ŸÈ®]TìÞMuw7ñövuu”Åã›TA¾ÿ!OÎÁWlýŠHJ“óD•µœÉ–˜Ã?LÕè²R˜*íRláö€^Ú±ƒÈîÝÔ<¨êJ&uÓ»çØØ»1;Ëôà âê*MMˆëë,<|ˆÝé$ÔØÈÒÓ§¬ŽáD¨=xl6A ÞÞŽœJ±>5E¨¡pc#‹1ÿð!ª(ê«x~?ÑÖVâÔ­Ï\^F^_G0® nò¾í6S¨W¬¦ráŸÍ‚ÃA¬£ƒêînª{{©éïÇ >»fZ)R þËÃÒ,o.…7â0͘¨F~rVU)ùÜTÖÔ/þåÜGµÍU[墛 ÕáÀæóni!qà5ß·O$‚+x.Vª,£Š"éåe}Eïôi&/]bcf†²XLWÕóóÈé´^"dÖÖÐÊÝ»Y˜ îÈê_y…²xœèÞ½”Åb$º»YaäÌÜçÎ!§RúªíTwwëãÈJLÑùPÚi¤´¾™DlàæçWW™¾qƒõÙYb­­hªÊø¥K¸ƒA==ëë?öV΋0ö ½ù&çã7˜½u+—{0o¥LýJÙ„c·ã*/ÇÙ³‡Úƒ‰ïÛGUW×óI_} ®|Ný‰q0³©OG3‘Rv<¼*¤%©*ã~±EòVÖ,™¢d¹»²We%»vQwäUIJËðÏê;Õ4Ä•¤T w0ˆ¬Ž³:6ÆÄùóŒŸ;Çä… (KK›¾ÛRê8WóT^ήÏžîÿðˆîÙ³©Œ@E–††È¬¬ݳçÙª¦‰û0ûH¿þU8ýçú›Më ¥+~íÏXgäÔyîœ9ËÔô4á†Ueqhìv"mmÔ=š›3à­¨øØ–G|¤ +½¸Èܽ{L^¾ÌäåËL]¹ÂÒãÇš¶)aºÕ3QyÂaÂ;v57+[[©hn~>½]cïê^í6ྪš/ø4–&^XÆxøl8'«…ªJ c?Yo°Î@-®,ϰÙÛ\|‰åÛ·Þ¹“†O~’²ÆqÊê¨cÓ4ìš‚ h› ÌeÞÒ{Ü/i% ¢ñÓ?ÎÂÇLݸÁÌ;xÊÊpûýlŒŒ`¿{—̽{lÌÍ y¯ÂÜìs*à I8@ûÏý ÇŽá./1îwÿ ¬OÁSðîųEô°¬BfFT6^¶j<•D‡ƒ²ÆFª{{iüä'©=|˜@2ù±Ì£}äBBi}É«Wyzü8cçα<4Djfym­¤w»ZLRÙD¸Ñ´ìðùHìßOuw75D[[ñF"¸ƒÁ瓃Ñ4øÏ? .ÃèÝÂ3°¨DZΪ#ÃYÔŒ|•’O®gI+[e^ª¯¹˜¤²ÿÎ QÕ½ŸêÞ>ªŽúaÛ×) ÞÇCPǰkOPS2Böf´÷ödϺˆfýÙ³×M·¦×Àþ—_!0µˆ}lŽØâ6oiQbme»ñš Q³·˜ˆ)ÛX^º©÷n:7‘–œÑýè=ªkä'¯ë²ÌúãÇ<ž™acf†ÙYjˆwv~ìF“½Ô KER ¤¿pA¯>>wŽ¥'OôQ]°i3«&Ap¸C!Êëë©?v EU™ºyO(DíÁƒ$Œ¤ùs_r¾uÎ|þàWÁšMWN6QŸ‚*é*ÁÔog žÈ…ÆVìá^܉c&(Ünœá0pG„Úþ>*mÛwqªUÆ®(84‡,c—ŠŒMRD ›¤nv5›û™ Ëlœ*|N[Ïÿ\Û0­Sz_b¶1­Z¼oPhÁeþœf7 {YÎòr<••Ô;FµqaŠ47?ûéé]ØX€K¯ý?ÆJ›ÊNr«µFÈ.gWw¥ü~Hiwiy~7s½yâ‘b³jj¢f`€æþa?ýi\#ƒÀ—Va‰««<üÖ·¸ÿÍo²ðà ¢IRN=½W¨çôû mÛFEK 55B;_<ÎÒÐ;?ÿyÂÛ¶=ÓÌ–¸sN~þøÿF[]@µëåUÙÿlѦ¬êÞíi cÏUFË'Ø%5?ç½Êì™lh P_O Êöáv wý#ê?bWY')E',»ª`Ul¢Š iim³“h)Oöb†1ý\K'iJßd)oM#Ëú}IÎÛÍ¤Š¸0EiKds+Ttß>v~þóÄÚÛ oßNxÛ¶çc73Çÿ Þþ L>Ì/;‘U®6NÎw HFþ1ûX3m¤ ²*eŸsZ5Ž}oe%žHO8L°¶öcEV/­ÂÚ˜›ãþ«¯rî×ÕÑQ`ó ÁâĹÝí&ÜÔD²¿Ÿšƒ‰··ãÇñD"/ÏÊÉÿð£ðè´‡·QlF2Ø8 mÆ%R5æ nØò>îiÁðnÏ’T‘ErÉ©0ÙÍfÓ§2‹Õ¯$£_Á]9øä# IDAT5ƒÃ¹Œ]ÕIɡʹͮ*Ø%Á`B!;;+S‚9ÞaO¿IéMÒÙ)8¢‘wåüI›Qó«Å6ð¥ì ³Ÿ»ª®.~ù—iüä'Ÿoè÷û¿ÏÁ‹ùÅùGóÀcT›$›¾Û¢çÍcËR–šd¿koM ‘Ý»©Ü»—Úǩرoe%ÞŠŠ]±ê ',U’Ȭ¬ ®®2yíC¯¿Î¨öÉétNEÙ].4MC•$0¬’]~?á;hüÄ'ô“qÿ~=÷ät¾Ð/JSU¤µ52ËË8="óÇ_&øÖwÑR+È‚†dÓTŒIÍB¶XÓäßžÎú¹ Êl\<½8Û§§Úlؼ^e55Ô èÝOU_Bü»d„oã@EP×°©*NMÊ‘•]Q°É*Bq÷òVSnÌó3”œz³a©†¡Ÿ,šì ¿Œ)¢Ì°¹qºØ’ÇæõâðûqG"ºGXo¯~Ò65=ûäô8L<…ÿåõÞ­Ôš>wÌ”Ì.’Hj~€ˆl„ºÙÐ^1ÈI4&!™/F¥òu ÃDZ>÷9:~îç¨Ø±Co”NÍâÿ" k}f†'ßý.¾ófïÞeáÁTQÌ=os: ÖÔ¬­Å[YÉêä$r:MxÛ6_y%×§å‹Å^ŽUË¥%ß}—ôíÛ¸¯^eæÚ5ö\¹Œ&€ì€ŒMWT2Æè.ÓTœœj0‘–¨mmlÁÆFÊ·o'ÑÓC¼£ƒŠÝ¼Uï‚aCþOh²€MQq¨²~‹ž—²ÉzNj“„I— ©-¦Þlzά¦Ä|¸—½•ä6…õ¥|³ÌjR\ÆjvÓým?õSkjþŸ<¼°–¸ºÊÔõë ½ý6#gΰ>5…¦(Ø‚55ÄÚÚ¨1†[ú“I2++¤ñUVâO$({IHJZ[cêúuÆÎŸgöêU>Ä34Ddm2#9*a\Q³ÓšÙ¬˜r!¶¹ @d³o–æpè­/{÷’ì룪»[o¤ŽÅÐìÿ;ª<ˆ,^EÜŠ† h¹ðO4l²ºÙþ2]‚1¾—Â2y¼ç\LÞX¹r>ü3O¡.^d,®3÷&–oÛF¤µUwZíê"Hà¯þÿÙ{óà8ûÎ÷ÓÝs0ƒÁ1ƒÁ $Aâ O‰’,'q’Mj¼T%ëªø%©——xíä%y®WŽŸ_Ö»›Ä^YÛ‰UÙœ+mœÃ—|R¢,’â)Š7Åû €¸oÌLßï>¦g0-›%[SÕ…!‚L÷·çç›^Ý´ï¯ÿ;{ óåç1kúD”A°Õk’Ã#òb¥y¢-¥èf%¯pSÒ°˜Yµ==TwuѸ{7ÕÄ %ü$=™`ù£QR½½ªJ¨²’ñ ˆÕ×ÓòÄÔ P–NãDÜYÓÞV àV*ÕÓuÔl-“aìÌîìÛÇÈK/! Ó»´Dµ,±gÀæòut+ŠÒWfµ/;I}>Ì`!¡ª§_<ÎðéÓè™ ©©·Ývît©EiŒ/aÈŸÇG4Ÿ* h&¢aX‘”j–¶æ*fà V‘¯ ×tÂ1“Ðm^»3´ªÙi®nGU»Àœ3Wæf¹Â,I˜¡bYUëÖYŒ¬íÛ-F˜ 1\º¤®ªhKKø––˜{þk$>÷ Ì…I4%ƒaÚ4ÍÞÏ4¬:+yD×Ì‹“f”vã.Aš>B(„¯¼œgqÜf„ùB!|áðOì"õ#¯ai¹³7oâF)ol\=¢äZcÓ42Ì 1yá#GŽ0ùê«—.Qf4qòs_¥†5ÞØõFµE*PUE ºšêžj·m£rãFb­­L]»FvzšÄš5Ôtu2”´  ^€¥_MÅPDL[¨Í,)å "ª7H ½w'jòz:Ñ“ã̬«–@9ìvÅ©Ïx éÅ«.I’IBÉ$ëÖѸw/5¶UW¸ºzÕê2º¢°82ÂÜà ³Ç#;FúÐAÊ3³h>»¸oæß`§›«`ÕsRaTå¸JÙ³9ç ¡š¢vvQ70@jóæwœtÞ]·D§Ò^¦:z”±“'Y¼}õÆ ²L9–ÁDÀÓ¥\‰Ù^Ыö¨™VD¥z뎦õQ&/Rê 5(ì'Šù¡§‡šM›¨ëï'±v-±ÆÆwÀ~ïÖœ°ºnu+gg-›®9vŒìð0ÌÌÍå¨Âò”s–§Í@¨Š·UtQD÷ù¢Qª{zHmÝJjëVjûû ÙÖ\’ßÿTôy˜þÌþ3d/^Þy…To%âžÍÁr‘ÇžCS=ö\Z¾&¥yÈ£®HÙB%S$R‚€&Iè~?átšêÞ^’›7ÓðØcT¬]‹?)¹Xü°ÊPU††¸ûÊ+Ü;p€©Ó§a|œöÙYbªJ‚¼±„EÍûG*nÉ+ÔKÍÁ™>Ѻ:êlÊlî]Äš› D£?Ñ©Þ;‚õýRÑl–¥‰ 2cc®@œ8|ÿ>AÓ$İÌ%ä—§WBáÛt¹€?Û&Þ_YIuOõ»vQÓÝMuw÷›s~Y:KàÖXþ{Õ¿¨Ê눣x&¬= -§¥«…犔–¨œÔÇû#äUÊÊðWUij²êP[¶PÓÝM¼µµÐ…úa7y––ÈŒYé}û9r„Ñ'ðÏÏÇZy©$Zé}.®A®IëX£¾òr‚UUDëêhÚ»—Ú-[HmÞLEKË;êóŽ`}ÿ"êÜà S—.1|ü8c§O3{ã ·n0M‚vå˜ ÓFµ'q)k.C UW[³Æ©;I¬[G¼µ•H2ùæReî|¦¾óç ÿ³R“£+aA=¦îb´šŽ4•Ô­Iiù¿Ó½Be,GÓx)#ºf åmm$·l¡¶¿ŸXSå øV™%/,0tø07¾ó¦^¹7ÈÞ»GÄ4‰aÜÆXÙñ¨øFô†´}H‘±–ª»»© ÙÓC¢­ò††wìè߬ïÿXáîáÃÜzáF_{ÜÄòÔ‚,÷ðºà8µ©7rÁñb’ÖsMOu;wR¿c‡[0”—ÿpCŒ—?£û`æTi;–ÜVQ]ʱƒ×½"å] qÊjá>›¦Yvòn‡Ë\þ_)eeTvwS¹q#5}}4ìÙc½v›ö(¹™.>÷§>ÿyæoÜÀ§ë„ì›’cÓå§4«½¸i²ìs’dºîÞ¤kÖдw/õ;vPÛ×GY:M¨¢â‘QLÃ`ìüyDI¢jݺUh߬â1}ý:GÿôO¹úÕ¯¢ÎÎ"Ù‚€s ¯Á@)ŽR±X€àÇñÇã¤íéêZ›Ùþ#3aâœø?òS¦ËMPå¢*%I™J¡Ó²¦-ªâ…[çóNªWr]QÆbè™ †ÍKsÒ:ç!ƒèš†®ë˜‚`¹n——“hk£qÏê¶o'½e ášD¿QKŽ™¯¿ÎÈ«¯2yå ‘šZ좶²´ÄÌ­[˜†AzëVšläqY*ÅÐÑ£Ì\¿Žº´dÁêR66I¥˜¾~C׉57Óüä“$7m¢º£Ãµf{(ÃÏÂÒârç]´ÙE¦Î]¤âåïs7 DL¨¦ô§R)j+R4Je[»>úQÚÞýîG‡†þq,-—³ØÞçÎ1xàÓW¯²42BnrÁ0<]¡(Ô/æµ›‚@¨ºÓ4ÉMMÏG¼¥…šînkÉz`€²º:ÊëêÞ2íßÿ6Ü= ·N¸m'Ó>«LÅZ äÒ…uWtLÏj‹™ª¼«0zÑ‚m±P™‘e--ÔwvZÅrÛq%\SC [µáEÓ4™¹~ÝrÞ>}š{‡#˜&‘ª*´ÅE–††XAY\¬ýÓÙ«WyýÙgYšžFžŸ§vË"É$mïzáÊJ¢©ÑtšÁ˜¹~ж6jûúhû©Ÿ"ÖÔÄâýûd¦¦ˆ75¹ËÓ4j¿/þçåPù£_……LÉa^Òv£DÕò òÅðÂR‚UjÑùo+;;InÞLí–-ÔÙ»˜o÷5Ÿ·\ ËÔu&¯\áê׾ƭï~—©+WвYôlÖµê*®GPQ~?b(D°²’ÔæÍÔmߎ¿¬ŒÑ³g‘š{ŒÚ¾>"55KÖ¾<‡ÿ|÷/aâžía­xvçO° ¢ ‚C>°oTÓøyíáçQâ®–í®Iz € [³†ÚíÛ©îé!Ù×GÅš5ˆ!1EÓú- +9uü G©;†}˜@vz†»‡q÷Ð!î;†:?žÍ‚¢à—$$ÛÈJŒši‚(oogLJ?LÇ/ýòrA°fíîÜaôÔ)kÖPÑÖ†/¶¦ÈÁå©ýH)‘¡Áâ¨õbäyøÇ÷äSù¬ S£ËÕÄ~_ »qbäòlÎ)ç±Ðš^Ã(µ¤P×^ÂÈf]Qòb‘))ç£à÷I¥(««#µy³…GÞ´‰Êµkñ‡Ã,ML`ê:ÑTêáG·ÎÃKð‰_spLûÐ|z‡bÎ*1—/ +‚%TÎáÎ?y°Èªž§8Õ‹"R"¿¦†X{;õ»vQÕÕ…oÝñ5•ˆ‚€hšˆ¦j~Åø_ø ¿¦âÓ,†»¨…ôÐR`>¯„—Õ8ðñYûÏó–Ý¢¬¢.gµ{yXÞQŠâÂa€¥úúè~ÿûi{÷»Wç=º#§aq ¾õ{¥Gà‹9÷v䄽@®«yÒªC¶P<©»C³PÌå[U^‘â߇‰J¥ˆÖÕѸ{7~é—Hõö®n­Ê4ÉÍÍaê:¡ŠŠ‡Rï|ä)¡²°ÀøùóŒ_¸Àð±cŒ=Ëô•+в,Š2ŠDÊyom¥rýzjººh~â âÍÍ”74X ¤ž»Êª0´”üÅÂ¥ãpõ”UuÒ°Ã}C³Od;ª"kETšÝµËJ6qÔsªfÞ ÇËRrEÊ®G•·¶’ìè m‹õbÃ>BÉ,ÁÐ9Œ}ÈÊ(>Ýb¶ ŸªáÓuü†ja‘Uá¡X°ä@°r¡Ê~©ƒaæßGJb+­Ã8§·îX±f »vQ–N?Ü÷ôø`ü2Ü?·_Y>ÀëMßK„E^ÇmÝvâV=¹"ÜN®D¯e™É „ÃÖD}Wµ[·R»y3±æfâ«Ê“çæ;{–‰K—X!ÑÚJýöí$Ö¬yàäGaªÊøÅ‹ÜÚ·Á—_fòÒ%”ùy«Vaw@O7Fôù,j®ƒ("ú|„«ª¬ùÀÍO,E½óä Ù,ÄAG–%I«¢ˆ.IVíuÍöì!=0@zëV"©²2ËÒë!§}¦a`hZ.ÇБ# =ʽƒ™¹u uaÃ0¨íë£éñÇizì1ê¶m³Ì‡Ðϵꂥ,,píë_çØ'?ɸíÐ\üE‘`,F¤¶–Êövjûú˜½{—Åû÷©êè qçNêˆ55=2~µ²¸ˆqçÁû÷˜9u‚Êg>ž¦<¾º]«rÆŒÂð>GiòdAÂç×H UVRÕÕEíc›m„ÊuëNÉȹ)ϰÈ’¦ã×UËG³„IÔ DÕ°žÛn8’¢#È&‚bZ\÷Rå!‹:v\f._“qÜp ŒŒõ\Smg嵯X„H„@e%Q;ÍO÷÷[»kÖ<øº£¦À•—àØÿ€s_) ÷¼s ÅÊZ$XŽã¶®æw.½>Åè•H«º$ᯬ$PYI¢£ƒ¦Ç§¦»›doï›[œÿQwïÀ˘†Îì­; •áÃǘ¹~³(ê“E’××SÛßOëOýM?N¼¥å¼_«šf''¹öopú‹_tíäËëëQÉÍ͊ǩްªõë©ß¹“dOµÕ., ŒÅ(ol|dæº,3uíSW®ÐxüeÌ£G];O¥` •n‹”"Ø8\lsS[´ 'š*!L¹åì¬S)Ê›šˆ¯_OÞ=Hfë§ Ôf˜1_dB7ˆdl¡Òó‚’®ãSmáÒ-'Ÿ¦¹‚åÚwÙåZxå–׬ ÌÏ-Ë–P‘³—§íôGѬçmT×òf)ÚM±8‹6£>ÖÖFª¯Ú-[¨X³†XcãÃ[}9õU¸zö6Ÿ›ª+DTÞÜY(÷Ð,\£[oDUøO–-,xE*”NSÙÜLbÃËPcíZbÍÍ?õ-è+hÏþ=ÂèmÌ3¯ÂÁý`@L…2Úsy³`Æ.U΋ºÎÒݻܛ›#;5EflŒÆÇ§¦«ëGÞY=Á2MÔlSשhi!šLÒ°s'‚$1qñ"¡ª*švï&µi“;Ií¥FS©G"R†ª2}ý:CGŽpë…H]yuóSg'ð©&è ˆW¬´N3ì¨ÊþèÆÕ鎷°ì%ˆñ¸U›°Šæ72Zõi¤èA4i EEÏêDm·W¨ŠEKÕ]³ IõØwÉû®•L$lï@<ÄQCÎJ8hdÓã‚ãDšb§@†Ç²‹Òs°@$BUw7U]]¤¶l¡á±ÇUVŒÇñ‡Ã/Õ™‚ÏþŒ^³Ü™âÙJópž»‹®yÜn‚…‘góË%Ò>µ„@+‚@(•"µiµýýÔïÞMbíZBâñU¥ð. 1ý¥¢é…ç1¯_ÀXšÃ4@´»˜ÎÈŒl–/5»)° ÈÍÍqÿØ1GG™¦åÉ'iس‡²ÚÚ·OJ˜šB“ekþççÝ–ô£n»š†<7ç.Ð8Àýýû1._f@–i’LL 7ýSÈúì ÏÌó»5³Ä‰é9ç½$3@ª¨À_]M²·—ÆÇ£fÓ&â]ĈƂqˆIíoTA5Ü(Éœt½ÀÙ§Ù¶]ÅQTqÁ$³rÚç²Û½-xt»ÓåXu9KÓªn9\©z¡@y¿¥Râb5%‰Šuëèýíߦë}ï#ä «>Ìs!»7ÏÃ?~.ÃÀtl×ì1±¨˜ä¢ÜŽ­YXgôÒUU»NW*Š"Aª¨ \_Oª¿Ÿ†]»HööR᤹«qØDvr’…‘F_x¥Ã‡éÌÔ… —/“˜Ÿ§Xg_?î*YDy £¨•ØÝ^L®.ŠDêë‰66RÕÓCÓ“ORÑÖFEk+þ„Æ¢ñUæõ¯¡(×1UÁ'Jr¢*Í6=uR?;í#o%_ìzSlS“+ñ1—ªÈŠ”îÙ[tXíŠQÚ·¢8¢ò5š~?‘º:ª»»éxï{ÙðÞ÷ZÅÙ‡ýxá_àüaøòçÜ.¥awqOçÖ51<ëLNSÄÉœU`Éfá nñê“‹¹ïwjÛ6ê¶o'ÞÚJ¼µuU;zj&ÃÜ;L^ºÄȉLž>Müª&&è°ÏsÅgÒéy´Z¢|—-ñ>«ž¨Y…¨Ù¼™ªÎNÒÛ¶Q»e µ}}o¿.á[J¬²YÎþÝßqö¯þŠÌÈÁ™6˜&ÕX`7ÁÓJ/ÅjWøþN8º§Ó®«£jãFj6m¢ñ±ÇH¬]K¤¦†Pe%¦ùOÌßFQ3ää“îx š®H¹‚¥îx‚¤ë¹ æ+ Ö QU±`™²Õ4S½âTÂk5·ÂÉ[ý+öt>š‘ë×S±~=©þ~Ò”×ת®^Õn¶¡iÌ\¿Î݃¹wäÓ—.¡ S;1AÒ0¨ÃÚqÏs!S.å‹Yj¿xüDŠFi~×»Øõ‘ho'‹=¹¬Ÿ8Á24 eaìä$S/2ø­oqûK_¢fi‰:,Ú¨ók-%TÚ 5§â?ë€ "••ª­%mßUk·n%±f ¾pØêÇ1ÍQ²êÏ#«&zNÁ”-7Q5ܹ(o×Ï+^%ç~Áò¦„žoÊùÁFg(k–6;-M©q#Äh”Š5k¨ßµ‹ô–-Ô I¥|>ëõ?„ôG—eäùy–FG™{í$Ó‡±íЗ!³ˆ!8 víL)Ì×u=)çkÄĽ8º(Ý—í.á0RE‰ HnÙb1û{{‰¦Óˆñõ®I9Ão›¡#G˜¾xiq‘°ªÒdTaòÃØ^²Ã÷CA—ò4D)E*+£jÃZžzŠ¿ò+T´µ=ÐNþOŒ`-1}õ*“.0~Ⓡa R‰å€,©bp_ñ¤T¥„BDˆÔדêë£a×.*ׯ'ÑÞ^´Ç•Á4žCSÿ E>‚‘ѳ’Q!ãÖ©DÍpEJT ·h^ÒYfe³ÓRæ§9»6ãmÃùb¥TO)‘îi¢ˆ?'R_ObÝ:êvì ÙÝM²»›²ºº‡žÖÏß»ÇÌ­[Œž:Åĉ$N¿FÃÔ-~+÷ÓD}v3ÄNQò½Å‘¡l‹–â+o¤¡ûýø«ªÕÕQ±v-é;Höôok£¬®îÑ0ÂL“¥±1ÎÿÃ?pæ‹_${ç!,o‚j,K:‡[ïØ-eMWœM,£°JA{ä$ÑÑA£íWìé!\YùP^Þµ`åff>vŒû'N0~ê‹W¯b ÎåˆESfÑFcù¼Râ5ìÂq¬µ•ªÎNj·n¥iï^¢µµDS©ÒuõP_ÄT¾‚šñ£ç,¡Ò³’åʬZ¢$ê¶`)Fáôy©Ð¦T„%—Nû ŽK5òˆ¹h èù IDAT=$[$RÅé¯/³¢ŠÍ›©ß¾ª‰76Ztˇ|Ñš†Áôõë\|î9î8ÀÂ;4ŽÒ¨ª¬“À°Ò?¬n®"ÚsRv÷V3–§:ÊtqU ”Nïè ±~=i›p©©!\]ýÈaj&Ãä¥K >Ì_düøqÌéi¢¶XE=Bå=ß –©”/ïHZ°¦†êînR½½ÔmÛæZ“9ØŸ‡ùø±,CÓвYr³³Œ;ÆÝ¸ó 33ˆKKD…¨m4á¼ø½H¬J½yÖò-B8LYc#uÛ¶Q¿cõ;v¸¶é%7âõ)ЮÀìû@›eSг†,Ú(»¸®–c³Rb ÔXtneÁ2¦»’_’vÛﺧ»UU9ušâ…a»R‰ìë£~çNË•¸§‡`,f¥º» ošèŠ‚–Í2|ô(§>óƦ2—£×®=:#Šªªd‹öP¯§\<W`0!è>F €/‘ ¹e 5½½¤¨éé!‹Y®Û ’2Muq‘ñóç¹ó½ïqgß>æ®_ÇX\DÈf š¦ëUPÌ­/…„V)ÇïGñ——“Þ¶Í…XV®_ïNׯ¦ûÛZ°tYfilŒÙÛ·?ž‘ãÇ~å²÷î°ß¬p‰7­a´”@àrËʈÖ×km¥n`ÀuC)K§ßxéV›„…—`æ“ Ÿ*È)LEÀ°—ÛÃ\tLýJ­è¯ä1X$X¦moØ…cÙ‹¦ñÌ Éε™E(^¤Ö°\©CÉ$Ád’šÞ^v³ÓºhW±x¬.-±0<ÌôµkŒ½ú*ãG2sà•ºN–±„äi”¸7 Á,• N½õG‚AUU„©éí%Õßo9߬[÷–aI98è‹Ï>‹2=íuŸ©DêW \étlC55HeedYœœ$\SC$¦n`€új:;-¿‚Gd¨ñ¶,Ó4™»}›±sç9q‚ñs瘵‘±‚¢¸&ŽM—ô Uñá,ØVmÜHeGuöÞV¬©‰²ÚÚì®z÷/@> Sÿf-%úݦís.xù1¹7Hýr¥£-3ç™´6<ÃŒ¦%X%#)ÏÌ·Ë嬅Ói ÜÛK½on&ôê%#gUeêêUFOâþ«¯2uá —/#LNjì’Ïsq3òŠë/Å §þml$ÑÑAUg§;¼M§ %o)ƒÓ‰×_çðŸü ·_xunÎ=Ï¥¢s^(‘þ¹Ïm>\¢£ƒª®.Ò˜‚ÀýÓ§ñ——[©^k+ñ––G²Ÿ»ÒãmA54ÙÛ·¹wä#ÇŽ1täÙ‰ Ô¹9YÆï9i“ ÓsBó»“KS’0Ý4Ñu$ !¤ª£ƒ´=Ð׸{7òråå?àÝÅ„ñïÁµ?娋Ë[.žCph|+ER¹•£-S¶§­íôΉ˜2Ù,wòÚUD’d­…¤R4lÝj-–Û³BÁx$²ª¡¿®ªÜ?y’³ý× 9‚29‰±°@@Ó(³ë2Aû½ÌRšøà,¥(í7$É*'“ÔoÝj5Hv零£YþhtÕEÊtÿEÓ41uA’Ü.›©ë, 3væ †ª,/G[\ÄÔõeež³Ñ:Óç#P^NMWõ;wR¿{75+*ðE"ªJÛÏü ~Ç…úaw4XIÀ4óœ|AÀÔ-°uñ9÷–ްLÃ`qd„óÿð¼öùÏ“-@!û(tBYÉǽ»ˆ"¾²2ü‰åMMÔíØA ¢‚‘“'1ÁºHûûIõöæ'®ßÌcö,^…ÿ¾ðJ)ö1·'§‘=„ÑR‘SQtåujöNX;å –§ÓçòÞÍÒ;{þÊJÂuu4ØìúdOö{Ìo{ú:3>Îýû9ù™Ï0}éR5›“ê‹+ VöB!UUDêê¬Û…9±nݪ’8µ\ÎýÿtEait”ÌÄsƒƒ”¥RøËʘ½}›¹»wiرƒê ,oG[@2ãã ?ÎðÑ£ =ÊÄÙ³¨ V‰€  .- ®®&TUEõ† ´<ý4é¾>ª»»WÕŽ¬8øÈNM‘™˜@Íd¬ëÌ4-²ìÂ--¨Ù,“—/ãFiص‹h2éžoÉKWUæïÞåþk¯qëÛßæÆ7¾23ãzJžÖ[¯€ÒÜv_Yñ–6P»u+ÉM›H´·®ª"77GËÓOon&\UõÃÝU•98ýIÛ“¯-Z±Ë” ÅÊ%Á+NÞ-agÒÜf´{§ªýæÓ̧c¦†€Nûú6ªjäË“êy<¡¬Œ²–jZ[©ß¹“T_ñæfâÍÍHŸ«É2·_|‘{‡3vú4“çÏ“+¸1ቨĢrqª¯{ŠÆe $::HnÚDz`€ªuë(ol\Ézçõe³L^¹Âü½{¢H¢µÕMuÇObææMQ¤<&39ÉâØeé4ó7oÒôÄÔnÝJyC‘dÒêD§RDS)‚±37oRÑÖFy}=s÷î‘›¥jýzZŸ~šD{;­­«Ãƒ[!ðXcòÒ%îŸ:ÅèÉ“ÌܸA¸²’@$Bnjй{÷(olDòù˜FÓ4j7ofqd„–§žrgßRÖÂð0ƒ/¿Ì½Ã‡}í5‡†gfÀ†ùy=åJu=Š‹‹•6Xµ'»»M¥ÆãÖÝíA…»¯üþ&Ü?^dc’?L›åLŽ v:'È fmÁ*êþ™vWo¤.É_ü#¡!¢!¡â3UÆ67"”A™2é×ðë2>¦‚?2d´“s,ýO‰do/ ¶ák4•"”H¬êZHñcææMË.ÌïgèÈ.<÷ƒßû™û÷Ý÷[*qƒb…ÈÊ{”54P»mé­[i~üqbMM+*¬Ôv•R=CU™xýu†Žeðå—™¸x=“!T^ŽP¦¦P¦¦,kí¢Ñ´ÓÖpm-隟|’æ§ž¢¢­Í-MèŠÂÂÐ÷O¢¢¥…²t5—cilŒh2I¸ªÊ">¢ú[vr’Áï};û÷3yáÙû÷ÉML f2VÍÑïGUÕü Ç.Ï856)¡¦§‡Ö§Ÿ¦q÷nkñQ –iäff˜¹yÓº³¾ò CG¢--i"šæ÷E#»6F¢ˆ/!km¥å‰'H÷÷S·}»5=ŒÅê³ÿ ÿòÀ¯[{ EcïŽH9x™âÍQÁ>¤l^À&R5Œ§ª¹µ¡™ÏáÿÂoªøIÒñ£@!ˆLKBȶ`åÜ#ˆL˜,a²„È!CÄÌ6²D… Q!KØÌÒsø„?‘Í.JVr33–E×Âåõõäff˜ºr…ÁC‡yõUB´¾ë]4îÙC eôìY†eøØ1ëâ¶]oDA@òû-»i"H›dPÝÙÉÜÐea•JÑòä“– s?±æf„7W‹Q¦aáÚÊ6KÅ6LˬÂM‡G:|„Û/ìgââë ¦AØ„„Ö*¥{0—Ñ RÛßÏÆ_ùÖ¼ç=Ä[[ _“ÇmÕ×ÎB6·Œãoj÷ÂøÊW¨9uÙ4Éš&9Ó, lË»µÎ¯8R[ËÖ|€ž_ÿuÊëëMJhê:SW¯rú™g¸ú•¯°84äFMŇ7ͤpÙ&ÊË©ln¦Ò.’'{z¨é줼¾þáÝUn€[¯Àw?jsn)H¡røWΖ¿ ä£(ÑNù„¬µX¬ßü¿È©woåÂS›ð£RÎ~TW¨œ3AMÙ°Bfn™x¹‚%d“%B†¨¹DP—‘dŸ°XëK€\ UÿOac þqH÷¿©T~áÞ=¦¯]côôiÆNŸfqd„xc#’$1uå “—/£år€¿¬ŒÌè(ówîÐøøãÔöõ«¯§¼¡P"ÁØÙ³øC!*ÛÛ1t¹»w WVRÝÕEãž=Ôtv¢f³ÌܾM¤ªŠš®.bMMonL{“W‡é‹pãÞxc [t,Q€†.ËÀú,´iù>kòë5Ϲ­—èV{50‹Q»y3kÞó*ÚÚJôú¢XÍŒÂËÏ.wý»OÀØ„ÝéÎ7 jíyÕX>2¢~Ÿ×ê\ëH--lùÀè~ßûWU­~ÑÝ4 æ:z”k_ý*·öíC]\,é€ã vDR)jûúH¬[ÇÒÄÓ7nPÓÕEÃŽ¤z{)¯¯'\UõðgD>ñ‹0{F/•Ü×Ñf»b –ƒB6U+í2vd•Í“Hüæ»9û ýœûÙ-øÐð¡áGEÂŽª2íç†óg…€nE\!S&`Xσöó°µ>’%"d\‹ Kø55¡eòšûçûˆvB¨½#RÑülÁÝ}þî]î:Äݘ¹t‰ìÈÙû÷ñ©*’("ˆ"š¦¹Á‰æ­;ú|D¨Û¾öŸýYR›7#Š"#¯¾ŠìV{vþöá•gAžZæŽ`:>rö¡ÛéŸ]‘³£+û¹jÀLº‚±5)þçWÿ-êà ‰®XùLëðª%R†%R~C%hÊîçý¦‚_³>tž#»î7a!‹OÓ2!ƒOÓ™9"BQ6 ]n¼f–™G°`‹Ù"‘@¬€%0—ÀÌ€œÓYÊÈ,È2K†á~ËâFgñ"­Û½ ¨ìè`ÏÇ>FÛOÿ4¾PÈun}>+ëÐ4«ÅÿÃFÎÚdîÂÅ߇‰× —ƒìÒrHß ƒ¹ÎRxña(6iÕæƒYkíI6—kZ)ʪ»—(Iá0Ry9±¶6êÚëöí”ÕÖ>NVffîÃâ4|êò!ެÂâürª-NN$¥9\4Ó¸3:³Ò¬³Wœ½"múýˆ‘¾H„ôÀÛ>ô!wï^Ö­~è‚¥.-qïèQ~ô£Ü?qÂŽ`Ë¥·¾-“!39I¸²’xs3õ;w’Þº•š©êèx´P¿—¾ çÂ×>‡ë{n_mάêÓmN»k0a' [¼T*"\ÿåÍœ{ÿnFw´!¡ãC³>¶Xé¶XÙ‡W°¦’ÿ;Ór¼±"*Õ}îPFCäð©~M%DQ1V}k™-W±@ÿmÙeÈ–p™Y›4ºh]´²m.‘1KÿóR(dG¬Äp˜†]»èûßaý/þ⃿'ÁÌE˜½ —?Sºhä¹0Íâ•&™DqDaÚî7†lVÓBñx—Æ‹õÏûßkX{y‘¦&bííÔmßN²§‡ª‰&“¯¬qáE¿WÃ+ÿ¸|Ë?KI~½a •¡æ]T=Ϭ/l”Wˆ¤‘Фӄkk©Ù´ÉÚCíè ¦«Ër¼*ñx¨5,ea»‡qíß`êÚ5|eeT¯_Om_õVâÜ9åå¤6m"ÞÒB¬¡á‘v®8} þ勘Gž‡¥YÏ@éá²»Ð>#/L^L‰nä]š¯üÞcŒí]ý_èBÄ ‚YW¨$]wÙV~Sů«–W¸|F^Ð|ªFÀ”ñk–H ÅÂϨ:ACFT ëk A¶˜Zh%ªžYOZ˜+¡8KVä`(VD¥jÖ ª‘³<sxÜpX(ÞÓ#"ÞÒBåúõÔmßNëÓOSÓÕõ`ÅJ™ƒc„ñ“0u¹4ØÉ;b¢ØQS6ÿy³ØìÔÁA뺅žß.(]pÞ´¯¬¥…î÷¿Ÿµ¿ø‹D’IÂÕÕwþmôüËŸÀ¥0q·pó¹Tdé,Ó.ssêßh£T$eøýD¨íè vëVËL¦¥Åâ„ý³5Â2T•™[·>q‚¹;w¬ý»ÎNk´ Æ4 kˆ.\=4lÉ⚉¹¸ˆ°´¿ñ^̱[˜3ã&ˆö˜´‚ÍnÇ‚º95+]Ë –fN‘g#ÿqwÿäĮ„ˆa†‘7†Ð=‘•Y:ºr]uE˧Ø5 I±Üq,r@·lj$ÅrÊ!‡…VÎËj/õ¬¢S—Ñí»«*Û0¦e„š-ú'òÜUu,°[ÛÏþ,[?øAª7nÌ»n?ˆ÷ÞÐ 3¯ý)ÜøÌ .‡;©ùZŒé1‘0=&ΊCX5ìÃAB«º=ç@]Í7fÖ»‹Å‚€ „BÄÛÛÙú»¿Ëº_ø…‡†bÁ4aú>ìûxéï­7ojØvK¡ˆ£CÁ€²cô«jyãÞ•0”¯[ÅZw2)kn&µu+émÛH ¸†"R0ø¦"ÉU©a9+oµ‡º´Äü½{ÄΞAÿÚ¿üöWÐCÖ²¬ z¢*ݪ%¿ý>Û¢dhSIÓ=ƒšÞsà‰z²»ê˜ûø®¡tÛÿÏf] ¥@°†â WÐ ÅÊþ:I×ð)y–»M9¼,IÑm“ Ѿ% ÞÂJÖc0a‹—cßeÚæ†uh²ÝõÑòæÅ&ÐÅnÍ^ÓO‚AB55D’IZž~šM¿ñT®]û€ ÅGaä$¼ð{%)t¦m±†g® T<¯Ýï×ì¡]—rÁ“V‹£ Ç¥:’Nok³.Øþ~Ò[¶<\œkgàöëðgïÁž|PW˜¥°çþ\f½áy†})XÈ2ò®(⫬$P]MyK õ{öêí¥²£ƒXsó\sþÉ#Žª*37o2|ô(¾“')¿päÉ㘢Ž!‚*Z%ªÏZòŽ8YÑ.®Û»yºY¸òâ=ÌŸkÀøân¨ ¡#`)š Z(cÇáFÒõ‚T/€â –›êù¿w<¨Êa¸ 9kGGMû¶ï¦8ܱé±ír.P]΋•c¥î8àrÞJ]Õó¨¥:?Þ‹Ôðû‰65‘X·Î ý·o'ÞØh-Ó>È óÉAØÿi¸ù-˜¼¹ `fjÖ…ˆ!z­¹ Ëù}Ø«OšM¹ßÀ2^^¡¡ Ù"•èè°ç·o'ÙÝmM›§RGóÌ‚ù)«³wã¦iÚh6ÚÝaͧyš—æAÑÊ—YºQœêR)ÊÛÚˆ··S·{7Õ]]”ÕÕQ^W‡ø»÷?Þ‚e»E›ºÎÌÜyñEî½ü2 —/³kb‚ÈÂeºŽê³h”¦a‰”n‹‘c0QÀh÷˜M¨%î¨fe€Êw#Ö…kƒˆ†‰) ˜9‹w…‚%@¶Á©3®à7íNŸW¬L%YéªM©F>Z’Í—¯±©›âxö ¯0eó©Ž#RšÝÝTì´GS=Hs9"YÁæFÙáYs³5Q¿guÛ¶QV_ï.O?Ї®Â_þŸpÿ0Ü¿J±£§¡å ĦKÆX^\wÄJWó ⊹¼h¾’©†b§>º(b–eü–-ÔïØAíÖ­ãq‚ååG¤LÃ0rYôïü+¾ç>oEUºŒaŸÃÞT´×ÀL-/H^S ‡Mb–îOh¢ˆæó¨©¡²³“Ê®.êwí¢º»›Pe囼#X®UWfb‚™›7|é%†_y…¥³g)SÚ€z»Ûàí vÁ,­rjUšYx-9•+I„6„iýz7Á¶&‚i •!‹Y«øåÓ5ÅÌÎ »ÓgæËyê&§¦ìIëä"aÊåë/dó…bç¢4lTÍ6;ÕTë¹nM¨ö<™W¤ržšœs“Öý~Äx_"aÝUwî¤ÖÞ¦R¯Ãeèpæ%«»u蹂 DÓ“¢ëÎÜ-XB®P° ;òzÊ%º[¥"H§xH$TWSc“V“›6QÛ×g-*¯B¦9u’é}ߦþï?…¤å0EÐíóÕù]öXiÊö9mÛäëOE"Uàú$¯¾²’P:M²¯Úþ~j6m"±n:zïÖô™¸C߆×_þ3kÌÄ*Ý"‰ªvD·/NA.TCͧ@ÅsB+92x(úý„R)bíí3Ë&o&Ö¬ù‘ßÔHY6Ëäw¾Cì'ré,†4)_ºswW=ã7Ó‚ÇW±„ ;ωDˆ65mn¦ª§‡úÝ»-j{áQì(¾­K]ZbüÂî8À½#G˜¹ze|a~ž˜iR‰E¡tp$Åk/~¤x} ¸në%ˆá0©Þ^j·n¥~çN„Þ¿Æ¿î.’hÕªtYBÍøQ—üèK’®cäD7­uʪœUû£¤éб2IÔSõtž{kSÞ¼!{È£J¾ ¯*ãSÏØ…ÓéRJ¤>‘ÆF6PÙÙIÃÞ½TÙÞ`<¾:xà™)øÝ_†Éë01TÀ÷uo"6ÿËt†v=f¨º§F£°²ë²ÂM*\[Kª¿ßr¤Þµ‹Š¶6‹4P^¾jÍ$Ó0¸âƒ/¾HëÑ#„®\¢lxC„\ÀBA›ö(©æÍ|‹M5JÕ  > ‰IlÜHõ¦MÔïÙcÕc1‹¶úˆÍŽßv‚¥årÜ?y’óÿø ?ÎÜŠ‚Ï4‰˜&1,¸[€üY1~d%v»n§:B8L.—CULIÂãÇ© qçNÒ[¶P»µ¤+dŒÏ°¤$àWe)@n>„‘Ñ–|˜9ÁšRp»€>]s×h|†† ¥×@¼ö[Å~EÞNTå|t„Êíriy òJS碥¼œDg'É­[-Dð–-T´·ã‹DVÍ¡[Ëf1î ßGüÀ¯bLßCÔ@°£)«’í½MÝ^‡²‹ëÎE[ÜrWX.Ì^†»‰ Åb„’I ë²e ©¾>*×­C°×ŒV£«.ÏÏ“gòâEÆ_z‰É^ {p¸a ™¦?oeÉ6ƒ-r_époÐ’Ñ(RùÁ‚‚zÁn›EÉÊh©?…•÷ú4Àôù¨Ú¸‘–w½‹ÞßüMª7lX1Mcþî]FNždpÿ~ÂçÏS7»xn·æµ7H}4@E„h!!±~½…²±ÇB‰R `5 Vá¢5T•ÌÔC‡sïȆdîÆ $YƯªT˜&åv¶Pìô¤³²_¦ê½1KD"‘UÝÝ–ëOo/µýýîØjºPÿH¿/ÃàúõëüÎïüΣ,Ó0XbîÞ=ÆÎžeè•W˜8wŽ™[·À(“ëM÷¼ÑT±…‘‹ÇE©ÑÚZ6дw/Õ6PÕÑA¸ºúÍý Sß„k?_¨Œ¶9{lA-ã$CGÐ D]w[ëÎ"í+õs+ÞÆÙÔfþ~Ûoàò >IÒ ˆ ‚ßDôøE•€¨àÔ’¬« Ïgíó'&ç ~ýêʋƢH ²’ü¿¦ IDAT²¦&*Ö­£~ûvjûú¨±£Ê‡ýÈNM1rò$w^z‰Ñ“'™8wav–˜ÝÁMc™} +4GTÇbÞ,=^RÜÉÕÁå·ÇÚÚh~ê)ª»º¨îè Z[ûÈšDwääç>Çýû5 Ÿ§œá”6ŠË+;yM5‰„[Ö¨Û±ƒêÎNk‘º¶ö-¹iòF›7oràÀ2™ üàß–.ËÜÜ·3Ï<ÃÌÍ›,ܽ‹‘Í.ã¶{­º ´Çš÷sD‚êÎNR›7Ó¸g‰µk)K§‰$“oÞ dîÜü,L”ñB;wÖòT+Ú5›Bª™Ö€¦U„ëøø{>ΫM U6Z¸AÅ/Ú‚%êø$ ¿¨"ú $ŸNP-Ñ”’‚åÍ¢×ÿéŸ8óÅ/2~æ ¢ªâ·£(§´áe×S$T¥,éœ×[ÕÙIUw7émÛ,¯ÌúzË…ú{¾ÙÇK/½Ä³Ï> À­[·8tèУO MC—e2\ÿú×9ñéO³04„`Üîbê¨#H‚("Ö¨(˜‚€ L$Höôи{·;(/Çÿðw—…;ðÝ ß·¶èÖî,STS5­9 Ý*‚ˆŸ™P%ÿß{ÿ+'Öí`"ž²V†5{å–OÐ$+ 2¢ÏÀ'iî׋&ê ƒÈDÈ ªhðöœ ¼ØK㮟#Ù¹ _$ò£ý.ÞäCžŸgöæMî:ÄçŸgôøq„L†ÝÅõFÂ÷©Ñ¬dnضlRYU4ìÞMýöíÔtu²­«VÛýÇÙ¬ü~×¾JÍd8ýÌ3œüÌgÈŒŒX‹ïòQÈ«/eYf¦$!©þ~ÒÛ¶QÛßOݶm– s8üH\¨˜ÇÔԪͲÿ£?ú#Ž?ÎÜÜî×Äb1"ž ‰üã«ðÓu‡‡Y¸Ÿ±3g¸÷Ê+Ü?~œ¹ÁA°Am¥Êû1TYI8•"ÑÞNrófr33Œ¿þ:±æfZžx‚TO•ë×?˜.Çü]yŽü,ÝÍGU+ J`Ÿ®ÛÙöj2|îûþü×>FЉjž8`ã(ntå5$Q·jU‚‚_²D,(ÈÅÅ—,G¨\ÁÒ¬zHÌ7OµðÇøô‚Ôà[»*7¤¹ÁA¾÷á3¸?êÜÜ2›.QÚã¼ÏÅnÛËFNì‹6œLN&©Ú¸‘æ½{©éé±j‘«0aîfŠ‚ ˆ~?ºª’cqlŒ™7}>Òýý”§Ó,sýùç9ñéO3?8ªêÞ˜½7h³èwáDWHÁD‚pm-U7Ò¸s§;Q¿šæ¤¦(<ÿüó|ä#áÚµk˾f``€ÆÆF~ë·~‹w¿ûÝîß}ô£}ø‚•çæw¿Ë¥/}‰™›7™ݱ¶ÅHdŠDÊ_VfM¯]KÓc‘ìíµxYÑ( ##`¹¡<È7.; ÿü«p{_þLÒXnêç*›¶¨yßÀOs¢oÏýûÿÝZ¹1d"ZÆJ±é¡±ò –@ùE{Ú®[9¦!r„Ìa!ëŠW±`9–²:¢lP&.ÒrŸ±QØŸz¨)þð‰œøÔ§¸õ­o®X¨;ÃÊÞ¡d’p] ãã,ŒYÕÑAug'-O=å²ÓÞt-òGLëfoÝbâõ×15²º:rÓÓÜ?y’ñóç™$7?OíæÍ4=þ8Í{÷"…BL]½Êݸ{è3W¯¢g2@(‘ÀPÔ¥%Ä`²TŠÅñqÔ\Ž`"AÕ† ${z¨ß±ƒªŽ*Z[x+ºGø8yò$Ï=÷¹\Žgžy¦ä×üùŸÿ9Á`ŸþéŸfýúõ+~¯‡/›†áz‘ú¸øì³Ìß»·L˜½A‘B!ëÖQ·mÍv7'œHXðWÏ2]]ÍlU%UÆ”+@1c­Þ`§zv*è4¢b öâ³–G͸ffŽ )ò|öˆh™L”K Ö÷׋!›u1kÀ"ÙC9×Zì«­Ÿ‚ävðý`,tljXËåÈMO[Ž$1wçº,“X»–±3g|ùe2ã㘂P`têt±Ä¢´Çu%E¤h”ä¦M¤6o¦vÛ6”\ŽÑÓ§‰ÔÖÒüøã$ÚÚ¬‰ëòò7îp6»š¡K©ç¢|þeM'½›¾qƒÛûö1øòËÌ^½Š27‡$Iøôl–ìì¬Už°_ËàÄ ƒƒdÆÆhܳ‡t_‘êj"ÕÕ =Jfb‚†;%Œž>m,{{­¡è3g¨Z·ŽÆÝ»­Ô6‘ PVöhŒmÈ(J×u¾üå/óÙÏ~ÖMÿîܹã~ßï'pðàA÷s½½½H?@¹âFX¦a0÷.w_y…»r÷àAfoÝr-¸¤`Ðzó’IååL߸A°¼œD{; ;wÒ¸{7©M›¬5€Õz\x^û ìÿ|a~â­ðªùˆJ³wí°™¡Ât¢Š;ííü÷?ù™jL¹N7AÃ^fF%ldñcGRvê'™–Ù„O·P3~ÝÂÉc’ƒfÞ`"$ä !CTX"hÊ”K ”ù è ¢l É:BÖÄ\,Áʘ–PÍc1Ú@;üü_ZJÒùøƒh¹™ÉI”ùyee¢ÈâÈS—/3|ìcgÎP¹~=þp˜‰K—P––¨ ù©§¨Û¶…‘FOâÎ /0zú4K÷ï[<4°Xíªê²ü±áš*;:hzì1lët'Õ1Taå‹ué¨Óˬ¦¸òßàÞ …3n^Ò —_¿t¾~ù ö²“3ÜÞÿ=½Âôõë˜v½Å©ñŠðJö\‘tÚòÜ»—æ'žÀ£,,P¹v-¾pøÿoï½Ã¤*Ïÿÿ×9gÚîlïXzg¥¢4Ä4$b%€ŠF&±!I4&ö’¨È7ô±— E¥I/KgÙ¾³;sêïçœ3g AâÜ×5מsvf`g^{ß÷s?ï7õ;w"É2iíÛ‹ÕrÛ¯àXË –,YBmm-7ÝtË–-kuM¯^½hgÁŽ=šéÓ§“~ŸñïXuåå|ý⋬~þyªÖ­#£S'Bii4ìÙƒ®ªduíJÁÀ´9’p~>uÛ·£G£dvíJfçÎ?LºûÞ¿à¡ËA·ÿBšBèLj‘U9 rTËÞöbBc(ÌÓý=Ÿ]dT°l%Ÿ¤2£"£"®ß®è¶â¨îQ5<2Éö÷¬üFÜ`"Éj"YnÄoh„åaY8âÈ19fkd9ÒÇÎÔU¨õ|ÿÓëAN¡i-»Vmdi]˜µµÔ¯^MíΚæš\–åö”‚¹¹ J—qã(2„Pf&;>ù„Ìö?F­«#«{wBìÿúk”@€¬îÝi?jùýû“ѹ³Ð0?˜ýƒº[cßlˆlm.óëÝÅÜ–Ó£´ê{Ü‚LÈtb*¨ºö ²:?~ c·´•$’òòèzÚi ˜<™‚~xùïïªÕÓØÈŸÿügžzê)vîÜÙêšsÏ=—¾}ûpúé§SVV&>rï½Ç¢E‹())áÒK/ýိ©a÷²eT¬ZERv6ù¥¥4ìÝKýÎäôìé.§Âá¸[‡Ý•#æç öéq}wŸn—ºpÄ IQ×'‰&Í ,EH’š„’iÌRÈÑÙ„“QØ’ÈV$XuÂTÂŒ@¬Ê QÓ$jš¨4Wm© ¥JJ ùeet8ñDÚMV·nT®_OÍ–-äôèAJa!µÛ¶¡«ªèÅde‘”•up¥Ž^ [ÏjøÔúxöÛB‘¡ œk©–’©¶Úªæ‘߉™B¯>f4—¸wª¥ŸwÓ¼)Id÷îM¡íøälí:ÖÆ ZÆÎ;¹è¢‹Ð4… ¶yÝo¼A(¢oß¾äååµyÍÒ¥KYµj¦irÙe—ý0ÀrzŽ­äô¨,ëOsXŒ¦êj”ʽ„n¾iã*04LI¨Œšž½ þF,Í‚FD%ˆ*âéìüù|öÛñ,»ög(~Óí?µVÀ=+YZë²&n>ÍΪl`9FNI¨èF\Y×ÅãØ?$&L't•%qB¦èk9jÆ­¼Úò´?š‡˜g^1=îìÕèIȼvU#\©I"½sgJ/½”²©SIÊÉiõ»·l7ïoœ°Žn½j^…Ý÷Š÷“®Æë¯¶ÌîÚ2Áû&`9=¶x¡ê¨Œš¶²ªÕ¶t[òÀNÈÈ Ó©§2ôÚk)4Hl >F¶½´ŒuëÖQWWÇ /¼ÀC=„eY¨ªêžÏÌ̤k×®ø|>æÏŸïÞ;3°7ÏJª½‰Ö²%¢ŒJq-%Ý„Š³ú°á‘ñ˜¡fpòÂÊg‰Þ”*)×qwÌ'ùu­°œ,«È42Y3ñ©â~9fºŽ8RÔTm¤h‹Ô B+ïAMƒ&S|UuဣÙrÈ^÷uoØR·=¥CrJKÉëߟΧœBþÀ‡®î°î6¨^µöÊ‘w7AK{–¶$'ZËŒ5—†6¢q5 #Ÿ—3TnÇ¡ù@NÅ-A%''“ѽ;9¶ú(ëׯç…^8"¯õ Xz4Ê–íQj¶lå‹G¡ê½÷ÓØD Ye‹.IèÄ ËÔ KB·$t$TIBC£W’„jŸKi_ƒq\&UÏü 9Ej*V>KG6L¬¨ä~€IP‘T«”œLÊ›a9òâ«¢âf›N8’ÉrÌt (d§Ži‘X^`5 _AS€Šx«$«µ§`KÓCQÄžÌ1c\ãËÔPüþC³êjØ `Å WÛ³"´éêÒ¬_å–å•<öêiÍ5ÁHiH9s´¬Z–¼f IIø22ÈêÓ‡"{Â<¯ÿøæécdì ººšŠŠ ÊËËùå/é–fû÷ïw³ànG£÷ߟ@ @zzz›¥^CCõõõ̘1ƒo¼‘víÚ5›NOËŽmÛjyÿý-ˆ)13\»u¿ÿÓfTÍ;®èóûpðÜð|)’ŸŸÜü!ù=öº”32k5v¡ ,Å0°T ½Ñ‡Õ$!Å,¬¨„Oî²jº¾®U—a9f~Sk–U9^Šf Û’ÉNÆ&td¬¸á§GäÏPm­,#Ž+ê×$>´ÎY¬uõÔ¦ù© ’WVÆÈ3(=úðW»ö,†ùçCãöæ3omiÃx^˜kÇåØR©q³ ÇìÔÔì ÊñÖ3D¿Îq‡Ñ´æ®0Ñ6ž’äd‚„òóÉîÛ—â‘#ÉìÖ¬îÝÅ à1Ö—z뭷ؽ{7ï¼óÏ?ÿ|«ó;vd̘1øý~üñoýøk×®åÞ{ï¥OŸ>\sÍ5ø¾'€SÀZ´h;O?½ض­ž>(GLÅxÁ¤R>üž¯ÞŸi ¬ X~ûºødHbó[PÜRòñ³O}&rÀ¤w§5œ9ìUŒFÑ—lwXœœ17“r²-ÛLÕ±ðòi¶ÀŸYªÕÌ`ÂŒyz1Ž€Ÿ}ì¸à˜Ž•z“¸ÏéY9ÙD#ßl|šTX(T(ËÊèòÓŸÒnøðÃË&¢U0ÿØû©°÷º·ÔómÃ4“ÖXºçœ¡Ç 64C”½ªÕÜ-¦å*ŸÚµ+i]ºÝ¯Å#G’ZRB8/O(ZcºãŽ;ضmo¿ý6»wïnv~Ô¨QîXÁþýû0`cÇŽ=¬ç|çwøì³Ï¸í¶Û~œÀ², SUÙ¼±’Q'¿ÄÞ½õvFå“ä‹ÃGV@RÄ}²_|•|ö}~ϱ-¢,ÙÀ“Zî÷ƒ%@Öò””×Bñ[rF#Ù¹•Ã1:ùj$[²€=ÍúVn¯Ê¶ùŠÃJÃg/AІ°·æ²3 3êùޫݳ—äcHÅâ꣆½¦ÚÜ–¥†6ý~¬@€¤ÂBŠGŒvUƑީþäd|¡Ð¡¯öjMðÖ°ñM¨ÛÒ\õâû3-| -)Ý ,ÏWçæÈB«Ž[·uà~”™œLVi)Ù}û’3`…Ç“VR‚/úáFn¾m+Dש¬¬tÁsÖYgP^^NÌÞg«•Ü}÷Ýœp ¤¥¥‘ŸŸï–v÷ß?~ø!/¾ø"™‡aªñÁpûí·sýõ×óóŸÿüšëǰԺ:jË˩ڰ=K–ð⃇—QoIàQP>±½B–Å÷²Xα¤ˆk$ç>{w›ìͼ|.•$ÉçfY’Ï?È3^),¬€„ð²B’YXañ•0<˜ ݬ ôQWÇeŠ+Ÿ.„ý$Mhf¹Y„L.¬ÔæÖéVÌþàzmÔí,CÓã•jÚ†VÜÒÊýÀÊ2JZÁœÂ:ÐnÔ(òú÷'¯2;wþî~™_¾ kހϞå_KyLïN{WnïÏt³%{—óou!åì>°-Ê4óÀ†§-5³|iiôþå/xÅdvïŽrËñGK¬_¿ž•+W²cÇ®½öÚVçEaüøñî÷sçÎýÆRMÓ4þøÇ?rûí·öë»ÿþû¹ä’KÈú·ÑUÀr\p*V­b÷’%ì[¾œÚ ø¸¶?/3 UR  ÙÉ•–ìó€Ê¾ß˜"Ç3/Ù›“mÉJóc+’IR€ ²Ï„È>É/@¥ø ¬ –ä·¬ü"Û2’°$ 3,Ó?øÃüŸRÈnn*¿Ù´íMT+Þ[²ÍšeThZ<«r™½%¦Ç3‹˜*ZCJ•$”Œ R;v$³O ;ŽÜ~ýH/)!¥¨è»n|ÿŸð¯éâK´m×¢Ù&vù¦Ûv]ºîɰ<½)§©îö¤ÌÖ6]±¬l€?#ƒ¬=(1‚S¦Ó³ç1ª‡~˜Í›7³téÒ6‡7 ÀE]„ßïgúôéÿS«ÿ?°, Ë41T•=Ë—³ëÓO)_°€Š+Pkj0êê˜&ËÅ\~E#aáB¿dK¶Ô"»òÞ¯Èq5»Öîqù$°D?K’»ð##‹ +>EwåSt¬ €•ì3Ýc`&ÉfA =Ù‡™$c„‚á}äÕl1ûÕó)Ú¿¹IkærcyVºZ®z9àr2 M‹[vy›ÈÍ>¬’„&ËÈéédõéCÁqÇ ÌÒR’srZm*ÿÎbÝçðÐUP±+ZƒäôªZÀÊÔ=NÚFÜ[Ð´ä®øÙ Ò=þ‰êÍ7›“’$LYF¶7V Jɘ1äôîM(-`fæQ;ØéÔ¼ä’KØ´i“Ûய¯ÄFbY–9óÌ3¹ñÆÙ¿?³gÏfÖ¬Ycvhõ@ñƒ¬Åš†AÅŠ¬ž;—-ï¾KÅW_55óÉvû;&çÐh€lâzxù$ _ 09Ðr ¥x€¥x2/çç$¥9Ð[‘K–ű%!a¹–¢nyèSt‘uùMEd[Nf&É.¼Œd+(a„ô$«Â}ÑÒüô»~'n|ë^¾›Þ_-'TÛÐ R­–é5)ÝîèVþ­¤$äŒ 99t(+£hÄrúõšQ))ßëŒmöl‡k~>0eAÉ£kli"ÁtödªØ>zöÞLÓ[òâ߬YÍûð2;Õ+ ™IJ~>¹¥¥®f}ö1Pö544ðÙgŸPQQÁ\Ðæu'Ÿ|2 Dí†Þì\rr2§v“'Of„ ‰ ëp"Z]Íž/¾`郲íƒ0ÚÔmw„ÍÞõŸÃ\~ A rê!¬Ú@QÀç) ½ÀrAfKöyŸXvùè³ËCÅ>Æ$+HŠ„dùP$X~È*²ßøÍÍ®|Šî–‰²ÏÄL’ÜF²âBLOñAb©AÔ´¾€N’Üįü“K3ü?o HE=å¡=3ädmùª€ j׎¤öíÉ8¢aÃÈèÚ•´’’ï]³]mh zÓ&Ô•Ë)~ñ äUŸbú…Û(QðEíÞ”cÜ*ÛV]¶-—·_åö¤Ì¶3§X‹~”agR©%%dtëFN¿~w¹½{“ѩӱŽ?üðE¼ÿþûìÛ·G}´Õù@ ÀM7Ýä~ûí·cöôÄO°gÏN:é$N8á„°¾MìüäWr¦vãF¶oÇRÕV±^½¤=¾<žvZÌr Y‹—~>¹ù±Ó¿rîW<ÀòÉñlÊ/Åæ—â–_ÀK–e±xˆŸ$2(X>Ù'Ì!¤€…¢øeÍÍÀÅÀ ‰’Qö›IŠèw…$ô°%` ¦PÓøa0”bÔì¢÷ªå¤YµŒ?õ~ Õþzfëæ±;ÔRRBFäBáðádضéÁ´´ï]Ù2 v/[ÆO>Iï/>#{ÿ.Ò£Uh~б>bb3¹¤ @Ù¨²È®4=nÕ¥99V«©¢´–L6€p»v DÁàÁtüÉOÄû¬,‘IååÐSO=Åܹsغu+7nluÍI'ÄÍ7ߌÏçãÄOüVoóçÏgáÂ…œuÖY 0 ¬¶Ê=µ®NdRË—³ý£(_¸ÊÕ«m‹^Ù²\“ ç-å•Fvd¶{ó@ÁüªŠžnbå4@Ȱ# ÀÈr¼ôs3/^>/¼äxæåôÀdEÔŸ²_œ÷‹~–“|¿,´ÖeŸI@R]sˆ€$œm|ŠN@RÁ/².Ÿ,z[~Y J’ðKVH4àýІö£§ø„ü±¬T!ml+‰æG÷P2÷S YŒúe1ÝDõù°’“‘ÒÓIéÜ™‚!CÈ<˜ì>}HïÜ_0(únßó‡Ô²,Ôº:š*+Ùþî»lzøaJÖ­¡»dâ“@W )(h"«B¦ÇÙîU⊪eOšñ–·´kioHJRþôt’‹‹i?r¤pâ¶¥Š$E9ªGTUeÅŠ\|ñÅlÞ¼]×Ñuݽ¦[·n¤§§3~üx~ó›ßð«_ýŠ+¯¼’.]ºPõà`B×u®»î:.¼ðBŠŠŠ\ â=°L]gû¢E|ýŸÿ°ë³Ï¨Xµ 3u3'É“Eyu¬½_-@ ççó¼~¥^BÀjDÍ´°²#4D—Ë“"{ð°ì Ê'Ç哚˹ßÛÀ·3/'ù’PðK²b;ØÈ1q¬`)>ár@E XB‹]Ò „PTP !Î-¬D@Q1 f’,„ø$‘a9Àòa)BŠÔ@5„n[„«D¨±7ùC‡’_VFj‡bVèj+©õõToÚľ/¾ â³Ïhúüsä•+é§ëdd0ût»oežK•<:bØ ²Z ¹¶ìE逓ڡݺ‰-1’[ZJjQÑQ?#UQQÁœ9s±%æÎ;ïluÍyçGQQ 4Ì{÷îíž«©©áŽ;î ++‹iÓ¦‘››{X¯ç†n sÑEÑ¥K—7°Ô†¶ÎŸÏ§ù {–-Cojj'Z|õJä:°  ')1‚^·uEjåz𲬬FX`ùâÀò9–Ý,÷BÊo7ÏkýH9°s€å“Ä4»äCö[¢Ò”¤¸_ ,€¥(†›Uù½™ËM@Ù’°†¨A‹ åc@xšÉ2RP\UWŸ=HLó™B˜/hÅH—kɪ’[¢]öƒ„R:±7‡R¹v-ÛæÏg÷§ŸR·~=æ¦MdÖד‹°èòÙ¿PS²Eë,ápfx ¤J6 $ÏŠ VRJ 1UòºvÓ<»woòú÷§pÈ &µ¸˜pnî11+5oÞ<ž{î9jkkyï½÷Z‡Ã<ûì³€PßÌù]ú/¿ü’§žzЇzè°_Û† ‡Ã.$TÀÒ£Q¶}ø![ÞŸŸ|Âþ5kPëê°L³œ$YÓÒÉÉäöéCJ»vTiØs IDAT­_O´¶–vÇS8t(í?žôŽQ‚AöÔ*t9V4B0XCCfVV“ý ñyJ;oVå–â“S>:prî÷ɶ;‚}_¿…¬XâÇ¿@Y'(Û:ì²–_]Ab"Ch¯+~ƒ@StBD‘ý&>ŸNHŠŠ2QƨA9b(ªæS RäÒ|u„‰#KdP†$ß ¾bŸã÷ÔDßøúë|ù°Å hhÀ¯ª¤™&™ÃSÇTZØz-¹¼24: + $%!¥¤Ù«ùC‡¢ª*;>ÿ%)‰¢ãŽ£hÐ ŠGŒ ’rÔo,Þ¶mªªòØcñÜsωDhhh ==¼¼™ /¼[n¹…nݺ1|øðÿê “ˆïX »wóÕ³ÏR¾`¡ôt$ zãF’²³Éêѵ¡š­[ÉíÝ›¢¡C…EQÇŽ$åätßaì •VDH“wãKŽP••™ð±œ&¹o¦»™”$àå–Sú9™U@Š_çû€dïèã ŠlÆ3)ÛÌÔéSyýƒÄJ1·i’„»×­9 ©$IÂ’ËYL²°›.¿ak[iB ٌȄÌ(IVrÔð’„¡DÐXáqÐû7Õë ±ÚZ”`_(„ÞÔDdß>ÂyyÄjkùâ±ÇXùÌ3D¶oÇÙ¨ä@Ê?‘Z,Žx½½ðRÒÒÈèÖì~ý(6ŒÛ•89/ï˜ÓŒ*//w{Põõõmê?ÝtÓMnoèÔSOuM@ÌW=ÿüólÞ¼™+¯¼’âââ}ްö|ù%õÛ·“ݳ'¡ôtjËËñƒ„óóA–iÚ¿Ÿ@J Áôtá¾û-—×y×âwÏYÄb²›‘’cìË,ÀL×Dw×ô‹@F>;ÃrŽÛ‚”ßɦ¤ø±Ÿxfåìôƒì7PÓõô[š £€å”÷ tîóZɉ A'‹’mA©)nŠ*E]`ù4)j Mö˜‰Ñ ÐU|ªl54bqãG]jµaèq.œrÀJz–»bÄbDkjØûå—”ôPPZJmy9û×­#)+‹Œ’Ê?úˆmóç£ÖÔà³Wr½ÅÞ?5-mÔ-Y¿9)‰Ìž=i 䗕Q0hI99ø’“ãnÈGy444ÐÔÔÀ¬Y³xê©§ˆF£®ò@("55•´´4Þxã :tè@Ò7,„ìÝ»—_ÿú×ðÇ?þñ{ÕŽJëÅÞ0¸ã5Zµä6a„MvguÀLÓÄÇÇh,§¼óÙ¥žÏ)ÏMò[qñ†€>Pd1² +¦U‰~•OÖ]Pù-a&BØkež{lßïfYfTd`¦ÈªB’]²$<x…ea‘âk ,E„î•j ‰F0"Š{lE$‚ºí3Øè–#ºîÀ« 0 áw`Å`Ŧ-lYô1»>ÿœÆ;‘, 9ÄÔuqóÀ‡+¹Î‚I0FD„UWR( ±H dfÊÍ%£K:|2¹ýû“WZJòa®hýñî»ïÒÐÐÀ¬Y³\‡botéÒ…h4Jii)?ýéO¹æškù¹–-[Æ›o¾É•W^Iö÷<Øû¿Ge7SY(©&K#ÐQÃrªŒ™ÓF žUù½ÙU<‹³ ’Ïj#Y2Q0P  1ø)›â¼l 3 Ÿ¬»¦AK+`y egY°‚–Gp30S˜úMñóIR~Ss3ª #(Ç\SUE1P$!Ôç•:¶š$«F "Â\ÂÕgØ€r€å¹™‘ÝH—žY#t²Ò-ð{öÞE£ÑV®7†Z`ùý¤vìH~¿~èÔnÝJj»vdtêDíöí4UV’Ù½;íF"·OÒKJŽIO½™3gºûòžyæ™6å§L™B=8p ‘H„>úè°G  DSS÷ÝwÅÅÅÿs›”4Ö²½&^бoFˆ:²ƒ[‰¦øÙ‘Õ-EÙ•áo,±-PÌHɲ€“"îH‚÷&+¦ûU–MÉ>VâÀR0|¬>K?$Ñ$$b,M¬ÂÁ&` ¿@b¦Èº?Á 1|†îÚÊû dI”‡~Sx &!,º|ºŽâxKyl¨wXV“°è’"Í¡e5‚Ñ(,»ô(D,¨wnUÇ@&Bó¦$‘Ò¾=íFŒ ÃèÑ Š?9™Š+Hi׎ôˆÕÕQ¿s'é:˶ôtQêa†a°víZ~õ«_°|ùr4Û$ÄÛZœ™¨=z43ý\¾|9‹/¦°°ñãÇÖ㯿þš+VP]]Í´iÓD:Ö€õá.ñoDH¯¬…€Nzh©IìÈìL,9ºYWË’OÒE†"ÛDz±8°rŽ%q“}¦°Þr eé.¼|Äå·„s³ß†¦!+Ꜻ>¶¼,Gó*DÜ;0` Û®$šÄŠ¡fˆRÑ×$ˢܳ…þä&³•S±Ù[uÔ¶å²lÝvÙ.ͨðTÕx«ËIļ._-ü”ÔT:žz*C®»Ž¢¡CòoŠ 6°}ûvfÏžíÎ?y£°°^½z‘žžÎ¼yóú±ï¿ÿ~~ñ‹_PRR’ ɵ$” ŠFj¤žX²_È@N%!Á> ‘üh¢¼³lHaÄ-C”Z¦!î—<7 dD&%›&Šià³t$Ó e÷°,!cìdO~KÎ͆î‚Ìñ ô›bUÏülëXVM1öàÌZºîšxÍ®^»nµ6úlŠKÓ(¤etMÈ‘š¡ÞV;°íZz¨zùçUyÐ@V=Î;¡×^Kf·nÇ\Y×V<üðÃTUUñöÛo³xñâ6¯9÷ÜséÕ«l&tw°qýõ×'r¤uÊ)§0a„oå¾ú}…fÁ;#$%7‘ªGNIŸl"§ÊÈ©2~Âz„Tê…ñ@>KoþUÐR°Á%Å!å =þøc[]ó§?ýɵLå•W¸öÚkK8GXåååL:•ÆÆFÆŒÓl/Ó ËBDˆÕÖR½o«¥B2ÂÒÂuX©JЉœ&á›$7ÕfÖ‘Bƒ˜@w²*t7“òY"³r2-Å´Ï[> td˦p\6EI¨`¸?ë8Ø,Õ5p 䔀®¼®¹÷;ôK¾š(!%Õ# ºîÂ˱éRLaÛ%EmGœ)‘ÕdëCÙvUšaƒÊ6uÜŠcVÜW°¥ .ËœŒœ–Ffq1C‡R4|8EC†^RrÌÉïÚµ‹={ö°fͦL™öb‚Óáðûý.˜þùÏÒÓV ®ÓðèÑ£9çœsèÞ½;¿ÿýï¿q‹L"ނ֦M›¬x€×^{h4Êœ9s8餓¾ÿl*¡f˪֯gûÂ…T®\É‚>=ycúoÉß³—öû¶S™™¦±?­€#‡pS„ÔºzÂшPC㔓=9ý,z¼§…Ýß²30§WåBÎÔEóáhã“⦦NÖäd[.˜Œ¸Á©OלLÍõ "«rŒO%U „*š³D¦eû útÝ5@•¢­å@*¦Ûr36œ­¶}½ý©@~>¡¢"RJJ(:”¼²22»t!­C‡ïGiô{Œ ðÕW_ðæ›oòÿ÷ÍÎgff2iÒ$ÒÒÒøÃþpPûÙgŸñî»ï’ŸŸï6ãq”7Ý-ZÄ©§žJaa!Ï<ó £FúΟLF©Z¿žŸ}&ö®\IãŽHûö‘oYüuÑ›ìïØ…ŽÛ·’_µ—Êœ,bi2ûÃÄ*“HÕëI«¯#9Ö(´©lÈ8ý,6l$QÒ9 w^¦X–X†îö·|†îö¿ü† )]À(``¹ÒâN8Šf¸>‚>Uw3)%f¸V_>MGŠY®k³ódUMVÜÂ+Ú\uTÕmç³9œZ–{-{Sáöíé{É%tÿÅ/ee‘”›{ÌM˜LŸ>}ûö±|ùò65£@(œ|òÉüô§?=¤çXºt)k×®eÏž=Üpà 2íM÷‘#G²yóf^zé%&NœHvv6ÿ÷ÿçÚV6ÕØÈê9sX=w.•kÖ`ÖÕ¡Äb„ ƒåãÐ>°›Æp!9þý¤%×Ñ”ÂLK"Ùˆ’‘®Ô’jÖ“l5º=,·o…îfMŽ ³bz€e÷ª|–îöªÜk O?Ënª+¦Xޝ ß°3)͆íÆìÜç84˪wgŽYHöW!}l53ž0¢q×#7•0ô¸ãMËlªåJŸ˜Ÿ’ÂaÒ;u¢ÿe—ÑwâDBÇȦÙh4ÊÎ;8í´Ó¨««`ß¾}†@»ví\âxÀ-ûî»ï> ¨¨¨8¤©ÁƒSVVÆk¯½Æ#<¸qãèܹs‚G+°‚Á III´oߞŋ3~üx¦M›Æ™gžyHÉXM µ[·²þ•Wøê‰'ˆíÞM!Ëž†Ðm÷#Bi'9,áäõ©©¨I~RªPtƒ ©†4«N e:Àò‚ÊÒãp²ôx™h—~SC±Ä ¨ßôôÀ =Þ¿²å80;Í>C¡ÚF§Šæ±·!…íò,!LךËRí¼XkûtÆ”cú©Çâö\š0xnæ­ç…”.~q„‹‹ “_VFñðáä÷ïOF§NÇDojùòå¬X±‚7r×]wµ:ŸœœÌ¹çž sжÆþú׿rõÕW“’’Âå—_N×®]¿õëe™ŸÿüçÌ;—?üáL˜0SO=5A‰£­$|ë­·˜7oÉÉÉôë×Ï=¹dÉþñ0qâDWˆì˾¦&öý5{–.¥üƒ¨Ý°ú êë›íúw6Ñb«âül}àt"Váª~Cc{q{j”tŒr¾JÌP5©uõ„Ìh¼‡eÙÙ”‡”›aI-20'ÃÂ,»ôsôŽo b0ù8°¼öñ>MGrí[Q,Õjæè82»Ž/çM÷Xtâ:Rš”Ó¯já/ê®ðetïNvïÞä—•ÑîøãIkßžÔââ#*ìw¨ñÜsÏ1þ|·ûòË/›/,,t7'''3qâăzÜuëÖ!IÝ»w?¬×gš&o½õ§vZ‚G°FŽi7޳Ï>›`0H§NÜ“uuuÜpà ¼üòËdgg3eʦOŸŽ¿Åd³eYÄjjX9{6_ª¯¿Æ¬¯Çª¯ÇgY‰›Á{'|œÿ&Pû·1Ħô§©"‰$Cl<Ý^Оº†4Ì­2ÁÚÉ5¤FêI2…â"ÅWÝÌÊ–é˜}ÞgØ ³ËC·L´-âÈ[ÆÛ–(Å0UC82«`9%×Ù¦ ÃSMm,×ìÔ°PmóOgÁ½Yq©`ÝqeIëÜ™‚Áƒ)6Œ£G“”•…?>ª{S•••îêݹçžËž={Ø»wo³m0éééøý~ÆïfJ‰’,lºÿ·hjjâä“OfñâÅÜu×]Ü|óÍîv„Xm-UëÖ±rölV<ý4VS“»Ã?@|—¿WyÔ”#Mb)÷÷Ça*Sð¥éè~ÛSÚÓ¸7k«D¨)Jf¸š”¦1q®Ä{X.”œ2вË?ÉsÞŠ[Ä»À2ÅW¿ngUºbJÖLd݈÷™bmØoÅ<~žLÊð@JÓâNÅš×FÝþêšÍ¥‚uE®Ìùù¤vîL»#((+#ÀR ú7Vee¥kòyá…‰DZ]sÒI'¹[^îºë.úôéÃK/½ÄŽ;èÝ»·ke•ˆD´ÙÃ:P$%%1gÎæÍ›Ç£>JUUƒºv¥4=m|ÀþU«D3݆•'J-%‘½À2%‰@ViÉA’ªDUȃh(D¨:Š1°š$’µF2ŒRhS➦»›A¡7”åɨ,=^îÙ}+'»’5I³4SdNÞ~SÌc!oƒÉ˜ï?y!ådNŽÙ©ã`¬Ù=*×øÔl.¬¾ÌL2zö$³G ‡ s]™ÃyyÈGùž½¯¿þš§žz €;wºŽ0ÞÈÈÈàÖ[oࢋ.jÕ ?묳xùå—Yºt)ÕÕÕœsÎ9‰Oi"¾]†å5kÖ0pà@2’“yüÞ{Ùtãh55nåµëòM8€²$ K’ð§¤Ó·/…C†ÐnÔHäþŸQÝô )èý|Ô[©lÝÚQl~Û)R™iÕ¤XYÀ2ã[q|¦úô€ÊÍ® ¿!2+T K}'gœÀRm 9ÇÞOó”z6¤\`y²*gÛŒ)'“ÒíÙ)o©§Iº$A8LþàÁä @á°aB0-`ZÚQ )Çñå¾ûîã•W^¡ººšuëÖ5kb˲LçÎÝ=|Á`~ãc755ñä“OòŸÿü‡çž{î˜vzIÄ,'æÎËÕW_¾?W‘kšÑ(”bµµ`³²ð…B4îßìóÌÎ&·o_JÆŒ¡hÈrz÷ÆSWó.{¶NG©7Ðt?C’ÙS_ÀÖõ ê1Øi:²Ò«òIJŸ—2ãÙ–ßÒÜæºb(voJÒM±1Ø!ÇÞðÜoxûRšZªX½3=™”Ór²*g ÁIP­ævUŽá©/#N…C‡RtÜqäH^ÿþÇÄŠÞÂ… ݃óÎ;ŠŠŠfç;wîL‡1*síµ×¶ÞÓÔ©S¹æškèÓ§Oâ›Ö¡«5Ì™3‡_ýêWôéÓ‡ž†Á¥çœCjr2•k×’œ—G^i)uååÔïÞMÁÀduïNf—.„22š)OFö¾Mõò_Ò£"* ÝÂ|êÍŽíYQä “ô¤Z²3+ K²-v=ý–/ÿLI7ua|gªq05Èô–vQOoÊ --^N™è±wnºj÷¢ŒÖ–ê1À H*,$µkWrJK):”ì=ÈèÒ…`ZÚQÿ&)//göìÙn¯)‹µ •ÜÜ\N9åwèxáÂ…ÌŸ?Ÿüü|¦NzÈÏ___Ï}÷݇ßïgòäÉ$>¹ `Z|ðÁ¼úê«<ðÀœyúéüûé§1T•PFJ @Su5²¢üW»ôè¶7ˆÌ¿˜d³‘@4FeÇ,Ö¥öb_yž¿«ÑHO©%+³Š°OlË Èª»ò§è–.”,U¬Þ9#–ÓŠÆ{R–J*\íkVîy›évf嘶̤œr/©]; † !¯¬Œâã'½¤„Pv6””£^áÓO?eæÌ™€ðÔ[²dI«kòóóÝRïøã'%%¥Õ5_|ñ_ý5UUU\}õÕ‡üzöìÙÃW_}Åþóþñ$>¹ `^/cÆŒ¼þúëlÞ¼™_ÿú×Üzë­ß¨oíþüÚWÐ^¼ŸŬ·¨ëšÉÖÜ®ÔìÉ Ù×H°1FFj YÙU$Q$ÅÔEöµ¥W´8ˆ)ÓQ8pzOÑ6îóÎMyÀd¶èI:¨ZÜWÏ;À©Ê2„ÃH))bEoÔ(rKKÉ8ŒÎ‘ù¸2N¬Zµ MÓ¸÷Þ{yõÕW1 ƒh4Ú NEEEtíÚ•gžyF¼y$é 4ÉMÓD×uWïp":·%â(–µµµL˜0·ß~››o¾™»ï¾ûÆ2M¢=‹ïÿ›L“fB ¨½RÙU܉HU˜”@!=JfF5é™5È’_±SãbvÍJ?O&լ̋5ïUZë•@XÎø·ÌóîÕSe_f¦ØXÜ©íO8œ¾}ÉìÚ•ôNŽ M©ÇÜUÛ¼í¶Û¨­­mvþøã§¬¬Œ;wÒ³gσú}&"Ç °¶oßÎâÅ‹¹å–[(++ã¼óÎã¿øE›×ÖmßΚ^€Ï_¦Ol‘ÈU ôO¦¢côˆp0BXŽžQƒTã{ïÔo–ê)ý´™—g¡YïJ%^ÌŒCÊ›IÅ)-Œ=È0€"{ì \XHò1âJ¼zõjw‚|Þ¼yîJŸ7þú׿Ү];JKKéÙ³'<öØc¬^½šY³ft月DõÀò‚ëÄOD×uî¿ÿ~†ÞÌ»±¢‚­|ÀÎwߤߪai&M TA _€h¯B 5TO8Á ÅP%‘æ8ÀÒHyšæVËÏV3`Ù㪠(Õ“EÅÝïÇ…PÒÒÈìÝ›âã'Ð ò=º`𨖮¨¨ ¾¾ž… róÍ7 ª*û÷ïĈãWXXèzíåååákñ絛¯§¾¾žÛn»[n¹…¼¼¼6{V‰HÄ1 ,'æÍ›ÇUW]E8fîܹ <Ø=×TYÉÞæ£_.z#Äš ¡(íOQo‹ôÀ¡h4ú-4d[}SóŽ´Whµ èmšë ñ=z-³(= —G 7—ì¾})5Ь=ÈêÞð1°:µ`Á×?ïé§ŸfÁ‚­®)--eÀ€”””¸ÙÖÁFyy9·Ýv}ûö媫®Jøê%â X¯¿þ:ãǧOŸ> 6Œûî»ÔÔT6^w%O>Fµ Ýw3R‡Ò "iÞ]ø×¾‰ÒˆÉMŠ€Ò(à¤iñ1ƒ6¥ÆA¥veÆÁäͤ4Ÿ¤âbÒºt!«_?Ú<™Ýº.( 9/ï˜èG]uÕUèºÎ»ï¾Ë–-[Z?÷Üs9餓xàø×¿þÕìÇ¡Ä|À‚ ¸ãŽ;Ÿ¢D±8"õÌé§ŸÎÊ•+™;w.úӟؼy3³{ŒêeËØ¹d9#—®F· ¥sg{HÿWj½F$f¡YÐ$ ºø”tÏÐf«ÁOML–Û" ÍT85IBSô@€`a!…’?d…C‡’Ù­Á´4|IIGm©§ª* €P9¸îºë±-ÆùÛ“™™éîõœ3g:t ??Ÿ¬¬, ¸îºë˜9s&cÆŒ9d‹ª1cÆœœÌ¨Q£¸âŠ+8ÿüó]éáD$â˜@AAƒ ¢¬¬Œh4J»nݸæškøã;ï‡[]¯5ÔÔY4úÀÒldÇs/ßTlx9½”W…3H©©øsrH*.¦ãàÁ Nv¯^dvëvL¨p._¾œíÛ·óÉ'Ÿðç?ÿ¹ÕùŒŒ N8áž}öY222Ú|œ³Î:‹³Î:˱:œ ÆÃ† cáÂ…<öØcìØ±#aw•ˆÿ`E£QÖ­[ÇÙgŸÍĉ¹îºëxðÁQ…ûï¿¿ÕõMPW1;³Ò,ð5Ï=CkEiFë¡Mç{+5•p§Nd””?dÅÇ“R\Ljq1c`Â|öìÙ¬Zµ €·ÞzË=öÆØ±c;v,®žùÁÄÌ™3ù÷¿ÿý¼Î+®¸"ñIJÄÿN«­Ø·o›6mrwì_}õÕL˜0Á-Q´ køjÜ@Ô˜Šd÷¥”F‘m©Vs‰`ǺJ•$Œ@€ôž=É)-%ÿ¸ã(6ŒpQÁ´4ümdrGKX–…i ³ø“N: ]×Y·nUUUî5NÉuõÕW3~üx~ûÛßò /СC‡ÃrND"À:ȨªªbÔ¨Q¬Y³†'žx‚aÆQZZ À{yI QЄ9¨Ž¸Åhn¾ JJ ]N;>¿ü%C†œŸÔˆ+**X³f Ÿþ97Þxc«kFŒá &Ι3ÇCX¶l¿ùÍo¸øâ‹¹øâ‹Å4}"‘Ö÷«W¯æßÿþ7O?ý4ÉÉÉ®kÏ—WNeÃcObà1ZP”Œ ê*+ãÆ ’DvÏžôš0ÞçœCΑöVü–ñꫯ²råJV­ZÕ¦fTQQ—^z)7ÝtS›=>o<óÌ3ìÚµ‹¡C‡2vìØÄ»: `‰X°`'žx"]»v¥k×®üó¶ÛxíøãÑ3"·rû÷'ÖÐ@ù¢EÔîÜ)¤N$‰œÞ½|å•ô:ï<’BCÌ;O?ý€•+Wºî0Þ˜4i'N$==áÇ«ÇçwX¶l£FbäÈ‘‰wv"À:ÑÐÐÀÓO?Í­·ÞJ÷®]ùÛW ìÙCÑqÇ‘7`–e±wùr¶~ð;>ù„ŠU«egÓoÒ$ºþìgòƒ—‚uuuî,Ô 'œ€išD£ÑfÛ`zõêE àÚk¯å½ÅÓå DIDAT÷ÞcÚ´i”””–P¦i̘1ƒŸýìg”””¸ºT‰HDXßs<üðÃ|ôÑGìß¿Ÿ_üâ\zé¥îTµÖØÈþ5kØñÉ'l_´ˆª è|ê©ô>ÿ|ò øA€µaÃÞyç·Ä}ì±ÇZ]3yòd×SoæÌ™®5ºªª\ýõäææ2yòäf}ªC‰›o¾Y–™8q"½òò8‰øŸˆ†üu×]ÇìÙ³™6mZ3˜šFý®]TmÜH &­}{ÂÈGxxñá‡æã?fÛ¶m,^¼¸ÕùîÝ»»ÓàgŸ}ö•XY¹r%O>ù$ÿûß{sË–-X–•pžIDXGºD¬©©áÌ3Ϥ¢¢‚ßýîwL:¿ßeYX†qĦҷnÝ Àoû[NUUU466º×˜2e “&M"——wÐÏQQQANNNbL!‰8åÄÞ½{9묳X¼x1ùË_:t(£Gþ^ŸSUUWÁ8à`æYgå®ä=šÉ“''ÞY‰HÄX \}?üðCn¿ýv’““yòÉ'ùÉO~ò?Ï’%Kxúé§QUÕU×lûÛß\]¨‰'º›¹ŸþyæÏŸÏÏþsÆ—x‡%"?V`9±téRN9åÒÒÒÈÈÈ`áÂ….0¥ätT7ï¸ãÞ{ï=jkkÙ±c~¿ßÕ}*--å‘G gÏžmö™LÓä믿æ•W^á„N ÿþ‡üÚ~ŒñÅ_PVVö­~®²²’7Þxƒ‹.º¨Íó{öìaõêÕ >ü°%q*++yõÕWÙ²e 3fÌh¥–ˆï1¬c8žzê)+##ÃêׯŸµvíÚƒþ9Ó4­W_}ÕzõÕW­Aƒy=^›ÝFmÝqLJüú~ÿûß[“'O¶Ö¬YcýØ£¦¦Æš:uªÕÐÐ`Åb1ë¹çž³Î9ç몫®²¾úê+Ë4M«¶¶Öš9s¦õÙgŸYMMMÖ½÷Þk;Ö:ýôÓ­ .¸Àzå•W,MÓÚ|üh4jmܸñ€Ï_WWg]ýõÖÊ•+xM4µþþ÷¿[?ùÉO¬ÓO?Ýš0a‚5oÞ}ºõé§ŸZ†a|/ÿ_{÷îµ~ýë_[ãÇ·þò—¿´úw×ÖÖZÓ§O·ªªªú1—.]j]}õÕÖgœa]~ùåÖ‚ ,]×-UU­_|Ñ:ÿüó­)S¦XK–,±LÓ<*ßGÇôŸ†Ë.» ¿ßÏ¢E‹¸ì²Ë9r$øÃÚ\‰klltWë,ËâÞ{ïmó1oºé&Wé ‹qÛm·òë»çž{عs'ÿüç?9÷ÜsÔ#º®³~ýz Ã`áÂ…|øá‡<øàƒ,[¶Œ§žzŠÛn»Í›7£i:uÂ4MvîÜÉ 7ÜÀرcY¾|93fÌ`øðá„B!¾úê+öïßOFFýû÷Ççó±sçNÚµkÇ'Ÿ|BNN[·n¥GtíÚ•ÔÔTÌk¯½Fß¾}Û|¦i²k×.®¹æN?ýtV¬XÁŒ3:t¨;jRSSÃo¼ACC ìØ±ƒòòr à ))‰Aƒ±qãFÖ­[G8¦ÿþdgg³yóföíÛG$! Ò©S'Ö¯_$I :´Õn†{¾}ûrçw2cÆ ^xá&Nœèžßºu+Ÿ|ò ¯¼ò ={ö¤´´”5kÖ°cDz³³4hP«L2%%…Ë/¿œÞ½{³dÉþú׿ҭ[76mÚÄ[o½Å=÷ÜÃÖ­[™5kG¥yí1ŸËNš4‰3Ï<“o¼‘{ï½—={ö0kÖ,÷üÛo¿Í]wÝ…®ë­¬ªœ•¸wÞyÇýå4È•Z¼x1£FbêÔ©\xá…‡ôúŠ‹‹™ûl3`©ªŠ®ëÔÖÖ‰Dx÷Ýwyýõ×4hï½÷[¶liU÷èÑÃ=ÎËË#`7n¤K—.´k׎””æÍ›GEEEXßcYˤI“˜4i§œrŠkúÙ2²³³Ý,gÀ€<øàƒÿõq‡ÎÂ… yâ‰'X¹r%ýúõ;dh=ñÄlݺ•ûÍMÎ?&`ÕÕÕ‘——‡¢($''£iªªR]]M(Âï÷£ë:–e1sæL~øa*++9ãŒ3HMM¥¾¾I’S¦L!’’’Bff&•••ßø^ºûî»ùÇ?þAUUãÆ#33³Ù{hĈTWW3~üxæÌ™Cß¾}™4iÁ`G}”®]»2mÚ4vìØÁwÜÁ¾}û°,‹rÑEa6làâ‹/&--%K–4VCCªªºÏ›››ëêð;ѹsg Ý­\Ó¦McâĉŒ3†/¾ø‚;ï¼ó€ý¼}ûö1{ölFŒAff&uuu¤¦¦â÷ûÝ? m™å&€õEUUo½õ×]wK—.åÝwßuÏ7ŽЫW¯o¥åÄá¸{£cÇŽ?jXÈIKK£®®Ã0hllÄï÷ÈÌÌdÇŽî"ˆ$IÌœ9“±cÇòå—_r÷Ýw‰D8ãŒ3…Bü¿ÿ÷ÿˆF£\rÉ%Í "Ë2ùùùD"LÓtAVSSCö1ôužó–[nqUrï¾ûnª««è$IYYY„Ãa4M£¡¡¢¢"ü~?iiiX–…®ëH’Dff&Á`ÔÔTÒÓÓ …B$''·‚CJJ @€êêj²³³ÝÙ¼…¦iD" e™œœ"‘H›×îÚµ‹¿ýíoîû¤¤$ÒÒÒØ»w/š¦FÝÌ2¬ï):wîÌÿøÇfõ½#Ûðá‡2mÚ´ÄÞº£X={öäå—_¦¢¢‚/¾ø‚””222(..æ‹/¾ ¶¶¶UODz,¢Ñ(†aÐÔÔĉ'žÈÏ~ö3n¾ùfV­ZŨQ£¾±Ô^³f»úX[[ËŸÿüçfï›¶²­h4ÊÁ.¤û|>:wîÌÂ… ݘ¢(î*ñÁ¶’’’(++ãå—_æ¼óÎ㥗^j¥ e™ºº:²³³éÙ³'¯½ö]ºtaþüùtëÖ­ÕãnÙ²…{²²2.¼ðBwõ»k×®|òÉ'ìØ±ƒmÛ¶aš&¹¹¹ `©èر#;vt¿3f —]v™™™Ìœ9ó¨ýeü/‡eY®^ט1c¨ªªbúôéäçç3uêT²³³ñûý¼ýöÛlÙ²…ÒÒRŠ‹‹¹ï¾ûx衇HKKcÊ”)dddðá‡2kÖ,ø O>ù$©©©\rÉ%­v*äææºHVV–Û—$‰3Î8ƒH$ÂÔ©SÉÊÊbêÔ©’››ëf/YYYîŒ Úµk×êÿË1"~ýõ×1bçw^³óáp˜K/½”o¼‘!C†pùå—3kÖ,&L˜@§NøÝï~×ê1?ýôSV­ZÅöíÛyã7ðù|<ñÄwÜqìÛ·ßÿþ÷ddd0yòä6_ÓÑÇäÖ¡ÆŠ+xùå—ÉÍÍMÈúáXµj·Ür sæÌù¯~†‡:‡õMÑrkíÚµÄb1ú÷ïŸøåCñ£À—_~Éš5kØ´iÓa,$âàãÃ?ä/ù ãÆãŠ+®H Z&"¬oï¼ó+V¬àÜsÏ¥}ûö yáD$âˆí§ô”SN¡[·nÜrË-¼þúë‰wB"‘ȰŽxùå—›ÍÁ$"‰H+‰HD"%a"‘ˆ°‘ˆD$"¬D$"‰8”øÿ ; VÛ¨IEND®B`‚snd-16.1/pix/fm.png0000644000076400007640000001323611147553267012263 0ustar bilbil‰PNG  IHDR‹ƒå&QSsBIT|dˆtEXtCREATORgnome-panel-screenshot—7w+IDATxœíÝy˜wÇñOU÷0WBgÁÁ(Ãh Îàb¢&B6$¸:ê³ëêúè®®ëñ8®ë®Og×u½ÆGct<†€â&!²I Gž¸ä‚‚Ã}ß×ôtí=ÝÓ]]ÕU]Ó3U=ý~=OÂLõ¯¾¿o7×ßU†$K€ƒ¸$m°v„"äs?ùº¶~ª-U,JÒ]f>ˆ L±˜Lt…™@dý0±°$q>_Yñ²eŠE«+Y’NËÒ¸«&õ*ĦçÖÉš,xYzŠÅDî‹§žÝ-]’,«¸ý/–•TlL†Þ8Z2Œ€éDˆ™úåÌ©“n¿Ôy^–eõÔ[Q—¥gÚ6²8èÑc2ctîü…â:»xA§¯Þ­Ú!sPÜû€ˆ³º‹1Ë 8k¥þ—®·²ãÝ>gNQ¡Ö®Yã+ÞÚ5…÷£ä´³ÅË–5²˜»fqô¨‘š6©^—:2 C† ÉPêëîÃôuÃèyíÌéSZûçµJ^JÈ0YÊÅ#×·¸¾6wûÒ¼6ëNoÓw<œù~D|ˆî»æ3Š©ŸX¿?ñ‚Z?Þ«þ’ôûõú\DT<5ÓZìŒk¶ÔÈ]W¯ã¥ïñŠwûœ9zô‘GcÜ1wnáxY\×,N7Jš7K’!Ó4d˜†LÔa˜¶ï ™f÷¯†¡ÃGŽè…_<£®®$ë 2täøQí;t çÚÎú½&}w~ε¦ÚÉúöÊÒük$IóFÔg EI:¹~§Ž¾ú’F,˜V’þŠ7bJXáoÚsÊÃïç š’AGeI–•W‰—ºÇ=Þ#«Wiî¼ÔÏÐ;æÎÕ#«Wå´I¿&I¬^U0ž”³Úþbªø“rG Ãþ}öש¢Ñ²R؆ü7€h[³áq}óþï˨ëYFb^^£ë_•nL}ŸH$ǵ`b£îÛ´Q£êߤ;.«W"Ù¥¸ËÜwvÏqÅ·ÔIWêïÝï}>te“¦Ô]¥sŽtžÒÆS¯¨íÐz]HvJ’ÖNûçTœc[TeÆÔ4ìÍZ~äYýjÿ:UÇé¯F5é/†OÕ•UÃuºëœž9õš~~à K^ÔgÇÍÕœõê¸xDŸØþ£Lÿÿ2áÝ2l²^:»[_ÞõK 2âãxåaÄzŠh¿Ÿ €¨éÝÈ¢Õý_O½•oõª‡ï³›7ÿ©@ñæÍÿ€¤Tq˜ŽŸ¾–n“UÌ‹×Ã}7´“ÌžbÑ4 r( C2s¿7,Cbd([±ñCTõÖQ’ÙSäÄ««2_?þÜzÝöÎwkñ õÓo¬Ð­ó5,V«UÓüYïωe¹üKÕ«¿·_=Ußžô1Å S§ÎŸÑÎCûtý„IZ4òÝpñ }yÿ¯eUõ´ï°·¨3™ÐŸîÕ‘'_Õ‰ÛõƒO~] C¯SgWB;÷¼¡ £ÇkÞˆšxn¨¾°¯MÝ¢9#êuuõH [¶G'ï§Á±j½}èu’¤ßþä—:¸óYýté÷Õ0ôZ×8Fu¬`Ão½.ï=ûù\DGºF´’Á×,fÿ¹·Ç+&®•LzÆ“¤U¿_©ù RGêd‰é×rú´Ü.¹®Y”bê^©Ø½&±gäа‡¦a+»wÓX±ð§ç£ ë£ ç\{ßæ¯å|èè­Ý¼^ón¾Uó&½K ®x‡$éþ›W,*™t\ãÕßgn¸[qÃÔ‘ãG5÷SÔ©‹gõáwë«ýyÝ4þM^aiÛ;™{Ξ?§߬Ã'ŽÊZ£›ßu³†^'˲ôÁÏ\/ïz]7N¢ßü¹ÞrÕ š¼<©m·ìÒ'÷ëšácõ¾›õ£§Öê} )nÄtîÂy=öÌ“ªŸ3S C¯-ç•[º\ó0ÇÔ©ªã¨Î¿å¢jcÕ:sÏ@4õfÍ¢Öf¯,:‡ñÒ^¹BXxgÞ5Çþ¼Ö,Úw¿X–•»‘Å0d˜Ù…cÖ¯Ýmd¦ËËîxü«(;Nk;¾öÿ—Ûr®ýjýJÍ»ùV}ñcŸÖºÁÚòÚKÚ¶ãÕ¼xV2ÿ狟þ&¯JMë>½ù9î<¯ÚÛ&éækújw›7_ù&=ýä)U§jà ÿ«Ã'©úÖkdÖÄôÖú·IJýlzð¿îÏë÷Íc®Õ3O=ªÇFmÕß «;šnÓ÷þý7š5|ª$iíÓOè|â‚nš2ÍWÝ윇Q“%éॺ¦vtê½ÆMÏÏ@4Ý ®—òë­dί~sðŠçu¿ßü¤ç,f‚öâÐtQ4¥Ôèdzd‘„@¹q[CxlëîLa&I/wl×Ö}¯jú¸ÔBÆûøÌ+jóºœÛåÕŸ•´2熙£êdÔÆ5ü†19÷v<“ùúÄéS2G–YW¥a×QõÈa’¤®dRÛ¶¿’×ï‰S'•8pFkw?¯OL¼]ãGÕ¬qoSýe©)ã‡þgµâã†JÝë ½â¸åaÄSSÔ.¤ŠÅ½‡Ȩ«J­ïf]7Pv,YL*“ÿç>¯˜¸–,Ïxi ï\”wÿ‚;ïÒÊË}å'X³hX=Uff¢l#‰RN±˜š¦î™óf=Pžb㇨ê¦Q™uË’«Ê?7µ}×Sš>îFuØ«'ŸÛ øÛGçµ±’>×,Úú{ùè.Õž¬¦ïÔ°5?SrHÞ;jzæõ?9nÆ SUC«e˜†^;½'Û4õÝûþ[›ö¤ÚÇb1Ýsmá‹2לò³¥ÞÛ6Gm¤+¦Ö,šö¢0k}bÎש{,ËJÅ‹qÎ"P® ¯U͕à ¶Y¿÷EÍþÑ'tê‰RmL±1ƒóÚXVÒ׳çíýÝ¿ïI½õÊë4òò+´ößîסΓºöòñ’¤­¯üIO=ÿ´â3ò‹S†’‰.m9òºþ¸w›Þ1~ª~±ô‡zãè^ušI]=l´jãÕZüó/éôÅý’)=vd«fަ‘—_!IZùøj™ƒ«dލÕKçwû‹ã’GÚ/f|Aš!ýúÅGõ ¿’b¦¯Ï@T¤j˲tç¢{ŠºsÅòe©IÙõVO¼ì_ý°,Ë3^vŽ+–/Ë\_±|Yæµ…wÝ­Ë—eîÎ×ÃudñÐÁCzùåm™³óFMC¦¡žM/Ýÿ?~\Οgd(wIïgÆ[IK—&Ô*yûUª¾hÉp}ôǩ݋Gwèã+¾¡¿™ø~MŸ2M“†Õ¾Ã´vÃúÁo~&ë²A2Æ )ç+ÛîÓâ­ÓuGý»uõ¨1êìJhמÝÚ¸éyíZ»UU·OP¼¶ZÏþ?¼pFÃk†(i%µò‰Ge^=LfULæ ¸¯8~ßw×îS2öŸ•9y4?#2d:uO÷4¯}aÀièBñþrQϦÁ‡–·çÅ~hy{¦Í‹îÑCËÛ]ãIÖ,þñ²ýzþÿ™Z7ä ³žÑþ,K;HÃ,‡u"kÖÚÏëð÷Ÿ•$Åßt™ãZC§6±XLCÆ_!+™Úç'Žßþ¶×ÓgŸùž?<¬®c¤D—ŒÚ*Å®¢êF(V/'!é§gŸÒ¾ók%öœ–u>!™†Ì!ƒdŽ«SüÜEUu&tIÒík¿¢÷o•.uI2T󶉊®‘•HúŠÓ¸êtôÇ/¸¾{ž—ŽÕ ËóGbD”‘;rWŒô=9k•mñ² ¼RÄ“¤øk¾>ð;Ýu÷ÝãeqÝ =xÚX×BÑ“aÈ2|Ž&ˆŒÚL•N^’”5tÚW¨Mj½²å+ŽŸþ ª›4R—FQòl§”Hv/}‘âuÕŠ¯U²+Y0NÍZ™ïš Ä™‹Rg—ÔÕýC±*¦xM•$CÉ®¤Ìª˜êO‘uêRæÀ²XmU&–Ÿ8^ïÇïç zÒCd–,-à·EÝkÉê`dþÜ÷G<¯ÑÊœv¶xÙ œ³Ø –¥ÀOÚÚÚZ©¶gG³ÓÏ…RµñÛÎT][#ÕÖäèJÊò§*WÕeSäê>À¶ûçU½Û™c^q¼òðû¹ˆ®êj‡S|JÜåþ¹z<©Ð\bÚüüºÞ†è©·¢/ûº$kƒµC_Zöí^u€ãÒñ³Úú©6Fà.oÍâ¹ÕÛµmÙÓ¡%€pL½§Iuó®Ï¹–)çR;ô*µPÜ´iSØ)„ª¡¡AÓß31çZ¦XŒ™fÎ AÎ*W†ahÆŒa§šÖÖVI=5aW÷ãJ³ŠÅ˜Ãm¨$éš0¿XŒQ,TºLM˜è”T`•Ç^2²€ {MèkÍâæÍ›‹ê„Í"åÉ^úÞàâ·lmm-I±hFæëJÚ™ &×b1‹ÖšÅt˜]4 oÙkBŽÎ@†û4t?mp1 C–eå™jvuÌŽ“îË©ä+°Á¥ÿ¦¡KUÄ9µ§Îýèœ~œ†¦˜ˆ¦Ð§¡K‰Í/¥èœÅ(r›n¦€®ÀÈb¸kK·7¯T:{MØsÎb?¯YôÚ ýzúëì6n1ì‡yú¹ì5¡ïièÖÖÖ’&â5²ègäÑ©ý›iü 4 =cÆŒ²|Þ3ÇèÇuºÜ6¸øQªÃ¿*EèGçôw±Fqà߀9:¥ç>²Øû@4¹?î¯ Ÿà€Òr†¶Ÿ©Ãy„•ÇýœÅ¬mÒl A%Ù²eCØ)º††%UØÑ9€_mmía§@¨š›K*¸Á…b•­©ifØ)8jlœJ¿7® ¥_@ÿklœ­ŽŽ’"pÎ"€â¥ÿ£­­]--KßÕâз œ³X^Gç¤7àDi}eö¦ (åå‡Ó†&û{ðÓÆÞ®7ŸƒŸ8¥jRÌÑ9QûKßþêrz.µ[®Ù×ý´ñó}Мœâ”ª èÁ\Ðgœ ±ôó¹‹)ÐüÄ)UËuÍb¼ÀÈb)¦(í‰mãõZ)óéÞ¾/¿m ?~§êýŒúiÊŸ½&Œ»´Ëð;ýèÕ&]ÔØÛÛ&û5·ƒÃýäì·¯RðÓWЩà¾8<ÝÏg@¡@eð,Ý-üÜןEHoûÊ.Ö¼Fòúâ}e¢¥èBd \,Úáê«â±/óqj¤€êQÂbP(»’‹^kæÂPŽM˜9S('Wô*Ã%«…>gÃ0|ý>”ªPtš/tŸ[~~┪ (ÌsdÑmMœ×_Ê…ÖÒõ–×:A?9GMØŸ³Ÿu~ÚØóéÍÚV¯8¥jÜùš†º®Ð錻¾ê«¯Úøäxš¾jSlÛ¨öÅßç°´µµºoéÒ{Kœ  Ò”lƒ Pîg‡‚«––%a§¨P‹€¤ææÅêèØvDÅâ0¦YÃT_?+ì]kk«ãõÀ»¡0ð1²’-[6„@FCÃŽ×)Ct‡+@©57/v¼N±²¦¦™a§ ÂÚ¿qãºPú-³]7zR,@DÙ‘ßÖÖ®––%ï嬼 ˜b±·Oé(ô{KÑÞ«˜-U_ˆŠÕÖÖè¾¥Kï-q&Ðc@<Á¥œ56Î;ÑÒ²$ì Åbˆš›«£cGØi¸ê·b‘iÙ\õõ³ÂN¡h[¶l;ÐÏYDQ‚®©ÑÖܼØñ:Å"ŠÖÔ43ìPAÂZ×»qãºPú€046Îv]G± ò‚¬ímkkWKË’À÷ò"H)ªX쯳Óý”º(Ž]Šœüü¾”ª ¨,¾‹E{QÓ—…W¥*¥xd¢Ÿß—Rµ•'ÐãþÐ{¥QôzÂL©Ú€ÊxÍ¢}*ûzo¦‘½¦BÓ…×cýgÑoñ—½N’‚T’ŠÙ túÜi c¡¶}1Mï×){A[ª6 2•|d±”LÝUí¶[Úm×¶½]vÿnGÊôæ}:fNýûáô¾úª ¨<¾‹E¯ÅÞ¤Ÿbúr+ˆú¢/¿ñŠmç·½Ÿx¥j„¡­­=Ð}K—Þ[âL òTôšEÓØ8;ìPaZZ–„T,ŠE¥¹y±::v„è'³ÁÅcd¾]7¢¯¹y±ãuŠÅ2·e˵µµ«©ifŸ÷Õ}„µrãÆu¡ô @46Îv]fF±ˆÈ ²&²­­]--KßÛ…0å¨O×,Fá9Ò¥ö3±ÊçÊOŸ‹åò?…˜eY¡½ E&vCGX¹Ü`àòµfÑë±xNíí¯»=j¯Øb(;v¡ÇÓùy”Ÿ[n…òvË©P_Nm½Þ7…"ˆÏbÑ­h)öº¤œ"Ïék?Ü M{¯ÜüöïT˜ºÅôsÝ/ EwC‡]Ì„ÝPåš7¨L%=:'Ì©S?ÓÐ(NÉŠÅ(­±+45 ÿï†.·ÂËo¾}ý¾Â>³ ž#‹ÙJì×Ó‚lRéKN9z~wC;m¬ñóùaégW6@©ùš†ö*Nü/^;¤‹´¿ 9ôæ½õ¦m%„mmíî[ºôÞgx6ôÑØ8;ìJ¦¥eIØ)€n‹@sóbutì; 0Q,–¹úúYa§€ÖÖVÇë<®‹ÅÍ›7÷wˆ FàŠb®(àÊu7´ÛŽT޼bqú·îQCCC¹ DÓ¿uOÞµ¼bño?üéÃé—„m¬Y€«¸$}î'_9 D‘!É ; DÓÿ?Œ¡bU—ùIEND®B`‚snd-16.1/pix/asyfm.png0000644000076400007640000020171611147553266013001 0ustar bilbil‰PNG  IHDRôE@ZbKGDÿÿÿ ½§“ pHYs  šœtIME×  {ÚöW IDATxÚì½y¸G}.üVU÷lg_´ï–-Yò†ñ‚w[ÆÜ°Ä˜-á¹pIB†H—'_ aqȽ1× !,f‡–ä³d[`l¼Ë²eË’Ðv¤££åìËLwU}ÔÒÕ==sŽËZê}žÑôT¯ÓsÔoýªÞßû#RJ “ÔßOèžÐ=<<<<<<<¡{xxxxxxxB÷ððððð8-ýÎ;ïL}þö·¿üã©¶o}ë[¸í¶ÛRmwß}7>ñ‰O¤Ú¾ùÍoⓟüä´ôõ¯ŸúÔ§Žú‹}æ3ŸÁûßÿ~<úè£þWöðððð8= }ll ŸøÄ'p×]w¤”øÁ~€Z­†n¸Ÿþô§166†ïÿûˆã×_=>ó™Ï`ll ßûÞ÷ „Àu×]‡Ï~ö³Ãw¿û]À5×\ƒÛo¿uçBàÛßþ6‚ ÀW\Ï}îs˜œœ<â/öýïwÞy'^xáÿ+{xxxxœž„¾k×.\wÝu˜;w.€sŽý×Å»Þõ.\~ùåÃëׯÇ7¾ñ ¼óïÄW\J)Ö¯_»ï¾ïxÇ;på•WBJ‰õë×ã;ßùÞþö·ãª«®BǹQóøø8~ô£á–[nÁ5×\ƒÉÉI<þøãþòðððð𘂼ÆU«VðÇ1„ ×{¿ÓžÐO|þóŸÇ}÷Ý×pý–-[ü¯ëááááá ýDÇ­·ÞŠ[o½µáúK/½<òˆÿ…=<<<ðàÎ;ïÄìÙ³ñÖ·¾_ýêW1oÞù$>ô¡¡T*áõ¯=:;;±aÃ|ðƒD©TÂM7Ý„öövlܸøÀP,>ø ž|òI<ñÄ „àæ›oF¥RÁsÏ=‡?ýÓ?µÛyxxxxxx4y©«­mذçŸþ1?®r¿ûî»qË-·ø_ÚÃÃÃÃãô‹Ð'^ 2÷ðððððð„îááááááá ÝÃÃÃÃÃÃú‡‡‡‡‡‡‡'tOèžÐ=<<<<<<<¡{xxxxxxxB÷ððððð8œ*_dݺuøìg?k?oÞ¼ÙÿºžÐO6¬Y³kÖ¬±Ÿ}µ5Ó ~ÈÝÃÃÃÃÃÃGèÇq,0<\E‹i·mk+¢Rñtæï€‡‡‡‡Ç‰GNEOOÙ߈Àr÷ðððððð„îááááááá ÝÃÃÃÃÃÃã˜ÀÏ¡{xxxxÌœ+±ÚÄD„þþqp.Q«q:4‰‰‰BH½%ÉÝŸ€üuÕ*ÇøxBÆŽ>Þ$(Êå NY‡J%@[[—\2•Jè ÝÃÃÃÃãÔD ô÷kòKo¦6BkήŒQ„!¥ä˜\³”œËi·£”`öì J¥““=¡{xxxxÌ¥R€Õ«{ý8áçÐ=<<<<<<¡{xxxxxxœðCî§ ¤¦¦bRbÃ5!¢H€s )³óÍÉ\v ìß?‰‰¨ÉÑŽÅÜ÷L!ÅݪkaŒ »»Œöö‚ ‰})%Š––ð˜ÍñŸö„þƒüO>ùdÃõ}}}þ´‡‡ÇiL褔B©Ó›¡V˜˜ˆ0<\ŦMpèÐTÁRJÀ¹ÀÆû100‘OÃD^¢d?Ò#‡Aìò0×ɺÏBHıtÖI +VtcÉ’Ì™SÁòå](•„!E¹ T <¡+\tÑEXºtiÃõ?úѰgÏÿ¿ÚÃÃ㴥䈬S9X±¢ Õ*oxܦTLˆNM;–Ñú‹Öí±£ê%s¾† ííÅiÕùžÐK—.mJè•JÅÿöððð8L0FÑÝí=ÔOÊNœ¿žÐ=<<<<<dÎ{ºMJåoOˆÒ2”Ë‚À\‹ÈÙèê*âÊ+á5¯9K—vÎà»yB÷ððð8!ÐÓSÆÍ7¯ÄÍ7¯ô7#ƒ(âxê©üæ7{0:ZË!s  ×þÄçªp ¥gÕW¼b>fÍ:ñÜH=¡{xxxx¼¨C†‹/ž‡‹/žço†'ôé±nÝ:|ö³ŸµŸ7oÞì]Oè'Ö¬Yƒ5kÖØÏ—^z)yäÿ {xxxxxB÷ððð8Ç££5LNƹë…Pµ³óŒÚTÉPbßÝvulÙÀá-/Å<ò‘ŸSJàu¯»C~ò”96ÕÛÑYôK8Ë®ðͲ Üxãœw^Ûž'år€B!?9Œ`Μ–œ¹u‰0dhk+ R _Ô¬žÐ=<<<4§°~ý.lܸ?‡Ìa•ÚÊK=ý`¦” ŠÅ@?´ ¢HX?thRû²5÷tŠq’êÔ“#™†Œ©ÆI5;FÉ1FA)IÕF¿æšÎ#èé‘`x¸Š_þ²:Cò–ÓºœæȪÜÝŽÆüù­¸úêE¸ð¹èèxñ¼Þ=¡{xxxhÌšUÁ߸o|ã±QªÇ±@‹ºˆ~¦Bî™(¾g. 'G¹ºóB)NHEúé Oè/ÖVç`{xø¿4¡{xxxxOp.±cÇ8Žn¾úxì÷RCáúúyrJ“ÑJÕ”cŒ‘”ÈÒD·`¦#ÜY ³'t#@ÿ8ÆÆjЉ‰/¼p{öŒéÚׇS×;ýàΧB´Õib½JÑ’"B”`nÿþ T«ñaèÈHŒ}lCζyËî;i²®Ùù§;®}NE ¯çã_Uw}¦£0Ý÷1Œ|Bl¼}dI´e+Õä՜ȧ[ÿR! ©C¬iò¯O3”º#˜ÞVy½'žïR­­!ZZÂÔ¶”*áe¥€¾ÞžÐ=<*$axxn~¦@O¶Mùô'ƒÎÎV®ìF²ãvoü»‡‡‡Ç)„R)À%—Ìó7â4„'tc÷n‰ññérøÅ"ÁÒ¥¾à‹'tSwÞ¹µš!ͬÛAã9êo^€sÏ-9‡®ø-{̬Îĉíi|\tÑ\¼úÕgàe/›r9ı¬@ë ÝÃÃã¸c|<ƒîÆúõ»¨y_Æ‚¥T©‚³¾èaHQ,Úª3Q|+9”O<±Ï>{µ@P,–rŒëWcžydKr&¹æDÑžlǘk—J`,bƒ@ ¾V®l±÷A©à‰%BH®ª=Q«+s•óêZÒ„oÚê•îIa‘ìqÝS´dúÎË‘tÒ¤£¥Ï—G†RJpn:‹Éo¨êÒËT‡r÷îìÚ5‚gžÙŸºßúãgÓÝÒdO)Agg%gMmûÔSؽ{¯xÅ<¬Y³Ë—w3‘Ÿ't㎖–¯zÕ2¼êUËŽù±o¾y¹¿Á3!Ú¶mCCS9£C¤Ÿ~s0F0kV fͪÓÈÛº‡‡‡‡GSì;ÂtuYŽ/ôµ´µ‹^D±>¥gžÙuJýžžÐ=<<@VÁ/ÓDï,/]J°|9Acµ{¶M⣃k¯m;òÎÉtw$£Ó—½õ„îááñ“öîݣؽ{££5‡$6m:ˆŸüd ªU%Z“Rbb"ÆþýÖ®•R Ƙ&G0§T愘ujYY¡R»½™©‡gòÀŒ"‰þþq80•á!2MDJZÓ}fJš3ôx—Ùˆ¶ÙuÊi SMë¯7o—–œÜ{}|´ÉšÈšŸöõ©W}Ç Oä&¥Äºu´¯‘o{} \º=F½ ^½"ÑÑbÑ¢v\rÉ\\qŬ^Ý‹… Û0wnËQ9ËyB÷ðð8öY LNƪbhH‘§Qd/\ØŽ÷¿ÿ"‡TêýÊKÚÒ~åHm£ÈȨº©U ›ö„hÔ^ÕªÀÎÃØ»w¼Î¾óÄ M"À£?§{ÿfNèù0¿9îj0ÙpäçHŽ%DbïšïŒ>“6™Ûé0CŠÎÎ"¤”ˆ"ŽÑÑ*ªÕJJÅï ÝÃÃã„€J½êÆÊ•Ý'ܵw^—ÿ4öFŽßù€s—øûþbá”!ôgŸ}?ùÉOìçþþ~ÿëzxxœ”èÛ|óÇPb03çì Ýì<4ÉÊe£ÄÔ”s²í<<ðLæ%Í"ÒœÞáÏ-`GÀðÉw!­ªw§ê]’ù:Ä9Z^¹Œà¦üßÌ)Eè===¸ôÒKíç––ÿëzxx¤À¹Dµú☜˜~ÿ÷µa Šh©Lˆ™È„|m»KÚjÝð8ðij†x5ƒQ³ã€FhšÐònfþ½!9Î~ž«‹YEP7‡/ 8€¿ø›‡“$Ó#pÔêÒQ´Kâ:Á¬.àé´KÚ`Y÷moÞþöW¢_.Ó—$¿ü´#ô9sæ`Μ9ös[[›zyx%¦¦”X-Ž¢HØ9J)%ªUŽj•#ŠŒ—¸MNrLNÆzŽz:!Y^Ûá*±g^³û‘GFðéOï`P,Ig°/ÉlGr—Íœ4!„Ç1Í»Úáè9ýä³^†¡ã“Õ¨ טóÑôu8‘0ä4‘´Û.I‚îž4‚œ&ºoÒ !²þMNµ¿Ä}›e“¨¾~tâ¾û€ÿñ?€D¬–½fWÈÛ××¾¶• mðóTôy¶´ê½Tbhm †…Cww ¶¡Pð¢8c€}ûÆ16¦TéŒQp.pðà$8—ˆ"ak>BŸšŠEa¨ìM7o>„uëv`íÚ˜œT*vJÕ«XdV®l\Â0°"*¥fg(a–8(%Ú&UÕ­–"µž!¨ÆQ+ÀËZ–2Fñ{¿×â(ç1—Y6DëŠô\{Vµìu»jz¥Î76®ÔZ¹šãškRŠüä<„$÷Þ»»v O“ v$Väìs,ÃÑ ñ5­¥2SÛ]9ƒkŸAçb›ùü®wíi@ÔÙ¶FžîÉò¬Ye´µœyfn¾yÞô¦Uèí-{B÷ðð8zôô”ÑÕUÒ¥HjéÒÎæ}’l[«-Åÿïçcr2r¼Ç]ÿq¤¢Ù¼6³û 7ŸóÔæøÉv¤á°hÚÛ¼ÑúÆÒl¸µÑµMõax¸Š‰‰|ô£‹/òO÷F˜OŽ•O 9F†iú æodºmK!°rαû{Õ™TÞÿ/ò¿°éJ©:Äårˆrùè(Ùº‡‡Gêx4(T„ÝÙYô7ÓÁ3ÛÿU†'ëø²R>Ÿàï~Tc4ŸµÀ4ëdÎþD6l'¨Í»‰Æ£Ó™å9mÀ¯ŸÁ¶ÎûªÅÀ®öcžÐ=<ùÏ®[›t†Všg* ÏïÌ&uÕ}ñ›Á!-ž#±\]W§9¤]·®ùËæÑ»lÕK–§Èœä+Õuû@ð±'Íg’³ÉÌK`÷¶Ÿ[”é<ØWr®k/þâÏšGÎå2c'ï߸'týý5<ðÀffŸÚ_¢gŒj•¼·Öû3„ašÄÕ¶4%Z3*t)¥¾Äž?KxŒQÇ>Ö¨ÝaUòæxŒ°€‚£ØOw$¨Þ‡ à©:g†6ëË)ØáÚÙÀÏZÛ±¥Pl`âRß 8f:ë0ã|ëÌ9ß31ŒvÎ3UѦ9„T3çöõúµÄÚ5ûwdþ®]ÊÔÿcï ÈÔz•Aô1Õ6““5lØ0€Ç߇¬Îcæœ3!xÆT6D[[½½%æc|¼†©©€Ä•W.Äš5‹qùå ÐÑQD±xtãýžÐ=X~„ÿï‚£&hOèFÇô0.™&´ÔøË/¶ëõyJp·|©$زEfؼaæÍBÈ&¤=Bš«Ó³¼œÁ9d“c5+æ†æ„Ýð{èu·oÈ´åÜ—íf»¾aÂý­*EàûÓdÔŠ­30eŒ¢½ýäÊÖð„îááqÒàþû#ìÝ›7ë ÍÒ$ü¿–Ø?”Q’1›;ÍnY:ì's…qfY8ËõÊó\eºKŒ™zÞ)½žLñtû ÙyrXz&Foz#23-3b¶<"—$=ß]GèkWWÏà´oÁ™Ñ X{\µÜy·n“Î6Bí¿|1Ám!9×”\ôå—X²„žtÿ?<¡{xxô€bƒPt:ëW‚µkcôõeTÝv7â(2,˜ õH£sÊ UW±í(­SÄFBÉz¸»)h Tîu™OÒÄ KëÄvn>yNa–¬²ì° ÝÙ)•G¯w SæÜ7·Ýí’µÙÔ5ãËNu™ßœ8÷G:Þùz»­%ny[šä³ÃW_Ͱt)E3!›šdáPs€BbÅŠn¼ò•ËpÎ9½(•Ž/Åž´„~ûí·cíÚµ ×oÞ¼Ù?A=NYLLDغucc5ŒEøõ¯ûðÄû´Š@J`l,ÂÈHB¸uª²$„fÚHÊ‹<]Û:½Ú?Y—uj3ë!À¡Cqj½­•J Åb€(RV³;wŽ`r2ž–àò Ó ÿ6c&„j+×ì—sóy{q‡¶í¤YRF}dn"ÈÛ.*A¾h?oÈ^fG"òƒhi š<¡·lôÙ9᳃À]Ïævö¸ŠDiÌÑrh$3*¢—ò‰_ï+‚þ¨¾TãmxüñìÅK•Z/…~™uRƶ±|ò“›„äY¿&¶°å2Cgg—]6¯}írÌŸß‚ÖÖ¥RˆE‹ÚÛáŽÈû+' .½ôR<òÈ#¸ûî»qË-·xð8­À¹Ä®]ÃØºuq,†¬¡zÛ…ë‹õ•¥”y²lHÜõ37¤ÎXò2rJátÙ8xpO>ÙçŸ?„(Ó< óØ2oò·ù„1cD{®×?<ÿéa‚Ñ𦮫ý¦–ÏÅäò¹96r"Hägö¡ÉçFsíhBèGbߎÃ=¯>9Þp™ œ¨bÁÆíÙà¸nÛ9à.JÎ&„ç¦Y 4Oås;oª#ÇÂ*åÍ5űªuÀ¹)d$2Žz˼ٳ+X¹²«W÷bþüÖÓ7B÷ððh Æ”ût>ì'º» 8묎ÃÞ/ŠÑ‰™‘Ôçÿ øé$Åʨ“OîV#Àà5¡‡ÌI¦úWvnœà…jƒóËéÉ7å²–G¬9ëe†mp”„^w¿dúܹCùG2*@IŠígÔ»ÇeæÓ‚/ìÏ·Î<ûÕgucãë(Õët€'t{öëîω3â±'6Küã7¤®ˆª ؾ#™Çn4Ç §F9ͰaîˆƵMºCò®;ZÞÐszÛ ƒ£ãòñDO'Q'Î#†¹å4}f¥t#êÔåHÖ™CæÙŽ¼Î‰»­Ì±¢ÍnGœãèð>Ï^ xØÜK™[^Gqûõ»Ð‰öæ¼áj‚7]Œ,ìø—Ë–xB÷ððð˜1à¸õÖCé8µìÖ÷& ¡¯À¸"[¦_Ô} €é§³±`u#ïÔ²KÔ9¡.ɉŠI†ˆÝhØ’´®oùC¸DÑ#DJ!Õ»}©õD»¨…1:/×d®Ûáö1 å’¦ âysÒy „¤ÚG»®´ f΢Úõ Š )Q/B (E¼Ÿb쯃ô}EVØ'ëUûuNy¢ñ€ù=³£×D¦EwB‹ØŒ€àÿö=Šû.” ¬TmˆµE,'¸â‚eKÜ$‚7¿ÿûNœqÆÉA•žÐ=<^bH Maÿþ Mé¹ÁØ|ΨýHŽ“^÷ÿ°ë×6!`’Yg@SÇh:!]ÿ4¡”8gÓ$K´P™ªcž¸×ëS‚d½qe#šÈÌqT÷y ÷7toëÔmBÌ” Pἤ@Pêz BפnÈÙ=†úý)·4wÉT¾¸$Dºñ– !O÷f]Õ²dî´Ûí¦:ƒ/ÙVháƒ$’©v¡-dIÑòSj ^0 A¨Z¦‰ˆmöߎ‚àÖÙͺ¾©°`Ph»X ).$„à\"ª©w錚HgÂ^š6鬷÷Öl£:uSS1&Æc‡» ü%Áƒ¿ê뙫ãÝs)Ø’¶%¤¯Þk¦TÔ--!:: ((ˆî¬Ì™Ó‚nX‚óÏŸ¥Uð2ÕOìÕ‚ª IDATé)£··ŒööâŒçö=¡{xœ8”Žq<õÔ¶nÔb°#©™$ç»v`Æý¨V9‚€¥ìTÝ}!Úò”¦Ú• M)á/¾˜¦¢Ye“)5qJ-(3:µ¥ÒkZ4—¼L›9WZ4§Ö›šÖA@õ6šL´­PPÖ®”º }j—¿º?À¨ ÚÚ•€8*~É\ÒѼOCôÁ!Í’B‰Ÿ ¤#mâ£R„m¹UÖoCMßt¢¸„.3“a¾t:5²nh>ù,tAvª"vFí6’ÒTô<ðÞö†súTçnž‚4uSŒ«„”xï\ŽêÚ¼J+ˆK¬{ïx³Z§>s.±iÓ<ð@?6lا÷oä°“¾Ð‘‘ì Í“ý»íÉkÿþÀxªÒlÜxK—¶ˆ"ŽÙ³+X±¢ --!Î9§ç7KÛ1{B÷ð8©@ˆò[_¹²çFýccœçR§e‘†çO"ZçAK³o¶#€LºZýq“uéíÜs™ã¤Ï‘^?8¡üÏẞS¡“àÆïæŸ^~¾ƒ¢–70`¶ÝÐdp#ó¼—«r©:9BÒÆÅXrÈWæ•\uÉ!›7ž—J?SBŸq>9©ç&§-郘¹lY×QN£$IyÓé®GHà~YjÈCƒ¡£¢7ý£7¯þðüz^%èiM7ªQ°v¼ï}ó01礼¡qýtÞ !hk+Øú BH”Ë::ŠºÓ}äð„îáqŠv܇ƉŒçw?c˜£.||ô;À¾Q4.¨–ýLço]ú˜ÌyÏ™ßu ת܅EÖ‘:irÎΩùåb[„ùçLGÉu©Mɘ;IEÉ2S…´ÞjÖ>—Æö•q`k{>¡Ëf†1Y‡5×|'³NdŒx\8÷òŽå˜Ë<ëªûßsÃzà¯Ýp½M9¾ð‡™ï  ‚«.¨`õêS÷ÿ½'t ÿxðè"²Y§´DåüÂ.‚Çž‡c½jꎓz’v#UWç*×™©=.êIÛU·Óìv®…(Ñd%w‰eEXávÞ2-z£z¼8rö0Å–æ­>” Ék\Þ.i fÝ,'"6µ<¶¿ŒgµARâ¾µ%ËfÜ,o¿«µƒ4‡ì3¤5…1Ñ{+\½:ÝÞXCü®û›pÚÔAWïT‰Üœí'%ð·šð©ê¥—+±tž¹fauæ2àãMNúÿožÐ=„‡Úƒ½{džn-n%Ä*¢H`pp*U—¼±·9¦iò„rªF7µþþ_ÿz£`,Éíß?jU ±—hž}:›3 ‘j½ñú̃R烈âÙ¹j7eê+öBæzÝMs€Å%ÍõA#ˆcEÚ\@Œ ˆ¡àR0HÎ!¤°„ŒsDŽÊ=«X§æ•IºY–¸WÎy+ç<ï\¢Z·~óÕïÐíª s­jëÛ]ROî nÓ¢5ÁŠØ­€d¢t­b·éiZìf]Σ(¿g.x&yéƒÿgG=÷éß…|íÈ‘(½Îê.›¨ë2tRu4Ég×›çœÃÃùb·áa‰«®’¹DxºK¨š·‘Þ&F¢‚çC ­-@¥ Êe%æT"¸ôö–­†äüógá‚ fãŒ3º{Nݺ‡Ç1D¡@±hQ;J¥““‘㉮@Æ&U VãŽ8gºîùá¯wæfù½ï=„ıÀ¦MñŸÿ¹ [¶ÔlªcÅbàØµ¦ŸÄA@l”‘t ­eiêÜi»ÙD±®ŽßD,FÉNÁd ŒÔ`;AŒé{Ç(v°~\êÉ¿%Ë;€æ¯;ày‚«g. ‰Q.LªÜq.ÒQ·Î'¿ñ²{0¯{oZ±ž5^É´“®Úíåt–‡êÚ»{¡ê"ô”ðÌ "}-zÀ¶ýû½¯Ç¡‘î$ßÄ)"§–«Õ"jQ!MìHrÍ%T&ëŸ3µ,)$’·ç!®Z’“?®çvA©ëÿÔÞI†±„DIz›ƒŽ‚š'—Fín¥JÍιtla (Íÿ{vO´¯iw·7Šù 6íÎ=–”Êö5±…U©vãã5D·Çˆ"Žj5F­£½½€«¯^„³ÏîF2Á\WW ÝÝ¥ÌÿÁ™Á{¹{xxwì~ñ4±YF%¾v;ðg‘˜‡¸£v'ùD‘7Ð3ÿ f/HˆPÂ÷ü9{pÙ%¥H“XzL%™ÊÙzRÎ#äfdGèÍÒÎä ÛÏm8¿}a™úžz¸Û˜Ì@ß³ 06Ø i£wCî¦Í¦°Ô¦½¹#ÓÔA™Ùvfê„ï>¸z)ê#u\°xù§ïÿ«S&B_¿~=î¸ãûyëÖ­þ©éáñáÏov‚ãê–¨íx^&5Éi Š3ß\UÖÏœ¥Þ)œ÷'O'óØš¨ºf¢gÑAK„†„Ì1^ÀYuCÜYÒÌ#ÑFÄz8Äߌô›µ)¡»ëƒócœuþ Ù(OGç ab¨¢’äØCÛ:±å[gÖç¦7J•“Óz³õÄ™j!ÿ²Iâ_\ëX[ôŒ`ÕàÜÅH:z®½B¯þÝ©ÿÿÐã8ÆÔÔ”ý|Ýu×á±Çóº‡Gb<÷\£2buÌcñg”ض@ €'¶«ÌQŽS‰‰ª2ZIÙ°š‡0!ɲpÐZç*ž9=ƒ€Î# Z G8‘À¢OíB±· "%˜àjxa)²Q¶«ÜŒêiU N™ýnyµÉÛhݨ×mÀhÔìûÈìPx>©Ù}- g¶Î pI]ZœY Ðùóõ„ŸíÀ¡Ÿ;‚@9ÝéèH !(xiÎL†á9eØýW  „ú\*j—SJ4©“î,›/gÿ^B§"É> ®ù=œeçoÍÑE¶!׺ˆ°ò àsŸËv,\+X‰U« ˜5ëÄŽO™=´¶&åçÒ®W'/ªU¿ýÛ È·Y=<Uƒ§ð“ŸŒAW3ÑïyÇ‘é&m›åÔúúäoJ(X@0 B(&&¢„´í܉Âoè.i$•Dáõ@ñ‚Z¢>瓼ŒÉ±r¢§šÄc5·+(µóº‚Q¥Ú&B‰RhÑ›xOåËh%cNú¸LEúD Í/ÒŠ¶ˆã¿NàÚÖ+ØIÚš‰i“|r­_7t¶M‘°©[¦IœH’Ø®ÏuÕ¡¡6MM–Ú^I)„mºVµŒóÄâ–k?OÔúT§ãI({Z®Ýú±q;ß.(EÌÄCÕoÆ„!•gþ›1`íHýè‹ Ö?‚&ÄMœ¿?—ÌS>æKŒ¥SüaUô{ ¸ö—È]œ¸ÝtS+V­*¢¾Æ«p^®,·í…A{{ˆ––íímíZÐ¥w)Êåår€Ù³[P.9-{Qœ‡Ç4à\âùçâþûwaíÚ¯¥ÒX§–J ……C±d¬M)„vîѤ¦ö'Ž»VÊÜ!c!$ž~z8‡¬Iîqš©Ðc(•J¥\@­%¬k«jl`Ãjjb×±€ P !Sb5PFÁ(Ej»X}.J j##5üú¡=عSûhžÕ ¼ïüú¯27z"A„!ÊNµúÕm2eo#p¦Ó°¨D1¨¢NhbTeJþxöqVq‹´©I¤L%–GÛ"ÊZs†á3ùá®MªñéÎ#gÒ¤tjîð8É:€³ÛŸÃxK«fèL™&Û~DZiøl=ÈA!)´¯:ÅD\Á”­Ïº"~Ýé¡ÌV]Kq§«eXB&z*>£rºMgG"´šÞŒ ¼¶¬ øÝaöË À[Z“ˆÜˆÈ¿ð4°u8ÓË‘(NNÍpL¿IE8÷–34=–±6–Râ¿~þó¼ÂíRÿþêâ¥R¤ˆž‰ P¢º––ÝÝE”ËL;8J¬^݃W¿ú ÜpÃ’£"t/Šóðx‘Çû÷O Vã©vJ©Í=¥”he{ÔŒ7i´Ü|Þ4ÏrÕ¨ÇDM›Åó€õÛ‘›i÷Ç鬳¼¾Fž½<ÕÈŒ£›4f4z¾½T˜ÄËŸ6wÑý zžÆsÒ&/ÚÔE$•Êò<ÖÓ&)u çxóDjyóð$ãòÖ„êÓ†²¯+°B2·²š“Žöhß…xzß9*rב¹¤“¼„Ç·üy8é`ÈùyŽr4åG¤ÓrK˜JRðæ½ €r³~ýXê÷ ©Ä¼üˆ¨Ïzý7þ?CtgW)Û£H€s‘û+ù?$ǵwüâUPP­*ËÙU«zqÍ5‹°paÛ´ÿo}„îáq‚!(æÍk=é¿Ç7~øp>1oß“3H@‘.ÀFàÄ8®mH;¹ICäzx¿¥}knzHW6ã B¢TqöÂÔ\/—©R¥{Fç§r‰‰s ¥X¢!2v×7!óf$ìº4Uâf—y)o2=ãѰSáË!tó]ÝÜtA(æ·íÃ¼Ž„èujZU°¬¼#ÉC§Ä—?²î< ìîF]mwä]W]‘u»,Mg@äYÁf—3npz½Ïw_’êøuP4_¹øð§á³Æ?n=:2f¹ÒNQú£ve©s0ÉQ(Řý»S£a)òŽbŒ´!à1X¬„YŒ'$N…PuÂõû+gß‹Å>E,B½ ×´ý ‚SHIÀS<"’9ÜÙžwž§z† eN„š5ÉÐùò ™À;ð ])N»ËUC@‚1B$~>ùjÄDk ˆïLò2¾³÷-©ëU¶É”‚Q£›œp—ð ÉÛQ×:–ªÎÖ9eQÈP‚Õïé·ªö8 À)ÃÞï´(ñ!MLf¢mµïç$PL3ӛʂp£{8þî°–®Š¬µ…° à1ä0Ö¯ÚþU{¾¿á Î5h¢Ÿ7xÇÛ€Fnp]TÄ[ÞÒî ÝÃãÄ#Ü×?P¢ˆc| .¼p6.¼p6zzJhk+h‘\ sæTÐÓSAy†–Åyœvxæ™ý©ÕµïÚ5Šßüf/FGk È0M€F †J)†,õÙ¬§”Úô”jUàСIô÷cçÎk!YŸf™>cÙ”0âtÒÛenZp“^o:#fä7]¯¼¾.ºò§øÿ†  ”é6J [ 8øæ• ­ç©T$M…@G`±*nıJ“«lBWû 'XsÖ:,èìKÍCg‰ØD®– …&K,{æ·©áòìq¤#ÈÊÚ¸’&Å,á§¢pF°gùüÔÏ'ä»sÝ67ÜY6ªpW¹îz·gsȳ¤.POß|êív”Â÷ÃϽButœÊp–Hé›eA“Ñ ³lô@ÌH¦¾§!vΘZ&4_à”>]¾esú'µµªPEÛ„ÄïÍ稰äÇ1¯R&–¬B$û!Eq,Á¹²I©,ŠÍ3cË9×ïɶÊVæÔL7gÔFÖ+Þ¥Óèï$Ç.—‚@õò–-ëÀå—/ÄEÍAkë‘—<öºÇi‡sΙ•Û~ùåÀ›ß|ö‹zîZchhÊz§»¤Ù yëÓ„žnOÈ9]z}ú8Ïþê¿ò÷a9.mO70Q©P†'q@HŠ7¾õ‡`„[2Y2wÚ*£–¤ $j(`;–Ö‘¹jnŸÁuÝ!UT.….–Š`ænë‡45OnæÐSsëNçCJÒ˜¼ Ñ™š7Câ²[[ª˜¡t"íûX¥O.}™£ÚÏ©|F’rS!ÍØTѱD´fˆÒ%û<Ò¿â‚“Nƒ&ýöÞ‘ºïÛß?÷¯¿6UpÆ]võV|' ˆöz¯;[m:2€­hÇÖŽöôß•ÚÚ%Š,}þ¯Ü t—3‡sGE¤Dv ÍŒ’%ÿê}âÝ¿÷FV&ùûäËíH™n3µ ü»‡ÇIŠBaöì–ãr®ßöÛv»Æ/2E¸Ÿ¹Gâ¾MºÝˆ¸qm“‰ÁG£w'%-lжb4Áö,>ˆKÞôHÊ1žú¼ UIR)QSX1µÙ0~oóP™œLu ôкŒÕ\:Lu4™KIÐß97!p‘&p—Ôó=¥w¢ZBdÚ]Ž$b6@χeÈž @ç·OŽàÚÁûA©c\½SŽ--gâ…ÊYjnÛØá2 O,À)¥ˆ4q»³æ1:ßšè8eO¡ŽQ»›e¶˜§H_‚`îâ~¼éâï§Ú÷ïêÅcÿñ2=Œ­†³£‘£¿­¨u‘ÎOw5ÂÍáϦNg« y­tuêmÉ=ÙÙ"‰å³€;Þmç9Ü9\|ÐÑzê?_<¡{xœ„øüÛw:ªqS7ܤ…øõ‰Ÿ‰õª[nÔà ·Þ´©+ Guœ‰¸ít¾DË+ÇÑrÅ„ú.ΩbÎõûšߎ¥iBw\ßΕq…xc| „´uUŽ`NGÚ;v*¿ôDQîD”$ÃT&Â6Î,yÛ휉ßöhcNŠš}g ÁB¥F—Lr½H´d2N[°•/·jë€ÇXˆÝâ¤öø{[¿„sƒˆ æÊ|mÑ(jQæ%n3Ì%K†ÑÜà„¤Žk¦~x#Bw:dÀÒäï„‘Dñz?;2A$(–äÑäîDíA£ƒ£‡DÄ`Œ# "ô´„dĶßxú˜œ­:RD@R‚¡j'b$5Ê)Qd®ç¶Mó8¬*=.:=Ùö( Ú×ÌñwôÕÂ’-åm+¨­ØÓ Ñíh&ϼoÊIEËKI3^ë†|Yz›ÊÔÙ¼Ú±|k+ð­»dRèÅÇu´|âï³CéZçßúÖ²&C ™9‚µ)3šÖV%Š+ØéMè÷Þ{/6oÞÜpýÀÀ€g¤SÕ*ÇöíCèë³NkîÓ™ ”P-©Ã ıÄÞ½£Ø±cD;?å“òà`>:€‡ÀÞ½Èz¨ÂÀX€ ´ð¦Þ•˜ŒYG*J™~WëŒÍ*cêÚ Õ׬¾‡Ú/ùNûö¥…tiÒoÔ¡˜AÛÊ^`E¯c'à•ÝÀuIz•~Žr) bÛEL ÷ka””˜ìÇÕ¿L“ø‡fÿ/°§ÊjÖH Ñã²{è|=’1 )°"¤–ÐMQCÎB8‘¤Pd»bÇf¢š½YA™D]5µéÐ7{Û»Ò’&s÷9-I¢¤¯SÍ[GÀ„ä) `”Ûm«¨žª(©¢v=DhQ "µ¬wÓ¥?N<ç5iüì™×`h¢ÓFï¿X†]‡ÙT4¨ö˜©´3Éâ0°¢¶8P‘|-,ØÈ> É»süÖ‰¯  ÕH©<Û%@¾x¶ú½ŒØ.–À§7Õ›Êôö9UÒHa§ªíÁ)ä“÷7Ýh,?ÄexHbx¨ÙØ¿º¿Ë–=›3_U¹×{¸×{¼'ûµ·‡¸úêExýëÏ•W.IJe¨TÂӓл»»±páÂ†ë …‚g¼S”›òalSÿʼn±6U¤i„eBHÔje­jmA/\؆óÎëŻ߽:w½²|4䜼i'ïjÙÛ’uÙý Ÿ2FS)oBH<úè^lÛF00u«W¤'÷!=ÑÝ/ŠøVmn}࿨XÔ^_ëåáHgþÛázµÍUË~Kæ?¢ œ´#8§ôl’£-|‰%Pè‘s[œ'K¡„hÒʲÙèM«ÓÜ&œ.œ›j[]¬âÍ#ZDæ¶ó;楟Îì‡n´m2,cô¦ÖA³è\)íÓ£BHÄ: oÁ‚V,]ÚŽLu0FÐÓSF[[ÁÉd9rø´5“Ùt™˜kŸª'!¸}°v ‚¶ÅÔ¤awë“tÙSÛ¦J-]èž;¬Šo¨”&ñ–×þÈ–Ù¤º€ "‚6)NHÜŽY‰Ž£8Ä™#[ÆQÊøå÷Ÿû:¦†StܾŒqŒ’;/­Wµ;CëÖ Îõ_'G·œ¥Š\)Ssáæ¾"!±*v·3tßÂëðBçY©Î€Ás-g+Ã}¯RÃø.áÓô0½‰îÍrÄ6 ҵ¨òD»@…H™Ì¸}e*•ZõÒ?c–Üoç“!Ùl…©0 ðDL1·¢ô³)Ðí"U!B9éÑqL&¹è&çÛäeÁ £³Ky`­;Çœ©šde­­€—/±Ö¬” j•(”0 FTvF”¥-“ \©Ù)+(òEía°Û(p®Ø˜ä“ëן·c•Tñ˜>²\‹&Ýr­Tªßʸì¹uÌe.‹¹Žz’"qŠãÉм!yIÂ%ºÏT„N*çNbÖï@*‘†×U0ô­Šöu—}<ñï·µÊuÒFñÂqâsG‡HZ¥žøÕê¾T¢9Íëå/})ñxGlì^¾þôv@ †iêÙ \wÁG>6JWSo!ŠEzR<‹ü»ÇI½{Çðè£{±{÷hÎ|Z¶ì—ûî®Ç ßë{ÛB|ðƒ;œ+»LÐXÄææD;dl¢*œCf‡Æ3‡”zŠÀëf¥£¸Šïí@qªªlWyŒB­*ÂHù¨›Ï>ð¡È› a-@´ôá¼®§íùZ‚q¼{ö¿Ø!^"éúk(o™Tú1…ˆ)Ø Á£qb‚"IéˆUŽglWë Ÿ¸Rdýrý´E½±IÚ]¦¯!僮;Õ–"vž½ØÅ"— Ì› ˆDÄð$z9h ÀB¥^g!GPŒÁEö,ä@TFËæŒ P|)”ìPý¯¢+°C,•fúCEå,Vän ÛP!@#a§H ‘ÓXØ u©›)À#’¡yCòœªE(ýƒ`QÚ÷ZX@tˆ!úTMëÖ™‡ó~3 !%$„šT¥m„‰œ”B‚‹Ä½MHÉ%Ô¬‚¬Ë{·ïFTg¾N÷–W³5-Z3¯|d./. ?™¾Þ÷=-šËkWûV*V­êÅŠÝèî.“!y¡{œ°ðøãýX»v;ÆÇ#‹V²«¿ü0d˜˜ˆ±sç0§ÌŠãÌv…‚J Ã@ [(¢HâÉ'÷á‘Göêt´Fþ阆„ë‰>9b«DnÆ®U©à•ºj‹X‚b1@¡ ñ,HÄtf_%ê£ ”€i%}RŒ`°RÄ­˜•Dü@[\Üa‡•̓\lâà5eÂÂ9Sêq$ÅOˆTd,•ŠÄ_»ò§8»û9ëˆÖ[<€¥-ÛmTH„ÄÔó%Ì}¬ß:¶Aô€ØKSÕÌ8¢YaJ<æÞÚ” Ò)_)ëV;òàÔ7'Ó¨Øe½[™tª~¹îqnu6s_\õú⾩œs2´عvJ_õrð€)Ò–4ÖtÀÁ"Ž@¨œsVS„Nhâ¶f†¼%MŠ£¼‹~Ͷ Bqý5Èle- ‚ÇF/Ä¿x]2ê-Ó¢ù)™uªð W‘<åŠÜ™àvê¼²·þî:R éôôJ-,(B@þ¨I«Ø)‰‰ë[tp,!Ðs¼{xÒŠÏŒ«z)bc%,Sm\Û¾š:BÛÚm-ñkí€p¬\•]¬²ˆ5Ç7V¯BT«ÜÚÅÆ±±„øá‡!¥jS/(ŠíçZ-ç<‡Ä³„„ÔgÍ*ãšk¡··‚Õ«{}„î#t£ÅñúË?Òž÷Ú€jœîGl>ð«œ>mÜÏ0Ãä.±«isb¹Š… w'Ñ($þàwþ%6¥HH0p´TÇ1w¨_i‰³7>‡Îþ!p¡Ì]OiBФT©I1Ó9á.a›w«ö&"EäìP·Kìv;’¶fµv¬ÙQ‹ ‘»êxW8gÒàÌ÷0˶ˆcy+%±sÛª_!¬bÝ\‡1¡Tà`{žŸµR‘9ã ľÖ9jH^Gïf4ĨЭÁ %Ö#Ýš¿8Np&Ÿ\Pª²ƒ #Q¾òä-ÚáM‘þ®¾y¨E…üúãÖ£€¨N€ÖLP‘T%#vZœ¤¼Þ!”nÂÚËßwÑ`$[æŽnci+pçÕéö¶pÕ²SëÙñb ä|„îqÚ‚œQOýøòÊ„”aá¯ü¯M3P@̸~1fx›ó.èÇ‚óöXÂikÅêÕϪR¥BÍ¿Ou`þèœ5òd¬”äå‰I,Ý·]Eõ‚A ŠÁŽ.ëÐfÞ! R""Iߢ$)§jÄ]†Ø4-×qÍwÊ?¢ŽÐ‰K£=¥vG&××lÈÛ¨å]B’BòİƤ£qÁÒÆ2ÄQ˜ëeJЬЗ<©†ß)°•/WùæaŒ]lvÒÅ„ÚΕ«±dZB0'‚gŽ;œ&y0›~ÆÃïŸÿ*5P¿6lY‰‰©²Šê%…ÅÆ{—`j¤€Ä\(]#ž»õÈ]s+D HRM@ÈŒ’ÍSÄuÛv ¼ö×éŽ@o¸å噎^u!p㥧ï³Ãº‡Ç1F_ŸÄÄ„ódríU5~ð àËßI}p3ÿ+ ƪý‡œ©’¥#LéZ\"½ª]@°D€PaïgüqÚN€A û–[&Q)N Œ#ôÊh‹GA÷ ´ÄãxOõ.ð˜!ª…(FU„µQ¬Ôæ1°¯mNR[ ñHK€¶?AEÚ` IFk`5ž6Às<Ò ‘‰HŒ&m”+„³N“ÒŸ2Ux&?„shªÌ©QÌB7ßO ¹sÁ¬àÕ„˜´Yßy§#C‰°‘¼U§3n£öÞà€"t£‹ bÛ„ Œ¾wè÷QC“²ŒÑ¨-‰|5ÉÛ‚.uÖ¯Bº *Ek“˜ÙÝÃàÁ8Mà.Y¸ CLö®mÁGÊ*²œø~‘¤—!ÝK;ŠQ/TKêFN×7ê¨×‘V»[ò'8 ;~™ñßhèisëØk.&øË?ÊŽ¨c‹ÀâÅä”|yB÷ðp0<ÌñÕ¯Dý¸m¾í _àxî¹LŠ“ŽºW? Œš]j»±\•Ôy2Ø´“D¹"ç€;êvò®.EÞ „ƒ–º> ìVC!1HDQ‹ £¯kÿEt\Í™^[¸‹° BD2Ä©@PŠZPÀmUæ"\Z,= Ál¤jÈÓFà:w ¡mïhJ„æÎ‹w=<ˆB-UùL¢A5´œ”3¡œÍÓCóuŸÝázJ“ˆß¤æâ”K[mUñ‚¤è‹é¬BœÚQˆ˜¶3`G(8µB:ÓáQU\iJ‘Î(·×0%4®” Âã¸qÉ=(j‚}“ ðÄ Õ}&î¸#Q»µY5Q»!tÉsJB3¡ÝÝŒûg q$Ä*Åz­P@Ûk”~— b!b`²`ôßkº `WXw(!_CÄæ÷âŽã›éì2G: Ͷ»ÏÂçL¿Óäÿ „À qÒçt;@°å!à+Ÿ—™imÕqX¼øð‡Ô[³ºïóæQ¼ùÍs<¡{xL‡]»F°nÝ Mal,ÂÈH ££úûÇ1>åŽ)ÒHEN‘V¯»cÎîç¼qëtO}|\býú± ¡“iö%æ ^Q†øe3±]¦ã@$h1Ñi6>û2eäz\ÙªúT‚rŽ Ž1µ+B¡Vƒ¬\Ûu?^Ùs¯¶ä”¸°å 0p5ï-T)Ómµ3 ª<¿‰jXh‰ÉF¥1%\Gm%—üøX*‚IÄZ>8‰Â¡ZRÖT—4zwBV0ÞÑb?§ÄhH›¿4Ë!7·ÍÚfRØò†ëé=ª;2Œ!l#G©{*•>|]¦Î.Ù|x.¨- ÃEÒ᱑|fYHEè\2;$o:?F;±¡Ã”A¬–™@ØáÒÙ¿±ƒY³öc2VµCûçâžGn´÷B}¿5±Kpعy3Ïm½Ü‰r‚3Ÿ£BÎjaµ‚²|­‹ oQÞìÄ#àŠNMÄRýÝoîzÞù½d¢6·W8CûÒéd¬]Ý‚AÖÓ:ƒò|Ò‘Ó–©Ñ ‰;%n½µÑ¸"^ëì¾ò•vÔÛÚ¹óÂ9¾Èy©ý‘‚Y³Êèè( µµ€R)ÀÂ…m¸öÚÅX¼¸}ÚÊ3š ð¢8ƒƒSX¿~֮ݡí¦V°vÂbT«Õ#(ëßn¼ÓÍzÓf¼Ü•í*µÖŠA@­-«ªI¬ìT7o>„ûï߉¡¡©œh<‡I¦Ý¦9„$øÙöÌzùjmíðæœÆŽ$À¢ž]èjãLàCþ“s…2·µqe‹ãq¬ÔÊQZ‘ØâÝ;UIRÎ,á^ûŸ÷5µoÌU$Ë%KHÎ)_j¢ÛÔ¼´¤ ‘Dë®5D ·lgÒ)’ú;VÛŠïiÍF;Dž]Î*áSÃõ *¶'®7sø&gÜ–5%j(œQ%b XŒ‰%ì½ržýM8eèŸ7\ja tT/uiw"}×wÞÜ[Ê’¡yFy*j7$oUýΈGúv¨õ÷?|-vö-Vb¹ˆaû–%†ÜàNº™¦0þí‚)CIˆÚ¥¨ 6]mF^øfþ\­»‡0ÿ-J1KðH)ÑÏë–´'ö¨*åT½¤„Vš [;ܨÔâ]µ uÉ&ÿoåa¶É&ífÄHÙ¾.\؆j5†«W÷âÚkcá¶cþõ„îáñ"ãÞMÀŸÊ &P .ÿû´“snÉ;É{¶CöšèÚÛGq嵿²jãUó7anWRê’ÒÔÞæS#1x±b'ÎÐ96„+_ø•­1Î9Ãê矅Œ’´6CÜ\(ßõ˜« hóïÝÄH ›[7™µ¡X to:€FA7qž‹=-×a?“œˆ£YxöšÕõ„îÌËçŠÕ˜°Ûç5FyµSž¼´˜- 1B! 1h(°ûì…*M-蛵;z—€ë´2¥6gà„‚U©Ì”{µCöH:7nÚž!sÕ-7"u×JÖä“GµÏ’\¬·øÈz Ü{ºå’–€ÄA¹Øìddg7 ùÁþjÄ`ñ!¼v’U¦æVÓ)/‘vßú» #Ÿ:zË.\³»QXÃÑ£ê^õM¢öÜù,º0­¨]IC!+4ž¼6~j­jвbêÒ ×½HQT¨Âð;»ÞEWwPzJ1/·5Œt%½ÒZð)·4³% d2°±×|Èó[Šø]³`™¼}µqDÃqûµúÌ‹Ì߯¾5U§Dåèï´†‘IÏÕ2Üb@ NfäϘv‰Ò°AîóÏ >ÿómcŸúÛ¿+БcKX5`ÿâïÀ­G† yp°w7l™Ùœ£þÂDè>ú(÷ÜsOz|Ï=÷pþüùÍ}s¼äø­ßêrô¨eHM.I²úÛ/ÿ'dzÇé-w ­I;¬§ÎpÇh;kOÓ‡`â- lªR[nø¡SÞl#¨}!Õ¶¨Ö{“–ð-K‡Ä ÞÐÿOâ2’o»ò fW横‚~¿ÄÅäã«È%ÏÆŽõàÙ‡æ(Vª«LÚ/5“ OøNŒHPWÚ»Ü@AõÖM/ës_*ãzòð5\Þ¹#½vyzš“®iµÑEðŽr¯q;ºœ)g|¤.jè…Úµö@_¨Š¢SQþv±ÜÉcâ6DéÿX½‹9f`×£$¦ðÛÉ£\ÈÔrfƒûYŠ®-wocôìUeÐÆ ¨Ú¤“-­MJt@²OµRò•s]ËœeõÓãÔÇÔP«Zû?)“x¿‡$Al’gÓã¿Hv¸ö?§¥ãˆqNB-ü͵äo|¼æ¶LnÀâ´Óû±ñM@ßL¹oŽ—œ#Ýq¿KϭƇ>t–ßøKƒùmFçü¬ôØc†Ë—C„;!Ú“StÔR.EÙBØøã,—ô¨}Ý2…@N"þö6Ô[ÇPAg{lºÏ؆¢ª(ê ‰EWuüq"±¥’j›Õ)mê7þÀ䇹»xГ¶Œb¶žãÚµcô»¥O£/IöüL"¬9ãgÖ‘}; Œ‚áHì%²¬Eç­¨|Þæ¸à®¾F:æOúÝ#ÅLÖÇÆ™Û:›Ž1JqïkßãÓðá¿OJ¯¤¦ev  +B¾¨PÎø¶³ôe§ïÁ^W”>EîËŠ“æ =5†(,gºûøÈÑ÷c¤ÀšJyd¡«‚Z+j]°D6M­ *åÛÎ’¬«±è~…Îd`ãþ䯨ŒTë[kíüñó»Ïtè.v02” >ÕÅ}h…dÛg“³@"‰å­ÿHÏL*–EÚF/.g¬»Lÿ·¥Òš·„…F-3þ[[‚UkǛ߬^bû˜¿õ­[ùÉŸ¼æ« ´"¿Ïí”7}Ðÿùù.'Nxƺg§û ÕÇòrÅÂBÅÅ>‹‹BJ·[súô*§N-%éUOR“(¥BeR¥ô7!b›’ ’¨*ó—-òø^q;zK)ÓgÅVîQ`Í{¢Ú¥gØûïQ– ¯,uyÔ…â Q¢•D^ÆõÙ÷ï¡?­Zªmº®½›õ@ŽÀGR¨&%¹yÛ³ÌKX)Ù×9Ëßßñ/ƒšcúâ2åžÈkÉÄ©5¶?t¥- Ÿ£¡lbD¤ûR³‚{é(Ù ‚¯N·Î÷£Ð\¼ÜJ\å» ®²ºqâõ=±O¿â¯"ñfv³¬§=xK/Æ£U€^ëM@^‹]Ô¾M:žeÐc^ú5‘Õ¤¿}úèÛyváÆ '¸ÔÛÁ‰Åƒ>š×FIê¢Hæ(UQRéÒGøÒ/ôªo*jºG™WKº†"Ðçâ;Fú€A«Ùª·§óx±?÷\ûœ®Wðå3žh¥³³c¼õ­‡¹ùæíI~5JºÖµ—Y$8sÔµ¡ª¢ôª¡ª,Æ4·~ßI×fQá tþËÚ˜pM›[”€õd<Û’¡M²i¿ßn¤c-ÖŒ18g1¦-ë÷ù¿åúë·rÛm»¸îºm80ÍwîåÖ[w16¦¾ªóñfÛÚæøïumÙ»w’ïùžW¦}Rz=s¯WÞ̨q•º²ÒçÅçyþù+t»&=¯µH ô¸O©ö¾´Q=iœ½óø|d´Ç}  “?ÙsÍkü{Þ;®¬ãwRpa ~îA•‚ž€¾€U$/š¢Ýáv’öã¨D&<¼:‰¥8ZÕüõ»>šRì8xÝìýlWWÆ2¹ºÊîû.$½ô™ÓKŒ/¬7d(é¨÷é–êšÈIvWäÁঠõoD/ï¬ãèjiøQõn—ëá8Ôýmëì?vŠÿå/®’¸˜g¯Ûâyß¹&2áѵ#\ßîëÖJð‰]ßæÁµkU£m†Rö=໚Òö‘Ö+ÆiëìÚOó@X‹ p·ìy–Wî{΃ªœ[ÛÍs—®JpšÏþák¹¼>‹Ñ«,µ¶XUá¤Ä) ²M^pêÄD”-¯óî6ï'<çšš¾mó(š…_þÇoh_7+}øƒqš¶ØÕqüƒ[ý¢~r²àС-ÜxãvfgÇRσfÐzÏö n7ûÜÀkÝÐk"#>¾.ß7 ø9ÃÞ¥÷lôáy¿!-&"[¿®›Å‚×—÷€>=Ýáúë·qøðV¶oËæ¸Í}3Bß_õ±²'.Œžèè#pv©=ñ×ÎŽ"Èå n#Þª¬™Ù½Œp!,wÞõ%n<ütmPÖ°¿<öj>g¼îÔýl][À‰0Žr½ßÔN­¯ûÆHswtˆÂ‰t ‡8Ü»\Ûd’ÃZÜV1tÞ…hàS«—ØÐ_ƒ§ÕSÌl|E%t HÇb±Åkµ—ÛùØôw¡U2†%9C_–> "uå eÙ÷ª}ʧç£|»"¤K=å2Èújå-Q¿¤îà´8€–5Vw³TÍxKYí£v¥ü-Ôb=;ºÇE¦¹pXïF«Ô3^+•¢v£½0L]h¾ôÉ©néd‡¹Ç&†™‡NŒØÃҮШ³ ª¾ I»f~ä9©- Ê =Çèr¶ƒBÁÿþÃn vÓ,$~ä‚©ÉÍ9m3å¾9¾.†sÐëÙ?Ök¾ýÛ—è÷sp<ë6<<{ž{ÏNw±“á„Ê^tו Êl™äªÈ˜¼2l‹$Ó*€-?Q0y]®=ÑmjvéëŒõ»tl]Õ¬žä;?Ìþâ F(Ûã~ÂFQ©‚KS;“¸²&©©uæzÌ~l®­DÖu¸£"wÔg»·+ì oÀ{„aIâÐmA¯HBÞ(Û-F¤Û¥ËlNÓÚÇ5ÖîYxü"Œ‰`ýºÅC®¥ç„€çAniÔßê}š¹»g=°‡›èøžs©,ªô.g²°É«\~úăB\]k*Sà¬H}ø±—?ïœ@ißövDåæâY”6Üà^ –¥ ÿêäOÐëw¼ãšs8ãÓíÑ¾Ô ‘@á³VÉtŒRm©ò+ÎZ{¼SžÌvøŽ9j¥© ÍÚ­¶ßÑ5wEoEséçúáÿ:œó¾ ÌÕ¬q¼Åh” Ýeû‡m#µ·!fz&íÝ ,Œð¿C+¨¬äþýø&#Íù9á·> elL«áp¼ñ?ó3/Õ^"+ nFè›ú_ Ñëæç×1ÆCú}C¯gX_¯9~…ªô•»ä*Ï¿œãa~¾æðÙÁИ¶Wèàs}–|‰Ïífg•µÚÄ֙鳿bL$Æ»ø¥›ÐUM§Û£ì÷)«>^e ¯™y„ ÖÖróس|ÇÁ§ž`S+º½1œÞÅøZå¶§ç`Ï<±Ä¶?œO¢.I‰-Scs¶qG삦yPW}C‘ᚨåF*ú’ª(¨Š‚~Çï¯î4î\ÕZ釿pk5΂uvX( ›“[2¯ùᢠüù…•œÜhk½»Áö³µ«j±¿œ›_$üÄOàoÜ2ü÷]õý_ú¾ÓQìÞ=Áؘ¦($ccš]»üãÍ}s|"câuíY§Ïtÿ ;'É6ò ØvÃ<»o»¢Ç;ßö0c“¼ð%v¦tðev°§{žÛ¯<šËn;úSó+©»ÀV_/vÌëe£ÀÀž‡Ï§y$­_ZgÇÓ—7§²ØA¶Å¶A<'84=²b@ô.V!"¾î9‰=÷^j3 ªSw ?Q6_Ý9ê²àô­Úiÿ0)Š, Ë£"ùäÑ¢5/…ïo±ÿ¥I„B¥9W­êÆåLU>yÜ Âè>s³\œØ…”–Sâ —Ùá‰i:{ô˜òŽ¢?Ñ’ÔhÕØ–FÕ·ÀZ¥ö渉f{ü•ë¼å•ŸM'ôñ/¾š•ÅI„s¬_ãäýûC‰Ù¯âÖ¦2è`g•:ç/•E^F ô$:…ãõ‰¡ôû민ëUÙÅ.H)à¾OlN¬›€¾9þ2õõFbãœ.üØOÂñ Q®m›aŽà O‡[dfEoòVMO‚ˆ2l  nú¥çQÖ“—Æ·¯3³g £¼ø)qЧM顜þ~fîŸ3Ó]¢ª ʵ>»—/ЭǨª‚u;ÎâØèCm´¯½Ö‚[~ç©–±Iì-@ÀFzž"‚2·-6ÊŸ»»ÝŒýèï:‚ÊpðÔé¡Ï·J²sáÒÐ[œ;¼‡ã·^›=ŠœDéÛhEjl~4^ñíQÁª4ÔÔIÂ7@ ¯e<ʵöà^èŠBWhU³› ”²Ï65OUº =õ>ï3®4•-€zÇýUTà )°Ï¥^sM÷HrÌOÚÄëV™ÀëÜ›eÉøíká5¾ð•¶Û“'qµ€®HÊj"Ô©s Y͹«d–G\©%3C#Y-kÍüâÓðÅÿBÞ,5$œà“Ÿ¤B2Y{\-ùÎoüÀß¼ÚÅÛκMLl.6Sî›ãk2Nž\çá‡çÒIB–öò§~jŽcÇÞø[6‡ð-…Œ¢A5Fäš]”¬ð–iĤDXAq‹cúêQÏL×¶ö’ŸÖ&«$Û:óÜ¡¿ä'^!ø‘þ¿çH÷(U¿ ×ëЫ:ôë’nŒÚj¶¾¸=Ÿ&Ÿ<³Êµ¿« owÖڧȹ€,¸ª›£¦÷HDŽ ƒ“õPkÓÀB!o-KR–/C·õå<µ@ÁîìÁ}»éÚUVEÁé½ZQhŠÚ G?rÃ:™ìI£F{4dQÒwºJ €R÷=¹-hµ+éûÈ;eBVt:=ÆÊ.eÑgÅLñ;O¿ «$ókÛ8~å°—QY/B&&¤æëR§V³*Dóý² . ª² Wv™ÍJ•®9ŸA«½®ýâ&Ô‹“zȬ?ìXùÍ]¬„“=xr-c¢«¦ýÌflô:²û¥ëC^掲¼ç={7ýÏÃø•_ùxà Ÿ¿÷Þ{¹|ùò& ‡Ñëž}ö2Ÿÿü)žzêu½é,ß'­œ²÷•¯¬ñùÏ_¡1÷lî¦õ¸,e&©ª‰MJ$V%2´˜œ:½Ìêj —<Ð4ÿÌ­%üø-­ïžBMù4¹2ÁÈBâë‘Ê3…­’l-çù±í`<ÏÔ$_ñ~¯¤_•ÞO|nxèÏH7¾n¹÷ùs¨¾9Ç,< ½ùÌó"Óôˆ)ñÕXc˜˜&®îU2Š„¶õ€W×Ù¼–ûjÄÀkü¶)„í^pш¾D†yìoY•¢Zz.{<¨y‰µÝFM @¿(9~ÍáìÔ î»õ›Y+'RJÞZ™¼Ç­“(aRê¾µ‡c´ªk^«:õ–kí#øNÙ£T}´¬é”=:ªG©ûtÆzhéy WV¶óâ…ë)í÷¿ôV./ïð€ˆhÈ Ì­ôË£½Üj¿,©µ¢*KËôÝ…Ã Y”IÆÕz–¼•2!+]4~æNÀÑuøÃå&_èÿ}"#\ 0"{=ö›·RCntÝæjžáÂmðzÁÌ–×Ù<Ò½Oz]™Œç÷UUcƒllNhÕàni¶ÞÿþƒlÌlw/óñèçff:ÜqÇ^Þô¦ƒìß?ƒ›€¾áXXX`}}}Ãç¿õ[¿•Ç{lÐã%Øëkk5½žÉH#ÃWÙ¥KkÜwßiÖÖêtŒP}rÏ(÷Õ­E`Ïl‡¶´j£©ÞH¯zIÕ†_£µ =¡2½‡‰È´ÚáÂ…U>ýé£Üÿ––º\^ƒSKÙd"€ÛŽÀ;nkÀC ˜í´ºÜÒ¤@kËÌ"Óã+€å{®û5n˜zaÚÕl“ó~ò0±¾ÆX¯K榇ŸcËåEõGy±›o×®ûOÂú£P+სÐz[÷¼DjƒÏÚâ[÷á;¶Ö,£²¡ »“‰,u:4µ+ÛèâèB6•‹UUÆ!-ô^3‹›Ò¡ẽyµµ„¢ 摜&eÓF&e³O¨Ðb¦lÚŸ”àd{ápUE·…Àzgòð¸3Ñã›îú2Òù:ù­žäúG‘Á |Ê}¬îrÛ•Ç|›€ƒN±s>Ô}w± —í ó$Ô…À(¨uÈh*èN9¯£¡K×ÈkËê®­tv!Õí®–²fPv•$Úó¤ãGêÁÈÃ&œU(㼞NvÓµCX|Å6Ì„júÅ¥ãÊ Û±2‰¿$0.[èÓþÐ.¥M oR[O\‹€ß"¸n˜èÙ uÿðî;¹2¾ë$ËzšÏoSÓÊÚ[iúÐâ§TSw/µ×d×¢¦£|‰¦Ô}JÙOýãÒZ$™$y×hKj•ä¹Ý<÷ø‰D÷ü}×±¼2Òù¨]IœrTEée]CÖÈÉÁœ]~êéŽ"Jè;ÑÒooþp–š»÷Á»oÌÿÆ]pd׿üôg=6Iq›ãÏlkk£ƒ¹%ø›ÿt /,à &sêêQáMº@ØQXä¸IV§·¼÷(»_AÕ5¥¬Ø¿ûª6Hg3]æg};uüÀÚÄ^«Ù»vίŽZÜǼ¢€;-p«KY€Ù µXå°ZðöB%HçÓÙ œôÛHᕻ¾H0jæØ\ü†—´Í{Á݈H=±Ž3ËêÄ’6MÄî'vï;í + v8ãO±00}eq¥‰â„p”K}œ ä/ÙÁÜþY讉`ó> ÁHáQ:‹r¾—\IÓ€|„b"à‡}Q~u#I×;yØÿzU‡o\þ#ž»™ny_’Ö]sÄZœL‘:@!+oM*j * *J×¾=oLrevXv¹˜)Åáן.jš©C+¬›1¬RÌŸ›áÉ_½É/ô ‹«‚Ö€h7#RÛÑvÔ p%’ø ªA™ ‹Í8&y ;Ô×|Zðàg_pÏ~Ø6>: ý£ Þõ†ËÛã Õæ|¸ è›ãÏõè÷ÿøÚpŽ4“žAðÏ~Æg\8ÎB4éQ/]8Ц‘]Õuâc'Êáè¼Q£'-ÂY¦w¹æ»(ªŠN¿ç'ãÊ¢…õþäsŽkÇŽá¬à›õ}¼J? gúŽûm±qiÀ9RîÐ¥"2@^Á»ì}bÚÚÙÐc¯xüN±?¼¥Ï5Øc;™ôLðØRÖ/K¾´û_k׆u5N¿Sú4¼²èÒ×TlI•Ew¼ó™* zÌoËÒ&Pr®±¦î‘ɣ܊F€¥G‡%f’ØÏçÿÇûׂœZ<ˆ«@Å ‚5¨Úg|V¨ö t›ñ3ŒmÜÖL³8Ö% ÆáÙðøúyU8!°[¾·pŶVuwvžÉÅ*‘Àœs\[Ô”4$2ç¼ôª³ô©1¹çwãnŒ¥Œò~ÏPU&Ñü9J«º,Ø-YVç†A=BPÛãÜ ©½5Ç9œk“Ò"ÎeúïÎyBÛä¤brRf x^ãÒwÂ15U0;;FQˆáϬ÷}û&yûÛ¯åmo;ÄΛúæø“C‡føÀ^Å>ðªÿ®÷éõ /¾8ÇÓO_E!=¿O¦V2!ÚŒõ†ÉÙ¼¦Ñ['i½KÙH³ú÷i˜îŸ;)¸ï ü/:Åéjœ¨ôάK¬eËÔ"·Ýò˜Œœá5Gaï–s:w‚ÝÇ.`äÀS§»ÔMŽYËzÚ÷ùj‰kZ{b»“E&½ð(Râ„H4ùØ*z®N(*„󀥌^ÕíìØ>æÜl2;yœW{aãSßRxà”Ò¢‹ÚGÍÒƒ¹Ð¾Ü‘ôÙ3շت˜Ä`TÐ {ß=ûѤævoý-tëq‚ »xòÌÍ©MAuh)³®  Mx|ïcyr[‹ÿQŸ]ªÔŽ–K·:Éoªõÿà ;‡‚âƒ[*¦•£L¸äØÒ¿w-ñ6Èæèß̳ÃÒUûÚà;¸Y oÛÌõøšÈbosnMøÈNo¾-öÈ€Ï×µËþÆœñnÓ÷’®¹f ·Þº“™™ÎfÊ}s|}ŽNGqË-;¹å–*ï_XA€ûð}ðk·LN.Á™6#QcÞæcS]þÊ÷}c¼\çàì)J×ç—žáuÏÜO¿*™X\£\îSU=ÓauË$µÕ>ú ~×áS®Î"{¶Åx.Wúì¿÷LHM»Ö"½¸XÁzÛžÔEty¢ªÉ‰Ì Z GÚ-3ç 'AœpHA«/œ¬m,õ‚kGùmI[Ó¬°önBÎ[¥†ZºUá ÊF 52Îc¯¸Q*™±¤[ûZé¤ìvËÁ瓪Ûro’›¼Àþ¾ÏÜÆü¥Ÿ1’º«›t´óŒF´üÅ› Šp.è²4 odlƒÞôvƒòsV6ø5Š¡ç: ¾ðm‘à]¯üèÛF—v´†©ñÍys3å¾™rÿ =xŽŸr 7¤Ž_8?û+®M€K®`™U^“ÎîÇ^±ÎØ=ŽÃßyœÙ›çRMõ`}ŠWôŸÁÅk/?À-—Ÿ¢×ëP™‚~¿¤6^'½_• LŒõ®åå>3ç—pN°°"èÏõ8ø™SÍœ9<ÁžÔÀÎíJs­ì´íš4}b²‰\W;¨·ÍLÓ 3rvAîÓÓ¢Ñ6û’…h&äýÃ%¶aŽ ÛòB{™Ý+èþ5ÕÏýß6-é½¢'<«=Ùµ*ïßm¥OÉÚV®!ZOäAg8Ÿ)霫R¤õÖóÔ|̆ÄÞ" .i±ïó¨ä¦uäZ˲ÏSk·pª>HQTáxjñ–TÚHâ+R4me1jG$+R«$¦¶¤E£Ë^^µÖÚ‹ÀºÑj—2´ÄëÂ"Y½Ôá¹{w‡…ŸdíAu>rɼÃóíÄ8OýŽAÁæ¹Üy2Z ÌóŒrº(mSo oÑp'3 xõu‚Ÿþ›MZ=ݧφ7¿Q°w÷朸¡oŽ?·ãŸXá×½Ë0ÑÍ“Ùî{ÈqìTlf €GðŽd§II¸º!ÀI‡ØfÿçÚ§M±Œ}C—±» àŠØÎ{™åƒTUÁîµ Ü°úkÝ ªªàLg?=ÑÁZé…D¬JžãG;ÊÙÿºŒžxfÖÑç—qÀê*,wáJ&˜•Ä]bˆs•>pçX Ò«²Õîo[´IÜ>2.“t0~`2¦=ÚˆŠÜÒCd /ìÆÀRÙRXäªE}$î¯<ó~+ŒÝZeÎ`0÷=³X¥BD"ð0q°Éö5¥äà·8 n MTÝDfø!¥Miú˜’Q»ŽBWž¬ÈoJвbçÔ%öé³”e­k¶-ÎS+ý)î}â=¯‚Œt£Tú»ã¶•ÊIÌ­ æ+!Z¯Ê"Õ¸«Òëµ÷:Aº5j¸+Ý)™þAŸºÇ‚~ÊÑ» W£z¼Gý›s™t ªmqŸÌ¤[å€Ljd IW#Û²®ù{å2«ŽÆÄ( $Å!Ûê|ü$|Ïg]óý ÑdwjÉÛÞ{w7¥œœ_´vüê¯nßœ\7#ô¿¸úâb‹WY\ìe*i ©¬($Î9VW+6ÒÑ\Zêqü¸—P[_¯è÷mz®®¿ø‹G%Rª¤êæëä’ºvá5 p¯¯»Ð;¾É®¥£ž3àS& 8<Ó¼Í§”°ˆmÈnØòB9fí¿8ù½„'† ³F¯×¡»>Fe ºÝ1¬•tžZÁ¬úº³zz…Ù>é»l”@Ö5Uߦy/W³lÙf ˜- Üù£ÞTnKü7;¬ÚmI•TI.[…¹µ¾ézÐ*,|?wË´º_Í¢÷V·l¶Së—0©'<Ñòm1íÙù¾ÞGù§¿÷€OI‡´úÚ¶ úe™¢vãÔÈ>îOÀ1‚OQ} ×Åت»‹†”Óð䣔kYöýß  ¥î£”¡ìx-v!ÝjÌ À øâS¯ç¹“7á”/?œ¹°¿ñ—¾¾ŽÃGê!MŸÈjº!«Õ…¦Vèûc%µömgýN™@¾*ŠT«_KÖ/^êZáVmCà^¬áŸ|¹19q@má……,> ×*ð ž2Lñ—íV´Áí¡éÀÅ»a>ßm°ºµõ²6‘lr²dlL–ÙY‘ÈwM½=ú‹›ý.ód·„þÉp³|ï÷àÀñ‘ß«ÓQá3áÈ‘­LMWù%7¯/K•H‚2µ–lÝ:Æ®]LM•›€¾ è_œçK_:ÇÑ£ H)(K•ØáJI&' Œqœ;·ÂÕ5ÕyÉ}Q'])Ï"_]­xæ™+<ùäE®\é¦cµZêRØöûj-ÑZ%’œ1.‘è„€ÓS[93µµépÛ3ï:Òȼg,ﱢ˻¯ÿ>°óÃ)åS—?ñv{cL?²ÀžO¤ï4VÂî{^@,v± Œö‰€”¡Œ^r@CÌ"ÓJoy‡¿”¨‹ž¾r—¼KhPk}”¿EÒÇq¹j›÷t«añÚkR"­c}fš¹ƒ»ƒMSƒŽ€.œK€'±(2á–pŒR È+åû½•4 ,µ=ßʤþn)-ó·ncmçDúZع•ó‡÷`L6²q;yŒäãþøYTïO™H’­‰\ÒôÉM ‘TÝ„pE•z˵öíe§ŸÒïIú7öT$¹PÉ|£×Ò_™äù¦†}®Uª[Ç|´N€n‘)júíUéõÔ#°Ûä«>x ‰án¬öt Kk¸{áB9RšÜ¹H&c„Á‰'¥™zÐsÜðbdDí hfˆ˜6üCh¤Ymf83ÓáU¯ÚÉ[Þrˆ={&3vGUÙÀ°wé>²é#Ó>ê¹7àzW¢—µqWÝ/LMT•¡ßoôâÇÇ nºi–ÛoßËÓ›)÷ͱñ¸þúm\ý¶?“Ïî÷ —/¯±¸ØËX¡b@£]dfž¶°&’”Iø‰ß†çç@(Ø+c(˼¥ƒç ‰BZ„€¿õÎÿD©úT\»Å;“0‡¨Ñ`al¹‹E²óÉK¼éŸ|ŽJ äB—±3ËÔEp õnÐByæªó¼£V‹,4)õîKüDË|źBKœRëdÒb‡ ÝYô|çI&û5¯9 êJ³õÆ…ätöøg_Íé§x"’þréSóõ75ÐGNy%“Ûš•§hTßòÕÍ écíZ \¤î|Ua{Ð~±·æK™É;®‡¿ûZ7¯³Ó$%ÁAÆø(FzþÚ¨±~ÕU-dZìíhwûöq¶nK-›c3BocÇŽqß}÷¥Ç?û³?ËÑ£G7Iq ãÓ_„K1ã¢íÕüÈ/»FáM4å«ÓˆH¶¿r©kçxÝ;aë¶ETí•¶¢vÙ¸ë÷ãKë¼÷ùÍXTôË •^„H\·Á;FÞF…2¾68q)õ¡éÉHrü1~9bÄœ'h÷Œ§y=ÐrÑ/™Eð*€¼² CÇœªýM:ЕßÎOy§äôÁI~õÄÁC8!€ ç0Öܵ𑭒2›Öu½ËN!Á IDATfŸVèu‘Ýkã k…¯i«Â ´CjËsÛnäøÌa¬8)ù#uFIŒÔX¥Bë‰e5ƒ EŽVÏˆŠ‘hËÖÉæ‘¢öø|ŠÎ­KýáÊTí%[•5ÁhÌ+¼Åô»‚žíðð/Ý™À~éØ K/Îø4½jZÊ"È[!©µJª€Ne+¶øŸëÈHilGã Ð €¼`ØÍå5u†·ßþÕ¿ ©Ót@Ûej¾ýí›sÝ×Ûø ¡ !PjSø«5Žwü£ì|t¥[FxiÓÏ<踼R{ VÁ›\ºF†5n#ùV[ß¾Îö7¬¢kî®0³me ëõkK^Í-¦.§ÖVøÑ_ý ×àþý‡ýd+}¥û¤Uq²®vò²¢h?Cà-þx`=28y÷¼3Ï5sqœÃÅ`ÉR´ƒ7™Ùœ†rq’¯û¢¸ž¬‚ÎúfóAsŠƒÇN%Vþîþ¬ðQîùm{xúšWú´µõÚê±\˺ù`1\2òÚ¿NKòÑLS£?®Pû»g¹ÆžB^üå@çBãëØNðé¹·sÂ\ã¾.m¥Ìzŵÿø¼”XZÍÂB ÖâmàqĨ<|òNºñÖzŸqS7 oW¥õ‚71ío”âÐN`¤Æ§O,3}l9µ´ùGû1+@Œ"ð5œWTYÚ¥E¢Èë0¹Ïm–âq´/¦x ²Üc-)‚¾iÈqßÿSq¥+Y×ÚK¦:‚w¿%‚¼k»Æûßú^Á_ý«›öf„þ5_Ï5ôn·n‰(©f”c¼%êü|Ÿ••Qþæß÷zŽïøŽ“´}Ê»2c$ËËYÂ}‘1Ñó01!Phq¹mÒÛ•:Açušéï×”UŸ »î½¤ƒTfŒ€wŽ3sf üóÿü3”uL­¯lh£i*XŸóQy­„<4\~æŽãÓšB„¹L4ÜF(²ÄÚAöShÀÔe5mTgIÇÞ7µçب[.€ÎþöiOk„ÁâºkŸºôÉp­&Z¯‰2öÒ4X ë,}oGf’kíd.DJ'&ýç¯K3Hg©µfnl¶•†OQ;äcÝ]ëºy€=DëJy­u­ý>ÝñÛE§¢è„H¾S¡:†J-qRr¥šåC_ù^\l“’ã«×УãçÚ ­­ýM)ÿz¥1A=ÝËàI.”_Ì8Ö&•·¢_yµ7c|ÿºsIÖ5ê²G€6|”^¯¥¦Û£’…ÿÌGÇ‘ÿ¾C]A];Lß2}ÔàœÁ‡‡Å`w8&»ÛáŸs8l"Ž9gÃõ•é·ÇÅ@+ª§©5ÅÕmÎNOZì²ImµØ¢Í*q|:TègXŽÕµöÇwLóÃ?<û'®eçÛ33’ÉIÖmNPQÈD|+Kõ—.¥¿ è_Ãqþü ËË}„€••ŠÇ¿Ä‰‹™|¢¿øæç{(%÷¢'ZK._^ãòån+yÛëY–—+^xa‰³g mÿÐQ>¢™IûÚ¸ÖŠ²ÔÁ—Üû›Çm©$:z•+ÐJ!‚bœ’Š'¯ÛÂÊx•d/bÌG2cÝ.^é,~Ï“±œåî]rƒ{½œã˜ùÿ8ò¹£‰ìÙËJšäœÕ?jY;F ¬tWWžTJPK 7?ùc|"2°‘ZøÁ•¶6iÍe“óÀ;ìl|ìB¡œcÛ]^øÅçP&ßâš)i”ãeþ²ù2ë]—1ÂÏ‚¶¸¾Ju÷¼F? Ðm«ZÒ­B4ijXo^éLñÔö[X.Žïâ¹É›Rº]9_COúê:è«ÇZ»ÈÒð*§ˆ:©hU£ËÚ§äµIÀ.´C–¾w>)µ‰F®õ÷O½3å5Ù¥æ©ó7q|ñ V©5[©©•¢.JŒ”ÔE š~Ñ¡ÒNª ñ*‚ù‹×—&Þ¼tktåK¥!çÓóVHÿ8ÔΣª[d¾Wº _”~À_UpãïÖ©Æl­ãÍ 5Së¦E:³ÖQ×u¸oaÞÜPUŽªªñÌXøÖZ¬ó­f6í d7ç°ÆQ…4k‚À’jÖ4’¯Uߦ¿Ù$ Û(±]˜f_"•å^ÆÍ ‡+vïOŒu/Û [¶”ÌÎŽqÝužÅ¥oëÚ„óf©*/s{5â\Y*n¾y;·Ý¶ûÏŒÏô—6åþõ0ff:ŒÛ¶Y&' n½uçrIdŒK®\Ygi©O¿ï–Q½‘Q-éÔ¢\™6:éMÛ[{¼—R¢”é¢ð7¥–úÜz  øÂEÁÿñéÂz[Ц ÷‚ÿA8¶’ž„UXTßðÝ·ÿn[xŒ×=r?Sf…ñ‹ë˜³ŠÞÞŽoG[3xõW,ë_„JKz«šîš ¯%F *%1Û¡–ÐmtáûŠ}P!R9±ÉDŠ úÈE ÐG‘ÖlˆÐs8 6FíÖC“0i:¸òŒEZ(¬C[‡²–ê¼ó€o…±Œ½Ë¡öf«‡ÜX¶ö¢ ¢—`N6Y—EâÒ D匮ýG@wÖ«—%˜(yû…ŸO Qñö8ºý1ns%@ÿíéw³¤}$„¾,½ë˜ ix š`X"|:;º¥)ç£öÂUÞð¤ð¦*²k…WvóYcâHpÚ_7Ím\”äðì)–ªij¡©(øÏŸù6%Núý}¡°Úxc0­¼ ž ”P˜”½Ý¬-ƒPPp³a1g"øÛŒáR]ðýç!å#yãà™}º…%k{ Ê:“Tuð¯ï„ë§›… s^5pvÌa ò¦ Q͆Ôx®žË¯6dµáç¡-ÙÚd ÉZÆ\ëó€ 8-';H¸~¯¸¯•l$f³•ùØ·oŠÉÉ‚±1ß¹“·¼å ¨Am÷Á!¥`ëÖÛ·ýHâmú×pLL´{ÿ<_(½Ö«6ŠüøïÀRŸá6ó¼Õ<€Ñ¶ƒsìbÝG…Å=•‘t A·èp±2,»àÌX6 mdcÉlœó`êBn›•ŠÍ![éuZPîž ñkZ—ò½é÷‚ @.¬½à>ZÖÖbÂDo°ÝXL׃¹€Þûc)ŒE[‹¾Õ"îpɬ…)ರu¼ºXìQ+:A@‡¦ç¢öÛ…E¾F#”¡s¨fÏO®2a׸C=JÇöøéþ¿@¬;DÏQõ¼žúäÉUª~ÁÿBÚiVæGOw=MBVÅ᪀úe 7ð"ï²m°Q¼L~ÕÀ˜¦w×¾`’á£òzû%1O°©µËPž+ŒKipm,ÂBa¬_( å|Ú6*¶¥þð î¦JoJ£„Au +}Ê׫µÅm¸Y_Ú…·•…Ejo*dèX´€º2…Ò­¢_{•7cT2­©N5öÚê&jZø‘-u×…tIÜ%’â¤ôZëFªÔÆv¶·ø.îÂp~ukÝ Ïxb7B¹”1q2ãdÝ1}íÉaÑdY$?ñêNêR'ƒ•ª(¼Œòr­]SÒ×¥, æ>.X}ÔR¥ÀÍ8Úm‡n ´`œGITÙÞŽÑKº5“fÛF5úíVyà7ª!®EšœL–j.;><×)¡TÙb%×z·oüÁ/üoòj¿ Ö¾ñqÁí·oº´lF艇µŽåå>óó]VW=£ýñÇ/óÜs‹¡¶ÉmŠa2Û ±­¹è¡u~ï÷ÖÂè¬ +Érãq‘m­ÓˆxQkTÛ¦OêGÂŒDtCa8hOñ¾â£L˜5þšþuªª`UM²¦&ʱïÁ³èº¦üw§Q}Á%#¹tª¢VNBgß“:" ŽÈÀvC@w#£éhÄ\çÆæ3\+õ.ê>3÷oI³®ß´W(¤qT[ÆY¼a6wz~m°ËL€î 6.&5¨kÚÏÊyŽDT>‹€$µ6!\j “oÀÚÔ×hßR¦Wnߎó¤2Õ é‰f¢ðVHj”ÍPÔ΃wU>ýneôúÑI­¶:EíÑ-Öߥ²8ëÚ~ï…®|¯kŠ¢b|zÜó!вB ˃§ïæÂòn„t¬÷Æù½gÞ†ØK*‡$ö¿ õÐÓ?‚9Ðô‡V·òÑM-ZÖZ']ö~YÒ/¼ÑJñö’‰w€—õ±~w>¬h€uÿáh{5Ùå.–w2±˜–ô`.#Û‘þ ³ÜfÚÄf@¿=æ!ë¾ì& ‡£7ª—1‹é¾ð9xÃÙØ |vVò#?2ËhrÙÕÛFí‹2®~A"„cf¦`ÿþIöî`Ïž ˜bzºleì6Ç& ÕÆÂB8ÍÜ\­cc)%_øÂI¾üåKôzfmªÊÑëy–iQ(VV*Ö×-E¡)KÍä¤'ÐyœäرEΞ]ô(ßv¶\BŒ–|b8ŠwÀ•*K9¾ù0|ËõPúCÔMcLM­2!Öø§Óÿá¬q°<…s‚£kGÐÝš±£ëÜðéç©Vî#WJ°´l“_ÄøŒ4Z nCbÀŽq;"ßàÚÛ#SñbÄ4$Û-dn £#¾^æßÇ6û¦N_Në´bï±KIŽõôk±º} lT{cd ÃaCÔn½ïxel¨Å[”u‰Ý[Ç  Ki“ÈK¬_kéÛÅôZ~¾ö=ÜR0~yÝGïc–3wï÷‘oip“í’mhôûN}Þ…Âv$Fç0ç¼¶>%Ÿƒ»±ªUwÒ%²R&‰½h]û¿C{¦; U¥Ëì9¶1ïØ*v¸œþ£|ænž>öÊ¡¯.OIˆ(JÝFýõä#n¯¢Å®üôW‡67'„wMÓ:É´ÕX¨"Çà {› È88¼5¬üc¹f¹æÃ7ŒrããÛT±S»Œ©äS[÷°ùÈ 5Æ•SÛÒëŸ|Í-¬ÎNûv=ëR/xrs6õ„GšC Eh>ž”¦eô¨à&¬‚Cÿw¡*ŠõŠéÓË”ºïÓà+¾În ÅCê.f™xŠàÃv÷öèk­‚r› ²­Œ&2OðØãèø¹{ñdŸJc¥:8^ù-O§’¶¾b••)V&yøž;˜ÇþpÑ Ê?DðqåùI,&DúC%1àÚL,À¶ÒïëÀÿü¼nÒA¡sÍŒàÎkh×±CÆù¦½ðóß·9ÿmŽÍý/T„~µá|á &Ôê2-Qáø¿?ìøo_t>]®-hCÏZj¢´˜%§E{ Ü_1{Ë×÷ ŠÊGuRûh±* n±O¡/×üÀSÿ‘ýžaâ¿­ùgpp5–×|i±*à‰ã¾Í-rzê@öu™uilÁj©V2èÙÀµ§t|.ëÕq;ˆÛݵ&C× Ö‚©qÀÝerœÍwËnðséÖð“4«hèQW=÷AÏÁ(ýœ¸ïßL·à Éù]{<ø¸‹¶¡à¢Ø‹>ýîœH©wIµ-ºÄGò…ªÐøH=Fîeá]AðE×”>/v¯ç¹õ› ð5úcË×b„ààëòJ$¢™r‰S™•¨VAÁMp/öb Y€Ð³íDèÕ €Áh=¾4Ö÷}Óô;á³I¿öV–”ŸüW7Ò[èàP8'éŸTÔ”¿†boyžâ±à‚_¹ÏjØ‹e§S{I‡7÷ÅMªA¤síÞÊÀt—HÆõC¾ÆGý5ü•oüÄÔÝc )…ó޽{7Þ(7‘nÐ7ýÏzÜ{ï÷ß¿JCŽS­˜ÕZøÅ_¬Ì(bE`¤ëºÑQ—Q_ÔµÐIÜÜ¡x_‡²×gúU]¶|Ó*e¿ï#>k0…¢{â?P£ùÀÇ?Ìøãë¨Lë{.\„+—FùyXìB­ÁÆ›òÄ·ìˆàaWç§Q.eÐ6.‰óf#‹í'=èÂϵ1j60%aïŒôÌtkÙ¾«`|RxOqÕx—6þß.jdü¥Œk˜z¡Uw—ŸPä+”«¤n­”<~ó« ŸÚy£;4‘­kôÈ…ð)yëdŠÎÁ:øã´lt×µ¨Qxoð¹—EŸBTEEQïx/ÊŠÎx¢¬xèì]!³'ç®áñã¯nRó ŒŠ– «•ïZКZ‡t¾ŽÀîeZk­¨UáA_k¿¯ÐXéûÆcí:jµçѵªŒuëÜ„õä9il‰jm‘ oT( hÍÒ#ºÏkÿ9Rc_¨°¿¹ÜxëF)Ô:¶•eÞ»ùJÏd¬ö–÷­öÅUvä[lô¬n]×ÈÖ«}PšU@­2v2/rË«_-xÇ;4W—YÍe[ýöì¬â§~jÿ&Bnú×fÌÏϳ¶¶¶áóï|ç;yüñÇÿ»ÝZÇúzTÚò:´¯E_¹²Î§>u”{îyšÅÅ~xUœíà ˜€Xޏ ¤”!ƒ5©HûΞ­˜›3á]îÓ(Û?¶êÖÖë5bAxû¤ß>0ÿëuþÛLCga¼»îµ·k½M—Ëì/ÎðÓ3ÿÕ5¼þ?Ñç vlVÎÁùÇu!XµÐ­¡*uN;Œ«.x’#üv+ &‹Ð®wâÞ 3YRt ó‘ ì`a½9‰³"º€.¬@U j‡ ]xãJøD†Rÿÿì½y´d×]ßûÙÃ9Uwê{{ÔÝêÖh –dYeÙÂÂŒÍä8q€¼,œ</!àÇbJVÂJ ÎÊKï…$òÆ Øa°Á Dzñ [ÖdYóÐ-õ<Þ±Î9{ï÷Çoï}NÕ­Û’Ì3x¨½Vu:çTÕ骺û»¿ß÷÷ý*毦5¥Zßo-éi¥¥þ¬Œï”*BîöËéx¿>¨'ô²þ¤v¬”Ó,÷…öɯ汭—¢T`ÑÎåTp*§ÞSú=Eò‰tfµ˜£˜ €n¼Ë@n½0Ïm! ß+X-ûzýAŽÚË~…Òåz†³+ ™€÷?>öN.o#h¨±, f­Á‰Ö±ÌÑ[÷FQ›"³Î›¢äk[ÒC]”ÔeÙ‘nµÙè„HˆÍuiŒªmÏõuí¼d¢EjneSšAÑ“,ÉRÀ?ÛÄ“‚‡wÞÓ©7‚s§VGZÍ6òÒ®ik£Ø½{†«®ÚŠ6D‚X$~E2˜k|»íð>õ©OmxüÙgŸýÿå}ǾpŒG91:˪ZkèõDfõàÁÍ¼á —pèÐyÆÛÖASÞÒZ33SÐëY¬5…FkM¯g)Kavоº¼§àt–5”kyÃãÇW¸ï¾ã|ö³§yØÍp”~\WøÇ7µk èl 9¥XR³ìÛò4—nyœëÕ=¼£ùUú'ÖØÿ{OK;Òh†J+WœL±ÖÓBz+¡)ºØq˲^ÐŒ€»7÷à#D´nT>ÊVWc‚Ь’Ö1¤ÒÝÖÛ è œÈuj')KÓ(LPw.0hÀ×à›€»{‘¢ Ssp‹&,Xš%ÚÄžpëò½)D¾TÛøAØÞÚ£Uêóçñ™+L+Y¸~çÙÿA8+‘ûíûnãäÔ6PðÉ-¯`Júëz„HçcÞylZºq¢§^èZÀ½¨…X§J*¬o°¾¡× 0ÎQêŠ"Ô’)Ð zÒ´â[ßø‘\_?qvñ™W€†Æž||çÎÍŠ®g“ðKÛB&5xyg4µUR¢±žºðxh 3ò¥Ú`Ò¹hL>ú›»5וo`*„lÁšRùbø7öï_9\#¯ü§Ou~¬·g£þùzpñ>Pš«®ÚÊÞ°K/]À5tD?=—mzMÓÊ“&)ÕV”¨©.Ûuí†ö§×Iž4Ø›ÆSU]x ë>TÒs’>|WÒUXè©ÞlX|ŽÇ²Ï{ÏOœ£(ÌÐgꜼo]ûü™T•Z„„@–ÇÞ¹sšW¾r/Û¶}ãõÇORî_'ã©Óï{÷ ++5(Å!¦8©Ê6Àhb@f¹WÝø)®Ø÷(Í<ÃÛŽ¿ŸÝGްåäi‰ú>çàÓžµEÍà°€øZOÓ”0(®€º Ô…‚Â㠉ʱgAiÐCt:µè.›Üx”¯ ZÃúôµêÌ-:FnÁ ˆ{¯ÑM"!iLÓFí¦ Ðhld£«FQ4Ó(l(ꀭ¡WzµGMYØTPxǹËXÙ7ݺ%· ìi;‚½¶> ÀèÂgÙ â[ÿ…–5žTtàÞM×áŒa`züß{~$ƒ”¦@±ªA7^,LùU«£itãäË¢À/‰æq”½*Û¦% t[Iµp4¹ÏÛYÃ3Ïìfqy&åž~x~â2‚JìrbJ>¦écª=h15‘:½Š&*z¨¦>ìfÓY%uÕ‰ºò«ñ¦²1¢ãÜÓ®&=ëÛ¯»S‡ô¢s'óšƒðc¯à±V³cÇô:ÙçɘŒ  ƒú¡#ðè“ Iœ}à/àÝÜfóS¦0K•™xÓm1wfÿ Ó[W¹ôÆ'yñMríÚýXßð¶Ãï§TׄEEùgÜÞij4«…¡±âUOá‹À ”{_ê”v¬œòPÚ ˆë¨J×%Ÿ1ìGΈ7y·Ì¬ç Ø6è©dIÛ¿žŽIÛ—™‚€î§ N¡#È«L£Nc\@7*º,l(š€n4eíéÕ’ž/OáDðBk‰~¾xÕÖ­<+Û§Á’ܘè2AÝöÄBÔ– ¦'}á¶× EõJ‡a-¡´‹`žØâuSàƒ0Á“þo¥•*Å“\;>6{+6ýÍ(Oé‹9Û,d×h©ÛF[Ó‚|¡j´óB–S1Mß«0Á呼å IDATVEí}Ö?ï2ŃR„…F‡´îÞH«[­ ÑX·†•å)îúåÅxX:6Åê©BRöÆLÈr®m‹Û˜)KuD]³ûÕ¶!ÒF§ýN˃S%·Ž‚[èÔ³ý¨L{YFA¡†Á?ßOæ)Öÿ¨^ó² (MÆ7`Êýëqœ<x×»$ ×ç€~RŽ9so"` {aIO4É´ÏôË<ó7(ê»®;Íö]g¸A}›ÖîâÖ•ÑÔ–fÍboo0ŸvøSš*”4 QúÓ*Vãm î)šR´cñ‹«`AG åë “pã¦au¤ì0—G¨v?ô^ÜÎÍ£uõ'ÑàÄ5K5Šëª£våÐuPNC#D:ï4¾×|£ÑµGÕB¦ ¤"%é+,ë-ÏœF?+à~êÀVB)½ÖO]v±è•ñÕÖJ8 !ª]ÈbmÛö"Ë<‚}’pM}Ö^Â.Mc³¨KÓXÉ€Dö$Ló ýinæhãùTñJõ÷auÃûÖÞÎÑjWëxæ£šŠ¼ ïšü(ƒÔÝS¯w" ¥”vЭÈKÚN`žZà†dXQYcýê¿w˜ºRÜÉûç8÷Ät|g çî´¬ÜÓtDêýx…¡qz#C¬¯ïÐ!m¨Pç~FZZjåðð›®Tk[[w>:¶¹Žv{LO}×ÛCËŒ'å"nªÿðïtª]„–Á>7ÿüŸ—“ s2&€~ÁJO¬¬4œ?? ®ý0à ŸÛî{ó›Æûqþ䊪Ò<òíÄ¥Fr°ª“b´Mu' ®lÒ°`€@ÿïÌ1ý*ËôtÍÞùcÌVK|÷ÂxéÔçØ´zžé3+,?4Ãæ?>C½ZàŽ*SÒl1  ¡8𤋮bõ±%'¼Íy×ÓâØþ+kjLUmèS;.·¡}÷€º£ÝW¼ÔÖø\ ~^&@ŸÝ)|4¿P”7¨&í×èüF†h4ºøFE@÷à´h«=ۣȋ"0½²‚^“Þð+~£õTÁC_‰n<:xj_d¶¹vž‰†­k@+RÛ©ñå«2zƒ¢©^7ÎQpkä;«]‘åW“j[r+»Ì>Ê‹ì—ÐÚsÍÜ4F¤[Ÿäÿ(ÞËBàL³™º.ЃDí'‹'d³Ì(GHg:H´®Ïʵ".CZëÉ5DûR­2û܃š7̾\°°±Šº4˜+ Ó«…€¾µT8êwzèOP <úl=ôk dÆXÄïÐnwÃæ®ÐA]f†‘t~'ú÷YT¾='ë¬ëÈ’O oÖ3ã»*IH¿ú¿û…¡ ©s -)ÎZøíßVlL4c]}àºë¦ø…_Ø÷\3à—3kþ%ö%Ûf…1bý,¶§Xš¤Ü¿Ì”»sG=ÃOœáüùŠûî;ÁG?úÏ<#2«Öúýk JiŒ1(eÐÚròäO=uç`¼Ù…n닦ÖjŠÂb­ÎÞä¢ê&ä7=Ò•Rh Ji¿fgûŸ¹y |ë.´÷L¯¬ðM;þ'3j™ïÙõ{ì:LðŠwcӽ百{…ª.[SŽÝ…óóÌ N)üÑ5ܳËyÞJsžrcÜÆL)ê9þ¤Õ ü| ]¥73œ~×;Á‹Fyhöhª+ ”)Ñu°koÑ1Ý.5vð±IÞ4r®©%õNc(/ÀÞ@éÞéÜ‚Ê,ò$ɪhÝÒ´òÒ.¦EÅmezšC ûð=ͳ3{¬{ Úx‰Ì˘¦ïK”nKvS8tÏ£{âîîô€·ŠmM ¹GgûSȲšØ?§tBGÔ%õw|èÔ›xdérTÔMÁÇŸ½%gŒsÒ6Ö¸ÜcxÚDÇÅÞðàs*^y©»dÛY±Q¢uoLThKniQ†UÚÛ,UY¶„¶¸Èµ­1ýþ“t%ICX°c¥Î$+!zErYÔ ÷!²¼UK&K¬p bÞËù¡ë­=B: ¾%²ßß¼ïZ‡¾D“k ™à&$¹qËÜ x®^ˆŸKUnÛ¶MqÅ[˜-2Ñ,]“ÜûxÍ]_q?Ä”bÃ{G²:‹´¯û<¥ÀE¿o˜š²ìÞ=ËÍ7ïåÆwqàÀ<,P“úI„þBV4 ¦§-›7O1;[²oß&ÞüæË2Œ£(K›Á5±TµVœ=;àØ±åiÄSÃCkYîIÒ5­`“\«1šp'_Ó(­àÀæ¡Z´¹ßñƒ·ý2Æ9®ß~=3 ñ–ýð4uS0ûÐ~ 9³i3•+eB= [>v§nÍ¡O®I«YúñÚ¢{˜i$óß%o8¥h”ÂÅ›´ErT§%Muþ ±¼²&Ž o&iEJ€ÞéýN=í!°ê „ß'3¶ü~©}/~SÉòËJ¼3¯QÆyrZ€;:XùFácO#¼j 4R‹÷ R¯¦Uu3ʵ‚'± ¯•ÏiïB×à [³¿~Z<­Õ9¬i8çæy°¸JHhM#úì1R7…ÃVRc7¥€:†!·`T«ÊfL{EUœµ6ÑiÚÒ§ßUj¸rëC\±õa*_²{áGÏíäÜûTl Lâ.Æ9iKb/Ý>¸' ÑÞg0O¤:åC–QQ.ÕÊsj>ʰ¦H>{£w®»¡Ïù7í]‡[§×j¨Üp»S€wß Ûû­¤jœºçz?Ì.ï¶n%–y´´ÝÝŸžÛ#Æ ûËFÆ_V^’ùùûömbjªtß]œä}t?ÐÕïžÛeÛw¯µ=gý¾îç35e™š*&,“ý…Gè_ãîÇáÔbKéþàðË‘r‹Ðø¶ØÛ4`ËÁÓlZ8Ï·~÷K]×fïÒa6-žçŸù«ƒ)«=jWP/L?³‚höÿÎÓ­SâÖØ‰†µKncR‹>±æ¥ M£¤ŠÜhSšFG0G€¼( вˆ%IÕ)]ªNN"ö GýmÝ{lˆá>Pñ·Áañ¿ò[ðànHÕí÷> OžLÍÖÑÌÙL’)¶Ôìÿ§ÑÁ3³g™}/;„R'8È›Î|ˆkN=ÀUGdyu†cS;YUS”g*¶Þ{ µØzß)yó­"0§ã䥜['ÏtW|I?Jñ"J•È×°vR«×> ¾$­u¥eQIÔn¥ÿ[kO¯PØš-Åiz½¥­øö]D¯7`qmŽ?øÂ[P*0hz, Ä”$EÝ)ŠõJgÝõ®x×TÅC]ë¶ã=ìLæGûÇ7¨àu»CÄáDž2Rq­þº¤³[½uã Þ³e{XÙ½…†€‰€n”kÛ®b ˜ÑÒ~e´˜Œ%Àn­Òl!Ñ|×!=ò3ü–+ ^S%O_¾ß«<ùìÝ£õÆÛœFÚ“L«RÂÖ”ô|GûÓ²¨òu÷z"ÃÚ/×è÷Ö(u%ÿ7ëxöÄîúÒM>¾—gž½(zÒ0O©êµg75­ðÆP"…šg^kšÒæ¶±ºWäH¾. êBHiú…¤ìQ/Úê’N½õä—ÜËŠFGà q¿ü4œ¬†ûÄÿô,Ö±—Îß…gØÈ$='µ•%MÇGeZƒV.Ê_ú8Ú¨q@ü§:A§uÎXÅÂ|ëÇB” øä‰îÃP­}ý{ucª{Äųi“æßü›Ë.PS¸Ðãèá9®‰ ¤>dôû†éi;ÂRoÏ›-¸ôÒÍ<¸0AÞI„þå¹¹Û·OSמ#G–¸óΧùØÇžfq±¢×+°¶ÕT/ ËÜ\/J­ŠBäW‹ÂbŒ0Ì{=Û!Êi¶nռ㛹ãާyì±³c€¿³p;™tÎýßn…m3ú·n‰&Oóx 66=É÷^ü^úz›Ê» ÀcþRjWpÃ_`÷òž9K¹\±ú4¬<.À½tÖ| âÅ6IhÛt½~^½äu‚0cWˆÃëݹPøSt]…ÖŒ­eßìàÆ)ÐO^wCtí}ŽÎuð¹̨ w¼Á­•íÂDÝòòIftmwÕ½Iô[v;FŠ[·s÷u/Áy“Ùó ä çzsŒ ]0ÙD%Û£F+Qc¢[šmr&¡,ªœ¢/ Qjëë5zj@éEàÅ4µ9pÝ«ïࢳÏpò̶øÝiþð½of­îç…Š71…®Ú¨ÝC}¾˜'@÷1º¯ ‹·P—eLÛkêÒàLÀ¦Px­¨•í€k¬“ óG\dÝgœ¸õâõ]W7ÁŠÆ“ÿü18½<ìRÆhº¨û÷¥Æ¤ßGñ¶v¯Ë;¦yÃ.áU¯Ú†1JtØ—õÞ'Æxˆ2­dö¸l‡Î"@ˆÎBHÇ]–su‘-ÇÏÄE‚§®»r­.³ÓëÚ °sªjòù‰Ø'²ªM‡¬²Œjb¸Cà†vòÆ7äÊ+·ŒeŸ—¥Žó¥¦ªƒ‹×ÐŽ••š••z¢œ7‰Ð¿¼}”×e±nø¡Œý{¿0åòù~Œ'—àsO·/ù³Ÿ„Ïžˆk «Úü´lÛy’ùùs¼dÿÝ|ÓåwäÖ!ûÎà¶?¿žuRºnƒãb_Z•DyÖyì£yTn5c¢q=ä#Á#ô‘|7¸É&TÖ·äH–#õh—|Åm%ÛE¶RØÖ¦æyèÚk18Ö¦û,ÎÍeU3C”] .׫­j½°µ€»n°e#.cÑB´(å^™ Xº>(ÅÒô,·¿ô6¼×,Ú9ž™½H@>¼×4NÚÇR­hA^‘ûœ߹‰fê)ZHj¾´Úyz倞ˆè‹‘ñ®mht‰ìqεõCîãî?}‰øŒkÍÉǶQ/¹æ”˜§HP›TÙ6¡cÞ$[W|ÓlÙy–Kö=ÁžíG)« E`Wu”W.~о[ãÚc÷ÃG <«àAð‡D[½*Á—"ÇÚ”àŒl»hcêlœ mGÍ2¶¨ù.ˆwû½Ç(qmبÖGì9&òm:^EwÕ±‘ΑºÑz¼·µl'@7 ”0µ\ÜùM›8¶}'Ë33<¼ÿ IÃ×JšªNԎܶÆà2€[#îbEQ· ß«Eà¥#ß:NbàÌÔfÚ~%ÅC³Wr÷üK²È‹ &yª»§>yŠÚ}ô¸ÑN߬£ F¹@¿X£ðâŒfu“Ûźªm’ñRKd]jýrVÈnO|ê «ç§pư||†'~ç ^u…_ä‹°x{ƵoÔ´Ï®ií—ì;¿ÈF\çK§•¢«Ÿ>*ɪ†íBCø»ui5V[Eø‘׳¡1Ø®-ðÓß?€É˜úWåX\\äèÑ£ùñ[ßúVî»ï¾¯ ?öXêköøü¯ïßýp§&k'ÏÙ•6ˆ¢[”dÍ2­*Pðè¸ê‡Ø4³Äܦ%¦Ã*[Âifô27¹»xºƒòpŦæ<ö¿4„³ Z£*éãU*àÊ@]…£éEOrhÊ6÷&sseTÄ”ãÓÓ³³E&Âi­Ø´©dv¶Ì²­×_¿“Í›'­t@ÿ ú¯üÊçÒK_ÇG?ú  ‚,4r0Óï阉‚/ºQPiš¦ xisqÕâœÉ rïEøEÅ(Ëh—•Ú¬mX3}>4ý& ŽÇ¸TÒðÞåÔ»A=3äcÔn{ å””S©+P½ ‘zìõîö|{eK•nÚb–ÅGÁ”Ïž¸ž;¾œÆ8myèäA*_Tj9èºu[·$Ŭ\’d çQ^¶µu \w©ú¤Ê ɰvÍSèWE«Ÿžî7ÄŸ8^aßS6CÒ§Þ^ºvL3$3:*9šØÜ&Êû à3$‘Ú}ÍVc<¬#¨vß?é§'S­ÕÐóººê©ÅÌ9OÓ›\®Ãý‡…Q+M»]U.J¤¶×QUÂü–ë¾NïƒA3t|f¦à–[öqóÍû¸üòÍ™|7$e‡°è…ÝžÞ7ɲv¯w£}ÎyÖÖº,x:Ì{¸æšíÐþ*_÷mkÓÓ–[oÝÏ­·îÿоÏ;ßM ¬Âý§àc‡Ç'¶ì<Í 7Ùb‰›®º çª{Ä5†_z’°¬8;¿@í‹,N✴=eÃ'Û’§°²@Ð…# ](ô3þ‡b*ZéˆÁQO=Ƚw ûðÙŽYe)V¥@m÷Ê5Û³Þz ¥UŒ~Ùß¶ÔÃHò"Œ€9cÚáRÚ¿Û¢ŸÄò´bïºj®2"ÏêU¶ ^ÇÒ›eÝu†u×qYÜåMöC¶æ.n¢05z|tõõ–ŽÂ×QжÉmqu~\ú SEñšRÄkº>àYj5)´E½õd<Ò›eZwl?Ëwmÿ³ ôŸî_ÇšëP;¾…¾xuî^ûÄaÎyMÝM;{5Ø É(»h>ƒŠ<6våCVbS!  xÔÚ.èlÚ>Ìð÷àÛJgÚèxÑ.ø‡¯›LÊ“1@ÿ ާàô¹VdâÞÇ?ó+1£¦ÇOÑêOwôbìÖ»àØý²#\ö¦G™·ç¸dúqæçø_îþïTUÉô™ª¦äüô&¶'Â$±›ú—­–H¼\©°u“_ß<å˜ùÃåé)BÐÔkÓ„3*3¨Sÿ±’^))niË9Á˜ÿ›õY¢QJÝŒ$°´­‚øuß-5k5ÖÕNpoÓr®’çømz˜D–NÝi SáfœÒÃ)ûà4*(Bt×H‹XÝ"ô·“Îz–i ÑY-~–É,¶»q\ª“1ë¹D?NYV¼ûÉÿ•PJŸù‰j»Ø‰¯±U¬±{©»+P…hÒgãÐ 6Öfõ¶$ɚٚ©³9cغoǯ4 ûÖØ{ÕéìÄ~ïìáü±) _CuB3ÜîÕWAR÷©¦ì:d²`†äAjÉÊKä*Ùdåç;é—!âÃ>ãã²ÎìõÝŰ_yLÿL•žÿðî2ÆŠ·¼Jñ¾c4ÍÓ=WQppÿdΚŒIÊýë2åþBHqÏ<ãyÿû«˜ë ¹þ‡·{nÿ ŸìÀÈBáÎÊMÇýJØëæèÝ0ªaþç˜Ùy _s›¿›Vïâ[Îü ++Ó¬¬LÓ4–ÕÁ”ˆ’8CÓXŒv¸ mM½Á€í_8‘[œ6Ý{žÞãi‡ &Ûžº[£‚Dª!H”ä”®ðƒ¨·îgÝÀKu=Þ'@rï´NËÕдòØv8r¬½¡.ã~ë\ÒÃoÓhëåVÄ[éP6øÛt“‚zjó¡ªKšÆR»Bl`¡qâîƒô'™ÖÆÙ,ÓZ»"§ÞCP¦– €òèZ¬L{åkú½5j]ð‘§ÞHQÔœ]Yà GnÈu÷¢W‹]hZ¬D@ÏiPcr;X×"ÔI½g‹Ð"FíFgéÕºm€]_ IDAT(¨Š²•bzë±C)ûµS†£h3z4ƒß?G$’D»ðl}¼É©úv [öd7µº²Ž «ëH ºÙ,Œj±Ó $Oðt Y:0* A§õ!I¯Ž°0ý˜ÅD$½íØ¢ù™éx—_Ða4ðÖ·öØ·obÑ9@ÿšô÷¼ç7¸þú7óã?þPƤÄx¢Û™3ðÙϺ «¶¨Û%ÂåÉÉÈ9eÔ ÿÞyÌ›¦Ñû ¸"dŸ›úgìQÏrYõ(j1PU%k«}Ö}‚W êžLú¤5­n¸ñýŸ—”ûfž\¦ñ–ÆÛ,9ê¼ø_'¢\R!óq2MýÎí©·:j]³У[­í¦R#Qz¬Sk|Ö(×JäU“4«V¢¿n´´ùµI<Ä™…ã¯Ù!~à=‡*‚€ÏaJñWeŒÞ­ôV×¾ i,US ¸;›yÎ˨q6Gíéó©]!æ-3ÞšFº”¸¡¥r?ºÒ~o^O´Õ§ú«T¡ä©Ssnyž÷þù÷ŠÂ[ìýÖø è™QëÑÉ-[„j²äjvK³BL«Ë"J¯Ú­×e!F*…¥ê•™‰ž@?D—D lîZÁ×HÉ%¿ö|ît ð9šÃ6jiÕ9ÕNô?ÔûèL 蹕¬«Å®Ûv2ºÑ{ÇÝ'/0ý˜VŠŽ¶p€ñ¤05’E#€Þ¦nºÉ²e‹ó½v÷Þ5ÐðÞ÷ÞÄÂÂ_§úÙó™Æzƒµ‹š¨ÅLýkÐáï/çBíÆ˜ìAnŒŽþ㣾äÉ“\S÷KNo›0¿yü­`È:Ü×m»ïÚûSYÃ`PõX\š#xÅÚZï4;OÃ,:oÿ<æœpr%µpª]1¤@–"ñ,Rû—3 #Ìo`Ø3¦ÝQAâë]ö.ƒ=Í­’ïÔÌÃ\pO‘z² M s£$"N`ž„_ÀFtÌ Sã6Ž_»[643–ÁB´-„E®Ê àVû€kCí êPЛ?Gí^S»B˜ñª%Ïiåi¼Í×냦(Äá  ß[“k-š¼óù{=|t/ýÌëQΞçÄÉí('*niq”´Ñ--‚¼3ÂÎOúê!(ê¢ÈÇ„í®hJ› Vª²”ÞTQ’5÷™Š%Ü %¶$ þ¾‡àžãCxµõüS«ƒuøç}ÆÏäîGHä^ ᪣<ÙW<­°äùm˜8æ\K[/g´˜oraìëÌÏ—ìÙ3ËË_¾èËZœsIÊuغ׆|ÕÓu­÷ünI|éøz‚œï¼ëéÊR³cÇ4e©¹+ÞÅ¥—.ðÚ×îga¡YìrŽÖŠؽ{v‚ˆ@ÿêôw¼ã_sÓMߺáŠU~ìÂj7F=zº×Zñ ŸÐ<»*¤³j®Ï‘};¢Ò›¼ÌŽÍǹõú;˜Ö+¼ö¢?Ï5ÔîÄ?¨z¬®Mqõ3_dÏ¡gijËÞ'Sœ©©\)ÑfS⼡ruîù䳨U'uoÄs\R­m´"ðuî)MÕ±¨LAÏÙ­ <~ÕÁ º¨Ðú¡V3IÖú l)r7´¦#Z·iøT¯N`®utK‹)ùÂÔÒ6fDÁ­Ð!»9ÃÊÖiŠ^Í™…Íœ]X-ië`TõT£vV㋘šV–F[jUÐ`3 {¯sÍ=-Q£¹÷¢ÐP(- 4”ÔÚ˲êt'†ÖÛÝKªÇíà𡽙„ø©?zƒ¥žðÒd¯T–mM‘uê HÔ®y¡´ngZËöP[™½fŒË¨ @Ü¡#¸¢ÀÁž“g˜]Z%tAÙÃÁùÀ;_1 *-ðvh=Ó<·¢¹ás“~y ‚dvyË$dõeF§G­Û¶MqÙe›¹ì²-è†ëÿÏÞÓôv12Ê>O úÑϪ»(ý ÓgÂÆÿ¿ôzSS–ýû7¢LÆпÁkè‡Ãâr ZrüâGˆ oðìJ ÊþÉÐ[¨èÏ­qðʧ¸éæÏÓSæfQ>äº(À‚;ËL½LðŠÛ¾t;;ŽÇ,9Ôù@8&)àª)™ÿÜ96=z>²ÐÓ¤¢(–+‚ ÃΣ*™qW#¦ª#ƒ™û˜;š^ýÞМqlçNî»þZ‰" 7¶`yj&ƒÞ «¼œh“ûŠ!@O)n«›ü89‹-*m—£ô$òRšŠÂª2 ûž¢WóØô¥œêmEéÀY¨MŒbc Ú…‹:äCd3#V MaEÌ%HÙ¢ÁÐY‹]iiyK}þhžb|þÿ§ì€­› ÖÆ¹üý`qqK$·ÿâ7ççÖç ÖÎõ3»<)º%ßq‚ÔÉ#à§ú{ªÅ‡ ¢¹Î:î! ¸@¬G§íÐñ žk†[ FõÕsúvM«6º÷íbà—þ.ܾq@ü¢Lô¿'c2þ Æ7ì²î?þ—À ´(½ýú‡<÷< ôÄCë]nZ­Òͯ[df×€½7á¢+Ž ƒg©™eQÍq|°ƒ Ûãæêì^=Âõ§ïáÒ±¶Ò§”Lr×Â’bë'Nu¢)`v}æc+Wº¥Qwâ•–ºê µÐj¥«ÖÞåÁ‡ +CïwÉÚ\òé'†®ãÔÂV>pE~üо+9?µ)÷{w=GèñR>z:–£ö¤µT¸—¶¢P’Šïb!ZªŠ’ŠÝõOP_¬¯fM÷ÑÖóé#/Ç+“=2˜;«ÅîÓD{ÐÂà “m@k[JDo mpʶm[±çÈDÃntnx³'qùÌÅJ4IlLqãÏ|>×Íß¿ƒ£ŸÙ•ðÇgnI·\0bÊÞG Ö¨µžx@6T „(ÇÚQaKŠ<É„>ýTÇ”ÎÊÏüö-© X š'‡h­´ê·¶«¯N[[ÇßõF³^` :7øßÿñø'c2&ú"ôk¯ýOìÜùV¤ÈmR¯w|ÒÓ(')ó²ƒí¡èâPP…Ÿ3Lí¨Ø¼ï<Ó³kMqo#ª'iÓŸê¿‹mî$/=Eïì€Þ'ôï[ËÓO®\(û¿n_Vx±z"³©ŽX- g#”‘h=º ϑɗ٠plóN…Dö§g¶ð‘kÞ( ‡Ç)‰*“R["É%ðÅíò>«„Xfm“û» Sc€/‹ Ê^%@ojzSʲ¢ìUô§×(ú5G»°=Ç’Ÿå·?ý¶ìÖh‹·š:š‰¸Âà ‹³R¯–¨½hÁ½(©Š‚ÆF T+Ç’$kô ¹­D†Õ6M–aµu$ËÆùÈÓ¹^ž>§ºTú™{¨|g «w[–ÿ#Ã)™55äí­‚¡°–¦ŽéÝìE%Xö¨Íò{²º&õtåY}T?°#Ú"ü®¡ŠïüX“îz²ñó]]õ‘í9îõ·&@c«6æñEÞýîíø±¾°Qz² ˜Œ  ÿuŒÏ}îs>|xÃã?ñ?Á#<üS”º km¬¼¬ê¶ÉÙ„N³³†—n‡™‚FÿêEL7«ô«5lÓÐ F¡ƒ§(j^²ån‚Rüëÿ„Ù#KØ£ ®2lúØyÊCÕ0‘L‡ñœµñüˆ­Â +TŽõ&ïJ®Žb]3¬µ?ÏEÅ( §‘˜ã*„ÌøÄþ›ybËAGç/c­è·QnŠÚñ(A>Fç:HÞ8—Ý8©¯—J½(c}]  º¦ìUôú‘…>³JÙ—^rUH©äé³û¸ýs·ââÄò6ŽÜ&5v« †Ì"w…Ф'\@½él×¶ *z ÊMQ0(û8[ˆêZã# »¨¯î)ªZ¶7,Ãê=N›¬ÔÖ‹ò!¿wÒR¯m‘­L]­à‡Ÿê¿dßß6·‰¦x×úk{¢B™ÏþØM#ž×Uå3Ñ+‘½ù«®>J¶†à䞀¬79&D­å½Q¾•(ùšp²?8äÞ .$]$É­÷.©U6ØÞè±g|cü¸ýž_ù•ض­|‹‚ð<÷‡çùÜçÖTžŸï³wï»vÍ0;[NPl2¾öSîçÏŸçØ±c¯ë€¿ñ7æ¹á†”¥A)ͽ÷çSŸz–G=Mèƒn».Ù%sÊ7ïÍ¥l?êñÍ*SèàYaš ÇøŽK~Ÿ)µÊ7oþ3ößÿ4³_Xbêð*½£ƒœŽmöØÜóŒ¢ô¼£€êÛt|J­«. o¸Lɨ2²­:©ÎÀ\mèÂV}o!À+«OñŠ#ŸF+ϽÍu,—R{ÿÍ}›Ú9j'ªÖií3ÐY-®UQ•ÍI}½1 #õB×ô”xƒ—¾¢çØÐЯ×(C% õ‚(Ç ¯¿åÏñFsäì.ž>rµ<ø¥ËxúÉÝ4E7 o u!Â/uYÐD›Ðº08 TEÀÙg¾¬ ÚI¤‘ …=hP.D9Ö}ß[éUã$C!^&±• rÔž¼Ë)Ž?8ô»yÚÃgãw…c~ô€æâ©€÷&“±¼OòBÀjeN’˃ŠD«ËÏëʨzï†Èa-ë»%µ¯Í‹¼K²&Ö%é×´H‘÷BkûÃM×1üœ°Žxöá?¾î5GŸS×>/˜z=Í‹^´•«¯Þ6ôž^„¼cë÷;ز¥¿Žd8“ñuŸrÿõ_ÿ Þþv!Å5>ÿXÍÊJMÝx~í^ø­ã6MA_úƒÛöô@ѫٲù ÓS+|ïÞK¿Ycßò!ôY^~÷g˜Z^Å,;¨c­3*‘%…´Lþ2®ma Ïão:î  êy,âÕ¸/y8šWã£q€®ÖN)Õœ4æ“]ÒRÏÎgª%bií9[. L`PôøÅ½? ÀšîsÌîÌ"FI4kþ}ÓH„ny\•ìKix/iøÂÔª¦?½&é{íE†Žj›Š©öH*[®§Yó}jkùìŸ^ñg·IêÝΞžrŽ)q[ÈŠ2ïkb;™Hëªõšïê®K^B: ¢Ž‹Ñv£ZŽCª‘#ÏIf.ëêÎãÛK(ÕðñÙ~ë­ã3{·ÀÂôúÔóº`ø\Ï ÏaA:îø8–÷FïÓe˜ç²Ó_;<ë]ÿ¹¤ÅF÷}z=ËÔÔ„e>“ý+>>üŠ#Å–ð/?X‚.×kˉD"#$¸ù‹ì¹á[7Ÿä%7ÝÃüÚ9^sêNÂ@ñê§>‰o¤¯¹ž*X+û¹ç:1¢• ¶&i"¹«úç‘)´“|kΪñUWÔP¾]Ü”Äí5\¼7ô‘²€wZnÑé,õu{ý½AТ²œ Âïé?{î_`Œãto Ø{3Æ:žÒóiý qÃe[ЂhŽâ›¶o=FíÖ‹há„ß×k/mqʈIVmS±Õ iuË2¬ÞpÕm‡¸Ü¡)-çÖæøÒŸîÇYCe N<0ÇÒcÎÓ[ÆE2¸^)¥2Nèdòj,êí…ŽàŠýuÙ§³ôê(Kè´3d»Ï‘÷ pbÝïFn7Ü1æ÷¥ào¿^²ÜâRñšàU/~ÞqÁd&ŒÉ˜Dè_ù­¿s«ÍW+„g!À=‡ê{z—Vìý‘sL7Ëlž>Ë®mǹ¤~œ·û÷áW5{W³6è㼃8o0F¬M Sg¹Ó¢¨EJ´¨„襛6Bwˆ¸TGˆ#4JÀ±Ñ'®wÃÛ^éý¦Hxl¤žSô!k©£@©[wõÔÓ¶6>Ë­æóRy k°ÚvºÆI_·w"v“ošÆæô{ãÚõbú¬R­ÝѦ7VìJÏÙyž).¢´vßÆí«·a'ÿß !˱ ÍêÞQØë %ím¶nòÿ[;O0*G¿ÞèÜæc»Wj1L’«IW½*Jª¢äÜÉiVû Š’5Õçð?¡ñZØu½ßtTWºE€ëîëËB‡—÷E2™ññjØçÛuÔØÒóÇe†-;2„Ö<(^¸x7à “®*œW¼ø*Å»þå sk¡(& €É˜Œ  9€Î/Añn㡨…ê½UÁÍs ýW*æß®™^]á*ÿ õÜh?Ï·ôÿ„¦¶¬®NQU%ÞiêºhM>”Ç©‘÷ì ÛrN[¥xMH^Ú¡ô^ãÁ?ªQhû¹ó}hUÅr”­ZÑ–³7.0ØÚë°×»i¿À¹­ó¤Ò¾l¤¢7ñø8ë©›¨§ïM! m¦çÐ¥ìS:àMõÆÛ|ß46ß'á–ä|æ¼ÉÑzR²ÓÊãÑ#ªq((ËJ¼ÈmC¿¿FYTüÚ©¿Ë½‹×¡½ç go`um K¬µ;©µÛF½ ‚šòB´s^÷±Þ´Â4NÜÏR¯war+X]  Ž¬v¯E•-K®–%ƒ^ª,Y+û¬~¼¦úà"^G°^là/Î2Ô3ˆ@@úrýH ¥£ôåÕp¤Ÿ½o–YõÈ=t™ãc@>owt×C‡¹ÞEzÕ²á[Æ;#=ìÆ{­mtó¼ñSüÐmÚ0õþÂÀqóÍÛØ¹sj2›OÆпþý'A¿N&Ñ™~ìÅ`l·pÛñ&_Yæ»¶}+¦æEý/qÉÔã4µ¥©m–i͆'^ç~jk¶>ÅÎ{Ž EÈűšâ‘:·ª%6xÒï: åH½ãMÝô Î#F(Ù$%j¦ŸÝ½@°*«´iíy|×%¢:¦Ûó•iï3¨ñ9Æc¬“cEkšbznÈ@E™kÌ:ß;¤Ë£q* ¶DƒçôZ{ÜNRªA)Ê¢B週Ž~oM²EÏÇÏÜÂb5‡ÆóËþ ¡QX£v$ý®ëhãÚûÜZ–Aºñ9RÏQ{vI4l1­xLÑWý2³Ð½^¶B­­8¼q¦œj¸èƒO¡–ª!µ¦ñÔò˜¤-ç…©>ò:Ð.P ösºªCÙ¤eDçüyK¥^ Ýaìù£ÇýØswïžáÀyêºÉ»ÄÖu¹–L—äÚ›£i¼á »Øµ«¿ŽÄ6þº¸Àb!<ǹ=GZÞöì™ÅÄsžÁ@¼ÏÓy }^úÒ]Üxã.¶n,@&cè/Ðßú÷þ#ô¢`­§À(ØÒ»¶E©ÀÜðߨ5s”9»H©«œvµ¸–)u]°uñÖ‰mé-ôq|%öœ @-‡…vм׿íqÑù¸=]Oõ¤º–ú»€'½ôlˆbMi³¼ªÕ OÍ\ÌÉ©m™¤ç´aYÍH›WŒÚÓ¶)\NÅ›žËÇtáA‹bY2IÄ3o´h¬' 7:Ë—:côãçãÏ ÕÉh-ÿ7cÖ6CŸSúÒ¾Sƒ­, fù¯wý=Œw4«–³§„d×´B/Ú‰iŠ´”IÚ_älCŽà½Ò1pî0Îõ¹džR[aŸ ^öצȪ€ë07@±XCÒív@?µe‘Ù €žÚ¸Jå¹|k˦†ÔòÕ²®“þy>ÛÆHc>à¢l«°»‡ȇ€‹À×e§·ëƒ0Bí¾Ñ×–1­*·ŽI>z¼+ç:3SpóÍ{yÅ+ö03SÉ¿“ìºrªí5Žž;ŽÄöå/ï5”ku69é²õÓ0FÑï[¦¦Š1ŒøÉ˜Œ  ?w„þæ÷ÂU4زáú×ßÀ7ßòg¦Î¦í<,ðœâÚc÷³uñήû⽋5uSd½õÆÙÈÉQ§Gçh^&QݲÃØ£Æ/ú»z§÷,1å‡4Ôu æ èS=¿ërf´¨±¥Û²áÚ‡µrü‰ê «Lµ>ç&²óKŸ™ãÚJË™7âóLDò¾ì)‚·êYs=>Îv *ÞŒ0ÐCP­_ú° ŒDÔ#JmíG¦8}~ ŸùâM¨ 8ùÌž~h´Œ9¤}̧{û$»šRò¢­Ò*´¬“Ý) S‚RÙÆtt//5ýwÓïÝïÝÁ®)ž*EÓ´ªk¾ïØ·m2YMÆdLÆ78 «›~ƒM¯þv®ýáû±ºa÷Á#t¤AHRØe¨0ÁñºÓwpÓÉ»¨ª’ÍgÏP¬ÔTU™=·ë¦2˜ ÏÜ)½î‚iA<ÖBsT†£ñQ]p5úUtêá-‘: ‰´$@G‘ÓïŠ6í®­†ºö¹®omv-ºé…©Yôs#rYVôÅ¥9ü¹4=KÄ;úíá}¼ØßǵÍý\áfeuš•jš'ÍVÍUYR™’î¼¢²%®”šzãìPb¿uŒœsJ8ŒÞÚc#ôq)ÛušªvÖ´iú¸üÌsÔåOë²È _ÅØ WfpôzÔeÔ]·%^tðÒÇÞ°'ÉÕtŸ$WgßQäÚ÷Úað_¬åûò NWð‹ ³ÇÃH X·]lH¯ÜtØå†u¦âjÄ¥Ë"-c[·öQZEÉÖ(Õê<®ñ"ÃJYäÅç{ݪu#}ß>~Ç;ºÀÝ}‘îþd¥&Û—_^òš×ÌŒùÂÆþÛã¤WÇÝ`nÎòýß¿V¶eièõÌо~ß²gÏ,ei&3ødLÆ7R„®ÿÕ{¸øo¾­?¶ëÙg1ÎQ„Zz¨±¬¬N³Võ ~åM°T¾¤©-eS1þ\ޏ“‡vêµNêp£©ßµáÀv]¨uÁ±™c籡”rš£ƒê(‰ Ä” Ùù,=/Eí]"]ªµÖD‡0í)M…ö^"tÕʬf·³r€U¢ÊÖ+’îO‚< ®GU—Ù¯û~ó- êÞkNÙž¯Éw¬>£Z¢6…!XEÕ+h"èz=œÕ ÊU¯mDUn¹7M+¹ªÇë–iŸ¬W3•¢ p¶n¿—?x>y¸Ã L¯èU•ž\$>u£ò(´ß•T}.†õöíS¼þõxõ«/ÂuØ[¿ð¦q™)߸Éo è[©UuÛ÷rNdЋL«ëøÇ׊¯+’­­Öû°æ{++\˜I>Ž9¾ÞgZæMö‹…¶L$]z\}õ6´V‘ÙÞ^—hÖ»ø>!òªÊ ë\`0hÖ‘õÒßÓÅÏóº×íç¶Û²mÛ„‘>“ý«b\kïç]tý°AXÑKÌ ÛÚkjS°ê§èSÕ*×»73°½×lY;ÍM‡îjšqsòF:è£Òª-ô•bš?ßûÚ±óü][oâDoûPÊ~¨^ÜxÉYûè)õßù´ÀH A‰•)Œr­nºõµd_j¼(µ•A¶{Í@z½ƒz&ê¶¾íѼú{?‰7šÊ•Üõ'7IM]iŽ<¼›ã_Ú‘¥XÈçZ¼Õ­†¹1¢ŒZX‚ x«¨Ê‚`ÁYMÕ3’Y.Á•t#ªm w=ÙÔÕ‡ŽxK0-ØÝ®··€qÙ~//y1\ÿâ¡ sþø1¶ž=#@[ ø}ëðÒ‹†¿GïÉ‘öø2P]yåVn¸a'›7÷¿êþ†BḑEÀ…Ï cŸ¡ã;:ŠBÓïO$V'c2¾î½®kVVZkRç¤.yùÖG8¶|UnQ²ARÍ.n8û®=?M#lõž°séØ@kåñ{ujy^]-r“Z î‡5ÞX¤5×èDÛל}€U;Õ²Üuà··ýMŸº$vMÁ€Þpë[—€ÇHTŸ?¦Äµò('ä9ëÅþ³Ð’¦6ÁQêÐ 'ªl¥®(œÔ¨QÑó[ÉçªBjß F@zßëå”úÜKÙsöÙL†ûôϽ‚º.üœ¦©mÌ È£Õ`Þ@S0g5®|nJÀ4±Më›ÒÑCnt­`KHŸ¾#ȺÂ,#iöŽìî‘°“#ìÚÿ¡p÷êúÌóþmðŸhüïaf ì×@Ö8µdÙ –NÆdLRîãÎ;ïä—~é—òã|ä#œ>}š×þ_ÿ€ß|%W_Äa¸´~Œ›«OàœÈ·*ÞëÌ ZßnÝ‘(U. \P{BÐSú¼ÛŸÞíSÏiû¸Ý¶[]ii#S:ð¹é—ògÓß,©| ×·°ÊT[€\AjûŠ€Ã¤/^"t¤æ¬½ÏÒª&D õh„bCÓʬzñùF!Œòš:Tq} IDATø,”£‚Dí)zwÚ BÞm£2.1Úë¢àä=Ûxæw/Â+!Í-Þ1‹;§£¾^š (ípF,o½¸BƒñÍÞS‹˜êÔ›“xè*´©6âvhÁœ‘º¸ëª­™aOï®îº§}qnÑuçŸý0\}Igá‘Ãí·½^³}ûd²šŒÉ˜Œo@©†þ“ï~ ßö]ó\­¾(Q`EC"kØêFˆS‰®c›Wd1¦íçΊ—IOÝ«u†C ®:f(I­3znuó*?N}ì™=[ᔊ‹ZñÅ^´Ç w”¯cM‰h΃¼ˆ÷„ïÇ+“>õÂ'Õ:¡a1.¢Ôãåf›FdVã±RWhíNãó±6"ÓÞw[¼ÏéuåCîWZÑX+us#Ìö¤ÊV•B\<ó±Í –Ä“¼z²`õ]´GiG0´'è@ÐQÒWüI[ðV{íGHhtúÁ;+¯ÕwR,]™UßqRK5óì]‚œ3qZÄ燎®zZp$F{É9‡¸à[¿E±cǸõø}?øƒ[¸ùæ 3}2&cè_g€þoß³Û¾g{V} >‚aˆŠjIpE5Y=Lù ÊbÁçˆS…йSCF)Eéÿ_{ç%Euïûﮪf†f``@Þ|‰^õFy˜‡£ÇxãŠ"ᬓ,õ®…s}Ý“„«¬ÜKPÑ¢99ˆ€‰ËèõÆDs—š“ƒ^–ѰàŠÈCP˜azºkïûÇ®½kWwŒÐêÌðý°fMuuuuuí¡¿µw}÷÷çy2Îd÷•u…ÛùË%¥çÙœt“¨fzìRyqªšŠSÕ„ÐQ©ö}<…n‘Æ!äì0A¥p×Á{!=EÏÇ>ÙŒ½Å¡Ú™ÅDQÂ/F¥LÍoÚ´µ@moÞCˆbtAàµøÅО/!•M_2.ŽbæL*›òôHDw*mïŸ2)+öGü:á3B uÃ{8eø d³ …‡C]…ÈÈ¢PІ®|¾  Qa9¸•óO*}1 }^Ñs P0ë”cÓËJš7òfïÙÛuJªØ9o.*Îïm\éÑD<ù¸®ÎCM¨ þ²lÿ55êê2ð<½mœnfê¤ËèsK(Õ…!C|Œ_SN„tÚƒ” Ùl€ñãcìØzÔ×§£×ÅïQZ‡½òç,'› 0th-jkSñÙ’n)U ›Í‰m9YðwÅöŠ¡Ø‘¥‹u(=¬ì)-T^(á¢{ÉRZ!RÙž§ˆzIfØT):=tTt3DDÕ³R!·ë<Ä¢.¼D8‹ô<{O:zþ´ÂÆ•á¶sÀ£áu³^ õ÷YsÝtŠ7òS¡Bí ÿÃö8Ö$§i!°½P­x¡ÒË¡‚'£¶(]ÍĬú¡v”û2Œ/ŒB}Ž!J†æC}ßÝÜó7‘«¶¼iÔk7ËÊ÷t­p……cñÿœS~v[M‡C-RbjƒÂÅõSÜŒ'D¢¯¬›ÛÉZ7nïø5Ê:̵#\&^k\àñc×@_ ¸ðRA;ºƒåï‰uñ=e/@DÁÔçA)… ð0dH Z[aܸgÓÄÁJ©Ï“þ-Ÿ?þœúü´·ç±aÇ —¼ù¬f?¦-Ž.äñúææ,Î9g†”psŽÂP;ØKEŸ ú¥­»{³bc2¾½PÆßÄJ›¾TÔƒ…í… û»'A/-ª?^gXÄõ³]q7Ó¹LVºû“ˆTõµÈÛ9ÜQ"[Ñ ì¼oó>¥ª™lçg_>’‡á©PTúOaûžáxõÍÏÛûÌ…|úú Þš˜ñгPzîµæ" ]Ñq«*>× RB„Q1“MÏšëL[1ПǸß!+kÁz•TÊjÂWÚ’"ñ7Ÿn:Élp Ê© æ´Þæƒ÷<Æ¥ÐÛñ¯ã?ÚvÇz©y:Wœ™â„PÐû Ú°gW‹o©l.Ós`…€o;Ì®œHÖ¨Wné2ðâ ¶›µnʘZ!wÄÖöe{ÝpØ¢{ΉHU‹»¯ú¾MC ?j‰ ¤˜Šb¦‡o{ðu±3~x}®žô'+þo¼:>Ê™Fç®:ßO9Æ--êZûÌýy‘L3 Íps‰{<ôlÚ™ˆòL„[ŽS =MÂIe«Øñ,[·W韨1¡ð—€{ý:.ν zúÞwM)çRA0ýY³ì i‡ÒMĪ)9ú¯Û.ÀÎö‘e½tûz§ÈŠ-™êÖóˆjs»Ùà‰!y#øž“›…¸Àƒ­ïm=‘› _›b(…´¾7mľèG™é¾WÖ“Wt¡‡Aª[-ÀÁ]‡¶ëHU)<|¸¬ ²Ë\ð8=x”Ôì†ó;áׂ®¢)dª¬–·gê¾Ö/¯ó-½dH™¾Bs¢W#ãœIf‹jÔ/~ȸ£Qs¢Ξ"0ylä\·Ç¿¯'V>îñ›„BAÿ¤”íDc½@±$ÜåvÊ’%M‚î »"î{¡Bæû!¾Òòôc§Â™ ?ñz;͈øŽFÅ…VTÜk·‚i1"n„ÜöU‰@“•õÄMH‹ýb$¦Š™HÕbJOëN§unzh3Z sÓuqÏS€_Bœ¦ì­ˆº{ ž®u^ôWï‚Zß_ µ€‡lß®wÅÝöŒ÷x"z5Ú>ì!zµ4†5t¦•¹j¥Îv!“‚oÖ9#-ëw)¬Êõë&ð!ͽ\)ðüs=e¢—˜Ÿ€nÜwßhœuV®‡¿ÜÞÖãîaˆ¢‡¹•A P[ —KÙß55¾-ûIé¿ x—û?3¿Þj ¨ÈÐK¸ÇUГÜCT3\D‚•5µÅ¿—-‘[Þéå^þ·‹¢Î ~¿ÿØxöïR€‹¼#òFðˆ›Êgìp:àT>šÊBߨ„sé{(¤S=?‘›nD>ôã £‰Öo ”6©EÃåÖàæÎ½ÞÒüiw²×¼u?ðÚ{¨±çаJ>Vˆ{Òf{wˆ%#ÇAÕK±Tð<ÖÖA˜>½Ùl`àŒ¡.6Ò©Äzm\Ó²B!6›³1•¹&3ýú¤ñ,Þ|ueÌjzqþz|²Ë/.²Ù--Y´¶ÖbذZŒQ‹!Cj0|xÓ§·`èÐ̽ÿbQ³j ¥õеáÍ<ÖËgœ1--9~ËÂzuØãµ`‹7Q ‚5X™@7JµTÐM Œ'¤x3ôîyZÔ ûQYL_D÷è#1÷"'²ÀÑ_Øn ©@õã:ЕÏZñݺi6¾v¦ôü¡Œž¦fÜá®à›8/Nj3&Ò?¯ÛƒOˆ|4„oê{릤/PH@z*š÷­œÎµ­åÍÛ2¢*“«¨zà¼ú¤ÈOÎÓ&%ô漆þnT>!¤™È¥*8¾õ<(ëL7¢bÅuXÇ¢#ËbK &‹” !Tù|ŢĤI8õÔf47×Âóâ)^°Ëæ”RŽñÎ=>wZÛ&+gª—»N•™çâ)bÇêÕ½§_S£§ˆ¹ÑªÆÕîšÝs^z®Ì>Íy©¯Oó– zõØíµb³ÿ9{¯Üô4­  á°*¯f&…/êõAWˆë‚N²\Ô“÷UhÝFÐÏ,Û ‡¬‚ªöþúˆ/îÆð >°ÓÕþí©sÑu0k§ŸµmnÄÁu‰!{WäÍç0GÌ0¾íÉ«(s=*”b\ó QØK !}bÊ„ÔEâ —¸]Î’éãU“Žx7MÍd£SzX·[`ÝN‘ùã€ëÏ«<‚|ÝlÀç­kB9‰zèbœƒÒXÕc÷aDÂg]ìQ†9 sÑÍ:_êùî G=âÀ(À—a,ò2JUSR“§ïM—û苷Ǧ7ÏǾw›ÐñA½®v`ó`ìxbT4ü×]Z¹ãŒxS-šKo0jÿsB(談Ž8,&F‚÷ÄãJfqÇÓ]ˆîœZ)7¿Lo׈½; M@Å¡5QššYöŠQ\ª3ÿÝ„°DSèlô¸´CêfTÁ ©‡u>Ru_g£×®.ÙªÝê©Ý"7ƒ‚‰{õ Þ–¨-HTz¸ZÆó°E´,„‚DO(“ž&BÈ(]ÍšÇDɲ[×Ûsë{»Óz¨8¦׿۫KЧ(8Â.ðÔ~\ƒ¼˜ŒY}þ— žÆéîÄóhøø†\uU€žJvVZ>í´,X¡„BAÿLè쬅ü¨>Ž# c$o7*GíE¤+z´* y‘"žŽÒÜô|îxY‹±%Ðùa\ÅĨz¡ŒSÕ¢¬tf#ÂhøÞ1#™ž¼ÉE7F7)âTµb ;•ÆàŇQH§t.º“GíµY2Fﻋ€,Å‚^Ö&(/29)„¡‡0òy…0Ôå@¥QdjTVÓFzêúÜ2 ãû½ˆ\Ri3U(¥Ý^J ­ Cs C%¯²L®ª÷"ÀºàÝá|ààž oq{/^¬*vñ{ø™3§ &ÔàÄbZŽîF/­æ’ü©¯OcêÔa˜:µ…†3BH‚~ër_¼x1^~ùåŸÿóŸÿŒ îü™‹þVƒG½´Ä½çøzÔ#M º2Á.Qz™‰f5!-Êó ½Ø=ž¬” w;V“ &¢ïm]S$„J'ÁÎ3‘©Ñ‚J;4/¤Šh¢šâˆ]ìèN§í±Úc‹>î #@Ý¡¸Ó ÌÀ%^dh’:ã<5"Ž05±›JÅ3í²Ö‚†a"BÕ<¯”D‰a/ŠÅ0Ú¯^çyNü(”žý~…‚ÔÇ=/•^WèÖû(òxÒ|¾¨³Ü£Œwí6­;Ü4–q— aI[OQ¥=9ä+‹z:íaöì1˜6­©”g³æM™ßدì1„¡D>¢P(Ú|uß÷0hP d³mÃîî…Bhß3<œvZ3fÍ\Žæ4B(èý3mmÒ=?ÀÐ/ÍŽî ;üZ:+j×{CÑÑ^«&Ø%z/v‘öÐyßKö"mÓ½Zˆz”ö»_$CXl1ø¾r";=šæ)—éD\ ÕM }ß匮lS%-rž»| ðõñåÛ_v0lÿóBH_bÀ¹OüÜvLþâÆ„ù+™§ï•·ŒÛ‡ÎŽœ}N /zNàýõÍØ½q°_µÒ< Êó#MnÊ›*)øÊÙH‰’eXA׳Á7Ûgn xQááCB@þ¯#PmQ"˜©z¶b7ÐVˆ]T*è¢âž¼(™öåvò{JKC1vŠœ$ÔD2—Üù°$RUŠØE.MiU'6Õ º>®#"QùÄù?]"ðÓ%ªäØ;€Q£€yóü’á çxSýxîÜfœ~z–ÿ£ !ô+èû¡íýÆX¢ûÌnÅ1#æFÐM©Îb Os+î¾ÎC/¤R… eæø|]R©€1uÀ‘(\F.îÿ¹ Ø›Oˆ»P ÙBwB¸T™˜95¶­°«¤Ì)÷ùHÿ#µµ²Íüq?g„Öd”+üâ!1wü¨µ¬+ã;¯ª‡—ë•;v(üã?VúÌñ:!€š™Œgóö_x!ƒÁƒý²×ÅékÉZÜÉÒ¨f[•x{¾õsÒî'ŽZMn'ÉøÈf}[šTlÖÇàÁÔÖ8í´¡øÒ—Æb„F–/%„PÐ{KçG9སd œSŦÇEß«ÆL&}=/àLó¼D.º]Nù6j5îq;¿‘MŠ ðƒ³ãÙI¡Ú®9RÄ9›?ЎÝÀ© çŽHŠ›‰2uã9­;\)›¹­Ÿ7ËÅ¢JÄtºyá®ØiW¸Œ/*"JDÍ+y®·b¥z¹ÿè6ðð…/ŒÀé§7#“ñmÔh[îÂïîÑÝt”'óÈãscïîóÆ%ŸÏ‡Ö _)µ¶6À”)M81hjâˆ!„‚^½úþƒ“2!2¦ªBùÒhÍE÷œûîž.ìâÓËÀ«¬]p¬èÎÐzÉDë¨gÜàO5#’YèRàìÀe†6ß~5ŸÄ„BNAÿ(‹®L½ÕÔÒé[ÂVêr:‚¦SjóLâ¬u]·;îÕ»5ÌËÅÜföJ"SášÉD\¾Óê|lÛ"¶è+ Ç覇ÀûœˆÍk!¢{âÀÍÿEàÒsK+•Å˾\x>ÿB½Ÿ8„ÐoCì/-"âq×Õí„À$^Ë”ž.æô¤ÝtáüHÄ=ˆ0úqÖÁ¬‡“•.â¸ÔRg<”=öîÐËØdvÿƒî·7c~3Žw”'ðßþ«;D^)L¯›:5Àu×qø˜B(èŸ%ª(ìÚòH:Â^°3Ì]§JÅÞä‰GóÀít±Ð)*bÖIO˜p„³d:› ™ŒTJ@*-òÊq’«H\£;ÄÖ즌Né%ãÓ2i©J[í¡Ì…‰Œ/Z ÒÃý÷»¶Ò!ŠXиï>¿dÛÊâ_~a qçc1kVãÑ©·Y•í[ü¾ññÕÖÈåR¨­MÃ÷uìk}}õõiÔ֦͘4i¦Ooá7!„‚ÞgØ `dø›éq¯9!è!0¢©¢æÞõŸ€ó[Ò ÇêŠ^õGެÃÈ‘u‰ÌíX”P¶.W#Èå¯éi9ìJÏÇëâ*ʾGüÑô-DÛ D˜#±÷y“ß^)xؾë"7¯‘Raðà Æo@KKé´oÙ¼Æ-®æ^HT¼&›M!•b  !„‚þ™óÁà­·Þ²;::ô» d܃6÷È­pû€?¾bçù¡õÀËc}û?_ÿ|e­5˜<š\Ÿ&Bèél„BAïç´µµaÆ öñáÇõ‡‡ #yÛÍ;’¹0P)˜3·ýþéÿ~š¸o0u"ðå³UÒÌæF¶*ÿ~‹ÀÐ&þB©RÇf W[Ã)‹€úË^´W’Y®Ê]ân$ªIH3âî.‡NºÍa7SÔ¢8SÔœ3=qŒ@:%’>²²+…þç:Œq¬žgå&92ƒ `!„°‡>ø°hßUž—+Ïýv³Ò+•† É"“ñÉøð£r³f¨<Ž/Z|ßCmm€1c£¦†NsB¡ ¸ì¢L˜0L»ª¥J8µ«;4ëœçC©k³Uh×k—9†Q̪ŒãE]a Cí8×.õКÀŒÈ÷¹Aj"EãÈUIÚÝ­×÷ä ×"(0yrfÎY³FC$Ìhæó ÒyßøĘݴs‰cêîQ(È„^ê®òJ‚^(hW~cc&4 › JyVÐͱ“Ïãy™ŒÏãè!„PÐ#æÎ‰k¯=ã(=̧z7-Ô íO!pL!¬îM–ÞîL@PŸ !„‚~¼h‹E¥í§vNúÛ1B9:œçC!„°‡Þ÷ùÃÚ±ÿîž­‡d-oý8—óñ÷ÏÉå„Bú&ÚnðÅ Â]IÐU?55.ºhh¯q‹c\(ôôþ=-÷î¸S)Ó¦ ìYc0cÆ)4”B{è‹G9—_þU$܈òÎ%ŠE‘Àq¾ÇbYƒšt³#Ê]—וî+ %Ž áyÀôéÃ1n\Ã1F>öõg„BA˜47g0nÜ ~vÔTeB!šâ!„ :!„BúývÈÝ­ã}ôí(ÃY Ž~Ÿš÷± !„|úô[—û<€W^y¥Çç_{í5´··cúô;ÑÚ:•³ÏÑËåäïQ£êÐØX@_,äó!òùFŽ¬Ã—¿<çœ3¾OU'„BA?aÌ´µÕ«WcΜ9liB!ÞC'„B(è„B¡ B!¤* ø`™­[Û±ví.„¡´Ion oÏ>|†ÏaÈ,ê„B(è}‘ÎÎöíë²Q¬ÅbˆbQÚWßÈfSÖµN!„PÐû S§Åå—O`KBÐð:!„BA'„BB!ôÞpèP3 B9‰=› 8B½ß@jN!dà3`¦­½òÊ+X´h‘}¼yóf¶.!„ zcöìÙ˜={¶}lª­B!'t¹B!tB!„PÐ !„BA'„BB¡ B!„‚N!„ :!„B>UAïììÄ¡C‡zµÝáÇÙ"„BÈqð‰&ŽýöÛX¶lÒé4æÏŸ &TÜnÓ¦MX¶ljjjpÓM7aܸqlB!¤/ôÐwìØ5kÖ`Á‚¸õÖ[ñóŸÿmmmeÛ½÷Þ{øÕ¯~…»ï¾·Ür {ì18p€-C!„ô…z[[òùŒÆÆÆ²í …† سgŽ9‚Áƒ³u!„ÏZÐ?ižyæ¼ùæ›=>¿k×.¶.!„ z_笳ÎBkkkÏÿú׿ÆÎ;q÷Ýwãá‡fKB¡  Èd2سgòù<š››Q[[ (‹X»v-.¼ðB466"•JaïÞ½èêêBKK jjj޹ÿ &ôh²€\.زe ¶lÙ–&„2 J)õIí|Ó¦MxôÑG‘J¥.÷{î¹Ë—/ÇÊ•+1sæL¼õÖ[xôÑG‘Éd0þ|Œ?þ„ßûÅ_ľ}ûð“Ÿüßþö·íÅĉ²dÉÜtÓMH¥RU;O÷ß?îºë®ªíïõ×_ÇpÑEUeëÖ­Cww7f̘Qµc¬v»<ôÐC¸ùæ›ût»¬_¿Uk—µk×¢X,â /¬Ú1þøÇ?Æõ×_l6ÛgÛeÑ¢E¸óÎ;«Ú.ÄìÙ³OšvyðÁñï|AP>R ‹/®Z» ,]ºßýîw«v×®]‹0 qÁTµ]n¸á†^uB?•vQŸ0ª³³3±îÃ?TwÜq‡ÊçóGݮ̙3GµµµUmW]u•êêêªê1^zé¥UÝß³Ï>«}ôѪíïÉ'ŸTË—/¯ê1^{íµª½½ý¤j—gžyF=öØc}º]®¹æuàÀªíïk_ûš:räHŸn—ßüæ7êg?ûYÕö·f͵bÅŠª·KGGGÕöwå•W&¾O)¥ºì²Ëª¶¿®®.uÕUWUõ®^½Z­\¹²ªûüÆ7¾Qõvéîî>î×â÷ÐëêêÊÖ577cÑ¢EÇÜŽB!½#à)øøÃ}étºªû¬¶ioæÌ™( UÛßW¾ò|‚wfª6<Þ×ÛeÖ¬Y']»ô‡ÿ/³gÏ®j»|õ«_íóí²xñâªÞB`É’%UÛ_:.ëô(_|q¿h—¹ BAÿ˜͈w¼Lš4©ªûkhh¨êþ† ÒçÛeâĉl¶ Ûe€´‹çyUÿ®=Ú…ÅY!„Bø .\8 ? ïcÊ”)U›žAªC8õÔSÙ.}ðÿ ۥﶋïû<}ð{¬¯´Ë':B!Ÿr'„B(è„B¡ B!„‚N!„ :!„BA'„BB!tB!„PÐ !„ :!„B(è'Ào¼åË—s»õë×cÅŠl]B!½âãèFWWþøÇ?RЗ-[¶à¹çžC.—Ã>Øãv›7oÆóÏ?l6‹%K–ð¯”BÈQù¸ºqÇwôÉNc¿)ÎrÅWàÙgŸ…ïûXµj„¸îºëŽºÝŠ+PSSƒk®¹†±ä¤bÆ ˜6mO!S_V®\‰t:k¯½¶â¶÷ÜsÎ9ç<ýôÓxüñÇÙC?Â0´%ê<σ”ò„¶#d ðþûïã…^H¬ûÞÒ]KûIDATþ÷¿ÏCÈqêKOýÜmÛ¶Áó<Œ3¦O~šâéç¼ùæ›øÝï~‡íÛ·Ûu?üáírgg':;;±}ûv´··CJ‰mÛ¶áСC‰/´mÛ¶aÛ¶m¼&¤6mÚ„¦¦& 6¬O_À&"¤óôÓOcãÆxä‘G°xñb¼ôÒKøÑ~„—_~ù|·Ür  ®®MMM2dÞyçŒ5 ·Ýv2™ žzê)¼úê«€Ù³gãꫯæ‰%¤„ àúë¯ÇòåËñÎ;ï`Ë–-˜8q"{è—¹sçbÕªU8tèþò—¿`Ö¬Yö¹… Úå9sæ`Íš5èèèÀ† 0sæLþ’Íüùóq饗bñâÅ€¦¦&xžþ¯íyšššÐÔÔ„xJ)!°téRlܸ]]]Xµj¤”Xºt)–.]Š_üâ<©ä¤ÂÕ7Þx3f̨¨/÷Þ{/F‘#G"—Ë¡¶¶–=ôãáºë®ÃêÕ«ñ­o} O>ù¤ýÂZ½z5–-[†\.‡;ï¼ßüæ7ñÄOàÆoÄêÕ«ív„œ,L›6 étJ¥0}út» çž{nbû¿þõ¯x饗ðÄO¦L™Â“HN*zÒ_þò—X¶lêêêpûí·ã’K.´µµaÏž=hmm¥ BÌ;sçÎ-ú\.‡+¯¼Òn7oÞ<Ì›7¥„ô’‡~gŸ}6O9)éI7æÍ›‡úúz«/†ÆÆFÜ~ûí}îs ˆîkéÉ&äd"“É@»îº °wï^>|û÷{öìÁž={ìº]»váàÁƒèììÄîÝ»që­·âÉ'ŸÄÖ­[±uëV,X°€'•~¨/4ÅÒÏ9óÌ3±sçNLž<ðâ‹/âÌ3Ïĺuë0kÖ,¼ûî»ô”¥Ö­[‡ÖÖVŒ3¿ÿýïqÛm·aáÂ…øÞ÷¾X´hO*!ýq¤¡¿ËB!¤gþ?½Ô –=s;IEND®B`‚snd-16.1/pix/sceq20.png0000644000076400007640000000675611147553270012761 0ustar bilbil‰PNG  IHDR#É_V¤OsRGB®Îé9PLTEÿÿÿ°°°ppp```ððð€€€àààÀÀÀÐÐÐ000@@@PPP    ÅÅÅ©©©ªÐª pHYs  šœtIMEØ ¬ùÒ¡ ;IDATxÚí]‹–«* ÅʳjË=ÿÿ±——V% ´hµCÖ:s¦y!l’MDÈHsk1"„¢*!a‰;e7ë8þèÏY"Te´S?øµ4D¶® µDI+DO(¾”Žnls‚Üþº…è·¯éÙ•oðF”ñcM#–¼zÆsʸo¥ú³„JP.Ô¨¿q¥Ÿ"ËbåÖuõá SrÇ艰 ”öfÑÐÆPl4è)PÇ€}¤îÔß•ây_dR·ùÓ}Î[Úo6KU5CR=ü¸u”)Cˆ1ê„3µV¤yˆ¢CHݱ_B},Ä=´ »"ݽó¡*äì÷ý!ÓÏA=‹‡mõ¯'ê”èx¸¹!Ñ—Ó{>Å\I³ÞqÑ|ˆ=BWé¾cÁÕØ]«~íô€Q#†ùèCM©¦…J´M¸ÒÕ¦H—,!Íp, 2*#з2¡ÐžªÛ¥7Ùâ®a²Ñã¥i`bŸ²¹a¨„žw¡B’ð‡~ÚD–¬íÎv. š°×‹~… b÷+‡'p =ø…*fæÁwÅß}€Ô­ÌQÏS¡ ]Ù±’…†G, n Ô”Ô3ñr;ЕIza’˜ñ¡ÉLGe x)„ +YGIc–¨œ¬LÒˆI‚`Ƈ&/ñ–1IW…¹•™\÷v ˜$f–ÐD+ mG–m#”á@)éˆI‚`Ƈ&¯q¤,}S¡|]<á0IÌøÐ䥣‡2Eêë%BÁÔÍ5|Q‰.„IB`Ƈ&“Žx«ÆÝ¡dÜ/îà !–˜$š¼ºå¾NF( ¾Í–BŠhSZEl½_£›5š`üB‘²W´iî"C+ =3šÂžù^Ì·O¼I6¡I&BlºP3»Éðj¬ç.löÚû]Úî> íÑÆÒ‘Þ&*MHpÈu©#[BÍQ²‹¸s"Π#»´NHpÈMu¡#[â¿G×]-À“¦£¹‹ÌŒˆ’rD]Øöý9­ÌšU’…r#D]ε%öým 5‹ä„d‡ÜQ—:Zbß_Ù? ÷ýƒŽ>LHÖwÈMu©£ö-¶¹-WÑóÌæ9’õr#D]èÈǾ…z2Ç‹L&?’’!êÀÒ‚Ʊ¹¬†=''QQÉZˆšSâ˜=wìŸIGgò®+çÆ‘T났:ñÍÑܱOøe=>=ò*J¬à\óü}&¾#¨ÈõkÍÒ>\QR'Ïßgâ;‚Zˆ\Z×¼ŠÒ+8ÕFàùûL|GP ‘ë}ÙqäU”\ÁÙL’%3ñqÞQU¿"¼ÃY×CLR †dš¤*©&)Aµ¿ÀÞÏØg¬&Û; úsÐñwYØ›Sí=ö×õÙû{¶ÀÝðíWet†Þð$]uïñü­X¾ýòàqôŒL?™{ÍØ[’}A+xþë”´úr´žo‚mÀC} E˜:”„<±ØæáD‘S“³à gGÚÇ}¼õeÈfN3égçYlÝœ`„©C¤AÁVtý.ó|€`ÖdtÒüm¸H Wñhë먗c[³å&¸UêœLàθE‚ò^†ë3¯LMnÜG¾ŽÒO,´±€Ä:Á‰íÉlåkt|µ‰T±ˆ¿z1Z]¿‹»›×MFùù:âm°[hÕ33%ÏñØÅú™‚Íš|"x^£ëWÿ»›×MFùù:šâžPèxÕØ]ß` Ÿ¿I·: ·¾bdvF? iÓ?FëÒ¹J9 @h–mj2ÎÍÖ{„»åÅŽ©ÑÌóïàq4ö‡ä±ºü­­ßD‚§(Ü䣠=¢·p·Ðº1«P8ŸÛ@=™o6ƒvºðb´¦~ vn7¯šŒ‡s³uÔ7ánù±ã‡ä ©v”v™Ó¦U÷Ê®e >Y¨:¹­b´³úãÁÚ¿ÎÅð@"Ýò»CÜ`xþPÂü’)òiÚÃÿ¤I SÆžy¦Ôç理-›"_&í×2šTÀ+#©°¸G>[Âì·³Óœ¹öKŽ—¿ÇóÿŽ"x¸ài_Gdcq];í·ÓiÎl½.ÏæùC@ãòúÃ|˜ç¸µ:z};¬n:­¹éò_àùc'œ6œU¿âÙ·ÃGãèJY^ƒ‡ dÃ:|Ä=Z1|öíð‰=%ƒüÛ.¡Â2fÿ ÖtôßCoÕ-î‘=ÁÓ·ö4§Ù¡.U‹_#F×µÏÿ½%}Û%TVfÙÿÙúa`ð± !_ca…Aažÿ{5Å%Ttefÿ_âì\…tdpvˆçÿžµHq 5OM¶ŽF·Ÿ—¢kFÕ4“éÉöÈç¿é*-}Þ~Mº{ôRXt#ˆºÉ ^‹ûùü—.¡¥OhÉLó€ï|Óàü!7¹v¤”íñ–Kh‡ßwÐkœ´ŽhëüèõQšàÚ¡Á~¨ÈŒ£í7Eã^rrI›àùO~´nö! °Ÿ¸(!u‹ç@>‡óç-žñ|„5W}¼òü·ÍQåùÇåÓŠ²°´2ûIEND®B`‚snd-16.1/pix/sceq11.png0000644000076400007640000001555211147553270012753 0ustar bilbil‰PNG  IHDR´!§h¯TsRGB®Îé pHYs  šœtIMEØ  2N/üIDATxÚí]{TWþŸ0"A1,èº<y(BŽˆÈîqÑ…(ž…öP·µ=ÇGeív­í²À´­…ø±VÝcÝ"N“-Âb@Y,/‘ ¯@%ïd~Üsæ—“¹™L aw>e.wîý~>ßïý23wæ^Š¢Ò@Q´©©I¡PH$’ÔÔTkv}òäÉàààÉÉÉÇ;88,¡ÃÃÃW®\ñðð Ñh,ËÊ:@Q[[kooïààðÛßþv…“D")--MKKƒ.wèÒY³´>µak;²Ø`YÖ1f¡ìgG mšššêëëãââÊËËÿýï[³ëÁÁÁ¡¡¡øøø%O1?pwwW*•¶à”êêêGÅÆÆòx¼Ÿ~úi¹Ä’L&ëìì,..†.wèÑY³„¬mjØÚŽ,¶–@–µ˜–Ë~ö”Ö&aÇŽ>>>(ŠÎÎή_¿Þš]¿ôÒK!!!žžžK.›ÍvwwGQô›o¾±…«þÆÆÆÝ»w#ò«_ýêÎ;ÇŽ[±äèèƒýÏÐ;\îУ³„g YÛÔ°µYl-,k1-—ý¨‹“ãìì|õêÕÄÄD//¯E¶¦T*oß¾=66æãã“””dgGô çÙ³g111Ç?yò$“É\<†5•ŸŸÆ`0h4‚ ÎÎÎáááÐÝÝÝ)//‹‹3—°óóó•••4-$$$44Ô$q¶lÙ"‘H‹Å“““f±GO¥RYSS#•J’““ÁÈDQ´¾¾~ffÆÑÑ1))‰N§›êS‹‚À=vP"êë냃ƒùË_-´ÚÀÁlžžžvuuMHHA ¥ ­‰ —Ë]¹r¥¯¯¯H$ …ñññ†BÑP d`öaktà@}„¢hCCƒR©tppˆ‹‹Ó£ [*‹yCÝ Ä(Œ†1ù1N »ÞÈ2T¸˜tg…ì÷ÿcŒÂpäȑ۷o/¦­VËáp$‰F£ÉÎÎNMMÕjµ†*K¥R©TŠ¢èÙ³g¿úê«E_]]}þüùµk× F³iÓ¦ˆˆˆÈÈÈÈÈÈŒŒ âF}j( Z0ÊڼÖÌÀ1䣜œ>Ÿ¢hsssVV7¡²X"Ô͘@Œ‚L“ã†d‡Ž,há"Óž˜æÍ~º .LÃçŸ^TT„¢hnnnffæbšêèèx÷ÝwA( ''§{÷îª|æÌ™ÒÒRE9Ε+WÌÂÅÏÏ Ùááá~øA·;ÝDƒÇ“'OöíÛg.Uw¹\ž››«R©Lgjjª¯¯äµ¶¶6³‹£V«œœÚÛÛQ4M­V«Õê´´4¬~zzºZ­6Él‹^[¢ÇO;¼~ýzTT”^V…³3ãÀ^ Ä.ƒ|||æææ ”¡5ÁáåË—É„"A FY[bØ[ õ‘D"a³ÙØŸØlöÔÔ”!oâe±D¨›7…Ñ0&?Ɖe×Y† ™îôÄ´Dö ^H$BwwwSSŠ¢===àº{×®]^^^B¡°³³óСC‹iœÁ`Fƒ ÈŠ+V­Z%‹ õ»oß>ww÷ááá¾¾¾W_}ÕìL×­[~×ÖÖÆÆÆ2 CÆ 222²bÅ ³t=<<ÜÑÑ>55E§ÓsrrìííM§¯¯¯¢¢âÞ½{L&sÇŽf‡N§ONN}zzzvïÞM§Óíììêëë‹‹‹QU*•(ŠÒét“ÌV«Õ•••ãããsssz‡‹´™À=@‰€?µµµEDDè=á„egƃ ˆ@ X³f øM£ÑÜÜÜîÞ½ ¥ ­©÷è”8 Z0ÊÚ¢Ãj-ÔG­­­؉,«µµ•À›z²˜=ÔÍ›@Œ‚L“ã²['Ýé‰iÁìG= 0„ÚÚÚ¾¾¾ÚÚÚƒÞ»wïÕW_C§§§;::ÀÓBs¡··×ÍÍM"‘÷ÛÕÕ¥{WgÆ›c 333………FEP(Ø#ÇE¢¬¬ŒÍf߸q£­­í‹/¾¸sçÎÄ0£Gðâ…Âýë_o½õÖèè(&Ž««kRRÒgŸ}&‰`¶u k ””ˆT*-//GQ4::»å‚’dgÆsçΈˆì0((Hï~£LP“Ãá|óÍ7UUUÙÙÙàF ІZ ÏÚ¼ÃÖèÀÁûèÊ•+)))؉ÉÉÉ—.]2äM¼,–u3&bc’cœ8_}r`–t§³g?jZÏŸ?¯ªªBQ”Çã%%%¡(ÚÞÞ.“É,Ñ—V«}å•Wª««­Ü/4Žsss±Akc.]ºÄd2ÁlŸF£ñ÷÷×Í>¶#ŽP(ï½÷ÞÍ›7±¹˜üüü„„&“YQQa >%Ž.Cì DJKKÁÝ’nÅ. ;™Lïzzz‚9 ÈÏ?ÿìââbööËËËÃÃÃ÷îÝ«V«ÇÆÆ6nÜh~¡èììÔûŒÍ Æèf.†-b#â´µµq8œ7n€)g—––GGÇøøx0gùæ›oªTª¦¦&1mǧ†,ÑEuu5žˆ››ÛøøxKK ‚ ƒƒƒ%%%{öì‘H$øÂßýîwKÂÎ××|Ò¢èÓ§O£££ Q†Ölmm=pàÀÀÀ6­.—Ë …¢¡¾–jœ œ¾¾>¼¼½½gfft/}|| 5ñ²@#ÄÖB (Gh»¸¸ãl6ÛP¾úïHwVzç`jjŠÇãTH$à![ø\îóçÏ×®]«ÑhÀ“(³÷Âçóy<žJ¥R*•ÍÍÍÿùϬÓ/€¯¯¯Þ°¯¾ú*66ÖÊ"¨Õêàà`ðq„V«Ý´i°ÊvÄ©¬¬|ýõ×Á³V‰Dbgg×ÞÞ^WW&nnܸÑÜܼäfG”!"ð&`…KÂN¡PìÙ³<›år¹ØGqxʆj>~üøêÕ«Xb±XàP|(B[X*Ÿ’8xÉåò   ðÞƒZ­ Ô{:Õ„Êbû¡NÄaL~ŒËŽOªz…¶™îÌ?­ÀãñNž<™œœüÎ;ïàÿªV«Ïž=‹=£†ÂÕÕU¡P477ÿæ7¿±©UUUvvv###hmm‰D»ví2ûUm||¼T*Å.Ò¥Ri~~¾¥ûE„ËåvuuMOO„‡‡8p»¥Ð}óÖ "€÷„Ï;÷·¿ýíüã­[·þüç?{{{Û”8‰‰‰ßÿ½ŸŸß§Ÿ~š““ÞPËÌÌ,//ß¹sçýû÷'&&RSS—Ðl2Ñe‡'΋ÅeeeSSSW®\IMMfër¹\ë³³··g±X]]]%%%çÎ3DZAÿü‘ÇãmذáÔ©S×®]÷døPÔjµø¬340p 9îĉçÎKOO/,,ÌÍÍ]¹r¥¡šxY b;¡nd˜ü‡‰¡¤Š/´µtgüÉAMMÍÂ..N:•——ýSAAÁýû÷É4’––^{±hµÚ‘‘•J¥ÕjGGGÁÛ+&aaïâ.¾ßÅ@,ƒOfÍh ID"Q}}=q奧···®®nddD·°¿¿¿®®¯`i³Íþ¦7"6å”ùùùÆÆÆööv£ËÅÔìééihhÐýŽŠø,Äzn%3p°·íêêêÈԄʲT¡n›cœ¼ìË4Ý¡(JCQthh¨¾¾þí·ß^ÀµE~~>‚ ÇÇ¿ÚvàÀÒÒR2ܺuK¥RýáøozY!##ãóÏ?§^Ú t T¥@¹•²ƒÝøøø;ï¼óôéÓ®®®‰‰ 0Àår«ªªÀ!‚ £££\.whhH(Þ¹sçÉ“'z­àËÛÚÚ‚‚‚ôªA—ÓA$66öÛo¿]<CíS @ L¸8˜˜˜X³fB¡xþü9xmòïÿ;›ÍÞ»wï¡C‡úúú‘ÉdEEEgdd$..îàÁƒ àáÇøò»wïnݺU·§ºº:ƒ!•J>,—Ë/^¼XUUþäêê*‰ô,S(ÿ1€‡ê¾ði´} (P @yØoݺuãÆ6løõ¯ Š*++SSS7oÞü /”••åääøûûïØ±£¿¿?** Am۶ݽ{ûÎÕÁÁ_>22¢ûöÄüü¼J¥ xöìÙää$›Í~ÿý÷u¯´Z­F£ÑýŽN*•vuu²ÛÇÇÇÉɉ|û(P @Âÿ2?~Œ H@@A VùZ¡¥¥åÖ­[```[`ŸF£mذü¦Óé*• «m‚©[.—Ëu—Î6ºžƒƒƒØp+qssÃÞ¢7 2ëEè>ðÐíèã?Ö-áóù%%%dú={ö¬££#ø-‰Îœ9ƒý‰Çãedd`êeee­Zµ ûk^^Þ‚}üÁlÚ´iaìNž<) Íp[·nMOOÇMÒáêÕ«íííæÉÉÉ/¾øâÂÄ)))áóù¶0ŒÏž=»0UÛÛÛ¯^½jËIê£>Z¿~ýÂ|ô׿þuzzz™fçÇë.€o’[=ú¿ð,==]ï¾n “ÛrÇ‹/¾˜œœ¬ûƒN§ëNâãK°BŠ¢ÙÙÙ6lxûí·»ºº|}}ccc/\¸°}ûöË—/ œ8q‚Á`äççËåòììlAŽ?xäÈA •?~<99Ywµ€½{÷ž>}zÛ¶mzë9DGG777ëî!‹ÏŸ?%L£Ñþò—¿è£í[Ô»E””ª(·R°€]¯ÀúŒ†J°B{A ¸ãzüø1‹ÅÚ¾};‚ “““(ŠÖÖÖ‚Í­±3ÉüöõõÅ»»»§¦¦"""îß¿® kjjöï߯ûä@o×,‹•››kˆ¤ÞFXFÛ§@ þ—¡w-Á íIIIÉÊÊ ussó÷÷/,,äñxvvv›7oþòË/üñG.—«V«››› E{{ûÈț͖ËåÐr6›½k×®²²2l—Râ5CÄb1¶|ÁlaM (P @á¿4p»/•JçææÀ–$(ŠŽŽŽ2™L™LÆ`0ð»}Š¢û÷ï/++£ÑhX›žžžt:}llŒÅbéî{qíÚ5OOÏ^xaÁ4ˆÛ_$”JeMMT*uppHNN&ÙrffægŸ}fRG</,,ŒÉd‚C.—»råJ___‘H$ ãããÍî~jæ2ƨJ¥òöíÛccc>>>III ØP­¯¯Ÿ™™qttLJJoªB­µ´Jdt€ ÓÓÓ®®® ` @É.€‚IÑ5??_YYI£ÑBBBBCCm J¥ÒÁÁ!..¤xÍ¡"@OÏÏÏ c0àÐÙÙ9<<ÜrÞÁ“‚†”UzLɧYè“t+w˜JAúúúàà`𔎡ÞñYN¢… [“ÔÀ‡–I):ÜH¦C²C£Ý,™ÄÈ¿U ¡¬¬ŒËå­¦ÑhÒÒÒŒ.s¶„ÈÈÈ+«€20ißúêêêóçϯ]»Vw®ÌÌLWWW''§”” í}¥f^cˆuÐjµG"‘h4šìììÔÔT EEEÏž=+t}øá‡ÖZN%ò:@ = ö ©¬¬üä“OÈ.€ùè …o¼ñÆää¤L&‹‰‰‹ºçä䀅@š››³²²@M¨æPð§k4šM›6EDDDFFFFF†„„dddXÎ;PRÐð€’‚Z…gJ>8ÍEߨ[IºÃ$âØN 7n ¢íÚ‘å$Zذ%¯4´È§èé$S!‰ðmš1“À‚Z­öÓO?}þü9qµ¯¿þúÑ£G6{e¶7mooGQT Ðh4°‰% ·øåË——šuŒéèèx÷ÝwAdƒÏUîÝ»§V«ÓÒÒ°:éééjµÚµ–V‰ŒøB@ˆ Ÿ¹¹9(YKSHLL½ÈåòÜÜ\•J%‘HØl6VÍfOMMA5‡Š=}xxø‡~À Ïœ9Ò¢…¨áIAÃÃ)«t™’N+Ó7ꎿ~ýzTT¸80Dß»¡¡jS™¤>´LJøÓɧCáÛ´N&±³àŒöþûïwwwԙݶm[`` ÍλÐéôÉÉIðadOOÏîÝ»¡›[–[çqÔÌn ƒÁ`I«+V¬ZµJ,ÛÙÙÕ××£( V§ÓéÄÖZy5Lhwº…`Íš5Ø@pss»{÷.”¬E) wtt„‡‡OMMÑéôœœ{{ûÖÖV¬‹Åjmm…jmzúºuë°‡kkkccc±¯ ÍN J ĤŒZE>8­IŸŒ;L%ÞÖÖMÓÑ´#[“ˆ¼ÐÐ"Ÿ  §“OP‰ mZ'“Ø[4‡2Œ;wTpuuݶm›¿—áèè866öðáC>Ÿ_\\lµ~çææJJJ\\\ÚÛÛ“““ÙlöR³1[¶linn¿ûúúT*UTTF»páÂþýûËËË£¢¢>úè#k­ ’Qð…ºkÈd²'OžÄÆÆâÉZ”B[[ÛúõëoÞ¼éííÍç󃂂^zé%¡Pˆ-ÎT …†4Çz:¶B‰D"Ä&;-A J †H‘´Š|pZ“>w˜D\&“ŒŒDFFb¢½Äwdk‘WÃPh‘LÐÓɧ¨DÐ6¡‘i~1Q äæ8Á{ï½wóæM«=ÁîííŽfggýüü,´q¥!jV6F«Õ¾òÊ+ÕÕÕàpxx8???!!ÉdVTTXkiÃÈè€/”Édaaasss(Šzzz"k9 —.]b2™`&^£Ñøûû‹D¢‹/¾üòËX”””ÂÂBÍõD0t:@nn®îd§%¨AI ()«ôÜmRpZ‡>Iw'^ZZ î§£££Á´‚!:P‰ Ù”DäÕ -2©zºI©/±IÍ$ÔÅ ˜žžvppèéé±ÎÅ.|||ÀžRV£fecòòò¾ýö[ð{ff&--M£ÑhµÚ¯¿þÚÍÍ­··—Œ#,a˜©:`…§¦¦¦±±qûöí;=²¥PRRŠFGG_»vM÷½Ú}ûöýãÿ Ö\WèéØäîŽ; c.jPRÐð0Hx« î&œÖ¡OÆä‰?xð ³³SR÷âÀÝÞ¡ÙšDäÕ -£©ÀÐé&¥=‰ˆM²h&±C({†™šš fqÜÜÜ\\\ZZZ¬Ðokk«ŸŸŸî´™\._*j–6¦¼¼<<<<99Y­VŒŒTWWÇÇÇÛÙÙÑh´7ß|3//¯©© j­T2ªƒ!|}};–°gÏž§OŸb«…ꑵ(…€€Ý-Êh4šR©ôööž™™Á %‰Tsh›ÐÓÁïÎÎNÝÙ\ Qƒ’‚†””©V‘ NkÒ'ãòÄûúúZZZ KJJ¡t €vdk‘WZäS¡ÓI¦¨D&Y:“Ø#!‰°M"fgg%IXX˜^sswwÏÊÊÂúýù矉ßÞ0;5«ÓÔÔäáá­R©ÚÚÚÜÜÜÖ­[§»ý·‹‹‹——ÔZ&“ii•Œê0>>Ž/T*•ñññ«W¯æóù , JÖ¢Ú†……÷™ Š¢ããã111žžžb±ìs¦ÑhÄbñÎ;ù|>^s¨;wîÄŸŽå5ÝEÍ-D JêÁƒøð˜žžÆ“"¶Jïe.’ÁiMúdÜõ&ÔÝ5æ ^{íµ-[¶@é@{‡ª1??oSA„víää„-ò©z:ùT•íVÊ$ÔdÑïýNŸ>ÝØØ844täÈ‘'NX¢—ï¿ÿþôéÓL&óرcׯ_Çr¹ÜŸ~úéÈ‘#ß}÷Õ¨YÓ˜ÞÞ^ÝݶÀÕ®V«ÍÈȸqãÆ“'OªªªÀª!k-§yð…fÿþýýýý|>ÿ­·Þ3ŽP²–vtCCÃ|044”——wáÂPX^^Îáp ‡Ã)++“—xÍ ‰€?à‹/¾ˆ×íÝBÔð¤ áaˆÔ*èé鉊Šò©ÂRTTTTTD"‘ÜŒA^¿~½bÅ ---///EEEmmí£°DEE !i­¤¤$**êÔ©Sd2YSSsÈGIIIIIINNnPgUUUEEEeee™ššŠ‰‰mÙ²EUUµg5›_¿~UWW»¸¸èêê._¾|ôèÑ$111ƒØØØ¡h<44ƒÁ@Ûfll,…BQVVæS…Å%---¯^½277×ÒÒ`éÒ¥111#IaAHIIIddäþýûpqq¼«ñ?ííít:ýÉ“'æææNNNìœell Nɳ³³„„„<(""÷¨OïF÷§OŸrÐ\RRÒµk×,--Am„„„ F’Ôbcc£¢¢¸l¤   &&ÔV#Œâââââbvj®^½ÚÕÕÕÚÚÚÅÅEOOóŠ‹‹‹­­íåË—ýú%(ò‰ŽŽŽ‹‹ƒµd ËÎÎnܸqƒm+99Ç»¹¹3¦kùöíÛŸ?>’¤fjj:oÞ//åSQQQUUkÈVQQQSSS_3AŸ5kÖŒ5гKΟ??))©µµUp¥VSSSSS3`µ´´´K—.-\¸åF; ’’’---‚Þ«¨T*•JeýùåË]]]Ž; g íØ±ãåË—|è,ÂfÿaWa­\¹²/_>OOOGGGn:ŸššÚ¢E‹^¿~-¸R›1cƬY³ú¯“ššš““sùòå &°ßòîÝ»Ÿ)¬^ikk»téVTTäòªS¦L‘‘‘1ŽÝÝ`0îîî¹¹¹ƒ=WFF¦ëØd°`Á‚Ẻ½½}@@À?ò2WUU Ö>p`w¿(‹MIIqvv†ÄCWHHhÕªU7nܘ1cÆÛ³úëׯŸ?îß¿_AAƒÓFŒ4rrr”””TTT†íƒ,,¼pḸ¸aU®¨¨hPÃù‘3ÂòôôÌÉÉaýS[[kgg'//Õ…¥¤¤ÔÔÔØÜ"Ëo„‡‡‡„„t+$‰åååvvvœi+ýû÷?xð@ {U~~~~~>ƒÁxûö­££ãðÞ̨Q£øÍ`Ïï a¡ÑèÊÊJ–¶b0ëׯ‡üÚ»víÂ`0²²²7޵´´ì¦jCCC³³³W®\ÉeããÆ+++c0ýû@ð3::::::••• þinÆŒ!!!ÍÍÍüqíÚµœECÀ†5ÔÎ~K—.ŽŽh ’Éd…Ó§O/Z´’Y …û.ïܹsøða~¸“M›6ùúúÂoûWX<`˜:Ž122JJJ²°°öŽåëë;fÌqqq6ëËÈÈhiiÉÉÉIIIñÏë±{÷îGíÙ³Â6“’’>þ\VVöb÷•ûÏØ±c¡ °£¥¥5à`þÁ××…¥¬¬¬¬¬üöí[žÝº±±qtt4…Bá&óE__¿¸¸¸;wrÓ²+¢¢¢³gÏþùóçÊdÉ’%gÏž?þð¾ö x<~Ó¦M쟂B¡P(/û;Œ;¶²²²³³“ûxíííx<þáÇFFF‡l§›={öׯ_ xìý?à—Dªûöíóòò‚°Aƒqâĉ††† .@¨­x‰¹¹9÷‘㹡©©éÞ½{§OŸ]BBBBB‚L&sÓHggg^^ž««kLL ƒ±±±ü ÉÂòöö.**ⱕaÆŒP­FDD€v1.sÁöE||<’Ì;÷û÷ïÃØ9âããçÏŸÏÁ‡Ãáp8~ëë&&&\Ž‹oß¾ííííää´wï^nÚ‰‹‹KHHÁ½Ü†\a­^½ZCCƒ÷ ,ËýÆ”?JJJ?~|è|è y“øàÁƒwïÞ–ž†D"çÏŸÏÁ¹êêêêêêüöâq$«¹¹Ù×××ÅÅÅÞÞþÚµkS¦LáòNŒŒŒÜ‹Ê?,X°€Ôkï KQQ‘}#+„8p€›hYUUUçÏŸ—••]´hÑš~ddddddx MMMQRRÂãA ²²²8ÓVˆ‰‰ KgX––nnnÔ)±±±ÿý÷ƒQSS¬þó¯L ‡  ¥ªªšÍqÁßß? àØ±cøÕv(Ø»wïëׯy™Ÿ‚B¡¼{÷n÷îÝ#¯»?ž}í_PPpþüùööö‹/r°žÃ;…E£Ñ ÆpÛè¼¼üĉ:::...¼ùpÑét:Σ'$,liiÞÙÙÉ›ŸöðáCGGGnVÜ ÆpõŸþa3—Z[[Û‡âãã;6ž%¼ì?ÿ„Ââ½ÑŸqãfÍšõþý{6ë?~ü8,,ìÆ3gÎäÙMÆÇÇÇÆÆòìrS§NåA±?^¹rÅÅÅ…ËÅ/þ4º°qãF??¿þëøøø\½zUUUu÷îÝCôý,£;}rúš† —Â`ÆŒ¹¹¹YYYýç.OOO‹‹³´´d?ž'T˜››ó8öîôéÓ………}||¶lÙ2D— “““;yòä`sèöd„ ‚ç$777::záÂ…öööCjƒ³°°ÈÊÊú—õNuu5gAa>ü1båÊ•aaaýÔÉÊÊJOO·µµ4i÷/˜@0mÚ4È[®¬¬<þ<‰\°`„„ÄÈc¯Î"t:=**êçÏŸëÖ­›6m®Œ$rss9[låÓàyJJJbbb½ªáææægÏžÉÉÉ999ýkyÚ´i¸¸¸8;;7Žû«ªªâããkkk;ö¬[õŒéÚÚÚêçç§¡¡±uëVîýàa†¶ø G}ñâE·$†X,ÖÃÃcݺuë­z àÇ3…Á`>~üèååÕW¢¡Óé¿ÿ>xð`@@À”)SÐh4´Ú àÇŸ=^WW·ë2tjjê¥K—,X`nnÎ3mðã˜ø #K–,‰µ±± ³³ÓÍÍÍÀÀàâÅ‹Ã~c=øñggçâââ[·n‰ŠŠž:uŠý Æ… „……„³³óí•øñg=z4+Å–»»»¶¶6ï#…Àü VX|‚‘‘‡ûýûwCCÃïß¿Oœ8ÁW†mmí3gÎH$pQOUUUYYÙÊʪgÍÇ@£ÑÊËËÄùóçEDD†Å1˜ Óé7oÞÜ¿?¼VXP²råJ//¯éÓ§ïß¿ŸBÜòË|^XXYYƒÁÉ人º/^üøñ€1cÆÐh´ÂÂB0œè*))ÉûíVüɆ œœœîÞ½ËMèýŠŠŠ hç°úúú)¬þ3?óYYÙ'NðÛóc?ó3o—————¿ví«{ãð¡[æg~cÚ´i7oÞ„6Õ`ßÁÊüìììÜÞÞaƒ&&&à 4 «ŸÌÏ0ßgî3fÌðFÔé–ù™ß––ÞѺÀe~®<¸½Ì*úšˆ h )ÞÀNæç™®™Ÿazg~†XaÁÀÀÀ†Â*//îkÈš™™Ù³°¡¡¡§M‡Édöºÿ ®®®¶¶¶gyvvv¯û{{½"ƒÁèÕS¬¦¦¦¾¾¾gyVV“É„Dd­­­ÁÁÁ=ouœŸŸÏÚÝÊ*¬­­e%ïb¶¶¶²V¸Y…………­­­477³¢ Ô×׳ «&Ngy<± ‹‹‹[ZZ Ñh¬-VD"‘e7aÕìèèÈÍÍíVˆÃáXº¾J?àñøàà`Ö#fµÖÖÖVPPгð®Û«$ñx<Ë–›› n]îši©ÿÓËËËYQFY¥©©©´´´[Í®¿”UXYY zvíÌ]J¯³ZZZ‚ƒƒ{m­ë«QZZÊ2Ëäää°6“÷ú3”C_Ç] ‰Db93UTT°ò ´µµ3}ÖÑ®¹k‡éú¢±s'ƒ¥–¸¸8 …¢P(...=ÿûõëמa’jjj(J7×›ÎÎN,kffÖ³C3™ÌžŽÚß¿711é™=´×+vtt$%%™ššv+Çáp¢gnˆÄÄDWW×µk×B ã……Q(ÔçÏŸ%%%ÅÅÅ»Þë899ù¿ÿþsˆ² q8œ°°°¦¦f×ÂæææœœCCî…)))S¦L‘––¦P(8ŒmfW7N²j¶¶¶¦§§ƒÑY…iiiÚÚÚrrrMMM………à죲²’F£[üX5ÛÛÛÿþ=gΜ®…à Ú·oßLMM………8ÀæžM  ú[tm­¥¥%;;ü¥]; 뺽J2;;ôØàdž††¢¢¢õõõõõõS§Nívú¼yó„„„ºæææ*))©¨¨””¤¯¯/!!A$Á<7]kví~¬Â‚‚YYY55µÎÎÎïß¿ƒÉÜÈd2¹Àšì;s! %##ãææ&--ݵµ®833S]]\çÅb±FFF`@Ê^¥4 û:îúPª««›šš&Mš*w$ †œguf‰TQQËKKK…„„ÀΜžž>vìØnfÀ«£P¨“'OúõcöÁ… z-OKKëµ044´[!ƒÁHOOïYùëׯñññ=ËÓÓÓ ›wÒÑÑ‘‘‘ѳ<..îÛ·o=ËÿþýÛÙÙÉ„Ö]uë8''§µµµ[á—/_»Òh´ÜÜÜn…yyy---L&³´´ÔÛÛ,¬©©©ªªêV³­­-;;»[áóçÏËËË™Lfsss~~>XXWWWQQÑ­f{{{fff·_TTTÔØØØÿCa_>¬ÖZ[[srrÀB"‘~·ºÞL×Í*,))!“Éàqfff{{;“ÉlhhÀápì<ˆÒÒR‰ggg·µµ1™Ìüü|ÿn5»þRVaYY@û›»»;X~úyØááǵµµÝZëúˆ‹‹‹) xœ‘‘ÑÑÑÑ”º÷ZØ×‰]»@(++ñx<‘HïÝ»766…ÕÕÕÕÕÕýw˜o•„úš(………­^½ž3÷,X>Ü?kÖ,YYYXÐÝ¿~ý áeBBBLMMÏž=ÛµỸ¸˜˜˜ ûÖÅÁ¡|¾}û6kÖ,—9sæ0™ÌÕ«WïÙ³ÇÎÎNYYùïß¿‚ر ”755ûIDDDWØæÌ™“ŸŸÿõëWPŒ£G>xð ŸË'%%e°Ášû™$ÆÖÖF³ÊÏ;·~ýzgggssó‘/°¯¡×Î;íììÐhôÉ“'™LæÛ·o×­[‡F£íììýüüÖ¯_¿dÉ’äädp„ommF£À¹LW ÇÀ™3gX…t:ÝÊÊÊËË‹Éd¢Ñhmmm¦@aii¹|ùò-[¶„‡‡3™ÌÜÜ\sss4maaQXX˜““³lÙ2GGG Úk—.]joo÷îÝžMùùùó¾9sæ¼{÷®³³ÓÖÖ–D"µ¶¶š››ß¿Ÿ)€lß¾|\]]™L¦¯¯ïúõëÑh´½½=•J%‰6l`u˜úúz++«Ã‡oÚ´‰F£ukÊÃÃÃÑÑ‘Éd¾{÷‰D²f%þþþ/^¼`2™fff¾¾¾>>>L&3""BSS“ÏåsýúõÝ»woݺÕÚÚœ®.[¶ F¯\¹²¸¸¸g‡9räÈ®]»V­ZUZZÚ­©?þLž<™D"åäähjj‚} ‡ÃÍž=;55•F£ééé¡Ñh戠ϭ9d2ÙÌÌ TÏ%%%ªªªÛ·o_¹r¥ƒƒCuuõçÏŸÝÝÝeddBBB ;väÈ‘””ÐÜ ¶£¢¢2iÒ¤ÈÈÈn{t[ZZ‚‚‚¼½½Ø´iÓ«W¯Kѧ§§III¹ºº®\¹‰Dš››9räÅ‹ÑÑÑd2y÷îÝK–,¹{÷nKK‹¹¹ùçÏŸ544öîÝkkk nëÛstt4‘èëë ½y󦾾þíÛ·bbb6lÄ!‰DZºtéÞ½{/^\VV¦¦¦¶k×.ssskk뺺ºúúz …Á`nܸA¥R÷ïß?wîÜC‡9;;§§§‹‹‹³VTUU}}}oÞ¼ €µµõ¶mÛX1Žííí¸|ùrGG‡hÂÿýû·Ï¥K—ø_DBBB÷ïß¿téRPP‰‰‰……ÅáÇ=zWUUåììlfföàÁ=zTQQñêÕ«ÈÈH???GGGÖ«¸¸¸¿¿¿¥¥¥‚‚‚‚‚ÂôéÓAÑ%&&ÊÊÊ‚™ë7lØÀêo‚NŸ KCCÃÙÙ;;»––yyù{÷î}ùòåË—/nnn–––àpéÑ£Gàê…B©©©)))y÷î••kM 7iÒ$p¥fÄ`mm ®­hkk %%•žž~àÀäää­[·ZYY9räÝ»w;vì`0•••?+..þöíÛ”)SX¾âââ$IQQñÌ™3ªªªGމˆˆ P(;vì³K©ªª ¢|´´´Àä}666­­­àΡèèhpª8qâD2™ìää4}út…²²²ÖÖÖòòr<ÿöí[KKKÖΰ~¶»744ÈËË»ººª©©:tèóçÏ>>>W®\9sæÌ RUçÏŸ—––Þ¹sgTT”””ÔŸ?œþü¹{÷n4ýúõë={öP^^^PPàêêJ&“333׬YÃê?àJô¿CŸ «®®‹Åššš‚ ·nÝZ²dÉž={´µµsrrðxü«W¯ž={våʕ۷o#ˆM›6ÙÚÚÆÆÆÎš5ËÇLJå&ÓS8Þ´iSppðúõëKp à :ï<}útüøñ{öì!“ÉŸ?~øðá›7oÂÃý¼¼ŒŒŒÄåË—edd‚ƒƒ­¬¬"##»½<þüñãÇ­­­§NzåÊ&“¹råÊC‡Y[[ nǪ®®þõë—±±1Ønß¾½lÙ²;w‚'~~~GŽikk»q㆕•غuëúõ룢¢æÌ™óôéS–CNû‰¹¹ù§OŸfÍš~ù¨TêòåËÑh´­­íÔ©SsrrBBB|||þüù#(‘ƒƒƒ÷îÝ ÊÇËËkÊ”)»víª©©IHHxüøñû÷ï?|øðàÁƒ  SSS SZZJ JKKYýG^^@ÄÅÅ566Ö××WWWƒ¾ÂÂÂ………ÙÙÙ&LˆŒŒÜ÷Ÿ®Ðéô—/_æææv+?zôè¦M›¾ÿ.pò¹~ýzuu5$M0³!;•ÛÚÚnݺõþý{íW"C¤½½½kjj0L¯äääV­Z•””„Çãmllà™yBB´iÓ·mÛöâŋÇÃ2éJ^^“'OîV~ãÆ’’’àà`qq ·y IDATñ¾Œl>|xæÌ6닉‰½+88xݺu÷{{7º{{{qܨ···¡¡á©S§ú¯fddTXXÈʯ)@ÄÇÇÇÅÅAØàÇW­ZªòÆÆFA‹p8‡ƒ°µ¯_¿nݺµ×ÿŽ?ÞÅÅ¥¸¸ØÃÃCPä—UW\¸p!g6¯²²²¢°V¯^ͱé÷ïß¿FFFzzzìTF£Ñþþþ555‚%5CCC###Hš¢ÑhçÏŸÿD"‘ÚÚÚ©©©­°ÔÕÕÕÕÕ¡jíÉ“'»ví꿎µµµ“““‡‡GפÙ|‹‘‘$ãAŸŸojjÊÁ¹{öìyôèÑQXŠŠŠ`úõÁòüùs--­©S§²Y_RRrÖ¬Yß¾},©ÉÈÈ@b.mjjzùò¥“““œœ«ÐÞÞ> @ –˜˜˜`{üýý7lØ0`kÂÂÂ***NNN>>>ü?D…ªÿ<|øpïÞ½œ+..¾hÑ¢ÈÈÈ‘ °8 ££ÃÇÇÇÄÄd° ÆÆÆRRR_¾|ù þüÑÐÐPQQéZ($$$///ˆ3ehéìì|óæŽŽÎÌ™3Ù½ººÚÏÏïèÑ£·`mmÈ·ò±°°X¶l7-ÄÆÆ.Y²„û;‘‘‘iiix…Å>eeeÑÑÑ[¶láÒÈ*$$tðàÁÛ·oxÓ…B‰ŒŒ´±±îOø+V¬8ƒ($TWW‡……999q¶ìóÿ»µ°ð‘#Gîß¿/(ŸÀAQPP ¤¤¤¤¤Ikh4ÚÓÓS°VqqqSS;ç¿ÿÞÂÂ’-uªªªBBBáâPSSS]]ÍÁ‰¥¥¥t:ÝÁÁ¡mÚtuuüø!ˆo•J¥R©œH >|ø`oo/++Ëå=Œ=ZJJª°°?ûOmm-gçvttx{{ïØ±ª›QUU÷¥°ÂÊÊÊ"“ÉýŸÉd2?|ø`bbá–@A16———sàt—––öñãG2™<~üx6í ß¿ÐQ$…Bá@Í=}útÛ¶m]<¸aÛ¶mqqqx<žßäƒÇã9vÚ¬¬¬5j€ð~äåå|ßùZa­Y³f@ÇÑàà`UUUïfÊ”)---|ØÃºÁã(hewvvž8q"›§Œ5JSS3))IàŽ£d2ùÖ­[§N’””„ðN.\ȇ3FFF†††œ{÷î]ŽW·úb÷îÝ?`…ÅÎLPMMËUÕ^™7o^bbâ3:°ceï•Å‹ÿ jÁÁÁÞÞÞ'Ož„¼åÿþûoìØ±Ÿ>}‚ ´¶¶Š–UUUÂÉÂzÿþ½ºº:´c+Ó§O¯««ÜýžÓ “ŸŸ? •½W”•••••Á­¿# µcÇQQÑ¡hßÄÄD@Mݨ­­ÅápÆÆÆCѸ¶¶vII‰ *,OOÏœœÞk+åË—þü™Ÿ¥2`µ„„„7nØÛÛ³ceï‹-[¶øùùA¦…üüüüüüþë´··§¥¥¹¸¸èèèÌ;ªÈP=‘’’²´´ä+/‡ÁÚjÁåˆ÷TrŒ ˜±z‹ÐhtOŸuÐÊ>ÔÚ ]]]ÇÏ»X---×®]Û×Á5—3gÎ455]¸paôèÑÜ\KLL …B ÖSGG§?¾††ÿììl 3X_v066ÎÌÌlnnæù¬]»ÖÒÒ’ýúÍÍÍ/_¾Ü¸q#7q4>@€d˜§„µµµ§OŸ†ÜÊÞ{÷î}øð¡ ŽÛ‰DâñãÇíìì\]]{n»áŒC‡ݹsgÄ̯_¿îåå5{öì¾ý‡‚“'O^½zUÅÕÒÒróæÍ#GŽpïêÑ?ÿý÷_ff&ŸKƒ­~þþþD"ñâÅ‹Cde艚šZMM “É”ŽõâÅ ‰D§Ó¯\¹",, íÂó´iÓ222¦M›& Jª¾¾þÍ›7  åøñã***<~²RRR ‚"4<ÔÐÐàææmwê•É“'çååý÷ߦ°ÊËËSRRŠŠŠ‚ƒƒÁ(_S§Nå™¶@HHèÔ©SW®\quuå¥8êêê°X¬ˆˆH?ƒ£ÖÖÖÈÈÈŒŒ III •——G ضm›¢¢¢ššÚPܘ•••¯¯¯ŠŠ ÿ'ïÀãñ©©©`ÿ ¦¦¦¨¨…BÙÚÚ***c4ñÜ»w³ý‰ÐŽ˜¢¢¢²²²>}úÔ—öß;MMM[[[#‹õAXXØ­BvûuH$’³žÐ‹ÂG¡PàÛ8cÆ MMÍay®ŠŠŠ"""uuuÝ¢¯ UUUÇŽ“011é?ú °°0 …’‘‘QRRB¡PfffÊÊÊC}{222†††ñññöööü0í•––îõ¿¬þN48ŽÙ-òòòŠŠŠ%%%l:îróBŽ;¶¯ÿ"°ÿ(+++**öZgæÌ™ý´0Dˆ‹‹·µµ é%˜Læ«W¯Èd2çžú¼I"Àùùù=꫟›7o&%% c v8{ö,•JÞ‡ÒÔÔtûöm"‘ÈË$PQRRrïÞ½!½DNNÎÓ§Oy™„Bbcc#""†¨ñööv__ßôôtnáëDª“&MjkkRÇ÷âââÇëë뻸¸Ìž=›Ïg[‡öýá7nÜØ¾}{_C>GKKK\\|èüÚrss±X,„ýxÿÆ èÂ1zzz\Úa{WX~~~|âE6þü¯_¿Qã·nÝŠŠŠ:}ú´¾¾þ NLLL„*‰À`§É:::ÃåI¥RÏŸ?áÂ…}¦JKKKKKù󺕙™™””ÄŽ¶JHHàÏíCÑreee}}ýôéÓ¹l§w…µlÙ2.½‡ B__ŸH$B.Ä´´´Û·o[[[ïÛ·³»®t§VVV111lÆÒ€ÖnõâÅ‹cÇŽ±SyÔ¨Q|»80iÒ¤ŽŽÈ¿ÇYYYÿþeÓQÃÀÀ€ûWW€(++ ‡Ä”Ù»ÂRQQ0‰6—,Y²$&&ÂSSS³³³­¬¬8Ž3Áñ÷ íØ±ãõë×¼t¬MII ܸq#›þèüÓz²råʈˆhg‚¿ÿvpp`35‰„*"äñs®šÙ³gC•ÂãøñãçÎëËeÈæÚµkuuuœØÒÒrí򵮮FofXü°z:¶¼zõ*##ò–CBBÑéôùóçóùX¨3fLEE›‹Å ?þüóçÏ®]»¸OÈç,_¾< @WW—³Ó©T*‹…*ZÉÀ6¬~ø /«V­ª¨¨HKK°&N?qâDssóÆ!÷)c3€/íYX,ƒÁp篥¥ÅÃÃcãÆóçÏ?pà÷ÚŠ~|òZ²*²­­-00ðÁƒâââgÏžå^[qÀÇŒ=º¶¶–³•æææ§OŸ®Y³f(|9{a¡Ñh¾Íâ¹qãFÿÎÎÎ~¿…††¦¥¥]¾|™M¿˜ÁbiiY\\ÌWbÙ±cGUUÕåË——.]:gÎ6ÏŠˆˆHMMmoo?pàÀ‰' º™øñ S¦L§}‘““Ä`0–/_aƒµk×ògþ±nƒƒ?ö¨²Wâââ¾~ýŠF£‡(Ö  M YØÙÙ½{÷.==ÝÑѱ[ºÍ>üýû·¥¥ÅÝÝ}ˆ´?÷ìÙsñâÅ„„ccãE‹õUÓßß¿µµµ¬¬ŒL&»¹¹!‘HŠ;-`Ò“yóæu-LHH())yùòåÖ­[¥¥¥y[‰O011ñóóËÍÍeÇÔP^^SQQ1kÖ¬‹/Ý] ä+-,,lcc“›› îk›9sfvv68$\¿~ý‰' \F(TUUèÕmll̳íDùùù...‘€””"‘8iÒ$---Þ\1$$äÖ­[o߾全ÙÙÙׯ8YYYöC;ÂâgV7”””ÌÍÍy|Q>´aõŰ˜“ņ¡6›„ ‹5›áýûÕßý0000¬°```†^¦„•••iii%%%‚bƒ"ÆŽÛktͶ¶˜˜˜ììl9990lù¿‰””T¯ ‘åååééépÿ`Ñ¢ERRRÝ i4Z\\\nnnLLŒ¥ðiié… B °„´´4™L>wîD"QJJ ŒeS]]­ªª &1®¬¬dåóèõ˜ÉdVWWƒÎcmmmMMM`²†^+wtt‰DÐ%¯¥¥¥­­ |– bbbàª_mm­¢¢"¸ÀÜk#AFFÜPRUU5jÔ(6oµ³³³¦¦¼ÕÖÖÖææf%%¥uëÖõª°„„„¤¥¥ÃÂÂRRR Óéd2ô¤§R© ´m“H$IIIPn555( ?º(…BA `„©úúz$)&&ÆÎÝv“@m·---­­­`˜^+·µµ566‚J¶©©©³³¼U"‘(-- ÊmÀG\WW§   **:zôè^–ˆˆˆ´´4‘HûO_í´··744€rëë¡ÔÖÖ‚YˆX”›°°0¸¾Y__/''º¶ôÚ‰D’µFMM²²2èì2(!Óét …Ê­ë#fU`0õõõàS Ñh4 | Ó§Oï©°Àþ#&&výúuQQÑ®¯FSS“ÉCeu}(ƒễúiííí$ |ïš››ét:ë½o¾¶¶VIIIDD¤µµ•J¥‚·ÚØØ($$> ++ >…ªª*555ÐK¦ÿ«kjjr °úÜü|îÜ9𠨨¨¡¡<þû÷o{{;xœ’’ªÜõ˜u"ƒÁHMMóóóû9‘@ ܹs‡uŒÃáÀãÒÒÒúúzð8++‹µ·×+P(ð8--­££ƒÍ[íèèHKKÉdraaရ0YçR©ÔÜÜ\𸶶¶¬¬ <...&‘Hàqzz:Nïvbyy9˜{‘Édæææ²²K x·]ËÛÚÚX›Ÿ‰DbIII· çÏŸgåÈËË«««+**ÀãÂÂB2™Üó÷zÅœœœææföåÓ×/jnnÎÉÉéçg¶··ÿýû·çC©¨¨`mÎËË_r&“yþüùÎÎÎn –””°òeddd´µµ±)Ø®Ç]qMMMyyy·ét:+·‰D*..P>÷ïß÷Nw}5úz(];ó€w;¨þC£Ñ²²²ÀãúúúÒÒRð‡ÃðøÎ;à1…B)(( +++«ªªXÉbX‘RSS ›·Ê½»5tì+“&M‚§Ð<€Édž:uêôéÓ|”rØyúôéÌ™3g̘1t—øôéSggç ÊŠÄÄD–\||¼‘‘QÏáXW""" ßK<2î&L˜0aüžðLayxx477âè‹7oÞpK 'gÏž=tèÐñãÇ¿ÿ^]]½jÕª!]ÎOJJêúˆþüI£Ñú?åË—/\úׯ_ÒÒÒ|°l6,°°0ooï¶¶¶Ó§Oƒ#íéÓ§Ÿ8q¢´´TQQqþüù»víÊÎÎF£ÑŠŠŠK—.ݶmë\oo﨨(‰„Á`ŠŠŠêêêH$’§§gss³Ïýû÷›ššôõõ³²²úÿªð-h4šF£ÕÕÕݽ{W]]ýÉ“'éééµµµ£FÂ`0÷îÝ;zô(‹uss‹ŒŒþÜÐÐ0f̘ììl"‘¸}ûvðO0Q»kÆ7gΟŸ¿iÓ¦—/_®Y³†H$fee9s†Édš™™ýúõ+##cûöí¬™¹À±`Á‚ÆÆÆÐÐи¸8ƒabbB ¼½½µµµi4ÚéÓ§Á´”“'Oîèè âp8+++&“éêêzèСœœœ­[·º»»3™ÌÇ'&&îÞ½;66üô± Ê–-[233ñx<ƒÁb±›7o¦Óé7n|¸|ù2@hhh Ž?~ü8pàÀÏŸ?7nÜØÞÞ~úôéwïÞ999mÞ¼yåÊ•` ›7onllüúõëÁƒ™Lf]]Ý®]»h4Ú‰'˜Lfvvö¦M›rss'OžŒÇãkjjöìÙÓÜÜ|úôé²²2IIIv µ|HŸ#,KK˳gÏJJJzzzfee…»víš:u*H$²½½½¢¢âáÇ"//‹Å®^½\2(--½råJggç—/_f̘qîÜ9EEEV48KKËÒÒÒØØX]]]ÁÛ¯§§çì쬪ªêææ€©©©’’R¯{;„……µ´´œÁýÆ`áÕ«W%%%q8\]]‹‹KQQ‘ŸŸŸŒŒÌâÅ‹ù<:›XXXœ9sFBBâîÝ»ÉÉÉ[·n3f •JíYyôèÑwîÜ ýöí3gÎܵk¨ËŠ‹‹Ïž=K¡P~üøamm}ìØ1™n{Œ–.]zêÔ)11±G555…„„àñxp¬„Åbµ´´$%%Áe)´´´ ¸°ÃZ_ÿUQQÑÑÑ¡¦¦Æ›€ëîîî222»wŠKÀ5å={ö”––jjj644lÙ²EDDäòåË\¼x±®®Že¹SVV–••ÕÒÒ{ …’‘‘QWWß¹s'‰Dó*¡Ñhp™””TjjjEE…°°0¸z ¡¡Ñ-v€ Ú°ŠŠŠ Þ¿?{öì+W®ôsþõë×1Ì… @m¢¥¥…Á`nÞ¼ùèÑ£žžJû÷ïÏÍÍ=r䈀¾ááá‹/>}útkkë€é|¨Tê›7oìííýýýÍÌ̺ý×ÑуÁ?~üÚµk#ÆÆ”ŸŸ_VVööíÛÙ³g»»»XßÓÓsáÂ…·nÝ:}út·Íž=ƒÁ¸»»{{{÷znVV™L~õêÕìÙ³/^¼¨¡¡QRRbllÌrªè—ü?¾ÿ²bÅŠüüüØØXÞH),,¬[É·oß*++÷ïßÿùóç®Õ"##ƒ‚‚–-[–‘‘A¥RãããûjÇ'$$lÙ²%(([t¥¶¶V__ÿíÛ· ãÓ§Oõõõ#Ć5aÂ,ûçÏ*•jgg×k ~ïÞ½¬¬, ÅRX666 ¹*,,ìèÑ£=O\ºt©¡¡á† ÷…´´´9uêÔïß¿·mÛ&$$”œœìææöâÅ 111‘ÄÄÄK—.}úôIKKKLL¬©©é÷ïßááá]}~~~ÞÞÞžžžþþþ111ÖÖÖ[¶lÁãñÝ¢:::qqqþü!‘HNNNãÇß¾}»……ŵk×8%6oÞ\VVf¸ÐÔÔÄb± 'Ož?~<«3gÎ\½zÕÓÓ3((èÖ­[.\Xºté¸q㺎€ôôôöíÛ÷çÏŸŠŠŠÃ‡€Á`<ØÏÚØØØØØ°þܲeËܹsåääÌÌ̪««y ¥¼¼xxx€É¨555333cbbŽ;F&“]]]>œ‘‘ ¦ºPUU TSSë+R£¼¼|YYYrr²——WJJÊ’%Kºþ×ÊÊŠ%ØmÛ¶ñ2^TôéÖ@$[[[PSSsÄÄÄš››Á…X …ËAS …Aèt:¨¼ÕÕÕ[ZZDEEEEEA? p©ž@ HJJ tps¸˜˜ËŸB¡üúõ 4755>|øÐ¡CšššH$²±±‘Š^AA¡££CVVt®#‘H4 œæ°ä†D"%%%:Ï@-»£Gÿ¼zõªÐ½{÷ètº§§çرcW¯^-)) :^‚'JII ³&}--- """ ™ìoH$RXX˜µ\S__æ¿]±Xì7À°¬îÇê± +V·põà%„……ÅÅÅEDD FMM ËÑq(§Æ üiMMMÒÒÒ¬÷TOd2™%ÆÆÆF$ɺ7ð1 °ÿ°ÞJ2™ÌZ#/K UTT1`[~X0l’˜˜¸mÛ6]0æ§N¢R©÷îݺK¤§§?xðÀÑÑ‘ƒìd0°Âú· ©©©Ë–-ƒEÑ+ÙÙÙúúú°(``…3ÂÃËÀÀÀÀ VX000°Â‚ ¬°````…+,XaÁÀÀÀ VX0000°Â‚ ¬°`````…+,XaÁÀÀÀ°A/QèËËËSRRddd–.] íÅòòòÆß5]… ÒÚÚ €¹¹9´i«I$˜=åÿ|R„…׬Y#@òÁãñ©©©²²²ÝR¶pCccc\\x¼téÒ®)°Ž––0¡……E·\SXX&566VSSû·–¸¸8 …zþü9´ «³³300@ôÌ='`ƒRaa 8sæL0E%T<~ü¸gâÂÎÎN—qãÆMš4I^^žÏå#!!B¡^¼xÁ¥Â*--­««ÊÉÉ-^¼,¿qㆈˆÈÊ•+Y)E B¡LLLFÅq;ÿþ¥Óé?~ü(//Ÿ8q¢žž^zzzrr²`}Þ PX******ÁÁÁÐ^©®®NBB¢¦¦FÐE&&&6wîÜ?þ@ÛlRR’¶¶öܹs{þkÞ¼y¥¥¥IIIÉÉÉëׯ=z4?ËGUUUUU•³þÓÔÔÔØØèççWWW7nÜŒXý¸áIDAT8---[[Û®uæÎK&“#""^¿~­¥¥eoo¯¤¤$@ýG\\|îܹ?þäà\@ <==eeeËÊÊ6lØ`ee¥¡¡Áú¶544üsSÂ!âÆ`:èêêê‘=jåŒïß¿ÛÛÛ÷õßqãÆ7ŽD"½|ùROOÏÜÜ|„ý|‰tùòeYYY999'''•~*ËËË;:::::Þ¹sçñãÇRRR` ÕÌ?‚‚‚”••ÅÅÅwíÚ5kÖ¬ó5é]aùùù•””@x™Â‰' ¤¤D$]a%&&&$$¬[·ªÓÒÒTUU:)**º¸¸DGGß¼yÓÉɉoG¥¥¥¥¥¥ìÔüóçÏ;w ÆÔ©S1Ì`/tèÐ!îß¿üøñQ£F¡Ñhè? ‰‰‰›6mbgHåíí]]]=gΜå3f̘ÌÌÌQa-[¶Œ³!k_øúúž8q---§§§'ÐRÓ××700€°ÁÏŸ?ïܹ“ÍÊË–-ÓÓÓ{óæ••7F¡cÔ¨Qý߉DЉ‰)++SWW¿zõj·ÌáƒåÀ`>d—U«V-X°€ÏûÁôéÓû¯óáÇÔÔTiié­[·²ù?~<´ã >¤w·¨Ö/ˆ‰‰111óe/X° !!AÐ¥†D"YY¿!ÈÈÈ(++³ÊèÑ£7nÜøäÉþ”„„D_ý§ººúÝ»w§N¢P(›6mrppPWWç~á@¨««c0˜¦¦¦+W®¤¤¤ðyÿ‘““ëõ_4-!!ÁÅÅEUUÕÕÕõÔ©S°ýdà„P©Ôïß¿_¸p¡ëç%-- ÚŠàB&“ýüü\]]9èôÆÆÆQQQ‚bÏb0oß¾­ªª233{üøñ]eÕªUsæÌ‰ŽŽ®¬¬œ7ož‚‚‚ ô*•š––eddÄÁìø¡÷VGGGgg'$ Y»vm·ù‚ ¯2 ƒIS+V¬âàÜeË– N=|Eggg·þSVVvêÔ)£G éÕ•””ìííEEEEEE¬?‹‹‹ÃÃï_¿>sæLžÝüyóΜ9óðáC???~ë?Ÿ>}ŠŽŽfýíîîîììÜíÓîÂ:xðà”)S¸ÿÌFGG/_¾|äImÅŠ|ïÝ»çììÌM ’’’G½xñ"_ÉgÒ¤I“&M ¿~ýºcÇŽa¹WW×iÓ¦½zõНä³jÕ* ÖÇÉd=zÚ]ÿ–‚„[·nmß¾½WãâÚµkCBBþqч††š››s¿¸!--­¤¤TVVƇ¿‡Ã%$$8::ã~,}}}}}ýãÇóá Zjj*@077—¤`8TXx<¾¹¹™›vóóóeddúr,RSS«®®\©Õ×××ÕÕq9)‘‘™7o$÷³víÚèèè––>‘Oóÿðõõݶm›¸¸øðÞ¾¾þÕ«WÛÛÛëëëù¤ÿ„ÆÆÆäädw\ //O&“ÿ9…•’’B ¸ÑV_¿~ݽ{w_&L˜ÐÕÆ!pssÿt:===BgeMMÍÑ£GCë:Ç $‰D"…„„XZZ"~¸%¡££€Çã‡ýf ‹ŠŠÂÂÂŒŒŒTUU!lÙÁÁáõë×ÿœÂ²²²ÒÔÔä¬Åœœœïß¿ïÚµ«ÿjóæÍKLLP©Ï™3‡³si4Ú•+WŽ= ¡'+V¬€d444$$$ÊËËùmòÁƒïÞ½;ì·1gÎcccع2…Å1ÙÙÙááá .°æ²eËâããÛÛÛÿ)q744ŒÈ_‡B¡øÄNÇS…åé陓“3¨iNrròׯ_·mÛÆ v1 ›6mòõõD©…‡‡v•377700ÐÆÆfèZM˜0L&óƒÎÊÏχÄoètVUUÕ0¾Ø!!!áááC´ÔÉÉéåË—ÿ–ÂB£ÑS§Ne³‰ÆÆF__ß’’’íV=_°’’¨\êy‰¥¥%›>~ ƒL&‡……a±XDnÚ±cÇóçχ]>::::::|ûøddd6oÞüðáÃár‚_»v­¥¥å±cdž¢ñ)S¦”——S©TxJØ .\¸sçÎòåËíìì88}âĉ………#x{ïÞ½­[·"‘È;vð X( …"‘Hüàø®¢¢ÂÏAåää —¾;ü X¼xqWOú]aáñøÇ/_¾ÜÅÅåÈ‘#gΜá8Rð¶mÛ^¼x1ÂdÊ`0?~|ãÆ — ¼ÿ~þüù<»º‘‘ѯ_¿øÁ˜2`•áåÌ™3îîî#ò­655ÍËË#‰#ï§õ­¡²²2--­¤¤$<<¼ky^^èí9vìX ‹%K–hkks{yyyy0¨à*ÃK[[[LLLvv¶œœ …b•c±X:~âvìØ!''7,ÁªÖ¯_æÌ™™3gJJJ‹|ÊËËÓÓÓùßô+***..N¥R¡MiÑØØ˜˜˜8yòä &ôZF£ÅÅÅåææé¯366þõë×Ê•+ùPòÑÑÑÆÆÆ}Ø´ÂB ÒÒÒ¢¢¢Ý¶ 8::Eh33³oß¾A½s¨’––“’’ê*¢ .ðIB •ºº:Ž=é¸ÿIKKó‰¿hÿ¨««WTTLž<™ãššš@⨨¨šš!''7oÞ¼~ÜVXýgHÚ¢E‹"##ccc¡õ¤ç€´´4p8\DDhY¶l™°0‡Æ¨^.’Mw*î™;w®««+„)¸ŸÐ½ÿ¾[⃮ˆ‰‰-\¸0##ÃÄÄÚ¬9P±lÙ²èèhöC˜–ïß¿;¶¯ß®¦¦¦¦¦ÖmxΟ,\¸0..n° ‹B¡´µµýüù311±ººzüøñ“'O3fŒ‹‹ ;îu .äAˆA ‹3gΘššòx¬]__Ïd2=zD¡P`9Ǻ¹¹±ïB0…Å{@GvB\󀂂Aw½›‹åA‡WRR:|øð†¥ýõë×ïß¿+++étºÍÌ™3………‡Î лš7o^ÏÄCj:tèÐÝ»w8ÀeWà’ÄÄĹsçxS¦LÑÕÕåç×l̘1åååжI£Ñ>|xàÀwA¢P¨®Ëü èÞón³²²ž?ÞÖÖ6~üx+++%%%ΌĽ¢««Ë¾Ÿ#—HII™››ß½{×ÉÉIVVªfkkkƒ‚‚¾|ùbkkkii9f̘¡ØmÆ®Â=z4Éihhˆˆˆàp8îW9&((HKK‹ï!EEEEEE~~­­­!l3;;[MM.))9\k”ƒeÚ´i¬´Òäææ>{öLOOÏÊÊÊÐÐp(bã(**ò8ؼ­­-ƒ™;w.÷6øÊÊÊoß¾•••Í™3ÇÊÊ Úh"Ì?]gß¾}Ož<.§Çàà`UUUŽc0ð§Î‚0àLfffVVV?©^GÍÍÍ_¿~Åb±óçÏwrrš;wî°Gò‚ UUU77·öööèèhŽM´ÞÞÞoß¾ÕÖÖ>~üøÜ¹sy¬­øKa`ooÀûë¶··C Š;v,T³ÂÌÌÌ?þlݺÑ`0 …²cÇŽÕ«WÈhaaÁd21 gQRüüüf̘F£ ‡ë'@³ù*¦OŸ^___YYÉË‹’Éäk×®¹¹¹±ïWÁÁægÞUv¢´´´ôôôAi+>ßüÜææævúôiÞ¨*póó°üRsss77·k×®…††êÄgÏžM›6mxŸ›Ÿ¡eïÞ½ááá<[cЉ‰ñóólŠsö7?#šššÜG×ÌÈÈÈÉÉìLÏ7?÷ÄÃÃÃÅÅED„G^>àæçaü½h4ZAAáܹslögÏž™ššrŸ˜f¤M ””ܸqcdd$ÆYAAA ÃÑÑq¤¦àfŠM¥RãââÒÒÒÂmc Gá ÿ#--=oÞ¼'N„††¾|ùrÀô¹¹¹ü ­øQaÒܲeËÛ·o‡n÷&@pqqQSS[¾|¹%æÙ¬°¢¢Âßß¿­­mË–-œ%y ZZZþÍ[ÒÒÒ444ŒŒŒôòòê+/ …B6œ77ô>. 4}åÊ•;w*++CøÎtttøúúÖÔÔp㦠ڰøÿ#9T Æ?RRRlllÔÕÕ9»®Ù°„„„x‘ ´añÉÖ=====½âââׯ_·´´œ:uª›G•——×¾}ûøZa¡Ñh[¾{åôéÓ×®]c06l€Ä&âååUUUegg§§§ÇM;–––ÅÅÅüÿ6ÊÈȰÈ­¾¾þÅ‹4múôéGŽáæºdò°°ðõõ=zô(//ºvíZ~ §­­}ôèQ …röìY…)S¦ðçR©Ÿ÷§“'O644~úô …BmذaP{¤ËËË¿~ýÚØØøñãÇ©S§îÛ·oìØ±¼qÉåÜþG_ãÍ7oÞ€F YYÙmÛ¶IKKÿkI=ÕÔÔø9Ö /A"‘×®]«««ËÍÍ=þ¼¿-.‰ð¿víÚUQQQ__éÒ¥ÖÖV°|âĉ=?ã ]Ç ÅÂÂBWWwÆ ü™Ä…ƒ¬ÜÜÜøøxðϬ¬¬®»DEDDÀP±ƒýŒ$ú \õÏ¢¢¢¢¢¢2sæÌ´´4—ÚÚZþùÆ õÖÚÓÓ3&&&22’ŸÅZXXØÓP²`Áhã±õJxx8ƒñññáÏð2=ï¶«ÁbܸqC}Åüü|ˆ03,„„„ܺuëíÛ·ÃâQ ákVÿLœ8qâĉÃriA±a±î–ÇW8?,Ç6,AA ¬°````†~JX]]‘‘QZZõ/‹f̘1½½jkkKHHÈËËKLL”¨OC”””™™YÏòÊÊJдÿ÷ÌÌÌzº¤¶¶¶~ýúµ   !!a;-ˆ´´4qkaEGG³6ùúú²éžüÁƒðæÍŠŠŠµµµM®xÿþýçÝðÔz„B!œ/þ©'¬­­UTTÎápàîïáÇÃÃÀ755ÁKùµ£BÕüúë¯ I¨®®†gŸKÈÞ*<22gQƒOÉdUUU€OOO···o]8|>ž “É€·µµÁÁ6ÊËËAB¦­´ö¹nM,×××Î`0zzz]*൵µ‰@ÌÎÎÂqƒƒƒCCC€·´´ðx<ÀËÊÊÔjõÖ[òÜ€6@VV "‘ðÁÁÁõõuÀûûûᓵ9\P­V ¾¼¼<66¶IÁÅÅEøÂ‹Å|jjJ N¥Re2Ù&Wd0b±ðG©Tª-6U¥R=zô𥥥ññqèY€ËJ¥R8ŸÏg³Ù€ONN …BÀ‡††”JåŸ ²Ùl>ŸøèèèÊÊÊ[«}\¡PP(X†L&óO'h4šììlÀ% NœÇãq8ÀÇÇÇ—––ž|ÄO½âÈÈÈêêêÖå³Ñ­®®ŽŒŒlr›ëë냃ƒO>‡Ããñ§Óé‰ðììlFó§ ™Læââ"à E¡PlQ°Ú|eeettôÉG T*•CCC€ …ÂÉÉÉgʧ¤¤dnn¼ðCyüø1—Ë}ò¡h+ó3[û\ú#“ɨT*à`jj p‹rI@„ÃဠÅb1ƒÁgggggg[^^|``@­Vo±©{¶+[÷.¶ …L&£P¨]Qìâ/`hhˆF£½ˆ/ÉéîççwïÞ=øç7ÂÂÂRSSƒƒƒår98¨R©ÂÃÃ"##¯^½úïyº U'T xyya0oooíéíâââÐÐP4›Ž;VUUŒ@ ‚‚‚þQ1é?þÓO?Á? ÃÃÓ““CCCaûT©T†††&%%EDD|óÍ7ÿª"//O{³ÔüqäÈ ããã£h¡¨¨èìÙ³)))!!!°ëæï‚§§gmm-Xø~úôém ŒµÑÐK*•ÆÆÆ¢Ñh %‘H2339ƒÁ ¬­­MKK;wî\@@€R©¤R©666Ÿ|ò \ƒÁÀiÁ¸Œßyç•••¡¡![[Ûúúzh'cjjêÌ™3( ‹ÅBTZZÚÕÕ% /\¸ÐÙÙÝÕÕu÷î]àþƒËVTT|ûí·N¶Ñ<=={zz4ƒƒCRR8N&“Î;G$çççCBBÀñ€€€²²²ŒŒ 4íààpýúu4ýñÇÃV¡6>üðC ]]Ý›7o¾úê«yyy/T>‰…B¡ÑèØØX©TúÕW_q¹Ü±±1¡P˜žžF£ Èd2‰Œ‰‰m 77·þþ~…BaooùòeX!ƒ‚‚äryssóáǡ¸¸¸ÐÐÐéééï¾û®··waaáüùóííí .\èíí]]]uwwwrr6šB¡ »}û6AŸ}ö™‹‹ \ajjj__èª`ƒn}}=111)))**ŠJ¥†……ã'Ož,++ËÊÊB£ÑöööX,F‡„„ÀÞm¸»»ëëë[XX}}ý‚‚‚mÚ†VJJJZZA™™™mmmmmm¾¾¾/^¤P(ÍÍÍÇŽãóù%%%ÅÅÅà}¨©©Ñ.. SRR|||`Ç—_~ ;SNŸ>]ZZº£µÍÞÞ¾££cyy922R °Ùl__ß+W®ÉårKKËþþþ¨¨(0¶‚|_ýµ‡‡ìÚ»w‡àׯ_‡?ÉÉÉ===|>t1ñññßÿ}KKËñãÇ»»»›ƒÁ´¶¶BD"‘ Á ÊÏÏwtt¬ªªJJJb±Xd2ù…ÊçÒ¥K¥¥¥uvv677Ÿ:u …BgŸŸß­[· òððXXXpww'‰ `ee¥··7àùùù(J»ÚßÿýÌ™3999;½·ª©©ñ÷÷—H$mmm™™™333ÞÞÞ999%%%‰‰DR(‰úñÌÌÌøøx؉ì‚úúúììì´«]\\LNN>qâìí•H$~~~kkkååå}}}/^¬¬¬llløà77·§î½xFF …zfœ€ÈÈÈœœœôôôððpðstttbbÂÜÜÜÄÄìƒ{ûí·a&àFµ “É8ðÚk¯1 ++«—“8€Édb0˜ñññ;wîZXX°þ½÷ÞK"""¶h¼?½§§çÍ›7;::z{{w´þp8œéééÜÜ\"‘XYYùæ›oÆÄÄTWWƒm _|ñ…“““———™™Ùs9ÌḬ̀X¬©©)¬ððp,›]RR2??O£ÑÖ×ס¯QxT*ÕÇLJF£éèè8;;ÂuvvÊåòÉÉI±X¼qìÿ.dggc±ØÜÜÜÏ?ÿÈÄÁÁF£ÙôœP2™ìäÉ“D"@¸ººjˇÃဉ³ÖÖÖÀÀ@!‰ZZZ:;;]]] @‘¢¢¢ÔÔÔ¼¼¼&‰hÿÅèè(Fëêêruu½ÿ~__ßKH’wµX,6++ Çóx¼ÉÉÉÕÕU0çÍår©TêFY,ÖØØHñä€@ ~øá¥Ricc£¯¯ÿÌ ™ÿ|¸¸¸`±Ø‚‚‚ºº: ?‡‹x:::`çÝS^À––X>ÃÃÃ>>>t:}ïÞ½Úï]SSStttBB‹Åêîžž¾‰þ…BXèt:•Jýí·ßœ{{{Édò6 Mw“µ3wîÜ!wïÞmhh¸|ù2‡‹Å!!!Ÿ~úi]]ÝÁƒ[[[áÜ===‘‘‘àãùÑGáñxGGG"‘øóÏ?×ÖÖº¹¹áp8ÀápÞÿýmfÿ?âÁƒD"ññãÇsss8ÎÓÓÓÏÏ/&&ÆÚÚº¯¯¯¤¤„ÇãÁjG"‘„¡¡azz:çóùõõõ ½½½jµ:44´¿¿Ç;99‰Åbð¥511‰Dþþþ–––àëgdd”““ÃåráÎñIxxxhôôôH$‘H~É£G¾ù”–––——„ÊÊÊæææ´´4</‰D"ŸÏ¿qㆋ‹Kuuull,OXXˆŠŠêïï/..>tèB¡ð÷÷çp8$)$$¤¸¸˜@ °X¬wß}÷üùó;Z0̵kבHÌÏÏ/,,ôõõ=zôh\\‹%‘Hazz]I£Ñ@äOKKK"‘ˆÇãÙlvGGÇ­[·zzzttt<==9‚Çã~ùåPÐÇÇÇÜܼ  `||ÜÎÎÎÔÔ„lzë­·6êz¼¼¼<<<´õ§»»»­­M(ÆÇÇ{yym£Ü6[Ö  %É믿nnn.‰@M6›M&“e2Hƒ~ðàÁ={öðù|•Jegg * `iïß¿ßÄÄ„Çãíß¿ßÐÐP,/--!$¹Smn.—«R©€µµ¼¼ldd´wï^@°gÏžÜÜ\`ë!‘H}}}6› Ä—e³ÙF__ßÚÚZ$!SSÓµµ5°ÏØØÎW ž°±±yå•WÄÕ«W“““•J¥R©422ZYY100ÐÓÓS«ÕR©ôÉ€¶\.÷À««« Z‡ƒD"Am/‹‹‹+++ûöí333ƒõgffÆÖÖ6%%ƒÁÀwÊãñ4­­íSõG.—‹D"›¥¥%°rØÊÊêÿ Îêêª@ ÐÓÓ³µµ‹ÅûöíÓÑÑ™ŸŸW«Õ×®]KNN†ßpãÚÙ•gff 200°²²‚õçOrgj4à·144Þ€ììl›øøxX$‰¡¡¡®®®J¥’ÉdOæ¸ \=@{­­­·'æÌ_ð{577wtt@»Ør¹<33óU^WW¯2Ý¡@£Ñ»z²Éë•+W^PåÕÕÕgÏž…Ðî8ü•…£<OWW÷ßo+P«Õt:ÝÑÑqWB¡>|xWOÅúúúÄÄÄ?j¡Ü?»+Ýw±‹]ìüüš ð$IEND®B`‚snd-16.1/pix/fmeq4.png0000644000076400007640000000126511147553267012674 0ustar bilbil‰PNG  IHDRUE}<3PLTEÿÿÿààà°°°   pppðððPPP€€€@@@000ÐÐÐÀÀÀ``` CY¼ pHYs  šœtIME× 3åOÒXIDATHǽV’« $„hPþÿk_H¨ŠÕöúî¦Î´©h6›e:÷â¢è¾y½«Fü^b½þ“C(Ó‡]ÀZæù¦´ÉôºÝËáõ˜”ú•u-‡!ÿ3>Š_NÈ—,çã]FS ?žª†ªÊ‚÷`!jHQ‰Ð±0µ6!å1ÑŸY…ió¥@ÀX…FJØwGGÝ6Ô £ä³vQòQg!i³Íœe}dÎå–Uû@ú¼yñ„ ·öN€=jaGƒüYƒË©öc®`>¶1_Ú§ç㇔Ki@©ú9U_MÉ]Qåm¬ @¸(HNk.¦¬ò©ÝD(¼ÛG×ö¤ üd“×€ŒÏ´ñyìPåE¶iA¾EÜ!î|깥ǒáànõ1û¸Õ è‰Ï°C­ú(5ÂÕôÁÍ9…[½\o³4ùnâ³}dÖ,4 3Ÿ'ÀµVž£f/õõ¸†Ñ=@Fr¼rƒŠN4Þði»Ïlc èÌgäâƒ÷ÕþT¶:àIƒÉ%R1­± ‹ÈI“ j쎃𼈗Bn†5 4ìêð0bè+Ë\H;jÖÊ`Ö@û!t;"û8,WÇÅý†J7§ñè º8¶…¯Ý9³³nÕÿùx_ç²ÿ—âRØÏ|½±—Øö²·üéß cŒÎ—m§¦ü&ƒÉ}ó*oËÁWùT:ÿQ­~hIEND®B`‚snd-16.1/pix/sceq27.png0000644000076400007640000000246311147553270012757 0ustar bilbil‰PNG  IHDRˆ"rm¾(BPLTEÿÿÿààà   €€€@@@ÀÀÀPPP```ðððÐÐа°°000ppp ©©©999yyyiiiIIIò\È pHYs  šœtIME× úBÕ„IDAThÞíY‡š£ ¦*X®½ÿ«MDIJY¼˜\æûÖ5‚ Nÿ„ŽI÷¥ =Hz8I¨:=ó„9’ÂtúN¿ý陵·~žõ+4òQÌ\xò…ôüûÇ•8_6PÃ4æºÒÖ#ëCÎ/AŠ )ªƒíñ¶á-«Ä ©µˆq7`3—kŠXe‡8æü¢„›í±ÜÂf‡Àéu¢!}2Ò`§äê:Ä Î¯I*‹LZÏÑ$S„·Ê0èZÂBqGlE ¤n ÜSóÖš \K+;"¹)¹:`ŽõYÎ7OÃ@=õŒæGxÞ,…ÝDÅZØÎ0¿…0+}Õâ`•aóV_õšý˜F8Ë""Fù0öLaëv¶0ˆí‰/²>ÏùîÔ é6%I1¶1¹¯=š¢WÉbB¨ÍØ0¿œ(‚Òx –Iˆ‰£ %ã~v¬Ïs¾}ZnÛÔô½X‘‘ŒH¯#ø ±œ‰Œ".æd#’ðb”’›$3ÁêHp3¸”’¹Xµ™ëóœ¿Q›ÕZ¡h’GXÜŒi‘¬±àŠX'ëÞǨlB^€ñ~¡$õ´Faªž`+ÎÎ21Ž¡…Ü-vëóœ" €äÁŠÎ™“­e ´îä”&Öfl¥R(TMxì VIî†l¼·0ÿíË0²>Ëùá,Š}¶yâ˜Ô×€ÃOiXŽ2”f@71Mu6Ü |·øâ§òz%½ø7Ñß•n¤ß‰åD°1ꣀÅO%EØc¥¨ˆ,MfWß@^Qy@2}å%x•Þ;@ï_7ïÑÆã§’"–X¡˜&îSN„Š”>¥rRr€$dŒäð'…Wó½ÛïÏ_~¿Vi67Xü±€Ã&‘;³Ôá&T’LÕÅŽÉòx™žÁÍðjy"’OÙ“"Ø–G=ÀWbÞÿJV3 á‚”áU†gbµ¦Ô"¤É ¤PÛß@…Ðô”##‹¨R@’¨bÂ0x‰gÌ~ÿ™ök«" YŒIÓÆìÛ!,Iö±ûm²Ñb H¢*& Ó©ψ´úµåë?­O°=d€5²þææŸ¡Ú‹˜zD…ËExÀ0:Ã3œ¬s†Ÿ Œpá¬é›uNW··Ç §L/©_|2/çÄ#ø©‘)šo«ÄaR··‹yÊôW;’IE°~?‰nªÒ놡NÚvø§^.§r—*€®B³é\—é&`)PŠÃ?±W›6ºTtšMÇ]¦w¥ÿ\²z¹K˜šM‡]¦÷­ø.mÈlt©ÓR³ u™Þ•j5d6W/u©ÓR³é°Ëô¶¡©JCfsõr—jbZh6w™nU* ëÚ3.ÕâÒl:î2ÝŽøËv¼Gñø¸#óMŸc§g¹@†?Šxyüûñˆ§ÓÿòŽÃG&×Ð_<3{™OHIEND®B`‚snd-16.1/pix/saveas.png0000644000076400007640000012510111533757164013137 0ustar bilbil‰PNG  IHDR,5zÌ6ísBITÛáOàtEXtSoftwaregnome-screenshotï¿> IDATxœìÝw\çðç’0Y ‚€,·¨¨¨XqJ]­VŠZG]Õ:ªUªÕVjmUjU( ¶VÀ‰[†€âOEq²GHîýýqpÆ@B€@Ï÷ÃG“Ë»’÷.ï½w—{B!¡`Y¨êf „j^./ÉØp—Ç<9‘­ÚÖ „jVL€€²AJUÙ„BQ*u²ºYìÈHɧeƒ…ƒB¡êR#fæÖŠ'¿qåªåGK*„¿õçäh)RÑå|£xõ5¬Ï¶Q3[ñ:hûû}ªn‹LOlþ3àê/zµñ×ì¿TÝÔ¤©äçæ(’VXZD‘šóT2ñ^êu³vÕÑáË/®¸¸äÚ8…BÍ ZG„šÂÒ’Áj*n\Ú…ê¥BÝHÔ¨  í5lœ‰Œ¬˜æÃK@æ $ú¨ÔzÙ¹E…%²*ÖÔPke¢/¡æ€”ý¯} ¸fTQ;"7µŠ”7ŠƒâšB±­Jƒš0B€šyæ5lXdÄiÉׇ QžDjÔ¨d&Ô³-=¦G«÷¹y…e{}ÌÞEQ@1455[<£OáLÕ¥ †#ZM·Ñ´ñSá‹ÈìV?û6Z,¦ïÑJݘ ÜLaÖÑw‘›2w IéÏVk':“ýï„´ù ÍÑzÔù?MŽÆ”ô§ÞŸS§ÔšÎg8¢µz«7¥ïBߟY÷|g1]ÉΖ&Gc±éì1ÃLÕMÞ‹rÎæ\üöÙ¶w¢l6–†æ3Öèå•Kò7eï}}´ÊŒŠ×.ë]ßëxÖBÝlë‹=æê­¼[ , ‹6gÿöê0´T3Úaµ¦ŸÀíYÉËåO,ãI_T·M"Nîí Æˆ8uŠYÎ,€ˆS§Mˆì™ÄÒ¶ÆÐµ­^I©zQ‘U>1#§|ÒT×Ôá bqåFuÈNËêëïà¿Ûq‚bG›vžÅ=7†o*®îÊïœû6'1ãŽ:¿gg·…¦3x©â5ÔÏG_EL25@»§ÉÞë ¢¡†}59¹ù¹—?;£6‘³ÛwË(ÃÁ¹Åyÿ^ÿ¯‹]Çy-§µ}c6éÝBö*QÖ›‡xˆiqJFªMkë©F>Ý…Î’'–h•2“Œ9“g–´ÿh¹òÕÍç‘­âågÜm¿Q‘Úå¼k¦ê¯ZNO›ñòMV[«MKãÎÅ&9>ûÓ!ÈU·3!^‰ö¶ÙÌãH‚ÃAÕfB§Ož1òîíÍ>f–—Oƒ€éµ±²«ã‡¢8ªü8P@• (ŠCU’!¥²Öµ €zôôñœ¯?/ÔÌ´[i¼s¬¨1d¶xË-Cm]þ§Ã&ûœæm=ø‡ ÛâÆ_ÏÊ{ÕR×dˆaßãñÿ|2ÕN_ˆ’ÒîÅ]F¿Ù㓞¤X;´½økô0gÏîKÚ$xý8êí Ón˜,Þ¸ìè™°nÝ»ßvÄÉÌÁ÷Ï>w¹Àl ŸfŒœí jprg¨³ÓìÖ“.œ‹µê$+ãý¾Ï¬]λ†.‰©I#gøjiÞ=zC§Öçugמ`Ùæ!'è¹gm0[ ΄P"„”ÿ=u"Üû“QÀŽ@§N„³¯ ̄ʖP‡âPL%Ì¡¸CQùFƒ+7ª;wÞ'–µµ°~}çÙûÌÛ™÷ö_;ü"ù=ï Ìh9~^È4=M›ØÄÀ˜›*R¨jvæ ÝiÃú{ŹäiÐŽGàóÚ·qbRFí¬Å™ï|1£ÐýÃ8ÐIË‘ypæß³Û:)Y9¯Zê™t°p>u*úÄÄž©‰9Ý´.<‹u¶sr´i§¾¶´ë ™µé@O…j—ó®çãÿkÓÅÎ$»(ÇX×H—¯Û!¯ìœÏé ‘”ƒÆr¥¤´DCM£,B¨Ž±ç„àdxØÈQ>ìcÉ—˜¤ ]˜ðaâCÊϱ#ó´’Œ)ÕÑ[¯È‰þ´o{;gk»‘í½†¶èú——¥u›å6_ÀïaûnÝìëæ>~ÄX—CJ / ޼޸ÂnZ·¾^·jsµž¿|~íÎuª“&B‚C~òáj‚ôÿ=âÍË刵˖Pb‰FóŠí Ñ([á9¯Å”˜Z,¦ ¹´Z”E ÄÜ÷²3æk—õ®3¯™m³ °€cÈ£u(‘ ÌÆ(.+°TTÊ1æÙÐ"J\>EãvŠêMiFùŒaåvŒ}Êáp€¢ª¾0b!‡¢(fƒ)˜ l ªpt!%ÒSÓ}¥þnuìfrX¨Y¬vçÈuM Íö·-̬­ ¸¤xÍÖï( µþCû—e ’ï’¾M·7´Y>m1„Çœ$GŸ{«$(ŠŠO¸|)ó2¡€Ëáz¹N¦Sún6E«•}•ß}—Ä<ðê?44/ª³UÇVšÆp/ùS ì=à—Ø?D†jƒû@Rz2$fÈÌø¨ärjŸk>­§¥ËÍìû[Ëz×/³ØO†ð@¤÷a$Ky–Ê~̃ð°£ÌãQ>cÂÃŽ²‰) ªq8®|À äÃÙ¡²’ðœªsmuÚDö;x·ûƒ—¹¯Zk™jjhŠÄâôÇéy—‹Á454·­Úš'(òqûp (ª”{ñá|£Fv6œ2áur¯(%2õÜ0»AlÚ}9õšHƒîdêl¨mà´¸{qËR¢öae~ð69*íÂÛ›—mœñü3k3+HJK>û_4Øq™4vÖ¶W~¼@4(cmCØ{ìÅç&¾H‘•QlÇ=“xÎË©òÚÛµó4éËɤÕþ+m;¬òw­YL¨ ’Å^‡}/ãÁÍgw»šwܹfÛ?É—zvìA€Pì&‹ƒª3ÌjÆœõí;–Yx<ô!äxèfÉ(¿ã¡G€ (…/LPWÓøpq\ÙFQÌf®ÆÅûý :÷:ïÍùÇÿuÐi×ÑÊYL‹î¦ßÛ¾{gæ«ÌY9kÏnžÛcưþCcï]Þqö×ÀasËò J!ôi䲎_RõàabjF×U»T(|~cÙ‚[)£z{÷rèQRZ’öâQÈåÃÅWréqZ4ï£CÕ³¯-]|wÆ'½†Û™Ùfç½?{âû_6‰4Ä# æ»=øàns3ó†¿~÷zÛ;ÎÇ]àtФ5‰œŒs/- ¸_yí„@ÞCú}»·çÛTò®©¶| [¤ä1C€Ygl鲪W§nV݃B~Z6fa >›·ST§!>cÆ1ÃŽýÍ^‰vìofùhß±aÇþ.»Äíãµ±,”Ã…wÑþ,Ë{²×$Cùµæçç ;´Ë,Tyo!iÔ;P?_9b"$@ð9+u0â•¶!¼ë"H1€—ÒáGBàPÜþü"Gj/u¼€‡Û]»Øˆµ,Š› ¤_–RÅ„p€âs ²R/q"„óQÕj/)N‚¼Q%4Q£8†<ª­­ %m‰ú¾"(¤)ku(¦I–Ô€c©N™© Û€X—ÈɨöJfíj‘%ðD†<ª—†P§òw]bGÔA!MÙ¨ÓÝÕKˆú…PD˜§T>¡.“÷bJu’Z¥@Ùiˆ»óD*é=Ôô%ô=ÑÚÜ:+ó‰ßx;z¸bö%5uô‡¼3™åZ¨¡$‡¦|NÑÁÈCŠT_Â-Å=,T·´zkQù„#B€ ÕAlDh wVãµQã”ÐêÀ±U§„å+³¸G}˜.UH€Ñà”MtDÜÔ¹Ùê” @ð€ÖJôÑg&%×MǤ$@q@¤"cB‰€òÔæä ùÀR "ÀRCBkU*/£¼Ú]5¹vˆMYï@¢j1P¥À¬Cåæ©Èxýµ¹9h àXªA1„Ðbéë‘Rf£¡Ž= e'L¥}x‰ù…O•‡ãŽòÏU£¸r£:VªOƒ¾ôBªh "4­$}ù:I„&¤ÂB±W¼C¯Hj  µ‰Pû£% @C©s‹Jj‘•QNí""Ò!lbYïZ²jª„ô‡–ˆA¤G‹ô$s6%BuGCCSÁ””"ƒB!¤ŠJ¸úOu’+raB!¤×БU'ú˜Ô!‡Ê~¬ŠBÕ‹fBœsÅOÎ¥ª²9!„š4ËAvô çÊ!n.çR 2UÓ.„BÍŸofåÚ‘}Z6q8éB!ebFæŽså3!.W•-B!Ôl0#B!„T€qJKK!„BõLrÄÁA!„P½ÂA!„ÊT:áÕq!„êƒäˆƒ3!„Bõ Ç!„R„B© B!„T!„B*ƒWÇ!„R¼:®†´µ+‹&BPaá‹*Ó¼­V™|¾¡"Éðp\ͽxQu·!„PCfjZýicãö ¦|ðà°µu?ERâ T+zzªnBÕ#EæLÕRÉ ÄÁA!„P½qÊÎq¹\œ U Ÿo¦ê& „P£$9âàá8„BõŠ[ÙLˆS­«´óó ||¦èë[š˜Øæääòùféé0t¨ïöí»jÙ>ÉB”R`E&&¶—.Å+±@w÷¡ÁÁ{•X`í«VâÇXïNé=‚j°$GœŽ;tèÈ£G÷îŧ¥ÝTSS7ÎGW—¯ü–xzz89µ““`РOvîü­.ªVÐàÁ£CCO6Àªåtòó6œOµ¸¸Ä×wª [‚R:ɧ†ƒÐÿþ÷¼cGg ‹Ö@[[ë?vš˜+¿¥ Îóôô¨‹’•";;'!á¶§gÿXµœN…ÍVÓ¼¢¢¢“'Ï0KŠ‹KÖ®Ýüöí;Õ6 !¤µ„Æ›¾mÛ/¡¡'ù|3ö9'I$­^½ÑÖ¶K‹–ýú ¿~ý&³üðáÐŽ{ ææNŸ~ú¹üº$#UÌèï?ïòåëK–¬æóͬ­;É©477wÒ¤™††ÖíÛ÷våÊ3¾|ô(ÃÇgJ»vö†† ö B¨!«í ô÷ß{çÏŸ3fÌÈ‚‚Ì‚‚ÌÌÌäJ“-]úí¥Kñýõû;q#Gz5éÝ»÷YY¯fÏ\¶lAJÊóçO Ø_ÁJ+ÍøÇ;{ötÙ´iMAAæãÇwdU sç~ýèQÆ¿ÿFüý÷Û·ï*)2ÅîÜù›©©¼Ã}ò={ÎËk óxûö`w÷ññ1&Œ™5+ ??æÍ[tåÊ'Bþû/2''ÏÏo!„I¿cÇnOOøøèŽüýç-^¼zýú.œzúôùæÍ?Éù +V½m[ð°aƒïÞŸ1cêäɳRSÓlöçŸ/xñ"ë¿ÿ"ݼ—ùX*~ª¬%KV‡‡ŸŽŽ>neÕFªL9=»{÷¾… ç={–¸ví7ì'#«GØæéêê~^\\’–öhÈ__oE{!Ô°)áp\•rss÷ìùó×_·»¸tmÓÆ|áÂy66Ö‘‘ÑÌ•!Cšš¶tp°›2eœ‚*’QN¥ááAA:tprvvܸqµH$b²˜™µrsëV³÷(‹cbþ:tóÔÛ{èôé“ììÚ®\ù5ܺu÷íÛwÇŽüñÇõ..]öìùéöí{×®ÝdÓO:ÞÞÞvéÒÀ‡ÓæÍ›Ù·oïÎ;|öÙ”ØØ+rÞNŪ==ûO:Þ̬U`à..]öïÿK‘f¿yóöôé¨Üàììèèèðý÷>–Š!K££ÿ‰Š:nn^Éåér:hÂ_—®0nœ—Ëe>Y=Â6ïìÙs“'ÏZ°`®§§ŸÏ6ÌÇ!Ô4Tz‰¶’o`š””ZZZÚ¹³»äÂ/†¶kgß³§K‡½†4p`ßQ£Fhkk)R "eUš’’FqqéÂ,éÚµûþ}|¼}|j¸‹}íÚM@×ÁÁŽyÊ^Àår Zäää=|˜NÓ´«kwfyëÖ¦ææfÉÉ™aModdNNÌSccÜœ\9o§bÕݺ}8hÖ½{—ääTEš¢¨NÊîÉÑ¡ƒ“ššš¬\[·îàr¹±±g˜%¡¡'§OŸËþ‡Ãaß#—ËUÊ {æLÌС%[(ù*{Ø¢¨J³K¥—|Êä•óJU]›f+ÈݽǙ3çbbþ™8ÑY2dÈ€7þa[Z¶‘ÓARŸóîdõÛ<ƒÌ?¿O Ž®|A)ÎÓs¥äÓßΧÒß )ùpœ££=Ç;wîߊ/q8>ß}·<>>æñãÿIžl—¯ÒŒ\.—ýº—U©ƒƒ-!„=S’–öX(,­ÑÛúÈÙ³çÙb•²··áp8ׯ'0OŸ?ñìY¦££½‚åËù ¥ªNHøpææÆ[íÚÙ)Òl{{BÈ;÷™å÷î%–––},’Ÿ*£G×=KÙ+ tttìím™?uu5¨NÏÊé©·ÆãñÆ÷•óvBõ¦°ð…ä_Ë©sBúúz³fM[°`ùÉ“gž?qûö½5k6%'?¼yóÎO?ýš’’úâEVXØ)Bˆ¥¥…"ÊÊØºµÙÕ«7²²^½Ÿ-«RCCƒ‘#½V¯ÞXR" K׬ùžÝ7 ;5jÔ¤š½ÇŒŒ'}ûö–“ÀÐÐ`̘‘ ¬HH¸””2sf@çΘ³#Šõvž>}.UuLÌ¿ÎÌ|¹mÛ/ׯߚ:u¼¬2%óŽ1$0ð›ÄÄäää‡K—®áñx|ü©²yì÷Ç?Ϙñe¥ãbµzVVT|k¡¦§>!øþûogÍš¶dÉj''·Ñ£'?~œahh £Ã?{ö|ÿþÞÝ·mÛõÇ?[[[*Rš¬Œ_$'§ÚÙuëÚµŸ¬Jà矷€½}·=yxôaOWdf¾¼z5¡fo°w uùivìøÁÅ¥‹·÷ø¾}‡éêòÝ/ëè\¥*};gÏž“ª: `ö©Sg:tè¹{÷þ‚ííme(•w×® V­Lúôñòõ:gÎt.—ü$õ©²¼½‡îÜùäI3ãã¯I•\Ýž­´G*¾5„PÓ#9âP0,l›dë¾)(ÈTeÓ6mmÓ/^0¡ø|³;6ûûO®ÿføøL1bHͪ–“7-íq§N½32î²—Ô¿Ú¼5„‚˜øœ µ36n¯à‘·Ç/*OˆÏ7[ž¸<œ±á.ÞÀ´æFŒ¢’zûôéY㪥ò^»–Ÿ_б£óË—¯,øfàÀ~**6!Ô$UOÕ€ª®× üBYy‹ŠŠ—ed<ÕÔÔôôìÿãjݺZ©Í[C5F85kýú¹ß¹§êV „š/%ÿFµùÀ“g!T{8!„R<W=¦¦¦ªnB58!„’éÁƒÃuZ>BÕP›ÛT „P£Ãç*òÓŸÚÀsB!„T!„B*ƒƒB!•ÁA!„Êà „BHepB!¤28!„R„B© B!„T!„B*ƒƒB!•ÁA!„Êà „BHej~í‚‚·JljPŒÛÈ= &bˆ€<.Åõ*éªêv!„ꊱq{6PÀ«WÕûz·²j_ã µ åвvÙQ£ƒ=ŽP³‘qOñÄVVík\Qmã ײÔЊ¢(öAq1]›ª•ÔŽ¦kÕÔ p8UŸ&l =.N:Õ¯_ÝFÜB¨É“³ÕØÉÏ›–v†Ï·©MíJ„!U'BG•ª`Ÿ>}zÇŽ ÙÙÙæææÊhtKpõC¨öälGBa!4!´HT””íà0Ëå1KÔÔ´k_u­®ŽÃí¿¹©VôéÓgÅŠuׄPý‰„÷ïGdg?OJЦi‘KÆ™’¦¬™Ðرc !!dOY:ôÝwßeddèééyzzŸÏ¼$™ž¦iB‡Ãáp8Ìr‡Ã B¸ú!T§Äb!û !Š¢(ŠÀìÿ5€sB̉)ühbäœo¬AË„˜=<<<<<–.]ÚªU««W¯zxxTLOaÖ¥¤¤888@ZZšP(ÄÃq)…¬­>--²|êCʯJ18EÕ~(ª“™ÐŽ;wíÚ%õ5 ~ïçää22RêUˆ‹‹“¬%99™yª§§wøða6±¿¿¿âAÕÌû÷™„Ð BÄ’Ç*ÔÕ5j_>ÆBÒ”5B5*Üê•p8NKK«ö… F{!¤,µ„•ÒÔpÈß'ÂG¨éi¬3!>_Äç·PVSPÇ=ŽR.<'„BHej5*(À»þ4MÚ2nÆ=ŽPS%k«¯kÞIÃðÞ57ò·ú:Uá½ 0|øð… Ö¾FTwQxoY0ì7BÕ¢ÈV_wê旅vvvÆŸ6|(¼·,x;„ªE…Û‹â )hÉ’%µ© 55ïíååµhÑ¢ºkB¨QSÂ,Œ|ÌÕÕõ›o¾ñòò²²²²³³;qâ³|À€[·n%„<þÜØØxÿþýÌòŸ~úÉÂÂâíÛ·5 ØLHcÇŽ]¾|¹»»»T–½{÷vîÜY[[ÛÄÄdΜ9………ó”|ÕÌÌlÛ¶m ,xöìÙÇ—/_l``P-A ‡Ã JNN ½~ýúÚµk¥0a¿W¬XñèÑ£‹/zzz²//^¼8++kݺuþþþyyyÀ†ý °ß5"uÞÛ××·{÷î„!C†ôë×oïÞ½6l‰#õ&LŸ9sfnnî¸qã¼¼¼T8#)rú¢;MlböÁ”)S˜ææækÖ¬Y´h³z°0ì7BõL…ÛKüìÃÙÙ™}ܾ}û¤¤¤ŠivîÜéììÌçó¥î£Œš¼øøøo¾ùæöíÛ……… ¤`Øo„š:¹:N$± ¥Â_²óóóE"ÑÛ·ouuukß Toj0b×ÂÂÂQ£F=zÔÐÐðÒ¥K£F’*Ã~#Ô|ÔI<¡k×®± ¯]»Æa¿‰òóóg̘±|ùò”””3fDGGcø€†£NÃ{§¦¦fggjjjÀ½{÷*-Ã~#TŸü¾t)’¢(''7===eU­ü™!äÂ… {÷îŸ/ukÑ:ZaBˆ2Ã{+1*3û Ò¼FFF²*Bµ'çìÙNS^^ÞºuëæÎËãñ$óbo„nGʼ)•ùÓO?=xð ¼™Q›¨ÌóÊ©54%%%ãÆ³°°Xµj•ÔKu´Â „e^§Ü¨Ì’ÅJå•SªŠï4•””Œ;¶¸¸øÔ©SjjjR1Œ7BHÉñ„”•YòtY¥y !²*Bµ§¬ðÞB¡pܸqoß¾ŒŒÔÒÒª4†ñF¨!hÜ¡ØoåFe–<9$•7!!¡ÒŠjÿ^"ù¨ !ãÇ¿uëÖþýû=zÄ,l×®ºº:†ñF±”yN¨Þ¢2W·"T-JÙ'*))‰ŒŒ|ùòå!CÜÊ=}ú0Œ7B gBL íšÀZ‡%™ æ,(x ÐÒØØ¸¨¨¨ˆê—––Öýû÷Û·o ÷€˜ˆE ð¸׫¤+ö8BM»Õ¾`–¼zõ6#ãž½½‹™™íû÷™„Ð BÄ’Ç*ÔÕ522ÍÍmMMíÙ¼UâóÍV¥l€ûel¸‹á½‘4 ïPsÓ¸Ï a°çæ{!¤,Êï; ïPsÓXgBì¹¹ÁG)žB!¤2ÞUÃ{#ÔÜÈÚêE"!! ìyåð(eÁÃðÞH†÷F¨¹‘µÕ_»Qþ“pš½[ EQª\-«n@á½Û[µQxoY0ì7BÕ"k«¿yóŠ"ÙÍÍkU»òÃ{÷íÛ×××7  Æ¥á½XT«Ê_ÁÞ©‡ðÞ²à*„Pµ¨p{©Õ… ¸77Õêq&¼÷?ÿü|íÚ5??¿ºkB¨‘Rrxï©S§ÆÇÇ/\¸ÇãµnÝš’ŸŸ?sæL###@àëëûüùs&¥¬å’eb ïúuÞ{ïÞ½;wÖÖÖ611™3gNaaażö¡z£ÈV_w”|‰öþýû{õêµuëÖÒÒÒgÏžÀœ9s._¾qùò圜œÑ£G3ïVÖrûyÅŠ=ºxñ¢§§§r›Šê“dxo‡”œœzýúõµk×J%–ÓõÁÁÁ‹/ÎÊÊZ·n¿¿^^°a¿Ã‚‚‚0ì7Bˆ2Ã{K.g¾yóæÈ‘#gΜqqq€½{÷¶mÛöÊ•+¶¶¶•.ïÑ£›]NìgT§ä|Î5Ûi’ ï=eÊf¹¹¹ùš5k-Z´aÃÉôö¡zÖtfBR>|HÓ43´@ëÖ­ÍÍÍ“’’d-—Ì‹1¼›†Šá½ãããû÷ﯯ¯¯®®>jÔ¨W¯^IeÁ°ß5J>'D>>©SéS—3±ŸCBBÌÌÌÖ¯_ïââ’ŸŸ_«ŸHû7ú^ô¹ç„9BY=.Gqq±ŸŸ_qqqhh(Þ»  `Ô¨Qžžž©©©ÅÅÅ111b±X*—¬®‡ò°ßlS¥Â~3Ù°ß!EÔ~¨ %‡÷‡Ã|5€½½=‡Ã¹zõjß¾}àùóçÏž=srr²±±©t¹Ôç‚1¼U¢â¯Ï9rÓqƒwtíÃ{§¦¦fggjjjÀ½{÷*-Ã~#TŸë LR[»¹¹ùåË—ÇŽ«®®n``0f̘ÀÀÀ_ýUKKkáÂ…;wîÞ½;EQ•.'3!Y±Ÿkß`T-ý,ú¹ê¸J.Q¤ˆŒðÞ‘‘‘£GNOOß¾};[ †ýF¨Rþ9¡ÀÀÀ””›Î;ÀÏ?ÿìââ2|øð>}úèêꆆ†2C®¬å,Œá­*R¡¡¯q-ÿÚ‚Õ*DVxo}}ýÝ»wýõ×vvv3gÎ d³`Øo„TÃ{£†Ã{#ÔÜÈ ïŸ/V${·n®µ ï7EFÒ¤ö‰¢ïE«sÔ=,<@SU-BÕ­Æ}Nƒ=7yì… ÌSìq„²`xo$MjŸHêÂìq„šžÆ:Â`ÏÍsa—âzAWìq„raxo„B*ƒá½Q%$/r–¼0{¡¦JU?mÀðÞHZÅ@¿’&`#ÔôÈ ï]\xo9‰üÑÁk©b ßŠwL¨‡—ìǼ¼¼ñãÇ_¸pAMM-777$$dÉ’%™™™AAA5à‹bÉ ï]?”|Ûc{×,øàÁƒåߎ¥Ü’¯Q“úô$/L¨4A•&NœxäÈ‘C‡7NÁ,’}½ÿþÇ'''ëééÑ4=þüï¾ûnܸqÚÚÚØÑ)… 7%%ĪB¡pÉ’%õVªT züðáÃYYYÕÊ%Ù×OŸ>íØ±c›6m 77÷ýû÷lÑ/ÒC¨)Pf(‡Š±½mllŽ;Æ&ÐÓÓ‹U<¸««ëÊ•+½½½ ƒ‚‚ °uëVæ%Y!¢¥š„ª ”Þ›òìÙ³eË–íÙ³GV.YýÈöµÏ–-[Ž=Êãñx<ž8::òx¼ŒŒŒZ¿]„P ï]1¶·‚Éä„úÞµk×¢E‹Þ¼y3oÞ¼Ú]Uˆh¤r„™3g.Y²D2”*û144400pìØ±¥¥¥¥¥¥¯_¿€äääÒÒRKKË:m?B¨(?¼7;´Vš@rà%rC€3qWýüüúôéCanÌæ’"Z²¨ä|zÕÚiÚµkMÓ3gΔZ$)ØRûkØÅ)W™ ÕŒüPßL¤²Šª TëÑ£G7nܽ{·üÛ`?"ÔÌ)?¨ä©ðb’‡ ¡Ânu¥&Wq¦UXX8jÔ¨€€€£G^ºtiÔ¨QRÙkÿ¾,Š|¼×¯_ÏÊʲ··gžŠÅâ©S§îÛ·/""‚M£`?Vú/v1BMƒ’Ã{KÆö@““Ã<}õêUaa!“^‘à¿nØ1LNˆh©qÕ€œ¹‹âá½|ãÆ‡8x={ö\³fdÞjõ#BÕÆzS†ä×dlï-ZôíÛ7$$„ùuȲeË8óõ¡Hp"Aª:9!¢+6 )"¯@ prrbŸRÕºuë6mÚBØ0Þ öc¥v1BMƒ’Ï IÅö^¾|¹¦¦¦••UÏž=ÌÆ¡Q0¸,rBD£Ú«ë}"6Œ7ö#B †÷F †÷F¨¹QmxoÕ_‡î!„T¢qŸÂ`ÏÍ ö8BHY0¼7’&Ÿ{¡¦§±Î„0Øssƒ=ŽR.<'„BHe0Z3ª ïPSÕXÃ{£æÃ{#Ôô4îðÞ¨¹©·€î5#N:Õ¯_?U7¡Æ¡Ñ‡÷FÍMuo™SƒðÞµ„÷õA¨Zšu(ÔˆÔ`M­Yxo„P3ƒª6¢°JÃ{Ë é-éàÁƒ&&&“&Mbººº®Y³Æ×××ÄÄÄÚÚ:,,ŒYž=vìX;;»ðððjµ!8BM‘Þ»ÊÞ/_¾œ1cÆŠ+=ztñâEOOOö¥àààÅ‹gee­[·Îßß?//æÌ™“žžTRRR÷o!¤xNUCµvšd…÷–Ò›ñæÍ:t¨¡¡¡©©©ƒƒ[Âĉ]\\!&LHHHpvv »páB‡`óæÍîîîìþBH*Ü^pBu‚ ïWñv ñññß|óÍíÛ·™ ‡@*££c¯^½œœœ¼¼¼ äãã£]þÉI•@ ÈÍÍMII!„¸ºº2 »uëÆårëèM!„”Ç¡jSä(3Þ[KKKKK«¤¤dêԩÆ +((5j”§§gjjjqqqLLŒX,–ÊKQTTTTHHˆ™™Ùúõë]\\òóó™=56`<ó”‰ÏËápØx‰‡„jzx¡fGµß'8BÕPûðÞrBzKUäááááá±téÒV­Z]½zÕÃÃ*\{MaÖ¥¤¤888@ZZšP(l›BHc½)jžù~—Þ;;;[VHo6ì÷Í›7ccc¬§§M±´´”µãf``0räÈ•+W8p€¢¨U«V±³%e¿o„òáá8T¯ä„ôfÃ~óùü3gÎôïßßÎÎnÛ¶mûöí³¶¶–Sæ®]»ÀÖÖÖÍÍmÀ€ÚªºB΄Pã øá8)ïß¿g3úùùùùù±/Íš5‹YĤ±··ŒŒ”ÌÎ$ˆ‹‹“¬=99™yª§§wøða6±¿¿Í‰ª8B¡ægB¨1ÁðÞ!eÁAU†÷F¨éÁ™j0¼7BH¹ðœB!•Á™ª†ûY†ªnB¨N¸ÊûDÂAU!àÖV]Õ­@)ÙŽsù®ÖªÙ´qBÕöä]ýý§…î«Ã§Š{÷o9Ò£hððÜy‹jPHmòVÙ0%–‰Jä–P*üYB¨˜•¦ëµRšš†"!%íÚ×°j„(¿ÙLÃjì!Ô(0»K¢:[_)¡¨tL€ˆ ˆ¼™¿´ìyõZÙÍf†P Â™^‡ªMLWñG EVZwjck¦nÙÃA+ò„˜C´é×ɶµf[{#ã…sèÂ"&±Å ƒ +M'Œ°±m¡÷ËV’ÓÊßÏÖBÛÊÅV;"hbZâ¡·s ›¥Åæ5­¦ù´µ7²êl©}*ŒY.« fT±ü#-ÝìíLÕÚÚµœ5Q~ᲆø×ØÿH ÷î”gB¨˜Ý¥*gî¦ËtÎEdnùµ¤]{õÇi чûrí¶vjO3Z-0úaMÖŠï™ôúüütßñž§9…f_ù«=Nq™p8¦K¾ „%ì±"Qu‹½¿üïÀÉ¢?Âô™Îÿ4¯¯'­£+§ R¡Ù¼W/M¿òÏüñ÷÷ܼ­„+ò 7[8KVÃjÜðpj,˜U,÷D7ç½þ¡ßžì=‘×ß Š[YÐðvÌ4&Aq+ Xòéê™ß|Ï”™3r\ž[? *,D„¦‡],tì/Vo±ÑSLÊvÖ˜™“å½ÏäüÎn@ûQ“Z-ûRýNBAÏþrª`ó²ÔÞ¼€aâ†`bVhã² /qh/«a5vÃ{£ÆEþN“VJ"%åõì/•Œ=ÎtÃR­û·8E… Ö° Šm˜Çj©É@HAg7f‹(èÐp¹Ì„ƒNŸ–´±b‹zœœšÈ¬B*/£ÐΩ {o‡Þö¹‡çõ”3| ­¥-«p9 C¨ À«ãPc"÷Ÿù^|姨Ðzš÷«™é¿µ0Ô½rÑfºwÙ´†€˜ÃcÓ‡#¢¸Ì¤(.p¸Ì露”åhB}hš&¤@f’y%p>¯Apé|ËmëZþ´!)2ÖæWZ¸ü†!Ô¨q8 º[Çá „ªƒYQåïþØ:ùbNÿ¡ìBÍÇ©ÜÜ쳿¦54@#ùžd9ì ›Â¶í(BÔÓSŠmÚ1¹¨R!Í NŸ×‘:ÇCP—]©ìœÅÉé=(§÷ ç_.ïÒÑ@ûæ•ÜÞ+-\NÃjì¸*½)^‡ªYQ ‘÷'´x=~¦å²9‚Ϫe>Ó» ø/ºÄ´ Qל;M¨?NkùÛÊ‘(°´…Ñû!£[oZ%% šý°(Šy $kù¸ 9UHæ5Ùó£å♄€ö- ÒLMâ½ÌlqúRln-«p9 Ã?ükì@Gu3!„PµÑ¤Š¿ŒÕÛÞ|2ÑúëÏ:º·µ\þ””-Òø£ÍÚzZZ/šþbÖ"¶(Ÿy06î€N=Ú8{uÉé=ÖÒ&䣙PÅ,Ìc9UHæÕxòH;ñ6M@¤­£w!Òqt¯N½,[íÞš¾í`‘E[Y…Ëiþá_cÿ£Êr¨ÈB»‡&°ÖaIAA¦‚9 Þòùx;˦I[Ûô@î1‹@<àq)®WI×ô<ûmÕ¯<ƃP5ÚÔ…ûù_ Ö),|Á,yõêmFƽü|±"Ù»us55µgóV‰Ï7[•² ì?”±á.žBÕ È9!„PãB©ôpB¨ÚZ*œ»#„”¯ŽCEÁÎóùªnBHÉpBCû–oÛ·Tu#BuBG%µâÕq!„TgB¨ p…A¨iÒÖ–^ÒµkBØËöþrE•ÿ¼•¢(  V7ÁïT=ÆÆÆªnBHÉÁA)_hhh``àØ±cKKKÿý÷ñãÇ?yòäúõëÌ«§OŸVWW2dÌ™3çòåË—/_ÎÉÉ=z4!¤wïÞÏŸ?€ØØXCCÃØØX¸uë!¤k×®lE/_¾œ1cÆŠ+=ztñâEOOOö¥àààÅ‹gee­[·Îßß?//©.===...,,,((¨¤¤¤>?„/@÷È‘?ûôéõ÷ßû”8ŽCÕ¢ÈN“db&e‹-†~ðàÁîÝ»ÀŸþ9nÜ8.—ûúõë#GŽœ9sÆÅÅöîÝÛ¶mÛ+W®ôèÑÃÁÁáÒ¥KãÆ»téÒ¼yó.\¸@¹té’«««ššÛ€7oÞÀСC MMMØ—&NœèââB™0aB@@@BB‚³³sXXØ… :tè›7ovwwg‰Ps¦ÈV è9r üÂ¥Á™ªS§N=räHiié›7o¢££'Ož >¤iºGLšÖ­[›››'%%€»»{lllVVÖ«W¯æÌ™“  cccÝÝÝ%‹uttìÕ«—““Ó§Ÿ~zðàÁÂÂBö%+++ö±@ ÈÍÍMII!„¸ºº2 »uëÆårëø}#Ôè‰Å¥b±˜€Pp8\Çã©+åÒ8À™ªEvš¤æLƒær¹QQQOž<±··ïܹ³äD²@fyïÞ½·lÙréÒ¥=zØØØ\½zõòåË_|ñ…dbŠ¢¢¢¢þý÷ßóçϯ_¿~ãÆW¯^åóùÌK’)™ L9‡Ãa–s8f™B²\»Q¾©ÒÌŠb~ Ê¡ÊÕ² „P50+œâßÚlJ.—;qâÄC‡=yò„¹|ìíí9ÎÕ«Wûöí ÏŸ?ö왓“3}öÙg'OždŽ˜õîÝ{Ïž=ÙÙÙ®®®RµSåááááá±téÒV­Z]½zÕÃÃ*\{MaÖ¥¤¤888@ZZšP(ÄÃqŒðÞE[XTñcU%T 5 j§­mZ‡íBªV1¨ÝTÁTU7 !T‡ØÀt5øzWAP;Å«DÑž§Ôìq„š‰úÜØñ„B*ƒƒB!•ÁA!„Êà „BHepB!¤28!„R„B© B!„T!„B*ƒƒB!•ÁA!„Êà „BHepB!¤28!„R„B© B!„T!„B*ƒƒB!•ÁA!„Êðjçñã‹JoB¡FÍÙy|aá‹êæªÉ ÄTV³Œ!„šž×,c !¨Áˆ‡BIÂsB!„T!„B*ƒƒB!•ÁA!„Êà „BHepB!¤28!„R™Æ79:ºòùf۷画ò-,œù|³àà½uT>ªا5Xoj\&MšÉç›M›6GÕ A ©Ma_#I¸>(!¥)..QuBõ·wei¬ƒPqqÉüùKZ¶´·²êøë¯e‡Y„ÂÒuë¶´oßS_ßÒήë²ekÙeÉ’ÕÎÎ= ¬ôôÚ89¹}ûí÷Ba)óRVÖ+Ÿ)V:õ>s&Fª"9e2×®Ý>Sø|³ >cäååµhaÉç›?‘-påÊõ“&Í46¶±µíòûï*Ò$E~ŸÊZ*öWNN®œ5Göu“qèБîÝ=ôõ- ­;wî³bÅ:fy¥Û{µÖ%ìÖJ5ÖA((è—£"Qéë×o-Z™ššŸ}6oãÆ ·oß{zö‰Ä?ý<}úLú+Wnèé †Ô§OÏÌÌ—?üðÓ† [™—&Nœu^(,¥(ÎÔ©sòòò%+’S&cûö]‘‘1­Zµäp¤?Lgg}}=Ð××ëÒ¥c—.gΜ gÏž{ÿ>Ξ½ –¶liÒ¿¿;›kÛ¶]oß¾ëÖ­ó‹Yóç/‰Š:¯`KK~ŸÊZ*ö—Ë•³æH¾nRSÓgÏLN~Ø·o¯û …Âsçþ•L µ½Wk]Ân­Tc„Œ ÓÓoß½ÏårišŽ‹»zÿ~RXØ)ˆ‰9~ôèþsçNÀÉ“gÙ+CÅþÒÑáËJ,ûºixô(ƒbkk²çÈ‘}‰‰WÝ/™@j{W|]ÊÈøvk¥ë äãã­§'hÝÚÔÐÐrssoݺ˼äæ6Ï7ëØ±óôÞ½Døõ×½ææN66]:tèÅlê/_¾€ÄÄd¶@6ÌSSSƒ­E~™ ?¿QÆÆF ®®¦H˧OŸ!!G…ÂÒ¨¨`üx_Éîî=ʸÀýûI ¶1ä÷)È^*U­ÄR°¯.]:òùÚ©©LMÚ·ï9}úÏŸ.@j{W|õÀn•¥æ¡TËаó€Çã!„E}õÕçE±)íìlbc¯¬Y³ æÎáæÖýüù‹û÷ÿEÓbÉÕÔÔ˜ì< ì@­œ2ÙÇFFÕjù¤Ic¿ývÓÕ« üq0//ÏÎΦK—Ž’ D"ó ´TÄ.T¤%HJ¥}ªÈÊÀªV⊰¯ã‹#~ûíÀíÛw9~âDäƒWMM[2 $·÷j­Ø­²4ÖA¨"fó&„ôïï>hP‹ÅááíÛ;<ø7hiinÞ¼$ò:9µc\¾|màÀ~÷ï'åç(R¦‚­RSã@AA»ÄØØÈÛ{hXØ©U«ÖÀøñ>RY""¢-šOaΨ·o﨔–4òû4%%d¬ P¡¿ä'–‚}Ýäää­€¢¢b §¢¢âÄÄdv’T­u »U–¦3uèàôÉ'ÃNœˆôó›Ö·oo—pûõë7YY©:µ€¢¢â3æëë þú+”ÍÕ¥KGW×n×®%L›öù!/^Œ¥(ŠÙg‘_¦††º"­²µµ€³gÏõìéicc}ðàn˜>}RXØ©‚‚B7Nú‹)55ÝÁ¡;¼zõ>ÿÜ_)-i>äKø_‡ IDAT÷©œ•*ô×W_}.'±ìë& =ý±‡‡w—.[·6}úôyQQ1dz··­4qµÖ¥ƒwc·Vª±žªÔÞ½¿,[¶Àܼõ¿ÿÆÆÆ^¶°h½xq€¦¦F÷î]¾ÿþ[##ÃððÓOž<]´èKÉ\!!{PXX{yÅŠ¯[´ÐW¤L›4{ö§ýú¹«©ñîÞ}pçÎ}f¡‡G+«6àæÖÍÚÚR*K`àC† (((hÙÒdÛ¶^^žJiI³"§Oå¯ Rý%?±ìë& eK“!C¼xñòô騒ºví²Ç¢u¥‰«µ.v« L íšÀZ‡%™Uæyüø¢³óx ï]£GOŽŽ¾ðãfÍú”]èèèú¿ÿ=Û°ae@ÀçªkR2ìkÔ(>.ðùf«R6Àý‡26Üm:‡ã‹_~ù=:úBLÌ?zz‚ŠÇgPS‚}P•šÔá¸F!.îJLÌ?––û÷ïÒÓ¨º9¨a_#T%œ Õ·C‡~“õRRÒµúl ªkØ×UI™ƒPAÁ[%–†”ÈØ¸={¬öÕ«êu“•UûêžÿÃ5¡Áªç5‘“SƒL¨Œ©©iÓ>¯ä™Ðã|{åˆ”ÂØø£§÷ÏkeÕ¾5bbbbÂþ3!!¡G?677g–Ìž=ûíÛ·ÇŽ“_Ž››Û'Ÿ|róæÍèèè–-[nݺuäÈ‘0pàÀáÇ/X°`Ú´i!!!Lâ–-[>{öL2;›Œ)jøðáwïÞ½téŸÏߺuëèÑ£ågÿé§ŸŽ9[±4‘Hôí·ßþùçŸoÞ¼éÔ©Ó¶mÛ\]]™dùùù¿ÿþ{ >·ºÃãñîÝ»Wÿk#3³ê+žP¥LMMUÝ„º¥äAˆpkÛ¬¯yo€vœËwµ–î”N\!Ê~ËMÊ_¡ÊÎMQU\L×Q«"""fÏžíééy÷îݶmÛ®[·nàÀ•¦ Ú²eËöíÛÿúë¯ñãÇß¾}ÛÞþþÎþýû322|}}çÏŸ_e¥ÁÁÁáááÇŽ ñ÷÷4hüìñññ]»v­´¨E‹%$$=z´eË–ÿý÷ˆ#’’’  k×®ßÿ½BŸB`o_¶&²u¡lM (ªì (Š¢¨Ú® ŽŽfµ,¡ÒÖnâ#ÔÑ9¡'ïHÕ‰P½È-¡ˆŒÞ00°“Ÿ7-í Ÿ_Ã{а_i’OÙÅÅÅYYY[·nÝ´iÓ¶mÛöíÛ÷É'Ÿ$$$HŽ.,OOÏiÓ¦ÀÂ… OŸ>½wïÞ 6€Ä½š¤Wl ûÒĉ]\\!&LHHHèׯŸœì?îܹ³äKLÊœœœÝ»wß¾}ÛÎξþúëãÇŸ>}zêÔ©`jjúäÉYíQ!YMjݺŠ5áúõHsóʰ‰P-){&t-ö™Æy÷›:cîðOÆ*¥=~ÃûxôõŸý•RJkŒZö—¡P˜CM-%%E;8 äryÌ55íºkMÓàíí=kÖ,ؼysDDÄÁƒ;vì8eÊ&Í;w˜1©{÷îlF—¤¤šßuØÊÊŠ},rsså§/((ÐÒÒª¸<))©´´ÔÙÙYr!{ÄI[[»´´T(ª«7š£ïÞ='DLÓtNN®¿ÿç{öìÐÑÑaÆ\uuMU·5eÊ?¢šîæd¿¿{ëz¯þCj\‚t{hRóö4 Uî‘‹DÂû÷#òò^%%E;9 ¦(¥]¸/5b'ZZZºººvvvl[[ÛÌÌÌE‹ݺu‹YbiiYéDJjT±.9ͼÐ4]iQ,ƒœœ©—!b±Þ¾}«££S±¢œœ>Ÿ¯¦¦Ö'Còåææ;åÖ­»ãÆ}zøð^]]ªó ÕQð É«Q :ù˜1 Gý1¢_'çÖš.öF+Î)(,b–÷ïjyòóXLC'+Ýk—c™ÇÏŸíÔ­‡¶ŽÞèA.Û7¯ù|š‹½QßΖgO…1 „BÑ–uËÝ;š;·Ö3¤Ç­WÅ4¼ÈÌìngzx?“fï¯Û{whýîÝ»…ŸO¹y-nÃÊö&œžÎ¦lÍêOòlO¥D"áýû'óò^@nîËÄÄÅï-s2Hzêææ–––Æ>}ôè‘™™™ŽŽŽ}9öKüÆl²ëׯ;::’q8f8‘OV{ädo×®]zzz¥Ëy<^ttt¥¹ÒÒÒ*6RåØN‘%77ÏÏo qàöí{ãÆMÏËË«ýš€êÔ«W÷«üSu« äAˆÙó£ Ð8îÒµ?ž½’ºcßñ»7¯íüa ]~hˆ9Fôáiy–c"ûÆ,ükï/3æ-‰Oz¸|ÃÒùŸæååÑ6®^x-þßí¿‡FƧ ô5s°wïÞµ4[¾á§ +¾z‘ù,=-åÇõ߬ٲ[WÏàûvqé½dmЃôw_Е6Ÿ?{8îÞ çrÕ ÛÙÙòxiiñÊš B²³³ïܹ“šš ‰‰‰wîÜÉËË#„|ùå—¡¡¡þùgzzúªU«222&NœXé·gLL̾}ûž?týúõ)S¦'Fæææ—/_~ùòå»wï*~óÂÇcOÅ—ädïÓ§Ïõë×+fÑ×ן={öW_}uâĉgϞݺukõêÕ‰‰‰L²k×®¹»»Woˆ¨{Uv–¯ïDmmíú ÐwÀ€¾|¾ö¼y_+’±º¶lÙѳ§g‹–­[;NŸþÅë×oä/€íÛwÙÙu54´9r“'O™…‹¯b"g3óç/‘Ÿ¾©rv/çÏÚºŸªX…:9'$¦FŒ™Æ,4ne1oÉw›W/ø¦ì’!š”¥){Jƒ˜Z,ŽýçìŒùß0ûïÃ}&;wvÓà5jÒºe_Þ»“àØ¾Ëßûƒÿsϲ­=LŸ»4&òø…¨SŸŒýÔkÔ¤˜Èðå_}–Ÿ—ë5j‚û€álù„þ¨®æ†È=N]»ŽUSÓ „|ø˜¡E¢|9¹Íœ®oooˆŠŠêÛ·ïàÁƒwîܹaÆgÏžµk×.44”9É_Q@@À©S§¾úê«–-[|øð/¿ü211ÑÉIú~û›6m244üúë¯333 úõëgdd%%%QQQ111ÕmF=?Љ9ÅÌišfUJ^,§DgÎÄL:¡[·NÏŸ¿X¹rýĉ3bbÂå, 9º~ýÖ={v88Ø®X±ÎÏïÓË—£™µC† üöÛ¥L±L|Kùé‘‚„ÂR£tÖ^\Çìzß¾·mÃÒäû·Š‹ €¯+š÷H¦§ ÜN¸Â×XÙ:2/™µ±bÓèôòrrÒRE¢Rï>í$ëê?ä&Ùò ¿Œìã Í× ‰b3’òêš³*¿F„ÂBÄ„0'Hh¥\˜ÀŽ3f̘1c*4‰ÀäÉ“'Ož,µPJ\\\¥y£¢¢ØÇ:t¸qãF¥…H&cŠb$''3Oåd×ÕÕ>}ú¾}û6mÚ$U‡ÃYºtéÒ¥K¥ÚÚ¥K—öíÛ×Å×wÓpþüIö1Ç?Þ?77W ÈZþË/¿Ï˜1mäH/øå—­66]þû/Þãèëëuìè,U¾œôˆqøpè† [32ž ºƒõÛ·o¸»õôô¸sçþåË×.œûÕWŸ¯_¿õС#YY¯­¬,Ö¯_5bĺhL BbŠ‹ ¿œæ=yfàÖߎëµ0¼yåbÀtofFB%9"„0Oÿ‰`g0„!Ô‡ 1MDb.%åjóu¤ª€Ôä……ùb±èí»·š|AyáÒ³®æ†Ã9»¿b±=gDQEq˜Fy»ÌÍÊâÅ‹-Z$‰x<…6–û÷ï¯[·®®[U3rfBbq))ÿ¹EEq9øÑX]),,äóµ+^‚È./)Þ½û`Ù²Ìrcc#{{Ûë×o2ƒJDDt‹–:::Æ Þ´é[}}=ùéde½š=;088¨ÿ>¹¹¹×®Ýd_úõ×½ÿ½7,¬gAAá¢E+Ïž=·sçNNí=z,)áTq¥”<1+,MàÉãÔ¼Üìɳ¿V×Ð$“ïAùŒ„¯+ÈËÍa¿{“U\TÈÌ„b/DÌ_¶Ir#5[²´uâòxñ£xùJÕ[X¿z¡ÿ̯Ve¤&»Ð?øðfãáp¹4MšóLˆ+û«'--²|êCÊ¿€˜Ÿ%Ræ·Šµ¬½Òë› ‹¿ÿþ[ñôAAAuט:ríZDù:P¶2H®å•/??ãÆ 9sü™@ì•.ñ"K,²¯š˜üŸ½ûkZk~:ØP¶ÊTd/Q”¡EAâˆëŠã*¸÷¸~.À (‚"n¯,eDÄ"(2dwäû#×ZÖ-AyO›œœœ¦iÞ&'}*Þ]D§Ûöíkݵ«Öë×ï¶xyM»qãÒׯ¥¼Ê\IÉW„ÐàÁŽJJŠjj \3ƽÿ¾!ƒqòä™°°S..ƒBšš"ü¡±°ƒ !„0 uVÓ—xpûªãÐ1y¹¯Ïüo7ú~]ÈÒÖáú¥3®îB{·ø“Éd CŸò?äxkÙw öý’†5¼Ž$GS3iþ¶¿‘Hd“V_KŠîÅ^vu§£o²çïå J*S殬ª¬ðv1?bŸ÷ô%¡ÎjZOÓ’\ÜÆ‰‰‰Ó”PDBä¦ 55HJJÿ—¿“G¨åg‘/^¼hñ²@šŒ%?dÙïé–„¦®®~ܸ™êk×ú 2ƒó"Ü݇â,--tt´†?žÅéj\àŒŒ úöµ27ïçêêäè8ÀÃc¸´ô_9cÈfe½b2™ýû÷kƒöˆªOH†¦¸vû‰Ý—îÙ´¬³†öÄÙËùãg$3¯[ç3qˆ•ºr'µé‹ÖÞ»!çZŸ~ŽT1‰&Ï„8ÝHKÖì”WTÞµqé—ÏùòŠÊ½û¤)ª$=¸y-"$8:•D¡ÊÊ+­ <ºf¡—­Ãmƒ ³—øLf«¥ ¨“Ò~ï”>§3"ý¼Œ SFF±eË‚?^]]ý¸q3êêê"#Ïrw€7ž®¤¤H¡P¾|ùñƒ˜ÂÂ/ööôöìiŽÊÏ/Ð×פ|GF&“cbÂþý7áîÝAA»·mÛ›pSFF!$à5gáÕ™BÈyÄ8çã8³FMœO—“WÚ}2†3/|0¨¿³çÔçä•ÄÕ£~9îþ”D¦L[ø×´…q¯ÔÚÎå߬jNù~‡ÝˬğêYœ‰ý/Ec‡í'æóM°´´ÃØ8 cqßÑ+.ÞÑG"R_Ï?~æ×¯¥W¯žç|ç5]BB¼GÓ„„Gƹ „¾|)~õ굕UÄ~ÏBêêj–ïàÈdòÀýìïïaœ’òØÁÁŽ»€±±•JOrv(êÆˆªO¨¹zÚ °srïÈ7"Bâq9NÔž*ÿºhsÖ:7ðñãgfd<;uêàÛ·ÿÝodd &Fmrº¸¸Øüù3||Võíke` »ví߆†úôC-^ì?dˆSçÎð>¡~ý¬ÍÍMB¼ÊÜãÇOâã<ˆF£Ýºuð®]µ”QPŸ6m¢E+öïßfbbôúõ&“åè(’Ÿ‰ää‹&ÕìÃÞ¼%þ¿.Z„kâO½j2Ÿz«««¿~ýBÈÕõÇûOŸ&jh¨59]W·ÛøñžEE_|}W}ýZJ§Û†‡ã?úùúµtþüå%%_•”‡ sÙ¼ù¿ $¼Êœ¬¬LlìÀÀÝUUUzzÝOœ8¨£Óµq±íÛ7Òhrsç.-..ÑÑÑÞ²%@Díþå¸w„ó#G ,vÌrò©WU~[0Ã;áÁF}=>å~ê«n:BNÌœù4}Þ4Ï»^R©T/·Ž.Ãf/\ΧüŒñnCÝÇŒöš,Üf´O|ò©·%II‰ªª¦Çâ5!äã3ßÇg~ƒ‰§OmVù?UsóÂèÅÄ\l<=>>–û©˜˜ØÆ«7n\ÝªÆ @ÈAȬs‰YgáV „¢­3Q6ȧv6øCîÛ{^ÉÊѾU”÷·ÔÁØ-ɶÎ?-úÎÀ€is–ÉT6! aØ/V1w±ÿÒy“ÝFMèß”ùçS¿#UU3UÕ–4ØNp/hŸââbH$’‰‰¼¼|ëkkOýãÇ<#S‹NÚœ‰Ìe7ç“=?/÷Á½ûN09‰9~•ÐÝŠŽ!ôï½›‡4»)¿¡öp&„¨=çÆœƒPUDµöHZ°¼· »¹¿ÿåååõèÑC[[[¸Í"Üpœ3 vã3!6'&‘~\ CUU},,ÈÓ10å“‚OZt}“¼÷oŸ{ñI¾Žúð¾IGè,á•OÝÒÒÏ¡.ºT¶ÆM\@DD~3™LÞµk—žžÞû÷ï}||6nÜÈ] ""bÅŠùùùgΜÁ§øøø\¿~ýðáæ¦¦oÞ¼a2™¢n$@¾1;‹ »ˆ¾§Eçü—WTqîµ}Ýâ¿¶—”’Þ±~‰¡™¥©…MeE¯ì|Ò¢÷²p|ßßwØÃ†ñK¾Žzžžlicß!®óNà$ÒT¶ð'’ËqÜ_½'Mš„?ÐÔÔܰaÃòåË·lÙÂ)Ì)Éy\ZZzüøñK—. <_ A‡jë¸õ„{cŽ_ŸBl ­ üg÷FßE“3õÖvÎëw…`ˆÄ';Ÿ´èvNnAkæ½ÎÎìn`Ú`M&_gcˆQ_—p/æÈÅ;™ÿá¡ •­H[øðqË–¿–,™Íh@ägB‰‰‰«W¯ÎÈȨ®®FÑh4þå³²²˜L¦½½H2å6ÓàLhѪ휧²r IoÙøSI)ÙUÿ[ø?΂üS°óI‹.-CsóžuáÄ’µ;B‡ÎÝã”i2ù:†¡Û×ÂŒÌzëöè _r:ÈÈ:&ÌŠŒ¼6fŒ[pð‘ߥæŽLÐûw›…󪪪ÊÃÃÃÙÙ9''§¶¶öÖ­[,«ñ ЫуVü]‹‹‹IHˆ-++Ê>ÀéjË¿ÉóV•|ùÌ`2,Ÿ“õlžP7’¨?¢ò©·CµµuD7ü ä „÷crŽ€999eee¾¾¾ÊÊÊ¡gÏž¡¦ ¾,þØÈȈJ¥>xð Ò:Ä£;ºItº«±±•÷š©-ÿ´5:íú笢¬˜€åWmØfmmÕÆ$êôž Õ×3þþ{‡™Y_…®úú–«VmÄãÇ¥KÑ22êÊÊ:oÞä"„edÔ­+++ûôy !%#£.#£^^^all-#£¾qã¶)S檪ênÞ¼!äï`jj«¤ÔM^^ÛÄÄfýú úz¾^ƒ±mÛÞž=íºvéb8b„7›Ín²æ nrAÎÜÚںŋý;w6èÖ­Ç?ÿœÄ'òiÞìõëƒfÌXÔ©“÷R|fñÚhí–hïŽÓÒÒ’ˆ‰‰9rä›7oöîÝ‹~î¢À)((LŸ>}Á‚055ÍÉÉa2™NNN¢h'à&ô Ÿz{óÛ¡3^ºM£ÑœRS3öí;’›ûþܹã£F¸råZxxÔ’%þAAë÷ì9L"‘ŽÙ%++kjjøéÓç²²ry|„NvÚ½{“Éä.]:ã¿à~ø0U^žfaaVQñ->þáöíûBëׯDÍœ¹(<< !¤£ÓU\\üÞ½86›Í§fŽ&äü`|×®C,ð/_*—/ÿkРúúº|šñ}©ƒúúºêê]rrÞr–â3‹×FÝÛÔJ¢íRPP8zô¨ŸŸßŠ+´´´|}}׬YóË¥vìØA£ÑæÌ™S\\¬££Óàn:Ð\ž ÷ÆȧÞ^ý:Ÿº(~1ÖÏŸg]ººuë²™™ñ›7¹=zô‹Šºž™™ejj¼{wàƒI÷îÅ îÅd2çÎfoo‡ >‚÷Ü89Ù7è¹QUU‰‹»®ªª‚ŸjDE£Ñä ‹ª«kŽ9qðà±ÈÈ«ëׯÌÌÌÂÉš5ËV¯^†zùò…BáS3Ž×‚\ PNH¸QYYellÍb±éëëòjg©=Lÿý÷ZMM­––I}=_Š×¬ººz>M¸o°}<¡ÿ.Çq¦xzzzzzržÎž=Ÿ{ãÆ NI<Ìp–¢R©7nܸq#g)a‚z*ÛHOŠ?°±qäžþìÙ SSc%%Åýû·yyMûò¥¸[7íM›Öþ²BOOUU„¸¸BèŸNîÝ{¤¬¬œSàóç/¡´´'øÓE‹f㌌ ið/5j„¼¡œœ7zzÝI$ÿšù,Ø‚f´ ÿÖ> ?½xñBèu‚Ö äL'H>uApç\-#x>õvÂÜÜÄÝ}è•+1žžS  S©Ô´´Œ/_Š sÄĨsæ,©©©8Ñ+ ÀßÒÒþæÍ»!!ç'OöFééé"„bco÷í묫«Óä(àf¡ššÚ™3+(Ð΋àÌ2553Æ-<½‚‚ÖïØ±?2òêÀý—/_¸‹3÷رý&&FçÎ…çææIJJÚÛÓñÆ/kæµ /ü›Ñ2¼6Z+«Bh¶LÿU'„ÐFCÿªª‚_.óîÝ¿¦¦Þ“VU•ÈÈ(‹¢• •¤¥Õ8ïWQQInî3«³¿ÙÙø ?dÒwššzjjÍM@YUU‚a:uêÄb±~]Zp&Ôz åùóçfff÷uu=î´=DÛÙ ÁoLÀ0L\\"7÷EËöÐqðŠ ÉȨ¯ËÞŠ >“»å) ïÝ!4îŽ~üø¡ jj¶j½œ¯Þ666£FÊÈȸvíZ·nÝN:E¥RgÏžýüùóþýûŸ?ÿÒ­§§·uëÖÑ£ÿKw­  píÚ5:Î][“yÙ###ýüürrrB!!!3f̈‰‰qvvf0***7nܰµµmÕ+ù#x&ÔNnL ïýç°;ZÔöîÝ»eË–õë×ÿý÷ß“'OVSS ’——Ÿ8qbPPà¿k2/;NÏÍÍÍÏÏ×ÐЈºµH IDATWVVŽwvvNOOÇ0ÌÒÒR¤/íÓNnLaÃ{ƒ¶ATw4'gŠ››Û”)SB«W¯îÑ£G`` ž¦vÖ¬YaaaÜåäÔàN«xäeWQQ144Œ‹‹óòòŠ‹‹[¸páÝ»w1 ‹‹‹³¶¶ƒC*‚ßÛv‰°á½A›i'o‡©©)þ@EE…û©ªªjyy9ÏÅá•—ÝÎÎ.>>ÞÁÁ¡¨¨hîܹ۷o¯¯¯·³³æËèÚÏ  #ò×ävr¼í÷]md2¹AZÕÆéV›œÈÙ©0¾yÙétz\\\\\œ­­­’’’®®î£G’’’ètz“uv4ÍzㄞÊ^Dx&$H_q“Ìûöíûßÿþ‡§ÜF1 MMÍ£Gº»»3™Ìõëׇ††[XXìÙ³ÇÚÚZ/áOÒÜP4NàÔàPØø)BˆF£•——㋊Šðsî#)'/»¤¤$âÊËŽ¢Óé3fÌˆŠŠ²³³Ã0ŒN§;v¬¬¬ÌÚÚš-Ð xç½oLhÎ).øm¨©© ñ>IÞÌ&H_q“Ì£GöóóÃo'Eݾ}›Édººº"„–/_ž––Ö¹sç . ><++ '´C×I 'ê`?÷ñpÿ0`ÀÙ³g½¼¼B«V­âœ«_æ"dÓq'pb2™,‹;$H¤ºº:YYYîþ|njj*§XJJJß¾}œØ‘Édîp­qÐj·0 ã³øRÀv¨-: >¼|ùòââb|à†±cÇ2ŒãÇ#„®]»faaáììܹsç¾}ûÞ¹s_ðY³fùûûs_Q¿ü¸/++kgg·nݺ¤¤¤7oÞlÚ´)++ËÕÕµÉ뇷nÝ:uêT~~þ®]»RRR&MšÔ ¨hjj&%%}þüùëׯ¯="Wƒ9³ø,þg#fàW„„°ïÜ»¾§§gÿþý1 “––æž[SSSXX¸sçÎ1cÆÜ½{×ÎÎÎÝÝ=;;ðdzÙìY³fa|,à—Pû¸ôª§§çááaaaqùòå'NØØØ4YrÉ’%ÑÑѦ¦¦ÿüóÏéÓ§ ðõõÍÎÎÖÕÕíÙ³g ZÒÊÅkp&Ú¡¶øYOã㿉nĈ³gÏFmÛ¶íÚµk§OŸž:uj```BB|f~_ ò©wîÜùôéÓÜš ø(à‹qïmnnžššÚd%ÜŸG½|ùÊgq@ÛyŸB•{þ_JJJNNN__Ÿ3WOO¯   %%¥°°Ó[Àb±&Ož|êÔ©k×®‰¢µtD}«“–V#d½à· òñ„PS?Ëà<µ±±yýú5çéÛ·o-,,\\\8ßUB}ûöݰaèQ£à{kËÀðÞ€(jjjjj?"?âîœhütÑ¢Ežžžƒ êׯþköñãÇÓh4N $ICCC[[‚Ðïò©·7mÿu¤ºúS¯üvNõæââràÀ-[¶|üøÑÈÈ(""B__ŸØ&ýy`xo@»%òËq ú‡˜8qâĉ9OŸî”––69Àï’^ÿù`xoÀÃ{ƒö†÷¢BxênÐ@{ȧ@0¼÷Ÿï7Þ»1ÂüNOO;vlVV•JåÕ^ÜÜÜ<=='MšÔâµ  ï Ú'Þˆ†a{öì9vìØÛ·o©TªÍŽ;,,,BAAAaaaYYY222ƒÞµkW§Nš¬¡ñ-þ¨ üX¼x1…Bi‡BþþþS¦LÁ3Á ¸ˆHAÇ*h‡àË ÎñNII) àÁƒ eðàÁ555¡k×®M›6íÞ½{GŽINNöôôlVýþþþƒV1^rssoÞ¼éííݲÅûõ뇺uëV‹À†÷îÞ›ûb”††F=òòòôõõ55µ°°pÿþýnnn>”““ÃgÕÕÕyyyiii­[·!ι|÷äÉüŒ‡À¿«ªªüÞ qc²²² †©©)w±‚‚ü´´4ƒÁ¨¯¯oq³Eª-÷k»á½Ûóç°cÒÐøE†¤””MM½Ö¬ßdeeMLLLLLètºššZLLÌØ±cBuuucÇŽ­­­ŽŽÃ0ÌÅÅ¥] ø­¤¤T^^Þ`VƒÆ°X,„PII‰¬¬lãbååå222ø«ã½Ö{Â/!ᘳó_+¯D{&Ä=¶·ŸŸ_çÎ÷îÝûêÕ+YYÙQ£FíÚµKJJ*22ÒÏÏ/''!2cÆŒ˜˜gggƒ¡¢¢rãÆ [[[Q4²ãàsøûú5ÃXø±˜Ífã‡eüè*..Ùš•6™Oç?v×××{yy•””ÄÄÄHIIqÂU»ðÛÈÈèÍ›7ܳ7ÆÈȈJ¥Þ¼ysäÈ‘kxýúµ±±q;‰@|~1&º=¡ƒ ÓgBj‘ßÌvøðለˆTUUEDDìÚµKOOïýû÷>>>7n ¤Óé¹¹¹ùùùñññÊÊÊñññÎÎÎééé†5èBçè8\LŒ*..Ž_©¯¯§Ñh!!G„R9†a¾¾¾...]ºt)**:pà€”””““›ÍöööNOO~ûö-^ØÈȨñ¹2ö}Àoggç .¤¤¤:t¨Áé >b÷رcÅÅÅ›ø™Ú+M?!Ä5àw“‹÷ïß?00{u£  0gÎ2™Ü»wï/_¾DFFzyy#„’““íììÚIâO¤{¼ˆär÷GŽ{loÎå~MMÍ 6,_¾|Ë–-***†††qqq^^^qqq .¼{÷.†aqqqÖÖÖíü:Æoÿ¼|ùÜèÑáO-,ÌÞ)Ä$  .,,,”““£Óé·nÝRTT¬­­‰‰Aqß»üüùs]]ÝÆ5à~ûøøàó69à÷´iÓtuu•••ß¿ßÜòY|ذa‹-zñâgl‘&³uëVeee??¿‚‚%%%{{{„P]]Ý7ÚÏï„ø¿­¢Þh’ÈÏ„¸‰‰‰«W¯ÎÈȨ®®FÑh4|º]||¼ƒƒCQQÑܹs·oß^__ogg'êæM.,,ÔÓsbzúÓž=ÍÏŸ?)''ÛúÀϹwìØ±³0 “À÷ƳL!vÀo99¹iÓ¦:ujëÖ­|C&“W®\¹råʳ"""zõêeffö[|‘Ñž"¹E›ûºç¾Ûªª*gg眜œÚÚÚ[·nqºètz\\\\\œ­­­’’’®®î£G’’’èt:ZG÷‹F“»x1´ÿ~.œâÜ·p+V¬(,,d2™-Xöùóçÿý·Ð›Ôb¿<­=´=‘'Ä9æä䔕•ùúúJJJ"„ž={Æ)I§Óg̘…_=§ÓéÇŽ+++³¶¶ð0 øäŠ &wñbÈ÷îh¡ùò©kii]¸p¡eËîÚµK¸i"ÚàE´wÇq×ÒÒ’ˆ‰‰9rä›7oöîÝË)©­­­®®vóæM<M:ÕÂÂBFF‚H±X ÃÂB$"‘(d2úþ»Ö‚|êí Ÿ·U¤{|´]ª7…£Gúùù­X±BKKË××wÍš5œ¹t:=** ÿ% Ng±Xt:½ÍÚögãuIN¾öý+@"á2黯ò©ÿFDº'ÀŸh/Ç5è öôôäN–<{ölάS§Ná0 ëÒ¥ Þk §A¢C"±µ´~ñEÐÀžˆ%Ì ¤ªj†?øzþ$fffÜO»u3ëÖÍŒWa¡àì  =kƒ=€_f‚ ÿÚàm‚=á·oh`P;„ €0„‚Â@@BAa Ðr Ǥ¥Õˆn¿1B´ ê @+A@BAa  !„ €0„FÈÃ{ÿIªªJˆn´;ªªfBüy!~ŠŠžÝh_TU…9*<¡_Ðѱ'º ðÇêè}B&Ì’‘QŸ2e.Ñ €Ž¨£!Âå8ƒ±{÷¡³gÃrsó$%%­¬z]¹r–L&×ÖÖî ‹,(ø¬¨¨0t¨ó¦Mk””Búú–ŸW¯^–“óúêÕÝ»ë=ºçë×ÒeËÖ~øçì<ðر}²²²Í*Y_ÏØ¶mïùó?¨ª*ãà/))26¶þðᣟßâ¼¼üèèëÒÒÒ«VùΙ3­OŸYYÙ¡ðð¨ðð(„PUU¯— É’–èõ !Íœ¹?‚ëèt¿w/ŽÍf“Éä)Sæ^½zƒB¡˜˜æä¼9uêljjz\\¬¸¸¾àÞ½‡I$R}=#33ËÛ{zqq‰˜˜xmm]ttìŽÖ¯_ÉY… %gÌXxéR4FsvvHMÍØ·ïHnîûsçŽs*ٵ렾¾®ºz—œœ·Ë—ÿ5hÐSSÃOŸ>—••+(Èëètmý¦Ð,­½—™™…G 5k–=žôøñ¿©©÷(ÊÓ§™W¯Þ@:´ãáÃÛ11á¡çϳ¢¢®s–ÕÑéš›ûìС¡¼¼ü™3'úôÒÃcB(>>‰{-¿,ùüyÖ¥KÑ¡[·.‡…ß¾}!u=33‹SI¦ÉÉwâãoˆ‹‹±Ùì„„GÁÁGìBNNöññ±ññ±­Üš¥µA(-í þ`Ñ¢Ùø##‰”‘ñ Ї ›ÞjjBééO9ËŽ1DJJÒÐPêå5 !dllˆ*/ÿƽ–_–äTkcã(#£Þ£G?üé³g/8•¸º:Q(YYEEE„PEEE+_;€VÚ-Ú$©¹‹ÈÉÉ „( þ”F£!„X,Bðf•Äÿ“H$ŸyÜ-Ñ××mP BˆB!7^€¶×Ú Ô»·þààÁcþþ>¡œœ7zzÝ{ö4ǧGF^›8Ñ+99íÓ§B„P¯^=Z¹Æ&áÕbæà`çää€b±X‘‘×ÌÌLø/(&FEUUÕˆ¢Uøkíå8SSã1cÜB7n37ï×§Ï@KK{‹Õ£‡éðáƒBóç/·µu:Ô!dffìæ6¤õnÌÜÜÄÝ}(BÈÓsŠ»ûøÑ£'ëêöš>>IKKcÅŠ%ø-Ú|Ì™3ÕÞÞNLŒúôiæ“'¤Ú !4[¦ÿªBh£¡?ŸÊp¼{÷¯©©·èno'ªªJŠŠžsÒöÀï„÷_ZZ­ññ_ð¸ #£¾.{+B($øLî–§1a  !„ €0„‚Â@@BAa  !„ €0„‚Â@@BAa  !„ €0„‚Â@@BAa  !„ €0„‚Â@@BAa  !„ €0„‚Â@@ªPj©ª*¤˜ªªYuõ'¡¬À@8A!TTôü—eTUÍZ¹''wá Îje=Ú¡!„©©7Ÿ¹p ‚û„BBÎ[[;**vÕÔ4Y´hEMM->ÝØØúò嫜b:é%&&OŸ¾0))Åß?@FF]GÇ!TUU=þ2uu#UU]oïéŸ>ó2´ÁAˆB!oß¾áÙ³¤ N¦¦¦oÞ¼ƒOá'ôíkµu놪ª‚wïž „.\þðaê•+g<ˆ)/ÿæé9ð¶j;€Ö"8M˜0ÖÞÞNSSN· ð޾.ø²%%_ÃãvïÞleeillxìØ¾ŒŒgÉÉE×ZÂEpJJJqrrWUÕ•‘Q=zraa±à˾zõ†Íf[[÷ÁŸjh¨ijª¿|ùJ4- |D¡êêšÑ£'999¼|™RY™Îf³ðY$‰»$Ÿ‹l Jø„Þ¼yW^^áã3_YY‰D"=þ’3KNN¶¢âþ¸¨èKuu þ˜B¡p’.™LNIIßæçúø±ÀØØ  _€V!2iiiHHˆ_¿~ !ôæMîþýÿpf ÐïܹˆÚÚºÚÚº5kþ&“ÿk§††ú£G©……E¥¥eÊÊJcƸ-]º6--#++{Ö¬%={š[YYób4‘AHAAþÈ‘=þþ††}æÌYâã33kõêe’’Ý»[ôëçâì1$ä¼µµ£¢bWMM“E‹VÔÔÔ"„øŸ¥å;Ç †¦¦Itt,BˆÉdêéõRTìjo?,%åqã5Y'¯´ÒÍ›÷¬¬zÓh4„PuuõŒ‹TUu û\¹ƒ¨ªªž?™ºº‘ªª®·÷ôOŸ ñévv®;vìŸ4iŽŠJ÷Þ½ÒÓŸ>{ö¢ÿ!JJÝFŒð®¨¨À‹ñy½Ü«.//÷öž®¢ÒÝÔÔöêÕx>—à8Ë–––7CYYÇ̬oTÔuüšØôé “’RüýddÔut,,»nÝ›ÜÜ«mr ÛÙ¹nÞ¼ÓÛ{º¦¦ ÷–©¨¨˜0a¾jüÍmò¥@- B……Esæø®Zµ4;;õÎ+ŽŽøt …¼}û†gÏ’.\8™šš¾yó„ШQ#rrÞdffáeîÞ}Àd²\\!„V®\—xîÜñ'OÜ܆xxLøúµ´Áºš¬“WøŸšÏkV¿{{ÈGüñÞ½Gììlo7föì%•••¡… —?|˜zåÊÙbÊË¿yzNÁ0 /¿ÿQg牉7{ô0™>}ኛ7¯½{7://Û¶}x>¯—{Õ{ö:ÔåéÓÄ™3'Oœ8;'ç€Íž7oé§O…Ä„…:räd]]=Bèĉ}ûZmݺ¡ªªàÝ»'Ü úûDF^½yór·nÚ êäµ…BGžZ¶láÇ/6n\ÍÙ2 ø½}›{ÿþµ NìÝ{_uã— ´$•”|E 쨦ÖÙÐPÒ$/|ú„ cííí45Õét›€ÿèèë!uõ.ýúYGDDãeÂãFŒp•¯¨¨8v,ôŸöZYYjkk.[¶PWW'&æfƒu5Y'¯¨«w±±éÝ’Í€‹Åºuëž««þtÄ×iÓ&èëwÿë/?„PzúÓ’’¯ááQ»wo¶²²466}*¼t)ð®]µ´´4$$į_¿…zó&wÿþ¸ñôô ‹Œ‰¹5fŒ;>EAA~öì)K—®‰ŠºžŸÿ)#ãÙ† [_¾|ޝ:›lBèÒ¥h -xEyyù¹¹ï  ó)£¬¬4fŒÛÒ¥kÓÒ2²²²gÍZÒ³§9Þ;"^¯·ñªoݺr¾ àóž=‡RRÒ'Oö¤Ù**ÊÇöõ]ýâÅË—/_­\¹J¥"DBih¨?z”ZXXTZZÆYÖÑÑþĉƒ3g.j2.òÚ¼¶Œ›Û€€ÀººúúzƆ AøÙ’ [ÐÁµ$ÉÊÊÄÆÞqpahØgÏžÃ'NÔÑ骠 äÈÿCÃ>sæ,ññùé¶iw÷¡Ÿ¥¥¥û÷ïË™´~öì)þþ&&6#GN|÷.WYY‰{)^u6Ù„PAÁçGÒZðŠbco;8ØIHˆó/¶ÿv+«^#Fx0TNN&,,˜×Õ¹&5ùz¯zÉ’9ÑÑ×ÍÍû=rÄÀ@OÀf>¼«K—Nýû=zòܹÓ(2>Ë×wþË—9úú½¹ï•GázàÀö f%&&7¨™×æåàÁ!ƒÞ¶¶NöÇ;ܪ€ŽŒ„‡-ÓÕ !´Ñпªª£ ±S^Ž ð¡Fš4|øàéÓ'¶}3Z³j>˾~ý΂ž›û”sëAÛ#p«øÀ‡rpP;UU3¯¼½{÷¯ ã ÉȨ¯ËÞŠ >“»åiGO׿ßáÃÿv«n°lrrZeeU¦Ÿ?-]ºÚÑÑžÀÔ¸yÐ!„òõÿ;®ºÁ²555¾¾«rsó$%%vïÞÒêÖµ [𻀠ôç°··{ò$èV@3@S„ €0ýr~—BtÜ ¤¦¦¦¦øÉÌ!„ €0„‚Â@@BAa  !„iaÆ„„„cÂm€ß>³e ¶0µx}\Ž@BAa  L‡O¨®®Šè&LBB¦ÁqñRBZÒ~Ô×+6˜Û¤ñ6Ï|vk¼Ÿ4W‡ BaŠŠúD·0¯__WWïÙx:•jÒöi'jj."Ô¿ñtØ&&Ãg>;?áõÙi–„0 !„˜Ì¢B&³!¬©9BÃXmÜžö€Dªæ1¶ICðÙijì'­Õaû„Øœ¿œœ7®>ññF,7oðø2ÓøøGC–ÅÅ=l;· ŸýDP4a\æìs¼ø¢  ?bËÓÿ/>/(ÈÚúòýûÜKÏ>þÔà~á;E'ì·0ŒÏNƒuÈ?Ä÷ƒÔ’:¿ÉÌÊLyœ—ðàÎý;‰^½Î.-ýŠaì²²ÒûîÇ%Æ•|-&ú…·p›ðßÃ>þ¬­¥³mÇ^˜LV`àV·QÏže yï-øì4o?\‡»×xÛ­ñ¹}û–íÎÝÛÇ{Olü?6öz]]}lìõ1c<£££¸ÿOðšæ° ËÀïˆz1Í×äN#´ýéÒ’mRZV–óú•¬4M§›ž„„$•JE1Œòò²w¹ïJK×1êú;•|-I’á4pš-R¿Þ&l6)))qʤé—.]5ʽqá+W¢V­Z{9ò’ë`çßm—ƒÏŽHtÀ „úéKͦKâŽ| ú{âøÉçΟnüÕʵ¦=,2Ÿ>¹zõª‡ÇÈÿÿu†ïW¤v…;yÍáÏÄ÷íkÆ6Éyóækiy¯Öâââõõuµµ5L&!$&&.//ß«g&“ùoÜ]ÙúúºÏŸ Ûóç³MøïíQÑQ³f;v5Z§»nn]5¹ç–––éê%&&Nš8ùàÁ}K—.Z‹E>;MÊ¡¯ƒ^Žã¾²0æ\høÑ~«ÒŸ¤4þï¿bõå+áOÓ_¾6dÈÿ·FM#úʬ°®á~vß/)ZÏûyuµ,›>ýÂÊÊJëëëH$’¸¸„„„$B¨¦¦¦¢¢ ÃØýlÿ»•ˆÉd´ µVVôÿ²˜œœêýû¼cÇao~û˜­ =òò¥1žcÿý÷>™Le2ÜsKJÊŸ<Épww¿pþÜ ANDþ´ÏNKßîÿñß&‚ê€ACè§ëÚŸ˜šÊz.>Úr2ŠƒjÈJ+8.ÔÄÿËHÉÏÿ_? 5m‡]d¥ð¹ø—%]ådF¯1=ê{‡SU]]UNÎÔÔÐGN<~|>'ç.ƒQ×vW­!Äã‹ gôïýû÷³fÍ×Ö6PPUÕrs{³¹;qpði2Yfóæ­„~tùí'VR\R’÷±ÀÌ´GMMumm­„„Ä·ÊoOže$$=¸}÷fæ‹gååââµµµõõµ, !Äd0T2r¤™,³k×>Δúú:UU-2Y&55íçÖ xtÀv233î6á¿>rx„›{äåËK–ønÛ±ÅúQ¾²²&44dÊ”©gÏ„zŒzªñâÙÙ·><ÆýWPð”Ïêž?þôéYË>ͪJˆŸAþFŽôš6m6÷”yóâNÜǤYûIót¸Ëqß÷¤[ÐkÐ „е¾O÷ìûçúηw|¼råÊͽï-Ô8é—¸ìäàµ#Oççç_Þü",,,ØÿáÉ“',¸Ñ½»Ú€iܵ½zu“D¢“¯«ûVRòšB‘îÖj¿8Ä";;ÇÎÎÉÔÔxß¾ºº:ß¾U>|˜ìï¿ÖÕÕ©YM 9Ó§ehèÙ5küšµ °µj›`––þd½K}}=ƒQO¥RSÒU×TšÊËë–––§>N–ù¬[×îÖ}¬ÙlVEEBˆÁd6ªÓÔÔ8}úÜÒ¥ ñç117¤¤¤¾7£Aúå+ÂÂV®\*à«hª†Æ¯”ç,Žùóæ92qÒ”˜˜kmܵkÏÊ•KñEöí;´víúðð07÷‘î_껤©ª0%%nÝ~üôDBB–DB,V-¯5R(’ŠDãÆ"‘(|š*xUœ*y/*ô8ÆõŸ×^ ¶åÑFëê€gB5ú6Çf³³^æL?éâÅ‹...טwêÔiÃ^ßÕÁ;ïNò¼þü„Þ½{ö說¯¿ïxдiÓ9\[[Ï]I}}uUU‰ŽÎyym*ULZZA[ÛZLL!TT”ýìÙåääàÔÔ3ïÞųXL Ã>~þôé%®6°RSÏ”–¾ÇøúøñùääàçÏ£++‹5k²N Ê‹_?y–œ|25õLNνßæøôÒÄ‚>FFwîD{x 577î×ÏjéÒééñøÜªªÊY³()iÊÊv5j\AA~“•¼ÿ>..ñìÙã……E>Bˆ}ùò]]3|npði2YîæÍÛ±Œ:YÙNIIbŸ8laa+)©¬¢¢=wš*„Ø12êÅ©¹®®FIIóêÕa\fùu %_KhJT*µ¦¦JLLüɳ ²«³ƒ–¦MN&óE–Ó !3¦Îvè$-ýßïíÙl6“ÉlÜ’!Cœ>|È{þü9>%4ôìĉc¿·/ƒq¯^½®{wÓwïÞ!Ä.//óôœ -­ª§gÅYdàÀ!;vìÁË[Yõÿë¯ Ã‡VTÔhÍ6á>QT”ï0pPäåp—ÁI‰ C‡Žˆ‹KÂ0,--còä©7bc]®\Žpvv‘’kò„ƒJ•”–V—Àÿ0ŒQ[[ššzæË—¼Ì§O™Ÿc2k_¿¾_YYøöí¿‰‰‡?>‹aسgWòòÒ²³o¦¥þôé9¯Ï›ÍÊËKKO¿œ|êÉ“ð¯_ß7®ªqÄòÙiæÕ?î)?Þz&³~ÍšMMIIe[[‡G’/eeÕõêu®®îÚÚ†zzæW®D‹¬‘­Õƒ¾Õ~Úšl6“&§pÿþ¿#FŒ˜µÑuǼ°“K{^fâ²A¡ëÃÇ®uÒ÷Ÿ!‡–Æî½;{øÀ±/^\8QlìM cq*¡P¨d2¥¼<ÉüÆf×aƒÍ®c0¾a“D"uëF·²šjf6²ººìóççaŠŠ]kjÊ™Ìÿj(/ÿˆ[UÕœBËËKþö퓱ñ>}¦uêd”}›Åb4hs“u2Uo߯kjZY[ÏìÕk¼²²˜˜,÷NÃããÔŒK ÅÅÅwï>X¼x.…BæžN&“ð³g/JL|týzÄ£G÷ÊËËÝݽ1ŒÝ¸žÐÐsNNzz:cÇŽ 9‹fggûîÝûüü„°øøDee¥øøD„°Ç30 ëÝÛ!ŒB¡ìÞ˜““~ùòÙää´ ÂÆ“›û!99¯9:úº¸¸¸««cë.)ºM >ëètg±˜d2¥¸¤¸´´Äª·gnmmmUeeiiÉׯÅee_™,&ƒÁ`2LF}Bâââ^^£BCÏ!„}ýúõÆÛãÇý¹ÿ=^ºtexø•ÿ½®££oó7oÞ%%ݾ|ùìÎûëêê/‚:xð~~KJK?´n›ð;098ô >é2xèÅógÝÜ=?N£Ñ”«ª*ÅÅåÒÒÒœ¢£.Û °OIMTT¤5U†þµ°žóG¥ŠwëfûáC2‹U_[[úñcª®î@ié.zzääÔtu°¼oß…Š¡¢¢—šš½mmçjkÓ)‰ÆŸ„Ø><,.~£«;ÐÊj†«„„‚¾¾wUMp[ÿÙiÝguزe«ï߈ÍÎNóð>tèè’’’&ßî×|øðbÿþíãÆMÏÎ~%š&µV B¡ÆgBØ?G?þÒ¥K Ý·n¸4fVŸƒç^úïYpuçÝI+‡‡Mô=°ð¶_ÈÐùýn^4vìØhkë±X,N%$¹k×~ùùé©©§³³o<­¯¯Æg)+w§ÑÔI$’„„”†FÏ’’·Tª´˜˜”œ\§ââW$ð¯_s•”ºQ(”ººo……Ù.4š&™Œ©ªêIJÒ¾}û‚‰»ÍMÖÉ`Ô"„TUI$™Œ)*j°X?:¥xí:\—Y~ý÷æÍ[„‰‰!þôÑ£11eü/!áaqqñ… —öïßfcÓÛÔÔ08øÈãÇO>Li\Ohèù©SÇ#„M™2þÂ…KuuµªªÊFFú$ „=x¸xñ\üq\\¢Mqq1„°)S¼ ꯥ¥Þ¿¿í¦Mk/_¾Š¦¤¤0b„ëéÓç¿×|nܸÑT*¥5'Á·IÞÇ%E¥úúz …’÷ñƒžnWNüýr\ƒ6`“&yŸ=Æf³.^¼<`@¿.]TnÂ0lþ|ߨØÛ÷ï_ÓÒRG+..ŽˆˆÚ¿»……©¹¹ñŽ›˜?*ÿiY/¯QööýZyˆá&„Z¹Ògó–#ÜGž?vúô™aa J=z4|øˆˆð .ƒ‡=zhÊäq¼*(*z™p 99ÿ+/ÿŒa˜’RWMýíÛø7o”•u;u2f0*Øl6†±0ŒÅ`TÖÔÕÖ#„TT õŒªúú2EE­ÆŸ&³¶¨(GWw ŠŠ>™ŒIJÊÈÈ(bØOU5õº„ðÙiÖ|ŽLVàüýóÏI|EåååGŽœ8yò Mï®]5W®ôÑÓë}½ñÛíééamm‰6dˆ“ƒýäÉÓ"h'ÏýDp®Oè»ÛðgÏ3}}–FFFÚÚÚ^‰½8Ñb«ÿñÑAÓÃÿ—²hÕsGÝ:)Ê?ÔmñÀÖþoê© ·:´aýúE‹ý%++M"‘ðªTTº©¨èÕÔ”UT|..~õùs¦‘‘«””|eeQ^^zuõW6›‰¢PÄ( ã›’R·¢¢—šš½˜ÌºÒÒÃÝܺºodrWëGÆ”&ë”’¢ÉÊvJI9./¯N£uQRêŠa‚¿ÅlÁ7Ý÷S@Ô£‡Izú¿ß¾UÒ鮯ÊÎ~Åf³ûöíƒÏÕÔ좥¥ñâEVß¾½¹«HJJ)..qwwEˆÝ¯_UU娨OO÷þýûÆÇ'dWXX4þ´­[w××ׯÇ'öïo‹W˜ðhåÊ ééO««kB4š>}ÊïéÓíܹ©¼¼"6öNRÒM_™ïéו”–UP©bÕÕUââò>˜› à^ª“ªÒ¤ñ#«C³µµ”––ºsç~hè¹… gý|!„mݺ›B¡¤¤ÜíÔIŸøòe6†a66øIÔ§…Bá^„óÀÐPO°Í›üâ¸#%%¾v߆ë6nØyÙ×wùæ-ïÚ¹ûÌé`wÑk7mZC¡xÕÓ OHJJ‘ɬd³ë»víóìY…"¦§7†Åªe±ê~nÒ‡`iiE«–Í®GUV6þŒÔÔ”a[YY—Áø†W‚a̦ªjw6Áa#F¸nذ’ó|Ë–]ß¾U"Ä~ñ"‹Á`Yq—vwÚøí655â4ÌÜÜäÅ‹—Ân'ÿýDP4qŸY³X,iÅ 8ðä©S³§.:|tå¨c~‡=÷ùDÅLXîòwÄÄ9ô=[Ž/ Þx',,lþ¼y\µjõ™3a³gOþ¹n†¤¤¬ŒŒ‰ººùÓ§a_¾¼ÕÒêùêÕ]55sSSw ZYÙÇÌÌK‘1 STÔúð!¹¦¦âÛ·$IIIÁ¨ÀÛF§/¡PÄ~ª—ñÓl6›É£NdhèX[[]^þñÓ§ÌOŸ2‡R(ÿuÏr‚%¯­"ȦÓÕíŠÊÊÊ633BIII˜™•••s×@"5¨­á;$ä\ii™¬¬Ö÷—à =ïééfgg»mÛ¾úõ³VVVÔÓëþèQZBBò‚3ª«kFŒçë;ïòåee¥ÿM1b^³«ë *•{'7÷ƒ¡¡ž¥¥ys>|6˯+¡PÈL&“D"c&F¥²X¬Ö}2±‰ÇnÚ´=3ó¥‡ÇЪªªïÍø¯Îú^½z36ööäÉ^œEÈdò÷«£ˆB!BÜ'C!ôýìP<·‰$ˆF“^¶tñæ-›Öýµ~]À_ë6ìܹ}Þ¼ë7¬[µj™„•O%Tª„””<ƒQ‰?e0*Øl&BXuu‹ÅÀ06“Y‡ã{ øW¢­"‘Èl6Ã0>Ÿ“Y×h/ý©ªŸ6‡0>;Í¢¤¤Ð³§穲²â·o•al6 !TQñ^V¶AJï†o7“ëæÆË¿Âų¤ƒ^ŽãÆfc{öì;vlhhèH¯Ñã“7L ž¹Ñu±ÃÿvFÏcºöà™À}k.œ:uÊËËëàáÃînn÷îÝ300Ãï¸ýÆbÕ1™ÕbbRLf-“Éd±]»Ú‘É”šš/¥¥oÂð]šJ•¤Ñº¿.-ý ¤ÔD"±XuRRò¤ÿ·wçQM\kÀïLö‘°HE@PEÅ jÅZ7+E—ªÝ”U ZwÄ ÷c±Vĺd1ˆÈ&mk}OŠ"®(êCe•=‘ì™™÷G$FH*,÷wîá$“™Ë½_æËÌÜ$ÚØX*¼ªE*}óEúbñ«öê¡ÓYFF#íì<ÅâW2™D©aH›;Mˆº©¯Ïþì³I‡G©\¦ÇEQôúõ×WJËËËËÊ*lm‡+¯)‹8œ”Ó§ºs犼de%feýYSSãääXXXœšš)ëãääxüø¯MMÜ Æ€?~ü¤©‰»v­Ÿ¾>Aˆ‚‚‡Šf“Éè’%±±œØØÄ¥K=Õ¹¸ú¾1aÐ)b‰˜DB ‚ÐbiÕ×7´·¦H,̾üב£ÑIç/Ö7¨®&À—.]“scþüÏ j˫ƛ Oœè”tÚ×wMròëKÍVVA—Èï>~üD"‘(?)mÝþ'1QË€:+¿û:të&Ï ÏKœ2ejXØ–à 6[ëÛŽãRE€À0Ù³g¹ÆÆcôô,JJ.+^¸ÚÐ~ŽÈó«©©¬Õ6ïfº wÔ)„Ê“%ïnccI&“³³ÿhk+ ütçåå+ºq#߯fXW7² öÐ'!@¸¢äåÝZ³æ‡óçÏ/Z´èâÅ‹«V­ÊÎÎ^±|EVVÖ¡àsK×Θ=40áÂéßG$$$^½zÕwÕªK—.yyyýòË/jj*30°Â0Aà(J0`Ø“'p¹•bq3Ÿ_WQqG~ŽNQ(F›u67×VW …BaãË—÷  ]ÅV ÝLSoO:rdOaaÉôéóSS³<(ÊÍÍß»÷0€J¥èëë.\è¸áæÍ;/_`ooçèh¯¼yjêo€E‹æa%/3f|:lØÐ¸¸$SÓÁÆÆ9œ'§ñ€I“ÆŸ={a̘‘òƒ>cš‘q ðäIé¡C‘ÊÕ.[æ’òÛíÛ÷/ž¯VwÚÑÙ˜h±˜¯^ñ@d2©­­ÝõwÛ\ Ã0NâÅ!ƒ­ü}ƒ&gf^i¯BSÓÁµµE?ÿ¼¯½fΜ{ìË/}³³¯ôõuÝÝ]6mÚ%K$ÉæÍáïz=ýÇZçŽjò¸yy÷ײŽO?`ï8Ö~\zZê¨Q££Ïü:sæ¬Ý#ÇÆÇ§¯1¶ÊͽÓ\_¯º9„L&æókùüzy‹ù——ç“É4SÓI&&ŽBa}]ݳ–D`r¹•R)_&É÷pD9‚¢d‹Ç/óxÕbq3WÅåV¨V¥Ò°®É÷Çfëøú®XáBfyyåíÛ÷·lÙ]XX¬ºæï¿ÿçäÉ¸ŠŠª½{ÊÏ¿·|¹w7µ“úà xëâ*“ÉÎÉÉ™6mZ||¼§§ç‰'<<<®]»¶iÓ¦»wïr"®Þ¹Ÿ±7êÖ­[ëׯONNvqqIKK[¸pá¹sçvíÚõkËÄ2“©WSSRT”ýèQVCÃs3³‰FFcÀ‡ ™øôé•‚‚”ÒÒ\CC[ù»~‚ tt‰ÅÍ$•Í*•¾žÈ`d4ÚÐЦ¬ìæƒiOžü%ó =ùü9¥´Y'Š’¹ÜªââË)/_ :…Nï¯|ѸC=²¶¶ÈÏ¿dnnâï¿ÎÞ~ª«ëâÂÂâìlŽƒÃhð¨¨ýŽŽöÎÎžŽŽ3ûõc¥¦F#È[Çt11gçÌ™N¡”º»Ïމá€;99R(dyUNN†999Ê×a³µOŠ ÙJ§ÓË+^J¥•–¼”®n:ÒÖáK?ñ ˜IDATíëd77稨 |uíZ.øñã&&£ÆŒùlÚ4'&“Ѳ‰räU®ÿIL:˜•À­®IÏúû/ßÕóÎ%ÉÎÄz§g”„m³12áô)7W÷k~þÞé²3±ç“sV¯¹ø{^íÿž©Îhh(½w/ñÑ£ß䥦æ÷²¾¾ÔÒrŽ‹MLž?ÿ[&“ahh-4ܾ÷ða†¢ÍçAÆÆöúúÏžýýàAÚóçy (JU®ª­‰ ]“;êì–­ž¬7ï‰ óñY²ÙÜüã9s¼Ÿ>-Õ×g«>Ý!!«ÒÒ~³´tˆŠúõìÙ(+«¡ÝÐÈ.ƒ€7ñ½eÉÀöáëøüÊ÷¯´7‰xººÃùü Å÷y+ŽE‹_¶l‡ÃñòòJLLôôôäp8 ,ˆ‹‹óòòJHHðöö>{öì’%K’’’¼½½SRRfÍškccíì<¾¥2„JÕ&‘h(Jà¸L&ãËO£‘É *µ?Ç1 P©ý¡F”Éüˆ  J¹©J? …… $‚À1L,‘4)ëöêDQ2•ªƒ¢ùÉq©”§ø¥”•Ý4èãV1¡RëÈä‘QÝUAÖÇÍÌÆíÞ½iÑ¢yß AXA:ŸµZ®VLbã3œ>™ª­­¸.[/÷FnQÑ}û16¦¦Æ˜ «©m¸úß<cóY³æ¼(+%àqyyy×¾ýÆSîõ öb¢š;­•f,_5ýXT‚ë\»Ý{n/ÉÌLts›—ÄIt÷øîÊ•hW×[·ÞY÷Ãìèè{›7O:lg7¬U%tº‰DW^"•6c˜ˆN× kZ¦Ðét]ù]¥Ðhl¥.T1I:Ê;„JíG&3„„ã2‰„‹a"EUª}üàrgÜ8çeËúûÕ}ÿ¢½ýäX,£Ðâ½€˜è¸gá÷ûàÄù)…7‡6+¿ûîêÕ«ëÖ­KMM]½zuZZZ@@@zzz``à… BBBRRR‚ƒƒ“/\ðõõõôô<}ú´‡‡Çñ'¾˜;7$$dæLNKe„XÜÔæ•JRé›ß€’Hš· knn#±%žDÂë 'mÖ‰aR¡°¶Ýη}à"_ÚõW{L]]C\\²@ twŸÝEQ#&Ÿ:ÍÊÎò\à%«ª+Ç;L°nSTRt&.SGGÇhà@¯_jkkWT•‹D" …šš–²ÈÛå xëÜi%ceÀøc\\¶—ä³X ‚ ŠÃÂÆìßgjÀüøàÁüÑ;¶»Lwpw¿µÅÂ~~RRê²oGÞþ«U%Ba]›•+çˆL&TÜÅ0‰@ðRñòmÐQÞb1W,æ*¯ÜªªVz,wPÔ¨ƒGq\­÷ À>ÖGOÇ)Ïs?yò„··÷”©SH$’ËææîF£Ñ溺Òh´ùl6ûëo¾12äëo¿ÕÓÓ›îìl``0ûsWS“%ËWwzB½Æ x×L°µ˜™9„‡GDFîe0hjnÛ1<ØÐÜü#Î9ŽãOKK0\f?zL€oÀ¢…‹'Mœ,“Iï?¸+ðétFròù)Ÿ~l1ÔDãAëò˜X­]û(4tâሺ¢¢êêÚ‚MÍ6n|¼wŽñÀç?6ݸ±`Ë–:ž ±´ÔñÇC…¡¡#BC5ÝÓÝO:Yp¼¢ƒ¢Nƒ5“Îêƒï„oÍùøø…ïß°nÃÅ‹÷íÝwêÔ©u?¬;ulÍ÷ß9z4$88:&fu`à™¸¸  }lߺõPDÄ®ía‡"ï Ûéìì Á¾¨£§§™ö˜W¯JZnªÝ A:øá‚NV2mª#“yÿÌ™h—9Ÿëéê¿âqkjª%R ‚ (Š’Id]¶Þ‹/þ¼òÇèQ–“Æöòhw“Þ ‘Þ1ݰáqXØÀ€Âe.1gr‚V»Åü"æFý”±Üg打Ѯ^Ö›7×F¶Þ±£áRñÅ”nêBWûÀrçæÍL@w7¬ÃÜé¬>8µ~ûœŸŸ3ÂÖ~ÿþ}þþþÁÁA~~~¡¡[üüüvíÚéãã³sçŽÀÀÀmÛÂ|||¶oß¶råÊü1(0àÈ‘ŸƒWDFݳg[/ÜÛ×Á Ÿ¨=@½˜ˆDâáÃ#KM=ßO›mia1x [GW,ñüººúë7R%"þ„ væfƒËË+™L“É ÓiÝ×nðŽ˜Œûzéþ±S]bbJÃÃgDE] 2Y»FúªNô‘ž–Åún­žyìÉÎv{öd|¹ô«¬ä††]]vuàýÀÜé}pbB³®®%÷\±D*•55qét:—Ëíß¿¿ZÙl6Š‚–¯:îí¨Tfyyž‘‘½Êò2Ù– Zr¢/@¡0“ &·Z®VL0 ãó…|¾@ òù‚²²êçeÕ••µÍ|! E©2“I<ÈÐÔÔˆÁ Ë‡&“Áb1Y,†â£Ä½G{1QÍV„BQeemüâo,ƒ‚ï…†~zø.ht˜ü‰¶¶•Jiª©+(~qÙ'Àfó–‚Ýán'Ž„dÔ¨4µ›;Ô`î¨jo?y'81äÍ‘ …‚êëëà8¡¥õŽãjý%EQåÚz½÷úv€©÷ ‰„jk³ šHÄ Yl¶¶••™T*Ã0 ÇqŠ¢$‰B!S©Æ`Ðét…Bîü¿èqíÆ¤ƒ½É¤™›­ÿoz]]½KþÍîO"‘€`ê}¢¯ãxûÏššÚ9×2 ëׯ_Ë÷ì}`ׄÔ'ŸâB¡°Þµâ¿U»§D·‡›Ò»©*P©@[»ÛZ¤iÌ °X:m>D¡€–Ö‡rþ­˜;Ý¢Ï B OŸfiº ÓÞgé…Âs=Ü’ÞÆDUÛ/¸0wTÁýä=õ¹AˆFc 8JÓ­è]$6“4ÝŠÞÆDÌUp?y}ösBAæÁA‚ Ò8AA!‚ Hcà Ai „ ‚ ƒA¤1p‚ ‚4BAÆÀA‚ Ò8AA!‚ Hcà Ai „ ‚ ƒA¤1p‚ ‚4æ­µ3 Ébiª)AпžYàHå»o BKý–¿žmAÔ‡ÁÓqAƹ›.çjºAAA=çÿ>NÌ¢´çmIEND®B`‚snd-16.1/pix/orig-oboe.png0000644000076400007640000000741111147553270013533 0ustar bilbil‰PNG  IHDRÈ¢7‚¢bKGDÿÿÿ ½§“ pHYs  šœtIME×4P…O–IDATxÚíÝ{LSgð§\+ ‚b’Åâ¦N(¦^ŠnsÊâ2ulñ²át͌Π¸K6g&a¢þ!*J  t#FC'8çˆl"CAn®ÎKÓ5:. E(àùþðó|bK>‹ž_ÒÄ÷ðž‹ï{z^úžS‰ ˆ¨Kvl"„ˆ!b@ˆžg@AÀåË—ŸºbGG.^¼ˆ[·n±ið$;;K—.}êŠGŽA||<öìÙ­VË–¤ÉáÉz½Þ¢7oÞŒÊÊJ$%%!??/¾ø¢YЊ‹‹{ÜÆ«¯¾Šùóç?óÿÔÎ;ñÙgŸ±wéÙ$22û÷ïÿ¿7,—Ë!‘HºüÙíÛ·‰ŽŽ«$99™!ë¤+­­­H$prr²xÃèòg:Ž-O¶9©ªªBss3®_¿..›8q"^yå•Nõ^zé%œ?ÍÍÍÉdlIÑh4˜1còóóÅe¡¡¡xë­·:ÕKKKCBB<<<°dɶ$ ŽK¬­[·šUÚ¾}»Ù2™j":::Äòãÿ¶ZòíìðàÁØÙõß5jÏ8Ä\QQV¯^-–M&“U÷çææ†­[·bõêÕHJJb/SÿˆJ¥BYY™Xæ×@Ç D 2०¦"++‹ AÏg Òßݽ{<`CßAˆ"„ˆ!b@ ­VkõYĀج¨¨( 6B40ôÉç .\À×_-–ïß¿?¨ùäÉ“pwwÇ´iÓ,^§®®Û¶mC\\ÏÒI“&!%%E,×ÔÔ@¥Rõ«†øüóψ©S§>ómëõz8;;ÃÓÓÓâuL&JJJx††€H¥Rxyy‰åþôUj hmm…““S¯Ð¥¥¥ äÄ1ÈÀöçŸÂ`0`áÂ…½Z/""‚gBÄ€b{ÚÚÚ`4Ù ˆíinnFuuµÕ¶_^^Žúúz|óÍ7llĶüøã˜9s&¾ýö[«í#::;vì`c3 ¶'66–¿Ù²5[¶lÁÕ«WÙ ˆmòðð°ê˜^ºt 7nÜèÕîÞ½Û«}ÔÕÕ ªÛ“Í"N:…ªªªWlooÇ©S§ð×_ ˆ†˜8q"þþûo‹Ÿúèââ™L†ëׯ[¼ŒŒ ,_¾Ü*ǯÓéàé鉋ÿåååïU¨BCCñóÏ?[µ/ÿFäçÍlªIzz:Ο?WWW¼óÎ;P*•]®xàÀTTTÀÍÍ aaaèõÎKJJÐíÏŸœžžž™LÖã6ïìÊÊÊ·<¼GÃÉÉ 111P©T0 pvvîqÚÚZŒ7¯½öÖ¬Yƒ7ß|³ÇúÅÅÅP(αzÚ1@KK ^xḹ¹YTÿäÉ“X¶l °k×.‹¹ÚÚÚ A°nÝ:Ì›7Ï¢>›9s&>üðC«ŽÁjjjú,$J¥AAAÝWž0yòdA!==]ˆ‹‹ºó¨Þ¾}û„„„³Ÿ:tHP«Õ]¾–-[&°èåãã#¨ÕjÁÛÛÛâuÞ{ï=!$$ÄâúS¦LÔjµ “É,^'22R¶¸þŒ3µZ- 6Ì¢ú...‚Z­‚‚‚,ÞÇܹs…‘#GZ\ßÓÓS˜3gŽÅõ‹-¤Ri¯ÖéíkñâÅVÝþã/…B!u{žKAÌË/¿ŒÊÊJ:t·nÝÂW_}Õe°ÕKJJ‚Éd§Ÿ~ÚéçW¯^íöæ ƒÁ€°°0J¨_HOOÇûï¿oÙ%Vw'´ÝS/oçëë __ßn¯—çÏŸ~øÁ&ðúõëØ¸q#222l¦ÓsrrP]]Ýí/¸þ(66 … ,èÓýº¸¸X> B^^þý÷_øøøˆËFÕéºpÆŒÈËËCcc#üüüz?øqp€»»»Mtœ««+mæxuºT*µ©c–J¥:th¿:f³‘ÜÞ½{‘ŸŸ™L†ððpÀG}dö×—Ý»w#??r¹!!!|Ÿ¦Él Òt:Ö®]‹ÜÜ\›h¤{÷¸ÁÁÁ6Ó±:õõõ6uS×… 0räHŒ7®ßŸÍk777› ÈårÈår›:fkÜîüÌ/±ˆè9ÄÅÅ¥WOø Tc"¾ƒ1 O7wî\¬]»ö©õT*6lØÀä6lØ¥R)¾<àáÕJ%¾ûî;±î½{÷ T*;=\¯®®J¥Û¶mëq?z½J¥»wï~~™7o233±`Á|ùå—=†#//*• ›7oT'„^¯ïÕŒà...………8uêV®\‰ÖÖVÀìÙ³QXXˆ1cƈ“7çÌ™ƒÂÂB¸»»cïÞ½€àà`ÂÙÙ¹Óà Ÿ´páB¢©© ¦ÛzVý3¯Éd‚³³3ìíí{|XœÉd‚T*…½½=ÚÛÛÍÉPYY‰ÄÄDÔÖÖbݺu˜5kÖ ˆ££#Q]]ââb¤¥¥x8óX*•ÂÎÎNœÎÿ輑H$âyÓÕ²žÎ9=ÞÀÏAž£ýû÷#44AAAÈÈÈÀ!CÕÕÕ¨««ÃºuëÇGYY†Ž5kÖrssQ^^˜0aÆŽ‹áÇcòäɨ­­EAABCCqôèQ\ºt 2™ ü1 0fÌüúë¯pvvƪU«YYY¸rå ¼¼¼ðÁà—_~¯¯/¼½½QSSƒªªª§NëV:::püøq,Z´hð Ò7mÚ„õë×úpœ>}'Nœ@\\L&"##QTT„O>ù puuE\\Nœ8òòrÈårH¥RÄÇÇãØ±c¨®®†\.Ç!CžžŽß~û /^ܹsGŽÁµk× —ËÑÞÞŽ={öàäÉ“ˆŒŒ„½½=ZZZ°oß>h4èõzÈår455!99ÇŽÕ+W<üT>''§ÏÚ¦££GÅâÅ‹ŸÉö"##±uëÖþÔÔT,\¸iiiâ***°k×.1T¯úî»ïbÅŠ˜>}:Ξ=‹ÒÒRL˜0Ë—/ǪU«úì¢7ÒÓÓ¡P(PVV&NMOMM…B¡€V«ÅÒ¥KÉÉÉP(¸yó¦xKÅáÇqúôéNÛKHH€B¡@ccc³‡­z‰5~üx@"‘ÀÞÞðûï¿›Õ›0aŠŠŠ:ÕèFŽ OOOøøøÀÁáÝàåå%Æ×׈‰‰App0áããƒ#F ¹¹Z­7oÞ·g4¡ÕjxzzbãÆP©TJ¥â'ooïNwMÊd2Ô××C«ÕâòåË())ÁŽ; V«Å“óÀ}Ö6NNN(..î´,00%%%°³³ï–œ6mšÙ2•Je¶ìÎ;H$¶÷ú믛ÕëŠý·Ö|¸`vÝÐÓt úçŸàçç‡Ñ£Gxx+¯‡‡Æ/Ö @ii)RRRpñâE,Z´8wîRRRPPPlß¾gΜAjj*233ÑÐЀõë×ãôéÓHKKÃåË—1þ| Œ7^^^hiiÑhDTTrssqèÐ!477cË–-H$1b²²²’’bv‚YýÚ¿›säÉã°dYWç–D"érÝ'ñ“twõêUDGG›]¶þ¿òóóñÇ &&®®®ƒ¶}×ÔÔ„²²2Ìž=û™n·¬¬ cÆŒßÝ"2ó-Lw&áNYIEND®B`‚snd-16.1/pix/fmeq44.png0000644000076400007640000000253711147553267012763 0ustar bilbil‰PNG  IHDR+.GÀÏ3PLTEÿÿÿ   PPP000€€€pppÐÐÐððð```ààà°°°ÀÀÀ@@@ ã¡{E pHYs  šœtIME×  th¿IDAThÞíZk—£ ÂC)ÿÿ×nx ZP;³ý²KΙcEo/!ÉM%$e '„ .IÏ´êŸÿ (!J Mˆé_°LŽŠÙÈ/ÿ½s¹MŽö=†I±¢wÑîç†kË&M9^a¨"rS¼¿…7£Ý9í®¼Ÿ$Ü2+S¸RvfÂk㔘E+÷vÒqeÓ¬“‡bι­ÚË+aüeB•:9*æ;ÄmI7—«)íð fT¯Æœ;…m»ê4†jý%õäh¯ÉW·Àñ”ɯп¤# >N”ßάðoeSç ž%¥Ùô³üþyLŸò]² ú Íe¬¼Fó³öÇ«¯àþÁ?ž#¹7”‡14Ê-mpÕon·w[ÜúÛ dùX”×òßž‰¸õ%õ8¬"`‚S–ÙèöT/¡îû¹Ú&Æ\,Zv Y¿Í}²xÁ½i§»¥§"õ8x¸ÑfÃ?š½"E˜ ¹ùùéÎ,Xso¡Ñiq°!QÂ’û–X3J[k=$Î >o®zx)G'Â?BUh8¿¢˜jXðU’ ÆFˆŽl‘nq’F‚þHÁÒLt…Z±*çj\iôÿ#ˆ mœ™:6Qyh+2~ W„Ç-´_ÅÝx…ÞÕí4Æ+¤NXà 3V@ô+º\@!:@ÊŽ”Ia5µØhaºZ±†¬G¡ÂeŒÇƒGXbó Í/!W‹¥€ŸR¯¬l©zùn¹æñ‹ÃU8‚àqFˆZHUÃåI]ó~Çéꎉ]zäV[LôŸ ¬S^—x|µ†ïøÍ·æëƒK˜!j¸Öv˜wVʏZ=IÁ¤¢7HUÃåI‰«mçªÚbõ«ìHŃÅÇ¥iÀ#zl˜Èy?|·~eÃîu_òŠ+{¯Øeá i„¨Ôj¸4éÌUµÁ ˳x•bÐDœŠ®ËêfŽá{À†+|žü:Å€Ò˜–u¦³4øûFˆH†Ë“Þ¸ªPIm¢oôiê”ñÖ¯p¯E‡EX¾¿d±Ú¤®p5°LâébÏ©îø¶m~ i„¨õ«ªáÚI-WjŪÄã’AXm èÜKðj†I«4Ò˜QP5 Z¾|QCgñj†_@ j!U —&Y¶¢ïãAó•%‚w¨;V¯n$œiºXZ׊@Bä]µ\ÄæJHBaùK·i€èiÿ†Ï+P V:®Ÿ³„ãîvmû§{çðá>^N)ùž ‘OÔ\…Z°ÊíL•?K¸”/{†ý@ûÜôE¾iþ÷mŒjÁª_²S›3ÄËz¾ÊÕˆn¡f¬°ÈsßÇ鳄{’Ã?nU|™ª ºÃº)Ûå¬m: 'ç/I5¿=K¸Ÿw2þ)³ƒ®JL™\Ýv™w 7ùzÐ OnÚ½Ò*NÎ7Šîl—p~¾‹“€c #á¦u,2‹©ËVQM}"ws¦uê‚ã{³¡¥Åg55¨ â{³ËP=¹º WÇ÷f'W—á*¼7»û•TW­Ýÿ\žß›R‹IËC“Ó«úö¯Í,HO¼­âIEND®B`‚snd-16.1/pix/sceq37.png0000644000076400007640000000430111147553270012751 0ustar bilbil‰PNG  IHDR³KÍ…™u9PLTEÿÿÿÀÀÀ€€€   ððð ÐÐÐ000°°°@@@àààPPPppp```©©©qqqP¼ pHYs  šœtIME×  (®ÛIDATxÚí\‹š£* æ"‚H•=ïÿ°'á" xéÌNÇnÉ·ÓNÔ„„\@ý ù!Ò³„1E½ Jä  ºÙâ]H BÔ´ÙâmH1+åÄ”h¦hôwªí«§’ls÷›ÄùËEÎ÷všì:æiǾܮA²ÅWÚ½€Ätïi èCÃ}vDÏ=Ù*\¢^½³&sàœò9((‘·-qTÌ/“…;÷?›§ÝRÁ¤ÕUŸ•êæ³Wayt a0×Aº„`[ªáJŒ,ðÓå[é¹+Ÿ¹‰–R£­¬Ú\0þQ²#,ão¢ºBR˜Ìr„¯Â9ÚR?1%‡YÂ|˜ B$ÁqË:Iqm”¨ù,Н.pÀîÜxTMÁ¤ÕŸe6 ›i© ‚O8ˆ08ÌDqC€uÑGëbÞ‚I·ytÙÖb¥ð‚(äd+IÍVXÆß T“‚CÔÌ­µñE ü…Fê5–V3c1¬éi(õA‰šÏ¢øêÆØ»UQ0i5Êk­oR<–âmmyly5S×§ì–¨I¼œé¸µ®8 ÅÞ>h1Š÷ÕªÂ2~M ‰Ÿ"üêÒqþ³k0Š”¸M˘õ’.êtaŠ£¶ .ZuW–Ôc~µÙl‘̲ŒºD¢¢²4[^bf\!ª’Íî~£Åe¡ÒfOXƯ ü2ÅQ,+VñØÝM?pçDŽWŽR' ´f¢²:·ÿøõ=Á»8öŒÀç6k£>¯}VE]›vüx¿ñ§öÛí×GvºÎ’{‘ú‡ÁCîKËŠ6¼™~bø ©Ô’F_'þ6™føïÐüúÐW¼™ý›|õ5º¹¬Ñ×f‚w#:6Ü›–M^A‰ú½ãFwŠªl“7PóÙíé¸ÉÛâìm(ßäõ‘7Ðö†A£F5jÔ¨Q£F]¥†ÁòvÔ0XÞö0XÜŽo3Ï=iƒw|Ûvá›ÑlÒó€Þƒ,‘¬aV½ ñø¢b£öUÜMR±f»Ö¬nŽ4ã¼j°¿Bä­n>AUÜœ3´Eõ3+ênŽ=k=Ä—X°äó)ߨÃ_Ö_¯ùì4ô>76+¸9|&éJÞâH±væ7‡jŽoÁ'Å÷™›¸4„Îá]ïŒg#£\>žIúçKš=Áé#&–nur°3G¸9szÑm&Mg†oVFøŠ„^°‘Q¾¨p*éŸ/i§OûZt×vEÌa€9x ÄÏ1S\N\+ˆ™å©Ÿ½ÀcžKú¬’V£ž"îEèV\‡r;S¿C ¯l^.`;’ô!©ñÔž=õº¿9cõ1ìL¸^ˆsjóbŽüãšÿ°Lô×Ï}¶’ôyt^á#èܱˆ¹‚7g\XÀΰJ*¦]P›ÔSb ø+NF¨²îútš í­aØäIú:ÀÍYã4…›30fvf¬úæ´-`<ÅÉX‰ÍÎÈ(>Ôeû¸9{pþÇ€1ô¯4àêÂ;ú¡­~7Hqºï4'GÛð .æ|«_|hf¬ãæxRµë³F¿¹RÇÍq¤ˆ¬Ú-x ¤¤=`ðF)VIVPÒ@Þ‡„¥„ÜØ7SܜҦâòh£»4$|ÿnf£Û,¨Ý®oD`Y –Ý9ä7Ÿ½ù]ßg Êaë¾Nü;Xå¯þ¿ž„Æ!¶Œmá?a¼T.ƒî¾Ø]…†ë"ÐØñ¿1âÅâ¶ÑxŸÑ"ÇgNü‹XÅò Ù’â£ø¼ÆXèE”oB.“+›±¿<¥'³›dç¼¹ãc„9¹¸­a•m^ƒÜ¸¤„ÿ"V‘|ê_I±7>_œ×z7£¼K6†tç{.¨XVÞ/Õ$þ¥¿vÄmØ”|è;r«J §þ¬"ùÔ¿’bo|_­cE-[æªÞS e n§×”[†:¡ Óa¡úެR|±lîø”¾?52º?Æmµ˜‘R|ENG÷Ñ;áÔ¿U$ïÅ1GÁß’âƒøD¼O6M15=™×3C*˜=|D'î)R7µB±«ä–»UÝ$<Œ:Ú&kíø<@þÒˆrýÇm½˜‘’~CÎ_CÃʼÜùw°Šä¸&B(¤?eÅ'ñјÛm¢™M–) •UYÏp ©°ÓÄ\Ñéä¶µL3™à ß5W±]™)¥<^Oz:¾+ mÄéÚp7î9sk˜)ùZ®Ý5¹¸,âοU,ïÄ9öO²¬ø$>GÌåhf’µR3þ”.ë9Z.T ‡\³ó´Ã˜‘¨÷½bs)šNyÚ £¬iØ®hîØ§vÁÄO²N#»ÚŠnGaµ¦ž“m˜'rqY¸Â4ˆ++¶‹k4ïèç&0›S}ñ¹Äü°QLY&Yæ>I£Z£ ³RÏ,ËÓ*·õ/1Þ±!¨¦¢CøK{ÇŽQPk2¢9Âk¿‘]m3òd"5³÷rqY¸ÂL7V^~ÅíR+†»Àž$$1ßlS–Q$+Yh- Ž‘O÷…™§+*ì—uRm31ØÍ A%ö[Øèè8Þ>h2b+›‰vÙÕ6#¾BŠ[»°ƒå/µm[÷rd9—…[ñ— ¢cµËë)w‹ÈJ5Îf+þ:“p‰ùn£˜²Œ¢) 9¦‹Yð?¹Tûû•§ûa1EãG;Îx¤Ê]ÁùÍ ûUþß}¢ÖÐ1æB‘‘[VÓ}÷¨Áˆ ý÷ÙÔ6#~U‰Û:&þVÎ>VF{*8QǺ• ¢cµÉ#"°MœWæöqe2ÙœjÏn.æ»bÊ2ŠfÒÁ¼PÌ‚ãèS!ÓÊٌ̡^Ó`1/æÕóíÃÅüí4Xüì,¾¡ëÇ,ã@¢ÒÒ1±1ŒFz¬…mF‚Ðk$¨mF|·õ{ß½•£Ø¥×s#êsDÇj“G£"nÔ¹bp!61¦èÊ&¸Ó‘Ý\ÌwÅ”egWIJrGŸ }²=Ú×°ö_ˆ«Ì³µÛ¥#pké)ŽØâëÍ¥6#œ?2Ô6#kÒV‹½½—ÃÔoÁbtÜ go¬±üªÔáŸsMã›Àwz²›‰ùa£˜²¼â½Þ‰céíùB'‘Ê(léØîâ›ÈÒÌÄ*Á 1Öo䢿£·5ðµí l›œ!6š>‚xbeʲ¬x˜¢;åìâ*é›”áF½&Ž~šÆ9Ö‚Òæ«eb¡­ÛÙ°˜uÛ\i*jÉ2)û\Ôôpm«¾M×Á¥ÞÈYbþd‰bÙ žY™uS(šOSqçyv§,ÍBKÈůŽ]ˆßŸçh4âoÜâ¶6ø?×ìóñ\•ð-«š5wþ$ èÇ–…ù9þäØq‹´µ½—ËàÒBâruÂú©ú?‘„—Ù½—Fàb¹98Ó*tc)ø 9 4ýB~<À;©þ9`Wð»5n;˜àüqÞ ð3„s€:ìýEïëqþ8‰pµ6X€'ØÏ„À—“ð‡P«ƒx0^—“Ø¡V+ðð®cɾ Öéã$Â!Ôê`~‡ãjq°Rüä­QnG'‚0IEND®B`‚snd-16.1/pix/xex.png0000644000076400007640000003064711147553271012465 0ustar bilbil‰PNG  IHDR,²we¥sRGB®Îé pHYs  šœtIMEÙ "/|= IDATxÚí]yXTW–KíUP R ‹ ˆ (FQ° Æ]Û´±3‰3'“/™LzÌžé5æË;éNº§cÛ¦íŒÝcÐ,îqÁ]QöE–Bö¡( öWoþ¸ÓõUõêÕ«w¡ ßïó„W·î;÷œsÏ9÷ÜsP›Í†¢(‚ ‚$iÿyÔGý‰l%IR«Õ–––&$$(•ÊQxêÔ)’$,XÉ‹Àz{{«ªªîÝ»§ÑhþN:QôÌ™3¡¡¡J¥òܹs@,ÇÂÙï]ÂñƒŒ¡38¼‘¡NÞà6›u²ØÇœÊûÁícRŒ‰Åb•J6öoééééééÝÝÝ@,¿üòË?ýéOGýì³Ï>üðêª*ff*Øisss÷îÝ«×ëY·uQýè£rssY§,Š¢===ùË_JKKaLûúõë›7oîëëcwp@ðÎÎΗ^z Ã0öÕ9†½ÿþû………0Ü‚ Nœ8¢(ŒÕ¬ªªúꫯ`ÌEÑãÇSŒÉd²€€‘H4Jd­Vë(%'‹³³³—.]º|ùòØØØÆÆÆ®®.Æ“kll,**êíímnn†¡~>ú裯¿þ†JÖh48zô(ŒÁ{zz~øá‚ ØÕÍ(ŠqçÎj»Æ\¼xèk{xIIÉÉ“'aȉF£)))€´ VUU¹Ð_]]]'Ož<~üøçŸÞÞÞŽ¢è±cÇ>þøcƒÁðúë¯ñÅ¿ùÍo-ZF³gÏŽ‹‹›9sfLLŒ\.÷„(Z­V$•––^¿~uõó׿þuûöíyyy0ääÑ£GÕÕÕ}}}0îøÃ–-[þ÷ÿ×d2±Ësƒ¡°°0!!áòåË0¸9%%¥§§Çl6Ã\ 466BqÉ0ŒÏçðPýꫯp§~Œü“Ÿü$##ðàà`AÖ¬Yc±X„B¡X,Þ¶m‚ ~~~`ÄQ>€‡ü×ÕÕe±X …V«eýý;::ÂÃÃF#°aØb 0”Õj …³fͺsçÎ’%KØygggBBBOOëžI’ýýý•••@}°Ž+VTTTôõõëÝx8óÂÂÂ'Ÿ|Òç‚..Ÿáñù|…B¡P(ìohÿyÚ´iŽÌÇîüL&Óœ9s€ÝËîW`f2™vîÜyÿþýôôtu[ww÷Í›7_{í5‚ t: õi³Ù`(f0¸V«u©›™áĉAÀØm6Û¥K—V¯^ísBˆað,¨ž»H.fÑÛ6›6mš>}z?»_Áçó-‹\.¿|ù2»Ó¶Z­&“I*•:±²èB)Àh4ß|óMƒÁÃù²X,Γ]²²ï›Ü¯'IR,«ÕêÖÖVvGÞµk×Ûo¿ã¸=¼äý@Q´¦¦fÇŽÁÁÁ0XÙh4Þ¼yS"‘Àˆ1ž9sfÑ¢E*•ʇ>a›¡W !`5ŠŸ HFר€EÜ¿¿··÷¿þ뿾øâ ½^Cå-^¼†œ`VVVÖßßÉöQà8¾{÷n/´´´üüç?gÝ4Å\”ÈÈÈÀÀÀòòrb’$e2Ùœ9snݺÅúà|>¿´´´¯¯BŸ1GQ'W„"`ˆÊÊ•+Yò¾¾¾¾¾¾^xA$=xðÀ·Öd\Áp°¦œPù˜Oh2™RSS E}}=»&"I’A¤¥¥}üñÇìÎY§Ó•””€¯ðE­¢( CF:˸ÎËÔÏ|ÂÚÚZ¹\Îî˜ÁÁÁð¢üðd¾•~iY$ñx9 ªçòøš£À Åqœ]%wùòå—^zI(úÜz …„„ðx<û©)+bÁq\&“A’C‹Å’‘‘!•J- $â\ºt +ú’Ú—ÐCÉÑjµƒÁñò‹¨¬¬„qŒ>¸råÊÆ‘Ë僃ƒl%0[Ñd2­\¹’X­V•JUYYùèÑ#HÄ)++ƒ1¬^¯7›Í“èY` –sxx¸¼¼¼ªªjhhˆ1‹TUUuuu%%%A1²yGyØÞ¬— ¡Ùl¶X,R©”[$G¡££cþüù ²T· FúhqqñÔöܘappÐK…$ ÙU¦ÙlFhÜ}dl&Á‹p°ëÝ»woddx°¿øÅ/|ˆF£ÑjµrB8–Õ½TGaÆ R©”NIX¼x1»âM’$8° MHH`×@°KµT*ýøãÙ•‰D²hÑ"HrȉcL¾‚ýðÁƒŒK˜R#''çÆ,î~111;vì@$,,¬¿¿ÿÌ™3(3<<Ì¢e±XJJJ/^ /Ášƒ¯î„`–î§+W®°5`ww÷矎8ÜZô•’*‹åÚµkœTL0l6ÛÒ¥KYBŸˆ}ÙÕŒ6 ï‹Ö·œ!IŽl !¸h³Ù,‹‡­` ¡½öÚkþþþpðPW‚g"mmmGŽéëëëêêb&HA¬Y³FMá‚‚‚¡¡!ná9x]vëÖ­Ÿüä'¬ !I’QQQ{÷î­­­=|ø03èÑ£GŒ:HÖ8p` êSYæ·(Ìf3㥱eZH’ä<Nç@^o¹ ‘HÆöf{ í–ððp@à»ó‡Wà +>o´´4‚ uÕ‚ZbŒÅ%T«Õëׯ†wø‰ ADGG‹ÅbßBP{auŸ·áìÙ³ïܹÓÒÒcðÄÄD„½ Ž©j‰$—±2ø™3g@ýU ‰æÏŸ£`ÇS(0äÐh4nÞ¼9""ÂW,0ÉôôôçŸ~ÆŒ»Z­V>ŸéÚØsÏ=WQQáák/0bÿeBB‚T*`e …Žؾ}{QQëܬP(–/_CH€9Z\\ ÚBú„ý Ì„††‚rA“¢;°ÉÒ@ð qp»Ô‘šÃÃÃß}÷çÃšÍæÊÊJÇV•Ó§Oïêꪬ¬„ñ"‹åäÉ“¬Ëçóýüü aÌY üøãt®0ÓÔ¬Y]]]VV&***ØR¦Þ.„@6 Ehh(¬W°œœæ±ËãcddäæÍ› ÀŒÝ ÂqRÖ¨iÍâhöëQ]]]wîÜD¡PãB †aÑÑÑ0ŒsÇçó‹ŠŠÚÚÚ stŠ­®®ÎÌÌ„ô§NJII0ºð ŸëV è —ËAYaÀÐ>ƒåóù S/$‹ž7äæèàà`]]¼°¸¸˜CÜ‘½£«vâÄ —™ÄÞ Ã@ßå©·¬Ø¤P“ÇãÁÛOè”ÖyÜ`³ÙÊÊÊ|=Àh4Br¿;!ä0)ðź;ã¾'„°*\p$‡ÇÌï ƒ`[·nEQ´¯¯[섵)\ÀÆíÍEÑ––¯2lEËÊÊ\^d̾â¹ù®Å8wîÜiÓ¦uwwÃEÑŒŒŒüü|n'üDDDìÙ³gÇŽ‘‘‘¬œŸ gµZ!Eà‡° {))) …ÂçxL~Á‚l5×\¹r¥¯T™s4`àóù¾Ò†aÅŠW¯^…Ç‚ž›I(Š~ÿý÷"‘$OùP½xñbaa!¼³ÇëׯOá 7óû„*N FÛýØf³±UãÈQäH’ÌÈȈ¯©©aqòöß,_¾Ü‡6C¨†ôÕ«W¹†0l¢··W§ÓmÙ²FF ‚ K—.[Iž•%Ôëõ>ܱc‡£À<|ø°©© [gddìß¿Ÿ»ëŒLõ°ùädÌ”””@¢lQQ¸ÙcæƒÄg>vãe‘í|®ïßB¨¼UZZ )…Ó‡©¦hqçNü9pBȾXžÄ—VÚ¡+ë¨ú8!üDEE±X*‚ƒ#H’´·¯‘J¥ C+GjNÿ7nÔëõ¾RÁ·@ĵk×Ö¯_¤.""âÉ'Ÿ„TV‹ƒoû„gÏžÕh40FžªÉôwBp˜i—º¦¦&H.8ø€:sHH’„TEÑÈÈÈÇÜúrÌòEQtxx¸³³“ŸB;3ðÙ€€€ððð ŽIäääܽ{×›­/PHjÂâ%ÜqËÄ€Ž Æä…F£ÉËËkmmíîîvk!Q***‚t[|…Õjµã¡(zýúõ'žxÂÃ=|,M- È;÷<‰tåÊ•ðª~p˜ÄÇÇC1G%Éœ9s¢££%‰»÷FFFjjj౟ϟ={öØLb‚ <)¤ ¤Z"‘Œ¥izzzHHˆÁ`ðP/^¼(•J¥R©£áZSø:Ö¬YÅ•ÉdÉÉɉ‰‰~~~îzY(ŠB-0ó—¿üLŒõ – ˆ¦¦¦œœœQŠŠŠÒh4 ~ESS¸Óì(ÌÛ·oÇ0Œ;HðE€U›6mšKíÌü…wž­766Bj,c2™òòò‚ƒƒGýÞf³ ›L&Ç7×'!!áðáÃÜA‚/EQµZ=Ö9bÇõfà8>öN[Šmxxع!ɉÍfkmmõ!¶ãÒžF¹t .mÍ=&›øúP Ób±Ì›7Ïßߟ“CƒÁ@'\çEB8oÞ<Ç^+|‹%999((ˆB·à]Bøí·ß677s«âÓ(,,tf·sðj!´·Å䔨¯ãîÝ»œzµÚl6¹\žšš:ÖÝâƒ'„ÁÁÁššš„„„ Þñ„Bác›Ã ’ua4ýåà“B8<<\TT„À9B@œòx¼wÞyçÂ… ^.*ð¿víÚîÝ»9v÷Ε„þ„ Ì©ö÷÷·(¸^¯¿wïžçÔKPÏ«ýê•Í.òóóóË\“±X̲ÚÃ0osäîß¿¿iÓ¦°°°qÿêyÅ~¡P86ëU.— ÐÐÆõ‘””¤T*!Qfšùt ¨dYµj5e˜¤­ †ÆÆÆææf½^ïUr¨V«{{{!±AýýýO?ý´ãø$I¦¤¤Èd2µZíÉàåååB¡pÚ´i£~iûb½V/A¡¡¡2™Œ“º±¤NNN¦&–¡V«½råJQQ‘V«e×¶ôP›â8¯˜¢Á`øãÿˆŒ):Š HCCƒ‡ý¤ZZZÆ-) R©`”çóùr¹œEjµZ×®] nNÃÅbáÅØl6‚  n'=bÙU*•ÿú¯ÿúì³Ï†‡‡³{"((ÔíõBÃEQCøÇÍÞ&Iòé§Ÿ...fý]BBBRRRX¬$ÒÜÜÜÞÞ{ RRRX¿CÄŒ3BCC¡úÌçÎcÙ?F·Ý¨‹íegg766rµžIýý÷ß³n @Àb§±üüüºº:ØM,Y ,[¶L(ÂSýõõõ,›£Œ×A???gAbccoݺ¯„6»lkµÚ®®.¶Æh>88xýúuÖÇìèèP©T111“U‹›Èµ7 cïÅ:ºì6æ@±>WcÆh4²ÞâîáÇ•••(ŠOãMè· †âââ3fp2À™â`½¢N§Ójµ‚ܺu Fw-¯BEù|þd Ž}ð¼5Ðñl‰½½½S_aƒÏç›L¦qÃEà_þå_®ð»oB¥RÁþ ¨ç[‘–––nܸqÜRn8އ††æææ>¶qWM[JsõêÕSxi¦”Þ¹s‡Çã9+Of6›=©9íÓŒ$ÉØëc¾âûûûOa!äyÕl<,3c2™€¾w¶Ý1³7@™™L¶hÑ"g›Œý³Çq‚ 9I’ü1?ø".]ºÄµËž8xg…P þàÁƒÎ ¹þô§?•ËåZ­–1¯”••eggÏ;Ò+èt:ßõ‡=/'É áh†¦È³IIIùú믻»»½“œÝEH$UUUžØº ‰ ’œíà£ûÉ”wã'TGFFš››_|ñE VóÑ•ÞK°|,Ãeee!8!Ë1̤E¯×ß½{á*ʸƒììlÖÓD8x˜fZZZŽ9Ò×××ÝÝíîmQNü¨¼›7oÂëcÅÁ÷„$Éèèè}ûöÕÖÖ>|؇NŸ|÷˜žk$È™£ãoef³Ù{w‰DÎ!@†.·s˜">¡EQ“É”œœ<¶Bò·Fܯ¾újcc#·ä8!t«Õ ö+w­Ç“'Oòx¼€€g»w__ßáÇ=™ÛTjÙ /ˆ«øä¥BVÃ0—eBôz=â~·¥X~Šút }t™Çª¹\ÃUV(PÜB&æ"I’:nÁ‚ÔOnÛ¶­¤¤dddÄ«ÈDDee¥³4b¶ÆÌá´Ÿ÷ÀËYÃ0lúôé£~›””ÔÝÝͺŸœ••„pV¼Ð5ùùù[¶l¡~Ìb±Ô××è«å¡‘üÝwßMŸ>}\ÆJHH‹ÅCCCÌÔ“Íf›1cFxx8$õw÷îÝuëÖýSuuµç‘Ç">>¾´´Ôd2qa0¯BÐóN‘\/4fì¦ì¸5Ñbbb´Z-ã¦n%%% …bÖ¬Y&úô鸸¸±¿ÇqF=E Ã.^¼| ^˜™’ç]@,»ºº›Ð}}}΢>žŸÄŠD¢ >Î …Ü6è¥B8•éèAS{……ql]ŽÂœúx<žÙl¦o$é‹·Ë×®]{äÈ/Ÿ¤ÙlæÎ0g݉ü2¨bP]]½bÅŠˆˆgðùüùóç#\½x$P[[ëÍ3DQtÕªU”çÀòNh …Bw/ªÌ›7ú£ÑÈÌ´ËÏÏçñx<ÏYd\,/X°àûï¿÷!wÅû§ ÊO477sâ4ABˆ¢hkkë‡~øßÿýßÍÍÍô#™ÃÃÃGŽqy;îå—_noogPžÐh4‚+ØÎEQ¡PȬ촚²ƒÁÁA®húDû„aaa;wî|æ™gÂÂÂ賦Íf@(ÏpI’ÄqüÖ­[Ìj„ÒÙ7˜•™‘H$»8#; uF:µ9˜\eVŸL&cv™bÁÀŸ,‹W%[Øl¶8+0c'‹7'ˆL¥¬W‚Ùlþàƒ ˜£!5) ̨T*Ðè†(‚œ>¨E¦—-[Æ‰Ä¤ì„ ¥™}s”ÃX¤§§_¼x±¾¾ž’*++KKKKJJ‚$‡»wï^¾|9—É9ñ¸~ý:”à‰8¢Qlx[(r{9yrìQWWGRbK+sR1Á¸qãG`",¿Á` ™ùa×Ù4•7?))iì]Qá8î…AN— dxr[â•yÅž+¾ Ú=ŒFãï~÷»]»vÑyX.—ƒ[ô•÷wß}gµZÇíBa‡H$JKKËËËó9ÎËÉÉ1 ìneÎ*,z3D"(x5ÅôÑÄÝ'F£‘Îï¿þzqq±[u—]î ¨›˜˜xÿþ}O¸v²Î>úˆu†–Éd4WdÒˆ/RRRFFFXÔÞÖöÆÀŒÕj-..f×nËfµZ™Ù3àHf²b±XØÍá%óRSSaÜ'„???ðƒF£ñ°FÉ(…BOê-LY!$IÆ=7OæÓÐÐ@ÝËËÏ ÇUIŒï@N°h'>†alÉ X¯¸¸8x-@¼N1 ƒwd î§C’$;6sæLŠñýüüd2™»fÐf³Á«m ˆ³Ò8†ùÄ ÏòòòÙ³gÃà‚ $ èßN<þõ>&Ym6[oo/uàÄñawŠðàà`xv`V KOOêëëc°#>€ÁgeeeãÖ¶ð!œ8qÒÈ---%%%àp+>>~Üz™¬`íÚµa… B«ÕzíÚ5êÌ/;”J¥T*ukW)--ˆˆ9+Ô;ˆ»²»g’$)•JKKKÛÚÚÜýlee¥T*MLL„DùÜÜ\ÛÈÔ€V«íîîBøÄOÄÇÇ#p"pñññÆiÛLfâæU&›ÍÖÖÖ&—Ëé¼áSO=uûöm·¢£ èB=¾L&{â‰'Ø ¯Ù74ÇÀºèéé¡6„<‰Q‰Åâ ®šeo™êýp4ÈI’ÌÏÏ€qlc6›/\¸Àš9Š¢hooonnîéÓ§=zDßtiÑÙi!“ÉîܹC§$”ÀQ(„pÞ¼yW®\ñ*>p©Ëâââè¤ z ¢¢¢|h¶vðùü’’’ÞÞ^HÎykk+›>¡H$ŠŽŽnhh`|ìF½«ðù| ‰$É‘‘· '·[ýêÕ«;æ+Üœ••âsBbòð’)ÎÆ˜˜£~~~ .LII1 4cÜb±Ø{jà¹EhE«ªªžþùIdŽiÓ¦•––ú +‹ÅâÜÜ\fUXO0¿ÊšFÐñ‚‚8räÈ«¯¾ ïY,xI¡.\P©T.³—»e×#§/ŒÏø|>³ÒnÍÐ^è PàáÇnyœz¤ös¸d»ÖÖVÐù€&RRR@’„Ë‘Qíëë[´h(âärÂö†3ô¡Óé蘣۶m3›Íî&yâ8N¼ØÉýû÷wîÜ •‡‚X·n]RR’ãKq—6&HqommrIq ÃÜr«Ö®]ûÅ_X,:kYYY988hÏl¢¶Š.\è®ÝO“ŸBCCKKK=zäÖàõõõ O<ñ¤þñÇUïg —.]ªªªâóùÜ=IBWWW÷ðáCšúÞ­ØV«¥¹¨‹…æN"‘Hâââ¾øâ HîÉdr7ëB­V···#ÐÄAŠö¸zÄÞ…ÆÃ¯ÖëõÌiq`AzÉ>6›-???33ÆþCÿI{{6!"š¢Åàî²]¨?ÈŠ´ŒBzzzzzzGG‡‡ÂÃzšd!¤Éý7nÜpËâr—ÛèäO{R¦~rk´`öþûï°Ëë ½½Ý›+ sBèZ…ÇÆÆ‹Ô. ÎÄÉ]¡ÊÌ̤稴´tñâÅóæÍsë[è?¼gÏžeË–ÑrxIä7nÜ`&À—Oe!Œ‰‰Áq!IÈxzįí-4.55õ£>¢™¹¦V«A:Â~¬âî®âòù ( ú®¯Ý<†''ûöíÛ½{7ÇåSÙçW¨XŒœ>–”8{lÿþýûöís—Ýy<7w}’ˆˆˆ5kÖ=z”õ*&&æÛo¿mlltë5###ÇmÈ x<W8|Š ¡ÕjU©Tf‹¥³¹q¾×‰D"eèô¸³W¦o»’$IÍKÃ@ÈédBÒWޏwï^UUUBB}ÇÀ!äâ%SSí>¸¤MX­íííˆs›ª»»›æMBG¬Zµª¯¯Ï¥‹ÕÔÔ$ ÝjsK¿}:ƒ&¤ÃÃÉd*ñë”<Šd’¶f0ZZZZ[[õz½P(´_ÒsF²C‡ýó?ÿ³»ä[¼xñçŸîòSÍÍÍ|>Ÿ~ÃwÇE"Ñðð0Íç?ýôÓ´´4šK¥R°mÒY:q] ÃþýßÿýÌ™3î.ÖùóçW­Z5u˜Ãüüü¦ÞöÎÄ8þ|~~~ooïüùóM&S]M ‚ãäx«Õj ÓH¯×ÓI‚Z`, Åܹs¯_¿N_®èßl\¶lÙàà ýÌ8Ee2"NÃÃÃåååî®Tiiirr²3!·Ùl̬\:~ +[$ Àî¡dggCºm4rÌ-’ B"HXXØË/¿üü?ýS˜R¢TJ¥Ò‘ËÇ]ÌsçÎ1+¯’’RQQA'+•Ïç+•Jš‹ÊãñÂÂÂÔj5Íih4ús/\¸@ŸK:::Äb1ìpÄÍÃ{ÈŠB#L›6-$$Ä“®fÎjä¨T*PœÎCQDQ´¦¦dkyùòe_1›“““é¬Ï-’  ÚÔ„ôô |¾±½Ý&˜kj’ÅââE‹Úî“n¦-IDATÔꈖ–¿;*´ÙÌÌÆÆÆØØXï°zõê5kÖ`æÌ…¿¿wïžL&‹ˆˆ ãéÙ»>ÙÏô\~äìÙ³o¼ñÍiF±XLÿÆÃƒššš$‰Ë™ (jo8Có$fdd„Â'I2<<<44´¸¸xóæÍŒ…„$É   ÈÈHÇßoÛ¶­ºº:((Èó‚ÙÇŽÕÐÀ[ëõz:i’ôAŒ2¸·uëV:Ì€¹+ÈÈÒßô÷#z=‚aÖ¡¡Äèè¡°°Öþ~d`ÀñÙß ÈÕ«W—/_Îà‰ŒŒlkk£hú .bs…¾YÕÚÚJç#MMMQQQ45zXXX?ó hÒºœ ŸÏ_±bEyy9ý×<{ölNNŽ3M Æéééñк«®®£0qêÔ)· ”8ÃØòìV‹‹¥e€qÎâȧN¢ie¸iŽ HJ ²q#²f ²h¢×[æ<ýtoddû²eÈÚµäºuÈßþ¡7vuuUWWgee13Kžzê©K—.Q)Èc¹¤µµÕh4:†Îèæïï_XXèìƒàë¾ýöÛøøx·433³¢¢‚ZÁ€Z­vddD$Ñ¿ŸJçúpæÌ™.w¹„„N÷àÁƧ…ÀÊåúPéÑQt†qj üÿ¸BHZ­<¡ð“ƒGFFþáþaýúõ‡¶o8ŒñÌ3ϨÕjµZí8Xà{÷îµ¶¶nÚ´‰Á°J¥ÒßßÿæÍ›Î6E;öÜsϹ{œ‘‘QPPre1"È:Y£4Ç …×®]£³ê¹¹¹‹/vHi½üáàþJDD„ã/“’’är9[ =*ªã~ó„m¶…‹# …Löì³Ï¡àQfU0H’<}úô½{÷öïßï¨ül6ÛŒ3Nž<ÉLƒ${éÒ¥ .¼øâ‹Z­699„<¯¨¨húôéO=õT^^¸bæ2A 6>žš ÊÊÊ †a===f³922’AÑ:‚ "##% s!4›Í6l è=ˆãø¾}ûÞ}÷]ЉD'NœP*•‹/¦¸¬©×ëÿûßÿò—¿¤ø:±Xü›ßüfýúõáááã~#¸ÀræÌ™_üâaD"ч~øòË/SÔ#äóùùùù]]]?ûÙÏ(¦„aØþýûß{ï=ŠE‰Dß|óMdddZZš3  (:<<|äÈ‘·ß~›šŸ}öÙæÍ›•J¥3šã8þðáÃÛ·o¿ôÒKΈ ‰öïßÿꫯRÔðåóùwîÜéííݲe  P°»H$úë_ÿ›ššJANwäÈ‘÷Þ{bíÄbñ§Ÿ~úôÓOOŸ>‚jµúÞ½{/¾ø"ÅPàÀ;wît¦‰ÁÍ›76oÞÌ 'PB¡Ð£P$ùùùQ÷NzòÉ']Þ]¸pa@@u…O‹Å²bÅ —_—™™%—Ë)^;33S&“QÒ]±bEXXu/ѹs熅…Ñ¡@`` 5RSS©) ‹ýþŠÇ–-[éïïOñLll¬Íf£&Š+”J%õ}Q•J¥ÓéèP\ó§À¢E‹\ÖÀöóóËÊÊr¹v€ÔÏÄÆÆ‚–XÔÉd²Š;Ä*• ´£ÓAŒJ–˜¡   77×åcf³Ùå3V«• —÷²À-GjX,ê\lœXpŸkb(044tàÀ¶fî’^Hv׎ÎP»wï¦~Aš †]¦G•P*•ÀVû§Q®-õ% »wKñøˆß¸ôï)†bkġȂˡX¡0ÿ/^ìr™hΜ¢Ý•wR€õµK±œœ™™9jQÏС€K t. ‚ï0™L.\èìì|å•W ï ÒØØøí·ß®_¿>!!»÷ ö"#) ‘EÑ£GŠÅâõë׃p€Ïóòònܸ¡P(ÀÝZvWÖ9!L]¿~=""bË–-¿ûÝïпAúúzµZýÊ+¯Ü½{·¾¾žãH SðÆQ¥r¥Ü%ïÑ£G333U*ÕÍ›7AÀÆNóüüü}ûöíØ±ãàÁƒ¬s8ÝÃz‹ÅRTT´páB³Ù<ÊO­®®–ËåR©”Û½A—Ï Aýû÷›ÍfjAEû.£¹f³Ôn ¿ìò¹k×®C‡½ù曬S £¯'@rŒ½øA ,+|´2ùÔÓå‚üøãííí ^+‚ CCCf³Ùl6ƒ8Äðð0XAƒÁ0<< N™¹…åïñù|ðÃÐЈ €ó!ß‹ïÙ³‡æóx¼ÆÆF¡P¨Õj{zznݺÅçó£¢¢:;;QÕh43gΤ8àíííkÖ¬éïïW(÷ïß_³fÍÞ½{ûûû›ššJKKårùgŸ}–™™ÙÓÓsâĉÂÂBÇÃÃÃ9û ¥¥Åßß¿¡¡A©TFGGóx¼={ödeea¶gÏž·ß~[«ÕÚ»©MôN"NéééV«µ°°pÛ¶m` !!!*•êÊ•+K—.½ã¹åœ,E>cÆ …Bñꫯ.Y²ä·¿ý­Éd’H$GŽimm}þùçO:U^^þë_ÿ:77·²²2..îðáÃmmméõ6nÜX__¯ÓéÒÓÓÝŽ‰ŽŽ>tèЉ'êëëÙ7aè—awŒÌ"NÊ`sná¤cÖ¬Y?üðCbb¢D"éïïÿÕ¯~…ãø»ï¾ 0}ðÁ8ŽwttètºÍ›7‹D¢yóæÅÄÄpt£frg±ºç„têA!\Ý xûöm©Tj0zzzZ[[I’lkk3™LÝÝÝ aaa³gÏ.))‰7›Í uúœÌ:“Óõ 9ø d2™Z­6›ÍþþþIIIF.—GFF‚¸_ggçœ9sž{î¹ÊÊÊÒÒÒ pöË$ ?çÂMUƒ ÞG8°‹ÿ—æ_dQz2ŽIEND®B`‚snd-16.1/pix/title.png0000644000076400007640000002252611147553271012777 0ustar bilbil‰PNG  IHDRN&”_sBIT|dˆtEXtCREATORgnome-panel-screenshot—7w IDATxœíÝ{˜eïñ_õô\“L®\r#DH œD²È ¢Džu7]]y@å<®î¢ëîrô(+fq` !@ȃa4A ˆ,‚áFˆ$™É}r™™®óǤfúRÕ]Ý]÷þ~žg S]ýÖ[ÕÝU¿yß·Þ6$™@IiIú¹9ìzDÖõ?þ†6~®}08IÒ¿u?f}"o(8eú†~ó½stûí·ë _ø‚N9唊 _øÞmÕÕDÎúzRÎߥŠEyÙ†‚“9ZøÎ;ïèž{îÑÂ… « NÙe€„0M;ùøªŠxö÷OÉœš‰GyY†ƒSñ300 wÞyG]]]š4i’fΜYr£¥Ê1”üß¾=»+zúá¾2Ms8'D½¼,Ã]uEZ‡Þ~ûm=ÿüó;v¬&Ož¬ 6hÓ¦MºôÒKUWWçø¼beðÖ²qÓ¥GÍ•$]üæw}ÛΪão”$=¼ç9ÝÑý+ß¶¶ Ž'Gæ‘`bš^çÍÁÿX9!»¼ó/¼°¬¢V?ö˜«òV?V|,wÎzyåeËjq(xP’6mÚ¤ŽŽÝpà =z´$iÆŒZ¶l™N;í4M›6ͱNeðž™þ€¿þ¿~¡·]æëöv=µY;^}Aã.ÿ€¯Û KÐLj•ôàLF¦YùŒFƒ-:U—g=§Tyç_x¡ôQÛ2.¸è¢âåe±ãdyá…´eË–œÐd¹ð µzõj}ö³ŸU*•²ßZœ€àäp¶®ýoýÑY¾nrWê_ÛªQ'Lòu;¡áxq“©´ÅI¦dš9¡’òŸã\Þ£«ÑE_"i0 =ºê‘œu¬Ç$éÑU-Oʹ«®ðÁc=VŸüä'•N§ ûøÇ?®›nºIo¼ñFÁx§;wjÓ¦MÊŒ%8–éMõÙ£ÏÕ¬æÉjN5h_æ ¶Ü®öm¿Ö‹ûß’$­>åIÒªžçÔoèÜ1s$Iwÿ—îÞÖ™SÞUÎÒã>¬´Q§'vn”‘1 ¶™éÏ •ùP÷3ú÷­O­ãì–ÉúÔ„ùšÝ2YM©íèÛ£õ{^Qû¶_ë`¦/gݺTJ_¹|™>1ÿeR¦Üñ{­ØþtÙå5i}râ|-}²&ÔÖÞ^=½çUýô/¿RoæPäŽ'Éš;»Ò'óÈÏðg*·¼U<쪜‹/¹t°eÈEy_r©¤Á d•o-³Öjm*(oXѧ‰'Ú†&IjnnÖç?ÿymذAÝÝÝ:ãŒ3”ÉdÔÓÓ£+Vhîܹ´8Y¾6å Mi¯ŒijóÛo¨¾®^'7YãŸ? ©íjš1nhÝó:U»îUß¡Ãjm9JŸš8_ë;×éõ“ÃÆÇZçèo&}L’´­g»æ¥fjÔ¨QÛÌþ îYÿ¦z^~Y­Ͷ­ßFLÓwŽ¿Vi#¥=öémïê}Sוã?¬Ó[ï‘Y?ܺ|Åy—hÏÁýê=Ы‰GÓg&£®7ëéI[Ë*ïÿ̸J§:A}ýzãÏoiê¤ãtñعšÖ;J7¼Û.£Ñ~eØÇ¨eV^ÊîÒ.¯€#]aÖ˜¤¼òÊ)×ÌdJ–'Iüò!]rÙà4ÙÉz,g›yåe+9Æ©˜Y³fiúôéúùÏ®×_]3gÎÔŽ;´dÉ3Fæs—]&TÇ4´J’žX¿Vÿ¯+5ºA£[Fi¤Ù¤ÝÇÈhmZ·gÏ.]pÝU?q‚žøá IÒÉýõÜïÖiô§iáø3$I[ÞíÒe_¸F©¦zýòßîÖ”£ËÙ¦Ù? ?Ü¡¾ûÕ½«G¶îRý›Û4bÊ8å»vÒ¥”vììÖEŸ[¬=‡öëšËéëŸù²æw¢NZiêå3ú‡ë¸{—.ú»OÊhHé—ÿ:¸í˧ÏÓªUÿ¨1骼ô¹Stú¨dš¦ùoõßo¾¦Y'ÏÖÊïüT˜|¢Nz £W>< Tº0<…u< «fŒ“lÆe/*»Eʳ<üÐJ]ºðò‚e¶Û+5Æ©Ò;àššš´téRõ÷÷«®®N†aÈ0ŒªÊ’è™]ÒY­³tÁüéô9mzcßV=÷—?êþžöìÑÀþán©§Ÿß ‡Ô}rÃвQ#Fª÷Ùj:q‚¦7 Ž)úý‹Ïêp½©ÆùÇ虯\è3ýõK·éÝÛÖI¦ÒSFÉÌØ6O1øÜuÏý^{û¨ùÜãµ&õª¾~äñ÷O˜¡uk“3†~÷Â3:¤>5~dúжOœ>SûŸWM“ÚJ—wpkZš%†¡¿ÿ³‚:½ÿèôtçãj]p¢Œ¼ž³°Ž'€a•ÞU甬òÊ)×43%Ë+õ|·õ“ʘǩÃ0T___XÆC¾ùê½úàk£uúq³uü”éúàûfëÌãNÖ™fëï_þ‰RÍß¡½û÷)5q„Ô”ÝÒbH}êß} §Üºñ-J7׫±uDÁ6­ÏàˆOÌRf×A)CF]ªäg35±EFsZ£O<:gyß{ûr×›0Bu¹Û6÷ÒÁm{\•7°ïðàÿ3½ü§W ê±kÏnõÿeŸúvíWý¨æœÇÂ<ž™ª¬ÅÉ!FÁgÊ*¯œrM™%˳,¼üÊ‚ç_vùzhå®ê'9ŒqjllÔ1Ç£Ûo¿]®+oihhвeËd™5ò8=9òýò×ë”ÙÖ«þë›tÁ‡ÎѩǞ¨žøƒÆº-g}£>¥ôˆÆ‚r2ý½Ùû4r²Îœ3W ׫ù¨‘j}BÁºæ@F?;ý©Mzâ½çuo×SCËóýqo—N=Cóç~HG=öÊŒlÒ_M®Ó¦¼`ó¡S?¨ÆUj5bhÛ¯½5ø…áýû\•w u𯺺TJÿrçÿÓ³ÜF]]Μݦ׺ÞFÖ©ý¬›d¤S9ûÖñ áàL…]uéÁFë3UP^9åfÌÒåIZxÅ¢¡?ô`Gβ…—_9´Ì®~yU?RvV?Þ™ú°â ™#ehâ„ Ê<ÃxÀrÛœë´oöm=·[i3¥é£‘$½¶åuõoÛ§ý]Ý…O*¼±K¦™ÑÊ®§uÓì«5ý¸©zìw*ÕT¯1# ÖÍôhJóIRÓ«û´wã[qæÛúýô'ô¯§.ÓøÖqZýÍŸi[ßnÐ:ØUµñ•MêܰNé¹ÃӌӪÇÿá§2ë4¡yp¼Ñ½«”qTcYåmxû:sê)ºëÛ?Ò[Ýï¨/•Ñ”£&©9ݨ«úí=´USGM*؇°Ž'Éú0™¦©Ë¯¼ª¬g®|à~GJþL ——ý7LÓ,Y^vW>pÿÐò•Ü?ôØÂ+iå÷=;·¼a¶-NoлÆHÉyRð’z{øë Èòð;¿Ó‰‡Çkê1“ÕÔØ¤{vkËÏê_îü¡R£Ôàpá“ì>BéñwžÑˆmZÒv¡F6Ð#¿yB2 ->/÷‹-³?ƒ™ƒý:´u·Ò;ZÕÐÚRPì Ý›õ·+¿¥¿™öqµÍ>EÇuŒÞÝþ­þͯôÃ{ÿCæ˜G‡‰×<¢þÌ€>ñWk×Þ=ºkå½zèWª¡m’êҮ˻qãúÔKgê‚Ó>ª)Vß@¿Þüó­vƒÞ\½QõçOµÝ‡°'€ÊºêŸs¤+,LR…]uÅÊûÄ•Wýþ‹V”ý‹V ­sù•Wé¬p,OrãÔÛ? Ýû V.GKºô8  –|oÓýÚ¹úUeÞÛ¯Lïa©_2SJoVÃQª>­¬þ²¶ÿàw’¤ôŒ1’iÚ.3û3º·÷·úÉ·ÿSýì‘™øýOß®þ7‡¿›ÉìÏ<ßìpülþ©©Gÿûéÿ«þm×@ÏA©@Fs½ê&Tã‰cU×”WÇãÇè{¿ú™ÞÞ-ÉPý¬qª›r”Ò£eög\•g6Öé'»;õÃïÝ£þ?ï•y _JJlPêØ¥{iÞ#_T÷¿ÿWÎ>„u<h¨/¬š™¾ì1Dyåe‡/Ê“¤;îs¬ïƒ÷éŠE‹ËËRõ]uNºæ OóG¦h`Ï¡ÁcFƒ“¤ Õ5Ö«at‹25údi÷`k‰™1—ÕÕÕ©ùŒ)ê›5^:4 C¦ŒÆ´êç-üìYŸA»çÛ1d¨åøñ:ò¤ÅÉ0Æ8>fš»l×Í_nW–Ó:~)g?ìž[î¾úÅ®.NËê£[v¯‰Ÿuúñ€8*çºä¦,Kçj箺*‡»­|©õ¬Ç‹…?yù"¸)«’7—¢¼ü ¹}^” øœPdp8]uÙœ§#`p¸WÍkAwߔھS«ˆÛǽnv4Í]­+źéŠm·Ô±öºU¨\Övн&nµ—Ç£Ô{$ì÷0D‘çF·ça·|ëªsSA/š×ü¾P»¹à•stÚ×ìÇú`–ªcØ¡È-§×ÄZæöX{uÛå÷ÞûsÍŸÖвyóΖ$­_ÿTÞ²>ï+ PDàcœ-Z¬ÎÎ'µqãK®ÖïêÚ¬®®Í>×  ´ÀƒSgç“’¤óÎ;§äºVk“$­[÷[ßêàF ÁiÑ¢Å9¿—juÊniZ²äj_êàV ÁÉjm²kuÊnm²ÐêÂXpÊom²8µ:Ùk¢Õ „)°à”ßÚd±ku²km²ÔZ«“a2 #ìjU0ÁÚ¬-{#ÖtN6n|©`Ú‚ööeo§ÙáÄ4ͪ˪¶ =e§SOšÜRrÿ]uÅB“4Øê´}ûpë×?•3—“ßòƒN5Á‡Ö!’Ë÷®:§±MùÜÎëä5»dšfEˆ–&’Í÷™Ã%iÍšò»÷â†Ð@òùœ::î³ýÚ•¤©$4Ñ­@¼Òâ{nÂá €èü+WâŠààRÍ'»;èŠ ôfBJjcœTž¼èí儚 NG¸ 7NëŽH¾šïªp‹ààÁ À%‚€K'—N.œ\"8¸Dpp‰ààÁ €#øw{—a'²Ä5$Pï`œHÜB‚Ï:û‰àŠ2M“uÁ +†aÄò"îgãx<²Å©þ'€çât!ÊApp‰àBa†LÓ »e!8úH'>‹Â_ˆµ‚c øà qj±!€pBpˆ¸„&(†àÀw„¦aqmÍŠk½ýÆq©=|å €ØÊ¿hÐ$ÌAM§5kÖ±5ˆ‹ € ùœ::îS[Û¿7žâ¯}w8FñÄû»rŒq€€1.ˆ/‚8ˆcÀ‰cÐ"b/®Ç%®õÎGp€%å‚R$>$Á J ØÄ¡Ì=Þë¥1á÷E„ /´8¸Dp€Äñvpº¼’ÅÏ×3Éï‚$XÜÂPJØ¡Œ1N’ÔtÀž_ÆÏÖ¬8¶”^"8EˆÝ‰ˆ0 VÄ5”ŵި ]u@Œ_ÉeÕ9®õFtœñ£•ÅïÀg‰k ‘×õŽk0˯w¯'Á Ê4ÍX†ƒ¸².äq e~ˆc(+…à¨á`˜ŸÇÂïV!¿Ê·‚{ÒºŒ N€²Å5($¥k á!8"ÉïpæG™„›ä#8j ]ŒÁJÚ¼b'@äÄ5ÜøÝJ×ã’$'<ÇpãwËMܺ]‹!8€X¾0œ\"8¸Dpp‰ààÁ À%‚€K'—N.œ\"8¸Dpp‰ààÁ À%‚Ó†a ýxQHž´ßX´h±ß›¨ša2MÓñ÷rËÉä{p’¤ÎÎ'K®³fÍZÝzë­Ô&—]H2M³¢ðd=‡ð@2ùÞU×ÑqŸ«õÚÚæø\UÓJâ!§ Î-Úê´fÍÚœà4oÞÙATËS•„&Z¦ˆ—@‚SGÇ}š0a¼ããv­M]]›m×mo_¡›oþš«í &QhrSÂÑØ]u œk»|ÍšµËÖ¯ʱœùóÏr½MÓ4ÊXprëä4¶iÊ”™ËÚÛWxZ'€r:S~«“]k“ŮթœÖ&·ìî‚+6ÐÛ«¹ž@ü2ÆÉ’?Ö©ÔtV«Ó·¿ýO’ü NRaxòb wµå€è 48IÃwØåßIgÇjuò+0esnœÖó;ÑÊ@qA4Tœ::îÓÆ/Å~Þ&P{BùÊ•R_ÃÇyœüµn¾ZŸè“ýgÿÙö¿VÕúþ[| N+VÜYösn¹åFI}ÞW JÞUg'—N@è߯m¼þµ×Á À5‚€K'—N( }üµ×¿¶ñú×6^ÿA'—|Ÿ9¼¥e\Yë÷övûTdóêKˆ‹•SìûõøËÂÄùßnj·|WÛ0´|ùÝZºôZÇÇÇŽ>ôïžž·ª¬UíÊŸ6¿ÒiôK•ãöƒFPçÿjÊŽºÀ¿ä·RcÇNÏ Kù¿Ã»7²iše¿Á+-'©$ˆº ÏÿI>×3Æ Iò ÉV¬•”T ¶Ä¦Å)­Mñb]\OHÞÏ€3Æ8ò¢OCvè— ßËÅ–Ù±ð@Ò%uÜSäƒSö€pëß´6J±1 ÖcÅž“ÿK. @1I}G>8Y!‰ÁàâŽñP@ü18¼ÆØý…\ì/_Ã0ŠþE]¬.@.Ó4s~€ yþO²È·8Á{ùoúJßì¥Ê)ÖÄ•WˆZºÐ :8ÿWàT£Ü¾yK­Wíã@d_ìZUæµq*Ãîq (œÿ«HpZ¾üîªË`|€09 /µÌÍlúâÃ÷àÔÛÛ]ôkTâ‚Áá.œ\"8¸”ˆ»êvîÜv@  Å À%‚€K‰èª³ó­o}7ì*€ˆºå–+z^bƒ“$ÍŸVÉuæÍ;[’´~ýS%×qRì¹Àn®ç¹ëöU´D§bæÍ;[]]›ÕÕµYíí+J†¬®®Í¶ËÝ<ø¯«k³¦M›¢)SfúÖ¨QscœæÍ;[Ó¦Mq B Þ¬UªÇ¨5œLÔ?T⃠€Úæe€Jtp²Æ1tumÖºu¿­ªŒD§õëŸR{ûа«"À‹ºœ¤Á) ¶lé"@P£ÚÛWhË–.Oî‚÷}:‚åËï.ký¥K¯õ¥V€Z·î·Z²äj_¶¢ÃjaòrÚ @æqZpõ-%×9cš¡ƒ÷ª··Û׺ H6?“%`ž1Í|›ÙÊ ºúˆ6?“%ôàd…¦g¶˜’öyZ¶›ÛÝÞšxóÍ_«¶:ÀGA\« N¹)wY1cÇNWOÏ[®—^.¯¨×IDAT[þð‡WtÍ5KÊ®'H¾+î¬èy§ì€tÆ4CÏl1s–e‡)/µµÍ)úø¢E‹%I÷ù²ý¨°ö3î’þ:ªãöº^Íu1à””* M¥Z™ÜZ´h±:;ŸTgç“Z³fmÉ€•O†]…ªÔÊë¨Ng瓚0a¼,8×—?¸›ÇɯV¥r,Z´X&Œ}ˆÅYÊë^—@'À +<˜¨M^¨ÀgÏO•tÓ;ÝõsLÀK¡|åJ9É KÖØ¦üßJùêW¿êI9 Ÿ3©p~¦ƒ÷Êí¼Mù!Émh²…mÜø’Î;ïWÏpâ{pZºôZß¿F¥”¶¶9Ú¾} €cÝ•íÕÙ¡tÕ…Å PkÖ¬ »*ÀGkÖ¬Õöí;<ŸÊ&ô¯\ Cv T­ ,j×-LùœJÝz˜”µÝ¸õÖ[î¾óûz—ØàTéwÐ8©©1NÕHl‹H¾·[v¹ZojïO¶WVpÚ¹sKÎïË®[¢wxR€Jtöv}|íÖê®/~ß“mÑUàÁ À¥’]uwü¸=ˆz”íü/_ìj=·yfÙuKŠ>^28]ý—\m h¯j³«õÜæ™Rc·K'€Èjq·šWy†1N.œ\*k§ÖÖi~ÕUÊŸc €Z±öÁ}‘=3‡€ØšÚ;ƳÉ-Ý «À%‚€KUwÕ†1ôoÓ4«-®ªz„¹ý ÕÚþ@´´Œ+kýÞÞnŸjœZÜçbª Nùo.怤s –/¿[K—^ësm‚ô>;}èß==oU]ž—* I¦iæ´@”«§ç­È&K`wÕYªÒ)»@fWVþzùë¸)Çí¶J)UŽ>Ë­3­z„#Ó8uºé*Ì^æ¦·Û ³Î´ê@2dwIY²[ZÆŽ^Ðò’¿Ìú=¿,»çÛVÜÖÕmYùÊ=v•,8ÑJ‡–»îÍJÊ <@¼9]Ä+¹¸— ^n«Z^š°ö'-NAó"”8…›8„;@x*¹ðWÂGÕ±Knœlxn¼èò$“]—•µ¥Ù» Tœ¬·ÓT;8Ü0B‰Ó~ùYºé ¢Ò}7źýVÕÌáVx²~ü ùÛqÚžÝzÙë¸)Çi¿ê\I9´X@üUr‘÷:„Ñjã×6K•ëÕv«îªs{¯öb_êùÖãn׫v7ëVZ7È Oonºêò×qzŽÛ J¹wZÿ.v\ì–yuìò1Æ €2,_~·ge¹ .¥Öqz<y5!ÉË}–*ß§Rëx¹ÏNN¸ÔÛÛèרDa¼SÐû쿎Á €ˆòj²ÈZä×±#8aI JAïKè-N;wnñ¼qQÕtµ„ààÁ À%‚€K'—N.LGÐöÝ«BùÒ?€(iûîUË ‚ÓÒk>-]óé@*'tÕ¸”–¤ëü«}†$3ìJÄÁÿ– kô‘Î&IEND®B`‚snd-16.1/pix/ncossweep.png0000644000076400007640000024526111147553270013666 0ustar bilbil‰PNG  IHDRôÇïO¡=sRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØÁÜO IDATxÚì½yd÷Uçû¹KîKíU]]Õ]½W«Õ‹ºÕRoRK­­[Ý­VK-Y–Íø1¶1Ä``à ƒ1K3D<36¼ˆ3<˜‰1bŒÁlÉÆ0~‡Ç††Á²°ÔK­¹TVeUîûzßçw+³²«%ŒuODFggUfÞ¼yë÷=ßïùžóÓ,˲p 'œp 'þY‡îœ'œp 'œpÝ 'œp 'œpÝ 'œp 'œpÝ 'œp‰ïšX]­òÊ+çDüÃtNN8á„ÿ˜‹Éçë€Æ/ýÒ7¸u«hd³ ^=ǯýÚ¼ç=»7<§TjÒn[„B.ç:€î„N8áÄ?UüÎïÜä+_‰ôGQffò€hˆXܹ¿°PºíùÿóÏWùµ_¿Å'?qÖ9™wÍi[s 'œpâÛ‰D‘Ï|fÐøÐ‡¾J¡ÐÀ²ì ¯¾ ˆêÿúúã««Ï2<ìàµ×2g¸ŒèN|ÇǾ@!‘àÐ{ßëœ 'œø6ÅÇ?þ*?üÃt;ûÞ Ð×¼‡‘o¨‹÷½Ñ æ ´M}£ÜÞ è¦Þ%¿k´¡Ó! u$v—]GWCetSžï5XJk|íÏÚœ9å0uÐøŽ‹ÄïüýÑ2óWExùû¾ªÀøåËì|òÉõåÇ´€©óçéÛ¹Ó9‰N8Ñ7n¤xòÉO°°eóú8=@®oïîr£‡±ÛµóÛ$t£Úf—ìnº©uý è:­7ÚÒÁ«nî®Ú¹ËT€®œòmƒµ¢Æë·,Μr¾cÐøŽ«\¦úWÅ~¹›7YªV)m Ï²CþÞ×€2pýå—¹þòË„€~ dïöíxúúÐà ÀÉŸýYüccë»´5‰pN¾ßÕQ­6ùð‡ÿ˜O}êub±w6¼©7íïbèF7Øwøf€nÿܵ C7¯3th¿®Wº¹•¬îêºÙ ÝÔÁ2Ð:¸œï¹;—»ÿdÑú“?&ÿ±±ø_`ˆEÄO; U@>¤¦åCŠ™¯ªçÔÔë¹= ä“ ÐÛê9ƒ€_=–×uö=ÿü:ȇÕk¸·oçÄOüÄúñé€èî 3À‰>‘ÍVù…_øùÈŸÞ™Û÷5mcû¶¶3MIÝZ—ƒÝèÔÈ»ëæ¦¾Ü×z×}S1uSC74´´¿–¦‰Üî×:w—ÑU?7; ½e •œíãk/9¨îºÿtQ©Ðú¿?Fú#ÿX®È *À´ÛÂÊg€RÀ¼O‡mß`‘áÃìÆ,˜b]`~70äÕs2@CÆ.æ`E½–½ÜM(@_Â÷ÜÃô³Ï‚bÿ¦:ÖÉÇc┣÷9ñög1.^üÙl­À{€]ë1³mZ+ßÄèÖ]+ßP/76Êé½ ¾Ì ›|ÚcAXÕÏýº8Ø=fg Œíp×Ëoh5?Þ´Ÿò—½Î—îºÿa¥Ö¨à=d>ûæ[ÀË ™ð°Ô„› Ìó@Ø€‹ù¥XCž“=pÀ„©:¬5aÆ’Ä ¥ÃjC¦)¿?Hó¦S:ÜÓ†e »ƒíìo à'Ô-¯Xú8°U1ùeõZz(„;`P%E•¸‡†xèßý»uù¿®nñq&À‰ ÈdªüÑÍð|žB¡¾ ˜wËë½-gZ§FÝ èF÷p­§ŸüìܾïR­j6KwuØ9.-¢aý‰%&™p˜ûtp+fn3tÍ캦£µ|øsnŠŸõ;_¾èNü£ƒù­T>ôã¤>û -˜UÀìÒài7,XnÂ\[À¼¢ ˜ŸB« ±ÌYšG=p¥ÚYˆÔåñàsÁƒ~ØÝ‚hI@~Qí]A8ìofkÂØW5ð{àá ô• U[Šåk.8à†‰XMyÌ–ÿ}:˜µ$XR @ i [¢äÕg,¾áav9‚1úeT"ÑÎýüÏîïÇBJ  ƒ{÷:Žo¹\÷¿ÿ>ýé7º—÷Ûo¶{ÝÐ7cÜÞCÞ öFÏï÷y·´nt@[ظÑaç]€Îï*9­_ýáømSœ2ÃÙìÜ®ŸkÊõnèèxð þÃ{üày§… SœÿX`þÙߥôâó,W-æ­0z4x— ZK@y±-uñ2ð@{`©(`¾ ž3â†Ë!he`®.Òü °-ÏöC%sU¸¥{]‡G‡aÒ9˜QÏYŽŽÁÙ0ä— ^“$#¼ðÂ8ø×D1¸¼ x`´¡U‚Ù†ï²ó3aØSe`Æ’: Øá‚mÙ5_úkˆ‘Qà ðç_ú.ä÷W•Àðx8þ0¦^£„8úŽ|ï÷²åØ1çÂr€ïùžßãsŸ›éòM@}Ó‘¬],{Ó4­3¦—±o&³o¨—wºz w GtÉx–⼚l‘êÑ;†8{tCí²¦™Â¨k´™I[=ŸÙaèN8ñÍÿúŸ)|ÿ÷«[Ì" [@dêk´,¸aÁ¢Õ³‡ƒ°Ë€•2Ì7ä9U ž­ Hça¾%ÀœöúájV‹°Ø€…Ä,p¹à™qp·!™†xEÞg 8³Ž{¡¸ UaæI .î…é6T’Âòo¶„åôÃs;¡”…Ô*,–EM(»aÏ0œ A~˜mË1O Ãý>ÌÂRIŸ Lºá` \5[±¨û41ùm³ä¸ Ðvj€¦ãÓ4–ûo©%í±Ÿú)·n¥BÇ+pìû¿ŸøW¿ê¸û¿Ë¢X¬óüóŸæÿp¶Ì»Mo› ‚éeá=­i›N{ët³»v®mb€ë’Ü]úÆ›¦Áçtùƒï³Dnj–5Ð ÅÎ Sø§fàû5t·I°Öäý'CüâUù@wâ:¿þÿ’þ7ÿ'ñ\q˜*ÀV Î)ðšµ:ì»_ƒ}^Ø¥ÃJ["u[:<Ú;[°RìÈò SØïÃÈÖ„1GZRw›py øš°’ƒh¢˜>¸<<×`¡. ™Óá¡I8b@: ± Ì5ä9[àüTó°šÐ^h ˜?¹¶4Ë/ȱ•üpé0 e¡µÑ‚$-qîÝ{]àIÃZ æ+’˜dt ¹>p­Éç¿e‰œï÷ƒ»•:DÔ9Ë!æ½à®.†¿Öè~`ïáÃdâqZë‡ÇÇÙºgñÿñ?8ö3?³ÞÞgîilu€ïØøøÇ_å#ùׯ§ÞÌ5à 2ylÞ ö›àÌÞ pÆXy÷Më’Øõ®!1¬èðÛ: X¶DnÚ`®wzÏu£ÐM‘õB {M­*—¦üÚÓ|ŽÞìºÿ@±š¤ö£?Âêï–H¹Â¼ópRƒÀ¼r¥G0špÉ å¶€o¤-R¶¡Ã¹ Lµ Q†›–jWÓàÝ#0X¹|®) @8„}a0êÌK=ø½ð̸3IÃ|S˜qß ï‡ ÿùšyÿâDÊÀU\;ƒiaÿ6ËOºàðN8> ùX]ƒxQ”ß„ rXÎÁ|V]pj/ìi J'ÒÂòª  €/áºÈø ÐÛÀ¤Ž_GJ+*™²¶¿Iµô¯(ößFº |@(kÛ_x{ÐÕ 89ÉñŸüÉ `¸Ý¸œö¾ð°,øô§_ç½ï}™b±qg0×»ŒnÆ& ­÷Œaíþ½n–nöÔÐmÆnjwhKÓ6ÖËm@w«[Æ€Oš`¶¡_âBôŽäîîv¶«q C÷jÐF@§X:ñž>v÷9,Ýt'¾ý N4JåÊe¯~ƒ9K€ÔfŒg58¤äåY„}–€1.ù!_É|Þ'ù”®†!›…˜bÒK ä_è‡p" ˜kINôÁýaX)øFšòœ°ž3# =« sý}ðÂ6h'!Q‚[uˆ6¡ ÃÕ}0¤ÃjN˜y¬"ìxï6xdÊQÈ­B¤&€ºkí‡þ¤Ò’Ì5@„«GAËÃZVÖ`©Ñø‡àêah¬ Ë_Ê ˜ì€K‡Àº•˜$¯+_ÀÔ<½êQHfáf[X~Ø„{497ó y| ©ñO{À߀-JáˆÑqòïRI@E=Þ]ã£ãäO©$Á†°JüGްç¹çÖ¯]–`&y„­§O;ߦøý߿γÏ~ŠÛkå]÷7ÔÅß ÐµžÐ6ú ýN¬\ëß6tûæÑáÿsÁ×5²Dn!r»ßsè†Ùs­Kr÷é0da„4Í,¾f/_ggØéGw݉ok´È]}šÄ«ßX7˜å!à0…€èœb†°]‡Ó^HÕ!Ö–Y@¤÷G}+À¢j?[ET¹gjÀLS¤ï%Kžsºza­ñ,´EJdloC3# }SIÙã!xf )Qæò^u\š‚aV2̉1/œ„SÃPO(ɼ ‹œ¸îñAs V²0ÓäÄ3φVV³òz±¤L8{7Œ ‘”úûRAXþ¶ðÈ0硘Äàó È– –„X«rÎ,/\Ùþä×`Q}þe`Ç ÜO’ÅN?è‡CniýË•¥¾?¯À|Ä€`ö¨sAjü5:½ú#J]IªÄ̶'^õ:µPS1wS±ÿ:p÷üCv¾º†¦.\ÀåwZ‘6‹—^úßÿýŸ§RimäöèV³«¯ü6 ¾ƒ[ÝÐo7Ê­»×ßÌü¶‰ÌÞ è¶®hÀÇ]`X0hI6BúÏ}]€n×Ï5ûft$wŸ£ƀŰ'ÅP=Ã.ìb{ÐéGw݉oOÔë´>úQÒ¿ù›Ä®_gA@ ™úvE±»9è«ÈºñˆKê鑦ԾmÆ¾× gÝP¬Àl«S/>懃€ÑZõ­–€‰ß”{P‡d –*°`AI‡Ǥ_=·* Û½PˆCvE {ËG'Á¿ÙR5~7<ÊII]~¡+ئJ 5H)ö¿Ð„Œ&Rþ‰€ÈüËy˜iÁŠ gvI{Ÿ;)ÉÏL[¾Ÿ²ç†agªE1ìÙ ˜¦Ã˜G€¦š#`óúuðµa§úL}gMÅâM•d•’`‹Å.d’_[%£gÎ`zeqö( o{½<ü‹¿¸j€áóÞ¾ýmñ'ößþÛküà~\®·ÇÜbÃÄ·Û·y»;}S0ßÌüfw×ãf—)îN2»ÙäöíËn´¿Ð±†ÛR?© / uÍo×;­j(–ŽÜ4t4¯F{«…9ÚbÄ·Êde‰§î™âgÆGßö˰c#pâÛƒçûéŸþéu†·Œ´žS»‰°Â¬Z¼/¹„¹Ï)pNm ñËD¸tIZÙæc?æ#]¢& {^±Ï° Ï ÀÄó"ÍG-‡ÇG`^ö= ¤5xa'L–!›–÷ŸmB‚]ƒðèXËC<'¸Ð††®_Š11ÅÍX‚D‹úP™‡%±GZpá~˜ò@.+iXÎJ­É‚+÷À r‹UǶê…KÂhÚ3JÁ¶0ó»$aéÏÂJ^ä÷… ,µáØv8¹E€<‘GÆ`·Ù˜J4T¿þå½pW êËÂ䯫DkdžÁÖ&¬¶$ù™S%“©>8ì…á²êñG‹¶Àþ ¬Tä{‰*0wið c-yÌž `ƒù80¬’¸eÅÜ£_ûº’ÿ[êz)o|þóX~зlaúïØÀò5`Ë©Sxç;¿kþ¾^yå&ï}ï+Ôëí0W÷õ®á/f·¤nÜa²Û&s×7ûÝÍ$v£Ëg;Ø»ëéwu·Žö 7%óXâØôÓÕ{®wÚÕtS¾QÍ ´¶Ž»ÑÀÝhPÓ=XA0mBF„¤‚Cwºß(ýÛËòÇ>FÄ’¶´´Z˜G˜'3*×ó.ð[RC¶ÛÕ|:<O]™Üè0öÜpÒIþ&Øi`ÐÏ @©&,s±)æ»Ñôö¤²v±†×&`¢$Òû\SLi+‚‡F`5/¦´¥rÇÿÌ>pç!Ÿ‰{põËÁˆCnM†ÕÌ6!¥Ãù#0©C:+òûrVXþø$<ºJI1Ò­eD(øáʽ0’…æ<ÄÊpKÕÅï‡ãP]‰=V†X¬ …é°0öd âe©ñûCðÜ4´W…™/TåµBÃpÏì­B!)‰Ä Õû¿}®Nˆ_!‘“÷™oAËûàþ~ȬJÂ0×’çœØ'PIHÁ6ìù}2Càh–ËpÝêôñê¢ÊìhI¢6KgZH-L%1æm_[‘é{©.öoƒ|¿ú½ÐÔ44ÃXÿ™©~wïsÏ1uîܦ°çÒ%Bß‘_Ÿüä7y÷»Ÿv»WŸPG¯wîzÏx7ãþV@½ü»æ´›oèë“àÞDjwëÐ0Ð~Ãi FZXÃô©/3@Gnï݈Åþö,O­I¸˜ÃmÖ©îðR¾7ÀH’þ™ããýüêžmLùßÞýè ;ñwŽöÍ›”^z‰Ø/ü æÒ^5¬¤õÌU¤¿úˆ.€¿ @!ƒWŸôJ‹Y´Ñ©—û دÁ1 âJz¶{ÒöÂV”êJbouÌ\†F–»ZÜúýð@¶Õ!Z ¶¡é‚KÛ„0dK°¤êåI ÂAxlBÀ<»*-ns@°žÙ Þ„ææëæzŸHÜ;Ü"±'sÂæcMؾÜõäc°\²Àîð?}«b~[PÓêÊAØ>"&¿bZdôÅ",5À ÀÕ»¡]f¾šc^Ê€¾0<1 Úªý¢2nƒóÛÀcÞ|Cdö‚žØ £-(¥õ.V–óÝpÕ]n@:%凅6Ôý°»Ozì«Iaÿ7,Hö˼wJ>ûM%å—t™ðwѵDT’‘, Æ\pº …¦$Q榺–ö©k%ÁÆÍzúTòhKùösCIýºJ kJœF=fª  ìÚµé<ç>ò<¡áaèC\ƒe°JЮB­íñq‚»wÛÿÆ^zé|ðƒH>¿É(×õ©o½ìº÷¾q‰ý½Ñ»—y—ám½ßܸ}pL·›Ý¥wÀ¸t¸îEÉ [XÃm¬!U? ›±x»ÝètKXº«nÎçè+æp›5êÛ<äO†ñŽÖÈ|m#ÜâÈ.7_9äuÝ&'þ¶Ñúú×I?ó K ÌÓqKkÀCŠIÍÓi£ª{”üºb (،ݥÁe˜JªžS ,¬Ãó^0ª"ãΪ÷©"²ü´G˜j¼&À¼Løàü4sÂVg•ùmï€ÔËkkʑނX,¼c» žYÉ ÈFêæÇ§àÞ>(,A*#5éENì—büI¸™–(C[à‰½òÞÉ ,e¤Í. ŒŽÂc»ü ˆ•äÜ욆³[ÁšâŠÔòoXÐêƒK÷@0# +‰Ìh;—÷V•Ö·d¢uXÖá‘ý°Ï¥˜€ü|Kzßûá© 0¢>Ì4EÉ™ÂäšbØ[*@´"e}C0= þ*dÖD™µ@óóû!‚Â2D•ÃYƒ³SpÔ¥I æêò9«œ†ý^It¢ei1\&Cb&ª‹20£Ú«l3Å3áWnýêš’ë§(/¨²€ {õó–ºþjJ3nõózÈÛ@zÍõÇt8ö}D|Ü^‡Æë‰ÂB"ûöáº÷^޼ÿýl9ztví×ñ„ÃëŠÁ·¿û»oð½ßÛÛšÖu3zöïeâöÎd·Õл'À½I ½À»ßËel¬›o`æÚFW»n ýr=ÛÆkÁp›¶½‚_“>I»~¾a2œºÞ„¾|¾\–¾b·Y§±Õ$ux˜\cÌpטÉG§‡¸æ2ß¶sã@wâo¯•‹‰'ÌÑcO >—ù®zi[-¼ç4ylÑê´QÝ놆ó¢jqË*Yöš ­†¸¾çö].†`B‡¥ª°Ï¨5ŽõÁa7³Â°oªÅüî0\@.-ûl[žãvÁó“`4a)/,3Ö”çœɾ p΂¸WŽÀ®:Ô–°n¶$ ƒ§÷@A߯’ž:ÁãÂò£j*ÝÑi83$õòtJ$ö›–,t×Éà™ÕŒy¬,†½'ÁŽ €|jM0Ò‚à†mm(ǘg,H¹áÊ1ØšY|© 7›’PݵÞ …5ILy9oKܳ NˆY/µ¦æèn?<¿ |)H'Eå˜UßÍ¥pÀ‚Læ«2­/ކ᠜ç|Y‹xAÞ ˜ ÀS#rÞ–‹r–²>7 ƒEQ_f”dŸW€|MÁÚœóÞn%Ù"IA÷.z†zÜT×Xõ[s/pò=ðÀ÷!Ô-à:X¯C6*#†oÚ#†Õkïë’þ×Ô5{ÿüþ‘|êuk€¥ëœééç·ãå—oðôÓ¿Ãí[žÚÌÜèaÐ]5óÛ¤wcsܦ€¾I›Z7#ßlç´·ô×|¿éC«Ñkc ·iÈptmcíÜèÔÏõ–N Xb ¦?Ÿ%\Êá1ê¶¹u`?no¿€n¢ YT·yùºgŠðú·éºNÜÌ_{ȹsDR)"jÁl;€Sj¡œW{ñ»<‚$áòvOúý&Ü­ÃJCläwð02`ÆvX§Q]ZÒÆtXª‰4C<3‡Åk³š—¾t{Vü±œsA>/Òï|[Žy{ÎôƒÖY8ZÆžC¦ÅM»dŠ\¼( EÞ„'öÀt +’H̶ ç‰!#[È ø/+`¬úàòai¯+Ä¥Åm¡ •~¸|W ‰ÿ¦1NÞ; °ÒòZÑ¢$;i ž†~æ)HåólÙç÷H»\aYÜò7-qå_¾ &KÒ߾Є&Ú†#Ûáä°$?KYé×סí—ÿ¡0”V¥.¿Ðöÿà]°» ú ¬eáºò% “ÛÀ•Rç¿*ÆÀ &Âpy+ä Êá_0oºàÉí0P0Wdö@¸wîsK6¸¨’Ÿ¸È.)¿d•—bQ}Ï-u îVÀ:ßÅÌQ²ü¥­õ€¹ ™½à>œý—0} ôˆó[и%Ãf+r `gP®ÿzVZ_€­ ©d¢®ŽËN€Cãã•bPRÇõ*GøíÜC”ËÍÍÁ|½…Ìx Ùü[¨¡›úíìý60ßdÌfõrÓ–ÙŽÜžrcüJCoÀXƒö¨E{È@j²@Ø­j¦m†v®Yþb™þL†l†¾|–¾bŽZ¿‡¯Ÿ½W¨AÐ[$(âÕqõ5ÐÆ,.un• IDAT™:?¤#ÀÛO~w\îN|Ka‹ä>üaV>ûY˜§»Àü~:æ7{;Tp^-E³ŠIÙ÷#†0™HCêÈqµ(?ä’Á3Ñfg£” 0eÀ$ ó1Ó­¨•÷É~†¥‚HÌ mÂ;‡`KR 0gÛÒÆuÿ žIU}[„íÁcc0XW|¼* ÅøVx¼Æ b ›mŠ),ë‚§Â`K¬ÆD öl‡=[ÀWûªšðÖꃧîpj1aÞ×-Hpâ.•H¨yð±’°ùÁx`tX]#ÝRY&Ï È€›f2ËRã_Ð`j7Ü„áœ󭺜›ºžÚ [,o»’3[¬ Zž¹ ôä"Á϶ ì‡ãpÐ’¿ä,¹`8¶‚¾&¯³X•D+gH½~‹K6ÄYÎÊyŽYàòÁù-0\ƒôšö€ª ûáŒå5éá·ÓeÀ‹~yN¢)غ @Þ«Ê9w«AA6coªko§Óµ0×Ô¨ÑÙáÎó]:Üw v]í–\À­U~IË6¾1\!x~¶e%ÑŠ·:›5਺¶—ÔûÛ`îB‰^Ub*_ç0¯p/U¾0×7¶‘Ý©†®·³o}û@×Þ¼×Ü4zXºv»ÎÔѾ@¯iè£-¬ hA5Î “qw™ëìãEÇ[®ªä UÕ­V íÓyõ£¸ê½EÞAw NÀ[¯•Yf™8ýìã€èN8±Y¤þÕ¿"öÒKDÈÔ"5W j¡‹±›ÀÅHI2Ìj?ªK}s¾¹±Æþ˜)û‘Ï´;á À¤ç=j 3^Trm ¸6 Ÿ]{5Lxç d„)Ï ’yxpޤ%m©(-nq úpqXYXKvŽmx.ŒƒVz£%&»¼ ×B_U±r%%ÇÚp`7œœ”òlBêò·,˜> ‚楘én"®ôÇöÃÝ.È©¹ï±’0æÐ <¶*XQãb#u1Ÿ]½†ªPIý–0Ó]ÛàÜ´E-˜¯KͼéƒgB "ÃmVrÂòÚ`úá™i éI(æ,ð Á»€{ *³2àæÕàÙÃ0Y%#R`Ž5T[àÐÔT¼,,ÖäûÜ3 çÇEIH¦E5˜47¼°×`mM’Ÿ•ú xgÌŠ( sVgƒŸ> ®PS†ÉEŽ-¤µmŸR‰º¯3̃t sí.0ß ½»ŸW2û4`uEJ)ËE)s­>Ú#}Þ¥äÆŰªŠ%]Ò¡d‰¼º¨´ð¤[ÕãÝrå¤W¼ªVÞðˇð`@Ø_L퇾 MxG‚Ù¨ÅvŇí„0ïhIdöœ ÛFáíM “]͈2PòH-°,£gWT»X! Oß¡”Œ„”Eú^lÁÔ$œ½,`¾”BÜ‚'Â/W!“„ÅŠ|o¡xqÚ‹OŠùïPpÁå0Y³`T9Öc-˜‡‡'!›&»œɾ“ݽñ%¬(_Â"°wÎø! 6½¹A§drah*Á\­ÓÉPAö¶?¨C±ÙQf œ§•o#G§]Îæ¼>u-VÙØú¶‡®Á¾‹Jnš‘„)‘…xZÎÛZ?{[P^ÿÅLMF§= Þå…\UÔœ:öìùúaõcê祈‹ßæn°Ÿ ÃbìÝÒŒ®=Å cãô¶u¦ÝÕ‡®o"Ãß©^n¼5;wéûÏmiÝìiSsëèïÃu]Ç®¢Ô±FÚ4Guš:­>CÝÓaó2ÎÀl´éOgXKÑŸÎЗÏõØ <áž !o€¯„ßWÆ,ã T6רfD™²™j,2™ŒÑ‘_pºN”?ó–ögY|í5"]5Ið€’Ôgè8ÜÛÀ=À^â j!k¨ÄüØm‰cïÈWBŒo'>v»õ-£’F]Ià}êzÍwy88÷}H€7¤ó WßqbYÈ·áìØS…\") ,¶e³ ‹!1&&ë’|Ùµ|]%º*kV©Z ‚—W¸Òæ½»¥õ€ywmÜü;ÖÐïê·ý«uس«»†nldåfÏT¸„cÞÄ70B-Y´í™í6C·÷?wuŽÛhY BåáJN¤öJž¹{÷âªÑïÊöä ù æþ2Þ@… U¢¯˜cÄ“d›e¢'›ü‘ ˆ‹>&@wâí¥/|…÷½x:MD1[J?£~ç&ØìQ l?ÇR è# ¨ç»²Iàqd‘¼ÕU/×€‹¦lÀQSät69nÂZAÆÅΪ÷?‚û,H«íKg˜»áé(W•[¼&²xIƒ ° È®I‹Ûœ%`úÂ>Ø’WúB]@f ¸kN Híy9¯6~©ƒ‚+Á(‰”¼––Äœ€Ç·ÂÎ:4otjÏN]&X+2Ý.Z”šýðìAU/_0—°¦¦àÑíP‹Ê°˜Å ÌéÒ~õ ãRÇÔ`¶kÛ ‡ÃRFXc[— a.LÀ¸ÙˆÔË[°â‚'Ê®s9¶›@ܔֻ‡Æ ¶*n"%iY+»àê!ð·Ä­ŸRmv1d¾üÕið¤Ä1o;üÝýðä(ì­uγ=IpÐWÇ@+©–°š$3kÀ¸G6ñ©6a^µ¾ÙRö„&-n^K’hc7ÔõPêON¼ÍÌ÷ÃÉŸ†@MÐÖš“zy,/·Dà!™{ŸNŠ“±.ÝeàR@FéFj¾¿%iÂάÎ$Å*ÐÄäe®ð‡¹m`L¯Ìþ­HîfÏ&+¶ÉlÝ ol¬¡wïen|C76Jî®;Ü;7þ܃i¶0ÃMôpÂm¬†ÍÞYÍ«ËV¨*éÐÑðg‹„K9Âå¡rŽPµÀòþqVŽ3àÊÐçÎ  û øü¼¾*¾F™Pª@°”#à.⨙nþpÏcxøû­<[{ÒLE|7µ9’»·ƒù—¾Ä.°Ôl£cds+0¯«ÅÒn# ©Zå„R)»û#êñEÅJì:æð¤z { U{ˆÈ3jM™o‰ÄžòÈ`š¥Š0¢¨ó‡ƒâ|^- (Ì«dbÔÏôC±!Ìw±.-YUàéIi 8GjrlM<· ÆÒ2®õ–%·Vî#Å¥¼Ù¸‚ðìÝ`å¥þÌ«Úó<{ôy‘¿çûLºàâ}°µùU•%ÑÛ‡Æ!Ü–V±µ”’ìªÅ¬º =áv½öÔQ)?´EJŸ¯KO¼9W@;+ †]û¶¤.õnæBB@{΂ÑpaŸ|Q•¸°Ïo…€¸ò‹"½Ç‹Ø‘:´¼’Lx’4¬¥d.ÀpfŽöIY µª¦òÞ0¼°Ü 9ÿ3 ÅØ58:÷ù ¬Þc¡ª0àþ Ü€|QT{\°wÁ¾6$[)Û®W¨ë­©’¼BWÍ<잀Gþ +’¥¶çT{aADIÀüù=Њˆ“¦!õÿ•¶¼Ï >³$‘›kuF\EJÅóVG²Í¤_æÿ™Kwó.çww/ø×7‚µÑ+¹ß¡ŽnÚ­oÝõr£Gj×Þ¼E­{KÔ®Ú¹¶jâþ ­9Ð@jb´h iÔG\4ú]4CfGnW=ó\‰dе4© é4Kû¶±xf#Æ*}î}î!o ¿ˆ×WÅ[¯àO”% –ÖØn,2sx™ÑaÆXa‚8ÛZQ¦ª‹„ úmØþÐøîæò2¹Ï}Ž[?ú£,‹,Ó1 íW5É”_{RWpVÕ£Š}—Õ²t‘³ívµ4²ÇyĔ誱W€ÃÀqMœès–,ŠdÀÌSAÐêÂçȇ]b$»«ËÊüA¤Ï ý°E‡TM&ÒV´%²}èjNäÒ`Ëœ ÃX^L\·T»~xÇ4˜%©UÇ•dŸÜ}2‘.›š·`pžÚæ¢ÔÒgæy\8“-ÙxQ”höO‰‘®¨Ly«9y¼„ËGÁŸƒÆ¬¤ÄüÕáô8âú’pSÕ"0 [W[¾®(i<ë–Ö·¿ìÔ–[·ü- ví”Ú·9/f¾9U²(úáê=ÐW–:~LM‘[jÂñiØÓÈ `/g„ZýR?è•cKfd¼ìŠ >( W[‘ó9£˜’ç·KË^2«<5ñ%X\Ø£ yŽ=³ Lºá°!ƒqìvEÛáV×ß”zlE]›öY°m.ý0ËR?jÍÈw-A¤ çgr.M€µ$ÿŸU;ò­Y°Å„cº\Osj¸%×óuMT’iûLÚˆ).ÄVÞÅ{)àãv7»¶Ì ãvÙÝ46s§iq›¹Ü7“ØÛÙù¦Á™kæ6¨›?ÀgÔp÷ÕÑZhCMÚíaÚ›z¿‹fÈ%€®’o¹Æ`b•dšþT†t†Ø]ÛI߯™bÈ•"ìÎ ;÷ŠÜî­Vð.—ñ/  ÷U²¬=0J}Q’ 7×ʦ)¬2Q‹aÎ6à Zú0͇?Œë‰+ŽäîÄwg´2ßýn¢üÇÄØ8cZŠùØŒ=¨jéµX%Õs‚Hís€Ž)-¯.¶G£_`c¯ð!à>M1övgì§WƒK>h(õœ% gØWƒ²‹Ùb£3E®¡Éæ"Û4ì­ “^ö†á¡A¨ä¤.:ß–ÑîÞ‡ ™ ¹®ÌZ¦®í”ƒÔµªÌj?½v…¥%-«˜t‘ùñÆŒ€ÜL ni²ê¹~¬HÂQõò‚»'á¾q‘þÓkÒâµØ‚†_¶]õ§¤–»’—csÂå°­ 刚¹^“Im'À¤ÊiÙf%+ŠÆš „­.é‰O«=Ü“^xâ8LT@¿%5û›m˜×a×~Ø„P¾³åk´$õò»§àîaa²™UerkÉV±—‚{J‹‡!(co÷5¡²$}ÿsMQZ¶ŽÂÑåXV% uX¶`wõA !uìH½cŒ¼Ë/;òåK²s]ì7Œl˜ã¥Ó}ÑÝ®æBvµ»ð}\™¨µ‰””beHTa[ŸLlEU‰£!æ·´%÷ó¦(@¯·%ɰßgpZým\§ÓGßVÌ\cïçÅ;€y¯ÍØÐ73µmºªñÖdzMpw2ÄÝfŠën[3Ðþ—·ÑÀnȰ—p-܆´ƒZé"¹«ÞswµA¨˜#\È.e —²¬í!~j;CfšA#Í +MÈS ä3œ¯\Ƴ\Á—(\*âϔɜ¦½ÇÅ$1†ê)|Ë|‰ ®T*Í9hܬиþç´~ÿÖN?ÊÎÿîðV ¬ºlð¤a†Ã ;ñÏ3¬Z™+WXøêW‰³q„æÒÇ»Ð%WZŠuœR¿éZH· ;¢e†§³OöEe¨»¡^ÏfùÓêµæ­N½ªdÊË^¨TÅ\e³üaSœï­|gR™ÝûþlPv1›¯¨žhKx¨ò)‘žgÔâ{döAmAÀâ¦:6žÝzQ˜Z\ ^Yß{|ŽK;Ò„¸Wî`lÏ Ë|C9ö''áÜT"×ÇJ°_o[j²©”à|¦÷Â]}à[‘M\¢jˆ‰>$sï²Èß‹‘Ù£-xêL˜’`,gTïwMŽùÚiCnAÙ¤}ðÔiMCk^|7•Ÿáà´¸âË R{¾{;ÏÞ z Ö–$1X)J¢uøì€kI’†E5«=°þÅУb>\PÀmÃØ <9!Cy¢ª^iH¶£Ù"Ÿ'®æåG‚ø¹>˜nÃZQdîY:;”1.NgŠ]½çšÃÓÿúÒ’u6"Òz8[–Ï™iÁ©mpTƒZBõÄ7eò]~t Hª6>»-²¡þ^Ψ÷_¤3®ØRÒ¿‹­üïb•0·sÕõ;™™Ýus}ó>ô mkßS7»Xý6nô¹ ÜÝ}ç¶ÎXñu@¯˜£ã Up‡êáZ¸²°Â …tjÒ‡îWl¾Õ"TÊÑ—ÏÐWÌ.æð7ËÌÜ3ʰ/ň¾Ê ‘fÀ“!è)ôñUÊx—Êx ÐE2ç†ÑŽil'ÂP5…g©†{¡Žo©‚;YÇ*´i,@iÜ@øX›!ë‹ð©/Ò¼ ÍoBáD3yüq¦>øAö\ùçÇàÉýmÕUn<û,³ Ìm³PP-Š5µ(Ùm7 }çCÊ(fïyÝVòæ9õøbWÝ <ªŒIsj¡Ë+¦>­ä|[.·]ñçÜ2Üc¥.-Yö®[£\sC¡*‹è¬*Lºà˜[vܲ[Üb–tÂì À1Ÿìº«‰1i 8= §]Ò®5£†•¬hp~—°¯lAI¿% ÁÁ-0aˆÃ9©Üß971¿eW„ÉÆÜ0²ž˜+&Ÿe®& …ƒ0®K«ØJFˆhKŒtçö@YM‘KæÄe?´ îÛCIfkòxu.ŸתŒ„gÌã5ñ];õ¬|þÕQ@–Mxì>˜²äóç’p« ÉŒOÀÙqIrVU?ú\]M±; ƒuÕÞ¦zâ[ÐòÀ3;doõLRõÊ+óÛÞ~¸×bÇ-o›ßBÈ6»|:NvC1óþQxþ]З0/Gå;›¯H²ÑÐáêNØš—íuoµä´ý{uyŸH»sÝf`ï´“Ó.Õª.•R÷ÿ/®ð 'í%˜ ³Ùíñ§Ý€n™z/¸÷JîoZC7nßtå¶yí›ôž»Œ.©]ýߣœêúë&/6 „K¸Ãuô~Ùó¼=Í!Æ IeÈG­ÏGÃïF× o%ÃÀÒË)†–×ðÔk|óÒ1¼cuÆ´†Œf†>oŽ€»„·XÆ¯à‹—ð&*øWJdŸÁu¸Å(IËiÜ u\‹ Ü‹u‚ñ"ÁDo*O½Ï"øÓ ¥U¦wÚס:/ÛGÓ"ë,¨åt†kûê²½ðM5ãbï{ÞÃÖ'Ðélá[|££ì{úiÐø§‹ä/ý ÿñ?¹y“%:ÛTú‘ÉoeØ6c7”4>¤Ot=gL}²«ÆÞ@úÑ÷)`·wÖ*+†Q‡½‡º-åŸ4eòW\õÇݸõÁ–&ä•ôn¿Ï~<æ…LSŒJіȵ†O‰\»š'u0½ðÔVYÐó9Ì[@V‡·Â!/¬”ñMM¥Û2OLA­ õr{ìª9§·ÂT Ê1a¥7‘íPφÁT2âb–e,¨;(›¸èua¸IeÌKêÒÇ~$ ½Ï©´ô1/»á£°G‡zDõv×å³NlƒvC+'cZ“i™ImÁîípf;Ô“bØK”`Qƒ½‡à¾aÐæ¡”yä·,hÂ¥ãàÎ@&-sâ£y9Ç÷„ñl<“]3Û\ Zƒpdì5¡¶Øé•_ñÁã'aK]L‰Œìi‚«Îî„þ¶¨K) ,µ!„³Û X)?^åfMƒûGá¸J)©eß°:3N0Õ†ŠÕ™Jh?ÒÔõæ<ýðü ÎÉ¢^ŠwÔœX ê:\Ù “åN‹á¬IKpíIÂêúš¥3üȧX¹O%¬6È7Ôc'€¿Âcügi£o4ÁÙ¬{3@7õMÜîÝnvm)þ-úÐ7•ÚÎÔ¹Íö7ßÌÑnú’‰ï‹ «ˆ?\Æìk¢÷µ±4ZCAƒú ‹Ê ŸjŸ¦ÇE0Sd(šd`)ÅÀJ _¥ÌëOÅ5Þf¢gTO2`f¤UÍÇ]¨â^ªâ‹—ÐÓUŠôcž´Øb-ËNl‘:®Ù®ÅžH ´Œ?^œ¬bþhUœ@oÝ€\Ö<°å}hƒ±íoÊãK9Q­•ÒØ¯IâPëâ²]NôûÜ·¯ú¾+jÍ›8}šCï~÷zêÖ ¶§N¡iòýÇb1¾ç{¾‡\.ÇÎ;9{ö,÷ßÿmköÎ;w݉®h·YýøÇù›|€¥f“¤YÔÅxTõRÃq)`V‹•=ÜCW@Rø¢ºÀ[Êøs\]ô‹ Ì몮y™Îà™¨Zü4à¨wiÂÔ”ù­ \ðÊþÙ15YÌfù{L¸à†µ–sDµ7YšŒät×!YY6ø  8;"`žPL:^‰u´.ìfš^6·LLÂù)°ºÌo7²ž9ýHg”#¼,#aïÙ÷ŽK­ c%%Ù`®"*ÇÎ)xh§L—[7ì•åÚ8° üš” âUSÓ'GaWC†òDêI‚h2Fø~K®»ËÂ. ÊËá´~xú f¥-­¸,IÉl–êò7ðâV+ÈXàVGJ·€ui‰[°:m‘UõOªß±')Ú“ßÜ*9®ÿ•‡ø­õaÈvë”dW/ oR?7zœî›ÖÄ»‡Ëôô¡›oêö}—¾¹!®g¤ëg»GÇüP\¦¶ùÂ̾&ôA{P§9(ì¼6à¦2 òaÔ› -&Š­2°¼F2Ã_¾ó,¾‘Í8ã$6Öè7³„]y|…f¼Ž;^Á/á[)S~¸ý´Î8 úsY\‘æl×\WDÝ·XÁ;RÅø¹– ò ·¯«mŒ}°ý‡À¯Z¹•ItoXRN Šw0ùf§ÍÖîæ1µ¶e»Ö@õ ãV÷ët:,î~ñE —‹/¾È¿øÐ‡xõÕWÙµkð€aüÅ_üÅmK÷Ü܉D€÷½ï};vÌô·{,ÿê¯òêü1%WÛõÅ»Ó^R€YT‹Ò p¯ºH£ÊÈÖP ÙYu1Gzêå;˜/ÐéIo*™ê µàΫE±„Ô½§5‘íÔþÙö¯«nn 뜡³·ún.¹\[bJÊ í­—Á¬Êö¥ j¯°žºTêlî1‚&žT†Eå<ÏphŽHí=R,Ø; Ol…朰Y{XLË×öCŸ½{YYÍ0oÁƒ{áà °R{XÌb¼2’•1¿EK²`'àà(ì¨Êv¤‹U²SðÀ®I81&}ç«Êü©BÅOÝ'®íbLÍJo@iž:þep³’‘cž³à¡a§GÀYÉõñ2øG`ßéýΫÉwKy1ÒMíS£2µ´$-nשCpz—šˆ·"`=_·þÞI8<(mwI•ÌDk2EîÀV8’MdÖR›Ïš¸ÏgZóÛ Ïy¡U–qÁÝ^ ;9Ý®’Ukž~BÆ[7廜mŠË>Ñ”alÏÃh®³Sß‚ºæ=ÀU Õù`—“šj¤«4e+P–*'íTÃÿÿËŒõÔ̵®A-FO›š¾QrïeéÆ&«Ü±†ÞcŒ3»v[{«Û›ô›ãÒÑÒ:?¬6 øe<}5ŒþôAkÀXgçµ/¥Á m4B‰,C‘$ƒñUVÒÔ†ü̼ë“ãícÚ Ãæa#§XÁµXÅŒ×ñ,• ÄK”/õ㹯Å+ôer³-Œ¹®ùî¹:îhO¬†w Šþ5+úVÐ Xɾ÷‚¿"7çeƒÅœ€yß684 Û 2/!Z×é´ÌZJ…í2wƒ¹G4k]j&]Å–™©)þº¿ŸW_}•ééi>ÿùϳ{÷nGrwâ­£:3Ã×®¿y“xµºÎ¾5UÇP Òr—‰gH1ö¤¶ñÈëó¤ZHƒªVØVL)Öuß ÷°ÌØõÅaಫVg :øjð IDATÕ°U—Ñž#meû9 žvIi ÒP\RÎçÓaØë†rY@fÁ’)rÛð¨_&Ví ‹Ù„gÆdVz¼".öHC6 ¹8%¼Ôšªÿ6¡€ƒp* V\dé[–HÙ÷ÝÓn‘õ– ’Äk aß(L‡¥&»jïonA¨®î““ž_éý09ì=& ÀbMdö¢.íÈÕIUŽ5 o Nì”~êb¼³!L½ž;ž˜ÈßѢȈ­QØ;%ç+¿&IA<'çahÎýÿì½yŒdùUïù¹÷Æš{fåžYY•Yû¾¯]U]ÝÕ{uWov{y¶X¼ @È0ÆæÉ1oñÃŒFhY€AÉFf!ì‡±ÇÆ ƒ—®Ê-2cÈŒŒ}óÇ9·âftVÛhhó*¤TwEd,™ù»ç{¾ç|Ï÷œ„Ú–¸­”$'›A¸õLÔ¡¹$ ½Ò„̌ϹqA°ô†T%Ökb|óâe1ÞÙÚ€Ô†´ Âj!øêi‰†Å¸|†•$-xô,4%ƒL©Â¨ðÔ,”Õ^UdÜbÎ}ÈHe YˆóÊMÊHe"±% ÀjSæÈÏÃ/ê<踖´ýô”žóE½ßqž›RÐn°}»æSz=}›~‹!É$%­ªh¿/*³¶‹à¶õÐÝ`¾ƒ(Î4ºDrø·±Ì}QÜè¾·u‰ïÿ²géë)ì«àªK¹}Р1â¡1ì¥6ì£:¤î÷áß(1˲+œd8¶Aej€õ2cŘiD™ y_ çËU±¢u¼kU¼Ñ*þt•Æ“}/5˜ E¶€y¯…µdãYvî_­áËÕñî­cý´-M7åµïI›%R‚Æ>˜¿*í–DK‘ÈŠ0s¥ óûà‘Y0t*$¬ËauSZµìwi&œÊŒ©ç¯Oïs{Àø‰üáw¾ÃWmÓëåSŸúäsŸû×®]ã=ïyÏ?:Æ?T¹ÿ7r«…ÃüýíÛ„ïÝ#éY Q²÷ÑYmZÓƒ1¢6¢àçd˜Ž‘L[[QË÷+cot1vKØ9=ôŽlSËT· 1qX”€ƒ&ÒŒë£.ã˜nÓ˜ØùŽf2.Æn;3p˵¬e'vn™;ǽIá¾Ãv5×R£ =±Ê}?u_ o£¿=`Òî{ÀÄhã ´ðg³7 lm1Ý¢º»Ä3{™öÅ™µ#LYqÆI±ËÚ$-aFšXá:¾pïF ûfÁËe&Û z7‹ËmÌ»6žeeç«u|u¼n`\hËT÷Ø·—äÚ7 ÿ18|RJìíU™$YWl¤ssðÈØë2’¹¦Þqý @l|Ót36˜Ö6eº‹™Àرc¬<òÿõÛ߯ð‰O|‚}èC<þøãÿŸâüC@ÿoÌÿî™g)˜;¥¢AeÌ^—(ÍQŸTvw•¸±›SzŸ#Jk¹À¼ØÕcG¿ÞÅp–¿K/Š„–2ñ¢=w¨ SÇàÎaaåõ5 ro´!7Ï^ƒ¤”Þc™ã^«Â¥ pd )H¦Ôß½$ŸùúY8Ü/[ç²ú™ÛÐ; ÏÎËè[)‹N¿|¢Ol|›"d»«gÍ™²8…ŒMn)˜Ú½ðʈC}UÚ,wµÿ]hÃñ¸nÉ‚ÇwÝ™²8¦¨u½6b.É~:ÇQ×û59p1ö¿ã„‚¹ËŸÔýt·o»ù¥õ·ºÏÚȹsO—`î>C· føz¾Þ"=½è¾þºz· · Z6VO‹žrÿf‘ÞLžL–¡­ ß{Ï%¦ ¦Úqf‰0a&56æKáæzO¤†?\¡õ\/×̃iéKKm¬{¶áBMü¡ž_jJV÷m-±ß0ßÜ€å*ŒÝ‚½Gåq{UtkE•eaÑî xr\W—dòa½.×G x¯ }ºHÊÑóT]1uJãhÒ•:½ô]¯¾Êÿ™ÉðùO€_ýÕ_ågögªÜÞ~À~ùë¯ó½_ùÖ–– Aç„K©é”„¼ æ†1§_Ž2ì;(Ü÷êWEƒß–>gcË+(;.r&â×CÇEÎY‡º`Àc†Ì(¯¸zì ë(cíŽYMñÀA¯Ì'ÊÂÚcús>7 ó H馴аàåI)Ç«RÊ7$©81ׯa+¯;¯uO·KØþŒîC×Ùwk^; fZv®‡Ê€7ÝcpsFTô›Ê˜[²võ¹#²ø¤Þݶ¨â_<cyeÒ:_¾Þ€³‡áì2Ø­BsHæØ)Éke’þ n^€ƒm1KÙÌÈv·T®?&Žk•DÇÛ=’‡‚ž¾"ëHó1Ò%s’:..vöŠÙ„«pÏ€S·`¡_þ¹¤”ò×Ë`ŒÀ¾=b¼“K‹^ ­cyÖ8ž†y¯LdSÒËNùá‰+ÂÊY•ϼhK_¾ì…`ª ¹-I{Õ²²¡ÃZerJŸV/¼ãômºÆòô¼•ó¸hBJ“Ÿ5:#›'Sšõ®R:t,Ž×é8¶µjuB¯#§5õ .òE^¦}¿g® Ýc€×ã*·+@Z×^ðýûŠâ¾ ;³uÏ[€ù›Êì2nx <«M†ïeÙؤ¿·@ ¯Š·¿9dÓ2hy¨û¨úi×Ûø’e‚±½©<½™[Í8d3EœÉv‚¢ŒÚs%ÚkMÌP+ÜÀ­Á+/V˜h' &Ë4¿gÁ˜K6žÅ&¾•žtÏÇZ VÎÒ/Of%9Þý,ìAŒ„åX«H…®ê…;§a(+‰óZE¬‡£ ‰iŽ–Â¯@¾Jg]´¡e^ïK»ø}>ö|ô£|äÓŸfcs“Ë—/ó—ù—|ò“Ÿ$ ñ9uŠ|àýám!{­ÆÊ/ýßùÿ„mß¡14‹Ü§€˜r‰xüÚû3]LÚþŒkàL¹Ô½Žn79§¿8¬ì;çUTíyYwî9}§ô3$äz»?û~IÙRLE¨û0ÅH¦ÜЭ[Z~Ÿ Âõ>è)v”Òa e #0m (…T-¾œ…KCP(H™{½qÎ/ÈÜqpS˜Ü=íå÷ ÀKûÀ³)ŠèõŠær&<¶öö od:;Ç÷ÌÀ™qèÍë⪼Ãðø<ŒÅß}UÁ¼„¹ éKç³Â¦ã[R4áÎ9™©-Å¥Ÿ¾Ü„Þ½pfƲ¤y™£Núáæ#">,Ååuây î=ûgÁ[…|\s¼¹Ì æÁX—Ç–k…©pb—²d2 æ%虀G/ÊáÙJ‹‰M*#Ÿ¹ož8)àRDt +MhŒÁÅyØÛ‘a\Kï+Àœꇼ$ë©ÄÕ^u¿V†RtÆÈŒ€$Z=[¢²é(¡ãâvÖ+-˜t]ÎFÄ•œÓ2»3zæœggú£¥gÝ9›ŽÉÒQ=ÇI=›Ezù=~‚Ó.~¦åqŸKçÌww÷зù«?`\mÛsûB–ï7²ö ™ó¬^½Ûûè¦iã«ÕðÿCƒÑæ&ÃÁ-úz‹øûjb&3ÔÆ2iy¨hÙàMUñ%Kã‚ù2…‹øŽÁ ¢hŸ$Ád;A S¢nA¨‰ªãI7°nù~¬Ì¸"¬Ð|äõ†‰¹dc-Ûx›˜ÙžÙXÇÌЫ«RFÏ AÿA8Ò¼>§‡bîrIƒáº‹á˜zÿ0%½ÿíç‡è,Wi*[º¢÷¯¸úòÃ&<„jC¶³ÙjÆ/+,[)‹;ýò– ¯ ŠÀ.\S§² Ø?(–°[Yé㆚Òã=¿.ÈHVR-L×Mèí…—æÀ«#i᪖ä xn?ì ÃLmªÐ® SâUÞLŠø-Tƒöã3²s<“ ×å:´û๳,Kß=•‘ÏiÉv·Û'À“ñ[J™t`ž9.â·jXXÇJbܾcMIâ[b“¨ÁôÜ8.nù¸nD«@až¹!NjÍaÒ‹-¨ÎÁµG!ÖÒ{V~±»sCÐ.ÀfBÁ<+U•³—aÎFJ:âö@ßxâ˜+2–.HÒµÄöÙ)¨¦uö¾, i-}>íqâv̽~xå Œ%æÓÒJ¹§Œ à€—Ôã`ÙÕNêS†=äª&9×@‚yUïßt%ÇCšÐæ\¬¬‡?ä},r7¹Ày­7º·»än¹L_ÜÌÜú>kRw_{«ú}`w)íßÐ <4ñ×ËXéé £¾ †z²ôö–„Ø0 ÍAÃÕ}¬D _²Œ?Y¤'Q ÿÈÞc&3D™!Ê$ &HÒ»•ÇÙØk6F¨!b¸§¼ ôjöî‡ãÓJ¿<³!ãb“'e7ø@+¢¢¿×†Ú <{¬ˆø±Gs2b—nÂõ'd{!%Šø¤|æ¤O>MIŒŠ1I4ÒƒðøÓ0”ƒö¢¸Ø…êp·%“wÎÂP^‰XQ’Œõ†$¢‡üpÚÞ†|ÞUÕRôúá¥=Èi¿´%ÁwK÷Ž®‰ 'ÑìGvÔé,wqJé}ÐKlß"hè™Ð ¾ájMý%Oñežp\ ™‹sÀÜgmSó> ‡þ–½óïWråkW/Ý»ƒ0n‡r»á_³‚¿QÆ(·ñfL&­#¾ =yzúÊXý-ŒÁ6ö°°óFÀéžX²D ]ÄcÚÔÞ9ÎD_š¢Lc¢¤7_ ±Ô¦µjÃZ s½Žÿ/ƒ—kŒÛ)‚‰"»Zo˜Øw ¸ÛÆZnáiÑzZ’YG×¾+Z’å:äÆáê‹àKJ )Ĥ-´Z•„ÿ4œíf-Ê\«C²-çᔞ¡(ê_Ö¯­žª‚yÞ%~ó‡nÝâøßÿäOðûý|á _à©§žúÿ5þ?ôE·Ü·¾Åן|’x.GÆUô«XÇp•­)ýJ°}ì¦GkÅuˆm `çõßQ:ëP=Êb]=v§/?‡Ì±G]BººÞD?Dz«_>¼¨ʪ^HýŸðIÙ8Ö{‰•{¼pÝ Yí£;ütÜôÁVUJÒë-)×|²sÛl ÃTÄ•.Ð/-H)½œ½ä<ð伬èÌliÉ^Uñ{GáÖn)×§•I¯7E•þÜQ¨B#®^á6Taa.ôÊB˜°.I¶¡<5Í’yjKÔôi ®Ÿ€… ”«s))¦zàæ˜m€­›ÂñÛ¾£pi4S²¥ÍQ²Wƒðì£àiH€ËŤÍN^…#Ò/¯¯«ú?Çž‚1 ¨%ý¬ÞïœLs¿^3yW¢»Ê~þ€÷Q#Ðái àží€îÙ¡[]€~Ô쀾mkÚ[õЮRþ};—~¹e´ð7+jE|*µf?£­,ãžCþ,ý=ýUÌ~U³GL=ÚÙf´Š7^&,aY6µ×&˜ ¦˜1̧Úqz²kÐ¼×Æµ0Mü·= _ª2ÜÈH—i½Í{ö†–ÓmÌ#6=Ô ¦ciö¢.Ej@q}|QIt³IG UÅ0éò<œõC=)e÷åº$ç›m9ûµ•¦³Ài5NjÜ̹æC““Œ~øÃ|áïÿž?ú“?axx˜ßýÝßåÅk؇€þ¯ä¶õõ¯ó×^#’u¥~=x-ópÄoû´d´á*™*pëWpu+5´ó ÎŽøÍã*W†\}yö•Ž)ð¯Ñ±w=®Ïq¯P­é{<¯Ï_qõåMàªö˜ÂÊœÍVRboAª,'§Ç~Ò7=°ÙP³n]óYðŽ)h×|úÁk¨^Ø#`’Ýö¿ä-ñP?bø‡ªUüÂ<> ¥’Œ‘ÅuçxÉ ¯“µ£¥„¨¿ïµ¡5wNAŠ:Û½Ôù‹‡áØl]Kf¥g­Ê¸Ü™ñ¤/ºFÜ>xæÌÖE­ËŠñÊVœ» -”چرF²®ÊLøW¤_^ŒK™=–‡Í^X8gw‰X¨Ó ç‡sOH¡RÏyµÅÝÎ@+#Ár3!½üh ÆÁÕ#Њ‰(-½!—É‹°{HÜÚêk2÷»\‡ÍÌÍ‹¿|%.‰Q4/Æ4€×/N€U×^zU€,ÐëFÁ,uÅDô<õ©³LgQJÁUJ?GÇÑ鉚*|Ö³·áª@y5˜ûØ>’$ëX½|†å8¼½Ôî1Á¯àís„pž®·{£šÕµA­«‡nºÇÖºfÊÝ=tó-ع;aðî è†ÇÀÓnào” Ô‹jE Á!æÚëŒz7äéí-áï¯a ´±Mšƒv±«aE«ø%|õåwM3ÙŸfÖˆ0m ˜÷årÔW ê+ÐZjC¼IÏ&7š —·ð¦ªØËmZo@ë® ÷ ÚK6íÃmú߯V®ß0o­È5x¯ Õ1¸~zSrn3›2þ¹Rƒ ÎLÁ#AÙWÖd?¬ýòàU= «l7rHиž—nñÛàð0æûÞÇÿüû¿ÏÆÆ?ò#?ÂsÏ=ÇW¿úUNž<É?øÁ‡€þðöà[öoÿ–¿ºs‡H<~_©ëô²÷*X§]Ù¥OÙwÝU*rû XÎlmÍ¥â=®©ÃØ[Ú{ŸWðÓ=ó¨(ÎKgOº3§yXKYŽM¦Ãò5ø5#v;Ï]·`Úe ë¨âßÙ M±î\Ò –—pª%Ly¥Õ鱟탻*}ñu-Ù÷ÀK3àÉ+^V–¿k—”äæê"~[®IB‘·àüU|ZûékmhxÄ-n (ö¢aeÙ} òºr4¤%ö° ·ŽÂ¡>Èd!á2‹é2cSÊÕ)-Ù0S&+Š’=×'ìw° ÛØ9Àp NƒÃ{å3åc2š-Cm žº©LfIXörSèÉÌ‚Œ×ÕòëÙW¿ç¤,ž)%;Ì<µ [˜?ÇGȫ뒜Ümþ+pfpWZ‘’ØÚí}–\­¡²«åV¥w—Òõ,o¹JéMP[̲¼Ãæ¿ÀKü°Í<ÆÁù=2»¯Ûn†¾c©½ ÐÍpÿùN ÞmõÚÕ?7¬6þf½„¿^&¨€žŸfÄ_`7a†}[ôedÍ;Ѐh Z4íH +V“r{¢„q¶‡àM» 3k  ”²T jË&ÍÕ6ö’Mÿ‹ÐÅf ˜Ã«ÑZ‘õöоgÐ^‚úB›‘ÿ^ _ŒEôæª^-(ŽÀÓ7ÌUd¹¢×ZªW§àŸ$Æ+Ú¶‹Úwú€;z~–]EçlLkÌsÚ–u˜Ÿ~ï{Ù:xüÇÿH¡PàÅ_äsŸû–eý³aÁC@ÿ!¾µJ%þï÷¼‡Å?û36šMJzðLíc+[κ‚R¯ö¥K]½Â€²’^=¬—n·² WPD_ÿ´¾h—*þ}O÷Öµ¶²ug†wÝ•LÜÒÌ7Bg&½†€És¦|¦u»ãï3เ,^YovzŸ½¼+š°ÕÕ¶l]ËO ÁÁ s´$%û-ŒÀõ~h¦!¡³Êa`ïÜ™€jJʾ«ué¿7|ðò¼$9‰¬°öhU~ž‹ pfHV¥n¥E`2avnŒB ¥%á†<c°×'‚œdV÷®·`tîÓ~y\¬bïµaá\ŸcY@>T—ŸµØw®BOA‚UlKÄd±\º c0ϤDÈgOÂË7ÀX‘à—Êáé? /Ê£—r}¤/Üxúl)ÕgÒ3OæÄxæÉ' ¯µìEÊP˜‚G_ODþðÙ˜T9"m蟃Òò: íóGëàé‡w…zAúûq>pfÂzàxê5¹?äª è4…32éîqïÖ ¼åš¾pJéŽÎ#Ívw/gÒ£¬ImÃ%|êþ†+ü!/ÓÆâþ¬¹©åu¿ ¾ÝÓÕCw»Á9f.¦µ}{Ú}¯ö®’û÷[›ºÓ¨šÕ=¢&ïkÑÂß(¬ñ×K%µ¹éI» vÛa¦ƒþ==e‚}Ì›ö€AƒV¸‰©aÅ«xãŒ+}ô^4˜jÇÙc®1ë 3XÎR^2)ßõP_;d3ò.›¾6Á\3Z§¡¬Û^„öPAó˜,Qi¯€qO¾*!“®ZpâÙ¼h®J¢»^’ Øzü½p²N¶a3/L~µ%­®ª §ôo¼Ävûë2²ØÐ8“ëê—ï{ï{ùÔÚßøæ7i6›|ñ‹_äÙgŸýgó‡€þC|kd³üÝG>Âw?ûY6]€éU`ô*(»Ù÷¤Ú¢K`æ¹JìÎs8j‚­¥ô5­B x—_ÄR«¶€_¨b {د`®åÚ²·f`Ÿ)sÔÑj§\»ž‚FVzÕ¡†(Ì^Q¸÷ªàÎËHVÒ€³³pnªIa³+-ˆ{àÒA8å‡zT@yY?÷®1xz¿(òSº¿<^†ŒFwÁ9I2² M(Ú°ï \›kM>órC†geç{ ¨â7ýl˜[6ï€yz’^8y&,†…IÇ Ï8,WI>Q†Æ\¼*©ò ØÒ}è© ì¹ ³»DI\_“Ñ·˜)ìÿÒ5Æ¡¹&%ùÕ2”†aþÌA5&¥ütFÚ›@ï0ÜÚ­¬€yR—ØÄ5^5aŸN•Å)÷ÒÙ=u @M=gÔëÆ8ëÿgºÄ¤=š ”]çmWõ9vñŸù0[ »Dp†‚¹ À}žíV¯Ý ÝzÀîóî²ûNnp÷ÇÖºËõ]Ê÷™ÉxM ËÀk×ñ×ËøëE‚µÒ}@72gD˜mG˜°’ô z«øû¤ÜÞò4mìµ:f´Š'QÅ\ðÑót€‰V’¢ìõ†©§©† oø¨-´bmFži2xÑÆ“sýæ4•/ hÛ§`ê`Ä7ÌËQÙoòÁñG`Ÿ qY[F÷tš¥?(K™|r–—[r :•¾Ë7³t ƒª®jÎ>ýûw;¿ìÙÃäõëüÆê*_ùÚט™™á3Ÿù ßüæ7‰D"oŠÛ¯¼ò ===\¾|ùþ¶µªÛC§¸F0Ïç’çòh IDATù›}ˆïþño+ûx´üÝèñʰwét?§O9çbßËß§êê±W€ŽÑYFð¬IÇøÅÝÐïsrÚ“Ÿ–*,aýlhµà*2òµâžöˆÁLºÞQ+Ìß鑾ø®mX»,¸Ø cQeG´_^0àÙI˜oI¹xµ¦â;æzà™^¨lvJu‰6Ô-xçn´äµºÅ-gÁÑQ8ß…ˆnq³!bÀ£ 2ó\[UürKXþð<¹ê[Vq¥ xé,ŒØÒãÞÒ·l\> G-a,Ú+\mñ2G_‰ &²ÎÖ׫`î…G+% dÒié}& rn¯Ÿ–ä$§ aâiµ$õl^1$ Õ¤jwõ1*`§º„™N_¼ÎjSGÈT0¯»›ÎuÓ§×@Þ¥?q˜yhað§Ür¹–Û»™o·‰ÌN‹Xº{Ûsk{Wóû+Ü=]3ë®÷66¾FE\ƒzºoA¢Ž•¬à-×ñŸdW-ΔgÎ\g¢§nS_ôÐ\lÑZ ÉØÅDÛØQ›Æ*ÂÎï‰h²êQX¸#¿}W½ÖÐ=Î_‚ý>à;rÎC ©Z…[0„—vW­Ûrn6õï|^c³xÇñ0\ͬÆÀŠëlŒÌÎòÌýïÿ…_௾ö5†‡‡ùâ¿È™3gháúùÏþþ¶´K—.ý“úC†þCv‹ñ‹|åÎ2¬ÜAiVœ›I[ ˜½]ì-;N(˜»gÒGô9މFÞ%¤;MÇxfÓÕ—ß§¥t÷Lº»ôY¤3_^×÷=@Ç&ÓaX––½\ŒÝY¡zÄ„k–˜Á¬¶;sìù„‘Åë jÀ¸^釢-¥ßõ†|¶ ðÒL5`Km?—Þ÷;öÀxÒE1=YU“ócðÈ.ñ‰OäÔ´ ž^xåXYíIWĬ$Ü>GlñW_ÖÀ¦¦áÚ(ds ¾y)¼â7T“ûÖ¦$Å~xá2 oBsYúÞ‹-¨Ž‹#Ûá>éeG51ˆ—À3 Ï?" C!&eîX |ûaï˜kˆ’½—Ä 1×oÃpYûå[*JËáËpô€üY-³on@m ¦ÂÁ] æ«Rz¯†±c0ë—„¡‘Þ{ÊCGáÔQhªRCø± ÌÂS:~ô[I1Yu•8¯Óqj[í*¥¡³`(îº<úž¥’ ˜ƒšè–»ÔêN0÷ècu×5h*£oÿ•Gù/ºѾyÀt1tG çÙ¾ˆÅku™¼t±ôïÇÎXr‹úìü~‰½VÂ_/¨—ñ×: ÝCÕ÷]ãhõ»ÌÙëLš F¼=U|}uÌÞµMƒÆºMs½‰®â­Õ ¾§Ÿ¡þ µ$³í“ÄhDš”W,JK&•{<­sÿCm¡¶”ÕW yOz6µCpâßÈÙo/ÊXZ&­6¾ܼ.ñ‡e¹ÿ^K40‰6Œøá]Ã`¨Èõ\[cÓùò-WEs·V4³w›ezÿ~/¼ÀÇ>ùIÞÿþ÷3??Ï'‹R_{í5þÙñá! ÿÝÖ?ûY¾ö“?I²TºÏ¤A\ŠÝìÛYY×Àç2KïêAu?g—sÚüœÑ7gÄ,Âö9ö}Z‚w±ï)í\×s&”±§Ùî"çGVQúôâržÓoÀ¼!#$މHJ“‰Ç½šqeÇÛ{Ü/÷C¶! R†·o®IÊÒíIë@Û¯LÀDYúë˺Å-݆ˣ"ÊÊ”tµh¢mðáÕ}òZ¹´0ÆU`xžÜ }I1«YmÀbSûéÃ0m `&tŒ,Ü„Á87 »Z‹Šú~Õ–µ£¯œ¡M¨­‹‹Üb[(åÓWÀJ‹*>‘@ßjÃ¥‹0ÚõŒ$Ù¤øQï:—N€’RfzK~ÎÉ'`÷´˜Å”#’dD Pï…+·ÁS’¾lB=•…ú(ܺ fBIq³NÀ‰'ÀZ—„!›’ñ¶´ξ#&T£:«®›×ò\¾^¨Å¥-°™î8é9¾•I‡ÙîJèT“œ¤Õ½Øß%d«ºV@+MeWeÊ Ø¦~Ë0õú±ïq”?âý4ñ²Í<&àôÍ­í_î¹ó71ôÌwP¯›æ›·¯}?Qœ á ËÀÛªão ÔŠê%üµ’¨Ú«%,«AøùSŒN”9ÜxƒY#¸)ãj¾Þ:žÞ&õ‚8²5Ö[´# ¬H…Þ#·=Œ3L5ãŒ5“ØÉ•U¨¬˜T–L¨ìý©&^»M#Õ%h¬  7EÏaƒcÏB;,¥÷¦ê<ÞhCÌ ×NÁ!ìeØPñåR[ £¦ðlPÚf+-s'>j¬qvO8Ž•mW|ôkŒÊ¹=¯eqìömþvf†_û½ß£Z­òË¿üË|ô£¥X,R.K½rtt”@ ðÏŽKî?·z&CìÏÿœ¿þÈGH•JÛD<»Ì3] £G{©K‘ëÑÌ3 eì¼ ˜GèØ¸¦ºzìû5HÆ],? ½w¿«÷]ÓÏuTY~„í®[˜c ÚŽ"Ù§B:Í¢õb wLh¶`³ \6áPKæÎݦ“)™§ª2BµnËϳ¿n*Ð9KW"@Û„wÀ®\gÙº 9Cn§{…y& j ôàÎnh¥Å,&ÔÏ0>"îfˆ€òrS€9kÁ ûa¢ ‰MˆnÉîõ¸-,û‘¨nhF 6áÀI8€Á¨ô¿C5øž Þqxò ˜±N¿<ž—äã‘‹09 @žW³˜õ: „‹À¼'A1–ƒ%Æ.Ã9h¯I 3¶%ïoÀÕ§ÁSìx»g°Y…Ƥ”ìÍ5aæÅ¸l›ýQ‚µ,÷o¨S^ÿ98¿Zâ·™÷Í}põ1èoK?4–ç…t‰“Õª³¨¥èª9š‘pWðíÑ3]Õûk.Pê™Ë»Î¹ó˜G_»êºŸŽÔP¦‡¿âM|Góo·ÜŒd¼î¹ózw¯¼ËÎ|p›;¬Nu•ñM³·Q•²ºŠÞd4MØy ^"P-R:´ ãH©ì2“¾cfš]žMú<= ZUhF ©[Ç€ó'dO7K¢X_n*3‘…,–z»Çròù¢ qq›ðëkE…§0w ÎŒ é¯ÉÛwÝáÜ!™awÌb"9¹ïx*"nËÆ„åGKpöe˜ ÛX”gÔG~\v´³"ïËÊû Ÿ…ãW µ. C&©eö,L‚3ç…Ý—"¢ŠOjŽÓ±>LÇ}нÅϯÁ×1L*w•Ò‡ô{ ® ì€¹¡Á½¹ûnïÀÊ=z¿óýÉÓ|™gÙ6oî”Ø]ìÜïž;€3Ü}ðõì j³ºÚ½ ýûXÀî0²faãkˆQL°®Â·zIzMþß_•1µÅ_xœ]#EŽ¿Ã~k‰ O’_†Þ`‰V Šë•eh®·hEôͶ˜|EïF‰áÒ£Õ4vªJ9 å5¨-ËeÏˤJ-,`^[ƒú¢ü7]‡‘k°ç ØQI@kË"Nu66>w ØÐKè.­Œ/ÀÞl8× KälxÌÊ¥µmaUŸŠ&ËlŸ~pÎÓþ|„_üÊWøîw¿ËÑ£Gyÿûß߯unnŽŸþéŸþÇ‹‡€þ6¾•£Q¾üòˬ~ë[Û‚’3B㞇uÏ´¾ l›IÔà—ë*=ú´,îϸ]䦕ýÄ]}yxðLº¡÷÷¹‚o]ÙÓUý\ÎÎs§‡uˆí3éŽ*~xB?粋•ï0!kwì¹|0䣘°®P­ûƒðDÌ‹¯ëJÖ àêÌ·ç²–Ëmé»õúൠh4„ÉGÊ2+ž3à™=bn“OËc‹mÈ{á…#0[€jB‰E[’‰CÓðØ”EÇó²H¦„pjXîæ¦Ú˜7OÀIø»§´Œõµk’ÄTÓR1ˆe¥Ÿ>¾®ò†‚y\Þ'3·nÁpÚ÷„µ¯Ôak®½¾4´"²§<–‡dN=3£PN(+WzÒ†óÏÀî€ô2kRi¨Ÿiñµ—äg‰æe±Ë©÷€¿¨*âS’ÔpéU°ªÀ‹kª¦/I‚¶é*¥tU“6\€ê×óYÝAÈÐd°Ò” =‹èëØ]}q£ ÈÑï÷êýÎùƒã|–ÃÆÓsºßÜÞ;÷½ »ºÙîîq5ÓÚnã”àÿ1¢8ËÀk7Uø&ཡ;̼VÂ_+R¼8Eá¿ÛÏ|%Ä‘Ú÷Øç_fÌ—fПäI~ÝCqÙ¢ºÒÆ70·ìþ‘6ƒ»Z äò —2Øé*Åu±=®†À¨Á· Õˆ‚|H¾Jë°áÏC_Ÿ0òƪ´–êæ£²’ØŽÈ8åzMÆ,c@Ë€ú`º.£šËª³(h¢¶W“ä+Ö¸ãã¬÷ôƒ ì½pS¿ù›¼ô®w±´¼ÌÉ“'ùó?ÿsÆÇǩץ¹cÆýþùC@xÛ~k·Ùøæ7ùÆÏýË_ÿú›D<tæaë®Rú¸tF»õ±­.&í”åm=äÎûø•™(“w;hÍêke5È:¥ªQ ¾:sìN)ýŒ‚|¨‹åÐ ,Æv¹1DäVÓç8 4ƹœ¹cúànù„¹‡ÔÞ5‰ÄÀ§‡¡¿ù’Ìœ:sì—ú%ÉÈéjÕ¥¶ü¬}^xm j˜×Ì«¦x¥ð cvÄo%/ÜÞ 5UÝ6$óµáȤˆßJÌXQ˜t=¯oEXy*#=~k ®„‰¬l1‹—¤W÷ `ï È÷'ròzÑ2Lî…«Ç ž…¬ö¦“UqʺzF‹ÒËÞJˆ(/?7žÀ†ô«Sç`£ǯÁÞi™mÏ%„§6¡÷8%®wÍEYz‘(‚ÿq˜?fXz˜[IHÔ¡< '^*QyÍäòRÊ?ûXóÊdÒêXu¿&“Ž#›{ü2 ì»¦ÁºálŸ~Õô~7˜;%óö@¾ûûúZU×uV#Àòã¬pˆûªvÓVP†îw‰á¶Í{¶—ÛwÚ¦f=` ‹iíüïJñÝæ3Sº­º«´^êºÃЫ@7Ú¤>zž‘þóÕUÛo0߻ʨƒ §L.â%·ä¥¼bÐ µ0s æ^i2´Û&¨2PÈÒÞ¨Rˆ@9$€Nþ¸Œ•Vcàó|Rœy†t!R}E„“!»N‹Å²‘”eB« ù$2%øxæZ’л[p^DÉ>âª:dÇ ÷h,q{vx€™sçøÖñã|á+_ass“|à\½z•™™ü~?gΜy[AÇÃúÛ Ëm›¥ßú-þê#!Çö1‰-å»úå~ACØÝcŸÔ祻ûˆ+1H»žã,ht|ߨ¥€í¶<QÁ\Vû˜Ë÷ ªx ¯¦Aò”>ÏÙº–Ó×:£¯êêËOê¿—éXx. l6І¥¦”¸Ó@ۀ׆!XƒdIúìë@Ý€“xĆdYÀ|Èpeø¡X•òr¤.â·†)À¼Ï€´2ð oÀ»vÜ®\¼Û’ע0?‹‰L¼ ‹"-hà•£`ä¥üœÒ7ï<{z“ÂLB5X4 æÇO‚),7ªBºdgáêa¨¤„™o&d`æ œ?¤"¢Uaÿ÷ ˜xŽÉLx1ÖI ¬)8&ú¥‡J‰=Sc/œ¹,ýúæ²æÍ!~Y6ȱ͈ØÂe˜|Ž“êBAñ™dó°ç&Ì–^ IÐÞJ‰`pΘeP«IM=ƒî™ð žç¢Þßê*‹Óu¿Ã²LMܬÜÂ=ÛÞG75™õès³ÿ/ñª‚¹rzÃèì ÷uÛ»v©™]³çž®™ó·óÊì;1ô7?ß4Úøê—ð­ènV.¬]Tîùwìgd ÀL=ÊL+Ê´cÒ—`È“¥¼aÐ ÙØk-Œ0˜‘&G~²ÄÀ„mÑ»YÄÞ¨Rˆ!ì<$YÑÁÞ¼€y1*켺ªm›6Üx|P^îÜ¿¢ vÆGàñ )ÁgÓ"æ\V6½à… 6$,¹b¡­¾~Þlci»Ï«qÓ=ä÷ù¸ù+¿Â}ï{üÆïþ.^¯—O}êSœ ï±¢Ÿ¡†(ߟ·dV}MKÜ„,Ý_ bÕÎY¿^”2ðzM’Œ°þÞž–9ÖhE€)Ü” 0Õ/MCqST´K-yÎì.8×39QË/"`nàÕýÐ_“²·S²´áð8œœ¡Ù–Ë,Æ7¯_D|ß—t¼fpž9 ͨlp‹ ’‡¢ž|ú¬Ž`msS‚ßÁópnNfÕ›«’˜ÜmÉ—aw?´CbHÉKiÜ7 ݆ZR’‚l¶â5àÜ»a°)n]­yŸôü D½X‰Hß»< C'`zZ>oN™ùVÌa8õ£`o몮HbÊIk"Ì› ^j]B6\Œ¹Öu¿3ýÝîl‡±zÆÝ9‰A¹KüæÓDÓîªfÉkìæ×ù9\}sQ v³sûºæÎ½]B8ËUrÿǰóï è&V»E V–¾x½D°*€î¯•V;l]+¨•ðŒ´Éÿç L’Ì´¢ÌÛ«,2;¦•m’¾dë®—òªIcÍfh°Â±Ÿ¨c¦ |É:­tl ÚF¿ü->b¢™¨„D’ðÉèÙ JQ©¥3*~¦Ä–¹ïx<„4æÍ[ð¼Ò5Ÿ®¸â“,Þñj¬q/Wñj¿¼éÒ Ýï—{<ìþøÇù³µ5^ýu{ì1>üáóÎw¾ómýmrË¿ñ‹Ÿý,ók¿F¾V»H,s“޹…ÛôbÄÅØ[]eù&Yq'#Ð$`“7+ÜÇøÝË(z´$åÕ Âaì^ÄÆÕR M»ž³[ر„u{/2÷Yu±o‡ýœÑÏq±|pSËùî™ôºöÞo˜òý!»3û¾Ç§½lH©.¤?O¿ÞÕ FIŒ]î9‰OöüWÀ?R“ °»žƒÒ–€öŠnw;1.jùvBÀI…7øá{!PE|DKöIàú<î‡Â¦Œ™­T!íƒáaxf¼ñ*wÆk¦öÀcû •êØÁÆK×…,ý†ÌjgãbȲւ£gàÌZâ UaÍGnŠó]s]TïÑœ€UÏ œ=ÍMy-gö;ã…óÏÃ.SÌ=«°Y„ÒAXxyh/C),IAc޼f jQU×Ç¡\ß |Z~W̪Ö%ÉYV'¿†+È*Xïľ-ý^Û|£ÕnöíÑóÖâÍ#iƒúx©ëzêu‰Ió®Ïåˆï>ÈÿJ‘ÞN á1¤ÌÞ è>·;œõ#™¼ÛÍ.7wø¯§«Ünš;.f1LO«±­”î×û6vîfèÕ"þÞ:öÏì!¸ÛÃd%Á,æÍUöõ.lgÙXö³yÏOaÑC5Ôf`°Î…ä±c^Œp›fºA&&¢ÌbXÎá…AÐT]FXØy1*:´nžƒ‘€ÜWŠé®r= ýpkÔÒÒbrœ+ÀAnX²¾wµÝ™rh)™9¬ÿw }‡4Ö´Ì^sU4‡††ùÉŸäÿýÛd³Y.^¼È;w8yò$§OŸf÷îÝo[yXr;€ù½{üÏ?O|yy[ óêák»˜´ÌÃÊX2lW¸÷kPq1vÇÖ­vX¾S–ßµcDœçŠl_¡êQ@5õþŒë9ÓÈ gD³äJ>ι„ti:ªÓ“ú3­¸žã®èÏé¸ÈeèØÑ^2Dù¾Òœ Ày/lV¤Œ»¢¿ƒA ^ @£(}tç}ü&<„9VKâ±åw0„Ç!¿!b­U 0GGàF@„^áªr&X>xe¼eQÝFJÒËÛ2ᬘ¿l%`Óñ#÷ÀãGá !Šñ¸îOúat••«ñ¬Œ‘%«PöÃ3ç¡§©eì„Tª£ðè)˜kŠ‹V^wA·Á…£ò÷­/uÌbÒ ¸ô<ŒôªYŒîCßÊ@6矀‘º”Øk«bíÚ÷’,daQ¶WÒ/¯ÏÁáÀŒC9¬IF 9ØÿnžÐQ¤%é™â°Ré”K[®@äÓ3æfÓnöÝ=^æÓÇ]ßï×óVc»»›_Wô\¸ÝI×õ”ïjMbñnQ¤¯ó‰ :Àí”ØÝ=sßFÖ<`çVךÔnÞýo§g¾ƒ±Œax›µû }ß“Ýù·ŠÞ‚µí}ó@­€ïJ/¾}M†2L7b²æÔ£¿¼E!nS^²©­6i†lzÛMξ»„'Ò¦µÒ¢·ÙJÉy*DœÇHE¬¼%ç"¿&• D ’<}\b\nMªMNÕj˜ï…ë}²•0\Ցö×%dò"³¶Æ ƒcÂ]­Æa%Y:N–˜Ÿ~÷»©_¸ÀOý§ÿ$"Û^àw~çwÈd2¬®®JBhšúÃÛ[€ùâ"vû6ÑÅÅ7I êáu÷ËMÍ.M_÷s†4åØ>ëW­²Ý¾ÐÔÃßßž×Ú«?é ~ÎŒy[ËåY}ŽOËõC.Àvzìô1ä÷Öò{^KìnùGõçwzéŽRõ%ýÝ„èÌ6÷‹aÙ!»³BõrŽ´Á®IIÜyŸ)/¼Ú…¦”ß×Äy’Š7vÁ^Jyaìø€ç{eåb¨Ñ¡¹2—û`KÇÑ¢eñáô$ì J0KæDü^:ó Y -Â@ÊÏ_…±Š¼G¼ NmÑ*8 žðù´”Ì·tõjiž½½`ß¾dCm/<ú¤ì/¯Etî½ #A×VQÙ²Qñ’> g®ŠéLk ªa•aô5˜=$MÈֲ̾NJ°ð¥|)ª½÷8æaô ôHÙ¿±,cG™ qß»Ggdò­X¶©‰h³«'n)›64ùs»» écÙ.fÞ«×M…íªx“ζ@ÇIÑ1_ZÐÄà˜äcüO®OjH6ØcuÄpk»w»Ð}Ú/÷t ávôkßaTmÇÿºúéf§¿_^ë°î k-PuõÐu4Í-ëûÌ<}í:#… ³v„ÝV˜)O”ÚF­uƒÌ’âŠEe=VgþtBÒzɤÕ8,IåØ~8J:Ý‹C."Ú”´/‡KL™r)ñxpJés©œåó®IÿÛà=ˆ1U”ŽïºÓ‚×ø” Sµs*0£ªèNÚ<À±Û·ùÚ‘#|æþ€ þâ/þ‚7nüÐáÉC@ÿS¿µ¹÷{¿Ç7þí¿%oÞô(˜ºØ·ÓßkÑQ¸;nÄUJïfìãt fÜZSú~]B‘) Œ]ÏÓ Àv¹€ŠÜštüØòÖQ}^ŒÎ–¬¶‚ù%}u[ۃ̉:{Ò%}/ðŒ~Þcoç|pÌÔQc¿Ý -±„]jw”ô»=ðŽ^Yì® øÆ‘ØøÂô7D¬Ö12Þ1ýYq~[Ô^] ¸5-{×7 °^– jËØÍk P.ˆ`.VjBÿœ…… ”â"~» ‚ðÂ­Š­j´(•p NÓ³ò¹¸êZÃðòðÅ¥œØ’ײæá‰ë`¬‹8žƒõôÌÁþ£0ì•€›ÓÑ´X¦/ÃÉã¢Vo-ÉãùØ÷!0×åQ[‡ø&4÷ÃÈyé‡FDmj£PkBߘ½.,¾¹,3Ä•TõoPq¶OÏêN s¯~o£«>¤ ¦{”Ó§ÛÒ³TîJ€@îV1j¢™Ò¯²KzBÏó·ÙÅoð!bÌvÝkJ ÙtgöÜïébí.÷msç0‘yøÍ´¶Ï›ïÔC7e¾Ü_/K/¼êš+¯n/«;€tz«ÄØÿØGï1?ýEÆ*iva&(­\…lrë¹e‹rÈäèãMv/ˆ¢£ Œ&ˆ›IØ}΃RÒ)q ÜJK"\öÂ}¢ÙJ‰>dMìxMØ€3>¹¦ÖZAÙ* IDATj’uÄÕ‚sJé­²Lí@(¼· ½¿ì:k#³³xþy>µ¾ÎŸ~éKŒŽŽrçÎû.oû÷ïgppðMáûµ×^£¯¯ïaÉýá šå2ßúÅ_äoý×)óæUŒ~WIÐÍ0¨ÜŒÝ£©û°š šý.Æî^¡:«ßëfì^½ßOgVÜyçbɰ}j@/°Á6‘8ǫݹÀMCÉW~ ú*Ðúž€p&-ýò}ïsYúå帬/õœ‡ù'ÀL‹9“ ^©ÃqmÝ“¤ ¹,eøuæ%\¢¤€èš‹-;É逋}»¯a}N± Ìw¯²Kÿá\óúš)×yöëkÍÒ™Øp*Pû\"ÓðUÎlóûûÍ­íàí3]_ÝåvóÍ`¾ÓFµ·M{“Ýëö’»ÇnvúâÕ¢ÞÞèbçêØºJù]@}`®Æä9?þXÁ\žÉz‚ #]¬’‹ËôCq­MeÕÆS´™·á®(ÖÓè[ ÈlÂî}pjNª6ÉMØL‰ 4Ú„ŠÏOKÛ(•aäZKΆ׀çz¡§-çvÕîøOTOã“®Ïý;Nu𸞙Û­}ú÷lòfëß‘©)ö~üã¼þÕ¯ò§_ú.\àŸøÏ<óÌýX½´´D.—{S ;Ìœ?dèoƒ›ÝlòŸÿy¾õÉOncÒ¦24Õ»Ä:z°Ý w¯²ß&Û-,M½¿ÇÅØ[.Æ>©¯³ÙÅò÷º÷–ªq}½M:¦ †Ñ1}­„«2ЧŒ½¦AÑaù&2B2Dg‰‹SÑÇR®Ì»©½°ØCúze`Ѐ¼PiI@XÓ÷1 ¸âÃmYưB‡±?å‡6my,¬ýrË€g‡ ¿)½½e[~¯C_^Öš:%ûþ \•}¸ ኰù0ÒÏÍ@£ kJÃuI&¦Æà¹Y0bÂTmY,±g/€‘ª”ä£%ÀV/œÚ{ú:ì&•“÷¿pIžc/‹"xµË\Æmh……å‡óÂòwí‡+W:KO²jòRìƒË¯BoN–¨4Vd½lï»ah|›b“Kˆé àÀ‹²¾²S>)Ö®C§ hCkQÊòeQ9‡jÚNp 0ôŒºJïŽÂ½ê:Ï0;çÙ½¾Òp%݆ #š€Úl_d!Ööž%Ç0Éaگ߾É)þ˜Ÿ ‰_ÞÍ0;¥ö Õaè>× º×ôžúçnœµ#·ÜÖΠnˆûý~x­D Z>yUEp÷EqEU¹—:€^-l”˜ÿE‹ÁC^z’ev3LÙq<å[É6Ùäס’qË+w ¿ª>YHl+Ïä`b?…-9Ï© ±eÚÒÎz÷”üÊRyñ2Ùò70€wÁ²!V—8AÇJú)ý»®³}U®åªÆ]U;gÄq¬KOt_Ùׇïg~†Ÿûõ_§X,Ò××ǽ{÷èííÅ0Œ·%û~ÈÐßf·Ä_ÿ5ÿð_þ ÿÏg?»mTÆ£ ×Ôƒêî—÷kvºÅöñš^e%¶o]s‚ŸE‡íÔCÊvüôŒÝ¯¬Ù¢ãÇî¼Ï\WyËI&é¸ÈÅè…ʾ ÛéËû•Í+;"[_甫¼æbF xÚ‚¬ú¤;Œ}Æ‚—½­‹çù¢þ<ïòÉg[mJnËïúx<Ú'¾ë+5Ú%“ƒpÆ#û½—k~ùP@ŒgšeX®Š’<Ò„-^ž…q¿°ò´nq‹{Fàθô‘SêE½ œZ€kc´kÒE«ÐꓪFÒßXE,i¿ ,h~GÄEKMàÆÓ0^€ZLX~¸ >éóçáè>#eµÌžÞ„âÜ|zR¨këR˜ü)ì“RH+$zÓ{FVÔ¶VEœ‹ÁVÆŸ…‰G´Tïb曚´8½OÇ•pFÿiWËÆ¥Ðóâ^mÚ£ [ ³XÃyÎaMj®þªÓr*@î±È9}ÿ*Û— ×ô /ßï¥{ù)˜ë$»×ìê™›k×çÐÝcjÖB¸®þ¹á6ˆ±Þ è]}sãÿeïÍ£$KÏòÎß½7"cË}ÏÚ÷­»«»zWwWoÕû®Vw‹CcIV3`$ Ö1F`yƒññÈ6XcŒÁXãFËša°16ݵç¾DfFfìû½óÇû~y¿¸YÝ:^Žgœ“§ª"ófDfÝï{¾ç}Ÿ÷y\‡žF]yq‹§êVÉ]A=±Õ'/ZýsU;ùF™‰[“¸×}úÖ‹ŒVWé©çYÏl,Kß»8^î{ z×D—±\”êÔJ²e8²GZPù99˜f5¯`1탃à5Äx±&÷sA÷·çcÐhÊZ2i‰¦šr¿Þ+s‘=;7lBáèÞ8¨÷…]Íñ€ÛÿÂ_`ñÐ!>ú©OðÆoð¹Ï}ŽO~ò“Ôëuâñ8ŸÒÏíöÐw] ÿæßð[ï?ù|Ç|yBŏnV¶PÃtnŠtΤ÷ë5åcO*h7èœái1é±›T¿~Ãz¤‚lƒÎÈI—0Vp…ÎqÝH×u™¾ü°2©˜‚¼aì)dŒ-Æö„[õõMˆ‹Ù° ._Ãò÷»ð´:ÂbX~xÖƒWvÆçΦàÎ$¬—Eg6˜‡GàfJ›Rz¿¤¿ƒá„„¸TªÒÛžÕà—¦Oì…)OúÛË%¿UðÌ ©@kI|Ú¯¨'ý‡„åWr²ÁÍ©ÊÞÉÀnƒvYXùÚª¼N0'÷Á阹¬å$Bµ}Μ„}¾Ìö›r<ø,$[꡾ æ8ú8L C<+lº8ËqØû:Œ J¹¾®³À¹8ûˆÑææe$©•€Þ[`â6™m÷/éÁ`FÆìÞB1c`1æ¨OvœÐühÍ:hzz_Nê}i÷D 3 –¬ƒfR«<&ö×:©¨E†‚~¯}zp,Î*×ëœäø!:"QÓÊÎÓžôÐm`OvôØ ÝôÐmG77bçjÿÛí,Á»$U’Õ’è*‚³{ã[€Þ¥o^+1ê"7l1öf„±ws‘3ImëÖFêX=ö²n²6cŸÔÏ›…×Ò÷uPßób¤'9©LjC9oõ½îÔ¿_',¯%tãÝGh߸¡ï÷~e竾€Å².ð}<ê@¶%€iÞ[?𨠙ÞiÉ`U¿×é„8Ì-E3 Ô±„½Ù‡µ‚€ò5 ïÂDžïƒBIi³M)#ÆbðÈ8ŒÂTªRF,ÇàÕc0\³,ÑêƒçÁÁ¶¨{çË;šõáÖãppy­nÈA#³»âË’,•ÍË÷ê¿î¹œyí9-ÙWzàá'd„nCËì¹%ÈÖáÐph24ž),Cã}pðœŒ÷oK?[‚ÄCpô¤ZÔ…akA?ü(Ä˼#Žtþ%±q³ZuK—1b‰Ï 0›¿ªnÊE ÌëÿŸiÙ˜ï5ª×¬Ñ©b6ù¦”n<zµÄî*(_W+F‡õþ›³£À^~ïÒ¯’²6=NÒ#°c:þìfõ;ï‹ên¾uûÓ±’ÒŸd½"à¼襰nÊ솕׊!Cúñ6ñ¡9ß$“-“*äÙÌ·Åw_çÉ «¢ÿ87 ÍKÒÆ™­CÏ6à@?œO@qUî×¹²XoèÿÙ³ž”Ò¯•Å–ÙD÷¨¶¦ç¬jJFµU:£r%'Ä9åu °‡õ-Ù'&8øä“üÕ·Þâáã•W^app¥¥%†‡‡ÜôÝÇ AÀÿóÃ?ÌŸüãÌæúz‡Q†órD”Ô›9j®a@Þ0iS2ï³N¤QÆÞ´6Es00>ÙÙ˵N¾Ö5)e9fÙ}Ìcúž—u#mZ¥Ïã„9éfó=¨›|]7Ò5½¦W…/M˜LÃØï×réu+=© <äÈ÷ZQð5=öÓÀ³Ž8´ýæëÉzI[¢‹eaìóú^îOÃ턞تø—‡áH }ä«uõŠ` žŸ„Í,­Ê\úu ƒWÂ`N|ßgšÂòý ¼|Bzò«›Ú{¯Š0ïá3pr6ÖÌ—uÄ-=OžgFRÉæKò½†NŠí«¯il EÓí¹E¢Je!Z%ñlÎ< §öBû›Òã^_‡ú98ñ¼ ZpQÊé ›Ðû8LÝÁ¬„cÕýmð1º â9ñಔÛ˳p¥ö˜€Ûuóžl¾'­»=ý0¦÷†ÑR¸V5gŽN'Ããˆ*}šÎé‡>ÂÌk“ÈWU@8«¯)"°z0¿èŸ§èY¥vÇ®$½H™ÝÝžyÞ5ïܲzµCX:”ì‘Ð7ÂÖÝÐù-U- hWÌme{´MÉ=U/Y¥øGïÝà®ä©üY†Ôl•d®D.ß&».­–yØÌÁÞ xpBÚ)óu¸®eóÕ¶¢œ ¿¦âÓ:,´Cc¨¸\'GˆS0¯:FÖ­ýá¨Õ2)Ðie=!FüfôD6“Øsâþê¯òÚÇ>Æþѱwï^¾üå/S¯×ùâ¿Àùóç¹ûî»ÿ9»%÷ÿJúÆ¿ým߯å¯|¥ÃÃS0wÙ>CÛ«7f7;ÊA½I£=ö!=™F]äúgÒ‹‘JÕz¤T5©×­ué±Òïe—>ÁL  ËfùcȈ‰)}š×9f-VÓ—oëæz¿þ|Q›Æó–nZž$¨%­ kÚ*±ÞŠÌ©N[,?”ÝŸKCKgÏ cí3q8Ö–2á%½¦éÀ‹ƒ°¯-³³ÓM鿯'ú$sy½$Nm³ y‡FàÎ>*jY\ ± |ÛˆoŠðîzU²ÚWx씈ß6ÖE̶X­É=b0ãÏ„yèÙ!˜8wNI$iVcJçËpö<Ý •¬‚¹Ž¸µ&áá—%óÜ¿ëbVãÞ 'ŸGû囫†äY˜ºI|³KZb/­ÁÔ‡að€åüKrh_“~ù¥¶ŒÌåô wLÙïZd02¡›²aì -£µDiFñ§˜"MXÃ!ü'næÇtˆÙK€K°Á"Ïy8¸ø[Žî.ßÍ—‰‘WÛO‡‡“1‡™àŸo¿O¾Þsp2d\Èx)Ä%õÏ­>ú€Í;÷ºôÎm†¾MÁ®ìÜu‰·šâµ©jQz9ôzI„pf4­aä–`®×)ñÐæ h^Œã®4Éå[,åBÅúZ^ÚI/ìƒ=R•ºâKkhÝ—øÓz · —\Y+A}|A×üuk šªÝQë@oG<ÒÏ/±}šfJÿW#$d§¨\ØÓMüéð¿ÿÒ/Q«ÕøÌg>Ãw}×w‘H$þ\âÎ. ÿWxÔr9þÕoðö¯ÿz“¶í(í~¹« ®`‚ìUp‹ºÈ è×"ר*â¨ïû¨.’H©ÊôØs„q¨Fy?Aè¬Tô1ët:Ï™p#|Z³NËGtÓ^¦ÓEnPËŸºðÍ5C £V¹´¤¯ñ¨þüW îMe^wè÷¿j‰e2<›”·¹¦¨h7±8¼Ø c¹ª¯ƒOeàP ãmÓ-)±ç×·¤ü¾TÒÌÛ§àî Ô³¢â½¤ýòD>xby·Õ¤lï¦á–I8Þ'ã>k9W[íG̗ofeÄ-ÛO<ýy±X]لْ8¶¼ÎW­ñcÏn‚»î{âKÒ/¯ÍIFúć ãAlQ^cmJ#pè£/É|yiQJìñ#0ü˜´ƒ‹ÊÊ/CëŠøÕ_Rñ[žPE>B8•`Ú,{õÞ¨Xì»®÷ømôeœEàŒóUîRpvÈ2N“8¡o‘¿»Ö¿£Ÿïöa’ÏíçŒiL9¼ÖqpR.dœŒKñÒ^Ø;Ovaê1«nÏšïè£i]»ëâ8.±VƒtµDR™yªª ^Õ5ÓC7 }«än{ÈÌ“µ2÷~Gž£·6ð/º´f6 mæT•ž[“ƒjÛ§†a¼ «E¸èJ5©ÈúIGö”ëÚb1Ì8‰$º–6ÆTSéÇ:Ûßöè}Ý7L®¢ëÜÍíµôDöÔP2æà­·òÖ¹sü­ô‚€O~ò“¬®®nEž^¸p—_~yÐw;—Ø/á üñÏÿ<×¾öµŽ~yÌ¿Õ#ýò4Ý]¯2º8*t:Âõ(˜µ#ýr#1Œ½Ò…±ÙîSmÆ{Ö",Ÿ^—¥Sy<„(† “§€jDIV}Jå‚u ˆüa=©Û½²Ieìʲ céÉß0óÝÊÊÇüM_¾ œuáhêí0'}‰X§] GÜVƒI¸Ó…‘¶é®¶E©Ûpà±~˜LÁfIFÙ®*ÈŸ…¤_¾ þî ܹÎÄ$e®*nXó-è€gC³&ŒhmCÊ•K.¼tL4ÄEnm]Ôâ¹^xòaÎëLxAÆÛ–[pê,œ=¢ö­ZbÏ–¡5<$¹ç­+Ð+q8òqèmË/¶1+ãEÅA8ú!HTDÁ\Ôþ©»ö¼¬€9ÌkÓ"Œz‡0)mŸ#­Žd ?gÁãýz/­büõ]jÄx›Sd9‚K†ËIëî'Ö6H;‘Ï9°vvtïÿŽéŠin»Óãàôº¶z:F°èngæ¹ èñÛ€îvcçQ@—;ŽC¼Y'U)‘®¸Ì C—²z—’{­ÐZ~Ÿœ,sï·5HmWÖ7é{oÈD®µ^KÉžU1ç‚þºÀÓºÏÌèzÛ°€ùB“©,¶ÐGt-ÛV­Fg‘Ö5k—ÒÓºw”é´¿6žüFOdW4“±¿û»ù|ž_ù•_áŽ;îàGôGyå•WþÜCÐ. ÿ|\üÕ_å7_:ÁÆõªé}Çõ„Ùd{€D/a€„;Sº1Vº0öQý·=si”ì½ñ£Œ}JŸ³áÌL®Çö¹_£XÏFzU]¬µcÏX}Ô¹ÈëܦïyžÎXÃq=á/ëfaf˜Ojù}ŽÐò±¬¿«çõÚ«z{y(Ç\qƒ»n)ÜïJŠ)L¹& lÒÝÇáÕ¬šçó¸ ’?—‹R.Ÿ d“¹gîMB!Ù,ÏÖXÙM¸®¬|± CðÊqÉ__‡åMaùù8¼p+LT„I/—Ä¥ÔÏÝ C›"b›+‹øÌ‚LJ  v°ë‹b ³Ú„;_†ñ)‰·®‰¹ÇJ?œþˆäÃWe–|©cß {!˜A\aA‚URç`ê)4—̃wÔ½ßÔJ܇Ó>,¶Bfn„lƦc˜Æå·xYFùØÑ“Q°îöœÓÄ龋…;x{0÷¬¿£+ÇÝ*µ»¶ÝÓ’{@»á ú6U{”GâPm%»Ó ðŽã¨UHUK$+EÒÕ¢üÝ.¹×¨µ”¾U’WFž¨u2ôx½Ìo´H×Ä4(·&ÿ—óE¹ó-Ù¦ð£Å@îs#@5B6[duŒ¬ެ¶,r`JékV)=E˜z¶Ù 3ó]ôDXÕI¬ýñðÿ0ßÿ…/033ÀåË—9vìØÿ´ èÿ…ú¹Ïñ»ß÷}T*•Ž ˆ”Þüu:£ãú¹nŒ½Wÿ]% 0Œ=¥ ÈVÅ'ôo²ÝEÎ$µEUñý„ImÑñ˜~廓Ü^}ýläš}„öIZ{E¸}Š¿IßÂu)ýߤ Áºæ”–•}›¾|’“®„sk$ÉpaŸ+"iÝ”žHÁ_¬bMJSaÒOz°Ö ÙiužKzðü $|5~Qß÷dN¤E-_ؔҼQÅ?67¢ŸQWºeö ÂÓ X –%q;~n‡ž5?›«ÂuNÝG{!±&)m3Êô½axü!ð ÂÈ7W`uÖ\¸ý1Ø›’{cZÆÏR/ÃèQH¬K=¿$ åÑÀÈañc¯,ÈXZµSß ™!$}æ’ôÍÛ—d&þ²&Â-#Äôñô7Eüg~guàœ#ÿ—ßFùC†ù5îc™!6·2m Ž–Óéò\7@ïÞN—ÒúN€n®+†õ$×ÅM‚Ók]>‚LŒ å$c¡åk7@ésQfÞ-þÔ‰*ÙõõDµLº"eöTÅî›+€W°UÉnËØ#kæy¯YáôímŽ€Ø5Ñe\ôa¦ +e(¶ÃêØ­ºÆìyý„®ç¸%f5k}ØjÁ-Ò9æºG׺±’nY½ï}V)ÝÖóŒèá¡)¥'3.¢z¢ã.pøG~„÷ô£Ì/,pîÜ9¾øÅ/òÿá?dcc€ŸýٟݲuÝôÝÇö~ùú:¿ý¡1ý{¿G¹TÚbß®Þ|®Þ¨6cOèG5ÂØ{´[ö}#ÆžÑ*Žp=º(|™tÛÖfìæš~T›±0?@èû^°û”ì¾—©JÜDhú`Ô÷Ã*ˆq G… “»Gót*é!*æÂ8TÇú˜þ® +,ë÷8åH"ÓLªk.$`_ }tãû^Nyð˜ë-¸èÈ5ˆžé¥ˆµÅ$c¦%V¦Þ?±‚Œ¸™· .ó巺°¯µä°éÂ#`2 •’Z¸Väwpd<¸ÚËPZRƒNÞ wCkNý®«â?ï ÂÃwKl.+ªøõ y_÷< 3мµÈV ñyŸœxÚׅůÇaèQ˜8!±ª¥}Kœƒ¾;EïÅedD@#TWrðŽ/ˆ àtF",½†8â]ÓI‚¤Oö@¹ÙÏÿáßÍoq††»°ov(ŸïôüN€Þ­G}.)³Ç¬¿x€“pp3€yF]ûçA:&£k¶ÚÝŽIõ¬¼ó¿öX—ô4«Äî„Ï{O¢V!].ªIV´g^-jß\ÅmÜ­2{""„KÕd½Ý¬Qïñyía9¼µfEàv±-ãŒe_Öú25`¦¢ ‹1B#Ÿ¦þÆF˜7èK4ê1]çE:GcËd4—Â}£$$¡øz¤Òèâ¿ù{¿ÇÊÊ Ÿþô§yá…þ»Ž:ÝôÿΕ•Þ|úiþÓÚbÒ†'ô†³{;f\͵ÊïXlzìµÈÍjúå•ËïÕ…QˆôØMLdÔ÷ÝÓEÓÅg‡ ÌØýò¸ö¸ë ¤æcV3D˜ºf®9¨¯o/ð@«·ê{²Oþ éjŽ‚ü¢õ{;€d¥ÏÎ$·UøfF•¦­¾ü„ŠuŠÀØñ‰ÏÄaÔaϽÆqà¾ÜÔÑÛ- €³q8™‘_úBUFÜV€þxibEaØWõu†{áÕqùÁª2Æ5Û†MGgÒ=W[Ù”—yÄ]ë‰}âÔ¶©id;o»†¡5#ª÷™ÌÖàÁÇ`_/”V¥Œ¾žñ[ò88,U”öu¨Ìˆ‹ÝÀ8q·‚òŒ°õêa8üañco΋Owa’wÂÔkÚ·¸,×ðMÍ͕ۯN nªÉJA,Óúÿ™vÁ‹Ÿábs¿ìßNd wv`èÑwtÏúïB8o‡˜®¨üÖµNÌÅÉ€›¡Ѓ´§ =è=Ý}'8ÏÛ>žæX=sÇÃk·…YWŠ è ÚÕ"©JqKðfJïf,-U+nY½ ˆ—·Jï•VªðÌ1YÏí?û3W4†TØþöŒñ™0ú¢u 7¢Ù\¤Õ×Ã>“÷­½¦ŸÐú×.¥éßó‘RzZIB5²×Å€<ÀoíÛÇ?úüç8}ú4Ï>û,žçñéOzÐwïþ(LOóæ‹/²ø'ÒùWpnFØ·§7$]{Êê±7"Œ½WŸ«D@Þ0ö¡òÜùJÆnæ4íœtOOØ)Ýí“ï°^“RL߫闃x¯÷jÉÜî±*géœ-íÑ{`•ñŒ!ÈCú~§#e¼»T`7G¨®miïý)ýþ3„3é\aì}8»…uÊ÷Ç$(âJÐéVwRRÔ–Œ#\ ›Öp^¿( }I“iu‘Û”^ù5õŠoÆà…0芫–ÀFŽÂýPÓøÒ+4Fáø$œMŠWölY€y5€i1úXW@_,Ãà)xàé—7¯K)umN½ñ5p®Ë ûR^’ÒŽ¿.?hmAæË7ç¡ÿ˜xœ+Ò+7€^š«MyjHÆá… 1•YÊ‹.ÁTS²ñ[øà«,oæžGSšUBß÷*pÒû=XowZK&< ¹ªÞêÆ]임̥/7¤4?ˆ‹ÜƒÃ°'€fY޹æ@J\äšQÄ_kâý)¸oT˜ùò¦æ›·¡ž„WodQ"T— æî(<}R+PÔ¼óë5Xsà¾ÛáЀôË×WEL7_…‘pß-úÒP³˜Â8œù ØÐ•ò¢üîÛûáðÓàmˆYLaê>L¼!¶œî¬‚ù;a(ËEó¬wOÀa׻⛙ñþ#·òuÐy#'Ö;1vw‡2»Cw{Ðc]ÀÜ×ÿAyÞé·/=ã) {[ ÝOűÎþ¹ªæEl^ݘG]á´Ôo5I–J[eöT¥HZÿÜbè6+7,½uŠ@wUr~‹u]/÷g`Ó×±IBÿ‡¸îñȾaö‡^]«å.ÕA3SéRoD€Ù³€¹9˜ÑÜŠµ™½ÎäÞ—"ûãÐÈñoÿvþòç?Ïêê*¯½öŸýìgÿ\¸½íú£GÐnóþößæ«?ò#%vs#;˜ÛŒ=¡‹Áfß®W7Æž&4˜±¯‰ë¢hDzì^dQÚ‹¥W?WŽôË­9y» Že»ïÕO-™³®1ñ•.á8йæŒ~Þ̘ŸgŸöäÌLº dI w£Š7Á/Cˆµ§æ†l9Ï9ÊðMÙÏ0ö&pÄóްÛkAÈØãÀË8AhJ³ª?ßûâbó:Û·y}/ ÁIVó2“>”Ò…ãM¨UàJ[”ñ+퇧& WV>_–ꀟ€—OA¦(Lz¾*óêÞ¼p ô®J{¶*L?³N÷”[‡µ™WϹpê~8”¤,¾”ƒ ¸í5HçÁ¿&ê÷¥*ø^èÍ€?/¢»ü<ÔØ÷}hZ%öwÄlm]ÌbÞb½pç8ðå@±X õ=.ÿ”oãëïÈßG?·Óhš]fŠßº)Ùã†alŒ‹ãIßÜí1œ1“1³çAÊz<ô-0·@ýF#j6ˆ[B¸x³Aª\"]*Úôieê[ŒÜôj1ŒHµ½Üëe¨WX ü-#—ûpc°Ò¡i-"V+æ5Ø ÛͱÒÕç=‹P˜ý)¥µ.mÃ> ˜»Ù_W#íIs˜Ø¦'rÎ~ðƒ”oº‰ïý»—l6ËsÏ=lj'¨ÕÄŠê®»îâ#ùÈ. ï>nüø¿â'øú§>ÕØ®Õ/oD@>®uëtinÖ¤ÞØõȧu”#ר‹¥¹ñôk£§èÂû“ÔV‰ôØ‹\Àö™ô :“ÚÌ5}ˆÈm3Ò/÷‘-”-ÆîèFrTöŠuÂ?¬ƒ²2s£¤FFe ØKV›á ý½L[×øÊþQQÜ´uÍ=Žˆïf••Æ>ìÀK1¨¹êç‡sìO ÀU¬_ñåu.¼:û4„âŠ/‡†5àæ¸0,¢¸å¢¨égèIÂKG ©cf3:âÖ3<%^íkp¥!Êø¡½ðäíPYæ½¾ËOÁ#OÀ@UTìµ9X,Aâa8|’kÒG_]—ÿ“Co@Z á|yâ.~z*l ߸$–°sš_~5€T/¼|‚u±˜½ÞU¸s¾Ø|‚Ÿ+ÝÿJê7bè;z7@‚¸Ó…;;”ØcÖßÍWÖMûx½ èé£/ô´°s?—±µžX‘såß±ˆ²Ýíf ãm±rÇu‰×k¤KE)µ—ŠC/‘ª  ‹ø­¨f2€×¬YóªôÍ›­‹A@EÒ#º>Vôÿl, ·:°¯)Ï+„–¸fôlTC«ÆlE3ÒÎ3ÀlcÙÚ ŒUiŒ }H¥ÑTÓ]@ÞN¼ü2×î½—ŸüÉŸ$“ÉðÆoð7ÿæßܧ]@ïµo~“ñüólÎÏÓl†·ž§7q:»«7²CçHš¹Á{ô·oü˜. ‡¡Ô¯ @/°çØ»¸ ÍY)ñ¯zpäƒ08 éiÅE(®ÁàK0tNOA—Ð/KŸýzM’Ò–=xð$ìõ¡½&*úk-9PÕ\xb ’õ!Ê¿ÁRÐ÷XøNÌ|'ðŽ–áÝwù¸ÑŒ¹g1ô˜~ÿõ-vî&Àëõq{œ>açNÆÙt?SPÓNi½Çî›G¬^·9ÁyÛÌc §Q'],*H—‹ÂÎË*~«Þ€¡×-Qœ*Ù{ê%Š­&Y‚­©‘ýiÝ ôõÂMiØ[Ú†TL^‚Ù‡Æt="m³Ö“ºÆÊl³ Ø.ÚM ÙêlwÌ "{K§gGTOtøå—ù…ÍM~û«_à_þËÉ /¼° P»€þÞÙ·ÞâÍ—^b}zš À1ÞV„±÷èØŒôË{tKitaì) äý.Œ½ÛbéVÞ2 Ùg»‹\¿µ(+0›¤¶*F «Ç¾nÖZ~ÀbìæuL¿|3²)ô jõº‚¼)‹»Ê"öЙ_íi‰}„Ð&Ò°ü½Èhg1v“Þô¡éÅ´ÅØoAæØm¹a¶z>Рæ=ðxªÉ29éIžLÁ¤Žj]ÒƒFàÁS#0äIDéRYJó9îÜ wôËXØj^{ìGnv¶£”n¶ˆV¤_îé ÛŠ0vÀìÀØ„Æ3vy)Ch0ÓŽRÌb©G¾×€>Wf»³’Ó¥Ç>¤,3ÒcOéBoX ×\sXßßš˜ÆEΈßÌØ‹aÿ7ë{ZŒôØèëÌ:Hø›T¥9¤¶=ú¹,aˆ‹aìOè{1 ÷’þ>Œîªõ:MÄBö¸«}t?|o{cðT 5Q¤›óÉ<Ÿ‚¼&¡]уF܃×F!ˆíëBUÆÕÖó{àlFs©$eùàÅ›áX*ºrµ ë1xú^ `#'#fÙœŒ¸> w“òz}FúéWÚpúy8<*?\iQ¿bwÀ±ç ˜ƒÊ¢ˆßš°÷à•¤On+ÙW³Ò/¿@fž? íEý~eù²`o¼: ­,LW=NóÉo±O¾3‡îNo7ê›wcå;zÌúhêÝ._ç¥}¼¾6^_€Ókúçâßn]º”ÛÛ¦‡n³ó( o+³ÇB+W Y©Hy½T†n˜yYJîIñL¥`9éÊÝÊ® y…N¹1-¥—-&(ÐÞ¦[«ígÒ¸ŒÁŒ½‘ìÕÏE}ßSˆW¸q3ÎsCˆçtE7+Óc€'õ=Ï8¢~7ÉNûk‚ã1‰–œ«Ê¢èÁ³GàX6×áZ®¶ œ€gnƒA_úè«9ñXŸk™spn4æ 2-Œ¹uÎ=±ð§%[}º}÷ÃÑó,ŠYÌæ´‡àÐKn:—C@oNKiþ›>d“09 ç'ÅÈf3 ÓZ¨õÀ‹‡aOAæß¯·à'xžßàîoÄwóÀ›Øù}'v³ºQ€x¸=àõµðúüз’Õ\ô8~JºŸŽã'ãøÝ=¶ [ìÜ Q)“)ä¥Ì^*†€^)Y‚8Q¶g¬2ûÈÑ2 L æ¸ëõ¼+mbÓ\ÿh\†b gaò%ðæ¤bã_†Ò,`º*÷z8Õ#~ «:­a±ÅôÜ£ð¬u8é:ÄÚìÔ³݃JlŸ2ãjQÆnë‰ì½nòðaÖ^|‘ÿõïý=Z­þð‡9þ<ž'¢Æ§Ÿ~š‰‰‰]ÀŠTŽwÖ£Q*ñÕøþôŸÿó&mDn~ö·@>ÊØã]»yØ®p7ªøhÉé‚Èb1gû8ˆ)‰E˜aò¦®…û ~¿\äÐЧ¥·ᬸW;¤_³d1vWÙú¡‹\Íú^gt£0ju“‘lzìW-ÆnJÿÇÓЊV)Ýf¬¾|¿2ð B9•@q¿¾¯‹ˆ8nˆ;pÔ…»c¢<¿„3é·õÀûØS‡Zp`Ôƒ§z¡Ñ”ÙÞ™&,©%ì}½’¡¾º¢.j@Ož†£E1ƒ¹Ö’ò{©ž?ý ™U_ÎI$뢧ÎÀÙ¨^•Q³¹28ÇáöG vZ×Uýž‚ÔÝpøN1)-@±(¥‰ý¯ƒs•-á%\e¶*IiË=ðø9˜lAýšˆï®¶åwìƒçÇ`jr9¸Ò‚?`„ËMßBÜ>ÞòJëߪœ×…¡wÅ…wšã:¸É6^ ¼8Ip“Ž˜$]±»K¸8 ')$\5”q»©Å¢3æ6˜$+Ò¥<ér~«o.}reç•"I«oÞ{¨ÅО6{ßcO“=É2Ãeâ×}ÜkÌÞ‘›Ô½†’ó—Ä«¿qM’÷Ê¢õX2)x2ã%qˆ»Hh ÔÒuqL[v"º7Œé>g `MPJJ×X)ÒcïëÒ4UËžn{]<α¿ø¹ÚßÏ_ûìgÙ»w/¯½ö?ôC?´åÏÉdvkÐw~Lå+üû¿ów¸üå/wôËÍöÐÖ3Ểô˱8AóŒ=:“žÔ׉ºÈÙŒ½9ôZ¥ôè8ˆ‰¬vaìÍûv¬^™sÛEnŒp&½a é÷Xµ®qõ?`±ocÙ§ýïUÂhÓ@¿¿1i4%î–~¯»õÏyB!„Ùês„Á/¾‚ùúM[=ÁIe}H¯xN¹ ¡ª¾ïmàTLKµ°d_îKÂ=Iùú9MP[FRðü´‹]KØY`r^Üî¢0ì‹*¾+Åà§¡¯)lyeCR̽pß 8ÒÕkˆ2_…Æa1˜é™0_Þ„õÿ0¤}u~[‚|Æÿ'è=¬§ «Ì^™%ýe`à<9 c¨ÍŠ‹Ýeí—ž‚§Õzv¹¨cyÀopzßciÞݶϙwcíﺓº=Ž‹›ð’àn}8² æI7üHˆÅ«cÇ¥Æ#9çæï6 ; æ@²X&]Ì“.È”ò[eö´%„K—‹$ý ©Ñ™3ùh“±r‹±ržÁb…äRx¶‰³$`\wtpîèéѱ‹à_íÃú*,æ¥:´À‰1x¼Š«°Ø+M«•v«®±ë„GèÚ٣ϭÒé"7ª{ÁF„±Çu¯©w!!Ì£ ÷Ïãć>ÄOþ»Ç[o½Å¾}ûøßùNž”$¾Ý>ùnÉý==f¾úUþÙãÓöý07[F;؆MïÂØ»|;Rvr#=vûÆ7%©¨ï{œNßwû`Ðoñ‘èœè€~})²ðFÙîûnzìƒ Žö¢ìÕE^‰œâS Ì.¡#œy“zÈX%œ/Ggõë—¬kˆ2½¦›Œ}Íqóýœaìç‘Ñ;“ÈfúÿSHˆKVŸŸ#œI6ñ@úÞÓú:}.| = ·™Ê@x, 7Ç¥¿>Ó€y_6ºñ$¼0Õ‚0ì+¾\sh^ƒÆ¢l®—Åü-‡àþ)(lÀÒ¦°ö…4áÅ÷AlC”ç¹UÌùûá™GÅù­>'ýò\Üô!H7¥¿¾¹ Å ˜üKÐ7e±ò·Å,fs.ª½ìpþ°ŒªUÄÈæDLuzîNÈósUaæ3\fŒ_äCl2ü-€x·ÏݸoÔ?75ûö15lj5½{\Ü8Äú[Ä´Üîöù¸½@Æ‘ŠºÃùi-³§D ç§â´“=ø=±H¢Z#MsH ¤ yÒ…©BA€½TÐÙ󼔨ý*<:H⃃Œ±ÎXm•ñr–ÑâÃ…ù}+E2KeóuŠ·õ<åªU‰Í¶p®W > ‹É»²ó%8tn†Ô†T_fËrßšÉ^àÝK®èÁyS×SRõ'æp¾N§É”1†²­bÍÁÝIUØí—ì?wŽñ§ŸæùÒ—øÆ7¾Á©S§x饗–{íàÁƒ¼öÚk»`µËÐw~”WV¸öå/ó•ïû>Z¾ßØÆ~Âl¬.]7Æ7¥ûÈóތݣsŽÝ0y¯Ë)Ö¸ÈÕ»ˆK o²Ù·Q¦øª‘¾—±|,Z?kL{ì=„®kFü6¦‡ãûn^'£§üŠXOÙtÂÚ,šVý¡»›é˧´œ^²˜tS_wJKðfìÆeÜ£?Ëe½ÆôØ÷"£o3ú±¬×¤€‡\y“—üðuzuŒ-¨I‰-ºÒü•º”Øgµ_>ÖÏ @a]DqוåŸì‡§3Pš•žôe`.€ÛÀ]ƒ®²”‡Å‚°&¿^¾œeaY«ë°”‚[Ÿ‡QG€¹´$,>× ç^ƒTªK[€ö(Œ?}ƒÀ[!+o_ö}© kýpdRƒ_Þ–äµé†Zjxå4ôçd^ýZUzü+¼ï(ÄjSlÎñÞgËßë˜ÚNsç7²wížžæ8’#î8®çøZ­Ö;÷RM¼T€—7nÊÁM¡åv‡@™ùV©=©ìoì#Mߌ«Ù×$”±Çf¦_~Rß—‰P­ë÷Úo±ã"×Ö׸G7‘iBç9WÁ„p¾¼h„5ÈÏ,¡Â½¡_È?u÷¬²‰b ÛjH¿Ü”ÜéI‚Ûµ†°ùÅ@ÜÖ. Á„#ê÷¹š¼·²/®HOúr ÀxӤΪç4[½K>xðÜÍhêZ63q¸÷qØãˆk~YÊü}pîeH–Äqns¼S°ïƒà®ßÐ2ûeÉCŸ+ˆYL.OÝý’ȶ¡ ÷ü¼ÿ8ôªÝtC˜ùšw€›Óð?/ÞÍ» ÞÞ+ ïT‚ïÖk¿ñ ºã¸88®¯c>žëà¸P)ë*t<¼„—òЃ­’;Ip’AÒ ûçV„–Þ“n§o»É >-;‹â$¸Y€Ä0Ü'Äsò|6'Öó È0àÁ³="œoÈ}nœÕ²ìÕÃïBD3¥ µÚi¦g‡«DõvKîÛ­j•öä“Ì~ýëÛÀܵÀœÀ¼[=ˆ°oÀA—€q‘‹Î¤ßÈ÷=¥¯c;»Ú 3ðÀø'C»ŠUKwaìÆ)ªF¨V7Œ}Tß›ºf\ä-07 |HûnuÂÓw»E¯]$ŒbDÁü>¿bõØ{‘„µ’ž›ÊŽÌ,Æ7>¦Ï›òû†þœ'¾øŒU²¯êk<çBS­b +™pà•˜¼—+j>cÎK#0@¶¨yà@Óƒ×öÃX675¦RKù·ÁCÃ2+¾T’p•Yº N CyES*²< {Z¨øíj&ž‚ƒ·ˆk~QÊèî8øÝ„f1Ú3¯ÎÁl¾ Lž…£0˜“9öl^*—÷Ý·÷J¬æRA n¦[€[ÇáHB”÷7/þe AÆÝzäïè;•×ÝygÉÝq<·¹®çhh™ù»üÙ¨Ç(¥ÖåÆ Þ× >Ð Ö߯íõqûœ¾7ã@ÆÁïYÎpqÚiSjÓJ%h'ãøñÄcÝÓÔÏ÷IoHoæIçódò›Rv/H ä9Bóž{KL6—«¯n±ò±Ê*#Åu†  ­oàâ“=1NéL/Û96òô®•H/VpšTçòó2®¶¾,VÁûÃxøl,ÃʪT曲vï͈ʽY—¿¿Ó}ñ”®Áë„£œf îÑ}kÑ:У{ɸ®×M¶û¾ÇØn0ãÿÄOð++|ú³Ÿàð»*׫Õ*¥R €'Ÿ|’ .ì¢÷.C—Ç•/}‰?øÙŸeæë_ï<ÝèVeåN°ßKݸG金w#ýròÝ’ÚŒï{·9Mã¬TŽ\“°@ÞfìÆWÙD¨6"}/ã"g÷Ë“Êt„@fÞ×^«,o/ð!$‘mÕê±Æ~Lÿm÷¾ÝDÆGhÌ{ëCæØ×¬’ ¯Œü}Ê.YŒ½GKìžVœ¬2âií×ÿ™‚¹É}ÔÃŽ0e»_> ¼ê@Ö—¾÷ŒÚ»ºä†àÄ!8“€öÛ’îv­&_žƒgnÔ’˜ÏÌUä0±æÁÈ çSœ…Â<WÄ¥ðæ Ó‚†‚üƲã–ŠrïLöÁóÃjÀ¼¶†f}¹Ÿ=$÷ ?£‡ÍáØØHÖç²l÷Ÿ°'cÚ‘ªa‹íIi½}}Œ~ä#|ÿ/ý+++ÜsÏ=üøÿ8o¿ý6Gehh¨cŽÇãÄãñ]ÄÞtyAÀŸþʯð•ïÿ~|ßßæDk‹ñÙ®pßI0w£û{aìݲÕ[lOjKëß»1öž.å­ófä`À¼‡íyǽº˜‹öR°3󨶺õ€ÞTY«÷mD4­MÁ¼NJYsMûuæW™|¿²ò5«Ç>¤×,+ ›jÂ>Ýx|ÂЉ†¾ÆúóL²€Õ%ÌC7æéû]FX¶™c?Ú#–¨é–8¼]Sß÷›àŒý…Pü6 ¤{à“E->_‘Òç¦ çÁ‰„€ùꆰ¥ãpï1Q²×`¦,U½÷À‰cPU(Tàà÷A2MGRZëªð;>T&áÂyHeÁÿ3¹îZ .»à “'!¥ãMÓ5yßKÃã?ÎüÁ°ºº Àèèè6@ß}ìöзW®ðÇŸû¿ÿÓ?MдéÒ/¿céóí. ïtyÛE.šÔÖc1vûšžHÝfÙI 䣾ïÝ»^Ô-©­›éè~>Y¬½z*/FzeÆ`¦IgNºé±椛kÌLzÞê}›kNêû^TÆÞÖßá]ú»™·X>z8«lݸȵôý>¤ß{ÚbßcÚKŸDTìÓ„.r/èÏNÆ~4§d&}¶öØïé‡û°™“¹ó«ú³ôˆ%l³3)qÎû0Ø8¥‚0¬¥¢ö‡ÇŽCpYòЧP˜„{>±T–DôTöáÐÇ ÕÁ¥™7¯Heà 6/Þ±YI^[Ω‘Žmh.ˆòýZU~žq¸y&]q«[Ù€Eexû÷Á“G`ò÷ŠÍVŠwwÛ‰‘w›7–Ôaâ°·F»]ý··çlÙ¥ËäX€§Ÿû³·n&DO7H ÔèhëohZÞí@¯Œ©‘qi§Å³ÝOÇh¥zh§zh%ÍŸ Ú‰üxœ ÂÌ3¹MÒ›dry2››dO¥vtˆáXŽw!oƒQ±Ö*“õeôêãå,ÃåKƒSüÑé;˜¨‡*÷‘Â:Cù RëeómÊ×eZ¢4/Á™ï€Ø¦„ñ”æ´ü¾kYùÿÜŒÁ‹§aØ—iŠÕ¼ÜS º¦÷{ðl–ÒG¿nµ³&´šæ©eN“©Cúœ=²jª†f\-ê™qüÂ>?0À›o¾I*•â×ý×yâ‰'vQx—¡ `~õ*ÿü¹çX¿xq˜;zÃïÌ]vžIßIg[Åú]À¼[R›aìµÈÀNj‹ú¾›lõhz‘ I(G»q‘«Gž2`‡ÎÌsÃäsÒÍ5ì* wS–Oé¦`«â÷kï-K§‹Ü"r«Zµ¶õ{ݬ×^£s&ý^s=ÒcÏ ¦4¦ïg’Ú†ÁÜ&b03¯ï-®=Ä ""›µzù'bpo ¦+"Š›×ßé½½ÂòWr¢d¿Ž¸È=>¦#|˜­ +Z `jž>ùuØTu5€cGáÁIaÒ¹Uñv¯MÂûžoQ€mJ>ù.Hü‰€¹YLa®Ô`. 7?“Ä.ÊlúRI4+=ðð­p°*ï‹%EM7àÀ>xð4ò°¸*,±*`~lœß<3J³ã½ÙºÞ¨ä¾½‡.%õ@w€£l[þmX¹y.è ÈžàÅäϘ]ÚCˆ΋ûÄÓmâ™6±t›XÚ×þy€“ ËíA ‚¤ƒ›’²»³Í%ÎbéVÿ<ÞhJ¯|sƒL~?æ1{ÿ92™û˜g8È1â¯3äõ×od™hHß|´¾FŽÛã³·¶Àx5ËXu•áRŽ¡üîrꜰòâu¨­ÃÞga`ÜU ã)iù}sI„‹³-8|žŸ§ Ùem™¨ùQÜ…—3iÊÿýŒV eÞ·X°M«j6¤kz%ÒNótopGfÍ^Ó?9ÉÞóçy³ÝæÍ7ßdxx˜‡~˜v»Í—¿üez{{9þü.ïúÎv½Îæô4ÿçK/±vñâ¶Ï»7óÊïN¤'nƒù»•åýHYÞÄDìÄØk‘²|ÕcoFþM=:bÒ‹ÊÖ¡Á0öŒuж]äúôë6#=öQ«WV²1ý ‹}0?¬ßcÙºÆÓ“ÿaNzÃócúܲ՗7#nÌ*>® {ŸŒU«øÓÁœUFEÌgV]ä*úû¸Kžwt#ÛÐ×>êÂ9R7b¡ÛRp[+%I#›Ê<4(¢EWUKؽpaJJ¥¹uq˜[éýcðà08W`u.µ >÷]oEú幜X»NÜ&`îCÀ<¸(£l×p%wß]aù•9i \Fãž™€©º¸Îͨè:01쇊Â,«ÁM>O…q_€ã—Wn§$­;é½úÎ%öÓÉʽ@˜¹æšx±ÀbæAX^ßú7Ä<ŸF-MnmèÁqâ©*ñt‹Xª­%wôT tRâ{d-év âÌèZ{ÌU0o‘.#O•Š1—Âñý §òŒ¸âÃAŽÑ`Ö¥äÞÌ2Ñ\a¨±Á;#§XéŸÀíñèk+ŒUW)¯Ó·™'˜oRžg¿ò,ôLÁÔã…Ú¾.%öò<çD·\„8ùÉ®%vg‡ûN ÷÷ÊØƒ÷Øc·òû²Õ»1ö’ÚÒ]»íû^Š0ö¤2ænÁ fˆ$ê5¤¹c7nq‹I–¿__k>Ò—ÖÏ­Dzì Ú-eàÆÁ*Ì—· =Ü Ë¿IKð3Æ>Ü«_k+é .r+„–°Eýý¾?&ïc¶%}Ǡ߃pÌoõ«zM x¦N0Sw·¹–¼Îž^xb*kaz! Ïߣ9h]’þú•*£ðØC_×Ré*ô={ž[OÿŠ6¥WzÑ—“нáþ7%ûürKÀ¼o<~üÞMW$÷¼ƒgï‚á– ˜Ï6 ’€—î€LÊ‹òž7Úö*q"wü·6º&®¨ÂºÝ˜%t‹‰¸Í5Ã*«û@w¶þóbžÏµ‹G¨×dŽ#žlГnÑ“nßbç6 ;‚@îA*ì¡ 37êü¹±~yÄ-2…M2››¤77Ù˜:@|ƽ5F]ða„°Îh°Æhk±æ*-/ÆNÝÅüÀ>ö4™h¬0^Ï2^Í2ZY#¹^¦>ëS½fù(z^N Í«Pž–2{iA¦æJOó÷B¦.½ôÍlXÚNeà± ¬êÄÄ5Á5uÏxP×Ü,á(§é—Óµ¶l­'³Ö—Et¯I¥ÓŒ~ÿ÷ó±ŸùÊå2/¾ø"ÿäŸüGî‡çž{nwýÝ¿ýñóGÿàìæÝžß©_n˜|”±{7`ìïÖcoìòÝ»q‘ë–Ôff;£Im¦Çeì†}Gûå)ún3éÃú~óÖ5Æ¿9A§ÂÝóo.ò‡tç­{LŸO*ö+SZJ_b»‹ÜY}¯¦$ØÒŸå ¢²¿dmJf³Êès³Ã8¤Œý¡‹\U¿öiê¾°o3û>ìÁË)™á½Ò ÇåêÀ 8Ð’Q±™¦”«¼:ý=2/ž-J K-/Ÿ…áE)—_oˆ‰ÌÍOÃTJ"JW× »#OÀž¨ýwÌ[×|ß s¼œËÂÜÖròÙ^Ø·˜‚ÖE}›©Š®š€çoƒþ:,­‰(o¥ 턉½ðØ”X…n.HÿZ«+¾5sQ¬»± Ì.ñ x+÷Li=°€<Ámx,dë1ýȯ’ÏMq¼8ÄÓ-âýHû•špÓ¾:à CRà'‘R{RFØœˆSÜÖØZK¼Ù$½™§7—£å÷°zøÉ aånŽQgg‘@À|Ì_eÄ_g´¹FÓ‹ó¥=Ï3ä9ؘÙôÑÚÃåuœÅ:å¨NCå:´Êpð W3bù[…Ò4çåÀ7W‡3·ÃñIh¬‰càúšT`f€xÜ‚[ã°ƒ™V8MÒÖVÖeåÓtÆΗg#:—^kß(GîŠá{îaþða~ìoü ¦¦¦øøÇ?ÎÙ³gùÄ'>!ZœÞ^~ú§zw}çGîòeÞúÅ_0”qnæß cw"eù÷Úc7¹f—²üN¾ï†±Ww`ìÈ¡Áø'û‘€aò=Ê–íCCFÕû6¾ïèÂ7 Ü€|FÏžGíÓ2{QAÞ>ùÒ?¬×1B:ãÉn3ö´n>%Ât·¶>¿O7˜kc#=î¡Q†ñŠ?¤eùëÆžÖ^z5€é dì.<ßeÍ;7¯³?& ÕgµëmXÀ÷àé=0àèQYFÜjIxí .‰#ܵL'àæó°OýÓ×r"L:Sw€¯¡Á;á(Û;ôƒ÷çmanKEq¾[IÁ÷ÀxM¿>/ýò…¦ü‡<{Ò X^Ï沈ôøo>)æ7µe)åÏ”a!gÏÁ釵àìÀÎß #77f¹UjߊWÖî)SEú汘°qSf÷bès×NJïÜñˆ§ªô¤›êiéŸ{©6^Ê—q5r’A’•»ŸpBvnzé IY‹ûM’ù"ÉB?ˆáö2Ë2æ®2â…€>ÊZÈÌý5zý¿?|¹Ä0cÁ*­&[ËL5–«¯Ò›ÏãÏ·¨\À®Ì@ÿí0x$èU§…±Wæ 8#¶ÀÅ4>'¦ º(•™ìºDÜ. ‡¤Ç!^Qd+ JkUì˜r¯[í,G×ߤÞãYkO1ýò˜®¿jd:òíßÎ?˜žækŸÿ·˜ß¨þnŒýFªøyôùnŒ=»eìA„}›{¼ cï±{-ÂØ‹\‘N¹´‚p™Î±ã"W'œI7 |Œp^ܾ¦_Á9Ïö`‡ýúu¶´±k!LjkèûÚg}¯eëuL¶º±„5›’‹¤GõZÂVôùû´š0OÈV|íÕÕßãL €ò³1(Õħ}FßÛÞ<ƒJMæÎ§ýÐöÕ)èkËF:W•ÃA«^=ýKR½Þ‚K.Üs?î• {e*)Øó ŒvSjÿÿØ{óàHÎóÌó—WÝ ÷ѾØ÷I²›l6Ù<Äûê&›%JÛë¡ÏqìÌÈaEøØ±¶,;veµòÚñ!i<I–5–ej$K–%­(iHÓ¢.’Ý(U8ªP÷•™ûÇûee¢h²¹:<T@²P(d~Ï÷¼ïó>OuB ™Âpà ìHŒjmZÀ÷Ò—?3 ¬‰óÜ\&Ëj¾Ýpv§xÎ/®Š%è\58¼Nö*‘UFÄ|cœ½ŽD £¬mpÕ\̃=rÍôY·f(§»h¦»Ð[¬\µn¸˜&>ˆ{ÌÜ”¯W·SÈ÷!ÌM(Þ k¶úçVÔFW,]‹Š ÎU ݉ª2â™Ëè8 ̃¥vËmZ+Î)1@Gg‰!#M¯±B¿±D¯¾B¯¾BŸ¾,}sw…>g™Lx€¯Æn%êfÄžgÄžg°™f°‘f°¾¨Jì.ÕI¨LŠ/l/ Þî,4fåþò””ßKs°˜…j/Üu'˜%aìÅyH¯IZ^Zƒëû`¿z^6€ŽwY]ã¨ky¿åµ³ö¨Ïž“c=°¡ïÁr ®]†¦qø©§ø¿¦¦øÚ׿Noo/ÿøÇ9tè•J˲0Í­€Ïïçí_ÄØÚüsÏñá šË]S‰Ý½†Ç®vŒ¸ÿµôØõ@Y¾Ùö\Ö&Œ}³¤6Oä¦q¥ó\Ð?¹±'ÔÏçØ=«XkÆžPÀYb½ï{H¹«„JàoR ÇJ[¿<©{ž+}ߨ¿/˜“®!3áýêþ *>‰(rWÕ èðžRël —AÆØ þÞ1®bëGåw±ß¨ÃJÊÝSðÒ¶šcWÙê{Bp¼"MÈ䕘80§: kEØÕ˜+ö®wÞ ;-‰µLç ƒƒ?V]zëîe™//Ì‹`n1o¸z òXiAúõ/}{àÄ ôDE?]‘¹ܸnAÞÒŠJw«„Ç‚V†RJÜÅ&lжÁÁaØïÂÚtˆ'VŸæ Î1ÖËž6JPCÆÏ<›é¶X¹a€fÌ`LÞ¦¶Ì=–nzßK슡{ŸqL>û±,t¢]Eb=y"É¡® ¡®*fg½ÃAK8h Å5ܸŽ×qâ*Q-fbÇüQµf4L#¡Žàº^-ÒÌY`›t™Eú¬eúŒets‰>}™c•>–éw—èµWÈ„øh÷[Øæ¤v¶iÌ3ÐÈÐ[^FKÕ¨N‰{_eÜ&lÿ ùß;3PŸïʤ°öµ¤+Ð} ŽwI6ù”˜ÅL¸Â¦ï†ãä–Å0h ?/á~芷Ñ-*`GÕcí:—~êZÛZÓ·oã]]|=á+_ù ¿þë¿Î;ßùN~õWµõ3.\à¶ÛnÛBÝ-@ßøVÍå˜þâùÛ§Ÿ¦²ºúÚþàM@þõl^Í÷]ÛÌMzìf ”ï´ÝolÂØ#wÚÊòAç9· ämŒÝ+£oÓèõÊ:Õ1íQˆ1²åÀnÝÛ0 ªÏ«¬·‰ìU,?ËzU¼×c¯«òž·À舺6®$}{ãuשMAP?‚̘çÕ¢äõò£È›©XÉb \x½úýs¬w‘{ƒ.ö¶sŽ¿¨»txDƒŒ-‹¢§¤¿! §; [—±°/©lÜƼ€ü+.,ZpöFرZ:•(ýa]Íqp.=Ë+’G¾‡{o•Rº}YÌbÆÕk8x nìw^zâÓjd®…‡o„PrY)É.æäµxãஈøÍËCï…ûŽAhJJ¹ß,ur¦ñê º  {Ö¬¦+€®úâ†)@n¬wÝô{äº*§·í¦æf w.`î´úKÏßÊøK7 aŽWˆuç‰vç‰$ËX]B]5ŒÎ¦ø¶{³ç-@7į]Ť6c!šjæ¼@wm°ÖÊTrq4Ûjx¿¹t ÷j+ô³„EƒO&£dÆég‰wž¡æ"#Íy†ê‹tä×°çšT'¤”^[³†ÎƒU{ª“ è§̳‹váð]0Ú->ýå9±ž¬ÉùùQÐs°¦Ld.«sÓVZï<ŸÀW¸£®ËQu½.6ºÞàMÆ´g›÷^wó÷ßÏ{>ð*• ïz×»xç;ß¹eѺUrí·z©Äg~îçøÎ‡?|ÍÇnæ›Ý¯}Ÿ{쯖Զ‘`ÎÀw‘kﱇ7è±{B:O_kcìøÙêÍ67ÕÅT¸Ç ÚúåcG1ÜJ˜ûÓ_Â~ñÄ5Ûñ£+¶°SýÌ\à÷ª$˜T ÒRൠ)ö±‚ßû¶UÕá¤:~J-X5õ~ìR›O­žW¯÷ 0ìøV±KêïzØg­”-‹¥÷ÚŽÅàT–*º2á@VƒSÃpƒ!Lj¡,,?¶ Ø.ϳ²(yèÕ8ý0V 1Î84/Ëcã,ÅáÁÓП÷̪„«¤#2G~SRlaÓy˜¬HÏ\KÀ¹²AXVJö…<,h`%ᡃ`/@aQúï—]è»÷‚5.&&S5¸èx²N}ƒ:•ëšé Ü|²taäÞý†Ùè†ë+ÚUIÝô@Ýt±<@7]Ö–˜ŸÙ„1,‡p¼F8^#o`Å­þ¹uТZTõËUÉÝõÄqQ»k=0n: ̵ Õµ(–£Ño.\ èú z¦è Š|8ñ6Šf‚agíΜº³ÈPs‘Èj‘ÆŒCm Ê¢Ò}'ôœR%öÉ5¯L(0Ÿñ›±N…^ ÊãÒK_Y‰†lP“q8·ôÑ_L5´³jC~TƒQå7¨ZéêzRÖ ½«®®³˜Úä–ÛȆ‹‘{ì1þÏ?üCºººèïï'•JñŽw¼cÝzùÖ·¾•;v0<<¼eãºèëoýö·s铟¼¶rÄës6ózì°ùûÕûFå÷ölõvKXäÛ{”gÒ#ê÷´g«{3éžï{±'Õ뺻i ä£ ”ƒýrÏ`¦„ŸèdÃø3¬Áck_aýLz\±ïr _îm&©÷`¶­/ïe«ÏãϤ»ŠuŒʈžëU'âÒÀÏV÷²ÛÈ¿¢˜Œ7.÷:)¯ûáÜVžªÊã+ÀíƒpÊ‚‚ÊCb#pïah¦¥ì=¿•8Üðv°òи öÔ'¥ÿý2°ý(<¸OœáêSò{^ŠIxäŒÄ¡V&%fZÙh ¸pô,, k_(Iû='aOTJì¹e~cÁÃÒ0&`-—R"6s´‹âMšY¬/±·Äo¾ÎP}qïçüï•9L«gظez,ÝÆR÷}óë÷P©v£éáxžH¼F(V'¯+Po*C™&DA‹!®pu»ÑpT0‹î}Ö0Ý&f®De-a› šóô⺶ÌÅо:BݱÛdØU€îÌÓW_ÂX¬R›@ÊìS E¡ïtí–àœú$­|uJ³bòã솳÷BsÊ—dlmqMFÒfÓ;àZFúåy$-ðœE[Ü'ñQ×Y_`Ó¼n{Ôç•@;Í[†{Œ_þä'ÉüÞïqäÈžyævîܹáÚû‘|„gŸ}€§Ÿ~š¾¾¾-ôÝtxécãoâ'¨ ÿ¿™ùÕÊïúUzì¼NÆÞÜä7ò}o}Ûˆ±×7è±o”Ôæ…»Àú9Q4Cø3éXv'~k±÷ª¯smŒ½C1öl[=Œ?GÞ>“îõØÚzu €WÛ˜ˆbÓÍ+öD<êùÚ¥½ê˜…¶{—ó²ð¥ÕßëÊu"nqËk`9ðü<öp" §B0QЕ9å“}w?qa%%êâ1`p< "¶Å<¤K°óqèÝÎÔ'DWJ 0¿87 Š™LyFó% ÖNB4ù%˜*I¿<íÀÙëÅ¿»”W~ì+’{½¤ÒÝvhŸP%û,GàÞÓ°½&¿aMù¾;°ïìit×gåæF îb˜šbèJµ|Ìp[,ÞhõÑÛº¹Q‰ÝÅ2›˜†ÃÌ¥cärÃ`˜„ ¢ñ*áDpBÝŠ7°âMŒ˜w .ÉjnÌÁj8QbÂÒ ÅÜõ¨†Ö0ÝUôÚNzÈÒo¦4ÓzŸ¶L¿¾Äs¡›ùrø†Xd;Áˆ;ϰ³À6'E²´ÚR±{€®ÇaÛƒ––öI}R•Ù §aÕ€cOA" 5%~,¦`¦$çS΀‡¯ƒM(.œFÎŽ‡u8£Á’íG{säIddUõÒƒ Qm³²Ò¬ÔÛÖ§}?ÿóüÊ'?I8vìŸûÜç6Œ=õnO=õÔÚnõÐ×ß¾û‘ðßög¯¿½®?üuöÒ7»ÿj`î²¹‹Ükí±ëÝW£í/©­Ùƾ_-©ÍÀÌy¯Ëó}¯²ÞÈÆ ô؃֎ž%lDm Ú{ŸÚÙçË-ŦCjçt£R%øl[e ée“ÚõGÔÏ´g«ïV¥üÅ6ÆžN«×”R VSýìYõýT 2îV ?¦6«ˆ/ÉÃ!a™ºÌ÷¦€ž(ÜÕ]%X]Ù°mîÝÎÌç!Sƒm÷Àö㺛“ÂÌó))£.wÀÀÜÒLC1 cŠå7;àÂqˆ¯¨”¶Š¤¨­§÷Ãᤈß2«’{>S·Žnƒý%~Ë hgÂðÐõ°£õH¤/ŸÁí·@Of–’ìûî{hÉ/5÷J6t+Ð/¶÷YW*wC1p£Urw¨{ãh~y]@ÝÁ2mêåŸÿÄ‘/õbè‰h‰Žî,±î5ÂÉ‘îVg ³³ÑÙÄè°q$4Ü„Ž3pâʳ½Mç¸ÐÌé¤sÛéÖr êäí€>`dè5VÀ€is'_ ¥e¶¹)¶;s » Ù‹tds­Z“˜ IDAT{ušKÐýDûÀ(@sZJìµ ôÊ4ä`I‡ë‡¤¥Jð“¯;­úâCƒpªº °––yô1eƒ÷Z0êÈy9Ázñ[ñrXU÷{"7¯Ö£~¶ÐFDà ÀÌ®],-/ó;¿ó;„B!^|ñÅÖϼï}ïÛ0uë¶ÅÐ[ýò¿û·ÿ–—>ö1ê*äþ æWcìWq»ZY~3Æ~-sìV€±ÛmÿØð&Œ=¶ c©c6ò}ïàÊ(D±ë›0ö¤ÿBÛÎßcìéÀ1º*qÇó 2ö^¶9Ö§»éÈLºg/ôœÞ¦Ø¶çá^ñ˜…úýéc·Õ}§ÔóLû~õa *r¯ŒÓà šš*W+ ÍÞ<ÚZ^zÕ㊠õÂýÃPϨÕì~¶„Ú%é™7&!Ÿ†‹6¬%á³Ð±"}ôÜŒ9pYƒC‡à` ¢‹ 2]•E>íÂûàP–2jƼsMèè—5{òªÏ>áB÷uðh/lË‹øm¦ —l™o~è6è,‰ïü\6Ø?—Q4#s¥T7ƒ%õ = jo©×MGÀ]õÌÍVßÜQ}sGJì¦#ýsÃæ›_½|©Í‚p¨F4Q!’¨ªz½5ƒnÄlŒ˜³!¦áFõ;×".DÀPew=¢aÒ¤‘ÓXÉЧ¯0h¤Ð3 ÌL н¯]CãO#O£kÛÜÛHÉg7Å &´\¢6á `OЉÐàÿñapçä^Rì\ ä²K9 'ŽH¤iõ’»¢Òò¦€¾^¸wœEùù1Ú+êڸ߂a[6f—× jÜ¥îK±^´Ú£®Á<ëá†Ožä3¥_zåŒÙYþðÿŸþéŸÞBÑ-@í·ââ";žùçŸÿž=çÕúèWìîߨüþZæØ7ë±77é±Û0v¯ÇÞ»Ú®pþ³£ø3éA!]\}ÞÌE®ÔÖc·kvÚ˜´àU»ÿ ˆf³¤6C•Ø ,0`÷(`^hû=ª”^`}¶zË©ʈÞ1׫…,…?_îe«ß¤Ê”³Š¡ÛHFû­ ħ,?©ÁyJ®”¿gT¿¼? '¡¾"â·‹Šýìì†7C6-#Dse8úŒì€ê+P—;³& ]NŠ%l,% ýš˜ÅL÷ÜM¨§`¦S)óǺá?å,̧%,f¾(åÿî^8@Åkª²ì°{/ܽSÞ¨µŒT.ÛPMÀc7C<+ 1¿š}3­MMjg誌(Á¯¾ºâ¨T즋aØ"€33v^)&yù;·AÄ%j‹–ÐãU"‰¡xp¢Ž™h`Ä›èq=æâÆ4Ü8Q -f Åh•Üõ˜z“ÚŠÎRi§€¹žfPO·À|Àï7¤Ün›&ú×D´*£î,ÛH1âγݣ¯¶ u)¡ ö†4Ä%Þ#:i)£WØW¦¤_Þu+:-›<¯üžÎÉdD6 á¶.ùù%Õ/ŸP× Î[©J„îX ¥«MkXçé@_ÜP%v=pÝסí§Oóµøø‡>Ôêƒoù _Ó­JñWo~ó÷̯ä7ë—õ…»¼ZY~#ÁÜëÉVág«Ûm÷[\éût‘kG‰«‹¿}&Ýy/ï8ÈØûÔ±í¾ïøImAöí éªm,ßRŒÝ‹J ²üí è=ÆÌV?ŒÇš ”ò«¿e"ÀVÂjÛ‡…‚Œý*IޱÞEn'p‹Y[Œg¼\é~ Î% •Ùî  †7íš0æé ,6áàý0Ô/Ì«>%‹ölQÊ¥õxÓõž‘±¤¹’Ö,pû8Ð`N©ûLCØÚCû”3Y5_^µìèÛ· +Ï-+³àи½œ—eî|܆i Žœ‚=q{ZÈÊÇ|ÊM½ukº† 2tWÞÔ”aŒ{¸¯cè-1œ¯b÷î·LG‰à¼2»Ý*»[¦ƒe9|õ ÷ATÃ9D£¢±Ê:†R ÝŒ5Ðc6zÔA‹¹>;¹Ø­pxÃmbg Ò•ôi ÌôÆ Ý\Æ55>dý(Q­Ì67Å(³Œ¸ólsS$‹«Ø3MjÓŠ•CôFï#`,Ëb}R>jãRf/ÍA1ÇB.Ô.ÊF¯8'—]ȇááƒ0TƒÒ¤TyÆ]Ùp&Üeˆ‰Ñ„ë·†lu½xrµ1u}ÖU³^u­,·]ë‘d’t,Æ_¼Hæ…xøá‡yßûÞÇ·¾õ-~îç~€|sçÎm¡é o|sšM^øã?æÅ?û3ÒÞÌãv-Bº×ËØ7*¿›¯ÂØ›mÏ·cßÌió\äÆÞî"W;øòŒÝÞ ÇÞ£À6ÛÖcïPì¸Äz…»¥»ËzG8oôÍ‹] :XÅ0gÕcžó\D-d!|¹ºúÛO©×å…QxÏuˆÁÍ~„ª‹Œ½ÐD%>åÊ15 †M¸'ù¼x¸OežÜ eX*ˆ:#pò&èí€êe1 )§ÄámÊ€ƒGEyš•÷ŒÅE‡à‘aØQc‘Ù*L×¥ÄÞÓ÷ï‚JVÄ)l¾.bªGAŸ«ÂU2R®]‹Ã}G`OCTÕ‹kp± ³9G» ”ùœæöCÂѱX™hLÀ<’Påöx +.€®Å\ô˜ÇcçQ"nëCÃenm”fÕ¢O_aˆEô CÆ"F†ACzçf†¤™ãYë6&ÝD¨ ˆ“bÔeØY #Ÿ£1åH?|KÕè½ôE—æ”k“ªo>&†Aù8{+„«R†¯MB!%çͤÛwÃ]ÐS´¼©Šo ãjp>} H×|ó#OºM•ÙWð'6šJ——–Ô¹„âq’?ú£üþ_ýó¹=ôøÀèïïgÏž=<þøã[ºè¯~{áþˆÏþ»÷Cß+0ߌ±¿–ØÕvÆnp¥(.èûÞÎØÃêñ«ù¾×ÚzìÆÞlcìÑM»§Š²oÏVÃwwsÛ’ë]§¢Š™Wñç¼—!u\ª±ªçZmcìIÅ´ Še¯zì§ÕëºèåÇÔÏ{3é©Ë?­Jð—TOÜ;æB ªÕI[6 Þ²úSž®CsÎ> öT.I¿4¿(]n»Åd¾<· æ@¤Ú Ö‚ˆßÆk2þ¶„Ì—ë°’“^úü𤻭ðÄ1變éÈŠšW/Å᱓л*›‰¹Š*×:pú(ÜÐ-‚¼ù5úù2è½ðà)øóôºWn_ÇÐM0,­•žf˜ [n äNËùÍ|ÃD·ë{²{%ö  ›6¦acY6_ú‡7Qq˜±&ñXI=^i•ÜCŠ¡[ñz¼©Ýi©Ù1;ê¢Å„¡kºÍ˹ë¨Öc k Œhó jRj4C72-ÜgBòOÆlwæ¤_NŠæÙf§/—¨M»ÔÆEàÖÌCßODC¤\š3´«+@ÏÎCü49¡¼ß~É-ʸà8pݸsHþg¹%qôúâ†oŒC¢*&Fcmí¤!uN§ðÅoÞzÓ¸ó¬Q/ìÝË—>úQÖÖÖøíßþmòù<¿÷{¿ÀÍ7ßÌ… ¶t Ð7¿-¿ôßúÏÿ™¯¿ç=ÿìÞ¨×«Š¿šW¼ÍæBº@^ÛÌ=ƾ‘ï»ÓÖûö@~#ßwKZƒ+gÒ;Ô±kmŒ=®Ž)¶R‹Eß÷Ý;ázÔãËm,¿[=–°¯”¾C=ÇLà Q²'ÀgÒ»gXï<ÂOjKá«âHêZ™û^àÊ™ô—ñ}ßu ÎG!ÙP,J±"Ä7÷CO&j²ø#p×#P_àÚ”œÆ˜Õá®c"¼«½"F!—eÒoÚ î¤¨â'ëòQ4á‘Ðoür˜[(Hæõ`,þEq›/Jùµ‡'B2%ì¢!ýz·ž> Ú2,ÏK¿>•‡Un; ýPIC½ì‹â Œ°ÇЕ¢=ÀÔ=õzð{ÝtZ3çÞ‡iú¢8³Õ?wÚ>l,5wþíoÜAÑN¢Ç‘"‰X‘X¬L,^n•ÜC‰V¢Ž¯£Çm´8hqâ:N´˜¦@Ý1\¾?‚ݰخÍ1¤-²ƒZšS˜¹§l03üužWôƒìq&ü2;ó 4Ó詪8¾M `Ûeüq°æàŽ»Âº§ä±šê©/ç`ÛyÚ ÍYuÿ¤ü?Ç(tÂñ~ñ¨^öí‚=³˜ëBbKlUàÛo'ÕÔ5sZ] žÈ³hgõ©ka‰õIi}7ßÌÿýÜs¼üÍoÒßßÏ3Ï<ÃÝwßM±XÄŠÚ2†Ùô«ÞVÇÆø¯?ÌÚôô?Û7ë{1⦘ükQÅ{`îråLº·Än”Ôæe«oä"§·¹W–©Å 8âfâ+܃Çè›ôصc¯¶±ü`RÛFÙêj¡ ŽÐD˜—XŸÔf¶õØ=9S=×vupö½K±ùšsï÷x‹_Im<¹„*ã{q¬sj£ajp§É&L5ÌS‡ 2F4Q—<òÈv¸õ.¨¦TŠÖŒŒ‹]v`É€[®ƒ}®¸‚e¼` tÀC2Ò”*ÉÆ`¦%ÞýŽêqç`¾)ŽÂ™¨¨õÙŠlˆÃ“{ +% o¼!eÙP/òÈ#ÿSùÕTñ\̯%ÝM¿ cßl&½=©-æõýfŒ½ÚvŒ¥@»¾ c×Ûúå^/ÛSÅ—Ú6}êùƒ,ßÀ•i÷}ï@s¹@Ï ”å=KØ cߣ_T±+p^T^=Œø»ñîuõšîTï‰æ%õ\wÐëÀx`TèH‡„»ÄKR*°A†[Ï€³$)YÅ91“s¥”~ßì°¡4á Ÿæ4xâŒÖdŒlª"#Is6lë‡{’Ðí 3ŸÏÃ\]Ø3·ö‹¹ÈªÊžÔ$å–$¸cRš¿¬fÌnxà˜Ë¢bŸ_6¿àHìêH Öfam¾T¸Žÿát4̃aáºW^÷zæë€@‰=ÈÈÕãÖ³æ–O³Ô¸šáðü ÷ShvK©=\"-—ÖõÐà s3VoõÏݘ&†1¦²uM‡—*‡ÉÛÉVÙ|H[dH[dX_h)Û4y«“/šw1Ãv9Së”ìÉâ vÊW7¥‰ˆŸ„ž4˜sq¯)f>%ºjì|{¡þ 4¦Ä“}ZMFÔcâ1]”ûç*rÿ¬ÒlµdºPQÜ”º>\uþoSÒÙ¶k ¢®ƒŠÚ8ͤtÓä¥f“Ïg³|ùk_ãmo{'NœàSŸúŸúÔ§ø­ßú-’Éäjnúæ·üƒ?àkïyÏ?k0¿¶¾Ùˆ\›*þjeysÆî°ÇØÛgÒ¯æûn°>uÍ»øÃ Ð6ó}:ÂyBº°ì`¿<¡Živð fÀO‚òŽéW›ƒÕ@Û{®øq¬•ÀëÚ§ŽŸ ô½\çªÌuÞ©¿Õ¶~y/b0³¢Jìc×{uˆÚ2B4­Ž¹%!êâ•5ø¶&‚¹Ð œ¿]ÊÕå9ÈωÈmHtÃãû¡>/"SÊ(dÍ„ `{Vœß&æóì”9öÕLç¥Ä>Ó–ulÎöCvFʸ“*óúÎýpcš/Iý’&Œ}×N8; ãuÓyóT:àÝЯÃꔨæçŠ0©i’¬â"^ »aÅЭv1œÏÊ[B8«-hÅr×Ýo†åõÌÝ–¢ÝTcjËË£¼2s -á•èˆHD‹$âÅu=t+QÅLÔ1MŒx-áâÆuˆk81CJí!›¯ÔÎR²;üQ3mž!ÔÓŒèó-†ž·:ù ë_ÑídÙãL¬M‹çÖ¨Oº2r¦ÆÏºî‚žÛÁñ[mJ1ó1ù¼¶•ípãSÊð;Rf_Ëø}ñÝ»ádâó›—ÿå˜jušð# Iůúýr¯d~tΨ èëç˻չžokµ%†‡ ?ý4ÿå]~•Ÿú©Ÿâýïÿ|M}ñÅ¥·Wü(/^¼H<gûöí[HýÏЛÕ*ŸûùŸçŸÞÿ~\ÇùŸþ|-#nlPbµlõÊï›%µm”­Þîû¿yÙêí ›ù¾‡Xï"d߉@=˜Ô–PÇÚ{Xg}ƒ{¿zÝËmŒ½S1ö%Ö+rc ˜ë^aжa1^ÝóƒP`tÐêVå÷yµ(z çp½9WJŸ)uÌ™(Üì(^r!†ÛNCo§Ê®NA.-iXÓ@7<¼K\¿Ö–e!ª<2 Ûs¢2Ù±Ú¼Çúál·ôPSJ¬6×7oß¡ºØË¦sRþOkpvœ°¡:& ïe`É„;ŽÂu¬-ɦ`¾ ,d;œ=Õdç„å§jÒ£8Ù¯Á7ÄtX÷zÈEi И[¾YŒ0öà›Û½­ï¡û¯–S³,Ì-Óá«ßxâŽÔèZ€¾®Üž¨a%jqö\‹¹81b:N l+Ä×í[¨¸ñV`ÊF€>`dÈYI>b=Å –ÈSw¾¥d¯©MºTÕœ8ŽÌŽwŸ½Cc* |›”ÿA± Ípâ^°§dƼ>KÊ0hV‡›IÀOcFÒõ.*@\ˆ@£(ÂÇËêܭ⇠á+߃×M¿ºF–ñ•ïÞ­Ôî»÷¾÷½ìÞ½›¾¾>|ðA>ûÙÏú ašÜsÏ=ß÷5ôOþäO8qâçÏŸgpp‹/rêÔ)\×åïþîï8tèáp˜ÁÁA¾ð…/‰D¸õÖ[·Pü‡ èÅ…¾öž÷ðÂÿñ¿¨7óZ¬b¯5Ü%ò¯¥üîÝ¿c÷ÀÜnÛlÖc2öZûözì^¶úf=öj[=©~>Øcá;ÏÔtu‡ZÜ‚ªønµ•ÚŽ )Ю«ÎÙ銙÷(öí¹Èy¶7À<«~ÏÄó:ãú£p}ntdLlÜ…yÞp wó.ΉýêTC¹ÅuI™ÝN 8Û¦š!xdv¥~±)·‚’b"²ªJâ³%é—‚7î«ÙeX(Êkˆtù!Ø]‘ …§¢_0àÞÂàVÓ*ÊÇ|]üåÏì…ò²°Â•)ñœ€[öÀç_öº.¬ÚYóÆÖ¬ JëVÛÜùb¸–ÂÝM³|1œ¥ÊîcÓ'˜ÏïF;t„ ò¡=ž(I¹=^%”¨cÅë Ì›¢lsqc:5ËàyN±L?;ìFÜù ³À¶È –fX_ g$ùoÖzìUFlåÇNŠáÆ<æR…ê´+%ô puúq‰\(0÷¡122Â3Ï<ÃÜÜ•J…ZÍ/È—J¥ÖÌùÀÀ¿ök¿öý!yÍ&õzÛ–«û¹çž#™L244ÄüÁpäÈ"‘ûöícyy™jµJ¡PàØBò Ï~å+|ôüyªÙì¿h05ߨ&ñzzì›1vë*ŒÝÄ·Šmqñ€9¸1ˆªc*´Í©nÒc÷Êò;ÆžP _Þ€±7Yoz¡+ö¡á+r=æ‘TåôUÖϤ‡£.²Þ÷Ýó>d± ªâoPÏ— ôËõ»O*ð÷6 àFnue„lXÐáÑÓâ—›†ü¼˜¼L:ÑáæQ8–¨ÒÅ51‹™öôÁù>h¦ü1²qœ¼y$òó)•â6ëB8í-KË2—> D:áü.§¥*0fûLî‰C°ÃLFLlR%H5ahîU¦4ù´Œ¿Mذ÷8œç;`§ü²[¢8­Ur÷úáA•»_‚¿Ì-×÷l”×[@n:˜–iÚ<óìд,âV‰®ð‘<‘BK'b8U3ã ôD=î Å%xÅŽ¹¸!Ïë÷²àlc´9Ëv{ŽmŽùó2ª¦\á Z‚ÿ¾@‡]`Äžg›“bÄ™g ¹ˆ–ªµRÒj ¹0ü“MkOI½6¥À|\Œ‹pèÇ ;¡úåÊÞuFÍ‘k½ðöã`¦¡<&ÿç˪l^î‹Ãa+¢}˜l4;ˆß¼j'CT¼~yõÂPï:Üû¶·ñ»¯¼ÂÜsÏ1::ʧ?ýi:Ä¡C‡6\Çžxâ‰ïûzìØ1Þð†7022ÒúÞ»íÞ½›B¡@¡PÀ¶m4M#‹]5f Ð`þ_î»fµú/úM½Vå»÷صô؃q¬›e«·3ö ÈÛmeü|ß½Xïû®{¹mÓ`á«âKm=öNõÚÚ}߃ÙêAç9 qrk*Àö%ÏC¾“+“ÚºÕ1Ù¶…,U?;`ù2ÆRåÊ ¿ü(b#T¸wkp@‡ýŽo­YÁƒ' GƒÕi ÊX,ˆø­jÂùë` )Šñyµ0§€ã½²`W&…Å_VÎsFžÜᲘÎÌ•`®!F2÷ Þ”²°°*™×³@gžÚ)»ŽLNF߯‘axr¸+Å:W”ÙøbH’Ú:¬ÌŠú}±(eþãÇád¯¤»R0çèÂÐ+lc†¥ä®…ƒåvÖ³tËŸ5¿’;b"(·›Š©Ëî_ù§GiDC„¬:]æ]QÐ;bâñR+ÿÜJ40ªÔw•:Sû<çœbEëgGc†mÍ”0tg¾èÃÚdXs:øËŽ7ÓÓ\eÈ^dÄ@ï©,ã¤TƘOÉy»ígÁȃ=+eõÚ””Ñk"&t·ÃÞG¡Ë€ÚwEÉ^œ‡q°î†7gRò觪r®-¨óöì®K•å’y¯_¾KUŽ–ÿ6p t¨Mk ßb9xM/=Ê'¿û]žáÞúÖ·rêÔ)^|ñE^|ñE¶oßÎ]wÝõCY78À—¿üežyæÞùÎwòüóÏ3<<ÌÙ³g™}î¹ç8qâ…BF£Añ{í±è×x«¬®2û•¯ðÌOþä¿x0¿`_­üînÐ/ߌͿZ¶º½ c÷ÊòN[YÞcìõØÛ“Ú‚Œ½ÜÖ/÷æØk›0vßy.âÃ7‘ñŽñÊòu®LjR«7_î1öAU6ϵ1ö„bì+ °½c,u¿è±×Ôfå¤zÜ3˜)ªç~L‡š#à;,¸ÿ ôi°:'Aóeée×Mx`;ôUÔYÕ/ÙOÂ]””‡ºyÝ„'À¨ˆêy¶¬Ìb4¸uöÆÄ`&“ÁÔ² 1xhìi#1 ŒÂ=ƒ`§Åñm¶ ó5™c?Ž0ù•Œ€|>‡áÆ88!ŸKMx¿ù$¸²MôºrÑBš?š¶QÏÜÚ¤än<Û=u{‹™ ¨§³;øæìô¸CÂ(Òe®ÑËûåvÅÐÃÊ»ÝJ4˜;w!®á†trÕs¡l«§n.°ÍNµX÷°¶ cjî"+n7Ïtg ža¨¹È³¨bOWhÎ*%ûÔÓÒj~+è«Rb¯OCeL9¼MCv¬£°ÿ.pW¡þ²½U;‚®N¸o‡$ì­-ɆÎ3‹ ÁmaˆU•–BƒeuÞÇ Fë Èøf1Á¶YÏÞ½\ŸØ½uÈ­ø¥ù¼ûâðHòYq—óÊâ'ºáhô¦”ßg«0cËÂ|ë Ãò,–¤—šÖàÑ}pÕ? {éóÃ"rK•%+=U‡’ o<1GfuY’ÚªIxø $V 9!îr—h섟ÉÉÂ~4»ÉÎý/ß“ÇèÒкr‰ó¹¦¬\¥¯n¶À]¹ß7ÇX.–i·X¹÷õGÿág[>L,TfH_×¶xš®¨0õD¬H4Qi¹Â™M´­Ã…¸1åZ7Ÿµ"b×j,2l/°­™b´9˰»À°¾À¾ÈªÝɧ»ÏuªŒ4æ¶ré,®Ò˜vüŒòIè;]GÀM)ñ›ú¨*S˜ì ¸áúû¡9/ _—9ÿËLiðаëJü6¦ÂU–a ÎE ^ñ&«ä IDATÇ"½ì 8¦6®S¬ö®˜Ú˜Ú6á»vQ¸p_ùÿ€_üÅ_ä]ïz†al¡à ¿¶[½Xä//\`òóŸßókdì©å7SÅoÆØ=«Ø{hƒ²¼šV€±K9^½Ú¶1ˆáÛËUñaÕc¯µõå |ß÷b[½C}äÚ{ŒõÙê67X¯ŠQ¾wmÐcïAsK¬ŸI ©kÞ ¯×ËïP¯ÕS_×^'³Ý«Ëòy²)‹ì®N8š€® ,ç´'Pž‚Î5e"ƒ¿ßÓ ×‡!S–Ùó¹:Ì»ÐeÁ±ØaŠ!ÍlYUté£ï¨BaIʲ‘@˜½p{BFÜf*¾gš°cnU|v –r’•ÝLÂ'!”&™*ÈÆ@Ûçn‡ƒÿ\ÌÀ¢Â®Cß&¶§„Þéº7ƒ(¯[m¬ÜrZàîÍ™{ýrÃS³[Þç&éÃ|ø+?‹¶ÔÓè¡4ñ ]±5:¢ÒC&*æ‰&FÂFëp ܘFºÖËg¬G‰6« ×jJ }Äž…;óô»–›IþûÐ9ºšyi¶5R Ú‹D× Ô¦\*¾¸mè)èØ-±§õixï±Ê„L „ÃÍ÷¸7T\ê\^Y +ýí5¨ÍI´­ç>XFL¸³˜ñ€#\QªïPçè ¾(λÎÕ9¼º&q÷Ýüú¾@8uê·ß~;Éd’ŽŽÞþö·300°…†[%÷ÍoßøOÿ‰gßýnrSSÿK¿Áîëù× æZ[Ým»ÿZ“Ú<Æ^cã9ö:Wf«{f5í=ö¨:¦ÔÖc)Þhcì†_C-JÁ{—ùB[¿<¬Êï Ö+Ü DÌQ€í•½ž ‹\±ïQ¿c6Àò;»èN©ç‘>¸}XiK˲0ÏØÂ¤Ž'á–N(­ÉB>©B\, žèèª(Õ/©…<¼¡ ŽhÒãž©©à / ÷C¹.Á+³Uß+þÁa)ÂʲlÆ€jÛýuÈ¬ÈÆ`¦‹6œ… ¿™eÉCŸvÀí€'5+óò3ÊÜ$1 ÷žû2¸¶ [¦C(lc†ô!Zì\ß̃@`èæ:qœÛê§›–C¡ÖÍç/>†Öá’Ћ$µI#GWd®¸€yG¬@,Vö{çq#a 3ÀR£‡¿· «‘g ‘a¸±ÀpsagGLaz›K,ÙÝüÃÈ}ôÕWl¤l¤®Ïc­”©ÎºT&¡2Í4ô? ÈYÌŒsö¥YÈšpô­ ©HÜ é—ÏU$`'Ò ÷¶¢è櫾ø C_]4^‚š7G>€8¿eÔ†r5°¡M(0y×Z8eÇÏü ¿ð±‘Nž<Ég>ó™Öœ÷òò2¹\Ž®®®-$ÜôÍÌåÛñ|îï ^*m½ÃßCÆî^̃÷¿š`Încßcgƒ~y°ÇÜ4{{º[L=^jcìôž*Þ<—ÇØƒsìºò¸båA…{T-tå zìÃêsp׋võfσJúQÅ~VÏŽöŒþiõyÎöA.+ 7U‚YGÓC ¸) k+ÒGse¶ x¢ Â91‘S vEƒ318® óž®K¿< Fàá>ÈW|g² Ñ-¸§vV%«|\1• xëè)‰¸mJ%²e\867ôªJ‚ÊIOé`vÁ#ûÁœõ n¦Bpý5AŸ“\õ†f€fHâY¸ÙR¸r7è¡ã÷ÎÕgs]ïœ@Ý¦ƒa¹¼8u+g„p¬F·“07×芨zL±s5{nÆEծLjBÚéåóÆtÖ Ô2 6ÓRFw 3O=MºÑó£wÒ]Ï1XË0`  ›‹e*Ó¬+“PŸƒþ ¹ļ%\§6)ï[8õ$Ä\%Š›’µI%~{wÈÉ•_ÿqu®9<á̪CO³á…Uç²òv šÕ§Î×lÛ5J&é½pÿãSŸb5›å¦›nâ½ï}/•J…••z{{éë룯¯okQÞôÍo/â|òGtë½ÆÎUÀÜ»ÿµø¾`ò›•ß_O¶z}Æî©âëmŒÝSÅ7`ìaäµ6ÆÞŸ­ÞÎØ-|±Z0©­K-dÁ™ôˆbìMµVŒ}Ÿú[¼™toQÜ¡=ÅúÞÓˆ½ì,þ¨Ðþ¸¯OTä™5a_SjSq gcÒ«ûcDqCÙÌœ̼…¼Ë‚»B°GƒË‰]SƒÁ<”„¢2~™v¤”¿£€Ê’Üïy{Û&¼e$sÂȧj²ȸpjN÷A:#`>W•cî9û#ÒÇ]U#n³Üói@-%îr3Eh„ÌC·Â6VØÁ½‚¡¯gâÞ×A0÷l_ Ë+»»­>ºi: |iîAŒ›.{MÝÌ‘ å¤w_k²DâÕV¹]O8pIÛ}|NX½Â`5Í@]zs^Dpî½Í%Ò•$ÿãºÛélª.2XOÓW_B[ªR—±²ê ˜0tºvI†yEœÕ¦…¯f †›Ÿ€HÕWÀg—Äbw 쇷ÉýkKâ=p?§ü‰t×Åð2¾Â$(¤ÎA佪պ¦<ç·à†zçí·ó÷##|àÏÿ€O|âœ>}š~ðƒìÝ»—'Ÿ|rk1ÞôÍo¹©)>þÄ,}÷»[ïê÷è¯U÷Zzì 6ï±77y6`ßÞ{+“Úª@4è<çe«7ÛÊ‹kŽà÷ ƒÙêö½¤¶ ë}ßw ãoí3é§Ô¦á"~Të‰8›„¹¬ø±Ï6ä±p4 7‡ #ËwwÁW€ù%Ûï—÷šðö(”ê*%«)ýò†Cpk'dó2w>éÈkÛß÷uIú\MʲsÀÎNq«ë\ƒË5QKÏ5ÁŠÀíÝp0 iq‘›m@Z‡{‹®rI¬b_q`9÷œ†‘<”ez¶ ®<É|ßn4Í ®µJînØÅ ¹9taæf{éÝjgèÁÏN«Ô^wcüÕK?IH¸Ezj«t“¥;”%ΑŒåèŒçÐãRn÷zçÄ]œ>mœ#V­Ð_Yb¨¶(et;͈-&2]Õ2õ$ϺƒîZ޾Ê2CÕEºË+8™:¥iíê”×ìx ´44.AÅ{lZ¾^Zc/œºAüû«Ê,&—‘ÁY`o?Ü;¥1XRf1SjCy4·›°V…—U¸Ê’:Cêtñã}+m(õ jÞµ¶ý¶Ûøì¶m|øc#óÁ~ÇMÓø¥_ú¥­…v Ð_ýV\Xà/œô7¿¹õŽþÊòe«oÆØÍ«0öïUÝÂï±·3öˆúºÔæ1ü×`R›¥À´ÖvŒ©X¹©Ør°ÇÞ‰¨âWÛ6 QµøUYŸÇFbWuUÆôfx D,W Ÿ NDàæ(,äEI>Û”Å7¬Ãù°š"$›²dkÀ­18d‹ÈmB-ØY`È€'LÈV¬§XpÁÕàþ¸¨œòÂòg\YüÄᎨ0¼éšR>kp²Ά¡‡Ë ‰Zp †'F¡Ù„EÕãŸR9é·í0/ψˆkÌ…LHR×¶•%£}¶$`^´`ÏÑ0ÎR]7ˆ„k„ÂMôƒr[ Ýř֕}ô–ºÝòçЃ÷yÀ>ž»ŽËõC„âuº+Yz¬U’º°ód$GWLJîñ¸”ÛÅHFáj ‹Íý$ôýå%ú«K ×l¦²væé(eI»I¾uð4½åz++ôW–H–V°ç”g%­2‘Øv˜“ FeÆôÒd Ðw<®"q§¡4 %y?×BðØ~è­ȧT‚Úœ:?XpF‡•€YŒçdØ…ŸI0¨Ny¨~um.·mœã==\®VùÈÂß~öY>Ì“O>Éž={xñʼnÇãìß¿kqÝô«°JÇá…?ú#^üÓ?Ýó˜;¯Ì7ËV÷þéZ`{`œcw7`ìõ¶ç mÂØ ülõà1AÆ^f}¶zDSa½ÂÝR€í©x›¬]mOjCýü€bëYÖ;híUß/à÷hH&y—ó%$&õ-ÒO•„1OÙò»¢š™œšŒƒM;Rί·„á„+à?îú*æÓ PS¢8×geçЧK‰{¦! ¯ ìŠÀa(d¥,Yý­7tÀš”Ñ'š²9H9ÁãÃP¯JŠÚBI^[Nƒ»Gá Ézq¸{Óq©ÈxÝtI„q¥0‚'¡RQmŠ°Âž$üø>1±ÉÎûþî»öÀ[v‰mi&ÓUQÆ×cpîV°ÊP\ÓÀ0Ñtƒh¤J(lCHS%w/ ]³ìmŒ\<ÈÐb8Ëá›k71gî n•èk,Óg.Ó«¯Ðc­ÒÉ’ŒJɽ+¾F,QnÍž7ðµúm|;tŠ‘ü<• Õ õ #ö<4ábžL£“˧o «R »e ’!–ËSM9”§„]—g Ô{ß&Ih•”Ü_™@Ï/Hd÷Mpb”.Êckåò§v·oÜ˰ºäߟâ:¼%f]Är“Ȱ¬ÎÍQà0þýùÀF³›õIiÁë&ÞÑÁÀ/üÿúÝï¦V«ñÈ#ð·û·[ç[€þZ©¹Ë?üʯðõßýÝ­wð{x»0ß °_M¿Q¸‹¾ c éì Êòp¥G´—îVk{>OßÜ„±ë hƒýò¨ú(¶mBøªø`»—­Áw„ó@¾W=¶‚o# þLú ~¿<¡ÁضR~7…5U€ îµ ØÙnoô¬Gƒ½:ŒÚ"ˆò A4àQ\QÃ{Îsy„-ß‚Š-`1ãcèðh‡x„Ï–…ÉÍ©¿çö(œ´a®,~ðÓ.4؆ûz PV>S`Ø–QV~Fø¤æØ ·÷BsLÄoÓ5˜o‘°«Ü¢Œä•ò:t‹ .© Û8!'ä÷ÐKôÌ-wÃ^ºi­ï¥çœ>>Wx«£Aw1K¯¶B¾*,ÝëŸ{€[#«ŠÕiÚ.Ï6î`Ì8ÌpaþÒ• ƒ5Q«51rE–é`æ–£t×Hæsô”V‰eר̹”fhz´®{ØPMAyÖúÕe(Äàþ{¥½Rº,eø%528ôuÁ­=_•‘Á %Š[â®´Wªâ»Ô}Á¤6oñÓðsҽѷ>¤Ï¾Ü¶iH"½ôE|ÀŽOhÐpÈgyÌF\º®Ó¡¨î÷@vPƒ‡ (ÙÒ+õ;À}Œ¸’‘>ޝ¾ß¯ÁY V¼ßãJkÀÔàÑ8XUÙqW~„¢°½*Õ‚1MÀ¼¤Á:á`æ=0oÊïí„{ú ¶èÅÌh°gîHBsVŽ¯Ã‚ ‡ÀáAȯˆëÝêä\ L“°U!®c…lì0Ø!®dèÁñµ€<ÈÖ-Ý€g³w‘‹wÓS]¥Ï]¦W[‘r»–•þ¹WråéŒå‰Äª4]¬ßÄEã}ùº‹YKiªëišiŒl‰-Á♽t– $s9’…álÒ¬ó¨¥%Ôf÷C² ¬LKŸ¼< Å)©Ž”;áŽ7H¢ZyFJì鬈Ü58:·u‹˜pqÍ%,1 1ÁmˆXΛ~hªsù&õµüS œÏ#ê±åÀù `h×]¸ÀŸg³|áß ³³“üãœ9s†§Ÿ~úŠudff†o|ã4­…u Ðå–ùÖ·øè¹sägg·Þ¹cßlŒ-øØëÉV¿U¼¹ c÷Jùu6}kï±› Ì›\é<WÇ7`ìqò팽Oýl®í˜AU¶¦®iêç‡Õýž`.”Å‹®0¬Y×ïcÞ ì×¥¼=…ŸE=€¸ÈemßÄ+—žz\qóXYØ«Á]ÌÚbHã%k…58•'oÈ⟒¼)*Œý’² såýy´vY0]Ö>ãÈß³-ö@5#¢¸‹Ê+þ`¿ŒÄ•g¥Ä>Ù·¸›Á‰Añ!_^RªUÿwè>0 BVƒp¸N(ܤÒ°C.N€¡û@îÏ ›W°u§õ½e¹´.¾¦ÝN4Z¡¯´Üô^c…nCºWrïŠÉØ®ÍóÍ3|Ã:Í@6Cw>Koi…ÁJšÁZšþz²e–‰³z÷nå «y’k9Ì•2¥9—â ”¦¡º(%öŽN°ç%»¾8¥ØùœT.ŠI¸ï0J¢=(Íɦé’+çΩ~¸%k³rÿ¸JÑ«·pJ—©ƒ‰6³˜°ó"²1 Ns„Õ¹Ya½þ 92Bjt”ÿgm¿ÿÂH&“|úÓŸæÌ™3›®#;vì`ÇŽ[ ê Ë­Y­òÊ'>ÁßýûOyiië]ûgV–×Ù<Ž6ÏV·7)Ëof#ëù¾o¤ŠßȬ&(Ë·¾…¸²Çî¼Ã•Îs^=ß¶iˆ(ö]jcù!æ6ëÔLUÞŒ*¶ìÙìCIkøŠd/Äå6D°ôŠã‡¸4Ô¦à>D¥>… aªû#ÀwðmdmDxw›—laØ êµí5àˆ)"»—m9&ôèð¦4JpÑ‘žlKH‡!&Š2Ê6­zü;¢ð@Ö!¥ÄW À}pwDÀg¢¡Æål8{wÁò‚Œce²°¤ÃÉ5^š» ,“p¨I$RÇ ;ZŸ¶dåí=s£e&C oîR2:ù¯åCïvè]^a ™¡ßY¢O[¦ÇX¥×Z¡'¼Jw8KwT@=씘_N2›ØÉ@9CïÚ =ÅUúÊË ÖÒôV–°W«ä´(…ÿ¯½3“«ªÓÿçÖ^Õûžt:[g1²0$DL1Ä–2‚ èäADEDÇd`F4,ƒ~‰(ƒÊ"YÄ H"dë¤÷­ö}_îïsn×­êNu”û>O?IŸº[Ý{û¼ç»½ßuS© Ç©ôǨ†Á›&: í‡X/ä‚о ªl= ±AÑ¿>Þ#2ý‚Ì7œ&X52‘AQçß-Ÿç²&X`MyzS¥®ôfÑøç¨Œ£kž™‚$ë)ò]ëgl¼¼Z.ðBe Ó§ܰ»ï¿ŸL&ÃW¾ò®ºê*î¼óN¶oßÀ§?ýi–.]jL”¡L,Æó7ÜÀ[>hÜ­ ™¯¹Ë»YòǪcσäßOŒ]sËgDZØÍ”6wÑ^D-Æ®_˜Ê,v}V¼KsœÒ¬x‡t¿§)mi•dn‘¬“\‚Pã”®O˜Iò ˆIYߦ²XAQxFs—ÎÇRýãåvDÓ—JE¸jõuÇ'›a¾F²â³^ùjø¤¢©bF´¨1ÁIvhRDÓ•¾ ªP0ÃúF¨+ˆf1ùdmpñhŽ@È#DdºòÂ’_2 :*Àë DFÂà1ÃÒ¥Ðj*M(yvk»=‹Õ–GµY¡[Õ’ wK™B\9±*ÇYU« 8&S•Šn9 ªŸz% bèVár¯q„©v„q#àq°»ê ”¤™æ ‡†¨Ÿ†¸ŸÆ¤†¤—¬/EÄî uæD*ýq*üq*1TwšØ€Jl¢}õÁŒOBKè­GEkÛX¿ðP¸ kMTT¯ ûG$³õN\8ª’",Ñ—)f¥€“˜¦ŠrÅ.éÍÑr6fÊwp˜b•…ª—ïz°lqj’ïw`Ý:þù¡‡hiiaóæÍÜzë­8¶nÝjLŽÞÐóÙ,ÏýÃ?°gÛ6ãN}ñ¿ÝøEc?uìú~씑¹ÂøZñƱ»8vV¼]ŽëcìZÛÕ$¥*r6iekÝÕ´ìâÀŠºÚš&| "Y®ŽR9NUºJåDÝ­³Ø§ æü”¶¼4kå÷ìÑÅØóÙ×yŠ(Ië•nñP£ˆdº¨”Õêå'›`£],TŽ$…Û^#ŒÍP•_T¯ ±Š¹` 4øÀ#ë¡J·ü©“`Q5ŒxE¬x$&\ù«—‰f0ÉN`š s \ö$v{«=OÁVÀlŦkÌbÕêÑ‘1ruLÙš–Ýn²Á®ÜÇqZ“4ù¼4e¼4å¼4ü4à§Þqt«HŠ«PbÄ< »&¬%—pÐä÷R ÑóÑôS—ð‘õ¥‰XmÎlÀMãr'pùãä=¢ýË\ºÒOø;¨©‚L·°º52xDžÁIóá#“ ê}Ͳ4°¨´‹.v¦¨Xi!˜$äÅŠx7´8ºO·.­sma–Ôy´ä7eŒ…ö .àK?ù ƒ?øííí\|ñÅøý~¾ô¥/Q__Ï·¾õ-c24p|BïyñE¶Ÿq†q‡þ -öc¹å—<±šñbìÃb?VŒÝ&“9†Åžd¬XS¥>Æn’d®èÜåÚ±ªä>‘2‹½ëÖb’šµ´HN²(NÊy91/—Ç9@1^nB4jqIË\/Ÿ,÷é•?Z7,—t¿gõÈš›_NRÄbâ`®¸0ÈÌ"‘n _ìî“ †s,b¼''êË}€ÕçÕ=}²µj?à°Á-P5"b쇱 pVÁu³ ‡¯(JÇk? ³èV)óÌ)pÙÒåž'oW±ØUòúºf™ëEfô2VM"Vá¿” È8ì4DýLL Ó’vÓœóÐ\ðШøh0û©·¨·¨T„ü6vOY·ÒèõQS Ð÷R‘ògˆÚ-8>UÉŸÆ6”ÁéIvçˆA¸b} À çBEô6 WztP(éõàôE0­B½B}$\LL¬•Írò~!$tD-.Ú9aÞ¡Xý—.ô6ùvRªJè¡¡ŒÎ]¯Ÿœg\}5·¿ü2ƒ@GGÏ<ó S§N5&?ïÐ?ù¤¡Çþ7f±¿ŸDºw«)wÙë»»ea±ç¿!Ly»c·Êñò»Kn›,sIVÊã…)Už«‘j˜Ò®kóª[‡(*x¤u¿TN®ý: Ë*&ŠõåZ’Ý`¡ÎÊÊëv!êÅãÒ’ÑY_ ɪ8¼>8¨/±nŠÚÞÓ5&¡ÞS–tQâv†–ŸÝÝÜ€ÓçÕ‚Ý'jË ’üj*„Š\"(,ò‘ˆèá¶ÂʹВä ×Ái&BÄ&!I~D^[ °X^ÇQyž°¼þSM7:ÕRwí4àc’ÈF-1„ZÝJ'8²¢^þ¨ÌÊwšáœj°‹IY@½>Ù©¨#ŽÁ`6øØLh+@´ Üaq~ë¨4a±ä„ËÝ‘ÅbÏ“µ°ÈÒ5S‰e^¦ g--[SL {8‘:‚TÅ¢4ż´$Ý4e¡7üÔ[D ½Z “vg²¶à™8‹Ú‘UÞ(50u‘ •áQ_Žt5ÔŸkFñæQzr˜‡³¤Fò„…î}l^X¸ê*DÒ[pDú°¨ 6Á²0£‚ò …·nYxZ ´™!*&zå;Ó ŸÍ°|†u®ô*„XŒG>½*¡Ö8B©ø‘4Ï›GÏŠ|ç¾û°ÛíÜ~ûí8Nî¼óN.¹ä’ãfµ0Gy„gPˆ ¶láð“O2ô»ßwèCHòïÕb?ž+_ßýXò²ïæ9ú IDATÅbGŽkYñ™2‹½R'^f±×È}ô½Õ«ñïÅlq-¾Ù.ÉtXçâÖ&ßùò\G$Éfåã4ùyœ°ãò<³ñ÷Š%I9¹`8]û ¥ÝݖɰÀ~I Úrz"Ñ®á.”×<ÏËm0œ#ÙbG¸“*`žLa‘-¯%e58àœHÄYõÇ…TlKü]» «p¿°J;™ àáŽoB• ‡-…KºÉž'cS1ÛÔÑö©å oåV¹ÙªbÎçØ—_€ßÞHsØCM8LSÔKKBtEkÊyi4‰²µ‚¤<ÜŽ:ü™MåP§;I/Lm(„3%âÍ‘¬„I~U¤í÷牨„†1G!æ‡%Ÿ„z»(I x 4$’ÙÓ`­†3Z¡Õþ~Ñ_¾'[¬r8»Fä-ø"²ÄOš9C>³~¹8ó•½Ouò¦TɰI.ƒºwF{oÛ.äíSNáÎûîà®»î#cÀÀq ½³³“É“'sÏ“ObµZyðÁÙ?w.ù™3K6¾öÚkyàÒK =::æt:Ù´i¡žvï6îè_±[þ±Øß­Oûx‰tdzسã¸ßÇËŠ·I‹=EiRœE7”ÖöV!2Ö}RÔ7d™#?ÔYߪ$ø9û¡kIvà$9yëé@”*µIò×—¾ÕHW¾[€G^[‹$ìJIæÚ>IUrñÑ«[L,2‹Ÿž”p¿k {k*…`M0&Jìºä÷l²Â…5à‹K9Ø´pÙÏhÕ“!ä¦)ˆ4ÀÜÉpR-<œ*M¸¬I\¦$Gly,v‘GyzYF»Å f³Š)“%5¬¯§9å¡*(ÜæÍQÏhýx³*âçu…)wC-ÑEÓ©ê‹bJSáSc Åyó$+`ʧÁ< …îj¯JxXÖ÷„ú…îâ3¡ApË %·þ¼HŒÛ8S¨ëyDç¹.)½[P`m%´äÄ=ë‘zqй•2dÓG±ªI¾3NIäúæ*Zò›RöÎØNrííl9p€è;ï`³Ùp»ÝTWW“–÷Gè³fÍ*‘ܲe˸û|>.•=u5tvvòü믓˜4 ÿÂ…£ã¬_·Ž×·o§ëW¿*ÙgNGÉÁAÒ‘ˆñ>àû±²â•w±ØÕãyá{žcwwÏbO•YìVI€9i…k €Ji1»åæ·J2µKÂÔK¶ âÖC”ÆËmÒýž– -ÁI‘VY“ÎbOè\¯‹å¹uû$DV|Hƒ¦VgC”ÄÙ±oŠÝ¸(â»ôd„Å>,Ïšfä…ÕÙ#3¬S&X[%# QÆÖŸ…f6ÀiÂíì÷ }÷d¬].´È3G!µH— §5…Ë,²ÜU;XF-t½ä+£Zî)*cVò˜âið'88i.%…3”¤:¡.„ž.wÅG íK ™ÈÌ«Á5˜Ä:Å9’¤Êňôð`ÂF0÷‰Wè+†À°(;‹ C4'¯€&‹ˆ‰û¼ôˆlþÞ4WÃ'Ú =ìG¢B”Ç( ,w@Súd [ÍÊ6ËÅœ‹bõƒþ}š&ßgm¨-(µê‹¥í}Aè±7þýßsËãÌdX¹r%ßüæ7ùêW¿:ºÍÆY³f1xo.÷÷‚ÆÆFÇŒ_vÙeãnÿÜsÏQyÎ9,8眒ñ pëE‰Å0™„=gµÙ¸û®»ùÃxãÞ{‹ä¡(˜ÍfÔBµP0žØ_Èb‡÷ŸHw<’‡ñ³âß­ôíXÝÝÊ-v«$îT™Ë¾F­ÒþÑfIæVia…tÇk@d­QÚÄE#ó¤$ù<3¯”¹f})ÒýÞL1ÉN‹£6#âõŠeL¹ÏéòºJ‹=¢s埀°µÚ÷°Ì ')kår1àÜ ˜Rqò®œP,óÓjàc óˆä·£9HÖÀ†%P5 ºŒõ§ d•„nKâ,$°Û³äí f[³–§—zÕ[èäE³o‚ˆ¹—-…=ÁéORYê-1!×Ú”÷Roö“‹$ñ{@YU‹SU0õƱ÷ ëÜHàóðù n)4µˆ”ëV·ß-=4,ÊöV­†«p½{½àó€[–å5TÀš "üàõ ™^™d°Â“ bÑÔ¥½)“t ÀÔê®×ÉÏó”V? É¿^n){oíf3­W^ÉÍ?ÿ9CCC,[¶ŒGy„––V¬XaLPþ÷}<,_¾ü˜ŸkEÙÛÛË’‹.bÕªUœ¡+{饗xþàAø‡›2e óçÏgç~0F?þ /$¾w/¾Œ'ùg´Øßï>量½¼,N“—}·®úcÙäÿ˳âíußõYñ“äD«É»ftî÷Ir[}}¹Ey5¥Ùê 2ÙÛ(Õ}WIwóå5uê\ùH®çÐÇQ¥Å®Åص}Ú$i§å±´H•\0Lö«E‹½œn†i¡<§uöÊ#:{5§e‚ÔŠ©‚ÕõàsË>éÈUÃù ¡¢_ÈŸÍ ̭ V[žJK\Äвv V›ŠÙ®s¹—I¼šr9ðÇÁŸ N“Ÿ;‘æ”›'ƒË— .¤!"äZ'äFh*¸É%SøàÚXÙnAíLbéÏáN€?…; âöÂÄ•0ùàmÈö‰˜¸Ï#È<0¡<¬^M9)–„>÷s‚ 6µ€7Þ°ÈðײÒ'›aƒ†Óp8WÌJÏËðË©r‘×M±,Q[4Ζ÷Þ£#yM/¡šbb¦>^>cõj~Z]ÍMwßMee%·Þz+µµµüä'?)ù[Ù°aíííÆdeàÝ 4UUÕ¿ôIzè!Î?ÿ|*++ßÓö###D¤{>™LòÀðùÏ‹ÅÂ?}õ«dÊ\÷7Ýt¿{î9~û/ÿ2:ær¹X¶lÑÁAcð²òMǰòõò²åãæã¸åUÆ6„q0V+Þ, »BN°úR¡ZDÓ‹ˆt}'uÖ÷tyLO™%5IºÒ}éTiyuÈ |„¢N·K¯àÓ¹ò›™ÏnŠÙêyIØòø}kÒ+ sеïqy¬*bүˊ7k-0)G)û*uß;*`i„c¢z¯ j\x¸Üõ 2tÀ’ÕðÍ¥÷±£å">ö›—9Íö"ÓN=Hz¶ oÓÍälva¡[UÌ–ss2)@ñÅQ|qòsZ°LvaÈaëËPé‰Q%k-)7-…òñ8Á„JÕYfNrû-(½*ö¡4yoO@Å„ ËaÊP Ó/ˆÜçֹߓ¦ÀÜ)àHJùÚ€éÏ@Â$JÒN«ƒ`\Šèd‹ ­i&8Ý©¯¯÷¦L”‹37¥ºëZ¿Iò¹tÞ‹|×,ò½Ðk)˜É«WóLM ?þùÏ©¯¯ç‡?ü!+V¬ Œù;zê©§èêêàÆodúô鯤càƒCè ‰ƒƒƒÇmØÛÛË›o¾Y2VYYÉÀÀ/<önÙyHÃ5Ÿÿ<î_ÿšÞ—^*oiiBÁЯÿ#IþýXóÇj"SÞÝM?®ÅØõÝÝ,ÒšrÈIV¯0W+ 5ª›”5IØé;[i‰l&D,½A’¼Þb¯”î׈ÜGcŸ"?×’ïròºæÊëòSZÞ4EGòaäå‚a¥U MvQC>¨‹—g) œfŸ”kÕ»Ò'Pl¯«•%jÉ”¥õ ØAM{ëåþJÅbœUUÖ­ãñؽw/ë×¯çæ›o>®§Ó€¿YBÿSðüóϳjÕ*ÌfsÉx à>Y&¢Ç™gžÉOzˆ7î¿t¬Âåâ+·Ü‚÷í·y§Ì5fàøûñz»s ’?žÅc…g&È߃”¶P­×¹>õ’°rbNÈ}R:’Ÿ€ˆ{(­ž(Ò¹òUk ‘=(?‹ê¬ÿeòw½ÅÞ ¬’ß¡‡bwø¤¼†nŠZñ6Etj3Yeb\VÏå„s'CEPc§ ýVX½R4|y»0ƒ³>³ 5ë^|šSê^aÒòn3] 5µáwMµÐM…æPÅ›ÀH`ò'À£é£6jgYQ*XŽ÷ym8DcÄ'º¢%bŒT’Nè¸,>ùƒf”n•”'Çp†кfÍŽŠ^åÞ¸àqƒ'--pÖLˆûEa8,êì‡ V`s•†LŠ-^ž—ÞšÓ±ð鑊pŠÕõrQ4¬s™›ehùn„tï§].3ò¹ätᆱªŠúnàê;î •J±qãF-ZTÒÒôk_û‡Ã˜D |°}dd„—to]]k×®u! 6nÜ8úùk¯½FWW6luÅwwwóÛßþ–¥K—¾«›é‰'žÀd2±aÆ?ÛwÈd2Äãq}ôQÎ;ï ;Ò9ä½´J¯H?Åê»\€)Õµgã•,E=vM¯ Bzfâ:öŽ×µ´`¾ôR¶|ÿû¤R).»ì2î—†B"‘}kkkQÅ`&,Bî¹çxóÍ79í´ÓF]Þ .dÇŽ466b2™á’K.áµ×^£³³“öövöìÙÃ¥—^:J¤‹/æ7Þ`óæÍLœ8qÌy …Û·og„  |>_|ñÿÉE6›åµ×^ý}``€ú§âŽ;îàGwÞIÂç+–ÉÄ7¾ñ ö½ô¯ßsOÉqÚÚÚp D‡†>”ny“n¼Üý^®/¯u]«‘“kt×§¦û®—„­“ûÅʬoÅ^Ô!Ý>fé~wêÜòyŠª_­’Ìý:¯6ù# ;ªsËO¤(<¢ÅåMrQÐ&·×«‹5 Dq’€4ÏÀLD¼^E¸Ø5+߅ЄWM‚È{ âÚj¬°±Ìa±QÁk…OÌjhI¤®)üó=¿/¬õ)Nl{æCDfÔÐß0 ¯c"™¤‚âOb Ä1ùâ -tqN¾$‰3£’ÞoGéTq$…Ê[<ñ(Ãa•`Nºìà¨]¢†|0&z‹O\sg EjBwÞw Ú`e¤£¢¼l CðªâÙŸm…*‹hTÓ—$¯•ž.ŸOÅJíÙœ ŸEyŸòZDBcZGòúä7­óŸ¾¹ŠIQ˜qÑEÜ÷ƼíóaµZ¹é¦›8ùä“©®®¦±±‘ÖÖVƒ‰ üY`ùß$ÄRŽà œ?&¦Dbz†"PÓQÀåJ`Mg©Tb8m¢ÝfÏa±ª˜ÒYwÅŸ|"‚6™ìˆ‘8ìÂÚ›Å<§b8Nm8ˆ)e ª2„ Á>t 2Œ@o"4ÃSp Ë»?$Û»faJ ¬©‚°_Ô×÷%EY^PÞ³sL`UሬË×—®Û’¸>4s‚|îZYb^·œ lAÈ,Ÿµ…b¼\ß)í„ /份½¼zèuuu<ýôÓìÛ·ýû÷0oÞ<ƒÐ |ð }Ê”)¼òÊ+£D}íµ×r÷ÝwhnìĉùÊW¾rÜmæÍ›Ç¼yóÆýì ßþ6sçÎ¥©©©Äâ¿3•‚%KJ¶ýÌg>Ã/wì(ÉêX¶|9‹/fÿOJÜíþ«'ùr y­\-B©ÀŒCçúÔ¶EZÓšR—^÷½Šb/j½»Ô‰ˆ['(-}3Ë ^#yý> ’èË'"‘.F©T¬V¯^A±¯¶¶˜¨C$e ÉmŸ6i±wëÜÂ9yŒ5ò¼Ý…¢Œm£Ö; qô. aó¦ÁÄHëO ·u² M-PáŠS‘ŠS­D¨°‹²µ¤=YÍÁH e(âOˆIèMUa–. }ÐŽzHÁÑ•ÂÖ—¡Ê¡‹ÓŸTé Á´ÂœéÀ[P8*ú·÷$¡7 IœµøDÜÂòˆ ϯ•°ÎŸcíˈxy\ÞßåýëÌ3šõ}ª|–ý”–žM– ªAJõ L2dSM±Ä1_ö>ÊÂ/M³gÓU]ÍwûúxõÕWùô§?Í7ÞÈ‚ 8餓 æ1ð×EèsæÌáöÛo7îð‰ÓO?}ÌX[[ßûÞ÷ÆŒG"Îÿìg9ÿ³Ÿ¥¯¯_ÿú×\vÙe455ñíoÏÉ'“K&Káp˜ç®¿ž|¦¨YuÚòå˜Uõ'á;^¦¼¦û®e¤«:kÚÊØ>éIvYJUäL’Ì­:»žÌk¥E+så7ÊíôZñ&IæU’°õ¥o.DÌö±aµZIÎÀ_¡8pÇÃìÙ³ÅäètbµZ™2e û÷ïÇl6ÓÒÒ‚ÓédíÚµ<ûì³,\¸ƒrÑE1uêTyäÖ­[ÇÎ;G]êÿùŸÿI4åºë®ÃápÐÒÒ¡C‡( Lž<›Íö¡zˆÕÕÕ£šÏ&“‰¯}íkTTTŒëI$<û쳜-Ã!úã<º};]ÝÝ%ãkÖ¬¡½¢‚×u ~ xÌù<™hô/ö]Šelå­Z-”öV××ýÚåä«/q3IÒFçÆVuÖ¿ Ö»òm%<#: OˤwPZú¦Hë®Až#¤ÛÇ)I;§³þ´:öòó!¹Ðö™€è7Pf±k„•Ÿi%YõÀ&ðeDv·/žn…Ö˜(ë:¬B²vøÔ‰`á“NÀ•‰Q“ S¥DqI—»¥%?’„‘Š;-,sIèsz™Qý,r˜Ž°ögÉSô'UzâÐ2æ´‚i¿ soŽdD·¸pî"hð@Ä]ièNÀHVôŸkÍü1èT ;_Ô·Ÿ--ó~éµ”ïÒòž.IyˆbVºæe©£(É›Ñ=çIòwýbJÓ>Ðú”‹Õ¶µÚ´‰;¾ÿ} …×_=wÝuÏ?ÿùÎ%-óÅ26½ûÝDQG‹ã6êˆIk""#þ#:’J’©C$E(öcO!Ñ6šÀV~w;œÓfÂ#°÷ö³xfæz&¿äf…ÿe¦Ÿ|”ŠUqŽÒÂÞ=-z-ä‡S£„nòÅÙrëÖP:!û†SoŒ/ËѬJW"*|b4DÀÔ)êÅ +i‹8K@ÊÑæ¡;C9±h™c†5fΊkîÕ¹ÒÛS¤…=ž+}¦üÌ­[Ù%Ñ›ñòHÙ³i’$®·äµLv›<ŽþÝ0Më×ój.Ç>û,óçÏçºë®ãª«®2&„nàoªª Ù¶mýýý|ãßDŸïýÛ¿‘ K¶ß²e /üô§¼ö¯ÿZ2¾xñbf͚őgž!ÿQVûx®y-‘n¼ø»¦<7^CsÉ#ÇírrÏŒãÊWË\ùšeî–·>–ï„¡i{k„aG$Åi®|}ݳfIº¥…©í3]. <’̵óÔH÷{bw·0U3.uß­V8wЏa~¿È"Þ»‚—Z×Ó¾{ˆeÑW™º¬Ûò4oõN`ÿˆôCaDº5gÝ*?³¦¦(tƒé0({,$‚yŽäTޤ!n†OœuqP;Eg³ƒˆîfª >5 šÂô‹ñž<¸ b2_¥Šˆ“¥T®WSØë§TÈÇ!ïK£¼/z…?§\¤(ÆËµgS'Ÿg¼ŒäÍ’èy³e‹Æ™7ÜÀ-?Α®.æÏŸÏš5kX¢Ëu9ûì³Îiþz]î>«AEáõ×_gåÊ•,^¼xt¼¾¾ž­eîy™ÿ'oÚÄÉ›6"öÿØcqÉ?þ#ßùÎwîè ««É½úê«Q ž½îº’ãÌ;5—# ½?Çk.s¬&2yƲQ)•éÔ&l­OûxV¾Ö§½ ×j,B:"ÑܵZò]RGv„[>E1‘N#ó‰òó¡2‹}"ÂýßGÑ-Œ\H,ÛR 'LFĘ» E‹= \] Ù$xâB˜¥»L *“jÒ!*Íqœö©PŽd–ü`F (#I_‚f[Œ95)’‡€N°€džCŠJg" lXUAHõYÖ#R®6o†s'BµOŒ’ w~U܃¹ÀºUAæúòÓá­ôLKX³I’/PåѤZ]ˆ˜yy.ƒI’¹]>3ý³±Èýòòù”×’4\p_yâ ÜË—/çÇ?þ1N§“ƒ„FÌÜ€a¡ø[FWW‡ã˜e;Á`G}tÌø¼yóøá=÷pðg?+_¿~=k֬ᵻï&xôh1†n2¢ æóïÚ*vÓºñ…ÝòZæ÷`‰zQíY¿—ü}ñË[xù•é84Àüæw`Nˆ£3‡Õà>j#5’ÃäI0Ýšâ¼Åy¼iÈLŸÈ“߉H~Ó[ßZ¼Ü…pÁÇ(툧é¸$a‡›ä˜Gä8dÊf6ÆæR(Àä~”—?ò~øðÃ(Š2š/4222Æ‹5sæL***¸üòË?^¡0ðÇ"—ËqäÈb±>ø ×_=étšûï½—àÑ£%Û¯^µ K0ÈËeuýLlmep÷n²º…Þš?ž(ÎñdlõŸiYùPšEm’Dn–ãúDºJiåÇ)UË«B¸¥£ÝòIp'ÊEFŒyà4;4ŸZ—ÔóÖÛ³èbf['îº4Ý>3=.‚}&2ž J(ÍÅÓ TU‰^ã™>!1Û-Ió,©p†B+]«—ÿˆšÁ—$¯%ù©òzµä¿AŠ5þv„ >/½|{Ò ¹IDATZ‘Íß ·õSÚõ¬Qþ¢4^î@„'RŒÍ°Ëûœ.[€9ëêˆ××3²|9ÿ¾c .äꫯæÊ+¯<æû§¹Þ-Ë(¹0`º"B¡¡PˆiÓ¦w»_ýêWÄãñÑßß~ûm~÷»ß1uêTŽ>ûlI¬ÿúë¯Çiµòü 7”ÃétRSSC:³x7Wþx­bí[Åê³òÒúLPÿwR”*Õ—ËÙîj(6É#TÒY ÔîB=a"Ãõœ¢¢e˜£ô* wىȅ³Ì0©¬©ƒaBC}@^G;pª|Šè/Þ«³ü§ Q?ÞC1Æ­u·›,¯Ë­û>vDö†b{[­,°Az@.$²:¯HƒöÜË@Z.C’Ò„E“<—RvŸì. W^É­=Æàà ÍÍÍlÛ¶m4¤±±‹ÅHK2`ºXìÙ³‡×_ý˜VØÐÐÿñÿ1füÄOdpp—î»Ͼ}£ãg­]˲eËxã¾ûˆ¿'+_KÌ+—¾µR,±Ó[’6iµg(Mð²IÒ,Åq')UaÒR+Îl%à ÌI 3R§+ ^7úLdbTÎ6Ë=&NcÜ&àÀ« {P-ž§U.†)&ì( éTS,½ÓˆÙ%I>ÉØšðFù=uï5ë»VC_I •žYåqÒežãk˜é·ÝÆ·nÅëõ²råJ~ùË_òØcÑÛÛ À5×\Ccc£ñcÀ t>¨H§Ó˜Íæ?Êú ‡ÃüøÇ?fóæÍ£c|ùË_&î÷SÈiø²Ë.£««‹_}ñ‹tºümmmœ²`e]ü´f5å$o–„•/³ò-’ü´¸¼vf;ÂÍ­"’å6,QÈö›H·VS›ñ»Ê`‚nHK6] ˆRºAµT¬Å*-iÂe®‰µ(ˆ„´É’”õé,3ùË{Øk¢4óì³yxbçNL&¿ùÍoX±b…ñb0Ý€Äb1víÚÅÙgŸ=æ³mÛ¶ñÖ[o•Œ~úé¤Ói~}çT·µ1CÊÿNu»q„CìýÛI…B˜%iæ[Æe×Yÿã)ìetVy9ɦ[ǯ©õ•»Åmr,;Î>Ê8„­—þ-MXtd®¯nm¥³¢‚tvBÈèwÞ1^,¡0`àƒ®®.¢Ñ(ÿþïÿ>Z/ÝÜÜÌ׿þuB]]%]ùÚÚÚØ´i»wìàÀc¡H ½yÂ:æÎÅw𠱡¡ÑaëW“Z/þ¯åè÷Ñ´ú e MÆÆ×ñWŽq~½\°~ŸªI“HoÚÄ?>ü0‘H„/|á \xá…ìáŽY³f±eËã…1`º>¸xøá‡9ùä“éèèx×mß|óMºËºòuvvÒßßÏÈoêé߸q#'žx"»¿û]B==£dj2›ill$îñ€t÷ÃøJ~ãeÿë‰ùX¿ãU ëÉå—_N<çÞ[n!¯ó´··³yófÞüéO9üÔS£ãõõõ´¶¶’ÏçyòÀzfΤ§¿Ÿ[n¹…¯ýë(ŠbÜh¡0`ÀÀ_  ©©é¸êl/¼ð2[]Ãܹsyå•WèîîfÛ¶m€hÕ;‘/Z´ˆ+®¸¢8adoÀ t ø`àwÞa×®]\sÍ5ïºíž={Fe}W¬XQ¢ø÷~000Àã?ÎÒ¥KY²dÉq·ýÙÏ~†ÇãyO×gÀ€Aè øPÁçóqï½÷âv»±Z­ÜqÇÇÌ^ß¹s'O?ý4sçÎåÊ+¯Äf³ýIçÖÈ|õêÕüö·¿eÑ¢Eœxâ‰ãn»cÇZ[[ijjâ…^àsŸûœ!1kà=ÃdÜ ü­ãÞ{ïåꫯfëÖ­Lš4iLßr Ï=÷Ùl–­[·²jÕ*|ðÁ?ùÜ¿øÅ/8óÌ3éèèà3ŸùÌq¹{÷nV®\ɼyóPU•ÁÁAãá0Ý€4¸Ýn𛛍©©!»]WWíííttt°_—MoÀ€Aè 0`À€ƒÐ 0`àOEee%±X €T*…ÃáýìСCÄãq@”´ƒA¼^ï¨Uÿ§àœsÎáùçŸçwÞaÛ¶m\uÕU£Ÿ=öØcÜx㣿/_¾œ_|‘}ûöa2™˜4i’ñð ¼gIq ø›Gww7÷ß?±XŒóÏ?Ÿü㣟µ¶¶²}ûvV­Zˆ6o¼ñÍÍÍÜtÓM–¤´žzê)N9å/^<:¾oß>z{{Ù°aÃèØÏþs¼^/ŸûÜçŒgÀ t 0`àÃÃånÀ€ „nÀ€ 0Ý€ 0`º 0`À t 0`À t 0`ÀÀÿý饂o ßóIEND®B`‚snd-16.1/pix/tanhsum.png0000644000076400007640000001543411147553271013335 0ustar bilbil‰PNG  IHDR%‘T7®sRGB®Îé pHYs  šœtIMEØ.2£´NÑ®IDATxÚí]yXSWÚ? «ˆ€VA V놸4(ˆ( è(ø(‹ueªÎ¨•Ú§Ó‘¶¸3j§ƒ:¸P•>Ô­0P(‹hÂb‚ ›ˆ$H"‚,IÈöýqúÝçöÞ$„$DÔûûƒ'÷pîyïyß÷Þ³þÎk —Ëx'ÐÑÑ!“É&L˜€Ionn¶µµ577×­8CBãŒ(Ðéô 6zxç!—ËóòònÞ¼™žžŽ$ÞºukÍš5·oßNKKûöÛoy<þF.—{êÔ)…eŠÅâôôt|ûptt¼~ýºÎkA4!€gÏž%%%Õ××Ȇ†Û·os8œ7ò0'Nü裣¼ó “Évvv›6mÊÌÌ,((€‰“'Ož:uêºuëÖ¯_ïàà˜˜ˆ¿ÑÆÆ†D"),óæÍ›ùË_þkÔ¨Q3gΤP(DBàtvvŽLÑÝÝÝÈ[¿Vp¹\“ùóçþgìÞ½{Ó¦M .422200ÈË˃ùy<Þƒ–.]zèС¤¤¤¬¬¬¦¦¦‡ÓÞÞ>ÜVÀk†J¥.Y²„Çã•””ègžYý* ‡ß ëÙ3ñßt‹pss{üø1bý¥K—D"QAAAHHLïêêb0t:½¡¡¡®®®¿¿ŸN§ççç×ÖÖæçç ˜ÅbÙÛÛÃßl6»¨¨ˆÏç ¼¼¼·×å`Š€>! ÓÓÓUd¸zõjmmí åˆÅâƒJ$e%_¾|yåÊ•Ÿþù¹sçâããcbbbccT«Žt¼h…ÈÊÊ***Rv©=D"QJJÊ™3gÈd²T*Eÿ+..nܸq\.WámmmQQQŸ~ú)¼„_j¨ÀÅ‹Ÿ}Zõ mHª@ã£>Â|ÂÍ<}úô믿®¬¬Œ‰‰a³Ùè<µµµƒŽ#ubMÕΣ+;b¤«°i||ü¡C‡Ô)óÀÚè_ÏÈÏÏohhËååååpÔ‹´,kÞ¼yHÎÒÒR©TZRRrðàA¤ F7!2™ ¹½§§G*•†††J$’ÆÆF¤ŒBÐ 4"Vô‰çÏŸ766.Y²ÄÀÀI¬««kmmµ°°°²²²¶¶®««›4i’««kKKKCCƒ³³³‰‰IyyùìÙ³?üðCx˃¦OŸ®ºäÂÂB___ä’ËåfggÿöÛoè»Ð¢ÝÝÝù|þ Òñ¢ÕÕÕ¯^½òññ©­­mooGcÅŠ;vìØ¸q#̆¹Ô¦¦¦åååR©ÔÈÈÈÄÄd̘1mmmè vvv×®][½zõ²eË/^Œ/ÁÂÂÂÂÂ`ff¶aÃ†ŽŽooogg第¬ööv[[[´™ðP¨ Í€h¦°°pÙ²e¶¶¶£Fb³ÙS¦LA¯‘x{{ëÐ!•UAµó(´£2_=z´šn¬Â¦T*uß¾}p®¿­­ÍÛÛ[·/&¦FÊüY' •••|>ßÇLJN§GEE?^"‘=z´¦¦æÂ… &L “ÉÝÝÝ #55¹1==ÝÈÈÈÈÈÈËË‹Á`477_»vËåVWW3ŒÆÆÆÖÖÖI“&™™™ÁüÑÑÑ£G®««ëìì„4är¹Î7õ£ýÇãåääÄÆÆþþûïHb^^^FFüïÎ;Ÿ>}§ãY,Ö† öîÝK£Ñ„B¡ŸŸ_]]2×^öPXòöíÛ÷ìÙS\\L¥RþñÔ××£Ÿ#v•Ž-—Ësrrêëësrr"##=zN&“‘ÿúøø 3c.u‚ºº:8rÇà믿vrrêììƒâU¡ñ(ÑL?ì†Ãùt†ðððS§Né§ ƒ:ÆŽ*|I}7VfS©Têàà  ªªªæÎûôéSÝŽBÐ5RíÏÚ ­­mçÎL&S(þûßÿêÊßëׯ_¿~­:Û•+WàØz`` »»[*•¢ŸN§£×Wt2 !vdé÷ïß ÑhãÆCét:ŸÏ—Ëå'Nܸq£‹‹ËÂ… ῦM›¶páB±Xìååejj:gΜÒÒRø/‡ƒì»PV2…B‰ŒŒôðððôô\¾|9‹ÅâóùèçÁˆ¨##º¯¯O,»ººš››¿|ùÒÓÓ󫯾 @2Èd2©TªìR'} ˜˜˜ëׯ[YYáÿkkk ?j:7(FZjÆÜÜvx­¬¬ ÑÕDöêE”5Ù$]]] ƒVaPçÁØQ…/©ïÆÊlúøñãiÓ¦Ñh´iӦ͚5+>>ÞÙÙYçÖ„5ÔŸµqÔÐÐЭ[·zxxH$´qÕ‰‰‰¥¥¥¥¥¥êl[·nÍÊÊ;ÖÐÐÐÆÆ©`eeå²eËt«7b"Kg8wîB,Àlâ>~ü8`ýúõ<Ãá ŸiÀŽ;BBBbbb¼½½= @™ ‘-€b±þ …&&&H6|ÉÏž=ëïïŸ7o,ÍÒÒríÚµû÷ï///W!ZéÑkÖ¬Aï\°`ºúÆÆÆp^[á¥öˆ‹‹ûôÓOW¯^­ìÅûé§ŸBCCLMMukqŒ*ÔñP­™úúú¾¾>OOOxI&“]\\¶oß>vìX…l’{÷îÍŸ?ìØ±ðR 0™Ì7nìÞ½[YÔtÌÓªö%5ÝX™M©TªP(,**‚³^˜Y¬/^œ9s=ÝÈýî»ïÆŒ£Ž5aõgQQQQWW×ÓÓ“••% ÷îÝ;_!“àààööv<»ÃálÙ²?#§ÓMˆ.çjUãÆ[¶léïï777‡ÝÞÞÞ‡>þŒ¤\¹r%55ÕÕÕÕÍÍ ®/™™™ýóŸÿT±ÏäÚµk .twwWý$xYXYY‰D¢ââbe)à ''§æææ & ¯ŸD"ùùçŸýüü^¾|¹pá²²²»wïJ¥Ò€€@@¡P$Iqq±H$b0ÇÓÓÓÓÓsÑ¢EÉÉÉáááø’Ÿ?~ëÖ­ß~ûÍÚÚúüùóp{ëÓ§O322æÍ›‡ÑZ´±±1NT:Ftff¦¡¡!‡ÃÙ¼y3NñâÅ¢E‹mmmè¾æRÔ××õ÷÷ÿÑ24D~#ÈËËX»v­ÂÄbqOO\=RØ…Ç ##ΉOŸ>=33söìÙx+ …RQQÑÙÙyîܹ¹sçnÞ¼yPÍÔ××çææR©T†VïåË—ccc!+(//oïÞ½—.]ª««+))”••q¹\؉ Å/aªÀårÕqüÓªð%KKK5ÝX¡MY,–««+üø’H$¦ÍúÓ úWíÏÚÀËË+--F£´¶¶Î;÷ml<(®ªgggk¼:ÿý÷ßÿðÃê³–†ÊwÓ˜j§ÙMϬ"¡PØÞÞŽN;p8š.«±C¦Ã—<(t"– ‹e2YKK †µ”””››«ìrXÑÐаcÇ̦&4.]ºW€å&„WWW_Á¡»»{ÇŽt:].—ÁÝ÷x+h 4ƒ¦(c“üúë¯x¯ðõõUáHš=­®ÜX!wÙk'‰^¼x¡ºÌo¾ùFý«ögíÑÚÚ:$|¸ý.!!Aã"~øá…MˆBÖÒç»á9DoŠU¤%’““)ÊH-•JwïÞØs9¬xýúuxx8žàxKBBÂêÕ«‘™2B8ÿûß!YJ¥~ùå—:´‚š¹s玻»ûâÅ‹?ùä“ÜÜܤ¤¤œœwøðáüü|eMˆX,&“Énnnéé陯AtkG»q¿ôOŸÏß·oßœ9s***à:>uöôôxyyÁ47ˆçÏŸJCç»iLµS“ìtÊwÓ'ÂÂÂNž<¹`ÁÈ¢oܸ…Øs9|ÉdÛ¶mßr b³Ù ¥¥¥å§Ÿ~B6 ‘H¤   ï¿ÿ>22R,cÊ 1cÆ«W¯È´ªN¬ füýýkkk‘K@`fff``ðå—_¢×~mllÐSÄFFFÁÁÁÁÁÁÚ8’ní¨s7Ö€:§7Ï|'aÔÞÞ>nÜ8‘HÔÛÛ‹lÞ8yòdTT”‘‘QDDÄþó777@pñâEx4ñÊ•+ƒ‚‚ÜÜÜ`þÇs8Lzii)\¬ØÙÙÁS‰jkkÙlv~~¾««+’!??_(®]»–Ïç:tè›o¾¹téÒœ9s¢££U<FVnnî”)Súûû?ûì³Ï?ÿ¿YÑÝÝÝsæÌA>µ˜KÃáàW¢(Jjjª»»»\.Ÿ4iRNNŸÏG7!t:ÝÞÞCµ‰Dàÿ9J Ÿ- !ñx<„„n` ‡mc|JEE…2­¹¸¸èÙ 1LMMßÔ‹7¨h++«9sæ(»ÄC‡ ;vlDD„úu WØ…ÇÀÆÆæÛo¿}òäÉÁƒÑ]]-­0¨fF”# ÇÓ¾A7Ö¸FoÅ÷AOMˆÂÔ’’’ÔÔÔòòr6›lDSÆLž<ŸŽç iÆw*Õn¨d7…)666Èn u÷Ì£Z5áîî¾}ûvÌzH GècèÛ·oGT†ê®¥¥¥d2ùÝSËÒ¥KÿÔ„TTTxxx¼~ýzÅŠ.\˜?~oo/›Í‰D°!Q6]¨&oH3¾›f²€Úd7…)mmmñññÊ*{àÀÌcošÆªÂ5£ ðFÜ•D"½Á‘Ö°BLMMaw¾©©ÉÃÃ#77×ÖÖvþüùx6}NNNHHˆ:”7Õ¼!…”¥äädtžäää/¾ør”îß¿¯Õ®ººº££cÁ‚hrzfÏá§ØÚÚ9rD©ÖŒV¿ŽA(œá®:AGG‡L&ÃpÒÜÜlkk«ó“zG9räƒ>HLL´··733svv¶¶¶¾y󦋋 ‡Ã=ztVVÖÔ©SÁµkךššœ~ùå—/^L:µ©©Iaº½½½±±qAA¿¿?€Ëå&&&&&&:88°Ùìdff¦¥¥;wÓ8ß½{—Åb™››?~üØÜÜ\*•^½zµ©©iÆŒjÊJLL|þüyKKË„ ÆŽ[VVöÉ'Ÿ ËŒmmm>DÂI*L0T=ûDgg'ƒÁŽ£å´ÝÝÝ]RR‚>Ÿ¢>FŽÂG8ÞáÐÞ]!¹çÁƒȆÒ[·nEGG›››?yòäÆü1~}ŽËå&$$(<ñ^,ÿïÿSÈ•¶´´üùçŸ1übîííëëãñxhʇà ÷÷÷«àgiɾÛÈnzæ»iLdP|Ü\ Üj[|ÐÐ7Fôáï ÒÓÓ™L¦\.ß¶mÛ;w`"FÛ¿?ü}þüy…1Ózzz”‘i’’’àaï qÿþý{÷îiùؘ°ÁÃ/DŸô7udá9D#ŸU„aÝ+Œ›û>þß7þðÎ ###%%E.—Ÿ8qâìÙ³0ñĉ0< ^UUÓ_½zõàÁÆb±>|Ï¡ÑhyyyOž<ÉË˃œJ49¿±±±°°Çã"a•UÇSÑ lðð6!2™ì_ÿúWoo¯졎,|oKÍþ×›Â[àö!ü|þðîA*•!ß€ììl*•ºÿ~tx¨cÇŽAnlFFl]är¹@ ‘H­­­L&366V.—ør¹œÅbÕÖÖ¦¥¥ÅÅÅÁÀ_0]uà[ v ï²>yCƒÊÂsˆtΓRêêêÆÆF˜RUUcUΞ=¦`B‡ë^aÜ\‚ðÿ6‚ð‡÷rTà[HÈGÎÊÀPƒôºhÑ"77·§OŸÂ§OŸîíí=wîÜ£GšššÂ-²fff&L°··‰DíííR©T&“! þVVV·oß^¹r%zý¢¬Ë5¡áV™>yCªeá9Dzcu9r¤¼¼<$$¤³³óêÕ«0¥««+00°··níÈÏÏg±XË–-ûðÃá^dðgÖ=ŸÏ¯®®.))AŸP„ÿÂÂÂü1>>>??M¥Ä”,.]º£ÝAÂ\\<\ 22 >ƒ'ü›ššB¿P(LHHÈÌÌDÔ¨áŸáï9ÚÛÛÿö·¿üüü.^¼¸s玿¿¿§§'“É”••!$¶gÏž¡ƒNž<¹¸¸xãÆÿýï1«ú 5J&“1™L6›=|»Åˆ½.Ã&“™½mÛ6ƒæææúúúââb‹µdÉØ×`³Ù………øÐ¡àÏ‘AF·Cp«AlÝ¡F·Ãà–ðÂÞöñ&ðmAAATTÔöíÛI$R[[[MMÍ…  ÉdòÕ«WÏž=‹Ž×ÞŒŒ¼¼¼ Fss3‹Å*--år¹ÕÕÕwïÞmlläñx¿-::ú÷ß=z4q"Ï óM½ÄvûaÇ;wfΜ GFF¾ûî;ô¶Hgg眜œ}ûöáC‡¢Y÷ ãæ¾E„„?¼Ïþ€|kff†>+póæMä÷¶mÛÐÿ:~ü8<ç îñ¥Óé0ýÑ£G€Y³f}öÙgx°“½½ý™3gÁªU«º»»g̘ÌF®X±]¬öaƒ‰&DÓkè࣠B,Ã|èP ë7÷-"ü üá}¶»–oMLLÆ™Ç`ëÖ­W¯^ݹs§±±1<¤ÙÆÆVVVîÚµ _û°ÁÄDÖ°#88øáÇHoîÎ;ëׯG÷ ™Læ† †Å0üñqs5 p«áHÑmNÜþ@øÃ;ý¾511 nooÇÿ‹ÃálÙ²Eû3íå†á¯At[9Aø'üð‡ƒøVƒ°ÁD2Ò1Âܾ„  ¬{1Ô[ˆÙꑎ°°0Ö××72EテaD  üá-…[~ 0k#F D"Ñ›Š ªZtww÷³gÏÐôL| Âx‡ñq¹œîþ'IEND®B`‚snd-16.1/pix/fmeq1.png0000644000076400007640000000110611147553267012663 0ustar bilbil‰PNG  IHDRj„Ž» 3PLTEÿÿÿààà°°°   pppðððPPP€€€@@@000ÐÐÐÀÀÀ``` CY¼ pHYs  šœtIME× /d†¦IDAT8ËU‹–„ U‘2Áòÿ¿vŸÍZ{f9'¨æ^žÆ(õ&HêŸÒ™4é7¼û:„1æÎ44ô‹\½}ciOu& 'kW]x]Ô5³øþ[´â¿2IrOï Úõ2??}xØabV¤Ç®µ1ºÃTBàìMí‡ñ!”æ3rcv¤jÖ`Ó¥„dœ¢””®ðž5¿ñjÞ||e.æÆìÈ(˜¤qK»£;èpnªFùå¨>ÈÇ`vdy™4äp &ðb‘rQd&ŸcT.Ë‘ôWa Õ=”«‰Uk{l4…Ê7écófÕsU!N¡rT%±®’ô!•ç+§[Ûsû°î¡<fGwY{’äÏŒòÚe³lvTîD!kËQ¡®¹Ž†¬5Ú ˜Ô) cM;Ïl'¸íL½À#EL¹àS¨>G|CZ—s §kå;Ãr)ˆ«½ä>vÅÄlH?Áë…v;¹µ¿Ù´P"Z0†~–H·5Ïü†'OvÁÄ0ô›8üâÿƒyÅ,G7þíHÿ÷¯±3±ë89 ÉVÒ€IEND®B`‚snd-16.1/pix/rksin.png0000644000076400007640000004162311147553270013002 0ustar bilbil‰PNG  IHDRÌ]„õôsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ  ºÔ IDATxÚíyXMÛÿÇßͳ¡PHDdHÕ×U¦N¦ %¥A ¥ÄnH™E™7dV!³(7×ÐÅ¥¢”&Rš'¥ýûÃÓù9Ouꜳ×ëyÎóÔ>kïuÞkí½?kü|(Š¢@ ›’" Ç HYY[ÿöíŠŠŠØ>@ |d@ž={†3f4ûÂùùùؽ{7¬­­áêêŠøøxRÚ@7†¿ÿþìL—øøø€Á` ((üñÎ;‡ÔÔTRâÀ'7• 99Ïž=ƒ³³3ÒÒÒˆ©ïæ8tè:„ôôt:t¾¾¾,inݺ…¡C‡"++‹yl×®]8rä:„Çc„ PSSãËB|ÿþ=úõë‡òòrZ·Â¾~ýJKÝoÞ¼ÁðáÃaooOKýþù'–,YBÛúŒŒÄÈ‘#±|ùrb@~EDDJJJPRRÂîÝ»¡¤¤EEE–4ãÆÃµk×н{wæ1%%%XXX@II zzz000àÛB|ñ↠Z>@wïÞŸqã ))IKýaaaÐÕÕ…°°0芀€èêÔâÎ;˜>}:-µ7yÇwêÔ©É¡EEÅ:Fˆò}!ÒÝLrr2iý¥;t誟¸2i£Ö0 „††’¡999(**‚ŠŠ ƇˆˆÚ>õ-œáwjç=”••¡©©‰ÈÈHb@-k}LŸ>·nÝ¢m9ØÙÙáĉ´Òüùóg@UU“&M£Gh[ÿ ,À… h¥¹vsô€ ££ƒþù‡B󩨨@AAXz#t!!!ÑÑј3gú÷ïÄÄDÚö@éÈ¿ÿþ‹ÂÂBèëë£oß¾´÷6A·{6ˆ‰‰Á¤I“Xz#úõ@ ºÝ Ä€Ú aaa ººšM럢(|ÿþ1 {hhh S§N'…AÞ½{ÇÜß5~üxáõëפ`ˆ!4‡³gÏbÑ¢E€^½zAVV111¤`hÂÕ«W1wî\?&RÐj( æææ´­ÿ[·nÁÐР¦¦†üü|dffBhááá˜8q"@NN222´šHôðð€‡‡Ë1:M$>}úcÇŽôìÙX<2ø›ÿý£GôíÛ%%%ÈËË#„Ð<~4£Û$ZNNzôèAë2 èzïÒJ~mmO›6 >¤µgV:/k566FPPy0hŠ……ˆ!´ŒÁƒ#>>ž+Q222ЫW/–cNNN8tèmë_]]ÑÑѴК––%%%–cnnnرc-ô/Z´¨Ž±5j^½zE›û8/jaaa˜0amõ»»»3£NÖ"%%…’’Zè¿wï¦L™BÛú_µjU€p222(..¦…þüü|téÒ…Öï@®1 7nÜ`qƒñþý{Œ3†« ïÊ•+pqq©÷;: ãÐ}®ãÌ™3ðññ!-)CçáZ€‹†°¦OŸŽ‹/2?ƒæê‚ûúõ+$%%!!!Qç»Áƒ#66–¶Ï­[·0cÆ ¾Öž““ƒ®]»BTT´Þú‹‹£íKåüùóX¸p!_kÌÊÊ‚‚‚B½ÏÀÀ‘@ H»v…„…!))Éü r÷ôLXX €>}úÔùnïÞ½X³f _ß8111èÓ§:wî\ç;111TTTðµþ[·ná·ß~C×®]iYÿ¯^½Â°aà &&VoýWVVòµþ‹/ÂØØ¸ÞD}KÛ‰!°W°‚‚¨©©á[}QQQèÛ·o½„úé^ÿ‘‘‘PWWo0L5¿ëolèªÖµ=†x‰iÕÕÕÈÊʪ·÷QK}Ìü·oßðåËôîÝ»Á4ëÖ­ƒ——_ꯨ¨@~~>sã`}-ð¥K—âÀ|©¿¬¬ ÅÅÅ——¯÷ûÎ;ÃÌÌ ÇŽãKýÅÅÅ(//g‰Àú3=zôÀôéÓáïïO ¡.¥¥¥ ãûqþ†ÈÏÏGdd$&OžLKýµ˜k=ÐŒŒ ¤¤¤@WW—–úSRR““mmmÚ¿ ‰i%%%––n4MmxW~ôL[ZZ ))©FÓhkk£¤¤ïß¿§¥~ÔÔÔðå~ ÒÒRHJJ6šF__?~ħOŸø²Ö”~QQQTUUñý0.1 -ÀÚÚ§OŸn4Íÿþ÷?ÀóçÏùN¿½½=Ž?Þh|ÿþeee|§ßÙÙ¹ÉÍ’“'OFzz:_PWWWìÝ»·Ñ4]ºtAyy9_.¦Ø¸q#¶oßÞhš¹sçâÅ‹HOO'„ÀJs'Ç qóæM¾Ò~åÊÌ›7¯YiŒŒLÛúŸ7o®\¹ÂWÚÏœ9Ãô>Ýt qû3‹-™3gˆ!ü?ì,Ñ=z4ß¹5xúô)~ûí·f¥ÕÑÑArr2¾|ùÂ7ú7oÞ OOÏf¥ýí·ßðôéS¾ªÿðððf{_ÐÓÓCll,_y§]½z5¼½½›•v„ xüø1_Õÿ—/_X†åˆaƒÌÌL³µÉÑÀÀ÷ïßç ýiii––®wïCCøúúbÙ²e|¡?%%ÕÕÕPQQiö9&Là›[‰‰‰PPPhrþïg¼¼¼àêêÊúããã!**Š~ýú5ûœ1cÆðM#"66{öìaÙãC ›(!!ÁÖ ´råJØØØàÎ;<¯?** ²²²PTT¤eý¿zõ ŠŠŠ ._­;;;ØØØðEKôÅ‹PQQ¬¬,-ëÿÉ“'PWWG§Nš}΢E‹`mmÈÈH¾è}êèè°xß „ <ggg¶Î…——Ï»¶¨¬¬„¿¿?–.]ÊÖy:u‚‰‰ vìØÁÓ»“‹ŠŠkkk¶ÎëÞ½;Ö­[ÇóQ ¿|ù‚°í¢¤wïÞÐÑÑÁxzEbFF"##1gζÎëß¿?–,YÂó“éIIIˆ­³ufˆ©S§6¹|ïW ¡¡ââbäææò¬þk×®aòäÉ-Ò¯¦¦†K—.ñt¤Æ0Œz}Ÿ5†   ´µµ™ÃŸ¼ÊíÛ·¡¯¯ßàÎó†ÂÈ‘#áççÇÓs!wïÞÅ„ Z¤ìرˆ‹‹ãéÔýû÷1nܸº®k(.EWW—244äšß£¯¯ßªóß½{G9;;S¼È¹s稞={¶êË—/§æÏŸOñ*­­ÿ7oÞP«W¯æIíþù'¥¢¢Òªk,\¸²³³£mý›˜˜P<©}ÿþý”ººz½ß‘H”””`×®]ضm[«®3tèPTWW#>>žç†n>|Øê(k@×®]ññãGžÒ_PPOOOìÛ·¯U×1bJJJxn(+??¡¡¡¸xñb«®ãïïèèh$''ó”þ¼¼<üñÇMî{jŠóçÏcýúõ<× ¯º ¬¿‡MLDãÄÅÅ¡°°¹1°5¸»»cîܹxóæ ÏèwuuEbb"[+êCDDnnn˜?>OEì{ùò%ÄÄÄ0|øðV_kÍš5Í^Ê TWWÃÉÉ ùùù­^8!""‚±cÇÂÜÜœ§\‡‡‡CII ýû÷oÕuDEEakk ???žÑ^ZZŠåË—CHH¨A¿_Ä€4ñ;v ööömr=YYYÌ™3¯^½â OÕÕÕˆŽŽÆéÓ§ë„.m òòò˜6mÞ¾}Ë3õùòe˜››·Éõ¡¢¢Â3Ëz+++ñéÓ'œ:uŠ­•g áéé ---žYPRXXˆððpµÉõTUUÑ©S'žY‘UXXˆÒÒR;v¬A¯Û:’––Fݾ}»ÞϰaÃ:t$55•;v,åààÐæ×^¼x1uõêU®÷LNN¦´µµ©òòò6¿öîÝ»©{÷îqµþÄÄDjäÈ‘¹¶‰‰ õàÁ®ÖŸ@-[¶Œ#×vww§žå*ý_¾|¡TUU©76kôŸHII¡&L˜ÐnË ïß¿O)**R×®]ãŠ2OJJ¢ÆŽK999µK~·nÝ¢LMM¹æ%š@éèèPkÖ¬i—ü®]»FÉËËSaaa\¡ÿÇ”¦¦&µqãÆvÉïÊ•+Ô‚ ¨¿ÿþ›k†m†Nmݺµ]ò;þ<¥¨¨È5Ãy111”ƒƒµk×®fŸC ÈO-I“&QVVVTqqq»å{ÿþ}jß¾}TPPP‡–w^^5~üxÊÖÖ–*++k×¼ûöíKÙÙÙQ ¦?;;›ÒÕÕ¥–-[FUVV¶[¾·nÝ¢öîÝKݹs§Cë?==3f åääDUWW·[¾”’’eggG¥§§w˜þÚ9¿U«Vµk¾ÁÁÁÔîÝ»;¼'–@5ŠŠˆˆ`ë<ÚÒÒRÊÕÕ•244¤9:lÑØCtäÈjذaTRR•ŸŸßny—””P+W®¤ŒŒŒ¨ÄÄÄv5ž?÷|6oÞL©ªªRÙÙÙíšwqq1åàà@ÍŸ?ŸJLLäè°MC”••Q{÷î¥FM%%%qtèðWŠŠŠ¨%K–PæææTbb"G‡m꣦¦†JLL¤Ö¬YCijjR999íšaa!eeeEÙØØP‰‰‰íÞxª}·nÝJéééQ_¾|i×¼ ¨ PöööTbb"Û‹f(Š;דêéé¡sçΧ‚>àÇðððh4Æw{àãデB\\~~~ ®½n+®]»†øøx$$$`Û¶mm²T³5xyyáË—/PUUÅœ9s8î´/00 HLLÄîÝ»;ÜIàöíÛyyy9r¤á¥“mÄåË—‘˜˜ˆ¤¤$x{{³å$S“ë0`ÌÌÌØòúÛ.\¸€¤¤$¤¤¤ààÁƒl»©ik6n܈ššôïßæææÿ=çÎCrr2RSSqôèÑ–-˜¡c$..Ž255¥zõêE=~ü˜«tgggS/^¤–-[Fùøøp$èèhÊÔÔ”òõõåºå”ÔÅ‹){{{êСCÉãõë×”©©)¥¤¤Äu“˜iiiÔÅ‹)[[[ÊÏÏ#y¼xñ‚255¥Nœ8A½xñ‚«ô§¤¤P/^¤lll¨'Np$'OžP¦¦¦Ô€¨—/_r•þÚyH###êôéÓÉ#,,Œ255¥üýý©×¯_·êZ\݉‹‹Ãˆ#““ƒ³gφ QQQ¶®õéÓ'äçç#00wïÞ…„„fÏž KKKtëÖ+—ÒàéÓ§ðññÁׯ_ñ×_† ÆŒ·Þ\RRRPXXðó󃸸86lØ€.]º°}­ö"??ÿý7:„¢¢"üùçŸ555 ±½,µ¨¨gΜÁÓ§O!""sssÌ›7k]“øðVVV––Fyy9Ž= PWW‡€€[×JLLDII Nž<‰W¯^aüøñX½z5ºvíÊvY¶_¿~Ž{÷pòäITUUáàÁƒ~¸„a—?¢´´¾¾¾ˆ‰‰€€–.] CCC¶bÛ´ÅÅň‹‹ƒ³³3¤¤¤@Q||| uuõ-K.++ÃÁƒ)S¦`Ù²e••… `ëvrðÄÖÞ½{‘••…û÷ïÃÈȈYéòòòõ®UOHH@HHKWM[[’’’X²d † ^b×®]øòå nß¾ 333ÈÈÈøá*ÛÔÔ´Nú¸¸8–=§OŸ†žžÄÄİlÙ2 8§ôoÛ¶ ùùù µµ5Ó#ª’’æÎ['}LL ˃'N`òäÉŠ+ ¬¬ÌSú=<â—@ Ä€@ B b@@ „@ ­k–ñÂ××—ùLL ÆŽKjˆ@ ¸Z{ã%BË!CX@ „@ Ä€@ B 1 @ „@ Ä€@ B 1 @ „@ Ä€ »žqÿûï?øùùº@g²sçNìÙ³§ÙNLLDpp0ºuë†ÔÔT“Ò&>¢É€Rååå8~ü8´µµñðáÃf_ØÅÅ—/_†„„ª««áîîŽ~ýúACCƒ”:@ ÐÁ€¢ÿþÐ××ÇÎ;›}áòòrHHHüÈDXEáû÷ï,i¢££qçÎzÏOOOGnn.¼¼¼H-`dd„AƒÕ5 NNNˆgI¼~ýzLœ83gÎd;#&ÓÈÊÊbäÈ‘õ~'--˜˜¬[·ŽÔ@ p***õà×è¶‚‚-_¤U_¤Ü_õîݽ{÷®÷ü·oߢ-¢íúûûCLL ,àhÁ.Z´ÞÞÞèÑ£Gó™2e îÝ»ÇÑí‘G{× ?Õ?§µ´×sÙžÏ??<—lÿ¦¦$''ƒÁ`€Á`àýû÷`0uZsqqqØ¿?ŠŠŠ˜ÇðæÍ0 xyyÁÎÎ={ölw¿ ..Þ.­ N·¤Û#i·®9ö¼PÿBBBáù<Ú»þÛãþjúgë7Qm1ND€¹¹9||| //O ƒ†Ì˜1W¯^府Ð>àÁƒ´ÓMv¢ޤK—.|ÓU&°¬¬l» a¸·þéÂ"épØØØ 99¹ÙçTUUaÿþý¤ð£¼¼œùÌþü¹ÙçáØ±cuŽ;880¯ÇŽ[(Òáq¾~ý wwwæ¦Æ={ö`ýúõèÕ«W£çåååaýúõÈÊÊ"% "77ÌgÞËË 6l€‚‚B£çåää`åÊ•Ĺsç˜Ç—.]ŠU«VAJJ ðòåKdffÂÑÑ‘ô@øãÇÃØØ}úôAŸ>}°uëV8995zNVV> R€\NXXJJJh£7)) Ge~ÈMð ÞÞÞ°²²b>󮮮ذaC£ç¤¦¦âðáÃX»vmïF¾}û2¯÷ñãG 8çˉ!**ŠùóçCEE…—€¯_¿ÒBkYY<æÇÏÏ………äFh‚¦kÄÄÄ`iiYïÈ„Ó7 §§'ÆŒƒÉ“'ó|™“Û¢e4µâFNNrrr¨¬¬$…Å””” ¨¨ xýú5`ذȧúgJKK‘ŸŸEEE±øˆSRRbº«IJJb1<šššDMM 3àÇ þýû·ø·øðªªªHHH@aa!zõêÕäðiCTUU!==sæÌa $÷iP;¼ÕÐ|Iii)|}}1iÒ$èêêò…fb@8Ô!p¹¹¹8}ú4ÄÄĘ­í'OžÔb Æû÷ï1jÔ((**âàÁƒ(--e~/!!+V ==W¯^EUU󻸸8XXXàüùóx÷î󸈈æÎ uuõýö    ´´ÕÕÕ‡­­-*++qåÊ–´²²²°··oö½…÷ïß“û¹ðõõ…ššôôôøF1 ÍÀÌÌ Û·o‡¾¾>€Ú6oÞÌ’fçÎHNNÆñãÇIq!ýúõHJJbýúõƒP…ŒŒ ØÚÚÂÈÈÐÖÖ„‡‡#44”ÅHˆ‹‹ãÕ«Wž?ÎrLVVcÆŒaþÿøñcܿ۷o¯Wû«W¯ ªª iiirCü‚´´t£Ïð¯eª££Ó`z¾,#b@´ATT´^w3âââèÖ­ÜÜÜ€èèhœgÎÌ›7¡¡¡Ì’ü)–j‚ŒŒ ÊÁÁrpp )ÊÙÙ™%͹sç(Tjj*óØçÏŸ)OOOÊÁÁruu¥^½zE±ƒ®®.ehhHñ"†††Tyy9óÿ””jÓ¦MÔºuë(~çÞ½{”——˱ÄÄDJOOЧèƒÁ`ù?>>žrss£<<<ø^ûµkרƒ²‹¥´´´¨ììlZÔ¿¾¾>ËÿÑÑÑÔúõ멲²2¾ÓÚ¤©¨¨ âââX>>|`ISXXHÅÅÅQß¾}c9ž——GÅÅÅQiiilÿ0^5 þþþT@@USSÃrüóçÏÔìÙ³©¼¼<¾~xvîÜI…††Ö9žM­X±‚ïõ:tˆºvíZãYYY”‘‘õõëW¾Ö¿~ýz*22²ÎñÌÌLÊÔÔ”ÊÏÏçký;vì¨÷þÏÈÈ œœœ¨‚‚¾ÒÛä–˜˜TUUY>ƒ bIÓ©S'¨ªªBDD„åxí²Ý_c óûøw—.]êÌõèÑgΜÁîÝ»‘À×ePßP§¼¼<<<<°gÏ$%%ñ­ö¼¼<ÈÉÉÕ9®  ///Ì;—ê›+íÙ³'äååáííôôt¾Õž““ƒ=zÔ9Þ«W/XZZÂÜÜYYYôœ!´ŽN:aĈ°²²B^^­^ ''‡AƒÁÊÊ EEE´«yyy())ÁÒÒ’e¾ 8pàäää`ii‰ªª*ZÝûÀ­RRR°´´$„P—ØØX¤§§³Äîo‚q̘1|Ù )//GMMM£ñµMMM¡¡¡9sæðþÈÈH€¶¶vƒ ˆ#GŽ`È!|Ù +--…  `£+Žììì ¬¬ŒùóçóþÐÐPôîÝC† i°uòäI(((ðM/”6¤ººß¿‡˜˜Xƒi$$$àíí‡"<<œ¯ôÇÄÄ ¸¸ÿûßÿL#))‰ƒbܸqˆˆˆà+ýß¾}ˆŠŠ6ªßÏÏ—/_ÆÓ§OùJÿóçÏ!##55µÓHIIáäÉ“:t(^¼xÁWú+++!((aá†wGHKKãìÙ³ðõõmp1 „&™?>lllðìÙ3ZtßÅÅÅ|ñµ„Y³fÁÚÚoß¾åMì7ýý÷ßq÷îÝF=Qð3 –––<¿¼ŸbÀ€عs'æÎË7óì¼@:uê„þýûcæÌ™xóæ íê_SSë֭Ô)ShÙ€••…¢¢"&OžLKoÝ'NIJeË0uêTžÖ! BÇXnAA˜™™¢(\½z‹/¦Õ ÌÌÌPUU…U«V5ÛË3?Õ¿­­-qîÜ9˜››Óª¶¶¶¨ªªÂš5khç²HHHÎÎÎE`` LLLH„À> ,€””Ž?ÎöÈmÔÔÔ°mD-Z[[[üõ×_<¯¿%ØØØ ²²çÎãyýE±]ÿööö˜5k[ŽZù‰%K– ''×®]#=BËü…ihh`ÆŒÈÏÏǺuëxV»››BCCÙ>oäÈ‘022ÂÀ¡««K»{FCC&&&(..n3Ç¥——† ‚áÇӪ…1|øp,\¸åååX°`éЕ̘1ƒíó „³gÏâĉ´,7555œ>}ší—·ñàÁƒF—p7f@üýýqøðažï´mmmœ:u !!!<«½ººÏŸ?‡žžÛçêêêâäɓػw/Ïé&¤ äI“Zt®ŽŽÔÔÔ`gg‡ŠŠ Ú•ÝØ±c1þ|8::ò¬Ó½þùcÇŽmѹãÆCÏž=áââB§ƒ?3iÒ$èëëcíÚµÌåмÄ÷ïßñßÿaôèÑ-:ßÀÀ¢¢¢Ø²e 1 „–Œøøxìß¿Ÿ'kÝý4oß¾ÅÑ£GiYÿׯ_Gdd$N:EËú>>ðôôDaa!í´kkk#$$ñññ\éµ›' ˆ¼¼X±b׎_¼xfff¹öСC!//gggTWWÓ²%&&ÆÕ«ò.\¸À±ú×ÒÒ¬]»––Â`0P]]MË F0mÚ4Ó2–8Ìž=Ÿ?æZÀQ—ìóæÍCJJ WO¨rÒ›°¹¹9bcc¹vBýܹs°°°àØõkƒq›~ž1 =zô@HHÌÍÍiÅLAAwïÞÅŽ;h€§W¯^xôè¦NŠøøx®üœ˜¨EQQøý÷ß¹6Š'õ÷éÓ/^¼ÀèÑ£i¹*±oß¾øûï¿áää„””b@ZŠ¡¡!ÌÍÍMË–¸½½=Ž;º2aÂXZZ"!!V-ðZ,,,pîÜ9Úõ@jÑÖÖ†µµ5ÒÒÒhwˆÀÐÐÁÁÁÄ€´”5kÖÀØØ111´ @¤¢¢eee„††r•~WW×vqGíááñãÇãÇ´4 ຠ†Ë–-ƒŸŸÇóÙ»w/ÔÕÕ‘œœLËú×ÓÓCqq1Þ¾}Ë5­®DWW—244lð{êúõë\õ› F»åehhHÝ»wk´›˜˜PíZÖááá\£ßÐÐ*//o·ü&NœHEDDÐòÞ§(Š7nõÏ?ÿÐV¿®®.õüùó×ͳÞx—.]Ê“XÚŠ+V`çδÕïââ‚mÛ¶qÕoâäÀ¯8::b×®]´­ÿ¥K—ÂÛÛ›¶úmll¸boÏlÙ²ÞÞÞ(//ïðßóåËtëÖ­Ýò›:u*V¯^-[¶Ð2•¡¡!\\\àëëË5+“ÚsHqΜ9077‡··7W`jïáT333Ìš5‹kçƒ8ͬY³ðìÙ3øùùuèÒnžŽ2aÂTUUáŸþáŠq{‚®Ø`ÙÞLŸ>[·nѸbƒ]{3pà@LŸ>G¥eì `ÕªU¸ÿ~»Qn`Ô¨QÐÔÔl·–‚üXˆêêêøï¿ÿàîîNËVÈ„ ðþýû›Píh´´´ððáCÚºú044Dxxx»6 ¸¥ ãÆÃ¥K—pèÐ!ZÖÿ¼yópåÊb@ZÓ »tébccQ\\LË›ÈÃÃ{öìAII í´«©©!88‘‘‘´ì…?¼Öº»»ÓR¿¦¦&nݺ…ÐÐP”••Ѳþýüü°jÕ*Žëä×TTT„ŸŸfÍš…ÔÔTÚÝ@}úô³³3æÌ™ƒôôtŽçÇm®õ•””°sçNÌŸ?¿C]=týúõƒ……ÌÍÍñùógŽæ‹!C†p•~eee¬[·VVV´ì‰0†††X²d G£¸ òs!ÊÊÊ¢_¿~\á+«#èÑ£zôèŽÏ‡pÓF-½{÷†´´4þûï?ZÖ¿~ý $$Äñ]úׯ_ÇìÙ³¹N¿ŠŠ *++i;fÈ!(((ÀŠ+ˆi ÒÒÒ8xð Þ½{GË0¸;wÆÑ£G!,,LË^˜¬¬,Ž?އ¶‹~n3¢Ý»wÇÉ“'QXXˆ¬¬,Zõ@a OŸ>K—.!;;›v÷ïÞ½€OŸ>q¬*Èï…(##ƒíÛ·cåÊ•ËãÇPRRb{÷|{ЩS'Ìž=³gÏFdd$-¨lmm9–Gtt4† AAî{œºtéèëëãÍ›7´ê?v©ïÝ»K–,áX¯^½‚¦¦&×6¢ ˆi –––8sæ G®ýôéS >:uâJíË–-ƒWÅRnoæÍ›‡«W¯räÚ¡¡¡?~}§OŸ¦¥þÑ£GãÓ§OÈÉÉ!¤¥\¹r‰‰‰ˆŽŽ¦åM´iÓ&œ|8²³³¹" rG0räH¤¤¤`É’%­®®1 ·nÝÂܹs™N‡§Ü°a mÃànݺ#GŽÄ‚ h©ßËË ´Ý¥~àÀÈÉÉaéÒ¥´Ôïçç%%%ÄÄÄÐR¿¿¿?ÊÊÊZKk ÈìÙ³qóæMægèСíò ÅãÇiymÛ¶ QQQ´uõâéé‰Û·oãÅ‹´­ÿÈÈH¼~ýºÕ×â¥y ZÜÝÝŒ¨¨(ÚÖÿßÿÝ*/´œ©EHH£G†­­--c©KKKcÕªU°¶¶nµ«^|HJJbÈ!°°°hÕ¤2/j€ž={ÂÊÊ fffm:Â+tíÚ}úôÁ¼yóhéµzàÀ˜9s&Œ[<”- šc``€Í›7ãéÓ§-Ž¥ÎK“¨¿PHHHàŸþAß¾}[|-^-ƒ9sæ 77Ož<Á¼yóØ>¿  ¥¥¥èÕ«Ïi««+$%%###ÚÕ¿µµ5 ðøñc²}~­§ßîÝ»óœvqqqxxx@JJ aaa˜2e é´„E‹áèÑ£øóÏ?i©ßÆÆE᯿þ¢¥~{{{lÙ²lŸ›––†ÜÜ\hhhð¬~GGGäææâÒ¥K´¬¬\¹lŸ[ëéWUU•gõ»ºº">>7nÜ ¤¥üõ×_صk._¾L›!ŒŸ™8q"^¾|Év®ªª*|ûö ÒÒÒ<­ÿĉؼy3GýEq3zzzxõêÛK;+++QSSIIIžÖïç燵k×Òv>p̘1øï¿ÿPQQA HK:t(.\¸€?Òr<´W¯^077Ç‘#GØŠ’’’‚>´¨ûËMèèèàÔ©Sxûö--—6«ªªbÊ”)8zô(¾ÿÞìó¢¢¢P\\Œß~û§õ3 =zÏž=£åûoôèÑÀ¶—b@~B[[“'OfËÕCnn.bcc¡««Ëóúûí7DGGÃÕÕ•–õ?~üxŒ7Û¶m£¥~}}}<~üîîî´Ô?eÊÜ»w[·n¥¥þyóæáæÍ›Øµk1 ­±Ä¯^½bN®5EYYrss¡¤¤Äú?ލ¨(lذ¶]ùû÷ïÃÑÑ‘íá<~àâÅ‹¸}û6vïÞMËú Â… °ÿ~Úi:t(?~Œ¸¸¸f»:!¤Ο?ÌÌL<|ø°Yéùa¤)))\¾|ÂÂÂHJJ¢eý_½z111´ À%--àà`TTT ==vúeddpýúuÒ2Š¡œœÖ­[??¿fÅ’'¤ºu놓'O"<<¼Y“мº„±!°xñbìÙ³‡–®.áïïOÛUIýúõÚz)8p ,X€-[¶ÐRm,ub@ZJŸ>}pàÀ4ÚÿðáÌwúûöí‹.]ºðüäxKQVV†ŒŒ ´µµñéÓ§Ó%&&BEE…ïôoÚ´ êêê˜={v£é6lØÀ÷ðÍ AƒðíÛ7Lœ8™™™ ¦KIIiÕþ)neïÞ½èÒ¥ -ZD HK„¶¶v£ûC¼¼¼ZíO†[Ù¹s' 6mÚÔàNõ®çÙ¼½½1lØ0œ?¾Á4GŽ££#_ÞûÀ¨Q£°iÓ¦=×ÔÔpe,ø¶àÈ‘#PPPÀõë×Lãïïkkk¾¬ÿcÇŽAEE›6mjÐs11 M°mÛ6téÒ…¶Ëûœœœ››Û`/ìÎ;˜6mßêß¿?¾}ûFKIÂÂÂprrBjjjƒó!ü4ÿ÷+bbb8räÒÒÒê [YY qqq¾Õ/%%GGG¼ÿ¾Áùb@š@ZZëÖ­ÃíÛ·‚?2¿‹ŽŽÆðáÃùZ¿ŒŒ |}}ZÇéà›7o0bľÖß¹sg¸»»ãÂ…  AJJ ó»×¯_CSS“¯õwíÚgΜÁåË—ë8]|ùò%sÿ¿"++‹;vÀ××!!!,1tLLLpõêU¾Öß­[7âèÑ£õÇO¢ØàÈ‘#ì$§œ‘žžEEEŽæQYY‰¢¢"ŽÆ8hŠ¢(*""‚/žËòòr®[XÔ&Ëx#""0wî\äææ2YXXàܹs~¸|–””äË»BCC´¿ß_MŽ·$''ÃÎÎÀUH ¢¢¢¸}û63Mii)RSSQ]]Í<¶hÑ"œ9s êêêØ¹s'ÄÄÄÚ] œœ\»­’j niØ]v@Ÿ>}x>——GçÎÛ¥þÛÃ'Ú Aƒ8ž‡´´4zöìÉóy?â¾óz°³Ÿß/ÜÖoÖ2^BÓ˜››ÃÇÇòòò¤0hÈŒ3Ø!$BÇóëªSº@v¢<Ô!ˆáC†J› …„º¨««ó­SABÓ°»Í_ CX@ =NR^^ƒƒ·oß6û¼ÂÂBüþûï¤ #77—ùÌÿìDµ)233±yóf–c˜={6óz¿ÿþ;¾}ûÆóe$Ln“¦IHHÀ¾}û˜n\ÜÜÜPYYÙä˸¸8x{{#++‹"ÀC¼ÿ~~~ÌgÞÕÕ .„††F£çÅÄÄ`ÇŽuVdZXXàÌ™3Ì¡¡¡ðññÁúõëI„ß „‰‰ óÿuëÖa÷îÝž“””„K—.ÁÍÍ —sþüyäçç·èÜ 6 ((ˆ§ô¾}ûÎÎÎÌÏË—/ÉMð gÏže‰Æçää„C‡5zλwïŒ7ÖùÎÖÖ–e7|hh( H„P? pppภBëyøð!tuuѵkW¶Ïµ²²j·}&mAqq18WWWæ±ýû÷CYY™ãnEx v÷uõíÛŽŽŽ¨ªªªó]mе’’lذ¿ÿþ;”””ˆ!Ô¤¤$$%%QYYI ƒ ÈÉÉAvv6KˆÚ™3g¢K—.uÒæååáÓ§OÐÐÐ@VV‹jæf¾'Ož 99C† aÙÿŠ!C†àÑ£G~ÄW×ÕÕmño ƒÁÀ£G‘‘#F@]]½Eת©©Aaa!† ‚ƒƒagg‡ššÔÔÔÔ; yøðaxxx0ëÛËË‹™¾¦¦§OŸFvv6óžøôéÓeO-Û¶mƒóœ§OŸ"""¢Å¿ûÓ§O°¶¶Æ›7oPSSƒàà`ÄÇÇãíÛ·°¶¶fù¬[·Ž­kGDDÐ6\s{ãååCCC 6Œo4‘H3ptt’‰´ÜûIDATÄÆ™Þ6>Œãdz¤qrrB\\s7jyy9RSSñíÛ7””” ..ÂÂÂÄXÑ£GÀ¬Y³`dd,¡ž={†Å‹ÃÉÉ óçÏg¦ÏÌÌÄÒ¥K™éƇnݺø³¦K—.8uêëC%, 777æÐùóç‘==½ýv---<{ö ÇáÇQ\\ŒaÆaÛ¶muòn XZZ‚Á`05ð{Xâ–°~ýzlÚ´ 222€#GŽÀÛÛ›%••Š‹‹™s`%%%HOOG^^ŠŠŠQQQôïßööö011¤¤$âââÝ»wçùaCb@šŒŒ 8€+Vø±"ã׊5j‹oŸÌÌL>| ¦¦†Ã‡CFF;wî$ÚÔ¾ü0_üE!44ÆÆÆPSScزe Ëä©‚‚V¬XQïÐW-uîÖúI“––†¸¸80ïÃÔÔÔ:׺téssó†‡1{ölÌž=›y¬±ôt¥sçÎØ½{7s®ÈÝݽÎÙÿþ÷?TTT0ÿOIIŸŸ€ó!‡F=àîîmmm„„„°œ?kÖ,Lž<™ºPkêÃÚÚšåÿ4šžÀ]¬Zµ >|À¡C‡ ** ///À… XêÑÁÁ999æ`aa©S§Â¢Å×C¯^½êšŸ B@@@ƒ+Å>|ˆQ£FµZ?"!!Ñè3¼|ùr–ÿkŠõ±dɾ,#b@´¡W¯^Ì!‰ŸQVV†¬¬,Œ1uêTÄÆÆâäÉ“°µµenüªeéÒ¥ÌaÈ;v 44ß¾}ƒÁÀíÛ·!** UUU–ëËÉÉÕÙ4–ÐloÄõNº*((ÀØØ¸Ñs‹‹‹‘žžÎr,""žžž}}}¬Y³†6qí m qeB tÿþû/‚‚‚È&§!«°„ ¶‡C ð2ÿ,J!‹æ–|mIEND®B`‚snd-16.1/pix/fmeq22.png0000644000076400007640000000326111147553267012752 0ustar bilbil‰PNG  IHDRñ-‰g¢¯3PLTEÿÿÿààà°°°   pppðððPPP€€€@@@000ÐÐÐÀÀÀ``` CY¼ pHYs  šœtIMEעɉñIDATxÚí\ “³* 1ŠÂÿÿµ——Ê# íî7³·%3­Û'É @·Ãð}B— ›º|ƒ)'2 c'ã+DØ7;Êý_]>^ˆ 4Ÿf3Òi'ãKò¸Iá_%ë³z—.]ºtéҥ˟¥ÔzÉ®¬ôåÛ'‹VJÇŸ9]ÕÚiùdY”ÊŽVÅL:-A€ÿ1<þÃrkì6ÈZM/šÍzúÏýýmD`Ï‘sBá—ð|*ÒC±±n0‡vùe©R2û*OäĺBR³coÕø&üåK£¿5]- žÞeH ½„¸ÉRÆãgZŸà5@2dã±AïTœÂ¬Õè ¹ÎØÁ;5¾ü‰1†%vÞnYòôC7EM’Ûãìz[¼.Ç'xh„ÊLƒ5½×Á# øÃŸ «MÝfîi)ÌŽ¼Q#Ø¿‘í[ënNP„Òs¶Dxz¡¥ElWDJŽˆ¢/âå *ظ¬:‹àê]”W…˜T~×)tavâ`[oÒð7²TÛ¨Ñs¶DyºaˆŒ#ñî.‚›³a¸! ç(Ìê‚0j;:A-:ŠW‚^¨Ú&…9ë»ÓˆûCuQÞHJµ)\ëùÓìÄÁCMƒ¹º¿‰í£ñR\Þç¢ =gK”§6CÔ¬LP¨´7•ÌÕ\L{áútXŠiugÓhÄGDNà7¹šD¦•zçQ¼ôBµC¾•Ò ëíeBŽYy+=*Õ¼3îgp?ý,ˆƒ‡šsuÛM2Ö0éZE£¨BÏÙå©ÉØUÊÂÜeÂŽL›lv¸ºÜ†d\–p$„ ¡ë±ºÝîà³L/=QAIÆäœÏÿk©ž˜qG p–ÛayŒa“ÊáYg q0¨i1×ô7¢n&Öj"Œž«%ÊS“!jA ÐÝU’BIM‹mÏãcÔ8¤Gåñyd9á7@ÂG|#^à%iè™ß¥ñ-㩃b½(ÙkùQ7nã"­"”ž³%ÎS“!êTùžJCr©Ê¾l÷ÑǼ²Ž×æKÑ_Dq¯½"¾bñ Z‘ur~ÍêXh¡º'—Æa3vêà‘¤̵ü¨3ÉØΡVÑâ¡ôœ-qžÚ mÜEÉõ“0{YBùÛÁYO&¡]J¡HÄÃfuó_ˆ4â¡LÓ8Ú¥P z¢’ÕopâŠ×K–xÖzyyKÖê&ÒdI;¨FFÄr’™:x¨i0WᯰÝ,w¤ùˆã¡ôœ-qžÚ [ÈîbÓ´õdwŽî”Íûd»<ØÝÊi¹l$lÛÍ`šdX~x±Ì¦š7Âæ…æx£eÄL3“HA£N nxÆM0ÞÎ5P‡|t-ë'›‚ Ú•Nztǯ;âࡦÁ\…¿ÜöÙ-x…¯§çh‰ótÇñ‡îÇ €Ém1Á¿Îí¯mðã9½‡â š| Ù’£ËØðm\q@Ï"J|©[Iâ­U$$n}™],íÎÚUæ*üåÇLöEªÄ4è9[¢<½ÅI‚²²óâMÆÏÎD†S1å • 'XgEJÑŠ´t¬uÀüä`Τq)xiö5¾I‹?Ò>±Cý½kYú2Cš'·ƒ„øáÓÝ žík‹™Íôí!YTdë&A½<Ý™­yÀ±J1™YZ”f?R㛼Éßïڽ̓áWåÇxº@nÊ“º{A:½hö½ßäŸùûºY"ÐiéÒ¥K—.]ºtùSBdÿ™Ÿ/“¾íþ2þ…_&á ‡Búo»}ª¸' º\Þý·Ý>7ëô™/¤ÿ¶Û§q)x9Æûo»}ª\O8äyüë~Ûí?/ŸBh¨åb\IEND®B`‚snd-16.1/pix/4grfs.png0000644000076400007640000001562511147553266012711 0ustar bilbil‰PNG  IHDR¨°¤[H÷sRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØÐ+aIDATxÚíÝÙŽ«:@ÑòÿÿËî§´—Á6<¬%µúÜT*΀w $Äã|ìŸ!@ €@@ ÀBø !Öà5Ë(+2C Í°øhn/8Ôæí…Ë/ZÏÂf”ðp@ïœ$é¯CdgÞ{ÚÓýÔj‘Úb¥ÆiÏ7Ã:5yÏcŒ±¹ÊÝsÚ[ÀýÞy€4‹!¸ ¯­-=¬w½ü-|ç°eŸ¹:U¤®CêÍØ«ñ÷~¿Ûb¨ÖZ¦^B¨Õcu{Xií(z"¶ö–ý‹˜{êï·â€@}Â÷bòT´ŠW¨ÆäFhÊãIÄ€@…Oã5'bE-Th"bkD­À@ MDmÍÀ½T Ù˜|óóÛb 4-ÌL,T@ 7¡Ç3‹j@ ˆeQí>*³œï³ðÔ¤ ÃÞFñ7‘Øþìèò« ‰ /€CÀ{LÔìá:ZSþ¿)×±„7ð¼‚I5ÆØÄ‹³  ^0ÇÄëϺ÷Älm@R–Ç "€ŒÒ6WϱÅ ï°Å¿/ß°‡€Ÿâ“$mO`´þljÊågï 8‹/À|B¸….@?þ*T*T*XFY‘ßWÊäþ €÷œ} è2òJ S€~,£¯àY¿)„Ð̲´¶<ÆÆØ÷•±16ÆÆ}elŒåq_ýýù *¨T¨/ké˜vcclŒñ16cclŒ±1>*.„èp`*† ÔÂ_á±ë@ sÞœ¹m­ËÍ©¨™OÔã_Œ1é ’{}h9N÷æ¶µ.7§F @£“Ã/&a5örô´¾À>ç4E ÿµ¯öìMJŸž¨Ú3À—C@/¡¸ µ_Lmãêwݽë¤ÜþÑõïÜÎÞò§\?5H¯n¿$l×·±×’õ=º¿Žn'÷ïžÝ>õóIŒÀ8¯ë¹¯éë ºúý«Ð͉ܣÛÙûý³ ÊÙƒY+ÄÎÖw“WoœÅjÎ8äü]Àœú©£wUk]€ö^ïß| ÏÙ[cùKÿÎÙíçÜæÙúÝf­ûåÎòÛ¦3K(nŸŸGsÛZ—›S#P 7Ê9*O"€þ_ïöðõ¼üg—ß¹ý§'‘¥·{tHrém­?7[ëhy¾{õ³—›S#P #fö>oZ:ù«±'ðèvR–/2÷¢uïòš±Wc}î‹£û+wü¯ö‹S€Ž·ùÑ+8ðð oM7Ä)@ß|Í „hãµÜTZ`******u+„ðBxìúԤ،1þÅ“¢3÷úŒaéuÁsâ5ƸÁ=a¬#0D ¦„‹=°ýp’$æT'B`íñC|×';J9,7÷úÔ¬HM¹,ågŒÉgP¨ P¨Ôá,È€@€Ê–QV$uo¢½ŽýݯÎê µ+{#Fúá_*L¨1F‡ÿTîšáÄANŽ**T*ü,£¬ˆï5¨MØûÎLÑ Ð‡øvå"¨ PË„v¦]ö€@ €@ €@Ž“ïTnØž‰xÄÐv¶e¨S…ý°·æ°Œ ¥á#\¾7ÌÔãþ—©½DøÞz´‡q†uÔ’è@ 6¥‡½sW‘=ÂÆÖ¨É‘Úb¥îî9àfXGࢠâÀǾþB&wK¯¥åïén-Y^‡mÀxCð_¿ðù2TïØz/cËwg{YG@ >ªÛËŸ ¶c½ì-\åjá@ ~ª{!y7(kFéѲ?ý7JÖ·ærU¨‚õ"ZKoëÉåý"Vßú›{{¼Å*TÑÚÁrÖÜ|ëoÍ×AT*Du¯pi)ßr@ V+ƶœ ® P_‰¸ ѳǎx Ÿ‡ëU¼ Y¨ÐD¼–„¬  M„liÐ \*ÐDÐÖ\Ñ €@šÉ·N4&„¨@áØÂ·E2€@h"{ùZ*! T‘Ü„¿ßYt·5„°;¡øMœ¶?;ºüjfÒ0~ÌÝî_x)P&ëhMùwJü¦\Q&Öñ˜4PcŒMl@mÄR˜3x>êÞ yk/)Ëcƒ>™Çáõ@ ºã Ëí?·—¯^|€âˆïŸ$i{£õgSS.?{ЈW€ù„8p ]€~ü3T¨T¨T¨´leE~ßyšû3Þc?P÷VR˜ôc}ÏêüM!„f–¥µå16ÆÆØ¸¯Œ±16î+ccl,ûêïÏgPh„@@ €@}YKÇ´cclŒ±ÁØcclŒñ¨ P¨p!D€Ð{P¨0L †þB]Z˜óæÌmk]nN@Í|¢ÆÿbŒIOÜë@Ëqº7·­u¹95>œÞhµ:Q³§ú朦T0&¼íé ‹!`Ä(;ŠÏõÏ®¢ôw{ÿ}ô7Žnïò’åü]^Ôë¿»Öœ¿»þYêø”þݳÛ@ v71±˜×^ØÔ ž³ß;ºýœËk.çÑïocòìïî]~'ìSÿ.`N@ínò‘óÄɽ>\mOR·)¹‡×Ý~Îök/þ®n3w½žX~ÛhØ>mŸÏGsÛZ—›S#P ' 96O"Joob¸ž<žm_r÷@žm¯žž–ÞîÙáÊ%·µþÜìYhÃ,¯E¹?«q¹95*ÙÛƒw¶çójÅÕç1SB·Ær¾äW˳wý£—ŒÏÕø0ðö;zÅ`À8­µy{2Žz ¯7—[œÌÅ×Ì€82þ´ñÚo*-°     Mjá/„ðØõ¨I±cü‹1&EgîõÃÒë‚çÄkŒq7‚{6Â:XG`ˆ@M {`úá$ĮN„ÀÚã‡ø®Ov”rXnîõ¨Y‘šrYÊϓϠ P@  P©ÃY •-£¬HêÞD{û»_ÕjWö"FŒôÃ!¾T˜:PcŒÿ¨Ü5Ƀœ *T*T¨TøYFYßk P›°÷™¢ ñí<ÊE8 P@ – !ì ¼½NémSŸ½Ä Py1š¨T¨SsX1 Pâä;•¶g"~3´ßü;Wg[ê0awv{VÛâ>€9,#hiøØ[ð½aö Æÿó¿œH½Ç%·“û{G1=ÒÆÖq6¥÷ÛûûíÇJOë8úïYG¨ÝFô(=MÞg¸Ák•絚öÎ]Evê:|ñ9Û»{ˆKî'“)€ùBÚë8€@*R[Ý@§îîù0ØÖ€ñ¢Ø!Þ0ïóÑsQ >Ÿëëµò€Ë=<ù©€{jÏk¡™u“~oÆU 6´¿úêAð‹¶’=»_/{ê“ééuôÂ6ì€ç›× ëO_A,P3Bµ4úr~§dâÕ²ýdØ[—Úë¸^O'Åbô ´É¢±ƒ™ŸÿBÓëc?N×Bwü*š~·Y;¬Z;ö‰õüÝVͯ *Y¾·Ãx„ïe¬qxÌÁ¼ÏÏx—@­¬Wñzt8êïvž~Ñkå³µO¿À× Õ;aûfϰñnilD˜åñ¸1v¸ÿ­ŸõG ®­< ×Q|Tw÷hEú×ë8Ê áV½½—ø‹)ü„F¿ËÓÓv¨§#šF8úÊaÚ•Ìh¾zÒœí%n-¯ö ˜ç£ø©¿W{CS¶W¿wuyéz<±¬­¼±ÑãæÍß3±@ v2æÙp½ó³V×ËãæûÀµ~ï‹¿ùÔï]={{ïÿà¹Át*>¨õ¸¹šlz‘êÿ…߯o”ý^‡ø{ýƒþ_«Ìoæækfà BþwöµCw¾Ž¨æ ô›/îw'½o¾àϲ±èiãþæ^Ræ˜Ô½½×¾—×\°=2n&Š×½Ë·!{¶¹/Pµ'(&=Ʀd£øö_ÞžÔz{ü÷œ*ÙÞ~±O-O/÷ÿÕ˜!\Ÿz¼ Tx1dÏÂv°ë³"Ÿí™Ý^.4ÇÛ¯¾.‰úâ¹Xÿ1îM†÷ÖñîkC+×âkÜ›Ï^N7Û<±ä10úQ"Îâ M½P¥\vôó£xu¢6ëWÉØèã1B¹³ qêIÂro÷Éuk%ÔZ|ãËkθۯö. T4p4lïüìì„U³nøJ¿‚Ä÷ÀŽq¿÷rz¬ÍûšÓZ,µôܹ轌Û×gjoý¤m”¨@rÀ>ñDëC™k„ïÕ^唟µ4Y˜ýqh2áþwÿ{ÍVž#oýž@˜4Š[ ┟ÙÀ1Ò¤èÎތֹtÿ·§ÆÛc¼­×ªZ¿—zÿÌ|? T€ƒ8õg%gž¬Ó#ì•6™j/4{›^¾¯ÙžÐv"d¤åaì×ñ_ÿ—; t49Ùû@ûÕDìÎõf çVczïgGÚ«ðÞÏS‚¹ô³Ô_ý^Îöñ©m£½.Ƙ;ˆ[y½ZJVâêE8åß)/æ^ØÆ 씟ý|”߻ڶ–„ÿÞ﮿Újï÷Î.OYž7ö¼_}‡ô“‡Y>q¸eÊ™jGžùœ±í‚ûŸ*ÚÊ.g‡/0r¼§LÚÞŒé/>¾ÝÞ¯¯ßÒgɯ¢ÿΗÙõ¹÷;?ÛÞO9ëŸ{fV6Ö: Öû}ÔÒø•>Æ—Ô'|k–;ïHýÆûß{*¦k¿YÐÊÏR>vuôÑ®”Ÿí=¾ŠÛÒ7(Þþ*µÜ@ÿzyJ~¯•u,ùÌöˆñ9Bä‡X°g‡£¤þ;å¶ï°Ï²@‡‘rã°ú£74®Þ9 ð³ .ý½Ü7îœ!eYs×ãîïY¾|ЉG 7bJ~ÏQm­µ@ý…åö]uA§\~¶â`>E‡øv³rB ÿ ***-[FY‘ßwžæþ €÷ÄÇÔ½•¦ýXF_Á³:S¡™eimyŒ±16î+cclŒûÊØËã¾úûóT!P¨ P_ÖÒ1íÆÆØãcl06ÆÆØcc|*T*\Ñà4ÀT* ¨!„¿Âc×€æ¼9sÛZ—›S#P3Ÿ¨1Æ¿cÒ$÷úÐrœîÍmk]nN@€'‘-,—I$ôË9M¨À0ÑlO½X £FÙÞ¯#m}YÎõ·—ooëêú{×M¹þúò’=*ÛõÝ»­œõ-çÔ¿{vûÔ®&&¥oÆ–šÛֺܜZ©96O"Áºô­Cnoxµ=)Ù[iOO Ko÷ìpåÒûéì~™”Ìmk\nN@€J“¹½°9;QÐQœæ~vô춯ÂîÎÚšãvµ<{×?úwÉøìÝ&ÃsÑ+>|³î4¼Þ\nq 0_3xÚxí·€؃ €@ €@ €@ €@ €@€¦5„ðBxìúԤ،1þÅ“¢3÷úŒaéuÁsâ5ƸÁ=a¬#0D ¦„‹=°ýp’$æT'B`íñC|×';J9,7÷úÔ¬HM¹,ågŒÉgP¨ P¨Ôá,È€@€Ê–QV$uo¢½ŽýݯÎê µ+{#Fúá_*L¨1F‡ÿTîšáÄANŽ**T*ü,£¬ˆï5¨MØûÎLÑ Ð‡øvå"¨ PË„v¦]ö€@ €@ €@Ž“ïTnØž‰xÄÐv¶e¨S…ý°·æ°Œ ¥áÓ{¸Ž²ol+¼V€@}%ÒjD«‰U›ë(ÂÀœß‡øž½Žrø¨Ã`:€ânæ½§"ꔑÚb¥ÆiÏ7Ã:5yÏcŒ±¹ÊÝsÚ[ÀýÞy€4‹!¸ ¯­-=¬w½ü-|ç°e'M:U¤®CêÍØ«ñ÷~¿Ûb¨ÖZ¦^B¨Õcu{Xií(z"¶ö–ý‹˜{êï·â_pt‰û@ Nª{ÑU_o…ãÞá'ÿî£ÅjÁz­¹·ÑBh?16o¯›X€vÙK Ô¢Õ2¿^oïÑLŠ€‰Õ׎áG“V?Lm/@ ¾ ¢•ÜÇËÕcF¼À}Þ,¦Tx2\¯âUÄ€@…&â5'bE-ð4Ÿ³íÿþ¨À+[{"b lÃTàŒ±=ñF P.¢¶fàÖX&“(“m<x5pkDï=6#lôl¼Ás 4½¥“ÉÖE¼³&Ô n¨Àd1üôä¶dB¯Çvégžßü=šT€—ƒù‹‰ô˜~ë÷¾¸/ÄÒazçñæþ¯Ö}²@=º£~“íÏŽ.¿šty0´Óo¿&?Ä%ñÓê™qЬ~ÜòÞäÝ™Š=§ÓUõ躔§ ¬-ÞÊm·¸=:Ú&M({šhÖØ‹úÆã§öaówç>_Ìì]‹–Õýlý¾ ÔV6nÞÉ@ÄÇìŸõ4Éjuoÿzòôaó­ïí¯ñüÖO–w5y/™Ü"µl¼zêŽîã%õ…¢µMY <=y*¤{9ÿÎßëáÈ„³@) ô¯>×çÍ„ÙçÕ-¬Ê%¹Ë¹þ½'Žê¨¨ÞYÀ×sãžN®×Ó²¶þ˜h9’k¾ ñÄ›)Wã¹|=Àbà~(?ñ&D{PSÂr»»w]×)—Ÿ €x˜OˆW ÐèÇ?C€@ €@ €@ @Ë–QVä÷§¹?à=1Æñuo%…)@?–ÑWð¬ÎßBhfYZ[cclŒûÊØcã¾26ÆÆò¸¯þþ|€FT*Ô—µtL»±16ÆÆøŒ±16ÆÆØ  Bt8 ° Ãjá/„ðØõ …9oÎܶÖåæÔÔÌ'jŒñ/Ƙôɽ>´§{sÛZ—›S#Pàæ„-çzµöÔ¸¯'yö†@»œÓ &}ÓLí  ‹! ·˜ÚþûˆëŸ­£ñèò”¿q'>ï,Ï/ÿ¿wùQ$oÇ¥$¶·'eù÷–éhùn'÷ïžÝ>µ©É‹ ÀxŽÂd/f~ÿ0©Axµ9»«åI¬aö[¯«åH æ³XMŸÜ¿ ˜S#P›š¤äƒûæd1u½Žî§£u¹Zþ³ë‹S€q„èÕúÛ€7do.Ÿ8‡¯™„:m¼®Ûƒ @ þ‹ä.@~ÞohIEND®B`‚snd-16.1/pix/crosswave.png0000644000076400007640000004376311147553266013704 0ustar bilbil‰PNG  IHDRöøeÑ?sRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ _ê& IDATxÚìÝwXWûðñ/U@E»ˆ Kìb#TÜ (`' ŠÆ^c±7PÄšh¢T,`oÑD,±KÄ.¨€  ˆÀ¾ø2?W0¨Ëý¹®½`î™svfØ›3åF£A!„È&]ÙB!>HILLäÆo½‚˜˜<ÈåË—ek !Ä—œ@&L˜ÀÏ?ÿüVo~ðà+V¬àäÉ“.[T!¾ú¯¶</^LÍš5¹téÒ[½yôèÑÌž=›B… ——kÖ¬‘­*„_R¹ÿ> 4ÀÌÌì­ÈÇ)T¨¦¦¦ÄÇÇgZÆÏÏGeùþ²eËâææ&{ᆑ‘VVV²1„À+§°Ê”)CÆ ?xMš4¡M›6™^¡¡¡üöÛoŸü|øðáq œ>}:Ë,FŒñI®Y³fqÿþ}ù&â}Z 9¥J•*YÆÍÍ͉‹‹ûä7àwß}Gppð{]»ví“®TT/^¼o!Þ§’––Fbb"III¼xñ‚ÄÄDRRR´n×®[·nU¦ûõëÇòåËILLdçÎ888Èý“&Mú$êùüùsÙYB|ééé$&&fú>}þü¹Ïx/))‰ÄÄDž={öÁÊÏø.OLL$---Óü¬ÊÌX>99ù_?ƒV¹zõ*øøøƒ‡‡þþþZ «T*Œ•éÖ­[S²dI<<<ˆŽŽÆÃÃCŽ˜öIÔ³K—.²³²púôidCˆ·ˆ‡‡Ý»w§m۶ܹs‡›7oÒ¬Y3¾ûî;jÔ¨Áºuë £V­ZxxxP¥Jþþûï÷.;!!Þ½{£V«±··gÔ¨Q™–iܸ1ʼݻwS¹re<<¤¿ÿþ;Ë&³_’† ÁŽ;¨Y³&öööÔ«W===jÖ¬©œÕɸ‰éCÞÌT±bET*_}õÅ‹ך÷üùsüüüèÖ­Ož<@OOOI\õ077§R¥JäË—[[[­uHBˆ´víZzöìIÁ‚ÑÕýx¾rûôéCPP :ôÖ! D¼—K—.1sæLÙB¼Á!C¸ví÷ïßçÏ?ÿü¨êfnnŽ¿¿?÷îÝ“"r_jjª\Xâ æÎËáÇ111aûöíÊ]Lk×®åÅ‹„„„ðôéS¥ٛǡC‡¸~ý:§NâÂ… ZóvìØÁÇ9~ü8-[¶^ÞµµvíZ­zÄÄÄpàÀ>|ÈöíÛµÖ¡/»X!rF­Zµ?~< ¤R¥J4lØ´´4öíÛG§N¸wï‹/¦T©RôêÕ µZM\\ëÖ­{ï²K•*…““žžž¼xñ‚qãÆqìØ1f̘Áï¿ÿιsçðóó£eË–xzz/o~qsscíÚµãêêÊW_}ÅĉÉŸ??µjÕ¢víÚ’@„"§5k֌ÇgŠgÕaíëÿÝ¿/CCCFÍèÑ£µâ>g5¯|ùò?~\+–Ñ{HVä–Bˆw" D!„$!„øØ¬[·Ž: V«9{ö,†Y³f¡V«qtt$66–ôôt €Z­ÆÕÕõƒ))‰öíÛ£V«™0aééé\ºt GGGÔj5+V¬àÕQÐåˆBä§OŸrùòeæÏŸO¹r倗w`mÞ¼™ƒ²zõj:uê„ñññ3fÌúöíËÊ•+ß«ìÈÈHÆŽKHHwïÞ¥sçÎܺuK™¿fÍüýý©S§Žëر#-[¶dÈ!´hÑ‚¥K—²dÉ&OžLÆ iÕªVVVØÙÙI D!rRTTAAA,X°@+>dÈ éÓ§æææJTYõYõ®Ú·oO¥J•hÖ¬_ýµÖ¼ž={2þ|­˜¡¡!C† P.°—+WŽŽ;R´hQzö쩵¼$!„È!6669rDé‹êsÂBˆB䯬®.¦¦¦øúú¢Ñh8yò¤$!„ÿ[rr2wîÜÁÐÐzõêajj À7HOO'::ZÐ,22Rëç‡KBB>T:Lü7éééܸqC«Ïž=ãîÝ»<þœ˜˜­åå"ºBäk×®áååEóæÍ©S§õë×ÇÔÔ”iӦϞ={puu¥FxyyqêÔ)Ö­[Çìٳ߻lsssîß¿Ï÷ßO\\ÅŠãÒ¥K2fÌ>cccœIKKS†6/^¼8ööö~úé'V¬X©©)½{÷f×®]ôë×Ý»w“˜˜ˆ›››Ö¸"r]!rHéÒ¥Ù°aNNNJìÖ­[Ì›7éÓ§cdd¤´6lØ@ÕªU±³³cäÈ‘ÄÅÅñ÷ߣ££ƒ¹¹9§NÊVÙ‰‰‰ØÛÛóÃ? V«µæ1‚.]ºP©R%¬­­8{ö,DGGccc"##IMM%((ž={ƃ¤"„¹áõqÐCCC9{ö,äÀJ\GGGëç›bÙ¡£££õzUçιwï®®®Ê³¯–õj½ßTi!D.INNæ‡~`þüùäË—BCCÿ“ºÔ©S‡Zµjaaa³³3'NœÈö:$!D.Ñh4Ô­[W9Ô²eKÒÓÓÿ³úèééѯ_?víÚõn­+Ù¥âCÛ¾}ûžSˆOÑóçÏ9þ<ñññœ?žgÏžƲeËð÷÷gÿþýèëëcaaÁ€8þ<îîî/^œÒ¥KÓ­[7Ο?ÏСC)T¨P¶Ê644dÇŽ±páB®\¹¢Ô#--3fðÇàççÇðá×w{¹»»sþüy†޹¹9?fòäÉüñÇ,_¾œ¼yóJ9'>>žøøxÙâ‹÷øñc¨W¯ÄÅűvíZ¢¢¢¸pá¿þú+ 4ˆŽ;@íÚµ™:u* .ÄÒÒ’€€úõë—©+õÿ¥T©R¬X±‚³gÏrïÞ=6nÜHLL ¤¤¤`kkËþýû©X±"7ÀÏÏbÅŠÀðáÃqqqÁßߟ/^°ÿ~¼½½©U«–R†œÂBˆR¤H¦M›–)^­ZµL±AƒeŠeõÞìhÔ¨5ÊrmÚ´¡M›6Zó 2•Y¢D‰7ÖCZ B!Þ‰´@„"¥¦¦’ššª<ó‘––FJJŠò¿¾¾>©©©J·îyòäAWW—””elt##£wº•÷õ²3¤§§óüùó7ÖÁÐÐ===^¼xAjjêë -!„È!Û¶m£k×®Êxèiii 6 {{{ðôô$))‰É“'Ó±cG4hÀ¡C‡€—Ïi¸»»S¹re=z”í²wîÜIïÞ½)Q¢D¦y‡¢AƒtìØ‘É“'°|ùr°··'((x9ô®««+µk׿üùóÒBˆÿJJJ .$00sssZµjE¯^½Ø¼y3ëÖ­cÏž=Ì›7O½0&&wwwæÍ›÷Þ×C^5oÞ<ºwïNË–-éÒ¥ jµšU«V1mÚ4âââðõõ¥|ùòìÙ³‡¿þú‹Å‹3oÞ&r K!rIrr2^^^,^¼˜ п~ÿý÷OöóH D!r‰F£áÑ£G,XB… ñäÉŠ-ª5VR×®]©U«•*UÒŠ}ãÆãôéÓZëkÚ´)•*UÂÑÑQ‰eôÒ[·n]%Ö­[7i!Dnéß¿?çÎÃÌÌ µZÍĉYºt)Ë—/GWW—9sæ`kk‹££##GŽ$!!ùóçS­Z5š4i‚Z­æöíÛx{{g»ìÁƒsúôiT*jµš±cDz~ýzjÖ¬I÷îÝ6l{÷îÅÑÑ‘Š+Ò¥KfÏžMzz:ǧbÅŠ´nÝâââøõ×_%!DnY²dI¦XÍš5ñôôÔŠ :”¡C‡þÏ÷fÇ‚ 2Å®^½ªüþúEq777ÜÜÜ´b·ø¾‰œÂBñNr­òìÙ3•éÈÈH ( {à²oß>:tè B‘»-]]],,,”WžÿM D!¾4*•ŠM›6ñóÏ?/oã­U«›6mbâĉ\»v 6(ï™5kû÷ïçøñãZ±ìòññ¡W¯^YÎ{u}6làøñã,_¾\‰ÍŸ?ŸãÇkT8sæÌÿ®"„_šfÍšpîÜ9J”(J¥â믿Vb+Vü¤OçKBˆ´wï^ Äš5k”ä±zõjV­ZEPPÒ­º$!„ŠÝ»w³qãFæÍ›‡¹¹9Ož}hÖ¬cÇŽå÷ß'))‰™3gÒ¬Y3:wîÌüùó9qâ~~~’@„"·lÙ²EëUÙ²e9}ú´Ö2*•Šp÷î]*T¨¼¼ýäÉÚ·o¯Õy[M›6¥^½zÊtÑ¢E9}ú4¥K—&Ož<̘1C‰Ãˬêׯ¯Õâ3f < k×®”/_^ˆBä›L±¬Æè(V¬ÅŠÓŠ•-[ö½Ê~µ3ƬÊ~½… Ö:ePªT)J•*õÆ2ä6^!„ïDZ B‘ƒÂÃÃ9{ö,+V¤N:JüÎ;ÄÇÇS±bEàåøé?ÆÐÐÎ;(O‰[XXвeËl—}ñâEN:@“&M2µ&BBBˆÇØØ˜Ž;’––¦t9U¬X1Z´hÁÇÙ¹s§Òª©U«–´@„"§EEEáââ¹sçpss#,,L™×­[7åâx`` ÇÇÈȈéÓ§³xñbfÏžÍÂ… 122ÂÓÓ“­[·f«ì»wïâââÂõë×9zô(...™–Y°`FFF0uêT–.]Š‘‘½{÷f÷îÝôë×;vðäÉ\]]¹xñ¢´@„"§i4FŽI=(Uª÷îÝàÌ™3$''+Ë?žõë×S½zuš4iÂèÑ£‰‹‹ãèÑ£èééQ¨P!Μ9“­²iÞ¼9ãÇG£Ñðí·ßjÍ5j...T­Z+++¥^ýõzzzäÍ›—ˆˆRRRX·n:::<{öŒû÷ï+×W¤"„9ÄÒÒ’ž={òäÉÖ®] À‰'pvvfÔ¨QZËêééiý|S,;tuuÑÑÑQ~¾ÊÉɉ;wîàêêÊ7ÞXæ«ï½ÒBˆNëÖ­±³³cåʕ̞=[9mô_©W¯µk×F¥Rѹsg­¾·Þ:AÉ®Bˆœ³ÿ~NŸ>­œJZ´hÇŽã—_~!88˜§OŸþguÓ××ÇËË‹âÅ‹¿[ Gv¯B䌫W¯²aÃ7nŒ··7'OždóæÍ¸»»Óºuk4h€‰‰ *•ŠrñâEúôéC±bÅ(Y²$=zôàâÅ‹ 6 ssól•m``ÀŽ;ظq#~~~\¾|™øøx.^¼HZZ³fÍâÀ,^¼XNW¥RѧO.^¼Èˆ#(X° =bÊ”)8p€+V`bb" D!rZþüù133cýúõÄÆÆR´hQ¬¬¬°²²¢qãÆ´nÝ}}}ŒZ­fõêÕØÚÚ2mÚ4-ZD‰%X½z5oìšýMJ—.ÍòåË9yò$111lܸ‘èèhV¯^MJJ U«VeÏž=”/_ž&Mš°xñbT*«W¯fÈ!¸ººâïïORR{öìaÞ¼yÔ®]ûÿZ0²‹…"g)RDé2äu*TPº-2dH¦eÞôÞ·Õ¸qc7nœå:2 Re``©Ì’%K¾±ÒBñN¤"„9(--´´4tuuÑ××'%%%Óýéé餥¥½üRÖ×GWW—ÔÔTÒÓÓ044|¯²_zz:©©©ÀËÛuõôô”eßTƒL·çZ $))‰õë×+¯¨¨(9²„Ÿµ'OžÐ­[7òäÉCÛ¶m¹qãyòäÑzݹs‡I“&áèèH:u8tè:u¢{÷îX[[—í²wïÞMïÞ½3uÒpèÐ!êÔ©ƒ££#“&M`Ù²e|óÍ74iÒ„õë×0xð`:uê„­­-çÏŸÏ´ž\=…•ššª¼4]BˆÏÚüùóiß¾=‹-bÏž=„……Q¿~}üýý=z43wî\zôè··7ýõ§Nbݺu4mÚooïwj}d´^çííM=˜;w.ÁÁÁœ:uŠ_ý•qãÆ1xð`-ZÄ©S§Ø»w/K—.ÅÉɉùóçgZO®Â266ÆÍÍM™Þºuë;eU!>”‡-Bä˜~øÛ·osìØ1J–,I‰%8pàyòä!&&oooòäÉ£õßýÁƒqtt$&&F+–]\ºtIéñUT.®Ÿ?ž˜˜Nœ8¡Ì?|ø0111\½zõ_ë ÑÅëÔ©SÙî NˆìÈ“'>d̘1(P€¼yó’'OÖ­[‡½½}¦ë ŸI B‘CÂÃÃ)V¬»víâéÓ§J‹722’&MšP¥J•OúóIBˆ¢V«qqqA£ÑP¹re%>nÜ8¦M›@‰%”ùÜÜܨY³¦Öˆ‚¯žþ&LàôéÓZëkÒ¤ ÖÖÖ´oß^‰uîÜkkk­ñK²ªƒÜÆ+„9dÉ’%ôë×`ccCƒ  åÊ•+Ê©«âÅ‹ãèèÈÈ‘#‰ÇÛÛ›êÕ«cgg‡Z­V®•d×àÁƒ9uê… B­V3vìX¨^½:=zô`èСìÝ»GGG¬¬¬èÒ¥ ³gÏ&--áÇceeEëÖ­ñððàáÇüöÛo’@„"·|óÍ7DDDhÅ7n¬Œ˜aذa 6L+¶téÒ÷*{Á‚™b¯Ö%ãvá ]»v¥k×®Z±üñ_ËSXB!Þ‰$!„’@„âc„Z­fÙ²e„††¢V«Q«ÕÊ3þþþJìÂ… ÀËN3b ïTvHHݺuË¿pႲnvîÜ©ÄBCC—O§gIJê=DˆBä`òð÷÷'99™~ýú‚...xyyáààÀùóç aêÔ©ØÙÙ±cÇ¢¢¢ !88ssóL×+ÞÆàÁƒ?~|–îØ±;;;¦NJHHwîÜ!$$///\\\´b‹/¦J•*ìÝ»WˆBässs‚ƒƒY¹rå—¹víAAAÊôŒ3øã?8vì˜V,»,X@ïÞ½³œ÷êú‚‚‚8~ü¸ÒB˜7oÇ×J>YÕAˆBä-ZDݺuiÓ¦ò|ÇÅ‹9wîÜ'ÿùä6^!„ÈAÎÎÎ/^ÄÓÓ“–-[~6ŸO®¼‡7ÊFB¼ÑîÝ»¹páUªTÁÕÕ•úõësùòeâããyöì—/_¦R¥JxzzrãÆ bccñõõÅÉɉ-ZpùòežÌòItI B‘CÊ•+G¥J•ððð sçαråJ*W®Lƒ X¹r%ééé|ûí·„††¢Ñh¨_¿>ffftïÞ•+WR¾|y*T¨í²7oÞŒF£ÁÓÓ“•+WróæMÚ·oO©R¥¨_¿>†ÐÐP¾ýö[1Þ/ IDAT[LMMiݺ5—/_æîÝ»ØÛÛcjjJçÎÙ¶mùóçÇÖÖ6SòˆBä°ï¿ÿ^ù}Ö¬Y™æ·jÕŠV­ZiÅzöìù^e:4SìÕ²_¯Gýúõ•Óm2F#|i!„x'ÒBˆ–q;¬žžž2­ÑhÐÕÕEWW—ôôtå¶]===ttt”e€7ÞŽû¿d¬÷õ÷k4¥No[‡Œ˜´@„"—\ºt +++ @tt4Mš4ÁÀÀOOO’’’˜8q"ÔªU‹ÐÐP:v숫«+*T ...ÛåîÝ»wwwŠ)’i^hh(µjÕÂÁÁ‰'°téRš7oN£FX·nƒ B­VSµjU¥«i!D.Ù¸q#¤¤¤àëëK¿~ýhذ!³gϦgÏž„„„Èž={ðññàôéÓDEEáîîŽS¦LÉV¹ÏŸ?Ïòá?zöìIË–-quuåÛo¿å·ß~ã§Ÿ~"..???*T¨À¾}û8pà‹/ÆÇLJŸþYZ B‘¶mÛFñâÅ©Y³&ðò)ô)S¦`kkK¡B…°²²"!!ððpå=ýõDGGkŲ«]»vYvÿúúÂÃɉ‰áøñãJìСCÄÄÄpåÊ%öçŸfZ$!„È!?ÿü3½{÷V®}Àˇ¨cbb?~<ÅŠ{çë9…%„9äòåËXZZr÷î].^¼ˆ³³3fffÔ­[—7âîîNbbâ'ûù¤"„9ÄËË‹ï¾û•JE¥J•(\¸05kÖ¤oß¾T¨P2eÊP¼xqììì”÷¸¸¸P£F ¬­­µb¤I“8sæŒÖúììì°¶¶¦mÛ¶J¬S§NX[[+ã—¸ººJ D!rKÆ„§N¢ZµjØØØàëë˼yóðòò¢cÇŽØÚÚâèèȈ#ˆÇÛÛ[[[7nŒZ­&::ooïl—=xð`Nž}Jxx8©©©¤¦¦òìÙ3ìììpvvÆÃÃ.\¸@HH“'O¦aÆìܹ“èèh‚ƒƒÙ°afff™®W¼Áƒ3nÜ8¶oßžiÞÎ;iذ!“'O&$$„»w‡ÎÎÎlÙ²E‰-\¸J•*ñÇHBˆÜ”7o^,,,èܹ35jÔ@£Ñ°bÅ RSSÑh4\½z•õë×£««‹ŽŽÓ§Ogß¾};vL+–] , wïÞYΛ>}::::èêê²~ýzŽ;ÆÒ¥K•òæÌ™Ã±cÇØ±c‡›6mZ¦õÈ]XB‘CLLLÈ—/çÎÃßߟâÅ‹³|ùr<<<8yò$³gÏÖêûS“k-§OŸ2räHåuöìY9ºÄGéÙ³g¬_¿^+‰™™[·nýd?ׯ¿þ*;7—•-[–ÐÐPþøãHJJbË–-tíÚöìÙóÎ×7¾¨bbb‚§§§ò*W®Ügq€tìØñ­ÆF‰‰¡dÉ’™â>äÙ³gõg|òä 'OžÄÞÞ^+>cÆ ÆŽûIï¿É“'3iÒ$­Xrr²rqóÕý—/_¾,;”ûT’Çß§ÌÞÞoooŒŒŒ°±±!55•mÛ¶Ñ®];:uêľ}ûHKKC¥R)ï)Uª ÄÔÔT+ö!œ?žÇk­O¥RajjJ±bÅ”XÉ’%155ÅÜÜ\‰•.]:Óúrí–¾¾>åË—W¦MMMß©ûÿÊ_ý…ÖŽÈŸ?ÿ[}Ž‘#G2gΜL·ñþöÛoÔ®][«+ƒÿÒ®]»hݺµV,--¤¤$òæÍ«ðà666Z'}jT*gΜùb¿à>¶ãïsS»vm¶lÙ½{÷Ø·onnn¨Õj‚ƒƒ166¦uëÖÔ«WV¬XÁÕ«WY¸p!vvv4oÞœéÓ§ÆÞ½{³]öŠ+Ø·oIIILŸ>N:Q¥JV®\ÉÂ… ™9s&7oÞÄÃÃæÍ›3~üxIJJbΜ94oÞ.\ȱcÇðõõýïHv<}ú” 0a„¦N{÷î¥P¡B™ÈçfëÖ­8::ju/ý.¦NÊøñã™7ož|‹ˆ/Ö¤I“8wîýû÷ÇÒÒ’_~ù…k×®P¦LòçÏO¿~ý¸}û6•*U`Μ9:::™ê!-!„È!  K—.´iÓ†.]ºh=¬÷_kРuêÔ¡páÂtéÒ…¿ÿþ;û Jv±B䌂 2räH%™<þü£ªŸ¾¾>ƒæÀïvBv±BäŒÄÄD~üñGåInLMM™2e .\`äÈ‘èééQ¨P!̵k×èׯ+V www®]»Æˆ#(P @¶Ê600`ûöí„„„°lÙ2.^¼Hbb"×®]#--9sæÊÒ¥K4hðò•~ýúqíÚ5FExøð!3fÌ 44”+V`ll, D!rÚš5kHHH`Æ L›6FѶm[ÆǪU«XµjC‡ÅÁÁeË–ammÍÌ™3Y²d … bÙ²eôêÕ ww÷l•]ºti–/_ΡC‡¸ví›6mâÆ,[¶ŒçÏŸcmmÍ–-[(S¦ Í›7`Ù²e˜šš²lÙ2 €››ÄÅűeËfÏžÍ×_ý-ÙÅB‘3Š-Êœ9s2Å»víJ×®]µbÇÏ´\VïÍ;;»Lýœe¬³}ûö´oß>S«åõ2K•*õÆzH D!Ä;‘ˆ_8F#!‡eÜæ®££ƒŽŽF“i:«eàÿn——}«Ñh2½ÿ•÷¶uˆ_¸Œn3Dθ|ù2Õ«W§S§N„……ƒzzzôë×ääd&L˜@Ë–-±µµ%44€o¿ý–N:Q¶lÙwúâ?þÀÝÝ=ËÄCCC±µµ¥eË–J¯çK–,ÁÎÎŽzõê±nÝ:H»v픆¥"„¹$&&WWWºwïΨQ£HIIaüøñôíÛ—zõê1wî\ºwïÎÖ­[ñ÷÷gÏž=,\¸NŸ>MTTîîî,\¸Pé~ým%&&¾ñ¶á… Ò«W/Z¶lI×®]qrrbõêÕL™2…¸¸8–,YBÅŠùã?Ø¿?‹/fÁ‚¬X±BZ B‘Ú¶mË™3gÈŸ??W®\ÁÀÀ€É“'Ó£G¾ùæàå¨ÿüóòžpíÚ5¢££µbÙåè訌ïñºW×÷Ï?ÿͱcÇ”ØÁƒ‰ŽŽæòåËÿZI B‘Cùæ›oˆÅÙٙ˗/cbbÀ/¿üB§N033ûd?Ÿ$!„ÈAuêÔ¡OŸ>üóÏ?DEEñøñc&L˜@Þ¼yY¹re¦¡¢?%¹v $>>oooe:<<\JQ!¾/^¼ oß¾T­Zooo:wîLãÆ•eºté‚­­-VVVZ±aÊ”)8::j­¯qãÆXYYáàà Ä:v숕••Ö)°¬êk ÄÈÈHë¡•#GŽÈíƒBˆÏš¯¯/“'OæÌ™3xzzR§N¼¼¼8~ü8žžž8::2bÄž>}Š5jÔ qãÆ¨Õj¢¢¢˜?~¶Ë}JLL 5kÖ$==#F`bb€(P éééŒ?}}}ÆOzz:iiiÊûǧtȘŽŽŽT¯^V­Zej}üüóÏ\¿~mÛ¶¡¯ÿ²-¡§§ÇèÑ£µÊ,[¶,®®®”*U www­»g?ÊÈ«Ï Ξ=‹··7...ò!„ȶѣG³xñb .Œ§§'E‹eÕªUÙiðCùñǹtéÝ»w'99ù¾ß>ÊHÆù¶Å‹/xöì™ü!²mÿþý|ýõטšš`ooÇçêÕ«LŸ>ý?©W¾|ù¨]»6+W®Ô:õÉ'!„ø<þœÃ‡+CÆfhß¾=•*UÂÓÓ àeϽ¯þ|S,;âââxöìOžƒ âÎ;”(Q‚’%KЧOªU«€Z­ÆÚÚš*Uª(ƒI 8KKKI B‘ÓLLL”îÛ_ýb/T¨P¦e3¾¸_U¯^½÷*¿X±b+V,ËuZZZj%x9líëeæË—ïõk B|!2n âC‘ˆ_ˆ}ûö±lÙ2¥7X‘;.^¼È¹sç(_¾<5kÖT⇦aÆÊôîÝ»yòä †††¨ÕjÖ¯_€J¥¢Y³fÙ.ûÊ•+œ={€† R¢D ­ù;vì !!cccÚ·oOZZ7n hÑ¢ØÙÙǾ}û€—§ÁªW¯.-!„Èi111¬]»–û÷ïãââÂ?ÿüÃÑ£GéÚµ+Ó¦MS– bРA¤¦¦2iÒ$–/_Îüùó™={6©©©|÷ÝwìØ±#[eß»wWWWÂÃÃùã?pssË´Ìœ9sHMM%55€™3gâããCjj*=zô`ß¾} 0€ 6pëÖ-\\\¸té’´@„"§=~ü˜k×®1lØ0^¼xÁÝ»wiÞ¼9Ë—/Wúœ # €ZµjѬY3ÆG\\‡&Ož<¨T*Î;§5èÓÿ’@£F˜4i†o¿ýVkþرcéÚµ+uëÖ¥\¹rœ8q‚'OòåËÇ•+WHLLdãÆèëëóüùsbcc±¶¶–ˆBä¤âÅ‹óôéSúöíËDZ¶¶F__?ËalóäÉ£õóM±ìÐ××GOOOùùªvíÚqýúu\\\´Æ É(ËÈÈèe’ÐÕÅÀÀ µ×/»X!rÆýû÷±µµÅÙÙWWWìíí)]ºôGQ·† R§N .Œ‹‹ GÍö:¤ò ÄgèÅ‹h4ªU«Æ€xþüùGU?†J‘"EÞéý’@>AAA²„ø ¢££Cdd$/^¼ÀØØ˜„„"##ILL$22’ÔÔTÌÍÍ2d‘‘‘xyy¡R©(Z´(}ûö%22’Q£Faff–íä°}ûv¶nÝÊŠ+¸xñ¢Rfzz:sçÎåðáÃ,[¶Œï¿ÿx9Ôø€ˆŒŒdôèј™™ñàÁfÍšÅáÇY±bÆÆÆ’@Dö9::²eËÙB¼¥Š+Ò¤Iüüü(Y²$7æêÕ«øùùQ­Z5üüüHLLdذa´jÕ ???Ê—/ϬY³Xºt)ùóçÇÏÏîÝ»óÝwße«ìÒ¥K³lÙ2þüóO.]ºÄƹ~ý:~~~$''S±bE6mÚDéÒ¥iѢ˗/ÇÈÈ???ú÷ïO×®] $66–M›61kÖ,­násíH\\îîîÊôÉ“'©\¹²aŸwwwÔj5ŽŽŽ²1„xKöööØÛÛ+Ó5jÔ F™–9rd¦Ø¼yóÞ«ì&MšÐ¤I“,×éèè˜éoÙÀÀ S™¥J•zc=r-˜››¬L»ºº'G—B|¢ä–BI Bñ1yúô)!!!4mÚT‰Ýºu ;;;)[¶,›7oæâÅ‹ØØØ V«)S¦ gÎœáØ±c/^µZM5¸ví¿üò VVV´nÝbccßXvbb"îîî4nܘš5kòÃ?hÍgáÂ…Œ?^‰ýõ×_”,YµZMíÚµ•k&666|óÍ7¨Õj>|( Dˆ7ñõõ• >ˆ´´4=z¤tJåʕټy3þþþ,Y²úõëGpp0sçÎÅ××—3f°fÍ‚ƒƒéС[¶laÍš5²iÓ& .¬ôs••»wïrûöm6lØÀºuëØµk—Öü¤¤$ž>}ª›;w.þþþÓ¢E vîÜI`` R¦‘‘çÏŸ—"Ä›ìß¿_6‚ø ,H¯^½(\¸°V¼I“&èééQ¿~}¥»÷ŒQ _½0ãX¨Y³&&&&oÕÕ{åÊ•)R¤*TÈôã×_­tÚ˜AOOO¹èžQváÂ…©^½:¦¦¦Zc˜HBñÎ$!„"„Ÿ‚Í›7“ššÊÎ;‰þoìW{¦x=vÿþ}þüóOâãã3]ÓÈʱcÇˆŠŠ",,Œ+W®üÏåSSSÙ¼y³VÙ·oßæÐ¡Cè:5 ]]Ù “|ùòQµjUŽ9òÙ|¦éÓ§gz@Ž?ñ¾>Ê#ÇÐЕJELLÌGS§‰'f™ÍßGdd$·oßÖYü÷ (P ÷ïßÿl>Ó¹sç¨ZµªâóO yóæÅÚÚšS§NÉBI B!$!„"›@!„$!„’@„BHB! D!„"„â=äZ_Xqqq¸»»+Ó'Ož¤råʲ„BÈ¿377×êTÌÕÕ•¸¸8Ùâ?A¹rådCñŽä–øbíÞ½›V­ZɆBˆBI B!$!>nsçÎeĈ²!„$!Dö˜››Ë -BˆBI B!$!„"„BHB! D!„$!„’@„BHB!$ˆÿ¡jÕª$''såÊÙBˆO';vŒºuë~Tu:|ø0 6üb ###4 )))ò"„øtÈÇøeýçŸÒ´iS9Z„âcN B!$!„"„BüG äÑ£G¸ºº*¯#GŽd{¿ÿþ;÷îÝ“½&„øW .”›@>§R @V®\©¼ÞåN«3gÎðQl¸[·nQ¢D 9‚„ø=z”´´4Ù9L?· ÒÑÑÁØØX™ÖÓÓû¤7Üž={hÙ²¥ABi!>offf$%%É©! D‘=uëÖ%22’ÈÆ’@„BHB! DdW¾|ù>š»Ë„BÈ'dáÂ… 4H6„@dd$‘‘‘²!$üFƒF£‘=&„øWÇçøñã²!$üŸÐÐP¼½½e !„$ìsuu%00Pöšâ_õïߟ%K–Ȇòj×®ÍÉ“'e¯ !þ•” ! D!„$/œ©©)ÉÉɼxñB6†Bˆx{õë×'""‚û÷ïËÆøH=z”úõëˆBˆ’@„"„BˆBI BñÑHKK#::š2eÊÈÆø/ÈÀqvv&""â­V°uëVœY¼x±lMñÙÚ¶míÛ·—‡Y?r)))œ>}šzõêÉÆÈÍÇ„ 3f üöÛo„‡‡ÿÏ?ªØØX©P¡BŽ&† "{Lü'®\¹B… ¨\¹2çÏŸ— "¯Œ‰NÁ‚)Y²$ýúõcÚ´iøùù½ñÍ?ÿü3ÁÁÁ|óÍ7øùùáååõÖ…_¸p­Ø¹sç¨]»6~~~lß¾€øøxtuu¹}ûv¦÷ä´Çpÿþ}¥ì+W®0tèP~ûí7Ž=ú¯ë°µµÅÐЀ‘#G’7o^ž>}J‰%8|øp®®¬XZZR @&OžŒ¹¹9ÏŸ?Wư?{ö¬RÏ¿ÿþ[ÙßÓ§OG¥R‘ššú¯û÷c’ñ<Î7”z¾éøKLLTÞ·cÇbcc?©?ô'N(¿ÌÇßûú”Ž¿O‰Z­ÆÁÁ!ó Íÿ÷×_iæÍ›—1©¹uë–ÆËËKóo:tèð¯ÓFÓ¯_?M‡2½J”(¡²|(P@cjjª300ШT*žžÞß—S/}}}J¥ÒèëëkÅÍÌÌ4fffoµŽüùókT*•ÆØØX+nbb¢)\¸p®¦7½LMM5*•Jcbb¢722Ò¨TªLË›››kòæÍ«Ë“'F¥Rittt>šÏ•ÕËÐÐP£R©4ºººo}ü™››ÔŸéß^ŸÂñ÷!^ŸÊñ÷)½òæÍ«©S§N¦ïwýœÎ\oêÐÌÕÕ•*Uª```ãÙ3))‰mÛ¶áììœk{õêÕôèÑ#×ÊÛ½{7Õ«W§hÑ¢Ÿåç ÀÙÙ9WŽ€“'Obbb‚M®”÷ôéSöïßZ­þ,—ëׯCãÆ?Ë¿ÁÏýxزeË›Oa™˜˜ðâÅ RRR044äîÝ»)RDkáË—/caaAÁ‚(R¤±±±XXXðäÉåÔÇÛ6lÆÆÆ9þÁãââ¸yó&£FÊ'ˆfª[IDATµ}äÈ‘\-ïéÓ§¸¸¸P¥J•Ïòó9s&׎€U«VannN‡r¥¼Û·oóèÑ£\Û¦¹}¼|(v‘üEôôô°ÿþYr1¡PˆË—/“™™‰,Ë´··óøñc`&7all Y–1\¿~˜Q¸{÷.²,SXXÈ… ðz½8NN:…,ËȲ̡C‡üf}¦§§©««#-- Y–éíí¥µµU8êÂsÄd©Nyyy¸««K9¯¯¯Ûl¶°@0Ÿ”••…kkkÃ555âaÌ1¯^½ Ÿ9s&ÜÚÚ®ªªRì'¼sçίö'ßêgŠŠŠÂ~¿ÿ‹þ¥ºº:l·Û»Íf ××׳N~¿?\TTô¯ú²? 1“-|‡îînΟ?ÇãÁår¡Óép8¤¥¥¡Õjyóæ $%%a4éëëSþ9¯Zµ ¯×KBBÃÃÃʇÃN§#55‡ÃF£Áív³zõj¦§§yþü90“wår¹X¶l*• ‡ÃñK—¢ÿj’’’(--¥»»[¼xÿD¾3 ÛÓÓCEEÇŽãܹsƒAâããimm%''‡¦¦&,XÀ§OŸØ¾};7oÞ$22’––<È£G¨®®¦±±£ÑH{{;*•Šééi6nÜÈ‘#GÈÏÏ'22§ÓÉèè(}}}¼|ù’¶¶6ÊËË1™L>|ø·^–ªV«ÅK'È ‹/f||ƒÁÀèèè 6CCCLMM)‰EF£‘‘‘eÜ1 Õj…‡óÆúõë1™L*JÊÛ¶m#//§Óɽ{÷hjj"..Žþþ~Ö¬YCll,{÷î%|µÌ«W¯’ÏçÃl6£×ëÙ³gSSSœ={–%H8NÚÚÚ€9ž`0øGú!22µZÏçC«Õâv»‰ÕoF&&&ÐëõÄÅÅ144Dbb"?~$""‚¨¨( ãããJÙ“““ÄÄÄ(çÁ`—Ë…Ùl&::šˆˆ´Z-^¯NÇðð0K–,c®ȉ'°Z­èt:&''9}úô¬ß8ÀÈÈÍÍÍÀŒ.Ö¥K—xöìáp³Ù̦M›„‡óFbb"z½žôôôY¶Ï'Ož$??Ÿû÷˜Hgg'‹…¶¶6²²²t‹‹‹•:¼~ýšôôtžèb?À’¬Ç9]©·¹QÉrˆ1NÀe?6hkÐÖ ­¿B!ØÖhk@[@)?Ô ´u‹5³¥6#0'´5hkÐÖ€¶m Ú´5 ­@[€¶m hk(*„ ­ /m ÚÊ !ĵ5äõÈ”ó¶,Ú:Å8¹Ô`æ„€¶€‚öOdÔÖŒ¶€¸.#d§­àØs²µkÇ@ Ú´5hkhŽõ­ {UkkHI[À±3C××]×·ÍüºÃ™Áp謪w.Ǹlëu1Ï<ô“sM`4?;mþ6¦O6;tàÌå÷ÚÚÈ4|á±ëïòÚ`6ùhÐúM[=¯zçβ€XƒÞøtÐZ[@2?¯*ߺÇbag:н/­§ùúÖ‹¼ÞZwOX ¬÷Úú0š%5ÂzŸùÖ†¶€® ZkkHÖÚÒ„µ¶€_y}å'hkTušK¸hk„uL’×[€a«zž×× qk ëgOÇS]'Q[0hX§®~1'€±ªzž×i¸¶`¬ªž¦)yUglëùë€Â:Ç$m½xÅR€îÃz2'€¾«zž×¹ŸN[ÐsUOÙfWkkTµ¶€sU]8©µ5ªZ[À冷!¬µ5’Z[0vUדÔÚ€özºŠ¤aÚx ÚI†¶ Òžn%©µ5•Vu[=­­¨«§›©êíÉÖÚ=Œ¶ hO÷ÓÚ€¢1Ý}Rkkò&õ1]¢­ßþ¥@ß1ÝRïžÈ˜«­TjtÜÓÃO».#×3zÜž~%µ5øøº§GÌèoik=éé“›ì†ùÖ´Ó2úƒª>:P[Œ’Ñb:7m ÐmIËè´[y:ÚžÚ ‡ŒVÒÙ«úĺÒÚ ±†–ÑÕÒÖõf´†®á×s¸¬µ¶Ѥ km Pº¡et¯a­­r´†-¬µ5À¥€VÏÂZ[œ­g =\UÏóúCÚÐê™YOUÕÚ(4¹ÃZ[]´tæËªžçõ[ö{€¯ûA@“¾ª§iJ±_eiëÅ/µ€É)ƒt]ÕÛÎꙡªZ[ÒU­­Ý Ÿ†õåe@´5ˆæ³¤3}&õ"¯sÒÖ š¡ë¤.¸ÿkkhµ˜E3ì%uÙªÖÖ ˜AOkkh-—3dì黓Z[@‚h–Ë §µ5BY4ƒžÖÖø¨5ô´¶€T­,—¡ó˜nª§µ5ZÓÚ­ ˆim @£•¬•%ÝiLkk€ÑsY%2Z[Hd¹ (éñÚúâ'À°¹,‘ªZIßÒÖ‹Ï© ŒÊrÐÐÚ@( e`¤ŒvdÓÖ“9ÊçZCkk@(Kd€êYCkk@% eõ¬­­¬’2¤³zÖÖ@Ç•¬•Rv³tÖÖ@O¹¬’rE³nÖÖ@ë­,—J¤³#-ÚZ e­ P®˜u3ÚT2€\ÍhkÊ\+f‡b´5T˜ËBàþPVÌhk¨³•å2€PmbÖÊB´5ÔF—šèc¡ ÚšVŠY+­dG]ÐÖ4ÍŠ W«dÐÖ©Š{£Y1¤LdU y[ïäšì.ùw‹nd±Dšokr§³hı,´5§êY:â@[£ž±³Xhë­ž&ËØ± @[ßÕШ¥‰•1À-Gñ¿!þ‰Úú³ŒÖÐ@Þ2vè+¬Çjk j8%Ç Æië­’–Ñ0nûïÀÅ¥ÝAëNÚÚ€4ôIJ€v »Õ¶^÷´Œ†º²ØIzLêNæ[¿œÖÓ8ˆ•1ìæõþªnkƒÓÈbA õTõþdëÛZO#‹€ÚÂú9äøžÊõ™Ë‡O4¯j=MK}lw€®ÃúßþŸãOüûÇ­Õª} 4WÕU´u!Æøü×ïOëc ªªþ(¬ïlë×pµ°VÉÊh½ª3¶uØ ,óª{îc‰ YÕÛzQÌó˜~}­ªk¯d¿ `°¤¾RÕÛz#óTõM¡lƒl÷ôõ¤¾¡­³˜&—m@€Iª§ïiëÂúÓb–Ëùc:SOßÓÖÃ¥³b¸;¦ ôô=mÝÆ õù!gé PYF.é;Ûº¥zÖÍJZ[Ÿ hõ ÐNC×YÒݵõ~C h€¦ê¹‰€î¨­ßÆ´†h§ž[èfÛzkXZLÔÚÍ}×skm½îi% PM4ÛÍ´µi·¶²hçU-¦’†²V¦­U5 ‘…²¶VÕW*Y"kkU Œ[Ã*™úÚ:Æ)U ÜØÄj˜^ÚZX€öÕÄhëÏ+Ú²z0Vk_ÈÕÖñwF‡lh(ß»"zhkP½z´5¨^Õ hk:­[Õ hkúo\u  ­zèZ  ­zK[] €¶šZi €¶z\E Ú. ­¡ÖÞ¸0Pf„)FmÍ0¥+y€òa­­)š¿Jè ¬[Ë_ù p5¬'ãÖý±ü(_ÕÓ´WÕÚºh b€F“údX×ÖW*Y Ó瓺«¶þ´˜U2[=/¤â#ÏKL6Ãø|7+fÎ7tªžÎÞÖñ÷«;™Ú;­›¸Ð ºh[Ÿ}óïbZFðQ1—¬çêÚz‘Ôb@(WÍÕµµ¤9Ž› åªÛZR´ØÁCÅñÕ óo˜ç¹ŒÑo gïêàÛ¹.# so wµ5@å*sÑÖ@Wͪ\ÑÖ M5+ ­ÂÐÖÒSwhk@YŽHz ­Az*KÐÖHOé T3›—_ÔÖ‚Uzœ­êý;hë®BV°äNê¸\~7àjIŸIê¼m.‡mª2–¿|‘©ñ«ŽÌÒÖ‹—òö=œy_Ê€+‰œ°›okëM ž„o2±¾”,:ßZI´Õ¯ÝToom-¬€‘sSÂjk@ÊMÐÖêM½©@@[’ õ ­AÆI.è¼lž¢ÚZÊ8€3úŠßKu9«úŽã· Xc[×Êr É$­GÁž,|í¡  =Ú­’׎ñô¨4ÐÖ@ŒœH5RüsnÂÛæ×lé\ÃÏ’N=½'ió•ôç “oz'¸·â;M=«:†üÀ†¾&i7‹€^çõ"¦Ÿ÷ù&¯{éfGsØ@u…V6жÂöñ6 %©£ùdžÐÄ‘Ê&N$o¹ƒÒ"©×‘}æ;ÓÁòÕì£ýK¶NÈΰ÷3»­Á@ß~lÐÖÐT[/)pÖ#´èÿuBæõüªêu^ kØkëÃb–Ô°Ï|kÐÖ ­ ?bÏ\A€ö휈hÜÒ(4n]r™‘Â+p{ºvŸÎöôtÞ §ó=½ÅÓ¥eÜ´5hkèO‰Y)5Ì}¡ÝÑ®‚½{ öZfÜ´5hkèIE†qkH#ïuCÏ/ŒŽ·X/ý±Ó'ÉoB[gÙ•­hÜÖçû$ùM è'ß®<ß·bŒë kX¯G¬·ú$ùMhk€nô5€°F[kó° €þòZm£­HÐ2‚Á퟿YýäÛ­ç2Ú­Ηñ‡î³{«O’ßÄ Çð¬{€¥Ô®”ñ|ÑÜõ7_ß~º¯ÿZ<üu7Û™Ñþ[¹v ´5ßåõÛ€^ýö›ë‡oÝ@ZÖ h)µß¿沪(ùŒÍöÖM1Æ3y}æn\aÜ ñ·×7ËûüÝÐÖ£7·¼ÐÖ\e²5€¶àl7/–øx~±XLwÚ^lþ(y PâèíP PgXOGë[Ï×´^¯Ù7ý^ªO^hkh†9! ­ &ÿbî ýR-dQIEND®B`‚snd-16.1/pix/random.png0000644000076400007640000000246311147553270013133 0ustar bilbil‰PNG  IHDR {ŒÂÎbKGDÿÿÿ ½§“ pHYs  šœtIME× &õe§ÀIDATxÚíÜÙ®›:Ð8Êÿÿ2÷å¦r©G0ÃZRÕ–669>aY–åPðV€  (A<.(B¯ÂaûŠÂkY–ײ,M¿wÀÔ£{’ú³ç˜¿¾¦;›q}G|†Ø…ƒâ; ‰ÿœ¥¢[ëL¯uä7ãZ®Ø)[Ïù󸇙{;ËÑáÎwµ!ï7bTydyŸmdÕ³ï{ƉÏjì¹Ï:ªðr#žÒ1r¯ïé4[ʸç9Ò¬i݈;ôžݨÐÙZ†[ûJ*äF‡Å·0¾3zÿ-çQ*œøÿëŠÜrwÉ]GKÃß7c8Ÿ:×­ºå}©:‰;P© jõkýp¼tý-AÞ{¬ZGŸº£9tD‘zfPzŽP{ưåó×§*½Ö¹÷l©cô$~Ôqk0õZ®LZ¢v=½ÔÚI{:\|ŒR˜·¶ÅuÝÌçF&ëí-áæE"4zîþ©†˜ºóµs¸ÖÀF~eÜŽ©}jªÔXsç—G­üSÿ>ºsÖê¨t}¥rÉݼâv” ü\ÛÉ…U©ÜÖõÚû㠟פ*io‡­5øÔȪtìõñJû×>{Ë4¨Ö@{¹g Z;^é¹Niÿïk½eU Â\½m ùÜþ¥€l Ûõ~µºwª·VØžJª5àÚÝfÝÐ[îെÙ{Í=ïÝóžÖs‰CqëÔ¶vn¥í­7¬– i=‡=eø傯Ubkºï ‰Ö÷מ >‡£¦LG—Ýžçn£Îoëhtk»ØsÌ÷SƒáŒ sÏèbľW*«#;ê®4«GoÚ0FŸ“ߘøì0:Ã#ëK] „-ƒ]î[+ú@Plºc 0õ (A A @P‚€  (þg™9p¿ °ÌL=A @P‚@P‚€  (A €ËÌû…eæ`ê @P‚‚€  (A @PXfÜ/(,3S@P‚€ €  (A @P‚ À2sà~Aa™9˜z‚€ €  (A @P‚âo!„äúŠÜöÞãçÒ½(,„]˜õÝžÛgÏþÀE‚âºw„lSêÛŸÖßý[<ãäüpDQêœñkgš2œqêrÖ)•ór^½Þ3.Æn8¢(ݵsSøµ–”ëݸHPôLK¶îœ¸:ÐYƒÐyÝã¼ (AÜLXLÀ# @P‚âÏÉvNÜ6{Úà¨í3Ûþû*±,Ë??:j8"$RmpÔöÙmßÔ#³žò]€ ÀÈ AÁØ;ç70R#ï¶Òöøý¹!|ê8½Ÿ[:>ý>W>y«O/ÛÔïxvv6ÁÁÁåÞ ‘‘‘ôë× ”k¹¹¹¹ôìÙ“_~ù¥\˽~ý:cÆŒAGG§LýÀÔÔôîÓ¯_?:tèPjž˜˜jÕªE¯^½Jì/ÖÖÖ„……•xmXX666,Y²www>ýôS† "¾òM`U¯^ý­nÒ¾}{üýýKLsqqÁÖÖ–ÂÂÂÓ éÒ¥Ë+Gx¯‹±±ñ;iЂ‚zöìÉ–-[ʵÜÐÐÐr/àÙ³g <øhÔÕÕQQQy«2JS544ÈÊÊ’Â999äåå‰/ücT ÿËÅ‹;v,=-(xc¦M›†»»»hAù ,{{{‚‚‚8}ú´¤¦‘-åÙ¾};FFF4oÞü•CÁÇǾ}û¸{÷.³fÍ’SG£¢¢¤°¹¹9±±±XYY±qãFÑhe$33“¨¨(¹e\\QQQDEEIó†)))R\RRR¹×#''‡¨¨(9¹ð" Òý322ÈÈÈâ$­ª(îÞ½{¯¯z{{Ë…ÍÌÌ033“‹kÖ¬ÙKÕ>`ôèÑŒ=Z..((H.¬©©ÉÏ?ÿ,ë58|ø0gÏžÅÕÕ•ÚµkÀðáÃÑ××çÆ8;;cdd„‹‹ þþþ¨ªªÒªU«rðññÁßߟ•+WrêÔ)úöí[,ÏŒ3PPP 66–©S§baaÁáÇٴiºººÈd2¼¼¼HOO§GôêÕ‹³gÏóv*¡@ ¨PPP ÷ÇËöíÛùDŠSPP ZµjB` UóçÏKsS~~~äææâèèÈùóçñööæßÿåĉðÓO?DµjÕ°µµ¥ÿþåV¿þú‹¿þú x¾ú«©©I÷îÝ3f ÑÑÑ„„„pæÌNŸ>MHH›6mÂÀÀ€M›6qåÊÔÔÔ:t(S¦LaÔ¨QôíÛooo²³³9tèP ‚ª@TTÚÚÚ¬ZµŠœœÉ`êÔ©„……ѹsgôôôøæ›oPWW§  €–k=¢££QRRbÕªU¨««sÿþ}ÆãÆ#>>žÆÓ©S':uêDãÆ‰gܸqÒqøðá„……ñÝwß •P ¨*Lš4©Äø¢ÿEºuëF·nÝÞI=ÆŒSbü°aä߃.–Þ¦MÚ´i#§¦¦Æ¼yóJ,ï½ ¬´´4¹MÇwîܽNðÚ\»v””)\š  êðÞVzz:rCZàuù¯‘XB`½6lÈ¢E‹¤°‹‹ 'NœoBðZŒ?^.¼råʶ-üüüX²d ÕªUãøñãØØØÀºuëh×®»víÂÃÀ‘#G2uêÔr­Ç‹¬>>>¨ªªËcnnNrr2?þø#}úôÁ××WîÝÙÚÚÒ§OI}TUUÅÇÇGJ“îA%Æßßrss9þ|8666RYùùùÒ*ãQ AùammÍÅ‹Y¹r% lݺ•ýû÷W¸zÏW/CCC±··§nݺ:tˆC‡Q¿~}9ƒ×’#, ’óÕW_Ñ­[7ÒÒÒ*¼/üŸ~ú‰ÔÔT\]]yúô)£G&--èèhÔÔÔˆŽŽK ¨ªxzzâë닃ƒ?üðÃKç}hBBBprr¢I“&ìÛ·¦M›’ššÊÆyðà7fÕªU¯,G, ³|ùr¦L™ÂÉ“'yúô)4oÞ\ʳtéRZ·n-ç@qðàÁtéÒ¥Üê±téÒÿüò sçÎ% €Y³faggGff&YYY$%%1kÖ,.]ºDJJŠä÷êŲTTTpppÂbK ¨Äx{{cjjÊ¢E‹PRRâÔ©SÔ¨QƒÖ­[cddDff&nnnÔ©S###-Z„¢¢"C‡¥~ýúåVccc’““122"%%…=zðàÁâââpttäöíÛpãÆ –/_N·nÝðôôÄÉɉíÛ·Ó¡C&MšÄ³gÏX´hFFFäääðõ×_ %Tš7o.Ù[½HIïÓ¦McÚ´iï¬.ÿ5eذaƒô»$?ýãÆ+qÑ˼¡ •P T„À•¡ •˜œœ8 …uuuéÑ£>>>Ò$|ß¾}©[·.·nÝâæÍ›´nÝZrñR^ìÚµKú=f̘mª,X€ŸŸ«V­¢mÛ¶XXX°mÛ6ÔÔÔ077/&dÞ†U«VѸqc,XÀ¿ÿþËÑ£GX²d ÑÑÑXYY 7¹~óæMöïßOpp0,X°€Aƒ,åÛ°a·nÝbâĉB` •™3gòÕW_Ï74ýÞ°a 8/¾ø€ï¾ûNòƒß°aÃr¯ËÞ½{8p äù×_%77:vì(—¿Y³f 8Pîȱ¦M›¢¡¡AçΙ={6€Ü¤¼XA%FEECCÃbñíÛ·/רQ£—®¾•%Õ£U«VÒï’6[—tMi›²Å–@ ¨4%„ÀïžN:add„‘‘†††˜››óàÁ:w‘zzzlÙ²…ôôtf̘A‡èܹ3ãÇ'99¹ÜêƧŸ~Š‘‘:::ܸqC.ýñãÇ\¹rccc¹ø={ö ®®Ž––‹/&::švíÚaddD³fÍØ¹s§\~1‡%Tb¬¬¬$WÛ·oG&“áììL»víØ¶m>>>XYYÑ¢E ®]»†——êêêXZZrñâE T.õ˜:u*K—.eÚ´ilÙ²…3fÈÊÉ‘#GHOO—âÒÒÒˆŠŠÂÖÖ----Z„­­-lÚ´ ooolmm%³ 1Â*9/:äÛ¶m&L‹ïׯzzzôîÝ}}}7nŒ©©é;«‹••ÊÊòc!CCC~ûí79cÑäädÜÜ܈ˆˆ`Ò¤IR¼ ¦¦¦4nÜX¨„AUãûï¿ç×_­TuVUUeôèÑ´iÓ†^½zI&¥ñÞUÂÇËùïyq#´@PV>,çéãÙ³gm[DFF¢ªªúNMÞõë×—Ž%+,,dîܹèèè”zÍ{a©¨¨P§Néï“O>_Ÿàµ©Q£†\?RPPøhÛâÆèèè¼cÐ÷Å‹§;W(U»vmF%ý•·1ÁÇA¯^½äúÑ«N ®ªÂ “³Ì}øð¡èu‚×fæÌ™„††Já¼¼¼²&MšDBB»ví’<L›6ÁƒÓ£GîÝ»Çܹsiß¾=-Z´ÀÜÜ%%%ôõõ100(·z899allŒ§§'¡¡¡œr‡K */ÚæÀs¤‘}ûöÈy«ÐÓÓãï¿ÿ–ÂEi[¶l‘»¶<=\´oß^ÎårQÙGEAAaÆaffV,ýEYPDiæD%TPPûû888°lÙ2ñåWR*BªHíPZû¼¯6{Ù=_·N¥ÕMÌa ‚JƒX%ª111Ô©S ).--ÌÌLé`ÒGI^ZuttÐÕÕ•òFEEѨQ£·Ó”•k×®I¿;v숢âÿ‡ˆ‰‰žûëjÒ¤ yyy’ꪢ¢B»ví(((,ÜåNŒK ¨Ädee±yóf<ˆ«««ôÑïÝ»6lˆƒƒ>ÄÊÊ ÔÔÔˆÇÝÝêÕ«³k×.vìØÏ+]¿Œ?þø;;;FŒÁáÇqttÄ€§OŸ2mÚ4rss©S§wîÜÁÃÃ?ÿüLLL8tè6l`àÀdddÐ¥K,,,äŽúK ¨Ä())ѤIªW¯._¿~}êÖ­+…ïÞ½KµjÕpuuEEE;;;nß¾‘‘Mš4yëE öîÝË×_ÍðáÃùþûï%GNN›7o¦FÌŸ?Ÿ«W¯²ÿ~vîÜI—.]000`ÇŽ 8+VHŽ{ôè!w1‡%TbÔÔÔ033“Žò*¢GÊŵlÙ’ºuëR«V-Ú¶m <÷offV.þà¿þúkàù‘^ÿuY­§§GÆ ùä“O$·è***’ºúâœ3gÎàèèÈ7PWWK |xºt邹¹9nnnŒ=š>}ú0vìX¶oßαcÇX¾|¹XàóråJfΜ‰––5kÖ”¼6ØÛÛK'W9rD,àc$%%…ììlrssIJJ*÷ò=z@||<2™ xîóª°°PZ±ÌÏÏçéÓ§’:k``@xx8îîîÅÊiÒ¤I±½‘B` •˜ììlvîÜIxx8Ç—,ÇOœ8Á™3g¸yó&;wîDGG‡‹/²xñbV®\ɱcÇÐÕÕ%99™;w———.]z£z˜˜˜Ð³gOvîÜIŸ>}¤Ér+++”””çûï¿gíÚµxxx §§‡‡‡‡t8EçÎ¥²† ÆÎ;Y»v-kÖ¬‘»X%*9yyyŒ5 øÿ°óóóÑ××G__Ÿ¼¼>>üøãâM ä077— ÏŸ?ÿ£l™LFzz:ëׯgÔ¨Qèëë“““Ãĉ‰%77—Õ«Wc``ÀÆÙ»w/ƒÆÞÞ233Y¼x1hkk¿Q=233166FSS“¬¬,|}}©U«–4úõôôdóæÍ(**Ò³gO-Z„’’‡bÍš5T«VãÇ£  €……?&77'''¾üòKé>b•P ¨Ä¤¦¦2vìX<<<$Ïž .$>>f̘ÁСC ÄÉÉ ¶mÛÆŽ;8yò$<`ìØ±ìß¿_š° @ïÞ½ñ÷÷§ÿþ 0@J»}û6K–,aÕªUìß¿ŸcÇŽ±oß>bbb˜={6?ÿü35â»ï¾cÞ¼ydffâïïµµ5C‡•»XA%¦fÍšx{{cjj*Å 8Ý»wϽ2Ì™3€Q£FѱcGôõõ™8q"Íš5ÃÛÛ›îÝ»¿u]~ùåQUU•K355¥{÷î4lØPNÛªY³&µjÕ’®}±œ‰'s°)–@PÅèÑ£ÚÚÚÄŒ3*d=ëիǰað´´ÄÒÒ’%K–¼ò!°‚*ˆªª*þþþèêêrøðá YÇøøxîß¿Oxx8ÚÚÚ,^¼X,àcf„ lÛ¶­Â×síÚµeÊ'–@PÅpss£ÿþlÛ¶M:]h×®]\½z•ððpÜÜÜÊý¾vvv|ÿý÷Ò)FdddpäÈüüüˆ‰‰‘Ûnãëëˉ'¤k_,ÇÍÍððp¹{Kw “””ÄСC),,dÆŒ²lÙ2®\¹‚‘‘………øúúÒ¹sg.\( [[[LMM¹{÷.&L   €#F0hÐ æÍ›÷Úõ8{ö,ÆÆÆQPPÀÙ³gçÛ†¾øâ V¯^ƒƒƒd¶ðí·ß¢  €»»;+W®¤F=z€ñãÇËÕ], ŠP»vmüýý‹Åjú"'N”V‹øì³ÏJ¼þuQVV&00°XüªU«€ç+”Eû_dàÀ 8P.ÎÓÓS¨„ ò#–@ ¨4•P ¨øùùѦMêÔ©<ß³aÃ)ÝÖÖ–àà`._¾ @§Nä|¾Ÿ>žž={bccâE‹8pàõë×—&ä ±²²BUU•ŒŒ ÚµkGll,Ë–-ãÚµkÌŸ?Ÿ>}ú0nܸ׮‡½½=––– <˜?ÿüSÚ/¸fÍÖ­[G­Zµ˜}Êßÿ-·hôèÑXZZòï¿ÿrùòåbü„À|ô¤¦¦J¾• MMMÉ|þ2}÷îÝdggS·n]É6këÖ­$$$ ­­ŽŽ999r×¹5~]LóæÍ˜9s&­ZµÀÕÕ• °aÃÉ­Zµ¨_¿>ùùù¬\¹R®CCC|}}¥z5kÖL,à¿[‘QceCYY¹ØñY@± N:’ð*B]]½Äëß„’ÊiÔ¨ð|å¯hõ¯6lXìšÒæ³Ä–@ ¨<Z4@PùÉËËCYYEEEòòòŠ(¡©©I~~>ùùùÒÈìE¿ë¹¹¹¨ªª³Ÿz²²²äî÷"Ïž=“Œ{ÿ{o€ììlQSSžo-*,,vXAU"77FŒÁ­[·øé§ŸèÝ»7æææ˜››£««Krr2“'OÆØØ˜Þ½{3vìXHOOÇÇLJ>}úHó[o•+WÐÕÕÅÜÜœ&MšÈ‡§§§3sæL éׯC† ‘ÛárëÖ-Ú¶m+MÔ²lÙ2Ö¯_/TB *ñìÙ3®_¿.w vÿþý9pà'OždΜ9ØÙÙñ÷߃—— ++‹   ²³³¹~ýú[ÛjÍ›7'''NžKµñIIDAT<‰“““ÜY¢÷îÝãæÍ›ìÙ³‡#GŽ ¡¡!9ø»yó&‡bæÌ™ÒjfXXwïÞ*¡@PÕ¨V­ ,àÑ£GR\¯^½¤ßþþþôéÓx¾W4_”§nݺ,X°€›7o¾u]ŠÌ!ÆŒæM›äÒ:wî,­Y‡‡?þø#õêÕ“òNž<îܹóáVzz:ׯ_—‘‘‘¢× ^›RRR¤paa¡h”ÿpúôiÔÔÔ022*¯¢åÍ•+Wðòò"44”ÈÈHNŸ>ýÊË÷.°RSS%‹X ˜“y ,\½z•û÷ï UŠªxùòeŒŒŒ*l.\ˆ««+æææ¬X±‚Ÿþ//¯Š%°tuuqtt”Â...œ:uJô0Ák1iÒ$¹ðêÕ«E£üG`²hÑ¢ [Çš5kbnn.½Ï²xm“îA%&??Ÿàà`¸uëÿþû/ƒ âøñãR>---<==Ù°a;wîÄÉɉš5k’••Epp0IIIܸqCnÔú:´lÙ’¯¾úŠàà`ŒŒŒ¤¹²áÇ“——lj'XµjdñâÅÔ©SMMM†Jpp0½zõ’,勞#&&†«W¯ %TrrrØ¿?5âúõë`ff&gëÔ±cGÜÝÝ‰ŠŠ"44WWW¾þúkRRRØ¿?:tàÌ™3¿Q=ÜÜÜèÞ½;û÷ï§k×®¸»»Ï'ØÛ´iÃŽ;HHHàÒ¥K¬[·Žþýû³gÏš7oÎþýû1b+V¬àÔ©SÄÅÅ¡¢¢Â>¬J(Ê--­Õa›bq½{÷¦wïÞrq 4(7uº¤rŠŽëÞ½;Ý»w—K«U«V‰×ØÛÛ •P T~„ÀB`}¬lÙ²…)S¦ˆ†„Àªøó¿ÿýO4„@ –@ K „À!°X@Pqyï–îaaaX[[Ká= eÅÖÖ–)\ä~W V¹ÒªU+9ß<...eÚ¥-¼ˆ³³³\XCCC4ŠP A<ÀÛÛ[4„XÁ‡áÙ³g())I§É”F|||¥=¿P,  `ggÇÏ?ÿ,9’%B` !°A9ð÷ß‹FK ¨̘1C4‚X@,@ K „ÀB` ‚·eΜ9DFF–)ï¥K—X¹r¥h´2ðÞ7?'$$päÈ)(Þ‚àµ9~ü8=’ª~ééée®S~~>YYYâ¥VÄ–’’šššÒß‹§Ó eE]]]®½/Nœ8Áõë×Å øXFXÚÚÚŒ7N §¤¤°sçNñ&¯EŸ>}äÂVVVïüžË—/ÇÌÌŒ‡Ò©S§òÜvvvÌ;—† Š–@ x9)))Ô¬YóƒÖ!11‘gÏž½2_AAgÏžK ” kkkÜÜÜ>ȽóóóYµj•X l|óÍ7t”“——Gfff™ò¦¦¦RXXøÊ|2™ŒÔÔT!°‚™°°0?~\®e^¸pµk×–)¯••OžVNœ8ANNŽÜ¡UsçÎqëÖ-!°‚ªÄ¥K—øê«¯^™/??%%¥÷²"Z\¿~{÷î %Td>|HÍš5©V­Z¹–»cÇzõêEnnî+ó^¹r…®]»~ð¶¸zõj™V5…À> *Ô¢E tuu?X.\ˆ££c™òþõ×_|ñÅìÞ½»LB³k×®rGõ•ÆÒ¥KË<ñ/–@ðÓµkWòòò¸yóæ+U·–-[rôèÑW–yðàAÚ·oÏ•+WJÍ÷Ï?ÿ””D÷îÝ…J(”FDDúúú};Ô¬Y™LFZZÚ{¿wFFùùùú~Vbb"Ç/5ONNK—.åÒ¥Kâ‹”Ⱦ}û^iHyüøqÖ¬YóV÷qvv§‰W–-[†ƒƒC¹•W¦½„–––4hЀAƒ½4Ïüùó2dÞÞÞÔªU‹–-[Š·UÎ=z”áÇcll\neΙ3‡nݺ½óºÿñǤ¤¤P£F \\\Jôw~æÌ"""øüóÏqttdáÂ…¯}7n‘‘!Å1¢Ô öŒ1‚K—.Ñ»wïRËÏË˞ϭ_¿þ¥ùâãã™={6~~~¯,·ˆ~ø¡Tëô¸¸8~üñG?~üÊ2ÃÃÃåÞqi[Šbccqtt$&&æ•åFEE°yóf|||^š/--Mê§QQQ%–«££S¦y³QÉd²‡q/ÚMÔ«W¦M›rûömÖ­[Ç–-[^Z±±1~~~Ì›7#FÈ­P„„„¼ô?^\\wïÞEEE…béùùù¨¨¨”û$“É(((@Y¹|÷¿Ëúæç磬¬Œ¢bùiòyyy())¡¤¤ôʼ7ndâĉotŸÕ«WÓ¢E š4i–-[pvv.–ÇÓÓ“ÜÜ\ „­­-^^^réÖÖÖ„……•X~`` d©­  €ŠŠ Ïž=+“õ¶²²r™V²PTT,“ÛeeeÊt¢ôë–[PPÀ ŸíKQUU¥   ÜË-k{õ«"A_Òs«¨¨¼V¿’ûZ“““9tè644¤iÓ¦oýQ·oßþ¥« ¥NöíÝ»—1cÆ”»HKKãâÅ‹ 0 \ËMJJ"88“r-÷É“'„††òÍ7ß|°^Û¶m?è³4uROOáÇ¿ó:S»vm>ûì³w~¯÷ýÎßÕ·ö_BCCQRR¢M›6¯Ý¯ä$Q£FÊ´aòüùó¬]»–7¾µ› CCC _šôN6qFGG³páÂr/ûÎ;¬^½ºÜË eË–-UjC«¥¥%]»v-—ã°ÊÚwß–¢‘biÓ#•õ¿«oí¿¸»»£¦¦öF[|ʤ[Ì›7›7orúôi233‰ŽŽ–îzyyaddD›6mèܹ³˜pÈakk‹¿¿?kÖ¬‘>ŠØØX’’’¤<£GæñãÇL™2…íÛ·‹F”>ÂzÇŽ“ ›ššbjj*§££Sfc²Š€––V™'C+ÚÚÚUÚŽ¦¦¦Æo¿ý&wîÜ9¹°ŠŠ ?ýôS…~ŽŽ;R·nÝ*) ÌÌ̪†ÀªŠÔ®]KKËJS߆ 2bÄñ/öó!çß5E+›a8*ª–Jø!)ïU¼wM5Ê};‚ êõ“²jïÃFî}£¯¯ÿƦ?rvX@ TÂW˜˜H|||©yRRRˆ‹‹“Â2™Œ§OŸŠ7Xd2±±±¤§§—š/..Ž””=zDll,±±±¯|7œbccKu±’ŸŸOll,ÙÙÙâå—ÙÙÙÄÆÆûÿÛ¯ÒÓÓ‰•3@}±_½Œøøx+¾JÁæÍ›IKKcòäÉ%úðyðànnnÄÆÆ2iÒ$ŒŒŒ8qâNNNœ:uJô¦Wàãョ§'-[¶dêÔ©%®rùûû³uëVtuu±¶¶fåÊ•’ïînß¾ýÁŸ£  €Í›7sùòe ^j¿åééÉ™3gèܹ3Ó§OG]]]t‚·ü'±aî]»†ŠŠŠô þ·_lÚ´‰ððp,,,èß¿±~Õ¸qãbå_¹rwwwªW¯Î”)SJ߸.ûÀ8;;˼¼¼dááá²É“'—˜ÇËËKæìì,KII‘ 4H&“Édûöí“õíÛWV‘زe‹,55U '&&ʶmÛöÁëedd$“Éd2™ŸŸ_‰y $KII‘ÞGÛ¶m“yxxTˆöÍÎΖÞyÑ3•ö¼#FŒÅÇÇW˜þ"›:uªìÞ½{²ÊDVV–ìÔ©S2™L&÷ þ·_ùùùÉäÒ^Ö¯^dòäɲððpé;/J»J8dÈ S—‚‚ñöö&..NrXVPP Mš’˜˜HNNŽœ»ÔÔT+¤úâíí££c…ð\YÙIOOgÍš5̘1ƒeË–‘ŸŸOvv6iiirý!))‰ÄÄDiÿ]NN‰‰‰$&&’™™IFF†´?233“‚‚òòòHLL$99€¬¬,ž={&ׯŠÂ‰‰‰Èd2rrräîñ²ý~ôíÛ—ÌÌLæÏŸ‹‹ËkÇ ¹Jxúôi´µµ+Å|LL vvv\½z•9sæ`jjŠ vvv(**²sçNžzzôè½½=ýû÷ž»”133“!˜™™aooOûöí%𡉋‹#++Knò999HJJbÉ’%4lØ===ÒÓÓ‰ŠŠâáÇ>|ø¥£š””6n܈žž5’Ž {úô)‡&??ŸÛ·o³gÏ>ÌáÇ_{±*==©S§„³³3[·n-±_éé顬¬Œ½½=ÖÖÖ%ö«‡bffÆ… ¤òGމ‡‡!!!¯4 úà#¬: ¥¥Evv¶´kûرcrM__ŸÉ“'“˜˜HÇŽçv7ÆÆÆo½ùº¯¬­­¹}û6Ÿ}öššš¢î£FÂÛÛ›.]ºÈý+z纺º¨ªª2xð`TUUiݺ5qqq(**’MNNŽÔÇrssñööÆÛÛKKKš5kÆÐ¡CQRRÂÀÀ€‹/Jÿü_ìkEÿøé§ŸX²d :::ÄÅÅñí·ß¾´îêêê,^¼X ùÖúo¿*l<|øN:•دrrr¦Y³fRy}úô¡~ýúhhh¼Ú †LP®Œ5J¶víZ™L&“YXXÈLLLd'Nœ%%%É–-[&suu•…††Ê/^,“Éd²™3gÊLLLd{öìW…ÉÈÈÞ¹L&“]»v­Äwnjj*311‘]ºtI&“ÉdG•™˜˜Èºwï.-JYXXÈV­Z%[»v­,&&Fæïï/311‘ 6L&“Éd›7o–…‡‡Ëd2™lûöí²ÐÐPYhh¨ÌÄÄDfbb"ËÍÍ•Éd2Ùõë×e³fͪTí( G‚J@‘Û¢Òœh¾/^äܹs|ÿý÷¨©©UšvK ¨n~þùçåR^ll,ïe‘§<ù?t‡í=Y…°§IEND®B`‚snd-16.1/pix/sceq36.png0000644000076400007640000000337511147553270012762 0ustar bilbil‰PNG  IHDR'LÀ^3PLTEÿÿÿÀÀÀ€€€ÐÐÐ ```PPP   ààà@@@pppððð°°°000^Q(I pHYs  šœtIME× .¥o¥]IDATxÚí\éšœ äe@Ô÷Úp rˆ®;;›¥L¾L€jš¶-*<`Ë< €ÝjÆ À+a@,=5ÃÂå챨A#Æ"âÍ{Q®¼ñ]_7JÕ'š–Ìâmˆo…| ,z…)U½S½6m26s>È¿ÜGl…üéj mž˜ýb ׺dó6ž_'¢ŠØù³YDÑ^Â1ò€µÞqÝB:€«SĨ†Ø ù£qÂ`ÑDqÂfé±ãCs}uÙë…ÃPèϤ˜/ÄK±ò²‰gÚ@Y^dC¤›¾l^a5]ýrŸS÷0mÇå‡*¥+=øDm 2ˆ ;®iÓœ²î G ú‰Që ¹‹®ïÔÆ“ß¼i3cúQ"Kå‰ÚrלOÒ]±—êBû0Ÿø¡x82UÌ'ó@êÏMFu ;®|!˜Çm8Ÿ“ß’ü˜8“,-2ÌeT .Ù8a¹®é¿ïÆ%§½‘Aôd*G–4¤ê'0”€¹ì,øŽ;€1ˆ1æöqÄ&°Hæ¤ÝqÜ,3¦ekqu.ú8åê8NãÄ^›ßÌáÃ:ÄÙèô’£orƒèÉT¶ŽkH2ÙÌt|atñ¸’_áIÒy´Œ˜œÍI¹³s³tL?Jk¨ž7 e©‹–ÝóH°|wpóq‘Íß½•Aôdj_Æ’¹OØ<‹å*ÎI¹6LÆtÿÈ[h;‚&eÙzä‘aº‘ ;îïH&š¤{=óbtˆÈ/˜i;g…×Î÷Mz<’ÔûO8ܰ¼tošîïèâÈËÇ[Mû»‹{JãcÀ#×*MWÇ\F¾nÛxçØ˜€KŸabù"¬NÝó;køKˆMsìK"9±·!¾ò ›qÀ# }â[!Ÿ0õ“å‘ }â›!:Þ xäÿ ùF‹tËïËQº•ë–©,j7+ 6YdzœŠG¡Ñ5•§‚™ÝlϧóòóŠ”nݺuëÖ­Û²~a¾Éú…ùFrÝ/Ì7nþÿè…ùnû&¸.eø•Z„/Ú )CÔåóµ .é â.®EÐ+y_Xàíš”!×壵Æn ¼]•2äº|²ÁæÐ]aÁž¥ ¹.Õ>é îø€°ÀZYÊ5 -éR¹„¡½©Ë¼ƒµ¾§Tx@Xà¨HpþÂi¦KY‹ ¼ÉÈvDà`µhÜQ*< ,ða¯HH>K®h”799BpÒ;XßuÜQ*|¯°À_žhsœJZåM,G(ÄI9ø-J…ïø¯^ù5¾¢EpÞìr„Bœ”ƒgJêç×®TxXX‘2DÍì]XZèRÔ"ض»$ ïà©RèJ…ïp˜63ëyšöÉèLÛXŽÏ'ý9TËS€Þ¨TøVaöäÐÌ iJd©¤EÐÞ„r„Rœ¤ƒ'J‹~E©ð‚ý¾¼NÛ°™€#Ï‰ëø¡OF7 ¼‰äIœvO” ý¦Rá)aAÀȶL³0Ÿ|nû€T7xñ­D#ÁÅ™RÁÞƒ¸§TxJX0²0A}3[Ÿ´§N‹Pès(,ùãè£Fâ‚®à–Rá)aAÀȲº‚hýínå¬}®×Üñ9aÁμ²º‚hýƒ¨Ôú|ÐiÁ“ÂËÈt»¡½ÏpìKY‹® P?4÷ùý¦…Ž‘µé ŒáZŸßoDxFÖª+P¿^íÓíã-þiÂþÛyaýŸC´õ¬ïÏY$,ðòóné)_p§Ç©h‘°ÀËô»•v³.¡P¿ÜØ?üœGâè³O`IEND®B`‚snd-16.1/pix/sum2.png0000644000076400007640000000444011147553271012537 0ustar bilbil‰PNG  IHDR½{àè^YsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ,HŒ+Q IDATxÚíÝë’£6@aØÚ÷žÙ''âÄËøX—–ú;U©ÚLÙKê>jYÀºmÛ¶€_š@z¤é@zåùÝëƒ×u]–eYf¸Lðö]>Å%“0©ôfݧÂZ×õ¯c ÞT¢{v,Ò !»z&@òÒ›Fv¯H~@zÓÊŽü€ôš /ªPÈHoÊêŽü ,.NßUw£‰ãþœK]/¤7©ìf©’U~Ò¾ºSõé]ÞŒ¨ú€ôROÕ¤—v—#ñ@2éÍøûÝUñ‘ÒK"¼ÌXî€É¥Gx¯«> ½ƒ"!<
¥GxsŠüdáÔ½7·m»” [&ÕêÂû~ó]¾‹vÿÜÛŸÿm·íyÇ‹”‰‘oc ÓàvÒëºJ 9=æ•ÀmìW&OÚæiÛ]°%¹Í4aéE“^‘ã탲T> ö£Ç~'ˆ“††çŒÎ’«#Ò«t¬Ávÿ™·Ï{%І’¨þˆ¥gß“Ç]ëø @ô”^É„XJz—ŽÓ;¨níøµ„ ˆ0¶ìzŽË(缕^¤¤zú½èQRߟsÀàîº öH›!dÈÙ¥wêý­æ“„,¸Ã\þA‚¤B~È*½Ãïm 5r àyÝ# æ–ùôžE­€Ø'ÝÚ× ’ù!ŸôÞ¾¯f´]PùUßÙ9K_"Š™$A~˜Qz‡…WrÐGJžA{¸Û¼`1Ì(tä”ÞË×—æèI2PÕ7ÜýM³ 0“ T}]z‡„÷]ø."Ñ“a€ÀþÆÞ˜Yª>Œ(½§¯+Ì3$½Î=Í-f ¤¯êÃXÒ{+¼+ƒxæäÖ)°‡Úà’aŒHô&˜DzWƒ9Ëï8ª¾ºá{IîÚcJï©ð®ÊΆ⛽ú“ÔUÁSz Ïöô0ËÓ>¹>Ú+Ðß%ôJú‚ô0ìŒvØ›*×N” «?UßU]ᑦ™Ñöà¥Gö´LŽÉª?⸪k$<ÒÔö!©=Û.Iõf¹“øÎO¼vëZŽ =¤ì7oŸ>!B›%©þºæ—ì¿ó]c»œR³ÿH;ëarZîd5¡¡ðH[Û|–°ˆ/w||2qz2q&=Hîª`Õ_\Ó-ß̶*RbŒ<É-¼@zØ&)¨ê 0^ä‰VýCzؤŸF€aÄ7Â8)Ýç/rCË~!=ѧ ›V7îÛ7ù uÈ€ÜÓ 0”øzŸš}ø&ôèÒ1zJ¦~2{í¾:÷½@z ?¯ŸTK0L.ª-¿V“’ƒßƒô@~Λ‰¯Ü8kÝæ'νg{“H„ìH0ZNº2îzµéÉsíÝΤR!;Œš—^ÃÞmv!F"´/édÈn 6Jê!sÓ÷®=þtšìÏãDŒDiWÒC\ùµOÏDhvÛÙùêi ·óh=1+‘òýié­ëZæ‘í¤‡^2ú~Xˆn.b•_æªoDé“_6ñÝËn¤*—ô °øf—ßÈKº¤Å7{Õ7úo˜¤ª¾C²›aÓ逪ïpu7ú.UÒUßÔÕÝ=¿ Ih/¾è™õúCÒòû!»…Gz@~)dGz@~é™DzP~5%´ßP“龡¤ÁäWC€™EGz0°K3+Ý¥çyT ß¶¸‹Ó*½È¦~6ƒq<Çs<Çs¼ù÷ *=@H@z^P¢oÅu~ÎÏù9?çGz¤ÀEÖÍ}i*=HÒÛsöÎà¥î$˜ƒ³Nxç‘_5OtÛ¶eÛ¶C'}öõÂ;ëË›@ð7 DVjì³$= aàYñät P…wû÷MtûÿßÿmÿÈ–ûc‘% Ò³YøYÉÝuÿïWâºÞ-žîÏðÛ8fŸ(^ß¿kò£Yj©×x]5Š#Ì2ž>„öˆGª.o>úÐW'.Hò1Ì6ž?ñˆ,@ ß/ÛÜÏtϼßÒ&ð¤ztïM@þž¢¹?éIEND®B`‚snd-16.1/vct.h0000644000076400007640000000276412333261443011312 0ustar bilbil#ifndef VCT_H #define VCT_H #if HAVE_SCHEME typedef struct s7_cell vct; #else typedef struct vct vct; #endif #ifdef __cplusplus extern "C" { #endif MUS_EXPORT void mus_vct_init(void); MUS_EXPORT int mus_vct_print_length(void); MUS_EXPORT void mus_vct_set_print_length(int len); MUS_EXPORT Xen mus_array_to_list(mus_float_t *arr, mus_long_t i, mus_long_t len); MUS_EXPORT bool mus_vct_is_equal(vct *v1, vct *v2); MUS_EXPORT char *mus_vct_to_readable_string(vct *v); MUS_EXPORT vct *mus_vct_make(mus_long_t len); MUS_EXPORT vct *mus_vct_free(vct *v); MUS_EXPORT double mus_vct_peak(vct *v); MUS_EXPORT Xen xen_list_to_vct(Xen lst); MUS_EXPORT vct *xen_to_vct(Xen arg); MUS_EXPORT Xen xen_make_vct(mus_long_t len, mus_float_t *data); MUS_EXPORT Xen xen_make_vct_wrapper(mus_long_t len, mus_float_t *data); MUS_EXPORT Xen g_vct_peak(Xen obj); MUS_EXPORT vct *mus_vct_wrap(mus_long_t len, mus_float_t *data); #if HAVE_SCHEME #define S_vct "float-vector" #define Xen_to_vct(Obj) (vct *)Obj #define mus_vct_length(V) s7_vector_length((s7_pointer)V) #define mus_vct_data(V) s7_float_vector_elements((s7_pointer)V) #define mus_is_vct(Obj) s7_is_float_vector(Obj) #define vct_to_xen(V) (Xen)V #else #define S_vct "vct" #define Xen_to_vct(arg) ((vct *)Xen_object_ref(arg)) MUS_EXPORT mus_long_t mus_vct_length(vct *v); MUS_EXPORT mus_float_t *mus_vct_data(vct *v); MUS_EXPORT bool mus_is_vct(Xen obj); MUS_EXPORT Xen vct_to_xen(vct *v); #endif #ifdef __cplusplus } #endif #endif snd-16.1/nb.rb0000644000076400007640000002546012453076052011272 0ustar bilbil# nb.rb -- translation of nb.scm # Translator/Author: Michael Scholz # Created: 02/12/10 22:08:15 # Changed: 14/11/13 03:02:23 # Tested with Snd 15.x, Ruby 2.x.x # # type nb = make_nb # nb.help # or xnb = make_nb_motif (installs a popup menu on info widget) # # global variable: # $nb_database # # make_nb(path) # # class NB # initialize(path) # # getter and setter: # name=(filename) # name # notes=(new_notes) # notes # # interactive methods: # unb # prune_db # open(path) # close # help (alias info and description) # =begin nb = make_nb nb.name nb.notes nb.notes = "new text" nb.prune_db # deletes empty entries nb.unb # deletes entry of current file nb.open # adds mouse hooks nb.close # removes mouse hooks nb.help # this help =end require "hooks" with_silence do unless defined? DBM.open require "dbm" end end $nb_database = "nb" unless defined? $nb_database if provided?("snd-motif") and (not provided?("xm")) with_silence(LoadError) do require "libxm" end end module Kernel # XM_NB should only create one instance of the popup menu on the # info_widget. @@XM_NB = false def Kernel.xm_nb @@XM_NB end def Kernel.xm_nb=(val) @@XM_NB = val end end def make_nb(path = $nb_database) NB.new(path) end def make_nb_motif(path = $nb_database) if Kernel.xm_nb.kind_of?(XM_NB) Kernel.xm_nb.open(path) else Kernel.xm_nb = XM_NB.new(path) end end if provided?("xm") class NB include Info Region_viewer = 2 View_files_dialog = 8 Info_dialog = 20 def initialize(path) @nb_database = path @type = nil @position = nil @name = nil @notes = "" @alert_color = make_color(1.0, 1.0, 0.94) @db_hook_name = format("%s-nb-hook", @nb_database) set_help create end attr_reader :name, :notes alias help description def inspect format("#<%s: nb_database: %s, open: %s, name: %s>", self.class, @nb_database.inspect, $mouse_enter_label_hook.member?(@db_hook_name).inspect, @name.inspect) end def name=(filename) if filename and File.exist?(File.expand_path(filename)) @name = filename show_popup_info else Snd.warning("no such file: %s", filename.inspect) end end def notes=(new_notes) @notes = new_notes nb @notes end def with_dbm(&body) ret = nil db = DBM.open(@nb_database) ret = body.call(db) db.close ret rescue Snd.warning("%s#%s", self.class, get_func_name) end def prune_db with_dbm do |db| db.delete_if do |k, v| k.empty? end end self end def open(path = @nb_database) @nb_database = path create self end def close $mouse_enter_label_hook.remove_hook!(@db_hook_name) $mouse_leave_label_hook.remove_hook!(@db_hook_name) self end def unb if @name and File.exist?(File.expand_path(@name)) with_dbm do |db| db.delete(@name) end show_popup_info else Snd.warning("no such file: %s", @name.inspect) end end private def create close $mouse_enter_label_hook.add_hook!(@db_hook_name) do |t, p, n| files_popup_info(t, p, n) unless t == Region_viewer end end def nb if @name and File.exist?(File.expand_path(@name)) with_dbm do |db| db[@name] = @notes end show_popup_info else Snd.warning("no such file: %s", @name.inspect) end end def files_popup_info(type, position, name) @type = type @position = position @name = name show_popup_info end def show_popup_info let(dialog_widgets[Info_dialog]) do |info_exists_p| info_dialog(@name, file_info) if info_widget = dialog_widgets[Info_dialog] unless info_exists_p width, height = widget_size(dialog_widgets[View_files_dialog]) set_widget_position(info_widget, [width + 10, 10]) end end end @name end def file_info with_dbm do |db| @notes = (db[@name] or "") end cs = mus_sound_chans(@name) sr = mus_sound_srate(@name) len = format("%1.3f", mus_sound_samples(@name).to_f / (cs * sr.to_f)) d_format = mus_sample_type_name(mus_sound_sample_type(@name)) h_type = mus_header_type_name(mus_sound_header_type(@name)) frms = mus_sound_framples(@name) max_amp = "" if mus_sound_maxamp_exists?(@name) str = "" mus_sound_maxamp(@name).each_pair do |s, v| str << format("%1.3f (%1.3fs), ", v, s / sr.to_f) end max_amp = format("\n maxamp: [%s]", str[0..-3]) end fdate = Time.at(mus_sound_write_date(@name)) date = fdate.localtime.strftime("%a %d-%b-%y %H:%M %z") info_string = format("\ chans: %d, srate: %d length: %1.3f (%d frms) format: %s [%s]%s written: %s\n", cs, sr, len, frms, d_format, h_type, max_amp, date) if defined?($info_comment_hook) and hook?($info_comment_hook) if $info_comment_hook.empty? if s = mus_sound_comment(@name) info_string += format("comment: %s\n", s) end else $info_comment_hook.run_hook do |prc| info_string = prc.call(@name, info_string) end end else if s = mus_sound_comment(@name) info_string += format("comment: %s\n", s) end end info_string += "\n" + @notes end def set_help self.description = "\ # global variable: # $nb_database (#{$nb_database}) # # make_nb(path) # make_nb_motif(path) # # class NB # initialize(path) # # getter and setter: # name=(filename) # name # notes=(new_notes) # notes # # interactive methods: # unb # prune_db # open(path) # close # help (alias info and description) nb = make_nb nb.name nb.notes nb.notes = \"new text\" nb.prune_db # deletes empty entries nb.unb # deletes entry of current file nb.open # adds mouse hooks nb.close # removes mouse hooks nb.help # this help " end end class XM_NB < NB require "popup" def initialize(path) @dialog = nil @file_name = nil @text_widget = nil @message_widget = nil super @db_str = format("DB: %s", File.basename(@nb_database)) @popup_nb_hook = Hook.new("@popup_nb_hook", 2, "\ lambda do |snd, info| ... \"new info\" end: called in popup.rb on graph-popup-menu entry `Info'. Its primary use is to communicate between popup.rb and nb.rb. To add your own information to the info string, you may use $info_comment_hook. The current selected SND is called with string INFO. If more than one hook procedures exists, each procedure's result is passed as input to the next. E.g. if an instance of NB or XM_NB is created (see nb.rb), the $nb_database entries of SND will be returned.") @popup_nb_hook.add_hook!("initialize-nb-hook") do |snd, info| @name = file_name(snd) with_dbm do |db| @notes = (db[@name] or "") end unless @notes.empty? info += "\n" unless info.empty? info += @notes end info end install_menu end attr_reader :popup_nb_hook def close if @dialog.kind_of?(Dialog) and RWidget?(@dialog.dialog) and RXtIsManaged(@dialog.dialog) RXtUnmanageChild(@dialog.dialog) end super end protected def post_edit if !@name and RWidget?(@message_widget) @name = if File.exist?(file = current_label(@message_widget).split[0]) file else format("no such file: %s", file.inspect) end end unless @dialog.kind_of?(Dialog) and RWidget?(@dialog.dialog) @dialog = make_dialog(@db_str, :help_cb, lambda do |w, c, i| help_cb end, :clear_cb, lambda do |w, c, i| RXmTextSetString(@text_widget, "") end) do |w, c, i| self.notes = RXmTextGetString(@text_widget) end @file_name = @dialog.add_label(@name) @text_widget = @dialog.add_text(:rows, 16, :columns, 60, :wordwrap, true, :value, @notes) @dialog.doit_string("Submit") end activate_dialog(@dialog.dialog) show_edit_info end def help_cb help_dialog(@db_str, "Edit info DB of sound files (see nb.scm). Provides pop-up help in the Files viewer. \ If you have `dbm', any data associated with \ the file in the dbm database will also be posted. \ The database name is defined by $nb_database \ (#{$nb_database.inspect}). o Edit info: opens the edit widget o Prune DB: clears non-existent file references out of the database o Clear: removes info entry from current file o Close: removes mouse hooks and popup menu; type `make_nb_motif' to reinstall the hooks and popup menu o Submit: submits info from edit widget to file info database #{self.description}", ["{Libxm}: graphics module", "{Ruby}: extension language", "{Motif}: Motif extensions via libxm"]) end def post_popup? $mouse_enter_label_hook.member?(@db_hook_name) and File.exist?(current_label(@message_widget).split[0]) end private def create @db_hook_name = format("%s-xm-nb-hook", @nb_database) super end def install_menu if RWidget?(wid = dialog_widgets[Info_dialog]) setup_menu(wid) else $new_widget_hook.add_hook!("nb-edit-hook") do |w| if w == dialog_widgets[Info_dialog] setup_menu(w) $new_widget_hook.remove_hook!("nb-edit-hook") end end end end def setup_menu(wid) @message_widget = find_child(wid, "Message") make_snd_popup("NB Edit Info", :where, :event, :parent, find_child(wid, "post-it-text")) do entry("Edit Info") do |w, snd, chn| Kernel.xm_nb.post_edit end entry("Prune DB") do |w, snd, chn| Kernel.xm_nb.prune_db end entry("Clear current Info") do |w, snd, chn| Kernel.xm_nb.unb end entry("Close NB Edit") do |w, snd, chn| Kernel.xm_nb.close end separator entry("Help") do |w, snd, chn| Kernel.xm_nb.help_cb end before_popup_hook.add_hook!("NB Edit Info") do |d1, d2, d3| Kernel.xm_nb.post_popup? end end end def files_popup_info(type, position, name) super show_edit_info end def show_edit_info xfname = string2compound(@name) if RWidget?(@file_name) RXtVaSetValues(@file_name, [RXmNlabelString, xfname]) end if RWidget?(@text_widget) RXtVaSetValues(@text_widget, [RXmNvalue, @notes]) end RXmStringFree(xfname) end end if provided?("xm") # nb.rb ends here snd-16.1/HISTORY.Snd0000644000076400007640000027271612626046436012172 0ustar bilbilSnd change log 30-Nov: Snd 16.1. 19-Oct: Snd 16.0. 11-Sep: Snd 15.9. 1-Aug: Snd 15.8. 15-Jun: Snd 15.7. 11-May: Snd 15.6. 3-Apr: Snd 15.5. 20-Mar: changed the no-gui repl to use repl.scm in the s7 case. 27-Feb: Snd 15.4. 25-Jan: Snd 15.3. 2015 ---------------------------------------------------------------- 18-Dec: Snd 15.2. 5-Nov: moved all the motif stuff (xm.c, snd-motif.scm etc) to the *motif* environment, OpenGL (gl.c, snd-gl.scm) to *gl*, and gtk (xg.c, snd-gtk.scm etc) to *gtk*. 4-Nov: Snd 15.1. 25-Sep: Snd 15.0. 17-Sep: moved snd-x*.c to snd-motif.c 18-Aug: Snd 14.9. 9-July: Snd 14.8. 31-May: Snd 14.7. 23-Apr: Snd 14.6. 18-Mar: Snd 14.5. 12-Feb: Snd 14.4. 4-Jan: Snd 14.3. 2014 ---------------------------------------------------------------- 22-Nov: Snd 14.2. 15-Oct: Snd 14.1. 11-Oct: removed frame.scm and mixer.scm: frames and mixers are obsolete in the scheme version of Snd. 11-Sep: Snd 14.0. Homogenous vectors, write readably, libc.scm, libgsl.scm. 5-Sep: removed kmenu.scm and oscope.scm. 9-Aug: write.scm, removed pretty-print.scm. 3-Aug: Snd 13.9. 17-Jul: many changes to the configure script, added tools/make-config-pc.rb. 30-Jun: Snd 13.8. 11-Jun: removed the view files dialog from the gtk version, including all the related extension language functions, and view-files-select-hook. 25-May: Snd 13.7. 14-May: glistener.c/h (gtk listener). 22-Apr: Snd 13.6. 12-Mar: Snd 13.5. 4-Feb: Snd 13.4. 2013 ---------------------------------------------------------------- 25-Dec: Snd 13.3. 30-Oct: Snd 13.2. 20-Sep: Snd 13.1. 8-Aug: Snd 13.0. 3-July: removed ptree-channel and max-virtual-ptrees, optimization, run.c. (clm 5.0, sndlib 22.0). 26-Jun: Snd 12.12. 4-Jun: removed the --with-static-* configuration switches. 21-May: Snd 12.11. 11-May: all scheme-side hook code changed. removed print-hook. 1-May: removed mus-audio-describe, ESD audio support, audinfo. 12-Apr: Snd 12.10. 5-Mar: Snd 12.9. Feb: s7: added random-state?, hash-table-iterator?, and morally-equal? clm/cmn/snd/s7: removed snd1.html and snd-contents.html (these were using Javascript for stuff that is now built into html), and translated the rest of the html files to html5. snd: removed the recorder, recorder-dialog, snd-g|xrec.c, changed various menu names and added a view:with-grid menu moved dialog buttons around at random, removed save-macros and named keyboard macros, added context-sensitive tooltips to the gtk version, changed the gtk listener default font to Monospace 11, the "minibuffer" is now a "statusbar". This means it is not editable, so all the key sequences that used to prompt for info are either undefined now, or use a dialog instead. removed minibuffer-history-length, prompt-in-minibuffer, clear-minibuffer, and report-in-minibuffer. Replaced the latter two with status-report. removed sound-specific search-procedures (i.e. there is only one search procedure) removed the bomb function 2-Feb: Snd 12.8. 27-Jan: removed snd10.scm. 2012 ---------------------------------------------------------------- 30-Dec: Snd 12.7. 8-Nov: Snd 12.6. 29-Sep: Snd 12.5. 19-Aug: Snd 12.4. 18-Aug: removed snd9.scm. 14-Jul: removed thread stuff. 11-Jul: Snd 12.3. 30-May: Snd 12.2. 24-Apr: Snd 12.1. 5-Apr: lint.scm. 25-Mar: show-full-range, info-popup-hook. 21-Mar: with-interrupts. 18-Mar: Snd 12.0. 18-Mar: removed time-graph-hook; replaced by combined-data-color. 10-Mar: space=play or pause, tracking-cursor stuff changed. 4-Mar: 'src' button in Save-as dialogs to do automatic sampling rate conversion. 1-Mar: delete-selection-and-smooth, delete-samples-and-smooth. 23-Feb: sync-style variable: sync-none, sync-all, or sync-by-sound (the new default). Options:Controls menu item, and Edit:Unselect show-selection and unselect-all. show-full-duration, initial-beg, initial-dur, ask-about-unsaved-edits. with-toolbar, with-tooltips, remember-sound-state, with-smpte-label. new built-in toolbars, removed toolbar.scm and panic.scm. removed Snd.gtkrc, Snd.ad, and the totally obsolete X resources stuff. The built-in popup menus are now context sensitive, and the files popup.scm and gtk-popup.scm have been removed. with-menu-icons (Gtk only). play-arrow-size 12-Feb: Snd 11.13. 7-Jan: Snd 11.12. 2011 ---------------------------------------------------------------- 29-Nov: Snd 11.11. 5-Nov: add|delete-watchers removed, replaced by effects-hook. 25-Oct: Snd 11.10. 22-Sep: def-clm-struct is now just a synonym for defgenerator. 19-Sep: removed snd7.scm and snd8.scm. 18-Sep: Snd 11.9. 19-Aug: removed the Gdk backend option; cairo is now the only choice. 12-Aug: Snd 11.8. 9-Aug: make-index.scm (replaces index.cl and indexer.scm). 30-Jul: removed *-button-color. 8-July: Snd 11.7. 12-Jun: removed window-property, window-property-changed-hook, send-mozilla. removed snd-gxutils.c. 7-June: Snd 11.6. 27-May: removed snd6.scm. added binary-io.scm. 29-Apr: Snd 11.5. 7-Apr: autoload support via s7's *unbound-variable-hook*. 20-Mar: Snd 11.4. 27-Feb: the run macro's argument no longer has to be a thunk. 11-Feb: Snd 11.3. 9-Feb: removed NLS support (the po directory and so on). 8-Feb: moved sound|channel|mix|mark|edit-property to C. 23-Jan: The rest of the Guile-dependent files have been removed. This includes pd-*, rt-*, and the --with-snd-as-pd-external --with-hobbit, and --with-rt configuration switches. 5-Jan: Snd 11.2. 2010 ---------------------------------------------------------------- 26-Dec: tools/sam.c. 21-Dec: moved focus-follows-mouse to C as with-pointer-focus. removed def-optkey-fun and def-optkey-instrument (use define* and definstrument). 16-Dec: make-current-window-display (draw.scm) moved to C as with-inset-graph. removed Guile support. 14-Dec: peak-env support moved to C, added peak-env-dir, removed peak-env.*, peak-env-info, read-peak-env-info-file, and write-peak-env-info-file. 11-Dec: removed midi.c and Alsa < 1.0 support. 7-Dec: removed SGI support. 4-Dec: portaudio support. 1-Dec: removed --with-modules configuration switch. 30-Nov: Snd 11.1. 23-Nov: colormaps are objects now. integer->colormap, colormap->integer. transforms are also objects. integer->transform, transform->integer. 20-Nov: play is generic now, "old-play" is the previous form. 6-Nov: removed all support for gtkglext. 2-Nov: selection function/object. selection->mix. 28-Oct: pretty-print.scm. 22-Oct: Snd 11.0. 16-Oct: clm.rb and grani.rb (thanks to Mike Scholz). 12-Oct: generic length, srate, channels, frames, file-name, sync, maxamp. 7-Oct: removed run-safety; the run macro only works in s7. 6-Oct: removed *snd-loaded-files* and *snd-remember-paths*. removed tools/sed-href, tools/lines.scm, and tools/check-gtk.scm. 29-Sep: mixes are objects (not ints), integer->mix and mix->integer. all "sample-reader" and "sample_reader" names changed to "sampler". marks are objects (not ints), integer->mark and mark->integer. regions are objects, integer->region, region->integer. several region functions now take the region argument first: insert-region, make-region-sampler, mix-region, region-sample, region->vct, region->frame, make-region-frame-reader. sounds are objects, but integers are still ok, integer->sound and sound->integer. players are objects. removed export-all.scm, snd4.scm, snd5.scm. 17-Sep: Snd 10.9. 10-Sep: removed show-backtrace. default optimization is 6. 9-Aug: Snd 10.8. 6-Jul: Snd 10.7. 2-Jul: default audio in Linux is now ALSA. 28-May: Snd 10.6. 17-Apr: Snd 10.5. 26-Feb: Snd 10.4. 30-Jan: big-gens.scm (scheme-only versions of the built-in generators). 15-Jan: Snd 10.3. 8-Jan: multiprecision math support for all scheme (s7) numeric types and functions via gmp, mpfr, and mpc. In configure, use --with-gmp. 2009 ---------------------------------------------------------------- 29-Dec: jcvoi.scm. 11-Dec: snd10.scm for sum-of-sines and friends. 28-Nov: Snd 10.2. 17-Nov: removed s7-optargs.scm -- define* is now built-in in s7. 11-Nov: removed s7-format.scm -- format is now built-in in s7. 4-Nov: moved snd-run.c to run.c (for sndlib). 29-Oct: osc.scm thanks to Kjetil. 16-Oct: removed Gauche support. 15-Oct: Snd 10.1. 3-Sep: Snd 10.0. 1-Sep: S7 extension language. 14-Jul: Snd 9.11. 7-July: with-threaded-channels. 30-Jun: flatten-partials. 27-Jun: axis-color. 20-Jun: time-graph-hook. 6-June: with-threaded-sound (ws.scm) 2-June: Snd 9.10. 30-May: peak-phases.scm. 20-May: rt-various.[ch], rt-coroutines.scm, rt-stalin.scm, rt-DotEmacs, and many other changes thanks to Kjetil. many const char* changes for g++ 4.3.0. 17-May: normalize-partials is now built-in. 12-May: expandn (clm-ins.scm) thanks to Michael Klingbeil. 10-May: merged green.scm into generators.scm. 5-May: music5 port: music5.f, music5-examples, old-music5.f 24-Apr: Snd 9.9. 29-Mar: wz_data.js. 25-Mar: with-mixed-sound and with-mixed-sound->notelist (ws.scm). 18-Mar: selection.scm. 17-Mar: Snd 9.8. 7-Mar: rt-faust.scm and rt-DotEmacs (thanks to Kjetil). 25-Feb: defgenerator. 24-Feb: envelopes can be in the form '((0 0) (100 1)). 11-Feb: the "stream" arg to outa and friends now defaults to *output*. 7-Feb: Snd 9.7. 2008 ---------------------------------------------------------------- 26-Dec: Snd 9.6. 17-Nov: fft-with-phases. 12-Nov: Open recent item in File menu. 8-Nov: Snd 9.5. 4-Nov: mingw changes thanks to Kjetil. 2-Nov: animals.scm. 11-Oct: changed default srate to 44100. 29-Sep: Snd 9.4. 20-Sep: export-all.scm. 4-Sep: generators.scm. 24-Aug: Snd 9.3. 7-Aug: renamed "correlate" in examp.scm to "display-correlation". 3-Aug: blackman5..10 and rv2..4 fft windows. rt-clm-ins.scm thanks to Kjetil. Savitzky-Golay filter (dsp.scm). 1-Aug: numerics.scm. 19-Jul: sndclm.html (Snd-specific version of clm.html). 12-Jul: Snd 9.2. 9-July: snddiff.scm. 1-July: max-virtual-ptrees. 7-June: Snd 9.1. 1-June: mix-sync-max. 28-May: mus-sound-mark-info. 21-May: background-gradient (gtk+cairo only). 9-May: peak-env-hook, draw-mix-hook. 1-May: Snd 9.0. 16-Apr: removed mix-chans, mix-locked?, mix-inverted?, all track stuff track-colors.scm, mix-menu.scm moved mix-properties into C. added edit-properties, mix-sync. spokenword.scm thanks to Ville Koskinen. 23-Mar: recorder dialog removed. 22-Mar: Snd 8.9. 14-Mar: cairo graphics backend (--with-cairo configure choice). 1-Mar: open-file-dialog-directory. 26-Feb: clean.scm (noise reduction). 17-Feb: File:Close all menu if more than one sound open. 14-Feb: three new fft windows. 9-Feb: Snd 8.8. 1-Feb: CAFF headers. 2-Jan: Snd 8.7. 2007 ---------------------------------------------------------------- 29-Dec: -nogtkrc startup switch. 27-Dec: add-source-file-extension. pi is now defined by default in Scheme. 21-Dec: unclip-channel. 17-Dec: region-home. 14-Dec: bird.fsm (Mike Scholz). 12-Dec: clip-hook. 11-Dec: sound-data-multiply! sound-data-add! sound-data-offset! sound-data* sound-data+ sound-data-copy sound-data-reverse! sound-data-peak. 4-Dec: frame.scm: sound->frame frame->sound region->frame make-frame-reader frame-reader? frame-reader-at-end frame-reader-position frame-reader-home free-frame-reader copy-frame-reader frame-reader-chans next-frame previous-frame read-frame make-region-frame-reader make-selection-frame-reader make-track-frame-reader read-track-frame make-sync-frame-reader frame->sound-data, sound-data->frame sound->sound-data sound-data->sound region->sound-data track->sound-data selection->sound-data file->vct vct->file frame->vct vct->frame file->sound-data sound-data->file insert-sound-data insert-frame insert-vct mix-sound-data mix-frame scan-sound map-sound simultaneous-zero-crossing compand-sound sync-all pad-sound contrast-sound dither-sound scale-sound offset-sound normalize-sound moved open-sound-file, close-sound-file, and vct->sound-file to snd8.scm. 29-Nov: Snd 8.6. 21-Nov: sound-data-scale! and sound-data-fill! with vct/sound-data with-sound output. mus-float-equal-fudge-factor fade.scm instruments changed to use outa rather than vct-map! 20-Nov: generic out-any, in-any, locsig, move-sound, mus-length, mus-channels. 13-Nov: RF64 headers. 3-Nov: mix-name->id, track-name->id (mix.scm, mix.rb). 1-Nov: ->frequency, ->samples (ws.scm). mix-name, track-name, track-tag-y. 24-Oct: filter-fft in examp.scm. 23-Oct: Snd 8.5. 16-Oct: add-watcher, delete-watcher. 12-Oct: removed selection-changed-hook (use simpler watcher mechanism instead). 11-Oct: gtk-effects-utils.scm and gtk support for *-menu.scm. 9-Oct: with-file-monitor. 2-Oct: gl2ps support, gl-graph->ps function, --with-gl2ps switch, gl2ps.[ch]. 26-Sep: save-marks changed to keep matching sync values, add-marks takes name and sync args. moved config.h to mus-config.h. 12-Sep: Snd 8.4. 6-Sep: def-optkey-instrument. 1-Sep: snd_frg.scm thanks to Olivier Doare. 28-Aug: removed vu-font and vu-font-size, added vu-in-dB. 16-Aug: display-bark-fft (dsp.scm). after-lisp-graph-hook, snd-color, snd-font, show-bare-x-axis. 4-Aug: analog-filter.rb thanks to Mike. "scheme" instead of "guile" in various names in inf-snd.el (for gauche). 3-Aug: granulated-sound-interp (examp.scm). poly-resultant and poly-discriminant (poly.scm). 1-Aug: Snd 8.3. 31-Jul: windowed-maxamp renamed moving-max, added moving-rms, moving-sum, moving-length (dsp.scm) average renamed moving-average in clm. overlay-rms-env in draw.scm. 28-Jul: snd8.scm, removed make-ppolar|zpolar (use make-two-pole|zero). 27-Jul: mfilter in dsp.scm. 17-Jul: merged new-icons.scm into new-buttons.scm and renamed the latter toolbar.scm. 12-Jul: green.scm. 10-Jul: dlocsig.scm. 3-July: removed vct-map. 28-Jun: moved rmsgain code to clm-ins.scm. 23-Jun: Snd 8.2. 12-Jun: fmviolin.clm. 6-Jun: changed after-apply-hook to after-apply-controls-hook. 2-Jun: removed mus-make-error. 25-May: Walter Zorn's wz_tooltip.js to spruce up the documentation. 7-May: Snd 8.1. 21-Apr: many .fs files thanks to Mike Scholz (removed obsolete gfm directory). 15-Apr: Gauche as extension language. 12-Apr: clm-load (ws.scm) for cm. 31-Mar: rt-player.scm (Kjetil). 28-Mar: Snd 8.0. Forth as extension language, thanks to Mike Scholz. shorten, tta, wavpack support. 20-Mar: heart.scm (use Snd with non-sound data). 14-Mar: x-axis-as-clock for more informative x-axis tick labels in very large files. 10-Mar: added a stop sign to interrupt long computations (equivalent to C-g). 8-Mar: kmenu.scm thanks to Maxim Krikun. 3-Mar: show-selection (extensions.scm). 27-Feb: Snd 7.19. tracking-cursor-style. 21-Feb: bind-key now takes a character or string 1st arg (as well as an integer); if a string, it's treated as the X/Gtk key name (e.g. "Home" or "plus"). It also has a 6th optional arg, a preferences dialog name (so that the dialog can reflect current key bindings by functionality). with-tracking-cursor and with-verbose-cursor as synonyms for cursor-follows-play and verbose-cursor. 17-Feb: mus-file-data-clipped -> mus-clipping, added mus-file-clipping for local settings data-clipped -> clipping mus-prescaler (global) alongside previous mus-file-prescaler added pausing -- returns #t if DAC is paused, can be set to #t or #f to start/stop pausing similarly playing -- #t if DAC is running (may be paused), settable to start/stop playing removed dac-is-running (it's in snd7.scm) 9-Feb: Bill Sack's stochastic.scm and snd-stochastic.pd, stochastic.png in grfsnd.html. 2-Feb: mus_audio_sun_outputs -> mus_sun_set_outputs, added mus_netbsd_set_outputs. mus_audio_set_oss_buffers -> mus_oss_set_buffers. changed ALSA environment variable names to use MUS, not SNDLIB. changed ALSA default device to "default" from "hw:0" 30-Jan: new-sound-dialog. 15-Jan: Snd 7.18. 5-Jan: sound-file? for easier file-filter definition. 2-Jan: removed the sorting indices (sort-by-name|size|date|entry), and changed the way the user-defined sorter works. Also removed file-filters, file-sorters, and just-sounds-hook. 2006 ---------------------------------------------------------------- 26-Dec: help-snd-fm.pd and pd-fm.scm thanks to Kjetil. default sample type is now float. 19-Dec: analog-filter.scm: Butterworth, Chebyshev, inverse-Chebyshev, Bessel(-Thompson), Elliptic filters. new fft windows: samaraki and ultraspherical (related to the dolph-chebyshev window). fft-window-alpha (ultraspherical xmu parameter). 5-Dec: snd_pd_external.c and other changes for Pd, thanks to Kjetil. sinc-train (clm.html), reverse-by-blocks and reverse-within-blocks (examp.scm), pulse-voice (examp.scm). 28-Nov: Snd 7.17. 21-Nov: if --with-float-samples and --with-doubles, the internal sample data type is double. 18-Nov: moved snd-apropos to snd7.scm. 15-Nov: sync-max. 12-Nov: all dlp directory files moved to main directory (to simplify load-path handling). SND_PATH environment variable (optional load path directory list). 3-Nov: ws.scm definstrument macro changed to support :notehook arg in with-sound and *definstrument-hook* for CM. 27-Oct: effects-utils.scm to make various added menus independent. 12-Oct. Snd 7.16. 3-Oct: snd-g|xprefs.c, preferences-dialog function. 26-Sep: save-region-dialog, more buttons. 15-Sep: --enable-threads configure switch, and first use thereof (FIR filtering). 6-Sep: snd-error is now (throw 'snd-error ...). 31-Aug: mix|track-speed-style. changed recorder-in|out-format -> recorder-in|out-data-format, recorder-out-type -> recorder-out-header-type 28-Aug: Snd 7.15. 18-Aug: _sndlib.h and sndlib.h.in. 15-Aug: in View:Files, click of file name no longer opens that file. view-files-select-hook return type no longer matters, and args are: dialog file-name. optional dialog arg to view-files-sort (local set). -init startup switch to set init filename as arg snd-file.h 8-Aug: removed previous|view-files-sort-procedure. sort-files-by-name|size|date|entry. view-files-amp|speed|amp-env|speed-style|files|selected-files. removed keep-mix-dialog-open-upon-ok from snd-motif.scm before-exit|close-hook. 2-Aug: sound-file-extensions as settable list. 30-Jul: preload-directory -> add-directory-to-view-files-list, preload-file -> add-file-to-view-files-list. 29-Jul: previous-files-* -> view-files-* (sort, select-hook). 28-Jul: File:Insert menu item and dialog added, also insert-file-dialog. File:Save as can write OGG, Speex, and Flac files. 21-Jul: clear-minibuffer, new as-error arg to report-in-minibuffer. 15-Jul: removed yes-or-no? with associated dialog (and snd-g|xerror.c). 14-Jul: Snd 7.14. 5-Jul: default-output-type -> default-output-header-type, default-output-format -> default-output-data-format. 1-Jul: --with-fam configuration switch. tools/check-gtk.scm. 27-Jun: output-name-hook now takes an argument, the current output file name. changed find to find-channel to avoid collision with Scheme's srfi-1. 24-Jun: channels-combined is now the default channel-style. 20-Jun: 'Extract' option to Save as dialogs (to extract a channel). 13-Jun: folded gl-ruby.c into gl.c, xm-ruby.c into xm.c, xg-ruby.c into xg.c. 6-June: removed save-options (use save-state). 1-June: Snd 7.13. show-axes View:Axes menu. 26-May: beats-per-measure and x-axis-style x-axis-in-measures. 25-May: create-audit-dialog in snd-motif.scm. 23-May: maraca.rb, play.rb, prc95.rb, singer.rb, and zip.rb thanks to Mike Scholz. rt.tex thanks to Kjetil Matheussen. 16-May: before-save-as-hook. 2-May: region-|selection-|maxamp-position. windowed-maxamp generator (dsp.scm) harmonicizer (dsp.scm) 26-Apr: Snd 7.12. 25-Apr: y-axis-label. 20-Apr: draw.rb, poly.rb, musglyphs.rb thanks to Mike Scholz. zip.scm (zipper) changed (takes env args now, not thunks, uses def-clm-struct, etc). changed mus-error-to-string to mus-error-type->string. moved mus-data-format->string and mus-header-type->string from ws.scm to C. 18-Apr: removed xen->sample generator. changed moog.scm to use def-clm-struct, rather than a list. 12-Apr: before-save-state-hook. 8-Apr: poly.scm. 7-Apr: moved load-font to snd-motif.scm and snd-gtk.scm. 6-Apr: volterra-filter in dsp.scm 4-Apr: rt-examples.scm (Kjetil Matheussen). 30-Mar: marks.rb (Mike Scholz). 25-Mar: mixer.scm with various matrix/vector related functions (determinant, inverse, solve simultaneous linear equations, etc) as applied to mixers/frames. invert-filter in dsp.scm. 23-Mar: changed interpretation of frame->frame args. 18-Mar: Snd 7.11. 17-Mar: gc-on|off are no-ops now in Guile. pvoc.rb thanks to Mike Scholz. 10-Mar: dsp.rb thanks to Mike Scholz. 1-Mar: rt-engine.scm thanks to Kjetil Matheussen! zoom-focus-style can be a function 28-Feb: env-channel-with-base. Ruby side of edit-list->function. 24-Feb: mix.rb thanks to Mike Scholz. 22-Feb: changed libxm to libxg in gtk case, also xm-version to xg-version --with-static-xg configure option 21-Feb: removed snd_test.rb, replaced by snd-test.rb thanks to Mike Scholz! oo.scm and rt-compiler.scm thanks to Kjetil Matheussen! 11-Feb: Snd 7.10. 8-Feb: grani.scm and grani in clm-ins.rb thanks to Mike Scholz. CLM sndwarp (B Battey) translated to Scheme: sndwarp.scm. 31-Jan: removed support for Motif 1 and Lesstif. changed memo-sound to *snd-opened-sound*. snd-load-files to *snd-loaded-files*. snd-remember-paths to *snd-remember-paths* (default value is now #t). 26-Jan: removed useless edpos arg to controls->channel. 20-Jan: translation of CLM scentroid (B Battey) in dsp.scm. 19-Jan: changed send-netscape to send-mozilla. transform?, delete-transform. 18-Jan: changed transform-hook to after-transform-hook. variable-graph?, free-player. 14-Jan: moved makesnd.* into makefile.in. 10-Jan: colormap? moved sndsine.c to documentation 5-Jan: Snd 7.9. 3-Jan: removed next-to-last (xen fallback) arg to ptree-channel, and associated xen-channel stuff. 2005 ---------------------------------------------------------------- 29-Dec: eval-c.scm (Kjetil Matheussen). 7-Dec: after-save-as-hook, replacing emacs-style-save-as. 3-Dec: mark-tag-width|height. 29-Nov: quick.html 17-Nov: Snd 7.8. 16-Nov: moved the 'Apply' button and friends from the Controls pane to a popup menu. 5-Nov: recorder-in-chans. 1-Nov: edit history pane popup menu (popup.scm). 28-Oct: rms-envelope in env.scm. removed edpos arg to play-selection. 18-Oct: oscope.scm. 15-Oct: normalize-channel. 11-Oct: vct->string moved scale-sound-by and scale-sound-to to snd7.scm. sndins and gfm directories (Mike Scholz sndlib/clm code) controls->channel 5-Oct: Snd 7.7. 4-Oct: moved vct->samples and samples->vct to snd7.scm. edit-list->function changed transform-samples->vct to transform->vct, region-samples->vct to region->vct, transform-samples-size to transform-frames. (Old forms are in snd7.scm). 1-Oct: grid-density (controls axis tick spacing) 30-Sep: mus-audio-mixer-read|write vector arg is now a vct. 27-Sep: do? (examp.scm -- do that can be interrupted and continued) 20-Sep: show-sonogram-cursor. 13-Sep: removed buffer generator. log-freq-start. 9-Sep: vct-reverse! 8-Sep: create-ssb-dialog in snd-motif.scm. 6-Sep: removed vct-convolve! (see snd7.scm). removed float vector as possible arg to formant-bank (use vct) (see snd7.scm). removed oscil-bank, mus-bank (snd7.scm) 2-Sep: vct|channel|spectral-polynomial in dsp.scm. 23-Aug: Snd 7.6. 16-Aug: removed built-in Hadamard transform out-chan argument to add-player so that channel data can be sent to any audio channel (also play, play-and-wait, play-channel) 12-Aug: major gtk-version bugfix thanks to Kjetil 2-Aug: players: returns list of active players run-safety: add error checking to run macro code clm-table-size: default table size in clm --with-midi configuration switch 27-Jul: --with-hobbit and --with-builtin-gtkrc configure switches clm23.scm 14-Jul: new file: NEWS 30-Jun: snd-hobbit.scm thanks to Kjetil Snd 7.5. 23-Jun: new configure variables GUILE_CONFIG_name and GUILE_name (for OSX/fink) cursor-location-offset. 18-Jun: ssb-fm in dsp.scm. 10-Jun: gtk support in fft-menu.scm thanks to Kjetil ssb-bank in dsp.scm. 9-Jun: new CLM generator ssb-am. 4-Jun: add-colormap, delete-colormap, colormap-size, colormap-name, changed colormap-ref removed 2 previously built-in colormaps, added rainbow colormap, default colormap is 0. 1-Jun: read-ascii in examp.scm. 27-May: cursor-update-interval. 25-May: removed stop-playing-region-hook, stop-playing-channel-hook, before-apply-hook added stop-function arg to play, play-and-wait, play-selection, play-region, add-player 21-May: --with-doc-dir configuration switch. 17-May: Snd 7.4. 6-May: mono->stereo, mono-files->stereo, stereo->mono (extensions.scm). channel-variance etc in dsp.scm, taken from J Smith "Mathematics of the DFT" 5-May: reverse-channels, scramble-channels, rotate-channel, scramble-channel (extsnd.html, examp.scm) 22-Apr: complexify in snd-gl.scm. 19-Apr: add-to-menu now returns the new menu label widget. 13-Apr: removed forward|backward-graph|mix|mark -- see snd7.scm for Scheme versions. 12-Apr: dither-channel. goertzel in dsp.scm (faster version of find-sine). 5-Apr: Snd 7.3. 24-Mar: dialog function consistency changes: added find-dialog, print-dialog changed region-dialog to view-regions-dialog, edit-save-as-dialog -> save-selection-dialog file-dialog -> view-files-dialog, mix-dialog -> view-mixes-dialog, track-dialog -> view-tracks-dialog file-save-as-dialog -> save-sound-dialog 19-Mar: change-window-property is now a procedure-with-setter named window-property. removed change-menu-label, menu-sensitive, recolor-widget. 16-Mar: def-optkey-fun in ws.scm. 15-Mar: exported mus_optkey_* from sndlib and began incorporating optkey args into Snd. region-position and optional channel arg to region-frames suggested by Matt Wright 10-Mar: make-font-selector-dialog and make-color-selector-dialog in snd-gtk replaced snd-motif.rb with snd-xm.rb (thanks to Michael Scholz). 4-Mar: tempo-control-bounds, and all other such variables' global defaults can be set including cursor-follows-play. 3-Mar: read|write-speex for Speex files and read|write-flac for FLAC files (examp.scm) 1-Mar: show-grid. C-_ deletes text in listener to previous command. 23-Feb: speed-control-tones, speed-control-style, reverb-control-decay now handled like other control settings removed Options:Speed Style menu 20-Feb: Snd 7.2. 19-Feb: filter-channel (regularized filter-sound) 18-Feb: an enormous number of improvements to the Ruby code and inf-snd.el thanks to Michael Scholz. also new: snd-motif.rb. 16-Feb: *-control-bounds. 12-Feb: gui.scm and many other improvements thanks to Kjetil S. Matheussen. 11-Feb: added optional truncate arg to file-selection. 9-Feb: channels-equal? and channels=? in extensions.scm. play-sine, play-sines, open-play-oputput in play.scm. notch-channel and notch-selection in dsp.scm. 6-Feb: expand-control-jitter. 29-Jan: removed X resources epsfile (use eps-file) and overwriteCheck (use ask-before-overwrite) 26-Jan: changed filter-control-env to filter-control-envelope, filter-waveform-color to filter-control-waveform-color, also filter-env-in-hz to filter-control-in-hz as a sound-local variable 13-Jan: Motif version of draw-string now adds in the font height to y0 (to mimic Gtk version). 12-Jan: removed enved-selected-env, changed enved-active-env to enved-envelope. 9-Jan: Snd 7.1. 8-Jan: extensions.rb thanks to Michael Scholz. 5-Jan: envelopes can now have the property 'envelope-base. added dur arg to make-env for duration in samples. hooks.rb and hooks support in Ruby thanks to Michael Scholz. 2004 ---------------------------------------------------------------- 22-Dec: selection-changed-hook. changed enved-exp? to enved-style (envelope-linear, envelope-exponential). 15-Dec: kosine-summation in dsp.scm -- sum-of-cosines with an "FM index". sine-ramp and sine-env-channel for envelopes that connect the dots with a sinusoidal curve. Also env-squared-channel, and (x^n for any positive n) env-expt-channel. offset-channel, contrast-channel, ring-modulate-channel. 28-Nov: pan-mix-selection|region|vct in mix.scm. 26-Nov: rtio.rb thanks to Michael Scholz. 25-Nov: copy-sample-reader, read-region-sample, region-sample-reader?. removed free-mix|track-sample-reader (use free-sample-reader). sample-reader-position|home|at-end? are generic. 24-Nov: Snd 7.0. 20-Nov: track-tempo. 17-Nov: mix-dialog-mix, track-dialog-track, mix-inverted? 10-Nov: removed next-mix-sample, next-track-sample. renamed mix-panel to mix-dialog, added track-dialog. 5-Nov: Jack audio support thanks to Kjetil S. Matheussen. mix-anchor -> mix-tag-position. 4-Nov: copy-mix, copy-track. 31-Oct: removed 'snd' arg to make-track-sample-reader. 30-Oct: Kjetil S. Matheussen's snd_conffile.scm. 27-Oct: removed notion of a selected mix (selected-mix, selected-mix-color, select-mix, select-mix-hook). moved find-mix to mix.scm, changed mix-locked to mix-locked? renamed mix-dragged-hook to mix-release-hook. removed mix-amp|speed|amp-env-changed-hooks and multichannel-mix-hook. 24-Oct: data-location bugfixes in save-region|selection (thanks to Kjetil S. Matheussen). 21-Oct: track-property in mix.scm. added (or moved from mix.scm into C): track, tracks, track?, make-track, track-amp, track-position, track-frames, track-speed, track-amp-env, track-track, delete-track, delete-mix, track-color, lock-track, track-chans. env-track is now track-amp-env, unused-track and new-track are now make-track. mix-frames is no longer settable. 13-Oct: recorder-file-hook to set or modify recorder output file name, recorder-out-type. changed multichannel-mix-hook. 10-Oct: removed mix-sync (use mix-track). 9-Oct: removed the mix-id in list option for various functions. 8-Oct: optional filename arg for save-marks (and Ruby case implemented). 6-Oct: cursor-style and cursor-size can be set globally. 24-Sep: snd 6.12. 22-Sep: env.rb, spectr.rb, and spectr.scm thanks to Michael Scholz. 19-Sep: clm-ins.rb thanks to Michael Scholz. removed menu-hook. 18-Sep: info-dialog (for info-only stuff now that the help dialog has gotten complicated). 17-Sep: removed finder.scm, changed index.scm|rb to use snd-xref.c tables. 15-Sep: just-sounds support in Gtk. 12-Sep: quit-button-color, help-button-color, reset-button-color, doit-button-color, doit-again-button-color. 8-Sep: show-all-axes-unlabelled and show-x-axis-unlabelled. removed parse-rc-file, added support for Snd.gtkrc. 2-Sep: removed bold-button-font and boldbuttonFont resource. 29-Aug: gcc complex trig replaces GSL if it's available. 21-Aug: snd->sample and xen->sample (Snd-specific) generators to redirect ina and friends automatically to Snd data. 19-Aug: removed mouse-release-hook (use mouse-click-hook). 15-Aug: snd 6.11. 11-Aug: start-playing-selection-hook (suggested by Kjetil S. Matheussen). removed dlp/dp-new-effects.scm and plugins-menu.scm. int -> bool changes (ISO C99). 7-Aug: dac-is-running. 1-Aug: ladspa.scm and ladspa-help.scm thanks to Kjetil S. Matheussen. ladspa struct constants and accessors. 28-Jul: Sun disk space bugfix (thanks to Russell Aspinwall). 22-Jul: removed protect-region. 18-Jul: removed button-font and buttonFont resource, help-text-font and helpTextFont. 10-Jul: record->raw file segfault bugfix (thanks to Russell Aspinwall). 1-July: optional 'nth' arg to find-sound. optional begin time to make-track-sample-reader, play-track, and play-mix. 30-Jun: snd 6.10. 24-Jun: moved mix-name and mix-name->id to snd6.scm. 23-Jun: mix-amp-env-changed-hook. changed mix-amp-changed-hook to take 2nd chan arg. 18-Jun: mix-sound moved to mix.scm. 16-Jun: mark-drag-triangle-hook. renamed mix-position-changed-hook to mix-dragged-hook. mix.scm name changes (see snd6.scm for old forms). with-mix (ws.scm). 12-Jun: bess1.scm and bess1.rb from Michael Scholz. 10-Jun: initial-length arg to new-sound. 2-June: debug.scm and with-sound debugger in ws.scm. 28-May: snd 6.9. 26-May: x-axis-label. 20-May: make-variable-display in snd-motif.scm. 16-May: definstrument changes, clm-ins.scm. 14-May: optional begin-time arg to make-mix-sample-reader. 12-May: removed --with-html and associated variables. html-program. 7-May: or-hooks now run all functions on the hook list. mix-drag-hook. 5-May: after-save-state-hook. removed gm.scm. more IIR filters in dsp.scm, including arbitrary (even) order Butterworths, hum-eliminator 2-May: data-size, samples field in edit-header dialog. 1-May: mark-property in marks.scm. 30-Apr: mix-property in mix.scm. property-changed-hook -> window-property-changed-hook. 29-Apr: mix-click-hook 28-Apr: snd 6.8. freeverb.rb and freeverb.scm from Michael Scholz. 22-Apr: samples function returns a vct, not a vector. 15-Apr: removed fix-bar, makefile.motif.osx, and makefile.gtk.osx. 11-Apr: moved dismiss-all-dialogs to snd6.scm. change-property -> change-window-property (old form in snd6.scm) 9-Apr: nb.rb, ws.rb, dlocsig.rb from Michael Scholz. 3-Apr: noise.scm and noise.rb from Michael Scholz. 2-Apr: init-with-sound and finish-with-sound in ws.scm. 31-Mar: removed audio-state-file. mus_set_srate -> set_mus_srate in Ruby, mus-set-srate removed from Guile. similarly for mus_sound_set_maxamp, mus_set_rand_seed, mus_file_data_clipped, and mus_file_set_prescaler. 28-Mar: file arg to save-macros. 26-Mar: maxf.scm and maxf.rb from Michael Scholz. 21-Mar: snd 6.7. 19-Mar: xm-enved.rb and rubber.rb thanks to Michael Scholz. listener-click-hook with click-for-listener-help in draw.scm. 17-Mar: Mac OSX Record implemented. piano.rb, rgb.rb, strad.scm, and strad.rb thanks to Michael Scholz. moved contrib/* to the main directory. 13-Mar: removed use-sinc-interp. 12-Mar: select-mix, clear-audio-inputs and append-to-minibuffer moved to snd6.scm. 10-Mar: Ruby-related bugfixes thanks to Michael Scholz. 5-Mar: contrib/popup.rb from Michael Scholz. 4-Mar: redo renamed redo_edit in Ruby version, and in -> call_in. 3-Mar: contrib/effects.rb from Michael Scholz. 1-Mar: make-power-env and power-env in env.scm. 28-Feb: new-effects.scm bugfixes from Michael Scholz. 21-Feb: convolve-arrays renamed vct-convolve!. 20-Feb: removed transform-samples and region-samples. 17-Feb: snd 6.6. 10-Feb: removed click-for-help option. 7-Feb: German translation (po/de.po) thanks to Michael Scholz. 30-Jan: gettext changes. 12-Jan: snd 6.5. 8-Jan: removed loop-samples. 7-Jan: various simple FIR filters to dsp.scm. 6-Jan: xramp-channel for virtual exp envs. edpos args for swap-channels. map-channel arg for ptree-channel (xen-channel) for generalized virtual ops. orientation-hook and color-hook. waterfall spectrum in snd-gl.scm. channel-amp-envs now returns vcts, not vectors. 2003 ---------------------------------------------------------------- 16-Dec: snd 6.4. 11-Dec: --with-shared-sndlib configure switch. 10-Dec: contrib/inf-snd.el from Michael Scholz. 9-Dec: init-func arg to ptree-channel. 1-Dec: removed Chebyshev and Hankel transforms. def-clm-struct support in run completed. new-sound-hook, sound-let (ws.scm). -nostdin switch for CLM/Snd communication. 22-Nov: contrib/v.rb thanks to Michael Scholz. 13-Nov: snd 6.3. 8-Nov: gtk-effects.scm. 1-Nov: snd-gtk.scm. 31-Oct: gtk-popup.scm. 28-Oct: peaks-font and bold-peaks-font. 25-Oct: -I switch to add dir to load path. 23-Oct: origin arg to bind-key, edpos arg to find-mark. 16-Oct: snd 6.2. 14-Oct: removed max-sounds. 11-Oct: add-find-to-listener in snd-motif.scm. 18-Sep: show-font-name et al in snd-motif.scm. 16-Sep: snd 6.1. 12-Sep: removed "set-" names. 11-Sep: save-state-hook. 10-Sep: new edit123.scm thanks to Tom Roth. 9-Sep: bess.scm. set-oss-buffers -> mus-audio-set-oss-buffers. 4-Sep: --with-modules for modularized sndlib. 2-Sep: removed gtk-1 and gtkextra support. 1-Sep: bugfix: if no extension language, edit position could get confused. 26-Aug: filter-control-coeffs. graph-lisp|time|transform? inverted to be lisp|time|transform-graph? graph-time-once -> graph-once, graph-transform-once -> graph-once graph-time-as-wavogram -> graph-as-wavogram, graph-transform-as-sonogram -> graph-as-sonogram graph-transform-as-spectrogram -> graph-as-spectrogram. snd6.scm. ccrma-ftp: old-cmdist.html. dont-normalize-transform -> dont-normalize normalize-transform-by-channel -> normalize-by-channel normalize-transform-by-sound -> normalize-by-sound normalize-transform-globally -> normalize-globally 16-Aug: IBM adpcm from Perry Cook's adpcmdec.c. 15-Aug: set-channel-drop in snd-motif.scm. 13-Aug: snd 6.0. 1-Aug: def-clm-struct (ws.scm). 30-Jul: list constant ops in optimizer. 23-Jul: "|" removed from *.scm (r5rs restriction). 19-Jul: contrib/rmsgain.scm thanks to Fabio Furlanete. with-relative-panes. 17-Jul: mix-length -> mix-frames, region-length -> region-frames, selection-length -> selection-frames. 15-Jul: snd 5.12. continue-sample->file, read/write-ogg in examp.scm. 11-Jul: run macro for Snd. 8-Jul: update-transform changed to update-transform-graph. sample-reader-position. 3-Jul: contrib/DotEmacs thanks to Fernando. 27-Jun: bad-header-hook. 20-Jun: ptree-channel -- func as virtual edit. env-channel can take envelope (list) arg. 18-Jun: snd colors now mimic xm/xg, snd-pixel is a no-op. 12-Jun: snd 5.11. moved forward|backward-sample to snd5.scm. 10-Jun: mix panel amp envs are now editable. 7-Jun: fftw support, removed fht. 6-Jun: removed --with-big-colormap switch (use -DCOLORMAP_SIZE=64 to get old form). 4-Jun: Gtk OpenGL support via the gtkglext library. 3-Jun: removed "colour" spelling option (snd5.scm has backwards compatible definitions). 28-May: Dave Phillips' Snd tutorial added in contrib/tutorial. 24-May: with-gl to choose between GL/X graphics, snd-gl.scm 23-May: gl1.png (spectrogram uses GL now if mono and HAVE_GL). 20-May: removed glfft.c and glfft.scm snd-gxl-context on -DHAVE_GL switch (configure --with-gl) gl.c, makegl.scm, gldata.scm. (GL example in grfsnd.html). 15-May: update-hook. 13-May: snd 5.10. 9-May: sound-loop-info bugfix (thanks to Dave Phillips). 6-May: support for files larger than 2^31 bytes. 1-May: maraca.scm, piano.scm. 30-Apr: vct-map. 29-Apr: snd5.scm, singer.scm, fade.scm. 15-Apr: snd 5.9. 12-Apr: optimization variable, --with-run configure switch, snd-run.c. 9-Apr: ramp-channel. 8-Apr: virtualized envelopes. 4-Apr: improvements in contrib/dlp, thanks to Dave Phillips. 3-Apr: read-sample, read-mix-sample, read-track-sample, selection-maxamp. 1-Apr: insert-samples and set-samples no longer delete file passed as 'data'. 29-Mar: Mac-OSX with Motif (thanks to Charles Nichols). 28-Mar: removed movies function. 27-Mar: selected-mix, selected-sound, and selected-channel return #f if none selected (not -1). 24-Mar: removed ALSA 0.5 support. cosine-summation, legendre-summation in dsp.scm. mus-sound-forget and mus-sound-prune bindings. clear-listener (bound to C-M-g). C-? tries to invoke snd-help. help-hook. M-p and M-n now work in the listener (it has a history of previous forms). added bad-type error and removed internal catch from map-chan et al removed cursor-no-action, cursor-update-display. 18-Mar: squelch-vowels in examp.scm (and ramp gen). 13-Mar: snd 5.8. 12-Mar: header editor bugfix (thanks to Ludger Brummer). 11-Mar: removed channel-sync. 28-Feb: edit-position bugfix (thanks to Ludger Brummer). 27-Feb: color-scale bugfix (thanks to Anders Vinjar). 25-Feb: gtk2 port with xg (see example in grfsnd.html). 11-Feb: snd 5.7. xg.c (gtk2 bindings), makexg.scm, xgdata.scm. 30-Jan: removed stats dialog, snd-xstats.c, snd-gstats.c, show-usage-stats, update-usage-stats. 28-Jan: Alpha bugfix thanks to Stefan Schwandter. 23-Jan: color-samples (draw.scm). 21-Jan: bird.rb. channel-properties, sound-properties (accessors in extensions.scm). 18-Jan: zip-channel (zip.scm). removed old-sndlib.h and old-sndlib2scm.scm. 14-Jan: gsl-error. snd.rb (Ruby code and tests). 11-Jan: snd 5.6. flute.scm. 7-Jan: mix-channel, insert-channel in extensions.scm. event.scm. the Snd widget lists now return objects compatible with the xm module, so the various "cast" functions such as |Widget are no-ops. 4-Jan: removed loop.scm. 2002 ---------------------------------------------------------------- 26-Dec: explode-sf2 in examp.scm. 14-Dec: removed icons.scm and backgrounds.scm (replaced by contrib/dlp code). removed reverb-control-procedures and contrast-control-procedure. 10-Dec: midi.c. 6-Dec: play.scm. 3-Dec: snd 5.5. 28-Nov: add-tooltip in snd-motif.scm. 23-Nov: draw-mark-hook. 20-Nov: xm-enved.scm. 19-Nov: reopen menu example in examp.scm. 13-Nov: edit123.scm by Tom Roth added to contrib directory. emacs-style-save-as. 10-Nov: new-widget-hook. 5-Nov: snd 5.4. 29-Oct: contrib/dlp directory with Dave Phillips' ladspa plugin stuff. 15-Oct: multichannel ladspa plugins, ladspa-dir. 12-Oct: various regularized *-channel functions. 8-Oct: snap-mix|mark-to-beat. 5-Oct: x-axis-in-beats, beats-per-minute. 1-Oct: Snd 5.3. 26-Sep: after-edit-hook. 24-Sep: changed mus-sound-max-amp to mus-sound-maxamp to match all other such cases (old name still exists) 18-Sep: backwards incompatible change to save-state of small regions. 17-Sep: section-scale-by renamed scale-sound-by (more consistent), also scale-sound-to. 14-Sep: peak-env.scm. 7-Sep: define-selection-via-marks in marks.scm. removed --with-snd-conf and --with-ccrma, added --with-temp-dir, --with-save-dir. 4-Sep: eps-size. 3-Sep: mix-file-dialog. optional position arg to add-to-menu. 1-Sep: zero-phase, rotate-phase in dsp.scm (Scott McNab). region-play-list in examp.scm. 31-Aug: snd 5.2. 29-Aug: edit-menu.scm and merged in Dave Phillips' changes for effects.scm. 28-Aug: after-apply-hook, before-apply-hook. 24-Aug: add-amp-controls in snd-motif.scm, add-notes in examp.scm. 21-Aug: explicit FIR/FFT choice to envelope editor (enved-filter). fft-squelch in examp.scm. 20-Aug: add-listener-popup, fft-popup in popup.scm. 17-Aug: GSL 0.9. Gtk+extra 0.99.16. 16-Aug: removed load-colormap. 14-Aug: recorder-in-device for OSS. 13-Aug: stop-dac-hook, file-save-as-dialog, stop-playing-selection-hook. remember-sound-state in extensions.scm. 10-Aug: make-level-meter, with-level-meters in snd-motif.scm. dac-hook, sound-data-maxamp. 9-Aug: show-smpte-label in snd-motif.scm. region-graph-style. 7-Aug: snd-print locale bugfix (thanks to Ludger Brummer). makefile.in prefix bugfix (thanks to Marc Herbert). edit-save-as-dialog (for selection popup menu in snd-motif.scm). 6-Aug: drop file into channel graph mixes at cursor. make-sound-box, select-file, snd-clock-icon in snd-motif.scm. 3-Aug: moved listener widget to main-widgets list. add-selection-popup in snd-motif.scm. 2-Aug: mark-hook and add-mark-pane in snd-motif.scm. 1-Aug: region browser display bugfix (thanks to Dave Phillips). check-for-unsaved-edits in extensions.scm. 28-Jul: removed set-pixmap, make-pixmap (see snd-motif.scm replacement). 27-Jul: zync/unzync, make-hidden-controls-dialog in snd-motif.scm. 26-Jul: 'play selected sound' button to open file dialog. previous-files-select-hook, open-file-dialog, install-searcher (grfsnd.html). snd-motif.scm. 25-Jul: snd 5.1. removed snd-gtk.scm (guile-gtk is no longer supported). removed add/remove-idler/input. 23-Jul: xm.c (Motif module). 12-Jul: ALSA 0.9 support from Fernando. 9-Jul: xen.c, xen.html. 6-Jul: sg.h, sl.h, noguile.h, sr.h, sz.h -> xen.h. snd-scm.c, clm2scm.[ch], sndlib2scm.[ch] -> xen for scm. many internal name changes to change scm to xen. 5-Jul: Ruby support. 3-Jul: added -b (-batch) switch for scripts. snd-4 compatibility names are no longer built-in (use snd4.scm). 1-Jul: gtk+extra 0.99.15. snd-trace in extensions.scm. 28-Jun: find enhancements (see snd.html and examp.scm); find-pitch. colormap-ref, colormap-size. 26-Jun: sound-files-in-directory returns a list, not a vector (to be consistent with CLM). 25-Jun: gcc 3.0. added type and comment args to save-region, and moved format arg after type (to be consistent with other such calls). mouse-click-hook. reverse-track (mix.scm). mus-sound-max-amp now returns (and takes) a list, not a vector. 21-Jun: dsp.scm, autosave.scm, extensions.scm. find-mix. 20-Jun: read-hook. hooks.scm. snd-debug in extensions.scm. 19-Jun: removed snd-main-shell -- use (cadr (main-widgets)) instead. make-pixmap and set-pixmap. moved Snd-4 stuff from examp.scm to snd4.scm. clone-sound-as in extsnd.html, remove-clicks in examp.scm. 18-Jun: GSL 0.8. Gtk+-1.2.10. display-current-window-location in draw.scm. example of Snd as script engine in grfsnd.html with added script-arg and script-args. 16-Jun: snd 5.0. corruption-time -> auto-update-interval. 13-Jun: previous-files-sort-procedure (for View:Files dialog). 12-Jun: x-axis-style can be channel-local. 7-June: added Reset button to envelope editor (to return to initial state). yes-or-no-p -> yes-or-no? 5-June: replaced wavo by time-graph-type, graph-time-once, graph-time-as-wavogram (analogous to transform-graph-type). 4-June: configure.ac for autoconf 2.50. prepended "zoom-" to the zoom-focus-style choices (e.g. zoom-focus-left). added axis- to x-axis-style choices (e.g. x-axis-in-samples). x-to-one -> x-axis-as-percentage. print-hook. graphing -> graph-lisp?, ffting -> graph-transform?, waving -> graph-time?, fft-graph -> transform-graph, fft-beta -> fft-window-beta, fft-hook -> transform-hook, transform-size -> transform-samples-size, fft-size -> transform-size, fft-style -> transform-graph-type, before-fft-hook -> before-transform-hook, max-fft-peaks -> max-transform-peaks, show-fft-peaks -> show-transform-peaks, normal-fft -> graph-transform-once, sonogram -> graph-transform-as-sonogram, spectrogram -> graph-transform-as-spectrogram, normalize-by-channel -> normalize-transform-by-channel, normalize-by-sound -> normalize-transform-by-sound, normalize-globally -> normalize-transform-globally, normalize-transform -> transform-normalization, update-fft -> update-transform, update-graph -> update-time-graph, dont-normalize -> dont-normalize-transform. 1-June: add-to-menu and remove-from-menu can affect the popup menu. region handling changed to use the region "id", not its current stack position. many related changes: region-* procedures take the id as the region number argument. removed: select-region, select-region-hook, id-region, region-id renamed: delete-region -> forget-region. selection-chans, selection-srate (since regions may be disassociated from the selection). with-big-colormap is now the default. removed all the map and scan functions except map-chan and scan-chan (the rest can be easily re-implemented using loops, sample-readers, set-samples, and sync -- see examp.scm). removed all the temp-to-sound|selection (and vice versa) functions (and temp-filenames) (these were redundant since set-samples can take a filename -- see examp.scm for re-implementations) Snd version 5.0 due to these changes. added channel arg to save-selection and set-samples (for multi-file selection saves) make-selection (examp.scm). removed env-base. 29-May: combined channel-style and uniting under the name channel-style (uniting removed). dac-folding -> dac-combines-channels (not sure about this name change). C-x x|n|x_x|n key support ("eval expression") removed (was useless and broken). These four keys can be re-implemented using bind-key and as-one-edit. c-g! (simulates typing C-g). 28-May: renamed enved-exping -> enved-exp?, enved-waving -> enved-wave?, enved-clipping -> enved-clip? amplitude-env -> enved-amplitude, srate-env -> enved-srate, spectrum-env -> enved-spectrum removed save-state-on-exit (use exit-hook with save-state). removed activate-listener and hide-listener (the latter is now (set! (show-listener) #f)). 27-May: replaced mix-sound-channel and mix-sound-index by mix-home. player-home. Added "control" to the various control panel names: amp -> amp-control, contrast -> contrast-control, contrast-amp -> contrast-control-amp, contrast-func -> contrast-control-procedure, contrasting -> contrast-control?, expand -> expand-control, expand-hop -> expand-control-hop, expand-length -> expand-control-length, expand-ramp -> expand-control-ramp, expanding -> expand-control?, filtering -> filter-control?, filter-order -> filter-control-order, filter-env -> filter-control-env, reverb-decay -> reverb-control-decay, reverb-feedback -> reverb-control-feedback, reverb-funcs -> reverb-control-procedures, reverb-length -> reverb-control-length, reverb-lowpass -> reverb-control-lowpass, reverb-scale -> reverb-control-scale, reverbing -> reverb-control?, speed -> speed-control, speed-as-float -> speed-control-as-float, speed-as-ratio -> speed-control-as-ratio, speed-as-semitone -> speed-control-as-semitone, speed-style -> speed-control-style, speed-tones -> speed-control-tones, filter-dBing -> filter-control-in-dB, enved-dBing -> enved-in-dB. renamed filter-env-order -> enved-filter-order. Some rationale: Scheme uses "procedure" rather than "function" and "?" for booleans. The control names ("amp" in particular) were too likely to be confused or shadowed. filter-env-order was too similar to filter-order (and not obvious it meant the envelope editor filter order) These names actually predated the decision to use Guile -- I didn't foresee 4 years ago where Snd was headed. 26-May: removed fit-data-on-open; here's a replacement: (define (fit-data snd chn dur) (let ((mx (maxamp snd chn))) (list 0.0 dur (- mx) mx "time" (- mx) mx))) (add-hook! initial-graph-hook fit-data #t) ; #t to make sure env restorers get to function first added 'extended' arg to bind-key et al so C-x keys can be bound. example of zero-crossing based C-p, C-n, and C-k in extsnd.html (bind-key). save-control-panel renamed save-controls, similarly for reset-controls and restore-controls (these now parallel show-controls and apply-controls). mark->sound renamed mark-home (the arrow is out of place here, and it's returning the sound-channel list). sample-reader-home. 25-May: removed open-alternate-sound -- is exactly the same as close-sound + open-sound. removed earlier scm_apply optimizations ("Rule #1 of optimization: don't do it"). removed normalize-on-open (use after-open-hook and equalize-panes): (add-hook! after-open-hook (lambda (snd) (equalize-panes))) renamed normalize-view to equalize-panes. 24-May: removed line-size, prefix-arg (it's now an optional arg to the key function). ignore-prefix arg to bind-key removed, Snd no longer handles prefix itself. removed cut (use delete-selection). call-apply renamed apply-controls. prompt-in-minibuffer callback func now takes only the response arg (no longer the snd index). 23-May: OSS fragment defaults changed -- see extsnd.html or HISTORY.sndlib. old default was (set-oss-buffers 4 12) but 2 12 is usable in most cases. fft-smoother added to examp.scm. smooth renamed smooth-sound. 22-May: widget-text (mainly for auto-testing). 21-May: Gtk version can now use the mozilla embedded browser for the help dialog. hankel-jn (default 0.0) for Bessel choice in Hankel transform. removed raw-srate, raw-chans, raw-format, and use-raw-defaults (use open-raw-sound-hook instead), erase-rectangle. mouse-enter|leave-text-hook now works in Gtk version as well as Motif. 20-May: snd 4.14. 18-May: Gtk+ version was forgetting to make the listener menu active! (thanks to Dave Phillips) 14-May: continuable errors -- deleted the next day (gc troubles). 11-May: selection-to-temp was writing files that Sox et al can't read (thanks to Matti Koskinen). 9-May: support for GSL 0.7+. 7-May: added edit-position arg to various play functions, save-sound-as, scan/map/find funcs, frames and maxamps. "vector synthesis" in examp.scm. Guile 1.5. 1-May: Alpha (64-bit) and FreeBSD (Old OSS) fixups. 29-Apr: describe-audio replaced by mus-audio-describe. 28-Apr: noguile play segfault caused by backwards NOT_BOUND_P macro (thanks to Bob Sturm). 26-Apr: in user-written makefiles, -DHAVE_GUILE=0 should be changed to -DHAVE_EXTENSION_LANGUAGE=0 25-Apr: snd.1 (and mandir business in makefile.in) 24-Apr: mouse-enter|leave-text-hook. 23-Apr: snd 4.13. 19-Apr: use GSL_IEEE_MODE if it exists. 17-Apr: Haar transform. 16-Apr: mus-out-format, listener-selection. 9-Apr: noguile.h, sl.h (moving toward Librep support, and maybe Ruby). 29-Mar: drop-hook. 23-Mar: removed syncing (use sync), and abort? (use c-g?). removed support for Guile 1.3.0 (Snd now needs 1.3.4 or later). select-region-hook, select-mix-hook. 22-Mar: removed snd-noscm.c. sndlib-scm calls that fail throw 'mus-error now, rather than returning -1. files-popup-buffer in examp.scm (thanks to Anders Vinjar). select-sound-hook, select-channel-hook. 21-Mar: mus-expand-filename. open-raw-sound-hook (old raw-* variables are obsolete). 20-Mar: mouse-enter-label hook function needs full filename (thanks to Anders Vinjar). 19-Mar: snd 4.12. removed gdbm support from sndlib. 16-Mar: read|write-peak-env-info-file. 15-Mar: tested ok with gtk 1.2.9. src-sound with negative envelope bugfix, also the interpretation of the envelope arg is changed to be consistent with the envelope editor src function. '(0 1 1 1) now returns no change (src ratio of 1 throughout -- the value is used directly, rather than being an offset from 1.0. 14-Mar: dac reverb segfault in ALSA with Midiman delta bugfix (thanks to Oded Ben-Tal). peak-env-info. 13-Mar: removed initial-x0, initial-x1, initial-y0, initial-y1, and replaced with initial-graph-hook -- this is a non-backwards compatible change! add-idler, remove-idler (background process) removed (long obsolete) showing-controls (replaced by show-controls) 12-Mar: musglyphs.scm. 10-Mar: moved grfsnd.html index to new file: index.html. 9-Mar: removed *.txt mouse-enter|leave-graph|listener-hook. show-widget, hide-widget, focus-widget. 7-Mar: mouse-enter|leave-label-hook, listener-text-color, axis-info. nb.scm 5-Mar: Guile-level graphics changes (to unify Motif and Gtk in this regard): removed all the guile-gtk-specific procedures (except sg-options-menu-widget and sg-menu-bar-widget). added cursor-size, cursor-position, cursor-style can be a procedure. time-graph, fft-graph, lisp-graph, cursor-context, copy-context. position->x, position->y, x->position, y->position. foreground-color, load-font, current-font, widget-position, widget-size. draw-dot, draw-line, draw-dots, draw-lines, draw-string. fill-rectangle, erase-rectangle, fill-polygon. main-widgets, menu-widgets, sound-widgets, channel-widgets, dialog-widgets. lisp-graph-hook, recolor-widget, show-backtrace. make-graph-data, graph-data, property-changed-hook. 28-Feb: enved-hook with enved-add-point, enved-delete-point, and enved-move-point. 27-Feb: removed cursor-claim-selection (was identical to cursor-update-display). 26-Feb: Tab-completion is much smarter in Guile 1.4.1. 23-Feb: --with-gsl is the default in configure. 21-Feb: snd 4.11. 14-Feb: vct func now built-in (was in examp.scm). 13-Feb: search-procedure, key-binding. 12-Feb: added Wakefield's freeverb, changed user-defined reverb handlers. 6-Feb: removed expand-funcs: it could not have worked given the "hidden controls" exposure. 30-Jan: rtio.scm. 29-Jan: pvf headers. 23-Jan: no-gui version now reads ~/.snd (thanks to Eliot Handelman). 16-Jan: fm.html, sndscm.html. 15-Jan: snd 4.10. 9-Jan: rubber-sound in rubber.scm. 2001 ---------------------------------------------------------------- 28-Dec: filter-sound|selection can be passed any CLM filtering gen (Butterworth in examp.scm). 21-Dec: env|src-sound|selection can be passed CLM env. 18-Dec: enved.scm (suggested by Anders Vinjar). play-hook, player?. 15-Dec: update-lisp-graph. graph data arg can be envelope. graph-style can apply to time, transform, and lisp graphs independently. 13-Dec: prc95.scm (Perry Cook's physical modelling examples). 12-Dec: ws.scm (more elaborate with-sound implementation). save-listener. play-syncd-marks (marks.scm). 11-Dec: snd 4.9. 7-Dec: zero-pad bugfixes. 29-Nov: before-fft-hook, string completion from help list. 28-Nov: BSD support thanks to Steven Schultz. Dolph-Chebyshev window if HAVE_GSL. 24-Nov: fht (Hartley transform). 21-Nov: abort? -> C-g?. edit-tree and display-edits documented. 17-Nov: esd support thanks to Nick Bailey. 14-Nov: un-normalized fft display bugfix. 13-Nov: mark-drag-hook. 11-Nov: insert-silence. 10-Nov: snd 4.8. 8-Nov: filter text field also has history (M-p) now. 7-Nov: shell style M-p and M-n in minibuffer with variable minibuffer-history-length (8). 6-Nov: various cosmetic changes for the new g++ (Redhat 7.0). insert-sound arguments changed (to match mix-sound more closely). TODO.Snd. 2-Nov: insert-selection, mix-selection, delete-selection. 1-Nov: filter-env-in-hz switch. 31-Oct: syncing -> sync. Set! extended to frames, maxamp, x|y-zoom|position-slider. 30-Oct: examp.scm soft-port example of redirecting display to Snd's listener. support for GSL 0.7. scale-selection-to bugfix. selection-creates-region switch. 25-Oct: emacs subjob 'read: unexpected ")"' bugfix. 24-Oct: eps-bottom-margin and eps-left-margin (for Print command). menu-hook. 23-Oct: interface to mixes changed: mix consoles are now in a separate dialog, each mix displayed with a tag and its waveform. removed mix-console-state, mix-console-state-changed-hook, show-mix-consoles. removed mix-console-amp-scaler, mix-console-speed-scaler, mix-waveform-color. changed mix-console-y to mix-tag-y, Show Consoles menu item to Mix Panel. changed with-mix-consoles to with-mix-tags, mix-focus-color to selected-mix-color. show-mix-waveforms default is #t. removed snd-gtkfixed.*. added mix-tag-width and height, mix-panel. removed .sndrc and other related stuff. removed Show Marks menu item. 16-Oct: snd 4.7. optional environ arg to loop-samples and clm example to grfsnd.html. 11-Oct: delete button in envelope editor. 10-Oct: removed scaler arg to mix-region and associated kbd scaler arg. 9-Oct: bird.scm. added origin arg to as-one-edit. 6-Oct: removed chans arg to mix-vct. 4-Oct: enved-active-env and enved-selected-env. 3-Oct: scale-by and scale-to now use embedded fragment scalers. 2-Oct: audio-input-device. 27-Sep: showing-controls -> show-controls. data-format and header-type now return just the sndlib int. 22-Sep: removed override-data-format|header-type|data-location and replaced with generalized set! of header fields. 18-Sep: snd 4.6. selection now follows the edit history lists. selection-beg is now selection-position (to be consistent with everything else). 12-Sep: effects.scm. 11-Sep: generalized set! now built-in (the set-* forms still exist for old versions of Guile). removed setf.scm. x-bounds and y-bounds setters now take a list of (low high) values. 8-Sep: make-player, add-player, stop-player, start-playing (and make-amp-controls example in snd-gtk.scm). changed setf.scm to use Guile 1.4's generalized set! (rather than setf). 6-Sep: gtk menu accelerators, stop-playing-channel-hook, just-sounds-hook. 5-Sep: changed Apply button handling -- control-click now for selection. HAVE_GTKEXTRA to support libgtkextra's icon-oriented file selector. 31-Aug: gtk popup menu fixed. 30-Aug: new snd.spec thanks to Fernando Lopez-Lezcano. snd-emacs errors now go to emacs, play-region notices its wait argument (thanks to Anders Vinjar). sash-color, gtk CLM/Snd connection finally works. 28-Aug: more gtk-related bugfixes. 24-Aug: drag-and-drop bugfixes. 23-Aug: removed -s startup switch. 22-Aug: removed snd-gdac.c, snd-xdac.c. 19-Aug: removed special-case Lesstif support. 18-Aug: scan and map-chan and friends (including find and count-matches) no longer call the function with #f at the end -- this is a non-backwards-compatible change. The #f call can be implemented using closures (see data-max example), the early exit with continuations, and the possible end-extension with insert and as-one-edit. 17-Aug: recorder work (one serious bug fixed). 14-Aug: snd 4.5. 10-Aug: extsnd.html re-organized. wavo,wavo-hop,wavo-trace,line-size,max-fft-peaks,show-fft-peaks,zero-pad,fft-style,fft-window, verbose-cursor,fft-log-frequency,fft-log-magnitude,min-dB,wavelet-type,fft-size,fft-beta,transform-type, normalize-fft,show-mix-consoles,show-mix-waveforms,graph-style,dot-size,show-axes,graphs-horizontal, spectro-x|y|z-angle|scale,spectro-hop,spectro-cutoff,spectro-start can be treated as channel-local. reverb-decay,speed-tones,speed-style can be treated as sound-local. Snd builds and runs in Mac OS-X. 3-Aug: C-q with moving cursor bug, extended normalize-fft choices (Daniel Aronovitch). show-y-zero, show-marks can be local to a given sound or channel. 2-Aug: compute-uniform-circular-string in examp.scm. 1-Aug: removed xmin,xmax,ymin,ymax (redundant and pointless). 31-Jul: amp env subsampling, C-x v, and superimposed fft bugs (thanks to Daniel Aronovitch). control panel funcs (set-amp etc) can take snd arg = #t -> all sounds. snd-gtk.scm make-control-dialog to expose hidden control-panel variables. 28-Jul: use throw for error handling. 27-Jul: (read-set! keywords 'prefix) is now built-in. 26-Jul: Snd now uses clm for all control-panel functions (play/apply). name-click-hook, show-indices. ladspa-related bugfix thanks to Jorn Nettingsmeier. 24-Jul: snd-tempnam, sound-interp gen in examp.scm and env-sound-interp 20-Jul: sum-of-sines, phase-vocoder. 18-Jul: play-selection and added end arg to play etc. C-u 0 C-x p -> play region 0, C-x p -> play selection. 17-Jul: optargs keyword bug was caused by string-length which existed for guile 1.3.0 (fixed). 14-Jul: Snd appears to work in FreeBSD (thanks to Heiko Recktenwald). pvoc.scm, loop.scm, fmv.scm. -l no longer necessary -- if file has .scm extension, it is assumed to be Scheme. 10-Jul: added sounds (list of currently active sounds). region-id and id-region, regions now returns a list of active region ids. mixes now returns a list similar to marks. removed active-sounds. 6-Jul: snd 4.4. user-specified menu callbacks must be functions (not strings). removed dsp-devices. 5-Jul: experimental erase-zeros flag. swap-channels. 3-Jul: save-hook and auto-save (examp.scm) improvements. ok? renamed sound?, mix-ok? -> mix?, new mark?, region?, selection? setf.scm for (setf () ) in place of (set- ). control-panel reverb can handle any number of chans (and now gets input from all). show-axes variable changed: now has 3 values, show-all-axes (default), show-no-axes, show-x-axis. removed View:Show Axes menu item; also these no longer affect the control-panel filter graph. removed edit-history list support from Motif 1. 29-Jun: many ardour-related improvements from Paul Barton-Davis. 28-Jun: new channel argument to save-sound-as (for channel extraction). removed OSS-specific set-dsp-reset. 27-Jun: update configure for gsl 0.6. 26-Jun: as-one-edit now handles mark changes correctly. make-sample-reader snd arg can be filename (to read external files without opening them). Guile 1.4 is now the default -- if you are using 1.3.4, include -DHAVE_GUILE_1_3. various bugs fixed (thanks to Daniel Aronovitch) 22-Jun: version renamed snd-version (old name collides with guile) -- similarly for apropos and help. 21-Jun: marks.scm. 19-Jun: changes to GC handling for new guile. sync field in marks and changed much of the Guile interface to marks: marks -> list of mark ids mark-sync, set-mark-sync, syncd-marks mark-sample, set-mark-sample, mark-name, set-mark-name no longer take (useless) snd/chn args. new mark->sound returns '(sound channel) (holders of mark) syncd marks can be moved together, played, etc edits function now returns a list, not a vector 15-Jun: changed edit|undo-hook procedure to take no args. 13-Jun: snd-error, snd-warning; cursor-style (default cursor-cross, also cursor-line). channel-specific edit-hook and undo-hook. 12-Jun: experimental multifile-sound support (under FILE_PER_CHAN switch). 9-Jun: bugfixes and improvements from Paul Barton-Davis. 8-Jun: OSS/ALSA choice at run-time (snd-xrec/snd-dac changes thanks to Fernando Lopez-Lezcano). 7-Jun: snd-error-hook, snd-warning-hook. 5-Jun: snd 4.3. 30-May: transform-size for glfft, glfft.scm, glfft.c. 29-May: mix-sound to help with CLM/Snd explode support. 25-May: removed snd-clm.c, snd-xclm.c, snd-gclm.c. 24-May: sndctrl.c and related X properties in Snd. 23-May: snd-ladspa.c (LADSPA support thanks to Richard W.E. Furse). 'sync' arg to play and play-and-wait. 22-May: set-reverb-funcs, set-contrast-func, set-expand-funcs. bind-key in guile version no longer takes a string as the "code" arg -- must be procedure. snd-gxutils for better communication with netscape. 18-May: new error symbols for many functions: 'no-such-sound etc. removed vax float support. 16-May: stop-playing-region-hook and 2nd wait arg to play-region. 15-May: index.scm. 12-May: mus-error-hook. 8-May: help function. 5-May: dac-folding variable (default #t). 2-May: replaced Legendre transform with cepstrum. 1-May: snd 4.2. 27-Apr: graphs-horizontal variable. 25-Apr: split out the drag-and-drop stuff into snd-[xg]drop.c. removed XmHTML? function -- now using the *features* list instead. 21-Apr: extended scope of scm evaluation to most user interface text widgets. update-var renamed define-envelope. make-formant radius arg now matches CLM (lisp) version (1.0-old-value). 20-Apr: convolve-files. 19-Apr: filter-sound 'env' can now be the filter coefficients, and vector->vct, both changes for gmeteor support. 18-Apr: added spectrum of window to fft window graph in transform dialog. 17-Apr: bell.scm, moog.scm, prompt-in-minibuffer. 12-Apr: Fernando Lopez-Lezcano provided a new ALSA port! changed clm2scm to use built-in keyword support (use (read-set! keywords 'prefix)) 11-Apr: new sndlib names (mus-aiff etc) (old names will eventually be moved to old-sndlib2scm.scm) 10-Apr: updated Be audio support, added no-gui option. 7-Apr: interrupted save-as in kde/kfm when launched via icon bugfix (thanks to Marcus Roeckrath, Patrick Pagano, and Victor Yarosh). 6-Apr: quad playback bug introduced in 27-Mar version fixed. 3-Apr: soundfont-info. 29-Mar: snd 4.1. 28-Mar: add-transform. 27-Mar: MUS_SAMPLE_BITS and SNDLIB_USE_FLOATS: you can choose Snd's internal sample representation. changed use-sinc-interp default to #t 22-Mar: raw-type variable removed. 21-Mar: multi-channel control-panel apply bug fix. 20-Mar: gdbm (under HAVE_GDBM) to handle headers. samples->sound-data and sndlib2scm.h. removed snd-parser.c and all C expression stuff. 17-Mar: edit-fragment, mark-loops example in examp.scm. 15-Mar: snd 4.0. Gtk+ port. Since .Xdefaults is ignored by Gtk, new variables added to set fonts in ~/.snd. Gtk version reads ~/.sndrc instead of .Xdefaults (untested). New font variables are button-font, bold-button-font, axis-label-font, axis-numbers-font, help-text-font, and listener-font. To keep file names sensible, snd-gh.c -> snd.scm.c, snd-xgh.c -> snd-xscm.c, snd-xvulab.c -> snd-gxbitmaps.s, added snd-gxcolormaps.c. Removed the "record" and "replay" buttons for real-time control panel changes. added during-open-hook and mus-prescaler to handle float files with tiny maxamps. added after-open-hook and removed the "default-*" variables related to the control panel. Removed -scrollers option. Added many widget and graphics-context functions to support guile-gtk. split extsnd.html into extsnd.html and grfsnd.html, added snd-gtk.scm. after-graph-hook. changed find dialog to provide next and previous buttons. snd_plug mechanism changed (greatly simplified); removed call-plug etc, added loop-samples. removed snd-plugin.h, anoi.c. 14-Feb: snd 3.7. HAVE_MAKE_SMOB_TYPE is now the default -- use HAVE_GUILE_1_3_0 for the old case. HAVE_GUILE_1_4 for the new (fixed!) backtrace. 11-Feb: removed y1..y8 business and "{}" support in "C expressions". removed clm? function (it's always loaded now). 10-Feb: save-dir for simplified saved-state files. with-mix-consoles to turn off mix consoles globally. 7-Feb: better mix movies. added multichannel-mix-hook (see mix.scm). superimpose-ffts in examp.scm, based on extension of graph function. 2-Feb: pqwvox.scm, makefile.msv. 31-Jan: src-sound now takes the usual snd and chn args. 27-Jan: env.scm. 26-Jan: various envelope editor improvements for mix envs. 21-Jan: underlying mix input data can now be edited just like any displayed sound data. 20-Jan: Snd can now be run as an emacs scheme subjob. play-track, track-sample-readers. 17-Jan: amp env improvements, individual mix colors settable, edit-position. 13-Jan: snd 3.6. 12-Jan: selected-mix, select-mix. 11-Jan: mix-locked, mixed-related hooks. Guile GC-related bugfixes. 5-Jan: mix.scm. data-clipped. removed all group support. added mix-name, mix-track, mix-chans, mix-ok?, mix-amp-env, mixes, mix-vct, mix-sound-channel, mix-sound-index, mix-console-y, removed mix-groups. removed --with-clm option -- clm is now always included. added mix-sample-reader support. replaced snd-test.cl with snd-test.scm. 2000 ---------------------------------------------------------------- 16-Dec: changed mixer-save-state-file to audio-state-file. also mix-amp-scaler to mix-console-amp-scaler, mix-speed-scaler to mix-console-speed-scaler, and mix-state to mix-console-state. 15-Dec: changed as-one-edit to omit the snd and chn args and apply across all chans. 9-Dec: use-sinc-interp for high quality src from control panel. 6-Dec: snd 3.5. 3-Dec: gif -> png. 2-Dec: as-one-edit, apropos. 30-Nov: snd1.html, snd-contents.html; spectro-start. 29-Nov: --with-doubles configure switch. 26-Nov: changed aiff-sound-file to aifc-sound-file and old-style-aiff-sound-file to aiff-sound-file. add-to-menu callback can be a function now. 24-Nov: make-region-sample-reader, frame->list, xy slider readers. 19-Nov: sample-reader functions and vct-map! (et al) to speed up data accesses from Guile. Also formant-bank, oscil-bank, vct-peak. 15-Nov: removed max-fft-size and fft.c. 12-Nov: removed defaultOutputType resource. Added default-ouput-chans, default-output-srate, output-name-hook. 11-Nov: default-output-format and old-style-AIFF-sound-file, output-comment-hook. 8-Nov: snd 3.4. 5-Nov: memory leaks plugged? marks bugfix (add mark, save edit, add mark -> segfault). 1-Nov: start-playing-hook, enved-power. Error History Edit menu option. if Motif 2, edit history portion is now a horizontal pane of the channel window, so Edit History menu option is removed. 28-Oct: listener-prompt, graph-cursor. 25-Oct: 'env' is 'env-sound' and 'snd-env' is deleted. Similarly, convolve -> convolve-arrays, filter -> filter-sound, src -> src-sound (and snd-src deleted), spectrum -> snd-spectrum. These changes to avoid confusion with the CLM module. 22-Oct: audio-output-device. sync is now an integer, allowing complex grouping. 15-Oct: changed variable 'spectro-color' to 'colormap' 11-Oct: changed axis drawer so the x axis doesn't jump around. 8-Oct: dsp-devices (Linux OSS) for setting audio ports by hand, bomb function. hook handlers are now taken from Guile (version 1.3.4) and use Scheme functions, rather than strings. 7-Oct: count-matches (and bind-key) arg can now be a Scheme function, as in find. load-colormap. 6-Oct: play can handle any number of channels (will fold them into available DAC chans). 5-Oct: snd 3.3. 4-Oct: list->vct, selection-beg, selection-length, selection-member, play-and-wait, squelch-update, file->array, array->file. 27-Sep: 'print' renamed 'graph->ps'. snd-print. added width arg to make-src (accidentally forgotten). 23-Sep: bugfixes related to Sonorus Studio. more configure options. snd-xgh.c added. 22-Sep: Guile 1.3.4 support. 17-Sep: ALSA port thanks to Paul Barton-Davis. 13-Sep: added -separate switch at suggestion of Anders Vinjar: each sound has its own window. Linux alpha port thanks to Guenter Geiger. 9-Sep: more CLM-2 changes (fit-data-on-open is now a boolean, open-raw-sound). reverse -> reverse-sound (old name collides with scheme built-in) 5-Sep: CLM to Snd connection changes (removed .debugdata, .marks and .explode files, added snd-memo check for .scm). 30-Aug: Alpha CLM-2 mixup untangled? Added trap-segfault. 27-Aug: Guile 1.3.2 support 20-Aug: infinite zoom-in segfault bugfix. 19-Aug: snd 3-2. 'snd -p .' followed by attempt to play read-protected 'previous' file segfault bugfix. 5-Aug: setlocale in save-options to keep "." decimal point while writing Scheme code. 8-July: stereo 'unite' ctrl-click 'play' c-t c-q segfault bugfix. Changed 'guile' to 'guile?' 1-July: spectrum function. 13-Jun: snd 3.1. 7-June: snd_as_widget. 3-June: new notebook and scroller outer widget choices. 2-June: mark-click-hook. removed save/mark-segments -- will replace later. 31-May: mix-save-state-file, vct->sound-file, open-sound-file, close-sound-file. 28-May: multi-channel recording bugfix. Y2K compliance!! 24-May: scanning and mapping functions. More examples in examp.scm. snd-length replaced by frames. progress-report handlers (hourglass icon). 19-May: find/eval via C-s, C-r, C-x C-x, etc can now handle Scheme functions. 18-May: -e (-eval) switch. global-set-key replaced by bind-key. 11-May: configure guile version bugfix(?). Removed support for versions of Guile before 1.3. 10-May: snd 3.0. 5-May: several resource name changes, other color-related stuff. 28-Apr: all the colors now have guile equivalents, also new functions make-color and color?, rgb.scm. 26-Apr: graphcolor, markcolor, selectedgraphcolor, datacolor, selecteddatacolor resources. 23-Apr: show-axes view menu option and vars. Moved all customization documentation to extsnd.html. 20-Apr: rpm version now assumes guile 1.3. vct guile smob to optimize data access from scheme. 12-Apr: multi-channel impulse response convolution (with-convolve). 5-Apr: snd 2.8. save-defvar renamed update-var. 1-Apr: call-apply. 29-Mar: extsnd.html, external program linkages. auto-save via "in" in examp.scm. 23-Mar: added args to new-sound and save-sound-as. 22-Mar: smooth, smooth-selection. Removed the trailing "?" from all the functions that had a corresponding set- function without the "?". 16-Mar: graph-dots-and-lines and graph-lollipops options. 15-Mar: activate-listener. 11-Mar: added ignore_prefix arg to global-set-key. 10-Mar: file save-as under same name segfault bugfix. 8-Mar: snd 2.7. show-usage-stats with Options menu choice. 3-Mar: various bugfixes related to empty files. Changed "stop" function to "stop-playing". Added sample argument to insert-region function. 1-Mar: dismiss-all-dialogs. 26-Feb: select-all function. 23-Feb: fft.c, convolve, convolve-with, convolve-selection-with functions. 22-Feb: find and count-matches functions. MixWaveColor resource. 19-Feb: removed mix-duration-brackets, replaced with show-mix-waveforms and mix-waveform-height. 18-Feb: snd multichannel mix segfault bugfix. New sort option in files dialog ('entry'). LinuxPPC audio. 15-Feb: more colormaps. selection-transform option. 12-Feb: C++ fixups. src-selection, filter-selection, call-plug-selection, reverse, reverse-selection. added file arg to peaks function (and it follows sync buttons now). 9-Feb: removed lispcall.c. 8-Feb: snd 2.6. snd-plugin.h, anoi.c for plug-in support. new resources (zoomSliderWidth et al). 1-Feb: C-h deletes previous sample; linux save/restore mixer state finally works; much Sun audio work. NIST-sphere headers are now writable. Hadamard transform. audio-outputs function on Sun. 27-Jan: Sun-related word alignment bugfixes. AIFF headers retained (not changed to AIFC). 19-Jan: regions can now be edited. 14-Jan: sort choices to Previous Files dialog (previous-files-choice variable). 6-Jan: snd 2.5. 5-Jan: port to Cygwin Windows 95 system, and MS C. 1-Jan: removed subsampling option. 1999 ---------------------------------------------------------------- 28-Dec: lisp listener improvements, apply to selection. 21-Dec: improved guile error handling. max-fft-peaks and corruption-time variables. 15-Dec: SND_CONF for global initializations (/etc/snd.conf), and flags -noglob and -noinit. 11-Dec: expanded AIFC/RIFF possibilities. 7-Dec: max_regions variable. 4-Dec: lesstif bugfixes. 30-Nov: snd 2.4. Select all Edit menu. Sonorus Studi/o linux card support. News Help menu. 19-Nov: stop-playing-hook. 18-Nov: abort? function to interrupt guile computation. Removed Session dialog. session-file changed to save-state-file. 17-Nov: auto-trigger scale to recorder, recorder-trigger, recorder-max-duration. 16-Nov: Metrolink ctrl-click->segfault bugfix. Recorder vu-size != 1 depth != 8 bugfix. Comment field text preload and take-focus bugfix. 13-Nov: CD (analog) support in linux audio. env editor now clips x axis. 11-Nov: OSS Lite (Linux audio) work. auto-update switch. 9-Nov: snd 2.3. autoconf fixups 4-Nov: added editable frequency response graph to control panel, removed ability to load filter coeffs from file. 30-Oct: save-region has new format arg, delete-marks, mark-segments, save-segments. dB button (enved-dBing) in env editor and freq response if spectrum. envedwavecolor, min-dB variable, enved filter order text field. 26-Oct: tab-completion in listener, cursor/selection color should work. 19-Oct: Walsh Transform and built-in autocorrelation, changed to correlation in examp.scm. 12-Oct: dac-size variable; more headers. 5-Oct: snd 2.2. guile 1.3 changes. mkLinux SWiM port, rpm files, statically loaded image. add-sound-file-extension. Command and filename completion upon TAB in text widgets. Unixware 7 makefile thanks to Larry Plona. 23-Sep: clm/Snd interface changes. 21-Sep: asf headers. 16-Sep: set-oss-buffers and various lisp graph mouse/key hooks. 14-Sep: y0 and y1 args to graph (Lisp function). XmHTML support. 9-Sept: control-click 'f' or 'w' buttons affects all chans. 7-Sept: save-state implemented. global-unset-key. change-menu-label. set-menu-sensitive. 3-Sept: snd 2.1. save-edit-history. 1-Sept: global-set-key (re)implemented. Edit history feature. 27-Aug: removed old clipboard support (never worked right). 25-Aug: remove-from-menu for Buffers in examp.scm. removed -remote switch (linux bugs). 18-Aug: changed snd/clm fifo names to try to use current home directory. 17-Aug: better text handling in lisp listener (action procs), listenerFont, snd-env/clm-env. 14-Aug: horizontal-pane normalization, control panel expand typo. 10-Aug: snd 2.0. Guile added (snd-gh.c). Many non-backwards-compatible changes to snd-clm (M-x) interface. Snd compiles in Hummingbird Exceed X/Motif in Windows 95; does not yet load however. .marks and .explode clm/snd files now omit the intermediate extension (due to linux-msdos bug). Lisp listener window added below control panel. removed support for backup file (.snd-backup), all "ufun" stuff, and the escape to CLM (M-X with-sound). graph-filled option (to View Graph style menu). 30-June: better symlink handling. Transform dialog replaces 5 or 6 menu items (snd-xfft.c). fft beta now handled differently. View Info menu moved to Edit: Edit Header. New -h flag to Snd: position sounds horizontally, not vertically (vertical paned window). 25-June: DEC Alpha port. 24-June: exponential and step envelopes. Sun-related bugfixes and HPUX port thanks to Seppo Ingalsuo. control-panel related variables have new (longer) names: explen becomes expand-length and so on -- all panel settings now have parallel defaults settable via .snd or M-X: default-expand-length, etc. 12-June: snd 1.4. recorder-buffer-size variable. Recorder can read multiple card inputs in Linux. 8-June: log freq sonogram drawing bug fixed (low components didn't fill their bin completely). 2-June: print interruptible. Multi-card support in linux (quad via 2 soundcards). 27-May: more elaborate checks for write-permission problems. 28-Apr: group_max_out_chans now a variable (for n-channel mixes). 13-Apr: added amps to show-peaks in fft. 30-Mar: snd 1.3. 26-Mar: sndplay, sndinfo, audinfo, various autoconf configuration files added. 23-Mar: sound.c, sndlib.h, sndlib.html added, cmus_prototypes.h, sound_types.h removed. 20-Mar: apply in control panel now clears the panel. 19-Mar: click or drag fft to get description. 10-Mar: 8-channel ADAT support; audio.c. Fixed major bug in multi-channel scale-by and several selection-related problems. 12-Feb: 3 more header formats; Most C-x C-x built-in vars removed; override-data-location and override-sound-format. 5-Feb: 8 more header formats; show-marks is now the default. 28-Jan: Oki adpcm and snd-trans.c little-endian cases. 21-Jan: Transform type option menu with wavelet choice window. 19-Jan: src in env editor and M-X (src-width, src-style). find and expr interruptible. 12-Jan: autoResize resource. 8-Jan: snd 1.2. various env vars to customize envelope editor. Print dialog for enved print button. 1-Jan-98: save selection output file size calc was off in multi-channel case. 1998 ---------------------------------------------------------------- 22-Dec: envelope editor dialog, Sun support except for recorder. filter-env function. 12-Dec: defvar, named envelopes. 8-Dec: fft freq axis is now dragable. 3-Dec: Mix dialog is now a file selection box. global-explen and friends. 6-Oct: ports to UnixWare2 and OpenServer5 courtesy of Larry Plona. 30-Sep: snd 1.1. digital line-in recording fixed on the SGI. snd.spec. 22-Sep: iconify closes all active dialogs. 9-Sep: read-only variable and icon. 8-Sep: Lesstif 0.80 port (see README.Snd for caveats). Raw data handling improved. 1-Sep: record window implemented, save-as dialog uses file selection box. 13-Aug: [space] to pause/continue playback. 11-Aug: an icon and other sound support improvements in Linux. 20-July: searching bugs fixed. global-set-key. space cancels selection. Snd to CLM communication improved (m-x lisp expr). 8-July: cursor play stuff caused seg fault in region play. no-rld stuff removed. 26-June: y1..8 in parser. 24-June: click mix console brings it to top of stack. 23-June: C-x C-j: goto mix and other mix-<> functions. cursor follows play upon control-click. 20-June: group/mixer support. File save-as now remains in current file, rather than switching to new. 10-June: print dialog. superimposed channel graphs (part 1). 4-June: group editor. 19-May: click file name for info. 16-May: cursor changes. sync'd mixes. green sashes! 13-May: %spectrum works for normal fft. Sound control labels are clickable. initial-x0 and friends. 5-May: support for explode in CLM with-sound. dB for sonogram etc. 23-Apr: normalize-fft, better spectrum rotations. 14-Apr: first mix console step. expand clicks fixed. 4-Apr: speed style option menu, associated variables. 20-Mar: file update option. Most dialogs now not transient (not auto-raised). -remote switch. 18-Mar: x axis units option. 17-Mar: session options. selection play fixed. 14-Mar: scale-by, scale-to, amp-envelope, with selection cases. More header types. 1-Mar: data command for clm through-snd. 24-Feb: Next switches, sessions, ufun action lists. 17-Feb: file browser (view files). 10-Feb: view color and orientation menu options, with associated color variables. 31-Jan: file-loadable filter/envelopes. 20-Jan: improved spectrogram rotation, keypad keymap, wavogram. 17-Jan: dot-size. 'unite' button and Combine channels menu option. zoom focus choices (option menu). 8-Jan-97: fixed bug in fft peak calculation. Save-As in Edit menu improved. 1997 ---------------------------------------------------------------- 30-Dec: clm display hooks. 23-Dec: amp env improved. 18-Dec: new file option smarter, spectrogram improved. 16-Dec: more clm-snd connections, peaks command. 9-Dec: Info menu option, save-marks. 4-Dec: Linux fixups (XmCreateMessageDialog -> bad drawable) 20-Nov: clm marks, fixed several apply and aiff header bugs 18-Oct: Linux port. info option, c-X c-V 30-Sep: snd-trans.c 17-Sep: better support for schemes, cross disk saves 9-Sep-96: launched! 1996 ---------------------------------------------------------------- snd-16.1/examp.scm0000644000076400007640000022525212623732553012171 0ustar bilbil;;; examples of Scheme extensions to Snd ;;; ;;; documentation examples made harder to break ;;; 'info' from extsnd.html using format ;;; correlation ;;; XEmacs-like "Buffers" menu ;;; Reopen menu ;;; set transform-size based on current time domain window size ;;; superimpose spectra of sycn'd sounds ;;; translate mpeg input to 16-bit linear and read into Snd ;;; read and write OGG files ;;; make dot size dependent on number of samples being displayed ;;; move window left edge to mark upon 'm' key ;;; flash selected data red and green ;;; use loop info (if any) to set marks at loop points ;;; mapping extensions (map arbitrary single-channel function over various channel collections) ;;; do-chans, do-all-chans, do-sound-chans ;;; every-sample? ;;; sort-samples ;;; mix mono sound into stereo sound panning according to env, also simple sound placement ;;; fft-edit, fft-squelch, squelch-vowels, fft-env-interp, fft-smoother -- FFT based editing, fft-smoothing ;;; comb-filter, notch-filter, formant-filter ;;; echo (delays) ;;; ring-modulation, am, vibro ;;; src-related sound effects (src, rand-interp, etc) ;;; compand (array-interp) ;;; shift pitch keeping duration constant (src+granulate) ;;; tempo change via envelope (granulate) ;;; cross-synthesis (using a formant bank) ;;; voiced->unvoiced (formants) ;;; convolution (convolve) ;;; time varying FIR filter, notch filter ;;; sound-interp, env-sound-interp ;;; filtered-env (low-pass and amplitude follow envelope) ;;; multi-colored rxvt printout ;;; lisp graph with draggable x axis ;;; pointer focus within Snd ;;; View: Files dialog chooses which sound is displayed ;;; remove-clicks ;;; searching examples (zero+, next-peak, find-pitch) ;;; file->floats and a sort of cue-list, I think, and region-play-list, region-play-sequence ;;; explode-sf2 -- turn soundfont file into a bunch of files of the form sample-name.aif ;;; open-next-file-in-directory -- middle button click closes current file and opens next ;;; chain-dsps ;;; scramble-channels -- reorder chans ;;; scramble-channel -- randomly reorder segments within a sound ;;; reverse-by-blocks and reverse-within-blocks -- reorder or reverse blocks within a channel ;;; sound segmentation ;;; sync-everything (provide 'snd-examp.scm) (if (provided? 'snd) (require snd-ws.scm) (require sndlib-ws.scm)) (require snd-env.scm) ;;; -------- (ext)snd.html examples made harder to break -------- ;;; ;;; this mainly involves keeping track of the current sound/channel (define selection-rms (let ((documentation "(selection-rms) -> rms of selection data using samplers")) (lambda () (if (selection?) (let ((data (samples (selection-position) (selection-framples)))) (sqrt (/ (dot-product data data) (selection-framples)))) (error 'no-active-selection (list "selection-rms-1")))))) (define region-rms (let ((documentation "(region-rms n) -> rms of region n's data (chan 0)")) (lambda (reg) (if (region? reg) (let ((data (region->float-vector reg 0 0))) (sqrt (/ (dot-product data data) (length data)))) (error 'no-such-region (list "region-rms" reg)))))) (define window-samples (let ((documentation "(window-samples snd chn) -> samples in snd channel chn in current graph window")) (lambda* (snd chn) (let ((wl (left-sample snd chn)) (wr (right-sample snd chn))) (channel->float-vector wl (+ 1 (- wr wl)) snd chn))))) (define display-energy ;; in this version, the y-zoom-slider controls the graph amp (let ((documentation "(display-energy hook) is a lisp-graph-hook function to display the time domain data as energy (squared)")) (lambda (hook) (let* ((snd (hook 'snd)) (chn (hook 'chn)) (ls (left-sample snd chn)) (rs (right-sample snd chn)) (datal (make-graph-data snd chn)) (data (if (float-vector? datal) datal (cadr datal))) (sr (srate snd)) (y-max (y-zoom-slider snd chn))) (if (and data ls rs) (begin (float-vector-multiply! data data) (graph data "energy" (/ ls sr) (/ rs sr) 0.0 (* y-max y-max) snd chn #f))))))) ;(hook-push lisp-graph-hook display-energy) (define display-db (let ((documentation "(display-db hook) is a lisp-graph-hook function to display the time domain data in dB")) (lambda (hook) (let* ((snd (hook 'snd)) (chn (hook 'chn)) (datal (make-graph-data snd chn))) (if datal (let* ((data (if (float-vector? datal) datal (cadr datal))) (len (length data)) (sr (srate snd))) (define (dB val) (if (< val .001) -60.0 (* 20.0 (log val 10)))) (do ((i 0 (+ i 1))) ((= i len)) (set! (data i) (+ 60.0 (dB (abs (data i)))))) (graph data "dB" (/ (left-sample snd chn) sr) (/ (right-sample snd chn) sr) 0.0 60.0 snd chn))))))) ;(hook-push lisp-graph-hook display-db) (define window-rms (let ((documentation "(window-rms) -> rms of data in currently selected graph window")) (lambda () (let* ((ls (left-sample)) (rs (right-sample)) (data (channel->float-vector ls (+ 1 (- rs ls)))) (len (length data))) (sqrt (/ (dot-product data data) len)))))) (define fft-peak (let ((documentation "(fft-peak hook) returns the peak spectral magnitude. It is intended for use with after-transform-hook.")) (lambda (hook) (let ((snd (hook 'snd)) (chn (hook 'chn))) (if (and (transform-graph?) (= *transform-graph-type* graph-once)) (status-report (number->string (/ (* 2.0 (float-vector-peak (transform->float-vector snd chn))) *transform-size*)) snd)))))) ;(hook-push after-transform-hook fft-peak) ;;; -------- 'info' from extsnd.html using format -------- (define finfo (let ((documentation "(finfo file) -> description (as a string) of file")) (lambda (file) (format #f "~A: chans: ~D, srate: ~D, ~A, ~A, len: ~1,3F" file (channels file) (srate file) (mus-header-type-name (mus-sound-header-type file)) (mus-sample-type-name (mus-sound-sample-type file)) (/ (mus-sound-samples file) (* 1.0 (channels file) (srate file))))))) ;;; -------- Correlation -------- ;;; ;;; correlation of channels in a stereo sound (define display-correlation (let ((documentation "(display-correlation hook) returns the correlation of snd's 2 channels (intended for use with graph-hook). y0 and y1 are ignored.")) (lambda (hook) (let ((snd (hook 'snd))) (if (and (= (channels snd) 2) (> (framples snd 0) 1) (> (framples snd 1) 1)) (let* ((ls (left-sample snd 0)) (rs (right-sample snd 0)) (ilen (+ 1 (- rs ls))) (pow2 (ceiling (log ilen 2))) (fftlen (floor (expt 2 pow2))) (fftscale (/ 1.0 fftlen)) (rl1 (channel->float-vector ls fftlen snd 0)) (rl2 (channel->float-vector ls fftlen snd 1)) (im1 (make-float-vector fftlen)) (im2 (make-float-vector fftlen))) (fft rl1 im1 1) (fft rl2 im2 1) (let ((tmprl (copy rl1)) (tmpim (copy im1))) (float-vector-multiply! tmprl rl2) ; (* tempr1 tempr2) (float-vector-multiply! tmpim im2) ; (* tempi1 tempi2) (float-vector-multiply! im2 rl1) ; (* tempr1 tempi2) (float-vector-multiply! rl2 im1) ; (* tempr2 tempi1) (float-vector-add! tmprl tmpim) ; add the first two (float-vector-subtract! im2 rl2) ; subtract the 4th from the 3rd (fft tmprl im2 -1) (float-vector-scale! tmprl fftscale) ; scale by fftscale (graph tmprl "lag time" 0 fftlen))) (status-report "display-correlation wants stereo input")))))) ;(hook-push graph-hook display-correlation) ;;; -------- set transform-size based on current time domain window size ;;; ;;; also zoom spectrum based on y-axis zoom slider (define zoom-spectrum (let ((documentation "(zoom-spectrum hook) sets the transform size to correspond to the time-domain window size (use with graph-hook)")) (lambda (hook) (let ((snd (hook 'snd)) (chn (hook 'chn))) (if (and (transform-graph? snd chn) (= (transform-graph-type snd chn) graph-once)) (begin (set! (transform-size snd chn) (expt 2 (ceiling (log (- (right-sample snd chn) (left-sample snd chn)) 2.0)))) (set! (spectrum-end snd chn) (y-zoom-slider snd chn)))))))) ;(hook-push graph-hook zoom-spectrum) ;;; -------- superimpose spectra of sycn'd sounds (define superimpose-ffts (let ((documentation "(superimpose-ffts hook) superimposes ffts of multiple (syncd) sounds (use with graph-hook)")) (lambda (hook) (let ((maxsync (apply max (map sync (sounds)))) (snd (hook 'snd)) (chn (hook 'chn)) (y0 (hook 'y0)) (y1 (hook 'y1))) (if (and (> (sync snd) 0) (> (right-sample snd chn) (left-sample snd chn)) (equal? snd (integer->sound (apply min (map (lambda (n) (if (= (sync snd) (sync n)) (sound->integer n) (+ 1 maxsync))) (sounds)))))) (let* ((ls (left-sample snd chn)) (rs (right-sample snd chn)) (pow2 (ceiling (log (max 1 (- rs ls)) 2))) (fftlen (floor (expt 2 pow2)))) (if (> pow2 2) (let ((ffts ())) (for-each (lambda (n) (if (and (= (sync n) (sync snd)) (> (channels n) chn)) (set! ffts (append ffts (let ((fdr (channel->float-vector ls fftlen n chn)) (fdi (make-float-vector fftlen)) (spectr (make-float-vector (/ fftlen 2)))) (list (float-vector-add! spectr (spectrum fdr fdi #f 2)))))))) (sounds)) (graph ffts "spectra" 0.0 0.5 y0 y1 snd chn))))))))) ;;(hook-push graph-hook superimpose-ffts) ;;; -------- translate mpeg input to 16-bit linear and read into Snd ;;; ;;; mpg123 with the -s switch sends the 16-bit (mono or stereo) representation of ;;; an mpeg file to stdout. There's also apparently a switch to write 'wave' output. (define mpg (let ((documentation "(mpg file tmpname) converts file from MPEG to raw 16-bit samples using mpg123")) (lambda (mpgfile rawfile) (let* ((fd (open-input-file mpgfile "r")) (b0 (char->integer (read-char fd))) (b1 (char->integer (read-char fd))) (b2 (char->integer (read-char fd))) (b3 (char->integer (read-char fd)))) (close-input-port fd) (if (or (not (= b0 255)) (not (= (logand b1 #b11100000) #b11100000))) (snd-print (format #f "~S is not an MPEG file (first 11 bytes: #b~B #b~B)" mpgfile b0 (logand b1 #b11100000))) (let ((id (ash (logand b1 #b11000) -3)) (layer (ash (logand b1 #b110) -1)) ;; (protection (logand b1 1)) ;; (bitrate-index (ash (logand b2 #b11110000) -4)) (srate-index (ash (logand b2 #b1100) -2)) ;; (padding (ash (logand b2 #b10) -1)) (channel-mode (ash (logand b3 #b11000000) -6)) ;; (mode-extension (ash (logand b3 #b110000) -4)) ;; (copyright (ash (logand b3 #b1000) -3)) ;; (original (ash (logand b3 #b100) -2)) ;; (emphasis (logand b3 #b11)) ) (if (= id 1) (snd-print (format #f "odd: ~S is using a reserved Version ID" mpgfile))) (if (= layer 0) (snd-print (format #f "odd: ~S is using a reserved layer description" mpgfile))) (let* ((chans (if (= channel-mode 3) 1 2)) (mpegnum (if (= id 0) 4 (if (= id 2) 2 1))) (mpeg-layer (if (= layer 3) 1 (if (= layer 2) 2 3))) (srate (/ (list-ref (list 44100 48000 32000 0) srate-index) mpegnum))) (snd-print (format #f "~S: ~A Hz, ~A, MPEG-~A~%" mpgfile srate (if (= chans 1) "mono" "stereo") mpeg-layer)) (system (format #f "mpg123 -s ~A > ~A" mpgfile rawfile)) (open-raw-sound rawfile chans srate (if (little-endian?) mus-lshort mus-bshort))))))))) ;;; (mpg "mpeg.mpg" "mpeg.raw") ;;; -------- read and write OGG files (define read-ogg (let ((documentation "(read-ogg filename) tries to open an OGG file")) (lambda (filename) ;; check for "OggS" first word, if found, translate to something Snd can read ;; (open-sound (read-ogg "/home/bil/sf1/oboe.ogg")) (and (call-with-input-file filename (lambda (fd) (and (char=? (read-char fd) #\O) (char=? (read-char fd) #\g) (char=? (read-char fd) #\g) (char=? (read-char fd) #\S)))) (let ((aufile (string-append filename ".au"))) (if (file-exists? aufile) (delete-file aufile)) (system (format #f "ogg123 -d au -f ~A ~A" aufile filename)) aufile))))) #| (hook-push open-hook (lambda (hook) (let ((filename (hook 'name))) (if (= (mus-sound-header-type filename) mus-raw) (read-ogg filename))))) ;; was returning #f? |# (define write-ogg (let ((documentation "(write-ogg snd) writes 'snd' in OGG format")) (lambda (snd) (if (or (> (car (edits snd)) 0) (not (= (header-type snd) mus-riff))) (let ((file (string-append (file-name snd) ".tmp"))) (save-sound-as file snd :header-type mus-riff) (system (format #f "oggenc ~A" file)) (delete-file file)) (system (format #f "oggenc ~A" (file-name snd))))))) ;;; -------- read and write Speex files (define read-speex (let ((documentation "(read-speex filename) tries to open a SPEEX file")) (lambda (filename) (let ((wavfile (string-append filename ".wav"))) (if (file-exists? wavfile) (delete-file wavfile)) (system (format #f "speexdec ~A ~A" filename wavfile)) wavfile)))) (define write-speex (let ((documentation "(write-speex snd) writes 'snd' in Speex format")) (lambda (snd) ;; write snd data in Speex format (if (or (> (car (edits snd)) 0) (not (= (header-type snd) mus-riff))) (let ((file (string-append (file-name snd) ".wav")) (spxfile (string-append (file-name snd) ".spx"))) (save-sound-as file snd :header-type mus-riff) (system (format #f "speexenc ~A ~A" file spxfile)) (delete-file file)) (system (format #f "speexenc ~A ~A" (file-name snd) (string-append (file-name snd) ".spx"))))))) ;;; -------- read and write FLAC files (define read-flac (let ((documentation "(read-flac filename) tries to read a FLAC file")) (lambda (filename) (system (format #f "flac -d ~A" filename))))) (define write-flac (let ((documentation "(write-flac snd) writes 'snd' in a FLAC file")) (lambda (snd) ;; write snd data in FLAC format (if (or (> (car (edits snd)) 0) (not (= (header-type snd) mus-riff))) (let ((file (string-append (file-name snd) ".wav"))) (save-sound-as file snd :header-type mus-riff) (system (format #f "flac ~A" file)) (delete-file file)) (system (format #f "flac ~A" (file-name snd))))))) ;;; -------- play AC3 via a52dec (define play-ac3 (let ((documentation "(play-ac3 name) uses a52dec to play an AC3 sound")) (lambda (name) ;; to turn an AC3 file into something Snd can edit, /usr/local/bin/a52dec test.ac3 -o wav > test.wav (system (format #f "a52dec ~A" name))))) ;;; -------- read ASCII files ;;; ;;; these are used by Octave (WaveLab) -- each line has one integer, apparently a signed short. (define read-ascii (let ((documentation "(read-ascii in-filename (out-filename \"test.snd\") (out-type mus-next) (out-format mus-bshort) (out-srate 44100)) tries to \ read an ASCII sound file")) (lambda* (in-filename (out-filename "test.snd") (out-type mus-next) (out-format mus-bshort) (out-srate 44100)) (let ((in-fd (open-input-file in-filename)) (out-fd (new-sound out-filename 1 out-srate out-format out-type (format #f "created by read-ascii: ~A" in-filename))) (bufsize 8192) (bufsize1 8191)) (as-one-edit (lambda () (let ((data (make-float-vector bufsize)) (short->float (/ 1.0 32768.0))) (do ((fr 0 (+ fr bufsize))) ((eof-object? (peek-char in-fd))) (do ((loc 0 (+ loc 1)) (val (read-line in-fd) (read-line in-fd))) ((or (eof-object? val) (= loc bufsize1)) ; bufsize-1 so that we don't throw away a sample at the buffer end (if (number? val) (begin (float-vector-set! data loc (* (string->number val) short->float)) (float-vector->channel data fr (+ loc 1) out-fd 0)) (float-vector->channel data fr loc out-fd 0))) (float-vector-set! data loc (* (string->number val) short->float))))))) (close-input-port in-fd) out-fd)))) ;;; -------- make dot size dependent on number of samples being displayed ;;; ;;; this could be extended to set time-graph-style to graph-lines if many samples are displayed, etc (define auto-dot (let ((documentation "(auto-dot hook) sets the dot size depending on the number of samples being displayed (use with graph-hook)")) (lambda (hook) (let* ((snd (hook 'snd)) (chn (hook 'chn)) (dots (- (right-sample snd chn) (left-sample snd chn)))) (if (> dots 100) (set! (dot-size snd chn) 1) (if (> dots 50) (set! (dot-size snd chn) 2) (if (> dots 25) (set! (dot-size snd chn) 3) (set! (dot-size snd chn) 5)))))))) ;(hook-push graph-hook auto-dot) ;;; -------- move window left edge to mark upon 'm' ;;; ;;; in large sounds, it can be pain to get the left edge of the window ;;; aligned with a specific spot in the sound. In this code, we assume ;;; the desired left edge has a mark, and the 'm' key (without control) ;;; will move the window left edge to that mark. (define first-mark-in-window-at-left (let ((documentation "(first-mark-in-window-at-left) moves the graph so that the leftmost visible mark is at the left edge")) (lambda () (let* ((keysnd (or (selected-sound) (car (sounds)))) (keychn (or (selected-channel keysnd) 0)) (current-left-sample (left-sample keysnd keychn)) (chan-marks (marks keysnd keychn))) (define (find-leftmost-mark samps) (and (pair? samps) (if (> (car samps) current-left-sample) (car samps) (find-leftmost-mark (cdr samps))))) (if (= (length chan-marks) 0) (status-report "no marks!") (let ((leftmost (find-leftmost-mark (map mark-sample chan-marks)))) (if (number? leftmost) (begin (set! (left-sample keysnd keychn) leftmost) keyboard-no-action) (status-report "no mark in window")))))))) ;(bind-key #\m 0 (lambda () "align window left edge with mark" (first-mark-in-window-at-left))) ;;; -------- flash selected data red and green (define flash-selected-data (let ((data-red? #t) (red (make-color 1 0 0)) (green (make-color 0 1 0)) (documentation "(flash-selected-data millisecs) causes the selected data to flash red and green")) (lambda (interval) (if (selected-sound) (begin (set! *selected-data-color* (if data-red? green red)) (set! data-red? (not data-red?)) (in interval (lambda () (flash-selected-data interval)))))))) ;;; -------- use loop info (if any) to set marks at loop points (define mark-loops (let ((documentation "(mark-loops) places marks at loop points found in the selected sound's header")) (lambda () (let ((loops (or (sound-loop-info) (mus-sound-loop-info (file-name))))) (if (pair? loops) (if (not (= (car loops) 0 (cadr loops))) (begin (add-mark (car loops)) (add-mark (cadr loops)) (if (not (= (caddr loops) 0 (cadddr loops))) (begin (add-mark (caddr loops)) (add-mark (cadddr loops)))))) (snd-print (format #f "~S has no loop info" (short-file-name)))))))) ;;; -------- mapping extensions (map arbitrary single-channel function over various channel collections) ;;; (define all-chans (let ((documentation "(all-chans) -> two parallel lists, the first sound objects, the second channel numbers. If we have two sounds open (indices 0 and 1 for example), and the second has two channels, (all-chans) returns '((# # #) (0 0 1))")) (lambda () (let ((sndlist ()) (chnlist ())) (for-each (lambda (snd) (let ((chntop (- (channels snd) 1))) (do ((i chntop (- i 1))) ((< i 0)) (set! sndlist (cons snd sndlist)) (set! chnlist (cons i chnlist))))) (sounds)) (list sndlist chnlist))))) (define do-all-chans (let ((documentation "(do-all-chans func edhist) applies func to all active channels, using edhist as the edit history indication: (do-all-chans (lambda (val) (* 2.0 val)) \"double all samples\")")) (lambda* (func origin) (apply for-each (lambda (snd chn) (map-channel func 0 #f snd chn #f origin)) (all-chans))))) (define update-graphs (let ((documentation "(update-graphs) updates (redraws) all graphs")) (lambda () (apply for-each update-time-graph (all-chans))))) (define do-chans (let ((documentation "(do-chans func edhist) applies func to all sync'd channels using edhist as the edit history indication")) (lambda* (func origin) (let ((snc (sync))) (if (> snc 0) (apply for-each (lambda (snd chn) (if (= (sync snd) snc) (map-channel func 0 #f snd chn #f origin))) (all-chans)) (snd-warning "sync not set")))))) (define do-sound-chans (let ((documentation "(do-sound-chans func edhist) applies func to all selected channels using edhist as the edit history indication")) (lambda* (proc origin) (let ((snd (selected-sound))) (if snd (do ((chn 0 (+ 1 chn))) ((= chn (channels snd)) #f) (map-channel proc 0 #f snd chn #f origin)) (snd-warning "no selected sound")))))) (define every-sample? (let ((documentation "(every-sample func) -> #t if func is not #f for all samples in the current channel, otherwise it moves the cursor to the first offending sample")) (lambda (proc) (let ((reader (make-sampler)) (len (framples))) (call-with-exit (lambda (quit) (do ((i 0 (+ i 1))) ((= i len) #t) (if (not (proc (next-sample reader))) (begin (set! (cursor) i) (quit #f)))))))))) (define sort-samples (let ((documentation "(sort-samples bins) provides a histogram in 'bins' bins")) (lambda (nbins) (let ((bins (make-vector nbins 0)) (reader (make-sampler)) (len (framples)) (ops (make-vector nbins))) (do ((i 0 (+ i 1))) ((= i nbins)) (set! (ops i) (make-one-pole 1.0 -1.0))) (do ((i 0 (+ i 1))) ((= i len)) (one-pole (vector-ref ops (floor (* nbins (abs (next-sample reader))))) 1.0)) (do ((i 0 (+ i 1))) ((= i nbins) bins) (set! (bins i) (floor (one-pole (ops i) 0.0)))))))) ;;; -------- mix mono sound into stereo sound panning according to env (define place-sound (let ((documentation "(place-sound mono-snd stereo-snd pan-env) mixes a mono sound into a stereo sound, splitting it into two copies whose amplitudes depend on the envelope 'pan-env'. If 'pan-env' is a number, the sound is split such that 0 is all in channel 0 and 90 is all in channel 1.")) (lambda (mono-snd stereo-snd pan-env) (let ((len (framples mono-snd))) (if (number? pan-env) (let ((pos (/ pan-env 90.0)) (reader0 (make-sampler 0 mono-snd)) (reader1 (make-sampler 0 mono-snd))) (map-channel (lambda (y) (+ y (* pos (read-sample reader1)))) 0 len stereo-snd 1) (map-channel (lambda (y) (+ y (* (- 1.0 pos) (read-sample reader0)))) 0 len stereo-snd 0)) (let ((e0 (make-env pan-env :length len)) (e1 (make-env pan-env :length len)) (reader0 (make-sampler 0 mono-snd)) (reader1 (make-sampler 0 mono-snd))) (map-channel (lambda (y) (+ y (* (env e1) (read-sample reader1)))) 0 len stereo-snd 1) (map-channel (lambda (y) (+ y (* (- 1.0 (env e0)) (read-sample reader0)))) 0 len stereo-snd 0))))))) ;;; -------- FFT-based editing ;;; (define fft-edit (let ((documentation "(fft-edit low-Hz high-Hz snd chn) ffts an entire sound, removes all energy below low-Hz and all above high-Hz, then inverse ffts.")) (lambda* (bottom top snd chn) (let* ((sr (srate snd)) (len (framples snd chn)) (fsize (expt 2 (ceiling (log len 2)))) (fsize2 (/ fsize 2)) (rdata (channel->float-vector 0 fsize snd chn)) (idata (make-float-vector fsize)) (lo (round (/ bottom (/ sr fsize)))) (hi (round (/ top (/ sr fsize))))) (fft rdata idata 1) (if (> lo 0) (begin (fill! rdata 0.0 0 lo) (fill! idata 0.0 0 lo) (fill! rdata (- fsize lo) fsize) (fill! idata (- fsize lo) fsize))) (if (< hi fsize2) (begin (fill! rdata 0.0 hi (- fsize hi)) (fill! idata 0.0 hi (- fsize hi)))) (fft rdata idata -1) (float-vector-scale! rdata (/ 1.0 fsize)) (float-vector->channel rdata 0 (- len 1) snd chn #f (format #f "fft-edit ~A ~A" bottom top)))))) (define fft-squelch (let ((documentation "(fft-squelch squelch snd chn) ffts an entire sound, sets all bins to 0.0 whose energy is below squelch, then inverse ffts")) (lambda* (squelch snd chn) (let* ((len (framples snd chn)) (fsize (expt 2 (ceiling (log len 2)))) (rdata (channel->float-vector 0 fsize snd chn)) (idata (make-float-vector fsize)) (scaler 1.0)) (fft rdata idata 1) (let ((vr (copy rdata)) (vi (copy idata))) (rectangular->polar vr vi) (set! scaler (float-vector-peak vr))) (let ((scl-squelch (* squelch scaler)) (rd (copy rdata)) (id (copy idata))) (float-vector-multiply! rd rd) (float-vector-multiply! id id) (float-vector-add! rd id) (do ((i 0 (+ i 1))) ((= i fsize)) (if (< (sqrt (float-vector-ref rd i)) scl-squelch) (begin (set! (rdata i) 0.0) (set! (idata i) 0.0)))) (fft rdata idata -1) (float-vector-scale! rdata (/ 1.0 fsize))) (float-vector->channel rdata 0 (- len 1) snd chn #f (format #f "fft-squelch ~A" squelch)) scaler)))) (define fft-cancel (let ((documentation "(fft-cancel lo-freq hi-freq snd chn) ffts an entire sound, sets the bin(s) representing lo-freq to hi-freq to 0.0, then inverse ffts")) (lambda* (lo-freq hi-freq snd chn) (let* ((sr (srate snd)) (len (framples snd chn)) (fsize (expt 2 (ceiling (log len 2)))) (rdata (channel->float-vector 0 fsize snd chn)) (idata (make-float-vector fsize))) (fft rdata idata 1) (let* ((hz-bin (/ sr fsize)) (lo-bin (round (/ lo-freq hz-bin))) (hi-bin (round (/ hi-freq hz-bin)))) (fill! rdata 0.0 lo-bin hi-bin) (fill! idata 0.0 lo-bin hi-bin) (fill! rdata 0.0 (- fsize hi-bin) (- fsize lo-bin))) (fft rdata idata -1) (float-vector-scale! rdata (/ 1.0 fsize)) (float-vector->channel rdata 0 (- len 1) snd chn #f (format #f "fft-cancel ~A ~A" lo-freq hi-freq)))))) ;;; same idea but used to distinguish vowels (steady-state) from consonants (define ramp (let ((documentation "(ramp gen up) is a kind of CLM generator that produces a ramp of a given length, then sticks at 0.0 or 1.0 until the 'up' argument changes")) (lambda (gen up) ;; gen is list: ctr size ;; the idea here is that we want to ramp in or out a portion of a sound based on some ;; factor of the sound data -- the ramp gen produces a ramp up when 'up' is #t, sticking ;; at 1.0, and a ramp down when 'up' is #f, sticking at 0.0 ;; ;; this could use the moving-average generator (or one-pole?) (let-set! gen 'up up) (with-let gen (set! val (min 1.0 (max 0.0 (+ val (if up incr (- incr)))))))))) (define* (make-ramp (size 128)) (inlet 'val 0.0 'incr (/ 1.0 size) 'up 1)) ;;; (let ((r (make-ramp))) (map-channel (lambda (y) (* y (ramp r (> (random 1.0) 0.5)))))) (define squelch-vowels (let ((documentation "(squelch-vowels snd chn) suppresses portions of a sound that look like steady-state")) (lambda* (snd chn) (let* ((fft-size 32) (fft-mid (floor (/ fft-size 2))) (rl (make-float-vector fft-size)) (im (make-float-vector fft-size)) (ramper (make-ramp 256)) ; 512 ok too (peak (/ (maxamp) fft-mid)) (read-ahead (make-sampler 0 snd chn)) (ctr 0) (in-vowel #f)) (do ((i 0 (+ i 1))) ((= i fft-size)) (float-vector-set! rl i (read-sample read-ahead))) (set! ctr (- fft-size 1)) (map-channel (lambda (y) (set! ctr (+ ctr 1)) (if (= ctr fft-size) (begin (fft rl im 1) (float-vector-multiply! rl rl) (float-vector-multiply! im im) (float-vector-add! rl im) (set! in-vowel (> (+ (rl 0) (rl 1) (rl 2) (rl 3)) peak)) ;; fancier version checked here ratio of this sum and ;; sum of all rl vals, returned vowel if > 0.5 (set! ctr 0) (do ((i 0 (+ i 1))) ((= i fft-size)) (float-vector-set! rl i (read-sample read-ahead))) (fill! im 0.0))) (let ((rval (- 1.0 (ramp ramper in-vowel)))) ; squelch consonants if just ramp value (not 1.0-val) ;(and (> rval 0.0) ; if this is included, the vowel-portions are omitted (* y rval) ; squelch vowels ;(* y (+ (* 2 rval) .1)) ;accentuate consonants )) 0 #f snd chn #f "squelch-vowels"))))) (define fft-env-data (let ((documentation "(fft-env-data fft-env snd chn) applies fft-env as spectral env to current sound, returning float-vector of new data")) (lambda* (fft-env snd chn) (let* ((len (framples snd chn)) (fsize (expt 2 (ceiling (log len 2)))) (rdata (channel->float-vector 0 fsize snd chn)) (idata (make-float-vector fsize)) (e (make-env (concatenate-envelopes fft-env (reverse-envelope fft-env)) :length fsize)) (ve (make-float-vector fsize))) (fft rdata idata 1) (do ((i 0 (+ i 1))) ((= i fsize)) (float-vector-set! ve i (env e))) (float-vector-multiply! rdata ve) (float-vector-multiply! idata ve) (fft rdata idata -1) (float-vector-scale! rdata (/ 1.0 fsize)))))) (define fft-env-edit (let ((documentation "(fft-env-edit fft-env snd chn) edits (filters) current chan using fft-env")) (lambda* (fft-env snd chn) (float-vector->channel (fft-env-data fft-env snd chn) 0 (- (framples) 1) snd chn #f (format #f "fft-env-edit '~A" fft-env))))) (define fft-env-interp (let ((documentation "(fft-env-interp env1 env2 interp snd chn) interpolates between two fft-filtered versions (env1 and env2 are the spectral envelopes) following interp (an env between 0 and 1)")) (lambda* (env1 env2 interp snd chn) (let* ((data1 (fft-env-data env1 snd chn)) (data2 (fft-env-data env2 snd chn)) (len (framples snd chn)) (new-data (make-float-vector len)) (e (make-env interp :length len)) (erev (make-env (scale-envelope interp -1.0 1.0) :length len))) ; 1.0 - e (do ((i 0 (+ i 1))) ((= i len)) (float-vector-set! new-data i (+ (* (env erev) (float-vector-ref data1 i)) (* (env e) (float-vector-ref data2 i))))) (float-vector->channel new-data 0 (- len 1) snd chn #f (format #f "fft-env-interp '~A '~A '~A" env1 env2 interp)))))) (define filter-fft (let ((documentation "(filter-fft flt normalize snd chn) gets the spectrum of all the data in the given channel, \ applies the function 'flt' to it, then inverse ffts. 'flt' should take one argument, the \ current spectrum value. (filter-fft (lambda (y) (if (< y .01) 0.0 y))) is like fft-squelch.")) (lambda* (flt (normalize #t) snd chn) (let* ((len (framples snd chn)) (mx (maxamp snd chn)) (fsize (expt 2 (ceiling (log len 2)))) (fsize2 (/ fsize 2)) ;(orig 0.0) (cur 0.0) (rdata (channel->float-vector 0 fsize snd chn)) (idata (make-float-vector fsize)) (spect (snd-spectrum rdata rectangular-window fsize #t 1.0 #f normalize)) ; not in-place! (vf (make-float-vector fsize))) (fft rdata idata 1) (flt (spect 0)) (do ((i 1 (+ i 1)) (j (- fsize 1) (- j 1))) ((= i fsize2)) (float-vector-set! vf j (float-vector-set! vf i (/ (flt (spect i)) (max (spect i) 1e-5))))) (float-vector-multiply! rdata vf) (float-vector-multiply! idata vf) (fft rdata idata -1) (if (not (= mx 0.0)) (let ((pk (float-vector-peak rdata))) (float-vector->channel (float-vector-scale! rdata (/ mx pk)) 0 (- len 1) snd chn #f (format #f "filter-fft ~A" flt))) (float-vector->channel rdata 0 (- len 1) snd chn #f (format #f "filter-fft ~A" flt))))))) ;; (let ((op (make-one-zero .5 .5))) (filter-fft op)) ;; (let ((op (make-one-pole .05 .95))) (filter-fft op)) ;; (filter-fft (lambda (y) (if (< y .1) 0.0 y))) ;; (let ((rd (make-sampler 0 0 0 1 0))) (scale-by 0) (filter-fft (lambda (y) (rd)))) ; treat original sound as spectrum ;; (filter-fft contrast-enhancement) ;; (filter-fft (lambda (y) (* y y y))) ; extreme low pass #| (let* ((ind (or (find-sound "now.snd") (open-sound "now.snd"))) (mx (maxamp ind 0))) (do ((i 1 (+ i 1)) (lo 0.0 (+ lo .1))) ((= i 8)) (filter-fft (lambda (y) (contrast-enhancement y (+ 1.0 (* lo 30.0)))) #t ind 0)) (let ((mixers (make-vector 8))) (do ((i 0 (+ i 1)) (lo 0.001 (+ lo .12))) ((= i 8)) (env-sound (list 0 0 lo 1 1 0) 0 #f 32.0 ind 0 (+ i 1)) (set! (mixers i) (make-sampler 0 ind 0 1 (edit-position ind 0)))) (scale-by 0.0) (map-channel (lambda (y) (let ((sum 0.0)) (do ((i 0 (+ i 1))) ((= i 8) sum) (set! sum (+ sum (read-sample (mixers i))))))))) (scale-to mx)) |# (define fft-smoother (let ((documentation "(fft-smoother cutoff start samps snd chn) uses fft-filtering to smooth a section: (float-vector->channel (fft-smoother .1 (cursor) 400) (cursor) 400)")) (lambda* (cutoff start samps snd chn) (let* ((fftpts (floor (expt 2 (ceiling (log (+ 1 samps) 2))))) (rl (channel->float-vector start fftpts snd chn)) (im (make-float-vector fftpts)) (top (floor (* fftpts cutoff)))) (let ((old0 (rl 0)) (old1 (rl (- samps 1))) (oldmax (float-vector-peak rl))) (fft rl im 1) (do ((i top (+ i 1))) ((= i fftpts)) (set! (rl i) 0.0) (set! (im i) 0.0)) (fft rl im -1) (float-vector-scale! rl (/ 1.0 fftpts)) (let ((newmax (float-vector-peak rl))) (if (= newmax 0.0) rl (begin (if (> (/ oldmax newmax) 1.5) (float-vector-scale! rl (/ oldmax newmax))) (let* ((new0 (rl 0)) (new1 (rl (- samps 1))) (offset0 (- old0 new0)) (offset1 (- old1 new1)) (incr (if (= offset1 offset0) 0.0 (/ (- offset1 offset0) samps)))) (do ((i 0 (+ i 1)) (trend offset0 (+ trend incr))) ((= i samps)) (set! (rl i) (+ (rl i) trend))) rl))))))))) ;;; -------- comb-filter (define comb-filter (let ((documentation "(comb-filter scaler size) returns a comb-filter ready for map-channel etc: (map-channel (comb-filter .8 32)). If you're in a hurry use: (clm-channel (make-comb .8 32)) instead")) (lambda (scaler size) (let ((cmb (make-comb scaler size))) (lambda (x) (comb cmb x)))))) ;;; by using filters at harmonically related sizes, we can get chords: (define comb-chord (let ((documentation "(comb-chord scaler size amp) returns a set of harmonically-related comb filters: (map-channel (comb-chord .95 100 .3))")) (lambda (scaler size amp) (let ((cs (make-comb-bank (vector (make-comb scaler (floor size)) (make-comb scaler (floor (* size .75))) (make-comb scaler (floor (* size 1.2))))))) (lambda (x) (* amp (comb-bank cs x))))))) ;;; or change the comb length via an envelope: (define zcomb (let ((documentation "(zcomb scaler size pm) returns a comb filter whose length varies according to an envelope: (map-channel (zcomb .8 32 '(0 0 1 10)))")) (lambda (scaler size pm) (define (max-envelope-1 e mx) (if (null? e) mx (max-envelope-1 (cddr e) (max mx (abs (cadr e)))))) (let ((cmb (make-comb scaler size :max-size (floor (+ size 1 (max-envelope-1 pm 0.0))))) (penv (make-env pm :length (framples)))) (lambda (x) (comb cmb x (env penv))))))) (define notch-filter (let ((documentation "(notch-filter scaler size) returns a notch-filter: (map-channel (notch-filter .8 32))")) (lambda (scaler size) (let ((cmb (make-notch scaler size))) (lambda (x) (notch cmb x)))))) (define formant-filter (let ((documentation "(formant-filter radius frequency) returns a formant generator: (map-channel (formant-filter .99 2400)). Faster is: (filter-sound (make-formant 2400 .99))")) (lambda (radius frequency) (let ((frm (make-formant frequency radius))) (lambda (x) (formant frm x)))))) ;;; to impose several formants, just add them in parallel: (define formants (let ((documentation "(formants r1 f1 r2 f2 r3 f3) returns 3 formant filters in parallel: (map-channel (formants .99 900 .98 1800 .99 2700))")) (lambda (r1 f1 r2 f2 r3 f3) (let ((fr1 (make-formant f1 r1)) (fr2 (make-formant f2 r2)) (fr3 (make-formant f3 r3))) (lambda (x) (+ (formant fr1 x) (formant fr2 x) (formant fr3 x))))))) (define moving-formant (let ((documentation "(moving-formant radius move) returns a time-varying (in frequency) formant filter: (map-channel (moving-formant .99 '(0 1200 1 2400)))")) (lambda (radius move) (let ((frm (make-formant (cadr move) radius)) (menv (make-env move :length (framples)))) (lambda (x) (let ((val (formant frm x))) (mus-set-formant-frequency frm (env menv)) val)))))) (define osc-formants (let ((documentation "(osc-formants radius bases amounts freqs) set up any number of independently oscillating formants, then calls map-channel: (osc-formants .99 (float-vector 400.0 800.0 1200.0) (float-vector 400.0 800.0 1200.0) (float-vector 4.0 2.0 3.0))")) (lambda (radius bases amounts freqs) ; changed to call map-channel itself, 21-Apr-05 (let ((len (length bases))) (if (= len 3) ;; this way is faster but verbose (let ((fa1 (amounts 0)) (fa2 (amounts 1)) (fa3 (amounts 2)) (frq1 (bases 0)) (frq2 (bases 1)) (frq3 (bases 2)) (fr1 (make-formant (bases 0) radius)) (fr2 (make-formant (bases 1) radius)) (fr3 (make-formant (bases 2) radius)) (o1 (make-oscil (freqs 0))) (o2 (make-oscil (freqs 1))) (o3 (make-oscil (freqs 2)))) (map-channel (lambda (y) (+ (formant fr1 y (hz->radians (+ frq1 (* fa1 (oscil o1))))) (formant fr2 y (hz->radians (+ frq2 (* fa2 (oscil o2))))) (formant fr3 y (hz->radians (+ frq3 (* fa3 (oscil o3))))))))) (let ((frms (make-vector len)) (oscs (make-vector len)) (amps (make-float-vector len 1.0))) (do ((i 0 (+ i 1))) ((= i len)) (set! (frms i) (make-formant (bases i) radius)) (set! (oscs i) (make-oscil (freqs i)))) (let ((frms1 (make-formant-bank frms amps))) (map-channel (lambda (x) (let ((val (formant-bank frms1 x))) (do ((i 0 (+ i 1))) ((= i len)) (mus-set-formant-frequency (vector-ref frms i) (+ (bases i) (* (amounts i) (oscil (oscs i)))))) val)))))))))) ;;; -------- echo (define echo (let ((documentation "(echo scaler secs) returns an echo maker: (map-channel (echo .5 .5) 0 44100)")) (lambda (scaler secs) (let ((del (make-delay (round (* secs (srate)))))) (lambda (inval) (+ inval (delay del (* scaler (+ (tap del) inval))))))))) (define zecho (let ((documentation "(zecho scaler secs freq amp) returns a modulated echo maker: (map-channel (zecho .5 .75 6 10.0) 0 65000)")) (lambda (scaler secs frq amp) (let* ((os (make-oscil frq)) (len (round (* secs (srate)))) (del (make-delay len :max-size (floor (+ len amp 1))))) (lambda (inval) (+ inval (delay del (* scaler (+ (tap del) inval)) (* amp (oscil os))))))))) (define flecho (let ((documentation "(flecho scaler secs) returns a low-pass filtered echo maker: (map-channel (flecho .5 .9) 0 75000)")) (lambda (scaler secs) (let ((flt (make-fir-filter :order 4 :xcoeffs (float-vector .125 .25 .25 .125))) (del (make-delay (round (* secs (srate)))))) (lambda (inval) (+ inval (delay del (fir-filter flt (* scaler (+ (tap del) inval)))))))))) ;;; -------- ring-mod and am ;;; ;;; CLM instrument is ring-modulate.ins (define ring-mod (let ((documentation "(ring-mod freq gliss-env) returns a time-varying ring-modulation filter: (map-channel (ring-mod 10 (list 0 0 1 (hz->radians 100))))")) (lambda (freq gliss-env) (let* ((os (make-oscil :frequency freq)) (len (framples)) (genv (make-env gliss-env :length len))) (lambda (inval) (* (oscil os (env genv)) inval)))))) (define am (let ((documentation "(am freq)returns an amplitude-modulator: (map-channel (am 440))")) (lambda (freq) (let ((os (make-oscil freq))) (lambda (inval) (amplitude-modulate 1.0 inval (oscil os))))))) ;;; this taken from sox (vibro.c) (define vibro (let ((documentation "(vibro speed depth) adds vibrato or tremolo")) (lambda (speed depth) (let* ((sine (make-oscil speed)) (scl (* 0.5 depth)) (offset (- 1.0 scl))) (lambda (y) (* y (+ offset (* scl (oscil sine))))))))) ;;; -------- hello-dentist ;;; ;;; CLM instrument version is in clm.html (define hello-dentist (let ((documentation "(hello-dentist frq amp snd chn) varies the sampling rate randomly, making a voice sound quavery: (hello-dentist 40.0 .1)")) (lambda* (frq amp snd chn) (let* ((rn (make-rand-interp :frequency frq :amplitude amp)) (len (framples)) (rd (make-sampler 0 snd chn)) (sr (make-src :srate 1.0 :input (lambda (dir) (read-sample-with-direction rd dir))))) (map-channel (lambda (y) (src sr (rand-interp rn))) 0 len snd chn #f (format #f "hello-dentist ~A ~A" frq amp)))))) ;;; a very similar function uses oscil instead of rand-interp, giving ;;; various "Forbidden Planet" sound effects: (define fp (let ((documentation "(fp sr osamp osfrq snd chn) varies the sampling rate via an oscil: (fp 1.0 .3 20)")) (lambda* (sr osamp osfrq snd chn) (let* ((os (make-oscil osfrq)) (sf (make-sampler 0 snd chn)) (s (make-src :srate sr :input (lambda (dir) (read-sample-with-direction sf dir))))) (map-channel (lambda (y) (src s (* osamp (oscil os)))) 0 #f snd chn #f (format #f "fp ~A ~A ~A" sr osamp osfrq)))))) ;;; -------- compand, compand-channel (define compand-table (float-vector -1.000 -0.960 -0.900 -0.820 -0.720 -0.600 -0.450 -0.250 0.000 0.250 0.450 0.600 0.720 0.820 0.900 0.960 1.000)) ;; (we're eye-balling the curve on p55 of Steiglitz's "a DSP Primer") (define compand (let ((documentation "(compand) returns a compander: (map-channel (compand))")) (lambda () (lambda (inval) (array-interp compand-table (+ 8.0 (* 8.0 inval)) 17))))) ;;; -------- shift pitch keeping duration constant ;;; ;;; both src and granulate take a function argument to get input whenever it is needed. ;;; in this case, src calls granulate which reads the currently selected file. ;;; CLM version is in expsrc.ins (define expsrc (let ((documentation "(expsrc rate snd chn) uses sampling-rate conversion and granular synthesis to produce a sound at a new pitch but at the original tempo. It returns a function for map-channel.")) (lambda* (rate snd chn) (let* ((gr (make-granulate :expansion rate :input (make-sampler 0 snd chn))) (sr (make-src :srate rate :input (lambda (dir) (granulate gr))))) (lambda (inval) (src sr 0.0)))))) ;;; the next (expsnd) changes the tempo according to an envelope; the new duration ;;; will depend on the expansion envelope -- we integrate it to get ;;; the overall expansion, then use that to decide the new length. (define expsnd (let ((documentation "(expsnd gr-env snd chn) uses the granulate generator to change tempo according to an envelope: (expsnd '(0 .5 2 2.0))")) (lambda* (gr-env snd chn) (let* ((dur (/ (* (/ (framples snd chn) (srate snd)) (integrate-envelope gr-env)) ; in env.scm (envelope-last-x gr-env))) (gr (make-granulate :expansion (cadr gr-env) :jitter 0 :input (make-sampler 0 snd chn))) (ge (make-env gr-env :duration dur)) (sound-len (round (* (srate snd) dur))) (len (max sound-len (framples snd chn))) (out-data (make-float-vector len))) (do ((i 0 (+ i 1))) ((= i len)) (float-vector-set! out-data i (granulate gr)) (set! (mus-increment gr) (env ge))) (float-vector->channel out-data 0 len snd chn #f (format #f "expsnd '~A" gr-env)))))) ;;; -------- cross-synthesis ;;; ;;; CLM version is in clm.html (define cross-synthesis (let ((documentation "(cross-synthesis cross-snd amp fftsize r) does cross-synthesis between 'cross-snd' (a sound object) and the currently selected sound: (map-channel (cross-synthesis (integer->sound 0) .5 128 6.0))")) (lambda (cross-snd amp fftsize r) (let* ((freq-inc (/ fftsize 2)) (fdr #f) (fdi (make-float-vector fftsize)) (spectr (make-float-vector freq-inc)) (inctr 0) (ctr freq-inc) (radius (- 1.0 (/ r fftsize))) (bin (/ (srate) fftsize)) (formants (make-vector freq-inc)) (old-srate *clm-srate*)) (set! *clm-srate* (srate)) ;; if mus-srate is 44.1k and srate is 48k, make-formant thinks we're trying to go past srate/2 ;; and in any case it's setting its formants incorrectly for the actual output srate (do ((i 0 (+ i 1))) ((= i freq-inc)) (set! (formants i) (make-formant (* i bin) radius))) (set! formants (make-formant-bank formants spectr)) (set! *clm-srate* old-srate) (lambda (inval) (if (= ctr freq-inc) (begin (set! fdr (channel->float-vector inctr fftsize cross-snd 0)) (set! inctr (+ inctr freq-inc)) (spectrum fdr fdi #f 2) (float-vector-subtract! fdr spectr) (float-vector-scale! fdr (/ 1.0 freq-inc)) (set! ctr 0))) (set! ctr (+ ctr 1)) (float-vector-add! spectr fdr) (* amp (formant-bank formants inval))))))) ;;; similar ideas can be used for spectral cross-fades, etc -- for example: (define voiced->unvoiced (let ((documentation "(voiced->unvoiced amp fftsize r tempo snd chn) turns a vocal sound into whispering: (voiced->unvoiced 1.0 256 2.0 2.0)")) (lambda* (amp fftsize r tempo snd chn) (let* ((freq-inc (/ fftsize 2)) (fdr #f) (fdi (make-float-vector fftsize)) (spectr (make-float-vector freq-inc)) (noi (make-rand (/ (srate snd) 3))) (inctr 0) (ctr 0) (radius (- 1.0 (/ r fftsize))) (bin (/ (srate snd) fftsize)) (len (framples snd chn)) (outlen (floor (/ len tempo))) (hop (floor (* freq-inc tempo))) (out-data (make-float-vector (max len outlen))) (formants (make-vector freq-inc)) (old-peak-amp 0.0)) (do ((i 0 (+ i 1))) ((= i freq-inc)) (set! (formants i) (make-formant (* i bin) radius))) (set! formants (make-formant-bank formants spectr)) (do ((i 0 (+ i freq-inc))) ((>= i outlen)) (set! ctr (min (- outlen i) freq-inc)) (if (odd? ctr) (set! ctr (- ctr 1))) (set! fdr (channel->float-vector inctr fftsize snd chn)) (let ((pk (float-vector-peak fdr))) (if (> pk old-peak-amp) (set! old-peak-amp pk))) (spectrum fdr fdi #f 2) (float-vector-subtract! fdr spectr) (float-vector-scale! fdr (/ 2.0 freq-inc)) (set! inctr (+ inctr hop)) (do ((k 0 (+ k 2)) (j i (+ j 2))) ((= k ctr)) (float-vector-add! spectr fdr) (float-vector-set! out-data j (formant-bank formants (rand noi))) (float-vector-set! out-data (+ j 1) (formant-bank formants (rand noi))))) (float-vector-scale! out-data (* amp (/ old-peak-amp (float-vector-peak out-data)))) (float-vector->channel out-data 0 (max len outlen) snd chn))))) ;;; very similar but use ncos (glottal pulse train?) instead of white noise (define pulse-voice (let ((documentation "(pulse-voice cosines (freq 440) (amp 1.0) (fftsize 256) (r 2.0) snd chn) uses ncos to manipulate speech sounds")) (lambda* (cosines (freq 440.0) (amp 1.0) (fftsize 256) (r 2.0) snd chn) (let* ((freq-inc (/ fftsize 2)) (fdr #f) (fdi (make-float-vector fftsize)) (spectr (make-float-vector freq-inc)) (pulse (make-ncos freq cosines)) (inctr 0) (ctr 0) (radius (- 1.0 (/ r fftsize))) (bin (/ (srate snd) fftsize)) (len (framples snd chn)) (out-data (make-float-vector len)) (formants (make-vector freq-inc)) (old-peak-amp 0.0)) (do ((i 0 (+ i 1))) ((= i freq-inc)) (set! (formants i) (make-formant (* i bin) radius))) (set! formants (make-formant-bank formants spectr)) (do ((i 0 (+ i freq-inc))) ((>= i len)) (set! ctr (min (- len i) freq-inc)) (set! fdr (channel->float-vector inctr fftsize snd chn)) (let ((pk (float-vector-peak fdr))) (if (> pk old-peak-amp) (set! old-peak-amp pk))) (spectrum fdr fdi #f 2) (float-vector-subtract! fdr spectr) (float-vector-scale! fdr (/ 1.0 freq-inc)) (set! inctr (+ inctr freq-inc)) (do ((k 0 (+ k 1)) (j i (+ j 1))) ((= k ctr)) (float-vector-add! spectr fdr) (float-vector-set! out-data j (formant-bank formants (ncos pulse))))) (float-vector-scale! out-data (* amp (/ old-peak-amp (float-vector-peak out-data)))) (float-vector->channel out-data 0 len snd chn))))) ;;; (pulse-voice 80 20.0 1.0 1024 0.01) ;;; (pulse-voice 80 120.0 1.0 1024 0.2) ;;; (pulse-voice 30 240.0 1.0 1024 0.1) ;;; (pulse-voice 30 240.0 1.0 2048) ;;; (pulse-voice 6 1000.0 1.0 512) ;;; -------- convolution example (define cnvtest (let ((documentation "(cnvtest snd0 snd1 amp) convolves snd0 and snd1, scaling by amp, returns new max amp: (cnvtest 0 1 .1)")) (lambda (snd0 snd1 amp) (let* ((flt-len (framples snd0)) (total-len (+ flt-len (framples snd1))) (cnv (make-convolve :filter (channel->float-vector 0 flt-len snd0) :input (make-sampler 0 snd1))) (out-data (make-float-vector total-len))) (do ((i 0 (+ i 1))) ((= i total-len)) (float-vector-set! out-data i (convolve cnv))) (float-vector-scale! out-data amp) (let ((max-samp (float-vector-peak out-data))) (float-vector->channel out-data 0 total-len snd1) (if (> max-samp 1.0) (set! (y-bounds snd1) (list (- max-samp) max-samp))) max-samp))))) ;;; -------- locate-zero (Anders Vinjar) (define locate-zero (let ((documentation "(locate-zero limit) looks for successive samples that sum to less than 'limit', moving the cursor if successful")) (lambda (limit) (let* ((start (cursor)) (sf (make-sampler start))) (do ((n start (+ 1 n)) (val0 (abs (next-sample sf)) val1) (val1 (abs (next-sample sf)) (abs (next-sample sf)))) ((or (sampler-at-end? sf) (< (+ val0 val1) limit)) (set! (cursor) n) n)))))) ;;; -------- sound interp ;;; ;;; make-sound-interp sets up a sound reader that reads a channel at an arbitary location, ;;; interpolating between samples if necessary, the corresponding "generator" is sound-interp (define make-sound-interp (let ((documentation "(make-sound-interp start snd chn) -> an interpolating reader for snd's channel chn")) (lambda* (start snd chn) (let* ((data (channel->float-vector start #f snd chn)) (size (length data))) (lambda (loc) (array-interp data loc size)))))) (define sound-interp (let ((documentation "(sound-interp func loc) -> sample at loc (interpolated if necessary) from func created by make-sound-interp")) (lambda (func loc) ;make it look like a clm generator (func loc)))) #| (define test-interp (lambda (freq) ;; use a sine wave to lookup the current sound (let ((osc (make-oscil :frequency freq :initial-phase (+ pi (/ pi 2)))) (reader (make-sound-interp 0 0 0)) (len (- (framples 0 0) 1))) (map-channel (lambda (val) (sound-interp reader (* len (+ 0.5 (* 0.5 (oscil osc)))))))))) ;;; (test-interp 0.5) ;;; our FM index is len * 0.5 * (hz->radians freq) (define (sound-via-sound snd1 snd2) ; "sound composition"?? (let* ((intrp (make-sound-interp 0 snd1 0)) (len (- (framples snd1 0) 1)) (rd (make-sampler 0 snd2 0)) (mx (maxamp snd2 0))) (map-channel (lambda (val) (sound-interp intrp (floor (* len (* 0.5 (+ 1.0 (/ (read-sample rd) mx)))))))))) |# ;; env-sound-interp takes an envelope that goes between 0 and 1 (y-axis), and a time-scaler ;; (1.0 = original length) and returns a new version of the data in the specified channel ;; that follows that envelope (that is, when the envelope is 0 we get sample 0, when the ;; envelope is 1 we get the last sample, envelope = .5 we get the middle sample of the ;; sound and so on. (env-sound-interp '(0 0 1 1)) will return a copy of the ;; current sound; (env-sound-interp '(0 0 1 1 2 0) 2.0) will return a new sound ;; with the sound copied first in normal order, then reversed. src-sound with an ;; envelope could be used for this effect, but it is much more direct to apply the ;; envelope to sound sample positions. (define env-sound-interp (let ((documentation "(env-sound-interp env (time-scale 1.0) snd chn) reads snd's channel chn according to env and time-scale")) (lambda* (envelope (time-scale 1.0) snd chn) ;; since the old/new sounds can be any length, we'll write a temp file rather than trying to use map-channel (let* ((len (framples snd chn)) (newlen (floor (* time-scale len)))) (let ((new-snd (with-sound ((snd-tempnam) :to-snd #f :srate (srate snd)) (let ((data (channel->float-vector 0 #f snd chn)) (read-env (make-env envelope :length (+ 1 newlen) :scaler len))) (do ((i 0 (+ i 1))) ((= i newlen)) (outa i (array-interp data (env read-env) len))))))) (set-samples 0 newlen new-snd snd chn #t (format #f "env-sound-interp '~A ~A" envelope time-scale) 0 current-edit-position #t)))))) ;;; (env-sound-interp '(0 0 1 1 2 0) 2.0) ;;; here's a very similar function that uses granular synthesis to move at a varying tempo through a sound (define granulated-sound-interp (let ((documentation "(granulated-sound-interp envelope (time-scale 1.0) (grain-length 0.10) (grain-envelope '(0 0 1 1 2 1 3 0)) (output-hop 0.05) snd chn) reads \ the given channel following 'envelope' (as in env-sound-interp), using grains to create the re-tempo'd read")) (lambda* (envelope (time-scale 1.0) (grain-length 0.10) (grain-envelope '(0 0 1 1 2 1 3 0)) (output-hop 0.05) snd chn) (let* ((len (framples snd chn)) (newlen (floor (* time-scale len)))) (let ((read-env (make-env envelope :length newlen :scaler len)) (grain-frames (round (* grain-length (srate snd)))) (hop-frames (round (* output-hop (srate snd)))) (num-readers (ceiling (/ grain-length output-hop))) (cur-readers 0) (next-reader 0) (jitter (* (srate snd) .005))) (let ((readers (make-vector num-readers #f)) (grain-envs (make-vector num-readers #f))) (do ((i 0 (+ i 1))) ((= i num-readers)) (set! (grain-envs i) (make-env grain-envelope :length grain-frames))) (let ((new-snd (with-sound ((snd-tempnam) :to-snd #f :srate (srate snd)) (do ((i 0 (+ i hop-frames))) ((>= i newlen)) (let ((start i) (stop (min newlen (+ i hop-frames))) (e #f) (r #t)) (set! (mus-location read-env) i) (let ((position-in-original (env read-env))) (set! (readers next-reader) (make-sampler (max 0 (round (+ position-in-original (mus-random jitter)))) snd chn)) (mus-reset (grain-envs next-reader)) ; restart grain env (set! next-reader (modulo (+ next-reader 1) num-readers)) (if (< cur-readers next-reader) (set! cur-readers next-reader))) (do ((k 0 (+ k 1))) ((= k cur-readers)) (set! e (grain-envs k)) (set! r (readers k)) (do ((j start (+ j 1))) ((= j stop)) (outa j (* (env e) (next-sample r)))))))))) (set-samples 0 newlen new-snd snd chn #t (format #f "granulated-sound-interp '~A ~A ~A ~A ~A" envelope time-scale grain-length grain-envelope output-hop) 0 current-edit-position #t)))))))) ;;; (granulated-sound-interp '(0 0 1 .1 2 1) 1.0 0.2 '(0 0 1 1 2 0)) ;;; (granulated-sound-interp '(0 0 1 1) 2.0) ;;; (granulated-sound-interp '(0 0 1 .1 2 1) 1.0 0.2 '(0 0 1 1 2 0) 0.02) ;;; -------- filtered-env (define filtered-env (let ((documentation "(filtered-env env snd chn) is a time-varying one-pole filter: when env is at 1.0, no filtering, as env moves to 0.0, low-pass gets more intense; amplitude and low-pass amount move together")) (lambda* (e snd chn) (let* ((samps (framples)) (flt (make-one-pole 1.0 0.0)) (xc (mus-xcoeffs flt)) (yc (mus-ycoeffs flt)) (amp-env (make-env e :length samps))) (map-channel (lambda (val) (let ((env-val (env amp-env))) (float-vector-set! xc 0 env-val) (float-vector-set! yc 1 (- env-val 1.0)) (one-pole flt (* env-val val)))) 0 #f snd chn #f (format #f "filtered-env '~A" e)))))) ;;; -------- multi-colored rxvt printout ;;; ;;; if you're using display to write to rxvt, you can use the latter's escape sequences ;;; for things like multi-colored text: #| (define red-text (format #f "~C[31m" #\escape)) (define normal-text (format #f "~C[0m" #\escape)) ;;; there are a bunch of these: (define black-on-red-text (format #f "~C[30m~C[41m" #\escape #\escape)) ;;; or perhaps more convenient: (define black-fg (format #f "~C[30m" #\escape)) (define black-bg (format #f "~C[40m" #\escape)) (define red-fg (format #f "~C[31m" #\escape)) (define red-bg (format #f "~C[41m" #\escape)) (define green-fg (format #f "~C[32m" #\escape)) (define green-bg (format #f "~C[42m" #\escape)) (define yellow-fg (format #f "~C[33m" #\escape)) (define yellow-bg (format #f "~C[43m" #\escape)) (define blue-fg (format #f "~C[34m" #\escape)) (define blue-bg (format #f "~C[44m" #\escape)) ;;; etc (magenta: 35 cyan: 36 white: 37 default: 39) (define bold-text (format #f "~C[1m" #\escape)) (define unbold-text (format #f "~C[22m" #\escape)) (define underline-text (format #f "~C[4m" #\escape)) (define ununderline-text (format #f "~C[24m" #\escape)) (define blink-text (format #f "~C[5m" #\escape)) (define unblink-text (format #f "~C[25m" #\escape)) |# ;;; -------- remove-clicks (define find-click (let ((documentation "(find-click loc) finds the next click starting at 'loc'")) (lambda (loc) (let ((reader (make-sampler loc)) (mmax (make-moving-max 10)) (samp0 0.0) (samp1 0.0) (samp2 0.0) (len (framples))) (call-with-exit (lambda (return) (do ((ctr loc (+ ctr 1))) ((= ctr len) #f) (set! samp0 samp1) (set! samp1 samp2) (set! samp2 (next-sample reader)) (let ((local-max (max .1 (moving-max mmax samp0)))) (if (and (> (abs (- samp0 samp1)) local-max) (> (abs (- samp1 samp2)) local-max) (< (abs (- samp0 samp2)) (/ local-max 2))) (return (- ctr 1))))))))))) (define remove-clicks (let ((documentation "(remove-clicks) tries to find and smooth-over clicks")) (lambda () ;; this is very conservative -- the click detection limits above could be set much tighter in many cases (define (remove-click loc) (let ((click (find-click loc))) (if click (begin (smooth-sound (- click 2) 4) (remove-click (+ click 2)))))) (remove-click 0)))) ;;; -------- searching examples (zero+, next-peak) (define search-for-click (let ((documentation "(search-for-click) looks for the next click (use with C-s)")) (lambda () (let ((samp0 0.0) (samp1 0.0) (samp2 0.0) (mmax (make-moving-max 10))) (lambda (val) (set! samp0 samp1) (set! samp1 samp2) (set! samp2 val) (let ((local-max (max .1 (moving-max mmax samp0)))) (and (>= (abs (- samp0 samp1)) local-max) (>= (abs (- samp1 samp2)) local-max) (<= (abs (- samp0 samp2)) (/ local-max 2))))))))) (define zero+ (let ((documentation "(zero+) finds the next positive-going zero crossing (if searching forward) (for use with C-s)")) (lambda () (let ((lastn 0.0)) (lambda (n) (let ((rtn (and (< lastn 0.0) (>= n 0.0)))) (set! lastn n) rtn)))))) (define next-peak (let ((documentation "(next-peak) finds the next max or min point in the time-domain waveform (for use with C-s)")) (lambda () (let ((last0 #f) (last1 #f)) (lambda (n) (let ((rtn (and (number? last0) (or (and (< last0 last1) (> last1 n)) (and (> last0 last1) (< last1 n)))))) (set! last0 last1) (set! last1 n) rtn)))))) (define find-pitch (let ((documentation "(find-pitch pitch) finds the point in the current sound where 'pitch' (in Hz) predominates -- C-s (find-pitch 300) In most cases, this will be slightly offset from the true beginning of the note")) (lambda (pitch) (define (interpolated-peak-offset la pk ra) (let ((logla (log (/ (max la .0000001) pk) 10)) (logra (log (/ (max ra .0000001) pk) 10))) (/ (* 0.5 (- logla logra)) (+ logla logra)))) (let ((data (make-float-vector *transform-size*)) (data-loc 0)) (lambda (n) (set! (data data-loc) n) (set! data-loc (+ data-loc 1)) (let ((rtn #f)) (if (= data-loc *transform-size*) (begin (set! data-loc 0) (if (> (float-vector-peak data) .001) ;ignore noise sections?? (let ((spectr (snd-spectrum data rectangular-window *transform-size*)) (pk 0.0) (pkloc 0)) (let ((pit (do ((i 0 (+ i 1))) ((= i (/ *transform-size* 2)) (if (or (= pk 0.0) (= pkloc 0)) 0.0 (/ (* (+ pkloc (interpolated-peak-offset (spectr (- pkloc 1)) pk (spectr (+ 1 pkloc)))) (srate)) *transform-size*))) (if (> (spectr i) pk) (begin (set! pk (spectr i)) (set! pkloc i)))))) (if (< (abs (- pitch pit)) (/ (srate) (* 2 *transform-size*))) ; uh... why not do it direct? (set! rtn #t))))) (fill! data 0.0))) rtn)))))) ;;; -------- file->floats and a sort of cue-list, I think (define (file->floats file) (samples 0 (framples file) file)) (define add-notes (let ((documentation "(add-notes notes snd chn) adds (mixes) 'notes' which is a list of lists of the form: file (offset 0.0) (amp 1.0) starting at the cursor in the currently selected channel: (add-notes '((\"oboe.snd\") (\"pistol.snd\" 1.0 2.0)))")) (lambda* (notes snd chn) (let ((start (cursor snd chn))) (as-one-edit (lambda () (for-each (lambda (note) (let* ((file (car note)) (offset (if (> (length note) 1) (cadr note) 0.0)) (amp (and (> (length note) 2) (caddr note))) (beg (+ start (floor (* (srate snd) offset))))) (if (and (number? amp) (not (= amp 1.0))) (mix-float-vector (float-vector-scale! (file->floats file) amp) beg snd chn #f "add-notes") (mix file beg 0 snd chn #f)))) notes)) (format #f "add-notes '~S" notes)))))) (define region-play-list (let ((documentation "(region-play-list data): 'data' is list of lists (list (list reg time)...), time in secs, setting up a sort of play list: (region-play-list (list (list reg0 0.0) (list reg1 0.5) (list reg2 1.0) (list reg0 1.0)))")) (lambda (data) (for-each (lambda (tone) (let ((time (floor (* 1000 (cadr tone)))) (region (car tone))) (if (region? region) (in time (lambda () (play region)))))) data)))) (define region-play-sequence (let ((documentation "(region-play-sequence data): 'data' is list of regions which will be played one after the other: (region-play-sequence (list reg0 reg2 reg1))")) (lambda (data) (region-play-list (let ((time 0.0)) (map (lambda (id) (let ((cur time)) (set! time (+ time (/ (framples id) (srate id)))) (list cur id))) data)))))) ;;; -------- explode-sf2 (define explode-sf2 (let ((documentation "(explode-sf2) turns the currently selected soundfont file into a bunch of files of the form sample-name.aif")) (lambda () (letrec ((sf2it (lambda (lst) (if (pair? lst) (let* ((vals (car lst)) ;; each inner list is: '(name start loop-start loop-end) (name (car vals)) (start (cadr vals)) (end (if (null? (cdr lst)) (framples) (cadadr lst))) (loop-start (- (caddr vals) start)) (loop-end (- (cadddr vals) start)) (filename (string-append name ".aif"))) (if (selection?) (set! (selection-member? #t) #f)) ; clear entire current selection, if any (set! (selection-member?) #t) (set! (selection-position) start) (set! (selection-framples) (- end start)) (save-selection filename (selection-srate) mus-bshort mus-aifc) (let ((temp (open-sound filename))) (set! (sound-loop-info temp) (list loop-start loop-end)) (close-sound temp)) (sf2it (cdr lst))))))) (sf2it (soundfont-info)))))) ;;; -------- open-next-file-in-directory (define open-next-file-in-directory (let ((last-file-opened #f) (current-directory #f) (current-sorted-files #f)) (define (file-from-path curfile) (let ((last-slash 0)) (do ((i 0 (+ i 1))) ((= i (length curfile))) (if (char=? (curfile i) #\/) (set! last-slash i))) (substring curfile (+ 1 last-slash)))) (define (directory-from-path curfile) (let ((last-slash 0)) (do ((i 0 (+ i 1))) ((= i (length curfile))) (if (char=? (curfile i) #\/) (set! last-slash i))) (substring curfile 0 last-slash))) (define (find-next-file) ;; find the next file in the sorted list, with wrap-around (let ((choose-next (not (string? last-file-opened))) (just-filename (file-from-path last-file-opened))) (call-with-exit (lambda (return) (for-each (lambda (file) (if choose-next (return file) (if (string=? file just-filename) (set! choose-next #t)))) current-sorted-files) ;; if we get here we wrapped around (car current-sorted-files))))) (define (get-current-files dir) (set! current-directory dir) (set! current-sorted-files (sort! (copy (sound-files-in-directory dir)) stringin (or last first) ;; we take this list and create and evaluate a new function (let ((dsp-chain (apply vector (reverse (map (lambda (gen) (if (pair? gen) (make-env gen :duration dur) gen)) dsps)))) (start (seconds->samples beg)) (samps (seconds->samples dur)) (body 0.0) (closure ())) (let ((end (+ start samps)) (len (length dsp-chain))) ;; create the let variable list and lambda body of our new function (do ((i 0 (+ i 1))) ((= i len)) (let ((g (dsp-chain i)) (gname (string->symbol (format #f "g~D" i)))) (set! closure (cons `(,gname (dsp-chain ,i)) closure)) (if (env? g) (set! body (if (eqv? body 0.0) `(env ,gname) `(* (env ,gname) ,body))) (if (readin? g) (set! body (if (eqv? body 0.0) `(readin ,gname) `(+ ,body (readin ,gname)))) (if (mus-generator? g) (set! body (if (eqv? body 0.0) (list (string->symbol (mus-name g)) gname) (list (string->symbol (mus-name g)) gname body))) (set! body (list gname body))))))) ;; now patch the two together (the apply let below) and evaluate the resultant thunk (apply define (list 'inner) `((let ,closure (do ((k ,start (+ k 1))) ((= k ,end)) (outa k ,body))))) (inner)))))) #| (with-sound () (chain-dsps 0 1.0 '(0 0 1 .5 2 0) (make-oscil 440)) (chain-dsps 1 1.0 '(0 0 1 4 2 0) (make-one-zero .5) (make-readin "oboe.snd")) (chain-dsps 2 1.0 '(0 0 1 .5 2 0) (let ((osc1 (make-oscil 220)) (osc2 (make-oscil 440))) (lambda (val) (+ (osc1 val) (osc2 (* 2 val))))))) |# ;;; amplitude-modulate-channel could be (lambda (y data forward) (* y 0.5 (+ 1.0 (sin angle))) etc ...) ;;; -------- re-order channels (define scramble-channels (let ((documentation "scramble-channels can arbitrarily re-order a sound's channels. The new channel order is \ passed as the arguments so to end with channel 3 in channel 0, 2 in 1, 0 in 2, and 1 in 3, (scramble-channels 3 2 0 1)")) (lambda new-order (define (find-chan chans chan len) (let ((pos #f)) (do ((i 0 (+ i 1))) ((or pos (= i len)) pos) (if (= (chans i) chan) (set! pos i))))) (define (scramble-channels-1 cur-chans end-chans chans loc) (if (> chans loc) (let* ((end-chan (end-chans loc)) ; we want this channel at loc (cur-chan (cur-chans loc)) ; this (original) channel is currently at loc (end-loc (find-chan cur-chans end-chan chans))) ; where is end-chan currently? ;; end-chan goes in cur-chan's slot (if (not (= cur-chan end-chan)) (begin (swap-channels #f end-loc #f loc) (set! (cur-chans end-loc) cur-chan) (set! (cur-chans loc) end-chan))) (scramble-channels-1 cur-chans end-chans chans (+ 1 loc))))) (let ((len (length new-order))) (if (> len 1) (let ((end-chans (apply vector new-order)) (cur-chans (make-vector len))) (do ((i 0 (+ i 1))) ((= i len)) (set! (cur-chans i) i)) (scramble-channels-1 cur-chans end-chans len 0))))))) (define (scramble-channel silence-1) ;; (scramble-channel .01) (let ((buffer (make-moving-average 128)) (silence (/ silence-1 128)) (edges ()) (in-silence #t) (old-max *max-regions*) (old-tags *with-mix-tags*)) (dynamic-wind (lambda () (set! *max-regions* 1024) (set! *with-mix-tags* #f)) (lambda () (let ((len (framples)) (reader (make-sampler))) (do ((i 0 (+ i 1))) ((= i len)) (let ((y (next-sample reader))) (let* ((sum-of-squares (moving-average buffer (* y y))) (now-silent (< sum-of-squares silence))) (if (not (eq? in-silence now-silent)) (set! edges (cons i edges))) (set! in-silence now-silent))))) (set! edges (append (reverse edges) (list (framples)))) (let* ((len (length edges)) (pieces (make-vector len #f)) (start 0) (ctr 0)) (for-each (lambda (end) (set! (pieces ctr) (make-region start end)) (set! ctr (+ ctr 1)) (set! start end)) edges) (set! start 0) (as-one-edit (lambda() (scale-by 0.0) (do ((i 0 (+ i 1))) ((= i len)) (let* ((this (random len)) (reg (pieces this))) (set! (pieces this) #f) (if (not reg) (begin (do ((j (+ 1 this) (+ j 1))) ((or (= j len) reg)) (set! reg (pieces j)) (if reg (set! (pieces j) #f))) (if (not reg) (do ((j (- this 1) (- j 1))) ((or (< j 0) reg)) (set! reg (pieces j)) (if reg (set! (pieces j) #f)))))) (mix-region reg start) (set! start (+ start (framples reg))) (forget-region reg))))))) (lambda () (set! *with-mix-tags* old-tags) (set! *max-regions* old-max))))) ;; -------- reorder blocks within channel (define reverse-by-blocks (let ((documentation "(reverse-by-blocks block-len snd chn): divide sound into block-len blocks, recombine blocks in reverse order")) (lambda* (block-len snd chn) (let* ((len (framples snd chn)) (num-blocks (floor (/ len (* (srate snd) block-len))))) (if (> num-blocks 1) (let* ((actual-block-len (ceiling (/ len num-blocks))) (rd (make-sampler (- len actual-block-len) snd chn)) (beg 0) (ctr 1)) (map-channel (lambda (y) (let ((val (read-sample rd))) (if (< beg 10) ; ramp start and end to avoid clicks (might want to mix with next section) (set! val (* val beg .1)) (if (> beg (- actual-block-len 10)) (set! val (* val (- actual-block-len beg) .1)))) (set! beg (+ beg 1)) (if (= beg actual-block-len) (begin (set! ctr (+ ctr 1)) (set! beg 0) (set! rd (make-sampler (max 0 (- len (* ctr actual-block-len))) snd chn)))) val)) 0 #f snd chn #f (format #f "reverse-by-blocks ~A" block-len)))))))) (define reverse-within-blocks (let ((documentation "(reverse-within-blocks block-len snd chn): divide sound into blocks, recombine in order, but each block internally reversed")) (lambda* (block-len snd chn) (let* ((len (framples snd chn)) (num-blocks (floor (/ len (* (srate snd) block-len))))) (if (> num-blocks 1) (let ((actual-block-len (ceiling (/ len num-blocks))) (no-clicks-env (list 0.0 0.0 .01 1.0 .99 1.0 1.0 0.0))) (as-one-edit (lambda () (do ((beg 0 (+ beg actual-block-len))) ((>= beg len)) (reverse-channel beg actual-block-len snd chn) (env-channel no-clicks-env beg actual-block-len snd chn))) (format #f "reverse-within-blocks ~A" block-len))) (reverse-channel 0 #f snd chn)))))) ;;; -------- channel-clipped? #| (define channel-clipped? (let ((documentation "(channel-clipped? snd chn) returns the sample number if it finds clipping")) (lambda* (snd chn) (let ((last-y 0.0) (len (framples snd chn)) (reader (make-sampler 0 snd chn))) (call-with-exit (lambda (quit) (do ((i 0 (+ i 1))) ((= i len) #f) (let ((y (next-sample reader))) (if (and (>= (abs y) 0.9999) (>= (abs last-y) 0.9999)) (quit i) (set! last-y y)))))))))) |# ;;; not pretty but faster: (define channel-clipped? (let ((documentation "(channel-clipped? snd chn) returns the sample number if it finds clipping")) (lambda* (snd chn) (do ((pos (scan-channel (lambda (y) (>= (abs y) 0.9999)) 0 #f snd chn) (scan-channel (lambda (y) (>= (abs y) 0.9999)) (+ pos 1) #f snd chn))) ((or (not pos) (>= (abs (sample (+ pos 1) snd chn)) 0.9999)) pos))))) ; or (and pos (+ pos 1)) to mimic the old version ;;; -------- sync-everything (define sync-everything (let ((documentation "(sync-everything) sets the sync fields of all currently open sounds to the same, unique value")) (lambda () (let ((new-sync (+ 1 (sync-max)))) (for-each (lambda (snd) (set! (sync snd) new-sync)) (sounds)))))) snd-16.1/fmv.scm0000644000076400007640000001611512616231602011632 0ustar bilbil;;; fm-violin as a generator (and at end, original instrument using this generator) ;;; ;;; make-fm-violin takes the same args as the instrument version with the following changes ;;; beg and dur are omitted, also degree, reverb-amount, distance ;;; all envelopes default to constants (rather than envelopes) ;;; from the generator's point of view, each envelope is a function called at run time to get its next value, ;;; very much like "as-needed" input in src or granulate, so the envelopes could actually be any ;;; arbitrary function you like (see examples at end). ;;; returns a violin function ;;; fm-violin takes the value returned by make-fm-violin and returns a new sample each time it is called (provide 'snd-fmv.scm) (define make-fm-violin (let ((documentation "(make-fm-violin frequency amplitude (fm-index 1.0) (amp-env #f) (periodic-vibrato-rate 5.0) (random-vibrato-rate 16.0) (periodic-vibrato-amplitude 0.0025) (random-vibrato-amplitude 0.005) (noise-amount 0.0) (noise-freq 1000.0) (ind-noise-freq 10.0) (ind-noise-amount 0.0) (amp-noise-freq 20.0) (amp-noise-amount 0.0) (gliss-env #f) (fm1-env #f) (fm2-env #f) (fm3-env #f) (fm1-rat 1.0) (fm2-rat 3.0) (fm3-rat 4.0) (fm1-index #f) (fm2-index #f) (fm3-index #f) (base 1.0)) makes a new fm-violin generator. It is the same as the v.scm version, but does not assume it is running within with-sound. In terms of arguments beg, dur, degree, reverb-amount, and distance are omitted, and all envelopes default to constants (rather than envelopes). From the generator's point of view, each envelope is a function called at run time to get its next value, very much like 'as-needed' input in src or granulate. fm-violin takes the value returned by make-fm-violin and returns a new sample each time it is called: (define (test-v beg dur freq amp) (let ((v (make-fm-violin freq amp :amp-env (let ((e (make-env :envelope '(0 0 1 1 2 0) :scaler amp :length dur))) (lambda () (env e))))) (data (channel->float-vector beg dur))) (do ((i 0 (+ 1 i))) ((= i dur)) (set! (data i) (+ (data i) (v)))) (float-vector->channel data beg dur))))")) (lambda* (frequency amplitude (fm-index 1.0) amp-env (periodic-vibrato-rate 5.0) (random-vibrato-rate 16.0) (periodic-vibrato-amplitude 0.0025) (random-vibrato-amplitude 0.005) (noise-amount 0.0) (noise-freq 1000.0) (ind-noise-freq 10.0) (ind-noise-amount 0.0) (amp-noise-freq 20.0) (amp-noise-amount 0.0) gliss-env fm1-env fm2-env fm3-env (fm1-rat 1.0) (fm2-rat 3.0) (fm3-rat 4.0) fm1-index fm2-index fm3-index (base 1.0)) (let* ((frq-scl (hz->radians frequency)) (modulate (not (zero? fm-index))) (maxdev (* frq-scl fm-index)) (logfreq (log frequency)) (index1 (or fm1-index (min pi (* maxdev (/ 5.0 logfreq))))) (index2 (or fm2-index (min pi (* maxdev 3.0 (/ (- 8.5 logfreq) (+ 3.0 (* frequency .001))))))) (index3 (or fm3-index (min pi (* maxdev (/ 4.0 (sqrt frequency)))))) (easy-case (and (zero? noise-amount) (or (not fm2-env) (equal? fm1-env fm2-env)) (or (not fm3-env) (equal? fm1-env fm3-env)) (= fm1-rat (floor fm1-rat)) (= fm2-rat (floor fm2-rat)) (= fm3-rat (floor fm3-rat)))) (carrier (make-oscil frequency)) (fmosc1 (and modulate (make-oscil (* fm1-rat frequency)))) (fmosc2 (and modulate (or easy-case (make-oscil (* fm2-rat frequency))))) (fmosc3 (and modulate (or easy-case (make-oscil (* fm3-rat frequency))))) (coeffs (and easy-case modulate (partials->polynomial (list fm1-rat index1 (floor (/ fm2-rat fm1-rat)) index2 (floor (/ fm3-rat fm1-rat)) index3)))) (ampf (or amp-env (lambda () amplitude))) (indf1 (or fm1-env (lambda () (or (and easy-case modulate 1.0) index1)))) (indf2 (or fm2-env (lambda () index2))) (indf3 (or fm3-env (lambda () index3))) (pervib (make-triangle-wave periodic-vibrato-rate (* periodic-vibrato-amplitude frq-scl))) (ranvib (make-rand-interp random-vibrato-rate (* random-vibrato-amplitude frq-scl))) (fm-noi (and (not (= 0.0 noise-amount)) (make-rand noise-freq (* pi noise-amount)))) (amp-noi (and (not (= 0.0 amp-noise-amount)) (not (= 0.0 amp-noise-freq)) (make-rand-interp amp-noise-freq amp-noise-amount))) (ind-noi (and (not (= 0.0 ind-noise-amount)) (not (= 0.0 ind-noise-freq)) (make-rand-interp ind-noise-freq ind-noise-amount))) (frqf (or gliss-env (lambda () 0.0)))) (lambda () (let ((vib (+ (frqf) (triangle-wave pervib) (rand-interp ranvib))) (fuzz (if fm-noi (rand fm-noi) 0.0))) (* (ampf) (if amp-noi (+ 1.0 (rand-interp amp-noi)) 1.0) (oscil carrier (+ vib (* (if ind-noi (+ 1.0 (rand-interp ind-noi)) 1.0) (if fmosc1 (if coeffs (* (indf1) (polynomial coeffs (oscil fmosc1 vib))) (+ (* (indf1) (oscil fmosc1 (+ (* fm1-rat vib) fuzz))) (* (indf2) (oscil fmosc2 (+ (* fm2-rat vib) fuzz))) (* (indf3) (oscil fmosc3 (+ (* fm3-rat vib) fuzz))))) 0.0))))))))))) #| (define test-v (lambda (beg dur freq amp amp-env) (let ((v (make-fm-violin freq amp :amp-env (let ((e (make-env :envelope (or amp-env '(0 0 1 1 2 0)) :scaler amp :length dur))) (lambda () (env e))))) (data (channel->float-vector beg dur))) (do ((i 0 (+ 1 i))) ((= i dur)) (set! (data i) (+ (data i) (v)))) (float-vector->channel data beg dur)))) ;;; (with-sound () (test-v 0 10000 440 .1 '(0 0 1 1 2 0))) (define test-v1 ;; use oscil as index envelope (lambda (beg dur freq amp amp-env) (let ((v (make-fm-violin freq amp :amp-env (let ((e (make-env :envelope (or amp-env '(0 0 1 1 2 0)) :scaler amp :length dur))) (lambda () (env e))) :fm1-env (let ((osc (make-oscil 100.0))) (lambda () (oscil osc))))) (data (channel->float-vector beg dur))) (do ((i 0 (+ 1 i))) ((= i dur)) (set! (data i) (+ (data i) (v)))) (float-vector->channel data beg dur)))) |# (define fm-violin-ins (let ((documentation "(fm-violin-ins startime dur freq amp degree (reverb-amount 0.0) (distance 1.0) :rest args) calls the fm-violin with the given args and mixes the results into the current sound")) (lambda* (startime dur freq amp degree (reverb-amount 0.0) (distance 1.0) :rest args) (let* ((beg (floor (* startime (srate)))) (len (floor (* dur (srate)))) (loc (make-locsig :channels (channels) :degree (or degree (random 90.0)) :reverb reverb-amount :distance distance)) (out-data (make-float-vector len)) (v (apply make-fm-violin freq amp args))) (do ((i 0 (+ 1 i))) ((= i len)) (set! (out-data i) (v))) (if (= (channels) 2) (let ((bsamps (copy out-data))) (mix-float-vector (float-vector-scale! bsamps (locsig-ref loc 1)) beg #f 1 #f) (mix-float-vector (float-vector-scale! out-data (locsig-ref loc 0)) beg #f 0 #f)) (mix-float-vector out-data beg #f 0 #f)))))) snd-16.1/rgb.rb0000644000076400007640000006452312306421672011447 0ustar bilbil# rgb.rb -- Guile -> Ruby translation # Translator/Author: Michael Scholz # Created: Sun Mar 09 03:51:38 CET 2003 # Changed: Wed Nov 25 01:25:31 CET 2009 # X11 color names converted to Snd (Ruby) colors # tan -> tawny 24-Aug-01 # rgb.scm Snow = make_color(1.00, 0.98, 0.98) Ghost_white = make_color(0.97, 0.97, 1.00) White_smoke = make_color(0.96, 0.96, 0.96) Gainsboro = make_color(0.86, 0.86, 0.86) Floral_white = make_color(1.00, 0.98, 0.94) Old_lace = make_color(0.99, 0.96, 0.90) Linen = make_color(0.98, 0.94, 0.90) Antique_white = make_color(0.98, 0.92, 0.84) Papaya_whip = make_color(1.00, 0.93, 0.83) Blanched_almond = make_color(1.00, 0.92, 0.80) Bisque = make_color(1.00, 0.89, 0.77) Peach_puff = make_color(1.00, 0.85, 0.72) Navajo_white = make_color(1.00, 0.87, 0.68) Moccasin = make_color(1.00, 0.89, 0.71) Cornsilk = make_color(1.00, 0.97, 0.86) Ivory = make_color(1.00, 1.00, 0.94) Lemon_chiffon = make_color(1.00, 0.98, 0.80) Seashell = make_color(1.00, 0.96, 0.93) Honeydew = make_color(0.94, 1.00, 0.94) Mint_cream = make_color(0.96, 1.00, 0.98) Azure = make_color(0.94, 1.00, 1.00) Alice_blue = make_color(0.94, 0.97, 1.00) Lavender = make_color(0.90, 0.90, 0.98) Lavender_blush = make_color(1.00, 0.94, 0.96) Misty_rose = make_color(1.00, 0.89, 0.88) White = make_color(1.00, 1.00, 1.00) Black = make_color(0.00, 0.00, 0.00) Dark_slate_gray = make_color(0.18, 0.31, 0.31) Dark_slate_grey = make_color(0.18, 0.31, 0.31) Dim_gray = make_color(0.41, 0.41, 0.41) Dim_grey = make_color(0.41, 0.41, 0.41) Slate_gray = make_color(0.44, 0.50, 0.56) Slate_grey = make_color(0.44, 0.50, 0.56) Light_slate_gray = make_color(0.46, 0.53, 0.60) Light_slate_grey = make_color(0.46, 0.53, 0.60) Gray = make_color(0.74, 0.74, 0.74) Grey = make_color(0.74, 0.74, 0.74) Light_grey = make_color(0.82, 0.82, 0.82) Light_gray = make_color(0.82, 0.82, 0.82) Midnight_blue = make_color(0.10, 0.10, 0.44) Navy = make_color(0.00, 0.00, 0.50) Navy_blue = make_color(0.00, 0.00, 0.50) Cornflower_blue = make_color(0.39, 0.58, 0.93) Dark_slate_blue = make_color(0.28, 0.24, 0.54) Slate_blue = make_color(0.41, 0.35, 0.80) Medium_slate_blue = make_color(0.48, 0.41, 0.93) Light_slate_blue = make_color(0.52, 0.44, 1.00) Medium_blue = make_color(0.00, 0.00, 0.80) Royal_blue = make_color(0.25, 0.41, 0.88) Blue = make_color(0.00, 0.00, 1.00) Dodger_blue = make_color(0.12, 0.56, 1.00) Deep_sky_blue = make_color(0.00, 0.75, 1.00) Sky_blue = make_color(0.53, 0.80, 0.92) Light_sky_blue = make_color(0.53, 0.80, 0.98) Steel_blue = make_color(0.27, 0.51, 0.70) Light_steel_blue = make_color(0.69, 0.77, 0.87) Light_blue = make_color(0.68, 0.84, 0.90) Powder_blue = make_color(0.69, 0.87, 0.90) Pale_turquoise = make_color(0.68, 0.93, 0.93) Dark_turquoise = make_color(0.00, 0.80, 0.82) Medium_turquoise = make_color(0.28, 0.82, 0.80) Turquoise = make_color(0.25, 0.87, 0.81) Cyan = make_color(0.00, 1.00, 1.00) Light_cyan = make_color(0.87, 1.00, 1.00) Cadet_blue = make_color(0.37, 0.62, 0.62) Medium_aquamarine = make_color(0.40, 0.80, 0.66) Aquamarine = make_color(0.50, 1.00, 0.83) Dark_green = make_color(0.00, 0.39, 0.00) Dark_olive_green = make_color(0.33, 0.42, 0.18) Dark_sea_green = make_color(0.56, 0.73, 0.56) Sea_green = make_color(0.18, 0.54, 0.34) Medium_sea_green = make_color(0.23, 0.70, 0.44) Light_sea_green = make_color(0.12, 0.70, 0.66) Pale_green = make_color(0.59, 0.98, 0.59) Spring_green = make_color(0.00, 1.00, 0.50) Lawn_green = make_color(0.48, 0.98, 0.00) Green = make_color(0.00, 1.00, 0.00) Chartreuse = make_color(0.50, 1.00, 0.00) Medium_spring_green = make_color(0.00, 0.98, 0.60) Green_yellow = make_color(0.68, 1.00, 0.18) Lime_green = make_color(0.20, 0.80, 0.20) Yellow_green = make_color(0.60, 0.80, 0.20) Forest_green = make_color(0.13, 0.54, 0.13) Olive_drab = make_color(0.42, 0.55, 0.14) Dark_khaki = make_color(0.74, 0.71, 0.42) Khaki = make_color(0.94, 0.90, 0.55) Pale_goldenrod = make_color(0.93, 0.91, 0.66) Light_goldenrod_yellow = make_color(0.98, 0.98, 0.82) Light_yellow = make_color(1.00, 1.00, 0.87) Yellow = make_color(1.00, 1.00, 0.00) Gold = make_color(1.00, 0.84, 0.00) Light_goldenrod = make_color(0.93, 0.86, 0.51) Goldenrod = make_color(0.85, 0.64, 0.12) Dark_goldenrod = make_color(0.72, 0.52, 0.04) Rosy_brown = make_color(0.73, 0.56, 0.56) Indian_red = make_color(0.80, 0.36, 0.36) Saddle_brown = make_color(0.54, 0.27, 0.07) Sienna = make_color(0.62, 0.32, 0.18) Peru = make_color(0.80, 0.52, 0.25) Burlywood = make_color(0.87, 0.72, 0.53) Beige = make_color(0.96, 0.96, 0.86) Wheat = make_color(0.96, 0.87, 0.70) Sandy_brown = make_color(0.95, 0.64, 0.37) # tan collides with Scheme built-in -- tawny suggested by Dave Phillips Tawny = make_color(0.82, 0.70, 0.55) Chocolate = make_color(0.82, 0.41, 0.12) Firebrick = make_color(0.70, 0.13, 0.13) Brown = make_color(0.64, 0.16, 0.16) Dark_salmon = make_color(0.91, 0.59, 0.48) Salmon = make_color(0.98, 0.50, 0.45) Light_salmon = make_color(1.00, 0.62, 0.48) Orange = make_color(1.00, 0.64, 0.00) Dark_orange = make_color(1.00, 0.55, 0.00) Coral = make_color(1.00, 0.50, 0.31) Light_coral = make_color(0.94, 0.50, 0.50) Tomato = make_color(1.00, 0.39, 0.28) Orange_red = make_color(1.00, 0.27, 0.00) Red = make_color(1.00, 0.00, 0.00) Hot_pink = make_color(1.00, 0.41, 0.70) Deep_pink = make_color(1.00, 0.08, 0.57) Pink = make_color(1.00, 0.75, 0.79) Light_pink = make_color(1.00, 0.71, 0.75) Pale_violet_red = make_color(0.86, 0.44, 0.57) Maroon = make_color(0.69, 0.19, 0.37) Medium_violet_red = make_color(0.78, 0.08, 0.52) Violet_red = make_color(0.81, 0.12, 0.56) Magenta = make_color(1.00, 0.00, 1.00) Violet = make_color(0.93, 0.51, 0.93) Plum = make_color(0.86, 0.62, 0.86) Orchid = make_color(0.85, 0.44, 0.84) Medium_orchid = make_color(0.73, 0.33, 0.82) Dark_orchid = make_color(0.60, 0.20, 0.80) Dark_violet = make_color(0.58, 0.00, 0.82) Blue_violet = make_color(0.54, 0.17, 0.88) Purple = make_color(0.62, 0.12, 0.94) Medium_purple = make_color(0.57, 0.44, 0.86) Thistle = make_color(0.84, 0.75, 0.84) Snow1 = make_color(1.00, 0.98, 0.98) Snow2 = make_color(0.93, 0.91, 0.91) Snow3 = make_color(0.80, 0.79, 0.79) Snow4 = make_color(0.54, 0.54, 0.54) Seashell1 = make_color(1.00, 0.96, 0.93) Seashell2 = make_color(0.93, 0.89, 0.87) Seashell3 = make_color(0.80, 0.77, 0.75) Seashell4 = make_color(0.54, 0.52, 0.51) Antiquewhite1 = make_color(1.00, 0.93, 0.86) Antiquewhite2 = make_color(0.93, 0.87, 0.80) Antiquewhite3 = make_color(0.80, 0.75, 0.69) Antiquewhite4 = make_color(0.54, 0.51, 0.47) Bisque1 = make_color(1.00, 0.89, 0.77) Bisque2 = make_color(0.93, 0.83, 0.71) Bisque3 = make_color(0.80, 0.71, 0.62) Bisque4 = make_color(0.54, 0.49, 0.42) Peachpuff1 = make_color(1.00, 0.85, 0.72) Peachpuff2 = make_color(0.93, 0.79, 0.68) Peachpuff3 = make_color(0.80, 0.68, 0.58) Peachpuff4 = make_color(0.54, 0.46, 0.39) Navajowhite1 = make_color(1.00, 0.87, 0.68) Navajowhite2 = make_color(0.93, 0.81, 0.63) Navajowhite3 = make_color(0.80, 0.70, 0.54) Navajowhite4 = make_color(0.54, 0.47, 0.37) Lemonchiffon1 = make_color(1.00, 0.98, 0.80) Lemonchiffon2 = make_color(0.93, 0.91, 0.75) Lemonchiffon3 = make_color(0.80, 0.79, 0.64) Lemonchiffon4 = make_color(0.54, 0.54, 0.44) Cornsilk1 = make_color(1.00, 0.97, 0.86) Cornsilk2 = make_color(0.93, 0.91, 0.80) Cornsilk3 = make_color(0.80, 0.78, 0.69) Cornsilk4 = make_color(0.54, 0.53, 0.47) Ivory1 = make_color(1.00, 1.00, 0.94) Ivory2 = make_color(0.93, 0.93, 0.87) Ivory3 = make_color(0.80, 0.80, 0.75) Ivory4 = make_color(0.54, 0.54, 0.51) Honeydew1 = make_color(0.94, 1.00, 0.94) Honeydew2 = make_color(0.87, 0.93, 0.87) Honeydew3 = make_color(0.75, 0.80, 0.75) Honeydew4 = make_color(0.51, 0.54, 0.51) Lavenderblush1 = make_color(1.00, 0.94, 0.96) Lavenderblush2 = make_color(0.93, 0.87, 0.89) Lavenderblush3 = make_color(0.80, 0.75, 0.77) Lavenderblush4 = make_color(0.54, 0.51, 0.52) Mistyrose1 = make_color(1.00, 0.89, 0.88) Mistyrose2 = make_color(0.93, 0.83, 0.82) Mistyrose3 = make_color(0.80, 0.71, 0.71) Mistyrose4 = make_color(0.54, 0.49, 0.48) Azure1 = make_color(0.94, 1.00, 1.00) Azure2 = make_color(0.87, 0.93, 0.93) Azure3 = make_color(0.75, 0.80, 0.80) Azure4 = make_color(0.51, 0.54, 0.54) Slateblue1 = make_color(0.51, 0.43, 1.00) Slateblue2 = make_color(0.48, 0.40, 0.93) Slateblue3 = make_color(0.41, 0.35, 0.80) Slateblue4 = make_color(0.28, 0.23, 0.54) Royalblue1 = make_color(0.28, 0.46, 1.00) Royalblue2 = make_color(0.26, 0.43, 0.93) Royalblue3 = make_color(0.23, 0.37, 0.80) Royalblue4 = make_color(0.15, 0.25, 0.54) Blue1 = make_color(0.00, 0.00, 1.00) Blue2 = make_color(0.00, 0.00, 0.93) Blue3 = make_color(0.00, 0.00, 0.80) Blue4 = make_color(0.00, 0.00, 0.54) Dodgerblue1 = make_color(0.12, 0.56, 1.00) Dodgerblue2 = make_color(0.11, 0.52, 0.93) Dodgerblue3 = make_color(0.09, 0.45, 0.80) Dodgerblue4 = make_color(0.06, 0.30, 0.54) Steelblue1 = make_color(0.39, 0.72, 1.00) Steelblue2 = make_color(0.36, 0.67, 0.93) Steelblue3 = make_color(0.31, 0.58, 0.80) Steelblue4 = make_color(0.21, 0.39, 0.54) Deepskyblue1 = make_color(0.00, 0.75, 1.00) Deepskyblue2 = make_color(0.00, 0.70, 0.93) Deepskyblue3 = make_color(0.00, 0.60, 0.80) Deepskyblue4 = make_color(0.00, 0.41, 0.54) Skyblue1 = make_color(0.53, 0.80, 1.00) Skyblue2 = make_color(0.49, 0.75, 0.93) Skyblue3 = make_color(0.42, 0.65, 0.80) Skyblue4 = make_color(0.29, 0.44, 0.54) Lightskyblue1 = make_color(0.69, 0.88, 1.00) Lightskyblue2 = make_color(0.64, 0.82, 0.93) Lightskyblue3 = make_color(0.55, 0.71, 0.80) Lightskyblue4 = make_color(0.37, 0.48, 0.54) Slategray1 = make_color(0.77, 0.88, 1.00) Slategray2 = make_color(0.72, 0.82, 0.93) Slategray3 = make_color(0.62, 0.71, 0.80) Slategray4 = make_color(0.42, 0.48, 0.54) Lightsteelblue1 = make_color(0.79, 0.88, 1.00) Lightsteelblue2 = make_color(0.73, 0.82, 0.93) Lightsteelblue3 = make_color(0.63, 0.71, 0.80) Lightsteelblue4 = make_color(0.43, 0.48, 0.54) Lightblue1 = make_color(0.75, 0.93, 1.00) Lightblue2 = make_color(0.70, 0.87, 0.93) Lightblue3 = make_color(0.60, 0.75, 0.80) Lightblue4 = make_color(0.41, 0.51, 0.54) Lightcyan1 = make_color(0.87, 1.00, 1.00) Lightcyan2 = make_color(0.82, 0.93, 0.93) Lightcyan3 = make_color(0.70, 0.80, 0.80) Lightcyan4 = make_color(0.48, 0.54, 0.54) Paleturquoise1 = make_color(0.73, 1.00, 1.00) Paleturquoise2 = make_color(0.68, 0.93, 0.93) Paleturquoise3 = make_color(0.59, 0.80, 0.80) Paleturquoise4 = make_color(0.40, 0.54, 0.54) Cadetblue1 = make_color(0.59, 0.96, 1.00) Cadetblue2 = make_color(0.55, 0.89, 0.93) Cadetblue3 = make_color(0.48, 0.77, 0.80) Cadetblue4 = make_color(0.32, 0.52, 0.54) Turquoise1 = make_color(0.00, 0.96, 1.00) Turquoise2 = make_color(0.00, 0.89, 0.93) Turquoise3 = make_color(0.00, 0.77, 0.80) Turquoise4 = make_color(0.00, 0.52, 0.54) Cyan1 = make_color(0.00, 1.00, 1.00) Cyan2 = make_color(0.00, 0.93, 0.93) Cyan3 = make_color(0.00, 0.80, 0.80) Cyan4 = make_color(0.00, 0.54, 0.54) Darkslategray1 = make_color(0.59, 1.00, 1.00) Darkslategray2 = make_color(0.55, 0.93, 0.93) Darkslategray3 = make_color(0.47, 0.80, 0.80) Darkslategray4 = make_color(0.32, 0.54, 0.54) Aquamarine1 = make_color(0.50, 1.00, 0.83) Aquamarine2 = make_color(0.46, 0.93, 0.77) Aquamarine3 = make_color(0.40, 0.80, 0.66) Aquamarine4 = make_color(0.27, 0.54, 0.45) Darkseagreen1 = make_color(0.75, 1.00, 0.75) Darkseagreen2 = make_color(0.70, 0.93, 0.70) Darkseagreen3 = make_color(0.61, 0.80, 0.61) Darkseagreen4 = make_color(0.41, 0.54, 0.41) Seagreen1 = make_color(0.33, 1.00, 0.62) Seagreen2 = make_color(0.30, 0.93, 0.58) Seagreen3 = make_color(0.26, 0.80, 0.50) Seagreen4 = make_color(0.18, 0.54, 0.34) Palegreen1 = make_color(0.60, 1.00, 0.60) Palegreen2 = make_color(0.56, 0.93, 0.56) Palegreen3 = make_color(0.48, 0.80, 0.48) Palegreen4 = make_color(0.33, 0.54, 0.33) Springgreen1 = make_color(0.00, 1.00, 0.50) Springgreen2 = make_color(0.00, 0.93, 0.46) Springgreen3 = make_color(0.00, 0.80, 0.40) Springgreen4 = make_color(0.00, 0.54, 0.27) Green1 = make_color(0.00, 1.00, 0.00) Green2 = make_color(0.00, 0.93, 0.00) Green3 = make_color(0.00, 0.80, 0.00) Green4 = make_color(0.00, 0.54, 0.00) Chartreuse1 = make_color(0.50, 1.00, 0.00) Chartreuse2 = make_color(0.46, 0.93, 0.00) Chartreuse3 = make_color(0.40, 0.80, 0.00) Chartreuse4 = make_color(0.27, 0.54, 0.00) Olivedrab1 = make_color(0.75, 1.00, 0.24) Olivedrab2 = make_color(0.70, 0.93, 0.23) Olivedrab3 = make_color(0.60, 0.80, 0.20) Olivedrab4 = make_color(0.41, 0.54, 0.13) Darkolivegreen1 = make_color(0.79, 1.00, 0.44) Darkolivegreen2 = make_color(0.73, 0.93, 0.41) Darkolivegreen3 = make_color(0.63, 0.80, 0.35) Darkolivegreen4 = make_color(0.43, 0.54, 0.24) Khaki1 = make_color(1.00, 0.96, 0.56) Khaki2 = make_color(0.93, 0.90, 0.52) Khaki3 = make_color(0.80, 0.77, 0.45) Khaki4 = make_color(0.54, 0.52, 0.30) Lightgoldenrod1 = make_color(1.00, 0.92, 0.54) Lightgoldenrod2 = make_color(0.93, 0.86, 0.51) Lightgoldenrod3 = make_color(0.80, 0.74, 0.44) Lightgoldenrod4 = make_color(0.54, 0.50, 0.30) Lightyellow1 = make_color(1.00, 1.00, 0.87) Lightyellow2 = make_color(0.93, 0.93, 0.82) Lightyellow3 = make_color(0.80, 0.80, 0.70) Lightyellow4 = make_color(0.54, 0.54, 0.48) Yellow1 = make_color(1.00, 1.00, 0.00) Yellow2 = make_color(0.93, 0.93, 0.00) Yellow3 = make_color(0.80, 0.80, 0.00) Yellow4 = make_color(0.54, 0.54, 0.00) Gold1 = make_color(1.00, 0.84, 0.00) Gold2 = make_color(0.93, 0.79, 0.00) Gold3 = make_color(0.80, 0.68, 0.00) Gold4 = make_color(0.54, 0.46, 0.00) Goldenrod1 = make_color(1.00, 0.75, 0.14) Goldenrod2 = make_color(0.93, 0.70, 0.13) Goldenrod3 = make_color(0.80, 0.61, 0.11) Goldenrod4 = make_color(0.54, 0.41, 0.08) Darkgoldenrod1 = make_color(1.00, 0.72, 0.06) Darkgoldenrod2 = make_color(0.93, 0.68, 0.05) Darkgoldenrod3 = make_color(0.80, 0.58, 0.05) Darkgoldenrod4 = make_color(0.54, 0.39, 0.03) Rosybrown1 = make_color(1.00, 0.75, 0.75) Rosybrown2 = make_color(0.93, 0.70, 0.70) Rosybrown3 = make_color(0.80, 0.61, 0.61) Rosybrown4 = make_color(0.54, 0.41, 0.41) Indianred1 = make_color(1.00, 0.41, 0.41) Indianred2 = make_color(0.93, 0.39, 0.39) Indianred3 = make_color(0.80, 0.33, 0.33) Indianred4 = make_color(0.54, 0.23, 0.23) Sienna1 = make_color(1.00, 0.51, 0.28) Sienna2 = make_color(0.93, 0.47, 0.26) Sienna3 = make_color(0.80, 0.41, 0.22) Sienna4 = make_color(0.54, 0.28, 0.15) Burlywood1 = make_color(1.00, 0.82, 0.61) Burlywood2 = make_color(0.93, 0.77, 0.57) Burlywood3 = make_color(0.80, 0.66, 0.49) Burlywood4 = make_color(0.54, 0.45, 0.33) Wheat1 = make_color(1.00, 0.90, 0.73) Wheat2 = make_color(0.93, 0.84, 0.68) Wheat3 = make_color(0.80, 0.73, 0.59) Wheat4 = make_color(0.54, 0.49, 0.40) Tan1 = make_color(1.00, 0.64, 0.31) Tan2 = make_color(0.93, 0.60, 0.29) Tan3 = make_color(0.80, 0.52, 0.25) Tan4 = make_color(0.54, 0.35, 0.17) Chocolate1 = make_color(1.00, 0.50, 0.14) Chocolate2 = make_color(0.93, 0.46, 0.13) Chocolate3 = make_color(0.80, 0.40, 0.11) Chocolate4 = make_color(0.54, 0.27, 0.07) Firebrick1 = make_color(1.00, 0.19, 0.19) Firebrick2 = make_color(0.93, 0.17, 0.17) Firebrick3 = make_color(0.80, 0.15, 0.15) Firebrick4 = make_color(0.54, 0.10, 0.10) Brown1 = make_color(1.00, 0.25, 0.25) Brown2 = make_color(0.93, 0.23, 0.23) Brown3 = make_color(0.80, 0.20, 0.20) Brown4 = make_color(0.54, 0.14, 0.14) Salmon1 = make_color(1.00, 0.55, 0.41) Salmon2 = make_color(0.93, 0.51, 0.38) Salmon3 = make_color(0.80, 0.44, 0.33) Salmon4 = make_color(0.54, 0.30, 0.22) Lightsalmon1 = make_color(1.00, 0.62, 0.48) Lightsalmon2 = make_color(0.93, 0.58, 0.45) Lightsalmon3 = make_color(0.80, 0.50, 0.38) Lightsalmon4 = make_color(0.54, 0.34, 0.26) Orange1 = make_color(1.00, 0.64, 0.00) Orange2 = make_color(0.93, 0.60, 0.00) Orange3 = make_color(0.80, 0.52, 0.00) Orange4 = make_color(0.54, 0.35, 0.00) Darkorange1 = make_color(1.00, 0.50, 0.00) Darkorange2 = make_color(0.93, 0.46, 0.00) Darkorange3 = make_color(0.80, 0.40, 0.00) Darkorange4 = make_color(0.54, 0.27, 0.00) Coral1 = make_color(1.00, 0.45, 0.34) Coral2 = make_color(0.93, 0.41, 0.31) Coral3 = make_color(0.80, 0.36, 0.27) Coral4 = make_color(0.54, 0.24, 0.18) Tomato1 = make_color(1.00, 0.39, 0.28) Tomato2 = make_color(0.93, 0.36, 0.26) Tomato3 = make_color(0.80, 0.31, 0.22) Tomato4 = make_color(0.54, 0.21, 0.15) Orangered1 = make_color(1.00, 0.27, 0.00) Orangered2 = make_color(0.93, 0.25, 0.00) Orangered3 = make_color(0.80, 0.21, 0.00) Orangered4 = make_color(0.54, 0.14, 0.00) Red1 = make_color(1.00, 0.00, 0.00) Red2 = make_color(0.93, 0.00, 0.00) Red3 = make_color(0.80, 0.00, 0.00) Red4 = make_color(0.54, 0.00, 0.00) Deeppink1 = make_color(1.00, 0.08, 0.57) Deeppink2 = make_color(0.93, 0.07, 0.54) Deeppink3 = make_color(0.80, 0.06, 0.46) Deeppink4 = make_color(0.54, 0.04, 0.31) Hotpink1 = make_color(1.00, 0.43, 0.70) Hotpink2 = make_color(0.93, 0.41, 0.65) Hotpink3 = make_color(0.80, 0.37, 0.56) Hotpink4 = make_color(0.54, 0.23, 0.38) Pink1 = make_color(1.00, 0.71, 0.77) Pink2 = make_color(0.93, 0.66, 0.72) Pink3 = make_color(0.80, 0.57, 0.62) Pink4 = make_color(0.54, 0.39, 0.42) Lightpink1 = make_color(1.00, 0.68, 0.72) Lightpink2 = make_color(0.93, 0.63, 0.68) Lightpink3 = make_color(0.80, 0.55, 0.58) Lightpink4 = make_color(0.54, 0.37, 0.39) Palevioletred1 = make_color(1.00, 0.51, 0.67) Palevioletred2 = make_color(0.93, 0.47, 0.62) Palevioletred3 = make_color(0.80, 0.41, 0.54) Palevioletred4 = make_color(0.54, 0.28, 0.36) Maroon1 = make_color(1.00, 0.20, 0.70) Maroon2 = make_color(0.93, 0.19, 0.65) Maroon3 = make_color(0.80, 0.16, 0.56) Maroon4 = make_color(0.54, 0.11, 0.38) Violetred1 = make_color(1.00, 0.24, 0.59) Violetred2 = make_color(0.93, 0.23, 0.55) Violetred3 = make_color(0.80, 0.20, 0.47) Violetred4 = make_color(0.54, 0.13, 0.32) Magenta1 = make_color(1.00, 0.00, 1.00) Magenta2 = make_color(0.93, 0.00, 0.93) Magenta3 = make_color(0.80, 0.00, 0.80) Magenta4 = make_color(0.54, 0.00, 0.54) Orchid1 = make_color(1.00, 0.51, 0.98) Orchid2 = make_color(0.93, 0.48, 0.91) Orchid3 = make_color(0.80, 0.41, 0.79) Orchid4 = make_color(0.54, 0.28, 0.54) Plum1 = make_color(1.00, 0.73, 1.00) Plum2 = make_color(0.93, 0.68, 0.93) Plum3 = make_color(0.80, 0.59, 0.80) Plum4 = make_color(0.54, 0.40, 0.54) Mediumorchid1 = make_color(0.87, 0.40, 1.00) Mediumorchid2 = make_color(0.82, 0.37, 0.93) Mediumorchid3 = make_color(0.70, 0.32, 0.80) Mediumorchid4 = make_color(0.48, 0.21, 0.54) Darkorchid1 = make_color(0.75, 0.24, 1.00) Darkorchid2 = make_color(0.70, 0.23, 0.93) Darkorchid3 = make_color(0.60, 0.20, 0.80) Darkorchid4 = make_color(0.41, 0.13, 0.54) Purple1 = make_color(0.61, 0.19, 1.00) Purple2 = make_color(0.57, 0.17, 0.93) Purple3 = make_color(0.49, 0.15, 0.80) Purple4 = make_color(0.33, 0.10, 0.54) Mediumpurple1 = make_color(0.67, 0.51, 1.00) Mediumpurple2 = make_color(0.62, 0.47, 0.93) Mediumpurple3 = make_color(0.54, 0.41, 0.80) Mediumpurple4 = make_color(0.36, 0.28, 0.54) Thistle1 = make_color(1.00, 0.88, 1.00) Thistle2 = make_color(0.93, 0.82, 0.93) Thistle3 = make_color(0.80, 0.71, 0.80) Thistle4 = make_color(0.54, 0.48, 0.54) Gray0 = make_color(0.00, 0.00, 0.00) Grey0 = make_color(0.00, 0.00, 0.00) Gray1 = make_color(0.01, 0.01, 0.01) Grey1 = make_color(0.01, 0.01, 0.01) Gray2 = make_color(0.02, 0.02, 0.02) Grey2 = make_color(0.02, 0.02, 0.02) Gray3 = make_color(0.03, 0.03, 0.03) Grey3 = make_color(0.03, 0.03, 0.03) Gray4 = make_color(0.04, 0.04, 0.04) Grey4 = make_color(0.04, 0.04, 0.04) Gray5 = make_color(0.05, 0.05, 0.05) Grey5 = make_color(0.05, 0.05, 0.05) Gray6 = make_color(0.06, 0.06, 0.06) Grey6 = make_color(0.06, 0.06, 0.06) Gray7 = make_color(0.07, 0.07, 0.07) Grey7 = make_color(0.07, 0.07, 0.07) Gray8 = make_color(0.08, 0.08, 0.08) Grey8 = make_color(0.08, 0.08, 0.08) Gray9 = make_color(0.09, 0.09, 0.09) Grey9 = make_color(0.09, 0.09, 0.09) Gray10 = make_color(0.10, 0.10, 0.10) Grey10 = make_color(0.10, 0.10, 0.10) Gray11 = make_color(0.11, 0.11, 0.11) Grey11 = make_color(0.11, 0.11, 0.11) Gray12 = make_color(0.12, 0.12, 0.12) Grey12 = make_color(0.12, 0.12, 0.12) Gray13 = make_color(0.13, 0.13, 0.13) Grey13 = make_color(0.13, 0.13, 0.13) Gray14 = make_color(0.14, 0.14, 0.14) Grey14 = make_color(0.14, 0.14, 0.14) Gray15 = make_color(0.15, 0.15, 0.15) Grey15 = make_color(0.15, 0.15, 0.15) Gray16 = make_color(0.16, 0.16, 0.16) Grey16 = make_color(0.16, 0.16, 0.16) Gray17 = make_color(0.17, 0.17, 0.17) Grey17 = make_color(0.17, 0.17, 0.17) Gray18 = make_color(0.18, 0.18, 0.18) Grey18 = make_color(0.18, 0.18, 0.18) Gray19 = make_color(0.19, 0.19, 0.19) Grey19 = make_color(0.19, 0.19, 0.19) Gray20 = make_color(0.20, 0.20, 0.20) Grey20 = make_color(0.20, 0.20, 0.20) Gray21 = make_color(0.21, 0.21, 0.21) Grey21 = make_color(0.21, 0.21, 0.21) Gray22 = make_color(0.22, 0.22, 0.22) Grey22 = make_color(0.22, 0.22, 0.22) Gray23 = make_color(0.23, 0.23, 0.23) Grey23 = make_color(0.23, 0.23, 0.23) Gray24 = make_color(0.24, 0.24, 0.24) Grey24 = make_color(0.24, 0.24, 0.24) Gray25 = make_color(0.25, 0.25, 0.25) Grey25 = make_color(0.25, 0.25, 0.25) Gray26 = make_color(0.26, 0.26, 0.26) Grey26 = make_color(0.26, 0.26, 0.26) Gray27 = make_color(0.27, 0.27, 0.27) Grey27 = make_color(0.27, 0.27, 0.27) Gray28 = make_color(0.28, 0.28, 0.28) Grey28 = make_color(0.28, 0.28, 0.28) Gray29 = make_color(0.29, 0.29, 0.29) Grey29 = make_color(0.29, 0.29, 0.29) Gray30 = make_color(0.30, 0.30, 0.30) Grey30 = make_color(0.30, 0.30, 0.30) Gray31 = make_color(0.31, 0.31, 0.31) Grey31 = make_color(0.31, 0.31, 0.31) Gray32 = make_color(0.32, 0.32, 0.32) Grey32 = make_color(0.32, 0.32, 0.32) Gray33 = make_color(0.33, 0.33, 0.33) Grey33 = make_color(0.33, 0.33, 0.33) Gray34 = make_color(0.34, 0.34, 0.34) Grey34 = make_color(0.34, 0.34, 0.34) Gray35 = make_color(0.35, 0.35, 0.35) Grey35 = make_color(0.35, 0.35, 0.35) Gray36 = make_color(0.36, 0.36, 0.36) Grey36 = make_color(0.36, 0.36, 0.36) Gray37 = make_color(0.37, 0.37, 0.37) Grey37 = make_color(0.37, 0.37, 0.37) Gray38 = make_color(0.38, 0.38, 0.38) Grey38 = make_color(0.38, 0.38, 0.38) Gray39 = make_color(0.39, 0.39, 0.39) Grey39 = make_color(0.39, 0.39, 0.39) Gray40 = make_color(0.40, 0.40, 0.40) Grey40 = make_color(0.40, 0.40, 0.40) Gray41 = make_color(0.41, 0.41, 0.41) Grey41 = make_color(0.41, 0.41, 0.41) Gray42 = make_color(0.42, 0.42, 0.42) Grey42 = make_color(0.42, 0.42, 0.42) Gray43 = make_color(0.43, 0.43, 0.43) Grey43 = make_color(0.43, 0.43, 0.43) Gray44 = make_color(0.44, 0.44, 0.44) Grey44 = make_color(0.44, 0.44, 0.44) Gray45 = make_color(0.45, 0.45, 0.45) Grey45 = make_color(0.45, 0.45, 0.45) Gray46 = make_color(0.46, 0.46, 0.46) Grey46 = make_color(0.46, 0.46, 0.46) Gray47 = make_color(0.47, 0.47, 0.47) Grey47 = make_color(0.47, 0.47, 0.47) Gray48 = make_color(0.48, 0.48, 0.48) Grey48 = make_color(0.48, 0.48, 0.48) Gray49 = make_color(0.49, 0.49, 0.49) Grey49 = make_color(0.49, 0.49, 0.49) Gray50 = make_color(0.50, 0.50, 0.50) Grey50 = make_color(0.50, 0.50, 0.50) Gray51 = make_color(0.51, 0.51, 0.51) Grey51 = make_color(0.51, 0.51, 0.51) Gray52 = make_color(0.52, 0.52, 0.52) Grey52 = make_color(0.52, 0.52, 0.52) Gray53 = make_color(0.53, 0.53, 0.53) Grey53 = make_color(0.53, 0.53, 0.53) Gray54 = make_color(0.54, 0.54, 0.54) Grey54 = make_color(0.54, 0.54, 0.54) Gray55 = make_color(0.55, 0.55, 0.55) Grey55 = make_color(0.55, 0.55, 0.55) Gray56 = make_color(0.56, 0.56, 0.56) Grey56 = make_color(0.56, 0.56, 0.56) Gray57 = make_color(0.57, 0.57, 0.57) Grey57 = make_color(0.57, 0.57, 0.57) Gray58 = make_color(0.58, 0.58, 0.58) Grey58 = make_color(0.58, 0.58, 0.58) Gray59 = make_color(0.59, 0.59, 0.59) Grey59 = make_color(0.59, 0.59, 0.59) Gray60 = make_color(0.60, 0.60, 0.60) Grey60 = make_color(0.60, 0.60, 0.60) Gray61 = make_color(0.61, 0.61, 0.61) Grey61 = make_color(0.61, 0.61, 0.61) Gray62 = make_color(0.62, 0.62, 0.62) Grey62 = make_color(0.62, 0.62, 0.62) Gray63 = make_color(0.63, 0.63, 0.63) Grey63 = make_color(0.63, 0.63, 0.63) Gray64 = make_color(0.64, 0.64, 0.64) Grey64 = make_color(0.64, 0.64, 0.64) Gray65 = make_color(0.65, 0.65, 0.65) Grey65 = make_color(0.65, 0.65, 0.65) Gray66 = make_color(0.66, 0.66, 0.66) Grey66 = make_color(0.66, 0.66, 0.66) Gray67 = make_color(0.67, 0.67, 0.67) Grey67 = make_color(0.67, 0.67, 0.67) Gray68 = make_color(0.68, 0.68, 0.68) Grey68 = make_color(0.68, 0.68, 0.68) Gray69 = make_color(0.69, 0.69, 0.69) Grey69 = make_color(0.69, 0.69, 0.69) Gray70 = make_color(0.70, 0.70, 0.70) Grey70 = make_color(0.70, 0.70, 0.70) Gray71 = make_color(0.71, 0.71, 0.71) Grey71 = make_color(0.71, 0.71, 0.71) Gray72 = make_color(0.72, 0.72, 0.72) Grey72 = make_color(0.72, 0.72, 0.72) Gray73 = make_color(0.73, 0.73, 0.73) Grey73 = make_color(0.73, 0.73, 0.73) Gray74 = make_color(0.74, 0.74, 0.74) Grey74 = make_color(0.74, 0.74, 0.74) Gray75 = make_color(0.75, 0.75, 0.75) Grey75 = make_color(0.75, 0.75, 0.75) Gray76 = make_color(0.76, 0.76, 0.76) Grey76 = make_color(0.76, 0.76, 0.76) Gray77 = make_color(0.77, 0.77, 0.77) Grey77 = make_color(0.77, 0.77, 0.77) Gray78 = make_color(0.78, 0.78, 0.78) Grey78 = make_color(0.78, 0.78, 0.78) Gray79 = make_color(0.79, 0.79, 0.79) Grey79 = make_color(0.79, 0.79, 0.79) Gray80 = make_color(0.80, 0.80, 0.80) Grey80 = make_color(0.80, 0.80, 0.80) Gray81 = make_color(0.81, 0.81, 0.81) Grey81 = make_color(0.81, 0.81, 0.81) Gray82 = make_color(0.82, 0.82, 0.82) Grey82 = make_color(0.82, 0.82, 0.82) Gray83 = make_color(0.83, 0.83, 0.83) Grey83 = make_color(0.83, 0.83, 0.83) Gray84 = make_color(0.84, 0.84, 0.84) Grey84 = make_color(0.84, 0.84, 0.84) Gray85 = make_color(0.85, 0.85, 0.85) Grey85 = make_color(0.85, 0.85, 0.85) Gray86 = make_color(0.86, 0.86, 0.86) Grey86 = make_color(0.86, 0.86, 0.86) Gray87 = make_color(0.87, 0.87, 0.87) Grey87 = make_color(0.87, 0.87, 0.87) Gray88 = make_color(0.87, 0.87, 0.87) Grey88 = make_color(0.87, 0.87, 0.87) Gray89 = make_color(0.89, 0.89, 0.89) Grey89 = make_color(0.89, 0.89, 0.89) Gray90 = make_color(0.89, 0.89, 0.89) Grey90 = make_color(0.89, 0.89, 0.89) Gray91 = make_color(0.91, 0.91, 0.91) Grey91 = make_color(0.91, 0.91, 0.91) Gray92 = make_color(0.92, 0.92, 0.92) Grey92 = make_color(0.92, 0.92, 0.92) Gray93 = make_color(0.93, 0.93, 0.93) Grey93 = make_color(0.93, 0.93, 0.93) Gray94 = make_color(0.94, 0.94, 0.94) Grey94 = make_color(0.94, 0.94, 0.94) Gray95 = make_color(0.95, 0.95, 0.95) Grey95 = make_color(0.95, 0.95, 0.95) Gray96 = make_color(0.96, 0.96, 0.96) Grey96 = make_color(0.96, 0.96, 0.96) Gray97 = make_color(0.96, 0.96, 0.96) Grey97 = make_color(0.96, 0.96, 0.96) Gray98 = make_color(0.98, 0.98, 0.98) Grey98 = make_color(0.98, 0.98, 0.98) Gray99 = make_color(0.98, 0.98, 0.98) Grey99 = make_color(0.98, 0.98, 0.98) Gray100 = make_color(1.00, 1.00, 1.00) Grey100 = make_color(1.00, 1.00, 1.00) Dark_grey = make_color(0.66, 0.66, 0.66) Dark_gray = make_color(0.66, 0.66, 0.66) Dark_blue = make_color(0.00, 0.00, 0.54) Dark_cyan = make_color(0.00, 0.54, 0.54) Dark_magenta = make_color(0.54, 0.00, 0.54) Dark_red = make_color(0.54, 0.00, 0.00) Light_green = make_color(0.56, 0.93, 0.56) # rgb.rb ends here snd-16.1/repl.scm0000644000076400007640000015040712620411146012005 0ustar bilbil;;; a repl ;;; ;;; (load "repl.scm") ((*repl* 'run)) (provide 'repl.scm) (require libc.scm) (unless (defined? '*repl*) (define *repl* ; environment that holds the REPL functions (let ((prompt #f) ; function to get/set prompt (keymap #f) ; function to get/set keymap entries (history #f) ; function to get/set history buffer entries (history-size #f) ; function to get/set history buffer size (save-history #f) ; function to save the current history buffer entries in a file (restore-history #f) ; function to restore history buffer entries from a file (helpers ()) ; list of functions displaying help strings (run #f) ; function that fires up a REPL (top-level-let (sublet (rootlet) :** #f)) ; environment in which evaluation takes place (repl-let ; environment for keymap functions to access all the REPL innards (cursor-position etc) (with-let (sublet *libc*) ;; -------- completion -------- (define (symbol-completion text) (let ((st (symbol-table)) (text-len (length text)) (match #f)) (call-with-exit (lambda (return) (for-each (lambda (symbol) (let* ((sym (symbol->string symbol)) (sym-len (length sym))) (when (and (>= sym-len text-len) (string=? text (substring sym 0 text-len))) (if match (return text) (set! match sym))))) st) (or match text))))) (define (filename-completion text) (let ((g (glob.make))) (glob (string-append text "*") (logior (if (and (defined? 'GLOB_TILDE) (char=? (text 0) #\~)) GLOB_TILDE 0) GLOB_MARK) g) (let ((files (map (lambda (f) ; get rid of emacs' *~ files (if (and (> (length f) 1) (char=? #\~ (f (- (length f) 1)))) (values) f)) (glob.gl_pathv g)))) (globfree g) (if (or (null? files) (not (null? (cdr files)))) text (car files))))) ;; -------- history -------- (let ((histbuf (make-vector 100 "")) (histsize 100) (histpos 0) (m-p-pos 0) (histtop ()) (histtail ())) (define (push-line line) (if (null? histtop) (begin (set! histtop (list line)) (set! histtail histtop)) (begin (set-cdr! histtail (list line)) (set! histtail (cdr histtail))))) (define (history-member line) (do ((i 0 (+ i 1))) ((or (= i histsize) (string=? (vector-ref histbuf i) line)) (and (< i histsize) i)))) (define history-size (dilambda (lambda () histsize) (lambda (new-size) (unless (= new-size histsize) (if (<= new-size 0) (error 'out-of-range "new history buffer size must be positive") (let ((new-hist (make-vector new-size "")) (new-end (min (- new-size 1) histpos))) (let loop ((oldpos histpos) (newpos new-end)) (set! (new-hist newpos) (histbuf oldpos)) (if (zero? newpos) (set! newpos (- new-size 1)) (set! newpos (- newpos 1))) (unless (= newpos new-end) (if (zero? oldpos) (set! oldpos (- histsize 1)) (set! oldpos (- oldpos 1))) (unless (= oldpos histpos) (loop oldpos newpos)))) (set! histsize new-size) (set! histpos new-end) (set! histbuf new-hist) new-size)))))) (define history (dilambda (lambda (back) (let ((i (+ histpos back))) (if (< i 0) (histbuf (+ histsize i)) (if (>= i histsize) (histbuf (- i histsize)) (histbuf i))))) (lambda (new-line) (let ((pos (history-member new-line))) (when (integer? pos) ; remove the earlier case, circularly compress the buffer (when (>= pos histpos) (do ((i pos (+ i 1))) ((>= i (- histsize 1))) (set! (histbuf i) (histbuf (+ i 1)))) (set! (histbuf (- histsize 1)) (histbuf 0)) (set! pos 0)) (do ((i pos (+ i 1))) ((>= i (- histpos 1))) (set! (histbuf i) (histbuf (+ i 1)))) (set! histpos (- histpos 1))) (set! (histbuf histpos) new-line) (set! histpos (+ histpos 1)) (if (= histpos histsize) (set! histpos 0)))))) (define (history-help) (set! (*repl* 'helpers) (list (lambda (c) (format #f "size: ~A, pos: ~A" histsize histpos)) (lambda (c) (format #f "buf: ~A ~A ~A" (history -1) (history -2) (history -3))) (lambda (c) (format #f "line: ~A" histtop))))) (define (pop-history) ; throw away most recent addition (set! histpos (- histpos 1)) (if (negative? histpos) (set! histpos (- histsize 1)))) (define* (write-history port (spaces 0)) (format port "~NC(set! histpos ~D)~%" spaces #\space histpos) (format port "~NC(set! histsize ~D)~%" spaces #\space histsize) (let ((pl (*s7* 'print-length))) (set! (*s7* 'print-length) (* 2 histsize)) (format port "~NC(set! histbuf ~A)" spaces #\space (object->string histbuf)) (set! (*s7* 'print-length) pl))) (define* (save-history (file "repl-history.scm")) (call-with-output-file file write-history)) (define* (restore-history (file "repl-history.scm")) (load file (curlet))) (let ((prompt-string "<1> ") ; this doesn't look very good, but I can't find anything better (prompt-length 4) ; perhaps the line number could go in the terminal's right margin? (cur-line "") ; current expression (can contain newlines) (prev-line ()) ; for undo via C-_ (selection #f) ; for C-y (cursor-pos 0) ; cursor-pos is the logical position (index into cur-line) (cur-row 0) ; catch window scrolling (red-par-pos #f) ; paren match position (index into cur-line) (prompt-row 0) ; need to tie everything to prompt position (it can move in media res if window scrolls) (prompt-col 0) (last-row 0) ; these hold the window bounds when we start (last-col 0) (input-fd (fileno stdin)) ; source of chars, either tty input or file input (terminal-fd (fileno stdin)) (tab-as-space (make-string 6 #\space)) (next-char #f) (chars 0) ; (sigh) a kludge to try to distinguish tab-as-space from tab-as-completion/indentation (unbound-case #f) (all-done #f)) ; if #t, repl returns to its caller, if any ;; -------- evaluation --------- (define (badexpr h) ; *missing-close-paren-hook* function for Enter command (set! (h 'result) 'string-read-error)) (define (shell? h) ; *unbound-variable-hook* function, also for Enter ;; examine cur-line -- only call system if the unbound variable matches the first non-whitespace chars ;; of cur-line, and command -v name returns 0 (indicating the shell thinks it is an executable command) (do ((i 0 (+ i 1))) ((or (= i (length cur-line)) (not (char-whitespace? (cur-line i)))) (let ((var-name (symbol->string (h 'variable)))) (when (and (>= (- (length cur-line) i) (length var-name)) ; var-name might be unrelated to cur-line (string=? var-name (substring cur-line i (+ i (length var-name)))) (zero? (system (string-append "command -v " var-name " >/dev/null")))) (set! unbound-case #t) (if (procedure? ((rootlet) 'system)) (begin (set! ((*repl* 'top-level-let) '**) (((rootlet) 'system) cur-line #t)) (display ((*repl* 'top-level-let) '**) *stderr*)) (set! ((*repl* 'top-level-let) '**) (system cur-line))) (set! (h 'result) (symbol " "))))))) (define (with-repl-let body) ;; for multiline edits, we will use *missing-close-paren-hook* rather than try to parse the input ourselves. (let ((old-badexpr-hook (hook-functions *missing-close-paren-hook*)) (old-unbound-var-hook (hook-functions *unbound-variable-hook*)) (old-eval #f) (old-eval-string #f) (old-load #f)) ;; if the repl's top-level-let is not rootlet, and we load some file into rootlet ;; that (for example) defines a function at its top level, that function's definition ;; env is rootlet. If we then define something in the repl, it is in the ;; repl's top level. If we now call the function asking is the new thing defined, ;; it looks in rootlet, not the repl top-level, and says no. ;; so, locally redefine these three to use the repl top-level while we're in the repl. ;; in addition, for each of these, we need to report missing close parens and so on (define (repl-hooks) (set! (hook-functions *missing-close-paren-hook*) (cons badexpr old-badexpr-hook)) (set! (hook-functions *unbound-variable-hook*) (cons shell? old-unbound-var-hook))) (define (original-hooks) (set! unbound-case #f) (set! (hook-functions *missing-close-paren-hook*) old-badexpr-hook) (set! (hook-functions *unbound-variable-hook*) old-unbound-var-hook)) (define new-load (let ((documentation "this is the repl's load replacement; its default is to use the repl's top-level-let.") (signature '(values string? let?))) (lambda* (file (e (*repl* 'top-level-let))) (dynamic-wind original-hooks (lambda () (load file e)) repl-hooks)))) (define new-eval (let ((documentation "this is the repl's eval replacement; its default is to use the repl's top-level-let.") (signature '(values list? let?))) (lambda* (form (e (*repl* 'top-level-let))) (dynamic-wind original-hooks (lambda () (eval form e)) repl-hooks)))) (define new-eval-string (let ((documentation "this is the repl's eval-string replacement; its default is to use the repl's top-level-let.") (signature '(values string? let?))) (lambda* (str (e (*repl* 'top-level-let))) (dynamic-wind original-hooks (lambda () (eval-string str e)) repl-hooks)))) (dynamic-wind (lambda () (repl-hooks) (set! eval new-eval) (set! eval-string new-eval-string) (set! load new-load)) body (lambda () (set! eval old-eval) (set! eval-string old-eval-string) (set! load old-load) (original-hooks))))) ;; -------- match parens -------- (define (char-constant? pos) (and (> pos 2) (char=? (cur-line (- pos 1)) #\\) (char=? (cur-line (- pos 2)) #\#))) (define (check-parens) (let ((endpos (- cursor-pos 1))) (if (and (> cursor-pos 1) (char=? (cur-line endpos) #\)) ; ")" on left of cursor (not (char-constant? endpos))) ; it's not "#\)" (let ((oparens ()) (new-red-pos #f)) (do ((i 0 (+ i 1))) ((>= i endpos)) (case (cur-line i) ((#\() (set! oparens (cons i oparens))) ((#\)) (if (pair? oparens) (set! oparens (cdr oparens)))) ((#\;) (do ((k (+ i 1) (+ k 1))) ((or (>= k endpos) (char=? (cur-line k) #\newline)) (set! i k) (if (>= i endpos) ; (f1 "(+ 1 3) should not show first paren as a match (similarly below) (set! oparens ()))))) ((#\") (do ((k (+ i 1) (+ k 1))) ((or (>= k endpos) (and (char=? (cur-line k) #\") (not (char=? (cur-line (- k 1)) #\\)))) (set! i k) (if (>= i endpos) (set! oparens ()))))) ((#\#) (if (char=? (cur-line (+ i 1)) #\|) (do ((k (+ i 1) (+ k 1))) ((or (>= k endpos) (and (char=? (cur-line k) #\|) (char=? (cur-line (+ k 1)) #\#))) (set! i (+ k 1)) (if (>= i endpos) (set! oparens ())))))))) (if (pair? oparens) (set! new-red-pos (car oparens))) (unless (equal? new-red-pos red-par-pos) (if (number? new-red-pos) (set! red-par-pos new-red-pos) (set! red-par-pos #f)))) (if (number? red-par-pos) (set! red-par-pos #f))))) ;; -------- indentation -------- (define (indent pos) (let ((old-red red-par-pos) (old-line (copy cur-line)) (old-cursor cursor-pos)) (set! cur-line (string-append (substring cur-line 0 cursor-pos) ")")) (set! cursor-pos (length cur-line)) (check-parens) (set! cur-line old-line) (set! cursor-pos old-cursor) (let ((new-red red-par-pos)) (set! red-par-pos old-red) (let ((col 0)) (do ((i 0 (+ i 1))) ((= i new-red)) (if (char=? (cur-line i) #\newline) (set! col 0) (set! col (+ col 1)))) (let ((sym (do ((i (+ new-red 1) (+ i 1))) ((not (char-alphabetic? (cur-line i))) (substring cur-line (+ new-red 1) i))))) (let ((spaces (+ col (if (member sym '("or" "and" "cond" "if")) (+ (length sym) 2) 2)))) (if (= cursor-pos (length cur-line)) (begin (set! cur-line (format #f "~A~NC" cur-line spaces #\space)) (set! cursor-pos (length cur-line))) (begin (set! cur-line (format #f "~A~NC~A" (substring cur-line 0 cursor-pos) spaces #\space (substring cur-line (+ cursor-pos 1)))) (set! cursor-pos (+ cursor-pos spaces)))))))))) ;; -------- prompt -------- (define (original-prompt num) (set! prompt-string (format #f "<~D> " num)) (set! prompt-length (length prompt-string))) ;; -------- vt100 -------- (define (bold text) (format #f "~C[1m~A~C[0m" #\escape text #\escape)) (define (red text) (format #f "~C[31m~A~C[0m" #\escape text #\escape)) ; black=30, green=32, yellow=33, blue=34 (define* (rgb text (r 0) (g 0) (b 0) all-colors) (if all-colors (format #f "~C[38;5;~Dm~A~C[0m" #\escape (+ 16 (* 36 (round (* r 5))) (* 6 (round (* g 5))) (round (* b 5))) text #\escape) (format #f "~C[~Dm~A~C[0m" #\escape (+ 30 (ash (round b) 2) (ash (round g) 1) (round r)) text #\escape))) (define (move-cursor y x) (format *stderr* "~C[~D;~DH" #\escape y x)) (define (cursor-coords) (let* ((c (string #\null #\null)) (cc (string->c-pointer c)) (terminal-fd (fileno stdin))) (format *stderr* "~C[6n" #\escape) (do ((b (read terminal-fd cc 1) (read terminal-fd cc 1))) ((char=? (c 0) #\escape))) (read terminal-fd cc 1) (and (char=? (c 0) #\[) (let ((y 0) (x 0)) (do ((b (read terminal-fd cc 1) (read terminal-fd cc 1))) ((not (char-numeric? (c 0)))) (set! y (+ (* 10 y) (- (char->integer (c 0)) (char->integer #\0))))) (and (char=? (c 0) #\;) (do ((b (read terminal-fd cc 1) (read terminal-fd cc 1))) ((not (char-numeric? (c 0))) (and (char=? (c 0) #\R) (cons x y))) (set! x (+ (* 10 x) (- (char->integer (c 0)) (char->integer #\0)))))))))) (define (cursor-bounds) (let ((coords (cursor-coords))) (set! prompt-col (car coords)) (set! prompt-row (cdr coords)) (move-cursor 4000 4000) (let ((bounds (cursor-coords))) (move-cursor (cdr coords) (car coords)) (set! last-col (car bounds)) (set! last-row (cdr bounds))))) ;; to enable mouse click coords (in xterm anyway), (format *stderr* "~C[?9h" #\escape) ;; disable: (format *stderr* "~C[?9l" #\escape) ;; while enabled, mouse selection instead sends coords to repl (so it's annoying) ;; also it's sticky! exit repl does not clear this flag so mouse is effectively dead ;; upon click, we get ESC [ M bxy -- need to poll for this? ;; -------- display -------- (define (display-prompt) (format *stderr* "~A" prompt-string)) (define (new-prompt) (set! cur-line "") (set! cursor-pos 0) (set! cur-row 0) (set! prev-line ()) ((*repl* 'prompt) (+ (length histtop) 1)) (display-prompt) (cursor-bounds)) (define (display-line start end) ;; if a line wraps, it will confuse the redisplay/cursor positioning code. so truncate the display (let ((line-len (+ (- end start) 1 prompt-length))) (if (>= line-len last-col) (set! end (- end (- line-len last-col))))) (if (and red-par-pos (<= start red-par-pos) (< red-par-pos end)) (string-append (if (zero? start) (format #f "~A" prompt-string) (format #f "~NC" prompt-length #\space)) (if (= start red-par-pos) (format #f "~A~A" (bold (red "(")) (substring cur-line (+ start 1) end)) (format #f "~A~A~A" (substring cur-line start red-par-pos) (bold (red "(")) (substring cur-line (+ red-par-pos 1) end)))) (if (zero? start) (format #f "~A~A" prompt-string (substring cur-line 0 end)) (format #f "~NC~A" prompt-length #\space (substring cur-line start end))))) (define (display-cursor) (let ((row 0) (start 0) (len (length cur-line))) (do ((i 0 (+ i 1))) ((or (= i len) (= i cursor-pos)) (move-cursor (+ prompt-row row) (+ prompt-col (- cursor-pos start)))) (when (char=? (cur-line i) #\newline) (set! row (+ row 1)) (set! start (+ i 1)))))) (define (display-lines) (move-cursor prompt-row 0) (format *stderr* "~C[J" #\escape) (let ((len (length cur-line)) (new-line "")) (let ((line-end 0)) (do ((i 0 (+ line-end 2))) ((> i len)) (set! line-end (end-of-line i)) (set! new-line (string-append new-line (display-line i (min (+ line-end 2) len)))))) (format *stderr* "~A" new-line) (display-cursor))) ;; -------- help/debugging -------- (define (one-line text) (if (string? text) (let ((ntext (copy text))) (do ((i 0 (+ i 1))) ((= i (length ntext)) ntext) (if (char=? (ntext i) #\newline) (set! (ntext i) #\|)))) text)) (define (help c) (when (pair? (*repl* 'helpers)) (let ((coords (cursor-coords)) (col (floor (/ last-col 2)))) (move-cursor 1 col) (format *stderr* "+~NC" (- col 2) #\-) (do ((i 2 (+ i 1)) ; put box in top right corner so we don't get trailing output as we scroll (lst (*repl* 'helpers) (cdr lst))) ((null? lst)) (let ((str ((car lst) c))) (move-cursor i col) (format *stderr* "~C[K| ~A" #\escape (if (> (length str) col) (substring str 0 (- col 1)) str)))) (move-cursor (+ 2 (length (*repl* 'helpers))) col) (format *stderr* "+~NC" (- col 2) #\-) (move-cursor (cdr coords) (car coords))))) (define (debug-help) (set! (*repl* 'helpers) (list (lambda (c) (format #f "cursor: ~A, ~C, line: ~S" cursor-pos (if (> (length cur-line) 0) (let ((c (cur-line (max 0 (min cursor-pos (- (length cur-line) 1)))))) (if (char=? c #\newline) #\| c)) #\space) (one-line cur-line))) (lambda (c) (format #f "len: ~D, selection: ~S, previous: ~S" (length cur-line) (one-line selection) (if (pair? prev-line) (one-line (cdar prev-line)) ()))) (lambda (c) (format #f "cur-row: ~A, prompt-row: ~A" cur-row prompt-row)) (lambda (c) (format #f "c: ~S ~D, start: ~A, end: ~A" (object->string c #t) (char->integer c) (start-of-line cursor-pos) (end-of-line cursor-pos)))))) ;; -------- keymap(s) -------- (define meta-keymap-functions (make-vector 256)) (define keymap-functions (make-vector 256 #f)) (define keymap (dilambda (lambda (c) (cond ((char? c) (keymap-functions (char->integer c))) ((integer? c) (keymap-functions c)) ((string? c) (if (= (length c) 1) (keymap-functions (char->integer (c 0))) (if (and (= (length c) 2) (char=? (c 0) #\escape)) (meta-keymap-functions (char->integer (c 1))) (lambda (c) #t)))) (else (error 'wrong-type-arg "keymap takes a character or string argument")))) (lambda (c f) (cond ((char? c) (set! (keymap-functions (char->integer c)) f)) ((integer? c) (set! (keymap-functions c) f)) ((string? c) (if (= (length c) 1) (set! (keymap-functions (char->integer (c 0))) f) (if (and (= (length c) 2) (char=? (c 0) #\escape)) (set! (meta-keymap-functions (char->integer (c 1))) f)))) (else (error 'wrong-type-arg "set! keymap takes a character or string first argument")))))) (define C-a 1) ; #\x01 etc (define C-b 2) (define C-d 4) (define C-e 5) (define C-f 6) (define C-h 8) (define C-k 11) (define C-l 12) ;(define C-m 13) ; #\return -- Enter handles this case (crlf?) (define C-n 14) (define C-o 15) (define C-p 16) ;(define C-r 18) (define C-t 20) (define C-y 25) (define C-_ 31) (define Tab 9) (define Enter 10) ; #\linefeed (define Backspace 127) (define Escape 27) ; #\escape (define (end-of-line pos) ; prompt or #\newline mark the line boundary (let ((len (length cur-line))) (do ((i (max 0 (min pos len)) (+ i 1))) ((or (>= i len) (char=? (cur-line i) #\newline)) (if (>= i len) len (max 0 (- i 1))))))) (define (start-of-line pos) (if (<= pos 0) 0 (do ((i (min pos (- (length cur-line) 1)) (- i 1))) ((or (zero? i) (char=? (cur-line i) #\newline)) (if (zero? i) 0 (+ i 1)))))) (define (count-newlines line) (let ((len (length line)) (newlines 0)) (do ((i 0 (+ i 1))) ((= i len) newlines) (if (char=? (cur-line i) #\newline) (set! newlines (+ newlines 1)))))) (define (append-newline) (set! cur-line (string-append cur-line (string #\space #\newline))) (set! cursor-pos (length cur-line)) (when (= last-row (+ prompt-row cur-row)) (format *stderr* "~%") (set! prompt-row (- prompt-row 1))) (set! cur-row (+ cur-row 1))) (define (word-break pos) ; assume we're at the start of a word (let ((len (length cur-line))) (let loop ((i pos)) (if (or (>= i len) (not (or (char-alphabetic? (cur-line i)) (char-numeric? (cur-line i))))) i (loop (+ i 1)))))) (define (save-line) (set! prev-line (cons (cons cursor-pos (copy cur-line)) prev-line))) (let ((main-keyfunc (lambda (c) (if (<= chars 1) (save-line)) (if (= cursor-pos (length cur-line)) (set! cur-line (string-append cur-line (string c))) (if (= cursor-pos 0) (set! cur-line (string-append (string c) cur-line)) (set! cur-line (string-append (substring cur-line 0 cursor-pos) (string c) (substring cur-line cursor-pos))))) (set! cursor-pos (+ cursor-pos 1)) (set! m-p-pos 0))) (no-op-keyfunc (lambda (c) #t))) (do ((i 0 (+ i 1))) ((= i 32)) (set! (keymap-functions i) no-op-keyfunc)) (do ((i 32 (+ i 1))) ((= i 256)) (set! (keymap-functions i) main-keyfunc)) (do ((i 0 (+ i 1))) ((= i 256)) (set! (meta-keymap-functions i) no-op-keyfunc))) ;; -------- cursor movement (set! (keymap-functions C-a) (lambda (c) (set! cursor-pos (start-of-line cursor-pos)) 'just-cursor)) (set! (keymap-functions C-e) (lambda (c) (set! cursor-pos (end-of-line cursor-pos)) 'just-cursor)) (set! (keymap-functions C-b) (lambda (c) (when (> cursor-pos 0) (set! cursor-pos (- cursor-pos 1)) (if (char=? (cur-line cursor-pos) #\newline) (set! cursor-pos (- cursor-pos 1)))) 'just-cursor)) (set! (keymap-functions C-f) (lambda (c) (let ((len (length cur-line))) (when (< cursor-pos len) (set! cursor-pos (+ cursor-pos 1)) (if (and (< cursor-pos len) (char=? (cur-line cursor-pos) #\newline)) (set! cursor-pos (+ cursor-pos 1))))) 'just-cursor)) (set! (keymap-functions C-p) (lambda (c) ;; try to find corresponding column in previous line (let ((start (start-of-line cursor-pos))) (when (positive? start) (let ((upstart (start-of-line (- start 2))) (upend (end-of-line (- start 2))) (line-pos (- cursor-pos start))) (set! cursor-pos (min (+ upstart line-pos) upend))))) 'just-cursor)) (set! (keymap-functions C-n) (lambda (c) ;; try to find corresponding column in next line (let ((start (start-of-line cursor-pos)) (len (length cur-line)) (next-start (+ (end-of-line cursor-pos) 1))) ; should be at #\newline (if any) (if (> len next-start) ; not already at last line (let ((next-end (end-of-line (+ next-start 1))) (line-pos (- cursor-pos start))) (set! cursor-pos (min (+ next-start 1 line-pos) next-end))))) 'just-cursor)) (set! (keymap-functions C-l) (lambda (c) (format *stderr* "~C[H~C[J" #\escape #\escape) (new-prompt))) ;; -------- deletion (set! (keymap-functions C-d) (lambda (c) (let ((len (length cur-line))) (when (< cursor-pos len) (save-line) (do ((i cursor-pos (+ i 1))) ((>= i (- len 1))) (set! (cur-line i) (cur-line (+ i 1)))) (set! cur-line (substring cur-line 0 (- len 1))))))) (set! (keymap-functions C-h) (lambda (c) (when (positive? cursor-pos) (save-line) (let ((len (length cur-line))) (set! cursor-pos (- cursor-pos 1)) (do ((i cursor-pos (+ i 1))) ((>= i (- len 1))) (set! (cur-line i) (cur-line (+ i 1)))) (set! cur-line (substring cur-line 0 (- len 1))))))) (set! (keymap-functions Backspace) (keymap-functions C-h)) (set! (keymap-functions C-k) (lambda (c) (let ((len (length cur-line))) (when (< cursor-pos len) (save-line) (let ((end (end-of-line cursor-pos))) (if (= end len) (begin (set! selection (substring cur-line cursor-pos)) (set! cur-line (substring cur-line 0 cursor-pos))) (if (or (= cursor-pos end) ; delete following newline (char=? (cur-line cursor-pos) #\newline)) (set! cur-line (string-append (substring cur-line 0 cursor-pos) (substring cur-line (+ cursor-pos 1)))) (begin (set! selection (substring cur-line cursor-pos (+ end 1))) (set! cur-line (string-append (substring cur-line 0 cursor-pos) (substring cur-line (+ end 1)))) )))))))) ;; -------- undo/selection (set! (keymap-functions C-y) (lambda (c) (when selection (save-line) (if (zero? cursor-pos) (set! cur-line (string-append selection cur-line)) (if (>= cursor-pos (length cur-line)) (set! cur-line (string-append cur-line selection)) (set! cur-line (string-append (substring cur-line 0 cursor-pos) selection (substring cur-line cursor-pos))))) (set! cursor-pos (+ cursor-pos (length selection)))))) (set! (keymap-functions C-_) (lambda (c) (when (pair? prev-line) (set! cur-line (cdar prev-line)) (set! cursor-pos (caar prev-line)) (set! prev-line (cdr prev-line))))) ;; -------- add newline (set! (keymap-functions C-o) (lambda (c) (if (= cursor-pos 0) (set! cur-line (string-append (string #\space #\newline) cur-line)) (if (>= cursor-pos (length cur-line)) (set! cur-line (string-append cur-line (string #\space #\newline))) (if (char=? (cur-line (- cursor-pos 1)) #\newline) (set! cur-line (string-append (substring cur-line 0 cursor-pos) (string #\space #\newline) (substring cur-line cursor-pos))) (set! cur-line (string-append (substring cur-line 0 cursor-pos) (if (char=? (cur-line (+ cursor-pos 1)) #\newline) (string #\space #\newline #\space) (string #\space #\newline)) (substring cur-line (+ cursor-pos 1))))))) (when (= last-row (+ prompt-row cur-row)) (set! prompt-row (- prompt-row 1)) (display-lines)))) ;; -------- transpose (set! (keymap-functions C-t) (lambda (c) (let ((end (end-of-line cursor-pos))) (save-line) (let ((cur (if (>= cursor-pos end) (- cursor-pos 1) cursor-pos))) (if (positive? cur) (let ((tmp-c (cur-line (- cur 1)))) (set! (cur-line (- cur 1)) (cur-line cur)) (set! (cur-line cur) tmp-c) (set! cursor-pos (+ cur 1)))))))) ;; -------- indentation/completion (set! (keymap-functions Tab) (lambda (c) ;; if user pastes in a selection, it may have embedded tabs which are just spacing, ;; not requests for filename completion! We'll try to catch this case by assuming ;; that a selection will not be the single character #\tab (if (> chars 1) (begin (set! cur-line (string-append cur-line " ")) (set! cursor-pos (+ cursor-pos 4))) (let ((start (start-of-line cursor-pos)) (end (end-of-line cursor-pos)) (completion #f)) (if (and (positive? start) (= end start)) (indent start) (if (= cursor-pos end) (let ((loc (do ((i (- end 1) (- i 1))) ((or (< i 0) (char-whitespace? (cur-line i)) (member (cur-line i) '(#\( #\' #\" #\)) eqv?)) i)))) (if (< loc 0) (set! completion (symbol-completion cur-line)) (if (char=? (cur-line loc) #\") (set! completion (filename-completion (substring cur-line (+ loc 1)))) (set! completion (symbol-completion (substring cur-line (+ loc 1)))))) (when (and completion (> (length completion) (- end loc 1))) (save-line) (if (= end (length cur-line)) (set! cur-line (string-append (substring cur-line 0 (+ loc 1)) completion)) (set! cur-line (string-append (substring cur-line 0 (+ loc 1)) completion (substring cur-line (+ end 1))))) (set! cursor-pos (end-of-line cursor-pos)))))))))) ;; -------- evaluation/multiline (set! (keymap-functions Enter) (lambda (c) (call-with-exit (lambda (return) (let ((len (length cur-line))) (do ((i 0 (+ i 1))) ; check for just whitespace ((or (= i len) (not (char-whitespace? (cur-line i)))) (when (= i len) (append-newline) (return)))) (set! red-par-pos #f) (if (or (= chars 1) (not (= input-fd terminal-fd))) (display-lines)) (catch #t (lambda () ;; we want to add cur-line (copied) to the history buffer ;; unless it is an on-going edit (missing close paren) (catch 'string-read-error (lambda () (set! cursor-pos len) (if (or (= chars 1) (not (= input-fd terminal-fd))) (display-lines)) (set! (history) (copy cur-line)) (set! m-p-pos 0) (with-repl-let (lambda () ;; get the newline out if the expression does not involve a read error (let ((form (with-input-from-string cur-line #_read))) ; not libc's read (newline *stderr*) (let ((val (eval form (*repl* 'top-level-let)))) (if unbound-case (set! unbound-case #f) (begin (format *stderr* "~S~%" val) (set! ((*repl* 'top-level-let) '**) val)))))))) (lambda (type info) (pop-history) ; remove last history entry (append-newline) (return)))) (lambda (type info) (format *stderr* "~A: " (red "error")) (apply format *stderr* info) (newline *stderr*))) (push-line (copy cur-line)) (new-prompt)))))) ;; -------- escaped (Meta/Alt/arrow) keys (set! (keymap-functions Escape) (lambda (esc) (let ((chr (next-char))) ((meta-keymap-functions (char->integer chr)) chr)))) (set! (meta-keymap-functions (char->integer #\[)) (lambda (c) (let ((chr (next-char))) (case chr ((#\A) ((keymap-functions C-p) C-p)) ; arrow keys ((#\B) ((keymap-functions C-n) C-n)) ((#\C) ((keymap-functions C-f) C-f)) ((#\D) ((keymap-functions C-b) C-b)))))) (let () ;; Meta key is a problem on the Mac, so I'll package these for easier disposal (define (fixup-new-line) (set! cursor-pos (length cur-line)) (let ((newlines (count-newlines cur-line))) (when (< last-row (+ prompt-row newlines)) (format *stderr* "~NC" (- (+ prompt-row newlines) last-row) #\newline) (set! prompt-row (- prompt-row newlines))) (set! cur-row newlines))) (define (get-previous-line c) ; get earlier line indexed by numeric arg (let ((len (length histtop))) (let ((pos (or (string->number cur-line) len))) (set! pos (min len (max pos 1))) (set! cur-line (histtop (- pos 1))) (fixup-new-line)))) (define (move-forward-in-history c) (set! m-p-pos (min 0 (+ m-p-pos 1))) (when (positive? (length (history m-p-pos))) (set! cur-line (history m-p-pos)) (fixup-new-line))) (define (move-backward-in-history c) (let ((old-index m-p-pos)) (when (and (zero? m-p-pos) (> (length cur-line) 0)) (set! (history) cur-line) (set! m-p-pos -1)) (set! m-p-pos (max (- m-p-pos 1) (- histsize))) (if (positive? (length (history m-p-pos))) (begin (set! cur-line (history m-p-pos)) (fixup-new-line)) (set! m-p-pos old-index)))) (define (go-to-start c) (set! cursor-pos 0) 'just-cursor) (define (go-to-end c) (set! cursor-pos (length cur-line)) 'just-cursor) (define (capitalize c) (let ((len (length cur-line))) (let loop ((i cursor-pos)) (if (< i len) (if (char-alphabetic? (cur-line i)) (begin (save-line) (set! (cur-line i) (char-upcase (cur-line i))) (set! cursor-pos (word-break i))) (loop (+ i 1))))))) (define (upper-case c) (let ((len (length cur-line))) (do ((i cursor-pos (+ i 1))) ((or (= i len) (char-alphabetic? (cur-line i))) (when (< i len) (save-line) (do ((k i (+ k 1))) ((or (= k len) (not (char-alphabetic? (cur-line k)))) (set! cursor-pos k)) (set! (cur-line k) (char-upcase (cur-line k))))))))) (define (lower-case c) (let ((len (length cur-line))) (do ((i cursor-pos (+ i 1))) ((or (= i len) (char-alphabetic? (cur-line i))) (when (< i len) (save-line) (do ((k i (+ k 1))) ((or (= k len) (not (char-alphabetic? (cur-line k)))) (set! cursor-pos k)) (set! (cur-line k) (char-downcase (cur-line k))))))))) (set! (meta-keymap-functions (char->integer #\p)) move-backward-in-history) (set! (meta-keymap-functions (char->integer #\n)) move-forward-in-history) (set! (meta-keymap-functions (char->integer #\.)) get-previous-line) (set! (meta-keymap-functions (char->integer #\<)) go-to-start) (set! (meta-keymap-functions (char->integer #\>)) go-to-end) (set! (meta-keymap-functions (char->integer #\c)) capitalize) (set! (meta-keymap-functions (char->integer #\u)) upper-case) (set! (meta-keymap-functions (char->integer #\l)) lower-case) ) ;; -------- terminal setup -------- (define* (run file) (let ((saved #f) (tty #t)) ;; we're in libc here, so exit is libc's exit! (define (tty-reset no) (if tty (tcsetattr terminal-fd TCSAFLUSH saved)) (if (not (equal? input-fd terminal-fd)) (close input-fd)) (#_exit)) (varlet (*repl* 'top-level-let) :exit (let ((documentation "(exit) resets the repl tty and exits the repl")) (lambda () (newline *stderr*) (tty-reset 0)))) ;; check for dumb terminal (if (or (zero? (isatty terminal-fd)) ; not a terminal -- input from pipe probably (string=? (getenv "TERM") "dumb")) ; no vt100 codes -- emacs shell for example (let ((buf (c-pointer->string (calloc 512 1) 512))) (set! tty #f) (format *stderr* "> ") (do ((b (fgets buf 512 stdin) (fgets buf 512 stdin))) ((zero? (length b)) (#_exit)) (let ((len (strlen buf))) (when (positive? len) (do ((i 0 (+ i 1))) ((or (not (char-whitespace? (buf i))) (= i len)) (when (< i len) (with-repl-let (lambda () (catch #t (lambda () (format *stderr* "~S~%" (eval-string (substring buf 0 (- (strlen buf) 1)) (*repl* 'top-level-let)))) (lambda (type info) (format *stderr* "error: ") (apply format *stderr* info) (newline *stderr*))))) (format *stderr* "> "))))))))) ;; not a pipe or a dumb terminal -- hopefully all others accept vt100 codes (let ((buf (termios.make)) (read-size 128)) (set! next-char ; this indirection is needed if user pastes the selection into the repl (let* ((c (make-string read-size #\null)) (cc (string->c-pointer c)) (ctr 0)) (lambda () (call-with-exit (lambda (return) (when (>= ctr chars) (set! ctr 0) (set! chars (read input-fd cc read-size)) (if (= chars 0) (tty-reset terminal-fd)) (when (= chars read-size) ;; concatenate buffers until we get the entire selection (let ((str (substring c 0 read-size))) (let reading ((num (read input-fd cc read-size))) (set! str (string-append str (substring c 0 num))) (set! chars (+ chars num)) (if (= num read-size) (reading (read input-fd cc read-size)))) ;; look for simple cut/paste -- no control chars etc (when (= input-fd terminal-fd) (let ((bcksp (integer->char 127)) (ok-chars (list #\newline #\linefeed #\return #\tab))) (do ((i 0 (+ i 1))) ((or (= i chars) (char>=? (str i) bcksp) (and (char max-cols (- last-col prompt-length)) (let ((old-len ((funclet pretty-print) '*pretty-print-length*))) (set! ((funclet pretty-print) '*pretty-print-length*) (- last-col prompt-length 2)) (set! cur-line (with-output-to-string (lambda () (pretty-print (with-input-from-string cur-line #_read))))) (set! ((funclet pretty-print) '*pretty-print-length*) old-len))) (set! cursor-pos (length cur-line)) (set! chars 0) (set! ctr 1) (display-lines) (return #\newline))))))) (set! c str) (set! cc (string->c-pointer c)) ;; avoid time-consuming redisplays. We need to use a recursive call on next-char here ;; since we might have multi-char commands (embedded #\escape -> meta, etc) ;; actually, the time is not the repl's fault -- xterm seems to be waiting ;; for the window manager or someone to poke it -- if I move the mouse, ;; I get immediate output. I also get immediate output in any case in OSX. ;; valgrind and ps say we're not computing, we're just sitting there. (catch #t (lambda () (do ((ch (next-char) (next-char))) ((= ctr (- chars 1)) (set! chars 0) (display-lines) (return ch)) ((keymap-functions (char->integer ch)) ch))) (lambda (type info) (set! chars 0) (move-cursor prompt-row prompt-col) (format *stderr* "internal error: ") (apply format *stderr* info) (newline *stderr*) (format *stderr* "line ~A: ~A~%" ((owlet) 'error-line) ((owlet) 'error-code)) (set! chars 0) (set! ctr 0) (new-prompt) (return #\null)))))) (let ((result (c ctr))) (set! ctr (+ ctr 1)) result)))))) (set! input-fd (if (not file) terminal-fd (open file O_RDONLY 0))) (set! saved (termios.make)) (tcgetattr terminal-fd saved) (tcgetattr terminal-fd buf) (termios.set_c_lflag buf (logand (termios.c_lflag buf) (lognot (logior ECHO ICANON)))) (termios.set_c_cc buf VMIN 1) (termios.set_c_cc buf VTIME 0) (when (negative? (tcsetattr terminal-fd TCSAFLUSH buf)) (tty-reset terminal-fd)) ;; -------- the repl -------- (display-prompt) (cursor-bounds) ;; (debug-help) ;; (history-help) (do () (all-done (set! all-done #f)) ; clear for next call (catch #t (lambda () (let ((chr (next-char))) (let ((res ((keymap-functions (char->integer chr)) chr)) (last-pos red-par-pos)) (check-parens) (if (or last-pos red-par-pos (not (eq? res 'just-cursor))) (display-lines) (display-cursor))) (help chr))) (lambda (type info) (move-cursor prompt-row prompt-col) (format *stderr* "internal error: ") (apply format *stderr* info) (format *stderr* "~%line ~A: ~A~%" ((owlet) 'error-line) ((owlet) 'error-code)) (set! chars 0) (new-prompt))))))) (curlet)))))) (define (save-repl) (call-with-output-file "save.repl" (lambda (p) (format p "(for-each~%~NC~ (lambda (f)~%~NC~ (if (not (provided? f))~%~NC~ (let ((autofile (*autoload* f)))~%~NC~ (if (and autofile (file-exists? autofile))~%~NC(load autofile)))))~%~NC~W)~%~%" 2 #\space 4 #\space 8 #\space 10 #\space 14 #\space 2 #\space *features*) (format p "(with-let (*repl* 'repl-let)~%") (((*repl* 'repl-let) 'write-history) p 2) (format p ")~%~%") (format p "~W" (*repl* 'top-level-let))))) (define (restore-repl) (set! (*repl* 'top-level-let) (load "save.repl"))) ;; I think this could be a merge rather than a reset by using (with-let top-level-let (load ...)) (set! keymap (repl-let 'keymap)) (set! history (repl-let 'history)) (set! history-size (repl-let 'history-size)) (set! save-history (repl-let 'save-history)) (set! restore-history (repl-let 'restore-history)) (set! prompt (repl-let 'original-prompt)) (set! run (repl-let 'run)) (curlet)))) ;; ((*repl* 'run)) ;;; -------------------------------------------------------------------------------- (autoload 'lint "lint.scm") (autoload 'pretty-print "write.scm") (autoload '*libm* "libm.scm") (autoload '*libgsl* "libgsl.scm") #| (define pwd (let ((pd (lambda args ((*libc* 'getcwd) (make-string 256 #\null) 256)))) (openlet (inlet 'object->string pd ; pwd (repl calls object->string) 'let-ref-fallback pd)))) ; (pwd) (repl calls let-ref-fallback method) ;; > pwd ;; /home/bil/cl (define date (let ((pd (lambda args (with-let (sublet *libc*) (let ((timestr (make-string 128))) (let ((len (strftime timestr 128 "%a %d-%b-%Y %H:%M:%S %Z" (localtime (time.make (time (c-pointer 0))))))) (substring timestr 0 len))))))) (openlet (inlet 'object->string pd 'let-ref-fallback pd)))) |# ;; cd needs to be implemented (define cd (openlet (inlet 'object->string (lambda args (let ((line ((*repl* 'repl-let) 'cur-line))) ((*libc* 'chdir) (do ((i 3 (+ i 1))) ((or (not (char-whitespace? (line i))) (= i (length line))) (substring ((*repl* 'repl-let) 'cur-line) i)))) ((*libc* 'getcwd) (make-string 256 #\null) 256))) 'let-ref-fallback (lambda (obj str) ; let-ref-fallback's first arg will be cd: (cd "..") ((*libc* 'chdir) str) ((*libc* 'getcwd) (make-string 256 #\null) 256))))) ;; > cd .. ;; /home/bil ;; > cd cl ;; /home/bil/cl #| (define-macro (make-command name) `(define ,name (openlet (inlet 'object->string (lambda args (system ((*repl* 'repl-let) 'cur-line) #t)))))) ;; (make-command ls) |# (define-macro (time expr) (let ((start (gensym))) `(let ((,start ((*libc* 'gettimeofday)))) ,expr (let ((end ((*libc* 'gettimeofday)))) (+ (- (car end) (car ,start)) ; seconds (* 0.000001 (- (cadr end) (cadr ,start)))))))) (define* (apropos name (e (*repl* 'top-level-let))) (define (levenshtein s1 s2) (let ((l1 (length s1)) (l2 (length s2))) (cond ((zero? l1) l2) ((zero? l2) l1) (else (let ((distance (make-vector (list (+ l2 1) (+ l1 1)) 0))) (do ((i 0 (+ i 1))) ((> i l1)) (set! (distance 0 i) i)) (do ((i 0 (+ i 1))) ((> i l2)) (set! (distance i 0) i)) (do ((i 1 (+ i 1))) ((> i l2)) (do ((j 1 (+ j 1))) ((> j l1)) (let ((c1 (+ (distance i (- j 1)) 1)) (c2 (+ (distance (- i 1) j) 1)) (c3 (+ (distance (- i 1) (- j 1)) (if (char=? (s2 (- i 1)) (s1 (- j 1))) 0 1)))) (set! (distance i j) (min c1 c2 c3))))) (distance l2 l1)))))) (define* (make-full-let-iterator lt (stop (rootlet))) ; walk the entire let chain (if (eq? stop lt) (make-iterator lt) (letrec ((iterloop (let ((iter (make-iterator lt)) (iterator? #t)) (lambda () (let ((result (iter))) (if (and (eof-object? result) (iterator-at-end? iter)) (if (eq? stop (iterator-sequence iter)) result (begin (set! iter (make-iterator (outlet (iterator-sequence iter)))) (iterloop))) result)))))) (make-iterator iterloop)))) (let ((ap-name (if (string? name) name (if (symbol? name) (symbol->string name) (error 'wrong-type-arg "apropos argument 1 should be a string or a symbol")))) (ap-env (if (let? e) e (error 'wrong-type-arg "apropos argument 2 should be an environment")))) (let ((strs ()) (min2 (floor (log (length ap-name) 2))) (have-orange (string=? ((*libc* 'getenv) "TERM") "xterm-256color"))) (for-each (lambda (binding) (if (pair? binding) (let ((symbol-name (symbol->string (car binding)))) (if (string-position ap-name symbol-name) (set! strs (cons (cons binding 0) strs)) (let ((distance (levenshtein ap-name symbol-name))) (if (< distance min2) (set! strs (cons (cons binding distance) strs)))))))) (make-full-let-iterator ap-env)) (if (pair? strs) (begin (for-each (lambda (b) (format *stderr* (if (zero? (cdr b)) "~C[1m~A~C[0m: ~S~%" ; black if exact match somewhere (if (or (< (cdr b) 2) (not have-orange)) "~C[31m~A~C[0m: ~S~%" ; red for near miss "~C[38;5;208m~A~C[0m: ~S~%")) ; orange for less likely choices #\escape (caar b) #\escape (if (procedure? (cdar b)) (let ((doc (procedure-documentation (cdar b)))) (if (and (string? doc) (positive? (length doc))) doc 'procedure)) (cdar b)))) (sort! strs (lambda (a b) (stringstring (caar a)) (symbol->string (caar b)))))) '----) 'no-match)))) ;;; -------------------------------------------------------------------------------- #| to work in a particular environment: (set! (*repl* 'top-level-let) (sublet (rootlet) :** #f)) ; or any other like *libc* now (define g 43) puts g in the new top-level-let, so ((rootlet) 'g) -> #, and ((*repl* 'top-level-let) 'g) -> 43 (= g in repl of course) to start with a fresh top-level, just set top-level-let to (sublet (rootlet)) again. to add/change keymap entry (using sublet here to protect against inadvertent changes to the repl). (set! ((*repl* 'keymap) (integer->char 17)) ; C-q to quit and return to caller (lambda (c) (set! ((*repl* 'repl-let) 'all-done) #t))) (set! ((*repl* 'keymap) (integer->char 12)) ; C-l will expand to "(lambda " at the cursor (lambda (c) (with-let (sublet (*repl* 'repl-let)) (if (zero? cursor-pos) (set! cur-line (string-append "(lambda " cur-line)) (if (>= cursor-pos (length cur-line)) (set! cur-line (string-append cur-line "(lambda ")) (set! cur-line (string-append (substring cur-line 0 cursor-pos) "(lambda " (substring cur-line cursor-pos))))) (set! cursor-pos (+ cursor-pos (length "(lambda ")))))) change the prompt: (set! (*repl* 'prompt) (lambda (num) (with-let (*repl* 'repl-let) (set! prompt-string "scheme> ") (set! prompt-length (length prompt-string))))) red lambda prompt: (set! (*repl* 'prompt) (lambda (num) (with-let (*repl* 'repl-let) (set! prompt-string (bold (red (string #\xce #\xbb #\> #\space)))) (set! prompt-length 3)))) ; until we get unicode length calc to post a help string (kinda tedious, but the helper list is aimed more at posting variable values): (set! (*repl* 'helpers) (list (lambda (c) (let ((sym (with-let (sublet (*repl* 'repl-let)) (let ((len (length cur-line))) (let loop ((i (min (- len 1) cursor-pos))) (and (not (negative? i)) (if (char=? (cur-line i) #\() (let loop1 ((k (+ i 1))) (and (< k len) (if (not (char-alphabetic? (cur-line k))) (and (> k (+ i 1)) (string->symbol (substring cur-line (+ i 1) k))) (loop1 (+ k 1))))) (loop (- i 1))))))))) (if sym (let ((str (help sym))) (if str (substring (help sym) 0 (min (length str) 40)) "")) ""))))) ;; function keys: (set! ((*repl* 'keymap) (string #\escape #\[)) (lambda (c) (with-let (sublet (*repl* 'repl-let)) (let ((next (next-char))) (case next ((#\A) ((keymap-functions C-p) C-p)) ((#\B) ((keymap-functions C-n) C-n)) ((#\C) ((keymap-functions C-f) C-f)) ((#\D) ((keymap-functions C-b) C-b)) ((#\1) ; on my system F1 is esc [ 1 1 ~, F2 esc [ 1 2 ~, etc (but they skip F6?) (let ((n (- (char->integer (next-char)) (char->integer #\0)))) (next-char) ; throw away the tilde (set! cur-line (string-append cur-line (format #f "--F~D!--" n)))))))))) ;; this actually works but doesn't echo the filename correctly and the cursor is off during the filename processing (set! ((*repl* 'keymap) (integer->char 24)) ; C-x (lambda (c) (with-let (sublet (*repl* 'repl-let)) (let ((next (next-char))) (when (char=? next (integer->char 6)) ; C-f (format *stderr* "~%load: ") ;; now recursive call: prompt="load: " (let ((old-prompt (*repl* 'prompt)) (old-cur-line cur-line) (old-cursor-pos cursor-pos) (old-enter-func (keymap-functions 10)) (filename #f)) (set! (*repl 'prompt) (lambda (num) (with-let (*repl* 'repl-let) (set! prompt-string "load: ") (set! prompt-length 6)))) (set! cur-line "") (set! cursor-pos 0) (set! (keymap-functions 10) (lambda (c) (set! filename cur-line) (set! (*repl* 'prompt) old-prompt) (set! cur-line old-cur-line) (set! cursor-pos old-cursor-pos) (set! (keymap-functions 10) old-enter-func))) (do ((c (next-char) (next-char))) ((string? filename)) ((keymap-functions (char->integer c)) c) (display-lines)) (load filename))))))) |# ;; unicode someday: I think all we need is unicode_string_length and index into unicode string (set/ref) ;; scroll past top line? *repl* snd-16.1/env.rb0000644000076400007640000005247512434353162011470 0ustar bilbil# env.rb -- snd/env.scm # Translator/Author: Michael Scholz # Created: 03/09/20 23:24:17 # Changed: 14/11/13 04:52:42 # module Env (see env.scm) # envelope_interp(x, en, base) # window_envelope(beg, dur, en) # map_envelopes(en1, en2, &func) # multiply_envelopes(en1, en2) # add_envelopes(en1, en2) # max_envelope(en) # min_envelope(en) # integrate_envelope(en) # envelope_last_x(en) # stretch_envelope(fn, old_att, new_att, old_dec, new_dec) # scale_envelope(en, scale, offset) # reverse_envelope(en) alias envelope_reverse # concatenate_envelopes(*envs) alias envelope_concatenate # repeat_envelope(ur_env, repeats, reflect, x_normalized) alias envelope_repeat # # class Power_env # initialize(*rest) # power_env # power_env_channel(beg, dur, snd, chn, edpos, edname) # # make_power_env(*rest) # power_env(pe) # power_env_channel(pe, beg, dur, snd, chn, edpos) # powenv_channel(envelope, beg, dur, snd, chn, edpos) # # envelope_exp(en, power, xgrid) # rms_envelope(file, *rest) # # envelope_length(en) # normalize_envelope(en, new_max) # x_norm(en, xmax) # # exp_envelope(env, *args) # [by Fernando Lopez-Lezcano (nando@ccrma.stanford.edu)] # db_envelope(env, cutoff, error) # make_db_env(env, *args) # semitones_envelope(env, around, error) # make_semitones_env(env, *args) # octaves_envelope(env, around, error) # make_octaves_env(env, *args) require "clm" module Env add_help(:envelope_interp, "envelope_interp(*args) envelope_interp(x, env, base = 1.0) ==> value of env at x; \ BASE controls connecting segment type: \ envelope_interp(0.3, [0, 0, 0.5, 1, 1, 0]) ==> 0.6") def envelope_interp(x, en, base = 1.0) unless en.empty? en.map! do |y| y.to_f end end if en.empty? 0.0 else if x <= en[0] or en[2..-1].empty? en[1] else if en[2] > x if en[1] == en[3] or base.zero? en[1] else if base == 1.0 en[1] + (x - en[0]) * ((en[3] - en[1]) / (en[2] - en[0])) else en[1] + ((en[3] - en[1]) / (base - 1.0)) * ((base ** ((x - en[0]) / (en[2] - en[0]))) - 1.0) end end else envelope_interp(x, en[2..-1], base) end end end end add_help(:window_envelope, "window_envelope(beg, dur, env) \ Portion of ENV lying between x axis values BEG and DUR: \ window_envelope(1.0, 3.0, [0.0, 0.0, 5.0, 1.0]) ==> [1.0, 0.2, 3.0, 0.6]") def window_envelope(beg, dur, en) unless en.empty? en.map! do |x| x.to_f end end nenv = [] lasty = en.empty? ? 0.0 : en[1] len = en.length 0.step(len - 1, 2) do |i| x = en[i] y = lasty = en[i + 1] if nenv.empty? if x >= beg nenv.push(beg, envelope_interp(beg, en)) unless x == beg if x >= dur return nenv.push(dur, envelope_interp(dur, en)) else nenv.push(x, y) end end end else if x <= dur nenv.push(x, y) return nenv if x == dur else if x > dur return nenv.push(dur, envelope_interp(dur, en)) end end end end nenv.push(dur, lasty) end add_help(:map_envelopes, "map_envelopes(env1, env2, &func) \ Maps FUNC over the breakpoints in ENV1 and ENV2 returning a new envelope.") def map_envelopes(en1, en2, &func) unless en1.empty? en1.map! do |x| x.to_f end end if array?(en2) and (not en2.empty?) en2.map! do |x| x.to_f end end xs = [] at0 = lambda do |e| diff = e.first lastx = e[-2] 0.step(e.length - 1, 2) do |i| x = (e[i] - diff) / lastx xs.push(x) e[i] = x end e end if en1.empty? at0.call(en2) else if en2.empty? at0.call(en1) else ee1 = at0.call(en1) ee2 = at0.call(en2) newe = [] xs.uniq.sort.each do |x| newe.push(x, func.call(envelope_interp(x, ee1), envelope_interp(x, ee2))) end newe end end end add_help(:multiply_envelopes, "multiply_envelopes(env1, env2) \ Multiplies break-points of ENV1 and ENV2 returning a new envelope: \ multiply_envelopes([0, 0, 2, 0.5], [0, 0, 1, 2, 2, 1]) ==> \ [0.0, 0.0, 0.5, 0.5, 1.0, 0.5]") def multiply_envelopes(en1, en2) map_envelopes(en1, en2) do |x, y| x * y end end add_help(:add_envelopes, "add_envelopes(env1, env2) \ Adds break-points of ENV1 and ENV2 returning a new envelope.") def add_envelopes(en1, en2) map_envelopes(en1, en2) do |x, y| x + y end end add_help(:max_envelope, "max_envelope(env) \ Returns max y value in ENV.") def max_envelope(en) mx = en[1].to_f 1.step(en.length - 1, 2) do |i| mx = [mx, en[i]].max.to_f end mx end add_help(:min_envelope, "min_envelope(env) \ Returns min y value in ENV.") def min_envelope(en) mn = en[1].to_f 1.step(en.length - 1, 2) do |i| mn = [mn, en[i]].min.to_f end mn end add_help(:integrate_envelope, "integrate_envelope(env) \ Returns area under ENV.") def integrate_envelope(en) sum = 0.0 0.step(en.length - 3, 2) do |i| sum = sum + (en[i + 1] + en[i + 3]) * (en[i + 2] - en[i]) * 0.5 end sum end add_help(:envelope_last_x, "envelope_last_x(env) \ Returns max x axis break point position.") def envelope_last_x(en) en.empty? ? 0.0 : en[-2] end add_help(:stretch_envelope, "stretch_envelope(fn, old_att, new_att, old_dec, new_dec) \ Takes FN and returns a new envelope based on it but with the attack \ and optionally decay portions stretched or squeezed; \ OLD_ATT is the original x axis attack end point, \ NEW_ATT is where that section should end in the new envelope. \ Similarly for OLD_DEC and NEW_DEC. \ This mimics divseg in early versions of CLM \ and its antecedents in Sambox and Mus10 (linen). stretch_envelope([0, 0, 1, 1], 0.1, 0.2) ==> [0, 0, 0.2, 0.1, 1.0, 1] stretch_envelope([0, 0, 1, 1, 2, 0], 0.1, 0.2, 1.5, 1.6) ==> [0, 0, 0.2, 0.1, 1.1, 1, 1.6, 0.5, 2.0, 0]") def stretch_envelope(fn, old_att = false, new_att = false, old_dec = false, new_dec = false) unless array?(fn) error("%s: need an envelope, %s", get_func_name, fn.inspect) end unless fn.empty? fn.map! do |x| x.to_f end end if old_att and (not new_att) Snd.raise(:wrong_number_of_args, old_att.inspect, "old_att but no new_att?") else if (not new_att) fn else if old_dec and (not new_dec) Snd.raise(:wrong_number_of_args, format("%s %s %s", old_att, new_att, old_dec), "old_dec but no new_dec?") else new_x = x0 = fn[0] last_x = fn[-2] y0 = fn[1] new_fn = [x0, y0] scl = (new_att - x0) / [0.0001, old_att - x0].max if old_dec and old_dec == old_att old_dec = old_dec + 0.000001 * last_x end fn[2..-1].each_pair do |x1, y1| if x0 < old_att and x1 >= old_att y0 = if x1 == old_att y1 else y0 + (y1 - y0) * ((old_att - x0) / (x1 - x0)) end x0 = old_att new_x = new_att new_fn.push(new_x, y0) scl = if old_dec (new_dec - new_att) / (old_dec - old_att) else (last_x - new_att) / (last_x - old_att) end end if old_dec and x0 < old_dec and x1 >= old_dec y0 = if x1 == old_dec y1 else y0 + (y1 - y0) * ((old_dec - x0) / (x1 - x0)) end x0 = old_dec new_x = new_dec new_fn.push(new_x, y0) scl = (last_x - new_dec) / (last_x - old_dec) end if x0 != x1 new_x = new_x + scl * (x1 - x0) new_fn.push(new_x, y1) x0, y0 = x1, y1 end end new_fn end end end end add_help(:scale_envelope, "scale_envelope(env, scale, offset = 0.0) \ Scales y axis values by SCALER and optionally adds OFFSET.") def scale_envelope(en, scale, offset = 0.0) 1.step(en.length - 1, 2) do |i| en[i] = en[i] * scale + offset end en end add_help(:reverse_envelope, "reverse_envelope(env) \ Reverses the breakpoints in ENV.") def reverse_envelope(en1) len = en1.length if len.zero? or len == 2 en1 else en2 = en1.dup xmax = en1[-2] 0.step(len - 2, 2) do |i| en2[-(i + 2)], en2[-(i + 1)] = xmax - en1[i], en1[i + 1] end en2 end end alias envelope_reverse reverse_envelope add_help(:concatenate_envelopes, "concatenate_envelopes(*envs) \ Concatenates its arguments into a new envelope.") def concatenate_envelopes(*envs) if envs.length == 1 envs.first else xoff = 0.0 ren = [] envs.each do |en| (en or []).map! do |x| x.to_f end firstx = en.first if ren[-1] == en[1] xoff -= 0.01 en = en[2..-1] end 0.step(en.length - 1, 2) do |i| ren.push(xoff + (en[i] - firstx), en[i + 1]) end xoff += 0.01 + ren[-2] end ren end end alias envelope_concatenate concatenate_envelopes add_help(:repeat_envelope, "repeat_envelope(ur_env, repeats, reflected = false, \ x_normalized = false) \ Repeats ENV REPEATS times. repeat_envelope([0, 0, 100, 1] 2) ==> [0, 0, 100, 1, 101, 0, 201, 1] If the final y value is different from the first y value, \ a quick ramp is inserted between repeats. \ X_NORMALIZED causes the new envelope's x axis \ to have the same extent as the original's. \ REFLECTED causes every other repetition to be in reverse.") def repeat_envelope(ur_env, repeats, reflected = false, x_normalized = false) (ur_env or []).map! do |x| x.to_f end tms = (reflected ? (repeats / 2).floor : repeats) en = if reflected lastx = ur_env[-2] new_env = ur_env.dup rev_env = ur_env[0..-3].reverse 0.step(rev_env.length - 1, 2) do |i| new_env.push(lastx + (lastx - rev_env[i + 1]), rev_env[i]) end new_env else ur_env end (en or []).map! do |x| x.to_f end first_y = en[1] x_max = en[-2] x = en.first first_y_is_last_y = (first_y == en.last) new_env = [first_y, x] len = en.length tms.times do |i| 2.step(len - 1, 2) do |j| x += en[j] - en[j - 2] new_env.push(x, en[j + 1]) end if (i < tms - 1) and (not first_y_is_last_y) x = x + x_max / 100.0 new_env.push(x, first_y) end end if x_normalized scl = x_max / x 0.step(new_env.length - 1, 2) do |i| new_env[i] *= scl end end new_env end alias envelope_repeat repeat_envelope class Power_env def initialize(*rest) envelope, scaler, offset, duration = nil optkey(rest, binding, [:envelope, [0, 0, 1, 100, 1, 1]], [:scaler, 1.0], [:offset, 0.0], [:duration, 0.0]) envelope.map! do |val| Float(val) end xext = envelope[-3] - envelope.first j = 0 @envs = make_array(envelope.length / 3 - 1) do |i| x0 = envelope[j] x1 = envelope[j + 3] y0 = envelope[j + 1] y1 = envelope[j + 4] base = envelope[j + 2] j += 3 make_env(:envelope, [0.0, y0, 1.0, y1], :base, base, :scaler, scaler, :offset, offset, :duration, duration * ((x1 - x0) / xext)) end @current_pass = mus_length(@envs.first) @current_env = 0 end def power_env val = env(@envs[@current_env]) @current_pass -= 1 if @current_pass.zero? and @current_env < (@envs.length - 1) @current_env += 1 @current_pass = mus_length(@envs[@current_env]) end val end def power_env_channel(beg, dur, snd, chn, edpos, edname) curbeg = beg as_one_edit_rb(edname) do | | @envs.each do |en| len = mus_length(en) + 1 env_channel(en, curbeg, len, snd, chn, edpos) curbeg += len end end end end # Power envelope def make_power_env(*rest) Power_env.new(*rest) end def power_env(pe) pe.power_env end def power_env_channel(pe, beg = 0, dur = false, snd = false, chn = false, edpos = false) pe.power_env_channel(beg, dur, snd, chn, edpos, get_func_name) end def powenv_channel(envelope, beg = 0, dur = false, snd = false, chn = false, edpos = false) curbeg = beg fulldur = (dur or framples(snd, chn, edpos)) len = envelope.length x1 = envelope[0] xrange = envelope[len - 3] - x1 y1 = envelope[1] base = envelope[2] x0 = y0 = 0.0 if len == 3 scale_channel(y1, beg, dur, snd, chn, edpos) else as_one_edit_rb(get_func_name) do | | 3.step(len - 1, 3) do |i| x0, x1 = x1, envelope[i] y0, y1 = y1, envelope[i + 1] curdur = (fulldur * ((x1 - x0) / xrange)).round xramp_channel(y0, y1, base, curbeg, curdur, snd, chn, edpos) curbeg += curdur base = envelope[i + 2] end end end end # by Anders Vinjar: # # envelope-exp can be used to create exponential segments to include in # envelopes. Given 2 or more breakpoints, it approximates the # curve between them using 'xgrid linesegments and 'power as the # exponent. # # env is a list of x-y-breakpoint-pairs, # power applies to whole envelope, # xgrid is how fine a solution to sample our new envelope with. def envelope_exp(en, power = 1.0, xgrid = 100) unless en.empty? en.map! do |x| x.to_f end end mn = min_envelope(en) largest_diff = max_envelope(en) - mn x_min = en.first x_max = en[-2] x_incr = (x_max - x_min) / xgrid.to_f new_en = [] x_min.step(x_max, x_incr) do |x| y = envelope_interp(x, en) new_en.push(x, (largest_diff.zero? ? y : (mn + largest_diff * (((y - mn) / largest_diff) ** power)))) end new_en end def rms_envelope(file, *rest) beg, dur, rfreq, db = nil optkey(rest, binding, [:beg, 0.0], :dur, [:rfreq, 30.0], :db) e = [] incr = 1.0 / rfreq fsr = mus_sound_srate(file) incrsamps = (incr * sfr).round start = (beg * fsr).round reader = make_sampler(start, file) fin = dur ? [start + (fsr * dur).round, mus_sound_framples(file)].min : mus_sound_framples(file) rms = make_moving_average(incrsamps) 0.step(fin, incrsamps) do |i| rms_val = 0.0 incrsamps.times do |j| val = reader.call rms_val = moving_average(rms, val * val) end e.push(i.to_f / fsr) rms_val = sqrt(rms_val) if db if rms_val < 0.00001 e.push(-100.0) else e.push(20.0 * (log(rms_val) / log(10.0))) end else e.push(rms_val) end end end def envelope_length(en) en.length / 2 end def normalize_envelope(en, new_max = 1.0) mx = en[1].abs.to_f 1.step(en.length - 1, 2) do |i| mx = [mx, en[i].abs].max.to_f end scale_envelope(en, new_max / mx) end def x_norm(en, xmax) scl = xmax / en[-2].to_f en.each_pair do |x, y| [x * scl, y.to_f] end.flatten end # ;;;======================================================================= # ;;; Exponential envelopes # ;;;======================================================================= # # ;;; Approximate an exponential envelope with a given base and error bound # ;;; by Fernando Lopez-Lezcano (nando@ccrma.stanford.edu) # ;;; # ;;; base: # ;;; step size of the exponential envelope # ;;; error: # ;;; error band of the approximation # ;;; scaler: # ;;; scaling factor for the y coordinates # ;;; offset: # ;;; offset for the y coordinates # ;;; cutoff: # ;;; lowest value of the exponentially rendered envelope, values lower than # ;;; this cutoff value will be approximated as cero. # ;;; out-scaler # ;;; scaler for the converted values def exp_envelope(env, *args) base, error, scaler, offset, cutoff, out_scaler = nil optkey(args, binding, [:base, 2 ** (1.0 / 12)], [:error, 0.01], [:scaler, 1.0], [:offset, 0.0], :cutoff, [:out_scaler, 1.0]) result = [] ycutoff = (cutoff ? (base ** (offset + cutoff * scaler)) : false) interpolate = lambda do |xl, yl, xh, yh, xi| yl + (xi - xl) * ((yh - yl) / (xh - xl)) end exp_seg = lambda do |xl, yle, xh, yhe, yl, yh, err| xint = (xl + xh) / 2.0 yint = interpolate.call(xl, yl, xh, yh, xint) yinte = interpolate.call(xl, yle, xh, yhe, xint) yexp = base ** yint yerr = base ** (yint + err) - yexp if (yexp - yinte).abs > yerr and ((ycutoff and yinte > ycutoff) or true) xi, yi = exp_seg.call(xl, yle, xint, yexp, yl, yint, err) xj, yj = exp_seg.call(xint, yexp, xh, yhe, yint, yh, err) [xi + [xint] + xj, yi + [yexp] + yj] else [[], []] end end nx = nyscl = 0.0 0.step(env.length - 4, 2) do |i| x = env[i] y = env[i + 1] nx = env[i + 2] ny = env[i + 3] yscl = offset + y * scaler nyscl = offset + ny * scaler result.push(x) result.push((((not ycutoff) or base ** yscl >= ycutoff) ? (out_scaler * base ** yscl) : 0.0)) xs, ys = exp_seg.call(x, base ** yscl, nx, base ** nyscl, yscl, nyscl, error) unless xs.empty? ys_scaled = vct_scale!(list2vct(ys), out_scaler) xs.each_with_index do |xx, ii| result.push(xx) result.push(ys_scaled[ii]) end end end result.push(nx) result.push((((not ycutoff) or base ** nyscl >= ycutoff) ? (out_scaler * base ** nyscl) : 0.0)) end # ;;; Amplitude envelope in dBs # ;;; # ;;; The db scale is defined as: # ;;; value(db)=(* 20 (log10 (/ vin vref))) # ;;; where: # ;;; vref=1.0 reference value = digital clipping def db_envelope(env, cutoff = -70, error = 0.01) exp_envelope(env, :base, 10.0, :scaler, 1.0 / 20, :cutoff, cutoff, :error, error) end def make_db_env(env, *args) scaler, offset, base, duration, len, cutoff, error = nil optkey(args, binding, [:scaler, 1.0], [:offset, 0.0], [:base, 1.0], [:duration, 0.0], [:len, 0], [:cutoff, -70], [:error, 0.01]) make_env(:envelope, db_envelope(env, cutoff, error), :scaler, scaler, :offset, offset, :base, base, :duration, duration, :length, len) end # ;;; Pitch envelopes (y units are semitone and octave intervals) def semitones_envelope(env, around = 1.0, error = 0.01) exp_envelope(env, :error, error, :out_scaler, around) end def make_semitones_env(env, *args) around, scaler, offset, base, dur, len, error = nil optkey(args, binding, [:around, 1.0], [:scaler, 1.0], [:offset, 0.0], [:base, 1.0], [:duration, 0.0], [:len, 0], [:error, 0.01]) make_env(:envelope, semitones_envelope(env, around, error), :scaler, scaler, :offset, offset, :base, base, :duration, dur, :length, len) end def octaves_envelope(env, around = 1.0, error = 0.01) exp_envelope(env, :error, error, :base, 2.0, :out_scaler, around) end def make_octaves_env(env, *args) around, scaler, offset, base, dur, len, error = nil optkey(args, binding, [:around, 1.0], [:scaler, 1.0], [:offset, 0.0], [:base, 1.0], [:duration, 0.0], [:len, 0], [:error, 0.01]) make_env(:envelope, octaves_envelope(env, around, error), :scaler, scaler, :offset, offset, :base, base, :duration, dur, :length, len) end end include Env =begin # power envelope test (clm/env.lisp) def test_power_env(start, dur, en) os = make_oscil() pe = make_power_env(:envelope, en, :duration, dur, :scaler, 0.5) beg, len = times2samples(start, dur) (beg...len).each do |i| outa(i, power_env(pe) * oscil(os), $output) end end with_sound(:channels, 1, :play, 1) do | | test_power_env(0, 1, [0, 0, 0.325, 1, 1, 32, 2, 0, 0]) test_power_env(1.2, 1, [0, 0, 0.325, 1, 1, 32, 2, 0.5, 1, 3, 1, 0.1234, 4, 0, 0]) test_power_env(2.4, 1, [0, 0, 0, 1, 1, 1, 2, 0.5, 0.123, 3, 1, 321, 4, 0, 0]) end =end # env.rb ends here snd-16.1/snd-gfile.c0000644000076400007640000035103712525674306012372 0ustar bilbil#include "snd.h" #include "snd-file.h" /* various file-related dialogs: File|Edit:Save-as File:Open|View File|Edit:Mix File:Insert File:Edit-Header File:New Info and Raw View:Files (replaced) */ #define HAVE_G_FILE_MONITOR_DIRECTORY 1 /* (GLIB_CHECK_VERSION(2, 18, 1) but it might be much older */ #define WITH_SKETCH 1 /* (!GTK_CHECK_VERSION(3, 0, 0)) see below */ /* if thumbnail graph display is too slow: save the points? split the idler? g_source_remove if overlap? * * In gtk2, if we have a file selected, then some other process writes a file in the * current directory (emacs autosaving), the file chooser gets confused as * to what is selected! So we can't get the selected filename except immediately upon * "selection-changed" and even then we're asking for trouble. * * In gtk3, each time we reopen the chooser, it starts all the way back at the useless "recently used"! * We can't use gtk_..._set|select_filename -- the function is simply ignored! * so currently we never hide the dialog. * And if we resize the dialog, a hand cursor appears, and the next thing we know we're moving the dialog itself! * And valgrind reports a million invalid reads in gtk's code! * And the sketch gets an incomprehensible cairo error * this apparently happens because our "signal-changed" callback takes too long to draw a long sound's graph! * but making it idle does not fully fix the problem -- we have to save the graph points and rescale directly. * * 3.10 will have gtk_file_chooser_get_current_name */ /* we can find the embedded tree view: (define* (traveler w (spaces 0)) (gtk_container_foreach (GTK_CONTAINER w) (lambda (w1 d) (do ((i 0 (+ i 1))) ((= i spaces)) (format #t " ")) (format #t "~A " (gtk_widget_get_name w1)) (if (GTK_IS_LABEL w1) (format #t "~A~%" (gtk_label_get_text (GTK_LABEL w1))) (if (GTK_IS_BUTTON w1) (format #t "~A~%" (gtk_button_get_label (GTK_BUTTON w1))) (if (GTK_IS_ENTRY w1) (format #t "~A~%" (gtk_entry_get_text (GTK_ENTRY w1))) (begin (newline) (if (GTK_IS_CONTAINER w1) (traveler w1 (+ spaces 2)))))))))) (traveler (open-file-dialog)) * now how to get at the sidebar and remove "recently used"? or change the row-colors in gtk3? * no way that I can find... * in 3.12 they've added gtk_places_sidebar_set_local_only, but it's not clear how to get at this thing * and it probably isn't what we want anyway. */ /* ---------------------------------------- file monitor ---------------------------------------- */ #if HAVE_G_FILE_MONITOR_DIRECTORY static void cleanup_new_file_watcher(void); static void cleanup_edit_header_watcher(void); void cleanup_file_monitor(void) { cleanup_edit_header_watcher(); cleanup_new_file_watcher(); ss->file_monitor_ok = false; } void *unmonitor_file(void *watcher) { if (G_IS_FILE_MONITOR(watcher)) g_file_monitor_cancel((GFileMonitor *)watcher); return(NULL); } static void *unmonitor_directory(void *watcher) { if (G_IS_FILE_MONITOR(watcher)) g_file_monitor_cancel((GFileMonitor *)watcher); return(NULL); } static void sp_file_changed(GFileMonitor *mon, GFile *file, GFile *other, GFileMonitorEvent ev, gpointer data) { snd_info *sp = (snd_info *)data; if (sp->writing) return; switch (ev) { case G_FILE_MONITOR_EVENT_CHANGED: /* this includes cp overwriting old etc */ if (file_write_date(sp->filename) != sp->write_date) /* otherwise chmod? */ { sp->need_update = true; if (auto_update(ss)) snd_update(sp); else start_bomb(sp); } #ifndef _MSC_VER else { int err; err = access(sp->filename, R_OK); if (err < 0) { char *msg; msg = mus_format("%s is read-protected!", sp->short_filename); status_report(sp, "%s", msg); free(msg); sp->file_unreadable = true; start_bomb(sp); } else { sp->file_unreadable = false; clear_status_area(sp); err = access(sp->filename, W_OK); if (err < 0) /* if err < 0, then we can't write (W_OK -> error ) */ sp->file_read_only = FILE_READ_ONLY; else sp->file_read_only = FILE_READ_WRITE; if ((sp->user_read_only == FILE_READ_ONLY) || (sp->file_read_only == FILE_READ_ONLY)) show_lock(sp); else hide_lock(sp); } } #endif break; case G_FILE_MONITOR_EVENT_DELETED: /* snd_update will post a complaint in this case, but I like it explicit */ if (mus_file_probe(sp->filename) == 0) { /* user deleted file while editing it? */ status_report(sp, "%s no longer exists!", sp->short_filename); sp->file_unreadable = true; start_bomb(sp); return; } case G_FILE_MONITOR_EVENT_CREATED: #if HAVE_GTK_WIDGET_GET_VISIBLE case G_FILE_MONITOR_EVENT_MOVED: #endif if (sp->write_date != file_write_date(sp->filename)) { sp->file_unreadable = false; sp->need_update = true; if (auto_update(ss)) snd_update(sp); else start_bomb(sp); } break; default: /* ignore the rest */ break; } } void monitor_sound(snd_info *sp) { GFile *file; GError *err = NULL; file = g_file_new_for_path(sp->filename); sp->file_watcher = (void *)g_file_monitor_file(file, G_FILE_MONITOR_NONE, NULL, &err); if (err != NULL) snd_warning("%s", err->message); else g_signal_connect(G_OBJECT(sp->file_watcher), "changed", G_CALLBACK(sp_file_changed), (gpointer)sp); g_object_unref(file); /* is this safe? */ } #else void cleanup_file_monitor(void) {} void *unmonitor_file(void *watcher) {return(NULL);} static void *unmonitor_directory(void *watcher) {return(NULL);} void monitor_sound(snd_info *sp) {} #endif /* ---------------------------------------- dialogs ---------------------------------------- */ #define FILE_DIALOG_DEFAULT_WIDTH 500 #define FILE_DIALOG_DEFAULT_HEIGHT 300 #define FILE_DIALOG_DEFAULT_SKETCH_HEIGHT 75 typedef struct file_dialog_info { GtkWidget *dialog, *ok_button, *cancel_button, *help_button, *extract_button, *play_button, *chooser; read_only_t file_dialog_read_only; GtkWidget *frame, *info, *vbox; void *unsound_directory_watcher; /* doesn't exist, not a sound file, bogus header, etc */ void *info_filename_watcher; /* watch for change in selected file and repost info */ char *unsound_dirname, *unsound_filename; char *info_filename; snd_info *player; file_data *panel_data; char *filename; save_dialog_t type; void *file_watcher; gulong filename_watcher_id; mus_header_t header_type; mus_sample_t sample_type; #if WITH_SKETCH point_t *p0, *p1; int pts; gc_t *gc; axis_info *axis; GtkWidget *drawer; snd_info *sp; bool in_progress, two_sided; mus_long_t samps; int srate; bool unreadable; #endif } file_dialog_info; static file_dialog_info *odat = NULL; /* open file */ static file_dialog_info *mdat = NULL; /* mix file */ static file_dialog_info *idat = NULL; /* insert file */ void reflect_just_sounds(void) {} static bool post_sound_info(file_dialog_info *fd, const char *filename, bool with_filename) { if ((!filename) || (is_directory(filename)) || (!is_sound_file(filename))) { gtk_label_set_text(GTK_LABEL(fd->info), ""); #if WITH_SKETCH gtk_widget_hide(fd->drawer); #endif return(false); } else { char *buf; char *mx, *lenstr; buf = (char *)calloc(1024, sizeof(char)); if (mus_sound_maxamp_exists(filename)) { int i, chns, lim; mus_long_t pos = 0; mx = (char *)calloc(128, sizeof(char)); chns = mus_sound_chans(filename); lim = 5; if (chns < lim) lim = chns; snprintf(mx, 128, "\nmaxamp: %.3f", mus_sound_channel_maxamp(filename, 0, &pos)); for (i = 1; i < lim; i++) { char fb[16]; snprintf(fb, 16, " %.3f", mus_sound_channel_maxamp(filename, i, &pos)); strcat(mx, fb); } if (lim < chns) strcat(mx, "..."); } else { mx = (char *)calloc(2, sizeof(char)); mx[0] = '\n'; } lenstr = (char *)calloc(128, sizeof(char)); if (mus_sound_samples(filename) < 1000) snprintf(lenstr, 128, "%d samples", (int)mus_sound_samples(filename)); else snprintf(lenstr, 128, "%.3f seconds", mus_sound_duration(filename)); snprintf(buf, 1024, "%s%s%d chan%s, %d Hz, %s\n%s, %s%s%s", (with_filename) ? filename_without_directory(filename) : "", (with_filename) ? ": " : "", mus_sound_chans(filename), (mus_sound_chans(filename) > 1) ? "s" : "", mus_sound_srate(filename), lenstr, mus_header_type_name(mus_sound_header_type(filename)), short_sample_type_name(mus_sound_sample_type(filename), filename), snd_strftime(", %d-%b-%Y", mus_sound_write_date(filename)), mx); gtk_label_set_text(GTK_LABEL(fd->info), buf); free(buf); free(mx); free(lenstr); #if WITH_SKETCH gtk_widget_show(fd->drawer); #endif } return(true); } static void file_dialog_stop_playing(file_dialog_info *fd) { if ((fd->player) && (fd->player->playing)) { stop_playing_sound(fd->player, PLAY_BUTTON_UNSET); fd->player = NULL; } } void clear_deleted_snd_info(void *ufd) { file_dialog_info *fd = (file_dialog_info *)ufd; fd->player = NULL; } #if WITH_AUDIO static void file_dialog_play(GtkWidget *w, gpointer data) { file_dialog_info *fd = (file_dialog_info *)data; if ((fd->player) && (fd->player->playing)) file_dialog_stop_playing(fd); else { char *filename; filename = fd->filename; /* gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fd->chooser)); */ if ((filename) && (!is_directory(filename))) { if (mus_file_probe(filename)) { fd->player = make_sound_readable(filename, false); fd->player->delete_me = (void *)fd; if (fd->player) play_sound(fd->player, 0, NO_END_SPECIFIED); } } } } #endif #if WITH_SKETCH static void tiny_string(cairo_t *cr, const char *str, int x0, int y0) { PangoLayout *layout = NULL; cairo_save(cr); layout = pango_cairo_create_layout(cr); pango_layout_set_font_description(layout, TINY_FONT(ss)); pango_layout_set_text(layout, str, -1); cairo_move_to(cr, x0, y0); pango_cairo_show_layout(cr, layout); g_object_unref(G_OBJECT(layout)); cairo_restore(cr); } static void sketch_1(file_dialog_info *fd, bool new_data) { #define X_AXIS 24 #define Y_AXIS 8 char *filename, *str; int hgt, wid, i, xoff, yoff; axis_info *ap; cairo_t *old_cr; double xscl, yscl; point_t *g_p0, *g_p1; filename = fd->filename; /* gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fd->chooser)); */ /* gtk_widget_show(fd->drawer); */ if (!filename) return; if ((is_directory(filename)) || (!is_sound_file(filename))) return; if ((!new_data) && (fd->unreadable)) return; wid = widget_width(fd->drawer); hgt = widget_height(fd->drawer); ap = fd->axis; if (new_data) { bool two_sided = false; chan_info *active_channel; axis_info *active_ap = NULL; snd_info *sp; sp = make_sound_readable(filename, false); if (!sp) { fd->unreadable = true; return; } fd->unreadable = false; active_channel = sp->chans[0]; active_ap = active_channel->axis; ap->graph_active = true; fd->samps = current_samples(active_channel); fd->srate = snd_srate(active_channel->sound); ap->losamp = 0; ap->hisamp = fd->samps - 1; ap->y0 = -1.0; ap->y1 = 1.0; ap->x0 = 0.0; ap->x1 = (double)(fd->samps) / (double)(fd->srate); ap->x_axis_x0 = 0; ap->y_axis_y0 = 1000; ap->x_axis_x1 = 1000; ap->y_axis_y1 = 0; active_channel->axis = ap; init_axis_scales(ap); fd->pts = make_background_graph(active_channel, fd->srate, &two_sided); fd->two_sided = two_sided; memcpy((void *)(fd->p0), (void *)get_grf_points(), fd->pts * sizeof(point_t)); if (fd->two_sided) memcpy((void *)(fd->p1), (void *)get_grf_points1(), fd->pts * sizeof(point_t)); active_channel->axis = active_ap; sp->chans[0]->active = CHANNEL_INACTIVE; completely_free_snd_info(sp); sp = NULL; } else { ap->x1 = (double)(fd->samps) / (double)(fd->srate); } ap->x_axis_x0 = X_AXIS + 2; ap->y_axis_y1 = Y_AXIS; ap->x_axis_x1 = wid - 4; ap->y_axis_y0 = hgt - Y_AXIS * 2; g_p0 = get_grf_points(); g_p1 = get_grf_points1(); if (!new_data) { memcpy((void *)g_p0, (void *)(fd->p0), fd->pts * sizeof(point_t)); if (fd->two_sided) memcpy((void *)g_p1, (void *)(fd->p1), fd->pts * sizeof(point_t)); } xoff = ap->x_axis_x0; yoff = ap->y_axis_y1; xscl = (ap->x_axis_x1 - xoff) * 0.001; yscl = (ap->y_axis_y0 - yoff) * 0.001; init_axis_scales(ap); for (i = 0; i < fd->pts; i++) { g_p0[i].x = xoff + (int)(g_p0[i].x * xscl); g_p0[i].y = yoff + (int)(g_p0[i].y * yscl); } if (fd->two_sided) { for (i = 0; i < fd->pts; i++) { g_p1[i].x = xoff + (int)(g_p1[i].x * xscl); g_p1[i].y = yoff + (int)(g_p1[i].y * yscl); } } /* here we could check that nothing has changed while getting the data ready, but it doesn't seem to be a problem? */ old_cr = ss->cr; ss->cr = make_cairo(WIDGET_TO_WINDOW(fd->drawer)); cairo_push_group(ss->cr); cairo_set_source_rgba(ss->cr, fd->gc->bg_color->red, fd->gc->bg_color->green, fd->gc->bg_color->blue, fd->gc->bg_color->alpha); cairo_rectangle(ss->cr, 0, 0, wid, hgt); cairo_fill(ss->cr); cairo_set_source_rgba(ss->cr, fd->gc->fg_color->red, fd->gc->fg_color->green, fd->gc->fg_color->blue, fd->gc->fg_color->alpha); /* y axis */ cairo_rectangle(ss->cr, X_AXIS, 8, 2, hgt - Y_AXIS - 16); cairo_fill(ss->cr); /* x axis */ cairo_rectangle(ss->cr, X_AXIS, hgt - Y_AXIS - 8, wid - X_AXIS - 4, 2); cairo_fill(ss->cr); tiny_string(ss->cr, "1.0", 4, 6); tiny_string(ss->cr, "-1.0", 0, hgt - 24); tiny_string(ss->cr, "0.0", 24, hgt - 12); str = prettyf(ap->x1, 3); if (str) { tiny_string(ss->cr, str, wid - 4 - 6 * strlen(str), hgt - 12); free(str); } if (fd->pts > 0) { if (fd->two_sided) draw_both_grf_points(1, ap->ax, fd->pts, GRAPH_LINES); else draw_grf_points(1, ap->ax, fd->pts, ap, 0.0, GRAPH_LINES); } cairo_pop_group_to_source(ss->cr); cairo_paint(ss->cr); free_cairo(ss->cr); ss->cr = old_cr; } static idle_func_t get_sketch(gpointer data) { sketch_1((file_dialog_info *)data, true); return(false); } static idle_func_t get_resketch(gpointer data) { sketch_1((file_dialog_info *)data, false); return(false); } static void stop_sketch(gpointer data) { file_dialog_info *fd = (file_dialog_info *)data; fd->in_progress = false; } #define sketch(Fd) {fd->in_progress = true; g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, get_sketch, (gpointer)Fd, (GDestroyNotify)stop_sketch);} #define resketch(Fd) if (!fd->in_progress) {fd->in_progress = true; g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, get_resketch, (gpointer)Fd, (GDestroyNotify)stop_sketch);} #endif static void selection_changed_callback(GtkFileChooser *w, gpointer data) { file_dialog_info *fd = (file_dialog_info *)data; fd->filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fd->chooser)); #if WITH_SKETCH if (post_sound_info(fd, fd->filename, false)) sketch(fd); #else post_sound_info(fd, fd->filename, false); #endif } static gboolean file_filter_callback(const GtkFileFilterInfo *filter_info, gpointer data) { /* return true => include this file */ if (filter_info) return(Xen_boolean_to_C_bool(Xen_call_with_1_arg((Xen)data, C_string_to_Xen_string(filter_info->filename), "filter func"))); return(false); } #if WITH_SKETCH static gboolean drawer_expose(GtkWidget *w, GdkEventExpose *ev, gpointer data) { file_dialog_info *fd = (file_dialog_info *)data; resketch(fd); return(false); } #endif /* if icons do not get displayed, check the system preferences menu+toolbar dialog */ static file_dialog_info *make_fsb(const char *title, const char *file_lab, const char *ok_lab, const gchar *stock, bool with_extract, bool save_as) { file_dialog_info *fd; int i; GtkFileFilter *just_sounds_filter, *all_files_filter; const char **exts; char buf[32]; fd = (file_dialog_info *)calloc(1, sizeof(file_dialog_info)); /* -------- base dialog -------- */ fd->dialog = snd_gtk_dialog_new(); #if GTK_CHECK_VERSION(3, 14, 0) gtk_window_set_transient_for(GTK_WINDOW(fd->dialog), GTK_WINDOW(MAIN_SHELL(ss))); #endif gtk_window_set_title(GTK_WINDOW(fd->dialog), title); sg_make_resizable(fd->dialog); gtk_container_set_border_width(GTK_CONTAINER(fd->dialog), 10); gtk_widget_realize(fd->dialog); /* -------- buttons -------- */ fd->help_button = gtk_dialog_add_button(GTK_DIALOG(fd->dialog), "Help", GTK_RESPONSE_NONE); #if WITH_AUDIO if (!save_as) fd->play_button = gtk_dialog_add_button(GTK_DIALOG(fd->dialog), "Play", GTK_RESPONSE_NONE); #endif if (with_extract) fd->extract_button = gtk_dialog_add_button(GTK_DIALOG(fd->dialog), "Extract", GTK_RESPONSE_NONE); fd->cancel_button = gtk_dialog_add_button(GTK_DIALOG(fd->dialog), "Go away", GTK_RESPONSE_NONE); fd->ok_button = gtk_dialog_add_button(GTK_DIALOG(fd->dialog), "Ok", GTK_RESPONSE_NONE); gtk_widget_set_name(fd->help_button, "dialog_button"); gtk_widget_set_name(fd->cancel_button, "dialog_button"); if (with_extract) gtk_widget_set_name(fd->extract_button, "dialog_button"); gtk_widget_set_name(fd->ok_button, "dialog_button"); #if WITH_AUDIO if (!save_as) { gtk_widget_set_name(fd->play_button, "dialog_button"); #if GTK_CHECK_VERSION(3, 0, 0) add_highlight_button_style(fd->play_button); #endif } #endif #if GTK_CHECK_VERSION(3, 0, 0) add_highlight_button_style(fd->ok_button); add_highlight_button_style(fd->cancel_button); add_highlight_button_style(fd->help_button); if (with_extract) add_highlight_button_style(fd->extract_button); #endif gtk_widget_show(fd->ok_button); gtk_widget_show(fd->cancel_button); gtk_widget_show(fd->help_button); #if WITH_AUDIO if (!save_as) gtk_widget_show(fd->play_button); #endif if (with_extract) gtk_widget_show(fd->extract_button); just_sounds_filter = gtk_file_filter_new(); gtk_file_filter_set_name(just_sounds_filter, "Just sounds"); exts = get_sound_file_extensions(); buf[0] = '*'; buf[1] = '.'; for (i = 0; i < sound_file_extensions_length(); i++) { buf[2] = '\0'; strcat((char *)(buf + 2), exts[i]); gtk_file_filter_add_pattern(just_sounds_filter, buf); } all_files_filter = gtk_file_filter_new(); gtk_file_filter_set_name(all_files_filter, "All files"); gtk_file_filter_add_pattern(all_files_filter, "*"); fd->chooser = gtk_file_chooser_widget_new((save_as) ? GTK_FILE_CHOOSER_ACTION_SAVE : GTK_FILE_CHOOSER_ACTION_OPEN); gtk_box_pack_start(GTK_BOX(DIALOG_CONTENT_AREA(fd->dialog)), fd->chooser, true, true, 10); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fd->chooser), just_sounds_filter); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fd->chooser), all_files_filter); #if HAVE_EXTENSION_LANGUAGE { /* now look for added filters added via add-file-filter */ int i; for (i = 0; i < ss->file_filters_size; i++) if (!(Xen_is_false(Xen_vector_ref(ss->file_filters, i)))) { const char *filter_name; GtkFileFilter *nfilt; Xen filter_func; filter_name = Xen_string_to_C_string(Xen_car(Xen_vector_ref(ss->file_filters, i))); filter_func = Xen_cadr(Xen_vector_ref(ss->file_filters, i)); nfilt = gtk_file_filter_new(); gtk_file_filter_set_name(nfilt, filter_name); gtk_file_filter_add_custom(nfilt, GTK_FILE_FILTER_FILENAME, file_filter_callback, (gpointer)filter_func, NULL); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fd->chooser), nfilt); } } #endif gtk_widget_show(fd->chooser); gtk_widget_set_size_request(fd->chooser, FILE_DIALOG_DEFAULT_WIDTH, FILE_DIALOG_DEFAULT_HEIGHT); gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(fd->chooser), (just_sounds(ss)) ? just_sounds_filter : all_files_filter); #if HAVE_GTK_WIDGET_GET_VISIBLE if (save_as) gtk_file_chooser_set_create_folders(GTK_FILE_CHOOSER(fd->chooser), true); #endif fd->filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fd->chooser)); return(fd); } static file_dialog_info *make_file_dialog(read_only_t read_only, const char *title, const char *file_title, const char *ok_title, snd_dialog_t which_dialog, GCallback file_ok_proc, GCallback file_mkdir_proc, GCallback file_delete_proc, GCallback file_dismiss_proc, GCallback file_help_proc, const gchar *stock) { file_dialog_info *fd; GtkWidget *vbox, *hbox; fd = make_fsb(title, file_title, ok_title, stock, false, false); fd->file_dialog_read_only = read_only; vbox = DIALOG_CONTENT_AREA(fd->dialog); hbox = gtk_hbox_new(true, 8); gtk_box_pack_start(GTK_BOX(vbox), hbox, true, true, 8); gtk_widget_show(hbox); fd->info = gtk_label_new(NULL); gtk_box_pack_start(GTK_BOX(hbox), fd->info, false, true, 8); gtk_widget_show(fd->info); #if WITH_SKETCH fd->sp = NULL; fd->gc = gc_new(); gc_set_background(fd->gc, ss->white); gc_set_foreground(fd->gc, ss->black); fd->drawer = gtk_drawing_area_new(); gtk_box_pack_end(GTK_BOX(hbox), fd->drawer, true, true, 10); gtk_widget_set_events(fd->drawer, GDK_EXPOSURE_MASK); gtk_widget_set_size_request(fd->drawer, -1, FILE_DIALOG_DEFAULT_SKETCH_HEIGHT); gtk_widget_show(fd->drawer); fd->axis = (axis_info *)calloc(1, sizeof(axis_info)); fd->axis->ax = (graphics_context *)calloc(1, sizeof(graphics_context)); fd->axis->ax->wn = WIDGET_TO_WINDOW(fd->drawer); fd->axis->ax->w = fd->drawer; fd->axis->ax->gc = fd->gc; fd->axis->ax->current_font = AXIS_NUMBERS_FONT(ss); fd->p0 = (point_t *)calloc(POINT_BUFFER_SIZE, sizeof(point_t)); fd->p1 = (point_t *)calloc(POINT_BUFFER_SIZE, sizeof(point_t)); fd->unreadable = true; SG_SIGNAL_CONNECT(fd->drawer, DRAW_SIGNAL, drawer_expose, (gpointer)fd); gtk_widget_show(fd->dialog); #endif SG_SIGNAL_CONNECT(fd->help_button, "clicked", file_help_proc, (gpointer)fd); SG_SIGNAL_CONNECT(fd->ok_button, "clicked", file_ok_proc, (gpointer)fd); SG_SIGNAL_CONNECT(fd->cancel_button, "clicked", file_dismiss_proc, (gpointer)fd); if (file_delete_proc) SG_SIGNAL_CONNECT(fd->dialog, "delete_event", file_delete_proc, (gpointer)fd); #if WITH_AUDIO SG_SIGNAL_CONNECT(fd->play_button, "clicked", file_dialog_play, (gpointer)(fd)); #endif gtk_label_set_text(GTK_LABEL(fd->info), ""); set_dialog_widget(which_dialog, fd->dialog); SG_SIGNAL_CONNECT(fd->chooser, "selection-changed", selection_changed_callback, (gpointer)fd); return(fd); } static void file_open_error(const char *error_msg, file_dialog_info *fd) { gtk_label_set_text(GTK_LABEL(fd->info), error_msg); gtk_widget_show(fd->info); } static void redirect_file_open_error(const char *error_msg, void *ufd) { /* called from snd_error, redirecting error handling to the dialog */ file_open_error(error_msg, (file_dialog_info *)ufd); } static void clear_file_error_label(file_dialog_info *fd) { gtk_label_set_text(GTK_LABEL(fd->info), ""); if (fd->unsound_directory_watcher) { fd->unsound_directory_watcher = unmonitor_directory(fd->unsound_directory_watcher); if (fd->unsound_dirname) {free(fd->unsound_dirname); fd->unsound_dirname = NULL;} if (fd->unsound_filename) {free(fd->unsound_filename); fd->unsound_filename = NULL;} } } /* key press event here, not key release -- the latter is triggered by the release * that triggered the error, so our error is immediately erased */ #if HAVE_G_FILE_MONITOR_DIRECTORY static void unpost_unsound_error(GFileMonitor *mon, GFile *file, GFile *other, GFileMonitorEvent ev, gpointer data) { file_dialog_info *fd; char *filename; switch (ev) { case G_FILE_MONITOR_EVENT_CHANGED: case G_FILE_MONITOR_EVENT_CREATED: filename = g_file_get_path(file); fd = (file_dialog_info *)data; if ((fd) && (filename) && (mus_strcmp(filename, fd->unsound_filename))) clear_file_error_label(fd); break; default: /* ignore the rest */ break; } } static void start_unsound_watcher(file_dialog_info *fd, const char *filename) { GFile *file; GError *err = NULL; if (fd->unsound_directory_watcher) { fd->unsound_directory_watcher = unmonitor_directory(fd->unsound_directory_watcher); if (fd->unsound_dirname) free(fd->unsound_dirname); if (fd->unsound_filename) free(fd->unsound_filename); } fd->unsound_filename = mus_expand_filename(filename); fd->unsound_dirname = just_directory(fd->unsound_filename); file = g_file_new_for_path(fd->unsound_dirname); fd->unsound_directory_watcher = (void *)g_file_monitor_directory(file, G_FILE_MONITOR_NONE, NULL, &err); if (err != NULL) snd_warning("%s", err->message); else g_signal_connect(G_OBJECT(fd->unsound_directory_watcher), "changed", G_CALLBACK(unpost_unsound_error), (gpointer)fd); g_object_unref(file); } #else static void start_unsound_watcher(file_dialog_info *fd, const char *filename) {} #endif static void file_open_dialog_ok(GtkWidget *w, gpointer data) { file_dialog_info *fd = (file_dialog_info *)data; char *filename = NULL; filename = fd->filename; /* gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fd->chooser)); */ /* fprintf(stderr, "open %s, %s\n", fd->filename, gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fd->chooser))); */ file_dialog_stop_playing(fd); if ((filename) && (!is_directory(filename))) { snd_info *sp; redirect_snd_error_to(redirect_file_open_error, (void *)fd); ss->requestor_dialog = fd->dialog; ss->open_requestor = FROM_OPEN_DIALOG; sp = snd_open_file(filename, fd->file_dialog_read_only); redirect_snd_error_to(NULL, NULL); if (sp) { #if (!GTK_CHECK_VERSION(3, 0, 0)) gpointer hide_me; hide_me = g_object_get_data(G_OBJECT(fd->dialog), "hide-me"); /* see snd-gtk.scm where this is set */ if (hide_me == 0) gtk_widget_hide(fd->dialog); #endif select_channel(sp, 0); /* add_sound_window (snd-xsnd.c) -> make_file_info (snd-file) will report reason for error, if any */ } else { if (ss->open_requestor != FROM_RAW_DATA_DIALOG) { start_unsound_watcher(fd, filename); } } } else { char *str; str = mus_format("%s is a directory", filename); file_open_error(str, fd); free(str); } } static void file_open_dialog_dismiss(GtkWidget *w, gpointer context) { file_dialog_info *fd = (file_dialog_info *)context; file_dialog_stop_playing(fd); gtk_label_set_text(GTK_LABEL(fd->info), ""); gtk_widget_hide(fd->dialog); } static void file_open_dialog_help(GtkWidget *w, gpointer context) { open_file_dialog_help(); } static gint file_open_dialog_delete(GtkWidget *w, GdkEvent *event, gpointer context) { file_dialog_info *fd = (file_dialog_info *)context; file_dialog_stop_playing(fd); gtk_label_set_text(GTK_LABEL(fd->info), ""); gtk_widget_hide(fd->dialog); return(true); } static void file_activated_callback(GtkFileChooser *w, gpointer data) { const char *filename; file_dialog_info *fd = (file_dialog_info *)data; fd->filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fd->chooser)); filename = fd->filename; if ((filename) && (!(is_directory(filename)))) { snd_info *sp; redirect_snd_error_to(redirect_file_open_error, (void *)fd); ss->requestor_dialog = fd->dialog; ss->open_requestor = FROM_OPEN_DIALOG; sp = snd_open_file(filename, fd->file_dialog_read_only); redirect_snd_error_to(NULL, NULL); if (sp) { #if (!GTK_CHECK_VERSION(3, 0, 0)) gpointer hide_me; hide_me = g_object_get_data(G_OBJECT(fd->dialog), "hide-me"); /* see snd-gtk.scm where this is set */ if (hide_me == 0) gtk_widget_hide(fd->dialog); #endif select_channel(sp, 0); /* add_sound_window (snd-xsnd.c) -> make_file_info (snd-file) will report reason for error, if any */ } else { start_unsound_watcher(fd, filename); } } } widget_t make_open_file_dialog(read_only_t read_only, bool managed) { if (!odat) { odat = make_file_dialog(read_only, (char *)((read_only == FILE_READ_ONLY) ? "View" : "Open"), (char *)((read_only == FILE_READ_ONLY) ? "view:" : "open:"), NULL, FILE_OPEN_DIALOG, (GCallback)file_open_dialog_ok, NULL, /* no mkdir */ (GCallback)file_open_dialog_delete, (GCallback)file_open_dialog_dismiss, (GCallback)file_open_dialog_help, ICON_OPEN); SG_SIGNAL_CONNECT(odat->chooser, "file-activated", file_activated_callback, (gpointer)odat); } else { if (read_only != odat->file_dialog_read_only) { set_stock_button_label(odat->ok_button, (char *)((read_only == FILE_READ_ONLY) ? "View" : "Open")); gtk_window_set_title(GTK_WINDOW(odat->dialog), (char *)((read_only == FILE_READ_ONLY) ? "View" : "Open")); odat->file_dialog_read_only = read_only; } #if GTK_CHECK_VERSION(3, 0, 0) /* this doesn't work!! and nothing else does either */ /* if (odat->filename) gtk_file_chooser_select_filename(GTK_FILE_CHOOSER(odat->chooser), odat->filename); */ #endif } if (managed) gtk_widget_show(odat->dialog); return(odat->dialog); } /* -------- mix file dialog -------- */ static void file_mix_cancel_callback(GtkWidget *w, gpointer context) { file_dialog_stop_playing(mdat); gtk_label_set_text(GTK_LABEL(mdat->info), ""); gtk_widget_hide(mdat->dialog); } static void file_mix_help_callback(GtkWidget *w, gpointer context) { mix_file_dialog_help(); } static gint file_mix_delete_callback(GtkWidget *w, GdkEvent *event, gpointer context) { file_dialog_stop_playing(mdat); gtk_label_set_text(GTK_LABEL(mdat->info), ""); gtk_widget_hide(mdat->dialog); return(true); } static void file_mix_ok_callback(GtkWidget *w, gpointer context) { char *filename = NULL; filename = mdat->filename; /* gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(mdat->chooser)); */ if ((!filename) || (!(*filename))) { file_open_error("no filename given", mdat); } else { file_dialog_stop_playing(mdat); if (!(is_directory(filename))) { snd_info *sp; int err; sp = any_selected_sound(); redirect_snd_error_to(redirect_file_open_error, (void *)mdat); ss->requestor_dialog = mdat->dialog; ss->open_requestor = FROM_MIX_DIALOG; err = mix_complete_file_at_cursor(sp, filename); redirect_snd_error_to(NULL, NULL); if (err < 0) { if (ss->open_requestor != FROM_RAW_DATA_DIALOG) { if (err == MIX_FILE_NO_FILE) start_unsound_watcher(mdat, filename); } } else { status_report(sp, "%s mixed in at cursor", filename); } } else { char *str; str = mus_format("%s is a directory", filename); file_open_error(str, mdat); free(str); } } } widget_t make_mix_file_dialog(bool managed) { if (mdat == NULL) { mdat = make_file_dialog(FILE_READ_ONLY, "Mix", "mix:", "Mix", FILE_MIX_DIALOG, (GCallback)file_mix_ok_callback, NULL, /* no mkdir */ (GCallback)file_mix_delete_callback, (GCallback)file_mix_cancel_callback, (GCallback)file_mix_help_callback, ICON_ADD); } if (managed) gtk_widget_show(mdat->dialog); return(mdat->dialog); } /* -------- File:Insert dialog -------- */ static void file_insert_cancel_callback(GtkWidget *w, gpointer context) { file_dialog_stop_playing(idat); gtk_widget_hide(idat->dialog); } static void file_insert_help_callback(GtkWidget *w, gpointer context) { insert_file_dialog_help(); } static gint file_insert_delete_callback(GtkWidget *w, GdkEvent *event, gpointer context) { file_dialog_stop_playing(idat); gtk_widget_hide(idat->dialog); return(true); } static void file_insert_ok_callback(GtkWidget *w, gpointer context) { file_dialog_info *fd = (file_dialog_info *)context; char *filename; filename = fd->filename; /* gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fd->chooser)); */ if ((!filename) || (!(*filename))) { file_open_error("no filename given", fd); } else { file_dialog_stop_playing(fd); if (!(is_directory(filename))) /* this can be a directory name if the user clicked 'ok' when he meant 'cancel' */ { bool ok; snd_info *sp; sp = any_selected_sound(); ss->requestor_dialog = w; ss->open_requestor = FROM_INSERT_DIALOG; redirect_snd_error_to(redirect_file_open_error, (void *)fd); ok = insert_complete_file_at_cursor(sp, filename); redirect_snd_error_to(NULL, NULL); if (!ok) { if (ss->open_requestor != FROM_RAW_DATA_DIALOG) { char *fullname; fullname = mus_expand_filename(filename); if (!(mus_file_probe(fullname))) start_unsound_watcher(fd, filename); free(fullname); } } else { status_report(sp, "%s inserted at cursor", filename); } } else { char *str; str = mus_format("%s is a directory", filename); file_open_error(str, fd); free(str); } } } widget_t make_insert_file_dialog(bool managed) { if (idat == NULL) idat = make_file_dialog(FILE_READ_ONLY, "Insert", "insert:", "Insert", FILE_INSERT_DIALOG, (GCallback)file_insert_ok_callback, NULL, /* no mkdir */ (GCallback)file_insert_delete_callback, (GCallback)file_insert_cancel_callback, (GCallback)file_insert_help_callback, ICON_PASTE); if (managed) gtk_widget_show(idat->dialog); return(idat->dialog); } void set_open_file_play_button(bool val) { } /* ---------------- file data panel ---------------- */ char *get_file_dialog_sound_attributes(file_data *fdat, int *srate, int *chans, mus_header_t *header_type, mus_sample_t *sample_type, mus_long_t *location, mus_long_t *samples, int min_chan) { char *str; int res; fdat->error_widget = NOT_A_SCANF_WIDGET; fdat->scanf_widget = NOT_A_SCANF_WIDGET; if ((srate) && (fdat->srate_text)) { str = (char *)gtk_entry_get_text(GTK_ENTRY(fdat->srate_text)); fdat->scanf_widget = SRATE_WIDGET; if ((str) && (*str)) (*srate) = string_to_int(str, 1, "srate"); else snd_error_without_format("no srate?"); } if ((chans) && (fdat->chans_text)) { str = (char *)gtk_entry_get_text(GTK_ENTRY(fdat->chans_text)); fdat->scanf_widget = CHANS_WIDGET; if ((str) && (*str)) (*chans) = string_to_int(str, min_chan, "chans"); else { if (min_chan > 0) snd_error_without_format("no chans?"); } } if ((location) && (fdat->location_text)) { str = (char *)gtk_entry_get_text(GTK_ENTRY(fdat->location_text)); fdat->scanf_widget = DATA_LOCATION_WIDGET; if ((str) && (*str)) (*location) = string_to_mus_long_t(str, 0, "data location"); else snd_error_without_format("no data location?"); } if ((samples) && (fdat->samples_text)) { str = (char *)gtk_entry_get_text(GTK_ENTRY(fdat->samples_text)); fdat->scanf_widget = SAMPLES_WIDGET; if ((str) && (*str)) (*samples) = string_to_mus_long_t(str, 0, "samples"); else snd_error_without_format("no samples?"); } fdat->scanf_widget = SAMPLES_WIDGET; if (fdat->header_type_list) { res = fdat->header_type_list->selected_item; if (res == SLIST_NO_ITEM_SELECTED) res = fdat->header_type_pos; if (res != NO_SELECTION) { (*header_type) = position_to_header_type(res); fdat->current_header_type = (*header_type); } } if (fdat->sample_type_list) { res = fdat->sample_type_list->selected_item; if (res == SLIST_NO_ITEM_SELECTED) /* can this happen? */ res = fdat->sample_type_pos; if (res != NO_SELECTION) { (*sample_type) = position_to_sample_type(fdat->current_header_type, res); fdat->current_sample_type = (*sample_type); } } if (fdat->comment_text) { char *comment = NULL; if (GTK_IS_TEXT_VIEW(fdat->comment_text)) comment = sg_get_text(fdat->comment_text, 0, -1); else comment = (char *)gtk_entry_get_text(GTK_ENTRY(fdat->comment_text)); str = mus_strdup(comment); return(str); } return(NULL); } #define IGNORE_DATA_LOCATION -1 #define IGNORE_SAMPLES MUS_UNKNOWN_SAMPLE #define IGNORE_CHANS -1 #define IGNORE_SRATE -1 #define IGNORE_HEADER_TYPE MUS_UNKNOWN_HEADER static void set_file_dialog_sound_attributes(file_data *fdat, mus_header_t header_type, mus_sample_t sample_type, int srate, int chans, mus_long_t location, mus_long_t samples, char *comment) { int i; const char **fl = NULL; if (!(fdat->sample_type_list)) return; if (header_type != IGNORE_HEADER_TYPE) fdat->current_header_type = header_type; else fdat->current_header_type = MUS_RAW; fdat->current_sample_type = sample_type; fl = header_type_and_sample_type_to_position(fdat, fdat->current_header_type, fdat->current_sample_type); if (fl == NULL) return; if ((header_type != IGNORE_HEADER_TYPE) && (fdat->header_type_list)) { slist_select(fdat->header_type_list, fdat->header_type_pos); slist_moveto(fdat->header_type_list, fdat->header_type_pos); } slist_clear(fdat->sample_type_list); for (i = 0; i < fdat->sample_types; i++) slist_append(fdat->sample_type_list, (const char *)fl[i]); slist_select(fdat->sample_type_list, fdat->sample_type_pos); slist_moveto(fdat->sample_type_list, fdat->sample_type_pos); if ((srate != IGNORE_SRATE) && (fdat->srate_text)) widget_int_to_text(fdat->srate_text, srate); if ((chans != IGNORE_CHANS) && (fdat->chans_text)) widget_int_to_text(fdat->chans_text, chans); if (fdat->comment_text) { if (GTK_IS_TEXT_VIEW(fdat->comment_text)) { gtk_text_buffer_set_text(gtk_text_view_get_buffer(GTK_TEXT_VIEW(fdat->comment_text)), "", 0); sg_text_insert(fdat->comment_text, comment); } else gtk_entry_set_text(GTK_ENTRY(fdat->comment_text), comment); } if ((location != IGNORE_DATA_LOCATION) && (fdat->location_text)) widget_mus_long_t_to_text(fdat->location_text, location); if ((samples != IGNORE_SAMPLES) && (fdat->samples_text)) widget_mus_long_t_to_text(fdat->samples_text, samples); } static gboolean data_panel_srate_key_press(GtkWidget *w, GdkEventKey *event, gpointer data) { if (EVENT_KEYVAL(event) == snd_K_Tab) { gtk_entry_set_text(GTK_ENTRY(w), srate_completer(w, (char *)gtk_entry_get_text(GTK_ENTRY(w)), NULL)); gtk_editable_set_position(GTK_EDITABLE(w), mus_strlen((char *)gtk_entry_get_text(GTK_ENTRY(w)))); return(true); } return(false); } #define NUM_REFLECTION_IDS 5 enum {REFLECT_SRATE_ID, REFLECT_CHANS_ID, REFLECT_SAMPLES_ID, REFLECT_LOCATION_ID, REFLECT_COMMENT_ID}; static void reflect_file_data_panel_change(file_data *fd, void *data, void (*change_action)(GtkWidget *w, gpointer context)) { if (!(fd->reflection_ids)) fd->reflection_ids = (gulong *)calloc(NUM_REFLECTION_IDS, sizeof(gulong)); if (fd->srate_text) fd->reflection_ids[REFLECT_SRATE_ID] = SG_SIGNAL_CONNECT(fd->srate_text, "changed", change_action, (gpointer)data); if (fd->chans_text) fd->reflection_ids[REFLECT_CHANS_ID] = SG_SIGNAL_CONNECT(fd->chans_text, "changed", change_action, (gpointer)data); if (fd->samples_text) fd->reflection_ids[REFLECT_SAMPLES_ID] = SG_SIGNAL_CONNECT(fd->samples_text, "changed", change_action, (gpointer)data); if (fd->location_text) fd->reflection_ids[REFLECT_LOCATION_ID] = SG_SIGNAL_CONNECT(fd->location_text, "changed", change_action, (gpointer)data); if (fd->comment_text) { if (GTK_IS_TEXT_VIEW(fd->comment_text)) fd->reflection_ids[REFLECT_COMMENT_ID] = SG_SIGNAL_CONNECT(gtk_text_view_get_buffer(GTK_TEXT_VIEW(fd->comment_text)), "changed", change_action, (gpointer)data); else fd->reflection_ids[REFLECT_COMMENT_ID] = SG_SIGNAL_CONNECT(fd->comment_text, "changed", change_action, (gpointer)data); } } static void unreflect_file_data_panel_change(file_data *fd, void *data, void (*change_action)(GtkWidget *w, gpointer context)) { int i; if (!(fd->reflection_ids)) return; if ((fd->srate_text) && (fd->reflection_ids[REFLECT_SRATE_ID] > 0)) g_signal_handler_disconnect(fd->srate_text, fd->reflection_ids[REFLECT_SRATE_ID]); if ((fd->chans_text) && (fd->reflection_ids[REFLECT_CHANS_ID] > 0)) g_signal_handler_disconnect(fd->chans_text, fd->reflection_ids[REFLECT_CHANS_ID]); if ((fd->samples_text) && (fd->reflection_ids[REFLECT_SAMPLES_ID] > 0)) g_signal_handler_disconnect(fd->samples_text, fd->reflection_ids[REFLECT_SAMPLES_ID]); if ((fd->location_text) && (fd->reflection_ids[REFLECT_LOCATION_ID] > 0)) g_signal_handler_disconnect(fd->location_text, fd->reflection_ids[REFLECT_LOCATION_ID]); if ((fd->comment_text) && (fd->reflection_ids[REFLECT_COMMENT_ID] > 0)) { if (GTK_IS_TEXT_VIEW(fd->comment_text)) g_signal_handler_disconnect(gtk_text_view_get_buffer(GTK_TEXT_VIEW(fd->comment_text)), fd->reflection_ids[REFLECT_COMMENT_ID]); else g_signal_handler_disconnect(fd->comment_text, fd->reflection_ids[REFLECT_COMMENT_ID]); } for (i = 0; i < NUM_REFLECTION_IDS; i++) fd->reflection_ids[i] = 0; } /* -------- panel error handling -------- */ /* if an error occurs, a callback is added to the offending text widget, and an error is * posted in the error_text label. When the user modifies the bad entry, the callback * erases the error message, and removes itself from the text widget. */ static void clear_dialog_error(file_data *fdat) { gtk_label_set_text(GTK_LABEL(fdat->error_text), ""); } static void post_file_dialog_error(const char *error_msg, file_data *fdat) { gtk_label_set_text(GTK_LABEL(fdat->error_text), (gchar *)error_msg); } static void redirect_post_file_dialog_error(const char *error_msg, void *ufd) { file_data *fdat = (file_data *)ufd; gtk_label_set_text(GTK_LABEL(fdat->error_text), error_msg); } static gulong chans_key_press_handler_id = 0; static gboolean chans_key_press_callback(GtkWidget *w, GdkEventKey *event, gpointer data) { file_data *fdat = (file_data *)data; gtk_label_set_text(GTK_LABEL(fdat->error_text), ""); if (chans_key_press_handler_id) { g_signal_handler_disconnect(fdat->chans_text, chans_key_press_handler_id); chans_key_press_handler_id = 0; } return(false); } static void clear_error_if_chans_changes(GtkWidget *dialog, void *data) { file_data *fdat = (file_data *)data; if (fdat->chans_text) chans_key_press_handler_id = SG_SIGNAL_CONNECT(fdat->chans_text, "key_press_event", chans_key_press_callback, data); } static gulong panel_modify_handler_id = 0; static gboolean panel_modify_callback(GtkWidget *w, GdkEventKey *event, gpointer data) { file_data *fdat = (file_data *)data; gtk_label_set_text(GTK_LABEL(fdat->error_text), ""); if (panel_modify_handler_id) { g_signal_handler_disconnect(w, panel_modify_handler_id); panel_modify_handler_id = 0; } return(false); } static void clear_error_if_panel_changes(GtkWidget *dialog, file_data *fdat) { GtkWidget *baddy; switch (fdat->error_widget) { case SRATE_WIDGET: baddy = fdat->srate_text; break; case DATA_LOCATION_WIDGET: baddy = fdat->location_text; break; case SAMPLES_WIDGET: baddy = fdat->samples_text; break; default: baddy = fdat->chans_text; break; } if (baddy) panel_modify_handler_id = SG_SIGNAL_CONNECT(baddy, "key_press_event", panel_modify_callback, (void *)fdat); } static void post_file_panel_error(const char *error_msg, file_data *fdat) { fdat->error_widget = fdat->scanf_widget; post_file_dialog_error(error_msg, fdat); } static void redirect_post_file_panel_error(const char *error_msg, void *ufd) { post_file_panel_error(error_msg, (file_data *)ufd); } /* -------- file data choices -------- */ static void update_header_type_list(const char *name, int row, void *data) { /* needed to reflect type selection in sample_type list */ file_data *fdat = (file_data *)data; if (position_to_header_type(row) != fdat->current_header_type) { position_to_header_type_and_sample_type(fdat, row); set_file_dialog_sound_attributes(fdat, fdat->current_header_type, fdat->current_sample_type, IGNORE_SRATE, IGNORE_CHANS, IGNORE_DATA_LOCATION, IGNORE_SAMPLES, NULL); } } static void update_sample_type_list(const char *name, int row, void *data) { file_data *fdat = (file_data *)data; fdat->current_sample_type = position_to_sample_type(fdat->current_header_type, row); } static void file_data_src_callback(GtkWidget *w, gpointer context) { file_data *fdat = (file_data *)context; fdat->src = (bool)(TOGGLE_BUTTON_ACTIVE(w)); } #define WITH_SRATE_FIELD true #define WITHOUT_SRATE_FIELD false #define WITHOUT_AUTO_COMMENT false static file_data *make_file_data_panel(GtkWidget *parent, const char *name, dialog_channels_t with_chan, mus_header_t header_type, mus_sample_t sample_type, dialog_data_location_t with_loc, dialog_samples_t with_samples, dialog_header_type_t with_header_type, dialog_comment_t with_comment, header_choice_t header_choice, bool with_src, bool with_auto_comment) { GtkWidget *form, *scbox, *frame_box, *frame; file_data *fdat; int nsample_types = 0, nheaders = 0; const char **sample_types = NULL, **headers = NULL; switch (header_choice) { case WITH_READABLE_HEADERS: headers = short_readable_headers(&nheaders); break; case WITH_WRITABLE_HEADERS: headers = short_writable_headers(&nheaders); break; case WITH_BUILTIN_HEADERS: headers = short_builtin_headers(&nheaders); break; } fdat = (file_data *)calloc(1, sizeof(file_data)); fdat->src = save_as_dialog_src(ss); fdat->auto_comment = save_as_dialog_auto_comment(ss); fdat->saved_comment = NULL; fdat->current_header_type = header_type; fdat->current_sample_type = sample_type; sample_types = header_type_and_sample_type_to_position(fdat, header_type, sample_type); nsample_types = fdat->sample_types; frame = gtk_frame_new(NULL); gtk_box_pack_start(GTK_BOX(parent), frame, false, true, 8); gtk_widget_show(frame); frame_box = gtk_vbox_new(false, 0); gtk_container_add(GTK_CONTAINER(frame), frame_box); gtk_widget_show(frame_box); form = gtk_hbox_new(true, 8); gtk_box_pack_start(GTK_BOX(frame_box), form, false, false, 4); gtk_widget_show(form); /* header type */ if (with_header_type == WITH_HEADER_TYPE_FIELD) { fdat->header_type_list = slist_new_with_title("header type", form, (const char **)headers, nheaders, BOX_PACK); /* BOX_PACK widget_add_t (snd-g0.h) */ fdat->header_type_list->select_callback = update_header_type_list; fdat->header_type_list->select_callback_data = (void *)fdat; slist_select(fdat->header_type_list, fdat->header_type_pos); } /* sample type */ #if GTK_CHECK_VERSION(3, 0, 0) fdat->sample_type_list = slist_new_with_title(" sample type ", form, (const char **)sample_types, nsample_types, BOX_PACK); #else fdat->sample_type_list = slist_new_with_title("sample type", form, (const char **)sample_types, nsample_types, BOX_PACK); #endif fdat->sample_type_list->select_callback = update_sample_type_list; fdat->sample_type_list->select_callback_data = (void *)fdat; slist_select(fdat->sample_type_list, fdat->sample_type_pos); scbox = gtk_vbox_new(false, 0); gtk_box_pack_start(GTK_BOX(form), scbox, false, false, 4); gtk_widget_show(scbox); /* srate */ { GtkWidget *srate_label; srate_label = snd_gtk_highlight_label_new("srate"); gtk_box_pack_start(GTK_BOX(scbox), srate_label, false, false, 0); gtk_widget_show(srate_label); if (with_src) { GtkWidget *src_box; src_box = gtk_hbox_new(false, 0); gtk_box_pack_start(GTK_BOX(scbox), src_box, false, false, 0); gtk_widget_show(src_box); fdat->srate_text = snd_entry_new(src_box, NULL, WITH_WHITE_BACKGROUND); gtk_entry_set_width_chars(GTK_ENTRY(fdat->srate_text), 8); SG_SIGNAL_CONNECT(fdat->srate_text, "key_press_event", data_panel_srate_key_press, NULL); /* srate completer */ fdat->src_button = gtk_check_button_new_with_label("src"); gtk_box_pack_end(GTK_BOX(src_box), fdat->src_button, false, false, 4); SG_SIGNAL_CONNECT(fdat->src_button, "toggled", file_data_src_callback, fdat); gtk_widget_show(fdat->src_button); set_toggle_button(fdat->src_button, fdat->src, false, (void *)fdat); } else { fdat->srate_text = snd_entry_new(scbox, NULL, WITH_WHITE_BACKGROUND); SG_SIGNAL_CONNECT(fdat->srate_text, "key_press_event", data_panel_srate_key_press, NULL); /* srate completer */ } } if (with_samples != WITH_SAMPLES_FIELD) { GtkWidget *spacer; spacer = gtk_vseparator_new(); gtk_box_pack_start(GTK_BOX(scbox), spacer, false, false, 12); gtk_widget_show(spacer); } /* chans */ if (with_chan != WITHOUT_CHANNELS_FIELD) { GtkWidget *chans_label; chans_label = snd_gtk_highlight_label_new((with_chan == WITH_CHANNELS_FIELD) ? "channels" : "extract channel"); gtk_box_pack_start(GTK_BOX(scbox), chans_label, false, false, 0); gtk_widget_show(chans_label); fdat->chans_text = snd_entry_new(scbox, NULL, WITH_WHITE_BACKGROUND); if (with_loc == WITH_DATA_LOCATION_FIELD) { GtkWidget *loclab; loclab = snd_gtk_highlight_label_new("location"); gtk_box_pack_start(GTK_BOX(scbox), loclab, false, false, 0); gtk_widget_show(loclab); fdat->location_text = snd_entry_new(scbox, NULL, WITH_WHITE_BACKGROUND); } } /* samples */ if (with_samples == WITH_SAMPLES_FIELD) { GtkWidget *samplab; samplab = snd_gtk_highlight_label_new("samples"); gtk_box_pack_start(GTK_BOX(scbox), samplab, false, false, 0); gtk_widget_show(samplab); fdat->samples_text = snd_entry_new(scbox, NULL, WITH_WHITE_BACKGROUND); } else { /* need a spacer to force the lists to have room */ GtkWidget *spacer; spacer = gtk_vseparator_new(); gtk_box_pack_start(GTK_BOX(scbox), spacer, false, false, 12); gtk_widget_show(spacer); } /* comment */ if (with_comment != WITHOUT_COMMENT_FIELD) { GtkWidget *frame, *comment_label; GtkWidget *w1, *combox; w1 = gtk_vseparator_new(); gtk_box_pack_start(GTK_BOX(frame_box), w1, false, false, 4); gtk_widget_show(w1); combox = gtk_hbox_new(false, 0); gtk_box_pack_start(GTK_BOX(frame_box), combox, false, true, 4); gtk_widget_show(combox); if (with_auto_comment) { GtkWidget *cbox; cbox = gtk_vbox_new(false, 0); gtk_box_pack_start(GTK_BOX(combox), cbox, false, false, 0); gtk_widget_show(cbox); comment_label = snd_gtk_highlight_label_new("comment"); gtk_box_pack_start(GTK_BOX(cbox), comment_label, false, false, 0); gtk_widget_show(comment_label); fdat->auto_comment_button = gtk_check_button_new_with_label("auto"); gtk_box_pack_end(GTK_BOX(cbox), fdat->auto_comment_button, false, false, 4); gtk_widget_show(fdat->auto_comment_button); set_toggle_button(fdat->auto_comment_button, fdat->auto_comment, false, (void *)fdat); } else { comment_label = snd_gtk_highlight_label_new("comment"); gtk_box_pack_start(GTK_BOX(combox), comment_label, false, false, 0); gtk_widget_show(comment_label); } frame = gtk_frame_new(NULL); gtk_box_pack_start(GTK_BOX(combox), frame, true, true, 4); gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN); gtk_widget_show(frame); fdat->comment_text = make_scrolled_text(frame, true, CONTAINER_ADD, false); /* this returns a text_view widget */ connect_mouse_to_text(fdat->comment_text); } /* error */ fdat->error_text = gtk_label_new(NULL); gtk_box_pack_end(GTK_BOX(parent), fdat->error_text, false, false, 0); gtk_widget_show(fdat->error_text); return(fdat); } /* -------- save as dialog (file and edit menus) -------- */ static file_dialog_info *save_sound_as = NULL, *save_selection_as = NULL, *save_region_as = NULL; void reflect_save_as_sound_selection(const char *sound_name) { if (save_sound_as) { char *file_string; if (sound_name) file_string = mus_format("save %s", sound_name); else { snd_info *sp; sp = any_selected_sound(); if (sp) file_string = mus_format("save %s", sp->short_filename); else file_string = mus_strdup("nothing to save!"); } gtk_window_set_title(GTK_WINDOW(save_sound_as->dialog), file_string); free(file_string); } } void reflect_save_as_src(bool val) { if (save_sound_as) { set_toggle_button(save_sound_as->panel_data->src_button, val, false, (void *)save_sound_as); save_sound_as->panel_data->src = val; } if (save_selection_as) { set_toggle_button(save_selection_as->panel_data->src_button, val, false, (void *)save_selection_as); save_selection_as->panel_data->src = val; } if (save_region_as) { set_toggle_button(save_region_as->panel_data->src_button, val, false, (void *)save_region_as); save_region_as->panel_data->src = val; } } void reflect_save_as_auto_comment(bool val) { if (save_sound_as) { set_toggle_button(save_sound_as->panel_data->auto_comment_button, val, false, (void *)save_sound_as); save_sound_as->panel_data->auto_comment = val; } } static void make_auto_comment(file_dialog_info *fd) { if ((fd == save_sound_as) && (widget_is_active(fd->dialog))) { file_data *fdat; fdat = fd->panel_data; if (!(fdat->auto_comment)) { /* don't erase typed-in comment, if any */ sg_text_insert(fdat->comment_text, fdat->saved_comment); } else { snd_info *sp; bool edits = false; int i; char *original_sound_comment, *comment, *orig_comment = NULL; sp = any_selected_sound(); original_sound_comment = mus_sound_comment(sp->filename); if (original_sound_comment) { if (*original_sound_comment) orig_comment = mus_format("\n%s comment:\n%s\n", sp->short_filename, original_sound_comment); free(original_sound_comment); original_sound_comment = NULL; } fdat->saved_comment = sg_get_text(fdat->comment_text, 0, -1); if ((fdat->saved_comment) && (!(*(fdat->saved_comment)))) fdat->saved_comment = NULL; for (i = 0; i < sp->nchans; i++) if (sp->chans[i]->edit_ctr != 0) { edits = true; break; } if (!edits) comment = mus_format("%ssaved %s from %s (no edits)\n%s", (fdat->saved_comment) ? "\n" : "", snd_local_time(), sp->filename, (orig_comment) ? orig_comment : ""); else { int len; char **edit_strs; char *time; time = snd_local_time(); len = 2 * mus_strlen(sp->filename) + mus_strlen(time) + 32 * sp->nchans + mus_strlen(fdat->saved_comment) + mus_strlen(original_sound_comment); edit_strs = (char **)malloc(sp->nchans * sizeof(char *)); for (i = 0; i < sp->nchans; i++) { edit_strs[i] = edit_list_to_function(sp->chans[i], 1, sp->chans[i]->edit_ctr); len += mus_strlen(edit_strs[i]); } comment = (char *)calloc(len, sizeof(char)); snprintf(comment, len, "%ssaved %s from %s with edits:\n", (fdat->saved_comment) ? "\n" : "", snd_local_time(), sp->filename); for (i = 0; i < sp->nchans; i++) { if (sp->nchans > 1) { char buf[32]; snprintf(buf, 32, "\n-------- channel %d --------\n", i); strcat(comment, buf); } strcat(comment, edit_strs[i]); } if (orig_comment) strcat(comment, orig_comment); free(edit_strs); } sg_text_insert(fdat->comment_text, comment); if (comment) free(comment); if (orig_comment) free(orig_comment); } } } static void file_data_auto_comment_callback(GtkWidget *w, gpointer context) { file_dialog_info *fd = (file_dialog_info *)context; fd->panel_data->auto_comment = (bool)(TOGGLE_BUTTON_ACTIVE(w)); make_auto_comment(fd); } void reflect_selection_in_save_as_dialog(bool on) { if ((on) && (save_selection_as) && (save_selection_as->panel_data)) clear_dialog_error(save_selection_as->panel_data); } void reflect_region_in_save_as_dialog(void) { if ((save_region_as) && (save_region_as->dialog) && (widget_is_active(save_region_as->dialog)) && (region_ok(region_dialog_region()))) clear_dialog_error(save_region_as->panel_data); } static void save_as_undoit(file_dialog_info *fd) { set_stock_button_label(fd->ok_button, "Save"); clear_dialog_error(fd->panel_data); fd->file_watcher = unmonitor_file(fd->file_watcher); } #if HAVE_G_FILE_MONITOR_DIRECTORY static void watch_save_as_file(GFileMonitor *mon, GFile *file, GFile *other, GFileMonitorEvent ev, gpointer data) { /* if file is deleted, respond in some debonair manner */ switch (ev) { case G_FILE_MONITOR_EVENT_CHANGED: case G_FILE_MONITOR_EVENT_DELETED: case G_FILE_MONITOR_EVENT_CREATED: #if HAVE_GTK_WIDGET_GET_VISIBLE case G_FILE_MONITOR_EVENT_MOVED: #endif save_as_undoit((file_dialog_info *)data); break; default: /* ignore the rest */ break; } } #endif static bool srates_differ(int srate, file_dialog_info *fd) { switch (fd->type) { case SOUND_SAVE_AS: return(snd_srate(any_selected_sound()) != srate); case SELECTION_SAVE_AS: return(selection_srate() != srate); case REGION_SAVE_AS: return(region_srate(region_dialog_region()) != srate); } return(false); } static double srate_ratio(int srate, file_dialog_info *fd) { switch (fd->type) { case SOUND_SAVE_AS: return((double)(snd_srate(any_selected_sound())) / (double)srate); case SELECTION_SAVE_AS: return((double)selection_srate() / (double)srate); case REGION_SAVE_AS: return((double)region_srate(region_dialog_region()) / (double)srate); } return(1.0); } static void save_or_extract(file_dialog_info *fd, bool saving) { char *str = NULL, *comment = NULL, *msg = NULL, *fullname = NULL, *tmpfile = NULL; snd_info *sp = NULL; mus_header_t header_type = MUS_NEXT, output_type; mus_sample_t sample_type = DEFAULT_OUTPUT_SAMPLE_TYPE; int srate = DEFAULT_OUTPUT_SRATE, chans = DEFAULT_OUTPUT_CHANS; int chan = 0, extractable_chans = 0; bool file_exists = false; mus_long_t location = 28, samples = 0; io_error_t io_err = IO_NO_ERROR; clear_dialog_error(fd->panel_data); if ((fd->type == SELECTION_SAVE_AS) && (!(selection_is_active()))) { if (saving) msg = (char *)"no selection to save"; else msg = (char *)"can't extract: no selection"; post_file_dialog_error((const char *)msg, fd->panel_data); return; } if ((fd->type == REGION_SAVE_AS) && (!(region_ok(region_dialog_region())))) { post_file_dialog_error("no region to save", fd->panel_data); return; } sp = any_selected_sound(); if ((!sp) && (fd->type != REGION_SAVE_AS)) { if (saving) msg = (char *)"nothing to save"; else msg = (char *)"nothing to extract"; post_file_dialog_error((const char *)msg, fd->panel_data); return; } /* get output filename */ str = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fd->chooser)); if ((!str) || (!*str)) { if (saving) msg = (char *)"can't save: no file name given"; else msg = (char *)"can't extract: no file name given"; post_file_dialog_error((const char *)msg, fd->panel_data); return; } if (is_directory(str)) { post_file_dialog_error("can't overwrite a directory", fd->panel_data); return; } /* get output file attributes */ redirect_snd_error_to(redirect_post_file_panel_error, (void *)(fd->panel_data)); if (saving) comment = get_file_dialog_sound_attributes(fd->panel_data, &srate, &chans, &header_type, &sample_type, &location, &samples, 0); else comment = get_file_dialog_sound_attributes(fd->panel_data, &srate, &chan, &header_type, &sample_type, &location, &samples, 0); output_type = header_type; redirect_snd_error_to(NULL, NULL); if (fd->panel_data->error_widget != NOT_A_SCANF_WIDGET) { clear_error_if_panel_changes(fd->dialog, fd->panel_data); if (comment) free(comment); return; } switch (fd->type) { case SOUND_SAVE_AS: clear_status_area(sp); if (!saving) extractable_chans = sp->nchans; break; case SELECTION_SAVE_AS: if (!saving) extractable_chans = selection_chans(); break; default: break; } if (!saving) { if ((chan > extractable_chans) || (((extractable_chans > 1) && (chan == extractable_chans)) || (chan < 0))) { if (chan > extractable_chans) msg = mus_format("can't extract chan %d (%s has %d chan%s)", chan, (fd->type == SOUND_SAVE_AS) ? "sound" : "selection", extractable_chans, (extractable_chans > 1) ? "s" : ""); else msg = mus_format("can't extract chan %d (first chan is numbered 0)", chan); post_file_dialog_error((const char *)msg, fd->panel_data); clear_error_if_chans_changes(fd->dialog, (void *)(fd->panel_data)); free(msg); if (comment) free(comment); return; } } fullname = mus_expand_filename(str); if (run_before_save_as_hook(sp, fullname, fd->type != SOUND_SAVE_AS, srate, sample_type, header_type, comment)) { msg = mus_format("%s cancelled by %s", (saving) ? "save" : "extract", S_before_save_as_hook); post_file_dialog_error((const char *)msg, fd->panel_data); free(msg); free(fullname); if (comment) free(comment); return; } file_exists = mus_file_probe(fullname); if ((fd->type == SOUND_SAVE_AS) && (mus_strcmp(fullname, sp->filename))) { /* save-as here is the same as save */ if ((sp->user_read_only == FILE_READ_ONLY) || (sp->file_read_only == FILE_READ_ONLY)) { msg = mus_format("can't overwrite %s (it is write-protected)", sp->short_filename); post_file_dialog_error((const char *)msg, fd->panel_data); free(msg); free(fullname); if (comment) free(comment); return; } } else { if (!(fd->file_watcher)) { /* check for overwrites that are questionable -- DoIt click will return here with fd->file_watcher active */ snd_info *parlous_sp = NULL; if ((file_exists) && ((ask_before_overwrite(ss)) || ((fd->type == SOUND_SAVE_AS) && (parlous_sp = file_is_open_elsewhere_and_has_unsaved_edits(sp, fullname))))) { msg = mus_format("%s exists%s. To overwrite it, click '%s'", str, (parlous_sp) ? ", and has unsaved edits" : "", "DoIt" ); #if HAVE_G_FILE_MONITOR_DIRECTORY { GFile *file; GError *err = NULL; file = g_file_new_for_path(fullname); fd->file_watcher = (void *)g_file_monitor_file(file, G_FILE_MONITOR_NONE, NULL, &err); if (err != NULL) snd_warning("%s", err->message); else g_signal_connect(G_OBJECT(fd->file_watcher), "changed", G_CALLBACK(watch_save_as_file), (gpointer)fd); g_object_unref(file); } #endif post_file_dialog_error((const char *)msg, fd->panel_data); set_stock_button_label(fd->ok_button, "DoIt"); free(msg); free(fullname); if (comment) free(comment); return; } } } /* try to save... if it exists already, first write as temp, then move */ if (fd->file_watcher) save_as_undoit(fd); ss->local_errno = 0; if (header_is_encoded(header_type)) { output_type = header_type; sample_type = MUS_LSHORT; header_type = MUS_RIFF; tmpfile = snd_tempnam(); } else { tmpfile = fullname; } redirect_snd_error_to(redirect_post_file_dialog_error, (void *)(fd->panel_data)); switch (fd->type) { case SOUND_SAVE_AS: if (saving) io_err = save_edits_without_display(sp, tmpfile, header_type, sample_type, srate, comment, AT_CURRENT_EDIT_POSITION); else io_err = save_channel_edits(sp->chans[chan], tmpfile, AT_CURRENT_EDIT_POSITION); /* protects if same name */ break; case SELECTION_SAVE_AS: { char *ofile; if (file_exists) /* file won't exist if we're encoding, so this isn't as wasteful as it looks */ ofile = snd_tempnam(); else ofile = mus_strdup(tmpfile); io_err = save_selection(ofile, srate, sample_type, header_type, comment, (saving) ? SAVE_ALL_CHANS : chan); if (io_err == IO_NO_ERROR) io_err = move_file(ofile, fullname); free(ofile); break; } case REGION_SAVE_AS: { if (region_ok(region_dialog_region())) { char *ofile; if (file_exists) ofile = snd_tempnam(); else ofile = mus_strdup(tmpfile); io_err = save_region(region_dialog_region(), ofile, sample_type, header_type, comment); if (io_err == IO_NO_ERROR) io_err = move_file(ofile, fullname); free(ofile); } } break; } redirect_snd_error_to(NULL, NULL); /* check for possible srate conversion */ if ((fd->panel_data->src) && (srates_differ(srate, fd))) { /* if src, and srates differ, do the sampling rate conversion. * this needs to happen before the snd_encode (->OGG etc) below * if we do it before the save-as above, then undo it later, it messes up the user's edit history list * so do it here to tmpfile (tmpfile is fullname unless we're doing a translation to something like OGG) */ src_file(tmpfile, srate_ratio(srate, fd)); } if (io_err == IO_NO_ERROR) { if (header_is_encoded(output_type)) { snd_encode(output_type, tmpfile, fullname); snd_remove(tmpfile, REMOVE_FROM_CACHE); free(tmpfile); } if (saving) { if (fd->type == SOUND_SAVE_AS) status_report(sp, "%s saved as %s", sp->short_filename, str); else status_report(sp, "%s saved as %s", (fd->type == SELECTION_SAVE_AS) ? "selection" : "region", str); } else { if (fd->type == SOUND_SAVE_AS) status_report(sp, "%s chan %d saved as %s", sp->short_filename, chan, str); else status_report(sp, "selection chan %d saved as %s", chan, str); } run_after_save_as_hook(sp, str, true); /* true => from dialog */ gtk_widget_hide(fd->dialog); } else { msg = mus_format("%s as %s: %s (%s)", (saving) ? "save" : "extract chan", str, io_error_name(io_err), snd_io_strerror()); post_file_dialog_error((const char *)msg, fd->panel_data); free(msg); } free(fullname); if (comment) free(comment); } static void save_as_ok_callback(GtkWidget *w, gpointer data) { save_or_extract((file_dialog_info *)data, true); } static void save_as_extract_callback(GtkWidget *w, gpointer data) { save_or_extract((file_dialog_info *)data, false); } static void save_as_cancel_callback(GtkWidget *w, gpointer data) { file_dialog_info *fd = (file_dialog_info *)data; gtk_widget_hide(fd->dialog); } static void save_as_help_callback(GtkWidget *w, gpointer data) { save_as_dialog_help(); } static gint save_as_delete_callback(GtkWidget *w, GdkEvent *event, gpointer context) { file_dialog_info *fd = (file_dialog_info *)context; gtk_widget_hide(fd->dialog); return(true); } static file_dialog_info *make_save_as_dialog(const char *file_string, mus_header_t header_type, mus_sample_t sample_type, int dialog_type) { file_dialog_info *fd; GtkWidget *vbox; fd = make_fsb(file_string, "save as:", "Save as", ICON_SAVE_AS, (dialog_type != REGION_SAVE_AS), true); fd->type = (save_dialog_t)dialog_type; fd->header_type = header_type; fd->sample_type = sample_type; vbox = DIALOG_CONTENT_AREA(fd->dialog); fd->panel_data = make_file_data_panel(vbox, "data-form", (fd->type == REGION_SAVE_AS) ? WITHOUT_CHANNELS_FIELD : WITH_EXTRACT_CHANNELS_FIELD, fd->header_type, fd->sample_type, WITHOUT_DATA_LOCATION_FIELD, WITHOUT_SAMPLES_FIELD, WITH_HEADER_TYPE_FIELD, WITH_COMMENT_FIELD, WITH_WRITABLE_HEADERS, WITH_SRATE_FIELD, fd->type == SOUND_SAVE_AS); gtk_widget_show(fd->dialog); if (fd->type != REGION_SAVE_AS) SG_SIGNAL_CONNECT(fd->extract_button, "clicked", save_as_extract_callback, (void *)fd); SG_SIGNAL_CONNECT(fd->help_button, "clicked", save_as_help_callback, (gpointer)fd); SG_SIGNAL_CONNECT(fd->ok_button, "clicked", save_as_ok_callback, (gpointer)fd); SG_SIGNAL_CONNECT(fd->cancel_button, "clicked", save_as_cancel_callback, (gpointer)fd); fd->panel_data->dialog = fd->dialog; switch (fd->type) { case SOUND_SAVE_AS: set_dialog_widget(SOUND_SAVE_AS_DIALOG, fd->dialog); break; case SELECTION_SAVE_AS: set_dialog_widget(SELECTION_SAVE_AS_DIALOG, fd->dialog); break; case REGION_SAVE_AS: set_dialog_widget(REGION_SAVE_AS_DIALOG, fd->dialog); break; default: snd_error("internal screw up"); break; } SG_SIGNAL_CONNECT(fd->dialog, "delete_event", save_as_delete_callback, (void *)fd); if (fd->type != REGION_SAVE_AS) { if (fd->type == SOUND_SAVE_AS) SG_SIGNAL_CONNECT(fd->panel_data->auto_comment_button, "toggled", file_data_auto_comment_callback, fd); } return(fd); } static file_dialog_info *make_sound_save_as_dialog_1(bool managed, int chan) { snd_info *sp = NULL; char *com = NULL; file_info *hdr = NULL; file_dialog_info *fd; char *file_string; sp = any_selected_sound(); if (sp) hdr = sp->hdr; file_string = mus_format("save %s", (char *)((sp) ? sp->short_filename : "")); if (!save_sound_as) save_sound_as = make_save_as_dialog(file_string, default_output_header_type(ss), default_output_sample_type(ss), SOUND_SAVE_AS); else gtk_window_set_title(GTK_WINDOW(save_sound_as->dialog), file_string); free(file_string); fd = save_sound_as; set_file_dialog_sound_attributes(fd->panel_data, fd->panel_data->current_header_type, fd->panel_data->current_sample_type, (hdr) ? hdr->srate : selection_srate(), IGNORE_CHANS, IGNORE_DATA_LOCATION, IGNORE_SAMPLES, com = output_comment(hdr)); if (com) free(com); if (chan >= 0) { char *chan_str; chan_str = (char *)calloc(8, sizeof(char)); snprintf(chan_str, 8, "%d", chan); gtk_entry_set_text(GTK_ENTRY(fd->panel_data->chans_text), chan_str); free(chan_str); } if (managed) gtk_widget_show(fd->dialog); make_auto_comment(fd); return(fd); } widget_t make_sound_save_as_dialog(bool managed) { file_dialog_info *fd; fd = make_sound_save_as_dialog_1(managed, -1); return(fd->dialog); } void make_channel_extract_dialog(int chan) { make_sound_save_as_dialog_1(true, chan); } widget_t make_selection_save_as_dialog(bool managed) { file_dialog_info *fd; if (!save_selection_as) save_selection_as = make_save_as_dialog("save current selection", default_output_header_type(ss), default_output_sample_type(ss), SELECTION_SAVE_AS); else gtk_window_set_title(GTK_WINDOW(save_selection_as->dialog), "save current selection"); fd = save_selection_as; set_file_dialog_sound_attributes(fd->panel_data, fd->panel_data->current_header_type, fd->panel_data->current_sample_type, selection_srate(), IGNORE_CHANS, IGNORE_DATA_LOCATION, IGNORE_SAMPLES, NULL); if (managed) gtk_widget_show(fd->dialog); return(fd->dialog); } widget_t make_region_save_as_dialog(bool managed) { file_dialog_info *fd; char *comment = NULL; if (!save_region_as) save_region_as = make_save_as_dialog("save current region", default_output_header_type(ss), default_output_sample_type(ss), REGION_SAVE_AS); else gtk_window_set_title(GTK_WINDOW(save_region_as->dialog), "save current region"); fd = save_region_as; comment = region_description(region_dialog_region()); set_file_dialog_sound_attributes(fd->panel_data, fd->panel_data->current_header_type, fd->panel_data->current_sample_type, region_srate(region_dialog_region()), IGNORE_CHANS, IGNORE_DATA_LOCATION, IGNORE_SAMPLES, comment); if (comment) free(comment); if (managed) gtk_widget_show(fd->dialog); return(fd->dialog); } void save_file_dialog_state(FILE *fd) { if ((odat) && (widget_is_active(odat->dialog))) { #if HAVE_SCHEME fprintf(fd, "(%s #t)\n", S_open_file_dialog); #endif #if HAVE_RUBY fprintf(fd, "%s(true)\n", to_proc_name(S_open_file_dialog)); #endif #if HAVE_FORTH fprintf(fd, "#t %s drop\n", S_open_file_dialog); #endif } if ((mdat) && (widget_is_active(mdat->dialog))) { #if HAVE_SCHEME fprintf(fd, "(%s #t)\n", S_mix_file_dialog); #endif #if HAVE_RUBY fprintf(fd, "%s(true)\n", to_proc_name(S_mix_file_dialog)); #endif #if HAVE_FORTH fprintf(fd, "#t %s drop\n", S_mix_file_dialog); #endif } if ((idat) && (widget_is_active(idat->dialog))) { #if HAVE_SCHEME fprintf(fd, "(%s #t)\n", S_insert_file_dialog); #endif #if HAVE_RUBY fprintf(fd, "%s(true)\n", to_proc_name(S_insert_file_dialog)); #endif #if HAVE_FORTH fprintf(fd, "#t %s drop\n", S_insert_file_dialog); #endif } if ((save_sound_as) && (widget_is_active(save_sound_as->dialog))) { #if HAVE_SCHEME fprintf(fd, "(%s #t)\n", S_save_sound_dialog); #endif #if HAVE_RUBY fprintf(fd, "%s(true)\n", to_proc_name(S_save_sound_dialog)); #endif #if HAVE_FORTH fprintf(fd, "#t %s drop\n", S_save_sound_dialog); #endif } if ((save_selection_as) && (widget_is_active(save_selection_as->dialog))) { #if HAVE_SCHEME fprintf(fd, "(%s #t)\n", S_save_selection_dialog); #endif #if HAVE_RUBY fprintf(fd, "%s(true)\n", to_proc_name(S_save_selection_dialog)); #endif #if HAVE_FORTH fprintf(fd, "#t %s drop\n", S_save_selection_dialog); #endif } if ((save_region_as) && (widget_is_active(save_region_as->dialog))) { #if HAVE_SCHEME fprintf(fd, "(%s #t)\n", S_save_region_dialog); #endif #if HAVE_RUBY fprintf(fd, "%s(true)\n", to_proc_name(S_save_region_dialog)); #endif #if HAVE_FORTH fprintf(fd, "#t %s drop\n", S_save_region_dialog); #endif } } /* -------------------------------- Raw Data Dialog -------------------------------- */ typedef struct raw_info { GtkWidget *dialog; mus_long_t location; file_data *rdat; read_only_t read_only; bool selected; char *filename; char *help; open_requestor_t requestor; void *requestor_data; GtkWidget *requestor_dialog; } raw_info; static int raw_info_size = 0; static raw_info **raw_infos = NULL; static raw_info *new_raw_dialog(void) { int loc = -1; if (raw_info_size == 0) { loc = 0; raw_info_size = 4; raw_infos = (raw_info **)calloc(raw_info_size, sizeof(raw_info *)); } else { int i; for (i = 0; i < raw_info_size; i++) if ((!raw_infos[i]) || (!(widget_is_active(raw_infos[i]->dialog)))) { loc = i; break; } if (loc == -1) { loc = raw_info_size; raw_info_size += 4; raw_infos = (raw_info **)realloc(raw_infos, raw_info_size * sizeof(raw_info *)); for (i = loc; i < raw_info_size; i++) raw_infos[i] = NULL; } } if (!raw_infos[loc]) { raw_infos[loc] = (raw_info *)calloc(1, sizeof(raw_info)); raw_infos[loc]->dialog = NULL; raw_infos[loc]->filename = NULL; raw_infos[loc]->help = NULL; } raw_infos[loc]->requestor = NO_REQUESTOR; raw_infos[loc]->requestor_data = NULL; raw_infos[loc]->location = 0; return(raw_infos[loc]); } static void raw_data_ok_callback(GtkWidget *w, gpointer context) { raw_info *rp = (raw_info *)context; int raw_srate = 0, raw_chans = 0; mus_sample_t raw_sample_type = MUS_UNKNOWN_SAMPLE; redirect_snd_error_to(redirect_post_file_panel_error, (void *)(rp->rdat)); get_file_dialog_sound_attributes(rp->rdat, &raw_srate, &raw_chans, NULL, &raw_sample_type, &(rp->location), NULL, 1); redirect_snd_error_to(NULL, NULL); if (rp->rdat->error_widget != NOT_A_SCANF_WIDGET) { clear_error_if_panel_changes(rp->dialog, rp->rdat); } else { mus_header_set_raw_defaults(raw_srate, raw_chans, raw_sample_type); mus_sound_override_header(rp->filename, raw_srate, raw_chans, raw_sample_type, MUS_RAW, rp->location, mus_bytes_to_samples(raw_sample_type, mus_sound_length(rp->filename) - rp->location)); /* choose action based on how we got here */ if ((rp->requestor_dialog) && ((rp->requestor == FROM_MIX_DIALOG) || (rp->requestor == FROM_INSERT_DIALOG))) { ss->reloading_updated_file = true; /* don't reread lack-of-header! */ /* redirection may be still set here, but I'll make it obvious */ switch (rp->requestor) { case FROM_MIX_DIALOG: redirect_snd_error_to(redirect_file_open_error, (void *)mdat); mix_complete_file_at_cursor(any_selected_sound(), rp->filename); break; case FROM_INSERT_DIALOG: redirect_snd_error_to(redirect_file_open_error, (void *)idat); insert_complete_file_at_cursor(any_selected_sound(), rp->filename); break; default: snd_error("wrong requestor type in raw data dialog? %d\n", (int)(rp->requestor)); break; } redirect_snd_error_to(NULL, NULL); ss->reloading_updated_file = false; } else { file_info *hdr; hdr = (file_info *)calloc(1, sizeof(file_info)); hdr->name = mus_strdup(rp->filename); hdr->type = MUS_RAW; hdr->srate = raw_srate; hdr->chans = raw_chans; hdr->sample_type = raw_sample_type; hdr->samples = mus_bytes_to_samples(raw_sample_type, mus_sound_length(rp->filename) - rp->location); hdr->data_location = rp->location; hdr->comment = NULL; if (rp->requestor == FROM_KEYBOARD) { clear_status_area((snd_info *)(rp->requestor_data)); rp->selected = true; } finish_opening_sound(add_sound_window(rp->filename, rp->read_only, hdr), rp->selected); } gtk_widget_hide(rp->dialog); } } static void raw_data_cancel_callback(GtkWidget *w, gpointer context) { raw_info *rp = (raw_info *)context; gtk_widget_hide(rp->dialog); if ((rp->requestor_dialog) && ((rp->requestor == FROM_OPEN_DIALOG) || (rp->requestor == FROM_MIX_DIALOG))) gtk_widget_show(rp->requestor_dialog); } static gint raw_data_delete_callback(GtkWidget *w, GdkEvent *event, gpointer context) { raw_info *rp = (raw_info *)context; if ((rp->requestor_dialog) && ((rp->requestor == FROM_OPEN_DIALOG) || (rp->requestor == FROM_MIX_DIALOG))) gtk_widget_show(rp->requestor_dialog); return(true); } static void raw_data_reset_callback(GtkWidget *w, gpointer context) { raw_info *rp = (raw_info *)context; int raw_srate, raw_chans; mus_sample_t raw_sample_type; rp->location = 0; mus_header_raw_defaults(&raw_srate, &raw_chans, &raw_sample_type); /* pick up defaults */ set_file_dialog_sound_attributes(rp->rdat, IGNORE_HEADER_TYPE, raw_sample_type, raw_srate, raw_chans, rp->location, IGNORE_SAMPLES, NULL); clear_dialog_error(rp->rdat); } static void raw_data_help_callback(GtkWidget *w, gpointer context) { raw_info *rp = (raw_info *)context; raw_data_dialog_help(rp->help); } static void make_raw_data_dialog(raw_info *rp, const char *filename, const char *title) { GtkWidget *reset_button, *help_button, *cancel_button, *ok_button; int raw_srate, raw_chans; mus_sample_t raw_sample_type; rp->dialog = snd_gtk_dialog_new(); #if GTK_CHECK_VERSION(3, 14, 0) gtk_window_set_transient_for(GTK_WINDOW(rp->dialog), GTK_WINDOW(MAIN_SHELL(ss))); #endif if (!title) gtk_window_set_title(GTK_WINDOW(rp->dialog), "No header on file"); else gtk_window_set_title(GTK_WINDOW(rp->dialog), title); sg_make_resizable(rp->dialog); gtk_container_set_border_width(GTK_CONTAINER(rp->dialog), 10); gtk_window_resize(GTK_WINDOW(rp->dialog), 350, 260); gtk_widget_realize(rp->dialog); help_button = gtk_dialog_add_button(GTK_DIALOG(rp->dialog), "Help", GTK_RESPONSE_NONE); reset_button = gtk_dialog_add_button(GTK_DIALOG(rp->dialog), "Reset", GTK_RESPONSE_NONE); cancel_button = gtk_dialog_add_button(GTK_DIALOG(rp->dialog), "Go away", GTK_RESPONSE_NONE); ok_button = gtk_dialog_add_button(GTK_DIALOG(rp->dialog), "Ok", GTK_RESPONSE_NONE); gtk_widget_set_name(help_button, "dialog_button"); gtk_widget_set_name(cancel_button, "dialog_button"); gtk_widget_set_name(reset_button, "dialog_button"); gtk_widget_set_name(ok_button, "dialog_button"); #if GTK_CHECK_VERSION(3, 0, 0) add_highlight_button_style(cancel_button); add_highlight_button_style(help_button); add_highlight_button_style(reset_button); add_highlight_button_style(ok_button); #endif mus_header_raw_defaults(&raw_srate, &raw_chans, &raw_sample_type); /* pick up defaults */ rp->rdat = make_file_data_panel(DIALOG_CONTENT_AREA(rp->dialog), "data-form", WITH_CHANNELS_FIELD, MUS_RAW, raw_sample_type, WITH_DATA_LOCATION_FIELD, WITHOUT_SAMPLES_FIELD, WITHOUT_HEADER_TYPE_FIELD, WITHOUT_COMMENT_FIELD, WITH_READABLE_HEADERS, WITHOUT_SRATE_FIELD, WITHOUT_AUTO_COMMENT); rp->rdat->dialog = rp->dialog; set_file_dialog_sound_attributes(rp->rdat, IGNORE_HEADER_TYPE, raw_sample_type, raw_srate, raw_chans, rp->location, IGNORE_SAMPLES, NULL); SG_SIGNAL_CONNECT(rp->dialog, "delete_event", raw_data_delete_callback, rp); SG_SIGNAL_CONNECT(ok_button, "clicked", raw_data_ok_callback, rp); SG_SIGNAL_CONNECT(help_button, "clicked", raw_data_help_callback, rp); SG_SIGNAL_CONNECT(reset_button, "clicked", raw_data_reset_callback, rp); SG_SIGNAL_CONNECT(cancel_button, "clicked", raw_data_cancel_callback, rp); gtk_widget_show(ok_button); gtk_widget_show(cancel_button); gtk_widget_show(help_button); gtk_widget_show(reset_button); set_dialog_widget(RAW_DATA_DIALOG, rp->dialog); } void raw_data_dialog_to_file_info(const char *filename, char *title, char *info, read_only_t read_only, bool selected) { raw_info *rp; rp = new_raw_dialog(); rp->read_only = read_only; rp->selected = selected; if (rp->filename) free(rp->filename); rp->filename = mus_strdup(filename); rp->requestor = ss->open_requestor; rp->requestor_dialog = ss->requestor_dialog; ss->open_requestor = NO_REQUESTOR; ss->requestor_dialog = NULL; if ((rp->requestor_dialog) && ((rp->requestor == FROM_OPEN_DIALOG) || (rp->requestor == FROM_MIX_DIALOG))) gtk_widget_hide(rp->requestor_dialog); if (!title) title = mus_format("no header found on %s\n", filename); if (!rp->dialog) make_raw_data_dialog(rp, filename, title); else gtk_window_set_title(GTK_WINDOW(rp->dialog), title); free(title); if (rp->help) free(rp->help); if (info) { rp->help = mus_strdup(info); free(info); } else rp->help = NULL; raise_dialog(rp->dialog); gtk_widget_show(rp->dialog); } /* -------------------------------- New File -------------------------------- */ static GtkWidget *new_file_dialog = NULL, *new_file_text = NULL, *new_file_ok_button = NULL; static file_data *ndat = NULL; static mus_long_t initial_samples = 1; static char *new_file_filename = NULL; static void *new_file_watcher = NULL; static void cleanup_new_file_watcher(void) { new_file_watcher = unmonitor_file(new_file_watcher); } static gulong new_file_handler_id = 0; static gboolean new_filename_modify_callback(GtkWidget *w, GdkEventKey *event, gpointer ignored); static void new_file_undoit(void) { clear_dialog_error(ndat); if (new_file_handler_id) { if (new_file_handler_id) { g_signal_handler_disconnect(new_file_text, new_file_handler_id); new_file_handler_id = 0; } } set_stock_button_label(new_file_ok_button, "Ok"); new_file_watcher = unmonitor_file(new_file_watcher); } static gboolean new_filename_modify_callback(GtkWidget *w, GdkEventKey *event, gpointer ignored) { new_file_undoit(); return(false); } static void clear_error_if_new_filename_changes(GtkWidget *dialog) { if (new_file_text) new_file_handler_id = SG_SIGNAL_CONNECT(new_file_text, "key_press_event", new_filename_modify_callback, NULL); } #if HAVE_G_FILE_MONITOR_DIRECTORY static void watch_new_file(GFileMonitor *mon, GFile *file, GFile *other, GFileMonitorEvent ev, gpointer data) { /* if file is deleted, respond in some debonair manner */ switch (ev) { case G_FILE_MONITOR_EVENT_CHANGED: case G_FILE_MONITOR_EVENT_DELETED: case G_FILE_MONITOR_EVENT_CREATED: #if HAVE_GTK_WIDGET_GET_VISIBLE case G_FILE_MONITOR_EVENT_MOVED: #endif new_file_undoit(); break; default: /* ignore the rest */ break; } } #endif static void new_file_ok_callback(GtkWidget *w, gpointer context) { mus_long_t loc; char *newer_name = NULL, *msg; mus_header_t header_type; mus_sample_t sample_type; int srate, chans; newer_name = (char *)gtk_entry_get_text(GTK_ENTRY(new_file_text)); if ((!newer_name) || (!(*newer_name))) { msg = (char *)"new sound needs a file name ('New file:' field is empty)"; post_file_dialog_error((const char *)msg, ndat); clear_error_if_new_filename_changes(new_file_dialog); } else { char *comment; redirect_snd_error_to(redirect_post_file_panel_error, (void *)ndat); comment = get_file_dialog_sound_attributes(ndat, &srate, &chans, &header_type, &sample_type, &loc, &initial_samples, 1); redirect_snd_error_to(NULL, NULL); if (ndat->error_widget != NOT_A_SCANF_WIDGET) { clear_error_if_panel_changes(new_file_dialog, ndat); } else { /* handle the overwrite hook directly */ if (new_file_filename) free(new_file_filename); new_file_filename = mus_expand_filename(newer_name); /* need full filename for fam */ if ((!new_file_watcher) && (ask_before_overwrite(ss)) && (mus_file_probe(new_file_filename))) { msg = mus_format("%s exists. If you want to overwrite it, click 'DoIt'", newer_name); #if HAVE_G_FILE_MONITOR_DIRECTORY { GFile *file; GError *err = NULL; file = g_file_new_for_path(new_file_filename); new_file_watcher = (void *)g_file_monitor_file(file, G_FILE_MONITOR_NONE, NULL, &err); if (err != NULL) snd_warning("%s", err->message); else g_signal_connect(G_OBJECT(new_file_watcher), "changed", G_CALLBACK(watch_new_file), NULL); g_object_unref(file); } #endif set_stock_button_label(new_file_ok_button, "DoIt"); post_file_dialog_error((const char *)msg, ndat); clear_error_if_new_filename_changes(new_file_dialog); free(msg); } else { snd_info *sp; if (new_file_watcher) new_file_undoit(); ss->local_errno = 0; redirect_snd_error_to(redirect_post_file_dialog_error, (void *)ndat); sp = snd_new_file(newer_name, chans, srate, sample_type, header_type, comment, initial_samples); redirect_snd_error_to(NULL, NULL); if (!sp) { #if HAVE_G_FILE_MONITOR_DIRECTORY if ((ss->local_errno) && (mus_file_probe(new_file_filename))) /* see comment in snd-xfile.c */ { GFile *file; GError *err = NULL; file = g_file_new_for_path(new_file_filename); new_file_watcher = (void *)g_file_monitor_file(file, G_FILE_MONITOR_NONE, NULL, &err); if (err != NULL) snd_warning("%s", err->message); else g_signal_connect(G_OBJECT(new_file_watcher), "changed", G_CALLBACK(watch_new_file), NULL); g_object_unref(file); } #endif clear_error_if_new_filename_changes(new_file_dialog); } else { gtk_widget_hide(new_file_dialog); } } } if (comment) free(comment); } } static char *new_file_dialog_filename(int header_type) { static int new_file_dialog_file_ctr = 1; char *filename = NULL; const char *extensions[6] = {"aiff", "aiff", "wav", "wav", "caf", "snd"}; int extension = 0; filename = (char *)calloc(64, sizeof(char)); switch (header_type) { case MUS_AIFC: extension = 0; break; case MUS_AIFF: extension = 1; break; case MUS_RF64: extension = 2; break; case MUS_RIFF: extension = 3; break; case MUS_CAFF: extension = 4; break; default: extension = 5; break; } snprintf(filename, 64, "new-%d.%s", new_file_dialog_file_ctr++, extensions[extension]); return(filename); } static void load_new_file_defaults(char *newname) { char *new_comment = NULL; mus_header_t header_type; mus_sample_t sample_type; int chans, srate; header_type = default_output_header_type(ss); chans = default_output_chans(ss); sample_type = default_output_sample_type(ss); srate = default_output_srate(ss); new_comment = output_comment(NULL); if ((!newname) || (!(*newname))) newname = new_file_dialog_filename(header_type); gtk_entry_set_text(GTK_ENTRY(new_file_text), newname); mus_sound_forget(newname); set_file_dialog_sound_attributes(ndat, header_type, sample_type, srate, chans, IGNORE_DATA_LOCATION, initial_samples, new_comment); if (new_comment) free(new_comment); } static void new_file_cancel_callback(GtkWidget *w, gpointer context) { gtk_widget_hide(new_file_dialog); } static void new_file_reset_callback(GtkWidget *w, gpointer context) { char *current_name; current_name = (char *)gtk_entry_get_text(GTK_ENTRY(new_file_text)); load_new_file_defaults(current_name); if (new_file_watcher) new_file_undoit(); } static gint new_file_delete_callback(GtkWidget *w, GdkEvent *event, gpointer context) { gtk_widget_hide(new_file_dialog); return(true); } static void new_file_help_callback(GtkWidget *w, gpointer context) { new_file_dialog_help(); } widget_t make_new_file_dialog(bool managed) { if (!new_file_dialog) { GtkWidget *name_label, *hform, *help_button, *cancel_button, *reset_button; new_file_dialog = snd_gtk_dialog_new(); #if GTK_CHECK_VERSION(3, 14, 0) gtk_window_set_transient_for(GTK_WINDOW(new_file_dialog), GTK_WINDOW(MAIN_SHELL(ss))); #endif gtk_window_set_title(GTK_WINDOW(new_file_dialog), "New file"); sg_make_resizable(new_file_dialog); gtk_container_set_border_width (GTK_CONTAINER(new_file_dialog), 10); gtk_window_resize(GTK_WINDOW(new_file_dialog), 400, 250); gtk_widget_realize(new_file_dialog); help_button = gtk_dialog_add_button(GTK_DIALOG(new_file_dialog), "Help", GTK_RESPONSE_NONE); reset_button = gtk_dialog_add_button(GTK_DIALOG(new_file_dialog), "Reset", GTK_RESPONSE_NONE); cancel_button = gtk_dialog_add_button(GTK_DIALOG(new_file_dialog), "Go away", GTK_RESPONSE_NONE); new_file_ok_button = gtk_dialog_add_button(GTK_DIALOG(new_file_dialog), "Ok", GTK_RESPONSE_NONE); gtk_widget_set_name(help_button, "dialog_button"); gtk_widget_set_name(cancel_button, "dialog_button"); gtk_widget_set_name(new_file_ok_button, "dialog_button"); gtk_widget_set_name(reset_button, "dialog_button"); #if GTK_CHECK_VERSION(3, 0, 0) add_highlight_button_style(help_button); add_highlight_button_style(cancel_button); add_highlight_button_style(reset_button); add_highlight_button_style(new_file_ok_button); #endif hform = gtk_hbox_new(false, 0); gtk_box_pack_start(GTK_BOX(DIALOG_CONTENT_AREA(new_file_dialog)), hform, false, false, 4); gtk_widget_show(hform); name_label = gtk_label_new("New file:"); gtk_box_pack_start(GTK_BOX(hform), name_label, false, false, 2); gtk_widget_show(name_label); new_file_text = snd_entry_new(hform, NULL, WITH_WHITE_BACKGROUND); ndat = make_file_data_panel(DIALOG_CONTENT_AREA(new_file_dialog), "data-form", WITH_CHANNELS_FIELD, default_output_header_type(ss), default_output_sample_type(ss), WITHOUT_DATA_LOCATION_FIELD, WITH_SAMPLES_FIELD, WITH_HEADER_TYPE_FIELD, WITH_COMMENT_FIELD, WITH_BUILTIN_HEADERS, WITHOUT_SRATE_FIELD, WITHOUT_AUTO_COMMENT); ndat->dialog = new_file_dialog; SG_SIGNAL_CONNECT(new_file_dialog, "delete_event", new_file_delete_callback, ndat); SG_SIGNAL_CONNECT(cancel_button, "clicked", new_file_cancel_callback, ndat); SG_SIGNAL_CONNECT(help_button, "clicked", new_file_help_callback, ndat); SG_SIGNAL_CONNECT(new_file_ok_button, "clicked", new_file_ok_callback, ndat); SG_SIGNAL_CONNECT(reset_button, "clicked", new_file_reset_callback, ndat); SG_SIGNAL_CONNECT(new_file_text, "activate", new_file_ok_callback, ndat); gtk_widget_show(cancel_button); gtk_widget_show(new_file_ok_button); gtk_widget_show(reset_button); gtk_widget_show(help_button); set_dialog_widget(NEW_FILE_DIALOG, new_file_dialog); load_new_file_defaults(NULL); } else { char *new_name; new_name = (char *)gtk_entry_get_text(GTK_ENTRY(new_file_text)); if (new_file_watcher) { /* if overwrite question pends, but file has been deleted in the meantime, go back to normal state */ if ((!new_name) || (!(*new_name)) || (!(mus_file_probe(new_name)))) new_file_undoit(); } if (strncmp(new_name, "new-", 4) == 0) { /* if file is open with currently posted new-file dialog name, and it's our name (new-%d), then tick the counter */ snd_info *sp; sp = find_sound(new_name, 0); if (sp) { char *filename; filename = new_file_dialog_filename(default_output_header_type(ss)); gtk_entry_set_text(GTK_ENTRY(new_file_text), filename); mus_sound_forget(filename); free(filename); } } } if (managed) gtk_widget_show(new_file_dialog); return(new_file_dialog); } /* ---------------- Edit Header ---------------- */ typedef struct edhead_info { GtkWidget *dialog, *save_button; file_data *edat; snd_info *sp; bool panel_changed; void *file_ro_watcher; int sp_ro_watcher_loc; } edhead_info; static int edhead_info_size = 0; static edhead_info **edhead_infos = NULL; static edhead_info *new_edhead_dialog(void) { int loc = -1; if (edhead_info_size == 0) { loc = 0; edhead_info_size = 4; edhead_infos = (edhead_info **)calloc(edhead_info_size, sizeof(edhead_info *)); } else { int i; for (i = 0; i < edhead_info_size; i++) if ((!edhead_infos[i]) || (!(widget_is_active(edhead_infos[i]->dialog)))) { loc = i; break; } if (loc == -1) { loc = edhead_info_size; edhead_info_size += 4; edhead_infos = (edhead_info **)realloc(edhead_infos, edhead_info_size * sizeof(edhead_info *)); for (i = loc; i < edhead_info_size; i++) edhead_infos[i] = NULL; } } if (!edhead_infos[loc]) { edhead_infos[loc] = (edhead_info *)calloc(1, sizeof(edhead_info)); edhead_infos[loc]->dialog = NULL; edhead_infos[loc]->panel_changed = false; } edhead_infos[loc]->sp = NULL; edhead_infos[loc]->file_ro_watcher = NULL; return(edhead_infos[loc]); } static void cleanup_edit_header_watcher(void) { int i; for (i = 0; i < edhead_info_size; i++) if (edhead_infos[i]) { edhead_info *ep; ep = edhead_infos[i]; if (ep->file_ro_watcher) ep->file_ro_watcher = unmonitor_file(ep->file_ro_watcher); } } static char *make_header_dialog_title(edhead_info *ep, snd_info *sp) { /* dialog may not yet exist */ char *str; str = (char *)calloc(PRINT_BUFFER_SIZE, sizeof(char)); if ((sp->user_read_only == FILE_READ_ONLY) || (sp->file_read_only == FILE_READ_ONLY)) { if (sp->hdr->type == MUS_RAW) snprintf(str, PRINT_BUFFER_SIZE, "Add header to (write-protected) %s", sp->short_filename); else snprintf(str, PRINT_BUFFER_SIZE, "Edit header of (write-protected) %s", sp->short_filename); } else { if (sp->hdr->type == MUS_RAW) snprintf(str, PRINT_BUFFER_SIZE, "Add header to %s", sp->short_filename); else snprintf(str, PRINT_BUFFER_SIZE, "Edit header of %s", sp->short_filename); } return(str); } static void edit_header_help_callback(GtkWidget *w, gpointer context) { edit_header_dialog_help(); } static void edit_header_set_ok_sensitive(GtkWidget *w, gpointer context) { edhead_info *ep = (edhead_info *)context; ep->panel_changed = true; } static void edit_header_done(edhead_info *ep) { gtk_widget_hide(ep->dialog); unreflect_file_data_panel_change(ep->edat, (void *)ep, edit_header_set_ok_sensitive); ep->panel_changed = false; ep->file_ro_watcher = unmonitor_file(ep->file_ro_watcher); } static void edit_header_cancel_callback(GtkWidget *w, gpointer context) { edit_header_done((edhead_info *)context); } static gint edit_header_delete_callback(GtkWidget *w, GdkEvent *event, gpointer context) { edit_header_done((edhead_info *)context); return(true); } #if HAVE_G_FILE_MONITOR_DIRECTORY static void watch_file_read_only(GFileMonitor *mon, GFile *file, GFile *other, GFileMonitorEvent ev, gpointer data) { /* if file is deleted or permissions change, respond in some debonair manner */ edhead_info *ep = (edhead_info *)data; snd_info *sp = NULL; sp = ep->sp; if (sp->writing) return; switch (ev) { case G_FILE_MONITOR_EVENT_CHANGED: #ifndef _MSC_VER { if (mus_file_probe(sp->filename)) { char *title; int err; err = access(sp->filename, W_OK); sp->file_read_only = ((err < 0) ? FILE_READ_ONLY : FILE_READ_WRITE); if ((sp->file_read_only == FILE_READ_WRITE) && (sp->user_read_only == FILE_READ_WRITE)) clear_dialog_error(ep->edat); title = make_header_dialog_title(ep, sp); gtk_window_set_title(GTK_WINDOW(ep->dialog), title); free(title); return; } } #endif /* else fall through */ case G_FILE_MONITOR_EVENT_DELETED: case G_FILE_MONITOR_EVENT_CREATED: #if HAVE_GTK_WIDGET_GET_VISIBLE case G_FILE_MONITOR_EVENT_MOVED: #endif /* I don't think it makes sense to continue the dialog at this point */ clear_dialog_error(ep->edat); gtk_widget_hide(ep->dialog); if (ep->panel_changed) unreflect_file_data_panel_change(ep->edat, (void *)ep, edit_header_set_ok_sensitive); ep->panel_changed = false; ep->file_ro_watcher = unmonitor_file(ep->file_ro_watcher); break; default: /* ignore the rest */ break; } } #endif static void edit_header_ok_callback(GtkWidget *w, gpointer context) { edhead_info *ep = (edhead_info *)context; if ((ep->sp) && (ep->sp->active)) { bool ok; redirect_snd_error_to(redirect_post_file_dialog_error, (void *)(ep->edat)); ok = edit_header_callback(ep->sp, ep->edat, redirect_post_file_dialog_error, redirect_post_file_panel_error); redirect_snd_error_to(NULL, NULL); if (ep->edat->error_widget != NOT_A_SCANF_WIDGET) { clear_error_if_panel_changes(ep->dialog, ep->edat); return; } else { if (!ok) return; } ep->file_ro_watcher = unmonitor_file(ep->file_ro_watcher); gtk_widget_hide(ep->dialog); unreflect_file_data_panel_change(ep->edat, (void *)ep, edit_header_set_ok_sensitive); } } GtkWidget *edit_header(snd_info *sp) { char *str; file_info *hdr; edhead_info *ep = NULL; if (!sp) return(NULL); /* look for a dialog already editing this sound, raise if found, else make a new one */ if (edhead_info_size > 0) { int i; for (i = 0; i < edhead_info_size; i++) if ((edhead_infos[i]) && ((edhead_infos[i]->sp == sp) || ((edhead_infos[i]->sp) && /* maybe same sound open twice -- only one edit header dialog for it */ (edhead_infos[i]->sp->inuse == SOUND_NORMAL) && (mus_strcmp(sp->filename, edhead_infos[i]->sp->filename))))) { ep = edhead_infos[i]; break; } } if (!ep) ep = new_edhead_dialog(); ep->sp = sp; hdr = sp->hdr; ep->panel_changed = (hdr->type == MUS_RAW); if (!ep->dialog) { GtkWidget *help_button, *cancel_button; ep->dialog = snd_gtk_dialog_new(); #if GTK_CHECK_VERSION(3, 14, 0) gtk_window_set_transient_for(GTK_WINDOW(ep->dialog), GTK_WINDOW(MAIN_SHELL(ss))); #endif /* gtk_window_set_title(GTK_WINDOW(ep->dialog), "Edit Header"); */ sg_make_resizable(ep->dialog); gtk_container_set_border_width (GTK_CONTAINER(ep->dialog), 10); gtk_window_resize(GTK_WINDOW(ep->dialog), 400, 250); gtk_widget_realize(ep->dialog); help_button = gtk_dialog_add_button(GTK_DIALOG(ep->dialog), "Help", GTK_RESPONSE_NONE); cancel_button = gtk_dialog_add_button(GTK_DIALOG(ep->dialog), "Go away", GTK_RESPONSE_NONE); ep->save_button = gtk_dialog_add_button(GTK_DIALOG(ep->dialog), "Save", GTK_RESPONSE_NONE); gtk_widget_set_name(help_button, "dialog_button"); gtk_widget_set_name(cancel_button, "dialog_button"); gtk_widget_set_name(ep->save_button, "dialog_button"); #if GTK_CHECK_VERSION(3, 0, 0) add_highlight_button_style(help_button); add_highlight_button_style(cancel_button); add_highlight_button_style(ep->save_button); #endif ep->edat = make_file_data_panel(DIALOG_CONTENT_AREA(ep->dialog), "Edit Header", WITH_CHANNELS_FIELD, hdr->type, hdr->sample_type, WITH_DATA_LOCATION_FIELD, WITH_SAMPLES_FIELD, WITH_HEADER_TYPE_FIELD, WITH_COMMENT_FIELD, WITH_BUILTIN_HEADERS, WITHOUT_SRATE_FIELD, WITHOUT_AUTO_COMMENT); ep->edat->dialog = ep->dialog; SG_SIGNAL_CONNECT(ep->dialog, "delete_event", edit_header_delete_callback, ep); SG_SIGNAL_CONNECT(cancel_button, "clicked", edit_header_cancel_callback, ep); SG_SIGNAL_CONNECT(help_button, "clicked", edit_header_help_callback, ep); SG_SIGNAL_CONNECT(ep->save_button, "clicked", edit_header_ok_callback, ep); gtk_widget_show(cancel_button); gtk_widget_show(ep->save_button); gtk_widget_show(help_button); set_dialog_widget(EDIT_HEADER_DIALOG, ep->dialog); } else clear_dialog_error(ep->edat); str = make_header_dialog_title(ep, sp); gtk_window_set_title(GTK_WINDOW(ep->dialog), str); free(str); if (hdr->type == MUS_RAW) set_file_dialog_sound_attributes(ep->edat, default_output_header_type(ss), hdr->sample_type, hdr->srate, hdr->chans, hdr->data_location, hdr->samples, hdr->comment); else set_file_dialog_sound_attributes(ep->edat, hdr->type, hdr->sample_type, hdr->srate, hdr->chans, hdr->data_location, hdr->samples, hdr->comment); gtk_widget_show(ep->dialog); reflect_file_data_panel_change(ep->edat, (void *)ep, edit_header_set_ok_sensitive); #if HAVE_G_FILE_MONITOR_DIRECTORY { GFile *file; GError *err = NULL; file = g_file_new_for_path(ep->sp->filename); ep->file_ro_watcher = (void *)g_file_monitor_file(file, G_FILE_MONITOR_NONE, NULL, &err); if (err != NULL) snd_warning("%s", err->message); else g_signal_connect(G_OBJECT(ep->file_ro_watcher), "changed", G_CALLBACK(watch_file_read_only), (gpointer)ep); g_object_unref(file); } #endif return(ep->dialog); } void save_edit_header_dialog_state(FILE *fd) { int i; for (i = 0; i < edhead_info_size; i++) if (edhead_infos[i]) { edhead_info *ep; ep = edhead_infos[i]; if ((ep->dialog) && (widget_is_active(ep->dialog)) && (snd_ok(ep->sp))) { #if HAVE_SCHEME fprintf(fd, "(%s (%s \"%s\"))\n", S_edit_header_dialog, S_find_sound, ep->sp->short_filename); #endif #if HAVE_RUBY fprintf(fd, "%s(%s(\"%s\"))\n", to_proc_name(S_edit_header_dialog), to_proc_name(S_find_sound), ep->sp->short_filename); #endif #if HAVE_FORTH fprintf(fd, "\"%s\" %s %s drop\n", ep->sp->short_filename, S_find_sound, S_edit_header_dialog); #endif } } } /* ---------------- Post-it Monolog ---------------- */ #define POST_IT_ROWS 12 #define POST_IT_COLUMNS 56 static GtkWidget *post_it_text = NULL, *post_it_dialog = NULL; static void dismiss_post_it(GtkWidget *w, gpointer context) {gtk_widget_hide(post_it_dialog);} static gint delete_post_it(GtkWidget *w, GdkEvent *event, gpointer context) { gtk_widget_hide(post_it_dialog); return(true); } static void create_post_it_monolog(void) { /* create scrollable but not editable text window */ GtkWidget *ok_button; post_it_dialog = gtk_dialog_new(); #if GTK_CHECK_VERSION(3, 14, 0) gtk_window_set_transient_for(GTK_WINDOW(post_it_dialog), GTK_WINDOW(MAIN_SHELL(ss))); #endif SG_SIGNAL_CONNECT(post_it_dialog, "delete_event", delete_post_it, NULL); gtk_window_set_title(GTK_WINDOW(post_it_dialog), "Info"); sg_make_resizable(post_it_dialog); gtk_container_set_border_width(GTK_CONTAINER(post_it_dialog), 10); gtk_window_resize(GTK_WINDOW(post_it_dialog), POST_IT_COLUMNS * 9, POST_IT_ROWS * 20); gtk_widget_realize(post_it_dialog); ok_button = gtk_dialog_add_button(GTK_DIALOG(post_it_dialog), "Ok", GTK_RESPONSE_NONE); gtk_widget_set_name(ok_button, "dialog_button"); SG_SIGNAL_CONNECT(ok_button, "clicked", dismiss_post_it, NULL); gtk_widget_show(ok_button); #if GTK_CHECK_VERSION(3, 0, 0) add_highlight_button_style(ok_button); #endif post_it_text = make_scrolled_text(DIALOG_CONTENT_AREA(post_it_dialog), false, BOX_PACK, true); gtk_text_view_set_left_margin(GTK_TEXT_VIEW(post_it_text), 10); gtk_widget_show(post_it_dialog); set_dialog_widget(POST_IT_DIALOG, post_it_dialog); } widget_t post_it(const char *subject, const char *str) { if (ss == NULL) return(NULL); if (!(post_it_dialog)) create_post_it_monolog(); else raise_dialog(post_it_dialog); gtk_window_set_title(GTK_WINDOW(post_it_dialog), subject); gtk_text_buffer_set_text(gtk_text_view_get_buffer(GTK_TEXT_VIEW(post_it_text)), "", 0); sg_text_insert(post_it_text, (char *)str); return(post_it_dialog); } void post_it_append(const char *str) { if (post_it_text) sg_text_insert(post_it_text, (char *)str); } void save_post_it_dialog_state(FILE *fd) { if ((post_it_dialog) && (widget_is_active(post_it_dialog))) { char *subject; gchar *text; subject = dialog_get_title(post_it_dialog); text = sg_get_text(post_it_text, 0, -1); #if HAVE_SCHEME fprintf(fd, "(%s \"%s\" \"%s\")\n", S_info_dialog, subject, text); #endif #if HAVE_RUBY fprintf(fd, "%s(\"%s\", \"%s\")\n", to_proc_name(S_info_dialog), subject, text); #endif #if HAVE_FORTH fprintf(fd, "\"%s\" \"%s\" %s drop\n", subject, text, S_info_dialog); #endif if (text) g_free(text); if (subject) free(subject); } } /* ---------------- unsaved edits dialog ---------------- */ static int num_unsaved_edits_dialogs = 0; static GtkWidget **unsaved_edits_dialogs = NULL; static snd_info **unsaved_edits_sounds = NULL; static GtkWidget *unsaved_edits_dialog(snd_info *sp) { int i; /* are there any such dialogs? */ if (num_unsaved_edits_dialogs == 0) return(NULL); /* now see if we've already prompted about this sound */ for (i = 0; i < num_unsaved_edits_dialogs; i++) if (unsaved_edits_sounds[i] == sp) return(unsaved_edits_dialogs[i]); /* try to find a free unmanaged dialog */ for (i = 0; i < num_unsaved_edits_dialogs; i++) if ((unsaved_edits_dialogs[i]) && (!widget_is_active(unsaved_edits_dialogs[i]))) return(unsaved_edits_dialogs[i]); return(NULL); } static void save_unsaved_edits_dialog(GtkWidget *d, snd_info *sp) { if (num_unsaved_edits_dialogs == 0) { unsaved_edits_dialogs = (GtkWidget **)calloc(1, sizeof(GtkWidget *)); unsaved_edits_sounds = (snd_info **)calloc(1, sizeof(snd_info *)); } else { unsaved_edits_dialogs = (GtkWidget **)realloc(unsaved_edits_dialogs, (num_unsaved_edits_dialogs + 1) * sizeof(GtkWidget *)); unsaved_edits_sounds = (snd_info **)realloc(unsaved_edits_sounds, (num_unsaved_edits_dialogs + 1) * sizeof(snd_info *)); } unsaved_edits_dialogs[num_unsaved_edits_dialogs] = d; unsaved_edits_sounds[num_unsaved_edits_dialogs] = sp; num_unsaved_edits_dialogs++; } void unpost_unsaved_edits_if_any(snd_info *sp) { int i; for (i = 0; i < num_unsaved_edits_dialogs; i++) if (((unsaved_edits_sounds[i] == sp) || (!snd_ok(unsaved_edits_sounds[i]))) && (widget_is_active(unsaved_edits_dialogs[i]))) gtk_widget_hide(unsaved_edits_dialogs[i]); } static void zero_edits(chan_info *cp) { cp->edit_ctr = 0; } static void unsaved_edits_activate(GtkDialog *w, gint id, gpointer context) { snd_info *sp = (snd_info *)context; if (id == GTK_RESPONSE_NO) for_each_sound_chan(sp, zero_edits); else save_edits(sp); snd_close_file(sp); gtk_widget_hide(GTK_WIDGET(w)); } void save_edits_now(snd_info *sp) { char *question; GtkWidget *dialog; question = mus_format("%s has unsaved edits. Save them?", sp->short_filename); dialog = unsaved_edits_dialog(sp); if (!dialog) { dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, "%s", question); SG_SIGNAL_CONNECT(dialog, "response", unsaved_edits_activate, (gpointer)sp); save_unsaved_edits_dialog(dialog, sp); } else { g_object_set(dialog, "text", question, NULL); } free(question); gtk_widget_show(dialog); } /* ---------------- file has changed dialog ---------------- */ static int num_file_has_changed_dialogs = 0; static GtkWidget **file_has_changed_dialogs = NULL; static snd_info **file_has_changed_sounds = NULL; static GtkWidget *file_has_changed_dialog(snd_info *sp) { int i; /* are there any such dialogs? */ if (num_file_has_changed_dialogs == 0) return(NULL); /* now see if we've already prompted about this sound */ for (i = 0; i < num_file_has_changed_dialogs; i++) if (file_has_changed_sounds[i] == sp) return(file_has_changed_dialogs[i]); /* try to find a free unmanaged dialog */ for (i = 0; i < num_file_has_changed_dialogs; i++) if ((file_has_changed_dialogs[i]) && (!widget_is_active(file_has_changed_dialogs[i]))) return(file_has_changed_dialogs[i]); return(NULL); } static void save_file_has_changed_dialog(GtkWidget *d, snd_info *sp) { if (num_file_has_changed_dialogs == 0) { file_has_changed_dialogs = (GtkWidget **)calloc(1, sizeof(GtkWidget *)); file_has_changed_sounds = (snd_info **)calloc(1, sizeof(snd_info *)); } else { file_has_changed_dialogs = (GtkWidget **)realloc(file_has_changed_dialogs, (num_file_has_changed_dialogs + 1) * sizeof(GtkWidget *)); file_has_changed_sounds = (snd_info **)realloc(file_has_changed_sounds, (num_file_has_changed_dialogs + 1) * sizeof(snd_info *)); } file_has_changed_dialogs[num_file_has_changed_dialogs] = d; file_has_changed_sounds[num_file_has_changed_dialogs] = sp; num_file_has_changed_dialogs++; } void unpost_file_has_changed_if_any(snd_info *sp) { int i; for (i = 0; i < num_file_has_changed_dialogs; i++) if (((file_has_changed_sounds[i] == sp) || (!snd_ok(file_has_changed_sounds[i]))) && (widget_is_active(file_has_changed_dialogs[i]))) gtk_widget_hide(file_has_changed_dialogs[i]); } static void file_has_changed_activate(GtkDialog *w, gint id, gpointer context) { if (id == GTK_RESPONSE_YES) { snd_info *sp = (snd_info *)context; save_edits_without_asking(sp); sp->need_update = false; stop_bomb(sp); /* in case Snd already noticed the problem */ clear_status_area(sp); } gtk_widget_hide(GTK_WIDGET(w)); } void changed_file_dialog(snd_info *sp) { char *question; GtkWidget *dialog; question = mus_format("%s has changed! Save edits anyway?", sp->short_filename); dialog = file_has_changed_dialog(sp); if (!dialog) { dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, "%s", question); SG_SIGNAL_CONNECT(dialog, "response", file_has_changed_activate, (gpointer)sp); save_file_has_changed_dialog(dialog, sp); } else { g_object_set(dialog, "text", question, NULL); } free(question); gtk_widget_show(dialog); } /* drop */ typedef struct { void (*drop_watcher)(GtkWidget *w, const char *message, int x, int y, void *data); void (*drag_watcher)(GtkWidget *w, const char *message, int x, int y, drag_style_t dtype, void *data); GtkWidget *caller; void *context; } drop_watcher_t; static drop_watcher_t **drop_watchers = NULL; static int drop_watchers_size = 0; #define DROP_WATCHER_SIZE_INCREMENT 2 static int add_drop_watcher(GtkWidget *w, void (*drop_watcher)(GtkWidget *w, const char *message, int x, int y, void *data), void (*drag_watcher)(GtkWidget *w, const char *message, int x, int y, drag_style_t dtype, void *data), void *context) { int loc = -1; if (!(drop_watchers)) { loc = 0; drop_watchers_size = DROP_WATCHER_SIZE_INCREMENT; drop_watchers = (drop_watcher_t **)calloc(drop_watchers_size, sizeof(drop_watcher_t *)); } else { int i; for (i = 0; i < drop_watchers_size; i++) if (!(drop_watchers[i])) { loc = i; break; } if (loc == -1) { loc = drop_watchers_size; drop_watchers_size += DROP_WATCHER_SIZE_INCREMENT; drop_watchers = (drop_watcher_t **)realloc(drop_watchers, drop_watchers_size * sizeof(drop_watcher_t *)); for (i = loc; i < drop_watchers_size; i++) drop_watchers[i] = NULL; } } drop_watchers[loc] = (drop_watcher_t *)calloc(1, sizeof(drop_watcher_t)); drop_watchers[loc]->drop_watcher = drop_watcher; drop_watchers[loc]->drag_watcher = drag_watcher; drop_watchers[loc]->context = context; drop_watchers[loc]->caller = w; return(loc); } static drop_watcher_t *find_drop_watcher(GtkWidget *caller) { if (drop_watchers) { int i; for (i = 0; i < drop_watchers_size; i++) { if (drop_watchers[i]) { drop_watcher_t *d; d = drop_watchers[i]; if (d->caller == caller) return(d); } } } return(NULL); } enum {TARGET_STRING, TARGET_UTF8, TARGET_URL}; static GtkTargetEntry target_table[] = { {(char *)"STRING", 0, TARGET_STRING}, {(char *)"FILE_NAME", 0, TARGET_STRING}, {(char *)"text/plain", 0, TARGET_STRING}, {(char *)"COMPOUND_TEXT", 0, TARGET_STRING}, {(char *)"UTF8_STRING", 0, TARGET_UTF8}, /* untested */ {(char *)"text/uri-list", 0, TARGET_URL} }; static Xen drop_hook; #if HAVE_GTK_ADJUSTMENT_GET_UPPER #define SELECTION_DATA(Data) (gtk_selection_data_get_data(Data)) #define SELECTION_LENGTH(Data) (gtk_selection_data_get_length(Data)) #define SELECTION_FORMAT(Data) (gtk_selection_data_get_format(Data)) #else #define SELECTION_DATA(Data) (Data->data) #define SELECTION_LENGTH(Data) (Data->length) #define SELECTION_FORMAT(Data) (Data->format) #endif static void drag_data_received(GtkWidget *caller, GdkDragContext *context, gint mx, gint my, GtkSelectionData *data, guint info, guint time) { /* data->target */ if ((SELECTION_LENGTH(data) >= 0) && (SELECTION_FORMAT(data) == 8)) { gsize bread, bwritten; GError *error; char *str; if (info == TARGET_STRING) str = (char *)(SELECTION_DATA(data)); else str = (char *)g_filename_from_utf8((gchar *)(SELECTION_DATA(data)), SELECTION_LENGTH(data), &bread, &bwritten, &error); if ((!(Xen_hook_has_list(drop_hook))) || (!(Xen_is_true(run_or_hook(drop_hook, Xen_list_1(C_string_to_Xen_string(str)), S_drop_hook))))) { drop_watcher_t *d; d = find_drop_watcher(caller); if (d) { /* loop through possible list of filenames, calling watcher on each */ char *filename; int len = 0, i, j = 0; len = mus_strlen(str); filename = (char *)calloc(len, sizeof(char)); for (i = 0; i < len; i++) { if (isspace((int)str[i])) { if (j > 0) { filename[j] = '\0'; if (strncmp(filename, "file://", 7) == 0) { char *tmp; tmp = (char *)(filename + 7); (*(d->drop_watcher))(caller, (const char *)tmp, mx, my, d->context); } else (*(d->drop_watcher))(caller, (const char *)filename, mx, my, d->context); j = 0; } /* else ignore extra white space chars */ } else { filename[j++] = str[i]; } } free(filename); } } gtk_drag_finish (context, true, false, time); return; } gtk_drag_finish(context, false, false, time); } static void drag_leave(GtkWidget *w, GdkDragContext *context, guint time) { drop_watcher_t *d; d = find_drop_watcher(w); if ((d) && (d->drag_watcher)) (*(d->drag_watcher))(w, NULL, 0, 0, DRAG_LEAVE, d->context); } static gboolean drag_motion(GtkWidget *w, GdkDragContext *context, gint x, gint y, guint time) { drop_watcher_t *d; d = find_drop_watcher(w); if ((d) && (d->drag_watcher)) (*(d->drag_watcher))(w, NULL, x, y, DRAG_MOTION, d->context); return(true); /* this is what the examples return in gtk/tests/testdnd.c -- don't know what it means, if anything */ } void add_drag_and_drop(GtkWidget *w, void (*drop_watcher)(GtkWidget *w, const char *message, int x, int y, void *data), void (*drag_watcher)(GtkWidget *w, const char *message, int x, int y, drag_style_t dtype, void *data), void *context) { gtk_drag_dest_set(w, GTK_DEST_DEFAULT_ALL, target_table, 6, (GdkDragAction)(GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK)); SG_SIGNAL_CONNECT(w, "drag_data_received", drag_data_received, NULL); SG_SIGNAL_CONNECT(w, "drag_motion", drag_motion, NULL); SG_SIGNAL_CONNECT(w, "drag_leave", drag_leave, NULL); add_drop_watcher(w, drop_watcher, drag_watcher, context); } void g_init_gxfile(void) { #define H_drop_hook S_drop_hook " (name): called whenever Snd receives a drag-and-drop \ event. If it returns " PROC_TRUE ", the file is not opened by Snd." drop_hook = Xen_define_hook(S_drop_hook, "(make-hook 'name)", 1, H_drop_hook); } snd-16.1/clm-ins.scm0000644000076400007640000036002112623430025012400 0ustar bilbil;;; CLM instruments translated to Snd/Scheme (provide 'snd-clm-ins.scm) (if (provided? 'snd) (require snd-ws.scm) (require sndlib-ws.scm)) (require snd-env.scm snd-dsp.scm snd-fullmix.scm snd-expandn.scm) ;;; -------- pluck ;;; ;;; The Karplus-Strong algorithm as extended by David Jaffe and Julius Smith -- see ;;; Jaffe and Smith, "Extensions of the Karplus-Strong Plucked-String Algorithm" ;;; CMJ vol 7 no 2 Summer 1983, reprinted in "The Music Machine". ;;; translated from CLM's pluck.ins (definstrument (pluck start dur freq amp (weighting .5) (lossfact .9)) "(pluck start dur freq amp weighting lossfact) implements the Jaffe-Smith plucked string physical model. 'weighting' is the ratio of the once-delayed to the twice-delayed samples. It defaults to .5=shortest decay. Anything other than .5 = longer decay. Must be between 0 and less than 1.0. 'lossfact' can be used to shorten decays. Most useful values are between .8 and 1.0. (with-sound () (pluck 0 1 330 .3 .7 .995))" (define (getOptimumC S o p) (let* ((pa (* (/ 1.0 o) (atan (* S (sin o)) (+ (- 1.0 S) (* S (cos o)))))) (tmpInt (floor (- p pa))) (pc (- p pa tmpInt))) (if (< pc .1) (do () ((>= pc .1)) (set! tmpInt (- tmpInt 1)) (set! pc (+ pc 1.0)))) (list tmpInt (/ (- (sin o) (sin (* o pc))) (sin (+ o (* o pc))))))) (define (tuneIt f s1) (let ((p (/ *clm-srate* f)) ;period as float (s (if (= s1 0.0) 0.5 s1)) (o (hz->radians f))) (let ((vals (getOptimumC s o p)) (vals1 (getOptimumC (- 1.0 s) o p))) (if (and (not (= s .5)) (< (abs (cadr vals)) (abs (cadr vals1)))) (list (- 1.0 s) (cadr vals) (car vals)) (list s (cadr vals1) (car vals1)))))) (let ((vals (tuneIt freq weighting))) (let ((wt0 (car vals)) (c (cadr vals)) (dlen (caddr vals)) (beg (seconds->samples start)) (end (seconds->samples (+ start dur))) (lf (if (= lossfact 0.0) 1.0 (min 1.0 lossfact)))) (let ((wt (if (= wt0 0.0) 0.5 (min 1.0 wt0))) (tab (make-float-vector dlen))) ;; get initial waveform in "tab" -- here we can introduce 0's to simulate different pick ;; positions, and so on -- see the CMJ article for numerous extensions. The normal case ;; is to load it with white noise (between -1 and 1). (let ((allp (make-one-zero (* lf (- 1.0 wt)) (* lf wt))) (feedb (make-one-zero c 1.0)) ;or (feedb (make-one-zero 1.0 c)) (c1 (- 1.0 c))) (do ((i 0 (+ i 1))) ((= i dlen)) (float-vector-set! tab i (mus-random 1.0))) (do ((i beg (+ i 1)) (ctr 0 (modulo (+ ctr 1) dlen))) ((= i end)) (outa i (* amp (float-vector-set! tab ctr (* c1 (one-zero feedb (one-zero allp (float-vector-ref tab ctr))))))))))))) #| (let ((val (float-vector-ref tab ctr))) ;current output value (float-vector-set! tab ctr (* c1 (one-zero feedb (one-zero allp val)))) (outa i (* amp val))))))))) |# ;;; -------- mlbvoi ;;; ;;; translation from MUS10 of Marc LeBrun's waveshaping voice instrument (using FM here) ;;; this version translated (and simplified slightly) from CLM's mlbvoi.ins (definstrument (vox beg dur freq amp ampfun freqfun freqscl phonemes formant-amps formant-indices (vibscl .1) (deg 0) (pcrev 0)) (let ((formants '((I 390 1990 2550) (E 530 1840 2480) (AE 660 1720 2410) (UH 520 1190 2390) (A 730 1090 2440) (OW 570 840 2410) (U 440 1020 2240) (OO 300 870 2240) (ER 490 1350 1690) (W 300 610 2200) (LL 380 880 2575) (R 420 1300 1600) (Y 300 2200 3065) (EE 260 3500 3800) (LH 280 1450 1600) (L 300 1300 3000) (I2 350 2300 3340) (B 200 800 1750) (D 300 1700 2600) (G 250 1350 2000) (M 280 900 2200) (N 280 1700 2600) (NG 280 2300 2750) (P 300 800 1750) (T 200 1700 2600) (K 350 1350 2000) (F 175 900 4400) (TH 200 1400 2200) (S 200 1300 2500) (SH 200 1800 2000) (V 175 1100 2400) (THE 200 1600 2200)(Z 200 1300 2500) (ZH 175 1800 2000) (ZZ 900 2400 3800) (VV 565 1045 2400)))) ;;formant center frequencies for a male speaker (define (find-phoneme phoneme forms) (if (eq? phoneme (caar forms)) (cdar forms) (find-phoneme phoneme (cdr forms)))) (define (vox-fun phons which) (let ((f1 ()) (len (length phons))) (do ((i 0 (+ i 2))) ((>= i len)) (set! f1 (cons (phons i) f1)) (set! f1 (cons ((find-phoneme (phons (+ i 1)) formants) which) f1))) (reverse f1))) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (car-os (make-oscil 0)) (fs (length formant-amps)) (per-vib (make-triangle-wave :frequency 6 :amplitude (hz->radians (* freq vibscl)))) (ran-vib (make-rand-interp :frequency 20 :amplitude (hz->radians (* freq .5 vibscl)))) (freqf (make-env freqfun :duration dur :scaler (hz->radians (* freqscl freq)) :offset (hz->radians freq)))) (if (and (= fs 3) (= (channels *output*) 1)) ;; optimize the common case (let ((a0 (make-env ampfun :scaler (* amp (formant-amps 0)) :duration dur)) (a1 (make-env ampfun :scaler (* amp (formant-amps 1)) :duration dur)) (a2 (make-env ampfun :scaler (* amp (formant-amps 2)) :duration dur)) (o0 (make-oscil 0.0)) (o1 (make-oscil 0.0)) (o2 (make-oscil 0.0)) (e0 (make-oscil 0.0)) (e1 (make-oscil 0.0)) (e2 (make-oscil 0.0)) (ind0 (formant-indices 0)) (ind1 (formant-indices 1)) (ind2 (formant-indices 2)) (f0 (make-env (vox-fun phonemes 0) :scaler (hz->radians 1.0) :duration dur)) (f1 (make-env (vox-fun phonemes 1) :scaler (hz->radians 1.0) :duration dur)) (f2 (make-env (vox-fun phonemes 2) :scaler (hz->radians 1.0) :duration dur))) (do ((i start (+ i 1))) ((= i end)) (let* ((frq (+ (env freqf) (triangle-wave per-vib) (rand-interp ran-vib))) (carg (oscil car-os frq)) (frm0 (/ (env f0) frq)) (frm1 (/ (env f1) frq)) (frm2 (/ (env f2) frq))) (outa i (+ (* (env a0) (+ (* (even-weight frm0) (oscil e0 (+ (* ind0 carg) (even-multiple frm0 frq)))) (* (odd-weight frm0) (oscil o0 (+ (* ind0 carg) (odd-multiple frm0 frq)))))) (* (env a1) (+ (* (even-weight frm1) (oscil e1 (+ (* ind1 carg) (even-multiple frm1 frq)))) (* (odd-weight frm1) (oscil o1 (+ (* ind1 carg) (odd-multiple frm1 frq)))))) (* (env a2) (+ (* (even-weight frm2) (oscil e2 (+ (* ind2 carg) (even-multiple frm2 frq)))) (* (odd-weight frm2) (oscil o2 (+ (* ind2 carg) (odd-multiple frm2 frq))))))))))) (let ((evens (make-vector fs)) (odds (make-vector fs)) (ampfs (make-vector fs)) (indices (make-float-vector fs 0.0)) (frmfs (make-vector fs)) (carrier 0.0) (frm-int 0) (rfrq 0.0) (frm0 0.0) (frac 0.0) (fracf 0.0) (loc (make-locsig deg 1.0 pcrev))) (do ((i 0 (+ i 1))) ((= i fs)) (set! (evens i) (make-oscil 0)) (set! (odds i) (make-oscil 0)) (set! (ampfs i) (make-env ampfun :scaler (* amp (formant-amps i)) :duration dur)) (set! (indices i) (formant-indices i)) (set! (frmfs i) (make-env (vox-fun phonemes i) :scaler (hz->radians 1.0) :duration dur))) (if (= fs 3) (let ((frmfs0 (frmfs 0)) (frmfs1 (frmfs 1)) (frmfs2 (frmfs 2)) (index0 (indices 0)) (index1 (indices 1)) (index2 (indices 2)) (ampfs0 (ampfs 0)) (ampfs1 (ampfs 1)) (ampfs2 (ampfs 2)) (evens0 (evens 0)) (evens1 (evens 1)) (evens2 (evens 2)) (odds0 (odds 0)) (odds1 (odds 1)) (odds2 (odds 2))) (do ((i start (+ i 1))) ((= i end)) (set! rfrq (+ (env freqf) (triangle-wave per-vib) (rand-interp ran-vib))) (set! carrier (oscil car-os rfrq)) (set! frm0 (/ (env frmfs0) rfrq)) (set! frm-int (floor frm0)) (set! frac (- frm0 frm-int)) (set! fracf (+ (* index0 carrier) (* frm-int rfrq))) (if (even? frm-int) (locsig loc i (* (env ampfs0) (+ (* (- 1.0 frac) (oscil evens0 fracf)) (* frac (oscil odds0 (+ fracf rfrq)))))) (locsig loc i (* (env ampfs0) (+ (* frac (oscil evens0 (+ fracf rfrq))) (* (- 1.0 frac) (oscil odds0 fracf)))))) (set! frm0 (/ (env frmfs1) rfrq)) (set! frm-int (floor frm0)) (set! frac (- frm0 frm-int)) (set! fracf (+ (* index1 carrier) (* frm-int rfrq))) (if (even? frm-int) (locsig loc i (* (env ampfs1) (+ (* (- 1.0 frac) (oscil evens1 fracf)) (* frac (oscil odds1 (+ fracf rfrq)))))) (locsig loc i (* (env ampfs1) (+ (* frac (oscil evens1 (+ fracf rfrq))) (* (- 1.0 frac) (oscil odds1 fracf)))))) (set! frm0 (/ (env frmfs2) rfrq)) (set! frm-int (floor frm0)) (set! frac (- frm0 frm-int)) (set! fracf (+ (* index2 carrier) (* frm-int rfrq))) (if (even? frm-int) (locsig loc i (* (env ampfs2) (+ (* (- 1.0 frac) (oscil evens2 fracf)) (* frac (oscil odds2 (+ fracf rfrq)))))) (locsig loc i (* (env ampfs2) (+ (* frac (oscil evens2 (+ fracf rfrq))) (* (- 1.0 frac) (oscil odds2 fracf)))))))) (do ((i start (+ i 1))) ((= i end)) (set! rfrq (+ (env freqf) (triangle-wave per-vib) (rand-interp ran-vib))) (set! carrier (oscil car-os rfrq)) ; better name: modulator or perhaps perceived-carrier? (do ((k 0 (+ k 1))) ((= k fs)) (set! frm0 (/ (env (vector-ref frmfs k)) rfrq)) (set! frm-int (floor frm0)) (set! frac (- frm0 frm-int)) (set! fracf (+ (* (float-vector-ref indices k) carrier) (* frm-int rfrq))) (if (even? frm-int) (locsig loc i (* (env (vector-ref ampfs k)) (+ (* (- 1.0 frac) (oscil (vector-ref evens k) fracf)) (* frac (oscil (vector-ref odds k) (+ fracf rfrq)))))) (locsig loc i (* (env (vector-ref ampfs k)) (+ (* frac (oscil (vector-ref evens k) (+ fracf rfrq))) (* (- 1.0 frac) (oscil (vector-ref odds k) fracf)))))))))))))) ;;; (with-sound (:statistics #t) (vox 0 2 170 .4 '(0 0 25 1 75 1 100 0) '(0 0 5 .5 10 0 100 1) .1 '(0 E 25 AE 35 ER 65 ER 75 I 100 UH) '(.8 .15 .05) '(.005 .0125 .025) .05 .1)) ;;; (with-sound () (vox 0 2 300 .4 '(0 0 25 1 75 1 100 0) '(0 0 5 .5 10 0 100 1) .1 '(0 I 5 OW 10 I 50 AE 100 OO) '(.8 .15 .05) '(.05 .0125 .025) .02 .1)) ;;; (with-sound () (vox 0 5 600 .4 '(0 0 25 1 75 1 100 0) '(0 0 5 .5 10 0 100 1) .1 '(0 I 5 OW 10 I 50 AE 100 OO) '(.8 .16 .04) '(.01 .01 .1) .01 .1)) ;;; -------- PQWVOX ;;; translation of CLM pqwvox.ins (itself translated from MUS10 of MLB's waveshaping voice instrument (using phase quadrature waveshaping)) (definstrument (pqw-vox beg dur freq spacing-freq amp ampfun freqfun freqscl phonemes formant-amps formant-shapes) "(pqw-vox beg dur freq spacing-freq amp ampfun freqfun freqscl phonemes formant-amps formant-shapes) produces vocal sounds using phase quadrature waveshaping" (define formants '((I 390 1990 2550) (E 530 1840 2480) (AE 660 1720 2410) (UH 520 1190 2390) (A 730 1090 2440) (OW 570 840 2410) (U 440 1020 2240) (OO 300 870 2240) (ER 490 1350 1690) (W 300 610 2200) (LL 380 880 2575) (R 420 1300 1600) (Y 300 2200 3065) (EE 260 3500 3800) (LH 280 1450 1600) (L 300 1300 3000) (I2 350 2300 3340) (B 200 800 1750) (D 300 1700 2600) (G 250 1350 2000) (M 280 900 2200) (N 280 1700 2600) (NG 280 2300 2750) (P 300 800 1750) (T 200 1700 2600) (K 350 1350 2000) (F 175 900 4400) (TH 200 1400 2200) (S 200 1300 2500) (SH 200 1800 2000) (V 175 1100 2400) (THE 200 1600 2200)(Z 200 1300 2500) (ZH 175 1800 2000) (ZZ 900 2400 3800) (VV 565 1045 2400))) ;;formant center frequencies for a male speaker (define (find-phoneme phoneme form) (if (eq? (caar form) phoneme) (cdar form) (find-phoneme phoneme (cdr form)))) (define (vox-fun phons which newenv) ;; make an envelope from which-th entry of phoneme data referred to by phons (if (null? phons) newenv (vox-fun (cddr phons) which (append newenv (list (car phons) ((find-phoneme (cadr phons) formants) which)))))) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (car-sin (make-oscil 0)) (car-cos (make-oscil 0 :initial-phase (/ pi 2.0))) (frq-ratio (/ spacing-freq freq)) (fs (length formant-amps)) (freqf (make-env freqfun :duration dur :scaler (* freqscl freq) :offset freq)) (per-vib (make-triangle-wave :frequency 6.0 :amplitude (* freq .1))) (ran-vib (make-rand-interp :frequency 20.0 :amplitude (* freq .05)))) (let ((sin-evens (make-vector fs)) (cos-evens (make-vector fs)) (sin-odds (make-vector fs)) (cos-odds (make-vector fs)) (ampfs (make-vector fs)) (frmfs (make-vector fs)) (sin-coeffs (make-vector fs)) (cos-coeffs (make-vector fs)) (frq 0.0) (rfrq 0.0) (carcos 0.0) (carsin 0.0) (frac 0.0) (fracf 0.0) (frm0 0.0) (frm-int 0) (fax 0.0) (yfax 0.0)) (do ((i 0 (+ i 1))) ((= i fs)) (let ((shape (normalize-partials (formant-shapes i)))) (set! (sin-evens i) (make-oscil 0)) (set! (sin-odds i) (make-oscil 0)) (set! (cos-evens i) (make-oscil 0 :initial-phase (/ pi 2.0))) (set! (cos-odds i) (make-oscil 0 :initial-phase (/ pi 2.0))) (set! (ampfs i) (make-env ampfun :scaler (* amp (formant-amps i)) :duration dur)) (set! (cos-coeffs i) (partials->polynomial shape mus-chebyshev-first-kind)) (set! (sin-coeffs i) (partials->polynomial shape mus-chebyshev-second-kind)) (set! (frmfs i) (make-env (vox-fun phonemes i ()) :duration dur)))) (if (= fs 3) ; unroll the inner loop in the most common case (let ((frmfs0 (frmfs 0)) (frmfs1 (frmfs 1)) (frmfs2 (frmfs 2)) (ampfs0 (ampfs 0)) (ampfs1 (ampfs 1)) (ampfs2 (ampfs 2)) (sin-evens0 (sin-evens 0)) (sin-evens1 (sin-evens 1)) (sin-evens2 (sin-evens 2)) (sin-odds0 (sin-odds 0)) (sin-odds1 (sin-odds 1)) (sin-odds2 (sin-odds 2)) (cos-evens0 (cos-evens 0)) (cos-evens1 (cos-evens 1)) (cos-evens2 (cos-evens 2)) (cos-odds0 (cos-odds 0)) (cos-odds1 (cos-odds 1)) (cos-odds2 (cos-odds 2)) (cos-coeffs0 (cos-coeffs 0)) (cos-coeffs1 (cos-coeffs 1)) (cos-coeffs2 (cos-coeffs 2)) (sin-coeffs0 (sin-coeffs 0)) (sin-coeffs1 (sin-coeffs 1)) (sin-coeffs2 (sin-coeffs 2))) (do ((i start (+ i 1))) ((= i end)) (set! frq (+ (env freqf) (triangle-wave per-vib) (rand-interp ran-vib))) (set! rfrq (hz->radians frq)) (set! carsin (oscil car-sin (* rfrq frq-ratio))) (set! carcos (oscil car-cos (* rfrq frq-ratio))) (set! frm0 (/ (env frmfs0) frq)) (set! frm-int (floor frm0)) (set! frac (- frm0 frm-int)) (set! fracf (* frm-int rfrq)) (set! fax (polynomial cos-coeffs0 carcos)) (set! yfax (* carsin (polynomial sin-coeffs0 carcos))) (if (even? frm-int) (outa i (* (env ampfs0) (+ (* (- 1.0 frac) (- (* yfax (oscil sin-evens0 fracf)) (* fax (oscil cos-evens0 fracf)))) (* frac (- (* yfax (oscil sin-odds0 (+ fracf rfrq))) (* fax (oscil cos-odds0 (+ fracf rfrq)))))))) (outa i (* (env ampfs0) (+ (* frac (- (* yfax (oscil sin-evens0 (+ fracf rfrq))) (* fax (oscil cos-evens0 (+ fracf rfrq))))) (* (- 1.0 frac) (- (* yfax (oscil sin-odds0 fracf)) (* fax (oscil cos-odds0 fracf)))))))) (set! frm0 (/ (env frmfs1) frq)) (set! frm-int (floor frm0)) (set! frac (- frm0 frm-int)) (set! fracf (* frm-int rfrq)) (set! fax (polynomial cos-coeffs1 carcos)) (set! yfax (* carsin (polynomial sin-coeffs1 carcos))) (if (even? frm-int) (outa i (* (env ampfs1) (+ (* (- 1.0 frac) (- (* yfax (oscil sin-evens1 fracf)) (* fax (oscil cos-evens1 fracf)))) (* frac (- (* yfax (oscil sin-odds1 (+ fracf rfrq))) (* fax (oscil cos-odds1 (+ fracf rfrq)))))))) (outa i (* (env ampfs1) (+ (* frac (- (* yfax (oscil sin-evens1 (+ fracf rfrq))) (* fax (oscil cos-evens1 (+ fracf rfrq))))) (* (- 1.0 frac) (- (* yfax (oscil sin-odds1 fracf)) (* fax (oscil cos-odds1 fracf)))))))) (set! frm0 (/ (env frmfs2) frq)) (set! frm-int (floor frm0)) (set! frac (- frm0 frm-int)) (set! fracf (* frm-int rfrq)) (set! fax (polynomial cos-coeffs2 carcos)) (set! yfax (* carsin (polynomial sin-coeffs2 carcos))) (if (even? frm-int) (outa i (* (env ampfs2) (+ (* (- 1.0 frac) (- (* yfax (oscil sin-evens2 fracf)) (* fax (oscil cos-evens2 fracf)))) (* frac (- (* yfax (oscil sin-odds2 (+ fracf rfrq))) (* fax (oscil cos-odds2 (+ fracf rfrq)))))))) (outa i (* (env ampfs2) (+ (* frac (- (* yfax (oscil sin-evens2 (+ fracf rfrq))) (* fax (oscil cos-evens2 (+ fracf rfrq))))) (* (- 1.0 frac) (- (* yfax (oscil sin-odds2 fracf)) (* fax (oscil cos-odds2 fracf)))))))))) (do ((i start (+ i 1))) ((= i end)) (set! frq (+ (env freqf) (triangle-wave per-vib) (rand-interp ran-vib))) (set! rfrq (hz->radians frq)) (set! carsin (oscil car-sin (* rfrq frq-ratio))) (set! carcos (oscil car-cos (* rfrq frq-ratio))) (do ((k 0 (+ k 1))) ((= k fs)) (set! frm0 (/ (env (vector-ref frmfs k)) frq)) (set! frm-int (floor frm0)) (set! frac (- frm0 frm-int)) (set! fracf (* frm-int rfrq)) (set! fax (polynomial (vector-ref cos-coeffs k) carcos)) (set! yfax (* carsin (polynomial (vector-ref sin-coeffs k) carcos))) (if (even? frm-int) (outa i (* (env (vector-ref ampfs k)) (+ (* (- 1.0 frac) (- (* yfax (oscil (vector-ref sin-evens k) fracf)) (* fax (oscil (vector-ref cos-evens k) fracf)))) (* frac (- (* yfax (oscil (vector-ref sin-odds k) (+ fracf rfrq))) (* fax (oscil (vector-ref cos-odds k) (+ fracf rfrq)))))))) (outa i (* (env (vector-ref ampfs k)) (+ (* frac (- (* yfax (oscil (vector-ref sin-evens k) (+ fracf rfrq))) (* fax (oscil (vector-ref cos-evens k) (+ fracf rfrq))))) (* (- 1.0 frac) (- (* yfax (oscil (vector-ref sin-odds k) fracf)) (* fax (oscil (vector-ref cos-odds k) fracf)))))))))))))) ;;; (with-sound (:statistics #t) (pqw-vox 0 1 300 300 .1 '(0 0 50 1 100 0) '(0 0 100 0) 0 '(0 L 100 L) '(.33 .33 .33) '((1 1 2 .5) (1 .5 2 .5 3 1) (1 1 4 .5)))) ;;; (a test to see if the cancellation is working -- sounds like a mosquito) ;;; (with-sound () (pqw-vox 0 2 200 200 .1 '(0 0 50 1 100 0) '(0 0 100 1) .1 '(0 UH 100 ER) '(.8 .15 .05) '((1 1 2 .5) (1 1 2 .5 3 .2 4 .1) (1 1 3 .1 4 .5)))) ;;; (with-sound () (pqw-vox 0 2 100 314 .1 '(0 0 50 1 100 0) '(0 0 100 1) .1 '(0 UH 100 ER) '(.8 .15 .05) '((1 1 2 .5) (1 1 2 .5 3 .2 4 .1) (1 1 3 .1 4 .5)))) ;;; (with-sound () (pqw-vox 0 2 200 314 .1 '(0 0 50 1 100 0) '(0 0 100 1) .01 '(0 UH 100 ER) '(.8 .15 .05) '((1 1 2 .5) (1 1 4 .1) (1 1 2 .1 4 .05)))) ;;; (with-sound () (pqw-vox 0 2 100 414 .2 '(0 0 50 1 100 0) '(0 0 100 1) .01 '(0 OW 50 E 100 ER) '(.8 .15 .05) '((1 1 2 .5 3 .1 4 .01) (1 1 4 .1) (1 1 2 .1 4 .05)))) ;;; -------- FOF (definstrument (fofins beg dur frq amp vib f0 a0 f1 a1 f2 a2 (ae '(0 0 25 1 75 1 100 0)) ve) "(fofins beg dur frq amp vib f0 a0 f1 a1 f2 a2 (ampenv '(0 0 25 1 75 1 100 0)) vibenv) produces FOF synthesis: (fofins 0 1 270 .2 .001 730 .6 1090 .3 2440 .1)" (let ((foflen (if (= *clm-srate* 22050) 100 200))) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (ampf (make-env ae :scaler amp :duration dur)) (vibf (make-env (or ve (list 0 1 100 1)) :scaler vib :duration dur)) (frq0 (hz->radians f0)) (frq1 (hz->radians f1)) (frq2 (hz->radians f2)) (vibr (make-oscil 6)) (win-freq (/ (* 2.0 pi) foflen)) (wt0 (make-wave-train :size foflen :frequency frq))) (let ((foftab (mus-data wt0))) (do ((i 0 (+ i 1))) ((= i foflen)) (float-vector-set! foftab i (* (+ (* a0 (sin (* i frq0))) (* a1 (sin (* i frq1))) (* a2 (sin (* i frq2)))) .5 (- 1.0 (cos (* i win-freq))))))) (do ((i start (+ i 1))) ((= i end)) (outa i (* (env ampf) (wave-train wt0 (* (env vibf) (oscil vibr))))))))) ;;; FM TRUMPET --------------------------------------------------- ;;; Dexter Morrill's FM-trumpet: ;;; from CMJ feb 77 p51 (definstrument (fm-trumpet startime dur (frq1 250.0) (frq2 1500.0) (amp1 0.5) (amp2 0.1) (ampatt1 0.03) (ampdec1 0.35) (ampatt2 0.03) (ampdec2 0.3) (modfrq1 250.0) (modind11 0.0) (modind12 2.66) (modfrq2 250.0) (modind21 0.0) (modind22 1.8) (rvibamp 0.007) (rvibfrq 125.0) (vibamp 0.007) (vibfrq 7.0) (vibatt 0.6) (vibdec 0.2) (frqskw 0.03) (frqatt 0.06) (ampenv1 '(0 0 25 1 75 .9 100 0)) (ampenv2 '(0 0 25 1 75 .9 100 0)) (indenv1 '(0 0 25 1 75 .9 100 0)) (indenv2 '(0 0 25 1 75 .9 100 0)) (degree 0.0) (distance 1.0) (reverb-amount 0.005)) (let ((dec-01 (max 75 (* 100 (- 1.0 (/ .01 dur)))))) (let ((beg (seconds->samples startime)) (end (seconds->samples (+ startime dur))) (loc (make-locsig degree distance reverb-amount)) (per-vib-f (make-env (stretch-envelope '(0 1 25 .1 75 0 100 0) 25 (min (* 100 (/ vibatt dur)) 45) 75 (max (* 100 (- 1.0 (/ vibdec dur))) 55)) :scaler vibamp :duration dur)) (ran-vib (make-rand-interp :frequency rvibfrq :amplitude rvibamp)) (per-vib (make-oscil vibfrq)) (frq-f (make-env (stretch-envelope '(0 0 25 1 75 1 100 0) 25 (min 25 (* 100 (/ frqatt dur))) 75 dec-01) :scaler frqskw :offset 1.0 :duration dur)) (ampattpt1 (min 25 (* 100 (/ ampatt1 dur)))) (ampdecpt1 (max 75 (* 100 (- 1.0 (/ ampdec1 dur))))) (ampattpt2 (min 25 (* 100 (/ ampatt2 dur)))) (ampdecpt2 (max 75 (* 100 (- 1.0 (/ ampdec2 dur)))))) (let ((mod1-f (make-env (stretch-envelope indenv1 25 ampattpt1 75 dec-01) :scaler (* modfrq1 (- modind12 modind11)) :duration dur)) (mod1 (make-oscil 0.0)) (car1 (make-oscil 0.0)) ;; set frequency to zero here because it is handled multiplicatively below (car1-f (make-env (stretch-envelope ampenv1 25 ampattpt1 75 ampdecpt1) :scaler amp1 :duration dur)) (mod2-f (make-env (stretch-envelope indenv2 25 ampattpt2 75 dec-01) :scaler (* modfrq2 (- modind22 modind21)) :duration dur)) (mod2 (make-oscil 0.0)) (car2 (make-oscil 0.0)) (car2-f (make-env (stretch-envelope ampenv2 25 ampattpt2 75 ampdecpt2) :scaler amp2 :duration dur))) (do ((i beg (+ i 1))) ((= i end)) (let ((frq-change (hz->radians (* (+ 1.0 (rand-interp ran-vib)) (+ 1.0 (* (env per-vib-f) (oscil per-vib))) (env frq-f))))) (locsig loc i (+ (* (env car1-f) (oscil car1 (* frq-change (+ frq1 (* (env mod1-f) (oscil mod1 (* modfrq1 frq-change))))))) (* (env car2-f) (oscil car2 (* frq-change (+ frq2 (* (env mod2-f) (oscil mod2 (* modfrq2 frq-change))))))))))))))) ;;; -------- STEREO-FLUTE (definstrument (stereo-flute start dur freq flow (flow-envelope '(0 1 100 1)) (decay 0.01) ; additional time for instrument to decay (noise 0.0356) (embouchure-size 0.5) (fbk-scl1 0.5) ; these two are crucial for good results (fbk-scl2 0.55) (offset-pos 0.764264) ; from 0.0 to 1.0 along the bore (out-scl 1.0) (a0 0.7) (b1 -0.3) ; filter coefficients (vib-rate 5) (vib-amount 0.03) (ran-rate 5) (ran-amount 0.03)) "(stereo-flute dur freq flow (flow-envelope '(0 1 100 1)) (decay 0.01) (noise 0.0356) (embouchure-size 0.5) (fbk-scl1 0.5) (fbk-scl2 0.55) (offset-pos 0.764264) (out-scl 1.0) (a0 0.7) (b1 -0.3) (vib-rate 5) (vib-amount 0.03) (ran-rate 5) (ran-amount 0.03)) is a physical model of a flute: (stereo-flute 0 1 440 .55 :flow-envelope '(0 0 1 1 2 1 3 0))" (let ((period-samples (floor (/ *clm-srate* freq)))) (let ((embouchure-samples (floor (* embouchure-size period-samples)))) (let ((current-excitation 0.0) (current-difference 0.0) (current-flow 0.0) (out-sig 0.0) (tap-sig 0.0) (previous-out-sig 0.0) (previous-tap-sig 0.0) (dc-blocked-a 0.0) (dc-blocked-b 0.0) (previous-dc-blocked-a 0.0) (previous-dc-blocked-b 0.0) (delay-sig 0.0) (emb-sig 0.0) (beg (seconds->samples start)) (end (seconds->samples (+ start dur))) (flowf (make-env flow-envelope :scaler flow :duration (- dur decay))) (periodic-vibrato (make-oscil vib-rate)) (random-vibrato (make-rand-interp :frequency ran-rate :amplitude ran-amount)) (breath (make-rand :frequency (/ *clm-srate* 2) :amplitude noise)) (embouchure (make-delay embouchure-samples :initial-element 0.0)) (bore (make-delay period-samples)) (offset (floor (* period-samples offset-pos))) (reflection-lowpass-filter (make-one-pole a0 b1))) (do ((i beg (+ i 1))) ((= i end)) (set! delay-sig (delay bore out-sig)) (set! emb-sig (delay embouchure current-difference)) (set! current-flow (+ (* vib-amount (oscil periodic-vibrato)) (rand-interp random-vibrato) (env flowf))) (set! current-difference (+ current-flow (* current-flow (rand breath)) (* fbk-scl1 delay-sig))) (set! current-excitation (- emb-sig (* emb-sig emb-sig emb-sig))) (set! out-sig (one-pole reflection-lowpass-filter (+ current-excitation (* fbk-scl2 delay-sig)))) (set! tap-sig (tap bore offset)) ;; NB the DC blocker is not in the cicuit. It is applied to the out-sig ;; but the result is not fed back into the system. (set! dc-blocked-a (+ (- out-sig previous-out-sig) (* 0.995 previous-dc-blocked-a))) (set! dc-blocked-b (+ (- tap-sig previous-tap-sig) (* 0.995 previous-dc-blocked-b))) (outa i (* out-scl dc-blocked-a)) (outb i (* out-scl dc-blocked-b)) (set! previous-out-sig out-sig) (set! previous-dc-blocked-a dc-blocked-a) (set! previous-tap-sig tap-sig) (set! previous-dc-blocked-b dc-blocked-b)))))) ;;; -------- FM-BELL (definstrument (fm-bell startime dur frequency amplitude amp-env index-env index) "(fm-bell startime dur frequency amplitude amp-env index-env index) mixes in one fm bell note" (let ((fmInd2 (hz->radians (* 4.0 (- 8.0 (/ frequency 50.0)))))) (let ((beg (seconds->samples startime)) ;(len (seconds->samples dur)) (end (seconds->samples (+ startime dur))) (fmInd1 (hz->radians (* 32.0 frequency))) (fmInd3 (* fmInd2 0.705 (- 1.4 (/ frequency 250.0)))) (fmInd4 (hz->radians (* 32.0 (- 20 (/ frequency 20))))) (mod1 (make-oscil (* frequency 2))) (mod2 (make-oscil (* frequency 1.41))) (mod3 (make-oscil (* frequency 2.82))) (mod4 (make-oscil (* frequency 2.4))) (car1 (make-oscil frequency)) (car2 (make-oscil frequency)) (car3 (make-oscil (* frequency 2.4))) (indf (make-env (or index-env (list 0 1 2 1.1 25 .75 75 .5 100 .2)) (or index 1.0) dur)) (ampf (make-env (or amp-env (list 0 0 .1 1 10 .6 25 .3 50 .15 90 .1 100 0)) amplitude dur))) (do ((i beg (+ i 1))) ((= i end)) (let ((fmenv (env indf))) (outa i (* (env ampf) (+ (oscil car1 (* fmenv fmInd1 (oscil mod1))) (* .15 (oscil car2 (* fmenv (+ (* fmInd2 (oscil mod2)) (* fmInd3 (oscil mod3)))))) (* .15 (oscil car3 (* fmenv fmInd4 (oscil mod4)))))))))))) ;(define fbell '(0 1 2 1.1000 25 .7500 75 .5000 100 .2000 )) ;(define abell '(0 0 .1000 1 10 .6000 25 .3000 50 .1500 90 .1000 100 0 )) ;(fm-bell 0.0 1.0 220.0 .5 abell fbell 1.0) ;;; -------- FM_INSECT (definstrument (fm-insect startime dur frequency amplitude amp-env mod-freq mod-skew mod-freq-env mod-index mod-index-env fm-index fm-ratio (degree 0.0) (distance 1.0) (reverb-amount 0.005)) (let ((beg (seconds->samples startime)) (end (seconds->samples (+ startime dur))) (loc (make-locsig degree distance reverb-amount)) (carrier (make-oscil frequency)) (fm1-osc (make-oscil mod-freq)) (fm2-osc (make-oscil (* fm-ratio frequency))) (ampf (make-env amp-env :scaler amplitude :duration dur)) (indf (make-env mod-index-env :scaler (hz->radians mod-index) :duration dur)) (modfrqf (make-env mod-freq-env :scaler (hz->radians mod-skew) :duration dur)) (fm2-amp (hz->radians (* fm-index fm-ratio frequency)))) (do ((i beg (+ i 1))) ((= i end)) (let ((garble-in (* (env indf) (oscil fm1-osc (env modfrqf))))) (locsig loc i (* (env ampf) (oscil carrier (+ (* fm2-amp (oscil fm2-osc garble-in)) garble-in)))))))) #| (with-sound (:srate 22050) (let ((locust '(0 0 40 1 95 1 100 .5)) (bug_hi '(0 1 25 .7 75 .78 100 1)) (amp '(0 0 25 1 75 .7 100 0))) (fm-insect 0 1.699 4142.627 .015 amp 60 -16.707 locust 500.866 bug_hi .346 .500) (fm-insect 0.195 .233 4126.284 .030 amp 60 -12.142 locust 649.490 bug_hi .407 .500) (fm-insect 0.217 2.057 3930.258 .045 amp 60 -3.011 locust 562.087 bug_hi .591 .500) (fm-insect 2.100 1.500 900.627 .06 amp 40 -16.707 locust 300.866 bug_hi .346 .500) (fm-insect 3.000 1.500 900.627 .06 amp 40 -16.707 locust 300.866 bug_hi .046 .500) (fm-insect 3.450 1.500 900.627 .09 amp 40 -16.707 locust 300.866 bug_hi .006 .500) (fm-insect 3.950 1.500 900.627 .12 amp 40 -10.707 locust 300.866 bug_hi .346 .500) (fm-insect 4.300 1.500 900.627 .09 amp 40 -20.707 locust 300.866 bug_hi .246 .500))) |# ;;; -------- FM-DRUM ;;; Jan Mattox's fm drum: (definstrument (fm-drum start-time duration frequency amplitude index high (degree 0.0) (distance 1.0) (reverb-amount 0.01)) (let (;; many of the following variables were originally passed as arguments (casrat (if high 8.525 3.515)) (fmrat (if high 3.414 1.414)) (glsfun '(0 0 25 0 75 1 100 1)) (indxfun '(0 0 5 .014 10 .033 15 .061 20 .099 25 .153 30 .228 35 .332 40 .477 45 .681 50 .964 55 .681 60 .478 65 .332 70 .228 75 .153 80 .099 85 .061 90 .033 95 .0141 100 0)) (indxpt (- 100 (* 100 (/ (- duration .1) duration)))) (ampfun '(0 0 3 .05 5 .2 7 .8 8 .95 10 1.0 12 .95 20 .3 30 .1 100 0)) (atdrpt (* 100 (/ (if high .01 .015) duration)))) (let ((divindxf (stretch-envelope indxfun 50 atdrpt 65 indxpt))) (let ((beg (seconds->samples start-time)) (end (seconds->samples (+ start-time duration))) (glsf (make-env glsfun :scaler (if high (hz->radians 66) 0.0) :duration duration)) (ampf (make-env (stretch-envelope ampfun 10 atdrpt 15 (max (+ atdrpt 1) (- 100 (* 100 (/ (- duration .2) duration))))) :scaler amplitude :duration duration)) (indxf (make-env divindxf :scaler (min (hz->radians (* index fmrat frequency)) pi) :duration duration)) (mindxf (make-env divindxf :scaler (min (hz->radians (* index casrat frequency)) pi) :duration duration)) (devf (make-env (stretch-envelope ampfun 10 atdrpt 90 (max (+ atdrpt 1) (- 100 (* 100 (/ (- duration .05) duration))))) :scaler (min pi (hz->radians 7000)) :duration duration)) (loc (make-locsig degree distance reverb-amount)) (rn (make-rand :frequency 7000 :amplitude 1.0)) (carrier (make-oscil frequency)) (fmosc (make-oscil (* frequency fmrat))) (cascade (make-oscil (* frequency casrat)))) (do ((i beg (+ i 1))) ((= i end)) (let ((gls (env glsf))) (locsig loc i (* (env ampf) (oscil carrier (+ gls (* (env indxf) (oscil fmosc (+ (* gls fmrat) (* (env mindxf) (oscil cascade (+ (* gls casrat) (* (env devf) (rand rn)))))))))))))))))) #| (with-sound () (fm-drum 0 1.5 55 .3 5 #f) (fm-drum 2 1.5 66 .3 4 #t)) |# ;;; -------- FM-GONG ;;; Paul Weineke's gong. (definstrument (gong start-time duration frequency amplitude (degree 0.0) (distance 1.0) (reverb-amount 0.005)) (let ((mfq1 (* frequency 1.16)) (mfq2 (* frequency 3.14)) (mfq3 (* frequency 1.005))) (let ((indx01 (hz->radians (* .01 mfq1))) (indx11 (hz->radians (* .30 mfq1))) (indx02 (hz->radians (* .01 mfq2))) (indx12 (hz->radians (* .38 mfq2))) (indx03 (hz->radians (* .01 mfq3))) (indx13 (hz->radians (* .50 mfq3))) (atpt 5) (atdur (* 100 (/ .002 duration))) (expf '(0 0 3 1 15 .5 27 .25 50 .1 100 0)) (rise '(0 0 15 .3 30 1.0 75 .5 100 0)) (fmup '(0 0 75 1.0 98 1.0 100 0)) (fmdwn '(0 0 2 1.0 100 0))) (let ((ampfun (make-env (stretch-envelope expf atpt atdur) :scaler amplitude :duration duration)) (indxfun1 (make-env fmup :duration duration :scaler (- indx11 indx01) :offset indx01)) (indxfun2 (make-env fmdwn :duration duration :scaler (- indx12 indx02) :offset indx02)) (indxfun3 (make-env rise :duration duration :scaler (- indx13 indx03) :offset indx03)) (loc (make-locsig degree distance reverb-amount)) (carrier (make-oscil frequency)) (mod1 (make-oscil mfq1)) (mod2 (make-oscil mfq2)) (mod3 (make-oscil mfq3)) (beg (seconds->samples start-time)) (end (seconds->samples (+ start-time duration)))) (do ((i beg (+ i 1))) ((= i end)) (locsig loc i (* (env ampfun) (oscil carrier (+ (* (env indxfun1) (oscil mod1)) (* (env indxfun2) (oscil mod2)) (* (env indxfun3) (oscil mod3))))))))))) ;;; (with-sound () (gong 0 3 261.61 .6)) (definstrument (attract beg dur amp c-1) ;c from 1 to 10 or so ;; by James McCartney, from CMJ vol 21 no 3 p 6 (let ((st (seconds->samples beg)) (nd (seconds->samples (+ beg dur))) (c c-1) (a .2) (b .2) (dt .04) (scale (/ (* .5 amp) c-1)) (x -1.0) (y 0.0) (z 0.0)) (do ((i st (+ i 1))) ((= i nd)) (let ((x1 (- x (* dt (+ y z))))) (set! y (+ y (* dt (+ x (* a y))))) (set! z (+ z (* dt (- (+ b (* x z)) (* c z))))) (set! x x1) (outa i (* scale x)))))) ;;; -------- PQW (definstrument (pqw start dur spacing-freq carrier-freq amplitude ampfun indexfun partials (degree 0.0) (distance 1.0) (reverb-amount 0.005)) ;; phase-quadrature waveshaping used to create asymmetric (i.e. single side-band) spectra. ;; The basic idea here is a variant of sin x sin y - cos x cos y = cos (x + y) (define (clip-env e) (do ((x e (cddr x))) ((null? x) e) (if (> (cadr x) 1.0) (list-set! x 1 1.0)))) (let ((normalized-partials (normalize-partials partials)) (spacing-cos (make-oscil spacing-freq :initial-phase (/ pi 2.0))) (spacing-sin (make-oscil spacing-freq)) (carrier-cos (make-oscil carrier-freq :initial-phase (/ pi 2.0))) (carrier-sin (make-oscil carrier-freq))) (let ((sin-coeffs (partials->polynomial normalized-partials mus-chebyshev-second-kind)) (cos-coeffs (partials->polynomial normalized-partials mus-chebyshev-first-kind)) (amp-env (make-env ampfun :scaler amplitude :duration dur)) (ind-env (make-env (clip-env indexfun) :duration dur)) (loc (make-locsig degree distance reverb-amount)) (r (/ carrier-freq spacing-freq)) (tr (make-triangle-wave :frequency 5 :amplitude (hz->radians (* .005 spacing-freq)))) (rn (make-rand-interp :frequency 12 :amplitude (hz->radians (* .005 spacing-freq)))) (beg (seconds->samples start)) (end (seconds->samples (+ start dur)))) (do ((i beg (+ i 1))) ((= i end)) (let* ((vib (+ (triangle-wave tr) (rand-interp rn))) (ax (* (env ind-env) (oscil spacing-cos vib)))) (locsig loc i (* (env amp-env) (- (* (oscil carrier-sin (* vib r)) (oscil spacing-sin vib) (polynomial sin-coeffs ax)) (* (oscil carrier-cos (* vib r)) (polynomial cos-coeffs ax)))))))))) ;; (with-sound () (pqw 0 .5 200 1000 .2 '(0 0 25 1 100 0) '(0 1 100 0) '(2 .1 3 .3 6 .5))) ;; to see the asymmetric spectrum most clearly, set the index function above to '(0 1 100 1) ;;; taken from Perry Cook's stkv1.tar.Z (Synthesis Toolkit), but I was ;;; in a bit of a hurry and may not have made slavishly accurate translations. ;;; Please let me know of any errors. (definstrument (tubebell beg dur freq amp (base 32.0)) ;; from Perry Cook's TubeBell.cpp (let ((osc0 (make-oscil (* freq 0.995))) (osc1 (make-oscil (* freq 1.414 0.995))) (osc2 (make-oscil (* freq 1.005))) (osc3 (make-oscil (* freq 1.414))) (ampenv1 (make-env (list 0 0 .005 1 dur 0) :base base :duration dur :scaler (* amp .5 .707))) (ampenv2 (make-env (list 0 0 .001 1 dur 0) :base (* 2 base) :duration dur :scaler (* .5 amp))) (ampmod (make-oscil 2.0)) (st (seconds->samples beg)) (nd (seconds->samples (+ beg dur)))) (do ((i st (+ i 1))) ((= i nd)) (outa i (* (+ (* .007 (oscil ampmod)) .993) (+ (* (env ampenv1) (oscil osc0 (* .203 (oscil osc1)))) (* (env ampenv2) (oscil osc2 (* .144 (oscil osc3)))))))))) (definstrument (wurley beg dur freq amp) ;; from Perry Cook's Wurley.cpp (let ((osc0 (make-oscil freq)) (osc1 (make-oscil (* freq 4.0))) (osc2 (make-oscil 510.0)) (osc3 (make-oscil 510.0)) (ampmod (make-oscil 8.0)) (g0 (* .5 amp)) (ampenv (make-env '(0 0 1 1 9 1 10 0) :duration dur)) (indenv (make-env (list 0 0 .001 1 .15 0 (max dur .16) 0) :duration dur :scaler .117)) (resenv (make-env (list 0 0 .001 1 .25 0 (max dur .26) 0) :duration dur :scaler (* .5 .307 amp))) (st (seconds->samples beg)) (nd (seconds->samples (+ beg dur)))) (do ((i st (+ i 1))) ((= i nd)) (outa i (* (env ampenv) (+ 1.0 (* .007 (oscil ampmod))) (+ (* g0 (oscil osc0 (* .307 (oscil osc1)))) (* (env resenv) (oscil osc2 (* (env indenv) (oscil osc3)))))))))) (definstrument (rhodey beg dur freq amp (base .5)) ;; from Perry Cook's Rhodey.cpp (let ((osc0 (make-oscil freq)) (osc1 (make-oscil (* freq 0.5))) (osc2 (make-oscil freq)) (osc3 (make-oscil (* freq 15.0))) (ampenv1 (make-env (list 0 0 .005 1 dur 0) :base base :duration dur :scaler (* amp .5))) (ampenv2 (make-env (list 0 0 .001 1 dur 0) :base (* base 1.5) :duration dur :scaler (* amp .5))) (ampenv3 (make-env (list 0 0 .001 1 .25 0 (max dur .26) 0) :base (* base 4) :duration dur :scaler .109)) (st (seconds->samples beg)) (nd (seconds->samples (+ beg dur)))) (do ((i st (+ i 1))) ((= i nd)) (outa i (+ (* (env ampenv1) (oscil osc0 (* .535 (oscil osc1)))) (* (env ampenv2) (oscil osc2 (* (env ampenv3) (oscil osc3))))))))) (definstrument (hammondoid beg dur freq amp) ;; from Perry Cook's BeeThree.cpp (let ((osc0 (make-oscil (* freq 0.999))) (osc1 (make-oscil (* freq 1.997))) (osc2 (make-oscil (* freq 3.006))) (osc3 (make-oscil (* freq 6.009))) (ampenv1 (make-env (list 0 0 .005 1 (- dur .008) 1 dur 0) :duration dur)) (ampenv2 (make-env (list 0 0 .005 1 dur 0) :duration dur :scaler (* .5 .75 amp))) (g0 (* .25 .75 amp)) (g1 (* .25 .75 amp)) (g2 (* .5 amp)) (st (seconds->samples beg)) (nd (seconds->samples (+ beg dur)))) (do ((i st (+ i 1))) ((= i nd)) (outa i (+ (* (env ampenv1) (+ (* g0 (oscil osc0)) (* g1 (oscil osc1)) (* g2 (oscil osc2)))) (* (env ampenv2) (oscil osc3))))))) (definstrument (metal beg dur freq amp) ;; from Perry Cook's HeavyMtl.cpp (let ((osc0 (make-oscil freq)) (osc1 (make-oscil (* freq 4.0 0.999))) (osc2 (make-oscil (* freq 3.0 1.001))) (osc3 (make-oscil (* freq 0.50 1.002))) (ampenv0 (make-env (list 0 0 .001 1 (- dur .002) 1 dur 0) :duration dur :scaler (* amp .615))) (ampenv1 (make-env (list 0 0 .001 1 (- dur .011) 1 dur 0) :duration dur :scaler .202)) (ampenv2 (make-env (list 0 0 .01 1 (- dur .015) 1 dur 0) :duration dur :scaler .574)) (ampenv3 (make-env (list 0 0 .03 1 (- dur .040) 1 dur 0) :duration dur :scaler .116)) (st (seconds->samples beg)) (nd (seconds->samples (+ beg dur)))) (do ((i st (+ i 1))) ((= i nd)) (outa i (* (env ampenv0) (oscil osc0 (+ (* (env ampenv1) (oscil osc1 (* (env ampenv2) (oscil osc2)))) (* (env ampenv3) (oscil osc3))))))))) (definstrument (drone startime dur frequency amp ampfun synth ampat ampdc amtrev deg dis rvibamt rvibfreq) (let ((beg (seconds->samples startime)) (end (seconds->samples (+ startime dur))) (waveform (partials->wave synth)) (amplitude (* amp .25)) (freq (hz->radians frequency))) (let ((s (make-table-lookup :frequency frequency :wave waveform)) (amp-env (make-env (stretch-envelope ampfun 25 (* 100 (/ ampat dur)) 75 (- 100 (* 100 (/ ampdc dur)))) :scaler amplitude :duration dur)) (ran-vib (make-rand :frequency rvibfreq :amplitude (* rvibamt freq))) (loc (make-locsig deg dis amtrev))) (do ((i beg (+ i 1))) ((= i end)) (locsig loc i (* (env amp-env) (table-lookup s (rand ran-vib)))))))) (definstrument (canter beg dur pitch amp-1 deg dis pcrev ampfun ranfun skewfun skewpc ranpc ranfreq indexfun atdr dcdr ampfun1 indfun1 fmtfun1 ampfun2 indfun2 fmtfun2 ampfun3 indfun3 fmtfun3 ampfun4 indfun4 fmtfun4) (let ((amp (* amp-1 .25)) ;pvc's amplitudes in bag.clm are very high (overflows) (rangetop 910.0) (rangebot 400.0)) (let ((k (floor (* 100 (log (/ pitch rangebot) (/ rangetop rangebot))))) (atpt (* 100 (/ atdr dur))) (dcpt (- 100 (* 100 (/ dcdr dur))))) (let ((lfmt1 (envelope-interp k fmtfun1)) (lfmt2 (envelope-interp k fmtfun2)) (lfmt3 (envelope-interp k fmtfun3)) (lfmt4 (envelope-interp k fmtfun4)) (dev11 (hz->radians (* (envelope-interp k indfun1) pitch))) (dev12 (hz->radians (* (envelope-interp k indfun2) pitch))) (dev13 (hz->radians (* (envelope-interp k indfun3) pitch))) (dev14 (hz->radians (* (envelope-interp k indfun4) pitch)))) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (dev01 (* dev11 .5)) (dev02 (* dev12 .5)) (dev03 (* dev13 .5)) (dev04 (* dev14 .5)) (harm1 (floor (+ .5 (/ lfmt1 pitch)))) (harm2 (floor (+ .5 (/ lfmt2 pitch)))) (harm3 (floor (+ .5 (/ lfmt3 pitch)))) (harm4 (floor (+ .5 (/ lfmt4 pitch))))) (let ((lamp1 (* (envelope-interp k ampfun1) amp (- 1 (abs (- harm1 (/ lfmt1 pitch)))))) (lamp2 (* (envelope-interp k ampfun2) amp (- 1 (abs (- harm2 (/ lfmt2 pitch)))))) (lamp3 (* (envelope-interp k ampfun3) amp (- 1 (abs (- harm3 (/ lfmt3 pitch)))))) (lamp4 (* (envelope-interp k ampfun4) amp (- 1 (abs (- harm4 (/ lfmt4 pitch)))))) (tidx-stretched (stretch-envelope indexfun 25 atpt 75 dcpt))) (let ((tampfun (make-env (stretch-envelope ampfun 25 atpt 75 dcpt) :duration dur)) (tskwfun (make-env (stretch-envelope skewfun 25 atpt 75 dcpt) :scaler (hz->radians (* pitch skewpc)) :duration dur)) (tranfun (make-env (stretch-envelope ranfun 25 atpt 75 dcpt) :duration dur)) (d1env (make-env tidx-stretched :offset dev01 :scaler dev11 :duration dur)) (d2env (make-env tidx-stretched :offset dev02 :scaler dev12 :duration dur)) (d3env (make-env tidx-stretched :offset dev03 :scaler dev13 :duration dur)) (d4env (make-env tidx-stretched :offset dev04 :scaler dev14 :duration dur)) (modgen (make-oscil pitch)) (ranvib (make-rand :frequency ranfreq :amplitude (hz->radians (* ranpc pitch)))) (loc (make-locsig deg dis pcrev)) (gen1 (make-oscil (* pitch harm1))) (gen2 (make-oscil (* pitch harm2))) (gen3 (make-oscil (* pitch harm3))) (gen4 (make-oscil (* pitch harm4)))) (do ((i start (+ i 1))) ((= i end)) (let* ((frqval (+ (env tskwfun) (* (env tranfun) (rand ranvib)))) (modval (oscil modgen frqval))) (locsig loc i (* (env tampfun) (+ (* lamp1 (oscil gen1 (* (+ (* (env d1env) modval) frqval) harm1))) (* lamp2 (oscil gen2 (* (+ (* (env d2env) modval) frqval) harm2))) (* lamp3 (oscil gen3 (* (+ (* (env d3env) modval) frqval) harm3))) (* lamp4 (oscil gen4 (* (+ (* (env d4env) modval) frqval) harm4))))))))))))))) ;;; NREV (the most popular Samson box reverb) (definstrument (nrev (reverb-factor 1.09) (lp-coeff 0.7) (volume 1.0)) ;; reverb-factor controls the length of the decay -- it should not exceed (/ 1.0 .823) ;; lp-coeff controls the strength of the low pass filter inserted in the feedback loop ;; output-scale can be used to boost the reverb output (define (prime? val) (or (= val 2) (and (odd? val) (do ((i 3 (+ i 2)) (lim (sqrt val))) ((or (= 0 (modulo val i)) (> i lim)) (> i lim)))))) (define (next-prime val) (if (prime? val) val (next-prime (+ val 2)))) (let ((srscale (/ *clm-srate* 25641)) (dly-len (list 1433 1601 1867 2053 2251 2399 347 113 37 59 53 43 37 29 19)) (chan2 (> (channels *output*) 1)) (chan4 (= (channels *output*) 4))) (do ((i 0 (+ i 1))) ((= i 15)) (let ((val (floor (* srscale (dly-len i))))) (if (even? val) (set! val (+ val 1))) (set! (dly-len i) (next-prime val)))) (let ((len (+ (floor *clm-srate*) (framples *reverb*))) (comb1 (make-comb (* .822 reverb-factor) (dly-len 0))) (comb2 (make-comb (* .802 reverb-factor) (dly-len 1))) (comb3 (make-comb (* .773 reverb-factor) (dly-len 2))) (comb4 (make-comb (* .753 reverb-factor) (dly-len 3))) (comb5 (make-comb (* .753 reverb-factor) (dly-len 4))) (comb6 (make-comb (* .733 reverb-factor) (dly-len 5))) (low (make-one-pole lp-coeff (- lp-coeff 1.0))) (allpass1 (make-all-pass -0.700 0.700 (dly-len 6))) (allpass2 (make-all-pass -0.700 0.700 (dly-len 7))) (allpass3 (make-all-pass -0.700 0.700 (dly-len 8))) (allpass4 (make-all-pass -0.700 0.700 (dly-len 9))) ; 10 for quad (allpass5 (make-all-pass -0.700 0.700 (dly-len 11))) (allpass6 (and chan2 (make-all-pass -0.700 0.700 (dly-len 12)))) (allpass7 (and chan4 (make-all-pass -0.700 0.700 (dly-len 13)))) (allpass8 (and chan4 (make-all-pass -0.700 0.700 (dly-len 14))))) (let ((filts (if (not chan2) (vector allpass5) (if (not chan4) (vector allpass5 allpass6) (vector allpass5 allpass6 allpass7 allpass8)))) (combs (make-comb-bank (vector comb1 comb2 comb3 comb4 comb5 comb6))) (allpasses (make-all-pass-bank (vector allpass1 allpass2 allpass3)))) (do ((i 0 (+ i 1))) ((= i len)) (out-bank filts i (all-pass allpass4 (one-pole low (all-pass-bank allpasses (comb-bank combs (* volume (ina i *reverb*)))))))))))) (definstrument (reson startime dur pitch amp numformants indxfun skewfun pcskew skewat skewdc vibfreq vibpc ranvibfreq ranvibpc degree distance reverb-amount data) ;; data is a list of lists of form '(ampf resonfrq resonamp ampat ampdc dev0 dev1 indxat indxdc) (let ((beg (seconds->samples startime)) (end (seconds->samples (+ startime dur))) (carriers (make-vector numformants)) (modulator (make-oscil pitch)) (ampfs (make-vector numformants)) (indfs (make-vector numformants)) (c-rats (make-vector numformants)) (frqf (make-env (stretch-envelope skewfun 25 (* 100 (/ skewat dur)) 75 (- 100 (* 100 (/ skewdc dur)))) :scaler (hz->radians (* pcskew pitch)) :duration dur)) (totalamp 0.0) (loc (make-locsig degree distance reverb-amount)) (pervib (make-triangle-wave :frequency vibfreq :amplitude (hz->radians (* vibpc pitch)))) (ranvib (make-rand-interp :frequency ranvibfreq :amplitude (hz->radians (* ranvibpc pitch))))) ;; initialize the "formant" generators (do ((i 0 (+ i 1))) ((= i numformants)) (set! totalamp (+ totalamp ((data i) 2)))) (do ((i 0 (+ i 1))) ((= i numformants)) (let* ((frmdat (data i)) (freq (cadr frmdat)) (ampf (car frmdat)) (rfamp (frmdat 2)) (ampat (* 100 (/ (frmdat 3) dur))) (ampdc (- 100 (* 100 (/ (frmdat 4) dur)))) (dev0 (hz->radians (* (frmdat 5) freq))) (dev1 (hz->radians (* (frmdat 6) freq))) (indxat (* 100 (/ (frmdat 7) dur))) (indxdc (- 100 (* 100 (/ (frmdat 8) dur)))) (harm (round (/ freq pitch))) (rsamp (- 1.0 (abs (- harm (/ freq pitch))))) (cfq (* pitch harm))) (if (zero? ampat) (set! ampat 25)) (if (zero? ampdc) (set! ampdc 75)) (if (zero? indxat) (set! indxat 25)) (if (zero? indxdc) (set! indxdc 75)) (set! (indfs i) (make-env (stretch-envelope indxfun 25 indxat 75 indxdc) :duration dur :scaler (- dev1 dev0) :offset dev0)) (set! (ampfs i) (make-env (stretch-envelope ampf 25 ampat 75 ampdc) :duration dur :scaler (* rsamp amp (/ rfamp totalamp)))) (set! (c-rats i) harm) (set! (carriers i) (make-oscil cfq)))) (if (= numformants 2) (let ((e1 (ampfs 0)) (e2 (ampfs 1)) (c1 (carriers 0)) (c2 (carriers 1)) (i1 (indfs 0)) (i2 (indfs 1)) (r1 (c-rats 0)) (r2 (c-rats 1))) (do ((i beg (+ i 1))) ((= i end)) (let* ((vib (+ (env frqf) (triangle-wave pervib) (rand-interp ranvib))) (modsig (oscil modulator vib))) (locsig loc i (+ (* (env e1) (oscil c1 (+ (* vib r1) (* (env i1) modsig)))) (* (env e2) (oscil c2 (+ (* vib r2) (* (env i2) modsig))))))))) (do ((i beg (+ i 1))) ((= i end)) (let* ((outsum 0.0) (vib (+ (env frqf) (triangle-wave pervib) (rand-interp ranvib))) (modsig (oscil modulator vib))) (do ((k 0 (+ k 1))) ((= k numformants)) (set! outsum (+ outsum (* (env (ampfs k)) (oscil (carriers k) (+ (* vib (c-rats k)) (* (env (indfs k)) modsig))))))) (locsig loc i outsum)))))) ;; (with-sound (:statistics #t) (reson 0 1.0 440 .1 2 '(0 0 100 1) '(0 0 100 1) .1 .1 .1 5 .01 5 .01 0 1.0 0.01 '(((0 0 100 1) 1200 .5 .1 .1 0 1.0 .1 .1) ((0 1 100 0) 2400 .5 .1 .1 0 1.0 .1 .1)))) ;;; STK's feedback-fm instrument named CelloN in Sambox-land (definstrument (cellon beg dur pitch0 amp ampfun betafun beta0 beta1 betaat betadc ampat ampdc dis pcrev deg pitch1 glissfun glissat glissdc pvibfreq pvibpc pvibfun pvibat pvibdc rvibfreq rvibpc rvibfun) (let ((st (seconds->samples beg)) (nd (seconds->samples (+ beg dur))) (pit1 (if (zero? pitch1) pitch0 pitch1)) (loc (make-locsig deg dis pcrev)) (carrier (make-oscil pitch0)) (low (make-one-zero .5 -.5)) (fm 0.0) (fmosc (make-oscil pitch0)) (pvib (make-triangle-wave :frequency pvibfreq :amplitude 1.0)) (rvib (make-rand-interp :frequency rvibfreq :amplitude 1.0)) (ampap (if (> ampat 0.0) (* 100 (/ ampat dur)) 25)) (ampdp (if (> ampdc 0.0) (* 100 (- 1.0 (/ ampdc dur))) 75)) (glsap (if (> glissat 0.0) (* 100 (/ glissat dur)) 25)) (glsdp (if (> glissdc 0.0) (* 100 (- 1.0 (/ glissdc dur))) 75)) (betap (if (> betaat 0.0) (* 100 (/ betaat dur)) 25)) (betdp (if (> betadc 0.0) (* 100 (- 1.0 (/ betadc dur))) 75)) (pvbap (if (> pvibat 0.0) (* 100 (/ pvibat dur)) 25)) (pvbdp (if (> pvibdc 0.0) (* 100 (- 1.0 (/ pvibdc dur))) 75))) (let ((pvibenv (make-env (stretch-envelope (or pvibfun '(0 1 100 1)) 25 pvbap 75 pvbdp) :duration dur :scaler (hz->radians (* pvibpc pitch0)))) (rvibenv (make-env (or rvibfun '(0 1 100 1)) :duration dur :scaler (hz->radians (* rvibpc pitch0)))) (glisenv (make-env (stretch-envelope (or glissfun '(0 0 100 0)) 25 glsap 75 glsdp) :duration dur :scaler (hz->radians (- pit1 pitch0)))) (amplenv (make-env (stretch-envelope ampfun 25 ampap 75 ampdp) :scaler amp :duration dur)) (betaenv (make-env (stretch-envelope betafun 25 betap 75 betdp) :duration dur :scaler (- beta1 beta0) :offset beta0))) (if (and (= pitch0 pitch1) (or (zero? pvibfreq) (zero? pvibpc)) (or (zero? rvibfreq) (zero? rvibpc))) (do ((i st (+ i 1))) ((= i nd)) (set! fm (one-zero low (* (env betaenv) (oscil fmosc fm)))) (locsig loc i (* (env amplenv) (oscil carrier fm)))) (do ((i st (+ i 1))) ((= i nd)) (let ((vib (+ (* (env pvibenv) (triangle-wave pvib)) (* (env rvibenv) (rand-interp rvib)) (env glisenv)))) (set! fm (one-zero low (* (env betaenv) (oscil fmosc (+ fm vib))))) (locsig loc i (* (env amplenv) (oscil carrier (+ fm vib)))))))))) (definstrument (jl-reverb (decay 3.0) (volume 1.0)) (let ((allpass1 (make-all-pass -0.700 0.700 2111)) (allpass2 (make-all-pass -0.700 0.700 673)) (allpass3 (make-all-pass -0.700 0.700 223)) (comb1 (make-comb 0.742 9601)) (comb2 (make-comb 0.733 10007)) (comb3 (make-comb 0.715 10799)) (comb4 (make-comb 0.697 11597)) (outdel1 (make-delay (seconds->samples .013))) (outdel2 (make-delay (seconds->samples .011))) (len (floor (+ (* decay *clm-srate*) (length *reverb*))))) (let ((filts (vector outdel1 outdel2)) (combs (make-comb-bank (vector comb1 comb2 comb3 comb4))) (allpasses (make-all-pass-bank (vector allpass1 allpass2 allpass3)))) (do ((i 0 (+ i 1))) ((= i len)) (out-bank filts i (* volume (comb-bank combs (all-pass-bank allpasses (ina i *reverb*))))))))) (definstrument (gran-synth start-time duration audio-freq grain-dur grain-interval amp) (let ((grain-size (ceiling (* (max grain-dur grain-interval) *clm-srate*)))) (let ((beg (seconds->samples start-time)) (end (seconds->samples (+ start-time duration))) (grain-env (make-env '(0 0 25 1 75 1 100 0) :duration grain-dur)) (carrier (make-oscil audio-freq)) (grains (make-wave-train :size grain-size :frequency (/ 1.0 grain-interval)))) (let ((grain (mus-data grains))) (do ((i 0 (+ i 1))) ((= i grain-size)) (set! (grain i) (* (env grain-env) (oscil carrier))))) (do ((i beg (+ i 1))) ((= i end)) (outa i (* amp (wave-train grains))))))) ;;; (with-sound () (gran-synth 0 2 100 .0189 .02 .4)) (definstrument (touch-tone start telephone-number) (let ((touch-tab-1 '(0 697 697 697 770 770 770 852 852 852 941 941 941)) (touch-tab-2 '(0 1209 1336 1477 1209 1336 1477 1209 1336 1477 1209 1336 1477))) (do ((i 0 (+ i 1))) ((= i (length telephone-number))) (let ((k (telephone-number i)) (beg (seconds->samples (+ start (* i .4))))) (let ((end (+ beg (seconds->samples .3))) (i (if (number? k) (if (not (= 0 k)) k 11) (if (eq? k '*) 10 12)))) (let ((frq1 (make-oscil (touch-tab-1 i))) (frq2 (make-oscil (touch-tab-2 i)))) (do ((j beg (+ j 1))) ((= j end)) (outa j (* 0.1 (+ (oscil frq1) (oscil frq2))))))))))) ;;; (with-sound () (touch-tone 0.0 '(7 2 3 4 9 7 1))) ;;; I think the dial tone is 350 + 440 ;;; http://www.hackfaq.org/telephony/telephone-tone-frequencies.shtml (definstrument (spectra start-time duration frequency amplitude (partials '(1 1 2 0.5)) (amp-envelope '(0 0 50 1 100 0)) (vibrato-amplitude 0.005) (vibrato-speed 5.0) (degree 0.0) (distance 1.0) (reverb-amount 0.005)) (let ((beg (seconds->samples start-time)) (end (seconds->samples (+ start-time duration))) (waveform (partials->wave partials)) (freq (hz->radians frequency))) (let ((s (make-table-lookup :frequency frequency :wave waveform)) (amp-env (make-env amp-envelope :scaler amplitude :duration duration)) (per-vib (make-triangle-wave :frequency vibrato-speed :amplitude (* vibrato-amplitude freq))) (loc (make-locsig degree distance reverb-amount)) (ran-vib (make-rand-interp :frequency (+ vibrato-speed 1.0) :amplitude (* vibrato-amplitude freq)))) (do ((i beg (+ i 1))) ((= i end)) (locsig loc i (* (env amp-env) (table-lookup s (+ (triangle-wave per-vib) (rand-interp ran-vib))))))))) #| (with-sound (:play #t) (spectra 0 1 440.0 .1 '(1.0 .4 2.0 .2 3.0 .2 4.0 .1 6.0 .1) '(0.0 0.0 1.0 1.0 5.0 0.9 12.0 0.5 25.0 0.25 100.0 0.0))) |# ;;; interpolate between two waveforms (this could be extended to implement all the various ;;; wavetable-based synthesis techniques). (definstrument (two-tab start-time duration frequency amplitude (partial-1 '(1.0 1.0 2.0 0.5)) (partial-2 '(1.0 0.0 3.0 1.0)) (amp-envelope '(0 0 50 1 100 0)) (interp-func '(0 1 100 0)) (vibrato-amplitude 0.005) (vibrato-speed 5.0) (degree 0.0) (distance 1.0) (reverb-amount 0.005)) (let ((beg (seconds->samples start-time)) (end (seconds->samples (+ start-time duration))) (waveform-1 (partials->wave partial-1)) (waveform-2 (partials->wave partial-2)) (freq (hz->radians frequency))) (let ((s-1 (make-table-lookup :frequency frequency :wave waveform-1)) (s-2 (make-table-lookup :frequency frequency :wave waveform-2)) (amp-env (make-env amp-envelope :scaler amplitude :duration duration)) (interp-env (make-env interp-func :duration duration)) (interp-env-1 (make-env interp-func :duration duration :offset 1.0 :scaler -1.0)) (loc (make-locsig degree distance reverb-amount)) (per-vib (make-triangle-wave :frequency vibrato-speed :amplitude (* vibrato-amplitude freq))) (ran-vib (make-rand-interp :frequency (+ vibrato-speed 1.0) :amplitude (* vibrato-amplitude freq)))) (do ((i beg (+ i 1))) ((= i end)) (let ((vib (+ (triangle-wave per-vib) (rand-interp ran-vib)))) (locsig loc i (* (env amp-env) (+ (* (env interp-env) (table-lookup s-1 vib)) (* (env interp-env-1) (table-lookup s-2 vib)))))))))) (definstrument (lbj-piano begin-time duration frequency amplitude pfreq (degree 45) (reverb-amount 0) (distance 1)) (let ((piano-spectra (list (list 1.97 .0326 2.99 .0086 3.95 .0163 4.97 .0178 5.98 .0177 6.95 .0315 8.02 .0001 8.94 .0076 9.96 .0134 10.99 .0284 11.98 .0229 13.02 .0229 13.89 .0010 15.06 .0090 16.00 .0003 17.08 .0078 18.16 .0064 19.18 .0129 20.21 .0085 21.27 .0225 22.32 .0061 23.41 .0102 24.48 .0005 25.56 .0016 26.64 .0018 27.70 .0113 28.80 .0111 29.91 .0158 31.06 .0093 32.17 .0017 33.32 .0002 34.42 .0018 35.59 .0027 36.74 .0055 37.90 .0037 39.06 .0064 40.25 .0033 41.47 .0014 42.53 .0004 43.89 .0010 45.12 .0039 46.33 .0039 47.64 .0009 48.88 .0016 50.13 .0006 51.37 .0010 52.70 .0002 54.00 .0004 55.30 .0008 56.60 .0025 57.96 .0010 59.30 .0012 60.67 .0011 61.99 .0003 62.86 .0001 64.36 .0005 64.86 .0001 66.26 .0004 67.70 .0006 68.94 .0002 70.10 .0001 70.58 .0002 72.01 .0007 73.53 .0006 75.00 .0002 77.03 .0005 78.00 .0002 79.57 .0006 81.16 .0005 82.70 .0005 84.22 .0003 85.41 .0002 87.46 .0001 90.30 .0001 94.02 .0001 95.26 .0002 109.39 .0003) (list 1.98 .0194 2.99 .0210 3.97 .0276 4.96 .0297 5.96 .0158 6.99 .0207 8.01 .0009 9.00 .0101 10.00 .0297 11.01 .0289 12.02 .0211 13.04 .0127 14.07 .0061 15.08 .0174 16.13 .0009 17.12 .0093 18.16 .0117 19.21 .0122 20.29 .0108 21.30 .0077 22.38 .0132 23.46 .0073 24.14 .0002 25.58 .0026 26.69 .0035 27.77 .0053 28.88 .0024 30.08 .0027 31.13 .0075 32.24 .0027 33.36 .0004 34.42 .0004 35.64 .0019 36.78 .0037 38.10 .0009 39.11 .0027 40.32 .0010 41.51 .0013 42.66 .0019 43.87 .0007 45.13 .0017 46.35 .0019 47.65 .0021 48.89 .0014 50.18 .0023 51.42 .0015 52.73 .0002 54.00 .0005 55.34 .0006 56.60 .0010 57.96 .0016 58.86 .0005 59.30 .0004 60.75 .0005 62.22 .0003 63.55 .0005 64.82 .0003 66.24 .0003 67.63 .0011 69.09 .0007 70.52 .0004 72.00 .0005 73.50 .0008 74.95 .0003 77.13 .0013 78.02 .0002 79.48 .0004 82.59 .0004 84.10 .0003) (list 2.00 .0313 2.99 .0109 4.00 .0215 5.00 .0242 5.98 .0355 7.01 .0132 8.01 .0009 9.01 .0071 10.00 .0258 11.03 .0221 12.02 .0056 13.06 .0196 14.05 .0160 15.11 .0107 16.11 .0003 17.14 .0111 18.21 .0085 19.23 .0010 20.28 .0048 21.31 .0128 22.36 .0051 23.41 .0041 24.05 .0006 25.54 .0019 26.62 .0028 27.72 .0034 28.82 .0062 29.89 .0039 30.98 .0058 32.08 .0011 33.21 .0002 34.37 .0008 35.46 .0018 36.62 .0036 37.77 .0018 38.92 .0042 40.07 .0037 41.23 .0011 42.67 .0003 43.65 .0018 44.68 .0025 45.99 .0044 47.21 .0051 48.40 .0044 49.67 .0005 50.88 .0019 52.15 .0003 53.42 .0008 54.69 .0010 55.98 .0005 57.26 .0013 58.53 .0027 59.83 .0011 61.21 .0027 62.54 .0003 63.78 .0003 65.20 .0001 66.60 .0006 67.98 .0008 69.37 .0019 70.73 .0007 72.14 .0004 73.62 .0002 74.40 .0003 76.52 .0006 77.97 .0002 79.49 .0004 80.77 .0003 81.00 .0001 82.47 .0005 83.97 .0001 87.27 .0002) (list 2.00 .0257 2.99 .0142 3.97 .0202 4.95 .0148 5.95 .0420 6.95 .0037 7.94 .0004 8.94 .0172 9.95 .0191 10.96 .0115 11.97 .0059 12.98 .0140 14.00 .0178 15.03 .0121 16.09 .0002 17.07 .0066 18.08 .0033 19.15 .0022 20.18 .0057 21.22 .0077 22.29 .0037 23.33 .0066 24.97 .0002 25.49 .0019 26.55 .0042 27.61 .0043 28.73 .0038 29.81 .0084 30.91 .0040 32.03 .0025 33.14 .0005 34.26 .0003 35.38 .0019 36.56 .0037 37.68 .0049 38.86 .0036 40.11 .0011 41.28 .0008 42.50 .0004 43.60 .0002 44.74 .0022 45.99 .0050 47.20 .0009 48.40 .0036 49.68 .0004 50.92 .0009 52.17 .0005 53.46 .0007 54.76 .0006 56.06 .0005 57.34 .0011 58.67 .0005 59.95 .0015 61.37 .0008 62.72 .0004 65.42 .0009 66.96 .0003 68.18 .0003 69.78 .0003 71.21 .0004 72.45 .0002 74.22 .0003 75.44 .0001 76.53 .0003 78.31 .0004 79.83 .0003 80.16 .0001 81.33 .0003 82.44 .0001 83.17 .0002 84.81 .0003 85.97 .0003 89.08 .0001 90.70 .0002 92.30 .0002 95.59 .0002 97.22 .0003 98.86 .0001 108.37 .0001 125.54 .0001) (list 1.99 .0650 3.03 .0040 4.03 .0059 5.02 .0090 5.97 .0227 6.98 .0050 8.04 .0020 9.00 .0082 9.96 .0078 11.01 .0056 12.01 .0095 13.02 .0050 14.04 .0093 15.08 .0064 16.14 .0017 17.06 .0020 18.10 .0025 19.14 .0023 20.18 .0015 21.24 .0032 22.29 .0029 23.32 .0014 24.37 .0005 25.43 .0030 26.50 .0022 27.60 .0027 28.64 .0024 29.76 .0035 30.81 .0136 31.96 .0025 33.02 .0003 34.13 .0005 35.25 .0007 36.40 .0014 37.51 .0020 38.64 .0012 39.80 .0019 40.97 .0004 42.09 .0003 43.24 .0003 44.48 .0002 45.65 .0024 46.86 .0005 48.07 .0013 49.27 .0008 50.49 .0006 52.95 .0001 54.23 .0005 55.45 .0004 56.73 .0001 58.03 .0003 59.29 .0002 60.59 .0003 62.04 .0002 65.89 .0002 67.23 .0002 68.61 .0002 69.97 .0004 71.36 .0005 85.42 .0001) (list 1.98 .0256 2.96 .0158 3.95 .0310 4.94 .0411 5.95 .0238 6.94 .0152 7.93 .0011 8.95 .0185 9.92 .0166 10.93 .0306 11.94 .0258 12.96 .0202 13.97 .0403 14.95 .0228 15.93 .0005 17.01 .0072 18.02 .0034 19.06 .0028 20.08 .0124 21.13 .0137 22.16 .0102 23.19 .0058 23.90 .0013 25.30 .0039 26.36 .0039 27.41 .0025 28.47 .0071 29.64 .0031 30.60 .0027 31.71 .0021 32.84 .0003 33.82 .0002 35.07 .0019 36.09 .0054 37.20 .0038 38.33 .0024 39.47 .0055 40.55 .0016 41.77 .0006 42.95 .0002 43.27 .0018 44.03 .0006 45.25 .0019 46.36 .0033 47.50 .0024 48.87 .0012 50.03 .0016 51.09 .0004 53.52 .0017 54.74 .0012 56.17 .0003 57.40 .0011 58.42 .0020 59.70 .0007 61.29 .0008 62.56 .0003 63.48 .0002 64.83 .0002 66.12 .0012 67.46 .0017 68.81 .0003 69.13 .0003 70.53 .0002 71.84 .0001 73.28 .0002 75.52 .0010 76.96 .0005 77.93 .0003 78.32 .0003 79.73 .0003 81.69 .0002 82.52 .0001 84.01 .0001 84.61 .0002 86.88 .0001 88.36 .0002 89.85 .0002 91.35 .0003 92.86 .0002 93.40 .0001 105.28 .0002 106.22 .0002 107.45 .0001 108.70 .0003 122.08 .0002) (list 1.97 .0264 2.97 .0211 3.98 .0234 4.98 .0307 5.96 .0085 6.94 .0140 7.93 .0005 8.96 .0112 9.96 .0209 10.98 .0194 11.98 .0154 12.99 .0274 13.99 .0127 15.01 .0101 15.99 .0002 17.04 .0011 18.08 .0032 19.14 .0028 20.12 .0054 21.20 .0053 22.13 .0028 23.22 .0030 24.32 .0006 25.24 .0004 26.43 .0028 27.53 .0048 28.52 .0039 29.54 .0047 30.73 .0044 31.82 .0007 32.94 .0008 34.04 .0012 35.13 .0018 36.29 .0007 37.35 .0075 38.51 .0045 39.66 .0014 40.90 .0004 41.90 .0002 43.08 .0002 44.24 .0017 45.36 .0013 46.68 .0020 47.79 .0015 48.98 .0010 50.21 .0012 51.34 .0001 53.82 .0003 55.09 .0004 56.23 .0005 57.53 .0004 58.79 .0005 59.30 .0002 60.03 .0002 61.40 .0003 62.84 .0001 66.64 .0001 67.97 .0001 69.33 .0001 70.68 .0001 73.57 .0002 75.76 .0002 76.45 .0001 79.27 .0001 80.44 .0002 81.87 .0002) (list 2.00 .0311 2.99 .0086 3.99 .0266 4.97 .0123 5.98 .0235 6.97 .0161 7.97 .0008 8.96 .0088 9.96 .0621 10.99 .0080 11.99 .0034 12.99 .0300 14.03 .0228 15.04 .0105 16.03 .0004 17.06 .0036 18.09 .0094 18.95 .0009 20.17 .0071 21.21 .0161 22.25 .0106 23.28 .0104 24.33 .0008 25.38 .0030 26.46 .0035 27.50 .0026 28.59 .0028 29.66 .0128 30.75 .0139 31.81 .0038 32.93 .0006 34.04 .0004 35.16 .0005 36.25 .0023 37.35 .0012 38.46 .0021 39.59 .0035 40.71 .0006 41.86 .0007 42.42 .0001 43.46 .0003 44.17 .0032 45.29 .0013 46.57 .0004 47.72 .0011 48.79 .0005 50.11 .0005 51.29 .0003 52.47 .0002 53.68 .0004 55.02 .0005 56.18 .0003 57.41 .0003 58.75 .0007 59.33 .0009 60.00 .0004 61.34 .0001 64.97 .0003 65.20 .0002 66.48 .0002 67.83 .0002 68.90 .0003 70.25 .0003 71.59 .0002 73.68 .0001 75.92 .0001 77.08 .0002 78.45 .0002 81.56 .0002 82.99 .0001 88.39 .0001) (list .97 .0059 1.98 .0212 2.99 .0153 3.99 .0227 4.96 .0215 5.97 .0153 6.98 .0085 7.98 .0007 8.97 .0179 9.98 .0512 10.98 .0322 12.00 .0098 13.02 .0186 14.00 .0099 15.05 .0109 15.88 .0011 17.07 .0076 18.11 .0071 19.12 .0045 20.16 .0038 21.23 .0213 22.27 .0332 23.34 .0082 24.34 .0014 25.42 .0024 26.47 .0012 27.54 .0014 28.60 .0024 29.72 .0026 30.10 .0008 31.91 .0021 32.13 .0011 33.02 .0007 34.09 .0014 35.17 .0007 36.27 .0024 37.39 .0029 38.58 .0014 39.65 .0017 40.95 .0012 41.97 .0004 42.43 .0002 43.49 .0001 44.31 .0012 45.42 .0031 46.62 .0017 47.82 .0013 49.14 .0013 50.18 .0010 51.54 .0003 53.90 .0006 55.06 .0010 56.31 .0003 57.63 .0001 59.02 .0003 60.09 .0004 60.35 .0004 61.62 .0009 63.97 .0001 65.19 .0001 65.54 .0002 66.92 .0002 67.94 .0002 69.17 .0003 69.60 .0004 70.88 .0002 72.24 .0002 76.12 .0001 78.94 .0001 81.75 .0001 82.06 .0001 83.53 .0001 90.29 .0002 91.75 .0001 92.09 .0002 93.28 .0001 97.07 .0001) (list 1.98 .0159 2.98 .1008 3.98 .0365 4.98 .0133 5.97 .0101 6.97 .0115 7.97 .0007 8.99 .0349 10.01 .0342 11.01 .0236 12.00 .0041 13.02 .0114 14.05 .0137 15.06 .0100 16.05 .0007 17.04 .0009 18.12 .0077 19.15 .0023 20.12 .0017 21.24 .0113 22.26 .0126 23.30 .0093 24.36 .0007 25.43 .0007 26.47 .0009 27.55 .0013 28.59 .0025 29.61 .0010 30.77 .0021 31.86 .0023 32.96 .0003 34.03 .0007 35.06 .0005 36.20 .0006 37.34 .0006 38.36 .0009 39.60 .0016 40.69 .0005 41.77 .0002 42.92 .0002 44.02 .0003 45.24 .0006 46.33 .0004 47.50 .0007 48.71 .0007 49.87 .0002 51.27 .0002 53.42 .0003 55.88 .0003 57.10 .0004 58.34 .0002 59.86 .0003 61.13 .0003 67.18 .0001 68.50 .0001 71.17 .0001 83.91 .0001 90.55 .0001) (list .98 .0099 2.00 .0181 2.99 .0353 3.98 .0285 4.97 .0514 5.96 .0402 6.96 .0015 7.98 .0012 8.98 .0175 9.98 .0264 10.98 .0392 11.98 .0236 13.00 .0153 14.04 .0049 15.00 .0089 16.01 .0001 17.03 .0106 18.03 .0028 19.05 .0024 20.08 .0040 21.11 .0103 22.12 .0104 23.20 .0017 24.19 .0008 25.20 .0007 26.24 .0011 27.36 .0009 27.97 .0030 29.40 .0044 30.37 .0019 31.59 .0017 32.65 .0008 33.59 .0005 34.79 .0009 35.75 .0027 36.88 .0035 37.93 .0039 39.00 .0031 40.08 .0025 41.16 .0010 43.25 .0004 44.52 .0012 45.62 .0023 45.85 .0012 47.00 .0006 47.87 .0008 48.99 .0003 50.48 .0003 51.62 .0001 52.43 .0001 53.56 .0002 54.76 .0002 56.04 .0002 56.68 .0006 57.10 .0003 58.28 .0005 59.47 .0003 59.96 .0002 60.67 .0001 63.08 .0002 64.29 .0002 66.72 .0001 67.97 .0001 68.65 .0001 70.43 .0001 79.38 .0001 80.39 .0001 82.39 .0001) (list 1.00 .0765 1.99 .0151 2.99 .0500 3.99 .0197 5.00 .0260 6.00 .0145 6.98 .0128 7.97 .0004 8.98 .0158 9.99 .0265 11.02 .0290 12.02 .0053 13.03 .0242 14.03 .0103 15.06 .0054 16.04 .0006 17.08 .0008 18.10 .0058 19.16 .0011 20.16 .0055 21.18 .0040 22.20 .0019 23.22 .0014 24.05 .0005 25.31 .0019 26.38 .0018 27.44 .0022 28.45 .0024 29.57 .0073 30.58 .0032 31.66 .0071 32.73 .0015 33.85 .0005 34.96 .0003 36.00 .0020 37.11 .0018 38.18 .0055 39.23 .0006 40.33 .0004 41.52 .0003 43.41 .0028 45.05 .0003 45.99 .0002 47.07 .0003 48.52 .0002 49.48 .0003 50.63 .0003 51.81 .0002 54.05 .0002 55.24 .0001 56.62 .0001 57.81 .0004 59.16 .0013 60.23 .0003 66.44 .0001 68.99 .0004 75.49 .0001 87.56 .0004) (list .98 .0629 1.99 .0232 2.98 .0217 4.00 .0396 4.98 .0171 5.97 .0098 6.99 .0167 7.99 .0003 8.98 .0192 9.98 .0266 10.99 .0256 12.01 .0061 13.02 .0135 14.02 .0062 15.05 .0158 16.06 .0018 17.08 .0101 18.09 .0053 19.11 .0074 20.13 .0020 21.17 .0052 22.22 .0077 23.24 .0035 24.00 .0009 25.32 .0016 26.40 .0022 27.43 .0005 28.55 .0026 29.60 .0026 30.65 .0010 31.67 .0019 32.77 .0008 33.81 .0003 34.91 .0003 36.01 .0005 37.11 .0010 38.20 .0014 39.29 .0039 40.43 .0012 41.50 .0006 43.38 .0017 43.75 .0002 44.94 .0005 46.13 .0002 47.11 .0003 48.28 .0005 48.42 .0005 49.44 .0003 50.76 .0004 51.93 .0002 54.15 .0003 55.31 .0005 55.50 .0003 56.98 .0003 57.90 .0004 60.33 .0002 61.39 .0001 61.59 .0001 65.09 .0002 66.34 .0001 68.85 .0001 70.42 .0002 71.72 .0001 73.05 .0003 79.65 .0001 85.28 .0002 93.52 .0001) (list 1.02 .0185 1.99 .0525 2.98 .0613 3.99 .0415 4.98 .0109 5.97 .0248 6.99 .0102 7.98 .0005 8.98 .0124 9.99 .0103 10.99 .0124 12.00 .0016 13.01 .0029 14.03 .0211 15.04 .0128 16.07 .0021 17.09 .0009 18.09 .0043 19.14 .0022 20.13 .0016 21.20 .0045 22.21 .0088 23.26 .0046 24.29 .0013 25.35 .0009 26.39 .0028 27.49 .0009 28.51 .0006 29.58 .0012 30.70 .0010 31.74 .0019 32.75 .0002 33.85 .0001 34.95 .0005 36.02 .0003 37.16 .0009 38.25 .0018 39.35 .0008 40.54 .0004 41.61 .0002 43.40 .0004 43.74 .0003 45.05 .0001 46.11 .0003 47.40 .0002 48.36 .0004 49.55 .0004 50.72 .0002 52.00 .0001 55.58 .0002 57.02 .0001 57.98 .0002 59.13 .0003 61.56 .0001 66.56 .0001 87.65 .0002) (list 1.00 .0473 1.99 .0506 2.99 .0982 3.99 .0654 5.00 .0196 5.99 .0094 6.99 .0118 7.93 .0001 8.99 .0057 10.01 .0285 11.01 .0142 12.03 .0032 13.03 .0056 14.06 .0064 15.06 .0059 16.11 .0005 17.09 .0033 18.14 .0027 19.15 .0014 20.17 .0010 21.21 .0059 22.26 .0043 23.31 .0031 24.31 .0018 25.33 .0009 26.41 .0005 27.47 .0015 28.53 .0015 29.58 .0041 30.65 .0025 31.73 .0011 32.83 .0010 34.98 .0003 36.07 .0009 37.23 .0001 38.26 .0020 39.41 .0014 40.53 .0005 41.40 .0003 42.80 .0002 43.48 .0028 43.93 .0001 45.03 .0003 46.18 .0007 47.41 .0001 48.57 .0002 49.67 .0001 50.83 .0002 54.39 .0001 55.58 .0002 57.97 .0005 58.11 .0002 59.21 .0001 60.42 .0002 61.66 .0001) (list 1.00 .0503 2.00 .0963 2.99 .1304 3.99 .0218 4.98 .0041 5.98 .0292 6.98 .0482 7.99 .0005 8.99 .0280 10.00 .0237 11.00 .0152 12.02 .0036 12.95 .0022 14.06 .0111 15.07 .0196 16.08 .0016 17.11 .0044 18.13 .0073 19.17 .0055 20.19 .0028 21.20 .0012 22.27 .0068 23.30 .0036 24.35 .0012 25.35 .0002 26.46 .0005 27.47 .0005 28.59 .0009 29.65 .0021 30.70 .0020 31.78 .0012 32.89 .0010 35.06 .0005 36.16 .0008 37.27 .0010 38.36 .0010 39.47 .0014 40.58 .0004 41.43 .0007 41.82 .0003 43.48 .0008 44.53 .0001 45.25 .0003 46.43 .0002 47.46 .0002 48.76 .0005 49.95 .0004 50.96 .0002 51.12 .0002 52.33 .0001 54.75 .0001 55.75 .0002 56.90 .0002 58.17 .0002 59.40 .0004 60.62 .0002 65.65 .0001 66.91 .0002 69.91 .0001 71.25 .0002) (list 1.00 .1243 1.98 .1611 3.00 .0698 3.98 .0390 5.00 .0138 5.99 .0154 7.01 .0287 8.01 .0014 9.01 .0049 10.00 .0144 11.01 .0055 12.05 .0052 13.01 .0011 14.05 .0118 15.07 .0154 16.12 .0028 17.14 .0061 18.25 .0007 19.22 .0020 20.24 .0011 21.27 .0029 22.30 .0046 23.34 .0049 24.35 .0004 25.45 .0003 26.47 .0007 27.59 .0008 28.16 .0009 29.12 .0002 29.81 .0006 30.81 .0009 31.95 .0004 33.00 .0011 34.12 .0005 35.18 .0003 36.30 .0008 37.38 .0003 38.55 .0003 39.64 .0006 40.77 .0007 41.52 .0006 41.89 .0006 43.04 .0011 43.60 .0009 44.31 .0002 45.68 .0002 46.56 .0003 47.60 .0001 48.83 .0006 50.01 .0003 51.27 .0003 56.04 .0005 57.21 .0003 58.56 .0004 59.83 .0003 61.05 .0001 62.20 .0001 67.37 .0002 76.53 .0001) (list .99 .0222 1.99 .0678 2.99 .0683 4.00 .0191 5.00 .0119 6.01 .0232 6.98 .0336 7.99 .0082 9.01 .0201 10.01 .0189 11.01 .0041 12.01 .0053 13.05 .0154 14.04 .0159 15.06 .0092 16.11 .0038 17.12 .0014 18.15 .0091 19.16 .0006 20.30 .0012 21.25 .0061 22.28 .0099 23.34 .0028 24.38 .0012 25.43 .0016 26.49 .0048 27.55 .0025 28.62 .0015 29.71 .0032 30.78 .0077 31.88 .0011 32.97 .0007 34.08 .0006 35.16 .0008 36.28 .0004 37.41 .0006 38.54 .0005 39.62 .0002 40.80 .0003 41.93 .0001 43.06 .0002 44.21 .0003 45.38 .0002 46.54 .0007 47.78 .0003 48.95 .0004 50.10 .0003 51.37 .0002 53.79 .0003 56.20 .0001 58.71 .0002 66.47 .0003) (list 1.01 .0241 1.99 .1011 2.98 .0938 3.98 .0081 4.99 .0062 5.99 .0291 6.99 .0676 7.59 .0004 8.98 .0127 9.99 .0112 10.99 .0142 12.00 .0029 13.02 .0071 14.02 .0184 15.03 .0064 16.07 .0010 17.09 .0011 18.11 .0010 19.15 .0060 20.19 .0019 21.24 .0025 22.29 .0013 23.31 .0050 25.41 .0030 26.50 .0018 27.53 .0006 28.63 .0012 29.66 .0013 30.77 .0020 31.84 .0006 34.04 .0001 35.14 .0001 36.32 .0004 37.41 .0007 38.53 .0007 39.67 .0009 40.85 .0003 45.49 .0002 46.65 .0001 47.81 .0004 49.01 .0002 53.91 .0002 55.14 .0002 57.69 .0002) (list 1.00 .0326 2.00 .1066 2.99 .1015 4.00 .0210 4.97 .0170 5.99 .0813 6.98 .0820 7.96 .0011 8.99 .0248 10.03 .0107 11.01 .0126 12.01 .0027 13.01 .0233 14.04 .0151 15.05 .0071 16.04 .0002 17.10 .0061 18.12 .0059 19.15 .0087 20.23 .0005 21.25 .0040 22.30 .0032 23.35 .0004 24.40 .0001 25.45 .0030 26.54 .0022 27.60 .0003 28.70 .0009 29.80 .0029 30.85 .0006 31.97 .0006 34.19 .0004 35.30 .0003 36.43 .0007 37.56 .0005 38.68 .0019 39.88 .0013 41.00 .0003 43.35 .0003 44.51 .0002 45.68 .0006 46.93 .0010 48.11 .0006 49.29 .0003 55.58 .0002) (list .98 .0113 1.99 .0967 3.00 .0719 3.98 .0345 4.98 .0121 6.00 .0621 7.00 .0137 7.98 .0006 9.01 .0314 10.01 .0171 11.02 .0060 12.03 .0024 13.05 .0077 14.07 .0040 15.12 .0032 16.13 .0004 17.15 .0011 18.20 .0028 19.18 .0003 20.26 .0003 21.31 .0025 22.35 .0021 23.39 .0005 25.55 .0002 26.62 .0014 27.70 .0003 28.78 .0005 29.90 .0030 31.01 .0011 32.12 .0005 34.31 .0001 35.50 .0002 36.62 .0002 37.76 .0005 38.85 .0002 40.09 .0004 43.60 .0001 44.73 .0002 46.02 .0002 47.25 .0004 48.44 .0004) (list .99 .0156 1.98 .0846 2.98 .0178 3.98 .0367 4.98 .0448 5.98 .0113 6.99 .0189 8.00 .0011 9.01 .0247 10.02 .0089 11.01 .0184 12.03 .0105 13.00 .0039 14.07 .0116 15.09 .0078 16.13 .0008 17.14 .0064 18.19 .0029 19.22 .0028 20.25 .0017 21.32 .0043 22.37 .0055 23.42 .0034 24.48 .0004 25.54 .0002 26.61 .0017 27.70 .0011 28.80 .0002 29.89 .0019 30.97 .0028 32.09 .0007 34.30 .0002 35.44 .0003 36.55 .0001 37.69 .0004 38.93 .0002 40.05 .0005 41.20 .0005 42.37 .0002 43.54 .0003 44.73 .0001 45.95 .0002 47.16 .0001 48.43 .0005 49.65 .0004 55.90 .0002 59.81 .0004) (list 1.01 .0280 2.00 .0708 2.99 .0182 3.99 .0248 4.98 .0245 5.98 .0279 6.98 .0437 7.99 .0065 8.99 .0299 10.00 .0073 10.99 .0011 12.03 .0122 13.03 .0028 14.08 .0044 15.11 .0097 16.15 .0010 17.17 .0025 18.19 .0017 19.24 .0008 20.28 .0040 21.32 .0024 22.38 .0008 23.46 .0032 24.52 .0010 25.59 .0008 26.68 .0009 27.76 .0012 28.88 .0003 29.95 .0005 31.05 .0017 32.14 .0002 33.29 .0003 37.88 .0002 39.03 .0002 40.19 .0004 41.37 .0003 43.74 .0002 46.20 .0001 48.68 .0001 49.93 .0001 51.19 .0002) (list 1.00 .0225 1.99 .0921 2.98 .0933 3.99 .0365 4.99 .0100 5.98 .0213 6.98 .0049 7.98 .0041 8.98 .0090 9.99 .0068 11.01 .0040 12.03 .0086 13.02 .0015 14.04 .0071 15.09 .0082 16.14 .0011 17.15 .0014 18.18 .0010 19.26 .0013 20.26 .0005 21.33 .0006 22.36 .0011 23.46 .0016 24.52 .0004 25.59 .0002 26.70 .0006 27.78 .0007 28.87 .0002 30.03 .0008 31.14 .0010 32.24 .0006 33.37 .0002 35.67 .0003 37.99 .0004 39.17 .0004 40.35 .0005 41.53 .0001 46.42 .0001) (list 1.00 .0465 1.99 .0976 2.98 .0678 4.00 .0727 4.99 .0305 5.98 .0210 6.98 .0227 8.00 .0085 9.01 .0183 10.02 .0258 11.05 .0003 12.06 .0061 13.05 .0021 14.10 .0089 15.12 .0077 16.16 .0016 17.21 .0061 18.23 .0011 19.29 .0031 20.36 .0031 21.41 .0007 22.48 .0013 23.55 .0020 24.64 .0004 25.74 .0005 26.81 .0006 27.95 .0006 29.03 .0001 30.22 .0010 31.30 .0004 32.48 .0001 33.60 .0002 38.30 .0003) (list 1.00 .0674 1.99 .0841 2.98 .0920 3.99 .0328 4.99 .0368 5.98 .0206 6.99 .0246 8.01 .0048 9.01 .0218 10.03 .0155 11.05 .0048 12.06 .0077 13.00 .0020 14.10 .0083 15.15 .0084 16.18 .0015 17.22 .0039 18.27 .0032 19.34 .0026 20.40 .0012 21.47 .0009 22.54 .0008 23.62 .0016 24.71 .0005 25.82 .0004 26.91 .0002 28.03 .0008 29.17 .0002 30.32 .0028 31.45 .0004 32.61 .0005 33.77 .0001 36.14 .0003 37.32 .0002 38.54 .0005 39.75 .0002 42.23 .0002 48.65 .0001) (list 1.01 .0423 1.99 .0240 2.98 .0517 4.00 .0493 5.00 .0324 6.00 .0094 6.99 .0449 7.99 .0050 9.00 .0197 10.03 .0132 11.03 .0009 12.07 .0017 13.08 .0023 14.12 .0094 15.16 .0071 16.21 .0020 17.25 .0005 18.30 .0027 19.04 .0004 20.43 .0022 21.51 .0002 22.59 .0006 23.72 .0018 24.80 .0002 25.88 .0002 27.03 .0002 28.09 .0006 29.31 .0002 30.46 .0004 31.61 .0007 32.78 .0005 33.95 .0001 36.34 .0002 37.56 .0001 38.80 .0001 40.02 .0001 44.14 .0001) (list 1.00 .0669 1.99 .0909 2.99 .0410 3.98 .0292 4.98 .0259 5.98 .0148 6.98 .0319 7.99 .0076 9.01 .0056 10.02 .0206 11.04 .0032 12.05 .0085 13.08 .0040 14.12 .0037 15.16 .0030 16.20 .0013 17.24 .0021 18.30 .0010 19.36 .0015 20.44 .0013 21.50 .0009 22.60 .0015 23.69 .0014 24.80 .0006 25.87 .0002 27.02 .0006 28.12 .0002 29.28 .0003 30.43 .0002 31.59 .0007 32.79 .0001 35.14 .0001 37.57 .0001 40.03 .0002 41.28 .0004 44.10 .0001) (list .99 .0421 1.99 .1541 2.98 .0596 3.98 .0309 4.98 .0301 5.99 .0103 7.00 .0240 8.01 .0073 9.01 .0222 10.04 .0140 11.05 .0033 12.08 .0045 13.13 .0009 14.13 .0015 15.21 .0026 16.24 .0003 17.30 .0004 18.35 .0010 19.39 .0003 20.50 .0015 21.57 .0003 22.68 .0011 23.80 .0005 24.90 .0008 26.02 .0002 27.16 .0001 28.30 .0006 29.48 .0002 31.81 .0005 33.00 .0003 34.21 .0001 37.89 .0001) (list .99 .0389 2.00 .2095 3.00 .0835 3.99 .0289 5.00 .0578 5.99 .0363 7.01 .0387 8.01 .0056 9.04 .0173 10.05 .0175 11.08 .0053 12.10 .0056 13.15 .0064 14.19 .0036 15.22 .0019 16.29 .0010 17.36 .0017 18.43 .0018 19.51 .0004 20.60 .0011 21.70 .0003 22.82 .0003 23.95 .0001 25.05 .0004 26.17 .0001 28.50 .0003 29.68 .0001 32.07 .0003 33.28 .0004 34.52 .0001) (list 1.00 .1238 1.99 .2270 3.00 .0102 3.99 .0181 4.98 .0415 6.00 .0165 7.01 .0314 8.02 .0148 9.04 .0203 10.05 .0088 11.07 .0062 12.11 .0070 13.14 .0054 14.19 .0028 15.24 .0044 16.30 .0029 17.38 .0009 18.45 .0026 19.56 .0003 20.65 .0025 21.74 .0014 22.87 .0013 23.99 .0007 25.15 .0002 27.46 .0004 28.39 .0006 28.65 .0004 29.85 .0001 31.05 .0002 32.27 .0003 33.52 .0002 34.76 .0003) (list 1.00 .1054 2.00 .2598 2.99 .0369 3.98 .0523 4.99 .0020 5.99 .0051 7.00 .0268 8.01 .0027 9.04 .0029 10.05 .0081 11.08 .0047 12.12 .0051 13.16 .0091 14.19 .0015 15.27 .0030 16.34 .0017 17.42 .0006 18.51 .0003 19.61 .0007 20.72 .0003 21.84 .0001 22.99 .0010 24.13 .0001 28.44 .0001 30.09 .0001) (list .99 .0919 2.00 .0418 2.99 .0498 3.99 .0135 4.99 .0026 6.00 .0155 7.01 .0340 8.02 .0033 9.04 .0218 10.08 .0084 11.11 .0057 12.15 .0051 13.21 .0043 14.25 .0015 15.31 .0023 16.40 .0008 17.48 .0004 18.59 .0016 19.71 .0010 20.84 .0018 21.98 .0002 23.11 .0013 24.26 .0003 26.67 .0002 29.12 .0002 30.37 .0002 31.62 .0003 32.92 .0001) (list .99 .1174 1.99 .1126 2.99 .0370 3.99 .0159 5.01 .0472 6.01 .0091 7.03 .0211 8.05 .0015 9.07 .0098 10.11 .0038 11.15 .0042 12.20 .0018 13.24 .0041 14.32 .0033 15.41 .0052 16.49 .0001 17.61 .0004 18.71 .0004 19.84 .0004 20.99 .0002 22.14 .0006 23.31 .0006 24.50 .0004 25.70 .0002 28.09 .0002 28.66 .0002 32.00 .0001) (list 1.00 .1085 2.00 .1400 2.99 .0173 3.99 .0229 5.00 .0272 6.02 .0077 7.03 .0069 8.04 .0017 9.08 .0045 10.10 .0030 11.15 .0040 12.20 .0007 13.25 .0019 14.32 .0008 15.42 .0024 16.50 .0002 17.59 .0005 18.71 .0003 19.83 .0002 20.98 .0005 23.29 .0008) (list 1.00 .0985 2.00 .1440 2.99 .0364 3.99 .0425 5.00 .0190 6.01 .0089 7.03 .0278 8.04 .0006 9.07 .0083 10.10 .0021 11.14 .0050 12.18 .0005 13.26 .0036 14.33 .0005 15.41 .0026 17.62 .0004 18.75 .0004 19.89 .0003 21.04 .0012 22.21 .0002 23.38 .0004 27.04 .0001) (list .99 .1273 2.00 .1311 2.99 .0120 4.00 .0099 5.00 .0235 6.02 .0068 7.03 .0162 8.06 .0009 9.08 .0083 10.12 .0014 11.17 .0050 12.24 .0010 13.29 .0013 14.39 .0022 15.48 .0011 16.59 .0002 17.70 .0003 18.84 .0010 20.00 .0003 21.17 .0003 23.56 .0004 28.79 .0003) (list 1.00 .1018 2.00 .1486 3.00 .0165 4.00 .0186 5.01 .0194 6.02 .0045 7.04 .0083 8.06 .0012 9.10 .0066 10.15 .0009 11.19 .0008 12.26 .0011 13.34 .0028 14.45 .0006 15.53 .0009 16.66 .0002 17.79 .0006 18.94 .0005 20.11 .0003 21.29 .0005 22.49 .0003 23.73 .0005 26.22 .0001 27.52 .0001 28.88 .0002) (list 1.00 .1889 1.99 .1822 3.00 .0363 4.00 .0047 5.01 .0202 6.03 .0053 7.05 .0114 8.01 .0002 9.13 .0048 10.17 .0010 11.23 .0033 12.30 .0010 13.38 .0006 14.50 .0002 15.62 .0010 20.27 .0001 21.47 .0001) (list 1.00 .0522 1.99 .0763 2.99 .0404 4.00 .0139 5.01 .0185 6.01 .0021 7.06 .0045 8.09 .0002 9.11 .0003 10.17 .0006 11.25 .0004 12.32 .0005 13.40 .0003 14.53 .0003 15.65 .0007 16.80 .0001 17.95 .0002 19.14 .0006 20.34 .0002 21.56 .0003) (list .99 .1821 1.99 .0773 3.00 .0125 4.01 .0065 5.01 .0202 6.03 .0071 7.05 .0090 8.08 .0006 9.13 .0008 10.18 .0013 11.25 .0010 12.33 .0012 13.42 .0006 14.54 .0005 15.65 .0004 17.97 .0002 19.15 .0001) (list 1.00 .1868 2.00 .0951 3.00 .0147 4.01 .0134 5.02 .0184 6.04 .0132 7.06 .0011 8.11 .0008 9.15 .0010 10.22 .0012 11.30 .0011 12.40 .0003 13.11 .0004 13.49 .0002 14.62 .0003 15.77 .0001) (list 1.00 .1933 2.00 .0714 3.00 .0373 4.00 .0108 5.02 .0094 6.02 .0010 7.07 .0022 8.11 .0002 9.16 .0065 10.23 .0015 11.31 .0023 12.40 .0003 13.53 .0014 14.66 .0002 15.81 .0011 18.20 .0002 19.41 .0001) (list .99 .2113 1.99 .0877 3.00 .0492 4.01 .0094 5.02 .0144 6.04 .0103 7.07 .0117 8.12 .0006 9.19 .0019 10.25 .0007 11.35 .0017 12.45 .0010 13.58 .0003 14.74 .0003 15.91 .0003 19.57 .0002) (list .99 .2455 1.99 .0161 3.00 .0215 4.01 .0036 5.03 .0049 6.04 .0012 7.09 .0036 8.14 .0011 9.21 .0009 10.30 .0001 11.40 .0012 12.50 .0001 13.66 .0005 14.84 .0001) (list 1.00 .1132 2.00 .0252 3.00 .0292 4.01 .0136 5.03 .0045 6.06 .0022 7.11 .0101 8.17 .0004 9.23 .0010 10.33 .0012 11.44 .0013 12.58 .0011 13.75 .0002 14.93 .0005 16.14 .0002) (list 1.00 .1655 2.00 .0445 3.00 .0120 4.00 .0038 5.02 .0015 6.07 .0038 7.11 .0003 8.19 .0002 9.25 .0010 10.36 .0011 11.48 .0005 12.63 .0002 13.79 .0003 16.24 .0002) (list .99 .3637 1.99 .0259 3.01 .0038 4.01 .0057 5.03 .0040 6.07 .0067 7.12 .0014 8.19 .0004 9.27 .0003 10.38 .0002 12.67 .0001) (list 1.00 .1193 2.00 .0230 3.00 .0104 4.01 .0084 5.04 .0047 6.08 .0035 7.13 .0041 8.20 .0002 9.29 .0005 10.40 .0005 11.53 .0003 12.70 .0002 13.91 .0002) (list 1.00 .0752 2.00 .0497 3.00 .0074 4.02 .0076 5.05 .0053 6.09 .0043 7.15 .0024 8.22 .0001 9.32 .0006 10.45 .0002 11.58 .0001 12.78 .0001 15.22 .0001) (list 1.00 .2388 2.00 .0629 3.01 .0159 4.04 .0063 5.07 .0051 6.12 .0045 7.19 .0026 8.29 .0015 9.43 .0001 11.75 .0002) (list 1.00 .1919 2.01 .0116 3.01 .0031 4.03 .0090 5.07 .0061 6.13 .0036 7.19 .0013 8.30 .0016 9.13 .0001 10.59 .0002 11.78 .0002) (list 1.00 .1296 2.00 .0135 3.01 .0041 4.04 .0045 5.09 .0028 6.14 .0046 7.23 .0007 8.32 .0007 9.50 .0001) (list 1.00 .0692 2.00 .0209 3.02 .0025 4.05 .0030 5.09 .0047 6.17 .0022 7.25 .0015 8.36 .0015 9.53 .0010 10.69 .0001 13.40 .0001) (list 1.00 .1715 2.00 .0142 3.01 .0024 4.03 .0015 5.07 .0017 6.13 .0018 7.22 .0009 8.33 .0014 9.51 .0007 10.69 .0002) (list 1.00 .1555 2.01 .0148 3.02 .0007 4.06 .0006 5.10 .0005 6.16 .0008 7.26 .0009 8.39 .0008 9.58 .0002) (list 1.00 .1357 2.00 .0116 3.02 .0026 4.04 .0009 5.09 .0004 6.17 .0005 7.27 .0002 8.40 .0001) (list 1.00 .2185 2.01 .0087 3.03 .0018 4.06 .0025 5.11 .0020 6.20 .0012 7.32 .0005 8.46 .0001 9.66 .0003) (list 1.00 .2735 2.00 .0038 3.02 .0008 4.06 .0012 5.12 .0008 6.22 .0011 7.35 .0003 8.50 .0002) (list 1.00 .1441 1.99 .0062 3.01 .0023 4.05 .0011 5.11 .0012 6.20 .0003 7.33 .0004 8.50 .0001) (list 1.00 .0726 2.01 .0293 3.03 .0022 5.14 .0005 6.26 .0011 7.41 .0002 8.63 .0002) (list 1.00 .0516 2.00 .0104 3.02 .0029 5.15 .0002 6.27 .0001) (list 1.00 .0329 2.00 .0033 3.03 .0013 4.10 .0005 5.19 .0004 6.32 .0002) (list 1.00 .0179 1.99 .0012 3.04 .0005 4.10 .0017 5.20 .0005 6.35 .0001) (list 1.00 .0334 2.01 .0033 3.04 .0011 4.13 .0003 5.22 .0003) (list .99 .0161 2.01 .0100 3.04 .0020 4.13 .0003) (list 1.00 .0475 1.99 .0045 3.03 .0035 4.12 .0011) (list 1.00 .0593 2.00 .0014 4.17 .0002) (list 1.00 .0249 2.01 .0016) (list 1.00 .0242 2.00 .0038 4.19 .0002) (list 1.00 .0170 2.02 .0030) (list 1.00 .0381 2.00 .0017 3.09 .0002) (list 1.00 .0141 2.03 .0005 3.11 .0003 4.26 .0001) (list 1.00 .0122 2.03 .0024) (list 1.00 .0107 2.07 .0007 3.12 .0004) (list 1.00 .0250 2.02 .0026 3.15 .0002) (list 1.01 .0092) (list 1.01 .0102 2.09 .0005) (list 1.00 .0080 2.00 .0005 3.19 .0001) (list 1.01 .0298 2.01 .0005))) (*piano-attack-duration* .04) (*piano-release-duration* .2) (*db-drop-per-second* -10.0)) (define (get-piano-partials freq) (let ((pitch (round (* 12 (log (/ freq 32.703) 2))))) (piano-spectra pitch))) (define (make-piano-ampfun dur) (let ((releaseAmp (db->linear (* *db-drop-per-second* dur))) (attackTime (/ (* *piano-attack-duration* 100) dur))) (list 0 0 (/ attackTime 4) 1.0 attackTime 1.0 100 releaseAmp))) ;; This thing sounds pretty good down low, below middle c or so. ;; The high notes sound pretty rotten--they just don't ;; sparkle; I have a feeling that this is due to the low amplitude of the ;; original data, and the lack of mechanical noise. ;; ;; The only thing you can do to alter the sound of a piano note is to set the ;; pfreq parameter. Pfreq is used to look up the partials. By default, it's ;; set to the requested frequency. Setting it to a neighboring freq is useful ;; when you're repeating notes. Note that there's no nyquist detection; ;; a high freq with a low pfreq, will give you fold over (hmmm...maybe ;; I can get those high notes to sparkle after all). (if (not (number? pfreq)) (set! pfreq frequency)) (let ((partials (normalize-partials (get-piano-partials pfreq))) (beg (seconds->samples begin-time)) (newdur (+ duration *piano-attack-duration* *piano-release-duration*))) (let ((end (+ beg (seconds->samples newdur))) (env1dur (- newdur *piano-release-duration*)) (siz (floor (/ (length partials) 2)))) (let ((env1samples (+ beg (seconds->samples env1dur))) (freqs (make-float-vector siz)) (phases (make-float-vector siz 0.0)) (alist (make-float-vector siz)) (locs (make-locsig degree distance reverb-amount)) (ampfun1 (make-piano-ampfun env1dur))) (let ((ampenv1 (make-env ampfun1 :scaler amplitude :duration env1dur :base 10000.0)) (ampenv2 (make-env '(0 1 100 0) :scaler (* amplitude (ampfun1 (- (length ampfun1) 1))) :duration env1dur :base 1.0))) (do ((i 0 (+ i 2)) (j 0 (+ j 1))) ((= i (length partials))) (set! (alist j) (partials (+ i 1))) (set! (freqs j) (hz->radians (* (partials i) frequency)))) (let ((obank (make-oscil-bank freqs phases alist #t))) (do ((i beg (+ i 1))) ((= i env1samples)) (locsig locs i (* (env ampenv1) (oscil-bank obank)))) (do ((i env1samples (+ i 1))) ((= i end)) (locsig locs i (* (env ampenv2) (oscil-bank obank))))))))))) ;;; (with-sound () (lbj-piano 0 3 440.0 .2)) (definstrument (resflt start dur driver ranfreq noiamp noifun cosamp cosfreq1 cosfreq0 cosnum ampcosfun freqcosfun frq1 r1 g1 frq2 r2 g2 frq3 r3 g3 (degree 0.0) (distance 1.0) (reverb-amount 0.005)) ;; driver=0 -- use sum of cosines to drive the filter, ;; driver=1 -- use white noise ;; if noise used, ranfreq=frequency of random number generator, ;; noiamp=amplitude thereof, ;; noifun=amplitude envelope on white noise ;; if ncos (i.e. a band-limited pulse train), ;; cosamp=amplitude of pulse train, ;; cosfreq1=top frequency (given freqcosfun) (i.e. pulse frequency) ;; cosfreq0=bottom frequency, ;; cosnum=number of cosines in the pulse, ;; ampcosfun=amplitude envelope on pulse train ;; freqcosfun=frequency envelope on pulse train ;; There are then 3 resonators, centered at frq1, frq2, frq3, ;; with pole-radius r1, r2, and r3 respectively, and ;; with gains of g1, g2, and g3. (let ((with-noise (= driver 1))) (let ((beg (seconds->samples start)) (end (seconds->samples (+ start dur))) (f1 (make-two-pole :radius r1 :frequency frq1)) (f2 (make-two-pole :radius r2 :frequency frq2)) (f3 (make-two-pole :radius r3 :frequency frq3)) (loc (make-locsig degree distance reverb-amount)) (frqf (and (not with-noise) (make-env freqcosfun :duration dur :scaler (hz->radians (- cosfreq1 cosfreq0))))) (ampf (if with-noise (make-env noifun :scaler noiamp :duration dur) (make-env ampcosfun :scaler cosamp :duration dur))) (rn (and with-noise (make-rand :frequency ranfreq))) (cn (and (not with-noise) (make-ncos cosfreq0 cosnum)))) (set! (mus-xcoeff f1 0) g1) (set! (mus-xcoeff f2 0) g2) (set! (mus-xcoeff f3 0) g3) (if with-noise (do ((i beg (+ i 1))) ((= i end)) (let ((input1 (* (env ampf) (rand rn)))) (locsig loc i (+ (two-pole f1 input1) (two-pole f2 input1) (two-pole f3 input1))))) (do ((i beg (+ i 1))) ((= i end)) (let ((input1 (* (env ampf) (ncos cn (env frqf))))) (locsig loc i (+ (two-pole f1 input1) (two-pole f2 input1) (two-pole f3 input1))))))))) ; (with-sound () (resflt 0 1.0 0 0 0 #f .1 200 230 10 '(0 0 50 1 100 0) '(0 0 100 1) 500 .995 .1 1000 .995 .1 2000 .995 .1)) ; (with-sound () (resflt 0 1.0 1 10000 .01 '(0 0 50 1 100 0) 0 0 0 0 #f #f 500 .995 .1 1000 .995 .1 2000 .995 .1)) (definstrument (scratch start file src-ratio turnaroundlist) (let ((f (make-file->sample file)) (beg (seconds->samples start)) (turntable (apply vector turnaroundlist)) (turn-i 1) (turns (length turnaroundlist))) (let ((cur-sample (seconds->samples (turntable 0))) (turn-sample (seconds->samples (turntable 1)))) (let ((func (lambda (dir) (let ((inval (file->sample f cur-sample))) (set! cur-sample (+ cur-sample dir)) inval))) (turning 0) (last-val 0.0) (last-val2 0.0) (rd (make-src :srate src-ratio)) (forwards (> src-ratio 0.0))) (if (and forwards (< turn-sample cur-sample)) (set! (mus-increment rd) (- src-ratio))) (do ((i beg (+ i 1))) ((>= turn-i turns)) (let ((val (src rd 0.0 func))) (if (= turning 0) (if (and forwards (>= cur-sample turn-sample)) ;; we passed turn point going forwards (set! turning 1) (if (and (not forwards) (<= cur-sample turn-sample)) ;; we passed turn point going backwards (set! turning -1))) ;; wait for an inflection... (if (or (and (<= last-val2 last-val) (>= last-val val)) (and (>= last-val2 last-val) (<= last-val val))) (begin (set! turn-i (+ turn-i 1)) (if (< turn-i turns) (begin (set! turn-sample (seconds->samples (turntable turn-i))) (set! forwards (not forwards)) (set! (mus-increment rd) (- (mus-increment rd))))) (set! turning 0)))) (set! last-val2 last-val) (set! last-val val) (outa i val))))))) ;;; (with-sound () (scratch 0.0 "now.snd" 1.5 '(0.0 .5 .25 1.0))) ;;; spectral modeling (SMS) (definstrument (pins beg dur file amp (transposition 1.0) ; this can be used to transpose the sound (time-scaler 1.0) ; this can make things happen faster (< 1.0)/slower (> 1.0) in the output (fftsize 256) ; should be a power of 2 ;; at 22050 srate, this is ok for sounds above 300Hz or so, below that you need 512 or 1024, ;; at 44100, probably best to double these sizes -- it takes some searching sometimes. (highest-bin 128) ; how high in fft data should we search for peaks (max-peaks 16) ; how many spectral peaks to track at the maximum attack) ; whether to use original attack via time domain splice ;; do the sliding fft shuffle, translate to polar coordinates, find spectral peaks, ;; match with current, do some interesting transformation, resynthesize using oscils ;; All the envelopes are created on the fly. max-peaks is how many of these peaks ;; we are willing to track at any given time. (let ((max-peaks-1 max-peaks) (fftsize-1 fftsize) (highest-bin-1 highest-bin) (start (seconds->samples beg)) (attack-size (or attack 1))) (let* ((hop (floor (/ fftsize-1 4))) (outhop (floor (* time-scaler hop))) (ifreq (/ 1.0 outhop)) (max-oscils (* 2 max-peaks-1))) (let ((end (+ start (seconds->samples dur))) (fil (make-readin file)) (fdr (make-float-vector fftsize-1)) (fdi (make-float-vector fftsize-1)) (window (make-fft-window blackman2-window fftsize-1)) (current-peak-freqs (make-float-vector max-oscils 0.0)) (last-peak-freqs (make-float-vector max-oscils 0.0)) (current-peak-amps (make-float-vector max-oscils 0.0)) (last-peak-amps (make-float-vector max-oscils 0.0)) (peak-amps (make-float-vector max-peaks-1 0.0)) (peak-freqs (make-float-vector max-peaks-1 0.0)) (amps (make-float-vector max-oscils 0.0)) ;run-time generated amplitude and frequency envelopes (rates (make-float-vector max-oscils 0.0)) (freqs (make-float-vector max-oscils 0.0)) (sweeps (make-float-vector max-oscils 0.0)) ;; (lowest-magnitude .001) (ihifreq (hz->radians ifreq)) (fftscale (/ 1.0 (* fftsize-1 .42323))) ;integrate Blackman-Harris window = .42323*window width and shift by fftsize-1 (fft-mag (/ *clm-srate* fftsize-1)) (furthest-away-accepted .1) (filptr 0) (filend 0) (cur-oscils max-oscils) (splice-attack (number? attack)) (ramped-attack (make-float-vector attack-size 0.0))) (let ((obank (make-oscil-bank freqs (make-float-vector max-oscils 0.0) amps))) (set! filend (mus-length fil)) (float-vector-scale! window fftscale) (if splice-attack (let ((cur-end (+ start attack-size))) ;; my experience in translating SMS, and rumor via Greg Sandell leads me to believe that ;; there is in fact no way to model some attacks successfully in this manner, so this block ;; simply splices the original attack on to the rest of the note. "attack" is the number ;; of samples to include bodily. (do ((i start (+ i 1))) ((= i cur-end)) (outa i (* amp (readin fil)))) (set! filptr attack_size) (let ((mult (make-env '(0 1.0 1.0 0.0) :length attack-size))) (do ((k 0 (+ k 1))) ((= k attack-size)) (float-vector-set! ramped-attack k (* (env mult) (readin fil))))) (set! start cur-end))) (if (< start end) (do ((i start (+ i outhop))) ((>= i end)) (if (<= filptr filend) (let ((peaks 0)) ;; get next block of data and apply window to it (set! (mus-location fil) filptr) (do ((k 0 (+ k 1))) ((= k fftsize-1)) (float-vector-set! fdr k (readin fil))) (float-vector-multiply! fdr window) (set! filptr (+ filptr hop)) (fill! fdi 0.0) ;; get the fft (mus-fft fdr fdi fftsize-1 1) ;; change to polar coordinates (ignoring phases) (rectangular->magnitudes fdr fdi) (float-vector-scale! fdr 2.0) (float-vector-subseq current-peak-freqs 0 max-oscils last-peak-freqs) (float-vector-subseq current-peak-amps 0 max-oscils last-peak-amps) (fill! current-peak-amps 0.0) (fill! peak-amps 0.0) (let ((ra (fdr 0)) (la 0.0) (ca 0.0)) ;; search for current peaks following Xavier Serra's recommendations in ;; "A System for Sound Analysis/Transformation/Synthesis ;; Based on a Deterministic Plus Stochastic Decomposition" (do ((k 0 (+ k 1))) ((= k highest-bin-1)) (set! la ca) (set! ca ra) (set! ra (fdr k)) (if (and (> ca .001) ; lowest-magnitude (> ca ra) (> ca la) (not (zero? ra)) (not (zero? la))) ;; found a local maximum above the current threshold (its bin number is k-1) (let ((logla (log la 10.0)) (logca (log ca 10.0)) (logra (log ra 10.0))) (let* ((offset (/ (* .5 (- logla logra)) (+ logla (* -2 logca) logra))) ; isn't logca always 0? (amp (expt 10.0 (- logca (* .25 (- logla logra) offset)))) (freq (* fft-mag (+ k offset -1)))) ;; (if (not (real? amp)) (format *stderr* "~A ~A ~A -> ~A ~A~%" la ca ra offset amp)) (if (= peaks max-peaks-1) ;; gotta either flush this peak, or find current lowest and flush him (let ((minp 0) (minpeak (peak-amps 0))) (do ((j 1 (+ j 1))) ((= j max-peaks-1)) (if (< (peak-amps j) minpeak) (begin (set! minp j) (set! minpeak (peak-amps j))))) (if (> amp minpeak) (begin (set! (peak-freqs minp) freq) (set! (peak-amps minp) amp)))) (begin (set! (peak-freqs peaks) freq) (set! (peak-amps peaks) amp) (set! peaks (+ peaks 1))))))))) ;; now we have the current peaks -- match them to the previous set and do something interesting with the result ;; the end results are reflected in the updated values in the rates and sweeps arrays. ;; search for fits between last and current, set rates/sweeps for those found ;; try to go by largest amp first (do ((k 0 (+ k 1))) ((= k peaks)) (let ((pl (float-vector-peak-and-location peak-amps))) (let ((maxpk (car pl)) (maxp (cadr pl))) ;; now maxp points to next largest unmatched peak (if (> maxpk 0.0) (let ((closestp -1) (closestamp 10.0) (current-freq (peak-freqs maxp))) (let ((icf (/ 1.0 current-freq))) (do ((j 0 (+ j 1))) ((= j max-peaks-1)) (if (> (last-peak-amps j) 0.0) (let ((closeness (* icf (abs (- (last-peak-freqs j) current-freq))))) (if (< closeness closestamp) (begin (set! closestamp closeness) (set! closestp j)))))) (if (< closestamp furthest-away-accepted) (begin ;; peak-amp is transferred to appropriate current-amp and zeroed, (set! (current-peak-amps closestp) (peak-amps maxp)) (set! (peak-amps maxp) 0.0) (set! (current-peak-freqs closestp) current-freq))))))))) (do ((k 0 (+ k 1))) ((= k max-peaks-1)) (if (> (peak-amps k) 0.0) ;; find a place for a new oscil and start it up (let ((new-place -1)) (do ((j 0 (+ j 1))) ((or (not (= new-place -1)) (= j max-oscils))) (if (= (last-peak-amps j) 0.0 (current-peak-amps j)) (set! new-place j))) (set! (current-peak-amps new-place) (peak-amps k)) (set! (peak-amps k) 0.0) (set! (current-peak-freqs new-place) (peak-freqs k)) (set! (last-peak-freqs new-place) (peak-freqs k)) (set! (freqs new-place) (hz->radians (* transposition (peak-freqs k))))))) (set! cur-oscils 0) (do ((k 0 (+ k 1))) ((= k max-oscils)) (set! (rates k) (* amp ifreq (- (current-peak-amps k) (last-peak-amps k)))) (if (or (not (= (current-peak-amps k) 0.0)) (not (= (last-peak-amps k) 0.0))) (set! cur-oscils k)) (set! (sweeps k) (* ihifreq transposition (- (current-peak-freqs k) (last-peak-freqs k))))) (set! cur-oscils (+ cur-oscils 1)) (set! (mus-length obank) cur-oscils) (let ((stop (min end (+ i outhop)))) (do ((k i (+ k 1))) ((= k stop)) ;; run oscils, update envelopes (outa k (oscil-bank obank)) (float-vector-add! amps rates) (float-vector-add! freqs sweeps)))))))))))) ;; (with-sound (:statistics #t) (pins 0 2 "oboe.snd" 1.0 :max-peaks 8)) (definstrument (zc time dur freq amp length1 length2 feedback) (let ((beg (seconds->samples time)) (end (seconds->samples (+ time dur))) (s (make-pulse-train freq amp)) (d0 (make-comb :size length1 :max-size (+ 1 (max length1 length2)) :scaler feedback)) (zenv (make-env '(0 0 1 1) :scaler (- length2 length1) :duration dur))) (do ((i beg (+ i 1))) ((= i end)) (outa i (comb d0 (pulse-train s) (env zenv)))))) ;; (with-sound () (zc 0 3 100 .1 20 100 .95) (zc 3.5 3 100 .1 100 20 .95)) (definstrument (zn time dur freq amp length1 length2 feedforward) ;; notches are spaced at srate/len, feedforward sets depth thereof ;; so sweep of len from 20 to 100 sweeps the notches down from 1000 Hz to ca 200 Hz ;; so we hear our downward glissando beneath the pulses. (let ((beg (seconds->samples time)) (end (seconds->samples (+ time dur))) (s (make-pulse-train freq amp)) (d0 (make-notch :size length1 :max-size (+ 1 (max length1 length2)) :scaler feedforward)) (zenv (make-env '(0 0 1 1) :scaler (- length2 length1) :duration dur))) (do ((i beg (+ i 1))) ((= i end)) (outa i (notch d0 (pulse-train s) (env zenv)))))) ;;(with-sound () (zn 0 1 100 .1 20 100 .995) (zn 1.5 1 100 .1 100 20 .995)) (definstrument (za time dur freq amp length1 length2 feedback feedforward) (let ((beg (seconds->samples time)) (end (seconds->samples (+ time dur))) (s (make-pulse-train freq amp)) (d0 (make-all-pass feedback feedforward :size length1 :max-size (+ 1 (max length1 length2)))) (zenv (make-env '(0 0 1 1) :scaler (- length2 length1) :duration dur))) (do ((i beg (+ i 1))) ((= i end)) (outa i (all-pass d0 (pulse-train s) (env zenv)))))) ;;(with-sound () (za 0 1 100 .1 20 100 .95 .95) (za 1.5 1 100 .1 100 20 .95 .95)) (define* (clm-expsrc beg dur input-file exp-ratio src-ratio amp rev start-in-file) (let ((stf (floor (* (or start-in-file 0) (srate input-file)))) (two-chans (= (channels input-file) 2 (channels *output*))) (revit (and *reverb* rev))) (let ((st (seconds->samples beg)) (exA (make-granulate (make-readin input-file :channel 0 :start stf) :expansion exp-ratio)) (exB (and two-chans (make-granulate (make-readin input-file :channel 1 :start stf) :expansion exp-ratio)))) (let ((srcA (make-src :srate src-ratio :input (lambda (dir) (granulate exA)))) (srcB (and two-chans (make-src :srate src-ratio :input (lambda (dir) (granulate exB))))) (rev-amp (if revit (if two-chans (* rev .5) rev) 0.0)) (nd (seconds->samples (+ beg dur)))) (if revit (let ((valA 0.0) (valB 0.0)) (if two-chans (do ((i st (+ i 1))) ((= i nd)) (set! valA (* amp (src srcA))) (set! valB (* amp (src srcB))) (outa i valA) (outb i valB) (outa i (* rev-amp (+ valA valB)) *reverb*)) (do ((i st (+ i 1))) ((= i nd)) (set! valA (* amp (src srcA))) (outa i valA) (outa i (* rev-amp valA) *reverb*)))) (if two-chans (do ((i st (+ i 1))) ((= i nd)) (outa i (* amp (src srcA))) (outb i (* amp (src srcB)))) (do ((i st (+ i 1))) ((= i nd)) (outa i (* amp (src srcA)))))))))) ;;; (with-sound () (clm-expsrc 0 2.5 "oboe.snd" 2.0 1.0 1.0)) (definstrument (exp-snd file beg dur amp (exp-amt 1.0) (ramp .4) (seglen .15) (sr 1.0) (hop .05) ampenv) ;; granulate with envelopes on the expansion amount, segment envelope shape, ;; segment length, hop length, and input file resampling rate (let ((max-seg-len (if seglen (if (pair? seglen) (max-envelope seglen) seglen) .15)) (initial-seg-len (if seglen (if (pair? seglen) (cadr seglen) seglen) .15)) (rampdata (if (pair? ramp) ramp (list 0 ramp 1 ramp))) (max-out-hop (if hop (if (pair? hop) (max-envelope hop) hop) .05)) (initial-out-hop (if hop (if (pair? hop) (cadr hop) hop) .05)) (min-exp-amt (if exp-amt (if (pair? exp-amt) (min-envelope exp-amt) exp-amt) 1.0)) (initial-exp-amt (if exp-amt (if (pair? exp-amt) (cadr exp-amt) exp-amt) 1.0))) (if (or (<= (min-envelope rampdata) 0.0) (>= (max-envelope rampdata) 0.5)) (format #t "ramp argument to exp-snd must always be between 0.0 and 0.5: ~A" ramp) (let ((st (seconds->samples beg)) (nd (seconds->samples (+ beg dur))) (f0 (make-readin file 0)) (expenv (make-env (if (pair? exp-amt) exp-amt (list 0 exp-amt 1 exp-amt)) :duration dur)) (lenenv (make-env (if (pair? seglen) seglen (list 0 seglen 1 seglen)) :scaler *clm-srate* :duration dur)) (scaler-amp (if (> max-seg-len .15) (/ (* 0.6 .15) max-seg-len) 0.6)) (srenv (make-env (if (pair? sr) sr (list 0 sr 1 sr)) :duration dur)) (rampenv (make-env rampdata :duration dur)) (initial-ramp-time (if ramp (if (pair? ramp) (cadr ramp) ramp) .4)) (max-in-hop (/ max-out-hop min-exp-amt))) (let ((max-len (seconds->samples (+ (max max-out-hop max-in-hop) max-seg-len))) (hopenv (make-env (if (pair? hop) hop (list 0 hop 1 hop)) :duration dur)) (ampe (make-env (or ampenv (list 0 0 .5 1 1 0)) :scaler amp :duration dur))) (let ((exA (make-granulate :expansion initial-exp-amt :input f0 :max-size max-len :ramp initial-ramp-time :hop initial-out-hop :length initial-seg-len :scaler scaler-amp)) (ex-samp 0.0) (next-samp 0.0) (vol 0.0) (valA0 0.0) (valA1 0.0)) (set! vol (env ampe)) (set! valA0 (* vol (granulate exA))) (set! valA1 (* vol (granulate exA))) (do ((i st (+ i 1))) ((= i nd)) (let ((sl (env lenenv))) ;current segment length ;; now we set the granulate generator internal state to reflect all these envelopes (set! vol (env ampe)) (set! (mus-length exA) (round sl)) (set! (mus-ramp exA) (floor (* sl (env rampenv)))) ;current ramp length (0 to .5) (set! (mus-frequency exA) (env hopenv)) ;current hop size (set! (mus-increment exA) (env expenv)) ;current expansion amount (set! next-samp (+ next-samp (env srenv))) ;current resampling increment (if (> next-samp (+ 1 ex-samp)) (let ((samps (floor (- next-samp ex-samp)))) (if (> samps 2) (do ((k 0 (+ k 1))) ((= k (- samps 2))) (granulate exA))) (if (>= samps 2) (set! valA0 (* vol (granulate exA))) (set! valA0 valA1)) (set! valA1 (* vol (granulate exA))) (set! ex-samp (+ ex-samp samps)))) (if (= next-samp ex-samp) (outa i valA0) (outa i (+ valA0 (* (- next-samp ex-samp) (- valA1 valA0))))))))))))) ;;; (with-sound (:statistics #t) (exp-snd "fyow.snd" 0 3 1 '(0 1 1 3) 0.4 .15 '(0 2 1 .5) 0.05)) ;;; (with-sound () (exp-snd "oboe.snd" 0 3 1 '(0 1 1 3) 0.4 .15 '(0 2 1 .5) 0.2)) (defgenerator grn (rampval 0.0) (rampinc 0.0) (loc 0) (segctr 0) (whichseg 0) (ramplen 0) (steadylen 0) (trigger 0) file) (definstrument (expfil start duration hopsecs rampsecs steadysecs file1 file2) (let ((fil1 (make-file->sample file1)) (fil2 (make-file->sample file2)) (hop (seconds->samples hopsecs)) (rampdur (seconds->samples rampsecs)) (steadydur (seconds->samples steadysecs)) (beg (seconds->samples start)) (end (seconds->samples (+ start duration)))) (let ((grn1 (make-grn :rampval 0.0 :rampinc (/ 1.0 rampdur) :loc 0 :segctr 0 :whichseg 0 :ramplen rampdur :steadylen steadydur :trigger 0 :file fil1)) (grn2 (make-grn :rampval 0.0 :rampinc (/ 1.0 rampdur) :loc 0 :segctr 0 :whichseg 0 :ramplen rampdur :steadylen steadydur :trigger 0 :file fil2)) (out1 beg) (out2 (+ hop beg))) (do ((i beg (+ i 1))) ((= i end)) (let ((val 0.0)) (if (= i out1) (begin (set! val (with-let grn1 (let ((inval (ina loc file))) (set! loc (+ loc 1)) (if (= whichseg 0) ;ramp-up (begin (set! inval (* inval rampval)) (set! rampval (+ rampval rampinc)) (set! segctr (+ segctr 1)) (if (= segctr ramplen) (begin (set! segctr 0) (set! whichseg (+ whichseg 1))))) (if (= whichseg 1) ;steady-state (begin (set! segctr (+ segctr 1)) (if (= segctr steadylen) (begin (set! segctr 0) (set! whichseg (+ whichseg 1))))) (begin ;ramp-down (set! inval (* inval rampval)) (set! segctr (+ segctr 1)) (set! rampval (- rampval rampinc)) (if (= segctr ramplen) (begin (set! segctr 0) (set! trigger 1) (set! whichseg 0) (set! rampval 0.0)))))) inval))) (set! out1 (+ out1 1)) (if (= (grn1 'trigger) 1) (begin (set! (grn1 'trigger) 0) (set! out1 (+ out1 hop)))))) (if (= i out2) (begin (set! val (+ val (with-let grn2 (let ((inval (ina loc file))) (set! loc (+ loc 1)) (if (= whichseg 0) ;ramp-up (begin (set! inval (* inval rampval)) (set! rampval (+ rampval rampinc)) (set! segctr (+ segctr 1)) (if (= segctr ramplen) (begin (set! segctr 0) (set! whichseg (+ whichseg 1))))) (if (= whichseg 1) ;steady-state (begin (set! segctr (+ segctr 1)) (if (= segctr steadylen) (begin (set! segctr 0) (set! whichseg (+ whichseg 1))))) (begin ;ramp-down (set! inval (* inval rampval)) (set! segctr (+ segctr 1)) (set! rampval (- rampval rampinc)) (if (= segctr ramplen) (begin (set! segctr 0) (set! trigger 1) (set! whichseg 0) (set! rampval 0.0)))))) inval)))) (set! out2 (+ out2 1)) (if (= (grn2 'trigger) 1) (begin (set! (grn2 'trigger) 0) (set! out2 (+ out2 hop)))))) (outa i val)))))) ;;; (with-sound () (expfil 0 2 .2 .01 .1 "oboe.snd" "fyow.snd")) #| From: Marco Trevisani This should work like a Graphic Equalizer.... Very easy to use. Just some note: "amp" & "amp-env" apply an enveloppe to the final result of the filtering. "dur" as ""standard"" in my instruments, when dur = 0 it will take the length of the sndfile input, otherwise the duration in seconds. "gain-freq-list" is a list of gains and frequencies to filter --in this order gain and frequencies--. There is no limit to the size of the list. Gain can be a number or an envelope. Unfortunatelly in this version they can't alternate, one should chose, all envelopes or all numbers i.e.: case 1 -> '( .1 440.0 .3 1500.0 .2 330.0 ...etc) or case 2 -> '((0 .1 1 .5) 440.0 (0 1 1 .01) 1500 (0 .3 1 .5) 330.0 ...etc) '( .1 440.0 (0 1 1 .01) 1500 ..etc) <<< again, this is not allowed .. "offset-gain" This apply to all the gains if case 1. It adds or subtracts an offset to all the gains in the list. This number can be positive or negative. In case the result is a negative number --let's say offset = -.4 and, like in case 1, the first gain is .1, the result would be -.3 -- the instrument will pass a gain equal to 0. "filt-gain-scale" & "filt-gain-base" will apply to the elements of the envelopes if we are in case 2, gains are envelopes. "stats" if #t --default-- prints the number of seconds processed, if nil doesnt print anything, which will speed up a bit the process. |# (definstrument (graphEq file (beg 0) (dur 0) (or-beg 0) (amp 1) (amp-env '(0 1 .8 1 1 0)) (amp-base 1) (offset-gain 0) (gain-freq-list '(.8 440 .2 660)) (filt-gain-scale 1) (filt-gain-base 1) (a1 .99)) (let ((st (seconds->samples beg)) (durata (if (= 0 dur) (mus-sound-duration file) dur)) (or-start (round (* or-beg (srate file)))) (gain-list (let ((lst ()) (len (length gain-freq-list))) (do ((i (- len 2) (- i 2))) ((< i 0)) (set! lst (cons (gain-freq-list i) lst))) lst)) (freq-list (let ((lst ()) (len (length gain-freq-list))) (do ((i (- len 1) (- i 2))) ((<= i 0)) (set! lst (cons (gain-freq-list i) lst))) lst))) (let ((nd (+ st (seconds->samples durata))) (RdA (make-readin :file file :start or-start)) (half-list (/ (length gain-freq-list) 2)) (ampenv (make-env amp-env :scaler amp :duration durata :base amp-base)) (env-size (and (pair? (car gain-list)) (make-vector (length freq-list)))) (if-list-in-gain (pair? (car gain-list))) (frm-size (make-vector (length freq-list))) (gains (make-float-vector (length freq-list) 1.0))) (do ((k 0 (+ k 1))) ((= k half-list)) (let ((gval (gain-list k)) (fval (freq-list k))) (if (pair? gval) (begin (set! (env-size k) (make-env gval :scaler (* filt-gain-scale (- 1.0 a1)) :duration durata :base filt-gain-base)) (set! (frm-size k) (make-formant fval a1))) (begin (set! (frm-size k) (make-formant fval a1)) (set! (gains k) (if (< (+ offset-gain gval) 0) 0 (+ offset-gain gval))))))) (set! frm-size (make-formant-bank frm-size gains)) (if if-list-in-gain (do ((i st (+ i 1))) ((= i nd)) (do ((k 0 (+ k 1))) ((= k half-list)) (float-vector-set! gains k (env (vector-ref env-size k)))) (outa i (* (env ampenv) (formant-bank frm-size (readin RdA))))) (do ((i st (+ i 1))) ((= i nd)) (outa i (* (env ampenv) (formant-bank frm-size (readin RdA))))))))) (definstrument (anoi infile start dur (fftsize 128) (amp-scaler 1.0) rr) ;; a kind of noise reduction -- on-going average spectrum is squelched to some extent ;; obviously aimed at intermittent signal in background noise ;; this is based on Perry Cook's Scrubber.m (let ((r (or rr (* 2.0 pi))) (freq-inc (floor (/ fftsize 2))) (fdi (make-float-vector fftsize)) (fdr (make-float-vector fftsize))) (let ((spectr (make-vector freq-inc 1.0)) (scales (make-float-vector freq-inc 1.0)) (diffs (make-float-vector freq-inc 0.0)) (win (make-fft-window blackman2-window fftsize)) (k 0) (amp 0.0) (incr (/ (* amp-scaler 4) *clm-srate*)) (beg (seconds->samples start)) (end (seconds->samples (+ start dur))) (file (make-file->sample infile)) (radius (- 1.0 (/ r fftsize))) (bin (/ *clm-srate* fftsize)) (fs (make-vector freq-inc)) (samp 0) (fdrc 0.0)) (do ((ctr 0 (+ ctr 1))) ((= ctr freq-inc)) (set! (fs ctr) (make-formant (* ctr bin) radius))) (set! fs (make-formant-bank fs scales)) (set! (scales 0) 0.0) (do ((i beg (+ i 1))) ((= i end)) (let ((inval (file->sample file samp))) (set! samp (+ samp 1)) (set! (fdr k) inval) (set! k (+ k 1)) (if (< amp amp-scaler) (set! amp (+ amp incr))) (if (>= k fftsize) (begin (set! k 0) (spectrum fdr fdi win 1) (do ((ctr 0 (+ ctr 1))) ((= ctr freq-inc)) (set! fdrc (fdr ctr)) (set! (spectr ctr) (+ (* .9 (spectr ctr)) (* .1 fdrc))) (if (>= (spectr ctr) fdrc) (set! (diffs ctr) (/ (scales ctr) (- fftsize))) (set! (diffs ctr) (/ (- (/ (- fdrc (spectr ctr)) fdrc) (scales ctr)) fftsize)))))) (outa i (* amp (formant-bank fs inval))) (float-vector-add! scales diffs)))))) #| Date: Fri, 25 Sep 1998 09:56:41 +0300 From: Matti Koskinen To: linux-audio-dev@ginette.musique.umontreal.ca Subject: [linux-audio-dev] Announce: alpha version of denoising [...] I wrote a simple denoiser called anoi after it's parent clm-instrument anoi.ins. anoi tries to remove white noise like tape hiss from wav- files. Removing of noise succeeds ok, but depending of the original sound, some distortion can be audible. If someone is interested, http://www.sci.fi/~mjkoskin contains tarred and gzipped file. Now only monophonic wav-files can be denoised, but adding others isn't too difficult. -matti mjkoskin@sci.fi |# ;;; bes-fm -- can also use bes-j0 here as in earlier versions (define bes-fm (let ((documentation "(bes-fm beg dur freq amp ratio index) produces J1(J1) imitating FM")) (lambda (beg dur freq amp ratio index) (let ((car-incr (hz->radians freq))) (let ((st (seconds->samples beg)) (nd (seconds->samples (+ beg dur))) (car-ph 0.0) (mod-ph 0.0) (mod-incr (* ratio car-incr)) (ampenv (make-env '(0 0 25 1 75 1 100 0) :scaler amp :duration dur))) (do ((i st (+ i 1))) ((= i nd)) (outa i (* (env ampenv) (bes-j1 car-ph))) (set! car-ph (+ car-ph car-incr (* index (bes-j1 mod-ph)))) (set! mod-ph (+ mod-ph mod-incr)))))))) ;;; (with-sound (:statistics #t) (bes-fm 0 1 440 10.0 1.0 4.0)) ;;; ssb-fm ;;; this might be better named "quasi-ssb-fm" -- cancellations are not perfect (defgenerator sbfm (am0 #f) (am1 #f) (car0 #f) (car1 #f) (mod0 #f) (mod1 #f) modsig) (define make-ssb-fm (let ((documentation "(make-ssb-fm freq) makes an ssb-fm generator")) (lambda (freq) (make-sbfm :am0 (make-oscil freq 0) :am1 (make-oscil freq (* 0.5 pi)) :car0 (make-oscil 0 0) :car1 (make-oscil 0 (* 0.5 pi)) :mod0 (make-hilbert-transform 40) :mod1 (make-delay 40))))) (define ssb-fm (let ((documentation "(ssb-fm gen modsig) runs an ssb-fm generator")) (lambda (gen modsig) (let-set! gen 'modsig modsig) (with-let gen (+ (* (oscil am0) (oscil car0 (hilbert-transform mod0 modsig))) (* (oscil am1) (oscil car1 (delay mod1 modsig)))))))) ;;; if all we want are asymmetric fm-generated spectra, we can just add 2 fm oscil pairs: (define make-fm2 (let ((documentation "(make-fm2 f1 f2 f3 f4 p1 p2 p3 p4) makes two FM paired oscils")) (lambda (f1 f2 f3 f4 p1 p2 p3 p4) ;; (make-fm2 1000 100 1000 100 0 0 (* 0.5 pi) (* 0.5 pi)) ;; (make-fm2 1000 100 1000 100 0 0 0 (* 0.5 pi)) (list (make-oscil f1 p1) (make-oscil f2 p2) (make-oscil f3 p3) (make-oscil f4 p4))))) (define fm2 (let ((documentation "(fm2 gen index) runs an fm2 generator")) (lambda (gen index) (* .25 (+ (oscil (gen 0) (* index (oscil (gen 1)))) (oscil (gen 2) (* index (oscil (gen 3))))))))) ;;; rms gain balance ;;; This is a translation of the rmsgain code provided by Fabio Furlanete. (defgenerator rmsg (c1 0.0) (c2 0.0) (q 0.0) (r 0.0) (avg 0.0) (avgc 0) sig rmsval) (define make-rmsgain (let ((documentation "(make-rmsgain (hp 10.0)) makes an RMS gain generator")) (lambda* ((hp 10.0)) (let* ((b (- 2.0 (cos (* hp (/ (* 2.0 pi) *clm-srate*))))) (c2 (- b (sqrt (- (* b b) 1.0)))) (c1 (- 1.0 c2))) (make-rmsg :c1 c1 :c2 c2))))) (define rms (let ((documentation "(rms gen sig) runs an RMS gain generator")) (lambda (gen sig) (let-set! gen 'sig sig) (with-let gen (set! q (+ (* c1 sig sig) (* c2 q))) (sqrt q))))) (define gain (let ((documentation "(gain gen sig rmsval) returns the current RMS gain")) (lambda (gen sig rmsval) (let-set! gen 'sig sig) (let-set! gen 'rmsval rmsval) (with-let gen (set! r (+ (* c1 sig sig) (* c2 r))) (let ((this-gain (if (zero? r) rmsval (/ rmsval (sqrt r))))) (set! avg (+ avg this-gain)) (set! avgc (+ avgc 1)) (* sig this-gain)))))) (define balance (let ((documentation "(balance gen signal compare) scales a signal based on a RMS gain")) (lambda (gen signal compare) (gain gen signal (rms gen compare))))) (define gain-avg (let ((documentation "(gain-avg gen) is part of the RMS gain stuff")) (lambda (gen) (/ (gen 'avg) (gen 'avgc))))) (define balance-avg (let ((documentation "(balance-avg gen) is part of the RM gain stuff")) (lambda (gen) (gen 'avg)))) (definstrument (cnvrev file impulse (rev-amt .1)) (let* ((file-len (mus-sound-framples file)) (filter-len (mus-sound-framples impulse)) (filter-chan0 (make-float-vector filter-len)) (filter-chan1 (and (= (mus-channels *output*) 2) (> (mus-sound-chans impulse) 1) (make-float-vector filter-len)))) (file->array impulse 0 0 filter-len filter-chan0) (if filter-chan1 (file->array impulse 1 0 filter-len filter-chan1) (set! filter-chan1 filter-chan0)) (let ((fd (make-readin file)) (fd1 (and (= (mus-channels *output*) 2) (> (mus-sound-chans file) 1) (make-readin file :channel 1)))) (let ((ff0 (make-convolve :input fd :filter filter-chan0)) (ff1 (and (= (mus-channels *output*) 2) (> (mus-sound-chans file) 1) (make-convolve :input fd1 :filter filter-chan1))) (end (+ file-len filter-len))) (if ff1 (do ((i 0 (+ i 1))) ((= i end)) (outa i (* rev-amt (convolve ff0))) (outb i (* rev-amt (convolve ff1)))) (do ((i 0 (+ i 1))) ((= i end)) (outa i (* rev-amt (convolve ff0))))))))) #| (with-sound (:statistics #t :scaled-to .5 :srate 44100 :channels 1) (cnvrev "oboe.snd" "fyow.snd")) |# snd-16.1/snd-sig.c0000644000076400007640000062721612626144463012071 0ustar bilbil#include "snd.h" #include "clm2xen.h" #include "clm-strings.h" /* collect syncd chans */ typedef struct { sync_info *si; snd_fd **sfs; mus_long_t dur; } sync_state; static void free_sync_state(sync_state *sc) { if (sc) { if (sc->si) sc->si = free_sync_info(sc->si); if (sc->sfs) free(sc->sfs); free(sc); } } int to_c_edit_position(chan_info *cp, Xen edpos, const char *caller, int arg_pos) { int pos = AT_CURRENT_EDIT_POSITION; /* need to allow #f here for optargs */ /* also remember that there might be no extension language */ #if (!HAVE_EXTENSION_LANGUAGE) return(cp->edit_ctr); #endif Xen_check_type(!Xen_is_bound(edpos) || Xen_is_integer(edpos) || Xen_is_false(edpos), edpos, arg_pos, caller, "an integer, or " PROC_FALSE); if (Xen_is_integer(edpos)) pos = Xen_integer_to_C_int(edpos); if (pos == AT_CURRENT_EDIT_POSITION) return(cp->edit_ctr); if ((pos < 0) || (pos >= cp->edit_size) || (cp->edits[pos] == NULL)) Xen_error(NO_SUCH_EDIT, Xen_list_8(C_string_to_Xen_string("~A: no such edpos: ~A (from ~A), sound index: ~A (~S), chan: ~A, current edit: ~A"), C_string_to_Xen_string(caller), C_int_to_Xen_integer(pos), edpos, C_int_to_Xen_sound(cp->sound->index), C_string_to_Xen_string(cp->sound->short_filename), C_int_to_Xen_integer(cp->chan), C_int_to_Xen_integer(cp->edit_ctr))); return(pos); } mus_long_t to_c_edit_samples(chan_info *cp, Xen edpos, const char *caller, int arg_pos) { return(cp->edits[to_c_edit_position(cp, edpos, caller, arg_pos)]->samples); } mus_long_t beg_to_sample(Xen beg, const char *caller) { if (Xen_is_integer(beg)) { mus_long_t start; start = Xen_llong_to_C_llong(beg); if (start < 0) Xen_error(NO_SUCH_SAMPLE, Xen_list_3(C_string_to_Xen_string("~A: no such sample: ~A"), C_string_to_Xen_string(caller), beg)); if (start > (1LL << 34)) Xen_out_of_range_error(caller, 1, beg, "too large"); return(start); } return(0); } mus_long_t dur_to_samples(Xen dur, mus_long_t beg, chan_info *cp, int edpos, int argn, const char *caller) { if (Xen_is_integer(dur)) { mus_long_t samps; samps = Xen_llong_to_C_llong(dur); if (samps < 0) Xen_wrong_type_arg_error(caller, argn, dur, "a positive integer"); if (samps > (1LL << 34)) Xen_out_of_range_error(caller, argn, dur, "too large"); return(samps); } return(cp->edits[edpos]->samples - beg); } static mus_long_t end_to_sample(Xen end, chan_info *cp, int edpos, const char *caller) { if (Xen_is_integer(end)) { mus_long_t last; last = Xen_llong_to_C_llong(end); if (last < 0) Xen_error(NO_SUCH_SAMPLE, Xen_list_3(C_string_to_Xen_string("~A: no such sample: ~A"), C_string_to_Xen_string(caller), end)); if (last > (1LL << 34)) Xen_out_of_range_error(caller, 2, end, "too large"); return(last); } return(cp->edits[edpos]->samples - 1); } static sync_state *get_sync_state_1(snd_info *sp, chan_info *cp, mus_long_t beg, bool over_selection, read_direction_t forwards, mus_long_t prebeg, Xen edpos, const char *caller, int arg_pos) { /* can return NULL if over_selection and no current selection */ sync_info *si = NULL; snd_fd **sfs = NULL; chan_info *ncp; int i, pos; mus_long_t dur = 0, pbeg; sync_state *sc; if ((!over_selection) && (sp == NULL)) return(NULL); if ((!over_selection) && (sp->sync != 0)) { si = snd_sync(sp->sync); sfs = (snd_fd **)malloc(si->chans * sizeof(snd_fd *)); for (i = 0; i < si->chans; i++) { ncp = si->cps[i]; si->begs[i] = beg; pos = to_c_edit_position(ncp, edpos, caller, arg_pos); if (forwards == READ_FORWARD) sfs[i] = init_sample_read_any(beg, ncp, READ_FORWARD, pos); else sfs[i] = init_sample_read_any(ncp->edits[pos]->samples - 1, ncp, READ_BACKWARD, pos); } } else { if (over_selection) { if (selection_is_active()) { si = selection_sync(); dur = selection_len(); sfs = (snd_fd **)malloc(si->chans * sizeof(snd_fd *)); for (i = 0; i < si->chans; i++) { ncp = si->cps[i]; pos = to_c_edit_position(ncp, edpos, caller, arg_pos); if (forwards == READ_FORWARD) { pbeg = si->begs[i] - prebeg; if (pbeg < 0) pbeg = 0; sfs[i] = init_sample_read_any(pbeg, ncp, READ_FORWARD, pos); } else sfs[i] = init_sample_read_any(si->begs[i] + dur - 1, ncp, READ_BACKWARD, pos); } } else { snd_warning_without_format("no selection"); return(NULL); } } } if (si == NULL) { snd_fd *sf = NULL; pos = to_c_edit_position(cp, edpos, caller, arg_pos); if (forwards == READ_FORWARD) sf = init_sample_read_any(beg, cp, READ_FORWARD, pos); else sf = init_sample_read_any(cp->edits[pos]->samples - 1, cp, READ_BACKWARD, pos); if (sf) { si = make_simple_sync(cp, beg); sfs = (snd_fd **)malloc(sizeof(snd_fd *)); sfs[0] = sf; } else return(NULL); } sc = (sync_state *)calloc(1, sizeof(sync_state)); sc->dur = dur; sc->sfs = sfs; sc->si = si; return(sc); } static sync_state *get_sync_state(snd_info *sp, chan_info *cp, mus_long_t beg, bool over_selection, read_direction_t forwards, Xen edpos, const char *caller, int arg_pos) { return(get_sync_state_1(sp, cp, beg, over_selection, forwards, 0, edpos, caller, arg_pos)); } static sync_state *get_sync_state_without_snd_fds(snd_info *sp, chan_info *cp, mus_long_t beg, bool over_selection) { sync_info *si = NULL; mus_long_t dur = 0; sync_state *sc; if ((sp->sync != 0) && (!over_selection)) { int i; si = snd_sync(sp->sync); for (i = 0; i < si->chans; i++) si->begs[i] = beg; } else { if (over_selection) { if (selection_is_active()) { si = selection_sync(); dur = selection_len(); } else { snd_warning_without_format("no selection"); return(NULL); } } } if (si == NULL) si = make_simple_sync(cp, beg); sc = (sync_state *)calloc(1, sizeof(sync_state)); sc->dur = dur; sc->si = si; sc->sfs = NULL; return(sc); } static char *convolve_with_or_error(char *filename, mus_float_t amp, chan_info *cp, Xen edpos, int arg_pos) { /* if string returned, needs to be freed */ /* amp == 0.0 means unnormalized, cp == NULL means current selection */ sync_state *sc; sync_info *si; snd_info *sp = NULL; int ip, stop_point = 0, filter_chans; mus_sample_t dataformat; mus_long_t filtersize = 0, dataloc; chan_info *ncp, *ucp; char *origin; if (cp) { sp = cp->sound; ncp = cp; } else { sp = any_selected_sound(); if (!sp) return(NULL); ncp = any_selected_channel(sp); } filter_chans = mus_sound_chans(filename); if (filter_chans <= 0) return(mus_format("convolve: impulse response file %s chans: %d", filename, filter_chans)); filtersize = mus_sound_samples(filename) / filter_chans; if (filtersize <= 0) return(mus_format("convolve: impulse response file %s is empty", filename)); /* if impulse response is stereo, we need to use both its channels */ dataloc = mus_sound_data_location(filename); dataformat = mus_sound_sample_type(filename); sc = get_sync_state_without_snd_fds(sp, ncp, 0, (cp == NULL)); if (sc == NULL) return(NULL); si = sc->si; #if HAVE_FORTH origin = mus_format("\"%s\" %.3f %s", filename, amp, (cp == NULL) ? S_convolve_selection_with : S_convolve_with); #else origin = mus_format("%s" PROC_OPEN "\"%s\"" PROC_SEP "%.3f", to_proc_name((cp == NULL) ? S_convolve_selection_with : S_convolve_with), filename, amp); #endif if (!(ss->stopped_explicitly)) { snd_info *gsp = NULL; int impulse_chan = 0; for (ip = 0; ip < si->chans; ip++) { char *ofile, *saved_chan_file; io_error_t io_err; bool ok = false; mus_long_t filesize; ucp = si->cps[ip]; if (!(is_editable(ucp))) continue; sp = ucp->sound; if (!(sp->active)) continue; if ((ip == 0) || (sp != gsp)) gsp = ucp->sound; /* ofile here = new convolved data */ ofile = snd_tempnam(); saved_chan_file = snd_tempnam(); io_err = save_channel_edits(ucp, saved_chan_file, to_c_edit_position(ucp, edpos, S_convolve_with, arg_pos)); if (io_err != IO_NO_ERROR) { if (ofile) free(ofile); free_sync_state(sc); return(mus_format("convolve: save chan (%s[%d]) in %s hit error: %s\n", sp->short_filename, ucp->chan, saved_chan_file, snd_open_strerror())); } else { int scfd; scfd = mus_file_open_read(saved_chan_file); if (scfd == -1) { if (ofile) free(ofile); free_sync_state(sc); return(mus_format("convolve: open saved chan (%s[%d]) file %s hit error: %s\n", sp->short_filename, ucp->chan, saved_chan_file, snd_open_strerror())); } else { file_info *hdr; int fltfd; hdr = sp->hdr; snd_file_open_descriptors(scfd, saved_chan_file, hdr->sample_type, hdr->data_location, 1, hdr->type); /* ??? */ fltfd = mus_file_open_read(filename); if (fltfd == -1) { if (ofile) free(ofile); free_sync_state(sc); return(mus_format("convolve: open filter file %s hit error: %s\n", filename, snd_open_strerror())); } else { snd_file_open_descriptors(fltfd, filename, dataformat, dataloc, filter_chans, mus_sound_header_type(filename)); if (cp == NULL) filesize = selection_len(); else filesize = to_c_edit_samples(ucp, edpos, S_convolve_with, arg_pos); if (filesize > 0) { int ipow; mus_long_t fftsize; ipow = (int)(ceil(log(filtersize + filesize) / log(2.0))) + 1; fftsize = snd_mus_long_t_pow2(ipow); ok = true; c_convolve(ofile, amp, scfd, mus_sound_data_location(saved_chan_file), fltfd, dataloc, filtersize, fftsize, filter_chans, impulse_chan, filtersize + filesize + 1, gsp); impulse_chan++; if (impulse_chan >= filter_chans) impulse_chan = 0; } if (mus_file_close(fltfd) != 0) { if (ofile) free(ofile); free_sync_state(sc); return(mus_format("convolve: close filter file %s hit error: %s\n", filename, snd_io_strerror())); } } } if (mus_file_close(scfd) != 0) { if (ofile) free(ofile); free_sync_state(sc); return(mus_format("convolve: close saved chan (%s[%d]) file %s hit error: %s\n", sp->short_filename, ucp->chan, saved_chan_file, snd_io_strerror())); } } snd_remove(saved_chan_file, REMOVE_FROM_CACHE); free(saved_chan_file); if (ok) { if (cp == NULL) { delete_samples(si->begs[ip], sc->dur, ucp, ucp->edit_ctr); if ((filtersize + filesize) > 0) { file_insert_samples(si->begs[ip], filtersize + filesize, ofile, ucp, 0, DELETE_ME, origin, ucp->edit_ctr); reactivate_selection(ucp, si->begs[ip], si->begs[ip] + filtersize + filesize); backup_edit_list(ucp); ripple_trailing_marks(ucp, si->begs[ip], sc->dur, filtersize + filesize); } else snd_remove(ofile, REMOVE_FROM_CACHE); update_graph(ucp); } else file_override_samples(filtersize + filesize, ofile, ucp, 0, DELETE_ME, origin); } if (ofile) free(ofile); check_for_event(); if (ss->stopped_explicitly) { stop_point = ip; break; } } } if (origin) { free(origin); origin = NULL; } if (ss->stopped_explicitly) { /* clean up and undo all edits up to stop_point */ ss->stopped_explicitly = false; for (ip = 0; ip <= stop_point; ip++) { ucp = si->cps[ip]; undo_edit(ucp, 1); } } free_sync_state(sc); return(NULL); } /* amplitude scaling */ void scale_by(chan_info *cp, mus_float_t *ur_scalers, int len, bool over_selection) { /* if over_selection, sync to current selection, else sync to current sound */ /* 3-Oct-00: the scale factors are now embedded in the edit fragments */ sync_info *si; int i, j; if (over_selection) si = selection_sync(); else si = sync_to_chan(cp); if (!si) return; for (i = 0, j = 0; i < si->chans; i++) { mus_long_t beg, framples; chan_info *ncp; ncp = si->cps[i]; if (over_selection) { beg = selection_beg(ncp); framples = selection_end(ncp) - beg + 1; } else { beg = 0; framples = current_samples(ncp); } scale_channel(ncp, ur_scalers[j], beg, framples, ncp->edit_ctr, NOT_IN_AS_ONE_EDIT); j++; if (j >= len) j = 0; } free_sync_info(si); } bool scale_to(snd_info *sp, chan_info *cp, mus_float_t *ur_scalers, int len, bool over_selection) { /* essentially the same as scale-by, but first take into account current maxamps */ /* here it matters if more than one arg is given -- if one, get overall maxamp */ /* if more than one, get successive maxamps */ bool scaled = false; int i, chans, nlen, datum_size; sync_info *si = NULL; chan_info *ncp; mus_float_t maxamp = -1.0, val; mus_float_t *scalers; if ((!over_selection) && (cp == NULL)) return(false); if (over_selection) { if (!(selection_is_active())) return(false); si = selection_sync(); sp = si->cps[0]->sound; } else si = sync_to_chan(cp); datum_size = mus_bytes_per_sample((sp->hdr)->sample_type); chans = si->chans; scalers = (mus_float_t *)calloc(chans, sizeof(mus_float_t)); if (chans < len) nlen = chans; else nlen = len; for (i = 0; i < nlen; i++) scalers[i] = ur_scalers[i]; if (chans > len) for (i = len; i < chans; i++) scalers[i] = ur_scalers[len - 1]; /* now find maxamps (special if len==1) and fixup the scalers */ if (len == 1) { if (scalers[0] != 0.0) { for (i = 0; i < chans; i++) { ncp = si->cps[i]; if (over_selection) val = selection_maxamp(ncp); else val = channel_maxamp(ncp, AT_CURRENT_EDIT_POSITION); if (val > maxamp) maxamp = val; } if ((!(clipping(ss))) && (scalers[0] == 1.0) && (datum_size <= 2)) { if (datum_size == 2) scalers[0] = 32767.0 / 32768.0; else scalers[0] = 127.0 / 128.0; } if (maxamp != 0.0) val = scalers[0] / maxamp; else val = 0.0; } else val = 0.0; for (i = 0; i < chans; i++) scalers[i] = val; } else { for (i = 0; i < chans; i++) { ncp = si->cps[i]; if (scalers[i] != 0.0) { if (over_selection) val = selection_maxamp(ncp); else val = channel_maxamp(ncp, AT_CURRENT_EDIT_POSITION); if (val > maxamp) maxamp = val; if (val != 0.0) { if ((!(clipping(ss))) && (scalers[i] == 1.0) && (datum_size <= 2)) { if (datum_size == 2) scalers[0] = 32767.0 / 32768.0; else scalers[0] = 127.0 / 128.0; } scalers[i] /= val; } else scalers[i] = 0.0; } else maxamp = 1.0; /* turn off the maxamp check */ } } if (maxamp != 0.0) { for (i = 0; i < si->chans; i++) { mus_long_t beg, framples; char *origin = NULL; mus_float_t norm = 1.0; ncp = si->cps[i]; if (nlen > i) norm = ur_scalers[i]; else norm = ur_scalers[0]; if (over_selection) { beg = selection_beg(ncp); framples = selection_end(ncp) - beg + 1; #if HAVE_FORTH origin = mus_format("%.3f" PROC_SEP "%lld" PROC_SEP "%lld %s", norm, beg, framples, S_normalize_channel); #else origin = mus_format("%s" PROC_OPEN "%.3f" PROC_SEP "%lld" PROC_SEP "%lld", to_proc_name(S_normalize_channel), norm, beg, framples); #endif } else { beg = 0; framples = current_samples(ncp); #if HAVE_FORTH origin = mus_format("%.3f 0 " PROC_FALSE " %s", norm, S_normalize_channel); #else origin = mus_format("%s" PROC_OPEN "%.3f" PROC_SEP "0" PROC_SEP PROC_FALSE, to_proc_name(S_normalize_channel), norm); #endif } scale_channel_with_origin(ncp, scalers[i], beg, framples, ncp->edit_ctr, NOT_IN_AS_ONE_EDIT, origin); if (origin) free(origin); origin = NULL; } scaled = true; } free(scalers); free_sync_info(si); return(scaled); } static void swap_channels(chan_info *cp0, chan_info *cp1, mus_long_t beg, mus_long_t dur, int pos0, int pos1) { snd_fd *c0, *c1; snd_info *sp0; file_info *hdr0 = NULL, *hdr1 = NULL; int ofd0 = 0, ofd1 = 0, datumb = 0; bool temp_file; mus_long_t alloc_len; mus_float_t **data0, **data1; mus_float_t *idata0, *idata1; bool reporting = false; char *ofile0 = NULL, *ofile1 = NULL; io_error_t io_err = IO_NO_ERROR; if (dur <= 0) return; if ((!(is_editable(cp0))) || (!(is_editable(cp1)))) return; sp0 = cp0->sound; reporting = ((sp0) && (dur > REPORTING_SIZE) && (!(cp0->squelch_update))); if (reporting) start_progress_report(cp0); if (dur > REPORTING_SIZE) { alloc_len = REPORTING_SIZE; temp_file = true; ofile0 = snd_tempnam(); hdr0 = make_temp_header(ofile0, snd_srate(sp0), 1, dur, (char *)S_swap_channels); ofd0 = open_temp_file(ofile0, 1, hdr0, &io_err); if (ofd0 == -1) { free_file_info(hdr0); snd_error("%s " S_swap_channels " temp file %s: %s\n", (io_err != IO_NO_ERROR) ? io_error_name(io_err) : "can't open", ofile0, snd_open_strerror()); return; } datumb = mus_bytes_per_sample(hdr0->sample_type); ofile1 = snd_tempnam(); hdr1 = make_temp_header(ofile1, snd_srate(sp0), 1, dur, (char *)S_swap_channels); ofd1 = open_temp_file(ofile1, 1, hdr1, &io_err); if (ofd1 == -1) { close_temp_file(ofile0, ofd0, hdr0->type, 0); free_file_info(hdr0); free_file_info(hdr1); if (ofile0) free(ofile0); snd_error("%s " S_swap_channels " temp file %s: %s\n", (io_err != IO_NO_ERROR) ? io_error_name(io_err) : "can't open", ofile1, snd_open_strerror()); return; } } else { temp_file = false; alloc_len = dur; } data0 = (mus_float_t **)malloc(sizeof(mus_float_t *)); data0[0] = (mus_float_t *)calloc(alloc_len, sizeof(mus_float_t)); data1 = (mus_float_t **)malloc(sizeof(mus_float_t *)); data1[0] = (mus_float_t *)calloc(alloc_len, sizeof(mus_float_t)); idata0 = data0[0]; idata1 = data1[0]; c0 = init_sample_read_any_with_bufsize(beg, cp0, READ_FORWARD, pos0, alloc_len); c1 = init_sample_read_any_with_bufsize(beg, cp1, READ_FORWARD, pos1, alloc_len); if (temp_file) { mus_long_t k; ss->stopped_explicitly = false; sampler_set_safe(c0, dur); sampler_set_safe(c1, dur); for (k = 0; k < dur; k += alloc_len) { int j, n, err; j = dur - k; if (j > alloc_len) j = alloc_len; for (n = 0; n < j; n++) { idata0[j] = read_sample(c1); idata1[j] = read_sample(c0); } mus_file_write(ofd0, 0, j - 1, 1, data0); err = mus_file_write(ofd1, 0, j - 1, 1, data1); if (err != MUS_NO_ERROR) break; if (reporting) { progress_report(cp0, (mus_float_t)((double)k / (double)dur)); if (ss->stopped_explicitly) break; if ((cp0->active < CHANNEL_HAS_EDIT_LIST) || (cp1->active < CHANNEL_HAS_EDIT_LIST)) { ss->stopped_explicitly = true; break; } } } close_temp_file(ofile0, ofd0, hdr0->type, dur * datumb); close_temp_file(ofile1, ofd1, hdr1->type, dur * datumb); free_file_info(hdr0); free_file_info(hdr1); if (!(ss->stopped_explicitly)) { file_change_samples(beg, dur, ofile0, cp0, 0, DELETE_ME, S_swap_channels, cp0->edit_ctr); file_change_samples(beg, dur, ofile1, cp1, 0, DELETE_ME, S_swap_channels, cp1->edit_ctr); } else { set_status(sp0, "swap interrupted", false); ss->stopped_explicitly = false; } if (ofile0) {free(ofile0); ofile0 = NULL;} if (ofile1) {free(ofile1); ofile1 = NULL;} if (reporting) finish_progress_report(cp0); } else { samples_to_vct_with_reader(dur, idata0, c1); samples_to_vct_with_reader(dur, idata1, c0); change_samples(beg, dur, data0[0], cp0, S_swap_channels, cp0->edit_ctr, -1.0); change_samples(beg, dur, data1[0], cp1, S_swap_channels, cp1->edit_ctr, -1.0); } swap_marks(cp0, cp1); update_graph(cp0); update_graph(cp1); if (ofile0) free(ofile0); if (ofile1) free(ofile1); free(data0[0]); free(data0); free(data1[0]); free(data1); free_snd_fd(c0); free_snd_fd(c1); } /* -------- reverse-channel -------- */ mus_float_t previous_sample_value_unscaled_and_unchecked(snd_fd *sf); mus_float_t previous_sample_value_unscaled(snd_fd *sf); mus_float_t previous_sample_value_unchecked(snd_fd *sf); static char *reverse_channel(chan_info *cp, snd_fd *sf, mus_long_t beg, mus_long_t dur, Xen edp, const char *caller, int arg_pos) { snd_info *sp; peak_env_info *ep = NULL; file_info *hdr = NULL; int ofd = 0, datumb = 0, edpos = 0; bool section = false, temp_file; mus_long_t k, alloc_len; char *origin = NULL; mus_float_t **data; mus_float_t *idata; char *ofile = NULL; io_error_t io_err = IO_NO_ERROR; if ((beg < 0) || (dur <= 0)) return(NULL); if (!(is_editable(cp))) return(NULL); /* if last was reverse and start/end match, we could just copy preceding edlist entry, or undo/redo etc -- * how to tell that this is happening? */ sp = cp->sound; edpos = to_c_edit_position(cp, edp, caller, arg_pos); if (dur > cp->edits[edpos]->samples) dur = cp->edits[edpos]->samples; if (dur > REPORTING_SIZE) { temp_file = true; alloc_len = REPORTING_SIZE; ofile = snd_tempnam(); hdr = make_temp_header(ofile, snd_srate(sp), 1, dur, caller); ofd = open_temp_file(ofile, 1, hdr, &io_err); if (ofd == -1) { char *str; str = mus_format("%s %s temp file %s: %s\n", (io_err != IO_NO_ERROR) ? io_error_name(io_err) : "can't open", caller, ofile, snd_open_strerror()); if (ofile) free(ofile); return(str); } datumb = mus_bytes_per_sample(hdr->sample_type); } else { temp_file = false; alloc_len = dur; } if ((beg == 0) && (dur == cp->edits[edpos]->samples)) ep = peak_env_copy(cp, true, edpos); /* true -> reversed */ else { ep = peak_env_copy(cp, false, edpos); if (ep) { int i, j, sbin, ebin; /* now reverse the selection */ sbin = (int)ceil(beg / ep->samps_per_bin); ebin = (int)floor((beg + dur) / ep->samps_per_bin); if (ebin > ep->peak_env_size) ebin = ep->peak_env_size; for (i = sbin, j = ebin - 1; i < j; i++, j--) { mus_float_t min1, max1; min1 = ep->data_min[i]; max1 = ep->data_max[i]; ep->data_min[i] = ep->data_min[j]; ep->data_max[i] = ep->data_max[j]; ep->data_min[j] = min1; ep->data_max[j] = max1; } if (sbin > 0) pick_one_bin(ep, sbin - 1, ep->samps_per_bin * (sbin - 1), cp, edpos); if (ebin < ep->peak_env_size) pick_one_bin(ep, ebin, ep->samps_per_bin * ebin, cp, edpos); } section = true; /* only for reverse_marks below */ } sampler_set_safe(sf, dur); data = (mus_float_t **)malloc(sizeof(mus_float_t *)); data[0] = (mus_float_t *)malloc(alloc_len * sizeof(mus_float_t)); idata = data[0]; #if HAVE_FORTH if (dur == cp->edits[edpos]->samples) origin = mus_format("%lld" PROC_SEP PROC_FALSE " %s", beg, S_reverse_channel); else origin = mus_format("%lld" PROC_SEP "%lld %s", beg, dur, S_reverse_channel); #else if (dur == cp->edits[edpos]->samples) origin = mus_format("%s" PROC_OPEN "%lld" PROC_SEP PROC_FALSE, to_proc_name(S_reverse_channel), beg); else origin = mus_format("%s" PROC_OPEN "%lld" PROC_SEP "%lld", to_proc_name(S_reverse_channel), beg, dur); #endif if (temp_file) { for (k = 0; k < dur; k += alloc_len) { int err; mus_long_t kp, kdur; kdur = dur - k; if (kdur > alloc_len) kdur = alloc_len; for (kp = 0; kp < kdur; kp++) idata[kp] = read_sample(sf); err = mus_file_write(ofd, 0, kdur - 1, 1, data); if (err != MUS_NO_ERROR) break; } close_temp_file(ofile, ofd, hdr->type, dur * datumb); hdr = free_file_info(hdr); file_change_samples(beg, dur, ofile, cp, 0, DELETE_ME, origin, edpos); if (ofile) { free(ofile); ofile = NULL; } } else { mus_long_t n; if ((sf->runf == previous_sample_value_unscaled_and_unchecked) || ((sf->runf == previous_sample_value_unscaled) && (sf->loc - sf->first >= (dur - 1)))) { for (n = sf->loc, k = 0; k < dur; k++, n--) idata[k] = sf->data[n]; } else { if (sf->runf == previous_sample_value_unchecked) { for (n = sf->loc, k = 0; k < dur; k++, n--) idata[k] = sf->data[n] * sf->fscaler; } else { /* beg is begin time of the edit, not where the reverse read starts */ /* independent of sf, if edpos is 0, and saved_data is available, and beg+dur < saved_data length, just use it. */ mus_float_t **d; if ((sf->runf == previous_sample_value_unscaled) && (edpos == 0) && (beg + dur <= cp->edits[0]->samples) && (d = mus_sound_saved_data(sp->filename))) { mus_long_t d2; mus_float_t *dc; dc = d[cp->chan]; if (dur & 1) d2 = dur - 1; else d2 = dur; for (n = beg + dur, k = 0; k < d2; ) { idata[k++] = dc[n--]; idata[k++] = dc[n--]; } if (k < dur) idata[k] = dc[n]; } else { for (k = 0; k < dur; k++) idata[k] = read_sample(sf); } } } change_samples(beg, dur, idata, cp, origin, edpos, -1.0); } if (ep) cp->edits[cp->edit_ctr]->peak_env = ep; reverse_marks(cp, (section) ? beg : -1, dur); update_graph(cp); free(data[0]); free(data); if (origin) free(origin); return(NULL); } void reverse_sound(chan_info *ncp, bool over_selection, Xen edpos, int arg_pos) { sync_state *sc; sync_info *si; int i, stop_point = 0; snd_fd **sfs; char *caller; snd_info *sp; chan_info *cp; sp = ncp->sound; caller = (char *)((over_selection) ? S_reverse_selection : S_reverse_sound); sc = get_sync_state(sp, ncp, 0, over_selection, READ_BACKWARD, edpos, (const char *)caller, arg_pos); if (sc == NULL) return; si = sc->si; sfs = sc->sfs; if (!(ss->stopped_explicitly)) { for (i = 0; i < si->chans; i++) { char *errmsg = NULL; mus_long_t dur; cp = si->cps[i]; sp = cp->sound; if (over_selection) dur = sc->dur; else dur = to_c_edit_samples(cp, edpos, caller, arg_pos); if (dur == 0) { sfs[i] = free_snd_fd(sfs[i]); continue; } errmsg = reverse_channel(cp, sfs[i], si->begs[i], dur, edpos, caller, arg_pos); sfs[i] = free_snd_fd(sfs[i]); if (errmsg) { snd_error_without_format(errmsg); free(errmsg); break; } if (ss->stopped_explicitly) { stop_point = i; break; } } } if (ss->stopped_explicitly) { set_status(sp, "reverse stopped", false); ss->stopped_explicitly = false; for (i = 0; i <= stop_point; i++) { cp = si->cps[i]; undo_edit(cp, 1); } } free_sync_state(sc); } /* -------- src -------- */ typedef struct { mus_any *gen; snd_fd *sf; mus_long_t sample; int dir; } src_state; static mus_float_t src_input_as_needed(void *arg, int direction) { src_state *sr = (src_state *)arg; snd_fd *sf; sf = sr->sf; sr->sample++; if (direction != sr->dir) { read_sample_change_direction(sf, (direction == 1) ? READ_FORWARD : READ_BACKWARD); sr->dir = direction; } return(read_sample(sf)); } static mus_float_t src_input_as_needed_unchanged(void *arg, int direction) { src_state *sr = (src_state *)arg; sr->sample++; return(read_sample(sr->sf)); } static mus_float_t read_sample_input(void *arg, int direction) { src_state *sr = (src_state *)arg; return(read_sample(sr->sf)); } static src_state *make_src(mus_float_t srate, snd_fd *sf, bool src_change) { src_state *sr; if ((sinc_width(ss) > MUS_MAX_CLM_SINC_WIDTH) || (sinc_width(ss) < 0) || (fabs(srate) > MUS_MAX_CLM_SRC)) return(NULL); sr = (src_state *)calloc(1, sizeof(src_state)); sr->sf = sf; if (srate >= 0.0) sr->dir = 1; else sr->dir = -1; /* if env on src, this will be 0.0 even if env vals are < 0.0 */ if (src_change) sr->gen = mus_make_src(&src_input_as_needed, srate, sinc_width(ss), (void *)sr); else sr->gen = mus_make_src(&src_input_as_needed_unchanged, srate, sinc_width(ss), (void *)sr); mus_set_increment(sr->gen, srate); sr->sample = 0; return(sr); } static src_state *free_src(src_state *sr) { mus_free(sr->gen); free(sr); return(NULL); } static int mus_long_t_compare(const void *a, const void *b) { mus_long_t *m1, *m2; m1 = (mus_long_t *)a; m2 = (mus_long_t *)b; if (*m1 < *m2) return(-1); if (*m1 == *m2) return(0); return(1); } mus_float_t next_sample_value_unscaled_and_unchecked(snd_fd *sf); static char *src_channel_with_error(chan_info *cp, snd_fd *sf, mus_long_t beg, mus_long_t dur, mus_float_t ratio, mus_any *egen, const char *origin, bool over_selection, bool *clm_err) { snd_info *sp = NULL; bool reporting = false; bool full_chan; mus_float_t **data; file_info *hdr = NULL; int j, ofd = 0, datumb = 0, err = 0; mus_long_t *old_marks = NULL, *new_marks = NULL; int cur_marks = 0; mus_long_t k; char *ofile = NULL; mus_float_t *idata; io_error_t io_err = IO_NO_ERROR; src_state *sr; /* fprintf(stderr, "src: %lld %f %s\n", dur, ratio, origin); */ if ((egen == NULL) && (sf->edit_ctr == cp->edit_ctr)) { if (ratio == 1.0) return(NULL); if (ratio == -1.0) return(reverse_channel(cp, sf, beg, dur, C_int_to_Xen_integer(sf->edit_ctr), origin, 0)); } sp = cp->sound; if (!(is_editable(cp))) return(NULL); /* edit hook result perhaps */ sr = make_src(ratio, sf, egen); /* ratio is 0.0 if egen because the envelope is the srate, but it's passed as the "sr-change" arg */ if (sr == NULL) { (*clm_err) = true; return(mus_format("invalid src ratio: %f\n", ratio)); } if ((egen) && (mus_phase(egen) < 0.0)) sr->dir = -1; full_chan = ((beg == 0) && (dur == cp->edits[sf->edit_ctr]->samples)); /* not current_samples here! */ reporting = ((sp) && (dur > REPORTING_SIZE) && (!(cp->squelch_update))); if (reporting) start_progress_report(cp); ofile = snd_tempnam(); hdr = make_temp_header(ofile, snd_srate(sp), 1, dur, (char *)origin); ofd = open_temp_file(ofile, 1, hdr, &io_err); if (ofd == -1) { return(mus_format("%s %s temp file %s: %s\n", (io_err != IO_NO_ERROR) ? io_error_name(io_err) : "can't open", origin, ofile, snd_open_strerror())); } data = (mus_float_t **)malloc(sizeof(mus_float_t *)); datumb = mus_bytes_per_sample(hdr->sample_type); j = 0; ss->stopped_explicitly = false; if (egen == NULL) { if ((ratio == 0.5) && (dur < (1 << 22))) { mus_long_t in_dur, swid2; mus_float_t *in_data; swid2 = 2 * sinc_width(ss); in_dur = dur + 4 + swid2; in_data = (mus_float_t *)calloc(in_dur, sizeof(mus_float_t)); samples_to_vct_with_reader(in_dur - swid2, (mus_float_t *)(in_data + swid2), sf); data[0] = mus_src_05(sr->gen, in_data, dur); k = dur * 2 + 1; j = k; free(in_data); } else { if ((ratio == 2.0) && (dur < (1 << 23))) { /* make and fill input data, make output data, pass mus_src_20 the input data array, new dur, and sr->gen */ mus_long_t in_dur, swid2; mus_float_t *in_data; swid2 = 2 * sinc_width(ss); in_dur = dur + 4 + swid2; in_data = (mus_float_t *)calloc(in_dur, sizeof(mus_float_t)); samples_to_vct_with_reader(in_dur - swid2, (mus_float_t *)(in_data + swid2), sf); data[0] = mus_src_20(sr->gen, in_data, dur); k = dur / 2 + 1; if ((dur & 1) != 0) k++; /* ?? */ j = k; free(in_data); } else { mus_long_t out_dur; data[0] = (mus_float_t *)malloc(MAX_BUFFER_SIZE * sizeof(mus_float_t)); idata = data[0]; out_dur = ceil(dur / fabs(ratio)) + 1; for (k = 0; k < out_dur; k += MAX_BUFFER_SIZE) { mus_long_t kdur; kdur = out_dur - k; if (kdur > MAX_BUFFER_SIZE) kdur = MAX_BUFFER_SIZE; mus_src_to_buffer(sr->gen, &read_sample_input, idata, kdur); err = mus_file_write(ofd, 0, kdur - 1, 1, data); if (err != MUS_NO_ERROR) break; if (reporting) { progress_report(cp, (mus_float_t)((double)(sr->sample) / (double)dur)); if (ss->stopped_explicitly) break; if (!(sp->active)) { ss->stopped_explicitly = true; break; } } } j = 0; k = out_dur; } } } else { mus_long_t next_pass; mus_long_t cur_mark_sample; int cur_mark = 0, cur_new_mark = 0; mus_float_t env_val; data[0] = (mus_float_t *)malloc(MAX_BUFFER_SIZE * sizeof(mus_float_t)); idata = data[0]; cur_mark_sample = -1; env_val = mus_env(egen); /* envelope case -- have to go by sr->sample, not output sample counter, also check marks */ if ((cp->edits[cp->edit_ctr]->marks) && (cp->edits[cp->edit_ctr]->mark_ctr >= 0)) { int m; mark **mps; mps = cp->edits[cp->edit_ctr]->marks; cur_marks = cp->edits[cp->edit_ctr]->mark_ctr + 1; new_marks = (mus_long_t *)malloc(cur_marks * sizeof(mus_long_t)); old_marks = (mus_long_t *)malloc(cur_marks * sizeof(mus_long_t)); for (m = 0; m < cur_marks; m++) { mus_long_t pos; pos = mark_sample(mps[m]); new_marks[m] = -1; if ((env_val >= 0.0) || (pos < beg) || (pos > (beg + dur))) old_marks[m] = pos; else { old_marks[m] = (dur - pos - 1) + beg; /* moving backwards, so flip marks */ cur_new_mark = m; } } if ((env_val < 0.0) && (cur_marks > 1)) qsort((void *)old_marks, cur_marks, sizeof(mus_long_t), mus_long_t_compare); for (m = 0; m < cur_marks; m++) if (old_marks[m] > beg) { cur_mark_sample = old_marks[m]; cur_mark = m; if ((env_val >= 0.0) || (cur_marks <= 1)) cur_new_mark = m; break; } } next_pass = sr->sample; for (k = 0; sr->sample < dur; k++) { idata[j] = ((mus_src(sr->gen, env_val, &src_input_as_needed))); j++; if (j == MAX_BUFFER_SIZE) { err = mus_file_write(ofd, 0, j - 1, 1, data); j = 0; if (err != MUS_NO_ERROR) break; if (reporting) { progress_report(cp, (mus_float_t)((double)(sr->sample) / (double)dur)); if (ss->stopped_explicitly) break; if (!(sp->active)) { ss->stopped_explicitly = true; break; } } } if (next_pass != sr->sample) /* tick env forward dependent on sr->sample */ { mus_long_t jj, idiff; idiff = sr->sample - next_pass; next_pass = sr->sample; if ((new_marks) && (cur_mark_sample != -1) && (next_pass >= (cur_mark_sample - beg))) { /* not '==' because sr->sample can be incremented by more than 1 */ new_marks[cur_new_mark] = k + beg; cur_mark++; if (env_val >= 0.0) cur_new_mark++; else cur_new_mark--; if (cur_mark < cur_marks) cur_mark_sample = old_marks[cur_mark]; else cur_mark_sample = -1; } env_val = mus_env(egen); for (jj = 1; jj < idiff; jj++) env_val = mus_env(egen); } } } if (reporting) finish_progress_report(cp); sr = free_src(sr); if ((!(ss->stopped_explicitly)) && (j > 0)) mus_file_write(ofd, 0, j - 1, 1, data); close_temp_file(ofile, ofd, hdr->type, k * datumb); hdr = free_file_info(hdr); if (!(ss->stopped_explicitly)) { char *new_origin = NULL; /* egen null -> use ratio, else env, if dur=samples #f */ if (egen == NULL) { #if HAVE_FORTH if (dur == cp->edits[sf->edit_ctr]->samples) new_origin = mus_format("%.4f" PROC_SEP "%lld" PROC_SEP PROC_FALSE " %s", ratio, beg, S_src_channel); else new_origin = mus_format("%.4f" PROC_SEP "%lld" PROC_SEP "%lld %s", ratio, beg, dur, S_src_channel); #else if (dur == cp->edits[sf->edit_ctr]->samples) new_origin = mus_format("%s" PROC_OPEN "%.4f" PROC_SEP "%lld" PROC_SEP PROC_FALSE, to_proc_name(S_src_channel), ratio, beg); else new_origin = mus_format("%s" PROC_OPEN "%.4f" PROC_SEP "%lld" PROC_SEP "%lld", to_proc_name(S_src_channel), ratio, beg, dur); #endif } else { mus_float_t base; char *envstr; env *newe; base = mus_increment(egen); newe = make_envelope_with_offset_and_scaler(mus_data(egen), mus_env_breakpoints(egen) * 2, mus_offset(egen), mus_scaler(egen)); envstr = env_to_string(newe); #if HAVE_FORTH if (base == 1.0) { if (dur == cp->edits[sf->edit_ctr]->samples) new_origin = mus_format("%s" PROC_SEP "%lld" PROC_SEP PROC_FALSE " %s", envstr, beg, S_src_channel); else new_origin = mus_format("%s" PROC_SEP "%lld" PROC_SEP "%lld %s", envstr, beg, dur, S_src_channel); } else new_origin = mus_format("%s :base %.4f :end %lld %s %lld" PROC_SEP "%lld %s", envstr, base, dur, S_make_env, beg, dur, S_src_channel); #else if (base == 1.0) { if (dur == cp->edits[sf->edit_ctr]->samples) new_origin = mus_format("%s" PROC_OPEN "%s" PROC_SEP "%lld" PROC_SEP PROC_FALSE, to_proc_name(S_src_channel), envstr, beg); else new_origin = mus_format("%s" PROC_OPEN "%s" PROC_SEP "%lld" PROC_SEP "%lld", to_proc_name(S_src_channel), envstr, beg, dur); } else new_origin = mus_format("%s" PROC_OPEN BPAREN "%s" PROC_OPEN "%s" PROC_SEP ":base" PROC_SEP "%.4f" PROC_SEP ":end" PROC_SEP "%lld)" PROC_SEP "%lld" PROC_SEP "%lld", to_proc_name(S_make_env), to_proc_name(S_src_channel), envstr, base, dur, beg, dur); #endif if (envstr) free(envstr); free_env(newe); } if (!full_chan) { /* here we need delete followed by insert since dur is probably different */ if (k == dur) file_change_samples(beg, dur, ofile, cp, 0, DELETE_ME, new_origin, sf->edit_ctr); else { delete_samples(beg, dur, cp, sf->edit_ctr); file_insert_samples(beg, k, ofile, cp, 0, DELETE_ME, new_origin, cp->edit_ctr); if (over_selection) reactivate_selection(cp, beg, beg + k); /* backwards compatibility */ backup_edit_list(cp); ripple_marks(cp, 0, 0); } update_graph(cp); } else file_override_samples(k, ofile, cp, 0, DELETE_ME, new_origin); if (new_origin) free(new_origin); /* not file_change_samples because that would not necessarily change the current file length */ if (cp->edits[cp->edit_ctr]->marks) { if (egen == NULL) src_marks(cp, ratio, dur, k, beg, full_chan); else { if (new_marks) reset_marks(cp, cur_marks, new_marks, beg + dur, (k - dur), full_chan); } } /* if possible, copy the previous amp env and change the samps_per_bin to reflect ratio */ if ((full_chan) && (egen == NULL) && /* just ratio -- egen is freed by caller */ (!(cp->edits[cp->edit_ctr]->peak_env))) /* can this happen? */ { peak_env_info *ep; ep = cp->edits[sf->edit_ctr]->peak_env; /* previous peak env (sf is freed by caller) */ if (ep) { mus_float_t bratio; int iratio; bratio = ep->samps_per_bin / fabs(ratio); iratio = (int)bratio; if ((bratio - iratio) < .001) { peak_env_info *new_ep; new_ep = copy_peak_env_info(ep, (ratio < 0.0)); /* might return NULL if ep but not ep->completed */ if (new_ep) { new_ep->samps_per_bin = iratio; cp->edits[cp->edit_ctr]->peak_env = new_ep; } } } } update_graph(cp); } else { set_status(sp, "src interrupted", false); /* should we remove the temp file here? */ ss->stopped_explicitly = false; } if (old_marks) free(old_marks); old_marks = NULL; if (new_marks) free(new_marks); new_marks = NULL; free(ofile); ofile = NULL; free(data[0]); free(data); return(NULL); } void src_env_or_num(chan_info *cp, env *e, mus_float_t ratio, bool just_num, const char *origin, bool over_selection, mus_any *gen, Xen edpos, int arg_pos) { snd_info *sp = NULL; sync_state *sc; sync_info *si; snd_fd **sfs; int i; mus_long_t scdur; int stop_point = 0; char *errmsg = NULL; if ((!just_num) && (e == NULL) && (gen == NULL)) return; if ((just_num) && (ratio == 0.0)) return; /* get envelope or src ratio */ sp = cp->sound; /* get current syncd chans */ sc = get_sync_state(sp, cp, 0, over_selection, (ratio < 0.0) ? READ_BACKWARD : READ_FORWARD, /* 0->beg, 0->over_selection (ratio = 0.0 if from enved) */ edpos, origin, arg_pos); if (sc == NULL) return; si = sc->si; sfs = sc->sfs; scdur = sc->dur; if (!(ss->stopped_explicitly)) { for (i = 0; i < si->chans; i++) { mus_long_t dur; mus_any *egen = NULL; bool clm_err = false; cp = si->cps[i]; if (scdur == 0) dur = to_c_edit_samples(cp, edpos, origin, arg_pos); else dur = scdur; if (dur == 0) { sfs[i] = free_snd_fd(sfs[i]); continue; } if (!just_num) { if (e) egen = mus_make_env(e->data, e->pts, 1.0, 0.0, e->base, 0.0, dur - 1, NULL); else egen = gen; if (egen) ratio = 0.0; /* added 14-Mar-01 otherwise the envelope is an offset? */ } errmsg = src_channel_with_error(cp, sfs[i], si->begs[i], dur, ratio, egen, origin, over_selection, &clm_err); if (egen) { if (e) mus_free(egen); else mus_reset(gen); } if (errmsg) break; if (ss->stopped_explicitly) { stop_point = i; break; } } } if (ss->stopped_explicitly) { /* clean up and undo all edits up to stop_point */ ss->stopped_explicitly = false; for (i = 0; i <= stop_point; i++) { cp = si->cps[i]; undo_edit(cp, 1); } } for (i = 0; i < si->chans; i++) free_snd_fd(sfs[i]); free_sync_state(sc); if (errmsg) snd_error_without_format(errmsg); } static mus_float_t input_as_needed(void *arg, int dir) { return(mus_readin((mus_any *)arg)); } void src_file(const char *file, double ratio) { mus_any **rds, **srcs; char *temp_out; const char *comment; int k, chan, chans, width, out_fd, buffer_size; mus_sample_t sample_type; mus_header_t header_type; mus_long_t samp, old_samps, new_samps; mus_float_t old_srate, new_srate; mus_float_t **obufs; old_srate = mus_srate(); new_srate = mus_sound_srate(file); /* need have no connection with previous CLM srate setting */ mus_set_srate(new_srate); chans = mus_sound_chans(file); sample_type = mus_sound_sample_type(file); header_type = mus_sound_header_type(file); comment = mus_sound_comment(file); buffer_size = mus_file_buffer_size(); old_samps = mus_sound_framples(file); new_samps = old_samps / ratio; /* old-srate/new-srate in-coming */ width = sinc_width(ss); if (width < 32) width = 32; temp_out = snd_tempnam(); out_fd = mus_sound_open_output(temp_out, new_srate, chans, sample_type, header_type, comment); srcs = (mus_any **)malloc(chans * sizeof(mus_any *)); rds = (mus_any **)malloc(chans * sizeof(mus_any *)); obufs = (mus_float_t **)malloc(chans * sizeof(mus_float_t *)); for (chan = 0; chan < chans; chan++) { rds[chan] = mus_make_readin(file, chan, 0, 1); srcs[chan] = mus_make_src(NULL, ratio, width, (void *)rds[chan]); obufs[chan] = (mus_float_t *)malloc(buffer_size * sizeof(mus_float_t)); } for (k = 0, samp = 0; samp < new_samps; samp++) { for (chan = 0; chan < chans; chan++) obufs[chan][k] = (mus_src(srcs[chan], 0.0, &input_as_needed)); k++; if (k == buffer_size) { mus_sound_write(out_fd, 0, buffer_size - 1, chans, obufs); k = 0; } } if (k > 0) mus_sound_write(out_fd, 0, k - 1, chans, obufs); mus_sound_close_output(out_fd, new_samps * chans * mus_bytes_per_sample(sample_type)); mus_sound_forget(file); for (chan = 0; chan < chans; chan++) { free(obufs[chan]); mus_free(srcs[chan]); mus_free(rds[chan]); } free(obufs); free(srcs); free(rds); move_file(temp_out, file); free(temp_out); mus_set_srate(old_srate); } /* FIR filtering */ static mus_float_t *get_filter_coeffs(int order, env *e) { /* interpret e as frequency response */ mus_float_t *a = NULL, *fdata; if (!e) return(NULL); /* get the frequency envelope and design the FIR filter */ fdata = sample_linear_env(e, order); if (!fdata) return(NULL); a = (mus_float_t *)calloc(order + 1, sizeof(mus_float_t)); mus_make_fir_coeffs(order, fdata, a); free(fdata); return(a); } void display_frequency_response(env *e, axis_info *ap, graphics_context *gax, int order, bool dBing) { /* not cp->min_dB here -- this is sound panel related which refers to ss->min_dB */ mus_float_t *coeffs = NULL; int height, width, i, pts, x1, y1; mus_float_t samps_per_pixel, invpts, resp, pix; int fsize, j; mus_float_t step, fx; mus_float_t *rl, *im; if (order & 1) order++; height = (ap->y_axis_y1 - ap->y_axis_y0); width = (ap->x_axis_x1 - ap->x_axis_x0); pts = order * 4; if (pts > width) pts = width; if (pts <= 0) pts = 1; invpts = 1.0 / (mus_float_t)pts; samps_per_pixel = (mus_float_t)(ap->x_axis_x1 - ap->x_axis_x0) * invpts; coeffs = get_filter_coeffs(order, e); if (!coeffs) return; fsize = 2 * snd_to_int_pow2((pts > order) ? pts : order); /* *2 for 1/2 frqs */ rl = (mus_float_t *)calloc(fsize, sizeof(mus_float_t)); im = (mus_float_t *)calloc(fsize, sizeof(mus_float_t)); for (i = 0, j = order - 1; i < order / 2; i++, j -= 2) rl[j] = coeffs[i]; /* by 2 from 1 for 1/2 bins */ mus_fft(rl, im, fsize, -1); resp = 2 * rl[0]; if (dBing) y1 = (int)(ap->y_axis_y0 + (min_dB(ss) - in_dB(min_dB(ss), ss->lin_dB, resp)) * height / min_dB(ss)); else y1 = (int)(ap->y_axis_y0 + resp * height); x1 = ap->x_axis_x0; step = (mus_float_t)(fsize - 1) / (4 * (mus_float_t)pts); /* fsize-1 since we got 1 already, *4 due to double size fft */ for (i = 1, pix = x1, fx = step; i < pts; i++, pix += samps_per_pixel, fx += step) { int fxi, x0, y0; x0 = x1; y0 = y1; x1 = (int)(pix); fxi = (int)fx; resp = 2 * (rl[fxi] + (fx - fxi) * (rl[fxi + 1] - rl[fxi])); if (resp < 0.0) resp = -resp; if (dBing) y1 = (int)(ap->y_axis_y0 + (min_dB(ss) - in_dB(min_dB(ss), ss->lin_dB, resp)) * height / min_dB(ss)); else y1 = (int)(ap->y_axis_y0 + resp * height); draw_line(gax, x0, y0, x1, y1); } free(rl); free(im); free(coeffs); } static char *clm_channel(chan_info *cp, mus_any *gen, mus_long_t beg, mus_long_t dur, int edpos, mus_long_t overlap, const char *origin) { /* calls gen over cp[beg for dur] data, replacing. */ snd_info *sp; file_info *hdr = NULL; int j = 0, ofd = 0, datumb = 0; bool temp_file; mus_long_t k, alloc_len; mus_float_t **data; mus_float_t *idata; char *ofile = NULL; snd_fd *sf; mus_float_t (*runf)(mus_any *gen, mus_float_t arg1, mus_float_t arg2); if ((beg < 0) || ((dur + overlap) <= 0)) return(NULL); sp = cp->sound; if (!(is_editable(cp))) return(NULL); sf = init_sample_read_any(beg, cp, READ_FORWARD, edpos); if (sf == NULL) return(mus_format("%s can't read %s[%d] channel data!", S_clm_channel, sp->short_filename, cp->chan)); runf = mus_run_function(gen); if ((dur + overlap) > REPORTING_SIZE) { io_error_t io_err = IO_NO_ERROR; alloc_len = REPORTING_SIZE; temp_file = true; ofile = snd_tempnam(); hdr = make_temp_header(ofile, snd_srate(sp), 1, dur + overlap, S_clm_channel); ofd = open_temp_file(ofile, 1, hdr, &io_err); if (ofd == -1) { free_snd_fd(sf); return(mus_format("%s %s temp file %s: %s\n", (io_err != IO_NO_ERROR) ? io_error_name(io_err) : "can't open", S_clm_channel, ofile, snd_open_strerror())); } datumb = mus_bytes_per_sample(hdr->sample_type); } else { temp_file = false; alloc_len = dur + overlap; } data = (mus_float_t **)malloc(sizeof(mus_float_t *)); data[0] = (mus_float_t *)calloc(alloc_len, sizeof(mus_float_t)); idata = data[0]; if (temp_file) { sampler_set_safe(sf, dur); for (k = 0; k < dur; k += alloc_len) { int n, err; j = dur - k; if (j > alloc_len) j = alloc_len; for (n = 0; n < j; n++) idata[n] = runf(gen, read_sample(sf), 0.0); err = mus_file_write(ofd, 0, j - 1, 1, data); j = 0; if (err != MUS_NO_ERROR) break; } } else { samples_to_vct_with_reader(dur, idata, sf); for (k = 0; k < dur; k++) idata[k] = runf(gen, idata[k], 0.0); j = (int)dur; } if (overlap > 0) { snd_fd *fd; fd = init_sample_read_any_with_bufsize(beg + dur, cp, READ_FORWARD, edpos, overlap); for (k = 0; k < overlap; k++) idata[j++] = runf(gen, 0.0, 0.0) + read_sample(fd); free_snd_fd(fd); dur += overlap; } sf = free_snd_fd(sf); if (temp_file) { if (j > 0) mus_file_write(ofd, 0, j - 1, 1, data); close_temp_file(ofile, ofd, hdr->type, dur * datumb); hdr = free_file_info(hdr); file_change_samples(beg, dur, ofile, cp, 0, DELETE_ME, origin, edpos); if (ofile) { free(ofile); ofile = NULL; } } else { if (dur > 0) change_samples(beg, dur, idata, cp, origin, edpos, -1.0); } update_graph(cp); free(data[0]); free(data); return(NULL); } #define TWO_30 1073741824 #define MAX_SINGLE_FFT_SIZE 1048576 static mus_float_t convolve_next_sample(void *ptr, int dir) { return(read_sample(((snd_fd *)ptr))); } static char *convolution_filter(chan_info *cp, int order, env *e, snd_fd *sf, mus_long_t beg, mus_long_t dur, const char *origin, mus_float_t *precalculated_coeffs) { snd_info *sp; file_info *hdr = NULL; int ofd = 0, datumb = 0; char *ofile = NULL; int fsize; mus_float_t *fltdat = NULL; io_error_t io_err = IO_NO_ERROR; if (!(is_editable(cp))) return(NULL); sp = cp->sound; dur += order; if (dur < TWO_30) fsize = snd_to_int_pow2(dur); else fsize = TWO_30; ofile = snd_tempnam(); hdr = make_temp_header(ofile, snd_srate(sp), 1, dur, (char *)origin); #if MUS_LITTLE_ENDIAN if (sizeof(mus_float_t) == 4) hdr->sample_type = MUS_LFLOAT; else hdr->sample_type = MUS_LDOUBLE; #else if (sizeof(mus_float_t) == 4) hdr->sample_type = MUS_BFLOAT; else hdr->sample_type = MUS_BDOUBLE; #endif ofd = open_temp_file(ofile, 1, hdr, &io_err); if (ofd == -1) { return(mus_format("%s %s temp file %s: %s\n", (io_err != IO_NO_ERROR) ? io_error_name(io_err) : "can't open", origin, ofile, snd_open_strerror())); } if (fsize > MAX_SINGLE_FFT_SIZE) { /* set up convolution generator and run overlap-add in order-sized blocks */ bool reporting; mus_any *gen; mus_float_t **data; mus_float_t *idata; mus_long_t alloc_len; int j; reporting = ((sp) && (dur > REPORTING_SIZE) && (!(cp->squelch_update))); if (order == 0) order = 65536; /* presumably fsize is enormous here, so no MIN needed */ if (!(is_power_of_2(order))) order = snd_to_int_pow2(order); fsize = 2 * order; /* need room for convolution */ if (precalculated_coeffs) fltdat = precalculated_coeffs; else fltdat = get_filter_coeffs(order, e); gen = mus_make_convolve(convolve_next_sample, fltdat, fsize, order, (void *)sf); if (dur > MAX_BUFFER_SIZE) alloc_len = MAX_BUFFER_SIZE; else alloc_len = dur; data = (mus_float_t **)malloc(sizeof(mus_float_t *)); data[0] = (mus_float_t *)malloc(alloc_len * sizeof(mus_float_t)); idata = data[0]; if (reporting) start_progress_report(cp); ss->stopped_explicitly = false; if (alloc_len == dur) { for (j = 0; j < dur; j++) idata[j] = mus_convolve(gen, NULL); mus_file_write(ofd, 0, dur - 1, 1, data); } else { mus_long_t offk; for (offk = 0; offk < dur; offk += alloc_len) { mus_long_t kdur; kdur = dur - offk; if (kdur > alloc_len) kdur = alloc_len; for (j = 0; j < kdur; j++) idata[j] = mus_convolve(gen, NULL); mus_file_write(ofd, 0, kdur - 1, 1, data); if (reporting) { progress_report(cp, (mus_float_t)((double)offk / (double)dur)); if (ss->stopped_explicitly) break; if (!(sp->active)) { ss->stopped_explicitly = true; break; } } } } if (reporting) finish_progress_report(cp); close_temp_file(ofile, ofd, hdr->type, dur * datumb); if (!(ss->stopped_explicitly)) file_change_samples(beg, dur, ofile, cp, 0, DELETE_ME, origin, sf->edit_ctr); else { set_status(sp, "filter interrupted", false); ss->stopped_explicitly = false; } mus_free(gen); free(data[0]); free(data); } else { /* we think there's enough memory to do the entire thing in one pass */ if (precalculated_coeffs) fltdat = precalculated_coeffs; else fltdat = sample_linear_env(e, fsize); if (fltdat) { mus_float_t *sndrdat, *sndidat; mus_float_t scale; mus_long_t k; ssize_t bytes; sndrdat = (mus_float_t *)calloc(fsize, sizeof(mus_float_t)); sndidat = (mus_float_t *)calloc(fsize, sizeof(mus_float_t)); samples_to_vct_with_reader(dur, sndrdat, sf); mus_fft(sndrdat, sndidat, fsize, 1); scale = 1.0 / (mus_float_t)fsize; for (k = 0; k < fsize; k++) { double scl; scl = scale * fltdat[k]; sndrdat[k] *= scl; /* fltdat is already reflected around midpoint */ sndidat[k] *= scl; } mus_fft(sndrdat, sndidat, fsize, -1); bytes = write(ofd, sndrdat, fsize * sizeof(mus_float_t)); close_temp_file(ofile, ofd, hdr->type, fsize * sizeof(mus_float_t)); if (bytes != 0) file_change_samples(beg, dur + order, ofile, cp, 0, DELETE_ME, origin, sf->edit_ctr); else set_status(sp, "can't write data?", false); free(sndrdat); free(sndidat); } else { close_temp_file(ofile, ofd, hdr->type, 0); snd_remove(ofile, REMOVE_FROM_CACHE); } } if (ofile) {free(ofile); ofile = NULL;} hdr = free_file_info(hdr); if ((fltdat) && (!precalculated_coeffs)) free(fltdat); update_graph(cp); return(NULL); } static char *direct_filter(chan_info *cp, int order, env *e, snd_fd *sf, mus_long_t beg, mus_long_t dur, const char *origin, bool truncate, bool over_selection, mus_any *gen, mus_float_t *precalculated_coeffs) { mus_float_t *fcoeffs = NULL; snd_info *sp; bool reporting = false; mus_long_t offk; file_info *hdr = NULL; int j = 0, ofd = 0, datumb = 0, err = 0; bool temp_file; char *new_origin = NULL; mus_float_t **data; mus_float_t *idata; char *ofile = NULL; io_error_t io_err = IO_NO_ERROR; mus_any *g = NULL; mus_float_t (*runf)(mus_any *gen, mus_float_t arg1, mus_float_t arg2); if (!(is_editable(cp))) return(NULL); sp = cp->sound; if ((!over_selection) || (!truncate)) dur += order; /* if over-selection this causes it to clobber samples beyond the selection end -- maybe mix? */ reporting = ((sp) && (dur > REPORTING_SIZE) && (!(cp->squelch_update))); if (reporting) start_progress_report(cp); if (!gen) { if (precalculated_coeffs) fcoeffs = precalculated_coeffs; else { if (order & 1) order++; fcoeffs = get_filter_coeffs(order, e); if (!fcoeffs) return(NULL); } } if (dur > MAX_BUFFER_SIZE) { temp_file = true; ofile = snd_tempnam(); hdr = make_temp_header(ofile, snd_srate(sp), 1, dur, (char *)origin); ofd = open_temp_file(ofile, 1, hdr, &io_err); if (ofd == -1) { return(mus_format("%s %s temp file %s: %s\n", (io_err != IO_NO_ERROR) ? io_error_name(io_err) : "can't open", origin, ofile, snd_open_strerror())); } datumb = mus_bytes_per_sample(hdr->sample_type); } else temp_file = false; data = (mus_float_t **)malloc(sizeof(mus_float_t *)); data[0] = (mus_float_t *)malloc(MAX_BUFFER_SIZE * sizeof(mus_float_t)); idata = data[0]; sampler_set_safe(sf, dur); if (gen) { mus_reset(gen); g = gen; } else { g = mus_make_fir_filter(order, fcoeffs, NULL); if (over_selection) { int m; mus_long_t prebeg = 0; /* see if there's data to pre-load the filter */ if (beg >= order) prebeg = order - 1; else prebeg = beg; if (prebeg > 0) for (m = (int)prebeg; m > 0; m--) mus_fir_filter(g, read_sample(sf)); } } if ((over_selection) && (!truncate)) dur -= order; runf = mus_run_function(g); if (!temp_file) { for (j = 0; j < dur; j++) idata[j] = runf(g, read_sample(sf), 0.0); } else { for (offk = 0; offk < dur; offk++) { idata[j] = runf(g, read_sample(sf), 0.0); j++; if (j == MAX_BUFFER_SIZE) { err = mus_file_write(ofd, 0, j - 1, 1, data); j = 0; if (err != MUS_NO_ERROR) break; if (reporting) { progress_report(cp, (mus_float_t)((double)offk / (double)dur)); if (ss->stopped_explicitly) return(NULL); if (!(sp->active)) { ss->stopped_explicitly = true; break; } } } } } if ((over_selection) && (!truncate)) { snd_fd *sfold; sfold = init_sample_read_any(beg + dur, cp, READ_FORWARD, sf->edit_ctr); for (offk = 0; offk < order; offk++) { idata[j] = runf(g, read_sample(sf), 0.0) + read_sample(sfold); j++; if ((temp_file) && (j == MAX_BUFFER_SIZE)) { err = mus_file_write(ofd, 0, j - 1, 1, data); j = 0; if (err != MUS_NO_ERROR) break; } } dur += order; free_snd_fd(sfold); } if (reporting) finish_progress_report(cp); if (origin) new_origin = mus_strdup(origin); else { if (precalculated_coeffs) { vct *v; char *vstr = NULL; v = mus_vct_wrap(order, precalculated_coeffs); vstr = mus_vct_to_readable_string(v); #if HAVE_FORTH if (dur == (order + cp->edits[sf->edit_ctr]->samples)) new_origin = mus_format("%s %d %lld" PROC_SEP PROC_FALSE " %s", vstr, order, beg, S_filter_channel); else new_origin = mus_format("%s %d %lld" PROC_SEP "%lld %s", vstr, order, beg, dur, S_filter_channel); #else if (dur == (order + cp->edits[sf->edit_ctr]->samples)) new_origin = mus_format("%s" PROC_OPEN "%s" PROC_SEP "%d" PROC_SEP "%lld" PROC_SEP PROC_FALSE, to_proc_name(S_filter_channel), vstr, order, beg); else new_origin = mus_format("%s" PROC_OPEN "%s" PROC_SEP "%d" PROC_SEP "%lld" PROC_SEP "%lld", to_proc_name(S_filter_channel), vstr, order, beg, dur); #endif if (vstr) free(vstr); #if (!HAVE_SCHEME) mus_vct_free(v); #endif } else { /* new_origin = filter-channel + envelope */ char *envstr; envstr = env_to_string(e); #if HAVE_FORTH if (dur == (order + cp->edits[sf->edit_ctr]->samples)) new_origin = mus_format("%s %d %lld" PROC_SEP PROC_FALSE " %s", envstr, order, beg, S_filter_channel); else new_origin = mus_format("%s %d %lld" PROC_SEP "%lld %s", envstr, order, beg, dur, S_filter_channel); #else if (dur == (order + cp->edits[sf->edit_ctr]->samples)) new_origin = mus_format("%s" PROC_OPEN "%s" PROC_SEP "%d" PROC_SEP "%lld" PROC_SEP PROC_FALSE, to_proc_name(S_filter_channel), envstr, order, beg); else new_origin = mus_format("%s" PROC_OPEN "%s" PROC_SEP "%d" PROC_SEP "%lld" PROC_SEP "%lld", to_proc_name(S_filter_channel), envstr, order, beg, dur); #endif if (envstr) free(envstr); } } if (temp_file) { if (j > 0) mus_file_write(ofd, 0, j - 1, 1, data); close_temp_file(ofile, ofd, hdr->type, dur * datumb); hdr = free_file_info(hdr); file_change_samples(beg, dur, ofile, cp, 0, DELETE_ME, new_origin, sf->edit_ctr); if (ofile) {free(ofile); ofile = NULL;} } else change_samples(beg, dur, data[0], cp, new_origin, sf->edit_ctr, -1.0); if (new_origin) free(new_origin); update_graph(cp); free(data[0]); free(data); if (!gen) mus_free(g); if ((fcoeffs) && (!precalculated_coeffs)) free(fcoeffs); return(NULL); } static char *filter_channel(chan_info *cp, int order, env *e, mus_long_t beg, mus_long_t dur, int edpos, const char *origin, bool truncate, mus_float_t *coeffs) { bool over_selection; snd_fd *sf; char *errstr = NULL; if ((order == 1) && (coeffs != NULL) && (e == NULL)) { /* a silly optimization... */ if ((coeffs[0] != 1.0) || (edpos != cp->edit_ctr)) scale_channel(cp, coeffs[0], beg, dur, edpos, NOT_IN_AS_ONE_EDIT); return(NULL); } over_selection = ((beg != 0) || (dur < cp->edits[edpos]->samples)); sf = init_sample_read_any(beg, cp, READ_FORWARD, edpos); if ((!over_selection) && ((order == 0) || (order >= 128))) errstr = convolution_filter(cp, order, e, sf, beg, dur, origin, coeffs); else errstr = direct_filter(cp, order, e, sf, beg, dur, origin, truncate, over_selection, NULL, coeffs); free_snd_fd(sf); return(errstr); } static char *apply_filter_or_error(chan_info *ncp, int order, env *e, const char *caller, const char *origin, bool over_selection, mus_float_t *ur_a, mus_any *gen, Xen edpos, int arg_pos, bool truncate, bool *clm_error) { /* if string returned, needs to be freed */ /* interpret e as frequency response and apply as filter to all sync'd chans */ sync_state *sc; sync_info *si; snd_info *sp; int i, stop_point = 0; mus_long_t scdur, dur; snd_fd **sfs; chan_info *cp; char *errstr = NULL; if ((!e) && (!ur_a) && (!gen)) return(NULL); if ((gen) && (!(mus_run_function(gen)))) { (*clm_error) = true; return(mus_format("%s: can't handle %s generators", caller, mus_name(gen))); } sp = ncp->sound; sc = get_sync_state_1(sp, ncp, 0, over_selection, READ_FORWARD, (over_selection) ? (order - 1) : 0, edpos, caller, arg_pos); if (sc == NULL) return(NULL); si = sc->si; sfs = sc->sfs; scdur = sc->dur; ss->stopped_explicitly = false; if ((!ur_a) && (!gen) && (!over_selection) && ((order == 0) || (order >= 128))) { /* use convolution if order is large and not over_selection */ for (i = 0; i < si->chans; i++) { cp = si->cps[i]; sp = cp->sound; if (!(sp->active)) continue; if (scdur == 0) dur = to_c_edit_samples(cp, edpos, caller, arg_pos); else dur = scdur; if (dur == 0) { sfs[i] = free_snd_fd(sfs[i]); continue; } errstr = convolution_filter(cp, order, e, sfs[i], si->begs[i], dur, (origin) ? origin : caller, NULL); sfs[i] = free_snd_fd(sfs[i]); check_for_event(); if ((errstr) || (ss->stopped_explicitly)) { stop_point = i; break; } } } else { /* use FIR filter */ mus_float_t *a = NULL; if (order == 0) order = enved_filter_order(ss); if (!gen) { if (ur_a) a = ur_a; else { if (order & 1) order++; a = get_filter_coeffs(order, e); } if (!a) return(NULL); } /* now filter all currently sync'd chans (one by one) */ /* for each decide whether a file or internal array is needed, scale, update edit tree */ if (!(ss->stopped_explicitly)) { for (i = 0; i < si->chans; i++) { /* done channel at a time here, rather than in parallel as in apply-env because */ /* in this case, the various sync'd channels may be different lengths */ cp = si->cps[i]; if (scdur == 0) dur = to_c_edit_samples(cp, edpos, caller, arg_pos); else dur = scdur; if (dur == 0) { sfs[i] = free_snd_fd(sfs[i]); continue; } errstr = direct_filter(cp, order, e, sfs[i], si->begs[i], dur, (origin) ? origin : caller, truncate, over_selection, gen, a); sfs[i] = free_snd_fd(sfs[i]); if ((errstr) || (ss->stopped_explicitly)) { stop_point = i; break; } } } if ((a) && (!ur_a)) free(a); } if (ss->stopped_explicitly) { /* clean up and undo all edits up to stop_point */ set_status(sp, "filter stopped", false); ss->stopped_explicitly = false; for (i = 0; i <= stop_point; i++) { cp = si->cps[i]; undo_edit(cp, 1); } } free_sync_state(sc); return(errstr); } void apply_filter(chan_info *ncp, int order, env *e, const char *caller, const char *origin, bool over_selection, mus_float_t *ur_a, mus_any *gen, Xen edpos, int arg_pos, bool truncate) { char *error; bool err_type; /* ignored in this context */ error = apply_filter_or_error(ncp, order, e, caller, origin, over_selection, ur_a, gen, edpos, arg_pos, truncate, &err_type); if (error) { snd_error_without_format(error); free(error); } } static char *edit_list_envelope(mus_any *egen, mus_long_t beg, mus_long_t env_dur, mus_long_t called_dur, mus_long_t chan_dur, mus_float_t base) { char *new_origin, *envstr; env *newe; newe = make_envelope_with_offset_and_scaler(mus_data(egen), mus_env_breakpoints(egen) * 2, mus_offset(egen), mus_scaler(egen)); /* mus_env_offset|scaler are the fixed up versions, the originals are mus_offset|scaler. mus_data is the original data */ envstr = env_to_string(newe); if (((env_dur == chan_dur) || (env_dur == (chan_dur - 1))) && (called_dur == chan_dur)) { #if HAVE_FORTH if (base == 1.0) new_origin = mus_format("%s %lld" PROC_SEP PROC_FALSE " %s", envstr, beg, S_env_channel); else new_origin = mus_format("%s %.4f %lld" PROC_SEP PROC_FALSE " %s", envstr, base, beg, S_env_channel_with_base); #else if (base == 1.0) new_origin = mus_format("%s" PROC_OPEN "%s" PROC_SEP "%lld" PROC_SEP PROC_FALSE, to_proc_name(S_env_channel), envstr, beg); else new_origin = mus_format("%s" PROC_OPEN "%s" PROC_SEP "%.4f" PROC_SEP "%lld" PROC_SEP PROC_FALSE, to_proc_name(S_env_channel_with_base), envstr, base, beg); #endif } else { /* env dur was apparently not chan dur, or called dur was not full sound? */ #if HAVE_FORTH new_origin = mus_format("%s :base %.4f :end %lld %s %lld" PROC_SEP "%lld %s", envstr, base, env_dur, S_make_env, beg, called_dur, S_env_channel); #else new_origin = mus_format("%s" PROC_OPEN BPAREN "%s" PROC_OPEN "%s" PROC_SEP ":base" PROC_SEP "%.4f" PROC_SEP ":end" PROC_SEP "%lld)" PROC_SEP "%lld" PROC_SEP "%lld", to_proc_name(S_env_channel), to_proc_name(S_make_env), envstr, base, env_dur, beg, called_dur); #endif } if (envstr) free(envstr); free_env(newe); return(new_origin); } void apply_env(chan_info *cp, env *e, mus_long_t beg, mus_long_t dur, bool over_selection, const char *origin, mus_any *gen, Xen edpos, int arg_pos) { /* basic cases: if env has 1 y value, use scale-channel, * if step env (base == 0.0), use sequence of scale-channels, * if not optimizable (via virtual edits), call mus_env on each sample * if optimizable, use sequence of (x)ramp-channels */ /* e can be NULL => use gen */ snd_info *sp; sync_info *si; sync_state *sc = NULL; int i, j, k, len; bool scalable = true, rampable = true, is_xramp = false; mus_float_t val[1]; mus_any *egen; mus_long_t *passes; mus_float_t *rates; mus_float_t base; mus_float_t scaler, offset; if ((!e) && (!gen)) return; if (over_selection) dur = selection_len(); if (dur <= 0) return; if (e) { if (e->pts == 0) return; val[0] = e->data[1]; /* ok because no possibility of scaler/offset here */ for (i = 1, j = 2; i < e->pts; i++, j += 2) if (e->data[j + 1] != val[0]) { scalable = false; break; } if ((scalable) && (beg == 0)) { int pos; pos = to_c_edit_position(cp, edpos, origin, arg_pos); if ((cp->edit_ctr == pos) && (dur >= cp->edits[pos]->samples)) { scale_by(cp, val, 1, over_selection); return; } } } else scalable = false; si = NULL; sp = cp->sound; if (scalable) /* only true if e (not gen) and all vals are equal and not full chan (latter case handled above) */ { /* ---------------- use scale-channel ---------------- */ sc = get_sync_state_without_snd_fds(sp, cp, beg, over_selection); if (sc == NULL) return; si = sc->si; for (i = 0; i < si->chans; i++) { if (over_selection) scale_channel(si->cps[i], val[0], si->begs[i], selection_end(si->cps[i]) - si->begs[i] + 1, to_c_edit_position(si->cps[i], edpos, origin, arg_pos), NOT_IN_AS_ONE_EDIT); else scale_channel(si->cps[i], val[0], si->begs[i], dur, to_c_edit_position(si->cps[i], edpos, origin, arg_pos), NOT_IN_AS_ONE_EDIT); } free_sync_state(sc); return; } if (e) egen = mus_make_env(e->data, e->pts, 1.0, 0.0, e->base, 0.0, dur - 1, NULL); else egen = gen; len = mus_env_breakpoints(egen); passes = mus_env_passes(egen); rates = mus_env_rates(egen); scaler = mus_env_scaler(egen); /* fixed-up versions if base != 1.0 */ offset = mus_env_offset(egen); base = mus_increment(egen); if (base == 0.0) { /* ---------------- step env -- handled as sequence of scalings ---------------- */ int local_edpos, pos; mus_long_t segbeg, segnum, segend; /* base == 0 originally, so it's a step env */ sc = get_sync_state_without_snd_fds(sp, cp, beg, over_selection); if (sc == NULL) { if (e) mus_free(egen); return; } si = sc->si; for (i = 0; i < si->chans; i++) { bool edited = false; if (!(is_editable(si->cps[i]))) continue; segbeg = si->begs[i]; segend = si->begs[i] + dur; segnum = passes[0] + 1; local_edpos = si->cps[i]->edit_ctr; /* for as_one_edit backup */ pos = to_c_edit_position(si->cps[i], edpos, origin, arg_pos); for (k = 0; k < len; k++) { if ((segbeg + segnum) > segend) segnum = segend - segbeg; else if ((k == (len - 1)) && ((segbeg + segnum) < segend)) segnum = segend - segbeg; /* last value is sticky in envs */ if (segnum > 0) { if (scale_channel(si->cps[i], (mus_float_t)(offset + scaler * rates[k]), segbeg, segnum, pos, IN_AS_ONE_EDIT)) edited = true; pos = si->cps[i]->edit_ctr; } segbeg += segnum; if (segbeg >= segend) break; segnum = passes[k + 1] - passes[k]; } if (edited) { as_one_edit(si->cps[i], local_edpos + 1); if (cp->edits[cp->edit_ctr]->origin) free(cp->edits[cp->edit_ctr]->origin); cp->edits[cp->edit_ctr]->origin = edit_list_envelope(egen, si->begs[i], (len > 1) ? (passes[len - 2]) : dur, dur, current_samples(si->cps[i]), base); after_edit(cp); update_graph(si->cps[i]); reflect_edit_history_change(si->cps[i]); } } free_sync_state(sc); if (e) mus_free(egen); return; } /* step env, special env, and degenerate cases are out of the way */ /* need to use the same sync/selection choice as will be used below! */ sc = get_sync_state_without_snd_fds(sp, cp, beg, over_selection); si = sc->si; if (base != 1.0) is_xramp = true; for (i = 0; i < si->chans; i++) if (unrampable(si->cps[i], si->begs[i], dur, to_c_edit_position(si->cps[i], edpos, origin, arg_pos), is_xramp)) { rampable = false; break; } free_sync_state(sc); if (!rampable) { /* ---------------- not optimizable, so call mus_env on each sample ---------------- */ mus_long_t ioff, alloc_len; mus_float_t **data; mus_float_t *idata; bool reporting = false, temp_file = false; int ofd = 0, datumb = 0; file_info *hdr = NULL; char *ofile = NULL; snd_fd **sfs; /* run env over samples */ sc = get_sync_state(sp, cp, beg, over_selection, READ_FORWARD, edpos, origin, arg_pos); if (sc == NULL) { if (e) mus_free(egen); return; } si = sc->si; sfs = sc->sfs; if (dur > MAX_BUFFER_SIZE) { io_error_t io_err = IO_NO_ERROR; alloc_len = MAX_BUFFER_SIZE; temp_file = true; ofile = snd_tempnam(); hdr = make_temp_header(ofile, snd_srate(sp), si->chans, dur, (char *)origin); ofd = open_temp_file(ofile, si->chans, hdr, &io_err); if (ofd == -1) { if (e) mus_free(egen); for (i = 0; i < si->chans; i++) sfs[i] = free_snd_fd(sfs[i]); free_sync_state(sc); if (e) mus_free(egen); snd_error("%s %s temp file %s: %s\n", (io_err != IO_NO_ERROR) ? io_error_name(io_err) : "can't open", origin, ofile, snd_open_strerror()); free(ofile); return; } datumb = mus_bytes_per_sample(hdr->sample_type); } else { temp_file = false; alloc_len = dur; } data = (mus_float_t **)malloc(si->chans * sizeof(mus_float_t *)); for (i = 0; i < si->chans; i++) data[i] = (mus_float_t *)calloc(alloc_len, sizeof(mus_float_t)); j = 0; reporting = ((dur > REPORTING_SIZE) && (!(cp->squelch_update))); if (reporting) start_progress_report(cp); if (si->chans > 1) { ss->stopped_explicitly = false; if (temp_file) { for (ioff = 0; ioff < dur; ioff++) { mus_float_t egen_val; egen_val = mus_env(egen); for (k = 0; k < si->chans; k++) data[k][j] = (read_sample(sfs[k]) * egen_val); j++; if (j == alloc_len) { int err; if (reporting) { progress_report(cp, (mus_float_t)((double)ioff / ((double)dur))); if (ss->stopped_explicitly) break; if (!(sp->active)) { ss->stopped_explicitly = true; break; } } err = mus_file_write(ofd, 0, j - 1, si->chans, data); j = 0; if (err != MUS_NO_ERROR) break; } } } else { for (k = 0; k < si->chans; k++) samples_to_vct_with_reader(dur, data[k], sfs[k]); for (j = 0; j < dur; j++) { mus_float_t egen_val; egen_val = mus_env(egen); for (k = 0; k < si->chans; k++) data[k][j] *= egen_val; } } } else { snd_fd *sf = NULL; sf = sfs[0]; idata = data[0]; if (temp_file) { ss->stopped_explicitly = false; for (ioff = 0; ioff < dur; ioff++) { idata[j] = (read_sample(sf) * mus_env(egen)); j++; if (j == alloc_len) { int err; if (reporting) { progress_report(cp, (mus_float_t)((double)ioff / ((double)dur))); if (ss->stopped_explicitly) break; if (!(sp->active)) { ss->stopped_explicitly = true; break; } } err = mus_file_write(ofd, 0, j - 1, 1, data); j = 0; if (err != MUS_NO_ERROR) break; } } } else { samples_to_vct_with_reader(dur, idata, sf); for (j = 0; j < dur; j++) idata[j] *= mus_env(egen); } } if (temp_file) { if (j > 0) mus_file_write(ofd, 0, j - 1, si->chans, data); close_temp_file(ofile, ofd, hdr->type, dur * si->chans * datumb); free_file_info(hdr); } if (reporting) finish_progress_report(cp); if (ss->stopped_explicitly) { ss->stopped_explicitly = false; if (temp_file) snd_remove(ofile, REMOVE_FROM_CACHE); } else { if ((temp_file) && (si->chans > 1)) remember_temp(ofile, si->chans); for (i = 0; i < si->chans; i++) { char *new_origin; int pos; pos = to_c_edit_position(si->cps[i], edpos, origin, arg_pos); new_origin = edit_list_envelope(egen, si->begs[i], (len > 1) ? (passes[len - 2]) : dur, dur, current_samples(si->cps[i]), base); if (temp_file) { file_change_samples(si->begs[i], dur, ofile, si->cps[i], i, (si->chans > 1) ? MULTICHANNEL_DELETION : DELETE_ME, new_origin, pos); if ((si->begs[i] == 0) && (dur == si->cps[i]->edits[pos]->samples)) amp_env_env(si->cps[i], mus_data(egen), len, pos, base, scaler, offset); else { if ((len < 2) || (snd_abs_mus_long_t(dur - passes[len - 2]) < 2)) amp_env_env_selection_by(si->cps[i], egen, si->begs[i], dur, pos); } } else change_samples(si->begs[i], dur, data[i], si->cps[i], new_origin, pos, -1.0); free(new_origin); update_graph(si->cps[i]); } } for (i = 0; i < si->chans; i++) { sfs[i] = free_snd_fd(sfs[i]); free(data[i]); } if ((temp_file) && (ofile)) {free(ofile); ofile = NULL;} if (data) free(data); } else { /* ---------------- optimizable -- treat env as a sequence of virtual (x)ramps and scalings (if slope=0) ---------------- */ int local_edpos, m, pos, env_pos; bool need_xramp = false; mus_long_t segbeg, segnum, segend; double power = 0.0; mus_float_t *data; data = mus_data(egen); if (base != 1.0) need_xramp = true; sc = get_sync_state_without_snd_fds(sp, cp, beg, over_selection); if (sc == NULL) { if (e) mus_free(egen); return; } si = sc->si; /* in snd-test.scm, one sync_state pointer is lost here because env-channel requests edpos 2 (or is it 123?), but only 1 exists */ for (i = 0; i < si->chans; i++) { bool edited = false; if (!(is_editable(si->cps[i]))) continue; segbeg = si->begs[i]; segend = si->begs[i] + dur; segnum = passes[0]; local_edpos = si->cps[i]->edit_ctr; /* for as_one_edit backup */ pos = to_c_edit_position(si->cps[i], edpos, origin, arg_pos); env_pos = pos; for (k = 0, m = 1; k < len; k++, m += 2) { bool applied_ramp = false; if ((segbeg + segnum) > segend) segnum = segend - segbeg; else if ((k >= (len - 2)) && ((segbeg + segnum) < segend)) segnum = segend - segbeg; /* last value is sticky in envs */ if (segnum > 0) { if (k == 0) { if (need_xramp) { power = mus_env_initial_power(egen); applied_ramp = xramp_channel(si->cps[i], power, rates[0], scaler, offset, segbeg, segnum, pos, IN_AS_ONE_EDIT, egen, 0); power *= exp(log(rates[0]) * segnum); } else applied_ramp = ramp_channel(si->cps[i], offset + scaler * data[m], rates[0], segbeg, segnum, pos, IN_AS_ONE_EDIT); } else { if (need_xramp) /* divide by segnum since we end at the break point and don't want to repeat it, so go to next position in env */ { applied_ramp = xramp_channel(si->cps[i], power, rates[k], scaler, offset, segbeg, segnum, pos, IN_AS_ONE_EDIT, egen, k); power *= exp(log(rates[k]) * segnum); } else { if (k == (len - 1)) /* oops -- must have sticky end in play here? this doesn't work if a clm env passed */ applied_ramp = scale_channel(si->cps[i], (mus_float_t)(offset + scaler * data[m]), segbeg, segnum, pos, IN_AS_ONE_EDIT); else applied_ramp = ramp_channel(si->cps[i], offset + scaler * data[m], rates[k], segbeg, segnum, pos, IN_AS_ONE_EDIT); } } pos = si->cps[i]->edit_ctr; } if (!edited) edited = applied_ramp; segbeg += segnum; if (segbeg >= segend) break; segnum = passes[k + 1] - passes[k]; } if (edited) { if ((si->begs[i] == 0) && (dur == si->cps[i]->edits[env_pos]->samples)) amp_env_env(si->cps[i], mus_data(egen), len, env_pos, base, scaler, offset); else { if ((len < 2) || (snd_abs_mus_long_t(dur - passes[len - 2]) < 2)) amp_env_env_selection_by(si->cps[i], egen, si->begs[i], dur, env_pos); } as_one_edit(si->cps[i], local_edpos + 1); if (si->cps[i]->edits[si->cps[i]->edit_ctr]->origin) free(si->cps[i]->edits[si->cps[i]->edit_ctr]->origin); si->cps[i]->edits[si->cps[i]->edit_ctr]->origin = edit_list_envelope(egen, si->begs[i], (len > 1) ? (passes[len - 2]) : dur, dur, current_samples(si->cps[i]), base); after_edit(cp); update_graph(si->cps[i]); reflect_edit_history_change(si->cps[i]); } } } if (e) mus_free(egen); free_sync_state(sc); } void cursor_delete(chan_info *cp, mus_long_t count) { mus_long_t beg; snd_info *sp; if (count == 0) return; if (count > 0) beg = cursor_sample(cp); else { count = -count; beg = cursor_sample(cp) - count; if (beg < 0) { count += beg; beg = 0; if (count <= 0) return; } } sp = cp->sound; if (sp->sync != 0) { int i; sync_info *si; chan_info **cps; si = snd_sync(sp->sync); cps = si->cps; for (i = 0; i < si->chans; i++) { if (delete_samples(beg, count, cps[i], cps[i]->edit_ctr)) { cursor_sample(cps[i]) = beg; update_graph(si->cps[i]); } } si = free_sync_info(si); } else { if (delete_samples(beg, count, cp, cp->edit_ctr)) { cursor_sample(cp) = beg; update_graph(cp); } } } void cursor_insert(chan_info *cp, mus_long_t beg, mus_long_t count) { snd_info *sp; sp = cp->sound; if (count < 0) { count = -count; if (count > beg) count = beg; beg -= count; } if (sp->sync != 0) { int i; sync_info *si; chan_info **cps; si = snd_sync(sp->sync); cps = si->cps; for (i = 0; i < si->chans; i++) { if ((count > 0) && (extend_with_zeros(cps[i], mus_oclamp(0, beg, current_samples(si->cps[i])), count, cps[i]->edit_ctr, "cursor insert"))) update_graph(cps[i]); } si = free_sync_info(si); } else { if ((count > 0) && (extend_with_zeros(cp, mus_oclamp(0, beg, current_samples(cp)), count, cp->edit_ctr, "cursor insert"))) update_graph(cp); } } void cursor_zeros(chan_info *cp, mus_long_t count, bool over_selection) { int i; mus_long_t beg, num; snd_info *sp; sync_info *si = NULL; chan_info *ncp; if (count == 0) return; if (count < 0) num = -count; else num = count; sp = cp->sound; if ((sp->sync != 0) && (!over_selection)) { si = snd_sync(sp->sync); for (i = 0; i < si->chans; i++) si->begs[i] = cursor_sample(cp); } else { if ((over_selection) && (selection_is_active())) { si = selection_sync(); num = selection_len(); } } if (!si) si = make_simple_sync(cp, cursor_sample(cp)); for (i = 0; i < si->chans; i++) { /* if zeroing entire sound, set scalers and remake peak_env */ ncp = si->cps[i]; if ((si->begs[i] == 0) && (num >= current_samples(ncp))) { mus_float_t scaler[1]; snd_info *nsp; int old_sync; nsp = ncp->sound; old_sync = nsp->sync; nsp->sync = 0; scaler[0] = 0.0; scale_by(ncp, scaler, 1, OVER_SOUND); nsp->sync = old_sync; } else { if (count > 0) beg = si->begs[i]; else beg = si->begs[i] + count; /* special case 1 sample -- if already 0, treat as no-op */ if ((count != 1) || (beg >= current_samples(ncp)) || (chn_sample(beg, ncp, ncp->edit_ctr) != 0.0)) scale_channel(ncp, 0.0, beg, num, ncp->edit_ctr, NOT_IN_AS_ONE_EDIT); } } si = free_sync_info(si); } /* smooth-channel could be a built-in virtual op, but the smoothed section is never long, so it doesn't save anything */ static void smooth_channel(chan_info *cp, mus_long_t beg, mus_long_t dur, int edpos) { mus_float_t *data = NULL; mus_long_t k; char *origin = NULL; mus_float_t y0, y1; if ((beg < 0) || (dur <= 0)) return; if (!(is_editable(cp))) return; if ((beg + dur) > cp->edits[edpos]->samples) { dur = cp->edits[edpos]->samples - beg; if (dur <= 0) return; } y0 = chn_sample(beg, cp, edpos); y1 = chn_sample(beg + dur, cp, edpos); /* one past end -- this is a debatable choice */ #if HAVE_FORTH origin = mus_format("%lld" PROC_SEP "%lld %s", beg, dur, S_smooth_channel); #else origin = mus_format("%s" PROC_OPEN "%lld" PROC_SEP "%lld", to_proc_name(S_smooth_channel), beg, dur); #endif data = (mus_float_t *)malloc(dur * sizeof(mus_float_t)); if (y0 == y1) { for (k = 0; k < dur; k++) data[k] = y0; change_samples(beg, dur, data, cp, origin, edpos, fabs(y0)); } else { mus_float_t angle, incr, off, scale; if (y1 > y0) angle = M_PI; else angle = 0.0; incr = M_PI / (double)dur; off = 0.5 * (y1 + y0); scale = 0.5 * fabs(y0 - y1); /* if scale is very small, it might work here to just use linear interpolation, but that case appears to be very uncommon. */ for (k = 0; k < dur; k++, angle += incr) data[k] = (off + scale * cos(angle)); change_samples(beg, dur, data, cp, origin, edpos, ((y0 > y1) && (y1 >= 0.0)) ? y0 : -1.0); } if (origin) free(origin); update_graph(cp); free(data); } void cos_smooth(chan_info *cp, mus_long_t beg, mus_long_t num, bool over_selection) { /* verbatim, so to speak from Dpysnd */ /* start at beg, apply a cosine for num samples, matching endpoints */ sync_state *sc; int i; snd_info *sp; sync_info *si; sp = cp->sound; sc = get_sync_state_without_snd_fds(sp, cp, beg, over_selection); if (sc == NULL) return; si = sc->si; if (over_selection) num = sc->dur; for (i = 0; i < si->chans; i++) smooth_channel(si->cps[i], si->begs[i], num, si->cps[i]->edit_ctr); free_sync_state(sc); } #if USE_MOTIF /* this is used by the view-files dialog */ typedef struct { snd_fd **fds; int len; } scale_and_src_data; static mus_float_t scale_and_src_input(void *data, int direction) { scale_and_src_data *sd = (scale_and_src_data *)data; int i; mus_float_t sum; sum = 0.0; for (i = 0; i < sd->len; i++) if (sd->fds[i]) sum += read_sample(sd->fds[i]); return(sum); } char *scale_and_src(char **files, int len, int max_chans, mus_float_t amp, mus_float_t speed, env *amp_env, bool *temp_file_err) { /* view files mix and insert possible src change */ char *tempfile; snd_fd ***fds = NULL; snd_info **sps = NULL; int i, chan, chans = 0; mus_long_t k, new_dur = 0, dur = 0; mus_float_t **data; file_info *hdr = NULL; int j, ofd = 0, datumb = 0, err = 0, srate = 0; io_error_t io_err = IO_NO_ERROR; mus_float_t sum; mus_any *e = NULL; mus_any **sgens = NULL; scale_and_src_data **sdata = NULL; (*temp_file_err) = false; tempfile = snd_tempnam(); for (i = 0; i < len; i++) { int fchans, fsrate; mus_long_t flen; fchans = mus_sound_chans(files[i]); flen = mus_sound_framples(files[i]); fsrate = mus_sound_srate(files[i]); if (chans < fchans) chans = fchans; if (srate < fsrate) srate = fsrate; if (dur < flen) dur = flen; } /* open output sound file */ hdr = make_temp_header(tempfile, srate, chans, dur, "scale-and-src temp"); ofd = open_temp_file(tempfile, chans, hdr, &io_err); if (ofd == -1) { (*temp_file_err) = true; free_file_info(hdr); free(tempfile); return(mus_format("%s temp file %s: %s\n", (io_err != IO_NO_ERROR) ? io_error_name(io_err) : "can't open", tempfile, snd_open_strerror())); } fds = (snd_fd ***)calloc(len, sizeof(snd_fd **)); sps = (snd_info **)calloc(len, sizeof(snd_info *)); for (i = 0; i < len; i++) { fds[i] = (snd_fd **)calloc(max_chans, sizeof(snd_fd *)); sps[i] = make_sound_readable(files[i], false); sps[i]->short_filename = filename_without_directory(files[i]); sps[i]->filename = NULL; /* why? squelch graphics perhaps? */ for (chan = 0; chan < sps[i]->nchans; chan++) fds[i][chan] = init_sample_read(0, sps[i]->chans[chan], READ_FORWARD); } /* now we have readers set up for all chans of all sounds about to be mixed/scaled/enveloped/resampled... */ datumb = mus_bytes_per_sample(hdr->sample_type); data = (mus_float_t **)calloc(chans, sizeof(mus_float_t *)); for (i = 0; i < chans; i++) data[i] = (mus_float_t *)malloc(MAX_BUFFER_SIZE * sizeof(mus_float_t)); if (!(snd_feq(speed, 1.0))) { new_dur = (mus_long_t)((double)dur / (double)speed); sgens = (mus_any **)calloc(chans, sizeof(mus_any *)); sdata = (scale_and_src_data **)calloc(chans, sizeof(scale_and_src_data *)); for (chan = 0; chan < chans; chan++) { int m; sdata[chan] = (scale_and_src_data *)calloc(1, sizeof(scale_and_src_data)); sdata[chan]->len = len; sdata[chan]->fds = (snd_fd **)calloc(len, sizeof(snd_fd *)); for (m = 0; m < len; m++) sdata[chan]->fds[m] = fds[m][chan]; sgens[chan] = mus_make_src(scale_and_src_input, speed, 0, (void *)(sdata[chan])); /* width=0 -> use current default */ } } else new_dur = dur; if (!(is_default_env(amp_env))) e = mus_make_env(amp_env->data, amp_env->pts, amp, 0.0, 1.0, 0.0, new_dur - 1, NULL); j = 0; if (!sgens) { for (k = 0; k < dur; k++) { if (e) amp = mus_env(e); for (chan = 0; chan < chans; chan++) { sum = 0.0; for (i = 0; i < len; i++) if (fds[i][chan]) sum += read_sample(fds[i][chan]); sum *= amp; data[chan][j] = (sum); } j++; if (j == MAX_BUFFER_SIZE) { err = mus_file_write(ofd, 0, j - 1, chans, data); j = 0; if (err != MUS_NO_ERROR) break; } } } else { for (k = 0; k < new_dur; k++) { if (e) amp = mus_env(e); for (chan = 0; chan < chans; chan++) data[chan][j] = (amp * mus_src(sgens[chan], 0.0, &scale_and_src_input)); j++; if (j == MAX_BUFFER_SIZE) { err = mus_file_write(ofd, 0, j - 1, chans, data); j = 0; if (err != MUS_NO_ERROR) break; } } } if (j > 0) mus_file_write(ofd, 0, j - 1, chans, data); /* close and free everything */ close_temp_file(tempfile, ofd, hdr->type, new_dur * datumb); hdr = free_file_info(hdr); if (e) mus_free(e); for (i = 0; i < len; i++) { for (chan = 0; chan < sps[i]->nchans; chan++) free_snd_fd(fds[i][chan]); free(fds[i]); sps[i] = completely_free_snd_info(sps[i]); } free(fds); free(sps); for (i = 0; i < chans; i++) free(data[i]); free(data); if (sgens) { for (chan = 0; chan < chans; chan++) { free(sdata[chan]->fds); free(sdata[chan]); mus_free(sgens[chan]); } free(sdata); free(sgens); } return(tempfile); } #endif static Xen map_channel_to_temp_file(chan_info *cp, snd_fd *sf, Xen proc, mus_long_t beg, mus_long_t num, int pos, const char *caller) { snd_info *sp; int rpt4, ofd, datumb; char *filename; file_info *hdr; bool reporting; io_error_t io_err = IO_NO_ERROR; Xen res = Xen_false; sampler_set_safe(sf, num); sp = cp->sound; reporting = ((num > REPORTING_SIZE) && (!(cp->squelch_update))); if (reporting) start_progress_report(cp); rpt4 = MAX_BUFFER_SIZE / 4; filename = snd_tempnam(); hdr = make_temp_header(filename, snd_srate(cp->sound), 1, 0, S_map_channel); datumb = mus_bytes_per_sample(hdr->sample_type); ofd = open_temp_file(filename, 1, hdr, &io_err); if (ofd == -1) snd_error("%s: %s (temp file) %s: %s", S_map_channel, (io_err != IO_NO_ERROR) ? io_error_name(io_err) : "can't open", filename, snd_open_strerror()); else { int err = MUS_NO_ERROR, i, j = 0, rpt = 0; mus_float_t **data = NULL; mus_long_t kp, samps = 0; data = (mus_float_t **)malloc(1 * sizeof(mus_float_t *)); data[0] = (mus_float_t *)malloc(MAX_BUFFER_SIZE * sizeof(mus_float_t)); ss->stopped_explicitly = false; /* fprintf(stderr, "tempfile %d, %lld %s\n", __LINE__, num, DISPLAY(body)); */ for (kp = 0; kp < num; kp++) { /* changed here to remove catch 24-Mar-02 */ res = Xen_unprotected_call_with_1_arg(proc, C_double_to_Xen_real((double)read_sample(sf))); if (Xen_is_number(res)) /* one number -> replace current sample */ { samps++; data[0][j++] = Xen_real_to_C_double(res); if (j == MAX_BUFFER_SIZE) { err = mus_file_write(ofd, 0, j - 1, 1, data); j = 0; if (err != MUS_NO_ERROR) break; } } else { if (!Xen_is_false(res)) /* if #f, no output on this pass */ { if (Xen_is_true(res)) /* if #t we halt the entire map */ break; else { if (mus_is_vct(res)) { vct *v; mus_long_t vlen; mus_float_t *vdata; v = Xen_to_vct(res); vlen = mus_vct_length(v); vdata = mus_vct_data(v); for (i = 0; i < vlen; i++) { data[0][j++] = vdata[i]; if (j == MAX_BUFFER_SIZE) { err = mus_file_write(ofd, 0, j - 1, 1, data); j = 0; if (err != MUS_NO_ERROR) break; } } samps += vlen - 1; } else { close_temp_file(filename, ofd, hdr->type, samps * datumb); sf = free_snd_fd(sf); if (reporting) finish_progress_report(cp); snd_remove(filename, REMOVE_FROM_CACHE); free(filename); free(data[0]); free(data); Xen_error(BAD_TYPE, Xen_list_3(C_string_to_Xen_string("~A: result of procedure must be a (non-complex) number, boolean, or vct: ~A"), C_string_to_Xen_string(caller), res)); } } } } if (reporting) { rpt++; if (rpt > rpt4) { progress_report(cp, (mus_float_t)((double)kp / (double)num)); if (!(sp->active)) { ss->stopped_explicitly = true; break; } rpt = 0; } } if (ss->stopped_explicitly) break; } if (j > 0) mus_file_write(ofd, 0, j - 1, 1, data); close_temp_file(filename, ofd, hdr->type, samps * datumb); free_file_info(hdr); free(data[0]); free(data); sf = free_snd_fd(sf); if (reporting) finish_progress_report(cp); if (ss->stopped_explicitly) ss->stopped_explicitly = false; else { if (cp->active < CHANNEL_HAS_EDIT_LIST) { snd_remove(filename, REMOVE_FROM_CACHE); free(filename); Xen_error(NO_SUCH_CHANNEL, Xen_list_2(C_string_to_Xen_string("~A: can't edit closed channel!"), C_string_to_Xen_string(caller))); return(Xen_false); } if (samps == num) file_change_samples(beg, samps, filename, cp, 0, DELETE_ME, caller, pos); else { delete_samples(beg, num, cp, pos); if (samps > 0) { int cured; cured = cp->edit_ctr; file_insert_samples(beg, samps, filename, cp, 0, DELETE_ME, caller, cp->edit_ctr); backup_edit_list(cp); if (cp->edit_ctr > cured) backup_edit_list(cp); ripple_trailing_marks(cp, beg, num, samps); } else snd_remove(filename, REMOVE_FROM_CACHE); } } } free(filename); return(res); } #if HAVE_SCHEME static bool tree_memq(s7_scheme *sc, s7_pointer symbol, s7_pointer tree) { if (symbol == tree) return(true); if (s7_is_pair(tree)) return((tree_memq(sc, symbol, s7_car(tree))) || (tree_memq(sc, symbol, s7_cdr(tree)))); return(false); } #endif static Xen map_channel_to_buffer(chan_info *cp, snd_fd *sf, Xen proc, mus_long_t beg, mus_long_t num, int pos, const char *caller) { /* not temp_file -- use resizable buffer */ int i, data_pos = 0, kp; mus_long_t cur_size; mus_float_t *data = NULL; Xen res = Xen_false; #if HAVE_SCHEME mus_float_t *in_data; int gc_loc, proc_loc; bool use_apply; s7_pointer arg_list, body, e, slot; s7_pointer (*eval)(s7_scheme *sc, s7_pointer code, s7_pointer e); arg_list = xen_nil; body = xen_nil; e = xen_nil; slot = xen_nil; eval = NULL; body = s7_closure_body(s7, proc); if ((s7_is_pair(body)) && (s7_is_pair(s7_closure_args(s7, proc)))) { s7_pointer arg; if (s7_is_null(s7, s7_cdr(body))) { res = s7_car(body); arg = s7_car(s7_closure_args(s7, proc)); if (s7_is_pair(arg)) arg = s7_car(arg); /* lambda* + default */ if ((s7_is_boolean(res)) || (res == arg)) { /* #f = delete all samples in the range, #t = no-op, (lambda (y) y) a no-op */ sf = free_snd_fd(sf); if (res == s7_f(s7)) delete_samples(beg, num, cp, pos); return(res); } if (!s7_is_pair(res)) { s7_double x; if (s7_is_symbol(res)) { s7_pointer old_e; e = s7_sublet(s7, s7_closure_let(s7, proc), s7_nil(s7)); old_e = s7_set_curlet(s7, e); /* new env for map lambda */ res = s7_symbol_value(s7, res); s7_set_curlet(s7, old_e); } x = s7_number_to_real_with_caller(s7, res, "map-channel"); data = (mus_float_t *)malloc(num * sizeof(mus_float_t)); for (kp = 0; kp < num; kp++) data[kp] = x; /* since we're not calling eval or the event checker, the channel can't be closed during the loop (??) */ change_samples(beg, num, data, cp, caller, pos, fabs(x)); free(data); sf = free_snd_fd(sf); return(res); } /* look first for the common scaling case */ if ((s7_list_length(s7, res) == 3) && (s7_cadr(res) != s7_caddr(res)) && ((s7_car(res) == s7_make_symbol(s7, "*")) || (s7_car(res) == s7_make_symbol(s7, "+"))) && (((s7_cadr(res) == arg) && (!s7_is_pair(s7_caddr(res)))) || ((s7_caddr(res) == arg) && (!s7_is_pair(s7_cadr(res)))))) { double x; s7_pointer fx; if (s7_cadr(res) == arg) fx = s7_caddr(res); else fx = s7_cadr(res); if (s7_is_symbol(fx)) { s7_pointer old_e; e = s7_sublet(s7, s7_closure_let(s7, proc), s7_nil(s7)); old_e = s7_set_curlet(s7, e); /* new env for map lambda */ fx = s7_symbol_value(s7, fx); s7_set_curlet(s7, old_e); } x = s7_number_to_real_with_caller(s7, fx, "map-channel"); if (s7_car(res) == s7_make_symbol(s7, "*")) scale_channel(cp, x, beg, num, pos, NOT_IN_AS_ONE_EDIT); else { data = (mus_float_t *)calloc(num, sizeof(mus_float_t)); samples_to_vct_with_reader(num, data, sf); for (kp = 0; kp < num; kp++) data[kp] += x; change_samples(beg, num, data, cp, caller, pos, -1.0); free(data); } sf = free_snd_fd(sf); return(res); } /* try rf mechanism */ if (s7_is_symbol(s7_car(res))) { s7_pointer fcar; fcar = s7_symbol_value(s7, s7_car(res)); if (s7_rf_function(s7, fcar)) { s7_rf_t rf; s7_pointer yp, old_e, y; e = s7_sublet(s7, s7_closure_let(s7, proc), s7_nil(s7)); old_e = s7_set_curlet(s7, e); /* new env for map lambda */ /* we need to connect to the lambda's closure so subsequent symbol lookups work right */ y = s7_make_mutable_real(s7, 1.5); /* slot for the map lambda arg */ yp = s7_make_slot(s7, e, arg, y); s7_xf_new(s7, e); rf = s7_rf_function(s7, fcar)(s7, res); if (rf) { s7_pointer *top, *p; data = (mus_float_t *)calloc(num, sizeof(mus_float_t)); top = s7_xf_start(s7); if (tree_memq(s7, arg, res)) { samples_to_vct_with_reader(num, data, sf); for (kp = 0; kp < num; kp++) { s7_slot_set_real_value(s7, yp, data[kp]); p = top; data[kp] = rf(s7, &p); } } else { for (kp = 0; kp < num; kp++) { p = top; data[kp] = rf(s7, &p); } } s7_xf_free(s7); sf = free_snd_fd(sf); change_samples(beg, num, data, cp, caller, pos, -1.0); free(data); s7_set_curlet(s7, old_e); return(res); } s7_xf_free(s7); s7_set_curlet(s7, old_e); } } } /* (let ((rd (make-sampler 0))) (map-channel (lambda (y) (+ (next-sample rd) y)))) */ arg = s7_car(s7_closure_args(s7, proc)); e = s7_sublet(s7, s7_closure_let(s7, proc), s7_nil(s7)); gc_loc = s7_gc_protect(s7, e); slot = s7_make_slot(s7, e, arg, s7_make_real(s7, 0.0)); use_apply = false; if (s7_is_null(s7, s7_cdr(body))) { eval = s7_eval_form; body = s7_car(body); } else eval = s7_eval; } else { /* presumably "proc" is something like abs */ arg_list = Xen_list_1(Xen_false); gc_loc = s7_gc_protect(s7, arg_list); use_apply = true; } proc_loc = s7_gc_protect(s7, proc); #endif /* fprintf(stderr, "map %lld: body: %s\n", num, s7_object_to_c_string(s7, body)); */ data = (mus_float_t *)calloc(num, sizeof(mus_float_t)); #if HAVE_SCHEME in_data = (mus_float_t *)calloc(num, sizeof(mus_float_t)); samples_to_vct_with_reader(num, in_data, sf); #endif cur_size = num; for (kp = 0; kp < num; kp++) { #if HAVE_SCHEME if (use_apply) { s7_set_car(arg_list, s7_make_real(s7, in_data[kp])); if (kp == 0) res = s7_call_with_location(s7, proc, arg_list, __func__, __FILE__, __LINE__); else res = s7_apply_function(s7, proc, arg_list); } else { s7_slot_set_value(s7, slot, s7_make_real(s7, in_data[kp])); res = eval(s7, body, e); } #else res = Xen_unprotected_call_with_1_arg(proc, C_double_to_Xen_real((double)read_sample(sf))); #endif if (Xen_is_number(res)) /* one number -> replace current sample */ { if (data_pos >= cur_size) { cur_size *= 2; data = (mus_float_t *)realloc(data, cur_size * sizeof(mus_float_t)); } data[data_pos++] = Xen_real_to_C_double(res); } else { if (!Xen_is_false(res)) /* if #f, no output on this pass */ { if (Xen_is_true(res)) /* if #t we halt the entire map */ break; else { if (mus_is_vct(res)) { vct *v; mus_long_t vlen; mus_float_t *vdata; v = Xen_to_vct(res); vlen = mus_vct_length(v); vdata = mus_vct_data(v); for (i = 0; i < vlen; i++) { if (data_pos >= cur_size) { cur_size *= 2; data = (mus_float_t *)realloc(data, cur_size * sizeof(mus_float_t)); } data[data_pos++] = vdata[i]; } } else { if (data) {free(data); data = NULL;} sf = free_snd_fd(sf); #if HAVE_SCHEME s7_gc_unprotect_at(s7, gc_loc); s7_gc_unprotect_at(s7, proc_loc); #endif Xen_error(BAD_TYPE, Xen_list_3(C_string_to_Xen_string("~A: result of procedure must be a number, boolean, or vct: ~A"), C_string_to_Xen_string(caller), res)); } } } } } sf = free_snd_fd(sf); #if HAVE_SCHEME free(in_data); s7_gc_unprotect_at(s7, gc_loc); s7_gc_unprotect_at(s7, proc_loc); #endif if (cp->active < CHANNEL_HAS_EDIT_LIST) { if (data) {free(data); data = NULL;} Xen_error(NO_SUCH_CHANNEL, Xen_list_2(C_string_to_Xen_string("~A: can't edit closed channel!"), C_string_to_Xen_string(caller))); return(Xen_false); } if (data_pos == num) change_samples(beg, data_pos, data, cp, caller, pos, -1.0); else { /* the version above truncates to the new length... */ delete_samples(beg, num, cp, pos); if (data_pos > 0) { int cured; cured = cp->edit_ctr; insert_samples(beg, data_pos, data, cp, caller, cp->edit_ctr); backup_edit_list(cp); if (cp->edit_ctr > cured) backup_edit_list(cp); ripple_trailing_marks(cp, beg, num, data_pos); } } if (data) {free(data); data = NULL;} return(res); } static Xen g_map_chan_1(Xen proc_and_list, Xen s_beg, Xen s_end, Xen org, Xen snd, Xen chn, Xen edpos, Xen s_dur, const char *fallback_caller) { chan_info *cp; const char *caller; mus_long_t beg = 0, end = 0, dur = 0; mus_long_t num; int pos; Xen res = Xen_false; Xen proc; proc = proc_and_list; if (Xen_is_string(org)) caller = Xen_string_to_C_string(org); else caller = fallback_caller; Xen_check_type((Xen_is_procedure(proc)) || (mus_is_xen(proc)), proc, 1, caller, "a procedure"); Snd_assert_sample_type(caller, s_beg, 2); Snd_assert_sample_type(caller, s_end, 3); Snd_assert_sample_type(caller, s_dur, 3); Snd_assert_channel(caller, snd, chn, 5); cp = get_cp(snd, chn, caller); if (!cp) return(Xen_false); if (!(is_editable(cp))) return(Xen_false); pos = to_c_edit_position(cp, edpos, caller, 7); beg = beg_to_sample(s_beg, caller); if (Xen_is_false(s_dur)) end = end_to_sample(s_end, cp, pos, caller); else dur = dur_to_samples(s_dur, beg, cp, pos, 3, caller); /* 3 is arg num from caller's point of view */ if (end == 0) { if (dur != 0) end = beg + dur - 1; else end = cp->edits[pos]->samples - 1; } num = end - beg + 1; if (num > 0) { snd_fd *sf = NULL; char *errmsg = NULL; bool temp_file, backup = false; errmsg = procedure_ok(proc, 1, caller, "", 1); if (errmsg) { Xen errstr; errstr = C_string_to_Xen_string(errmsg); free(errmsg); return(snd_bad_arity_error(caller, errstr, proc)); } /* added 27-Oct-06 -- can't see why map-channel should be that different from insert-samples et al */ if (beg > cp->edits[pos]->samples) { if (!(extend_with_zeros(cp, cp->edits[pos]->samples, beg - cp->edits[pos]->samples, pos, "extend for " S_map_channel))) return(Xen_false); backup = true; pos = cp->edit_ctr; } sf = init_sample_read_any_with_bufsize(beg, cp, READ_FORWARD, pos, (num > REPORTING_SIZE) ? REPORTING_SIZE : num); if (sf == NULL) return(Xen_true); temp_file = (num > REPORTING_SIZE); if (temp_file) res = map_channel_to_temp_file(cp, sf, proc, beg, num, pos, caller); else res = map_channel_to_buffer(cp, sf, proc, beg, num, pos, caller); if (backup) backup_edit_list(cp); update_graph(cp); } return(res); } static Xen g_sp_scan(Xen proc_and_list, Xen s_beg, Xen s_end, Xen snd, Xen chn, const char *caller, bool counting, Xen edpos, int arg_pos, Xen s_dur) { chan_info *cp; mus_long_t beg = 0, end = 0, dur = 0; snd_info *sp; snd_fd *sf; mus_long_t kp, num; int rpt = 0, rpt4 = 0; bool reporting = false; int counts = 0, pos; char *errmsg; Xen proc; proc = proc_and_list; Xen_check_type((Xen_is_procedure(proc)), proc, 1, caller, "a procedure"); Snd_assert_sample_type(caller, s_beg, 2); Snd_assert_sample_type(caller, s_end, 3); Snd_assert_sample_type(caller, s_dur, 3); Snd_assert_channel(caller, snd, chn, 4); cp = get_cp(snd, chn, caller); if (!cp) return(Xen_false); pos = to_c_edit_position(cp, edpos, caller, arg_pos); beg = beg_to_sample(s_beg, caller); if (beg > cp->edits[pos]->samples) return(Xen_false); if (Xen_is_false(s_dur)) end = end_to_sample(s_end, cp, pos, caller); else dur = dur_to_samples(s_dur, beg, cp, pos, 3, caller); errmsg = procedure_ok(proc, 1, caller, "", 1); if (errmsg) { Xen errstr; errstr = C_string_to_Xen_string(errmsg); free(errmsg); return(snd_bad_arity_error(caller, errstr, proc)); } sp = cp->sound; if (end == 0) { if (dur != 0) end = beg + dur - 1; else end = cp->edits[pos]->samples - 1; } num = end - beg + 1; if (num <= 0) return(Xen_false); sf = init_sample_read_any_with_bufsize(beg, cp, READ_FORWARD, pos, (num < REPORTING_SIZE) ? REPORTING_SIZE : num); if (sf == NULL) return(Xen_true); sampler_set_safe(sf, num); #if HAVE_SCHEME { s7_pointer arg_list; int gc_loc; bool use_apply; s7_pointer body, e, slot; s7_pointer (*eval)(s7_scheme *sc, s7_pointer code, s7_pointer e); arg_list = xen_nil; body = xen_nil; e = xen_nil; slot = xen_nil; eval = NULL; body = s7_closure_body(s7, proc); if ((s7_is_pair(body)) && (s7_is_pair(s7_closure_args(s7, proc)))) { s7_pointer arg, expr; arg = s7_car(s7_closure_args(s7, proc)); if (s7_is_pair(arg)) arg = s7_car(arg); expr = s7_car(body); if (expr == xen_false) { free_snd_fd(sf); return(xen_false); } if (!s7_is_pair(expr)) { free_snd_fd(sf); return(s_beg); } if (s7_is_null(s7, s7_cdr(body))) { s7_pointer res; res = s7_car(body); /* try pf mechanism */ if (s7_is_symbol(s7_car(res))) { s7_pointer fcar; fcar = s7_symbol_value(s7, s7_car(res)); if (s7_pf_function(s7, fcar)) { s7_pf_t pf; s7_pointer yp, old_e, y, val; e = s7_sublet(s7, s7_closure_let(s7, proc), s7_nil(s7)); old_e = s7_set_curlet(s7, e); /* new env for scan lambda */ y = s7_make_mutable_real(s7, 1.5); /* slot for the scan lambda arg */ yp = s7_make_slot(s7, e, arg, y); val = y; s7_xf_new(s7, e); pf = s7_pf_function(s7, fcar)(s7, res); if (pf) { s7_pointer *top, *p; top = s7_xf_start(s7); for (kp = 0; kp < num; kp++) { s7_slot_set_real_value(s7, yp, read_sample(sf)); p = top; val = pf(s7, &p); if (val != s7_f(s7)) { if (counting) counts++; else { if (reporting) finish_progress_report(cp); sf = free_snd_fd(sf); s7_xf_free(s7); s7_set_curlet(s7, old_e); return(C_llong_to_Xen_llong(kp + beg)); } } } s7_xf_free(s7); sf = free_snd_fd(sf); s7_set_curlet(s7, old_e); if (counting) return(C_int_to_Xen_integer(counts)); return(val); } s7_xf_free(s7); s7_set_curlet(s7, old_e); } } } e = s7_sublet(s7, s7_closure_let(s7, proc), s7_nil(s7)); gc_loc = s7_gc_protect(s7, e); slot = s7_make_slot(s7, e, arg, s7_make_real(s7, 0.0)); use_apply = false; if (s7_is_null(s7, s7_cdr(body))) { eval = s7_eval_form; body = s7_car(body); } else eval = s7_eval; } else { /* is this for built-in funcs? */ arg_list = Xen_list_1(Xen_false); gc_loc = s7_gc_protect(s7, arg_list); use_apply = true; } /* fprintf(stderr, "scan %lld: body: %s\n", num, s7_object_to_c_string(s7, body)); */ reporting = ((num > REPORTING_SIZE) && (!(cp->squelch_update))); if (reporting) start_progress_report(cp); rpt4 = MAX_BUFFER_SIZE / 4; ss->stopped_explicitly = false; for (kp = 0; kp < num; kp++) { Xen res; if (use_apply) { s7_set_car(arg_list, s7_make_real(s7, read_sample(sf))); if (kp == 0) res = s7_call_with_location(s7, proc, arg_list, __func__, __FILE__, __LINE__); else res = s7_apply_function(s7, proc, arg_list); } else { s7_slot_set_value(s7, slot, s7_make_real(s7, read_sample(sf))); res = eval(s7, body, e); } #else for (kp = 0; kp < num; kp++) { Xen res; res = Xen_unprotected_call_with_1_arg(proc, C_double_to_Xen_real((double)read_sample(sf))); #endif /* leak here -- if reader active and error occurs, we jump out without cleanup */ /* see dynamic_wind above */ if (!Xen_is_false(res)) { if ((counting) && (Xen_is_true(res))) counts++; else { sf = free_snd_fd(sf); if (reporting) finish_progress_report(cp); #if HAVE_SCHEME s7_gc_unprotect_at(s7, gc_loc); #endif return(C_llong_to_Xen_llong(kp + beg)); } } if (reporting) { rpt++; if (rpt > rpt4) { progress_report(cp, (mus_float_t)((double)kp / (double)num)); if (!(sp->active)) { ss->stopped_explicitly = true; break; } rpt = 0; } } if (ss->stopped_explicitly) { ss->stopped_explicitly = false; status_report(sp, "%s stopped at sample %lld", caller, kp + beg); break; } } #if HAVE_SCHEME s7_gc_unprotect_at(s7, gc_loc); } #endif if (reporting) finish_progress_report(cp); sf = free_snd_fd(sf); if (counting) return(C_int_to_Xen_integer(counts)); return(Xen_false); } mus_long_t scan_channel(chan_info *cp, mus_long_t start, mus_long_t end, Xen proc) { Xen result; result = g_sp_scan(proc, C_llong_to_Xen_llong(start), C_llong_to_Xen_llong(end), Xen_false, Xen_false, "search procedure", false, C_int_to_Xen_integer(AT_CURRENT_EDIT_POSITION), 0, Xen_false); if (Xen_is_llong(result)) return(Xen_llong_to_C_llong(result)); return(-1); } #if (!HAVE_SCHEME) static Xen g_scan_chan(Xen proc, Xen beg, Xen end, Xen snd, Xen chn, Xen edpos) { #if HAVE_SCHEME #define scan_chan_example "(scan-chan (lambda (y) (> y .1)))" #endif #if HAVE_RUBY #define scan_chan_example "scan_chan(lambda do |y| y > 0.1 end)" #endif #if HAVE_FORTH #define scan_chan_example "lambda: <{ y }> y 0.1 f> ; scan-chan" #endif #define H_scan_chan "(" S_scan_chan " func :optional (start 0) (end len) snd chn edpos): \ apply 'func' to samples in current channel (or the specified channel). \ 'func' is a function of one argument, the current sample. \ if 'func' returns non-" PROC_FALSE ", the scan stops, and the current sample number is returned.\n " scan_chan_example Snd_assert_channel(S_scan_chan, snd, chn, 4); return(g_sp_scan(proc, beg, end, snd, chn, S_scan_chan, false, edpos, 6, Xen_false)); } #endif static Xen g_scan_channel(Xen proc, Xen beg, Xen dur, Xen snd, Xen chn, Xen edpos) { #if HAVE_SCHEME #define scan_channel_example "(scan-channel (lambda (y) (> y .1)))" #endif #if HAVE_RUBY #define scan_channel_example "scan_channel(lambda do |y| y > 0.1 end)" #endif #if HAVE_FORTH #define scan_channel_example "lambda: <{ y }> y 0.1 f> ; scan-channel" #endif #define H_scan_channel "(" S_scan_channel " func :optional (start 0) (dur len) snd chn edpos): \ apply func to samples in current channel (or the specified channel). \ func is a function of one argument, the current sample. \ if func returns non-" PROC_FALSE ", the scan stops, and the current sample number is returned. \n " scan_channel_example Snd_assert_channel(S_scan_channel, snd, chn, 4); return(g_sp_scan(proc, beg, Xen_false, snd, chn, S_scan_channel, false, edpos, 6, (Xen_is_bound(dur)) ? dur : Xen_false)); } #if (!HAVE_SCHEME) static Xen g_map_chan(Xen proc, Xen s_beg, Xen s_end, Xen org, Xen snd, Xen chn, Xen edpos) { #if HAVE_SCHEME #define map_chan_example "(map-chan (lambda (y) (* y 2.0)))" #endif #if HAVE_RUBY #define map_chan_example "map_chan(lambda do |y| y * 2.0 end)" #endif #if HAVE_FORTH #define map_chan_example "lambda: <{ y }> y 2.0 f* ; map-chan" #endif #define H_map_chan "(" S_map_chan " func :optional (start 0) (end len) edname snd chn edpos): \ apply func to samples in current channel; edname is the edit history name for this editing operation.\n " map_chan_example return(g_map_chan_1(proc, s_beg, s_end, org, snd, chn, edpos, Xen_false, S_map_chan)); } #endif static Xen g_map_channel(Xen proc, Xen s_beg, Xen s_dur, Xen snd, Xen chn, Xen edpos, Xen org) { #if HAVE_SCHEME #define map_channel_example "(map-channel (lambda (y) (* y 2.0)))" #endif #if HAVE_RUBY #define map_channel_example "map_channel(lambda do |y| y * 2.0 end)" #endif #if HAVE_FORTH #define map_channel_example "lambda: <{ y }> y 2.0 f* ; map-channel" #endif #define H_map_channel "(" S_map_channel " func :optional (start 0) (dur len) snd chn edpos edname): \ apply func to samples in current channel; edname is the edit history name for this editing operation.\n " map_channel_example return(g_map_chan_1(proc, s_beg, Xen_false, org, snd, chn, edpos, (Xen_is_bound(s_dur)) ? s_dur : Xen_false, S_map_channel)); } #if (!HAVE_SCHEME) static Xen g_find_channel(Xen expr, Xen sample, Xen snd, Xen chn_n, Xen edpos) { #if HAVE_SCHEME #define find_channel_example "(find-channel (lambda (y) (> y .1)))" #endif #if HAVE_RUBY #define find_channel_example "find_channel(lambda do |y| y > 0.1 end)" #endif #if HAVE_FORTH #define find_channel_example "lambda: <{ y }> y 0.1 f> ; find-channel" #endif #define H_find_channel "(" S_find_channel " func :optional (start-samp 0) snd chn edpos): apply func, a function of one argument, \ the current sample, to each sample in snd's channel chn, starting at 'start-samp' until func returns something other than " PROC_FALSE ": \n " find_channel_example /* no free here -- it's handled as ss->search_expr in snd-find.c */ Snd_assert_channel(S_find_channel, snd, chn_n, 3); return(g_sp_scan(expr, sample, Xen_false, snd, chn_n, S_find_channel, false, edpos, 5, Xen_false)); } #endif static Xen g_count_matches(Xen expr, Xen sample, Xen snd, Xen chn_n, Xen edpos) { #if HAVE_SCHEME #define count_matches_example "(count-matches (lambda (y) (> y .1)))" #endif #if HAVE_RUBY #define count_matches_example "count_matches(lambda do |y| y > 0.1 end)" #endif #if HAVE_FORTH #define count_matches_example "lambda: <{ y }> y 0.1 f> ; count-matches" #endif #define H_count_matches "(" S_count_matches " func :optional (start-samp 0) snd chn edpos): return how many \ samples satisfy func (a function of one argument, the current sample, returning " PROC_TRUE " upon match):\n " count_matches_example Snd_assert_channel(S_count_matches, snd, chn_n, 3); return(g_sp_scan(expr, sample, Xen_false, snd, chn_n, S_count_matches, true, edpos, 5, Xen_false)); } static Xen g_smooth_sound(Xen beg, Xen num, Xen snd, Xen chn_n) { #define H_smooth_sound "(" S_smooth_sound " :optional (start-samp 0) (samps len) snd chn): smooth \ data from start-samp for samps in snd's channel chn" chan_info *cp; mus_long_t start, samps; Snd_assert_sample_type(S_smooth_sound, beg, 1); Snd_assert_sample_type(S_smooth_sound, num, 2); Snd_assert_channel(S_smooth_sound, snd, chn_n, 3); cp = get_cp(snd, chn_n, S_smooth_sound); if (!cp) return(Xen_false); start = beg_to_sample(beg, S_smooth_sound); samps = dur_to_samples(num, start, cp, cp->edit_ctr, 2, S_smooth_sound); cos_smooth(cp, start, samps, OVER_SOUND); return(beg); } static Xen g_smooth_channel(Xen beg, Xen dur, Xen snd, Xen chn_n, Xen edpos) { #define H_smooth_channel "(" S_smooth_channel " :optional (beg 0) (dur len) snd chn edpos): \ smooth data from beg for dur in snd's channel chn" chan_info *cp; mus_long_t start, num; int pos; Snd_assert_sample_type(S_smooth_channel, beg, 1); Snd_assert_sample_type(S_smooth_channel, dur, 2); Snd_assert_channel(S_smooth_channel, snd, chn_n, 3); cp = get_cp(snd, chn_n, S_smooth_channel); if (!cp) return(Xen_false); pos = to_c_edit_position(cp, edpos, S_smooth_channel, 5); start = beg_to_sample(beg, S_smooth_channel); num = dur_to_samples(dur, start, cp, pos, 2, S_smooth_channel); if ((start < cp->edits[pos]->samples) && (num > 0)) smooth_channel(cp, start, num, pos); return(beg); } static Xen g_smooth_selection(void) { #define H_smooth_selection "(" S_smooth_selection "): smooth the data in the currently selected portion" chan_info *cp; if (!(selection_is_active())) return(snd_no_active_selection_error(S_smooth_selection)); cp = get_cp(Xen_false, Xen_false, S_smooth_selection); if (!cp) return(Xen_false); cos_smooth(cp, 0, 0, OVER_SELECTION); return(Xen_true); } static void cut_and_smooth_1(chan_info *cp, mus_long_t beg, mus_long_t end, bool over_selection, int pos) { #define SPLICE_LEN 32 /* making this 128 is not a big improvement */ mus_long_t start; mus_float_t splice[2 * SPLICE_LEN]; double ramp, incr; int i; snd_fd *sf, *sf_end; incr = 0.5 / SPLICE_LEN; if (end < SPLICE_LEN) start = 0; else start = end - SPLICE_LEN; sf_end = init_sample_read_any_with_bufsize(start, cp, READ_FORWARD, pos, 2 * SPLICE_LEN); if (beg < SPLICE_LEN) start = 0; else start = beg - SPLICE_LEN; sf = init_sample_read_any_with_bufsize(start, cp, READ_FORWARD, pos, 2 * SPLICE_LEN); for (i = 0, ramp = 1.0; i < 2 * SPLICE_LEN; i++, ramp -= incr) { mus_float_t x, y; x = read_sample(sf); y = read_sample(sf_end); splice[i] = (x * ramp) + (y * (1.0 - ramp)); } free_snd_fd(sf); free_snd_fd(sf_end); if (over_selection) cp_delete_selection(cp); else delete_samples(beg, end - beg + 1, cp, pos); change_samples(start, 2 * SPLICE_LEN, splice, cp, (over_selection) ? S_delete_selection_and_smooth : S_delete_samples_and_smooth, cp->edit_ctr, -1.0); } void cut_and_smooth(chan_info *cp) { if (selection_is_active_in_channel(cp)) cut_and_smooth_1(cp, selection_beg(cp), selection_end(cp), true, cp->edit_ctr); } static Xen g_delete_selection_and_smooth(void) { #define H_delete_selection_and_smooth "(" S_delete_selection_and_smooth ") deletes the current selection, and tries to \ make the splice-point smooth." if (!(selection_is_active())) return(snd_no_active_selection_error(S_delete_selection_and_smooth)); for_each_chan(cut_and_smooth); return(Xen_false); } static Xen g_delete_samples_and_smooth(Xen samp_n, Xen samps, Xen snd, Xen chn_n, Xen edpos) { #define H_delete_samples_and_smooth "(" S_delete_samples_and_smooth " start-samp samps :optional snd chn edpos): \ delete 'samps' samples from snd's channel chn starting at 'start-samp', then try to smooth-over the splice" chan_info *cp; int pos; mus_long_t samp, len; Xen_check_type(Xen_is_integer(samp_n), samp_n, 1, S_delete_samples_and_smooth, "an integer"); Xen_check_type(Xen_is_llong(samps), samps, 2, S_delete_samples_and_smooth, "an integer"); Snd_assert_channel(S_delete_samples_and_smooth, snd, chn_n, 3); cp = get_cp(snd, chn_n, S_delete_samples_and_smooth); if (!cp) return(Xen_false); pos = to_c_edit_position(cp, edpos, S_delete_samples_and_smooth, 5); samp = beg_to_sample(samp_n, S_delete_samples_and_smooth); if (samp > cp->edits[pos]->samples) Xen_out_of_range_error(S_delete_samples_and_smooth, 1, samp_n, "beyond end of sound"); len = Xen_llong_to_C_llong(samps); if (len <= 0) return(Xen_false); if (len > cp->edits[pos]->samples) len = cp->edits[pos]->samples; cut_and_smooth_1(cp, samp, samp + len - 1, false, pos); update_graph(cp); return(samp_n); } static Xen g_reverse_sound(Xen snd, Xen chn_n, Xen edpos) { #define H_reverse_sound "(" S_reverse_sound " :optional snd chn edpos): reverse snd's channel chn" chan_info *cp; Snd_assert_channel(S_reverse_sound, snd, chn_n, 1); cp = get_cp(snd, chn_n, S_reverse_sound); if (!cp) return(Xen_false); reverse_sound(cp, OVER_SOUND, edpos, 3); return(Xen_false); } static Xen g_reverse_selection(void) { #define H_reverse_selection "(" S_reverse_selection "): reverse the data in the currently selected portion" chan_info *cp; if (!(selection_is_active())) return(snd_no_active_selection_error(S_reverse_selection)); cp = get_cp(Xen_false, Xen_false, S_reverse_selection); if (!cp) return(Xen_false); reverse_sound(cp, OVER_SELECTION, C_int_to_Xen_integer(AT_CURRENT_EDIT_POSITION), 0); return(Xen_false); } static Xen g_reverse_channel(Xen s_beg, Xen s_dur, Xen snd, Xen chn_n, Xen edpos) { #define H_reverse_channel "(" S_reverse_channel " :optional (beg 0) (dur len) snd chn edpos): reverse a portion of snd's channel chn" chan_info *cp; char *errmsg; mus_long_t beg = 0, dur = 0, end; int pos; snd_fd *sf; Snd_assert_sample_type(S_reverse_channel, s_beg, 1); Snd_assert_sample_type(S_reverse_channel, s_dur, 2); Snd_assert_channel(S_reverse_channel, snd, chn_n, 3); cp = get_cp(snd, chn_n, S_reverse_channel); if (!cp) return(Xen_false); beg = beg_to_sample(s_beg, S_reverse_channel); pos = to_c_edit_position(cp, edpos, S_reverse_channel, 5); dur = dur_to_samples(s_dur, beg, cp, pos, 2, S_reverse_channel); if ((beg > cp->edits[pos]->samples) || (dur == 0)) return(Xen_false); end = beg + dur; if (end > cp->edits[pos]->samples) end = cp->edits[pos]->samples; sf = init_sample_read_any(end - 1, cp, READ_BACKWARD, pos); errmsg = reverse_channel(cp, sf, beg, end - beg, edpos, S_reverse_channel, 5); free_snd_fd(sf); if (errmsg) { Xen str; str = C_string_to_Xen_string(errmsg); free(errmsg); Xen_error(Xen_make_error_type("IO-error"), Xen_list_2(C_string_to_Xen_string(S_reverse_channel ": IO error ~A"), str)); } return(s_beg); } static Xen g_insert_silence(Xen beg, Xen num, Xen snd, Xen chn) { #define H_insert_silence "(" S_insert_silence " beg num :optional snd chn): insert num zeros at beg in snd's chn" chan_info *cp; /* follows sync */ mus_long_t start = 0, len = 0; Xen_check_type(Xen_is_integer(beg), beg, 1, S_insert_silence, "an integer"); Xen_check_type(Xen_is_integer(num), num, 2, S_insert_silence, "an integer"); Snd_assert_channel(S_insert_silence, snd, chn, 3); cp = get_cp(snd, chn, S_insert_silence); if (!cp) return(Xen_false); start = beg_to_sample(beg, S_insert_silence); len = Xen_llong_to_C_llong(num); if (len <= 0) return(Xen_false); if (len > (1LL << 34)) Xen_out_of_range_error(S_insert_silence, 2, num, "too large"); cursor_insert(cp, start, len); return(beg); } static Xen g_pad_channel(Xen beg, Xen num, Xen snd, Xen chn, Xen edpos) { #define H_pad_channel "(" S_pad_channel " beg dur :optional snd chn edpos): insert dur zeros at beg in snd's chn" chan_info *cp; mus_long_t bg, len; int pos; Xen_check_type(Xen_is_integer(beg), beg, 1, S_pad_channel, "an integer"); Xen_check_type(Xen_is_integer(num), num, 2, S_pad_channel, "an integer"); Snd_assert_channel(S_pad_channel, snd, chn, 3); cp = get_cp(snd, chn, S_pad_channel); if (!cp) return(Xen_false); bg = beg_to_sample(beg, S_pad_channel); len = Xen_llong_to_C_llong(num); if (len <= 0) return(Xen_false); /* to parallel insert-silence above -- maybe better would be an out of range error in both cases */ if (len > (1LL << 34)) Xen_out_of_range_error(S_pad_channel, 2, num, "too large"); pos = to_c_edit_position(cp, edpos, S_pad_channel, 5); if ((len > 0) && (extend_with_zeros(cp, bg, len, pos, S_pad_channel))) update_graph(cp); return(beg); } static Xen g_swap_channels(Xen snd0, Xen chn0, Xen snd1, Xen chn1, Xen beg, Xen dur, Xen edpos0, Xen edpos1) { #define H_swap_channels "(" S_swap_channels " :optional snd0 chn0 snd1 chn1 (beg 0) (dur len) edpos0 edpos1): \ swap the indicated channels" chan_info *cp0 = NULL, *cp1 = NULL; snd_info *sp = NULL; Snd_assert_channel(S_swap_channels, snd0, chn0, 1); cp0 = get_cp(snd0, chn0, S_swap_channels); if (!cp0) return(Xen_false); if (!(cp0->editable)) return(Xen_false); if (Xen_is_integer(chn1)) { Snd_assert_channel(S_swap_channels, snd1, chn1, 3); cp1 = get_cp(snd1, chn1, S_swap_channels); } else { if (Xen_is_integer(snd1) || xen_is_sound(snd1)) sp = get_sp(snd1); else sp = cp0->sound; if (sp == NULL) return(snd_no_such_sound_error(S_swap_channels, snd1)); if (cp0->sound == sp) { if ((cp0->chan + 1) < sp->nchans) cp1 = sp->chans[cp0->chan + 1]; else cp1 = sp->chans[0]; } else cp1 = sp->chans[0]; } if (cp0 == cp1) return(Xen_false); if (!(cp1->editable)) return(Xen_false); if ((cp0) && (cp1)) { int pos0, pos1; mus_long_t dur0, dur1, beg0 = 0, num; if (Xen_is_integer(beg)) beg0 = Xen_llong_to_C_llong(beg); pos0 = to_c_edit_position(cp0, edpos0, S_swap_channels, 7); pos1 = to_c_edit_position(cp1, edpos1, S_swap_channels, 8); dur0 = cp0->edits[pos0]->samples; dur1 = cp1->edits[pos1]->samples; if (Xen_is_integer(dur)) num = Xen_llong_to_C_llong(dur); else { if (dur0 > dur1) num = dur0; else num = dur1; /* was min here 13-Dec-02 */ } if ((beg0 != 0) || ((num != dur0) && (num != dur1))) /* if just a section being swapped, use readers */ swap_channels(cp0, cp1, beg0, num, pos0, pos1); else { if ((pos0 == 0) && (pos1 == 0)) { /* common special case -- just setup a new ed-list entry with the channels/sounds swapped */ if ((dur0 == 0) && (dur1 == 0)) return(Xen_false); if ((is_editable(cp0)) && (is_editable(cp1))) { peak_env_info *e0, *e1; e0 = peak_env_copy(cp0, false, cp0->edit_ctr); e1 = peak_env_copy(cp1, false, cp1->edit_ctr); file_override_samples(dur1, cp1->sound->filename, cp0, cp1->chan, DONT_DELETE_ME, S_swap_channels); file_override_samples(dur0, cp0->sound->filename, cp1, cp0->chan, DONT_DELETE_ME, S_swap_channels); cp0->edits[cp0->edit_ctr]->peak_env = e1; /* can be NULL */ cp1->edits[cp1->edit_ctr]->peak_env = e0; swap_marks(cp0, cp1); update_graph(cp0); update_graph(cp1); } } else { /* look for simple cases where copying the current edit tree entry is not too hard */ if ((num < FILE_BUFFER_SIZE) || (sound_fragments_in_use(cp0, pos0)) || (sound_fragments_in_use(cp1, pos1))) swap_channels(cp0, cp1, beg0, num, pos0, pos1); else copy_then_swap_channels(cp0, cp1, pos0, pos1); /* snd-edits.c */ } } } return(Xen_false); } static mus_float_t *load_mus_float_ts(Xen scalers, int *result_len, const char *caller) { int len = 0, i; mus_float_t *scls; vct *v = NULL; if (Xen_is_number(scalers)) len = 1; else { if (mus_is_vct(scalers)) { v = Xen_to_vct(scalers); len = mus_vct_length(v); } else { if (Xen_is_list(scalers)) { len = Xen_list_length(scalers); if (len < 0) Xen_wrong_type_arg_error(caller, 1, scalers, "a proper list"); } else Xen_wrong_type_arg_error(caller, 1, scalers, "a number, list, or " S_vct); } if (len == 0) Xen_error(NO_DATA, Xen_list_2(C_string_to_Xen_string("~A: scalers data is empty?"), C_string_to_Xen_string(caller))); } scls = (mus_float_t *)calloc(len, sizeof(mus_float_t)); if (v) memcpy((void *)scls, (void *)(mus_vct_data(v)), len * sizeof(mus_float_t)); else { if (Xen_is_list(scalers)) { Xen lst; for (i = 0, lst = Xen_copy_arg(scalers); i < len; i++, lst = Xen_cdr(lst)) scls[i] = (mus_float_t)Xen_real_to_C_double(Xen_car(lst)); } else scls[0] = (mus_float_t)Xen_real_to_C_double(scalers); } result_len[0] = len; return(scls); } static Xen g_scale_to(Xen scalers, Xen snd, Xen chn_n) { #define H_scale_to "(" S_scale_to " :optional (norms 1.0) snd chn): \ normalize snd to norms (following sync); norms can be a float or a " S_vct "/list of floats" /* chn_n irrelevant if sync */ chan_info *cp; bool happy; int len[1]; mus_float_t *scls; Snd_assert_channel(S_scale_to, snd, chn_n, 2); cp = get_cp(snd, chn_n, S_scale_to); if (!cp) return(Xen_false); scls = load_mus_float_ts(scalers, len, S_scale_to); happy = scale_to(cp->sound, cp, scls, len[0], OVER_SOUND); free(scls); if (happy) return(scalers); return(Xen_false); } static Xen g_scale_by(Xen scalers, Xen snd, Xen chn_n) { #define H_scale_by "(" S_scale_by " scalers :optional snd chn): \ scale snd by scalers (following sync); scalers can be a float or a " S_vct "/list of floats" /* chn_n irrelevant if sync */ chan_info *cp; int len[1]; mus_float_t *scls; Snd_assert_channel(S_scale_by, snd, chn_n, 2); cp = get_cp(snd, chn_n, S_scale_by); if (!cp) return(Xen_false); len[0] = 0; /* fprintf(stderr, "(scale-by %s %s %s)\n", Xen_object_to_C_string(scalers), Xen_object_to_C_string(snd), Xen_object_to_C_string(chn_n)); */ scls = load_mus_float_ts(scalers, len, S_scale_by); if (len[0] == 0) { /* fprintf(stderr, "len is 0\n"); */ return(Xen_false); } scale_by(cp, scls, len[0], OVER_SOUND); free(scls); return(scalers); } static Xen g_scale_selection_to(Xen scalers) { #define H_scale_selection_to "(" S_scale_selection_to " norms): normalize selected portion to norms" if (selection_is_active()) { int len[1]; bool happy; mus_float_t *scls; scls = load_mus_float_ts(scalers, len, S_scale_selection_to); happy = scale_to(NULL, NULL, scls, len[0], OVER_SELECTION); free(scls); if (happy) return(scalers); return(Xen_false); } return(snd_no_active_selection_error(S_scale_selection_to)); } Xen g_scale_selection_by(Xen scalers) { #define H_scale_selection_by "(" S_scale_selection_by " scalers): scale selected portion by scalers" if (selection_is_active()) { int len[1]; mus_float_t *scls; scls = load_mus_float_ts(scalers, len, S_scale_selection_by); scale_by(NULL, scls, len[0], OVER_SELECTION); free(scls); return(scalers); } return(snd_no_active_selection_error(S_scale_selection_by)); } static Xen g_clm_channel(Xen gen, Xen samp_n, Xen samps, Xen snd, Xen chn_n, Xen edpos, Xen overlap, Xen origin) { #define H_clm_channel "(" S_clm_channel " gen :optional (beg 0) (dur len) snd chn edpos (overlap 0) origin): \ apply gen to snd's channel chn starting at beg for dur samples. overlap is the 'ring' time, if any." chan_info *cp; mus_long_t beg = 0, dur = 0; int pos; mus_any *egen; char *errmsg = NULL, *caller = NULL; Snd_assert_sample_type(S_clm_channel, samp_n, 2); Snd_assert_sample_type(S_clm_channel, samps, 3); Xen_check_type(Xen_is_integer(overlap) || Xen_is_false(overlap) || !Xen_is_bound(overlap), overlap, 7, S_clm_channel, "an integer or " PROC_FALSE); Xen_check_type(Xen_is_string_or_unbound(origin), origin, 8, S_clm_channel, "a string"); Snd_assert_channel(S_clm_channel, snd, chn_n, 4); cp = get_cp(snd, chn_n, S_clm_channel); if (!cp) return(Xen_false); pos = to_c_edit_position(cp, edpos, S_clm_channel, 6); beg = beg_to_sample(samp_n, S_clm_channel); dur = dur_to_samples(samps, beg, cp, pos, 3, S_clm_channel); if (dur == 0) return(Xen_false); Xen_check_type(mus_is_xen(gen), gen, 1, S_clm_channel, "a clm generator"); egen = Xen_to_mus_any(gen); if (Xen_is_string(origin)) caller = mus_strdup(Xen_string_to_C_string(origin)); else caller = mus_strdup(S_clm_channel); errmsg = clm_channel(cp, egen, beg, dur, pos, (Xen_is_llong(overlap)) ? Xen_llong_to_C_llong(overlap) : 0, caller); free(caller); if (errmsg) { Xen str; str = C_string_to_Xen_string(errmsg); free(errmsg); Xen_error(Xen_make_error_type("IO-error"), Xen_list_2(C_string_to_Xen_string(S_clm_channel ": IO error ~A"), str)); } return(gen); } static Xen g_apply_env_1(Xen edata, mus_long_t beg, mus_long_t dur, Xen ebase, chan_info *cp, Xen edpos, const char *caller, bool over_selection) { if (Xen_is_list(edata)) { env *e; e = get_env(edata, caller); if (e) { if (Xen_is_number(ebase)) { /* env 'e' is a temp here, so we can clobber its base, etc */ e->base = Xen_real_to_C_double(ebase); if (e->base < 0.0) { free_env(e); Xen_out_of_range_error(caller, 4, ebase, "base < 0.0?"); } } apply_env(cp, e, beg, dur, over_selection, caller, NULL, edpos, 7); free_env(e); return(edata); } } else { mus_any *egen = NULL; Xen_check_type((mus_is_xen(edata)) && (mus_is_env(egen = Xen_to_mus_any(edata))), edata, 1, caller, "an env generator or a list"); apply_env(cp, NULL, beg, dur, over_selection, caller, egen, edpos, 7); return(edata); } return(Xen_false); } static Xen g_env_selection(Xen edata, Xen base) { #define H_env_selection "(" S_env_selection " env :optional (env-base 1.0)): \ apply envelope to the selection using env-base to determine how breakpoints are connected" if (!(selection_is_active())) return(snd_no_active_selection_error(S_env_selection)); return(g_apply_env_1(edata, 0, 0, base, get_cp(Xen_false, Xen_false, S_env_selection), C_int_to_Xen_integer(AT_CURRENT_EDIT_POSITION), S_env_selection, OVER_SELECTION)); } static Xen g_env_sound(Xen edata, Xen samp_n, Xen samps, Xen base, Xen snd, Xen chn_n, Xen edpos) { #define H_env_sound "(" S_env_sound " env :optional (start-samp 0) (samps len) (env-base 1.0) snd chn edpos): \ apply amplitude envelope (a list of breakpoints or a CLM env) to snd's channel chn starting at start-samp, going \ either to the end of the sound or for samps samples, with segments interpolating according to env-base" mus_long_t beg = 0, dur = 0; int pos; chan_info *cp; Snd_assert_sample_type(S_env_sound, samp_n, 2); Snd_assert_sample_type(S_env_sound, samps, 3); Snd_assert_channel(S_env_sound, snd, chn_n, 5); cp = get_cp(snd, chn_n, S_env_sound); if (!cp) return(Xen_false); pos = to_c_edit_position(cp, edpos, S_env_sound, 7); beg = beg_to_sample(samp_n, S_env_sound); dur = dur_to_samples(samps, beg, cp, pos, 3, S_env_sound); return(g_apply_env_1(edata, beg, dur, base, cp, edpos, S_env_sound, OVER_SOUND)); } static Xen g_env_channel(Xen gen, Xen samp_n, Xen samps, Xen snd, Xen chn_n, Xen edpos) { #define H_env_channel "(" S_env_channel " clm-env-gen-or-envelope :optional (beg 0) (dur len) snd chn edpos): \ apply amplitude envelope to snd's channel chn starting at beg for dur samples." chan_info *cp; snd_info *sp; mus_long_t beg = 0, dur; int old_sync = 0, pos; Xen val; Snd_assert_sample_type(S_env_channel, samp_n, 2); Snd_assert_sample_type(S_env_channel, samps, 3); Snd_assert_channel(S_env_channel, snd, chn_n, 4); cp = get_cp(snd, chn_n, S_env_channel); if (!cp) return(Xen_false); beg = beg_to_sample(samp_n, S_env_channel); pos = to_c_edit_position(cp, edpos, S_env_channel, 6); dur = dur_to_samples(samps, beg, cp, pos, 3, S_env_channel); if (dur == 0) return(Xen_false); if (beg > cp->edits[pos]->samples) return(Xen_false); /* not redundant */ sp = cp->sound; old_sync = sp->sync; sp->sync = 0; val = g_apply_env_1(gen, beg, dur, Xen_false, cp, edpos, S_env_channel, OVER_SOUND); sp->sync = old_sync; return(val); } static Xen g_env_channel_with_base(Xen gen, Xen base, Xen samp_n, Xen samps, Xen snd, Xen chn_n, Xen edpos) { #define H_env_channel_with_base "(" S_env_channel_with_base " clm-env-gen-or-envelope :optional (base 1.0) (beg 0) (dur len) snd chn edpos): \ apply amplitude envelope to snd's channel chn starting at beg for dur samples." chan_info *cp; snd_info *sp; mus_long_t beg = 0, dur; int old_sync = 0, pos; Xen val; Snd_assert_sample_type(S_env_channel, samp_n, 2); Snd_assert_sample_type(S_env_channel, samps, 3); Snd_assert_channel(S_env_channel, snd, chn_n, 4); cp = get_cp(snd, chn_n, S_env_channel); if (!cp) return(Xen_false); beg = beg_to_sample(samp_n, S_env_channel); pos = to_c_edit_position(cp, edpos, S_env_channel, 6); dur = dur_to_samples(samps, beg, cp, pos, 3, S_env_channel); if (dur == 0) return(Xen_false); if (beg > cp->edits[pos]->samples) return(Xen_false); /* not redundant */ sp = cp->sound; old_sync = sp->sync; sp->sync = 0; val = g_apply_env_1(gen, beg, dur, base, cp, edpos, S_env_channel, OVER_SOUND); sp->sync = old_sync; return(val); } static Xen g_ramp_channel(Xen rmp0, Xen rmp1, Xen beg, Xen num, Xen snd, Xen chn, Xen edpos) { #define H_ramp_channel "(" S_ramp_channel " rmp0 rmp1 :optional (beg 0) (dur len) snd chn edpos): \ scale samples in the given sound/channel between beg and beg + num by a ramp going from rmp0 to rmp1." chan_info *cp; mus_long_t samp, samps; int pos; double seg0, seg1; Xen_check_type(Xen_is_number(rmp0), rmp0, 1, S_ramp_channel, "a number"); Xen_check_type(Xen_is_number(rmp1), rmp1, 2, S_ramp_channel, "a number"); Snd_assert_sample_type(S_ramp_channel, beg, 3); Snd_assert_sample_type(S_ramp_channel, num, 4); Snd_assert_sound(S_ramp_channel, snd, 5); samp = beg_to_sample(beg, S_ramp_channel); cp = get_cp(snd, chn, S_ramp_channel); if (!cp) return(Xen_false); pos = to_c_edit_position(cp, edpos, S_ramp_channel, 7); samps = dur_to_samples(num, samp, cp, pos, 4, S_ramp_channel); if (unrampable(cp, samp, samps, pos, false)) /* false - not xramp */ { snd_info *sp; int old_sync; Xen val; sp = cp->sound; old_sync = sp->sync; sp->sync = 0; val = g_apply_env_1(Xen_list_4(C_double_to_Xen_real(0.0), rmp0, C_double_to_Xen_real(1.0), rmp1), samp, samps, C_double_to_Xen_real(1.0), cp, edpos, S_ramp_channel, false); sp->sync = old_sync; return(val); } seg0 = Xen_real_to_C_double(rmp0); seg1 = Xen_real_to_C_double(rmp1); if (ramp_channel(cp, seg0, (seg1 - seg0) / (double)(samps - 1), samp, samps, pos, NOT_IN_AS_ONE_EDIT)) { if (cp->edits[pos]->peak_env) { mus_float_t data[4]; data[0] = 0.0; data[1] = seg0; data[2] = 1.0; data[3] = seg1; if ((samp == 0) && (samps >= cp->edits[pos]->samples)) amp_env_env(cp, data, 2, pos, 1.0, 1.0, 0.0); else { mus_any *egen; egen = mus_make_env(data, 2, 1.0, 0.0, 1.0, 0.0, samps - 1, NULL); amp_env_env_selection_by(cp, egen, samp, samps, pos); mus_free(egen); } } update_graph(cp); } return(rmp0); } static Xen g_xramp_channel(Xen rmp0, Xen rmp1, Xen base, Xen beg, Xen num, Xen snd, Xen chn, Xen edpos) { #define H_xramp_channel "(" S_xramp_channel " rmp0 rmp1 base :optional (beg 0) (dur len) snd chn edpos): \ scale samples in the given sound/channel between beg and beg + num by an exponential ramp going from rmp0 to rmp1 with curvature set by base." chan_info *cp; mus_long_t samp, samps; int pos; mus_float_t ebase = 1.0; Xen_check_type(Xen_is_number(rmp0), rmp0, 1, S_xramp_channel, "a number"); Xen_check_type(Xen_is_number(rmp1), rmp1, 2, S_xramp_channel, "a number"); Xen_check_type(Xen_is_number(base), base, 3, S_xramp_channel, "a number"); Snd_assert_sample_type(S_xramp_channel, beg, 4); Snd_assert_sample_type(S_xramp_channel, num, 5); Snd_assert_sound(S_xramp_channel, snd, 6); samp = beg_to_sample(beg, S_xramp_channel); cp = get_cp(snd, chn, S_xramp_channel); if (!cp) return(Xen_false); pos = to_c_edit_position(cp, edpos, S_xramp_channel, 8); samps = dur_to_samples(num, samp, cp, pos, 4, S_xramp_channel); ebase = Xen_real_to_C_double(base); if (ebase < 0.0) Xen_out_of_range_error(S_xramp_channel, 3, base, "base < 0.0?"); if (ebase > 1.0e10) Xen_out_of_range_error(S_xramp_channel, 3, base, "base too large"); if (unrampable(cp, samp, samps, pos, (ebase != 1.0))) { snd_info *sp; int old_sync; Xen val; sp = cp->sound; old_sync = sp->sync; sp->sync = 0; val = g_apply_env_1(Xen_list_4(C_double_to_Xen_real(0.0), rmp0, C_double_to_Xen_real(1.0), rmp1), samp, samps, base, cp, edpos, S_xramp_channel, false); sp->sync = old_sync; return(val); } else { double seg0; seg0 = Xen_real_to_C_double(rmp0); if (ebase == 0.0) scale_channel(cp, seg0, samp, samps, pos, NOT_IN_AS_ONE_EDIT); else { double seg1; seg1 = Xen_real_to_C_double(rmp1); if (ebase == 1.0) ramp_channel(cp, seg0, (seg1 - seg0) / (double)(samps - 1), samp, samps, pos, NOT_IN_AS_ONE_EDIT); else { mus_any *e; mus_float_t *data; mus_float_t *rates; data = (mus_float_t *)malloc(4 * sizeof(mus_float_t)); data[0] = 0.0; data[1] = seg0; data[2] = 1.0; data[3] = seg1; e = mus_make_env(data, 2, 1.0, 0.0, ebase, 0.0, samps - 1, NULL); rates = mus_env_rates(e); if (xramp_channel(cp, mus_env_initial_power(e), rates[0], mus_env_scaler(e), mus_env_offset(e), samp, samps, pos, NOT_IN_AS_ONE_EDIT, e, 0)) { if (cp->edits[pos]->peak_env) { if ((samp == 0) && (samps >= cp->edits[pos]->samples)) amp_env_env(cp, data, 2, pos, ebase, mus_env_scaler(e), mus_env_offset(e)); else { mus_any *egen; egen = mus_make_env(data, 2, 1.0, 0.0, ebase, 0.0, samps - 1, NULL); amp_env_env_selection_by(cp, egen, samp, samps, pos); mus_free(egen); } } } free(data); mus_free(e); update_graph(cp); } } } return(rmp0); } static Xen g_fft(Xen reals, Xen imag, Xen sign) { #define H_fft "(" S_fft " reals imags :optional (sign 1)): fft the data returning the result in reals. \ If sign is -1, perform inverse fft. Incoming data is in " S_vct "s." vct *v1 = NULL, *v2 = NULL; int n = 0, n2 = 0, isign = 1; bool need_free = false; mus_float_t *rl = NULL, *im = NULL; Xen_check_type(Xen_is_integer_or_unbound(sign), sign, 3, S_fft, "an integer"); Xen_check_type(mus_is_vct(reals), reals, 1, S_fft, S_vct); Xen_check_type(mus_is_vct(imag), imag, 2, S_fft, S_vct); isign = (Xen_is_integer(sign)) ? Xen_integer_to_C_int(sign) : 1; v1 = Xen_to_vct(reals); v2 = Xen_to_vct(imag); n = mus_vct_length(v1); if (mus_vct_length(v2) < n) n = mus_vct_length(v2); if (n == 0) return(Xen_integer_zero); if (is_power_of_2(n)) { n2 = n; rl = mus_vct_data(v1); im = mus_vct_data(v2); } else { int ipow; ipow = (int)ceil(log(n + 1) / log(2.0)); /* ceil because we're assuming below that n2 >= n */ n2 = snd_int_pow2(ipow); rl = (mus_float_t *)calloc(n2, sizeof(mus_float_t)); im = (mus_float_t *)calloc(n2, sizeof(mus_float_t)); need_free = true; memcpy((void *)rl, (void *)(mus_vct_data(v1)), n * sizeof(mus_float_t)); memcpy((void *)im, (void *)(mus_vct_data(v2)), n * sizeof(mus_float_t)); } mus_fft(rl, im, n2, isign); if (need_free) { memcpy((void *)(mus_vct_data(v1)), (void *)rl, n * sizeof(mus_float_t)); memcpy((void *)(mus_vct_data(v2)), (void *)im, n * sizeof(mus_float_t)); free(rl); free(im); } return(reals); } static Xen g_snd_spectrum(Xen data, Xen win, Xen len, Xen linear_or_dB, Xen beta, Xen in_place, Xen normalized) { #define H_snd_spectrum "(" S_snd_spectrum " data :optional (window " S_rectangular_window ") (len data-len) (linear " PROC_TRUE ") (beta 0.0) in-place (normalized " PROC_TRUE ")): \ magnitude spectrum of data (a " S_vct "), in data if in-place, using fft-window win and fft length len." bool linear = true, in_data = false, normed = true; int i, n, n2, wtype; mus_float_t maxa, lowest, b = 0.0; mus_float_t *rdat; vct *v; Xen_check_type((mus_is_vct(data)), data, 1, S_snd_spectrum, "a " S_vct); Xen_check_type(Xen_is_integer_or_unbound(win), win, 2, S_snd_spectrum, "an integer"); Xen_check_type(Xen_is_integer_or_unbound(len), len, 3, S_snd_spectrum, "an integer"); Xen_check_type(Xen_is_boolean_or_unbound(linear_or_dB), linear_or_dB, 4, S_snd_spectrum, "a boolean"); Xen_check_type(Xen_is_number_or_unbound(beta), beta, 5, S_snd_spectrum, "a number"); Xen_check_type(Xen_is_boolean_or_unbound(in_place), in_place, 6, S_snd_spectrum, "a boolean"); Xen_check_type(Xen_is_boolean_or_unbound(normalized), normalized, 7, S_snd_spectrum, "a boolean"); v = Xen_to_vct(data); n = (Xen_is_integer(len)) ? Xen_integer_to_C_int(len) : mus_vct_length(v); if (n > mus_vct_length(v)) n = mus_vct_length(v); if (n <= 0) Xen_out_of_range_error(S_snd_spectrum, 3, len, "length <= 0 or " S_vct " length == 0?"); if (Xen_is_boolean(linear_or_dB)) linear = Xen_boolean_to_C_bool(linear_or_dB); if (Xen_is_boolean(in_place)) in_data = Xen_boolean_to_C_bool(in_place); if (Xen_is_boolean(normalized)) normed = Xen_boolean_to_C_bool(normalized); wtype = (Xen_is_integer(win)) ? Xen_integer_to_C_int(win) : (int)MUS_RECTANGULAR_WINDOW; if (!(mus_is_fft_window(wtype))) Xen_out_of_range_error(S_snd_spectrum, 2, win, "unknown fft window"); if (Xen_is_number(beta)) b = Xen_real_to_C_double(beta); if (b < 0.0) b = 0.0; else if (b > 1.0) b = 1.0; if (!in_data) { mus_float_t *vdata; vdata = mus_vct_data(v); rdat = (mus_float_t *)malloc(n * sizeof(mus_float_t)); if (n < mus_vct_length(v)) for (i = 0; i < n; i++) rdat[i] = vdata[i]; else memcpy((void *)rdat, (void *)vdata, mus_vct_length(v) * sizeof(mus_float_t)); } else rdat = mus_vct_data(v); if (wtype != (int)MUS_RECTANGULAR_WINDOW) { mus_float_t *window; window = (mus_float_t *)calloc(n, sizeof(mus_float_t)); mus_make_fft_window_with_window((mus_fft_window_t)wtype, n, b * fft_beta_max((mus_fft_window_t)wtype), 0.0, window); for (i = 0; i < n; i++) rdat[i] *= window[i]; free(window); } n2 = n / 2; { int j; mus_float_t *idat; idat = (mus_float_t *)calloc(n, sizeof(mus_float_t)); mus_fft(rdat, idat, n, 1); rdat[0] *= rdat[0]; rdat[n2] *= rdat[n2]; for (i = 1, j = n - 1; i < n2; i++, j--) { rdat[i] = rdat[i] * rdat[i] + idat[i] * idat[i]; rdat[j] = rdat[i]; } free(idat); } lowest = 0.000001; maxa = 0.0; n = n / 2; for (i = 0; i < n; i++) { mus_float_t val; val = rdat[i]; if (val < lowest) rdat[i] = 0.0; else { rdat[i] = sqrt(val); if (rdat[i] > maxa) maxa = rdat[i]; } } if (maxa > 0.0) { if (normed) maxa = 1.0 / maxa; else maxa = 1.0; if (!linear) /* dB */ { mus_float_t todb; todb = 20.0 / log(10.0); for (i = 0; i < n; i++) if (rdat[i] > 0.0) rdat[i] = todb * log(rdat[i] * maxa); else rdat[i] = -90.0; /* min_dB(ss)? or could channel case be less? */ } else { if (normed) for (i = 0; i < n; i++) rdat[i] *= maxa; } } if (in_data) return(data); return(xen_make_vct(n, rdat)); /* xen_make_vct uses the data array directly (frees upon gc) */ } static Xen g_convolve_with_1(Xen file, Xen new_amp, chan_info *cp, Xen edpos, const char *caller) { /* cp NULL -> selection (see above) */ mus_float_t amp; static char *fname = NULL; Xen_check_type(Xen_is_string(file), file, 1, caller, "a string"); if (Xen_is_number(new_amp)) amp = Xen_real_to_C_double(new_amp); else { if (Xen_is_false(new_amp)) amp = 0.0; else amp = 1.0; } if (fname) free(fname); fname = mus_expand_filename(Xen_string_to_C_string(file)); if (mus_file_probe(fname)) { char *error = NULL; error = convolve_with_or_error(fname, amp, cp, edpos, 5); if (error) { Xen errstr; errstr = C_string_to_Xen_string(error); free(error); Xen_error(Xen_make_error_type("IO-error"), Xen_list_3(C_string_to_Xen_string("~A: IO error ~A"), C_string_to_Xen_string(caller), errstr)); } } else return(snd_no_such_file_error(caller, file)); return(file); } static Xen g_convolve_with(Xen file, Xen new_amp, Xen snd, Xen chn_n, Xen edpos) { #define H_convolve_with "(" S_convolve_with " file :optional (amp 1.0) snd chn edpos): \ convolve file with snd's channel chn (or the currently sync'd channels); amp is the resultant peak amp" chan_info *cp; Snd_assert_channel(S_convolve_with, snd, chn_n, 3); cp = get_cp(snd, chn_n, S_convolve_with); if (!cp) return(Xen_false); return(g_convolve_with_1(file, new_amp, cp, edpos, S_convolve_with)); } static Xen g_convolve_selection_with(Xen file, Xen new_amp) { #define H_convolve_selection_with "(" S_convolve_selection_with " file :optional (amp 1.0)): \ convolve the selection with file; amp is the resultant peak amp" if (!(selection_is_active())) return(snd_no_active_selection_error(S_convolve_selection_with)); return(g_convolve_with_1(file, new_amp, NULL, C_int_to_Xen_integer(AT_CURRENT_EDIT_POSITION), S_convolve_selection_with)); } enum {SRC_ENV_NO_ERROR, SRC_ENV_HIT_ZERO, SRC_ENV_THROUGH_ZERO}; static mus_float_t check_src_envelope(int pts, mus_float_t *data, int *error) { /* can't go through zero here, and if negative need to return 1.0 */ int i; mus_float_t res = 0.0; (*error) = SRC_ENV_NO_ERROR; for (i = 0; i < (2 * pts); i += 2) if (data[i + 1] == 0.0) { (*error) = SRC_ENV_HIT_ZERO; return(res); } else { if (data[i + 1] < 0.0) { if (res <= 0.0) res = -1.0; else { (*error) = SRC_ENV_THROUGH_ZERO; return(res); } } else { if (res >= 0) res = 1.0; else { (*error) = SRC_ENV_THROUGH_ZERO; return(res); } } } return(res); } static bool is_NaN(double x) {return(x != x);} static Xen g_src_channel(Xen ratio_or_env, Xen beg_n, Xen dur_n, Xen snd, Xen chn_n, Xen edpos) { #define H_src_channel "(" S_src_channel " ratio-or-env :optional (beg 0) (dur len) snd chn edpos): \ sampling-rate convert snd's channel chn by ratio, or following an envelope (a list or a CLM env generator)." chan_info *cp; char *errmsg; snd_fd *sf; mus_long_t beg, dur; int pos; bool clm_err = false; mus_any *egen = NULL; bool need_free = false; mus_float_t ratio = 0.0; /* not 1.0 here! -- the zero is significant */ env *e = NULL; Xen_check_type((Xen_is_number(ratio_or_env)) || (Xen_is_list(ratio_or_env)) || ((mus_is_xen(ratio_or_env)) && (mus_is_env(egen = Xen_to_mus_any(ratio_or_env)))), ratio_or_env, 1, S_src_channel, "a number, an envelope, or a CLM env generator"); Snd_assert_sample_type(S_src_channel, beg_n, 2); Snd_assert_sample_type(S_src_channel, dur_n, 3); Snd_assert_channel(S_src_channel, snd, chn_n, 4); cp = get_cp(snd, chn_n, S_src_channel); if (!cp) return(Xen_false); beg = beg_to_sample(beg_n, S_src_channel); pos = to_c_edit_position(cp, edpos, S_src_channel, 6); dur = dur_to_samples(dur_n, beg, cp, pos, 3, S_src_channel); if (dur == 0) return(Xen_false); if (beg > cp->edits[pos]->samples) return(Xen_false); if (Xen_is_number(ratio_or_env)) { ratio = Xen_real_to_C_double(ratio_or_env); if ((pos == cp->edit_ctr) && ((ratio == 0.0) || (ratio == 1.0))) return(Xen_false); if ((is_NaN(ratio)) || (fabs(ratio) < 1.0e-10)) /* dur > 0 here */ Xen_out_of_range_error(S_src_channel, 1, ratio_or_env, "too small (resultant sound will be too large)"); } else { int error = SRC_ENV_NO_ERROR; if (egen == NULL) { e = get_env(ratio_or_env, S_src_channel); egen = mus_make_env(e->data, e->pts, 1.0, 0.0, e->base, 0.0, dur - 1, NULL); need_free = true; } check_src_envelope(mus_env_breakpoints(egen), mus_data(egen), &error); if (error != SRC_ENV_NO_ERROR) { Xen data; if (e) free_env(e); data = mus_array_to_list(mus_data(egen), 0, mus_env_breakpoints(egen) * 2); if (need_free) mus_free(egen); if (error == SRC_ENV_HIT_ZERO) Xen_out_of_range_error(S_src_channel, 1, data, "envelope hits 0.0"); else Xen_out_of_range_error(S_src_channel, 1, data, "envelope passes through 0.0"); return(Xen_false); /* just for clarity... */ } } if (((egen) && (mus_phase(egen) >= 0.0)) || ((!egen) && (ratio >= 0.0))) /* ratio == 0.0 if env in use because env is the srate (as change arg) */ sf = init_sample_read_any_with_bufsize(beg, cp, READ_FORWARD, pos, (!egen) ? MAX_BUFFER_SIZE : FILE_BUFFER_SIZE); else sf = init_sample_read_any(beg + dur - 1, cp, READ_BACKWARD, pos); errmsg = src_channel_with_error(cp, sf, beg, dur, ratio, egen, S_src_channel, OVER_SOUND, &clm_err); sf = free_snd_fd(sf); if (need_free) mus_free(egen); if (e) free_env(e); if (errmsg) { Xen err; err = C_string_to_Xen_string(errmsg); free(errmsg); Xen_error(Xen_make_error_type((clm_err) ? "mus-error" : "IO-error"), Xen_list_2(C_string_to_Xen_string(S_src_channel ": ~A"), err)); } return(ratio_or_env); } #if (defined(__sun) && defined(__SVR4)) static bool is_inf(s7_double x) {return((x == x) && (is_NaN(x - x)));} /* there's no isinf in Solaris */ #else #define is_inf(x) isinf(x) #endif static Xen g_src_1(Xen ratio_or_env, Xen ebase, Xen snd, Xen chn_n, Xen edpos, const char *caller, bool over_selection) { chan_info *cp; Snd_assert_channel(caller, snd, chn_n, 3); cp = get_cp(snd, chn_n, caller); if (!cp) return(Xen_false); if (Xen_is_number(ratio_or_env)) { mus_float_t ratio; ratio = Xen_real_to_C_double(ratio_or_env); if ((is_NaN(ratio)) || (is_inf(ratio))) Xen_out_of_range_error(caller, 1, ratio_or_env, "src ratio must be a normal number"); if (ratio != 1.0) src_env_or_num(cp, NULL, ratio, true, caller, over_selection, NULL, edpos, 5); } else { int error = SRC_ENV_NO_ERROR; if (Xen_is_list(ratio_or_env)) { env *e = NULL; mus_float_t e_ratio = 1.0; /* env 'e' is a temp here, so we can clobber its base, etc */ e = get_env(ratio_or_env, caller); if (Xen_is_number(ebase)) e->base = Xen_real_to_C_double(ebase); e_ratio = check_src_envelope(e->pts, e->data, &error); if (error != SRC_ENV_NO_ERROR) { Xen data; data = mus_array_to_list(e->data, 0, e->pts * 2); free_env(e); if (error == SRC_ENV_HIT_ZERO) Xen_out_of_range_error(caller, 1, data, "envelope hits 0.0"); else Xen_out_of_range_error(caller, 1, data, "envelope passes through 0.0"); } else { src_env_or_num(cp, e, e_ratio, false, caller, over_selection, NULL, edpos, 5); free_env(e); } } else { mus_any *egen; Xen_check_type(mus_is_xen(ratio_or_env), ratio_or_env, 1, caller, "a number, list, or env generator"); egen = Xen_to_mus_any(ratio_or_env); Xen_check_type(mus_is_env(egen), ratio_or_env, 1, caller, "a number, list, or env generator"); check_src_envelope(mus_env_breakpoints(egen), mus_data(egen), &error); if (error != SRC_ENV_NO_ERROR) { Xen data; data = mus_array_to_list(mus_data(egen), 0, mus_env_breakpoints(egen) * 2); if (error == SRC_ENV_HIT_ZERO) Xen_out_of_range_error(S_src_channel, 1, data, "envelope hits 0.0"); else Xen_out_of_range_error(S_src_channel, 1, data, "envelope passes through 0.0"); } else src_env_or_num(cp, NULL, (mus_phase(egen) >= 0.0) ? 1.0 : -1.0, /* mus_phase of env apparently = current_value(!) */ false, caller, over_selection, egen, edpos, 5); } } return(ratio_or_env); } static Xen g_src_sound(Xen ratio_or_env, Xen base, Xen snd, Xen chn_n, Xen edpos) { #define H_src_sound "(" S_src_sound " ratio-or-env :optional (base 1.0) snd chn edpos): \ sampling-rate convert snd's channel chn by ratio, or following an envelope. A negative ratio reverses the sound" return(g_src_1(ratio_or_env, base, snd, chn_n, edpos, S_src_sound, OVER_SOUND)); } static Xen g_src_selection(Xen ratio_or_env, Xen base) { #define H_src_selection "(" S_src_selection " ratio-or-env :optional (base 1.0)): \ sampling-rate convert the currently selected data by ratio (which can be an envelope)" if (!(selection_is_active())) return(snd_no_active_selection_error(S_src_selection)); return(g_src_1(ratio_or_env, base, Xen_false, Xen_false, C_int_to_Xen_integer(AT_CURRENT_EDIT_POSITION), S_src_selection, OVER_SELECTION)); } static Xen g_filter_channel(Xen e, Xen order, Xen beg, Xen dur, Xen snd, Xen chn_n, Xen edpos, Xen truncate, Xen origin) { #define H_filter_channel "(" S_filter_channel " env :optional order beg dur snd chn edpos (truncate " PROC_TRUE ") origin): \ applies an FIR filter to snd's channel chn. 'env' is the frequency response envelope, or a " S_vct " with the coefficients." chan_info *cp; char *errstr = NULL; const char *caller = NULL; bool truncate_1 = true; int order_1 = 0, edpos_1 = AT_CURRENT_EDIT_POSITION; mus_long_t beg_1 = 0, dur_1 = 0; env *e_1 = NULL; mus_float_t *coeffs = NULL; Xen_check_type(Xen_is_list(e) || mus_is_vct(e), e, 1, S_filter_channel, "an envelope or a " S_vct); Xen_check_type(Xen_is_integer_or_unbound(order), order, 2, S_filter_channel, "an integer"); Xen_check_type(Xen_is_string_or_unbound(origin), origin, 9, S_filter_channel, "a string"); if (Xen_is_integer(order)) { order_1 = Xen_integer_to_C_int(order); if (order_1 < 0) Xen_out_of_range_error(S_filter_channel, 2, order, "order should not be negative"); } Snd_assert_channel(S_filter_channel, snd, chn_n, 5); cp = get_cp(snd, chn_n, S_filter_channel); if (!cp) return(Xen_false); Xen_check_type(Xen_is_boolean_or_unbound(truncate), truncate, 8, S_filter_channel, "boolean"); if (Xen_is_boolean(truncate)) truncate_1 = Xen_boolean_to_C_bool(truncate); Snd_assert_sample_type(S_filter_channel, beg, 3); Snd_assert_sample_type(S_filter_channel, dur, 4); beg_1 = beg_to_sample(beg, S_filter_channel); edpos_1 = to_c_edit_position(cp, edpos, S_filter_channel, 7); dur_1 = dur_to_samples(dur, beg_1, cp, edpos_1, 4, S_filter_channel); if (Xen_is_list(e)) { e_1 = get_env(e, S_filter_channel); if (e_1 == NULL) return(Xen_false); if (order_1 == 0) order_1 = e_1->pts * 4; } else { vct *v = NULL; int len; v = Xen_to_vct(e); len = mus_vct_length(v); if (len == 0) Xen_out_of_range_error(S_filter_channel, 1, e, "filter coeffs array is empty"); coeffs = mus_vct_data(v); if (order_1 == 0) order_1 = len; } if (Xen_is_string(origin)) caller = Xen_string_to_C_string(origin); errstr = filter_channel(cp, order_1, e_1, beg_1, dur_1, edpos_1, caller, truncate_1, coeffs); if (e_1) free_env(e_1); if (errstr) { Xen str; str = C_string_to_Xen_string(errstr); free(errstr); Xen_error(Xen_make_error_type("IO-error"), Xen_list_2(C_string_to_Xen_string(S_filter_channel ": IO error ~A"), str)); } return(e); } static Xen g_filter_1(Xen e, Xen order, Xen snd, Xen chn_n, Xen edpos, const char *caller, const char *origin, bool over_selection, bool truncate) { chan_info *cp; Snd_assert_channel(caller, snd, chn_n, 3); cp = get_cp(snd, chn_n, caller); if (!cp) return(Xen_false); if (mus_is_xen(e)) { char *error; bool clm_err = false; error = apply_filter_or_error(cp, 0, NULL, caller, origin, over_selection, NULL, Xen_to_mus_any(e), edpos, 5, truncate, &clm_err); if (error) { Xen errstr; errstr = C_string_to_Xen_string(error); free(error); Xen_error(Xen_make_error_type((clm_err) ? "mus-error" : "IO-error"), Xen_list_3(C_string_to_Xen_string("~A: ~A"), C_string_to_Xen_string(caller), errstr)); } } else { int len = 0; Xen_check_type(Xen_is_integer_or_unbound(order), order, 2, caller, "an integer"); if (Xen_is_integer(order)) { len = Xen_integer_to_C_int(order); if (len <= 0) Xen_out_of_range_error(caller, 2, order, "order should be positive"); } if (mus_is_vct(e)) /* the filter coefficients direct */ { vct *v; char *new_origin = NULL, *estr = NULL; v = Xen_to_vct(e); if (len > mus_vct_length(v)) Xen_out_of_range_error(caller, 2, order, "order > length coeffs"); else { if (len == 0) len = mus_vct_length(v); } if ((!origin) && (mus_vct_length(v) < 16)) { estr = mus_vct_to_readable_string(v); #if HAVE_FORTH new_origin = mus_format("%s %d%s %s", estr, len, (over_selection) ? "" : PROC_SEP "0" PROC_SEP PROC_FALSE, caller); #else new_origin = mus_format("%s" PROC_OPEN "%s" PROC_SEP "%d%s", to_proc_name(caller), estr, len, (over_selection) ? "" : PROC_SEP "0" PROC_SEP PROC_FALSE); #endif } else new_origin = mus_strdup(origin); apply_filter(cp, len, NULL, caller, new_origin, over_selection, mus_vct_data(v), NULL, edpos, 5, truncate); if (estr) free(estr); if (new_origin) free(new_origin); } else { env *ne = NULL; char *new_origin = NULL, *estr = NULL; Xen_check_type(Xen_is_list(e), e, 1, caller, "a list, " S_vct ", or env generator"); ne = get_env(e, caller); /* arg here must be a list */ if (!origin) { estr = env_to_string(ne); #if HAVE_FORTH new_origin = mus_format("%s %d%s %s", estr, len, (over_selection) ? "" : " 0 " PROC_FALSE, caller); #else new_origin = mus_format("%s" PROC_OPEN "%s" PROC_SEP "%d%s", to_proc_name(caller), estr, len, (over_selection) ? "" : PROC_SEP "0" PROC_SEP PROC_FALSE); #endif } else new_origin = mus_strdup(origin); if (len == 0) len = ne->pts * 4; apply_filter(cp, len, ne, caller, new_origin, over_selection, NULL, NULL, edpos, 5, truncate); if (ne) free_env(ne); if (estr) free(estr); if (new_origin) free(new_origin); } } return(Xen_true); } static Xen g_filter_sound(Xen e, Xen order, Xen snd, Xen chn_n, Xen edpos, Xen origin) { #define H_filter_sound "(" S_filter_sound " filter :optional order snd chn edpos origin): \ applies FIR filter to snd's channel chn. 'filter' is either the frequency response envelope, a CLM filter, or a " S_vct " with the actual coefficients" Xen_check_type(Xen_is_string_or_unbound(origin), origin, 6, S_filter_sound, "a string"); return(g_filter_1(e, order, snd, chn_n, edpos, S_filter_sound, (Xen_is_string(origin)) ? Xen_string_to_C_string(origin) : NULL, OVER_SOUND, false)); } static Xen g_filter_selection(Xen e, Xen order, Xen truncate) { #define H_filter_selection "(" S_filter_selection " filter :optional order (truncate " PROC_TRUE ")): apply filter to selection. If truncate, \ cut off filter output at end of selection, else mix" Xen_check_type(Xen_is_boolean_or_unbound(truncate), truncate, 3, S_filter_selection, "boolean"); if (!(selection_is_active())) return(snd_no_active_selection_error(S_filter_selection)); return(g_filter_1(e, order, Xen_false, Xen_false, C_int_to_Xen_integer(AT_CURRENT_EDIT_POSITION), S_filter_selection, NULL, OVER_SELECTION, Xen_boolean_to_C_bool(truncate))); } static Xen g_sinc_width(void) {return(C_int_to_Xen_integer(sinc_width(ss)));} static Xen g_set_sinc_width(Xen val) { #define H_sinc_width "(" S_sinc_width "): sampling rate conversion sinc width (10). \ The higher this number, the better the src low-pass filter, but the slower \ src runs. If you use too low a setting, you can sometimes hear high \ frequency whistles leaking through." int len; Xen_check_type(Xen_is_integer(val), val, 1, S_set S_sinc_width, "an integer"); len = Xen_integer_to_C_int(val); if ((len >= 0) && (len <= MUS_MAX_CLM_SINC_WIDTH)) set_sinc_width(len); return(C_int_to_Xen_integer(sinc_width(ss))); } #ifndef _MSC_VER #include #endif #if 0 static int primes[129] = {1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719}; #else static int primes[2049] = {1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511, 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609, 1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733, 1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973, 1979, 1987, 1993, 1997, 1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053, 2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129, 2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203, 2207, 2213, 2221, 2237, 2239, 2243, 2251, 2267, 2269, 2273, 2281, 2287, 2293, 2297, 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357, 2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423, 2437, 2441, 2447, 2459, 2467, 2473, 2477, 2503, 2521, 2531, 2539, 2543, 2549, 2551, 2557, 2579, 2591, 2593, 2609, 2617, 2621, 2633, 2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687, 2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741, 2749, 2753, 2767, 2777, 2789, 2791, 2797, 2801, 2803, 2819, 2833, 2837, 2843, 2851, 2857, 2861, 2879, 2887, 2897, 2903, 2909, 2917, 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999, 3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079, 3083, 3089, 3109, 3119, 3121, 3137, 3163, 3167, 3169, 3181, 3187, 3191, 3203, 3209, 3217, 3221, 3229, 3251, 3253, 3257, 3259, 3271, 3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331, 3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413, 3433, 3449, 3457, 3461, 3463, 3467, 3469, 3491, 3499, 3511, 3517, 3527, 3529, 3533, 3539, 3541, 3547, 3557, 3559, 3571, 3581, 3583, 3593, 3607, 3613, 3617, 3623, 3631, 3637, 3643, 3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709, 3719, 3727, 3733, 3739, 3761, 3767, 3769, 3779, 3793, 3797, 3803, 3821, 3823, 3833, 3847, 3851, 3853, 3863, 3877, 3881, 3889, 3907, 3911, 3917, 3919, 3923, 3929, 3931, 3943, 3947, 3967, 3989, 4001, 4003, 4007, 4013, 4019, 4021, 4027, 4049, 4051, 4057, 4073, 4079, 4091, 4093, 4099, 4111, 4127, 4129, 4133, 4139, 4153, 4157, 4159, 4177, 4201, 4211, 4217, 4219, 4229, 4231, 4241, 4243, 4253, 4259, 4261, 4271, 4273, 4283, 4289, 4297, 4327, 4337, 4339, 4349, 4357, 4363, 4373, 4391, 4397, 4409, 4421, 4423, 4441, 4447, 4451, 4457, 4463, 4481, 4483, 4493, 4507, 4513, 4517, 4519, 4523, 4547, 4549, 4561, 4567, 4583, 4591, 4597, 4603, 4621, 4637, 4639, 4643, 4649, 4651, 4657, 4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729, 4733, 4751, 4759, 4783, 4787, 4789, 4793, 4799, 4801, 4813, 4817, 4831, 4861, 4871, 4877, 4889, 4903, 4909, 4919, 4931, 4933, 4937, 4943, 4951, 4957, 4967, 4969, 4973, 4987, 4993, 4999, 5003, 5009, 5011, 5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087, 5099, 5101, 5107, 5113, 5119, 5147, 5153, 5167, 5171, 5179, 5189, 5197, 5209, 5227, 5231, 5233, 5237, 5261, 5273, 5279, 5281, 5297, 5303, 5309, 5323, 5333, 5347, 5351, 5381, 5387, 5393, 5399, 5407, 5413, 5417, 5419, 5431, 5437, 5441, 5443, 5449, 5471, 5477, 5479, 5483, 5501, 5503, 5507, 5519, 5521, 5527, 5531, 5557, 5563, 5569, 5573, 5581, 5591, 5623, 5639, 5641, 5647, 5651, 5653, 5657, 5659, 5669, 5683, 5689, 5693, 5701, 5711, 5717, 5737, 5741, 5743, 5749, 5779, 5783, 5791, 5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849, 5851, 5857, 5861, 5867, 5869, 5879, 5881, 5897, 5903, 5923, 5927, 5939, 5953, 5981, 5987, 6007, 6011, 6029, 6037, 6043, 6047, 6053, 6067, 6073, 6079, 6089, 6091, 6101, 6113, 6121, 6131, 6133, 6143, 6151, 6163, 6173, 6197, 6199, 6203, 6211, 6217, 6221, 6229, 6247, 6257, 6263, 6269, 6271, 6277, 6287, 6299, 6301, 6311, 6317, 6323, 6329, 6337, 6343, 6353, 6359, 6361, 6367, 6373, 6379, 6389, 6397, 6421, 6427, 6449, 6451, 6469, 6473, 6481, 6491, 6521, 6529, 6547, 6551, 6553, 6563, 6569, 6571, 6577, 6581, 6599, 6607, 6619, 6637, 6653, 6659, 6661, 6673, 6679, 6689, 6691, 6701, 6703, 6709, 6719, 6733, 6737, 6761, 6763, 6779, 6781, 6791, 6793, 6803, 6823, 6827, 6829, 6833, 6841, 6857, 6863, 6869, 6871, 6883, 6899, 6907, 6911, 6917, 6947, 6949, 6959, 6961, 6967, 6971, 6977, 6983, 6991, 6997, 7001, 7013, 7019, 7027, 7039, 7043, 7057, 7069, 7079, 7103, 7109, 7121, 7127, 7129, 7151, 7159, 7177, 7187, 7193, 7207, 7211, 7213, 7219, 7229, 7237, 7243, 7247, 7253, 7283, 7297, 7307, 7309, 7321, 7331, 7333, 7349, 7351, 7369, 7393, 7411, 7417, 7433, 7451, 7457, 7459, 7477, 7481, 7487, 7489, 7499, 7507, 7517, 7523, 7529, 7537, 7541, 7547, 7549, 7559, 7561, 7573, 7577, 7583, 7589, 7591, 7603, 7607, 7621, 7639, 7643, 7649, 7669, 7673, 7681, 7687, 7691, 7699, 7703, 7717, 7723, 7727, 7741, 7753, 7757, 7759, 7789, 7793, 7817, 7823, 7829, 7841, 7853, 7867, 7873, 7877, 7879, 7883, 7901, 7907, 7919, 7927, 7933, 7937, 7949, 7951, 7963, 7993, 8009, 8011, 8017, 8039, 8053, 8059, 8069, 8081, 8087, 8089, 8093, 8101, 8111, 8117, 8123, 8147, 8161, 8167, 8171, 8179, 8191, 8209, 8219, 8221, 8231, 8233, 8237, 8243, 8263, 8269, 8273, 8287, 8291, 8293, 8297, 8311, 8317, 8329, 8353, 8363, 8369, 8377, 8387, 8389, 8419, 8423, 8429, 8431, 8443, 8447, 8461, 8467, 8501, 8513, 8521, 8527, 8537, 8539, 8543, 8563, 8573, 8581, 8597, 8599, 8609, 8623, 8627, 8629, 8641, 8647, 8663, 8669, 8677, 8681, 8689, 8693, 8699, 8707, 8713, 8719, 8731, 8737, 8741, 8747, 8753, 8761, 8779, 8783, 8803, 8807, 8819, 8821, 8831, 8837, 8839, 8849, 8861, 8863, 8867, 8887, 8893, 8923, 8929, 8933, 8941, 8951, 8963, 8969, 8971, 8999, 9001, 9007, 9011, 9013, 9029, 9041, 9043, 9049, 9059, 9067, 9091, 9103, 9109, 9127, 9133, 9137, 9151, 9157, 9161, 9173, 9181, 9187, 9199, 9203, 9209, 9221, 9227, 9239, 9241, 9257, 9277, 9281, 9283, 9293, 9311, 9319, 9323, 9337, 9341, 9343, 9349, 9371, 9377, 9391, 9397, 9403, 9413, 9419, 9421, 9431, 9433, 9437, 9439, 9461, 9463, 9467, 9473, 9479, 9491, 9497, 9511, 9521, 9533, 9539, 9547, 9551, 9587, 9601, 9613, 9619, 9623, 9629, 9631, 9643, 9649, 9661, 9677, 9679, 9689, 9697, 9719, 9721, 9733, 9739, 9743, 9749, 9767, 9769, 9781, 9787, 9791, 9803, 9811, 9817, 9829, 9833, 9839, 9851, 9857, 9859, 9871, 9883, 9887, 9901, 9907, 9923, 9929, 9931, 9941, 9949, 9967, 9973, 10007, 10009, 10037, 10039, 10061, 10067, 10069, 10079, 10091, 10093, 10099, 10103, 10111, 10133, 10139, 10141, 10151, 10159, 10163, 10169, 10177, 10181, 10193, 10211, 10223, 10243, 10247, 10253, 10259, 10267, 10271, 10273, 10289, 10301, 10303, 10313, 10321, 10331, 10333, 10337, 10343, 10357, 10369, 10391, 10399, 10427, 10429, 10433, 10453, 10457, 10459, 10463, 10477, 10487, 10499, 10501, 10513, 10529, 10531, 10559, 10567, 10589, 10597, 10601, 10607, 10613, 10627, 10631, 10639, 10651, 10657, 10663, 10667, 10687, 10691, 10709, 10711, 10723, 10729, 10733, 10739, 10753, 10771, 10781, 10789, 10799, 10831, 10837, 10847, 10853, 10859, 10861, 10867, 10883, 10889, 10891, 10903, 10909, 10937, 10939, 10949, 10957, 10973, 10979, 10987, 10993, 11003, 11027, 11047, 11057, 11059, 11069, 11071, 11083, 11087, 11093, 11113, 11117, 11119, 11131, 11149, 11159, 11161, 11171, 11173, 11177, 11197, 11213, 11239, 11243, 11251, 11257, 11261, 11273, 11279, 11287, 11299, 11311, 11317, 11321, 11329, 11351, 11353, 11369, 11383, 11393, 11399, 11411, 11423, 11437, 11443, 11447, 11467, 11471, 11483, 11489, 11491, 11497, 11503, 11519, 11527, 11549, 11551, 11579, 11587, 11593, 11597, 11617, 11621, 11633, 11657, 11677, 11681, 11689, 11699, 11701, 11717, 11719, 11731, 11743, 11777, 11779, 11783, 11789, 11801, 11807, 11813, 11821, 11827, 11831, 11833, 11839, 11863, 11867, 11887, 11897, 11903, 11909, 11923, 11927, 11933, 11939, 11941, 11953, 11959, 11969, 11971, 11981, 11987, 12007, 12011, 12037, 12041, 12043, 12049, 12071, 12073, 12097, 12101, 12107, 12109, 12113, 12119, 12143, 12149, 12157, 12161, 12163, 12197, 12203, 12211, 12227, 12239, 12241, 12251, 12253, 12263, 12269, 12277, 12281, 12289, 12301, 12323, 12329, 12343, 12347, 12373, 12377, 12379, 12391, 12401, 12409, 12413, 12421, 12433, 12437, 12451, 12457, 12473, 12479, 12487, 12491, 12497, 12503, 12511, 12517, 12527, 12539, 12541, 12547, 12553, 12569, 12577, 12583, 12589, 12601, 12611, 12613, 12619, 12637, 12641, 12647, 12653, 12659, 12671, 12689, 12697, 12703, 12713, 12721, 12739, 12743, 12757, 12763, 12781, 12791, 12799, 12809, 12821, 12823, 12829, 12841, 12853, 12889, 12893, 12899, 12907, 12911, 12917, 12919, 12923, 12941, 12953, 12959, 12967, 12973, 12979, 12983, 13001, 13003, 13007, 13009, 13033, 13037, 13043, 13049, 13063, 13093, 13099, 13103, 13109, 13121, 13127, 13147, 13151, 13159, 13163, 13171, 13177, 13183, 13187, 13217, 13219, 13229, 13241, 13249, 13259, 13267, 13291, 13297, 13309, 13313, 13327, 13331, 13337, 13339, 13367, 13381, 13397, 13399, 13411, 13417, 13421, 13441, 13451, 13457, 13463, 13469, 13477, 13487, 13499, 13513, 13523, 13537, 13553, 13567, 13577, 13591, 13597, 13613, 13619, 13627, 13633, 13649, 13669, 13679, 13681, 13687, 13691, 13693, 13697, 13709, 13711, 13721, 13723, 13729, 13751, 13757, 13759, 13763, 13781, 13789, 13799, 13807, 13829, 13831, 13841, 13859, 13873, 13877, 13879, 13883, 13901, 13903, 13907, 13913, 13921, 13931, 13933, 13963, 13967, 13997, 13999, 14009, 14011, 14029, 14033, 14051, 14057, 14071, 14081, 14083, 14087, 14107, 14143, 14149, 14153, 14159, 14173, 14177, 14197, 14207, 14221, 14243, 14249, 14251, 14281, 14293, 14303, 14321, 14323, 14327, 14341, 14347, 14369, 14387, 14389, 14401, 14407, 14411, 14419, 14423, 14431, 14437, 14447, 14449, 14461, 14479, 14489, 14503, 14519, 14533, 14537, 14543, 14549, 14551, 14557, 14561, 14563, 14591, 14593, 14621, 14627, 14629, 14633, 14639, 14653, 14657, 14669, 14683, 14699, 14713, 14717, 14723, 14731, 14737, 14741, 14747, 14753, 14759, 14767, 14771, 14779, 14783, 14797, 14813, 14821, 14827, 14831, 14843, 14851, 14867, 14869, 14879, 14887, 14891, 14897, 14923, 14929, 14939, 14947, 14951, 14957, 14969, 14983, 15013, 15017, 15031, 15053, 15061, 15073, 15077, 15083, 15091, 15101, 15107, 15121, 15131, 15137, 15139, 15149, 15161, 15173, 15187, 15193, 15199, 15217, 15227, 15233, 15241, 15259, 15263, 15269, 15271, 15277, 15287, 15289, 15299, 15307, 15313, 15319, 15329, 15331, 15349, 15359, 15361, 15373, 15377, 15383, 15391, 15401, 15413, 15427, 15439, 15443, 15451, 15461, 15467, 15473, 15493, 15497, 15511, 15527, 15541, 15551, 15559, 15569, 15581, 15583, 15601, 15607, 15619, 15629, 15641, 15643, 15647, 15649, 15661, 15667, 15671, 15679, 15683, 15727, 15731, 15733, 15737, 15739, 15749, 15761, 15767, 15773, 15787, 15791, 15797, 15803, 15809, 15817, 15823, 15859, 15877, 15881, 15887, 15889, 15901, 15907, 15913, 15919, 15923, 15937, 15959, 15971, 15973, 15991, 16001, 16007, 16033, 16057, 16061, 16063, 16067, 16069, 16073, 16087, 16091, 16097, 16103, 16111, 16127, 16139, 16141, 16183, 16187, 16189, 16193, 16217, 16223, 16229, 16231, 16249, 16253, 16267, 16273, 16301, 16319, 16333, 16339, 16349, 16361, 16363, 16369, 16381, 16411, 16417, 16421, 16427, 16433, 16447, 16451, 16453, 16477, 16481, 16487, 16493, 16519, 16529, 16547, 16553, 16561, 16567, 16573, 16603, 16607, 16619, 16631, 16633, 16649, 16651, 16657, 16661, 16673, 16691, 16693, 16699, 16703, 16729, 16741, 16747, 16759, 16763, 16787, 16811, 16823, 16829, 16831, 16843, 16871, 16879, 16883, 16889, 16901, 16903, 16921, 16927, 16931, 16937, 16943, 16963, 16979, 16981, 16987, 16993, 17011, 17021, 17027, 17029, 17033, 17041, 17047, 17053, 17077, 17093, 17099, 17107, 17117, 17123, 17137, 17159, 17167, 17183, 17189, 17191, 17203, 17207, 17209, 17231, 17239, 17257, 17291, 17293, 17299, 17317, 17321, 17327, 17333, 17341, 17351, 17359, 17377, 17383, 17387, 17389, 17393, 17401, 17417, 17419, 17431, 17443, 17449, 17467, 17471, 17477, 17483, 17489, 17491, 17497, 17509, 17519, 17539, 17551, 17569, 17573, 17579, 17581, 17597, 17599, 17609, 17623, 17627, 17657, 17659, 17669, 17681, 17683, 17707, 17713, 17729, 17737, 17747, 17749, 17761, 17783, 17789, 17791, 17807, 17827, 17837, 17839, 17851, 17863}; #endif static mus_float_t all_mins[128] = {1.0000, 1.7600, 1.9797, 2.0390, 2.3435, 2.5493, 2.6394, 2.7946, 2.9617, 3.1023, 3.2180, 3.3887, 3.5241, 3.6122, 3.7680, 3.8738, 3.9802, 4.1438, 4.2210, 4.2890, 4.4824, 4.5866, 4.6052, 4.7280, 4.8531, 5.0050, 5.0640, 5.1573, 5.2413, 5.3623, 5.4800, 5.5259, 5.6320, 5.7167, 5.7648, 5.8770, 5.9291, 6.0764, 6.1247, 6.2388, 6.3296, 6.4351, 6.4755, 6.5454, 6.6312, 6.6921, 6.7592, 6.8630, 6.9144, 7.0054, 7.0637, 7.1368, 7.1997, 7.2564, 7.3299, 7.3515, 7.4959, 7.5862, 7.6389, 7.6004, 7.7602, 7.7988, 7.8838, 7.9463, 8.0038, 8.0641, 8.1270, 8.1759, 8.2203, 8.1858, 8.3294, 8.4352, 8.4355, 8.5093, 8.6129, 8.6292, 8.7018, 8.7310, 8.8164, 8.8399, 8.9113, 8.9487, 8.9469, 9.0279, 9.1400, 9.2143, 9.2076, 9.3188, 9.3608, 9.4148, 9.4762, 9.5310, 9.4369, 9.6238, 9.6045, 9.7150, 9.8146, 9.7808, 9.8684, 9.9374, 9.9893, 10.0292, 10.0825, 10.1311, 10.1809, 10.2348, 10.2757, 10.3212, 10.4394, 10.4438, 10.4982, 10.4710, 10.6004, 10.5194, 10.6682, 10.6756, 10.7494, 10.7909, 10.8383, 10.8805, 10.9294, 10.9655, 11.0898, 11.0638, 11.1608, 11.1455, 11.1939, 11.3092}; static mus_float_t odd_mins[128] = {1.0000, 1.5390, 1.7387, 2.0452, 2.3073, 2.5227, 2.6183, 2.7907, 2.8862, 3.0534, 3.1766, 3.3619, 3.4745, 3.5985, 3.7384, 3.8570, 3.9264, 4.0695, 4.1719, 4.3580, 4.4485, 4.5810, 4.6616, 4.7864, 4.8868, 5.0064, 5.0888, 5.0889, 5.2634, 5.3531, 5.4189, 5.5633, 5.6030, 5.7405, 5.8333, 5.9776, 6.0191, 6.1443, 6.1815, 6.2725, 6.3216, 6.4032, 6.4742, 6.5992, 6.6249, 6.7092, 6.7852, 6.8280, 6.9896, 6.9471, 7.0877, 7.0801, 7.2526, 7.3281, 7.3642, 7.4191, 7.4889, 7.5859, 7.6178, 7.6996, 7.7755, 7.8170, 7.9041, 7.9574, 8.0418, 8.0952, 8.1280, 8.2044, 8.2749, 8.3285, 8.4066, 8.3664, 8.5147, 8.4879, 8.6495, 8.6513, 8.7070, 8.7153, 8.8646, 8.8701, 8.9263, 8.8955, 9.0607, 9.1335, 9.1729, 9.2133, 9.3199, 9.3240, 9.3316, 9.4217, 9.4566, 9.5527, 9.6288, 9.6539, 9.7169, 9.7594, 9.8323, 9.8526, 9.9278, 9.9678, 9.9646, 10.0458, 10.1025, 10.1685, 10.1158, 10.1983, 10.2960, 10.3255, 10.4140, 10.4081, 10.5889, 10.5826, 10.5864, 10.6208, 10.6743, 10.7333, 10.7833, 10.8122, 10.9166, 10.9086, 11.0006, 11.0363, 11.1211, 11.1342, 11.1221, 11.2224, 11.2680, 11.2612}; static mus_float_t prime_mins[128] = {1.0000, 1.7600, 1.9798, 2.1921, 2.4768, 2.8054, 3.0618, 3.2628, 3.3822, 3.6019, 3.7784, 3.9359, 4.1545, 4.3244, 4.4669, 4.6015, 4.7191, 4.8554, 5.0150, 5.1886, 5.3250, 5.4444, 5.5636, 5.6457, 5.8110, 6.0603, 6.1342, 6.1909, 6.3650, 6.4518, 6.7015, 6.8403, 6.8471, 6.9918, 7.1647, 7.2743, 7.2923, 7.3972, 7.4571, 7.7036, 7.8670, 7.9689, 8.0462, 8.1786, 8.1587, 8.2656, 8.4225, 8.4701, 8.6383, 8.6779, 8.6547, 8.8203, 8.9537, 9.1135, 9.1486, 9.4076, 9.5698, 9.4963, 9.4489, 9.6577, 9.8482, 9.7939, 9.7212, 9.9180, 10.2494, 10.2168, 10.3295, 10.4019, 10.4139, 10.4406, 10.5788, 10.5922, 10.7617, 10.7115, 11.0223, 11.0723, 10.8825, 11.1288, 11.2266, 11.4514, 11.5009, 11.4800, 11.5157, 11.5609, 11.6403, 11.5250, 11.9270, 11.9889, 12.2189, 12.0405, 12.1250, 12.1239, 12.3234, 12.3723, 12.5103, 12.6686, 12.6382, 12.8988, 13.0893, 13.1158, 13.0683, 13.3991, 13.4243, 13.1969, 13.1439, 13.2161, 13.5618, 13.6628, 13.6943, 13.7797, 13.7655, 13.8646, 14.0364, 14.2144, 14.1698, 14.4672, 14.6007, 14.5453, 14.3907, 14.5061, 14.5506, 14.8452, 14.6063, 14.8769, 14.7724, 14.9200, 14.9658, 14.6466}; static mus_float_t even_mins[128] = {1.0000, 1.7602, 2.0215, 2.4306, 2.6048, 2.8370, 3.0470, 3.1975, 3.4540, 3.5587, 3.6561, 3.7869, 3.9726, 4.0967, 4.1921, 4.3250, 4.4630, 4.5694, 4.7415, 4.8395, 4.9197, 5.0552, 5.1479, 5.2532, 5.4032, 5.4523, 5.6204, 5.7317, 5.7663, 5.9070, 5.9878, 6.0611, 6.1626, 6.2228, 6.3623, 6.4321, 6.5805, 6.5366, 6.6832, 6.7481, 6.8810, 6.9415, 7.0552, 7.0483, 7.1652, 7.2760, 7.2926, 7.4670, 7.5877, 7.6224, 7.6548, 7.7863, 7.7505, 7.8451, 8.0075, 8.0420, 8.1156, 8.1027, 8.1945, 8.3124, 8.3566, 8.3910, 8.4139, 8.5009, 8.6650, 8.7856, 8.8244, 8.7974, 8.8704, 9.0010, 9.0999, 8.9855, 9.1604, 9.2507, 9.2084, 9.3920, 9.3628, 9.3359, 9.5324, 9.5713, 9.5437, 9.6632, 9.7525, 9.7487, 9.6937, 9.8045, 9.8747, 9.9683, 10.1103, 10.2395, 10.1678, 10.2333, 10.1208, 10.4354, 10.4453, 10.5480, 10.4547, 10.5295, 10.4140, 10.4721, 10.7995, 10.8253, 10.8315, 10.7829, 10.9236, 10.9172, 10.9844, 11.0254, 11.0804, 11.2647, 11.3526, 11.2728, 11.1978, 11.3362, 11.3367, 11.5548, 11.3673, 11.5805, 11.6248, 11.7167, 11.5799, 11.7805, 11.7526, 11.8398, 11.8194, 11.9815, 11.8908, 11.9243}; static mus_float_t min_8[4] = {16.2329, 17.2610, 18.0460, 23.9548}; static mus_float_t min_9[4] = {24.1124, 24.0647, 25.2901, 38.6029}; static mus_float_t min_10[4] = {34.3800, 35.3998, 35.8426, 65.3493}; static mus_float_t min_11[4] = {51.4838, 50.4877, 51.3446, 95.9043}; #define USE_CLM_RANDOM (!HAVE_SCHEME) static mus_float_t local_random(mus_float_t val) { #if USE_CLM_RANDOM return(mus_random(val)); #else return(val * (1.0 - (s7_random(s7, NULL) * 2.0))); #endif } static mus_float_t local_frandom(mus_float_t val) { #if USE_CLM_RANDOM return(mus_frandom(val)); #else return(val * s7_random(s7, NULL)); #endif } typedef struct { mus_float_t pk; mus_float_t *phases; } pk_data; /* -------------------------------------------------------------------------------- */ #define ALL 0 #define ODD 1 #define EVEN 2 #define PRIME 3 #define FFT_MULT 160 /* if 64, errors or .005 are common * if 128, which works in 99% of the cases, errors can be as much as .002 */ #define S_fpsap "fpsap" static mus_float_t saved_min(int ch, int nn) { if (nn <= 128) { switch (ch) { case ALL: return(all_mins[nn - 1]); case ODD: return(odd_mins[nn - 1]); case EVEN: return(even_mins[nn - 1]); case PRIME: return(prime_mins[nn - 1]); } } if (nn == 256) return(min_8[ch]); if (nn == 512) return(min_9[ch]); if (nn == 1024) return(min_10[ch]); if (nn == 2048) return(min_11[ch]); return((mus_float_t)nn); } static mus_float_t get_peak(int choice, int fft_size, int n, mus_float_t *phases, mus_float_t *rl, mus_float_t *im) { int i, m; mus_float_t pi2, mx_sin, mx_cos; pi2 = M_PI / 2.0; memset((void *)rl, 0, fft_size * sizeof(mus_float_t)); memset((void *)im, 0, fft_size * sizeof(mus_float_t)); for (m = 0; m < n; m++) { int bin; mus_float_t phi; phi = (M_PI * phases[m]) + pi2; if (choice == ALL) bin = m + 1; else { if (choice == ODD) bin = (m * 2) + 1; else { if (choice == EVEN) { bin = m * 2; if (bin == 0) bin = 1; } else bin = primes[m]; } } rl[bin] = cos(phi); im[bin] = sin(phi); } mus_fft(rl, im, fft_size, -1); /* real part is sine reconstruction, imaginary part is cosine, we're interested in both! */ /* we could also add and subtract the 2 to get 2 more cases "for free", amp sqrt(2), phase asin(cos(0)/sqrt(2)) */ /* and repeat this with a shift (rotation from i) for 2n other cases */ /* resultant amp is between 0 and 2 (cosine) */ mx_sin = fabs(rl[0]); mx_cos = fabs(im[0]); for (i = 1; i < fft_size; i++) { mus_float_t mxtemp; mxtemp = fabs(rl[i]); if (mxtemp > mx_sin) mx_sin = mxtemp; mxtemp = fabs(im[i]); if (mxtemp > mx_cos) mx_cos = mxtemp; } if (mx_sin <= mx_cos) return(mx_sin); /* use the cosine case, but make it sine-based with 0.0 initial phase for the fundamental */ for (m = 1; m < n; m++) { int bin; if (choice == ALL) bin = m + 1; else { if (choice == ODD) bin = (m * 2) + 1; else { if (choice == EVEN) { bin = m * 2; if (bin == 0) bin = 1; } else bin = primes[m]; } } phases[m] += (0.5 * (bin - 1)); } return(mx_cos); } static Xen g_fpsap(Xen x_choice, Xen x_n, Xen start_phases, Xen x_size, Xen x_increment) { #define H_fpsap "(" S_fpsap " choice n phases (size 6000) (increment 0.06)) searches \ for a peak-amp minimum using a simulated annealing form of the genetic algorithm. choice: 0=all, 1=odd, 2=even, 3=prime." #define INCR_DOWN 0.92 #define INCR_MAX 1.0 #define INCR_MIN 0.00005 #define RETRIES 10 #define RETRY_MULT 2 #define INIT_TRIES 5000 int choice, n, size, counts = 0; mus_float_t increment = INCR_MAX, orig_incr, local_best = 1000.0, incr_mult = INCR_DOWN, overall_min; mus_float_t *min_phases = NULL, *temp_phases = NULL, *diff_phases = NULL, *initial_phases = NULL; const char *choice_name[4] = {"all", "odd", "even", "prime"}; pk_data **choices = NULL, **free_choices = NULL; mus_float_t *rl, *im; const char *file = NULL; bool just_best = false; #ifndef _MSC_VER { struct timeval tm; struct timezone tz; gettimeofday(&tm, &tz); mus_set_rand_seed((unsigned long)(tm.tv_sec * 1000 + tm.tv_usec / 1000)); } #endif choice = Xen_integer_to_C_int(x_choice); if ((choice < ALL) || (choice > PRIME)) choice = ALL; n = Xen_integer_to_C_int(x_n); if (Xen_is_integer(x_size)) size = Xen_integer_to_C_int(x_size); else size = 3000; if (Xen_is_double(x_increment)) increment = Xen_real_to_C_double(x_increment); else increment = 0.06; /* was .03 */ counts = 50; /* 100? */ orig_incr = increment; incr_mult = INCR_DOWN; file = "test.data"; just_best = false; if (Xen_is_vector(start_phases)) { int i; initial_phases = (mus_float_t *)malloc(n * sizeof(mus_float_t)); for (i = 0; i < n; i++) initial_phases[i] = (mus_float_t)Xen_real_to_C_double(Xen_vector_ref(start_phases, i)); } min_phases = (mus_float_t *)calloc(n, sizeof(mus_float_t)); overall_min = saved_min(choice, n); if (overall_min < sqrt((double)n)) overall_min = sqrt((double)n); overall_min += .5; temp_phases = (mus_float_t *)calloc(n, sizeof(mus_float_t)); diff_phases = (mus_float_t *)calloc(n, sizeof(mus_float_t)); { int start, n1, day_counter, free_top, fft_size; if (choice == ALL) n1 = n; else { if (choice != PRIME) n1 = n * 2; else n1 = primes[n]; } fft_size = (int)pow(2.0, (int)ceil(log(FFT_MULT * n1) / log(2.0))); rl = (mus_float_t *)calloc(fft_size, sizeof(mus_float_t)); im = (mus_float_t *)calloc(fft_size, sizeof(mus_float_t)); choices = (pk_data **)calloc(size, sizeof(pk_data *)); free_choices = (pk_data **)calloc(size, sizeof(pk_data *)); for (start = 0; start < size; start++) { choices[start] = (pk_data *)calloc(1, sizeof(pk_data)); choices[start]->phases = (mus_float_t *)calloc(n, sizeof(mus_float_t)); } free_top = 0; day_counter = 0; local_best = (mus_float_t)n; increment = orig_incr; /* here to stay focussed, * for (k = 0; k < n; k++) choices[0]->phases[k] = initial_phases[k]; * choices[0]->pk = get_peak(choice, fft_size, n, initial_phases, rl, im); * for (start = 1; start < size; start++) * etc * but this is not an improvement */ for (start = 0; start < size; start++) { mus_float_t pk, local_pk = 100000.0; int k, init_try; for (init_try = 0; init_try < INIT_TRIES; init_try++) { if (initial_phases) { for (k = 1; k < n; k++) temp_phases[k] = initial_phases[k] + local_random(increment) + local_random(increment); } else { for (k = 1; k < n; k++) temp_phases[k] = local_frandom(2.0); } pk = get_peak(choice, fft_size, n, temp_phases, rl, im); if (pk < local_best) { local_best = pk; if ((!just_best) || (pk < overall_min)) { for (k = 1; k < n; k++) min_phases[k] = temp_phases[k]; if (pk < overall_min) { FILE *ofile; if (file) ofile = fopen(file, "a"); else ofile = stderr; fprintf(ofile, "%s, %d %f #(", choice_name[choice], n, pk); for (k = 0; k < n - 1; k++) fprintf(ofile, "%f ", min_phases[k]); fprintf(ofile, "%f)\n", min_phases[n - 1]); if (file) fclose(ofile); overall_min = pk; } } } if (pk < local_pk) { for (k = 1; k < n; k++) choices[start]->phases[k] = temp_phases[k]; choices[start]->pk = pk; local_pk = pk; } } } while (true) { int i, j = 0, k, len; mus_float_t sum = 0.0, avg; len = size; day_counter++; for (i = 0; i < len; i++) sum += choices[i]->pk; avg = sum / len; for (i = 0; i < len; i++) { pk_data *datum; datum = choices[i]; choices[i] = NULL; if (datum->pk < avg) choices[j++] = datum; else free_choices[free_top++] = datum; } for (i = 0, k = j; k < len; i++, k++) { pk_data *data; mus_float_t *phases; mus_float_t cur_min, temp_min = 100000.0, pk = 100000.0; int llen, local_try, ii, kk, local_tries; pk_data *new_pk; if (i == j) i = 0; data = choices[i]; new_pk = free_choices[--free_top]; cur_min = data->pk; phases = data->phases; llen = n; local_tries = RETRIES + day_counter * RETRY_MULT; /* try to find a point nearby that is better */ for (local_try = 0; (local_try < local_tries) && (pk >= cur_min); local_try++) { for (ii = 1; ii < llen; ii++) temp_phases[ii] = fmod(phases[ii] + local_random(increment) + local_random(increment), 2.0); /* not mus_frandom! */ pk = get_peak(choice, fft_size, n, temp_phases, rl, im); if (pk < temp_min) { temp_min = pk; new_pk->pk = pk; for (kk = 1; kk < llen; kk++) new_pk->phases[kk] = temp_phases[kk]; } } /* if a better point is found, try to follow the slopes */ if (new_pk->pk < data->pk) { int happy = 3; for (kk = 1; kk < llen; kk++) diff_phases[kk] = new_pk->phases[kk] - data->phases[kk]; while (happy > 0) { for (kk = 1; kk < llen; kk++) temp_phases[kk] = fmod(new_pk->phases[kk] + local_frandom(diff_phases[kk]), 2.0); /* use frandom 30-mar-11 */ pk = get_peak(choice, fft_size, n, temp_phases, rl, im); if (pk < new_pk->pk) { new_pk->pk = pk; for (kk = 1; kk < llen; kk++) new_pk->phases[kk] = temp_phases[kk]; happy = 3; } else happy--; } } pk = new_pk->pk; if (pk < local_best) { local_best = pk; if ((!just_best) || (pk < overall_min)) { for (kk = 1; kk < llen; kk++) min_phases[kk] = new_pk->phases[kk]; if (pk < overall_min) { FILE *ofile; if (file) ofile = fopen(file, "a"); else ofile = stderr; fprintf(ofile, "%s, %d %f #(", choice_name[choice], n, pk); for (kk = 0; kk < llen - 1; kk++) fprintf(ofile, "%f ", min_phases[kk]); fprintf(ofile, "%f)\n", min_phases[llen - 1]); if (file) fclose(ofile); overall_min = pk; } } day_counter = 0; } choices[k] = new_pk; } if (day_counter < counts) { /* .9^50 = .005, so starting at .1 bottoms out at .0005 * perhaps the counts variable should be (ceiling (log INCR_MIN incr_mult)) = 90 or so in the current case * incr_mult is currently always INCR_DOWN = .9 */ increment *= incr_mult; if (increment < INCR_MIN) { increment = INCR_MIN; } if (increment > INCR_MAX) { increment = INCR_MAX; incr_mult = INCR_DOWN; } } else break; } } free(temp_phases); free(diff_phases); free(rl); free(im); free(free_choices); if (initial_phases) free(initial_phases); { int i; for (i = 0; i < size; i++) { free(choices[i]->phases); free(choices[i]); } free(choices); } return(Xen_list_2(C_double_to_Xen_real(local_best), xen_make_vct(n, min_phases))); } #if HAVE_SCHEME static s7_pointer g_phases_get_peak(s7_scheme *sc, s7_pointer args) { s7_int choice, i, m, n; int fft_size, fft_mult = 128, n1; s7_pointer phases; s7_pointer *elements; double pi2, mx; mus_float_t *rl, *im; pi2 = M_PI / 2.0; choice = s7_integer(s7_car(args)); n = s7_integer(s7_cadr(args)); phases = s7_caddr(args); elements = s7_vector_elements(phases); if (choice == 0) n1 = n; else { if (choice == 3) n1 = primes[n]; else n1 = 2 * n; } fft_size = (int)pow(2.0, (int)ceil(log(fft_mult * n1) / log(2.0))); rl = (mus_float_t *)calloc(fft_size, sizeof(mus_float_t)); im = (mus_float_t *)calloc(fft_size, sizeof(mus_float_t)); for (m = 0; m < n; m++) { double phi; int bin; phi = pi2 + M_PI * (s7_real(elements[m])); if (choice == 0) bin = m + 1; else { if (choice == 1) bin = 1 + (m * 2); else { if (choice == 2) { bin = m * 2; if (bin == 0) bin = 1; } else bin = primes[m]; } } rl[bin] = cos(phi); im[bin] = sin(phi); } mus_fft(rl, im, fft_size, -1); mx = fabs(rl[0]); for (i = 1; i < fft_size; i++) { double tmp; tmp = fabs(rl[i]); if (tmp > mx) mx = tmp; } free(rl); free(im); return(s7_make_real(sc, mx)); } #endif Xen_wrap_6_optional_args(g_scan_channel_w, g_scan_channel) Xen_wrap_7_optional_args(g_map_channel_w, g_map_channel) #if (!HAVE_SCHEME) Xen_wrap_7_optional_args(g_map_chan_w, g_map_chan) Xen_wrap_6_optional_args(g_scan_chan_w, g_scan_chan) Xen_wrap_5_optional_args(g_find_channel_w, g_find_channel) #endif Xen_wrap_5_optional_args(g_count_matches_w, g_count_matches) Xen_wrap_4_optional_args(g_smooth_sound_w, g_smooth_sound) Xen_wrap_5_optional_args(g_smooth_channel_w, g_smooth_channel) Xen_wrap_no_args(g_smooth_selection_w, g_smooth_selection) Xen_wrap_no_args(g_delete_selection_and_smooth_w, g_delete_selection_and_smooth) Xen_wrap_5_optional_args(g_delete_samples_and_smooth_w, g_delete_samples_and_smooth) Xen_wrap_3_optional_args(g_reverse_sound_w, g_reverse_sound) Xen_wrap_5_optional_args(g_reverse_channel_w, g_reverse_channel) Xen_wrap_no_args(g_reverse_selection_w, g_reverse_selection) Xen_wrap_8_optional_args(g_swap_channels_w, g_swap_channels) Xen_wrap_4_optional_args(g_insert_silence_w, g_insert_silence) Xen_wrap_1_optional_arg(g_scale_selection_to_w, g_scale_selection_to) Xen_wrap_1_arg(g_scale_selection_by_w, g_scale_selection_by) Xen_wrap_3_optional_args(g_scale_to_w, g_scale_to) Xen_wrap_3_optional_args(g_scale_by_w, g_scale_by) Xen_wrap_2_optional_args(g_env_selection_w, g_env_selection) Xen_wrap_7_optional_args(g_env_sound_w, g_env_sound) Xen_wrap_6_optional_args(g_env_channel_w, g_env_channel) Xen_wrap_7_optional_args(g_env_channel_with_base_w, g_env_channel_with_base) Xen_wrap_7_optional_args(g_ramp_channel_w, g_ramp_channel) Xen_wrap_8_optional_args(g_xramp_channel_w, g_xramp_channel) Xen_wrap_3_optional_args(g_fft_w, g_fft) Xen_wrap_7_optional_args(g_snd_spectrum_w, g_snd_spectrum) Xen_wrap_5_optional_args(g_convolve_with_w, g_convolve_with) Xen_wrap_2_optional_args(g_convolve_selection_with_w, g_convolve_selection_with) Xen_wrap_5_optional_args(g_src_sound_w, g_src_sound) Xen_wrap_2_optional_args(g_src_selection_w, g_src_selection) Xen_wrap_6_optional_args(g_src_channel_w, g_src_channel) Xen_wrap_5_optional_args(g_pad_channel_w, g_pad_channel) Xen_wrap_9_optional_args(g_filter_channel_w, g_filter_channel) Xen_wrap_6_optional_args(g_filter_sound_w, g_filter_sound) Xen_wrap_3_optional_args(g_filter_selection_w, g_filter_selection) Xen_wrap_8_optional_args(g_clm_channel_w, g_clm_channel) Xen_wrap_no_args(g_sinc_width_w, g_sinc_width) Xen_wrap_1_arg(g_set_sinc_width_w, g_set_sinc_width) Xen_wrap_5_optional_args(g_fpsap_w, g_fpsap) #if HAVE_SCHEME static s7_pointer acc_sinc_width(s7_scheme *sc, s7_pointer args) {return(g_set_sinc_width(s7_cadr(args)));} #endif void g_init_sig(void) { Xen_define_procedure(S_scan_channel, g_scan_channel_w, 1, 5, 0, H_scan_channel); #if (!HAVE_SCHEME) Xen_define_procedure(S_scan_chan, g_scan_chan_w, 1, 5, 0, H_scan_chan); Xen_define_procedure(S_find_channel, g_find_channel_w, 1, 4, 0, H_find_channel); Xen_define_procedure(S_map_chan, g_map_chan_w, 1, 6, 0, H_map_chan); #endif Xen_define_procedure(S_count_matches, g_count_matches_w, 1, 4, 0, H_count_matches); Xen_define_procedure(S_map_channel, g_map_channel_w, 1, 6, 0, H_map_channel); Xen_define_safe_procedure(S_smooth_sound, g_smooth_sound_w, 0, 4, 0, H_smooth_sound); Xen_define_safe_procedure(S_smooth_selection, g_smooth_selection_w, 0, 0, 0, H_smooth_selection); Xen_define_safe_procedure(S_delete_selection_and_smooth, g_delete_selection_and_smooth_w, 0, 0, 0, H_delete_selection_and_smooth); Xen_define_safe_procedure(S_delete_samples_and_smooth, g_delete_samples_and_smooth_w, 2, 3, 0, H_delete_samples_and_smooth); Xen_define_safe_procedure(S_reverse_sound, g_reverse_sound_w, 0, 3, 0, H_reverse_sound); Xen_define_safe_procedure(S_reverse_selection, g_reverse_selection_w, 0, 0, 0, H_reverse_selection); Xen_define_safe_procedure(S_swap_channels, g_swap_channels_w, 0, 8, 0, H_swap_channels); Xen_define_safe_procedure(S_insert_silence, g_insert_silence_w, 2, 2, 0, H_insert_silence); Xen_define_safe_procedure(S_scale_selection_to, g_scale_selection_to_w, 0, 1, 0, H_scale_selection_to); Xen_define_safe_procedure(S_scale_selection_by, g_scale_selection_by_w, 1, 0, 0, H_scale_selection_by); Xen_define_safe_procedure(S_scale_to, g_scale_to_w, 0, 3, 0, H_scale_to); Xen_define_safe_procedure(S_scale_by, g_scale_by_w, 1, 2, 0, H_scale_by); Xen_define_safe_procedure(S_env_selection, g_env_selection_w, 1, 1, 0, H_env_selection); Xen_define_safe_procedure(S_env_sound, g_env_sound_w, 1, 6, 0, H_env_sound); Xen_define_safe_procedure(S_fft, g_fft_w, 2, 1, 0, H_fft); Xen_define_safe_procedure(S_snd_spectrum, g_snd_spectrum_w, 1, 6, 0, H_snd_spectrum); Xen_define_safe_procedure(S_convolve_with, g_convolve_with_w, 1, 4, 0, H_convolve_with); Xen_define_safe_procedure(S_convolve_selection_with, g_convolve_selection_with_w, 1, 1, 0, H_convolve_selection_with); Xen_define_safe_procedure(S_src_sound, g_src_sound_w, 1, 4, 0, H_src_sound); Xen_define_safe_procedure(S_src_selection, g_src_selection_w, 1, 1, 0, H_src_selection); Xen_define_safe_procedure(S_filter_channel, g_filter_channel_w, 1, 8, 0, H_filter_channel); Xen_define_safe_procedure(S_filter_sound, g_filter_sound_w, 1, 5, 0, H_filter_sound); Xen_define_safe_procedure(S_filter_selection, g_filter_selection_w, 1, 2, 0, H_filter_selection); Xen_define_safe_procedure(S_reverse_channel, g_reverse_channel_w, 0, 5, 0, H_reverse_channel); Xen_define_safe_procedure(S_clm_channel, g_clm_channel_w, 1, 7, 0, H_clm_channel); Xen_define_safe_procedure(S_env_channel, g_env_channel_w, 1, 5, 0, H_env_channel); Xen_define_safe_procedure(S_env_channel_with_base, g_env_channel_with_base_w, 1, 6, 0, H_env_channel_with_base); Xen_define_safe_procedure(S_ramp_channel, g_ramp_channel_w, 2, 5, 0, H_ramp_channel); Xen_define_safe_procedure(S_xramp_channel, g_xramp_channel_w, 2, 6, 0, H_xramp_channel); Xen_define_safe_procedure(S_smooth_channel, g_smooth_channel_w, 0, 5, 0, H_smooth_channel); Xen_define_safe_procedure(S_src_channel, g_src_channel_w, 1, 5, 0, H_src_channel); Xen_define_safe_procedure(S_pad_channel, g_pad_channel_w, 2, 3, 0, H_pad_channel); Xen_define_dilambda(S_sinc_width, g_sinc_width_w, H_sinc_width, S_set S_sinc_width, g_set_sinc_width_w, 0, 0, 1, 0); Xen_define_procedure(S_fpsap, g_fpsap_w, 3, 2, 0, H_fpsap); #if HAVE_SCHEME Xen_define_procedure("phases-get-peak", g_phases_get_peak, 3, 0, 0, ""); s7_symbol_set_access(s7, ss->sinc_width_symbol, s7_make_function(s7, "[acc-" S_sinc_width "]", acc_sinc_width, 2, 0, false, "accessor")); s7_symbol_set_documentation(s7, ss->sinc_width_symbol, "*sinc-width*: sampling rate conversion sinc width (10)."); #endif } #if 0 /* these work in snd-test, but are not faster */ (define* (scan-channel func (beg 0) dur snd chn edpos) (let ((end (if dur (min (+ beg dur) (framples snd chn)) (framples snd chn))) (rd (make-sampler beg snd chn 1 edpos))) (do ((pos beg (+ pos 1))) ((or (>= pos end) (func (next-sample rd))) (and (< pos end) pos))))) (define* (count-matches func (beg 0) snd chn edpos) (let ((end (framples snd chn edpos)) (matches 0) (reader (make-sampler beg snd chn 1 edpos))) (do ((i beg (+ i 1))) ((>= i end) matches) (if (func (next-sample reader)) (set! matches (+ matches 1)))))) (define-macro* (scan-channel-1 func (beg 0) dur snd chn edpos) (let ((end (if dur (min (+ beg dur) (framples snd chn)) (framples snd chn)))) `(let ((rd (make-sampler ,beg ,snd ,chn 1 ,edpos)) (f ,func)) (define (call) (do ((pos ,beg (+ pos 1))) ((or (>= pos ,end) (f (next-sample rd))) (and (< pos ,end) pos)))) (call)))) (define* (scan-channel-2 func (beg 0) dur snd chn edpos) (define* (uncons lst (res ())) (if (null? lst) res (uncons (cdr lst) (cons (list (caar lst) (cdar lst)) res)))) (let ((end (if dur (min (+ beg dur) (framples snd chn)) (framples snd chn))) (source (procedure-source func)) (e (funclet func))) (let ((arg (caadr source)) (body (cddr source)) (new-e (if (eq? e (rootlet)) () (uncons (let->list e)))) (rd (make-sampler beg snd chn 1 edpos))) (define call (apply let new-e `((lambda () (do ((pos ,beg (+ pos 1)) (,arg (next-sample ,rd) (next-sample ,rd))) ((or (>= pos ,end) (begin ,@body)) (and (< pos ,end) pos))))))) (call)))) */ #endif snd-16.1/analog-filter.scm0000644000076400007640000004476312615151307013602 0ustar bilbil;;; various even order analog filters, based primarily on Anders Johansson's (GPL'd) code ;;; ;;; butterworth-lowpass|highpass|bandstop|bandpass ;;; chebyshev-lowpass|highpass|bandstop|bandpass ;;; inverse-chebyshev-lowpass|highpass|bandstop|bandpass ;;; ;;; if GSL included in Snd: ;;; bessel-lowpass|highpass|bandstop|bandpass ;;; elliptic-lowpass|highpass|bandstop|bandpass ;;; ;;; build Snd with gsl for best results (provide 'snd-analog-filter.scm) (define* (analog->digital n num den fz) (let ((g 1.0) (Q 1.0) (wc (tan (* pi fz))) (c (make-float-vector (* 2 n)))) (define (cascade->canonical A) ;; (cascade->canonical A) converts cascade filter coeffs to canonical form ;; from Orfanidis "Introduction to Signal Processing" (define (conv M h L x y) ;; x * h -> y (do ((n 0 (+ n 1))) ((= n (+ L M))) (let ((sum 0.0) (start (max 0 (- n (+ L 1)))) (end (min n M))) (do ((m start (+ m 1))) ((> m end)) (set! sum (+ sum (* (h m) (x (- n m)))))) (set! (y n) sum)))) (let* ((K (length A)) (d (make-float-vector (+ 1 (* 2 K)))) (a1 (make-float-vector (+ 1 (* 2 K))))) (set! (a1 0) 1.0) (do ((i 0 (+ i 1))) ((= i K)) (conv 2 (A i) (+ 1 (* 2 i)) a1 d) (copy d a1 0 (+ 3 (* 2 i)))) a1)) (do ((i 0 (+ i 2)) (j 0 (+ j 3)) (k 0 (+ k 4))) ((>= i n)) (let* ((nt0 (/ (num (+ j 0)) (* wc wc))) (nt1 (/ (num (+ j 1)) wc)) (nt2 (num (+ j 2))) (dt0 (/ (den (+ j 0)) (* wc wc))) (dt1 (/ (den (+ j 1)) (* wc Q))) (dt2 (den (+ j 2))) (kd (+ dt0 dt1 dt2)) (kn (+ nt0 nt1 nt2))) (set! (c k ) (/ (- (* 2.0 dt2) (* 2.0 dt0)) kd)) (set! (c (+ k 1)) (/ (+ dt0 (- dt1) dt2) kd)) (set! (c (+ k 2)) (/ (- (* 2.0 nt2) (* 2.0 nt0)) kn)) (set! (c (+ k 3)) (/ (+ nt0 (- nt1) nt2) kn)) (set! g (* g (/ kn kd))))) (let ((a ()) (b ())) (do ((i 0 (+ i 2)) (k 0 (+ k 4))) ; c ((>= i n)) (set! a (cons (float-vector (c (+ k 3)) (c (+ k 2)) (c (+ k 3))) a)) (set! b (cons (float-vector 1.0 (c k) (c (+ k 1))) b))) (list (float-vector-scale! (cascade->canonical a) g) ; scale entire numerator because this is the convolved form (cascade->canonical b))))) (define (prototype->highpass n num den) (let ((g 1.0) (numt (make-float-vector (length num))) (dent (make-float-vector (length den)))) (do ((k 0 (+ k 2)) (i 0 (+ i 3))) ((>= k n)) (set! g (* g (/ (num (+ i 2)) (den (+ i 2))))) (set! (numt i ) 1.0) (set! (numt (+ i 1)) (/ (num (+ i 1)) (num (+ i 2)))) (set! (numt (+ i 2)) (/ (num i) (num (+ i 2)))) (set! (dent i ) 1.0) (set! (dent (+ i 1)) (/ (den (+ i 1)) (den (+ i 2)))) (set! (dent (+ i 2)) (/ (den i) (den (+ i 2))))) (set! (numt 0) g) (list numt dent))) ;;; ---------------- Butterworth ---------------- (define (butterworth-prototype n) (let* ((len (/ (* n 3) 2)) (num (make-float-vector len)) (den (make-float-vector len))) (do ((w 1 (+ w 2)) (j 0 (+ j 3))) ((>= w n)) (set! (num j) 0.0) (set! (num (+ j 1)) 0.0) (set! (num (+ j 2)) 1.0) (set! (den j) 1.0) (set! (den (+ j 1)) (* 2.0 (cos (/ (* w pi) (* 2.0 n))))) (set! (den (+ j 2)) 1.0)) (list num den))) (define make-butterworth-lowpass (let ((documentation "(make-butterworth-lowpass n fc) returns a lowpass Buttterworth filter; n = order, fc = cutoff \ freq (srate = 1.0): (make-butterworth-lowpass 8 .1)")) (lambda (n fc) ;; identical to make-butter-lp except for fc (freq->1.0) fixup (if (odd? n) (set! n (+ n 1))) (let* ((proto (butterworth-prototype n)) (coeffs (analog->digital n (car proto) (cadr proto) fc))) (make-filter :xcoeffs (car coeffs) :ycoeffs (cadr coeffs)))))) (define make-butterworth-highpass (let ((documentation "(make-butterworth-highpass n fc) returns a highpass Butterworth filter; n = order, fc = cutoff \ freq (srate = 1.0): (make-butterworth-highpass 8 .1)")) (lambda (n fc) (if (odd? n) (set! n (+ n 1))) (let* ((proto (butterworth-prototype n)) (hproto (prototype->highpass n (car proto) (cadr proto))) (coeffs (analog->digital n (car hproto) (cadr hproto) fc))) (make-filter :xcoeffs (car coeffs) :ycoeffs (cadr coeffs)))))) (define make-butterworth-bandpass (let ((documentation "(make-butterworth-bandpass n fl fh) returns a bandpass Butterworth filter; n = order, fl and fh \ are (1.0-based) edge freqs: (make-butterworth-bandpass 4 .1 .2)")) (lambda (n fl fh) (if (odd? n) (set! n (+ n 1))) (let ((lp (make-butterworth-lowpass n fh)) (hp (make-butterworth-highpass n fl))) (lambda (y) (filter lp (filter hp y))))))) (define make-butterworth-bandstop (let ((documentation "(make-butterworth-bandstop n fl fh) returns a bandstop Butterworth filter; n = order, fl and fh \ are (1.0-based) edge freqs: (make-butterworth-bandstop 4 .1 .2)")) (lambda (n fl fh) (if (odd? n) (set! n (+ n 1))) (let ((lp (make-butterworth-lowpass n fl)) (hp (make-butterworth-highpass n fh))) (lambda (y) (+ (filter lp y) (filter hp y))))))) ;;; ---------------- Chebyshev ---------------- (define* (chebyshev-prototype n (ripple 1.0)) ; ripple in dB (positive) (let* ((e (sqrt (- (expt 10.0 (* 0.1 ripple)) 1.0))) (v0 (/ (asinh (/ 1.0 e)) n)) (len (/ (* n 3) 2)) (num (make-float-vector len)) (den (make-float-vector len))) (do ((l 1.0 (+ l 2.0)) (j 0 (+ j 3))) ((>= l n)) (let ((u (- (* (sinh v0) (sin (/ (* l pi) (* 2.0 n)))))) (w (* (cosh v0) (cos (/ (* l pi) (* 2.0 n)))))) (set! (num j ) 0.0) (set! (num (+ j 1)) 0.0) (set! (num (+ j 2)) 1.0) (set! (den j ) 1.0) (set! (den (+ j 1)) (* -2.0 u)) (set! (den (+ j 2)) (+ (* u u) (* w w))))) (set! (num 2) (/ (expt 2.0 (- 2 n)) (expt 3.2 (log ripple 10.0)))) ; whatever works... (list num den))) (define make-chebyshev-lowpass (let ((documentation "(make-chebyshev-lowpass n fc (ripple 1.0)) returns a lowpass Chebyshev filter; n = order, \ fc = cutoff freq (srate = 1.0): (make-chebyshev-lowpass 8 .1)")) (lambda* (n fc (ripple 1.0)) (if (odd? n) (set! n (+ n 1))) (let* ((proto (chebyshev-prototype n ripple)) (coeffs (analog->digital n (car proto) (cadr proto) fc))) (make-filter :xcoeffs (car coeffs) :ycoeffs (cadr coeffs)))))) (define make-chebyshev-highpass (let ((documentation "(make-chebyshev-highpass n fc (ripple 1.0)) returns a highpass Chebyshev filter; n = order, \ fc = cutoff freq (srate = 1.0): (make-chebyshev-highpass 8 .1 .01)")) (lambda* (n fc (ripple 1.0)) (if (odd? n) (set! n (+ n 1))) (let* ((proto (chebyshev-prototype n ripple)) (hproto (prototype->highpass n (car proto) (cadr proto))) (coeffs (analog->digital n (car hproto) (cadr hproto) fc))) (make-filter :xcoeffs (car coeffs) :ycoeffs (cadr coeffs)))))) (define make-chebyshev-bandpass (let ((documentation "(make-chebyshev-bandpass n fl fh (ripple 1.0)) returns a bandpass Chebyshev filter; n = order, \ fl and fh = edge freqs (srate = 1.0): (make-chebyshev-bandpass 4 .1 .2)")) (lambda* (n fl fh (ripple 1.0)) (if (odd? n) (set! n (+ n 1))) (let ((lp (make-chebyshev-lowpass n fh ripple)) (hp (make-chebyshev-highpass n fl ripple))) (lambda (y) (filter lp (filter hp y))))))) (define make-chebyshev-bandstop (let ((documentation "(make-chebyshev-bandstop n fl fh (ripple 1.0)) returns a bandstop Chebyshev filter; n = order, \ fl and fh = edge freqs (srate = 1.0): (make-chebyshev-bandstop 8 .1 .4 .01)")) (lambda* (n fl fh (ripple 1.0)) (if (odd? n) (set! n (+ n 1))) (let ((lp (make-chebyshev-lowpass n fl ripple)) (hp (make-chebyshev-highpass n fh ripple))) (lambda (y) (+ (filter lp y) (filter hp y))))))) ;;; ---------------- inverse Chebyshev ---------------- (define* (inverse-chebyshev-prototype n (loss-dB 60.0)) ; stopband loss (let* ((e (sqrt (/ 1.0 (- (expt 10.0 (* 0.1 loss-dB)) 1.0)))) (v0 (/ (asinh (/ 1.0 e)) n)) (len (/ (* n 3) 2)) (num (make-float-vector len)) (den (make-float-vector len))) (let ((pl 0.0)) (do ((l 1.0 (+ l 2.0)) (j 0 (+ j 3))) ((>= l n)) (let ((u (- (* (sinh v0) (sin (/ (* l pi) (* 2.0 n)))))) (w (* (cosh v0) (cos (/ (* l pi) (* 2.0 n))))) (t (/ 1.0 (sin (/ (* (+ l pl) pi) (* 2.0 n)))))) (set! (num j ) 1.0) (set! (num (+ j 1)) 0.0) (set! (num (+ j 2)) (* t t)) (set! (den j ) 1.0) (set! (den (+ j 1)) (/ (* -2.0 u) (+ (* u u) (* w w)))) (set! (den (+ j 2)) (/ 1.0 (+ (* u u) (* w w))))))) (list num den (expt 1.122 (- loss-dB))))) ; argh (define make-inverse-chebyshev-lowpass (let ((documentation "(make-inverse-chebyshev-lowpass n fc (loss-dB 60.0)) returns a lowpass inverse-Chebyshev filter; n = order, \ fc = cutoff freq (srate = 1.0): (make-inverse-chebyshev-lowpass 10 .4 120)")) (lambda* (n fc (loss-dB 60.0)) (if (odd? n) (set! n (+ n 1))) (let* ((proto (inverse-chebyshev-prototype n loss-dB)) (coeffs (analog->digital n (car proto) (cadr proto) fc))) (make-filter :xcoeffs (float-vector-scale! (car coeffs) (caddr proto)) :ycoeffs (cadr coeffs)))))) (define make-inverse-chebyshev-highpass (let ((documentation "(make-inverse-chebyshev-highpass n fc (loss-dB 60.0)) returns a highpass inverse-Chebyshev filter; n = order, \ fc = cutoff freq (srate = 1.0): (make-inverse-chebyshev-highpass 10 .1 120)")) (lambda* (n fc (loss-dB 60.0)) (if (odd? n) (set! n (+ n 1))) (let* ((proto (inverse-chebyshev-prototype n loss-dB)) (hproto (prototype->highpass n (car proto) (cadr proto))) (coeffs (analog->digital n (car hproto) (cadr hproto) fc))) (make-filter :xcoeffs (float-vector-scale! (car coeffs) (caddr proto)) :ycoeffs (cadr coeffs)))))) (define make-inverse-chebyshev-bandpass (let ((documentation "(make-inverse-chebyshev-bandpass n fl fh (loss-dB 60.0)) returns a bandpass inverse-Chebyshev filter; n = order, \ fl and fh are edge freqs (srate=1.0): (make-inverse-chebyshev-bandpass 8 .1 .4)")) (lambda* (n fl fh (loss-dB 60.0)) (if (odd? n) (set! n (+ n 1))) (let ((lp (make-inverse-chebyshev-lowpass n fh loss-dB)) (hp (make-inverse-chebyshev-highpass n fl loss-dB))) (lambda (y) (filter lp (filter hp y))))))) (define make-inverse-chebyshev-bandstop (let ((documentation "(make-inverse-chebyshev-bandstop n fl fh (loss-dB 60.0)) returns a bandstop inverse-Chebyshev filter; n = order, \ fl and fh are edge freqs (srate=1.0): (make-inverse-chebyshev-bandstop 8 .1 .4 90)")) (lambda* (n fl fh (loss-dB 60.0)) (if (odd? n) (set! n (+ n 1))) (let ((lp (make-inverse-chebyshev-lowpass n fl loss-dB)) (hp (make-inverse-chebyshev-highpass n fh loss-dB))) (lambda (y) (+ (filter lp y) (filter hp y))))))) ;;; ---------------- Bessel (-Thompson) ---------------- (define (bessel-prototype n) (define (fact n) (let ((x 1)) (do ((i 2 (+ i 1))) ((> i n)) (set! x (* x i))) x)) ; this form overflows if we don't have bignums ; (define (bessel-i n) ; (let ((cs (make-float-vector (+ n 1)))) ; (do ((i 0 (+ i 1))) ; ((> i n)) ; (set! (cs i) (/ (fact (- (* 2 n) i)) ; (* (expt 2 (- n i)) ; (fact i) ; (fact (- n i)))))) ; cs)) (define (bessel-i n) (let ((cs (make-float-vector (+ n 1)))) (do ((i 0 (+ i 1))) ((> i n)) (let ((val (/ 1.0 (* (fact i) (expt 2 (- n i)))))) (do ((k 1 (+ k 1)) (f (- n i -1) (+ f 1))) ; (f (+ 1 (- n i)) (+ 1 f)) ((> k n)) (set! val (* val f))) (set! (cs i) val))) cs)) (let* ((len (/ (* n 3) 2)) (num (make-float-vector len)) (den (make-float-vector len)) (b2 (bessel-i n))) (let ((p (gsl-roots (copy b2 (make-vector (length b2)))))) (do ((i 0 (+ i 1))) ((= i n)) (set! (p i) (/ (p i) (expt (b2 0) (/ 1.0 n))))) (do ((j 0 (+ j 3)) (i 0 (+ i 2))) ((>= i n)) (set! (num j ) 0.0) (set! (num (+ j 1)) 0.0) (set! (num (+ j 2)) 1.0) (set! (den j ) 1.0) (set! (den (+ j 1)) (* -2.0 (real-part (p i)))) (set! (den (+ j 2)) (real-part (* (p i) (p (+ i 1))))))) (list num den))) (define make-bessel-lowpass (let ((documentation "(make-bessel-lowpass n fc) returns a lowpass Bessel filter; n = order, fc = cutoff freq (srate = 1.0): (make-bessel-lowpass 4 .1)")) (lambda (n fc) (if (odd? n) (set! n (+ n 1))) (let* ((proto (bessel-prototype n)) (coeffs (analog->digital n (car proto) (cadr proto) fc))) (make-filter :xcoeffs (car coeffs) :ycoeffs (cadr coeffs)))))) (define make-bessel-highpass (let ((documentation "(make-bessel-highpass n fc) returns a highpass Bessel filter; n = order, fc = cutoff freq (srate = 1.0): (make-bessel-highpass 8 .1)")) (lambda* (n fc) (if (odd? n) (set! n (+ n 1))) (let* ((proto (bessel-prototype n)) (hproto (prototype->highpass n (car proto) (cadr proto))) (coeffs (analog->digital n (car hproto) (cadr hproto) fc))) (make-filter :xcoeffs (car coeffs) :ycoeffs (cadr coeffs)))))) (define make-bessel-bandpass (let ((documentation "(make-bessel-bandpass n fl fh) returns a bandpass Bessel filter; n = order, fl and fh are edge freqs (srate=1.0): (make-bessel-bandpass 4 .1 .2)")) (lambda* (n fl fh) (if (odd? n) (set! n (+ n 1))) (let ((lp (make-bessel-lowpass n fh)) (hp (make-bessel-highpass n fl))) (lambda (y) (filter lp (filter hp y))))))) (define make-bessel-bandstop (let ((documentation "(make-bessel-bandstop n fl fh) returns a bandstop Bessel filter; n = order, fl and fh are edge freqs (srate=1.0): (make-bessel-bandstop 8 .1 .2)")) (lambda* (n fl fh) (if (odd? n) (set! n (+ n 1))) (let ((lp (make-bessel-lowpass n fl)) (hp (make-bessel-highpass n fh))) (lambda (y) (+ (filter lp y) (filter hp y))))))) ;;; ---------------- Elliptic ---------------- (define* (elliptic-prototype n (ripple 1.0) (loss-dB 60.0)) (define* (minimize-function f xmin xmax arg1 arg2) (let* ((n 20) (x (make-float-vector n)) (fx (f xmin arg1 arg2))) (do ((i 0 (+ i 1))) ((= i n)) (let ((step (/ (- xmax xmin) (- n 1.0)))) (do ((j 0 (+ j 1)) (s xmin (+ s step))) ((= j (- n 1))) (float-vector-set! x j s)) (set! (x (- n 1)) xmax)) (do ((j 0 (+ j 1))) ((= j n)) (let ((ft (f (x j) arg1 arg2))) (if (< ft fx) (begin (set! fx ft) (set! xmax (if (< j (- n 1)) (x (+ j 1)) (x (- n 1)))) (set! xmin (if (> j 0) (x (- j 1)) (x 0)))))))) (/ (+ xmax xmin) 2.0))) (define (findm m arg1 arg2) (abs (- (/ (gsl-ellipk m) (gsl-ellipk (- 1.0 m))) arg1))) (define (findv u arg1 arg2) (let ((vals (gsl-ellipj u arg1))) (abs (- arg2 (/ (car vals) (cadr vals)))))) (let* ((e (sqrt (- (expt 10.0 (* 0.1 ripple)) 1.0))) (k1 (/ e (sqrt (- (expt 10.0 (* 0.1 loss-dB)) 1.0)))) (k1p (sqrt (- 1.0 (* k1 k1)))) (kr 0.0) (m 0.0) (k 0.0) (len (/ (* n 3) 2)) (num (make-float-vector len)) (den (make-float-vector len)) (g 1.0) (eps 0.0000001)) (if (> (abs (- 1.0 (* k1p k1p))) eps) (set! kr (* n (/ (gsl-ellipk (* k1 k1)) (gsl-ellipk (* k1p k1p)))))) (set! m (minimize-function findm 0.001 0.999 kr)) (set! k (gsl-ellipk m)) (let ((cv (make-float-vector (floor (* 0.5 3 (+ n 1)))))) (do ((i 0 (+ i 2)) (j 0 (+ j 3))) ((>= i n)) (let* ((vals (gsl-ellipj (/ (* (+ i 1) k) (* 1.0 n)) m)) (sn (car vals)) (cn (cadr vals)) (dn (caddr vals))) (set! (cv j ) sn) (set! (cv (+ j 1)) cn) (set! (cv (+ j 2)) dn) (let* ((z (/ 0.0-i (* (sqrt m) sn))) (pz (real-part (* z (complex (real-part z) (- (imag-part z))))))) (set! g (/ g pz)) (set! (num j ) 1.0) (set! (num (+ j 1)) (* -2.0 (real-part z))) (set! (num (+ j 2)) pz)))) (let* ((optarg0 (* k1p k1p)) (optarg1 (/ 1.0 e)) (minf (minimize-function findv 0.0 (/ 1.0 e) optarg0 optarg1)) (v0 (/ (* k minf) (* n (gsl-ellipk (* k k1))))) (vals (gsl-ellipj v0 (- 1.0 m))) (sn (car vals)) (cn (cadr vals)) (dn (caddr vals))) (do ((i 0 (+ i 2)) (j 0 (+ j 3))) ((>= i n)) (let ((p (/ (- (+ (* (cv (+ j 1)) (cv (+ j 2)) sn cn) (* 0.0+i (cv j) dn))) (- 1.0 (* (cv (+ j 2)) sn (cv (+ j 2)) sn))))) (let ((pp (real-part (* p (complex (real-part p) (- (imag-part p))))))) (set! g (* g pp)) (set! (den j ) 1.0) (set! (den (+ j 1)) (* -2.0 (real-part p))) (set! (den (+ j 2)) pp)))))) (set! g (abs (/ g (sqrt (+ 1.0 (* e e)))))) (list num den g))) (define make-elliptic-lowpass (let ((documentation "(make-elliptic-lowpass n fc (ripple 1.0) (loss-dB 60.0)) returns a lowpass elliptic filter; n = order, \ fc = cutoff freq (srate = 1.0): (make-elliptic-lowpass 8 .25 .01 90)")) (lambda* (n fc (ripple 1.0) (loss-dB 60.0)) (if (odd? n) (set! n (+ n 1))) (let* ((proto (elliptic-prototype n ripple loss-dB)) (coeffs (analog->digital n (car proto) (cadr proto) fc))) (make-filter :xcoeffs (float-vector-scale! (car coeffs) (caddr proto)) :ycoeffs (cadr coeffs)))))) (define make-elliptic-highpass (let ((documentation "(make-elliptic-highpass n fc (ripple 1.0) (loss-dB 60.0)) returns a highpass elliptic filter; n = order, \ fc = cutoff freq (srate = 1.0): (make-elliptic-highpass 8 .25 .01 90)")) (lambda* (n fc (ripple 1.0) (loss-dB 60.0)) (if (odd? n) (set! n (+ n 1))) (let* ((proto (elliptic-prototype n ripple loss-dB)) (hproto (prototype->highpass n (car proto) (cadr proto))) (coeffs (analog->digital n (car hproto) (cadr hproto) fc))) (make-filter :xcoeffs (float-vector-scale! (car coeffs) (caddr proto)) :ycoeffs (cadr coeffs)))))) (define make-elliptic-bandpass (let ((documentation "(make-elliptic-bandpass n fl fh (ripple 1.0) (loss-dB 60.0)) returns a bandpass elliptic filter; n = order, \ fl and fh are edge freqs (srate=1.0): (make-elliptic-bandpass 6 .1 .2 .1 90)")) (lambda* (n fl fh (ripple 1.0) (loss-dB 60.0)) (if (odd? n) (set! n (+ n 1))) (let ((lp (make-elliptic-lowpass n fh ripple loss-dB)) (hp (make-elliptic-highpass n fl ripple loss-dB))) (lambda (y) (filter lp (filter hp y))))))) (define make-elliptic-bandstop (let ((documentation "(make-elliptic-bandstop n fl fh (ripple 1.0) (loss-dB 60.0)) returns a bandstop elliptic filter; n = order, \ fl and fh are edge freqs (srate=1.0): (make-elliptic-bandstop 6 .1 .2 .1 90)")) (lambda* (n fl fh (ripple 1.0) (loss-dB 60.0)) (if (odd? n) (set! n (+ n 1))) (let ((lp (make-elliptic-lowpass n fl ripple loss-dB)) (hp (make-elliptic-highpass n fh ripple loss-dB))) (lambda (y) (+ (filter lp y) (filter hp y))))))) snd-16.1/snd-menu.h0000644000076400007640000002130412306421667012241 0ustar bilbil#ifndef SND_MENU_H #define SND_MENU_H #define I_LINES_OR_DOTS "Dots or lines" #define I_CHANNEL_LAYOUT "Channel layout" #define I_ZOOM_CENTERS_ON "Zoom centers on" #define I_AXIS_LAYOUT "Axis layout" enum {m_menu, f_menu, f_cascade_menu, f_open_menu, f_open_recent_menu, f_open_recent_cascade_menu, f_close_menu, f_close_all_menu, f_save_menu, f_save_as_menu, f_revert_menu, f_exit_menu, f_new_menu, f_view_menu, f_print_menu, f_mix_menu, f_insert_menu, f_update_menu, f_sep_menu, e_menu, e_cascade_menu, e_cut_menu, e_paste_menu, e_mix_menu, e_play_menu, e_save_as_menu, e_undo_menu, e_redo_menu, e_find_menu, e_env_menu, e_header_menu, e_select_all_menu, e_unselect_menu, e_select_sep_menu, e_edit_sep_menu, h_menu, h_cascade_menu, h_about_snd_menu, h_fft_menu, h_find_menu, h_undo_menu, h_sync_menu, h_controls_menu, h_env_menu, h_marks_menu, h_sound_files_menu, h_init_file_menu, h_mix_menu, h_keys_menu, h_play_menu, h_save_menu, h_resample_menu, h_filter_menu, h_insert_menu, h_delete_menu, h_reverb_menu, h_debug_menu, h_region_menu, h_selection_menu, h_colors_menu, o_menu, o_cascade_menu, o_transform_menu, o_controls_menu, o_save_state_menu, o_sep_menu, o_preferences_menu, v_menu, v_cascade_menu, v_graph_style_menu, v_graph_style_cascade_menu, v_lines_menu, v_dots_menu, v_filled_menu, v_dots_and_lines_menu, v_lollipops_menu, v_zero_menu, v_cursor_menu, v_inset_menu, v_controls_menu, v_listener_menu, v_region_menu, v_combine_menu, v_combine_cascade_menu, v_combine_separate_menu, v_combine_combined_menu, v_combine_superimposed_menu, v_color_orientation_menu, v_files_menu, v_mix_dialog_menu, v_x_axis_menu, v_x_axis_cascade_menu, v_x_axis_seconds_menu, v_x_axis_samples_menu, v_x_axis_percentage_menu, v_x_axis_beats_menu, v_x_axis_measures_menu, v_x_axis_clock_menu, v_axes_menu, v_axes_cascade_menu, v_no_axes_menu, v_all_axes_menu, v_just_x_axis_menu, v_all_axes_unlabelled_menu, v_just_x_axis_unlabelled_menu, v_bare_x_axis_menu, v_focus_style_menu, v_focus_cascade_menu, v_focus_right_menu, v_focus_left_menu, v_focus_middle_menu, v_focus_active_menu, v_grid_menu, v_sep2_menu, NUM_MENU_WIDGETS }; #define main_menu (ss->mw[m_menu]) #define file_menu (ss->mw[f_menu]) #define file_cascade_menu (ss->mw[f_cascade_menu]) #define file_open_menu (ss->mw[f_open_menu]) #define file_open_recent_menu (ss->mw[f_open_recent_menu]) #define file_open_recent_cascade_menu (ss->mw[f_open_recent_cascade_menu]) #define file_close_menu (ss->mw[f_close_menu]) #define file_close_all_menu (ss->mw[f_close_all_menu]) #define file_save_menu (ss->mw[f_save_menu]) #define file_save_as_menu (ss->mw[f_save_as_menu]) #define file_revert_menu (ss->mw[f_revert_menu]) #define file_exit_menu (ss->mw[f_exit_menu]) #define file_new_menu (ss->mw[f_new_menu]) #define file_view_menu (ss->mw[f_view_menu]) #define file_print_menu (ss->mw[f_print_menu]) #define file_mix_menu (ss->mw[f_mix_menu]) #define file_insert_menu (ss->mw[f_insert_menu]) #define file_update_menu (ss->mw[f_update_menu]) #define file_sep_menu (ss->mw[f_sep_menu]) #define edit_menu (ss->mw[e_menu]) #define edit_cascade_menu (ss->mw[e_cascade_menu]) #define edit_cut_menu (ss->mw[e_cut_menu]) #define edit_paste_menu (ss->mw[e_paste_menu]) #define edit_mix_menu (ss->mw[e_mix_menu]) #define edit_play_menu (ss->mw[e_play_menu]) #define edit_save_as_menu (ss->mw[e_save_as_menu]) #define edit_undo_menu (ss->mw[e_undo_menu]) #define edit_redo_menu (ss->mw[e_redo_menu]) #define edit_find_menu (ss->mw[e_find_menu]) #define edit_env_menu (ss->mw[e_env_menu]) #define edit_header_menu (ss->mw[e_header_menu]) #define edit_select_all_menu (ss->mw[e_select_all_menu]) #define edit_unselect_menu (ss->mw[e_unselect_menu]) #define edit_select_sep_menu (ss->mw[e_select_sep_menu]) #define edit_edit_sep_menu (ss->mw[e_edit_sep_menu]) #define help_menu (ss->mw[h_menu]) #define help_cascade_menu (ss->mw[h_cascade_menu]) #define help_about_snd_menu (ss->mw[h_about_snd_menu]) #define help_fft_menu (ss->mw[h_fft_menu]) #define help_find_menu (ss->mw[h_find_menu]) #define help_undo_menu (ss->mw[h_undo_menu]) #define help_sync_menu (ss->mw[h_sync_menu]) #define help_controls_menu (ss->mw[h_controls_menu]) #define help_env_menu (ss->mw[h_env_menu]) #define help_marks_menu (ss->mw[h_marks_menu]) #define help_sound_files_menu (ss->mw[h_sound_files_menu]) #define help_init_file_menu (ss->mw[h_init_file_menu]) #define help_mix_menu (ss->mw[h_mix_menu]) #define help_keys_menu (ss->mw[h_keys_menu]) #define help_play_menu (ss->mw[h_play_menu]) #define help_save_menu (ss->mw[h_save_menu]) #define help_resample_menu (ss->mw[h_resample_menu]) #define help_filter_menu (ss->mw[h_filter_menu]) #define help_insert_menu (ss->mw[h_insert_menu]) #define help_delete_menu (ss->mw[h_delete_menu]) #define help_reverb_menu (ss->mw[h_reverb_menu]) #define help_debug_menu (ss->mw[h_debug_menu]) #define help_region_menu (ss->mw[h_region_menu]) #define help_selection_menu (ss->mw[h_selection_menu]) #define help_colors_menu (ss->mw[h_colors_menu]) #define options_menu (ss->mw[o_menu]) #define options_cascade_menu (ss->mw[o_cascade_menu]) #define options_transform_menu (ss->mw[o_transform_menu]) #define options_save_state_menu (ss->mw[o_save_state_menu]) #define options_sep_menu (ss->mw[o_sep_menu]) #define options_preferences_menu (ss->mw[o_preferences_menu]) #define options_controls_menu (ss->mw[o_controls_menu]) #define view_menu (ss->mw[v_menu]) #define view_cascade_menu (ss->mw[v_cascade_menu]) #define view_graph_style_menu (ss->mw[v_graph_style_menu]) #define view_graph_style_cascade_menu (ss->mw[v_graph_style_cascade_menu]) #define view_lines_menu (ss->mw[v_lines_menu]) #define view_dots_menu (ss->mw[v_dots_menu]) #define view_filled_menu (ss->mw[v_filled_menu]) #define view_dots_and_lines_menu (ss->mw[v_dots_and_lines_menu]) #define view_lollipops_menu (ss->mw[v_lollipops_menu]) #define view_zero_menu (ss->mw[v_zero_menu]) #define view_cursor_menu (ss->mw[v_cursor_menu]) #define view_inset_menu (ss->mw[v_inset_menu]) #define view_controls_menu (ss->mw[v_controls_menu]) #define view_listener_menu (ss->mw[v_listener_menu]) #define view_region_menu (ss->mw[v_region_menu]) #define view_combine_menu (ss->mw[v_combine_menu]) #define view_combine_cascade_menu (ss->mw[v_combine_cascade_menu]) #define view_combine_separate_menu (ss->mw[v_combine_separate_menu]) #define view_combine_combined_menu (ss->mw[v_combine_combined_menu]) #define view_combine_superimposed_menu (ss->mw[v_combine_superimposed_menu]) #define view_color_orientation_menu (ss->mw[v_color_orientation_menu]) #define view_files_menu (ss->mw[v_files_menu]) #define view_mix_dialog_menu (ss->mw[v_mix_dialog_menu]) #define view_x_axis_menu (ss->mw[v_x_axis_menu]) #define view_x_axis_cascade_menu (ss->mw[v_x_axis_cascade_menu]) #define view_x_axis_seconds_menu (ss->mw[v_x_axis_seconds_menu]) #define view_x_axis_clock_menu (ss->mw[v_x_axis_clock_menu]) #define view_x_axis_samples_menu (ss->mw[v_x_axis_samples_menu]) #define view_x_axis_percentage_menu (ss->mw[v_x_axis_percentage_menu]) #define view_x_axis_beats_menu (ss->mw[v_x_axis_beats_menu]) #define view_x_axis_measures_menu (ss->mw[v_x_axis_measures_menu]) #define view_axes_menu (ss->mw[v_axes_menu]) #define view_axes_cascade_menu (ss->mw[v_axes_cascade_menu]) #define view_no_axes_menu (ss->mw[v_no_axes_menu]) #define view_all_axes_menu (ss->mw[v_all_axes_menu]) #define view_just_x_axis_menu (ss->mw[v_just_x_axis_menu]) #define view_all_axes_unlabelled_menu (ss->mw[v_all_axes_unlabelled_menu]) #define view_just_x_axis_unlabelled_menu (ss->mw[v_just_x_axis_unlabelled_menu]) #define view_bare_x_axis_menu (ss->mw[v_bare_x_axis_menu]) #define view_sep2_menu (ss->mw[v_sep2_menu]) #define view_focus_style_menu (ss->mw[v_focus_style_menu]) #define view_focus_cascade_menu (ss->mw[v_focus_cascade_menu]) #define view_focus_right_menu (ss->mw[v_focus_right_menu]) #define view_focus_left_menu (ss->mw[v_focus_left_menu]) #define view_focus_middle_menu (ss->mw[v_focus_middle_menu]) #define view_focus_active_menu (ss->mw[v_focus_active_menu]) #define view_grid_menu (ss->mw[v_grid_menu]) void edit_menu_update(void); void view_menu_update(void); void file_menu_update(void); void update_file_from_menu(void); void revert_file_from_menu(void); void save_state_from_menu(void); void unprotect_callback(int slot); int g_add_to_main_menu(const char *label, int slot); widget_t g_add_to_menu(int which_menu, const char *label, int callb, int position); int g_remove_from_menu(int which_menu, const char *label); void g_menu_callback(int callb); #endif snd-16.1/r7rs.scm0000644000076400007640000003473412624210506011745 0ustar bilbil;;; r7rs compatibility (require cload.scm libc.scm stuff.scm) (provide 'r7rs.scm) (define (vector-map p . args) (apply vector (apply map p args))) (define (string-map p . args) (apply string (apply map p args))) (define vector-for-each for-each) (define string-for-each for-each) (define* (vector->string v (start 0) end) (let ((stop (or end (length v)))) (copy v (make-string (- stop start)) start stop))) (define* (string->vector s (start 0) end) (let ((stop (or end (length s)))) (copy s (make-vector (- stop start)) start stop))) (define list-copy copy) (define* (vector-copy v (start 0) end) (let ((stop (or end (length v)))) (copy v (make-vector (- stop start)) start stop))) (define* (r7rs-string-copy s (start 0) end) (let ((stop (or end (length s)))) (copy s (make-string (- stop start)) start stop))) (define r7rs-vector-fill! fill!) ; or do these return the sequence, not the filler? (define r7rs-string-fill! fill!) (define* (vector-copy! dest at src (start 0) end) ; apparently end is exclusive here? (let ((len (or end (length src)))) (if (or (not (eq? dest src)) (<= at start)) (do ((i at (+ i 1)) (k start (+ k 1))) ((= k len) dest) (set! (dest i) (src k))) (do ((i (+ at (- len start 1)) (- i 1)) (k (- len 1) (- k 1))) ((< k start) dest) (set! (dest i) (src k)))))) (define (r7rs-make-hash-table . args) (if (null? args) (#_make-hash-table) (if (procedure? (car args)) (#_make-hash-table (if (null? (cdr args)) 511 (cadr args)) (car args)) (apply #_make-hash-table args)))) (define bytevector byte-vector) (define ->bytevector ->byte-vector) (define bytevector? byte-vector?) (define make-bytevector make-byte-vector) (define bytevector-copy! vector-copy!) (define string-copy! vector-copy!) (define (bytevector->list bv) (map values bv)) (define (boolean=? . args) (or (null? args) (and (boolean? (car args)) (or (null? (cdr args)) (every? (lambda (obj) (eq? (car args) obj)) (cdr args)))))) (define (symbol=? . args) (or (null? args) (and (symbol? (car args)) (or (null? (cdr args)) (every? (lambda (obj) (eq? (car args) obj)) (cdr args)))))) (define char-foldcase char-downcase) (define string-foldcase string-downcase) ;;; these and the string functions in s7 are not unicode-aware. To get true unicode ;;; handling of the bytes, use the glib functions in libxg or use cload (see xgdata.scm). (define (digit-value c) (and (char-numeric? c) (- (char->integer c) (char->integer #\0)))) (define +inf.0 inf.0) (define +nan.0 nan.0) (define (finite? n) (and (number? n) (not (nan? n)) (not (infinite? n)))) (define exact-integer? integer?) (define (exact-integer-sqrt i) (let ((sq (floor (sqrt i)))) (values sq (- i (* sq sq))))) (define inexact exact->inexact) (define exact inexact->exact) (define (square x) (* x x)) (define truncate-quotient quotient) (define truncate-remainder remainder) (define floor-remainder modulo) (define (floor-quotient x y) (floor (/ x y))) (define (input-port-open? p) (not (port-closed? p))) (define (output-port-open? p) (not (port-closed? p))) (define (port? p) (or (input-port? p) (output-port? p))) (define binary-port? port?) (define textual-port? port?) (define (close-port p) (if (input-port? p) (close-input-port p) (close-output-port p))) (define open-binary-input-file open-input-file) (define open-binary-output-file open-output-file) (define (call-with-port port proc) ((if (input-port? port) call-with-input-file call-with-output-file) port proc)) (define (bytevector-u8-ref b k) (b k)) (define (bytevector-u8-set! b k c) (set! (b k) c)) (define bytevector-length length) (define (bytevector-copy . args) (->byte-vector (apply string-copy args))) (define (bytevector-append . args) (->byte-vector (apply string-append args))) (define write-bytevector write-string) (define* (read-bytevector! bv port (start 0) end) (let ((lim (or end (length bv))) (pt (or port (current-input-port)))) (do ((i start (+ i 1)) (c (read-byte pt) (read-byte pt))) ((or (>= i lim) (eof-object? c)) bv) (set! (bv i) c)))) (define* (read-bytevector k port) (read-bytevector! (->byte-vector (make-string k)) port)) (define (get-output-bytevector port) (->byte-vector (get-output-string port))) (define open-input-bytevector open-input-string) (define open-output-bytevector open-output-string) (define read-u8 read-byte) (define write-u8 write-byte) (define u8-ready? char-ready?) (define peek-u8 peek-char) (define* (utf8->string v (start 0) end) (substring v start (or end (length v)))) (define* (string->utf8 s (start 0) end) (->byte-vector (substring s start (or end (length s))))) (define write-simple write) (define (eof-object) #) (define (features) *features*) (define (with-exception-handler handler thunk) (catch #t thunk handler)) (define raise error) (define raise-continuable error) (define-macro (guard results . body) `(let ((,(car results) (catch #t (lambda () ,@body) (lambda args (car args))))) (cond ,@(cdr results)))) (define (read-error? obj) (eq? (car obj) 'read-error)) (define (file-error? obj) (eq? (car obj) 'io-error)) (define (error-message obj) (apply format #f (cadr obj))) (define error-irritants cdadr) (define interaction-environment curlet) (define-macro (include . files) `(begin ,@(map (lambda (file) `(load ,file (outlet (curlet)))) files))) (set! *#readers* (cons (cons #\; (lambda (s) (read) (values))) *#readers*)) ;; I prefer (define-expansion (comment . stuff) (reader-cond (#t (values)))) ;; or (format #f "~^ this is a comment ") (define-macro (define-values vars . body) `(apply begin (map (lambda (var val) `(define ,var ,val)) ',vars (list (begin ,@body))))) (define-macro (let*-values vars . body) `(let () ,@(map (lambda (nvars . nbody) `(apply define-values ',nvars ',@nbody)) (map car vars) (map cdr vars)) ,@body)) ;; case-lambda (define-macro (case-lambda . choices) `(lambda args (case (length args) ,@(map (lambda (choice) (if (or (symbol? (car choice)) (negative? (length (car choice)))) `(else (apply (lambda ,(car choice) ,@(cdr choice)) args)) `((,(length (car choice))) (apply (lambda ,(car choice) ,@(cdr choice)) args)))) choices)))) ;; parameters (define* (make-parameter init converter) (let* ((convert (or converter (lambda (x) x))) (old-values ()) ; see below -- this is part of the funclet (value (convert init))) (lambda () value))) (define-macro (parameterize vars . body) `(dynamic-wind (lambda () ,@(map (lambda (var) `(with-let (funclet ,(car var)) (set! old-values (cons value old-values)) (set! value (convert ,(cadr var))))) vars)) (lambda () ,@body) (lambda () ,@(map (lambda (var) `(with-let (funclet ,(car var)) (set! value (car old-values)) (set! old-values (cdr old-values)))) vars)))) ;; libraries (apply define (symbol (object->string '(scheme base))) (inlet) ()) ; ignore (scheme base) (apply define (symbol (object->string '(scheme read))) (inlet) ()) ; and so on... what a pile of baloney (apply define (symbol (object->string '(scheme write))) (inlet) ()) (apply define (symbol (object->string '(scheme time))) (inlet) ()) (apply define (symbol (object->string '(scheme file))) (inlet) ()) (apply define (symbol (object->string '(scheme cxr))) (inlet) ()) (apply define (symbol (object->string '(scheme inexact))) (inlet) ()) (apply define (symbol (object->string '(scheme char))) (inlet) ()) (apply define (symbol (object->string '(scheme complex))) (inlet) ()) (define-macro (define-library libname . body) ; |(lib name)| -> environment `(define ,(symbol (object->string libname)) (with-let (sublet (unlet) (cons 'import (symbol->value 'import)) (cons '*export* ()) (cons 'export (symbol->value (define-macro (,(gensym) . names) `(set! *export* (append ',names *export*)))))) ,@body (apply inlet (map (lambda (entry) (if (or (member (car entry) '(*export* export import)) (and (pair? *export*) (not (member (car entry) *export*)))) (values) entry)) (curlet)))))) (define-macro (import . libs) `(varlet (curlet) ,@(map (lambda (lib) (case (car lib) ((only) `((lambda (e names) (apply inlet (map (lambda (name) (cons name (e name))) names))) (symbol->value (symbol (object->string (cadr ',lib)))) (cddr ',lib))) ((except) `((lambda (e names) (apply inlet (map (lambda (entry) (if (member (car entry) names) (values) entry)) e))) (symbol->value (symbol (object->string (cadr ',lib)))) (cddr ',lib))) ((prefix) `((lambda (e prefx) (apply inlet (map (lambda (entry) (cons (string->symbol (string-append (symbol->string prefx) (symbol->string (car entry)))) (cdr entry))) e))) (symbol->value (symbol (object->string (cadr ',lib)))) (caddr ',lib))) ((rename) `((lambda (e names) (apply inlet (map (lambda (entry) (let ((info (assoc (car entry) names))) (if info (cons (cadr info) (cdr entry)) entry))) ; I assume the un-renamed ones are included e))) (symbol->value (symbol (object->string (cadr ',lib)))) (cddr ',lib))) (else `(let ((sym (symbol (object->string ',lib)))) (if (not (defined? sym)) (format #t "~A not loaded~%" sym) (symbol->value sym)))))) libs))) ;; delay and force: ugh ;; this implementation is based on the r7rs spec (define-macro (delay-force expr) `(make-promise #f (lambda () ,expr))) (define-macro (r7rs-delay expr) ; "delay" is taken damn it `(delay-force (make-promise #t (lambda () ,expr)))) (define (make-promise done? proc) (list (cons done? proc))) (define (force promise) (if (caar promise) ((cdar promise)) (let ((promise* ((cdar promise)))) (if (not (caar promise)) (begin (set-car! (car promise) (caar promise*)) (set-cdr! (car promise) (cdar promise*)))) (force promise)))) ;; floor/ and truncate/ can't work as intended: they assume that multiple values ;; are not spliced. The "division library" is a trivial, pointless micro-optimization. ;; and why no euclidean-rationalize or exact-integer-expt? ;; (imagine what will happen when r8rs stumbles on the zoo of continued fraction algorithms!) (let ((e (curlet))) (c-define '((in-C "static int g_time(void) {return((int)time(NULL));} \n\ static struct timeval overall_start_time; \n\ static bool time_set_up = false; \n\ static double get_internal_real_time(void) \n\ { \n\ struct timezone z0; \n\ struct timeval t0; \n\ double secs; \n\ if (!time_set_up) {gettimeofday(&overall_start_time, &z0); time_set_up = true;} \n\ gettimeofday(&t0, &z0); \n\ secs = difftime(t0.tv_sec, overall_start_time.tv_sec);\n\ return(secs + 0.000001 * (t0.tv_usec - overall_start_time.tv_usec)); \n\ }") (double get_internal_real_time (void)) (int g_time (void))) "" '("time.h" "sys/time.h")) (varlet e (cons 'jiffies-per-second (lambda () 1000)) (cons 'current-jiffy (lambda () (round (* (get_internal_real_time) 1000.0)))) (cons 'current-second g_time))) (define get-environment-variable (*libc* 'getenv)) (define get-environment-variables (*libc* 'getenvs)) (define (r7rs-file-exists? arg) (= ((*libc* 'access) arg (*libc* 'F_OK)) 0)) (define r7rs-delete-file (*libc* 'unlink)) (define (os-type) (car ((*libc* 'uname)))) (define (cpu-architecture) (cadr ((*libc* 'uname)))) (define (machine-name) (caddr ((*libc* 'uname)))) (define (os-version) (string-append (list-ref ((*libc* 'uname)) 3) " " (list-ref ((*libc* 'uname)) 4))) (define (implementation-name) "s7") (define (implementation-version) (substring (s7-version) 3 7)) ;; command-line is problematic: s7 has no access to the caller's "main" function, and ;; outside Windows, there's no reasonable way to get these arguments. ;; in Linux, you might win with: (define (command-line) (let ((lst ())) (with-input-from-file "/proc/self/cmdline" (lambda () (do ((c (read-char) (read-char)) (s "")) ((eof-object? c) (reverse lst)) (if (char=? c #\null) (begin (set! lst (cons s lst)) (set! s "")) (set! s (string-append s (string c))))))))) ;; other minor differences: ;; in s7, single-quote can occur in a name ;; s7 doesn't currently implement #\xxxx characters ;; records (define-macro (define-record-type type make ? . fields) (let ((new-type (if (pair? type) (car type) type)) (inherited (if (pair? type) `(list ,@(cdr type)) ()))) `(begin (define-class ,new-type ,inherited (map (lambda (f) (if (pair? f) (car f) f)) ',fields)) (define (,? obj) ; perhaps the define-class type predicate should use this (define (search-inherited obj type) (define (search-inheritors objs type) (and (pair? objs) (or (search-inherited (car objs) type) (search-inheritors (cdr objs) type)))) (or (eq? (obj 'class-name) type) (search-inheritors (obj 'inherited) type))) (and (let? obj) (search-inherited obj ',new-type))) (define ,make (let ((new-obj (copy ,new-type))) ,@(map (lambda (slot) `(set! (new-obj ',slot) ,slot)) (cdr make)) new-obj)) ,@(map (lambda (field) (if (pair? field) (if (null? (cdr field)) (values) (if (null? (cddr field)) `(define (,(cadr field) obj) (if (not (,? obj)) (error 'wrong-type-arg "~S should be a ~A" obj ',type)) (obj ',(car field))) `(begin (define (,(cadr field) obj) (if (not (,? obj)) (error 'wrong-type-arg "~S should be a ~A" obj ',type)) (obj ',(car field))) (define (,(caddr field) obj val) (if (not (,? obj)) (error 'wrong-type-arg "~S should be a ~A" obj ',type)) (set! (obj ',(car field)) val))))))) fields) ',new-type))) ;;; srfi 111: (define-record-type box-type (box value) box? (value unbox set-box!)) snd-16.1/poly.rb0000644000076400007640000004307012434353162011652 0ustar bilbil# poly.rb -- polynomial-related stuff; poly.scm --> poly.rb # Translator: Michael Scholz # Created: 05/04/09 23:55:07 # Changed: 14/11/21 05:06:17 # class Complex # to_f # to_f_or_c # # class Poly < Vec # inspect # to_poly # reduce # +(other) # *(other) # /(other) # derivative # resultant(other) # discriminant # gcd(other) # roots # eval(x) # # class Float # +(other) # *(other) # /(other) # # class String # to_poly # # class Array # to_poly # # class Vct # to_poly # # Poly(obj) # make_poly(len, init, &body) # poly?(obj) # poly(*vals) # poly_reduce(obj) # poly_add(obj1, obj2) # poly_multiply(obj1, obj2) # poly_div(obj1, obj2) # poly_derivative(obj) # poly_gcd(obj1, obj2) # poly_roots(obj) require "clm" require "mix" include Math class Complex attr_writer :real, :imag with_silence do def to_f self.real.to_f end end def to_f_or_c self.imag.zero? ? self.to_f : self end end class Poly < Vec Poly_roots_epsilon = 1.0e-6 def inspect @name = "poly" super end def to_poly self end def reduce if self.last.zero? i = self.length - 1 while self[i].zero? and i > 0 i -= 1 end self[0, i + 1] else self end end # [1, 2, 3].to_poly.reduce ==> poly(1.0, 2.0, 3.0) # poly(1, 2, 3, 0, 0, 0).reduce ==> poly(1.0, 2.0, 3.0) # vct(0, 0, 0, 0, 1, 0).to_poly.reduce ==> poly(0.0, 0.0, 0.0, 0.0, 1.0) def poly_add(other) assert_type((array?(other) or vct?(other) or number?(other)), other, 0, "a poly, a vct an array, or a number") if number?(other) v = self.dup v[0] += other v else if self.length > other.length self.add(other) else Poly(other).add(self) end end end alias + poly_add # poly(0.1, 0.2, 0.3) + poly(0, 1, 2, 3, 4) ==> poly(0.1, 1.2, 2.3, 3.0, 4.0) # poly(0.1, 0.2, 0.3) + 0.5 ==> poly(0.6, 0.2, 0.3) # 0.5 + poly(0.1, 0.2, 0.3) ==> poly(0.6, 0.2, 0.3) def poly_multiply(other) assert_type((array?(other) or vct?(other) or number?(other)), other, 0, "a poly, a vct, an array, or a number") if number?(other) Poly(self.scale(Float(other))) else len = self.length + other.length m = Poly.new(len, 0.0) self.each_with_index do |val1, i| other.each_with_index do |val2, j| m[i + j] = m[i + j] + val1 * val2 end end m end end alias * poly_multiply # poly(1, 1) * poly(-1, 1) ==> poly(-1.0, 0.0, 1.0, 0.0) # poly(-5, 1) * poly(3, 7, 2) ==> poly(-15.0, -32.0, -3.0, 2.0, 0.0) # poly(-30, -4, 2) * poly(0.5, 1) ==> poly(-15.0, -32.0, -3.0, 2.0, 0.0) # poly(-30, -4, 2) * 0.5 ==> poly(-15.0, -2.0, 1.0) # 2.0 * poly(-30, -4, 2) ==> poly(-60.0, -8.0, 4.0) def poly_div(other) assert_type((array?(other) or vct?(other) or number?(other)), other, 0, "a poly, a vct, an array, or a number") if number?(other) [self * (1.0 / other), poly(0.0)] else if other.length > self.length [poly(0.0), other.to_poly] else r = self.dup q = Poly.new(self.length, 0.0) n = self.length - 1 nv = other.length - 1 (n - nv).downto(0) do |i| q[i] = r[nv + i] / other[nv] (nv + i - 1).downto(i) do |j| r[j] = r[j] - q[i] * other[j - i] end end nv.upto(n) do |i| r[i] = 0.0 end [q, r] end end end alias / poly_div # poly(-1.0, 0.0, 1.0) / poly(1.0, 1.0) # ==> [poly(-1.0, 1.0, 0.0), poly(0.0, 0.0, 0.0)] # poly(-15, -32, -3, 2) / poly(-5, 1) # ==> [poly(3.0, 7.0, 2.0, 0.0), poly(0.0, 0.0, 0.0, 0.0)] # poly(-15, -32, -3, 2) / poly(3, 1) # ==> [poly(-5.0, -9.0, 2.0, 0.0), poly(0.0, 0.0, 0.0, 0.0)] # poly(-15, -32, -3, 2) / poly(0.5, 1) # ==> [poly(-30.0, -4.0, 2.0, 0.0), poly(0.0, 0.0, 0.0, 0.0)] # poly(-15, -32, -3, 2) / poly(3, 7, 2) # ==> [poly(-5.0, 1.0, 0.0, 0.0), poly(0.0, 0.0, 0.0, 0.0)] # poly(-15, -32, -3, 2) / 2.0 # ==> [poly(-7.5, -16.0, -1.5, 1.0), poly(0.0)] def derivative len = self.length - 1 pl = Poly.new(len, 0.0) j = len (len - 1).downto(0) do |i| pl[i] = self[j] * j j -= 1 end pl end # poly(0.5, 1.0, 2.0, 4.0).derivative ==> poly(1.0, 4.0, 12.0) def resultant(other) m = self.length m1 = m - 1 n = other.length n1 = n - 1 d = n1 + m1 mat = Array.new(d) do Vct.new(d, 0.0) end n1.times do |i| m.times do |j| mat[i][i + j] = self[m1 - j] end end m1.times do |i| n.times do |j| mat[i + n1][i + j] = other[n1 - j] end end determinant(mat) end # poly(-1, 0, 1).resultant([1, -2, 1]) ==> 0.0 # poly(-1, 0, 2).resultant([1, -2, 1]) ==> 1.0 # poly(-1, 0, 1).resultant([1, 1]) ==> 0.0 # poly(-1, 0, 1).resultant([2, 1]) ==> 3.0 def discriminant self.resultant(self.derivative) end # poly(-1, 0, 1).discriminant ==> -4.0 # poly(1, -2, 1).discriminant ==> 0.0 # (poly(-1, 1) * poly(-1, 1) * poly(3, 1)).reduce.discriminant # ==> 0.0 # (poly(-1, 1) * poly(-1, 1) * poly(3, 1) * poly(2, 1)).reduce.discriminant # ==> 0.0 # (poly(1, 1) * poly(-1, 1) * poly(3, 1) * poly(2, 1)).reduce.discriminant # ==> 2304.0 # (poly(1, 1) * poly(-1, 1) * poly(3, 1) * poly(3, 1)).reduce.discriminant # ==> 0.0 def gcd(other) assert_type((array?(other) or vct?(other)), other, 0, "a poly, a vct or an array") if self.length < other.length poly(0.0) else qr = self.poly_div(other).map do |m| m.reduce end if qr[1].length == 1 if qr[1][0].zero? Poly(other) else poly(0.0) end else qr[0].gcd(qr[1]) end end end # (poly(2, 1) * poly(-3, 1)).reduce.gcd(poly(2, 1)) # ==> poly(2.0, 1.0) # (poly(2, 1) * poly(-3, 1)).reduce.gcd(poly(3, 1)) # ==> poly(0.0) # (poly(2, 1) * poly(-3, 1)).reduce.gcd(poly(-3, 1)) # ==> poly(-3.0, 1.0) # (poly(8, 1) * poly(2, 1) * poly(-3, 1)).reduce.gcd(poly(-3, 1)) # ==> poly(-3.0, 1.0) # (poly(8, 1) * poly(2, 1) * # poly(-3, 1)).reduce.gcd((poly(8, 1) * poly(-3, 1)).reduce) # ==> poly(-24.0, 5.0, 1.0) # poly(-1, 0, 1).gcd(poly(2, -2, -1, 1)) # ==> poly(0.0) # poly(2, -2, -1, 1).gcd(poly(-1, 0, 1)) # ==> poly(1.0, -1.0) # poly(2, -2, -1, 1).gcd(poly(-2.5, 1)) # ==> poly(0.0) def roots rts = poly() if (deg = self.length - 1).zero? rts else if self[0].zero? if deg == 1 poly(0.0) else Poly.new(deg) do |i| self[i + 1] end.roots.unshift(0.0) end else if deg == 1 linear_root(self[1], self[0]) else if deg == 2 quadratic_root(self[2], self[1], self[0]) else if deg == 3 and (rts = cubic_root(self[3], self[2], self[1], self[0])) rts else if deg == 4 and (rts = quartic_root(self[4], self[3], self[2], self[1], self[0])) rts else ones = 0 1.upto(deg) do |i| if self[i].nonzero? ones += 1 end end if ones == 1 nth_root(self[deg], self[0], deg) else if ones == 2 and deg.even? and self[deg / 2].nonzero? n = deg / 2 poly(self[0], self[deg / 2], self[deg]).roots.each do |qr| rts.push(*nth_root(1.0, -qr, n.to_f)) end rts else if deg > 3 and ones == 3 and (deg % 3).zero? and self[deg / 3].nonzero? and self[(deg * 2) / 3].nonzero? n = deg / 3 poly(self[0], self[deg / 3], self[(deg * 2) / 3], self[deg]).roots.each do |qr| rts.push(*nth_root(1.0, -qr, n.to_f)) end rts else q = self.dup pp = self.derivative qp = pp.dup n = deg x = Complex(1.3, 0.314159) v = q.eval(x) m = v.abs * v.abs 20.times do # until c_g? if (dx = v / qp.eval(x)).abs <= Poly_roots_epsilon break end 20.times do if dx.abs <= Poly_roots_epsilon break end y = x - dx v1 = q.eval(y) if (m1 = v1.abs * v1.abs) < m x = y v = v1 m = m1 break else dx /= 4.0 end end end x = x - self.eval(x) / pp.eval(x) x = x - self.eval(x) / pp.eval(x) if x.imag < Poly_roots_epsilon q = q.poly_div(poly(-x.real, 1.0)) n -= 1 else q = q.poly_div(poly(x.abs, 0.0, 1.0)) n -= 2 end rts = if n > 0 q.car.reduce.roots else poly() end rts << x.to_f_or_c rts end end end end end end end end end end def eval(x) sum = self.last self.reverse[1..-1].each do |val| sum = sum * x + val end sum end private def submatrix(mx, row, col) nmx = Array.new(mx.length - 1) do Vct.new(mx.length - 1, 0.0) end ni = 0 mx.length.times do |i| if i != row nj = 0 mx.length.times do |j| if j != col nmx[ni][nj] = mx[i][j] nj += 1 end end ni += 1 end end nmx end def determinant(mx) if mx.length == 1 mx[0][0] else if mx.length == 2 mx[0][0] * mx[1][1] - mx[0][1] * mx[1][0] else if mx.length == 3 ((mx[0][0] * mx[1][1] * mx[2][2] + mx[0][1] * mx[1][2] * mx[2][0] + mx[0][2] * mx[1][0] * mx[2][1]) - (mx[0][0] * mx[1][2] * mx[2][1] + mx[0][1] * mx[1][0] * mx[2][2] + mx[0][2] * mx[1][1] * mx[2][0])) else sum = 0.0 sign = 1 mx.length.times do |i| mult = mx[0][i] if mult != 0.0 sum = sum + sign * mult * determinant(submatrix(mx, 0, i)) end sign = -sign end sum end end end end # ax + b def linear_root(a, b) poly(-b / a) end # ax^2 + bx + c def quadratic_root(a, b, c) d = sqrt(b * b - 4.0 * a * c) poly((-b + d) / (2.0 * a), (-b - d) / (2.0 * a)) end # ax^3 + bx^2 + cx + d def cubic_root(a, b, c, d) # Abramowitz & Stegun 3.8.2 a0 = d / a a1 = c / a a2 = b / a q = (a1 / 3) - ((a2 * a2) / 9) r = ((a1 * a2 - 3 * a0) / 6) - ((a2 * a2 * a2) / 27) sq3r2 = sqrt(q * q * q + r * r) r1 = (r + sq3r2) ** (1 / 3.0) r2 = (r - sq3r2) ** (1 / 3.0) incr = (TWO_PI * Complex::I) / 3 pl = poly(a0, a1, a2, 1) sqrt3 = sqrt(-3) 3.times do |i| 3.times do |j| s1 = r1 * exp(i * incr) s2 = r2 * exp(j * incr) z1 = simplify_complex((s1 + s2) - (a2 / 3)) if pl.eval(z1).abs < Poly_roots_epsilon z2 = simplify_complex((-0.5 * (s1 + s2)) + (a2 / -3) + ((s1 - s2) * 0.5 * sqrt3)) if pl.eval(z2).abs < Poly_roots_epsilon z3 = simplify_complex((-0.5 * (s1 + s2)) + (a2 / -3) + ((s1 - s2) * -0.5 * sqrt3)) if pl.eval(z3).abs < Poly_roots_epsilon return poly(z1, z2, z3) end end end end end false end # ax^4 + bx^3 + cx^2 + dx + e def quartic_root(a, b, c, d, e) # Weisstein, "Encyclopedia of Mathematics" a0 = e / a a1 = d / a a2 = c / a a3 = b / a if yroot = poly((4 * a2 * a0) + -(a1 * a1) + -(a3 * a3 * a0), (a1 * a3) - (4 * a0), -a2, 1).roots yroot.each do |y1| r = sqrt((0.25 * a3 * a3) + (-a2 + y1)) dd = if r.zero? sqrt((0.75 * a3 * a3) + (-2 * a2) + (2 * sqrt(y1 * y1 - 4 * a0))) else sqrt((0.75 * a3 * a3) + (-2 * a2) + (-(r * r)) + (0.25 * ((4 * a3 * a2) + (-8 * a1) + (-(a3 * a3 * a3)))) / r) end ee = if r.zero? sqrt((0.75 * a3 * a3) + (-2 * a2) + (-2 * sqrt((y1 * y1) - (4 * a0)))) else sqrt((0.75 * a3 * a3) + (-2 * a2) + (-(r * r)) + (-0.25 * ((4 * a3 * a2) + (-8 * a1) + (-(a3 * a3 * a3)))) / r) end z1 = (-0.25 * a3) + ( 0.5 * r) + ( 0.5 * dd) z2 = (-0.25 * a3) + ( 0.5 * r) + (-0.5 * dd) z3 = (-0.25 * a3) + (-0.5 * r) + ( 0.5 * ee) z4 = (-0.25 * a3) + (-0.5 * r) + (-0.5 * ee) if poly(e, d, c, b, a).eval(z1).abs < Poly_roots_epsilon return poly(z1, z2, z3, z4) end end end false end # ax^n + b def nth_root(a, b, deg) n = (-b / a) ** (1.0 / deg) incr = (TWO_PI * Complex::I) / deg rts = poly() deg.to_i.times do |i| rts.unshift(simplify_complex(exp(i * incr) * n)) end rts end Poly_roots_epsilon2 = 1.0e-6 def simplify_complex(a) if a.imag.abs < Poly_roots_epsilon2 (a.real.abs < Poly_roots_epsilon2) ? 0.0 : a.real.to_f else if a.real.abs < Poly_roots_epsilon2 a.real = 0.0 end a end end end class Float unless defined? 0.0.poly_plus alias fp_plus + def poly_plus(other) case other when Poly other[0] += self other else self.fp_plus(other) end end alias + poly_plus end unless defined? 0.0.poly_times alias fp_times * def poly_times(other) case other when Poly Poly(other.scale(self)) else self.fp_times(other) end end alias * poly_times end unless defined? 0.0.poly_div alias fp_div / def poly_div(other) case other when Poly [poly(0.0), other] else self.fp_div(other) end end alias / poly_div end end class String def to_poly if self.scan(/^poly\([-+,.)\d\s]+/).null? poly() else eval(self) end end end class Array def to_poly poly(*self) end end class Vct def to_poly poly(*self.to_a) end end def Poly(obj) if obj.nil? obj = [] end assert_type(obj.respond_to?(:to_poly), obj, 0, "an object containing method 'to_poly'") obj.to_poly end def make_poly(len, init = 0.0, &body) Poly.new(len, init, &body) end def poly?(obj) obj.instance_of?(Poly) end def poly(*vals) Poly.new(vals.length) do |i| if integer?(val = vals[i]) Float(val) else val end end end def poly_reduce(obj) assert_type(obj.respond_to?(:to_poly), obj, 0, "an object containing method 'to_poly'") Poly(obj).reduce end def poly_add(obj1, obj2) if number?(obj1) assert_type(obj2.respond_to?(:to_poly), obj2, 1, "an object containing method 'to_poly'") Float(obj1) + Poly(obj2) else assert_type(obj1.respond_to?(:to_poly), obj1, 0, "an object containing method 'to_poly'") Poly(obj1) + obj2 end end def poly_multiply(obj1, obj2) if number?(obj1) assert_type(obj2.respond_to?(:to_poly), obj2, 1, "an object containing method 'to_poly'") Float(obj1) * Poly(obj2) else assert_type(obj1.respond_to?(:to_poly), obj1, 0, "an object containing method 'to_poly'") Poly(obj1) * obj2 end end def poly_div(obj1, obj2) if number?(obj1) assert_type(obj2.respond_to?(:to_poly), obj2, 1, "an object containing method 'to_poly'") Float(obj1) / Poly(obj2) else assert_type(obj1.respond_to?(:to_poly), obj1, 0, "an object containing method 'to_poly'") Poly(obj1) / obj2 end end def poly_derivative(obj) assert_type(obj.respond_to?(:to_poly), obj, 0, "an object containing method 'to_poly'") Poly(obj).derivative end def poly_gcd(obj1, obj2) assert_type(obj.respond_to?(:to_poly), obj, 0, "an object containing method 'to_poly'") Poly(obj1).gcd(obj2) end def poly_roots(obj) assert_type(obj.respond_to?(:to_poly), obj, 0, "an object containing method 'to_poly'") Poly(obj).roots end # poly.rb ends here snd-16.1/mix.fs0000644000076400007640000001676712327441227011507 0ustar bilbil\ mix.fs -- mix.scm -> mix.fs \ Translator: Michael Scholz \ Created: 05/10/11 18:23:12 \ Changed: 14/04/27 16:13:40 \ \ @(#)mix.fs 1.35 4/27/14 \ Commentary: \ \ ;;; various mix related functions \ \ mix-sound ( file start -- mix-id ) \ silence-all-mixes ( -- ) \ find-mix ( sample snd chn -- mx ) \ mix->vct ( id -- vct ) \ mix-maxamp ( id -- max-amp ) \ snap-mix-to-beat ( at-tag-position -- ) \ \ mix-click-sets-amp ( id -- #t ) \ mix-click-info ( id -- #t ) \ mix-name->id ( name -- id ) \ \ delete-mix ( id -- val ) \ scale-mixes ( mix-list scl -- ) \ silence-mixes ( mix-list -- ) \ move-mixes ( mix-list samps -- ) \ src-mixes ( mix-list sr -- ) \ transpose-mixes ( mix-list semitones -- ) \ color-mixes ( mix-list col -- ) \ set-mixes-tag-y ( mix-list new-y -- ) \ mixes-maxamp ( mix-list -- mx ) \ scale-tempo ( mix-list tempo-scl -- ) \ mixes-length ( mix-list -- len ) require clm require examp : tree-for-each ( proc-or-xt tree -- ) doc" Apply PROC-OR-XT to every leaf of TREE." { proc-or-xt tree } tree nil? unless tree cons? if proc-or-xt tree car recurse proc-or-xt tree cdr recurse else proc-or-xt proc? if proc-or-xt '( tree ) run-proc drop else tree proc-or-xt execute then then then ; : mix-sound <{ file :optional start 0 -- id }> doc" Mix FILE (all chans) at START in the currently selected sound." file start #t undef undef undef undef mix ; hide : silence-mix-xt <{ id -- }> id 0.0 set-mix-amp drop ; : silence-all-mixes-cb <{ -- }> <'> silence-mix-xt undef undef mixes tree-for-each ; set-current : silence-all-mixes ( -- ) doc" Set all mix amps to 0." <'> silence-all-mixes-cb undef as-one-edit drop ; previous : find-mix <{ samp :optional snd #f chn #f -- mx }> doc" Return the id of the mix at the given SAMPLE, or #f." #f \ flag snd snd-snd chn snd-chn mixes each { id } id mix-position samp d= if drop \ drop flag id \ return ID leave then end-each ; : mix->vct ( id -- v ) doc" Return mix's data in vct." { id } id mix? unless 'no-such-mix #( "%s: %s" get-func-name id ) fth-throw then id 0 make-mix-sampler { reader } id mix-length 0.0 make-vct map! reader read-mix-sample end-map reader free-sampler drop ; : mix-maxamp ( id -- max-amp ) doc" Return the max amp in the given mix." mix->vct vct-peak ; hide : snap-mix-to-beat-cb { id samps self -- #t } id mix-position samps + { samp } id mix-home 0 array-ref { snd } id mix-home 1 array-ref { chn } snd chn beats-per-minute 60.0 f/ { bps } snd srate { sr } samp bps f* sr f/ floor { beat } beat sr f* bps f/ floor f>s { lower } beat 1.0 f+ sr f* bps f/ floor f>s { higher } id samp lower - higher samp - < if 0 lower max else higher then set-mix-position drop #t ; set-current : snap-mix-to-beat <{ -- }> doc" Force a dragged mix to end up on a beat (see beats-per-minute). \ Resets mix-release-hook to cancel." mix-release-hook snap-mix-to-beat-cb add-hook! ; previous \ --- Mix Property --- : mix-click-sets-amp <{ id -- #t }> 'zero id mix-property not if 'amp id id mix-amp set-mix-property drop id 0.0 set-mix-amp drop 'zero id #t set-mix-property else id 'amp id mix-property set-mix-amp drop 'zero id #f set-mix-property then drop #t \ #t --> omit default action ; \ mix-click-hook <'> mix-click-sets-amp add-hook! \ mix-click-info : mix-click-info <{ id -- #t }> doc" A mix-click-hook function that describes a \ mix and its properties.\n\ mix-click-hook <'> mix-click-info add-hook!." id mix-home 0 array-ref { mid } id mix-name empty? if "" else " (%S)" #( id mix-name ) string-format then { mname } " mix id: %s%s\n" #( id mname ) string-format make-string-output-port { prt } prt " position: %d (%.3f secs)\n" #( id mix-position dup mid srate f/ ) port-puts-format prt " length: %d (%.3f secs)\n" #( id mix-length dup mid srate f/ ) port-puts-format prt " in: %s[%d]\n" #( mid short-file-name id mix-home 1 array-ref ) port-puts-format prt " scaler: %s\n" #( id mix-amp ) port-puts-format prt " speed: %.3f\n" #( id mix-speed ) port-puts-format prt " env: %s\n" #( id mix-amp-env ) port-puts-format id mix-properties { props } props empty? unless prt " properties: %s\n" #( props ) port-puts-format then "Mix info" prt port->string info-dialog drop #t ; \ mix-click-hook <'> mix-click-info add-hook! \ ;;; -------- mix-name->id : mix-name->id ( name -- mx ) doc" Return the mix id associated with NAME." { name } #f \ flag sounds each { snd } snd channels 0 do snd i ( chn ) mixes each { mx } mx mix-name name string= if drop \ flag mx \ return value exit \ leave word with mx on TOS then end-each loop end-each dup unless drop 'no-such-mix #( "%s: %S" get-func-name name ) fth-throw then ; \ ;;; ---------------- backwards compatibilty : delete-mix ( id -- val ) 0.0 set-mix-amp ; \ ;;; -------- mix lists (used to be "tracks" hide : scale-mixes-cb { mix-list scl -- prc; self -- } 0 proc-create ( prc ) mix-list , scl , does> { self -- } self cell+ @ { scl } self @ ( mix-list ) each { mx } mx mix-amp scl f* { val } mx val set-mix-amp drop end-each ; set-current : scale-mixes ( mix-list scl -- ) scale-mixes-cb undef as-one-edit drop ; previous : silence-mixes ( mix-list -- ) 0.0 scale-mixes ; hide : move-mixes-cb { mix-list samps -- prc; self -- } 0 proc-create ( prc ) mix-list , samps , does> { self -- } self cell+ @ { samps } self @ ( mix-list ) each { mx } mx mix-position samps + { val } mx val set-mix-position drop end-each ; set-current : move-mixes ( mix-list samps -- ) move-mixes-cb undef as-one-edit drop ; previous hide : src-mixes-cb { mix-list sr -- prc; self -- } 0 proc-create ( prc ) mix-list , sr , does> { self -- } self cell+ @ { sr } self @ ( mix-list ) each { mx } mx mix-speed sr f* { val } mx val set-mix-speed drop end-each ; set-current : src-mixes ( mix-list sr -- ) src-mixes-cb undef as-one-edit drop ; previous : transpose-mixes ( mix-list semitones -- ) doc" Transpose each mix in mix-list by semitones." 12.0 f/ 2.0 swap f** src-mixes ; 'snd-nogui provided? [unless] : color-mixes { mix-list col -- } mix-list each { mx } mx col set-mix-color drop end-each ; : set-mixes-tag-y { mix-list new-y -- } mix-list each { mx } mx new-y set-mix-tag-y drop end-each ; : mixes-maxamp { mix-list -- amp } 0.0 { amp } mix-list each { mx } mx mix-maxamp amp fmax to amp end-each amp ; [then] hide : scale-tempo-cb { mix-list tempo-scl first-beg -- prc; self -- } 0 proc-create ( prc ) mix-list , tempo-scl , first-beg , does> { self -- } self @ { mix-list } self cell+ @ { tempo-scl } self 2 cells + @ { first-beg } mix-list each { mx } mx mix-position first-beg - tempo-scl f* f>s { diff } diff 0<> if mx first-beg diff + set-mix-position drop then end-each ; set-current : scale-tempo { mix-list tempo-scl -- } mix-list 0 array-ref mix-position dup { first-beg last-beg } mix-list 1 nil array-subarray each { mx } mx mix-position { pos } first-beg pos min to first-beg last-beg pos max to last-beg end-each mix-list tempo-scl first-beg scale-tempo-cb undef as-one-edit drop ; previous \ ;;; reverse-mix-list is mix-list -1.0 scale-tempo : mixes-length { mix-list -- len } 0 ( maxlen ) mix-list each { mx } ( maxlen ) mx mix-position mx mix-length + max end-each ( maxlen ) 0 ( minlen ) mix-list each { mx } ( minlen ) mx mix-position min end-each ( maxlen minlen ) - 1+ ; \ mix.fs ends here snd-16.1/install-sh0000755000076400007640000001273607351112701012345 0ustar bilbil#!/bin/sh # # install - install a program, script, or datafile # This comes from X11R5 (mit/util/scripts/install.sh). # # Copyright 1991 by the Massachusetts Institute of Technology # # Permission to use, copy, modify, distribute, and sell this software and its # documentation for any purpose is hereby granted without fee, provided that # the above copyright notice appear in all copies and that both that # copyright notice and this permission notice appear in supporting # documentation, and that the name of M.I.T. not be used in advertising or # publicity pertaining to distribution of the software without specific, # written prior permission. M.I.T. makes no representations about the # suitability of this software for any purpose. It is provided "as is" # without express or implied warranty. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" transformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 else true fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d $dst ]; then instcmd=: chmodcmd="" else instcmd=mkdir fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f $src -o -d $src ] then true else echo "install: $src does not exist" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 else true fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` else true fi fi ## this sed command emulates the dirname command dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-${defaultIFS}}" oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" pathcomp='' while [ $# -ne 0 ] ; do pathcomp="${pathcomp}${1}" shift if [ ! -d "${pathcomp}" ] ; then $mkdirprog "${pathcomp}" else true fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then $doit $instcmd $dst && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename $dst` else dstfile=`basename $dst $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename $dst` else true fi # Make a temp file name in the proper directory. dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp && trap "rm -f ${dsttmp}" 0 && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && $doit $mvcmd $dsttmp $dstdir/$dstfile fi && exit 0 snd-16.1/dlocsig.scm0000644000076400007640000033454612623712467012514 0ustar bilbil;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Copyright (c) 92, 93, 94, 98, 99, 2000, 2001 Fernando Lopez Lezcano. ;;; All rights reserved. ;;; Use and copying of this software and preparation of derivative works ;;; based upon this software are permitted and may be copied as long as ;;; no fees or compensation are charged for use, copying, or accessing ;;; this software and all copies of this software include this copyright ;;; notice. Suggestions, comments and bug reports are welcome. Please ;;; address email to: nando@ccrma.stanford.edu ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Dynamic multichannel three-dimentional signal locator ;;; (wow that sound good! :-) ;;; ;;; by Fernando Lopez Lezcano ;;; CCRMA, Stanford University ;;; nando@ccrma.stanford.edu ;;; ;;; Thanks to Juan Pampin for help in the initial coding of the new version ;;; and for prodding me to finish it. To Joseph L. Anderson and Marcelo Perticone ;;; for insights into the Ambisonics coding and decoding process. ;;; http://www.york.ac.uk/inst/mustech/3d_audio/ambison.htm for more details... ;;; CHANGES: ;;; 01/28/2012: third order ambisonics support (Nando). ;;; 04/18/2011: various small changes from lint.scm. ;;; 04/26/2010: add delay hack to remove artifacts in delay output, fix other bugs (Nando) ;;; added proper doppler src conversion thanks to Bill's code in dsp.scm ;;; merged in code for higher order ambisonics (up to 2nd order h/v) ;;; 06/28/2009: remove class/method stuff for s7 (Bill) ;;; 01/08/2007: make a few functions local etc (Bill) ;;; 07/05/2006: translate to scheme, use move-sound generator (Bill) ;;; 04/29/2002: fixed reverb envelopes for no reverb under clisp ;;; 01/14/2001: added multichannel reverb output with local and global control ;;; in the reverberator (the hrtf code is currently not merged into ;;; this version). Reverb-amount can now be an envelope. Ambisonics ;;; now outputs signal to the reverb stream. ;;; 02/05/2000: . don't compile as part of the clm package, import symbols ;;; . switched over to clm-2, otherwise convolve HAS to operate ;;; on a file, we want convolve to process the output of the ;;; doppler delay line (for the hrtf code) ;;; 02/03/2000: started working on hrtf's ;;; 01/15/2000: rewrote transform-path code to account for 3d paths ;;; 01/13/2000: . changed order of b-format output file to W:X:Y:Z from X:Y:Z:W ;;; . plot method would bomb with paths that had constant velocity, ;;; fixed norm function ;;; . added make-literal-path and friends to enable to create ;;; paths with user supplied coordinates ;;; . decoded-ambisonics was rotating sounds in the wrong direction ;;; . in change-direction: only check for change if both points are ;;; different (intersect-inside-radius can create a redundant point) ;;; 11/28/1999: decoded-ambisonics is now working for N channels ;;; includes reverberation send ;;; 11/27/1999: set minimum segment distance for rendering, otherwise for long ;;; lines the amplitude envelope does not reflect power curve. ;;; 11/26/1999: added code to check for intersection with inner radius ;;; fixed nearest-point to handle trivial cases ;;; 01/21/2001: fix envelope generated for mono reverberation stream. ;;; change input and output to use frames and mixers ;;; fix supersonic movement warning code ;;; > add warnings when object goes outside of area covered by speakers ;;; > fix one common vertice case of 3 speaker group transitions ;;; > redo the old code for multiple images (reflections in a rectangular room) ;;; a bit of a pain, would have to add z (ceiling and floor reflections) ;;; would be better to find general purpose code for non-rectangular rooms ;;; > we really need a good N-channel reverb [fixed with freeverb] ;;; > change reverb to be multichannel, add local and global reverb ;;; 11/24/1999: should use a waveguide reverb like pph@ccrma project ;;; would be a good idea to inject the signal through a center ;;; injection point that moves inside the virtual cube, more like ;;; a physical model of what actually happens in a room ;;; | add ambisonics back-end ;;; 11/24/1999: code to b-format sort of working ;;; how to deal with the inner space and 0:0:0? ;;; decoded format not working if we incorporate distance att ;;; formulas are wrong... ;;; > add hrtf back-end ;;; > extract a supath from an existing path ;;; > recode the transformation functions ;;; > add arcs of circles and other basic geometric paths ;;; make it so that you can concatenate them... ;;; | 11/25/1999 fix the "diagonal case" (sounds go through the head of the listener) (provide 'snd-dlocsig.scm) #| (define* (envelope-interp x e base) ;e is list of x y breakpoint pairs, interpolate at x returning y ;; "(envelope-interp x e (base 1.0)) -> value of e at x; base controls connecting segment type: (envelope-interp .3 '(0 0 .5 1 1 0) -> .6" (cond ((null? e) 0.0) ;no data -- return 0.0 ((or (<= x (car e)) ;we're sitting on x val (or if < we blew it) (null? (cddr e))) ;or we're at the end of the list (cadr e)) ;so return current y value ((> (caddr e) x) ;x <= next env x axis value (if (or (= (cadr e) (cadddr e)) (and base (= base 0.0))) (cadr e) ;y1=y0, so just return y0 (avoid endless calculations below) (if (or (not base) (= base 1.0)) (+ (cadr e) ;y0+(x-x0)*(y1-y0)/(x1-x0) (* (- x (car e)) (/ (- (cadddr e) (cadr e)) (- (caddr e) (car e))))) (+ (cadr e) ; this does not exactly match xramp-channel (* (/ (- (cadddr e) (cadr e)) (- base 1.0)) (- (expt base (/ (- x (car e)) (- (caddr e) (car e)))) 1.0)))))) (else (envelope-interp x (cddr e) base)))) ;go on looking for x segment |# (define x-norm (let ((documentation "(x-norm e xmax) changes 'e' x axis values so that they run to 'xmax'")) (lambda (e xmax) (define (x-norm-1 e scl new-e) (if (null? e) (reverse! new-e) (x-norm-1 (cddr e) scl (cons (cadr e) (cons (* scl (car e)) new-e))))) (x-norm-1 e (/ xmax (e (- (length e) 2))) ())))) ;;;;;;;;;;;;;;;;;;;;; ;;; Global Parameters ;;; Define the base in which all angles are expressed (define dlocsig-one-turn 360) (define one-turn-is (let ((documentation "(one-turn-is unit) sets dlocsig's angle unit (degrees=360, the default or radians=2*pi)")) (lambda (unit) (set! dlocsig-one-turn unit)))) (define angles-in-degree (let ((documentation "(angles-in-degree) sets dlocsig's unit to degrees (the default)")) (lambda () (one-turn-is 360)))) (define angles-in-radians (let ((documentation "(angles-in-radians) sets dlocsig's unit to radians (default is degrees)")) (lambda () (one-turn-is (* 2 pi))))) (define angles-in-turns (let ((documentation "(angles-in-turns) sets dlocsig's angle unit to turns")) (lambda () (one-turn-is 1)))) ;; speed of sound in air, in meters per second under normal conditions (define dlocsig-speed-of-sound 344) (define distances-in-meters (let ((documentation "(distances-in-meters) sets dlocsig's distances in meters (the default)")) (lambda () (set! dlocsig-speed-of-sound 344)))) (define distances-in-feet (let ((documentation "(distances-in-feet) sets dlocsig's distances in feet (default is meters)")) (lambda () (set! dlocsig-speed-of-sound 1128)))) ;; default for whether to use two or three-dimensional speaker configurations (define dlocsig-3d #f) ;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Speaker Configuration (define* (make-group (id 0) (size 0) vertices speakers matrix) (list 'group id size vertices speakers matrix)) (define group-id (dilambda (lambda (a) (a 1)) (lambda (a b) (set! (a 1) b)))) (define group-size (dilambda (lambda (a) (a 2)) (lambda (a b) (set! (a 2) b)))) (define group-vertices (dilambda (lambda (a) (a 3)) (lambda (a b) (set! (a 3) b)))) (define group-speakers (dilambda (lambda (a) (a 4)) (lambda (a b) (set! (a 4) b)))) (define group-matrix (dilambda (lambda (a) (a 5)) (lambda (a b) (set! (a 5) b)))) (define* (make-speaker-config number dimension coords groups delays omap) (list 'speaker-config number dimension coords groups delays omap)) (define speaker-config-number (dilambda (lambda (a) (a 1)) (lambda (a b) (set! (a 1) b)))) (define speaker-config-dimension (dilambda (lambda (a) (a 2)) (lambda (a b) (set! (a 2) b)))) (define speaker-config-coords (dilambda (lambda (a) (a 3)) (lambda (a b) (set! (a 3) b)))) (define speaker-config-groups (dilambda (lambda (a) (a 4)) (lambda (a b) (set! (a 4) b)))) (define speaker-config-delays (dilambda (lambda (a) (a 5)) (lambda (a b) (set! (a 5) b)))) (define speaker-config-map (dilambda (lambda (a) (a 6)) (lambda (a b) (set! (a 6) b)))) ;;; Create a speaker configuration structure based on a list of speakers ;;; ;;; speakers: list of angles of speakers with respect to 0 ;;; delays: list of delays for each speaker, zero if nil ;;; distances: list relative speaker distances, ;;; (instead of delays) ;;; omap: mapping of speakers to output channels ;;; content should be output channel number, zero based (define cis (let ((documentation "(cis a) returns e^(ia)")) (lambda (a) (exp (* 0.0+1.0i a))))) ;; built-in 1-Feb-14 ;; (define-macro (when test . forms) `(if ,test (begin ,@forms))) (define third (let ((documentation "(third lst) returns the 3rd element of 'lst'")) (lambda (a) (and (>= (length a) 3) (a 2))))) (define fourth (let ((documentation "(fourth lst) returns the 4th element of 'lst'")) (lambda (a) (and (>= (length a) 4) (a 3))))) (define last (let ((documentation "(last lst n) returns the last 'n' elements of 'lst' as a list")) (lambda* (a n) (and (not (null? a)) (if (not n) (list (a (- (length a) 1))) (let ((res ())) (do ((i 0 (+ i 1))) ((= i n)) (set! res (cons (a (- (length a) (+ i 1))) res))) res)))))) (define listp pair?) (define (make-list-1 n val) (let ((lst ())) (do ((i 0 (+ i 1))) ((= i n)) (set! lst (cons val lst))) lst)) (define* (arrange-speakers (speakers ()) (groups ()) (delays ()) (distances ()) (channel-map ())) ;; sanity checking of configuration (define (has-duplicates? lst) ;; from ice-9/common-list.scm (cond ((null? lst) #f) ((member (car lst) (cdr lst)) #t) (else (has-duplicates? (cdr lst))))) (define (invert3x3 mat) ; invert a 3x3 matrix using cofactors (let ((m (make-float-vector (list 3 3) 0.0)) (det 0.0) (invdet 0.0)) (do ((i 0 (+ i 1))) ((= i 3)) (do ((j 0 (+ j 1))) ((= j 3)) (set! (m i j) (mat i j)))) (set! (mat 0 0) (- (* (m 1 1) (m 2 2)) (* (m 1 2) (m 2 1)))) (set! (mat 0 1) (- (* (m 0 2) (m 2 1)) (* (m 0 1) (m 2 2)))) (set! (mat 0 2) (- (* (m 0 1) (m 1 2)) (* (m 0 2) (m 1 1)))) (set! (mat 1 0) (- (* (m 1 2) (m 2 0)) (* (m 1 0) (m 2 2)))) (set! (mat 1 1) (- (* (m 0 0) (m 2 2)) (* (m 0 2) (m 2 0)))) (set! (mat 1 2) (- (* (m 0 2) (m 1 0)) (* (m 0 0) (m 1 2)))) (set! (mat 2 0) (- (* (m 1 0) (m 2 1)) (* (m 1 1) (m 2 0)))) (set! (mat 2 1) (- (* (m 0 1) (m 2 0)) (* (m 0 0) (m 2 1)))) (set! (mat 2 2) (- (* (m 0 0) (m 1 1)) (* (m 0 1) (m 1 0)))) (set! det (+ (* (m 0 0) (mat 0 0)) (* (m 0 1) (mat 1 0)) (* (m 0 2) (mat 2 0)))) (if (<= (abs det) 1e-06) #f (begin (set! invdet (/ 1.0 det)) (do ((row 0 (+ 1 row))) ((= row 3)) (do ((col 0 (+ 1 col))) ((= col 3)) (set! (mat row col) (* (mat row col) invdet)))) mat)))) (define (invert2x2 mat) ; invert a 2x2 matrix (let ((m (make-float-vector (list 2 2) 0.0)) (det (- (* (mat 0 0) (mat 1 1)) (* (mat 1 0) (mat 0 1))))) (if (<= (abs det) 1e-06) #f (begin (set! (m 0 0) (/ (mat 1 1) det)) (set! (m 1 1) (/ (mat 0 0) det)) (set! (m 0 1) (- (/ (mat 0 1) det))) (set! (m 1 0) (- (/ (mat 1 0) det))) m)))) (if (null? speakers) (error 'mus-error "ERROR: a speaker configuration must have at least one speaker!~%")) (if (pair? groups) (let ((first-len (length (car groups)))) (for-each (lambda (group) (if (not (= (length group) first-len)) (error 'mus-error "ERROR: all groups must be of the same length! (~A)~%" first-len))) groups)) ;; if the speakers are defined with only azimuth angles (no elevation) (if (not (pair? (car speakers))) ;; then create the groups ourselves because it is a 2d configuration; ;; we could create the 3d configuration groups but the algorithm for ;; doing that in the generic case is not trivial (let ((len (length speakers))) (if (= len 1) (set! groups (list (list 0))) (begin (do ((i 0 (+ i 1)) (j 1 (+ j 1))) ((= i len)) (set! groups (cons (list i (modulo j len)) groups))) (set! groups (reverse groups))))))) (if (null? groups) (error 'mus-error "ERROR: no groups specified, speakers must be arranged in groups~%")) (if (and (pair? delays) (pair? distances)) (error 'mus-error "ERROR: please specify delays or distances but not both~%")) (if (pair? delays) (if (> (length speakers) (length delays)) (error 'mus-error "ERROR: all speaker delays have to be specified, only ~A supplied [~A]~%" (length delays) delays) (if (< (length speakers) (length delays)) (error 'mus-error "ERROR: more speaker delays than speakers, ~A supplied instead of ~A [~A]~%" (length delays) (length speakers) delays)))) (for-each (lambda (dly) (if (< dly 0.0) (error 'mus-error "ERROR: delays must be all positive, ~A is negative~%" dly))) delays) (if (pair? distances) (if (> (length speakers) (length distances)) (error 'mus-error "ERROR: all speaker distances have to be specified, only ~A supplied [~A]~%" (length distances) distances) (if (< (length speakers) (length distances)) (error 'mus-error "ERROR: more speaker distances than speakers, ~A supplied instead of ~A [~A]~%" (length distances) (length speakers) distances)))) (for-each (lambda (dly) (if (< dly 0.0) (error 'mus-error "ERROR: distances must be all positive, ~A is negative~%" dly))) distances) (if (pair? channel-map) (if (> (length speakers) (length channel-map)) (error 'mus-error "ERROR: must map all speakers to output channels, only ~A mapped [~A]~%" (length channel-map) channel-map) (if (< (length speakers) (length channel-map)) (error 'mus-error "ERROR: trying to map more channels than there are speakers, ~A supplied instead of ~A [~A]~%" (length channel-map) (length speakers) channel-map)))) ;; collect unit vectors describing the speaker positions (let* ((coords (let ((val ())) (for-each (lambda (s) ; speakers (let* ((a (if (pair? s) (car s) s)) (e (if (pair? s) (or (cadr s) 0.0) 0.0)) (evec (cis (* (/ e dlocsig-one-turn) 2 pi))) (dxy (real-part evec)) (avec (cis (* (/ a dlocsig-one-turn) 2 pi))) (x (* dxy (imag-part avec))) (y (* dxy (real-part avec))) (z (imag-part evec)) (mag (sqrt (+ (* x x) (* y y) (* z z))))) (set! val (cons (list (/ x mag) (/ y mag) (/ z mag)) val)))) speakers) (reverse val))) ;; minimum distance (min-dist (if (pair? distances) (let ((mind (car distances))) (for-each (lambda (d) (if (< d mind) (set! mind d))) distances) mind) 0.0)) ;; find delay times from specified distances or delays (times (let ((v (make-float-vector (length speakers)))) (do ((i 0 (+ i 1))) ((= i (length speakers))) (set! (v i) (let ((distance (and (pair? distances) (distances i))) (dly (and (pair? delays) (delays i)))) (or dly (and distance (/ (- distance min-dist) dlocsig-speed-of-sound)) 0.0)))) v)) ;; create the group structures (groups (let ((vals ()) (id 0)) (for-each (lambda (group) (let* ((size (length group)) (vertices (map coords group)) (matrix (if (= size 3) (let ((m (make-float-vector (list 3 3) 0.0))) (do ((i 0 (+ i 1))) ((= i 3)) (do ((j 0 (+ j 1))) ((= j 3)) (set! (m i j) ((vertices i) j)))) (invert3x3 m)) (if (= size 2) (let ((m (make-float-vector (list 2 2) 0.0))) (do ((i 0 (+ i 1))) ((= i 2)) (do ((j 0 (+ j 1))) ((= j 2)) (set! (m i j) ((vertices i) j)))) (invert2x2 m)) #f)))) (set! vals (cons (make-group :id id :size size :speakers group :vertices vertices :matrix matrix) vals)) (set! id (+ 1 id)))) groups) (reverse vals)))) ;; check validity of map entries (if channel-map (let ((entries (length channel-map))) (for-each (lambda (entry) (if (>= entry entries) (error 'mus-error "ERROR: channel ~A in map ~A is out of range (max=~A)~%" entry channel-map entries))) channel-map) (if (has-duplicates? channel-map) (error 'mus-error "ERROR: there are duplicate channels in channel-map ~A~%" channel-map)))) ;; create the speaker configuration structure (make-speaker-config :number (length speakers) :dimension (group-size (car groups)) :coords coords :groups groups :delays times :omap (let ((v (make-vector (length speakers)))) (do ((chan 0 (+ 1 chan))) ((= chan (length speakers))) (set! (v chan) (or (and (pair? channel-map) (channel-map chan)) chan))) v)))) ;;; Default speaker configurations (define dlocsig-speaker-configs ;; by default up to eight channels, 2-d and 3-d configurations (list (list ;; ;; 2-D speaker configurations ;; no channels: impossible #f ;; mono (arrange-speakers :speakers '(0)) ;; stereo (arrange-speakers :speakers '(-60 60)) ;; three channels (arrange-speakers :speakers '(-45 45 180)) ;; four channels (arrange-speakers :speakers '(-45 45 135 225)) ;; five channels (5.1 arrangement) (arrange-speakers :speakers '(-45 0 45 135 -135)) ;; six channels (arrange-speakers :speakers '(-60 0 60 120 180 240)) ;; seven channels (arrange-speakers :speakers '(-45 0 45 100 140 -140 -100)) ;; eight speakers (arrange-speakers :speakers '(-22.5 22.5 67.5 112.5 157.5 202.5 247.5 292.5))) ;; ;; 3-D speaker configurations ;; (list ;; no channels: impossible #f ;; mono #f ;; stereo #f ;; three channels #f ;; four channels 3d (arrange-speakers :speakers '((-60 0) (60 0) (180 0) (0 90)) :groups '((0 1 3) (1 2 3) (2 0 3) ;; floor (0 1 2))) ;; five channels 3d (arrange-speakers :speakers '((-45 0) (45 0) (135 0) (-135 0) (0 90)) :groups '((0 1 4) (1 2 4) (2 3 4) (3 0 4) ;; floor (0 1 2) (2 3 0))) ;; six channels 3d (arrange-speakers :speakers '((-45 0) (45 0) (135 0) (-135 0) (-90 60) (90 60)) :groups '((0 1 4) (1 4 5) (1 2 5) (2 3 5) (3 4 5) (3 0 4) ;; floor (0 1 2) (2 3 0))) ;; seven channels 3d (arrange-speakers :speakers '((-45 0) (45 0) (135 0) (-135 0) (-60 60) (60 60) (180 60)) :groups '((0 1 4) (1 4 5) (1 2 5) (2 6 5) (2 3 6) (3 4 6) (3 0 4) (4 5 6) ;; floor (0 1 2) (2 3 0))) ;; eight speakers 3d (arrange-speakers :speakers '((-45 -10) (45 -10) (135 -10) (225 -10) (-45 45) (45 45) (135 45) (225 45)) :groups '((0 4 5) (0 5 1) (5 1 2) (2 6 5) (6 7 2) (2 3 7) (3 7 4) (3 0 4) ;; ceiling (4 7 6) (6 5 4) ;; floor (0 1 2) (2 3 0)))))) ;;; Set a particular speaker configuration (define set-speaker-configuration (let ((documentation "(set-speaker-configuration config (configs dlocsig-speaker-configs)) sets a dlocsig speaker configuration")) (lambda* (config (configs dlocsig-speaker-configs)) (let ((lst (if (< (speaker-config-dimension config) 3) (car configs) (cadr configs))) (num (speaker-config-number config))) (set! (lst num) config))))) ;;; Get the speaker configuration for a given number of output channels (define get-speaker-configuration (let ((documentation "(get-speaker-configuration channels (3d dlocsig-3d) (configs dlocsig-speaker-configs)) returns a dlocsig speaker configuration")) (lambda* (channels (3d dlocsig-3d) (configs dlocsig-speaker-configs)) (let ((config (if 3d ((cadr configs) channels) ((car configs) channels)))) (if (null? config) (error 'mus-error "ERROR: no speaker configuration exists for ~A ~A output channel~A~%~%" (if 3d "tridimensional" "bidimensional") channels (if (= channels 1) "s" ""))) config)))) ;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Dlocsig unit generator ;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; global dlocsig parameters (define dlocsig-path ()) (define dlocsig-scaler 1.0) (define dlocsig-direct-power 1.5) (define dlocsig-inside-direct-power 1.5) (define dlocsig-reverb-power 0.5) (define dlocsig-inside-reverb-power 0.5) (define dlocsig-initial-delay #f) (define dlocsig-unity-gain-distance #f) (define dlocsig-reverb-amount 0.04) (define dlocsig-inside-radius 1.0) (define dlocsig-minimum-segment-length 1.0) ;; render using: (define amplitude-panning 1) (define ambisonics 2) (define decoded-ambisonics 3) ;(define stereo-hrtf 4) ; for backwards compatibility (define b-format-ambisonics ambisonics) ; a reasonable default (define dlocsig-render-using amplitude-panning) ;; ambisonics horizontal and vertical order for encoding ;; the default is first order b-format WXYZ (define dlocsig-ambisonics-h-order 1) (define dlocsig-ambisonics-v-order 1) ;; globals for ambisonics (define point707 (cos (/ (* pi 2) 8.0))) (define dlocsig-ambisonics-scaler point707) (define dlocsig-ambisonics-ho-rev-scaler 0.05) ;; for 3rd order FuMa (define ambisonics-k1 (sqrt (/ (* 21 45) 224 8))) (define ambisonics-k2 (* (sqrt 3) 3 0.5)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Get number of channels needed by ambisonics (define* (ambisonics-channels (h-order dlocsig-ambisonics-h-order) (v-order dlocsig-ambisonics-v-order)) (let ((count 0)) (if (>= h-order 0) (begin (if (>= h-order 1) ;; W X Y (set! count (+ count 3))) (if (>= v-order 1) ;; Z (set! count (+ count 1))) (if (>= v-order 2) ;; R S T (set! count (+ count 3))) (if (>= h-order 2) ;; U V (set! count (+ count 2))) (if (>= v-order 3) ;; K L M N O (set! count (+ count 5))) (if (>= h-order 3) ;; P Q (set! count (+ count 2))) count) ;; error: we need at least horizontal order 1! 0))) ;;;;;;;;; ;;; Paths ;;;;;;;;; ;;; Generic path class ;;; path is a list (type rx ry rz rv rt tx ty tz tt ...) (define path-rx (dilambda (lambda (p) (p 1)) (lambda (p val) (set! (p 1) val)))) (define path-ry (dilambda (lambda (p) (p 2)) (lambda (p val) (set! (p 2) val)))) (define path-rz (dilambda (lambda (p) (p 3)) (lambda (p val) (set! (p 3) val)))) (define path-rv (dilambda (lambda (p) (p 4)) (lambda (p val) (set! (p 4) val)))) (define path-rt (dilambda (lambda (p) (p 5)) (lambda (p val) (set! (p 5) val)))) (define path-tx (dilambda (lambda (p) (p 6)) (lambda (p val) (set! (p 6) val)))) (define path-ty (dilambda (lambda (p) (p 7)) (lambda (p val) (set! (p 7) val)))) (define path-tz (dilambda (lambda (p) (p 8)) (lambda (p val) (set! (p 8) val)))) (define path-tt (dilambda (lambda (p) (p 9)) (lambda (p val) (set! (p 9) val)))) ;(define (make-path) (list 'path () () () () () () () () ())) (define (describe path) (cond ((memq (car path) '(bezier-path open-bezier-path)) (format #f ":~% rx: ~A~% ry: ~A~% rz: ~A~% rv: ~A~% rt: ~A~% tx: ~A~% ty: ~A~% tz: ~A~% tt: ~A~% ~ x: ~A~% y: ~A~% z: ~A~% v: ~A~% bx: ~A~% by: ~A~% bz: ~A~% error: ~A~% curvature: ~A~%" (path-rx path) (path-ry path) (path-rz path) (path-rv path) (path-rt path) (path-tx path) (path-ty path) (path-tz path) (path-tt path) (bezier-x path) (bezier-y path) (bezier-z path) (bezier-v path) (bezier-bx path) (bezier-by path) (bezier-bz path) (bezier-error path) (bezier-curvature path))) (else (format #f ":~% rx: ~A~% ry: ~A~% rz: ~A~% rv: ~A~% rt: ~A~% tx: ~A~% ty: ~A~% tz: ~A~% tt: ~A~%" (path-rx path) (path-ry path) (path-rz path) (path-rv path) (path-rt path) (path-tx path) (path-ty path) (path-tz path) (path-tt path))))) ;;; Inquiries into the state of the path (define (not-rendered path) (null? (path-rx path))) (define (not-transformed path) (null? (path-tx path))) ;;; Reset any transformations on the originally rendered path (define (reset-transformation path) (set! (path-tt path) ()) (set! (path-tx path) ()) (set! (path-ty path) ()) (set! (path-tz path) ()) path) ;;; Reset the rendered path (and any transformations) (define (reset-rendering path) (set! (path-rt path) ()) (set! (path-rv path) ()) (set! (path-rx path) ()) (set! (path-ry path) ()) (set! (path-rz path) ()) (reset-transformation path)) ;;; Return the best possible set of coordinates (define list?? (let ((documentation "list?? returns a if it is a list")) (lambda (a) (and (listp a) a)))) (define (path-x path) (or (list?? (path-tx path)) (list?? (path-rx path)) (path-rx (render-path path)))) (define (path-y path) (or (list?? (path-ty path)) (list?? (path-ry path)) (path-ry (render-path path)))) (define (path-z path) (or (list?? (path-tz path)) (list?? (path-rz path)) (path-rz (render-path path)))) (define (path-time path) (or (list?? (path-tt path)) (list?? (path-rt path)) (path-rt (render-path path)))) ;;;;;;;;;;;;;;;; ;;; Bezier paths ;;;;;;;;;;;;;;;; ;;; Parse a path as two or three-dimensional paths (define path-3d #f) ;;; Path class for bezier rendered paths ;;; bezier-path is path + path 3d polar x y z v bx by bz error curvature (define bezier-path (dilambda (lambda (p) (p 10)) (lambda (p val) (set! (p 10) val)))) (define bezier-3d (dilambda (lambda (p) (p 11)) (lambda (p val) (set! (p 11) val)))) (define bezier-polar (dilambda (lambda (p) (p 12)) (lambda (p val) (set! (p 12) val)))) (define bezier-x (dilambda (lambda (p) (p 13)) (lambda (p val) (set! (p 13) val)))) (define bezier-y (dilambda (lambda (p) (p 14)) (lambda (p val) (set! (p 14) val)))) (define bezier-z (dilambda (lambda (p) (p 15)) (lambda (p val) (set! (p 15) val)))) (define bezier-v (dilambda (lambda (p) (p 16)) (lambda (p val) (set! (p 16) val)))) (define bezier-bx (dilambda (lambda (p) (p 17)) (lambda (p val) (set! (p 17) val)))) (define bezier-by (dilambda (lambda (p) (p 18)) (lambda (p val) (set! (p 18) val)))) (define bezier-bz (dilambda (lambda (p) (p 19)) (lambda (p val) (set! (p 19) val)))) (define bezier-error (dilambda (lambda (p) (p 20)) (lambda (p val) (set! (p 20) val)))) (define bezier-curvature (dilambda (lambda (p) (p 21)) (lambda (p val) (set! (p 21) val)))) (define* (make-bezier-path (path ()) (3d #t) polar (error 0.01) curvature) (list 'bezier-path () () () () () () () () () path 3d polar () () () () () () () error curvature)) ;;; Path class for open bezier paths (define initial-direction (dilambda (lambda (p) (p 22)) (lambda (p val) (set! (p 22) val)))) (define final-direction (dilambda (lambda (p) (p 23)) (lambda (p val) (set! (p 23) val)))) (define* (make-open-bezier-path (path ()) (3d #t) polar (error 0.01) curvature (initial-direction '(0.0 0.0 0.0)) (final-direction '(0.0 0.0 0.0))) (list 'open-bezier-path () () () () () () () () () path 3d polar () () () () () () () error curvature initial-direction final-direction)) ;;; ;;; Generic defining function (for open, closed, polar and cartesian paths) ;;; (define* (make-path path (3d path-3d) polar closed curvature (error 0.01) ;; only for open paths initial-direction final-direction) ;; some sanity checks (if (null? path) (error 'mus-error "ERROR: Can't define a path with no points in it~%")) (if (and closed initial-direction) (error 'mus-error "ERROR: Can't specify initial direction ~A for a closed path ~A~%" initial-direction path)) (if (and closed final-direction) (error 'mus-error "ERROR: Can't specify final direction ~A for a closed path ~A~%" final-direction path)) (if (and closed (not (if (pair? (car path)) (let ((start (car path)) (end (car (last path)))) (and (= (car start) (car end)) (= (cadr start) (cadr end)) (or (not path-3d) (= (third start) (third end))))) (let ((end (last path (if path-3d 3 2)))) (and (= (car path) (car end)) (= (cadr path) (cadr end)) (or (not path-3d) (= (third path) (third end)))))))) (error 'mus-error "ERROR: Closed path ~A is not closed~%" path)) ;; create the path structure (if closed (make-bezier-path :path path :3d 3d :polar polar :curvature curvature :error error) (make-open-bezier-path :path path :3d 3d :polar polar :curvature curvature :error error :initial-direction initial-direction :final-direction final-direction))) ;;; Some convenient abbreviations (define* (make-polar-path path (3d path-3d) closed curvature (error 0.01) ;; only for open paths initial-direction final-direction) (if closed (make-path :path path :3d 3d :polar #t :closed closed :curvature curvature :error error) (make-path :path path :3d 3d :polar #t :closed closed :curvature curvature :error error :initial-direction initial-direction :final-direction final-direction))) (define* (make-closed-path path (3d path-3d) polar curvature (error 0.01)) (make-path :path path :3d 3d :polar polar :closed #t :curvature curvature :error error)) ;;; ;;; Parse a path and transform it into cartesian coordinates ;;; (define (not-parsed path) (null? (bezier-x path))) ;;; Parse a set of 2d or 3d points into the separate coordinates (define parse-cartesian-coordinates (let ((documentation "(parse-cartesian-coordinates points 3d) parses a set of 2d or 3d points into the separate coordinates")) (lambda (points 3d) (if (pair? (car points)) ;; decode a list of lists into x:y:z:v components ;; 3d -> t [default] ;; '((x0 y0 z0 v0) (x1 y1 z1 v1)...(xn yn zn vn)) ;; '((x0 y0 z0) (x1 y1 z1)...(xn yn zn)) ;; '((x0 y0) (x1 y1)...(xn yn)) ;; v: relative velocity ;; x, y, z: coordinates of source [missing z's assumed 0.0] ;; 3d -> nil ;; '((x0 y0 v0) (x1 y1 v1)...(xn yn vn)) ;; '((x0 y0) (x1 y1)...(xn yn)) ;; v: relative velocity ;; x, y, z: coordinates of source [missing z's assumed 0.0] (let ((v ()) (x ()) (y ()) (z ())) (for-each (lambda (p) (set! x (cons (car p) x)) (set! y (cons (cadr p) y)) (set! z (cons (if 3d (or (third p) 0.0) 0.0) z)) (set! v (cons (if 3d (fourth p) (third p)) v))) points) (list (reverse x) (reverse y) (reverse z) (reverse v))) ;; decode a plain list (if 3d ;; it's a three dimensional list ;; '(x0 y0 z0 x1 y1 z1 ... xn yn zn) ;; x, y, z: coordinates of source (let ((px ()) (py ()) (pz ()) (len (length points))) (do ((i 0 (+ i 3))) ((>= i len)) (set! px (cons (points i) px)) (set! py (cons (points (+ i 1)) py)) (set! pz (cons (points (+ i 2)) pz))) (list (reverse px) (reverse py) (reverse pz) (make-list-1 (length px) #f))) ;; it's a two dimensional list ;; '(x0 y0 x1 y1 ... xn yn) ;; x, y, z: coordinates of source [missing z's assumed 0.0] (let ((px ()) (py ()) (len (length points))) (do ((i 0 (+ i 2))) ((>= i len)) (set! px (cons (points i) px)) (set! py (cons (points (+ i 1)) py))) (list (reverse px) (reverse py) (make-list-1 (length px) 0.0) (make-list-1 (length px) #f)))))))) ;;; Parse a set of 2d or 3d polar points into the separate coordinates (define parse-polar-coordinates (let ((documentation "(parse-polar-coordinates points 3d) parses a polar path")) (lambda (points 3d) (if (pair? (car points)) ;; decode a list of lists of d:a:e:v into x:y:z:v components ;; 3d --> t [default] ;; '((d0 a0 e0 v0) (d1 a1 e1 v1)...(dn an en vn)) ;; '((d0 a0 e0) (d1 a1 e1)...(dn an en)) ;; '((d0 a0) (d1 a1)...(dn an)) ;; 3d --> nil ;; '((d0 a0 v0) (d1 a1 v1)...(dn an vn)) ;; '((d0 a0) (d1 a1)...(dn an)) ;; v: velocity ;; d: distance ;; a: azimut angle ;; e: elevarion angle [missing elevations assumed 0.0] (let ((x ()) (y ()) (z ()) (v ())) (for-each (lambda (p) (let* ((d (car p)) (a (cadr p)) (e (if 3d (if (pair? (cddr p)) (caddr p) 0.0) 0.0)) (evec (cis (* (/ e dlocsig-one-turn) 2 pi))) (dxy (* d (real-part evec))) (avec (cis (* (/ a dlocsig-one-turn) 2 pi)))) (set! x (cons (* dxy (imag-part avec)) x)) (set! y (cons (* dxy (real-part avec)) y)) (set! z (cons (* d (imag-part evec)) z)) (set! v (cons (if 3d (fourth p) (third p)) v)))) points) (list (reverse x) (reverse y) (reverse z) (reverse v))) ;; decode a list of d:a:e components (if 3d ;; decode a three dimensional list ;; '(d0 a0 e0 d1 a1 e1 ... dn an en) ;; d: distance ;; a: azimut angle ;; e: elevarion angle [missing elevations assumed 0.0] (let ((x ()) (y ()) (z ()) (len (length points))) (do ((i 0 (+ i 3))) ((>= i len)) (let* ((d (points i)) (a (points (+ i 1))) (e (points (+ i 2))) (evec (cis (* (/ e dlocsig-one-turn) 2 pi))) (dxy (* d (real-part evec))) (avec (cis (* (/ a dlocsig-one-turn) 2 pi)))) (set! x (cons (* dxy (imag-part avec)) x)) (set! y (cons (* dxy (real-part avec)) y)) (set! z (cons (* d (imag-part evec)) z)))) (list (reverse x) (reverse y) (reverse z) (make-list-1 (length x) #f))) ;; decode a two dimensional list ;; '(d0 a0 d1 a1 ... dn an) ;; d: distance ;; a: azimut angle ;; e: elevarion angle [missing elevations assumed 0.0] (let ((x ()) (y ()) (len (length points))) (do ((i 0 (+ i 2))) ((>= i len)) (let* ((d (points i)) (a (points (+ i 1))) (avec (cis (* (/ a dlocsig-one-turn) 2 pi)))) (set! x (cons (* d (imag-part avec)) x)) (set! y (cons (* d (real-part avec)) y)))) (list (reverse x) (reverse y) (make-list-1 (length x) 0.0) (make-list-1 (length x) #f)))))))) (define (xparse-path xpath) (let ((polar (bezier-polar xpath)) (points (bezier-path xpath)) (3d (bezier-3d xpath))) (if polar ;; parse a polar path (let ((vals (parse-polar-coordinates points 3d))) (set! (bezier-x xpath) (car vals)) (set! (bezier-y xpath) (cadr vals)) (set! (bezier-z xpath) (caddr vals)) (set! (bezier-v xpath) (cadddr vals))) (let ((vals (parse-cartesian-coordinates points 3d))) ;; parse a cartesian path (set! (bezier-x xpath) (car vals)) (set! (bezier-y xpath) (cadr vals)) (set! (bezier-z xpath) (caddr vals)) (set! (bezier-v xpath) (cadddr vals))))) (for-each (lambda (v) (if (and (number? v) (< v 0)) (error 'mus-error "ERROR: velocities for path ~A must be all positive~%" (bezier-path xpath)))) (bezier-v xpath)) (reset-fit xpath)) ;;; ;;; Bezier curve fitting auxiliary functions ;;; ;;; Pythagoras (define distance (let ((documentation "(distance x y z) returns the euclidean distance of (x y z) from the origin")) (lambda (x y z) (sqrt (+ (* x x) (* y y) (* z z)))))) ;;; Nearest point in a line (define (nearest-point x0 y0 z0 x1 y1 z1 px py pz) (define (vmag a b c) (sqrt (+ (* a a) (* b b) (* c c)))) (define (vcos a0 b0 c0 a1 b1 c1) (/ (+ (* a0 a1) (* b0 b1) (* c0 c1)) (* (vmag a0 b0 c0) (vmag a1 b1 c1)))) (define (same a0 b0 c0 a1 b1 c1) (and (= a0 a1) (= b0 b1) (= c0 c1))) (if (same x0 y0 z0 px py pz) (list x0 y0 z0) (if (same x1 y1 z1 px py pz) (list x1 y1 z1) (if (same x0 y0 z0 x1 y1 z1) (list x0 y0 z0) (let* ((xm0 (- x1 x0)) (ym0 (- y1 y0)) (zm0 (- z1 z0)) (xm1 (- px x0)) (ym1 (- py y0)) (zm1 (- pz z0)) (p (* (vmag xm1 ym1 zm1) (vcos xm0 ym0 zm0 xm1 ym1 zm1))) (l (vmag xm0 ym0 zm0)) (ratio (/ p l))) (list (+ x0 (* xm0 ratio)) (+ y0 (* ym0 ratio)) (+ z0 (* zm0 ratio)))))))) ;;; Bezier curve fitting auxilliary functions (define path-ak-even #f) (define path-ak-odd #f) (define path-maxcoeff 8) (define path-gtab #f) (define (make-a-even) (define (g m) (if (not path-gtab) (begin (set! path-gtab (make-vector path-maxcoeff)) (set! (path-gtab 0) 1) (set! (path-gtab 1) -4) (do ((i 2 (+ i 1))) ((= i path-maxcoeff)) (set! (path-gtab i) (- (* -4 (path-gtab (- i 1))) (path-gtab (- i 2))))))) (path-gtab m)) (set! path-ak-even (make-vector (- path-maxcoeff 1))) (do ((m 1 (+ 1 m))) ((= m path-maxcoeff)) (set! (path-ak-even (- m 1)) (make-vector m)) (do ((k 1 (+ k 1))) ((> k m)) (set! ((path-ak-even (- m 1)) (- k 1)) (* 1.0 (/ (- (g (- m k))) (g m))))))) (define path-ftab #f) (define (make-a-odd) (define (f m) (if (not path-ftab) (begin (set! path-ftab (make-vector path-maxcoeff)) (set! (path-ftab 0) 1) (set! (path-ftab 1) -3) (do ((i 2 (+ i 1))) ((= i path-maxcoeff)) (set! (path-ftab i) (- (* -4 (path-ftab (- i 1))) (path-ftab (- i 2))))))) (path-ftab m)) (set! path-ak-odd (make-vector (- path-maxcoeff 1))) (do ((m 1 (+ 1 m))) ((= m path-maxcoeff)) (set! (path-ak-odd (- m 1)) (make-vector m)) (do ((k 1 (+ k 1))) ((> k m)) (set! ((path-ak-odd (- m 1)) (- k 1)) (* 1.0 (/ (- (f (- m k))) (f m))))))) ;;; Calculate bezier difference vectors for the given path ;;; (path-x (make-path '((-10 10)(0 5)(10 10)))) (define (calculate-fit path) (cond ((not (eq? (car path) 'open-bezier-path)) (let* ((n (- (length (bezier-x path )) 1)) (m (/ (- n (if (odd? n) 3 4)) 2)) ;; data points P(i) (p (vector (apply vector (bezier-x path)) (apply vector (bezier-y path)) (apply vector (bezier-z path)))) ;; control points D(i) (d (vector (make-vector n 0.0) (make-vector n 0.0) (make-vector n 0.0)))) (define (a-1 k n) (if (odd? (min (+ (* path-maxcoeff 2) 1) n)) (begin (if (not path-ak-odd) (make-a-odd)) ((path-ak-odd (/ (- n 3) 2)) (- k 1))) (begin (if (not path-ak-even) (make-a-even)) ((path-ak-even (/ (- n 4) 2)) (- k 1))))) (define (xvector-ref z j i) (if (> i (- n 1)) ((z j) (- i n)) (if (< i 0) ((z j) (+ i n)) ((z j) i)))) (do ((i 0 (+ i 1))) ((= i n)) (do ((k 1 (+ k 1))) ((> k m)) (do ((a 0 (+ 1 a))) ((> a 2)) (set! ((d a) i) (+ ((d a) i) (* (a-1 k n) (- (xvector-ref p a (+ i k)) (xvector-ref p a (- i k))))))))) (if (bezier-curvature path) (do ((i 0 (+ i 1))) ((= i n)) (set! ((d 0) i) (* ((d 0) i) (bezier-curvature path))) (set! ((d 1) i) (* ((d 1) i) (bezier-curvature path))) (set! ((d 2) i) (* ((d 2) i) (bezier-curvature path))))) (list (- n 1) p d))) (else (let* ((n (- (length (bezier-x path)) 1)) (m (- n 1)) ;; data points P(i) (p (vector (apply vector (bezier-x path)) (apply vector (bezier-y path)) (apply vector (bezier-z path)))) ;; control points D(i) (d (vector (make-vector (+ n 1) 0.0) (make-vector (+ n 1) 0.0) (make-vector (+ n 1) 0.0)))) (define (ac k n) (let ((un (min n path-maxcoeff))) (if (not path-ak-even) (make-a-even)) ((path-ak-even (- un 2)) (- k 1)))) (define (ref z j i) (if (> i n) ((z j) (- i n)) (if (< i 0) ((z j) (+ i n)) (if (= i n) (- ((z j) n) ((d j) n)) (if (= i 0) (+ ((z j) 0) ((d j) 0)) ((z j) i)))))) ;; forced initial direction (if (initial-direction path) (begin (set! ((d 0) 0) (car (initial-direction path))) (set! ((d 1) 0) (cadr (initial-direction path))) (set! ((d 2) 0) (third (initial-direction path)))) (begin (set! ((d 0) 0) 0.0) (set! ((d 1) 0) 0.0) (set! ((d 2) 0) 0.0))) ;; forced final direction (if (final-direction path) (begin (set! ((d 0) n) (car (final-direction path))) (set! ((d 1) n) (cadr (final-direction path))) (set! ((d 2) n) (caddr (final-direction path)))) (begin (set! ((d 0) n) 0.0) (set! ((d 1) n) 0.0) (set! ((d 2) n) 0.0))) ;; calculate fit (do ((i 1 (+ i 1))) ((= i n)) (do ((k 1 (+ k 1))) ((> k (min m (- path-maxcoeff 1)))) (let ((d0 ((d 0) i)) (d1 ((d 1) i)) (d2 ((d 2) i))) (set! ((d 0) i) (+ d0 (* (ac k n) (- (ref p 0 (+ i k)) (ref p 0 (- i k)))))) (set! ((d 1) i) (+ d1 (* (ac k n) (- (ref p 1 (+ i k)) (ref p 1 (- i k)))))) (set! ((d 2) i) (+ d2 (* (ac k n) (- (ref p 2 (+ i k)) (ref p 2 (- i k))))))))) (list n p d))))) ;;; Calculate bezier control points for the given open path (define (not-fitted path) (null? (bezier-bx path))) (define (reset-fit path) (set! (bezier-bx path) ()) (set! (bezier-by path) ()) (set! (bezier-bz path) ()) (reset-rendering path)) (define (fit-path path) (cond ((eq? (car path) 'open-bezier-path) (if (not-parsed path) (xparse-path path)) (let ((points (length (bezier-x path)))) (if (> points 2) (let* ((vals (calculate-fit path)) (n (car vals)) (p (cadr vals)) (d (caddr vals))) (let ((c (bezier-curvature path)) (cs (make-vector n))) ;; setup the curvatures array (if (or (not c) (null? c)) ; no curvature specified, default is 1.0 (do ((i 0 (+ i 1))) ((= i n)) (set! (cs i) (list 1.0 1.0))) (if (number? c) ; same curvature for all segments (do ((i 0 (+ i 1))) ((= i n)) (set! (cs i) (list c c))) (if (and (pair? c) (= n (length c))) ; list of curvatures (let ((i 0)) (for-each (lambda (ci) (set! (cs i) (if (pair? ci) (if (not (= (length ci) 2)) (error 'mus-error "ERROR: curvature sublist must have two elements ~A~%" ci) ci) (list ci ci))) (set! i (+ i 1))) c)) (error 'mus-error "ERROR: bad curvature argument ~A to path, need ~A elements~%" c n)))) ;; calculate control points (let ((xc ()) (yc ()) (zc ())) (do ((i 0 (+ i 1))) ((= i n)) (set! xc (cons (list ((p 0) i) (+ ((p 0) i) (* ((d 0) i) (car (cs i)))) (- ((p 0) (+ i 1)) (* ((d 0) (+ i 1)) (cadr (cs i)))) ((p 0) (+ i 1))) xc)) (set! yc (cons (list ((p 1) i) (+ ((p 1) i) (* ((d 1) i) (car (cs i)))) (- ((p 1) (+ i 1)) (* ((d 1) (+ i 1)) (cadr (cs i)))) ((p 1) (+ i 1))) yc)) (set! zc (cons (list ((p 2) i) (+ ((p 2) i) (* ((d 2) i) (car (cs i)))) (- ((p 2) (+ i 1)) (* ((d 2) (+ i 1)) (cadr (cs i)))) ((p 2) (+ i 1))) zc))) (set! (bezier-bx path) (reverse xc)) (set! (bezier-by path) (reverse yc)) (set! (bezier-bz path) (reverse zc))))) (if (= points 2) ;; just a line, stays a line (let ((x1 (car (bezier-x path))) (x2 (cadr (bezier-x path))) (y1 (car (bezier-y path))) (y2 (cadr (bezier-y path))) (z1 (car (bezier-z path))) (z2 (cadr (bezier-z path)))) (set! (bezier-bx path) (list (list x1 x1 x2 x2))) (set! (bezier-by path) (list (list y1 y1 y2 y2))) (set! (bezier-bz path) (list (list z1 z1 z2 z2)))) (if (= points 1) ;; just one point, bezier won't do much here (begin (set! (bezier-bx path) ()) (set! (bezier-by path) ()) (set! (bezier-bz path) ()))))) (reset-rendering path))) (else (if (not-parsed path) (xparse-path path)) (if (> (length (bezier-x path)) 4) (let* ((vals (calculate-fit path)) (n (car vals)) (p (cadr vals)) (d (caddr vals))) ;; enough points, fit path (let ((xc ()) (yc ()) (zc ())) (do ((i 0 (+ i 1))) ((= i n)) (set! xc (cons (list ((p 0) i) (+ ((p 0) i) ((d 0) i)) (- ((p 0) (+ i 1)) ((d 0) (+ i 1))) ((p 0) (+ i 1))) xc)) (set! yc (cons (list ((p 1) i) (+ ((p 1) i) ((d 1) i)) (- ((p 1) (+ i 1)) ((d 1) (+ i 1))) ((p 1) (+ i 1))) yc)) (set! zc (cons (list ((p 2) i) (+ ((p 2) i) ((d 2) i)) (- ((p 2) (+ i 1)) ((d 2) (+ i 1))) ((p 2) (+ i 1))) zc))) (set! (bezier-bx path) (append (reverse xc) (list (list ((p 0) n) (+ ((p 0) n) ((d 0) n)) (- ((p 0) 0) ((d 0) 0)) ((p 0) 0))))) (set! (bezier-by path) (append (reverse yc) (list (list ((p 1) n) (+ ((p 1) n) ((d 1) n)) (- ((p 1) 0) ((d 1) 0)) ((p 1) 0))))) (set! (bezier-bz path) (append (reverse zc) (list (list ((p 2) n) (+ ((p 2) n) ((d 2) n)) (- ((p 2) 0) ((d 2) 0)) ((p 2) 0))))))) ;; not enough points to fit a closed path (let ((xc ()) (yc ()) (zc ()) (len (min (length (bezier-x path)) (length (bezier-y path)) (length (bezier-z path))))) (do ((i 0 (+ i 1))) ((>= i len)) (let ((x1 ((bezier-x path) i)) (x2 ((bezier-x path) (+ i 1))) (y1 ((bezier-y path) i)) (y2 ((bezier-y path) (+ i 1))) (z1 ((bezier-z path) i)) (z2 ((bezier-z path) (+ i 1)))) (set! xc (cons (list x1 x1 x2 x2) xc)) (set! yc (cons (list y1 y1 y2 y2) yc)) (set! zc (cons (list z1 z1 z2 z2) zc)))) (format *stderr* "[fit-path:closed-path] not enough points to do bezier fit (~A points)" len) (set! (bezier-bx path) (reverse xc)) (set! (bezier-by path) (reverse yc)) (set! (bezier-bz path) (reverse zc)))) (reset-rendering path)))) ;;;;;;;;;;;;;;;;; ;;; Literal paths ;;;;;;;;;;;;;;;;; (define literal-points (dilambda (lambda (p) (p 10)) (lambda (p val) (set! (p 10) val)))) (define literal-3d (dilambda (lambda (p) (p 11)) (lambda (p val) (set! (p 11) val)))) (define literal-polar (dilambda (lambda (p) (p 12)) (lambda (p val) (set! (p 12) val)))) ;;; Generic literal path creation function (define* (make-literal-path (points ()) (3d path-3d) polar) (list 'literal-path () () () () () () () () () points 3d polar)) ;;; Specific polar literal path creation function (define* (make-literal-polar-path (points ()) (3d path-3d)) (make-literal-path points 3d #t)) ;;;;;;;;;;; ;;; Spirals ;;;;;;;;;;; (define spiral-start-angle (dilambda (lambda (p) (p 13)) (lambda (p val) (set! (p 13) val)))) (define spiral-total-angle (dilambda (lambda (p) (p 14)) (lambda (p val) (set! (p 14) val)))) (define spiral-step-angle (dilambda (lambda (p) (p 15)) (lambda (p val) (set! (p 15) val)))) (define spiral-turns (dilambda (lambda (p) (p 16)) (lambda (p val) (set! (p 16) val)))) (define spiral-distance (dilambda (lambda (p) (p 17)) (lambda (p val) (set! (p 17) val)))) (define spiral-height (dilambda (lambda (p) (p 18)) (lambda (p val) (set! (p 18) val)))) (define spiral-velocity (dilambda (lambda (p) (p 19)) (lambda (p val) (set! (p 19) val)))) (define* (make-spiral-path (start-angle 0.0) total-angle step-angle (turns ()) (distance '(0 10 1 10)) (height '(0 0 1 0)) (velocity '(0 1 1 1))) (if (and total-angle (pair? turns)) (error 'mus-error "ERROR: can't specify total-angle [~A] and turns [~A] at the same time for the spiral path~%" total-angle turns)) (list 'spiral-path () () () () () () () () () () path-3d #f start-angle total-angle (or step-angle (/ dlocsig-one-turn 100)) turns distance height velocity)) ;;; Transform a Bezier control point fit to a linear segment approximation (define (bezier-render path) (if (not-fitted path) (fit-path path)) (let ((xrx ()) (xry ()) (xrz ()) (xrv ())) (define (bezier-point u c) ;; Evaluate a point at parameter u in bezier segment (let ((u1 (- 1 u)) (cr (vector (make-vector 3 0.0) (make-vector 3 0.0) (make-vector 3 0.0)))) (do ((j 0 (+ j 1))) ((= j 3)) (set! ((cr 0) j) (+ (* u1 ((c 0) j)) (* u ((c 0) (+ j 1))))) (set! ((cr 1) j) (+ (* u1 ((c 1) j)) (* u ((c 1) (+ j 1))))) (set! ((cr 2) j) (+ (* u1 ((c 2) j)) (* u ((c 2) (+ j 1)))))) (do ((i 1 (- i 1))) ((< i 0)) (do ((j 0 (+ j 1))) ((> j i)) (set! ((cr 0) j) (+ (* u1 ((cr 0) j)) (* u ((cr 0) (+ j 1))))) (set! ((cr 1) j) (+ (* u1 ((cr 1) j)) (* u ((cr 1) (+ j 1))))) (set! ((cr 2) j) (+ (* u1 ((cr 2) j)) (* u ((cr 2) (+ j 1))))) )) (list ((cr 0) 0) ((cr 1) 0) ((cr 2) 0)))) (define (berny xl yl zl xh yh zh ul u uh c err) ;; Create a linear segment rendering of a bezier segment (let* ((vals (bezier-point u c)) (x (car vals)) (y (cadr vals)) (z (caddr vals))) (let* ((val1 (nearest-point xl yl zl xh yh zh x y z)) (xn (car val1)) (yn (cadr val1)) (zn (caddr val1))) (if (> (distance (- xn x) (- yn y) (- zn z)) err) (let* ((val2 (berny xl yl zl x y z ul (/ (+ ul u) 2) u c err)) (xi (car val2)) (yi (cadr val2)) (zi (caddr val2))) (let* ((val3 (berny x y z xh yh zh u (/ (+ u uh) 2) uh c err)) (xj (car val3)) (yj (cadr val3)) (zj (caddr val3))) (list (append xi (list x) xj) (append yi (list y) yj) (append zi (list z) zj)))) (list () () ()))))) ;; Create linear segment approximations of the bezier segments ;; make sure there are initial and final velocity values (if (not (listp (bezier-v path))) (set! (bezier-v path) (list 1 1)) (if (not (car (bezier-v path))) (begin (set! ((bezier-v path) 0) 1) (set! ((bezier-v path) (- (length (bezier-v path)) 1)) 1)))) ;; only one point means no movement, static source (if (= (length (bezier-x path)) 1) (begin (set! (path-rx path) (bezier-x path)) (set! (path-ry path) (bezier-y path)) (set! (path-rz path) (bezier-z path)) (set! (path-rt path) (list 0.0)) (reset-transformation path)) ; after? (begin (let ((len (length (bezier-bx path)))) ;(path-x (make-path '((-10 10)(0 5)(10 10)))) ;; render the path only if it has at least two points (do ((i 0 (+ i 1))) ((= i len)) (let* ((x-bz ((bezier-bx path) i)) (y-bz ((bezier-by path) i)) (z-bz ((bezier-bz path) i)) (vi-bz ((bezier-v path) i)) (vf-bz ((bezier-v path) (+ i 1))) (xi-bz (car x-bz)) (xf-bz (x-bz (- (length x-bz) 1))) (yi-bz (car y-bz)) (yf-bz (y-bz (- (length y-bz) 1))) (zi-bz (car z-bz)) (zf-bz (z-bz (- (length z-bz) 1)))) (let* ((vals (berny xi-bz yi-bz zi-bz xf-bz yf-bz zf-bz 0.0 0.5 1.0 (vector (apply vector x-bz) (apply vector y-bz) (apply vector z-bz)) (bezier-error path))) (xs (car vals)) (ys (cadr vals)) (zs (caddr vals))) ;; approximate the bezier curve with linear segments (set! xrx (append xrx (list xi-bz) xs)) (set! xry (append xry (list yi-bz) ys)) (set! xrz (append xrz (list zi-bz) zs)) ;; accumulate intermediate unknown velocities as nils (set! xrv (append xrv (list vi-bz) (make-list-1 (length xs) #f))) (if (= i (- len 1)) (begin ;; add the last point (set! xrx (append xrx (list xf-bz))) (set! xry (append xry (list yf-bz))) (set! xrz (append xrz (list zf-bz))) (set! xrv (append xrv (list vf-bz))) )))))) ;; calculate times for each velocity segment (let ((len (- (length xrx) 1)) (ti 0) (times (list 0)) (xseg (list (xrx 0))) (yseg (list (xry 0))) (zseg (list (xrz 0))) (vseg (list (xrv 0))) (vi (xrv 0))) (do ((i 0 (+ i 1))) ((= i len)) (let ((x (xrx (+ i 1))) (y (xry (+ i 1))) (z (xrz (+ i 1))) (v (xrv (+ i 1)))) (set! xseg (append xseg (list x))) (set! yseg (append yseg (list y))) (set! zseg (append zseg (list z))) (set! vseg (append vseg (list v))) (if v (let ((dseg (list)) (sum 0.0) (len (- (length xseg) 1))) (do ((i 0 (+ i 1))) ((= i len)) (let ((xsi (xseg i)) (ysi (yseg i)) (zsi (zseg i)) (xsf (xseg (+ i 1))) (ysf (yseg (+ i 1))) (zsf (zseg (+ i 1)))) (set! sum (+ sum (distance (- xsf xsi) (- ysf ysi) (- zsf zsi)))) (set! dseg (cons sum dseg)))) (let ((df (car dseg))) (set! dseg (reverse dseg)) (let* ((tseg ()) (vf v) (a (/ (* (- vf vi) (+ vf vi)) df 4))) (if (= vi 0.0) (set! vi 1)) (for-each (lambda (d) (set! tseg (cons (+ ti (if (= vf vi) (/ d vi) (/ (- (sqrt (+ (* vi vi) (* 4 a d))) vi) (* 2 a)))) tseg))) dseg) (set! ti (car tseg)) (set! tseg (reverse tseg)) (set! times (append times tseg)) (set! xseg (list x)) (set! yseg (list y)) (set! zseg (list z)) (set! vseg (list v)) (set! vi v))))) )) (set! (path-rx path) xrx) (set! (path-ry path) xry) (set! (path-rz path) xrz) (set! (path-rt path) (let ((tf (times (- (length times) 1))) (val ())) (for-each (lambda (ti) (set! val (cons (/ ti tf) val))) times) (reverse val))) (reset-transformation path)))))) ;; (set! p (make-path '((-10 10 0 0) (0 5 0 1) (10 10 0 0)) :error 0.01)) ;; (set! p (make-path '((-10 10 0 1) (-7 7 0 0.9) (0 5 0 0) (7 7 0 0.2) (10 10 0 1)) :error 0.001)) ;; (with-sound(:channels 4 :play #f) (sinewave 0 2 880 0.5 :path p)) (define (literal-render path) ;; Render a user-defined literal path from the data points ;; decode the points into coordinates (let ((points (literal-points path)) (3d (literal-3d path)) (polar (literal-polar path))) (let ((vals (if polar (parse-polar-coordinates points 3d) (parse-cartesian-coordinates points 3d)))) (set! (path-rx path) (car vals)) (set! (path-ry path) (cadr vals)) (set! (path-rz path) (caddr vals)) (set! (path-rv path) (cadddr vals))) ;; make sure there are initial and final velocity values (if (not (car (path-rv path))) (begin (set! ((path-rv path) 0) 1) (set! ((path-rv path) (- (length (path-rv path)) 1)) 1))) ;; only one point means no movement, static source (if (= (length (path-rx path)) 1) (begin (set! (path-rt path) (list 0.0)) (reset-transformation path)) (let* ((rx (path-rx path)) (ry (path-ry path)) (rz (path-rz path)) (rv (path-rv path)) (xseg (list (car rx))) (yseg (list (car ry))) (zseg (list (car rz))) (vseg (list (car rv))) (vi (car rv)) (len (length rx)) (ti 0) (times (list ti))) (do ((i 1 (+ i 1))) ((= i len)) (let ((x (rx i)) (y (ry i)) (z (rz i)) (v (rv i))) (set! xseg (append xseg (list x))) (set! yseg (append yseg (list y))) (set! zseg (append zseg (list z))) (set! vseg (append vseg (list v))) (if (number? v) ; when v (let ((sofar 0.0) (dseg ()) (len (- (length xseg) 1))) (do ((i 0 (+ i 1))) ((= i len)) (let ((xsi (xseg i)) (ysi (yseg i)) (zsi (zseg i)) (xsf (xseg (+ i 1))) (ysf (yseg (+ i 1))) (zsf (zseg (+ i 1)))) (set! sofar (+ sofar (distance (- xsf xsi) (- ysf ysi) (- zsf zsi)))) (set! dseg (cons sofar dseg)))) (let ((df (car dseg))) (set! dseg (reverse dseg)) (let* ((tseg ()) (vf v) (a (/ (* (- vf vi) (+ vf vi)) df 4))) (for-each (lambda (d) (set! tseg (cons (+ ti (if (= vf vi) (/ d vi) (/ (- (sqrt (+ (* vi vi) (* 4 a d))) vi) (* 2 a)))) tseg))) dseg) (set! ti (car tseg)) (set! tseg (reverse tseg)) (set! times (append times tseg)) (set! xseg (list x)) (set! yseg (list y)) (set! zseg (list z)) (set! vseg (list v)) (set! vi v))))))) (set! (path-rt path) (let ((val ()) (tf (times (- (length times) 1)))) (for-each (lambda (ti) (set! val (cons (/ ti tf) val))) times) (reverse val))) (reset-transformation path))))) (define (spiral-render path) ;; Render a spiral path from the object data (let* ((start (* (/ (spiral-start-angle path) dlocsig-one-turn) 2 pi)) (total (if (spiral-total-angle path) (* (/ (spiral-total-angle path) dlocsig-one-turn) 2 pi) (if (spiral-turns path) (* (spiral-turns path) 2 pi) (error 'mus-error "ERROR: a spiral-path needs either a total-angle or turns, none specified~%")))) (steps (abs (/ total (* (/ (spiral-step-angle path) dlocsig-one-turn) 2 pi)))) (step (/ total (ceiling steps) (if (< (spiral-step-angle path) 0) -1 1))) (xdistance (x-norm (spiral-distance path) total)) (height (x-norm (spiral-height path) total))) (let* ((x ()) (y ()) (z ()) (segments (round (abs (/ total step)))) (len (+ 1 segments))) (do ((i 0 (+ i 1)) (angle start (+ angle step))) ((>= i len)) (let ((xy (cis angle)) (d (envelope-interp angle xdistance))) (set! x (cons (* d (imag-part xy)) x)) (set! y (cons (* d (real-part xy)) y)) (set! z (cons (envelope-interp angle height) z)))) (set! x (reverse x)) (set! y (reverse y)) (set! z (reverse z)) (let ((dp ()) (len (- (length x) 1)) (sofar 0.0)) (do ((i 0 (+ i 1))) ((>= i len)) (let ((xi (x i)) (xf (x (+ i 1))) (yi (y i)) (yf (y (+ i 1))) (zi (z i)) (zf (z (+ i 1)))) (set! sofar (+ sofar (distance (- xf xi) (- yf yi) (- zf zi)))) (set! dp (cons sofar dp)))) (let () (set! dp (reverse dp)) (let ((tp ()) (td 0) (len (- (length dp) 1))) (do ((i 0 (+ i 1))) ((>= i len)) (let* ((di (dp i)) (df (dp (+ i 1))) (vp (x-norm (spiral-velocity path) df)) (vi (envelope-interp di vp)) (vf (envelope-interp df vp))) (set! tp (cons td tp)) (set! td (+ td (/ (- df di) (+ vi vf) 2))))) (let ((tf (car tp))) (set! tp (reverse tp)) (set! (path-rx path) x) (set! (path-ry path) y) (set! (path-rz path) z) (let ((val ())) (for-each (lambda (ti) (set! val (cons (/ ti tf) val))) tp) (set! (path-rt path) (reverse val)))))))) (reset-transformation path))) (define (render-path path) (cond ((memq (car path) '(bezier-path open-bezier-path)) (bezier-render path)) ((eq? (car path) 'literal-path) (literal-render path)) (#t (spiral-render path)))) ;;;;;;;;;;;;;;;;;;; ;;; Transformations ;;;;;;;;;;;;;;;;;;; ;;; Transform a rendered path using scaling, translation and rotation ;;; Transform a path (scaling + translation + rotation) (define* (transform-path path scaling translation rotation rotation-center (rotation-axis '(0.0 0.0 1.0))) ;; Derive a rotation matrix from an axis vector and an angle (define (rotation-matrix x y z angle) ;; translated from C routine by David Eberly ;; (http://www.magic-software.com/) (define (normalize a b c) (let ((mag (sqrt (+ (* a a) (* b b) (* c c))))) (list (/ a mag) (/ b mag) (/ c mag)))) (let* ((vals (normalize x y z)) (dx (car vals)) (dy (cadr vals)) (dz (caddr vals)) (rotate (vector (vector 0.0 0.0 0.0) (vector 0.0 0.0 0.0) (vector 0.0 0.0 0.0))) (I (vector (vector 1.0 0.0 0.0) (vector 0.0 1.0 0.0) (vector 0.0 0.0 1.0))) (A (vector (vector 0.0 dz (- dy)) (vector (- dz) 0.0 dx) (vector dy (- dx) 0.0))) (AA (vector (vector 0.0 0.0 0.0) (vector 0.0 0.0 0.0) (vector 0.0 0.0 0.0))) (sn (sin (- angle))) (omcs (- 1 (cos angle)))) ; (cos (- angle)) == (cos angle) (do ((row 0 (+ 1 row))) ((= row 3)) (do ((col 0 (+ 1 col))) ((= col 3)) (set! ((AA row) col) 0.0) (do ((mid 0 (+ 1 mid))) ((= mid 3)) (set! ((AA row) col) (+ ((AA row) col) (* ((A row) mid) ((A mid) col))))))) ;; rotation matrix is I+sin(angle)*A+[1-cos(angle)]*A*A (do ((row 0 (+ 1 row))) ((= row 3)) (do ((col 0 (+ 1 col))) ((= col 3)) (set! ((rotate row) col) (+ ((I row) col) (* sn ((A row) col)) (* omcs ((AA row) col)))))) rotate)) (if (not-rendered path) (render-path path)) (if (or scaling translation rotation) ;; there's at least one transformation to execute (let* ((rotation (and rotation (* 2 pi (/ rotation dlocsig-one-turn)))) (matrix (and rotation (rotation-matrix (car rotation-axis) (cadr rotation-axis) (third rotation-axis) rotation))) (xc (path-x path)) (yc (path-y path)) (zc (path-z path))) (if (and rotation-center (not (= (length rotation-center) 3))) (error 'mus-error "ERROR: rotation center has to have all three coordinates~%")) (if (and rotation-axis (not (= (length rotation-axis) 3))) (error 'mus-error "ERROR: rotation axis has to have all three coordinates~%")) (let ((len (length xc)) (xtr ()) (ytr ()) (ztr ())) (do ((i 0 (+ i 1))) ((= i len)) (let* ((x (xc i)) (y (yc i)) (z (zc i)) (xw x) (yw y) (zw z)) ;; rotating around non-triple zero? translate first (if (and rotation-center rotation) (begin (set! xw (- xw (car rotation-center))) (set! yw (- yw (cadr rotation-center))) (set! zw (- zw (third rotation-center))))) ;; rotation (if rotation (let ((xr (+ (* ((matrix 0) 0) xw) (* ((matrix 1) 0) yw) (* ((matrix 2) 0) zw))) (yr (+ (* ((matrix 0) 1) xw) (* ((matrix 1) 1) yw) (* ((matrix 2) 1) zw))) (zr (+ (* ((matrix 0) 2) xw) (* ((matrix 1) 2) yw) (* ((matrix 2) 2) zw)))) (set! xw xr) (set! yw yr) (set! zw zr))) ;; rotating around non-triple zero? untranslate (if (and rotation-center rotation) (begin (set! xw (+ xw (car rotation-center))) (set! yw (+ yw (cadr rotation-center))) (set! zw (+ zw (third rotation-center))))) ;; scaling (if scaling (begin (set! xw (* xw (car scaling))) (if (cadr scaling) (set! yw (* yw (cadr scaling)))) (if (third scaling) (set! zw (* zw (third scaling)))))) ;; translating (if translation (begin (set! xw (+ xw (car translation))) (if (cadr translation) (set! yw (+ yw (cadr translation)))) (if (third translation) (set! zw (+ zw (third translation)))))) ;; collect the points (set! xtr (cons xw xtr)) (set! ytr (cons yw ytr)) (set! ztr (cons zw ztr)))) (set! (path-tx path) (reverse xtr)) (set! (path-ty path) (reverse ytr)) (set! (path-tz path) (reverse ztr)))) (begin ;; if there's no transformation just copy the rendered path (set! (path-tt path) (copy (path-rt path))) (set! (path-tx path) (copy (path-rx path))) (set! (path-ty path) (copy (path-ry path))) (set! (path-tz path) (copy (path-rz path))))) path) ;;; Scale a path (define (scale-path path scaling) (transform-path path :scaling scaling)) ;;; Translate a path (define (translate-path path translation) (transform-path path :translation translation)) ;;; Rotate a path (define rotate-path (let ((documentation "rotate-path is a dlocsig function that rotates a dlocsig path")) (lambda* (path rotation rotation-center (rotation-axis '(0.0 0.0 1.0))) (transform-path path :rotation rotation :rotation-center rotation-center :rotation-axis rotation-axis)))) ;;; Mirror a path around an axis (define* (mirror-path path (axis 'y) (around 0)) (if (not-transformed path) (transform-path path)) (if (eq? axis 'y) (let ((val ())) (for-each (lambda (x) (set! val (cons (- around x) val))) (path-tx path)) (set! (path-tx path) (reverse val))) (let ((val ())) (for-each (lambda (y) (set! val (cons (- around y) val))) (path-ty path)) (set! (path-ty path) (reverse val)))) path) ;;; Change the times of the rendered envelope so that the velocity is constant (define constant-velocity (let ((documentation "constant-velocity is a dlocsig function that changes the times of the rendered envelope so that the velocity is constant")) (lambda (path) (if (not (path-rx path)) (render-path path)) (reset-transformation path) (let* ((xcoords (path-x path)) (ycoords (path-y path)) (zcoords (path-z path)) (tcoords (path-time path)) (total-distance (let ((sum 0.0) (len (length xcoords))) (do ((i 0 (+ i 1))) ((= i len)) (let ((x1 (xcoords i)) (x2 (xcoords (+ i 1))) (y1 (ycoords i)) (y2 (ycoords (+ i 1))) (z1 (zcoords i)) (z2 (zcoords (+ i 1)))) (set! sum (+ sum (distance (- x2 x1) (- y2 y1) (- z2 z1)))))) sum)) (start-time (car tcoords)) (end-time (tcoords (- (length tcoords) 1))) (total-time (- end-time start-time)) (velocity (/ total-distance total-time))) (let ((len (length xcoords)) (now ()) (dist 0.0)) (do ((i 0 (+ i 1))) ((= i len)) (let ((xp (xcoords i)) (x (xcoords (+ i 1))) (yp (ycoords i)) (y (ycoords (+ i 1))) (zp (zcoords i)) (z (zcoords (+ i 1)))) (set! dist (+ dist (distance (- x xp) (- y yp) (- z zp)))) (set! now (cons (/ dist velocity) now)))) (set! now (reverse now)) (set! (path-rt path) (append (list start-time) now)) (set! (path-tx path) (copy (path-rx path))) (set! (path-ty path) (copy (path-ry path))) (set! (path-tz path) (copy (path-rz path))))) path))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Create a new dlocsig structure (define* (make-dlocsig start-time duration (path dlocsig-path) (scaler dlocsig-scaler) (direct-power dlocsig-direct-power) (inside-direct-power dlocsig-inside-direct-power) (reverb-power dlocsig-reverb-power) (inside-reverb-power dlocsig-inside-reverb-power) (reverb-amount dlocsig-reverb-amount) (initial-delay dlocsig-initial-delay) (unity-gain-dist dlocsig-unity-gain-distance) (inside-radius dlocsig-inside-radius) (minimum-segment-length dlocsig-minimum-segment-length) (render-using dlocsig-render-using) (ambisonics-h-order dlocsig-ambisonics-h-order) (ambisonics-v-order dlocsig-ambisonics-v-order) out-channels rev-channels) (if (null? start-time) (error 'mus-error "ERROR: a start time is required in make-dlocsig~%")) (if (null? duration) (error 'mus-error "ERROR: a duration has to be specified in make-dlocsig~%")) ;; check to see if we have the right number of channels for b-format ambisonics (if (= render-using ambisonics) (begin (if (or (> ambisonics-h-order 3) (> ambisonics-v-order 3)) (error 'mus-error "ERROR: ambisonics encoding is currently limited to third order components~%")) (let ((channels (ambisonics-channels ambisonics-h-order ambisonics-v-order))) (if (< (or out-channels (mus-channels *output*)) channels) (error 'mus-error "ERROR: ambisonics number of channels is wrong, dlocsig needs ~A output channels for h:~A, v:~A order (current number is ~A)~%" channels ambisonics-h-order ambisonics-v-order (or out-channels (mus-channels *output*))))))) (if (not out-channels) (if *output* (set! out-channels (channels *output*)) (begin (format #t "WARNING: no *output*? Will set out-channels to 2~%") (set! out-channels 2)))) (if (not rev-channels) (set! rev-channels (if *reverb* (channels *reverb*) 0))) (let* (;; speaker configuration for current number of channels (speakers (if (= render-using ambisonics) #f (get-speaker-configuration out-channels))) ;; array of gains -- envelopes (channel-gains (make-vector out-channels ())) (channel-rev-gains (make-vector out-channels ())) ;; speaker output delays (max-out-delay 0.0) (out-delays (make-vector out-channels)) ;; coordinates of rendered path (xpoints (path-x path)) (ypoints (path-y path)) (zpoints (path-z path)) (tpoints (path-time path)) ;; speed of sound expressed in terms of path time coordinates (speed-limit (/ (* dlocsig-speed-of-sound (- (car (last tpoints)) (car tpoints))) duration)) (start 0) ;(end 0) (dly ()) (doppler ()) (real-dur 0) (prev-time #f) (prev-dist #f) (prev-group #f) (prev-x #f) (prev-y #f) (prev-z #f) (first-dist #f) (last-dist #f) (min-dist #f) (max-dist #f) (min-delay #f) ;; without this the delay apparently stomps over something else in the structure ;; and we get artifacts in the output, probably a off-by-one error somewhere (delay-hack 1) (min-dist-unity #f) (unity-gain 1.0) (unity-rev-gain 1.0) (amb-unity-gain 1.0) (amb-unity-rev-gain 1.0) (run-beg #f) (run-end #f) ;; channel offsets in output stream for ambisonics ;; (depends on horizontal and vertical order, default is h=1,v=1) (w-offset 0) (x-offset 1) (y-offset 2) (z-offset #f) (r-offset #f) (s-offset #f) (t-offset #f) (u-offset #f) (v-offset #f) (k-offset #f) (l-offset #f) (m-offset #f) (n-offset #f) (o-offset #f) (p-offset #f) (q-offset #f)) (if (= render-using ambisonics) ;; calculate output channel offsets for ambisonics rendering (let ((offset 3)) ;; the default is at least a horizontal order of 1 (if (>= ambisonics-v-order 1) (begin ;; add Z (set! z-offset offset) (set! offset (+ offset 1)))) (if (>= ambisonics-v-order 2) (begin ;; add R S T (set! r-offset offset) (set! s-offset (+ offset 1)) (set! t-offset (+ offset 2)) (set! offset (+ offset 3)))) (if (>= ambisonics-h-order 2) (begin ;; add U V (set! u-offset offset) (set! v-offset (+ offset 1)) (set! offset (+ offset 2)))) (if (>= ambisonics-v-order 3) (begin ;; add K L M N O (set! k-offset offset) (set! l-offset (+ offset 1)) (set! m-offset (+ offset 2)) (set! n-offset (+ offset 3)) (set! o-offset (+ offset 4)) (set! offset (+ offset 5)))) (if (>= ambisonics-h-order 3) (begin ;; add P Q (set! p-offset offset) (set! q-offset (+ offset 1))) (set! offset (+ offset 2))))) (define (equalp-intersection l1 l2) (if (null? l2) l2 (let loop1 ((l1 l1) (result ())) (cond ((null? l1) (reverse! result)) ((member (car l1) l2) (loop1 (cdr l1) (cons (car l1) result))) (else (loop1 (cdr l1) result)))))) (define (dist->samples d) (round (* d (/ *clm-srate* dlocsig-speed-of-sound)))) ;; (define (dist->seconds d) (/ d dlocsig-speed-of-sound)) (define (time->samples time) (round (* time *clm-srate*))) (define (transition-point-3 vert-a vert-b xa ya za xb yb zb) (define (cross v1 v2) (list (- (* (cadr v1) (third v2)) (* (third v1) (cadr v2))) (- (* (third v1) (car v2)) (* (car v1) (third v2))) (- (* (car v1) (cadr v2)) (* (cadr v1) (car v2))))) (define (dot v1 v2) (+ (* (car v1) (car v2)) (* (cadr v1) (cadr v2)) (* (third v1) (third v2)))) (define (sub v1 v2) (list (- (car v1) (car v2)) (- (cadr v1) (cadr v2)) (- (third v1) (third v2)))) (define (add v1 v2) (list (+ (car v1) (car v2)) (+ (cadr v1) (cadr v2)) (+ (third v1) (third v2)))) (define (scale v1 c) (list (* (car v1) c) (* (cadr v1) c) (* (third v1) c))) (let* ((tolerance 1.0e-6) (line-b (list xa ya za)) (line-m (sub (list xb yb zb) line-b)) (normal (cross vert-a vert-b)) (denominator (dot normal line-m))) (if (<= (abs denominator) tolerance) #f (add line-b (scale line-m (/ (- (dot normal line-b)) denominator)))))) ;; calculate transition point between two adjacent two-speaker groups ;; original line intersection code from Graphic Gems III (define (transition-point-2 vert xa ya xb yb) (let* ((Ax (car vert)) (Bx (- xa xb)) (Ay (cadr vert)) (By (- ya yb)) (Cx (- xa)) (Cy (- ya)) (d (- (* By Cx) (* Bx Cy))) (f (- (* Ay Bx) (* Ax By)))) (and (not (= f 0)) (list (/ (* d Ax) f) (/ (* d Ay) f))))) ;; calculate speaker gains for group (define (calculate-gains x y z group) (let ((zero-coord 1.0e-10) (zero-gain 1.0e-10) (size (group-size group)) (mat (group-matrix group))) ; returns float-vector (if (and (< (abs x) zero-coord) (< (abs y) zero-coord) (< (abs z) zero-coord)) (list #t (list 1.0 1.0 1.0)) (if (= size 3) (let* ((gain-a (+ (* (mat 0 0) x) (* (mat 1 0) y) (* (mat 2 0) z))) (gain-b (+ (* (mat 0 1) x) (* (mat 1 1) y) (* (mat 2 1) z))) (gain-c (+ (* (mat 0 2) x) (* (mat 1 2) y) (* (mat 2 2) z))) (mag (sqrt (+ (* gain-a gain-a) (* gain-b gain-b) (* gain-c gain-c))))) ;; truncate to zero roundoff errors (if (< (abs gain-a) zero-gain) (set! gain-a 0.0)) (if (< (abs gain-b) zero-gain) (set! gain-b 0.0)) (if (< (abs gain-c) zero-gain) (set! gain-c 0.0)) (list (and (>= gain-a 0) (>= gain-b 0) (>= gain-c 0)) (list (/ gain-a mag) (/ gain-b mag) (/ gain-c mag)))) (if (= size 2) (let* ((gain-a (+ (* (mat 0 0) x) (* (mat 1 0) y))) (gain-b (+ (* (mat 0 1) x) (* (mat 1 1) y))) (mag (sqrt (+ (* gain-a gain-a) (* gain-b gain-b))))) ;; truncate to zero roundoff errors (if (< (abs gain-a) zero-gain) (set! gain-a 0.0)) (if (< (abs gain-b) zero-gain) (set! gain-b 0.0)) (list (and (>= gain-a 0) (>= gain-b 0)) (list (/ gain-a mag) (/ gain-b mag)))) (if (= size 1) (list #t (list 1.0)))))))) ;; find the speaker group that contains a point (define (find-group x y z) (call-with-exit (lambda (return) (for-each (lambda (group) (let* ((vals (calculate-gains x y z group)) (inside (car vals)) (gains (cadr vals))) (if inside (return (list group gains))))) (speaker-config-groups speakers)) (list #f #f)))) ;; push zero gains on all channels (define (push-zero-gains time) (let ((len (speaker-config-number speakers))) (do ((i 0 (+ i 1))) ((= i len)) (set! (channel-gains i) (cons time (channel-gains i))) (set! (channel-gains i) (cons 0.0 (channel-gains i))))) (let ((len rev-channels)) (do ((i 0 (+ i 1))) ((= i len)) (set! (channel-rev-gains i) (cons time (channel-rev-gains i))) (set! (channel-rev-gains i) (cons 0.0 (channel-rev-gains i)))))) (define (position val lst) (define (position-1 val lst pos) (call-with-exit (lambda (return) (and (not (null? lst)) (if (= val (car lst)) (return pos) (position-1 val (cdr lst) (+ 1 pos))))))) (position-1 val lst 0)) ;; push gain and time into envelopes (define (push-gains group gains dist time num) (let ((outputs (make-vector out-channels 0.0)) (rev-outputs (make-vector rev-channels 0.0)) ;; attenuation with distance of direct signal (att (if (>= dist inside-radius) (/ (expt dist direct-power)) (- 1.0 (expt (/ dist inside-radius) (/ inside-direct-power))))) ;; attenuation with distance of reverberated signal (ratt (if (>= dist inside-radius) (/ (expt dist reverb-power)) (- 1.0 (expt (/ dist inside-radius) (/ inside-reverb-power)))))) (if (>= dist inside-radius) ;; outside the inner sphere, signal is sent to group (let ((len (length gains))) (do ((i 0 (+ i 1))) ((= i len)) (let ((speaker ((group-speakers group) i)) (gain (gains i))) (set! (outputs speaker) (* gain att)) (if (and (> rev-channels 1) (< speaker (length rev-outputs))) (set! (rev-outputs speaker) (* gain ratt)))))) (let ((gain 0.0) (len (speaker-config-number speakers))) (do ((speaker 0 (+ 1 speaker))) ((= speaker len)) ;; inside the inner sphere, signal is sent to all speakers (let ((found (position speaker (group-speakers group)))) (if found ;; speaker belongs to group, add to existing gain (begin (set! gain (gains found)) (set! (outputs speaker) (+ gain (* (- 1.0 gain) att))) (if (> rev-channels 1) (set! (rev-outputs speaker) (+ gain (* (- 1.0 gain) ratt))))) ;; speaker outside of group (begin (set! (outputs speaker) att) (if (> rev-channels 1) (set! (rev-outputs speaker) ratt)))))))) ;; push all channel gains into envelopes (let ((len (speaker-config-number speakers))) (do ((i 0 (+ i 1))) ((= i len)) (if (or (null? (channel-gains i)) (> time (cadr (channel-gains i)))) (begin (set! (channel-gains i) (cons time (channel-gains i))) (set! (channel-gains i) (cons (outputs i) (channel-gains i))))))) (if (> rev-channels 1) (do ((i 0 (+ i 1))) ((= i rev-channels)) (if (or (null? (channel-rev-gains i)) (> time (cadr (channel-rev-gains i)))) (begin (set! (channel-rev-gains i) (cons time (channel-rev-gains i))) (set! (channel-rev-gains i) (cons (rev-outputs i) (channel-rev-gains i))))))) ;; push reverb gain into envelope for mono reverb (if (and (= rev-channels 1) (or (null? (channel-rev-gains 0)) (> time (cadr (channel-rev-gains 0))))) (begin (set! (channel-rev-gains 0) (cons time (channel-rev-gains 0))) (set! (channel-rev-gains 0) (cons ratt (channel-rev-gains 0))))))) ;; Render a trajectory breakpoint through amplitude panning (define (famplitude-panning x y z dist time q) ;; output gains for current point (if prev-group (let* ((vals (calculate-gains x y z prev-group)) (inside (car vals)) (gains (cadr vals))) ;; check that the source is not moving faster than sound (if (not (= time prev-time)) (let ((speed (/ (- dist prev-dist) (- time prev-time)))) (if (> speed speed-limit) (format #t "WARNING: supersonic radial movement at [~F,~F,~F, ~F], speed=~F~%" x y z time speed)))) (if inside ;; still in the same group (begin (push-gains prev-group gains dist time 1) (set! prev-x x) (set! prev-y y) (set! prev-z z)) ;; left the group (let* ((vals (find-group x y z)) (group (car vals)) (gains (cadr vals))) (if group ;; we have to interpolate a new point that lies on the shared ;; edge of the adjacent groups so that the speakers opposite ;; the edge have zero gain when the trajectory switches groups (let ((edge (equalp-intersection (group-vertices group) (group-vertices prev-group)))) (if (= (length edge) 2) ;; the groups have two shared points (ie: share an edge) ;; this must be a three speaker groups transition (let ((pint (transition-point-3 (car edge) (cadr edge) x y z prev-x prev-y prev-z))) (if pint (let* ((xi (car pint)) (yi (cadr pint)) (zi (third pint)) (di (distance xi yi zi)) (ti (+ prev-time (max .00001 (* (/ (distance (- xi prev-x) (- yi prev-y) (- zi prev-z)) (distance (- x prev-x) (- y prev-y) (- z prev-z))) (- time prev-time)))))) ;; see if we are inside the previous group ;; we can be on either side due to roundoff errors (let* ((vals (calculate-gains xi yi zi prev-group)) (inside (car vals)) (gains (cadr vals))) (if inside (push-gains prev-group gains di ti 2) (let* ((val1 (calculate-gains xi yi zi group)) (inside (car val1)) (gains (cadr val1))) (if inside (push-gains group gains di ti 3) ;; how did we get here? (error 'mus-error "ERROR: Outside of both adjacent groups [~A:~A:~A @~A]~%~%" xi yi zi ti)))))))) (if (and (= (length edge) 1) (= (group-size group) 2)) ;; two two-speaker groups share one point ;; z coordinates are silently ignored (let ((pint (transition-point-2 (car edge) x y prev-x prev-y))) (if pint (let* ((xi (car pint)) (yi (cadr pint)) (di (distance xi yi 0.0)) (ti (+ prev-time (max .00001 (* (/ (distance (- xi prev-x) (- yi prev-y) 0.0) (distance (- x prev-x) (- y prev-y) 0.0)) (- time prev-time)))))) ;; see if we are inside the previous group ;; we can be on either side due to roundoff errors (let* ((vals (calculate-gains xi yi 0.0 prev-group)) (inside (car vals)) (gains (cadr vals))) (if inside (push-gains prev-group gains di ti 4) (let* ((val1 (calculate-gains xi yi 0.0 group)) (inside (car val1)) (gains (cadr val1))) (if inside (push-gains group gains di ti 5) ;; how did we get here? (format #t "Outside of both adjacent groups [~A:~A @~A]~%~%" xi yi ti)))))))) (if (= (length edge) 1) ;; groups share only one point... for now a warning ;; we should calculate two additional interpolated ;; points as the trajectory must be crossing a third ;; group (begin (for-each (lambda (int-group) (if (and (member (car edge) (group-vertices int-group)) (not (equal? int-group group)) (not (equal? int-group prev-group))) (let ((edge1 (equalp-intersection (group-vertices int-group) (group-vertices prev-group))) (edge2 (equalp-intersection (group-vertices int-group) (group-vertices group)))) (format #t "e1=~A; e2=~A~%~%" edge1 edge2)))) (speaker-config-groups speakers)) (format #t "WARNING: crossing between groups with only one point in common~% prev=~A~% curr=~A~%" prev-group group)) ;; groups don't share points... how did we get here? (if (= (length edge) 0) (format #t "WARNING: crossing between groups with no common points, ~A~A to ~A~A~%" (group-id prev-group) (group-speakers prev-group) (group-id group) (group-speakers group)))))) ;; finally push gains for current group (push-gains group gains dist time 6) (set! prev-group group) (set! prev-x x) (set! prev-y y) (set! prev-z z)) ;; current point is outside all defined groups ;; we should send a warning at this point... (begin (push-zero-gains time) (set! prev-group #f)))))) ;; first time around (let* ((vals (find-group x y z)) (group (car vals)) (gains (cadr vals))) (if group (begin (push-gains group gains dist time 7) (set! prev-group group) (set! prev-x x) (set! prev-y y) (set! prev-z z)) (begin (push-zero-gains time) (set! prev-group #f)))))) ;; Render a trajectory breakpoint for ambisonics b-format coding ;; http://www.york.ac.uk/inst/mustech/3d_audio/ambis2.htm ;; ;; Ambisonics b-format has four discrete channels encoded as follows: ;; W 0.707107 0.707107 ;; X cos(A)cos(E) x ;; Y sin(A)cos(E) y ;; R 1.5sin(E)sin(E)-0.5 1.5zz-0.5 ;; S cos(A)sin(2E) 2zx ;; T sin(A)sin(2E) 2yz ;; U cos(2A)cos(E)cos(E) xx-yy ;; V sin(2A)cos(E)cos(E) 2xy ;; K z(2.5zz-1.5) ;; L K1(x(5zz-1) ;; K1=sqrt(21*45/(224*8)) ;; M K1(y(5zz-1)) ;; N K2(Uz) ;; K2=sqrt(3)*3/2 ;; O K2(Vz) ;; P x(xx-3yy) ;; Q y(3xx-yy) ;; ;; where: ;; A: counter-clockwise angle of rotation from the front center ;; E: the angle of elevation above the horizontal plane ;; ;; in our coordinate system (normalizing the vectors): ;; xy: (* dist (cos E)) ;; (cos A): (/ y xy) ;; (sin A): (/ -x xy) ;; (cos E): (/ xy dist) ;; (sin E): (/ z dist) ;; so: ;; W: (* signal 0.707) ;; X: (* signal (/ y dist)) ;; Y: (* signal (/ -x dist)) ;; Z: (* signal (/ z dist)) ;; ;; R: (* signal (- (* 1.5 z z 1/dist 1/dist) 0.5)) ;; S: (* signal 2 z (- x) 1/dist 1/dist) ;; T: (* signal 2 z y 1/dist 1/dist) ;; U: (* signal (- (* x x 1/dist 1/dist) (* y y 1/dist 1/dist))) ;; V: (* signal 2 (- x) y 1/dist 1/dist) ;; ;; K: (* signal z (- (* 2.5 z z 1/dist 1/dist) 1.5)) ;; L: (* signal K1 x 1/dist (- (* 5 z z 1/dist 1/dist) 1)) ;; M: (* signal K1 y 1/dist (- (* 5 z z 1/dist 1/dist) 1)) ;; N: (* signal K2 U z 1/dist) ;; O: (* signal K2 V z 1/dist) ;; P: (* signal x 1/dist (- (* x x 1/dist 1/dist) (* 3 y y 1/dist 1/dist))) ;; Q: (* signal y 1/dist (- (* 3 x x 1/dist 1/dist) (* y y 1/dist 1/dist))) ;; ;; see also: http://wiki.xiph.org/index.php/Ambisonics ;; for mixed order systems ;; (define (render-ambisonics x y z dist time) (let* ((att (if (> dist inside-radius) (expt (/ inside-radius dist) direct-power) (expt (/ dist inside-radius) (/ inside-direct-power)))) (attW (if (> dist inside-radius) (* point707 att) (- 1 (* (- 1 point707) (expt (/ dist inside-radius) direct-power))))) (ratt (if (> dist inside-radius) (expt (/ inside-radius dist) reverb-power) (expt (/ dist inside-radius) (/ inside-reverb-power)))) (rattW (if (> dist inside-radius) (* point707 ratt) (- 1 (* (- 1 point707) (expt (/ dist inside-radius) reverb-power))))) ;; storage for some intermediate calculations (u 0) (v 0) (lm 0) (no 0)) ;; output encoding gains for point ;; W: 0.707 (set! (channel-gains w-offset) (cons time (channel-gains w-offset))) (set! (channel-gains w-offset) (cons attW (channel-gains w-offset))) ;; X: (* (cos A) (cos E)) (set! (channel-gains x-offset) (cons time (channel-gains x-offset))) (set! (channel-gains x-offset) (cons (* (if (zero? dist) 0 (/ y dist)) att) (channel-gains x-offset))) ;; Y: (* (sin A) (cos E)) (set! (channel-gains y-offset) (cons time (channel-gains y-offset))) (set! (channel-gains y-offset) (cons (* (if (zero? dist) 0 (/ (- x) dist)) att) (channel-gains y-offset))) (if (>= ambisonics-v-order 1) (begin ;; Z: (sin E) (set! (channel-gains z-offset) (cons time (channel-gains z-offset))) (set! (channel-gains z-offset) (cons (* (if (zero? dist) 0 (/ z dist)) att) (channel-gains z-offset))))) (if (>= ambisonics-v-order 2) (begin ;; R (set! (channel-gains r-offset) (cons time (channel-gains r-offset))) (set! (channel-gains r-offset) (cons (* (if (zero? dist) 0 (- (* 1.5 z z (if (zero? dist) 1 (/ 1.0 (* dist dist)))) 0.5)) att) (channel-gains r-offset))) ;; S (set! (channel-gains s-offset) (cons time (channel-gains s-offset))) (set! (channel-gains s-offset) (cons (* (if (zero? dist) 0 2) z (- x) (if (zero? dist) 1 (/ 1.0 (* dist dist))) att) (channel-gains s-offset))) ;; T (set! (channel-gains t-offset) (cons time (channel-gains t-offset))) (set! (channel-gains t-offset) (cons (* (if (zero? dist) 0 2) z y (if (zero? dist) 1 (/ 1.0 (* dist dist))) att) (channel-gains t-offset))))) (if (>= ambisonics-h-order 2) (begin (set! u (* (if (zero? dist) 0 1) (- (* x x (if (zero? dist) 1 (/ 1.0 (* dist dist)))) (* y y (if (zero? dist) 1 (/ 1.0 (* dist dist))))) att)) (set! v (* (if (zero? dist) 0 2) (- x) y (if (zero? dist) 1 (/ 1.0 (* dist dist))) att)) ;; U (set! (channel-gains u-offset) (cons time (channel-gains u-offset))) (set! (channel-gains u-offset) (cons u (channel-gains u-offset))) ;; V (set! (channel-gains v-offset) (cons time (channel-gains v-offset))) (set! (channel-gains v-offset) (cons v (channel-gains v-offset))))) (if (>= ambisonics-v-order 3) (begin (set! lm (* ambisonics-k1 (- (* 5 z z (if (zero? dist) 1 (/ 1.0 (* dist dist)))) 1) att)) (set! no (* ambisonics-k2 z (if (zero? dist) 1 (/ dist)) att)) ;; K (set! (channel-gains k-offset) (cons time (channel-gains k-offset))) (set! (channel-gains k-offset) (cons (* (if (zero? dist) 0 1) (- (* 2.5 z z (if (zero? dist) 1 (/ 1.0 (* dist dist)))) 1.5) att) (channel-gains k-offset))) ;; L (set! (channel-gains l-offset) (cons time (channel-gains l-offset))) (set! (channel-gains l-offset) (cons (* (if (zero? dist) 0 (/ x dist)) lm) (channel-gains l-offset))) ;; M (set! (channel-gains m-offset) (cons time (channel-gains m-offset))) (set! (channel-gains m-offset) (cons (* (if (zero? dist) 0 (/ y dist)) lm) (channel-gains m-offset))) ;; N (set! (channel-gains n-offset) (cons time (channel-gains n-offset))) (set! (channel-gains n-offset) (cons (* (if (zero? dist) 0 no) u) (channel-gains n-offset))) ;; O (set! (channel-gains o-offset) (cons time (channel-gains o-offset))) (set! (channel-gains o-offset) (cons (* (if (zero? dist) 0 no) v) (channel-gains o-offset))))) (if (>= ambisonics-h-order 3) (begin ;; P (set! (channel-gains p-offset) (cons time (channel-gains p-offset))) (set! (channel-gains p-offset) (cons (* (if (zero? dist) 0 (/ att dist)) x (- (* x x (if (zero? dist) 1 (/ 1.0 (* dist dist)))) (* 3 y y (if (zero? dist) 1 (/ 1.0 (* dist dist)))))) (channel-gains p-offset))) ;; Q (set! (channel-gains q-offset) (cons time (channel-gains q-offset))) (set! (channel-gains q-offset) (cons (* (if (zero? dist) 0 (/ att dist)) y (- (* 3 x x (if (zero? dist) 1 (/ 1.0 (* dist dist)))) (* y y (if (zero? dist) 1 (/ 1.0 (* dist dist)))))) (channel-gains q-offset))))) ;; push reverb gain into envelope (if (= rev-channels 1) (begin ;; mono reverb output (set! (channel-rev-gains 0) (cons time (channel-rev-gains 0))) (set! (channel-rev-gains 0) (cons (if (>= dist inside-radius) (/ (expt dist reverb-power)) (- 1.0 (expt (/ dist inside-radius) (/ inside-reverb-power)))) (channel-rev-gains 0))))) (if (> rev-channels 1) (let ((ho-ratt dlocsig-ambisonics-ho-rev-scaler)) ;; multichannel reverb, send ambisonics components ;; W: 0.707 (set! (channel-rev-gains w-offset) (cons time (channel-rev-gains w-offset))) (set! (channel-rev-gains w-offset) (cons rattW (channel-rev-gains w-offset))) ;; X: (* (cos A)(cos E)) (set! (channel-rev-gains x-offset) (cons time (channel-rev-gains x-offset))) (set! (channel-rev-gains x-offset) (cons (* (if (zero? dist) 0 1) y (if (zero? dist) 1 (/ dist)) ratt)(channel-rev-gains x-offset))) ;; Y: (* (sin A)(cos E)) (set! (channel-rev-gains y-offset) (cons time (channel-rev-gains y-offset))) (set! (channel-rev-gains y-offset) (cons (* (if (zero? dist) 0 1) (- x) (if (zero? dist) 1 (/ dist)) ratt) (channel-rev-gains y-offset))) (if (>= ambisonics-v-order 1) (begin ;; Z: (sin E) (set! (channel-rev-gains z-offset) (cons time (channel-rev-gains z-offset))) (set! (channel-rev-gains z-offset) (cons (* (if (zero? dist) 0 1) z (if (zero? dist) 1 (/ dist)) ratt) (channel-rev-gains z-offset))))) (if (>= ambisonics-v-order 2) (begin ;; R (set! (channel-rev-gains r-offset) (cons time (channel-rev-gains r-offset))) (set! (channel-rev-gains r-offset) (cons (* (if (zero? dist) 0 (- (* 1.5 z z (if (zero? dist) 1 (/ 1.0 (* dist dist)))) 0.5)) ho-ratt ratt) (channel-rev-gains r-offset))) ;; S (set! (channel-rev-gains s-offset) (cons time (channel-rev-gains s-offset))) (set! (channel-rev-gains s-offset) (cons (* (if (zero? dist) 0 2) z (- x) (if (zero? dist) 1 (/ 1.0 (* dist dist))) ho-ratt ratt) (channel-rev-gains s-offset))) ;; T (set! (channel-rev-gains t-offset) (cons time (channel-rev-gains t-offset))) (set! (channel-rev-gains t-offset) (cons (* (if (zero? dist) 0 2) z y (if (zero? dist) 1 (/ 1.0 (* dist dist))) ho-ratt ratt) (channel-rev-gains t-offset))))) (if (>= ambisonics-h-order 2) (begin ;; U (set! (channel-rev-gains u-offset) (cons time (channel-rev-gains u-offset))) (set! (channel-rev-gains u-offset) (cons (* (if (zero? dist) 0 (- (* x x (if (zero? dist) 1 (/ 1.0 (* dist dist)))) (* y y (if (zero? dist) 1 (/ 1.0 (* dist dist)))))) ho-ratt ratt) (channel-rev-gains u-offset))) ;; V (set! (channel-rev-gains v-offset) (cons time (channel-rev-gains v-offset))) (set! (channel-rev-gains v-offset) (cons (* (if (zero? dist) 0 2) (- x) y (if (zero? dist) 1 (/ 1.0 (* dist dist))) ho-ratt ratt) (channel-rev-gains v-offset))))) (if (>= ambisonics-v-order 3) (begin (set! lm (* ambisonics-k1 (- (* 5 z z (if (zero? dist) 1 (/ 1.0 (* dist dist)))) 1) ho-ratt ratt)) (set! no (* ambisonics-k2 z (if (zero? dist) 1 (/ dist)) ratt)) ;; K (set! (channel-rev-gains k-offset) (cons time (channel-rev-gains k-offset))) (set! (channel-rev-gains k-offset) (cons (* (if (zero? dist) 0 1) (- (* 2.5 z z (if (zero? dist) 1 (/ 1.0 (* dist dist)))) 1.5) ho-ratt ratt) (channel-rev-gains k-offset))) ;; L (set! (channel-rev-gains l-offset) (cons time (channel-rev-gains l-offset))) (set! (channel-rev-gains l-offset) (cons (* (if (zero? dist) 0 (/ x dist)) lm) (channel-rev-gains l-offset))) ;; M (set! (channel-rev-gains m-offset) (cons time (channel-rev-gains m-offset))) (set! (channel-rev-gains m-offset) (cons (* (if (zero? dist) 0 (/ y dist)) lm) (channel-rev-gains m-offset))) ;; N (set! (channel-rev-gains n-offset) (cons time (channel-rev-gains n-offset))) (set! (channel-rev-gains n-offset) (cons (* (if (zero? dist) 0 no) u) (channel-rev-gains n-offset))) ;; O (set! (channel-rev-gains o-offset) (cons time (channel-rev-gains o-offset))) (set! (channel-rev-gains o-offset) (cons (* (if (zero? dist) 0 no) v) (channel-rev-gains o-offset))))) (if (>= ambisonics-h-order 3) (begin ;; P (set! (channel-rev-gains p-offset) (cons time (channel-rev-gains p-offset))) (set! (channel-rev-gains p-offset) (cons (* (if (zero? dist) 0 (/ ratt dist)) ho-ratt x (- (* x x (if (zero? dist) 1 (/ 1.0 (* dist dist)))) (* 3 y y (if (zero? dist) 1 (/ 1.0 (* dist dist)))))) (channel-rev-gains p-offset))) ;; Q (set! (channel-rev-gains q-offset) (cons time (channel-rev-gains q-offset))) (set! (channel-rev-gains q-offset) (cons (* (if (zero? dist) 0 (/ ratt dist)) ho-ratt y (- (* 3 x x (if (zero? dist) 1 (/ 1.0 (* dist dist)))) (* y y (if (zero? dist) 1 (/ 1.0 (* dist dist)))))) (channel-rev-gains q-offset))))) )))) ;; Render a trajectory breakpoint to a room for decoded ambisonics ;; ;; for a given speaker located in 3d space in polar coordinates: ;; az: azimut angle, increments clockwise ;; el: elevation angle ;; ;; S: (+ W (* X (cos az) (cos el)) ;; (* Y (sin az) (cos el)) ;; (* Z (sin el))) ;; (define (fdecoded-ambisonics x y z dist time) (let* ((att (if (> dist inside-radius) (expt (/ inside-radius dist) direct-power) (expt (/ dist inside-radius) (/ inside-direct-power)))) (attW (if (> dist inside-radius) (* point707 att) (- 1 (* (- 1 point707) (expt (/ dist inside-radius) direct-power))))) (ratt (if (> dist inside-radius) (expt (/ inside-radius dist) reverb-power) (expt (/ dist inside-radius) (/ inside-reverb-power)))) (rattW (if (> dist inside-radius) (* point707 ratt) (- 1 (* (- 1 point707) (expt (/ dist inside-radius) reverb-power)))))) ;; output decoded gains for point (let ((len (speaker-config-number speakers)) (spkrs (speaker-config-coords speakers))) (do ((i 0 (+ i 1))) ((= i len)) (let* ((s (spkrs i)) (signal (* dlocsig-ambisonics-scaler (+ ;; W (* attW point707) ;; (* X (cos az) (cos el)) (* att (if (= dist 0) 0 (/ y dist)) (cadr s)) ;; (* Y (sin az) (cos el)) (* att (if (= dist 0) 0 (/ x dist)) (car s)) ;; (* Z (sin el) (* att (if (= dist 0) 0 (/ z dist)) (third s)))))) (set! (channel-gains i) (cons time (channel-gains i))) (set! (channel-gains i) (cons signal (channel-gains i)))))) ;; push reverb gain into envelope (if (= rev-channels 1) (begin ;; mono reverberation (set! (channel-rev-gains 0) (cons time (channel-rev-gains 0))) (set! (channel-rev-gains 0) (cons (if (>= dist inside-radius) (/ (expt dist reverb-power)) (- 1.0 (expt (/ dist inside-radius) (/ inside-reverb-power)))) (channel-rev-gains 0)))) ;; multichannel reverb (do ((i 0 (+ i 1))) ((= i rev-channels)) (let* ((s ((speaker-config-coords speakers) i)) (signal (* dlocsig-ambisonics-scaler (+ ;; W (* rattW point707) ;; (* X (cos az) (cos el)) (* ratt (if (zero? dist) 0 (/ y dist)) (cadr s)) ;; (* Y (sin az) (cos el)) (* ratt (if (zero? dist) 0 (/ x dist)) (car s)) ;; (* Z (sin el) (* ratt (if (zero? dist) 0 (/ z dist)) (third s)))))) (set! (channel-rev-gains i) (cons time (channel-rev-gains i))) (set! (channel-rev-gains i) (cons signal (channel-rev-gains i)))))))) ;; Loop through all virtual rooms for one breakpoint in the trajectory (define (walk-all-rooms x y z time num) (let ((room 0) (dist (distance x y z))) ;; remember first and last distances (if (not first-dist) ; set to #f (far) above (set! first-dist dist)) (set! last-dist dist) ;; remember maximum and minimum distances (if (or (not min-dist) (< dist min-dist)) (set! min-dist dist)) (if (or (not max-dist) (> dist max-dist)) (set! max-dist dist)) ;; push delay for current point (for doppler) (if (or (null? dly) (> time (cadr dly))) (begin (set! dly (cons time dly)) (set! dly (cons (dist->samples dist) dly)) ;; doppler should be easy, yeah right. We use "relativistic" correction ;; as the sound object can be travelling close to the speed of sound. ;; http://www.mathpages.com/rr/s2-04/2-04.htm, ;; va = 0 (stationary listener) ;; ve = moving object ;; va = (* ve (/ 1 (+ 1 (/ ve c))) (sqrt (- 1 (* (/ ve c) (/ ve c))))) (if prev-time (let ((ratio (/ (- dist prev-dist) (* duration (- time prev-time) dlocsig-speed-of-sound)))) (set! doppler (cons (/ (+ prev-time time) 2) doppler)) (set! doppler (cons (* (/ 1.0 (+ 1 ratio)) (sqrt (- 1 (* ratio ratio)))) doppler)))))) ;; do the rendering of the point (if (= render-using amplitude-panning) ;; amplitude panning (famplitude-panning x y z dist time 1) (if (= render-using ambisonics) ;; ambisonics b format (render-ambisonics x y z dist time) (if (= render-using decoded-ambisonics) ;; ambisonics decoded (fdecoded-ambisonics x y z dist time)))) (set! room (+ 1 room)) ;; remember current time and distance for next point (set! prev-time time) (set! prev-dist dist) ;; return number of rooms processed room)) ;; Check to see if a segment changes radial direction: ;; a change in radial direction implies a change in ;; doppler shift that has to be reflected as a new ;; point in the rendered envelopes (define (change-direction xa ya za ta xb yb zb tb num) (walk-all-rooms xa ya za ta 1) (if (or (not (= xa xb)) (not (= ya yb)) (not (= za zb)) (not (= ta tb))) (let* ((vals (nearest-point xa ya za xb yb zb 0 0 0)) (xi (car vals)) (yi (cadr vals)) (zi (caddr vals))) (if (and (if (< xa xb) (<= xa xi xb) (<= xb xi xa)) (if (< ya yb) (<= ya yi yb) (<= yb yi ya)) (if (< za zb) (<= za zi zb) (<= zb zi za))) (walk-all-rooms xi yi zi (+ tb (* (- ta tb) (/ (distance (- xb xi) (- yb yi) (- zb zi)) (distance (- xb xa) (- yb ya) (- zb za))))) 2 ))))) ;; Check to see if a segment intersects the inner sphere: ;; points inside are rendered differently so we need to ;; create additional envelope points in the boundaries (define (intersects-inside-radius xa ya za ta xb yb zb tb) (let* ((mag (distance (- xb xa) (- yb ya) (- zb za))) (vx (/ (- xb xa) mag)) (vy (/ (- yb ya) mag)) (vz (/ (- zb za) mag)) (bsq (+ (* xa vx) (* ya vy) (* za vz))) (u (- (+ (* xa xa) (* ya ya) (* za za)) (* inside-radius inside-radius))) (disc (- (* bsq bsq) u)) (hit (>= disc 0.0))) (if hit ;; ray defined by two points hits sphere (let* ((root (sqrt disc)) (rin (- (- bsq) root)) (rout (+ (- bsq) root)) (xi #f) (yi #f) (zi #f) (ti #f) (xo #f) (yo #f) (zo #f) (to #f)) (if (> mag rin 0) ;(and (> rin 0) (< rin mag)) ;; intersects entering sphere (begin (set! xi (+ xa (* vx rin))) (set! yi (+ ya (* vy rin))) (set! zi (+ za (* vz rin))) (set! ti (+ tb (* (- ta tb) (/ (distance (- xb xi) (- yb yi) (- zb zi)) (distance (- xb xa) (- yb ya) (- zb za)))))))) (if (and (> rout 0) (< (abs rout) mag)) ;; intersects leaving sphere (begin (set! xo (+ xa (* vx rout))) (set! yo (+ ya (* vy rout))) (set! zo (+ za (* vz rout))) (set! to (+ tb (* (- ta tb) (/ (distance (- xb xo) (- yb yo) (- zb zo)) (distance (- xb xa) (- yb ya) (- zb za)))))))) (if xi (begin (change-direction xa ya za ta xi yi zi ti 1) (if xo (begin (change-direction xi yi zi ti xo yo zo to 2) (change-direction xo yo zo to xb yb zb tb 3)) (change-direction xi yi zi ti xb yb zb tb 4))) (if xo (begin (change-direction xa ya za ta xo yo zo to 5) (change-direction xo yo zo to xb yb zb tb 6)) (change-direction xa ya za ta xb yb zb tb 7)))) (change-direction xa ya za ta xb yb zb tb 8)))) ;; Recursively split segment if longer than minimum rendering distance: ;; otherwise long line segments that have changes in distance render ;; the amplitude envelope as a linear function that does not reflect ;; the chosen power function (1/d^n) (define (fminimum-segment-length xa ya za ta xb yb zb tb) (let ((dist (distance (- xb xa) (- yb ya) (- zb za)))) (if (< dist minimum-segment-length) (intersects-inside-radius xa ya za ta xb yb zb tb) ;; interpolate a new point half way thorugh the segment (let* ((xi (/ (+ xa xb) 2)) (yi (/ (+ ya yb) 2)) (zi (/ (+ za zb) 2)) (ti (+ tb (* (- ta tb) (/ (distance (- xb xi) (- yb yi) (- zb zi)) (distance (- xb xa) (- yb ya) (- zb za))))))) (fminimum-segment-length xa ya za ta xi yi zi ti) (fminimum-segment-length xi yi zi ti xb yb zb tb))))) ;; returns the new duration of a sound after using an envelope for time-varying sampling-rate conversion ;; (from Bill's dsp.scm) (define (src-duration e) (let* ((len (length e)) (ex0 (car e)) (ex1 (e (- len 2))) (all-x (- ex1 ex0)) (dur 0.0)) (do ((i 0 (+ i 2))) ((>= i (- len 2)) dur) (let* ((x0 (e i)) (x1 (e (+ i 2))) (y0 (e (+ i 1))) ; 1/x x points (y1 (e (+ i 3))) (area (if (< (abs (real-part (- y0 y1))) .0001) (/ (- x1 x0) (* y0 all-x)) (* (/ (- (log y1) (log y0)) (- y1 y0)) (/ (- x1 x0) all-x))))) (set! dur (+ dur (abs (real-part area)))))))) ;; Loop for each pair of points in the position envelope and render them (if (= (length xpoints) 1) ;; static source (we should check if this is inside the inner radius?) (walk-all-rooms (car xpoints) (car ypoints) (car zpoints) (car tpoints) 3) ;; moving source (let ((len (- (min (length xpoints) (length ypoints) (length zpoints) (length tpoints)) 1))) (do ((i 0 (+ i 1))) ((>= i len)) (let ((xa (xpoints i)) (ya (ypoints i)) (za (zpoints i)) (ta (tpoints i)) (xb (xpoints (+ i 1))) (yb (ypoints (+ i 1))) (zb (zpoints (+ i 1))) (tb (tpoints (+ i 1)))) (fminimum-segment-length xa ya za ta xb yb zb tb) (if (= i len) (walk-all-rooms xb yb zb tb 4)))))) ;; create delay lines for output channels that need them (if speakers (let* ((delays (speaker-config-delays speakers)) (len (length delays))) (do ((channel 0 (+ 1 channel))) ((= channel len)) (let ((delayo (delays channel))) (set! (out-delays channel) (and (not (= delayo 0.0)) (make-delay (time->samples delayo)))) (set! max-out-delay (max max-out-delay delayo)))))) ;; delay from the minimum distance to the listener (set! min-delay (dist->samples min-dist)) ;; duration of sound at listener's position after doppler src ;; ;; this does not work quite right but the error leads to a longer ;; run with zeroed samples at the end so it should be fine ; (format #t "doppler: ~S~%" doppler) (set! real-dur (* duration (if (null? doppler) 1.0 (src-duration (reverse doppler))))) ;; end of the run according to the duration of the note ;; (set! end (time->samples duration)) ;; start and end of the loop in samples (set! run-beg (time->samples start-time)) (set! run-end (floor (- (+ (time->samples (+ start-time (max duration real-dur))) (dist->samples last-dist) (time->samples max-out-delay)) (if initial-delay 0.0 min-delay)))) ;; sample at which signal first arrives to the listener (set! start (+ run-beg (dist->samples (- first-dist (if initial-delay 0.0 min-dist))))) ;; minimum distance for unity gain calculation (set! min-dist-unity (if (< min-dist inside-radius) inside-radius min-dist)) ;; unity-gain gain scalers (set! unity-gain (* scaler (if (number? unity-gain-dist) (expt unity-gain-dist direct-power) (if (not unity-gain-dist) (expt min-dist-unity direct-power) 1.0)))) (set! unity-rev-gain (* scaler (if (number? unity-gain-dist) (expt unity-gain-dist reverb-power) (if (not unity-gain-dist) ; defaults to #f above (expt min-dist-unity reverb-power) 1.0)))) ;; unity-gain ambisonics gain scalers (set! amb-unity-gain (* scaler (if (number? unity-gain-dist) (expt unity-gain-dist direct-power) (if (not unity-gain-dist) (expt min-dist-unity direct-power) 1.0)))) (set! amb-unity-rev-gain (* scaler (if (number? unity-gain-dist) (expt unity-gain-dist reverb-power) (if (not unity-gain-dist) ; defaults to #f above (expt min-dist-unity reverb-power) 1.0)))) ;;; XXX hack!! this should be intercepted in the calling code, no 0 duration please... (if (<= real-dur 0.0) (begin (format #t ";;; ERROR: resetting real duration to 0.1 (was ~A)~%" real-dur) (set! real-dur 0.1))) (list (make-move-sound (list ;; :start start ;; :end (time->samples (+ start-time (max duration real-dur))) ;; :out-channels (if speakers (speaker-config-number speakers) out-channels) ;; :rev-channels rev-channels ;; :path (make-delay delay-hack :max-size (max 1 (+ (ceiling (dist->samples max-dist)) delay-hack))) ;; :delay (make-env (reverse dly) :offset (if initial-delay 0.0 (- min-delay)) :duration real-dur) ;; :rev (make-env (if (number? reverb-amount) ; as opposed to an envelope I guess (list 0 reverb-amount 1 reverb-amount) reverb-amount) :duration real-dur) ;; :out-delays out-delays ;; :gains (let ((v (make-vector out-channels))) (do ((i 0 (+ i 1))) ((= i out-channels)) (set! (v i) (make-env (reverse (channel-gains i)) :scaler (if (= render-using ambisonics) amb-unity-gain unity-gain) :duration real-dur))) v) ;; :rev-gains (if (> rev-channels 0) (let ((v (make-vector rev-channels))) (do ((i 0 (+ i 1))) ((= i rev-channels)) (set! (v i) (make-env (reverse (channel-rev-gains i)) :scaler (if (= render-using ambisonics) amb-unity-rev-gain unity-rev-gain) :duration real-dur))) v) #f) ;; :out-map (if speakers (speaker-config-map speakers) (let ((v (make-vector out-channels))) (do ((i 0 (+ i 1))) ((= i out-channels)) (set! (v i) i)) v))) *output* *reverb*) ;; return start and end samples for the run loop run-beg run-end))) ;(with-sound(:channels 6 :play #f :statistics #t) (sinewave 0 10 440 0.5 :path (make-path '((-10 10) (0.5 0.5) (10 10)) :error 0.001))) ; ;(with-sound(:statistics #t :channels 4 :reverb-channels 4 :reverb freeverb :decay-time 3) ; (move 0 "/usr/ccrma/snd/nando/sounds/kitchen/bowl/small-medium-large-1.snd" ; :paths (list (make-spiral-path :start-angle 0 :turns 2.5) ; (make-spiral-path :start-angle 180 :turns 3.5)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Run macro to localize samples ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (define dlocsig move-sound) #| ;(define hi (make-path '((-10 10) (0.5 0.5) (10 10)) :3d #f :error 0.001)) ;(make-dlocsig 0 1.0 :out-channels 2 :rev-channels 0 :path (make-path '((-10 10) (0.5 0.5) (10 10)) :3d #f)) (if (provided? 'snd) (require snd-ws.scm) (require sndlib-ws.scm)) (define* (sinewave start-time duration freq amp (amp-env '(0 1 1 1)) (path (make-path :path '(-10 10 0 5 10 10)))) (let* ((vals (make-dlocsig :start-time start-time :duration duration :path path)) (dloc (car vals)) (beg (cadr vals)) (end (caddr vals))) (let ((osc (make-oscil :frequency freq)) (aenv (make-env :envelope amp-env :scaler amp :duration duration))) (do ((i beg (+ i 1))) ((= i end)) (dlocsig dloc i (* (env aenv) (oscil osc))))))) (with-sound (:channels 2) (sinewave 0 1.0 440 .5 :path (make-path '((-10 10) (0.5 0.5) (10 10)) :3d #f))) |# snd-16.1/effects-utils.scm0000644000076400007640000002645612514442507013635 0ustar bilbil(provide 'snd-effects-utils.scm) (require snd-motif) (with-let *motif* (define raise-dialog (let ((documentation "(raise-dialog w) tries to put 'w' on top of any widgets that are obscuring it")) (lambda (w) (if (and (Widget? w) (XtIsManaged w)) (let ((parent (XtParent w))) (if (and (Widget? parent) (XtIsSubclass parent xmDialogShellWidgetClass)) (XtPopup parent XtGrabNone))))))) (define activate-dialog (let ((documentation "(activate-dialog dialog) makes 'dialog' active and brings it to the top of the currently displayed widgets")) (lambda (dialog) (if (not (XtIsManaged dialog)) (XtManageChild dialog) (raise-dialog dialog))))) (define for-each-child (let ((documentation "(for-each-child w func) applies 'func' to 'w' and to its descendents")) (lambda (w func) (func w) (if (XtIsComposite w) (for-each (lambda (n) (for-each-child n func)) (cadr (XtGetValues w (list XmNchildren 0) 1))))))) (define use-combo-box-for-fft-size #f) ; cross-synthesis fft size: radio-buttons or combo-box choice (define current-screen (let ((documentation "(current-screen) returns the current X screen number of the current display")) (lambda () (DefaultScreenOfDisplay (XtDisplay (cadr (main-widgets))))))) (if (not (defined? 'all-chans)) (define all-chans (let ((documentation "(all-chans) returns a list of all current sound objects and channel numbers")) (lambda () (let ((sndlist ()) (chnlist ())) (for-each (lambda (snd) (do ((i (- (channels snd) 1) (- i 1))) ((< i 0)) (set! sndlist (cons snd sndlist)) (set! chnlist (cons i chnlist)))) (sounds)) (list sndlist chnlist)))))) (define update-label (let ((documentation "(update-label effects) evaluates the elements of the list 'effects'")) (lambda (effects) (if (pair? effects) (begin ((car effects)) (update-label (cdr effects))))))) (define effect-target-ok (let ((documentation "(effect-target-ok target) returns #t if the current effect's chosen target is ready")) (lambda (target) (if (eq? target 'sound) (pair? (sounds)) (if (eq? target 'selection) (selection?) (and (selected-sound) (>= (length (marks (selected-sound) (selected-channel))) 2))))))) (define make-effect-dialog (let ((documentation "(make-effect-dialog label ok-callback help-callback reset-callback target-ok-callback) makes a standard effects dialog")) (lambda* (label ok-callback help-callback reset-callback target-ok-callback) ;; make a standard dialog (let* ((xdismiss (XmStringCreate "Go Away" XmFONTLIST_DEFAULT_TAG)) (xhelp (XmStringCreate "Help" XmFONTLIST_DEFAULT_TAG)) (xok (XmStringCreate "DoIt" XmFONTLIST_DEFAULT_TAG)) (titlestr (XmStringCreate label XmFONTLIST_DEFAULT_TAG)) (new-dialog (XmCreateTemplateDialog (cadr (main-widgets)) label (list XmNcancelLabelString xdismiss XmNhelpLabelString xhelp XmNokLabelString xok XmNautoUnmanage #f XmNdialogTitle titlestr XmNresizePolicy XmRESIZE_GROW XmNnoResize #f XmNbackground *basic-color* XmNtransient #f)))) (for-each (lambda (button color) (XtVaSetValues (XmMessageBoxGetChild new-dialog button) (list XmNarmColor *selection-color* XmNbackground color))) (list XmDIALOG_HELP_BUTTON XmDIALOG_CANCEL_BUTTON XmDIALOG_OK_BUTTON) (list *highlight-color* *highlight-color* *highlight-color*)) (XtAddCallback new-dialog XmNcancelCallback (lambda (w c i) (XtUnmanageChild new-dialog))) (XtAddCallback new-dialog XmNhelpCallback help-callback) ; "Help" (XtAddCallback new-dialog XmNokCallback ok-callback) ; "DoIt" (if reset-callback ;; add a Reset button (let ((reset-button (XtCreateManagedWidget "Reset" xmPushButtonWidgetClass new-dialog (list XmNbackground *highlight-color* XmNforeground (BlackPixelOfScreen (current-screen)) XmNarmColor *selection-color*)))) (XtAddCallback reset-button XmNactivateCallback reset-callback))) (XmStringFree xhelp) (XmStringFree xok) (XmStringFree xdismiss) (XmStringFree titlestr) (if target-ok-callback (begin (XtSetSensitive (XmMessageBoxGetChild new-dialog XmDIALOG_OK_BUTTON) (target-ok-callback)) (hook-push effects-hook (lambda (hook) (XtSetSensitive (XmMessageBoxGetChild new-dialog XmDIALOG_OK_BUTTON) (target-ok-callback))))) (begin (XtSetSensitive (XmMessageBoxGetChild new-dialog XmDIALOG_OK_BUTTON) (pair? (sounds))) (hook-push effects-hook (lambda (hook) (XtSetSensitive (XmMessageBoxGetChild new-dialog XmDIALOG_OK_BUTTON) (pair? (sounds))))))) new-dialog)))) ;;; replacement for change-menu-label (define change-label (let ((documentation "(change-label widget new-label) changes the label of 'widget' to be 'new-label'")) (lambda (widget new-label) (let ((str (XmStringCreateLocalized new-label))) (XtSetValues widget (list XmNlabelString str)) (XmStringFree str))))) ;;; -------- log scaler widget (define log-scale-ticks 500) ; sets precision (to some extent) of slider (define scale-log->linear (let ((documentation "(scale-log->linear lo val hi) given user-relative low..val..hi returns val as scale-relative (0..log-scale-ticks)")) (lambda (lo val hi) (let ((log-lo (log (max lo 1.0) 2)) (log-hi (log hi 2)) (log-val (log val 2))) (floor (* log-scale-ticks (/ (- log-val log-lo) (- log-hi log-lo)))))))) (define scale-linear->log (let ((documentation "(scale-linear->log lo val hi) given user-relative lo..hi and scale-relative val, returns the user-relative val")) (lambda (lo val hi) ;; since log-scale widget assumes 0..log-scale-ticks, val can be used as ratio (log-wise) between lo and hi (let* ((log-lo (log (max lo 1.0) 2)) (log-hi (log hi 2)) (log-val (+ log-lo (* (/ val log-scale-ticks) (- log-hi log-lo))))) (expt 2.0 log-val))))) (define scale-log-label (let ((documentation "(scale-log-label lo val hi) makes a log scale label")) (lambda (lo val hi) (format #f "~,2F" (scale-linear->log lo val hi))))) (define create-log-scale-widget (let ((documentation "(create-log-scale-widget parent title low initial high callback scale) returns a log scale widget")) (lambda (parent title low initial high callback scale) (let ((label (XtCreateManagedWidget (format #f "~,2F" initial) xmLabelWidgetClass parent (list XmNbackground *basic-color*))) (scale (XtCreateManagedWidget "scale" xmScaleWidgetClass parent (list XmNorientation XmHORIZONTAL XmNshowValue #f XmNminimum 0 XmNmaximum log-scale-ticks XmNvalue (floor (scale-log->linear low initial high)) XmNdecimalPoints 0 XmNtitleString title XmNbackground *basic-color*)))) (XtAddCallback scale XmNvalueChangedCallback (lambda (widget context info) (change-label label (scale-log-label low (.value info) high)))) (XtAddCallback scale XmNdragCallback (lambda (widget context info) (change-label label (scale-log-label low (.value info) high)))) scale)))) ;;; -------- semitone scaler widget ;;; ;;; set up like log scale (use 'semi in place of 'log), ;;; to get the ratio from the semitones, use (expt 2.0 (/ value 12.0)) -- semitones->ratio below (define semi-range 24) ; 2 octaves either way (define semi-scale-label (let ((documentation "(semi-scale-label val) makes a semitone label")) (lambda (val) (format #f "semitones: ~D" (- val semi-range))))) (define semitones->ratio (let ((documentation "(semitones->ratio val) takes a semitone number 'val' and returns the corresponding float ratio")) (lambda (val) (expt 2.0 (/ val 12.0))))) (define ratio->semitones (let ((documentation "(ratio->semitones ratio) takes a float ratio and returns the corresponding number of semitones")) (lambda (ratio) (round (* 12 (log ratio 2)))))) (define create-semi-scale-widget (let ((documentation "(create-semi-scale-widget parent title initial callback) returns a semitone scale widget")) (lambda (parent title initial callback) (let ((label (XtCreateManagedWidget (format #f "semitones: ~D" (ratio->semitones initial)) xmLabelWidgetClass parent (list XmNbackground *basic-color*))) (scale (XtCreateManagedWidget "scale" xmScaleWidgetClass parent (list XmNorientation XmHORIZONTAL XmNshowValue #f XmNminimum 0 XmNmaximum (* 2 semi-range) XmNvalue (+ semi-range (ratio->semitones initial)) XmNdecimalPoints 0 XmNtitleString title XmNbackground *basic-color*)))) (XtAddCallback scale XmNvalueChangedCallback (lambda (widget context info) (change-label label (semi-scale-label (.value info))))) (XtAddCallback scale XmNdragCallback (lambda (widget context info) (change-label label (semi-scale-label (.value info))))) scale)))) (define add-sliders (let ((documentation "(add-sliders dialog sliders) takes 'sliders', a list of lists, each inner list being (title low initial high callback scale ['log]) \ and returns a list of widgets (for reset callbacks)")) (lambda* (dialog sliders) (let* ((mainfrm (XtCreateManagedWidget "formd" xmFormWidgetClass dialog (list XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_WIDGET XmNbottomWidget (XmMessageBoxGetChild dialog XmDIALOG_SEPARATOR) XmNbackground *highlight-color*))) (mainform (XtCreateManagedWidget "formd" xmRowColumnWidgetClass mainfrm (list XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNbackground *highlight-color* XmNorientation XmVERTICAL)))) (map (lambda (slider-data) (let* ((title (XmStringCreate (slider-data 0) XmFONTLIST_DEFAULT_TAG)) (low (slider-data 1)) (initial (slider-data 2)) (high (slider-data 3)) (func (slider-data 4)) (scale (slider-data 5)) (new-slider (if (= (length slider-data) 7) (if (eq? (slider-data 6) 'log) (create-log-scale-widget mainform title low initial high func scale) (create-semi-scale-widget mainform title initial func)) (XtCreateManagedWidget (car slider-data) xmScaleWidgetClass mainform (list XmNorientation XmHORIZONTAL XmNshowValue #t XmNminimum (floor (* low scale)) XmNmaximum (floor (* high scale)) XmNvalue (floor (* initial scale)) XmNdecimalPoints (if (= scale 10000) 4 (if (= scale 1000) 3 (if (= scale 100) 2 (if (= scale 10) 1 0)))) XmNtitleString title XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNbackground *basic-color*))))) (XmStringFree title) (XtAddCallback new-slider XmNvalueChangedCallback func) new-slider)) sliders))))) ) snd-16.1/snd-test.scm0000644000076400007640001106762112625572117012626 0ustar bilbil;;; Snd tests ;;; ;;; test 0: constants [554] ;;; test 1: defaults [1226] ;;; test 2: headers [1596] ;;; test 3: variables [1911] ;;; test 4: sndlib [2475] ;;; test 5: simple overall checks [4490] ;;; test 6: float-vectors [9242] ;;; test 7: colors [9513] ;;; test 8: clm [10032] ;;; test 9: mix [22115] ;;; test 10: marks [23894] ;;; test 11: dialogs [24832] ;;; test 12: extensions [25005] ;;; test 13: menus, edit lists, hooks, etc [25271] ;;; test 14: all together now [26604] ;;; test 15: chan-local vars [27487] ;;; test 16: regularized funcs [29224] ;;; test 17: dialogs and graphics [32973] ;;; test 18: save and restore [33085] ;;; test 19: transforms [34737] ;;; test 20: new stuff [36837] ;;; test 21: optimizer [38030] ;;; test 22: with-sound [40924] ;;; test 23: X/Xt/Xm [43909] ;;; test 24: GL [47583] ;;; test 25: errors [47706] ;;; test 26: s7 [49224] ;;; test all done [49295] ;;; test the end [49477] ;;; (set! (hook-functions *load-hook*) (list (lambda (hook) (format *stderr* "loading ~S...~%" (hook 'name))))) ;(set! (*s7* 'gc-stats) 6) (when (provided? 'pure-s7) (define (make-polar mag ang) (if (and (real? mag) (real? ang)) (complex (* mag (cos ang)) (* mag (sin ang))) (error 'wrong-type-arg "make-polar args should be real"))) (define (memq a b) (member a b eq?)) (define (memv a b) (member a b eqv?))) (define tests 1) (define keep-going #f) (define all-args #f) (define test-at-random 0) (if (<= tests 0) (set! tests 1)) #| (set! *#readers* (cons (cons #\_ (lambda (str) (if (string=? str "__line__") (port-line-number) #f))) *#readers*)) |# (set! *#readers* (cons (cons #\_ _snd-line-reader_) *#readers*)) (define (copy-file source dest) (system (string-append "cp " source " " dest))) (define-expansion (fill-float-vector v body) `(let ((len (length ,v))) (do ((i 0 (+ i 1))) ((= i len) ,v) (float-vector-set! ,v i ,body)))) (define-expansion (outa->fv v body) `(let ((len (length ,v))) (set! *output* ,v) (do ((i 0 (+ i 1))) ((= i len) (set! *output* #f) ,v) (outa i ,body)))) (define* (cfft! data n (dir 1)) (if (not n) (set! n (length data))) (let ((t0 (complex 0.0 (* pi dir)))) (do ((i 0 (+ i 1)) (j 0)) ((= i n)) (if (> j i) (let ((temp (data j))) (set! (data j) (data i)) (set! (data i) temp))) (let ((m (/ n 2))) (do () ((or (< m 2) (< j m))) (set! j (- j m)) (set! m (/ m 2))) (set! j (+ j m)))) (let ((ipow (floor (log n 2))) (prev 1)) (do ((lg 0 (+ lg 1)) (mmax 2 (* mmax 2)) (pow (/ n 2) (/ pow 2)) (theta t0 (* theta 0.5))) ((= lg ipow)) (let ((wpc (exp theta)) (wc 1.0)) (do ((ii 0 (+ ii 1))) ((= ii prev)) (do ((jj 0 (+ jj 1)) (i ii (+ i mmax)) (j (+ ii prev) (+ j mmax))) ((>= jj pow)) (let ((tc (* wc (data j)))) (set! (data j) (- (data i) tc)) (set! (data i) (+ (data i) tc)))) (set! wc (* wc wpc))) (set! prev mmax)))) data)) (define* (fft! rl im n (dir 1)) (if (not im) (set! im (make-float-vector (length rl)))) (if (not n) (set! n (length rl))) (do ((i 0 (+ i 1)) (j 0)) ((= i n)) (if (> j i) (let ((tempr (rl j)) (tempi (im j))) (set! (rl j) (rl i)) (set! (im j) (im i)) (set! (rl i) tempr) (set! (im i) tempi))) (let ((m (/ n 2))) (do () ((or (< m 2) (< j m))) (set! j (- j m)) (set! m (/ m 2))) (set! j (+ j m)))) (let ((ipow (floor (log n 2))) (prev 1)) (do ((lg 0 (+ lg 1)) (mmax 2 (* mmax 2)) (pow (/ n 2) (/ pow 2)) (theta (* pi dir) (* theta 0.5))) ((= lg ipow)) (let ((wpr (cos theta)) (wpi (sin theta)) (wr 1.0) (wi 0.0)) (do ((ii 0 (+ ii 1))) ((= ii prev)) (do ((jj 0 (+ jj 1)) (i ii (+ i mmax)) (j (+ ii prev) (+ j mmax))) ((>= jj pow)) (let ((tempr (- (* wr (rl j)) (* wi (im j)))) (tempi (+ (* wr (im j)) (* wi (rl j))))) (set! (rl j) (- (rl i) tempr)) (set! (im j) (- (im i) tempi)) (set! (rl i) (+ (rl i) tempr)) (set! (im i) (+ (im i) tempi)))) (let ((wtemp wr)) (set! wr (- (* wr wpr) (* wi wpi))) (set! wi (+ (* wi wpr) (* wtemp wpi))))) (set! prev mmax)))) rl) (if (not (defined? 'snd-test)) (define snd-test -1)) (define full-test (< snd-test 0)) (define total-tests 26) (if (not (defined? 'with-exit)) (define with-exit (< snd-test 0))) (define s7test-exits #f) (define test-number -1) (define-constant (snd-display line . args) (let ((str (if (null? (cdr args)) (car args) (if (or (string? (car args)) (and (not (car args)) (string? (cadr args)))) (apply format #f args) (object->string args))))) (format *stderr* "~%~A: ~8T~A" line str) (if (not (provided? 'snd-nogui)) (snd-print (format #f "~%~A: ~A" line str))))) (define with-big-file #f) (define big-file-name "/home/bil/zap/sounds/bigger.snd") (if with-big-file (begin (set! with-big-file (file-exists? big-file-name)) (if (not with-big-file) (snd-display #__line__ ";no big file")))) (define big-file-framples 0) (define original-save-dir (or *save-dir* "~/zap/snd")) (define original-temp-dir (or *temp-dir* "~/zap/tmp")) (define original-sound-file-extensions (sound-file-extensions)) (unbind-key #\c 4 #t) ;;; clear out old junk! (if (file-exists? original-save-dir) (system (format #f "rm ~A/snd_*" original-save-dir))) (if (file-exists? original-temp-dir) (system (format #f "rm ~A/snd_*" original-temp-dir))) (if (file-exists? "/tmp") (begin ; -noinit possibly (system "rm /tmp/snd_*") (system "rm /tmp/*.snd"))) (if (file-exists? "/var/tmp") (begin ; -noinit possibly (system "rm /var/tmp/snd_*") (system "rm /var/tmp/*.snd"))) (system "rm core*") (define home-dir (getenv "HOME")) (define sf-dir "/sf1") (if (not (file-exists? (string-append home-dir "/cl/oboe.snd"))) (if (file-exists? "/export/home/bil/cl/oboe.snd") (set! home-dir "/export/home/bil") (if (file-exists? "/Users/bil/cl/oboe.snd") (set! home-dir "/Users/bil") (if (file-exists? "/users/b/bil/cl/oboe.snd") (set! home-dir "/users/b/bil") (if (file-exists? "/usr/home/bil/cl/oboe.snd") (set! home-dir "/usr/home/bil")))))) (define cwd (string-append (getcwd) "/")) (define sf-dir1 (string-append home-dir sf-dir "/")) (if (not (file-exists? (string-append sf-dir1 "alaw.wav"))) (begin (set! sf-dir "/sf") (set! sf-dir1 (string-append home-dir sf-dir "/")) (if (not (file-exists? (string-append sf-dir1 "alaw.wav"))) (begin (snd-display #__line__ ";;;can't find sf directory!") (set! sf-dir1 #f))))) (set! sf-dir sf-dir1) (if (not (string=? (getcwd) (string-append home-dir "/cl"))) (for-each (lambda (file) (if (not (file-exists? file)) (begin (format #t "copying ~A~%" file) (copy-file (string-append home-dir "/cl/" file) (string-append (getcwd) "/" file))))) (list "4.aiff" "2.snd" "obtest.snd" "oboe.snd" "pistol.snd" "1a.snd" "now.snd" "fyow.snd" "storm.snd" "z.snd" "1.snd" "cardinal.snd" "now.snd.scm" "2a.snd" "4a.snd" "zero.snd" "loop.scm" "cmn-glyphs.lisp" "bullet.xpm" "mb.snd" "funcs.scm" "trumpet.snd" "1234.snd"))) (for-each mus-sound-preload (list "4.aiff" "2.snd" "obtest.snd" "oboe.snd" "pistol.snd" "1a.snd" "now.snd" "fyow.snd" "storm.snd" "1.snd" "cardinal.snd" "2a.snd")) ;;(setlocale LC_ALL "de_DE") (set! *with-background-processes* #f) ;; try to get a different random number sequence on each run (set! (mus-rand-seed) (current-time)) (set! (hook-functions bad-header-hook) ()) (hook-push bad-header-hook (lambda (hook) (set! (hook 'result) #t))) (define with-motif (provided? 'snd-motif)) (define with-gui (or (provided? 'snd-gtk) (provided? 'snd-motif))) (if (not with-gui) (define y-bounds (dilambda (lambda args (list -1.0 1.0)) (lambda args (list -1.0 1.0))))) (if (not with-gui) (define x-bounds (dilambda (lambda args (list 0.0 0.1)) (lambda args (list 0.0 0.1))))) (define real-time get-internal-real-time) (define (hundred n) (round (* 100 n))) (define times ()) (define-macro (time a) `(let ((start (real-time))) ,a (let ((val (hundred (- (real-time) start)))) (set! times (cons (list ',a val) times))))) (define original-prompt *listener-prompt*) (set! (show-listener) #t) (set! (window-x) 600) (set! (window-y) 10) (define-expansion (fneq a b) `(> (magnitude (- ,a ,b)) .001)) (define-expansion (ffneq a b) `(> (magnitude (- ,a ,b)) .01)) (define-expansion (fffneq a b) `(> (magnitude (- ,a ,b)) .1)) (define (cneq a b) (> (magnitude (- a b)) .001)) (define-constant (feql a b) (let ((old-eps (*s7* 'morally-equal-float-epsilon))) (set! (*s7* 'morally-equal-float-epsilon) .001) (let ((res (morally-equal? a b))) (set! (*s7* 'morally-equal-float-epsilon) old-eps) res))) (define-constant (ffeql a b) (let ((old-eps (*s7* 'morally-equal-float-epsilon))) (set! (*s7* 'morally-equal-float-epsilon) .1) (let ((res (morally-equal? a b))) (set! (*s7* 'morally-equal-float-epsilon) old-eps) res))) (define-constant (fveql a b i) (or (null? b) (and (not (fneq (car b) (a i))) (fveql a (cdr b) (+ i 1))))) (define* (mus-arrays-equal? x y (err .001)) (let ((old-eps (*s7* 'morally-equal-float-epsilon))) (set! (*s7* 'morally-equal-float-epsilon) err) (let ((res (morally-equal? x y))) (set! (*s7* 'morally-equal-float-epsilon) old-eps) res))) (define-constant sd-equal mus-arrays-equal?) (define-constant vequal mus-arrays-equal?) (define (vequal1 v0 v1) (mus-arrays-equal? v0 v1 .01)) (define (vvequal v0 v1) (mus-arrays-equal? v0 v1 .00002)) (define (vmaxdiff v0 v1) (float-vector-peak (float-vector-subtract! (copy v0) v1))) (define (within-.01? a b) (< (abs (- a b)) .01)) (define-constant (string-=? a b) ;(format *stderr* "str: ~A ~A~%" a b) (or (string=? a b) (and (or (char-position #\- a) (char-position #\- b)) (let ((alen (length a)) (blen (length b)) (j 0) (happy #t)) (do ((i 0 (+ i 1))) ((or (not happy) (= i alen)) (and happy (= j blen))) (let ((ac (a i)) (bc (b j))) (if (char=? ac bc) (set! j (+ j 1)) (if (not (and (char=? ac #\-) (<= i (- alen 7)) (string=? (substring a i (+ i 6)) "-0.000"))) (if (and (char=? bc #\-) (<= j (- blen 7)) (string=? (substring b j (+ j 6)) "-0.000")) (begin (set! j (+ j 1)) (if (not (char=? ac (b j))) (set! happy #f) (set! j (+ j 1)))) (set! happy #f)))))))))) (define dismiss-all-dialogs (let ((documentation "(dismiss-all-dialogs) hides all dialogs")) (lambda () (if (or (provided? 'xm) (provided? 'xg)) (for-each (lambda (dialog) (if dialog (if (symbol? (car dialog)) (if (provided? 'snd-motif) (if ((*motif* 'XtIsManaged) dialog) ((*motif* 'XtUnmanageChild) dialog)) (if (provided? 'snd-gtk) ((*gtk* 'gtk_widget_hide) dialog))) (for-each (lambda (d) (if (symbol? (car d)) (if (provided? 'snd-motif) (if ((*motif* 'XtIsManaged) d) ((*motif* 'XtUnmanageChild) d)) (if (provided? 'snd-gtk) ((*gtk* 'gtk_widget_hide) d))))) dialog)))) (dialog-widgets)))))) (define safe-color (make-color 1 0 0)) (define make-color-with-catch (let ((documentation "make-color but catch 'no-such-color")) (lambda (c1 c2 c3) (catch 'no-such-color (lambda () (make-color c1 c2 c3)) (lambda args safe-color))))) (define safe-display-edits (let ((documentation "display-edits but catch all errors")) (lambda* (snd chn edpos) (catch #t (lambda () (display-edits snd chn edpos)) (lambda args (snd-display #__line__ ";display-edits error: ~A" args)))))) (define (safe-divide a b) (if (zero? b) a (/ a b))) (define timings (make-vector (+ total-tests 1) 0)) (define default-srate *clm-srate*) (snd-display #__line__ ";;~A" (snd-version)) (if (not (defined? 'before-test-hook)) (define before-test-hook (make-hook 'n))) (if (not (defined? 'after-test-hook)) (define after-test-hook (make-hook 'n))) (set! (hook-functions before-test-hook) ()) (hook-push before-test-hook (lambda (hook) (let ((n (hook 'n))) (set! *clm-srate* default-srate) (dismiss-all-dialogs) (set! *clipping* #f) (set! (mus-clipping) #f) ; this cost me a morning of confusion! (set! test-number n) (set! (timings n) (real-time)) (snd-display #__line__ ";test ~D" n) ))) (define (clear-save-state-files) (for-each forget-region (regions)) (system (format #f "rm -f ~A/snd_*" (or *save-dir* original-save-dir))) (if (file-exists? "/var/tmp") (system "rm -f /var/tmp/snd_save_*")) (if (file-exists? "/tmp") (system "rm -f /tmp/snd_save_*")) (mus-sound-prune)) (set! (hook-functions after-test-hook) ()) (hook-push after-test-hook (lambda (hook) (let ((n (hook 'n))) (clear-save-state-files) (clear-listener) (set! *ask-about-unsaved-edits* #f) (if (pair? (sounds)) (begin (snd-display #__line__ ";end test ~D: open sounds: ~A" n (map short-file-name (sounds))) (for-each close-sound (sounds)))) (if (number? (vector-ref timings n)) (set! (timings n) (hundred (- (real-time) (vector-ref timings n)))))))) (define overall-start-time (real-time)) (snd-display #__line__ ";~A~%" (strftime "%d-%b %H:%M %Z" (localtime (current-time)))) (define (log-mem tst) (if (> tests 1) (snd-display #__line__ ";test ~D:~D " test-number (+ 1 tst)))) (define-macro (without-errors func) `(catch #t ; but this also squelches syntax errors! (lambda () ,func) (lambda args (car args)))) (require snd-hooks.scm snd-ws.scm) (define (set-arity-ok func args) (let ((arit (if (dilambda? func) (arity (procedure-setter func)) (and (procedure? (procedure-setter func)) (arity (procedure-setter func)))))) (and (pair? arit) (>= args (car arit)) (<= args (cdr arit))))) (define* (scale-sound-by scl beg dur snd chn edpos) (if (integer? chn) (scale-channel scl beg dur snd chn edpos) (do ((i 0 (+ i 1))) ((= i (channels snd))) (scale-channel scl beg dur snd i)))) (define* (scale-sound-to norm beg dur snd chn) (if (integer? chn) (let ((mx (maxamp snd chn))) (if (and (not (= mx 0.0)) (not (= mx norm))) (scale-channel (/ norm mx) beg dur snd chn))) (let ((mx (apply max (maxamp snd #t)))) (if (and (not (= mx 0.0)) (not (= mx norm))) (do ((i 0 (+ i 1))) ((= i (channels snd))) (scale-channel (/ norm mx) beg dur snd i)))))) (define (file->floats file) (samples 0 (framples file) file)) (define* (floats->file v file (srate 22050) (comment "")) (if (float-vector? v) (begin (array->file file v (length v) srate 1) file) (error 'wrong-type-arg "file->floats: ~A" v))) (if (and (> (length (script-args)) 0) (> (script-arg) 0)) (let ((arg (script-arg)) (args (script-args))) (if (not (string=? (args (- arg 1)) "-l")) (snd-display #__line__ ";script-args[~A]: ~A (~A)?" (- arg 1) (args (- arg 1)) args)) (if (not (string=? (args arg) "snd-test")) (snd-display #__line__ ";script-args[~A]: ~A (~A)?" arg (args arg) args)) (if (> (length args) (+ 1 arg)) (begin ;; test-number tests (set! snd-test (string->number (args (+ 1 arg)))) (set! test-at-random 0) (set! full-test (< snd-test 0)) (set! with-exit #t) (set! (script-arg) (+ 1 arg)) (if (> (length (script-args)) (+ arg 2)) (begin (set! tests (string->number (args (+ arg 2)))) (set! (script-arg) (+ arg 2)))))))) (if (and (provided? 'snd-motif) (provided? 'xm)) (require snd-snd-motif.scm) (if (and (provided? 'snd-gtk) (provided? 'xg)) (require snd-snd-gtk.scm))) (define default-file-buffer-size *clm-file-buffer-size*) ;(set! *clm-file-buffer-size* default-file-buffer-size) (if (not (defined? 'pi)) (snd-display #__line__ ";pi is not defined!") (if (fneq pi 3.14159) (snd-display #__line__ ";pi is ~A" pi))) ;;; ---------------- test 0: constants ---------------- (define (snd_test_0) (letrec ((test-constants (lambda (lst) (if (pair? lst) (begin (if (not (= (cadr lst) (caddr lst))) (snd-display #__line__ ";~A is not ~A (~A)~%" (car lst) (cadr lst) (caddr lst))) (test-constants (cdddr lst))))))) (if (or (pair? (sounds)) (pair? (mixes)) (pair? (marks)) (pair? (regions))) (snd-display #__line__ ";start up: ~A ~A ~A ~A" (sounds) (mixes) (marks) (regions))) (test-constants (list 'enved-amplitude enved-amplitude 0 'bartlett-window bartlett-window 4 'bartlett-hann-window bartlett-hann-window 21 'blackman2-window blackman2-window 6 'blackman3-window blackman3-window 7 'blackman4-window blackman4-window 8 'blackman5-window blackman5-window 24 'blackman6-window blackman6-window 25 'blackman7-window blackman7-window 26 'blackman8-window blackman8-window 27 'blackman9-window blackman9-window 28 'blackman10-window blackman10-window 29 'bohman-window bohman-window 22 'cauchy-window cauchy-window 12 'mlt-sine-window mlt-sine-window 33 'papoulis-window papoulis-window 34 'dpss-window dpss-window 35 'sinc-window sinc-window 36 'channels-combined channels-combined 1 'channels-separate channels-separate 0 'channels-superimposed channels-superimposed 2 'connes-window connes-window 18 'cursor-in-middle cursor-in-middle 3 'cursor-in-view cursor-in-view 0 'cursor-on-left cursor-on-left 1 'cursor-on-right cursor-on-right 2 'dolph-chebyshev-window dolph-chebyshev-window 16 'exponential-window exponential-window 9 'flat-top-window flat-top-window 23 'sync-none sync-none 0 'sync-all sync-all 1 'sync-by-sound sync-by-sound 2 'zoom-focus-active zoom-focus-active 2 'zoom-focus-left zoom-focus-left 0 'zoom-focus-middle zoom-focus-middle 3 'zoom-focus-right zoom-focus-right 1 'gaussian-window gaussian-window 14 'graph-dots graph-dots 1 'graph-dots-and-lines graph-dots-and-lines 3 'graph-filled graph-filled 2 'graph-lines graph-lines 0 'graph-lollipops graph-lollipops 4 'hamming-window hamming-window 5 'hann-window hann-window 1 'hann-poisson-window hann-poisson-window 17 'kaiser-window kaiser-window 11 'keyboard-no-action keyboard-no-action 4 'graph-once graph-once 0 'parzen-window parzen-window 3 'poisson-window poisson-window 13 'rectangular-window rectangular-window 0 'riemann-window riemann-window 10 'rv2-window rv2-window 30 'rv3-window rv3-window 31 'rv4-window rv4-window 32 'samaraki-window samaraki-window 19 'ultraspherical-window ultraspherical-window 20 'graph-as-sonogram graph-as-sonogram 1 'graph-as-spectrogram graph-as-spectrogram 2 'graph-once graph-once 0 'graph-as-wavogram graph-as-wavogram 3 'enved-spectrum enved-spectrum 1 'speed-control-as-float speed-control-as-float 0 'speed-control-as-ratio speed-control-as-ratio 1 'speed-control-as-semitone speed-control-as-semitone 2 'enved-srate enved-srate 2 'tukey-window tukey-window 15 'welch-window welch-window 2 'cursor-cross cursor-cross 0 'cursor-line cursor-line 1 'dont-normalize dont-normalize 0 'envelope-linear envelope-linear 0 'envelope-exponential envelope-exponential 1 'normalize-by-channel normalize-by-channel 1 'normalize-by-sound normalize-by-sound 2 'normalize-globally normalize-globally 3 'x-axis-in-samples x-axis-in-samples 1 'x-axis-in-beats x-axis-in-beats 3 'x-axis-in-measures x-axis-in-measures 4 'x-axis-in-seconds x-axis-in-seconds 0 'x-axis-as-clock x-axis-as-clock 5 'x-axis-as-percentage x-axis-as-percentage 2 'enved-add-point enved-add-point 0 'enved-delete-point enved-delete-point 1 'enved-move-point enved-move-point 2 'time-graph time-graph 0 'transform-graph transform-graph 1 'lisp-graph lisp-graph 2 'copy-context copy-context 0 'cursor-context cursor-context 3 'selection-context selection-context 2 'mark-context mark-context 4 'show-no-axes show-no-axes 0 'show-all-axes show-all-axes 1 'show-x-axis show-x-axis 2 'show-all-axes-unlabelled show-all-axes-unlabelled 3 'show-x-axis-unlabelled show-x-axis-unlabelled 4 'show-bare-x-axis show-bare-x-axis 5 ;; sndlib constants 'mus-unknown-header mus-unknown-header 0 'mus-next mus-next 1 'mus-aifc mus-aifc 2 'mus-riff mus-riff 3 'mus-nist mus-nist 6 'mus-raw mus-raw 12 'mus-ircam mus-ircam 15 'mus-aiff mus-aiff 49 'mus-bicsf mus-bicsf 5 'mus-voc mus-voc 10 'mus-svx mus-svx 9 'mus-soundfont mus-soundfont 26 'mus-rf64 mus-rf64 4 'mus-caff mus-caff 60 'mus-interp-none mus-interp-none 0 'mus-interp-linear mus-interp-linear 1 'mus-interp-sinusoidal mus-interp-sinusoidal 2 'mus-interp-all-pass mus-interp-all-pass 3 'mus-interp-lagrange mus-interp-lagrange 4 'mus-interp-bezier mus-interp-bezier 5 'mus-interp-hermite mus-interp-hermite 6 'mus-chebyshev-first-kind mus-chebyshev-first-kind 1 'mus-chebyshev-second-kind mus-chebyshev-second-kind 2 'mus-unknown-sample mus-unknown-sample 0 'mus-bshort mus-bshort 1 'mus-lshort mus-lshort 10 'mus-mulaw mus-mulaw 2 'mus-alaw mus-alaw 6 'mus-byte mus-byte 3 'mus-ubyte mus-ubyte 7 'mus-bfloat mus-bfloat 4 'mus-lfloat mus-lfloat 12 'mus-bint mus-bint 5 'mus-lint mus-lint 11 'mus-bintn mus-bintn 17 'mus-lintn mus-lintn 18 'mus-b24int mus-b24int 8 'mus-l24int mus-l24int 16 'mus-bdouble mus-bdouble 9 'mus-ldouble mus-ldouble 13 'mus-ubshort mus-ubshort 14 'mus-ulshort mus-ulshort 15 'mus-bfloat-unscaled mus-bfloat-unscaled 19 'mus-lfloat-unscaled mus-lfloat-unscaled 20 'mus-bdouble-unscaled mus-bdouble-unscaled 21 'mus-ldouble-unscaled mus-ldouble-unscaled 22 )) (if (not (equal? *region-graph-style* graph-lines)) (snd-display #__line__ ";region-graph-style set default: ~A" *region-graph-style*)) (if *ask-about-unsaved-edits* (snd-display #__line__ ";ask-about-unsaved-edits set default: ~A" *ask-about-unsaved-edits*)) (if (not (boolean? *show-full-duration*)) (snd-display #__line__ ";show-full-duration set default: ~A" *show-full-duration*)) (if *show-full-range* (snd-display #__line__ ";show-full-range set default: ~A" *show-full-range*)) (if (fneq *initial-beg* 0.0) (snd-display #__line__ ";initial-beg set default: ~A" *initial-beg*)) (if (fneq *initial-dur* 0.1) (snd-display #__line__ ";initial-dur set default: ~A" *initial-dur*)) (if *ask-before-overwrite* (snd-display #__line__ ";ask-before-overwrite set default: ~A" *ask-before-overwrite*)) (if (not *auto-resize*) (snd-display #__line__ ";auto-resize set default: ~A" *auto-resize*)) (if *auto-update* (snd-display #__line__ ";auto-update set default: ~A" *auto-update*)) (if (not (eqv? *channel-style* 1 )) (snd-display #__line__ ";channel-style set default: ~A" *channel-style*)) (if (and (fneq *color-cutoff* 0.003 ) (fneq *color-cutoff* 0.001)) (snd-display #__line__ ";color-cutoff set default: ~A" *color-cutoff*)) (if (not *color-inverted*) (snd-display #__line__ ";color-inverted set default: ~A" *color-inverted*)) (if (fneq *color-scale* 1.0 ) (snd-display #__line__ ";color-scale set default: ~A" *color-scale*)) (if (fneq *auto-update-interval* 60.0 ) (snd-display #__line__ ";auto-update-interval set default: ~A" *auto-update-interval*)) (if (fneq *cursor-update-interval* 0.05 ) (snd-display #__line__ ";cursor-update-interval set default: ~A" *cursor-update-interval*)) (if (not (= *cursor-location-offset* 0)) (snd-display #__line__ ";cursor-location-offset set default: ~A" *cursor-location-offset*)) (if (not *dac-combines-channels*) (snd-display #__line__ ";dac-combines-channels set default: ~A" *dac-combines-channels*)) (if (not (eqv? *dac-size* 256 )) (snd-display #__line__ ";dac-size set default: ~A" *dac-size*)) (if *clipping* (snd-display #__line__ ";clipping set default: ~A" *clipping*)) (if (not (eqv? *default-output-chans* 1 )) (snd-display #__line__ ";default-output-chans set default: ~A" *default-output-chans*)) (if (and (not (equal? *default-output-sample-type* mus-bdouble)) (not (equal? *default-output-sample-type* mus-ldouble))) (snd-display #__line__ ";default-output-sample-type set default: ~A" *default-output-sample-type*)) (if (not (eqv? *default-output-srate* 44100 )) (snd-display #__line__ ";default-output-srate set default: ~A" *default-output-srate*)) (if (not (equal? *default-output-header-type* mus-next)) (snd-display #__line__ ";default-output-header-type set default: ~A" *default-output-header-type*)) (if (not (eqv? *dot-size* 1 )) (snd-display #__line__ ";dot-size set default: ~A" *dot-size*)) (if (not (eqv? *cursor-size* 15 )) (snd-display #__line__ ";cursor-size set default: ~A" *cursor-size*)) (if (not (equal? *cursor-style* cursor-cross )) (snd-display #__line__ ";cursor-style set default: ~A" *cursor-style*)) (if (not (equal? *tracking-cursor-style* cursor-line )) (snd-display #__line__ ";tracking-cursor-style set default: ~A" *tracking-cursor-style*)) (if (fneq *enved-base* 1.0 ) (snd-display #__line__ ";enved-base set default: ~A" *enved-base*)) (if (not (enved-clip?)) (snd-display #__line__ ";enved-clip? set default: ~A" (enved-clip?))) (if (not (enved-filter)) (snd-display #__line__ ";enved-filter set default: ~A" (enved-filter))) (if (not (eqv? *enved-filter-order* 40)) (snd-display #__line__ ";enved-filter-order set default: ~A" *enved-filter-order*)) (if (enved-in-dB) (snd-display #__line__ ";enved-in-dB set default: ~A" (enved-in-dB))) (if (not (equal? *enved-style* envelope-linear )) (snd-display #__line__ ";enved-style set default: ~A" *enved-style*)) (if (fneq *enved-power* 3.0) (snd-display #__line__ ";enved-power set default: ~A" *enved-power*)) (if (not (eqv? *enved-target* 0 )) (snd-display #__line__ ";enved-target set default: ~A" *enved-target*)) (if *enved-wave?* (snd-display #__line__ ";enved-wave? set default: ~A" *enved-wave?*)) (if (and with-gui (pair? (enved-envelope))) (snd-display #__line__ ";enved-envelope set default: ~A" (enved-envelope))) (if (not (equal? *eps-file* "snd.eps" )) (snd-display #__line__ ";eps-file set default: ~A" *eps-file*)) (if (fneq *eps-bottom-margin* 0.0) (snd-display #__line__ ";eps-bottom-margin set default: ~A" *eps-bottom-margin*)) (if (fneq *eps-left-margin* 0.0) (snd-display #__line__ ";eps-left-margin set default: ~A" *eps-left-margin*)) (if (fneq *eps-size* 1.0) (snd-display #__line__ ";eps-size set default: ~A" *eps-size*)) (if (fneq *fft-window-alpha* 0.0 ) (snd-display #__line__ ";fft-window-alpha set default: ~A" *fft-window-alpha*)) (if (fneq *fft-window-beta* 0.0 ) (snd-display #__line__ ";fft-window-beta set default: ~A" *fft-window-beta*)) (if *fft-log-frequency* (snd-display #__line__ ";fft-log-frequency set default: ~A" *fft-log-frequency*)) (if *fft-log-magnitude* (snd-display #__line__ ";fft-log-magnitude set default: ~A" *fft-log-magnitude*)) (if *fft-with-phases* (snd-display #__line__ ";fft-with-phases set default: ~A" *fft-with-phases*)) (if (not (member *transform-size* (list 1024 4096))) (snd-display #__line__ ";transform-size set default: ~A" *transform-size*)) (if (not (equal? *transform-graph-type* graph-once)) (snd-display #__line__ ";transform-graph-type set default: ~A" *transform-graph-type*)) (if (not (eqv? *fft-window* 6 )) (snd-display #__line__ ";fft-window set default: ~A" *fft-window*)) (if (not (eqv? *graph-cursor* 34)) (snd-display #__line__ ";graph-cursor set default: ~A" *graph-cursor*)) (if (not (equal? *graph-style* graph-lines )) (snd-display #__line__ ";graph-style set default: ~A" *graph-style*)) (if (not *graphs-horizontal*) (snd-display #__line__ ";graphs-horizontal set default: ~A" *graphs-horizontal*)) (if (not (equal? *html-dir* ".")) (snd-display #__line__ ";html-dir set default: ~A" *html-dir*)) (if (not (equal? *html-program* "firefox")) (snd-display #__line__ ";html-program set default: ~A" *html-program*)) (if (not *just-sounds*) (snd-display #__line__ ";just-sounds set default: ~A" *just-sounds*)) (if (not (string? *listener-prompt*)) (snd-display #__line__ ";listener-prompt set default: ~A" *listener-prompt*)) (if (not (eqv? *max-transform-peaks* 100)) (snd-display #__line__ ";max-transform-peaks set default: ~A" *max-transform-peaks*)) (if (not (eqv? *max-transform-peaks* 100)) (snd-display #__line__ ";max-transform-peaks set -123: ~A" *max-transform-peaks*)) (if (not (eqv? *max-regions* 16 )) (snd-display #__line__ ";max-regions set default: ~A" *max-regions*)) (if (fneq *min-dB* -60.0 ) (snd-display #__line__ ";min-dB set default: ~A" *min-dB*)) (if (fneq *log-freq-start* 32.0 ) (snd-display #__line__ ";log-freq-start set default: ~A" *log-freq-start*)) (if (not *selection-creates-region*) (snd-display #__line__ ";selection-creates-region set default: ~A" *selection-creates-region*)) (if (not (equal? *transform-normalization* normalize-by-channel)) (snd-display #__line__ ";transform-normalization set default: ~A" *transform-normalization*)) (if (and with-motif (not (eqv? (view-files-sort) 0 ))) (snd-display #__line__ ";view-files-sort set default: ~A" (view-files-sort))) (if (not (member *print-length* '(12 32) )) (snd-display #__line__ ";print-length set default: ~A" *print-length*)) (if (not (eqv? *play-arrow-size* 10 )) (snd-display #__line__ ";play-arrow-size set default: ~A" *play-arrow-size*)) (if (not (equal? *save-state-file* "saved-snd.scm" )) (snd-display #__line__ ";save-state-file set default: ~A" *save-state-file*)) (if (not (eqv? *show-axes* 1)) (snd-display #__line__ ";show-axes set default: ~A" *show-axes*)) (if (not (boolean? *show-transform-peaks*)) (snd-display #__line__ ";show-transform-peaks set default: ~A" *show-transform-peaks*)) (if (not (boolean? *show-indices*)) (snd-display #__line__ ";show-indices set default: ~A" *show-indices*)) (if (not *show-marks*) (snd-display #__line__ ";show-marks set default: ~A" *show-marks*)) (if (not *show-mix-waveforms*) (snd-display #__line__ ";show-mix-waveforms set default: ~A" *show-mix-waveforms*)) (if *show-selection-transform* (snd-display #__line__ ";show-selection-transform set default: ~A" *show-selection-transform*)) (if *show-y-zero* (snd-display #__line__ ";show-y-zero set default: ~A" *show-y-zero*)) (if *show-grid* (snd-display #__line__ ";show-grid set default: ~A" *show-grid*)) (if (fneq *grid-density* 1.0) (snd-display #__line__ ";grid-density set default: ~A" *grid-density*)) (if *show-sonogram-cursor* (snd-display #__line__ ";show-sonogram-cursor set default: ~A" *show-sonogram-cursor*)) (if (not (eqv? *sinc-width* 10 )) (snd-display #__line__ ";sinc-width set default: ~A" *sinc-width*)) (if (fneq *spectrum-end* 1.0) (snd-display #__line__ ";spectrum-end set default: ~A" *spectrum-end*)) (if (not (eqv? *spectro-hop* 4 )) (snd-display #__line__ ";spectro-hop set default: ~A" *spectro-hop*)) (if (fneq *spectrum-start* 0.0 ) (snd-display #__line__ ";spectrum-start set default: ~A" *spectrum-start*)) (if (fneq *spectro-x-angle* (if (provided? 'gl) 300.0 90.0)) (snd-display #__line__ ";spectro-x-angle set default: ~A" *spectro-x-angle*)) (if (fneq *spectro-x-scale* (if (provided? 'gl) 1.5 1.0)) (snd-display #__line__ ";spectro-x-scale set default: ~A" *spectro-x-scale*)) (if (fneq *spectro-y-angle* (if (provided? 'gl) 320.0 0.0)) (snd-display #__line__ ";spectro-y-angle set default: ~A" *spectro-y-angle*)) (if (fneq *spectro-y-scale* 1.0 ) (snd-display #__line__ ";spectro-y-scale set default: ~A" *spectro-y-scale*)) (if (fneq *spectro-z-angle* (if (provided? 'gl) 0.0 358.0)) (snd-display #__line__ ";spectro-z-angle set default: ~A" *spectro-z-angle*)) (if (fneq *spectro-z-scale* (if (provided? 'gl) 1.0 0.1)) (snd-display #__line__ ";spectro-z-scale set default: ~A" *spectro-z-scale*)) (if (and *temp-dir* (not (equal? *temp-dir* "/home/bil/zap/tmp"))) (snd-display #__line__ ";temp-dir set default: ~A" *temp-dir*)) (if (not (equal? *ladspa-dir* "" )) (snd-display #__line__ ";ladspa-dir set default: ~A" *ladspa-dir*)) (if (and *peak-env-dir* (not (equal? *peak-env-dir* "/home/bil/peaks"))) (snd-display #__line__ ";peak-env-dir set default: ~A" *peak-env-dir*)) (if (and (not (equal? *tiny-font* "6x12")) (not (equal? *tiny-font* "Sans 8"))) (snd-display #__line__ ";tiny-font set default: ~A" *tiny-font*)) (if (not (equal? *transform-type* fourier-transform )) (snd-display #__line__ ";transform-type set default: ~A" *transform-type*)) (if (not (eq? *with-file-monitor* #t)) (snd-display #__line__ ";with-file-monitor set default: ~A" *with-file-monitor*)) (if (not (eqv? *clm-table-size* 512)) (snd-display #__line__ ";clm-table-size set default: ~A" *clm-table-size*)) (if (not (eqv? *clm-table-size* 512)) (snd-display #__line__ ";*clm-table-size*: ~A" *clm-table-size*)) (if (fneq *clm-default-frequency* 0.0) (snd-display #__line__ ";clm-default-frequency set default: ~A" *clm-default-frequency*)) (if (fneq *clm-default-frequency* 0.0) (snd-display #__line__ ";*clm-default-frequency*: ~A" *clm-default-frequency*)) (if (not (boolean? *with-verbose-cursor*)) (snd-display #__line__ ";with-verbose-cursor set default: ~A" *with-verbose-cursor*)) (if (not (boolean? *with-inset-graph*)) (snd-display #__line__ ";with-inset-graph set default: ~A" *with-inset-graph*)) (if (not *with-interrupts*) (snd-display #__line__ ";with-interrupts set default: ~A" *with-interrupts*)) (if *remember-sound-state* (snd-display #__line__ ";remember-sound-state set default: ~A" *remember-sound-state*)) (if *with-smpte-label* (snd-display #__line__ ";with-smpte-label set default: ~A" *with-smpte-label*)) (if (not (eq? *with-toolbar* (provided? 'snd-gtk))) (snd-display #__line__ ";with-toolbar set default: ~A" *with-toolbar*)) (if (not *with-tooltips*) (snd-display #__line__ ";with-tooltips set default: ~A" *with-tooltips*)) (if (not (boolean? *with-menu-icons*)) (snd-display #__line__ ";with-menu-icons set default: ~A" *with-menu-icons*)) (if *save-as-dialog-src* (snd-display #__line__ ";save-as-dialog-src set default: ~A" *save-as-dialog-src*)) (if *save-as-dialog-auto-comment* (snd-display #__line__ ";save-as-dialog-auto-comment set default: ~A" *save-as-dialog-auto-comment*)) (if (not (boolean? *with-pointer-focus*)) (snd-display #__line__ ";with-pointer-focus set default: ~A" *with-pointer-focus*)) (if (not (eqv? *wavelet-type* 0 )) (snd-display #__line__ ";wavelet-type set default: ~A" *wavelet-type*)) (if (not (equal? *time-graph-type* graph-once)) (snd-display #__line__ ";time-graph-type set default: ~A" *time-graph-type*)) (if (not (eqv? *wavo-hop* 3 )) (snd-display #__line__ ";wavo-hop set default: ~A" *wavo-hop*)) (if (not (eqv? *wavo-trace* 64 )) (snd-display #__line__ ";wavo-trace set default: ~A" *wavo-trace*)) (if (not (eqv? *x-axis-style* 0 )) (snd-display #__line__ ";x-axis-style set default: ~A" *x-axis-style*)) (if (fneq *beats-per-minute* 60.0 ) (snd-display #__line__ ";beats-per-minute set default: ~A" *beats-per-minute*)) (if (not (= *beats-per-measure* 4)) (snd-display #__line__ ";beats-per-measure set default: ~A" *beats-per-measure*)) (if (not (eqv? *zero-pad* 0)) (snd-display #__line__ ";zero-pad set default: ~A" *zero-pad*)) (if (not (eqv? *zero-pad* 0)) (snd-display #__line__ ";zero-pad set -123: ~A" *zero-pad*)) (if (not (null? (zero-pad #t #t))) (snd-display #__line__ ";zero-pad #t: ~A" (zero-pad #t #t))) (if (not (eqv? *zoom-focus-style* 2 )) (snd-display #__line__ ";zoom-focus-style set default: ~A" *zoom-focus-style*)) (if (not (equal? *sync-style* sync-by-sound )) (snd-display #__line__ ";sync-style set default: ~A" *sync-style*)) (if (not (eqv? *mix-waveform-height* 20 )) (snd-display #__line__ ";mix-waveform-height set default: ~A" *mix-waveform-height*)) (if (not (eqv? *mix-tag-width* 6)) (snd-display #__line__ ";mix-tag-width set default: ~A" *mix-tag-width*)) (if (not (eqv? *mix-tag-height* 14)) (snd-display #__line__ ";mix-tag-height set default: ~A" *mix-tag-height*)) (if (not (eqv? *mark-tag-width* 10)) (snd-display #__line__ ";mark-tag-width set default: ~A" *mark-tag-width*)) (if (not (eqv? *mark-tag-height* 4)) (snd-display #__line__ ";mark-tag-height set default: ~A" *mark-tag-height*)) (if (not (equal? *region-graph-style* graph-lines)) (snd-display #__line__ ";* region-graph-style set default: ~A" *region-graph-style*)) (if *ask-about-unsaved-edits* (snd-display #__line__ ";* ask-about-unsaved-edits set default: ~A" *ask-about-unsaved-edits*)) (if *show-full-range* (snd-display #__line__ ";* show-full-range set default: ~A" *show-full-range*)) (if (fneq *initial-beg* 0.0) (snd-display #__line__ ";* initial-beg set default: ~A" *initial-beg*)) (if (fneq *initial-dur* 0.1) (snd-display #__line__ ";* initial-dur set default: ~A" *initial-dur*)) (if *ask-before-overwrite* (snd-display #__line__ ";* ask-before-overwrite set default: ~A" *ask-before-overwrite*)) (if (not *auto-resize*) (snd-display #__line__ ";* auto-resize set default: ~A" *auto-resize*)) (if *auto-update* (snd-display #__line__ ";* auto-update set default: ~A" *auto-update*)) (if (not (eqv? *channel-style* 1 )) (snd-display #__line__ ";* channel-style set default: ~A" *channel-style*)) (if (and (fneq *color-cutoff* 0.003 ) (fneq *color-cutoff* 0.001)) (snd-display #__line__ ";* color-cutoff set default: ~A" *color-cutoff*)) (if (not (eq? *color-inverted* #t)) (snd-display #__line__ ";* color-inverted set default: ~A" *color-inverted*)) (if (fneq *color-scale* 1.0 ) (snd-display #__line__ ";* color-scale set default: ~A" *color-scale*)) (if (fneq *auto-update-interval* 60.0 ) (snd-display #__line__ ";* auto-update-interval set default: ~A" *auto-update-interval*)) (if (fneq *cursor-update-interval* 0.05 ) (snd-display #__line__ ";* cursor-update-interval set default: ~A" *cursor-update-interval*)) (if (not (= *cursor-location-offset* 0)) (snd-display #__line__ ";* cursor-location-offset set default: ~A" *cursor-location-offset*)) (if (not (eq? *dac-combines-channels* #t)) (snd-display #__line__ ";* dac-combines-channels set default: ~A" *dac-combines-channels*)) (if (not (eqv? *dac-size* 256 )) (snd-display #__line__ ";* dac-size set default: ~A" *dac-size*)) (if *clipping* (snd-display #__line__ ";* clipping set default: ~A" *clipping*)) (if (not (eqv? *default-output-chans* 1 )) (snd-display #__line__ ";* default-output-chans set default: ~A" *default-output-chans*)) (if (and (not (equal? *default-output-sample-type* mus-bdouble)) (not (equal? *default-output-sample-type* mus-ldouble))) (snd-display #__line__ ";* default-output-sample-type set default: ~A" *default-output-sample-type*)) (if (not (eqv? *default-output-srate* 44100 )) (snd-display #__line__ ";* default-output-srate set default: ~A" *default-output-srate*)) (if (not (equal? *default-output-header-type* mus-next)) (snd-display #__line__ ";* default-output-header-type set default: ~A" *default-output-header-type*)) (if (not (eqv? *dot-size* 1 )) (snd-display #__line__ ";* dot-size set default: ~A" *dot-size*)) (if (not (eqv? *cursor-size* 15 )) (snd-display #__line__ ";* cursor-size set default: ~A" *cursor-size*)) (if (not (equal? *cursor-style* cursor-cross )) (snd-display #__line__ ";* cursor-style set default: ~A" *cursor-style*)) (if (not (equal? *tracking-cursor-style* cursor-line )) (snd-display #__line__ ";* tracking-cursor-style set default: ~A" *tracking-cursor-style*)) (if (fneq *enved-base* 1.0 ) (snd-display #__line__ ";* enved-base set default: ~A" *enved-base*)) (if (not (eqv? *enved-filter-order* 40)) (snd-display #__line__ ";* enved-filter-order set default: ~A" *enved-filter-order*)) (if (not (equal? *enved-style* envelope-linear )) (snd-display #__line__ ";* enved-style set default: ~A" *enved-style*)) (if (fneq *enved-power* 3.0) (snd-display #__line__ ";* enved-power set default: ~A" *enved-power*)) (if (not (eqv? *enved-target* 0 )) (snd-display #__line__ ";* enved-target set default: ~A" *enved-target*)) (if *enved-wave?* (snd-display #__line__ ";* enved-wave? set default: ~A" *enved-wave?*)) (if (not (equal? *eps-file* "snd.eps" )) (snd-display #__line__ ";* eps-file set default: ~A" *eps-file*)) (if (fneq *eps-bottom-margin* 0.0) (snd-display #__line__ ";* eps-bottom-margin set default: ~A" *eps-bottom-margin*)) (if (fneq *eps-left-margin* 0.0) (snd-display #__line__ ";* eps-left-margin set default: ~A" *eps-left-margin*)) (if (fneq *eps-size* 1.0) (snd-display #__line__ ";* eps-size set default: ~A" *eps-size*)) (if (fneq *fft-window-alpha* 0.0 ) (snd-display #__line__ ";* fft-window-alpha set default: ~A" *fft-window-alpha*)) (if (fneq *fft-window-beta* 0.0 ) (snd-display #__line__ ";* fft-window-beta set default: ~A" *fft-window-beta*)) (if *fft-log-frequency* (snd-display #__line__ ";* fft-log-frequency set default: ~A" *fft-log-frequency*)) (if *fft-log-magnitude* (snd-display #__line__ ";* fft-log-magnitude set default: ~A" *fft-log-magnitude*)) (if *fft-with-phases* (snd-display #__line__ ";* fft-with-phases set default: ~A" *fft-with-phases*)) (if (not (member *transform-size* (list 1024 4096))) (snd-display #__line__ ";* transform-size set default: ~A" *transform-size*)) (if (not (equal? *transform-graph-type* graph-once)) (snd-display #__line__ ";* transform-graph-type set default: ~A" *transform-graph-type*)) (if (not (eqv? *fft-window* 6 )) (snd-display #__line__ ";* fft-window set default: ~A" *fft-window*)) (if (not (eqv? *graph-cursor* 34)) (snd-display #__line__ ";* graph-cursor set default: ~A" *graph-cursor*)) (if (not (equal? *graph-style* graph-lines )) (snd-display #__line__ ";* graph-style set default: ~A" *graph-style*)) (if (not *graphs-horizontal*) (snd-display #__line__ ";* graphs-horizontal set default: ~A" *graphs-horizontal*)) (if (not (equal? *html-dir* ".")) (snd-display #__line__ ";* html-dir set default: ~A" *html-dir*)) (if (not (equal? *html-program* "firefox")) (snd-display #__line__ ";* html-program set default: ~A" *html-program*)) (if (not *just-sounds*) (snd-display #__line__ ";* just-sounds set default: ~A" *just-sounds*)) (if (not (eqv? *max-transform-peaks* 100)) (snd-display #__line__ ";* max-transform-peaks set default: ~A" *max-transform-peaks*)) (if (not (eqv? *max-transform-peaks* 100)) (snd-display #__line__ ";* max-transform-peaks set -123: ~A" *max-transform-peaks*)) (if (not (eqv? *max-regions* 16 )) (snd-display #__line__ ";* max-regions set default: ~A" *max-regions*)) (if (fneq *min-dB* -60.0 ) (snd-display #__line__ ";* min-dB set default: ~A" *min-dB*)) (if (fneq *log-freq-start* 32.0 ) (snd-display #__line__ ";* log-freq-start set default: ~A" *log-freq-start*)) (if (not (eq? *selection-creates-region* #t )) (snd-display #__line__ ";* selection-creates-region set default: ~A" *selection-creates-region*)) (if (not (equal? *transform-normalization* normalize-by-channel)) (snd-display #__line__ ";* transform-normalization set default: ~A" *transform-normalization*)) (if (and with-motif (not (eqv? *view-files-sort* 0 )) ) (snd-display #__line__ ";* view-files-sort set default: ~A" *view-files-sort*)) (if (not (eqv? *play-arrow-size* 10 )) (snd-display #__line__ ";* play-arrow-size set default: ~A" *play-arrow-size*)) (if (not (equal? *save-state-file* "saved-snd.scm" )) (snd-display #__line__ ";* save-state-file set default: ~A" *save-state-file*)) (if (not (eqv? *show-axes* 1)) (snd-display #__line__ ";* show-axes set default: ~A" *show-axes*)) (if (not *show-marks*) (snd-display #__line__ ";* show-marks set default: ~A" *show-marks*)) (if (not *show-mix-waveforms*) (snd-display #__line__ ";* show-mix-waveforms set default: ~A" *show-mix-waveforms*)) (if *show-selection-transform* (snd-display #__line__ ";* show-selection-transform set default: ~A" *show-selection-transform*)) (if *show-y-zero* (snd-display #__line__ ";* show-y-zero set default: ~A" *show-y-zero*)) (if *show-grid* (snd-display #__line__ ";* show-grid set default: ~A" *show-grid*)) (if (fneq *grid-density* 1.0) (snd-display #__line__ ";* grid-density set default: ~A" *grid-density*)) (if *show-sonogram-cursor* (snd-display #__line__ ";* show-sonogram-cursor set default: ~A" *show-sonogram-cursor*)) (if (not (eqv? *sinc-width* 10 )) (snd-display #__line__ ";* sinc-width set default: ~A" *sinc-width*)) (if (fneq *spectrum-end* 1.0) (snd-display #__line__ ";* spectrum-end set default: ~A" *spectrum-end*)) (if (not (eqv? *spectro-hop* 4 )) (snd-display #__line__ ";* spectro-hop set default: ~A" *spectro-hop*)) (if (fneq *spectrum-start* 0.0 ) (snd-display #__line__ ";* spectrum-start set default: ~A" *spectrum-start*)) (if (fneq *spectro-x-angle* (if (provided? 'gl) 300.0 90.0)) (snd-display #__line__ ";* spectro-x-angle set default: ~A" *spectro-x-angle*)) (if (fneq *spectro-x-scale* (if (provided? 'gl) 1.5 1.0)) (snd-display #__line__ ";* spectro-x-scale set default: ~A" *spectro-x-scale*)) (if (fneq *spectro-y-angle* (if (provided? 'gl) 320.0 0.0)) (snd-display #__line__ ";* spectro-y-angle set default: ~A" *spectro-y-angle*)) (if (fneq *spectro-y-scale* 1.0 ) (snd-display #__line__ ";* spectro-y-scale set default: ~A" *spectro-y-scale*)) (if (fneq *spectro-z-angle* (if (provided? 'gl) 0.0 358.0)) (snd-display #__line__ ";* spectro-z-angle set default: ~A" *spectro-z-angle*)) (if (fneq *spectro-z-scale* (if (provided? 'gl) 1.0 0.1)) (snd-display #__line__ ";* spectro-z-scale set default: ~A" *spectro-z-scale*)) (if (and (not (equal? *tiny-font* "6x12")) (not (equal? *tiny-font* "Sans 8"))) (snd-display #__line__ ";* tiny-font set default: ~A" *tiny-font*)) (if (not *with-file-monitor*) (snd-display #__line__ ";* with-file-monitor set default: ~A" *with-file-monitor*)) (if (not *with-interrupts*) (snd-display #__line__ ";* with-interrupts set default: ~A" *with-interrupts*)) (if *remember-sound-state* (snd-display #__line__ ";* remember-sound-state set default: ~A" *remember-sound-state*)) (if *with-smpte-label* (snd-display #__line__ ";* with-smpte-label set default: ~A" *with-smpte-label*)) (if (not (eq? *with-toolbar* (provided? 'snd-gtk))) (snd-display #__line__ ";* with-toolbar set default: ~A" *with-toolbar*)) (if (not *with-tooltips*) (snd-display #__line__ ";* with-tooltips set default: ~A" *with-tooltips*)) (if *save-as-dialog-src* (snd-display #__line__ ";* save-as-dialog-src set default: ~A" *save-as-dialog-src*)) (if *save-as-dialog-auto-comment* (snd-display #__line__ ";* save-as-dialog-auto-comment set default: ~A" *save-as-dialog-auto-comment*)) (if (not (eqv? *wavelet-type* 0 )) (snd-display #__line__ ";* wavelet-type set default: ~A" *wavelet-type*)) (if (not (equal? *time-graph-type* graph-once)) (snd-display #__line__ ";* time-graph-type set default: ~A" *time-graph-type*)) (if (not (eqv? *wavo-hop* 3 )) (snd-display #__line__ ";* wavo-hop set default: ~A" *wavo-hop*)) (if (not (eqv? *wavo-trace* 64 )) (snd-display #__line__ ";* wavo-trace set default: ~A" *wavo-trace*)) (if (not (eqv? *x-axis-style* 0 )) (snd-display #__line__ ";* x-axis-style set default: ~A" *x-axis-style*)) (if (fneq *beats-per-minute* 60.0 ) (snd-display #__line__ ";* beats-per-minute set default: ~A" *beats-per-minute*)) (if (not (= *beats-per-measure* 4)) (snd-display #__line__ ";* beats-per-measure set default: ~A" *beats-per-measure*)) (if (not (eqv? *zero-pad* 0)) (snd-display #__line__ ";* zero-pad set default: ~A" *zero-pad*)) (if (not (eqv? *zoom-focus-style* 2 )) (snd-display #__line__ ";* zoom-focus-style set default: ~A" *zoom-focus-style*)) (if (not (equal? *sync-style* sync-by-sound )) (snd-display #__line__ ";* sync-style set default: ~A" *sync-style*)) (if (not (eqv? *mix-waveform-height* 20 )) (snd-display #__line__ ";* mix-waveform-height set default: ~A" *mix-waveform-height*)) (if (not (eqv? *mix-tag-width* 6)) (snd-display #__line__ ";* mix-tag-width set default: ~A" *mix-tag-width*)) (if (not (eqv? *mix-tag-height* 14)) (snd-display #__line__ ";* mix-tag-height set default: ~A" *mix-tag-height*)) (if (not (eqv? *mark-tag-width* 10)) (snd-display #__line__ ";* mark-tag-width set default: ~A" *mark-tag-width*)) (if (not (eqv? *mark-tag-height* 4)) (snd-display #__line__ ";* mark-tag-height set default: ~A" *mark-tag-height*)) (if (and with-motif (not (= (view-files-sort) 0))) (snd-display #__line__ ";view-files-sort def: ~A" (view-files-sort))) (if (> most-positive-fixnum (expt 2 36)) (begin (let ((old-max-malloc *mus-max-malloc*)) (set! *mus-max-malloc* (expt 2 36)) (if (not (= *mus-max-malloc* (expt 2 36))) (snd-display #__line__ ";mus-max-malloc as bignum: ~A" *mus-max-malloc*)) (set! *mus-max-malloc* old-max-malloc)) (let ((old-max-table-size *mus-max-table-size*)) (set! *mus-max-table-size* (expt 2 36)) (if (not (= *mus-max-table-size* (expt 2 36))) (snd-display #__line__ ";mus-max-table-size as bignum: ~A" *mus-max-table-size*)) (set! *mus-max-table-size* old-max-table-size)))) (if (not (provided? 'snd-gtk)) (for-each (lambda (func name) (let ((val (func))) (set! (func) "8x123") (if (or (not (string? (func))) (not (string=? val (func)))) (snd-display #__line__ ";set ~A to bogus value: ~A ~A" name val (func))))) (list axis-label-font axis-numbers-font tiny-font peaks-font bold-peaks-font) (list 'axis-label-font 'axis-numbers-font 'tiny-font 'peaks-font 'bold-peaks-font))) (set! *ask-about-unsaved-edits* #f) (set! *remember-sound-state* #f) )) ;;; ---------------- test 1: defaults ---------------- (define good-colormap hot-colormap) (define better-colormap black-and-white-colormap) (if (and with-gui (not (colormap? good-colormap))) (set! good-colormap (call-with-exit (lambda (return) (do ((i 1 (+ i 1))) ((= i 20)) (if (colormap? (integer->colormap i)) (return (integer->colormap i)))))))) (if (and with-gui (not (colormap? better-colormap))) (set! better-colormap (call-with-exit (lambda (return) (do ((i good-colormap (+ i 1))) ((= i 20)) (if (colormap? (integer->colormap i)) (return (integer->colormap i)))))))) (define (snd_test_1) (when with-gui (letrec ((test-defaults (lambda (lst) (if (pair? lst) (begin (if (and (not (equal? (cadr lst) (caddr lst))) (or (not (pair? (caddr lst))) (not (member (cadr lst) (caddr lst))))) (if (and (number? (caddr lst)) (not (rational? (caddr lst)))) (if (fneq (cadr lst) (caddr lst)) (snd-display #__line__ ";~A is not ~A (~A)" (car lst) (caddr lst) (cadr lst))) (snd-display #__line__ ";~A is not ~A (~A)" (car lst) (caddr lst) (cadr lst)))) (test-defaults (cdddr lst))))))) (for-each close-sound (sounds)) ; in case others opened elsewhere (test-defaults (list 'amp-control (without-errors (amp-control)) 'no-such-sound 'amp-control-bounds (cadr (amp-control-bounds)) 8.0 'ask-about-unsaved-edits *ask-about-unsaved-edits* #f 'ask-before-overwrite *ask-before-overwrite* #f 'auto-resize *auto-resize* #t 'auto-update *auto-update* #f 'auto-update-interval *auto-update-interval* 60.0 'beats-per-measure *beats-per-measure* 4 'beats-per-minute *beats-per-minute* 60.0 'channel-style *channel-style* 1 'clipping *clipping* #f 'clm-table-size *clm-table-size* 512 'clm-default-frequency *clm-default-frequency* 0.0 'color-cutoff *color-cutoff* '(0.003 0.001) 'color-inverted *color-inverted* #t 'color-scale *color-scale* 1.0 'colormap *colormap* (list hot-colormap jet-colormap) 'contrast-control (without-errors (contrast-control)) 'no-such-sound 'contrast-control-amp *contrast-control-amp* 1.0 'contrast-control-bounds (cadr (contrast-control-bounds)) 10.0 'contrast-control? (without-errors (contrast-control?)) 'no-such-sound 'cursor-location-offset *cursor-location-offset* 0 'cursor-size *cursor-size* 15 'cursor-style *cursor-style* cursor-cross 'cursor-update-interval *cursor-update-interval* 0.05 'dac-combines-channels *dac-combines-channels* #t 'dac-size *dac-size* 256 'default-output-chans *default-output-chans* 1 'default-output-sample-type *default-output-sample-type* mus-ldouble 'default-output-header-type *default-output-header-type* mus-next 'default-output-srate *default-output-srate* 44100 'dot-size *dot-size* 1 'enved-base *enved-base* 1.0 'enved-clip? (enved-clip?) #t 'enved-envelope (enved-envelope) () 'enved-filter (enved-filter) #t 'enved-filter-order *enved-filter-order* 40 'enved-in-dB (enved-in-dB) #f 'enved-power *enved-power* 3.0 'enved-style *enved-style* envelope-linear 'enved-target *enved-target* 0 'enved-wave? *enved-wave?* #f 'eps-bottom-margin *eps-bottom-margin* 0.0 'eps-file *eps-file* "snd.eps" 'eps-left-margin *eps-left-margin* 0.0 'eps-size *eps-size* 1.0 'expand-control (without-errors (expand-control)) 'no-such-sound 'expand-control-bounds (cadr (expand-control-bounds)) 20.0 'expand-control-hop *expand-control-hop* 0.05 'expand-control-jitter *expand-control-jitter* 0.1 'expand-control-length *expand-control-length* 0.15 'expand-control-ramp *expand-control-ramp* 0.4 'expand-control? (without-errors (expand-control?)) 'no-such-sound 'fft-log-frequency *fft-log-frequency* #f 'fft-log-magnitude *fft-log-magnitude* #f 'fft-with-phases *fft-with-phases* #f 'fft-window *fft-window* 6 'fft-window-alpha *fft-window-alpha* 0.0 'fft-window-beta *fft-window-beta* 0.0 'filter-control-coeffs (without-errors (filter-control-coeffs)) 'no-such-sound 'filter-control-envelope (without-errors (filter-control-envelope)) 'no-such-sound 'filter-control-in-dB *filter-control-in-dB* #f 'filter-control-in-hz *filter-control-in-hz* #f 'filter-control-order *filter-control-order* 20 'filter-control? (without-errors (filter-control?)) 'no-such-sound 'graph-cursor *graph-cursor* 34 'graph-style *graph-style* graph-lines 'graphs-horizontal *graphs-horizontal* #t 'grid-density *grid-density* 1.0 'html-dir *html-dir* "." 'html-program *html-program* "firefox" 'initial-beg *initial-beg* 0.0 'initial-dur *initial-dur* 0.1 'just-sounds *just-sounds* #t 'ladspa-dir *ladspa-dir* "" 'peak-env-dir *peak-env-dir* (list "" "/home/bil/peaks") 'lisp-graph? (without-errors (lisp-graph?)) 'no-such-sound ; 'listener-prompt *listener-prompt* ">" 'log-freq-start *log-freq-start* 32.0 'mark-tag-height *mark-tag-height* 4 'mark-tag-width *mark-tag-width* 10 'max-regions *max-regions* 16 'max-transform-peaks *max-transform-peaks* 100 'min-dB *min-dB* -60.0 'mix-tag-height *mix-tag-height* 14 'mix-tag-width *mix-tag-width* 6 'mix-waveform-height *mix-waveform-height* 20 'mus-array-print-length *mus-array-print-length* 8 'mus-clipping (mus-clipping) #f 'mus-float-equal-fudge-factor *mus-float-equal-fudge-factor* .0000001 'play-arrow-size *play-arrow-size* 10 'print-length *print-length* '(12 32) 'read-only (without-errors (read-only)) 'no-such-sound 'region-graph-style *region-graph-style* graph-lines 'remember-sound-state *remember-sound-state* #f 'reverb-control-feedback *reverb-control-feedback* 1.09 'reverb-control-length (without-errors (reverb-control-length)) 'no-such-sound 'reverb-control-length-bounds (cadr (reverb-control-length-bounds)) 5.0 'reverb-control-lowpass *reverb-control-lowpass* 0.7 'reverb-control-scale (without-errors (reverb-control-scale)) 'no-such-sound 'reverb-control-scale-bounds (cadr (reverb-control-scale-bounds)) 4.0 'reverb-control? (without-errors (reverb-control?)) 'no-such-sound 'save-as-dialog-auto-comment *save-as-dialog-auto-comment* #f 'save-as-dialog-src *save-as-dialog-src* #f 'save-state-file *save-state-file* "saved-snd.scm" 'selection-creates-region *selection-creates-region* #t 'show-axes *show-axes* 1 'show-controls *show-controls* #f 'show-full-duration *show-full-duration* '(#f #t) 'show-full-range *show-full-range* #f 'show-grid *show-grid* #f 'show-indices *show-indices* '(#f #t) 'show-marks *show-marks* #t 'show-mix-waveforms *show-mix-waveforms* #t 'show-selection-transform *show-selection-transform* #f 'show-sonogram-cursor *show-sonogram-cursor* #f 'show-transform-peaks *show-transform-peaks* '(#f #t) 'show-y-zero *show-y-zero* #f 'sinc-width *sinc-width* 10 'spectrum-end *spectrum-end* 1.0 'spectro-hop *spectro-hop* 4 'spectrum-start *spectrum-start* 0.0 'spectro-x-angle *spectro-x-angle* (if (provided? 'gl) 300.0 90.0) 'spectro-x-scale *spectro-x-scale* (if (provided? 'gl) 1.5 1.0) 'spectro-y-angle *spectro-y-angle* (if (provided? 'gl) 320.0 0.0) 'spectro-y-scale *spectro-y-scale* 1.0 'spectro-z-angle *spectro-z-angle* (if (provided? 'gl) 0.0 358.0) 'spectro-z-scale *spectro-z-scale* (if (provided? 'gl) 1.0 0.1) 'speed-control (without-errors (speed-control)) 'no-such-sound 'speed-control-bounds (cadr (speed-control-bounds)) 20.0 'sync (without-errors (sync)) 'no-such-sound 'sync-style *sync-style* sync-by-sound 'temp-dir *temp-dir* (list "" "/home/bil/zap/tmp") 'time-graph-type *time-graph-type* graph-once 'time-graph? (without-errors (time-graph?)) 'no-such-sound 'tiny-font *tiny-font* (if (provided? 'snd-motif) "6x12" "Sans 8") 'tracking-cursor-style *tracking-cursor-style* cursor-line 'transform-graph-type *transform-graph-type* graph-once 'transform-graph? (without-errors (transform-graph?)) 'no-such-sound 'transform-normalization *transform-normalization* normalize-by-channel 'transform-size *transform-size* *transform-size* 'transform-type *transform-type* fourier-transform 'wavelet-type *wavelet-type* 0 'wavo-hop *wavo-hop* 3 'wavo-trace *wavo-trace* 64 'with-mix-tags *with-mix-tags* #t 'with-relative-panes *with-relative-panes* #t ; 'with-tracking-cursor *with-tracking-cursor* '(#f 1) 'with-verbose-cursor *with-verbose-cursor* '(#f #t) 'with-inset-graph *with-inset-graph* '(#f #t) 'with-interrupts *with-interrupts* #t 'with-smpte-label *with-smpte-label* #f 'with-toolbar *with-toolbar* '(#f #t) 'with-tooltips *with-tooltips* #t 'with-menu-icons *with-menu-icons* '(#f #t) 'with-pointer-focus *with-pointer-focus* '(#f #t) 'x-axis-style *x-axis-style* 0 'zero-pad *zero-pad* 0 'zoom-focus-style *zoom-focus-style* 2 )) (if *snd-opened-sound* (snd-display #__line__ ";*snd-opened-sound*: ~A" *snd-opened-sound*)) (let ((s (open-sound "oboe.snd"))) (letrec ((test-vars (lambda (lst) (if (pair? lst) (let* ((args (car lst)) (name (args 0)) (getfnc (args 1)) (setfnc (lambda (val) (set! (getfnc) val))) (initval (args 2)) (newval (args 3)) (star-name (args 4))) (setfnc newval) (let ((nowval (symbol->value star-name))) (if (and (not (equal? newval nowval)) (or (not (list? newval)) (not (feql newval nowval)))) (if (and (number? newval) (not (rational? newval))) (if (> (abs (- newval nowval)) .01) (snd-display #__line__ ";~A is not ~A (~A)" star-name newval nowval)) (snd-display #__line__ ";~A is not ~A (~A)" star-name newval nowval))) (eval `(set! ,star-name ,initval)) (if (not (morally-equal? (getfnc) initval)) (snd-display #__line__ ";* ~A is not ~A" name initval)) (eval `(set! ,star-name ,newval)) (let ((nowval (getfnc))) (if (and (not (equal? newval nowval)) (or (not (list? newval)) (not (feql newval nowval)))) (if (and (number? newval) (not (rational? newval))) (if (> (abs (- newval nowval)) .01) (snd-display #__line__ ";set! ~A is not ~A (~A)" star-name newval nowval)) (snd-display #__line__ ";set! ~A is not ~A (~A)" star-name newval nowval))) (setfnc initval)) (test-vars (cdr lst)))))))) (test-vars (list (list 'ask-about-unsaved-edits ask-about-unsaved-edits #f #t '*ask-about-unsaved-edits*) (list 'ask-before-overwrite ask-before-overwrite #f #t '*ask-before-overwrite*) (list 'auto-resize auto-resize #t #f '*auto-resize*) (list 'auto-update auto-update #f #t '*auto-update*) (list 'channel-style channel-style 0 1 '*channel-style*) (list 'color-cutoff color-cutoff 0.003 0.01 '*color-cutoff*) (list 'color-inverted color-inverted #t #f '*color-inverted*) (list 'color-scale color-scale 1.0 0.5 '*color-scale*) (list 'contrast-control-amp contrast-control-amp 1.0 0.5 '*contrast-control-amp*) (list 'auto-update-interval auto-update-interval 60.0 120.0 '*auto-update-interval*) (list 'cursor-update-interval cursor-update-interval 0.05 0.10 '*cursor-update-interval*) (list 'cursor-location-offset cursor-location-offset 0 32768 '*cursor-location-offset*) ; (list 'with-tracking-cursor with-tracking-cursor 2 1 '*with-tracking-cursor*) (list 'cursor-size cursor-size 15 30 '*cursor-size*) (list 'cursor-style cursor-style cursor-cross cursor-line '*cursor-style*) (list 'tracking-cursor-style tracking-cursor-style cursor-line cursor-cross '*tracking-cursor-style*) (list 'dac-combines-channels dac-combines-channels #t #f '*dac-combines-channels*) (list 'dac-size dac-size 256 512 '*dac-size*) (list 'clipping clipping #f #t '*clipping*) (list 'default-output-chans default-output-chans 1 2 '*default-output-chans*) (list 'default-output-sample-type default-output-sample-type 1 1 '*default-output-sample-type*) (list 'default-output-srate default-output-srate 22050 44100 '*default-output-srate*) (list 'default-output-header-type default-output-header-type mus-next mus-aifc '*default-output-header-type*) (list 'dot-size dot-size 1 4 '*dot-size*) (list 'enved-base enved-base 1.0 1.5 '*enved-base*) (list 'enved-style enved-style envelope-linear envelope-exponential '*enved-style*) (list 'enved-power enved-power 3.0 3.5 '*enved-power*) (list 'enved-target enved-target 0 1 '*enved-target*) (list 'enved-wave? enved-wave? #f #t '*enved-wave?*) (list 'eps-file eps-file "snd.eps" "snd-1.eps" '*eps-file*) (list 'eps-left-margin eps-left-margin 0.0 72.0 '*eps-left-margin*) (list 'eps-size eps-size 1.0 2.0 '*eps-size*) (list 'eps-bottom-margin eps-bottom-margin 0.0 36.0 '*eps-bottom-margin*) (list 'expand-control-hop expand-control-hop 0.05 0.1 '*expand-control-hop*) (list 'expand-control-jitter expand-control-jitter 0.1 0.2 '*expand-control-jitter*) (list 'expand-control-length expand-control-length 0.15 0.2 '*expand-control-length*) (list 'expand-control-ramp expand-control-ramp 0.4 0.2 '*expand-control-ramp*) (list 'fft-window-alpha fft-window-alpha 0.0 1.0 '*fft-window-alpha*) (list 'fft-window-beta fft-window-beta 0.0 0.5 '*fft-window-beta*) (list 'fft-log-frequency fft-log-frequency #f #t '*fft-log-frequency*) (list 'fft-log-magnitude fft-log-magnitude #f #t '*fft-log-magnitude*) (list 'fft-with-phases fft-with-phases #f #t '*fft-with-phases*) (list 'transform-size transform-size 512 1024 '*transform-size*) (list 'transform-graph-type transform-graph-type graph-once graph-as-sonogram '*transform-graph-type*) (list 'fft-window fft-window 6 5 '*fft-window*) (list 'filter-control-in-dB filter-control-in-dB #f #t '*filter-control-in-dB*) (list 'enved-filter-order enved-filter-order 40 20 '*enved-filter-order*) (list 'filter-control-in-hz filter-control-in-hz #f #t '*filter-control-in-hz*) (list 'filter-control-order filter-control-order 20 40 '*filter-control-order*) ; (list 'graph-cursor graph-cursor 34 32 '*graph-cursor*) (list 'graph-style graph-style 0 1 '*graph-style*) (list 'initial-beg initial-beg 0.0 1.0 '*initial-beg*) (list 'initial-dur initial-dur 0.1 1.0 '*initial-dur*) (list 'just-sounds just-sounds #f #t '*just-sounds*) (list 'listener-prompt listener-prompt ">" ":" '*listener-prompt*) (list 'max-transform-peaks max-transform-peaks 100 10 '*max-transform-peaks*) (list 'max-regions max-regions 16 6 '*max-regions*) (list 'min-dB min-dB -60.0 -90.0 '*min-dB*) (list 'log-freq-start log-freq-start 32.0 10.0 '*log-freq-start*) (list 'mix-waveform-height mix-waveform-height 20 40 '*mix-waveform-height*) (list 'mix-tag-height mix-tag-height 14 20 '*mix-tag-height*) (list 'mix-tag-width mix-tag-width 6 20 '*mix-tag-width*) (list 'mark-tag-height mark-tag-height 4 20 '*mark-tag-height*) (list 'mark-tag-width mark-tag-width 10 20 '*mark-tag-width*) (list 'selection-creates-region selection-creates-region #t #f '*selection-creates-region*) (list 'transform-normalization transform-normalization normalize-by-channel dont-normalize '*transform-normalization*) (list 'play-arrow-size play-arrow-size 10 16 '*play-arrow-size*) (list 'print-length print-length 12 16 '*print-length*) (list 'region-graph-style region-graph-style graph-lines graph-lollipops '*region-graph-style*) (list 'reverb-control-decay reverb-control-decay 1.0 2.0 '*reverb-control-decay*) (list 'reverb-control-feedback reverb-control-feedback 1.09 1.6 '*reverb-control-feedback*) (list 'reverb-control-lowpass reverb-control-lowpass 0.7 0.9 '*reverb-control-lowpass*) (list 'show-axes show-axes 1 0 '*show-axes*) (list 'show-full-duration show-full-duration #f #t '*show-full-duration*) (list 'show-full-range show-full-range #f #t '*show-full-range*) (list 'show-transform-peaks show-transform-peaks #f #t '*show-transform-peaks*) (list 'show-indices show-indices #f #t '*show-indices*) (list 'show-marks show-marks #t #f '*show-marks*) (list 'show-mix-waveforms show-mix-waveforms #t #f '*show-mix-waveforms*) (list 'show-selection-transform show-selection-transform #f #t '*show-selection-transform*) (list 'show-y-zero show-y-zero #f #t '*show-y-zero*) (list 'show-grid show-grid #f #t '*show-grid*) (list 'grid-density grid-density 1.0 0.5 '*grid-density*) (list 'show-sonogram-cursor show-sonogram-cursor #f #t '*show-sonogram-cursor*) (list 'sinc-width sinc-width 10 40 '*sinc-width*) (list 'spectrum-end spectrum-end 1.0 0.7 '*spectrum-end*) (list 'spectro-hop spectro-hop 4 10 '*spectro-hop*) (list 'spectrum-start spectrum-start 0.0 0.1 '*spectrum-start*) (list 'spectro-x-angle spectro-x-angle (if (provided? 'gl) 300.0 90.0) 60.0 '*spectro-x-angle*) (list 'spectro-x-scale spectro-x-scale (if (provided? 'gl) 1.5 1.0) 2.0 '*spectro-x-scale*) (list 'spectro-y-angle spectro-y-angle (if (provided? 'gl) 320.0 0.0) 60.0 '*spectro-y-angle*) (list 'spectro-y-scale spectro-y-scale 1.0 2.0 '*spectro-y-scale*) (list 'spectro-z-angle spectro-z-angle (if (provided? 'gl) 0.0 358.0) 60.0 '*spectro-z-angle*) (list 'spectro-z-scale spectro-z-scale (if (provided? 'gl) 1.0 0.1) 0.2 '*spectro-z-scale*) (list 'speed-control-style speed-control-style 0 1 '*speed-control-style*) (list 'speed-control-tones speed-control-tones 12 18 '*speed-control-tones*) (list 'sync-style sync-style sync-by-sound sync-all '*sync-style*) (list 'tiny-font tiny-font (if (provided? 'snd-gtk) "Sans 8" "6x12") (if (provided? 'snd-gtk) "Monospace 10" "9x15") '*tiny-font*) (list 'with-verbose-cursor with-verbose-cursor #f #t '*with-verbose-cursor*) (list 'wavelet-type wavelet-type 0 1 '*wavelet-type*) (list 'time-graph-type time-graph-type graph-once graph-as-wavogram '*time-graph-type*) (list 'wavo-hop wavo-hop 3 6 '*wavo-hop*) (list 'wavo-trace wavo-trace 64 128 '*wavo-trace*) ;(list 'with-mix-tags with-mix-tags #t #f '*with-mix-tags*) (list 'with-relative-panes with-relative-panes #t #f '*with-relative-panes*) (list 'with-gl with-gl (provided? 'gl) #f '*with-gl*) (list 'x-axis-style x-axis-style 0 1 '*x-axis-style*) (list 'beats-per-minute beats-per-minute 30.0 120.0 '*beats-per-minute*) (list 'beats-per-measure beats-per-measure 1 120 '*beats-per-measure*) (list 'zero-pad zero-pad 0 1 '*zero-pad*) (list 'zoom-focus-style zoom-focus-style 2 1 '*zoom-focus-style*) ))) (close-sound s) )) (set! *ask-about-unsaved-edits* #f) (set! *remember-sound-state* #f) )) (set! (with-mix-tags) #t) ; assumed in test 16(!) (set! *default-output-sample-type* mus-ldouble) ;;; ---------------- test 2: headers ---------------- (define (snd_test_2) (if (string? sf-dir) (letrec ((test-headers (lambda (base-files) (if (pair? base-files) (let ((testf (car base-files))) (let ((file (string-append sf-dir (testf 0)))) (if (file-exists? file) (begin (if (not (equal? (mus-sound-chans file) (testf 1))) (snd-display #__line__ ";~A: chans ~A is not ~A" (testf 0) (mus-sound-chans file) (testf 1))) (if (not (equal? (mus-sound-srate file) (testf 2))) (snd-display #__line__ ";~A: srate ~A is not ~A" (testf 0) (mus-sound-srate file) (testf 2))) (if (fneq (mus-sound-duration file) (testf 3)) (snd-display #__line__ ";~A: duration ~A is not ~A" (testf 0) (mus-sound-duration file) (testf 3))) (if (and (not (= (mus-sound-sample-type file) mus-unknown-sample)) (not (= (mus-sound-header-type file) 27)) ; bogus header on test case (comdisco) (< (+ (mus-sound-length file) 1) (* (mus-sound-datum-size file) (mus-sound-duration file) (mus-sound-srate file) (mus-sound-chans file)))) (snd-display #__line__ ";mus-sound-length ~A: ~A (~A)" file (mus-sound-length file) (* (mus-sound-duration file) (mus-sound-srate file) (mus-sound-chans file) (mus-sound-datum-size file)))) (if (fneq (/ (mus-sound-framples file) (mus-sound-srate file)) (mus-sound-duration file)) (snd-display #__line__ ";mus-sound-framples ~A: ~A (~A ~A)" file (mus-sound-framples file) (mus-sound-duration file) (/ (mus-sound-framples file) (mus-sound-srate file)))) (if (> (abs (- (mus-sound-framples file) (/ (mus-sound-samples file) (mus-sound-chans file)))) 1) (snd-display #__line__ ";mus-sound-samples ~A: ~A ~A" file (mus-sound-samples file) (* (mus-sound-framples file) (mus-sound-chans file)))) (if (not (equal? (mus-header-type-name (mus-sound-header-type file)) (testf 4))) (snd-display #__line__ ";~A: type ~A is not ~A" (testf 0) (mus-header-type-name (mus-sound-header-type file)) (testf 4))) (if (not (equal? (mus-sample-type-name (mus-sound-sample-type file)) (testf 5))) (snd-display #__line__ ";~A: type ~A is not ~A" (testf 0) (mus-sample-type-name (mus-sound-sample-type file)) (testf 5))) (let ((lst (mus-sound-loop-info file))) (if (> (length testf) 6) (begin (if (not (equal? (car lst) (testf 6))) (snd-display #__line__ ";~A: loop start: ~A" (car lst) (testf 6))) (if (not (equal? (cadr lst) (testf 7))) (snd-display #__line__ ";~A: loop end: ~A" (cadr lst) (testf 7)))) (if (pair? lst) (snd-display #__line__ ";~A thinks it has loop info: ~A" file lst)))) (mus-sound-forget file)) (snd-display #__line__ ";~A missing?" file)) (test-headers (cdr base-files)))))))) ;; need to make sure raw defaults are consistent with following tests (let ((ind (open-raw-sound :file (string-append sf-dir "addf8.nh") :channels 2 :srate 44100 :sample-type mus-bshort))) (if (sound? ind) (close-sound ind))) (catch #t (lambda () (if (not (= (mus-sound-header-type (string-append sf-dir "midi60.mid")) -1)) (snd-display #__line__ ";midi60?"))) (lambda args args)) (test-headers (list (list "5_secs.aiff" 1 44100 5.303107 "AIFF" "big endian short (16 bits)") (list "8svx-8.snd" 1 22050 1.88766443729401 "SVX8" "signed byte (8 bits)") (list "Fnonull.aif" 1 8000 0.00112499995157123 "AIFC" "mulaw (8 bits)") (list "Pmiscck.aif" 1 8000 0.00112499995157123 "AIFC" "mulaw (8 bits)") (list "Pmiscck.wav" 1 8000 0.00112499995157123 "RIFF" "mulaw (8 bits)") ; (list "Pnossnd.aif" 1 8000 0.0 "AIFC" "mulaw (8 bits)") (list "Poffset.aif" 1 8000 0.00112499995157123 "AIFC" "mulaw (8 bits)") (list "Porder.aif" 1 8000 0.00112499995157123 "AIFC" "mulaw (8 bits)") (list "Ptjunk.aif" 1 8000 0.00112499995157123 "AIFC" "mulaw (8 bits)") (list "Ptjunk.wav" 1 8000 0.00112499995157123 "RIFF" "mulaw (8 bits)") (list "SINE24-S.WAV" 2 44100 2.0 "RIFF" "little endian int (24 bits)") (list "a1.asf" 1 16000 3.73656249046326 "asf" "unknown") (list "a2.asf" 1 8000 4.63062477111816 "asf" "unknown") (list "addf8.afsp" 1 8000 2.9760000705719 "Sun/Next" "big endian short (16 bits)") (list "addf8.d" 1 8000 2.9760000705719 "SPPACK" "big endian short (16 bits)") (list "addf8.dwd" 1 8000 2.9760000705719 "DiamondWare" "little endian short (16 bits)") (list "addf8.nh" 2 44100 0.269931972026825 "raw (no header)" "big endian short (16 bits)") (list "addf8.sd" 1 8000 2.9760000705719 "ESPS" "big endian short (16 bits)") (list "addf8.sf_mipseb" 1 8000 2.9760000705719 "IRCAM" "big endian short (16 bits)") (list "addf8.sf_sun" 1 8000 2.9760000705719 "IRCAM" "big endian short (16 bits)") (list "addf8.sf_vax_b" 1 8000 2.9760000705719 "IRCAM" "big endian short (16 bits)") (list "addf8.wav" 1 8000 2.9760000705719 "RIFF" "little endian short (16 bits)") (list "aebass.krz" 1 44100 3.0 "Kurzweil 2000" "big endian short (16 bits)") (list "aiff-16.snd" 2 44100 0.746666669845581 "AIFF" "big endian short (16 bits)") (list "aiff-8.snd" 2 44100 0.746666669845581 "AIFF" "signed byte (8 bits)") (list "alaw.aifc" 1 44100 0.0367800444364548 "AIFC" "alaw (8 bits)") (list "alaw.wav" 1 11025 8.70666694641113 "RIFF" "alaw (8 bits)") (list "astor_basia.mp2" 2 44100 1.02179133892059 "raw (no header)" "big endian short (16 bits)") (list "c.asf" 1 8000 21.3681259155273 "asf" "unknown") (list "ce-c3.w02" 1 33000 3.88848495483398 "TX-16W" "unknown") (list "ce-c4.w03" 1 33000 2.91618180274963 "TX-16W" "unknown") (list "ce-d2.w01" 1 33000 3.46439385414124 "TX-16W" "unknown") (list "clbonef.wav" 1 22050 2.57832193374634 "RIFF" "little endian float (32 bits)") (list "cranker.krz" 1 44100 3.48267579078674 "Kurzweil 2000" "big endian short (16 bits)") (list "d40130.aif" 1 10000 0.100000001490116 "AIFF" "big endian short (16 bits)") (list "d40130.au" 1 10000 0.100000001490116 "Sun/Next" "big endian short (16 bits)") (list "d40130.dsf" 1 8000 0.125 "Delusion" "little endian short (16 bits)") (list "d40130.fsm" 1 8000 0.125249996781349 "Farandole" "little endian short (16 bits)") (list "d40130.iff" 1 10000 0.100000001490116 "SVX8" "signed byte (8 bits)") (list "d40130.pat" 1 10000 0.100000001490116 "Gravis Ultrasound patch" "little endian short (16 bits)") (list "d40130.sds" 1 10000 0.100000001490116 "MIDI sample dump" "unknown") (list "d40130.sdx" 1 10000 0.100000001490116 "Sample dump" "unsigned little endian short (16 bits)") (list "d40130.sf" 1 10000 0.100000001490116 "IRCAM" "little endian short (16 bits)") (list "d40130.smp" 1 8000 0.125 "SMP" "little endian short (16 bits)") (list "d40130.sou" 1 8000 0.125 "SBStudioII" "little endian short (16 bits)") (list "d40130.st3" 1 8000 0.125 "Digiplayer ST3" "unsigned little endian short (16 bits)") (list "d40130.uwf" 1 8000 0.125249996781349 "Ultratracker" "little endian short (16 bits)") (list "d40130.voc" 1 10000 0.100100003182888 "VOC" "unsigned byte (8 bits)") (list "d40130.w00" 1 16000 0.0625 "TX-16W" "unknown") (list "d40130.wav" 1 10000 0.100000001490116 "RIFF" "little endian short (16 bits)") (list "d43.wav" 1 10000 0.100000001490116 "RIFF" "little endian short (16 bits)") (list "digit0v0.aiff" 1 8000 0.560000002384186 "AIFC" "big endian short (16 bits)") (list "esps-16.snd" 1 8000 3.09737491607666 "ESPS" "big endian short (16 bits)") (list "forest.aiff" 2 44100 3.907143 "AIFF" "big endian short (16 bits)" 24981 144332) ; (list "g721.au" 1 11025 4.35328817367554 "Sun/Next" "unknown") ; (list "g722.aifc" 1 44100 0.0184353739023209 "AIFC" "unknown") (list "gong.wve" 1 8000 3.96799993515015 "PSION" "alaw (8 bits)") (list "gsm610.wav" 1 11025 1.7687075138092 "RIFF" "unknown") (list "inrs-16.snd" 1 8000 2.46399998664856 "INRS" "little endian short (16 bits)") (list "kirk.wve" 1 8000 1.40799999237061 "PSION" "alaw (8 bits)") (list "loop.aiff" 1 44100 0.0367120169103146 "AIFC" "big endian short (16 bits)" 12 23) (list "m.asf" 1 8000 64.9646224975586 "asf" "unknown") (list "mary-sun4.sig" 1 8000 4.47612476348877 "Comdisco SPW signal" "big endian double (64 bits)") (list "mocksong.wav" 1 11025 7.86956930160522 "RIFF" "little endian short (16 bits)") (list "mono24.wav" 1 22050 1.98997735977173 "RIFF" "little endian int (24 bits)") (list "msadpcm.wav" 1 11025 4.43501138687134 "RIFF" "unknown") (list "n8.snd" 1 44100 0.0367800444364548 "Sun/Next" "signed byte (8 bits)") (list "nasahal.aif" 1 11025 9.89841270446777 "AIFF" "signed byte (8 bits)") (list "nasahal.avi" 1 11025 10.4327440261841 "AVI" "little endian short (16 bits)") (list "nasahal.dig" 1 11025 9.89841270446777 "Sound Designer 1" "big endian short (16 bits)") (list "nasahal.ivc" 2 44100 0.449002265930176 "raw (no header)" "big endian short (16 bits)") (list "nasahal.pat" 1 11025 3.95410442352295 "Gravis Ultrasound patch" "unsigned byte (8 bits)") (list "nasahal.snd" 1 11025 9.89841270446777 "SNDT" "unsigned byte (8 bits)") (list "nasahal.svx" 1 11025 9.89841270446777 "SVX8" "signed byte (8 bits)") (list "nasahal.v8" 1 8000 13.6412496566772 "Covox V8" "unsigned byte (8 bits)") (list "nasahal.voc" 1 11025 9.89941024780273 "VOC" "unsigned byte (8 bits)") (list "nasahal.vox" 2 44100 0.224444448947906 "raw (no header)" "big endian short (16 bits)") (list "nasahal8.wav" 1 11025 9.89841270446777 "RIFF" "unsigned byte (8 bits)") (list "nasahalad.smp" 1 11025 4.94920635223389 "Goldwave sample" "little endian short (16 bits)") (list "next-16.snd" 1 22050 1.00004529953003 "Sun/Next" "big endian short (16 bits)") (list "next-8.snd" 1 22050 0.226757362484932 "Sun/Next" "signed byte (8 bits)") (list "next-dbl.snd" 1 22050 0.226757362484932 "Sun/Next" "big endian double (64 bits)") (list "oboe.ldbl" 1 22050 2.30512475967407 "RIFF" "little endian double (64 bits)") (list "next-flt.snd" 1 22050 0.226757362484932 "Sun/Next" "big endian float (32 bits)") (list "aifc-float.snd" 1 22050 0.226757362484932 "AIFC" "big endian float (32 bits)") (list "next-mulaw.snd" 1 8012 2.03295063972473 "Sun/Next" "mulaw (8 bits)") (list "next24.snd" 1 44100 0.0367800444364548 "Sun/Next" "big endian int (24 bits)") (list "nist-01.wav" 1 16000 2.26912498474121 "NIST" "little endian short (16 bits)") (list "nist-10.wav" 1 16000 2.26912498474121 "NIST" "big endian short (16 bits)") (list "nist-16.snd" 1 16000 1.02400004863739 "NIST" "big endian short (16 bits)") (list "nist-shortpack.wav" 1 16000 4.53824996948242 "NIST" "unknown") (list "none.aifc" 1 44100 0.0367800444364548 "AIFC" "big endian short (16 bits)") (list "nylon2.wav" 2 22050 1.14376413822174 "RIFF" "unknown") (list "o2.adf" 1 44100 0.036780 "CSRE adf" "little endian short (16 bits)") (list "o2.avr" 1 44100 0.0183900222182274 "AVR" "big endian short (16 bits)") (list "o2.bicsf" 1 44100 0.0367800444364548 "IRCAM" "big endian short (16 bits)") (list "o2.mpeg1" 2 44100 0.00709750549867749 "raw (no header)" "big endian short (16 bits)") (list "o2.sd2" 2 44100 0.0183900222182274 "raw (no header)" "big endian short (16 bits)") (list "o2.sf2" 1 44100 0.0367800444364548 "SoundFont" "little endian short (16 bits)") (list "o2.smp" 1 8000 0.202749997377396 "SMP" "little endian short (16 bits)") (list "o2.voc" 1 44100 0.0368934236466885 "VOC" "little endian short (16 bits)") (list "o2.wave" 1 44100 0.0367800444364548 "RIFF" "little endian short (16 bits)") (list "o2_12bit.aiff" 1 44100 0.0367800444364548 "AIFF" "big endian short (16 bits)") (list "o2_18bit.aiff" 1 44100 0.0367800444364548 "AIFF" "big endian int (24 bits)") ; (list "o2_711u.wave" 1 44100 0.0367800444364548 "RIFF" "mulaw (8 bits)") ; (list "o2_722.snd" 1 44100 0.0183900222182274 "Sun/Next" "unknown") ; (list "o2_726.aiff" 1 8000 0.0367499999701977 "AIFC" "unknown") ; (list "o2_726.snd" 1 44100 0.0230158735066652 "Sun/Next" "unknown") ; (list "o2_728.aiff" 1 8000 0.0367499999701977 "AIFC" "unknown") (list "o2_8.iff" 1 44100 0.0367800444364548 "SVX8" "signed byte (8 bits)") (list "o2_8.voc" 1 44100 0.0370294786989689 "VOC" "unsigned byte (8 bits)") (list "o2_dvi.wave" 1 44100 0.0232199542224407 "RIFF" "unknown") (list "o2_float.bicsf" 1 44100 0.0367800444364548 "IRCAM" "big endian float (32 bits)") (list "o2_gsm.aiff" 1 8000 0.0367499999701977 "AIFC" "unknown") (list "o2_u8.avr" 1 44100 0.0367800444364548 "AVR" "unsigned byte (8 bits)") (list "o2_u8.wave" 1 44100 0.0367800444364548 "RIFF" "unsigned byte (8 bits)") (list "o28.mpc" 1 44100 0.036780 "AKAI 4" "little endian short (16 bits)") ; (list "oboe.g721" 1 22050 1.15287983417511 "Sun/Next" "unknown") ; (list "oboe.g723_24" 1 22050 0.864761888980865 "Sun/Next" "unknown") ; (list "oboe.g723_40" 1 22050 1.44126987457275 "Sun/Next" "unknown") (list "oboe.kts" 1 22050 2.305125 "Korg" "big endian short (16 bits)") (list "oboe.its" 1 22050 2.305125 "Impulse Tracker" "little endian short (16 bits)") (list "oboe.sf2" 1 22050 2.30512475967407 "SoundFont" "little endian short (16 bits)") (list "oboe.paf" 1 22050 2.305125 "Ensoniq Paris" "big endian short (16 bits)") (list "oboe.pf1" 1 22050 2.305125 "Ensoniq Paris" "little endian short (16 bits)") (list "oboe.smp" 1 22050 2.305125 "snack SMP" "little endian short (16 bits)") (list "oboe.rf64" 1 22050 2.305125 "rf64" "little endian short (16 bits)") (list "oboe-be32.caf" 1 22050 2.305125 "caff" "normalized big endian int (32 bits)") (list "oboe-bf64.caf" 1 22050 2.305125 "caff" "big endian double (64 bits)") (list "oboe-lf32.caf" 1 22050 2.305125 "caff" "little endian float (32 bits)") (list "oboe-ulaw.caf" 1 22050 2.305125 "caff" "mulaw (8 bits)") (list "oboe.nsp" 1 22050 2.305125 "CSL" "little endian short (16 bits)") ; (list "oboe.nvf" 1 8000 6.353500 "Creative NVF" "unknown") (list "oboe-ulaw.voc" 1 22050 2.305669 "VOC" "mulaw (8 bits)") (list "oboe-lf32.sf" 1 22050 2.305669 "IRCAM" "little endian float (32 bits)") (list "oboe.wfp" 1 22050 2.305125 "Turtle Beach" "little endian short (16 bits)") (list "oboe.sox" 1 22050 2.305125 "Sox" "normalized little endian int (32 bits)") (list "oki.snd" 2 44100 0.0041950112208724 "raw (no header)" "big endian short (16 bits)") (list "oki.wav" 1 44100 0.016780 "RIFF" "unknown") (list "orv-dvi-adpcm.wav" 1 44100 1.92725622653961 "RIFF" "unknown") (list "riff-16.snd" 1 22050 1.88766443729401 "RIFF" "little endian short (16 bits)") (list "riff-8-u.snd" 1 11025 0.506848096847534 "RIFF" "unsigned byte (8 bits)") (list "rooster.wve" 1 8000 2.04800009727478 "PSION" "alaw (8 bits)") (list "sd1-16.snd" 1 44100 0.400544226169586 "Sound Designer 1" "big endian short (16 bits)") ; (list "segfault.snd" 16777216 576061440 1.24986669902682e-7 "Sun/Next" "unknown") (list "sf-16.snd" 1 22050 1.88766443729401 "IRCAM" "big endian short (16 bits)") (list "si654.adc" 1 16000 6.71362495422363 "ADC/OGI" "big endian short (16 bits)") (list "smp-16.snd" 1 8000 5.2028751373291 "SMP" "little endian short (16 bits)") (list "sound.pat" 1 8000 1.95050001144409 "Gravis Ultrasound patch" "unsigned little endian short (16 bits)") (list "sound.sap" 1 8000 1.95050001144409 "Goldwave sample" "little endian short (16 bits)") (list "sound.sds" 1 8000 1.95050001144409 "MIDI sample dump" "unknown") (list "sound.sfr" 1 8000 1.95050001144409 "SRFS" "little endian short (16 bits)") (list "sound.v8" 1 8000 1.95050001144409 "Covox V8" "unsigned byte (8 bits)") (list "sound.vox" 2 44100 0.044217687100172 "raw (no header)" "big endian short (16 bits)") (list "step.omf" 1 11025 8.70666694641113 "OMF" "signed byte (8 bits)") (list "step.qt" 1 11025 8.70630359649658 "Quicktime" "unsigned byte (8 bits)") (list "sun-16-afsp.snd" 1 8000 2.9760000705719 "Sun/Next" "big endian short (16 bits)") (list "sun-mulaw.snd" 1 8000 4.61950016021729 "Sun/Next" "mulaw (8 bits)") (list "sw1038t_short.wav" 2 8000 6.0 "NIST" "mulaw (8 bits)") (list "swirl.pat" 1 22050 1.0619500875473 "Gravis Ultrasound patch" "unsigned little endian short (16 bits)") (list "sy85.snd" 1 8000 5.05600023269653 "Sy-85" "big endian short (16 bits)") (list "sy99.snd" 1 8000 4.54400014877319 "Sy-99" "big endian short (16 bits)") (list "telephone.wav" 1 16000 2.27881240844727 "NIST" "little endian short (16 bits)") (list "trumps22.adp" 1 22050 3.092880 "RIFF" "unknown") (list "truspech.wav" 1 8000 1.1599999666214 "RIFF" "unknown") (list "ulaw.aifc" 1 44100 0.0367800444364548 "AIFC" "mulaw (8 bits)") (list "voc-8-u.snd" 1 8000 1.49937498569489 "VOC" "unsigned byte (8 bits)") (list "o28.voc" 1 44100 0.036893 "VOC" "little endian short (16 bits)") (list "voxware.wav" 1 8000 0.324000000953674 "RIFF" "unknown") (list "wd.w00" 1 8000 0.202749997377396 "Sy-99" "big endian short (16 bits)") (list "wd1.smp" 1 8000 0.202749997377396 "SMP" "little endian short (16 bits)") (list "wd1.wav" 1 44100 0.0367800444364548 "RIFF" "little endian short (16 bits)") (list "wheel.mat" 2 44100 0.145646259188652 "raw (no header)" "big endian short (16 bits)") (list "b8.pvf" 1 44100 0.036803 "Portable Voice Format" "signed byte (8 bits)") (list "b16.pvf" 1 44100 0.036803 "Portable Voice Format" "big endian short (16 bits)") (list "b32.pvf" 1 44100 0.036803 "Portable Voice Format" "big endian int (32 bits)") (list "water.voc" 2 32000 42.3463897705078 "VOC" "little endian short (16 bits)") (list "wood.dsf" 1 8000 0.202749997377396 "Delusion" "little endian short (16 bits)") (list "wood.dvi" 1 22100 0.0278733037412167 "RIFF" "unknown") (list "wood.dwd" 1 22100 0.0733936652541161 "DiamondWare" "signed byte (8 bits)") (list "wood.fsm" 1 8000 0.202999994158745 "Farandole" "little endian short (16 bits)") (list "wood.mad" 1 22100 0.0372398197650909 "RIFF" "unknown") (list "wood.maud" 1 44100 0.0183900222182274 "MAUD" "big endian short (16 bits)") (list "wood.pat" 1 22100 0.0733936652541161 "Gravis Ultrasound patch" "little endian short (16 bits)") (list "wood.riff" 1 44100 0.0367800444364548 "RIFF" "little endian short (16 bits)") (list "wood.rifx" 1 44100 0.0367800444364548 "RIFF" "big endian short (16 bits)") (list "wood.sds" 1 22100 0.0733936652541161 "MIDI sample dump" "unknown") (list "wood.sdx" 1 22100 0.0733936652541161 "Sample dump" "unsigned little endian short (16 bits)") (list "wood.sf" 1 44100 0.0367800444364548 "IRCAM" "big endian short (16 bits)") (list "wood.sndr" 2 44100 0.0092290248721838 "raw (no header)" "big endian short (16 bits)") (list "wood.sndt" 1 44100 0.0367800444364548 "SNDT" "unsigned byte (8 bits)") (list "wood.st3" 1 8000 0.202749997377396 "Digiplayer ST3" "unsigned little endian short (16 bits)") (list "wood.uwf" 1 8000 0.202999994158745 "Ultratracker" "little endian short (16 bits)") (list "wood.w00" 1 16000 0.101374998688698 "TX-16W" "unknown") (list "wood12.aiff" 1 44100 0.0367800444364548 "AIFF" "big endian short (16 bits)") (list "wood16.dwd" 2 44100 0.0367800444364548 "DiamondWare" "little endian short (16 bits)") (list "wood16.wav" 2 44100 0.0367800444364548 "RIFF" "little endian short (16 bits)") (list "wood16.nsp" 2 44100 0.0367800444364548 "CSL" "little endian short (16 bits)") (list "wood16.smp" 2 44100 0.0367800444364548 "snack SMP" "little endian short (16 bits)") (list "wood24.aiff" 1 44100 0.0367800444364548 "AIFF" "big endian int (24 bits)") (list "woodblock.aiff" 1 44100 0.0367800444364548 "AIFF" "big endian short (16 bits)") (list "woodflt.snd" 1 44100 0.0367800444364548 "Sun/Next" "big endian float (32 bits)") (list "RealDrums.sf2" 1 44100 6.39725637435913 "SoundFont" "little endian short (16 bits)") (list "32bit.sf" 1 44100 4.6 "IRCAM" "little endian float (32 bits, unscaled)") (list "PCM_48_8bit_m.w64" 1 48000 0.375 "SoundForge" "unsigned byte (8 bits)") (list "oboe.sf6" 1 22050 2.305125 "SoundForge" "little endian short (16 bits)") (list "addf8.24we" 1 8000 2.976000 "RIFF" "little endian int (24 bits)") (list "hybrid.snd" 1 44100 4.600000 "BICSF" "big endian float (32 bits)") (list "litmanna.sf" 1 44100 .533 "IRCAM" "little endian short (16 bits)") (list "M1F1-float64C-AFsp.aif" 2 8000 2.9366 "AIFC" "big endian double (64 bits)") (list "MacBoing.wav" 1 11127 0.696 "RIFF" "unsigned byte (8 bits)") (list "t15.aiff" 2 44100 135.00 "AIFC" "little endian short (16 bits)") (list "tomf8.aud" 1 8000 2.016000 "INRS" "little endian short (16 bits)") (list "Xhs001x.nsp" 1 10000 6.017400 "CSL" "little endian short (16 bits)") (list "zulu_a4.w11" 1 33000 1.21987879276276 "TX-16W" "unknown" 23342 40042))) (for-each (lambda (in-name real-name) (if (not (string=? (mus-expand-filename in-name) real-name)) (snd-display #__line__ ";mus-expand-filename ~A -> ~A" in-name (mus-expand-filename in-name))) (if (file-exists? "/home/bil/./sf1/o2.voc") (let ((ind (open-sound in-name))) (if (not (sound? ind)) (snd-display #__line__ ";can't open ~A" in-name) (begin (if (not (string=? (file-name ind) real-name)) (snd-display #__line__ ";expand file name ~A: ~A" in-name (file-name ind))) (close-sound ind)))))) (list "/home/bil/./sf1/o2.voc" "~/./sf1/o2.voc" "~/cl/../sf1/o2.voc" "/home/bil/cl/../sf1/o2.voc") (list "/home/bil/sf1/o2.voc" "/home/bil/sf1/o2.voc" "/home/bil/sf1/o2.voc" "/home/bil/sf1/o2.voc")) (let ((lst (mus-sound-mark-info (string-append sf-dir "forest.aiff")))) (if (not (equal? lst '((4 0) (3 0) (2 144332) (1 24981)))) (snd-display #__line__ ";mus-sound-mark-info forest: ~A" lst))) (let ((lst (mus-sound-mark-info (string-append sf-dir "traffic.aiff")))) (if (not (equal? lst '((4 1) (3 0) (2 171931) (1 99461)))) (snd-display #__line__ ";mus-sound-mark-info traffic: ~A" lst))) ))) ;;; ---------------- test 3: variables ---------------- (define (snd_test_3) (let ((ind #f)) (set! ind (open-sound "oboe.snd")) (if (and (file-exists? "funcs.scm") (not (defined? 'swellf))) (load "funcs.scm")) (let ((td *temp-dir*)) (catch #t (lambda () (set! *temp-dir* (string-append home-dir "/test")) (if (not (string=? *temp-dir* (string-append home-dir "/test"))) (snd-display #__line__ ";set temp-dir: ~A?" *temp-dir*))) (lambda args args)) (if td (set! *temp-dir* td) (set! *temp-dir* ""))) (if (fneq (sample 1000) 0.0328) (snd-display #__line__ ";sample: ~A?" (sample 1000))) (when with-gui (set! *show-controls* #t) (let ((wid (enved-dialog) )) (if (not (equal? wid ((dialog-widgets) 1))) (snd-display #__line__ ";enved-dialog -> ~A ~A" wid ((dialog-widgets) 1)))) ;(if (not ((dialog-widgets) 1)) (snd-display #__line__ ";enved-dialog?")) (set! (enved-envelope) '(0.0 0.0 1.0 1.0 2.0 0.0)) (if (not (equal? (enved-envelope) (list 0.0 0.0 1.0 1.0 2.0 0.0))) (snd-display #__line__ ";set enved-envelope to self: ~A?" (enved-envelope))) (letrec ((test-vars (lambda (lst) (if (pair? lst) (let* ((name ((car lst) 0)) (getfnc ((car lst) 1)) (setfnc (lambda (val) (set! (getfnc) val))) (initval ((car lst) 2)) (newval ((car lst) 3))) (setfnc newval) (let ((nowval (getfnc))) (if (and (not (equal? newval nowval)) (or (not (list? newval)) (not (feql newval nowval)))) (if (and (number? newval) (not (rational? newval))) (if (> (abs (- newval nowval)) .01) (snd-display #__line__ ";~A is not ~A (~A)" name newval nowval)) (snd-display #__line__ ";~A is not ~A (~A)" name newval nowval))) (setfnc initval) (set! (getfnc) newval) (let ((nowval (getfnc))) (if (and (not (equal? newval nowval)) (or (not (list? newval)) (not (feql newval nowval)))) (if (and (number? newval) (not (rational? newval))) (if (> (abs (- newval nowval)) .01) (snd-display #__line__ ";set! ~A is not ~A (~A)" name newval nowval)) (snd-display #__line__ ";set! ~A is not ~A (~A)" name newval nowval))) (setfnc initval)) (test-vars (cdr lst)))))))) (test-vars (list (list 'amp-control amp-control 1.0 0.5) (list 'amp-control-bounds amp-control-bounds (list 0.0 8.0) (list 1.0 5.0)) (list 'ask-about-unsaved-edits ask-about-unsaved-edits #f #t) (list 'ask-before-overwrite ask-before-overwrite #f #t) (list 'auto-resize auto-resize #t #f) (list 'auto-update auto-update #f #t) (list 'channel-style channel-style 0 1) (list 'colormap colormap good-colormap better-colormap) (list 'color-cutoff color-cutoff 0.003 0.01) (list 'color-inverted color-inverted #t #f) (list 'color-scale color-scale 1.0 0.5) (list 'contrast-control contrast-control 0.0 0.5) (list 'contrast-control-bounds contrast-control-bounds (list 0.0 10.0) (list 1.0 5.0)) (list 'contrast-control-amp contrast-control-amp 1.0 0.5) (list 'contrast-control? contrast-control? #f #t) (list 'auto-update-interval auto-update-interval 60.0 120.0) (list 'cursor-update-interval cursor-update-interval 0.05 0.10) (list 'cursor-location-offset cursor-location-offset 0 32768) (list 'with-tracking-cursor with-tracking-cursor #f #t) (list 'cursor-size cursor-size 15 30) (list 'cursor-style cursor-style cursor-cross cursor-line) (list 'tracking-cursor-style tracking-cursor-style cursor-line cursor-cross) (list 'dac-combines-channels dac-combines-channels #t #f) (list 'dac-size dac-size 256 512) (list 'clipping clipping #f #t) (list 'default-output-chans default-output-chans 1 2) (list 'default-output-sample-type default-output-sample-type 1 1) (list 'default-output-srate default-output-srate 22050 44100) (list 'default-output-header-type default-output-header-type mus-next mus-aifc) (list 'dot-size dot-size 1 4) (list 'enved-base enved-base 1.0 1.5) (list 'enved-clip? enved-clip? #f #t) (list 'enved-in-dB enved-in-dB #f #t) (list 'enved-style enved-style envelope-linear envelope-exponential) (list 'enved-power enved-power 3.0 3.5) (list 'enved-target enved-target 0 1) (list 'enved-wave? enved-wave? #f #t) (list 'eps-file eps-file "snd.eps" "snd-1.eps") (list 'eps-left-margin eps-left-margin 0.0 72.0) (list 'eps-size eps-size 1.0 2.0) (list 'eps-bottom-margin eps-bottom-margin 0.0 36.0) (list 'expand-control expand-control 1.0 2.0) (list 'expand-control-bounds expand-control-bounds (list .001 20.0) (list 1.0 2.0)) (list 'expand-control-hop expand-control-hop 0.05 0.1) (list 'expand-control-jitter expand-control-jitter 0.1 0.2) (list 'expand-control-length expand-control-length 0.15 0.2) (list 'expand-control-ramp expand-control-ramp 0.4 0.2) (list 'expand-control? expand-control? #f #t) (list 'fft-window-alpha fft-window-alpha 0.0 1.0) (list 'fft-window-beta fft-window-beta 0.0 0.5) (list 'fft-log-frequency fft-log-frequency #f #t) (list 'fft-log-magnitude fft-log-magnitude #f #t) (list 'fft-with-phases fft-with-phases #f #t) (list 'transform-size transform-size 512 1024) (list 'transform-graph-type transform-graph-type graph-once graph-as-sonogram) (list 'fft-window fft-window 6 5) (list 'transform-graph? transform-graph? #f #t) (list 'filter-control-in-dB filter-control-in-dB #f #t) (list 'filter-control-envelope filter-control-envelope (list 0.0 1.0 1.0 1.0) (list 0.0 1.0 1.0 0.0)) (list 'enved-filter enved-filter #t #f) (list 'enved-filter-order enved-filter-order 40 20) (list 'filter-control-in-hz filter-control-in-hz #f #t) (list 'filter-control-order filter-control-order 20 40) (list 'filter-control? filter-control? #f #t) (list 'graph-cursor graph-cursor 34 32) (list 'graph-style graph-style 0 1) (list 'initial-beg initial-beg 0.0 1.0) (list 'initial-dur initial-dur 0.1 1.0) (list 'just-sounds just-sounds #f #t) (list 'listener-prompt listener-prompt ">" ":") (list 'max-transform-peaks max-transform-peaks 100 10) (list 'max-regions max-regions 16 6) (list 'min-dB min-dB -60.0 -90.0) (list 'log-freq-start log-freq-start 32.0 10.0) (list 'mix-waveform-height mix-waveform-height 20 40) (list 'mix-tag-height mix-tag-height 14 20) (list 'mix-tag-width mix-tag-width 6 20) (list 'mark-tag-height mark-tag-height 4 20) (list 'mark-tag-width mark-tag-width 10 20) (list 'mus-clipping mus-clipping #f #t) (list 'selection-creates-region selection-creates-region #t #f) (list 'transform-normalization transform-normalization normalize-by-channel dont-normalize) (list 'play-arrow-size play-arrow-size 10 16) (list 'print-length print-length 12 16) (list 'region-graph-style region-graph-style graph-lines graph-lollipops) (list 'reverb-control-decay reverb-control-decay 1.0 2.0) (list 'reverb-control-feedback reverb-control-feedback 1.09 1.6) (list 'reverb-control-length reverb-control-length 1.0 2.0) (list 'reverb-control-length-bounds reverb-control-length-bounds (list 0.0 5.0) (list 1.0 2.0)) (list 'reverb-control-lowpass reverb-control-lowpass 0.7 0.9) (list 'reverb-control-scale reverb-control-scale 0.0 0.2) (list 'reverb-control-scale-bounds reverb-control-scale-bounds (list 0.0 4.0) (list 0.0 0.2)) (list 'reverb-control? reverb-control? #f #t) (list 'show-axes show-axes 1 0) (list 'show-full-duration show-full-duration #f #t) (list 'show-full-range show-full-range #f #t) (list 'show-transform-peaks show-transform-peaks #f #t) (list 'show-indices show-indices #f #t) (list 'show-marks show-marks #t #f) (list 'show-mix-waveforms show-mix-waveforms #t #f) (list 'show-selection-transform show-selection-transform #f #t) (list 'show-y-zero show-y-zero #f #t) (list 'show-grid show-grid #f #t) (list 'grid-density grid-density 1.0 0.5) (list 'show-sonogram-cursor show-sonogram-cursor #f #t) (list 'sinc-width sinc-width 10 40) (list 'spectrum-end spectrum-end 1.0 0.7) (list 'spectro-hop spectro-hop 4 10) (list 'spectrum-start spectrum-start 0.0 0.1) (list 'spectro-x-angle spectro-x-angle (if (provided? 'gl) 300.0 90.0) 60.0) (list 'spectro-x-scale spectro-x-scale (if (provided? 'gl) 1.5 1.0) 2.0) (list 'spectro-y-angle spectro-y-angle (if (provided? 'gl) 320.0 0.0) 60.0) (list 'spectro-y-scale spectro-y-scale 1.0 2.0) (list 'spectro-z-angle spectro-z-angle (if (provided? 'gl) 0.0 358.0) 60.0) (list 'spectro-z-scale spectro-z-scale (if (provided? 'gl) 1.0 0.1) 0.2) (list 'speed-control speed-control 1.0 0.5) (list 'speed-control-bounds speed-control-bounds (list 0.05 20.0) (list 1.0 5.0)) (list 'speed-control-style speed-control-style 0 1) (list 'speed-control-tones speed-control-tones 12 18) (list 'sync sync 0 1) (list 'sync-style sync-style sync-by-sound sync-all) (list 'tiny-font tiny-font (if (provided? 'snd-gtk) "Sans 8" "6x12") (if (provided? 'snd-gtk) "Monospace 10" "9x15")) (list 'transform-type transform-type fourier-transform autocorrelation) (list 'with-verbose-cursor with-verbose-cursor #f #t) (list 'wavelet-type wavelet-type 0 1) (list 'time-graph? time-graph? #f #t) (list 'time-graph-type time-graph-type graph-once graph-as-wavogram) (list 'wavo-hop wavo-hop 3 6) (list 'wavo-trace wavo-trace 64 128) (list 'with-mix-tags with-mix-tags #t #f) (list 'with-relative-panes with-relative-panes #t #f) (list 'with-gl with-gl (provided? 'gl) #f) (list 'x-axis-style x-axis-style 0 1) (list 'beats-per-minute beats-per-minute 30.0 120.0) (list 'beats-per-measure beats-per-measure 1 120) (list 'zero-pad zero-pad 0 1) (list 'zoom-focus-style zoom-focus-style 2 1)))) (set! *ask-about-unsaved-edits* #f) (letrec ((test-bad-args (lambda (lst) (if (pair? lst) (let* ((name ((car lst) 0)) (getfnc ((car lst) 1)) (setfnc (lambda (val) (set! (getfnc) val))) (initval ((car lst) 2)) (newvals ((car lst) 3))) (for-each (lambda (n) (catch #t (lambda () (setfnc n)) (lambda args (car args))) (let ((nowval (getfnc))) (if (equal? n nowval) (snd-display #__line__ ";(bad set) ~A = ~A (~A)" name n initval)) (setfnc initval))) newvals) (test-bad-args (cdr lst))))))) (test-bad-args (list (list 'amp-control amp-control 1.0 '(-1.0 123.123)) (list 'amp-control-bounds amp-control-bounds (list 0.0 8.0) (list #f (list 0.0) (list 1.0 0.0) 2.0)) (list 'channel-style channel-style 0 '(32 -1 1.0)) (list 'colormap colormap good-colormap '(321 -123)) (list 'color-cutoff color-cutoff 0.003 '(-1.0 123.123)) (list 'color-scale color-scale 1.0 '(-32.0 2000.0)) (list 'contrast-control contrast-control 0.0 '(-123.123 123.123)) (list 'contrast-control-bounds contrast-control-bounds (list 0.0 10.0) (list #f (list 0.0) (list 1.0 0.0) 2.0)) (list 'cursor-size cursor-size 15 '(1.123 -2.5)) (list 'dac-size dac-size 256 '(-1 0 -123)) (list 'dot-size dot-size 1 '(0 -1 -123)) (list 'enved-target enved-target 0 '(123 -321)) (list 'expand-control expand-control 1.0 '(-1.0 0.0)) (list 'expand-control-bounds expand-control-bounds (list 0.001 20.0) (list #f (list 0.0) (list 1.0 0.0) 2.0)) (list 'expand-control-hop expand-control-hop 0.05 '(-1.0)) (list 'expand-control-length expand-control-length 0.15 '(-1.0 0.0)) (list 'expand-control-ramp expand-control-ramp 0.4 '(-1.0 1.0 123.123)) (list 'fft-window-alpha fft-window-alpha 0.0 '(-1.0 123.123)) (list 'fft-window-beta fft-window-beta 0.0 '(-1.0 123.123)) (list 'transform-size transform-size 512 '(-1 0)) (list 'zero-pad zero-pad 0 '(-1 -123)) (list 'cursor-style cursor-style cursor-cross '(-1)) (list 'cursor-style cursor-style cursor-line '(2 123)) (list 'tracking-cursor-style tracking-cursor-style cursor-line '(-1)) (list 'tracking-cursor-style tracking-cursor-style cursor-line '(2 123)) (list 'transform-graph-type transform-graph-type graph-once '(-1 123)) (list 'fft-window fft-window 6 '(-1 123)) (list 'enved-filter-order enved-filter-order 40 '(-1 0)) (list 'filter-control-order filter-control-order 20 '(-10 -1 0)) (list 'max-transform-peaks max-transform-peaks 100 '(-1)) (list 'max-regions max-regions 16 '(-1 -123)) (list 'reverb-control-length reverb-control-length 1.0 '(-1.0)) (list 'show-axes show-axes 1 '(-1 123)) (list 'sinc-width sinc-width 10 '(-10)) (list 'spectrum-end spectrum-end 1.0 '(-1.0)) (list 'spectro-hop spectro-hop 4 '(-10 -1 0)) (list 'spectrum-start spectrum-start 0.0 '(-1.0)) (list 'speed-control speed-control 1.0 '(0.0)) (list 'speed-control-bounds speed-control-bounds (list 0.05 20.0) (list #f (list 0.0) (list 1.0 0.0) 2.0)) (list 'speed-control-style speed-control-style 0 '(-1 10)) (list 'sync-style sync-style sync-by-sound '(-1 123)) (list 'transform-type transform-type fourier-transform (list (integer->transform -1) (integer->transform 123))) (list 'wavelet-type wavelet-type 0 '(-1 123)) (list 'wavo-hop wavo-hop 1 '(0 -123)) (list 'wavo-trace wavo-trace 1 '(0 -123)) (list 'x-axis-style x-axis-style 0 '(-1 123)) (list 'zoom-focus-style zoom-focus-style 2 '(-1 123))))) (set! *sync-style* sync-none) (set! (window-width) 300) (set! (window-height) 300) (if (<= (window-width) 30) (snd-display #__line__ ";window width: ~A is not 300?" (window-width))) (if (<= (window-height) 30) (snd-display #__line__ ";window height: ~A is not 300?" (window-height))) ; (set! (window-x) 123) ; (set! (window-y) 321) ; (if (not (equal? (window-x) 123)) ; (snd-display #__line__ ";window x: ~A is not 123?" (window-x))) ; (if (not (equal? (window-y) 321)) ; (snd-display #__line__ ";window y: ~A is not 321?" (window-y))) ; (set! (window-y) 10) ; get it back out of harm's way (set! *color-scale* 100.0) (if (fneq *color-scale* 100.0) (snd-display #__line__ ";color-scale to 100: ~A" *color-scale*)) (if (procedure? (search-procedure)) (snd-display #__line__ ";global search procedure: ~A?" (search-procedure))) (set! (search-procedure) (lambda (y) (> y .1))) (if (not (procedure? (search-procedure))) (snd-display #__line__ ";set global search procedure: ~A?" (search-procedure))) (if (not ((search-procedure) .2)) (snd-display #__line__ ";search > .1 .2")) (if ((search-procedure) .02) (snd-display #__line__ ";search > .1 .02")) (set! (search-procedure) (lambda (y) (< y 0.0))) (if ((search-procedure) .02) (snd-display #__line__ ";search < 0.0 .02")) (set! (search-procedure) #f) (if (procedure? (search-procedure)) (snd-display #__line__ ";global search procedure after reset: ~A?" (search-procedure))) (set! (search-procedure) (lambda (y) (> y .1))) (if (not (procedure? (search-procedure))) (snd-display #__line__ ";set global search procedure: ~A?" (search-procedure))) (set! *enved-filter-order* 5) (if (not (= *enved-filter-order* 6)) (snd-display #__line__ ";set enved-filter-order 5: ~A" *enved-filter-order*)) (if with-gui (begin (set! (enved-envelope) 'zero_to_one) ; funcs.scm above (if (not (feql (enved-envelope) zero_to_one)) (snd-display #__line__ ";set symbol enved-envelope: ~A ~A" (enved-envelope) zero_to_one)) (set! (enved-envelope) "mod_down") (if (not (feql (enved-envelope) mod_down)) (snd-display #__line__ ";set string enved-envelope: ~A ~A" (enved-envelope) mod_down)))) (dismiss-all-dialogs)) (close-sound ind) (let ((undef ()) (names (list '*snd-opened-sound* 'abort 'add-colormap 'add-mark 'add-player 'add-sound-file-extension 'add-source-file-extension 'add-to-main-menu 'add-to-menu 'add-transform 'after-apply-controls-hook 'after-edit-hook 'after-graph-hook 'after-lisp-graph-hook 'after-open-hook 'after-save-as-hook 'after-save-state-hook 'after-transform-hook 'all-pass 'all-pass? 'amp-control 'amp-control-bounds 'amplitude-modulate 'apply-controls 'array->file 'array-interp 'as-one-edit 'ask-about-unsaved-edits 'ask-before-overwrite 'asymmetric-fm 'asymmetric-fm? 'auto-resize 'auto-update 'auto-update-interval 'autocorrelate 'autocorrelation 'axis-color 'axis-info 'axis-label-font 'axis-numbers-font 'bad-header-hook 'bartlett-window 'bartlett-hann-window 'basic-color 'beats-per-measure 'beats-per-minute 'before-close-hook 'before-exit-hook 'before-save-as-hook 'before-save-state-hook 'before-transform-hook 'bind-key 'blackman2-window 'blackman3-window 'blackman4-window 'blackman5-window 'blackman6-window 'blackman7-window 'blackman8-window 'blackman9-window 'blackman10-window 'bohman-window 'bold-peaks-font 'cauchy-window 'mlt-sine-window 'cepstrum 'change-samples-with-origin 'channel->float-vector 'channel-amp-envs 'channel-properties 'channel-property 'channel-style 'channel-widgets 'channels 'channels-combined 'channels-separate 'channels-superimposed 'chans 'clear-listener 'clip-hook 'clipping 'clm-channel 'clm-table-size 'clm-default-frequency 'close-hook 'close-sound 'color->list 'color-cutoff 'color-orientation-dialog 'color-hook 'color-inverted 'color-scale 'color? 'colormap 'colormap-name 'colormap-ref 'colormap-size 'colormap? 'comb 'comb? 'combined-data-color 'comment 'connes-window 'continue-frample->file 'continue-sample->file 'contrast-control 'contrast-control-amp 'contrast-control-bounds 'contrast-control? 'contrast-enhancement 'controls->channel 'convolution 'convolve 'convolve-files 'convolve-selection-with 'convolve-with 'convolve? 'copy-context 'copy-sampler 'current-edit-position 'current-font 'cursor 'cursor-color 'cursor-context 'cursor-cross 'cursor-in-middle 'cursor-in-view 'cursor-line 'cursor-location-offset 'cursor-on-left 'cursor-on-right 'cursor-position 'cursor-size 'cursor-style 'cursor-update-interval 'dac-combines-channels 'dac-size 'data-color 'sample-type 'data-location 'data-size 'db->linear 'default-output-chans 'default-output-sample-type 'default-output-header-type 'default-output-srate 'define-envelope 'degrees->radians 'delay 'delay-tick 'delay? 'delete-colormap 'delete-mark 'delete-marks 'delete-sample 'delete-samples 'delete-samples-and-smooth 'delete-selection 'delete-selection-and-smooth 'delete-transform 'dialog-widgets 'disk-kspace 'display-edits 'dolph-chebyshev-window 'dont-normalize 'dot-product 'dot-size 'draw-axes 'draw-dot 'draw-dots 'draw-line 'draw-lines 'draw-mark-hook 'draw-mix-hook 'draw-string 'drop-hook 'during-open-hook 'edit-fragment 'edit-header-dialog 'edit-hook 'edit-list->function 'edit-position 'edit-tree 'edits 'edot-product 'env 'env-channel 'env-channel-with-base 'env-interp 'env-selection 'env-sound 'env? 'enved-add-point 'enved-amplitude 'enved-base 'enved-clip? 'enved-delete-point 'enved-dialog 'enved-envelope 'enved-filter 'enved-filter-order 'enved-hook 'enved-in-dB 'enved-move-point 'enved-power 'enved-spectrum 'enved-srate 'enved-style 'enved-target 'enved-wave? 'enved-waveform-color 'envelope-exponential 'envelope-linear 'eps-bottom-margin 'eps-file 'eps-left-margin 'eps-size 'even-multiple 'even-weight 'exit 'exit-hook 'expand-control 'expand-control-bounds 'expand-control-hop 'expand-control-jitter 'expand-control-length 'expand-control-ramp 'expand-control? 'exponential-window 'fft 'fft-log-frequency 'fft-log-magnitude 'fft-window 'fft-window-alpha 'fft-window-beta 'fft-with-phases 'file->array 'file->frample 'file->frample? 'file->sample 'file->sample? 'file->string 'file-name 'file-write-date 'fill-polygon 'fill-rectangle 'filter 'filtered-comb 'filtered-comb? 'filter-channel 'filter-control-coeffs 'filter-control-envelope 'filter-control-in-dB 'filter-control-in-hz 'filter-control-order 'filter-control-waveform-color 'filter-control? 'filter-selection 'filter-sound 'filter? 'find-dialog 'find-mark 'find-sound 'finish-progress-report 'fir-filter 'fir-filter? 'flat-top-window 'focus-widget 'foreground-color 'forget-region 'formant 'formant-bank 'formant-bank? 'formant? 'firmant 'firmant? 'comb-bank 'comb-bank? 'all-pass-bank 'all-pass-bank? 'filtered-comb-bank 'filtered-comb-bank? 'make-comb-bank 'make-all-pass-bank 'make-filtered-comb-bank 'fourier-transform 'free-player 'free-sampler 'gaussian-window 'gc-off 'gc-on ;'gl-graph->ps 'glSpectrogram 'goto-listener-end 'granulate 'granulate? 'graph 'graph->ps 'graph-as-sonogram 'graph-as-spectrogram 'graph-as-wavogram 'graph-color 'graph-cursor 'graph-data 'graph-dots 'graph-dots-and-lines 'graph-filled 'graph-hook 'graph-lines 'graph-lollipops 'graph-once 'graph-style 'graphs-horizontal 'grid-density 'haar-transform 'hamming-window 'hann-poisson-window 'hann-window 'header-type 'help-dialog 'help-hook 'hide-widget 'highlight-color 'html-dir 'html-program 'hz->radians 'iir-filter 'iir-filter? 'in 'in-any 'ina 'inb 'info-dialog 'initial-graph-hook 'insert-file-dialog 'insert-region 'insert-sample 'insert-samples 'insert-samples-with-origin 'insert-selection 'insert-silence 'insert-sound 'just-sounds 'kaiser-window 'key 'key-binding 'key-press-hook 'keyboard-no-action 'peak-env-dir ; 'ladspa-activate 'ladspa-cleanup 'ladspa-connect-port 'ladspa-deactivate 'ladspa-descriptor 'ladspa-dir ; 'ladspa-instantiate 'ladspa-run 'ladspa-run-adding 'ladspa-set-run-adding-gain 'list-ladspa 'init-ladspa 'apply-ladspa 'analyse-ladspa 'left-sample 'linear->db 'lisp-graph 'lisp-graph-hook 'lisp-graph-style 'lisp-graph? 'listener-click-hook 'listener-color 'listener-font 'listener-prompt 'listener-selection 'listener-text-color 'little-endian? 'locsig 'locsig-ref 'locsig-reverb-ref 'locsig-reverb-set! 'locsig-set! 'locsig-type 'locsig? 'log-freq-start 'main-menu 'main-widgets 'make-all-pass 'make-asymmetric-fm 'make-moving-average 'make-moving-max 'make-moving-norm 'make-bezier 'make-color 'make-comb 'make-filtered-comb 'make-convolve 'make-delay 'make-env 'make-fft-window 'make-file->frample 'make-file->sample 'make-filter 'make-fir-coeffs 'make-fir-filter 'make-formant 'make-firmant 'make-formant-bank 'make-granulate 'make-graph-data 'make-iir-filter 'make-locsig 'make-mix-sampler 'make-move-sound 'make-notch 'make-one-pole 'make-one-pole-all-pass 'make-one-zero 'make-oscil 'make-phase-vocoder 'make-player 'make-polyshape 'make-polywave 'make-pulse-train 'make-rand 'make-rand-interp 'make-readin 'make-region 'make-region-sampler 'make-sample->file 'make-sampler 'make-sawtooth-wave 'make-nrxysin 'make-nrxycos 'make-rxyk!cos 'make-rxyk!sin 'make-snd->sample 'make-square-wave 'make-src 'make-ssb-am 'make-ncos 'make-nsin 'make-table-lookup 'make-triangle-wave 'make-two-pole 'make-two-zero 'make-variable-graph 'make-float-vector 'make-wave-train 'map-channel 'mark-click-hook 'mark-color 'mark-context 'mark-drag-hook 'mark-home 'mark-hook 'mark-name 'mark-properties 'mark-property 'mark-sample 'mark-sync 'mark-sync-max 'mark-tag-height 'mark-tag-width 'mark? 'marks 'max-regions 'max-transform-peaks 'maxamp 'maxamp-position 'menu-widgets 'min-dB 'mix 'mix-amp 'mix-amp-env 'mix-click-hook 'mix-color 'mix-dialog-mix 'mix-drag-hook 'mix-file-dialog 'mix-length 'mix-home 'mix-name 'mix-position 'mix-properties 'mix-property 'mix-region 'mix-release-hook 'mix-sync 'mix-sync-max 'mix-sampler? 'mix-selection 'mix-speed 'mix-tag-height 'mix-tag-width 'mix-tag-y 'mix-float-vector 'mix-waveform-height 'mix? 'mixes 'mouse-click-hook 'mouse-drag-hook 'mouse-enter-graph-hook 'mouse-enter-label-hook 'mouse-enter-listener-hook 'mouse-enter-text-hook 'mouse-leave-graph-hook 'mouse-leave-label-hook 'mouse-leave-listener-hook 'mouse-leave-text-hook 'mouse-press-hook 'move-locsig 'move-sound 'move-sound? 'moving-average 'moving-average? 'moving-max 'moving-max? 'moving-norm 'moving-norm? 'mus-aifc 'mus-aiff 'mus-alaw 'mus-alsa-buffer-size 'mus-alsa-buffers 'mus-alsa-capture-device 'mus-alsa-device 'mus-alsa-playback-device 'mus-alsa-squelch-warning 'mus-apply 'mus-array-print-length 'mus-float-equal-fudge-factor 'mus-b24int 'mus-bdouble 'mus-bdouble-unscaled 'mus-bfloat 'mus-bfloat-unscaled 'mus-bicsf 'mus-bint 'mus-bintn 'mus-bshort 'mus-byte 'mus-bytes-per-sample 'mus-caff 'mus-channel 'mus-channels 'mus-chebyshev-first-kind 'mus-chebyshev-second-kind 'mus-clipping 'mus-close 'mus-data 'mus-sample-type->string 'mus-sample-type-name 'mus-describe 'mus-error-hook 'mus-error-type->string 'mus-expand-filename 'mus-feedback 'mus-feedforward 'mus-fft 'mus-file-buffer-size 'mus-file-clipping 'mus-file-name 'mus-frequency 'mus-generator? 'mus-header-raw-defaults 'mus-header-type->string 'mus-header-type-name 'mus-hop 'mus-increment 'mus-input? 'mus-interp-all-pass 'mus-interp-bezier 'mus-interp-hermite 'mus-interp-lagrange 'mus-interp-linear 'mus-interp-none 'mus-interp-sinusoidal 'mus-interp-type 'mus-interpolate 'mus-ircam 'mus-l24int 'mus-ldouble 'mus-ldouble-unscaled 'mus-length 'mus-lfloat 'mus-lfloat-unscaled 'mus-lint 'mus-lintn 'mus-location 'mus-lshort 'mus-max-malloc 'mus-max-table-size 'mus-file-mix 'mus-mulaw 'mus-name 'mus-next 'mus-nist 'mus-offset 'mus-order 'mus-oss-set-buffers 'mus-out-format 'mus-output? 'mus-phase 'mus-ramp 'mus-rand-seed 'mus-random 'mus-raw 'mus-reset 'mus-riff 'mus-run 'mus-scaler 'mus-set-formant-radius-and-frequency 'mus-sound-chans 'mus-sound-comment 'mus-sound-sample-type 'mus-sound-data-location 'mus-sound-datum-size 'mus-sound-duration 'mus-sound-forget 'mus-sound-framples 'mus-sound-header-type 'mus-sound-length 'mus-sound-loop-info 'mus-sound-mark-info 'mus-sound-maxamp 'mus-sound-maxamp-exists? 'mus-sound-path 'mus-sound-prune 'mus-sound-report-cache 'mus-sound-samples 'mus-sound-srate 'mus-sound-type-specifier 'mus-sound-write-date 'mus-soundfont 'mus-srate 'mus-svx 'mus-ubshort 'mus-ubyte 'mus-ulshort 'mus-unknown-sample 'mus-unknown-header 'mus-voc 'mus-width 'mus-xcoeff 'mus-xcoeffs 'mus-ycoeff 'mus-ycoeffs 'name-click-hook 'new-sound 'new-sound-dialog 'new-sound-hook 'new-widget-hook 'next-sample 'normalize-by-channel 'normalize-by-sound 'normalize-channel 'normalize-globally 'notch 'notch? 'odd-multiple 'odd-weight 'one-pole 'one-pole? 'one-pole-all-pass 'one-pole-all-pass? 'one-zero 'one-zero? 'open-file-dialog 'open-file-dialog-directory 'open-hook 'open-raw-sound 'open-raw-sound-hook 'open-sound 'orientation-hook 'oscil 'oscil? 'out-any 'outa 'outb 'outc 'outd 'output-comment-hook 'override-samples-with-origin 'pad-channel 'partials->polynomial 'partials->wave 'parzen-window 'pausing 'peaks 'peaks-font 'phase-partials->wave 'phase-vocoder 'phase-vocoder-amp-increments 'phase-vocoder-amps 'phase-vocoder-freqs 'phase-vocoder-phase-increments 'phase-vocoder-phases 'phase-vocoder? 'play 'play-arrow-size 'play-hook 'player-home 'player? 'players 'playing 'poisson-window 'polar->rectangular 'polynomial 'polyshape 'polywave 'polyshape? 'polywave? 'position->x 'position->y 'position-color 'preferences-dialog 'previous-sample 'print-dialog 'print-length 'progress-report 'pulse-train 'pulse-train? 'radians->degrees 'radians->hz 'ramp-channel 'rand 'rand-interp 'rand-interp? 'rand? 'read-mix-sample 'read-only 'read-region-sample 'read-sample 'readin 'readin? 'rectangular->magnitudes 'rectangular->polar 'rectangular-window 'redo 'redo-edit 'region->float-vector 'region-chans 'region-home 'region-framples 'region-graph-style 'region-maxamp 'region-maxamp-position 'region-position 'region-sample 'region-sampler? 'region-srate 'region? 'regions 'remember-sound-state 'remove-from-menu 'status-report 'reset-controls 'reset-listener-cursor 'restore-controls 'restore-region 'reverb-control-decay 'reverb-control-feedback 'reverb-control-length 'reverb-control-length-bounds 'reverb-control-lowpass 'reverb-control-scale 'reverb-control-scale-bounds 'reverb-control? 'reverse-channel 'reverse-selection 'reverse-sound 'revert-sound 'riemann-window 'right-sample 'ring-modulate 'rv2-window 'rv3-window 'rv4-window 'samaraki-window 'sample 'sample->file 'sample->file? 'sampler-at-end? 'sampler-home 'sampler-position 'sampler? 'samples 'samples->seconds 'sash-color 'save-controls 'save-dir 'save-edit-history 'save-envelopes 'save-hook 'save-listener 'save-marks 'save-region 'save-region-dialog 'save-selection 'save-selection-dialog 'save-sound 'save-sound-as 'save-sound-dialog 'save-state 'save-state-file 'save-state-hook 'sawtooth-wave 'sawtooth-wave? 'scale-by 'scale-channel 'scale-selection-by 'scale-selection-to 'scale-to 'scan-channel 'script-arg 'script-args 'search-procedure 'seconds->samples 'select-all 'select-channel 'select-channel-hook 'select-sound 'select-sound-hook 'selected-channel 'selected-data-color 'selected-graph-color 'selected-sound 'selection-chans 'selection-color 'selection-context 'selection-creates-region 'selection-framples 'selection-maxamp 'selection-maxamp-position 'selection-member? 'selection-position 'selection-srate 'selection? 'short-file-name 'show-all-axes 'show-all-axes-unlabelled 'show-bare-x-axis 'show-axes 'show-controls 'show-grid 'show-indices 'show-full-duration 'show-full-range 'initial-beg 'initial-dur 'show-listener 'show-marks 'show-mix-waveforms 'show-no-axes 'show-selection 'show-selection-transform 'show-sonogram-cursor 'show-transform-peaks 'show-widget 'show-x-axis 'show-x-axis-unlabelled 'show-y-zero 'sinc-width 'nrxysin 'nrxysin? 'nrxycos 'nrxycos? 'rxyk!cos 'rxyk!cos? 'rxyk!sin 'rxyk!sin? 'smooth-channel 'smooth-selection 'smooth-sound 'snd->sample 'snd->sample? 'snd-error 'snd-error-hook 'snd-gcs 'snd-help 'snd-font 'snd-color 'snd-print 'snd-spectrum 'snd-tempnam 'snd-url 'snd-urls 'snd-version 'snd-warning 'snd-warning-hook 'sound-file-extensions 'sound-file? 'sound-files-in-directory 'sound-loop-info 'sound-properties 'sound-property 'sound-widgets 'sound? 'soundfont-info 'sounds 'spectrum-end 'spectro-hop 'spectrum-start 'spectro-x-angle 'spectro-x-scale 'spectro-y-angle 'spectro-y-scale 'spectro-z-angle 'spectro-z-scale 'spectrum 'speed-control 'speed-control-as-float 'speed-control-as-ratio 'speed-control-as-semitone 'speed-control-bounds 'speed-control-style 'speed-control-tones 'square-wave 'square-wave? 'squelch-update 'srate 'src 'src-channel 'src-selection 'src-sound 'src? 'ssb-am 'ssb-am? 'start-playing 'start-playing-hook 'start-playing-selection-hook 'start-progress-report 'stop-player 'stop-playing 'stop-playing-hook 'stop-playing-selection-hook 'ncos 'ncos? 'nsin 'nsin? 'swap-channels 'sync 'sync-style 'sync-none 'sync-all 'sync-by-sound 'sync-max 'syncd-marks 'table-lookup 'table-lookup? 'tap 'tap? 'temp-dir 'text-focus-color 'time-graph 'time-graph-style 'time-graph-type 'time-graph? 'tiny-font 'tracking-cursor-style 'transform->float-vector 'transform-dialog 'transform-framples 'transform-graph 'transform-graph-style 'transform-graph-type 'transform-graph? 'transform-normalization 'transform-sample 'transform-size 'transform-type 'transform? 'triangle-wave 'triangle-wave? 'tukey-window 'two-pole 'two-pole? 'two-zero 'two-zero? 'ultraspherical-window 'unbind-key 'undo 'undo-edit 'undo-hook 'unselect-all 'update-hook 'update-lisp-graph 'update-sound 'update-time-graph 'update-transform-graph 'variable-graph? 'float-vector 'float-vector* 'float-vector+ 'float-vector->channel 'float-vector->string 'float-vector-add! 'length 'float-vector-max 'float-vector-min 'float-vector-move! 'float-vector-multiply! 'float-vector-offset! 'float-vector-peak 'float-vector-ref 'reverse! 'float-vector-scale! 'float-vector-set! 'float-vector-subseq 'float-vector-subtract! 'float-vector? 'walsh-transform 'wave-train 'wave-train? 'wavelet-transform 'wavelet-type 'wavo-hop 'wavo-trace 'welch-window 'widget-position 'widget-size 'widget-text 'window-height 'window-width 'window-x 'window-y 'with-background-processes 'with-file-monitor 'with-gl 'with-mix-tags 'with-relative-panes 'with-tracking-cursor 'with-verbose-cursor 'with-inset-graph 'with-interrupts 'with-pointer-focus 'with-smpte-label 'with-toolbar 'with-tooltips 'with-menu-icons 'save-as-dialog-src 'save-as-dialog-auto-comment 'x->position 'x-axis-as-clock 'x-axis-as-percentage 'x-axis-in-beats 'x-axis-in-measures 'x-axis-in-samples 'x-axis-in-seconds 'x-axis-label 'x-axis-style 'x-bounds 'x-position-slider 'x-zoom-slider 'xramp-channel 'y->position 'y-axis-label 'y-bounds 'y-position-slider 'y-zoom-slider 'zero-pad 'zoom-color 'zoom-focus-active 'zoom-focus-left 'zoom-focus-middle 'zoom-focus-right 'zoom-focus-style))) (for-each (lambda (n) (if (not (defined? n)) (set! undef (cons n undef)))) names) (if (pair? undef) (snd-display #__line__ ";undefined: ~A" undef))) )) ;;; ---------------- test 4: sndlib ---------------- (if (or (not (provided? 'snd-examp.scm)) (and (defined? 'ramp) ; why this? protection against funcs? (list? ramp))) (load "examp.scm")) (require snd-mix.scm snd-env.scm) (definstrument (out-samps beg chan data) (let ((len (length data))) (do ((i 0 (+ i 1))) ((= i len)) (out-any (+ beg i) (data i) chan)))) (definstrument (out-samps-invert beg chan data) (let ((len (length data))) (do ((i 0 (+ i 1))) ((= i len)) (out-any (+ beg i) (- (data i)) chan)))) (define (snd_test_4) (define (frame->byte file fr) (+ (mus-sound-data-location file) (* (mus-sound-chans file) (mus-sound-datum-size file) fr))) (do ((clmtest 0 (+ 1 clmtest))) ((= clmtest tests)) (log-mem clmtest) (clear-listener) (let ((chns (mus-sound-chans "oboe.snd")) (dl (mus-sound-data-location "oboe.snd")) (fr (mus-sound-framples "oboe.snd")) (smps (mus-sound-samples "oboe.snd")) (len (mus-sound-length "oboe.snd")) (size (mus-sound-datum-size "oboe.snd")) (com (mus-sound-comment "oboe.snd")) (sr (mus-sound-srate "oboe.snd")) (m1 (mus-sound-maxamp-exists? "oboe.snd")) (mal (mus-sound-maxamp "oboe.snd")) (mz (mus-sound-maxamp "z.snd")) (bytes (mus-bytes-per-sample (mus-sound-sample-type "oboe.snd")))) (if (or (not (= (car mz) 0)) (fneq (cadr mz) 0.0)) (snd-display #__line__ ";mus-sound-maxamp z.snd: ~A (~A ~A)" mz (not (= (car mz) 0)) (fneq (cadr mz) 0.0))) (let ((formats (list mus-bshort mus-lshort mus-mulaw mus-alaw mus-byte mus-ubyte mus-bfloat mus-lfloat mus-bint mus-lint mus-bintn mus-lintn mus-b24int mus-l24int mus-bdouble mus-ldouble mus-ubshort mus-ulshort mus-bdouble-unscaled mus-ldouble-unscaled mus-bfloat-unscaled mus-lfloat-unscaled)) (sizes (list 2 2 1 1 1 1 4 4 4 4 4 4 3 3 8 8 2 2 8 8 4 4))) (for-each (lambda (frm siz) (if (not (= (mus-bytes-per-sample frm) siz)) (snd-display #__line__ ";mus-bytes-per-sample ~A: ~A" (mus-sample-type-name frm) siz))) formats sizes)) (if (not (string=? (mus-sample-type->string mus-bshort) "mus-bshort")) (snd-display #__line__ ";mus-sample-type->string: ~A" (mus-sample-type->string mus-bshort))) (if (not (string=? (mus-header-type->string mus-aifc) "mus-aifc")) (snd-display #__line__ ";mus-header-type->string: ~A" (mus-header-type->string mus-aifc))) (mus-sound-report-cache "hiho.tmp") (let ((p (open-input-file "hiho.tmp"))) (if (not p) (snd-display #__line__ ";mus-sound-report-cache->hiho.tmp failed?") (let ((line (read-line p))) (if (or (not (string? line)) (and (not (string=? line "sound table:")) (not (string=? line (string-append "sound table:" (string #\newline)))))) (snd-display #__line__ ";print-cache 1: ~A?" line)) (close-input-port p) (delete-file "hiho.tmp")))) (if (not (= chns 1)) (snd-display #__line__ ";oboe: mus-sound-chans ~D?" chns)) (if (not (= dl 28)) (snd-display #__line__ ";oboe: mus-sound-data-location ~D (~A)?" dl (= dl 28))) (if (not (= fr 50828)) (snd-display #__line__ ";oboe: mus-sound-framples ~D?" fr)) (if (not (= smps 50828)) (snd-display #__line__ ";oboe: mus-sound-samples ~D?" smps)) (if (not (= len (+ 28 (* 2 50828)))) (snd-display #__line__ ";oboe: mus-sound-length ~D?" len)) (if (not (= size 2)) (snd-display #__line__ ";oboe: mus-sound-datum-size ~D?" size)) (if (not (= bytes 2)) (snd-display #__line__ ";oboe: sound-bytes ~D?" bytes)) (if (not (= sr 22050)) (snd-display #__line__ ";oboe: mus-sound-srate ~D?" sr)) (if (and m1 (= clmtest 0)) (snd-display #__line__ ";oboe: mus-sound-maxamp-exists before maxamp: ~A" m1)) (if (not (mus-sound-maxamp-exists? "oboe.snd")) (snd-display #__line__ ";oboe: not mus-sound-maxamp-exists after maxamp: ~A" (mus-sound-maxamp-exists? "oboe.snd"))) (if (= clmtest 0) (let ((vals (mus-header-raw-defaults))) (if (or (not (list? vals)) (not (= (length vals) 3))) (snd-display #__line__ ";mus-header-raw-defaults: ~A" vals) (let ((sr (car vals)) (chns (cadr vals)) (frm (caddr vals))) (if (not (= sr 44100)) (snd-display #__line__ ";mus-header-raw-defaults srate: ~A" sr)) (if (not (= chns 2)) (snd-display #__line__ ";mus-header-raw-defaults chns: ~A" chns)) (if (not (= frm mus-bshort)) (snd-display #__line__ ";mus-header-raw-defaults format: ~A: ~A" frm (mus-sample-type-name frm))))))) (set! (mus-header-raw-defaults) (list 12345 3 mus-bdouble-unscaled)) (let ((vals (mus-header-raw-defaults))) (if (or (not (list? vals)) (not (= (length vals) 3))) (snd-display #__line__ ";set mus-header-raw-defaults: ~A" vals) (let ((sr (car vals)) (chns (cadr vals)) (frm (caddr vals))) (if (not (= sr 12345)) (snd-display #__line__ ";set mus-header-raw-defaults srate: ~A" sr)) (if (not (= chns 3)) (snd-display #__line__ ";set mus-header-raw-defaults chns: ~A" chns)) (if (not (= frm mus-bdouble-unscaled)) (snd-display #__line__ ";set mus-header-raw-defaults format: ~A: ~A" frm (mus-sample-type-name frm)))))) (set! (mus-header-raw-defaults) (list 44100 2 mus-bshort)) (let ((str (strftime "%d-%b %H:%M %Z" (localtime (mus-sound-write-date "oboe.snd"))))) (if (not (string=? str "23-Nov 06:56 PST")) (snd-display #__line__ ";mus-sound-write-date oboe.snd: ~A?" str))) (let ((str (strftime "%d-%b %H:%M %Z" (localtime (mus-sound-write-date "pistol.snd"))))) (if (not (string=? str "23-Nov 06:56 PST")) (snd-display #__line__ ";mus-sound-write-date pistol.snd: ~A?" str))) (let ((index (open-sound "oboe.snd")) (long-file-name (let ((name "test")) (do ((i 0 (+ i 1))) ((= i 10)) ; 40 is about the limit in Linux (256 char limit here from OS, not Snd) (set! name (string-append name "-test"))) (string-append name ".snd")))) (if (variable-graph? index) (snd-display #__line__ ";variable-graph thinks anything is a graph...")) (if (player? index) (snd-display #__line__ ";player? thinks anything is a player...")) (if (not (sound? index)) (snd-display #__line__ ";~A is not a sound?" index)) (if (sound? #f) (snd-display #__line__ ";sound? #f -> #t?")) (if (sound? #t) (snd-display #__line__ ";sound? #t -> #t?")) (save-sound-as long-file-name index) (close-sound index) (set! index (open-sound long-file-name)) (if (not (sound? index)) (snd-display #__line__ ";can't find test...snd")) (if (or (< (length (file-name index)) (length long-file-name)) (< (length (short-file-name index)) (length long-file-name))) (snd-display #__line__ ";file-name lengths: ~A ~A ~A" (length (file-name index)) (length (short-file-name index)) (length long-file-name))) (close-sound index) (mus-sound-forget long-file-name) (delete-file long-file-name)) (let ((old-sound-path *mus-sound-path*) (new-path (if (provided? 'osx) "/Users/bil/sf1" "/home/bil/sf1"))) (set! *mus-sound-path* (list new-path)) (let ((ind (catch #t (lambda () (open-sound "o2.bicsf")) (lambda args #f)))) (if (not (sound? ind)) (snd-display #__line__ ";*mus-sound-path*: ~A~%" ind) (begin (close-sound ind) (set! (mus-sound-path) (list new-path)) (set! ind (catch #t (lambda () (open-sound "o2.bicsf")) (lambda args #f))) (if (not (sound? ind)) (snd-display #__line__ ";(mus-sound-path): ~A~%" ind) (close-sound ind))))) (set! *mus-sound-path* old-sound-path)) (let ((fsnd (string-append sf-dir "forest.aiff"))) (if (file-exists? fsnd) (begin (system (format #f "cp ~A fmv.snd" fsnd)) (let ((index (open-sound "fmv.snd"))) (if (not (equal? (sound-loop-info index) (mus-sound-loop-info fsnd))) (snd-display #__line__ ";loop-info: ~A ~A" (sound-loop-info index) (mus-sound-loop-info fsnd))) (set! (sound-loop-info index) (list 12000 14000 1 2 3 4)) (if (not (equal? (sound-loop-info index) (list 12000 14000 1 2 3 4 1 1))) (snd-display #__line__ ";set loop-info: ~A" (sound-loop-info index))) (save-sound-as "fmv1.snd" index :header-type mus-aifc) (close-sound index) (if (not (equal? (mus-sound-loop-info "fmv1.snd") (list 12000 14000 1 2 3 4 1 1))) (snd-display #__line__ ";saved loop-info: ~A" (mus-sound-loop-info "fmv1.snd")))))) (let ((index (open-sound "oboe.snd"))) (save-sound-as "fmv.snd" index :header-type mus-aifc) (close-sound index)) (let ((index (open-sound "fmv.snd"))) (if (not (null? (sound-loop-info index))) (snd-display #__line__ ";null loop-info: ~A" (sound-loop-info index))) (set! (sound-loop-info index) (list 1200 1400 4 3 2 1)) (if (not (equal? (sound-loop-info index) (list 1200 1400 4 3 2 1 1 1))) (snd-display #__line__ ";set null loop-info: ~A" (sound-loop-info index))) (save-sound-as "fmv1.snd" :sound index :header-type mus-aifc) (close-sound index) (if (not (equal? (mus-sound-loop-info "fmv1.snd") (list 1200 1400 4 3 2 1 1 1))) (snd-display #__line__ ";saved null loop-info: ~A" (mus-sound-loop-info "fmv1.snd")))) (let ((index (open-sound "fmv.snd"))) (set! (sound-loop-info) (list 1200 1400 4 3 2 1 1 0)) (if (not (equal? (sound-loop-info index) (list 1200 1400 0 0 2 1 1 0))) (snd-display #__line__ ";set null loop-info (no mode1): ~A" (sound-loop-info index))) (save-sound-as "fmv1.snd" index :header-type mus-aifc) (close-sound index) (if (not (equal? (mus-sound-loop-info "fmv1.snd") (list 1200 1400 0 0 2 1 1 0))) (snd-display #__line__ ";saved null loop-info (no mode1): ~A" (mus-sound-loop-info "fmv1.snd"))))) (if (> (length com) 0) (snd-display #__line__ ";oboe: mus-sound-comment ~A?" com)) (let ((fsnd (string-append sf-dir "nasahal8.wav"))) (if (file-exists? fsnd) (begin (set! com (mus-sound-comment fsnd)) (if (or (not (string? com)) (not (string=? com (string-append "ICRD: 1997-02-22" (string #\newline) "IENG: Paul R. Roger" (string #\newline) "ISFT: Sound Forge 4.0" (string #\newline))))) (snd-display #__line__ ";mus-sound-comment \"nasahal8.wav\") -> ~A?" com))))) (let ((fsnd (string-append sf-dir "8svx-8.snd"))) (if (file-exists? fsnd) (begin (set! com (mus-sound-comment fsnd)) (if (or (not (string? com)) (not (string=? com "File created by Sound Exchange "))) (snd-display #__line__ ";mus-sound-comment \"8svx-8.snd\") -> ~A?" com))))) (let ((fsnd (string-append sf-dir "sun-16-afsp.snd"))) (if (file-exists? fsnd) (begin (set! com (mus-sound-comment fsnd)) (if (or (not (string? com)) (not (string=? com "AFspdate:1981/02/11 23:03:34 UTC"))) (snd-display #__line__ ";mus-sound-comment \"sun-16-afsp.snd\") -> ~A?" com))))) (let ((fsnd (string-append sf-dir "smp-16.snd"))) (if (file-exists? fsnd) (begin (set! com (mus-sound-comment fsnd)) (if (or (not (string? com)) (not (string=? com "Converted using Sox. "))) (snd-display #__line__ ";mus-sound-comment \"smp-16.snd\") -> ~A?" com))))) (let ((fsnd (string-append sf-dir "d40130.au"))) (if (file-exists? fsnd) (begin (set! com (mus-sound-comment fsnd)) (if (or (not (string? com)) (not (string=? com "1994 Jesus Villena"))) (snd-display #__line__ ";mus-sound-comment \"d40130.au\") -> ~A?" com))))) (let ((fsnd (string-append sf-dir "wood.maud"))) (if (file-exists? fsnd) (begin (set! com (mus-sound-comment fsnd)) (if (or (not (string? com)) (not (string=? com "file written by SOX MAUD-export "))) (snd-display #__line__ ";mus-sound-comment \"wood.maud\") -> ~A?" com))))) (let ((fsnd (string-append sf-dir "addf8.sf_mipseb"))) (if (file-exists? fsnd) (begin (set! com (mus-sound-comment fsnd)) (if (or (not (string? com)) (not (string=? com "date=\"Feb 11 18:03:34 1981\" info=\"Original recorded at 20 kHz, 15-bit D/A, digitally filtered and resampled\" speaker=\"AMK female\" text=\"Add the sum to the product of these three.\" "))) (snd-display #__line__ ";mus-sound-comment \"addf8.sf_mipseb\") -> ~A?" com))))) (let ((fsnd (string-append sf-dir "mary-sun4.sig"))) (if (file-exists? fsnd) (begin (set! com (mus-sound-comment fsnd)) (if (or (not (string? com)) (not (string=? com (string-append "MARY HAD A LITTLE LAMB" (string #\newline))))) (snd-display #__line__ ";mus-sound-comment \"mary-sun4.sig\") -> ~A?" com))))) (let ((fsnd (string-append sf-dir "nasahal.pat"))) (if (file-exists? fsnd) (begin (set! com (mus-sound-comment fsnd)) (if (or (not (string? com)) (not (string=? com "This patch saved with Sound Forge 3.0."))) (snd-display #__line__ ";mus-sound-comment \"nasahal.pat\") -> ~A?" com))))) (let ((fsnd (string-append sf-dir "next-16.snd"))) (if (file-exists? fsnd) (begin (set! com (mus-sound-comment fsnd)) (if (or (not (string? com)) (not (string=? com ";Written on Mon 1-Jul-91 at 12:10 PDT at localhost (NeXT) using Allegro CL and clm of 25-June-91"))) (snd-display #__line__ ";mus-sound-comment \"next-16.snd\") -> ~A?" com))))) (let ((fsnd (string-append sf-dir "wood16.nsp"))) (if (file-exists? fsnd) (begin (set! com (mus-sound-comment fsnd)) (if (or (not (string? com)) (not (string=? com "Created by Snack "))) (snd-display #__line__ ";mus-sound-comment \"wood16.nsp\") -> ~A?" com))))) (let ((fsnd (string-append sf-dir "wood.sdx"))) (if (file-exists? fsnd) (begin (set! com (mus-sound-comment fsnd)) (if (or (not (string? com)) (not (string=? com "1994 Jesus Villena"))) (snd-display #__line__ ";mus-sound-comment \"wood.sdx\") -> ~A?" com))))) (let ((fsnd (string-append sf-dir "clmcom.aif"))) (if (file-exists? fsnd) (begin (set! com (mus-sound-comment fsnd)) (if (or (not (string? com)) (not (string=? com "this is a comment"))) (snd-display #__line__ ";mus-sound-comment \"clmcom.aif\") -> ~A?" com))))) (let ((fsnd (string-append sf-dir "anno.aif"))) (if (file-exists? fsnd) (begin (set! com (mus-sound-comment fsnd)) (if (or (not (string? com)) (not (string=? com (string-append "1994 Jesus Villena" (string #\newline))))) (snd-display #__line__ ";mus-sound-comment \"anno.aif\") -> ~A?" com))))) (let ((fsnd (string-append sf-dir "telephone.wav"))) (if (file-exists? fsnd) (begin (set! com (mus-sound-comment fsnd)) (if (or (not (string? com)) (not (string=? com (string-append "sample_byte_format -s2 01" (string #\newline) "channel_count -i 1" (string #\newline) "sample_count -i 36461" (string #\newline) "sample_rate -i 16000" (string #\newline) "sample_n_bytes -i 2" (string #\newline) "sample_sig_bits -i 16" (string #\newline))))) (snd-display #__line__ ";mus-sound-comment \"telephone.wav\") -> ~A?" com))))) (if (not (string? (mus-sound-comment (string-append sf-dir "traffic.aiff")))) (snd-display #__line__ ";mus-sound-comment traffic: ~A" (mus-sound-comment (string-append sf-dir "traffic.aiff")))) (if (= clmtest 0) (begin (if (fneq (cadr mal) .14724) (snd-display #__line__ ";oboe: mus-sound-maxamp ~F?" (cadr mal))) (if (not (= (car mal) 24971)) (snd-display #__line__ ";oboe: mus-sound-maxamp at ~D?" (car mal))))) (if (and (not (= (mus-sound-type-specifier "oboe.snd") #x646e732e)) ;little endian reader (not (= (mus-sound-type-specifier "oboe.snd") #x2e736e64))) ;big endian reader (snd-display #__line__ ";oboe: mus-sound-type-specifier: ~X?" (mus-sound-type-specifier "oboe.snd"))) (if (not (string=? (strftime "%d-%b-%Y %H:%M" (localtime (file-write-date "oboe.snd"))) "23-Nov-2012 06:56")) (snd-display #__line__ ";oboe: file-write-date: ~A?" (strftime "%d-%b-%Y %H:%M" (localtime (file-write-date "oboe.snd"))))) ; (mus-sound-forget "oboe.snd") (let ((lasth (do ((i 1 (+ i 1))) ((string=? (mus-header-type-name i) "unknown") i)))) (if (< lasth 50) (snd-display #__line__ ";header-type[~A] = ~A" lasth (mus-header-type-name lasth)))) (let ((lasth (do ((i 1 (+ i 1))) ((string=? (mus-sample-type-name i) "unknown") i)))) (if (< lasth 10) (snd-display #__line__ ";sample-type[~A] = ~A" lasth (mus-sample-type-name lasth)))) (when with-gui (set! *transform-normalization* dont-normalize) (if (not (= *transform-normalization* dont-normalize)) (snd-display #__line__ ";set-transform-normalization none -> ~A" *transform-normalization*)) (set! *transform-normalization* normalize-globally) (if (not (= *transform-normalization* normalize-globally)) (snd-display #__line__ ";set-transform-normalization globally -> ~A" *transform-normalization*)) (set! *transform-normalization* normalize-by-channel) (if (not (= *transform-normalization* normalize-by-channel)) (snd-display #__line__ ";set-transform-normalization channel -> ~A" *transform-normalization*))) (let ((ind (new-sound "fmv.snd" 1 22050 mus-ldouble mus-next "set-samples test" 100))) (set! (samples 10 3) (make-float-vector 3 .1)) (if (not (vequal (channel->float-vector 0 20 ind 0) (float-vector 0 0 0 0 0 0 0 0 0 0 .1 .1 .1 0 0 0 0 0 0 0))) (snd-display #__line__ ";1 set samples 0 for .1: ~A" (channel->float-vector 0 20 ind 0))) (set! (samples 20 3 ind 0) (make-float-vector 3 .1)) (if (not (vequal (channel->float-vector 10 20 ind 0) (float-vector .1 .1 .1 0 0 0 0 0 0 0 .1 .1 .1 0 0 0 0 0 0 0))) (snd-display #__line__ ";2 set samples 10 for .1: ~A" (channel->float-vector 10 20 ind 0))) (set! (samples 30 3 ind 0 #f "a name") (make-float-vector 3 .1)) (if (not (vequal (channel->float-vector 20 20 ind 0) (float-vector .1 .1 .1 0 0 0 0 0 0 0 .1 .1 .1 0 0 0 0 0 0 0))) (snd-display #__line__ ";3 set samples 20 for .1: ~A" (channel->float-vector 20 20 ind 0))) (set! (samples 0 3 ind 0 #f "a name" 0 1) (make-float-vector 3 .2)) (if (not (vequal (channel->float-vector 0 20 ind 0) (float-vector .2 .2 .2 0 0 0 0 0 0 0 .1 .1 .1 0 0 0 0 0 0 0))) (snd-display #__line__ ";4 set samples 0 at 1 for .1: ~A" (channel->float-vector 0 20 ind 0))) (if (not (vequal (channel->float-vector 20 20 ind 0) (make-float-vector 20 0.0))) (snd-display #__line__ ";5 set samples 20 at 1 for .1: ~A" (channel->float-vector 0 20 ind 0))) (let ((nd (new-sound "fmv1.snd" :channels 2))) (float-vector->channel (make-float-vector 10 .5) 0 10 nd 0) (float-vector->channel (make-float-vector 10 .3) 0 10 nd 1) (save-sound-as "fmv1.snd" nd) (close-sound nd)) (if (not (file-exists? "fmv1.snd")) (snd-display #__line__ ";fmv1 not saved??")) (set! (samples 0 10 ind 0 #f "another name" 1) "fmv1.snd") (if (not (vequal (channel->float-vector 0 20 ind 0) (float-vector .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .1 .1 .1 0 0 0 0 0 0 0))) (snd-display #__line__ ";6 set samples 0 at 1 for .1: ~A" (channel->float-vector 0 20 ind 0))) (set! (samples 5 6 ind 0 #f "another name 7" 0) "fmv1.snd") (if (not (vequal (channel->float-vector 0 20 ind 0) (float-vector .3 .3 .3 .3 .3 .5 .5 .5 .5 .5 .5 .1 .1 0 0 0 0 0 0 0))) (snd-display #__line__ ";7 set samples 0 at 1 for .1: ~A" (channel->float-vector 0 20 ind 0))) (revert-sound ind) (set! (samples 0 10 ind 0 #f "another name 8" 1 0 #f) "fmv1.snd") (if (not (vequal (channel->float-vector 0 20 ind 0) (float-vector .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 0 0 0 0 0 0 0 0 0 0))) (snd-display #__line__ ";8 set samples 0 at 1 for .1: ~A" (channel->float-vector 0 20 ind 0))) (set! (samples 10 10 ind 0 #f "another name 9" 0 0) "fmv1.snd") (if (not (vequal (channel->float-vector 0 20 ind 0) (float-vector 0 0 0 0 0 0 0 0 0 0 .5 .5 .5 .5 .5 .5 .5 .5 .5 .5))) (snd-display #__line__ ";9 set samples 0 at 1 for .1: ~A" (channel->float-vector 0 20 ind 0))) (set! (samples 20 10) "fmv1.snd") (if (not (vequal (channel->float-vector 10 20 ind 0) (make-float-vector 20 .5))) (snd-display #__line__ ";10 set samples 0 at 1 for .1: ~A" (channel->float-vector 10 20 ind 0))) (revert-sound ind) (set! (samples 0 10 ind 0 #t "another name" 1 0 #f) "fmv1.snd") (if (not (= (framples ind 0) 10)) (snd-display #__line__ ";11 set-samples truncate to ~A" (framples ind 0))) (revert-sound ind) (delete-file "fmv1.snd") ;; now try to confuse it (let ((tag (catch #t (lambda () (set! (samples 0 10 ind 0) "fmv1.snd")) (lambda args (car args))))) (if (not (eq? tag 'no-such-file)) (snd-display #__line__ ";set-samples, no such file: ~A" tag))) (let ((nd (new-sound "fmv1.snd" :channels 1))) (float-vector->channel (make-float-vector 10 .5) 0 10 nd 0) (save-sound-as "fmv1.snd" nd) (close-sound nd)) (let ((tag (catch #t (lambda () (set! (samples 0 10 ind 0 #f "another name" 1) "fmv1.snd")) ; chan 1 does not exist (lambda args (car args))))) (if (not (eq? tag 'no-such-channel)) (snd-display #__line__ ";set-samples no such channel: ~A" tag))) (let ((tag (catch #t (lambda () (set! (samples 0 10 ind 0 #f "another name" -1) "fmv1.snd")) (lambda args (car args))))) (if (not (eq? tag 'no-such-channel)) (snd-display #__line__ ";set-samples no such channel (-1): ~A" tag))) (let ((tag (catch #t (lambda () (set! (samples 0 -10) "fmv1.snd")) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";set-samples (-10): ~A" tag))) (let ((tag (catch #t (lambda () (set! (samples -10 10) "fmv1.snd")) (lambda args (car args))))) (if (not (eq? tag 'no-such-sample)) (snd-display #__line__ ";set-samples (beg -10): ~A" tag))) (close-sound ind)) (let ((len 100)) (for-each (lambda (type allowed-diff) (let ((ind (new-sound "test.snd" 1 22050 mus-ldouble mus-next)) (v (make-float-vector len)) (maxdiff 0.0) (maxpos #f)) (set! (v 0) 0.999) (set! (v 1) -1.0) (set! (v 2) .1) (set! (v 3) -.1) (set! (v 4) .01) (set! (v 5) -.01) (set! (v 4) .001) (set! (v 5) -.001) (set! (v 6) 0.0) (do ((i 7 (+ i 1))) ((= i len)) (let ((val (random 1.9999))) (if (or (> val 2.0) (< val 0.0)) (snd-display #__line__ ";random 2.0 -> ~A?" val)) (set! (v i) (- 1.0 val)))) (float-vector->channel v 0 len ind 0) (save-sound-as "test1.snd" ind :header-type mus-next :sample-type type) (close-sound ind) (set! ind (open-sound "test1.snd")) (let ((v1 (channel->float-vector 0 len ind 0))) (do ((i 0 (+ i 1))) ((= i len)) (let ((diff (abs (- (v i) (v1 i))))) (if (> diff maxdiff) (begin (set! maxdiff diff) (set! maxpos i))))) (if (> maxdiff allowed-diff) (snd-display #__line__ ";[line 2841] ~A: ~A at ~A (~A ~A)" (mus-sample-type-name type) maxdiff maxpos (v maxpos) (v1 maxpos))) (close-sound ind)))) (list mus-bshort mus-lshort mus-mulaw mus-alaw mus-byte mus-lfloat mus-bint mus-lint mus-b24int mus-l24int mus-ubshort mus-ulshort mus-ubyte mus-bfloat mus-bdouble mus-ldouble) (list (expt 2 -15) (expt 2 -15) 0.02 0.02 (expt 2 -7) (expt 2 -23) (expt 2 -23) (expt 2 -23) (expt 2 -23) (expt 2 -23) ; assuming sndlib bits=24 here (if int) (expt 2 -15) (expt 2 -15) (expt 2 -7) (expt 2 -23) (expt 2 -23) (expt 2 -23)))) (let* ((ob (view-sound "oboe.snd")) (samp (sample 1000 ob)) (old-comment (mus-sound-comment "oboe.snd")) (str (string-append "written " (strftime "%a %d-%b-%Y %H:%M %Z" (localtime (current-time)))))) (set! (comment ob) str) (let ((tag (catch #t (lambda () (save-sound-as "test.snd" ob :header-type mus-aifc :sample-type mus-bdouble)) (lambda args (car args))))) (if (eq? tag 'cannot-save) (snd-display #__line__ ";save-sound-as test.snd write trouble"))) (set! *filter-control-in-hz* #t) (let ((ab (open-sound "test.snd"))) (if (not (= (header-type ab) mus-aifc)) (snd-display #__line__ ";save-as aifc -> ~A?" (mus-header-type-name (header-type ab)))) (if (not (= (mus-sound-header-type "test.snd") mus-aifc)) (snd-display #__line__ ";saved-as aifc -> ~A?" (mus-header-type-name (mus-sound-header-type "test.snd")))) (if (fneq (sample 1000 ab) samp) (snd-display #__line__ ";aifc[1000] = ~A?" (sample 1000 ab))) (if (or (not (string? (mus-sound-comment "test.snd"))) (not (string=? (mus-sound-comment "test.snd") str))) (snd-display #__line__ ";output-comment: ~A ~A" (mus-sound-comment "test.snd") str)) (if (or (not (string? (comment ab))) (not (string=? (comment ab) str))) (snd-display #__line__ ";output-comment (comment): ~A ~A" (comment ab) str)) (close-sound ab)) (if (not (equal? old-comment (mus-sound-comment "oboe.snd"))) (snd-display #__line__ ";set-comment overwrote current ~A ~A" old-comment (mus-sound-comment "oboe.snd"))) (set! *filter-control-in-hz* #f) (save-sound-as "test.snd" ob :header-type mus-raw) (let ((ab (open-raw-sound "test.snd" 1 22050 mus-bshort))) (if (not (= (header-type ab) mus-raw)) (snd-display #__line__ ";save-as raw -> ~A?" (mus-header-type-name (header-type ab)))) (if (not (= (mus-sound-header-type "test.snd") mus-raw)) (snd-display #__line__ ";saved-as raw -> ~A?" (mus-header-type-name (mus-sound-header-type "test.snd")))) (if (fneq (sample 1000 ab) samp) (snd-display #__line__ ";raw[1000] = ~A?" (sample 1000 ab))) (close-sound ab)) (save-sound-as "test.snd" ob :header-type mus-nist :sample-type mus-bint) (let ((ab (open-sound "test.snd"))) (if (not (= (header-type ab) mus-nist)) (snd-display #__line__ ";save-as nist -> ~A?" (mus-header-type-name (header-type ab)))) (if (not (= (mus-sound-header-type "test.snd") mus-nist)) (snd-display #__line__ ";saved-as nist -> ~A?" (mus-header-type-name (mus-sound-header-type "test.snd")))) (if (not (= (sample-type ab) mus-bint)) (snd-display #__line__ ";save-as int -> ~A?" (mus-sample-type-name (sample-type ab)))) (if (not (= (mus-sound-sample-type "test.snd") mus-bint)) (snd-display #__line__ ";saved-as int -> ~A?" (mus-sample-type-name (mus-sound-sample-type "test.snd")))) (if (fneq (sample 1000 ab) samp) (snd-display #__line__ ";nist[1000] = ~A?" (sample 1000 ab))) (close-sound ab)) (set! (hook-functions output-comment-hook) ()) (hook-push output-comment-hook (lambda (hook) (set! (hook 'result) (string-append (hook 'comment) " [written by me]")))) (save-sound-as :file "test.snd" :sound ob :header-type mus-riff :sample-type mus-lfloat) (set! (hook-functions output-comment-hook) ()) (let ((ab (open-sound "test.snd"))) (if (not (= (header-type ab) mus-riff)) (snd-display #__line__ ";save-as riff -> ~A?" (mus-header-type-name (header-type ab)))) (if (not (= (mus-sound-header-type "test.snd") mus-riff)) (snd-display #__line__ ";saved-as riff -> ~A?" (mus-header-type-name (mus-sound-header-type "test.snd")))) (if (not (= (sample-type ab) mus-lfloat)) (snd-display #__line__ ";save-as float -> ~A?" (mus-sample-type-name (sample-type ab)))) (if (not (= (mus-sound-sample-type "test.snd") mus-lfloat)) (snd-display #__line__ ";saved-as float -> ~A?" (mus-sample-type-name (mus-sound-sample-type "test.snd")))) (if (fneq (sample 1000 ab) samp) (snd-display #__line__ ";riff[1000] = ~A?" (sample 1000 ab))) (if (or (not (string? (comment ab))) (not (string=? (comment ab) (string-append "written " (strftime "%a %d-%b-%Y %H:%M %Z" (localtime (current-time))) " [written by me]")))) (snd-display #__line__ ";output-comment-hook: ~A~%(~A)" (comment ab) (mus-sound-comment "test.snd"))) (close-sound ab)) (save-sound-as "test.snd" ob :header-type mus-aiff :sample-type mus-b24int) (let ((ab (open-sound "test.snd"))) (if (not (= (header-type ab) mus-aiff)) (snd-display #__line__ ";save-as aiff -> ~A?" (mus-header-type-name (header-type ab)))) (if (not (= (mus-sound-header-type "test.snd") mus-aiff)) (snd-display #__line__ ";saved-as aiff -> ~A?" (mus-header-type-name (mus-sound-header-type "test.snd")))) (if (not (= (sample-type ab) mus-b24int)) (snd-display #__line__ ";save-as 24-bit -> ~A?" (mus-sample-type-name (sample-type ab)))) (if (not (= (mus-sound-sample-type "test.snd") mus-b24int)) (snd-display #__line__ ";saved-as 24-bit -> ~A?" (mus-sample-type-name (mus-sound-sample-type "test.snd")))) (if (fneq (sample 1000 ab) samp) (snd-display #__line__ ";aiff[1000] = ~A?" (sample 1000 ab))) (close-sound ab)) (save-sound-as "test.snd" ob :header-type mus-ircam :sample-type mus-mulaw) (let ((ab (open-sound "test.snd"))) (if (not (= (header-type ab) mus-ircam)) (snd-display #__line__ ";save-as ircam -> ~A?" (mus-header-type-name (header-type ab)))) (if (not (= (mus-sound-header-type "test.snd") mus-ircam)) (snd-display #__line__ ";saved-as ircam -> ~A?" (mus-header-type-name (mus-sound-header-type "test.snd")))) (if (not (= (sample-type ab) mus-mulaw)) (snd-display #__line__ ";save-as mulaw -> ~A?" (mus-sample-type-name (sample-type ab)))) (if (not (= (mus-sound-sample-type "test.snd") mus-mulaw)) (snd-display #__line__ ";saved-as mulaw -> ~A?" (mus-sample-type-name (mus-sound-sample-type "test.snd")))) (if (fneq (sample 1000 ab) samp) (snd-display #__line__ ";ircam[1000] = ~A?" (sample 1000 ab))) (close-sound ab)) (save-sound-as "test.snd" ob :header-type mus-next :sample-type mus-alaw) (let ((ab (open-sound "test.snd"))) (if (not (= (header-type ab) mus-next)) (snd-display #__line__ ";save-as next -> ~A?" (mus-header-type-name (header-type ab)))) (if (not (= (mus-sound-header-type "test.snd") mus-next)) (snd-display #__line__ ";saved-as next -> ~A?" (mus-header-type-name (mus-sound-header-type "test.snd")))) (if (not (= (sample-type ab) mus-alaw)) (snd-display #__line__ ";save-as alaw -> ~A?" (mus-sample-type-name (sample-type ab)))) (if (not (= (mus-sound-sample-type "test.snd") mus-alaw)) (snd-display #__line__ ";saved-as alaw -> ~A?" (mus-sample-type-name (mus-sound-sample-type "test.snd")))) (if (fneq (sample 1000 ab) samp) (snd-display #__line__ ";next (alaw)[1000] = ~A?" (sample 1000 ab))) (close-sound ab)) (save-sound-as "test.snd" ob :header-type mus-next :sample-type mus-ldouble) (let ((ab (open-sound "test.snd"))) (if (not (= (header-type ab) mus-next)) (snd-display #__line__ ";save-as dbl next -> ~A?" (mus-header-type-name (header-type ab)))) (if (not (= (sample-type ab) mus-ldouble)) (snd-display #__line__ ";save-as dbl -> ~A?" (mus-sample-type-name (sample-type ab)))) (if (fneq (sample 1000 ab) samp) (snd-display #__line__ ";next (dbl)[1000] = ~A?" (sample 1000 ab))) (close-sound ab)) (save-sound-as "test.snd" ob :header-type mus-next :sample-type mus-bshort) (let ((ab (open-sound "test.snd"))) (if (not (= (header-type ab) mus-next)) (snd-display #__line__ ";save-as next -> ~A?" (mus-header-type-name (header-type ab)))) (if (not (= (mus-sound-header-type "test.snd") mus-next)) (snd-display #__line__ ";saved-as next -> ~A?" (mus-header-type-name (mus-sound-header-type "test.snd")))) (if (not (= (sample-type ab) mus-bshort)) (snd-display #__line__ ";save-as short -> ~A?" (mus-sample-type-name (sample-type ab)))) (if (not (= (mus-sound-sample-type "test.snd") mus-bshort)) (snd-display #__line__ ";saved-as short -> ~A?" (mus-sample-type-name (mus-sound-sample-type "test.snd")))) (if (fneq (sample 1000 ab) samp) (snd-display #__line__ ";next (short)[1000] = ~A?" (sample 1000 ab))) (set! (hook-functions update-hook) ()) (set! (y-bounds ab 0) (list -3.0 3.0)) (set! (sample-type ab) mus-lshort) (if (not (equal? ab (find-sound "test.snd"))) (set! ab (find-sound "test.snd"))) ; these set!'s can change the index via update-sound (if (not (= (sample-type ab) mus-lshort)) (snd-display #__line__ ";set sample-type: ~A?" (mus-sample-type-name (sample-type ab)))) (when with-gui (if (not (equal? (y-bounds ab 0) (list -3.0 3.0))) (snd-display #__line__ ";set sample type y-bounds: ~A?" (y-bounds ab 0)))) (set! (y-bounds ab 0) (list 2.0)) (when with-gui (if (not (equal? (y-bounds ab 0) (list -2.0 2.0))) (snd-display #__line__ ";set sample type y-bounds 1: ~A?" (y-bounds ab 0)))) (set! (y-bounds ab 0) (list -2.0)) (when with-gui (if (not (equal? (y-bounds ab 0) (list -2.0 2.0))) (snd-display #__line__ ";set sample type y-bounds -2: ~A?" (y-bounds ab 0)))) (set! (header-type ab) mus-aifc) (if (not (equal? ab (find-sound "test.snd"))) (set! ab (find-sound "test.snd"))) (if (not (= (header-type ab) mus-aifc)) (snd-display #__line__ ";set header-type: ~A?" (mus-header-type-name (header-type ab)))) (set! (channels ab) 3) (if (not (equal? ab (find-sound "test.snd"))) (set! ab (find-sound "test.snd"))) (if (not (= (channels ab) 3)) (snd-display #__line__ ";set chans: ~A?" (channels ab))) (set! (data-location ab) 1234) (if (not (equal? ab (find-sound "test.snd"))) (set! ab (find-sound "test.snd"))) (if (not (= (data-location ab) 1234)) (snd-display #__line__ ";set data-location: ~A?" (data-location ab))) (let ((old-size (data-size ab))) (set! (data-size ab) 1234) (if (not (equal? ab (find-sound "test.snd"))) (set! ab (find-sound "test.snd"))) (if (not (= (data-size ab) 1234)) (snd-display #__line__ ";set data-size: ~A?" (data-size ab))) (set! (data-size ab) old-size)) (set! (srate ab) 12345) (if (not (equal? ab (find-sound "test.snd"))) (set! ab (find-sound "test.snd"))) (if (not (= (srate ab) 12345)) (snd-display #__line__ ";set srate: ~A?" (srate ab))) (close-sound ab)) (save-sound-as "test.snd" ob :header-type mus-next :sample-type mus-bfloat) (let ((ab (open-sound "test.snd"))) (if (not (= (header-type ab) mus-next)) (snd-display #__line__ ";save-as next -> ~A?" (mus-header-type-name (header-type ab)))) (if (not (= (mus-sound-header-type "test.snd") mus-next)) (snd-display #__line__ ";saved-as next -> ~A?" (mus-header-type-name (mus-sound-header-type "test.snd")))) (if (not (= (sample-type ab) mus-bfloat)) (snd-display #__line__ ";save-as float -> ~A?" (mus-sample-type-name (sample-type ab)))) (if (not (= (mus-sound-sample-type "test.snd") mus-bfloat)) (snd-display #__line__ ";saved-as float -> ~A?" (mus-sample-type-name (mus-sound-sample-type "test.snd")))) (if (fneq (sample 1000 ab) samp) (snd-display #__line__ ";next (float)[1000] = ~A?" (sample 1000 ab))) (close-sound ab)) (save-sound-as "test.snd" ob :header-type mus-next :sample-type mus-ldouble) (close-sound ob) (let ((ab (open-sound "test.snd"))) (set! (sample-type) mus-lshort) (if (not (equal? ab (find-sound "test.snd"))) (set! ab (find-sound "test.snd"))) (if (not (= (sample-type) mus-lshort)) (snd-display #__line__ ";set sample-type: ~A?" (mus-sample-type-name (sample-type)))) (set! (header-type) mus-aifc) (if (not (equal? ab (find-sound "test.snd"))) (set! ab (find-sound "test.snd"))) (if (not (= (header-type) mus-aifc)) (snd-display #__line__ ";set header-type: ~A?" (mus-header-type-name (header-type)))) (set! (channels) 3) (if (not (equal? ab (find-sound "test.snd"))) (set! ab (find-sound "test.snd"))) (if (not (= (channels) 3)) (snd-display #__line__ ";set chans: ~A?" (channels))) (set! (data-location) 1234) (if (not (equal? ab (find-sound "test.snd"))) (set! ab (find-sound "test.snd"))) (if (not (= (data-location) 1234)) (snd-display #__line__ ";set data-location: ~A?" (data-location))) (set! (srate) 12345) (if (not (equal? ab (find-sound "test.snd"))) (set! ab (find-sound "test.snd"))) (if (not (= (srate) 12345)) (snd-display #__line__ ";set srate: ~A?" (srate))) (close-sound ab))) (let ((ind (open-sound "2a.snd"))) (save-sound-as "test.snd" :sample-type mus-l24int :header-type mus-riff :channel 0) (let ((ind0 (open-sound "test.snd"))) (if (not (= (channels ind0) 1)) (snd-display #__line__ ";save-sound-as :channel 0 chans: ~A" (channels ind0))) (if (not (= (sample-type ind0) mus-l24int)) (snd-display #__line__ ";save-sound-as :channel 0 sample-type: ~A ~A" (sample-type ind0) (mus-sample-type-name (sample-type ind0)))) (if (not (= (header-type ind0) mus-riff)) (snd-display #__line__ ";save-sound-as :channel 0 header-type: ~A ~A" (header-type ind0) (mus-header-type-name (header-type ind0)))) (if (not (= (srate ind0) (srate ind))) (snd-display #__line__ ";save-sound-as :channel 0 srates: ~A ~A" (srate ind0) (srate ind))) (if (not (= (framples ind0) (framples ind 0))) (snd-display #__line__ ";save-sound-as :channel 0 framples: ~A ~A" (framples ind0) (framples ind 0))) (if (fneq (maxamp ind0 0) (maxamp ind 0)) (snd-display #__line__ ";save-sound-as :channel 0 maxamps: ~A ~A" (maxamp ind0 0) (maxamp ind 0))) (close-sound ind0)) (save-sound-as "test.snd" :sample-type mus-l24int :header-type mus-riff) (let ((ind0 (open-sound "test.snd"))) (if (not (= (channels ind0) 2)) (snd-display #__line__ ";save-sound-as chans: ~A" (channels ind0))) (if (not (= (sample-type ind0) mus-l24int)) (snd-display #__line__ ";save-sound-as sample-type: ~A ~A" (sample-type ind0) (mus-sample-type-name (sample-type ind0)))) (if (not (= (header-type ind0) mus-riff)) (snd-display #__line__ ";save-sound-as header-type: ~A ~A" (header-type ind0) (mus-header-type-name (header-type ind0)))) (if (not (= (srate ind0) (srate ind))) (snd-display #__line__ ";save-sound-as srates: ~A ~A" (srate ind0) (srate ind))) (if (not (= (framples ind0) (framples ind 0))) (snd-display #__line__ ";save-sound-as framples: ~A ~A" (framples ind0) (framples ind 0))) (if (fneq (maxamp ind0 0) (maxamp ind 0)) (snd-display #__line__ ";save-sound-as maxamps: ~A ~A" (maxamp ind0 0) (maxamp ind 0))) (close-sound ind0)) (save-sound-as "test.snd" :sample-type mus-b24int :header-type mus-aiff) (let ((ind0 (open-sound "test.snd"))) (if (not (= (channels ind0) 2)) (snd-display #__line__ ";save-sound-as chans: ~A" (channels ind0))) (if (not (= (sample-type ind0) mus-b24int)) (snd-display #__line__ ";save-sound-as sample-type: ~A ~A" (sample-type ind0) (mus-sample-type-name (sample-type ind0)))) (if (not (= (header-type ind0) mus-aiff)) (snd-display #__line__ ";save-sound-as header-type: ~A ~A" (header-type ind0) (mus-header-type-name (header-type ind0)))) (if (not (= (srate ind0) (srate ind))) (snd-display #__line__ ";save-sound-as srates: ~A ~A" (srate ind0) (srate ind))) (if (not (= (framples ind0) (framples ind 0))) (snd-display #__line__ ";save-sound-as framples: ~A ~A" (framples ind0) (framples ind 0))) (if (fneq (maxamp ind0 0) (maxamp ind 0)) (snd-display #__line__ ";save-sound-as maxamps: ~A ~A" (maxamp ind0 0) (maxamp ind 0))) (close-sound ind0)) (save-sound-as "test.snd" :sample-type mus-bfloat :header-type mus-aifc :channel 1 :srate 12345) (let ((ind0 (open-sound "test.snd"))) (if (not (= (channels ind0) 1)) (snd-display #__line__ ";save-sound-as :channel 1 chans: ~A" (channels ind0))) (if (not (= (sample-type ind0) mus-bfloat)) (snd-display #__line__ ";save-sound-as :channel 1 sample-type: ~A ~A" (sample-type ind0) (mus-sample-type-name (sample-type ind0)))) (if (not (= (header-type ind0) mus-aifc)) (snd-display #__line__ ";save-sound-as :channel 1 header-type: ~A ~A" (header-type ind0) (mus-header-type-name (header-type ind0)))) (if (not (= (srate ind0) 12345)) (snd-display #__line__ ";save-sound-as :channel 1 srates: ~A ~A" (srate ind0) (srate ind))) (if (not (= (framples ind0) (framples ind 1))) (snd-display #__line__ ";save-sound-as :channel 1 framples: ~A ~A" (framples ind0) (framples ind 1))) (if (fneq (maxamp ind0 0) (maxamp ind 1)) (snd-display #__line__ ";save-sound-as :channel 1 maxamps: ~A ~A" (maxamp ind0 0) (maxamp ind 1))) (close-sound ind0)) (save-sound-as "test.snd" :channel 1 :comment "this is a test") (let ((ind0 (open-sound "test.snd"))) (if (not (= (channels ind0) 1)) (snd-display #__line__ ";save-sound-as :channel 1 (1) chans: ~A" (channels ind0))) (if (not (= (sample-type ind0) (sample-type ind))) (snd-display #__line__ ";save-sound-as :channel 1 (1) sample-type: ~A ~A" (sample-type ind0) (mus-sample-type-name (sample-type ind0)))) (if (not (= (header-type ind0) (header-type ind))) (snd-display #__line__ ";save-sound-as :channel 1 (1) header-type: ~A ~A" (header-type ind0) (mus-header-type-name (header-type ind0)))) (if (not (= (srate ind0) (srate ind))) (snd-display #__line__ ";save-sound-as :channel 1 (1) srates: ~A ~A" (srate ind0) (srate ind))) (if (not (= (framples ind0) (framples ind 1))) (snd-display #__line__ ";save-sound-as :channel 1 (1) framples: ~A ~A" (framples ind0) (framples ind 1))) (if (fneq (maxamp ind0 0) (maxamp ind 1)) (snd-display #__line__ ";save-sound-as :channel 1 (1) maxamps: ~A ~A" (maxamp ind0 0) (maxamp ind 1))) (if (not (string=? (comment ind0) "this is a test")) (snd-display #__line__ ";save-sound-as :channel 0 (1) comment: ~A" (comment ind0))) (close-sound ind0)) (close-sound ind)) (let ((fsnd (string-append sf-dir "t15.aiff"))) (if (file-exists? fsnd) (let ((ind (open-sound fsnd))) (if (or (fneq (sample 132300 ind 0) .148) (fneq (sample 132300 ind 1) .126)) (snd-display #__line__ ";aifc sowt trouble: ~A ~A" (sample 132300 ind 0) (sample 132300 ind 1))) (close-sound ind)))) (let ((fsnd (string-append sf-dir "M1F1-float64C-AFsp.aif"))) (if (file-exists? fsnd) (let ((ind (open-sound fsnd))) (if (or (fneq (sample 8000 ind 0) -0.024) (fneq (sample 8000 ind 1) 0.021)) (snd-display #__line__ ";aifc fl64 trouble: ~A ~A" (sample 8000 ind 0) (sample 8000 ind 1))) (close-sound ind)))) (for-each (lambda (n vals) (let ((val (catch #t (lambda () (list (mus-sound-chans n) (mus-sound-srate n) (mus-sound-framples n))) (lambda args (car args))))) (if (and (not (equal? val vals)) (not (eq? val 'mus-error))) (snd-display #__line__ ";~A: ~A ~A" n val vals)))) (list (string-append sf-dir "bad_chans.snd") (string-append sf-dir "bad_srate.snd") (string-append sf-dir "bad_data_format.snd") (string-append sf-dir "bad_chans.aifc") (string-append sf-dir "bad_srate.aifc") (string-append sf-dir "bad_length.aifc") (string-append sf-dir "bad_chans.riff") (string-append sf-dir "bad_srate.riff") (string-append sf-dir "bad_chans.nist") (string-append sf-dir "bad_srate.nist") (string-append sf-dir "bad_length.nist")) (list (list 0 22050 0) (list 1 0 0) (list 1 22050 4411) (list 0 22050 0) (list 1 0 0) (list 1 22050 -10) (list 0 22050 0) (list 1 0 0) (list 0 22050 0) (list 1 0 0) (list 1 22050 -10))) (let ((ind (open-sound (string-append "/usr/include/sys/" home-dir "/cl/oboe.snd")))) (if (or (not (sound? ind)) (not (string=? (short-file-name ind) "oboe.snd"))) (snd-display #__line__ ";open-sound with slashes: ~A ~A" ind (and (sound? ind) (short-file-name ind)))) (hook-push bad-header-hook (lambda (hook) (set! (hook 'result) #t))) (for-each (lambda (n) (catch #t (lambda () (insert-sound n)) (lambda args (car args))) (catch #t (lambda () (convolve-with n)) (lambda args (car args))) (catch #t (lambda () (mix n)) (lambda args (car args))) (catch #t (lambda () (let ((ind (open-sound n))) (if (and (number? ind) (sound? ind)) (close-sound ind)))) (lambda args (car args)))) (list (string-append sf-dir "bad_chans.snd") (string-append sf-dir "bad_srate.snd") (string-append sf-dir "bad_chans.aifc") (string-append sf-dir "bad_srate.aifc") (string-append sf-dir "bad_length.aifc") (string-append sf-dir "bad_chans.riff") (string-append sf-dir "bad_srate.riff") (string-append sf-dir "bad_chans.nist") (string-append sf-dir "bad_location.nist") (string-append sf-dir "bad_field.nist") (string-append sf-dir "bad_srate.nist") (string-append sf-dir "bad_length.nist"))) (close-sound ind)) (for-each close-sound (sounds)) (if (selected-sound) (snd-display #__line__ ";selected-sound ~A ~A" (selected-sound) (sounds))) (if (file-exists? (string-append (or sf-dir "") "a.sf2")) (let ((fil (open-sound (string-append (or sf-dir "") "a.sf2")))) (if fil (let ((loops (and fil (soundfont-info)))) (if (or (null? loops) (not (= (caddar loops) 65390)) (not (= (cadadr loops) 65490))) (snd-display #__line__ ";soundfont-info: ~A?" loops)) (close-sound fil))))) (if (file-exists? "fmv5.snd") (delete-file "fmv5.snd")) (set! *print-length* 12) (for-each (lambda (file) (let ((tag (catch #t (lambda () (open-sound (string-append sf-dir file))) (lambda args args)))) (if (not (eq? (car tag) 'mus-error)) (snd-display #__line__ ";open-sound ~A: ~A" file tag)))) (list "trunc.snd" "trunc.aiff" "trunc.wav" "trunc.sf" "trunc.voc" "trunc.nist" "bad.wav" "trunc1.aiff" "badform.aiff")) (hook-push open-raw-sound-hook (lambda (hook) (set! (hook 'result) (list 1 22050 mus-bshort)))) (let ((ind (open-sound (string-append sf-dir "empty.snd")))) (if (or (not (= (sample-type ind) mus-bshort)) (not (= (chans ind) 1)) (not (= (srate ind) 22050)) (not (= (data-location ind) 0)) (not (= (framples ind) 0))) (snd-display #__line__ ";open raw: ~A ~A ~A ~A ~A" (sample-type ind) (chans ind) (srate ind) (data-location ind) (framples ind))) (set! (hook-functions open-raw-sound-hook) ()) (close-sound ind)) (let ((sd (make-float-vector (list 1 1) 0.0))) (if (fneq (sd 0 0) 0.0) (snd-display #__line__ ";vector2 ref: ~A" (sd 0 0))) (set! (sd 0 0) 1.0) (if (fneq (sd 0 0) 1.0) (snd-display #__line__ ";vector2 set: ~A" (sd 0 0))) (if (not (equal? sd (let ((sd1 (make-float-vector (list 1 1) 0.0))) (vector-set! sd1 0 0 1.0) sd1))) (snd-display #__line__ ";vector2 set not equal: ~A" sd))) (let ((sd (make-float-vector (list 2 3) 0.0))) (if (fneq (sd 0 0) 0.0) (snd-display #__line__ ";vector2 ref (1): ~A" (sd 0 0))) (set! (sd 1 0) 1.0) (if (fneq (sd 1 0) 1.0) (snd-display #__line__ ";vector2 set (1 0): ~A" (sd 1 0))) (set! (sd 1 2) 2.0) (if (fneq (sd 1 2) 2.0) (snd-display #__line__ ";vector2 set (1 2): ~A" (sd 1 2))) (if (not (equal? sd (let ((sd1 (make-float-vector (list 2 3) 0.0))) (vector-set! sd1 1 0 1.0) (vector-set! sd1 1 2 2.0) sd1))) (snd-display #__line__ ";vector2 set (3) not equal: ~A" sd))) ;; check clipping choices (let ((ind (view-sound "oboe.snd"))) (set! *clipping* #f) (scale-channel 10.0) (save-sound-as "test.snd" ind :header-type mus-next :sample-type mus-ldouble) (undo 1 ind 0) (let ((ind1 (open-sound "test.snd"))) (if (fneq (maxamp ind1 0) (* 10 (maxamp ind 0))) (snd-display #__line__ ";clipping 0: ~A ~A" (maxamp ind1 0) (maxamp ind 0))) (close-sound ind1)) (delete-file "test.snd") (set! *clipping* #t) (map-channel (lambda (y) (* y 10.0)) 0 #f ind 0) (save-sound-as "test.snd" ind :header-type mus-next :sample-type mus-lshort) (undo 1 ind 0) (let ((ind1 (open-sound "test.snd"))) (if (fneq (maxamp ind1 0) 1.0) (snd-display #__line__ ";clipping 1: ~A ~A" (maxamp ind1 0) (maxamp ind 0))) (close-sound ind1)) (delete-file "test.snd") (set! *clipping* #f) (let* ((mx (maxamp ind)) (sub (- 1.001 mx))) (map-channel (lambda (y) (+ y sub)) 0 #f ind 0) (save-sound-as "test.snd" ind :header-type mus-next :sample-type mus-lfloat) (let ((ind1 (open-sound "test.snd")) (baddy (scan-channel (lambda (y) (< y 0.0))))) (if baddy (snd-display #__line__ ";clipping 2: ~A" baddy)) (close-sound ind1)) (delete-file "test.snd") (set! *clipping* #t) (save-sound-as "test.snd" ind :header-type mus-next :sample-type mus-ldouble) (let ((ind1 (open-sound "test.snd")) (baddy (scan-channel (lambda (y) (< y 0.0))))) (if baddy (snd-display #__line__ ";clipping 3: ~A ~A" baddy (sample baddy))) (close-sound ind1)) (delete-file "test.snd") (set! *clipping* #f)) (close-sound ind)) (delete-file "fmv.snd") (set! *clipping* #f) (let ((snd (new-sound "test.snd" :sample-type mus-lshort))) (pad-channel 0 10) (set! (sample 1) 1.0) (set! (sample 2) -1.0) (set! (sample 3) 0.9999) (set! (sample 4) 2.0) (set! (sample 5) -2.0) (set! (sample 6) 1.3) (set! (sample 7) -1.3) (set! (sample 8) 1.8) (set! (sample 9) -1.8) (save-sound snd) (close-sound snd)) (let ((snd (open-sound "test.snd"))) (let ((data (channel->float-vector 0 10))) (if (not (vequal data (float-vector 0.000 1.000 -1.000 1.000 0.000 0.000 -0.700 0.700 -0.200 0.200))) (snd-display #__line__ ";unclipped 1: ~A" data))) (close-sound snd)) (mus-sound-forget "test.snd") (set! *clipping* #t) (let ((snd (new-sound "test.snd" :sample-type mus-lshort))) (pad-channel 0 10) (set! (sample 1) 1.0) (set! (sample 2) -1.0) (set! (sample 3) 0.9999) (set! (sample 4) 2.0) (set! (sample 5) -2.0) (set! (sample 6) 1.3) (set! (sample 7) -1.3) (set! (sample 8) 1.8) (set! (sample 9) -1.8) (save-sound snd) (close-sound snd)) (let ((snd (open-sound "test.snd"))) (let ((data (channel->float-vector 0 10))) (if (not (vequal data (float-vector 0.000 1.000 -1.000 1.000 1.000 -1.000 1.000 -1.000 1.000 -1.000))) (snd-display #__line__ ";clipped: ~A" data))) (close-sound snd)) (set! *clipping* #f) (let ((test-data (lambda (file beg dur data) (catch #t (lambda () (let* ((ind (open-sound file)) (ndata (channel->float-vector beg dur ind 0))) (if (not (vequal data ndata)) (snd-display #__line__ ";~A: ~A != ~A" file data ndata)) (close-sound ind))) (lambda args args))))) (test-data (string-append sf-dir "next-dbl.snd") 10 10 (float-vector 0.475 0.491 0.499 0.499 0.492 0.476 0.453 0.423 0.387 0.344)) (test-data (string-append sf-dir "oboe.ldbl") 1000 10 (float-vector 0.033 0.035 0.034 0.031 0.026 0.020 0.013 0.009 0.005 0.004)) (test-data (string-append sf-dir "next-flt.snd") 10 10 (float-vector 0.475 0.491 0.499 0.499 0.492 0.476 0.453 0.423 0.387 0.344)) (test-data (string-append sf-dir "clbonef.wav") 1000 10 (float-vector 0.111 0.101 0.070 0.032 -0.014 -0.060 -0.085 -0.108 -0.129 -0.152)) (test-data (string-append sf-dir "next-8.snd") 10 10 (float-vector 0.898 0.945 0.977 0.992 0.992 0.977 0.945 0.906 0.844 0.773)) (test-data (string-append sf-dir "o2_u8.wave") 1000 10 (float-vector -0.164 -0.219 -0.258 -0.242 -0.180 -0.102 -0.047 0.000 0.039 0.055)) (test-data (string-append sf-dir "next-16.snd") 1000 10 (float-vector -0.026 -0.022 -0.024 -0.030 -0.041 -0.048 -0.050 -0.055 -0.048 -0.033)) (test-data (string-append sf-dir "o2.wave") 1000 10 (float-vector -0.160 -0.216 -0.254 -0.239 -0.175 -0.102 -0.042 0.005 0.041 0.059)) (test-data (string-append sf-dir "o2_18bit.aiff") 1000 10 (float-vector -0.160 -0.216 -0.254 -0.239 -0.175 -0.102 -0.042 0.005 0.041 0.059)) (test-data (string-append sf-dir "o2_12bit.aiff") 1000 10 (float-vector -0.160 -0.216 -0.254 -0.239 -0.175 -0.102 -0.042 0.005 0.041 0.059)) (test-data (string-append sf-dir "next24.snd") 1000 10 (float-vector -0.160 -0.216 -0.254 -0.239 -0.175 -0.102 -0.042 0.005 0.041 0.059)) (test-data (string-append sf-dir "mono24.wav") 1000 10 (float-vector 0.005 0.010 0.016 0.008 -0.007 -0.018 -0.025 -0.021 -0.005 0.001)) (test-data (string-append sf-dir "o2_711u.wave") 1000 10 (float-vector -0.164 -0.219 -0.254 -0.242 -0.172 -0.103 -0.042 0.005 0.042 0.060)) (test-data (string-append sf-dir "alaw.wav") 1000 10 (float-vector -0.024 -0.048 -0.024 0.000 0.008 0.008 0.000 -0.040 -0.064 -0.024)) ;; it is not a bug if these don't match if MUS_SAMPLE_BITS is not 24 (test-data (string-append sf-dir "b32.pvf") 1000 10 (float-vector -0.160 -0.216 -0.254 -0.239 -0.175 -0.102 -0.042 0.005 0.041 0.059)) (test-data (string-append sf-dir "b32.wave") 1000 10 (float-vector -0.160 -0.216 -0.254 -0.239 -0.175 -0.102 -0.042 0.005 0.041 0.059)) (test-data (string-append sf-dir "b32.snd") 1000 10 (float-vector -0.160 -0.216 -0.254 -0.239 -0.175 -0.102 -0.042 0.005 0.041 0.059)) (test-data (string-append sf-dir "32bit.sf") 1000 10 (float-vector 0.016 0.014 0.013 0.011 0.010 0.010 0.010 0.010 0.012 0.014)) (test-data (string-append sf-dir "nist-shortpack.wav") 10000 10 (float-vector 0.021 0.018 0.014 0.009 0.004 -0.001 -0.004 -0.006 -0.007 -0.008)) (test-data (string-append sf-dir "wood.sds") 1000 10 (float-vector -0.160 -0.216 -0.254 -0.239 -0.175 -0.102 -0.042 0.005 0.041 0.059)) ; (test-data (string-append sf-dir "oboe.g721") 1000 10 (float-vector -0.037 -0.040 -0.040 -0.041 -0.042 -0.038 -0.028 -0.015 -0.005 0.002)) ; (test-data (string-append sf-dir "oboe.g723_40") 1000 10 (float-vector -0.037 -0.040 -0.041 -0.041 -0.041 -0.038 -0.028 -0.015 -0.005 0.003)) (test-data (string-append sf-dir "mus10.snd") 10000 10 (float-vector 0.004 0.001 0.005 0.009 0.017 0.015 0.008 0.011 0.009 0.012)) (test-data (string-append sf-dir "ieee-text-16.snd") 1000 10 (float-vector -0.052 -0.056 -0.069 -0.077 -0.065 -0.049 -0.054 -0.062 -0.066 -0.074)) (test-data (string-append sf-dir "hcom-16.snd") 10000 10 (float-vector 0.000 0.000 0.000 0.008 0.000 -0.016 -0.016 -0.016 -0.008 0.000)) (test-data (string-append sf-dir "ce-c3.w02") 1000 10 (float-vector 0.581 0.598 0.596 0.577 0.552 0.530 0.508 0.479 0.449 0.425)) (test-data (string-append sf-dir "nasahal.avi") 20000 10 (float-vector 0.390 0.120 -0.399 -0.131 0.464 0.189 -0.458 -0.150 0.593 0.439)) (test-data (string-append sf-dir "oki.wav") 100 10 (float-vector 0.396 0.564 0.677 0.779 0.761 0.540 0.209 -0.100 -0.301 -0.265)) (test-data (string-append sf-dir "trumps22.adp") 5000 10 (float-vector 0.267 0.278 0.309 0.360 0.383 0.414 0.464 0.475 0.486 0.495)) ) (let ((errs (list "no error" "no frequency method" "no phase method" "null gen arg to method" "no length method" "no describe method" "no data method" "no scaler method" "memory allocation failed" "can't open file" "no sample input" "no sample output" "no such channel" "no file name provided" "no location method" "no channel method" "no such fft window" "unknown sample type" "header read failed" "unknown header type" "file descriptors not initialized" "not a sound file" "file closed" "write error" "header write failed" "can't open temp file" "interrupted" "bad envelope" "audio channels not available" "audio srate not available" "audio sample type not available" "no audio input available" "audio configuration not available" "audio write error" "audio size not available" "audio device not available" "can't close audio" "can't open audio" "audio read error" "can't write audio" "can't read audio" "no audio read permission" "can't close file" "arg out of range" "no channels method" "no hop method" "no width method" "no file-name method" "no ramp method" "no run method" "no increment method" "no offset method" "no xcoeff method" "no ycoeff method" "no xcoeffs method" "no ycoeffs method" "no reset" "bad size" "can't convert" "read error" "no feedforward method" "no feedback method" "no interp-type method" "no position method" "no order method" "no copy method" "can't translate" ))) (let ((happy #t) (len (length errs))) (do ((i 0 (+ i 1))) ((or (not happy) (= i len))) (if (not (string=? (errs i) (mus-error-type->string i))) (begin (snd-display #__line__ ";mus-error-type->string ~D: ~A ~A" i (errs i) (mus-error-type->string i)) (set! happy #f)))))) ; (let ((new-id (mus-make-error "hiho all messed up"))) ; (if (not (string=? (mus-error-type->string new-id) "hiho all messed up")) ; (snd-display #__line__ ";mus-make-error :~A ~A" new-id (mus-error-type->string new-id)))) (let ((cur-srate (mus-sound-srate "oboe.snd")) (cur-chans (mus-sound-chans "oboe.snd")) (cur-format (mus-sound-sample-type "oboe.snd")) (cur-type (mus-sound-header-type "oboe.snd")) (cur-loc (mus-sound-data-location "oboe.snd")) (cur-samps (mus-sound-samples "oboe.snd"))) (set! (mus-sound-srate "oboe.snd") (* cur-srate 2)) (if (not (= (* cur-srate 2) (mus-sound-srate "oboe.snd"))) (snd-display #__line__ ";set mus-sound-srate: ~A -> ~A" cur-srate (mus-sound-srate "oboe.snd"))) (set! (mus-sound-samples "oboe.snd") (* cur-samps 2)) (if (not (= (* cur-samps 2) (mus-sound-samples "oboe.snd"))) (snd-display #__line__ ";set mus-sound-samples: ~A -> ~A" cur-samps (mus-sound-samples "oboe.snd"))) (set! (mus-sound-chans "oboe.snd") (* cur-chans 2)) (if (not (= (* cur-chans 2) (mus-sound-chans "oboe.snd"))) (snd-display #__line__ ";set mus-sound-chans: ~A -> ~A" cur-chans (mus-sound-chans "oboe.snd"))) (set! (mus-sound-data-location "oboe.snd") (* cur-loc 2)) (if (not (= (* cur-loc 2) (mus-sound-data-location "oboe.snd"))) (snd-display #__line__ ";set mus-sound-data-location: ~A -> ~A" cur-loc (mus-sound-data-location "oboe.snd"))) (set! (mus-sound-header-type "oboe.snd") mus-nist) (if (not (= mus-nist (mus-sound-header-type "oboe.snd"))) (snd-display #__line__ ";set mus-sound-header-type: ~A -> ~A" cur-type (mus-sound-header-type "oboe.snd"))) (set! (mus-sound-sample-type "oboe.snd") mus-lintn) (if (not (= mus-lintn (mus-sound-sample-type "oboe.snd"))) (snd-display #__line__ ";set mus-sound-sample-type: ~A -> ~A" cur-format (mus-sound-sample-type "oboe.snd"))) (set! (mus-sound-srate "oboe.snd") cur-srate) (set! (mus-sound-samples "oboe.snd") cur-samps) (set! (mus-sound-chans "oboe.snd") cur-chans) (set! (mus-sound-data-location "oboe.snd") cur-loc) (set! (mus-sound-header-type "oboe.snd") cur-type) (set! (mus-sound-sample-type "oboe.snd") cur-format)) (let ((ind (open-sound "oboe.snd"))) (save-sound-as "test.wave" ind :header-type mus-riff) (save-sound-as "test.rf64" ind :header-type mus-rf64) (save-sound-as "test.aifc" ind :header-type mus-aifc) (close-sound ind) (for-each (lambda (file) (let ((cur-srate (mus-sound-srate file)) (cur-chans (mus-sound-chans file)) (cur-format (mus-sound-sample-type file)) (cur-type (mus-sound-header-type file)) (cur-loc (mus-sound-data-location file)) (cur-samps (mus-sound-samples file))) (set! (mus-sound-srate file) (* cur-srate 2)) (if (not (= (* cur-srate 2) (mus-sound-srate file))) (snd-display #__line__ ";~A: set mus-sound-srate: ~A -> ~A" file cur-srate (mus-sound-srate file))) (set! (mus-sound-samples file) (* cur-samps 2)) (if (not (= (* cur-samps 2) (mus-sound-samples file))) (snd-display #__line__ ";~A: set mus-sound-samples: ~A -> ~A" file cur-samps (mus-sound-samples file))) (set! (mus-sound-chans file) (* cur-chans 2)) (if (not (= (* cur-chans 2) (mus-sound-chans file))) (snd-display #__line__ ";~A: set mus-sound-chans: ~A -> ~A" file cur-chans (mus-sound-chans file))) (set! (mus-sound-data-location file) (* cur-loc 2)) (if (not (= (* cur-loc 2) (mus-sound-data-location file))) (snd-display #__line__ ";~A: set mus-sound-data-location: ~A -> ~A" file cur-loc (mus-sound-data-location file))) (set! (mus-sound-header-type file) mus-nist) (if (not (= mus-nist (mus-sound-header-type file))) (snd-display #__line__ ";~A: set mus-sound-header-type: ~A -> ~A" file cur-type (mus-sound-header-type file))) (set! (mus-sound-sample-type file) mus-lintn) (if (not (= mus-lintn (mus-sound-sample-type file))) (snd-display #__line__ ";~A: set mus-sound-sample-type: ~A -> ~A" file cur-format (mus-sound-sample-type file))) (set! (mus-sound-srate file) cur-srate) (set! (mus-sound-samples file) cur-samps) (set! (mus-sound-chans file) cur-chans) (set! (mus-sound-data-location file) cur-loc) (set! (mus-sound-header-type file) cur-type) (set! (mus-sound-sample-type file) cur-format))) (list "test.wave" "test.rf64" "test.aifc")) (for-each (lambda (file) (let ((ind (open-sound file))) (let ((cur-srate (srate ind)) (cur-chans (chans ind)) (cur-format (sample-type ind)) (cur-type (header-type ind)) (cur-loc (data-location ind)) (cur-samps (framples ind))) (set! (srate ind) (* cur-srate 2)) (if (not (= (* cur-srate 2) (srate ind))) (snd-display #__line__ ";~A: set srate: ~A -> ~A" file cur-srate (srate ind))) (set! (framples ind) (* cur-samps 2)) (if (not (= (* cur-samps 2) (framples ind))) (snd-display #__line__ ";~A: set framples: ~A -> ~A" file cur-samps (framples ind))) (set! (chans ind) (* cur-chans 2)) ; this can change the index (let ((xind (find-sound file))) (if (not (equal? ind xind)) (set! ind xind))) (if (not (= (* cur-chans 2) (chans ind))) (snd-display #__line__ ";~A: set chans: ~A -> ~A" file cur-chans (chans ind))) (set! (data-location ind) (* cur-loc 2)) (if (not (= (* cur-loc 2) (data-location ind))) (snd-display #__line__ ";~A: set data-location: ~A -> ~A" file cur-loc (data-location ind))) (set! (header-type ind) mus-nist) (if (not (= mus-nist (header-type ind))) (snd-display #__line__ ";~A: set header-type: ~A -> ~A" file cur-type (header-type ind))) (set! (sample-type ind) mus-lintn) (if (not (= mus-lintn (sample-type ind))) (snd-display #__line__ ";~A: set sample-type: ~A -> ~A" file cur-format (sample-type ind))) (set! (srate ind) cur-srate) (set! (framples ind) cur-samps) (set! (chans ind) cur-chans) (set! (data-location ind) cur-loc) (set! (header-type ind) cur-type) (set! (sample-type ind) cur-format)) (close-sound ind)) (if (file-exists? file) (delete-file file))) (list "test.wave" "test.rf64" "test.aifc"))) ;; (with-sound (big-file-name :srate 44100 :play #f) ;; (do ((i 0 (+ i 1))) ((= i 72000)) ;; (fm-violin i .1 440 (+ .01 (* (/ i 72000.0) .9))))) (if with-big-file (let ((probable-framples (floor (* (floor *clm-srate*) 71999.1)))) ; silence as last .9 secs, so it probably wasn't written (if (not (= (mus-sound-samples big-file-name) 3175160310)) (snd-display #__line__ ";bigger samples: ~A" (mus-sound-samples big-file-name))) (if (not (= (mus-sound-framples big-file-name) 3175160310)) (snd-display #__line__ ";bigger framples: ~A" (mus-sound-framples big-file-name))) (if (not (= (mus-sound-framples big-file-name) probable-framples)) (snd-display #__line__ ";bigger framples: ~A (probable: ~A)" (mus-sound-framples big-file-name) probable-framples)) (if (not (= (mus-sound-length big-file-name) 6350320648)) (snd-display #__line__ ";bigger bytes: ~A" (mus-sound-length big-file-name))) (if (fneq (mus-sound-duration big-file-name) 71999.1015) (snd-display #__line__ ";bigger dur: ~A" (mus-sound-duration big-file-name))) (let ((ind (open-sound big-file-name))) (if (not (= (framples ind) 3175160310)) (snd-display #__line__ ";bigger framples: ~A" (framples ind))) (set! big-file-framples (framples ind)) (if (not (= (framples ind) probable-framples)) (snd-display #__line__ ";bigger framples: ~A (probable: ~A)" (framples ind) probable-framples)) (if (not (= (framples ind 0 0) big-file-framples)) (snd-display #__line__ ";bigger edpos-framples: ~A" (framples ind))) (let ((m1 (add-mark (* (floor *clm-srate*) 50000) ind))) (if (not (= (mark-sample m1) (* (floor *clm-srate*) 50000))) (snd-display #__line__ ";bigger mark at: ~A" (mark-sample m1))) (set! (mark-sample m1) (* (floor *clm-srate*) 66000)) (if (not (= (mark-sample m1) (* (floor *clm-srate*) 66000))) (snd-display #__line__ ";bigger mark to: ~A" (mark-sample m1)))) (let ((mx (mix-sound "oboe.snd" (* (floor *clm-srate*) 60000)))) (if (mix? mx) (begin (if (not (= (mix-position mx) (* (floor *clm-srate*) 60000))) (snd-display #__line__ ";bigger mix at: ~A" (mix-position mx))) (set! (mix-position mx) (* (floor *clm-srate*) 61000)) (if (not (= (mix-position mx) (* (floor *clm-srate*) 61000))) (snd-display #__line__ ";bigger mix to: ~A" (mix-position mx)))) (snd-display #__line__ ";no mix tag from mix-sound")) (undo 2)) (let ((res (scan-channel (lambda (y) (> (abs y) 0.0))))) (if (or (not res) (> (cadr res) 100)) (snd-display #__line__ ";bigger find not 0.0: ~A" res))) (let ((old-select *selection-creates-region*)) (set! *selection-creates-region* #f) (select-all ind) (if (not (= (selection-framples) (framples ind))) (snd-display #__line__ ";bigger select all: ~A ~A" (selection-framples) (framples))) (set! (selection-position) (* (floor *clm-srate*) 50000)) (if (not (= (selection-position) (* (floor *clm-srate*) 50000))) (snd-display #__line__ ";bigger select pos: ~A" (selection-position))) (set! (selection-position) 0) (set! (selection-framples) (* (floor *clm-srate*) 65000)) (if (not (= (selection-framples) (* (floor *clm-srate*) 65000))) (snd-display #__line__ ";bigger select len: ~A" (selection-framples))) (set! *selection-creates-region* old-select)) (set! (cursor ind) (* (floor *clm-srate*) 50000)) (if (not (= (cursor ind) (* (floor *clm-srate*) 50000))) (snd-display #__line__ ";bigger cursor: ~A" (cursor ind))) (let ((m1 (add-mark (* 44123 51234) ind))) (if (not (= (mark-sample m1) (* 44123 51234))) (snd-display #__line__ ";bigger mark at: ~A" (mark-sample m1))) (let ((mid (find-mark (* 44123 51234)))) (if (or (not (number? mid)) (not (= mid m1))) (snd-display #__line__ ";bigger mark seach: ~A ~A" mid m1)))) (let ((mx (mix-sound "oboe.snd" (* 44123 61234)))) (let ((mxd (find-mix (* 44123 61234)))) (if (or (not (number? mxd)) (not (= mxd mx))) (snd-display #__line__ ";bigger find-mix ~A ~A" mxd mx)))) (set! (cursor ind) (* 44123 51234)) (if (not (= (cursor ind) (* 44123 51234))) (snd-display #__line__ ";bigger cursor 123: ~A" (cursor ind))) (close-sound ind)))) (let ((ind (new-sound "tmp.snd" 1 22050 mus-l24int mus-riff :size 100000)) (old-selection-creates-region *selection-creates-region*)) (set! *selection-creates-region* #t) (let ((incr (/ 1.0 (framples))) (data (make-float-vector (framples)))) (outa->fv data (- (* i incr) 0.5)) (float-vector->channel data)) (save-sound) (close-sound ind) (set! ind (open-sound "tmp.snd")) (let ((reg (select-all)) (v1 (make-float-vector 100000))) (save-selection "tmp1.snd" 22050 mus-l24int mus-next) (let ((ind1 (open-sound "tmp1.snd"))) (let ((incr (/ 1.0 (framples)))) (outa->fv v1 (- (* i incr) 0.5)) (let ((v0 (samples 0 100000 ind1 0))) (if (not (vequal v0 v1)) (snd-display #__line__ ";l24 (next) selection not saved correctly? ~A" v0)))) (close-sound ind1)) (save-selection "tmp1.snd" 22050 mus-l24int mus-aifc) (let ((ind1 (open-sound "tmp1.snd"))) (let ((v0 (samples 0 100000 ind1 0))) (if (not (vequal v0 v1)) (snd-display #__line__ ";l24 (aifc) selection not saved correctly? ~A" v0))) (close-sound ind1)) (save-region reg "tmp1.snd" mus-l24int mus-next) (let ((ind1 (open-sound "tmp1.snd"))) (let ((v0 (samples 0 100000 ind1 0))) (if (not (vequal v0 v1)) (snd-display #__line__ ";l24 (next) region not saved correctly? ~A" v0))) (close-sound ind1)) (delete-file "tmp1.snd") (close-sound ind) (delete-file "tmp.snd")) (set! *selection-creates-region* old-selection-creates-region)) (let ((ind (new-sound "tmp.snd" 1 22050 mus-ldouble mus-next :size 10 :comment #f))) (map-channel (lambda (y) 1.0)) (env-channel '(0 0 .1 .1 .2 .2 .3 .3 .4 .4 .5 .5 .6 .6 .7 .7 .8 .8 .9 .9)) (if (not (vequal (channel->float-vector) (float-vector 0.000 0.100 0.200 0.300 0.400 0.500 0.600 0.700 0.800 0.900))) (snd-display #__line__ ";ramp env by .1: ~A" (channel->float-vector))) (close-sound ind)) ) (set! (hook-functions open-raw-sound-hook) ()) (hook-push open-raw-sound-hook (lambda (hook) (set! (hook 'result) #t))) (set! (hook-functions bad-header-hook) ()) (hook-push bad-header-hook (lambda (hook) (set! (hook 'result) #t))) (if (null? (hook-functions open-raw-sound-hook)) (snd-display #__line__ ";add hook open-raw-sound-hook failed??")) (if (null? (hook-functions bad-header-hook)) (snd-display #__line__ ";add hook bad-header-hook failed??")) (let* ((magic-words (list ".snd" "FORM" "AIFF" "AIFC" "COMM" "COMT" "INFO" "INST" "inst" "MARK" "SSND" "FVER" "NONE" "ULAW" "ulaw" "ima4" "raw " "sowt" "in32" "in24" "ni23" "fl32" "FL32" "fl64" "twos" "ALAW" "alaw" "APPL" "CLM " "RIFF" "RIFX" "WAVE" "fmt " "data" "fact" "clm " "NIST" "8SVX" "16SV" "Crea" "tive" "SOUN" "D SA" "MPLE" "BODY" "VHDR" "CHAN" "ANNO" "NAME" "2BIT" "HCOM" "FSSD" "%//\n" "%---" "ALaw" "Soun" "MAUD" "MHDR" "MDAT" "mdat" "MThd" "sfbk" "sdta" "shdr" "pdta" "LIST" "GF1P" "ATCH" "$SIG" "NAL_" "GOLD" " SAM" "SRFS" "Diam" "ondW" "CSRE" "SND " "SNIN" "SNDT" "DDSF" "FSMu" "UWFD" "LM89" "SY80" "SY85" "SCRS" "DSPL" "AVI " "strf" "movi" "PRAM" " paf" "fap " "DS16" "HEDR" "HDR8" "SDA_" "SDAB" "SD_B" "NOTE" "file" "=sam" "SU7M" "SU7R" "PVF1" "PVF2" "AUTH" "riff" "TWIN" "IMPS" "SMP1" "Maui" "SDIF")) (len (length magic-words)) (ctr 0)) (for-each (lambda (magic) (if (null? (hook-functions open-raw-sound-hook)) (snd-display #__line__ ";open-raw-sound-hook cleared??")) (if (null? (hook-functions bad-header-hook)) (snd-display #__line__ ";bad-header-hook cleared??")) (if (file-exists? "test.snd") (delete-file "test.snd")) (mus-sound-forget "test.snd") ;; try random garbage (with-output-to-file "test.snd" (lambda () (display magic) (do ((i 0 (+ i 1))) ((= i 128)) (write (random 1.0))))) (let ((tag (catch #t (lambda () (open-sound "test.snd")) (lambda args (car args))))) (if (and (number? tag) (sound? tag)) (begin (snd-display #__line__ ";open-sound garbage ~A: ~A -> ~A?" magic tag (file->string "test.snd")) (if (sound? tag) (close-sound tag))))) (delete-file "test.snd") (mus-sound-forget "test.snd") ;; try plausible garbage (with-output-to-file "test.snd" (lambda () (display magic) (do ((i 0 (+ i 1))) ((= i 128)) (write (random 128))))) (let ((tag (catch #t (lambda () (open-sound "test.snd")) (lambda args (car args))))) (if (and (number? tag) (sound? tag)) (begin (snd-display #__line__ ";open-sound plausible garbage ~A: ~A?" magic tag) (if (sound? tag) (close-sound tag))))) (delete-file "test.snd") (mus-sound-forget "test.snd") ;; write very plausible garbage (with-output-to-file "test.snd" (lambda () (display magic) (do ((i 1 (+ i 1))) ((= i 12)) (if (< (+ ctr i) len) (display (magic-words (+ ctr i))) (display (magic-words i)))))) (let ((tag (catch #t (lambda () (open-sound "test.snd")) (lambda args (car args))))) (if (and (number? tag) (sound? tag)) (begin (snd-display #__line__ ";open-sound very plausible garbage ~A: ~A?" magic tag) (if (sound? tag) (close-sound tag))))) (set! ctr (+ ctr 1))) magic-words)) (if (file-exists? "test.snd") (delete-file "test.snd")) (mus-sound-forget "test.snd") (with-output-to-file "test.snd" (lambda () (display ".snd") (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o034) ; location (write-byte #o000) (write-byte #o001) (write-byte #o215) (write-byte #o030) ; nominal size (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o022) ; format (write-byte #o000) (write-byte #o000) (write-byte #o126) (write-byte #o042) ; srate (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o001) ; chans (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) ; comment (write-byte #o000) (write-byte #o001) ; samp 1 )) (if (not (= (mus-sound-sample-type "test.snd") mus-bshort)) (snd-display #__line__ ";next 18: ~A" (mus-sound-sample-type "test.snd"))) (delete-file "test.snd") (mus-sound-forget "test.snd") (with-output-to-file "test.snd" (lambda () (display ".snd") (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o004) ; location (write-byte #o000) (write-byte #o001) (write-byte #o215) (write-byte #o030) ; nominal size (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o022) ; format (write-byte #o000) (write-byte #o000) (write-byte #o126) (write-byte #o042) ; srate (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o001) ; chans (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) ; comment (write-byte #o000) (write-byte #o001) ; samp 1 )) (let ((tag (catch #t (lambda () (open-sound "test.snd")) (lambda args (car args))))) (if (and (number? tag) (sound? tag)) (begin (snd-display #__line__ ";open-sound next bad location ~A: ~A?" (data-location tag) tag) (close-sound tag)))) (delete-file "test.snd") (mus-sound-forget "test.snd") (letrec ((make-aifc-file (lambda (len auth-lo bits) (with-output-to-file "test.aif" (lambda () (display "FORM") (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o146) ; len (display "AIFCFVER") (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o004) ; version chunk size (write-byte #o242) (write-byte #o200) (write-byte #o121) (write-byte #o100) ; version (display "COMM") (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o046) ; COMM chunk size (write-byte #o000) (write-byte #o001) ; 1 chan (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte len) ; framples (write-byte #o000) (write-byte bits) ; bits (write-byte #o100) (write-byte #o016) (write-byte #o254) (write-byte #o104) (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) ; ;; srate as 80-bit float (sheesh) (display "NONE") ; compression (write-byte #o016) ; pascal string len (display "not compressed") (write-byte #o000) (display "AUTH") (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte auth-lo) ; AUTH chunk size (display "bil") (write-byte #o000) (display "SSND") (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o014) ; SSND chunk size (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) ; SSND data loc (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) ; block size? (write-byte #o000) (write-byte #o101) (write-byte #o000) (write-byte #o100) ; two samples ))))) (if (file-exists? "test.aif") (delete-file "test.aif")) (mus-sound-forget "test.aif") ;;correct (make-aifc-file #o002 #o004 #o020) (make-aifc-file #o102 #o004 #o020) (catch #t (lambda () (let ((ind (open-sound "test.aif"))) (if (not (= (framples ind) 2)) (snd-display #__line__ ";bad framples in header: ~A" (framples ind))) (close-sound ind))) (lambda args (snd-display #__line__ ";~S" args))) (delete-file "test.aif") (mus-sound-forget "test.aif") (make-aifc-file #o002 #o150 #o020) (let ((tag (catch #t (lambda () (open-sound "test.aif")) (lambda args (car args))))) (if (and (number? tag) (sound? tag)) (begin (snd-display #__line__ ";open-sound aifc no ssnd chunk ~A: ~A?" (data-location tag) tag) (close-sound tag)))) (delete-file "test.aif") (mus-sound-forget "test.aif") (make-aifc-file #o002 #o000 #o020) (let ((tag (catch #t (lambda () (open-sound "test.aif")) (lambda args (car args))))) (if (and (number? tag) (sound? tag)) (begin (snd-display #__line__ ";open-sound aifc 0-len auth chunk ~A: ~A?" (data-location tag) tag) (close-sound tag)))) (delete-file "test.aif") (mus-sound-forget "test.aif") (make-aifc-file #o002 #o150 #o120) (let ((tag (catch #t (lambda () (open-sound "test.aif")) (lambda args (car args))))) (if (and (number? tag) (sound? tag)) (begin (snd-display #__line__ ";open-sound bits 80 ~A: ~A?" (sample-type tag) tag) (close-sound tag)))) (delete-file "test.aif") (mus-sound-forget "test.aif")) (with-output-to-file "test.aif" (lambda () (display "FORM") (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o176) ; len (display "AIFCFVER") (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o004) ; version chunk size (write-byte #o242) (write-byte #o200) (write-byte #o121) (write-byte #o100) ; version (display "COMM") (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o046) ; COMM chunk size (write-byte #o000) (write-byte #o001) ; 1 chan (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o002) ; framples (write-byte #o000) (write-byte #o020) ; bits (write-byte #o100) (write-byte #o016) (write-byte #o254) (write-byte #o104) (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) ; srate as 80-bit float (sheesh) (display "NONE") ; compression (write-byte #o016) ; pascal string len (display "not compressed") (write-byte #o000) (display "AUTH") (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o004) ; AUTH chunk size (display "bil") (write-byte #o000) (display "ANNO") (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o004) ; AUTH chunk size (display "cat") (write-byte #o000) (display "NAME") (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o004) ; AUTH chunk size (display "dog") (write-byte #o000) (display "SSND") (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o014) ; SSND chunk size (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) ; SSND data loc (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) ; block size? (write-byte #o000) (write-byte #o101) (write-byte #o000) (write-byte #o100) ; two samples )) (catch #t (lambda () (if (not (= (length (mus-sound-comment "test.aif")) 15)) (snd-display #__line__ ";aifc 3 aux comments: ~A?" (mus-sound-comment "test.aif")))) (lambda args (snd-display #__line__ ";~S" args))) (delete-file "test.aif") (mus-sound-forget "test.aif") (with-output-to-file "test.aif" (lambda () (display "FORM") (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o142) ; len (display "AIFC") (display "SSND") (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o014) ; SSND chunk size (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) ; SSND data loc (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) ; block size? (write-byte #o000) (write-byte #o101) (write-byte #o000) (write-byte #o100) ; two samples (display "COMM") (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o046) ; COMM chunk size (write-byte #o000) (write-byte #o001) ; 1 chan (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o002) ; framples (write-byte #o000) (write-byte #o020) ; bits (write-byte #o100) (write-byte #o016) (write-byte #o254) (write-byte #o104) (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) ; srate as 80-bit float (sheesh) (display "NONE") ; compression (write-byte #o016) ; pascal string len (display "not compressed") (write-byte #o000) (display "COMT") (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o014) (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) (display "bil") (write-byte #o000) )) (catch #t (lambda () (if (not (string=? (substring (mus-sound-comment "test.aif") 0 3) "bil")) (snd-display #__line__ ";aifc trailing comt comment: ~A?" (mus-sound-comment "test.aif")))) (lambda args (snd-display #__line__ ";~S" args))) (if (not (= (mus-sound-framples "test.aif") 2)) (snd-display #__line__ ";aifc trailing comt framples: ~A?" (mus-sound-framples "test.aif"))) (catch #t (lambda () (let ((ind (open-sound "test.aif"))) (if (or (fneq (sample 0) 0.00198) (fneq (sample 1) 0.00195) (fneq (sample 2) 0.0) (fneq (sample 3) 0.0)) (snd-display #__line__ ";aifc trailing comt samps: ~A ~A ~A ~A" (sample 0) (sample 1) (sample 2) (sample 3))) (close-sound ind))) (lambda args (snd-display #__line__ ";~S" args))) (delete-file "test.aif") (mus-sound-forget "test.aif") (with-output-to-file "test.aif" (lambda () (display "FORM") (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o142) ; len (display "AIFC") (display "SSND") (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o014) ; SSND chunk size (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) ; SSND data loc (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) ; block size? (write-byte #o000) (write-byte #o101) (write-byte #o000) (write-byte #o100) ; two samples (display "COMM") (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o046) ; COMM chunk size (write-byte #o000) (write-byte #o001) ; 1 chan (write-byte #o000) (write-byte #o000) (write-byte #o100) (write-byte #o102) ; framples (write-byte #o000) (write-byte #o020) ; bits (write-byte #o100) (write-byte #o016) (write-byte #o254) (write-byte #o104) (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) ; srate as 80-bit float (sheesh) (display "NONE") ; compression (write-byte #o016) ; pascal string len (display "not compressed") (write-byte #o000) (display "COMT") (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o014) (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) (display "bil") (write-byte #o000) )) (if (or (not (string? (mus-sound-comment "test.aif"))) (not (string=? (substring (mus-sound-comment "test.aif") 0 3) "bil"))) (snd-display #__line__ ";aifc trailing comt comment: ~A?" (mus-sound-comment "test.aif"))) (if (not (= (mus-sound-framples "test.aif") 2)) (snd-display #__line__ ";aifc trailing comt (bogus) framples: ~A?" (mus-sound-framples "test.aif"))) (catch #t (lambda () (let ((ind (open-sound "test.aif"))) (if (or (fneq (sample 0) 0.00198) (fneq (sample 1) 0.00195) (fneq (sample 2) 0.0) (fneq (sample 3) 0.0)) (snd-display #__line__ ";aifc trailing comt samps (bogus frame setting): ~A ~A ~A ~A" (sample 0) (sample 1) (sample 2) (sample 3))) (close-sound ind))) (lambda args (snd-display #__line__ ";~S" args))) (delete-file "test.aif") (mus-sound-forget "test.aif") (with-output-to-file "test.aif" (lambda () (display "FORM") (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o142) ; len (display "AIFC") (display "SSND") (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o014) ; SSND chunk size (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) ; SSND data loc (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) ; block size? (write-byte #o000) (write-byte #o101) (write-byte #o000) (write-byte #o100) ; two samples (display "COMM") (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o046) ; COMM chunk size (write-byte #o000) (write-byte #o001) ; 1 chan (write-byte #o000) (write-byte #o000) (write-byte #o100) (write-byte #o102) ; framples (write-byte #o000) (write-byte #o020) ; bits (write-byte #o100) (write-byte #o016) (write-byte #o254) (write-byte #o104) (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) ; srate as 80-bit float (sheesh) (display "NONE") ; compression (write-byte #o016) ; pascal string len (display "not compressed") (write-byte #o000) (display "SSND") (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o014) ; SSND chunk size (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) ; SSND data loc (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) ; block size? (write-byte #o000) (write-byte #o101) (write-byte #o000) (write-byte #o100) ; two samples )) (let ((tag (catch #t (lambda () (open-sound "test.aif")) (lambda args (car args))))) (if (and (number? tag) (sound? tag)) (begin (snd-display #__line__ ";open-sound aifc 2 ssnd chunks ~A: ~A?" (data-location tag) tag) (close-sound tag)))) (delete-file "test.aif") (mus-sound-forget "test.aif") (with-output-to-file "test.aif" (lambda () (display "FORM") (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o040) ; len (display "AIFC") (display "SSND") (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o014) ; SSND chunk size (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) ; SSND data loc (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) ; block size? (write-byte #o000) (write-byte #o101) (write-byte #o000) (write-byte #o100) ; two samples )) (let ((tag (catch #t (lambda () (open-sound "test.aif")) (lambda args (car args))))) (if (not (eq? tag 'mus-error)) (begin (snd-display #__line__ ";open-sound aifc no comm chunk ~A?" tag) (if (and (number? tag) (sound? tag)) (close-sound tag))))) (delete-file "test.aif") (mus-sound-forget "test.aif") (with-output-to-file "test.aif" (lambda () ;write AIFC with trailing chunks to try to confuse file->sample (display "FORM") (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o176) ; len (display "AIFCFVER") (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o004) ; version chunk size (write-byte #o242) (write-byte #o200) (write-byte #o121) (write-byte #o100) ; version (display "COMM") (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o046) ; COMM chunk size (write-byte #o000) (write-byte #o001) ; 1 chan (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o002) ; framples (write-byte #o000) (write-byte #o020) ; bits (write-byte #o100) (write-byte #o016) (write-byte #o254) (write-byte #o104) (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) ; srate as 80-bit float (sheesh) (display "NONE") ; compression (write-byte #o016) ; pascal string len (display "not compressed") (write-byte #o000) (display "SSND") (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o014) ; SSND chunk size (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) ; SSND data loc (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) ; block size? (write-byte #o170) (write-byte #o101) (write-byte #o100) (write-byte #o100) ; two samples (display "AUTH") (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o004) ; AUTH chunk size (display "bil") (write-byte #o000) (display "ANNO") (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o004) ; AUTH chunk size (display "cat") (write-byte #o000) (display "NAME") (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o004) ; AUTH chunk size (display "dog") (write-byte #o000) )) (catch #t (lambda () (let ((gen (make-file->sample "test.aif"))) (if (fneq (gen 0) 0.93948) (snd-display #__line__ ";file->sample chunked 0: ~A" (gen 0))) (if (fneq (gen 1) 0.50195) (snd-display #__line__ ";file->sample chunked 1: ~A" (gen 1))) (if (fneq (gen 2) 0.0) (snd-display #__line__ ";file->sample chunked eof: ~A" (gen 2))) (if (fneq (gen 3) 0.0) (snd-display #__line__ ";file->sample chunked eof+1: ~A" (gen 3)))) (let ((file (open-sound "test.aif"))) (if (not (= (framples file) 2)) (snd-display #__line__ ";chunked framples: ~A" (framples file))) (if (fneq (sample 0) 0.93948) (snd-display #__line__ ";file chunked 0: ~A" (sample 0))) (if (fneq (sample 1) 0.50195) (snd-display #__line__ ";file chunked 1: ~A" (sample 1))) (if (fneq (sample 2) 0.0) (snd-display #__line__ ";file chunked eof: ~A" (sample 2))) (if (fneq (sample 3) 0.0) (snd-display #__line__ ";file chunked eof+1: ~A" (sample 3))) (close-sound file))) (lambda args (snd-display #__line__ ";~S" args))) (catch #t (lambda () (if (not (= (mus-sound-framples "test.aif") 2)) (snd-display #__line__ ";chunked mus-sound-framples: ~A" (mus-sound-framples "test.aif")))) (lambda args (snd-display #__line__ ";~S" args))) (delete-file "test.aif") (mus-sound-forget "test.aif") (with-output-to-file "test.aif" (lambda () ;write AIFC with trailing chunks to try to confuse file->sample (display "FORM") (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o176) ; len (display "AIFCFVER") (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o004) ; version chunk size (write-byte #o242) (write-byte #o200) (write-byte #o121) (write-byte #o100) ; version (display "SSND") (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o014) ; SSND chunk size (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) ; SSND data loc (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) ; block size? (write-byte #o170) (write-byte #o101) (write-byte #o100) (write-byte #o100) ; two samples (display "COMM") (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o046) ; COMM chunk size (write-byte #o000) (write-byte #o001) ; 1 chan (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o002) ; framples (write-byte #o000) (write-byte #o020) ; bits (write-byte #o100) (write-byte #o016) (write-byte #o254) (write-byte #o104) (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) ; srate as 80-bit float (sheesh) (display "NONE") ; compression (write-byte #o016) ; pascal string len (display "not compressed") (write-byte #o000) (display "APPL") (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte (char->integer #\h)) (display "CLM ;Written Mon 02-Nov-98 01:44 CST by root at ockeghem (Linux/X86) using Allegro CL, clm of 20-Oct-98") (write-byte #o000) )) (catch #t (lambda () (let ((gen (make-file->sample "test.aif"))) (if (fneq (gen 0) 0.93948) (snd-display #__line__ ";file->sample chunked 0: ~A" (gen 0))) (if (fneq (gen 1) 0.50195) (snd-display #__line__ ";file->sample chunked 1: ~A" (gen 1))) (if (fneq (gen 2) 0.0) (snd-display #__line__ ";file->sample chunked eof: ~A" (gen 2))) (if (fneq (gen 3) 0.0) (snd-display #__line__ ";file->sample chunked eof+1: ~A" (gen 3)))) (let ((file (open-sound "test.aif"))) (if (not (= (framples file) 2)) (snd-display #__line__ ";chunked framples: ~A" (framples file))) (if (fneq (sample 0) 0.93948) (snd-display #__line__ ";file chunked 0: ~A" (sample 0))) (if (fneq (sample 1) 0.50195) (snd-display #__line__ ";file chunked 1: ~A" (sample 1))) (if (fneq (sample 2) 0.0) (snd-display #__line__ ";file chunked eof: ~A" (sample 2))) (if (fneq (sample 3) 0.0) (snd-display #__line__ ";file chunked eof+1: ~A" (sample 3))) (if (or (not (string? (comment))) (not (string=? (comment) ";Written Mon 02-Nov-98 01:44 CST by root at ockeghem (Linux/X86) using Allegro CL, clm of 20-Oct-98"))) (snd-display #__line__ ";chunked appl comment: ~A" (comment))) (close-sound file))) (lambda args (snd-display #__line__ ";~S" args))) (delete-file "test.aif") (mus-sound-forget "test.aif") (with-output-to-file "test.aif" (lambda () ;write AIFC with trailing chunks to try to confuse file->sample (display "FORM") (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o176) ; len (display "AIFCFVER") (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o004) ; version chunk size (write-byte #o242) (write-byte #o200) (write-byte #o121) (write-byte #o100) ; version (display "SSND") (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o014) ; SSND chunk size (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) ; SSND data loc (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) ; block size? (write-byte #o170) (write-byte #o101) (write-byte #o100) (write-byte #o100) ; two samples (one frame) (display "COMM") (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o046) ; COMM chunk size (write-byte #o000) (write-byte #o002) ; 2 chans (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o001) ; framples (write-byte #o000) (write-byte #o020) ; bits (write-byte #o100) (write-byte #o016) (write-byte #o254) (write-byte #o104) (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte #o000) ; srate as 80-bit float (sheesh) (display "NONE") ; compression (write-byte #o016) ; pascal string len (display "not compressed") (write-byte #o000) (display "APPL") (write-byte #o000) (write-byte #o000) (write-byte #o000) (write-byte (char->integer #\h)) (display "CLM ;Written Mon 02-Nov-98 01:44 CST by root at ockeghem (Linux/X86) using Allegro CL, clm of 20-Oct-98") (write-byte #o000) )) (catch #t (lambda () (let ((gen (make-file->sample "test.aif"))) (if (fneq (gen 0 0) 0.93948) (snd-display #__line__ ";file->sample chunked 0 0: ~A" (gen 0 0))) (if (fneq (gen 0 1) 0.50195) (snd-display #__line__ ";file->sample chunked 0 1: ~A" (gen 0 1))) (if (fneq (gen 1 0) 0.0) (snd-display #__line__ ";file->sample chunked eof(stereo): ~A" (gen 1 0))) (if (fneq (gen 1 1) 0.0) (snd-display #__line__ ";file->sample chunked eof+1 (stereo): ~A" (gen 1 1)))) (let ((file (open-sound "test.aif"))) (if (not (= (framples file) 1)) (snd-display #__line__ ";chunked framples (1): ~A" (framples file))) (if (fneq (sample 0 file 0) 0.93948) (snd-display #__line__ ";file chunked 0 0: ~A" (sample 0 file 0))) (if (fneq (sample 0 file 1) 0.50195) (snd-display #__line__ ";file chunked 0 1: ~A" (sample 0 file 1))) (if (fneq (sample 1 file 0) 0.0) (snd-display #__line__ ";file chunked eof (stereo): ~A" (sample 1 file 0))) (if (fneq (sample 1 file 1) 0.0) (snd-display #__line__ ";file chunked eof+1 (stereo): ~A" (sample 1 file 1))) (if (or (not (string? (comment))) (not (string=? (comment) ";Written Mon 02-Nov-98 01:44 CST by root at ockeghem (Linux/X86) using Allegro CL, clm of 20-Oct-98"))) (snd-display #__line__ ";chunked appl comment (stereo): ~A" (comment))) (close-sound file))) (lambda args (snd-display #__line__ ";~S" args))) (delete-file "test.aif") (mus-sound-forget "test.aif") (let ((files (sound-files-in-directory cwd))) (define (difference a b) (let ((diffs ())) (for-each (lambda (f) (if (not (member f b)) (set! diffs (cons f diffs)))) a) (for-each (lambda (f) (if (not (member f a)) (set! diffs (cons f diffs)))) b) diffs)) (if (null? files) (snd-display #__line__ ";no sound files in ~A?" cwd)) (let ((files1 (sound-files-in-directory))) (if (not (equal? files files1)) (snd-display #__line__ ";different sound files in ~A and default?~% ~A~% ~A~%" cwd files files1)) (let ((files2 (sound-files-in-directory "."))) (if (or (not (equal? files1 files2)) (not (equal? files files2))) (snd-display #__line__ ";sound-files-in-directory dot: ~A~% ~A~% but ~A" (difference files2 files) files2 files))))) (set! (hook-functions bad-header-hook) ()) (set! (hook-functions open-raw-sound-hook) ()) (if (pair? (sounds)) (for-each close-sound (sounds))) (let ((ind (new-sound :size 0))) (if (not (= (framples ind) 0)) (snd-display #__line__ ";new-sound :size 0 -> ~A framples" (framples ind))) (if (fneq (sample 0) 0.0) (snd-display #__line__ ";new-sound :size 0 sample 0: ~A" (sample 0))) (let ((new-file-name (file-name ind))) (close-sound ind) (if (file-exists? new-file-name) (delete-file new-file-name)))) (let ((ind (new-sound :size 1))) (if (not (= (framples ind) 1)) (snd-display #__line__ ";new-sound :size 1 -> ~A framples" (framples ind))) (if (fneq (sample 0) 0.0) (snd-display #__line__ ";new-sound :size 1 sample 0: ~A" (sample 0))) (let ((new-file-name (file-name ind))) (close-sound ind) (if (file-exists? new-file-name) (delete-file new-file-name)))) (let ((tag (catch #t (lambda () (new-sound :size -1)) (lambda args (car args))))) (if (not (eq? tag 'out-of-range)) (begin (snd-display #__line__ ";new-sound :size -1: ~A" tag) (if (pair? (sounds)) (for-each close-sound (sounds)))))) (let ((ind (read-ascii (string-append sf-dir "caruso.asc")))) (if (not (sound? ind)) (snd-display #__line__ ";read-ascii can't find ~A (~A)" (string-append sf-dir "caruso.asc") (map file-name (sounds))) (begin (if (fneq (maxamp ind 0) 0.723) (snd-display #__line__ ";read-ascii maxamp: ~A" (maxamp ind 0))) (if (not (= (framples ind 0) 50000)) (snd-display #__line__ ";read-ascii framples: ~A" (framples ind 0))) (if (not (= (srate ind) 44100)) (snd-display #__line__ ";read-ascii srate: ~A" (srate ind))) (set! (srate ind) 8000) (if (or (not (= (framples ind 0) 50000)) (fneq (maxamp ind 0) .723)) (snd-display #__line__ ";set srate clobbered new sound: ~A ~A (~A)" (framples ind 0) (maxamp ind 0) (srate ind))) (close-sound ind)))) (let ((ind (open-sound "oboe.snd"))) (save-sound-as "test space.snd") (close-sound ind) (set! ind (open-sound "test space.snd")) (if (not (string=? (short-file-name ind) "test space.snd")) (snd-display #__line__ ";file name with space: ~A" (short-file-name ind))) (let ((len (framples ind)) (slen (mus-sound-framples "test space.snd"))) (if (not (= len slen)) (snd-display #__line__ ";spaced filename framples: ~A ~A" len slen))) (add-mark 1234 ind 0) (save-marks ind) ; should write "test space.marks" (close-sound ind) (set! ind (open-sound "test space.snd")) (load (string-append cwd "test space.marks")) (if (not (find-mark 1234 ind)) (snd-display #__line__ ";space file name save marks: ~A" (marks ind))) (let ((rd (make-readin :file "test space.snd"))) (if (not (string=? (mus-file-name rd) "test space.snd")) (snd-display #__line__ ";file name with space readin: ~A" (mus-file-name rd)))) (close-sound ind) (if (file-exists? "test space.snd") (delete-file "test space.snd")) (if (file-exists? "test space.marks") (delete-file "test space.marks"))) (if (directory? "oboe.snd") (snd-display #__line__ ";directory? oboe.snd!")) (if (not (directory? ".")) (snd-display #__line__ ";directory? . #f!")) (if (not (getenv "PATH")) (snd-display #__line__ ";getenv: no PATH?")) (if (not (number? (getpid))) (snd-display #__line__ ";getpid: ~A" (getpid))) (unless (provided? 'pure-s7) (let ((ip (current-input-port))) (let ((tag (catch #t (lambda () (set-current-input-port "hiho!")) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";set-current-input-port tag: ~A" tag)) (if (not (equal? ip (current-input-port))) (snd-display #__line__ ";set-current-input-port clobbered port? ~A ~A" ip (current-input-port))))) (let ((ip (current-output-port))) (let ((tag (catch #t (lambda () (set-current-output-port "hiho!")) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";set-current-output-port tag: ~A" tag)) (if (not (equal? ip (current-output-port))) (snd-display #__line__ ";set-current-output-port clobbered port? ~A ~A" ip (current-output-port))))) (let ((ip (current-error-port))) (let ((tag (catch #t (lambda () (set-current-error-port "hiho!")) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";set-current-error-port tag: ~A" tag)) (if (not (equal? ip (current-error-port))) (snd-display #__line__ ";set-current-error-port clobbered port? ~A ~A" ip (current-error-port)))))) (if (not (provided? 'gmp)) (let* ((LONG_MAX 2147483647) (LONG_MIN -2147483648) (LLONG_MAX most-positive-fixnum) (LLONG_MIN most-negative-fixnum) (ints (list 0 1 -1 10 -10 1234 -1234 LONG_MAX LONG_MIN 65536 -65536)) (shorts (list 0 1 -1 10 -10 1234 -1234 32767 -32768 8191 -8191)) (longs (list 0 1 -1 11 -11 LONG_MAX LONG_MIN LLONG_MAX LLONG_MIN 1000 -1000)) (floats (list 0.0 1.0 -1.0 0.1 -0.1 10.0 -10.0 1234.0 65536.0 -1234.0 -0.003)) (doubles (list 0.0 1.0 -1.0 0.1 -0.1 10.0 -10.0 1234.0 65536.0 -1234.0 -0.003))) (load "binary-io.scm") (with-output-to-file "idf1.data" (lambda () (write-lint32 123) (write-bint32 321) (do ((i 0 (+ i 1))) ((= i 11)) (write-lint32 (ints i)) (write-bint32 (ints i))) (do ((i 0 (+ i 1))) ((= i 11)) (write-lint16 (shorts i)) (write-bint16 (shorts i))) (do ((i 0 (+ i 1))) ((= i 11)) (write-lint64 (longs i)) (write-bint64 (longs i))) (do ((i 0 (+ i 1))) ((= i 11)) (write-lfloat32 (floats i)) (write-bfloat32 (floats i))) (do ((i 0 (+ i 1))) ((= i 11)) (write-lfloat64 (doubles i)) (write-bfloat64 (doubles i))) )) (with-input-from-file "idf1.data" (lambda () (define (testf val1 val2 name) (if (not (= val1 val2)) (if (and (not (eq? name 'lfloat32)) (not (eq? name 'bfloat32))) (snd-display #__line__ ";testf ~A: ~A != ~A~%" name val1 val2) (if (> (abs (- val1 val2)) 1.0e-6) (snd-display #__line__ ";testf ~A: ~A != ~A (~A)~%" name val1 val2 (abs (- val1 val2))))))) (testf (read-lint32) 123 'lint32) (testf (read-bint32) 321 'bint32) (do ((i 0 (+ i 1))) ((= i 11)) (testf (read-lint32) (ints i) 'lint32) (testf (read-bint32) (ints i) 'bint32)) (do ((i 0 (+ i 1))) ((= i 11)) (testf (read-lint16) (shorts i) 'lint16) (testf (read-bint16) (shorts i) 'bint16)) (do ((i 0 (+ i 1))) ((= i 11)) (testf (read-lint64) (longs i) 'lint64) (testf (read-bint64) (longs i) 'bint64)) (do ((i 0 (+ i 1))) ((= i 11)) (testf (read-lfloat32) (floats i) 'lfloat32) (testf (read-bfloat32) (floats i) 'bfloat32)) (do ((i 0 (+ i 1))) ((= i 11)) (testf (read-lfloat64) (doubles i) 'lfloat64) (testf (read-bfloat64) (doubles i) 'bfloat64)) )) )) )) ;;; ---------------- test 5: simple overall checks ---------------- (require snd-selection.scm snd-extensions.scm snd-selection.scm snd-dsp.scm snd-pvoc.scm) (if with-gui (require snd-edit-menu.scm)) (define (snd_test_5) (define a-ctr 0) (define g-init-val 0) (define (append-sound filename) (insert-sound filename (framples))) (define (test-edpos test-func func-name change-thunk ind1) (let ((fr1 (test-func ind1 0)) (fr2 (test-func ind1 0 0)) (fr3 (test-func ind1 0 current-edit-position))) (if (not (= fr1 fr2 fr3)) (snd-display #__line__ ";initial ~A: ~A ~A ~A?" func-name fr1 fr2 fr3)) (change-thunk) (let ((fr5 (test-func ind1 0)) (fr6 (test-func ind1 0 1)) (fr7 (test-func ind1 0 current-edit-position))) (if (not (= fr5 fr6 fr7)) (snd-display #__line__ ";~A (edpos 1): ~A ~A ~A?" func-name fr5 fr6 fr7)))) (revert-sound ind1)) (define (test-edpos-1 test-func func-name ind1) (let ((v0 (channel->float-vector 12000 10 ind1 0))) (test-func ind1 0) (let ((v1 (channel->float-vector 12000 10 ind1 0))) (if (vequal v0 v1) (snd-display #__line__ ";~A (0) no change! ~A ~A" func-name v0 v1)) (test-func ind1 0) (let ((v2 (channel->float-vector 12000 10 ind1 0))) (if (not (vequal v1 v2)) (snd-display #__line__ ";~A (1) ~A ~A" func-name v1 v2))))) (revert-sound ind1)) (define (test-orig func0 func1 func-name ind1) (let ((v0 (channel->float-vector 12000 10 ind1 0))) (func0 ind1) (let ((v1 (channel->float-vector 12000 10 ind1 0))) (if (vequal1 v0 v1) (snd-display #__line__ ";~A (orig: 0) no change! ~A ~A" func-name v0 v1)) (func1 ind1) (let ((v2 (channel->float-vector 12000 10 ind1 0))) (if (not (vequal1 v0 v2)) (snd-display #__line__ ";~A (orig: 1) ~A ~A" func-name v0 v2)))) (revert-sound ind1))) (define* (make-bandpass-2 flo1 fhi1 flo2 fhi2 (len 30)) (let ((f1 (make-bandpass flo1 fhi1 len)) (f2 (make-bandpass flo2 fhi2 len))) (float-vector-add! (mus-xcoeffs f1) (mus-xcoeffs f2)) f1)) #| (define* (cosine-channel (beg 0) dur snd chn edpos) (let ((samps (or dur (framples snd chn)))) (map-channel (let ((incr (/ pi samps)) (angle (* -0.5 pi))) (lambda (y) (let ((val (* y (cos angle)))) (set! angle (+ angle incr)) val))) beg dur snd chn edpos) )) |# (define* (cosine-channel (beg 0) dur snd chn edpos) (let ((samps (or dur (framples snd chn)))) (map-channel (let ((incr (/ pi samps)) (angle (* -0.5 pi)) (p (make-one-pole 1.0 -1.0))) (one-pole p (- angle incr)) (lambda (y) (* y (cos (one-pole p incr))))) beg dur snd chn edpos) )) (define (check-maxamp caller-line ind val name) (if (fneq (maxamp ind 0) val) (snd-display #__line__ ";maxamp amp-env ~A: ~A should be ~A" name (maxamp ind) val)) (let ((pos (scan-channel (lambda (y) (>= (abs y) (- val .0001))))) (maxpos (maxamp-position ind 0))) (if (not pos) (snd-display #__line__ ";actual maxamp ~A vals not right" name) (if (not (= maxpos pos)) (snd-display #__line__ ";~A: find and maxamp-position disagree: ~A (~A) ~A (~A)" name pos (sample pos ind 0) maxpos (sample maxpos ind 0)))) (let ((mx 0.0) (data #f) (mpos 0) (len (framples ind))) (let ((info (float-vector-peak-and-location (samples 0 len ind)))) (set! mpos (cadr info)) (set! mx (car info))) (if (not (= mpos maxpos)) (snd-display #__line__ ";(~D) scan and maxamp-position disagree: ~A ~A" caller-line mpos maxpos)) (if (fneq mx val) (snd-display #__line__ ";(~D) actual ~A max: ~A (correct: ~A)" caller-line name mx val))))) (define (check-env-vals name gen) (let ((len (framples)) (reader (make-sampler))) (call-with-exit (lambda (quit) (do ((i 0 (+ i 1))) ((= i len)) (let ((val (env gen)) (y (next-sample reader))) (if (fneq val y) (begin (format #t "~%;check-env-vals ~A at ~D: ~A ~A" name i val y) (quit))))))))) (define (our-x->position ind x) (let ((ax (axis-info ind 0))) (list (+ (ax 10) (/ (* (- x (ax 2)) (- (ax 12) (ax 10))) (- (ax 4) (ax 2)))) (x->position x ind)))) (define (region-to-float-vector r c len) (let ((rs (make-region-sampler r 0 c)) (v (make-float-vector len))) (outa->fv v (next-sample rs)))) (define (region2float-vector r c len) (region->float-vector r 0 len c)) (if (playing) (snd-display #__line__ ";dac is running??")) (do ((clmtest 0 (+ 1 clmtest))) ((= clmtest tests)) (log-mem clmtest) (let ((ind (open-sound "oboe.snd"))) (set! (transform-graph? ind 0) #t) (set! (transform-graph-type ind 0) graph-as-sonogram) (catch 'no-such-axis (lambda () (set! (y-axis-label ind 0 1) "hiho")) (lambda args (snd-display #__line__ ";no fft axis: ~A" args))) (set! (fft-log-frequency ind 0) #t) ; segfault here originally (update-transform-graph ind 0) (close-sound ind)) (let ((ind (new-sound "test.snd" :size 10))) (float-vector->channel (make-float-vector 10 1.0)) (env-channel '(0 0 1 1 2 0)) (let ((data (channel->float-vector))) (if (not (vequal data (float-vector 0.000 0.200 0.400 0.600 0.800 1.000 0.750 0.500 0.250 0.000))) (snd-display #__line__ ";pyr 10: ~A" data))) (undo) (env-channel '((0 0) (1 1) (2 0))) (let ((data (channel->float-vector))) (if (not (vequal data (float-vector 0.000 0.200 0.400 0.600 0.800 1.000 0.750 0.500 0.250 0.000))) (snd-display #__line__ ";pyr 10: ~A" data))) (undo) (env-channel (make-env '(0 0 1 1 2 0) :length 10)) (let ((data (channel->float-vector))) (if (not (vequal data (float-vector 0.000 0.200 0.400 0.600 0.800 1.000 0.750 0.500 0.250 0.000))) (snd-display #__line__ ";pyr 10: ~A" data))) (undo) (close-sound ind)) (for-each (lambda (size) (let ((ind (new-sound "test.snd" :size size)) (incr (/ 1.0 (- size 1))) (e (make-env '(0 0 1 1) :length size))) (float-vector->channel (make-float-vector size 1.0)) (ramp-channel 0.0 1.0) (let ((data (channel->float-vector))) (if (or (fneq (data 0) 0.0) (fneq (data (- size 1)) 1.0)) (snd-display #__line__ ";ramp-channel ~A end points: ~A ~A" size (data 0) (data (- size 1)))) (do ((i 0 (+ i 1))) ((= i size)) (let ((val (envelope-interp (* i incr) '(0.0 0.0 1.0 1.0))) (segval (env e))) (if (or (fneq segval val) (fneq (data i) val)) (snd-display #__line__ ";ramp-channel ~A of ~A: ramp: ~A, interp: ~A, env: ~A" i size (data i) val segval))))) (undo) (xramp-channel 0.0 1.0 32.0) (let ((e (make-env '(0 0 1 1) :length size :base 32.0))) (let ((data (channel->float-vector))) (if (or (fneq (data 0) 0.0) (fneq (data (- size 1)) 1.0)) (snd-display #__line__ ";xramp-channel 32 ~A end points: ~A ~A" size (data 0) (data (- size 1)))) (do ((i 0 (+ i 1))) ((= i size)) (let ((val (envelope-interp (* i incr) '(0.0 0.0 1.0 1.0) 32.0)) (segval (env e))) (if (or (fneq segval val) (fneq (data i) val)) (snd-display #__line__ ";xramp-channel 32 ~A of ~A: ramp: ~A, interp: ~A, env: ~A" i size (data i) val segval)))))) (undo) (xramp-channel 0.0 1.0 0.4) (let ((e (make-env '(0 0 1 1) :length size :base 0.4))) (let ((data (channel->float-vector))) (if (or (fneq (data 0) 0.0) (fneq (data (- size 1)) 1.0)) (snd-display #__line__ ";xramp-channel .4 ~A end points: ~A ~A" size (data 0) (data (- size 1)))) (do ((i 0 (+ i 1))) ((= i size)) (let ((val (envelope-interp (* i incr) '(0.0 0.0 1.0 1.0) 0.4)) (segval (env e))) (if (or (fneq segval val) (fneq (data i) val)) (snd-display #__line__ ";xramp-channel .4 ~A of ~A: ramp: ~A, interp: ~A, env: ~A" i size (data i) val segval)))))) (undo) (xramp-channel 1.0 -1.0 8.0) (let ((e (make-env '(0 1 1 -1) :length size :base 8.0))) (let ((data (channel->float-vector))) (if (or (fneq (data 0) 1.0) (fneq (data (- size 1)) -1.0)) (snd-display #__line__ ";xramp-channel 1 -1 8 ~A end points: ~A ~A" size (data 0) (data (- size 1)))) (do ((i 0 (+ i 1))) ((= i size)) (let ((segval (env e))) (if (fneq segval (data i)) (snd-display #__line__ ";xramp-channel 1 -1 8 ~A of ~A: ramp: ~A, env: ~A" i size (data i) segval)))))) (undo) (close-sound ind))) (list 10 100 1000)) ;; basic edit tree cases (let ((ind (new-sound "test.snd"))) (if (not (= (redo) 0)) (snd-display #__line__ ";redo with no ops: ~A" (redo))) (if (not (= (undo) 0)) (snd-display #__line__ ";undo with no ops: ~A" (undo))) (if (not (string-=? (display-edits) (string-append " EDITS: 0 (begin) [0:2]: (at 0, cp->sounds[0][0:0, 0.000]) [file: " cwd "test.snd[0]] (at 1, end_mark) "))) (snd-display #__line__ ";new 0: ~A" (display-edits))) (insert-samples 10 10 (make-float-vector 10)) (if (not (= (framples) 20)) (snd-display #__line__ ";new 1 framples: ~A" (framples))) (if (not (string-=? (display-edits) (string-append " EDITS: 1 (begin) [0:2]: (at 0, cp->sounds[0][0:0, 0.000]) [file: " cwd "test.snd[0]] (at 1, end_mark) (insert 1 20) ; insert-samples [1:4]: (at 0, cp->sounds[0][0:0, 0.000]) [file: " cwd "test.snd[0]] (at 1, cp->sounds[-1][0:8, 0.000]) (at 10, cp->sounds[1][0:9, 1.000]) [buf: 10] (at 20, end_mark) "))) (snd-display #__line__ ";new 1: ~A" (display-edits))) (undo) (insert-samples 0 10 (make-float-vector 10)) (if (not (= (framples) 11)) (snd-display #__line__ ";new 2 framples: ~A" (framples))) ; 11 because there was 1 sample when new-sound created (if (not (string-=? (display-edits) (string-append " EDITS: 1 (begin) [0:2]: (at 0, cp->sounds[0][0:0, 0.000]) [file: " cwd "test.snd[0]] (at 1, end_mark) (insert 0 10) ; insert-samples [1:3]: (at 0, cp->sounds[1][0:9, 1.000]) [buf: 10] (at 10, cp->sounds[0][0:0, 0.000]) [file: " cwd "test.snd[0]] (at 11, end_mark) "))) (snd-display #__line__ ";new 2: ~A" (display-edits))) (let ((eds (undo 2))) (if (not (= eds 2)) (snd-display #__line__ ";new 3 undo: ~A" eds))) (insert-samples 0 10 (make-float-vector 10)) (if (not (= (framples) 11)) (snd-display #__line__ ";new 3 framples: ~A" (framples))) (if (not (string-=? (display-edits) (string-append " EDITS: 1 (begin) [0:2]: (at 0, cp->sounds[0][0:0, 0.000]) [file: " cwd "test.snd[0]] (at 1, end_mark) (insert 0 10) ; insert-samples [1:3]: (at 0, cp->sounds[1][0:9, 1.000]) [buf: 10] (at 10, cp->sounds[0][0:0, 0.000]) [file: " cwd "test.snd[0]] (at 11, end_mark) "))) (snd-display #__line__ ";new 3: ~A" (display-edits))) (undo) (set! (sample 0) .5) (if (not (= (framples) 1)) (snd-display #__line__ ";new 4 framples: ~A" (framples))) (if (not (string-=? (display-edits) (string-append " EDITS: 1 (begin) [0:2]: (at 0, cp->sounds[0][0:0, 0.000]) [file: " cwd "test.snd[0]] (at 1, end_mark) (set 0 1) ; set-sample 0 0.5000 [1:2]: (at 0, cp->sounds[1][0:0, 1.000]) [buf: 1] (at 1, end_mark) "))) (snd-display #__line__ ";new 4: ~A" (display-edits))) (undo) (set! (samples 0 10) (make-float-vector 10)) (if (not (= (framples) 10)) (snd-display #__line__ ";new 5 framples: ~A" (framples))) (if (not (string-=? (display-edits) (string-append " EDITS: 1 (begin) [0:2]: (at 0, cp->sounds[0][0:0, 0.000]) [file: " cwd "test.snd[0]] (at 1, end_mark) (set 0 10) ; set-samples [1:2]: (at 0, cp->sounds[1][0:9, 1.000]) [buf: 10] (at 10, end_mark) "))) (snd-display #__line__ ";new 5: ~A" (display-edits))) (delete-samples 3 4) (if (not (= (framples) 6)) (snd-display #__line__ ";new 6 framples: ~A" (framples))) (if (not (string-=? (safe-display-edits ind 0 2) " (delete 3 4) ; delete-samples 3 4 [2:3]: (at 0, cp->sounds[1][0:2, 1.000]) [buf: 10] (at 3, cp->sounds[1][7:9, 1.000]) [buf: 10] (at 6, end_mark) ")) (snd-display #__line__ ";new 6: ~A" (safe-display-edits ind 0 2))) (set! (samples 1 4) (make-float-vector 4)) (if (not (= (framples) 6)) (snd-display #__line__ ";new 7 framples: ~A" (framples))) (if (not (string-=? (safe-display-edits ind 0 3) " (set 1 4) ; set-samples [3:4]: (at 0, cp->sounds[1][0:0, 1.000]) [buf: 10] (at 1, cp->sounds[2][0:3, 1.000]) [buf: 4] (at 5, cp->sounds[1][9:9, 1.000]) [buf: 10] (at 6, end_mark) ")) (snd-display #__line__ ";new 7: ~A" (safe-display-edits ind 0 3))) (undo 2) (insert-samples 2 3 (make-float-vector 3)) (insert-samples 2 1 (make-float-vector 1)) (insert-samples 4 1 (make-float-vector 1)) (insert-samples 15 1 (make-float-vector 1)) (if (not (= (framples) 16)) (snd-display #__line__ ";new 8 framples: ~A" (framples))) (if (not (string-=? (display-edits) (string-append " EDITS: 5 (begin) [0:2]: (at 0, cp->sounds[0][0:0, 0.000]) [file: " cwd "test.snd[0]] (at 1, end_mark) (set 0 10) ; set-samples [1:2]: (at 0, cp->sounds[1][0:9, 1.000]) [buf: 10] (at 10, end_mark) (insert 2 3) ; insert-samples [2:4]: (at 0, cp->sounds[1][0:1, 1.000]) [buf: 10] (at 2, cp->sounds[2][0:2, 1.000]) [buf: 3] (at 5, cp->sounds[1][2:9, 1.000]) [buf: 10] (at 13, end_mark) (insert 2 1) ; insert-samples [3:5]: (at 0, cp->sounds[1][0:1, 1.000]) [buf: 10] (at 2, cp->sounds[3][0:0, 1.000]) [buf: 1] (at 3, cp->sounds[2][0:2, 1.000]) [buf: 3] (at 6, cp->sounds[1][2:9, 1.000]) [buf: 10] (at 14, end_mark) (insert 4 1) ; insert-samples [4:7]: (at 0, cp->sounds[1][0:1, 1.000]) [buf: 10] (at 2, cp->sounds[3][0:0, 1.000]) [buf: 1] (at 3, cp->sounds[2][0:0, 1.000]) [buf: 3] (at 4, cp->sounds[4][0:0, 1.000]) [buf: 1] (at 5, cp->sounds[2][1:2, 1.000]) [buf: 3] (at 7, cp->sounds[1][2:9, 1.000]) [buf: 10] (at 15, end_mark) (insert 15 1) ; insert-samples [5:8]: (at 0, cp->sounds[1][0:1, 1.000]) [buf: 10] (at 2, cp->sounds[3][0:0, 1.000]) [buf: 1] (at 3, cp->sounds[2][0:0, 1.000]) [buf: 3] (at 4, cp->sounds[4][0:0, 1.000]) [buf: 1] (at 5, cp->sounds[2][1:2, 1.000]) [buf: 3] (at 7, cp->sounds[1][2:9, 1.000]) [buf: 10] (at 15, cp->sounds[5][0:0, 1.000]) [buf: 1] (at 16, end_mark) "))) (snd-display #__line__ ";new 8: ~A" (display-edits))) (delete-samples 2 1) (if (not (string-=? (safe-display-edits ind 0 6) " (delete 2 1) ; delete-samples 2 1 [6:7]: (at 0, cp->sounds[1][0:1, 1.000]) [buf: 10] (at 2, cp->sounds[2][0:0, 1.000]) [buf: 3] (at 3, cp->sounds[4][0:0, 1.000]) [buf: 1] (at 4, cp->sounds[2][1:2, 1.000]) [buf: 3] (at 6, cp->sounds[1][2:9, 1.000]) [buf: 10] (at 14, cp->sounds[5][0:0, 1.000]) [buf: 1] (at 15, end_mark) ")) (snd-display #__line__ ";new 9: ~A" (safe-display-edits ind 0 6))) (delete-samples 0 5) (if (not (string-=? (safe-display-edits ind 0 7) " (delete 0 5) ; delete-samples 0 5 [7:4]: (at 0, cp->sounds[2][2:2, 1.000]) [buf: 3] (at 1, cp->sounds[1][2:9, 1.000]) [buf: 10] (at 9, cp->sounds[5][0:0, 1.000]) [buf: 1] (at 10, end_mark) ")) (snd-display #__line__ ";new 10: ~A" (safe-display-edits ind 0 7))) (delete-samples 6 4) (if (not (string-=? (safe-display-edits ind 0 8) " (delete 6 4) ; delete-samples 6 4 [8:3]: (at 0, cp->sounds[2][2:2, 1.000]) [buf: 3] (at 1, cp->sounds[1][2:6, 1.000]) [buf: 10] (at 6, end_mark) ")) (snd-display #__line__ ";new 11: ~A" (safe-display-edits ind 0 8))) (delete-samples 0 1) (if (not (string-=? (safe-display-edits ind 0 9) " (delete 0 1) ; delete-samples 0 1 [9:2]: (at 0, cp->sounds[1][2:6, 1.000]) [buf: 10] (at 5, end_mark) ")) (snd-display #__line__ ";new 12: ~A" (safe-display-edits ind 0 9))) (delete-samples 0 5) (if (not (string-=? (safe-display-edits ind 0 10) " (delete 0 5) ; delete-samples 0 5 [10:1]: (at 0, end_mark) ")) (snd-display #__line__ ";new 13: ~A" (safe-display-edits ind 0 10))) (delete-samples 0 10) (if (not (= (edit-position) 10)) (snd-display #__line__ ";no-op delete deleted something! ~A" (display-edits))) (insert-samples 0 3 (make-float-vector 3)) (if (not (string-=? (safe-display-edits ind 0 11) " (insert 0 3) ; insert-samples [11:2]: (at 0, cp->sounds[6][0:2, 1.000]) [buf: 3] (at 3, end_mark) ")) (snd-display #__line__ ";new 14: ~A" (safe-display-edits ind 0 11))) (delete-samples 2 1) (if (not (string-=? (safe-display-edits ind 0 12) " (delete 2 1) ; delete-samples 2 1 [12:2]: (at 0, cp->sounds[6][0:1, 1.000]) [buf: 3] (at 2, end_mark) ")) (snd-display #__line__ ";new 15: ~A" (safe-display-edits ind 0 12))) (set! (sample 0) .5) (if (not (string-=? (safe-display-edits ind 0 13) " (set 0 1) ; set-sample 0 0.5000 [13:3]: (at 0, cp->sounds[7][0:0, 1.000]) [buf: 1] (at 1, cp->sounds[6][1:1, 1.000]) [buf: 3] (at 2, end_mark) ")) (snd-display #__line__ ";new 16: ~A" (safe-display-edits ind 0 13))) (set! (sample 1) .5) (if (not (string-=? (safe-display-edits ind 0 14) " (set 1 1) ; set-sample 1 0.5000 [14:3]: (at 0, cp->sounds[7][0:0, 1.000]) [buf: 1] (at 1, cp->sounds[8][0:0, 1.000]) [buf: 1] (at 2, end_mark) ")) (snd-display #__line__ ";new 17: ~A" (safe-display-edits ind 0 14))) (map-channel (lambda (y) 1.0) 0 10) (if (not (string-=? (safe-display-edits ind 0 15) " (set 0 10) ; map-channel [15:2]: (at 0, cp->sounds[9][0:9, 1.000]) [buf: 10] (at 10, end_mark) ")) (snd-display #__line__ ";new 18: ~A" (safe-display-edits ind 0 15))) (insert-samples 0 10 (make-float-vector 10)) (if (not (string-=? (safe-display-edits ind 0 16) " (insert 0 10) ; insert-samples [16:3]: (at 0, cp->sounds[10][0:9, 1.000]) [buf: 10] (at 10, cp->sounds[9][0:9, 1.000]) [buf: 10] (at 20, end_mark) ")) (snd-display #__line__ ";new 19: ~A" (safe-display-edits ind 0 16))) (set! (samples 2 3) (make-float-vector 3)) (if (not (string-=? (safe-display-edits ind 0 17) " (set 2 3) ; set-samples [17:5]: (at 0, cp->sounds[10][0:1, 1.000]) [buf: 10] (at 2, cp->sounds[11][0:2, 1.000]) [buf: 3] (at 5, cp->sounds[10][5:9, 1.000]) [buf: 10] (at 10, cp->sounds[9][0:9, 1.000]) [buf: 10] (at 20, end_mark) ")) (snd-display #__line__ ";new 20: ~A" (safe-display-edits ind 0 17))) (set! (samples 0 12) (make-float-vector 12)) (if (not (string-=? (safe-display-edits ind 0 18) " (set 0 12) ; set-samples [18:3]: (at 0, cp->sounds[12][0:11, 1.000]) [buf: 12] (at 12, cp->sounds[9][2:9, 1.000]) [buf: 10] (at 20, end_mark) ")) (snd-display #__line__ ";new 21: ~A" (safe-display-edits ind 0 18))) (set! (samples 30 10) (make-float-vector 10)) (if (not (string-=? (safe-display-edits ind 0 19) " (set 20 21) ; set-samples [19:5]: (at 0, cp->sounds[12][0:11, 1.000]) [buf: 12] (at 12, cp->sounds[9][2:9, 1.000]) [buf: 10] (at 20, cp->sounds[-1][0:9, 0.000]) (at 30, cp->sounds[13][0:9, 1.000]) [buf: 10] (at 40, end_mark) ")) (snd-display #__line__ ";new 21: ~A" (safe-display-edits ind 0 19))) (close-sound ind)) ;; scale/ramp (let ((ind (new-sound "test.snd"))) (map-channel (lambda (y) 1.0) 0 10) (scale-channel 0.5) (if (not (string-=? (safe-display-edits ind 0 2) " (scale 0 10) ; scale-channel 0.500 0 #f [2:2]: (at 0, cp->sounds[1][0:9, 0.500]) [buf: 10] (at 10, end_mark) ")) (snd-display #__line__ ";scl 0: ~A" (safe-display-edits ind 0 2))) (undo) (scale-channel 0.5 0 3) (if (not (string-=? (safe-display-edits ind 0 2) " (scale 0 3) ; scale-channel 0.500 0 3 [2:3]: (at 0, cp->sounds[1][0:2, 0.500]) [buf: 10] (at 3, cp->sounds[1][3:9, 1.000]) [buf: 10] (at 10, end_mark) ")) (snd-display #__line__ ";scl 1: ~A" (safe-display-edits ind 0 2))) (undo) (scale-channel 0.5 5 5) (if (not (string-=? (safe-display-edits ind 0 2) " (scale 5 5) ; scale-channel 0.500 5 5 [2:3]: (at 0, cp->sounds[1][0:4, 1.000]) [buf: 10] (at 5, cp->sounds[1][5:9, 0.500]) [buf: 10] (at 10, end_mark) ")) (snd-display #__line__ ";scl 2: ~A" (safe-display-edits ind 0 2))) (undo) (scale-channel 0.5 2 4) (if (not (string-=? (safe-display-edits ind 0 2) " (scale 2 4) ; scale-channel 0.500 2 4 [2:4]: (at 0, cp->sounds[1][0:1, 1.000]) [buf: 10] (at 2, cp->sounds[1][2:5, 0.500]) [buf: 10] (at 6, cp->sounds[1][6:9, 1.000]) [buf: 10] (at 10, end_mark) ")) (snd-display #__line__ ";scl 2a: ~A" (safe-display-edits ind 0 2))) (undo) (scale-channel 0.5 10 10) (if (not (= (edit-position) 1)) (snd-display #__line__ ";scale beyond end edited? ~A" (display-edits))) (scale-channel 0.5 100 10) (if (not (= (edit-position) 1)) (snd-display #__line__ ";scale way beyond end edited? ~A" (display-edits))) (scale-channel 0.5 5 10) (if (not (string-=? (safe-display-edits ind 0 2) " (scale 5 5) ; scale-channel 0.500 5 5 [2:3]: (at 0, cp->sounds[1][0:4, 1.000]) [buf: 10] (at 5, cp->sounds[1][5:9, 0.500]) [buf: 10] (at 10, end_mark) ")) (snd-display #__line__ ";scl 3: ~A" (safe-display-edits ind 0 2))) (undo) (set! (sample 4) .5) (if (not (string-=? (safe-display-edits ind 0 2) " (set 4 1) ; set-sample 4 0.5000 [2:4]: (at 0, cp->sounds[1][0:3, 1.000]) [buf: 10] (at 4, cp->sounds[2][0:0, 1.000]) [buf: 1] (at 5, cp->sounds[1][5:9, 1.000]) [buf: 10] (at 10, end_mark) ")) (snd-display #__line__ ";scl 4: ~A" (safe-display-edits ind 0 2))) (scale-channel 0.5 0 4) (if (not (string-=? (safe-display-edits ind 0 3) " (scale 0 4) ; scale-channel 0.500 0 4 [3:4]: (at 0, cp->sounds[1][0:3, 0.500]) [buf: 10] (at 4, cp->sounds[2][0:0, 1.000]) [buf: 1] (at 5, cp->sounds[1][5:9, 1.000]) [buf: 10] (at 10, end_mark) ")) (snd-display #__line__ ";scl 5: ~A" (safe-display-edits ind 0 3))) (scale-channel 0.5 4 1) (if (not (string-=? (safe-display-edits ind 0 4) " (scale 4 1) ; scale-channel 0.500 4 1 [4:4]: (at 0, cp->sounds[1][0:3, 0.500]) [buf: 10] (at 4, cp->sounds[2][0:0, 0.500]) [buf: 1] (at 5, cp->sounds[1][5:9, 1.000]) [buf: 10] (at 10, end_mark) ")) (snd-display #__line__ ";scl 6: ~A" (safe-display-edits ind 0 4))) (scale-channel 0.5 0 7) (if (not (string-=? (safe-display-edits ind 0 5) " (scale 0 7) ; scale-channel 0.500 0 7 [5:5]: (at 0, cp->sounds[1][0:3, 0.250]) [buf: 10] (at 4, cp->sounds[2][0:0, 0.250]) [buf: 1] (at 5, cp->sounds[1][5:6, 0.500]) [buf: 10] (at 7, cp->sounds[1][7:9, 1.000]) [buf: 10] (at 10, end_mark) ")) (snd-display #__line__ ";scl 7: ~A" (safe-display-edits ind 0 5))) (scale-channel 0.5 1 4) (if (not (string-=? (safe-display-edits ind 0 6) " (scale 1 4) ; scale-channel 0.500 1 4 [6:6]: (at 0, cp->sounds[1][0:0, 0.250]) [buf: 10] (at 1, cp->sounds[1][1:3, 0.125]) [buf: 10] (at 4, cp->sounds[2][0:0, 0.125]) [buf: 1] (at 5, cp->sounds[1][5:6, 0.500]) [buf: 10] (at 7, cp->sounds[1][7:9, 1.000]) [buf: 10] (at 10, end_mark) ")) (snd-display #__line__ ";scl 8: ~A" (safe-display-edits ind 0 6))) (undo 4) (scale-channel 0.5 1 8) (if (not (string-=? (safe-display-edits ind 0 3) " (scale 1 8) ; scale-channel 0.500 1 8 [3:6]: (at 0, cp->sounds[1][0:0, 1.000]) [buf: 10] (at 1, cp->sounds[1][1:3, 0.500]) [buf: 10] (at 4, cp->sounds[2][0:0, 0.500]) [buf: 1] (at 5, cp->sounds[1][5:8, 0.500]) [buf: 10] (at 9, cp->sounds[1][9:9, 1.000]) [buf: 10] (at 10, end_mark) ")) (snd-display #__line__ ";scl 9: ~A" (safe-display-edits ind 0 3))) (undo 2) (ramp-channel 0.0 1.0) (if (not (string-=? (safe-display-edits ind 0 2) " (ramp 0 10) ; ramp-channel 0.000 1.000 0 #f [2:2]: (at 0, cp->sounds[1][0:9, 1.000, [1]-0.000 -> 1.000]) [buf: 10] (at 10, end_mark) ")) (snd-display #__line__ ";ramp 0: ~A" (safe-display-edits ind 0 2))) (scale-channel 0.5) (if (not (string-=? (safe-display-edits ind 0 3) " (scale 0 10) ; scale-channel 0.500 0 #f [3:2]: (at 0, cp->sounds[1][0:9, 0.500, [1]-0.000 -> 1.000]) [buf: 10] (at 10, end_mark) ")) (snd-display #__line__ ";ramp 1: ~A" (safe-display-edits ind 0 3))) (undo) (scale-channel 0.5 0 5) (if (not (string-=? (safe-display-edits ind 0 3) " (scale 0 5) ; scale-channel 0.500 0 5 [3:3]: (at 0, cp->sounds[1][0:4, 0.500, [1]-0.000 -> 0.444]) [buf: 10] (at 5, cp->sounds[1][5:9, 1.000, [1]0.556 -> 1.000]) [buf: 10] (at 10, end_mark) ")) (snd-display #__line__ ";ramp 2: ~A" (safe-display-edits ind 0 3))) (undo) (scale-channel 0.5 2 4) (if (not (string-=? (safe-display-edits ind 0 3) " (scale 2 4) ; scale-channel 0.500 2 4 [3:4]: (at 0, cp->sounds[1][0:1, 1.000, [1]-0.000 -> 0.111]) [buf: 10] (at 2, cp->sounds[1][2:5, 0.500, [1]0.222 -> 0.556]) [buf: 10] (at 6, cp->sounds[1][6:9, 1.000, [1]0.667 -> 1.000]) [buf: 10] (at 10, end_mark) ")) (snd-display #__line__ ";ramp 3: ~A" (safe-display-edits ind 0 3))) (undo) (scale-channel 0.5 5 5) (if (not (string-=? (safe-display-edits ind 0 3) " (scale 5 5) ; scale-channel 0.500 5 5 [3:3]: (at 0, cp->sounds[1][0:4, 1.000, [1]-0.000 -> 0.444]) [buf: 10] (at 5, cp->sounds[1][5:9, 0.500, [1]0.556 -> 1.000]) [buf: 10] (at 10, end_mark) ")) (snd-display #__line__ ";ramp 4: ~A" (safe-display-edits ind 0 3))) (undo 2) (ramp-channel .2 .6 2 6) (if (not (string-=? (safe-display-edits ind 0 2) " (ramp 2 6) ; ramp-channel 0.200 0.600 2 6 [2:4]: (at 0, cp->sounds[1][0:1, 1.000]) [buf: 10] (at 2, cp->sounds[1][2:7, 1.000, [1]0.200 -> 0.600]) [buf: 10] (at 8, cp->sounds[1][8:9, 1.000]) [buf: 10] (at 10, end_mark) ")) (snd-display #__line__ ";ramp 5: ~A" (safe-display-edits ind 0 2))) (scale-channel 0.5 0 5) (if (not (string-=? (safe-display-edits ind 0 3) " (scale 0 5) ; scale-channel 0.500 0 5 [3:5]: (at 0, cp->sounds[1][0:1, 0.500]) [buf: 10] (at 2, cp->sounds[1][2:4, 0.500, [1]0.200 -> 0.360]) [buf: 10] (at 5, cp->sounds[1][5:7, 1.000, [1]0.440 -> 0.600]) [buf: 10] (at 8, cp->sounds[1][8:9, 1.000]) [buf: 10] (at 10, end_mark) ")) (snd-display #__line__ ";ramp 6: ~A" (safe-display-edits ind 0 3))) (undo) (scale-channel 0.5 2 6) (if (not (string-=? (safe-display-edits ind 0 3) " (scale 2 6) ; scale-channel 0.500 2 6 [3:4]: (at 0, cp->sounds[1][0:1, 1.000]) [buf: 10] (at 2, cp->sounds[1][2:7, 0.500, [1]0.200 -> 0.600]) [buf: 10] (at 8, cp->sounds[1][8:9, 1.000]) [buf: 10] (at 10, end_mark) ")) (snd-display #__line__ ";ramp 7: ~A" (safe-display-edits ind 0 3))) (undo) (scale-channel 0.5 5 4) (if (not (string-=? (safe-display-edits ind 0 3) " (scale 5 4) ; scale-channel 0.500 5 4 [3:6]: (at 0, cp->sounds[1][0:1, 1.000]) [buf: 10] (at 2, cp->sounds[1][2:4, 1.000, [1]0.200 -> 0.360]) [buf: 10] (at 5, cp->sounds[1][5:7, 0.500, [1]0.440 -> 0.600]) [buf: 10] (at 8, cp->sounds[1][8:8, 0.500]) [buf: 10] (at 9, cp->sounds[1][9:9, 1.000]) [buf: 10] (at 10, end_mark) ")) (snd-display #__line__ ";ramp 8: ~A" (safe-display-edits ind 0 3))) (undo) (set! (sample 4) .5) (if (not (string-=? (safe-display-edits ind 0 3) " (set 4 1) ; set-sample 4 0.5000 [3:6]: (at 0, cp->sounds[1][0:1, 1.000]) [buf: 10] (at 2, cp->sounds[1][2:3, 1.000, [1]0.200 -> 0.280]) [buf: 10] (at 4, cp->sounds[2][0:0, 1.000]) [buf: 1] (at 5, cp->sounds[1][5:7, 1.000, [1]0.440 -> 0.600]) [buf: 10] (at 8, cp->sounds[1][8:9, 1.000]) [buf: 10] (at 10, end_mark) ")) (snd-display #__line__ ";ramp 9: ~A" (safe-display-edits ind 0 3))) (undo) (scale-channel 0.5 4 1) (if (not (string-=? (safe-display-edits ind 0 3) " (scale 4 1) ; scale-channel 0.500 4 1 [3:6]: (at 0, cp->sounds[1][0:1, 1.000]) [buf: 10] (at 2, cp->sounds[1][2:3, 1.000, [1]0.200 -> 0.280]) [buf: 10] (at 4, cp->sounds[1][4:4, 0.500, [1]0.360 -> 0.360]) [buf: 10] (at 5, cp->sounds[1][5:7, 1.000, [1]0.440 -> 0.600]) [buf: 10] (at 8, cp->sounds[1][8:9, 1.000]) [buf: 10] (at 10, end_mark) ")) (snd-display #__line__ ";ramp 10: ~A" (safe-display-edits ind 0 3))) (undo) (delete-sample 4) (if (not (string-=? (safe-display-edits ind 0 3) " (delete 4 1) ; delete-samples 4 1 [3:5]: (at 0, cp->sounds[1][0:1, 1.000]) [buf: 10] (at 2, cp->sounds[1][2:3, 1.000, [1]0.200 -> 0.280]) [buf: 10] (at 4, cp->sounds[1][5:7, 1.000, [1]0.440 -> 0.600]) [buf: 10] (at 7, cp->sounds[1][8:9, 1.000]) [buf: 10] (at 9, end_mark) ")) (snd-display #__line__ ";ramp 11: ~A" (safe-display-edits ind 0 3))) (undo) (delete-samples 4 2) (if (not (string-=? (safe-display-edits ind 0 3) " (delete 4 2) ; delete-samples 4 2 [3:5]: (at 0, cp->sounds[1][0:1, 1.000]) [buf: 10] (at 2, cp->sounds[1][2:3, 1.000, [1]0.200 -> 0.280]) [buf: 10] (at 4, cp->sounds[1][6:7, 1.000, [1]0.520 -> 0.600]) [buf: 10] (at 6, cp->sounds[1][8:9, 1.000]) [buf: 10] (at 8, end_mark) ")) (snd-display #__line__ ";ramp 12: ~A" (safe-display-edits ind 0 3))) (undo) (delete-samples 4 3) (if (not (string-=? (safe-display-edits ind 0 3) " (delete 4 3) ; delete-samples 4 3 [3:5]: (at 0, cp->sounds[1][0:1, 1.000]) [buf: 10] (at 2, cp->sounds[1][2:3, 1.000, [1]0.200 -> 0.280]) [buf: 10] (at 4, cp->sounds[1][7:7, 1.000, [1]0.600 -> 0.600]) [buf: 10] (at 5, cp->sounds[1][8:9, 1.000]) [buf: 10] (at 7, end_mark) ")) (snd-display #__line__ ";ramp 13: ~A" (safe-display-edits ind 0 3))) (undo) (delete-samples 4 4) (if (not (string-=? (safe-display-edits ind 0 3) " (delete 4 4) ; delete-samples 4 4 [3:4]: (at 0, cp->sounds[1][0:1, 1.000]) [buf: 10] (at 2, cp->sounds[1][2:3, 1.000, [1]0.200 -> 0.280]) [buf: 10] (at 4, cp->sounds[1][8:9, 1.000]) [buf: 10] (at 6, end_mark) ")) (snd-display #__line__ ";ramp 14: ~A" (safe-display-edits ind 0 3))) (undo) (delete-samples 4 5) (if (not (string-=? (safe-display-edits ind 0 3) " (delete 4 5) ; delete-samples 4 5 [3:4]: (at 0, cp->sounds[1][0:1, 1.000]) [buf: 10] (at 2, cp->sounds[1][2:3, 1.000, [1]0.200 -> 0.280]) [buf: 10] (at 4, cp->sounds[1][9:9, 1.000]) [buf: 10] (at 5, end_mark) ")) (snd-display #__line__ ";ramp 15: ~A" (safe-display-edits ind 0 3))) (undo) (scale-channel 0.5 4 2) (if (not (string-=? (safe-display-edits ind 0 3) " (scale 4 2) ; scale-channel 0.500 4 2 [3:6]: (at 0, cp->sounds[1][0:1, 1.000]) [buf: 10] (at 2, cp->sounds[1][2:3, 1.000, [1]0.200 -> 0.280]) [buf: 10] (at 4, cp->sounds[1][4:5, 0.500, [1]0.360 -> 0.440]) [buf: 10] (at 6, cp->sounds[1][6:7, 1.000, [1]0.520 -> 0.600]) [buf: 10] (at 8, cp->sounds[1][8:9, 1.000]) [buf: 10] (at 10, end_mark) ")) (snd-display #__line__ ";ramp 16: ~A" (safe-display-edits ind 0 3))) (undo) (pad-channel 4 1) (if (not (string-=? (safe-display-edits ind 0 3) " (silence 4 1) ; pad-channel [3:6]: (at 0, cp->sounds[1][0:1, 1.000]) [buf: 10] (at 2, cp->sounds[1][2:3, 1.000, [1]0.200 -> 0.280]) [buf: 10] (at 4, cp->sounds[-1][0:0, 0.000]) (at 5, cp->sounds[1][4:7, 1.000, [1]0.360 -> 0.600]) [buf: 10] (at 9, cp->sounds[1][8:9, 1.000]) [buf: 10] (at 11, end_mark) ")) (snd-display #__line__ ";ramp 17: ~A" (safe-display-edits ind 0 3))) (close-sound ind)) ;; xramp (let ((ind (new-sound "test.snd"))) ; second main let (map-channel (lambda (y) 1.0) 0 10) (xramp-channel 0.0 1.0 32.0) (if (not (string-=? (safe-display-edits ind 0 2) " (ramp 0 10) ; xramp-channel 0.000 1.000 32.000 0 #f [2:2]: (at 0, cp->sounds[1][0:9, 1.000, [1]0.000 -> 1.000, off: -0.032, scl: 0.032]) [buf: 10] (at 10, end_mark) ")) (snd-display #__line__ ";xramp 1: ~A" (safe-display-edits ind 0 2))) (undo) (xramp-channel 0.0 1.0 0.325) (if (not (string-=? (safe-display-edits ind 0 2) " (ramp 0 10) ; xramp-channel 0.000 1.000 0.325 0 #f [2:2]: (at 0, cp->sounds[1][0:9, 1.000, [1]0.000 -> 1.000, off: 1.481, scl: -1.481]) [buf: 10] (at 10, end_mark) ")) (snd-display #__line__ ";xramp 2: ~A" (safe-display-edits ind 0 2))) (undo) (xramp-channel 0.0 1.0 0.0) (if (not (string-=? (safe-display-edits ind 0 2) (string-append " (scale 0 10) ; scale-channel 0.000 0 #f [2:2]: (at 0, cp->sounds[0][0:9, 0.000]) [file: " (getcwd) "/test.snd[0]] (at 10, end_mark) "))) (snd-display #__line__ ";xramp 3: ~A" (safe-display-edits ind 0 2))) (undo) (xramp-channel 0.0 1.0 1.0) (if (not (string-=? (safe-display-edits ind 0 2) " (ramp 0 10) ; ramp-channel 0.000 1.000 0 #f [2:2]: (at 0, cp->sounds[1][0:9, 1.000, [1]-0.000 -> 1.000]) [buf: 10] (at 10, end_mark) ")) (snd-display #__line__ ";xramp 4: ~A" (safe-display-edits ind 0 2))) (undo) (xramp-channel 0.5 1.5 32.0) (if (not (string-=? (safe-display-edits ind 0 2) " (ramp 0 10) ; xramp-channel 0.500 1.500 32.000 0 #f [2:2]: (at 0, cp->sounds[1][0:9, 1.000, [1]0.500 -> 1.500, off: 0.468, scl: 0.032]) [buf: 10] (at 10, end_mark) ")) (snd-display #__line__ ";xramp 5: ~A" (safe-display-edits ind 0 2))) (if (or (fneq (maxamp) 1.5) (fneq (sample 0) 0.5)) (snd-display #__line__ ";xramp 5 vals: ~A ~A" (maxamp) (sample 0))) (undo) (xramp-channel -0.5 1.5 32.0) (if (not (string-=? (safe-display-edits ind 0 2) " (ramp 0 10) ; xramp-channel -0.500 1.500 32.000 0 #f [2:2]: (at 0, cp->sounds[1][0:9, 1.000, [1]-0.500 -> 1.500, off: -0.565, scl: 0.065]) [buf: 10] (at 10, end_mark) ")) (snd-display #__line__ ";xramp 6: ~A" (safe-display-edits ind 0 2))) (if (or (fneq (maxamp) 1.5) (fneq (sample 0) -0.5)) (snd-display #__line__ ";xramp 6 vals: ~A ~A" (maxamp) (sample 0))) (undo) (xramp-channel 0.0 1.0 32.0) (let ((vals (channel->float-vector)) (ctr 0)) (scale-channel 0.5) (if (not (string-=? (safe-display-edits ind 0 3) " (scale 0 10) ; scale-channel 0.500 0 #f [3:2]: (at 0, cp->sounds[1][0:9, 0.500, [1]0.000 -> 1.000, off: -0.032, scl: 0.032]) [buf: 10] (at 10, end_mark) ")) (snd-display #__line__ ";xramp 7: ~A" (safe-display-edits ind 0 3))) (set! ctr 0) (let ((p (make-one-pole 1.0 -1.0))) (let ((baddy (scan-channel (lambda (y) (fneq y (* 0.5 (float-vector-ref vals (floor (- (one-pole p 1.0) 1.0))))))))) (if baddy (snd-display #__line__ ";trouble in xramp 7: ~A" baddy)))) (undo) (delete-sample 0) (if (not (string-=? (safe-display-edits ind 0 3) " (delete 0 1) ; delete-samples 0 1 [3:2]: (at 0, cp->sounds[1][1:9, 1.000, [1]0.015 -> 1.000, off: -0.032, scl: 0.032]) [buf: 10] (at 9, end_mark) ")) (snd-display #__line__ ";xramp 8: ~A" (safe-display-edits ind 0 3))) (set! ctr 1) (let ((p (make-one-pole 1.0 -1.0))) (let ((baddy (scan-channel (lambda (y) (fneq y (float-vector-ref vals (floor (one-pole p 1.0)))))))) (if baddy (snd-display #__line__ ";trouble in xramp 8: ~A" baddy)))) (undo) (delete-samples 0 2) (if (not (string-=? (safe-display-edits ind 0 3) " (delete 0 2) ; delete-samples 0 2 [3:2]: (at 0, cp->sounds[1][2:9, 1.000, [1]0.037 -> 1.000, off: -0.032, scl: 0.032]) [buf: 10] (at 8, end_mark) ")) (snd-display #__line__ ";xramp 9: ~A" (safe-display-edits ind 0 3))) (set! ctr 2) (let ((p (make-one-pole 1.0 -1.0))) (one-pole p 1.0) (let ((baddy (scan-channel (lambda (y) (fneq y (float-vector-ref vals (floor (one-pole p 1.0)))))))) (if baddy (snd-display #__line__ ";trouble in xramp 9: ~A" baddy)))) (undo) (delete-sample 0) (delete-sample 0) (if (not (string-=? (safe-display-edits ind 0 4) " (delete 0 1) ; delete-samples 0 1 [4:2]: (at 0, cp->sounds[1][2:9, 1.000, [1]0.037 -> 1.000, off: -0.032, scl: 0.032]) [buf: 10] (at 8, end_mark) ")) (snd-display #__line__ ";xramp 10: ~A" (safe-display-edits ind 0 4))) (undo 2) (delete-sample 4) (if (not (string-=? (safe-display-edits ind 0 3) " (delete 4 1) ; delete-samples 4 1 [3:3]: (at 0, cp->sounds[1][0:3, 1.000, [1]0.000 -> 0.070, off: -0.032, scl: 0.032]) [buf: 10] (at 4, cp->sounds[1][5:9, 1.000, [1]0.189 -> 1.000, off: -0.032, scl: 0.032]) [buf: 10] (at 9, end_mark) ")) (snd-display #__line__ ";xramp 11: ~A" (safe-display-edits ind 0 3))) (undo) (delete-samples 4 2) (if (not (string-=? (safe-display-edits ind 0 3) " (delete 4 2) ; delete-samples 4 2 [3:3]: (at 0, cp->sounds[1][0:3, 1.000, [1]0.000 -> 0.070, off: -0.032, scl: 0.032]) [buf: 10] (at 4, cp->sounds[1][6:9, 1.000, [1]0.293 -> 1.000, off: -0.032, scl: 0.032]) [buf: 10] (at 8, end_mark) ")) (snd-display #__line__ ";xramp 12: ~A" (safe-display-edits ind 0 3))) (undo) (scale-channel 0.5 4 2) (if (not (string-=? (safe-display-edits ind 0 3) " (scale 4 2) ; scale-channel 0.500 4 2 [3:4]: (at 0, cp->sounds[1][0:3, 1.000, [1]0.000 -> 0.070, off: -0.032, scl: 0.032]) [buf: 10] (at 4, cp->sounds[1][4:5, 0.500, [1]0.118 -> 0.189, off: -0.032, scl: 0.032]) [buf: 10] (at 6, cp->sounds[1][6:9, 1.000, [1]0.293 -> 1.000, off: -0.032, scl: 0.032]) [buf: 10] (at 10, end_mark) ")) (snd-display #__line__ ";xramp 13: ~A" (safe-display-edits ind 0 3))) (set! ctr 0) (let ((baddy (scan-channel (lambda (y) (if (or (and (> ctr 5) (fneq y (vals ctr))) (and (< ctr 4) (fneq y (vals ctr))) (and (or (= ctr 4) (= ctr 5)) (fneq y (* 0.5 (vals ctr))))) #t (begin (set! ctr (+ ctr 1)) #f)))))) (if baddy (snd-display #__line__ ";trouble in xramp 8: ~A" baddy))) (undo) (scale-channel 0.5 0 2) (if (not (string-=? (safe-display-edits ind 0 3) " (scale 0 2) ; scale-channel 0.500 0 2 [3:3]: (at 0, cp->sounds[1][0:1, 0.500, [1]0.000 -> 0.015, off: -0.032, scl: 0.032]) [buf: 10] (at 2, cp->sounds[1][2:9, 1.000, [1]0.037 -> 1.000, off: -0.032, scl: 0.032]) [buf: 10] (at 10, end_mark) ")) (snd-display #__line__ ";xramp 14: ~A" (safe-display-edits ind 0 3))) (undo) (pad-channel 4 2) (if (not (string-=? (safe-display-edits ind 0 3) " (silence 4 2) ; pad-channel [3:4]: (at 0, cp->sounds[1][0:3, 1.000, [1]0.000 -> 0.070, off: -0.032, scl: 0.032]) [buf: 10] (at 4, cp->sounds[-1][0:1, 0.000]) (at 6, cp->sounds[1][4:9, 1.000, [1]0.118 -> 1.000, off: -0.032, scl: 0.032]) [buf: 10] (at 12, end_mark) ")) (snd-display #__line__ ";xramp 15: ~A" (safe-display-edits ind 0 3))) (undo) (set! (sample 4) 1.0) (if (not (string-=? (safe-display-edits ind 0 3) " (set 4 1) ; set-sample 4 1.0000 [3:4]: (at 0, cp->sounds[1][0:3, 1.000, [1]0.000 -> 0.070, off: -0.032, scl: 0.032]) [buf: 10] (at 4, cp->sounds[2][0:0, 1.000]) [buf: 1] (at 5, cp->sounds[1][5:9, 1.000, [1]0.189 -> 1.000, off: -0.032, scl: 0.032]) [buf: 10] (at 10, end_mark) ")) (snd-display #__line__ ";xramp 16: ~A" (safe-display-edits ind 0 3))) (undo) (set! (samples 4 2) (make-float-vector 2)) (if (not (string-=? (safe-display-edits ind 0 3) " (set 4 2) ; set-samples [3:4]: (at 0, cp->sounds[1][0:3, 1.000, [1]0.000 -> 0.070, off: -0.032, scl: 0.032]) [buf: 10] (at 4, cp->sounds[2][0:1, 1.000]) [buf: 2] (at 6, cp->sounds[1][6:9, 1.000, [1]0.293 -> 1.000, off: -0.032, scl: 0.032]) [buf: 10] (at 10, end_mark) ")) (snd-display #__line__ ";xramp 17: ~A" (safe-display-edits ind 0 3))) (undo) (scale-channel 0.5) (set! (samples 4 2) (make-float-vector 2)) (if (not (string-=? (safe-display-edits ind 0 4) " (set 4 2) ; set-samples [4:4]: (at 0, cp->sounds[1][0:3, 0.500, [1]0.000 -> 0.070, off: -0.032, scl: 0.032]) [buf: 10] (at 4, cp->sounds[2][0:1, 1.000]) [buf: 2] (at 6, cp->sounds[1][6:9, 0.500, [1]0.293 -> 1.000, off: -0.032, scl: 0.032]) [buf: 10] (at 10, end_mark) ")) (snd-display #__line__ ";xramp 18: ~A" (safe-display-edits ind 0 4))) ) (close-sound ind)) (let ((ind (new-sound "test.snd"))) ; third (map-channel (lambda (y) 1.0) 0 100) (do ((i 0 (+ i 1))) ((= i 10)) (scale-channel 0.5 (* i 10) 10)) (ramp-channel 0.0 1.0) (if (not (string=? (safe-display-edits ind 0 12) " (ramp 0 100) ; ramp-channel 0.000 1.000 0 #f [12:11]: (at 0, cp->sounds[1][0:9, 0.500, [1]0.000 -> 0.091]) [buf: 100] (at 10, cp->sounds[1][10:19, 0.500, [1]0.101 -> 0.192]) [buf: 100] (at 20, cp->sounds[1][20:29, 0.500, [1]0.202 -> 0.293]) [buf: 100] (at 30, cp->sounds[1][30:39, 0.500, [1]0.303 -> 0.394]) [buf: 100] (at 40, cp->sounds[1][40:49, 0.500, [1]0.404 -> 0.495]) [buf: 100] (at 50, cp->sounds[1][50:59, 0.500, [1]0.505 -> 0.596]) [buf: 100] (at 60, cp->sounds[1][60:69, 0.500, [1]0.606 -> 0.697]) [buf: 100] (at 70, cp->sounds[1][70:79, 0.500, [1]0.707 -> 0.798]) [buf: 100] (at 80, cp->sounds[1][80:89, 0.500, [1]0.808 -> 0.899]) [buf: 100] (at 90, cp->sounds[1][90:99, 0.500, [1]0.909 -> 1.000]) [buf: 100] (at 100, end_mark) ")) (snd-display #__line__ ";multi-ramp 1: ~A" (safe-display-edits ind 0 12))) (if (fneq (maxamp) 0.5) (snd-display #__line__ ";multi ramp 1 maxamp: ~A" (maxamp))) (undo) (ramp-channel 0.1 1.0 10 90) (if (not (string=? (safe-display-edits ind 0 12) " (ramp 10 90) ; ramp-channel 0.100 1.000 10 90 [12:11]: (at 0, cp->sounds[1][0:9, 0.500]) [buf: 100] (at 10, cp->sounds[1][10:19, 0.500, [1]0.100 -> 0.191]) [buf: 100] (at 20, cp->sounds[1][20:29, 0.500, [1]0.201 -> 0.292]) [buf: 100] (at 30, cp->sounds[1][30:39, 0.500, [1]0.302 -> 0.393]) [buf: 100] (at 40, cp->sounds[1][40:49, 0.500, [1]0.403 -> 0.494]) [buf: 100] (at 50, cp->sounds[1][50:59, 0.500, [1]0.504 -> 0.596]) [buf: 100] (at 60, cp->sounds[1][60:69, 0.500, [1]0.606 -> 0.697]) [buf: 100] (at 70, cp->sounds[1][70:79, 0.500, [1]0.707 -> 0.798]) [buf: 100] (at 80, cp->sounds[1][80:89, 0.500, [1]0.808 -> 0.899]) [buf: 100] (at 90, cp->sounds[1][90:99, 0.500, [1]0.909 -> 1.000]) [buf: 100] (at 100, end_mark) ")) (snd-display #__line__ ";multi-ramp 2: ~A" (safe-display-edits ind 0 12))) (if (fneq (maxamp) 0.5) (snd-display #__line__ ";multi ramp 2 maxamp: ~A" (maxamp))) (undo) (ramp-channel 0.0 0.9 0 90) (if (not (string=? (safe-display-edits ind 0 12) " (ramp 0 90) ; ramp-channel 0.000 0.900 0 90 [12:11]: (at 0, cp->sounds[1][0:9, 0.500, [1]0.000 -> 0.091]) [buf: 100] (at 10, cp->sounds[1][10:19, 0.500, [1]0.101 -> 0.192]) [buf: 100] (at 20, cp->sounds[1][20:29, 0.500, [1]0.202 -> 0.293]) [buf: 100] (at 30, cp->sounds[1][30:39, 0.500, [1]0.303 -> 0.394]) [buf: 100] (at 40, cp->sounds[1][40:49, 0.500, [1]0.404 -> 0.496]) [buf: 100] (at 50, cp->sounds[1][50:59, 0.500, [1]0.506 -> 0.597]) [buf: 100] (at 60, cp->sounds[1][60:69, 0.500, [1]0.607 -> 0.698]) [buf: 100] (at 70, cp->sounds[1][70:79, 0.500, [1]0.708 -> 0.799]) [buf: 100] (at 80, cp->sounds[1][80:89, 0.500, [1]0.809 -> 0.900]) [buf: 100] (at 90, cp->sounds[1][90:99, 0.500]) [buf: 100] (at 100, end_mark) ")) (snd-display #__line__ ";multi-ramp 3: ~A" (safe-display-edits ind 0 12))) (if (fneq (maxamp) 0.5) (snd-display #__line__ ";multi ramp 3 maxamp: ~A" (maxamp))) (if (fneq (sample 89) 0.45) (snd-display #__line__ ";multi ramp 3 sample 89: ~A" (sample 89))) (if (fneq (sample 90) 0.5) (snd-display #__line__ ";multi ramp 3 sample 90: ~A" (sample 90))) (undo) (ramp-channel 0.1 0.9 10 80) (if (not (string=? (safe-display-edits ind 0 12) " (ramp 10 80) ; ramp-channel 0.100 0.900 10 80 [12:11]: (at 0, cp->sounds[1][0:9, 0.500]) [buf: 100] (at 10, cp->sounds[1][10:19, 0.500, [1]0.100 -> 0.191]) [buf: 100] (at 20, cp->sounds[1][20:29, 0.500, [1]0.201 -> 0.292]) [buf: 100] (at 30, cp->sounds[1][30:39, 0.500, [1]0.303 -> 0.394]) [buf: 100] (at 40, cp->sounds[1][40:49, 0.500, [1]0.404 -> 0.495]) [buf: 100] (at 50, cp->sounds[1][50:59, 0.500, [1]0.505 -> 0.596]) [buf: 100] (at 60, cp->sounds[1][60:69, 0.500, [1]0.606 -> 0.697]) [buf: 100] (at 70, cp->sounds[1][70:79, 0.500, [1]0.708 -> 0.799]) [buf: 100] (at 80, cp->sounds[1][80:89, 0.500, [1]0.809 -> 0.900]) [buf: 100] (at 90, cp->sounds[1][90:99, 0.500]) [buf: 100] (at 100, end_mark) ")) (snd-display #__line__ ";multi-ramp 4: ~A" (safe-display-edits ind 0 12))) (revert-sound) (map-channel (lambda (y) 1.0) 0 100) (ramp-channel 0.0 1.0) (do ((i 0 (+ i 1))) ((= i 10)) (scale-channel 0.5 (* i 10) 10)) (if (not (string=? (safe-display-edits ind 0 12) " (scale 90 10) ; scale-channel 0.500 90 10 [12:11]: (at 0, cp->sounds[1][0:9, 0.500, [1]0.000 -> 0.091]) [buf: 100] (at 10, cp->sounds[1][10:19, 0.500, [1]0.101 -> 0.192]) [buf: 100] (at 20, cp->sounds[1][20:29, 0.500, [1]0.202 -> 0.293]) [buf: 100] (at 30, cp->sounds[1][30:39, 0.500, [1]0.303 -> 0.394]) [buf: 100] (at 40, cp->sounds[1][40:49, 0.500, [1]0.404 -> 0.495]) [buf: 100] (at 50, cp->sounds[1][50:59, 0.500, [1]0.505 -> 0.596]) [buf: 100] (at 60, cp->sounds[1][60:69, 0.500, [1]0.606 -> 0.697]) [buf: 100] (at 70, cp->sounds[1][70:79, 0.500, [1]0.707 -> 0.798]) [buf: 100] (at 80, cp->sounds[1][80:89, 0.500, [1]0.808 -> 0.899]) [buf: 100] (at 90, cp->sounds[1][90:99, 0.500, [1]0.909 -> 1.000]) [buf: 100] (at 100, end_mark) ")) (snd-display #__line__ ";multi-ramp 5: ~A" (safe-display-edits ind 0 12))) (close-sound ind)) (let ((ind (open-sound "oboe.snd"))) (if (not (= (redo 1 ind 0) 0)) (snd-display #__line__ ";open redo with no ops: ~A" (redo))) (if (not (= (undo 1 ind 0) 0)) (snd-display #__line__ ";open undo with no ops: ~A" (undo))) (set! (cursor) 1000) (delete-sample 321) (if (not (= (cursor) 999)) (snd-display #__line__ ";delete-sample before cursor: ~A" (cursor))) (if (not (= (cursor ind 0 0) 1000)) (snd-display #__line__ ";delete-sample before cursor (0): ~A" (cursor ind 0 0))) (undo) (if (not (= (cursor) 1000)) (snd-display #__line__ ";delete-sample after cursor undo: ~A" (cursor))) (undo -1) (if (not (= (cursor) 999)) (snd-display #__line__ ";delete-sample before cursor redo: ~A" (cursor))) (redo -1) (delete-sample 1321) (if (not (= (cursor) 1000)) (snd-display #__line__ ";delete-sample after cursor: ~A" (cursor))) (undo) (delete-samples 0 100) (if (not (= (cursor) 900)) (snd-display #__line__ ";delete-samples before cursor: ~A" (cursor))) (undo) (delete-samples 1100 100) (if (not (= (cursor) 1000)) (snd-display #__line__ ";delete-samples after cursor: ~A" (cursor))) (undo) (insert-samples 100 100 (make-float-vector 100)) (if (not (= (cursor) 1100)) (snd-display #__line__ ";insert-samples before cursor: ~A" (cursor))) (undo) (insert-samples 1100 100 (make-float-vector 100)) (if (not (= (cursor) 1000)) (snd-display #__line__ ";insert-samples after cursor: ~A" (cursor))) (undo) (set! (samples 0 100) (make-float-vector 100)) (if (not (= (cursor) 1000)) (snd-display #__line__ ";set-samples cursor: ~A" (cursor))) (set! (show-axes ind 0) show-x-axis-unlabelled) (update-time-graph) (set! (show-axes ind 0) show-all-axes-unlabelled) (update-time-graph) (close-sound ind)) (let ((ind (new-sound "test.snd" :size 100))) (float-vector->channel (make-float-vector 3 1.0) 10 8) (if (fneq (maxamp ind 0) 1.0) (snd-display #__line__ ";float-vector->channel size mismatch maxamp: ~A" (maxamp ind 0))) (if (not (vequal (channel->float-vector 0 20 ind 0) (float-vector 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 1.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0))) (snd-display #__line__ ";float-vector->channel size mismatch: ~A" (channel->float-vector 0 20 ind 0))) (revert-sound ind) (set! (samples 10 5) (make-float-vector 3 1.0)) (if (fneq (maxamp ind 0) 1.0) (snd-display #__line__ ";set samples size mismatch maxamp: ~A" (maxamp ind 0))) (if (not (vequal (channel->float-vector 0 20 ind 0) (float-vector 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 1.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0))) (snd-display #__line__ ";set samples size mismatch: ~A" (channel->float-vector 0 20 ind 0))) (revert-sound ind) (insert-samples 10 8 (make-float-vector 3 1.0) ind 0) (if (fneq (maxamp ind 0) 1.0) (snd-display #__line__ ";insert samples size mismatch maxamp: ~A" (maxamp ind 0))) (if (not (vequal (channel->float-vector 0 20 ind 0) (float-vector 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 1.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0))) (snd-display #__line__ ";insert samples size mismatch: ~A" (channel->float-vector 0 20 ind 0))) (close-sound ind)) (let* ((index (open-sound "oboe.snd")) (bnds (x-bounds index)) (xp (x-position-slider)) (yp (y-position-slider)) (xz (x-zoom-slider)) (yz (y-zoom-slider))) (if (not (string=? (snd-completion " open-so") " open-sound")) (snd-display #__line__ ";completion: ~A" (snd-completion " open-so"))) ; (if (not (string=? (snd-completion " open-sound") " open-sound")) ; (snd-display #__line__ ";completion: ~A" (snd-completion " open-so"))) (if (not (string=? (snd-completion " zoom-focus-r") " zoom-focus-right")) (snd-display #__line__ ";completion: ~A" (snd-completion " zoom-focus-r"))) (play "oboe.snd" :wait #t) (play "oboe.snd" :start 12000 :wait #t) (play "oboe.snd" :start 12000 :end 15000 :wait #t) (play :edit-position (- (edit-position) 1) :wait #t) (let ((old-speed (speed-control index)) (old-style *speed-control-style*) (old-open (show-controls index))) (set! (show-controls index) #t) (set! (speed-control index) -2.0) (play index :start 12345 :wait #t) (set! *speed-control-style* speed-control-as-semitone) (set! (speed-control index) 0.5) (set! *speed-control-style* speed-control-as-ratio) (set! (speed-control index) 0.25) (set! (speed-control index) old-speed) (set! *speed-control-style* old-style) (set! (show-controls index) old-open)) (let ((k (disk-kspace "oboe.snd"))) (if (or (not (number? k)) (<= k 0)) (snd-display #__line__ ";disk-kspace = ~A" (disk-kspace "oboe.snd"))) (set! k (disk-kspace "/baddy/hiho")) (if (not (= k -1)) (snd-display #__line__ ";disk-kspace of bogus file = ~A" (disk-kspace "/baddy/hiho")))) (if (not (= (transform-framples) 0)) (snd-display #__line__ ";transform-framples ~A?" (transform-framples))) (set! *transform-size* 512) (set! (transform-graph?) #t) (set! (time-graph?) #t) (if with-gui (catch #t (lambda () (if (not (string=? (x-axis-label) "time")) (snd-display #__line__ ";def time x-axis-label: ~A" (x-axis-label))) (set! (x-axis-label index 0 time-graph) "no time") (if (not (string=? (x-axis-label) "no time")) (snd-display #__line__ ";time x-axis-label: ~A" (x-axis-label index 0 time-graph))) (update-transform-graph) (if (not (string=? (x-axis-label index 0 transform-graph) "frequency")) (snd-display #__line__ ";get fft x-axis-label: ~A" (x-axis-label index 0 transform-graph))) (set! (x-axis-label index 0 transform-graph) "hiho") (update-transform-graph) (if (not (string=? (x-axis-label index 0 transform-graph) "hiho")) (snd-display #__line__ ";set fft x-axis-label: ~A" (x-axis-label index 0 transform-graph))) (set! (x-axis-label index 0 transform-graph) "frequency") ; for later test (graph '(0 0 1 1 2 0) "lisp") (update-lisp-graph) (if (not (string=? (x-axis-label index 0 lisp-graph) "lisp")) (snd-display #__line__ ";def lisp x-axis-label: ~A" (x-axis-label index 0 lisp-graph))) (set! (x-axis-label index 0 lisp-graph) "no lisp") (if (not (string=? (x-axis-label index 0 lisp-graph) "no lisp")) (snd-display #__line__ ";lisp x-axis-label: ~A" (x-axis-label index 0 lisp-graph))) (set! (y-axis-label index 0 time-graph) "no amp") (if (not (string=? (y-axis-label) "no amp")) (snd-display #__line__ ";time y-axis-label: ~A" (y-axis-label index 0 time-graph))) (set! (y-axis-label index 0 lisp-graph) "no lamp") (if (not (string=? (y-axis-label index 0 lisp-graph) "no lamp")) (snd-display #__line__ ";lisp y-axis-label: ~A" (y-axis-label index 0 lisp-graph))) (set! (y-axis-label) #f) (set! (y-axis-label index 0) "no amp") (if (not (string=? (y-axis-label) "no amp")) (snd-display #__line__ ";time y-axis-label (time): ~A" (y-axis-label index 0 time-graph))) (set! (y-axis-label index) #f)) (lambda args (snd-display #__line__ ";axis label error: ~A" args)))) (if with-gui (begin (let ((cr (make-cairo (car (channel-widgets index 0))))) (graph-data (make-float-vector 4) index 0 copy-context #f #f graph-lines cr) (free-cairo cr) (update-lisp-graph)) (graph (float-vector 0 0 1 1 2 0)) (do ((i 0 (+ i 1))) ((= i 32)) (graph (float-vector 0 1 2)) (graph (list (float-vector 0 1 2) (float-vector 3 2 1) (float-vector 1 2 3))) (graph (list (float-vector 0 1 2) (float-vector 3 2 1)))) (set! (x-bounds) (list 0.0 0.01)) (let ((data (make-graph-data))) (if (float-vector? data) (let ((mid (round (* .5 (length data))))) (if (not (= (length data) (+ 1 (- (right-sample) (left-sample))))) (snd-display #__line__ ";make-graph-data bounds: ~A ~A -> ~A" (left-sample) (right-sample) (length data))) (if (fneq (data mid) (sample (+ (left-sample) mid))) (snd-display #__line__ ";make-graph-data[~D]: ~A ~A" mid (data mid) (sample (+ (left-sample) mid))))))) (let ((data (make-graph-data index 0 0 100 199))) (if (float-vector? data) (begin (if (not (= (length data) 100)) (snd-display #__line__ ";make-graph-data 100:199: ~A" (length data))) (if (fneq (data 50) (sample 50)) (snd-display #__line__ ";make-graph-data 50: ~A ~A" (data 50) (sample 50)))))) (set! (x-bounds) (list 0.0 0.1)) (update-transform-graph) (catch 'no-such-axis (lambda () (if (not (string=? (x-axis-label index 0 transform-graph) "frequency")) (snd-display #__line__ ";def fft x-axis-label: ~A" (x-axis-label index 0 transform-graph))) (set! (x-axis-label index 0 transform-graph) "fourier") (if (not (string=? (x-axis-label index 0 transform-graph) "fourier")) (snd-display #__line__ ";fft x-axis-label: ~A" (x-axis-label index 0 transform-graph))) (set! (x-axis-label) "hiho") (set! (y-axis-label index 0 transform-graph) "spectra") (let ((val (y-axis-label index 0 transform-graph))) (if (or (not (string? val)) (not (string=? val "spectra"))) (snd-display #__line__ ";fft y-axis-label: ~A" val))) (set! (y-axis-label) "hiho")) (lambda args (snd-display #__line__ ";transform axis not displayed?"))) )) (if (and (number? (transform-framples)) (= (transform-framples) 0)) (snd-display #__line__ ";transform-graph? transform-framples ~A?" (transform-framples))) (update-transform-graph) (let ((tag (catch #t (lambda () (peaks "/baddy/hiho")) (lambda args (car args))))) (if (not (eq? tag 'cant-open-file)) (snd-display #__line__ ";peaks bad file: ~A" tag))) (peaks "tmp.peaks") (let ((p (open-input-file "tmp.peaks"))) (if (not p) (snd-display #__line__ ";peaks->tmp.peaks failed?") (let ((line (read-line p))) (if (or (not (string? line)) (not (string=? "Snd: fft peaks" (substring line 0 14)))) (snd-display #__line__ ";peaks 1: ~A?" line)) (set! line (read-line p)) (set! line (read-line p)) (if (and (not (eof-object? line)) (or (not (string? line)) (and (not (string=? "oboe.snd, fft 512 points beginning at sample 0 (0.000 secs), Blackman2" line)) (not (string=? (string-append "oboe.snd, fft 512 points beginning at sample 0 (0.000 secs), Blackman2" (string #\newline)) line))))) (snd-display #__line__ ";peaks 2: ~A?" line)) (set! line (read-line p)) (set! line (read-line p)) (close-input-port p)))) (delete-file "tmp.peaks") (peaks) (if (and (provided? 'xm) (or (not ((dialog-widgets) 15)) (not ((*motif* 'XtIsManaged) ((dialog-widgets) 15))))) (snd-display #__line__ ";peaks but no help?")) (dismiss-all-dialogs) (let ((num-transforms 6) (num-transform-graph-types 3)) (set! (transform-graph? index 0) #t) (set! (transform-size index 0) 64) (do ((i 0 (+ i 1))) ((= i num-transforms)) (set! *transform-type* (integer->transform i)) (if (not (transform? (integer->transform i))) (snd-display #__line__ ";transform? ~A?" i)) (do ((j 0 (+ j 1))) ((= j num-transform-graph-types)) (set! (transform-graph-type index 0) j) (update-transform-graph index 0)))) (set! *transform-type* fourier-transform) (if (not (transform? *transform-type*)) (snd-display #__line__ ";transform? ~A ~A?" *transform-type* fourier-transform)) (if (not (transform? autocorrelation)) (snd-display #__line__ ";transform? autocorrelation")) (if (read-only index) (snd-display #__line__ ";read-only open-sound: ~A?" (read-only index))) (set! (read-only index) #t) (if (not (read-only index)) (snd-display #__line__ ";set-read-only: ~A?" (read-only index))) (bind-key #\a 0 (lambda () (set! a-ctr 3))) (key (char->integer #\a) 0) (if (not (= a-ctr 3)) (snd-display #__line__ ";bind-key: ~A?" a-ctr)) (let ((str (with-output-to-string (lambda () (display (procedure-source (key-binding (char->integer #\a) 0))))))) (if (not (string=? str "(lambda () (set! a-ctr 3))")) (snd-display #__line__ ";key-binding: ~A?" str))) (unbind-key (char->integer #\a) 0) (set! a-ctr 0) (key (char->integer #\a) 0) (do ((i 0 (+ i 1))) ((= i 5)) (let ((psf *eps-file*)) (if (and psf (string? psf)) (begin (if (file-exists? psf) (delete-file psf)) (set! *graph-style* i) (graph->ps) (if (not (file-exists? psf)) (snd-display #__line__ ";graph->ps: ~A?" psf) (delete-file psf)))))) (let ((err (catch 'cannot-print (lambda () (graph->ps "/bad/bad.eps")) (lambda args 12345)))) (if (not (= err 12345)) (snd-display #__line__ ";graph->ps err: ~A?" err))) (when with-gui (let ((n2 (or (open-sound "2.snd") (open-sound "4.aiff")))) (set! (transform-graph? n2) #t) (set! (channel-style n2) channels-superimposed) (if (not (= (channel-style n2) channels-superimposed)) (snd-display #__line__ ";channel-style->~D: ~A?" channels-superimposed (channel-style n2))) (graph->ps "aaa.eps") (set! (channel-style n2) channels-combined) (if (not (= (channel-style n2) channels-combined)) (snd-display #__line__ ";channel-style->~D: ~A?" channels-combined (channel-style n2))) (graph->ps "aaa.eps") (set! (channel-style n2) channels-separate) (if (not (= (channel-style n2) channels-separate)) (snd-display #__line__ ";channel-style->~D: ~A?" channels-separate (channel-style n2))) (graph->ps "aaa.eps") (close-sound n2))) (if (= (channels index) 1) (begin (set! (channel-style index) channels-superimposed) (if (not (= (channel-style index) channels-separate)) (snd-display #__line__ ";channel-style[0]->~D: ~A?" channels-separate (channel-style index))))) (set! (sync index) 32) (if (not (= (sync index) 32)) (snd-display #__line__ ";sync->32: ~A?" (sync index))) (if (< (sync-max) 32) (snd-display #__line__ ";sync-max 32: ~A" (sync-max))) (set! (sync index) 0) (set! (channel-sync index 0) 12) (if (not (= (channel-sync index 0) 12)) (snd-display #__line__ ";sync-chn->12: ~A?" (channel-sync index 0))) (set! (channel-sync index 0) 0) (if (not (= a-ctr 0)) (snd-display #__line__ ";unbind-key: ~A?" a-ctr)) (if (fneq xp 0.0) (snd-display #__line__ ";x-position-slider: ~A?" xp)) (if (fneq yp 0.0) (snd-display #__line__ ";y-position-slider: ~A?" yp)) (if (and (fneq xz 0.04338) (fneq xz 1.0)) (snd-display #__line__ ";x-zoom-slider: ~A?" xz)) (if (fneq yz 1.0) (snd-display #__line__ ";y-zoom-slider: ~A?" yz)) (if (and (or (fneq (car bnds) 0.0) (fneq (cadr bnds) 0.1)) (or (fneq (car bnds) 0.0) (fneq (cadr bnds) 2.305))) ; open-hook from ~/.snd* (snd-display #__line__ ";x-bounds: ~A?" bnds)) (if (not (equal? (find-sound "oboe.snd") index)) (snd-display #__line__ ";oboe: index ~D is not ~D?" (find-sound "oboe.snd") index)) (if (not (sound? index)) (snd-display #__line__ ";oboe: ~D not ok?" index)) (if (not (= (chans index) 1)) (snd-display #__line__ ";oboe: chans ~D?" (chans index))) (if (not (= (channels index) 1)) (snd-display #__line__ ";oboe: channels ~D?" (channels index))) (if (not (= (framples index) 50828)) (snd-display #__line__ ";oboe: framples ~D?" (framples index))) (if (not (= (srate index) 22050)) (snd-display #__line__ ";oboe: srate ~D?" (srate index))) (if (not (= (data-location index) 28)) (snd-display #__line__ ";oboe: location ~D?" (data-location index))) (if (not (= (data-size index) (* 50828 2))) (snd-display #__line__ ";oboe: size ~D?" (data-size index))) (if (not (= (sample-type index) mus-bshort)) (snd-display #__line__ ";oboe: format ~A?" (sample-type index))) (if (fneq (maxamp index) .14724) (snd-display #__line__ ";oboe: maxamp ~F?" (maxamp index))) (if (not (= (maxamp-position index) 24971)) (snd-display #__line__ ";oboe: maxamp-position ~A?" (maxamp-position index))) (if (> (length (comment index)) 0) (snd-display #__line__ ";oboe: comment ~A?" (comment index))) (if (not (= (length "asdf") 4)) (snd-display #__line__ ";string-length: ~A?" (length "asdf"))) (if (not (string=? (short-file-name index) "oboe.snd")) (snd-display #__line__ ";oboe short name: ~S?" (short-file-name index))) (let ((matches (count-matches (lambda (a) (> a .125))))) (if (not (= matches 1313)) (snd-display #__line__ ";count-matches: ~A?" matches))) (let ((spot (scan-channel (lambda (a) (> a .13))))) (if (or (not spot) (not (= spot 8862))) (snd-display #__line__ ";find: ~A?" spot))) (set! (right-sample) 3000) (let ((samp (right-sample))) (if (> (abs (- samp 3000)) 1) (snd-display #__line__ ";right-sample: ~A?" samp))) (set! (left-sample) 1000) (let ((samp (left-sample))) (if (> (abs (- samp 1000)) 1) (snd-display #__line__ ";left-sample: ~A?" samp))) (let ((eds (edits))) (if (not (= (car eds) 0 (cadr eds))) (snd-display #__line__ ";edits: ~A?" eds)) (if (not (= (edit-position) (car eds))) (snd-display #__line__ ";edit-position: ~A ~A?" (edit-position) eds))) (play index :channel 0 :wait #t) (if (not *selection-creates-region*) (set! *selection-creates-region* #t)) (select-all index 0) (let ((r0 (car (regions))) (sel (selection))) (if (not (selection?)) (snd-display #__line__ ";selection?")) (if (not (selection? sel)) (snd-display #__line__ ";selection? sel")) (if (not (region? r0)) (snd-display #__line__ ";region?")) (if (not (= (selection-chans) 1)) (snd-display #__line__ ";selection-chans(1): ~A" (selection-chans))) (if (not (= (channels sel) 1)) (snd-display #__line__ ";generic selection-chans(1): ~A" (channels sel))) (if (not (= (selection-srate) (srate index))) (snd-display #__line__ ";selection-srate: ~A ~A" (selection-srate) (srate index))) (if (not (= (srate sel) (srate index))) (snd-display #__line__ ";generic selection-srate: ~A ~A" (srate sel) (srate index))) (if (fneq (region-maxamp r0) (maxamp index)) (snd-display #__line__ ";region-maxamp (1): ~A?" (region-maxamp r0))) (if (not (= (region-maxamp-position r0) (maxamp-position index))) (snd-display #__line__ ";region-maxamp-position (1): ~A ~A?" (region-maxamp-position r0) (maxamp-position index))) (if (fneq (selection-maxamp index 0) (maxamp index)) (snd-display #__line__ ";selection-maxamp (1): ~A?" (selection-maxamp index 0))) (if (fneq (maxamp sel index 0) (maxamp index)) (snd-display #__line__ ";generic selection-maxamp (1): ~A?" (maxamp sel index 0))) (if (not (= (selection-maxamp-position index 0) (maxamp-position index))) (snd-display #__line__ ";selection-maxamp-position (1): ~A ~A?" (selection-maxamp-position index 0) (maxamp-position index))) (save-region r0 "temp.dat") (if (file-exists? "temp.dat") (delete-file "temp.dat") (snd-display #__line__ ";save-region file disappeared?")) (play r0 :wait #t) ;needs to be #t here or it never gets run (if (not (= (length (regions)) 1)) (snd-display #__line__ ";regions: ~A?" (regions))) (if (not (selection-member? index)) (snd-display #__line__ ";selection-member?: ~A" (selection-member? index))) (if (not (= (region-srate r0) 22050)) (snd-display #__line__ ";region-srate: ~A?" (region-srate r0))) (if (not (= (region-chans r0) 1)) (snd-display #__line__ ";region-chans: ~A?" (region-chans r0))) (if (not (equal? (region-home r0) (list "oboe.snd" 0 50827))) (snd-display #__line__ ";region-home: ~A" (region-home r0))) (if (not (= (region-framples r0) 50828)) (snd-display #__line__ ";region-framples: ~A?" (region-framples r0))) (if (not (= (selection-framples) 50828)) (snd-display #__line__ ";selection-framples: ~A?" (selection-framples 0))) (if (not (= (framples sel) 50828)) (snd-display #__line__ ";generic selection-framples: ~A?" (framples sel))) (if (not (= (length sel) 50828)) (snd-display #__line__ ";generic length selection-framples: ~A?" (length sel))) (if (not (= (selection-position) 0)) (snd-display #__line__ ";selection-position: ~A?" (selection-position))) (if (not (= (region-position r0 0) 0)) (snd-display #__line__ ";region-position: ~A?" (region-position r0 0))) (if (fneq (region-maxamp r0) (maxamp index)) (snd-display #__line__ ";region-maxamp: ~A?" (region-maxamp r0))) (if (fneq (selection-maxamp index 0) (maxamp index)) (snd-display #__line__ ";selection-maxamp: ~A?" (selection-maxamp index 0))) (let ((samps1 (channel->float-vector 0 50827 index 0)) (samps2 (region->float-vector r0 0 50828 0)) (vr (make-sampler 0 index 0 1))) (if (not (sampler? vr)) (snd-display #__line__ ";~A not sampler?" vr)) (if (not (= (sampler-position vr) 0)) (snd-display #__line__ ";initial sampler-position: ~A" (sampler-position vr))) (if (not (equal? (sampler-home vr) (list index 0))) (snd-display #__line__ ";sampler-home: ~A ~A?" (sampler-home vr) (list index 0))) (if (sampler-at-end? vr) (snd-display #__line__ ";~A init at end?" vr)) (let ((err (catch #t (lambda () (region->float-vector r0 -1 1233)) (lambda args (car args))))) (if (not (eq? err 'no-such-sample)) (snd-display #__line__ ";region->float-vector -1: ~A" err))) (let ((err (catch #t (lambda () (region->float-vector r0 12345678 1)) (lambda args (car args))))) ;; should this return 'no-such-sample? (if err (snd-display #__line__ ";region->float-vector 12345678: ~A" err))) (let ((reader-string (format #f "~A" vr))) (if (not (string=? reader-string "#")) (snd-display #__line__ ";sampler actually got: [~S]" reader-string))) (let ((evr vr)) (if (not (equal? evr vr)) (snd-display #__line__ ";sampler equal? ~A ~A" vr evr))) (catch 'break (lambda () (do ((i 0 (+ i 1))) ((= i 50827)) (if (not (= (if (odd? i) (next-sample vr) (read-sample vr)) (samps1 i) (samps2 i))) (begin (snd-display #__line__ ";readers disagree at ~D" i) (throw 'break))))) (lambda args (car args))) (free-sampler vr))) (let ((var (catch #t (lambda () (make-sampler 0 index -1)) (lambda args args)))) (if (not (eq? (car var) 'no-such-channel)) (snd-display #__line__ ";make-sampler bad chan (-1): ~A" var))) (let ((var (catch #t (lambda () (make-sampler 0 index 1)) (lambda args args)))) (if (not (eq? (car var) 'no-such-channel)) (snd-display #__line__ ";make-sampler bad chan (1): ~A, ~A" var index))) (let ((fd (make-sampler 0))) (if (mix-sampler? fd) (snd-display #__line__ ";sampler: mix ~A" fd)) (if (region-sampler? fd) (snd-display #__line__ ";sampler: region ~A" fd)) (if (not (sampler? fd)) (snd-display #__line__ ";sampler: normal ~A" fd)) (if (not (= (sampler-position fd) 0)) (snd-display #__line__ ";sampler: position: ~A" fd)) (free-sampler fd) (let ((str (format #f "~A" fd))) (if (not (string=? (substring str (- (length str) 16)) "at eof or freed>")) (snd-display #__line__ ";freed sampler: ~A [~A]?" str (substring str (- (length str) 16)))))) (let* ((reg (car (regions))) (chns (region-chans reg)) (var (catch #t (lambda () (make-region-sampler reg 0 (+ chns 1))) (lambda args args)))) (if (not (eq? (car var) 'no-such-channel)) (snd-display #__line__ ";make-region-sampler bad chan (2): ~A ~A" var (regions))) (let ((tag (catch #t (lambda () (make-region-sampler reg 0 0 -2)) (lambda args args)))) (if (not (eq? (car tag) 'no-such-direction)) (snd-display #__line__ ";make-region-sampler bad dir (-2): ~A" tag)))) (revert-sound index) (insert-sample 100 .5 index) (let ((var (catch #t (lambda () (insert-sound "oboe.snd" 0 1)) (lambda args args)))) (if (not (eq? (car var) 'no-such-channel)) (snd-display #__line__ ";insert-sound bad chan (1): ~A" var))) (let ((var (catch #t (lambda () (insert-sample -12 1.0)) (lambda args args)))) (if (not (eq? (car var) 'no-such-sample)) (snd-display #__line__ ";insert-sample bad pos: ~A" var))) (set! (show-axes index 0) show-no-axes) (update-transform-graph index) (update-time-graph index) (if (or (fneq (sample 100) .5) (not (= (framples index) 50829))) (snd-display #__line__ ";insert-sample: ~A ~A?" (sample 100) (framples index))) (let ((v0 (make-vector 3)) (v1 (make-float-vector 3))) (fill! v1 .75) (fill! v0 0.25) (insert-samples 200 3 v0 index) (insert-samples 300 3 v1 index) (if (or (fneq (sample 201) .25) (fneq (sample 301) .75) (not (= (framples index) 50835))) (snd-display #__line__ ";insert-samples: ~A ~A ~A?" (sample 201) (sample 301) (framples index)))) (save-sound-as "hiho.snd" index 22050 mus-ldouble mus-next) (let ((nindex (view-sound "hiho.snd"))) (if (fneq (sample 101 nindex) (sample 101 index)) (snd-display #__line__ ";save-sound-as: ~A ~A?" (sample 101 nindex) (sample 101 index))) (if (not (read-only nindex)) (snd-display #__line__ ";read-only view-sound: ~A?" (read-only nindex))) (set! (speed-control-style nindex) speed-control-as-semitone) (if (not (= (speed-control-style nindex) speed-control-as-semitone)) (snd-display #__line__ ";speed-control-style set semi: ~A" (speed-control-style nindex))) (set! (speed-control-tones nindex) -8) (if (not (= (speed-control-tones nindex) 12)) (snd-display #__line__ ";speed-control-tones -8: ~A" (speed-control-tones nindex))) (set! (speed-control-tones nindex) 18) (if (not (= (speed-control-tones nindex) 18)) (snd-display #__line__ ";speed-control-tones 18: ~A" (speed-control-tones nindex))) (graph->ps "aaa.eps") (close-sound nindex)) (revert-sound index) (set! (sample 50 index) .5) (if (fneq (sample 50) .5) (snd-display #__line__ ";set-sample: ~A?" (sample 50))) (let ((v0 (make-vector 3 0.25))) (set! (samples 60 3 index) v0) (if (or (fneq (sample 60) .25) (fneq (sample 61) .25)) (snd-display #__line__ ";set-samples: ~A ~A ~A?" (sample 60) (sample 61) (sample 62)))) (set! (samples 10 3 index) (list 0.1 0.2 0.3)) (if (not (vequal (channel->float-vector 10 3 index) (float-vector 0.1 0.2 0.3))) (snd-display #__line__ ";set-samples via list: ~A" (channel->float-vector 10 3 index))) (revert-sound index) (save-sound-as "temporary.snd" index) (set! (samples 100000 20000 index) "temporary.snd") (if (not (vequal (channel->float-vector 110000 10) (channel->float-vector 10000 10))) (snd-display #__line__ ";set samples to self: ~A ~A" (channel->float-vector 110000 10) (channel->float-vector 10000 10))) (revert-sound index) (delete-sample 100 index) (if (not (file-exists? "temporary.snd")) (snd-display #__line__ ";set-samples temp deleted?")) (delete-file "temporary.snd") (if (not (= (framples index) 50827)) (snd-display #__line__ ";delete-sample: ~A?" (framples index))) (delete-samples 0 100 index) (if (not (= (framples index) 50727)) (snd-display #__line__ ";delete-samples: ~A?" (framples index))) (revert-sound index) (let ((maxa (maxamp index))) (scale-to .5 index) (let ((newmaxa (maxamp index))) (if (fneq newmaxa .5) (snd-display #__line__ ";scale-to: ~A?" newmaxa)) (undo 1 index) (scale-by 2.0 index) (set! newmaxa (maxamp index)) (if (fneq newmaxa (* 2.0 maxa)) (snd-display #__line__ ";scale-by: ~A?" newmaxa)) (revert-sound index) (scale-by -1 index) (mix "oboe.snd") (if (fneq (maxamp index 0) 0.0) (snd-display #__line__ ";invert+mix->~A" (maxamp))) (revert-sound index) (select-all index) (if (not (= (length (regions)) 2)) (snd-display #__line__ ";regions(2): ~A?" (regions))) (scale-selection-to .5) (set! newmaxa (maxamp index)) (if (fneq newmaxa .5) (snd-display #__line__ ";scale-selection-to: ~A?" newmaxa)) (revert-sound index) (select-all index) (scale-selection-by 2.0) (set! newmaxa (maxamp index)) (if (fneq newmaxa (* 2.0 maxa)) (snd-display #__line__ ";scale-selection-by: ~A?" newmaxa)) (revert-sound index) (with-temporary-selection (lambda () (scale-selection-by 2.0)) 0 (framples) index 0) (set! newmaxa (maxamp index)) (if (fneq newmaxa (* 2.0 maxa)) (snd-display #__line__ ";with-temporary-selection: ~A?" newmaxa)) (revert-sound index) (let ((samp999 (sample 999 index 0)) (samp1001 (sample 1001 index 0))) (with-temporary-selection (lambda () (scale-selection-to 2.0)) 1000 1 index 0) (if (fneq (sample 1000 index 0) 2.0) (snd-display #__line__ ";with-temporary-selection 1000: ~A" (sample 1000 index 0))) (if (fneq (sample 999 index 0) samp999) (snd-display #__line__ ";with-temporary-selection 999: ~A from ~A" (sample 999 index 0) samp999)) (if (fneq (sample 1001 index 0) samp1001) (snd-display #__line__ ";with-temporary-selection 1001: ~A from ~A" (sample 1001 index 0) samp1001))) (revert-sound index) (make-selection 100 199 index 0) (let ((old-start (selection-position index 0)) (old-len (selection-framples index 0))) (with-temporary-selection (lambda () (scale-selection-to 2.0)) 1000 1 index 0) (if (not (selection?)) (snd-display #__line__ ";with-temporary-selection restore?")) (if (not (selection-member? index 0)) (snd-display #__line__ ";with-temporary-selection not member?")) (if (not (= (selection-position index 0) old-start)) (snd-display #__line__ ";with-temporary-selection start: ~A" (selection-position index 0))) (if (not (= (selection-framples index 0) old-len)) (snd-display #__line__ ";with-temporary-selection len: ~A" (selection-framples index 0)))) (unselect-all) (if (selection-member? index 0) (snd-display #__line__ ";unselect all ~D 0?" index)) (revert-sound index) (select-all index) (let ((rread (make-region-sampler (car (regions)) 0)) (sread (make-sampler 0 index)) (rvect (region->float-vector (car (regions)) 0 100)) (svect (samples 0 100 index))) (if (fneq (rvect 1) (region-sample (car (regions)) 1)) (snd-display #__line__ ";region-sample: ~A ~A?" (region-sample (car (regions)) 1) (rvect 1))) (do ((i 0 (+ i 1))) ((= i 100)) (let ((rval (next-sample rread)) (sval (next-sample sread))) (if (fneq rval sval) (snd-display #__line__ ";sample-read: ~A ~A?" rval sval)) (if (fneq rval (rvect i)) (snd-display #__line__ ";region-samples: ~A ~A?" rval (rvect i))) (if (fneq sval (svect i)) (snd-display #__line__ ";samples: ~A ~A?" sval (svect i))))) (free-sampler rread) (let ((val0 (next-sample sread))) (if (sampler-at-end? sread) (snd-display #__line__ ";premature end?")) (previous-sample sread) (let ((val1 (previous-sample sread))) (if (fneq val0 val1) (snd-display #__line__ ";previous-sample: ~A ~A?" val0 val1)))) (free-sampler sread)))) (revert-sound index) (let ((s100 (sample 100)) (s40 (sample 40)) (len (framples)) (addlen (mus-sound-framples "fyow.snd"))) (set! *cursor-style* cursor-line) (set! *cursor-size* 25) (set! (cursor index) 50) (if (not (= *cursor-style* cursor-line)) (snd-display #__line__ ";cursor-style: ~A? " *cursor-style*)) (if (not (= *cursor-size* 25)) (snd-display #__line__ ";cursor-size: ~A? " *cursor-size*)) (set! *cursor-style* cursor-cross) (set! *cursor-size* 15) (set! (cursor index 0) 30) (set! *cursor-style* cursor-line) (set! (cursor index 0) 20) (if with-gui (begin (set! (cursor-style index 0) (lambda (snd chn ax) (let* ((point (cursor-position)) (x (car point)) (y (cadr point)) (size (floor (/ *cursor-size* 2))) (cr (make-cairo (car (channel-widgets snd chn))))) (draw-line (- x size) (- y size) (+ x size) (+ y size) snd chn cursor-context cr) (draw-line (- x size) (+ y size) (+ x size) (- y size) snd chn cursor-context cr) (free-cairo cr)))) (if (not (procedure? (cursor-style index 0))) (snd-display #__line__ ";set cursor-style to proc: ~A" (cursor-style index 0))))) (set! (cursor index) 50) (insert-sound "fyow.snd" (cursor) 0 index 0) (if (or (fneq (sample 40) s40) (not (fneq (sample 100) s100)) (fneq (sample 100) 0.001831)) (snd-display #__line__ ";insert-sound: ~A?" (sample 100))) (if (not (= (framples) (+ len addlen))) (snd-display #__line__ ";insert-sound len: ~A?" (framples))) (save-sound-as "not-temporary.snd") (insert-samples 0 100 "not-temporary.snd") (set! (cursor index 0 0) (- (framples index 0 0) 2)) (revert-sound) (if (not (= (cursor index 0) (- (framples index 0) 2))) (snd-display #__line__ ";set edpos cursor: ~A ~A ~A" (cursor) (cursor index 0 0) (- (framples index 0 0) 2))) (if (not (file-exists? "not-temporary.snd")) (snd-display #__line__ ";insert-samples deleted its file?") (delete-file "not-temporary.snd")) (let ((id (make-region 0 99))) (insert-region id 60 index) (if (not (= (framples) (+ len 100))) (snd-display #__line__ ";insert-region len: ~A?" (framples))) (if (fneq (sample 100) s40) (snd-display #__line__ ";insert-region: ~A ~A?" (sample 100) s40)) (let ((var (catch #t (lambda () (insert-region (integer->region (+ 1000 (apply max (map region->integer (regions))))) 0)) (lambda args args)))) (if (not (eq? (car var) 'no-such-region)) (snd-display #__line__ ";insert-region bad id: ~A" var))) (save-region id "fmv.snd") (if (not (= (mus-sound-header-type "fmv.snd") mus-next)) (snd-display #__line__ ";save-region header: ~A?" (mus-header-type-name (mus-sound-header-type "fmv.snd")))) (if (not (= (mus-sound-sample-type "fmv.snd") mus-out-format)) (snd-display #__line__ ";save-region format: ~A?" (mus-sample-type-name (mus-sound-sample-type "fmv.snd")))) (if (not (= (mus-sound-srate "fmv.snd") (region-srate id))) (snd-display #__line__ ";save-region srate: ~A (~A)" (mus-sound-srate "fmv.snd") (region-srate id))) (if (not (= (mus-sound-chans "fmv.snd") (region-chans id))) (snd-display #__line__ ";save-region chans: ~A (~A)" (mus-sound-chans "fmv.snd") (region-chans id))) (if (not (= (mus-sound-framples "fmv.snd") (region-framples id))) (snd-display #__line__ ";save-region length: ~A (~A)" (mus-sound-framples "fmv.snd") (region-framples id))) (if (not (= (region-position id 0) 0)) (snd-display #__line__ ";save-region position: ~A" (region-position id 0))) (delete-file "fmv.snd") (save-region id "fmv.snd" mus-lshort mus-riff "this is a comment") (if (not (= (mus-sound-header-type "fmv.snd") mus-riff)) (snd-display #__line__ ";save-region riff header: ~A?" (mus-header-type-name (mus-sound-header-type "fmv.snd")))) (if (not (= (mus-sound-sample-type "fmv.snd") mus-lshort)) (snd-display #__line__ ";save-region lshort format: ~A?" (mus-sample-type-name (mus-sound-sample-type "fmv.snd")))) (if (not (= (mus-sound-framples "fmv.snd") (region-framples id))) (snd-display #__line__ ";save-region length: ~A (~A)" (mus-sound-framples "fmv.snd") (region-framples id))) (if (not (string=? (mus-sound-comment "fmv.snd") "this is a comment")) (snd-display #__line__ ";save-region comment: ~A" (mus-sound-comment "fmv.snd"))) (delete-file "fmv.snd") (save-region id :file "fmv.snd" :header-type mus-riff :sample-type mus-lshort :comment "this is a comment") (if (not (= (mus-sound-header-type "fmv.snd") mus-riff)) (snd-display #__line__ ";save-region opt riff header: ~A?" (mus-header-type-name (mus-sound-header-type "fmv.snd")))) (if (not (= (mus-sound-sample-type "fmv.snd") mus-lshort)) (snd-display #__line__ ";save-region opt lshort format: ~A?" (mus-sample-type-name (mus-sound-sample-type "fmv.snd")))) (if (not (= (mus-sound-framples "fmv.snd") (region-framples id))) (snd-display #__line__ ";save-region opt length: ~A (~A)" (mus-sound-framples "fmv.snd") (region-framples id))) (if (not (string=? (mus-sound-comment "fmv.snd") "this is a comment")) (snd-display #__line__ ";save-region opt comment: ~A" (mus-sound-comment "fmv.snd"))) (delete-file "fmv.snd") (save-region id :comment "this is a comment" :file "fmv.snd" :sample-type mus-lshort :header-type mus-riff) (if (not (= (mus-sound-header-type "fmv.snd") mus-riff)) (snd-display #__line__ ";save-region opt1 riff header: ~A?" (mus-header-type-name (mus-sound-header-type "fmv.snd")))) (if (not (= (mus-sound-sample-type "fmv.snd") mus-lshort)) (snd-display #__line__ ";save-region opt1 lshort format: ~A?" (mus-sample-type-name (mus-sound-sample-type "fmv.snd")))) (if (not (= (mus-sound-framples "fmv.snd") (region-framples id))) (snd-display #__line__ ";save-region opt1 length: ~A (~A)" (mus-sound-framples "fmv.snd") (region-framples id))) (if (not (string=? (mus-sound-comment "fmv.snd") "this is a comment")) (snd-display #__line__ ";save-region opt1 comment: ~A" (mus-sound-comment "fmv.snd"))) (delete-file "fmv.snd") (save-region id "fmv.snd" :sample-type mus-bshort) (if (not (= (mus-sound-header-type "fmv.snd") mus-next)) (snd-display #__line__ ";save-region opt2 next header: ~A?" (mus-header-type-name (mus-sound-header-type "fmv.snd")))) (if (not (= (mus-sound-sample-type "fmv.snd") mus-bshort)) (snd-display #__line__ ";save-region opt2 bshort format: ~A?" (mus-sample-type-name (mus-sound-sample-type "fmv.snd")))) (delete-file "fmv.snd") )) (close-sound index) (let ((var (catch #t (lambda () (new-sound "hi.snd" :channels 0)) (lambda args args)))) (if (or (not (pair? var)) (not (eq? (car var) 'out-of-range))) (snd-display #__line__ ";new-sound bad chan: ~A" var))) (set! index (new-sound "fmv.snd" 2 22050 mus-ldouble mus-next "unequal lens")) (insert-silence 0 1000 index 1) (if (or (not (= (framples index 0) 1)) (not (= (framples index 1) 1001))) (snd-display #__line__ ";silence 1: ~A ~A" (framples index 0) (framples index 1))) (save-sound index) (if (or (not (= (framples index 0) 1001)) (not (= (framples index 1) 1001))) (snd-display #__line__ ";saved silence 1: ~A ~A" (framples index 0) (framples index 1))) (if (not (= (mus-sound-framples "fmv.snd") 1001)) (snd-display #__line__ ";saved framers silence 1: ~A" (mus-sound-framples "fmv.snd"))) (let ((v0 (channel->float-vector 0 1000 index 0)) (v1 (channel->float-vector 0 1000 index 1))) (if (fneq (float-vector-peak v0) 0.0) (snd-display #__line__ ";auto-pad 0: ~A" (float-vector-peak v0))) (if (fneq (float-vector-peak v1) 0.0) (snd-display #__line__ ";silence 0: ~A" (float-vector-peak v1)))) (close-sound index) (delete-file "fmv.snd") (set! index (new-sound "fmv.snd" 2 22050 mus-ldouble mus-next "unequal lens")) (pad-channel 0 1000 index 1) (if (or (not (= (framples index 0) 1)) (not (= (framples index 1) 1001))) (snd-display #__line__ ";pad-channel 1: ~A ~A" (framples index 0) (framples index 1))) (let ((v0 (channel->float-vector 0 1000 index 0)) (v1 (channel->float-vector 0 1000 index 1))) (if (fneq (float-vector-peak v0) 0.0) (snd-display #__line__ ";pad 0: ~A" (float-vector-peak v0))) (if (fneq (float-vector-peak v1) 0.0) (snd-display #__line__ ";pad 1: ~A" (float-vector-peak v1)))) (map-channel (lambda (n) 1.0) 0 2 index 0) (map-channel (lambda (n) 1.0) 0 1002 index 1) (pad-channel 0 1000 index 0 1) (if (not (= (framples index 1) 1002)) (snd-display #__line__ ";pad-channel ed 1: ~A ~A" (framples index 0) (framples index 1))) (close-sound index) (delete-file "fmv.snd") (let ((ind (open-sound "1a.snd"))) (scale-to 1.0 ind 0) (make-selection 1000 2000 ind 0) (filter-selection-and-smooth .01 (float-vector .25 .5 .5 .5 .25)) ; (if (fneq (sample 1500 ind 0) -0.0045776) (snd-display #__line__ ";filter-selection-and-smooth: ~A" (sample 1500 ind 0))) (revert-sound ind) (close-sound ind)) (set! index (new-sound "fmv.snd" 1 22050 mus-bshort mus-ircam "this is a comment")) (let ((v0 (make-float-vector 128))) (set! (v0 64) .5) (set! (v0 127) .5) (float-vector->channel v0 0 128 index 0) (make-selection 0 126) (smooth-selection) (set! v0 (channel->float-vector 0 128 index 0)) (if (or (fneq (sample 127) .5) (fneq (sample 120) .4962) (fneq (sample 32) 0.07431) (fneq (sample 64) 0.25308)) (snd-display #__line__ ";smooth-selection: ~A?" v0)) (revert-sound index) (fill! v0 0.0) (set! (v0 10) .5) (float-vector->channel v0) (select-all) (let ((old-wid *sinc-width*)) (set! *sinc-width* 40) (src-selection 0.5) (set! *sinc-width* old-wid)) (set! v0 (channel->float-vector 0 128 index 0)) (if (or (fneq (sample 20) .5) (fneq (sample 30) 0.0) (fneq (sample 17) -.1057) ) (snd-display #__line__ ";src-selection: ~A?" v0)) (unselect-all) (if (selection-member?) (snd-display #__line__ ";unselect-all but still a selection?")) (unselect-all) (revert-sound index) (fill! v0 0.0) (set! (v0 10) .5) (float-vector->channel v0 0) (select-all) (filter-selection '(0 0 .1 1 1 0) 40) (set! v0 (channel->float-vector 0 128 index 0)) (if (or (fneq (sample 29) .1945) (fneq (sample 39) -.0137) (fneq (sample 24) -0.01986)) (snd-display #__line__ ";filter-selection: ~A?" v0)) (revert-sound index) (fill! v0 1.0) (float-vector->channel v0 0 128 index 0) (select-all) (filter-selection (make-one-zero :a0 .5 :a1 0.0)) (set! v0 (channel->float-vector 0 128 index 0)) (if (or (fneq (sample 29) .5) (fneq (sample 39) .5) (fneq (sample 24) 0.5)) (snd-display #__line__ ";filter-selection one-zero: ~A?" v0)) (revert-sound index) (fill! v0 1.0) (float-vector->channel v0 0 128 index 0) (if (file-exists? "fmv5.snd") (delete-file "fmv5.snd")) (select-all) (env-selection '(0 0 1 1 2 0) 1.0) (set! v0 (channel->float-vector 0 128 index 0)) (if (or (fneq (sample 64) 1.0) (fneq (sample 20) .3125) (fneq (sample 119) 0.127)) (snd-display #__line__ ";env-selection [len: ~A]: ~A ~A ~A ~A?" (selection-framples) (sample 64) (sample 20) (sample 119) v0)) (save-selection "fmv5.snd" 22050 mus-bint mus-next "") ;1.0->-1.0 if short (revert-sound index) (let ((tag (catch #t (lambda () (file->array "/baddy/hiho" 0 0 128 v0)) (lambda args (car args))))) (if (not (eq? tag 'no-such-file)) (snd-display #__line__ ";file->array w/o file: ~A" tag))) (let ((tag (catch #t (lambda () (file->array "fmv5.snd" 123 0 128 v0)) (lambda args (car args))))) (if (not (eq? tag 'no-such-channel)) (snd-display #__line__ ";file->array w/o channel: ~A" tag))) (file->array "fmv5.snd" 0 0 128 v0) (if (or (fneq (v0 64) 1.0) (fneq (v0 20) .3125) (fneq (v0 119) 0.127)) (snd-display #__line__ ";save-selection: ~A ~A ~A ~A?" (v0 64) (v0 20) (v0 119) v0)) (if (not (= (mus-sound-header-type "fmv5.snd") mus-next)) (snd-display #__line__ ";save-selection type: ~A?" (mus-header-type-name (mus-sound-header-type "fmv5.snd")))) (if (not (= (mus-sound-sample-type "fmv5.snd") mus-bint)) (snd-display #__line__ ";save-selection format: ~A?" (mus-sample-type-name (mus-sound-sample-type "fmv5.snd")))) (if (not (= (mus-sound-srate "fmv5.snd") 22050)) (snd-display #__line__ ";save-selection srate: ~A?" (mus-sound-srate "fmv5.snd"))) (fill! v0 0.0) (set! (v0 100) .5) (set! (v0 2) -.5) (float-vector->channel v0 0 128 index 0) (select-all) (without-errors (reverse-selection)) (save-selection "fmv4.snd" 44100 mus-lfloat mus-riff "this is a comment") (set! v0 (channel->float-vector 0 128 index 0)) (if (or (fneq (sample 27) 0.5) (fneq (sample 125) -.5)) (snd-display #__line__ ";reverse-selection: ~A?" v0)) (file->array "fmv4.snd" 0 0 128 v0) (if (or (fneq (sample 27) 0.5) (fneq (sample 125) -.5)) (snd-display #__line__ ";save reverse-selection: ~A?" v0)) (if (not (= (mus-sound-header-type "fmv4.snd") mus-riff)) (snd-display #__line__ ";save-selection type 1: ~A?" (mus-header-type-name (mus-sound-header-type "fmv4.snd")))) (if (not (= (mus-sound-sample-type "fmv4.snd") mus-lfloat)) (snd-display #__line__ ";save-selection format 1: ~A?" (mus-sample-type-name (mus-sound-sample-type "fmv4.snd")))) (if (not (= (mus-sound-srate "fmv4.snd") 44100)) (snd-display #__line__ ";save-selection srate 1: ~A?" (mus-sound-srate "fmv4.snd"))) (if (not (string=? (mus-sound-comment "fmv4.snd") "this is a comment")) (snd-display #__line__ ";save-selection comment: ~A?" (mus-sound-comment "fmv4.snd"))) (delete-file "fmv4.snd") (save-selection :file "fmv4.snd" :header-type mus-riff :sample-type mus-lfloat :srate 44100 :comment "this is a comment") (if (not (= (mus-sound-header-type "fmv4.snd") mus-riff)) (snd-display #__line__ ";save-selection opt type 1: ~A?" (mus-header-type-name (mus-sound-header-type "fmv4.snd")))) (if (not (= (mus-sound-sample-type "fmv4.snd") mus-lfloat)) (snd-display #__line__ ";save-selection opt format 1: ~A?" (mus-sample-type-name (mus-sound-sample-type "fmv4.snd")))) (if (not (= (mus-sound-srate "fmv4.snd") 44100)) (snd-display #__line__ ";save-selection opt srate 1: ~A?" (mus-sound-srate "fmv4.snd"))) (if (not (string=? (mus-sound-comment "fmv4.snd") "this is a comment")) (snd-display #__line__ ";save-selection opt comment: ~A?" (mus-sound-comment "fmv4.snd"))) (delete-file "fmv4.snd") (save-selection :file "fmv4.snd" :sample-type mus-bfloat :channel 0) (if (and (not (= (mus-sound-header-type "fmv4.snd") mus-next)) (not (= (mus-sound-header-type "fmv4.snd") mus-ircam))) (snd-display #__line__ ";save-selection opt1 type 1: ~A?" (mus-header-type-name (mus-sound-header-type "fmv4.snd")))) (if (not (= (mus-sound-sample-type "fmv4.snd") mus-bfloat)) (snd-display #__line__ ";save-selection opt1 format 1: ~A?" (mus-sample-type-name (mus-sound-sample-type "fmv4.snd")))) (if (not (= (mus-sound-chans "fmv4.snd") 1)) (snd-display #__line__ ";save-selection opt1 chans: ~A?" (mus-sound-chans "fmv4.snd"))) (delete-file "fmv4.snd") (revert-sound index) (fill! v0 0.0) (set! (v0 2) 1.0) (let ((v1 (make-float-vector 256))) (copy v0 v1 0 128) (float-vector->channel v1 0 128 index 0)) (select-all) (if (mus-clipping) (set! (mus-clipping) #f)) (if *clipping* (set! *clipping* #f)) (convolve-selection-with "fmv5.snd" .5) (set! v0 (channel->float-vector 0 128 index 0)) (if (fneq (sample 66) -.5) (snd-display #__line__ ";convolve-selection-with: ~A ~A ~A?" (v0 66) (sample 66) v0)) (close-sound index)) (let* ((obind (open-sound "oboe.snd")) (vol (maxamp obind)) (dur (framples))) (when with-gui (set! (amp-control obind) 2.0) (if (fffneq (amp-control obind) 2.0) (snd-display #__line__ ";set amp-control ~A" (amp-control obind))) (reset-controls obind) (if (ffneq (amp-control obind) 1.0) (snd-display #__line__ ";reset amp-control ~A" (amp-control obind))) (set! (amp-control-bounds obind) (list 0.0 4.0)) (if (not (equal? (amp-control-bounds obind) (list 0.0 4.0))) (snd-display #__line__ ";amp-control-bounds: ~A" (amp-control-bounds))) (set! (amp-control obind) 2.0) (if (eq? (without-errors (apply-controls obind)) 'no-such-sound) (snd-display #__line__ ";apply-controls can't find oboe.snd?")) (let ((newamp (maxamp obind))) (if (> (abs (- (* 2.0 vol) newamp)) .05) (snd-display #__line__ ";apply amp: ~A -> ~A?" vol newamp)) (set! (amp-control-bounds obind) (list 0.0 8.0)) (set! (speed-control-bounds obind) (list 1.0 5.0)) (if (not (equal? (speed-control-bounds obind) (list 1.0 5.0))) (snd-display #__line__ ";speed-control-bounds: ~A" (speed-control-bounds))) (set! (speed-control obind) 0.5) (set! (speed-control-bounds obind) (list .05 20.0)) (add-mark 1234) (apply-controls obind) (let ((newdur (framples obind))) (set! (speed-control obind) 1.0) (if (>= (- newdur (* 2.0 dur)) 256) (snd-display #__line__ ";apply speed: ~A -> ~A?" dur newdur)) ;; within 256 which is apply's buffer size (it always flushes full buffers) (set! (contrast-control? obind) #t) (set! (contrast-control-bounds obind) (list 0.5 2.5)) (if (not (equal? (contrast-control-bounds obind) (list 0.5 2.5))) (snd-display #__line__ ";contrast-control-bounds: ~A" (contrast-control-bounds))) (set! (contrast-control obind) 1.0) (apply-controls obind) (set! (contrast-control-bounds obind) (list 0.0 10.0)) (if (not (equal? (contrast-control-bounds obind) (list 0.0 10.0))) (snd-display #__line__ ";contrast-control-bounds (2): ~A" (contrast-control-bounds))) (let ((secamp (maxamp obind)) (secdur (framples obind))) (if (fneq secamp .989) (snd-display #__line__ ";apply contrast: ~A?" secamp)) (if (not (= secdur newdur)) (snd-display #__line__ ";apply contrast length: ~A -> ~A?" newdur secdur))) (undo 3 obind) (set! (reverb-control? obind) #t) (set! (reverb-control-scale-bounds obind) (list 0.0 1.0)) (if (not (equal? (reverb-control-scale-bounds obind) (list 0.0 1.0))) (snd-display #__line__ ";reverb-control-scale-bounds: ~A" (reverb-control-scale-bounds))) (set! (reverb-control-length-bounds obind) (list 0.0 2.0)) (if (not (equal? (reverb-control-length-bounds obind) (list 0.0 2.0))) (snd-display #__line__ ";reverb-control-length-bounds: ~A" (reverb-control-length-bounds))) (set! (reverb-control-scale obind) .2) (let ((nowamp (maxamp obind))) (apply-controls obind) (let ((revamp (maxamp obind)) (revdur (framples obind))) (if (ffneq revamp .214) (snd-display #__line__ ";apply reverb scale: ~A at ~A, scale: ~A previous max: ~A?" revamp (maxamp-position obind) (reverb-control-scale obind) nowamp)) (if (>= (- revdur (+ 50828 (round (* *reverb-control-decay* 22050)))) 256) (snd-display #__line__ ";apply reverb length: ~A?" revdur)))) (undo 1 obind) (set! (expand-control? obind) #t) (set! (expand-control-bounds obind) (list 1.0 3.0)) (if (not (equal? (expand-control-bounds obind) (list 1.0 3.0))) (snd-display #__line__ ";expand-control-bounds: ~A" (expand-control-bounds))) (set! (expand-control obind) 1.5) (apply-controls obind) (let ((expamp (maxamp obind)) (expdur (framples obind))) (if (> (abs (- expamp .152)) .05) (snd-display #__line__ ";apply expand-control scale: ~A?" expamp)) (if (<= expdur (* 1.25 50828)) (snd-display #__line__ ";apply expand-control length: ~A?" expdur)) (set! (expand-control-bounds obind) (list 0.001 20.0))) (undo 1 obind) (set! (filter-control? obind) #t) (set! (filter-control-order obind) 40) (set! (filter-control-envelope obind) '(0 0 1 .5 2 0)) (apply-controls obind) (let ((fltamp (maxamp obind)) (fltdur (framples obind))) (if (> (abs (- fltamp .02)) .005) (snd-display #__line__ ";apply filter scale: ~A?" fltamp)) (if (> (- fltdur (+ 40 50828)) 256) (snd-display #__line__ ";apply filter length: ~A?" fltdur)) (undo 1 obind))))) (revert-sound obind) (make-selection 1000 1000) (scale-selection-to .1) (scale-selection-by 2.0) (make-selection 2000 2001) (scale-selection-by 2.0) (scale-selection-to .5) (make-selection 1000 2001) (scale-selection-to .5) (scale-selection-by .5) (make-selection 2000 2000) (scale-selection-by 2.0) (scale-selection-to .5) (make-selection 1000 1001) (scale-selection-to .1) (scale-selection-by 2.0) (make-selection 999 2002) (scale-selection-to 1.0) (scale-selection-by .5) (let ((tree (edit-tree)) (true-tree '((0 0 0 998 1.0 0.0 0.0 0) (999 0 999 999 0.999969720840454 0.0 0.0 0) (1000 0 1000 1000 6.09052181243896 0.0 0.0 0) (1001 0 1001 1001 0.999969720840454 0.0 0.0 0) (1002 0 1002 1999 0.499984979629517 0.0 0.0 0) (2000 0 2000 2000 7.54652404785156 0.0 0.0 0) (2001 0 2001 2001 3.7732629776001 0.0 0.0 0) (2002 0 2002 2002 0.999969720840454 0.0 0.0 0) (2003 0 2003 50827 1.0 0.0 0.0 0) (50828 -2 0 0 0.0 0.0 0.0 0)))) (if (not (= (length tree) (length true-tree))) (snd-display #__line__ ";edit trees are not same length: ~A ~A?" (length tree) (length true-tree)) (let ((len (length tree))) (do ((i 0 (+ i 1))) ((= i len)) (let ((branch (tree i)) (true-branch (true-tree i))) (if (or (not (= (car branch) (car true-branch))) (not (= (cadr branch) (cadr true-branch))) (not (= (caddr branch) (caddr true-branch))) (not (= (cadddr branch) (cadddr true-branch))) (fneq (branch 4) (true-branch 4))) (snd-display #__line__ ";edit trees disagree at ~D: ~A ~A" i branch true-branch))))))) (insert-silence 1001 8) (insert-silence 900 50) (insert-silence 2005 1) (insert-silence 999 2) (let ((tree (edit-tree)) (true-tree '((0 0 0 899 1.0 0.0 0.0 0) (900 -1 0 49 0.0 0.0 0.0 0) (950 0 900 948 1.0 0.0 0.0 0) (999 -1 0 1 0.0 0.0 0.0 0) (1001 0 949 998 1.0 0.0 0.0 0) (1051 0 999 999 0.999969720840454 0.0 0.0 0) (1052 0 1000 1000 6.09052181243896 0.0 0.0 0) (1053 -1 0 7 0.0 0.0 0.0 0) (1061 0 1001 1001 0.999969720840454 0.0 0.0 0) (1062 0 1002 1946 0.499984979629517 0.0 0.0 0) (2007 -1 0 0 0.0 0.0 0.0 0) (2008 0 1947 1999 0.499984979629517 0.0 0.0 0) (2061 0 2000 2000 7.54652404785156 0.0 0.0 0) (2062 0 2001 2001 3.7732629776001 0.0 0.0 0) (2063 0 2002 2002 0.999969720840454 0.0 0.0 0) (2064 0 2003 50827 1.0 0.0 0.0 0) (50889 -2 0 0 0.0 0.0 0.0 0)))) (if (not (= (length tree) (length true-tree))) (snd-display #__line__ ";silenced edit trees are not same length: ~A ~A?" (length tree) (length true-tree)) (let ((len (length tree))) (do ((i 0 (+ i 1))) ((= i len)) (let ((branch (tree i)) (true-branch (true-tree i))) (if (or (not (= (car branch) (car true-branch))) (not (= (cadr branch) (cadr true-branch))) (not (= (caddr branch) (caddr true-branch))) (not (= (cadddr branch) (cadddr true-branch))) (fneq (branch 4) (true-branch 4))) (snd-display #__line__ ";silenced edit trees disagree at ~D: ~A ~A" i branch true-branch))))))) (if (or (fneq (sample 998) -.03) (fneq (sample 999) 0.0) (fneq (sample 1000) 0.0) (fneq (sample 1001) -.03)) (snd-display #__line__ ";insert-silence [999 for 2]: ~A ~A ~A ~A?" (sample 998) (sample 999) (sample 1000) (sample 1001) )) (if (or (fneq (sample 2006) -.033) (fneq (sample 2007) 0.0) (fneq (sample 2008) -.033)) (snd-display #__line__ ";insert-silence [2007 for 1]: ~A ~A ~A?" (sample 2006) (sample 2007) (sample 2008))) (revert-sound obind) (add-mark 1200 obind 0) (let ((mark-num (length (marks obind 0)))) (scale-by 2.0 obind 0) (let ((mark-now (length (marks obind 0)))) (if (not (= mark-num mark-now)) (snd-display #__line__ ";mark lost after scaling?")) (set! (selection-position) 0) (set! (selection-framples) 100) (scale-selection-to .5) (set! mark-now (length (marks obind 0))) (if (not (= mark-num mark-now)) (snd-display #__line__ ";mark lost after selection scaling?"))) (let ((m1 (add-mark 1000))) (set! (cursor obind 0) 100) (key (char->integer #\u) 4 obind) (key (char->integer #\1) 0 obind) (key (char->integer #\0) 0 obind) (key (char->integer #\0) 0 obind) (key (char->integer #\o) 4 obind) (if (not (= (mark-sample m1) 1100)) (snd-display #__line__ ";mark after zeros: ~D (1100)? " (mark-sample m1))) (set! (cursor obind) 0) (key (char->integer #\j) 4 obind) (if (not (= (cursor obind) 1100)) (snd-display #__line__ ";c-j to ~A" (cursor obind))) (add-mark 100) (set! (cursor obind) 0) (key (char->integer #\u) 4 obind) (key (char->integer #\2) 0 obind) (key (char->integer #\j) 4 obind) (if (not (= (cursor obind) 1100)) (snd-display #__line__ ";c-u 2 c-j ~A" (cursor obind))) (key (char->integer #\-) 4 obind) (key (char->integer #\j) 4 obind) (if (not (= (cursor obind) 100)) (snd-display #__line__ ";c-- c-j ~A" (cursor obind))))) (revert-sound obind) (let ((frs (framples obind))) (make-region 0 999 obind 0) (if (not (selection?)) (snd-display #__line__ ";make-region but no selection? ~A" (selection?))) (delete-selection) (if (not (= (framples obind) (- frs 1000))) (snd-display #__line__ ";delete-selection: ~A?" (framples obind))) (let ((val (sample 0 obind 0))) (undo) (if (fneq (sample 1000) val) (snd-display #__line__ ";delete-selection val: ~A ~A" val (sample 1000))) (insert-selection) (let ((var (catch #t (lambda () (insert-selection 0 obind 123)) (lambda args args)))) (if (not (eq? (car var) 'no-such-channel)) (snd-display #__line__ ";insert-selection bad chan: ~A" var))) (let ((var (catch #t (lambda () (mix-selection 0 obind 123)) (lambda args args)))) (if (not (eq? (car var) 'no-such-channel)) (snd-display #__line__ ";mix-selection bad chan: ~A" var))) (if (not (= (framples obind) (+ frs 1000))) (snd-display #__line__ ";insert-selection: ~A?" (framples obind))) (if (fneq (sample 2000) val) (snd-display #__line__ ";insert-selection val: ~A ~A" val (sample 2000))) (set! val (sample 900)) (mix-selection) (if (fneq (sample 900) (* 2 val)) (snd-display #__line__ ";mix-selection val: ~A ~A" (* 2 val) (sample 900))) (if (not (= (framples obind) (+ frs 1000))) (snd-display #__line__ ";mix-selection len: ~A?" (framples obind))))) (close-sound obind)) (let* ((ind (open-sound "2.snd")) (apply-to-sound 0) (apply-to-channel 1) (apply-to-selection 2) (len (framples ind))) (set! (sync ind) 1) (set! (speed-control ind) .5) (apply-controls ind apply-to-sound) ; temp 1 (if (> (abs (- (framples) (* 2 len))) 256) (snd-display #__line__ ";apply srate .5: ~A ~A" (framples) (* 2 len))) (make-selection 0 (framples)) (set! (speed-control ind) .5) (apply-controls ind apply-to-selection) ; temp 2 (if (> (abs (- (framples) (* 4 len))) 256) (snd-display #__line__ ";apply srate .5 to selection: ~A ~A" (framples) (* 4 len))) (env-sound '(0 0 1 1) 0 (framples) 32.0) ; temp 3 (let ((reg (select-all))) ; make multi-channel region (insert-region reg 0) ; temp 4 (insert-selection 0)) ; temp 5 (revert-sound ind) (set! (speed-control) .5) (set! (sync ind) 0) (set! (selected-channel ind) 1) (apply-controls ind apply-to-channel) (if (> (abs (- (framples ind 1) (* 2 len))) 256) (snd-display #__line__ ";apply srate .5 to chan 1: ~A ~A" (framples ind 1) (* 2 len))) (if (not (= (framples ind 0) len)) (snd-display #__line__ ";apply srate .5 but chan 0: ~A ~A" (framples ind 0) len)) (set! (speed-control ind) .5) (apply-controls ind apply-to-sound 1000) (make-selection 2000 4000) (set! (speed-control ind) .5) (apply-controls ind apply-to-selection) (set! (selected-channel ind) #f) (if (selected-channel ind) (snd-display #__line__ ";selected-channel #f: ~A" (selected-channel ind))) (close-sound ind)) (let* ((ind1 (open-sound "oboe.snd")) (mx1 (maxamp ind1 0)) (ind2 (open-sound "2.snd")) (mx20 (maxamp ind2 0)) (mx21 (maxamp ind2 1))) (select-sound ind1) (scale-sound-by 2.0) (let ((nmx (maxamp ind1 0))) (if (fneq (* 2 mx1) nmx) (snd-display #__line__ ";scale-sound-by 2.0: ~A ~A?" mx1 nmx)) (if (not (equal? (edit-fragment 1 ind1 0) (list "scale-channel 2.000 0 #f" "scale" 0 50828))) (snd-display #__line__ ";scale-sound-by: ~A?" (edit-fragment 1 ind1 0)))) (scale-sound-to 0.5) (let ((nmx (maxamp ind1 0))) (if (fneq nmx 0.5) (snd-display #__line__ ";scale-sound-to 0.5: ~A?" nmx)) (if (not (equal? (edit-fragment 2 ind1 0) (list "scale-channel 1.698 0 #f" "scale" 0 50828))) (snd-display #__line__ ";scale-sound-to: ~A?" (edit-fragment 2 ind1 0)))) (scale-sound-by 0.0 0 1000 ind1 0) (let ((nmx (maxamp ind1 0))) (if (fneq 0.5 nmx) (snd-display #__line__ ";scale-sound-by 0.0: ~A ~A?" mx1 nmx)) (if (not (equal? (edit-fragment 3 ind1 0) (list "scale-channel 0.000 0 1000" "scale" 0 1000))) (snd-display #__line__ ";scale-sound-by 0.0: ~A?" (edit-fragment 3 ind1 0)))) (let* ((v (channel->float-vector 0 1000 ind1 0)) (pk (float-vector-peak v))) (if (fneq pk 0.0) (snd-display #__line__ ";scale-sound-by 0.0 [0:1000]: ~A?" pk))) (revert-sound ind1) (let ((oldv (channel->float-vector 12000 10 ind1 0))) (scale-sound-by 2.0 12000 10 ind1 0) (let ((newv (channel->float-vector 12000 10 ind1 0))) (do ((i 0 (+ i 1))) ((= i 10)) (if (fneq (* 2.0 (oldv i)) (newv i)) (snd-display #__line__ ";scale ~D: ~A ~A?" i (oldv i) (newv i))))) (if (not (equal? (edit-fragment 1 ind1 0) (list "scale-channel 2.000 12000 10" "scale" 12000 10))) (snd-display #__line__ ";scale-sound-by 2.0 [12000:10]: ~A?" (edit-fragment 1 ind1 0)))) (revert-sound ind1) (select-sound ind2) (scale-sound-by 2.0) (let ((nmx (maxamp ind2 0))) (if (fneq (* 2 mx20) nmx) (snd-display #__line__ ";2:0 scale-sound-by 2.0: ~A ~A?" mx20 nmx))) (let ((nmx (maxamp ind2 1))) (if (fneq (* 2 mx21) nmx) (snd-display #__line__ ";2:1 scale-sound-by 2.0: ~A ~A?" mx21 nmx))) (scale-sound-to 0.5) (let ((nmx (max (maxamp ind2 0) (maxamp ind2 1)))) (if (fneq nmx 0.5) (snd-display #__line__ ";2 scale-sound-to 0.5: ~A (~A)?" nmx (maxamp ind2)))) (scale-sound-by 0.0 0 1000 ind2 1) (if (not (equal? (edit-fragment 3 ind2 1) (list "scale-channel 0.000 0 1000" "scale" 0 1000))) (snd-display #__line__ ";2:1 scale-sound-by 0.0: ~A?" (edit-fragment 3 ind2 1))) (let* ((v (channel->float-vector 0 1000 ind2 1)) (pk (float-vector-peak v))) (if (fneq pk 0.0) (snd-display #__line__ ";2:1 scale-sound-by 0.0 [0:1000]: ~A?" pk))) (revert-sound ind2) (let ((oldv (channel->float-vector 12000 10 ind2 0))) (scale-sound-by 2.0 12000 10 ind2 0) (let ((newv (channel->float-vector 12000 10 ind2 0))) (do ((i 0 (+ i 1))) ((= i 10)) (if (fneq (* 2.0 (oldv i)) (newv i)) (snd-display #__line__ ";2 scale ~D: ~A ~A?" i (oldv i) (newv i)))))) (revert-sound ind2) (set! (sync ind2) 3) (set! (sync ind1) 3) (scale-sound-by 2.0) (let ((nmx (maxamp ind1 0))) (if (fneq mx1 nmx) (snd-display #__line__ ";sync scale-sound-by 2.0: ~A ~A?" mx1 nmx))) (let ((nmx (maxamp ind2 0))) (if (fneq (* 2 mx20) nmx) (snd-display #__line__ ";2:0 sync scale-sound-by 2.0: ~A ~A?" mx20 nmx))) (let ((nmx (maxamp ind2 1))) (if (fneq (* 2 mx21) nmx) (snd-display #__line__ ";2:1 sync scale-sound-by 2.0: ~A ~A?" mx21 nmx))) (scale-sound-to 1.0 20000 40000 ind2 1) (let ((nmx (maxamp ind1 0))) (if (fneq mx1 nmx) (snd-display #__line__ ";sync scale-sound-to 1.0: ~A ~A?" mx1 nmx))) (let ((nmx (maxamp ind2 0))) (if (fneq (* 2 mx20) nmx) (snd-display #__line__ ";2:0 sync scale-sound-to 1.0: ~A ~A?" mx20 nmx))) (let ((nmx (maxamp ind2 1))) (if (fneq nmx 1.0) (snd-display #__line__ ";2:1 sync scale-sound-to 1.0: ~A?" nmx))) (close-sound ind1) (close-sound ind2)) (let ((ind (open-sound "now.snd"))) (set! (amp-control ind) .5) (if (ffneq (amp-control ind) .5) (snd-display #__line__ ";amp-control (.5): ~A?" (amp-control ind))) (set! (amp-control ind 0) .25) (if (ffneq (amp-control ind) .5) (snd-display #__line__ ";amp-control after local set (.5): ~A?" (amp-control ind))) (if (ffneq (amp-control ind 0) .25) (snd-display #__line__ ";amp-control 0 (.25): ~A?" (amp-control ind 0))) (set! (amp-control ind) 1.0) (if (ffneq (amp-control ind) 1.0) (snd-display #__line__ ";amp-control (1.0): ~A?" (amp-control ind))) (if (ffneq (amp-control ind 0) .25) (snd-display #__line__ ";amp-control 0 after set (.25): ~A?" (amp-control ind 0))) (set! (transform-graph? ind 0) #t) (set! (transform-graph-type ind 0) graph-as-sonogram) (update-transform-graph ind 0) (when with-motif (let ((val (transform-framples ind 0))) (if (or (not (list? val)) (fneq (car val) 1.0) (not (= (caddr val) 256))) (snd-display #__line__ ";transform-framples: ~A (~A)" val (transform-size ind 0))))) (close-sound ind) (set! ind (open-sound "4.aiff")) (if (ffneq (amp-control ind) 1.0) (snd-display #__line__ ";amp-control upon open (1.0): ~A?" (amp-control ind))) (if (ffneq (amp-control ind 2) 1.0) (snd-display #__line__ ";amp-control 2 upon open (1.0): ~A?" (amp-control ind 2))) (set! (amp-control ind) .5) (if (ffneq (amp-control ind 2) .5) (snd-display #__line__ ";amp-control 2 after global set (.5): ~A?" (amp-control ind 2))) (set! (amp-control ind 2) .25) (if (ffneq (amp-control ind 2) .25) (snd-display #__line__ ";amp-control 2 (.25): ~A?" (amp-control ind 2))) (if (ffneq (amp-control ind 1) .5) (snd-display #__line__ ";amp-control 1 after local set (.5): ~A?" (amp-control ind 1))) (let ((after-ran #f)) (set! (hook-functions after-apply-controls-hook) ()) (hook-push after-apply-controls-hook (lambda (hook) (set! after-ran (hook 'snd)))) (apply-controls ind) (if (not (equal? ind after-ran)) (snd-display #__line__ ";after-apply-controls-hook: ~A?" after-ran)) (set! (hook-functions after-apply-controls-hook) ())) (revert-sound ind) (set! (sync ind) 1) (scale-to (float-vector .1 .2)) (let ((mx (maxamp ind #t))) (if (or (fneq (mx 0) .1) (fneq (mx 1) .2) (fneq (mx 2) .2) (fneq (mx 3) .2)) (snd-display #__line__ ";scale to with vector: ~A" mx))) (set! (filter-control-envelope ind) '(0 0 1 1)) (if (not (feql '(0.0 0.0 1.0 1.0) (filter-control-envelope ind))) (snd-display #__line__ ";set filter-control-envelope: ~A?" (filter-control-envelope ind))) (set! (filter-control-order ind) 20) (if (not (vequal (filter-control-coeffs ind) (float-vector -0.007 0.010 -0.025 0.029 -0.050 0.055 -0.096 0.109 -0.268 0.241 0.241 -0.268 0.109 -0.096 0.055 -0.050 0.029 -0.025 0.010 -0.007))) (snd-display #__line__ ";highpass coeffs: ~A" (filter-control-coeffs ind))) (set! (filter-control-envelope ind) '(0 1 1 0)) (if (not (vequal (filter-control-coeffs ind) (float-vector 0.003 0.002 0.004 0.002 0.007 0.003 0.014 0.012 0.059 0.394 0.394 0.059 0.012 0.014 0.003 0.007 0.002 0.004 0.002 0.003))) (snd-display #__line__ ";lowpass coeffs: ~A" (filter-control-coeffs ind))) (close-sound ind)) (let* ((obind (open-sound "4.aiff")) (amps (maxamp obind #t)) (times (maxamp-position obind #t))) (if (not (equal? times (list 810071 810071 810071 810071))) (snd-display #__line__ ";4.aiff times: ~A" times)) (if (< (window-width) 600) (set! (window-width) 600)) (if (< (window-height) 600) (set! (window-height) 600)) (set! (x-bounds obind 0) (list 0.0 0.1)) (set! (show-axes obind 0) show-x-axis) (update-time-graph) (set! (amp-control obind) 0.1) (select-channel 2) (if (eq? (without-errors (apply-controls obind 1)) 'no-such-sound) (snd-display #__line__ ";apply-controls can't find 4.aiff?")) (let ((newamps (maxamp obind #t))) (if (or (fneq (car amps) (car newamps)) (fneq (cadr amps) (cadr newamps)) (> (abs (- (* 0.1 (caddr amps)) (caddr newamps))) .05) (fneq (cadddr amps) (cadddr newamps))) (snd-display #__line__ ";apply amps:~% ~A ->~% ~A?" amps newamps)) (undo 1 obind 2) (set! (amp-control obind) 0.1) (make-region 0 (framples obind) obind 1) (without-errors (apply-controls obind 2)) (set! newamps (maxamp obind #t)) (if (or (fneq (car amps) (car newamps)) (> (abs (- (* 0.1 (cadr amps)) (cadr newamps))) .05) (fneq (caddr amps) (caddr newamps)) (fneq (cadddr amps) (cadddr newamps))) (snd-display #__line__ ";apply selection amp:~% ~A ->~% ~A?" amps newamps)) (if with-gui (let* ((axinfo (axis-info obind 0 time-graph)) (losamp (car axinfo)) (hisamp (cadr axinfo)) (x0 (axinfo 2)) (y0 (axinfo 3)) (x1 (axinfo 4)) (y1 (axinfo 5)) (xpos (+ x0 (* .5 (- x1 x0)))) (ypos (+ y0 (* .75 (- y1 y0))))) (define (cp-x x) (floor (+ (axinfo 10) (* (- x x0) (/ (- (axinfo 12) (axinfo 10)) (- x1 x0)))))) (define (cp-y y) (floor (+ (axinfo 13) (* (- y1 y) (/ (- (axinfo 11) (axinfo 13)) (- y1 y0)))))) (select-channel 0) (set! (cursor obind) 100) (let ((xy (cursor-position obind))) (if (fneq (position->x (car xy)) (/ (cursor obind) (srate obind))) (snd-display #__line__ ";cursor-position: ~A ~A ~A?" (car xy) (position->x (car xy)) (/ (cursor obind) (srate obind))))) (if (fneq (position->x (x->position xpos)) xpos) (snd-display #__line__ ";x<->position: ~A ~A?" (position->x (x->position xpos)) xpos)) (if (> (abs (- (position->y (y->position ypos)) ypos)) .5) (snd-display #__line__ ";y<->position: ~A ~A?" (position->y (y->position ypos)) ypos)) (if (not (= losamp (left-sample obind 0))) (snd-display #__line__ ";axis-info[0 losamp]: ~A ~A?" losamp (left-sample obind 0))) (if (not (= hisamp (right-sample obind 0))) (snd-display #__line__ ";axis-info[1 hisamp]: ~A ~A?" hisamp (right-sample obind 0))) (if (fneq (axinfo 6) 0.0) (snd-display #__line__ ";axis-info[6 xmin]: ~A?" (axinfo 6))) (if (fneq (axinfo 7) -1.0) (snd-display #__line__ ";axis-info[7 ymin]: ~A?" (axinfo 7))) (if (fneq (axinfo 9) 1.0) (snd-display #__line__ ";axis-info[9 ymax]: ~A?" (axinfo 9))) (if (> (abs (apply - (our-x->position obind x0))) 1) (snd-display #__line__ ";x0->position: ~A?" (our-x->position obind x0))) (if (> (abs (apply - (our-x->position obind x1))) 1) (snd-display #__line__ ";x1->position: ~A?" (our-x->position obind x1))) (if (> (abs (apply - (our-x->position obind (* 0.5 (+ x0 x1))))) 1) (snd-display #__line__ ";xmid->position: ~A?" (our-x->position obind (* 0.5 (+ x0 x1))))) (if (not full-test) (begin (if (> (abs (- (x->position xpos) (cp-x xpos))) 1) (snd-display #__line__ ";cp-x .5: ~A ~A?" (x->position xpos) (cp-x xpos))) (if (> (abs (- (y->position ypos) (cp-y ypos))) 1) (snd-display #__line__ ";cp-y .75: ~A ~A?" (y->position ypos) (cp-y ypos))) (do ((i 0 (+ i 1))) ((= i 10)) (let ((xpos (+ x0 (random (- x1 x0)))) (ypos (+ y0 (random (- y1 y0))))) (if (> (abs (- (x->position xpos) (cp-x xpos))) 1) (snd-display #__line__ ";cp-x[~A] ~A: ~A ~A?" i xpos (x->position xpos) (cp-x xpos))) (if (> (abs (- (y->position ypos) (cp-y ypos))) 1) (snd-display #__line__ ";cp-y[~A] ~A: ~A ~A?" i ypos (y->position ypos) (cp-y ypos))) (if (fneq (position->x (cp-x xpos)) xpos) (snd-display #__line__ ";x->position cp-x ~A ~A" xpos (position->x (cp-x xpos)))) (if (fffneq (position->y (cp-y ypos)) ypos) (snd-display #__line__ ";y->position cp-y ~A ~A" ypos (position->y (cp-y ypos)))))))) (set! (left-sample obind 0) 1234) (if (not (= 1234 (car (axis-info obind 0)))) (snd-display #__line__ ";axis-info[0 losamp at 1234]: ~A ~A?" (car (axis-info obind 0)) (left-sample obind 0))) (set! axinfo (axis-info obind 0)) (set! x0 (axinfo 2)) (set! x1 (axinfo 4)) (if (> (abs (apply - (our-x->position obind x0))) 1) (snd-display #__line__ ";x0a->position: ~A?" (our-x->position obind x0))) (if (> (abs (apply - (our-x->position obind x1))) 1) (snd-display #__line__ ";x1a->position: ~A?" (our-x->position obind x1))) (if (> (abs (apply - (our-x->position obind (* 0.5 (+ x0 x1))))) 1) (snd-display #__line__ ";xmida->position: ~A?" (our-x->position obind (* 0.5 (+ x0 x1))))) (set! (y-bounds obind 0) (list -2.0 3.0)) (if (fneq ((axis-info obind 0) 7) -2.0) (snd-display #__line__ ";axis-info[7 ymin -2.0]: ~A?" ((axis-info obind 0) 7))) (if (fneq ((axis-info obind 0) 9) 3.0) (snd-display #__line__ ";axis-info[9 ymax 3.0]: ~A?" ((axis-info obind 0) 9))) )) (close-sound obind))) (let ((ind1 (open-sound "oboe.snd"))) (test-orig (lambda (snd) (src-sound 2.0 1.0 ind1)) (lambda (snd) (src-sound 0.5 1.0 ind1)) 'src-sound ind1) (test-orig (lambda (snd) (src-channel 2.0)) (lambda (snd) (src-channel 0.5)) 'src-channel ind1) (test-orig (lambda (snd) (scale-by 2.0 ind1)) (lambda (snd) (scale-by 0.5 ind1)) 'scale-by ind1) (test-orig (lambda (snd) (scale-channel 2.0)) (lambda (snd) (scale-channel 0.5)) 'scale-channel ind1) (test-orig (lambda (snd) (reverse-sound ind1)) (lambda (snd) (reverse-sound ind1)) 'reverse-sound ind1) (test-orig (lambda (snd) (reverse-channel)) (lambda (snd) (reverse-channel)) 'reverse-channel ind1) (test-orig (lambda (snd) (env-sound '(0 1.0 1 2.0))) (lambda (snd) (env-sound '(0 1.0 1 0.5))) 'env-sound ind1) (test-orig (lambda (snd) (env-sound '(0 1.0 1 2.0 2 1.0))) (lambda (snd) (env-sound '(0 1.0 1 0.5 2 1.0))) 'env-sound ind1) (test-orig (lambda (snd) (env-channel (make-env :envelope '(0 1.0 1 2.0) :length (framples)))) (lambda (snd) (env-channel (make-env :envelope '((0 1.0) (1 0.5)) :length (framples)))) 'env-channel ind1) (test-orig (lambda (snd) (env-channel '(0 1.0 1 2.0))) (lambda (snd) (env-channel '(0 1.0 1 0.5))) 'env-channel ind1) (test-orig (lambda (snd) (env-channel (make-env :envelope '(0 2 1 2 2 0.5 3 0.5) :base 0 :length (framples)))) (lambda (snd) (env-channel (make-env :envelope '(0 0.5 1 0.5 2 2 3 2) :base 0 :length (framples)))) 'env-channel ind1) (test-orig (lambda (snd) (map-channel (lambda (n) (* n 2.0)))) (lambda (snd) (map-channel (lambda (n) (* n 0.5)))) 'map-channel ind1) (test-orig (lambda (snd) (map-channel (lambda (n) (* n 2.0)) 1234)) (lambda (snd) (map-channel (lambda (n) (* n 0.5)) 1234)) 'map-channel ind1) (test-orig (lambda (snd) (map-channel (lambda (n) (* n 2.0)) 12005 10)) (lambda (snd) (map-channel (lambda (n) (* n 0.5)) 12005 10)) 'map-channel ind1) (test-orig (lambda (snd) (define m1 (let ((vect (make-float-vector 2 0.0))) (lambda (y) (float-vector-set! vect 0 (float-vector-set! vect 1 (* y 2))) vect))) (map-channel m1)) (lambda (snd) (define m2 (let ((outp #f)) (lambda (y) (and (set! outp (not outp)) (* y 0.5))))) (map-channel m2)) 'map-channel ind1) (test-orig (lambda (snd) (map-channel (lambda (n) (* n 2.0)))) (lambda (snd) (map-channel (lambda (n) (* n 0.5)))) 'map-channel ind1) (test-orig (lambda (snd) (pad-channel 1000 2000 ind1)) (lambda (snd) (delete-samples 1000 2000 ind1)) 'pad-channel ind1) (test-orig (lambda (snd) (clm-channel (make-one-zero :a0 2.0 :a1 0.0))) (lambda (snd) (clm-channel (make-one-zero :a0 0.5 :a1 0.0))) 'clm-channel ind1) (test-orig (lambda (snd) (clm-channel (make-one-pole :a0 2.0 :b1 0.0))) (lambda (snd) (clm-channel (make-one-pole :a0 0.5 :b1 0.0))) 'clm-channel ind1) (test-orig (lambda (snd) (filter-sound (make-one-zero :a0 2.0 :a1 0.0) 2 ind1 0)) (lambda (snd) (filter-sound (make-one-zero :a0 0.5 :a1 0.0) 2 ind1 0)) 'filter-sound ind1) (let ((var (catch #t (lambda () (src-sound '(0 0 1 1))) (lambda args args)))) (if (not (eq? (car var) 'out-of-range)) (snd-display #__line__ ";src-sound env at 0: ~A" var))) (let ((var (catch #t (lambda () (src-sound '(0 1 1 -1))) (lambda args args)))) (if (not (eq? (car var) 'out-of-range)) (snd-display #__line__ ";src-sound env through 0: ~A" var))) (scale-to 1.0 ind1) (let ((v0 (make-float-vector 10)) (v1 (channel->float-vector 12000 10 ind1 0))) (set! (v0 0) 1.0) (array->file "fmv3.snd" v0 10 22050 1) (copy-file "oboe.snd" "fmv4.snd") (convolve-with "fmv3.snd" 1.0 ind1) (convolve-files "fmv4.snd" "fmv3.snd" 1.0 "fmv5.snd") (let ((v2 (channel->float-vector 12000 10 ind1 0))) (if (not (vequal1 v1 v2)) (snd-display #__line__ ";~A (orig: 0) ~A ~A" 'convolve-with v1 v2)) (file->array "fmv5.snd" 0 12000 10 v2) (if (not (vequal1 v1 v2)) (snd-display #__line__ ";convolve-files: (orig: 0) ~A ~A" v1 v2))) (delete-file "fmv3.snd") (delete-file "fmv5.snd")) (convolve-files "2.snd" "oboe.snd" 0.5 "fmv5.snd") (if (or (fneq (cadr (mus-sound-maxamp "fmv5.snd")) 0.25) (fneq (cadddr (mus-sound-maxamp "fmv5.snd")) 0.5)) (snd-display #__line__ ";convolve-files stereo: ~A" (mus-sound-maxamp "fmv5.snd"))) (delete-file "fmv5.snd") (scale-to .25 ind1) (set! (y-bounds ind1) ()) (if (not (equal? (y-bounds ind1) (list -.25 .25))) (snd-display #__line__ ";y-bounds (): ~A?" (y-bounds ind1))) (revert-sound ind1) (scale-to 1.0 ind1) (let ((v0 (make-float-vector 10)) (v1 (channel->float-vector 12000 10 ind1 0))) (set! (v0 5) 1.0) (array->file "fmv3.snd" v0 10 22050 1) (convolve-with "fmv3.snd" 1.0 ind1) (convolve-files "fmv4.snd" "fmv3.snd" 1.0 "fmv5.snd") (let ((v2 (channel->float-vector 12005 10 ind1 0))) (if (not (vequal1 v1 v2)) (snd-display #__line__ ";~A (orig: 2) ~A ~A" 'convolve-with v1 v2)) (file->array "fmv5.snd" 0 12005 10 v2) (if (not (vequal1 v1 v2)) (snd-display #__line__ ";convolve-files: (orig: 2) ~A ~A" v1 v2))) (delete-file "fmv3.snd") (delete-file "fmv4.snd") (delete-file "fmv5.snd")) (revert-sound ind1) (let ((old-val *selection-creates-region*) (old-regions (regions))) (set! *selection-creates-region* #f) (select-all ind1) (set! *selection-creates-region* old-val) (if (not (equal? old-regions (regions))) (snd-display #__line__ ";selection-create-region: ~A -> ~A?" old-regions (regions)))) (convolve-selection-with "pistol.snd" (maxamp)) (let ((data (channel->float-vector 12000 10 ind1 0))) (convolve-with "pistol.snd" (maxamp ind1 0 0) ind1 0 0) (let ((new-data (channel->float-vector 12000 10 ind1 0))) (if (not (vequal1 data new-data)) (snd-display #__line__ ";convolve-selection-with: ~A ~A?" data new-data)))) (revert-sound ind1) (make-selection 1000 2000 ind1) (let ((ma (maxamp ind1))) (convolve-selection-with "pistol.snd" ma) (if (fneq (maxamp ind1) ma) (snd-display #__line__ ";convolve-selection-with 1000: ~A ~A?" ma (maxamp ind1)))) (make-selection 1000 2000 ind1) (let ((id (make-region))) (if (not (region? id)) (snd-display #__line__ ";make-region argless: ~A" id)) (if (not (= (region-framples id 0) (selection-framples))) (snd-display #__line__ ";region/selection-framples: ~A ~A (~A)?" (region-framples id 0) (selection-framples) (region-framples id))) (if (fneq (region-sample id 0) (sample 1000 ind1)) (snd-display #__line__ ";region-sample from make-region: ~A ~A?" (region-sample id 0) (sample 1000 ind1)))) (close-sound ind1)) (let* ((ind (open-sound "2.snd")) (reg (make-region 0 100 ind #t))) (if (not (equal? (region-home reg) (list "2.snd" 0 100))) (snd-display #__line__ ";make + region-home: ~A" (region-home reg))) (if (not (= (region-chans reg) 2)) (snd-display #__line__ ";make-region chan #t: ~A" (region-chans reg))) (close-sound ind)) (let ((ind1 (open-sound "2.snd"))) (let ((v0 (channel->float-vector 12000 10 ind1 0)) (v1 (channel->float-vector 12000 10 ind1 1))) (swap-channels ind1) (let ((v2 (channel->float-vector 12000 10 ind1 0)) (v3 (channel->float-vector 12000 10 ind1 1))) (if (or (vequal v0 v2) (vequal v1 v3)) (snd-display #__line__ ";swap-channels 0: no change! ~A ~A ~A ~A" v0 v2 v1 v3))) (swap-channels ind1) (let ((v2 (channel->float-vector 12000 10 ind1 0)) (v3 (channel->float-vector 12000 10 ind1 1))) (if (or (not (vequal v0 v2)) (not (vequal v1 v3))) (snd-display #__line__ ";swap-channels 1: ~A ~A ~A ~A" v0 v2 v1 v3))) ;; as long as we're here... (set! (sync ind1) 0) (set! (cursor ind1 0) 100) (set! (cursor ind1 1) 200) (if (or (not (= (cursor ind1 0) 100)) (not (= (cursor ind1 1) 200))) (snd-display #__line__ ";cursor: ~A ~A?" (cursor ind1 0) (cursor ind1 1))) (set! (sync ind1) 1) (scale-by (list .5 .25) ind1) (scale-by (float-vector 2.0 4.0) ind1) (revert-sound ind1) (let ((amps (maxamp ind1 #t))) (swap-channels ind1 0 ind1) (let ((newamps (maxamp ind1 #t))) (if (or (fneq (car amps) (cadr newamps)) (fneq (cadr amps) (car newamps))) (snd-display #__line__ ";swap-channels with cp def: ~A ~A" amps newamps))) (swap-channels ind1 1) (let ((newamps (maxamp ind1 #t))) (if (or (fneq (car amps) (car newamps)) (fneq (cadr amps) (cadr newamps))) (snd-display #__line__ ";swap-channels with cp def 0: ~A ~A" amps newamps)))) (close-sound ind1))) (let ((ind1 (open-sound "oboe.snd")) (ind2 (open-sound "2.snd"))) (let ((ups1 (count-matches (lambda (n) (> n .1)) 0 ind1 0)) (ups2 (let ((count 0) (len (framples ind1)) (reader (make-sampler 0 ind1))) (do ((i 0 (+ i 1))) ((= i len) count) (if (> (next-sample reader) .1) (set! count (+ count 1))))))) (if (not (= ups1 ups2)) (snd-display #__line__ ";scan-chan: ~A ~A?" ups1 ups2)) (set! ups1 (count-matches (lambda (n) (> n .03)) 0 ind2 0)) (set! ups2 (count-matches (lambda (n) (> n .03)) 0 ind2 1)) (let ((ups3 (let ((count 0) (len (framples ind2)) (reader (make-sampler 0 ind2 0))) (do ((i 0 (+ i 1))) ((= i len) count) (if (> (next-sample reader) .03) (set! count (+ count 1)))))) (ups4 (let ((count 0) (len (framples ind2)) (reader (make-sampler 0 ind2 1))) (do ((i 0 (+ i 1))) ((= i len) count) (if (> (next-sample reader) .03) (set! count (+ count 1))))))) (if (not (= ups1 ups3)) (snd-display #__line__ ";2[0] scan-chan: ~A ~A?" ups1 ups3)) (if (not (= ups2 ups4)) (snd-display #__line__ ";2[1] scan-chan: ~A ~A?" ups2 ups4)))) (close-sound ind1) (close-sound ind2)) (let* ((ind1 (open-sound "oboe.snd")) (len (framples ind1)) (ctr #f)) (map-channel (lambda (n) (and (set! ctr (not ctr)) (* n 2.0)))) (if (> (framples ind1) (+ (/ len 2) 1)) (snd-display #__line__ ";map-channel cut: ~A ~A?" len (framples ind1))) (revert-sound ind1) (set! ctr 0) (map-channel (lambda (n) (or (> (set! ctr (+ ctr 1)) 3) n))) (if (> ctr 4) (snd-display #__line__ ";map-channel no-edit count: ~A?" ctr)) (revert-sound ind1) (let ((v1 (make-float-vector 2))) (map-channel (lambda (n) (set! (v1 0) n) (set! (v1 1) (* n 3)) v1))) (if (> (abs (- (framples ind1) (* len 2))) 3) (snd-display #__line__ ";map-channel double: ~A ~A?" len (framples ind1))) (revert-sound ind1) (let ((otime (maxamp-position ind1))) (set! (sample 1234) .9) (let ((ntime (maxamp-position ind1)) (nval (maxamp ind1)) (npos (edit-position ind1 0))) (if (not (= ntime 1234)) (snd-display #__line__ ";maxamp-position 1234: ~A" ntime)) (let ((ootime (maxamp-position ind1 0 0))) (if (not (= ootime otime)) (snd-display #__line__ ";maxamp-position edpos 0: ~A ~A" otime ootime))) (let ((nntime (maxamp-position ind1 0 npos))) (if (not (= nntime ntime)) (snd-display #__line__ ";maxamp-position edpos ~D: ~A ~A" npos ntime nntime))) (if (fneq nval .9) (snd-display #__line__ ";maxamp .9: ~A" nval))) (set! (sample 1234) 0.0) (env-channel '(0 0 1 1)) (if (not (= (maxamp-position) 35062)) (snd-display #__line__ ";env-channel maxamp-position: ~A" (maxamp-position))) (let ((ootime (maxamp-position ind1 0 0))) (if (not (= ootime otime)) (snd-display #__line__ ";maxamp-position edpos 0(1): ~A ~A" otime ootime))) (let ((nntime (maxamp-position ind1 0 1))) (if (not (= nntime 1234)) (snd-display #__line__ ";maxamp-position edpos 1(1): ~A ~A" 1234 nntime))) (let ((nntime (maxamp-position ind1 0 current-edit-position))) (if (not (= nntime 35062)) (snd-display #__line__ ";maxamp-position edpos current: ~A ~A" 35062 nntime)))) (revert-sound ind1) (make-selection 24000 25000) (if (not (= (selection-maxamp-position) 971)) (snd-display #__line__ ";selection maxamp position: ~A" (selection-maxamp-position))) (let ((reg (make-region 24000 25000))) (if (not (= (region-maxamp-position reg) 971)) (snd-display #__line__ ";region maxamp position: ~A" (region-maxamp-position reg)))) (close-sound ind1)) (let ((ind1 (open-sound "oboe.snd"))) (test-edpos maxamp 'maxamp (lambda () (scale-by 2.0 ind1 0)) ind1) (test-edpos framples 'framples (lambda () (src-sound 2.0 1.0 ind1 0)) ind1) (test-edpos (lambda* ((snd 0) (chn 0) (edpos current-edit-position)) (count-matches (lambda (n1) (> n1 .1)) 0 snd chn edpos)) 'count-matches (lambda () (scale-by 2.0 ind1 0)) ind1) (test-edpos (lambda* ((snd 0) (chn 0) (edpos current-edit-position)) (scan-channel (lambda (n2) (> n2 .1)) 0 #f snd chn edpos)) 'find (lambda () (delete-samples 0 100 ind1 0)) ind1) (test-edpos (lambda* ((snd 0) (chn 0) (edpos current-edit-position)) (let ((p (make-one-pole 1.0 -1.0))) (scan-channel (lambda (n3) (or (> n3 .1) (not (one-pole p 1.0)))) 0 (framples snd chn) snd chn edpos) (floor (one-pole p 0.0)))) 'scan-chan (lambda () (delete-samples 0 100 ind1 0)) ind1) (src-sound 2.0 1.0 ind1 0) (undo 1 ind1 0) (delete-samples 0 10000 ind1 0) (save-sound-as "fmv.snd" ind1 :edit-position 0) (save-sound-as "fmv1.snd" ind1 :edit-position 1) (let ((var (catch #t (lambda () (save-sound-as "fmv2.snd" ind1 :channel 1234)) (lambda args args)))) (if (not (eq? (car var) 'no-such-channel)) (snd-display #__line__ ";save-sound-as bad chan: ~A" var))) (if (not (= (mus-sound-framples "fmv.snd") (framples ind1 0 0))) (snd-display #__line__ ";save-sound-as (edpos): ~A ~A?" (mus-sound-framples "fmv.snd") (framples ind1 0 0))) (if (not (= (mus-sound-framples "fmv1.snd") (framples ind1 0 1))) (snd-display #__line__ ";save-sound-as (edpos 1): ~A ~A?" (mus-sound-framples "fmv.snd") (framples ind1 0 1))) (if (= (mus-sound-framples "fmv.snd") (framples ind1 0 1)) (snd-display #__line__ ";save-sound-as (edpos 1)(2): ~A ~A?" (mus-sound-framples "fmv.snd") (framples ind1 0 1))) (let ((ind2 (open-sound "fmv.snd")) (ind3 (open-sound "fmv1.snd"))) (if (not (vequal (channel->float-vector 12000 10 ind1 0 0) (channel->float-vector 12000 10 ind2 0))) (snd-display #__line__ ";save-sound-as (edpos 3): ~A ~A?" (channel->float-vector 12000 10 ind1 0 0) (channel->float-vector 12000 10 ind2 0))) (if (not (vequal (channel->float-vector 12000 10 ind1 0 1) (channel->float-vector 12000 10 ind3 0))) (snd-display #__line__ ";save-sound-as (edpos 4): ~A ~A?" (channel->float-vector 12000 10 ind1 0 1) (channel->float-vector 12000 10 ind3 0))) (if (vequal (channel->float-vector 12000 10 ind2 0) (channel->float-vector 12000 10 ind3 0)) (snd-display #__line__ ";save-sound-as (edpos 5): ~A ~A?" (channel->float-vector 12000 10 ind2 0) (channel->float-vector 12000 10 ind3 0))) (select-sound ind3) (set! (comment) "hiho") (if (not (string=? (comment) "hiho")) (snd-display #__line__ ";set! comment no index: ~A" (comment))) (close-sound ind2) (close-sound ind3)) (delete-file "fmv.snd") (delete-file "fmv1.snd") (test-edpos-1 (lambda (snd pos) (reverse-sound snd 0 pos)) 'reverse-sound ind1) (test-edpos-1 (lambda (snd pos) (env-sound '(0 0 1 1 2 0) 0 20000 1.0 snd 0 pos)) 'env-sound ind1) (test-edpos-1 (lambda (snd pos) (src-sound 0.5 1.0 snd 0 pos)) 'src-sound ind1) (test-edpos-1 (lambda (snd pos) (filter-sound (make-fir-filter 6 (float-vector .1 .2 .3 .3 .2 .1)) 6 snd 0 pos)) 'filter-sound ind1) (test-edpos-1 (lambda (snd pos) (convolve-with "pistol.snd" .5 snd 0 pos)) 'convolve-with ind1) (let ((ind (new-sound "fmv.snd")) (v (make-float-vector 2000)) (e (make-env (list 0.0 0.0 1.0 (* 2000 0.2 pi)) :length 2001))) (fill-float-vector v (sin (env e))) (float-vector->channel v 0 2000 ind 0) (filter-sound '(0 0 .09 0 .1 1 .11 0 1 0) 1024) (if (> (maxamp) .025) (snd-display #__line__ ";filter-sound maxamp 1: ~A" (maxamp))) (undo) (filter-sound '(0 0 .19 0 .2 1 .21 0 1 0) 1024) (if (< (maxamp) .9) (snd-display #__line__ ";filter-sound maxamp 2: ~A" (maxamp))) (undo) (filter-sound '(0 0 .29 0 .3 1 .31 0 1 0) 1024) (if (> (maxamp) .02) (snd-display #__line__ ";filter-sound maxamp 3: ~A" (maxamp))) (set! *show-sonogram-cursor* #t) (set! *with-tracking-cursor* #t) (if (not *with-tracking-cursor*) (snd-display #__line__ ";with-tracking-cursor set to #t: ~A" *with-tracking-cursor*)) (set! *transform-graph-type* graph-as-sonogram) (play :wait #t) (set! (transform-graph?) #t) (close-sound ind)) (close-sound ind1)) (let ((ind (open-sound "1a.snd"))) ; from Anders Vinjar (set! (with-tracking-cursor) :track-and-return) (set! (cursor) 2000) (let ((here (cursor))) (play :start (cursor)) (if (or (not (= here 2000)) (not (= (cursor) 2000))) (snd-display #__line__ ";with-tracking-cursor set to :track-and-return: start: ~A, end: ~A" here (cursor)))) (set! (zoom-focus-style) zoom-focus-middle) (when with-motif (set! (x-zoom-slider) .5) (if (fneq (x-position-slider) 0.25) (snd-display #__line__ ";zoom focus middle .5: ~A" (x-position-slider))) (set! (x-zoom-slider) .1) (if (fneq (x-position-slider) 0.45) (snd-display #__line__ ";zoom focus middle .1: ~A" (x-position-slider))) (set! (x-zoom-slider) .9) (if (fneq (x-position-slider) 0.05) (snd-display #__line__ ";zoom focus middle .9: ~A" (x-position-slider))) (set! (zoom-focus-style) zoom-focus-left) (set! (x-zoom-slider) .1) (if (fneq (x-position-slider) 0.05) (snd-display #__line__ ";zoom focus left .1: ~A" (x-position-slider)))) (close-sound ind)) (let* ((ind (open-sound "oboe.snd")) (mx (maxamp ind 0)) (e0 (channel-amp-envs ind 0))) (define (peak-env-equal? name index e diff) (let ((reader (make-sampler 0 index 0)) (e-size (length (car e)))) (let ((samps-per-bin (ceiling (/ (framples index) e-size))) (mins (car e)) (maxs (cadr e)) (happy #t) (data #f)) (set! data (make-float-vector samps-per-bin)) (do ((e-bin 0 (+ e-bin 1))) ((or (not happy) (= e-bin e-size)) happy) (do ((k 0 (+ k 1))) ((= k samps-per-bin)) (float-vector-set! data k (next-sample reader))) (let ((mx (float-vector-max data)) (mn (float-vector-min data))) (let ((mxdiff (abs (- mx (maxs e-bin)))) (mndiff (abs (- mn (mins e-bin))))) (if (or (> mxdiff diff) (> mndiff diff)) (begin (snd-display #__line__ ";~A: peak-env-equal? [bin ~D of ~D]: (~,4F to ~,4F), diff: ~,5F" name e-bin e-size mn mx (max mxdiff mndiff)) (set! happy #f))))))))) (if (null? e0) (snd-display #__line__ ";no amp env data") (let ((mx1 (float-vector-peak (car e0))) (mx2 (float-vector-peak (cadr e0)))) (if (fneq mx (max mx1 mx2)) (snd-display #__line__ ";amp env max: ~A ~A ~A" mx mx1 mx2)) (peak-env-equal? "straight peak" ind e0 .0001) (scale-by 3.0) (let* ((e1 (channel-amp-envs ind 0 1)) (mx3 (float-vector-peak (car e1))) (mx4 (float-vector-peak (cadr e1)))) (if (or (fneq (* 3.0 mx1) mx3) (fneq (* 3.0 mx2) mx4)) (snd-display #__line__ ";3.0 amp env max: ~A ~A ~A ~A" mx1 mx2 mx3 mx4)) (peak-env-equal? "scaled peak" ind e1 .0001)) (if (fneq (maxamp ind 0) (* 3 mx)) (snd-display #__line__ ";maxamp after scale: ~A ~A" mx (maxamp ind 0))) (undo) (set! (selection-member? #t) #f) (set! (selection-member? ind 0) #t) (set! (selection-position ind 0) 20000) (set! (selection-framples ind 0) 12000) (scale-selection-by 3.0) (let* ((e1 (channel-amp-envs ind 0 1)) (mx3 (float-vector-peak (car e1))) (mx4 (float-vector-peak (cadr e1)))) (if (or (fneq (* 3.0 mx1) mx3) (fneq (* 3.0 mx2) mx4)) (snd-display #__line__ ";selection 3.0 amp env max: ~A ~A ~A ~A" mx1 mx2 mx3 mx4)) (if (fneq (maxamp ind 0) (* 3 mx)) (snd-display #__line__ ";maxamp after selection scale: ~A ~A" mx (maxamp ind 0))) (peak-env-equal? "selection peak" ind e1 .0001)) (map-channel abs) (let* ((e1 (channel-amp-envs ind 0 2)) (mx3 (float-vector-peak (car e1))) (mx4 (float-vector-peak (cadr e1)))) (if (fneq (* 3.0 mx2) mx4) (snd-display #__line__ ";abs selection 3.0 amp env max: ~A ~A ~A ~A" mx1 mx2 mx3 mx4)) (if (fneq (maxamp ind 0) (* 3 mx)) (snd-display #__line__ ";maxamp after abs selection scale: ~A ~A" mx (maxamp ind 0))) (if (ffneq mx3 0.03) (snd-display #__line__ ";abs max: ~A ~A" mx3 mx4)) (peak-env-equal? "map-channel peak" ind e1 .0001)) (delete-samples 10000 5000) (let* ((e1 (channel-amp-envs ind 0)) (mx3 (float-vector-peak (car e1))) (mx4 (float-vector-peak (cadr e1)))) (if (fneq (* 3.0 mx2) mx4) (snd-display #__line__ ";abs selection 3.0 amp env max: ~A ~A ~A ~A" mx1 mx2 mx3 mx4)) (if (fneq (maxamp ind 0) (* 3 mx)) (snd-display #__line__ ";maxamp after abs selection scale: ~A ~A" mx (maxamp ind 0))) (if (ffneq mx3 0.03) (snd-display #__line__ ";abs max: ~A ~A" mx3 mx4)) (peak-env-equal? "delete peak" ind e1 .0001)) (scale-selection-by -.333) (let* ((e1 (channel-amp-envs ind 0 4)) (mx3 (float-vector-peak (car e1)))) (if (fneq (maxamp ind 0) mx) (snd-display #__line__ ";maxamp after minus abs selection scale: ~A ~A" mx (maxamp ind 0))) (if (fneq (maxamp ind 0) mx3) (snd-display #__line__ ";mx3 maxamp after minus abs selection scale: ~A ~A" mx mx3)) (peak-env-equal? "scale-selection peak" ind e1 .0001)) (revert-sound ind) (ramp-channel 0.0 1.0) (peak-env-equal? "ramp-channel peak" ind (channel-amp-envs ind 0 1) .001) (undo) (env-channel '(0 0 1 1 2 0)) (peak-env-equal? "env-channel peak" ind (channel-amp-envs ind 0 1) .002) (undo) (env-channel (make-env '(0 0 1 1 2 0) :scaler 0.5 :length (framples))) (peak-env-equal? "scaled env-channel peak" ind (channel-amp-envs ind 0 1) .002) (undo) (env-channel (make-env '(0 0 1 1 2 0) 0.5 :length (framples))) (peak-env-equal? "scaled nokey env-channel peak" ind (channel-amp-envs ind 0 1) .001) (undo) (env-channel (make-env '(0 0 1 1 2 0) :scaler 0.5 :offset 0.5 :length (framples))) (peak-env-equal? "scaled and offset env-channel peak" ind (channel-amp-envs ind 0 1) .001) (undo) (env-channel (make-env '(0 0 1 1 2 .5 3 0) :base 0.0 :length (framples))) (peak-env-equal? "env-channel base 0.0 peak" ind (channel-amp-envs ind 0 1) .001) (undo) (xramp-channel 0.0 1.0 32.0) (peak-env-equal? "xramp 32.0 peak" ind (channel-amp-envs ind 0 1) .008) (undo) (xramp-channel 0.0 1.0 .032) (peak-env-equal? "xramp .032 peak" ind (channel-amp-envs ind 0 1) .004) (undo) (env-channel (make-env '(0 0 1 1 2 .5 3 0) :base 10.0 :length (framples))) (peak-env-equal? "env-channel base 10.0 peak" ind (channel-amp-envs ind 0 1) .003) (undo) (env-channel (make-env '(0 0 1 1 2 0) :base .10 :length (framples))) (peak-env-equal? "env-channel base .1 peak" ind (channel-amp-envs ind 0 1) .003) (undo) (revert-sound ind) (ramp-channel 0.0 1.0) (ramp-channel 1.0 0.0) (peak-env-equal? "ramp2 peak" ind (channel-amp-envs ind 0 2) .002) (revert-sound ind) (env-channel '(0 0 1 1)) (env-channel '(0 0 1 1 2 0)) (peak-env-equal? "env ramp2 peak" ind (channel-amp-envs ind 0 2) .002) (revert-sound ind) (ramp-channel 0.0 1.0 12000 5000) (peak-env-equal? "ramp-channel peak" ind (channel-amp-envs ind 0 1) .002) (undo) (env-channel '(0 0 1 1 2 0) 12000 5000) (peak-env-equal? "env-channel peak" ind (channel-amp-envs ind 0 1) .003) (undo) (env-channel (make-env '(0 0 1 1 2 0) :scaler 0.5 :length 5000) 12000 5000) (peak-env-equal? "scaled env-channel peak" ind (channel-amp-envs ind 0 1) .004) (undo) (env-channel (make-env '(0 0 1 1 2 0) 0.5 :length 5000) 12000 5000) (peak-env-equal? "scaled nokey env-channel peak" ind (channel-amp-envs ind 0 1) .004) (undo) (env-channel (make-env '(0 0 1 1 2 0) :scaler 0.5 :offset 0.5 :length 5000) 12000 5000) (peak-env-equal? "scaled and offset env-channel peak" ind (channel-amp-envs ind 0 1) .002) (undo) (xramp-channel 0.0 1.0 32.0 2000 1000) (peak-env-equal? "xramp 32.0 peak (1)" ind (channel-amp-envs ind 0 1) .009) (undo) (xramp-channel 0.0 1.0 .032 2000 1000) (peak-env-equal? "xramp .032 peak (1)" ind (channel-amp-envs ind 0 1) .009) (undo) (env-channel (make-env '(0 0 1 1 2 .5 3 0) :base 10.0 :length 5000) 12000 5000) (peak-env-equal? "env-channel base 10.0 peak" ind (channel-amp-envs ind 0 1) .1) ;; this can be way off because the envelope is not very closely sampled in this case (revert-sound ind) (ramp-channel 0.0 1.0) (ramp-channel 1.0 0.0 2000 1000) (peak-env-equal? "ramp2 peak" ind (channel-amp-envs ind 0 2) .002) (revert-sound ind) (env-channel '(0 0 1 1)) (env-channel '(0 0 1 1 2 0) 2000 1000) (peak-env-equal? "env ramp2 peak" ind (channel-amp-envs ind 0 2) .002) (revert-sound ind) (env-channel '(0 0 1 1)) (env-channel '(0 0 1 1 2 0)) (env-channel '(0 0 1 1) 12000 5000) (peak-env-equal? "env ramp3 peak" ind (channel-amp-envs ind 0 3) .01) (revert-sound ind) )) (close-sound ind)) (let ((ind (new-sound "test.snd"))) (map-channel (lambda (y) 1.0) 0 50001) (ramp-channel 0.5 1.0 1000 4000) (let* ((peaks (channel-amp-envs ind 0)) (mx (cadr peaks)) (mn (car peaks))) (call-with-current-continuation (lambda (break) (if (not (continuation? break)) (snd-display #__line__ ";not a continuation: ~A" break)) (let ((ln (- (length mn) 4))) (do ((i 0 (+ i 1))) ((= i ln)) (if (< (mn i) 0.5) (begin (snd-display #__line__ ";peak min: ~A ~A" (mn i) i) (break #f))) (if (< (mx i) 0.5) (begin (snd-display #__line__ ";peak max: ~A ~A" (mx i) i) (break #f)))))))) (undo 2) (map-channel (lambda (y) -1.0) 0 50001) (ramp-channel 0.5 1.0 1000 4000) (let* ((peaks (channel-amp-envs ind 0)) (mx (cadr peaks)) (mn (car peaks)) (happy #t) (ln (- (length mn) 4))) (do ((i 0 (+ i 1))) ((or (not happy) (= i ln))) (if (> (mn i) -0.5) (begin (snd-display #__line__ ";1 peak min: ~A ~A" (mn i) i) (set! happy #f))) (if (> (mx i) -0.5) (begin (snd-display #__line__ ";1 peak max: ~A ~A" (mx i) i) (set! happy #f))))) (close-sound ind)) (let ((index (new-sound "fmv.snd" 2 22050 mus-ldouble mus-next "channel tests"))) (define (test-channel-func func val-func init-val) (let ((len (framples index)) (chns (chans index)) (val #f)) (set! g-init-val init-val) (do ((k 0 (+ k 1))) ((= k 2)) (set! val (val-func len)) (set! (sync index) k) (do ((i 0 (+ i 1))) ((= i chns)) (map-channel (lambda (n) 0.0) 0 len index i) (if (scan-channel (lambda (n) (> (abs n) .001)) 0 len index i) (snd-display #__line__ ";init scan: ~A?" (scan-channel (lambda (n) (> (abs n) 0.001)))))) ;; now it's cleared (do ((i 0 (+ i 1))) ((= i chns)) (map-channel (lambda (n) g-init-val) 0 len index i) (func 0 len index i) (do ((j 0 (+ j 1))) ((= j chns)) (let ((vi (channel->float-vector 0 len index j))) (if (= j i) (if (not (vequal vi val)) (snd-display #__line__ ";chan func: ~A ~A" vi val)) (if (scan-channel (lambda (n) (> (abs n) .001)) 0 len index j) (snd-display #__line__ ";chan func leaks? ~A ~A: ~A" i j (scan-channel (lambda (n) (> (abs n) 0.001)) 0 len index j)))))) (map-channel (lambda (n) 0.0) 0 len index i)) (do ((i 0 (+ i 1))) ((= i chns)) (map-channel (lambda (n) g-init-val) 0 len index i) (let ((ed (edit-position index i))) (map-channel (lambda (n) (+ g-init-val 1.0)) 0 len index i) (func 0 len index i ed) (do ((j 0 (+ j 1))) ((= j chns)) (let ((vi (channel->float-vector 0 len index j))) (if (= j i) (if (not (vequal vi val)) (snd-display #__line__ ";ed chan func: ~A ~A" vi val)) (if (scan-channel (lambda (n) (> (abs n) 0.001)) 0 len index j) (snd-display #__line__ ";ed chan func leaks? ~A ~A ~A: ~A" i j ed (scan-channel (lambda (n) (> (abs n) 0.001)) 0 len index j)))))) (map-channel (lambda (n) 0.0) 0 len index i))) (let* ((beg (floor (/ len 3))) (dur beg) (nv (val-func dur))) (fill! val 0.0) (do ((i beg (+ i 1)) (j 0 (+ j 1))) ((= j dur)) (set! (val i) (nv j))) (do ((i 0 (+ i 1))) ((= i chns)) (map-channel (lambda (n) g-init-val) beg dur index i) (func beg dur index i) (add-mark beg index i) (do ((j 0 (+ j 1))) ((= j chns)) (let ((vi (channel->float-vector 0 len index j))) (if (= j i) (if (not (vequal vi val)) (snd-display #__line__ ";chan func n: ~A ~A" vi val)) (if (scan-channel (lambda (n) (> (abs n) 0.001)) 0 len index j) (snd-display #__line__ ";dur chan func leaks? ~A ~A: ~A" i j (scan-channel (lambda (n) (> (abs n) 0.001)) 0 len index j)))))) (map-channel (lambda (n) 0.0) 0 len index i)))))) (insert-silence 0 10 index 0) (insert-silence 0 10 index 1) (test-channel-func (lambda* (beg dur index chan edpos) (clm-channel (make-env :envelope '(0 0 1 1) :length dur) beg dur index chan edpos)) (lambda (dur) (let ((e (make-env :envelope '(0 0 1 1) :length dur)) (v (make-float-vector dur))) (do ((i 0 (+ i 1))) ((= i dur)) (set! (v i) (env e))) v)) 0.0) (test-channel-func (lambda* (beg dur index chan edpos) (clm-channel (make-oscil :frequency 0.0 :initial-phase (/ pi 2)) beg dur index chan edpos)) (lambda (dur) (let ((v (make-float-vector dur))) (fill! v 1.0) v)) 0.0) (test-channel-func (lambda* (beg dur index chan edpos) (scale-channel 0.5 beg dur index chan edpos)) (lambda (dur) (let ((v (make-float-vector dur))) (fill! v 0.5) v)) 1.0) (test-channel-func (lambda* (beg dur index chan edpos) (env-channel (make-env :envelope '(0 0 1 1) :length dur) beg dur index chan edpos)) (lambda (dur) (let ((e (make-env :envelope '(0 0 1 1) :length dur)) (v (make-float-vector dur))) (do ((i 0 (+ i 1))) ((= i dur)) (set! (v i) (env e))) v)) 1.0) (test-channel-func (lambda* (beg dur index chan edpos) (env-channel '(0 0 1 1) beg dur index chan edpos)) (lambda (dur) (let ((e (make-env :envelope '(0 0 1 1) :length dur)) (v (make-float-vector dur))) (do ((i 0 (+ i 1))) ((= i dur)) (set! (v i) (env e))) v)) 1.0) (test-channel-func (lambda* (beg dur index chan edpos) (let ((v (make-float-vector dur))) (fill! v -1.0) (float-vector->channel v beg dur index chan))) (lambda (dur) (let ((v (make-float-vector dur))) (fill! v -1.0) v)) 1.0) (test-channel-func (lambda* (beg dur index chan edpos) (delete-samples beg dur index chan edpos) (pad-channel beg dur index chan edpos)) make-float-vector 1.0) (test-channel-func (lambda* (beg dur index chan edpos) (let ((v (make-float-vector dur))) (fill! v -1.0) (delete-samples beg dur index chan edpos) (insert-samples beg dur v index chan edpos))) (lambda (dur) (let ((v (make-float-vector dur))) (fill! v -1.0) v)) 1.0) (test-channel-func (lambda* (beg dur index chan edpos) (let ((v (make-float-vector dur))) (fill! v -1.0) (set! (samples beg dur index chan #f "test-channel" 0 edpos) v))) (lambda (dur) (let ((v (make-float-vector dur))) (fill! v -1.0) v)) 1.0) (test-channel-func (lambda* (beg dur index chan edpos) (env-channel (make-env :envelope '(0 0 1 1) :length dur) beg dur index chan edpos) (reverse-channel beg dur index chan)) (lambda (dur) (let ((e (make-env :envelope '(0 1 1 0) :length dur)) (v (make-float-vector dur))) (do ((i 0 (+ i 1))) ((= i dur)) (set! (v i) (env e))) v)) 1.0) (test-channel-func (lambda* (beg dur index chan edpos) (env-channel (make-env :envelope '(0 0 1 1) :length dur) beg dur index chan edpos) (set! (sample (+ beg dur) index chan) 1.0) (smooth-channel beg dur index chan) (if (not (= beg 0)) (set! (sample (+ beg dur) index chan) 0.0))) (lambda (dur) (let ((v (make-float-vector dur)) (ipi (/ pi dur))) (do ((i 0 (+ i 1))) ((= i dur)) (set! (v i) (+ 0.5 (* 0.5 (cos (+ pi (* ipi i))))))) v)) 1.0) (let ((old-max (maxamp index #t)) (regdata (map (lambda (n) (catch #t (lambda () (region->float-vector n 0 10)) (lambda args (float-vector)))) (regions))) ;; (old-pos0 (edit-position index 0)) ;; (old-pos1 (edit-position index 1)) (old-reglen (map region-framples (regions))) (s61-files ())) (hook-push save-state-hook (lambda (hook) (set! s61-files (cons (hook 'name) s61-files)))) (if (file-exists? "s61.scm") (delete-file "s61.scm")) (save-state "s61.scm") (close-sound index) (for-each forget-region (regions)) (load (string-append cwd "s61.scm")) (if (not (equal? old-reglen (map region-framples (regions)))) (snd-display #__line__ ";region-framples after save: ~A ~A" old-reglen (map region-framples (regions)))) (catch #t (lambda () (for-each (lambda (n data) (if (not (vequal data (region->float-vector n 0 10))) (snd-display #__line__ ";region after save ~A: ~A ~A" n data (region->float-vector n 0 10)))) (regions) regdata)) (lambda args (snd-display #__line__ ";region->float-vector: ~A" args))) (set! index (find-sound "fmv.snd")) (if (not (equal? (maxamp index #t) old-max)) (snd-display #__line__ ";maxes: ~A ~A" (maxamp index #t) old-max)) (if (not (equal? (edits index) (list 275 0))) (snd-display #__line__ ";saved channel edits: ~A" (edits index))) (do ((i 0 (+ i 1))) ((= i 10)) (let ((pos (random (car (edits index))))) (scale-channel (random 2.0) (random 5) (random 5) index 0 pos) (set! (edit-position index) (floor (* (car (edits index)) .7))))) (close-sound index) (for-each forget-region (regions)) (for-each (lambda (file) (if (file-exists? file) (delete-file file))) s61-files) (delete-file "s61.scm") (set! (hook-functions save-state-hook) ()) )) (let ((index (new-sound "fmv.snd" 2 22050 mus-ldouble mus-next "channel tests")) (v (make-float-vector 10)) (sw *sinc-width*)) (set! *sinc-width* 10) (set! (v 0) 1.0) (float-vector->channel v 0 10 index 0) (src-channel 0.5 0 10 index 0) (let ((v (make-float-vector 10)) (s (make-src :srate 0.5 :input (let ((val 1.0)) (lambda (dir) (let ((rtn val)) (set! val 0.0) rtn)))))) (set! (v 0) (src s)) (do ((i 1 (+ i 1))) ((= i 10)) (set! (v i) (src s))) (if (not (vequal v (channel->float-vector 0 10 index 0))) (snd-display #__line__ ";src-channel: ~A ~A" v (channel->float-vector 0 10 index 0))) (if (not (vequal (make-float-vector 10) (channel->float-vector 0 10 index 1))) (snd-display #__line__ ";src-channel leaks: ~A" (channel->float-vector 0 10 index 1)))) (let ((tag (catch #t (lambda () (src-channel 120000.0)) (lambda args args)))) (if (not (eq? (car tag) 'mus-error)) (snd-display #__line__ ";src-channel crazy srate: ~A" tag))) (let ((tag (catch #t (lambda () (filter-sound (make-snd->sample))) (lambda args args)))) (if (not (eq? (car tag) 'mus-error)) (snd-display #__line__ ";filter-sound + un-run gen: ~A" tag))) (revert-sound index) (float-vector->channel v 0 10 index 1) (float-vector->channel v 10 10 index 1) (src-channel (make-env :envelope '(1 1 2 2) :length 21) 0 20 index 1) (if (not (vequal (channel->float-vector 0 10 index 1) (float-vector 1.000 -0.000 -0.048 0.068 -0.059 0.022 0.030 -0.100 0.273 0.606))) (snd-display #__line__ ";src-channel env: ~A" (channel->float-vector 0 10 index 1))) (if (not (vequal (make-float-vector 10) (channel->float-vector 0 10 index 0))) (snd-display #__line__ ";src-channel env leaks: ~A" (channel->float-vector 0 10 index 0))) (revert-sound index) (float-vector->channel v 0 10 index 1) (float-vector->channel v 10 10 index 1) (src-channel '(1 1 2 2) 0 20 index 1) ; end is off above -- should be 19 I think (if (not (vequal (channel->float-vector 0 10 index 1) (float-vector 1.000 -0.000 -0.051 0.069 -0.056 0.015 0.042 -0.117 0.320 0.568))) (snd-display #__line__ ";src-channel lst: ~A" (channel->float-vector 0 10 index 1))) (if (not (vequal (make-float-vector 10) (channel->float-vector 0 10 index 0))) (snd-display #__line__ ";src-channel lst leaks: ~A" (channel->float-vector 0 10 index 0))) (set! *sinc-width* sw) (close-sound index)) (let ((ind (new-sound :size 100))) (for-each (lambda (sr) (revert-sound ind) (set! (sample 50) .5) (set! (sample 51) -.5) (src-channel sr) (let ((v1 (channel->float-vector))) (revert-sound ind) (set! (sample 50) .5) (set! (sample 51) -.5) (src-channel (+ sr .00001)) (let ((v2 (channel->float-vector))) (float-vector-abs! (float-vector-subtract! v1 v2)) (let ((sum 0.0) (len (min (length v1) (length v2))) (mx (float-vector-peak v1))) (do ((i 0 (+ i 1))) ((= i len)) (set! sum (+ sum (float-vector-ref v1 i)))) (if (or (> sum .01) ; depends on sinc-width I think (> mx .002)) (snd-display #__line__ ";src-channel ~A: diff: ~A ~A~%" sr sum mx)))))) (list 0.5 0.75 1.0 1.5 2.0)) (close-sound ind)) (if (< *max-regions* 8) (set! *max-regions* 8)) (let* ((ind (open-sound "oboe.snd")) (rid0 (make-region 2000 2020 ind 0)) (rid0-data (region2float-vector rid0 0 20))) (scale-sound-by 2.0) (play rid0 :wait #t) (let ((nv (region2float-vector rid0 0 20))) (if (not (vequal rid0-data nv)) (snd-display #__line__ ";deferred region after scaling:~% ~A~% ~A" rid0-data nv))) (let ((nv (region-to-float-vector rid0 0 20))) (if (not (vequal rid0-data nv)) (snd-display #__line__ ";deferred region after scaling (rs):~% ~A~% ~A" rid0-data nv))) (undo) (scale-by 4.0) (play rid0 :wait #t) (let ((nv (region2float-vector rid0 0 20))) (if (not (vequal rid0-data nv)) (snd-display #__line__ ";file region after scaling:~% ~A~% ~A" rid0-data nv))) (let ((nv (region-to-float-vector rid0 0 20))) (if (not (vequal rid0-data nv)) (snd-display #__line__ ";file region after scaling (rs):~% ~A~% ~A" rid0-data nv))) (let* ((rid1 (make-region 2000 2020 ind 0)) (rid1-data (region2float-vector rid1 0 20))) (scale-to .5) (let ((nv (region2float-vector rid1 0 20))) (if (not (vequal rid1-data nv)) (snd-display #__line__ ";deferred region after scale-to:~% ~A~% ~A" rid1-data nv))) (close-sound ind) (play rid0 :wait #t) (play rid1 :wait #t) (let ((nv (region2float-vector rid1 0 20))) (if (not (vequal rid1-data nv)) (snd-display #__line__ ";deferred region after close:~% ~A~% ~A" rid1-data nv))) (let ((nv (region2float-vector rid0 0 20))) (if (not (vequal rid0-data nv)) (snd-display #__line__ ";file region after close:~% ~A~% ~A" rid0-data nv)))) (for-each (lambda (s1 l1 s2 l2) (set! ind (open-sound "2.snd")) (set! (selection-member? #t) #f) (set! (selection-member? ind 0) #t) (set! (selection-position ind 0) s1) (set! (selection-framples ind 0) l1) (set! (selection-member? ind 1) #t) (set! (selection-position ind 1) s2) (set! (selection-framples ind 1) l2) (let* ((rid2 (make-region)) (rid20-data (region2float-vector rid2 0 l1)) (rid21-data (region2float-vector rid2 1 l2))) (if (not (= (region-chans rid2) 2)) (snd-display #__line__ ";region-chans of sync'd sound: ~A?" (region-chans rid2))) (swap-channels ind 0 ind 1) (let ((nv (region2float-vector rid2 0 l1))) (if (not (vequal rid20-data nv)) (snd-display #__line__ ";deferred region after scaling (20):~% ~A~% ~A" rid20-data nv))) (let ((nv (region-to-float-vector rid2 0 l1))) (if (not (vequal rid20-data nv)) (snd-display #__line__ ";deferred region after scaling (20 rs):~% ~A~% ~A" rid20-data nv))) (let ((nv (region2float-vector rid2 1 l2))) (if (not (vequal rid21-data nv)) (snd-display #__line__ ";deferred region after scaling (21):~% ~A~% ~A" rid21-data nv))) (let ((nv (region-to-float-vector rid2 1 l2))) (if (not (vequal rid21-data nv)) (snd-display #__line__ ";deferred region after scaling (21 rs):~% ~A~% ~A" rid21-data nv))) (close-sound ind) (let ((nv (region2float-vector rid2 0 l1))) (if (not (vequal rid20-data nv)) (snd-display #__line__ ";deferred region after scaling (20):~% ~A~% ~A" rid20-data nv))) (let ((nv (region-to-float-vector rid2 0 l1))) (if (not (vequal rid20-data nv)) (snd-display #__line__ ";deferred region after scaling (20 rs):~% ~A~% ~A" rid20-data nv))) (let ((nv (region2float-vector rid2 1 l2))) (if (not (vequal rid21-data nv)) (snd-display #__line__ ";deferred region after scaling (21):~% ~A~% ~A" rid21-data nv))) (let ((nv (region-to-float-vector rid2 1 l2))) (if (not (vequal rid21-data nv)) (snd-display #__line__ ";deferred region after scaling (21 rs):~% ~A~% ~A" rid21-data nv))) )) (list 2000 2000 2000 0 2000 0 2000) (list 20 10 20 20 20 10 20) (list 2000 2000 2000 2000 0 2000 0) (list 20 20 10 20 20 20 10))) (let ((ind (open-sound "obtest.snd"))) (set! (read-only ind) #t) (delete-samples 0 1000 ind 0) (let ((val (catch #t (lambda () (save-sound ind)) (lambda args args)))) (if (sound? val) (snd-display #__line__ ";save-sound read-only: ~A" val)) (if (not (equal? (edits ind) (list 1 0))) (snd-display #__line__ ";read-only ignored? ~A" (edits ind)))) (set! (read-only ind) #f) (revert-sound ind) (let ((tag (catch #t (lambda () (save-sound ind)) (lambda args args)))) (if (not (sound? tag)) (snd-display #__line__ ";save-sound read-write: ~A" tag))) (key (char->integer #\j) 4) (key (char->integer #\-) 4) (key (char->integer #\j) 4) (key (char->integer #\j) 4) (key (char->integer #\x) 4) (key (char->integer #\c) 0) (catch #t (lambda () (add-mark 123)) (lambda args #f)) (key (char->integer #\u) 4) (key (char->integer #\6) 4) (key (char->integer #\j) 4) (key (char->integer #\u) 4) (key (char->integer #\6) 4) (key (char->integer #\x) 4) (key (char->integer #\c) 0) (close-sound ind)) (let ((ns (new-sound)) (v (make-float-vector 1000))) (unselect-all) (do ((i 0 (+ i 1)) (x 0.0 (+ x .001))) ((= i 1000)) (set! (v i) x)) (float-vector->channel v 0 1000 ns 0) (set! (selection-member? ns 0) #t) (set! (selection-position ns 0) 200) (set! (selection-framples ns 0) 300) (delete-selection-and-smooth) (if (not (= (framples ns 0) 700)) (snd-display #__line__ ";delete-selection-and-smooth framples: ~A" (framples ns 0))) (if (fneq (sample 167 ns 0) 0.167) (snd-display #__line__ ";delete-selection-and-smooth 167: ~A" (sample 167 ns 0))) (if (fneq (sample 234 ns 0) 0.534) (snd-display #__line__ ";delete-selection-and-smooth 234: ~A" (sample 234 ns 0))) (if (fneq (sample 210 ns 0) 0.406) (snd-display #__line__ ";delete-selection-and-smooth 210: ~A" (sample 210 ns 0))) (let* ((v1 (channel->float-vector)) (maxdiff 0.0) (mindiff 10.0) (ls (v1 0))) (do ((i 1 (+ i 1))) ((= i 700)) (let ((diff (- (v1 i) ls))) (set! ls (v1 i)) (if (> diff maxdiff) (set! maxdiff diff)) (if (< diff mindiff) (set! mindiff diff)))) (if (< mindiff .0009) (snd-display #__line__ ";delete-selection-and-smooth min diff: ~A" mindiff)) (if (> maxdiff .007) (snd-display #__line__ ";delete-selection-and-smooth max diff: ~A" maxdiff))) (close-sound ns)) (let ((ns (new-sound)) (v (make-float-vector 1000))) (do ((i 0 (+ i 1)) (x 0.0 (+ x .001))) ((= i 1000)) (set! (v i) x)) (float-vector->channel v 0 1000 ns 0) (delete-samples-and-smooth 200 300 ns 0) (if (not (= (framples ns 0) 700)) (snd-display #__line__ ";delete-samples-and-smooth framples: ~A" (framples ns 0))) (if (fneq (sample 167 ns 0) 0.167) (snd-display #__line__ ";delete-samples-and-smooth 167: ~A" (sample 167 ns 0))) (if (fneq (sample 234 ns 0) 0.534) (snd-display #__line__ ";delete-samples-and-smooth 234: ~A" (sample 234 ns 0))) (if (fneq (sample 210 ns 0) 0.406) (snd-display #__line__ ";delete-samples-and-smooth 210: ~A" (sample 210 ns 0))) (let* ((v1 (channel->float-vector)) (maxdiff 0.0) (mindiff 10.0) (ls (v1 0))) (do ((i 1 (+ i 1))) ((= i 700)) (let ((diff (- (v1 i) ls))) (set! ls (v1 i)) (if (> diff maxdiff) (set! maxdiff diff)) (if (< diff mindiff) (set! mindiff diff)))) (if (< mindiff .0009) (snd-display #__line__ ";delete-samples-and-smooth min diff: ~A" mindiff)) (if (> maxdiff .007) (snd-display #__line__ ";delete-samples-and-smooth max diff: ~A" maxdiff))) (close-sound ns)) (let ((old-beg *initial-beg*) (old-dur *initial-dur*) (old-show *show-full-duration*) (old-hook (hook-functions initial-graph-hook))) (set! (hook-functions initial-graph-hook) ()) (set! *show-full-duration* #t) (let ((ns (open-sound "1.snd"))) (let ((ls (left-sample ns 0)) (rs (right-sample ns 0)) (fr (framples ns 0))) (when with-gui (if (not (equal? (list fr ls rs) '(220501 0 220501))) (snd-display #__line__ ";show-full-duration 1: ~A" (list fr ls rs)))) (close-sound ns))) (set! *show-full-duration* #t) (set! *initial-beg* 0.0) (set! *initial-dur* 0.2) (let ((ns (open-sound "1.snd"))) (let ((ls (left-sample ns 0)) (rs (right-sample ns 0)) (fr (framples ns 0))) (when with-gui (if (not (equal? (list fr ls rs) '(220501 0 220501))) (snd-display #__line__ ";show-full-duration 2: ~A" (list fr ls rs)))) (close-sound ns))) (set! *show-full-duration* #f) (set! *initial-beg* 0.0) (set! *initial-dur* 0.2) (let ((ns (open-sound "1.snd"))) (let ((ls (left-sample ns 0)) (rs (right-sample ns 0)) (fr (framples ns 0))) (if (not (equal? (list fr ls rs) '(220501 0 4410))) (snd-display #__line__ ";show-full-duration 3: ~A" (list fr ls rs))) (close-sound ns))) (set! *initial-beg* 2.0) (set! *initial-dur* 1.0) (let ((ns (open-sound "1.snd"))) (let ((ls (left-sample ns 0)) (rs (right-sample ns 0)) (fr (framples ns 0))) (if (not (equal? (list fr ls rs) '(220501 44100 66150))) (snd-display #__line__ ";show-full-duration 4: ~A" (list fr ls rs))) (close-sound ns))) (set! *initial-beg* old-beg) (set! *initial-dur* old-dur) (set! *show-full-duration* old-show) (set! (hook-functions initial-graph-hook) old-hook)) (set! *show-full-range* #t) (let ((ns (open-sound "1a.snd"))) (if (or (fneq (car (y-bounds ns 0)) -1.0) (fneq (cadr (y-bounds ns 0)) 1.0)) (snd-display #__line__ ";show-full-range 1a: ~A" (y-bounds ns 0))) (close-sound ns)) (with-sound ("test.snd" :clipped #f :to-snd #f) (fm-violin 0 1 440 3.5)) (let ((ns (open-sound "test.snd"))) (when with-gui (if (or (fneq (car (y-bounds ns 0)) -3.5) (fneq (cadr (y-bounds ns 0)) 3.5)) (snd-display #__line__ ";show-full-range 3.5 test: ~A" (y-bounds ns 0)))) (with-sound ("test.snd" :clipped #f :to-snd #f) (fm-violin 0 1 440 1.5)) (update-sound ns) (when with-gui (if (or (fneq (car (y-bounds ns 0)) -1.5) (fneq (cadr (y-bounds ns 0)) 1.5)) (snd-display #__line__ ";show-full-range 1.5 test: ~A" (y-bounds ns 0)))) (close-sound ns)) (set! *show-full-range* #f) (let ((old-sync *sync-style*)) (set! *sync-style* sync-none) (let ((ns (open-sound "2.snd"))) (if (not (= (sync ns) 0)) (snd-display #__line__ ";sync-none open: ~A" (sync ns))) (set! (sync ns) 1) (set! *sync-style* sync-by-sound) (let ((ns1 (open-sound "1a.snd"))) (if (or ;(= (sync ns1) 0) ; this default changed 12.9 (= (sync ns1) 1) (not (= (sync ns) 1))) (snd-display #__line__ ";sync-by-sound open: ~A" (list (sync ns) (sync ns1)))) (close-sound ns1)) (close-sound ns)) (set! *sync-style* old-sync)) (let ((ind (view-sound "obtest.snd"))) (delete-samples 0 1000 ind 0) (let ((tag (catch #t (lambda () (save-sound ind)) (lambda args args)))) (if (integer? tag) (snd-display #__line__ ";save-viewed-sound: ~A" tag)) (if (not (equal? (edits ind) (list 1 0))) (snd-display #__line__ ";view read-only ignored? ~A" (edits ind)))) (close-sound ind)) (let ((ind (new-sound "test.snd" 1 22050 mus-ldouble mus-next))) (insert-silence 0 150000) (map-channel (lambda (y) 0.5)) (env-sound '(0 0 1 1 2 0)) (fp 1.0 0.3 20) (let ((old-curse *with-tracking-cursor*)) (set! *with-tracking-cursor* #t) (play :wait #t) (set! *with-tracking-cursor* old-curse)) (close-sound ind)) (let ((ind (new-sound "test.snd" 1 22050 mus-ldouble mus-next))) (for-each (lambda (dur) (insert-silence 0 dur) (map-channel (lambda (y) 1.0)) (env-sound '(0 0 1 1 2 0)) (let ((reader (make-sampler (- (framples) 1) ind 0 -1))) (if (not (= (sampler-position reader) (- (framples) 1))) (snd-display #__line__ ";sampler-position: ~A" (sampler-position reader))) (map-channel (lambda (y) (read-sample reader)))) (let ((e (make-env '(0 0 1 1 2 0) :length (+ 1 dur))) (len (framples))) (let ((v0 (make-float-vector len)) (v1 (samples 0 len ind 0))) (outa->fv v0 (env e)) (if (not (vequal v0 v1)) (snd-display #__line__ "~%;trouble in reverse read ~A ~A" v0 v1)))) (revert-sound)) (list 150 1500 150000)) (close-sound ind)) (let ((ind (new-sound "test.snd" 1 22050 mus-ldouble mus-next))) (insert-silence 0 1000) (map-channel (lambda (y) 1.0)) (env-sound '(0 0 1 1 2 0)) (scale-channel 0.0 100 200) (let ((reader (make-sampler (- (framples) 1) ind 0 -1))) (map-channel (lambda (y) (read-sample reader)))) (let ((e (make-env '(0 0 1 1 2 0) :length 1001)) (new-reader (make-sampler 0 ind 0)) (len (framples))) (call-with-exit (lambda (quit) (do ((old (env e) (env e)) (new (read-sample new-reader) (read-sample new-reader)) (i 0 (+ i 1))) ((= i len)) (if (or (and (or (> i 900) (<= i 700)) (fneq old new)) (and (> i 700) (<= i 900) (fneq new 0.0))) (begin (format #t "~%;trouble in reverse read 2 at ~D ~A ~A" i old new) (quit))))))) (close-sound ind)) (let ((ind (new-sound "test.snd" 1 22050 mus-ldouble mus-next))) (insert-silence 0 150000) (map-channel (lambda (y) 1.0)) (let ((edpos (edit-position))) (do ((i 0 (+ i 1))) ((= i 7)) (if (= i 5) (scale-channel 0.5 1000 12345)) (env-sound '(0 0 1 1 2.5 0 3 1 4 0)) (if (= i 1) (delete-samples 50 100) (if (= i 2) (insert-samples 300 100 (make-float-vector 100 0.5)) (if (= i 3) (scale-channel 0.0 1000 1000) (if (= i 4) (float-vector->channel (make-float-vector 100 .5) 500 100) (if (= i 6) (env-sound '(0 1 1 0) 10000 2000)))))) (let ((reader (make-sampler (- (framples) 1) ind 0 -1))) (map-channel (lambda (y) (read-sample reader)))) (let ((reader (make-sampler (- (framples) 1) ind 0 -1))) (map-channel (lambda (y) (read-sample reader)))) (let ((len (framples))) (let ((v0 (samples 0 len ind 0 (- (edit-position ind 0) 2))) (v1 (samples 0 len ind 0))) (if (not (vequal v0 v1)) (snd-display #__line__ "~%;trouble in reverse read ~A ~A" v0 v1)))) (set! (edit-position ind 0) edpos))) (close-sound ind)) (let ((reader #f) (last-proc #f)) (define (scan-again) (and (not (sampler-at-end? reader)) (let ((val (last-proc (reader)))) (if val (list val (- (sampler-position reader) 1)) (scan-again))))) (define* (my-scan-channel proc) (if proc (begin (set! last-proc proc) (set! reader (make-sampler 0)))) (scan-again)) (let ((ind (open-sound "oboe.snd")) (val #f)) (let ((samp (sample 1000))) (set! (cursor ind 0) 1000) (if (fneq (sample) samp) (snd-display #__line__ ";sample no args: ~A ~A" (sample) samp))) (set! val (my-scan-channel (lambda (y) (> y .1)))) (if (not (equal? val (list #t 4423))) (snd-display #__line__ ";my-scan-chan: ~A" val)) (set! val (scan-again)) (if (not (equal? val (list #t 4463))) (snd-display #__line__ ";scan-again: ~A" val)) (set! (cursor) 1000) (set! (sample) .5) (if (fneq (sample 1000) .5) (snd-display #__line__ ";set sample no arg: ~A ~A" (sample 1000) (sample 0))) (close-sound ind))) ;; edit-menu.scm tests (if (defined? 'selection->new) (let ((ind (view-sound "oboe.snd"))) (make-selection 1000 1999 ind 0) (let ((newsnd (selection->new))) (if (not (sound? newsnd)) (snd-display #__line__ ";selection->new -> ~A" newsnd)) (if (not (= (framples newsnd 0) 1000)) (snd-display #__line__ ";selection->new framples: ~A" (framples newsnd 0))) (if (not (equal? (edits ind 0) (list 0 0))) (snd-display #__line__ ";selection->new edited original? ~A" (edits ind 0))) (let ((newfile (file-name newsnd))) (close-sound newsnd) (delete-file newfile) (mus-sound-forget newfile))) (make-selection 1000 1999 ind 0) (let ((newsnd (cut-selection->new))) (if (not (sound? newsnd)) (snd-display #__line__ ";cut-selection->new -> ~A" newsnd)) (if (not (= (framples newsnd 0) 1000)) (snd-display #__line__ ";cut-selection->new framples: ~A" (framples newsnd 0))) (if (not (equal? (edits ind 0) (list 1 0))) (snd-display #__line__ ";cut-selection->new did not edit original? ~A" (edits ind 0))) (if (not (= (framples ind 0) (- (framples ind 0 0) 1000))) (snd-display #__line__ ";cut-selection->new cut: ~A ~A" (framples ind 0) (- (framples ind 0 0) 1000))) (undo 1 ind 0) (let ((newfile (file-name newsnd))) (close-sound newsnd) (delete-file newfile) (mus-sound-forget newfile))) (make-selection 1000 1999 ind 0) (append-selection) (if (not (= (framples ind 0) (+ (framples ind 0 0) 1000))) (snd-display #__line__ ";append-selection: ~A ~A" (framples ind 0) (framples ind 0 0))) (append-sound "oboe.snd") (if (not (= (framples ind 0) (+ (* 2 (framples ind 0 0)) 1000))) (snd-display #__line__ ";append-sound: ~A ~A" (framples ind 0) (framples ind 0 0))) (revert-sound ind) (let ((m1 (add-mark 1000)) (m2 (add-mark 12000))) (trim-front) (if (not (equal? (edits ind 0) (list 1 0))) (snd-display #__line__ ";time-front did not edit original? ~A" (edits ind 0))) (if (not (= (framples ind 0) (- (framples ind 0 0) 1000))) (snd-display #__line__ ";trim-front: ~A ~A" (framples ind 0) (- (framples ind 0 0) 1000))) (if (not (= (mark-sample m2) 11000)) (snd-display #__line__ ";trim-front m2: ~A" (mark-sample m2))) (undo 1 ind 0) (trim-back) (if (not (equal? (edits ind 0) (list 1 0))) (snd-display #__line__ ";time-back did not edit original? ~A" (edits ind 0))) (if (not (= (framples ind 0) 12001)) (snd-display #__line__ ";trim-back: ~A" (framples ind 0))) (if (not (= (mark-sample m1) 1000)) (snd-display #__line__ ";trim-back m1: ~A" (mark-sample m1))) (undo 1 ind 0) (add-mark 22000) (crop) (if (not (equal? (edits ind 0) (list 1 0))) (snd-display #__line__ ";crop did not edit original? ~A" (edits ind 0))) (if (not (= (framples ind 0) 21001)) (snd-display #__line__ ";crop: ~A" (framples ind 0))) (undo 1 ind 0) (close-sound ind)))) (let ((ind (new-sound "test.snd"))) (map-channel (lambda (y) 1.0) 0 1001) (env-channel (make-env '(0 1 1 1) :scaler .5 :length 1001)) (check-maxamp #__line__ ind .5 "simple scaler") (check-env-vals "simple scaler" (make-env '(0 1 1 1) :scaler .5 :length 1001)) (if (= (edit-position) 2) (undo) (snd-display #__line__ ";env+scl was no-op")) (env-channel (make-env '(0 1 1 1) :offset .5 :length 1001)) (check-maxamp #__line__ ind 1.5 "simple offset") (check-env-vals "simple offset" (make-env '(0 1 1 1) :offset .5 :length 1001)) (if (= (edit-position) 2) (undo) (snd-display #__line__ ";env+offset was no-op")) (env-channel (make-env '(0 0 1 1 2 0) :offset .5 :scaler 2.0 :length 1001)) (check-maxamp #__line__ ind 2.5 "off+scl") (check-env-vals "off+scl" (make-env '(0 0 1 1 2 0) :offset .5 :scaler 2.0 :length 1001)) (undo) (env-channel (make-env '(0 -0.5 1 0 2 -1) :offset .5 :scaler 2.0 :length 1001)) (check-maxamp #__line__ ind 1.5 "off+scl #2") (let ((mx -12.0)) (scan-channel (lambda (y) (not (set! mx (max mx y))))) (if (fneq mx 0.5) (snd-display #__line__ ";non abs max: ~A (correct: 0.5)" mx))) (check-env-vals "off+scl #2" (make-env '(0 -0.5 1 0 2 -1) :offset .5 :scaler 2.0 :length 1001)) (undo) (env-sound '(0 .5 1 .75 2 .25) 0 (framples) 32.0) (check-maxamp #__line__ ind 0.75 "xramp") (check-env-vals "xramp" (make-env '(0 .5 1 .75 2 .25) :base 32.0 :length 1001)) (undo) (env-channel-with-base '(0 .5 1 .75 2 .25) 32.0) (check-maxamp #__line__ ind 0.75 "xramp1") (check-env-vals "xramp1" (make-env '(0 .5 1 .75 2 .25) :base 32.0 :length 1001)) (close-sound ind)) (let ((hlb (make-hilbert-transform 8)) (data (make-float-vector 20))) (do ((i 0 (+ i 1))) ((= i 20)) (set! (data i) (hilbert-transform hlb (if (= i 0) 1.0 0.0)))) (if (not (vequal data (float-vector 0.0 -0.010 0.0 -0.046 0.0 -0.152 0.0 -0.614 0.0 0.614 0.0 0.152 0.0 0.046 0.0 0.010 0.0 0.0 0.0 0.0))) (snd-display #__line__ ";hilbert-transform 8 impulse response: ~A" data))) (let ((hlb (make-hilbert-transform 7)) (data (make-float-vector 20))) (do ((i 0 (+ i 1))) ((= i 20)) (set! (data i) (hilbert-transform hlb (if (= i 0) 1.0 0.0)))) (if (not (vequal data (float-vector -0.007 0.0 -0.032 0.0 -0.136 0.0 -0.608 0.0 0.608 0.0 0.136 0.0 0.032 0.0 0.007 0.0 0.0 0.0 0.0 0.0))) (snd-display #__line__ ";hilbert-transform 7 impulse response: ~A" data))) (let ((ind (new-sound "test.snd"))) (pad-channel 0 1000) (set! (sample 100) 1.0) (let ((h (make-hilbert-transform 100))) (map-channel (lambda (y) (hilbert-transform h y))) (map-channel (lambda (y) (hilbert-transform h y))) (map-channel (lambda (y) (hilbert-transform h y))) (map-channel (lambda (y) (hilbert-transform h y))) ;; now ideally we'd be back to an impulse (if (> (abs (- (sample 500) .98)) .01) (snd-display #__line__ ";hilbert impulse: ~A" (sample 500))) (set! (sample 500) 0.0) (if (> (maxamp ind 0) .02) (snd-display #__line__ ";hilbert sidelobes: ~A" (maxamp ind 0))) (scale-channel 0.0) (set! (sample 100) 1.0) (set! h (make-hilbert-transform 101)) (map-channel (lambda (y) (hilbert-transform h y))) (map-channel (lambda (y) (hilbert-transform h y))) (map-channel (lambda (y) (hilbert-transform h y))) (map-channel (lambda (y) (hilbert-transform h y))) (if (> (abs (- (sample 504) .98)) .01) (snd-display #__line__ ";hilbert 101 impulse: ~A: ~A" (sample 504) (channel->float-vector 498 10))) (set! (sample 504) 0.0) (if (> (maxamp ind 0) .02) (snd-display #__line__ ";hilbert 101 sidelobes: ~A" (maxamp ind 0))) (revert-sound)) (pad-channel 0 1000) (set! (sample 100) 1.0) (let ((lo (make-lowpass (* .1 pi) 20)) (hi (make-highpass (* .1 pi) 20))) (map-channel (lambda (y) (+ (lowpass lo y) (highpass hi y)))) (if (fneq (sample 120) 1.0) (snd-display #__line__ ";lowpass+highpass impulse: ~A" (sample 120))) (set! (sample 120) 0.0) (if (fneq (maxamp ind 0) 0.0) (snd-display #__line__ ";lowpass+highpass sidelobes: ~A" (maxamp ind 0)))) (undo 2) (let ((lo (make-bandpass (* .1 pi) (* .2 pi) 20)) (hi (make-bandstop (* .1 pi) (* .2 pi) 20))) (map-channel (lambda (y) (+ (bandpass lo y) (bandstop hi y)))) (if (fneq (sample 120) 1.0) (snd-display #__line__ ";bandpass+bandstop impulse: ~A" (sample 120))) (set! (sample 120) 0.0) (if (fneq (maxamp ind 0) 0.0) (snd-display #__line__ ";bandpass+bandstop sidelobes: ~A" (maxamp ind 0)))) (close-sound ind)) (let ((ind (new-sound "test.snd"))) (map-channel (lambda (y) (mus-random 1.0)) 0 10000) (let ((f2 (make-bandpass-2 (* .12 pi) (* .15 pi) (* .22 pi) (* .25 pi) 100))) (map-channel (lambda (y) (fir-filter f2 y))) (let ((data (channel->float-vector))) (undo) (let ((f1 (make-bandpass (* .12 pi) (* .15 pi) 100)) (f2 (make-bandpass (* .22 pi) (* .25 pi) 100))) (map-channel (lambda (y) (+ (fir-filter f1 y) (fir-filter f2 y)))) (let ((data1 (channel->float-vector))) (float-vector-subtract! data data1) (if (> (float-vector-peak data) .00001) (snd-display #__line__ ";fir-filter 2: ~A" (float-vector-peak data)))) (undo)))) (close-sound ind)) (reset-all-hooks) (let ((ind (new-sound "test.snd" 1 22050 mus-ldouble mus-next "first ramp re-order tests" 100))) (map-channel (lambda (y) 1.0)) (for-each (lambda (lst) (let ((name (car lst)) (try-scale (cadr lst)) (f1 (caddr lst)) (f2 (cadddr lst)) (edpos (edit-position ind 0))) (f1) (let ((v1 (channel->float-vector 0 100 ind 0))) (set! (edit-position ind 0) edpos) (f2) (let ((v2 (channel->float-vector 0 100 ind 0))) (if (not (vequal v1 v2)) (snd-display #__line__ ";env reordering test ~A:~%; ~A~%; ~A" name v1 v2)) (set! (edit-position ind 0) edpos))) (if try-scale (begin (scale-by 2.0) (f1) (let ((v1 (channel->float-vector 0 100 ind 0))) (set! (edit-position ind 0) edpos) (f2) (scale-by 2.0) (let ((v2 (channel->float-vector 0 100 ind 0))) (if (not (vequal v1 v2)) (snd-display #__line__ ";scaled (2) env reordering test ~A:~%; ~A~%; ~A" name v1 v2)) (set! (edit-position ind 0) edpos))) (f1) (scale-by .5) (let ((v1 (channel->float-vector 0 100 ind 0))) (set! (edit-position ind 0) edpos) (scale-by .5) (f2) (let ((v2 (channel->float-vector 0 100 ind 0))) (if (not (vequal v1 v2)) (snd-display #__line__ ";scaled (.5) env reordering test ~A:~%; ~A~%; ~A" name v1 v2)) (set! (edit-position ind 0) edpos))))))) (list (list "ramp-xramp" #t (lambda () (env-sound '(0 0 1 1 2 0)) (env-sound '(0 0 1 1) 0 100 2.0)) (lambda () (env-sound '(0 0 1 1) 0 100 2.0) (env-sound '(0 0 1 1 2 0)))) (list "ramp2-xramp (1)" #t (lambda () (env-sound '(0 0 1 1 2 0)) (env-sound '(0 0 1 1 3 0)) (env-sound '(0 0 1 1) 0 100 2.0)) (lambda () (env-sound '(0 0 1 1 2 0)) (env-sound '(0 0 1 1) 0 100 2.0) (env-sound '(0 0 1 1 3 0)))) (list "ramp2-xramp (2)" #t (lambda () (env-sound '(0 0 1 1 2 0)) (env-sound '(0 0 1 1)) (env-sound '(0 0 1 1 3 0) 0 100 2.0)) (lambda () (env-sound '(0 0 1 1 3 0) 0 100 2.0) (env-sound '(0 0 1 1 2 0)) (env-sound '(0 0 1 1)))) (list "xramp2-ramp (1)" #t (lambda () (env-sound '(0 0 1 1 2 0) 0 100 2.0) (env-sound '(0 0 1 1)) (env-sound '(0 0 1 1 3 0) 0 100 3.0)) (lambda () (env-sound '(0 0 1 1 2 0) 0 100 2.0) (env-sound '(0 0 1 1 3 0) 0 100 3.0) (env-sound '(0 0 1 1)))) (list "xramp2-ramp (2)" #t (lambda () (env-sound '(0 0 1 1 2 0) 0 100 2.0) (env-sound '(0 0 1 1 3 0)) (env-sound '(0 0 1 1) 0 100 3.0)) (lambda () (env-sound '(0 0 1 1 3 0)) (env-sound '(0 0 1 1 2 0) 0 100 2.0) (env-sound '(0 0 1 1) 0 100 3.0))) )) (close-sound ind)) )) (let ((ind (open-sound "oboe.snd"))) ;; simple cases (as-one-edit (lambda () (set! (sample 10) 1.0))) (if (fneq (sample 10) 1.0) (snd-display #__line__ ";as-one-edit 1: ~A" (sample 10))) (if (not (= (edit-position ind 0) 1)) (snd-display #__line__ ";as-one-edit 1 edpos: ~A" (edit-position ind 0)) (begin (if (not (equal? (edit-fragment 1 ind 0) (list "set-sample 10 1.0000" "set" 10 1))) (snd-display #__line__ ";as-one-edit 1 edlist: ~A" (edit-fragment 1 ind 0))) (if (not (equal? (edit-fragment 0 ind 0) (list "" "init" 0 50828))) (snd-display #__line__ ";as-one-edit 1 original edlist: ~A" (edit-fragment 0 ind 0))))) (revert-sound ind) (as-one-edit (lambda () (set! (sample 10) 1.0) (map-channel (lambda (y) (* y 2.0)) 0 20 ind 0 #f "map-channel as-one-edit") (if (not (= (edit-position ind 0) 2)) (snd-display #__line__ ";as-one-edit 2 edpos internal: ~A" (edit-position ind 0)))) "as-one-edit test-2") (if (fneq (sample 10) 2.0) (snd-display #__line__ ";as-one-edit 2: ~A" (sample 10))) (if (not (= (edit-position ind 0) 1)) (snd-display #__line__ ";as-one-edit 2 edpos: ~A" (edit-position ind 0)) (if (not (equal? (edit-fragment 0 ind 0) (list "" "init" 0 50828))) (snd-display #__line__ ";as-one-edit 2 original edlist: ~A" (edit-fragment 0 ind 0)))) (revert-sound ind) (let ((ind2 (open-sound "2a.snd"))) (set! (sample 1 ind2 0) 1.0) (set! (sample 2 ind2 1) 0.5) (set! (selected-sound) ind) (as-one-edit (lambda () (set! (sample 10 ind 0) 1.0))) (if (fneq (sample 10 ind 0) 1.0) (snd-display #__line__ ";as-one-edit 3: ~A" (sample 10 ind 0))) (if (not (= (edit-position ind 0) 1)) (snd-display #__line__ ";as-one-edit 3 edpos: ~A" (edit-position ind 0))) (if (not (= (edit-position ind2 0) 1)) (snd-display #__line__ ";as-one-edit 3 2 edpos: ~A" (edit-position ind2 0))) (if (not (= (edit-position ind2 1) 1)) (snd-display #__line__ ";as-one-edit 3 2 1 edpos: ~A" (edit-position ind2 1))) (if (not (equal? (edit-fragment 1 ind 0) (list "set-sample 10 1.0000" "set" 10 1))) (snd-display #__line__ ";as-one-edit 3 edlist: ~A" (edit-fragment 1 ind 0))) (if (not (equal? (edit-fragment 1 ind2 0) (list "set-sample 1 1.0000" "set" 1 1))) (snd-display #__line__ ";as-one-edit 3 2 edlist: ~A" (edit-fragment 1 ind2 0))) (if (not (equal? (edit-fragment 1 ind2 1) (list "set-sample 2 0.5000" "set" 2 1))) (snd-display #__line__ ";as-one-edit 3 2 1 edlist: ~A" (edit-fragment 1 ind2 1))) (revert-sound ind) (as-one-edit (lambda () (set! (sample 10 ind 0) 1.0) (map-channel (lambda (y) (* y 2.0)) 0 20 ind 0 #f "map-channel as-one-edit 2") (if (not (= (edit-position ind 0) 2)) (snd-display #__line__ ";as-one-edit 4 edpos internal: ~A" (edit-position ind 0)))) "as-one-edit test-4") (if (fneq (sample 10) 2.0) (snd-display #__line__ ";as-one-edit 4: ~A" (sample 10 ind 0))) (if (not (= (edit-position ind 0) 1)) (snd-display #__line__ ";as-one-edit 4 edpos: ~A" (edit-position ind 0))) (if (not (equal? (edit-fragment 1 ind2 0) (list "set-sample 1 1.0000" "set" 1 1))) (snd-display #__line__ ";as-one-edit 3 2 edlist: ~A" (edit-fragment 1 ind2 0))) (if (not (equal? (edit-fragment 1 ind2 1) (list "set-sample 2 0.5000" "set" 2 1))) (snd-display #__line__ ";as-one-edit 3 2 1 edlist: ~A" (edit-fragment 1 ind2 1))) (revert-sound ind) (set! (sample 3 ind 0) 1.0) (as-one-edit (lambda () (set! (sample 10 ind 0) 1.0) (set! (sample 10 ind2 0) 0.5) (set! (sample 10 ind2 1) 0.4))) (if (fneq (sample 3 ind 0) 1.0) (snd-display #__line__ ";as-one-edit 5 (3): ~A" (sample 3 ind 0))) (if (fneq (sample 10 ind 0) 1.0) (snd-display #__line__ ";as-one-edit 5 (10): ~A" (sample 10 ind 0))) (if (fneq (sample 10 ind2 0) 0.5) (snd-display #__line__ ";as-one-edit 5 (2 10): ~A" (sample 10 ind2 0))) (if (fneq (sample 10 ind2 1) 0.4) (snd-display #__line__ ";as-one-edit 5 (2 1 10): ~A" (sample 10 ind2 1))) (if (not (= (edit-position ind 0) 2)) (snd-display #__line__ ";as-one-edit 5 edpos: ~A" (edit-position ind 0))) (if (not (= (edit-position ind2 0) 2)) (snd-display #__line__ ";as-one-edit 5 2 edpos: ~A" (edit-position ind2 0))) (if (not (= (edit-position ind2 1) 2)) (snd-display #__line__ ";as-one-edit 5 2 1 edpos: ~A" (edit-position ind2 1))) (if (not (equal? (edit-fragment 2 ind 0) (list "set-sample 10 1.0000" "set" 10 1))) (snd-display #__line__ ";as-one-edit 5 edlist 2: ~A" (edit-fragment 1 ind 0))) (if (not (equal? (edit-fragment 1 ind 0) (list "set-sample 3 1.0000" "set" 3 1))) (snd-display #__line__ ";as-one-edit 5 edlist 1: ~A" (edit-fragment 1 ind 0))) (if (not (equal? (edit-fragment 0 ind 0) (list "" "init" 0 50828))) (snd-display #__line__ ";as-one-edit 5 original edlist: ~A" (edit-fragment 0 ind 0))) (if (not (equal? (edit-fragment 2 ind2 0) (list "set-sample 10 0.5000" "set" 10 1))) (snd-display #__line__ ";as-one-edit 5 edlist 2 1: ~A" (edit-fragment 1 ind2 0))) (as-one-edit (lambda () (map-channel (lambda (y) (* y 2.0)) 0 20 ind 0 #f "map-channel as-one-edit 6") (map-channel (lambda (y) (* y 2.0)) 0 20 ind2 1 #f "map-channel as-one-edit 6 2 1")) "as-one-edit test-6") (if (fneq (sample 3 ind 0) 2.0) (snd-display #__line__ ";as-one-edit 6 (3): ~A" (sample 3 ind 0))) (if (fneq (sample 10 ind 0) 2.0) (snd-display #__line__ ";as-one-edit 6 (10): ~A" (sample 10 ind 0))) (if (fneq (sample 10 ind2 0) 0.5) (snd-display #__line__ ";as-one-edit 6 (2 10): ~A" (sample 10 ind2 0))) (if (fneq (sample 10 ind2 1) 0.8) (snd-display #__line__ ";as-one-edit 6 (2 1 10): ~A" (sample 10 ind2 1))) (if (not (= (edit-position ind 0) 3)) (snd-display #__line__ ";as-one-edit 6 edpos: ~A" (edit-position ind 0))) (if (not (= (edit-position ind2 0) 2)) (snd-display #__line__ ";as-one-edit 6 2 edpos: ~A" (edit-position ind2 0))) (if (not (= (edit-position ind2 1) 3)) (snd-display #__line__ ";as-one-edit 6 2 1 edpos: ~A" (edit-position ind2 1))) (if (not (equal? (edit-fragment 2 ind 0) (list "set-sample 10 1.0000" "set" 10 1))) (snd-display #__line__ ";as-one-edit 5 edlist 2: ~A" (edit-fragment 1 ind 0))) (if (not (equal? (edit-fragment 2 ind2 0) (list "set-sample 10 0.5000" "set" 10 1))) (snd-display #__line__ ";as-one-edit 5 edlist 2 1: ~A" (edit-fragment 1 ind2 0))) (close-sound ind2)) ;; nested cases (revert-sound ind) (as-one-edit (lambda () (set! (sample 100) .9) (as-one-edit (lambda () (set! (sample 200) .8) (set! (sample 300) .7))) (set! (sample 300) .6))) (if (or (fneq (sample 100) .9) (fneq (sample 200) .8) (fneq (sample 300) .6)) (snd-display #__line__ ";nested as-one-edit 7: ~A ~A ~A" (sample 100) (sample 200) (sample 300))) (if (not (= (edit-position ind 0) 1)) (snd-display #__line__ ";nested as-one-edit 7 edpos: ~A" (edit-position ind 0))) (if (squelch-update ind 0) (begin (snd-display #__line__ ";nested as-one-edit 7 squelch is on") (set! (squelch-update) #f))) (if (not (equal? (edit-fragment 1 ind 0) (list "set-sample 300 0.6000" "set" 100 204))) (snd-display #__line__ ";as-one-edit 7 edlist: ~A" (edit-fragment 1 ind 0))) (revert-sound ind) (as-one-edit (lambda () (set! (sample 100) .9) (as-one-edit (lambda () (set! (sample 200) .8) (set! (sample 300) .7))) (set! (sample 300) .6)) "as-one-edit test-8") (if (or (fneq (sample 100) .9) (fneq (sample 200) .8) (fneq (sample 300) .6)) (snd-display #__line__ ";nested as-one-edit 8: ~A ~A ~A" (sample 100) (sample 200) (sample 300))) (if (not (= (edit-position ind 0) 1)) (snd-display #__line__ ";nested as-one-edit 8 edpos: ~A" (edit-position ind 0))) (if (not (equal? (edit-fragment 1 ind 0) (list "as-one-edit test-8" "set" 100 204))) (snd-display #__line__ ";as-one-edit 8 edlist: ~A" (edit-fragment 1 ind 0))) (revert-sound ind) (as-one-edit (lambda () (set! (sample 100) .9) (as-one-edit (lambda () (set! (sample 200) .8) (set! (sample 300) .7)) "as-one-edit 9 internal") (set! (sample 300) .6)) "as-one-edit test-9") (if (or (fneq (sample 100) .9) (fneq (sample 200) .8) (fneq (sample 300) .6)) (snd-display #__line__ ";nested as-one-edit 9: ~A ~A ~A" (sample 100) (sample 200) (sample 300))) (if (not (= (edit-position ind 0) 1)) (snd-display #__line__ ";nested as-one-edit 9 edpos: ~A" (edit-position ind 0))) (if (not (equal? (edit-fragment 1 ind 0) (list "as-one-edit test-9" "set" 100 204))) (snd-display #__line__ ";as-one-edit 9 edlist: ~A" (edit-fragment 1 ind 0))) (revert-sound ind) (as-one-edit (lambda () (set! (sample 100) .9) (as-one-edit (lambda () (set! (sample 200) .8) (as-one-edit (lambda () (set! (sample 400) .3)) "not a name") (set! (sample 300) .7)) "as-one-edit 10 internal") (set! (sample 300) .6)) "as-one-edit test-10") (if (or (fneq (sample 100) .9) (fneq (sample 200) .8) (fneq (sample 300) .6) (fneq (sample 400) .3)) (snd-display #__line__ ";nested as-one-edit 10: ~A ~A ~A ~A" (sample 100) (sample 200) (sample 300) (sample 400))) (if (not (= (edit-position ind 0) 1)) (snd-display #__line__ ";nested as-one-edit 10 edpos: ~A" (edit-position ind 0))) (if (not (equal? (edit-fragment 1 ind 0) (list "as-one-edit test-10" "set" 100 305))) (snd-display #__line__ ";as-one-edit 10 edlist: ~A" (edit-fragment 1 ind 0))) ;; try implicit as-one-edits nested (revert-sound ind) (env-channel-with-base '(0 0 1 1 2 .5 3 .25 4 0) 0.0 0 #f ind 0) (if (not (= (edit-position ind 0) 1)) (snd-display #__line__ ";as-one-edit 11 edpos: ~A" (edit-position ind 0))) (if (not (equal? (edit-fragment 1 ind 0) (list "env-channel-with-base '(0.000 0.000 1.000 1.000 2.000 0.500 3.000 0.250 4.000 0.000) 0.0000 0 #f" "scale" 0 50830))) (snd-display #__line__ ";as-one-edit 11: ~A" (edit-fragment 1 ind 0))) (revert-sound ind) (as-one-edit (lambda () (env-channel-with-base '(0 0 1 1 2 .5 3 .25 4 0) 0.0 0 #f ind 0)) "as-one-edit 12") (if (not (= (edit-position ind 0) 1)) (snd-display #__line__ ";as-one-edit 12 edpos: ~A" (edit-position ind 0))) (if (not (equal? (edit-fragment 1 ind 0) (list "as-one-edit 12" "scale" 0 50830))) (snd-display #__line__ ";as-one-edit 12: ~A" (edit-fragment 1 ind 0))) (revert-sound ind) (let ((m1 #f) (m2 #f) (m3 #f) (m4 #f)) (as-one-edit (lambda () (set! m1 (add-mark 1234 ind 0)) (set! (sample 1236 ind 0) .6) (as-one-edit (lambda () (set! (sample 123 ind 0) .3) (set! m2 (add-mark 1235 ind 0))) "as-one-edit inner 1") (if (not (mark? m1)) (snd-display #__line__ ";as-one-edit stepped on m1: ~A" m1)) (if (not (mark? m2)) (snd-display #__line__ ";as-one-edit stepped on m2: ~A" m2)) (as-one-edit (lambda () (set! m3 (add-mark 1238 ind 0)) (set! (sample 1238 ind 0) .8)) "as-one-edit inner 2") (set! (sample 1239 ind 0) .9) (set! m4 (add-mark 1237 ind 0))) "outer as-one-edit") (if (not (mark? m1)) (snd-display #__line__ ";second as-one-edit stepped on m1: ~A" m1)) (if (not (mark? m2)) (snd-display #__line__ ";second as-one-edit stepped on m2: ~A" m2)) (if (not (mark? m3)) (snd-display #__line__ ";second as-one-edit stepped on m3: ~A" m3)) (if (not (mark? m4)) (snd-display #__line__ ";second as-one-edit stepped on m4: ~A" m4)) (if (not (= (mark-sample m1) 1234)) (snd-display #__line__ ";as-one-edit m1 sample: ~A (1234)" (mark-sample m1))) (if (not (= (mark-sample m2) 1235)) (snd-display #__line__ ";as-one-edit m2 sample: ~A (1235)" (mark-sample m2))) (if (not (= (mark-sample m3) 1238)) (snd-display #__line__ ";as-one-edit m3 sample: ~A (1238)" (mark-sample m3))) (if (not (= (mark-sample m4) 1237)) (snd-display #__line__ ";as-one-edit m4 sample: ~A (1237)" (mark-sample m4))) (if (not (string=? (display-edits ind 0) (string-append " EDITS: 1 (begin) [0:2]: (at 0, cp->sounds[0][0:50827, 1.000]) [file: " cwd "oboe.snd[0]] (at 50828, end_mark) (set 123 1120) ; outer as-one-edit [1:9]: (at 0, cp->sounds[0][0:122, 1.000]) [file: " cwd "oboe.snd[0]] (at 123, cp->sounds[2][0:0, 1.000]) [buf: 1] (at 124, cp->sounds[0][124:1235, 1.000]) [file: " cwd "oboe.snd[0]] (at 1236, cp->sounds[1][0:0, 1.000]) [buf: 1] (at 1237, cp->sounds[0][1237:1237, 1.000]) [file: " cwd "oboe.snd[0]] (at 1238, cp->sounds[3][0:0, 1.000]) [buf: 1] (at 1239, cp->sounds[4][0:0, 1.000]) [buf: 1] (at 1240, cp->sounds[0][1240:50827, 1.000]) [file: " cwd "oboe.snd[0]] (at 50828, end_mark) "))) (snd-display #__line__ ";as-one-edit edits: ~A" (display-edits ind 0))) (revert-sound ind)) (let ((m1 #f) (m2 #f) (m3 #f) (m4 #f)) (as-one-edit (lambda () (set! m1 (mix-float-vector (float-vector .1 .2 .3) 1234 ind 0)) (set! (sample 1236 ind 0) .6) (as-one-edit (lambda () (set! (sample 123 ind 0) .3) (set! m2 (mix-float-vector (float-vector .1 .2 .3) 1235 ind 0))) "as-one-edit inner 1") (if (not (mix? m1)) (snd-display #__line__ ";as-one-edit stepped on m1: ~A" m1)) (if (not (mix? m2)) (snd-display #__line__ ";as-one-edit stepped on m2: ~A" m2)) (as-one-edit (lambda () (set! m3 (mix-float-vector (float-vector .1 .2 .3) 1238 ind 0)) (set! (sample 1238 ind 0) .8)) "as-one-edit inner 2") (set! (sample 1239 ind 0) .9) (set! m4 (mix-float-vector (float-vector .1 .2 .3) 1237 ind 0))) "outer as-one-edit") (if (not (mix? m1)) (snd-display #__line__ ";second as-one-edit stepped on mx1: ~A" m1)) (if (not (mix? m2)) (snd-display #__line__ ";second as-one-edit stepped on mx2: ~A" m2)) (if (not (mix? m3)) (snd-display #__line__ ";second as-one-edit stepped on mx3: ~A" m3)) (if (not (mix? m4)) (snd-display #__line__ ";second as-one-edit stepped on mx4: ~A" m4)) (revert-sound ind)) (let ((ind2 #f)) (as-one-edit (lambda () (set! ind2 (open-sound "pistol.snd")) (set! (sample 100 ind 0) .5) (set! (sample 200 ind2 0) .6)) "as-one-edit+open") (if (not (sound? ind2)) (snd-display #__line__ ";as-one-edit didn't open sound? ~A ~A" ind2 (sounds))) (if (not (= (edit-position ind2 0) 1)) (snd-display #__line__ ";edpos as-one-edit opened sound: ~A" (edit-position ind2 0))) (if (not (= (edit-position ind 0) 1)) (snd-display #__line__ ";edpos as-one-edit original sound: ~A" (edit-position ind 0))) (if (not (equal? (edit-fragment 1 ind 0) (list "as-one-edit+open" "set" 100 1))) (snd-display #__line__ ";as-one-edit open sound edlist orig: ~A" (edit-fragment 1 ind 0))) (if (not (equal? (edit-fragment 1 ind2 0) (list "set-sample 200 0.6000" "set" 200 1))) (snd-display #__line__ ";as-one-edit open sound edlist new: ~A" (edit-fragment 1 ind2 0))) (as-one-edit (lambda () (set! (sample 200 ind 0) .7) (close-sound ind2)) "as-one-edit+close") (if (sound? ind2) (begin (snd-display #__line__ ";as-one-edit didn't close sound? ~A ~A" ind2 (sounds)) (close-sound ind2))) (if (not (= (edit-position ind 0) 2)) (snd-display #__line__ ";edpos as-one-edit close original sound: ~A" (edit-position ind 0))) (if (not (string=? (display-edits ind 0) (string-append " EDITS: 2 (begin) [0:2]: (at 0, cp->sounds[0][0:50827, 1.000]) [file: " cwd "oboe.snd[0]] (at 50828, end_mark) (set 100 1) ; as-one-edit+open [1:4]: (at 0, cp->sounds[0][0:99, 1.000]) [file: " cwd "oboe.snd[0]] (at 100, cp->sounds[1][0:0, 1.000]) [buf: 1] (at 101, cp->sounds[0][101:50827, 1.000]) [file: " cwd "oboe.snd[0]] (at 50828, end_mark) (set 200 1) ; as-one-edit+close [2:6]: (at 0, cp->sounds[0][0:99, 1.000]) [file: " cwd "oboe.snd[0]] (at 100, cp->sounds[1][0:0, 1.000]) [buf: 1] (at 101, cp->sounds[0][101:199, 1.000]) [file: " cwd "oboe.snd[0]] (at 200, cp->sounds[2][0:0, 1.000]) [buf: 1] (at 201, cp->sounds[0][201:50827, 1.000]) [file: " cwd "oboe.snd[0]] (at 50828, end_mark) "))) (snd-display #__line__ ";as-one-edit open+close: ~A" (display-edits ind 0)))) (close-sound ind)) (let ((ind1 (open-sound "oboe.snd")) (ind2 #f)) (as-one-edit (lambda () (set! (sample 100 ind1 0) .5) (set! ind2 (open-sound "pistol.snd")) (as-one-edit (lambda () (set! (sample 200 ind2 0) .5) (close-sound ind1)) "inner edit") (set! (sample 300 ind2 0) .6)) "outer edit") (if (sound? ind1) (snd-display #__line__ ";as-one-edit close inner: ~A ~A" ind1 (sounds))) (if (not (sound? ind2)) (snd-display #__line__ ";as-one-edit open inner: ~A ~A" ind2 (sounds))) (revert-sound ind2) (as-one-edit (lambda () (set! ind1 (open-sound "oboe.snd")) (as-one-edit (lambda () (set! (sample 200 ind1 0) .5)) "inner edit") (set! (sample 100 ind2 0) .4)) "outer edit") (close-sound ind1) (close-sound ind2)) (let* ((ind (open-sound "oboe.snd")) (mx (maxamp ind 0))) (let ((tag (catch #t (lambda () (as-one-edit (lambda (oops) #f))) (lambda args (car args))))) (if (not (eq? tag 'bad-arity)) (snd-display #__line__ ";as-one-edit arg? ~A" tag))) (let ((tag (catch #t (lambda () (as-one-edit (lambda* (oops) #f))) (lambda args (car args))))) (if (not (eq? tag 'bad-arity)) (snd-display #__line__ ";as-one-edit arg? ~A" tag))) (close-sound ind)) (let ((ind (new-sound "test.snd" 1 22050 mus-ldouble mus-next "more tests" 10))) ;; offset-channel (offset-channel .1) (if (not (vequal (channel->float-vector 0 10) (make-float-vector 10 .1))) (snd-display #__line__ ";offset-channel (.1): ~A" (channel->float-vector 0 10))) (offset-channel -.2 5 5) (if (not (vequal (channel->float-vector 0 10) (float-vector .1 .1 .1 .1 .1 -.1 -.1 -.1 -.1 -.1))) (snd-display #__line__ ";offset-channel (-.1): ~A" (channel->float-vector 0 10))) (undo) (offset-channel .9 0 10 ind 0) (if (not (vequal (channel->float-vector 0 10) (make-float-vector 10 1.0))) (snd-display #__line__ ";offset-channel (1): ~A" (channel->float-vector 0 10))) ;; sine-env and sine-ramp... (revert-sound ind) (map-channel (lambda (y) 1.0)) (sine-ramp 0.0 1.0) (if (not (vequal (channel->float-vector) (float-vector 0.000 0.024 0.095 0.206 0.345 0.500 0.655 0.794 0.905 0.976))) (snd-display #__line__ ";sine-ramp 0 1: ~A" (channel->float-vector))) (revert-sound ind) (offset-channel 1.0) (sine-ramp 1.0 0.0) (if (not (vequal (channel->float-vector) (float-vector 1.000 0.976 0.905 0.794 0.655 0.500 0.345 0.206 0.095 0.024))) (snd-display #__line__ ";sine-ramp 1 0: ~A" (channel->float-vector))) (close-sound ind) (set! ind (new-sound "test.snd" 1 22050 mus-ldouble mus-next "sine-env tests" 100)) (map-channel (lambda (y) 1.0)) (sine-env-channel '(0 0 1 1 2 -.5 3 1)) (if (not (= (edit-position ind 0) 2)) (snd-display #__line__ ";as-one-edit sine-env-channel: ~A" (edit-position ind 0))) (revert-sound ind) (offset-channel -1.0) (sine-env-channel '(0 0 1 1 2 1 3 0) 40 20) (if (or (not (vequal (channel->float-vector 40 20) (float-vector -0.000 -0.050 -0.188 -0.389 -0.611 -0.812 -0.950 -1.000 -1.000 -1.000 -1.000 -1.000 -1.000 -1.000 -1.000 -0.950 -0.812 -0.611 -0.389 -0.188))) (not (vequal (channel->float-vector 30 10) (make-float-vector 10 -1.0)))) (snd-display #__line__ ";off+sine-env: ~A ~A" (channel->float-vector 40 20) (channel->float-vector 30 10))) (revert-sound ind) (scale-by 0.0) (dither-channel) (let ((mx (maxamp))) (if (or (< mx .00003) (> mx .0001)) (snd-display #__line__ ";dithering: ~A" mx))) (revert-sound ind) (map-channel (ring-mod 10 (list 0 0 1 (hz->radians 100)))) (osc-formants .99 (float-vector 400.0 800.0 1200.0) (float-vector 400.0 800.0 1200.0) (float-vector 4.0 2.0 3.0)) (map-channel (zecho .5 .75 6 10.0)) (map-channel (flecho .5 .9)) (filtered-env '(0 0 1 1 2 0)) (map-channel (formant-filter .99 2400)) (map-channel (comb-filter .8 32)) (map-channel (zcomb .8 32 '(0 0 1 10))) (map-channel (notch-filter .8 32)) (let ((ind1 (open-sound "now.snd"))) (select-sound ind1) (if (fneq (maxamp) .309) (snd-display #__line__ ";squelch-vowels init: ~A" (maxamp))) (squelch-vowels) (if (fneq (maxamp) .047) (snd-display #__line__ ";squelch-vowels maxamp: ~A" (maxamp))) (select-sound ind) (map-channel (cross-synthesis ind1 .5 128 6.0)) (revert-sound ind1) (fft-edit 40 8000) (fft-squelch .1) (close-sound ind) (revert-sound ind1) (scramble-channel .01) (revert-sound ind1) (close-sound ind1))) (let ((ind (new-sound "test.snd" 1 22050 mus-ldouble mus-next "special env tests" 100))) (map-channel (lambda (y) 1.0)) (blackman4-ramp 0.0 1.0) (let ((vals (channel->float-vector))) (undo) (blackman4-env-channel '(0 0 1 1)) (let ((new-vals (channel->float-vector))) (if (not (vequal vals new-vals)) (snd-display #__line__ ";blackman4-env-channel/ramp: ~A ~A" vals new-vals)) (undo) (blackman4-ramp 0.0 1.0 0 50) (set! vals (channel->float-vector)) (undo) (blackman4-env-channel '(0 0 1 1 2 1)) (set! new-vals (channel->float-vector)) (if (not (vequal vals new-vals)) (snd-display #__line__ ";blackman4-env-channel/ramp 1: ~A ~A" vals new-vals)) (undo) (blackman4-env-channel '(0 0 1 1 2 -.5 3 0)) (if (not (vequal (channel->float-vector 60 10) (float-vector -0.109 -0.217 -0.313 -0.392 -0.451 -0.488 -0.499 -0.499 -0.499 -0.499))) (snd-display #__line__ ";blackman4 to -.5: ~A" (channel->float-vector 60 10))) (undo) (ramp-squared 0.0 1.0) (set! vals (channel->float-vector)) (undo) (env-squared-channel '(0 0 1 1)) (set! new-vals (channel->float-vector)) (if (not (vequal vals new-vals)) (snd-display #__line__ ";env-squared/ramp: ~A ~A" vals new-vals)) (undo) (ramp-squared 0.0 1.0 #t 0 50) (set! vals (channel->float-vector)) (undo) (env-squared-channel '(0 0 1 1 2 1)) (set! new-vals (channel->float-vector)) (if (not (vequal vals new-vals)) (snd-display #__line__ ";env-squared/ramp 1: ~A ~A" vals new-vals)) (undo) (env-squared-channel '(0 0 1 1 2 -.5 3 0)) (if (not (vequal (channel->float-vector 60 10) (float-vector -0.450 -0.466 -0.478 -0.488 -0.494 -0.499 -0.500 -0.500 -0.498 -0.496))) (snd-display #__line__ ";env-squared to -.5: ~A" (channel->float-vector 60 10))) (undo) (env-squared-channel '(0 0 1 1 2 -.5 3 0) #f) (if (not (vequal (channel->float-vector 60 10) (float-vector -0.004 -0.080 -0.158 -0.240 -0.324 -0.410 -0.500 -0.500 -0.498 -0.496))) (snd-display #__line__ ";env-squared unsymmetric to -.5: ~A" (channel->float-vector 60 10))) (undo) (ramp-squared 0.0 1.0) (set! vals (channel->float-vector)) (undo) (env-expt-channel '(0 0 1 1) 2) (set! new-vals (channel->float-vector)) (if (not (vequal vals new-vals)) (snd-display #__line__ ";env-expt2/ramp: ~A ~A" vals new-vals)) (undo) (env-squared-channel '(0 0 1 1 2 -.5 3 0)) (set! vals (channel->float-vector)) (undo) (env-expt-channel '(0 0 1 1 2 -.5 3 0) 2.0) (set! new-vals (channel->float-vector)) (if (not (vequal vals new-vals)) (snd-display #__line__ ";env-expt2/env-squared: ~A ~A" vals new-vals)) (undo) (env-squared-channel '(0 0 1 1 2 -.5 3 0) #f) (set! vals (channel->float-vector)) (undo) (env-expt-channel '(0 0 1 1 2 -.5 3 0) 2.0 #f) (set! new-vals (channel->float-vector)) (if (not (vequal vals new-vals)) (snd-display #__line__ ";env-expt2/env-squared unsymmetric: ~A ~A" vals new-vals)) (undo) (ramp-expt 0.0 1.0 32.0) (set! vals (channel->float-vector)) (undo) (env-expt-channel '(0 0 1 1) 32.0) (set! new-vals (channel->float-vector)) (if (not (vequal vals new-vals)) (snd-display #__line__ ";env-expt/ramp 32: ~A ~A" vals new-vals)) (undo) (ramp-expt 0.0 1.0 32.0 #f 0 50) (set! vals (channel->float-vector)) (undo) (env-expt-channel '(0 0 1 1 2 1) 32.0) (set! new-vals (channel->float-vector)) (if (not (vequal vals new-vals)) (snd-display #__line__ ";env-expt/ramp 1 32: ~A ~A" vals new-vals)) (undo) (ramp-expt 0.0 1.0 .1) (set! vals (channel->float-vector)) (undo) (env-expt-channel '(0 0 1 1) .1) (set! new-vals (channel->float-vector)) (if (not (vequal vals new-vals)) (snd-display #__line__ ";env-expt/ramp .1: ~A ~A" vals new-vals)) (undo) (env-expt-channel '(0 0 1 1 2 -.5 3 0) 12.0) (if (not (vequal (channel->float-vector 30 10) (float-vector 0.319 0.472 0.691 1.000 0.537 0.208 -0.022 -0.182 -0.291 -0.365))) (snd-display #__line__ ";env-expt to -.5 12.0: ~A" (channel->float-vector 30 10))) (undo) (env-expt-channel '(0 0 1 1 2 -.5 3 0) 12.0 #f) (if (not (vequal (channel->float-vector 30 10) (float-vector 0.319 0.472 0.691 1.000 1.000 1.000 1.000 1.000 1.000 1.000))) (snd-display #__line__ ";env-expt to -.5 12.0 unsymmetric: ~A" (channel->float-vector 30 10))) (undo) (close-sound ind)))) (let ((ind (new-sound "test.snd" 1 22050 mus-ldouble mus-next "third ramp re-order tests" 101))) (offset-channel 1.0) (env-sound '(0 0 1 1)) (contrast-channel 1.0) (let ((reader (make-sampler 0)) (happy #t)) (do ((i 0 (+ i 1)) (val 0.0 (+ val .01))) ((or (not happy) (= i 100))) (let ((y (reader)) (ny (sin (+ (* val 0.5 pi) (* 1.0 (sin (* val 2.0 pi))))))) (if (fneq y ny) (begin (snd-display #__line__ ";contrast-channel: ~A ~A ~A" val y ny) (set! happy #f)))))) (close-sound ind)) (let ((ind0 (open-sound "oboe.snd")) (ind1 (open-sound "pistol.snd"))) (let ((clip (channel-clipped? ind0 0))) (if clip (snd-display #__line__ ";channel-clipped? oboe.snd -> ~A" clip))) (scale-to 1.5 ind0 0) (let ((clip (channel-clipped? ind0 0))) (if (not (member clip (list 4502 4503))) (snd-display #__line__ ";channel-clipped after scale: ~A" clip))) (revert-sound ind0) (ramp-channel 0.0 1.0 0 #f ind1 0) (ramp-channel 0.0 1.0 0 #f ind1 0) (ramp-channel 0.0 1.0 0 #f ind1 0) (ramp-channel 0.0 1.0 0 #f ind1 0) (make-selection 1000 2000 ind1 0) (set! (sync ind0) 1) (set! (selected-sound) ind0) (env-selection '(0 0 1 1)) (if (or (not (= (edit-position ind0 0) 0)) (not (= (edit-position ind1 0) 5))) (snd-display #__line__ ";selection override of sync field: ~A ~A" (edit-position ind0 0) (edit-position ind1 0))) (env-sound '(0 0 1 1 2 0)) (if (or (not (= (edit-position ind0 0) 1)) (not (= (edit-position ind1 0) 5))) (snd-display #__line__ ";sync field over selection: ~A ~A" (edit-position ind0 0) (edit-position ind1 0))) (close-sound ind1) (revert-sound ind0) (close-sound ind0)) (let ((s1 (open-sound "oboe.snd"))) (let ((s2 (copy s1))) (if (not (sound? s2)) (snd-display #__line__ ";copy sound oboe -> ~A" s2) (begin (if (not (= (srate s1) (srate s2))) (snd-display #__line__ ";copy sounds srates: ~A ~A" (srate s1) (srate s2))) (if (not (= (framples s1) (framples s2))) (snd-display #__line__ ";copy sounds framples: ~A ~A" (framples s1) (framples s2))) (if (not (= (chans s1) (chans s2) 1)) (snd-display #__line__ ";copy sounds chans: ~A ~A" (chans s1) (chans s2))) (let ((d1 (channel->float-vector 0 #f s1)) (d2 (channel->float-vector 0 #f s2))) (if (not (vequal d1 d2)) (snd-display #__line__ ";copied sound not equal? ~A?" (float-vector-peak (float-vector-subtract! d0 d1))))) (close-sound s2)))) (fill! s1 0.0) (if (fneq (maxamp s1) 0.0) (snd-display #__line__ ";fill 1 with 0: ~A" (maxamp s1))) (fill! s1 0.3) (if (fneq (maxamp s1) 0.3) (snd-display #__line__ ";fill 1 with 0.3: ~A" (maxamp s1))) (close-sound s1)) (let ((s1 (open-sound "2a.snd"))) (let ((s2 (copy s1))) (if (not (sound? s2)) (snd-display #__line__ ";copy sound 2a -> ~A" s2) (begin (if (not (= (srate s1) (srate s2))) (snd-display #__line__ ";copy sounds srates 2: ~A ~A" (srate s1) (srate s2))) (if (not (= (framples s1) (framples s2))) (snd-display #__line__ ";copy sounds framples 2: ~A ~A" (framples s1) (framples s2))) (if (not (= (chans s1) (chans s2) 2)) (snd-display #__line__ ";copy sounds chans 2: ~A ~A" (chans s1) (chans s2))) (let ((d10 (channel->float-vector 0 #f s1 0)) (d11 (channel->float-vector 0 #f s1 1)) (d20 (channel->float-vector 0 #f s2 0)) (d21 (channel->float-vector 0 #f s2 1))) (if (not (vequal d10 d20)) (snd-display #__line__ ";copied sound 2 (0) not equal? ~A?" (float-vector-peak (float-vector-subtract! d10 d20)))) (if (not (vequal d11 d21)) (snd-display #__line__ ";copied sound 2 (1) not equal? ~A?" (float-vector-peak (float-vector-subtract! d11 d21))))) (close-sound s2)))) (fill! s1 0.0) (if (fneq (maxamp s1) 0.0) (snd-display #__line__ ";fill 2 with 0: ~A" (maxamp s1))) (fill! s1 0.3) (if (fneq (maxamp s1) 0.3) (snd-display #__line__ ";fill 2 with 0.3: ~A" (maxamp s1))) (close-sound s1)) (for-each close-sound (sounds)) (unselect-all) (let ((snd (open-sound "oboe.snd"))) (make-selection 1000 2000 snd 0) (if (not (selection?)) (snd-display #__line__ ";make-selection for copy failed?")) (copy (selection)) (let* ((r1 (channel->float-vector 1000 1000 snd 0)) (snds (sounds)) (sel (if (equal? (car snds) snd) (cadr snds) (car snds))) (r2 (channel->float-vector 0 1000 sel 0))) (if (equal? sel snd) (snd-display #__line__ ";very weird: ~A equal? ~A from ~A (~A ~A ~A)" sel snd snds (car snds) (cadr snds) (equal? (car snds) snd))) (if (not (vequal r1 r2)) (snd-display #__line__ ";copied selection not equal? ~A?" (float-vector-peak (float-vector-subtract! r1 r2)))) (close-sound sel) (if (not (selection?)) (snd-display #__line__ ";copy selection unselected? ~A" (sounds)) (begin (fill! (selection) 0.0) (let ((r1 (channel->float-vector 1000 1000 snd 0))) (if (> (float-vector-peak r1) 0.0) (snd-display #__line__ ";fill! selection not 0.0? ~A" (float-vector-peak r1)))) (revert-sound snd) (if (not (selection?)) (snd-display #__line__ ";revert-sound selection unselected?") (begin (fill! (selection) 0.3) (let ((r1 (channel->float-vector 1000 1000 snd 0))) (if (or (not (= (float-vector-max r1) 0.3)) (not (= (float-vector-min r1) 0.3))) (snd-display #__line__ ";fill! selection not 0.3? ~A ~A" (float-vector-min r1) (float-vector-max r1))))))))) (for-each close-sound (sounds))) (let ((snd (open-sound "oboe.snd"))) (make-selection 1000 2000 snd 0) (if (not (selection?)) (snd-display #__line__ ";make-selection failed?") (let ((sel-max (maxamp (selection))) (sel-len (length (selection)))) (let ((mx (car (selection->mix)))) (if (not (mix? mx)) (snd-display #__line__ ";selection->mix: ~A" mx) (let ((mx-rd (make-mix-sampler mx 0)) (snd-rd (make-sampler 1000 snd 0)) (orig-rd (make-sampler 1000 snd 0 1 0))) (let ((happy #t)) (do ((i 0 (+ i 1))) ((or (not happy) (= i 1000))) (let ((mx-val (mx-rd)) (snd-val (snd-rd)) (orig-val (orig-rd))) (if (or (fneq mx-val snd-val) (fneq snd-val orig-val)) (begin (set! happy #f) (snd-display #__line__ ";selection->mix at ~A: ~A ~A ~A" (+ i 1000) mx-val snd-val orig-val)))))) (if (not (= (length mx) sel-len 1001)) (snd-display #__line__ ";selection->mix mix length: ~A (~A)" (length mx) sel-len)) (if (fneq (maxamp mx) sel-max) (snd-display #__line__ ";selection->mix maxamps: ~A ~A" (maxamp mx) sel-max))))))) (for-each close-sound (sounds))) (let ((snd (open-sound "2.snd"))) (set! (sync snd) 1) ;; make-selection claims it follows the sync field (make-selection 2000 3000 snd) (if (not (selection?)) (snd-display #__line__ ";make-selection (2) failed?") (let ((sel-max (maxamp (selection))) (sel-len (length (selection))) (sel-chns (channels (selection)))) (if (not (= sel-chns 2)) (snd-display #__line__ ";make-selection stereo syncd chans: ~A" sel-chns)) (if (not (= sel-len 1001)) (snd-display #__line__ ";make-selection stereo length: ~A" sel-len)) (let* ((mx-list (selection->mix)) (mx0 (car mx-list)) (mx1 (cadr mx-list))) (if (or (not (mix? mx0)) (not (mix? mx1))) (snd-display #__line__ ";selection->mix stereo: ~A ~A" mx0 mx1) (let ((mx0-rd (make-mix-sampler mx0 0)) (mx1-rd (make-mix-sampler mx1 0)) (snd0-rd (make-sampler 2000 snd 0)) (snd1-rd (make-sampler 2000 snd 1)) (orig0-rd (make-sampler 2000 snd 0 1 0)) (orig1-rd (make-sampler 2000 snd 1 1 0))) (let ((happy #t)) (do ((i 0 (+ i 1))) ((or (not happy) (= i 1000))) (let ((mx0-val (mx0-rd)) (mx1-val (mx1-rd)) (snd0-val (snd0-rd)) (snd1-val (snd1-rd)) (orig0-val (orig0-rd)) (orig1-val (orig1-rd))) (if (or (fneq mx0-val snd0-val) (fneq snd0-val orig0-val)) (begin (set! happy #f) (snd-display #__line__ ";selection->mix stereo 0 at ~A: ~A ~A ~A" (+ i 2000) mx0-val snd0-val orig0-val))) (if (or (fneq mx1-val snd1-val) (fneq snd1-val orig1-val)) (begin (set! happy #f) (snd-display #__line__ ";selection->mix stereo 1 at ~A: ~A ~A ~A" (+ i 2000) mx1-val snd1-val orig1-val)))))))) (if (not (= (length mx0) (length mx1) sel-len 1001)) (snd-display #__line__ ";selection->mix stereo mix length: ~A ~A (~A)" (length mx0) (length mx1) sel-len)) (if (fneq (max (maxamp mx0) (maxamp mx1)) sel-max) (snd-display #__line__ ";selection->mix stereo maxamps: ~A ~A ~A" (maxamp mx0) (maxamp mx1) sel-max))))) (for-each close-sound (sounds))) (let ((ind (new-sound :size 10))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (sample i ind 0) (* .1 i))) (let ((rd (make-sampler 3 ind 0))) (let ((val (read-sample-with-direction rd 1))) (if (fneq val .3) (snd-display #__line__ ";read-sample-with-direction 3: ~A" val)) (read-sample-with-direction rd -1) (set! val (read-sample-with-direction rd -1)) (if (fneq val .2) (snd-display #__line__ ";read-sample-with-direction 2: ~A" val)) (set! val (read-sample-with-direction rd -1)) (if (fneq val .1) (snd-display #__line__ ";read-sample-with-direction 1: ~A" val)) (close-sound ind)))) (clear-save-state-files)) ;;; ---------------- test 6: float-vectors ---------------- (define (snd_test_6) (do ((clmtest 0 (+ 1 clmtest))) ((= clmtest tests)) (log-mem clmtest) (let ((v0 (make-float-vector 10)) (v1 (make-float-vector 10)) (vlst (make-float-vector 3))) (if (not (float-vector? v0)) (snd-display #__line__ ";v0 isn't a float-vector?!?")) (if (eqv? v0 10) (snd-display #__line__ ";v0 is 10!?")) (if (float-vector? 10) (snd-display #__line__ ";10 is a float-vector?")) (if (not (= (length v0) 10)) (snd-display #__line__ ";v0 length = ~D?" (length v0))) (fill! v0 1.0) (fill! v1 0.5) (if (equal? v0 v1) (snd-display #__line__ ";float-vector equal? ~A ~A" v0 v1)) (if (eq? v0 v1) (snd-display #__line__ ";float-vector eq? ~A ~A" v0 v1)) (if (fneq (float-vector-max v0) 1.0) (snd-display #__line__ ";float-vector max ~A" (float-vector-max v0))) (if (fneq (float-vector-min v0) 1.0) (snd-display #__line__ ";float-vector min ~A" (float-vector-max v0))) (let ((v2 v1) (v3 (make-float-vector 10)) (v4 (make-float-vector 3))) (if (not (eq? v1 v2)) (snd-display #__line__ ";float-vector not eq? ~A ~A" v1 v2)) (fill! v3 0.5) (if (not (equal? v3 v1)) (snd-display #__line__ ";float-vector not equal? ~A ~A" v3 v1)) (if (equal? v4 v1) (snd-display #__line__ ";len diff float-vector equal? ~A ~A" v4 v1)) (set! (v3 0) 1.0) (if (fneq (v3 0) 1.0) (snd-display #__line__ ";set! float-vector-ref: ~A" (v3 0)))) (set! (vlst 1) .1) (if (not (feql (map values vlst) (list 0.0 0.1 0.0))) (snd-display #__line__ ";vector->list: ~A?" (map values vlst))) (let ((v2 (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4)) (set! (v2 i) i)) (float-vector-move! v2 3 2 #t) (if (or (fneq (v2 3) 2.0) (fneq (v2 2) 1.0)) (snd-display #__line__ ";float-vector-move! back: ~A?" v2))) (if (not (string=? (float-vector->string (float-vector 1.0 2.0)) "(float-vector 1.000 2.000)")) (snd-display #__line__ ";float-vector->string: ~A" (float-vector->string (float-vector 1.0 2.0)))) (if (not (vequal (float-vector 4 3 2 1) (reverse! (float-vector 1 2 3 4)))) (snd-display #__line__ ";float-vector-reverse: ~A" (reverse! (float-vector 1 2 3 4)))) (if (not (vequal (float-vector 3 2 1) (reverse! (float-vector 1 2 3)))) (snd-display #__line__ ";float-vector-reverse: ~A" (reverse! (float-vector 1 2 3)))) (if (not (vequal (float-vector 2 1) (reverse! (float-vector 1 2)))) (snd-display #__line__ ";float-vector-reverse: ~A" (reverse! (float-vector 1 2)))) (if (not (vequal (float-vector 1) (reverse! (float-vector 1)))) (snd-display #__line__ ";float-vector-reverse: ~A" (reverse! (float-vector 1)))) (if (not (vequal (float-vector 3 2 1) (reverse (float-vector 1 2 3)))) (snd-display #__line__ ";reverse(float-vector): ~A" (reverse (float-vector 1 2 3)))) (let ((v (float-vector 3 2 1))) (let ((rv (reverse v))) (if (not (vequal rv (float-vector 1 2 3))) (snd-display #__line__ ";reverse(float-vector) -> ~A ~A" v rv)))) (let ((v0 (make-float-vector 3))) (let ((var (catch #t (lambda () (v0 10)) (lambda args args)))) (if (not (eq? (car var) 'out-of-range)) (snd-display #__line__ ";float-vector-ref high index: ~A" var))) (let ((var (catch #t (lambda () (v0 -1)) (lambda args args)))) (if (not (eq? (car var) 'out-of-range)) (snd-display #__line__ ";float-vector-ref low index: ~A" var))) (let ((var (catch #t (lambda () (set! (v0 10) 1.0)) (lambda args args)))) (if (not (eq? (car var) 'out-of-range)) (snd-display #__line__ ";float-vector-set! high index: ~A" var))) (let ((var (catch #t (lambda () (set! (v0 -1) 1.0)) (lambda args args)))) (if (not (eq? (car var) 'out-of-range)) (snd-display #__line__ ";float-vector-set! low index: ~A" var))) (let ((var (catch #t (lambda () (float-vector-move! v0 10 0 #t)) (lambda args args)))) (if (not (eq? (car var) 'out-of-range)) (snd-display #__line__ ";float-vector-move! high index: ~A" var))) (let ((var (catch #t (lambda () (float-vector-move! v0 0 10 #t)) (lambda args args)))) (if (not (eq? (car var) 'out-of-range)) (snd-display #__line__ ";float-vector-move! high 2 index: ~A" var))) (let ((var (catch #t (lambda () (float-vector-move! v0 -10 0 #f)) (lambda args args)))) (if (not (eq? (car var) 'out-of-range)) (snd-display #__line__ ";float-vector-move! back high index: ~A" var))) (let ((var (catch #t (lambda () (float-vector-move! v0 0 -10 #f)) (lambda args args)))) (if (not (eq? (car var) 'out-of-range)) (snd-display #__line__ ";float-vector-move! back high 2 index: ~A" var)))) (let ((v (float-vector 0.0 1.0 -2.0 -3.0))) (if (not (vequal (float-vector-abs! v) (float-vector 0.0 1.0 2.0 3.0))) (snd-display #__line__ ";float-vector-abs! ~A" v))) ;; float-vector-add! + shared-vector: (let ((fv (float-vector 1 2 3 4 5))) (let ((sv (make-shared-vector fv '(4) 1))) (float-vector-add! sv fv) (if (not (vequal fv (float-vector 1.0 3.0 6.0 10.0 15.0))) (snd-display #__line__ ";float-vector+shared-vector: ~A" fv)))) (do ((i 0 (+ i 1))) ((= i 10)) (if (fneq (v0 i) 1.0) (snd-display #__line__ ";fill v0[~D] = ~F?" i (v0 i))) (if (fneq (v1 i) 0.5) (snd-display #__line__ ";preset v1[~D] = ~F?" i (v1 i)))) (float-vector-add! v0 v1) (do ((i 0 (+ i 1))) ((= i 10)) (if (fneq (v0 i) 1.5) (snd-display #__line__ ";add v0[~D] = ~F?" i (v0 i)))) (float-vector-subtract! v0 v1) (do ((i 0 (+ i 1))) ((= i 10)) (if (fneq (v0 i) 1.0) (snd-display #__line__ ";subtract v0[~D] = ~F?" i (v0 i)))) (let ((v2 (copy v0))) (do ((i 0 (+ i 1))) ((= i 10)) (if (fneq (v2 i) 1.0) (snd-display #__line__ ";copy v0[~D] = ~F?" i (v2 i)))) (float-vector-scale! v2 5.0) (do ((i 0 (+ i 1))) ((= i 10)) (if (fneq (v2 i) 5.0) (snd-display #__line__ ";scale v2[~D] = ~F?" i (v2 i)))) (float-vector-offset! v0 -1.0) (do ((i 0 (+ i 1))) ((= i 10)) (if (fneq (v0 i) 0.0) (snd-display #__line__ ";offset v0[~D] = ~F?" i (v0 i)))) (float-vector-multiply! v2 v1) (do ((i 0 (+ i 1))) ((= i 10)) (if (fneq (v2 i) 2.5) (snd-display #__line__ ";multiply v2[~D] = ~F?" i (v2 i)))) (if (fneq (float-vector-peak v2) 2.5) (snd-display #__line__ ";v2's peak is ~F?" (float-vector-peak v2))) (set! (v2 5) 123.0) (if (fneq (float-vector-peak v2) 123.0) (snd-display #__line__ ";v2's set peak is ~F?" (float-vector-peak v2))) (let ((vn (make-float-vector 32)) (vb (make-float-vector 64)) (vs (make-float-vector 3)) (vss (make-float-vector 1))) (do ((i 0 (+ i 1))) ((= i 32)) (set! (vn i) i)) (let ((vnew (float-vector-subseq vn 3))) (if (fneq (vnew 0) 3.0) (snd-display #__line__ ";float-vector-subseq[3:] ~A?" (vnew 0))) (if (not (= (length vnew) 29)) (snd-display #__line__ ";float-vector-subseq[3:] length: ~A?" (length vnew)))) (let ((vnew (float-vector-subseq vn 3 8))) (if (fneq (vnew 0) 3.0) (snd-display #__line__ ";float-vector-subseq[3:8] ~A?" (vnew 0))) (if (not (= (length vnew) 6)) (snd-display #__line__ ";float-vector-subseq[3:8] length: ~A?" (length vnew)))) (float-vector-subseq vn 3 3 vs) (if (or (fneq (vs 0) 3.0) (fneq (vs 1) 0.0) (fneq (vs 2) 0.0)) (snd-display #__line__ ";float-vector-subseq[3:3->vs] ~A?" vs)) (float-vector-subseq vn 0 32 vs) (if (not (= (length vs) 3)) (snd-display #__line__ ";float-vector-subseq[0:32->vs] length: ~A?" (length vs))) (float-vector-subseq vn 2 3 vss) (if (fneq (vss 0) 2.0) (snd-display #__line__ ";float-vector-subseq[2:3->vss] ~A?" (vss 0))) (set! (vb 8) 123.0) (float-vector-subseq vn 1 8 vb) (if (fneq (vb 0) 1.0) (snd-display #__line__ ";float-vector-subseq[1:8->vb] ~A?" (vb 0))) (if (fneq (vb 8) 123.0) (snd-display #__line__ ";float-vector-subseq[1:8->vb][8] ~A?" (vb 8)))) (let ((v (make-float-vector 20)) (mn 1.0) (mx -1.0)) (do ((i 0 (+ i 1))) ((= i 20)) (let ((val (mus-random 1.0))) (set! (v i) val) (if (< val mn) (set! mn val)) (if (> val mx) (set! mx val)))) (if (fneq (float-vector-min v) mn) (snd-display #__line__ ";float-vector-min ran: ~A ~A" (float-vector-min v) mn)) (if (fneq (float-vector-max v) mx) (snd-display #__line__ ";float-vector-max ran: ~A ~A" (float-vector-max v) mx)) (if (fneq (float-vector-peak v) (max (abs mn) (abs mx))) (snd-display #__line__ ";float-vector-peak ran: ~A ~A ~A" (float-vector-peak v) mn mx))) (let ((v1 (make-float-vector 3 .1)) (v2 (make-float-vector 4 .2))) (let ((val (float-vector+ (copy v1) v2))) (if (not (vequal val (float-vector .3 .3 .3))) (snd-display #__line__ ";float-vector+ .1 .2: ~A" val))) (set! (v1 1) .3) (let ((val (float-vector+ (copy v1) v2))) (if (not (vequal val (float-vector .3 .5 .3))) (snd-display #__line__ ";float-vector+ .1 .2 (1): ~A" val))) (let ((val (float-vector+ (copy v1) 2.0))) (if (not (vequal val (float-vector 2.1 2.3 2.1))) (snd-display #__line__ ";float-vector+ .1 2.0: ~A" val))) (let ((val (float-vector+ 2.0 (copy v1)))) (if (not (vequal val (float-vector 2.1 2.3 2.1))) (snd-display #__line__ ";float-vector+ .1 2.0 (1): ~A" val))) (let ((val (float-vector* 2.0 (copy v1)))) (if (not (vequal val (float-vector .2 .6 .2))) (snd-display #__line__ ";float-vector* 2.0: ~A" val))) (let ((val (float-vector* (copy v1) 2.0))) (if (not (vequal val (float-vector .2 .6 .2))) (snd-display #__line__ ";float-vector* 2.0 (1): ~A" val))) (let ((val (float-vector* (copy v1) v2))) (if (not (vequal val (float-vector .02 .06 .02))) (snd-display #__line__ ";float-vector* v1 v2: ~A" val)))) (fill! v0 1.0) (do ((i 0 (+ i 1))) ((= i 10)) (if (fneq (v0 i) 1.0) (snd-display #__line__ ";map v0[~D] = ~F?" i (v0 i))))) (if (fneq ((float-vector 1.0 2.0 3.0) 1) 2.0) (snd-display #__line__ ";(float-vector...) = ~A?" ((float-vector 1.0 2.0 3.0) 1))) (let ((v1 (float-vector 1 2 3 4))) (if (fneq (v1 1) 2.0) (snd-display #__line__ ";(v1 1) = ~A?" (v1 1)))) (when with-gui (let ((ind (open-sound "oboe.snd"))) (set! (speed-control ind) .5) (play :wait #t) (apply-controls) (revert-sound) (reset-controls ind) ;; try some special cases (apply-controls) (if (not (= (edit-position ind) 0)) (snd-display #__line__ ";apply-controls with no:change: ~A: ~A" (edits ind) (edit-tree ind))) (set! (speed-control ind) -1.0) (apply-controls) (if (not (= (edit-position ind) 1)) (snd-display #__line__ ";apply-controls with srate -1.0: ~A ~A ~A" (edit-position ind) (edits ind) (edit-tree ind))) (if (> (abs (- (framples ind 0) (framples ind 0 0))) 2) (snd-display #__line__ ";apply-controls srate -1.0 lengths: ~A ~A" (framples ind 0) (framples ind 0 0))) (if (or (fneq (maxamp) .147) (< (abs (sample 9327)) .01)) (snd-display #__line__ ";apply-controls srate -1.0 samples: ~A ~A" (maxamp) (sample 9327))) (if (fneq (speed-control ind) 1.0) (snd-display #__line__ ";apply-controls -1.0 -> ~A?" (speed-control ind))) (hook-push after-apply-controls-hook (lambda (hook) (let ((tag (catch #t apply-controls (lambda args args)))) (if (not (eq? (car tag) 'cannot-apply-controls)) (snd-display #__line__ ";after-apply-controls-hook: recursive attempt apply-controls: ~A" tag))))) (apply-controls) (set! (hook-functions after-apply-controls-hook) ()) (revert-sound) (close-sound ind))) (let ((hi (make-float-vector 3))) (let ((tag (catch #t (lambda () (float-vector-subseq hi 1 0)) (lambda args (car args))))) (if (not (eq? tag 'out-of-range)) (snd-display #__line__ ";float-vector-subseq 1 0: ~A" tag)))) (let ((v0 (make-float-vector 5 .1)) (v1 (make-float-vector 6 .2))) (float-vector-add! v0 v1 2) (if (not (vequal v0 (float-vector .1 .1 .3 .3 .3))) (snd-display #__line__ ";float-vector-add + offset: ~A" v0))) ;; check s7 stuff with float-vectors (let ((v (float-vector 1.0 2.0 3.0))) (if (not (string=? (format #f "~{~A~^-~}" v) "1.0-2.0-3.0")) (snd-display #__line__ ";float-vector in format {}: ~S" (format #f "~{~A~^-~}" v))) (if (not (= (length v) 3)) (snd-display #__line__ ";float-vector s7 len: ~A" (length v))) (if (not (equal? v (copy v))) (snd-display #__line__ ";float-vector s7 copy is not equal? ~A ~A" v (copy v))) (let ((val (map floor v))) (if (not (equal? val '(1 2 3))) (snd-display #__line__ ";float-vector s7 map: ~A" val))) (let ((val 0)) (for-each (lambda (x) (set! val (+ val (floor x)))) v) (if (not (eqv? val 6)) (snd-display #__line__ ";float-vector s7 for-each: ~A" val))) (set! v (reverse v)) (if (not (vvequal v (float-vector 3.0 2.0 1.0))) (snd-display #__line__ ";float-vector s7 reverse: ~A" v)) (fill! v 12.0) (if (not (vvequal v (float-vector 12.0 12.0 12.0))) (snd-display #__line__ ";float-vector s7 fill: ~A" (fill! v 12.0))) ) (let ((sum 0)) (for-each (lambda (n) (set! sum (+ sum n))) (float-vector 1 2 3)) (if (not (= sum 6.0)) (snd-display #__line__ ";object for-each (float-vector): ~A" sum))) (let ((x (float-vector 0.0)) (osc (make-oscil :frequency 440)) (e1 (make-env '(0 0 1 1 2 0) :length 100))) (do ((i 0 (+ i 1))) ((= i 100)) (float-vector-set! x 0 (* (env e1) (oscil osc (float-vector-ref x 0)))))) (if (fneq (float-vector-equal? (float-vector 1.0) (float-vector 1.1) .1) .0909) (snd-display #__line__ ";float-vector-equal? 0.0909: ~A" (float-vector-equal? (float-vector 1.0) (float-vector 1.1) .1))) (if (float-vector-equal? (float-vector 1.0) (float-vector 1.1) .01) (snd-display #__line__ ";float-vector-equal? #f: ~A" (float-vector-equal? (float-vector 1.0) (float-vector 1.1) .01))) ))) ;;; ---------------- test 7: colors ---------------- (require snd-rgb.scm) (define (snd_test_7) (define colormap-error-max 0.0) (define cfneq (lambda (a b) (> (abs (- a b)) colormap-error-max))) (define old-colormap-size *colormap-size*) (if (or (provided? 'snd-gtk) (provided? 'snd-motif)) (letrec ((test-color (lambda (lst) (if (pair? lst) (let* ((name ((car lst) 0)) (getfnc ((car lst) 1)) (setfnc (lambda (val) (set! (getfnc) val))) (initval ((car lst) 2))) (if (not (color? initval)) (snd-display #__line__ ";~A not color?" initval)) ;; we'll get warnings here if the cell chosen didn't exactly match the one requested -- not a bug ;; (if (not (equal? (getfnc) initval)) ;; (snd-display #__line__ ";~A is not ~A (~A)?" name initval (getfnc))) (setfnc beige) (if (not (equal? (getfnc) beige)) (snd-display #__line__ ";set-~A is not beige (~A)?" name (getfnc))) (setfnc initval) (test-color (cdr lst))))))) (let* ((c1 (catch 'no-such-color (lambda () (make-color 0 0 1)) (lambda args #f))) (c2 c1) (c3 (catch 'no-such-color (lambda () (make-color 0 0 1)) (lambda args #f)))) (if (not (equal? c1 c2)) (snd-display #__line__ ";color not equal? ~A ~A?" c1 c2)) (if (not (eq? c1 c2)) (snd-display #__line__ ";color not eq? ~A ~A?" c1 c2)) ;(if (not (equal? c1 c3)) (snd-display #__line__ ";diff color not equal? ~A ~A?" c1 c3)) (if (eq? c1 c3) (snd-display #__line__ ";diff color eq? ~A ~A?" c1 c3)) (if (and (not (equal? (color->list c1) (list 0.0 0.0 1.0))) (not (equal? (color->list c1) (list 0.0 0.0 1.0 1.0)))) (snd-display #__line__ ";color->list: ~A ~A?" c1 (color->list c1)))) (if (not (provided? 'snd-motif)) (let* ((c1 (catch 'no-such-color (lambda () (make-color 0 0 1 0.5)) (lambda args #f))) (c2 c1) (c3 (catch 'no-such-color (lambda () (make-color 0 0 1 0.5)) (lambda args #f)))) (if (not (equal? c1 c2)) (snd-display #__line__ ";alpha color not equal? ~A ~A?" c1 c2)) (if (not (eq? c1 c2)) (snd-display #__line__ ";alpha color not eq? ~A ~A?" c1 c2)) ;(if (not (equal? c1 c3)) (snd-display #__line__ ";alpha diff color not equal? ~A ~A?" c1 c3)) (if (eq? c1 c3) (snd-display #__line__ ";alpha diff color eq? ~A ~A?" c1 c3)) (let ((c4 (catch 'no-such-color (lambda () (make-color 0 0 1 0.0)) (lambda args #f)))) (if (equal? c1 c4) (snd-display #__line__ ";alpha color equal? ~A ~A?" c1 c2))))) (do ((i 0 (+ i 1))) ((not (colormap? (integer->colormap i)))) (let ((val (colormap-ref (integer->colormap i) 0)) (true-val ((list '(0.0 0.0 0.0) '(0.0 0.0 0.0) '(0.0 0.0 0.0) '(0.0 1.0 1.0) '(0.0 0.0 7.01915007248035e-4) '(0.0 0.0 0.0) '(0.0 0.0 0.0) '(0.0 0.0 0.49999) '(1.0 0.0 0.0) '(1.0 0.0 0.0) '(0.0 0.0 1.0) '(1.0 0.0 1.0) '(0.0 0.500007629510948 0.4) '(1.0 0.0 0.0) '(1.0 0.0 0.0) '(0.0 0.0 1.0)) i))) (if (not (feql val true-val)) (snd-display #__line__ ";colormap-ref ~A: ~A (~A)" i val true-val)))) (catch #t ; might be undefined var as well as no-such-color (lambda () (test-color (list (list 'basic-color basic-color ivory2) (list 'cursor-color cursor-color red) (list 'data-color data-color black) (list 'enved-waveform-color enved-waveform-color blue) (list 'filter-control-waveform-color filter-control-waveform-color blue) (list 'graph-color graph-color white) (list 'highlight-color highlight-color ivory1) (list 'listener-color listener-color alice-blue) (list 'listener-text-color listener-text-color black) (list 'mark-color mark-color red) (list 'mix-color mix-color dark-gray) (list 'position-color position-color ivory3) (list 'sash-color sash-color light-green) (list 'selected-data-color selected-data-color black) (list 'selected-graph-color selected-graph-color white) (list 'selection-color selection-color lightsteelblue1) (list 'text-focus-color text-focus-color white) (list 'zoom-color zoom-color ivory4) )) (let ((ind (open-sound "oboe.snd"))) (set! *selected-data-color* light-green) (set! *data-color* blue) (set! *selected-graph-color* black) (let ((red (make-color-with-catch 1.0 0.0 0.0))) (set! (foreground-color ind 0 cursor-context) red) (let ((col (foreground-color ind 0 cursor-context))) (if (not (feql (color->list col) (color->list red))) (snd-display #__line__ ";set foreground cursor color: ~A ~A" (color->list col) (color->list red)))) (set! (foreground-color) blue) (let ((col (foreground-color))) (if (not (feql (color->list col) (color->list blue))) (snd-display #__line__ ";set foreground-color: ~A ~A" (color->list col) (color->list blue)))) (set! (foreground-color ind) red) (let ((col (foreground-color ind))) (if (not (feql (color->list col) (color->list red))) (snd-display #__line__ ";set foreground-color with ind (red): ~A ~A" (color->list col) (color->list red)))) (set! (foreground-color ind) black) (let ((col (foreground-color ind))) (if (not (feql (color->list col) (color->list black))) (snd-display #__line__ ";set foreground-color with ind (black): ~A ~A" (color->list col) (color->list black))))) (set! *selected-graph-color* (make-color-with-catch 0.96 0.96 0.86)) (set! *data-color* black) (set! *selected-data-color* blue) (set! *graph-color* white) (close-sound ind))) (lambda args args)) (if (not (= (length jet-colormap) *colormap-size*)) (snd-display #__line__ ";jet-colormap length: ~A ~A" (length jet-colormap) *colormap-size*)) (for-each (lambda (n err) (set! *colormap-size* n) (set! colormap-error-max err) (do ((i 0 (+ i 1))) ((= i 10)) (let* ((x (random 1.0)) (r (if (< x 3/4) (* 7/8 x) (- (* 11/8 x) 3/8))) (g (if (< x 3/8) (* 7/8 x) (if (< x 3/4) (- (* 29/24 x) 1/8) (+ (* 7/8 x) 1/8)))) (b (if (< x 3/8) (* 29/24 x) (+ (* 7/8 x) 1/8))) (rgb (colormap-ref bone-colormap x)) (rgb1 (bone-colormap x)) (r1 (rgb 0)) (g1 (rgb 1)) (b1 (rgb 2)) (r2 (rgb1 0)) (g2 (rgb1 1)) (b2 (rgb1 2))) (if (and (< x (- 1.0 (/ 1.0 n))) (or (cfneq r r1) (cfneq g g1) (cfneq b b1) (cfneq r2 r1) (cfneq g2 g1) (cfneq b2 b1))) (snd-display #__line__ ";bone ~,3F (~,3F): ~{~,3F ~} ~{~,3F ~}" x (max (abs (- r r1)) (abs (- g g1)) (abs (- b b1))) (list r g b) (list r1 g1 b1))))) (do ((i 0 (+ i 1))) ((= i 10)) (let* ((x (random 1.0)) (r (if (< x 4/5) (* 5/4 x) 1.0)) (g (* 4/5 x)) (b (* 1/2 x)) (rgb (colormap-ref copper-colormap x)) (r1 (rgb 0)) (g1 (rgb 1)) (b1 (rgb 2))) (if (and (< x (- 1.0 (/ 1.0 n))) (or (cfneq r r1) (cfneq g g1) (cfneq b b1))) (snd-display #__line__ ";copper ~,3F (~,3F): ~{~,3F ~} ~{~,3F ~}" x (max (abs (- r r1)) (abs (- g g1)) (abs (- b b1))) (list r g b) (list r1 g1 b1))))) (do ((i 0 (+ i 1))) ((= i 10)) (let* ((x (random 1.0)) (r 0.0) (g x) (b (- 1.0 (/ g 2.0))) (rgb (colormap-ref winter-colormap x)) (r1 (rgb 0)) (g1 (rgb 1)) (b1 (rgb 2))) (if (and (< x (- 1.0 (/ 1.0 n))) (or (cfneq r r1) (cfneq g g1) (cfneq b b1))) (snd-display #__line__ ";winter ~,3F (~,3F): ~{~,3F ~} ~{~,3F ~}" x (max (abs (- r r1)) (abs (- g g1)) (abs (- b b1))) (list r g b) (list r1 g1 b1))))) (do ((i 0 (+ i 1))) ((= i 10)) (let* ((x (random 1.0)) (r 1.0) (g x) (b 0.0) (rgb (colormap-ref autumn-colormap x)) (r1 (rgb 0)) (g1 (rgb 1)) (b1 (rgb 2))) (if (and (< x (- 1.0 (/ 1.0 n))) (or (cfneq r r1) (cfneq g g1) (cfneq b b1))) (snd-display #__line__ ";autumn ~,3F (~,3F): ~{~,3F ~} ~{~,3F ~}" x (max (abs (- r r1)) (abs (- g g1)) (abs (- b b1))) (list r g b) (list r1 g1 b1))))) (do ((i 0 (+ i 1))) ((= i 10)) (let* ((x (random 1.0)) (r x) (g (- 1.0 r)) (b 1.0) (rgb (colormap-ref cool-colormap x)) (r1 (rgb 0)) (g1 (rgb 1)) (b1 (rgb 2))) (if (and (< x (- 1.0 (/ 1.0 n))) (or (cfneq r r1) (cfneq g g1) (cfneq b b1))) (snd-display #__line__ ";cool ~,3F (~,3F): ~{~,3F ~} ~{~,3F ~}" x (max (abs (- r r1)) (abs (- g g1)) (abs (- b b1))) (list r g b) (list r1 g1 b1))))) (do ((i 0 (+ i 1))) ((= i 10)) (let* ((x (random 1.0)) (r (if (< x 3/8) (* 8/3 x) 1.0)) (g (if (< x 3/8) 0.0 (if (< x 3/4) (- (* 8/3 x) 1.0) 1.0))) (b (if (< x 3/4) 0.0 (- (* 4 x) 3))) (rgb (colormap-ref hot-colormap x)) (r1 (rgb 0)) (g1 (rgb 1)) (b1 (rgb 2))) (if (and (< x (- 1.0 (/ 1.0 n))) (or (cfneq r r1) (cfneq g g1) (cfneq b b1))) (snd-display #__line__ ";hot ~,3F (~,3F): ~{~,3F ~} ~{~,3F ~}" x (max (abs (- r r1)) (abs (- g g1)) (abs (- b b1))) (list r g b) (list r1 g1 b1))))) (do ((i 0 (+ i 1))) ((= i 10)) (let* ((x (random 1.0)) (r (if (< x 3/8) 0.0 (if (< x 5/8) (- (* 4 x) 3/2) (if (< x 7/8) 1.0 (+ (* -4 x) 9/2))))) (g (if (< x 1/8) 0.0 (if (< x 3/8) (- (* 4 x) 1/2) (if (< x 5/8) 1.0 (if (< x 7/8) (+ (* -4 x) 7/2) 0.0))))) (b (if (< x 1/8) (+ (* 4 x) 1/2) (if (< x 3/8) 1.0 (if (< x 5/8) (+ (* -4 x) 5/2) 0.0)))) (rgb (colormap-ref jet-colormap x)) (r1 (rgb 0)) (g1 (rgb 1)) (b1 (rgb 2))) (if (and (< x (- 1.0 (/ 1.0 n))) (or (cfneq r r1) (cfneq g g1) (cfneq b b1))) (snd-display #__line__ ";jet ~,3F (~,3F): ~{~,3F ~} ~{~,3F ~}" x (max (abs (- r r1)) (abs (- g g1)) (abs (- b b1))) (list r g b) (list r1 g1 b1))))) (if (colormap? pink-colormap) (do ((i 0 (+ i 1))) ((= i 10)) (let* ((x (random 1.0)) (r (if (< x 3/8) (* 14/9 x) (+ (* 2/3 x) 1/3))) (g (if (< x 3/8) (* 2/3 x) (if (< x 3/4) (- (* 14/9 x) 1/3) (+ (* 2/3 x) 1/3)))) (b (if (< x 3/4) (* 2/3 x) (- (* 2 x) 1))) (rgb (colormap-ref pink-colormap x)) (r1 (rgb 0)) (g1 (rgb 1)) (b1 (rgb 2))) (if (and (< x (- 1.0 (/ 1.0 n))) (or (cfneq r r1) (cfneq g g1) (cfneq b b1))) (snd-display #__line__ ";pink ~,3F (~,3F): ~{~,3F ~} ~{~,3F ~}" x (max (abs (- r r1)) (abs (- g g1)) (abs (- b b1))) (list r g b) (list r1 g1 b1)))))) (do ((i 0 (+ i 1))) ((= i 10)) (let* ((x (random 1.0)) (r 1.0) (g x) (b (- 1.0 g)) (rgb (colormap-ref spring-colormap x)) (r1 (rgb 0)) (g1 (rgb 1)) (b1 (rgb 2))) (if (and (< x (- 1.0 (/ 1.0 n))) (or (cfneq r r1) (cfneq g g1) (cfneq b b1))) (snd-display #__line__ ";spring ~,3F (~,3F): ~{~,3F ~} ~{~,3F ~}" x (max (abs (- r r1)) (abs (- g g1)) (abs (- b b1))) (list r g b) (list r1 g1 b1))))) (do ((i 0 (+ i 1))) ((= i 10)) (let* ((x (random 1.0)) (r x) (g x) (b x) (rgb (colormap-ref gray-colormap x)) (r1 (rgb 0)) (g1 (rgb 1)) (b1 (rgb 2))) (if (and (< x (- 1.0 (/ 1.0 n))) (or (cfneq r r1) (cfneq g g1) (cfneq b b1))) (snd-display #__line__ ";gray ~,3F (~,3F): ~{~,3F ~} ~{~,3F ~}" x (max (abs (- r r1)) (abs (- g g1)) (abs (- b b1))) (list r g b) (list r1 g1 b1))))) (do ((i 0 (+ i 1))) ((= i 10)) (let* ((x (random 1.0)) (r 0.0) (g 0.0) (b 0.0) (rgb (colormap-ref black-and-white-colormap x)) (r1 (rgb 0)) (g1 (rgb 1)) (b1 (rgb 2))) (if (and (< x (- 1.0 (/ 1.0 n))) (or (cfneq r r1) (cfneq g g1) (cfneq b b1))) (snd-display #__line__ ";black-and-white ~,3F (~,3F): ~{~,3F ~} ~{~,3F ~}" x (max (abs (- r r1)) (abs (- g g1)) (abs (- b b1))) (list r g b) (list r1 g1 b1))))) (do ((i 0 (+ i 1))) ((= i 10)) (let* ((x (random 1.0)) (r x) (g (+ 0.5 (/ r 2))) (b 0.4) (rgb (colormap-ref summer-colormap x)) (r1 (rgb 0)) (g1 (rgb 1)) (b1 (rgb 2))) (if (and (< x (- 1.0 (/ 1.0 n))) (or (cfneq r r1) (cfneq g g1) (cfneq b b1))) (snd-display #__line__ ";summer ~,3F (~,3F): ~{~,3F ~} ~{~,3F ~}" x (max (abs (- r r1)) (abs (- g g1)) (abs (- b b1))) (list r g b) (list r1 g1 b1))))) (do ((i 0 (+ i 1))) ((= i 10)) (let* ((x (random 1.0)) (r (if (< x 2/5) 1.0 (if (< x 3/5) (+ (* -5 x) 3) (if (< x 4/5) 0.0 (- (* 10/3 x) 8/3))))) (g (if (< x 2/5) (* 5/2 x) (if (< x 3/5) 1.0 (if (< x 4/5) (+ (* -5 x) 4) 0.0)))) (b (if (< x 3/5) 0.0 (if (< x 4/5) (- (* 5 x) 3) 1.0))) (rgb (colormap-ref rainbow-colormap x)) (r1 (rgb 0)) (g1 (rgb 1)) (b1 (rgb 2))) (if (and (< x (- 1.0 (/ 1.0 n))) (or (cfneq r r1) (cfneq g g1) (cfneq b b1))) (snd-display #__line__ ";rainbow ~,3F (~,3F): ~{~,3F ~} ~{~,3F ~}" x (max (abs (- r r1)) (abs (- g g1)) (abs (- b b1))) (list r g b) (list r1 g1 b1))))) (do ((i 0 (+ i 1))) ((= i 10)) (let* ((x (random 1.0)) (rgb (colormap-ref prism-colormap x))) (if (and (< x (- 1.0 (/ 1.0 n))) (not (feql rgb '(1 0 0))) (not (feql rgb '(1 0.5 0))) (not (feql rgb '(1 1 0))) (not (feql rgb '(0 1 0))) (not (feql rgb '(0 0 1))) (not (feql rgb '(.6667 0 1)))) (snd-display #__line__ ";prism ~A" rgb)))) (do ((i 0 (+ i 1))) ((= i 10)) (let* ((x (random 1.0)) (rgb (colormap-ref flag-colormap x))) (if (and (< x (- 1.0 (/ 1.0 n))) (not (feql rgb '(1 0 0))) (not (feql rgb '(1 1 1))) (not (feql rgb '(0 0 1))) (not (feql rgb '(0 0 0)))) (snd-display #__line__ ";flag: ~A" rgb)))) ) (list 512 64) (list 0.005 0.04)) (let ((ind (add-colormap "white" (lambda (size) (list (make-float-vector size 1.0) (make-float-vector size 1.0) (make-float-vector size 1.0)))))) (if (not (colormap? ind)) (snd-display #__line__ ";add-colormap ~A: ~A" ind (colormap? ind))) (if (not (feql (colormap-ref ind 0.5) '(1.0 1.0 1.0))) (snd-display #__line__ ";white colormap: ~A" (colormap-ref ind 0.5))) (let ((tag (catch #t (lambda () (set! *colormap* ind)) (lambda args args)))) (if (or (eq? tag 'no-such-colormap) (not (equal? *colormap* ind)) (not (= (colormap->integer *colormap*) (colormap->integer ind)))) (snd-display #__line__ ";colormap white: ~A ~A ~A" tag ind *colormap*))) (if (not (string=? (colormap-name ind) "white")) (snd-display #__line__ ";white colormap name: ~A" (colormap-name ind)))) (let ((tag (catch #t (lambda () (delete-colormap (integer->colormap 1234))) (lambda args (car args))))) (if (not (eq? tag 'no-such-colormap)) (snd-display #__line__ ";delete-colormap 1234: ~A" tag))) (let ((tag (catch #t (lambda () (colormap-ref (integer->colormap 1234) 0.5)) (lambda args (car args))))) (if (not (eq? tag 'no-such-colormap)) (snd-display #__line__ ";colormap-ref 1234: ~A" tag))) (let ((tag (catch #t (lambda () (colormap-ref (integer->colormap -1) 0.5)) (lambda args (car args))))) (if (and (not (eq? tag 'no-such-colormap)) (not (eq? tag 'wrong-type-arg))) (snd-display #__line__ ";colormap-ref -1: ~A" tag))) (let ((tag (catch #t (lambda () (set! *colormap* (integer->colormap 1234))) (lambda args (car args))))) (if (not (eq? tag 'no-such-colormap)) (snd-display #__line__ "; set colormap 1234: ~A" tag))) (let ((tag (catch #t (lambda () (set! *colormap* (integer->colormap -1))) (lambda args (car args))))) (if (and (not (eq? tag 'no-such-colormap)) (not (eq? tag 'wrong-type-arg))) (snd-display #__line__ "; set colormap -1: ~A" tag))) (let ((tag (catch #t (lambda () (colormap-ref copper-colormap 2.0)) (lambda args (car args))))) (if (not (eq? tag 'out-of-range)) (snd-display #__line__ ";colormap-ref 2.0: ~A" tag))) (set! *colormap-size* old-colormap-size) (if (not (= *colormap-size* old-colormap-size)) (snd-display #__line__ ";set colormap-size: ~A ~A" *colormap-size* old-colormap-size)) (if (not (string=? (colormap-name black-and-white-colormap) "black-and-white")) (snd-display #__line__ ";black-and-white: ~A" (colormap-name black-and-white-colormap))) (if (not (string=? (colormap-name gray-colormap) "gray")) (snd-display #__line__ ";gray: ~A" (colormap-name gray-colormap))) (if (not (string=? (colormap-name rainbow-colormap) "rainbow")) (snd-display #__line__ ";rainbow: ~A" (colormap-name rainbow-colormap))) (let () (add-colormap "purple" (lambda (size) (let ((r (make-float-vector size)) (g (make-float-vector size)) (b (make-float-vector size)) (incr (/ 256.0 size)) (er (list 0 60 60 116 128 252 192 252 256 60)) (eg (list 0 0 64 0 128 252 192 252 256 0)) (eb (list 0 80 128 252 192 0 256 80))) (do ((i 0 (+ i 1)) (x 0.0 (+ x incr))) ((= i size)) (set! (r i) (/ (envelope-interp x er) 256.0)) (set! (g i) (/ (envelope-interp x eg) 256.0)) (set! (b i) (/ (envelope-interp x eb) 256.0))) (list r g b)))) (add-colormap "sin" (lambda (size) (let ((r (make-float-vector size)) (g (make-float-vector size)) (b (make-float-vector size)) (incr (/ (* 2 pi) size))) (do ((i 0 (+ i 1)) (x 0.0 (+ x incr))) ((= i size)) (set! (r i) (abs (sin (* 1.5 x)))) (set! (g i) (abs (sin (* 3.5 x)))) (set! (b i) (abs (sin (* 2.5 x))))) (list r g b)))) (add-colormap "another-sin" (lambda (size) (let ((r (make-float-vector size)) (g (make-float-vector size)) (b (make-float-vector size)) (incr (/ (* 2 pi) size))) (do ((i 0 (+ i 1)) (x 0.0 (+ x incr))) ((= i size)) (set! (r i) (abs (sin (* 2.5 x)))) (set! (g i) (abs (sin (* 3.5 x)))) (set! (b i) (abs (sin (* 4.5 x))))) (list r g b)))) (delete-colormap pink-colormap) (if (colormap? pink-colormap) (snd-display #__line__ ";delete-colormap ~A: ~A" pink-colormap (colormap? pink-colormap))) (let ((tag (catch #t (lambda () (set! *colormap* pink-colormap)) (lambda args args)))) (if (or (not (eq? (car tag) 'no-such-colormap)) (equal? *colormap* pink-colormap)) (snd-display #__line__ ";delete pink colormap: ~A ~A ~A" tag pink-colormap *colormap*))) (for-each (lambda (n) (set! *colormap-size* n) (do ((i 0 (+ i 1))) ((= i 10)) (let* ((x (random 1.0)) (r (if (< x 4/5) (* 5/4 x) 1.0)) (g (* 4/5 x)) (b (* 1/2 x)) (rgb (colormap-ref copper-colormap x)) (r1 (rgb 0)) (g1 (rgb 1)) (b1 (rgb 2))) (if (and (> n 2) (< x (- 1.0 (/ 1.0 n))) (or (cfneq r r1) (cfneq g g1) (cfneq b b1))) (snd-display #__line__ ";copper size reset ~A: ~,3F (~,3F): ~{~,3F ~} ~{~,3F ~}" n x (max (abs (- r r1)) (abs (- g g1)) (abs (- b b1))) (list r g b) (list r1 g1 b1)))))) (list 1024 256 2 512)) (set! *colormap-size* 512)) (set! (hook-functions graph-hook) ()) ))) ;;; ---------------- test 8: clm ---------------- (require snd-moog.scm snd-poly.scm snd-bird.scm snd-v.scm snd-numerics.scm snd-generators.scm) (if (defined? 'gsl-roots) (require snd-analog-filter.scm)) (defgenerator sa1 freq (coscar #f) (sincar #f) (dly #f) (hlb #f)) (define (copy-test o) (let ((p (copy o))) (if (not (equal? o p)) (snd-display #__line__ ";copy ~A != ~A~%" o p)) (mus-apply o 1.0) (if (equal? o p) (snd-display #__line__ ";copy/run ~A == ~A~%" o p)) (set! p (mus-copy o)) (if (not (equal? o p)) (snd-display #__line__ ";mus-copy ~A != ~A~%" o p)))) (define (osc-opt) (let ((g1 (make-oscil 1000)) (g2 (make-oscil 1000)) (g3 (make-oscil 1000)) (g4 (make-oscil 1000)) (g5 (make-oscil 1000)) (g6 (make-oscil 1000)) (x1 1.0) (x2 (hz->radians 100.0)) (x4 (hz->radians 5.0))) (do ((i 0 (+ i 1))) ((= i 50)) (let ((o1 (oscil g1 x2)) (o2 (* 1.0 (oscil g2 x2))) (o3 (oscil g3 (* x4 20.0))) (o4 (oscil g4 (* 20.0 x4))) (o5 (oscil g5 (* x1 x2))) (o6 (* 1.0 (oscil g6 (* 20.0 x4))))) (if (> (abs (- (+ o2 o3 o4 o5 o6) (* 5 o1))) 1e-6) (snd-display #__line__ "~A: ~1,4F ~1,4F ~1,4F ~1,4F ~1,4F ~1,4F" i o1 o2 o3 o4 o5 o6)))))) (define (nrxysin-opt) (let ((g1 (make-nrxysin 1000 :n 10 :r .9)) (g2 (make-nrxysin 1000 :n 10 :r .9)) (g3 (make-nrxysin 1000 :n 10 :r .9)) (g4 (make-nrxysin 1000 :n 10 :r .9)) (g5 (make-nrxysin 1000 :n 10 :r .9)) (g6 (make-nrxysin 1000 :n 10 :r .9)) (x1 1.0) (x2 (hz->radians 100.0)) (x4 (hz->radians 5.0))) (do ((i 0 (+ i 1))) ((= i 50)) (let ((o1 (nrxysin g1 x2)) (o2 (* 1.0 (nrxysin g2 x2))) (o3 (nrxysin g3 (* x4 20.0))) (o4 (nrxysin g4 (* 20.0 x4))) (o5 (nrxysin g5 (* x1 x2))) (o6 (* 1.0 (nrxysin g6 (* 20.0 x4))))) (if (> (abs (- (+ o2 o3 o4 o5 o6) (* 5 o1))) 1e-6) (format #t "~A: ~1,4F ~1,4F ~1,4F ~1,4F ~1,4F ~1,4F~%" i o1 o2 o3 o4 o5 o6)))))) (define (polywave-opt) (let ((g1 (make-polywave 1000 '(1 .5 2 .5))) (g2 (make-polywave 1000 '(1 .5 2 .5))) (g3 (make-polywave 1000 '(1 .5 2 .5))) (g4 (make-polywave 1000 '(1 .5 2 .5))) (g5 (make-polywave 1000 '(1 .5 2 .5))) (g6 (make-polywave 1000 '(1 .5 2 .5))) (x1 1.0) (x2 (hz->radians 100.0)) (x4 (hz->radians 5.0))) (do ((i 0 (+ i 1))) ((= i 50)) (let ((o1 (polywave g1 x2)) (o2 (* 1.0 (polywave g2 x2))) (o3 (polywave g3 (* x4 20.0))) (o4 (polywave g4 (* 20.0 x4))) (o5 (polywave g5 (* x1 x2))) (o6 (* 1.0 (polywave g6 (* 20.0 x4))))) (if (> (abs (- (+ o2 o3 o4 o5 o6) (* 5 o1))) 1e-6) (format #t "~A: ~1,4F ~1,4F ~1,4F ~1,4F ~1,4F ~1,4F~%" i o1 o2 o3 o4 o5 o6)))))) (define (test-simple-polywave n offset kind) (let ((p (make-polywave 400.0 (let ((h (if offset (list offset 0) (list)))) (do ((i 1 (+ i 1))) ((> i n)) (set! h (cons (* i .1) (cons i h)))) (reverse h)) kind)) (vp (make-float-vector 200)) (vo (make-float-vector 200)) (ob (make-oscil-bank (apply float-vector (let ((frqs (if offset (list 0.0) (list)))) (do ((i 1 (+ i 1))) ((> i n)) (set! frqs (cons (hz->radians (* i 400.0)) frqs))) (reverse frqs))) (let ((phases (make-float-vector (+ n (if offset 1 0)) (if (= kind mus-chebyshev-second-kind) 0.0 (/ pi 2))))) (if (and offset (= kind mus-chebyshev-second-kind)) (set! (phases 0) (/ pi 2))) phases) (apply float-vector (let ((amps (if offset (list offset) (list)))) (do ((i 1 (+ i 1))) ((> i n)) (set! amps (cons (* i .1) amps))) (reverse amps))) #t))) (do ((i 0 (+ i 1))) ((= i 200)) (float-vector-set! vp i (polywave p))) (do ((i 0 (+ i 1))) ((= i 200)) (float-vector-set! vo i (oscil-bank ob))) (if (not (mus-arrays-equal? vp vo)) (format *stderr* ";simple polywave ~A ~A ~A: ~A~% ~A~% ~A~%~A ~A~%" n offset (if (= kind mus-chebyshev-first-kind) 'first 'second) (float-vector-peak (float-vector-subtract! (copy vp) vo)) vp vo p ob)) (let ((temp 0.0)) (do ((i 0 (+ i 1))) ((= i 200)) (set! temp (polywave p)) (vector-set! vp i temp) (set! (vo i) (oscil-bank ob))) (if (not (mus-arrays-equal? vp vo)) (format *stderr* ";simple polywave (temps) ~A ~A ~A: ~A~% ~A~% ~A~%~A ~A~%" n offset (if (= kind mus-chebyshev-first-kind) 'first 'second) (float-vector-peak (float-vector-subtract! (copy vp) vo)) vp vo p ob))) (let ((t1 (with-sound ("test.snd") (do ((i 0 (+ i 1))) ((= i 200)) (outa i (polywave p))))) (t2 (with-sound ("tst.snd") (do ((i 0 (+ i 1))) ((= i 200)) (outa i (oscil-bank ob)))))) (set! vp (channel->float-vector 0 200 (find-sound t1) 0)) (set! vo (channel->float-vector 0 200 (find-sound t2) 0)) (if (not (mus-arrays-equal? vp vo)) (format *stderr* ";simple polywave (with-sound) n: ~A, offset: ~A, type: ~A (len: ~D ~D): dist: ~A~% ~A~% ~A~%~A ~A~%" n offset (if (= kind mus-chebyshev-first-kind) 'first 'second) (length vp) (length vo) (float-vector-peak (float-vector-subtract! (copy vp) vo)) vp vo p ob)) (close-sound (find-sound t1)) (close-sound (find-sound t2))))) (define (test-simple-nsin n) (let ((p (make-nsin 400.0 n)) (vp (make-float-vector 200)) (vo (make-float-vector 200))) (let ((ob (make-oscil-bank (apply float-vector (let ((frqs ())) (do ((i 1 (+ i 1))) ((> i n)) (set! frqs (cons (hz->radians (* i 400.0)) frqs))) (reverse frqs))) (make-float-vector n 0.0) (make-float-vector n (mus-scaler p)) #t))) (do ((i 0 (+ i 1))) ((= i 200)) (float-vector-set! vp i (nsin p))) (do ((i 0 (+ i 1))) ((= i 200)) (float-vector-set! vo i (oscil-bank ob))) (if (not (mus-arrays-equal? vp vo)) (format *stderr* ";simple nsin ~A: ~A~% ~A~% ~A~%~A ~A~%" n (float-vector-peak (float-vector-subtract! (copy vp) vo)) vp vo p ob))))) (define (test-simple-ncos n) (let ((p (make-ncos 400.0 n)) (vp (make-float-vector 200)) (vo (make-float-vector 200))) (let ((ob (make-oscil-bank (apply float-vector (let ((frqs ())) (do ((i 1 (+ i 1))) ((> i n)) (set! frqs (cons (hz->radians (* i 400.0)) frqs))) (reverse frqs))) (make-float-vector n (/ pi 2.0)) (make-float-vector n (mus-scaler p)) #t))) (do ((i 0 (+ i 1))) ((= i 200)) (float-vector-set! vp i (ncos p))) (do ((i 0 (+ i 1))) ((= i 200)) (float-vector-set! vo i (oscil-bank ob))) (if (not (mus-arrays-equal? vp vo)) (format *stderr* ";simple ncos ~A: ~A~% ~A~% ~A~%~A ~A~%" n (float-vector-peak (float-vector-subtract! (copy vp) vo)) vp vo p ob))))) (define (snd-test-jc-reverb decay-dur low-pass volume amp-env) (let ((allpass1 (make-all-pass -0.700 0.700 1051)) (allpass2 (make-all-pass -0.700 0.700 337)) (allpass3 (make-all-pass -0.700 0.700 113)) (comb1 (make-comb 0.742 4799)) (comb2 (make-comb 0.733 4999)) (comb3 (make-comb 0.715 5399)) (comb4 (make-comb 0.697 5801)) (dur (+ decay-dur (/ (framples) (srate)))) (outdel (make-delay (seconds->samples .013)))) (let ((combs (make-comb-bank (vector comb1 comb2 comb3 comb4))) (allpasses (make-all-pass-bank (vector allpass1 allpass2 allpass3)))) (if (or amp-env low-pass) (let ((flt (and low-pass (make-fir-filter 3 (float-vector 0.25 0.5 0.25)))) (envA (make-env :envelope (or amp-env '(0 1 1 1)) :scaler volume :duration dur))) (if low-pass (map-channel (lambda (inval) (+ inval (delay outdel (* (env envA) (fir-filter flt (comb-bank combs (all-pass-bank allpasses inval))))))) 0 (round (* dur (srate)))) (map-channel (lambda (inval) (+ inval (delay outdel (* (env envA) (comb-bank combs (all-pass-bank allpasses inval)))))) 0 (round (* dur (srate)))))) (map-channel (lambda (inval) (+ inval (delay outdel (* volume (comb-bank combs (all-pass-bank allpasses inval)))))) 0 (round (* dur (srate)))))))) ;;; -------- scissor-tailed flycatcher ;;; ;;; mix a scissor-tailed flycatcher call into the current sound ;;; see bird.scm for lots more birds (define scissor (let ((documentation "(scissor beg) is the scissor-tailed flycatcher")) (lambda (begin-time) ; test 23 also (let ((scissorf '(0 0 40 1 60 1 100 0))) (bigbird begin-time 0.05 1800 1800 .2 scissorf '(0 0 25 1 75 1 100 0) '(1 .5 2 1 3 .5 4 .1 5 .01)))))) (define (snd_test_8) ;; ---------------- (define (bumpy) (let* ((x 0.0) (xi (/ 1.0 (framples))) (start 0) (end 1) (scl (exp (/ 4.0 (- end start))))) ; normalize it (map-channel (lambda (y) (let ((val (if (or (<= x start) ; don't divide by zero (>= x end)) 0.0 (* (exp (/ -1.0 (- x start))) (exp (/ -1.0 (- end x))))))) (set! x (+ x xi)) (* scl val)))))) ;; ---------------- (define test-scanned-synthesis ;; check out scanned-synthesis (lambda (amp dur mass xspring damp) (let* ((size 256) (x0 (make-float-vector size)) (x1 (make-float-vector size)) (x2 (make-float-vector size))) (do ((i 0 (+ i 1))) ((= i 12)) (let ((val (sin (/ (* 2 pi i) 12.0)))) (set! (x1 (+ i (- (/ size 4) 6))) val))) (let ((gen1 (make-table-lookup 440.0 :wave x1)) (gen2 (make-table-lookup 440.0 :wave x2)) (recompute-samps 30) ;just a quick guess (data (make-float-vector dur))) (do ((i 0 (+ i 1)) (k 0.0) (kincr (/ 1.0 recompute-samps))) ((= i dur)) (if (>= k 1.0) (begin (set! k 0.0) (compute-uniform-circular-string size x0 x1 x2 mass xspring damp)) (set! k (+ k kincr))) (let ((g1 (table-lookup gen1)) (g2 (table-lookup gen2))) (set! (data i) (+ g2 (* k (- g1 g2)))))) (let ((curamp (float-vector-peak data))) (float-vector-scale! data (/ amp curamp))) (float-vector->channel data 0 dur))))) ;; (test-scanned-synthesis .1 10000 1.0 0.1 0.0) ;; ---------------- (define* (array-interp-sound-diff snd chn) (define (envelope->float-vector e len) (let ((v (make-float-vector len)) (e (make-env e :length len))) (do ((i 0 (+ i 1))) ((= i len)) (set! (v i) (env e))) v)) (let ((tbl (envelope->float-vector (list 0.0 -1.0 1.0 1.0) 1001)) (curpos (edit-position snd chn))) (map-channel (lambda (y) (array-interp tbl (+ 500.0 (* y 500)) 1000)) 0 #f snd chn) (let ((r (make-sampler 0 snd chn 1 curpos)) (mx 0.0)) (scan-channel (lambda (y) (set! mx (max mx (abs (- y (next-sample r)))))) 0 #f snd chn) mx))) ;; ---------------- (define make-papoulis-window (let ((documentation "(make-papoulis-window size) returns a papoulis window os the given size")) (lambda (n) (let ((v (make-float-vector n)) (n2 (/ n 2))) (do ((i (- n2) (+ i 1))) ((= i n2)) (let* ((ratio (/ i n)) (pratio (* 2 pi ratio))) (set! (v (+ i n2)) (+ (/ (abs (sin pratio)) pi) (* (- 1.0 (* 2 (abs ratio))) (cos pratio)))))) v)))) ;; ---------------- (define make-dpss-window (let ((documentation "(make-dpss-window size w) returns a prolate spheriodal (slepian) window of the given size")) ;; from Verma, Bilbao, Meng, "The Digital Prolate Spheroidal Window" ;; output checked using Julius Smith's dpssw.m, although my "w" is different (lambda (n w) (let ((mat (make-float-vector (list n n) 0.0)) (cw (cos (* 2 pi w)))) (do ((i 0 (+ i 1))) ((= i n)) (let ((n2 (- (* 0.5 (- n 1)) i))) (set! (mat i i) (* cw n2 n2)) (if (< i (- n 1)) (set! (mat i (+ i 1)) (* 0.5 (+ i 1) (- n 1 i)))) (if (> i 0) (set! (mat i (- i 1)) (* 0.5 i (- n i)))))) (let* ((vc (vector-ref (cadr (gsl-eigenvectors mat)) 0)) ; cadr->vector of fv-vectors (v (copy vc (make-float-vector (length vc)))) (pk 0.0)) ;; sign of eigenvalue is arbitrary, and eigenvector is scaled to sum to 1.0 ;; but we want peak of 1.0 to serve as fft window (do ((i 0 (+ i 1))) ((= i n)) (if (> (abs (v i)) (abs pk)) (set! pk (v i)))) (float-vector-scale! v (/ 1.0 pk))))))) ;; ---------------- (define (test-lpc) (define (make-sine n) (let ((data (make-float-vector n 0.0)) (incr (/ (* 2.0 pi) n))) (do ((i 0 (+ i 1)) (x 0.0 (+ x incr))) ((= i n) data) (set! (data i) (sin x))))) (define (make-sines n) (let ((data (make-float-vector n 0.0)) (incr (/ (* 2.0 pi) n))) (do ((i 0 (+ i 1)) (x 0.0 (+ x incr))) ((= i n) data) (set! (data i) (+ (sin x) (* .25 (sin (* 2.0 x))) (* .125 (sin (* 4.0 x)))))))) (let ((vals (lpc-predict (float-vector 0 1 2 3 4 5 6 7) 8 (lpc-coeffs (float-vector 0 1 2 3 4 5 6 7) 8 4) 4 2))) (if (not (vequal vals (float-vector 7.906 8.557))) (snd-display #__line__ ";predict ramp: ~A" vals))) (let ((vals (lpc-predict (float-vector 0 1 2 3 4 5 6 7) 8 (lpc-coeffs (float-vector 0 1 2 3 4 5 6 7) 8 7) 7 2))) (if (not (vequal vals (float-vector 7.971 8.816))) (snd-display #__line__ ";predict ramp 1: ~A" vals))) (let ((vals (lpc-predict (float-vector 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14) 15 (lpc-coeffs (float-vector 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14) 15 7) 7 5))) (if (not (vequal vals (float-vector 14.999 15.995 16.980 17.940 18.851))) (snd-display #__line__ ";predict ramp 2: ~A" vals))) (let ((vals (lpc-predict (float-vector 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14) 15 (lpc-coeffs (float-vector 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14) 15 14) 14 5))) (if (not (vequal vals (float-vector 15.000 16.000 16.998 17.991 18.971))) (snd-display #__line__ ";predict ramp 3: ~A" vals))) (let ((vals (lpc-predict (make-sine 16) 16 (lpc-coeffs (make-sine 16) 16 8) 8 2))) (if (not (vequal vals (float-vector 0.000 0.383))) (snd-display #__line__ ";predict sine: ~A" vals))) (let ((vals (lpc-predict (make-sine 16) 16 (lpc-coeffs (make-sine 16) 16 8) 8 8))) (if (not (vequal vals (float-vector 0.000 0.383 0.707 0.924 1.000 0.924 0.707 0.383))) (snd-display #__line__ ";predict sine 1: ~A" vals))) (let ((vals (lpc-predict (make-sines 32) 32 (lpc-coeffs (make-sines 32) 32 8) 8 8))) (if (not (vequal vals (float-vector 0.000 0.379 0.686 0.880 0.970 1.001 1.022 1.053))) (snd-display #__line__ ";predict sines: ~A" vals))) (let ((vals (lpc-predict (make-sines 32) 32 (lpc-coeffs (make-sines 32) 32 16) 16 8))) (if (and (not (vequal vals (float-vector 0.000 0.379 0.684 0.876 0.961 0.987 1.006 1.046))) (not (vequal vals (float-vector 0.000 0.379 0.685 0.876 0.961 0.985 0.998 1.029)))) (snd-display #__line__ ";predict sines 1: ~A" vals))) (let ((vals (lpc-predict (make-sines 32) 32 (lpc-coeffs (make-sines 32) 32 30) 30 4))) (if (and (not (vequal vals (float-vector 0.000 0.379 0.685 0.878))) (not (vequal vals (float-vector 0.000 0.379 0.684 0.875)))) ; double float-vectors (snd-display #__line__ ";predict sines 2: ~A" vals))) (let ((vals (lpc-predict (make-sines 64) 64 (lpc-coeffs (make-sines 64) 64 32) 32 8))) (if (not (vequal vals (float-vector 0.000 0.195 0.379 0.545 0.684 0.795 0.875 0.927))) (snd-display #__line__ ";predict sines 3: ~A" vals)))) ;; ---------------- (define (test-unclip-channel) (let ((ind (new-sound "test.snd" 2 22050 mus-lfloat mus-next "unclip-channel test" 1))) (set! (sync ind) 1) (mix "oboe.snd" 0 0 ind 0 #f) (mix "oboe.snd" 0 0 ind 1 #f) (let ((scl (/ 1.01 (maxamp ind 0))) (dur (framples ind 0))) (scale-channel scl 0 dur ind 0) (scale-channel scl 0 dur ind 1)) (let* ((vals (unclip-channel ind 1)) (umax (vals 1)) (clips (vals 3)) (lmax (vals 5))) (if (not (= clips 20)) (snd-display #__line__ ";unclip-channel 0 oboe clips: ~A" clips)) (if (not (= lmax 1)) (snd-display #__line__ ";unclip-channel 0 oboe max len: ~A" lmax)) (if (fneq umax .999) (snd-display #__line__ ";unclip-channel 0 oboe maxamp: ~A" umax))) (revert-sound ind) (let ((data (make-float-vector 100 0.0)) (e (make-env '(0 0 1 .8 1.5 1.0 2.0 1.0 2.5 .8 3.5 0) :length 101)) (o (make-oscil 1000))) (do ((i 0 (+ i 1))) ((= i 100) data) (set! (data i) (* 1.05 (env e) (oscil o)))) (float-vector->channel data 0 100 ind 0) (float-vector->channel data 0 100 ind 1)) (let* ((vals (unclip-channel ind 1)) (umax (vals 1)) (clips (vals 3)) (lmax (vals 5))) (if (not (= clips 1)) (snd-display #__line__ ";unclip-channel 1 sine clips: ~A" clips)) (if (not (= lmax 2)) (snd-display #__line__ ";unclip-channel 1 sine max len: ~A" lmax)) (if (fneq umax .999) (snd-display #__line__ ";unclip-channel 1 sine maxamp: ~A" umax))) (revert-sound ind) (let ((data (make-float-vector 100 0.0)) (e (make-env '(0 0 1 .8 1.75 1.0 2.0 1.0 2.25 .8 3.5 0) :length 101)) (o (make-oscil 1000))) (do ((i 0 (+ i 1))) ((= i 100) data) (set! (data i) (* 1.1 (env e) (oscil o)))) (float-vector->channel data 0 100 ind 0) (float-vector->channel data 0 100 ind 1)) (let* ((vals (unclip-channel ind 1)) (umax (vals 1)) (clips (vals 3)) (lmax (vals 5))) (if (not (= clips 1)) (snd-display #__line__ ";unclip-channel 2 sine clips: ~A" clips)) (if (not (= lmax 3)) (snd-display #__line__ ";unclip-channel 2 sine max len: ~A" lmax)) (if (fneq umax .999) (snd-display #__line__ ";unclip-channel 2 sine maxamp: ~A" umax))) (revert-sound ind) (let ((data (make-float-vector 100 0.0)) (e (make-env '(0 0 1 .8 1.85 1.0 2.0 1.0 2.15 .8 3.5 0) :length 101)) (o1 (make-oscil 1000)) (o2 (make-oscil 2000))) (do ((i 0 (+ i 1))) ((= i 100) data) (set! (data i) (* 1.2 (env e) (+ (* .75 (oscil o1)) (* .25 (oscil o2)))))) (float-vector->channel data 0 100 ind 0) (float-vector->channel data 0 100 ind 1)) (let* ((vals (unclip-channel ind 1)) (umax (vals 1)) (clips (vals 3)) (lmax (vals 5))) (if (not (= clips 1)) (snd-display #__line__ ";unclip-channel 3 sine clips: ~A" clips)) (if (not (= lmax 1)) (snd-display #__line__ ";unclip-channel 3 sine max len: ~A" lmax)) (if (fneq umax .999) (snd-display #__line__ ";unclip-channel 3 sine maxamp: ~A" umax))) (revert-sound ind) (let ((data (make-float-vector 100 0.0)) (e (make-env '(0 0 40 .75 45 1.0 50 1.25 55 1.0 60 .75 100 0.0) :length 101)) (o1 (make-oscil 1000)) (o2 (make-oscil 2000))) (do ((i 0 (+ i 1))) ((= i 100) data) (set! (data i) (* 1.5 (env e) (+ (* .75 (oscil o1)) (* .25 (oscil o2)))))) (float-vector->channel data 0 100 ind 0) (float-vector->channel data 0 100 ind 1)) (let* ((vals (unclip-channel ind 1)) (umax (vals 1)) (clips (vals 3)) (lmax (vals 5))) (if (not (= clips 1)) (snd-display #__line__ ";unclip-channel 4 sine clips: ~A" clips)) (if (not (= lmax 4)) (snd-display #__line__ ";unclip-channel 4 sine max len: ~A" lmax)) (if (fneq umax .999) (snd-display #__line__ ";unclip-channel 4 sine maxamp: ~A" umax))) (revert-sound ind) (let ((data (make-float-vector 100 0.0)) (o1 (make-oscil 1000))) (do ((i 0 (+ i 1))) ((= i 100) data) (set! (data i) (* .25 (oscil o1)))) (let ((true-max (float-vector-peak data))) (set! (data 50) (+ (data 50) 1.25)) (float-vector->channel data 0 100 ind 0) (float-vector->channel data 0 100 ind 1) (let* ((vals (unclip-channel ind 1)) (umax (vals 1)) (clips (vals 3)) (lmax (vals 5))) (if (not (= clips 1)) (snd-display #__line__ ";unclip-channel 5 click clips: ~A" clips)) (if (not (= lmax 1)) (snd-display #__line__ ";unclip-channel 5 click max len: ~A" lmax)) (if (fneq umax true-max) (snd-display #__line__ ";unclip-channel 5 click maxamp: ~A ~A" umax true-max))))) (revert-sound ind) (let ((data (make-float-vector 100 0.0)) (o1 (make-oscil 1000))) (do ((i 0 (+ i 1))) ((= i 100) data) (set! (data i) (* .25 (oscil o1)))) (let ((true-max (float-vector-peak data))) (do ((i 49 (+ i 1))) ((= i 51)) (set! (data i) (+ (data i) 1.25))) (float-vector->channel data 0 100 ind 0) (float-vector->channel data 0 100 ind 1) (let* ((vals (unclip-channel ind 1)) (umax (vals 1)) (clips (vals 3)) (lmax (vals 5))) (if (not (= clips 1)) (snd-display #__line__ ";unclip-channel 6 click clips: ~A" clips)) (if (not (= lmax 2)) (snd-display #__line__ ";unclip-channel 6 click max len: ~A" lmax)) (if (fneq umax true-max) (snd-display #__line__ ";unclip-channel 6 click maxamp: ~A ~A" umax true-max))))) (revert-sound ind) (let ((data (make-float-vector 100 0.0)) (o1 (make-oscil 1000))) (do ((i 0 (+ i 1))) ((= i 100) data) (set! (data i) (* .25 (oscil o1)))) (let ((true-max (float-vector-peak data))) (do ((i 45 (+ i 1))) ((= i 55)) (set! (data i) (+ (data i) 1.25))) (float-vector->channel data 0 100 ind 0) (float-vector->channel data 0 100 ind 1) (let* ((vals (unclip-channel ind 1)) (umax (vals 1)) (clips (vals 3)) (lmax (vals 5))) (if (not (= clips 1)) (snd-display #__line__ ";unclip-channel 7 click clips: ~A" clips)) (if (not (= lmax 10)) (snd-display #__line__ ";unclip-channel 7 click max len: ~A" lmax)) (if (fneq umax true-max) (snd-display #__line__ ";unclip-channel 7 click maxamp: ~A ~A" umax true-max))))) (revert-sound ind) (let ((data (make-float-vector 100 0.0)) (o1 (make-oscil 1000)) (o2 (make-oscil 2000))) (do ((i 0 (+ i 1))) ((= i 100) data) (set! (data i) (* .25 (+ (oscil o1) (oscil o2))))) (let ((true-max (float-vector-peak data))) (do ((i 45 (+ i 1))) ((= i 55)) (set! (data i) (+ (data i) 1.25))) (float-vector->channel data 0 100 ind 0) (float-vector->channel data 0 100 ind 1) (let* ((vals (unclip-channel ind 1)) (umax (vals 1)) (clips (vals 3)) (lmax (vals 5))) (if (not (= clips 1)) (snd-display #__line__ ";unclip-channel 8 click clips: ~A" clips)) (if (not (= lmax 10)) (snd-display #__line__ ";unclip-channel 8 click max len: ~A" lmax)) (if (fneq umax true-max) (snd-display #__line__ ";unclip-channel 8 click maxamp: ~A ~A" umax true-max))))) (revert-sound ind) (let ((data (make-float-vector 200 0.0)) (o1 (make-oscil 1000)) (o2 (make-oscil 2000))) (do ((i 0 (+ i 1))) ((= i 200) data) (set! (data i) (* .25 (+ (oscil o1) (oscil o2))))) (let ((true-max (float-vector-peak data))) (do ((i 45 (+ i 1))) ((= i 55)) (set! (data i) (+ (data i) 2.0))) (do ((i 75 (+ i 1))) ((= i 85)) (set! (data i) (+ (data i) 2.0))) (float-vector->channel data 0 200 ind 0) (float-vector->channel data 0 200 ind 1) (let* ((vals (unclip-channel ind 1)) (umax (vals 1)) (clips (vals 3)) (lmax (vals 5))) (if (not (= clips 2)) (snd-display #__line__ ";unclip-channel 9 collision clips: ~A" clips)) (if (not (= lmax 10)) (snd-display #__line__ ";unclip-channel 9 collision max len: ~A" lmax)) (if (fneq umax true-max) (snd-display #__line__ ";unclip-channel 9 collision maxamp: ~A ~A" umax true-max))))) (revert-sound ind) (mix "oboe.snd" 0 0 ind 0 #f) (mix "oboe.snd" 0 0 ind 1 #f) (scale-sound (/ 1.01 (maxamp ind 0))) (let* ((vals (unclip-channel ind 1)) (umax (vals 1)) (clips (vals 3)) (lmax (vals 5))) (if (not (= clips 20)) (snd-display #__line__ ";unclip-channel 10 oboe clips: ~A" clips)) (if (not (= lmax 1)) (snd-display #__line__ ";unclip-channel 10 oboe max len: ~A" lmax)) (if (fneq umax 0.999) (snd-display #__line__ ";unclip-channel 10 oboe maxamp: ~A" umax))) (revert-sound ind) (mix "oboe.snd" 0 0 ind 0 #f) (mix "oboe.snd" 0 0 ind 1 #f) (scale-sound (/ 1.05 (maxamp ind 0))) (let* ((vals (unclip-channel ind 1)) (umax (vals 1)) (clips (vals 3)) (lmax (vals 5))) (if (not (= clips 217)) (snd-display #__line__ ";unclip-channel 11 oboe clips: ~A" clips)) (if (not (= lmax 2)) (snd-display #__line__ ";unclip-channel 11 oboe max len: ~A" lmax)) (if (fneq umax 0.999) (snd-display #__line__ ";unclip-channel 11 oboe maxamp: ~A" umax))) (revert-sound ind) (mix "oboe.snd" 0 0 ind 0 #f) (mix "oboe.snd" 0 0 ind 1 #f) (let ((scl (/ 1.2 (maxamp ind 0)))) (env-sound (make-env (list 0 0 .48 (/ scl 2) .5 scl .52 (/ scl 2) 1.0 0) :length (framples ind 0)))) (let* ((vals (unclip-channel ind 1)) (umax (vals 1)) (clips (vals 3)) (lmax (vals 5))) (if (not (= clips 28)) (snd-display #__line__ ";unclip-channel 12 oboe clips: ~A" clips)) (if (not (= lmax 3)) (snd-display #__line__ ";unclip-channel 12 oboe max len: ~A" lmax)) (if (fneq umax 0.999) (snd-display #__line__ ";unclip-channel 12 oboe maxamp: ~A" umax))) (close-sound ind))) ;; ---------------- (define (analog-filter-tests) (define v (make-float-vector 1000)) (define (sweep->bins flt bins) (let ((ind (open-sound "sweep.snd"))) (if (mus-generator? flt) (clm-channel flt) (map-channel flt)) (let ((mx (maxamp)) (resp (make-float-vector bins)) (size (round (/ 22050 bins))) (data (channel->float-vector))) (do ((i 0 (+ i 1))) ((= i bins)) (float-vector-set! resp i (float-vector-peak (make-shared-vector data (list size) (* i size))))) (close-sound ind) (list mx resp)))) (define (filter-response-max f1) (set! (v 0) (f1 1.0)) (do ((i 1 (+ i 1))) ((= i 1000)) (set! (v i) (filter f1 0.0))) (float-vector-peak v)) (define (filter-equal? f1 f2) ; equalp in clm2xen is too restrictive (and (= (mus-order f1) (mus-order f2)) (vequal (mus-xcoeffs f1) (mus-xcoeffs f2)) (vequal (mus-ycoeffs f1) (mus-ycoeffs f2)))) ;; ---------------- butterworth tests ---------------- (let ((poles (list (float-vector 1.000 1.414 1.000) ; numerous references provide these tables (y[0] is ignored) (float-vector 1.000 1.848 1.000 1.000 0.765 1.000) (float-vector 1.000 1.932 1.000 1.000 1.414 1.000 1.000 0.518 1.000) (float-vector 1.000 1.962 1.000 1.000 1.663 1.000 1.000 1.111 1.000 1.000 0.390 1.000) (float-vector 1.000 1.975 1.000 1.000 1.782 1.000 1.000 1.414 1.000 1.000 0.908 1.000 1.000 0.313 1.000)))) (do ((i 2 (+ i 2)) (k 0 (+ k 1))) ((>= i 12)) (let ((vals (butterworth-prototype i))) (if (not (vequal (cadr vals) (poles k))) (snd-display #__line__ ";butterworth prototype poles ~A: ~A (~A)" i (cadr vals) (poles k))) (let ((zeros (make-float-vector (* (+ k 1) 3)))) (do ((j 2 (+ j 3))) ((>= j (* (+ k 1) 3))) (set! (zeros j) 1.0)) (if (not (vequal (car vals) zeros)) (snd-display #__line__ ";butterworth prototype zeros ~A: ~A (~A)" i (car vals) zeros))))) (do ((cutoff .1 (+ cutoff .1)) (m 0 (+ 1 m))) ((= m 3)) (do ((i 2 (+ i 2)) (k 1 (+ k 1))) ((= i 16)) (let ((local (make-butterworth-lowpass i cutoff)) (dsp (make-butter-lp k (* *clm-srate* cutoff)))) (if (not (filter-equal? local dsp)) (snd-display #__line__ ";butterworth lowpass ~A ~A ~A" cutoff local dsp))) (let ((local (make-butterworth-highpass i cutoff)) (dsp (make-butter-hp k (* *clm-srate* cutoff)))) (if (not (filter-equal? local dsp)) (snd-display #__line__ ";butterworth highpass ~A ~A ~A" cutoff local dsp))))) (let ((ind (open-sound "oboe.snd"))) (map-channel (make-eliminate-hum 550)) (let ((peaker (make-peaking-2 500 1000 1.0))) (map-channel peaker)) (map-channel (chordalize)) (close-sound ind)) (let ((ind (new-sound "sweep.snd" 1 22050 mus-ldouble mus-next #f 22050))) (let ((ph (make-one-pole 1.0 -1.0)) (fq (make-one-pole 1.0 -1.0)) (incr (/ pi 22050.0))) (map-channel (lambda (y) (* .5 (sin (one-pole ph (one-pole fq incr))))) 2)) ; make it look like the old form (save-sound ind) (close-sound ind)) (let* ((f1 (make-butterworth-lowpass 8 .1)) (vals (sweep->bins f1 10))) (if (fneq (car vals) .5) (snd-display #__line__ ";butterworth lp 8 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.500 0.500 0.359 0.014 0.001 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";butterworth lp 8 .1 spect: ~A" (cadr vals)))) (let* ((f1 (make-butterworth-lowpass 12 .25)) (vals (sweep->bins f1 10))) (if (fneq (car vals) .5) (snd-display #__line__ ";butterworth lp 12 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.500 0.500 0.500 0.500 0.499 0.358 0.010 0.000 0.000 0.000))) (snd-display #__line__ ";butterworth lp 12 .25 spect: ~A" (cadr vals)))) (let* ((f1 (make-butterworth-lowpass 10 .4)) (vals (sweep->bins f1 10))) (if (fneq (car vals) .5) (snd-display #__line__ ";butterworth lp 10 max: ~A" (car vals))) (if (and (not (vequal1 (cadr vals) (float-vector 0.500 0.500 0.500 0.500 0.500 0.500 0.500 0.499 0.361 0.001))) (not (vequal1 (cadr vals) (float-vector 0.500 0.500 0.500 0.500 0.500 0.500 0.500 0.499 0.360 0.002)))) (snd-display #__line__ ";butterworth lp 10 .4 spect: ~A" (cadr vals)))) (do ((i 2 (+ i 2))) ((= i 12)) (do ((j .1 (+ j .1))) ((>= j .45)) (let* ((f1 (make-butterworth-lowpass i j)) (mx (filter-response-max f1))) (if (> mx 1.0) (snd-display #__line__ ";butter low max ~A ~A: ~A" i j mx))))) (let* ((f1 (make-butterworth-highpass 8 .1)) (vals (sweep->bins f1 10))) (if (fneq (car vals) .5) (snd-display #__line__ ";butterworth hp 8 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.001 0.348 0.500 0.500 0.500 0.500 0.500 0.500 0.500 0.500))) (snd-display #__line__ ";butterworth hp 8 .1 spect: ~A" (cadr vals)))) (let* ((f1 (make-butterworth-highpass 12 .25)) (vals (sweep->bins f1 10))) (if (fneq (car vals) .5) (snd-display #__line__ ";butterworth hp 12 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.000 0.000 0.000 0.011 0.348 0.500 0.500 0.500 0.500 0.500))) (snd-display #__line__ ";butterworth hp 12 .25 spect: ~A" (cadr vals)))) (let* ((f1 (make-butterworth-highpass 10 .4)) (vals (sweep->bins f1 10))) (if (fneq (car vals) .5) (snd-display #__line__ ";butterworth hp 10 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.000 0.000 0.000 0.000 0.000 0.000 0.005 0.343 0.501 0.501))) (snd-display #__line__ ";butterworth hp 10 .4 spect: ~A" (cadr vals)))) (let* ((f1 (make-butterworth-bandpass 4 .1 .2)) (vals (sweep->bins f1 10))) (if (> (abs (- (car vals) .5)) .05) (snd-display #__line__ ";butterworth bp 4 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.028 0.350 0.481 0.479 0.346 0.132 0.038 0.009 0.002 0.000))) (snd-display #__line__ ";butterworth bp 4 .1 .2 spect: ~A" (cadr vals)))) (let* ((f1 (make-butterworth-bandpass 12 .1 .2)) (vals (sweep->bins f1 10))) (if (> (abs (- (car vals) .5)) .05) (snd-display #__line__ ";butterworth bp 12 max: ~A" (car vals))) (if (and (not (vequal1 (cadr vals) (float-vector 0.006 0.317 0.501 0.500 0.358 0.009 0.000 0.000 0.000 0.000))) (not (vequal1 (cadr vals) (float-vector 0.012 0.319 0.501 0.500 0.358 0.009 0.000 0.000 0.000 0.000))) (not (vequal1 (cadr vals) (float-vector 0.000 0.323 0.501 0.500 0.358 0.009 0.000 0.000 0.000 0.000)))) (snd-display #__line__ ";butterworth bp 12 .1 .2 spect: ~A" (cadr vals)))) (let* ((f1 (make-butterworth-bandpass 8 .3 .4)) (vals (sweep->bins f1 10))) (if (> (abs (- (car vals) .5)) .05) (snd-display #__line__ ";butterworth bp 8 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.000 0.000 0.000 0.003 0.034 0.344 0.499 0.499 0.353 0.002))) (snd-display #__line__ ";butterworth bp 8 .3 .4 spect: ~A" (cadr vals)))) (do ((i 2 (+ i 2))) ((= i 12)) (do ((j .1 (+ j .1))) ((>= j .45)) (let* ((f1 (make-butterworth-highpass i j)) (mx (filter-response-max f1))) (if (> mx 1.0) (snd-display #__line__ ";butter high max ~A ~A: ~A" i j mx))))) (let* ((f1 (make-butterworth-bandstop 4 .1 .2)) (vals (sweep->bins f1 10))) (if (> (abs (- (car vals) .5)) .05) (snd-display #__line__ ";butterworth bs 4 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.500 0.500 0.347 0.339 0.481 0.499 0.500 0.500 0.500 0.500))) (snd-display #__line__ ";butterworth bs 4 .1 .2 spect: ~A" (cadr vals)))) (let* ((f1 (make-butterworth-bandstop 12 .1 .2)) (vals (sweep->bins f1 10))) (if (> (abs (- (car vals) .5)) .05) (snd-display #__line__ ";butterworth bs 12 max: ~A" (car vals))) (if (and (not (vequal1 (cadr vals) (float-vector 0.503 0.503 0.364 0.334 0.500 0.500 0.500 0.500 0.500 0.500))) (not (vequal1 (cadr vals) (float-vector 0.502 0.503 0.365 0.334 0.500 0.500 0.500 0.500 0.500 0.500))) (not (vequal1 (cadr vals) (float-vector 0.500 0.500 0.365 0.334 0.500 0.500 0.500 0.500 0.500 0.500)))) (snd-display #__line__ ";butterworth bs 12 .1 .2 spect: ~A" (cadr vals)))) (let* ((f1 (make-butterworth-bandstop 8 .3 .4)) (vals (sweep->bins f1 10))) (if (> (abs (- (car vals) .5)) .05) (snd-display #__line__ ";butterworth bs 8 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.500 0.500 0.500 0.500 0.500 0.498 0.354 0.332 0.500 0.500))) (snd-display #__line__ ";butterworth bs 8 .3 .4 spect: ~A" (cadr vals)))) ;; ---------------- Chebyshev ---------------- ;; ripple .01 .1 1 for 2..10 even (let ((poles-01 (list (float-vector 1.000 4.456 10.426) (float-vector 1.000 0.822 2.006 1.000 1.984 1.299) (float-vector 1.000 0.343 1.372 1.000 0.937 0.939 1.000 1.280 0.506) (float-vector 1.000 0.189 1.196 1.000 0.537 0.925 1.000 0.804 0.542 1.000 0.948 0.272) (float-vector 1.000 0.119 1.121 1.000 0.347 0.940 1.000 0.540 0.646 1.000 0.680 0.352 1.000 0.754 0.170))) (zeros (list (float-vector 0.000 0.000 1.000) (float-vector 0.000 0.000 0.250 0.000 0.000 1.000) (float-vector 0.000 0.000 0.062 0.000 0.000 1.000 0.000 0.000 1.000) (float-vector 0.000 0.000 0.016 0.000 0.000 1.000 0.000 0.000 1.000 0.000 0.000 1.000) (float-vector 0.000 0.000 0.004 0.000 0.000 1.000 0.000 0.000 1.000 0.000 0.000 1.000 0.000 0.000 1.000))) (poles-1 (list (float-vector 1.000 2.372 3.314) (float-vector 1.000 0.528 1.330 1.000 1.275 0.623) (float-vector 1.000 0.229 1.129 1.000 0.627 0.696 1.000 0.856 0.263) (float-vector 1.000 0.128 1.069 1.000 0.364 0.799 1.000 0.545 0.416 1.000 0.643 0.146) (float-vector 1.000 0.082 1.044 1.000 0.237 0.862 1.000 0.369 0.568 1.000 0.465 0.274 1.000 0.515 0.092))) (poles-10 (list (float-vector 1.000 1.098 1.103) (float-vector 1.000 0.279 0.987 1.000 0.674 0.279) (float-vector 1.000 0.124 0.991 1.000 0.340 0.558 1.000 0.464 0.125) (float-vector 1.000 0.070 0.994 1.000 0.199 0.724 1.000 0.298 0.341 1.000 0.352 0.070) (float-vector 1.000 0.045 0.996 1.000 0.130 0.814 1.000 0.203 0.521 1.000 0.255 0.227 1.000 0.283 0.045)))) (do ((i 2 (+ i 2)) (k 0 (+ k 1))) ((>= i 12)) (let ((vals (chebyshev-prototype i .01))) (if (not (vequal1 (cadr vals) (poles-01 k))) (snd-display #__line__ ";chebyshev prototype .01 poles ~A: ~A (~A)" i (cadr vals) (poles-01 k)))) (let ((vals (chebyshev-prototype i .1))) (if (not (vequal1 (cadr vals) (poles-1 k))) (snd-display #__line__ ";chebyshev prototype .1 poles ~A: ~A (~A)" i (cadr vals) (poles-1 k)))) (let ((vals (chebyshev-prototype i))) (if (not (vequal1 (cadr vals) (poles-10 k))) (snd-display #__line__ ";chebyshev prototype 1 poles ~A: ~A (~A)" i (cadr vals) (poles-10 k))) (if (not (vequal (car vals) (zeros k))) (snd-display #__line__ ";chebyshev prototype .01 zeros ~A: ~A (~A)" i (car vals) (zeros k)))))) (let* ((f1 (make-chebyshev-lowpass 8 .1)) (vals (sweep->bins f1 10))) (if (ffneq (car vals) .51) (snd-display #__line__ ";chebyshev lp 8 max: ~A" (car vals))) (if (and (not (vequal1 (cadr vals) (float-vector 0.508 0.512 0.468 0.001 0.000 0.000 0.000 0.000 0.000 0.000))) (not (vequal1 (cadr vals) (float-vector 0.507 0.512 0.467 0.001 0.000 0.000 0.000 0.000 0.000 0.000))) (not (vequal1 (cadr vals) (float-vector 0.508 0.513 0.469 0.001 0.000 0.000 0.000 0.000 0.000 0.000))) (not (vequal1 (cadr vals) (float-vector 0.509 0.508 0.465 0.001 0.000 0.000 0.000 0.000 0.000 0.000)))) (snd-display #__line__ ";chebyshev lp 8 .1 spect: ~A" (cadr vals)))) (let* ((f1 (make-chebyshev-lowpass 12 .25)) (vals (sweep->bins f1 10))) (if (ffneq (car vals) .51) (snd-display #__line__ ";chebyshev lp 12 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.509 0.500 0.508 0.508 0.507 0.413 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";chebyshev lp 12 .25 spect: ~A" (cadr vals)))) (let* ((f1 (make-chebyshev-lowpass 10 .4)) (vals (sweep->bins f1 10))) (if (ffneq (car vals) .51) (snd-display #__line__ ";chebyshev lp 10 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.465 0.493 0.509 0.508 0.477 0.507 0.508 0.507 0.431 0.000))) (snd-display #__line__ ";chebyshev lp 10 .4 spect: ~A" (cadr vals)))) (do ((i 2 (+ i 2))) ((= i 10)) (do ((j .1 (+ j .1))) ((>= j .45)) (let* ((f1 (make-chebyshev-lowpass i j)) (mx (filter-response-max f1))) (if (> mx 1.0) (snd-display #__line__ ";cheby low max ~A ~A: ~A" i j mx))))) (let* ((f1 (make-chebyshev-lowpass 8 .1 .01)) (vals (sweep->bins f1 10))) (if (ffneq (car vals) .49) (snd-display #__line__ ";chebyshev lp 8 .1 .01 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.492 0.491 0.483 0.006 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";chebyshev lp 8 .1 .01 spect: ~A" (cadr vals)))) (let* ((f1 (make-chebyshev-lowpass 12 .25 .1)) (vals (sweep->bins f1 10))) (if (ffneq (car vals) .49) (snd-display #__line__ ";chebyshev lp 12 .1 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.488 0.488 0.488 0.488 0.487 0.403 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";chebyshev lp 12 .25 .1 spect: ~A" (cadr vals)))) (let* ((f1 (make-chebyshev-lowpass 10 .4 .001)) (vals (sweep->bins f1 10))) (if (ffneq (car vals) .49) (snd-display #__line__ ";chebyshev lp 10 .001 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.497 0.497 0.497 0.497 0.497 0.497 0.497 0.497 0.488 0.000))) (snd-display #__line__ ";chebyshev lp 10 .4 .001 spect: ~A" (cadr vals)))) (let* ((f1 (make-chebyshev-highpass 8 .1)) (vals (sweep->bins f1 10))) (if (ffneq (car vals) .55) (snd-display #__line__ ";chebyshev hp 8 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.000 0.341 0.551 0.509 0.466 0.501 0.509 0.505 0.481 0.461))) (snd-display #__line__ ";chebyshev hp 8 .1 spect: ~A" (cadr vals)))) (let* ((f1 (make-chebyshev-highpass 12 .25)) (vals (sweep->bins f1 10))) (if (ffneq (car vals) .55) (snd-display #__line__ ";chebyshev hp 12 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.000 0.000 0.000 0.000 0.299 0.554 0.509 0.509 0.500 0.509))) (snd-display #__line__ ";chebyshev hp 12 .25 spect: ~A" (cadr vals)))) (let* ((f1 (make-chebyshev-highpass 10 .4)) (vals (sweep->bins f1 10))) (if (and (not (vequal1 (cadr vals) (float-vector 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.297 0.786 0.677))) (not (vequal1 (cadr vals) (float-vector 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.301 0.788 0.660))) (not (vequal1 (cadr vals) (float-vector 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.322 0.861 0.724))) (not (vequal1 (cadr vals) (float-vector 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.262 0.571 0.509)))) (snd-display #__line__ ";chebyshev hp 10 .4 spect: ~A" (cadr vals)))) (let* ((f1 (make-chebyshev-highpass 8 .1 .01)) (vals (sweep->bins f1 10))) (if (ffneq (car vals) .49) (snd-display #__line__ ";chebyshev hp 8 .1 .01 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.000 0.498 0.498 0.492 0.491 0.492 0.492 0.492 0.491 0.491))) (snd-display #__line__ ";chebyshev hp 8 .1 .01 spect: ~A" (cadr vals)))) (let* ((f1 (make-chebyshev-highpass 12 .25 .1)) (vals (sweep->bins f1 10))) (if (ffneq (car vals) .51) (snd-display #__line__ ";chebyshev hp 12 .1 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.000 0.000 0.000 0.000 0.453 0.516 0.489 0.489 0.488 0.488))) (snd-display #__line__ ";chebyshev hp 12 .25 .1 spect: ~A" (cadr vals)))) (let* ((f1 (make-chebyshev-highpass 10 .4 .001)) (vals (sweep->bins f1 10))) (if (ffneq (car vals) .5) (snd-display #__line__ ";chebyshev hp 10 .001 max: ~A" (car vals))) (if (and (not (vequal1 (cadr vals) (float-vector 0.000 0.000 0.000 0.000 0.000 0.000 0.002 0.501 0.504 0.504))) (not (vequal1 (cadr vals) (float-vector 0.000 0.000 0.000 0.000 0.000 0.000 0.002 0.503 0.505 0.504))) (not (vequal1 (cadr vals) (float-vector 0.000 0.000 0.000 0.000 0.000 0.000 0.002 0.503 0.501 0.497)))) (snd-display #__line__ ";chebyshev hp 10 .4 .001 spect: ~A" (cadr vals)))) (do ((i 2 (+ i 2))) ((= i 10)) (do ((j .1 (+ j .1))) ((>= j .45)) (let* ((f1 (make-chebyshev-highpass i j)) (mx (filter-response-max f1))) (if (> mx 1.0) (snd-display #__line__ ";cheby high max ~A ~A: ~A" i j mx))))) (let* ((f1 (make-chebyshev-bandpass 4 .1 .2)) (vals (sweep->bins f1 10))) (if (> (abs (- (car vals) .5)) .05) (snd-display #__line__ ";chebyshev bp 4 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.009 0.449 0.509 0.505 0.442 0.065 0.013 0.003 0.000 0.000))) (snd-display #__line__ ";chebyshev bp 4 .1 .2 spect: ~A" (cadr vals)))) (let* ((f1 (make-chebyshev-bandpass 6 .1 .2)) (vals (sweep->bins f1 10))) (if (> (abs (- (car vals) .5)) .05) (snd-display #__line__ ";chebyshev bp 6 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.001 0.376 0.505 0.498 0.412 0.011 0.001 0.000 0.000 0.000))) (snd-display #__line__ ";chebyshev bp 6 .1 .2 spect: ~A" (cadr vals)))) (let* ((f1 (make-chebyshev-bandpass 8 .3 .4)) (vals (sweep->bins f1 10))) (if (> (abs (- (car vals) .5)) .05) (snd-display #__line__ ";chebyshev bp 8 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.000 0.000 0.000 0.000 0.002 0.363 0.517 0.513 0.433 0.000))) (snd-display #__line__ ";chebyshev bp 8 .3 .4 spect: ~A" (cadr vals)))) (let* ((f1 (make-chebyshev-bandpass 8 .2 .2 .01)) (vals (sweep->bins f1 10))) (if (> (abs (- (car vals) .5)) .05) (snd-display #__line__ ";chebyshev bp 10 .2 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.000 0.000 0.015 0.483 0.482 0.021 0.001 0.000 0.000 0.000))) (snd-display #__line__ ";chebyshev bp 10 .2 spect: ~A" (cadr vals)))) (let* ((f1 (make-chebyshev-bandstop 4 .1 .4)) (vals (sweep->bins f1 10))) (if (> (abs (- (car vals) .5)) .05) (snd-display #__line__ ";chebyshev bs 4 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.509 0.505 0.447 0.033 0.006 0.006 0.033 0.445 0.512 0.509))) (snd-display #__line__ ";chebyshev bs 4 .1 .4 spect: ~A" (cadr vals)))) (let* ((f1 (make-chebyshev-bandstop 8 .1 .4)) (vals (sweep->bins f1 10))) (if (> (abs (- (car vals) .51)) .05) (snd-display #__line__ ";chebyshev bs 8 max: ~A" (car vals))) (if (and (not (vequal1 (cadr vals) (float-vector 0.508 0.512 0.468 0.001 0.000 0.000 0.001 0.345 0.551 0.507))) (not (vequal1 (cadr vals) (float-vector 0.507 0.512 0.467 0.001 0.000 0.000 0.001 0.344 0.549 0.508))) (not (vequal1 (cadr vals) (float-vector 0.508 0.513 0.469 0.001 0.000 0.000 0.001 0.345 0.552 0.508))) (not (vequal1 (cadr vals) (float-vector 0.509 0.508 0.465 0.001 0.000 0.000 0.001 0.343 0.548 0.508)))) (snd-display #__line__ ";chebyshev bs 8 .1 .4 spect: ~A" (cadr vals)))) (let* ((f1 (make-chebyshev-bandstop 8 .1 .4 .01)) (vals (sweep->bins f1 10))) (if (> (abs (- (car vals) .5)) .05) (snd-display #__line__ ";chebyshev bs 8 .01 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.492 0.491 0.483 0.006 0.000 0.000 0.006 0.494 0.495 0.492))) (snd-display #__line__ ";chebyshev bs 8 .1 .4 .01 spect: ~A" (cadr vals)))) ;; ---------------- inverse-chebyshev ---------------- (let* ((f1 (make-inverse-chebyshev-lowpass 8 .1)) (vals (sweep->bins f1 10))) (if (ffneq (car vals) .51) (snd-display #__line__ ";inverse-chebyshev lp 8 max: ~A" (car vals))) (if (and (not (vequal1 (cadr vals) (float-vector 0.501 0.496 0.001 0.000 0.001 0.000 0.000 0.000 0.000 0.001))) (not (vequal1 (cadr vals) (float-vector 0.500 0.498 0.001 0.000 0.001 0.000 0.000 0.000 0.000 0.001)))) (snd-display #__line__ ";inverse-chebyshev lp 8 .1 spect: ~A" (cadr vals)))) (let* ((f1 (make-inverse-chebyshev-lowpass 12 .25)) (vals (sweep->bins f1 10))) (if (ffneq (car vals) .51) (snd-display #__line__ ";inverse-chebyshev lp 12 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.500 0.500 0.500 0.500 0.496 0.001 0.001 0.001 0.001 0.001))) (snd-display #__line__ ";inverse-chebyshev lp 12 .25 spect: ~A" (cadr vals)))) (let* ((f1 (make-inverse-chebyshev-lowpass 10 .4)) (vals (sweep->bins f1 10))) (if (ffneq (car vals) .51) (snd-display #__line__ ";inverse-chebyshev lp 10 max: ~A" (car vals))) (if (and (not (vequal1 (cadr vals) (float-vector 0.500 0.500 0.500 0.500 0.500 0.500 0.500 0.497 0.001 0.001))) (not (vequal1 (cadr vals) (float-vector 0.500 0.500 0.500 0.500 0.500 0.500 0.500 0.497 0.002 0.002)))) (snd-display #__line__ ";inverse-chebyshev lp 10 .4 spect: ~A" (cadr vals)))) (let* ((f1 (make-inverse-chebyshev-lowpass 10 .4 120)) (vals (sweep->bins f1 10))) (if (ffneq (car vals) .51) (snd-display #__line__ ";inverse-chebyshev lp 10 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.501 0.501 0.501 0.501 0.501 0.500 0.345 0.007 0.000 0.000))) (snd-display #__line__ ";inverse-chebyshev lp 10 .4 120 spect: ~A" (cadr vals)))) (do ((i 2 (+ i 2))) ((= i 10)) (do ((j .1 (+ j .1))) ((>= j .45)) (let* ((f1 (make-inverse-chebyshev-lowpass i j)) (mx (filter-response-max f1))) (if (> mx 1.0) (snd-display #__line__ ";inv cheby low max ~A ~A: ~A" i j mx))))) (let* ((f1 (make-inverse-chebyshev-highpass 8 .1)) (vals (sweep->bins f1 10))) (if (ffneq (car vals) .51) (snd-display #__line__ ";inverse-chebyshev hp 8 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.001 0.001 0.440 0.505 0.505 0.503 0.502 0.501 0.501 0.501))) (snd-display #__line__ ";inverse-chebyshev hp 8 .1 spect: ~A" (cadr vals)))) (let* ((f1 (make-inverse-chebyshev-highpass 12 .25)) (vals (sweep->bins f1 10))) (if (ffneq (car vals) .51) (snd-display #__line__ ";inverse-chebyshev hp 12 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.001 0.001 0.001 0.001 0.001 0.505 0.506 0.503 0.501 0.501))) (snd-display #__line__ ";inverse-chebyshev hp 12 .25 spect: ~A" (cadr vals)))) (let* ((f1 (make-inverse-chebyshev-highpass 10 .4)) (vals (sweep->bins f1 10))) (if (ffneq (car vals) .51) (snd-display #__line__ ";inverse-chebyshev hp 10 .4 max: ~A" (car vals))) (if (and (not (vequal1 (cadr vals) (float-vector 0.000 0.000 0.000 0.001 0.001 0.001 0.001 0.001 0.503 0.503))) (not (vequal1 (cadr vals) (float-vector 0.000 0.000 0.000 0.001 0.001 0.001 0.001 0.001 0.505 0.503))) (not (vequal1 (cadr vals) (float-vector 0.000 0.000 0.000 0.001 0.001 0.001 0.001 0.001 0.509 0.504)))) (snd-display #__line__ ";inverse-chebyshev hp 10 .4 spect: ~A" (cadr vals)))) (let* ((f1 (make-inverse-chebyshev-highpass 10 .1 120)) (vals (sweep->bins f1 10))) (if (ffneq (car vals) .51) (snd-display #__line__ ";inverse-chebyshev hp 10 .1 120 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.000 0.000 0.007 0.328 0.502 0.502 0.502 0.501 0.501 0.501))) (snd-display #__line__ ";inverse-chebyshev hp 10 .1 120 spect: ~A" (cadr vals)))) (do ((i 2 (+ i 2))) ((= i 10)) (do ((j .1 (+ j .1))) ((>= j .45)) (let* ((f1 (make-inverse-chebyshev-highpass i j)) (mx (filter-response-max f1))) (if (> mx 1.0) (snd-display #__line__ ";inv cheby high max ~A ~A: ~A" i j mx))))) (let* ((f1 (make-inverse-chebyshev-bandpass 10 .1 .2)) (vals (sweep->bins f1 10))) (if (> (abs (- (car vals) .5)) .05) (snd-display #__line__ ";inverse-chebyshev bp 4 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.001 0.001 0.498 0.485 0.001 0.001 0.000 0.001 0.000 0.001))) (snd-display #__line__ ";inverse-chebyshev bp 10 .1 .2 spect: ~A" (cadr vals)))) (let* ((f1 (make-inverse-chebyshev-bandpass 10 .1 .2 30)) (vals (sweep->bins f1 10))) (if (> (abs (- (car vals) .5)) .05) (snd-display #__line__ ";inverse-chebyshev bp 6 max: ~A" (car vals))) (if (and (not (vequal1 (cadr vals) (float-vector 0.026 0.025 0.509 0.505 0.020 0.016 0.012 0.016 0.011 0.016))) (not (vequal1 (cadr vals) (float-vector 0.030 0.042 0.511 0.505 0.020 0.016 0.012 0.016 0.011 0.016))) (not (vequal1 (cadr vals) (float-vector 0.022 0.017 0.511 0.505 0.020 0.016 0.012 0.016 0.011 0.016)))) (snd-display #__line__ ";inverse-chebyshev bp 10 .1 .2 30 spect: ~A" (cadr vals)))) (let* ((f1 (make-inverse-chebyshev-bandpass 8 .1 .4)) (vals (sweep->bins f1 10))) (if (> (abs (- (car vals) .5)) .05) (snd-display #__line__ ";inverse-chebyshev bp 8 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.001 0.001 0.440 0.506 0.505 0.503 0.502 0.434 0.001 0.001))) (snd-display #__line__ ";inverse-chebyshev bp 8 .1 .4 spect: ~A" (cadr vals)))) (let* ((f1 (make-inverse-chebyshev-bandpass 8 .3 .4 40)) (vals (sweep->bins f1 10))) (if (> (abs (- (car vals) .5)) .05) (snd-display #__line__ ";inverse-chebyshev bp 10 .2 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.002 0.005 0.007 0.007 0.005 0.005 0.503 0.505 0.006 0.005))) (snd-display #__line__ ";inverse-chebyshev bp 10 .2 spect: ~A" (cadr vals)))) (let* ((f1 (make-inverse-chebyshev-bandstop 4 .1 .4)) (vals (sweep->bins f1 10))) (if (> (abs (- (car vals) .5)) .05) (snd-display #__line__ ";inverse-chebyshev bs 4 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.500 0.054 0.001 0.001 0.000 0.000 0.000 0.001 0.055 0.503))) (snd-display #__line__ ";inverse-chebyshev bs 4 .1 .4 spect: ~A" (cadr vals)))) (let* ((f1 (make-inverse-chebyshev-bandstop 8 .1 .4)) (vals (sweep->bins f1 10))) (if (> (abs (- (car vals) .5)) .05) (snd-display #__line__ ";inverse-chebyshev bs 8 max: ~A" (car vals))) (if (and (not (vequal1 (cadr vals) (float-vector 0.501 0.496 0.001 0.001 0.000 0.000 0.000 0.001 0.507 0.506))) (not (vequal1 (cadr vals) (float-vector 0.506 0.328 0.000 0.000 0.000 0.000 0.000 0.000 0.268 0.511))) (not (vequal1 (cadr vals) (float-vector 0.500 0.498 0.001 0.001 0.000 0.000 0.000 0.001 0.507 0.506)))) (snd-display #__line__ ";inverse-chebyshev bs 8 .1 .4 spect: ~A" (cadr vals)))) (let* ((f1 (make-inverse-chebyshev-bandstop 8 .1 .4 90)) (vals (sweep->bins f1 10))) (if (> (abs (- (car vals) .5)) .05) (snd-display #__line__ ";inverse-chebyshev bs 8 90 max: ~A" (car vals))) (if (and (not (vequal1 (cadr vals) (float-vector 0.505 0.325 0.000 0.000 0.000 0.000 0.000 0.000 0.270 0.506))) (not (vequal1 (cadr vals) (float-vector 0.506 0.328 0.000 0.000 0.000 0.000 0.000 0.000 0.269 0.509))) (not (vequal1 (cadr vals) (float-vector 0.501 0.327 0.000 0.000 0.000 0.000 0.000 0.000 0.268 0.506)))) (snd-display #__line__ ";inverse-chebyshev bs 8 .1 .4 90 spect: ~A" (cadr vals)))) ;; ---------------- bessel ---------------- ;; checked poly coeff tables, but the prototype has scaling built in (if (provided? 'gsl) (begin (let* ((f1 (make-bessel-lowpass 4 .1)) (vals (sweep->bins f1 10))) (if (fneq (car vals) .5) (snd-display #__line__ ";bessel lp 4 .1 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.500 0.417 0.209 0.062 0.018 0.005 0.001 0.000 0.000 0.000))) (snd-display #__line__ ";bessel lp 4 .1 spect: ~A" (cadr vals)))) (let* ((f1 (make-bessel-lowpass 8 .1)) (vals (sweep->bins f1 10))) (if (fneq (car vals) .5) (snd-display #__line__ ";bessel lp 8 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.499 0.365 0.116 0.010 0.001 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";bessel lp 8 .1 spect: ~A" (cadr vals)))) (let* ((f1 (make-bessel-lowpass 12 .25)) (vals (sweep->bins f1 10))) (if (fneq (car vals) .5) (snd-display #__line__ ";bessel lp 12 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.500 0.477 0.410 0.309 0.185 0.063 0.006 0.000 0.000 0.000))) (snd-display #__line__ ";bessel lp 12 .25 spect: ~A" (cadr vals)))) (let* ((f1 (make-bessel-lowpass 10 .4)) (vals (sweep->bins f1 10))) (if (fneq (car vals) .5) (snd-display #__line__ ";bessel lp 10 max: ~A" (car vals))) (if (and (not (vequal1 (cadr vals) (float-vector 0.500 0.498 0.491 0.479 0.458 0.423 0.364 0.259 0.086 0.001))) (not (vequal1 (cadr vals) (float-vector 0.500 0.498 0.491 0.479 0.458 0.423 0.364 0.259 0.086 0.002)))) (snd-display #__line__ ";bessel lp 10 .4 spect: ~A" (cadr vals)))) (do ((i 2 (+ i 2))) ((= i 12)) (do ((j .1 (+ j .1))) ((>= j .45)) (let* ((f1 (make-bessel-lowpass i j)) (mx (filter-response-max f1))) (if (> mx 1.0) (snd-display #__line__ ";bess low max ~A ~A: ~A" i j mx))))) (let* ((f1 (make-bessel-highpass 8 .1)) (vals (sweep->bins f1 10))) (if (fneq (car vals) .5) (snd-display #__line__ ";bessel hp 8 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.001 0.115 0.290 0.386 0.435 0.465 0.483 0.493 0.498 0.500))) (snd-display #__line__ ";bessel hp 8 .1 spect: ~A" (cadr vals)))) (let* ((f1 (make-bessel-highpass 12 .25)) (vals (sweep->bins f1 10))) (if (fneq (car vals) .5) (snd-display #__line__ ";bessel hp 12 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.000 0.000 0.000 0.006 0.063 0.181 0.309 0.410 0.477 0.500))) (snd-display #__line__ ";bessel hp 12 .25 spect: ~A" (cadr vals)))) (let* ((f1 (make-bessel-highpass 10 .4)) (vals (sweep->bins f1 10))) (if (ffneq (car vals) .5) (snd-display #__line__ ";bessel hp 10 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.000 0.000 0.000 0.000 0.000 0.000 0.004 0.084 0.343 0.499))) (snd-display #__line__ ";bessel hp 10 .4 spect: ~A" (cadr vals)))) (let* ((f1 (make-bessel-bandpass 4 .1 .2)) (vals (sweep->bins f1 10))) (if (> (abs (- (car vals) .245)) .05) (snd-display #__line__ ";bessel bp 4 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.023 0.176 0.245 0.244 0.179 0.085 0.031 0.008 0.001 0.000))) (snd-display #__line__ ";bessel bp 4 .1 .2 spect: ~A" (cadr vals)))) (let* ((f1 (make-bessel-bandstop 12 .1 .2)) (vals (sweep->bins f1 10))) (if (> (abs (- (car vals) .5)) .05) (snd-display #__line__ ";bessel bs 12 max: ~A" (car vals))) (if (and (not (vequal1 (cadr vals) (float-vector 0.498 0.325 0.065 0.066 0.177 0.297 0.389 0.452 0.488 0.500))) (not (vequal1 (cadr vals) (float-vector 0.499 0.324 0.065 0.066 0.177 0.297 0.389 0.452 0.488 0.500)))) (snd-display #__line__ ";bessel bs 12 .1 .2 spect: ~A" (cadr vals)))) ;; ---------------- elliptic ---------------- (let* ((f1 (make-elliptic-lowpass 8 .1)) (vals (sweep->bins f1 10))) (if (> (abs (- (car vals) .5)) .1) (snd-display #__line__ ";elliptic lp 8 max: ~A" (car vals))) (if (and (not (vequal1 (cadr vals) (float-vector 0.500 0.515 0.379 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) (not (vequal1 (cadr vals) (float-vector 0.500 0.509 0.385 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) (not (vequal1 (cadr vals) (float-vector 0.499 0.498 0.373 0.000 0.000 0.000 0.000 0.000 0.000 0.000)))) (snd-display #__line__ ";elliptic lp 8 .1 spect: ~A" (cadr vals)))) (let* ((f1 (make-elliptic-lowpass 12 .25)) (vals (sweep->bins f1 10))) (if (> (abs (- (car vals) .5)) .1) (snd-display #__line__ ";elliptic lp 12 max: ~A" (car vals))) (if (and (not (vequal1 (cadr vals) (float-vector 0.476 0.500 0.491 0.499 0.494 0.412 0.003 0.001 0.000 0.000))) (not (vequal1 (cadr vals) (float-vector 0.476 0.500 0.491 0.499 0.494 0.561 0.004 0.000 0.000 0.000))) (not (vequal1 (cadr vals) (float-vector 0.476 0.500 0.491 0.499 0.493 0.299 0.006 0.001 0.000 0.000)))) (snd-display #__line__ ";elliptic lp 12 .25 spect: ~A" (cadr vals)))) (let* ((f1 (make-elliptic-lowpass 4 .4)) (vals (sweep->bins f1 10))) (if (> (abs (- (car vals) .5)) .1) (snd-display #__line__ ";elliptic lp 4 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.447 0.453 0.462 0.477 0.494 0.500 0.497 0.496 0.445 0.003))) (snd-display #__line__ ";elliptic lp 4 .4 spect: ~A" (cadr vals)))) (let* ((f1 (make-elliptic-lowpass 8 .1 .1)) (vals (sweep->bins f1 10))) (if (> (abs (- (car vals) .5)) .1) (snd-display #__line__ ";elliptic lp 8 .1 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.500 0.499 0.475 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";elliptic lp 8 .1 .1 spect: ~A" (cadr vals)))) (let* ((f1 (make-elliptic-lowpass 8 .1 .1 90)) (vals (sweep->bins f1 10))) (if (> (abs (- (car vals) .5)) .1) (snd-display #__line__ ";elliptic lp 8 .1 90 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.500 0.499 0.475 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";elliptic lp 8 .1 .1 90 spect: ~A" (cadr vals)))) (let* ((f1 (make-elliptic-lowpass 8 .25 .01 90)) (vals (sweep->bins f1 10))) (if (> (abs (- (car vals) .5)) .1) (snd-display #__line__ ";elliptic lp 8 .25 90 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.500 0.500 0.500 0.500 0.499 0.495 0.001 0.000 0.000 0.000))) (snd-display #__line__ ";elliptic lp 8 .25 .1 90 spect: ~A" (cadr vals)))) (let* ((f1 (make-elliptic-highpass 4 .1)) (vals (sweep->bins f1 10))) (if (> (abs (- (car vals) .5)) .1) (snd-display #__line__ ";elliptic hp 4 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.004 0.438 0.516 0.499 0.502 0.495 0.478 0.463 0.453 0.447))) (snd-display #__line__ ";elliptic hp 4 .1 spect: ~A" (cadr vals)))) (let* ((f1 (make-elliptic-highpass 12 .25)) (vals (sweep->bins f1 10))) ;(if (> (abs (- (car vals) .5)) .1) (snd-display #__line__ ";elliptic hp 12 max: ~A" (car vals))) (if (and (not (vequal1 (cadr vals) (float-vector 0.000 0.001 0.001 0.001 0.026 0.934 0.518 0.495 0.503 0.477))) (not (vequal1 (cadr vals) (float-vector 0.000 0.001 0.001 0.001 0.033 1.185 0.519 0.495 0.503 0.477))) (not (vequal1 (cadr vals) (float-vector 0.000 0.001 0.001 0.001 0.018 0.788 0.520 0.495 0.503 0.477)))) (snd-display #__line__ ";elliptic hp 12 .25 spect: ~A" (cadr vals)))) (let* ((f1 (make-elliptic-highpass 12 .25 .01 90)) (vals (sweep->bins f1 10))) (if (> (abs (- (car vals) .5)) .1) (snd-display #__line__ ";elliptic hp 12 90 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.000 0.000 0.000 0.000 0.499 0.517 0.503 0.501 0.500 0.500))) (snd-display #__line__ ";elliptic hp 12 .25 90 spect: ~A" (cadr vals)))) (let* ((f1 (make-elliptic-highpass 4 .4)) (vals (sweep->bins f1 10))) (if (> (abs (- (car vals) .5)) .1) (snd-display #__line__ ";elliptic hp 4 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.000 0.000 0.000 0.001 0.001 0.002 0.023 0.447 0.515 0.502))) (snd-display #__line__ ";elliptic hp 4 .4 spect: ~A" (cadr vals)))) (let* ((f1 (make-elliptic-highpass 8 .1 .1)) (vals (sweep->bins f1 10))) (if (> (abs (- (car vals) .5)) .1) (snd-display #__line__ ";elliptic hp 8 .1 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.000 0.478 0.553 0.506 0.499 0.501 0.501 0.499 0.497 0.495))) (snd-display #__line__ ";elliptic hp 8 .1 .1 spect: ~A" (cadr vals)))) (let* ((f1 (make-elliptic-highpass 8 .1 .1 90)) (vals (sweep->bins f1 10))) (if (> (abs (- (car vals) .5)) .1) (snd-display #__line__ ";elliptic hp 8 .1 90 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.000 0.478 0.554 0.506 0.499 0.501 0.501 0.499 0.497 0.495))) (snd-display #__line__ ";elliptic hp 8 .1 .1 90 spect: ~A" (cadr vals)))) (let* ((f1 (make-elliptic-highpass 8 .25 .01 90)) (vals (sweep->bins f1 10))) (if (> (abs (- (car vals) .5)) .1) (snd-display #__line__ ";elliptic hp 8 .25 90 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.000 0.000 0.000 0.001 0.516 0.517 0.507 0.503 0.501 0.500))) (snd-display #__line__ ";elliptic hp 8 .25 .1 90 spect: ~A" (cadr vals)))) (let* ((f1 (make-elliptic-bandpass 4 .1 .2 .1)) (vals (sweep->bins f1 10))) (if (> (abs (- (car vals) .5)) .1) (snd-display #__line__ ";elliptic bp 4 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.036 0.546 0.550 0.510 0.501 0.032 0.024 0.009 0.021 0.024))) (snd-display #__line__ ";elliptic bp 4 .1 .2 spect: ~A" (cadr vals)))) (let* ((f1 (make-elliptic-bandpass 6 .1 .2 .1 90)) (vals (sweep->bins f1 10))) (if (> (abs (- (car vals) .5)) .1) (snd-display #__line__ ";elliptic bp 6 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.002 0.511 0.532 0.503 0.492 0.003 0.001 0.001 0.001 0.001))) (snd-display #__line__ ";elliptic bp 6 .1 .2 90 spect: ~A" (cadr vals)))) (let* ((f1 (make-elliptic-bandstop 4 .1 .3 .1)) (vals (sweep->bins f1 10))) (if (> (abs (- (car vals) .5)) .1) (snd-display #__line__ ";elliptic bs 4 max: ~A" (car vals))) (if (not (vequal1 (cadr vals) (float-vector 0.499 0.502 0.498 0.037 0.050 0.540 0.544 0.527 0.526 0.521))) (snd-display #__line__ ";elliptic bs 4 .1 .2 spect: ~A" (cadr vals)))) (let* ((f1 (make-elliptic-bandstop 8 .1 .3 .1 120)) (vals (sweep->bins f1 10))) (if (> (abs (- (car vals) .5)) .1) (snd-display #__line__ ";elliptic bs 8 max: ~A" (car vals))) (if (and (not (vequal1 (cadr vals) (float-vector 0.500 0.499 0.476 0.000 0.000 0.495 0.526 0.505 0.501 0.501))) (not (vequal1 (cadr vals) (float-vector 0.500 0.499 0.475 0.000 0.000 0.495 0.526 0.505 0.501 0.501)))) (snd-display #__line__ ";elliptic bs 8 .1 .2 spect: ~A" (cadr vals)))) )))) (define (test-polyoid n) (let* ((res (with-sound (:channels 2 :clipped #f) (let ((freqs (make-float-vector n)) (phases (make-float-vector n)) ; for oscil-bank (cur-phases (make-float-vector (* 3 n))) ; for polyoid (amp (/ 1.0 n))) (do ((i 0 (+ i 1)) (j 0 (+ j 3))) ((= i n)) (set! (cur-phases j) (+ i 1)) (set! (cur-phases (+ j 1)) (/ 1.0 n)) (set! (cur-phases (+ j 2)) (random (* 2 pi))) (set! (freqs i) (hz->radians (+ i 1.0))) (set! (phases i) (cur-phases (+ j 2)))) (let ((gen (make-polyoid 1.0 cur-phases)) (obank (make-oscil-bank freqs phases (make-float-vector n 1.0) #t))) (do ((i 0 (+ i 1))) ((= i 88200)) (outa i (* amp (oscil-bank obank)))) (do ((i 0 (+ i 1))) ((= i 88200)) (outb i (polyoid gen 0.0))))))) (snd (find-sound res))) (channel-distance snd 0 snd 1))) ;; ---------------- (define (poly-roots-tests) (letrec ((ceql (lambda (a b) (if (null? a) (null? b) (and (not (null? b)) (not (or (fneq (real-part (car a)) (real-part (car b))) (fneq (imag-part (car a)) (imag-part (car b))))) (ceql (cdr a) (cdr b))))))) ;; degree=0 (let ((val (poly-roots (float-vector 0.0)))) (if (pair? val) (snd-display #__line__ ";poly-roots 0.0: ~A" val))) (let ((val (poly-roots (float-vector 12.3)))) (if (pair? val) (snd-display #__line__ ";poly-roots 12.3: ~A" val))) ;; degree 0 + x=0 (let ((val (poly-roots (float-vector 0.0 1.0)))) (if (not (ceql val (list 0.0))) (snd-display #__line__ ";poly-roots 0.0 1.0: ~A" val))) (let ((val (poly-roots (float-vector 0.0 0.0 0.0 121.0)))) (if (not (ceql val (list 0.0 0.0 0.0))) (snd-display #__line__ ";poly-roots 0.0 0.0 0.0 121.0: ~A" val))) ;; degree=1 (let ((val (poly-roots (float-vector -1.0 1.0)))) (if (not (ceql val (list 1.0))) (snd-display #__line__ ";poly-roots -1.0 1.0: ~A" val))) (let ((val (poly-roots (float-vector -2.0 4.0)))) (if (not (ceql val (list 0.5))) (snd-display #__line__ ";poly-roots -2.0 4.0: ~A" val))) (let ((val (poly-as-vector-roots (vector 0.0-i 1)))) (if (not (ceql val (list -0.0+1.0i))) (snd-display #__line__ ";poly-roots: -i 1: ~A" val))) ;; linear x^n (let ((val (poly-roots (float-vector -1.0 0.0 0.0 0.0 1.0)))) (if (and (not (ceql val (list 0.0-1.0i -1.0 0.0+1.0i 1.0))) (not (ceql val (list 1.0 -1.0 0.0+1.0i -0.0-1.0i)))) (snd-display #__line__ ";poly-roots -1.0 0.0 0.0 0.0 1.0: ~A" val))) (let ((val (poly-roots (float-vector -16.0 0.0 0.0 0.0 1.0)))) (if (and (not (ceql val (list 0.0-2.0i -2.0 0.0+2.0i 2.0))) (not (ceql val (list 2.0 -2.0 0.0+2.0i -0.0-2.0i)))) (snd-display #__line__ ";poly-roots -16.0 0.0 0.0 0.0 1.0: ~A" val))) (let ((val (poly-roots (float-vector -32.0 0 0 0 0 0 0.5)))) (if (not (ceql val (list 1.0-1.7320i -1.0-1.7320i -2.0 -1.0+1.7320i 1.0+1.7320i 2.0))) (snd-display #__line__ ";poly-roots 32 0 0 0 0 0 0.5: ~A" val))) ;; linear + x=0 (let ((val (poly-roots (float-vector 0.0 -2.0 4.0)))) (if (not (ceql val (list 0.0 0.5))) (snd-display #__line__ ";poly-roots 0.0 -2.0 4.0: ~A" val))) ;; degree=2 (let ((val (poly-roots (float-vector -1.0 0.0 1.0)))) (if (not (ceql val (list 1.0 -1.0))) (snd-display #__line__ ";poly-roots -1.0 0.0 1.0: ~A" val))) (let ((val (poly-roots (float-vector 15.0 -8.0 1.0)))) (if (not (ceql val (list 5.0 3.0))) (snd-display #__line__ ";poly-roots 15.0 -8.0 1.0: ~A" val))) (let ((val (poly-roots (float-vector 1 -2 1)))) (if (not (ceql val (list 1.0 1.0))) (snd-display #__line__ ";poly-roots 1 -2 1: ~A" val))) (let ((val (poly-as-vector-roots (vector -1 0.0+2i 1)))) (if (not (ceql val (list 0.0-1.0i 0.0-1.0i))) (snd-display #__line__ ";poly-roots -1 2i 1: ~A" val))) (let ((val (poly-roots (float-vector 1 1 5)))) (if (not (ceql val (list -0.1+0.43589i -0.1-0.43589i))) (snd-display #__line__ ";poly-roots 1 1 5: ~A" val))) ;; 2 + x=0 (let ((val (poly-roots (float-vector 0.0 0.0 -1.0 0.0 1.0)))) (if (not (ceql val (list 0.0 0.0 1.0 -1.0))) (snd-display #__line__ ";poly-roots 0.0 0.0 -1.0 0.0 1.0: ~A" val))) ;; quadratic in x^(n/2) (let ((vals (poly-roots (float-vector 1.0 0.0 -2.0 0.0 1.0)))) (if (and (not (ceql vals (list -1.0 1.0 -1.0 1.0))) (not (ceql vals (list 1.0 1.0 -1.0 -1.0)))) (snd-display #__line__ ";poly-roots 1 0 -2 0 1: ~A" vals))) (let ((vals (poly-roots (float-vector 64.0 0.0 0.0 -16.0 0.0 0.0 1.0)))) (if (not (ceql vals (list -1.0-1.73205i -1.0+1.73205i 2.0 -1.0-1.73205i -1.0+1.73205i 2.0))) (snd-display #__line__ ";poly-roots 64 0 0 -16 0 0 1: ~A" vals))) ;; degree=3 (let ((val (poly-roots (float-vector -15.0 23.0 -9.0 1.0)))) (if (not (ceql val (list 5.0 1.0 3.0))) (snd-display #__line__ ";poly-roots 5 1 3: ~A" val))) (let ((val (poly-roots (float-vector -126 -15 0 1)))) (if (not (ceql val (list 6.0 -3.0+3.46410i -3.0-3.46410i))) (snd-display #__line__ ";poly-roots -126 -15 0 1: ~A" val))) (let ((val (poly-roots (float-vector -1 3 -3 1)))) (if (not (ceql val (list 1.0 1.0 1.0))) (snd-display #__line__ ";poly-roots -1 3 -3 1: ~A" val))) (let ((val (poly-roots (float-vector 1 -1 -1 1)))) (if (and (not (ceql val (list 1.0 -1.0 1.0))) (not (ceql val (list -1.0 1.0 1.0)))) (snd-display #__line__ ";poly-roots 1 -1 1: ~A" val))) (let ((val (poly-roots (float-vector 2 -2 -2 2)))) (if (and (not (ceql val (list 1.0 -1.0 1.0))) (not (ceql val (list -1.0 1.0 1.0)))) (snd-display #__line__ ";poly-roots 2 -2 -2 2: ~A" val))) ;; degree=4 ; (let ((vals (poly-roots (float-vector -15 8 14 -8 1)))) ; (if (not (ceql vals (list 5.0 3.0 1.0 -1.0))) (snd-display #__line__ ";poly-roots -15 8 14 -8 1: ~A" vals))) ; (let ((vals (poly-roots (poly-reduce (poly* (poly* (float-vector 2 1) (float-vector -3 1)) (poly* (float-vector 8 1) (float-vector -9 1))))))) ; (if (not (ceql vals (list 9.0 3.0 -2.0 -8.0))) (snd-display #__line__ ";poly-roots 4(1): ~A" vals))) ; (let ((vals (poly-roots (poly-reduce (poly* (poly* (float-vector .2 1) (float-vector -3 1)) (poly* (float-vector .8 1) (float-vector -9 1))))))) ; (if (not (ceql vals (list 9.0 3.0 -0.2 -0.8))) (snd-display #__line__ ";poly-roots 4(2): ~A" vals))) ; (let ((vals (poly-roots (poly-reduce (poly* (poly* (float-vector .02 1) (float-vector -32 1)) (poly* (float-vector .8 1) (float-vector -9 1))))))) ; (if (not (ceql vals (list 32.0 9.0 -0.02 -0.8))) (snd-display #__line__ ";poly-roots 4(3): ~A" vals))) ;; degree>4 ; (let ((vals (poly-roots (poly-reduce (poly* (float-vector 1 1) (poly* (poly* (float-vector 2 1) (float-vector -3 1)) (poly* (float-vector -1 1) (float-vector -2 1)))))))) ; (if (not (ceql vals (list 3.0 2.0 -1.0 -2.0 1.0))) ; (snd-display #__line__ ";poly-roots n(1): ~A from ~A ~A ~A" ; vals ; (poly-reduce (poly* (float-vector 1 1) (poly* (poly* (float-vector 2 1) (float-vector -3 1)) (poly* (float-vector -1 1) (float-vector -2 1))))) ; *mus-float-equal-fudge-factor* ; poly-roots-epsilon))) ; (let ((vals (poly-roots (poly-reduce (poly* (float-vector 1 1) (poly* (poly* (float-vector 2 1) (float-vector -3 1)) (poly* (float-vector 8 1) (float-vector -9 1)))))))) ; (if (not (ceql vals (list 9.0 3.0 -2.0 -8.0 -1.0))) (snd-display #__line__ ";poly-roots n(2): ~A" vals))) ; (let ((vals (poly-roots (poly-reduce (poly* (float-vector -1 0 1) (poly* (poly* (float-vector 9 1) (float-vector -3 1)) (poly* (float-vector -10 1) (float-vector -2 1)))))))) ; (if (not (ceql vals (list 10.0 3.0 -1.0 -9.0 2.0 1.0))) (snd-display #__line__ ";poly-roots n(3): ~A" vals))) ; (let ((vals (poly-roots (poly-reduce (poly* (float-vector -1 0 1) (poly* (poly* (float-vector -4 0 1) (float-vector -3 1)) (poly* (float-vector -10 1) (float-vector -9 0 1)))))))) ; (if (not (ceql vals (list 10.0 3.0 -2.0 -3.0 -1.0 3.0 2.0 1.0))) (snd-display #__line__ ";poly-roots n(4): ~A" vals))) ; (let ((vals (poly-roots (poly-reduce (poly* (float-vector -1 0 1) (poly* (poly* (float-vector -4 0 1) (float-vector -16 0 1)) (poly* (float-vector -25 0 1) (float-vector -9 0 1)))))))) ; (if (not (ceql vals (list 5.0 -3.0 -4.0 -5.0 4.0 -2.0 3.0 -1.0 2.0 1.0))) (snd-display #__line__ ";poly-roots n(5): ~A" vals))) ; (let ((vals (poly-roots (poly-reduce (poly* (float-vector 1 1) (poly* (poly* (float-vector 2 1) (float-vector -3 1)) (poly* (float-vector 1 1) (float-vector -2 1)))))))) ; (if (not (ceql vals (list 3.0 -1.0 -1.0 -2.0 2.0))) (snd-display #__line__ ";poly-roots n(6): ~A" vals))) (let ((vals (poly-roots (float-vector -64 0 0 0 0 0 1)))) (if (not (ceql vals (list 0.999999999999999-1.73205080756888i -1.0-1.73205080756888i -2.0 -1.0+1.73205080756888i 1.0+1.73205080756888i 2.0))) (snd-display #__line__ ";poly-roots 64 6: ~A" vals))) (let ((vals (poly-roots (float-vector 64 0 0 -16 0 0 1)))) (if (not (ceql vals (list -1.0-1.73205080756888i -1.0+1.73205080756888i 2.0 -1.0-1.73205080756888i -1.0+1.73205080756888i 2.0))) (snd-display #__line__ ";poly-roots 64 16 6: ~A" vals))) (do ((i 0 (+ i 1))) ((= i 10)) (poly-roots (float-vector (random 1.0) (random 1.0) (random 1.0)))) (do ((i 0 (+ i 1))) ((= i 10)) (poly-roots (float-vector (mus-random 1.0) (mus-random 1.0) (mus-random 1.0)))) (let ((vals1 (convolution (float-vector 1 2 3 0 0 0 0 0) (float-vector 1 2 3 0 0 0 0 0) 8)) (vals2 (poly* (float-vector 1 2 3 0) (float-vector 1 2 3 0)))) (if (not (vequal vals1 vals2)) (snd-display #__line__ ";poly* convolve: ~A ~A" vals1 vals2))) (do ((i 0 (+ i 1))) ((= i 10)) (poly-as-vector-roots (vector (complex (mus-random 1.0) (mus-random 1.0)) (complex (mus-random 1.0) (mus-random 1.0))))) (do ((i 0 (+ i 1))) ((= i 10)) (poly-as-vector-roots (vector (complex (mus-random 1.0) (mus-random 1.0)) (complex (mus-random 1.0) (mus-random 1.0)) (complex (mus-random 1.0) (mus-random 1.0))))) (do ((i 0 (+ i 1))) ((= i 10)) (poly-roots (float-vector (mus-random 1.0) (mus-random 1.0) (mus-random 1.0) (mus-random 1.0)))) (do ((i 0 (+ i 1))) ((= i 10)) (poly-as-vector-roots (vector (complex (mus-random 1.0) (mus-random 1.0)) (complex (mus-random 1.0) (mus-random 1.0)) (complex (mus-random 1.0) (mus-random 1.0)) (complex (mus-random 1.0) (mus-random 1.0))))) ; (do ((i 0 (+ i 1))) ((= i 10)) ; (poly-roots (float-vector (mus-random 1.0) (mus-random 1.0) (mus-random 1.0) (mus-random 1.0) (mus-random 1.0)))) ; ; (do ((i 0 (+ i 1))) ((= i 10)) ; (poly-as-vector-roots (vector (complex (mus-random 1.0) (mus-random 1.0)) ; (complex (mus-random 1.0) (mus-random 1.0)) ; (complex (mus-random 1.0) (mus-random 1.0)) ; (complex (mus-random 1.0) (mus-random 1.0)) ; (complex (mus-random 1.0) (mus-random 1.0))))) (do ((i 3 (+ i 1))) ((= i 20)) (let ((v (make-float-vector i 0.0))) (set! (v 0) (mus-random 1.0)) (set! (v (- i 1)) 1.0) (poly-roots v))) (do ((i 3 (+ i 2))) ((= i 21)) (let ((v (make-float-vector i 0.0))) (set! (v 0) (mus-random 1.0)) (set! (v (- i 1)) 1.0) (set! (v (/ (- i 1) 2)) 1.0) (poly-roots v))) (let ((vals (poly-roots (float-vector 1 -1 -1 1)))) (if (and (not (ceql vals (list 1.0 -1.0 1.0))) (not (ceql vals (list -1.0 1.0 1.0)))) (snd-display #__line__ ";poly-roots 1-1-11: ~A" vals))) (let ((vals (poly-roots (float-vector 2 -1 -2 1)))) (if (not (ceql vals (list 2.0 -1.0 1.0))) (snd-display #__line__ ";poly-roots 2-1-21: ~A" vals))) (let ((vals (poly-roots (float-vector -1 1 1 1)))) (if (not (ceql vals (list 0.543689012692076 -0.771844506346038+1.11514250803994i -0.771844506346038-1.11514250803994i))) (snd-display #__line__ ";poly-roots -1111: ~A" vals))) (let ((vals (poly-roots (float-vector -1 3 -3 1)))) (if (not (ceql vals (list 1.0 1.0 1.0))) (snd-display #__line__ ";poly-roots -13-31: ~A" vals))) ; (let ((vals (poly-roots (float-vector 1 -4 6 -4 1)))) ; (if (not (ceql vals (list 1.0 1.0 1.0 1.0))) (snd-display #__line__ ";poly-roots 1-46-41: ~A" vals))) (let ((vals (poly-roots (float-vector 0.5 0 0 1.0)))) (if (and (not (ceql vals (list 0.396850262992049-0.687364818499302i -0.7937005259841 0.39685026299205+0.687364818499301i))) (not (ceql vals (list 0.39685026299205+0.687364818499301i 0.39685026299205-0.687364818499301i -0.7937005259841))) (not (ceql vals (list -7.9370052598409979172089E-1 3.968502629920498958E-1+6.873648184993013E-1i 3.96850262992049E-1-6.873648184993E-1i)))) (snd-display #__line__ ";poly-roots 0..5 3: ~A" vals))) (let ((vals (poly-roots (poly* (poly* (poly* (float-vector -1 1) (float-vector 1 1)) (poly* (float-vector -2 1) (float-vector 2 1))) (poly* (float-vector -3 1) (float-vector 3 1)))))) (if (not (ceql vals (list -3.0 3.0 -1.0 1.0 -2.0 2.0))) (snd-display #__line__ ";cube in 2: ~A" vals))) )) ;; ----------------- (define (test-fm-components) (if (and (provided? 'gsl) (not (provided? 'gmp))) (let ((str (with-output-to-string (lambda () (fm-complex-component 1200 1000 100 1.0 4.0 0.0 #f) (fm-cascade-component 2000 2000 500 1.5 50 1.0))))) (if (not (string=? str ";fm-complex-component add -0.000-0.010i from J-3(1.0) = -0.020 and I5(4.0) = 0.505 ;fm-complex-component add 0.163 from J-2(1.0) = 0.115 and I4(4.0) = 1.416 ;fm-complex-component add -0.000+1.469i from J-1(1.0) = -0.440 and I3(4.0) = 3.337 ;fm-complex-component add -4.914 from J0(1.0) = 0.765 and I2(4.0) = 6.422 ;fm-complex-component add 0.000+4.295i from J1(1.0) = 0.440 and I1(4.0) = 9.759 ;fm-complex-component add 1.299 from J2(1.0) = 0.115 and I0(4.0) = 11.302 ;fm-complex-component add 0.000-0.191i from J3(1.0) = 0.020 and I-1(4.0) = 9.759 ;fm-complex-component add -0.016 from J4(1.0) = 0.002 and I-2(4.0) = 6.422 ;fm-cascade-component add 0.512 from J0(1.5) = 0.512 and J0(1.0) = 1.000 ")) (snd-display #__line__ ";fm-components are unexpected:~%~S" str))))) ;; ---------------- (define fltit (let ((documentation "(fltit) returns a time-varying filter: (map-channel (fltit))")) (lambda () (let* ((coeffs (float-vector .1 .2 .3 .4 .4 .3 .2 .1)) (flt (make-fir-filter 8 coeffs)) (xcof (mus-xcoeffs flt)) ; maybe a copy? (es (make-float-vector 8))) (do ((i 0 (+ i 1))) ((= i 8)) (set! (es i) 0.9994)) ; something like (+ 1.0 (/ (log 1e-5) (* 0.5 *clm-srate*))) (set! (es 5) 1.00002) (lambda (x) (float-vector-multiply! xcof es) (fir-filter flt x)))))) ;;; (with-sound ("test.snd") (let ((p (make-pulse-train 1000))) (do ((i 0 (+ i 1))) ((= i 44100)) (outa i (* .5 (pulse-train p)))))) ;;; (map-channel (fltit)) ;; ---------------- (define (freq-sweep dur) (let ((ph (make-one-pole 1.0 -1.0)) (fq (make-one-pole 1.0 -1.0)) (incr (/ pi (* dur 1.05 *clm-srate*))) (len (framples))) (let ((data (make-float-vector len))) (do ((i 2 (+ i 1))) ((= i len)) (set! (data i) (sin (one-pole ph (one-pole fq incr))))) (float-vector->channel (float-vector-scale! data 0.5))))) ;; ---------------- (define* (make-ssb-am-1 freq (order 40)) (if (even? order) (set! order (+ 1 order))) (make-sa1 :freq (abs freq) :coscar (make-oscil freq (* .5 pi)) :sincar (make-oscil freq) :dly (make-delay order) :hlb (make-hilbert-transform order))) ;; ---------------- (define* (ssb-am-1 gen y (fm-1 0.0)) (let* ((fm fm-1) (ccos (oscil (gen 'coscar) fm)) (csin (oscil (gen 'sincar) fm)) (yh (hilbert-transform (gen 'hlb) y)) (yd (delay (gen 'dly) y))) (if (> (gen 'freq) 0.0) (- (* ccos yd) ; shift up (* csin yh)) (+ (* ccos yd) ; shift down (* csin yh))))) ;; ---------------- (define (rough-spectrum ind) (let ((data (channel->float-vector 0 10000 ind 0)) (spect (make-float-vector 10)) (g (make-one-pole 1.0 -1.0))) (float-vector-multiply! data data) (do ((i 0 (+ i 1)) (beg 0 (+ beg 1000)) (end 999 (+ end 1000))) ((= i 10)) (mus-reset g) (do ((j beg (+ j 1))) ((= j end)) (one-pole g (float-vector-ref data j))) (float-vector-set! spect i (one-pole g (float-vector-ref data end)))) (float-vector-scale! spect (/ 1.0 (float-vector-peak spect))))) ;; ---------------- (define* (print-and-check gen name desc (desc1 "") (desc2 "")) (if (not (string=? (mus-name gen) name)) (snd-display #__line__ ";mus-name ~A: ~A?" name (mus-name gen))) (if (and (not (string=? (mus-describe gen) desc)) (not (string=? (mus-describe gen) desc1)) (not (string=? (mus-describe gen) desc2))) (snd-display #__line__ ";mus-describe ~A: ~A?" (mus-name gen) (mus-describe gen))) (let ((egen gen)) (if (not (equal? egen gen)) (snd-display #__line__ ";equal? ~A: ~A?" gen egen)))) ;; ---------------- (define (test-gen-equal g0 g1 g2) ;; g0 = g1 at start != g2 (let ((g3 g0)) (if (not (eq? g0 g3)) (snd-display #__line__ ";let ~A not eq?~% ~A~% ~A" (mus-name g0) g0 g3)) (if (eq? g0 g1) (snd-display #__line__ ";arg ~A eq?~% ~A~% ~A" (mus-name g0) g0 g1)) (if (not (equal? g0 g1)) (snd-display #__line__ ";~A not equal?~% ~A~% ~A" (mus-name g0) g0 g1)) (if (equal? g0 g2) (snd-display #__line__ ";~A equal?~% ~A~% ~A" (mus-name g0) g0 g2)) (g0) (g3) (g3) (if (not (eq? g0 g3)) (snd-display #__line__ ";run let ~A not eq?~% ~A~% ~A" (mus-name g0) g0 g3)) (if (eq? g0 g1) (snd-display #__line__ ";arg ~A eq?~% ~A~% ~A" (mus-name g0) g0 g1)) (if (equal? g0 g1) (snd-display #__line__ ";run ~A equal?~% ~A~% ~A" (mus-name g0) g0 g1)) (if (equal? g0 g2) (snd-display #__line__ ";run ~A equal?~% ~A~% ~A" (mus-name g0) g0 g2)) (let ((data (catch #t (lambda () (mus-data g0)) (lambda args #f)))) (when (float-vector? data) (let ((g4 (copy g0))) (let ((data4 (catch #t (lambda () (mus-data g4)) (lambda args #f)))) (if (not (float-vector? data4)) (snd-display #__line__ ";~A copy -> mus-data ~A?" (mus-name g0) data4)))))))) ;; ---------------- (define (fm-test gen) (if (not (mus-generator? gen)) (snd-display #__line__ ";~A not a gen?" gen)) (set! (mus-frequency gen) 0.0) (set! (mus-phase gen) 0.0) (gen 0.0) (if (fneq (mus-phase gen) 0.0) (snd-display #__line__ ";~A phase(0): ~A" gen (mus-phase gen))) (gen 1.0) (if (fneq (mus-phase gen) 1.0) (snd-display #__line__ ";~A phase(1): ~A" gen (mus-phase gen))) (gen 0.0) (if (fneq (mus-phase gen) 1.0) (snd-display #__line__ ";~A phase(1, 0): ~A" gen (mus-phase gen))) (set! (mus-frequency gen) (radians->hz 2.0)) (if (fneq (mus-increment gen) 2.0) (snd-display #__line__ ";~A increment: ~A" gen (mus-increment gen))) (set! (mus-increment gen) 2.0) (if (fneq (mus-frequency gen) (radians->hz 2.0)) (snd-display #__line__ ";~A set increment: ~A ~A" gen (mus-increment gen) (hz->radians (mus-frequency gen)))) (gen 0.0) (if (fneq (mus-phase gen) 3.0) (snd-display #__line__ ";~A phase(1, 2): ~A ~A" gen (mus-phase gen) (mus-frequency gen))) (gen 1.0) (if (fneq (mus-phase gen) 6.0) (snd-display #__line__ ";~A phase(3, 2, 1): ~A ~A" gen (mus-phase gen) (mus-frequency gen))) (do ((i 0 (+ i 1))) ((= i 10)) (gen 10.0)) (if (fneq (mus-phase gen) (+ 26 (- 100 (* 2 pi 20)))) (snd-display #__line__ ";~A phase (over): ~A ~A" gen (mus-phase gen) (mus-frequency gen))) (set! (mus-frequency gen) 0.0) (set! (mus-phase gen) 0.0) (gen 1234567812345678) (gen -1234567812345678) (set! (mus-frequency gen) 0.0) (set! (mus-phase gen) 0.0) (gen -2.0) (if (and (fneq (mus-phase gen) -2.0) (fneq (mus-phase gen) (- (* 2 pi) 2.0))) (snd-display #__line__ ";phase: ~A freq: ~A" (mus-phase gen) (mus-frequency gen)))) ;; ---------------- (define* (agc (ramp-speed .001) (window-size 512)) (let ((maxer (make-moving-max window-size)) (mult 1.0)) (map-channel (lambda (y) (let* ((curmax (moving-max maxer y)) (diff (- 0.5 (* mult curmax))) (this-incr (* diff ramp-speed))) (set! mult (+ mult this-incr)) (* y mult)))))) ;; ---------------- (define (numerical-reality-checks) ;; a few reality checks from John Burkardt test_values.C (let ((vals (vector 1.6709637479564564156 1.5707963267948966192 1.4706289056333368229 1.3694384060045658278 1.2661036727794991113 1.1592794807274085998 1.0471975511965977462 0.92729521800161223243 0.79539883018414355549 0.64350110879328438680 0.45102681179626243254 0.00000000000000000000)) (args (vector -0.1 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0)) (max-bad 0.0)) (do ((i 0 (+ i 1))) ((= i 12)) (let* ((nval (acos (vector-ref args i))) (diff (abs (- nval (vector-ref vals i))))) (if (> diff max-bad) (set! max-bad diff)))) (if (> max-bad 1.0e-15) (snd-display #__line__ ";acos: ~A" max-bad))) (let ((vals (vector 0.0000000000000000000 0.14130376948564857735 0.44356825438511518913 0.62236250371477866781 0.75643291085695958624 0.86701472649056510395 0.96242365011920689500 1.3169578969248167086 1.7627471740390860505 1.8115262724608531070 2.0634370688955605467 2.2924316695611776878 2.9932228461263808979 5.2982923656104845907 7.6009022095419886114)) (args (vector 1.0 1.01 1.1 1.2 1.3 1.4 1.5 2.0 3.0 3.1415926535897932385 4.0 5.0 10.0 100.0 1000.0)) (max-bad 0.0)) (do ((i 0 (+ i 1))) ((= i 15)) (let* ((nval (acosh (vector-ref args i))) (diff (abs (- nval (vector-ref vals i))))) (if (> diff max-bad) (set! max-bad diff)))) (if (> max-bad 1.0e-15) (snd-display #__line__ ";acosh: ~A" max-bad))) (let ((vals (vector -0.10016742116155979635 0.00000000000000000000 0.10016742116155979635 0.20135792079033079146 0.30469265401539750797 0.41151684606748801938 0.52359877559829887308 0.64350110879328438680 0.77539749661075306374 0.92729521800161223243 1.1197695149986341867 1.5707963267948966192)) (args (vector -0.1 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0)) (max-bad 0.0)) (do ((i 0 (+ i 1))) ((= i 12)) (let* ((nval (asin (vector-ref args i))) (diff (abs (- nval (vector-ref vals i))))) (if (> diff max-bad) (set! max-bad diff)))) (if (> max-bad 1.0e-15) (snd-display #__line__ ";asin: ~A" max-bad))) (let ((vals (vector -2.3124383412727526203 -0.88137358701954302523 0.00000000000000000000 0.099834078899207563327 0.19869011034924140647 0.29567304756342243910 0.39003531977071527608 0.48121182505960344750 0.56882489873224753010 0.65266656608235578681 0.73266825604541086415 0.80886693565278246251 0.88137358701954302523 1.4436354751788103425 1.8184464592320668235 2.0947125472611012942 2.3124383412727526203 2.9982229502979697388 5.2983423656105887574 7.6009027095419886115)) (args (vector -5.0 -1.0 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 2.0 3.0 4.0 5.0 10.0 100.0 1000.0)) (max-bad 0.0)) (do ((i 0 (+ i 1))) ((= i 20)) (let* ((nval (asinh (vector-ref args i))) (diff (abs (- nval (vector-ref vals i))))) (if (> diff max-bad) (set! max-bad diff)) (if (> max-bad 1.0e-14) (snd-display #__line__ ";asinh(~A): ~A ~A -> ~A" (vector-ref args i) nval (vector-ref vals i) max-bad))))) (let ((vals (vector 0.00000000000000000000 0.24497866312686415417 0.32175055439664219340 0.46364760900080611621 0.78539816339744830962 1.1071487177940905030 1.2490457723982544258 1.3258176636680324651 1.3734007669450158609 1.4711276743037345919 1.5208379310729538578)) (args (vector 0.00000000000000000000 0.25000000000000000000 0.33333333333333333333 0.50000000000000000000 1.0000000000000000000 2.0000000000000000000 3.0000000000000000000 4.0000000000000000000 5.0000000000000000000 10.000000000000000000 20.000000000000000000)) (max-bad 0.0)) (do ((i 0 (+ i 1))) ((= i 11)) (let* ((nval (atan (vector-ref args i))) (diff (abs (- nval (vector-ref vals i))))) (if (> diff max-bad) (set! max-bad diff)))) (if (> max-bad 1.0e-15) (snd-display #__line__ ";atan: ~A" max-bad))) (let ((vals (vector -0.54930614433405484570 0.00000000000000000000 0.0010000003333335333335 0.10033534773107558064 0.20273255405408219099 0.30951960420311171547 0.42364893019360180686 0.54930614433405484570 0.69314718055994530942 0.86730052769405319443 1.0986122886681096914 1.4722194895832202300 2.6466524123622461977 3.8002011672502000318 7.2543286192620472067)) (args (vector -0.5 0.0 0.001 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 0.99 0.999 0.999999)) (max-bad 0.0)) (do ((i 0 (+ i 1))) ((= i 15)) (let* ((nval (atanh (vector-ref args i))) (diff (abs (- nval (vector-ref vals i))))) (if (> diff max-bad) (set! max-bad diff)) (if (> diff 1.0e-10) ; one is > e-11 (snd-display #__line__ ";atanh(~A): ~A ~A -> ~A" (vector-ref args i) (vector-ref vals i) nval diff))))) (let ((vals (vector 0.1000000000000000E+01 0.1010025027795146E+01 0.1040401782229341E+01 0.1092045364317340E+01 0.1166514922869803E+01 0.1266065877752008E+01 0.1393725584134064E+01 0.1553395099731217E+01 0.1749980639738909E+01 0.1989559356618051E+01 0.2279585302336067E+01 0.3289839144050123E+01 0.4880792585865024E+01 0.7378203432225480E+01 0.1130192195213633E+02 0.1748117185560928E+02 0.2723987182360445E+02 0.6723440697647798E+02 0.4275641157218048E+03 0.2815716628466254E+04)) (args (vector 0.00E+00 0.20E+00 0.40E+00 0.60E+00 0.80E+00 0.10E+01 0.12E+01 0.14E+01 0.16E+01 0.18E+01 0.20E+01 0.25E+01 0.30E+01 0.35E+01 0.40E+01 0.45E+01 0.50E+01 0.60E+01 0.80E+01 0.10E+02)) (max-bad 0.0)) (do ((i 0 (+ i 1))) ((= i 20)) (let* ((nval (bes-i0 (vector-ref args i))) (diff (abs (- nval (vector-ref vals i))))) (if (> diff max-bad) (set! max-bad diff)) (if (> diff 1.0e-4) (snd-display #__line__ ";bes-i0(~A): ~A ~A -> ~A" (vector-ref args i) (vector-ref vals i) nval diff))))) (let ((vals (vector -0.1775967713143383E+00 -0.3971498098638474E+00 -0.2600519549019334E+00 0.2238907791412357E+00 0.7651976865579666E+00 0.1000000000000000E+01 0.7651976865579666E+00 0.2238907791412357E+00 -0.2600519549019334E+00 -0.3971498098638474E+00 -0.1775967713143383E+00 0.1506452572509969E+00 0.3000792705195556E+00 0.1716508071375539E+00 -0.9033361118287613E-01 -0.2459357644513483E+00 -0.1711903004071961E+00 0.4768931079683354E-01 0.2069261023770678E+00 0.1710734761104587E+00 -0.1422447282678077E-01)) (args (vector -5.0E+00 -4.0E+00 -3.0E+00 -2.0E+00 -1.0E+00 0.0E+00 1.0E+00 2.0E+00 3.0E+00 4.0E+00 5.0E+00 6.0E+00 7.0E+00 8.0E+00 9.0E+00 10.0E+00 11.0E+00 12.0E+00 13.0E+00 14.0E+00 15.0E+00)) (max-bad 0.0)) (do ((i 0 (+ i 1))) ((= i 21)) (let* ((nval (bes-j0 (vector-ref args i))) (diff (abs (- nval (vector-ref vals i))))) (if (> diff max-bad) (set! max-bad diff)) (if (> diff 1.0e-15) (snd-display #__line__ ";bes-j0(~A): ~A ~A -> ~A" (vector-ref args i) (vector-ref vals i) nval diff))))) (let ((vals (vector 0.3275791375914652E+00 0.6604332802354914E-01 -0.3390589585259365E+00 -0.5767248077568734E+00 -0.4400505857449335E+00 0.0000000000000000E+00 0.4400505857449335E+00 0.5767248077568734E+00 0.3390589585259365E+00 -0.6604332802354914E-01 -0.3275791375914652E+00 -0.2766838581275656E+00 -0.4682823482345833E-02 0.2346363468539146E+00 0.2453117865733253E+00 0.4347274616886144E-01 -0.1767852989567215E+00 -0.2234471044906276E+00 -0.7031805212177837E-01 0.1333751546987933E+00 0.2051040386135228E+00)) (args (vector -5.0E+00 -4.0E+00 -3.0E+00 -2.0E+00 -1.0E+00 0.0E+00 1.0E+00 2.0E+00 3.0E+00 4.0E+00 5.0E+00 6.0E+00 7.0E+00 8.0E+00 9.0E+00 10.0E+00 11.0E+00 12.0E+00 13.0E+00 14.0E+00 15.0E+00)) (max-bad 0.0)) (do ((i 0 (+ i 1))) ((= i 21)) (let* ((nval (bes-j1 (vector-ref args i))) (diff (abs (- nval (vector-ref vals i))))) (if (> diff max-bad) (set! max-bad diff)) (if (> diff 1.0e-15) (snd-display #__line__ ";bes-j1(~A): ~A ~A -> ~A" (vector-ref args i) (vector-ref vals i) nval diff))))) (let ((vals (vector 0.1149034849319005E+00 0.3528340286156377E+00 0.4656511627775222E-01 0.2546303136851206E+00 -0.5971280079425882E-01 0.2497577302112344E-03 0.7039629755871685E-02 0.2611405461201701E+00 -0.2340615281867936E+00 -0.8140024769656964E-01 0.2630615123687453E-09 0.2515386282716737E-06 0.1467802647310474E-02 0.2074861066333589E+00 -0.1138478491494694E+00 0.3873503008524658E-24 0.3918972805090754E-18 0.2770330052128942E-10 0.1151336924781340E-04 -0.1167043527595797E+00)) (ns (vector 2 2 2 2 2 5 5 5 5 5 10 10 10 10 10 20 20 20 20 20)) (args (vector 1.0E+00 2.0E+00 5.0E+00 10.0E+00 50.0E+00 1.0E+00 2.0E+00 5.0E+00 10.0E+00 50.0E+00 1.0E+00 2.0E+00 5.0E+00 10.0E+00 50.0E+00 1.0E+00 2.0E+00 5.0E+00 10.0E+00 50.0E+00)) (max-bad 0.0)) (do ((i 0 (+ i 1))) ((= i 20)) (let* ((nval (bes-jn (vector-ref ns i) (vector-ref args i))) (diff (abs (- nval (vector-ref vals i))))) (if (> diff max-bad) (set! max-bad diff)) (if (> diff 1.0e-15) (snd-display #__line__ ";bes-jn(~A ~A): ~A ~A -> ~A" (vector-ref ns i) (vector-ref args i) (vector-ref vals i) nval diff))))) (let ((vals (vector -0.1534238651350367E+01 0.8825696421567696E-01 0.5103756726497451E+00 0.3768500100127904E+00 -0.1694073932506499E-01 -0.3085176252490338E+00 -0.2881946839815792E+00 -0.2594974396720926E-01 0.2235214893875662E+00 0.2499366982850247E+00 0.5567116728359939E-01 -0.1688473238920795E+00 -0.2252373126343614E+00 -0.7820786452787591E-01 0.1271925685821837E+00 0.2054642960389183E+00)) (args (vector 0.1E+00 1.0E+00 2.0E+00 3.0E+00 4.0E+00 5.0E+00 6.0E+00 7.0E+00 8.0E+00 9.0E+00 10.0E+00 11.0E+00 12.0E+00 13.0E+00 14.0E+00 15.0E+00)) (max-bad 0.0)) (do ((i 0 (+ i 1))) ((= i 16)) (let* ((nval (bes-y0 (vector-ref args i))) (diff (abs (- nval (vector-ref vals i))))) (if (> diff max-bad) (set! max-bad diff)) (if (> diff 1.0e-15) (snd-display #__line__ ";bes-y0(~A): ~A ~A -> ~A" (vector-ref args i) (vector-ref vals i) nval diff))))) (let ((vals (vector -0.6458951094702027E+01 -0.7812128213002887E+00 -0.1070324315409375E+00 0.3246744247918000E+00 0.3979257105571000E+00 0.1478631433912268E+00 -0.1750103443003983E+00 -0.3026672370241849E+00 -0.1580604617312475E+00 0.1043145751967159E+00 0.2490154242069539E+00 0.1637055374149429E+00 -0.5709921826089652E-01 -0.2100814084206935E+00 -0.1666448418561723E+00 0.2107362803687351E-01)) (args (vector 0.1E+00 1.0E+00 2.0E+00 3.0E+00 4.0E+00 5.0E+00 6.0E+00 7.0E+00 8.0E+00 9.0E+00 10.0E+00 11.0E+00 12.0E+00 13.0E+00 14.0E+00 15.0E+00)) (max-bad 0.0)) (do ((i 0 (+ i 1))) ((= i 16)) (let* ((nval (bes-y1 (vector-ref args i))) (diff (abs (- nval (vector-ref vals i))))) (if (> diff max-bad) (set! max-bad diff)) (if (> diff 1.0e-14) (snd-display #__line__ ";bes-y1(~A): ~A ~A -> ~A" (vector-ref args i) (vector-ref vals i) nval diff))))) (let ((vals (vector -0.1650682606816254E+01 -0.6174081041906827E+00 0.3676628826055245E+00 -0.5868082442208615E-02 0.9579316872759649E-01 -0.2604058666258122E+03 -0.9935989128481975E+01 -0.4536948224911019E+00 0.1354030476893623E+00 -0.7854841391308165E-01 -0.1216180142786892E+09 -0.1291845422080393E+06 -0.2512911009561010E+02 -0.3598141521834027E+00 0.5723897182053514E-02 -40816513889983664.0 -0.5933965296914321E+09 -0.1597483848269626E+04 0.1644263394811578E-01)) ;; yn(20, 2.0) prints -40816513889983664.0 but I guess due to float inaccuracies (bes-yn 20 2.0) is -40816513889983672.0? (ns (vector 2 2 2 2 2 5 5 5 5 5 10 10 10 10 10 20 20 20 20)) (args (vector 1.0E+00 2.0E+00 5.0E+00 10.0E+00 50.0E+00 1.0E+00 2.0E+00 5.0E+00 10.0E+00 50.0E+00 1.0E+00 2.0E+00 5.0E+00 10.0E+00 50.0E+00 2.0E+00 5.0E+00 10.0E+00 50.0E+00)) (max-bad 0.0)) (do ((i 0 (+ i 1))) ((= i 19)) (let* ((nval (bes-yn (vector-ref ns i) (vector-ref args i))) (diff (abs (- nval (vector-ref vals i))))) (if (> diff max-bad) (set! max-bad diff)) (if (and (> diff 1.0e-6) (not (= i 15))) ; see above (snd-display #__line__ ";bes-yn(~A ~A): ~A ~A -> ~A" (vector-ref ns i) (vector-ref args i) (vector-ref vals i) nval diff))))) ;; one (20 1.0) is off by a lot but the val is 1e22 ;; numerics stuff (let ((ns (vector 1 6 6 6 15 15 15 15 15 15 15)) (ks (vector 0 1 3 5 1 3 5 7 9 11 13)) (vals (vector 1 6 20 6 15 455 3003 6435 5005 1365 105))) (do ((i 0 (+ i 1))) ((= i 11)) (let ((nval (binomial-direct (vector-ref ns i) (vector-ref ks i))) (mval (n-choose-k (vector-ref ns i) (vector-ref ks i)))) (if (or (not (= nval (vector-ref vals i))) (not (= mval (vector-ref vals i)))) (snd-display #__line__ ";binomial(~A ~A): ~A ~A ~A" (vector-ref ns i) (vector-ref ks i) nval mval (vector-ref vals i)))))) (let ((ls (vector 1 1 1 1 1 2 2 2 3 3 3 3 4 5 6 7 8 9 10)) (ms (vector 0 0 0 0 1 0 1 2 0 1 2 3 2 2 3 3 4 4 5)) (vals (vector 0.000000 0.500000 0.707107 1.000000 -0.866025 -0.125000 -1.29904 2.25000 -0.437500 -0.324759 5.62500 -9.74278 4.21875 -4.92187 12.7874 116.685 -1050.67 -2078.49 30086.2)) (xs (vector 0.0 0.5 0.7071067 1.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5))) (do ((i 0 (+ i 1))) ((= i 19)) (let ((val (plgndr (vector-ref ls i) (vector-ref ms i) (vector-ref xs i)))) (if (or (not (real? val)) (not (real? (vector-ref vals i))) (> (abs (- val (vector-ref vals i))) 0.1)) (snd-display #__line__ ";plgndr(~A ~A ~A) = ~A (~A)" (vector-ref ls i) (vector-ref ms i) (vector-ref xs i) val (vector-ref vals i)))))) (let ((vals (vector 1.0000000000 0.8000000000 0.2800000000 -0.3520000000 -0.8432000000 -0.9971200000 -0.7521920000 -0.2063872000 0.4219724800 0.8815431680 0.9884965888 0.7000513741 0.1315856097)) (ns (vector 0 1 2 3 4 5 6 7 8 9 10 11 12)) (xs (vector 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8))) (do ((i 0 (+ i 1))) ((= i 13)) (let ((val (chebyshev (vector-ref ns i) (vector-ref xs i)))) (if (fneq val (vector-ref vals i)) (snd-display #__line__ ";chebyshev ~A ~A -> ~A ~A" (vector-ref ns i) (vector-ref xs i) val (vector-ref vals i))))) (do ((i 0 (+ i 1))) ((= i 10)) (let* ((x (random 10.0)) (order (random 10)) (val1 (gegenbauer order x 1.0)) (val2 (chebyshev order x 2))) (if (fneq val1 val2) (snd-display #__line__ ";gegenbauer/chebyshev (alpha=1) ~A ~A: ~A ~A" order x val1 val2))))) (let ((as (vector 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 3.0 3.0 3.0 3.0 3.0 3.0 3.0 3.0 3.0 3.0 3.0 3.0 3.0 3.0 3.0 3.0)) (vals (vector 1.0000000000 0.2000000000 -0.4400000000 -0.2800000000 0.2320000000 0.3075200000 -0.0805760000 -0.2935168000 -0.0395648000 0.2459712000 0.1290720256 0.696706 ; was 0 but explicit formula says 2/n cos(nx) -0.3600000000 -0.0800000000 0.8400000000 2.4000000000 4.6000000000 7.4400000000 10.9200000000 15.0400000000 19.8000000000 25.2000000000 9.0000000000 -0.1612800000 ; was -9 but that is wrong (see G&R explicit formula) -6.6729600000 -8.3750400000 -5.5267200000 0.0000000000 5.5267200000 8.3750400000 6.6729600000 0.1612800000 -9.0000000000 -15.4252800000 -9.6969600000 22.4409600000 100.8892800000 252.0000000000)) (ns (vector 0 1 2 3 4 5 6 7 8 9 10 2 2 2 2 2 2 2 2 2 2 2 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5)) (xs (vector 0.20 0.20 0.20 0.20 0.20 0.20 0.20 0.20 0.20 0.20 0.20 0.40 0.40 0.40 0.40 0.40 0.40 0.40 0.40 0.40 0.40 0.40 -0.50 -0.40 -0.30 -0.20 -0.10 0.00 0.10 0.20 0.30 0.40 0.50 0.60 0.70 0.80 0.90 1.00))) (define (g3 x alpha) (- (* 1/3 alpha x x x (+ (* 4 alpha alpha) (* 12 alpha) 8)) (* 2 alpha x (+ alpha 1)))) (define (g5 x alpha) (+ (* 1/15 alpha x x x x x (+ (* 4 alpha alpha alpha alpha) (* 40 alpha alpha alpha) (* 140 alpha alpha) (* 200 alpha) 96)) (* -1/3 alpha x x x (+ (* 4 alpha alpha alpha) (* 24 alpha alpha) (* 44 alpha) 24)) (* alpha x (+ (* alpha alpha) (* 3 alpha) 2)))) (do ((i 0 (+ i 1))) ((= i 38)) (let ((val (gegenbauer (vector-ref ns i) (vector-ref xs i) (vector-ref as i)))) (if (fneq val (vector-ref vals i)) (snd-display #__line__ ";gegenbauer ~A ~A ~A -> ~A ~A" (vector-ref ns i) (vector-ref xs i) (vector-ref as i) val (vector-ref vals i))))) (do ((i 0 (+ i 1))) ((= i 10)) (let* ((x (random 10.0)) (alpha (random 3.0)) (val1 (gegenbauer 3 x alpha)) (val2 (g3 x alpha))) (if (fneq val1 val2) (snd-display #__line__ ";gegenbauer 3 ~A ~A: ~A ~A" x alpha val1 val2)))) (do ((i 0 (+ i 1))) ((= i 10)) (let* ((x (random 10.0)) (alpha (random 3.0)) (val1 (gegenbauer 5 x alpha)) (val2 (g5 x alpha))) (if (fneq val1 val2) (snd-display #__line__ ";gegenbauer 5 ~A ~A: ~A ~A" x alpha val1 val2)))) ) (let ((vals (vector 1.0000000000 0.0000000000 -0.5000000000 -0.6666666667 -0.6250000000 -0.4666666667 -0.2569444444 -0.0404761905 0.1539930556 0.3097442681 0.4189459325 0.4801341791 0.4962122235 -0.4455729167 0.8500000000 -3.1666666667 34.3333333333)) (ns (vector 0 1 2 3 4 5 6 7 8 9 10 11 12 5 5 5 5)) (xs (vector 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.5 3.0 5.0 10.0))) (do ((i 0 (+ i 1))) ((= i 17)) (let ((val (laguerre (vector-ref ns i) (vector-ref xs i)))) (if (fneq val (vector-ref vals i)) (snd-display #__line__ ";laguerre ~A ~A -> ~A ~A" (vector-ref ns i) (vector-ref xs i) val (vector-ref vals i))))) ) (let ((vals (vector 1.0 10.0 98.0 940.0 8812.0 80600.0 717880.0 6211600.0 52065680.0 ; was off by factor of 10? 421271200 3275529760.0 24329873600.0 171237081280.0 41.0 -8.0 3816.0 3041200.0)) (ns (vector 0 1 2 3 4 5 6 7 8 9 10 11 12 5 5 5 5)) (xs (vector 5.0 5.0 5.0 5.0 5.0 5.0 5.0 5.0 5.0 5.0 5.0 5.0 5.0 0.5 1.0 3.0 10.0))) (do ((i 0 (+ i 1))) ((= i 13)) (let ((val (hermite (vector-ref ns i) (vector-ref xs i)))) (if (fneq val (vector-ref vals i)) (snd-display #__line__ ";hermite ~A ~A -> ~A ~A" (vector-ref ns i) (vector-ref xs i) val (vector-ref vals i))))) ) (do ((i 0 (+ i 1))) ((= i 10)) (let ((lv (legendre-polynomial (let ((v (make-vector 10 0.0))) (vector-set! v i 1.0) v) 0.5)) (pv (plgndr i 0 0.5))) (if (fneq lv pv) (snd-display #__line__ ";lv: ~A, pv: ~A (~A)" lv pv i)))) (let ((pow-x (lambda (pow x) ;; A&S p798 (if (= pow 0) (legendre-polynomial (vector 1) x) (if (= pow 1) (legendre-polynomial (vector 0 1) x) (if (= pow 2) (* (/ 1.0 3.0) (legendre-polynomial (vector 1 0 2) x)) (if (= pow 3) (* (/ 1.0 5.0) (legendre-polynomial (vector 0 3 0 2) x)) (if (= pow 4) (* (/ 1.0 35.0) (legendre-polynomial (vector 7 0 20 0 8) x)) (if (= pow 5) (* (/ 1.0 63.0) (legendre-polynomial (vector 0 27 0 28 0 8) x)) (if (= pow 6) (* (/ 1.0 231.0) (legendre-polynomial (vector 33 0 110 0 72 0 16) x)) 'oops)))))))))) (for-each (lambda (x) (for-each (lambda (pow) (let ((lv (pow-x pow x)) (sv (expt x pow))) (if (fneq lv sv) (snd-display #__line__ ";~A ^ ~A = ~A ~A?" x pow lv sv)))) (list 0 1 2 3 4 5 6))) (list 2.0 0.5 0.1 -0.5 3.0 0.8))) (let ((snd (with-sound (:scaled-to 0.5) (do ((i 0 (+ i 1)) (x 0.0 (+ x .02))) ((= i 100)) (outa i (legendre 20 (cos x))))))) (let ((index (find-sound snd))) (if (fneq (sample 0 index 0) 0.5) (snd-display #__line__ ";legendre(cos(x)) 0: ~A" (sample 0 index 0))) (if (fneq (sample 50 index 0) 0.062572978) (snd-display #__line__ ";legendre(cos(x)) 50: ~A" (sample 50 index 0))) (close-sound index))) (let (;(h0 (lambda (x) 1.0)) (h1 (lambda (x) (* 2 x))) (h2 (lambda (x) (- (* 4 x x) 2))) (h3 (lambda (x) (- (* 8 x x x) (* 12 x)))) (h4 (lambda (x) (+ (* 16 x x x x) (* -48 x x) 12))) (h5 (lambda (x) (+ (* 32 x x x x x) (* -160 x x x) (* 120 x)))) (h6 (lambda (x) (+ (* 64 x x x x x x) (* -480 x x x x) (* 720 x x) -120)))) (do ((i 0 (+ i 1))) ((= i 20)) (let ((x (random 10.0))) (let ((v1 (h1 x)) (v11 (hermite 1 x)) (v2 (h2 x)) (v22 (hermite 2 x)) (v3 (h3 x)) (v33 (hermite 3 x)) (v4 (h4 x)) (v44 (hermite 4 x)) (v5 (h5 x)) (v55 (hermite 5 x)) (v6 (h6 x)) (v66 (hermite 6 x))) (if (fneq v1 v11) (snd-display #__line__ ";hermite 1 ~A: ~A ~A" x v1 v11) (if (fneq v2 v22) (snd-display #__line__ ";hermite 2 ~A: ~A ~A" x v2 v22) (if (fneq v3 v33) (snd-display #__line__ ";hermite 3 ~A: ~A ~A" x v3 v33) (if (fneq v4 v44) (snd-display #__line__ ";hermite 4 ~A: ~A ~A" x v4 v44) (if (fneq v5 v55) (snd-display #__line__ ";hermite 5 ~A: ~A ~A" x v5 v55) (if (fneq v6 v66) (snd-display #__line__ ";hermite 6 ~A: ~A ~A" x v6 v66))))))))))) (let ((lg1 (lambda (x) (- 1 x))) (lg2 (lambda (x) (+ 1 (* 0.5 x x) (* -2 x)))) (lag1 (lambda (x a) (+ 1 a (- x)))) (lag2 (lambda (x a) (* 0.5 (+ (* x x) (* -2 x (+ a 2)) (* (+ a 1) (+ a 2)))))) (lag3 (lambda (x a) (* (/ -1.0 6.0) (+ (* x x x) (* -3 x x (+ a 3)) (* 3 x (+ a 2) (+ a 3)) (* -1 (+ a 1) (+ a 2) (+ a 3))))))) (let ((x (random 10.0)) (a (random 1.0))) (let ((v1 (laguerre 1 x)) (v11 (lg1 x)) (v2 (laguerre 2 x)) (v22 (lg2 x)) (va1 (lag1 x a)) (va11 (laguerre 1 x a)) (va2 (lag2 x a)) (va22 (laguerre 2 x a)) (va3 (lag3 x a)) (va33 (laguerre 3 x a))) (if (fneq v1 v11) (snd-display #__line__ ";laguerre 1 ~A: ~A ~A" x v1 v11) (if (fneq v2 v22) (snd-display #__line__ ";laguerre 2 ~A: ~A ~A" x v2 v22) (if (fneq va1 va11) (snd-display #__line__ ";laguerre 1a ~A ~A: ~A ~A" x a va1 va11) (if (fneq va2 va22) (snd-display #__line__ ";laguerre 2a ~A ~A: ~A ~A" x a va2 va22) (if (fneq va3 va33) (snd-display #__line__ ";laguerre 3a ~A ~A: ~A ~A" x a va3 va33))))))))) ) ;; ---------------- ;; start of test (do ((clmtest 0 (+ 1 clmtest))) ((= clmtest tests)) (log-mem clmtest) (numerical-reality-checks) (if (mus-generator? 321) (snd-display #__line__ ";123 is a gen?")) (if (mus-generator? (list 321)) (snd-display #__line__ ";(123) is a gen?")) (if (mus-generator? (list 'hi 321)) (snd-display #__line__ ";(hi 123) is a gen?")) (set! *clm-srate* 22050) (let ((samps (seconds->samples 1.0)) (secs (samples->seconds 22050))) (if (not (= samps 22050)) (snd-display #__line__ ";seconds->samples: ~A" samps)) (if (fneq secs 1.0) (snd-display #__line__ ";samples->seconds: ~A" secs))) (set! *clm-file-buffer-size* default-file-buffer-size) (let ((var (catch #t (lambda () (set! *clm-file-buffer-size* #f)) (lambda args args)))) (if (not (eq? (car var) 'wrong-type-arg)) (snd-display #__line__ ";mus-file-buffer-size bad size: ~A" var))) (set! *clm-file-buffer-size* 128) (if (not (= *clm-file-buffer-size* 128)) (snd-display #__line__ ";mus-file-buffer-size: ~D?" *clm-file-buffer-size*)) (set! *clm-file-buffer-size* default-file-buffer-size) (if (and (not (= *mus-array-print-length* 8)) (not (= *mus-array-print-length* 12)) (not (= *mus-array-print-length* 32))) (snd-display #__line__ ";mus-array-print-length: ~D?" *mus-array-print-length*)) (set! *mus-array-print-length* 32) (if (not (= *mus-array-print-length* 32)) (snd-display #__line__ ";set mus-array-print-length: ~D?" *mus-array-print-length*)) (set! *mus-array-print-length* 8) (let ((fudge *mus-float-equal-fudge-factor*)) (if (> (abs (- *mus-float-equal-fudge-factor* 0.0000001)) 0.00000001) (snd-display #__line__ ";mus-float-equal-fudge-factor: ~A?" *mus-float-equal-fudge-factor*)) (set! *mus-float-equal-fudge-factor* .1) (if (fneq *mus-float-equal-fudge-factor* .1) (snd-display #__line__ ";set mus-float-equal-fudge-factor: ~A?" *mus-float-equal-fudge-factor*)) (set! *mus-float-equal-fudge-factor* fudge)) (if (fneq *clm-srate* 22050.0) (snd-display #__line__ ";mus-srate: ~F?" *clm-srate*)) (if (fneq (hz->radians 1.0) 2.84951704088598e-4) (snd-display #__line__ ";hz->radians: ~F?" (hz->radians 1.0))) (if (fneq (radians->hz 2.84951704088598e-4) 1.0) (snd-display #__line__ ";radians->hz: ~F?" (radians->hz 2.84951704088598e-4))) (if (fneq (radians->degrees 1.0) 57.2957801818848) (snd-display #__line__ ";radians->degrees: ~F?" (radians->degrees 1.0))) (if (fneq (degrees->radians 57.2957801818848) 1.0) (snd-display #__line__ ";degrees->radians: ~F?" (degrees->radians 57.2957801818848))) (if (fneq (linear->db .25) -12.0411996841431) (snd-display #__line__ ";linear->db: ~F?" (linear->db .25))) (if (fneq (db->linear -12.0411996841431) .25) (snd-display #__line__ ";db->linear: ~F?" (db->linear -12.0411996841431))) (if (fneq (odd-weight 0.0) 0.0) (snd-display #__line__ ";odd-weight 0.0: ~F?" (odd-weight 0.0))) (if (fneq (odd-weight 2.0) 0.0) (snd-display #__line__ ";odd-weight 2.0: ~F?" (odd-weight 2.0))) (if (fneq (odd-weight 1.0) 1.0) (snd-display #__line__ ";odd-weight 1.0: ~F?" (odd-weight 1.0))) (if (fneq (odd-weight 1.5) 0.5) (snd-display #__line__ ";odd-weight 1.5: ~F?" (odd-weight 1.5))) (if (fneq (odd-weight 2.5) 0.5) (snd-display #__line__ ";odd-weight 2.5: ~F?" (odd-weight 2.5))) (if (fneq (odd-weight 2.1) 0.1) (snd-display #__line__ ";odd-weight 2.1: ~F?" (odd-weight 2.1))) (if (fneq (odd-weight 2.9) 0.9) (snd-display #__line__ ";odd-weight 2.9: ~F?" (odd-weight 2.9))) (if (fneq (odd-weight 1.1) 0.9) (snd-display #__line__ ";odd-weight 1.1: ~F?" (odd-weight 1.1))) (if (fneq (odd-weight 1.9) 0.1) (snd-display #__line__ ";odd-weight 1.9: ~F?" (odd-weight 1.9))) (if (fneq (even-weight 0.0) 1.0) (snd-display #__line__ ";even-weight 0.0: ~F?" (even-weight 0.0))) (if (fneq (even-weight 2.0) 1.0) (snd-display #__line__ ";even-weight 2.0: ~F?" (even-weight 2.0))) (if (fneq (even-weight 1.0) 0.0) (snd-display #__line__ ";even-weight 1.0: ~F?" (even-weight 1.0))) (if (fneq (even-weight 1.5) 0.5) (snd-display #__line__ ";even-weight 1.5: ~F?" (even-weight 1.5))) (if (fneq (even-weight 2.5) 0.5) (snd-display #__line__ ";even-weight 2.5: ~F?" (even-weight 2.5))) (if (fneq (even-weight 2.1) 0.9) (snd-display #__line__ ";even-weight 2.1: ~F?" (even-weight 2.1))) (if (fneq (even-weight 2.9) 0.1) (snd-display #__line__ ";even-weight 2.9: ~F?" (even-weight 2.9))) (if (fneq (even-weight 1.1) 0.1) (snd-display #__line__ ";even-weight 1.1: ~F?" (even-weight 1.1))) (if (fneq (even-weight 1.9) 0.9) (snd-display #__line__ ";even-weight 1.9: ~F?" (even-weight 1.9))) (if (fneq (odd-multiple 0.0 2.0) 2.0) (snd-display #__line__ ";odd-multiple 0.0: ~F?" (odd-multiple 0.0 2.0))) (if (fneq (odd-multiple 2.0 2.0) 6.0) (snd-display #__line__ ";odd-multiple 2.0: ~F?" (odd-multiple 2.0 2.0))) (if (fneq (odd-multiple 1.0 2.0) 2.0) (snd-display #__line__ ";odd-multiple 1.0: ~F?" (odd-multiple 1.0 2.0))) (if (fneq (odd-multiple 1.5 2.0) 2.0) (snd-display #__line__ ";odd-multiple 1.5: ~F?" (odd-multiple 1.5 2.0))) (if (fneq (odd-multiple 2.5 2.0) 6.0) (snd-display #__line__ ";odd-multiple 2.5: ~F?" (odd-multiple 2.5 2.0))) (if (fneq (odd-multiple 2.1 2.0) 6.0) (snd-display #__line__ ";odd-multiple 2.1: ~F?" (odd-multiple 2.1 2.0))) (if (fneq (odd-multiple 2.9 2.0) 6.0) (snd-display #__line__ ";odd-multiple 2.9: ~F?" (odd-multiple 2.9 2.0))) (if (fneq (odd-multiple 1.1 2.0) 2.0) (snd-display #__line__ ";odd-multiple 1.1: ~F?" (odd-multiple 1.1 2.0))) (if (fneq (odd-multiple 1.9 2.0) 2.0) (snd-display #__line__ ";odd-multiple 1.9: ~F?" (odd-multiple 1.9 2.0))) (if (fneq (even-multiple 0.0 2.0) 0.0) (snd-display #__line__ ";even-multiple 0.0: ~F?" (even-multiple 0.0 2.0))) (if (fneq (even-multiple 2.0 2.0) 4.0) (snd-display #__line__ ";even-multiple 2.0: ~F?" (even-multiple 2.0 2.0))) (if (fneq (even-multiple 1.0 2.0) 4.0) (snd-display #__line__ ";even-multiple 1.0: ~F?" (even-multiple 1.0 2.0))) (if (fneq (even-multiple 1.5 2.0) 4.0) (snd-display #__line__ ";even-multiple 1.5: ~F?" (even-multiple 1.5 2.0))) (if (fneq (even-multiple 2.5 2.0) 4.0) (snd-display #__line__ ";even-multiple 2.5: ~F?" (even-multiple 2.5 2.0))) (if (fneq (even-multiple 2.1 2.0) 4.0) (snd-display #__line__ ";even-multiple 2.1: ~F?" (even-multiple 2.1 2.0))) (if (fneq (even-multiple 2.9 2.0) 4.0) (snd-display #__line__ ";even-multiple 2.9: ~F?" (even-multiple 2.9 2.0))) (if (fneq (even-multiple 1.1 2.0) 4.0) (snd-display #__line__ ";even-multiple 1.1: ~F?" (even-multiple 1.1 2.0))) (if (fneq (even-multiple 1.9 2.0) 4.0) (snd-display #__line__ ";even-multiple 1.9: ~F?" (even-multiple 1.9 2.0))) (if (fneq (ring-modulate .4 .5) .2) (snd-display #__line__ ";ring-modulate: ~F?" (ring-modulate .4 .5))) (if (fneq (amplitude-modulate 1.0 .5 .4) .7) (snd-display #__line__ ";amplitude-modulate: ~F?" (amplitude-modulate 1.0 .5 .4))) (if (fneq (contrast-enhancement 0.1 0.75) (sin (+ (* 0.1 (/ pi 2)) (* .75 (sin (* 0.1 2.0 pi)))))) (snd-display #__line__ ";contrast-enhancement: ~F (0.562925306221587)" (contrast-enhancement 0.1 0.75))) (if (fneq (contrast-enhancement 1.0) 1.0) (snd-display #__line__ ";contrast-enhancement opt: ~A" (contrast-enhancement 1.0))) (let ((lv0 (partials->polynomial (float-vector 1 1 2 1) mus-chebyshev-first-kind)) (lv1 (partials->polynomial '(1 1 2 1) mus-chebyshev-second-kind)) (lv2 (partials->polynomial '(1 1 2 1 3 1 5 1) mus-chebyshev-first-kind)) (lv3 (partials->polynomial '(1 1 2 1 3 1 5 1) mus-chebyshev-second-kind)) (lv4 (partials->polynomial '(1 1 2 .5 3 .1 6 .01) mus-chebyshev-first-kind)) (lv5 (partials->polynomial (list 1 1 2 .5 3 .1 6 .01) mus-chebyshev-second-kind)) (lv6 (partials->polynomial (float-vector 1 9 2 3 3 5 4 7 5 1))) ; MLB (lv7 (partials->polynomial '(7 1))) (lv7a (partials->polynomial '(7 1) mus-chebyshev-first-kind)) (lv8 (partials->polynomial '(7 1) mus-chebyshev-second-kind)) ) (if (not (fveql lv0 '(-1.000 1.000 2.000) 0)) (snd-display #__line__ ";partials->polynomial(1): ~A?" lv0)) (if (not (fveql lv1 '(1.000 2.000 0.0) 0)) (snd-display #__line__ ";partials->polynomial(2): ~A?" lv1)) (if (not (fveql lv2 '(-1.000 3.000 2.000 -16.000 0.000 16.000) 0)) (snd-display #__line__ ";partials->polynomial(3): ~A?" lv2)) (if (not (fveql lv3 '(1.000 2.000 -8.000 0.000 16.000 0.000) 0)) (snd-display #__line__ ";partials->polynomial(4): ~A?" lv3)) (if (not (fveql lv4 '(-0.510 0.700 1.180 0.400 -0.480 0.000 0.320) 0)) (snd-display #__line__ ";partials->polynomial(5): ~A?" lv4)) (if (not (fveql lv5 '(0.900 1.060 0.400 -0.320 0.000 0.320 0.000) 0)) (snd-display #__line__ ";partials->polynomial(6): ~A?" lv5)) (if (not (vequal lv6 (float-vector 4.000 -1.000 -50.000 0.000 56.000 16.000))) (snd-display #__line__ ";partials->polynomial(7): ~A?" lv6)) (if (not (vequal lv7 (float-vector 0.000 -7.000 0.000 56.000 0.000 -112.000 0.000 64.000))) (snd-display #__line__ ";partials->polynomial(8): ~A?" lv7)) (if (not (vequal lv8 (float-vector -1.000 0.000 24.000 0.000 -80.000 0.000 64.000 0.000))) (snd-display #__line__ ";partials->polynomial(9): ~A?" lv8)) (if (not (vequal lv7 lv7a)) (snd-display #__line__ ";partials->polynomial kind=1? ~A ~A" lv7 lv7a)) (if (not (vequal (normalize-partials (list 1 1 2 1)) (float-vector 1.000 0.500 2.000 0.500))) (snd-display #__line__ ";normalize-partials 1: ~A" (normalize-partials (list 1 1 2 1)))) (if (not (vequal (normalize-partials (float-vector 1 1 2 1)) (float-vector 1.000 0.500 2.000 0.500))) (snd-display #__line__ ";normalize-partials 2: ~A" (normalize-partials (float-vector 1 1 2 1)))) (if (not (vequal (normalize-partials (float-vector 1 1 2 -1)) (float-vector 1.000 0.500 2.000 -0.500))) (snd-display #__line__ ";normalize-partials 3: ~A" (normalize-partials (float-vector 1 1 2 -1)))) (if (not (vequal (normalize-partials (float-vector 1 -.1 2 -.1)) (float-vector 1.000 -0.500 2.000 -0.500))) (snd-display #__line__ ";normalize-partials 4: ~A" (normalize-partials (float-vector 1 -.1 2 -.1)))) (if (not (vequal (normalize-partials (float-vector 0 2 1 1 4 1)) (float-vector 0.000 0.500 1.000 0.250 4.000 0.250))) (snd-display #__line__ ";normalize-partials 4: ~A" (normalize-partials (float-vector 0 2 1 1 4 1)))) (if (fneq (polynomial lv7 1.0) (cosh (* 7 (acosh 1.0)))) (snd-display #__line__ ";ccosh cheb 7 1.0: ~A ~A" (polynomial lv7 1.0) (cosh (* 7 (acosh 1.0))))) (if (fneq (polynomial lv7 1.0) (cos (* 7 (acos 1.0)))) (snd-display #__line__ ";cos cheb 7 1.0: ~A ~A" (polynomial lv7 1.0) (cos (* 7 (acos 1.0))))) (if (fneq (polynomial lv8 0.5) (/ (sin (* 7 (acos 0.5))) (sin (acos 0.5)))) (snd-display #__line__ ";acos cheb 7 1.0: ~A ~A" (polynomial lv8 0.5) (/ (sin (* 7 (acos 0.5))) (sin (acos 0.5))))) ;; G&R 8.943 p 984 uses n+1 where we use n in Un? (our numbering keeps harmonics aligned between Tn and Un) (do ((i 0 (+ i 1))) ((= i 10)) (let ((val (mus-random 1.0))) (if (fneq (polynomial lv7 val) (cosh (* 7 (acosh val)))) (snd-display #__line__ ";ccosh cheb 7 ~A: ~A ~A" val (polynomial lv7 val) (cosh (* 7 (acosh val))))) (if (fneq (polynomial lv7 val) (cos (* 7 (acos val)))) (snd-display #__line__ ";cos cheb 7 ~A: ~A ~A" val (polynomial lv7 val) (cos (* 7 (acos val))))) (if (fneq (polynomial lv8 val) (/ (sin (* 7 (acos val))) (sin (acos val)))) (snd-display #__line__ ";acos cheb 7 ~A: ~A ~A" val (polynomial lv8 val) (/ (sin (* 7 (acos val))) (sin (acos val))))))) ) ;; check phase-quadrature cancellations (let ((cos-coeffs (partials->polynomial '(1 1 2 1) mus-chebyshev-first-kind)) (sin-coeffs (partials->polynomial (float-vector 1 1 2 1) mus-chebyshev-second-kind)) (incr (/ (* 2 pi 440.0) 22050.0))) (do ((i 0 (+ i 1)) (a 0.0 (+ a incr))) ((= i 1100)) (let* ((x (cos a)) (y (sin a)) (cax (polynomial cos-coeffs x)) (sax (polynomial sin-coeffs x)) (upper (- (* (cos (* 2 a)) cax) (* (sin (* 2 a)) y sax))) (lower (+ (* (cos (* 2 a)) cax) (* (sin (* 2 a)) y sax))) (upper2 (+ (cos (* a 3)) (cos (* a 4)))) (lower2 (+ 1.0 (cos a)))) (if (or (fneq upper upper2) (fneq lower lower2)) (snd-display #__line__ ";~A ~A, ~A ~A" upper upper2 lower lower2))))) (let ((tag (catch #t (lambda () (harmonicizer 550.0 (list .5 .3 .2) 10)) (lambda args (car args))))) (if (not (eq? tag 'no-data)) (snd-display #__line__ ";odd length arg to partials->polynomial: ~A" tag))) (let ((rdat (make-float-vector 16)) (idat (make-float-vector 16)) (vdat (make-float-vector 16))) (set! (rdat 0) 1.0) (set! (vdat 0) 1.0) (let ((v0 (spectrum rdat idat (make-fft-window rectangular-window 16) 1)) ;rectangular here to avoid clobbering 0-th data point (v1 (snd-spectrum vdat rectangular-window 16 #t))) (do ((i 0 (+ i 1))) ((= i 8)) ;should all be 1.0 (impulse in) (if (fneq (v0 i) (v1 i)) (snd-display #__line__ ";spectra not equal 1: ~A ~A" v0 v1)))) (float-vector-scale! idat 0.0) (float-vector-scale! rdat 0.0) (set! (rdat 0) 1.0) (let ((v0 (spectrum rdat idat (make-fft-window rectangular-window 17) 1)) ;rectangular here to avoid clobbering 0-th data point (v1 (snd-spectrum vdat rectangular-window 16 #t))) (do ((i 0 (+ i 1))) ((= i 8)) ;should all be 1.0 (impulse in) (if (fneq (v0 i) (v1 i)) (snd-display #__line__ ";spectra not equal 0: ~A ~A" v0 v1)))) (let ((var (catch #t (lambda () (spectrum rdat idat #f -1)) (lambda args args)))) (if (or (float-vector? var) (not (eq? (car var) 'out-of-range))) (snd-display #__line__ ";spectrum bad type: ~A" var)))) (let ((rdat (make-float-vector 16)) (idat (make-float-vector 16)) (xdat (make-float-vector 16)) (ydat (make-float-vector 16))) (set! (rdat 3) 1.0) (set! (xdat 3) 1.0) (fft rdat idat 1) (mus-fft xdat ydat 16 1) (if (fneq (rdat 0) (xdat 0)) (snd-display #__line__ ";ffts: ~A ~A?" rdat xdat)) (fft rdat idat -1) (mus-fft xdat ydat 17 -1) ; mistake is deliberate (do ((i 0 (+ i 1))) ((= i 16)) (if (or (and (= i 3) (or (fneq (rdat i) 16.0) (fneq (xdat i) 16.0))) (and (not (= i 3)) (or (fneq (rdat i) 0.0) (fneq (xdat i) 0.0)))) (snd-display #__line__ ";fft real[~D]: ~A ~A?" i (rdat i) (xdat i))) (if (or (fneq (idat i) 0.0) (fneq (ydat i) 0.0)) (snd-display #__line__ ";fft imag[~D]: ~A ~A?" i (idat i) (ydat i)))) (let ((var (catch #t (lambda () (mus-fft xdat ydat -1 0)) (lambda args args)))) (if (not (eq? (car var) 'out-of-range)) (snd-display #__line__ ";mus-fft bad len: ~A" var)))) (let ((rdat (make-float-vector 20)) (idat (make-float-vector 19))) (set! (rdat 3) 1.0) (mus-fft rdat idat) (convolution rdat idat) (spectrum rdat idat #f)) (let ((v0 (make-float-vector 10)) (v1 (make-float-vector 10))) (fill! v0 1.0) (fill! v1 0.5) (float-vector-multiply! v0 v1) (if (fneq (v0 0) 0.5) (snd-display #__line__ ";multiple-arrays: ~F?" (v0 0))) (let ((sum (dot-product v0 v1))) (if (fneq sum 2.5) (snd-display #__line__ ";dot-product: ~F?" sum))) (let ((sum (dot-product v0 v1 10))) (if (fneq sum 2.5) (snd-display #__line__ ";dot-product (10): ~F?" sum))) (let ((sum (dot-product v0 v1 3))) (if (fneq sum 0.75) (snd-display #__line__ ";dot-product (3): ~F?" sum))) (fill! v0 0.0) (if (fneq (v0 3) 0.0) (snd-display #__line__ ";fill!: ~A?" v0)) (fill! v0 1.0) (fill! v1 0.5) (let ((v2 (rectangular->polar v0 v1))) (if (fneq (v2 0) 1.118) (snd-display #__line__ ";rectangular->polar: ~A?" v2))) (set! (v0 0) 1.0) (set! (v1 0) 1.0) (rectangular->polar v0 v1) (if (or (fneq (v0 0) (sqrt 2.0)) (fneq (v1 0) (- (atan 1.0 1.0)))) ;(tan (atan 1.0 1.0)) -> 1.0 (snd-display #__line__ ";rectangular->polar (~A ~A): ~A ~A?" (sqrt 2.0) (- (atan 1.0 1.0)) (v0 0) (v1 0))) (polar->rectangular v0 v1) (if (or (fneq (v0 0) 1.0) (fneq (v1 0) 1.0)) (snd-display #__line__ ";polar->rectangular (1 1): ~A ~A?" (v0 0) (v1 0))) (let ((ind (open-sound "oboe.snd")) (rl (channel->float-vector 1200 512)) (im (make-float-vector 512))) (fft rl im 512) (let ((rl-copy (copy rl)) (im-copy (copy im))) (rectangular->polar rl im) (polar->rectangular rl im) (do ((i 0 (+ i 1))) ((= i 512)) (if (or (fneq (rl i) (rl-copy i)) (fneq (im i) (im-copy i))) (snd-display #__line__ ";polar->rectangular[~D]: ~A ~A ~A ~A" i (rl i) (rl-copy i) (im i) (im-copy i))))) (close-sound ind))) (let ((v0 (make-float-vector 8)) (v1 (make-float-vector 8))) (do ((i 0 (+ i 1))) ((= i 8)) (set! (v0 i) i) (set! (v1 i) (/ (+ i 1)))) (rectangular->magnitudes v0 v1) (if (not (vequal v0 (float-vector 1.000 1.118 2.028 3.010 4.005 5.003 6.002 7.001))) (snd-display #__line__ ";rectangular->magnitudes v0: ~A" v0))) (let ((v0 (make-float-vector 8)) (v1 (make-float-vector 8)) (v2 (make-float-vector 8)) (v3 (make-float-vector 8))) (do ((i 0 (+ i 1))) ((= i 8)) (let ((val1 (random 1.0)) (val2 (random 1.0))) (set! (v0 i) val1) (float-vector-set! v2 i val1) (float-vector-set! v1 i val2) (float-vector-set! v3 i val2))) (rectangular->magnitudes v0 v1) (rectangular->polar v2 v3) (if (not (vequal v0 v2)) (snd-display #__line__ ";rectangular->magnitudes|polar: ~A ~A" v0 v2))) (if (defined? 'edot-product) ; needs complex numbers in C (let* ((vals (make-float-vector 1 1.0)) (v1 (edot-product 0.0 vals))) (if (fneq v1 1.0) ; exp 0.0 * 1.0 (snd-display #__line__ ";edot a 1.0: ~A" v1)) (set! (vals 0) 0.0) (set! v1 (edot-product 0.0 vals)) (if (fneq v1 0.0) ; exp 0.0 * 0.0 (snd-display #__line__ ";edot b 0.0: ~A" v1)) (set! vals (make-vector 1 1.0)) (set! v1 (edot-product 0.0 vals)) (if (fneq v1 1.0) ; exp 0.0 * 1.0 (snd-display #__line__ ";edot c 1.0: ~A" v1)) (set! (vals 0) 0.0+i) (set! v1 (edot-product 0.0 vals)) (if (cneq v1 0.0+i) (snd-display #__line__ ";edot i: ~A" v1)) (set! vals (make-float-vector 4 1.0)) (set! v1 (edot-product (* 0.25 2 pi) vals)) (let ((v2 (+ (exp (* 0 2 pi)) (exp (* 0.25 2 pi)) (exp (* 0.5 2 pi)) (exp (* 0.75 2 pi))))) (if (fneq v1 v2) (snd-display #__line__ ";edot 4: ~A ~A" v1 v2))) (set! vals (make-vector 4 0.0)) (do ((i 0 (+ i 1))) ((= i 4)) (set! (vals i) (+ i 1.0))) (set! v1 (edot-product (* 0.25 2 pi 0.0-i) vals)) (let ((v2 (+ (* (exp (* 0 2 pi 0.0-i))) (* 2 (exp (* 0.25 2 pi 0.0-i))) (* 3 (exp (* 0.5 2 pi 0.0-i))) (* 4 (exp (* 0.75 2 pi 0.0-i)))))) (if (cneq v1 v2) (snd-display #__line__ ";edot 4 -i: ~A ~A" v1 v2))) (do ((i 0 (+ i 1))) ((= i 4)) (set! (vals i) (+ i 1.0+i))) (set! v1 (edot-product (* 0.25 2 pi 0.0-i) vals)) (let ((v2 (+ (* 1+i (exp (* 0 2 pi 0.0-i))) (* 2+i (exp (* 0.25 2 pi 0.0-i))) (* 3+i (exp (* 0.5 2 pi 0.0-i))) (* 4+i (exp (* 0.75 2 pi 0.0-i)))))) (if (cneq v1 v2) (snd-display #__line__ ";edot 4 -i * i: ~A ~A" v1 v2))))) (let ((v0 (make-float-vector 3))) (set! (v0 0) 1.0) (set! (v0 1) 0.5) (set! (v0 2) 0.1) (if (or (fneq (polynomial v0 0.0) 1.0) (fneq (polynomial v0 1.0) 1.6) (fneq (polynomial v0 2.0) 2.4)) (snd-display #__line__ ";polynomial: ~A ~A ~A?" (polynomial v0 0.0) (polynomial v0 1.0) (polynomial v0 2.0)))) (if (fneq (polynomial (float-vector 0.0 2.0) 0.5) 1.0) (snd-display #__line__ ";polynomial 2.0 * 0.5: ~A" (polynomial (float-vector 2.0) 0.5))) (let ((var (catch #t (lambda () (polynomial #f 1.0)) (lambda args args)))) (if (not (eq? (car var) 'wrong-type-arg)) (snd-display #__line__ ";polynomial empty coeffs: ~A" var))) (do ((i 0 (+ i 1))) ((= i 100)) (let ((arg1 (- (random 100.0) 50.0)) (arg2 (- (random 100.0) 50.0))) (let ((val1 (modulo arg1 arg2)) (val2 (modulo arg1 arg2))) (if (and (> (abs (- val1 val2)) 1e-8) (> (abs (- (abs (- val1 val2)) (abs arg2))) 1e-8)) (snd-display #__line__ ";poly ~A ~A: ~A ~A -> ~A~%" arg1 arg2 val1 val2 (abs (- val1 val2))))))) (let ((err 0.0) (coeffs (float-vector 1.0 0.0 -.4999999963 0.0 .0416666418 0.0 -.0013888397 0.0 .0000247609 0.0 -.0000002605)) (pi2 (* pi 0.5))) (letrec ((new-cos (lambda (x) (let ((xx (abs x))) (if (<= xx pi2) (polynomial coeffs xx) (let ((nxx (modulo xx (* 2 pi)))) (if (<= nxx pi2) (polynomial coeffs nxx) (if (<= nxx pi) (- (polynomial coeffs (- pi nxx))) (if (< nxx (* 1.5 pi)) (- (polynomial coeffs (- nxx pi))) (polynomial coeffs (- (* 2 pi) nxx))))))))))) (do ((i 0 (+ i 1)) (x -10.0 (+ x .01))) ((= i 2000)) (let ((diff (abs (- (cos x) (new-cos x))))) (if (> diff err) (set! err diff)))) (if (> err 1.1e-7) (snd-display #__line__ ";new-cos poly err: ~A" err)))) (let ((val (poly+ (float-vector .1 .2 .3) (float-vector 0.0 1.0 2.0 3.0 4.0)))) (if (not (vequal val (float-vector 0.100 1.200 2.300 3.000 4.000))) (snd-display #__line__ ";poly+ 1: ~A" val))) (let ((val (poly+ (float-vector .1 .2 .3) .5))) (if (not (vequal val (float-vector 0.600 0.200 0.300))) (snd-display #__line__ ";poly+ 2: ~A" val))) (let ((val (poly+ .5 (float-vector .1 .2 .3)))) (if (not (vequal val (float-vector 0.600 0.200 0.300))) (snd-display #__line__ ";poly+ 3: ~A" val))) (let ((val (poly* (float-vector 1 1) (float-vector -1 1)))) (if (not (vequal val (float-vector -1.000 0.000 1.000 0.000))) (snd-display #__line__ ";poly* 1: ~A" val))) (let ((val (poly* (float-vector -5 1) (float-vector 3 7 2)))) (if (not (vequal val (float-vector -15.000 -32.000 -3.000 2.000 0.000))) (snd-display #__line__ ";poly* 2: ~A" val))) (let ((val (poly* (float-vector -30 -4 2) (float-vector 0.5 1)))) (if (not (vequal val (float-vector -15.000 -32.000 -3.000 2.000 0.000))) (snd-display #__line__ ";poly* 3: ~A" val))) (let ((val (poly* (float-vector -30 -4 2) 0.5))) (if (not (vequal val (float-vector -15.000 -2.000 1.000))) (snd-display #__line__ ";poly* 4: ~A" val))) (let ((val (poly* 2.0 (float-vector -30 -4 2)))) (if (not (vequal val (float-vector -60.000 -8.000 4.000))) (snd-display #__line__ ";poly* 5: ~A" val))) (let ((val (poly/ (float-vector -1.0 -0.0 1.0) (float-vector 1.0 1.0)))) (if (or (not (vequal (car val) (float-vector -1.000 1.000 0.000))) (not (vequal (cadr val) (float-vector 0.000 0.000 0.000)))) (snd-display #__line__ ";poly/ 1: ~A" val))) (let ((val (poly/ (float-vector -15 -32 -3 2) (float-vector -5 1)))) (if (or (not (vequal (car val) (float-vector 3.000 7.000 2.000 0.000))) (not (vequal (cadr val) (float-vector 0.000 0.000 0.000 0.000)))) (snd-display #__line__ ";poly/ 2: ~A" val))) (let ((val (poly/ (float-vector -15 -32 -3 2) (float-vector 3 1)))) (if (or (not (vequal (car val) (float-vector -5.000 -9.000 2.000 0.000))) (not (vequal (cadr val) (float-vector 0.000 0.000 0.000 0.000)))) (snd-display #__line__ ";poly/ 3: ~A" val))) (let ((val (poly/ (float-vector -15 -32 -3 2) (float-vector .5 1)))) (if (or (not (vequal (car val) (float-vector -30.000 -4.000 2.000 0.000))) (not (vequal (cadr val) (float-vector 0.000 0.000 0.000 0.000)))) (snd-display #__line__ ";poly/ 4: ~A" val))) (let ((val (poly/ (float-vector -15 -32 -3 2) (float-vector 3 7 2)))) (if (or (not (vequal (car val) (float-vector -5.000 1.000 0.000 0.000))) (not (vequal (cadr val) (float-vector 0.000 0.000 0.000 0.000)))) (snd-display #__line__ ";poly/ 5: ~A" val))) (let ((val (poly/ (float-vector -15 -32 -3 2) 2.0))) (if (not (vequal (car val) (float-vector -7.500 -16.000 -1.500 1.000))) (snd-display #__line__ ";poly/ 6: ~A" val))) (let ((val (poly/ (float-vector -1.0 0.0 0.0 0.0 1.0) (float-vector 1.0 0.0 1.0)))) (if (or (not (vequal (car val) (float-vector -1.0 0.0 1.0 0.0 0.0))) (not (vequal (cadr val) (make-float-vector 5)))) (snd-display #__line__ ";poly/ 7: ~A" val))) (let ((val (poly/ (float-vector -1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0) (float-vector 1.0 0.0 0.0 0.0 1.0)))) (if (or (not (vequal (car val) (float-vector -1.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0))) (not (vequal (cadr val) (make-float-vector 9)))) (snd-display #__line__ ";poly/ 8: ~A" val))) (let ((val (poly/ (float-vector -1.0 0.0 1.0) (float-vector -1.0 0.0 1.0)))) (if (or (not (vequal (car val) (float-vector 1.0 0.0 0.0))) (not (vequal (cadr val) (make-float-vector 3)))) (snd-display #__line__ ";poly/ 9: ~A" val))) (let ((val (poly/ (float-vector -1.0 0.0 1.0) (float-vector 2.0 1.0)))) (if (or (not (vequal (car val) (float-vector -2.000 1.000 0.000))) (not (vequal (cadr val) (float-vector 3.000 0.000 0.000)))) (snd-display #__line__ ";poly/ 10: ~A" val))) (let ((val (poly/ (float-vector 2 1) (float-vector -1.0 0.0 1.0)))) (if (or (not (vequal (car val) (float-vector 0.0))) (not (vequal (cadr val) (float-vector -1.000 0.000 1.000)))) (snd-display #__line__ ";poly/ 11: ~A" val))) (let ((val (poly/ (float-vector 1 2 3 0 1) (float-vector 0 0 0 1)))) (if (or (not (vequal (car val) (float-vector 0.000 1.000 0.000 0.000 0.000))) (not (vequal (cadr val) (float-vector 1.000 2.000 3.000 0.000 0.000)))) (snd-display #__line__ ";poly/ 12: ~A" val))) (let ((ind (open-sound "1a.snd"))) (let ((v1 (channel->float-vector 0 100 ind 0)) (v2 (channel->float-vector 0 100 ind 0))) (let ((vals (car (poly/ v1 v2))) (res (make-float-vector 100))) (set! (res 0) 1.0) (if (not (vequal vals res)) (snd-display #__line__ ";poly1 1a: ~A" vals)))) (close-sound ind)) (let ((val (poly-derivative (float-vector 0.5 1.0 2.0 4.0)))) (if (not (vequal val (float-vector 1.000 4.000 12.000))) (snd-display #__line__ ";poly-derivative: ~A" val))) (let ((val (poly-reduce (float-vector 1 2 3)))) (if (not (vequal val (float-vector 1.000 2.000 3.000))) (snd-display #__line__ ";poly-reduce 1: ~A" val))) (let ((val (poly-reduce (float-vector 1 2 3 0 0 0)))) (if (not (vequal val (float-vector 1.000 2.000 3.000))) (snd-display #__line__ ";poly-reduce 2: ~A" val))) (let ((val (poly-reduce (float-vector 0 0 0 0 1 0)))) (if (not (vequal val (float-vector 0.000 0.000 0.000 0.000 1.000))) (snd-display #__line__ ";poly-reduce 3: ~A" val))) (let ((vals (poly-gcd (poly-reduce (poly* (float-vector 2 1) (float-vector -3 1))) (float-vector 2 1)))) (if (not (vequal vals (float-vector 2.000 1.000))) (snd-display #__line__ ";poly-gcd 1: ~A" vals))) (let ((vals (poly-gcd (poly-reduce (poly* (float-vector 2 1) (float-vector -3 1))) (float-vector 3 1)))) (if (not (vequal vals (float-vector 0.000))) (snd-display #__line__ ";poly-gcd 2: ~A" vals))) (let ((vals (poly-gcd (poly-reduce (poly* (float-vector 2 1) (float-vector -3 1))) (float-vector -3 1)))) (if (not (vequal vals (float-vector -3.000 1.000))) (snd-display #__line__ ";poly-gcd 2: ~A" vals))) (let ((vals (poly-gcd (poly-reduce (poly* (float-vector 8 1) (poly* (float-vector 2 1) (float-vector -3 1)))) (float-vector -3 1)))) (if (not (vequal vals (float-vector -3.000 1.000))) (snd-display #__line__ ";poly-gcd 3: ~A" vals))) (let ((vals (poly-gcd (poly-reduce (poly* (float-vector 8 1) (poly* (float-vector 2 1) (float-vector -3 1)))) (poly-reduce (poly* (float-vector 8 1) (float-vector -3 1)))))) (if (not (vequal vals (float-vector -24.000 5.000 1.000))) (snd-display #__line__ ";poly-gcd 4: ~A" vals))) (let ((vals (poly-gcd (float-vector -1 0 1) (float-vector 2 -2 -1 1)))) (if (not (vequal vals (float-vector 0.000))) (snd-display #__line__ ";poly-gcd 5: ~A" vals))) (let ((vals (poly-gcd (float-vector 2 -2 -1 1) (float-vector -1 0 1)))) (if (not (vequal vals (float-vector 1.000 -1.000))) (snd-display #__line__ ";poly-gcd 6: ~A" vals))) (let ((vals (poly-gcd (float-vector 2 -2 -1 1) (float-vector -2.5 1)))) (if (not (vequal vals (float-vector 0.000))) (snd-display #__line__ ";poly-gcd 7: ~A" vals))) (poly-roots-tests) (let ((val (poly-as-vector-resultant (vector -1 0 1) (vector 1 -2 1)))) (if (fneq val 0.0) (snd-display #__line__ ";poly-resultant 0: ~A" val))) (let ((val (poly-as-vector-resultant (vector -1 0 2) (vector 1 -2 1)))) (if (fneq val 1.0) (snd-display #__line__ ";poly-resultant 1: ~A" val))) (let ((val (poly-as-vector-resultant (vector -1 0 1) (vector 1 1)))) (if (fneq val 0.0) (snd-display #__line__ ";poly-resultant 2: ~A" val))) (let ((val (poly-as-vector-resultant (vector -1 0 1) (vector 2 1)))) (if (fneq val 3.0) (snd-display #__line__ ";poly-resultant 3: ~A" val))) (let ((val (poly-resultant (float-vector -1 0 1) (float-vector 1 -2 1)))) (if (fneq val 0.0) (snd-display #__line__ ";poly-resultant 0: ~A" val))) (let ((val (poly-as-vector-discriminant (vector -1 0 1)))) (if (fneq val -4.0) (snd-display #__line__ ";poly-discriminant 0: ~A" val))) (let ((val (poly-as-vector-discriminant (vector 1 -2 1)))) (if (fneq val 0.0) (snd-display #__line__ ";poly-discriminant 1: ~A" val))) (let ((val (poly-discriminant (poly-reduce (poly* (poly* (float-vector -1 1) (float-vector -1 1)) (float-vector 3 1)))))) (if (fneq val 0.0) (snd-display #__line__ ";poly-discriminant 2: ~A" val))) (let ((val (poly-discriminant (poly-reduce (poly* (poly* (poly* (float-vector -1 1) (float-vector -1 1)) (float-vector 3 1)) (float-vector 2 1)))))) (if (fneq val 0.0) (snd-display #__line__ ";poly-discriminant 3: ~A" val))) (let ((val (poly-discriminant (poly-reduce (poly* (poly* (poly* (float-vector 1 1) (float-vector -1 1)) (float-vector 3 1)) (float-vector 2 1)))))) (if (fneq val 2304.0) (snd-display #__line__ ";poly-discriminant 4: ~A" val))) (let ((val (poly-discriminant (poly-reduce (poly* (poly* (poly* (float-vector 1 1) (float-vector -1 1)) (float-vector 3 1)) (float-vector 3 1)))))) (if (fneq val 0.0) (snd-display #__line__ ";poly-discriminant 5: ~A" val))) (let ((v0 (make-float-vector 10))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v0 i) i)) (if (fneq (array-interp v0 3.5) 3.5) (snd-display #__line__ ";array-interp: ~F?" (array-interp v0 3.5))) (if (fneq (array-interp v0 13.5) 3.5) (snd-display #__line__ ";array-interp(13.5): ~F?" (array-interp v0 13.5))) (if (fneq (array-interp v0 -6.5) 3.5) (snd-display #__line__ ";array-interp(-6.5): ~F?" (array-interp v0 -6.5))) (if (fneq (array-interp v0 103.6) 3.6) (snd-display #__line__ ";array-interp(103.5): ~F?" (array-interp v0 103.6))) (if (fneq (array-interp v0 -106.6) 3.4) (snd-display #__line__ ";array-interp(-106.6): ~F?" (array-interp v0 -106.6))) (if (fneq (array-interp v0 -0.5) 4.5) (snd-display #__line__ ";array-interp(-0.5): ~F?" (array-interp v0 -0.5))) ;; interpolating between 9 and 0 here (confusing...) (if (fneq (array-interp v0 -0.9) 8.1) (snd-display #__line__ ";array-interp(-0.9): ~F?" (array-interp v0 -0.9))) (if (fneq (array-interp v0 -0.1) 0.9) (snd-display #__line__ ";array-interp(-0.1): ~F?" (array-interp v0 -0.1))) (if (fneq (array-interp v0 9.1) 8.1) (snd-display #__line__ ";array-interp(9.1): ~F?" (array-interp v0 9.1))) (if (fneq (array-interp v0 9.9) 0.9) (snd-display #__line__ ";array-interp(9.9): ~F?" (array-interp v0 9.9))) (if (fneq (array-interp v0 10.1) 0.1) (snd-display #__line__ ";array-interp(10.1): ~F?" (array-interp v0 10.1))) (let ((var (catch #t (lambda () (array-interp v0 1 -10)) (lambda args args)))) (if (not (eq? (car var) 'out-of-range)) (snd-display #__line__ ";array-interp bad index: ~A" var)))) (let ((ind (open-sound "oboe.snd"))) (let ((diff (array-interp-sound-diff ind 0))) (if (> diff .00001) (snd-display #__line__ ";array-interp-sound-diff: ~A" diff))) (close-sound ind)) (let ((v0 (make-float-vector 10))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v0 i) i)) (let ((val (mus-interpolate mus-interp-linear 1.5 v0))) (if (fneq val 1.5) (snd-display #__line__ ";mus-interpolate linear: ~A" val)) (set! val (mus-interpolate mus-interp-all-pass 1.5 v0)) (if (fneq val 1.5) (snd-display #__line__ ";mus-interpolate all-pass: ~A" val)) (set! val (mus-interpolate mus-interp-none 1.5 v0)) (if (fneq val 1.0) (snd-display #__line__ ";mus-interpolate none: ~A" val)) (set! val (mus-interpolate mus-interp-hermite 1.5 v0)) (if (fneq val 1.5) (snd-display #__line__ ";mus-interpolate hermite: ~A" val)) (set! val (mus-interpolate mus-interp-bezier 1.5 v0)) (if (fneq val 1.5) (snd-display #__line__ ";mus-interpolate bezier: ~A" val)) (set! val (mus-interpolate mus-interp-lagrange 1.5 v0)) (if (fneq val 1.5) (snd-display #__line__ ";mus-interpolate lagrange: ~A" val)) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v0 i) (sin (* pi (/ i 5))))) (set! val (mus-interpolate mus-interp-linear 1.5 v0)) (if (fneq val 0.7694) (snd-display #__line__ ";mus-interpolate linear sin: ~A" val)) (set! val (mus-interpolate mus-interp-all-pass 1.5 v0)) (if (fneq val 0.7694) (snd-display #__line__ ";mus-interpolate all-pass sin: ~A" val)) (set! val (mus-interpolate mus-interp-none 1.5 v0)) (if (fneq val 0.5877) (snd-display #__line__ ";mus-interpolate none sin: ~A" val)) (set! val (mus-interpolate mus-interp-hermite 1.5 v0)) (if (fneq val 0.8061) (snd-display #__line__ ";mus-interpolate hermite sin: ~A" val)) (set! val (mus-interpolate mus-interp-bezier 1.5 v0)) (if (fneq val 0.6959) (snd-display #__line__ ";mus-interpolate bezier sin: ~A" val)) (set! val (mus-interpolate mus-interp-lagrange 1.5 v0)) (if (fneq val 0.7975) (snd-display #__line__ ";mus-interpolate lagrange sin: ~A" val)))) (let ((tag (catch #t (lambda () (mus-interpolate 1234 1.0 (make-float-vector 3))) (lambda args (car args))))) (if (not (eq? tag 'out-of-range)) (snd-display #__line__ ";mus-interpolate 1234: ~A" tag))) (let ((tag (catch #t (lambda () (mus-interpolate mus-interp-linear 1.0 (make-float-vector 3) -1)) (lambda args (car args))))) (if (not (eq? tag 'out-of-range)) (snd-display #__line__ ";mus-interpolate size -1: ~A" tag))) (let ((gen (make-delay 3)) (gen2 (make-delay 3)) (gen1 (make-delay 4 :initial-contents '(1.0 0.5 0.25 0.0))) (gen3 (make-delay 4 :initial-contents (float-vector 1.0 0.5 0.25 0.0))) (v0 (make-float-vector 10)) (v1 (make-float-vector 10))) (print-and-check gen "delay" "delay line[3, step]: [0 0 0]") (do ((i 0 (+ i 1))) ((= i 10)) (set! (v0 i) (delay gen i))) (let ((k 0)) (fill-float-vector v1 (let ((val (if (delay? gen2) (delay gen2 k) -1.0))) (set! k (+ k 1)) val))) (if (not (vequal v1 v0)) (snd-display #__line__ ";map delay: ~A ~A" v0 v1)) (if (not (delay? gen)) (snd-display #__line__ ";~A not delay?" gen)) (if (not (= (mus-length gen) 3)) (snd-display #__line__ ";delay length: ~D?" (mus-length gen))) (if (or (fneq (v0 1) 0.0) (fneq (v0 4) 1.0) (fneq (v0 8) 5.0)) (snd-display #__line__ ";delay output: ~A" v0)) (if (or (fneq (delay gen1) 1.0) (fneq (delay gen1) 0.5) (fneq (delay gen1) 0.25) (fneq (delay gen1) 0.0) (fneq (delay gen1) 0.0)) (snd-display #__line__ ";delay with list initial-contents confused")) (if (or (fneq (delay gen3) 1.0) (fneq (delay gen3) 0.5) (fneq (delay gen3) 0.25) (fneq (delay gen3) 0.0) (fneq (delay gen3) 0.0)) (snd-display #__line__ ";delay with float-vector initial-contents confused")) (let ((var (catch #t (lambda () (make-delay :size #f)) (lambda args args)))) (if (not (eq? (car var) 'wrong-type-arg)) (snd-display #__line__ ";make-delay bad size #f: ~A" var))) (let ((var (catch #t (lambda () (make-delay 3 :initial-element (make-oscil))) (lambda args args)))) (if (not (eq? (car var) 'wrong-type-arg)) (snd-display #__line__ ";make-delay bad initial element: ~A" var))) (let ((var (catch #t (lambda () (make-delay -3)) (lambda args args)))) (if (not (eq? (car var) 'out-of-range)) (snd-display #__line__ ";make-delay bad size: ~A" var)))) (test-gen-equal (let ((d1 (make-delay 3))) (delay d1 1.0) d1) (let ((d2 (make-delay 3))) (delay d2 1.0) d2) (let ((d3 (make-delay 4))) (delay d3 1.0) d3)) (test-gen-equal (make-delay 3 :initial-element 1.0) (make-delay 3 :initial-element 1.0) (make-delay 3 :initial-element 0.5)) (test-gen-equal (make-delay 3 :initial-contents '(1.0 0.0 0.0)) (make-delay 3 :initial-contents '(1.0 0.0 0.0)) (make-delay 3 :initial-contents '(1.0 1.0 1.0))) (let ((gen (make-delay 5))) (delay gen 1.0) (delay gen 0.0) (delay gen 0.5) (let ((data (copy (mus-data gen)))) (float-vector-set! (mus-data gen) 0 0.3) (if (fneq ((mus-data gen) 0) 0.3) (snd-display #__line__ ";delay data 0: ~A" ((mus-data gen) 0))) (set! (data 0) .75) (set! (mus-data gen) data) (if (fneq ((mus-data gen) 0) 0.75) (snd-display #__line__ ";delay set data 0: ~A" ((mus-data gen) 0))) (delay gen 0.0) (delay gen 0.0) (let ((val (delay gen 0.0))) (if (fneq val 0.75) (snd-display #__line__ ";set delay data: ~A ~A" val (mus-data gen))))) (if (mus-data (make-oscil)) (snd-display #__line__ ";mus-data osc: ~A" (mus-data (make-oscil))))) (let ((del (make-delay 5 :max-size 8))) (delay del 1.0) (do ((i 0 (+ i 1))) ((= i 4)) (delay del 0.0)) (let ((v0 (make-float-vector 5))) (do ((i 0 (+ i 1))) ((= i 5)) (set! (v0 i) (delay del 0.0 0.4))) (if (not (vequal v0 (float-vector 0.600 0.400 0.000 0.000 0.000))) (snd-display #__line__ ";zdelay: ~A" v0)) (delay del 1.0) (delay del 0.0 0.4) (if (not (string=? (mus-describe del) "delay line[5,8, linear]: [0 0 1 0 0]")) (snd-display #__line__ ";describe zdelay: ~A" (mus-describe del))))) (let ((tag (catch #t (lambda () (let ((gen (make-oscil))) (tap gen))) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";tap of oscil: ~A" tag))) (let ((dly (make-delay 3)) (flt (make-one-zero .5 .4)) (v (make-float-vector 20)) (inval 1.0)) (fill-float-vector v (let ((res (delay dly (+ inval (* (one-zero flt (tap dly)) .6))))) (set! inval 0.0) res)) (if (not (vequal v (float-vector 0.0 0.0 0.0 1.0 0.0 0.0 0.300 0.240 0.0 0.090 0.144 0.058 0.027 0.065 0.052 0.022 0.026 0.031 0.019 0.013))) (snd-display #__line__ ";tap with low pass: ~A" v))) (let ((dly (make-delay 3)) (v (make-float-vector 20)) (inval 1.0)) (fill-float-vector v (let ((res (delay dly (+ inval (tap dly))))) (set! inval 0.0) res)) (if (not (vequal v (float-vector 0.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0))) (snd-display #__line__ ";simple tap: ~A" v))) (let ((dly (make-delay 6)) (v (make-float-vector 20)) (inval 1.0)) (if (not (tap? dly)) (snd-display #__line__ ";tap?: ~A" (tap? dly))) (fill-float-vector v (let ((res (delay dly (+ inval (tap dly -2.0))))) (set! inval 0.0) res)) (set! *print-length* (max 20 *print-length*)) (if (not (vequal v (float-vector 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 1.0 0.0))) (snd-display #__line__ ";tap back 2: ~A" v))) (let ((dly (make-delay 3)) (flt (make-one-zero .5 .4)) (v (make-float-vector 20)) (inval 1.0)) (do ((i 0 (+ i 1))) ((= i 20)) (set! (v i) (let ((res (delay dly (+ inval (* (one-zero flt (tap dly)) .6))))) (set! inval 0.0) res))) (if (not (vequal v (float-vector 0.0 0.0 0.0 1.0 0.0 0.0 0.300 0.240 0.0 0.090 0.144 0.058 0.027 0.065 0.052 0.022 0.026 0.031 0.019 0.013))) (snd-display #__line__ ";tap with low pass: ~A" v))) (let ((dly (make-delay 3 :initial-element 32.0))) (if (not (float-vector? (mus-data dly))) (snd-display #__line__ ";delay data not float-vector?") (if (not (= (length (mus-data dly)) 3)) (snd-display #__line__ ";delay data len not 3: ~A (~A)" (length (mus-data dly)) (mus-data dly)) (if (fneq ((mus-data dly) 1) 32.0) (snd-display #__line__ ";delay [1] 32: ~A" ((mus-data dly) 1))))) (let ((tag (catch #t (lambda () (set! (mus-length dly) -1)) (lambda args (car args))))) (if (not (eq? tag 'out-of-range)) (snd-display #__line__ ";len to -1 -> ~A" tag))) (let ((tag (catch #t (lambda () (set! (mus-length dly) 0)) (lambda args (car args))))) (if (not (eq? tag 'out-of-range)) (snd-display #__line__ ";len to 0 -> ~A" tag))) (let ((tag (catch #t (lambda () (set! (mus-length dly) 100)) (lambda args (car args))))) (if (not (eq? tag 'out-of-range)) (snd-display #__line__ ";len to 100 -> ~A" tag))) (let ((tag (catch #t (lambda () (set! ((mus-data dly) 100) .1)) (lambda args (car args))))) (if (not (eq? tag 'out-of-range)) (snd-display #__line__ ";data 100 to .1 -> ~A" tag))) (let ((data (make-float-vector 32 1.0))) (set! (mus-data dly) data) (if (not (float-vector? (mus-data dly))) (snd-display #__line__ ";set delay data not float-vector?")) (if (fneq ((mus-data dly) 1) 1.0) (snd-display #__line__ ";set delay [1] 1: ~A" ((mus-data dly) 1))) (if (not (= (length (mus-data dly)) 32)) (snd-display #__line__ ";set delay data len(32): ~A" (length (mus-data dly)))) (let ((tag (catch #t (lambda () (set! (mus-length dly) 100)) (lambda args (car args))))) (if (not (eq? tag 'out-of-range)) (snd-display #__line__ ";set len to 100 -> ~A" tag))) (let ((tag (catch #t (lambda () (set! ((mus-data dly) 100) .1)) (lambda args (car args))))) (if (not (eq? tag 'out-of-range)) (snd-display #__line__ ";set data 100 to .1 -> ~A" tag))))) (let ((d1 (make-delay 4)) (d2 (make-delay 4 :max-size 5 :type mus-interp-linear)) (d3 (make-delay 4 :max-size 5 :type mus-interp-all-pass)) (d4 (make-delay 4 :max-size 5 :type mus-interp-none)) (d5 (make-delay 4 :max-size 4 :type mus-interp-lagrange)) (d6 (make-delay 4 :max-size 4 :type mus-interp-hermite)) (d7 (make-delay 4 :max-size 4 :type mus-interp-linear)) (v1 (make-float-vector 20)) (v2 (make-float-vector 20)) (v3 (make-float-vector 20)) (v4 (make-float-vector 20)) (v5 (make-float-vector 20)) (v6 (make-float-vector 20)) (v7 (make-float-vector 20))) (if (not (= (mus-interp-type d1) mus-interp-none)) (snd-display #__line__ ";d1 interp type: ~A" (mus-interp-type d1))) (if (not (= (mus-interp-type d2) mus-interp-linear)) (snd-display #__line__ ";d2 interp type: ~A" (mus-interp-type d2))) (if (not (= (mus-interp-type d3) mus-interp-all-pass)) (snd-display #__line__ ";d3 interp type: ~A" (mus-interp-type d3))) (if (not (= (mus-interp-type d4) mus-interp-none)) (snd-display #__line__ ";d4 interp type: ~A" (mus-interp-type d4))) (if (not (= (mus-interp-type d5) mus-interp-lagrange)) (snd-display #__line__ ";d5 interp type: ~A" (mus-interp-type d5))) (if (not (= (mus-interp-type d6) mus-interp-hermite)) (snd-display #__line__ ";d6 interp type: ~A" (mus-interp-type d6))) (if (not (= (mus-interp-type d7) mus-interp-linear)) (snd-display #__line__ ";d7 interp type: ~A" (mus-interp-type d7))) (set! (v1 0) (delay d1 1.0)) (set! (v2 0) (delay d2 1.0)) (set! (v3 0) (delay d3 1.0)) (set! (v4 0) (delay d4 1.0)) (set! (v5 0) (delay d5 1.0)) (set! (v6 0) (delay d6 1.0)) (set! (v7 0) (delay d7 1.0)) (delay-tick d1 0.0) (delay-tick d2 0.0) (delay-tick d3 0.0) (delay-tick d4 0.0) (delay-tick d5 0.0) (delay-tick d6 0.0) (delay-tick d7 0.0) (do ((i 1 (+ i 1)) (j -0.2 (- j 0.2))) ((= i 20)) (set! (v1 i) (tap d1 j)) (set! (v2 i) (tap d2 j)) (set! (v3 i) (tap d3 j)) (set! (v4 i) (tap d4 j)) (set! (v5 i) (tap d5 j)) (set! (v6 i) (tap d6 j)) (set! (v7 i) (tap d7 j))) (set! *print-length* (max 20 *print-length*)) (if (and (not (vequal v1 (float-vector 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 1.0 1.0 1.0 1.0 0.0 0.0 0.0 0.0 0.0))) (not (vequal v1 (float-vector 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 1.0 1.0 1.0 0.0 0.0 0.0 0.0 0.0)))) (snd-display #__line__ ";delay interp none (1): ~A" v1)) (if (not (vequal v2 (float-vector 0.0 0.0 0.0 0.0 0.0 0.0 0.200 0.400 0.600 0.800 1.0 0.800 0.600 0.400 0.200 0.0 0.0 0.0 0.0 0.0))) (snd-display #__line__ ";delay interp linear (2): ~A" v2)) (if (not (vequal v3 (float-vector 0.000 0.000 0.000 0.000 0.000 1.000 0.000 0.600 0.160 0.168 -0.168 0.334 0.199 0.520 0.696 -0.696 0.557 -0.334 0.134 -0.027))) (snd-display #__line__ ";delay interp all-pass (3): ~A" v3)) (if (and (not (vequal v4 (float-vector 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 1.0 1.0 1.0 1.0 0.0 0.0 0.0 0.0 0.0))) (not (vequal v4 (float-vector 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 1.0 1.0 1.0 0.0 0.0 0.0 0.0 0.0)))) (snd-display #__line__ ";delay interp none (4): ~A" v4)) (if (not (vequal v5 (float-vector 0.0 0.0 0.0 0.0 0.0 0.0 0.120 0.280 0.480 0.720 1.000 0.960 0.840 0.640 0.360 0.000 -0.080 -0.120 -0.120 -0.080))) (snd-display #__line__ ";delay interp lagrange (5): ~A" v5)) (if (not (vequal v6 (float-vector 0.0 -0.016 -0.048 -0.072 -0.064 0.0 0.168 0.424 0.696 0.912 1.0 0.912 0.696 0.424 0.168 0.0 -0.064 -0.072 -0.048 -0.016))) (snd-display #__line__ ";delay interp hermite (6): ~A" v6)) (if (not (vequal v7 (float-vector 0.0 0.0 0.0 0.0 0.0 0.0 0.200 0.400 0.600 0.800 1.0 0.800 0.600 0.400 0.200 0.0 0.0 0.0 0.0 0.0))) (snd-display #__line__ ";delay interp linear (7): ~A" v7))) (let ((dly1 (make-delay :size 2 :max-size 3)) (data (make-float-vector 5)) (impulse 1.0)) (do ((i 0 (+ i 1))) ((= i 5)) (set! (data i) (delay dly1 impulse 0.4)) ; longer line (set! impulse 0.0)) (if (not (vequal data (float-vector 0.0 0.0 0.6 0.4 0.0))) (snd-display #__line__ ";delay size 2, max 3, off 0.4: ~A" data)) (set! dly1 (make-delay :size 2 :max-size 3)) (set! impulse 1.0) (do ((i 0 (+ i 1))) ((= i 5)) (set! (data i) (delay dly1 impulse -0.4)) ; shorter line (set! impulse 0.0)) (if (not (vequal data (float-vector 0.0 0.4 0.6 0.0 0.0))) (snd-display #__line__ ";delay size 2, max 3, off -0.4: ~A" data)) (set! dly1 (make-delay :size 1 :max-size 2)) (set! impulse 1.0) (do ((i 0 (+ i 1))) ((= i 5)) (set! (data i) (delay dly1 impulse 0.4)) (set! impulse 0.0)) (if (not (vequal data (float-vector 0.0 0.6 0.4 0.0 0.0))) (snd-display #__line__ ";delay size 1, max 2, off 0.4: ~A" data)) (set! dly1 (make-delay :size 0 :max-size 1)) (set! impulse 1.0) (do ((i 0 (+ i 1))) ((= i 5)) (set! (data i) (delay dly1 impulse 0.4)) (set! impulse 0.0)) (if (not (vequal data (float-vector 0.6 0.4 0.0 0.0 0.0))) (snd-display #__line__ ";delay size 0, max 1, off 0.4: ~A" data)) (set! dly1 (make-delay :size 0 :max-size 1)) (let ((val (delay dly1 0.0))) (if (fneq val 0.0) (snd-display #__line__ ";initial delay 0 size val: ~A" val))) (set! dly1 (make-delay :size 0 :max-size 1)) (set! impulse 1.0) (do ((i 0 (+ i 1))) ((= i 5)) (set! (data i) (delay dly1 impulse -0.4)) ; shorter than 0? should this be an error? (set! impulse 0.0)) (if (not (vequal data (float-vector 1.4 -0.4 0.0 0.0 0.0))) ; hmmm -- they're asking for undefined values here (snd-display #__line__ ";delay size 0, max 1, off -0.4: ~A" data)) (set! dly1 (make-delay 0)) (set! impulse 1.0) (do ((i 0 (+ i 1))) ((= i 5)) (set! (data i) (delay dly1 impulse)) (set! impulse 0.0)) (if (not (vequal data (float-vector 1 0 0 0 0))) (snd-display #__line__ ";delay size 0: ~A" data)) (let ((x (delay dly1 0.5))) (if (fneq x 0.5) (snd-display #__line__ ";delay size 0 0.5: ~A" x))) ) (let ((gen (make-delay :size 0 :max-size 100)) (v (make-float-vector 10))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v i) (delay gen 0.5 i))) (if (not (vequal v (float-vector 0.500 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";delay 0 -> 100: ~A" v)) (do ((i 9 (- i 1))) ((< i 0)) (set! (v i) (delay gen 0.5 i))) (if (not (vequal v (float-vector 0.500 0.500 0.500 0.500 0.500 0.500 0.500 0.500 0.500 0.500))) (snd-display #__line__ ";delay 100 -> 0: ~A" v)) (mus-reset gen) (if (not (vequal (mus-data gen) (make-float-vector 100 0.0))) (snd-display #__line__ ";after reset mus-data delay peak: ~A" (float-vector-peak (mus-data gen)))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v i) (delay gen (if (odd? i) 1.0 0.0) (* i .1)))) (if (not (vequal v (float-vector 0.000 0.900 0.000 0.700 0.000 0.500 0.000 0.300 0.000 0.100))) (snd-display #__line__ ";delay 0 -> 100 .1: ~A (~A)" v gen)) (mus-reset gen) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v i) (delay gen (if (odd? i) 1.0 0.0) (+ 1.0 (* i .1))))) (if (not (vequal v (float-vector 0.000 0.000 0.800 0.300 0.600 0.500 0.400 0.700 0.200 0.900))) (snd-display #__line__ ";delay 0 -> 100 1.1: ~A" v))) (let ((gen (make-all-pass .4 .6 3)) (v0 (make-float-vector 10)) (gen1 (make-all-pass .4 .6 3)) (v1 (make-float-vector 10))) (print-and-check gen "all-pass" "all-pass feedback: 0.400, feedforward: 0.600, line[3, step]:[0 0 0]") (do ((i 0 (+ i 1))) ((= i 10)) (set! (v0 i) (all-pass gen 1.0))) (fill-float-vector v1 (if (all-pass? gen1) (all-pass gen1 1.0) -1.0)) (if (not (vequal v1 v0)) (snd-display #__line__ ";map all-pass: ~A ~A" v0 v1)) (if (not (all-pass? gen)) (snd-display #__line__ ";~A not all-pass?" gen)) (if (not (= (mus-length gen) 3)) (snd-display #__line__ ";all-pass length: ~D?" (mus-length gen))) (if (not (= (mus-order gen) 3)) (snd-display #__line__ ";all-pass order: ~D?" (mus-order gen))) (if (fneq (mus-feedback gen) .4) (snd-display #__line__ ";all-pass feedback: ~F?" (mus-feedback gen))) (if (fneq (mus-feedforward gen) .6) (snd-display #__line__ ";all-pass feedforward: ~F?" (mus-feedforward gen))) (if (or (fneq (v0 1) 0.6) (fneq (v0 4) 1.84) (fneq (v0 8) 2.336)) (snd-display #__line__ ";all-pass output: ~A" v0)) (set! (mus-feedback gen) 0.5) (if (fneq (mus-feedback gen) .5) (snd-display #__line__ ";all-pass set-feedback: ~F?" (mus-feedback gen))) (set! (mus-feedforward gen) 0.5) (if (fneq (mus-feedforward gen) .5) (snd-display #__line__ ";all-pass set-feedforward: ~F?" (mus-feedforward gen)))) (test-gen-equal (let ((d1 (make-all-pass 0.7 0.5 3))) (all-pass d1 1.0) d1) (let ((d2 (make-all-pass 0.7 0.5 3))) (all-pass d2 1.0) d2) (let ((d3 (make-all-pass 0.7 0.5 4))) (all-pass d3 1.0) d3)) (test-gen-equal (make-all-pass 0.7 0.5 3 :initial-element 1.0) (make-all-pass 0.7 0.5 3 :initial-element 1.0) (make-all-pass 0.7 0.5 3 :initial-element 0.5)) (test-gen-equal (make-all-pass 0.7 0.5 3 :initial-element 1.0) (make-all-pass 0.7 0.5 3 :initial-element 1.0) (make-all-pass 0.5 0.5 3 :initial-element 1.0)) (test-gen-equal (make-all-pass 0.7 0.5 3 :initial-contents '(1.0 0.0 0.0)) (make-all-pass 0.7 0.5 3 :initial-contents '(1.0 0.0 0.0)) (make-all-pass 0.7 0.5 3 :initial-contents '(1.0 1.0 1.0))) (let ((err (catch #t (lambda () (make-all-pass :feedback .2 :feedforward .1 :size -1)) (lambda args args)))) (if (not (eq? (car err) 'out-of-range)) (snd-display #__line__ ";make-all-pass bad size error message: ~A" err))) (let ((gen (make-moving-average 4)) (v0 (make-float-vector 10)) (gen1 (make-moving-average 4)) (v1 (make-float-vector 10))) (print-and-check gen "moving-average" "moving-average 0.000, line[4]:[0 0 0 0]") (do ((i 0 (+ i 1))) ((= i 10)) (set! (v0 i) (moving-average gen 1.0))) (fill-float-vector v1 (if (moving-average? gen1) (moving-average gen1 1.0) -1.0)) (if (not (vequal v1 v0)) (snd-display #__line__ ";map average: ~A ~A" v0 v1)) (if (not (moving-average? gen)) (snd-display #__line__ ";~A not average?" gen)) (if (not (= (mus-length gen) 4)) (snd-display #__line__ ";average length: ~D?" (mus-length gen))) (if (not (= (mus-order gen) 4)) (snd-display #__line__ ";average order: ~D?" (mus-order gen))) (if (or (fneq (v0 1) 0.5) (fneq (v0 4) 1.0) (fneq (v0 8) 1.0)) (snd-display #__line__ ";average output: ~A" v0))) (let* ((gen (make-moving-average 8)) (val (moving-average gen))) (if (fneq val 0.0) (snd-display #__line__ ";empty average: ~A" val)) (set! val (moving-average gen 1.0)) (if (fneq val 0.125) (snd-display #__line__ ";average 1: ~A" val)) (set! val (moving-average gen 1.0)) (if (fneq val 0.25) (snd-display #__line__ ";average 2: ~A" val)) (set! val (moving-average gen 0.5)) (if (fneq val 0.3125) (snd-display #__line__ ";average 2: ~A" val)) (do ((i 0 (+ i 1))) ((= i 5)) (set! val (moving-average gen 0.0))) (if (fneq val 0.3125) (snd-display #__line__ ";average 6: ~A" val)) (set! val (moving-average gen 0.0)) (if (fneq val 0.1875) (snd-display #__line__ ";average 7: ~A" val)) (set! val (moving-average gen 0.0)) (if (fneq val 0.0625) (snd-display #__line__ ";average 8: ~A" val)) (set! val (moving-average gen 0.0)) (if (fneq val 0.0) (snd-display #__line__ ";average 9: ~A" val)) ) (let* ((gen (make-moving-average 10 :initial-element .5)) (val (moving-average gen 0.5))) (if (fneq val 0.5) (snd-display #__line__ ";average initial-element: ~A" val))) (let* ((gen (make-moving-average 3 :initial-contents '(1.0 1.0 1.0))) (val (moving-average gen 1.0))) (if (fneq val 1.0) (snd-display #__line__ ";average initial-contents: ~A" val))) (test-gen-equal (let ((d1 (make-moving-average 3 :initial-contents '(0.7 0.5 3)))) (moving-average d1 1.0) d1) (let ((d2 (make-moving-average 3 :initial-contents (float-vector 0.7 0.5 3)))) (moving-average d2 1.0) d2) (let ((d3 (make-moving-average 4 :initial-contents '(0.7 0.5 0.1 4)))) (moving-average d3 1.0) d3)) (test-gen-equal (make-moving-average 3 :initial-element 1.0) (make-moving-average 3 :initial-element 1.0) (make-moving-average 3 :initial-element 0.5)) (test-gen-equal (make-moving-average 3 :initial-element 1.0) (make-moving-average 3 :initial-element 1.0) (make-moving-average 4 :initial-element 1.0)) (test-gen-equal (make-moving-average 3 :initial-contents '(1.0 0.0 0.0)) (make-moving-average 3 :initial-contents '(1.0 0.0 0.0)) (make-moving-average 3 :initial-contents '(1.0 1.0 1.0))) (let ((err (catch #t (lambda () (make-moving-average :size -1)) (lambda args args)))) (if (not (eq? (car err) 'out-of-range)) (snd-display #__line__ ";make-average bad size error message: ~A" err))) (let ((err (catch #t (lambda () (make-moving-average :size 0)) (lambda args args)))) (if (not (eq? (car err) 'out-of-range)) (snd-display #__line__ ";make-average size==0 error message: ~A" err))) (let ((gen (make-moving-max 4)) (v0 (make-float-vector 10)) (gen1 (make-moving-max 4)) (v1 (make-float-vector 10))) (print-and-check gen "moving-max" "moving-max 0.000, line[4]:[0 0 0 0]") (do ((i 0 (+ i 1))) ((= i 10)) (set! (v0 i) (moving-max gen 1.0))) (fill-float-vector v1 (if (moving-max? gen1) (moving-max gen1 1.0) -1.0)) (if (not (vequal v1 v0)) (snd-display #__line__ ";map max: ~A ~A" v0 v1)) (if (not (moving-max? gen)) (snd-display #__line__ ";~A not max?" gen)) (if (not (= (mus-length gen) 4)) (snd-display #__line__ ";max length: ~D?" (mus-length gen))) (if (not (= (mus-order gen) 4)) (snd-display #__line__ ";max order: ~D?" (mus-order gen))) (if (or (fneq (v0 1) 1.0) (fneq (v0 4) 1.0) (fneq (v0 8) 1.0)) (snd-display #__line__ ";max output: ~A" v0))) (let* ((gen (make-moving-max 8)) (val (moving-max gen))) (if (fneq val 0.0) (snd-display #__line__ ";empty max: ~A" val)) (set! val (moving-max gen 1.0)) (if (fneq val 1.0) (snd-display #__line__ ";max 1: ~A" val)) (set! val (moving-max gen -0.5)) (if (fneq val 1.0) (snd-display #__line__ ";max 2: ~A" val)) (set! val (moving-max gen -1.5)) (if (fneq val 1.5) (snd-display #__line__ ";max 2: ~A" val)) (do ((i 0 (+ i 1))) ((= i 5)) (set! val (moving-max gen 0.0))) (if (fneq val 1.5) (snd-display #__line__ ";max 6: ~A" val)) (set! val (moving-max gen 0.0)) (if (fneq val 1.5) (snd-display #__line__ ";max 7: ~A" val)) (set! val (moving-max gen 0.0)) (if (fneq val 1.5) (snd-display #__line__ ";max 8: ~A" val)) (set! val (moving-max gen 0.0)) (if (fneq val 0.0) (snd-display #__line__ ";max 9: ~A" val)) ) (let* ((gen (make-moving-max 10 :initial-element .5)) (val (moving-max gen 0.5))) (if (fneq val 0.5) (snd-display #__line__ ";max initial-element: ~A" val))) (let* ((gen (make-moving-max 3 :initial-contents '(1.0 1.0 1.0))) (val (moving-max gen 1.0))) (if (fneq val 1.0) (snd-display #__line__ ";max initial-contents: ~A" val))) (test-gen-equal (let ((d1 (make-moving-max 3 :initial-contents '(0.7 0.5 3)))) (moving-max d1 1.0) d1) (let ((d2 (make-moving-max 3 :initial-contents (float-vector 0.7 0.5 3)))) (moving-max d2 1.0) d2) (let ((d3 (make-moving-max 4 :initial-contents '(0.7 0.5 0.1 4)))) (moving-max d3 1.0) d3)) (test-gen-equal (make-moving-max 3 :initial-element 1.0) (make-moving-max 3 :initial-element 1.0) (make-moving-max 3 :initial-element 0.5)) (test-gen-equal (make-moving-max 3 :initial-element 1.0) (make-moving-max 3 :initial-element 1.0) (make-moving-max 4 :initial-element 1.0)) (test-gen-equal (make-moving-max 3 :initial-contents '(1.0 0.0 0.0)) (make-moving-max 3 :initial-contents '(1.0 0.0 0.0)) (make-moving-max 3 :initial-contents '(1.0 1.0 1.0))) (let ((err (catch #t (lambda () (make-moving-max :size -1)) (lambda args args)))) (if (not (eq? (car err) 'out-of-range)) (snd-display #__line__ ";make-max bad size error message: ~A" err))) (let ((err (catch #t (lambda () (make-moving-max :size 0)) (lambda args args)))) (if (not (eq? (car err) 'out-of-range)) (snd-display #__line__ ";make-max size==0 error message: ~A" err))) (let ((gen (make-moving-norm 4)) (v0 (make-float-vector 10)) (gen1 (make-moving-norm 4)) (v1 (make-float-vector 10))) (print-and-check gen "moving-norm" "moving-norm, max 0.000, y1 5.000, weight 0.800, line[4]:[0 0 0 0]") (do ((i 0 (+ i 1))) ((= i 10)) (set! (v0 i) (moving-norm gen 1.0))) (fill-float-vector v1 (if (moving-norm? gen1) (moving-norm gen1 1.0) -1.0)) (if (not (vequal v1 v0)) (snd-display #__line__ ";map norm: ~A ~A" v0 v1)) (if (not (moving-norm? gen)) (snd-display #__line__ ";~A not norm?" gen)) (if (not (= (mus-length gen) 4)) (snd-display #__line__ ";norm length: ~D?" (mus-length gen))) (if (not (= (mus-order gen) 4)) (snd-display #__line__ ";norm order: ~D?" (mus-order gen)))) (let* ((gen (make-moving-norm 8)) (val (moving-norm gen))) (if (fneq val 1.1236) (snd-display #__line__ ";empty norm: ~A" val)) (set! val (moving-norm gen 1.0)) (if (fneq val 1.1084) (snd-display #__line__ ";norm 1: ~A" val)) (set! val (moving-norm gen -0.5)) (if (fneq val 1.0952) (snd-display #__line__ ";norm 2: ~A" val)) (set! val (moving-norm gen -1.5)) (if (fneq val 1.0222) (snd-display #__line__ ";norm 2: ~A" val)) (do ((i 0 (+ i 1))) ((= i 5)) (set! val (moving-norm gen 0.0))) (if (fneq val 0.8261) (snd-display #__line__ ";norm 6: ~A" val)) (set! val (moving-norm gen 0.0)) (if (fneq val 0.8047) (snd-display #__line__ ";norm 7: ~A" val)) (set! val (moving-norm gen 0.0)) (if (fneq val 0.7866) (snd-display #__line__ ";norm 8: ~A" val)) (set! val (moving-norm gen 0.0)) (if (fneq val 0.8841) (snd-display #__line__ ";norm 9: ~A" val)) ) (let* ((gen (make-moving-norm 10 :initial-element .5)) (val (moving-norm gen 0.5))) (if (fneq val 1.0476) (snd-display #__line__ ";norm initial-element: ~A" val))) (let* ((gen (make-moving-norm 3 :initial-contents '(1.0 1.0 1.0))) (val (moving-norm gen 1.0))) (if (fneq val 1.0) (snd-display #__line__ ";norm initial-contents: ~A" val))) (test-gen-equal (let ((d1 (make-moving-norm 3))) (moving-norm d1 1.0) d1) (let ((d2 (make-moving-norm 3))) (moving-norm d2 1.0) d2) (let ((d3 (make-moving-norm 4))) (moving-norm d3 1.0) d3)) (test-gen-equal (make-moving-norm 3 :scaler 1.0) (make-moving-norm 3 :scaler 1.0) (make-moving-norm 4 :scaler 1.0)) (let ((err (catch #t (lambda () (make-moving-norm :size -1)) (lambda args args)))) (if (not (eq? (car err) 'out-of-range)) (snd-display #__line__ ";make-norm bad size error message: ~A" err))) (let ((err (catch #t (lambda () (make-moving-norm :size 0)) (lambda args args)))) (if (not (eq? (car err) 'out-of-range)) (snd-display #__line__ ";make-norm size==0 error message: ~A" err))) (let ((gen (make-comb .4 3)) (v0 (make-float-vector 10)) (gen1 (make-comb .4 3)) (v1 (make-float-vector 10))) (print-and-check gen "comb" "comb scaler: 0.400, line[3, step]: [0 0 0]") (do ((i 0 (+ i 1))) ((= i 10)) (set! (v0 i) (comb gen 1.0))) (fill-float-vector v1 (if (comb? gen1) (comb gen1 1.0) -1.0)) (if (not (vequal v0 v1)) (snd-display #__line__ ";map comb: ~A ~A" v0 v1)) (if (not (comb? gen)) (snd-display #__line__ ";~A not comb?" gen)) (if (not (= (mus-length gen) 3)) (snd-display #__line__ ";comb length: ~D?" (mus-length gen))) (if (not (= (mus-order gen) 3)) (snd-display #__line__ ";comb order: ~D?" (mus-order gen))) (if (fneq (mus-feedback gen) .4) (snd-display #__line__ ";comb feedback: ~F?" (mus-feedback gen))) (if (or (fneq (v0 1) 0.0) (fneq (v0 4) 1.0) (fneq (v0 8) 1.4)) (snd-display #__line__ ";comb output: ~A" v0))) (test-gen-equal (let ((d1 (make-comb 0.7 3))) (comb d1 1.0) d1) (let ((d2 (make-comb 0.7 3))) (comb d2 1.0) d2) (let ((d3 (make-comb 0.7 4))) (comb d3 1.0) d3)) (test-gen-equal (make-comb 0.7 3 :initial-element 1.0) (make-comb 0.7 3 :initial-element 1.0) (make-comb 0.7 3 :initial-element 0.5)) (test-gen-equal (make-comb 0.7 3 :initial-element 1.0) (make-comb 0.7 3 :initial-element 1.0) (make-comb 0.5 3 :initial-element 1.0)) (test-gen-equal (make-comb 0.7 3 :initial-contents '(1.0 0.0 0.0)) (make-comb 0.7 3 :initial-contents '(1.0 0.0 0.0)) (make-comb 0.7 3 :initial-contents '(1.0 1.0 1.0))) (let ((del (make-comb 0.0 5 :max-size 8))) (comb del 1.0) (do ((i 0 (+ i 1))) ((= i 4)) (comb del 0.0)) (let ((v0 (make-float-vector 5))) (do ((i 0 (+ i 1))) ((= i 5)) (set! (v0 i) (comb del 0.0 0.4))) (if (not (vequal v0 (float-vector 0.600 0.400 0.000 0.000 0.000))) ; this is assuming interpolation in the delay... (snd-display #__line__ ";zcomb: ~A" v0)) (comb del 1.0) (comb del 0.0 0.4) (if (not (string=? (mus-describe del) "comb scaler: 0.000, line[5,8, linear]: [0 0 1 0 0]")) (snd-display #__line__ ";describe zcomb: ~A" (mus-describe del)))) (set! (mus-feedback del) 1.0) (if (fneq (mus-feedback del) 1.0) (snd-display #__line__ ";comb feedback set: ~A" (mus-feedback del)))) (let ((gen (make-filtered-comb .4 5 :filter (make-one-zero .3 .7))) (v0 (make-float-vector 20))) (print-and-check gen "filtered-comb" "filtered-comb scaler: 0.400, line[5, step]: [0 0 0 0 0], filter: [one-zero a0: 0.300, a1: 0.700, x1: 0.000]") (let ((val 1.0)) (do ((i 0 (+ i 1))) ((= i 20)) (set! (v0 i) (filtered-comb gen val)) (set! val 0.0))) (if (not (vequal v0 (float-vector 0.000 0.000 0.000 0.000 0.000 1.000 0.000 0.000 0.000 0.000 0.120 0.280 0.000 0.000 0.000 0.014 0.067 0.078 0.000 0.000))) (snd-display #__line__ ";filtered-comb: ~A" v0)) (if (not (filtered-comb? gen)) (snd-display #__line__ ";~A not filtered-comb?" gen)) (if (not (= (mus-length gen) 5)) (snd-display #__line__ ";filtered-comb length: ~D?" (mus-length gen))) (if (not (= (mus-order gen) 5)) (snd-display #__line__ ";filtered-comb order: ~D?" (mus-order gen))) (if (fneq (mus-feedback gen) .4) (snd-display #__line__ ";filtered-comb feedback: ~F?" (mus-feedback gen)))) (let ((gen (make-filtered-comb .9 5 :filter (make-one-zero .5 .5))) (v0 (make-float-vector 20))) (print-and-check gen "filtered-comb" "filtered-comb scaler: 0.900, line[5, step]: [0 0 0 0 0], filter: [one-zero a0: 0.500, a1: 0.500, x1: 0.000]") (let ((val 1.0)) (do ((i 0 (+ i 1))) ((= i 20)) (set! (v0 i) (filtered-comb gen val)) (set! val 0.0))) (if (not (vequal v0 (float-vector 0.000 0.000 0.000 0.000 0.000 1.000 0.000 0.000 0.000 0.000 0.450 0.450 0.000 0.000 0.000 0.202 0.405 0.202 0.000 0.000))) (snd-display #__line__ ";filtered-comb .5 .5: ~A" v0))) (let ((gen (make-filtered-comb .9 5 :filter (make-fir-filter 5 (float-vector .1 .2 .3 .2 .1)))) (v0 (make-float-vector 20))) (print-and-check gen "filtered-comb" "filtered-comb scaler: 0.900, line[5, step]: [0 0 0 0 0], filter: [fir-filter order: 5, xs: [0.1 0.2 0.3 0.2 0.1]]") (let ((val 1.0)) (do ((i 0 (+ i 1))) ((= i 20)) (set! (v0 i) (filtered-comb gen val)) (set! val 0.0))) (if (not (vequal v0 (float-vector 0.000 0.000 0.000 0.000 0.000 1.000 0.000 0.000 0.000 0.000 0.090 0.180 0.270 0.180 0.090 0.008 0.032 0.081 0.130 0.154))) (snd-display #__line__ ";filtered-comb fir: ~A" v0))) (test-gen-equal (let ((d1 (make-filtered-comb 0.7 3 :filter (make-one-pole .3 .7)))) (filtered-comb d1 1.0) d1) (let ((d2 (make-filtered-comb 0.7 3 :filter (make-one-pole .3 .7)))) (filtered-comb d2 1.0) d2) (let ((d3 (make-filtered-comb 0.7 4 :filter (make-one-pole .3 .7)))) (filtered-comb d3 1.0) d3)) (test-gen-equal (make-filtered-comb 0.7 3 :initial-element 1.0 :filter (make-one-zero .5 .5)) (make-filtered-comb 0.7 3 :initial-element 1.0 :filter (make-one-zero .5 .5)) (make-filtered-comb 0.7 3 :initial-element 0.5 :filter (make-one-zero .5 .5))) (test-gen-equal (make-filtered-comb 0.7 3 :initial-element 1.0 :filter (make-one-zero .5 .5)) (make-filtered-comb 0.7 3 :initial-element 1.0 :filter (make-one-zero .5 .5)) (make-filtered-comb 0.7 3 :initial-element 1.0 :filter (make-one-zero .25 .75))) (test-gen-equal (make-filtered-comb 0.7 3 :initial-contents '(1.0 0.0 0.0) :filter (make-one-zero .5 .5)) (make-filtered-comb 0.7 3 :initial-contents '(1.0 0.0 0.0) :filter (make-one-zero .5 .5)) (make-filtered-comb 0.7 3 :initial-contents '(1.0 1.0 1.0) :filter (make-one-zero .5 .5))) (let ((del (make-filtered-comb 0.0 5 :max-size 8 :filter (make-one-zero .5 .5)))) (filtered-comb del 1.0) (do ((i 0 (+ i 1))) ((= i 4)) (filtered-comb del 0.0)) (let ((v0 (make-float-vector 5))) (do ((i 0 (+ i 1))) ((= i 5)) (set! (v0 i) (filtered-comb del 0.0 0.4))) (if (not (vequal v0 (float-vector 0.600 0.400 0.000 0.000 0.000))) ; this is assuming interpolation in the delay... (snd-display #__line__ ";zfiltered-comb: ~A" v0)) (filtered-comb del 1.0) (filtered-comb del 0.0 0.4) (if (not (string=? (mus-describe del) "filtered-comb scaler: 0.000, line[5,8, linear]: [0 0 1 0 0], filter: [one-zero a0: 0.500, a1: 0.500, x1: 0.000]")) (snd-display #__line__ ";describe zfiltered-comb: ~A" (mus-describe del)))) (set! (mus-feedback del) 1.0) (if (fneq (mus-feedback del) 1.0) (snd-display #__line__ ";filtered-comb feedback set: ~A" (mus-feedback del)))) (let ((gen (make-notch .4 3)) (v0 (make-float-vector 10)) (gen1 (make-notch .4 3)) (v1 (make-float-vector 10))) (print-and-check gen "notch" "notch scaler: 0.400, line[3, step]: [0 0 0]") (do ((i 0 (+ i 1))) ((= i 10)) (set! (v0 i) (notch gen 1.0))) (fill-float-vector v1 (if (notch? gen1) (notch gen1 1.0) -1.0)) (if (not (vequal v0 v1)) (snd-display #__line__ ";map notch: ~A ~A" v0 v1)) (if (not (notch? gen)) (snd-display #__line__ ";~A not notch?" gen)) (if (not (= (mus-length gen) 3)) (snd-display #__line__ ";notch length: ~D?" (mus-length gen))) (if (not (= (mus-order gen) 3)) (snd-display #__line__ ";notch order: ~D?" (mus-order gen))) (if (fneq (mus-feedforward gen) .4) (snd-display #__line__ ";notch feedforward: ~F?" (mus-feedforward gen))) (if (or (fneq (v0 1) 0.4) (fneq (v0 4) 1.4) (fneq (v0 8) 1.4)) (snd-display #__line__ ";notch output: ~A" v0)) (set! (mus-feedforward gen) 1.0) (if (fneq (mus-feedforward gen) 1.0) (snd-display #__line__ ";notch feedforward set: ~A" (mus-feedforward gen)))) (test-gen-equal (let ((d1 (make-notch 0.7 3))) (notch d1 1.0) d1) (let ((d2 (make-notch 0.7 3))) (notch d2 1.0) d2) (let ((d3 (make-notch 0.7 4))) (notch d3 1.0) d3)) (test-gen-equal (make-notch 0.7 3 :initial-element 1.0) (make-notch 0.7 3 :initial-element 1.0) (make-notch 0.7 3 :initial-element 0.5)) (test-gen-equal (make-notch 0.7 3 :initial-element 1.0) (make-notch 0.7 3 :initial-element 1.0) (make-notch 0.5 3 :initial-element 1.0)) (test-gen-equal (make-notch 0.7 3 :initial-contents '(1.0 0.0 0.0)) (make-notch 0.7 3 :initial-contents '(1.0 0.0 0.0)) (make-notch 0.7 3 :initial-contents '(1.0 1.0 1.0))) ;; make sure all-pass is the same as comb/notch given the appropriate feedback/forward settings (let ((gen (make-comb 0.5 5)) (v0 (make-float-vector 11)) (in1 1.0)) (do ((i 0 (+ i 1))) ((= i 11)) (set! (v0 i) (comb gen in1)) (set! in1 0.0)) (if (not (vequal v0 (float-vector 0.000 0.000 0.000 0.000 0.000 1.000 0.000 0.000 0.000 0.000 0.500))) (snd-display #__line__ ";comb (5 .5): ~A" v0))) (let ((gen (make-all-pass 0.5 0.0 5)) (v0 (make-float-vector 11)) (in1 1.0)) (do ((i 0 (+ i 1))) ((= i 11)) (set! (v0 i) (all-pass gen in1)) (set! in1 0.0)) (if (not (vequal v0 (float-vector 0.000 0.000 0.000 0.000 0.000 1.000 0.000 0.000 0.000 0.000 0.500))) (snd-display #__line__ ";all-pass (5 0 .5): ~A" v0))) (let ((gen (make-notch 0.5 5)) (v0 (make-float-vector 11)) (in1 1.0)) (do ((i 0 (+ i 1))) ((= i 11)) (set! (v0 i) (notch gen in1)) (set! in1 0.0)) (if (not (vequal v0 (float-vector 0.500 0.000 0.000 0.000 0.000 1.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";notch (5 .5): ~A" v0))) (let ((gen (make-all-pass 0.0 0.5 5)) (v0 (make-float-vector 11)) (in1 1.0)) (do ((i 0 (+ i 1))) ((= i 11)) (set! (v0 i) (all-pass gen in1)) (set! in1 0.0)) (if (not (vequal v0 (float-vector 0.500 0.000 0.000 0.000 0.000 1.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";all-pass (5 .5 0): ~A" v0))) ;; make sure zall-pass is the same as zcomb/znotch given the appropriate feedback/forward and "pm" settings (let ((gen (make-comb 0.5 5 :max-size 20)) (v0 (make-float-vector 11)) (in1 1.0)) (do ((i 0 (+ i 1))) ((= i 11)) (set! (v0 i) (comb gen in1)) (set! in1 0.0)) (if (not (vequal v0 (float-vector 0.000 0.000 0.000 0.000 0.000 1.000 0.000 0.000 0.000 0.000 0.500))) (snd-display #__line__ ";1comb (5 .5): ~A" v0))) (let ((gen (make-all-pass 0.5 0.0 5 :max-size 20)) (v0 (make-float-vector 11)) (in1 1.0)) (do ((i 0 (+ i 1))) ((= i 11)) (set! (v0 i) (all-pass gen in1)) (set! in1 0.0)) (if (not (vequal v0 (float-vector 0.000 0.000 0.000 0.000 0.000 1.000 0.000 0.000 0.000 0.000 0.500))) (snd-display #__line__ ";1all-pass (5 0 .5): ~A" v0))) (let ((gen (make-notch 0.5 5 :max-size 20)) (v0 (make-float-vector 11)) (in1 1.0)) (do ((i 0 (+ i 1))) ((= i 11)) (set! (v0 i) (notch gen in1)) (set! in1 0.0)) (if (not (vequal v0 (float-vector 0.500 0.000 0.000 0.000 0.000 1.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";1notch (5 .5): ~A" v0))) (let ((gen (make-all-pass 0.0 0.5 5 :max-size 20)) (v0 (make-float-vector 11)) (in1 1.0)) (do ((i 0 (+ i 1))) ((= i 11)) (set! (v0 i) (all-pass gen in1)) (set! in1 0.0)) (if (not (vequal v0 (float-vector 0.500 0.000 0.000 0.000 0.000 1.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";1all-pass (5 .5 0): ~A" v0))) ;; now actually use the size difference (let ((gen (make-comb 0.5 5 :max-size 20)) (v0 (make-float-vector 20)) (in1 1.0)) (do ((i 0 (+ i 1)) (phase 0.0 (+ phase .2))) ((= i 20)) (set! (v0 i) (comb gen in1 phase)) (set! in1 0.0)) (if (not (vequal v0 (float-vector 0.000 0.000 0.000 0.000 0.000 0.000 0.800 0.400 0.000 0.000 0.000 0.000 0.000 0.160 0.360 0.200 0.040 0.000 0.000 0.000))) (snd-display #__line__ ";2comb (5 .5): ~A" v0))) (let ((gen (make-all-pass 0.5 0.0 5 :max-size 20)) (v0 (make-float-vector 20)) (in1 1.0)) (do ((i 0 (+ i 1)) (angle 0.0 (+ angle .2))) ((= i 20)) (set! (v0 i) (all-pass gen in1 angle)) (set! in1 0.0)) (if (not (vequal v0 (float-vector 0.000 0.000 0.000 0.000 0.000 0.000 0.800 0.400 0.000 0.000 0.000 0.000 0.000 0.160 0.360 0.200 0.040 0.000 0.000 0.000))) (snd-display #__line__ ";2all-pass (5 0 .5): ~A" v0))) (let ((gen (make-notch 0.5 5 :max-size 20)) (v0 (make-float-vector 20)) (in1 1.0)) (do ((i 0 (+ i 1)) (angle 0.0 (+ angle .2))) ((= i 20)) (set! (v0 i) (notch gen in1 angle)) (set! in1 0.0)) (if (not (vequal v0 (float-vector 0.500 0.000 0.000 0.000 0.000 0.000 0.800 0.400 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";2notch (5 .5): ~A" v0))) (let ((gen (make-all-pass 0.0 0.5 5 :max-size 20)) (v0 (make-float-vector 20)) (in1 1.0)) (do ((i 0 (+ i 1)) (angle 0.0 (+ angle .2))) ((= i 20)) (set! (v0 i) (all-pass gen in1 angle)) (set! in1 0.0)) (if (not (vequal v0 (float-vector 0.500 0.000 0.000 0.000 0.000 0.000 0.800 0.400 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";2all-pass (5 .5 0): ~A" v0))) (let ((gen (make-comb 0.5 5 :max-size 20)) (v0 (make-float-vector 20)) (in1 1.0)) (do ((i 0 (+ i 1)) (angle 0.0 (- angle .2))) ((= i 20)) (set! (v0 i) (comb gen in1 angle)) (set! in1 0.0)) (if (not (vequal v0 (float-vector 0.000 0.000 0.000 0.000 0.800 0.000 0.000 0.160 0.160 0.000 0.080 0.064 0.016 0.035 0.013 0.018 0.007 0.007 0.003 0.002))) (snd-display #__line__ ";3comb (5 .5): ~A" v0))) (let ((gen (make-all-pass 0.5 0.0 5 :max-size 20)) (v0 (make-float-vector 20)) (in1 1.0)) (do ((i 0 (+ i 1)) (angle 0.0 (- angle .2))) ((= i 20)) (set! (v0 i) (all-pass gen in1 angle)) (set! in1 0.0)) (if (not (vequal v0 (float-vector 0.000 0.000 0.000 0.000 0.800 0.000 0.000 0.160 0.160 0.000 0.080 0.064 0.016 0.035 0.013 0.018 0.007 0.007 0.003 0.002))) (snd-display #__line__ ";3all-pass (5 0 .5): ~A" v0))) (let ((gen (make-notch 0.5 5 :max-size 20)) (v0 (make-float-vector 20)) (in1 1.0)) (do ((i 0 (+ i 1)) (angle 0.0 (- angle .2))) ((= i 20)) (set! (v0 i) (notch gen in1 angle)) (set! in1 0.0)) (if (not (vequal v0 (float-vector 0.500 0.000 0.000 0.000 0.800 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";3notch (5 .5): ~A" v0))) (let ((gen (make-all-pass 0.0 0.5 5 :max-size 20)) (v0 (make-float-vector 20)) (in1 1.0)) (do ((i 0 (+ i 1)) (angle 0.0 (- angle .2))) ((= i 20)) (set! (v0 i) (all-pass gen in1 angle)) (set! in1 0.0)) (if (not (vequal v0 (float-vector 0.500 0.000 0.000 0.000 0.800 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";3all-pass (5 .5 0): ~A" v0))) (let ((gen (make-comb 0.5 5 :max-size 20)) (v0 (make-float-vector 20)) (in1 1.0)) (do ((i 0 (+ i 1)) (angle 0.0 (+ angle .01))) ((= i 20)) (set! (v0 i) (comb gen in1 angle)) (set! in1 0.0)) (if (not (vequal v0 (float-vector 0.000 0.000 0.000 0.000 0.000 0.950 0.060 0.000 0.000 0.000 0.428 0.079 0.004 0.000 0.000 0.182 0.067 0.008 0.000 0.000))) (snd-display #__line__ ";4comb (5 .5): ~A" v0))) (let ((gen (make-all-pass 0.5 0.0 5 :max-size 20)) (v0 (make-float-vector 20)) (in1 1.0)) (do ((i 0 (+ i 1)) (angle 0.0 (+ angle .01))) ((= i 20)) (set! (v0 i) (all-pass gen in1 angle)) (set! in1 0.0)) (if (not (vequal v0 (float-vector 0.000 0.000 0.000 0.000 0.000 0.950 0.060 0.000 0.000 0.000 0.428 0.079 0.004 0.000 0.000 0.182 0.067 0.008 0.000 0.000))) (snd-display #__line__ ";4all-pass (5 0 .5): ~A" v0))) (let ((gen (make-notch 0.5 5 :max-size 20)) (v0 (make-float-vector 20)) (in1 1.0)) (do ((i 0 (+ i 1)) (angle 0.0 (+ angle .01))) ((= i 20)) (set! (v0 i) (notch gen in1 angle)) (set! in1 0.0)) (if (not (vequal v0 (float-vector 0.500 0.000 0.000 0.000 0.000 0.950 0.060 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";4notch (5 .5): ~A" v0))) (let ((gen (make-all-pass 0.0 0.5 5 :max-size 20)) (v0 (make-float-vector 20)) (in1 1.0)) (do ((i 0 (+ i 1)) (angle 0.0 (+ angle .01))) ((= i 20)) (set! (v0 i) (all-pass gen in1 angle)) (set! in1 0.0)) (if (not (vequal v0 (float-vector 0.500 0.000 0.000 0.000 0.000 0.950 0.060 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";4all-pass (5 .5 0): ~A" v0))) ;; now run off either end of the delay line "by accident" (let ((gen (make-comb 0.5 5 :max-size 10)) (v0 (make-float-vector 20)) (in1 1.0)) (do ((i 0 (+ i 1)) (angle 0.0 (+ angle .5))) ((= i 20)) (set! (v0 i) (comb gen in1 angle)) (set! in1 0.0)) (if (not (vequal v0 (float-vector 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.500 1.000 0.250 0.125 0.094 0.062 0.055 0.047 0.039 0.031 0.029))) (snd-display #__line__ ";5comb (5 .5): ~A" v0))) (let ((gen (make-all-pass 0.5 0.0 5 :max-size 10)) (v0 (make-float-vector 20)) (in1 1.0)) (do ((i 0 (+ i 1)) (angle 0.0 (+ angle .5))) ((= i 20)) (set! (v0 i) (all-pass gen in1 angle)) (set! in1 0.0)) (if (not (vequal v0 (float-vector 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.500 1.000 0.250 0.125 0.094 0.062 0.055 0.047 0.039 0.031 0.029))) (snd-display #__line__ ";5all-pass (5 0 .5): ~A" v0))) (let ((gen (make-notch 0.5 5 :max-size 10)) (v0 (make-float-vector 20)) (in1 1.0)) (do ((i 0 (+ i 1)) (angle 0.0 (+ angle .5))) ((= i 20)) (set! (v0 i) (notch gen in1 angle)) (set! in1 0.0)) (if (not (vequal v0 (float-vector 0.500 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.500 1.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";5notch (5 .5): ~A" v0))) (let ((gen (make-all-pass 0.0 0.5 5 :max-size 10)) (v0 (make-float-vector 20)) (in1 1.0)) (do ((i 0 (+ i 1)) (angle 0.0 (+ angle .5))) ((= i 20)) (set! (v0 i) (all-pass gen in1 angle)) (set! in1 0.0)) (if (not (vequal v0 (float-vector 0.500 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.500 1.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";5all-pass (5 .5 0): ~A" v0))) (let ((gen (make-comb 0.5 5 :max-size 10)) (v0 (make-float-vector 20)) (in1 1.0)) (do ((i 0 (+ i 1)) (angle 0.0 (- angle .5))) ((= i 20)) (set! (v0 i) (comb gen in1 angle)) (set! in1 0.0)) (if (not (vequal v0 (float-vector 0.000 0.000 0.000 0.500 0.000 0.125 0.000 0.031 0.016 0.004 1.000 0.000 0.250 0.031 0.000 0.012 0.002 0.250 0.125 0.008))) (snd-display #__line__ ";6comb (5 .5): ~A" v0))) (let ((gen (make-all-pass 0.5 0.0 5 :max-size 10)) (v0 (make-float-vector 20)) (in1 1.0)) (do ((i 0 (+ i 1)) (angle 0.0 (- angle .5))) ((= i 20)) (set! (v0 i) (all-pass gen in1 angle)) (set! in1 0.0)) (if (not (vequal v0 (float-vector 0.000 0.000 0.000 0.500 0.000 0.125 0.000 0.031 0.016 0.004 1.000 0.000 0.250 0.031 0.000 0.012 0.002 0.250 0.125 0.008))) (snd-display #__line__ ";6all-pass (5 0 .5): ~A" v0))) (let ((gen (make-notch 0.5 5 :max-size 10)) (v0 (make-float-vector 20)) (in1 1.0)) (do ((i 0 (+ i 1)) (angle 0.0 (- angle .5))) ((= i 20)) (set! (v0 i) (notch gen in1 angle)) (set! in1 0.0)) (if (not (vequal v0 (float-vector 0.500 0.000 0.000 0.500 0.000 0.000 0.000 0.000 0.000 0.000 1.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";6notch (5 .5): ~A" v0))) (let ((gen (make-all-pass 0.0 0.5 5 :max-size 10)) (v0 (make-float-vector 20)) (in1 1.0)) (do ((i 0 (+ i 1)) (angle 0.0 (- angle .5))) ((= i 20)) (set! (v0 i) (all-pass gen in1 angle)) (set! in1 0.0)) (if (not (vequal v0 (float-vector 0.500 0.000 0.000 0.500 0.000 0.000 0.000 0.000 0.000 0.000 1.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";6all-pass (5 .5 0): ~A" v0))) (let ((gen (make-filtered-comb 0.5 5 :filter (make-one-zero .5 .5))) (v0 (make-float-vector 21)) (in1 1.0)) (do ((i 0 (+ i 1))) ((= i 21)) (set! (v0 i) (filtered-comb gen in1)) (set! in1 0.0)) (if (not (vequal v0 (float-vector 0.000 0.000 0.000 0.000 0.000 1.000 0.000 0.000 0.000 0.000 0.250 0.250 0.000 0.000 0.000 0.062 0.125 0.062 0.000 0.000 0.016))) (snd-display #__line__ ";filtered-comb (5 .5): ~A" v0))) (let ((gen (make-filtered-comb 0.5 5 :filter (make-one-zero .25 .75))) (v0 (make-float-vector 21)) (in1 1.0)) (do ((i 0 (+ i 1))) ((= i 21)) (set! (v0 i) (filtered-comb gen in1)) (set! in1 0.0)) (if (not (vequal v0 (float-vector 0.000 0.000 0.000 0.000 0.000 1.000 0.000 0.000 0.000 0.000 0.125 0.375 0.000 0.000 0.000 0.016 0.094 0.141 0.000 0.000 0.002))) (snd-display #__line__ ";1filtered-comb (5 .5): ~A" v0))) (let ((gen (make-filtered-comb 0.5 5 :filter (make-one-zero .25 .75))) (v0 (make-float-vector 21)) (in1 1.0)) (define mus-filtered-comb filtered-comb) (do ((i 0 (+ i 1))) ((= i 21)) (set! (v0 i) (mus-filtered-comb gen in1)) (set! in1 0.0)) (if (not (vequal v0 (float-vector 0.000 0.000 0.000 0.000 0.000 1.000 0.000 0.000 0.000 0.000 0.125 0.375 0.000 0.000 0.000 0.016 0.094 0.141 0.000 0.000 0.002))) (snd-display #__line__ ";1mus-filtered-comb (5 .5): ~A" v0))) (let ((gen (make-filtered-comb 0.5 5 :filter (make-one-zero .25 .75))) (v0 (make-float-vector 21)) (in1 1.0)) (do ((i 0 (+ i 1))) ((= i 21)) (set! (v0 i) (filtered-comb gen in1)) (set! in1 0.0)) (if (not (vequal v0 (float-vector 0.000 0.000 0.000 0.000 0.000 1.000 0.000 0.000 0.000 0.000 0.125 0.375 0.000 0.000 0.000 0.016 0.094 0.141 0.000 0.000 0.002))) (snd-display #__line__ ";1run-filtered-comb (5 .5): ~A" v0))) (let ((gen (make-filtered-comb 0.5 5 :max-size 20 :filter (make-one-zero .5 .5))) (v0 (make-float-vector 20)) (in1 1.0)) (do ((i 0 (+ i 1)) (angle 0.0 (+ angle .2))) ((= i 20)) (set! (v0 i) (filtered-comb gen in1 angle)) (set! in1 0.0)) (if (not (vequal v0 (float-vector 0.000 0.000 0.000 0.000 0.000 0.000 0.800 0.400 0.000 0.000 0.000 0.000 0.000 0.080 0.220 0.300 0.140 0.040 0.000 0.000))) (snd-display #__line__ ";2filtered-comb (5 .5): ~A" v0))) (let ((gen (make-filtered-comb 0.5 5 :max-size 20 :filter (make-one-zero .5 .5))) (v0 (make-float-vector 20)) (in1 1.0)) (do ((i 0 (+ i 1)) (angle 0.0 (- angle .2))) ((= i 20)) (set! (v0 i) (filtered-comb gen in1 angle)) (set! in1 0.0)) (if (not (vequal v0 (float-vector 0.000 0.000 0.000 0.000 0.800 0.000 0.000 0.080 0.200 0.040 0.020 0.068 0.042 0.019 0.026 0.015 0.011 0.009 0.006 0.004))) (snd-display #__line__ ";3filtered-comb (5 .5): ~A" v0))) (let ((gen (make-filtered-comb 0.5 5 :max-size 20 :filter (make-one-zero .5 .5))) (v0 (make-float-vector 20)) (in1 1.0)) (do ((i 0 (+ i 1)) (angle 0.0 (+ angle .01))) ((= i 20)) (set! (v0 i) (filtered-comb gen in1 angle)) (set! in1 0.0)) (if (not (vequal v0 (float-vector 0.000 0.000 0.000 0.000 0.000 0.950 0.060 0.000 0.000 0.000 0.214 0.251 0.043 0.002 0.000 0.045 0.106 0.081 0.023 0.003))) (snd-display #__line__ ";4filtered-comb (5 .5): ~A" v0))) (let ((gen (make-one-pole .4 .7)) (v0 (make-float-vector 10)) (gen1 (make-one-pole .4 .7)) (v1 (make-float-vector 10))) (print-and-check gen "one-pole" "one-pole a0: 0.400, b1: 0.700, y1: 0.000") (do ((i 0 (+ i 1))) ((= i 10)) (set! (v0 i) (one-pole gen 1.0))) (fill-float-vector v1 (if (one-pole? gen) (one-pole gen1 1.0) -1.0)) (if (not (vequal v0 v1)) (snd-display #__line__ ";map one-pole: ~A ~A" v0 v1)) (if (not (one-pole? gen)) (snd-display #__line__ ";~A not one-pole?" gen)) (if (not (= (mus-order gen) 1)) (snd-display #__line__ ";one-pole order: ~D?" (mus-order gen))) (if (fneq (mus-xcoeff gen 0) .4) (snd-display #__line__ ";one-pole a0: ~F?" (mus-xcoeff gen 0))) (if (fneq (mus-ycoeff gen 1) .7) (snd-display #__line__ ";one-pole b1: ~F?" (mus-ycoeff gen 1))) (if (or (fneq (v0 1) 0.120) (fneq (v0 4) 0.275) (fneq (v0 8) 0.245)) (snd-display #__line__ ";one-pole output: ~A" v0)) (if (fneq (mus-ycoeff gen 1) .7) (snd-display #__line__ ";1p ycoeff 1 .7: ~A" gen)) (set! (mus-ycoeff gen 1) .1) (if (fneq (mus-ycoeff gen 1) .1) (snd-display #__line__ ";1p set ycoeff 1 .1: ~A" gen)) (if (fneq (mus-xcoeff gen 0) .4) (snd-display #__line__ ";1p xcoeff 0 .4: ~A" gen)) (set! (mus-xcoeff gen 0) .3) (if (fneq (mus-xcoeff gen 0) .3) (snd-display #__line__ ";1p set xcoeff 0 .3: ~A" gen))) (let ((gen (make-one-zero .4 .7)) (v0 (make-float-vector 10)) (gen1 (make-one-zero .4 .7)) (v1 (make-float-vector 10))) (print-and-check gen "one-zero" "one-zero a0: 0.400, a1: 0.700, x1: 0.000") (do ((i 0 (+ i 1))) ((= i 10)) (set! (v0 i) (one-zero gen 1.0))) (fill-float-vector v1 (if (one-zero? gen) (one-zero gen1 1.0) -1.0)) (if (not (vequal v0 v1)) (snd-display #__line__ ";map one-zero: ~A ~A" v0 v1)) (if (not (one-zero? gen)) (snd-display #__line__ ";~A not one-zero?" gen)) (if (not (= (mus-order gen) 1)) (snd-display #__line__ ";one-zero order: ~D?" (mus-order gen))) (if (fneq (mus-xcoeff gen 0) .4) (snd-display #__line__ ";one-zero a0: ~F?" (mus-xcoeff gen 0))) (if (fneq (mus-xcoeff gen 1) .7) (snd-display #__line__ ";one-zero a1: ~F?" (mus-xcoeff gen 1))) (if (fneq (v0 1) 1.1) (snd-display #__line__ ";one-zero output: ~A" v0)) (if (fneq (mus-xcoeff gen 0) .4) (snd-display #__line__ ";1z xcoeff 0 .4: ~A" gen)) (set! (mus-xcoeff gen 0) .1) (if (fneq (mus-xcoeff gen 0) .1) (snd-display #__line__ ";1z set xcoeff 0 .1: ~A" gen))) (let ((gen (make-two-zero .4 .7 .3)) (v0 (make-float-vector 10)) (gen1 (make-two-zero .4 .7 .3)) (v1 (make-float-vector 10))) (print-and-check gen "two-zero" "two-zero a0: 0.400, a1: 0.700, a2: 0.300, x1: 0.000, x2: 0.000") (do ((i 0 (+ i 1))) ((= i 10)) (set! (v0 i) (two-zero gen 1.0))) (fill-float-vector v1 (if (two-zero? gen1) (two-zero gen1 1.0) -1.0)) (if (not (vequal v0 v1)) (snd-display #__line__ ";map two-zero: ~A ~A" v0 v1)) (if (not (two-zero? gen)) (snd-display #__line__ ";~A not two-zero?" gen)) (if (not (= (mus-order gen) 2)) (snd-display #__line__ ";two-zero order: ~D?" (mus-order gen))) (if (fneq (mus-xcoeff gen 0) .4) (snd-display #__line__ ";two-zero a0: ~F?" (mus-xcoeff gen 0))) (if (fneq (mus-xcoeff gen 1) .7) (snd-display #__line__ ";two-zero a1: ~F?" (mus-xcoeff gen 1))) (if (fneq (mus-xcoeff gen 2) .3) (snd-display #__line__ ";two-zero a2: ~F?" (mus-xcoeff gen 2))) (if (or (fneq (v0 1) 1.1) (fneq (v0 8) 1.4)) (snd-display #__line__ ";two-zero output: ~A" v0)) (if (fneq (mus-xcoeff gen 0) .4) (snd-display #__line__ ";2z xcoeff 0 .4: ~A" gen)) (set! (mus-xcoeff gen 0) .1) (if (fneq (mus-xcoeff gen 0) .1) (snd-display #__line__ ";2z set xcoeff 0 .1: ~A" gen)) (set! (mus-xcoeff gen 0) 1.0) (let ((r (mus-scaler gen))) (set! (mus-frequency gen) 500.0) (if (ffneq (mus-frequency gen) 500.0) (snd-display #__line__ ";set mus-frequency two-zero: ~A" (mus-frequency gen))) (if (fneq (mus-scaler gen) r) (snd-display #__line__ ";set mus-frequency two-zero hit r: ~A" (mus-scaler gen))) (set! (mus-scaler gen) .99) (if (fneq (mus-scaler gen) .99) (snd-display #__line__ ";set mus-scaler two-zero: ~A" (mus-scaler gen))) (if (ffneq (mus-frequency gen) 500.0) (snd-display #__line__ ";set mus-scaler hit freq two-zero: ~A" (mus-frequency gen))) (let ((g3 (make-two-zero :radius .99 :frequency 500.0))) (if (or (fneq (mus-xcoeff gen 0) (mus-xcoeff g3 0)) (fneq (mus-xcoeff gen 1) (mus-xcoeff g3 1)) (fneq (mus-xcoeff gen 2) (mus-xcoeff g3 2))) (snd-display #__line__ ";two-zero setters: ~A ~A" gen g3))))) (let ((gen (make-two-zero .4 .7 .3))) (let ((val (gen 1.0))) (if (fneq val .4) (snd-display #__line__ ";2zero->0.4: ~A" val)) (set! val (gen 0.5)) (if (fneq val .9) (snd-display #__line__ ";2zero->0.9: ~A" val)) (set! val (gen 1.0)) (if (fneq val 1.05) (snd-display #__line__ ";2zero->1.05: ~A" val)))) (let ((gen (make-two-pole .4 .7 .3)) (v0 (make-float-vector 10)) (gen1 (make-two-pole .4 .7 .3)) (v1 (make-float-vector 10))) (print-and-check gen "two-pole" "two-pole a0: 0.400, b1: 0.700, b2: 0.300, y1: 0.000, y2: 0.000") (do ((i 0 (+ i 1))) ((= i 10)) (set! (v0 i) (two-pole gen 1.0))) (fill-float-vector v1 (if (two-pole? gen1) (two-pole gen1 1.0) -1.0)) (if (not (vequal v0 v1)) (snd-display #__line__ ";map two-pole: ~A ~A" v0 v1)) (if (not (two-pole? gen)) (snd-display #__line__ ";~A not two-pole?" gen)) (if (not (= (mus-order gen) 2)) (snd-display #__line__ ";two-pole order: ~D?" (mus-order gen))) (if (fneq (mus-xcoeff gen 0) .4) (snd-display #__line__ ";two-pole a0: ~F?" (mus-xcoeff gen 0))) (if (fneq (mus-ycoeff gen 1) .7) (snd-display #__line__ ";two-pole b1: ~F?" (mus-ycoeff gen 1))) (if (fneq (mus-ycoeff gen 2) .3) (snd-display #__line__ ";two-pole b2: ~F?" (mus-ycoeff gen 2))) (if (or (fneq (v0 1) 0.12) (fneq (v0 8) 0.201)) (snd-display #__line__ ";two-pole output: ~A" v0)) (if (fneq (mus-ycoeff gen 1) .7) (snd-display #__line__ ";2p ycoeff 1 .7: ~A" gen)) (set! (mus-ycoeff gen 1) .1) (if (fneq (mus-ycoeff gen 1) .1) (snd-display #__line__ ";2p set ycoeff 1 .1: ~A" gen)) (if (fneq (mus-xcoeff gen 0) .4) (snd-display #__line__ ";2p xcoeff 0 .4: ~A" gen)) (set! (mus-xcoeff gen 0) .3) (if (fneq (mus-xcoeff gen 0) .3) (snd-display #__line__ ";2p set xcoeff 0 .3: ~A" gen)) (set! (mus-xcoeff gen 0) 1.0) (let ((r (mus-scaler gen))) (set! (mus-frequency gen) 500.0) (if (ffneq (mus-frequency gen) 500.0) (snd-display #__line__ ";set mus-frequency two-pole: ~A" (mus-frequency gen))) (if (fneq (mus-scaler gen) r) (snd-display #__line__ ";set mus-frequency two-pole hit r: ~A" (mus-scaler gen))) (set! (mus-scaler gen) .99) (if (fneq (mus-scaler gen) .99) (snd-display #__line__ ";set mus-scaler two-pole: ~A" (mus-scaler gen))) (if (ffneq (mus-frequency gen) 500.0) (snd-display #__line__ ";set mus-scaler hit freq two-pole: ~A" (mus-frequency gen))) (let ((g3 (make-two-pole :radius .99 :frequency 500.0))) (if (or (fneq (mus-xcoeff gen 0) (mus-xcoeff g3 0)) (fneq (mus-ycoeff gen 1) (mus-ycoeff g3 1)) (fneq (mus-ycoeff gen 2) (mus-ycoeff g3 2))) (snd-display #__line__ ";two-pole setters: ~A ~A" gen g3))))) (let ((gen (make-two-pole .4 .7 .3))) (let ((val (gen 1.0))) (if (fneq val .4) (snd-display #__line__ ";a0->out 2pole: ~A" val)) (set! val (gen 0.5)) (if (fneq val -.08) (snd-display #__line__ ";a0->out 2pole (-0.08): ~A" val)) (set! val (gen 1.0)) (if (fneq val 0.336) (snd-display #__line__ ";a0->out 2pole (0.336): ~A" val)))) (let ((gen (make-oscil 440.0)) (gen1 (make-oscil 440.0)) (gen2 (make-oscil 440.0)) (v0 (make-float-vector 10)) (v1 (make-float-vector 10)) (v2 (make-float-vector 10))) (print-and-check gen "oscil" "oscil freq: 440.000Hz, phase: 0.000") (do ((i 0 (+ i 1))) ((= i 10)) (set! (v0 i) (oscil gen 0.0)) (set! (v1 i) (mus-apply gen1 0.0 0.0))) (fill-float-vector v2 (if (oscil? gen2) (oscil gen2 0.0) -1.0)) (if (not (vequal v0 v2)) (snd-display #__line__ ";map oscil: ~A ~A" v0 v2)) (if (not (oscil? gen)) (snd-display #__line__ ";~A not oscil?" gen)) (if (fneq (mus-phase gen) 1.253787) (snd-display #__line__ ";oscil phase: ~F?" (mus-phase gen))) (if (fneq (mus-frequency gen) 440.0) (snd-display #__line__ ";oscil frequency: ~F?" (mus-frequency gen))) (if (not (= (mus-length gen) 1)) (snd-display #__line__ ";oscil cosines: ~D?" (mus-length gen))) (if (or (fneq (v0 1) 0.125) (fneq (v0 8) 0.843)) (snd-display #__line__ ";oscil output: ~A" v0)) (set! (mus-phase gen) 0.0) (if (fneq (mus-phase gen) 0.0) (snd-display #__line__ ";oscil set-phase: ~F?" (mus-phase gen))) (set! (mus-frequency gen) 100.0) (if (fneq (mus-frequency gen) 100.0) (snd-display #__line__ ";oscil set-frequency: ~F?" (mus-frequency gen))) (do ((i 0 (+ i 1))) ((= i 10)) (if (fneq (v0 i) (v1 i)) (snd-display #__line__ ";mus-apply oscil at ~D: ~A ~A?" i (v0 i) (v1 i)))) (if (fneq (mus-apply) 0.0) (snd-display #__line__ ";(mus-apply): ~A" (mus-apply)))) ;; we can't (or don't anyway) guarantee optimized arg order evaluation so: (let ((o (make-oscil 1000.0)) (o1 (make-oscil 1000.0)) (v (make-float-vector 10)) (x 0.0)) (do ((i 0 (+ i 1))) ((= i 10)) (set! x (oscil o (oscil o1) (oscil o1))) (set! (v i) x)) (let ((o4 (make-oscil 1000.0)) (o5 (make-oscil 1000.0)) (v2 (make-float-vector 10)) (x1 0.0) (x2 0.0)) (do ((i 0 (+ i 1))) ((= i 10)) (set! x1 (oscil o5)) (set! x2 (oscil o5)) (set! (v2 i) (oscil o4 x2 x1))) (let () (define (hi) (let ((o2 (make-oscil 1000.0)) (o3 (make-oscil 1000.0)) (v1 (make-float-vector 10))) (do ((i 0 (+ i 1))) ((= i 10) v1) (float-vector-set! v1 i (oscil o2 (oscil o3) (oscil o3)))))) (hi) (let ((v1 (hi))) (if (and (not (mus-arrays-equal? v v1)) (not (mus-arrays-equal? v2 v1))) (format *stderr* ":orig: ~A~%; v1: ~A~%; v2: ~A~%" v v1 v2)))))) (test-fm-components) (osc-opt) (nrxysin-opt) (polywave-opt) (do ((i 1 (+ i 1))) ((= i 6)) (test-simple-polywave i #f mus-chebyshev-first-kind) (test-simple-polywave i .1 mus-chebyshev-first-kind) (test-simple-polywave i #f mus-chebyshev-second-kind) (test-simple-polywave i .1 mus-chebyshev-second-kind)) (let ((gen1 (make-oscil 100.0)) (gen2 (make-oscil -100.0)) (mx 0.0)) (do ((i 0 (+ i 1))) ((= i 100)) (set! mx (max mx (abs (+ (gen1) (gen2)))))) (if (fneq mx 0.0) (snd-display #__line__ ";oscil +-: ~A" mx))) (let ((gen1 (make-oscil 100.0 (* pi 0.5))) (gen2 (make-oscil -100.0 (* pi 0.5))) (mx 0.0)) (do ((i 0 (+ i 1))) ((= i 100)) (set! mx (max mx (abs (- (gen1) (gen2)))))) (if (fneq mx 0.0) (snd-display #__line__ ";cosil +-: ~A" mx))) (let ((frqs (float-vector 0.0 0.0)) (amps (float-vector 0.0 0.0)) (phs (float-vector 0.0 0.0))) (let ((ob (make-oscil-bank frqs phs amps))) (if (not (oscil-bank? ob)) (snd-display #__line__ ";oscil-bank? ~A" ob)) (if (not (equal? (mus-data ob) phs)) (snd-display #__line__ ";oscil-bank data: ~A ~A" (mus-data ob) phs)) (let ((x (oscil-bank ob))) (if (not (= x 0.0)) (snd-display #__line__ ";oscil-bank 0.0: ~A~%" x))) (set! (amps 0) 0.5) (set! (amps 1) 0.2) (let ((x (oscil-bank ob))) (if (not (= x 0.0)) (snd-display #__line__ ";oscil-bank 0.0 (amps): ~A~%" x))) (set! (frqs 0) .1) (set! (frqs 1) .2) (oscil-bank ob) (let ((x (oscil-bank ob))) (if (not (morally-equal? x 0.08965057448242633)) (snd-display #__line__ ";oscil-bank 0.09: ~A~%" x))))) (fm-test (make-oscil)) (fm-test (make-nrxysin)) (fm-test (make-nrxycos)) (fm-test (make-square-wave)) (fm-test (make-triangle-wave)) (fm-test (make-ncos)) (fm-test (make-nsin)) (fm-test (make-sawtooth-wave)) (fm-test (make-rand)) (fm-test (make-rand-interp)) (fm-test (make-pulse-train)) (let ((gen (make-oscil 440.0)) (gen1 (make-oscil 440.0))) (do ((i 0 (+ i 1))) ((= i 10)) (let ((oval (oscil gen .1)) (mval (mus-run gen1 .1))) (if (fneq oval mval) (snd-display #__line__ ";mus-run ~A but oscil ~A?" mval oval))))) (let ((gen (make-oscil 440.0)) (gen1 (make-oscil 440.0)) (gen2 (make-oscil 440.0)) (gen3 (make-oscil 440.0)) (fm-index (hz->radians 440.0)) (v0 (make-float-vector 10)) (v1 (make-float-vector 10))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v0 i) (oscil gen (* fm-index (oscil gen1 0.0)))) (set! (v1 i) (mus-apply gen2 (* fm-index (mus-apply gen3 0.0 0.0)) 0.0))) (if (or (fneq (v0 1) 0.125) (fneq (v0 6) 0.830) (fneq (v0 8) 0.987)) (snd-display #__line__ ";oscil fm output: ~A" v0)) (do ((i 0 (+ i 1))) ((= i 10)) (if (fneq (v0 i) (v1 i)) (snd-display #__line__ ";mus-apply fm oscil at ~D: ~A ~A?" i (v0 i) (v1 i))))) (test-gen-equal (make-oscil 440.0) (make-oscil 440.0) (make-oscil 100.0)) (test-gen-equal (make-oscil 440.0) (make-oscil 440.0) (make-oscil 440.0 1.0)) (let ((gen (make-oscil 440.0)) (gen1 (make-oscil 440.0)) (pm-index 2.0) (v0 (make-float-vector 10))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v0 i) (gen 0.0 (* pm-index (gen1 0.0))))) (if (or (fneq (v0 1) 0.367) (fneq (v0 6) 0.854) (fneq (v0 8) 0.437)) (snd-display #__line__ ";oscil pm output: ~A" v0))) (let ((gen (make-oscil 440.0))) (do ((i 0 (+ i 1))) ((= i 1100)) (let ((val1 (sin (mus-phase gen))) (val2 (gen 0.0))) (if (fneq val1 val2) (snd-display #__line__ ";oscil: ~A: ~A ~A" i val1 val2))))) (let ((gen (make-oscil 440.0 :initial-phase (* pi 0.5))) (incr (/ (* 2 pi 440.0) 22050.0))) (do ((i 0 (+ i 1)) (a 0.0 (+ a incr))) ((= i 900)) (let ((val1 (cos a)) (val2 (gen 0.0))) (if (fneq val1 val2) (snd-display #__line__ ";oscil (cos): ~A: ~A ~A" i val1 val2))))) (let ((gen (make-oscil 0.0)) (gen1 (make-oscil 40.0)) (incr (/ (* 2 pi 40.0) 22050.0))) (do ((i 0 (+ i 1)) (a 0.0 (+ a incr))) ((= i 1100)) (let ((val1 (sin (sin a))) (val2 (oscil gen 0.0 (oscil gen1 0.0)))) (if (fneq val1 val2) (snd-display #__line__ ";oscil pm: ~A: ~A ~A" i val1 val2))))) (let ((gen (make-oscil 0.0)) (gen1 (make-oscil 40.0)) (incr (/ (* 2 pi 40.0) 22050.0)) (a1 0.0)) (do ((i 0 (+ i 1)) (a 0.0 (+ a incr))) ((= i 100)) (let ((fm (sin a)) (val1 (sin a1)) (val2 (oscil gen (oscil gen1 0.0)))) (set! a1 (+ a1 fm)) (if (fneq val1 val2) (snd-display #__line__ ";oscil fm: ~A: ~A ~A" i val1 val2))))) (let () (define (oscil-1-1) (let ((osc (make-oscil 440.0))) (let ((v1 (make-vector 10 0.0)) (v2 (make-vector 10 0.0))) (set! (v1 0) (oscil osc)) (set! (v1 1) (oscil osc)) (let ((osc (make-oscil 440.0))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v2 i) (oscil osc)))) (do ((i 2 (+ i 1))) ((= i 10)) (set! (v1 i) (oscil osc))) (if (not (equal? v1 v2)) (snd-display #__line__ ";oscil-1 shadowing test1: ~A ~A" v1 v2))))) (define (oscil-1-2) (define (ho-1 osc v i) (set! (v i) (oscil osc))) (let ((o1 (make-oscil 440.0)) (o2 (make-oscil 440.0)) (v1 (make-vector 10 0.0)) (v2 (make-vector 10 0.0))) (ho-1 o1 v1 0) (ho-1 o1 v1 1) (do ((i 0 (+ i 1))) ((= i 10)) (ho-1 o2 v2 i)) (do ((i 2 (+ i 1))) ((= i 10)) (ho-1 o1 v1 i)) (if (not (equal? v1 v2)) (snd-display #__line__ ";oscil-1 shadowing test2: ~A ~A" v1 v2)))) (define (oscil-1-3) (define (ho) (let ((osc (make-oscil 440.0))) (lambda () (oscil osc)))) (let ((o1 (ho)) (v1 (make-vector 10 0.0)) (v2 (make-vector 10 0.0))) (set! (v1 0) (o1)) (set! (v1 1) (o1)) (let ((o2 (ho))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v2 i) (o2)))) (do ((i 2 (+ i 1))) ((= i 10)) (set! (v1 i) (o1))) (if (not (equal? v1 v2)) (snd-display #__line__ ";oscil-1 shadowing test3: ~A ~A" v1 v2)))) (oscil-1-1) (oscil-1-2) (oscil-1-3)) (let ((var (catch #t (lambda () (mus-location (make-oscil))) (lambda args args)))) (if (not (eq? (car var) 'mus-error)) (snd-display #__line__ ";mus-location bad gen: ~A" var))) (let ((var (catch #t (lambda () (set! (mus-location (make-oscil)) 0)) (lambda args args)))) (if (not (eq? (car var) 'mus-error)) (snd-display #__line__ ";set mus-location bad gen: ~A" var))) (let ((var (catch #t (lambda () (set! (mus-scaler (make-oscil)) 0)) (lambda args args)))) (if (not (eq? (car var) 'mus-error)) (snd-display #__line__ ";set mus-scaler bad gen: ~A" var))) (let ((var (catch #t (lambda () (mus-frequency (make-one-pole))) (lambda args args)))) (if (not (eq? (car var) 'mus-error)) (snd-display #__line__ ";mus-frequency bad gen: ~A" var))) (let ((var (catch #t (lambda () (set! (mus-frequency (make-one-pole)) 0)) (lambda args args)))) (if (not (eq? (car var) 'mus-error)) (snd-display #__line__ ";set mus-frequency bad gen: ~A" var))) (let ((var (catch #t (lambda () (make-delay (* 1024 1024 40))) (lambda args args)))) (if (not (eq? (car var) 'out-of-range)) (snd-display #__line__ ";make-delay huge line: ~A" var))) (let ((var (catch #t (lambda () (make-delay 32 :max-size (* 1024 1024 40))) (lambda args args)))) (if (not (eq? (car var) 'out-of-range)) (snd-display #__line__ ";make-delay huge line: ~A" var))) (let ((size 1000)) (define (test-pm beg end freq amp mc-ratio index) (let ((pm (make-oscil (* freq mc-ratio))) (carrier (make-oscil freq))) (do ((i beg (+ i 1))) ((= i end)) (outa i (* amp (oscil carrier 0.0 (* index (oscil pm)))))))) (define (test-fm beg end freq amp mc-ratio index) (let ((fm (make-oscil (* freq mc-ratio) :initial-phase (/ pi 2.0))) (carrier (make-oscil freq)) (fm-index (* (hz->radians freq) mc-ratio index))) (do ((i beg (+ i 1))) ((= i end)) (outa i (* amp (oscil carrier (* fm-index (oscil fm)))))))) ;; there's an initial-phase confusion here, so by making the srate high and freq low, we minimize uninteresting off-by-1 troubles (let ((v1 (with-sound ((make-float-vector size) :srate 441000) (test-pm 0 size 20 1 1 1))) (v2 (with-sound ((make-float-vector size) :srate 441000) (test-fm 0 size 20 1 1 1)))) (if (not (vequal v1 v2)) (snd-display #__line__ ";fm/pm peak diff (1 1): ~A" (float-vector-peak (float-vector-subtract! v1 v2))))) (do ((i 0 (+ i 1))) ((= i 10)) (let ((ratio (+ 1 (random 4))) (index (random 2.0))) (let ((v1 (with-sound ((make-float-vector size) :srate 441000) (test-pm 0 size 20 1 ratio index))) (v2 (with-sound ((make-float-vector size) :srate 441000) (test-fm 0 size 20 1 ratio index)))) (if (not (vequal v1 v2)) (snd-display #__line__ ";fm/pm peak diff ~A ~A: ~A" ratio index (float-vector-peak (float-vector-subtract! v1 v2)))))))) (let ((gen (make-ncos 440.0 10)) (v0 (make-float-vector 10)) (gen1 (make-ncos 440.0 10)) (v1 (make-float-vector 10))) (print-and-check gen "ncos" "ncos freq: 440.000Hz, phase: 0.000, n: 10") (do ((i 0 (+ i 1))) ((= i 10)) (set! (v0 i) (ncos gen 0.0))) (fill-float-vector v1 (if (ncos? gen1) (ncos gen1 0.0) -1.0)) (if (not (vequal v0 v1)) (snd-display #__line__ ";map ncos: ~A ~A" v0 v1)) (if (not (ncos? gen)) (snd-display #__line__ ";~A not ncos?" gen)) (if (fneq (mus-phase gen) 1.253787) (snd-display #__line__ ";ncos phase: ~F?" (mus-phase gen))) (if (fneq (mus-frequency gen) 440.0) (snd-display #__line__ ";ncos frequency: ~F?" (mus-frequency gen))) (if (fneq (mus-scaler gen) .1) (snd-display #__line__ ";ncos scaler: ~F?" (mus-scaler gen))) (if (not (= (mus-length gen) 10)) (snd-display #__line__ ";ncos n: ~D?" (mus-length gen))) (if (not (= (mus-length gen) 10)) (snd-display #__line__ ";ncos length: ~D?" (mus-length gen))) (if (or (fneq (v0 1) 0.722) (fneq (v0 8) -0.143)) (snd-display #__line__ ";ncos output: ~A" v0)) (set! (mus-scaler gen) .5) (if (fneq (mus-scaler gen) 0.5) (snd-display #__line__ ";ncos set-scaler: ~F?" (mus-scaler gen))) (set! (mus-length gen) 5) (if (not (= (mus-length gen) 5)) (snd-display #__line__ ";set ncos n: ~D?" (mus-length gen))) (if (fneq (mus-scaler gen) .2) (snd-display #__line__ ";set n->scaler: ~A" (mus-scaler gen)))) (test-gen-equal (make-ncos 440.0 3) (make-ncos 440.0 3) (make-ncos 440.0 5)) (test-gen-equal (make-ncos 440.0 3) (make-ncos 440.0 3) (make-ncos 400.0 3)) (let ((gen (make-ncos 440 10))) (do ((i 0 (+ i 1))) ((= i 1100)) (let* ((den (sin (* (mus-phase gen) 0.5))) (val1 (if (= 0.0 den) 1.0 (min 1.0 (* (mus-scaler gen) (- (/ (sin (* (mus-phase gen) (+ (mus-length gen) 0.5))) (* 2.0 den)) 0.5))))) (val2 (gen 0.0))) (if (> (abs (- val1 val2)) .002) (snd-display #__line__ ";ncos: ~A: ~A ~A" i val1 val2))))) (let ((gen1 (make-ncos 100.0 10)) (gen2 (make-ncos -100.0 10)) (mx 0.0)) (do ((i 0 (+ i 1))) ((= i 100)) (set! mx (max mx (abs (- (gen1) (gen2)))))) (if (fneq mx 0.0) (snd-display #__line__ ";ncos +-: ~A" mx))) (test-simple-ncos 1) (test-simple-ncos 3) (test-simple-ncos 10) (let ((gen (make-nsin 440.0 10)) (v0 (make-float-vector 10)) (gen1 (make-nsin 440.0 10)) (v1 (make-float-vector 10))) (print-and-check gen "nsin" "nsin freq: 440.000Hz, phase: 0.000, n: 10") (do ((i 0 (+ i 1))) ((= i 10)) (set! (v0 i) (nsin gen 0.0))) (fill-float-vector v1 (if (nsin? gen1) (nsin gen1 0.0) -1.0)) (if (not (vequal v0 v1)) (snd-display #__line__ ";map nsin: ~A ~A" v0 v1)) (if (not (nsin? gen)) (snd-display #__line__ ";~A not nsin?" gen)) (if (fneq (mus-phase gen) 1.253787) (snd-display #__line__ ";nsin phase: ~F?" (mus-phase gen))) (if (fneq (mus-frequency gen) 440.0) (snd-display #__line__ ";nsin frequency: ~F?" (mus-frequency gen))) (if (fneq (mus-scaler gen) .1315) (snd-display #__line__ ";nsin scaler: ~F?" (mus-scaler gen))) (if (not (= (mus-length gen) 10)) (snd-display #__line__ ";nsin n: ~D?" (mus-length gen))) (if (not (= (mus-length gen) 10)) (snd-display #__line__ ";nsin length: ~D?" (mus-length gen))) (if (or (fneq (v0 1) 0.784) (fneq (v0 8) 0.181)) (snd-display #__line__ ";nsin output: ~A" v0)) (set! (mus-scaler gen) .5) (if (fneq (mus-scaler gen) 0.5) (snd-display #__line__ ";nsin set-scaler: ~F?" (mus-scaler gen))) (set! (mus-length gen) 5) (if (not (= (mus-length gen) 5)) (snd-display #__line__ ";set nsin n: ~D?" (mus-length gen))) (if (fneq (mus-scaler gen) .2525) (snd-display #__line__ ";set sines->scaler: ~A" (mus-scaler gen)))) (test-gen-equal (make-nsin 440.0 3) (make-nsin 440.0 3) (make-nsin 440.0 5)) (test-gen-equal (make-nsin 440.0 3) (make-nsin 440.0 3) (make-nsin 400.0 3)) (let ((gen1 (make-nsin 100.0 10)) (gen2 (make-nsin -100.0 10)) (mx 0.0)) (do ((i 0 (+ i 1))) ((= i 100)) (set! mx (max mx (abs (+ (gen1) (gen2)))))) (if (fneq mx 0.0) (snd-display #__line__ ";nsin +-: ~A" mx))) (test-simple-nsin 1) (test-simple-nsin 3) (test-simple-nsin 10) (let ((gen (make-nrxysin 440.0)) (v0 (make-float-vector 10)) (gen1 (make-nrxysin 440.0)) (v1 (make-float-vector 10))) (print-and-check gen "nrxysin" "nrxysin frequency: 440.000, ratio: 1.000, phase: 0.000, n: 1, r: 0.500") (do ((i 0 (+ i 1))) ((= i 10)) (set! (v0 i) (nrxysin gen 0.0))) (fill-float-vector v1 (if (nrxysin? gen1) (nrxysin gen1 0.0) -1.0)) (if (not (vequal v0 v1)) (snd-display #__line__ ";map nrxysin: ~A ~A" v0 v1)) (if (not (nrxysin? gen)) (snd-display #__line__ ";~A not nrxysin?" gen)) (if (fneq (mus-phase gen) 1.253787) (snd-display #__line__ ";nrxysin phase: ~F?" (mus-phase gen))) (if (fneq (mus-frequency gen) 440.0) (snd-display #__line__ ";nrxysin frequency: ~F?" (mus-frequency gen))) (if (fneq (mus-scaler gen) 0.5) (snd-display #__line__ ";mus-scaler (a) nrxysin: ~A" (mus-scaler gen))) (set! (mus-scaler gen) 0.75) (if (fneq (mus-scaler gen) 0.75) (snd-display #__line__ ";mus-scaler (set a) nrxysin: ~A" (mus-scaler gen))) (if (not (= (mus-length gen) 1)) (snd-display #__line__ ";mus-length nrxysin: ~A" (mus-length gen))) (if (fneq (mus-offset gen) 1.0) (snd-display #__line__ ";mus-offset nrxysin: ~A" (mus-offset gen)))) (test-gen-equal (make-nrxysin 440.0) (make-nrxysin 440.0) (make-nrxysin 100.0)) (test-gen-equal (make-nrxysin 440.0) (make-nrxysin 440.0) (make-nrxysin 440.0 1.5)) (test-gen-equal (make-nrxysin 440.0) (make-nrxysin 440.0) (make-nrxysin 440.0 :n 3)) (let ((v1 (make-float-vector 10))) (with-sound (v1 :srate 44100) (let ((gen (make-nrxysin 1000 :n 10 :r .99))) (do ((i 0 (+ i 1))) ((= i 10)) (outa i (nrxysin gen))))) (if (not (vequal v1 (float-vector 0.000 0.671 0.637 0.186 0.017 0.169 0.202 0.048 0.007 0.105))) (snd-display #__line__ ";ws nrxysin output: ~A" v1))) (let ((gen (make-nrxycos 440.0)) (v0 (make-float-vector 10)) (gen1 (make-nrxycos 440.0)) (v1 (make-float-vector 10))) (print-and-check gen "nrxycos" "nrxycos frequency: 440.000, ratio: 1.000, phase: 0.000, n: 1, r: 0.500") (do ((i 0 (+ i 1))) ((= i 10)) (set! (v0 i) (nrxycos gen 0.0))) (fill-float-vector v1 (if (nrxycos? gen1) (nrxycos gen1 0.0) -1.0)) (if (not (vequal v0 v1)) (snd-display #__line__ ";map nrxycos: ~A ~A" v0 v1)) (if (not (nrxycos? gen)) (snd-display #__line__ ";~A not nrxycos?" gen)) (if (fneq (mus-phase gen) 1.253787) (snd-display #__line__ ";nrxycos phase: ~F?" (mus-phase gen))) (if (fneq (mus-frequency gen) 440.0) (snd-display #__line__ ";nrxycos frequency: ~F?" (mus-frequency gen))) (if (fneq (mus-scaler gen) 0.5) (snd-display #__line__ ";mus-scaler (a) nrxycos: ~A" (mus-scaler gen))) (set! (mus-scaler gen) 0.75) (if (fneq (mus-scaler gen) 0.75) (snd-display #__line__ ";mus-scaler (set a) nrxycos: ~A" (mus-scaler gen))) (if (not (= (mus-length gen) 1)) (snd-display #__line__ ";mus-length nrxycos: ~A" (mus-length gen))) (if (fneq (mus-offset gen) 1.0) (snd-display #__line__ ";mus-offset nrxycos: ~A" (mus-offset gen)))) (test-gen-equal (make-nrxycos 440.0) (make-nrxycos 440.0) (make-nrxycos 100.0)) (test-gen-equal (make-nrxycos 440.0) (make-nrxycos 440.0) (make-nrxycos 440.0 1.5)) (test-gen-equal (make-nrxycos 440.0) (make-nrxycos 440.0) (make-nrxycos 440.0 :n 3)) (let ((v1 (with-sound ((make-float-vector 10) :srate 44100) (let ((gen (make-nrxycos 1000 :n 10 :r .99))) (do ((i 0 (+ i 1))) ((= i 10)) (outa i (nrxycos gen))))))) (if (not (vequal v1 (float-vector 1.000 0.602 -0.067 -0.242 -0.007 0.071 -0.087 -0.128 -0.007 0.012))) (snd-display #__line__ ";ws nrxycos output: ~A" v1))) (let ((gen (make-asymmetric-fm 440.0)) (v0 (make-float-vector 10)) (gen1 (make-asymmetric-fm 440.0)) (v1 (make-float-vector 10))) (print-and-check gen "asymmetric-fm" "asymmetric-fm freq: 440.000Hz, phase: 0.000, ratio: 1.000, r: 1.000") (do ((i 0 (+ i 1))) ((= i 10)) (set! (v0 i) (asymmetric-fm gen 0.0))) (fill-float-vector v1 (if (asymmetric-fm? gen1) (asymmetric-fm gen1 0.0) -1.0)) (if (not (vequal v0 v1)) (snd-display #__line__ ";map asymmetric-fm: ~A ~A" v0 v1)) (if (not (asymmetric-fm? gen)) (snd-display #__line__ ";~A not asymmetric-fm?" gen)) (if (fneq (mus-phase gen) 1.253787) (snd-display #__line__ ";asymmetric-fm phase: ~F?" (mus-phase gen))) (set! (mus-phase gen) 1.0) (if (fneq (mus-phase gen) 1.0) (snd-display #__line__ ";set! asymmetric-fm phase: ~F?" (mus-phase gen))) (if (fneq (mus-frequency gen) 440.0) (snd-display #__line__ ";asymmetric-fm frequency: ~F?" (mus-frequency gen))) (set! (mus-frequency gen) 100.0) (if (fneq (mus-frequency gen) 100.0) (snd-display #__line__ ";set! asymmetric-fm frequency: ~F?" (mus-frequency gen))) (if (or (fneq (v0 2) 0.969) (fneq (v0 8) .538)) (snd-display #__line__ ";asymmetric-fm output: ~A" v0)) (if (fneq (mus-scaler gen) 1.0) (snd-display #__line__ ";mus-scaler (r) asymmetric-fm: ~A" (mus-scaler gen))) (set! (mus-scaler gen) 0.5) (if (fneq (mus-scaler gen) 0.5) (snd-display #__line__ ";mus-scaler (set r) asymmetric-fm: ~A" (mus-scaler gen))) (if (fneq (mus-offset gen) 1.0) (snd-display #__line__ ";mus-offset asymmetric-fm: ~A" (mus-offset gen)))) (test-gen-equal (make-asymmetric-fm 440.0) (make-asymmetric-fm 440.0) (make-asymmetric-fm 100.0)) (test-gen-equal (make-asymmetric-fm 440.0) (make-asymmetric-fm 440.0) (make-asymmetric-fm 440.0 1.0)) (test-gen-equal (make-asymmetric-fm 440.0) (make-asymmetric-fm 440.0) (make-asymmetric-fm 440.0 0.0 3)) (let ((gen1 (make-asymmetric-fm 1000 0 1.0 0.1)) (gen2 (make-oscil 1000 :initial-phase (* 0.5 pi))) (happy #t)) (do ((i 0 (+ i 1))) ((or (not happy) (= i 100))) (let ((ss (asymmetric-fm gen1 0.0)) (os (oscil gen2 0.0))) (if (fneq ss os) (begin (snd-display #__line__ ";asymmetric-fm 1: ~A: os: ~A ss: ~A" i os ss) (set! happy #f)))))) (for-each (lambda (index) (for-each (lambda (r) (let ((peak (float-vector-peak (with-sound (:clipped #f :output (make-float-vector 1000)) (let ((gen (make-asymmetric-fm 2000.0 :ratio .1 :r r))) (do ((i 0 (+ i 1))) ((= i 1000)) (outa i (asymmetric-fm gen index)))))))) (if (> (abs (- peak 1.0)) .1) (snd-display #__line__ ";asymmetric-fm peak: ~A, index: ~A, r: ~A" peak index r)))) (list -10.0 -1.5 -0.5 0.5 1.0 1.5 10.0))) (list 1.0 3.0 10.0)) (let ((float-vector0 (make-float-vector 2048)) (float-vector1 (make-float-vector 2048)) (gen3 (make-asymmetric-fm 1000 0 1.0 0.2)) (gen4 (make-oscil 1000 (* 0.5 pi))) (gen5 (make-oscil 200)) (fm1 (hz->radians (* 1.0 .2 1000)))) ; make notions of "index" match (do ((i 0 (+ i 1))) ((= i 2048)) (set! (float-vector0 i) (asymmetric-fm gen3 1.0)) (set! (float-vector1 i) (oscil gen4 (* fm1 (oscil gen5))))) (let ((spectr1 (snd-spectrum float-vector0 rectangular-window 2048 #t)) (spectr2 (snd-spectrum float-vector1 rectangular-window 2048 #t)) (happy #t)) (do ((i 1 (+ i 1))) ((or (not happy) (= i 512))) (if (> (abs (- (spectr1 i) (spectr2 i))) .02) (begin (snd-display #__line__ ";asymmetric-fm 2: ~A: ~A ~A" i (spectr1 i) (spectr2 i)) (set! happy #f)))))) (let ((gen (make-asymmetric-fm 40.0 0.0 1.0 0.1)) (gen1 (make-asyfm :frequency 40.0 :ratio .1 :index 2.0)) (incr (/ (* 2 pi 40.0) *clm-srate*)) (r 1.0) (ratio 0.1) (index 2.0)) (let ((cr (* 0.5 (- r (/ 1.0 r)))) (sr (* 0.5 (+ r (/ 1.0 r))))) (do ((i 0 (+ i 1)) (a 0.0 (+ a incr))) ((= i 1100)) (let ((val1 (asymmetric-fm gen 2.0)) ; 1.0=index (val3 (asyfm-J gen1 0.0)) (mth (* ratio a))) (let ((val2 (* (exp (* index cr (+ 1.0 (cos mth)))) (cos (+ a (* index sr (sin mth))))))) (if (or (fneq val1 val2) (fneq val1 val3)) (snd-display #__line__ ";asyfm by hand: ~A: ~A ~A ~A" i val1 val2 val3))))))) (let ((float-vector0 (make-float-vector 2048)) (float-vector1 (make-float-vector 2048)) (gen3 (make-asymmetric-fm 1000 0 2.0 0.1)) (gen4 (make-asymmetric-fm 1000 0 0.5 0.1))) (do ((i 0 (+ i 1))) ((= i 2048)) (set! (float-vector0 i) (asymmetric-fm gen3 2.0)) (set! (float-vector1 i) (asymmetric-fm gen4 2.0))) (let ((spectr1 (snd-spectrum float-vector0 rectangular-window 2048 #t)) (spectr2 (snd-spectrum float-vector1 rectangular-window 2048 #t)) (s1-loc 0) (s2-loc 0)) (do ((i 1 (+ i 1))) ((= i 256)) (if (< (abs (- 1.0 (spectr1 i))) .01) (set! s1-loc i)) (if (< (abs (- 1.0 (spectr2 i))) .01) (set! s2-loc i))) (if (> s2-loc s1-loc) (snd-display #__line__ ";asymmetric-fm peaks: ~A ~A" s1-loc s2-loc)) (let ((center (* (/ 22050 2048) .5 (+ s1-loc s2-loc)))) (if (> (abs (- 1000 center)) 60) (snd-display #__line__ ";asymmetric-fm center: ~A" center))) (set! (mus-scaler gen3) 0.5) (do ((i 0 (+ i 1))) ((= i 2048)) (set! (float-vector0 i) (asymmetric-fm gen3 2.0))) (set! spectr1 (snd-spectrum float-vector0 rectangular-window 2048 #t)) (do ((i 1 (+ i 1))) ((= i 256)) (if (< (abs (- 1.0 (spectr1 i))) .01) (set! s1-loc i))) (if (not (= s2-loc s1-loc)) (snd-display #__line__ ";asymmetric-fm set r peaks: ~A ~A" s1-loc s2-loc)) (do ((i 0 (+ i 1))) ((= i 2048)) (set! (float-vector0 i) (asymmetric-fm gen3 2.0))) (snd-spectrum float-vector0 rectangular-window 2048 #t 0.0 #t) (do ((i 1 (+ i 1))) ((= i 256)) (if (< (abs (- 1.0 (float-vector0 i))) .01) (set! s1-loc i))) (if (not (= s2-loc s1-loc)) (snd-display #__line__ "asymmetric-fm set r in place peaks: ~A ~A" s1-loc s2-loc)))) (let ((gen (make-asyfm :frequency 2000 :ratio .1))) (asyfm-I gen 0.0)) (do ((i 2 (+ i 1))) ((= i 40)) (let ((v (make-float-vector i))) (do ((k 0 (+ k 1))) ((= k i)) (set! (v k) (expt 1.2 (- k)))) (let ((f (make-fir-filter i v))) (do ((k 0 (+ k 1)) (x 1.0 0.0)) ((= k i)) (let ((val (fir-filter f x)) (exval (expt 1.2 (- k)))) (if (> (abs (- val exval)) 1e-12) (format *stderr* ";for-filter ~D at ~D: ~A ~A~%" i k val exval))))))) (let ((f (make-fir-filter 3 (float-vector 1.0 .5 .25))) (v (make-float-vector 10))) (set! (v 0) (f 1.0)) (do ((i 1 (+ i 1))) ((= i 5)) (set! (v i) (f 0.0))) (set! (v 5) (f 1.0)) (do ((i 6 (+ i 1))) ((= i 10)) (set! (v i) (f 0.0))) (if (not (mus-arrays-equal? v (float-vector 1.0 0.5 .25 0.0 0.0 1.0 0.5 .25 0.0 0.0))) (format *stderr* ";f3: ~A~%" v))) (let ((f (make-fir-filter 7 (float-vector .7 .6 .5 .4 .3 .2 .1))) (v (make-float-vector 10))) (set! (v 0) (f 1.0)) (do ((i 1 (+ i 1))) ((= i 10)) (set! (v i) (f 0.0))) (if (not (mus-arrays-equal? v (float-vector .7 .6 .5 .4 .3 .2 .1 0.0 0.0 0.0))) (format *stderr* ";f7: ~A~%" v))) (let ((f (make-iir-filter 3 (float-vector 1.0 .5 .25))) (v (make-float-vector 10))) (set! (v 0) (f 1.0)) (do ((i 1 (+ i 1))) ((= i 5)) (set! (v i) (f 0.0))) (set! (v 5) (f 1.0)) (do ((i 6 (+ i 1))) ((= i 10)) (set! (v i) (f 0.0))) (if (not (mus-arrays-equal? v (float-vector 1.0 -0.5 0.0 0.125 -0.0625 1.0 -0.484375 -0.0078125 0.125 -0.060546875))) (format *stderr* ";i3: ~A~%" v))) (let ((f (make-iir-filter 7 (float-vector .7 .6 .5 .4 .3 .2 .1))) (v (make-float-vector 30))) (set! (v 0) (f 1.0)) (do ((i 1 (+ i 1))) ((= i 30)) (set! (v i) (f 0.0))) (if (not (mus-arrays-equal? v (float-vector 1.000000 -0.600000 -0.140000 -0.016000 0.019600 0.032240 0.039256 0.045286 -0.048376 -0.021312 -0.001324 0.006140 0.007033 0.004780 0.000657 -0.005043 -0.002420 0.000256 0.001217 0.001013 0.000350 -0.000292 -0.000579 -0.000219 0.000109 0.000192 0.000115 0.000002 -0.000067 -0.000065))) (begin (format *stderr* ";i7: ") (do ((i 0 (+ i 1))) ((= i 30)) (format *stderr* "~,6f " (v i))) (format *stderr* "~%")))) (let ((x (make-float-vector 3)) (y (make-float-vector 3))) (do ((i 0 (+ i 1))) ((= i 3)) (set! (x i) (expt 1.2 (- i))) (set! (y i) (expt 1.5 (- i)))) (let ((f (make-filter 3 x y)) (v (make-float-vector 10))) (set! (v 0) (f 1.0)) (do ((i 1 (+ i 1))) ((= i 10)) (set! (v i) (f 0.0))) (if (not (mus-arrays-equal? v (float-vector 1.000000 0.166667 0.138889 -0.166667 0.049383 0.041152 -0.049383 0.014632 0.012193 -0.014632))) (begin (format *stderr* ";g3: ") (do ((i 0 (+ i 1))) ((= i 10)) (format *stderr* "~,6f " (v i))) (format *stderr* "~%"))))) (let ((x (make-float-vector 9)) (y (make-float-vector 9))) (do ((i 0 (+ i 1))) ((= i 9)) (set! (x i) (expt 1.2 (- i))) (set! (y i) (expt 1.2 (- i)))) (let ((f (make-filter 9 x y)) (v (make-float-vector 30))) (set! (v 0) (f 1.0)) (do ((i 1 (+ i 1))) ((= i 30)) (set! (v i) (f 0.0))) (if (not (mus-arrays-equal? v (float-vector 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0))) (begin (format *stderr* ";g9: ") (do ((i 0 (+ i 1))) ((= i 30)) (format *stderr* "~,6f " (v i))) (format *stderr* "~%"))))) (let ((x (make-float-vector 9)) (y (make-float-vector 9))) (do ((i 0 (+ i 1))) ((= i 9)) (set! (x i) (expt 1.2 (- i))) (set! (y i) (expt 1.5 (- i)))) (let ((f (make-filter 9 x y)) (v (make-float-vector 30))) (set! (v 0) (f 1.0)) (do ((i 1 (+ i 1))) ((= i 30)) (set! (v i) (f 0.0))) (if (not (mus-arrays-equal? v (float-vector 1.000000 0.166667 0.138889 0.115741 0.096451 0.080376 0.066980 0.055816 0.046514 -0.129033 0.004335 0.003613 0.003011 0.002509 0.002091 0.001742 0.001452 0.001210 -0.003356 0.000113 0.000094 0.000078 0.000065 0.000054 0.000045 0.000038 0.000031 -0.000087 0.000003 0.000002))) (begin (format *stderr* ";g9e: ") (do ((i 0 (+ i 1))) ((= i 30)) (format *stderr* "~,6f " (v i))) (format *stderr* "~%"))))) (let ((x (make-float-vector 8)) (y (make-float-vector 8))) (do ((i 0 (+ i 1))) ((= i 8)) (set! (x i) (expt 1.5 (- i))) (set! (y i) (expt 1.2 (- i)))) (let ((f (make-filter 8 x y)) (v (make-float-vector 30))) (set! (v 0) (f 1.0)) (do ((i 1 (+ i 1))) ((= i 30)) (set! (v i) (f 0.0))) (if (not (mus-arrays-equal? v (float-vector 1.000000 -0.166667 -0.111111 -0.074074 -0.049383 -0.032922 -0.021948 -0.014632 0.183795 -0.038761 -0.025841 -0.017227 -0.011485 -0.007657 -0.005104 -0.003403 0.042745 -0.009015 -0.006010 -0.004007 -0.002671 -0.001781 -0.001187 -0.000791 0.009941 -0.002097 -0.001398 -0.000932 -0.000621 -0.000414))) (begin (format *stderr* ";g-8: ") (do ((i 0 (+ i 1))) ((= i 30)) (format *stderr* "~,6f " (v i))) (format *stderr* "~%"))))) (let ((x (make-float-vector 18)) (y (make-float-vector 18))) (do ((i 0 (+ i 1))) ((= i 18)) (set! (x i) (expt 1.5 (- i))) (set! (y i) (expt 1.2 (- i)))) (let ((f (make-filter 18 x y)) (v (make-float-vector 30))) (set! (v 0) (f 1.0)) (do ((i 1 (+ i 1))) ((= i 30)) (set! (v i) (f 0.0))) (if (not (mus-arrays-equal? v (float-vector 1.000000 -0.166667 -0.111111 -0.074074 -0.049383 -0.032922 -0.021948 -0.014632 -0.009755 -0.006503 -0.004335 -0.002890 -0.001927 -0.001285 -0.000856 -0.000571 -0.000381 -0.000254 0.036715 -0.006260 -0.004173 -0.002782 -0.001855 -0.001237 -0.000824 -0.000550 -0.000366 -0.000244 -0.000163 -0.000109))) (begin (format *stderr* ";g-18: ") (do ((i 0 (+ i 1))) ((= i 30)) (format *stderr* "~,6f " (v i))) (format *stderr* "~%"))))) (let ((x (make-float-vector 9)) (y (make-float-vector 9))) (do ((i 0 (+ i 1))) ((= i 9)) (set! (x i) (expt 1.5 (- i))) (set! (y i) (expt 1.2 (- i)))) (let ((f (make-filter 9 x y)) (v (make-float-vector 30))) (set! (v 0) (f 1.0)) (do ((i 1 (+ i 1))) ((= i 30)) (set! (v i) (f 0.0))) (if (not (mus-arrays-equal? v (float-vector 1.000000 -0.166667 -0.111111 -0.074074 -0.049383 -0.032922 -0.021948 -0.014632 -0.009755 0.161291 -0.032301 -0.021534 -0.014356 -0.009571 -0.006380 -0.004254 -0.002836 -0.001891 0.031259 -0.006260 -0.004173 -0.002782 -0.001855 -0.001237 -0.000824 -0.000550 -0.000366 0.006058 -0.001213 -0.000809))) (begin (format *stderr* ";g-9: ") (do ((i 0 (+ i 1))) ((= i 30)) (format *stderr* "~,6f " (v i))) (format *stderr* "~%"))))) (let ((gen (make-fir-filter 3 (float-vector .5 .25 .125))) (v0 (make-float-vector 10)) (gen1 (make-fir-filter 3 (float-vector .5 .25 .125))) (v1 (make-float-vector 10))) (print-and-check gen "fir-filter" "fir-filter order: 3, xs: [0.5 0.25 0.125]" ) (set! (v0 0) (fir-filter gen 1.0)) (do ((i 1 (+ i 1))) ((= i 10)) (set! (v0 i) (fir-filter gen 0.0))) (let ((inp 1.0)) (fill-float-vector v1 (let ((val (if (fir-filter? gen1) (fir-filter gen1 inp) -1.0))) (set! inp 0.0) val))) (if (not (vequal v0 v1)) (snd-display #__line__ ";map fir-filter: ~A ~A" v0 v1)) (if (not (fir-filter? gen)) (snd-display #__line__ ";~A not fir-filter?" gen)) (if (not (= (mus-length gen) 3)) (snd-display #__line__ ";fir-filter length: ~D?" (mus-length gen))) (if (or (fneq (v0 1) 0.25) (fneq (v0 2) .125)) (snd-display #__line__ ";fir-filter output: ~A" v0)) (let ((data (mus-xcoeffs gen))) (if (fneq (data 1) .25) (snd-display #__line__ ";fir-filter xcoeffs: ~A?" data))) (let ((tag (catch #t (lambda () (mus-xcoeff gen 123)) (lambda args (car args))))) (if (not (eq? tag 'mus-error)) (snd-display #__line__ ";xcoeff 123: ~A" tag))) (let ((tag (catch #t (lambda () (mus-ycoeff gen 123)) (lambda args (car args))))) (if (not (eq? tag 'mus-error)) (snd-display #__line__ ";fir ycoeff 123: ~A" tag)))) (test-gen-equal (let ((f1 (make-fir-filter 3 (float-vector .5 .25 .125)) )) (fir-filter f1 1.0) f1) (let ((f2 (make-fir-filter 3 (float-vector .5 .25 .125)) )) (fir-filter f2 1.0) f2) (let ((f3 (make-fir-filter 3 (float-vector .75 .25 .125)))) (fir-filter f3 1.0) f3)) (test-gen-equal (let ((f1 (make-fir-filter 3 (float-vector .5 .25 .125)) )) (fir-filter f1 1.0) f1) (let ((f2 (make-fir-filter 3 (float-vector .5 .25 .125)) )) (fir-filter f2 1.0) f2) (let ((f3 (make-fir-filter 2 (float-vector .5 .25)))) (fir-filter f3 1.0) f3)) (let* ((coeffs (float-vector .1 .2 .3 .4 .4 .3 .2 .1)) (flt (make-fir-filter 8 coeffs)) (xcof (mus-xcoeffs flt)) (es (make-vector 8))) (do ((i 0 (+ i 1))) ((= i 8)) (set! (es i) (make-env (list 0 (coeffs i) 1 0) :length 102))) (set! (es 5) (make-env '(0 .4 1 1) :length 102)) (let ((data (make-float-vector 100))) (do ((k 0 (+ k 1))) ((= k 100)) (set! (data k) (fir-filter flt (if (= (modulo k 12) 0) 1.0 0.0))) (do ((i 0 (+ i 1))) ((= i 8)) (float-vector-set! xcof i (env (vector-ref es i))))) (if (or (fneq (data 1) .2) (fneq (data 10) 0.0) (fneq (data 18) 0.166) (fneq (data 89) 0.923)) (snd-display #__line__ ";filter xcoeffs: ~A?" data)))) (letrec ((make-f-filter (lambda (coeffs) (list coeffs (make-float-vector (length coeffs))))) (f-filter (lambda (flt x) (let* ((coeffs (car flt)) (xs (cadr flt)) (xlen (length xs))) (float-vector-move! xs (- xlen 1) (- xlen 2) #t) (set! (xs 0) x) (dot-product coeffs xs xlen))))) (let ((fir1 (make-fir-filter 3 (float-vector 1.0 0.4 0.1))) (fir2 (make-f-filter (float-vector 1.0 0.4 0.1))) (x 1.0) (happy #t)) (do ((i 0 (+ i 1))) ((or (not happy) (= i 10))) (let ((val1 (fir-filter fir1 x)) (val2 (f-filter fir2 x))) (set! x 0.0) (if (fneq val1 val2) (begin (snd-display #__line__ ";f-filter ~A -> ~A ~A" i val1 val2) (set! happy #f))))))) (let ((gen (make-spencer-filter))) (if (not (fir-filter? gen)) (snd-display #__line__ ";make-spencer-filter returns ~A?" gen) (begin (if (not (= (mus-order gen) 15)) (snd-display #__line__ ";make-spencer-filter order ~A?" (mus-order gen))) (if (not (vequal (mus-xcoeffs gen) (float-vector -0.009 -0.019 -0.016 0.009 0.066 0.144 0.209 0.231 0.209 0.144 0.066 0.009 -0.016 -0.019 -0.009))) (snd-display #__line__ ";make-spencer-filter coeffs: ~A" (mus-xcoeffs gen)))))) (let ((flt (make-savitzky-golay-filter 5 2))) (if (not (vequal (mus-xcoeffs flt) (float-vector -0.086 0.343 0.486 0.343 -0.086))) (snd-display #__line__ ";sg 5 2: ~A" (mus-xcoeffs flt)))) (let ((flt (make-savitzky-golay-filter 11 2))) (if (not (vequal (mus-xcoeffs flt) (float-vector -0.084 0.021 0.103 0.161 0.196 0.207 0.196 0.161 0.103 0.021 -0.084))) (snd-display #__line__ ";sg 11 2: ~A" (mus-xcoeffs flt)))) (let ((flt (make-savitzky-golay-filter 11 4))) (if (not (vequal (mus-xcoeffs flt) (float-vector 0.042 -0.105 -0.023 0.140 0.280 0.333 0.280 0.140 -0.023 -0.105 0.042))) (snd-display #__line__ ";sg 11 4: ~A" (mus-xcoeffs flt)))) (let ((flt (make-savitzky-golay-filter 25 2))) (if (not (vequal (mus-xcoeffs flt) (float-vector -0.049 -0.027 -0.006 0.012 0.028 0.043 0.055 0.066 0.075 0.082 0.086 0.089 0.090 0.089 0.086 0.082 0.075 0.066 0.055 0.043 0.028 0.012 -0.006 -0.027 -0.049))) (snd-display #__line__ ";sg 25 2: ~A" (mus-xcoeffs flt)))) (let ((gen (make-iir-filter 3 (float-vector .5 .25 .125))) (v0 (make-float-vector 10)) (gen1 (make-iir-filter 3 (float-vector .5 .25 .125))) (v1 (make-float-vector 10))) (print-and-check gen "iir-filter" "iir-filter order: 3, ys: [0.5 0.25 0.125]" ) (set! (v0 0) (iir-filter gen 1.0)) (do ((i 1 (+ i 1))) ((= i 10)) (set! (v0 i) (iir-filter gen 0.0))) (let ((inp 1.0)) (fill-float-vector v1 (let ((val (if (iir-filter? gen1) (iir-filter gen1 inp) -1.0))) (set! inp 0.0) val))) (if (not (vequal v0 v1)) (snd-display #__line__ ";map iir-filter: ~A ~A" v0 v1)) (if (not (iir-filter? gen)) (snd-display #__line__ ";~A not iir-filter?" gen)) (if (not (= (mus-length gen) 3)) (snd-display #__line__ ";iir-filter length: ~D?" (mus-length gen))) (if (or (fneq (v0 1) -0.25) (fneq (v0 2) -.062)) (snd-display #__line__ ";iir-filter output: ~A" v0)) (let ((data (mus-ycoeffs gen))) (if (fneq (data 1) .25) (snd-display #__line__ ";iir-filter ycoeffs: ~A?" data))) (let ((tag (catch #t (lambda () (mus-ycoeff gen 123)) (lambda args (car args))))) (if (not (eq? tag 'mus-error)) (snd-display #__line__ ";ycoeff 123: ~A" tag))) (let ((tag (catch #t (lambda () (mus-xcoeff gen 123)) (lambda args (car args))))) (if (not (eq? tag 'mus-error)) (snd-display #__line__ ";iir xcoeff 123: ~A" tag)))) (test-gen-equal (let ((f1 (make-iir-filter 3 (float-vector .5 .25 .125)))) (iir-filter f1 1.0) f1) (let ((f2 (make-iir-filter 3 (float-vector .5 .25 .125)) )) (iir-filter f2 1.0) f2) (let ((f3 (make-iir-filter 3 (float-vector .75 .25 .125)))) (iir-filter f3 1.0) f3)) (test-gen-equal (let ((f1 (make-iir-filter 3 (float-vector .5 .25 .125)) )) (iir-filter f1 1.0) f1) (let ((f2 (make-iir-filter 3 (float-vector .5 .25 .125)) )) (iir-filter f2 1.0) f2) (let ((f3 (make-iir-filter 2 (float-vector .5 .25)))) (iir-filter f3 1.0) f3)) (let ((gen (make-filter 3 (float-vector .5 .25 .125) (float-vector .5 .25 .125))) (v0 (make-float-vector 10)) (gen1 (make-filter 3 (float-vector .5 .25 .125) (float-vector .5 .25 .125))) (v1 (make-float-vector 10)) (gen2 (make-biquad .1 .2 .3 .4 .5))) (print-and-check gen "filter" "filter order: 3, xs: [0.5 0.25 0.125], ys: [0.5 0.25 0.125]" ) (set! (v0 0) (filter gen 1.0)) (do ((i 1 (+ i 1))) ((= i 10)) (set! (v0 i) (filter gen 0.0))) (let ((inp 1.0)) (fill-float-vector v1 (let ((val (if (filter? gen1) (filter gen1 inp) -1.0))) (set! inp 0.0) val))) (if (not (vequal v0 v1)) (snd-display #__line__ ";map filter: ~A ~A" v0 v1)) (if (not (filter? gen)) (snd-display #__line__ ";~A not filter?" gen)) (if (not (= (mus-length gen) 3)) (snd-display #__line__ ";filter length: ~D?" (mus-length gen))) (if (or (fneq (v0 1) 0.125) (fneq (v0 2) .031)) (snd-display #__line__ ";filter output: ~A" v0)) (if (not (filter? gen2)) (snd-display #__line__ ";make-biquad: ~A" gen2)) (let ((xs (mus-xcoeffs gen)) (ys (mus-ycoeffs gen))) (if (or (not (equal? xs (float-vector .5 .25 .125))) (not (equal? xs ys))) (snd-display #__line__ ";mus-xcoeffs: ~A ~A?" xs ys)))) (let ((var (catch #t (lambda () (make-filter :order 2 :xcoeffs (float-vector 1.0 0.5) :ycoeffs (float-vector 2.0 1.0 0.5))) (lambda args args)))) (if (not (eq? (car var) 'mus-error)) (snd-display #__line__ ";make-filter bad coeffs: ~A" var))) (let ((var (catch #t (lambda () (make-filter :order 0 :xcoeffs (float-vector 1.0 0.5))) (lambda args args)))) (if (not (eq? (car var) 'out-of-range)) (snd-display #__line__ ";make-filter bad order: ~A" var))) (let ((var (catch #t (lambda () (make-fir-filter :order 22 :xcoeffs (float-vector 1.0 0.5))) (lambda args args)))) (if (not (eq? (car var) 'mus-error)) (snd-display #__line__ ";make-fir-filter bad coeffs: ~A" var))) (let ((var (catch #t (lambda () (make-iir-filter :order 22 :ycoeffs (float-vector 1.0 0.5))) (lambda args args)))) (if (not (eq? (car var) 'mus-error)) (snd-display #__line__ ";make-iir-filter bad coeffs: ~A" var))) (let ((var (catch #t (lambda () (make-fir-filter -1)) (lambda args args)))) (if (not (eq? (car var) 'out-of-range)) (snd-display #__line__ ";make-fir-filter bad order: ~A" var))) (let ((var (make-filter :order 2 :ycoeffs (float-vector 1.0 0.5)))) (if (not (iir-filter? var)) (snd-display #__line__ ";make-filter with only y: ~A" var))) (test-gen-equal (let ((f1 (make-filter 3 (float-vector .5 .25 .125) (float-vector .5 .25 .125)))) (filter f1 1.0) f1) (let ((f2 (make-filter 3 (float-vector .5 .25 .125) (float-vector .5 .25 .125)))) (filter f2 1.0) f2) (let ((f3 (make-filter 3 (float-vector .5 .25 .125) (float-vector .5 .5 .5)))) (filter f3 1.0) f3)) (test-gen-equal (let ((f1 (make-filter 3 (float-vector .5 .25 .125) (float-vector .5 .25 .125)))) (filter f1 1.0) f1) (let ((f2 (make-filter 3 (float-vector .5 .25 .125) (float-vector .5 .25 .125)))) (filter f2 1.0) f2) (let ((f3 (make-filter 3 (float-vector .5 .5 .125) (float-vector .5 .25 .0625)))) (filter f3 1.0) f3)) (let ((fr (make-fir-filter 6 (float-vector 0 1 2 3 4 5)))) (if (not (= (mus-length fr) 6)) (snd-display #__line__ ";filter-length: ~A" (mus-length fr)))) (let ((val (cascade->canonical (list (float-vector 1.0 0.0 0.0) (float-vector 1.0 0.5 0.25))))) (if (not (vequal val (float-vector 1.000 0.500 0.250 0.000 0.000))) (snd-display #__line__ ";cas2can 0: ~A" val))) (let ((val (cascade->canonical (list (float-vector 1.0 1.0 0.0) (float-vector 1.0 0.5 0.25))))) (if (not (vequal val (float-vector 1.000 1.500 0.750 0.250 0.000))) (snd-display #__line__ ";cas2can 1: ~A" val))) (let ((val (cascade->canonical (list (float-vector 1 0.8 0) (float-vector 1 1.4 0.65) (float-vector 1 0 0))))) (if (not (vequal val (float-vector 1.000 2.200 1.770 0.520 0.000 0.000 0.000))) (snd-display #__line__ ";cascade->canonical: ~A" val))) (let ((val (cascade->canonical (list (float-vector 1 -0.9 0) (float-vector 1 1 0.74) (float-vector 1 -1.6 0.8))))) (if (not (vequal val (float-vector 1.000 -1.500 0.480 -0.330 0.938 -0.533 0.000))) (snd-display #__line__ ";cascade->canonical 1: ~A" val))) (let ((ind (new-sound "test.snd" 1 22050 mus-ldouble mus-next))) (pad-channel 0 10000) (freq-sweep .45) (let ((sp (rough-spectrum ind))) (if (and (not (vequal sp (float-vector 0.962 0.998 0.998 0.998 0.998 0.999 0.999 0.998 0.997 1.000))) (not (vequal sp (float-vector 0.963 0.999 0.999 0.999 0.999 0.999 1.000 1.000 0.998 0.997)))) (snd-display #__line__ ";initial rough spectrum: ~A" sp))) (let ((b (make-butter-high-pass 440.0)) (v (make-float-vector 10)) (d (make-delay 1))) (delay d (filter b 1.0)) (fill-float-vector v (delay d (filter b 0.0))) (if (not (vequal v (float-vector 0.915 -0.162 -0.146 -0.131 -0.117 -0.103 -0.090 -0.078 -0.066 -0.056))) (snd-display #__line__ ";butter high: ~A" v)) (set! b (make-butter-high-pass 1000.0)) (map-channel (lambda (y) (filter b y))) (let ((sp (rough-spectrum ind))) (if (and (not (vequal sp (float-vector 0.150 0.833 0.980 0.994 0.997 0.998 0.999 0.998 0.997 1.000))) (not (vequal sp (float-vector 0.150 0.833 0.981 0.995 0.998 0.999 1.000 1.000 0.998 0.997)))) (snd-display #__line__ ";hp rough spectrum: ~A" sp))) (undo)) (let ((b (make-butter-low-pass 440.0)) (v (make-float-vector 10)) (d (make-delay 1))) (delay d (filter b 1.0)) (fill-float-vector v (delay d (filter b 0.0))) (if (not (vequal v (float-vector 0.004 0.014 0.026 0.035 0.043 0.049 0.053 0.055 0.057 0.057))) (snd-display #__line__ ";butter low: ~A" v)) (set! b (make-butter-low-pass 1000.0)) (map-channel (lambda (y) (filter b y))) (let ((sp (rough-spectrum ind))) (if (not (vequal sp (float-vector 1.000 0.212 0.024 0.005 0.001 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";lp rough spectrum: ~A" sp))) (undo)) (let ((b (make-butter-band-pass 440.0 50.0)) (v (make-float-vector 10)) (d (make-delay 1))) (delay d (filter b 1.0)) (fill-float-vector v (delay d (filter b 0.0))) (if (not (vequal v (float-vector 0.007 0.014 0.013 0.013 0.012 0.011 0.009 0.008 0.007 0.005))) (snd-display #__line__ ";butter bandpass: ~A" v)) (set! b (make-butter-band-pass 1000.0 500.0)) (map-channel (lambda (y) (filter b y))) (let ((sp (rough-spectrum ind))) (if (not (vequal sp (float-vector 0.888 1.000 0.144 0.056 0.027 0.014 0.008 0.004 0.002 0.000))) (snd-display #__line__ ";bp rough spectrum: ~A" sp))) (undo)) (let ((b (make-butter-band-reject 440.0 50.0)) (v (make-float-vector 10)) (d (make-delay 1))) (delay d (filter b 1.0)) (fill-float-vector v (delay d (filter b 0.0))) (if (not (vequal v (float-vector 0.993 -0.014 -0.013 -0.013 -0.012 -0.011 -0.009 -0.008 -0.007 -0.005))) (snd-display #__line__ ";butter bandstop: ~A" v)) (set! b (make-butter-band-reject 1000.0 500.0)) (map-channel (lambda (y) (filter b y))) (let ((sp (rough-spectrum ind))) (if (and (not (vequal sp (float-vector 0.662 0.687 0.953 0.980 0.989 0.994 0.997 0.997 0.997 1.000))) (not (vequal sp (float-vector 0.664 0.689 0.955 0.982 0.992 0.996 0.999 1.000 0.999 0.998)))) (snd-display #__line__ ";bs rough spectrum: ~A" sp))) (undo)) (if (defined? 'gsl-roots) (analog-filter-tests)) (test-lpc) (test-unclip-channel) (let ((v (spectrum->coeffs 10 (float-vector 0 1.0 0 0 0 0 0 0 1.0 0))) (v1 (make-fir-coeffs 10 (float-vector 0 1.0 0 0 0 0 0 0 1.0 0)))) (if (not (vequal v (float-vector -0.190 -0.118 0.000 0.118 0.190 0.190 0.118 0.000 -0.118 -0.190))) (snd-display #__line__ ";spectrum->coeffs: ~A" v)) (if (not (vequal v v1)) (snd-display #__line__ ";spectrum->coeffs v make-fir-coeffs: ~A ~A" v v1))) (let ((notched-spectr (make-float-vector 20))) (set! (notched-spectr 2) 1.0) (let ((v (spectrum->coeffs 20 notched-spectr)) (v1 (make-fir-coeffs 20 notched-spectr))) (if (not (vequal v (float-vector 0.095 0.059 -0.000 -0.059 -0.095 -0.095 -0.059 0.000 0.059 0.095 0.095 0.059 0.000 -0.059 -0.095 -0.095 -0.059 -0.000 0.059 0.095))) (snd-display #__line__ ";spectrum->coeffs (notch): ~A" v)) (if (not (vequal v v1)) (snd-display #__line__ ";spectrum->coeffs v(2) make-fir-coeffs: ~A ~A" v v1)) (let ((flt (make-fir-filter 20 v))) (map-channel (lambda (y) (fir-filter flt y))))) (let ((sp (rough-spectrum ind))) (if (not (vequal sp (float-vector 0.007 0.493 1.000 0.068 0.030 0.019 0.014 0.011 0.009 0.009))) (snd-display #__line__ ";sp->coeff rough spectrum: ~A" sp))) (undo)) (let ((rspect (make-float-vector 20))) (do ((i 0 (+ i 1))) ((= i 20)) (set! (rspect i) (random 1.0))) (let ((v (spectrum->coeffs 20 rspect)) (v1 (make-fir-coeffs 20 rspect))) (if (not (vequal v v1)) (snd-display #__line__ ";spectrum->coeffs v(3) make-fir-coeffs: ~A ~A" v v1)))) (let ((b (make-highpass (hz->radians 1000.0) 10)) (v (make-float-vector 20)) (d (make-delay 1))) (delay d (fir-filter b 1.0)) (fill-float-vector v (delay d (fir-filter b 0.0))) (if (not (vequal v (float-vector -0.001 -0.002 -0.005 -0.011 -0.021 -0.034 -0.049 -0.065 -0.078 -0.087 0.909 -0.087 -0.078 -0.065 -0.049 -0.034 -0.021 -0.011 -0.005 -0.002))) (snd-display #__line__ ";dsp.scm high: ~A" v)) (set! b (make-highpass (hz->radians 1000.0) 20)) (map-channel (lambda (y) (fir-filter b y))) (let ((sp (rough-spectrum ind))) (if (and (not (vequal sp (float-vector 0.053 0.774 0.998 0.997 0.997 0.996 0.996 0.996 0.997 1.000))) (not (vequal sp (float-vector 0.053 0.776 1.000 0.998 0.998 0.998 0.998 0.998 0.998 1.000)))) (snd-display #__line__ ";dsp hp rough spectrum: ~A" sp))) (undo)) (let ((b (make-lowpass (hz->radians 1000.0) 10)) (v (make-float-vector 20)) (d (make-delay 1))) (delay d (fir-filter b 1.0)) (fill-float-vector v (delay d (fir-filter b 0.0))) (if (not (vequal v (float-vector 0.001 0.002 0.005 0.011 0.021 0.034 0.049 0.065 0.078 0.087 0.091 0.087 0.078 0.065 0.049 0.034 0.021 0.011 0.005 0.002))) (snd-display #__line__ ";dsp.scm low: ~A" v)) (set! b (make-lowpass (hz->radians 1000.0) 20)) (map-channel (lambda (y) (fir-filter b y))) (let ((sp (rough-spectrum ind))) (if (not (vequal sp (float-vector 1.000 0.054 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";dsp lp rough spectrum: ~A" sp))) (undo)) (let ((b (make-bandpass (hz->radians 1500.0) (hz->radians 2000.0) 10)) (v (make-float-vector 20)) (d (make-delay 1))) (delay d (fir-filter b 1.0)) (fill-float-vector v (delay d (fir-filter b 0.0))) (if (not (vequal v (float-vector 0.001 -0.001 -0.005 -0.011 -0.017 -0.019 -0.013 0.003 0.022 0.039 0.045 0.039 0.022 0.003 -0.013 -0.019 -0.017 -0.011 -0.005 -0.001))) (snd-display #__line__ ";dsp.scm bp: ~A" v)) (set! b (make-bandpass (hz->radians 1500.0) (hz->radians 2000.0) 20)) (map-channel (lambda (y) (fir-filter b y))) (let ((sp (rough-spectrum ind))) (if (not (vequal sp (float-vector 0.010 1.000 0.154 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";dsp bp rough spectrum: ~A" sp))) (undo)) (let ((b (make-bandstop (hz->radians 1500.0) (hz->radians 2000.0) 10)) (v (make-float-vector 20)) (d (make-delay 1))) (delay d (fir-filter b 1.0)) (fill-float-vector v (delay d (fir-filter b 0.0))) (if (not (vequal v (float-vector -0.001 0.001 0.005 0.011 0.017 0.019 0.013 -0.003 -0.022 -0.039 0.955 -0.039 -0.022 -0.003 0.013 0.019 0.017 0.011 0.005 0.001))) (snd-display #__line__ ";dsp.scm bs: ~A" v)) (set! b (make-bandstop (hz->radians 1500.0) (hz->radians 2000.0) 20)) (map-channel (lambda (y) (fir-filter b y))) (let ((sp (rough-spectrum ind))) (if (and (not (vequal sp (float-vector 0.904 0.425 0.821 0.998 0.997 0.996 0.996 0.996 0.997 1.000))) (not (vequal sp (float-vector 0.906 0.425 0.822 1.000 0.999 0.998 0.998 0.998 0.998 1.000)))) (snd-display #__line__ ";dsp bs rough spectrum: ~A" sp))) (undo)) (let ((b (make-differentiator 10)) (v (make-float-vector 20)) (d (make-delay 1))) (delay d (fir-filter b 1.0)) (fill-float-vector v (delay d (fir-filter b 0.0))) (if (not (vequal v (float-vector -0.008 0.011 -0.021 0.039 -0.066 0.108 -0.171 0.270 -0.456 0.977 0.000 -0.977 0.456 -0.270 0.171 -0.108 0.066 -0.039 0.021 -0.011))) (snd-display #__line__ ";dsp.scm df: ~A" v)) (set! b (make-differentiator 20)) (map-channel (lambda (y) (fir-filter b y))) (let ((sp (rough-spectrum ind))) (if (not (vequal sp (float-vector 0.004 0.027 0.075 0.147 0.242 0.362 0.506 0.674 0.864 1.000))) (snd-display #__line__ ";dsp df rough spectrum: ~A" sp))) (undo)) (let ((b (make-iir-high-pass-2 440.0)) (v (make-float-vector 10)) (d (make-delay 1))) (delay d (filter b 1.0)) (fill-float-vector v (delay d (filter b 0.0))) (if (not (vequal v (float-vector 0.915 -0.162 -0.146 -0.131 -0.117 -0.103 -0.090 -0.078 -0.066 -0.056))) (snd-display #__line__ ";iir-2 high: ~A" v)) (set! b (make-iir-high-pass-2 1000.0)) (map-channel (lambda (y) (filter b y))) (let ((sp (rough-spectrum ind))) (if (and (not (vequal sp (float-vector 0.150 0.833 0.980 0.994 0.997 0.998 0.999 0.998 0.997 1.000))) (not (vequal sp (float-vector 0.150 0.833 0.981 0.995 0.998 0.999 1.000 1.000 0.998 0.997)))) (snd-display #__line__ ";iir-2 hp rough spectrum: ~A" sp))) (undo)) (let ((b (make-iir-low-pass-2 440.0)) (v (make-float-vector 10)) (d (make-delay 1))) (delay d (filter b 1.0)) (fill-float-vector v (delay d (filter b 0.0))) (if (not (vequal v (float-vector 0.004 0.014 0.026 0.035 0.043 0.049 0.053 0.055 0.057 0.057))) (snd-display #__line__ ";iir-2 low: ~A" v)) (set! b (make-iir-low-pass-2 1000.0)) (map-channel (lambda (y) (filter b y))) (let ((sp (rough-spectrum ind))) (if (not (vequal sp (float-vector 1.000 0.212 0.024 0.005 0.001 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";iir-2 lp rough spectrum: ~A" sp))) (undo)) (let ((b (make-iir-band-pass-2 440.0 490.0)) (v (make-float-vector 10)) (d (make-delay 1))) (delay d (filter b 1.0)) (fill-float-vector v (delay d (filter b 0.0))) (if (not (vequal v (float-vector 0.007 0.014 0.013 0.013 0.012 0.010 0.009 0.008 0.006 0.004))) (snd-display #__line__ ";iir bp-2 bandpass: ~A" v)) (set! b (make-iir-band-pass-2 1000.0 1500.0)) (map-channel (lambda (y) (filter b y))) (let ((sp (rough-spectrum ind))) (if (not (vequal sp (float-vector 0.239 1.000 0.117 0.041 0.019 0.010 0.005 0.003 0.001 0.000))) (snd-display #__line__ ";iir bp-2 rough spectrum: ~A" sp))) (undo)) (let ((b (make-iir-band-stop-2 440.0 500.0)) (v (make-float-vector 10)) (d (make-delay 1))) (delay d (filter b 1.0)) (fill-float-vector v (delay d (filter b 0.0))) (if (not (vequal v (float-vector 0.992 -0.017 -0.016 -0.015 -0.014 -0.012 -0.011 -0.009 -0.007 -0.005))) (snd-display #__line__ ";iir-2 bandstop: ~A" v)) (set! b (make-iir-band-stop-2 1000.0 1500.0)) (map-channel (lambda (y) (filter b y))) (let ((sp (rough-spectrum ind))) (if (and (not (vequal sp (float-vector 0.836 0.525 0.943 0.979 0.989 0.994 0.997 0.997 0.997 1.000))) (not (vequal sp (float-vector 0.838 0.527 0.945 0.981 0.991 0.996 0.999 1.000 0.999 0.998)))) (snd-display #__line__ ";iir bs-2 rough spectrum: ~A" sp))) (undo)) (let ((b (make-butter-hp 4 440.0)) (v (make-float-vector 10)) (d (make-delay 1))) (delay d (filter b 1.0)) (fill-float-vector v (delay d (filter b 0.0))) (if (and (not (vequal v (float-vector 0.725 -0.466 -0.315 -0.196 -0.104 -0.036 0.014 0.047 0.0685 0.0775))) (not (vequal v (float-vector 0.725 -0.466 -0.315 -0.196 -0.104 -0.035 0.015 0.049 0.070 0.081))) (not (vequal v (float-vector 0.725 -0.466 -0.315 -0.196 -0.104 -0.035 0.014 0.049 0.069 0.079)))) (snd-display #__line__ ";butter hp: ~A" v)) (set! b (make-butter-hp 4 1000.0)) (map-channel (lambda (y) (filter b y))) (let ((sp (rough-spectrum ind))) (if (and (not (vequal sp (float-vector 0.0505 0.982 1.000 1.000 0.998 0.998 0.999 0.998 0.996 0.999))) (not (vequal sp (float-vector 0.051 0.982 1.000 1.000 0.998 0.998 0.998 0.999 0.997 0.995))) (not (vequal sp (float-vector 0.051 0.991 1.000 1.000 0.998 0.998 0.999 0.999 0.997 0.995))) (not (vequal sp (float-vector 0.045 0.970 1.000 1.000 0.998 0.998 0.999 0.999 0.997 0.995))) (not (vequal sp (float-vector 0.052 0.971 1.000 1.000 0.998 0.998 0.999 0.999 0.997 0.995)))) (snd-display #__line__ ";bhp rough spectrum: ~A" sp))) (undo)) (let ((b (make-butter-lp 4 440.0)) (v (make-float-vector 10)) (d (make-delay 1))) (delay d (filter b 1.0)) (fill-float-vector v (delay d (filter b 0.0))) (if (not (vequal v (float-vector 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) ;; ??? (snd-display #__line__ ";butter lp: ~A" v)) (set! b (make-butter-lp 4 1000.0)) (map-channel (lambda (y) (filter b y))) (let ((sp (rough-spectrum ind))) (if (and (not (vequal sp (float-vector 1.000 0.035 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) (not (vequal sp (float-vector 1.000 0.038 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000)))) (snd-display #__line__ ";blp rough spectrum: ~A" sp))) (undo)) (let ((b (make-butter-bp 4 440.0 500.0)) (v (make-float-vector 10)) (d (make-delay 1))) (delay d (filter b 1.0)) (fill-float-vector v (delay d (filter b 0.0))) (if (not (vequal v (float-vector 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";butter bp: ~A" v)) (set! b (make-butter-bp 4 1000.0 1500.0)) (map-channel (lambda (y) (filter b y))) (undo)) (let ((b (make-butter-bs 4 440.0 500.0)) (v (make-float-vector 10)) (d (make-delay 1))) (delay d (filter b 1.0)) (fill-float-vector v (delay d (filter b 0.0))) (if (and (not (vequal v (float-vector 0.978 -0.043 -0.041 -0.038 -0.035 -0.031 -0.026 -0.0225 -0.015 -0.0085))) (not (vequal v (float-vector 0.978 -0.043 -0.041 -0.038 -0.035 -0.031 -0.027 -0.022 -0.017 -0.011))) (not (vequal v (float-vector 0.978 -0.043 -0.041 -0.038 -0.035 -0.031 -0.027 -0.021 -0.014 -0.011)))) (snd-display #__line__ ";butter bs: ~A" v)) (set! b (make-butter-bs 4 1000.0 1500.0)) (map-channel (lambda (y) (filter b y))) (undo)) (revert-sound) (test-scanned-synthesis .1 10000 1.0 0.1 0.0) (close-sound ind)) (let ((gen (make-sawtooth-wave 440.0)) (v0 (make-float-vector 10)) (gen1 (make-sawtooth-wave 440.0)) (v1 (make-float-vector 10))) (print-and-check gen "sawtooth-wave" "sawtooth-wave freq: 440.000Hz, phase: 3.142, amp: 1.000") (do ((i 0 (+ i 1))) ((= i 10)) (set! (v0 i) (sawtooth-wave gen 0.0))) (fill-float-vector v1 (if (sawtooth-wave? gen1) (sawtooth-wave gen1 0.0) -1.0)) (if (not (vequal v0 v1)) (snd-display #__line__ ";map sawtooth: ~A ~A" v0 v1)) (if (not (sawtooth-wave? gen)) (snd-display #__line__ ";~A not sawtooth-wave?" gen)) (if (fneq (mus-phase gen) 4.39538) (snd-display #__line__ ";sawtooth-wave phase: ~F?" (mus-phase gen))) ;starts at pi (if (fneq (mus-frequency gen) 440.0) (snd-display #__line__ ";sawtooth-wave frequency: ~F?" (mus-frequency gen))) (set! (mus-frequency gen) 100.0) (if (fneq (mus-frequency gen) 100.0) (snd-display #__line__ ";set! sawtooth-wave frequency: ~F?" (mus-frequency gen))) (if (fneq (mus-scaler gen) 1.0) (snd-display #__line__ ";sawtooth-wave scaler: ~F?" (mus-scaler gen))) (set! (mus-scaler gen) 0.5) (if (fneq (mus-scaler gen) 0.5) (snd-display #__line__ ";set! sawtooth-wave scaler: ~F?" (mus-scaler gen))) (if (or (fneq (v0 1) 0.04) (fneq (v0 8) .319)) (snd-display #__line__ ";sawtooth-wave output: ~A" v0))) (test-gen-equal (make-sawtooth-wave 440.0) (make-sawtooth-wave 440.0) (make-sawtooth-wave 120.0)) (test-gen-equal (make-sawtooth-wave 440.0) (make-sawtooth-wave 440.0) (make-sawtooth-wave 440.0 1.0 1.0)) (test-gen-equal (make-sawtooth-wave 440.0) (make-sawtooth-wave 440.0) (make-sawtooth-wave 440.0 0.5)) (let ((gen1 (make-sawtooth-wave 100.0)) (gen2 (make-sawtooth-wave -100.0)) (mx 0.0)) (do ((i 0 (+ i 1))) ((= i 100)) (set! mx (max mx (abs (+ (gen1) (gen2)))))) (if (fneq mx 0.0) (snd-display #__line__ ";sawtooth +-: ~A" mx))) (let ((gen (make-square-wave 440.0)) (v0 (make-float-vector 10)) (gen1 (make-square-wave 440.0)) (v1 (make-float-vector 10))) (print-and-check gen "square-wave" "square-wave freq: 440.000Hz, phase: 0.000, amp: 1.000") (do ((i 0 (+ i 1))) ((= i 10)) (set! (v0 i) (square-wave gen 0.0))) (let ((w 1.0)) (fill-float-vector v1 (begin (set! w (mus-width gen1)) (if (square-wave? gen1) (square-wave gen1 0.0) -1.0))) (if (fneq w 0.5) (snd-display #__line__ ";mus-width opt: ~A" w))) (if (not (vequal v0 v1)) (snd-display #__line__ ";map square-wave: ~A ~A" v0 v1)) (if (not (square-wave? gen)) (snd-display #__line__ ";~A not square-wave?" gen)) (if (fneq (mus-phase gen) 1.253787) (snd-display #__line__ ";square-wave phase: ~F?" (mus-phase gen))) (if (fneq (mus-frequency gen) 440.0) (snd-display #__line__ ";square-wave frequency: ~F?" (mus-frequency gen))) (if (fneq (mus-scaler gen) 1.0) (snd-display #__line__ ";square-wave scaler: ~F?" (mus-scaler gen))) (set! (mus-scaler gen) 0.5) (if (fneq (mus-scaler gen) 0.5) (snd-display #__line__ ";set! square-wave scaler: ~F?" (mus-scaler gen))) (if (fneq (mus-width gen) 0.5) (snd-display #__line__ ";square-wave width: ~A" (mus-width gen))) (set! (mus-width gen) 0.75) (if (fneq (mus-width gen) 0.75) (snd-display #__line__ ";set! square-wave width: ~A" (mus-width gen))) (if (or (fneq (v0 1) 1.0) (fneq (v0 8) 1.0)) (snd-display #__line__ ";square-wave output: ~A" v0))) (test-gen-equal (make-square-wave 440.0) (make-square-wave 440.0) (make-square-wave 120.0)) (test-gen-equal (make-square-wave 440.0) (make-square-wave 440.0) (make-square-wave 440.0 1.0 1.0)) (test-gen-equal (make-square-wave 440.0) (make-square-wave 440.0) (make-square-wave 440.0 0.5)) (let ((old-srate *clm-srate*)) (set! *clm-srate* 500.0) (let ((gen (make-square-wave 100.0 -0.5 (* pi 0.5))) (v0 (make-float-vector 20))) (do ((i 0 (+ i 1))) ((= i 20)) (set! (v0 i) (gen))) (if (not (vequal v0 (float-vector -0.5 -0.5 0.0 0.0 -0.5 -0.5 -0.5 0.0 0.0 -0.5 -0.5 -0.5 0.0 0.0 -0.5 -0.5 -0.5 0.0 0.0 -0.5))) (snd-display #__line__ ";square-wave -.5: ~A " v0))) (set! *clm-srate* old-srate)) (let ((gen (make-triangle-wave 440.0)) (gen1 (make-triangle-wave 440.0 1.0 pi)) (v0 (make-float-vector 10)) (gen2 (make-triangle-wave 440.0)) (v1 (make-float-vector 10))) (print-and-check gen "triangle-wave" "triangle-wave freq: 440.000Hz, phase: 0.000, amp: 1.000") (do ((i 0 (+ i 1))) ((= i 10)) (set! (v0 i) (triangle-wave gen 0.0))) (fill-float-vector v1 (if (triangle-wave? gen2) (triangle-wave gen2 0.0) -1.0)) (if (not (vequal v0 v1)) (snd-display #__line__ ";map triangle-wave: ~A ~A" v0 v1)) (if (not (triangle-wave? gen)) (snd-display #__line__ ";~A not triangle-wave?" gen)) (if (fneq (mus-phase gen) 1.253787) (snd-display #__line__ ";triangle-wave phase: ~F?" (mus-phase gen))) (if (fneq (mus-phase gen1) pi) (snd-display #__line__ ";init triangle-wave phase: ~F?" (mus-phase gen1))) (if (fneq (mus-frequency gen) 440.0) (snd-display #__line__ ";triangle-wave frequency: ~F?" (mus-frequency gen))) (if (fneq (mus-scaler gen) 1.0) (snd-display #__line__ ";triangle-wave scaler: ~F?" (mus-scaler gen))) (set! (mus-scaler gen) 0.5) (if (fneq (mus-scaler gen) 0.5) (snd-display #__line__ ";set! triangle-wave scaler: ~F?" (mus-scaler gen))) (if (or (fneq (v0 1) 0.080) (fneq (v0 8) 0.639)) (snd-display #__line__ ";triangle-wave output: ~A" v0))) (let ((gen1 (make-triangle-wave 100.0)) (gen2 (make-triangle-wave -100.0)) (mx 0.0)) (do ((i 0 (+ i 1))) ((= i 100)) (set! mx (max mx (abs (+ (gen1) (gen2)))))) (if (fneq mx 0.0) (snd-display #__line__ ";triangle +-: ~A" mx))) (test-gen-equal (make-triangle-wave 440.0) (make-triangle-wave 440.0) (make-triangle-wave 120.0)) (test-gen-equal (make-triangle-wave 440.0) (make-triangle-wave 440.0) (make-triangle-wave 440.0 1.0 1.0)) (test-gen-equal (make-triangle-wave 440.0) (make-triangle-wave 440.0) (make-triangle-wave 440.0 0.5)) (let ((gen (make-pulse-train 440.0)) (v0 (make-float-vector 10)) (gen1 (make-pulse-train 440.0)) (v1 (make-float-vector 10))) (print-and-check gen "pulse-train" "pulse-train freq: 440.000Hz, phase: 0.000, amp: 1.000") (do ((i 0 (+ i 1))) ((= i 10)) (set! (v0 i) (pulse-train gen 0.0))) (fill-float-vector v1 (if (pulse-train? gen1) (pulse-train gen1 0.0) -1.0)) (if (not (vequal v0 v1)) (snd-display #__line__ ";map pulse-train: ~A ~A" v0 v1)) (if (not (pulse-train? gen)) (snd-display #__line__ ";~A not pulse-train?" gen)) (if (fneq (mus-phase gen) 1.253787) (snd-display #__line__ ";pulse-train phase: ~F?" (mus-phase gen))) (if (fneq (mus-frequency gen) 440.0) (snd-display #__line__ ";pulse-train frequency: ~F?" (mus-frequency gen))) (if (fneq (mus-scaler gen) 1.0) (snd-display #__line__ ";pulse-train scaler: ~F?" (mus-scaler gen))) (set! (mus-scaler gen) 0.5) (if (fneq (mus-scaler gen) 0.5) (snd-display #__line__ ";set! pulse-train scaler: ~F?" (mus-scaler gen))) (if (or (fneq (v0 0) 1.0) (fneq (v0 8) 0.0)) (snd-display #__line__ ";pulse-train output: ~A" v0))) (test-gen-equal (make-pulse-train 440.0) (make-pulse-train 440.0) (make-pulse-train 120.0)) (test-gen-equal (make-pulse-train 440.0) (make-pulse-train 440.0) (make-pulse-train 440.0 1.0 1.0)) (test-gen-equal (make-pulse-train 440.0) (make-pulse-train 440.0) (make-pulse-train 440.0 0.5)) (let ((old-srate *clm-srate*)) (set! *clm-srate* 500.0) (let ((gen (make-pulse-train 100.0 -0.5 (* pi 0.5))) (v0 (make-float-vector 20))) (do ((i 0 (+ i 1))) ((= i 20)) (set! (v0 i) (gen))) (if (not (vequal v0 (float-vector 0.0 0.0 0.0 0.0 -0.5 0.0 0.0 0.0 0.0 -0.5 0.0 0.0 0.0 0.0 -0.5 0.0 0.0 0.0 0.0 -0.5))) (snd-display #__line__ ";pulse-train -.5: ~A " v0))) (set! *clm-srate* old-srate)) (let ((gen (make-two-pole 1200.0 .1))) (if (not (two-pole? gen)) (snd-display #__line__ ";~A not 2-polar?" gen)) (if (not (= (mus-order gen) 2)) (snd-display #__line__ ";2-polar order: ~D?" (mus-order gen))) (if (fneq (mus-xcoeff gen 0) 1.0) (snd-display #__line__ ";2-polar a0: ~F?" (mus-xcoeff gen 0))) (if (fneq (mus-ycoeff gen 1) -.188) (snd-display #__line__ ";2-polar b1: ~F?" (mus-ycoeff gen 1))) (if (fneq (mus-ycoeff gen 2) .01) (snd-display #__line__ ";2-polar b2: ~F?" (mus-ycoeff gen 2))) (if (fneq (mus-frequency gen) 1200.0) (snd-display #__line__ ";freq 2-polar: ~A" (mus-frequency gen))) (if (fneq (mus-scaler gen) 0.1) (snd-display #__line__ ";scaler 2-polar: ~A" (mus-scaler gen)))) (let ((gen (make-two-pole :frequency 1200.0 :radius .1))) (if (not (two-pole? gen)) (snd-display #__line__ ";~A not f2-polar?" gen)) (if (not (= (mus-order gen) 2)) (snd-display #__line__ ";f2-polar order: ~D?" (mus-order gen))) (if (fneq (mus-xcoeff gen 0) 1.0) (snd-display #__line__ ";f2-polar a0: ~F?" (mus-xcoeff gen 0))) (if (fneq (mus-ycoeff gen 1) -.188) (snd-display #__line__ ";f2-polar b1: ~F?" (mus-ycoeff gen 1))) (if (fneq (mus-ycoeff gen 2) .01) (snd-display #__line__ ";f2-polar b2: ~F?" (mus-ycoeff gen 2))) (if (fneq (mus-frequency gen) 1200.0) (snd-display #__line__ ";freq f2-polar: ~A" (mus-frequency gen))) (if (fneq (mus-scaler gen) 0.1) (snd-display #__line__ ";scaler f2-polar: ~A" (mus-scaler gen)))) (let ((gen (make-two-zero :radius .1 :frequency 1200.0))) (if (not (two-zero? gen)) (snd-display #__line__ ";~A not 2-zp?" gen)) (if (not (= (mus-order gen) 2)) (snd-display #__line__ ";2-zp order: ~D?" (mus-order gen))) (if (fneq (mus-xcoeff gen 0) 1.0) (snd-display #__line__ ";2-zp a0: ~F?" (mus-xcoeff gen 0))) (if (fneq (mus-xcoeff gen 1) -.188) (snd-display #__line__ ";2-zp a1: ~F?" (mus-xcoeff gen 1))) (if (fneq (mus-xcoeff gen 2) .01) (snd-display #__line__ ";2-zp a2: ~F?" (mus-xcoeff gen 2))) (if (fneq (mus-frequency gen) 1200.0) (snd-display #__line__ ";freq 2-zp: ~A" (mus-frequency gen))) (if (fneq (mus-scaler gen) 0.1) (snd-display #__line__ ";scaler 2-zp: ~A" (mus-scaler gen)))) (let ((gen (make-two-zero 1200.0 .1))) (if (not (two-zero? gen)) (snd-display #__line__ ";~A not f2-zp?" gen)) (if (not (= (mus-order gen) 2)) (snd-display #__line__ ";f2-zp order: ~D?" (mus-order gen))) (if (fneq (mus-xcoeff gen 0) 1.0) (snd-display #__line__ ";f2-zp a0: ~F?" (mus-xcoeff gen 0))) (if (fneq (mus-xcoeff gen 1) -.188) (snd-display #__line__ ";f2-zp a1: ~F?" (mus-xcoeff gen 1))) (if (fneq (mus-xcoeff gen 2) .01) (snd-display #__line__ ";f2-zp a2: ~F?" (mus-xcoeff gen 2))) (if (fneq (mus-frequency gen) 1200.0) (snd-display #__line__ ";freq f2-zp: ~A" (mus-frequency gen))) (if (fneq (mus-scaler gen) 0.1) (snd-display #__line__ ";scaler f2-zp: ~A" (mus-scaler gen)))) (let ((gen (make-formant 1200.0 0.9)) (v0 (make-float-vector 10)) (gen1 (make-formant 1200.0 0.9)) (v1 (make-float-vector 10))) (print-and-check gen "formant" "formant frequency: 1200.000, radius: 0.900") (set! (v0 0) (formant gen 1.0)) (do ((i 1 (+ i 1))) ((= i 10)) (set! (v0 i) (formant gen 0.0))) (let ((inp 1.0)) (fill-float-vector v1 (let ((val (if (formant? gen1) (formant gen1 inp) -1.0))) (set! inp 0.0) val))) (if (not (vequal v0 v1)) (snd-display #__line__ ";map formant: ~A ~A" v0 v1)) (if (not (formant? gen)) (snd-display #__line__ ";~A not formant?" gen)) (if (not (= (mus-order gen) 2)) (snd-display #__line__ ";formant order: ~D?" (mus-order gen))) (if (fneq (mus-frequency gen) 1200.0) (snd-display #__line__ ";formant frequency: ~F?" (mus-frequency gen))) (if (or (fneq (v0 0) .095) (fneq (v0 1) .161)) (snd-display #__line__ ";formant output: ~A" v0)) (if (fneq (mus-scaler gen) 0.9) (snd-display #__line__ ";formant gain: ~F?" (mus-scaler gen))) (set! (mus-scaler gen) 2.0) (if (fneq (mus-scaler gen) 2.0) (snd-display #__line__ ";formant set gain: ~F?" (mus-scaler gen)))) (test-gen-equal (let ((f1 (make-formant 1200.0 0.9))) (formant f1 1.0) f1) (let ((f2 (make-formant 1200.0 0.9))) (formant f2 1.0) f2) (let ((f3 (make-formant 600.0 0.9))) (formant f3 1.0) f3)) (test-gen-equal (let ((f1 (make-formant 1200.0 0.9))) (formant f1 1.0) f1) (let ((f2 (make-formant 1200.0 0.9))) (formant f2 1.0) f2) (let ((f3 (make-formant 1200.0 0.99))) (formant f3 1.0) f3)) (test-gen-equal (let ((f1 (make-formant 1200.0 0.9))) (formant f1 1.0) f1) (let ((f2 (make-formant 1200.0 0.9))) (formant f2 1.0) f2) (let ((f3 (make-formant 1200.0 0.5))) (formant f3 1.0) f3)) (let ((fs (make-vector 2)) (f0 (make-formant 1000.0 .1)) (f1 (make-formant 100.0 .2)) (amps (make-float-vector 2 1.0)) (val 1.0) (v0 (make-float-vector 10)) (v1 (make-float-vector 10))) (set! (fs 0) (make-formant 1000.0 .1)) (set! (fs 1) (make-formant 100.0 .2)) (set! fs (make-formant-bank fs amps)) (set! (amps 0) 0.5) (set! (amps 1) 0.25) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v0 i) (+ (* 0.5 (formant f0 val)) (* 0.25 (formant f1 val)))) (set! (v1 i) (formant-bank fs val)) (set! val 0.0)) (if (not (vequal v0 v1)) (snd-display #__line__ ";formant bank 1: ~A ~A" v0 v1))) (let ((fs (make-vector 2)) (amps (make-float-vector 2 1.0)) (val 1.0) (v (make-float-vector 5))) (set! (fs 0) (make-formant 1000.0 .1)) (set! (fs 1) (make-formant 100.0 .2)) (set! fs (make-formant-bank fs amps)) (set! (amps 0) 0.5) (set! (amps 1) 0.25) (fill-float-vector v (let ((res (formant-bank fs val))) (set! val 0.0) res)) (if (not (vequal v (float-vector 0.368 0.095 -0.346 -0.091 -0.020))) (snd-display #__line__ ";run formant-bank: ~A" v))) (let ((ob (open-sound "oboe.snd"))) (define (poltergeist frek amp R gain frek-env R-env) ;; test courtesy of Anders Vinjar (let ((filt (make-formant frek R)) (fe (make-env :envelope frek-env :length (framples) :offset frek)) (re (make-env :envelope R-env :length (framples) :offset R))) (lambda (y) (let ((outval (* gain (formant filt (* amp y))))) (mus-set-formant-radius-and-frequency filt (env re) (env fe)) outval)))) (map-channel (poltergeist 300 0.1 0.0 30.0 '(0 100 1 4000.0) '(0 0.99 1 .9))) ;; should sound like "whyieee?" (play ob :wait #t) (close-sound ob)) (let ((gen (make-firmant 1200.0 0.9)) (v0 (make-float-vector 10)) (gen1 (make-firmant 1200.0 0.9)) (v1 (make-float-vector 10))) (print-and-check gen "firmant" "firmant frequency: 1200.000, radius: 0.900") (set! (v0 0) (firmant gen 1.0)) (do ((i 1 (+ i 1))) ((= i 10)) (set! (v0 i) (firmant gen 0.0))) (let ((inp 1.0)) (fill-float-vector v1 (let ((val (if (firmant? gen1) (firmant gen1 inp) -1.0))) (set! inp 0.0) val))) (if (not (vequal v0 v1)) (snd-display #__line__ ";map firmant: ~A ~A" v0 v1)) (if (not (firmant? gen)) (snd-display #__line__ ";~A not firmant?" gen)) (if (not (= (mus-order gen) 2)) (snd-display #__line__ ";firmant order: ~D?" (mus-order gen))) (if (fneq (mus-frequency gen) 1200.0) (snd-display #__line__ ";firmant frequency: ~F?" (mus-frequency gen))) (if (or (fneq (v0 0) .058) (fneq (v0 1) .099)) (snd-display #__line__ ";firmant output: ~A" v0)) (if (fneq (mus-scaler gen) 0.9) (snd-display #__line__ ";firmant gain: ~F?" (mus-scaler gen))) (set! (mus-scaler gen) .20) (if (fneq (mus-scaler gen) .20) (snd-display #__line__ ";firmant set gain: ~F?" (mus-scaler gen)))) (test-gen-equal (let ((f1 (make-firmant 1200.0 0.9))) (firmant f1 1.0) f1) (let ((f2 (make-firmant 1200.0 0.9))) (firmant f2 1.0) f2) (let ((f3 (make-firmant 600.0 0.9))) (firmant f3 1.0) f3)) (test-gen-equal (let ((f1 (make-firmant 1200.0 0.9))) (firmant f1 1.0) f1) (let ((f2 (make-firmant 1200.0 0.9))) (firmant f2 1.0) f2) (let ((f3 (make-firmant 1200.0 0.99))) (firmant f3 1.0) f3)) (test-gen-equal (let ((f1 (make-firmant 1200.0 0.9))) (firmant f1 1.0) f1) (let ((f2 (make-firmant 1200.0 0.9))) (firmant f2 1.0) f2) (let ((f3 (make-firmant 1200.0 0.5))) (firmant f3 1.0) f3)) (let ((gen (make-fft-window hamming-window 16))) (if (not (vequal gen (float-vector 0.080 0.115 0.215 0.364 0.540 0.716 0.865 1.000 1.000 0.865 0.716 0.540 0.364 0.215 0.115 0.080))) (snd-display #__line__ ";hamming window: ~A" gen))) (let ((gen (make-fft-window rectangular-window 16))) (if (not (vequal gen (float-vector 1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000))) (snd-display #__line__ ";rectangular window: ~A" gen))) (let ((gen (make-fft-window hann-window 16))) (if (not (vequal gen (float-vector 0.000 0.038 0.146 0.309 0.500 0.691 0.854 1.000 1.000 0.854 0.691 0.500 0.309 0.146 0.038 0.000))) (snd-display #__line__ ";hann window: ~A" gen))) (let ((gen (make-fft-window welch-window 16))) (if (not (vequal gen (float-vector 0.000 0.234 0.438 0.609 0.750 0.859 0.938 1.000 1.000 0.938 0.859 0.750 0.609 0.438 0.234 0.000))) (snd-display #__line__ ";welch window: ~A" gen))) (let ((gen (make-fft-window connes-window 16))) (if (not (vequal gen (float-vector 0.000 0.055 0.191 0.371 0.562 0.739 0.879 1.000 1.000 0.879 0.739 0.562 0.371 0.191 0.055 0.000))) (snd-display #__line__ ";connes window: ~A" gen))) (let ((gen (make-fft-window parzen-window 16))) (if (not (vequal gen (float-vector 0.000 0.125 0.250 0.375 0.500 0.625 0.750 1.000 1.000 0.750 0.625 0.500 0.375 0.250 0.125 0.000))) (snd-display #__line__ ";parzen window: ~A" gen))) (let ((gen (make-fft-window bartlett-window 16))) (if (not (vequal gen (float-vector 0.000 0.125 0.250 0.375 0.500 0.625 0.750 1.000 1.000 0.750 0.625 0.500 0.375 0.250 0.125 0.000))) (snd-display #__line__ ";bartlett window: ~A" gen))) (let ((gen (make-fft-window blackman2-window 16))) (if (not (vequal gen (float-vector 0.005 0.020 0.071 0.177 0.344 0.558 0.775 1.000 1.000 0.775 0.558 0.344 0.177 0.071 0.020 0.005))) (snd-display #__line__ ";blackman2 window: ~A" gen))) (let ((gen (make-fft-window blackman3-window 16))) (if (not (vequal gen (float-vector 0.000 0.003 0.022 0.083 0.217 0.435 0.696 1.000 1.000 0.696 0.435 0.217 0.083 0.022 0.003 0.000))) (snd-display #__line__ ";blackman3 window: ~A" gen))) (let ((gen (make-fft-window blackman4-window 16))) (if (not (vequal gen (float-vector 0.002 0.002 0.003 0.017 0.084 0.263 0.562 1.000 1.000 0.562 0.263 0.084 0.017 0.003 0.002 0.002))) (snd-display #__line__ ";blackman4 window: ~A" gen))) (let ((gen (make-fft-window blackman5-window 16))) (if (not (vequal gen (float-vector 0.000 0.000 0.003 0.022 0.097 0.280 0.574 1.000 1.000 0.574 0.280 0.097 0.022 0.003 0.000 0.000))) (snd-display #__line__ ";blackman5 window: ~A" gen))) (let ((gen (make-fft-window blackman6-window 16))) (if (not (vequal gen (float-vector 0.000 0.000 0.001 0.011 0.064 0.223 0.520 1.000 1.000 0.520 0.223 0.064 0.011 0.001 0.000 0.000))) (snd-display #__line__ ";blackman6 window: ~A" gen))) (let ((gen (make-fft-window blackman7-window 16))) (if (not (vequal gen (float-vector 0.000 0.000 0.000 0.006 0.042 0.177 0.471 1.000 1.000 0.471 0.177 0.042 0.006 0.000 0.000 0.000))) (snd-display #__line__ ";blackman7 window: ~A" gen))) (let ((gen (make-fft-window blackman8-window 16))) (if (not (vequal gen (float-vector 0.000 0.000 0.000 0.003 0.028 0.141 0.426 1.000 1.000 0.426 0.141 0.028 0.003 0.000 0.000 0.000))) (snd-display #__line__ ";blackman8 window: ~A" gen))) (let ((gen (make-fft-window blackman9-window 16))) (if (not (vequal gen (float-vector 0.000 0.000 0.000 0.001 0.018 0.112 0.385 1.000 1.000 0.385 0.112 0.018 0.001 0.000 0.000 -0.000))) (snd-display #__line__ ";blackman9 window: ~A" gen))) (let ((gen (make-fft-window blackman10-window 16))) (if (not (vequal gen (float-vector 0.000 0.000 0.000 0.001 0.012 0.089 0.349 1.000 1.000 0.349 0.089 0.012 0.001 0.000 0.000 -0.000))) (snd-display #__line__ ";blackman10 window: ~A" gen))) (let ((gen (make-fft-window rv2-window 16))) (if (not (vequal gen (float-vector 0.000 0.001 0.021 0.095 0.250 0.478 0.729 1.000 1.000 0.729 0.478 0.250 0.095 0.021 0.001 0.000))) (snd-display #__line__ ";rv2 window: ~A" gen))) (let ((gen (make-fft-window rv3-window 16))) (if (not (vequal gen (float-vector 0.000 0.000 0.003 0.029 0.125 0.330 0.622 1.000 1.000 0.622 0.330 0.125 0.029 0.003 0.000 0.000))) (snd-display #__line__ ";rv3 window: ~A" gen))) (let ((gen (make-fft-window rv4-window 16))) (if (not (vequal gen (float-vector 0.000 0.000 0.000 0.009 0.062 0.228 0.531 1.000 1.000 0.531 0.228 0.062 0.009 0.000 0.000 0.000))) (snd-display #__line__ ";rv4 window: ~A" gen))) (let ((gen (make-fft-window exponential-window 16))) (if (not (vequal gen (float-vector 0.000 0.087 0.181 0.283 0.394 0.515 0.646 0.944 0.944 0.646 0.515 0.394 0.283 0.181 0.087 0.000))) (snd-display #__line__ ";exponential window: ~A" gen))) (let ((gen (make-fft-window riemann-window 16))) (if (not (vequal gen (float-vector 0.000 0.139 0.300 0.471 0.637 0.784 0.900 1.000 1.000 0.900 0.784 0.637 0.471 0.300 0.139 0.000))) (snd-display #__line__ ";riemann window: ~A" gen))) (let ((gen (make-fft-window kaiser-window 16 2.5))) (if (not (vequal gen (float-vector 0.304 0.426 0.550 0.670 0.779 0.871 0.941 1.000 1.000 0.941 0.871 0.779 0.670 0.550 0.426 0.304))) (snd-display #__line__ ";kaiser window: ~A" gen))) (let ((gen (make-fft-window cauchy-window 16 2.5))) (if (not (vequal gen (float-vector 0.138 0.173 0.221 0.291 0.390 0.532 0.719 1.000 1.000 0.719 0.532 0.390 0.291 0.221 0.173 0.138))) (snd-display #__line__ ";cauchy window: ~A" gen))) (let ((gen (make-fft-window poisson-window 16 2.5))) (if (not (vequal gen (float-vector 0.082 0.112 0.153 0.210 0.287 0.392 0.535 1.000 1.000 0.535 0.392 0.287 0.210 0.153 0.112 0.082))) (snd-display #__line__ ";poisson window: ~A" gen))) (let ((gen (make-fft-window gaussian-window 16 1.0))) (if (not (vequal gen (float-vector 0.607 0.682 0.755 0.823 0.882 0.932 0.969 1.000 1.000 0.969 0.932 0.882 0.823 0.755 0.682 0.607))) (snd-display #__line__ ";gaussian window: ~A" gen))) (let ((gen (make-fft-window tukey-window 16))) (if (not (vequal gen (float-vector 0.000 0.038 0.146 0.309 0.500 0.691 0.854 1.000 1.000 0.854 0.691 0.500 0.309 0.146 0.038 0.000))) (snd-display #__line__ ";tukey window: ~A" gen))) (let ((gen (make-fft-window hann-poisson-window 16))) (if (not (vequal gen (float-vector 0.000 0.038 0.146 0.309 0.500 0.691 0.854 1.000 1.000 0.854 0.691 0.500 0.309 0.146 0.038 0.000))) (snd-display #__line__ ";tukey window: ~A" gen))) (let ((gen (make-fft-window bohman-window 16))) (if (not (vequal gen (float-vector 0.000 0.006 0.048 0.151 0.318 0.533 0.755 1.000 1.000 0.755 0.533 0.318 0.151 0.048 0.006 0.000))) (snd-display #__line__ ";bohman window: ~A" gen))) (for-each (lambda (window-data) (let ((window (car window-data)) (func (caddr window-data)) (name (cadr window-data))) (let ((v1 (make-fft-window window 16)) (v2 (make-float-vector 16)) (incr (/ (* 2 pi) 16.0))) (do ((i 0 (+ i 1)) (j 15 (- j 1)) (ang 0.0 (+ ang incr))) ((> i 8)) ; yikes -- even size + smallness = questionable code... (let ((val (func ang))) (set! (v2 i) val) (set! (v2 j) val))) (if (not (vequal v1 v2)) (snd-display #__line__ ";~A by hand:~%; mus: ~A~%; loc: ~A" name v1 v2))))) (list (list hann-window "hann" (lambda (ang) (- 0.5 (* 0.5 (cos ang))))) (list rv2-window "rv2" (lambda (ang) (+ .375 (* -0.5 (cos ang)) (* .125 (cos (* 2 ang)))))) (list rv3-window "rv3" (lambda (ang) (+ (/ 10.0 32.0) (* (/ -15.0 32.0) (cos ang)) (* (/ 6.0 32.0) (cos (* 2 ang))) (* (/ -1.0 32.0) (cos (* 3 ang)))))) (list rv4-window "rv4" (lambda (ang) (+ (/ 35.0 128.0) (* (/ -56.0 128.0) (cos ang)) (* (/ 28.0 128.0) (cos (* 2 ang))) (* (/ -8.0 128.0) (cos (* 3 ang))) (* (/ 1.0 128.0) (cos (* 4 ang)))))) (list hamming-window "hamming" (lambda (ang) (- 0.54 (* 0.46 (cos ang))))) (list blackman2-window "blackman2" (lambda (ang) (+ 0.42323 (* -0.49755 (cos ang)) (* 0.07922 (cos (* 2 ang)))))) (list blackman3-window "blackman3" (lambda (ang) (+ 0.35875 (* -0.48829 (cos ang)) (* 0.14128 (cos (* 2 ang))) (* -0.01168 (cos (* 3 ang)))))) (list blackman4-window "blackman4" (lambda (ang) (+ 0.287333 (* -0.44716 (cos ang)) (* 0.20844 (cos (* 2 ang))) (* -0.05190 (cos (* 3 ang))) (* 0.005149 (cos (* 4 ang)))))) (list blackman5-window "blackman5" (lambda (ang) (+ .293557 (* -.451935 (cos ang)) (* .201416 (cos (* 2 ang))) (* -.047926 (cos (* 3 ang))) (* .00502619 (cos (* 4 ang))) (* -.000137555 (cos (* 5 ang)))))) (list blackman6-window "blackman6" (lambda (ang) (+ .271220 (* -.433444 (cos ang)) (* .218004 (cos (* 2 ang))) (* -.065785 (cos (* 3 ang))) (* .01076186 (cos (* 4 ang))) (* -.000770012 (cos (* 5 ang))) (* .0000136808 (cos (* 6 ang)))))) (list blackman7-window "blackman7" (lambda (ang) (+ .253317 (* -.416327 (cos ang)) (* .228839 (cos (* 2 ang))) (* -.081575 (cos (* 3 ang))) (* .01773592 (cos (* 4 ang))) (* -.002096702 (cos (* 5 ang))) (* .0001067741 (cos (* 6 ang))) (* -.0000012807(cos (* 7 ang)))))) (list blackman8-window "blackman8" (lambda (ang) (+ .238433 (* -.400554 (cos ang)) (* .235824 (cos (* 2 ang))) (* -.095279 (cos (* 3 ang))) (* .02537395 (cos (* 4 ang))) (* -.00415243 (cos (* 5 ang))) (* .0003685604 (cos (* 6 ang))) (* -.0000138435 (cos (* 7 ang))) (* .000000116180(cos (* 8 ang)))))) (list blackman9-window "blackman9" (lambda (ang) (+ .225734 (* -.386012 (cos ang)) (* .240129 (cos (* 2 ang))) (* -.107054 (cos (* 3 ang))) (* .03325916 (cos (* 4 ang))) (* -.00687337 (cos (* 5 ang))) (* .0008751673 (cos (* 6 ang))) (* -.0000600859 (cos (* 7 ang))) (* .000001710716 (cos (* 8 ang))) (* -.00000001027272(cos (* 9 ang)))))) (list blackman10-window "blackman10" (lambda (ang) (+ .215153 (* -.373135 (cos ang)) (* .242424 (cos (* 2 ang))) (* -.1166907 (cos (* 3 ang))) (* .04077422 (cos (* 4 ang))) (* -.01000904 (cos (* 5 ang))) (* .0016398069 (cos (* 6 ang))) (* -.0001651660 (cos (* 7 ang))) (* .000008884663 (cos (* 8 ang))) (* -.000000193817 (cos (* 9 ang))) (* .000000000848248(cos (* 10 ang)))))) (list rectangular-window "rectangular" (lambda (ang) 1.0)) (list bartlett-window "bartlett" (let ((val 0.0)) (lambda (ang) (let ((result val)) (set! val (+ val (/ 1.0 8))) result)))) (list parzen-window "parzen" (let ((i 0)) (lambda (ang) (let ((result (- 1.0 (abs (/ (- i 8) 8.0))))) (set! i (+ i 1)) result)))) (list welch-window "welch" (let ((i 0) (sqr (lambda (x) (* x x)))) (lambda (ang) (let ((result (- 1.0 (sqr (/ (- i 8) 8.0))))) (set! i (+ i 1)) result)))) (list flat-top-window "flat-top" (lambda (ang) (+ 0.2156 (* -0.4160 (cos ang)) (* 0.2781 (cos (* 2 ang))) (* -0.0836 (cos (* 3 ang))) (* 0.0069 (cos (* 4 ang)))))) (list bohman-window "bohman" (let ((i 0)) (lambda (ang) (let* ((r (/ (- 8 i) 8)) (result (+ (* (- 1.0 r) (cos (* pi r))) (* (/ 1.0 pi) (sin (* pi r)))))) (set! i (+ i 1)) result)))) (list bartlett-hann-window "bartlett-hann" (let ((i 0)) (lambda (ang) (let ((result (+ 0.62 (* -0.48 (abs (- (/ i 16.0) 0.5))) (* 0.38 (cos (* 2 pi (- (/ i 16.0) 0.5))))))) (set! i (+ i 1)) result)))) (list connes-window "connes" (let ((i 0) (sqr (lambda (x) (* x x)))) (lambda (ang) (let ((result (sqr (- 1.0 (sqr (/ (- i 8) 8.0)))))) (set! i (+ i 1)) result)))) (list riemann-window "riemann" (let ((i 0)) (lambda (ang) (let ((result (if (= 8 i) 1.0 (/ (sin (* (/ (* 2 pi) 16.) (- 8 i))) (* (/ (* 2 pi) 16.0) (- 8 i)))))) (set! i (+ i 1)) result)))) (list exponential-window "exponential" (let ((expsum 1.0)) (lambda (ang) (let ((result (- expsum 1.0))) (set! expsum (* expsum (+ 1.0 (/ (log 2) 8.0)))) result)))) )) (let ((win (make-fft-window bartlett-hann-window 32)) (unhappy #f)) (do ((i 0 (+ i 1))) ((or unhappy (= i 32))) (let ((val (+ 0.62 (* -0.48 (abs (- (/ i 31) 0.5))) (* 0.38 (cos (* 2 pi (- (/ i 31) 0.5))))))) (if (> (abs (- val (win i))) .03) (begin (set! unhappy #t) (snd-display #__line__ ";bartlett-hann at ~D: ~A ~A" i val (win i))))))) (let ((win (make-fft-window flat-top-window 32)) (unhappy #f)) (do ((i 0 (+ i 1))) ((or unhappy (= i 32))) (let ((val (+ 0.2156 (* -0.4160 (cos (/ (* 2 pi i) 31))) (* 0.2781 (cos (/ (* 4 pi i) 31))) (* -0.0836 (cos (/ (* 6 pi i) 31))) (* 0.0069 (cos (/ (* 8 pi i) 31)))))) (if (> (abs (- val (win i))) .1) ; error is much less, of course, in a bigger window (begin (set! unhappy #t) (snd-display #__line__ ";flat-top at ~D: ~A ~A" i val (win i))))))) (catch #t (lambda () (let ((gen (make-fft-window samaraki-window 16))) (if (not (vequal gen (float-vector 1.000 0.531 0.559 0.583 0.604 0.620 0.631 0.638 0.640 0.638 0.631 0.620 0.604 0.583 0.559 0.531))) (snd-display #__line__ ";samaraki window: ~A" gen))) (let ((gen (make-fft-window ultraspherical-window 16))) (if (not (vequal gen (float-vector 1.000 0.033 0.034 0.035 0.036 0.036 0.037 0.037 0.037 0.037 0.037 0.036 0.036 0.035 0.034 0.033))) (snd-display #__line__ ";ultraspherical window: ~A" gen))) (let ((gen (make-fft-window dolph-chebyshev-window 16))) (if (not (vequal gen (float-vector 1.000 0.033 0.034 0.035 0.036 0.036 0.037 0.037 0.037 0.037 0.037 0.036 0.036 0.035 0.034 0.033))) (snd-display #__line__ ";dolph-chebyshev window: ~A" gen))) (without-errors (let ((gen (make-fft-window dolph-chebyshev-window 16 1.0))) (if (not (vequal gen (float-vector 1.000 0.274 0.334 0.393 0.446 0.491 0.525 0.546 0.553 0.546 0.525 0.491 0.446 0.393 0.334 0.274))) (snd-display #__line__ ";dolph-chebyshev window: ~A" gen)))) (let ((val1 (make-fft-window ultraspherical-window 16 0.0 0.0)) (val2 (make-fft-window dolph-chebyshev-window 16 0.0))) (if (not (vequal val1 val2)) (snd-display #__line__ ";ultra/dolph 0: ~A ~A" val1 val2))) (let ((val1 (make-fft-window ultraspherical-window 16 0.0 1.0)) (val2 (make-fft-window samaraki-window 16 0.0))) (if (not (vequal val1 val2)) (snd-display #__line__ ";ultra/sam 0: ~A ~A" val1 val2))) (let ((val1 (make-fft-window ultraspherical-window 16 0.5 0.0)) (val2 (make-fft-window dolph-chebyshev-window 16 0.5))) (if (not (vequal val1 val2)) (snd-display #__line__ ";ultra/dolph 5: ~A ~A" val1 val2))) (let ((val1 (make-fft-window ultraspherical-window 16 0.5 1.0)) (val2 (make-fft-window samaraki-window 16 0.5))) (if (not (vequal val1 val2)) (snd-display #__line__ ";ultra/sam 5: ~A ~A" val1 val2))) (let ((val1 (dolph 16 1.0)) (val2 (make-fft-window dolph-chebyshev-window 16 1.0))) (if (not (vequal val1 val2)) (snd-display #__line__ ";dolph/dolph 1: ~A ~A" val1 val2)))) (lambda args (snd-display #__line__ ";new windows: ~A" args))) (if (defined? 'gsl-eigenvectors) (begin (let ((win (make-dpss-window 16 .01))) (if (not (vequal win (float-vector 0.964 0.973 0.981 0.987 0.992 0.996 0.999 1.000 1.000 0.999 0.996 0.992 0.987 0.981 0.973 0.964))) (snd-display #__line__ ";make-dpss-window 16 .01: ~A" win))) (let ((win (make-dpss-window 16 .1))) (if (not (vequal win (float-vector 0.090 0.193 0.332 0.494 0.664 0.818 0.936 1.000 1.000 0.936 0.818 0.664 0.494 0.332 0.193 0.090))) (snd-display #__line__ ";make-dpss-window 16 .1: ~A" win))) (let ((win (make-dpss-window 32 .09))) (if (not (vequal win (float-vector 0.004 0.011 0.025 0.050 0.086 0.138 0.206 0.290 0.388 0.496 0.610 0.722 0.823 0.908 0.968 1.000 1.000 0.968 0.908 0.823 0.722 0.610 0.496 0.388 0.290 0.206 0.138 0.086 0.050 0.025 0.011 0.004))) (snd-display #__line__ ";make-dpss-window 32 .09: ~A" win))) (for-each (lambda (n) (for-each (lambda (beta) (let ((win1 (make-dpss-window n beta)) (win2 (make-fft-window dpss-window n beta))) (if (not (vequal win1 win2)) (snd-display #__line__ ";dpss-windows:~% ~A~% ~A" win1 win2)))) (list .01 .07 .12 .2))) (list 16 32)))) (let ((win (make-papoulis-window 32))) (if (not (vequal win (float-vector 0.000 0.001 0.006 0.021 0.048 0.091 0.151 0.227 0.318 0.422 0.533 0.647 0.755 0.852 0.930 0.982 1.000 0.982 0.930 0.852 0.755 0.647 0.533 0.422 0.318 0.227 0.151 0.091 0.048 0.021 0.006 0.001))) (snd-display #__line__ ";make-papoulis-window 32: ~A" win))) (for-each (lambda (n) (let ((win1 (make-papoulis-window n)) (win2 (make-fft-window papoulis-window n))) (if (not (vequal win1 win2)) (snd-display #__line__ ";papoulis-windows:~% ~A~% ~A" win1 win2)))) (list 32 64 256)) (let ((v0 (make-float-vector 10)) (gen (make-env '(0 0 1 1 2 0) :scaler 0.5 :length 11)) (v1 (make-float-vector 10)) (gen1 (make-env '(0 0 1 1 2 0) :scaler 0.5 :length 11))) (print-and-check gen "env" "env linear, pass: 0 (dur: 11), index: 0, scaler: 0.5000, offset: 0.0000, data: [0 0 1 1 2 0]") (if (not (env? gen)) (snd-display #__line__ ";~A not env?" gen)) (if (fneq (mus-scaler gen) 0.5) (snd-display #__line__ ";env scaler ~F?" (mus-scaler gen))) (if (fneq (mus-increment gen) 1.0) (snd-display #__line__ ";env base (1.0): ~A?" (mus-increment gen))) (if (not (= (mus-length gen) 11)) (snd-display #__line__ ";env length: ~A" (mus-length gen))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v0 i) (env gen))) (let ((off 123.0)) (fill-float-vector v1 (begin (set! off (mus-offset gen1)) (if (env? gen1) (env gen1) -1.0))) (if (fneq off 0.0) (snd-display #__line__ ";mus-offset opt: ~A" off))) (if (not (vequal v0 v1)) (snd-display #__line__ ";map env: ~A ~A" v0 v1)) (if (or (fneq (v0 0) 0.0) (fneq (v0 1) .1) (fneq (v0 6) .4)) (snd-display #__line__ ";~A output: ~A" gen v0)) (if (fneq (env-interp 1.6 gen) 0.2) (snd-display #__line__ ";env-interp ~A at 1.6: ~F?" gen (env-interp 1.5 gen))) (set! gen (make-env :envelope '(0 1 1 0) :base 32.0 :length 11)) (if (fneq (mus-increment gen) 32.0) (snd-display #__line__ ";env base (32.0): ~A?" (mus-increment gen))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v0 i) (env gen))) (if (or (fneq (v0 0) 1.0) (fneq (v0 1) .698) (fneq (v0 8) .032)) (snd-display #__line__ ";~A output: ~A" gen v0)) (set! gen (make-env :envelope '(0 1 1 0) :base .0325 :length 11)) (if (fneq (mus-increment gen) .0325) (snd-display #__line__ ";env base (.0325): ~A?" (mus-increment gen))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v0 i) (env gen))) (if (or (fneq (v0 0) 1.0) (fneq (v0 1) .986) (fneq (v0 8) .513)) (snd-display #__line__ ";~A output: ~A" gen v0)) (set! gen (make-env :envelope '(0 1 1 .5 2 0) :base 0.0 :length 11 :offset 1.0)) (if (fneq (mus-offset gen) 1.0) (snd-display #__line__ ";mus-offset: ~A" (mus-offset gen))) (if (fneq (mus-increment gen) 0.0) (snd-display #__line__ ";env base (0.0): ~A?" (mus-increment gen))) (do ((i 0 (+ i 1))) ((= i 10)) (if (and (= i 3) (not (= (mus-location gen) 3))) (snd-display #__line__ ";env location: ~A?" (mus-location gen))) (set! (v0 i) (env gen))) (if (or (fneq (v0 0) 2.0) (fneq (v0 6) 1.5) (fneq (v0 8) 1.5)) (snd-display #__line__ ";~A output: ~A" gen v0)) (if (fneq (env-interp 1.5 gen) 1.5) (snd-display #__line__ ";env-interp ~A at 1.5: ~F?" gen (env-interp 1.5 gen))) (set! (mus-location gen) 6) (if (not (= (mus-location gen) 6)) (snd-display #__line__ ";set! mus-location ~A (6)?" (mus-location gen))) (let ((val (env gen))) (if (fneq val 1.5) (snd-display #__line__ ";set! mus-location 6 -> ~A (1.5)?" val))) (set! (mus-location gen) 0) (let ((val (env gen))) (if (fneq val 2.0) (snd-display #__line__ ";set! mus-location 0 -> ~A (2.0)?" val))) (let ((gen (make-env '(0 0 1 -1 2 0) :length 11))) (do ((i 0 (+ i 1))) ((= i 5)) (let ((val (env gen))) (if (fneq val (/ i -5.0)) (snd-display #__line__ ";neg env: ~D ~A" i val)))) (do ((i 0 (+ i 1))) ((= i 5)) (let ((val (env gen))) (if (fneq val (+ -1.0 (/ i 5.0))) (snd-display #__line__ ";neg env: ~D ~A" (+ i 5) val))))) (let ((gen (make-env '(0 0 1 -1 2 0) :length 11 :base 0.5)) (v (float-vector 0.0 -0.14869 -0.31950 -0.51571 -0.74110 -1.0 -0.74110 -0.51571 -0.31950 -0.14869))) (do ((i 0 (+ i 1))) ((= i 10)) (let ((val (env gen))) (if (fneq val (v i)) (snd-display #__line__ ";neg exp env: ~D ~A" i val)))) (mus-apply gen)) (let ((v (make-float-vector 10))) (let ((e (make-env '(0 0 1 1) :length 10))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v i) (env e))) (if (not (vequal v (float-vector 0.000 0.111 0.222 0.333 0.444 0.556 0.667 0.778 0.889 1.000))) (snd-display #__line__ ";simple ramp: ~A" v))) (let ((v (make-float-vector 10))) (let ((e (make-env '(0 0 1 1) :base 0 :length 8))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v i) (env e))) (if (not (vequal v (float-vector 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 1.000 1.000))) (snd-display #__line__ ";simple ramp, base 0: ~A" v)))) (let ((v (make-float-vector 10))) (let ((e (make-env '(0 0 1 1 2 .5) :base 0 :length 8))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v i) (env e))) (if (not (vequal v (float-vector 0.000 0.000 0.000 0.000 1.000 1.000 1.000 1.000 0.500 0.500))) (snd-display #__line__ ";two-step, base 0: ~A" v)))) (let ((e (make-env '((0 0) (1 1)) :length 10))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v i) (env e))) (if (not (vequal v (float-vector 0.000 0.111 0.222 0.333 0.444 0.556 0.667 0.778 0.889 1.000))) (snd-display #__line__ ";simple ramp embedded: ~A" v))) (let ((e (make-env '(0 1 1 0) :length 10))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v i) (env e))) (if (not (vequal v (float-vector 1.000 0.889 0.778 0.667 0.556 0.444 0.333 0.222 0.111 0.000))) (snd-display #__line__ ";simple ramp down: ~A" v))) (let ((e (make-env '(0 0 1 1 2 0) :length 10))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v i) (env e))) (if (not (vequal v (float-vector 0.000 0.200 0.400 0.600 0.800 1.000 0.750 0.500 0.250 0.000))) (snd-display #__line__ ";simple pyr: ~A" v))) (let ((e (make-env '((0 0) (1 1) (2 0)) :length 10))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v i) (env e))) (if (not (vequal v (float-vector 0.000 0.200 0.400 0.600 0.800 1.000 0.750 0.500 0.250 0.000))) (snd-display #__line__ ";simple pyr embedded: ~A" v))) (let ((e (make-env '(0 0 1 1 2 -.5) :length 10))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v i) (env e))) (if (not (vequal v (float-vector 0.000 0.200 0.400 0.600 0.800 1.000 0.625 0.250 -0.125 -0.500))) (snd-display #__line__ ";simple pyr -.5: ~A" v))) (let ((e (make-env '((0 0) (1 1) (2 -.5)) :length 10))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v i) (env e))) (if (not (vequal v (float-vector 0.000 0.200 0.400 0.600 0.800 1.000 0.625 0.250 -0.125 -0.500))) (snd-display #__line__ ";simple pyr -.5 embedded: ~A" v))) (let ((e (make-env '(0 0 1 1 2 -.5) :length 10))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v i) (env e))) (if (not (vequal v (float-vector 0.000 0.200 0.400 0.600 0.800 1.000 0.625 0.250 -0.125 -0.500))) (snd-display #__line__ ";simple pyr -.5: ~A" v)))) (let ((v (make-float-vector 10))) (let ((e (make-env (float-vector 0 0 1 1) :length 10))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v i) (env e))) (if (not (vequal v (float-vector 0.000 0.111 0.222 0.333 0.444 0.556 0.667 0.778 0.889 1.000))) (snd-display #__line__ ";simple ramp: ~A" v))) (let ((v (make-float-vector 10))) (let ((e (make-env (float-vector 0 0 1 1) :base 0 :length 8))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v i) (env e))) (if (not (vequal v (float-vector 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 1.000 1.000))) (snd-display #__line__ ";simple ramp, base 0: ~A" v)))) (let ((v (make-float-vector 10))) (let ((e (make-env (float-vector 0 0 1 1 2 .5) :base 0 :length 8))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v i) (env e))) (if (not (vequal v (float-vector 0.000 0.000 0.000 0.000 1.000 1.000 1.000 1.000 0.500 0.500))) (snd-display #__line__ ";two-step, base 0: ~A" v)))) (let ((e (make-env (float-vector 0 1 1 0) :length 10))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v i) (env e))) (if (not (vequal v (float-vector 1.000 0.889 0.778 0.667 0.556 0.444 0.333 0.222 0.111 0.000))) (snd-display #__line__ ";simple ramp down: ~A" v))) (let ((e (make-env (float-vector 0 0 1 1 2 0) :length 10))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v i) (env e))) (if (not (vequal v (float-vector 0.000 0.200 0.400 0.600 0.800 1.000 0.750 0.500 0.250 0.000))) (snd-display #__line__ ";simple pyr: ~A" v))) (let ((e (make-env (float-vector 0 0 1 1 2 -.5) :length 10))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v i) (env e))) (if (not (vequal v (float-vector 0.000 0.200 0.400 0.600 0.800 1.000 0.625 0.250 -0.125 -0.500))) (snd-display #__line__ ";simple pyr -.5: ~A" v))) (let ((e (make-env (float-vector 0 0 1 1 2 -.5) :length 10))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v i) (env e))) (if (not (vequal v (float-vector 0.000 0.200 0.400 0.600 0.800 1.000 0.625 0.250 -0.125 -0.500))) (snd-display #__line__ ";simple pyr -.5: ~A" v)))) (let ((v (make-float-vector 10))) (let ((e (make-env (vector 0 0 1 1) :length 10))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v i) (env e))) (if (not (vequal v (float-vector 0.000 0.111 0.222 0.333 0.444 0.556 0.667 0.778 0.889 1.000))) (snd-display #__line__ ";simple ramp: ~A" v))) (let ((v (make-float-vector 10))) (let ((e (make-env (vector 0 0 1 1) :base 0 :length 8))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v i) (env e))) (if (not (vequal v (float-vector 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 1.000 1.000))) (snd-display #__line__ ";simple ramp, base 0: ~A" v)))) (let ((v (make-float-vector 10))) (let ((e (make-env (vector 0 0 1 1 2 .5) :base 0 :length 8))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v i) (env e))) (if (not (vequal v (float-vector 0.000 0.000 0.000 0.000 1.000 1.000 1.000 1.000 0.500 0.500))) (snd-display #__line__ ";two-step, base 0: ~A" v)))) (let ((e (make-env (vector 0 1 1 0) :length 10))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v i) (env e))) (if (not (vequal v (float-vector 1.000 0.889 0.778 0.667 0.556 0.444 0.333 0.222 0.111 0.000))) (snd-display #__line__ ";simple ramp down: ~A" v))) (let ((e (make-env (vector 0 0 1 1 2 0) :length 10))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v i) (env e))) (if (not (vequal v (float-vector 0.000 0.200 0.400 0.600 0.800 1.000 0.750 0.500 0.250 0.000))) (snd-display #__line__ ";simple pyr: ~A" v))) (let ((e (make-env (vector 0 0 1 1 2 -.5) :length 10))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v i) (env e))) (if (not (vequal v (float-vector 0.000 0.200 0.400 0.600 0.800 1.000 0.625 0.250 -0.125 -0.500))) (snd-display #__line__ ";simple pyr -.5: ~A" v))) (let ((e (make-env (vector 0 0 1 1 2 -.5) :length 10))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v i) (env e))) (if (not (vequal v (float-vector 0.000 0.200 0.400 0.600 0.800 1.000 0.625 0.250 -0.125 -0.500))) (snd-display #__line__ ";simple pyr -.5: ~A" v)))) (let ((e (make-env '(0 0 1 1) :length 10))) (if (fneq (env-interp 1.0 e) 1.0) (snd-display #__line__ ";env-interp 0011 at 1: ~A" (env-interp 1.0 e))) (if (fneq (env-interp 2.0 e) 1.0) (snd-display #__line__ ";env-interp 0011 at 2: ~A" (env-interp 2.0 e))) (if (fneq (env-interp 0.0 e) 0.0) (snd-display #__line__ ";env-interp 0011 at 0: ~A" (env-interp 0.0 e))) (if (fneq (env-interp 0.444 e) 0.444) (snd-display #__line__ ";env-interp 0011 at .444: ~A" (env-interp 0.45 e))) (mus-reset e) (do ((i 0 (+ i 1))) ((= i 10)) (let ((val (env e))) (if (fneq val (* i .111111)) (snd-display #__line__ ";ramp env over 10: ~A at ~A" val i))))) (let ((e (make-env '(0 0 .5 .5 1 1) :base 32 :length 10)) (v (float-vector 0.0 0.0243 0.0667 0.1412 0.2716 0.5000 0.5958 0.7090 0.8425 1.0))) (do ((i 0 (+ i 1)) (x 0.0 (+ x 0.11111))) ((= i 10)) (let ((val (env-interp x e))) (if (fneq val (v i)) (snd-display #__line__ ";(0 .5 1) env-interp over 10: ~A at ~A (~A)" val i (v i)))))) (let ((e (make-env '(0 -1.0 1 1) :base 32 :length 10)) (v (float-vector -1.0 -0.9697 -0.9252 -0.8597 -0.7635 -0.6221 -0.4142 -0.1088 0.34017 1.0))) (do ((i 0 (+ i 1)) (x 0.0 (+ x 0.11111))) ((= i 10)) (let ((val (env-interp x e))) (if (fneq val (v i)) (snd-display #__line__ ";(-1 1) env-interp over 10: ~A at ~A (~A)" val i (v i)))))) (let ((e (make-env '(0 -1.0 .5 .5 1 0) :base 32 :length 10)) (v (float-vector -1.0 -0.952 -0.855 -0.661 -0.274 0.5 0.356 0.226 0.107 0.0))) (do ((i 0 (+ i 1)) (x 0.0 (+ x 0.11111))) ((= i 10)) (let ((val (env-interp x e))) (if (fneq val (v i)) (snd-display #__line__ ";(-1 .5 0) env-interp over 10: ~A at ~A (~A)" val i (v i)))))) (let ((e (make-env '(0 0.0 .5 .5 1 -1.0) :base 32 :length 10)) (v (float-vector 0.0 0.085 0.177 0.276 0.384 0.5 -0.397 -0.775 -0.933 -1.0))) (do ((i 0 (+ i 1)) (x 0.0 (+ x 0.11111))) ((= i 10)) (let ((val (env-interp x e))) (if (fneq val (v i)) (snd-display #__line__ ";(0 .5 -1) env-interp over 10: ~A at ~A (~A)" val i (v i)))))) (let ((e (make-env '(0 0 1 1) :length 10 :base 4.0))) (if (fneq (env-interp 1.0 e) 1.0) (snd-display #__line__ ";env-interp 0011 4 at 1: ~A" (env-interp 1.0 e))) (if (fneq (env-interp 0.0 e) 0.0) (snd-display #__line__ ";env-interp 0011 4 at 0: ~A" (env-interp 0.0 e))) (if (fneq (env-interp 0.45 e) 0.2839) (snd-display #__line__ ";env-interp 0011 4 at .45: ~A" (env-interp 0.45 e)))) (let ((e (make-env '(0 0 1 1) :length 10 :base 0.2))) (if (fneq (env-interp 1.0 e) 1.0) (snd-display #__line__ ";env-interp 0011 2 at 1: ~A" (env-interp 1.0 e))) (if (fneq (env-interp 0.0 e) 0.0) (snd-display #__line__ ";env-interp 0011 2 at 0: ~A" (env-interp 0.0 e))) (if (fneq (env-interp 0.45 e) 0.6387) (snd-display #__line__ ";env-interp 0011 2 at .45: ~A" (env-interp 0.45 e)))) (let ((val (let ((e (make-env '(0 0 1 1) :length 10 :offset 2.0))) (set! (mus-offset e) 3.0) (mus-offset e)))) (if (fneq val 3.0) (snd-display #__line__ ";set mus-offset env: ~A" val))) (let ((e (make-env '(0 0 1 1 2 0) :length 10)) (v (make-float-vector 10 0.0))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v i) (env e))) (if (not (vequal v (float-vector 0.000 0.200 0.400 0.600 0.800 1.000 0.750 0.500 0.250 0.000))) (snd-display #__line__ ";e set off 0: ~A" v)) (if (not (= (mus-length e) 10)) (snd-display #__line__ ";e set off 0 len: ~A" (mus-length e))) (if (fneq (mus-scaler e) 1.0) (snd-display #__line__ ";e set off 0 scl: ~A" (mus-scaler e))) (if (fneq (mus-offset e) 0.0) (snd-display #__line__ ";e set off 0 off: ~A" (mus-offset e))) (set! (mus-scaler e) 2.0) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v i) (env e))) (if (not (vequal v (float-vector 0.000 0.400 0.800 1.200 1.600 2.000 1.500 1.000 0.500 0.000))) (snd-display #__line__ ";e set off 1: ~A" v)) (if (not (= (mus-length e) 10)) (snd-display #__line__ ";e set off 1 len: ~A" (mus-length e))) (if (fneq (mus-scaler e) 2.0) (snd-display #__line__ ";e set off 1 scl: ~A" (mus-scaler e))) (if (fneq (mus-offset e) 0.0) (snd-display #__line__ ";e set off 1 off: ~A" (mus-offset e))) (set! (mus-offset e) 1.0) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v i) (env e))) (if (not (vequal v (float-vector 1.000 1.400 1.800 2.200 2.600 3.000 2.500 2.000 1.500 1.000))) (snd-display #__line__ ";e set off 2: ~A" v)) (if (not (= (mus-length e) 10)) (snd-display #__line__ ";e set off 2 len: ~A" (mus-length e))) (if (fneq (mus-scaler e) 2.0) (snd-display #__line__ ";e set off 2 scl: ~A" (mus-scaler e))) (if (fneq (mus-offset e) 1.0) (snd-display #__line__ ";e set off 2 off: ~A" (mus-offset e))) (set! (mus-length e) 19) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v i) (env e))) (if (not (vequal v (float-vector 1.000 1.222 1.444 1.667 1.889 2.111 2.333 2.556 2.778 3.000))) (snd-display #__line__ ";e set off 3: ~A" v)) (if (not (= (mus-length e) 19)) (snd-display #__line__ ";e set off 3 len: ~A" (mus-length e))) (if (fneq (mus-scaler e) 2.0) (snd-display #__line__ ";e set off 3 scl: ~A" (mus-scaler e))) (if (fneq (mus-offset e) 1.0) (snd-display #__line__ ";e set off 3 off: ~A" (mus-offset e)))) (let ((e (make-env (float-vector 0 0 1 1 2 0) :length 10)) (v (make-float-vector 10 0.0))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v i) (env e))) (if (not (vequal v (float-vector 0.000 0.200 0.400 0.600 0.800 1.000 0.750 0.500 0.250 0.000))) (snd-display #__line__ ";e from float-vector: ~A" v))) (let ((e1 (make-env '(0 0 1 1) :base 32.0 :length 11)) (v (float-vector 0.000 0.013 0.032 0.059 0.097 0.150 0.226 0.333 0.484 0.698 1.00))) (do ((i 0 (+ i 1))) ((> i 10)) (let ((val (env e1))) (if (fneq val (v i)) (snd-display #__line__ ";exp env direct (32.0): ~A ~A" val (v i)))))) (let ((e1 (make-env '(0 1 1 2) :base 32.0 :length 11)) (v (float-vector 1.000 1.013 1.032 1.059 1.097 1.150 1.226 1.333 1.484 1.698 2.00))) (do ((i 0 (+ i 1))) ((> i 10)) (let ((val (env e1))) (if (fneq val (v i)) (snd-display #__line__ ";exp env direct (32.0) offset: ~A ~A" val (v i)))))) (let ((e1 (make-env '((0 1) (1 2)) :base 32.0 :length 11)) (v (float-vector 1.000 1.013 1.032 1.059 1.097 1.150 1.226 1.333 1.484 1.698 2.00))) (do ((i 0 (+ i 1))) ((> i 10)) (let ((val (env e1))) (if (fneq val (v i)) (snd-display #__line__ ";exp env direct (32.0) offset embedded: ~A ~A" val (v i)))))) (let ((e1 (make-env '(0 1 1 2) :base 32.0 :length 11)) (v (float-vector 1.000 1.013 1.032 1.059 1.097 1.150 1.226 1.333 1.484 1.698 2.00))) (do ((i 0 (+ i 1))) ((> i 10)) (let ((val (env e1))) (if (fneq val (v i)) (snd-display #__line__ ";exp env direct (32.0) offset (and dur): ~A ~A" val (v i)))))) (let ((e1 (make-env '(0 0 1 1) :base 0.032 :length 11)) (v (float-vector 0.000 0.301 0.514 0.665 0.772 0.848 0.902 0.940 0.967 0.986 1.0))) (do ((i 0 (+ i 1))) ((> i 10)) (let ((val (env e1))) (if (fneq val (v i)) (snd-display #__line__ ";exp env direct (.032): ~A ~A" val (v i)))))) (let ((e1 (make-env '(0 0 1 1) :base .03125 :length 11)) (e2 (make-env '(0 0 1 1 2 0) :base 32.0 :length 11)) (e3 (make-env '(0 0 .1 1 2 0) :base 1.1 :length 101))) (do ((i 0 (+ i 1))) ((= i 10)) (let ((lv1 (env-interp (* i .1) e1)) (lv2 (env e1)) (lv3 (env-interp (* i .2) e2)) (lv4 (env e2))) (if (ffneq lv1 lv2) (snd-display #__line__ ";env-interp[rmp ~F]: ~A (~A)?" (* .1 i) lv1 lv2)) (if (ffneq lv3 lv4) (snd-display #__line__ ";env-interp[pyr ~F]: ~A (~A)?" (* .2 i) lv3 lv4)))) (do ((i 0 (+ i 1))) ((= i 100)) (let ((lv5 (env-interp (* i .02) e3)) (lv6 (env e3))) (if (ffneq lv5 lv6) (snd-display #__line__ ";env-interp[tri ~F]: ~A (~A)?" (* .02 i) lv5 lv6))))) (let ((e1 (make-env '(0 0 1 1 2 0) :length 10)) (lv1 (make-float-vector 11)) (lv2 (make-float-vector 11)) (lv3 (make-float-vector 11))) (do ((i 0 (+ i 1))) ((= i 11)) (set! (lv1 i) (env e1))) (do ((i 0 (+ i 1))) ((= i 11)) (set! (lv2 i) (env e1))) (mus-reset e1) (do ((i 0 (+ i 1))) ((= i 11)) (set! (lv3 i) (env e1))) (if (not (vequal lv1 lv3)) (snd-display #__line__ ";mus-reset: ~A ~A?" lv1 lv3)) (if (not (vequal lv2 (make-float-vector 11))) (snd-display #__line__ ";mus-reset 1: ~A?" lv2))) (set! gen (make-env '(0 0 1 1 2 0) :length 11)) (do ((i 0 (+ i 1))) ((= i 4)) (env gen)) (let ((val (env gen))) (if (fneq val .8) (snd-display #__line__ ";env(5): ~A?" val)) (mus-reset gen) (do ((i 0 (+ i 1))) ((= i 4)) (env gen)) (set! val (env gen)) (if (fneq val .8) (snd-display #__line__ ";mus-reset (via reset): ~A?" val)) (set! (mus-location gen) 6) (let ((val (env gen))) (if (fneq val 0.8) (snd-display #__line__ ";set! mus-location 6 -> ~A (0.8)?" val))))) (let ((gen (make-env '(0 0 1 1) :base .032 :length 12))) (set! (mus-location gen) 5) (let ((val (env gen))) (if (fneq val 0.817) (snd-display #__line__ ";set env location with base: ~A ~A" val gen)))) (let ((gen (make-env '(0 0 1 1) :base .032 :length 12))) (set! (mus-location gen) 5) (let ((val (env gen))) (if (fneq val 0.817) (snd-display #__line__ ";set env location with base and dur: ~A ~A" val gen)))) (test-gen-equal (make-env '(0 0 1 1 2 0) :scaler 0.5 :length 10) (make-env '(0 0 1 1 2 0) :scaler 0.5 :length 10) (make-env '(0 0 1 1 2 0) :scaler 0.25 :length 10)) (test-gen-equal (make-env '(0 0 1 1 2 0) :scaler 0.5 :length 10) (make-env '(0 0 1 1 2 0) :scaler 0.5 :length 10) (make-env '(0 0 1 1 2 0) :scaler 0.5 :length 11)) (test-gen-equal (make-env '(0 0 1 1 2 0) :scaler 0.5 :length 10) (make-env '(0 0 1 1 2 0) :scaler 0.5 :length 10) (make-env '(0 0 1 1 3 0) :scaler 0.5 :length 10)) (test-gen-equal (make-env '((0 0) (1 1) (2 0)) :scaler 0.5 :length 10) (make-env '(0 0 1 1 2 0) :scaler 0.5 :length 10) (make-env '((0 0) (1 1) (3 0)) :scaler 0.5 :length 10)) (let ((var (catch #t (lambda () (make-env :envelope ())) (lambda args args)))) (if (not (eq? (car var) 'no-data)) (snd-display #__line__ ";make-env null env: ~A" var))) (let ((var (catch #t (lambda () (make-env :length 1)) (lambda args args)))) (if (not (eq? (car var) 'no-data)) (snd-display #__line__ ";make-env no env: ~A" var))) (let ((var (catch #t (lambda () (make-env :envelope '(0 0) :length -1)) (lambda args args)))) (if (not (eq? (car var) 'out-of-range)) (snd-display #__line__ ";make-env bad dur: ~A" var))) (let ((var (catch #t (lambda () (make-env :envelope '(0 0) :duration -1.0)) (lambda args args)))) (if (not (eq? (car var) 'out-of-range)) (snd-display #__line__ ";make-env bad duration: ~A" var))) (let ((var (catch #t (lambda () (make-env :envelope '(0 0) :base -1.0)) (lambda args args)))) (if (not (eq? (car var) 'out-of-range)) (snd-display #__line__ ";make-env bad base: ~A" var))) (let ((var (catch #t (lambda () (make-env :envelope '(1 1 0 0) :length 11)) (lambda args args)))) (if (not (eq? (car var) 'mus-error)) (snd-display #__line__ ";make-env bad env 1 1 0 0: ~A" var))) (let ((var (catch #t (lambda () (make-env :envelope '(0 1 -1 0) :length 11)) (lambda args args)))) (if (not (eq? (car var) 'mus-error)) (snd-display #__line__ ";make-env bad env 0 1 -1 0: ~A" var))) (let ((var (catch #t (lambda () (make-env :envelope '(0 1 1 0) :length 11 :length 10)) (lambda args args)))) (if (not (eq? (car var) 'mus-error)) (snd-display #__line__ ";make-env bad end/dur: ~A" var))) (let ((var (catch #t (lambda () (make-env :envelope '(0 0 1 1 2 0 1) :duration 1.0)) (lambda args args)))) (if (not (eq? (car var) 'bad-type)) (snd-display #__line__ ";make-env odd length env: ~A" var))) (let ((var (catch #t (lambda () (make-env :envelope (list "hi" 0 1 1 2 0) :duration 1.0)) (lambda args args)))) (if (not (eq? (car var) 'wrong-type-arg)) (snd-display #__line__ ";make-env env of non-number: ~A" var))) ;; env-any (let* ((env-any-1 (lambda (e func) (let* ((pts (mus-data e)) (mus-position mus-channels) (pt (min (* 2 (mus-position e)) (- (length pts) 4))) (val (/ (- (env e) (mus-offset e)) (mus-scaler e))) (y0 (min (pts (+ pt 1)) (pts (+ pt 3)))) (y1 (max (pts (+ pt 1)) (pts (+ pt 3)))) (new-val (func (/ (- val y0) (- y1 y0))))) (+ (mus-offset e) (* (mus-scaler e) (+ y0 (* (- y1 y0) new-val))))))) (sine-env-1 (lambda (e) (env-any-1 e (lambda (y) (* 0.5 (+ 1.0 (sin (+ (* -0.5 pi) (* pi y))))))))) (square-env-1 (lambda (e) (env-any-1 e (lambda (y) (* y y))))) (blackman4-env-1 (lambda (e) (env-any-1 e (lambda (y) (let ((cx (cos (* pi y)))) (+ 0.084037 (* cx (+ -.29145 (* cx (+ .375696 (* cx (+ -.20762 (* cx .041194))))))))))))) (multi-expt-env-1 (lambda (e expts) (env-any-1 e (lambda (y) (let ((b (expts (modulo (mus-channels e) (length expts))))) (/ (- (expt b y) 1.0) (- b 1.0)))))))) ;; assume sine-env square-env blackman4-env and multi-exp-env are available from generators.scm (8) (let ((val1 (with-sound ((make-float-vector 20)) (let ((e (make-env '(0 0 1 1 2 .25 3 1 4 0) :length 20))) (do ((i 0 (+ i 1))) ((= i 20)) (outa i (sine-env e)))))) (val2 (with-sound ((make-float-vector 20)) (let ((e (make-env '(0 0 1 1 2 .25 3 1 4 0) :length 20))) (do ((i 0 (+ i 1))) ((= i 20)) (outa i (sine-env e)))))) (val3 (with-sound ((make-float-vector 20)) (let ((e (make-env '(0 0 1 1 2 .25 3 1 4 0) :length 20))) (do ((i 0 (+ i 1))) ((= i 20)) (outa i (sine-env-1 e))))))) (if (not (vequal val1 val2)) (snd-display #__line__ ";sine-env straight and run: ~%; ~A~%; ~A" val1 val2)) (if (not (vequal val1 val3)) (snd-display #__line__ ";sine-env straight and scm: ~%; ~A~%; ~A" val1 val3))) (let ((val1 (with-sound ((make-float-vector 20)) (let ((e (make-env '(0 0 1 1 2 .25 3 1 4 0) :length 20))) (do ((i 0 (+ i 1))) ((= i 20)) (outa i (square-env e)))))) (val2 (with-sound ((make-float-vector 20)) (let ((e (make-env '(0 0 1 1 2 .25 3 1 4 0) :length 20))) (do ((i 0 (+ i 1))) ((= i 20)) (outa i (square-env e)))))) (val3 (with-sound ((make-float-vector 20)) (let ((e (make-env '(0 0 1 1 2 .25 3 1 4 0) :length 20))) (do ((i 0 (+ i 1))) ((= i 20)) (outa i (square-env-1 e))))))) (if (not (vequal val1 val2)) (snd-display #__line__ ";square-env straight and run: ~%; ~A~%; ~A" val1 val2)) (if (not (vequal val1 val3)) (snd-display #__line__ ";square-env straight and scm: ~%; ~A~%; ~A" val1 val3))) (let ((val1 (with-sound ((make-float-vector 20)) (let ((e (make-env '(0 0 1 1 2 .25 3 1 4 0) :length 20))) (do ((i 0 (+ i 1))) ((= i 20)) (outa i (blackman4-env e)))))) (val3 (with-sound ((make-float-vector 20)) (let ((e (make-env '(0 0 1 1 2 .25 3 1 4 0) :length 20))) (do ((i 0 (+ i 1))) ((= i 20)) (outa i (blackman4-env-1 e))))))) (if (not (vequal val1 val3)) (snd-display #__line__ ";blackman4-env straight and scm: ~%; ~A~%; ~A" val1 val3))) (let ((val1 (with-sound ((make-float-vector 20)) (let ((e (make-env '(0 0 1 1 2 .25 3 1 4 0) :length 20)) (bases (float-vector 32.0 0.3 1.5))) (do ((i 0 (+ i 1))) ((= i 20)) (outa i (multi-expt-env e bases)))))) (val2 (with-sound ((make-float-vector 20)) (let ((e (make-env '(0 0 1 1 2 .25 3 1 4 0) :length 20)) (bases (float-vector 32.0 0.3 1.5))) (do ((i 0 (+ i 1))) ((= i 20)) (outa i (multi-expt-env e bases)))))) (val3 (with-sound ((make-float-vector 20)) (let ((e (make-env '(0 0 1 1 2 .25 3 1 4 0) :length 20)) (bases (float-vector 32.0 0.3 1.5))) (do ((i 0 (+ i 1))) ((= i 20)) (outa i (multi-expt-env-1 e bases))))))) (if (not (vequal val1 val2)) (snd-display #__line__ ";multi-expt-env straight and run: ~%; ~A~%; ~A" val1 val2)) (if (not (vequal val1 val3)) (snd-display #__line__ ";multi-expt-env straight and scm: ~%; ~A~%; ~A" val1 val3))) (let ((val1 (with-sound ((make-float-vector 220)) (let ((e1 (make-env '(0 0 1 1 2 .25 3 1 4 0) :length 220)) (e2 (make-env '(0 0 1 1 2 .25 3 1 4 0) :length 220))) (do ((i 0 (+ i 1))) ((= i 220)) (outa i (env-any e1 (lambda (y1) (* y1 (env-any e2 (lambda (y2) y2)))))))))) (val2 (with-sound ((make-float-vector 220)) (let ((e1 (make-env '(0 0 1 1 2 .25 3 1 4 0) :length 220)) (e2 (make-env '(0 0 1 1 2 .25 3 1 4 0) :length 220))) (do ((i 0 (+ i 1))) ((= i 220)) (outa i (env-any e1 ; try it with and without "declare" (lambda (y1) (* y1 (env-any e2 (lambda (y2) y2))))))))))) (if (not (vequal val1 val2)) (snd-display #__line__ ";env-any recursive: ~%; ~A~%; ~A" val1 val2)))) (let ((ind (new-sound :size 20))) (select-sound ind) (map-channel (lambda (y) 1.0)) (bumpy) (let ((vals (channel->float-vector))) (if (not (vequal vals (float-vector 0.0 0.0 0.001 0.021 0.105 0.264 0.467 0.673 0.846 0.960 1.000 0.960 0.846 0.673 0.467 0.264 0.105 0.021 0.001 0.0))) (snd-display #__line__ ";bumpy: ~A" vals))) (if (fneq (channel-lp-inf) 1.0) ; just a fancy name for maxamp (snd-display #__line__ ";channel-lp-inf: ~A" (channel-lp-inf))) (linear-src-channel 2.0) (let ((vals (channel->float-vector))) (if (not (vequal vals (float-vector 0.000 0.001 0.105 0.467 0.846 1.000 0.846 0.467 0.105 0.001))) (snd-display #__line__ ";linear-src-channel: ~A" vals))) (let ((old-clip *clipping*)) (set! *clipping* #t) (save-sound-as "tst.snd") (let ((fvals (file->floats "tst.snd")) (vals (channel->float-vector))) (if (not (vequal vals fvals)) (snd-display #__line__ ";file->floats: ~A ~A" vals fvals))) (mus-sound-forget "tst.snd") (delete-file "tst.snd") (set! *clipping* old-clip)) (let ((hp (make-differentiator))) (map-channel (lambda (y) (differentiator hp y)))) (if (fneq (maxamp) .0013) (snd-display #__line__ ";differentiator: ~A" (maxamp))) (revert-sound ind) (let ((val (window-rms))) (if (fneq val 0.0) (snd-display #__line__ ";window-rms empty: ~A" val)) (set! (sample 10) 1.0) (set! val (window-rms)) (if (fneq val .218) (snd-display #__line__ ";window-rms 1: ~A" val)) (let ((vals (window-samples))) (if (or (not (float-vector? vals)) (not (= (length vals) 21)) (fneq (vals 10) 1.0)) (snd-display #__line__ ";window-samples: ~A" vals)))) (revert-sound ind) (let ((new-file-name (file-name ind))) (close-sound ind) (if (file-exists? new-file-name) (delete-file new-file-name)))) (let ((gen (make-table-lookup 440.0 :wave (partials->wave '(1 1 2 1)))) (gen1 (make-table-lookup 440.0 :wave (partials->wave '(1 1 2 1) (make-float-vector 512)))) ;;(gen2 (partials->wave '(1 1 2 1 3 1 4 1) #f #t)) (gen3 (make-table-lookup)) (v0 (make-float-vector 10)) (v1 (make-float-vector 10)) (gen4 (make-table-lookup 440.0 :wave (partials->wave '(1 1 2 1)))) (v2 (make-float-vector 10))) (print-and-check gen "table-lookup" "table-lookup freq: 440.000Hz, phase: 0.000, length: 512, interp: linear") (if (not (= (mus-length gen) 512)) (snd-display #__line__ ";table-lookup length: ~A?" (mus-length gen))) (if (not (= (mus-length gen3) 512)) (snd-display #__line__ ";default table-lookup length: ~A?" (mus-length gen3))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v0 i) (table-lookup gen 0.0)) (set! (v1 i) (mus-apply gen1 0.0))) (fill-float-vector v2 (if (table-lookup? gen4) (table-lookup gen4 0.0) -1.0)) (if (not (vequal v0 v2)) (snd-display #__line__ ";map table-lookup: ~A ~A" v0 v2)) (set! gen4 (make-table-lookup 440.0 :wave (partials->wave (float-vector 1 1 2 1)))) (fill-float-vector v2 (table-lookup gen4)) (if (not (vequal v0 v2)) (snd-display #__line__ ";map table-lookup (no fm): ~A ~A" v0 v2)) (if (not (table-lookup? gen)) (snd-display #__line__ ";~A not table-lookup?" gen)) (if (not (float-vector? (mus-data gen))) (snd-display #__line__ ";mus-data table-lookup: ~A" (mus-data gen))) (if (fneq (mus-phase gen) 1.253787) (snd-display #__line__ ";table-lookup phase: ~F?" (mus-phase gen))) (set! (mus-phase gen) 1.0) (if (fneq (mus-phase gen) 1.0) (snd-display #__line__ ";set! table-lookup phase: ~F?" (mus-phase gen))) (if (fneq (mus-frequency gen) 440.0) (snd-display #__line__ ";table-lookup frequency: ~F?" (mus-frequency gen))) (set! (mus-frequency gen) 100.0) (if (fneq (mus-frequency gen) 100.0) (snd-display #__line__ ";set! table-lookup frequency: ~F?" (mus-frequency gen))) (if (or (fneq (v0 1) 0.373) (fneq (v0 8) 1.75)) (snd-display #__line__ ";table-lookup output: ~A" v0)) (do ((i 0 (+ i 1))) ((= i 10)) (if (fneq (v0 i) (v1 i)) (snd-display #__line__ ";mus-apply table-lookup at ~D: ~A ~A?" i (v0 i) (v1 i)))) (set! gen (make-table-lookup 440.0 :wave (phase-partials->wave (list 1 1 0 2 1 (* pi .5))))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v0 i) (table-lookup gen 0.0))) (if (or (fneq (v0 1) 1.094) (fneq (v0 8) .421)) (snd-display #__line__ ";table-lookup phase output: ~A" v0)) (if (or (fneq (float-vector-peak (partials->wave '(1 1 2 1))) 1.76035475730896) (fneq (float-vector-peak (partials->wave '(1 1 2 1) #f #t)) 1.0) (fneq (float-vector-peak (partials->wave '(1 1 2 1 3 1 4 1) #f #t)) 1.0)) (snd-display #__line__ ";normalized partials?")) (set! (mus-data gen) (phase-partials->wave (list 1 1 0 2 1 (* pi .5)) #f #t))) (let ((tag (catch #t (lambda () (phase-partials->wave (list 1 .3 2 .2))) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";bad length arg to phase-partials->wave: ~A" tag))) (let ((tag (catch #t (lambda () (phase-partials->wave (list "hiho" .3 2 .2))) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";bad harmonic arg to phase-partials->wave: ~A" tag))) (let ((tag (catch #t (lambda () (phase-partials->wave (list))) (lambda args (car args))))) (if (not (eq? tag 'no-data)) (snd-display #__line__ ";nil list to phase-partials->wave: ~A" tag))) (let ((vals (phase-partials->wave (list 1 1 0) (make-float-vector 16) #f))) (do ((i 0 (+ i 1))) ((= i 16)) (if (fneq (vals i) (sin (/ (* 2 pi i) 16))) (snd-display #__line__ ";phase-partials->wave 1 1 0 at ~D: ~A ~A" i (vals i) (sin (/ (* 2 pi i) 16)))))) (let ((vals (phase-partials->wave (list 1 1 (* .25 pi)) (make-float-vector 16) #f))) (do ((i 0 (+ i 1))) ((= i 16)) (if (fneq (vals i) (sin (+ (* .25 pi) (/ (* 2 pi i) 16)))) (snd-display #__line__ ";phase-partials->wave 1 1 .25 at ~D: ~A ~A" i (vals i) (sin (+ (* .25 pi) (/ (* 2 pi i) 16))))))) (let ((vals (phase-partials->wave (float-vector 1 1 0 2 1 0) (make-float-vector 16) #f))) (do ((i 0 (+ i 1))) ((= i 16)) (if (fneq (vals i) (+ (sin (/ (* 2 pi i) 16)) (sin (/ (* 4 pi i) 16)))) (snd-display #__line__ ";phase-partials->wave 1 1 0 2 1 0 at ~D: ~A ~A" i (vals i) (+ (sin (/ (* 2 pi i) 16)) (sin (/ (* 4 pi i) 16))))))) (let ((vals (phase-partials->wave (float-vector 1 1 0 2 1 (* .5 pi)) (make-float-vector 16) #f))) (do ((i 0 (+ i 1))) ((= i 16)) (if (fneq (vals i) (+ (sin (/ (* 2 pi i) 16)) (sin (+ (* .5 pi) (/ (* 4 pi i) 16))))) (snd-display #__line__ ";phase-partials->wave 1 1 0 2 1 .5 at ~D: ~A ~A" i (vals i) (+ (sin (/ (* 2 pi i) 16)) (sin (+ (* .5 pi) (/ (* 4 pi i) 16)))))))) (test-gen-equal (make-table-lookup 440.0 :wave (partials->wave (float-vector 1 1 2 1))) (make-table-lookup 440.0 :wave (partials->wave '(1 1 2 1))) (make-table-lookup 100.0 :wave (partials->wave '(1 1 2 1)))) (test-gen-equal (make-table-lookup 440.0 :wave (partials->wave '(1 1 2 1))) (make-table-lookup 440.0 :wave (partials->wave '(1 1 2 1))) (make-table-lookup 440.0 :wave (partials->wave '(1 1 2 .5)))) (test-gen-equal (make-table-lookup-with-env 440.0 '(0 0 1 1)) (make-table-lookup-with-env 440.0 (list 0 0 1 1)) (make-table-lookup-with-env 440.0 '(0 0 1 1 2 0))) (let ((tag (catch #t (lambda () (partials->wave (list .5 .3 .2))) (lambda args (car args))))) (if (not (eq? tag 'bad-type)) (snd-display #__line__ ";odd length arg to partials->wave: ~A" tag))) (let ((hi (make-table-lookup :size 256))) (if (not (= (mus-length hi) 256)) (snd-display #__line__ ";table-lookup set length: ~A?" (mus-length hi)))) (let ((tag (catch #t (lambda () (make-table-lookup :size 0)) (lambda args (car args))))) (if (not (eq? tag 'out-of-range)) (snd-display #__line__ ";table-lookup size 0: ~A" tag))) (let ((gen (make-table-lookup 440.0 :wave (partials->wave '(1 1)))) (incr (/ (* 2 pi 440.0) 22050.0))) (do ((i 0 (+ i 1)) (a 0.0 (+ a incr))) ((= i 1100)) (let ((val1 (sin a)) (val2 (gen 0.0))) (if (fneq val1 val2) (snd-display #__line__ ";table lookup (1 1): ~A: ~A ~A" i val1 val2))))) (let ((gen (make-table-lookup 4.0 :wave (partials->wave '(1 1)))) (incr (/ (* 2 pi 4.0) 22050.0))) (do ((i 0 (+ i 1)) (a 0.0 (+ a incr))) ((= i 1100)) (let ((val1 (sin a)) (val2 (gen 0.0))) (if (fneq val1 val2) (snd-display #__line__ ";table lookup (1 1) 4: ~A: ~A ~A" i val1 val2))))) (let ((gen (make-table-lookup 440.0 :wave (partials->wave '(1 .75 3 .25)))) (incr (/ (* 2 pi 440.0) 22050.0))) (do ((i 0 (+ i 1)) (a 0.0 (+ a incr))) ((= i 1100)) (let ((val1 (+ (* .75 (sin a)) (* .25 (sin (* 3 a))))) (val2 (gen 0.0))) (if (fneq val1 val2) (snd-display #__line__ ";table lookup (1 .75 3 .25): ~A: ~A ~A" i val1 val2))))) (let ((gen (make-table-lookup 0.0 :wave (partials->wave '(1 1)))) (gen1 (make-table-lookup 40.0 :wave (partials->wave '(1 1)))) (incr (/ (* 2 pi 40.0) 22050.0)) (a1 0.0)) (do ((i 0 (+ i 1)) (a 0.0 (+ a incr))) ((= i 100)) (let ((fm (sin a)) (val1 (sin a1)) (val2 (table-lookup gen (table-lookup gen1 0.0)))) (set! a1 (+ a1 fm)) (if (fneq val1 val2) (snd-display #__line__ ";lookup/lookup fm: ~A: ~A ~A" i val1 val2))))) (for-each (lambda (args) (let ((type (car args)) (vals (cadr args))) (let ((tbl1 (make-table-lookup :frequency 0.0 :size 4 :type type))) (float-vector-set! (mus-data tbl1) 1 1.0) (let ((v (make-float-vector 10))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v i) (table-lookup tbl1 (* .1 pi)))) (if (and (not (vequal v vals)) (not (= type mus-interp-all-pass)) (or (not (= type mus-interp-none)) (not (vequal v (float-vector 0.000 0.000 0.000 0.000 0.000 0.000 1.000 1.000 1.000 1.000))))) (snd-display #__line__ ";tbl interp ~A: ~A" type v)) (if (not (= (mus-interp-type tbl1) type)) (snd-display #__line__ ";tbl interp-type (~A): ~A" type (mus-interp-type tbl1))))))) (list (list mus-interp-none (float-vector 0.000 0.000 0.000 0.000 0.000 1.000 1.000 1.000 1.000 1.000)) (list mus-interp-linear (float-vector 0.000 0.200 0.400 0.600 0.800 1.000 0.800 0.600 0.400 0.200)) (list mus-interp-lagrange (float-vector 0.000 0.120 0.280 0.480 0.720 1.000 0.960 0.840 0.640 0.360)) (list mus-interp-all-pass (float-vector 1.000 0.000 0.429 0.143 0.095 0.905 0.397 0.830 0.793 0.912)) (list mus-interp-hermite (float-vector 0.000 0.168 0.424 0.696 0.912 1.000 0.912 0.696 0.424 0.168)))) ;; this is different if doubles -- not sure whether it's a bug or not (let ((size 1000) (tbl-size 1024)) (define (test-tbl beg end freq amp mc-ratio index) (let* ((sine (let ((v (make-float-vector tbl-size)) (xp (/ (* 2 pi) tbl-size))) (do ((i 0 (+ i 1)) (x 0.0 (+ x xp))) ((= i tbl-size) v) (set! (v i) (sin x))))) (fm (make-table-lookup (* mc-ratio freq) :wave sine)) (carrier (make-table-lookup freq :wave sine))) (do ((i beg (+ i 1))) ((= i end)) (outa i (* amp (table-lookup carrier (* index (table-lookup fm)))))))) (define (test-fm1 beg end freq amp mc-ratio index) (let ((fm (make-oscil (* mc-ratio freq))) (carrier (make-oscil freq))) (do ((i beg (+ i 1))) ((= i end)) (outa i (* amp (oscil carrier (* index (oscil fm)))))))) (let ((v1 (with-sound ((make-float-vector size) :srate 44100) (test-tbl 0 size 200 1 1 1))) (v2 (with-sound ((make-float-vector size) :srate 44100) (test-fm1 0 size 200 1 1 1)))) (if (and (not (vequal v1 v2)) (> (float-vector-peak (float-vector-subtract! v1 v2)) .002)) (snd-display #__line__ ";fm/tbl peak diff (1 1): ~A" (float-vector-peak (float-vector-subtract! v1 v2))))) (do ((i 0 (+ i 1))) ((= i 10)) (let ((ratio (+ 1 (random 4))) (index (random 0.1))) (let ((v1 (with-sound ((make-float-vector size) :srate 44100) (test-tbl 0 size 20 1 ratio index))) (v2 (with-sound ((make-float-vector size) :srate 44100) (test-fm1 0 size 20 1 ratio index)))) (if (and (not (vequal v1 v2)) (> (float-vector-peak (float-vector-subtract! v1 v2)) .002)) (snd-display #__line__ ";fm/tbl peak diff ~A ~A: ~A" ratio index (float-vector-peak (float-vector-subtract! v1 v2)))))))) (let ((gen0 (make-polyshape 440.0 :coeffs (partials->polynomial '(1 1)))) (gen (make-polyshape 440.0 :partials '(1 1) :kind mus-chebyshev-first-kind)) (v0 (make-float-vector 10)) (gen1 (make-polyshape 440.0)) (v1 (make-float-vector 10))) (print-and-check gen "polyshape" "polyshape freq: 440.000Hz, phase: 0.000, coeffs[2]: [0 1]") (if (not (= (mus-length gen) 2)) (snd-display #__line__ ";polyshape length: ~A?" (mus-length gen))) (do ((i 0 (+ i 1))) ((= i 10)) (let ((val0 (polyshape gen0 1.0 0.0)) (val (polyshape gen 1.0 0.0))) (if (fneq val val0) (snd-display #__line__ ";polyshape: ~A is not ~F?" val val0)) (set! (v0 i) val))) (fill-float-vector v1 (if (polyshape? gen1) (polyshape gen1 1.0 0.0) -1.0)) (if (not (vequal v0 v1)) (snd-display #__line__ ";map polyshape: ~A ~A" v0 v1)) (set! gen1 (make-polyshape 440.0 :coeffs (partials->polynomial '(1 1)))) (fill-float-vector v1 (polyshape gen1 1.0)) (if (not (vequal v0 v1)) (snd-display #__line__ ";1 map polyshape: ~A ~A" v0 v1)) (if (not (polyshape? gen)) (snd-display #__line__ ";~A not polyshape?" gen)) (if (fneq (mus-phase gen) 1.253787) (snd-display #__line__ ";polyshape phase: ~F?" (mus-phase gen))) (set! (mus-phase gen) 1.0) (if (fneq (mus-phase gen) 1.0) (snd-display #__line__ ";set! polyshape phase: ~F?" (mus-phase gen))) (if (fneq (mus-frequency gen) 440.0) (snd-display #__line__ ";polyshape frequency: ~F?" (mus-frequency gen))) (set! (mus-frequency gen) 100.0) (if (fneq (mus-frequency gen) 100.0) (snd-display #__line__ ";polyshape frequency: ~F?" (mus-frequency gen))) (if (not (float-vector? (mus-data gen))) (snd-display #__line__ ";mus-data polyshape: ~A" (mus-data gen))) (if (or (fneq (v0 1) 0.992) (fneq (v0 8) 0.538)) (snd-display #__line__ ";polyshape output: ~A" v0)) (set! (mus-data gen0) (make-float-vector 32)) (set! (mus-length gen0) 32) (if (not (= (mus-length gen0) 32)) (snd-display #__line__ ";set mus-length polyshape: ~A" (mus-length gen0)))) (test-gen-equal (make-polyshape 440.0 :partials '(1 1)) (make-polyshape 440.0) (make-polyshape 100.0 :partials '(1 1))) (test-gen-equal (make-polyshape 440.0 :partials '(1 1)) (make-polyshape 440.0) (make-polyshape 440.0 :partials '(1 1 2 .5))) (test-gen-equal (make-polyshape 440.0 :partials '(1 1)) (make-polyshape 440.0 :partials (float-vector 1 1)) (make-polyshape 440.0 :partials '(1 .5))) (test-gen-equal (make-polyshape 440.0 :partials (list 1 .1 2 1 3 .5)) (make-polyshape 440.0 :partials (float-vector 1 .1 2 1 3 .5)) (make-polyshape 440.0 :partials '(1 .1 2 .1 3 .5))) (let ((gen (make-polyshape 440.0 :partials '(1 1))) (happy #t)) (do ((i 0 (+ i 1))) ((or (not happy) (= i 1100))) (let* ((a (mus-phase gen)) (val1 (cos a)) (val2 (gen 1.0 0.0))) (if (fneq val1 val2) (begin (snd-display #__line__ ";polyshaper (1 1) ~A: ~A ~A" i val1 val2) (set! happy #f)))))) (let ((gen (make-polyshape 440.0)) ; check default for partials: '(1 1) (happy #t)) (do ((i 0 (+ i 1))) ((or (not happy) (= i 1100))) (let* ((a (mus-phase gen)) (val1 (cos a)) (val2 (gen 1.0 0.0))) (if (fneq val1 val2) (begin (snd-display #__line__ ";polyshaper default: '(1 1) ~A: ~A ~A" i val1 val2) (set! happy #f)))))) (let ((gen (make-polyshape 440.0 :partials (float-vector 1 1))) (happy #t)) (do ((i 0 (+ i 1))) ((or (not happy) (= i 1100))) (let* ((a (mus-phase gen)) (val1 (* .5 (cos a))) (val2 (gen 0.5 0.0))) (if (fneq val1 val2) (begin (snd-display #__line__ ";polyshaper (1 1) .5 index ~A: ~A ~A" i val1 val2) (set! happy #f)))))) (let ((var (catch #t (lambda () (make-polyshape 440.0 :coeffs 3.14)) (lambda args args)))) (if (not (eq? (car var) 'wrong-type-arg)) (snd-display #__line__ ";make-polyshape bad coeffs: ~A" var))) (let ((gen (make-polyshape 0.0 :coeffs (partials->polynomial '(1 1)))) (gen1 (make-polyshape 40.0 :coeffs (partials->polynomial '(1 1)))) (a1 0.0) (incr (/ (* 2 pi 40.0) 22050.0)) (happy #t)) (do ((i 0 (+ i 1)) (a 0.0 (+ a incr))) ((or (not happy) (= i 400))) (let ((fm (cos a)) (val1 (cos a1)) (val2 (polyshape gen 1.0 (polyshape gen1 1.0)))) (set! a1 (+ a1 fm)) (if (> (abs (- val1 val2)) .002) (begin (snd-display #__line__ ";polyshape fm: ~A: ~A ~A" i val1 val2) (set! happy #f)))))) (for-each (lambda (amps name) (let ((data1 (make-float-vector 100)) (data2 (make-float-vector 100)) (data3 (make-float-vector 100)) (n (length amps)) (incr (hz->radians 1.0))) (do ((i 0 (+ i 1)) (angle 0.0 (+ angle incr))) ((= i 100)) (float-vector-set! data1 i (mus-chebyshev-t-sum angle amps))) (do ((k 0 (+ k 1)) (kincr 0.0 (+ kincr incr))) ((= k n)) (do ((i 0 (+ i 1)) (angle 0.0 (+ angle kincr))) ((= i 100)) (float-vector-set! data3 i (cos angle))) (float-vector-scale! data3 (float-vector-ref amps k)) (float-vector-add! data2 data3)) (let ((fudge *mus-float-equal-fudge-factor*)) (set! *mus-float-equal-fudge-factor* .0001) (if (not (mus-arrays-equal? data1 data2)) (snd-display #__line__ "~A: ~A~%~A~%" name data1 data2)) (set! *mus-float-equal-fudge-factor* fudge)))) (list (float-vector 0.0 1.0) (float-vector 0.0 0.5 0.25 0.25) (make-float-vector 100 0.01) (make-float-vector 1000 0.001)) (list 'one-cos 'three-cos 'hundred-cos 'thousand-cos)) (for-each (lambda (amps name) (let ((data1 (make-float-vector 100)) (data2 (make-float-vector 100)) (data3 (make-float-vector 100)) (n (length amps)) (incr (hz->radians 1.0))) (do ((i 0 (+ i 1)) (angle 0.0 (+ angle incr))) ((= i 100)) (float-vector-set! data1 i (mus-chebyshev-u-sum angle amps))) (do ((k 0 (+ k 1)) (kincr 0.0 (+ kincr incr))) ((= k n)) (do ((i 0 (+ i 1)) (angle 0.0 (+ angle kincr))) ((= i 100)) (float-vector-set! data3 i (sin angle))) (float-vector-scale! data3 (float-vector-ref amps k)) (float-vector-add! data2 data3)) (let ((fudge *mus-float-equal-fudge-factor*)) (set! *mus-float-equal-fudge-factor* .0001) (if (not (mus-arrays-equal? data1 data2)) (snd-display #__line__ "~A: ~A~%~A~%" name data1 data2)) (set! *mus-float-equal-fudge-factor* fudge)))) (list (float-vector 0.0 1.0) (float-vector 0.0 0.5 0.25 0.25) (make-float-vector 100 0.01) (make-float-vector 1000 0.001)) (list 'one-sin 'three-sin 'hundred-sin 'thousand-sin)) (for-each (lambda (camps samps name) (let ((data1 (make-float-vector 100)) (data2 (make-float-vector 100)) (data3 (make-float-vector 100)) (n (length camps)) (incr (hz->radians 1.0))) (do ((i 0 (+ i 1)) (angle 0.0 (+ angle incr))) ((= i 100)) (float-vector-set! data1 i (mus-chebyshev-tu-sum angle camps samps))) (do ((k 0 (+ k 1)) (kincr 0.0 (+ kincr incr))) ((= k n)) (do ((i 0 (+ i 1)) (angle 0.0 (+ angle kincr))) ((= i 100)) (float-vector-set! data3 i (sin angle))) (float-vector-scale! data3 (float-vector-ref samps k)) (float-vector-add! data2 data3) (do ((i 0 (+ i 1)) (angle 0.0 (+ angle kincr))) ((= i 100)) (float-vector-set! data3 i (cos angle))) (float-vector-scale! data3 (float-vector-ref camps k)) (float-vector-add! data2 data3)) (let ((fudge *mus-float-equal-fudge-factor*)) (set! *mus-float-equal-fudge-factor* .0001) (if (not (mus-arrays-equal? data1 data2)) (snd-display "~A: ~A~%~A~%" name data1 data2)) (set! *mus-float-equal-fudge-factor* fudge)))) (list (float-vector 0.0 1.0) (float-vector 0.0 0.25 0.0 0.25) (make-float-vector 100 .004) (make-float-vector 1000 0.0005)) (list (float-vector 0.0 0.0) (float-vector 0.0 0.25 0.25 0.0) (make-float-vector 100 .006) (make-float-vector 1000 0.0005)) (list 'one-tu 'three-tu 'hundred-tu 'thousand-tu)) ;; polywave (let ((gen0 (make-polywave 440.0 '(1 1))) (gen (make-polywave 440.0 :partials '(1 1) :type mus-chebyshev-first-kind)) (v0 (make-float-vector 10)) (gen1 (make-polywave 440.0)) (v1 (make-float-vector 10))) (print-and-check gen "polywave" "polywave freq: 440.000Hz, phase: 0.000, coeffs[2]: [0 1]") (if (not (= (mus-length gen) 2)) (snd-display #__line__ ";polywave length: ~A?" (mus-length gen))) (do ((i 0 (+ i 1))) ((= i 10)) (let ((val0 (polywave gen0 0.0)) (val (polywave gen 0.0))) (if (fneq val val0) (snd-display #__line__ ";polywave: ~A is not ~F?" val val0)) (set! (v0 i) val))) (fill-float-vector v1 (if (polywave? gen1) (polywave gen1 0.0) -1.0)) (if (not (vequal v0 v1)) (snd-display #__line__ ";map polywave: ~A ~A" v0 v1)) (set! gen1 (make-polywave 440.0 (float-vector 1 1))) (fill-float-vector v1 (polywave gen1)) (if (not (vequal v0 v1)) (snd-display #__line__ ";1 map polywave: ~A ~A" v0 v1)) (if (not (polywave? gen)) (snd-display #__line__ ";~A not polywave?" gen)) (if (fneq (mus-phase gen) 1.253787) (snd-display #__line__ ";polywave phase: ~F?" (mus-phase gen))) (set! (mus-phase gen) 1.0) (if (fneq (mus-phase gen) 1.0) (snd-display #__line__ ";set! polywave phase: ~F?" (mus-phase gen))) (if (fneq (mus-frequency gen) 440.0) (snd-display #__line__ ";polywave frequency: ~F?" (mus-frequency gen))) (set! (mus-frequency gen) 100.0) (if (fneq (mus-frequency gen) 100.0) (snd-display #__line__ ";polywave frequency: ~F?" (mus-frequency gen))) (if (not (float-vector? (mus-data gen))) (snd-display #__line__ ";mus-data polywave: ~A" (mus-data gen))) (if (or (fneq (v0 1) 0.992) (fneq (v0 8) 0.538)) (snd-display #__line__ ";polywave output: ~A" v0))) (test-gen-equal (make-polywave 440.0 :partials '(1 1)) (make-polywave 440.0) (make-polywave 100.0 :partials '(1 1))) (test-gen-equal (make-polywave 440.0 '(1 1)) (make-polywave 440.0) (make-polywave 440.0 '(1 1 2 .5))) (test-gen-equal (make-polywave 440.0 '(1 1)) (make-polywave 440.0 (float-vector 1 1)) (make-polywave 440.0 '(1 .5))) (test-gen-equal (make-polywave 440.0 (list 1 .1 2 1 3 .5)) (make-polywave 440.0 (float-vector 1 .1 2 1 3 .5)) (make-polywave 440.0 '(1 .1 2 .1 3 .5))) (let ((gen (make-polywave 440.0 '(1 1))) (happy #t)) (do ((i 0 (+ i 1))) ((or (not happy) (= i 1100))) (let* ((a (mus-phase gen)) (val1 (cos a)) (val2 (gen 0.0))) (if (fneq val1 val2) (begin (snd-display #__line__ ";polywaver (1 1) ~A: ~A ~A" i val1 val2) (set! happy #f)))))) (let ((gen (make-polywave 440.0)) ; check default for partials: '(1 1) (happy #t)) (do ((i 0 (+ i 1))) ((or (not happy) (= i 1100))) (let* ((a (mus-phase gen)) (val1 (cos a)) (val2 (gen 0.0))) (if (fneq val1 val2) (begin (snd-display #__line__ ";polywaver default: '(1 1) ~A: ~A ~A" i val1 val2) (set! happy #f)))))) (let ((gen (make-polywave 440.0 (float-vector 1 1))) (happy #t)) (set! (mus-scaler gen) 0.5) (do ((i 0 (+ i 1))) ((or (not happy) (= i 1100))) (let* ((a (mus-phase gen)) (val1 (* .5 (cos a))) (val2 (gen 0.0))) (if (fneq val1 val2) (begin (snd-display #__line__ ";polywaver (1 1) .5 index ~A: ~A ~A" i val1 val2) (set! happy #f)))))) (let ((old-srate *clm-srate*) (v0 (make-float-vector 4410)) (v1 (make-float-vector 4410))) (set! *clm-srate* 44100) (for-each (lambda (k) (let ((gen (make-polywave 100.0 (list 1 0.5 k 0.5))) (incr (/ (* 2.0 pi 100.0) 44100)) (kincr (/ (* 2.0 k pi 100.0) 44100))) (do ((i 0 (+ i 1))) ((= i 4410)) (set! (v0 i) (polywave gen))) (do ((i 0 (+ i 1)) (ph 0.0 (+ ph incr)) (kph 0.0 (+ kph kincr))) ((= i 4410)) (float-vector-set! v1 i (+ (cos ph) (cos kph)))) (float-vector-scale! v1 0.5) (if (not (vequal v0 v1)) (snd-display #__line__ ";polywave ~D vs cos: ~A" k (float-vector-peak-and-location (float-vector-subtract! v0 v1)))))) (list 2 19 20 29 30 39 40 60 100)) (for-each (lambda (n) (let ((gen1 (make-polywave 100.0 (list n 1.0))) (gen2 (make-oscil (* n 100.0) (/ pi 2))) (happy #t)) (do ((i 0 (+ i 1))) ((or (not happy) (= i 1000))) (let ((val1 (polywave gen1)) (val2 (oscil gen2))) (if (fneq val1 val2) (begin (set! happy #f) (snd-display #__line__ ";polywave ~A at ~A: ~A ~A" n i val1 val2))))))) (list 1 8 50 128)) (for-each (lambda (n) (let ((gen1 (make-polywave 100.0 (list n 1.0) mus-chebyshev-second-kind)) (gen2 (make-oscil (* n 100.0))) (happy #t)) (do ((i 0 (+ i 1))) ((or (not happy) (= i 1000))) (let ((val1 (polywave gen1)) (val2 (oscil gen2))) (if (fneq val1 val2) (begin (set! happy #f) (snd-display #__line__ ";polywave second ~A at ~A: ~A ~A" n i val1 val2))))))) (list 1 8 50 128)) (for-each (lambda (n) (let ((gen1 (make-polyshape 100.0 :partials (list n 1.0))) (gen2 (make-oscil (* n 100.0) (/ pi 2))) (happy #t)) (do ((i 0 (+ i 1))) ((or (not happy) (= i 1000))) (let ((val1 (polyshape gen1)) (val2 (oscil gen2))) (if (fneq val1 val2) (begin (set! happy #f) (snd-display #__line__ ";polyshape ~A at ~A: ~A ~A" n i val1 val2))))))) (list 1 8 16)) (for-each (lambda (n) (let ((gen1 (make-polyshape 100.0 :partials (list n 1.0) :kind mus-chebyshev-second-kind)) (gen2 (make-oscil (* n 100.0))) (happy #t)) (do ((i 0 (+ i 1))) ((or (not happy) (= i 1000))) (let ((val1 (polyshape gen1)) (val2 (oscil gen2))) (if (fneq val1 val2) (begin (set! happy #f) (snd-display #__line__ ";polyshape second ~A at ~A: ~A ~A" n i val1 val2))))))) (list 1 8 16)) (for-each (lambda (n) (let ((gen1 (make-polywave 100.0 (list n 1.0) mus-chebyshev-first-kind)) (gen2 (make-oscil (* n 100.0) (/ pi 2))) (max-dist 0.0)) (do ((i 0 (+ i 1))) ((= i 1000)) (let ((val1 (polywave gen1)) (val2 (oscil gen2))) (set! max-dist (max max-dist (abs (- val1 val2)))))) (if (fneq max-dist 0.0) (snd-display #__line__ ";polywave run ~A: ~A" n max-dist)))) (list 1 3 30 200)) (for-each (lambda (n) (let ((gen1 (make-polywave 100.0 (list n 1.0) mus-chebyshev-second-kind)) (gen2 (make-oscil (* n 100.0))) (max-dist 0.0)) (do ((i 0 (+ i 1))) ((= i 1000)) (let ((val1 (polywave gen1)) (val2 (oscil gen2))) (set! max-dist (max max-dist (abs (- val1 val2)))))) (if (fneq max-dist 0.0) (snd-display #__line__ ";polywave second run ~A: ~A" n max-dist)))) (list 1 3 30 200)) (for-each (lambda (n) (let ((gen1 (make-polyshape 100.0 :partials (list n 1.0) :kind mus-chebyshev-first-kind)) (gen2 (make-oscil (* n 100.0) (/ pi 2))) (max-dist 0.0)) (do ((i 0 (+ i 1))) ((= i 1000)) (let ((val1 (polyshape gen1)) (val2 (oscil gen2))) (set! max-dist (max max-dist (abs (- val1 val2)))))) (if (fneq max-dist 0.0) (snd-display #__line__ ";polyshape run ~A: ~A" n max-dist)))) (list 1 3 25)) (for-each (lambda (n) (let ((gen1 (make-polyshape 100.0 :partials (list n 1.0) :kind mus-chebyshev-second-kind)) (gen2 (make-oscil (* n 100.0))) (max-dist 0.0)) (do ((i 0 (+ i 1))) ((= i 1000)) (let ((val1 (polyshape gen1)) (val2 (oscil gen2))) (set! max-dist (max max-dist (abs (- val1 val2)))))) (if (fneq max-dist 0.0) (snd-display #__line__ ";polyshape second run ~A: ~A" n max-dist)))) (list 1 3 25)) (let ((gen (make-polywave 100.0 (list 1 .9 3 .1 4 0.0)))) (let ((vals (mus-data gen))) (if (or (not (float-vector? vals)) (not (vequal vals (float-vector 0.000 0.900 0.000 0.100 0.00)))) (snd-display #__line__ ";polywave mus-data: ~A" vals) (begin (float-vector-set! (mus-data gen) 2 .1) (float-vector-set! (mus-data gen) 3 0.0) (let ((happy #t) (gen1 (make-oscil 100.0 (/ pi 2))) (gen2 (make-oscil 200.0 (/ pi 2)))) (do ((i 0 (+ i 1))) ((or (not happy) (= i 1000))) (let ((val1 (polywave gen)) (val2 (+ (* .9 (oscil gen1)) (* .1 (oscil gen2))))) (if (fneq val1 val2) (begin (set! happy #f) (snd-display #__line__ ";polywave set mus-data at ~A: ~A ~A" i val1 val2)))))))))) (set! *clm-srate* old-srate)) ;; check dc (do ((i 2 (+ i 1))) ((= i 7)) (let ((cfs (make-list (* 2 i) 0.1))) (do ((k 0 (+ k 2))) ((>= k (length cfs))) (set! (cfs k) (/ k 2))) (let ((p (make-polywave 100.0 cfs mus-chebyshev-second-kind))) (let ((val (polywave p))) (if (fneq val 0.1) (snd-display #__line__ ";polywave ~D order second 0-coeff: ~A" i val)))))) (do ((i 2 (+ i 1))) ((= i 7)) (let ((cfs (make-list (* 2 i) 0.1))) (do ((k 0 (+ k 2))) ((>= k (length cfs))) (set! (cfs k) (/ k 2))) (let ((p (make-polywave 100.0 cfs mus-chebyshev-first-kind))) (let ((val (polywave p))) (if (fneq val (* 0.1 i)) (snd-display #__line__ ";polywave ~D order first 0-coeff: ~A" i val)))))) (let ((var (catch #t (lambda () (make-polywave 440.0 3.14)) (lambda args args)))) (if (not (eq? (car var) 'wrong-type-arg)) (snd-display #__line__ ";make-polywave bad coeffs: ~A" var))) (let ((gen (make-wave-train 440.0 0.0 (make-float-vector 20))) (v0 (make-float-vector 10)) (gen1 (make-wave-train 440.0 0.0 (make-float-vector 20))) (v1 (make-float-vector 10))) (print-and-check gen "wave-train" "wave-train freq: 440.000Hz, phase: 0.000, size: 20, interp: linear") (do ((i 0 (+ i 1))) ((= i 20)) (float-vector-set! (mus-data gen) i (* i .5)) (float-vector-set! (mus-data gen1) i ((mus-data gen) i))) (if (not (= (length (mus-data gen)) 20)) (snd-display #__line__ ";wave-train data length: ~A?" (length (mus-data gen)))) (if (not (= (mus-length gen) 20)) (snd-display #__line__ ";wave-train length: ~A?" (mus-length gen))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v0 i) (wave-train gen 0.0))) (fill-float-vector v1 (if (wave-train? gen1) (wave-train gen1) -1.0)) (if (not (vequal v0 v1)) (snd-display #__line__ ";map wave-train: ~A ~A" v0 v1)) (if (not (wave-train? gen)) (snd-display #__line__ ";~A not wave-train?" gen)) (if (fneq (mus-phase gen) 0.0) (snd-display #__line__ ";wave-train phase: ~F?" (mus-phase gen))) (set! (mus-phase gen) 1.0) (if (fneq (mus-phase gen) 1.0) (snd-display #__line__ ";set wave-train phase: ~F?" (mus-phase gen))) (if (fneq (mus-frequency gen) 440.0) (snd-display #__line__ ";wave-train frequency: ~F?" (mus-frequency gen))) (set! (mus-frequency gen) 100.0) (if (fneq (mus-frequency gen) 100.0) (snd-display #__line__ ";set wave-train freq: ~A" (mus-frequency gen))) (if (or (fneq (v0 1) 0.5) (fneq (v0 8) 4.0)) (snd-display #__line__ ";wave-train output: ~A" v0)) (mus-reset gen) (if (fneq (mus-phase gen) 0.0) (snd-display #__line__ ";wt reset phase: ~A" (mus-phase gen))) (let ((val (wave-train gen 0.0))) (if (fneq val 0.0) (snd-display #__line__ ";wt reset data: ~A" val))) (if (not (float-vector? (mus-data gen))) (snd-display #__line__ ";mus-data wave-train: ~A" (mus-data gen))) (set! (mus-data gen) (make-float-vector 3))) (test-gen-equal (make-wave-train 440.0 0.0 (make-float-vector 20)) (make-wave-train 440.0 0.0 (make-float-vector 20)) (make-wave-train 100.0 0.0 (make-float-vector 20))) (test-gen-equal (make-wave-train 440.0 0.0 (make-float-vector 20)) (make-wave-train 440.0 0.0 (make-float-vector 20)) (make-wave-train 440.0 1.0 (make-float-vector 20))) (test-gen-equal (make-wave-train-with-env 440.0 '(0 0 1 1)) (make-wave-train-with-env 440.0 (list 0 0 1 1)) (make-wave-train-with-env 440.0 '(0 0 1 1 2 0))) (let ((hi (make-wave-train :size 256))) (if (not (= (mus-length hi) 256)) (snd-display #__line__ ";wave-train set length: ~A?" (mus-length hi))) (set! (mus-length hi) 128) (if (not (= (mus-length hi) 128)) (snd-display #__line__ ";set wave-train set length: ~A?" (mus-length hi)))) (for-each (lambda (args) (let ((type (car args)) (vals (cadr args))) (let ((tbl1 (make-wave-train :frequency 3000.0 :initial-phase (/ (* 2.0 pi .2) 4) :size 4 :type type))) (float-vector-set! (mus-data tbl1) 1 1.0) (let ((v (make-float-vector 10))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v i) (wave-train tbl1 0.0))) ;(wave-train tbl1 (/ (* 2 pi .2) 4)))) (if (not (vequal v vals)) (snd-display #__line__ ";wt tbl interp ~A: ~A ~A" type v (mus-describe tbl1))) (if (not (= (mus-interp-type tbl1) type)) (snd-display #__line__ ";wt tbl interp-type (~A): ~A" type (mus-interp-type tbl1))))))) (list (list mus-interp-none (float-vector 0.000 1.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 1.000)) (list mus-interp-linear (float-vector 0.200 0.800 0.000 0.000 0.000 0.000 0.000 0.000 0.200 0.800)) (list mus-interp-lagrange (float-vector 0.120 0.960 -0.080 0.000 0.000 0.000 0.000 0.000 0.120 0.960)) (list mus-interp-hermite (float-vector 0.168 0.912 -0.064 -0.016 0.000 0.000 0.000 0.000 0.168 0.912)))) (let ((tag (catch #t (lambda () (make-wave-train :size 0)) (lambda args (car args))))) (if (not (eq? tag 'out-of-range)) (snd-display #__line__ ";wave-train size 0: ~A" tag))) (let ((ind (new-sound "fmv.snd" :size 10 :comment "line 20501"))) (if (not (= (framples) 10)) (snd-display #__line__ ";new-sound size(10): ~A" (framples))) (map-channel (lambda (y) 1.0) 7 8) (if (not (= (framples) 15)) (snd-display #__line__ ";map-channel 7 8: ~A" (framples))) (map-channel (lambda (y) 1.0)) (if (not (= (framples) 15)) (snd-display #__line__ ";map-channel (no dur): ~A" (framples))) (revert-sound ind) (map-channel (lambda (y) 1.0) 9 10) (if (not (= (framples) 19)) (snd-display #__line__ ";map-channel 9 10: ~A" (framples))) (if (> (edit-position ind 0) 2) (snd-display #__line__ ";map-channel pad edits: ~A" (edit-position ind 0))) (revert-sound ind) (map-channel (lambda (y) 1.0) 10 10) (if (not (= (framples) 20)) (snd-display #__line__ ";map-channel 10 10: ~A" (framples))) (if (> (edit-position ind 0) 2) (snd-display #__line__ ";map-channel pad edits (2): ~A" (edit-position ind 0))) (revert-sound ind) (map-channel (lambda (y) 1.0) 20 10) (if (not (= (framples) 30)) (snd-display #__line__ ";map-channel 20 10: ~A" (framples))) (if (> (edit-position ind 0) 2) (snd-display #__line__ ";map-channel pad edits (3): ~A" (edit-position ind 0))) (revert-sound ind) (if (scan-channel (lambda (y) #f) 30 10) (snd-display #__line__ ";scan-channel past end?")) (let ((new-file-name (file-name ind))) (close-sound ind) (if (file-exists? new-file-name) (delete-file new-file-name)))) (let ((ind (new-sound :size 1000))) (let* ((table (float-vector 0.0 .1 .2 .3 .4 .5 .6)) (gen (make-wave-train 1000.0 :wave table))) (map-channel (lambda (y) (wave-train gen))) (let ((mx (maxamp))) (if (fneq mx 0.6) (snd-display #__line__ ";wt 0 max: ~A" mx))) (if (not (vequal (channel->float-vector 0 30) (float-vector 0.000 0.100 0.200 0.300 0.400 0.500 0.600 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.100 0.200 0.300 0.400 0.500 0.600))) (snd-display #__line__ ";wt 0 data: ~A" (channel->float-vector 0 30))) (if (not (vequal (channel->float-vector 85 30) (float-vector 0.000 0.000 0.000 0.000 0.000 0.100 0.200 0.300 0.400 0.500 0.600 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.100 0.200 0.300))) (snd-display #__line__ ";wt 0 data 85: ~A" (channel->float-vector 85 30))) (undo)) (let* ((table (make-float-vector 10 .1)) (gen (make-wave-train 1000.0 :initial-phase pi :wave table))) ; initial-phase is confusing in this context! (map-channel (lambda (y) (wave-train gen))) (let ((mx (maxamp))) (if (fneq mx 0.1) (snd-display #__line__ ";wt 1 max: ~A" mx))) (if (not (vequal (channel->float-vector 0 30) (float-vector 0.100 0.100 0.100 0.100 0.100 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.000 0.000))) (let ((op *print-length*)) (set! *print-length* 32) (snd-display #__line__ ";wt 1 data: ~A" (channel->float-vector 0 30)) (set! *print-length* op))) (undo)) (let* ((table (make-float-vector 10 .1)) (gen (make-wave-train 2000.0 :wave table))) (map-channel (lambda (y) (wave-train gen))) (let ((mx (maxamp))) (if (fneq mx 0.1) (snd-display #__line__ ";wt 2 max: ~A" mx))) (if (not (vequal (channel->float-vector 0 30) (float-vector 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.000 0.000 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.000 0.100 0.100 0.100 0.100 0.100 0.100 0.100))) (snd-display #__line__ ";wt 2 data: ~A" (channel->float-vector 0 30))) (if (and (not (vequal (channel->float-vector 440 30) (float-vector 0.000 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.000 0.000 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.000 0.100 0.100 0.100 0.100 0.100 0.100))) ;; if double, round off is just enough different to cause an off-by-1 problem here (and below) (not (vequal (channel->float-vector 440 30) (float-vector 0.000 0.000 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.000 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.000 0.100 0.100 0.100 0.100 0.100 0.100)))) (snd-display #__line__ ";wt 2 data 440: ~A" (channel->float-vector 440 30))) (undo)) (let* ((table (make-float-vector 10 .1)) (gen (make-wave-train 3000.0 :wave table))) (map-channel (lambda (y) (wave-train gen))) (let ((mx (maxamp))) (if (fneq mx 0.2) (snd-display #__line__ ";wt 3 max: ~A" mx))) (if (not (vequal (channel->float-vector 0 30) (float-vector 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.200 0.200 0.100 0.100 0.100 0.100 0.100 0.200 0.200 0.200 0.100 0.100 0.100 0.100 0.100 0.200 0.200 0.100 0.100 0.100 0.100 0.100))) (snd-display #__line__ ";wt 3 data: ~A" (channel->float-vector 0 30))) (if (not (vequal (channel->float-vector 440 30) (float-vector 0.100 0.200 0.200 0.200 0.100 0.100 0.100 0.100 0.100 0.200 0.200 0.100 0.100 0.100 0.100 0.100 0.200 0.200 0.200 0.100 0.100 0.100 0.100 0.100 0.200 0.200 0.100 0.100 0.100 0.100))) (snd-display #__line__ ";wt 3 data 440: ~A" (channel->float-vector 440 30))) (undo)) (let* ((table (make-float-vector 10 .1)) (gen (make-wave-train 5000.0 :wave table))) (map-channel (lambda (y) (wave-train gen))) (let ((mx (maxamp))) (if (fneq mx 0.3) (snd-display #__line__ ";wt 4 max: ~A" mx))) (if (not (vequal (channel->float-vector 0 30) (float-vector 0.100 0.100 0.100 0.100 0.100 0.200 0.200 0.200 0.200 0.300 0.200 0.200 0.200 0.200 0.300 0.200 0.200 0.200 0.300 0.200 0.200 0.200 0.200 0.300 0.200 0.200 0.200 0.300 0.200 0.200))) (snd-display #__line__ ";wt 4 data: ~A" (channel->float-vector 0 30))) (if (not (vequal (channel->float-vector 440 30) (float-vector 0.200 0.200 0.300 0.200 0.200 0.200 0.300 0.200 0.200 0.200 0.300 0.300 0.200 0.200 0.200 0.300 0.200 0.200 0.200 0.300 0.200 0.200 0.200 0.200 0.300 0.200 0.200 0.200 0.300 0.200))) (snd-display #__line__ ";wt 4 data 440: ~A" (channel->float-vector 440 30))) (undo)) (let* ((table (make-float-vector 10 .1)) (gen (make-wave-train 1000.0 :wave table)) (e (make-env '(0 1 1 2) :length 1001)) (base-freq (mus-frequency gen))) (map-channel (lambda (y) (let ((result (wave-train gen))) (set! (mus-frequency gen) (* base-freq (env e))) result))) (let ((mx (maxamp))) (if (fneq mx 0.1) (snd-display #__line__ ";wt 5 max: ~A" mx))) (if (not (vequal (channel->float-vector 0 30) (float-vector 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.100 0.100 0.100 0.100 0.100 0.100 0.100))) (snd-display #__line__ ";wt 5 data: ~A" (channel->float-vector 0 30))) (if (not (vequal (channel->float-vector 440 30) (float-vector 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.000 0.000 0.000 0.000 0.000 0.000 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.000 0.000 0.000 0.000 0.000 0.100))) (snd-display #__line__ ";wt 5 data 440: ~A" (channel->float-vector 440 30))) (if (not (vequal (channel->float-vector 900 30) (float-vector 0.100 0.000 0.000 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.000 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.000 0.000 0.100 0.100 0.100 0.100))) (snd-display #__line__ ";wt 5 data 900: ~A" (channel->float-vector 900 30))) (undo)) (let* ((table (make-float-vector 10 .1)) (gen (make-wave-train 500.0 :wave table)) (ctr 0)) (map-channel (lambda (y) (let ((result (wave-train gen))) (if (> ctr 22) (begin (set! ctr 0) (float-vector-scale! (mus-data gen) 1.05)) (set! ctr (+ ctr 1))) result))) (let ((mx (maxamp))) (if (fneq mx 0.704) (snd-display #__line__ ";wt 6 max: ~A" mx))) (if (not (vequal (channel->float-vector 0 30) (float-vector 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";wt 6 data: ~A" (channel->float-vector 0 30))) (if (and (not (vequal (channel->float-vector 440 30) (float-vector 0.000 0.241 0.241 0.241 0.241 0.241 0.241 0.241 0.241 0.241 0.241 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) (not (vequal (channel->float-vector 440 30) (float-vector 0.000 0.000 0.241 0.241 0.241 0.241 0.241 0.241 0.241 0.241 0.241 0.241 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000)))) (snd-display #__line__ ";wt 6 data 440: ~A" (channel->float-vector 440 30))) (if (not (vequal (channel->float-vector 900 30) (float-vector 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.639 0.639 0.639))) (snd-display #__line__ ";wt 6 data 900: ~A" (channel->float-vector 900 30))) (undo)) (let ((fname (file-name ind))) (close-sound ind) (delete-file fname))) (let ((gen (make-readin "oboe.snd" 0 1490)) (v0 (make-float-vector 10)) (gen1 (make-readin "oboe.snd" 0 1490)) (v1 (make-float-vector 10))) (print-and-check gen "readin" "readin oboe.snd[chan 0], loc: 1490, dir: 1") (do ((i 0 (+ i 1))) ((= i 10)) (set! (v0 i) (readin gen))) (fill-float-vector v1 (if (readin? gen1) (if (= (mus-channel gen1) 0) (readin gen1) 1.0) (if (string=? (mus-file-name gen1) "oboe.snd") -1.0 1.0))) (if (not (vequal v0 v1)) (snd-display #__line__ ";map readin: ~A ~A" v0 v1)) (if (not (readin? gen)) (snd-display #__line__ ";~A not readin?" gen)) (if (not (mus-input? gen)) (snd-display #__line__ ";~A not input?" gen)) (if (not (= (mus-length gen) 50828)) (snd-display #__line__ ";readin length: ~A?" (mus-length gen))) (if (not (= (mus-channel gen) 0)) (snd-display #__line__ ";readin chan: ~A?" (mus-channel gen))) (if (not (string=? (mus-file-name gen) "oboe.snd")) (snd-display #__line__ ";readin mus-file-name: ~A" (mus-file-name gen))) (if (or (fneq (v0 1) -0.009) (fneq (v0 7) .029)) (snd-display #__line__ ";readin output: ~A" v0)) (set! (mus-location gen) 1000) (if (not (= (mus-location gen) 1000)) (snd-display #__line__ ";set! mus-location: ~A?" (mus-location gen))) (let ((val (readin gen))) (if (fneq val 0.033) (snd-display #__line__ ";set! mus-location readin: ~A?" val))) (set! (mus-increment gen) -1) (if (fneq (mus-increment gen) -1.0) (snd-display #__line__ ";set increment readin: ~A" (mus-increment gen)))) (let ((tag (catch #t (lambda () (make-readin "/baddy/hiho" 0 124)) (lambda args args)))) (if (not (eq? (car tag) 'no-such-file)) (snd-display #__line__ ";make-readin w/o file: ~A" tag))) (let ((tag (catch #t (lambda () (make-readin "oboe.snd" 123 124)) (lambda args args)))) (if (not (eq? (car tag) 'out-of-range)) (snd-display #__line__ ";make-readin with bad chan: ~A" tag))) (test-gen-equal (make-readin "oboe.snd" 0) (make-readin "oboe.snd" 0) (make-readin "oboe.snd" 0 1230)) (test-gen-equal (make-readin "oboe.snd" 0 :size 512) (make-readin "oboe.snd" 0 :size 512) (make-readin "pistol.snd" 0 :size 512)) (test-gen-equal (make-readin "2.snd" 1) (make-readin "2.snd" 1) (make-readin "2.snd" 0)) (let ((gen (make-readin "2.snd" 1 :size 1024)) (v0 (make-float-vector 10))) (print-and-check gen "readin" "readin 2.snd[chan 1], loc: 0, dir: 1") (do ((i 0 (+ i 1))) ((= i 10)) (set! (v0 i) (readin gen))) (if (not (= (mus-channel gen) 1)) (snd-display #__line__ ";readin chan 1: ~A?" (mus-channel gen))) (if (or (fneq (v0 1) 0.010) (fneq (v0 7) -.006)) (snd-display #__line__ ";readin 1 output: ~A" v0)) (print-and-check gen "readin" "readin 2.snd[chan 1], loc: 10, dir: 1")) (let ((gen (make-file->sample "oboe.snd")) (v0 (make-float-vector 10))) (print-and-check gen "file->sample" "file->sample oboe.snd") (if (not (mus-input? gen)) (snd-display #__line__ ";~A not input?" gen)) (if (not (= (mus-length gen) 50828)) (snd-display #__line__ ";file->sample length: ~A?" (mus-length gen))) (if (not (string=? (mus-file-name gen) "oboe.snd")) (snd-display #__line__ ";file->sample mus-file-name: ~A" (mus-file-name gen))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v0 i) (file->sample gen (+ 1490 i)))) (if (not (file->sample? gen)) (snd-display #__line__ ";~A not file->sample?" gen)) (if (or (fneq (v0 1) -0.009) (fneq (v0 7) .029)) (snd-display #__line__ ";file->sample output: ~A" v0)) (if (fneq (mus-increment gen) 0.0) (snd-display #__line__ ";file->sample increment: ~A" (mus-increment gen))) (set! (mus-increment gen) 1.0) (if (fneq (mus-increment gen) 1.0) (snd-display #__line__ ";file->sample set increment: ~A" (mus-increment gen))) (mus-reset gen)) ; a no-op I hope (let* ((ind (open-sound "oboe.snd")) (gen (make-snd->sample ind)) (gen1 (make-snd->sample ind)) (v0 (make-float-vector 10))) (print-and-check gen "snd->sample" "snd->sample reading oboe.snd (1 chan) at 0:[no readers]") (if (equal? gen gen1) (snd-display #__line__ ";snd->sample eq? not itself?")) (if (not (mus-input? gen)) (snd-display #__line__ ";snd->sample ~A not input?" gen)) (if (not (= (framples ind) (mus-length gen))) (snd-display #__line__ ";snd->sample len: ~A ~A" (framples ind) (mus-length gen))) (if (not (string=? (mus-file-name gen) (string-append cwd "oboe.snd"))) (snd-display #__line__ ";snd->sample mus-file-name: ~A ~A" (mus-file-name gen) (string-append cwd "oboe.snd"))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v0 i) (snd->sample gen (+ 1490 i)))) (if (not (snd->sample? gen)) (snd-display #__line__ ";~A not snd->sample?" gen)) (if (or (fneq (v0 1) -0.009) (fneq (v0 7) .029)) (snd-display #__line__ ";snd->sample output: ~A" v0)) (if (not (= (mus-channels gen) 1)) (snd-display #__line__ ";snd->sample channels: ~A" (mus-channels gen))) (if (not (= (mus-location gen) 1499)) (snd-display #__line__ ";snd->sample location: ~A" (mus-location gen))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v0 i) (ina (+ 1490 i) gen))) (if (or (fneq (v0 1) -0.009) (fneq (v0 7) .029)) (snd-display #__line__ ";snd->sample ina output: ~A" v0)) (close-sound ind)) (let* ((ind (open-sound "2.snd")) (gen (make-snd->sample ind)) (v0 (make-float-vector 10))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v0 i) (snd->sample gen (+ 1490 i) 0)) (set! (v0 i) (snd->sample gen (+ 1490 i) 1))) (print-and-check gen "snd->sample" "snd->sample reading 2.snd (2 chans) at 1499:[#, #]") (if (not (mus-input? gen)) (snd-display #__line__ ";snd->sample ~A not input?" gen)) (if (not (string=? (mus-file-name gen) (string-append cwd "2.snd"))) (snd-display #__line__ ";snd->sample mus-file-name: ~A ~A" (mus-file-name gen) (string-append cwd "2.snd"))) (if (not (snd->sample? gen)) (snd-display #__line__ ";~A not snd->sample?" gen)) (if (not (= (mus-channels gen) 2)) (snd-display #__line__ ";snd->sample channels (2): ~A" (mus-channels gen))) (if (not (= (mus-location gen) 1499)) (snd-display #__line__ ";snd->sample location (2): ~A" (mus-location gen))) (close-sound ind)) (let ((gen (make-file->frample "oboe.snd")) (v0 (make-float-vector 10)) (g1 (float-vector 0.0))) (print-and-check gen "file->frample" "file->frample oboe.snd" "file->frample oboe.snd") (if (not (mus-input? gen)) (snd-display #__line__ ";~A not input?" gen)) (if (not (= (mus-length gen) 50828)) (snd-display #__line__ ";file->frample length: ~A?" (mus-length gen))) (if (not (string=? (mus-file-name gen) "oboe.snd")) (snd-display #__line__ ";file->frample mus-file-name: ~A" (mus-file-name gen))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v0 i) ((file->frample gen (+ 1490 i) g1) 0))) (if (not (file->frample? gen)) (snd-display #__line__ ";~A not file->frample?" gen)) (if (or (fneq (v0 1) -0.009) (fneq (v0 7) .029)) (snd-display #__line__ ";file->frample output: ~A" v0))) (if (file-exists? "fmv.snd") (delete-file "fmv.snd")) (if (file-exists? "fmv1.snd") (delete-file "fmv1.snd")) (if (file-exists? "fmv2.snd") (delete-file "fmv2.snd")) (if (file-exists? "fmv3.snd") (delete-file "fmv3.snd")) (let ((gen (make-sample->file "fmv.snd" 2 mus-lshort mus-riff))) (print-and-check gen "sample->file" "sample->file fmv.snd") (if (not (mus-output? gen)) (snd-display #__line__ ";~A not output?" gen)) (if (not (sample->file? gen)) (snd-display #__line__ ";~A not sample->file?" gen)) (if (not (= (mus-length gen) *clm-file-buffer-size*)) (snd-display #__line__ ";sample->file length: ~A?" (mus-length gen))) (let ((genx gen)) (if (not (equal? genx gen)) (snd-display #__line__ ";sample->file equal? ~A ~A" genx gen))) (if (not (string=? (mus-file-name gen) "fmv.snd")) (snd-display #__line__ ";sample->file mus-file-name: ~A" (mus-file-name gen))) (do ((i 0 (+ i 1))) ((= i 100)) (sample->file gen i 0 (* i .001)) (sample->file gen i 1 (* i .01))) (outa 50 .015 gen) (outb 50 .15 gen) (out-any 60 .015 0 gen) (out-any 60 .15 1 gen) (mus-close gen)) (let* ((gen (make-file->sample "fmv.snd")) (val0 (in-any 20 0 gen)) (val1 (in-any 20 1 gen)) (val2 (ina 30 gen)) (val3 (inb 30 gen)) (val4 (file->sample gen 40 0)) (val5 (file->sample gen 40 1)) (val6 (in-any 50 0 gen)) (val7 (in-any 50 1 gen)) (val8 (in-any 60 0 gen)) (val9 (in-any 60 1 gen))) (print-and-check gen "file->sample" "file->sample fmv.snd") (if (not (= (mus-channels gen) 2)) (snd-display #__line__ ";make-sample->file chans: ~A?" (mus-channels gen))) (if (not (mus-input? gen)) (snd-display #__line__ ";~A not input?" gen)) (if (or (fneq val0 .02) (fneq val1 .2)) (snd-display #__line__ ";in-any: ~A ~A?" val0 val1)) (if (or (fneq val2 .03) (fneq val3 .3)) (snd-display #__line__ ";inab: ~A ~A?" val2 val3)) (if (or (fneq val4 .04) (fneq val5 .4)) (snd-display #__line__ ";sample->file: ~A ~A?" val4 val5)) (if (or (fneq val6 .065) (fneq val7 .65)) (snd-display #__line__ ";outab: ~A ~A?" val6 val7)) (if (or (fneq val8 .075) (fneq val9 .75)) (snd-display #__line__ ";out-any: ~A ~A?" val8 val9))) (let ((gen (make-float-vector 10))) (do ((i 0 (+ i 1)) (x 0.0 (+ x 0.1))) ((= i 10)) (outa i x gen)) (if (not (vequal gen (float-vector 0 .1 .2 .3 .4 .5 .6 .7 .8 .9))) (snd-display #__line__ ";outa->float-vector ramp: ~A" gen)) (do ((i 0 (+ i 1)) (x 0.0 (+ x 0.1))) ((= i 10)) (outa i x gen)) (if (not (vequal gen (float-vector-scale! (float-vector 0 .1 .2 .3 .4 .5 .6 .7 .8 .9) 2.0))) (snd-display #__line__ ";outa->float-vector ramp 2: ~A" gen)) (if (not (= (mus-channels gen) 1)) (snd-display #__line__ ";mus-channels float-vector: ~A" (mus-channels gen)))) (let ((gen (make-float-vector (list 4 100) 0.0))) (do ((i 0 (+ i 1))) ((= i 10)) (outa i .1 gen) (outb i .2 gen) (outc i .3 gen) (outd i .4 gen)) (do ((i 0 (+ i 1))) ((= i 10)) (outa i .01 gen) (outb i .02 gen) (outc i .03 gen) (outd i .04 gen)) (mus-close gen) ; should be a no-op (do ((i 0 (+ i 1))) ((= i 10)) (if (or (fneq (ina i gen) .11) (fneq (inb i gen) .22) (fneq (in-any i 2 gen) .33) (fneq (in-any i 3 gen) .44)) (snd-display #__line__ ";4-chan sd out/in[~A]: ~A ~A ~A ~A?" i (ina i gen) (inb i gen) (in-any i 2 gen) (in-any i 3 gen)))) (if (not (= (mus-channels gen) 4)) (snd-display #__line__ ";mus-channels sd 4: ~A" (mus-channels gen)))) (let ((gen (make-float-vector (list 4 100) 0.0))) (do ((i 0 (+ i 1))) ((= i 10)) (out-any i .1 0 gen) (out-any i .2 1 gen) (out-any i .3 2 gen) (out-any i .4 3 gen)) (do ((i 0 (+ i 1))) ((= i 10)) (out-any i .01 0 gen) (out-any i .02 1 gen) (out-any i .03 2 gen) (out-any i .04 3 gen)) (do ((i 0 (+ i 1))) ((= i 10)) (if (or (fneq (in-any i 0 gen) .11) (fneq (in-any i 1 gen) .22) (fneq (in-any i 2 gen) .33) (fneq (in-any i 3 gen) .44)) (snd-display #__line__ ";4-chan sd out/in-any[~A]: ~A ~A ~A ~A?" i (in-any i 0 gen) (in-any i 1 gen) (in-any i 2 gen) (in-any i 3 gen))))) (let ((gen (make-oscil 440.0))) (let ((tag (catch #t (lambda () (outa 0 .1 gen)) (lambda args (car args))))) (if (and (not (eq? tag 'wrong-type-arg)) (not (eq? tag 'mus-error))) (snd-display #__line__ ";outa -> oscil: ~A" tag)))) (let ((gen (make-sample->file "fmv.snd" 4 mus-lshort mus-riff))) (print-and-check gen "sample->file" "sample->file fmv.snd") (do ((i 0 (+ i 1))) ((= i 10)) (outa i .1 gen) (outb i .2 gen) (outc i .3 gen) (outd i .4 gen)) (do ((i 0 (+ i 1))) ((= i 10)) (outa i .01 gen) (outb i .02 gen) (outc i .03 gen) (outd i .04 gen)) (mus-close gen)) (let ((gen (make-file->sample "fmv.snd"))) (print-and-check gen "file->sample" "file->sample fmv.snd") (do ((i 0 (+ i 1))) ((= i 10)) (if (or (fneq (ina i gen) .11) (fneq (inb i gen) .22) (fneq (in-any i 2 gen) .33) (fneq (in-any i 3 gen) .44)) (snd-display #__line__ ";4-chan out/in[~A]: ~A ~A ~A ~A?" i (ina i gen) (inb i gen) (in-any i 2 gen) (in-any i 3 gen))))) (let ((gen (make-sample->file "fmv.snd" 4 mus-lshort mus-riff))) (do ((i 0 (+ i 1))) ((= i 10)) (outa i .1 gen) (outb i .2 gen) (outc i .3 gen) (outd i .4 gen)) (do ((i 0 (+ i 1))) ((= i 10)) (outa i .01 gen) (outb i .02 gen) (outc i .03 gen) (outd i .04 gen)) (mus-close gen)) (let ((gen (make-file->sample "fmv.snd"))) (do ((i 0 (+ i 1))) ((= i 10)) (if (or (fneq (ina i gen) .11) (fneq (inb i gen) .22) (fneq (in-any i 2 gen) .33) (fneq (in-any i 3 gen) .44)) (snd-display #__line__ ";4-chan out/in[~A]: ~A ~A ~A ~A?" i (ina i gen) (inb i gen) (in-any i 2 gen) (in-any i 3 gen))))) (let ((var (catch #t (lambda () (make-sample->file "fmv.snd" -1 mus-lshort mus-next)) (lambda args args)))) (if (not (eq? (car var) 'out-of-range)) (snd-display #__line__ ";make-sample->file bad chans: ~A" var))) (let ((var (catch #t (lambda () (mus-location (make-oscil))) (lambda args args)))) (if (or (not (list? var)) (not (eq? (car var) 'mus-error))) (snd-display #__line__ ";mus-location oscil: ~A" var))) (let ((var (catch #t (lambda () (make-sample->file "fmv.snd" 1 -1 mus-next)) (lambda args args)))) (if (not (eq? (car var) 'out-of-range)) (snd-display #__line__ ";make-sample->file bad format: ~A" var))) (let ((var (catch #t (lambda () (make-sample->file "fmv.snd" 1 mus-lshort -1)) (lambda args args)))) (if (not (eq? (car var) 'out-of-range)) (snd-display #__line__ ";make-sample->file bad type: ~A" var))) (let ((v (vector 1.0 0.5 0.25 0.125 0.0)) (v1 (make-float-vector 5 0.0))) (do ((i 0 (+ i 1))) ((= i 5)) (set! (v1 i) (in-any i 0 v))) (if (not (vequal v1 (float-vector 1.0 0.5 0.25 0.125 0.0))) (snd-display #__line__ ";vector in-any -> ~A?" v1))) (let ((invals (make-float-vector 10))) (do ((i 0 (+ i 1))) ((= i 10)) (float-vector-set! invals i (* i 0.1))) (let ((result (with-sound ((make-float-vector 10)) (do ((i 0 (+ i 1))) ((= i 10)) (outa i (ina i invals)))))) (if (not (vequal result (float-vector 0.000 0.100 0.200 0.300 0.400 0.500 0.600 0.700 0.800 0.900))) (snd-display #__line__ ";ina from float-vector: ~A" result)))) (let ((invals (make-float-vector 10))) (do ((i 0 (+ i 1))) ((= i 10)) (float-vector-set! invals i (* i 0.1))) (let ((result (with-sound ((make-float-vector 10)) (do ((i 0 (+ i 1))) ((= i 10)) (outa i (ina i invals)))))) (if (not (vequal result (float-vector 0.000 0.100 0.200 0.300 0.400 0.500 0.600 0.700 0.800 0.900))) (snd-display #__line__ ";run ina from float-vector: ~A" result)))) (for-each close-sound (sounds)) (let ((vals (with-sound ((make-float-vector 4410)) (fm-violin 0 .1 440 .1)))) (if (fneq (float-vector-peak vals) .1) (snd-display #__line__ ";locsig to float-vector fm-violin peak: ~A" (float-vector-peak vals)))) (let ((vals (with-sound ((make-float-vector (list 2 4410) 0.0)) (fm-violin 0 .1 440 .1 :degree 30)))) (let ((mxs (maxamp vals))) (if (fneq mxs 0.0666) (snd-display #__line__ ";locsig to sound-data fm-violin peak: ~A" mxs)))) (let ((gen (make-sample->file "fmv2.snd" 4 mus-bshort mus-aifc))) (print-and-check gen "sample->file" "sample->file fmv2.snd") (if (not (mus-output? gen)) (snd-display #__line__ ";~A not output?" gen)) (if (not (sample->file? gen)) (snd-display #__line__ ";~A not sample->file?" gen)) (do ((i 0 (+ i 1))) ((= i 100)) (sample->file gen i 0 (* i .001)) (sample->file gen i 1 (* i .01)) (sample->file gen i 2 (* i .002)) (sample->file gen i 3 (* i .003))) (outa 50 .015 gen) (outb 50 .15 gen) (outc 50 .02 gen) (outd 50 .03 gen) (out-any 60 .015 0 gen) (out-any 60 .15 1 gen) (out-any 60 .02 2 gen) (out-any 60 .03 3 gen) (mus-close gen)) (let* ((gen (make-file->sample "fmv2.snd")) (val0 (in-any 20 2 gen)) (val1 (in-any 20 3 gen)) (val2 (file->sample gen 50 2)) (val3 (file->sample gen 50 3)) (val4 (file->sample gen 60 2)) (val5 (file->sample gen 60 3))) (if (not (= (mus-channels gen) 4)) (snd-display #__line__ ";make-file->sample (4) chans: ~A?" (mus-channels gen))) (if (not (= (mus-increment gen) 0.0)) (snd-display #__line__ ";file->sample increment: ~A" (mus-increment gen))) ; dir never set in this case (if (or (fneq val0 .04) (fneq val1 .06)) (snd-display #__line__ ";in-any(0, 4): ~A ~A?" val0 val1)) (if (or (fneq val2 .12) (fneq val3 .18)) (snd-display #__line__ ";file->sample(4): ~A ~A?" val2 val3)) (if (or (fneq val4 .14) (fneq val5 .21)) (snd-display #__line__ ";in-any(4, 4): ~A ~A?" val4 val5))) (if (file-exists? "fmv.snd") (delete-file "fmv.snd")) (mus-sound-forget "fmv.snd") (let ((sf (make-sample->file "fmv.snd" 2 mus-bshort mus-next "this is a comment"))) (do ((i 0 (+ i 1))) ((= i 10)) (sample->file sf i 0 (* i .1)) (sample->file sf i 1 (* i .01))) (mus-close sf) (if (not (= (mus-sound-chans "fmv.snd") 2)) (snd-display #__line__ ";sample->file chans: ~A" (mus-sound-chans "fmv.snd"))) (if (not (= (mus-sound-framples "fmv.snd") 10)) (snd-display #__line__ ";sample->file framples: ~A" (mus-sound-framples "fmv.snd"))) (if (not (= (mus-sound-samples "fmv.snd") 20)) (snd-display #__line__ ";sample->file samples: ~A" (mus-sound-samples "fmv.snd"))) (if (not (= (mus-sound-header-type "fmv.snd") mus-next)) (snd-display #__line__ ";sample->file type: ~A" (mus-header-type-name (mus-sound-header-type "fmv.snd")))) (if (not (= (mus-sound-sample-type "fmv.snd") mus-bshort)) (snd-display #__line__ ";sample->file format: ~A" (mus-sample-type-name (mus-sound-sample-type "fmv.snd")))) (if (not (string=? (mus-sound-comment "fmv.snd") "this is a comment")) (snd-display #__line__ ";sample->file comment: ~A" (mus-sound-comment "fmv.snd"))) (let ((rd (make-file->sample "fmv.snd")) (happy #t)) (do ((i 0 (+ i 1))) ((or (not happy) (= i 10))) (let ((c0 (file->sample rd i 0)) (c1 (file->sample rd i 1))) (if (or (fneq c0 (* i .1)) (fneq c1 (* i .01))) (begin (snd-display #__line__ ";sample->file->sample at ~A: ~A ~A" i c0 c1) (set! happy #f))))) (mus-close rd)) (set! sf (continue-sample->file "fmv.snd")) (do ((i 0 (+ i 1))) ((= i 10)) (sample->file sf (+ i 5) 0 (* i -.02)) (sample->file sf (+ i 5) 1 (* i -.01))) (mus-close sf) (mus-sound-forget "fmv.snd") (if (not (= (mus-sound-chans "fmv.snd") 2)) (snd-display #__line__ ";continue-sample->file chans: ~A" (mus-sound-chans "fmv.snd"))) (if (not (= (mus-sound-framples "fmv.snd") 15)) (snd-display #__line__ ";continue-sample->file framples: ~A" (mus-sound-framples "fmv.snd"))) (if (not (= (mus-sound-samples "fmv.snd") 30)) (snd-display #__line__ ";continue-sample->file samples: ~A" (mus-sound-samples "fmv.snd"))) (if (not (= (mus-sound-header-type "fmv.snd") mus-next)) (snd-display #__line__ ";continue-sample->file type: ~A" (mus-header-type-name (mus-sound-header-type "fmv.snd")))) (if (not (= (mus-sound-sample-type "fmv.snd") mus-bshort)) (snd-display #__line__ ";continue-sample->file format: ~A" (mus-sample-type-name (mus-sound-sample-type "fmv.snd")))) (if (not (string=? (mus-sound-comment "fmv.snd") "this is a comment")) (snd-display #__line__ ";continue-sample->file comment: ~A" (mus-sound-comment "fmv.snd"))) (let ((ind (open-sound "fmv.snd"))) (let ((c0 (channel->float-vector 0 15 ind 0)) (c1 (channel->float-vector 0 15 ind 1))) (if (not (vequal c0 (float-vector 0.0 0.1 0.2 0.3 0.4 0.5 0.58 0.66 0.74 0.82 -0.1 -0.12 -0.14 -0.16 -0.18))) (snd-display #__line__ ";continue-sample->file (0): ~A" c0)) (if (not (vequal c1 (float-vector 0.0 0.01 0.02 0.03 0.04 0.05 0.05 0.05 0.05 0.05 -0.05 -0.06 -0.07 -0.08 -0.09))) (snd-display #__line__ ";continue-sample->file (1): ~A" c1))) (close-sound ind)) (delete-file "fmv.snd") (mus-sound-forget "fmv.snd")) (let ((f1 (float-vector 1.0 1.0)) (f2 (float-vector 0.0 0.0)) (m1 (float-vector .5 .25 .125 1.0))) (let ((result (frample->frample m1 f1 2 f2 2))) (if (not (equal? result (float-vector 0.625 1.25))) (snd-display #__line__ ";frample->frample: ~A" result)))) (let ((f1 (float-vector 1.0 2.0 3.0)) (f2 (float-vector 0.0 0.0 0.0)) (m1 (float-vector 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0))) (let ((result (frample->frample m1 f1 3 f2 3))) (if (not (equal? result (float-vector 30.0 36.0 42.0))) (snd-display #__line__ ";frample->frample 1: ~A" result)))) (let ((sf (make-frample->file "fmv.snd" 2 mus-lfloat mus-riff "this is a comment"))) (do ((i 0 (+ i 1))) ((= i 10)) (frample->file sf i (float-vector (* i .1) (* i .01)))) (mus-close sf) (if (not (= (mus-sound-chans "fmv.snd") 2)) (snd-display #__line__ ";frample->file chans: ~A" (mus-sound-chans "fmv.snd"))) (if (not (= (mus-sound-framples "fmv.snd") 10)) (snd-display #__line__ ";frample->file framples: ~A" (mus-sound-framples "fmv.snd"))) (if (not (= (mus-sound-samples "fmv.snd") 20)) (snd-display #__line__ ";frample->file samples: ~A" (mus-sound-samples "fmv.snd"))) (if (not (= (mus-sound-header-type "fmv.snd") mus-riff)) (snd-display #__line__ ";frample->file type: ~A" (mus-header-type-name (mus-sound-header-type "fmv.snd")))) (if (not (= (mus-sound-sample-type "fmv.snd") mus-lfloat)) (snd-display #__line__ ";frample->file format: ~A" (mus-sample-type-name (mus-sound-sample-type "fmv.snd")))) (if (not (string=? (mus-sound-comment "fmv.snd") "this is a comment")) (snd-display #__line__ ";frample->file comment: ~A" (mus-sound-comment "fmv.snd"))) (let ((rd (make-file->frample "fmv.snd")) (f0 (float-vector 0.0 0.0)) (happy #t)) (do ((i 0 (+ i 1))) ((or (not happy) (= i 10))) (file->frample rd i f0) (if (or (not (= (mus-length f0) 2)) (fneq (f0 0) (* i .1)) (fneq (f0 1) (* i .01))) (begin (snd-display #__line__ ";frample->file->frample at ~A: ~A" i f0) (set! happy #f)))) (mus-close rd)) (set! sf (continue-frample->file "fmv.snd")) (do ((i 0 (+ i 1))) ((= i 10)) (frample->file sf (+ i 5) (float-vector (* i -.02) (* i -.01)))) (mus-close sf) (mus-sound-forget "fmv.snd") (if (not (= (mus-sound-chans "fmv.snd") 2)) (snd-display #__line__ ";continue-frample->file chans: ~A" (mus-sound-chans "fmv.snd"))) (if (not (= (mus-sound-framples "fmv.snd") 15)) (snd-display #__line__ ";continue-frample->file framples: ~A" (mus-sound-framples "fmv.snd"))) (if (not (= (mus-sound-samples "fmv.snd") 30)) (snd-display #__line__ ";continue-frample->file samples: ~A" (mus-sound-samples "fmv.snd"))) (if (not (= (mus-sound-header-type "fmv.snd") mus-riff)) (snd-display #__line__ ";continue-frample->file type: ~A" (mus-header-type-name (mus-sound-header-type "fmv.snd")))) (if (not (= (mus-sound-sample-type "fmv.snd") mus-lfloat)) (snd-display #__line__ ";continue-frample->file format: ~A" (mus-sample-type-name (mus-sound-sample-type "fmv.snd")))) (if (not (string=? (mus-sound-comment "fmv.snd") "this is a comment")) (snd-display #__line__ ";continue-frample->file comment: ~A" (mus-sound-comment "fmv.snd"))) (let ((ind (open-sound "fmv.snd"))) (let ((c0 (channel->float-vector 0 15 ind 0)) (c1 (channel->float-vector 0 15 ind 1))) (if (not (vequal c0 (float-vector 0.0 0.1 0.2 0.3 0.4 0.5 0.58 0.66 0.74 0.82 -0.1 -0.12 -0.14 -0.16 -0.18))) (snd-display #__line__ ";continue-frample->file (0): ~A" c0)) (if (not (vequal c1 (float-vector 0.0 0.01 0.02 0.03 0.04 0.05 0.05 0.05 0.05 0.05 -0.05 -0.06 -0.07 -0.08 -0.09))) (snd-display #__line__ ";continue-frample->file (1): ~A" c1))) (close-sound ind)) (delete-file "fmv.snd") (mus-sound-forget "fmv.snd")) (let ((v0 (make-float-vector 1000)) (os (make-oscil 440.0))) (do ((i 0 (+ i 1))) ((= i 1000)) (set! (v0 i) (* .1 (oscil os)))) (array->file "fmv3.snd" v0 10000 22050 1) ; 10000 deliberate (let ((v1 (make-float-vector 1000))) (file->array "fmv3.snd" 0 0 1000 v1) (do ((i 0 (+ i 1))) ((= i 1000)) (if (fneq (v0 i) (v1 i)) (snd-display #__line__ ";array->file->array: ~A ~A ~A?" i (v0 i) (v1 i))))) (let ((var (catch #t (lambda () (array->file "fmv3.snd" v0 -1 1000 1)) (lambda args args)))) (if (not (eq? (car var) 'out-of-range)) (snd-display #__line__ ";array->file bad samps: ~A" var))) (let ((var (catch #t (lambda () (array->file "/bad/baddy/fmv3.snd" v0 1 1000 1)) (lambda args args)))) (if (not (eq? (car var) 'mus-error)) (snd-display #__line__ ";array->file bad file: ~A" var))) (let ((var (catch #t (lambda () (file->array "fmv3.snd" -1 0 -1 v0)) (lambda args args)))) (if (not (eq? (car var) 'out-of-range)) (snd-display #__line__ ";file->array bad samps: ~A" var)))) (let ((gen (make-rand 10000.0)) (v0 (make-float-vector 10))) (print-and-check gen "rand" "rand freq: 10000.000Hz, phase: 0.000, amp: 1.000") (do ((i 0 (+ i 1))) ((= i 10)) (set! (v0 i) (rand gen))) (if (not (rand? gen)) (snd-display #__line__ ";~A not rand?" gen)) (if (fneq (mus-phase gen) 3.3624296) (snd-display #__line__ ";rand phase: ~F?" (mus-phase gen))) (if (fneq (mus-frequency gen) 10000.0) (snd-display #__line__ ";rand frequency: ~F?" (mus-frequency gen))) (set! (mus-scaler gen) 0.5) (if (fneq (mus-scaler gen) 0.5) (snd-display #__line__ ";set! mus-scaler rand: ~A" (mus-scaler gen))) (if (= (v0 1) (v0 8)) (snd-display #__line__ ";rand output: ~A" v0))) (let ((gen (make-rand 10000.0 :envelope '(0 0 1 1))) (v0 (make-float-vector 10))) (print-and-check gen "rand" "rand freq: 10000.000Hz, phase: 0.000, amp: 1.000, with distribution envelope") (do ((i 0 (+ i 1))) ((= i 10)) (set! (v0 i) (rand gen))) (if (not (rand? gen)) (snd-display #__line__ ";(dist) ~A not rand?" gen)) (if (fneq (mus-frequency gen) 10000.0) (snd-display #__line__ ";(dist) rand frequency: ~F?" (mus-frequency gen))) (if (= (v0 1) (v0 8)) (snd-display #__line__ ";(dist) rand output: ~A" v0)) (if (or (not (float-vector? (mus-data gen))) (not (= (mus-length gen) (length (mus-data gen)))) (not (= (mus-length gen) 512))) (snd-display #__line__ ";(dist) rand data: ~A ~A" (mus-length gen) (mus-data gen)))) (let ((gen1 (make-rand 10000.0 :envelope '(0 0 1 1))) (gen2 (make-rand 10000.0 :envelope '(0 1 1 0))) (up1 0) (down1 0) (bad1 0) (up2 0) (down2 0) (bad2 0)) (do ((i 0 (+ i 1))) ((= i 1000)) (let ((val1 (rand gen1)) (val2 (rand gen2))) (if (>= val1 .5) (set! up1 (+ 1 up1)) (if (>= val1 0.0) (set! down1 (+ 1 down1)) (set! bad1 (+ 1 bad1)))) (if (>= val2 .5) (set! up2 (+ 1 up2)) (if (>= val2 0.0) (set! down2 (+ 1 down2)) (set! bad2 (+ 1 bad2)))))) (if (or (not (= bad1 0)) (not (= bad2 0)) (> (* 2 down1) up1) (> (* 2 up2) down2)) (snd-display #__line__ "; rand dist: ~A ~A ~A, ~A ~A ~A" down1 up1 bad1 down2 up2 bad2))) ; (test-gen-equal (make-rand 1000) (make-rand 1000) (make-rand 500)) ; (test-gen-equal (make-rand 1000) (make-rand 1000) (make-rand 1000 0.5)) (let ((gen (make-rand-interp 100.0 0.0))) (do ((i 0 (+ i 1))) ((= i 10)) (let ((val (rand-interp gen))) (if (not (zero? val)) (snd-display #__line__ ";rand-interp 0 amp: ~A" val))))) (let ((gen (make-rand-interp 4000.0)) (v0 (make-float-vector 10))) (print-and-check gen "rand-interp" (mus-describe gen)) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v0 i) (rand-interp gen 0.0))) (if (not (rand-interp? gen)) (snd-display #__line__ ";~A not rand-interp?" gen)) (if (fneq (mus-phase gen) 5.114882) (snd-display #__line__ ";rand-interp phase: ~F?" (mus-phase gen))) (if (fneq (mus-frequency gen) 4000.0) (snd-display #__line__ ";rand-interp frequency: ~F?" (mus-frequency gen))) (set! (mus-scaler gen) 0.5) (if (fneq (mus-scaler gen) 0.5) (snd-display #__line__ ";set! mus-scaler rand-interp: ~A" (mus-scaler gen))) (if (= (v0 1) (v0 8)) (snd-display #__line__ ";rand-interp output: ~A" v0))) (let ((gen (make-rand-interp 4000.0 :envelope '(-1 1 0 0 1 1))) (v0 (make-float-vector 10))) (print-and-check gen "rand-interp" (mus-describe gen)) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v0 i) (rand-interp gen 0.0))) (if (not (rand-interp? gen)) (snd-display #__line__ ";(dist) ~A not rand-interp?" gen)) (if (= (v0 1) (v0 8)) (snd-display #__line__ ";(dist) rand-interp output: ~A" v0)) (if (or (not (float-vector? (mus-data gen))) (not (= (mus-length gen) (length (mus-data gen)))) (not (= (mus-length gen) 512))) (snd-display #__line__ ";(dist) rand-interp data: ~A ~A" (mus-length gen) (mus-data gen)))) (let ((gen (make-rand 10000.0 1.0)) (gen1 (make-rand-interp 10000.0 1.0))) (do ((i 0 (+ i 1))) ((= i 1000)) (let ((val1 (gen 0.0)) (val2 (gen1 0.0))) (if (or (> val1 1.0) (< val1 -1.0)) (snd-display #__line__ ";rand: ~A ~A" val1 gen)) (if (or (> val2 1.0) (< val2 -1.0)) (snd-display #__line__ ";rand-interp: ~A ~A" val2 gen1))))) (let ((gen (make-rand 10000.0 :distribution (inverse-integrate '(0 0 1 1)))) (v0 (make-float-vector 10))) (print-and-check gen "rand" "rand freq: 10000.000Hz, phase: 0.000, amp: 1.000, with distribution envelope") (do ((i 0 (+ i 1))) ((= i 10)) (set! (v0 i) (rand gen))) (if (not (rand? gen)) (snd-display #__line__ ";(dist 2) ~A not rand?" gen)) (if (fneq (mus-frequency gen) 10000.0) (snd-display #__line__ ";(dist 2) rand frequency: ~F?" (mus-frequency gen))) (if (= (v0 1) (v0 8)) (snd-display #__line__ ";(dist 2) rand output: ~A" v0)) (if (or (not (float-vector? (mus-data gen))) (not (= (mus-length gen) (length (mus-data gen)))) (not (= (mus-length gen) 512))) (snd-display #__line__ ";(dist 2) rand data: ~A ~A" (mus-length gen) (mus-data gen)))) (let ((gen1 (make-rand 10000.0 :distribution (inverse-integrate '(0 0 1 1)))) (gen2 (make-rand 10000.0 :distribution (inverse-integrate '(0 1 1 0)))) (up1 0) (down1 0) (bad1 0) (up2 0) (down2 0) (bad2 0)) (do ((i 0 (+ i 1))) ((= i 1000)) (let ((val1 (rand gen1)) (val2 (rand gen2))) (if (>= val1 .5) (set! up1 (+ 1 up1)) (if (>= val1 0.0) (set! down1 (+ 1 down1)) (set! bad1 (+ 1 bad1)))) (if (>= val2 .5) (set! up2 (+ 1 up2)) (if (>= val2 0.0) (set! down2 (+ 1 down2)) (set! bad2 (+ 1 bad2)))))) (if (or (not (= bad1 0)) (not (= bad2 0)) (> (* 2.5 down1) up1) (> (* 2.0 up2) down2)) (snd-display #__line__ "; rand dist 2: ~A ~A ~A, ~A ~A ~A" down1 up1 bad1 down2 up2 bad2))) ; 234 766 0, 705 295 0 (let ((ind (new-sound :size 100))) (select-sound ind) (map-channel (lambda (y) (any-random 1.0 '(0 1 1 1)))) (let ((place (scan-channel (lambda (y) (not (<= 0.0 y 1.0)))))) ; (or (< y 0.0) (> y 1.0)))))) (if place (snd-display #__line__ ";any-random 0 to 1: ~A" place))) (if (< (maxamp) .5) (snd-display #__line__ ";any-random maxamp: ~A" (maxamp))) ; possible, but extremely unlikely (let ((avg 0.0)) (scan-channel (lambda (y) (set! avg (+ avg y)) #f)) (if (> (abs (- (/ avg (framples)) .5)) .2) (snd-display #__line__ ";any-random skewed?"))) (let ((g (gaussian-distribution 1.0))) (map-channel (lambda (y) (any-random 1.0 g)))) (let ((g (pareto-distribution 1.0))) (map-channel (lambda (y) (any-random 1.0 g)))) (let ((new-file-name (file-name ind))) (close-sound ind) (if (file-exists? new-file-name) (delete-file new-file-name)))) (let ((v1 (inverse-integrate '(-1 1 1 1)))) (if (fneq (v1 4) -0.984) (snd-display #__line__ ";inverse-integrate -1 to 1 uniform: ~A" v1))) (let ((v1 (inverse-integrate '(0 1 1 1)))) (if (fneq (v1 4) .008) (snd-display #__line__ ";inverse-integrate 0 to 1 uniform: ~A" v1))) (let ((v1 (inverse-integrate '(0 1 1 0)))) (if (fneq (v1 4) .004) (snd-display #__line__ ";inverse-integrate 0 to 1 1 to 0: ~A" v1))) (let ((v1 (inverse-integrate '(0 0 .5 1 1 0)))) (if (fneq (v1 4) .073) (snd-display #__line__ ";inverse-integrate triangle: ~A" v1))) (let ((v1 (inverse-integrate (gaussian-envelope 1.0)))) (if (fneq (v1 4) -0.593) (snd-display #__line__ ";inverse-integrate gaussian: ~A" v1))) (let ((minp 1.0) (maxp -1.0)) (do ((i 0 (+ i 1))) ((= i 1100)) (let ((val1 (mus-random 1.0))) (if (< val1 minp) (set! minp val1)) (if (> val1 maxp) (set! maxp val1)) (if (or (> val1 1.0) (< val1 -1.0)) (snd-display #__line__ ";mus-random: ~A" val1)))) (if (or (< maxp .9) (> minp -.9)) (snd-display #__line__ ";mus-random: ~A ~A" minp maxp)) (set! minp 12.0) (set! maxp -12.0) (do ((i 0 (+ i 1))) ((= i 1100)) (let ((val1 (mus-random 12.0))) (if (< val1 minp) (set! minp val1)) (if (> val1 maxp) (set! maxp val1)) (if (or (> val1 12.0) (< val1 -12.0)) (snd-display #__line__ ";mus-random (12): ~A" val1)))) (if (or (< maxp 11.0) (> minp -11.0)) (snd-display #__line__ ";mus-random (12): ~A ~A" minp maxp))) (let ((v (lambda (n) ; chi^2 or mus-random (let ((hits (make-vector 10 0))) (do ((i 0 (+ 1 i ))) ((= i n)) (let ((y (floor (+ 5 (mus-random 5.0))))) (set! (hits y) (+ 1 (vector-ref hits y))))) (let ((sum 0.0) (p (/ n 10.0))) (do ((i 0 (+ i 1))) ((= i 10) sum) (let ((num (- (vector-ref hits i) p))) (set! sum (+ sum (/ (* num num) p)))))))))) ;;:(v 10000) ;;#(999 1017 1002 1024 1048 971 963 1000 980 996) 5.8 ;; if less than 3 complain (let ((vr (v 10000))) (if (< vr 3.0) (snd-display #__line__ ";mus-random not so random? ~A (chi)" vr)))) (let ((v1 (lambda (n) (let ((hits (make-vector 10 0)) (gen (make-rand 22050.0 5))) (do ((i 0 (+ 1 i ))) ((= i n)) (let ((y (floor (+ 5 (rand gen))))) (set! (hits y) (+ 1 (vector-ref hits y))))) (let ((sum 0.0) (p (/ n 10.0))) (do ((i 0 (+ i 1))) ((= i 10) sum) (let ((num (- (vector-ref hits i) p))) (set! sum (+ sum (/ (* num num) p)))))))))) ;;:(v1 10000) ;;#(979 1015 977 1008 954 1049 997 1020 1015 986) 6.606 (let ((vr (v1 10000))) (if (< vr 3.5) (snd-display #__line__ ";rand not so random? ~A (chi)" vr)))) (let ((data (make-float-vector 65536))) (do ((i 0 (+ i 1))) ((= i 65536)) (set! (data i) (mus-random 1.0))) (let* ((ndat (snd-spectrum data rectangular-window 65536 #t 0.0 #f #f)) (peak (float-vector-peak ndat)) (sum 0.0)) (if (> peak 1000.0) (snd-display #__line__ ";mus-random spectral peak: ~A" peak)) (do ((i 0 (+ i 1))) ((= i 32768)) (set! sum (+ sum (float-vector-ref ndat i)))) (if (> (/ sum 32768.0) 200.0) (snd-display #__line__ ";random average: ~A ~A" (/ sum 32768.0) (ndat 0))) (do ((i 0 (+ i 1))) ((= i 65536)) (set! (data i) (mus-random 1.0))) (autocorrelate data) (set! (data 0) 0.0) (let ((pk (float-vector-peak data))) (if (> pk 1000) (snd-display #__line__ ";random autocorrelate peak: ~A" (float-vector-peak data))) (set! sum 0.0) (float-vector-abs! data) (do ((i 0 (+ i 1))) ((= i 32768)) (set! sum (+ sum (float-vector-ref data i)))) (if (> (/ sum 32768.0) 200.0) (snd-display #__line__ ";random autocorrelate average: ~A" (/ sum 32768.0)))))) (set! (locsig-type) mus-interp-linear) (let* ((gen (make-locsig 30.0 :channels 2)) (gen1 (make-locsig 60.0 :channels 2)) (gen2 (make-locsig 60.0 :channels 4)) (gen200 (make-locsig 200.0 :channels 4)) (gen3 gen1)) (locsig gen 0 1.0) (print-and-check gen "locsig" "locsig chans 2, outn: [0.667 0.333], interp: linear") (if (not (locsig? gen)) (snd-display #__line__ ";~A not locsig?" gen)) (if (not (eq? gen1 gen3)) (snd-display #__line__ ";locsig eq? ~A ~A" gen1 gen3)) (if (not (equal? gen1 gen3)) (snd-display #__line__ ";locsig equal? ~A ~A" gen1 gen3)) (if (eq? gen1 gen2) (snd-display #__line__ ";locsig 1 eq? ~A ~A" gen1 gen2)) (if (equal? gen gen1) (snd-display #__line__ ";locsig 2 equal? ~A ~A" gen gen1)) (if (equal? gen gen2) (snd-display #__line__ ";locsig 3 equal? ~A ~A" gen gen2)) (if (or (fneq (locsig-ref gen 0) .667) (fneq (locsig-ref gen 1) .333)) (snd-display #__line__ ";locsig ref: ~F ~F?" (locsig-ref gen 0) (locsig-ref gen 1))) (if (not (vequal (mus-data gen) (float-vector 0.667 0.333))) (snd-display #__line__ ";locsig gen outn: ~A" (mus-data gen))) (if (not (vequal (mus-data gen1) (float-vector 0.333 0.667))) (snd-display #__line__ ";locsig gen2 outn: ~A" (mus-data gen1))) (if (not (vequal (mus-data gen2) (float-vector 0.333 0.667 0.000 0.000))) (snd-display #__line__ ";locsig gen2 outn: ~A" (mus-data gen2))) (if (not (vequal (mus-data gen200) (float-vector 0.000 0.000 0.778 0.222))) (snd-display #__line__ ";locsig gen200 outn: ~A" (mus-data gen200))) (locsig-set! gen 0 .25) (if (not (vequal (mus-data gen) (float-vector 0.250 0.333))) (snd-display #__line__ ";locsig gen .25 outn: ~A" (mus-data gen))) (locsig gen 0 1.0) (locsig-set! gen 0 .5) (if (not (vequal (mus-data gen) (float-vector 0.500 0.333))) (snd-display #__line__ ";locsig gen .5 outn: ~A" (mus-data gen))) (locsig gen 0 1.0) (set! gen (make-locsig 120.0 2.0 .1 :channels 4)) (if (not (vequal (mus-data gen) (float-vector 0.000 0.333 0.167 0.000))) (snd-display #__line__ ";locsig gen 120 outn: ~A" (mus-data gen))) (locsig gen 0 1.0) (set! gen (make-locsig 300.0 2.0 .1 :channels 4)) (if (not (vequal (mus-data gen) (float-vector 0.167 0.000 0.000 0.333))) (snd-display #__line__ ";locsig gen 300 outn: ~A" (mus-data gen))) (locsig gen 0 1.0) (move-locsig gen1 90.0 1.0) (if (not (vequal (mus-data gen1) (float-vector 0.000 1.000))) (snd-display #__line__ ";locsig gen1 90 outn: ~A" (mus-data gen1))) (move-locsig gen1 0.0 1.0) (if (not (vequal (mus-data gen1) (float-vector 1.000 0.000))) (snd-display #__line__ ";locsig gen1 0 outn: ~A" (mus-data gen1))) (move-locsig gen1 45.0 1.0) (if (not (vequal (mus-data gen1) (float-vector 0.500 0.500))) (snd-display #__line__ ";locsig gen1 45 outn: ~A" (mus-data gen1))) (move-locsig gen1 135.0 2.0) (if (not (vequal (mus-data gen1) (float-vector 0.000 0.500))) (snd-display #__line__ ";locsig gen1 135 outn: ~A" (mus-data gen1))) (move-locsig gen1 -270.0 3.0) (if (not (vequal (mus-data gen1) (float-vector 0.333 0.0))) (snd-display #__line__ ";locsig gen1 -270 outn: ~A" (mus-data gen1)))) (for-each (lambda (chans) (let* ((loc (make-locsig :channels chans)) (last (make-float-vector chans)) (data (mus-data loc))) ;; do a full circle looking for jumps (move-locsig loc -400.0 1.0) (copy data last) (do ((x -400.0 (+ x 10.0))) ((> x 400.0)) (move-locsig loc x 1.0) (if (or (< (float-vector-min data) 0.0) (> (float-vector-max data) 1.0)) (format #t ";locsig, chans: ~D, degree: ~F, ~A~%" chans x data)) (let ((diff (float-vector-peak (float-vector-subtract! last data)))) (copy data last) (if (> diff .25) (format #t ";locsig, increment ~F with deg ~F~%" diff x)))))) (list 1 2 4 5 8)) (for-each (lambda (chans) (let ((m1 (make-locsig :channels chans))) (if (or (not (= (mus-channels m1) chans)) (not (= (mus-length m1) chans))) (snd-display #__line__ ";locsig ~A chans but: ~A ~A" chans (mus-channels m1) (mus-length m1))) (do ((i 0 (+ i 1))) ((= i chans)) (locsig-set! m1 i (* i .1))) (do ((i 0 (+ i 1))) ((= i chans)) (if (fneq (locsig-ref m1 i) (* i .1)) (snd-display #__line__ ";locsig[~A] = ~A (~A)?" i (locsig-ref m1 i) (* i .1)))))) (list 1 2 4 8)) (let ((var (catch #t (lambda () (make-locsig :channels 0)) (lambda args args)))) (if (not (eq? (car var) 'mus-error)) (snd-display #__line__ ";make-locsig bad (0) chans: ~A" var))) (let ((var (catch #t (lambda () (make-locsig :channels -2)) (lambda args args)))) (if (not (eq? (car var) 'out-of-range)) (snd-display #__line__ ";make-locsig bad (-2) chans: ~A" var))) (let ((var (catch #t (lambda () (make-locsig :output 1)) (lambda args args)))) (if (not (eq? (car var) 'wrong-type-arg)) (snd-display #__line__ ";make-locsig bad output: ~A" var))) (let ((var (catch #t (lambda () (locsig-ref (make-locsig) 1)) (lambda args args)))) (if (and (pair? var) (not (eq? (car var) 'mus-error))) (snd-display #__line__ ";locsig-ref bad chan: ~A" var))) (let ((var (catch #t (lambda () (make-locsig :revout 1)) (lambda args args)))) (if (and (pair? var) (not (eq? (car var) 'wrong-type-arg))) (snd-display #__line__ ";make-locsig bad revout: ~A" var))) (let ((var (catch #t (lambda () (let ((locs (make-locsig 200 :channels 2))) (locsig-ref locs -1))) (lambda args args)))) (if (and (pair? var) (not (eq? (car var) 'mus-error))) (snd-display #__line__ ";locsig-ref bad chan: ~A" var))) (let ((var (catch #t (lambda () (let ((locs (make-locsig))) (locsig-set! locs 2 .1))) (lambda args args)))) (if (and (pair? var) (not (eq? (car var) 'mus-error))) (snd-display #__line__ ";locsig-set! bad chan (2): ~A" var))) (let ((var (catch #t (lambda () (let ((locs (make-locsig :reverb .1))) (locsig-reverb-ref locs 2))) (lambda args args)))) (if (and (pair? var) (not (eq? (car var) 'mus-error))) (snd-display #__line__ ";locsig-reverb-ref bad reverb chan (2): ~A" var))) (let ((var (catch #t (lambda () (let ((locs (make-locsig :reverb .1))) (locsig-reverb-set! locs 2 .1))) (lambda args args)))) (if (and (pair? var) (not (eq? (car var) 'mus-error))) (snd-display #__line__ ";locsig-reverb-set! bad reverb chan (2): ~A" var))) (let ((locs (make-locsig :channels 8 :degree 0))) (move-locsig locs 180 1.0) (if (fneq (locsig-ref locs 0) 0.0) (snd-display #__line__ ";move-locsig by jump: ~A" (mus-data locs))) (if (not (vequal (mus-data locs) (float-vector 0.000 0.000 0.000 0.000 1.000 0.000 0.000 0.000))) (snd-display #__line__ ";move-locsig by jump data: ~A" (mus-data locs))) (move-locsig locs 120.0 1.0) (if (not (vequal (mus-data locs) (float-vector 0.000 0.000 0.333 0.667 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";move-locsig by jump 120 data: ~A" (mus-data locs))) (move-locsig locs -20.0 1.0) (if (not (vequal (mus-data locs) (float-vector 0.556 0.000 0.000 0.000 0.000 0.000 0.000 0.444))) (snd-display #__line__ ";move-locsig by jump -20 data: ~A" (mus-data locs)))) (let ((sf (make-sample->file "fmv4.snd" 8 mus-bshort mus-next "this is a comment")) (sfrev (make-sample->file "fmv4.reverb" 8 mus-bshort mus-next "this is a comment"))) (let ((locs (make-locsig :channels 8 :degree 0 :distance 1.0 :reverb 0.1 :output sf :revout sfrev :type mus-interp-linear))) (if (not (vequal (mus-data locs) (float-vector 1.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";ws not move-locsig by jump data: ~A" (mus-data locs))) (if (not (vequal (mus-xcoeffs locs) (float-vector 0.100 0.000 0.000 0.000 0.0 0.0 0.0 0.0))) (snd-display #__line__ ";ws not move-locsig by jump rev data: ~A" (mus-xcoeffs locs))) (move-locsig locs 180 2.0) (if (fneq (locsig-ref locs 0) 0.0) (snd-display #__line__ ";ws move-locsig by jump: ~A" (mus-data locs))) (if (not (vequal (mus-data locs) (float-vector 0.000 0.000 0.000 0.000 0.500 0.000 0.000 0.000))) (snd-display #__line__ ";ws move-locsig by jump data: ~A" (mus-data locs))) (if (not (vequal (mus-xcoeffs locs) (float-vector 0.000 0.000 0.000 0.000 0.071 0.000 0.000 0.000))) (snd-display #__line__ ";ws move-locsig by jump rev data: ~A" (mus-xcoeffs locs))) (move-locsig locs 120.0 3.0) (if (not (vequal (mus-data locs) (float-vector 0.000 0.000 0.111 0.222 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";ws move-locsig by jump 120 data: ~A" (mus-data locs))) (if (not (vequal (mus-xcoeffs locs) (float-vector 0.000 0.000 0.019 0.038 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";ws move-locsig by jump 120 rev data: ~A" (mus-xcoeffs locs))) (move-locsig locs -20.0 4.0) (if (not (vequal (mus-data locs) (float-vector 0.139 0.000 0.000 0.000 0.000 0.000 0.000 0.111))) (snd-display #__line__ ";ws move-locsig by jump -20 data: ~A" (mus-data locs))) (if (not (vequal (mus-xcoeffs locs) (float-vector 0.028 0.000 0.000 0.000 0.000 0.000 0.000 0.022))) (snd-display #__line__ ";ws move-locsig by jump -20 rev data: ~A" (mus-xcoeffs locs)))) (mus-close sf) (mus-close sfrev)) (if (file-exists? "fmv4.snd") (delete-file "fmv4.snd")) (if (file-exists? "fmv4.reverb") (delete-file "fmv4.reverb")) (mus-sound-prune) (for-each (lambda (ht) (let ((ind (find-sound (with-sound (:channels 8) (do ((i 0 (+ i 1))) ((= i 8)) (locsig (make-locsig :degree (* i 45) :output *output*) i 0.5)))))) (do ((i 0 (+ i 1))) ((= i 8)) (let ((samps (channel->float-vector 0 8 ind i))) (do ((k 0 (+ k 1))) ((= k 8)) (if (and (= k i) (fneq (samps k) 0.5)) (snd-display #__line__ ";8 out ~A chan ~A samp ~A (0.5): ~A" (mus-header-type->string ht) i k (samps k))) (if (and (not (= i k)) (fneq (samps k) 0.0)) (snd-display #__line__ ";8 out ~A chan ~A samp ~A (0.0): ~A" (mus-header-type->string ht) i k (samps k)))))) (close-sound ind))) (list mus-caff mus-aifc mus-next mus-riff mus-rf64)) (let* ((gen (make-frample->file "fmv4.snd" 2 mus-bshort mus-next)) (rev (make-frample->file "fmv4.reverb" 1 mus-bshort mus-next)) (lc (make-locsig 60.0 :reverb .1 :channels 2 :output gen :revout rev))) (do ((i 0 (+ i 1))) ((= i 100)) (locsig lc i 1.0)) (if (fneq (locsig-reverb-ref lc 0) .1) (snd-display #__line__ ";locsig reverb ref: ~A?" (locsig-reverb-ref lc 0))) (locsig-reverb-set! lc 0 .2) (if (fneq (locsig-reverb-ref lc 0) .2) (snd-display #__line__ ";locsig reverb set: ~A?" (locsig-reverb-ref lc 0))) (mus-close gen) (mus-close rev) (let ((v0 (make-float-vector 100)) (v1 (make-float-vector 100)) (v2 (make-float-vector 100))) (file->array "fmv4.snd" 0 0 100 v0) (file->array "fmv4.snd" 1 0 100 v1) (file->array "fmv4.reverb" 0 0 100 v2) (if (fneq (v2 0) .1) (snd-display #__line__ ";locsig reverb: ~A?" v2)) (if (fneq (* 2 (v0 0)) (v1 0)) (snd-display #__line__ ";locsig direct: ~A ~A?" (v0 0) (v1 0))))) (let* ((gen (make-frample->file "fmv4.snd" 4 mus-bshort mus-next)) (rev (make-frample->file "fmv4.reverb" 4 mus-bshort mus-next)) (lc (make-locsig 60.0 :reverb .1 :channels 4 :distance 4.0 :output gen :revout rev))) (print-and-check lc "locsig" "locsig chans 4, outn: [0.083 0.167 0.000 0.000], revn: [0.017 0.033 0.000 0.000], interp: linear") (do ((i 0 (+ i 1))) ((= i 100)) (locsig lc i 1.0)) (do ((i 0 (+ i 1))) ((= i 4)) (locsig-reverb-set! lc i (* i .1)) (if (fneq (locsig-reverb-ref lc i) (* i .1)) (snd-display #__line__ ";locsig reverb set![~A]: ~A?" i (locsig-reverb-ref lc i)))) (print-and-check lc "locsig" "locsig chans 4, outn: [0.083 0.167 0.000 0.000], revn: [0.000 0.100 0.200 0.300], interp: linear") (if (not (float-vector? (mus-data lc))) (snd-display #__line__ ";out data locsig: ~A" (mus-data lc))) (if (not (float-vector? (mus-xcoeffs lc))) (snd-display #__line__ ";rev data locsig: ~A" (mus-xcoeffs lc))) (let ((xcs (mus-xcoeffs lc))) (if (fneq (mus-xcoeff lc 0) (xcs 0)) (snd-display #__line__ ";locsig xcoeff: ~A ~A" (mus-xcoeff lc 0) (xcs 0))) (if (fneq (mus-xcoeff lc 1) .1) (snd-display #__line__ ";locsig xcoeff 1: ~A ~A (.1)" (mus-xcoeff lc 0) (xcs 0)))) (mus-close gen) (mus-close rev)) (print-and-check (make-locsig 160 :channels 4) "locsig" "locsig chans 4, outn: [0.000 0.222 0.778 0.000], interp: linear") (print-and-check (make-locsig -200 :channels 4) "locsig" "locsig chans 4, outn: [0.000 0.222 0.778 0.000], interp: linear") (print-and-check (make-locsig 160 :channels 4 :distance .5) "locsig" "locsig chans 4, outn: [0.000 0.222 0.778 0.000], interp: linear") (print-and-check (make-locsig 320 :channels 4) "locsig" "locsig chans 4, outn: [0.556 0.000 0.000 0.444], interp: linear") (print-and-check (make-locsig -40 :channels 4) "locsig" "locsig chans 4, outn: [0.556 0.000 0.000 0.444], interp: linear") (print-and-check (make-locsig 320 :channels 2) "locsig" "locsig chans 2, outn: [0.000 1.000], interp: linear") (print-and-check (make-locsig -40 :channels 2) "locsig" "locsig chans 2, outn: [1.000 0.000], interp: linear") (print-and-check (make-locsig 160 :channels 4 :output (make-float-vector (list 4 10) 0.0)) "locsig" "locsig chans 4, outn: [0.000 0.222 0.778 0.000], interp: linear") (print-and-check (make-locsig 0 :channels 1 :output (make-float-vector 10)) "locsig" "locsig chans 1, outn: [1.000], interp: linear") (letrec ((locsig-data (lambda (gen) (let* ((chans (mus-channels gen)) (dat (make-float-vector chans))) (do ((i 0 (+ i 1))) ((= i chans)) (set! (dat i) (locsig-ref gen i))) dat)))) (let ((gen (make-locsig -.1 :channels 8))) (if (not (vequal (locsig-data gen) (float-vector 0.998 0.000 0.000 0.000 0.000 0.000 0.000 0.002))) (snd-display #__line__ ";locsig -.1(8): ~A" (locsig-data gen))) (set! gen (make-locsig -359.9 :channels 8)) (if (not (vequal (locsig-data gen) (float-vector 0.998 0.002 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";locsig -359.9(8): ~A" (locsig-data gen))) (set! gen (make-locsig -359.9 :channels 4)) (if (not (vequal (locsig-data gen) (float-vector 0.999 0.001 0.000 0.000))) (snd-display #__line__ ";locsig -359.9(4): ~A" (locsig-data gen))) (set! gen (make-locsig -360.1 :channels 8)) (if (not (vequal (locsig-data gen) (float-vector 0.998 0.000 0.000 0.000 0.000 0.000 0.000 0.002))) (snd-display #__line__ ";locsig -360.1(8): ~A" (locsig-data gen))) (set! gen (make-locsig -700 :channels 8)) (if (not (vequal (locsig-data gen) (float-vector 0.556 0.444 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";locsig -700(8): ~A" (locsig-data gen))) (set! gen (make-locsig -700 :channels 2)) (if (not (vequal (locsig-data gen) (float-vector 1.000 0.000))) (snd-display #__line__ ";locsig -700(2): ~A" (locsig-data gen))) (set! gen (make-locsig 20 :channels 2)) (if (not (vequal (locsig-data gen) (float-vector 0.778 0.222))) (snd-display #__line__ ";locsig 20(2): ~A" (locsig-data gen))) (set! gen (make-locsig 123456.0 :channels 8)) (if (not (vequal (locsig-data gen) (float-vector 0.467 0.000 0.000 0.000 0.000 0.000 0.000 0.533))) (snd-display #__line__ ";locsig 123456(8): ~A" (locsig-data gen))) (set! gen (make-locsig 336.0 :channels 8)) (if (not (vequal (locsig-data gen) (float-vector 0.467 0.000 0.000 0.000 0.000 0.000 0.000 0.533))) (snd-display #__line__ ";locsig 336(8): ~A" (locsig-data gen))) (set! gen (make-locsig -123456.0 :channels 8)) (if (not (vequal (locsig-data gen) (float-vector 0.467 0.533 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";locsig -123456(8): ~A" (locsig-data gen))) (set! gen (make-locsig 24.0 :channels 8)) (if (not (vequal (locsig-data gen) (float-vector 0.467 0.533 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";locsig 24(8): ~A" (locsig-data gen))))) (for-each (lambda (rev-chans) (define (locsig-scalers chans degree type) (define (xmodulo a b) (let ((pos (floor (/ a b)))) (- a (* pos b)))) (if (= chans 1) (float-vector 1.0) (let* ((deg (if (= chans 2) (max 0.0 (min 90.0 degree)) (xmodulo degree 360.0))) (degs-per-chan (if (= chans 2) 90.0 (/ 360.0 chans))) (pos (/ deg degs-per-chan)) (left (floor pos)) (right (xmodulo (+ left 1) chans)) (frac (- pos left)) (v (make-float-vector chans))) (if (= type mus-interp-linear) (begin (set! (v left) (- 1.0 frac)) (set! (v right) frac)) (let* ((ldeg (* (/ pi 2) (- 0.5 frac))) (norm (/ (sqrt 2.0) 2.0)) (c (cos ldeg)) (s (sin ldeg))) (set! (v left) (* norm (+ c s))) (set! (v right) (* norm (- c s))))) v))) (if (file-exists? "test.reverb") (delete-file "test.reverb")) (let ((revfile (and (> rev-chans 0) (make-frample->file "test.reverb" rev-chans mus-bshort mus-next))) (happy #t)) (for-each (lambda (type) ;; global type def as well as local par override etc (if happy (begin (set! (locsig-type) type) (if (not (= (locsig-type) type)) (snd-display #__line__ ";locsig-type: ~A ~A" type (locsig-type))) (for-each (lambda (deg) (let ((gen (make-locsig deg :channels 1 :revout revfile :reverb .1 :distance 2.0)) (revs (if revfile (locsig-scalers rev-chans deg type)))) (if (not (= (mus-channels gen) 1)) (snd-display #__line__ ";locsig ~A: ~A" deg gen)) (if (fneq (locsig-ref gen 0) 0.5) (snd-display #__line__ ";locsig scaler[~A] ~A: ~A" type deg (locsig-ref gen 0))) (if revfile (do ((i 0 (+ i 1))) ((or (not happy) (= i rev-chans))) (if (fneq (locsig-reverb-ref gen i) (* (/ .1 (sqrt 2.0)) (revs i))) (begin (snd-display #__line__ ";mono locrev[~A] ~A at ~A: ~A ~A" type gen deg (locsig-reverb-ref gen i) (* (/ .1 (sqrt 2.0)) (revs i))) (set! happy #f))))))) (list 0.0 45.0 90.0 1234.0)) (for-each (lambda (ltype) (for-each (lambda (deg) (let ((gen (make-locsig deg :channels 1 :type ltype))) (if (not (= (mus-channels gen) 1)) (snd-display #__line__ ";locsig ~A: ~A" deg gen)) (if (fneq (locsig-ref gen 0) 1.0) (snd-display #__line__ ";locsig[~A] scaler ~A: ~A" ltype deg (locsig-ref gen 0))))) (list 0.0 45.0 90.0 1234.0))) (list mus-interp-linear mus-interp-sinusoidal)) (for-each (lambda (chans) (for-each (lambda (deg) (let ((gen (make-locsig deg :channels chans :revout revfile :reverb .1))) (if (not (= (mus-channels gen) chans)) (snd-display #__line__ ";multi locsig ~A: ~A" deg gen)) (let ((scalers (locsig-scalers chans deg type)) (revs (if revfile (locsig-scalers rev-chans deg type)))) (do ((i 0 (+ i 1))) ((or (not happy) (= i chans))) (if (fneq (locsig-ref gen i) (scalers i)) (begin (snd-display #__line__ ";locsig[~A] ~A at ~A: ~A ~A" type gen deg (locsig-ref gen i) (scalers i)) (set! happy #f)))) (if revfile (do ((i 0 (+ i 1))) ((or (not happy) (= i rev-chans))) (if (fneq (locsig-reverb-ref gen i) (* .1 (revs i))) (begin (snd-display #__line__ ";locrev[~A] ~A at ~A: ~A ~A" type gen deg (locsig-reverb-ref gen i) (* .1 (revs i))) (set! happy #f)))))))) (list 0.0 45.0 90.0 120.0 180.0 275.0 315.0 300.0 15.0 1234.0))) (list 2 3 4 5 8 12 16 24)) (for-each (lambda (chans) (for-each (lambda (ltype) (for-each (lambda (deg) (let ((gen (make-locsig deg :channels chans :type ltype :revout revfile :reverb .1))) (if (not (= (mus-channels gen) chans)) (snd-display #__line__ ";stereo locsig ~A: ~A" deg gen)) (let ((scalers (locsig-scalers chans deg ltype)) (revs (if revfile (locsig-scalers rev-chans deg ltype)))) (do ((i 0 (+ i 1))) ((or (not happy) (= i chans))) (if (fneq (locsig-ref gen i) (scalers i)) (begin (snd-display #__line__ ";locsig[~A] ~A at ~A: ~A ~A" ltype gen deg (locsig-ref gen i) (scalers i)) (set! happy #f)))) (if revfile (do ((i 0 (+ i 1))) ((or (not happy) (= i rev-chans))) (if (fneq (locsig-reverb-ref gen i) (* .1 (revs i))) (begin (snd-display #__line__ ";locrev[~A] ~A at ~A: ~A ~A" type gen deg (locsig-reverb-ref gen i) (* .1 (revs i))) (set! happy #f)))))))) (list 0.0 45.0 90.0 120.0 180.0 275.0 315.0 300.0 15.0 1234.0))) (list mus-interp-linear mus-interp-sinusoidal))) (list 2 3 4 5 8 12 16 24)) ))) (list mus-interp-linear mus-interp-sinusoidal)) (if revfile (mus-close revfile)))) (list 0 1 2 4)) (set! (locsig-type) mus-interp-linear) (let* ((outp (make-float-vector (list 1 10) 0.0)) (gen (make-locsig 0.0 :output outp))) (if (not (= (mus-channels gen) 1)) (snd-display #__line__ ";make-locsig->sd chans (1): ~A" (mus-channels gen))) (do ((i 0 (+ i 1))) ((= i 10)) (locsig gen i 1.0)) (if (not (vequal (outp 0) (make-float-vector 10 1.0))) (snd-display #__line__ ";locsig->sd chan 0: ~A" (outp 0)))) (let* ((outp (make-float-vector (list 2 10) 0.0)) (gen (make-locsig 0.0 :output outp))) (if (not (= (mus-channels gen) 2)) (snd-display #__line__ ";make-locsig->sd chans: ~A" (mus-channels gen))) (do ((i 0 (+ i 1))) ((= i 10)) (locsig gen i 1.0)) (if (not (vequal (outp 0) (make-float-vector 10 1.0))) (snd-display #__line__ ";locsig->sd chan 0: ~A" (outp 0))) (if (not (vequal (outp 1) (make-float-vector 10 0.0))) (snd-display #__line__ ";locsig->sd chan 1: ~A" (outp 1)))) (let* ((outp (make-float-vector (list 2 10) 0.0)) (gen (make-locsig 45.0 :output outp))) (if (not (= (mus-channels gen) 2)) (snd-display #__line__ ";make-locsig->sd chans: ~A" (mus-channels gen))) (do ((i 0 (+ i 1))) ((= i 10)) (locsig gen i 1.0)) (if (not (vequal (outp 0) (make-float-vector 10 0.5))) (snd-display #__line__ ";locsig->sd chan 0 (0.5): ~A (~A)" (outp 0) gen)) (if (not (vequal (outp 1) (make-float-vector 10 0.5))) (snd-display #__line__ ";locsig->sd chan 1 (0.5): ~A" (outp 1))) (do ((i 0 (+ i 1))) ((= i 10)) (locsig gen i 0.5)) (if (not (vequal (outp 0) (make-float-vector 10 0.75))) (snd-display #__line__ ";locsig->sd chan 0 (0.75) (~A): ~A" (outp 0) gen)) (if (not (vequal (outp 1) (make-float-vector 10 0.75))) (snd-display #__line__ ";locsig->sd chan 1 (0.75): ~A" (outp 1)))) (let* ((outp (make-float-vector 10)) (gen (make-locsig 0.0 :output outp))) (if (not (= (mus-channels gen) 1)) (snd-display #__line__ ";make-locsig->float-vector chans: ~A" (mus-channels gen))) (do ((i 0 (+ i 1))) ((= i 10)) (locsig gen i 1.0)) (if (not (vequal outp (make-float-vector 10 1.0))) (snd-display #__line__ ";locsig->float-vector chan 0: ~A" outp)) (do ((i 0 (+ i 1))) ((= i 10)) (locsig gen i 0.5)) (if (not (vequal outp (make-float-vector 10 1.5))) (snd-display #__line__ ";locsig->float-vector chan 0: ~A" outp))) (let* ((outp (make-float-vector 10)) (gen (make-locsig 45.0 :channels 2 :output outp))) (if (not (= (mus-channels gen) 2)) (snd-display #__line__ ";make-locsig->float-vector chans (2): ~A" (mus-channels gen))) (do ((i 0 (+ i 1))) ((= i 10)) (locsig gen i 1.0)) (if (not (vequal outp (make-float-vector 10 0.5))) (snd-display #__line__ ";locsig(2)->float-vector chan 0: ~A" outp)) (do ((i 0 (+ i 1))) ((= i 10)) (locsig gen i 0.5)) (if (not (vequal outp (make-float-vector 10 0.75))) (snd-display #__line__ ";locsig(2)->float-vector chan 0: ~A" outp))) (let* ((outp (make-float-vector (list 4 10) 0.0)) (gen (make-locsig 135.0 :output outp))) (if (not (= (mus-channels gen) 4)) (snd-display #__line__ ";make-locsig->sd chans (4): ~A" (mus-channels gen))) (do ((i 0 (+ i 1))) ((= i 10)) (locsig gen i 1.0)) (if (not (vequal (outp 0) (make-float-vector 10 0.0))) (snd-display #__line__ ";locsig(4)->sd chan 0 (0.5): ~A" (outp 0))) (if (not (vequal (outp 1) (make-float-vector 10 0.5))) (snd-display #__line__ ";locsig(4)->sd chan 1 (0.5) (~A): ~A" (outp 1) gen)) (if (not (vequal (outp 2) (make-float-vector 10 0.5))) (snd-display #__line__ ";locsig(4)->sd chan 2 (0.5): ~A" (outp 2))) (if (not (vequal (outp 3) (make-float-vector 10 0.0))) (snd-display #__line__ ";locsig(4)->sd chan 3 (0.5): ~A" (outp 3)))) (set! *mus-array-print-length* 8) (let* ((outf1 (make-frample->file "fmv.snd" 1 mus-ldouble mus-next)) (outf4 (make-frample->file "fmv1.snd" 4 mus-ldouble mus-next)) (revf (make-frample->file "fmv2.snd" 1 mus-ldouble mus-next)) (start 0) (end 1000) (dur 1.0) (gen1 (make-move-sound (list 0 1000 1 0 (make-delay 32) (make-env '(0 0 1 1) :length 1001) (make-env '(0 0 1 1) :length 1001) (vector (make-delay 32)) (vector (make-env '(0 0 1 1) :length 1001)) #f (vector 0 1)) outf1)) (gen2 (make-move-sound (list start end 4 0 (make-delay 12) (make-env '(0 0 10 1) :duration dur) #f (make-vector 4 #f) (vector (make-env '(0 0 1 1 2 0 3 0 4 0) :duration dur) (make-env '(0 0 1 0 2 1 3 0 4 0) :duration dur) (make-env '(0 0 1 0 2 0 3 1 4 0) :duration dur) (make-env '(0 0 1 0 2 0 3 0 4 1) :duration dur)) #f (vector 0 1 2 3)) outf4)) (gen3 (make-move-sound (list 0 1000 1 1 (make-delay 32) (make-env '(0 0 1 1) :length 1001) (make-env '(0 0 1 1) :length 1001) (vector (make-delay 32)) (vector (make-env '(0 0 1 1) :length 1001)) (vector (make-env '(0 1 1 1) :length 1001)) (vector 0 1)) outf1 revf))) (print-and-check gen1 "move-sound" "move-sound start: 0, end: 1000, out chans 1, rev chans: 0 doppler delay line[32, step]: [0 0 0 0 0 0 0 0...(0: 0, 0: 0)] doppler env linear, pass: 0 (dur: 1001), index: 0, scaler: 1.0000, offset: 0.0000, data: [0 0 1 1] global reverb env linear, pass: 0 (dur: 1001), index: 0, scaler: 1.0000, offset: 0.0000, data: [0 0 1 1] out_delays[1]: [0]: delay line[32, step]: [0 0 0 0 0 0 0 0...(0: 0, 0: 0)] out_envs[1]: [0]: env linear, pass: 0 (dur: 1001), index: 0, scaler: 1.0000, offset: 0.0000, data: [0 0 1 1] rev_envs: nil out_map[1]: (0) free: arrays: true, gens: false ") (print-and-check gen2 "move-sound" "move-sound start: 0, end: 1000, out chans 4, rev chans: 0 doppler delay line[12, step]: [0 0 0 0 0 0 0 0...(0: 0, 0: 0)] doppler env linear, pass: 0 (dur: 22050), index: 0, scaler: 1.0000, offset: 0.0000, data: [0 0 10 1] global reverb null out_delays[4]: [0]: nil [1]: nil [2]: nil [3]: nil out_envs[4]: [0]: env linear, pass: 0 (dur: 22050), index: 0, scaler: 1.0000, offset: 0.0000, data: [0 0 1 1 2 0 3 0...(0: 0, 8: 4)] [1]: env linear, pass: 0 (dur: 22050), index: 0, scaler: 1.0000, offset: 0.0000, data: [0 0 1 0 2 1 3 0...(0: 0, 8: 4)] [2]: env linear, pass: 0 (dur: 22050), index: 0, scaler: 1.0000, offset: 0.0000, data: [0 0 1 0 2 0 3 1...(0: 0, 8: 4)] [3]: env linear, pass: 0 (dur: 22050), index: 0, scaler: 1.0000, offset: 0.0000, data: [0 0 1 0 2 0 3 0...(0: 0, 8: 4)] rev_envs: nil out_map[4]: (0 1 2 3) free: arrays: true, gens: false ") (print-and-check gen3 "move-sound" "move-sound start: 0, end: 1000, out chans 1, rev chans: 1 doppler delay line[32, step]: [0 0 0 0 0 0 0 0...(0: 0, 0: 0)] doppler env linear, pass: 0 (dur: 1001), index: 0, scaler: 1.0000, offset: 0.0000, data: [0 0 1 1] global reverb env linear, pass: 0 (dur: 1001), index: 0, scaler: 1.0000, offset: 0.0000, data: [0 0 1 1] out_delays[1]: [0]: delay line[32, step]: [0 0 0 0 0 0 0 0...(0: 0, 0: 0)] out_envs[1]: [0]: env linear, pass: 0 (dur: 1001), index: 0, scaler: 1.0000, offset: 0.0000, data: [0 0 1 1] rev_envs[1]: [0]: env linear, pass: 0 (dur: 1001), index: 0, scaler: 1.0000, offset: 0.0000, data: [0 1 1 1] out_map[1]: (0) free: arrays: true, gens: false ") (if (not (move-sound? gen1)) (snd-display #__line__ ";move-sound?")) (if (equal? gen1 gen2) (snd-display #__line__ ";move-sounds are equal?")) (if (not (= (mus-channels gen1) 1)) (snd-display #__line__ ";mus-channels move-sound (1): ~A" (mus-channels gen1))) (if (not (= (mus-channels gen2) 4)) (snd-display #__line__ ";mus-channels move-sound (4): ~A" (mus-channels gen2))) (mus-reset gen1) ; a no-op (let ((v (make-float-vector 10 0.0))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v i) (+ (move-sound gen1 i 0.5) (gen2 i 0.25) (move-sound gen3 i 0.125)))) (if (not (vequal v (make-float-vector 10 0.875))) (snd-display #__line__ ";move-sound output: ~A" v))) (let ((var (catch #t (lambda () (make-move-sound (list 0 1000 1 0 (make-oscil 32) (make-env '(0 0 1 1) :length 1001) (make-env '(0 0 1 1) :length 1001) (vector (make-delay 32)) (vector (make-env '(0 0 1 1) :length 1001)) #f (vector 0 1)) outf1)) (lambda args args)))) (if (not (eq? (car var) 'wrong-type-arg)) (snd-display #__line__ ";make-move-sound bad doppler delay: ~A" var))) (let ((var (catch #t (lambda () (make-move-sound (list 0 1000 1 0 (make-oscil 32) (make-env '(0 0 1 1) :length 1001) (make-env '(0 0 1 1) :length 1001) (vector (make-delay 32))) outf1)) (lambda args args)))) (if (not (eq? (car var) 'wrong-type-arg)) (snd-display #__line__ ";make-move-sound truncated list: ~A" var))) (let ((var (catch #t (lambda () (make-move-sound (list 0 1000 1 0 (make-delay 32) (make-env '(0 0 1 1) :length 1001) #f (vector #f) (vector (make-env '(0 0 1 1) :length 1001)) #f #f) outf1)) (lambda args args)))) (if (not (eq? (car var) 'wrong-type-arg)) (snd-display #__line__ ";make-move-sound no out map: ~A" var))) (mus-close outf1) (mus-close outf4) (mus-close revf) (if (file-exists? "fmv.snd") (delete-file "fmv.snd")) (if (file-exists? "fmv1.snd") (delete-file "fmv1.snd")) (if (file-exists? "fmv2.snd") (delete-file "fmv2.snd")) (mus-sound-prune)) (let* ((vo (make-float-vector 1000)) (gen1 (make-move-sound (list 0 1000 1 0 (make-delay 32) (make-env '(0 0 1 1) :length 1001) (make-env '(0 0 1 1) :length 1001) (vector (make-delay 32)) (vector (make-env '(0 0 1 1) :length 1001)) #f (vector 0 1)) vo)) (start -1)) (do ((i 0 (+ i 1))) ((= i 1000)) (move-sound gen1 i 0.5) (if (and (< start 0) (fneq (vo i) 0.0)) (set! start i))) (if (not (= start 64)) (snd-display #__line__ ";move-sound float-vector output start: ~A" start)) (if (fneq (float-vector-peak vo) 0.484) (snd-display #__line__ ";move-sound float-vector output: ~A" (float-vector-peak vo)))) (let* ((vo (make-float-vector (list 1 1000) 0.0)) (gen1 (make-move-sound (list 0 1000 1 0 (make-delay 32) (make-env '(0 0 1 1) :length 1001) (make-env '(0 0 1 1) :length 1001) (vector (make-delay 32)) (vector (make-env '(0 0 1 1) :length 1001)) #f (vector 0 1)) vo)) (start -1)) (do ((i 0 (+ i 1))) ((= i 1000)) (move-sound gen1 i 0.5) (if (and (< start 0) (fneq (vo 0 i) 0.0)) (set! start i))) (if (not (= start 64)) (snd-display #__line__ ";move-sound sd output start: ~A" start)) (if (fneq (maxamp vo) 0.484) (snd-display #__line__ ";move-sound sd output: ~A" (maxamp vo)))) (let* ((vo (make-float-vector 1000)) (gen1 (make-move-sound (list 0 1000 1 0 (make-delay 32) (make-env '(0 0 1 1) :length 1001) (make-env '(0 0 1 1) :length 1001) (vector (make-delay 32)) (vector (make-env '(0 0 1 1) :length 1001)) #f (vector 0 1)) vo)) (start -1)) (do ((i 0 (+ i 1))) ((= i 1000)) (move-sound gen1 i 0.5) (if (and (< start 0) (> (abs (vo i)) 0.001)) (set! start i))) (if (not (= start 64)) (snd-display #__line__ ";move-sound opt float-vector output start: ~A" start)) (if (fneq (float-vector-peak vo) 0.484) (snd-display #__line__ ";move-sound opt float-vector output: ~A" (float-vector-peak vo)))) (let* ((vo (make-float-vector (list 1 1000) 0.0)) (gen1 (make-move-sound (list 0 1000 1 0 (make-delay 32) (make-env '(0 0 1 1) :length 1001) (make-env '(0 0 1 1) :length 1001) (vector (make-delay 32)) (vector (make-env '(0 0 1 1) :length 1001)) #f (vector 0 1)) vo)) (start -1)) (do ((i 0 (+ i 1))) ((= i 1000)) (move-sound gen1 i 0.5) (if (and (< start 0) (> (abs (vo 0 i)) 0.001)) (set! start i))) (if (not (= start 64)) (snd-display #__line__ ";move-sound opt sd output start: ~A" start)) (if (fneq (maxamp vo) 0.484) (snd-display #__line__ ";move-sound opt sd output: ~A" (maxamp vo)))) (let ((var (catch #t (lambda () (make-src :width -1)) (lambda args args)))) (if (not (eq? (car var) 'out-of-range)) (snd-display #__line__ ";make-src bad width: ~A" var))) (let ((s1 (make-src (lambda (y) 1.0) 2.0))) (src s1 25.0) ; try to tickle segfault (src s1 25.0) (src s1 125.0) (src s1 -25.0) (src s1 -125.0)) (do ((i 0 (+ i 1))) ((= i 10)) (make-src (lambda (y) 1.0) 1.5 :width (+ 5 (* i 10)))) (let ((ctr 0.0)) (let ((gen (make-src :srate 2.0 :input (lambda (dir) (let ((val ctr)) (set! ctr (+ ctr 1)) val)))) (v0 (make-float-vector 10))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v0 i) (src gen 0.0))) (set! ctr 0.0) ; will be accessed within reset (mus-reset gen) (do ((i 0 (+ i 1))) ((= i 10)) (let ((old-val (v0 i)) (new-val (src gen 0.0))) (if (fneq old-val new-val) (snd-display #__line__ ";reset src ~A ~A ~A" i old-val new-val)))))) (let () (define (so1 s p) (src s (env p))) (let ((s1 (make-src :srate 2.0 :input (make-readin "oboe.snd" 0 10000))) (s2 (make-src :srate 2.0 :input (make-readin "oboe.snd" 0 10000))) (s3 (make-src :srate 2.0 :input (make-readin "oboe.snd" 0 10000))) (e1 (make-env '(0 1 2 0.5) :duration 1000)) (e2 (make-env '(0 1 2 0.5) :duration 1000)) (e3 (make-env '(0 1 2 0.5) :duration 1000))) (do ((i 0 (+ i 1))) ((= i 100)) (let ((x1 (src s1 (env e1))) (ex2 (env e2))) (let ((x2 (src s2 ex2)) (x3 (so1 s3 e3))) (if (not (= x1 x2 x3)) (format #t "~D ~A ~A ~A~%" i x1 x2 x3))))))) (let ((gen (make-granulate :expansion 2.0 :input (make-readin "oboe.snd" 0 4000 1 2048))) (v0 (make-float-vector 1000)) (v1 (make-float-vector 1000)) (rd1b (make-readin :file "oboe.snd" :channel 0 :start 4000 :direction 1 :size *clm-file-buffer-size*))) (let ((gen1 (make-granulate :expansion 2.0 :input (lambda (dir) (readin rd1b))))) (print-and-check gen "granulate" "granulate expansion: 2.000 (551/1102), scaler: 0.600, length: 0.150 secs (3308 samps), ramp: 0.060") (do ((i 0 (+ i 1))) ((= i 1000)) (set! (v0 i) (granulate gen))) (fill-float-vector v1 (if (granulate? gen1) (granulate gen1) -1.0)) (let ((worst (abs (- (float-vector-peak v0) (float-vector-peak v1))))) (if (> worst .01) (snd-display #__line__ ";run granulate: ~A" worst))) (let ((genx gen1)) (if (not (equal? genx gen1)) (snd-display #__line__ ";granulate equal? ~A ~A ~A" genx gen1 (equal? genx gen1)))) (if (equal? gen gen1) (snd-display #__line__ ";granulate equal? ~A ~A" gen gen1)) (if (= (float-vector-peak v0) 0.0) (snd-display #__line__ ";granulate output peak: ~F?" (float-vector-peak v0))) (if (not (granulate? gen)) (snd-display #__line__ ";~A not granulate?" gen)) (if (fneq (mus-increment gen) 2.0) (snd-display #__line__ ";granulate increment: ~F?" (mus-increment gen))) (if (fneq (mus-scaler gen) 0.6) (snd-display #__line__ ";granulate scaler: ~F?" (mus-scaler gen))) (if (ffneq (mus-frequency gen) 0.05) (snd-display #__line__ ";granulate frequency: ~F?" (mus-frequency gen))) (if (not (= (mus-ramp gen) 1323)) (snd-display #__line__ ";granulate ramp: ~F?" (mus-ramp gen))) (if (not (= (mus-length gen) 3308)) (snd-display #__line__ ";granulate length: ~A?" (mus-length gen))) (if (not (= (mus-hop gen) 1102)) (snd-display #__line__ ";granulate hop: ~A?" (mus-hop gen))) (set! (mus-hop gen) 1000) (if (not (= (mus-hop gen) 1000)) (snd-display #__line__ ";granulate set-hop: ~A?" (mus-hop gen))) (set! (mus-ramp gen) 1000) (if (not (= (mus-ramp gen) 1000)) (snd-display #__line__ ";granulate set-ramp: ~A?" (mus-ramp gen))) (set! (mus-length gen) 3000) (if (not (= (mus-length gen) 3000)) (snd-display #__line__ ";granulate set-length: ~A?" (mus-length gen))) (set! (mus-increment gen) 3.0) (if (> (abs (- (mus-increment gen) 3.0)) .01) (snd-display #__line__ ";granulate set-increment: ~F?" (mus-increment gen))) (set! (mus-increment gen) 0.0) ; should be a no-op (if (> (abs (- (mus-increment gen) 3.0)) .01) (snd-display #__line__ ";granulate set-increment 0.0: ~F?" (mus-increment gen))) (set! (mus-location gen) 1) (if (not (= (mus-location gen) 1)) (snd-display #__line__ ";mus-location grn: ~A" (mus-location gen))) (set! (mus-frequency gen) .1) (if (fneq (mus-frequency gen) .1) (snd-display #__line__ ";set granulate freq: ~A" (mus-frequency gen)))) (let ((var (catch #t (lambda () (make-granulate :hop 35.0 :length 35.0)) (lambda args args)))) (if (not (eq? (car var) 'out-of-range)) (snd-display #__line__ ";make-granulate bad sizes: ~A" var)))) (let ((ind (new-sound :size 10))) (set! (sample 2) .1) (set! (sample 6) -.5) (let ((rd (make-sampler))) (let ((vals (map values rd))) (if (not (morally-equal? vals '(0.0 0.0 0.1 0.0 0.0 0.0 -0.5 0.0 0.0 0.0))) (snd-display #__line__ ";rd new: ~A" vals)))) (close-sound ind)) (let ((ind (open-sound "oboe.snd")) (mx (maxamp))) (let ((rd (make-sampler 0))) (if (not (= (length rd) 50828)) (snd-display #__line__ ";sampler (oboe) length: ~A" (length rd))) (let ((grn (make-granulate :expansion 2.0 :input (lambda (dir) (read-sample rd)) :edit (lambda (g) (float-vector-scale! (mus-data g) 2.0) 0)))) (map-channel (lambda (y) (granulate grn))) (if (or (< (/ (maxamp) mx) 1.4) (> (/ mx (maxamp)) 2.5)) (snd-display #__line__ ";gran edit 2* (0): ~A ~A" mx (maxamp))) (undo))) (let ((rd (make-sampler 0))) (let ((grn (make-granulate :expansion 2.0 :input (lambda (dir) (read-sample rd)) :edit (lambda (g) (float-vector-scale! (mus-data g) 4.0) 0)))) (map-channel (lambda (y) (granulate grn))) (if (or (< (/ (maxamp) mx) 3.0) (> (/ mx (maxamp)) 6.0)) (snd-display #__line__ ";gran edit 4* (0): ~A ~A" mx (maxamp))) (revert-sound ind))) (let* ((rd (make-sampler 0)) (grn (make-granulate :expansion 2.0 :input (lambda (dir) (read-sample rd)) :edit (lambda (g) (float-vector-scale! (mus-data g) 2.0) 0)))) (map-channel (lambda (y) (granulate grn))) (if (or (< (/ (maxamp) mx) 1.4) (> (/ mx (maxamp)) 2.5)) (snd-display #__line__ ";gran edit 2* (1): ~A ~A" mx (maxamp))) (undo) (let* ((rd (make-sampler 0)) (grn (make-granulate :expansion 2.0 :edit (lambda (g) (float-vector-scale! (mus-data g) 4.0) 0) :input (lambda (dir) (read-sample rd))))) (map-channel (lambda (y) (granulate grn))) (if (or (< (/ (maxamp) mx) 2.9) (> (/ mx (maxamp)) 6.0)) (snd-display #__line__ ";gran edit 4* (1): ~A ~A" mx (maxamp))) (revert-sound ind))) (let ((grn (make-granulate :expansion 2.0 :input (make-sampler 0) :edit (lambda (g) (float-vector-scale! (mus-data g) 2.0) 0)))) (map-channel (lambda (y) (granulate grn))) (if (or (< (/ (maxamp) mx) 1.4) (> (/ mx (maxamp)) 2.5)) (snd-display #__line__ ";gran edit 2* (2): ~A ~A" mx (maxamp))) (undo) (let* ((rd (make-sampler 0)) (grn (make-granulate :expansion 2.0 :input (lambda (dir) (read-sample rd)) :edit (lambda (g) (float-vector-scale! (mus-data g) 4.0) 0)))) (map-channel (lambda (y) (granulate grn))) (if (or (< (/ (maxamp) mx) 3.0) (> (/ mx (maxamp)) 6.0)) (snd-display #__line__ ";gran edit 4* (2): ~A ~A" mx (maxamp))))) (close-sound ind)) (let ((ind (open-sound "oboe.snd"))) (let* ((rd (make-sampler 0)) (grn (make-granulate :expansion 2.0 :length .01 :hop .05 :input (lambda (dir) (next-sample rd))))) (map-channel (lambda (y) (granulate grn))) (let ((mx (maxamp))) (if (> mx .2) (snd-display #__line__ ";trouble in granulate len .01 hop .05: ~A" mx)) (undo))) (let* ((rd (make-sampler 0)) (grn (make-granulate :expansion 2.0 :length .04 :hop .05 :input (lambda (dir) (next-sample rd))))) (map-channel (lambda (y) (granulate grn))) (let ((mx (maxamp))) (if (> mx .2) (snd-display #__line__ ";trouble in granulate len .04 hop .05: ~A" mx)) (undo))) (let* ((rd (make-sampler 0)) (grn (make-granulate :expansion 2.0 :length .01 :hop .25 :input (lambda (dir) (next-sample rd))))) (map-channel (lambda (y) (granulate grn))) (let ((mx (maxamp))) (if (> mx .2) (snd-display #__line__ ";trouble in granulate len .01 hop .25: ~A" mx)) (undo))) (let* ((rd (make-sampler 0)) (grn (make-granulate :expansion 2.0 :length .4 :hop .5 :input (lambda (dir) (next-sample rd))))) (map-channel (lambda (y) (granulate grn))) (let ((mx (maxamp))) (if (> mx .2) (snd-display #__line__ ";trouble in granulate len .4 hop .5: ~A" mx)) (undo))) (close-sound ind)) (let ((ind (new-sound :size 1000))) (let ((gen (make-granulate :jitter 0.0 :hop .004 :length .001 :input (lambda (dir) .1)))) (map-channel (lambda (y) (granulate gen))) (let ((mx (maxamp))) (if (fneq mx 0.06) (snd-display #__line__ ";gran 0 max: ~A" mx))) (if (not (vequal (channel->float-vector 0 30) (float-vector 0.000 0.007 0.013 0.020 0.027 0.033 0.040 0.047 0.053 0.060 0.060 0.060 0.060 0.060 0.060 0.053 0.047 0.040 0.033 0.027 0.020 0.013 0.007 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";gran 0 data: ~A" (channel->float-vector 0 30))) (if (not (vequal (channel->float-vector 85 30) (float-vector 0.000 0.000 0.000 0.000 0.007 0.013 0.020 0.027 0.033 0.040 0.047 0.053 0.060 0.060 0.060 0.060 0.060 0.060 0.053 0.047 0.040 0.033 0.027 0.020 0.013 0.007 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";gran 0 data 85: ~A" (channel->float-vector 85 30))) (undo)) (let ((gen (make-granulate :jitter 0.0 :hop .002 :length .001 :input (lambda (dir) .1)))) (map-channel (lambda (y) (granulate gen))) (let ((mx (maxamp))) (if (fneq mx 0.06) (snd-display #__line__ ";gran 1 max: ~A" mx))) (if (not (vequal (channel->float-vector 0 30) (float-vector 0.000 0.007 0.013 0.020 0.027 0.033 0.040 0.047 0.053 0.060 0.060 0.060 0.060 0.060 0.060 0.053 0.047 0.040 0.033 0.027 0.020 0.013 0.007 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";gran 1 data: ~A" (channel->float-vector 0 30))) (if (not (vequal (channel->float-vector 40 30) (float-vector 0.000 0.000 0.000 0.000 0.000 0.007 0.013 0.020 0.027 0.033 0.040 0.047 0.053 0.060 0.060 0.060 0.060 0.060 0.060 0.053 0.047 0.040 0.033 0.027 0.020 0.013 0.007 0.000 0.000 0.000))) (snd-display #__line__ ";gran 1 data 40: ~A" (channel->float-vector 85 30))) (undo)) (let ((gen (make-granulate :jitter 0.0 :hop .002 :length .001 :ramp .1 :input (lambda (dir) .1)))) (map-channel (lambda (y) (granulate gen))) (let ((mx (maxamp))) (if (fneq mx 0.06) (snd-display #__line__ ";gran 2 max: ~A" mx))) (if (not (vequal (channel->float-vector 0 30) (float-vector 0.000 0.030 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.030 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";gran 2 data: ~A" (channel->float-vector 0 30))) (if (not (vequal (channel->float-vector 40 30) (float-vector 0.000 0.000 0.000 0.000 0.000 0.030 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.030 0.000 0.000 0.000))) (snd-display #__line__ ";gran 2 data 40: ~A" (channel->float-vector 40 30))) (undo)) (let ((gen (make-granulate :jitter 0.0 :hop .002 :length .001 :ramp .5 :input (lambda (dir) .1)))) (map-channel (lambda (y) (granulate gen))) (let ((mx (maxamp))) (if (fneq mx 0.06) (snd-display #__line__ ";gran 3 max: ~A" mx))) (if (not (vequal (channel->float-vector 0 30) (float-vector 0.000 0.005 0.011 0.016 0.022 0.027 0.033 0.038 0.044 0.049 0.055 0.060 0.060 0.055 0.049 0.044 0.038 0.033 0.027 0.022 0.016 0.011 0.005 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";gran 3 data: ~A" (channel->float-vector 0 30))) (if (not (vequal (channel->float-vector 85 30) (float-vector 0.000 0.000 0.000 0.000 0.005 0.011 0.016 0.022 0.027 0.033 0.038 0.044 0.049 0.055 0.060 0.060 0.055 0.049 0.044 0.038 0.033 0.027 0.022 0.016 0.011 0.005 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";gran 3 data 85: ~A" (channel->float-vector 85 30))) (undo)) (let ((gen (make-granulate :jitter 0.0 :hop .001 :length .001 :ramp .5 :input (lambda (dir) .1)))) (map-channel (lambda (y) (granulate gen))) (let ((mx (maxamp))) (if (fneq mx 0.06) (snd-display #__line__ ";gran 4 max: ~A" mx))) (if (not (vequal (channel->float-vector 0 30) (float-vector 0.000 0.005 0.011 0.016 0.022 0.027 0.033 0.038 0.044 0.049 0.055 0.060 0.060 0.055 0.049 0.044 0.038 0.033 0.027 0.022 0.016 0.011 0.005 0.005 0.011 0.016 0.022 0.027 0.033 0.038))) (snd-display #__line__ ";gran 4 data: ~A" (channel->float-vector 0 30))) (if (not (vequal (channel->float-vector 85 30) (float-vector 0.022 0.016 0.011 0.005 0.005 0.011 0.016 0.022 0.027 0.033 0.038 0.044 0.049 0.055 0.060 0.060 0.055 0.049 0.044 0.038 0.033 0.027 0.022 0.016 0.011 0.005 0.005 0.011 0.016 0.022))) (snd-display #__line__ ";gran 4 data 85: ~A" (channel->float-vector 85 30))) (undo)) (let ((gen (make-granulate :jitter 0.0 :hop .001 :length .001 :ramp .25 :scaler 1.0 :input (lambda (dir) .1)))) (map-channel (lambda (y) (granulate gen))) (let ((mx (maxamp))) (if (fneq mx 0.1) (snd-display #__line__ ";gran 5 max: ~A" mx))) (if (not (vequal (channel->float-vector 0 30) (float-vector 0.000 0.020 0.040 0.060 0.080 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.080 0.060 0.040 0.020 0.020 0.040 0.060 0.080 0.100 0.100 0.100))) (snd-display #__line__ ";gran 5 data: ~A" (channel->float-vector 0 30))) (if (not (vequal (channel->float-vector 85 30) (float-vector 0.080 0.060 0.040 0.020 0.020 0.040 0.060 0.080 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.080 0.060 0.040 0.020 0.020 0.040 0.060 0.080))) (snd-display #__line__ ";gran 5 data 85: ~A" (channel->float-vector 85 30))) (undo)) (let ((gen (make-granulate :jitter 0.0 :hop .001 :length .002 :ramp .5 :scaler 1.0 :input (lambda (dir) .1)))) (map-channel (lambda (y) (granulate gen))) (let ((mx (maxamp))) (if (fneq mx 0.105) (snd-display #__line__ ";gran 6 max: ~A" mx))) (if (not (vequal (channel->float-vector 0 30) (float-vector 0.000 0.005 0.009 0.014 0.018 0.023 0.027 0.032 0.036 0.041 0.045 0.050 0.055 0.059 0.064 0.068 0.073 0.077 0.082 0.086 0.091 0.095 0.100 0.105 0.105 0.105 0.105 0.105 0.105 0.105))) (snd-display #__line__ ";gran 6 data: ~A" (channel->float-vector 0 30))) (if (not (vequal (channel->float-vector 85 30) (float-vector 0.105 0.105 0.105 0.105 0.105 0.105 0.105 0.105 0.105 0.105 0.105 0.105 0.105 0.105 0.105 0.105 0.105 0.105 0.105 0.105 0.105 0.105 0.105 0.105 0.105 0.105 0.105 0.105 0.105 0.105))) (snd-display #__line__ ";gran 6 data 85: ~A" (channel->float-vector 85 30))) (undo)) (let ((gen (make-granulate :jitter 0.0 :hop .001 :length .005 :ramp .5 :scaler 1.0 :input (lambda (dir) .1)))) (map-channel (lambda (y) (granulate gen))) (let ((mx (maxamp))) (if (fneq mx 0.264) (snd-display #__line__ ";gran 7 max: ~A" mx))) (if (not (vequal (channel->float-vector 0 30) (float-vector 0.000 0.002 0.004 0.005 0.007 0.009 0.011 0.013 0.015 0.016 0.018 0.020 0.022 0.024 0.025 0.027 0.029 0.031 0.033 0.035 0.036 0.038 0.040 0.044 0.047 0.051 0.055 0.058 0.062 0.065))) (snd-display #__line__ ";gran 7 data: ~A" (channel->float-vector 0 30))) (if (not (vequal (channel->float-vector 85 30) (float-vector 0.244 0.244 0.244 0.244 0.245 0.247 0.249 0.251 0.253 0.255 0.256 0.258 0.260 0.262 0.264 0.264 0.262 0.260 0.258 0.256 0.255 0.253 0.251 0.249 0.247 0.245 0.245 0.247 0.249 0.251))) (snd-display #__line__ ";gran 7 data 85: ~A" (channel->float-vector 85 30))) (undo)) (let ((gen (make-granulate :jitter 0.0 :hop .01 :length .001 :ramp .5 :scaler 1.0 :expansion 2.0 :input (lambda (dir) .1)))) (map-channel (lambda (y) (granulate gen))) (let ((mx (maxamp))) (if (fneq mx 0.1) (snd-display #__line__ ";gran 8 max: ~A" mx))) (if (not (vequal (channel->float-vector 0 30) (float-vector 0.000 0.009 0.018 0.027 0.036 0.045 0.055 0.064 0.073 0.082 0.091 0.100 0.100 0.091 0.082 0.073 0.064 0.055 0.045 0.036 0.027 0.018 0.009 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";gran 8 data: ~A" (channel->float-vector 0 30))) (if (not (vequal (channel->float-vector 220 30) (float-vector 0.000 0.009 0.018 0.027 0.036 0.045 0.055 0.064 0.073 0.082 0.091 0.100 0.100 0.091 0.082 0.073 0.064 0.055 0.045 0.036 0.027 0.018 0.009 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";gran 8 data 220: ~A" (channel->float-vector 220 30))) (undo)) (let ((gen (make-granulate :jitter 0.0 :hop .01 :length .001 :ramp .5 :scaler 1.0 :expansion 0.5 :input (lambda (dir) .1)))) (map-channel (lambda (y) (granulate gen))) (let ((mx (maxamp))) (if (fneq mx 0.1) (snd-display #__line__ ";gran 9 max: ~A" mx))) ; same as 8 because expansion hits the input counter (if (not (vequal (channel->float-vector 0 30) (float-vector 0.000 0.009 0.018 0.027 0.036 0.045 0.055 0.064 0.073 0.082 0.091 0.100 0.100 0.091 0.082 0.073 0.064 0.055 0.045 0.036 0.027 0.018 0.009 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";gran 9 data: ~A" (channel->float-vector 0 30))) (if (not (vequal (channel->float-vector 220 30) (float-vector 0.000 0.009 0.018 0.027 0.036 0.045 0.055 0.064 0.073 0.082 0.091 0.100 0.100 0.091 0.082 0.073 0.064 0.055 0.045 0.036 0.027 0.018 0.009 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";gran 9 data 220: ~A" (channel->float-vector 220 30))) (undo)) (let ((gen (make-granulate :jitter 0.0 :hop .001 :length .005 :ramp .5 :scaler 1.0 :input (lambda (dir) .1) :edit (lambda (g) (float-vector-scale! (mus-data g) 2.0) 0)))) (map-channel (lambda (y) (granulate gen))) (let ((mx (maxamp))) (if (fneq mx (* 2 0.264)) (snd-display #__line__ ";gran 10 max: ~A" mx))) (if (not (vequal (float-vector-scale! (channel->float-vector 0 30) 0.5) (float-vector 0.000 0.002 0.004 0.005 0.007 0.009 0.011 0.013 0.015 0.016 0.018 0.020 0.022 0.024 0.025 0.027 0.029 0.031 0.033 0.035 0.036 0.038 0.040 0.044 0.047 0.051 0.055 0.058 0.062 0.065))) (snd-display #__line__ ";gran 10 data: ~A" (channel->float-vector 0 30))) (if (not (vequal (float-vector-scale! (channel->float-vector 85 30) 0.5) (float-vector 0.244 0.244 0.244 0.244 0.245 0.247 0.249 0.251 0.253 0.255 0.256 0.258 0.260 0.262 0.264 0.264 0.262 0.260 0.258 0.256 0.255 0.253 0.251 0.249 0.247 0.245 0.245 0.247 0.249 0.251))) (snd-display #__line__ ";gran 10 data 85: ~A" (channel->float-vector 85 30))) (undo)) (let ((forward #t) (ctr -0.5) (incr .001)) (let ((f1 (lambda (dir) (set! ctr (+ ctr incr)))) (f2 (lambda (g) (if forward ; no change to data (set! forward #f) (let ((len (mus-length g))) (let ((grain (make-shared-vector (mus-data g) (list len)))) (set! forward #t) (reverse! grain)))) ; should get ramps going up then down across overall rising ramp (mus-length g)))) (let ((gen (make-granulate :jitter 0.0 :hop .005 :length .002 :ramp 0.0 :scaler 1.0 :input f1 :edit f2))) (map-channel (lambda (y) (granulate gen))))) (let ((mx (maxamp))) (if (> mx 0.6) (snd-display #__line__ ";gran 11 max: ~A" mx))) (if (not (vequal (channel->float-vector 0 30) (float-vector -0.499 -0.498 -0.497 -0.496 -0.495 -0.494 -0.493 -0.492 -0.491 -0.490 -0.489 -0.488 -0.487 -0.486 -0.485 -0.484 -0.483 -0.482 -0.481 -0.480 -0.479 -0.478 -0.477 -0.476 -0.475 -0.474 -0.473 -0.472 -0.471 -0.470))) (snd-display #__line__ ";gran 11 data: ~A" (channel->float-vector 0 30))) (if (not (vequal (channel->float-vector 100 30) (float-vector 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 -0.345 -0.346 -0.347 -0.348 -0.349 -0.350 -0.351 -0.352 -0.353 -0.354 -0.355 -0.356 -0.357 -0.358 -0.359 -0.360 -0.361 -0.362 -0.363 -0.364))) (snd-display #__line__ ";gran 11 data 100: ~A" (channel->float-vector 100 30))) (undo)) (let* ((ctr -0.5) (incr .001) (gen (make-granulate :jitter 0.0 :hop .005 :length .002 :ramp 0.0 :scaler 1.0 :input (lambda (dir) (set! ctr (+ ctr incr)))))) (map-channel (lambda (y) (granulate gen))) (let ((mx (maxamp))) (if (> mx 0.6) (snd-display #__line__ ";gran 12 max: ~A" mx))) (if (not (vequal (channel->float-vector 0 30) (float-vector -0.499 -0.498 -0.497 -0.496 -0.495 -0.494 -0.493 -0.492 -0.491 -0.490 -0.489 -0.488 -0.487 -0.486 -0.485 -0.484 -0.483 -0.482 -0.481 -0.480 -0.479 -0.478 -0.477 -0.476 -0.475 -0.474 -0.473 -0.472 -0.471 -0.470))) (snd-display #__line__ ";gran 12 data: ~A" (channel->float-vector 0 30))) (if (not (vequal (channel->float-vector 100 30) (float-vector 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 -0.389 -0.388 -0.387 -0.386 -0.385 -0.384 -0.383 -0.382 -0.381 -0.380 -0.379 -0.378 -0.377 -0.376 -0.375 -0.374 -0.373 -0.372 -0.371 -0.370))) (snd-display #__line__ ";gran 12 data 100: ~A" (channel->float-vector 100 30))) (undo)) (let ((gen (make-granulate :jitter 0.0 :hop .001 :length .005 :ramp .5 :scaler 1.0 :input (lambda (dir) .1) :edit (lambda (g) (float-vector-scale! (mus-data g) 2.0) 0)))) (map-channel (lambda (y) (granulate gen))) (let ((mx (maxamp))) (if (> mx .6) (snd-display #__line__ ";gran 13 max: ~A" mx))) (if (not (vequal (float-vector-scale! (channel->float-vector 0 30) 0.5) (float-vector 0.000 0.002 0.004 0.005 0.007 0.009 0.011 0.013 0.015 0.016 0.018 0.020 0.022 0.024 0.025 0.027 0.029 0.031 0.033 0.035 0.036 0.038 0.040 0.044 0.047 0.051 0.055 0.058 0.062 0.065))) (snd-display #__line__ ";gran 13 data: ~A" (channel->float-vector 0 30))) (if (not (vequal (float-vector-scale! (channel->float-vector 85 30) 0.5) (float-vector 0.244 0.244 0.244 0.244 0.245 0.247 0.249 0.251 0.253 0.255 0.256 0.258 0.260 0.262 0.264 0.264 0.262 0.260 0.258 0.256 0.255 0.253 0.251 0.249 0.247 0.245 0.245 0.247 0.249 0.251))) (snd-display #__line__ ";gran 13 data 85: ~A" (channel->float-vector 85 30))) (undo)) (let* ((forward #t) (ctr -0.5) (incr .001) (gen (make-granulate :jitter 0.0 :hop .005 :length .002 :ramp 0.0 :scaler 1.0 :input (lambda (dir) (set! ctr (+ ctr incr))) :edit (lambda (g) (if forward (set! forward #f) (let ((len (mus-length g))) (let ((grain (make-shared-vector (mus-data g) (list len)))) (set! forward #t) (reverse! grain)))) (mus-length g))))) (map-channel (lambda (y) (granulate gen))) (let ((mx (maxamp))) (if (> mx 0.6) (snd-display #__line__ ";gran 14 max: ~A" mx))) (if (not (vequal (channel->float-vector 0 30) (float-vector -0.499 -0.498 -0.497 -0.496 -0.495 -0.494 -0.493 -0.492 -0.491 -0.490 -0.489 -0.488 -0.487 -0.486 -0.485 -0.484 -0.483 -0.482 -0.481 -0.480 -0.479 -0.478 -0.477 -0.476 -0.475 -0.474 -0.473 -0.472 -0.471 -0.470))) (snd-display #__line__ ";gran 14 data: ~A" (channel->float-vector 0 30))) (if (not (vequal (channel->float-vector 100 30) (float-vector 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 -0.345 -0.346 -0.347 -0.348 -0.349 -0.350 -0.351 -0.352 -0.353 -0.354 -0.355 -0.356 -0.357 -0.358 -0.359 -0.360 -0.361 -0.362 -0.363 -0.364))) (snd-display #__line__ ";gran 14 data 100: ~A" (channel->float-vector 100 30))) (undo)) (let* ((gen (make-granulate :jitter 0.0 :hop .004 :length .001 :ramp 0.0 :input (lambda (dir) .1))) (e (make-env '(0 0 1 .5) :length 1001)) (base-ramp-len (mus-length gen))) (map-channel (lambda (y) (let ((result (granulate gen))) (set! (mus-ramp gen) (round (* base-ramp-len (env e)))) result))) (let ((mx (maxamp))) (if (fneq mx 0.06) (snd-display #__line__ ";granf 0 max: ~A" mx))) (if (> (abs (- (mus-ramp gen) (* .5 (mus-length gen)))) 1) (snd-display #__line__ ";granf 0 ramp: ~A ~A" (mus-ramp gen) (mus-length gen))) (if (not (vequal (channel->float-vector 0 30) (float-vector 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";granf 0 data: ~A" (channel->float-vector 0 30))) (if (not (vequal (channel->float-vector 440 30) (float-vector 0.000 0.012 0.024 0.036 0.048 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.048 0.036 0.024 0.012 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";granf 0 data 440: ~A" (channel->float-vector 440 30))) (if (not (vequal (channel->float-vector 880 30) (float-vector 0.000 0.006 0.012 0.018 0.024 0.030 0.036 0.042 0.048 0.054 0.060 0.060 0.060 0.060 0.054 0.048 0.042 0.036 0.030 0.024 0.018 0.012 0.006 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";granf 0 data 880: ~A" (channel->float-vector 880 30))) (undo)) (let* ((gen (make-granulate :jitter 0.0 :hop .004 :length .001 :ramp 0.0 :input (lambda (dir) .1))) (e (make-env '(0 1 1 .25) :length 1001)) (base-hop-len (mus-hop gen))) (map-channel (lambda (y) (let ((result (granulate gen))) (set! (mus-hop gen) (round (* base-hop-len (env e)))) result))) (let ((mx (maxamp))) (if (fneq mx 0.06) (snd-display #__line__ ";granf 1 max: ~A" mx))) (if (> (abs (- (mus-hop gen) (* .001 *clm-srate*))) 1) (snd-display #__line__ ";granf 1 hop: ~A ~A, ~A ~A" (mus-hop gen) (abs (- (mus-hop gen) (* .001 (srate)))) (srate) *clm-srate*)) (if (not (vequal (channel->float-vector 0 30) (float-vector 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";granf 1 data: ~A" (channel->float-vector 0 30))) (if (not (vequal (channel->float-vector 900 30) (float-vector 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.000 0.000 0.000 0.000 0.000 0.000 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060))) (snd-display #__line__ ";granf 1 data 900: ~A" (channel->float-vector 900 30))) (undo)) (let* ((gen (make-granulate :jitter 0.0 :hop .004 :length .001 :ramp 0.0 :input (lambda (dir) .1))) (e (make-env '(0 1 1 .25) :length 1001)) (base-freq (mus-frequency gen))) (map-channel (lambda (y) (let ((result (granulate gen))) (set! (mus-frequency gen) (* base-freq (env e))) result))) (let ((mx (maxamp))) (if (fneq mx 0.06) (snd-display #__line__ ";granf 2 max: ~A" mx))) (if (> (abs (- (mus-hop gen) (* .001 *clm-srate*))) 1) (snd-display #__line__ ";granf 2 hop: ~A" (mus-hop gen))) (if (not (vequal (channel->float-vector 0 30) (float-vector 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";granf 2 data: ~A" (channel->float-vector 0 30))) (if (not (vequal (channel->float-vector 900 30) (float-vector 0.060 0.060 0.060 0.060 0.060 0.000 0.000 0.000 0.000 0.000 0.000 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060))) (snd-display #__line__ ";granf 2 data 900: ~A" (channel->float-vector 900 30))) (undo)) (let ((gen (make-granulate :jitter 0.0 :hop .002 :length .001 :ramp 0.0 :scaler 1.0 :input (lambda (dir) .1)))) (map-channel (lambda (y) (granulate gen))) (let ((mx (maxamp))) (if (fneq mx 0.1) (snd-display #__line__ ";granf 3 max: ~A" mx))) (if (not (vequal (channel->float-vector 0 30) (float-vector 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";gran 3 data: ~A" (channel->float-vector 0 30))) (undo)) (let ((gen (make-granulate :jitter 0.0 :hop .004 :length .001 :ramp 0.0 :scaler 1.0 :input (lambda (dir) .1))) (e (make-env '(0 1 1 0.0) :length 1001))) (map-channel (lambda (y) (let ((result (granulate gen))) (set! (mus-scaler gen) (env e)) result))) (let ((mx (maxamp))) (if (fneq mx 0.1) (snd-display #__line__ ";granf 4 max: ~A" mx))) (if (not (vequal (channel->float-vector 0 30) (float-vector 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";granf 4 data: ~A" (channel->float-vector 0 30))) (if (not (vequal (channel->float-vector 440 30) (float-vector 0.056 0.056 0.056 0.056 0.056 0.056 0.056 0.056 0.056 0.056 0.056 0.056 0.056 0.056 0.056 0.056 0.056 0.056 0.056 0.056 0.056 0.056 0.056 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";granf 4 data 440: ~A" (channel->float-vector 440 30))) (if (not (vequal (channel->float-vector 900 30) (float-vector 0.012 0.012 0.012 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";granf 4 data 900: ~A" (channel->float-vector 900 30))) (undo)) (let* ((gen (make-granulate :jitter 0.0 :hop .006 :length .001 :ramp 0.0 :max-size 2200 :input (lambda (dir) .1))) (e (make-env '(0 1 1 5) :length 1001)) (base-len (mus-length gen))) (map-channel (lambda (y) (let ((result (granulate gen))) (set! (mus-length gen) (round (* base-len (env e)))) result))) (let ((mx (maxamp))) (if (fneq mx 0.06) (snd-display #__line__ ";granf 5 max: ~A" mx))) (if (> (abs (- (mus-length gen) (* 5 base-len))) 10) (snd-display #__line__ ";granf 5 length: ~A ~A" (mus-length gen) (* 5 base-len))) (if (not (vequal (channel->float-vector 0 30) (float-vector 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";granf 5 data: ~A" (channel->float-vector 0 30))) (if (not (vequal (channel->float-vector 440 30) (float-vector 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";granf 5 data 440: ~A" (channel->float-vector 440 30))) (if (not (vequal (channel->float-vector 800 30) (float-vector 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060))) (snd-display #__line__ ";granf 5 data 800: ~A" (channel->float-vector 800 30))) (undo)) (let* ((gen (make-granulate :jitter 0.0 :hop .006 :length .005 :ramp 0.0 :max-size 2200 :input (lambda (dir) .1))) (e (make-env '(0 1 1 .2) :length 1001)) (base-len (mus-length gen))) (map-channel (lambda (y) (let ((result (granulate gen))) (set! (mus-length gen) (round (* base-len (env e)))) result))) (let ((mx (maxamp))) (if (fneq mx 0.06) (snd-display #__line__ ";granf 6 max: ~A" mx))) (if (> (abs (- (mus-length gen) (* .2 base-len))) 4) (snd-display #__line__ ";granf 6 length: ~A ~A" (mus-length gen) (* .2 base-len))) (if (not (vequal (channel->float-vector 0 30) (float-vector 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060))) (snd-display #__line__ ";granf 6 data: ~A" (channel->float-vector 0 30))) (if (not (vequal (channel->float-vector 820 30) (float-vector 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";granf 6 data 820: ~A" (channel->float-vector 820 30))) (undo)) (let ((max-list (lambda () (let ((pts ()) (samp 0) (lasty 0.0)) (scan-channel (lambda (y) (if (and (< lasty 0.1) (>= y .1)) (set! pts (cons samp pts))) (set! lasty y) (set! samp (+ samp 1)) #f)) (reverse pts))))) (let ((gen (make-granulate :jitter 0.0 :hop .01 :length .001 :ramp .5 :scaler 1.0 :expansion 0.5 :input (lambda (dir) .1)))) (map-channel (lambda (y) (granulate gen))) (let ((vals (max-list))) (if (not (equal? vals (list 11 231 451 671 891))) (snd-display #__line__ ";grn jitter 0 max: ~A" vals))) (undo)) (let ((oldvals #f)) (let ((gen (make-granulate :jitter 0.3 :hop .01 :length .001 :ramp .5 :scaler 1.0 :expansion 0.5 :input (lambda (dir) .1)))) (map-channel (lambda (y) (granulate gen))) ;; (11 232 490 736 982) or whatever (let ((vals (max-list))) (if (equal? vals (list 11 231 451 671 891)) (snd-display #__line__ ";grn jitter 0.3 max: ~A" vals)) (set! oldvals vals)) (undo)) (let ((gen (make-granulate :jitter 0.3 :hop .01 :length .001 :ramp .5 :scaler 1.0 :expansion 0.5 :input (lambda (dir) .1)))) (map-channel (lambda (y) (granulate gen))) (let ((vals (max-list))) (if (equal? vals oldvals) (snd-display #__line__ ";grn jitter 0.3 max: ~A ~A" vals oldvals))) (undo))) (let ((oldvals #f) (seed 0)) (let ((gen (make-granulate :jitter 1.0 :hop .01 :length .001 :ramp .5 :scaler 1.0 :expansion 0.5 :input (lambda (dir) .1)))) (set! seed (mus-location gen)) (map-channel (lambda (y) (granulate gen))) (set! oldvals (max-list)) (undo)) (let ((gen (make-granulate :jitter 1.0 :hop .01 :length .001 :ramp .5 :scaler 1.0 :expansion 0.5 :input (lambda (dir) .1)))) (set! (mus-location gen) seed) (map-channel (lambda (y) (granulate gen))) (let ((vals (max-list))) (if (not (equal? vals oldvals)) (snd-display #__line__ ";grn jitter 1.0 max with seed: ~A ~A" vals oldvals))) (undo)))) (let ((fname (file-name ind))) (close-sound ind) (delete-file fname) (if (and with-motif (view-files-dialog #f)) (begin (set! (view-files-files (view-files-dialog #f)) ()) (if (pair? (view-files-files (view-files-dialog #f))) (snd-display #__line__ ";set vf files list null: ~A" (view-files-files (view-files-dialog #f))))))) ) ;; granulate with jitter=0, small hop (comb filter effect) (let ((ind (new-sound "tmp.snd" 1 22050 mus-ldouble mus-next :size 10000))) (let ((gen (make-granulate :expansion 20.0 :input (lambda (dir) .01) :length .00995 :hop .01 :ramp 0.0 :scaler 1.0 :jitter 0.0))) (clm-channel gen) ; -> .01 max (stable) (if (fneq (maxamp) .01) (snd-display #__line__ ";granulate stable 1: ~A" (maxamp))) (let ((minval (scan-channel (lambda (y) (< y .0099))))) (if minval (snd-display #__line__ ";granulate stable 1 min: ~A" minval))) (undo) (set! gen (make-granulate :expansion 20.0 :input (lambda (dir) .1) :length .00995 :hop .01 :ramp 0.0 :scaler 0.5 :jitter 0.0)) (clm-channel gen) ; -> .05 max (stable) (if (fneq (maxamp) .05) (snd-display #__line__ ";granulate stable 2: ~A" (maxamp))) (let ((minval (scan-channel (lambda (y) (< y .0499))))) (if minval (snd-display #__line__ ";granulate stable 2 min: ~A" minval))) (undo) (set! gen (make-granulate :expansion 10.0 :input (lambda (dir) .05) :length .099975 :hop .1 :ramp 0.0 :scaler 1.0 :jitter 0.0)) (clm-channel gen) ; -> .05 max (stable) (if (fneq (maxamp) .05) (snd-display #__line__ ";granulate stable 3: ~A" (maxamp))) (let ((minval (scan-channel (lambda (y) (< y .0499))))) (if minval (snd-display #__line__ ";granulate stable 3 min: ~A ~A" minval (sample (cadr minval))))) (undo) (let ((ctr -0.0001)) (set! gen (make-granulate :expansion 2.0 :input (lambda (dir) (set! ctr (+ ctr .0001))) :length .01 :hop .1 :ramp 0.0 :scaler 1.0 :jitter 0.0)) (clm-channel gen) (if (fneq (maxamp) .462) (snd-display #__line__ ";granulate ramped 4: ~A" (maxamp))) (let ((vals (count-matches (lambda (y) (> (abs y) 0.0))))) (if (> (abs (- vals 1104)) 10) (snd-display #__line__ ";granulate ramped 4 not 0.0: ~A" vals))) (if (or (not (vequal (channel->float-vector 2203 10) (float-vector 0.000 0.000 0.110 0.110 0.110 0.111 0.111 0.111 0.111 0.111))) (not (vequal (channel->float-vector 4523 10) (float-vector 0.232 0.232 0.232 0.232 0.232 0.232 0.232 0.232 0.233 0.233))) (not (vequal (channel->float-vector 8928 10) (float-vector 0.452 0.452 0.452 0.452 0.452 0.452 0.452 0.452 0.452 0.452)))) (snd-display #__line__ ";granulate ramped 4 data off: ~A ~A ~A" (channel->float-vector 2203 10) (channel->float-vector 4523 10) (channel->float-vector 8928 10))) (undo) (let ((e (make-env '(0 0 1 1) :length 10000))) (set! gen (make-granulate :expansion 2.0 :input (lambda (dir) (env e)) :length .00995 :hop .01 :ramp 0.0 :scaler 1.0 :jitter 0.0))) (clm-channel gen) (if (fneq (maxamp) .505) (snd-display #__line__ ";granulate ramped 5: ~A" (maxamp))) (let* ((mxoff 0.0) (mx (maxamp)) (len (framples)) (cur 0.0) (incr (/ mx len))) (scan-channel (lambda (y) (let ((diff (abs (- cur y)))) (if (> diff mxoff) (set! mxoff diff)) (set! cur (+ cur incr)) #f))) (if (> mxoff .02) (snd-display #__line__ ";granulate ramped 5 mxoff: ~A" mxoff))) ; .0108 actually (undo) (let ((e (make-env '(0 0 1 1) :length 10000))) (set! gen (make-granulate :expansion 2.0 :input (lambda (dir) (env e)) :length .00995 :hop .01 :ramp 0.5 :scaler 1.0 :jitter 0.0))) (clm-channel gen) (if (fneq (maxamp) .495) (snd-display #__line__ ";granulate ramped 6: ~A" (maxamp))) (if (or (not (vequal (channel->float-vector 2000 10) (float-vector 0.018 0.019 0.020 0.021 0.022 0.023 0.024 0.025 0.026 0.027))) (not (vequal (channel->float-vector 8000 10) (float-vector 0.294 0.298 0.301 0.305 0.309 0.313 0.316 0.320 0.324 0.328)))) (snd-display #__line__ ";granulate ramped 6 data: ~A ~A" (channel->float-vector 2000 10) (channel->float-vector 8000 10))) (undo) (let ((e (make-env '(0 0 1 1) :length 10000))) (set! gen (make-granulate :expansion 2.0 :input (lambda (dir) (env e)) :length .00995 :hop .01 :ramp 0.25 :scaler 1.0 :jitter 0.0))) (clm-channel gen) (if (fneq (maxamp) .505) (snd-display #__line__ ";granulate ramped 7: ~A" (maxamp))) (if (or (not (vequal (channel->float-vector 2000 10) (float-vector 0.037 0.039 0.040 0.042 0.044 0.046 0.048 0.050 0.052 0.054))) (not (vequal (channel->float-vector 8000 10) (float-vector 0.404 0.404 0.404 0.404 0.404 0.405 0.405 0.405 0.405 0.405)))) (snd-display #__line__ ";granulate ramped 7 data: ~A ~A" (channel->float-vector 2000 10) (channel->float-vector 8000 10))) (undo) (let ((e (make-env '(0 0 1 1) :length 10000))) (set! gen (make-granulate :expansion 2.0 :input (lambda (dir) (env e)) :length .05 :hop .01 :ramp 0.25 :scaler 0.1 :jitter 0.0))) (clm-channel gen) (if (fneq (maxamp) .201) (snd-display #__line__ ";granulate ramped 7: ~A" (maxamp))) (let* ((mxoff 0.0) (mx (maxamp)) (len (framples)) (cur 0.0) (incr (/ mx len))) (scan-channel (lambda (y) (let ((diff (abs (- cur y)))) (if (> diff mxoff) (set! mxoff diff)) (set! cur (+ cur incr)) #f))) (if (> mxoff .01) (snd-display #__line__ ";granulate ramped 7 mxoff: ~A" mxoff))) ; .0097 actually (undo) (let ((e (make-env '(0 0 1 1) :length 10000))) (set! gen (make-granulate :expansion 2.0 :input (lambda (dir) (env e)) :length .1 :hop .01 :ramp 0.1 :scaler 0.1 :jitter 0.0))) (clm-channel gen) (if (fneq (maxamp) .501) (snd-display #__line__ ";granulate ramped 8: ~A" (maxamp))) (let* ((mxoff 0.0) (mx (maxamp)) (len (- (framples) 2000)) (cur (sample 2000)) (incr (/ (- mx cur) len))) (scan-channel (lambda (y) (let ((diff (abs (- cur y)))) (if (> diff mxoff) (set! mxoff diff)) (set! cur (+ cur incr)) #f)) 2000) (if (> mxoff .001) (snd-display #__line__ ";granulate ramped 8 mxoff: ~A" mxoff))) (undo) (let ((e (make-env '(0 0 1 1) :length 10000))) (set! gen (make-granulate :expansion 2.0 :input (lambda (dir) (env e)) :length .4 :hop .01 :ramp 0.4 :scaler 0.025 :jitter 0.0))) (clm-channel gen) (if (fneq (maxamp) .433) (snd-display #__line__ ";granulate ramped 9: ~A" (maxamp))) (undo) (close-sound ind)))) (let ((v0 (make-float-vector 32)) (v1 (make-float-vector 256)) (v2 (make-float-vector 256)) (v01 (make-float-vector 32)) (v11 (make-float-vector 256)) (v21 (make-float-vector 256))) (do ((i 1 (+ i 1))) ((= i 16)) (set! (v0 i) (/ 1.0 i)) (set! (v01 i) (/ 1.0 i))) (set! (v1 0) 1.0) (set! (v11 0) 1.0) (let ((n -1) (n1 -1)) (let ((gen (make-convolve :filter v0 :input (lambda (dir) (set! n (+ n 1)) (v1 n)))) (gen1 (make-convolve :filter v01 :input (lambda (dir) (set! n1 (+ n1 1)) (v11 n1))))) (print-and-check gen "convolve" "convolve size: 64") (if (not (convolve? gen)) (snd-display #__line__ ";~A not convolve?" gen)) (let ((genx gen1)) (if (not (equal? genx gen1)) (snd-display #__line__ ";convolve equal?: ~A ~A ~A" genx gen1 (equal? genx gen1)))) (if (equal? gen gen1) (snd-display #__line__ ";convolve equal? ~A ~A" gen gen1)) (if (not (= (mus-length gen) 64)) (snd-display #__line__ ";convolve fft len: ~D?" (mus-length gen))) (do ((i 0 (+ i 1))) ((= i 128)) (set! (v2 i) (convolve gen))) (fill-float-vector v21 (if (convolve? gen1) (convolve gen1) -1.0)) (if (not (vequal v2 v21)) (snd-display #__line__ ";run gran: ~A ~A" v2 v21)) (if (or (fneq (v2 0) 0.0) (fneq (v2 1) 1.0) (fneq (v2 4) 0.25) (fneq (v2 7) 0.143)) (snd-display #__line__ ";convolve output: ~A?" v2))) (convolve-files "oboe.snd" "fyow.snd" .5 "fmv.snd") (if (fneq (cadr (mus-sound-maxamp "fmv.snd")) .5) (snd-display #__line__ ";convolve-files: ~A is not .5?" (cadr (mus-sound-maxamp "fmv.snd")))) )) (let ((flt (float-vector 1.0 0.5 0.1 0.2 0.3 0.4 0.5 1.0)) (data (float-vector 0.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0)) (ctr -1)) (let ((res (make-float-vector 16)) (g (make-convolve :filter flt :input (lambda (dir) (set! ctr (+ ctr 1)) (data ctr))))) (do ((i 0 (+ i 1))) ((= i 16)) (set! (res i) (convolve g))) (if (not (vequal res (float-vector 0.0 1.0 0.5 0.1 1.2 0.8 0.5 0.7 1.3 0.4 0.5 1.0 0.0 0.0 0.0 0.0))) (snd-display #__line__ ";convolve: ~A~%" res)))) (let ((ind (new-sound "fmv.snd"))) (set! (sample 1) .1) (save-sound ind) (if (not (equal? (edits ind 0) (list 0 0))) (snd-display #__line__ ";weird: edits not cleared after save-sound?: ~A" (edits ind 0))) (close-sound ind) (set! ind (open-sound "fmv.snd")) (if (not (= (framples ind 0) 2)) (snd-display #__line__ ";save-sound 2 samps: ~A?" (framples ind 0))) (if (or (fneq (sample 0) 0.0) (fneq (sample 1) 0.1)) (snd-display #__line__ ";save-sound: ~A ~A?" (sample 0) (sample 1))) (do ((i 3 (+ i 1))) ((= i 6)) (set! (sample i) (* i .1)) (save-sound ind) (if (not (equal? (edits ind 0) (list 0 0))) (snd-display #__line__ ";weird: edits not cleared after save-sound ~A?: ~A" i (edits ind 0))) (close-sound ind) (set! ind (open-sound "fmv.snd")) (if (not (= (framples ind 0) (+ i 1))) (snd-display #__line__ ";save-sound ~A samps: ~A?" (+ i 1) (framples ind 0))) (if (or (fneq (sample 0) 0.0) (fneq (sample 1) 0.1) (fneq (sample i) (* i 0.1))) (snd-display #__line__ ";save-sound ~A: ~A ~A ~A?" i (sample 0) (sample 1) (sample i)))) (close-sound ind)) (let ((ind (new-sound "test.snd" :srate 22050 :channels 1 :size 1000)) (gen (make-ssb-am 100.0))) (map-channel (lambda (y) (ssb-am gen))) (if (fneq (maxamp) 0.0) (snd-display #__line__ ";ssb-am 0.0: ~A" (maxamp))) (let ((gen1 (make-oscil 220.0))) (map-channel (lambda (y) (* 0.5 (oscil gen1)))) (set! gen (make-ssb-am 100.0 100)) (map-channel (lambda (y) (ssb-am gen y))) (delete-samples 0 200) (set! gen1 (make-oscil 320.0 :initial-phase (asin (* 2 (sample 0))))) ; depends on rising side (map-channel (lambda (y) (- y (* 0.5 (oscil gen1))))) (if (> (maxamp) .004) (snd-display #__line__ ";ssb-am cancelled: ~A" (maxamp))) (undo 3) (set! gen (make-ssb-am 100.0 100)) (let ((hx (hz->radians 50.0))) (map-channel (lambda (y) (ssb-am gen y hx)))) (delete-samples 0 180) (set! gen1 (make-oscil 370.0 :initial-phase (asin (* 2 (sample 0))))) ; depends on rising side (map-channel (lambda (y) (- y (* 0.5 (oscil gen1))))) (if (> (maxamp) .004) (snd-display #__line__ ";ssb-am fm cancelled: ~A" (maxamp))) (close-sound ind))) (let* ((ind (new-sound "test.snd" :srate 22050 :channels 1 :size 1000)) (scl (/ (* 2 pi) 50)) (x (- scl))) (map-channel (lambda (y) (sin (set! x (+ x scl))))) ;; 441 Hz (ssb-bank 441 882 1 100) (delete-samples 0 217) (let ((gen1 (make-oscil 882.0 :initial-phase (asin (sample 0))))) (map-channel (lambda (y) (- y (oscil gen1)))) (if (> (maxamp) .04) (snd-display #__line__ ";ssb-bank cancelled: ~A" (maxamp)))) (close-sound ind)) (if *output* (begin (snd-display #__line__ ";*output* ~A" *output*) (set! *output* #f))) (let ((nind (new-sound "fmv.snd" 1 22050 mus-bshort mus-aifc "this is a comment"))) (time (mix-float-vector (with-temp-sound (:output (make-float-vector 22050)) (fm-violin 0 1 440 .1)) 0 nind 0)) (play nind :wait #t) (save-sound nind) (if (not (sound? nind)) (snd-display #__line__ ";save sound clobbered ~A?" nind)) (let ((oboe-index (or (find-sound "oboe.snd") (open-sound "oboe.snd")))) (if (equal? oboe-index nind) (snd-display #__line__ ";find-sound found bogus case: ~A" oboe-index)) (cnvtest oboe-index nind .1) (select-sound nind) (select-channel 0) (if (not (equal? (selected-sound) nind)) (snd-display #__line__ ";selected-sound: ~A?" (selected-sound))) (if (not (= (selected-channel) 0)) (snd-display #__line__ ";selected-channel: ~A?" (selected-channel))) (snd-test-jc-reverb 1.0 #f .1 #f) (play nind :wait #t) (voiced->unvoiced 1.0 256 2.0 2.0) (pulse-voice 80 20.0 1.0 1024 0.01) (map-channel (fltit)) (close-sound oboe-index)) (if (not (sound? nind)) (snd-display #__line__ ";close sound clobbered ~A?" nind)) (let ((fr (framples nind 0))) (do ((k 0 (+ k 1))) ((= k 10)) (delete-samples 10 100 nind 0) (save-sound nind)) ;flush out memory leaks here (if (not (= (framples nind 0) (- fr 1000))) (snd-display #__line__ ";delete-samples: ~A ~A" fr (framples nind 0)))) (revert-sound nind) (close-sound nind)) (if (file-exists? "fmv.snd") (delete-file "fmv.snd")) (let ((nind (new-sound "fmv.snd"))) (if (not (= (header-type nind) *default-output-header-type*)) (snd-display #__line__ ";new-sound default header-type: ~A ~A?" (mus-header-type-name (header-type nind)) (mus-header-type-name *default-output-header-type*))) (if (not (= (sample-type nind) *default-output-sample-type*)) (snd-display #__line__ ";new-sound default sample-type: ~A ~A?" (mus-sample-type-name (sample-type nind)) (mus-sample-type-name *default-output-sample-type*))) (if (not (= (chans nind) *default-output-chans*)) (snd-display #__line__ ";new-sound default chans: ~A ~A?" (chans nind) *default-output-chans*)) (if (not (= (srate nind) *default-output-srate*)) (snd-display #__line__ ";new-sound default srate: ~A ~A?" (srate nind) *default-output-srate*)) (close-sound nind) (if (file-exists? "fmv.snd") (delete-file "fmv.snd"))) (let ((nind (new-sound "fmv.snd" 1 22050 mus-bshort mus-nist "this is a comment"))) (set! (sample 0 nind) 1.0) (start-progress-report nind) (convolve-with "oboe.snd") (progress-report .1 nind) (if (fneq (sample 1000) 0.223) (snd-display #__line__ ";convolve-with: ~A?" (sample 1000))) (progress-report .3 nind) (revert-sound nind) (progress-report .5 nind) (set! (sample 200) .0001) (set! (sample 100) 1.0) (progress-report .8 nind) (smooth-sound 0 100) (finish-progress-report nind) (if (or (fneq (sample 50) .5) (fneq (sample 30) 0.20608) (fneq (sample 90) 0.9755)) (snd-display #__line__ ";smooth: ~A ~A ~A?" (sample 50) (sample 30) (sample 90))) (undo) (let ((old-wid *sinc-width*)) (set! *sinc-width* 40) (set! (sample 100) 0.5) (if (fneq (sample 100) 0.5) (snd-display #__line__ ";set-sample 100: ~A?" (sample 100))) (src-sound .1) (set! *sinc-width* old-wid)) (if (or (fneq (sample 1000) 0.5) (fneq (sample 1024) 0.0625) (fneq (sample 1010) 0.0)) (snd-display #__line__ ";src-sound: ~A ~A ~A?" (sample 1000) (sample 1024) (sample 1010))) (revert-sound) (close-sound nind)) (let ((nind (new-sound "fmv.snd" 1 22050 mus-lshort mus-riff "this is a comment" 22050))) (if (not (= (framples nind) 22050)) (snd-display #__line__ "; new-sound initial-length: ~A" (framples nind))) (mix "pistol.snd") (map-channel (expsrc 2.0 nind)) (undo) (let ((eds (edits))) (if (not (= (car eds) 1 (cadr eds))) (snd-display #__line__ ";undo edits: ~A?" eds)) (if (not (= (edit-position) (car eds))) (snd-display #__line__ ";undo edit-position: ~A ~A?" (edit-position) eds))) (expsnd '(0 1 2 .4)) (map-channel (comb-chord .95 100 .3)) (map-channel (formants .99 900 .02 1800 .01 2700)) (map-channel (moving-formant .99 '(0 1200 1 2400))) (scale-to .3) (let ((eds (edits))) (if (or (not (= (car eds) 6)) (not (= (cadr eds) 0))) (snd-display #__line__ ";edits(6): ~A?" eds)) (if (not (= (edit-position) (car eds))) (snd-display #__line__ ";edit-position(6): ~A ~A?" (edit-position) eds))) (set! (edit-position) 1) (if (not (= (edit-position) 1)) (snd-display #__line__ ";set edit-position(1) ~A?" (edit-position))) (set! (edit-position) 4) (if (not (= (edit-position) 4)) (snd-display #__line__ ";set edit-position(4): ~A?" (edit-position))) (revert-sound nind) (mix "pistol.snd") (map-channel (zecho .5 .75 6 10.0) 0 65000) (map-channel (am 440)) (add-mark 1200) (add-mark 2300) (key (char->integer #\x) 4) (key (char->integer #\c) 0) ; trigger mark-define-region (reverse-sound nind) (revert-sound nind) (let ((mid (mix-sound "pistol.snd" 0))) (if (and (mix? mid) (not (equal? (mix-home mid) (list (selected-sound) 0 #f 0)))) (snd-display #__line__ ";mix-sound mix-home: ~A" (mix-home mid)))) (hello-dentist 40.0 .1) (fp 1.0 .3 20) (revert-sound nind) (enveloped-mix "oboe.snd" 0 '(0 0 1 1 2 0)) (if all-args (pvoc :pitch 0.5 :time 1.0 :snd nind)) (revert-sound nind) (close-sound nind)) (if (and all-args (defined? 'edot-product)) (let ((ind (new-sound :size 100)) (len 100)) (set! (sample 10) 0.5) (set! (sample 30) -0.8) (stretch-sound-via-dft 2.0 ind 0) (let ((new-len (framples ind 0))) (if (> (abs (- (* 2 len) new-len)) 10) (snd-display #__line__ ";stretch-sound-via-dft: ~A ~A" len new-len))) (close-sound ind))) (let ((make-mix-output (lambda (name i) (if (or (= i 0) (= i 1)) name (continue-sample->file name)))) (make-mix-input (lambda (name i) (if (or (= i 0) (= i 2)) name (make-file->frample name))))) (define (mus-file-mix-1 outf . args) (apply mus-file-mix outf args) (if (not (string? outf)) (mus-close outf))) (do ((k 0 (+ k 1))) ((= k 4)) (if (file-exists? "fmv.snd") (delete-file "fmv.snd")) (if (file-exists? "fmv1.snd") (delete-file "fmv1.snd")) (if (file-exists? "fmv2.snd") (delete-file "fmv2.snd")) (if (file-exists? "fmv3.snd") (delete-file "fmv3.snd")) (let ((v0 (make-float-vector 12))) (fill! v0 0.1) (array->file "fmv1.snd" v0 12 22050 1) (fill! v0 0.2) (array->file "fmv2.snd" v0 12 22050 2) (fill! v0 0.3) (array->file "fmv3.snd" v0 12 22050 4) (do ((i 0 (+ i 1))) ((= i 12)) (set! (v0 i) (* i .01))) (array->file "fmv.snd" v0 12 22050 1) (mus-file-mix-1 (make-mix-output "fmv.snd" k) (make-mix-input "fmv1.snd" k)) (file->array "fmv.snd" 0 0 12 v0) ;; v0: #(0.1 0.11 0.12 0.13 0.14 0.15 0.16 0.17 0.18 0.19 0.2 0.21) (let ((happy #t)) (do ((i 0 (+ i 1))) ((or (not happy) (= i 12))) (if (fneq (v0 i) (+ 0.1 (* i .01))) (begin (snd-display #__line__ ";~D mus-file-mix(1->1): ~A?" k v0) (set! happy #f))))) (mus-file-mix-1 (make-mix-output "fmv.snd" k) (make-mix-input "fmv2.snd" k) 3 9 0 (float-vector 0.3 0.0 0.7 0.0)) (file->array "fmv.snd" 0 0 12 v0) ;; v0: #(0.1 0.11 0.12 0.33 0.34 0.35 0.36 0.37 0.38 0.19 0.2 0.21) (if (or (fneq (v0 0) .1) (fneq (v0 3) .33) (fneq (v0 9) .19)) (snd-display #__line__ ";~D mus-file-mix(2->1): ~A?" k v0)) (mus-file-mix-1 (make-mix-output "fmv.snd" k) (make-mix-input "fmv3.snd" k)) (file->array "fmv.snd" 0 0 12 v0) ;; ?? v0: #(0.4 0.41 0.42 0.33 0.34 0.35 0.36 0.37 0.38 0.19 0.2 0.21) (if (or (fneq (v0 0) .4) (fneq (v0 3) .33)) (snd-display #__line__ ";~D mus-file-mix(4->1): ~A?" k v0)) (let ((e0 (make-env '(0 0 1 1) :length 11)) (vf (make-vector 1)) (vf1 (make-vector 1))) (set! (vf 0) vf1) (set! (vf1 0) e0) (mus-file-mix-1 (make-mix-output "fmv.snd" k) (make-mix-input "fmv1.snd" k) 0 12 0 (float-vector 1.0) vf) (file->array "fmv.snd" 0 0 12 v0) ;; ?? v0: #(0.4 0.42 0.4400000000000001 0.36 0.38 0.4 0.42 0.44 0.46 0.28 0.3 0.31) (if (or (fneq (v0 0) .4) (fneq (v0 3) .360) (fneq (v0 9) .28)) (snd-display #__line__ ";~D mus-file-mix(env): ~A?" k v0)) (mus-file-mix-1 (make-mix-output "fmv.snd" k) (make-mix-input "fmv2.snd" k) 0 12 0 (float-vector 1.0 1.0 1.0 1.0) vf)) ;; clm2xen should protect us here (let ((vf (make-vector 2)) (vf1 (make-vector 2)) (vf2 (make-vector 2))) (set! (vf 0) vf1) (set! (vf 1) vf2) (set! (vf1 0) (make-env '(0 0 1 1) :length 10)) (set! (vf2 1) (make-env '(0 0 1 1) :length 10)) (mus-file-mix-1 (make-mix-output "fmv.snd" k) (make-mix-input "fmv2.snd" k) 0 12 0 (float-vector 1.0 1.0 1.0 1.0) vf) (let ((tag (catch #t (lambda () (set! (vf 0) (make-oscil)) (mus-file-mix-1 (make-mix-output "fmv.snd" k) (make-mix-input "fmv2.snd" k) 0 12 0 (float-vector 1.0 1.0 1.0 1.0) vf)) (lambda args (car args))))) (if (not (eq? tag 'bad-type)) (snd-display #__line__ ";~D mix w oscil-vect: ~A" k tag))) (set! (vf 0) vf1) (set! (vf 1) vf2) (let ((tag (catch #t (lambda () (set! (vf1 0) (make-oscil)) (set! (vf2 1) 0+i) (mus-file-mix-1 (make-mix-output "fmv.snd" k) (make-mix-input "fmv2.snd" k) 0 12 0 (float-vector 1.0 1.0 1.0 1.0) vf)) (lambda args (car args))))) (if (not (eq? tag 'bad-type)) (snd-display #__line__ ";~D mix w oscil-env: ~A" k tag)))) (delete-file "fmv.snd") (do ((i 0 (+ i 1))) ((= i 12)) (set! (v0 i) (* i .01))) (array->file "fmv.snd" v0 12 22050 4) (mus-file-mix-1 (make-mix-output "fmv.snd" k) (make-mix-input "fmv1.snd" k)) (file->array "fmv.snd" 0 0 3 v0) ; chan 0 start 0 len 3 ;; v0: #(0.1 0.14 0.18 0.03 0.04 0.05 0.06 0.07000000000000001 0.08 0.09 0.1 0.11) (if (or (fneq (v0 0) .1) (fneq (v0 2) .18)) (snd-display #__line__ ";~D mus-file-mix(1->4): ~A?" k v0)) (mus-file-mix-1 (make-mix-output "fmv.snd" k) (make-mix-input "fmv2.snd" k) 0 3 0 (float-vector 0.3 0.0 0.7 0.0)) (file->array "fmv.snd" 0 0 3 v0) ;; v0: #(0.3 0.34 0.38 0.03 0.04 0.05 0.06 0.07000000000000001 0.08 0.09 0.1 0.11) (if (or (fneq (v0 0) .3) (fneq (v0 2) .38)) (snd-display #__line__ ";~D mus-file-mix(2->4): ~A?" k v0)) (mus-file-mix-1 (make-mix-output "fmv.snd" k) (make-mix-input "fmv3.snd" k) 0 2 0) (file->array "fmv.snd" 0 0 3 v0) ;; v0: #(0.6000000000000001 0.6400000000000001 0.38 0.03 0.04 0.05 0.06 0.07000000000000001 0.08 0.09 0.1 0.11) (if (or (fneq (v0 0) .6) (fneq (v0 2) .38)) (snd-display #__line__ ";~D mus-file-mix(4->4): ~A?" k v0))) (if (file-exists? "fmv.snd") (delete-file "fmv.snd")) (let ((v0 (make-float-vector 12)) (len (mus-sound-framples "oboe.snd"))) (array->file "fmv.snd" v0 12 22050 1) (mus-file-mix-1 (make-mix-output "fmv.snd" k) (make-mix-input "oboe.snd" k)) (mus-file-mix-1 (make-mix-output "fmv.snd" k) (make-mix-input "oboe.snd" k) 0 len 0 (float-vector 0.5)) (let ((egen (make-vector 1)) (outv (make-vector 1))) (set! (outv 0) egen) (set! (egen 0) (make-env :envelope '(0 0 1 1) :length len)) (mus-file-mix-1 (make-mix-output "fmv.snd" k) (make-mix-input "oboe.snd" k) 0 len 0 #f outv) (set! (egen 0) (make-env :envelope '(0 1 1 0) :length len)) (mus-file-mix-1 (make-mix-output "fmv.snd" k) (make-mix-input "oboe.snd" k) 0 len 0 (float-vector 1.0) outv)) (let ((ind-oboe (open-sound "oboe.snd")) (ind-mix (open-sound "fmv.snd"))) (if (not (vequal (channel->float-vector 1000 10 ind-oboe) (float-vector-scale! (channel->float-vector 1000 10 ind-mix) (/ 1.0 2.5)))) (snd-display #__line__ ";~D mus-file-mix 1 chan: ~A ~A" k (channel->float-vector 1000 10 ind-oboe) (channel->float-vector 1000 10 ind-mix))) (close-sound ind-oboe) (close-sound ind-mix)) (delete-file "fmv.snd") (let ((v0 (make-float-vector 12)) (len (mus-sound-framples "2.snd"))) (array->file "fmv.snd" v0 12 22050 2) (if (not (= (mus-sound-chans "fmv.snd") 2)) (snd-display #__line__ ";~D array->file chans? ~A" k (mus-sound-chans "fmv.snd"))) (mus-file-mix-1 (make-mix-output "fmv.snd" k) (make-mix-input "2.snd" k)) (mus-file-mix-1 (make-mix-output "fmv.snd" k) (make-mix-input "2.snd" k) 0 len 0 (float-vector 0.5 0.0 0.0 0.5)) (let ((egen0 (make-vector 2)) (egen1 (make-vector 2)) (outv (make-vector 2))) (set! (outv 0) egen0) (set! (outv 1) egen1) (set! (egen0 0) (make-env :envelope '(0 0 1 1) :length len)) (set! (egen1 1) (make-env :envelope '(0 0 1 1) :length len)) (mus-file-mix-1 (make-mix-output "fmv.snd" k) (make-mix-input "2.snd" k) 0 len 0 #f outv)) (let ((ind-mix (open-sound "fmv.snd"))) (if (not (= (channels ind-mix) 2)) (snd-display #__line__ ";~D fmv re-read chans? ~A ~A" k (mus-sound-chans "fmv.snd") (channels ind-mix))) (if (not (vequal (channel->float-vector 1000 10 ind-mix 0) (float-vector 0.003 0.010 0.012 0.011 0.008 0.004 0.002 0.002 0.007 0.017))) (snd-display #__line__ ";~D mus-file-mix 2 chan (2.snd written: ~A): ~A ~A" k (strftime "%d-%b %H:%M %Z" (localtime (mus-sound-write-date "2.snd"))) (channel->float-vector 1000 10 ind-mix 0) (channel->float-vector 1000 10 ind-mix 1))) (close-sound ind-mix) (delete-file "fmv.snd")))) ); end do loop ); end let (let () ;; someday this should be expanded (if (pair? (sounds)) (for-each close-sound (sounds))) (catch #t (lambda () (mus-file-mix-with-envs rd 0 1000 (float-vector))) (lambda args 'error)) (with-sound ("flat.snd") (do ((i 0 (+ i 1))) ((= i 1000)) (outa i 1.0))) (with-sound ("mix.snd") (let ((rd (vector (make-readin "flat.snd")))) (mus-file-mix-with-envs rd 0 1000 (float-vector 0.5) #f #f #f #f))) (let ((ind (find-sound "mix.snd"))) (if (sound? ind) (if (fneq (sample 100 ind) 0.5) (snd-display #__line__ ";mus-file-mix-with-envs 1: ~A" (sample 100 ind))) (snd-display #__line__ ";mus-file-mix-with envs 1: no output? ~A" (map short-file-name (sounds))))) (with-sound ("mix.snd") (let ((rd (vector (make-readin "flat.snd"))) (es (vector (make-env '(0 0 1 1) :length 1000)))) (mus-file-mix-with-envs rd 0 1000 (float-vector 0.0) #f es #f #f))) (let ((ind (find-sound "mix.snd"))) (if (sound? ind) (if (fneq (sample 100 ind) 0.1) (snd-display #__line__ ";mus-file-mix-with-envs 2: ~A" (sample 100 ind))) (snd-display #__line__ ";mus-file-mix-with envs 2: no output? ~A" (map short-file-name (sounds))))) (with-sound ("mix.snd" 2 :clipped #f) (let ((rd (vector (make-readin "flat.snd") (make-readin "flat.snd"))) (es (vector (make-env '(0 0 1 1) :length 1000 :scaler .1) (make-env '(0 1 1 0) :length 1000 :scaler .1) (make-env '(0 1 1 1) :length 1000 :scaler .5) (make-env '(0 1 1 1) :length 1000 :scaler -.5)))) (mus-file-mix-with-envs rd 0 1000 (float-vector 0.0 0.0 0.0 0.0) #f es #f #f))) (let ((ind (find-sound "mix.snd"))) (if (sound? ind) (begin (if (fneq (sample 100 ind 0) 0.51) (snd-display #__line__ ";mus-file-mix-with-envs 3 chan 0: ~A" (sample 100 ind 0))) (if (fneq (sample 100 ind 1) -0.41) (snd-display #__line__ ";mus-file-mix-with-envs 3 chan 1: ~A" (sample 100 ind 1)))) (snd-display #__line__ ";mus-file-mix-with envs 3: no output? ~A" (map short-file-name (sounds))))) (with-sound ("mix.snd" 2 :clipped #f) (let ((rd (vector (make-readin "flat.snd"))) (es (vector (make-env '(0 0 1 1) :length 1000 :scaler .3) (make-env '(0 1 1 0) :length 1000 :scaler .4)))) (mus-file-mix-with-envs rd 0 1000 (float-vector 0.0 0.0 0.0 0.0) #f es #f #f))) (let ((ind (find-sound "mix.snd"))) (if (sound? ind) (begin (if (fneq (sample 100 ind 0) 0.03) (snd-display #__line__ ";mus-file-mix-with-envs 4 chan 0: ~A" (sample 100 ind 0))) (if (fneq (sample 100 ind 1) 0.36) (snd-display #__line__ ";mus-file-mix-with-envs 4 chan 1: ~A" (sample 100 ind 1)))) (snd-display #__line__ ";mus-file-mix-with envs 4: no output? ~A" (map short-file-name (sounds))))) (with-sound ("mix.snd" 1 :clipped #f) (let ((rd (vector (make-readin "flat.snd") (make-readin "flat.snd"))) (es (vector (make-env '(0 0 1 1) :length 1000 :scaler .3) (make-env '(0 1 1 0) :length 1000 :scaler .4)))) (mus-file-mix-with-envs rd 0 1000 (float-vector 0.0 0.0 0.0 0.0) #f es #f #f))) (let ((ind (find-sound "mix.snd"))) (if (sound? ind) (if (fneq (sample 100 ind) 0.39) (snd-display #__line__ ";mus-file-mix-with-envs 5: ~A" (sample 100 ind))) (snd-display #__line__ ";mus-file-mix-with envs 5: no output? ~A" (map short-file-name (sounds))))) (with-sound ("flat.snd") (outa 99 0.5) (outa 100 1.0) (outa 101 0.5)) (require snd-jcrev.scm) (with-sound ("mix.snd" :reverb jc-reverb) (let ((rd (vector (make-readin "flat.snd")))) (mus-file-mix-with-envs rd 0 1000 (float-vector 0.5) (float-vector 0.1) #f #f #f))) (with-sound ("mix.snd" :reverb jc-reverb) (let* ((rd (vector (make-readin "flat.snd") (make-readin "flat.snd"))) (srcs (vector (make-src :input (vector-ref rd 0) :srate 2.0) (make-src :input (vector-ref rd 1) :srate 0.5)))) (mus-file-mix-with-envs rd 0 1000 (float-vector 1.0 1.0 0.5 0.5) (float-vector 0.1) #f srcs #f))) (let ((ind (find-sound "mix.snd"))) (if (sound? ind) (if (fneq (sample 200 ind) 0.5) (snd-display #__line__ ";mus-file-mix-with-envs 7: ~A" (sample 200 ind))) (snd-display #__line__ ";mus-file-mix-with envs 7: no output? ~A" (map short-file-name (sounds))))) (for-each close-sound (sounds)) (delete-file "flat.snd") (delete-file "mix.snd") ) (let* ((gen (make-phase-vocoder #f 512 4 256 1.0 #f #f #f)) (val (catch #t (lambda () (phase-vocoder gen)) (lambda args (car args))))) (if (fneq val 0.0) (snd-display #__line__ ";simple no-in pv call: ~A" val)) (set! val (catch #t (lambda () (set! gen (make-phase-vocoder :fft-size 1234))) (lambda args (car args)))) (if (not (eq? val 'out-of-range)) (snd-display #__line__ ";pv bad fft: ~A" val)) ) (let* ((ind (open-sound "oboe.snd")) (pi2 (* 2.0 pi)) (reader (make-sampler 0)) (pv (make-phase-vocoder (lambda (dir) (next-sample reader)) 512 4 128 1.0 #f ;no change to analysis #f ;no change to edits #f ;no change to synthesis ))) (if (not (phase-vocoder? pv)) (snd-display #__line__ ";~A not phase-vocoder?" pv)) (print-and-check pv "phase-vocoder" "phase-vocoder outctr: 128, interp: 128, filptr: 0, N: 512, D: 128, in_data: nil") (let ((val (let ((pv (make-phase-vocoder))) (set! (mus-location pv) 120) (mus-location pv)))) (if (not (= val 120)) (snd-display #__line__ ";pv set outctr: ~A" val))) (select-sound ind) (map-channel (lambda (val) (phase-vocoder pv))) (float-vector-set! (phase-vocoder-amp-increments pv) 0 .1) (if (fneq ((phase-vocoder-amp-increments pv) 0) .1) (snd-display #__line__ ";set phase-vocoder-amp-increments: ~A?" ((phase-vocoder-amp-increments pv) 0))) (float-vector-set! (phase-vocoder-amps pv) 0 .1) (if (fneq ((phase-vocoder-amps pv) 0) .1) (snd-display #__line__ ";set phase-vocoder-amps: ~A?" ((phase-vocoder-amps pv) 0))) (float-vector-set! (phase-vocoder-phases pv) 0 .1) (if (fneq ((phase-vocoder-phases pv) 0) .1) (snd-display #__line__ ";set phase-vocoder-phases: ~A?" ((phase-vocoder-phases pv) 0))) (float-vector-set! (phase-vocoder-phase-increments pv) 0 .1) (if (fneq ((phase-vocoder-phase-increments pv) 0) .1) (snd-display #__line__ ";set phase-vocoder-phase-increments: ~A?" ((phase-vocoder-phase-increments pv) 0))) (float-vector-set! (phase-vocoder-freqs pv) 0 .1) (if (fneq ((phase-vocoder-freqs pv) 0) .1) (snd-display #__line__ ";set phase-vocoder-freqs: ~A?" ((phase-vocoder-freqs pv) 0))) (undo 1) (free-sampler reader) (let ((lastphases (make-float-vector 512)) (diffs (make-float-vector 512))) (define (efunc v) ;; new editing func changes pitch (let ((N (mus-length v)) ;mus-increment => interp, mus-data => in-data (D (mus-hop v)) (freqs (phase-vocoder-freqs v))) (copy freqs diffs) (float-vector-subtract! diffs lastphases) (copy freqs lastphases) (let ((N2 (floor (/ N 2))) (pscl (/ 1.0 D)) (kscl (/ pi2 N))) (do ((k 0 (+ k 1)) (kx 0.0 (+ kx kscl))) ((= k N2)) (float-vector-set! freqs k (* 0.5 (+ (* pscl (remainder (float-vector-ref diffs k) pi2)) kx))))) #f)) (set! reader (make-sampler 0)) (set! pv (make-phase-vocoder (lambda (dir) (next-sample reader)) 512 4 128 1.0 #f ;no change to analysis efunc #f ; no change to synthesis )) (map-channel (lambda (val) (phase-vocoder pv)))) (undo 1) (free-sampler reader) (set! reader (make-sampler 0)) (set! pv (make-phase-vocoder (lambda (dir) (next-sample reader)) 512 4 (* 128 2) 1.0 #f ;no change to analysis #f ;no change to edits #f ;no change to synthesis )) (let* ((len 1000) (data (make-float-vector len))) (fill-float-vector data (phase-vocoder pv)) (set! (samples 0 len) data)) (undo 1) (free-sampler reader) (let ((incalls 0) (outcalls 0)) (set! reader (make-sampler 0)) (set! pv (make-phase-vocoder (lambda (dir) (next-sample reader)) 512 4 (* 128 2) 1.0 (lambda (v infunc) (set! incalls (+ incalls 1)) #t) #f ;no change to edits (lambda (v) (set! outcalls (+ outcalls 1)) 0.0) )) (let* ((len 1000) (data (make-float-vector len))) (fill-float-vector data (phase-vocoder pv)) (set! (samples 0 len) data)) (undo 1) (free-sampler reader) (if (or (= incalls 0) (= outcalls 0)) (snd-display #__line__ ";phase-vocoder incalls: ~A, outcalls: ~A" incalls outcalls))) (let ((tag (catch #t (lambda () (make-phase-vocoder #f 512 4 256 1.0 (lambda (a b c) #f) #f #f)) (lambda args args)))) (if (not (eq? (car tag) 'bad-arity)) (snd-display #__line__ ";make-phase-vocoder bad analyze func: ~A" tag))) (let ((tag (catch #t (lambda () (make-phase-vocoder #f 512 4 256 1.0 (lambda (a b) 0.0) (lambda (a b c) #f) #f)) (lambda args args)))) (if (not (eq? (car tag) 'bad-arity)) (snd-display #__line__ ";make-phase-vocoder bad edit func: ~A" tag))) (let ((tag (catch #t (lambda () (make-phase-vocoder #f 512 4 256 1.0 (lambda (a b) 0.0) (lambda (a) #f) (lambda (a b) 0))) (lambda args args)))) (if (not (eq? (car tag) 'bad-arity)) (snd-display #__line__ ";make-phase-vocoder bad synthesize func: ~A" tag))) (let ((geno (make-phase-vocoder (lambda (dir) 0.0)))) (let ((genx (make-phase-vocoder :input (lambda (dir) 0.0)))) (if (equal? geno genx) (snd-display #__line__ ";phase-vocoder equal? ~A ~A" geno genx)) (if (fneq (mus-frequency genx) 1.0) (snd-display #__line__ ";mus-frequency phase-vocoder: ~A" (mus-frequency genx))) (set! (mus-frequency genx) 2.0) (if (fneq (mus-frequency genx) 2.0) (snd-display #__line__ ";set mus-frequency phase-vocoder: ~A" (mus-frequency genx))) (if (fneq (mus-increment genx) 128) (snd-display #__line__ ";mus-increment phase-vocoder: ~A" (mus-increment genx))) (set! (mus-increment genx) 256) (if (fneq (mus-increment genx) 256) (snd-display #__line__ ";set mus-increment phase-vocoder: ~A" (mus-increment genx))) (if (not (= (mus-hop genx) 128)) (snd-display #__line__ ";phase vocoder hop: ~A" (mus-hop genx))) (set! (mus-hop genx) 64) (if (not (= (mus-hop genx) 64)) (snd-display #__line__ ";set phase vocoder hop: ~A" (mus-hop genx))) (if (not (= (mus-length genx) 512)) (snd-display #__line__ ";phase vocoder length: ~A" (mus-length genx))) (let ((genxx genx)) (if (not (equal? genx genxx)) (snd-display #__line__ ";phase-vocoder equal: ~A ~A" genxx genx))))) (close-sound ind)) (let ((old-fudge *mus-float-equal-fudge-factor*) ; some phase-vocoder tests (ind (new-sound :size 110)) (rd #f) (pv #f)) (set! (sample 1) 1.0) (set! rd (make-sampler)) (set! pv (make-phase-vocoder (lambda (dir) (next-sample rd)) 128 4 32 1.0 #f #f #f)) (map-channel (lambda (y) (phase-vocoder pv))) (set! *mus-float-equal-fudge-factor* 1e-5) (let ((v (channel->float-vector 0 50)) (v0 (float-vector 0.00022 0.00130 0.00382 0.00810 0.01381 0.01960 0.02301 0.02143 0.01421 0.00481 0.00000 0.00396 0.01168 0.01231 0.00413 0.00018 0.00704 0.00984 0.00189 0.00197 0.00881 0.00290 0.00151 0.00781 0.00091 0.00404 0.00498 0.00047 0.00641 -0.00017 0.00590 0.00006 0.00492 0.00031 0.00380 0.00052 0.00290 0.00066 0.00219 0.00074 0.00164 0.00076 0.00123 0.00074 0.00092 0.00067 0.00069 0.00058 0.00052 0.00048))) (if (and (not (mus-arrays-equal? v v0)) (not (mus-arrays-equal? (float-vector-scale! v -1.0) v0))) (snd-display #__line__ ";pv 1 diff: ~A" (float-vector-peak (float-vector-subtract! v v0))))) (undo) (set! rd (make-sampler)) (set! pv (make-phase-vocoder (lambda (dir) (next-sample rd)) 128 4 32 2.0 #f #f #f)) (map-channel (lambda (y) (phase-vocoder pv))) (let ((v (channel->float-vector 0 50)) (v0 (float-vector 0.00044 0.00255 0.00705 0.01285 0.01595 0.01177 0.00281 0.00069 0.00782 0.00702 0.00001 0.00584 0.00385 0.00138 0.00547 0.00035 0.00494 0.00082 0.00305 0.00310 0.00003 0.00380 0.00245 -0.00019 0.00159 0.00348 0.00268 0.00087 -0.00020 -0.00036 -0.00010 0.00012 0.00036 0.00057 0.00075 0.00089 0.00099 0.00105 0.00108 0.00107 0.00104 0.00099 0.00094 0.00087 0.00080 0.00073 0.00066 0.00059 0.00053 0.00047))) (if (not (mus-arrays-equal? v v0)) (snd-display #__line__ ";pv 2 diff: ~A" (float-vector-peak (float-vector-subtract! v v0))))) (undo) (set! rd (make-sampler)) (set! pv (make-phase-vocoder (lambda (dir) (next-sample rd)) 128 4 32 0.5 #f #f #f)) (map-channel (lambda (y) (phase-vocoder pv))) (let ((v (channel->float-vector 0 50)) (v0 (float-vector 0.00011 0.00065 0.00195 0.00428 0.00785 0.01266 0.01845 0.02456 0.02989 0.03305 0.03267 0.02803 0.01970 0.00993 0.00228 0.00009 0.00441 0.01250 0.01858 0.01759 0.00975 0.00160 0.00079 0.00795 0.01454 0.01201 0.00325 0.00024 0.00716 0.01261 0.00704 0.00003 0.00384 0.00962 0.00620 0.00027 0.00196 0.00655 0.00492 0.00040 0.00101 0.00448 0.00375 0.00041 0.00053 0.00305 0.00273 0.00033 0.00029 0.00204))) (if (not (mus-arrays-equal? v v0)) (snd-display #__line__ ";pv 3 diff: ~A" (float-vector-peak (float-vector-subtract! v v0))))) (undo) (set! rd (make-sampler)) (set! pv (make-phase-vocoder (lambda (dir) (next-sample rd)) 128 4 64 1.0 #f #f #f)) (map-channel (lambda (y) (phase-vocoder pv))) (let ((v (channel->float-vector 0 100)) (v0 (float-vector 0.00005 0.00033 0.00098 0.00214 0.00392 0.00633 0.00923 0.01228 0.01495 0.01652 0.01633 0.01401 0.00985 0.00497 0.00114 0.00004 0.00221 0.00625 0.00929 0.00880 0.00488 0.00080 0.00040 0.00397 0.00727 0.00601 0.00162 0.00012 0.00358 0.00630 0.00352 0.00002 0.00217 0.00552 0.00300 -0.00008 0.00299 0.00479 0.00083 0.00098 0.00457 0.00175 0.00033 0.00412 0.00172 0.00039 0.00399 0.00087 0.00118 0.00356 -0.00016 0.00280 0.00169 0.00051 0.00326 -0.00030 0.00301 0.00040 0.00184 0.00144 0.00078 0.00213 0.00015 0.00242 -0.00017 0.00240 -0.00038 0.00230 -0.00049 0.00214 -0.00053 0.00194 -0.00051 0.00172 -0.00047 0.00150 -0.00040 0.00127 -0.00033 0.00106 -0.00025 0.00086 -0.00019 0.00068 -0.00013 0.00052 -0.00008 0.00039 -0.00005 0.00027 -0.00002 0.00017 -0.00001 0.00009 -0.00000 0.00003 -0.00000 -0.00002 -0.00001 -0.00006))) (if (not (mus-arrays-equal? v v0)) (snd-display #__line__ ";pv 4 diff: ~A" (float-vector-peak (float-vector-subtract! v v0))))) (undo) (set! (sample 10) 1.0) (set! (sample 23) 1.0) (set! rd (make-sampler)) (set! pv (make-phase-vocoder (lambda (dir) (next-sample rd)) 128 4 32 1.0 #f #f #f)) (map-channel (lambda (y) (phase-vocoder pv))) (let ((v (channel->float-vector 0 100)) (v0 (float-vector 0.00100 0.00598 0.01756 0.03708 0.06286 0.08826 0.10172 0.09163 0.05680 0.01564 -0.00075 0.02124 0.05164 0.04457 0.00861 0.00529 0.03648 0.02747 -0.00875 0.00936 0.02402 -0.00553 -0.00090 -0.02262 -0.00221 0.06633 -0.03229 0.01861 0.05228 0.00672 0.00885 0.01442 -0.00484 -0.02293 -0.01893 -0.02256 -0.10229 -0.22474 0.31110 0.07597 0.07127 0.03670 0.02583 0.03173 0.02260 0.01550 0.01485 0.03212 -0.00966 0.00779 -0.00964 0.00698 0.01100 0.00468 0.00107 0.00517 0.00469 0.00131 0.00058 0.00530 0.00582 -0.00652 0.00011 0.00000 -0.00000 -0.00000 -0.00000 0.00000 -0.00000 0.00000 0.00000 -0.00000 -0.00000 -0.00000 -0.00000 -0.00000 -0.00000 0.00000 -0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 -0.00000 -0.00000 -0.00000 0.00000 0.00000 0.00000 -0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000))) (if (not (mus-arrays-equal? v v0)) (snd-display #__line__ ";pv 5 diff: ~A" (float-vector-peak (float-vector-subtract! v v0))))) (undo) (set! (sample 40) 1.0) (set! (sample 63) 1.0) (set! rd (make-sampler)) (set! pv (make-phase-vocoder (lambda (dir) (next-sample rd)) 128 4 32 1.0 #f #f #f)) (map-channel (lambda (y) (phase-vocoder pv))) (let ((v (channel->float-vector 0 100)) (v0 (float-vector 0.00332 0.01977 0.05805 0.12252 0.20738 0.29035 0.33291 0.29696 0.18017 0.04637 -0.00003 0.08250 0.18618 0.15495 0.02775 0.02252 0.13597 0.09767 -0.03116 0.05301 0.10256 -0.05005 0.01966 0.06176 -0.04418 0.04118 -0.11409 -0.04115 -0.05157 -0.11409 0.07815 -0.08155 -0.00536 0.02090 -0.18804 -0.10686 -0.11931 -0.42989 0.39009 0.03157 0.14253 0.05984 0.05439 0.00764 0.02636 -0.02799 -0.01346 -0.01011 -0.04925 -0.02896 -0.07812 -0.07880 -0.11338 -0.13133 -0.41421 0.38140 0.08676 0.07712 0.00983 0.03731 0.01585 0.00108 0.00101 0.00282 -0.01106 -0.00403 -0.02165 -0.02054 -0.02452 -0.02382 -0.03213 -0.02693 -0.03734 -0.03978 -0.04879 -0.07504 -0.09597 -0.31426 0.32995 0.13460 0.04120 0.05029 0.01900 0.02517 0.01163 0.01294 0.00827 0.00576 0.00640 0.00141 0.00489 -0.00057 0.00301 -0.00089 0.00099 -0.00000 0.00000 -0.00000 -0.00000 -0.00000))) (if (not (mus-arrays-equal? v v0)) (snd-display #__line__ ";pv 6 diff: ~A" (float-vector-peak (float-vector-subtract! v v0))))) (close-sound ind) (set! *mus-float-equal-fudge-factor* old-fudge)) (let () (define (pvoc-d beg dur amp size) (let ((N2 (floor (/ size 2)))) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (lastphases (make-float-vector N2)) (two-pi (* 2 pi)) (osc (make-oscil 1000.0)) (amps #f) (paincrs #f) (ppincrs #f) (phases #f) (freqs #f)) (define (ifunc dir) (oscil osc)) (define (efunc c) (let* ((D (floor (/ size 4))) ; overlap = 4 (pscl (/ 1.0 D)) (kscl (/ two-pi size))) (do ((k 0 (+ k 1)) (ks 0.0 (+ ks kscl))) ((= k N2)) (let* ((freq (freqs k)) (diff (- freq (lastphases k)))) (set! (lastphases k) freq) (if (> diff pi) (set! diff (- diff two-pi))) (if (< diff (- pi)) (set! diff (+ diff two-pi))) (set! (freqs k) (+ (* diff pscl) ks)))) #f)) (define (sfunc c) (float-vector-add! amps paincrs) (float-vector-add! ppincrs freqs) (float-vector-add! phases ppincrs) (let ((sum 0.0)) (do ((i 0 (+ i 1))) ((= i N2)) (if (> (amps i) .75) (set! sum (+ sum (* (amps i) (if (> (modulo (phases i) two-pi) pi) 1.0 -1.0)))))) sum)) (let ((sr (make-phase-vocoder :fft-size size :interp (/ size 4) :overlap 4 :edit efunc :synthesize sfunc :input ifunc))) (set! amps (phase-vocoder-amps sr)) (set! paincrs (phase-vocoder-amp-increments sr)) (set! ppincrs (phase-vocoder-phase-increments sr)) (set! phases (phase-vocoder-phases sr)) (set! freqs (phase-vocoder-freqs sr)) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (phase-vocoder sr)))))))) (let ((v (make-float-vector 200))) (with-sound (v :srate 44100) (pvoc-d 0 .0025 .2 128)) (do ((i 55 (+ i 1))) ((= i 65)) (if (> (abs (- (v i) .196)) .01) (snd-display #__line__ ";pvoc-d at ~D: ~A~%" i (v i)))) (do ((i 75 (+ i 1))) ((= i 85)) (if (> (abs (- (v i) -.196)) .01) (snd-display #__line__ ";pvoc-d at ~D: ~A~%" i (v i))))) ) (let ((ind (open-sound "oboe.snd"))) (let ((gen (make-moog-filter 500.0 .1))) (if (fneq 500.0 (moog-frequency gen)) (snd-display #__line__ ";moog freq: ~A" (moog-frequency gen))) ; moog-frequency is a separate function (if (fneq .1 (gen 'Q)) (snd-display #__line__ ";moog Q: ~A" (gen 'Q))) ; (if (not (float-vector? (gen 's))) (snd-display #__line__ ";moog state: ~A" (gen 's))) (if (fneq 0.0 (gen 'y)) (snd-display #__line__ ";moog A? ~A" (gen 'y))) (if (fneq -0.861 (gen 'fc)) (snd-display #__line__ ";moog freqtable: ~A" (gen 'fc))) (let ((vals (make-float-vector 20))) (set! (vals 0) (moog-filter gen 1.0)) (do ((i 1 (+ i 1))) ((= i 20)) (set! (vals i) (moog-filter gen 0.0))) (if (not (vequal vals (float-vector 0.0 0.0 0.0025 0.0062 0.0120 0.0198 0.0292 0.0398 0.0510 0.0625 0.0739 0.0847 0.0946 0.1036 0.1113 0.1177 0.1228 0.1266 0.1290 0.1301))) (snd-display #__line__ ";moog output: ~A" vals)))) (close-sound ind)) (let ((gen (make-ssb-am 440.0)) (v0 (make-float-vector 10)) (gen1 (make-ssb-am 440.0)) (v1 (make-float-vector 10))) (print-and-check gen "ssb-am" "ssb-am shift: up, sin/cos: 439.999975 Hz (0.000000 radians), order: 41" "ssb-am shift: up, sin/cos: 440.000000 Hz (0.000000 radians), order: 41" "ssb-am shift: up, sin/cos: 439.999969 Hz (0.000000 radians), order: 41") (do ((i 0 (+ i 1))) ((= i 10)) (set! (v0 i) (ssb-am gen))) (fill-float-vector v1 (if (ssb-am? gen1) (ssb-am gen1) -1.0)) (if (not (vequal v0 v1)) (snd-display #__line__ ";map ssb-am: ~A ~A" v0 v1)) (if (not (ssb-am? gen)) (snd-display #__line__ ";~A not ssb-am?" gen)) (if (fneq (mus-phase gen) 1.253787) (snd-display #__line__ ";ssb-am phase: ~F?" (mus-phase gen))) (if (fneq (mus-frequency gen) 440.0) (snd-display #__line__ ";ssb-am frequency: ~F?" (mus-frequency gen))) (if (not (= (mus-order gen) 41)) (snd-display #__line__ ";ssb-am order: ~F?" (mus-order gen))) (if (not (= (mus-length gen) 41)) (snd-display #__line__ ";ssb-am length: ~D?" (mus-length gen))) (if (not (= (mus-interp-type gen) mus-interp-none)) (snd-display #__line__ ";ssb-am interp type: ~D?" (mus-interp-type gen))) (if (fneq (mus-xcoeff gen 0) -0.00124) (snd-display #__line__ ";ssb-am xcoeff 0: ~A" (mus-xcoeff gen 0))) (if (fneq (mus-xcoeff gen 1) 0.0) (snd-display #__line__ ";ssb-am xcoeff 1: ~A" (mus-xcoeff gen 1))) ; (if (not (float-vector? (mus-data gen))) (snd-display #__line__ ";mus-data ssb-am: ~A" (mus-data gen))) ; (if (not (float-vector? (mus-xcoeffs gen))) (snd-display #__line__ ";mus-xcoeffs ssb-am: ~A" (mus-xcoeffs gen))) ;; these apparently aren't handled in clm2xen ) (test-gen-equal (make-ssb-am 440.0) (make-ssb-am 440.0) (make-ssb-am 500.0)) (let ((o1 (make-ssb-am 400.0)) (o2 (make-ssb-am-1 400.0)) (happy #t)) (do ((i 0 (+ i 1))) ((or (not happy) (= i 100))) (let* ((inval (sin (* .1 i))) (o1o (ssb-am o1 inval)) (o2o (ssb-am-1 o2 inval))) (if (fneq o1o o2o) (begin (snd-display #__line__ ";ssb-am (up): ~A ~A at ~A" o1o o2o i) (set! happy #f)))))) (let ((o1 (make-ssb-am 400.0)) (o2 (make-ssb-am-1 400.0)) (happy #t)) (do ((i 0 (+ i 1))) ((or (not happy) (= i 100))) (let* ((inval (sin (* .1 i))) (fmval (sin (* .2 i))) (o1o (ssb-am o1 inval fmval)) (o2o (ssb-am-1 o2 inval fmval))) (if (fneq o1o o2o) (begin (snd-display #__line__ ";ssb-am + fm (up): ~A ~A at ~A" o1o o2o i) (set! happy #f)))))) (let ((o1 (make-ssb-am -100.0)) (o2 (make-ssb-am-1 -100.0)) (happy #t)) (do ((i 0 (+ i 1))) ((or (not happy) (= i 100))) (let* ((inval (random 1.0)) (o1o (ssb-am o1 inval)) (o2o (ssb-am-1 o2 inval))) (if (fneq o1o o2o) (begin (snd-display #__line__ ";ssb-am (down): ~A ~A at ~A" o1o o2o i) (set! happy #f)))))) (let ((o1 (make-ssb-am 1000.0 100)) (o2 (make-ssb-am-1 1000.0 100)) (happy #t)) (do ((i 0 (+ i 1))) ((or (not happy) (= i 100))) (let* ((inval (random 1.0)) (o1o (ssb-am o1 inval)) (o2o (ssb-am-1 o2 inval))) (if (fneq o1o o2o) (begin (snd-display #__line__ ";ssb-am (down): ~A ~A at ~A" o1o o2o i) (set! happy #f)))))) (let ((index (open-sound "pistol.snd")) (data (channel->float-vector 0 100))) (convolve-with "oboe.snd" #f) (let ((scl (maxamp))) (convolve-with "oboe.snd" scl index 0 0) (if (ffneq (maxamp) scl) (snd-display #__line__ ";convolve-with amps: ~A ~A" (maxamp) scl))) (revert-sound index) (agc) (if (fneq (maxamp index 0) 1.29) (snd-display #__line__ ";agc: ~A" (maxamp index 0))) (close-sound index) (let ((reader (make-sampler 0 "pistol.snd"))) (do ((i 0 (+ i 1))) ((= i 10)) (if (fneq (data i) (next-sample reader)) (snd-display #__line__ ";external reader trouble"))) (free-sampler reader))) (let ((make-procs (list make-all-pass make-asymmetric-fm make-moving-average make-moving-max make-moving-norm make-comb (lambda () (make-convolve :filter (float-vector 0 1 2))) make-delay (lambda () (make-env '(0 1 1 0) :length 10)) (lambda () (make-filter :xcoeffs (float-vector 0 1 2))) (lambda () (make-fir-filter :xcoeffs (float-vector 0 1 2))) (lambda () (make-filtered-comb :filter (make-one-zero .5 .5))) make-formant make-granulate (lambda () (make-iir-filter :xcoeffs (float-vector 0 1 2))) make-locsig make-notch make-one-pole (lambda () (make-one-pole-all-pass 1 .5)) make-one-zero make-oscil make-pulse-train make-rand make-rand-interp make-sawtooth-wave make-square-wave make-src make-table-lookup make-triangle-wave make-two-pole make-two-zero make-wave-train make-polyshape make-phase-vocoder make-ssb-am (lambda () (make-filter :ycoeffs (float-vector 0 1 2))) (lambda () (make-filter :xcoeffs (float-vector 1 2 3) :ycoeffs (float-vector 0 1 2))))) (gen-procs (list all-pass asymmetric-fm moving-average moving-max moving-norm comb convolve delay env filter fir-filter filtered-comb formant granulate iir-filter (lambda (gen a) (locsig gen 0 a)) notch one-pole one-pole-all-pass one-zero oscil pulse-train rand rand-interp sawtooth-wave square-wave (lambda (gen a) (src gen 0.0 a)) table-lookup triangle-wave two-pole two-zero wave-train polyshape phase-vocoder ssb-am filter filter)) (ques-procs (list all-pass? asymmetric-fm? moving-average? moving-max? moving-norm? comb? convolve? delay? env? filter? fir-filter? filtered-comb? formant? granulate? iir-filter? locsig? notch? one-pole? one-pole-all-pass? one-zero? oscil? pulse-train? rand? rand-interp? sawtooth-wave? square-wave? src? table-lookup? triangle-wave? two-pole? two-zero? wave-train? polyshape? phase-vocoder? ssb-am? filter? filter?)) (func-names (list 'all-pass 'asymmetric-fm 'moving-average 'moving-max 'moving-norm 'comb 'convolve 'delay 'env 'filter-x 'fir-filter 'filtered-comb 'formant 'granulate 'iir-filter 'locsig 'notch 'one-pole 'one-pole-all-pass 'one-zero 'oscil 'pulse-train 'rand 'rand-interp 'sawtooth-wave 'square-wave 'src 'table-lookup 'triangle-wave 'two-pole 'two-zero 'wave-train 'polyshape 'phase-vocoder 'ssb-am 'filter-y 'filter-xy)) (gen-args (list 0.0 0.0 1.0 1.0 1.0 0.0 (lambda (dir) 0.0) 0.0 #f 0.0 0.0 0.0 0.0 (lambda (dir) 0.0) 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 (lambda (dir) 0.0) 0.0 0.0 0.0 0.0 0.0 0.0 (lambda (dir) 0.0) 0.0 0.0 0.0)) (generic-procs (list mus-channel mus-channels mus-data mus-feedback mus-feedforward mus-frequency mus-hop mus-increment mus-length mus-location mus-order mus-phase mus-ramp mus-scaler mus-xcoeffs mus-ycoeffs)) (generic-names (list 'mus-channel 'mus-channels 'mus-data 'mus-feedback 'mus-feedforward 'mus-frequency 'mus-hop 'mus-increment 'mus-length 'mus-location 'mus-order 'mus-phase 'mus-ramp 'mus-scaler 'mus-xcoeffs 'mus-ycoeffs))) (for-each (lambda (make runp ques arg name) (let ((gen (make))) (if (not (ques gen)) (snd-display #__line__ ";~A: ~A -> ~A?" name make gen)) (let ((tag (catch #t (lambda () (if arg (runp gen arg) (runp gen))) (lambda args args)))) (if (and (not (number? tag)) (not (float-vector? tag))) (snd-display #__line__ ";~A: ~A ~A ~A: ~A" name runp gen arg tag))) (for-each (lambda (func genname) (let ((tag (catch #t (lambda () (func #f)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";generic func with #f: (~A #f) -> ~A" genname tag))) (let ((g1 (make-oscil)) (g2 (make-one-pole .1 .9))) (let ((tag (catch #t (lambda () (func g1)) (lambda args (car args))))) (if (and (symbol? tag) (not (eq? tag 'wrong-type-arg)) (not (eq? tag 'mus-error))) (snd-display #__line__ ";generic ~A of oscil: ~A" genname tag))) (let ((tag (catch #t (lambda () (func g2)) (lambda args (car args))))) (if (and (symbol? tag) (not (eq? tag 'wrong-type-arg)) (not (eq? tag 'mus-error))) (snd-display #__line__ ";generic ~A of delay: ~A" genname tag)))) (let ((tag (catch #t (lambda () (func gen)) (lambda args (car args))))) (if (and (not (symbol? tag)) (dilambda? func) (or (not (eq? genname 'mus-data)) (float-vector? tag))) (let ((tag1 (catch #t (lambda () (set! (func gen) tag)) (lambda args (car args))))) (if (and (symbol? tag1) (not (eq? tag1 'mus-error)) (not (eq? tag1 'out-of-range))) (snd-display #__line__ ";~A set ~A ~A ~A -> ~A" name genname gen tag tag1)))))) generic-procs generic-names) (mus-reset gen))) make-procs gen-procs ques-procs gen-args func-names) (let ((make-procs (list make-all-pass make-asymmetric-fm make-moving-average make-moving-max make-comb (lambda () (make-filtered-comb :filter (make-one-zero .5 .5))) (lambda () (make-convolve :filter (float-vector 0 1 2) :input (lambda (dir) 1.0))) make-delay (lambda () (make-env :length 11 :envelope '(0 1 1 0))) (lambda () (make-filter :xcoeffs (float-vector 0 1 2))) (lambda () (make-fir-filter :xcoeffs (float-vector 0 1 2))) (lambda () (make-formant :radius .1 :frequency 440.0)) (lambda () (make-granulate (lambda (dir) 1.0))) (lambda () (make-iir-filter :xcoeffs (float-vector 0 1 2))) make-locsig make-notch (lambda () (make-one-pole .3 .7)) (lambda () (make-one-zero .5 .5)) make-oscil make-pulse-train make-sawtooth-wave make-square-wave (lambda () (make-table-lookup :wave (make-float-vector 128 .1))) make-triangle-wave (lambda () (make-two-pole .1 .3 .6)) (lambda () (make-two-zero .1 .3 .5)) (lambda () (make-polyshape 440.0 :partials '(1 1))) (lambda () (make-phase-vocoder (lambda (dir) 1.0))) make-ssb-am (lambda () (make-filter :ycoeffs (float-vector 0 1 2))) (lambda () (make-filter :xcoeffs (float-vector 1 2 3) :ycoeffs (float-vector 0 1 2))))) (gen-procs (list all-pass asymmetric-fm moving-average moving-max comb filtered-comb convolve delay (lambda (gen ignored) (env gen)) filter fir-filter formant granulate iir-filter (lambda (gen a) (locsig gen 0 1.0)) notch one-pole one-zero oscil pulse-train sawtooth-wave square-wave table-lookup triangle-wave two-pole two-zero polyshape phase-vocoder ssb-am filter filter)) (func-names (list 'all-pass 'asymmetric-fm 'moving-average 'moving-max 'comb 'filtered-comb 'convolve 'delay 'env 'filter-x 'fir-filter 'formant 'granulate 'iir-filter 'locsig 'notch 'one-pole 'one-zero 'oscil 'pulse-train 'sawtooth-wave 'square-wave 'table-lookup 'triangle-wave 'two-pole 'two-zero 'polyshape 'phase-vocoder 'ssb-am 'filter-y 'filter-xy))) (for-each (lambda (make runp name) (let ((gen (make)) (data (make-float-vector 10))) (set! (data 0) (runp gen 1.0)) (do ((i 1 (+ i 1))) ((= i 10)) (set! (data i) (runp gen 0.0))) (do ((k 0 (+ k 1))) ((= k 2)) (mus-reset gen) (if (and (not (eq? name 'env)) (not (eq? name 'locsig))) (let ((not-zero #f)) (let ((first-val (if (= k 0) (runp gen 1.0) (mus-apply gen 1.0 0.0)))) (if (not (= (data 0) 0.0)) (set! not-zero #t)) (if (fneq (data 0) first-val) (snd-display #__line__ ";[~A] ~A: ~A ~A ~A" (if (= k 0) 'run 'apply) name 0 (data 0) first-val))) (do ((i 1 (+ i 1))) ((= i 10)) (let ((old-val (data i)) (new-val (if (= k 0) (runp gen 0.0) (mus-apply gen 0.0 0.0)))) (if (not (= old-val 0.0)) (set! not-zero #t)) (if (fneq old-val new-val) (snd-display #__line__ ";[~A] ~A: ~A ~A ~A" (if (= k 0) 'run 'apply) name i old-val new-val)))) (if (and (not (eq? name 'polyshape)) (not (eq? name 'ssb-am)) (not not-zero)) (snd-display #__line__ ";~A not much of a reset test!" name))))))) make-procs gen-procs func-names)) (if (and all-args (= clmtest 0)) (begin (for-each (lambda (make runp) (catch #t (lambda () (let ((gen (make))) ;; run args (for-each (lambda (arg1) ;; how did this ever work?? (catch #t (lambda () (runp gen arg1)) (lambda args (car args))) (for-each (lambda (arg2) (catch #t (lambda () (runp gen arg1 arg2)) (lambda args (car args)))) (list 1.5 "/hiho" (list 0 1) 1234 (make-float-vector 3) (make-color-with-catch .95 .95 .95) #(0 1) 3/4 'mus-error 0+i (make-delay 32) (lambda () #t) (curlet) (make-float-vector (list 2 3) 0.0) :order 0 1 -1 #f #t #\c 0.0 1.0 -1.0 () 3 4 2 8 16 32 64 (make-vector 0) '(1 . 2) (expt 2.0 21.5) (expt 2.0 -18.0) ))) (list 1.5 "/hiho" (list 0 1) 1234 (make-float-vector 3) (make-color-with-catch .95 .95 .95) #(0 1) 3/4 'mus-error 0+i (make-delay 32) (lambda () #t) (curlet) (make-float-vector (list 2 3) 0.0) :order 0 1 -1 #f #t #\c 0.0 1.0 -1.0 () 3 4 2 8 16 32 64 (make-vector 0) '(1 . 2) (expt 2.0 21.5) (expt 2.0 -18.0) )) ;; generic args (for-each (lambda (func name) (catch #t (lambda () (let ((default-value (func gen))) (for-each (lambda (arg1) (catch #t (lambda () (func gen) (set! (func gen) arg1)) (lambda args #f))) (list 1.5 "/hiho" (list 0 1) 1234 (make-float-vector 3) #(0 1) 3/4 'mus-error 0+i (lambda () #t) (make-float-vector (list 2 3) 0.0) :order 0 1 -1 #f #t #\c 0.0 1.0 -1.0 () 3 4 64 -64 (make-vector 0) '(1 . 2) (expt 2.0 21.5) (expt 2.0 -18.0) (lambda (a) a))) (if (not (equal? (func gen) default-value)) (catch #t (lambda () (set! (func gen) default-value)) (lambda args #f))))) (lambda args #f))) generic-procs generic-names) (mus-reset gen))) (lambda args (car args)))) make-procs gen-procs) (let ((new-wave (make-float-vector 1))) (for-each (lambda (g g1) (let ((gen (g :wave new-wave))) (g1 gen 1.0))) (list make-table-lookup) (list table-lookup))) (let ((old-clm-srate *clm-srate*)) (for-each (lambda (n) (set! *clm-srate* n) (for-each (lambda (g name) (let ((tag (catch #t (lambda () (g :frequency 440.0)) (lambda args (car args))))) (if (not (memq tag '(wrong-type-arg out-of-range))) (snd-display #__line__ ";key-check ~A: ~A -> ~A" n name tag)))) (list make-oscil make-asymmetric-fm make-triangle-wave make-square-wave make-pulse-train make-sawtooth-wave make-rand make-rand-interp) (list 'oscil 'asymmetric-fm 'triangle-wave 'square-wave 'pusle-train 'sawtooth-wave 'rand 'rand-interp))) (list 100 1)) (set! *clm-srate* old-clm-srate)) (let ((random-args (list (expt 2.0 21.5) (expt 2.0 -18.0) 1.5 "/hiho" (list 0 1) 1234 (make-float-vector 3) (make-color-with-catch .1 .2 .3) #(0 1) 3/4 0+i (make-delay 32) (lambda () 0.0) (lambda (dir) 1.0) (lambda (a b c) 1.0) 0 1 -1 #f #t #\c 0.0 1.0 -1.0 () 32 '(1 . 2) )) (gen-make-procs (list make-all-pass make-asymmetric-fm make-moving-average make-moving-max make-moving-norm make-table-lookup make-triangle-wave make-comb ;make-convolve make-delay make-env make-fft-window make-filter make-filtered-comb make-fir-filter make-formant make-iir-filter make-locsig make-notch make-one-pole make-one-pole-all-pass make-one-zero make-oscil make-pulse-train make-rand make-rand-interp make-sawtooth-wave make-polyshape make-polywave make-square-wave ;make-src make-two-pole make-two-zero make-wave-train make-ssb-am))) (define (random-gen args) (for-each (lambda (n) (let ((gen (catch #t (lambda () (apply n args)) (lambda args (car args))))) (if (mus-generator? gen) (for-each (lambda (arg) (catch #t (lambda () (gen arg)) (lambda args (car args)))) random-args)))) gen-make-procs)) (random-gen ()) (for-each (lambda (arg1) (random-gen (list arg1)) (for-each (lambda (arg2) (random-gen (list arg1 arg2)) (for-each (lambda (arg3) (random-gen (list arg1 arg2 arg3)) (for-each (lambda (arg4) (random-gen (list arg1 arg2 arg3 arg4))) random-args)) random-args)) random-args)) random-args))))) (let ((gen (make-moving-max 4))) (let ((ov (make-float-vector 10)) (iv (float-vector .1 .05 -.2 .15 -1.5 0.1 0.01 0.001 0.0 0.0)) (tv (float-vector .1 .1 .2 .2 1.5 1.5 1.5 1.5 0.1 0.01))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (ov i) (moving-max gen (iv i)))) (if (not (vequal tv ov)) (snd-display #__line__ ";moving-max: ~A ~A" ov tv)))) (let ((g1 (make-moving-max 10))) (do ((i 0 (+ i 1))) ((= i 1000)) (let ((val (moving-max g1 (random 1.0)))) (let ((pk (float-vector-peak (mus-data g1)))) (if (not (= pk val)) (snd-display #__line__ ";moving-max ~A ~A" pk val)))))) (let ((odata (make-float-vector 15 0.0)) (data (float-vector 1.0 0.0 -1.1 1.1001 0.1 -1.1 1.0 1.0 0.5 -0.01 0.02 0.0 0.0 0.0 0.0)) (g (make-moving-max 3))) (do ((i 0 (+ i 1))) ((= i 15)) (set! (odata i) (moving-max g (data i)))) (if (not (vequal odata (float-vector 1.000 1.000 1.100 1.100 1.100 1.100 1.100 1.100 1.000 1.000 0.500 0.020 0.020 0.000 0.000))) (snd-display #__line__ ";moving max odata: ~A" odata)) (if (= (odata 4) (odata 7)) (snd-display #__line__ ";moving-max .0001 offset?")) (set! odata (make-float-vector 15 0.0)) (set! data (float-vector 0.1 -0.2 0.3 0.4 -0.5 0.6 0.7 0.8 -0.9 1.0 0.0 0.0)) (set! g (make-moving-sum 3)) (do ((i 0 (+ i 1))) ((= i 12)) (set! (odata i) (moving-sum g (data i)))) (if (not (vequal odata (float-vector 0.100 0.300 0.600 0.900 1.200 1.500 1.800 2.100 2.400 2.700 1.900 1.000 0.000 0.000 0.000))) (snd-display #__line__ ";moving-sum odata: ~A" odata)) (set! odata (make-float-vector 15 0.0)) (set! g (make-moving-rms 4)) (do ((i 0 (+ i 1))) ((= i 12)) (set! (odata i) (moving-rms g (data i)))) (if (not (vequal odata (float-vector 0.050 0.112 0.187 0.274 0.367 0.464 0.561 0.660 0.758 0.857 0.783 0.673 0.000 0.000 0.000))) (snd-display #__line__ ";moving-rms odata: ~A" odata)) (set! odata (make-float-vector 15 0.0)) (set! g (make-moving-length 4)) (do ((i 0 (+ i 1))) ((= i 12)) (set! (odata i) (moving-length g (data i)))) (if (not (vequal odata (float-vector 0.100 0.224 0.374 0.548 0.735 0.927 1.122 1.319 1.517 1.715 1.565 1.345 0.000 0.000 0.000))) (snd-display #__line__ ";moving-length odata: ~A" odata)) (let ((ind (new-sound "test.snd" :size 20))) (set! (sample 3) 1.0) (let ((gen1 (make-weighted-moving-average 4)) (gen2 (make-fir-filter 4 (float-vector 0.4 0.3 0.2 0.1)))) (map-channel (lambda (y) (weighted-moving-average gen1 y))) (let ((data1 (channel->float-vector))) (undo) (map-channel (lambda (y) (fir-filter gen2 y))) (let ((data2 (channel->float-vector))) (if (not (vequal data1 data2)) (snd-display #__line__ ";weighted-moving-average and fir:~%; ~A~%: ~A" data1 data2))) (undo))) (close-sound ind)) (do ((i 0 (+ i 1))) ((= i 10)) (set! (data i) (mus-random 0.5))) (set! g (make-moving-length 4)) (do ((i 0 (+ i 1))) ((= i 12)) (set! (odata i) (moving-length g (data i)))) (do ((i -3 (+ i 1)) (k 0 (+ k 1))) ((= i 8)) (let ((sum 0.0)) (do ((j 0 (+ j 1))) ((= j 4)) (if (>= (+ i j) 0) (set! sum (+ sum (* (data (+ i j)) (data (+ i j))))))) (if (fneq (odata k) (sqrt sum)) (snd-display #__line__ ";moving length ran: ~A ~A" (odata k) (sqrt sum))))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (data i) (mus-random 0.5))) (set! g (make-moving-sum 4)) (do ((i 0 (+ i 1))) ((= i 12)) (set! (odata i) (moving-sum g (data i)))) (do ((i -3 (+ i 1)) (k 0 (+ k 1))) ((= i 8)) (let ((sum 0.0)) (do ((j 0 (+ j 1))) ((= j 4)) (if (>= (+ i j) 0) (set! sum (+ sum (abs (data (+ i j))))))) (if (fneq (odata k) sum) (snd-display #__line__ ";moving sum ran: ~A ~A" (odata k) sum)))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (data i) (mus-random 0.5))) (set! g (make-moving-rms 4)) (do ((i 0 (+ i 1))) ((= i 12)) (set! (odata i) (moving-rms g (data i)))) (do ((i -3 (+ i 1)) (k 0 (+ k 1))) ((= i 8)) (let ((sum 0.0)) (do ((j 0 (+ j 1))) ((= j 4)) (if (>= (+ i j) 0) (set! sum (+ sum (* (data (+ i j)) (data (+ i j))))))) (if (fneq (odata k) (sqrt (/ sum 4))) (snd-display #__line__ ";moving rms ran: ~A ~A" (odata k) (sqrt (/ sum 4))))))) (let ((ind (open-sound "oboe.snd"))) (harmonicizer 550.0 (list 1 .5 2 .3 3 .2) 10) (close-sound ind)) (let ((arglist ())) (do ((i 0 (+ i 1))) ((= i 16)) (set! arglist (cons 440.0 (cons :frequency arglist)))) (set! arglist (reverse arglist)) (for-each (lambda (make name) (let ((tag (catch #t (lambda () (apply make arglist)) (lambda args (car args))))) (if (not (eq? tag 'mus-error)) (snd-display #__line__ ";long arglist to ~A: ~A" name tag)))) (list make-wave-train make-polyshape make-delay make-moving-average make-moving-max make-moving-norm make-comb make-filtered-comb make-notch make-rand make-rand-interp make-table-lookup make-env make-readin make-locsig make-granulate make-convolve make-phase-vocoder) (list 'make-wave-train 'make-polyshape 'make-delay 'make-moving-average 'make-moving-max 'make-moving-norm 'make-comb 'make-filtered-comb 'make-notch 'make-rand 'make-rand-interp 'make-table-lookup 'make-env 'make-readin 'make-locsig 'make-granulate 'make-convolve 'make-phase-vocoder))) (let ((v1 (make-float-vector 10 .1))) (let ((g1 (make-table-lookup :wave v1))) (if (not (eq? v1 (mus-data g1))) (snd-display #__line__ ";table-lookup data not eq?: ~A ~A" v1 (mus-data g1))) (if (not (eqv? v1 (mus-data g1))) (snd-display #__line__ ";table-lookup data not eqv?: ~A ~A" v1 (mus-data g1))) (if (not (equal? v1 (mus-data g1))) (snd-display #__line__ ";table-lookup data not equal?: ~A ~A" v1 (mus-data g1))) (set! (v1 1) .3) (if (fneq ((mus-data g1) 1) .3) (snd-display #__line__ ";table-lookup float-vectorset: ~A ~A" (v1 1) ((mus-data g1) 1))) (float-vector-set! (mus-data g1) 1 .5) (if (fneq (v1 1) .5) (snd-display #__line__ ";table-lookup float-vectorref: ~A ~A" (v1 1) ((mus-data g1) 1)))) (let ((g1 (make-wave-train :wave v1))) (if (not (eq? v1 (mus-data g1))) (snd-display #__line__ ";wave-train data not eq?: ~A ~A" v1 (mus-data g1))) (if (not (eqv? v1 (mus-data g1))) (snd-display #__line__ ";wave-train data not eqv?: ~A ~A" v1 (mus-data g1))) (if (not (equal? v1 (mus-data g1))) (snd-display #__line__ ";wave-train data not equal?: ~A ~A" v1 (mus-data g1))) (set! (v1 1) .3) (if (fneq ((mus-data g1) 1) .3) (snd-display #__line__ ";wave-train float-vectorset: ~A ~A" (v1 1) ((mus-data g1) 1))) (float-vector-set! (mus-data g1) 1 .5) (if (fneq (v1 1) .5) (snd-display #__line__ ";wave-train float-vectorref: ~A ~A" (v1 1) ((mus-data g1) 1)))) (let ((g1 (make-polyshape :coeffs v1))) (if (not (eq? v1 (mus-data g1))) (snd-display #__line__ ";polyshape data not eq?: ~A ~A" v1 (mus-data g1))) (if (not (eqv? v1 (mus-data g1))) (snd-display #__line__ ";polyshape data not eqv?: ~A ~A" v1 (mus-data g1))) (if (not (equal? v1 (mus-data g1))) (snd-display #__line__ ";polyshape data not equal?: ~A ~A" v1 (mus-data g1))) (set! (v1 1) .3) (if (fneq ((mus-data g1) 1) .3) (snd-display #__line__ ";polyshape float-vectorset: ~A ~A" (v1 1) ((mus-data g1) 1))) (float-vector-set! (mus-data g1) 1 .5) (if (fneq (v1 1) .5) (snd-display #__line__ ";polyshape float-vectorref: ~A ~A" (v1 1) ((mus-data g1) 1)))) (let ((g1 (make-delay :initial-contents v1))) (if (not (eq? v1 (mus-data g1))) (snd-display #__line__ ";delay data not eq?: ~A ~A" v1 (mus-data g1))) (if (not (eqv? v1 (mus-data g1))) (snd-display #__line__ ";delay data not eqv?: ~A ~A" v1 (mus-data g1))) (if (not (equal? v1 (mus-data g1))) (snd-display #__line__ ";delay data not equal?: ~A ~A" v1 (mus-data g1))) (set! (v1 1) .3) (if (fneq ((mus-data g1) 1) .3) (snd-display #__line__ ";delay float-vectorset: ~A ~A" (v1 1) ((mus-data g1) 1))) (float-vector-set! (mus-data g1) 1 .5) (if (fneq (v1 1) .5) (snd-display #__line__ ";delay float-vectorref: ~A ~A" (v1 1) ((mus-data g1) 1)))) (let ((g1 (make-filtered-comb :scaler .5 :initial-contents v1 :filter (make-one-zero .1 .2)))) (if (not (eq? v1 (mus-data g1))) (snd-display #__line__ ";filtered-comb data not eq?: ~A ~A" v1 (mus-data g1))) (if (not (eqv? v1 (mus-data g1))) (snd-display #__line__ ";filtered-comb data not eqv?: ~A ~A" v1 (mus-data g1))) (if (not (equal? v1 (mus-data g1))) (snd-display #__line__ ";filtered-comb data not equal?: ~A ~A" v1 (mus-data g1))) (set! (v1 1) .3) (if (fneq ((mus-data g1) 1) .3) (snd-display #__line__ ";filtered-comb float-vectorset: ~A ~A" (v1 1) ((mus-data g1) 1))) (float-vector-set! (mus-data g1) 1 .5) (if (fneq (v1 1) .5) (snd-display #__line__ ";filtered-comb float-vectorref: ~A ~A" (v1 1) ((mus-data g1) 1)))) (let ((g1 (make-rand :distribution v1))) (if (not (eq? v1 (mus-data g1))) (snd-display #__line__ ";rand data not eq?: ~A ~A" v1 (mus-data g1))) (if (not (eqv? v1 (mus-data g1))) (snd-display #__line__ ";rand data not eqv?: ~A ~A" v1 (mus-data g1))) (if (not (equal? v1 (mus-data g1))) (snd-display #__line__ ";rand data not equal?: ~A ~A" v1 (mus-data g1))) (set! (v1 1) .3) (if (fneq ((mus-data g1) 1) .3) (snd-display #__line__ ";rand float-vectorset: ~A ~A" (v1 1) ((mus-data g1) 1))) (float-vector-set! (mus-data g1) 1 .5) (if (fneq (v1 1) .5) (snd-display #__line__ ";rand float-vectorref: ~A ~A" (v1 1) ((mus-data g1) 1)))) (let ((g1 (make-fir-filter :xcoeffs v1))) (if (not (eq? v1 (mus-xcoeffs g1))) (snd-display #__line__ ";fir-filter xcoeffs not eq?: ~A ~A" v1 (mus-xcoeffs g1))) (if (not (eqv? v1 (mus-xcoeffs g1))) (snd-display #__line__ ";fir-filter xcoeffs not eqv?: ~A ~A" v1 (mus-xcoeffs g1))) (if (not (equal? v1 (mus-xcoeffs g1))) (snd-display #__line__ ";fir-filter xcoeffs not equal?: ~A ~A" v1 (mus-xcoeffs g1))) (set! (v1 1) .3) (if (fneq ((mus-xcoeffs g1) 1) .3) (snd-display #__line__ ";fir-filter float-vectorset: ~A ~A" (v1 1) ((mus-xcoeffs g1) 1))) (float-vector-set! (mus-xcoeffs g1) 1 .5) (if (fneq (v1 1) .5) (snd-display #__line__ ";fir-filter float-vectorref: ~A ~A" (v1 1) ((mus-xcoeffs g1) 1)))) (let ((g1 (make-iir-filter :ycoeffs v1))) (if (not (eq? v1 (mus-ycoeffs g1))) (snd-display #__line__ ";iir-filter ycoeffs not eq?: ~A ~A" v1 (mus-ycoeffs g1))) (if (not (eqv? v1 (mus-ycoeffs g1))) (snd-display #__line__ ";iir-filter ycoeffs not eqv?: ~A ~A" v1 (mus-ycoeffs g1))) (if (not (equal? v1 (mus-ycoeffs g1))) (snd-display #__line__ ";iir-filter ycoeffs not equal?: ~A ~A" v1 (mus-ycoeffs g1))) (set! (v1 1) .3) (if (fneq ((mus-ycoeffs g1) 1) .3) (snd-display #__line__ ";iir-filter float-vectorset: ~A ~A" (v1 1) ((mus-ycoeffs g1) 1))) (float-vector-set! (mus-ycoeffs g1) 1 .5) (if (fneq (v1 1) .5) (snd-display #__line__ ";iir-filter float-vectorref: ~A ~A" (v1 1) ((mus-ycoeffs g1) 1)))) ) (let ((tanh-1 (lambda (x) (+ x (* -1/3 x x x) (* 2/15 x x x x x) (* -17/315 x x x x x x x) (* 62/2835 x x x x x x x x x) (* -1382/155925 x x x x x x x x x x x)))) (tanh-2 (lambda (y) (let ((x (sin y)) (x3 (sin (* 3 y))) (x5 (sin (* 5 y))) (x7 (sin (* 7 y))) (x9 (sin (* 9 y))) (x11 (sin (* 11 y)))) (+ (* 140069/172800 x) (* 13319/241920 x3) (* 1973/483840 x5) (* 799/1451520 x7) (* -71/7257600 x9) (* 691/79833600 x11)))))) (for-each (lambda (x) (let ((val (tanh (sin x))) (val1 (tanh-1 (sin x))) (val2 (tanh-2 x))) (if (or (fneq val val1) (fneq val1 val2)) (snd-display #__line__ ";tanh(~A): ~A ~A ~A" x val val1 val2)))) (list 1.0 0.1 0.1 0.333))) (if all-args (let ((maxerr 0.0) (max-case #f) (cases 0)) (do ((n 1 (+ n 1))) ((= n 100)) (do ((m 1 (+ m 1))) ((= m 4)) (let ((val (sin (/ (* m pi) n))) (expr (sin-m*pi/n m n))) (if expr (let ((err (magnitude (- val (eval expr))))) (set! cases (+ cases 1)) (if (> err maxerr) (begin (set! maxerr err) (set! max-case (/ m n))))))))) (if (> maxerr 1e-12) (snd-display #__line__ "sin-m*pi/n (~A cases) max err ~A at ~A~%" cases maxerr max-case)))) (let ((tag (catch #t (lambda () (with-sound () (outa -1 .1))) (lambda args (car args))))) (if (not (eq? tag 'out-of-range)) (snd-display #__line__ ";outa -1 -> ~A" tag))) (let ((tag (catch #t (lambda () (let ((v (with-sound ((make-float-vector 10)) (outa -1 .1)))) v)) (lambda args (car args))))) (if (not (eq? tag 'out-of-range)) (snd-display #__line__ ";outa (float-vector) -1 -> ~A" tag))) (let ((tag (catch #t (lambda () (let ((v (with-sound ((make-float-vector (list 1 10) 0.0)) (outa -1 .1)))) v)) (lambda args (car args))))) (if (not (eq? tag 'out-of-range)) (snd-display #__line__ ";outa (vector 2) -1 -> ~A" tag))) (let ((v (with-sound () (catch #t (lambda () (outa -1 .1)) (lambda args 'error))))) (if (file-exists? v) (begin (if (> (cadr (mus-sound-maxamp v)) 0.0) (snd-display #__line__ ";outa to file at -1: ~A" v)) (if (> (mus-sound-chans v) 1) (snd-display #__line__ ";outa to file at -1 chans: ~A" (mus-sound-chans v))) (if (find-sound v) (close-sound (find-sound v))) (delete-file v)))) (let ((v (with-sound ((make-float-vector 10)) (catch #t (lambda () (outa -1 .1)) (lambda args 'error))))) (if (> (float-vector-peak v) 0.0) (snd-display #__line__ ";outa to float-vector at -1: ~A" v))) (let ((v (with-sound ((make-float-vector (list 1 10) 0.0)) (catch #t (lambda () (outa -1 .1)) (lambda args 'error))))) (if (> (maxamp v) 0.0) (snd-display #__line__ ";outa to vector1 at -1: ~A" v))) (if (not (= (signum 0) 0)) (snd-display #__line__ ";signum 0: ~A" (signum 0))) (if (not (= (signum 10) 1)) (snd-display #__line__ ";signum 10: ~A" (signum 10))) (if (not (= (signum -32) -1)) (snd-display #__line__ ";signum -32: ~A" (signum -32))) (let ((c1 (make-comb .5 3)) (c2 (make-comb-bank (vector (make-comb .5 3))))) (do ((i 0 (+ i 1)) (x 1.0 0.0)) ((= i 20)) (let ((x0 (comb c1 x)) (x1 (comb-bank c2 x))) (if (not (morally-equal? x0 x1)) (snd-display #__line__ ";(comb .5 3) ~A, comb: ~A, bank: ~A" i x0 x1))))) (let ((c1 (make-comb .5 3)) (c2 (make-comb .2 10)) (c3 (make-comb-bank (vector (make-comb .5 3) (make-comb .2 10))))) (do ((i 0 (+ i 1)) (x 1.0 0.0)) ((= i 30)) (let ((x0 (+ (comb c1 x) (comb c2 x))) (x1 (comb-bank c3 x))) (if (not (morally-equal? x0 x1)) (snd-display #__line__ ";(comb .5 3) + (comb .2 10) ~A, comb: ~A, bank: ~A" i x0 x1))))) (let ((c1 (make-comb .5 3)) (c2 (make-comb .2 10)) (c3 (make-comb -.7 11)) (c4 (make-comb-bank (vector (make-comb .5 3) (make-comb .2 10) (make-comb -.7 11))))) (do ((i 0 (+ i 1)) (x 1.0 0.0)) ((= i 40)) (let ((x0 (+ (comb c1 x) (comb c2 x) (comb c3 x))) (x1 (comb-bank c4 x))) (if (not (morally-equal? x0 x1)) (snd-display #__line__ ";(comb .5 3) + (comb .2 10) + (comb -.7 11) ~A, comb: ~A, bank: ~A" i x0 x1))))) (let ((c1 (make-all-pass -.5 .5 3)) (c2 (make-all-pass-bank (vector (make-all-pass -.5 .5 3))))) (do ((i 0 (+ i 1)) (x 1.0 0.0)) ((= i 20)) (let ((x0 (all-pass c1 x)) (x1 (all-pass-bank c2 x))) (if (not (morally-equal? x0 x1)) (snd-display #__line__ ";(all-pass -.5 .5 3) ~A, all-pass: ~A, bank: ~A" i x0 x1))))) (let ((c1 (make-all-pass -.5 .5 3)) (c2 (make-all-pass -.2 .2 10)) (c3 (make-all-pass-bank (vector (make-all-pass -.5 .5 3) (make-all-pass -.2 .2 10))))) (do ((i 0 (+ i 1)) (x 1.0 0.0)) ((= i 30)) (let ((x0 (all-pass c1 (all-pass c2 x))) (x1 (all-pass-bank c3 x))) (if (not (morally-equal? x0 x1)) (snd-display #__line__ ";(all-pass -.5 .5 3) + (all-pass -.2 .2 10) ~A, all-pass: ~A, bank: ~A" i x0 x1))))) (let ((c1 (make-all-pass -.5 .5 3)) (c2 (make-all-pass -.2 .2 10)) (c3 (make-all-pass -.7 .1 11)) (c4 (make-all-pass-bank (vector (make-all-pass -.5 .5 3) (make-all-pass -.2 .2 10) (make-all-pass -.7 .1 11))))) (do ((i 0 (+ i 1)) (x 1.0 0.0)) ((= i 40)) (let ((x0 (all-pass c1 (all-pass c2 (all-pass c3 x)))) (x1 (all-pass-bank c4 x))) (if (not (morally-equal? x0 x1)) (snd-display #__line__ ";(all-pass -.5 .5 3) + (all-pass -.2 .2 10) + (all-pass -.7 .1 11) ~A, all-pass: ~A, bank: ~A" i x0 x1))))) (let ((c1 (make-filtered-comb .5 3)) (c2 (make-filtered-comb-bank (vector (make-filtered-comb .5 3))))) (do ((i 0 (+ i 1)) (x 1.0 0.0)) ((= i 20)) (let ((x0 (filtered-comb c1 x)) (x1 (filtered-comb-bank c2 x))) (if (not (morally-equal? x0 x1)) (snd-display #__line__ ";(filtered-comb .5 3) ~A, filtered-comb: ~A, bank: ~A" i x0 x1))))) (let ((c1 (make-filtered-comb .5 3)) (c2 (make-filtered-comb .2 10)) (c3 (make-filtered-comb-bank (vector (make-filtered-comb .5 3) (make-filtered-comb .2 10))))) (do ((i 0 (+ i 1)) (x 1.0 0.0)) ((= i 30)) (let ((x0 (+ (filtered-comb c1 x) (filtered-comb c2 x))) (x1 (filtered-comb-bank c3 x))) (if (not (morally-equal? x0 x1)) (snd-display #__line__ ";(filtered-comb .5 3) + (filtered-comb .2 10) ~A, filtered-comb: ~A, bank: ~A" i x0 x1))))) (let ((c1 (make-filtered-comb .5 3)) (c2 (make-filtered-comb .2 10)) (c3 (make-filtered-comb -.7 11)) (c4 (make-filtered-comb-bank (vector (make-filtered-comb .5 3) (make-filtered-comb .2 10) (make-filtered-comb -.7 11))))) (do ((i 0 (+ i 1)) (x 1.0 0.0)) ((= i 40)) (let ((x0 (+ (filtered-comb c1 x) (filtered-comb c2 x) (filtered-comb c3 x))) (x1 (filtered-comb-bank c4 x))) (if (not (morally-equal? x0 x1)) (snd-display #__line__ ";(filtered-comb .5 3) + (filtered-comb .2 10) + (filtered-comb -.7 11) ~A, filtered-comb: ~A, bank: ~A" i x0 x1))))) ;; make-formant-bank tests (let ((c1 (make-formant 440.0 .5)) (c2 (make-formant-bank (vector (make-formant 440.0 .5))))) (do ((i 0 (+ i 1)) (x 1.0 0.0)) ((= i 40)) (let ((x0 (formant c1 x)) (x1 (formant-bank c2 x))) (if (not (morally-equal? x0 x1)) (snd-display #__line__ ";(formant 440.0 .5) ~A, formant: ~A, bank: ~A" i x0 x1))))) (let ((c1 (make-formant 440.0 .5)) (c2 (make-formant 1000.0 .2)) (c3 (make-formant-bank (vector (make-formant 440.0 .5) (make-formant 1000.0 .2))))) (do ((i 0 (+ i 1)) (x 1.0 0.0)) ((= i 40)) (let ((x0 (+ (formant c1 x) (formant c2 x))) (x1 (formant-bank c3 x))) (if (not (morally-equal? x0 x1)) (snd-display #__line__ ";(formant 440.0 .5) + (formant 1000.0 .2) ~A, formant: ~A, bank: ~A" i x0 x1))))) (let ((c1 (make-formant 440.0 .5)) (c2 (make-formant 1000.0 .2)) (c3 (make-formant 34.0 .1)) (c4 (make-formant-bank (vector (make-formant 440.0 .5) (make-formant 1000.0 .2) (make-formant 34.0 .1))))) (do ((i 0 (+ i 1)) (x 1.0 0.0)) ((= i 40)) (let ((x0 (+ (formant c1 x) (formant c2 x) (formant c3 x))) (x1 (formant-bank c4 x))) (if (not (morally-equal? x0 x1)) (snd-display #__line__ ";(formant 440.0 .5) + (formant 1000.0 .2) + (formant 34.0 .1) ~A, formant: ~A, bank: ~A" i x0 x1))))) (let ((c1 (make-formant 440.0 .75)) (c2 (make-formant 1000.0 .75)) (c3 (make-formant 34.0 .75)) (c4 (make-formant-bank (vector (make-formant 440.0 .75) (make-formant 1000.0 .75) (make-formant 34.0 .75))))) (do ((i 0 (+ i 1)) (x 1.0 0.0)) ((= i 40)) (let ((x0 (+ (formant c1 x) (formant c2 x) (formant c3 x))) (x1 (formant-bank c4 x))) (if (not (morally-equal? x0 x1)) (snd-display #__line__ ";(formant 440.0 .75) + (formant 1000.0 .75) + (formant 34.0 .75) ~A, formant: ~A, bank: ~A" i x0 x1))))) (let ((c1 (make-formant 440.0 .5)) (c2 (make-formant 1000.0 .2)) (c3 (make-formant 34.0 .1)) (c4 (make-formant-bank (vector (make-formant 440.0 .5) (make-formant 1000.0 .2) (make-formant 34.0 .1)) (float-vector .5 .3 .4)))) (do ((i 0 (+ i 1)) (x 1.0 0.0)) ((= i 40)) (let ((x0 (+ (* .5 (formant c1 x)) (* .3 (formant c2 x)) (* .4 (formant c3 x)))) (x1 (formant-bank c4 x))) (if (not (morally-equal? x0 x1)) (snd-display #__line__ ";fb 3 with amps at ~A, formant: ~A, bank: ~A" i x0 x1))))) (let ((c1 (make-formant 440.0 .9)) (c2 (make-formant 1000.0 .9)) (c3 (make-formant 34.0 .9)) (c4 (make-formant-bank (vector (make-formant 440.0 .9) (make-formant 1000.0 .9) (make-formant 34.0 .9)) (float-vector .5 .3 .4)))) (do ((i 0 (+ i 1)) (x 1.0 0.0)) ((= i 40)) (let ((x0 (+ (* .5 (formant c1 x)) (* .3 (formant c2 x)) (* .4 (formant c3 x)))) (x1 (formant-bank c4 x))) (if (not (morally-equal? x0 x1)) (snd-display #__line__ ";fb 3 with amps c1_c2 at ~A, formant: ~A, bank: ~A" i x0 x1))))) (let ((c1 (make-formant 440.0 .5)) (c2 (make-formant 1000.0 .2)) (c3 (make-formant 34.0 .1)) (inputs (make-float-vector 3 1.0)) (c4 (make-formant-bank (vector (make-formant 440.0 .5) (make-formant 1000.0 .2) (make-formant 34.0 .1))))) (do ((i 0 (+ i 1)) (x 1.0 0.0)) ((= i 40)) (let ((x0 (+ (formant c1 x) (formant c2 x) (formant c3 x))) (x1 (formant-bank c4 inputs))) (fill! inputs 0.0) (if (not (morally-equal? x0 x1)) (snd-display #__line__ ";many (formant 440.0 .5) + (formant 1000.0 .2) + (formant 34.0 .1) ~A, formant: ~A, bank: ~A" i x0 x1))))) (let ((c1 (make-formant 440.0 .75)) (c2 (make-formant 1000.0 .75)) (c3 (make-formant 34.0 .75)) (inputs (make-float-vector 3 1.0)) (c4 (make-formant-bank (vector (make-formant 440.0 .75) (make-formant 1000.0 .75) (make-formant 34.0 .75))))) (do ((i 0 (+ i 1)) (x 1.0 0.0)) ((= i 40)) (let ((x0 (+ (formant c1 x) (formant c2 x) (formant c3 x))) (x1 (formant-bank c4 inputs))) (fill! inputs 0.0) (if (not (morally-equal? x0 x1)) (snd-display #__line__ ";many (formant 440.0 .75) + (formant 1000.0 .75) + (formant 34.0 .75) ~A, formant: ~A, bank: ~A" i x0 x1))))) (let ((c1 (make-formant 440.0 .5)) (c2 (make-formant 1000.0 .2)) (c3 (make-formant 34.0 .1)) (inputs (make-float-vector 3 1.0)) (c4 (make-formant-bank (vector (make-formant 440.0 .5) (make-formant 1000.0 .2) (make-formant 34.0 .1)) (float-vector .5 .3 .4)))) (do ((i 0 (+ i 1)) (x 1.0 0.0)) ((= i 40)) (let ((x0 (+ (* .5 (formant c1 x)) (* .3 (formant c2 x)) (* .4 (formant c3 x)))) (x1 (formant-bank c4 inputs))) (fill! inputs 0.0) (if (not (morally-equal? x0 x1)) (snd-display #__line__ ";fb 3 with amps at ~A, formant: ~A, bank: ~A" i x0 x1))))) (let ((c1 (make-formant 440.0 .9)) (c2 (make-formant 1000.0 .9)) (c3 (make-formant 34.0 .9)) (inputs (make-float-vector 3 1.0)) (c4 (make-formant-bank (vector (make-formant 440.0 .9) (make-formant 1000.0 .9) (make-formant 34.0 .9)) (float-vector .5 .3 .4)))) (do ((i 0 (+ i 1)) (x 1.0 0.0)) ((= i 40)) (let ((x0 (+ (* .5 (formant c1 x)) (* .3 (formant c2 x)) (* .4 (formant c3 x)))) (x1 (formant-bank c4 inputs))) (fill! inputs 0.0) (if (not (morally-equal? x0 x1)) (snd-display #__line__ ";fb 3 with amps c1_c2 at ~A, formant: ~A, bank: ~A" i x0 x1))))) (let ((c1 (make-formant 440.0 .9)) (c2 (make-formant 1000.0 .9)) (c3 (make-formant 34.0 .9)) (inputs (make-float-vector 3 1.0)) (c4 (make-formant-bank (vector (make-formant 440.0 .9) (make-formant 1000.0 .9) (make-formant 34.0 .9)) (float-vector .5 .3 .4)))) (do ((i 0 (+ i 1)) (x 1.0 0.0) (y 1.0 0.0) (z 1.0 0.0)) ((= i 40)) (if (< i 10) (let ((x0 (+ (* .5 (formant c1 x)) (* .3 (formant c2 y)) (* .4 (formant c3 z)))) (x1 (formant-bank c4 inputs))) (fill! inputs 0.0) (if (not (morally-equal? x0 x1)) (snd-display #__line__ ";fb 3(1) with amps c1_c2 at ~A, formant: ~A, bank: ~A" i x0 x1))) (if (< i 20) (let ((x0 (+ (* .5 (formant c1 x)) (* .3 (formant c2 y)) (* .4 (formant c3 z)))) (x1 (formant-bank c4 0.0))) (if (not (morally-equal? x0 x1)) (snd-display #__line__ ";fb 3(2) with amps c1_c2 at ~A, formant: ~A, bank: ~A" i x0 x1))) (if (< i 30) (begin (set! x 0.5) (set! y 0.25) (set! z 0.125) (set! (inputs 0) x) (set! (inputs 1) y) (set! (inputs 2) z) (let ((x0 (+ (* .5 (formant c1 x)) (* .3 (formant c2 y)) (* .4 (formant c3 z)))) (x1 (formant-bank c4 inputs))) (if (not (morally-equal? x0 x1)) (snd-display #__line__ ";fb 3(3) with amps c1_c2 at ~A, formant: ~A, bank: ~A" i x0 x1)))) (begin (set! x 0.25) (set! y 0.25) (set! z 0.25) (let ((x0 (+ (* .5 (formant c1 x)) (* .3 (formant c2 y)) (* .4 (formant c3 z)))) (x1 (formant-bank c4 .25))) (if (not (morally-equal? x0 x1)) (snd-display #__line__ ";fb 3(4) with amps c1_c2 at ~A, formant: ~A, bank: ~A" i x0 x1))))))))) (let ((c1 (make-formant 440.0 .9)) (c2 (make-formant 1000.0 .9)) (c3 (make-formant 34.0 .9)) (c4 (make-formant 340.0 .9)) (c5 (make-formant 2000.0 .9)) (inputs (make-float-vector 5 1.0)) (c6 (make-formant-bank (vector (make-formant 440.0 .9) (make-formant 1000.0 .9) (make-formant 34.0 .9) (make-formant 340.0 .9) (make-formant 2000.0 .9))))) (do ((i 0 (+ i 1)) (x 1.0 0.0) (y 1.0 0.0) (z 1.0 0.0) (a 1.0 0.0) (b 1.0 0.0)) ((= i 40)) (if (< i 10) (let ((x0 (+ (formant c1 x) (formant c2 y) (formant c3 z) (formant c4 a) (formant c5 b))) (x1 (formant-bank c6 inputs))) (fill! inputs 0.0) (if (not (morally-equal? x0 x1)) (snd-display #__line__ ";fb 5(1) no amps c1_c2 at ~A, formant: ~A, bank: ~A" i x0 x1))) (if (< i 20) (let ((x0 (+ (formant c1 x) (formant c2 y) (formant c3 z) (formant c4 a) (formant c5 b))) (x1 (formant-bank c6 0.0))) (if (not (morally-equal? x0 x1)) (snd-display #__line__ ";fb 5(2) no amps c1_c2 at ~A, formant: ~A, bank: ~A" i x0 x1))) (if (< i 30) (begin (set! x 0.5) (set! y 0.25) (set! z 0.125) (set! a .1) (set! b .3) (set! (inputs 0) x) (set! (inputs 1) y) (set! (inputs 2) z) (set! (inputs 3) a) (set! (inputs 4) b) (let ((x0 (+ (formant c1 x) (formant c2 y) (formant c3 z) (formant c4 a) (formant c5 b))) (x1 (formant-bank c6 inputs))) (if (not (morally-equal? x0 x1)) (snd-display #__line__ ";fb 5(3) no amps c1_c2 at ~A, formant: ~A, bank: ~A" i x0 x1)))) (begin (set! x 0.25) (set! y 0.25) (set! z 0.25) (set! a 0.25) (set! b 0.25) (let ((x0 (+ (formant c1 x) (formant c2 y) (formant c3 z) (formant c4 a) (formant c5 b))) (x1 (formant-bank c6 .25))) (if (not (morally-equal? x0 x1)) (snd-display #__line__ ";fb 5(4) no amps c1_c2 at ~A, formant: ~A, bank: ~A" i x0 x1))))))))) (set! *clm-srate* 44100) (if (file-exists? "jcrev-ip.snd") (begin (with-sound (:reverb jc-reverb) (outa 0 .1) (outa 0 .5 *reverb*)) (let ((s1 (find-sound "test.snd")) (s2 (open-sound "jcrev-ip.snd"))) (if (not (= (channel-distance s1 0 s2 0) 0.0)) (snd-display #__line__ ";jcrev ip: ~A" (channel-distance s1 0 s2 0))) (close-sound s1) (close-sound s2)))) (if (file-exists? "nrev-ip.snd") (begin (with-sound (:reverb nrev) (outa 0 .1) (outa 0 .5 *reverb*)) (let ((s1 (find-sound "test.snd")) (s2 (open-sound "nrev-ip.snd"))) (if (not (= (channel-distance s1 0 s2 0) 0.0)) (snd-display #__line__ ";nrev ip: ~A" (channel-distance s1 0 s2 0))) (close-sound s1) (close-sound s2)))) (if (file-exists? "freeverb-ip.snd") (begin (with-sound (:reverb freeverb :reverb-data '(:output-gain 3.0)) (outa 0 .5 *reverb*)) (let ((s1 (find-sound "test.snd")) (s2 (open-sound "freeverb-ip.snd"))) (if (not (= (channel-distance s1 0 s2 0) 0.0)) (snd-display #__line__ ";freeverb ip: ~A" (channel-distance s1 0 s2 0))) (close-sound s1) (close-sound s2)))) (let () (defgenerator (old-rxyk!sin :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) g)) (frequency *clm-default-frequency*) (ratio 1.0) (r 0.5) (angle 0.0) fm) (define* (old-rxyk!sin gen (fm 0.0)) (set! (gen 'fm) fm) (with-let gen (let* ((x angle) (y (* x ratio))) (set! angle (+ x fm frequency)) (/ (* (exp (* r (cos y))) (sin (+ x (* r (sin y))))) (exp (abs r)))))) (defgenerator (old-rxyk!cos :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) (set! (g 'ar) (/ 1.0 (exp (abs (g 'r))))) g)) (frequency *clm-default-frequency*) (ratio 1.0) (r 0.5) (angle 0.0) fm ar) (define* (old-rxyk!cos gen (fm 0.0)) (set! (gen 'fm) fm) (with-let gen (let* ((x angle) (y (* x ratio))) (set! angle (+ x fm frequency)) (* (exp (* r (cos y))) (cos (+ x (* r (sin y)))) ar)))) (define-macro (define-memoized name&arg . body) (let ((arg (cadr name&arg)) (memo (gensym "memo"))) `(define ,(car name&arg) (let ((,memo (make-hash-table))) (lambda (,arg) (or (,memo ,arg) ; check for saved value (set! (,memo ,arg) (begin ,@body)))))))) ; set! returns the new value (define-memoized (kfactorial n) (define (k n m) (if (<= n m) n (* (k n (* 2 m)) (k (- n m) (* 2 m))))) (if (zero? n) 1 (k n 1))) (define (rxyk!cos-direct x y a terms) (let ((sum 0.0)) (do ((k 0 (+ k 1))) ((= k terms) (/ sum (exp (abs a)))) (set! sum (+ sum (* (/ (expt a k) (kfactorial k)) (cos (+ x (* k y))))))))) (define (rxyk!sin-direct x y a terms) (let ((sum 0.0)) (do ((k 0 (+ k 1))) ((= k terms) (/ sum (exp (abs a)))) (set! sum (+ sum (* (/ (expt a k) (kfactorial k)) (sin (+ x (* k y))))))))) (let ((g1 (make-rxyk!cos 100.0)) (g2 (make-old-rxyk!cos 100.0)) (x3 (hz->radians 100.0))) (do ((i 0 (+ i 1)) (x 0.0 (+ x x3))) ((= i 100)) (let ((v1 (rxyk!cos g1)) (v2 (old-rxyk!cos g2)) (v3 (rxyk!cos-direct x x 0.5 12))) (if (or (> (abs (- v1 v2)) 1e-6) (> (abs (- v1 v3)) 1e-6)) (format #t ";rxyk!cos ~A ~A: ~A ~A ~A -> ~A~%" i x v1 v2 v3 (max (abs (- v1 v2)) (abs (- v1 v3)))))))) (let ((g1 (make-rxyk!sin 100.0)) (g2 (make-old-rxyk!sin 100.0)) (x3 (hz->radians 100.0))) (do ((i 0 (+ i 1)) (x 0.0 (+ x x3))) ((= i 100)) (let ((v1 (rxyk!sin g1)) (v2 (old-rxyk!sin g2)) (v3 (rxyk!sin-direct x x 0.5 12))) (if (or (> (abs (- v1 v2)) 1e-6) (> (abs (- v1 v3)) 1e-6)) (format #t ";rxyk!sin ~A ~A: ~A ~A ~A -> ~A~%" i x v1 v2 v3 (max (abs (- v1 v2)) (abs (- v1 v3)))))))) (let ((g1 (make-rxyk!cos 100.0 :ratio 2.0 :r 0.25)) (g2 (make-old-rxyk!cos 100.0 :ratio 2.0 :r 0.25))) (do ((i 0 (+ i 1))) ((= i 100)) (let ((v1 (rxyk!cos g1)) (v2 (old-rxyk!cos g2))) (if (> (abs (- v1 v2)) 1e-6) (format #t ";rxyk!cos ratio:2: ~A: ~A ~A -> ~A~%" i v1 v2 (abs (- v1 v2))))))) (let ((g1 (make-rxyk!sin 100.0 :ratio 2.0 :r 0.25)) (g2 (make-old-rxyk!sin 100.0 :ratio 2.0 :r 0.25))) (do ((i 0 (+ i 1))) ((= i 100)) (let ((v1 (rxyk!sin g1)) (v2 (old-rxyk!sin g2))) (if (> (abs (- v1 v2)) 1e-6) (format #t ";rxyk!sin ratio:2: ~A: ~A ~A -> ~A~%" i v1 v2 (abs (- v1 v2))))))) (let ((g1 (make-rxyk!cos 100.0 :ratio 2.0 :r 0.25)) (o1 (make-oscil 400.0)) (g2 (make-old-rxyk!cos 100.0 :ratio 2.0 :r 0.25)) (o2 (make-oscil 400.0))) (do ((i 0 (+ i 1))) ((= i 100)) (let ((v1 (rxyk!cos g1 (oscil o1))) (v2 (old-rxyk!cos g2 (oscil o2)))) (if (> (abs (- v1 v2)) 1e-6) (format #t ";rxyk!cos fm ~A: ~A ~A -> ~A~%" i v1 v2 (abs (- v1 v2))))))) (let ((g1 (make-rxyk!sin 100.0 :ratio 2.0 :r 0.25)) (o1 (make-oscil 400.0)) (g2 (make-old-rxyk!sin 100.0 :ratio 2.0 :r 0.25)) (o2 (make-oscil 400.0))) (do ((i 0 (+ i 1))) ((= i 100)) (let ((v1 (rxyk!sin g1 (oscil o1))) (v2 (old-rxyk!sin g2 (oscil o2)))) (if (> (abs (- v1 v2)) 1e-6) (format #t ";rxyk!sin fm ~A: ~A ~A -> ~A~%" i v1 v2 (abs (- v1 v2)))))))) (let () (defgenerator one-pole-allpass coeff input x1 y1) (define (one-pole-allpass gen input) (set! (gen 'input) input) (with-let gen (set! y1 (+ x1 (* coeff (- input y1)))) (set! x1 input) y1)) (defgenerator one-pole-allpass-bank coeff input x1 y1 x2 y2 x3 y3 x4 y4 x5 y5 x6 y6 x7 y7 x8 y8) (define (one-pole-allpass-bank gen input) (set! (gen 'input) input) (with-let gen (set! y1 (+ x1 (* coeff (- input y1)))) (set! x1 input) (set! y2 (+ x2 (* coeff (- y1 y2)))) (set! x2 y1) (set! y3 (+ x3 (* coeff (- y2 y3)))) (set! x3 y2) (set! y4 (+ x4 (* coeff (- y3 y4)))) (set! x4 y3) (set! y5 (+ x5 (* coeff (- y4 y5)))) (set! x5 y4) (set! y6 (+ x6 (* coeff (- y5 y6)))) (set! x6 y5) (set! y7 (+ x7 (* coeff (- y6 y7)))) (set! x7 y6) (set! y8 (+ x8 (* coeff (- y7 y8)))) (set! x8 y7) y8)) (let ((o1 (make-one-pole-all-pass 1 .5)) (o2 (make-one-pole-allpass .5))) (do ((i 0 (+ i 1)) (impulse 1.0 0.0)) ((= i 30)) (let ((v1 (one-pole-all-pass o1 impulse)) (v2 (one-pole-allpass o2 impulse))) (if (> (abs (- v1 v2)) 1e-6) (format #t ";one-pole-all-pass (1) ~A: ~A ~A -> ~A~%" i v1 v2 (abs (- v1 v2))))))) (let ((o1 (make-one-pole-all-pass 8 .5)) (o2 (make-one-pole-allpass-bank .5))) (do ((i 0 (+ i 1)) (impulse 1.0 0.0)) ((= i 30)) (let ((v1 (one-pole-all-pass o1 impulse)) (v2 (one-pole-allpass-bank o2 impulse))) (if (> (abs (- v1 v2)) 1e-6) (format #t ";one-pole-all-pass (1) ~A: ~A ~A -> ~A~%" i v1 v2 (abs (- v1 v2))))))) ) (let ((old-srate *clm-srate*)) (set! *clm-srate* 44100) (let ((pe (make-pulsed-env '(0 0 1 1 2 0) .0004 2205)) (v (make-float-vector 100))) (do ((i 0 (+ i 1))) ((= i 100)) (set! (v i) (pulsed-env pe))) (if (not (vequal v (float-vector 0.000 0.125 0.250 0.375 0.500 0.625 0.750 0.875 1.000 0.875 0.750 0.625 0.500 0.375 0.250 0.125 0.000 0.000 0.000 0.000 0.000 0.125 0.250 0.375 0.500 0.625 0.750 0.875 1.000 0.875 0.750 0.625 0.500 0.375 0.250 0.125 0.000 0.000 0.000 0.000 0.000 0.125 0.250 0.375 0.500 0.625 0.750 0.875 1.000 0.875 0.750 0.625 0.500 0.375 0.250 0.125 0.000 0.000 0.000 0.000 0.000 0.125 0.250 0.375 0.500 0.625 0.750 0.875 1.000 0.875 0.750 0.625 0.500 0.375 0.250 0.125 0.000 0.000 0.000 0.000 0.000 0.125 0.250 0.375 0.500 0.625 0.750 0.875 1.000 0.875 0.750 0.625 0.500 0.375 0.250 0.125 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";pulsed-env: ~A" v))) (set! *clm-srate* old-srate)) (copy-test (make-oscil 330.0)) (copy-test (make-ncos 440.0 10)) (copy-test (make-nsin 440.0 10)) (copy-test (make-nrxycos 330.0 0.9 10)) (copy-test (make-nrxysin 330.0 0.9 10)) (copy-test (make-rxyk!cos 440.0)) (copy-test (make-rxyk!sin 440.0)) (copy-test (make-sawtooth-wave 100)) (copy-test (make-pulse-train 100)) (copy-test (make-triangle-wave 100)) (copy-test (make-square-wave 100)) (copy-test (make-one-zero .1 .2)) (copy-test (make-one-pole .1 .2)) (copy-test (make-two-zero .9 .1 .2)) (copy-test (make-two-pole .9 .1 .2)) (copy-test (make-polywave 440.0 '(1 .5 2 .5))) (copy-test (make-polyshape 440.0 :coeffs (partials->polynomial '(1 1.0)))) (copy-test (make-oscil-bank (float-vector 100 200 300) (float-vector 0.0 1.0 2.0) (float-vector 0.5 0.25 0.125))) (copy-test (make-delay 10)) (copy-test (make-comb .7 10)) (copy-test (make-notch .7 10)) (copy-test (make-all-pass .8 .7 10)) (copy-test (make-moving-average 10)) (copy-test (make-moving-norm 10)) (copy-test (make-moving-max 10)) (copy-test (make-comb-bank (vector (make-comb 0.742 99) (make-comb 0.733 49) (make-comb 0.715 53)))) (copy-test (make-all-pass-bank (vector (make-all-pass -0.700 0.700 51) (make-all-pass -0.700 0.700 33) (make-all-pass -0.700 0.700 11)))) (copy-test (make-filtered-comb .4 5 :filter (make-one-zero .3 .7))) (copy-test (make-filtered-comb-bank (vector (make-filtered-comb .5 3) (make-filtered-comb .2 10) (make-filtered-comb -.7 11)))) (copy-test (make-formant 1200.0 0.9)) (copy-test (make-firmant 1200.0 0.9)) (copy-test (make-fir-filter 4 (float-vector 0.4 0.3 0.2 0.1))) (copy-test (make-iir-filter 4 (float-vector 0.4 0.3 0.2 0.1))) (copy-test (make-filter 4 (float-vector 0.4 0.3 0.2 0.1))) (copy-test (make-one-pole-all-pass 8 .5)) (copy-test (make-readin "oboe.snd")) (copy-test (make-env '(0 0 1 1) :length 10)) (copy-test (make-pulsed-env '(0 0 1 1) .001 1000)) ;; formant-bank isn't really testing equality yet (let ((o (make-rand 100.0))) (let ((p (copy o))) (if (not (equal? o p)) (snd-display #__line__ ";rand copy ~A != ~A~%" o p)))) (let ((o (make-rand-interp 100.0))) (let ((p (copy o))) (if (not (equal? o p)) (snd-display #__line__ ";rand-interp copy ~A != ~A~%" o p)))) (let ((v1 (make-float-vector 10 .1))) (let ((o (make-rand 100.0 :distribution v1))) (let ((p (copy o))) (if (not (equal? o p)) (snd-display #__line__ ";rand+dist copy ~A != ~A~%" o p)))) (let ((o (make-rand-interp 100.0 :distribution v1))) (let ((p (copy o))) (if (not (equal? o p)) (snd-display #__line__ ";rand-interp+dist copy ~A != ~A~%" o p))))) (let ((o (make-nssb 440.0))) (let ((p (copy o))) (if (not (equal? o p)) (snd-display #__line__ ";nssb copy ~A != ~A~%" o p)) (nssb o 1.0) (if (equal? o p) (snd-display #__line__ ";nssb copy/run ~A == ~A~%" o p)))) (let ((v1 (float-vector 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9))) (let ((o (make-wave-train 100 :wave v1))) (let ((p (copy o))) (if (not (equal? o p)) (snd-display #__line__ ";wave-train copy ~A != ~A~%" o p))))) (let ((v1 (float-vector 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9))) (let ((o (make-table-lookup 440.0 :wave v1))) (let ((p (copy o))) (if (not (equal? o p)) (snd-display #__line__ ";table-lookup copy ~A != ~A~%" o p)) (table-lookup o 1.0) (if (equal? o p) (snd-display #__line__ ";table-lookup run ~A == ~A~%" o p))))) )) ;;; ---------------- test 9: mix ---------------- (define (snd_test_9) (define (make-waltz) (define (frequency->tag-y freq lo octs) ; tag height dependent on freq (round (* 100 (- 1.0 (/ (log (/ freq lo)) (* (log 2.0) octs)))))) (let ((oldie (find-sound "test.snd"))) (if (sound? oldie) (close-sound oldie))) (let ((violin-sync 1) (violin-color (make-color 0 0 1)) ; blue (cello-sync 2) (cello-color (make-color 0 1 0)) ; green (index (new-sound "test.snd" :channels 1 :size (* 22050 22)))) (define (violin beg dur freq amp) (let ((id (car (mix (with-temp-sound () ; write instrument output to temp sound (fm-violin 0 dur (->frequency freq #t) amp)) ; our favorite FM instrument (->sample beg) 0 index 0 ; mix start, file in-chan, sound, channel #t #t)))) ; mix with tag and auto-delete (if (symbol? freq) (set! (mix-name id) (symbol->string freq))) (set! (mix-sync id) violin-sync) (set! (mix-color id) violin-color) (set! (mix-tag-y id) (frequency->tag-y (->frequency freq #t) (->frequency 'c2) 3)))) (define (cello beg dur freq amp) (let ((id (car (mix (with-temp-sound () (fm-violin 0 dur (->frequency freq #t) amp :fm-index 1.5)) (->sample beg) 0 index 0 #t #t)))) (if (symbol? freq) (set! (mix-name id) (symbol->string freq))) (set! (mix-sync id) cello-sync) (set! (mix-color id) cello-color) (set! (mix-tag-y id) (frequency->tag-y (->frequency freq #t) (->frequency 'c2) 3)))) (as-one-edit (lambda () (violin 0 1 'e4 .2) (violin 1 1.5 'g4 .2) (violin 2.5 .5 'g3 .2) (cello 0 1 'c3 .2) (cello 1 1.5 'e3 .2) (cello 2.5 .5 'g2 .2) (violin 3 3 'f4 .2) (cello 3 3 'd3 .2) (violin 6 1 'e4 .2) (violin 7 1 'g3 .2) (violin 8 1 'e4 .2) (cello 6 1 'c3 .2) (cello 7 1 'g2 .2) (cello 8 1 'c3 .2) (violin 9 3 'd4 .2) (cello 9 3 'b2 .2) (violin 12 1 'f4 .2) (violin 13 1.5 'a4 .2) (violin 14.5 .5 'g3 .2) (cello 12 1 'd3 .2) (cello 13 1.5 'f3 .2) (cello 14.5 .5 'g2 .2) (violin 15 3 'g4 .2) (cello 15 3 'e3 .2) (violin 18 1 'f4 .2) (violin 19 1 'g3 .2) (violin 20 1 'f4 .2) (cello 18 1 'd3 .2) (cello 19 1 'g2 .2) (cello 20 1 'd3 .2) (violin 21 3 'e4 .2) (cello 21 3 'c3 .2) index)))) (define (make-bagatelle) ;; Columbia, Gem of the Ocean (define (seg data) ; SEG functions expected data in (y x) pairs. (let ((unseg ()) (len (length data))) (do ((i 0 (+ i 2))) ((>= i len) (reverse unseg)) (let ((x (data (+ i 1))) (y (data i))) (set! unseg (cons y (cons x unseg))))))) (let ((oldie (find-sound "test.snd"))) (if (sound? oldie) (close-sound oldie))) (let ((soprano ()) (alto ()) (tenor ()) (bass ()) (ind (new-sound "test.snd" :channels 1)) (f1 (seg '(0 0 1 25 1 75 0 100))) (f5 (seg '(-1 0 .25 10 0 20 0 100))) ;; (grc1 (seg '(1 0 .5 10 0 20 0 50 0 100))) ;; (grc2 (seg '(0 0 1 10 0 20 0 50 0 100))) ;; (grc3 (seg '(.5 0 1 10 0 20 0 50 0 100))) ;; (grc4 (seg '(1 0 0 10 1 20 0 30 1 40 0 50 1 60 0 70 1 80 0 90 1 100))) ;; (grc5 (seg '(1 0 .5 10 1 20 0 30 1 40 .5 50 1 60 0 70 1 80 .5 90 1 100))) ;; (grc6 (seg '(1 0 .5 10 0 20 -.5 30 -1 40 -.5 50 0 60 .5 70 1 80 .5 90 0 100))) (f6 (seg '(1 1 .5 10 .75 50 .4 75 .6 90 0 100))) (f7 (seg '(0 1 .5 10 .25 25 .75 50 .5 75 1 90 0 100))) ;; (f2 (seg '(0 1 .5 10 .4 90 0 100))) ;; (f3 (seg '(1 0 .5 10 .75 90 0 100))) ;; (ramp (seg '(0 0 1 2.5 1 7.5 0 10 1 12.5 1 17.5 0 20 1 22.5 1 27.5 0 30 1 32.5 1 37.5 ;; 0 40 1 42.5 1 47.5 0 50 1 52.5 1 57.5 0 60 1 62.5 1 67.5 0 70 1 72.5 1 77.5 ;; 0 80 1 82.5 1 87.5 0 90 1 92.5 1 97.5 0 100))) ;; (str (seg '(1 1 1 100))) ) (define (mix-fmsimp beg dur freq amp ampfunc freqfunc rat1 indx1 rat2 indx2 ignored) (let ((freq1 (if (> freq (/ *clm-srate* 8)) (/ freq 8) freq)) (amp1 (* amp .175))) (let ((id (car (mix (with-temp-sound () (fm-violin 0 dur freq1 amp1 :fm1-rat (* 1.002 rat1) :fm1-index (* .5 rat1 indx1 (hz->radians freq)) :fm1-env f6 :fm2-rat (* 1.003 rat2) :fm2-index (* .5 indx2 rat2 (hz->radians freq)) :fm2-env f7 :fm3-index 0.0 :reverb-amount 1.0 :amp-env ampfunc)) (->sample beg) 0 ind 0 #t #t)))) ; with tag and auto-delete (set! (mix-name id) (number->string (floor freq))) (if (> freq 700) (set! soprano (cons id soprano)) (if (> freq 500) (set! alto (cons id alto)) (if (> freq 300) (set! tenor (cons id tenor)) (set! bass (cons id bass)))))))) (as-one-edit (lambda () (mix-fmsimp .000 2.488 659.255 .500 f1 f5 5.000 1.260 2.000 .501 .000 ) (mix-fmsimp .750 1.988 654.084 .167 f1 f5 3.000 1.260 1.000 .710 .000 ) (mix-fmsimp 1.000 2.738 880.000 .500 f1 f5 5.000 1.260 1.000 .140 .001 ) (mix-fmsimp 2.000 2.488 880.000 .500 f1 f5 1.000 1.671 2.000 .745 .001 ) (mix-fmsimp 2.750 1.969 871.429 .495 f1 f5 5.000 1.312 1.000 .447 .001 ) (mix-fmsimp 3.000 2.750 493.883 .100 f1 f5 1.000 1.260 2.000 1.069 .002 ) (mix-fmsimp 4.000 2.488 654.568 .500 f1 f5 3.000 1.671 5.000 .793 .002 ) (mix-fmsimp 4.750 1.988 590.042 .241 f1 f5 2.000 1.671 5.000 1.046 .002 ) (mix-fmsimp 5.000 2.238 551.574 .500 f1 f5 4.000 1.671 1.000 .073 .003 ) (mix-fmsimp 5.500 2.238 664.174 .504 f1 f5 3.000 1.671 4.000 .791 .003 ) (mix-fmsimp 6.000 1.988 659.255 .400 f1 f5 2.000 1.671 2.000 .955 .003 ) (mix-fmsimp 6.250 2.738 880.000 .400 f1 f5 5.000 1.260 5.000 .645 .003 ) (mix-fmsimp 7.250 2.505 885.724 .336 f1 f5 5.000 1.260 4.000 .302 .004 ) (mix-fmsimp 8.000 1.988 880.000 .500 f1 f5 3.000 1.260 2.000 .672 .004 ) (mix-fmsimp 8.250 2.738 493.883 .100 f1 f5 4.000 1.671 1.000 .013 .004 ) (mix-fmsimp 9.250 2.488 659.255 .250 f1 f5 3.000 1.671 3.000 1.167 .005 ) (mix-fmsimp 10.000 1.988 587.330 .240 f1 f5 2.000 1.314 5.000 .423 .005 ) (mix-fmsimp 10.250 2.238 554.365 .500 f1 f5 1.000 1.671 2.000 .078 .005 ) (mix-fmsimp 10.750 2.238 659.255 .500 f1 f5 1.000 1.260 5.000 .797 .005 ) (mix-fmsimp 11.250 1.988 651.332 .400 f1 f5 5.000 1.671 1.000 .883 .006 ) (mix-fmsimp 11.500 1.926 878.372 .200 f1 f5 1.000 1.434 4.000 .322 .006 ) (mix-fmsimp 11.688 2.497 880.000 .335 f1 f5 2.000 1.671 4.000 .879 .006 ) (mix-fmsimp 12.438 2.006 887.764 .288 f1 f5 1.000 1.671 4.000 .652 .006 ) (mix-fmsimp 12.688 2.738 493.883 .100 f1 f5 1.000 1.671 4.000 .521 .006 ) (mix-fmsimp 13.688 2.488 659.255 .250 f1 f5 2.000 1.671 2.000 1.247 .007 ) (mix-fmsimp 14.438 1.988 587.330 .240 f1 f5 1.000 1.260 2.000 1.182 .007 ) (mix-fmsimp 14.688 2.238 547.848 .494 f1 f5 4.000 1.671 2.000 .432 .007 ) (mix-fmsimp 15.188 3.238 867.651 .500 f1 f5 4.000 1.671 1.000 .571 .008 ) (mix-fmsimp 16.688 2.238 659.255 .400 f1 f5 4.000 1.671 4.000 .477 .008 ) (mix-fmsimp 17.188 1.988 652.468 .495 f1 f5 3.000 1.671 2.000 .438 .009 ) (mix-fmsimp 17.438 1.926 880.000 .200 f1 f5 2.000 1.671 4.000 1.107 .009 ) (mix-fmsimp 17.625 2.523 880.000 .500 f1 f5 5.000 1.671 1.000 .830 .009 ) (mix-fmsimp 18.375 1.988 880.000 .400 f1 f5 4.000 1.671 3.000 .186 .009 ) (mix-fmsimp 18.625 2.738 493.883 .100 f1 f5 1.000 1.260 5.000 .407 .009 ) (mix-fmsimp 19.625 2.488 657.231 .166 f1 f5 5.000 1.260 2.000 .389 .010 ) (mix-fmsimp 20.375 1.976 587.330 .238 f1 f5 2.000 1.671 1.000 .712 .010 ) (mix-fmsimp 20.625 2.238 554.365 .500 f1 f5 3.000 1.260 5.000 .171 .010 ) (mix-fmsimp 21.125 3.238 880.000 .500 f1 f5 4.000 1.671 1.000 .507 .011 ) (mix-fmsimp 22.625 2.238 650.838 .395 f1 f5 3.000 1.671 4.000 .160 .011 ) (mix-fmsimp 23.125 1.978 659.255 .497 f1 f5 1.000 1.671 1.000 .867 .012 ) (mix-fmsimp 23.375 1.926 885.243 .333 f1 f5 2.000 1.412 4.000 .811 .012 ) (mix-fmsimp 23.563 2.488 880.000 .500 f1 f5 4.000 1.671 3.000 .439 .012 ) (mix-fmsimp 24.313 1.995 882.799 .401 f1 f5 1.000 1.671 4.000 1.089 .012 ) (mix-fmsimp 24.563 2.730 246.942 .100 f1 f5 2.000 1.671 1.000 .092 .012 ) (mix-fmsimp 25.563 2.488 329.628 .167 f1 f5 2.000 1.671 2.000 1.149 .012 ) (mix-fmsimp 26.313 2.007 587.330 .242 f1 f5 3.000 1.671 3.000 .472 .011 ) (mix-fmsimp 26.563 2.238 548.468 .495 f1 f5 2.000 1.671 1.000 .259 .011 ) (mix-fmsimp 27.063 3.238 439.221 .500 f1 f5 3.000 1.260 3.000 1.014 .011 ) (mix-fmsimp 28.563 2.493 441.603 .401 f1 f5 3.000 1.671 5.000 .056 .010 ) (mix-fmsimp 29.313 2.220 659.255 .500 f1 f5 3.000 1.260 3.000 1.108 .010 ) (mix-fmsimp 29.813 1.960 329.628 .500 f1 f5 1.000 1.671 1.000 .944 .010 ) (mix-fmsimp 30.063 1.894 440.000 .333 f1 f5 1.000 1.260 4.000 .602 .009 ) (mix-fmsimp 30.250 2.453 443.160 .400 f1 f5 1.000 1.260 3.000 .750 .009 ) (mix-fmsimp 31.000 1.938 441.168 .333 f1 f5 5.000 1.671 3.000 .522 .009 ) (mix-fmsimp 31.250 2.684 246.942 .100 f1 f5 5.000 1.654 1.000 1.020 .009 ) (mix-fmsimp 32.250 2.415 325.263 .167 f1 f5 4.000 1.671 3.000 .014 .008 ) (mix-fmsimp 33.000 1.901 587.330 .240 f1 f5 4.000 1.671 5.000 1.106 .008 ) (mix-fmsimp 33.250 2.149 554.936 .501 f1 f5 2.000 1.260 2.000 1.159 .008 ) (mix-fmsimp 33.750 3.137 440.000 .500 f1 f5 2.000 1.671 1.000 .647 .008 ) (mix-fmsimp 35.250 2.359 440.000 .400 f1 f5 5.000 1.671 4.000 1.149 .007 ) (mix-fmsimp 36.000 2.101 661.109 .501 f1 f5 4.000 1.377 2.000 1.121 .006 ) (mix-fmsimp 36.500 1.836 329.628 .500 f1 f5 2.000 1.671 4.000 1.459 .006 ) (mix-fmsimp 36.750 1.768 440.000 .250 f1 f5 5.000 1.671 5.000 .601 .006 ) (mix-fmsimp 36.938 2.327 442.815 .400 f1 f5 2.000 1.671 3.000 .354 .006 ) (mix-fmsimp 37.688 1.813 440.000 .400 f1 f5 4.000 1.671 2.000 .205 .006 ) (mix-fmsimp 37.938 2.559 246.712 .100 f1 f5 4.000 1.671 2.000 1.044 .006 ) (mix-fmsimp 38.938 2.290 329.628 .167 f1 f5 1.000 1.260 2.000 1.316 .005 ) (mix-fmsimp 39.688 1.781 587.330 .240 f1 f5 1.000 1.671 3.000 .524 .005 ) (mix-fmsimp 39.938 2.021 554.365 .500 f1 f5 1.000 1.671 2.000 .522 .005 ) (mix-fmsimp 40.438 2.998 438.022 .498 f1 f5 3.000 1.260 4.000 .264 .004 ) (mix-fmsimp 41.938 2.253 443.810 .403 f1 f5 1.000 1.671 4.000 1.157 .004 ) (mix-fmsimp 42.688 1.720 414.691 .319 f1 f5 4.000 1.671 1.000 .612 .003 ) (mix-fmsimp 42.938 1.965 659.255 .500 f1 f5 2.000 1.671 2.000 .559 .003 ) (mix-fmsimp 43.438 1.690 329.628 .496 f1 f5 5.000 1.671 2.000 1.457 .003 ) (mix-fmsimp 43.688 1.630 440.000 .249 f1 f5 2.000 1.671 5.000 .505 .003 ) (mix-fmsimp 43.875 2.197 440.000 .400 f1 f5 3.000 1.260 3.000 .843 .003 ) (mix-fmsimp 44.625 1.678 440.000 .332 f1 f5 2.000 1.671 5.000 1.165 .002 ) (mix-fmsimp 44.875 2.405 246.942 .100 f1 f5 4.000 1.671 3.000 .105 .002 ) (mix-fmsimp 45.875 2.160 332.580 .168 f1 f5 1.000 1.260 5.000 1.107 .002 ) (mix-fmsimp 46.625 1.646 583.584 .238 f1 f5 4.000 1.673 5.000 .201 .001 ) (mix-fmsimp 46.875 1.891 553.184 .492 f1 f5 1.000 1.304 2.000 1.230 .001 ) (mix-fmsimp 47.375 2.882 438.012 .489 f1 f5 5.000 1.737 4.000 .024 .001 ) (mix-fmsimp 48.875 2.104 440.000 .487 f1 f5 2.000 1.770 2.000 .308 .000 ) (mix-fmsimp 49.625 1.590 414.068 .319 f1 f5 4.000 1.866 3.000 .415 .001 ) (mix-fmsimp 49.875 1.835 659.255 .467 f1 f5 1.000 1.914 3.000 .477 .001 ) (mix-fmsimp 50.375 1.592 333.127 .470 f1 f5 5.000 1.930 2.000 .230 .001 ) (mix-fmsimp 50.625 1.509 440.000 .250 f1 f5 5.000 1.963 1.000 .829 .001 ) (mix-fmsimp 50.813 2.068 440.000 .400 f1 f5 3.000 1.979 1.000 1.450 .001 ) (mix-fmsimp 51.563 1.536 434.964 .330 f1 f5 4.000 1.991 2.000 .308 .002 ) (mix-fmsimp 51.813 2.299 246.942 .088 f1 f5 4.000 1.581 5.000 1.149 .002 ) (mix-fmsimp 52.813 2.030 329.628 .167 f1 f5 5.000 1.916 5.000 1.234 .002 ) (mix-fmsimp 53.563 1.524 590.360 .241 f1 f5 4.000 2.119 4.000 .374 .003 ) (mix-fmsimp 53.813 1.761 554.365 .433 f1 f5 3.000 2.168 3.000 .269 .003 ) (mix-fmsimp 54.313 2.720 434.908 .425 f1 f5 3.000 2.184 1.000 1.209 .003 ) (mix-fmsimp 55.813 1.966 440.000 .426 f1 f5 4.000 2.196 2.000 1.493 .004 ) (mix-fmsimp 56.563 1.446 415.305 .316 f1 f5 4.000 2.312 1.000 .753 .004 ) (mix-fmsimp 56.813 2.205 369.994 .406 f1 f5 2.000 2.361 1.000 .292 .004 ) (mix-fmsimp 57.813 1.668 329.628 .400 f1 f5 4.000 2.377 1.000 .179 .005 ) (mix-fmsimp 58.313 1.422 329.628 .394 f1 f5 4.000 2.441 3.000 1.117 .005 ) (mix-fmsimp 58.563 1.360 435.856 .250 f1 f5 1.000 1.960 5.000 .811 .005 ) (mix-fmsimp 58.750 1.919 440.000 .389 f1 f5 2.000 2.489 3.000 .242 .005 ) (mix-fmsimp 59.500 1.405 439.947 .387 f1 f5 3.000 2.501 4.000 1.265 .006 ) (mix-fmsimp 59.750 2.173 249.594 .073 f1 f5 2.000 2.550 2.000 .351 .006 ) (mix-fmsimp 60.750 1.881 329.628 .200 f1 f5 2.000 2.566 2.000 1.431 .006 ) (mix-fmsimp 61.500 1.367 293.665 .240 f1 f5 1.000 2.096 1.000 1.378 .007 ) (mix-fmsimp 61.750 1.613 554.365 .363 f1 f5 1.000 2.678 1.000 .201 .007 ) (mix-fmsimp 62.250 2.603 433.901 .356 f1 f5 2.000 2.694 5.000 .950 .007 ) (mix-fmsimp 63.750 1.809 440.000 .354 f1 f5 4.000 2.727 4.000 .459 .008 ) (mix-fmsimp 64.500 1.314 415.305 .320 f1 f5 3.000 2.265 1.000 1.059 .008 ) (mix-fmsimp 64.750 2.057 374.139 .341 f1 f5 2.000 2.307 3.000 .054 .008 ) (mix-fmsimp 65.750 1.538 329.628 .335 f1 f5 4.000 2.887 3.000 1.281 .009 ) (mix-fmsimp 66.250 1.278 329.628 .326 f1 f5 3.000 2.952 4.000 .363 .009 ) (mix-fmsimp 66.500 1.211 440.000 .322 f1 f5 5.000 2.405 4.000 .361 .009 ) (mix-fmsimp 66.688 1.769 440.000 .319 f1 f5 4.000 2.419 3.000 .190 .009 ) (mix-fmsimp 67.438 1.256 437.237 .316 f1 f5 1.000 2.430 2.000 1.121 .010 ) (mix-fmsimp 67.688 1.979 246.942 .056 f1 f5 2.000 2.472 4.000 1.172 .010 ) (mix-fmsimp 68.688 1.736 330.174 .250 f1 f5 4.000 2.486 3.000 .893 .010 ) (mix-fmsimp 69.438 1.213 292.204 .238 f1 f5 5.000 2.732 1.000 1.265 .011 ) (mix-fmsimp 69.688 1.462 553.724 .294 f1 f5 3.000 3.189 3.000 .427 .011 ) (mix-fmsimp 70.188 2.455 440.000 .292 f1 f5 2.000 2.598 5.000 .489 .011 ) (mix-fmsimp 71.688 1.654 440.000 .284 f1 f5 5.000 3.237 2.000 1.299 .012 ) (mix-fmsimp 72.438 1.175 415.305 .277 f1 f5 3.000 2.995 4.000 .916 .012 ) (mix-fmsimp 72.688 1.933 369.994 .271 f1 f5 1.000 3.382 1.000 .886 .012 ) (mix-fmsimp 73.688 1.639 440.000 .046 f1 f5 4.000 3.398 5.000 .993 .012 ) (mix-fmsimp 74.438 15.942 329.628 .257 f1 f5 1.000 2.822 1.000 .402 .011 ) (mix-fmsimp 74.938 (- 45.394 20) 329.628 .249 f1 f5 1.000 2.864 2.000 1.093 .011 ) (mix-fmsimp 75.438 (- 45.063 20) 440.000 .246 f1 f5 3.000 3.543 2.000 .978 .011 ) (mix-fmsimp 75.625 (- 45.335 20) 444.508 .244 f1 f5 2.000 2.920 4.000 .563 .011 ) (mix-fmsimp 76.375 (- 44.125 20) 445.106 .240 f1 f5 3.000 2.931 2.000 .768 .010 ) (mix-fmsimp 76.625 (- 43.875 20) 248.294 .038 f1 f5 2.000 2.973 2.000 .155 .010 ) (mix-fmsimp 77.625 (- 43.455 20) 334.084 .234 f1 f5 3.000 2.987 4.000 .047 .010 ) (mix-fmsimp 78.375 (- 41.938 20) 292.359 .222 f1 f5 3.000 3.521 5.000 1.140 .009 ) (mix-fmsimp 78.625 (- 41.605 20) 554.365 .215 f1 f5 2.000 3.085 4.000 .595 .009 ) (mix-fmsimp 79.125 (- 41.769 20) 440.000 .214 f1 f5 3.000 3.780 3.000 .541 .009 ) (mix-fmsimp 80.625 (- 39.875 20) 440.000 .200 f1 f5 3.000 3.812 2.000 1.111 .008 ) (mix-fmsimp 91.130 (- 29.335 20) 415.305 .111 f1 f5 3.000 3.759 2.000 .490 .003 ) ind)))) (if with-gui (begin (do ((test-ctr 0 (+ 1 test-ctr))) ((= test-ctr tests)) (let ((ind (new-sound "test.snd" :size 10))) (let ((v (float-vector .1 .2 .3))) (let ((id (mix-float-vector v 0))) (let ((nv (channel->float-vector))) (if (not (vequal nv (float-vector .1 .2 .3 0 0 0 0 0 0 0))) (snd-display #__line__ ";mix v at 0: ~A" nv))) (let ((eds (edit-tree ind 0))) (if (not (feql eds '((0 0 0 2 0.0 0.0 0.0 3) (3 0 3 9 0.0 0.0 0.0 2) (10 -2 0 0 0.0 0.0 0.0 0)))) (snd-display #__line__ ";mix v at 0 eds: ~A" eds))) (if (not (mix? id)) (snd-display #__line__ ";mix v at 0 id from mix?: ~A" id)) (if (fneq (mix-amp id) 1.0) (snd-display #__line__ ";mix v at 0 amp: ~A" (mix-amp id))) (if (fneq (mix-speed id) 1.0) (snd-display #__line__ ";mix v at 0 speed: ~A" (mix-speed id))) (if (not (= (mix-sync id) 0)) (snd-display #__line__ ";mix v at 0 sync: ~A" (mix-sync id))) (if (not (null? (mix-amp-env id))) (snd-display #__line__ ";mix v at 0 amp-env: ~A" (mix-amp-env id))) (if (not (= (mix-position id) 0)) (snd-display #__line__ ";mix v at 0 beg: ~A" (mix-position id))) (if (not (= (mix-length id) 3)) (snd-display #__line__ ";mix v at 0 length: ~A" (mix-length id))) (if (not (equal? (mix-name id) "")) (snd-display #__line__ ";mix v at 0 name: ~A" (mix-name id))) (if (not (null? (mix-properties id))) (snd-display #__line__ ";mix v at 0 properties: ~A" (mix-properties id))) (if (not (equal? (mix-color id) *mix-color*)) (snd-display #__line__ ";mix v at 0 color: ~A" (mix-color id))) (if (not (= (mix-tag-y id) 0)) (snd-display #__line__ ";mix v at 0 tag-y: ~A" (mix-tag-y id))) (let ((sf (make-mix-sampler id)) (data (make-float-vector 10))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (data i) (read-mix-sample sf))) (if (not (vequal data (channel->float-vector))) (snd-display #__line__ ";mix v at 0 read mix samples: ~A" data)) (if (not (sampler-at-end? sf)) (snd-display #__line__ ";mix v at 0 reader not at end?")) (free-sampler sf)) (if (not (equal? (mixes ind 0) (list id))) (snd-display #__line__ ";mix v at 0 mixes: ~A" (mixes ind 0))) (if (not (equal? (mix-home id) (list ind 0 #f 0))) (snd-display #__line__ ";mix v at 0 home: ~A" (mix-home id))) (undo)) (mix-float-vector v 8) (if (not (= (framples ind 0) 11)) (snd-display #__line__ ";mix v at 8 new len: ~A" (framples ind 0))) (let ((nv (channel->float-vector))) (if (not (vequal nv (float-vector 0 0 0 0 0 0 0 0 .1 .2 .3))) (snd-display #__line__ ";mix v at 8: ~A" nv))) (undo) (mix-float-vector v 3) (if (not (= (framples ind 0) 10)) (snd-display #__line__ ";mix v at 3 new len: ~A" (framples ind 0))) (let ((nv (channel->float-vector))) (if (not (vequal nv (float-vector 0 0 0 .1 .2 .3 0 0 0 0))) (snd-display #__line__ ";mix v at 3: ~A" nv))) (undo)) (let ((v (make-float-vector 20 .5))) (mix-float-vector v 0) (if (not (= (framples ind 0) 20)) (snd-display #__line__ ";mix v20 at 0 new len: ~A" (framples ind 0)))) (close-sound ind)) (let ((ind (new-sound "test.snd" :size 100000))) (let ((id (car (mix "oboe.snd" 0)))) (if (not (mix? id)) (snd-display #__line__ ";mix oboe at 0 id from mix?: ~A" id)) (if (fneq (mix-amp id) 1.0) (snd-display #__line__ ";mix oboe at 0 amp: ~A" (mix-amp id))) (if (fneq (mix-speed id) 1.0) (snd-display #__line__ ";mix oboe at 0 speed: ~A" (mix-speed id))) (if (not (= (mix-sync id) 0)) (snd-display #__line__ ";mix oboe at 0 sync: ~A" (mix-sync id))) (if (not (null? (mix-amp-env id))) (snd-display #__line__ ";mix oboe at 0 amp-env: ~A" (mix-amp-env id))) (if (not (= (mix-position id) 0)) (snd-display #__line__ ";mix oboe at 0 beg: ~A" (mix-position id))) (if (not (= (mix-length id) 50828)) (snd-display #__line__ ";mix oboe at 0 length: ~A" (mix-length id))) (if (not (equal? (mix-name id) "")) (snd-display #__line__ ";mix oboe at 0 name: ~A" (mix-name id))) (if (not (null? (mix-properties id))) (snd-display #__line__ ";mix oboe at 0 properties: ~A" (mix-properties id))) (if (not (equal? (mix-color id) *mix-color*)) (snd-display #__line__ ";mix oboe at 0 color: ~A" (mix-color id))) (if (not (= (mix-tag-y id) 0)) (snd-display #__line__ ";mix oboe at 0 tag-y: ~A" (mix-tag-y id))) (if (fneq (maxamp ind 0) .14724) (snd-display #__line__ ";mix oboe maxamp: ~A" (maxamp ind 0))) (if (not (equal? (mixes ind 0) (list id))) (snd-display #__line__ ";mix oboe at 0 mixes: ~A" (mixes ind 0))) (if (not (equal? (mix-home id) (list ind 0 "/home/bil/cl/oboe.snd" 0))) (snd-display #__line__ ";mix oboe at 0 home: ~A" (mix-home id)))) (undo) (mix "oboe.snd" 70000) (if (not (= (framples ind 0) (+ 70000 50828))) (snd-display #__line__ ";mix oboe at 70k framples: ~A" (framples ind 0))) (close-sound ind)) (let ((ind (new-sound "test.snd" :size 10))) (let ((v (float-vector .1 .2 .3))) (let ((id (mix-float-vector v 0))) (scale-by 2.0) (if (not (mix? id)) (snd-display #__line__ ";scaled (2) mix not active?")) (let ((nv (channel->float-vector))) (if (not (vequal nv (float-vector-scale! (float-vector .1 .2 .3 0 0 0 0 0 0 0) 2.0))) (snd-display #__line__ ";mix v at 0 scale-by 2: ~A" nv))) (if (fneq (mix-amp id) 2.0) (snd-display #__line__ ";mix then scale mix amp: ~A" (mix-amp id))) (undo) (delete-sample 1) (if (not (mix? id)) (snd-display #__line__ ";delete hit mix: ~A" (mix? id))) (let ((nv (channel->float-vector))) (if (not (vequal nv (float-vector .1 .3 0 0 0 0 0 0 0))) (snd-display #__line__ ";mix v at 0 delete .2: ~A" nv))) (revert-sound ind)) (let ((id (mix-float-vector v 0))) (delete-sample 7) (reverse-sound ind 0) (if (not (mix? id)) (snd-display #__line__ ";reversed mix: ~A" (mix? id))) (let ((nv (channel->float-vector))) (if (not (vequal nv (reverse! (float-vector .1 .2 .3 0 0 0 0 0 0)))) (snd-display #__line__ ";mix v at 0 reversed: ~A" nv))) (undo) (if (not (mix? id)) (snd-display #__line__ ";revert reverse mix: ~A" (mix? id))) (map-channel (lambda (y) .1)) (if (not (mix? id)) (snd-display #__line__ ";clobbered mix: ~A" (mixes))) (scale-by 2.0) (let ((id (mix-float-vector v 0))) (if (not (mix? id)) (snd-display #__line__ ";mix on scale (2) not active?")) (scale-by 3.0) (if (not (mix? id)) (snd-display #__line__ ";scaled (3) mix not active?")) (let ((nv (channel->float-vector))) (if (not (vequal nv (float-vector-scale! (float-vector-add! (make-float-vector 9 .2) (float-vector .1 .2 .3)) 3.0))) (snd-display #__line__ ";mix v at 0 scale-by 2 and 3: ~A" nv)))) (revert-sound ind) (map-channel (lambda (y) 1.0)) (env-channel '(0 0 1 1 2 0) 0 11) (let ((v (float-vector .1 .2 .3))) (mix-float-vector v 3) (let ((nv (channel->float-vector))) (if (not (vequal nv (float-vector 0.000 0.200 0.400 0.700 1.000 1.300 0.800 0.600 0.400 0.200))) (snd-display #__line__ ";mix v at 3 after env: ~A" nv)))) (close-sound ind)))) (let ((ind (new-sound "test.snd" :size 100))) (let ((v (float-vector .1 .2 .3))) (let ((id (mix-float-vector v 10))) (pad-channel 0 10) (if (not (mix? id)) (snd-display #__line__ ";padded mix not active?")) (if (not (= (mix-position id) 20)) (snd-display #__line__ ";after pad mix pos: ~A" (mix-position id))) (set! (mix-sync id) 2) (if (not (= (mix-sync id) 2)) (snd-display #__line__ ";set mix sync 2: ~A" (mix-sync id))) (if (and full-test (< (mix-sync-max) 2)) (snd-display #__line__ ";mix-sync-max: ~A" (mix-sync-max))) (pad-channel 50 10) (if (not (mix? id)) (snd-display #__line__ ";padded 50 mix not active?")) (if (not (= (mix-position id) 20)) (snd-display #__line__ ";after pad 50 mix pos: ~A" (mix-position id))) (undo 1) (let ((id1 (mix-float-vector v 22)) (id2 (mix-float-vector v 21))) (let ((vals (channel->float-vector 18 10))) (if (not (vequal vals (float-vector 0.000 0.000 0.100 0.300 0.600 0.500 0.300 0.000 0.000 0.000))) (snd-display #__line__ ";mix 3 vs: ~A" vals)) (if (not (mix? id)) (snd-display #__line__ ";mix 3vs 1 not active?")) (if (not (mix? id1)) (snd-display #__line__ ";mix 3vs 2 not active?")) (if (not (mix? id2)) (snd-display #__line__ ";mix 3vs 3 not active?")) (set! (mix-position id) 10) (set! vals (channel->float-vector 18 10)) (if (not (vequal vals (float-vector 0.000 0.000 0.000 0.100 0.300 0.500 0.300 0.000 0.000 0.000))) (snd-display #__line__ ";mix 3 vs then move first: ~A" vals)) (set! (mix-position id2) 30) (set! vals (channel->float-vector 18 10)) (if (not (vequal vals (float-vector 0.000 0.000 0.000 0.000 0.100 0.200 0.300 0.000 0.000 0.000))) (snd-display #__line__ ";mix 3 vs then move 2: ~A" vals)) (scale-by 2.0) (if (not (mix? id)) (snd-display #__line__ ";mix 3vs 1 scl not active?")) (if (not (mix? id1)) (snd-display #__line__ ";mix 3vs 2 scl not active?")) (if (not (mix? id2)) (snd-display #__line__ ";mix 3vs 3 scl not active?")) (set! vals (channel->float-vector 18 10)) (if (not (vequal vals (float-vector 0.000 0.000 0.000 0.000 0.200 0.400 0.600 0.000 0.000 0.000))) (snd-display #__line__ ";mix 3 vs then move 2 scl: ~A" vals)) (delete-sample 15) (if (not (mix? id)) (snd-display #__line__ ";mix 3vs 1 scl del not active?")) (if (not (mix? id1)) (snd-display #__line__ ";mix 3vs 2 scl del not active?")) (if (not (mix? id2)) (snd-display #__line__ ";mix 3vs 3 scl del not active?")) (if (not (= (mix-position id) 10)) (snd-display #__line__ ";mix 3vs etc pos: ~A" (mix-position id))) (if (not (= (mix-position id1) 21)) (snd-display #__line__ ";mix 3vs etc pos 1: ~A" (mix-position id1))) (if (not (= (mix-position id2) 29)) (snd-display #__line__ ";mix 3vs etc pos 2: ~A" (mix-position id2))) )))) (close-sound ind)) (let ((ind (new-sound "test.snd" :size 15))) (let ((id (mix-float-vector (make-float-vector 11 1.0) 2))) (set! (mix-amp-env id) '(0 0 1 1)) (let ((vals (channel->float-vector))) (if (not (vequal vals (float-vector 0 0 0 .1 .2 .3 .4 .5 .6 .7 .8 .9 1.0 0 0))) (snd-display #__line__ ";ramp mix amp env: ~A" vals))) (set! (mix-amp-env id) #f) (if (pair? (mix-amp-env id)) (snd-display #__line__ ";set mix-amp-env to null: ~A" (mix-amp-env id))) (set! (mix-speed id) 0.5) (if (not (= (framples) 24)) (snd-display #__line__ ";mix speed lengthens 24: ~A" (framples))) (set! (mix-speed id) 1.0) (let ((vals (channel->float-vector))) (if (not (vequal vals (float-vector 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0))) (snd-display #__line__ ";return to mix original index: ~A" vals))) (set! (mix-amp-env id) '(0 0 1 1 2 1 3 0)) (set! (mix-speed id) 0.5) (set! (mix-amp-env id) #f) (set! (mix-speed id) 1.0) (let ((vals (channel->float-vector))) (if (not (vequal vals (float-vector 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0))) (snd-display #__line__ ";return again to mix original index: ~A" vals))) (close-sound ind))) (let ((id (open-sound "oboe.snd"))) (make-selection 1000 2000 id 0) (let ((mix-id (car (mix-selection 3000 id 0)))) (set! (mix-amp mix-id) .5) (if (fneq (mix-amp mix-id) .5) (snd-display #__line__ ";mix-amp .5: ~A" (mix-amp mix-id))) (scale-by .5) (undo) (close-sound id))) (set! *print-length* 30) (let* ((ind (open-sound "2.snd")) (md (car (mix "1a.snd" 1000 0 ind 1 #t)))) (if (fneq (maxamp ind 1) .1665) (snd-display #__line__ ";maxamp after mix into chan 2: ~A" (maxamp ind 1))) (set! (mix-amp md) 0.0) (if (or (not (equal? (edits ind 0) (list 0 0))) (not (equal? (edits ind 1) (list 2 0)))) (snd-display #__line__ ";mix into chan2 zeroed: ~A ~A" (edits ind 0) (edits ind 1))) (if (fneq (maxamp ind 1) .066) (snd-display #__line__ ";maxamp after mix zeroed into chan 2: ~A" (maxamp ind 1))) (set! (mix-amp md) 0.5) (if (fneq (maxamp ind 1) .116) (snd-display #__line__ ";maxamp after mix 0.5 into chan 2: ~A" (maxamp ind 1))) (set! (mix-speed md) 2.0) (if (fneq (/ (mix-length md) (mus-sound-framples "1a.snd")) 0.5) (snd-display #__line__ ";mix srate chan 2: ~A ~A" (mix-length md) (mus-sound-framples "1a.snd"))) (update-time-graph) (set! (mix-speed md) 0.5) (update-time-graph) (set! (mix-amp md) 1.0) (if (fneq (maxamp ind 1) .166) (snd-display #__line__ ";non-sync mix-speed maxamp: ~A" (maxamp ind 1))) (set! (mix-amp-env md) '(0 0 1 1 2 0)) (update-time-graph) (set! (mix-speed md) 1.0) (update-time-graph) (revert-sound ind) (set! (sync ind) 1) (let ((m0 (maxamp ind 0)) (m1 (maxamp ind 1)) (len (framples ind 0))) (set! md (mix "2.snd" 0 #t)) ; should double both chans, no len change (if (or (not (= (framples ind 0) len)) (fneq (maxamp ind 0) (* 2 m0)) (fneq (maxamp ind 1) (* 2 m1))) (snd-display #__line__ ";mix twice syncd: 0: ~A -> ~A, m1: ~A -> ~A, len: ~A -> ~A" m0 (maxamp ind 0) m1 (maxamp ind 1) len (framples ind 0))) (set! (hook-functions mix-release-hook) ()) (close-sound ind))) (let ((ind (new-sound "fmv.snd" 1 22050 mus-ldouble mus-next "mix tests"))) (insert-silence 0 20 ind) (let ((indout (new-sound "test.snd" 1 22050 mus-ldouble mus-next "mix tests"))) (insert-silence 0 10 indout) (set! (sample 2 indout 0) .5) (set! (sample 5 indout 0) .25) (save-sound indout) (close-sound indout)) (let ((tag (car (mix "test.snd")))) (let ((samps (channel->float-vector 0 20)) (v (make-float-vector 20 0.0))) (set! (v 2) .5) (set! (v 5) .25) (if (not (vequal samps v)) (snd-display #__line__ ";mix 1->1: ~A ~A" samps v))) (if (not (mix? tag)) (snd-display #__line__ ";mix 1->1 tag: ~A" tag)) (undo)) (let ((tag (car (mix "test.snd" 5)))) (let ((samps (channel->float-vector 0 20)) (v (make-float-vector 20 0.0))) (set! (v 7) .5) (set! (v 10) .25) (if (not (vequal samps v)) (snd-display #__line__ ";mix 1->1 at 5: ~A ~A" samps v))) (if (not (mix? tag)) (snd-display #__line__ ";mix 1->1 at 5 tag: ~A" tag)) (undo)) (let ((tag (mix "test.snd" 0 0 ind 0 #f))) (let ((samps (channel->float-vector 0 20)) (v (make-float-vector 20 0.0))) (set! (v 2) .5) (set! (v 5) .25) (if (not (vequal samps v)) (snd-display #__line__ ";mix 1->1 at 0 #f: ~A ~A" samps v))) (if (mix? tag) (snd-display #__line__ ";mix 1->1 at 5 #f tag: ~A" tag)) (undo)) (let ((indout (new-sound "test.snd" 2 22050 mus-ldouble mus-next "mix tests"))) (insert-silence 0 10 indout 0) (insert-silence 0 10 indout 1) (set! (sample 2 indout 0) .5) (set! (sample 5 indout 0) .25) (set! (sample 2 indout 1) .95) (set! (sample 5 indout 1) .125) (save-sound indout) (close-sound indout)) (let ((tag (car (mix "test.snd" 0 1)))) (let ((samps (channel->float-vector 0 20)) (v (make-float-vector 20 0.0))) (set! (v 2) .95) (set! (v 5) .125) (if (not (vequal samps v)) (snd-display #__line__ ";mix 2->1: ~A ~A" samps v))) (if (not (mix? tag)) (snd-display #__line__ ";mix 2->1 tag: ~A" tag)) (undo)) (let ((tag (car (mix "test.snd" 5 1)))) (let ((samps (channel->float-vector 0 20)) (v (make-float-vector 20 0.0))) (set! (v 7) .95) (set! (v 10) .125) (if (not (vequal samps v)) (snd-display #__line__ ";mix 2->1 at 5: ~A ~A" samps v))) (if (not (mix? tag)) (snd-display #__line__ ";mix 2->1 at 5 tag: ~A" tag)) (undo)) (close-sound ind) (set! ind (new-sound "fmv.snd" 2 22050 mus-ldouble mus-next "mix tests")) (insert-silence 0 20 ind 0) (insert-silence 0 20 ind 1) (let ((tag (car (mix "test.snd" 0 #t)))) (let ((samps0 (channel->float-vector 0 20 ind 0)) (samps1 (channel->float-vector 0 20 ind 1)) (v (make-float-vector 20 0.0))) (set! (v 2) .95) (set! (v 5) .125) (if (not (vequal samps1 v)) (snd-display #__line__ ";mix 1->1 (2): ~A ~A" samps1 v)) (set! (v 2) .5) (set! (v 5) .25) (if (not (vequal samps0 v)) (snd-display #__line__ ";mix 1->1 (3): ~A ~A" samps0 v))) (if (not (mix? tag)) (snd-display #__line__ ";mix 1->1 tag: ~A" tag)) (undo 1 ind 0) (undo 1 ind 1)) (let ((tag (mix "test.snd" 0 1 ind 1 #f))) ; samp:0, in-chan: 1 (let ((samps0 (channel->float-vector 0 20 ind 0)) (samps1 (channel->float-vector 0 20 ind 1)) (v (make-float-vector 20 0.0))) (if (not (vequal samps0 v)) (snd-display #__line__ ";mix 1->1 (4): ~A ~A" samps0 v)) (set! (v 2) .95) (set! (v 5) .125) (if (not (vequal samps1 v)) (snd-display #__line__ ";mix 1->1 (5): ~A ~A" samps1 v))) (if (mix? tag) (snd-display #__line__ ";mix 1->1 tag (5): ~A" tag)) (undo 1 ind 1)) (set! (sync ind) 1) (mix "test.snd" 0 #t) (let ((samps0 (channel->float-vector 0 20 ind 0)) (samps1 (channel->float-vector 0 20 ind 1)) (v (make-float-vector 20 0.0))) (set! (v 2) .5) (set! (v 5) .25) (if (not (vequal samps0 v)) (snd-display #__line__ ";mix 1->1 (6): ~A ~A" samps0 v)) (set! (v 2) .95) (set! (v 5) .125) (if (not (vequal samps1 v)) (snd-display #__line__ ";mix 1->1 (7): ~A ~A" samps1 v)) (undo)) (close-sound ind)) (delete-file "test.snd") (delete-file "fmv.snd") ;; check ripple_mixes (let* ((ind (open-sound "oboe.snd")) (data (channel->float-vector 100 100)) (m1 (mix-float-vector data 321 ind 0 #t)) (m2 (mix-float-vector data 123 ind 0 #t))) (set! (mix-position m1) 500) (if (not (= (mix-position m1) 500)) (snd-display #__line__ ";mix-position m1[0]: ~A" (mix-position m1))) (if (not (= (mix-position m2) 123)) (snd-display #__line__ ";mix-position m2[0]: ~A" (mix-position m2))) (undo) (set! (mix-position m2) 500) (if (not (= (mix-position m2) 500)) (snd-display #__line__ ";mix-position m2[1]: ~A" (mix-position m2))) (if (not (= (mix-position m1) 321)) (snd-display #__line__ ";mix-position m1[1]: ~A" (mix-position m1))) (undo) (insert-silence 0 100) (if (not (= (mix-position m1) (+ 100 321))) (snd-display #__line__ ";mix-position m1[2]: ~A" (mix-position m1))) (if (not (= (mix-position m2) (+ 100 123))) (snd-display #__line__ ";mix-position m2[2]: ~A" (mix-position m2))) (delete-samples 0 50) (if (not (= (mix-position m1) (+ 50 321))) (snd-display #__line__ ";mix-position m1[3]: ~A" (mix-position m1))) (if (not (= (mix-position m2) (+ 50 123))) (snd-display #__line__ ";mix-position m2[3]: ~A" (mix-position m2))) (undo 2) (set! (mix-position m2) 500) (undo) (scale-channel 0.5 1000 100) (if (not (= (mix-position m2) 123)) (snd-display #__line__ ";mix-position m2[5]: ~A" (mix-position m2))) (if (not (= (mix-position m1) 321)) (snd-display #__line__ ";mix-position m1[5]: ~A" (mix-position m1))) (undo) (set! (mix-position m2) 500) (undo) (set! (mix-position m2) 500) (undo-edit) (ramp-channel 0.0 1.0 3000 100) (catch #t (lambda () (if (not (= (mix-position m2) 123)) (snd-display #__line__ ";mix-position m2[7]: ~A" (mix-position m2))) (if (not (= (mix-position m1) 321)) (snd-display #__line__ ";mix-position m1[7]: ~A" (mix-position m1)))) (lambda args (snd-display #__line__ ";mix-position trouble: ~A" args))) (undo) (delay-channel-mixes 200 100 ind 0) (if (not (= (mix-position m2) 123)) (snd-display #__line__ ";delay-channel mixes mix-position m2: ~A" (mix-position m2))) (if (not (= (mix-position m1) 421)) (snd-display #__line__ ";delay-channel-mixes mix-position m1: ~A" (mix-position m1))) (check-mix-tags ind 0) (close-sound ind)) ;; check that current console is correct (let ((ind (open-sound "storm.snd"))) (set! (x-bounds) (list 0 80.0)) (make-selection 1000000 1050000) (let ((m1 (car (mix-selection 900000))) (m2 (car (mix-selection 400000)))) (as-one-edit (lambda () (set! (mix-position m1) 0) (set! (mix-position m2) 1))) (if (or (not (= (mix-position m1) 0)) (not (= (mix-position m2) 1))) (snd-display #__line__ ";as-one-edit positions: ~A ~A" (mix-position m1) (mix-position m2))) (undo-channel) (if (or (not (= (mix-position m1) 900000)) (not (= (mix-position m2) 400000))) (snd-display #__line__ ";as-one-edit positions after undo: (~A): ~A (~A): ~A" m1 (mix-position m1) m2 (mix-position m2))) (redo-channel) (if (or (not (= (mix-position m1) 0)) (not (= (mix-position m2) 1))) (snd-display #__line__ ";as-one-edit positions after redo: ~A ~A" (mix-position m1) (mix-position m2))) (close-sound ind))) (let ((ind (open-sound "2.snd"))) (make-selection 0 10000 ind) (if (not (= (selection-chans) 2)) (snd-display #__line__ ";stereo selection: ~A" (selection-chans))) (set! (sync ind) #t) (let ((md (car (mix-selection 500 ind)))) (if (not (mix? (integer->mix (+ 1 (mix->integer md))))) (snd-display #__line__ ";where is second mix? ~A ~A" md (mixes))) (if (not (= (edit-position ind 0) 1)) (snd-display #__line__ ";edit-position 0 after stereo mix selection: ~A" (edit-position ind 0))) (if (not (= (edit-position ind 1) 1)) (snd-display #__line__ ";edit-position 1 after stereo mix selection: ~A" (edit-position ind 1))) (set! (sync ind) #f) (undo-edit 1 ind 0) (delete-sample 25 ind 0) (set! (mix-position (integer->mix (+ 1 (mix->integer md)))) 750) (if (not (= (edit-position ind 1) 2)) (snd-display #__line__ ";edit-position 1 after stereo mix selection moved: ~A" (edit-position ind 2))) (revert-sound ind) (close-sound ind))) (let ((ind (new-sound "test.snd")) (v (make-float-vector 20))) (do ((i 0 (+ i 1))) ((= i 20)) (set! (v i) (* i .01))) (float-vector->channel v) (do ((i 0 (+ i 1))) ((= i 20)) (set! (v i) (* i -.01))) (let ((mx (mix-float-vector v 10))) (let ((hi (make-mix-sampler mx)) (ho (make-mix-sampler mx 5)) (happy #t)) (do ((i 0 (+ i 1))) ((or (not happy) (= i 10))) (let ((ho-val (ho)) (hi-val (hi))) (if (fneq hi-val (* i -.01)) (begin (snd-display #__line__ ";mix-reader at ~A from 0: ~A" i hi-val) (set! happy #f))) (if (fneq ho-val (* (+ i 5) -.01)) (begin (snd-display #__line__ ";mix-reader at ~A from 5: ~A" i ho-val) (set! happy #f))))))) (revert-sound ind) (set! v (make-float-vector 21)) (fill! v 0.5) (float-vector->channel v) (let ((mx (mix-float-vector v 10))) (set! (mix-amp-env mx) '(0 0 1 1)) (let ((hi (make-mix-sampler mx 0)) (ho (make-mix-sampler mx 10)) (happy #t)) (do ((i 0 (+ i 1))) ((or (not happy) (= i 10))) (let ((ho-val (ho)) (hi-val (hi))) (if (fneq hi-val (* i .025)) (begin (snd-display #__line__ ";mix-reader env'd at ~A from 0: ~A" i hi-val) (set! happy #f))) (if (fneq ho-val (* (+ i 10) .025)) (begin (snd-display #__line__ ";mix-reader env'd at ~A from 10: ~A" i ho-val) (set! happy #f))))))) (close-sound ind)) (let ((ind (open-sound "oboe.snd")) (id (mix-float-vector (make-float-vector 10 .1)))) (set! (mix-position id) 100) (if (or (not (= (mix-position id) 100)) (not (= (edit-position ind 0) 2))) (snd-display #__line__ ";mix-position init: ~A ~A" (mix-position id) (edit-position ind 0))) (set! (mix-position id) 100) (if (or (not (= (mix-position id) (mix-position id))) (not (= (edit-position ind 0) 2))) (snd-display #__line__ ";mix-position 2 (no-op): ~A ~A" (mix-position id) (edit-position ind 0))) (set! (mix-amp id) 1.0) (if (or (fneq (mix-amp id) 1.0) (not (= (edit-position ind 0) 2))) (snd-display #__line__ ";mix-amp no-op: ~A ~A" (mix-amp id) (edit-position ind 0))) (set! (mix-amp id) 0.5) (if (or (fneq (mix-amp id) 0.5) (not (= (edit-position ind 0) 3))) (snd-display #__line__ ";mix-amp .5: ~A ~A" (mix-amp id) (edit-position ind 0))) (set! (mix-speed id) 1.0) (if (or (fneq (mix-speed id) 1.0) (not (= (edit-position ind 0) 3))) (snd-display #__line__ ";mix-speed no-op: ~A ~A" (mix-speed id) (edit-position ind 0))) (set! (mix-speed id) .5) (if (or (fneq (mix-speed id) 0.5) (not (= (edit-position ind 0) 4))) (snd-display #__line__ ";mix-speed .5: ~A ~A" (mix-speed id) (edit-position ind 0))) (set! (mix-amp-env id) '(0 0 1 1)) (if (not (= (edit-position ind 0) 5)) (snd-display #__line__ ";mix-amp-env init: ~A ~A" (mix-amp-env id) (edit-position ind 0))) (set! (mix-amp-env id) '(0 0 1 1)) (if (not (= (edit-position ind 0) 5)) (snd-display #__line__ ";mix-amp-env no-op: ~A ~A" (mix-amp-env id) (edit-position ind 0))) (close-sound ind)) (let ((ind (new-sound "test.snd" 1 22050 mus-ldouble mus-next "color-mix tests" 300)) (old-color *mix-color*)) (set! *mix-color* (make-color-with-catch 1 1 0)) (let ((mix1 (mix-float-vector (make-float-vector 10 .5) 10))) (if (or (and (not (equal? (color->list *mix-color*) (list 1.0 1.0 0.0))) (not (equal? (color->list *mix-color*) (list 1.0 1.0 0.0 1.0)))) (and (not (equal? (color->list (mix-color mix1)) (list 1.0 1.0 0.0))) (not (equal? (color->list (mix-color mix1)) (list 1.0 1.0 0.0 1.0))))) (snd-display #__line__ ";set mix-color: ~A ~A ~A ~A" (color->list *mix-color*) (color->list (mix-color mix1)) (list 1.0 1.0 0.0) (color->list old-color))) (set! *mix-color* old-color) (save-mix mix1 "test1.snd") (let ((ind1 (open-sound "test1.snd"))) (if (not (= (framples ind1) (mix-length mix1))) (snd-display #__line__ ";save-mix framples: ~A ~A" (mix-length mix1) (framples ind1))) (if (not (vequal (channel->float-vector 0 10) (mix->float-vector mix1))) (snd-display #__line__ ";save-mix data: ~A ~A" (mix->float-vector mix1) (channel->float-vector 0 10 ind1))) (define mix7 (integer->mix 71231)) (if (mix? mix7) (snd-display #__line__ ";mix? ~A~%" mix7)) (catch #t (lambda () (save-mix mix7 "test.snd") (snd-display #__line__ ";save-mix of a bad mix??")) (lambda args #f)) (close-sound ind1) (if (file-exists? "test1.snd") (delete-file "test1.snd")))) (close-sound ind)) (let ((ind (new-sound "test.snd" 1 22050 mus-ldouble mus-next "lock mix tests" 300)) (mix1 (mix-float-vector (make-float-vector 10 .5) 10))) (set! (mix-amp mix1) 0.0) (if (fneq (maxamp ind 0) 0.0) (snd-display #__line__ ";delete-mix maxamp: ~A" (maxamp ind 0))) (undo-channel 1 ind 0) (if (fneq (maxamp ind 0) 0.5) (snd-display #__line__ ";undelete-mix maxamp: ~A" (maxamp ind 0))) (redo-channel 1 ind 0) (if (fneq (maxamp ind 0) 0.0) (snd-display #__line__ ";redelete-mix maxamp: ~A" (maxamp ind 0))) (undo 2) ; (if (mix? mix1) (snd-display #__line__ ";undo 2 kept mix?")) (if (fneq (maxamp ind 0) 0.0) (snd-display #__line__ ";no delete-mix maxamp: ~A" (maxamp ind 0))) (redo) (if (fneq (maxamp ind 0) 0.5) (snd-display #__line__ ";reundelete-mix maxamp: ~A" (maxamp ind 0))) (close-sound ind)) (let ((ind (new-sound "test.snd" :size 100))) (let ((id (mix-float-vector (make-float-vector 5 .5) 11))) ;; pad-channel (if (not (vequal (channel->float-vector 10 10) (float-vector 0 .5 .5 .5 .5 .5 0 0 0 0))) (snd-display #__line__ ";float-vector .5 at 11: ~A" (channel->float-vector 10 10))) (pad-channel 0 10) (if (not (mix? id)) (snd-display #__line__ ";pad locked mix? ~A" (mix? id))) (if (not (= (mix-position id) 21)) (snd-display #__line__ ";float-vector .5 at 21 position: ~A" (mix-position id))) (if (not (vequal (channel->float-vector 20 10) (float-vector 0 .5 .5 .5 .5 .5 0 0 0 0))) (snd-display #__line__ ";float-vector .5 at 21: ~A" (channel->float-vector 20 10))) (if (not (vequal (channel->float-vector 10 10) (make-float-vector 10 0.0))) (snd-display #__line__ ";float-vector .5 at 21 at 10: ~A" (channel->float-vector 10 10))) (pad-channel 30 10) (if (not (mix? id)) (snd-display #__line__ ";pad 30 locked mix? ~A" (mix? id))) (if (not (= (mix-position id) 21)) (snd-display #__line__ ";float-vector .5 at 21 position 30: ~A" (mix-position id))) (if (not (vequal (channel->float-vector 20 10) (float-vector 0 .5 .5 .5 .5 .5 0 0 0 0))) (snd-display #__line__ ";float-vector .5 at 21 30: ~A" (channel->float-vector 20 10))) (pad-channel 150 10) (if (not (mix? id)) (snd-display #__line__ ";pad 150 locked mix? ~A" (mix? id))) (if (not (= (mix-position id) 21)) (snd-display #__line__ ";float-vector .5 at 21 position 150: ~A" (mix-position id))) (if (not (vequal (channel->float-vector 20 10) (float-vector 0 .5 .5 .5 .5 .5 0 0 0 0))) (snd-display #__line__ ";float-vector .5 at 21 150: ~A" (channel->float-vector 20 10))) (pad-channel 20 10) (if (not (mix? id)) (snd-display #__line__ ";pad 20 locked mix? ~A" (mix? id))) (if (not (= (mix-position id) 31)) (snd-display #__line__ ";float-vector .5 at 31 position: ~A" (mix-position id))) (if (not (vequal (channel->float-vector 30 10) (float-vector 0 .5 .5 .5 .5 .5 0 0 0 0))) (snd-display #__line__ ";float-vector .5 at 31: ~A" (channel->float-vector 30 10))) (pad-channel 32 3) ; (if (mix? id) (snd-display #__line__ ";pad within mix but exists?: ~A" (mix? id))) (if (not (mix? id)) (snd-display #__line__ ";pad within mix but no mix?: ~A" (mix? id))) (if (not (vequal (channel->float-vector 30 10) (float-vector 0 .5 0 0 0 .5 .5 .5 .5 0))) (snd-display #__line__ ";float-vector .5 at 31 pad at 32: ~A" (channel->float-vector 30 10))) (set! (edit-position) 1) (if (not (mix? id)) (snd-display #__line__ ";mix float-vector after reset edit position: ~A" (mix? id))) (if (not (= (mix-position id) 11)) (snd-display #__line__ ";mix float-vector position after reset edit position: ~A" (mix-position id))) (if (not (vequal (channel->float-vector 10 10) (float-vector 0 .5 .5 .5 .5 .5 0 0 0 0))) (snd-display #__line__ ";float-vector .5 at 11 after reset edit: ~A" (channel->float-vector 10 10))) ;; delete (delete-samples 0 10) (if (not (mix? id)) (snd-display #__line__ ";delete locked mix? ~A" (mix? id))) (if (not (= (mix-position id) 1)) (snd-display #__line__ ";float-vector .5 at 1 position: ~A" (mix-position id))) (if (not (vequal (channel->float-vector 0 10) (float-vector 0 .5 .5 .5 .5 .5 0 0 0 0))) (snd-display #__line__ ";float-vector .5 at 1: ~A" (channel->float-vector 0 10))) (delete-samples 30 10) (if (not (mix? id)) (snd-display #__line__ ";delete 30 locked mix? ~A" (mix? id))) (if (not (= (mix-position id) 1)) (snd-display #__line__ ";float-vector .5 at 1 position del 30: ~A" (mix-position id))) (if (not (vequal (channel->float-vector 0 10) (float-vector 0 .5 .5 .5 .5 .5 0 0 0 0))) (snd-display #__line__ ";float-vector .5 at 1 del 30: ~A" (channel->float-vector 0 10))) (delete-samples 3 3) ; (if (mix? id) (snd-display #__line__ ";delete within mix but exists?: ~A" (mix? id))) (if (not (mix? id)) (snd-display #__line__ ";delete within mix but no mix?: ~A" (mix? id))) (if (not (vequal (channel->float-vector 0 10) (float-vector 0 .5 .5 0 0 0 0 0 0 0))) (snd-display #__line__ ";float-vector .5 at 1 del at 3: ~A" (channel->float-vector 0 10))) (set! (edit-position) 1) (if (not (mix? id)) (snd-display #__line__ ";mix float-vector after del reset edit position: ~A" (mix? id))) (if (not (= (mix-position id) 11)) (snd-display #__line__ ";mix float-vector position after del reset edit position: ~A" (mix-position id))) (if (not (vequal (channel->float-vector 10 10) (float-vector 0 .5 .5 .5 .5 .5 0 0 0 0))) (snd-display #__line__ ";float-vector .5 at 11 after del reset edit: ~A" (channel->float-vector 10 10))) ;; change (set! (samples 0 5) (make-float-vector 5 .6)) (if (not (mix? id)) (snd-display #__line__ ";set locked mix? ~A" (mix? id))) (if (not (= (mix-position id) 11)) (snd-display #__line__ ";float-vector .5 at 11 set position: ~A" (mix-position id))) (if (not (vequal (channel->float-vector 10 10) (float-vector 0 .5 .5 .5 .5 .5 0 0 0 0))) (snd-display #__line__ ";float-vector .5 at 11 set: ~A" (channel->float-vector 10 10))) (set! (samples 20 5) (make-float-vector 5 .7)) (if (not (mix? id)) (snd-display #__line__ ";set 20 locked mix? ~A" (mix? id))) (if (not (= (mix-position id) 11)) (snd-display #__line__ ";float-vector .5 at 11 set 20 position: ~A" (mix-position id))) (if (not (vequal (channel->float-vector 10 10) (float-vector 0 .5 .5 .5 .5 .5 0 0 0 0))) (snd-display #__line__ ";float-vector .5 at 11 set 20: ~A" (channel->float-vector 10 10))) (set! (samples 12 2) (float-vector -.5 .8)) ; (if (mix? id) (snd-display #__line__ ";set within mix but exists?: ~A" (mix? id))) (if (not (mix? id)) (snd-display #__line__ ";set within mix but no mix?: ~A" (mix? id))) (if (not (vequal (channel->float-vector 10 10) (float-vector 0 .5 -.5 .8 .5 .5 0 0 0 0))) (snd-display #__line__ ";float-vector .5 at 11 set at 12: ~A" (channel->float-vector 10 10))) (set! (edit-position) 1) (if (not (mix? id)) (snd-display #__line__ ";mix float-vector after set reset edit position: ~A" (mix? id))) (if (not (= (mix-position id) 11)) (snd-display #__line__ ";mix float-vector position after set reset edit position: ~A" (mix-position id))) (if (not (vequal (channel->float-vector 10 10) (float-vector 0 .5 .5 .5 .5 .5 0 0 0 0))) (snd-display #__line__ ";float-vector .5 at 11 after set reset edit: ~A" (channel->float-vector 10 10))) ;; scale (scale-channel 2.0) (if (not (mix? id)) (snd-display #__line__ ";scale locked mix? ~A" (mix? id))) (if (not (= (mix-position id) 11)) (snd-display #__line__ ";float-vector .5 at 11 scale position: ~A" (mix-position id))) (if (not (vequal (channel->float-vector 10 10) (float-vector 0 1 1 1 1 1 0 0 0 0))) (snd-display #__line__ ";float-vector 1 at 11 scale: ~A" (channel->float-vector 10 10))) (scale-channel 0.5) (if (not (mix? id)) (snd-display #__line__ ";unscale locked mix? ~A" (mix? id))) (if (not (= (mix-position id) 11)) (snd-display #__line__ ";float-vector .5 at 11 unscale position: ~A" (mix-position id))) (if (not (vequal (channel->float-vector 10 10) (float-vector 0 .5 .5 .5 .5 .5 0 0 0 0))) (snd-display #__line__ ";float-vector 1 at 11 unscale: ~A" (channel->float-vector 10 10))) (scale-channel -1.0 0 5) (if (not (mix? id)) (snd-display #__line__ ";scale at 0 locked mix? ~A" (mix? id))) (if (not (= (mix-position id) 11)) (snd-display #__line__ ";float-vector .5 at 11 scale at 0 position: ~A" (mix-position id))) (if (not (vequal (channel->float-vector 10 10) (float-vector 0 .5 .5 .5 .5 .5 0 0 0 0))) (snd-display #__line__ ";float-vector 1 at 11 scale at 0: ~A" (channel->float-vector 10 10))) (scale-channel -1.0 22 10) (if (not (mix? id)) (snd-display #__line__ ";scale at 22 locked mix? ~A" (mix? id))) (if (not (= (mix-position id) 11)) (snd-display #__line__ ";float-vector .5 at 11 scale at 22 position: ~A" (mix-position id))) (if (not (vequal (channel->float-vector 10 10) (float-vector 0 .5 .5 .5 .5 .5 0 0 0 0))) (snd-display #__line__ ";float-vector 1 at 11 scale at 22: ~A" (channel->float-vector 10 10))) (scale-channel 2.0 12 2) ; (if (mix? id) (snd-display #__line__ ";scale within mix but exists?: ~A" (mix? id))) (if (not (mix? id)) (snd-display #__line__ ";scale within mix but no mix?: ~A" (mix? id))) (if (not (vequal (channel->float-vector 10 10) (float-vector 0 .5 1 1 .5 .5 0 0 0 0))) (snd-display #__line__ ";float-vector .5 at 11 scale at 12: ~A" (channel->float-vector 10 10))) (set! (edit-position) 1) (if (not (mix? id)) (snd-display #__line__ ";mix float-vector after scale reset edit position: ~A" (mix? id))) (if (not (= (mix-position id) 11)) (snd-display #__line__ ";mix float-vector position after scale reset edit position: ~A" (mix-position id))) (if (not (vequal (channel->float-vector 10 10) (float-vector 0 .5 .5 .5 .5 .5 0 0 0 0))) (snd-display #__line__ ";float-vector .5 at 11 after scale reset edit: ~A" (channel->float-vector 10 10))) ;; envelopes (env-channel '(0 0 1 1) 0 8) (if (not (mix? id)) (snd-display #__line__ ";env locked mix? ~A" (mix? id))) (if (not (= (mix-position id) 11)) (snd-display #__line__ ";float-vector .5 at 11 env position: ~A" (mix-position id))) (if (not (vequal (channel->float-vector 10 10) (float-vector 0 .5 .5 .5 .5 .5 0 0 0 0))) (snd-display #__line__ ";float-vector 1 at 11 env: ~A" (channel->float-vector 10 10))) (env-channel '(0 0 1 1) 17 10) (if (not (mix? id)) (snd-display #__line__ ";env 17 locked mix? ~A" (mix? id))) (if (not (= (mix-position id) 11)) (snd-display #__line__ ";float-vector .5 at 11 env 17 position: ~A" (mix-position id))) (if (not (vequal (channel->float-vector 10 10) (float-vector 0 .5 .5 .5 .5 .5 0 0 0 0))) (snd-display #__line__ ";float-vector 1 at 11 env 17: ~A" (channel->float-vector 10 10))) (env-channel '(0 0 1 1)) ; (if (mix? id) (snd-display #__line__ ";env over mix but exists?: ~A" (mix? id))) (if (not (mix? id)) (snd-display #__line__ ";env over mix but no mix?: ~A" (mix? id))) (if (not (vequal (channel->float-vector 10 10) (float-vector 0.000 0.056 0.061 0.066 0.071 0.076 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";float-vector .5 at 11 over env: ~A" (channel->float-vector 10 10))) (set! (edit-position) 1) ; (if (not (mix? id)) (snd-display #__line__ ";mix float-vector after env reset edit position: ~A" (mix? id))) (if (not (= (mix-position id) 11)) (snd-display #__line__ ";mix float-vector position after env reset edit position: ~A" (mix-position id))) (if (not (vequal (channel->float-vector 10 10) (float-vector 0 .5 .5 .5 .5 .5 0 0 0 0))) (snd-display #__line__ ";float-vector .5 at 11 after env reset edit: ~A" (channel->float-vector 10 10))) (scale-by 0.0) (if (not (mix? id)) (snd-display #__line__ ";zero mix but no mix?: ~A" (mix? id))) (if (not (vequal (channel->float-vector 10 10) (float-vector 0 0 0 0 0 0 0 0 0 0))) (snd-display #__line__ ";float-vector 1 at 11 scale 0: ~A" (channel->float-vector 10 10))) (undo 2) (let ((ids ())) (do ((i 0 (+ i 1))) ((= i 5)) (set! ids (cons (mix-float-vector (make-float-vector 5 .1) (+ i 10)) ids))) (let ((vals (channel->float-vector 8 14))) (if (not (vequal vals (float-vector 0.000 0.000 0.100 0.200 0.300 0.400 0.500 0.400 0.300 0.200 0.100 0.000 0.000 0.000))) (snd-display #__line__ ";pile up mixes: ~A" vals))) (let ((mx (mixes-maxamp ids))) (if (fneq mx .1) (snd-display #__line__ ";mixes-maxamp: ~A" mx))) (let ((len (mixes-length ids))) (if (not (= len 10)) (snd-display #__line__ ";mixes-length: ~A" len))) (sync-all-mixes 21) (for-each (lambda (m) (if (not (= (mix-sync m) 21)) (snd-display #__line__ ";sync-all-mixes ~A: ~A" m (mix-sync m)))) ids) (sync-all-mixes 0) (for-each (lambda (m) (if (not (= (mix-sync m) 0)) (snd-display #__line__ ";re sync-all-mixes ~A: ~A" m (mix-sync m)))) ids) (scale-mixes ids -2.0) (for-each (lambda (m) (if (fneq (mix-amp m) -2.0) (snd-display #__line__ ";scale-mixes ~A: ~A" m (mix-amp m)))) ids) (let ((vals (channel->float-vector 8 14))) (if (not (vequal vals (float-vector 0.000 0.000 -0.200 -0.400 -0.600 -0.800 -1.000 -0.800 -0.600 -0.400 -0.200 0.000 0.000 0.000))) (snd-display #__line__ ";scale piled up mixes: ~A" vals))) (silence-mixes ids) (let ((vals (channel->float-vector 8 14))) (if (not (vequal vals (make-float-vector 14 0.0))) (snd-display #__line__ ";silence piled up mixes: ~A" vals))) (undo 2) (let ((vals (channel->float-vector 8 14))) (if (not (vequal vals (float-vector 0.000 0.000 0.100 0.200 0.300 0.400 0.500 0.400 0.300 0.200 0.100 0.000 0.000 0.000))) (snd-display #__line__ ";undo 2 to pile up mixes: ~A" vals))) (play-mixes ids) (set-mixes-tag-y ids 100) (for-each (lambda (m) (if (not (= (mix-tag-y m) 100)) (snd-display #__line__ ";set-mixes-tag-y ~A: ~A" m (mix-tag-y m)))) ids) (set-mixes-tag-y ids 0) (move-mixes ids 10) (let ((vals (channel->float-vector 18 14))) (if (not (vequal vals (float-vector 0.000 0.000 0.100 0.200 0.300 0.400 0.500 0.400 0.300 0.200 0.100 0.000 0.000 0.000))) (snd-display #__line__ ";move piled up mixes: ~A" vals))) (let ((vals (channel->float-vector 8 8))) (if (not (vequal vals (make-float-vector 8 0.0))) (snd-display #__line__ ";move piled up mixes original: ~A" vals))) (move-mixes ids -10) (let ((vals (channel->float-vector 8 14))) (if (not (vequal vals (float-vector 0.000 0.000 0.100 0.200 0.300 0.400 0.500 0.400 0.300 0.200 0.100 0.000 0.000 0.000))) (snd-display #__line__ ";move piled up mixes -10: ~A" vals))) (let ((vals (channel->float-vector 23 8))) (if (not (vequal vals (make-float-vector 8 0.0))) (snd-display #__line__ ";move piled up mixes -10: ~A" vals))) (for-each (lambda (m) (set! (mix-sync m) 24)) ids) (let ((mxs (syncd-mixes 24))) (if (not (= (length mxs) (length ids))) (snd-display #__line__ ";syncd-mixes: ~A ~A" mxs ids)) (for-each (lambda (m) (if (not (member m ids)) (snd-display #__line__ ";syncd-mixes: ~A not in ~A" m ids))) mxs)) (sync-all-mixes 0) (env-mixes ids '(0 0 1 1 2 0)) (let ((vals (channel->float-vector 10 10))) (if (not (vequal vals (float-vector 0.000 0.045 0.137 0.278 0.460 0.360 0.203 0.087 0.020 0.000))) (snd-display #__line__ ";env-mixes: ~A" vals))) (undo 3) (let ((vals (channel->float-vector 8 14))) (if (not (vequal vals (float-vector 0.000 0.000 0.100 0.200 0.300 0.400 0.500 0.400 0.300 0.200 0.100 0.000 0.000 0.000))) (snd-display #__line__ ";undo 3 mixes envd: ~A" vals))) (color-mixes ids (make-color 0 1 0)) (scale-tempo ids 2.0) (let ((begs (map mix-position ids))) (if (not (equal? begs (list 18 16 14 12 10))) (snd-display #__line__ ";scale-tempo by 2: ~A" begs))) (let ((vals (channel->float-vector 10 15))) (if (not (vequal vals (float-vector 0.100 0.100 0.200 0.200 0.300 0.200 0.300 0.200 0.300 0.200 0.200 0.100 0.100 0.000 0.000))) (snd-display #__line__ ";scale-tempo 2 vals: ~A" vals))) (scale-tempo ids 0.5) (let ((begs (map mix-position ids))) (if (not (equal? begs (list 14 13 12 11 10))) (snd-display #__line__ ";scale-tempo by 0.5: ~A" begs))) (let ((vals (channel->float-vector 10 10))) (if (not (vequal vals (float-vector 0.100 0.200 0.300 0.400 0.500 0.400 0.300 0.200 0.100 0.000))) (snd-display #__line__ ";scale-tempo back 0.5: ~A" vals))) (scale-tempo ids -1.0) (let ((begs (map mix-position ids))) (if (not (equal? begs (list 6 7 8 9 10))) (snd-display #__line__ ";scale-tempo by -1: ~A" begs))) (let ((vals (channel->float-vector 0 15))) (if (not (vequal vals (float-vector 0.000 0.000 0.000 0.000 0.000 0.000 0.100 0.200 0.300 0.400 0.500 0.400 0.300 0.200 0.100))) (snd-display #__line__ ";scale-tempo -1 vals: ~A" vals))) (undo 3) (set! *sinc-width* 10) (src-mixes ids 0.5) (if (fneq (mix-speed (car ids)) 0.5) (snd-display #__line__ ";src-mixes speed: ~A" (mix-speed (car ids)))) (if (not (= (mixes-length ids) 15)) (snd-display #__line__ ";src-mixes length: ~A" (mixes-length ids))) (let ((vals (channel->float-vector 10 15))) (if (not (vequal vals (float-vector 0.100 0.211 0.311 0.408 0.508 0.505 0.495 0.505 0.508 0.460 0.362 0.262 0.152 0.052 0.000))) (snd-display #__line__ ";src-mixes 0.5 vals: ~A" vals))) (if (not (vequal (mix->float-vector (car ids)) (mix->float-vector (cadr ids)))) (snd-display #__line__ ";src-mixes vals don't match: ~A ~A" (mix->float-vector (car ids)) (mix->float-vector (cadr ids)))) (undo) (transpose-mixes ids -12) (if (fneq (mix-speed (car ids)) 0.5) (snd-display #__line__ ";transpose-mixes speed: ~A" (mix-speed (car ids)))) (if (not (= (mixes-length ids) 15)) (snd-display #__line__ ";transpose-mixes length: ~A" (mixes-length ids))) (let ((vals (channel->float-vector 10 15))) (if (not (vequal vals (float-vector 0.100 0.211 0.311 0.408 0.508 0.505 0.495 0.505 0.508 0.460 0.362 0.262 0.152 0.052 0.000))) (snd-display #__line__ ";transpose-mixes 0.5 vals: ~A" vals))) (if (not (vequal (mix->float-vector (car ids)) (mix->float-vector (cadr ids)))) (snd-display #__line__ ";transpose-mixes vals don't match: ~A ~A" (mix->float-vector (car ids)) (mix->float-vector (cadr ids)))) (revert-sound)) (close-sound ind))) ;; check locks (let ((ind (new-sound "test.snd" :size 100))) (let ((id (mix-float-vector (float-vector .1 .2 .3) 50))) (if (not (mix? id)) (snd-display #__line__ ";mix lock 0: ~A ~A" id (mix? id))) (ramp-channel 0.0 1.0 0 20) (if (not (mix? id)) (snd-display #__line__ ";mix lock 5: ~A ~A" id (mix? id))) (undo) (xramp-channel 0.0 1.0 32.0 0 20) (if (not (mix? id)) (snd-display #__line__ ";mix lock 6: ~A ~A" id (mix? id))) (undo 2) (delete-sample 52) (if (not (mix? id)) (snd-display #__line__ ";mix lock 7: ~A ~A" id (mix? id))) (undo) (delete-sample 10) (if (not (mix? id)) (snd-display #__line__ ";mix lock 8: ~A ~A" id (mix? id))) (undo) (insert-samples 51 2 (float-vector .1 .2)) (if (not (mix? id)) (snd-display #__line__ ";mix lock 9: ~A ~A" id (mix? id))) (undo) (insert-samples 1 2 (float-vector .1 .2)) (if (not (mix? id)) (snd-display #__line__ ";mix lock 10: ~A ~A" id (mix? id))) (undo) (set! (sample 51) 1.0) (if (not (mix? id)) (snd-display #__line__ ";mix lock 11: ~A ~A" id (mix? id))) (undo) (set! (sample 1) 1.0) (if (not (mix? id)) (snd-display #__line__ ";mix lock 12: ~A ~A" id (mix? id))) (undo) (xramp-channel 0 1 32 0 40) (if (not (mix? id)) (snd-display #__line__ ";mix lock 13: ~A ~A" id (mix? id))) (xramp-channel 0 1 32 0 40) (if (not (mix? id)) (snd-display #__line__ ";mix lock 14: ~A ~A" id (mix? id))) (close-sound ind))) (do ((i 0 (+ i 1))) ((= i 2)) (let ((ind (new-sound "test.snd" :size 100)) (tag *with-mix-tags*)) ;; check various mix ops briefly (map-channel (lambda (y) 1.0)) (env-channel '(0 0 1 1)) (let ((id (mix-float-vector (float-vector .1 .2 .3) 50))) (let ((vals (channel->float-vector 48 10))) (if (not (vequal vals (float-vector 0.485 0.495 0.605 0.715 0.825 0.535 0.545 0.556 0.566 0.576))) (snd-display #__line__ ";mix on env: ~A" vals))) (if (and tag (not (mix? id))) (snd-display #__line__ ";mix on env: ~A ~A" id (mix? id))) (if (and tag (not (= ((cadr (edit-tree)) 7) 5))) (snd-display #__line__ ";mix on env edit-tree: ~A" ((cadr (edit-tree)) 7))) (let ((data (make-float-vector 10)) (reader (make-sampler 57 ind 0 -1))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (data i) (read-sample reader))) (if (not (vequal data (reverse! (float-vector 0.485 0.495 0.605 0.715 0.825 0.535 0.545 0.556 0.566 0.576)))) (snd-display #__line__ ";read mix on env reversed: ~A" data))) (undo)) (env-channel '(0 0 1 1)) (let ((id (mix-float-vector (float-vector .1 .2 .3) 50))) (let ((vals (channel->float-vector 48 10))) (if (not (vequal vals (float-vector 0.235 0.245 0.355 0.465 0.576 0.287 0.298 0.309 0.320 0.331))) (snd-display #__line__ ";mix on env 1: ~A" vals))) (if (and tag (not (mix? id))) (snd-display #__line__ ";mix on env 1: ~A ~A" id (mix? id))) (if (and tag (not (= ((cadr (edit-tree)) 7) 7))) (snd-display #__line__ ";mix on env1 edit-tree: ~A" ((cadr (edit-tree)) 7))) (let ((data (make-float-vector 10)) (reader (make-sampler 57 ind 0 -1))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (data i) (read-sample reader))) (if (not (vequal data (reverse! (float-vector 0.235 0.245 0.355 0.465 0.576 0.287 0.298 0.309 0.320 0.331)))) (snd-display #__line__ ";read mix on env1 reversed: ~A" data))) (undo)) (env-channel '(0 0 1 1)) (let ((id (mix-float-vector (float-vector .1 .2 .3) 50))) (let ((vals (channel->float-vector 48 10))) (if (not (vequal vals (float-vector 0.114 0.121 0.229 0.337 0.445 0.153 0.162 0.171 0.181 0.191))) (snd-display #__line__ ";mix on env 2: ~A" vals))) (if (and tag (not (mix? id))) (snd-display #__line__ ";mix on env 2: ~A ~A" id (mix? id))) (if (and tag (not (= ((cadr (edit-tree)) 7) 11))) (snd-display #__line__ ";mix on env2 edit-tree: ~A" ((cadr (edit-tree)) 7))) (let ((data (make-float-vector 10)) (reader (make-sampler 57 ind 0 -1))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (data i) (read-sample reader))) (if (not (vequal data (reverse! (float-vector 0.114 0.121 0.229 0.337 0.445 0.153 0.162 0.171 0.181 0.191)))) (snd-display #__line__ ";read mix on env2 reversed: ~A" data))) (undo)) (env-channel '(0 0 1 1)) (let ((id (mix-float-vector (float-vector .1 .2 .3) 50))) (let ((vals (channel->float-vector 48 10))) (if (not (vequal vals (float-vector 0.055 0.060 0.165 0.270 0.376 0.082 0.089 0.095 0.102 0.110))) (snd-display #__line__ ";mix on env 3: ~A" vals))) (if (and tag (not (mix? id))) (snd-display #__line__ ";mix on env 3: ~A ~A" id (mix? id))) (if (and tag (not (= ((cadr (edit-tree)) 7) 11))) (snd-display #__line__ ";mix on env3 edit-tree: ~A" ((cadr (edit-tree)) 7))) (let ((data (make-float-vector 10)) (reader (make-sampler 57 ind 0 -1))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (data i) (read-sample reader))) (if (not (vequal data (reverse! (float-vector 0.055 0.060 0.165 0.270 0.376 0.082 0.089 0.095 0.102 0.110)))) (snd-display #__line__ ";read mix on env3 reversed: ~A" data))) (undo)) (env-channel '(0 0 1 1)) (let ((id (mix-float-vector (float-vector .1 .2 .3) 50))) (let ((vals (channel->float-vector 48 10))) (if (not (vequal vals (float-vector 0.027 0.030 0.133 0.236 0.340 0.044 0.048 0.053 0.058 0.063))) (snd-display #__line__ ";mix on env 4: ~A" vals))) (if (and tag (not (mix? id))) (snd-display #__line__ ";mix on env 4: ~A ~A" id (mix? id))) (if (and tag (not (= ((cadr (edit-tree)) 7) 11))) (snd-display #__line__ ";mix on env4 edit-tree: ~A" ((cadr (edit-tree)) 7))) (let ((data (make-float-vector 10)) (reader (make-sampler 57 ind 0 -1))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (data i) (read-sample reader))) (if (not (vequal data (reverse! (float-vector 0.027 0.030 0.133 0.236 0.340 0.044 0.048 0.053 0.058 0.063)))) (snd-display #__line__ ";read mix on env4 reversed: ~A" data))) (undo)) (set! (edit-position ind 0) 1) (xramp-channel 1 0 32.0) (let ((id (mix-float-vector (float-vector .1 .2 .3) 50))) (let ((vals (channel->float-vector 48 10))) (if (not (vequal vals (float-vector 0.160 0.153 0.247 0.341 0.435 0.129 0.124 0.118 0.113 0.108))) (snd-display #__line__ ";mix on xramp: ~A" vals))) (if (and tag (not (mix? id))) (snd-display #__line__ ";mix on xramp: ~A ~A" id (mix? id))) (if (and tag (not (= ((cadr (edit-tree)) 7) 9))) (snd-display #__line__ ";mix on xramp edit-tree: ~A" ((cadr (edit-tree)) 7))) (let ((data (make-float-vector 10)) (reader (make-sampler 57 ind 0 -1))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (data i) (read-sample reader))) (if (not (vequal data (reverse! (float-vector 0.160 0.153 0.247 0.341 0.435 0.129 0.124 0.118 0.113 0.108)))) (snd-display #__line__ ";read mix on xramp reversed: ~A" data)))) (set! (edit-position ind 0) 1) (xramp-channel 1 0 32.0) (xramp-channel 1 0 32.0) (let ((id (mix-float-vector (float-vector .1 .2 .3) 50))) (let ((vals (channel->float-vector 48 10))) (if (not (vequal vals (float-vector 0.026 0.024 0.122 0.220 0.318 0.017 0.015 0.014 0.013 0.012))) (snd-display #__line__ ";mix on xramp2: ~A" vals))) (if (and tag (not (mix? id))) (snd-display #__line__ ";mix on xramp2: ~A ~A" id (mix? id))) (if (and tag (not (= ((cadr (edit-tree)) 7) 13))) (snd-display #__line__ ";mix on xramp2 edit-tree: ~A" ((cadr (edit-tree)) 7))) (let ((data (make-float-vector 10)) (reader (make-sampler 57 ind 0 -1))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (data i) (read-sample reader))) (if (not (vequal data (reverse! (float-vector 0.026 0.024 0.122 0.220 0.318 0.017 0.015 0.014 0.013 0.012)))) (snd-display #__line__ ";read mix on xramp2 reversed: ~A" data)))) (set! (edit-position ind 0) 1) (xramp-channel 1 0 32.0) (xramp-channel 1 0 32.0) (ramp-channel 1 0) (let ((id (mix-float-vector (float-vector .1 .2 .3) 50))) (let ((vals (channel->float-vector 48 10))) (if (not (vequal vals (float-vector 0.013 0.012 0.111 0.210 0.309 0.008 0.007 0.006 0.006 0.005))) (snd-display #__line__ ";mix on xramp2_ramp: ~A" vals))) (if (and tag (not (mix? id))) (snd-display #__line__ ";mix on xramp2_ramp: ~A ~A" id (mix? id))) (if (and tag (not (= ((cadr (edit-tree)) 7) 15))) (snd-display #__line__ ";mix on xramp2_ramp edit-tree: ~A" ((cadr (edit-tree)) 7))) (let ((data (make-float-vector 10)) (reader (make-sampler 57 ind 0 -1))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (data i) (read-sample reader))) (if (not (vequal data (reverse! (float-vector 0.013 0.012 0.111 0.210 0.309 0.008 0.007 0.006 0.006 0.005)))) (snd-display #__line__ ";read mix on xramp2_ramp reversed: ~A" data)))) (set! (edit-position ind 0) 1) (xramp-channel 1 0 32.0) (xramp-channel 1 0 32.0) (ramp-channel 1 0) (ramp-channel 1 0) (let ((id (mix-float-vector (float-vector .1 .2 .3) 50))) (let ((vals (channel->float-vector 48 10))) (if (not (vequal vals (float-vector 0.007 0.006 0.105 0.205 0.304 0.004 0.003 0.003 0.002 0.002))) (snd-display #__line__ ";mix on xramp2_ramp2: ~A" vals))) (if (and tag (not (mix? id))) (snd-display #__line__ ";mix on xramp2_ramp2: ~A ~A" id (mix? id))) (if (and tag (not (= ((cadr (edit-tree)) 7) 15))) (snd-display #__line__ ";mix on xramp2_ramp2 edit-tree: ~A" ((cadr (edit-tree)) 7))) (let ((data (make-float-vector 10)) (reader (make-sampler 57 ind 0 -1))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (data i) (read-sample reader))) (if (not (vequal data (reverse! (float-vector 0.007 0.006 0.105 0.205 0.304 0.004 0.003 0.003 0.002 0.002)))) (snd-display #__line__ ";read mix on xramp2_ramp2 reversed: ~A" data)))) (set! (edit-position ind 0) 1) (xramp-channel 1 0 32.0) (ramp-channel 1 0) (let ((id (mix-float-vector (float-vector .1 .2 .3) 50))) (let ((vals (channel->float-vector 48 10))) (if (not (vequal vals (float-vector 0.082 0.077 0.173 0.268 0.364 0.060 0.056 0.053 0.049 0.046))) (snd-display #__line__ ";mix on xramp_ramp: ~A" vals))) (if (and tag (not (mix? id))) (snd-display #__line__ ";mix on xramp_ramp: ~A ~A" id (mix? id))) (if (and tag (not (= ((cadr (edit-tree)) 7) 15))) (snd-display #__line__ ";mix on xramp_ramp edit-tree: ~A" ((cadr (edit-tree)) 7))) (let ((data (make-float-vector 10)) (reader (make-sampler 57 ind 0 -1))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (data i) (read-sample reader))) (if (not (vequal data (reverse! (float-vector 0.082 0.077 0.173 0.268 0.364 0.060 0.056 0.053 0.049 0.046)))) (snd-display #__line__ ";read mix on xramp_ramp reversed: ~A" data)))) (set! (edit-position ind 0) 1) (xramp-channel 1 0 32.0) (ramp-channel 1 0) (ramp-channel 1 0) (let ((id (mix-float-vector (float-vector .1 .2 .3) 50))) (let ((vals (channel->float-vector 48 10))) (if (not (vequal vals (float-vector 0.042 0.039 0.136 0.233 0.330 0.028 0.026 0.023 0.021 0.019))) (snd-display #__line__ ";mix on xramp_ramp2: ~A" vals))) (if (and tag (not (mix? id))) (snd-display #__line__ ";mix on xramp_ramp2: ~A ~A" id (mix? id))) (if (and tag (not (= ((cadr (edit-tree)) 7) 15))) (snd-display #__line__ ";mix on xramp_ramp2 edit-tree: ~A" ((cadr (edit-tree)) 7))) (let ((data (make-float-vector 10)) (reader (make-sampler 57 ind 0 -1))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (data i) (read-sample reader))) (if (not (vequal data (reverse! (float-vector 0.042 0.039 0.136 0.233 0.330 0.028 0.026 0.023 0.021 0.019)))) (snd-display #__line__ ";read mix on xramp_ramp2 reversed: ~A" data)))) (set! (edit-position ind 0) 1) (xramp-channel 1 0 32.0) (ramp-channel 1 0) (ramp-channel 1 0) (ramp-channel 1 0) (let ((id (mix-float-vector (float-vector .1 .2 .3) 50))) (let ((vals (channel->float-vector 48 10))) (if (not (vequal vals (float-vector 0.022 0.020 0.118 0.216 0.314 0.013 0.012 0.010 0.009 0.008))) (snd-display #__line__ ";mix on xramp_ramp3: ~A" vals))) (if (and tag (not (mix? id))) (snd-display #__line__ ";mix on xramp_ramp3: ~A ~A" id (mix? id))) (if (and tag (not (= ((cadr (edit-tree)) 7) 15))) (snd-display #__line__ ";mix on xramp_ramp3 edit-tree: ~A" ((cadr (edit-tree)) 7))) (let ((data (make-float-vector 10)) (reader (make-sampler 57 ind 0 -1))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (data i) (read-sample reader))) (if (not (vequal data (reverse! (float-vector 0.022 0.020 0.118 0.216 0.314 0.013 0.012 0.010 0.009 0.008)))) (snd-display #__line__ ";read mix on xramp_ramp3 reversed: ~A" data)))) (set! *with-mix-tags* #t) (revert-sound) (mix-float-vector (float-vector .1 .2 .3) 50) (reverse-sound) (let ((vals (channel->float-vector 45 8))) (if (not (vequal vals (float-vector 0.000 0.000 0.300 0.200 0.100 0.000 0.000 0.000))) (snd-display #__line__ ";reversed mix vals: ~A" vals))) (close-sound ind)) (set! *with-mix-tags* #f)) (set! *with-mix-tags* #t) (let ((ind (open-sound "oboe.snd"))) (mix-float-vector (make-float-vector 100 .1) 1000) (for-each (lambda (mtest) (let ((func (car mtest)) ;;(beg (cadr mtest)) ;;(lock (caddr mtest)) ;;(name (cadddr mtest)) (edpos (edit-position ind 0))) (func) (set! (edit-position ind 0) edpos))) (list (list (lambda () (pad-channel 0 100)) 1100 #f 'pad0) (list (lambda () (pad-channel 0 2000)) 3000 #f 'pad20) (list (lambda () (pad-channel 800 100)) 1100 #f 'pad800) (list (lambda () (pad-channel 850 100)) 1100 #f 'pad800) (list (lambda () (pad-channel 990 100)) 1100 #f 'pad990) (list (lambda () (pad-channel 1010 100)) 1000 #t 'pad1010) (list (lambda () (pad-channel 1050 10)) 1000 #t 'pad1050) (list (lambda () (pad-channel 1110 100)) 1000 #f 'pad1110) (list (lambda () (pad-channel 2000 100)) 1000 #f 'pad2000) (list (lambda () (insert-samples 0 100 (make-float-vector 100 .2))) 1100 #f 'insert0) (list (lambda () (insert-samples 800 100 (make-float-vector 100 .2))) 1100 #f 'insert800) (list (lambda () (insert-samples 990 100 (make-float-vector 100 .2))) 1100 #f 'insert990) (list (lambda () (insert-samples 1010 100 (make-float-vector 100 .2))) 1000 #t 'insert1010) (list (lambda () (insert-samples 1050 10 (make-float-vector 100 .2))) 1000 #t 'insert1050) (list (lambda () (insert-samples 1110 100 (make-float-vector 100 .2))) 1000 #f 'insert1110) (list (lambda () (insert-samples 2000 100 (make-float-vector 100 .2))) 1000 #f 'insert2000) (let ((fr (mus-sound-framples "1a.snd"))) (list (lambda () (insert-sound "1a.snd" 0)) (+ fr 1000) #f 'inserts0) (list (lambda () (insert-sound "1a.snd" 800)) (+ fr 1000) #f 'inserts800) (list (lambda () (insert-sound "1a.snd" 990)) (+ fr 1000) #f 'inserts990) (list (lambda () (insert-sound "1a.snd" 1010)) 1000 #t 'inserts1010) (list (lambda () (insert-sound "1a.snd" 1050)) 1000 #t 'inserts1050) (list (lambda () (insert-sound "1a.snd" 1110)) 1000 #f 'inserts1110) (list (lambda () (insert-sound "1a.snd" 2000)) 1000 #f 'inserts2000)) (list (lambda () (delete-samples 0 100)) 900 #f 'delete0) (list (lambda () (delete-samples 0 2000)) 1000 #t 'delete20) (list (lambda () (delete-samples 800 100)) 900 #f 'delete800) (list (lambda () (delete-samples 850 100)) 900 #f 'delete850) (list (lambda () (delete-samples 950 40)) 960 #f 'delete950) (list (lambda () (delete-samples 990 100)) 1000 #t 'delete990) (list (lambda () (delete-samples 1010 100)) 1000 #t 'delete1010) (list (lambda () (delete-samples 1050 10)) 1000 #t 'delete1050) (list (lambda () (delete-samples 1110 100)) 1000 #f 'delete1110) (list (lambda () (delete-samples 2000 100)) 1000 #f 'delete2000) (list (lambda () (set! (samples 0 100) (make-float-vector 100 .2))) 1000 #f 'set0) (list (lambda () (set! (samples 0 2000) (make-float-vector 2000 .2))) 1000 #t 'set0) (list (lambda () (set! (samples 800 100) (make-float-vector 100 .2))) 1000 #f 'set800) (list (lambda () (set! (samples 990 100) (make-float-vector 100 .2))) 1000 #t 'set990) (list (lambda () (set! (samples 1010 100) (make-float-vector 100 .2))) 1000 #t 'set1010) (list (lambda () (set! (samples 1050 10) (make-float-vector 100 .2))) 1000 #t 'set1050) (list (lambda () (set! (samples 1110 100) (make-float-vector 100 .2))) 1000 #f 'set1110) (list (lambda () (set! (samples 2000 100) (make-float-vector 100 .2))) 1000 #f 'set2000) (list (lambda () (scale-channel 2.0 0 100)) 1000 #f 'scale0) (list (lambda () (scale-channel 2.0 0 2000)) 1000 #t 'scale20) (list (lambda () (scale-channel 2.0 800 100)) 1000 #f 'scale800) (list (lambda () (scale-channel 2.0 850 100)) 1000 #f 'scale850) (list (lambda () (scale-channel 2.0 950 40)) 1000 #f 'scale950) (list (lambda () (scale-channel 2.0 990 100)) 1000 #t 'scale990) (list (lambda () (scale-channel 2.0 1010 100)) 1000 #t 'scale1010) (list (lambda () (scale-channel 2.0 1050 10)) 1000 #t 'scale1050) (list (lambda () (scale-channel 2.0 1110 100)) 1000 #f 'scale1110) (list (lambda () (scale-channel 2.0 2000 100)) 1000 #f 'scale2000) (list (lambda () (env-channel '(0 0 1 1) 0 100)) 1000 #f 'env0) (list (lambda () (env-channel '(0 0 1 1) 0 2000)) 1000 #t 'env20) (list (lambda () (env-channel '(0 0 1 1) 800 100)) 1000 #f 'env800) (list (lambda () (env-channel '(0 0 1 1) 850 100)) 1000 #f 'env850) (list (lambda () (env-channel '(0 0 1 1) 950 40)) 1000 #f 'env950) (list (lambda () (env-channel '(0 0 1 1) 990 100)) 1000 #t 'env990) (list (lambda () (env-channel '(0 0 1 1) 1010 100)) 1000 #t 'env1010) (list (lambda () (env-channel '(0 0 1 1) 1050 10)) 1000 #t 'env1050) (list (lambda () (env-channel '(0 0 1 1) 1110 100)) 1000 #f 'env1110) (list (lambda () (env-channel '(0 0 1 1) 2000 100)) 1000 #f 'env2000) )) (close-sound ind)) (let ((ind (open-sound "4.aiff")) (selind (open-sound "oboe.snd"))) (make-selection 100 500 selind 0) (mix-selection 500 ind 2) (if (not (= (edit-position ind 0) 0)) (snd-display #__line__ ";mix-selection 0->2 0: ~A" (edit-position ind 0))) (if (not (= (edit-position ind 1) 0)) (snd-display #__line__ ";mix-selection 0->2 1: ~A" (edit-position ind 1))) (if (not (= (edit-position ind 2) 1)) (snd-display #__line__ ";mix-selection 0->2 2: ~A" (edit-position ind 2))) (if (not (= (edit-position ind 3) 0)) (snd-display #__line__ ";mix-selection 0->2 3: ~A" (edit-position ind 3))) (revert-sound ind) (set! (sync ind) 1234) (mix-selection 500 ind 1) (if (not (= (edit-position ind 0) 0)) (snd-display #__line__ ";mix-selection 1->2 0: ~A" (edit-position ind 0))) (if (not (= (edit-position ind 1) 1)) (snd-display #__line__ ";mix-selection 1->2 1: ~A" (edit-position ind 1))) (if (not (= (edit-position ind 2) 0)) (snd-display #__line__ ";mix-selection 1->2 2: ~A" (edit-position ind 2))) (if (not (= (edit-position ind 3) 0)) (snd-display #__line__ ";mix-selection 1->2 3: ~A" (edit-position ind 3))) (revert-sound ind) (set! (sync ind) 0) (insert-selection 500 ind 2) (if (not (= (edit-position ind 0) 0)) (snd-display #__line__ ";insert-selection 0->2 0: ~A" (edit-position ind 0))) (if (not (= (edit-position ind 1) 0)) (snd-display #__line__ ";insert-selection 0->2 1: ~A" (edit-position ind 1))) (if (not (= (edit-position ind 2) 1)) (snd-display #__line__ ";insert-selection 0->2 2: ~A" (edit-position ind 2))) (if (not (= (edit-position ind 3) 0)) (snd-display #__line__ ";insert-selection 0->2 3: ~A" (edit-position ind 3))) (revert-sound ind) (set! (sync ind) 1234) (insert-selection 500 ind 1) (if (not (= (edit-position ind 0) 0)) (snd-display #__line__ ";insert-selection 1->2 0: ~A" (edit-position ind 0))) (if (not (= (edit-position ind 1) 1)) (snd-display #__line__ ";insert-selection 1->2 1: ~A" (edit-position ind 1))) (if (not (= (edit-position ind 2) 0)) (snd-display #__line__ ";insert-selection 1->2 2: ~A" (edit-position ind 2))) (if (not (= (edit-position ind 3) 0)) (snd-display #__line__ ";insert-selection 1->2 3: ~A" (edit-position ind 3))) (revert-sound ind) (set! (sync ind) 0) (close-sound ind) (close-sound selind)) (let ((new-index (new-sound "hiho.wave" 1 22050 mus-ldouble mus-next))) (log-mem test-ctr) (select-sound new-index) (if (find-mix 0 new-index 0) (snd-display #__line__ ";found non-existent mix? ~A" (find-mix 0 new-index 0))) (let ((mix-id (car (mix "pistol.snd" 100)))) (if (not (mix? mix-id)) (snd-display #__line__ ";~A not mix?" mix-id)) (view-mixes-dialog) (let ((pos (mix-position mix-id)) (len (mix-length mix-id)) (spd (mix-speed mix-id)) (snd (car (mix-home mix-id))) (chn (cadr (mix-home mix-id))) (nam (mix-name mix-id)) (amp (mix-amp mix-id)) (mr (make-mix-sampler mix-id))) (if (not (mix-sampler? mr)) (snd-display #__line__ ";~A not mix-sampler?" mr)) (if (region-sampler? mr) (snd-display #__line__ ";mix sampler: region ~A" mr)) ; (if (sampler? mr) (snd-display #__line__ ";mix sampler: normal ~A" mr)) (if (not (= (sampler-position mr) 0)) (snd-display #__line__ ";mix sampler position: ~A" (sampler-position mr))) (if (sampler-at-end? mr) (snd-display #__line__ ";mix sampler at end? ~A" mr)) (if (not (equal? (sampler-home mr) mix-id)) (snd-display #__line__ ";~A home: ~A" mr (sampler-home mr))) (let ((reader-string (format #f "~A" mr))) (if (not (string=? (substring reader-string 0 16) "#id "test-mix"))) (if (not (equal? id mix-id)) (snd-display #__line__ ";mix-name->id: ~A ~A" id mix-id))) (set! (mix-name mix-id) "test-mix-again") ; make sure previous name is freed (if (or (not (string? (mix-name mix-id))) (not (string=? (mix-name mix-id) "test-mix-again"))) (snd-display #__line__ ";mix-name set again: ~A" (mix-name mix-id))) (set! (mix-name mix-id) "") (if (not (equal? (mix-name mix-id) "")) (snd-display #__line__ ";set mix-name #f: ~A" (mix-name mix-id))) (set! (mix-position mix-id) 200) (set! (mix-amp mix-id) 0.5) (set! (mix-speed mix-id) 2.0) (set! (mix-amp-env mix-id) '(0.0 0.0 1.0 1.0)) (set! (mix-tag-y mix-id) 20) (let ((pos (mix-position mix-id)) (spd (mix-speed mix-id)) (amp (mix-amp mix-id)) (my (mix-tag-y mix-id))) (if (not (= pos 200)) (snd-display #__line__ ";set-mix-position: ~A?" pos)) (if (not (= my 20)) (snd-display #__line__ ";set-mix-tag-y: ~A?" my)) (if (fneq amp 0.5) (snd-display #__line__ ";set-mix-amp: ~A?" amp)) (if (fneq spd 2.0) (snd-display #__line__ ";set-mix-speed: ~A?" spd)) (if (not (equal? (mix-amp-env mix-id) '(0.0 0.0 1.0 1.0))) (snd-display #__line__ ";set-mix-amp-env: ~A?" (mix-amp-env mix-id)))) )) (mix-float-vector (make-float-vector 3 .1) 100) (set! (cursor) 0) (let ((nid (find-mix 100))) (if (or (not (mix? nid)) (not (= (mix-position nid) 100))) (snd-display #__line__ ";find-mix(100): ~A ~A ~A?" nid (and (mix? nid) (mix-position nid)) (map mix-position (mixes new-index 0))))) (let ((nid (find-mix 200))) (if (or (not (mix? nid)) (not (= (mix-position nid) 200))) (snd-display #__line__ ";find-mix(200): ~A ~A?" nid (and (mix? nid) (mix-position nid))))) (let ((mix-id (car (mix "oboe.snd" 100)))) (set! *mix-waveform-height* 40) (set! (mix-property :hiho mix-id) 123) (if (not (= (mix-property :hiho mix-id) 123)) (snd-display #__line__ ";mix-property: ~A" (mix-property :hiho mix-id))) (if (mix-property :not-there mix-id) (snd-display #__line__ ";mix-not-property: ~A" (mix-property :not-there mix-id))) (update-time-graph) (set! *mix-waveform-height* 20)) (close-sound new-index)) ) (dismiss-all-dialogs) ;; pan-mix tests (let ((ind (new-sound "fmv.snd" 1 22050 mus-ldouble mus-next "pan-mix tests"))) (let ((id0 (car (pan-mix "1a.snd" 10000 '(0 0 1 1))))) (if (or (fneq (mix-amp id0) 1.0) (not (feql (mix-amp-env id0) '(0 1 1 0)))) (snd-display #__line__ ";pan-mix 1->1 2: ~A ~A" (mix-amp id0) (mix-amp-env id0))) (if (not (= (mix-position id0) 10000)) (snd-display #__line__ ";pan-mix 1->1 pos 2: ~A" (mix-position id0))) (revert-sound ind)) (let* ((ids (pan-mix "2a.snd" 100 '(0 0 1 1))) (id0 (car ids)) (id1 (cadr ids))) (if (or (not (mix? id0)) (not (mix? id1))) (snd-display #__line__ ";pan-mix 2->1: ~A ~A" id0 id1)) (if (not (= (mix-position id0) (mix-position id1) 100)) (snd-display #__line__ ";pan-mix 2->1 pos: ~A ~A" (mix-position id0) (mix-position id1))) (if (or (fneq (mix-amp id0) 1.0) (fneq (mix-amp id1) 1.0)) (snd-display #__line__ ";pan-mix 2->1 mix amps 3: ~A ~A" (mix-amp id0) (mix-amp id1))) (if (not (feql (mix-amp-env id0) '(0 1 1 0))) (snd-display #__line__ ";pan-mix 2->1 ramp env: ~A" (mix-amp-env id0))) (revert-sound ind)) (close-sound ind)) (let ((ind (new-sound "fmv.snd" 2 22050 mus-ldouble mus-next "pan-mix tests"))) (let* ((ids (pan-mix "1a.snd" 100 '(0 0 1 1 2 0))) (id0 (car ids)) (id1 (cadr ids))) (if (or (not (mix? id0)) (not (mix? id1))) (snd-display #__line__ ";pan-mix 1->2: ~A ~A" id0 id1)) (if (not (= (mix-position id0) (mix-position id1) 100)) (snd-display #__line__ ";pan-mix 1->2 pos: ~A ~A" (mix-position id0) (mix-position id1))) (if (or (fneq (mix-amp id0) 1.0) (fneq (mix-amp id1) 1.0)) (snd-display #__line__ ";pan-mix 1->2 amps: ~A ~A" (mix-amp id0) (mix-amp id1))) (if (not (feql (mix-amp-env id0) '(0 1 1 0 2 1))) (snd-display #__line__ ";pan-mix 1->2 env 0: ~A" (mix-amp-env id0))) (if (not (feql (mix-amp-env id1) '(0 0 1 1 2 0))) (snd-display #__line__ ";pan-mix 1->2 env 1: ~A" (mix-amp-env id1))) (revert-sound ind)) (let* ((ids (pan-mix "2a.snd" 100 '(0 0 1 1 2 0))) (id0 (car ids)) (id1 (cadr ids)) (id2 (caddr ids)) (id3 (cadddr ids))) (if (or (not (mix? id0)) (not (mix? id1)) (not (mix? id2)) (not (mix? id3))) (snd-display #__line__ ";pan-mix 2->2: ~A ~A ~A ~A" id0 id1 id2 id3)) (if (not (= (mix-position id0) (mix-position id1) (mix-position id2) (mix-position id3) 100)) (snd-display #__line__ ";pan-mix 2->2 pos: ~A ~A ~A ~A" (mix-position id0) (mix-position id1) (mix-position id2) (mix-position id3))) (if (or (fneq (mix-amp id0) 1.0) (fneq (mix-amp id1) 1.0)) (snd-display #__line__ ";pan-mix 2->2 amps: ~A ~A" (mix-amp id0) (mix-amp id1))) (if (not (feql (mix-amp-env id0) '(0 1 1 0 2 1))) (snd-display #__line__ ";pan-mix 2->2 env 0: ~A" (mix-amp-env id0))) (if (not (feql (mix-amp-env id1) '(0 0 1 1 2 0))) (snd-display #__line__ ";pan-mix 2->2 env 1: ~A" (mix-amp-env id1))) (if (not (feql (mix-amp-env id2) '(0 1 1 0 2 1))) (snd-display #__line__ ";pan-mix 2->2 env 2: ~A" (mix-amp-env id2))) (if (not (feql (mix-amp-env id3) '(0 0 1 1 2 0))) (snd-display #__line__ ";pan-mix 2->2 env 3: ~A" (mix-amp-env id3))) (revert-sound ind)) (close-sound ind)) (let ((ind (new-sound "test.snd" 2 22050 mus-ldouble mus-next "pan-mix-* tests" 1000))) (let* ((ids (pan-mix-float-vector (make-float-vector 100 .3) 100 '(0 0 1 1))) (id0 (car ids)) (id1 (cadr ids))) (if (or (not (mix? id0)) (not (mix? id1))) (snd-display #__line__ ";pan-mix-float-vector 1->2: ~A ~A" id0 id1)) (if (not (= (mix-position id0) (mix-position id1) 100)) (snd-display #__line__ ";pan-mix-float-vector 1->2 pos: ~A ~A" (mix-position id0) (mix-position id1))) (if (or (fneq (mix-amp id0) 1.0) (fneq (mix-amp id1) 1.0)) (snd-display #__line__ ";pan-mix-float-vector 1->2 amps: ~A ~A" (mix-amp id0) (mix-amp id1))) (if (not (feql (mix-amp-env id0) '(0 1 1 0))) (snd-display #__line__ ";pan-mix-float-vector 1->2 env 0: ~A" (mix-amp-env id0))) (if (not (feql (mix-amp-env id1) '(0 0 1 1))) (snd-display #__line__ ";pan-mix-float-vector 1->2 env 1: ~A" (mix-amp-env id1))) (revert-sound ind)) (let* ((reg (make-region 0 50 ind 0)) (ids (pan-mix-region reg 100 '(0 0 1 1))) (id0 (car ids)) (id1 (cadr ids))) (if (or (not (mix? id0)) (not (mix? id1))) (snd-display #__line__ ";pan-mix-region 1->2: ~A ~A" id0 id1)) (if (not (= (mix-position id0) (mix-position id1) 100)) (snd-display #__line__ ";pan-mix-region 1->2 pos: ~A ~A" (mix-position id0) (mix-position id1))) (if (or (fneq (mix-amp id0) 1.0) (fneq (mix-amp id1) 1.0)) (snd-display #__line__ ";pan-mix-region 1->2 amps: ~A ~A" (mix-amp id0) (mix-amp id1))) (if (not (feql (mix-amp-env id0) '(0 1 1 0))) (snd-display #__line__ ";pan-mix-region 1->2 env 0: ~A" (mix-amp-env id0))) (if (not (feql (mix-amp-env id1) '(0 0 1 1))) (snd-display #__line__ ";pan-mix-region 1->2 env 1: ~A" (mix-amp-env id1))) (revert-sound ind)) (select-all) (let* ((ids (pan-mix-selection 100 '(0 0 1 1))) (id0 (car ids)) (id1 (cadr ids))) (if (or (not (mix? id0)) (not (mix? id1))) (snd-display #__line__ ";pan-mix-selection 1->2: ~A ~A" id0 id1)) (if (not (= (mix-position id0) (mix-position id1) 100)) (snd-display #__line__ ";pan-mix-selection 1->2 pos: ~A ~A" (mix-position id0) (mix-position id1))) (if (or (fneq (mix-amp id0) 1.0) (fneq (mix-amp id1) 1.0)) (snd-display #__line__ ";pan-mix-selection 1->2 amps: ~A ~A" (mix-amp id0) (mix-amp id1))) (if (not (feql (mix-amp-env id0) '(0 1 1 0))) (snd-display #__line__ ";pan-mix-selection 1->2 env 0: ~A" (mix-amp-env id0))) (if (not (feql (mix-amp-env id1) '(0 0 1 1))) (snd-display #__line__ ";pan-mix-selection 1->2 env 1: ~A" (mix-amp-env id1))) (revert-sound ind)) (close-sound ind)) ;; copy mix (let ((snd (new-sound "test.snd"))) (let ((v (make-float-vector 1000))) (do ((i 0 (+ i 1))) ((= i 1000)) (set! (v i) (* i .001))) (let ((mx (mix-float-vector v 0 snd 0))) (let ((mx-copy (copy mx))) (if (not (= (length mx) (length mx-copy))) (snd-display #__line__ ";copy mix lengths: ~A ~A" (length mx) (length mx-copy))) (if (not (= (mix-position mx) (mix-position mx-copy))) (snd-display #__line__ ";copy mix positions: ~A ~A" (mix-position mx) (mix-position mx-copy))) (set! (mix-position mx-copy) 2000) (let ((rd1 (make-sampler 0)) (rd2 (make-sampler 2000)) (happy #t)) (do ((i 0 (+ i 1))) ((or (not happy) (= i 1000))) (let ((x1 (rd1)) (x2 (rd2))) (if (or (fneq x1 x2) (fneq x1 (* i .001))) (begin (set! happy #f) (snd-display #__line__ ";copy mix at ~A: ~A ~A ~A" i x1 x2 (* i .001)))))))))) (close-sound snd)) (if all-args (begin (let ((ind (make-waltz))) ;; mix.scm stuff... (close-sound ind)) (let ((ind (make-bagatelle))) (close-sound ind)))) ))) ;;; ---------------- test 10: marks ---------------- (require snd-marks.scm) (if (provided? 'snd-motif) (define mark-sync-color (*motif* 'mark-sync-color))) (define (snd_test_10) (define maxval 0.0) (define (data-max beg end) (set! maxval 0.0) (apply for-each (lambda (snd chn) (set! maxval (max maxval (float-vector-peak (samples beg (- end beg) snd chn))))) (all-chans)) maxval) (define (data-max2 beg end snd) (set! maxval 0.0) (do ((i 0 (+ i 1))) ((= i (chans snd)) maxval) (set! maxval (max maxval (float-vector-peak (samples beg (- end beg) snd i)))))) (define (data-max1 beg dur snd chn) (float-vector-peak (samples beg dur snd chn))) ;; from marks.scm (commented out) (define (eval-header sndf) (and (string? (comment sndf)) (catch #t (lambda () (eval-string (comment sndf))) (lambda args #f)))) (define (marks->string sndf) (let ((str (format #f "(require snd-marks.scm)~%(let ((m #f))~%")) (chan 0)) (for-each (lambda (chan-marks) (for-each (lambda (m) (set! str (string-append str (format #f " (set! m (add-mark ~A #f ~D ~A ~D))~%" (mark-sample m) chan (and (string? (mark-name m)) (> (length (mark-name m)) 0) (format #f "~S" (mark-name m))) (mark-sync m)))) (if (pair? (mark-properties m)) (set! str (string-append str (format #f " (set! (mark-properties m) '~A)~%" (mark-properties m)))))) chan-marks) (set! chan (+ 1 chan))) (marks sndf)) (string-append str (format #f " m)~%")))) (do ((test-ctr 0 (+ 1 test-ctr))) ((= test-ctr tests)) (log-mem test-ctr) (let ((ind0 (view-sound "oboe.snd")) (ind1 (view-sound "pistol.snd")) (v0 (make-float-vector 100)) (vc (make-vector 10))) (fill! v0 .1) (set! (vc 0) (mix-float-vector v0 0 ind0)) (set! (vc 1) (mix-float-vector v0 1000 ind0)) (set! (vc 2) (mix-float-vector v0 2000 ind0)) (set! (vc 3) (mix-float-vector v0 3000 ind0)) (set! (vc 4) (mix-float-vector v0 4000 ind0)) (set! (vc 5) (mix-float-vector v0 0 ind1)) (set! (vc 6) (mix-float-vector v0 1000 ind1)) (set! (vc 7) (mix-float-vector v0 2000 ind1)) (set! (vc 8) (mix-float-vector v0 3000 ind1)) (set! (vc 9) (mix-float-vector v0 4000 ind1)) (close-sound ind0) (close-sound ind1) (set! ind0 (new-sound "fmv.snd" 1 22050 mus-bshort mus-aifc "this is a comment")) (let ((v0 (make-vector 10 1.0))) (insert-samples 0 10 v0 ind0) (time (env-sound '(0 0 1 1) 0 10 1.0 ind0)) (do ((i 0 (+ i 1))) ((= i 10)) (if (fneq (sample i) (* i .1111)) (snd-display #__line__ ";1 env-sound[~D]: ~A?" i (sample i)))) (undo) (env-sound (make-env '(0 0 1 1) :length 10) 0 10 1.0 ind0) (do ((i 0 (+ i 1))) ((= i 10)) (if (fneq (sample i) (* i .1111)) (snd-display #__line__ ";2 env-sound[~D]: ~A?" i (sample i)))) (undo) (env-sound '(0 0 .5 1 1 1) 0 10 0.0 ind0) (if (or (fneq (sample 3) 0.0) (fneq (sample 8) 1.0) ) (snd-display #__line__ ";env-sound stepped: ~A ~A?" (sample 3) (sample 8))) (undo) (env-sound '(0 0 1 1) 0 10 32.0 ind0) (if (or (fneq (sample 3) 0.070) (fneq (sample 8) 0.67) ) (snd-display #__line__ ";env-sound exp: ~A ~A?" (sample 3) (sample 8))) (undo) (env-sound (make-env '(0 0 1 1) :base 32.0 :length 10) 0 10 32.0 ind0) (if (or (fneq (sample 3) 0.070) (fneq (sample 8) 0.67) ) (snd-display #__line__ ";env-sound exp: ~A ~A?" (sample 3) (sample 8))) (undo) (env-sound '(0 2)) (do ((i 0 (+ i 1))) ((= i 10)) (if (fneq (sample i) 2.0) (snd-display #__line__ ";3 env-sound[~D]: ~A?" i (sample i)))) (undo) (env-sound '(0 2) 2 4 1.0 ind0) (if (or (fneq (sample 1) 1.0) (fneq (sample 2) 2.0) (fneq (sample 5) 2.0) (fneq (sample 8) 1.0)) (snd-display #__line__ ";3 env-sound exp: ~A ~A ~A ~A?" (sample 1) (sample 2) (sample 5) (sample 8))) (undo) (do ((i 1 (+ i 1))) ((= i 10)) (set! (sample i) 0.0)) (filter-sound '(0 1 1 0) 4) (if (or (fneq (sample 1) 0.3678) (fneq (sample 2) .3678) (fneq (sample 3) .132) (fneq (sample 4) 0.0)) (snd-display #__line__ ";filter-sound env: ~A?" (samples 0 8))) (undo) (filter-sound '(0 1 1 0) 1024) (undo) (filter-sound (make-fir-filter 6 (float-vector .1 .2 .3 .3 .2 .1))) (undo) (filter-sound (make-delay 120)) (undo) (filter-sound (make-formant 1200 .99)) (undo) (let ((vc0 (make-float-vector 4))) (set! (vc0 0) .125) (set! (vc0 1) .25) (set! (vc0 2) .25) (set! (vc0 3) .125) (filter-sound vc0 4) (if (or (fneq (sample 0) 0.125) (fneq (sample 1) .25) (fneq (sample 2) .25) (fneq (sample 5) 0.0)) (snd-display #__line__ ";filter-sound direct: ~A?" (samples 0 8))) (revert-sound))) (close-sound ind0) (set! ind0 (new-sound "fmv.snd" 2 22050 mus-bshort mus-aifc "this is a comment")) (let ((v0 (make-vector 10 1.0)) (ind1 (new-sound "fmv1.snd" 1 22050 mus-bshort mus-aifc "this is a comment"))) (set! (sync ind0) 123) (set! (sync ind1) 123) (insert-samples 0 10 v0 ind0 0) (insert-samples 0 10 v0 ind0 1) (insert-samples 0 10 v0 ind1 0) (env-sound '(0 0 1 1) 0 10 1.0 ind0) (do ((i 0 (+ i 1))) ((= i 10)) (if (fneq (sample i ind0 0) (* i .1111)) (snd-display #__line__ ";ind0:0 1 env-sound[~D]: ~A?" i (sample i ind0 0))) (if (fneq (sample i ind0 1) (* i .1111)) (snd-display #__line__ ";ind0:1 1 env-sound[~D]: ~A?" i (sample i ind0 1))) (if (fneq (sample i ind1 0) (* i .1111)) (snd-display #__line__ ";ind1:0 1 env-sound[~D]: ~A?" i (sample i ind1 0)))) (undo) (env-sound (make-env '(0 0 1 1) :length 10) 0 10 1.0 ind0) (do ((i 0 (+ i 1))) ((= i 10)) (if (fneq (sample i ind0 0) (* i .1111)) (snd-display #__line__ ";ind0:0 2 env-sound[~D]: ~A?" i (sample i ind0 0))) (if (fneq (sample i ind0 1) (* i .1111)) (snd-display #__line__ ";ind0:1 2 env-sound[~D]: ~A?" i (sample i ind0 1))) (if (fneq (sample i ind1 0) (* i .1111)) (snd-display #__line__ ";ind1:0 2 env-sound[~D]: ~A?" i (sample i ind1 0)))) (undo) (env-sound '(0 0 .5 1 1 1) 0 10 0.0 ind0) (if (or (fneq (sample 3 ind0 0) 0.0) (fneq (sample 8 ind0 0) 1.0) ) (snd-display #__line__ ";ind0:0 env-sound stepped: ~A ~A?" (sample 3 ind0 0) (sample 8 ind0 0))) (if (or (fneq (sample 3 ind0 1) 0.0) (fneq (sample 8 ind0 1) 1.0) ) (snd-display #__line__ ";ind0:1 env-sound stepped: ~A ~A?" (sample 3 ind0 1) (sample 8 ind0 1))) (if (or (fneq (sample 3 ind1 0) 0.0) (fneq (sample 8 ind1 0) 1.0) ) (snd-display #__line__ ";ind1:0 env-sound stepped: ~A ~A?" (sample 3 ind1 0) (sample 8 ind1 0))) (undo) (revert-sound ind0) (revert-sound ind1) (insert-samples 0 10 v0 ind0 0) (insert-samples 0 10 v0 ind0 1) (insert-samples 0 10 v0 ind1 0) (filter-sound (make-one-zero :a0 0.5 :a1 0.0) 0 ind0) (do ((i 0 (+ i 1))) ((= i 10)) (if (fneq (sample i ind0 0) 0.5) (snd-display #__line__ ";ind0:0 1 filter-sound[~D]: ~A?" i (sample i ind0 0))) (if (fneq (sample i ind0 1) 0.5) (snd-display #__line__ ";ind0:1 1 filter-sound[~D]: ~A?" i (sample i ind0 1))) (if (fneq (sample i ind1 0) 0.5) (snd-display #__line__ ";ind1:0 1 filter-sound[~D]: ~A?" i (sample i ind1 0)))) (close-sound ind1)) (close-sound ind0) (set! ind0 (new-sound "fmv.snd" 1 22050 mus-bshort mus-aifc "this is a comment")) (let ((v0 (make-float-vector 10)) (old5 (sample 5 ind0))) (fill! v0 0.1) (insert-samples 10 10 v0 ind0) (env-sound '(0 0 1 2) 10 10 1.0 ind0) (do ((i 0 (+ i 1))) ((= i 10)) (if (fneq (sample (+ i 10) ind0) (* i .0222)) (snd-display #__line__ ";env-sound [~D]: ~A?" (+ i 10) (sample (+ i 10) ind0)))) (if (fneq (sample 5 ind0) old5) (snd-display #__line__ ";env-sound 5: ~A ~A?" old5 (sample 5 ind0))) (undo) (env-sound '(0 0 1 2) 10 10 4.0 ind0) (set! v0 (channel->float-vector 10 10)) (if (or (fneq (v0 3) 0.039) (fneq (v0 8) .162)) (snd-display #__line__ ";env-sound 4: ~A" v0)) (undo) (env-sound '(0 0 1 2) 10 10 .05 ind0) (set! v0 (channel->float-vector 10 10)) (if (or (fneq (v0 3) 0.133) (fneq (v0 8) .196)) (snd-display #__line__ ";env-sound 05: ~A" v0))) (close-sound ind0) (set! ind0 (new-sound "fmv.snd" 2 22050 mus-bshort mus-aifc "this is a comment")) (set! ind1 (new-sound "fmv1.snd" 1 22050 mus-ldouble mus-next "this is a comment")) (let ((v0 (make-vector 10 1.0))) (insert-samples 0 10 v0 ind0 0) (fill! v0 0.1) (insert-samples 0 10 v0 ind0 1) (fill! v0 0.01) (insert-samples 0 10 v0 ind1 0) (let ((val (data-max1 0 9 ind0 0))) (if (fneq val 1.0) (snd-display #__line__ ";scan-chan[0,0]: ~A?" val))) (let ((val (data-max1 0 9 ind0 1))) (if (fneq val 0.1) (snd-display #__line__ ";scan-chan[0,1]: ~A?" val))) (let ((val (data-max1 0 9 ind1 0))) (if (fneq val 0.01) (snd-display #__line__ ";scan-chan[1,0]: ~A?" val))) (let ((val (data-max1 0 9 #f #f))) (if (fneq val 0.01) (snd-display #__line__ ";scan-chans: ~A?" val))) (let ((val (data-max 0 9))) (if (fneq val 1.0) (snd-display #__line__ ";scan-all-chans: ~A?" val))) (let ((val (data-max2 0 9 ind0))) (if (fneq val 1.0) (snd-display #__line__ ";scan-across-sound-chans: ~A?" val)))) (close-sound ind0) (close-sound ind1) (set! ind0 (new-sound "fmv.snd" 2 22050 mus-bshort mus-aifc "this is a comment")) (mix "oboe.snd") (let ((m1 (add-mark 100))) (delete-sample 10) (let ((m2 (add-mark 200))) (delete-sample 10) (let ((m3 (add-mark 300))) (undo) (save-sound) (if (not (= (length (marks ind0 0)) 2)) (snd-display #__line__ ";marks after save: ~A" (marks ind0 0))) (if (or (not (mark? m1)) (not (= (mark-sample m1) 99))) (snd-display #__line__ ";save-sound mark1: ~A" (mark-sample m1))) (if (or (not (mark? m2)) (not (= (mark-sample m2) 200))) (snd-display #__line__ ";save-sound mark2: ~A" (mark-sample m2))) (if (mark? m3) (snd-display #__line__ ";save-sound mark3: ~A" m3))))) (close-sound ind0) (let ((fd (open-sound "oboe.snd")) (m1 (add-mark 123)) (sync-val (+ 1 (mark-sync-max)))) (if (not (mark? m1)) (snd-display #__line__ ";mark?")) (if (not (= (mark-sample m1) 123)) (snd-display #__line__ ";add-mark: ~A? " (mark-sample m1))) (set! (mark-property :hiho m1) 123) (if (not (= (mark-property :hiho m1) 123)) (snd-display #__line__ ";mark-property: ~A" (mark-property :hiho m1))) (if (mark-property :not-there m1) (snd-display #__line__ ";mark-not-property: ~A" (mark-property :not-there m1))) (if (not (eq? (without-errors (mark-sample (integer->mark 12345678))) 'no-such-mark)) (snd-display #__line__ ";mark-sample err: ~A?" (without-errors (mark-sample 12345678)))) (if (not (eq? (without-errors (add-mark 123 123)) 'no-such-sound)) (snd-display #__line__ ";add-mark err: ~A?" (without-errors (add-mark 123 123)))) (let ((m2 (without-errors (add-mark 12345 fd 0)))) (if (eq? m2 'no-such-mark) (snd-display #__line__ ";add-mark failed?")) (if (not (= (mark-sample m2) 12345)) (snd-display #__line__ ";add-mark 0 0: ~A?" (mark-sample m2))) (if (not (= (mark-sync m2) 0)) (snd-display #__line__ ";init mark-sync: ~A?" (mark-sync m2))) (set! (mark-sync m2) sync-val) (if (not (= (mark-sync m2) sync-val)) (snd-display #__line__ ";set-mark-sync (~A): ~A?" sync-val (mark-sync m2))) (let* ((syncs (syncd-marks sync-val)) (chans (marks fd 0)) (samps (map mark-sample chans))) (if (not (equal? syncs (list m2))) (snd-display #__line__ ";syncd-marks: ~A?" syncs)) (if (not (equal? chans (list m1 m2))) (snd-display #__line__ ";marks: ~A?" chans)) (if (not (equal? samps (list (mark-sample m1) (mark-sample m2)))) (snd-display #__line__ ";map samps: ~A?" samps)) (delete-samples 200 100 fd 0) (set! chans (marks fd)) (set! samps (map mark-sample (car chans))) (if (not (equal? samps (list (mark-sample m1 0) (- (mark-sample m2 0) 100)))) (snd-display #__line__ ";map samps: ~A?" samps)) (let ((descr (describe-mark m2))) (if (not (list? descr)) (snd-display #__line__ ";describe-mark: ~A?" descr))) (set! (mark-sync m1) (mark-sync m2)) (move-syncd-marks sync-val 100) (set! chans (marks fd)) (set! samps (map mark-sample (car chans))) (if (not (equal? samps (list (+ (mark-sample m1 0) 100) (mark-sample m2 0)))) (snd-display #__line__ ";syncd move samps: ~A?" samps)) (set! (cursor) 500) (set! (mark-sync m1) #t) (if (not (= (mark-sync m1) 1)) (snd-display #__line__ ";mark-sync via bool: ~A" (mark-sync m1))) (delete-mark m1) (set! chans (marks fd 0)) (if (not (equal? chans (list m2))) (snd-display #__line__ ";delete-mark? ~A" chans)) (undo) (set! chans (marks fd 0)) (if (not (equal? chans (list m1 m2))) (snd-display #__line__ ";delete-mark then undo? ~A" chans)) (redo) (if (not (string=? (mark-name m2) "")) (snd-display #__line__ ";init mark-name: ~A?" (mark-name m2))) (set! (mark-name m2) "hiho!") (if (not (string=? (mark-name m2) "hiho!")) (snd-display #__line__ ";set-mark-name: ~A?" (mark-name m2))) (undo) (if (not (string=? (mark-name m2) "")) (snd-display #__line__ ";undo mark-name: ~A?" (mark-name m2))) (redo) (if (not (string=? (mark-name m2) "hiho!")) (snd-display #__line__ ";redo mark-name: ~A?" (mark-name m2))) (let ((m3 (find-mark "hiho!")) (m4 (find-mark (mark-sample m2))) (m5 (find-mark "not-a-mark")) (m6 (find-mark 123456787)) (m7 (mark-name->id "hiho!"))) (if (or (not (equal? m2 m3)) (not (equal? m4 m7)) (not (equal? m2 m4))) (snd-display #__line__ ";find-mark: ~A ~A ~A ~A?" m2 m3 m4 m7)) (if (or (not (equal? m5 m6)) m5) (snd-display #__line__ ";find-not-a-mark: ~A ~A?" m5 m6)) (set! (mark-sample m2) 2000) (set! m1 (add-mark 1000)) (set! m3 (add-mark 3000)) (set! m4 (add-mark 4000)) (insert-samples 2500 500 (make-float-vector 500) fd 0) (set! samps (map mark-sample (marks fd 0))) (if (not (equal? samps '(1000 2000 3500 4500))) (snd-display #__line__ ";insert ripple: ~A?" samps)) (set! (mark-sample m3) 300) (set! (cursor) 500) (let ((sd (open-sound "4.aiff"))) (set! m3 (add-mark 1000 sd 2)) (set! m4 (add-mark 1000 sd 3)) (if (not (equal? (mark-home m3) (list sd 2))) (snd-display #__line__ ";marks->sound 4: ~A?" (mark-home m3))) (close-sound sd)) (let ((file (save-marks fd))) (if (or (not file) (not (string=? file (string-append cwd "oboe.marks")))) (snd-display #__line__ ";save-marks -> ~A?" file))) (let ((file (save-marks fd "hiho.marks"))) (if (or (not file) (not (string=? file "hiho.marks"))) (snd-display #__line__ ";save-marks with arg -> ~A?" file)) (let ((val (system (format #f "diff hiho.marks ~A" (string-append cwd "oboe.marks"))))) (if (not (= val 0)) (snd-display #__line__ ";save marks differs")))) (close-sound fd) (let ((s1 (open-sound "oboe.snd")) (s2 (open-sound "oboe.snd"))) (add-mark 123 s1 0) (add-mark 321 s2 0) (set! *with-verbose-cursor* #t) (if (file-exists? "s61.scm") (delete-file "s61.scm")) (save-state "s61.scm") (set! *with-verbose-cursor* #f) (close-sound s1) (close-sound s2)) (load (string-append cwd "s61.scm")) (if (not *with-verbose-cursor*) (snd-display #__line__ ";save-state with-verbose-cursor?")) (let ((s1 (find-sound "oboe.snd" 0)) (s2 (find-sound "oboe.snd" 1))) (if (or (not (sound? s1)) (not (sound? s2))) (snd-display #__line__ ";can't re-open sounds? ~A ~A" s1 s2) (let ((m1 (marks s1)) (m2 (marks s2))) (if (or (not (= (length m1) 1)) (not (= (length m2) 1)) (not (= (length (car m1)) 1)) (not (= (length (car m2)) 1))) (snd-display #__line__ ";save-marks via save-state to: ~A ~A" m1 m2) (let ((samp1 (mark-sample (caar m1))) (samp2 (mark-sample (caar m2)))) (if (or (not (= samp1 123)) (not (= samp2 321))) (snd-display #__line__ ";save-marks via save-state positions: ~A ~A" samp1 samp2)))))) (if (sound? s1) (close-sound s1)) (if (sound? s2) (close-sound s2))) (let ((fd (open-sound "pistol.snd"))) (let ((file (save-marks))) (if file (snd-display #__line__ ";save-marks no marks -> ~A?" file))) (close-sound fd)) (let ((fd (open-sound "oboe.snd"))) (load (string-append cwd "oboe.marks")) (let ((mlst (marks fd 0))) (if (not (= (length mlst) 4)) (snd-display #__line__ ";restore oboe.marks: ~A, marks: ~A" (file->string "oboe.marks") (marks fd 0)))) (close-sound fd)) (let ((fd (open-sound "oboe.snd"))) (add-mark 1000) (add-mark 2500) (add-mark (- (framples) 4000)) (let ((ms (marks fd 0))) (src-sound -.5) (if (not (equal? (marks fd 0) (reverse (marks fd 0 0)))) (snd-display #__line__ ";src rev marks: ~A ~A ~A" ms (marks fd 0) (reverse (marks fd 0 0)))) (let ((ms1 (map mark-sample (marks fd 0)))) (if (not (equal? ms1 (list 7998 96654 99654))) ; off-by-1 somewhere... (snd-display #__line__ ";src rev mark locs: ~A" ms1)))) (close-sound fd)) (let ((fd (open-sound "4.aiff"))) (add-mark 1000 fd 0) (add-mark 2000 fd 1) (add-mark 3000 fd 2) (add-mark 4000 fd 3) (if (= (length (marks)) 0) (snd-display #__line__ ";marks (no args): ~A" (marks))) (save-marks fd) (close-sound fd) (set! fd (open-sound "4.aiff")) (load (string-append cwd "4.marks")) (delete-file "4.marks") (do ((i 0 (+ i 1))) ((= i 4)) (let ((mlst (marks fd i))) (if (not (= (length mlst) 1)) (snd-display #__line__ ";save-marks[~A]: ~A?" i mlst)) (if (not (= (mark-sample (car mlst)) (* (+ i 1) 1000))) (snd-display #__line__ ";save-marks[~A] at ~A?" i (mark-sample (car mlst)))))) (close-sound fd)) )))) (let ((fd (open-sound "oboe.snd")) (m1 (add-mark 1234))) (set! (mark-name m1) "1234") (set! (mark-sync m1) 1234) (let ((m2 (copy m1))) (if (not (mark? m2)) (snd-display #__line__ "; copy mark: ~A?" m2) (begin (if (not (= (mark-sample m1) (mark-sample m2) 1234)) (snd-display #__line__ ";copy mark sample: ~A ~A" (mark-sample m1) (mark-sample m2))) (if (not (= (mark-sync m1) (mark-sync m2) 1234)) (snd-display #__line__ ";copy mark sync: ~A ~A" (mark-sync m1) (mark-sync m2))) (if (not (string=? (mark-name m2) "1234")) (snd-display #__line__ ";copy mark name: ~A?" (mark-name m2)))))) (close-sound fd)) (let* ((ind (open-sound "pistol.snd")) (samp1 1834) (samp2 8345) (m1 (add-mark samp1 ind 0)) (m2 (add-mark samp2))) (set! (mark-sync m1) 123) (set! (mark-sync m2) 100) (if (not (= (mark-sync-max) 1234)) (snd-display #__line__ ";mark-sync-max: ~A" (mark-sync-max))) (src-sound -1) (if (not (= (mark-sample m1) 39788)) (snd-display #__line__ ";src -1 m1 -> ~A" (mark-sample m1))) (if (not (= (mark-sample m2) 33277)) (snd-display #__line__ ";src -1 m2 -> ~A" (mark-sample m2))) (undo) (src-sound .5) (if (not (= (mark-sample m1) (* 2 samp1))) (snd-display #__line__ ";src .5 m1 -> ~A" (mark-sample m1))) (if (not (= (mark-sample m2) (* 2 samp2))) (snd-display #__line__ ";src .5 m2 -> ~A" (mark-sample m2))) (undo) (delete-samples 1000 100) (if (not (= (mark-sample m1) (- samp1 100))) (snd-display #__line__ ";delete 100 m1 -> ~A" (mark-sample m1))) (insert-silence 1000 100) (if (not (= (mark-sample m1) samp1)) (snd-display #__line__ ";insert 100 m1 -> ~A" (mark-sample m1))) (revert-sound ind) (delete-samples 2000 100) (if (not (= (mark-sample m1) samp1)) (snd-display #__line__ ";delete(2) 100 m1 -> ~A" (mark-sample m1))) (if (not (= (mark-sample m2) (- samp2 100))) (snd-display #__line__ ";delete(2) 100 m2 -> ~A" (mark-sample m2))) (insert-silence 2000 100) (if (not (= (mark-sample m1) samp1)) (snd-display #__line__ ";insert(2) 100 m1 -> ~A" (mark-sample m1))) (if (not (= (mark-sample m2) samp2)) (snd-display #__line__ ";insert(2) 100 m2 -> ~A" (mark-sample m2))) (revert-sound ind) (delete-samples 10000 100) (if (not (= (mark-sample m1) samp1)) (snd-display #__line__ ";delete(3) 100 m1 -> ~A" (mark-sample m1))) (if (not (= (mark-sample m2) samp2)) (snd-display #__line__ ";delete(3) 100 m2 -> ~A" (mark-sample m2))) (insert-silence 10000 100) (if (not (= (mark-sample m1) samp1)) (snd-display #__line__ ";insert(3) 100 m1 -> ~A" (mark-sample m1))) (if (not (= (mark-sample m2) samp2)) (snd-display #__line__ ";insert(3) 100 m2 -> ~A" (mark-sample m2))) (src-sound '(0 .5 1 .5 2 1)) (if (not (= (mark-sample m1) (* 2 samp1))) (snd-display #__line__ ";src env .5 m1 -> ~A" (mark-sample m1))) (if (not (= (mark-sample m2) (* 2 samp2))) (snd-display #__line__ ";src env .5 m2 -> ~A" (mark-sample m2))) (undo) (reverse-sound) (if (not (= (mark-sample m1) 39788)) (snd-display #__line__ ";reverse-sound m1 -> ~A" (mark-sample m1))) (if (not (= (mark-sample m2) 33277)) (snd-display #__line__ ";reverse-sound m2 -> ~A" (mark-sample m2))) (undo) (src-sound '(0 -.5 1 -.5 2 -1)) (if (not (= (mark-sample m1) 68598)) (snd-display #__line__ ";src -env m1 -> ~A" (mark-sample m1))) (if (not (= (mark-sample m2) 61160)) (snd-display #__line__ ";src -env m2 -> ~A" (mark-sample m2))) (revert-sound ind) (src-channel (make-env '(0 .5 1 1) :length 8001) 2000 10000) (if (not (= (mark-sample m1) samp1)) (snd-display #__line__ ";src-channel(1) m1 -> ~A" (mark-sample m1))) (if (not (= (mark-sample m2) 11345)) (snd-display #__line__ ";src-channel(1) m2 -> ~A" (mark-sample m2))) (undo) (src-channel (make-env '(0 .5 1 1) :length 8001) 0 8000) (if (not (= (mark-sample m1) 3303)) (snd-display #__line__ ";src-channel(2) m1 -> ~A" (mark-sample m1))) (if (not (= (mark-sample m2) samp2)) (snd-display #__line__ ";src-channel(2) m2 -> ~A" (mark-sample m2))) (undo) (src-channel (make-env '(0 .5 1 1) :length 8001) 10000 8000) (if (not (= (mark-sample m1) samp1)) (snd-display #__line__ ";src-channel(3) m1 -> ~A" (mark-sample m1))) (if (not (= (mark-sample m2) samp2)) (snd-display #__line__ ";src-channel(3) m2 -> ~A" (mark-sample m2))) (close-sound ind) (set! ind (open-sound "2.snd")) (set! (sync ind) #t) (let ((m3 (add-mark 1000 ind 0)) (m4 (add-mark 8000 ind 1))) (swap-channels) (if (or (not (equal? (mark-home m3) (list ind 1))) (not (equal? (mark-home m4) (list ind 0)))) (snd-display #__line__ ";swapped mark homes: ~A ~A?" (mark-home m3) (mark-home m4))) (if (or (not (= (mark-sample m3) 1000)) (not (= (mark-sample m4) 8000))) (snd-display #__line__ ";swapped mark samples: ~A ~A?" (mark-sample m3) (mark-sample m4))) (close-sound ind)) (set! ind (open-sound "2.snd")) (set! (sync ind) #t) (let ((m3 (add-mark 1000 ind 0))) (delete-samples 1000 10 ind 1) (swap-channels) (if (not (equal? (mark-home m3) (list ind 1))) (snd-display #__line__ ";edited swapped mark home: ~A?" (mark-home m3))) (if (not (= (mark-sample m3) 1000)) (snd-display #__line__ ";edited swapped mark sample: ~A" (mark-sample m3))) (delete-marks)) (close-sound ind)) (let* ((ind (open-sound "oboe.snd")) (m1 (add-mark 123 ind 0)) (m2 (add-mark 234 ind 0)) (sel #f)) (define-selection-via-marks m1 m2) (set! sel (selection)) (if (or (not (selection?)) (not (selection? sel))) (snd-display #__line__ ";define-selection-via-marks failed?") (let ((mc (selection-members))) (if (not (equal? mc (list (list ind 0)))) (snd-display #__line__ ";selection-members after mark definition: ~A (should be '((~A 0)))" mc ind)) (if (not (= (selection-position) 123)) (snd-display #__line__ ";selection-position 123: ~A" (selection-position))) (if (not (= (selection-framples) 112)) (snd-display #__line__ ";selection-framples 112: ~A" (selection-framples))))) (set! m1 (add-mark 1000 ind 0)) (set! m2 (add-mark 2000 ind 0)) (define-selection-via-marks m1 m2) (if (not (selection?)) (snd-display #__line__ ";define-selection-via-marks repeat failed?") (let ((mc (selection-members))) (if (not (equal? mc (list (list ind 0)))) (snd-display #__line__ ";selection-members after second mark definition: ~A (should be '((~A 0)))" mc ind)) (if (not (= (selection-position) 1000)) (snd-display #__line__ ";selection-position 1000: ~A" (selection-position))) (if (not (= (selection-framples) 1001)) (snd-display #__line__ ";selection-framples 1001: ~A" (selection-framples))))) (set! (selection-member? #t) #f) (if (selection?) (snd-display #__line__ ";can't clear selection via selection-member?")) (if (selection) (snd-display #__line__ ";(inactive) selection returns: ~A" (selection))) (set! (selection-member? ind 0) #t) (set! (selection-position ind 0) 2000) (set! (selection-framples ind 0) 1234) (snap-marks) (set! m1 (find-mark 2000 ind 0)) (if (not (mark? m1)) (snd-display #__line__ ";snap-marks start: ~A" (map mark-sample (marks ind 0)))) (set! m2 (find-mark (+ 2000 1234))) (if (not (mark? m2)) (snd-display #__line__ ";snap-marks end: ~A" (map mark-sample (marks ind 0)))) (set! (selection-position ind 0) (+ (framples ind 0) 1123)) (if (not (= (selection-position ind 0) (- (framples ind) 1))) (snd-display #__line__ ";selection position past eof: ~A ~A" (selection-position ind 0) (- (framples ind) 1))) (revert-sound ind) (src-sound '(0 .5 1 1.75665)) ;; trying to hit previous dur on the nose "by accident..." ;; try to hit mark_size segfault (as-one-edit (lambda () (add-mark 10) (mix "oboe.snd") (do ((i 0 (+ i 1))) ((= i 20)) (scale-channel 1.2) (add-mark (* i 2))))) (scale-channel .5) (close-sound ind) ) (let ((ind (open-sound "oboe.snd")) (mtests 100)) (do ((i 0 (+ i 1))) ((= i mtests)) (let* ((current-marks (marks ind 0)) (current-samples (map mark-sample current-marks))) (if (pair? current-marks) (let ((id (current-marks (random (- (length current-marks) 1))))) (if (not (equal? id (find-mark (mark-sample id)))) (snd-display #__line__ ";~A: two marks at ~A? ~A" i (mark-sample id) (map mark-sample current-marks))) (if (find-mark "not-a-name") (snd-display #__line__ ";find-bogus-mark: ~A" (find-mark "not-a-name"))))) (case (random 15) ((0) (let ((beg (random (framples))) (dur (max 1 (random 100)))) (insert-silence beg dur) (for-each (lambda (id old-loc) (if (> old-loc beg) (if (not (mark? id)) (snd-display #__line__ ";insert clobbered mark: ~A" id) (if (not (= (mark-sample id) (+ old-loc dur))) (snd-display #__line__ ";insert, mark ~D ~D -> ~D (~D)" id old-loc (mark-sample id) dur))))) current-marks current-samples))) ((1) (if (> (car (edits ind 0)) 0) (undo))) ((2) (if (> (cadr (edits ind 0)) 0) (redo))) ((3) (if (> (maxamp ind 0) .1) (scale-channel .5) (scale-channel 2.0)) (if (not (equal? (marks ind 0) current-marks)) (snd-display #__line__ ";scaling changed marks: ~A ~A" (marks ind 0) current-marks)) (if (not (equal? (map mark-sample (marks ind 0)) current-samples)) (snd-display #__line__ ";scaling changed mark locations: ~A ~A" (map mark-sample (marks ind 0)) current-samples))) ((4) (set! (sample (random (- (framples) 1))) .5) (if (not (equal? (marks ind 0) current-marks)) (snd-display #__line__ ";set-sample changed marks: ~A ~A" (marks ind 0) current-marks)) (if (not (equal? (map mark-sample (marks ind 0)) current-samples)) (snd-display #__line__ ";set-sample changed mark locations: ~A ~A" (map mark-sample (marks ind 0)) current-samples))) ((5) (let* ((beg (random (framples))) (dur (max 1 (random 100))) (end (+ beg dur))) (delete-samples beg dur) (for-each (lambda (id old-loc) (if (and (> old-loc beg) (< old-loc end) (mark? id)) (snd-display #__line__ ";delete did not clobber mark: ~A ~A [~A ~A]" id old-loc beg end) (if (and (> old-loc end) (not (= (mark-sample id) (- old-loc dur)))) (snd-display #__line__ ";delete ripple mark ~D ~D -> ~D (~D)" id old-loc (mark-sample id) dur) (if (and (< old-loc beg) (not (= (mark-sample id) old-loc))) (snd-display #__line__ ";delete but mark before: ~A ~A ~A ~A" id old-loc (mark-sample id) beg))))) current-marks current-samples))) ((6) (revert-sound)) ((7) (if (and (pair? current-marks) (> (length current-marks) 1)) (let ((id (current-marks (random (- (length current-marks) 1))))) (delete-mark id) (if (mark? id) (snd-display #__line__ ";delete-mark failed? ~A" id)) (if (not (= (length (marks ind 0)) (- (length current-marks) 1))) (snd-display #__line__ ";delete-mark list trouble: ~A ~A ~A" id current-marks (marks ind 0)))))) ((8) (let ((rate (if (> (framples) 200000) 2.0 0.5))) (src-channel rate) (for-each (lambda (id old-loc) (if (not (mark? id)) (snd-display #__line__ ";src-channel clobbered mark: ~A" id) (if (> (abs (- (/ old-loc rate) (mark-sample id))) 2) (snd-display #__line__ ";src moved mark: ~A ~A ~A (~A -> ~A)" id old-loc (mark-sample id) rate (- (/ old-loc rate) (mark-sample id)))))) current-marks current-samples))) ((9) (reverse-channel) (for-each (lambda (id old-loc) (if (not (mark? id)) (snd-display #__line__ ";reverse-channel clobbered mark: ~A" id) (if (> (abs (- (framples) old-loc (mark-sample id))) 2) (snd-display #__line__ ";reverse moved mark: ~A ~A ~A (~A)" id old-loc (- (framples) old-loc) (mark-sample id))))) current-marks current-samples)) (else (add-mark (random (- (framples) 1))))))) (close-sound ind)) (if (and (provided? 'snd-motif) (provided? 'xm)) (mark-sync-color "blue")) (let ((ind (open-sound "oboe.snd"))) (let ((m0 (add-mark 4321))) (delete-sample 100) (let ((m1 (add-mark 1234))) (let ((val0 (describe-mark m0)) (val1 (describe-mark m1))) (if (or (not (equal? ((car val0) 0) m0)) (not (equal? ((car val0) 2) ind)) (not (= ((car val0) 5) 0)) (not (= (val0 1) 4321)) (not (= (val0 2) 4320))) (snd-display #__line__ ";describe-mark m0: ~A" val0)) (if (or (not (equal? ((car val1) 0) m1)) (not (equal? ((car val1) 2) ind)) (not (= ((car val1) 5) 0)) (val1 1) (not (= (val1 2) 1234))) (snd-display #__line__ ";describe-mark m1: ~A" val1)) (delete-mark m0) (delete-sample 5000) (set! val0 (describe-mark m0)) (set! val1 (describe-mark m1)) (if (or (not (equal? ((car val0) 0) m0)) (not (equal? ((car val0) 2) ind)) (not (= ((car val0) 5) 0)) (not (= (val0 1) 4321)) (val0 2) (val0 3)) (snd-display #__line__ ";describe-mark m0 [1]: ~A" val0)) (if (or (not (equal? ((car val1) 0) m1)) (not (equal? ((car val1) 2) ind)) (not (= ((car val1) 5) 0)) (val1 1) (not (= (val1 2) 1234)) (not (= (val1 3) 1234))) (snd-display #__line__ ";describe-mark m1 [1]: ~A" val1))))) (revert-sound ind) (hook-push draw-mark-hook (lambda (hook) #t)) (let ((m0 (add-mark 4321)) (m1 (add-mark 1234)) (dur (/ (framples ind) (srate ind)))) (pad-marks (list m0 m1) .01) (if (fneq (/ (framples ind) (srate ind)) (+ dur .02)) (snd-display #__line__ ";pad-marks: ~A ~A" dur (/ (framples ind) (srate ind)))) (if (and (not (= (mark-sample m0) 4763)) (not (= (mark-sample m0) 4761))) (snd-display #__line__ ";pad-marks m0 pos: ~A" (mark-sample m0))) (if (fneq (sample 1235) 0.0) (snd-display #__line__ ";pad-marks 1235: ~A" (sample 1235)))) (close-sound ind)) (set! (hook-functions draw-mark-hook) ()) (let ((ind (open-sound "oboe.snd"))) (if (find-mark 12345) (snd-display #__line__ ";find-mark when no marks: ~A" (find-mark 12345))) (add-mark 123 ind 0) (delete-sample 0) (let ((m1 (add-mark 23 ind 0))) (set! (mark-name m1) "23") (delete-sample 0) (let ((m00 (find-mark 123 ind 0 0)) (m01 (find-mark "23")) (m02 (find-mark 121))) (if (not m00) (snd-display #__line__ ";can't find 00th mark")) (if (not m01) (snd-display #__line__ ";can't find 01th mark")) (if (not m02) (snd-display #__line__ ";can't find 02th mark")) (delete-mark (find-mark "23")) (scale-by 2.0) (set! m1 (add-mark 1234)) (set! (mark-name m1) "23") (let ((m10 (find-mark "23")) (m11 (find-mark "23" ind 0 1)) (m12 (find-mark "23" ind 0 2))) (if (not m10) (snd-display #__line__ ";can't find 10th mark") (if (not (= (mark-sample m10) 1234)) (snd-display #__line__ ";mark 10th: ~A" (mark-sample m10)))) (if (not m11) (snd-display #__line__ ";can't find 11th mark") (if (not (= (mark-sample m11 1) 23)) (snd-display #__line__ ";mark 11th: ~A" (mark-sample m11 1)))) (if (mark? m12) (snd-display #__line__ ";found 12th mark: ~A ~A ~A" m12 (mark-sample m12 2) (mark-name m12)))) (set! (mark-name m1) #f))) (close-sound ind)) (if (string? sf-dir) (let ((ind (open-sound (string-append sf-dir "forest.aiff")))) (mark-loops) (let ((pos (map mark-sample (marks ind 0)))) (if (not (equal? pos (list 24981 144332))) (snd-display #__line__ ";forest marked loops: ~A ~A" (marks ind 0) pos))) (close-sound ind))) )) (let ((ind (open-sound "oboe.snd"))) (add-mark 123) (add-mark 234 ind 0 "hiho" 1) (add-mark 345 ind 0 #f 1) (add-mark 456 ind 0 "a mark" 2) (add-mark 567 ind 0 #f 1) (save-marks ind "oboe.marks") (close-sound ind) (set! ind (open-sound "oboe.snd")) (add-mark 1 ind 0 "new mark" 1) (load (string-append cwd "oboe.marks")) (let ((m (find-mark 123 ind 0))) (if (not (mark? m)) (snd-display #__line__ ";save marks missed 123?") (begin (if (not (= (length (mark-name m)) 0)) (snd-display #__line__ ";saved mark 123 name: ~A" (mark-name m))) (if (not (= (mark-sync m) 0)) (snd-display #__line__ ";saved mark 123 sync: ~A" (mark-sync m)))))) (let ((m1-sync 0)) (let ((m (find-mark 234 ind 0))) (if (not (mark? m)) (snd-display #__line__ ";save marks missed 234?") (begin (if (not (string=? (mark-name m) "hiho")) (snd-display #__line__ ";saved mark 234 name: ~A" (mark-name m))) (if (or (= (mark-sync m) 0) (= (mark-sync m) 1)) (snd-display #__line__ ";saved mark 234 sync: ~A" (mark-sync m))) (set! m1-sync (mark-sync m))))) (let ((m (find-mark 345 ind 0))) (if (not (mark? m)) (snd-display #__line__ ";save marks missed 345?") (begin (if (not (= (length (mark-name m)) 0)) (snd-display #__line__ ";saved mark 345 name: ~A" (mark-name m))) (if (not (= (mark-sync m) m1-sync)) (snd-display #__line__ ";saved mark 345 sync: ~A ~A" (mark-sync m) m1-sync))))) (let ((m (find-mark 567 ind 0))) (if (not (mark? m)) (snd-display #__line__ ";save marks missed 567?") (begin (if (not (= (length (mark-name m)) 0)) (snd-display #__line__ ";saved mark 567 name: ~A" (mark-name m))) (if (not (= (mark-sync m) m1-sync)) (snd-display #__line__ ";saved mark 567 sync: ~A ~A" (mark-sync m) m1-sync))))) (let ((m (find-mark 456 ind 0))) (if (not (mark? m)) (snd-display #__line__ ";save marks missed 456?") (begin (if (not (string=? (mark-name m) "a mark")) (snd-display #__line__ ";saved mark 456 name: ~A" (mark-name m))) (if (or (= (mark-sync m) m1-sync) (= (mark-sync m) 0) (= (mark-sync m) 1)) (snd-display #__line__ ";saved mark 456 sync: ~A ~A" (mark-sync m) m1-sync))))) ) (delete-file "oboe.marks") (let ((ind1 (open-sound "2a.snd"))) (add-mark 1 ind1 0) (add-mark 2 ind1 1) (add-mark 3 ind1 0 "hi3") (add-mark 6 ind1 1 "hi6") (add-mark 4 ind1 0 #f 4) (add-mark 8 ind1 1 #f 5) (add-mark 5 ind1 0 #f 9) (add-mark 10 ind1 1 #f 9) (add-mark 20 ind1 0 #f 12) (add-mark 40 ind1 1 #f 12) (add-mark 60 ind1 1 #f 12) (save-marks ind1 "test.marks") (close-sound ind) (close-sound ind1)) (set! ind (open-sound "2a.snd")) (load (string-append cwd "test.marks")) (let ((m1 (find-mark 1 ind 0)) (m2 (find-mark 2 ind 1))) (if (or (not (mark? m1)) (not (mark? m2))) (snd-display #__line__ ";save-marks 2a 1,2: ~A ~A" m1 m2) (if (or (not (= (mark-sync m1) 0)) (not (= (mark-sync m2) 0))) (snd-display #__line__ ";save-marks 2a 1,2 syncs: ~A ~A" (mark-sync m1) (mark-sync m2))))) (let ((m1 (find-mark 5 ind 0)) (m2 (find-mark 10 ind 1))) (if (or (not (mark? m1)) (not (mark? m2))) (snd-display #__line__ ";save-marks 2a 5,10: ~A ~A" m1 m2) (if (or (= (mark-sync m1) 0) (not (= (mark-sync m1) (mark-sync m2)))) (snd-display #__line__ ";save-marks 2a 5,10 syncs: ~A ~A" (mark-sync m1) (mark-sync m2))))) (let ((m1 (find-mark 4 ind 0)) (m2 (find-mark 8 ind 1)) (m3 (find-mark 5 ind 0))) (if (or (not (mark? m1)) (not (mark? m2))) (snd-display #__line__ ";save-marks 2a 4,8: ~A ~A" m1 m2) (if (or (= (mark-sync m1) 0) (= (mark-sync m2) 0) (= (mark-sync m1) (mark-sync m2)) (= (mark-sync m1) (mark-sync m3))) (snd-display #__line__ ";save-marks 2a 4,8 syncs: ~A ~A ~A" (mark-sync m1) (mark-sync m2) (mark-sync m3))))) (let ((m1 (find-mark 3 ind 0)) (m2 (find-mark 6 ind 1))) (if (or (not (mark? m1)) (not (mark? m2))) (snd-display #__line__ ";save-marks 2a 3,6: ~A ~A" m1 m2) (begin (if (or (not (= (mark-sync m1) 0)) (not (= (mark-sync m2) 0))) (snd-display #__line__ ";save-marks 2a 3,6 syncs: ~A ~A" (mark-sync m1) (mark-sync m2))) (if (not (string=? (mark-name m1) "hi3")) (snd-display #__line__ ";save-marks 2a 3 name: ~A" (mark-name m1))) (if (not (string=? (mark-name m2) "hi6")) (snd-display #__line__ ";save-marks 2a 6 name: ~A" (mark-name m2)))))) (let ((m1 (find-mark 4 ind 0)) (m2 (find-mark 5 ind 0)) (m3 (find-mark 20 ind 0)) (m4 (find-mark 40 ind 1)) (m5 (find-mark 60 ind 1))) (if (or (not (mark? m3)) (not (mark? m4)) (not (mark? m5))) (snd-display #__line__ ";save-marks 2a 20...: ~A ~A ~A" m3 m4 m5) (if (or (= (mark-sync m3) 0) (= (mark-sync m1) (mark-sync m3)) (= (mark-sync m2) (mark-sync m3)) (not (= (mark-sync m3) (mark-sync m4) (mark-sync m5)))) (snd-display #__line__ ";save-marks 2a 10... syncs: ~A ~A ~A" (mark-sync m3) (mark-sync m4) (mark-sync m5))))) (delete-file "test.marks") (close-sound ind)) (let ((ind (new-sound :size 1000))) (add-mark 123) (add-mark 234 ind 0 "hiho" 1) (add-mark 345 ind 0 #f 1) (add-mark 456 ind 0 "a mark" 2) (add-mark 567 ind 0 #f 1) (hook-push output-comment-hook (lambda (hook) (set! (hook 'result) (marks->string (selected-sound))))) (save-sound-as "tst.snd") (let ((new-file-name (file-name ind))) (close-sound ind) (if (file-exists? new-file-name) (delete-file new-file-name))) (set! ind (open-sound "tst.snd")) (set! (hook-functions output-comment-hook) ()) (eval-header ind) (let ((ms (marks ind 0))) (if (not (= (length ms) 5)) (snd-display #__line__ ";eval-header + marks->string: ~A" ms)) (let ((samps (map mark-sample ms))) (if (or (not (memv 123 samps)) (not (memv 567 samps))) (snd-display #__line__ ";eval marked header samps: ~A" samps))) (if (not (find-mark 234)) (snd-display #__line__ ";eval mark header no mark at 234?")) (if (mark? (find-mark 456)) (if (not (= (mark-sync (find-mark 456)) 2)) (snd-display #__line__ ";eval mark header sync: ~A" (mark-sync (find-mark 456)))) (snd-display #__line__ ";no mark at 456"))) (close-sound ind) (mus-sound-forget "tst.snd") (delete-file "tst.snd")) ;; mark-explode (let ((ind (new-sound :size 31)) (ctr -1)) (map-channel (lambda (y) (set! ctr (+ ctr 1)) (if (< ctr 10) .1 (if (< ctr 20) .4 .8)))) (add-mark 10) (add-mark 20) (add-mark 30) (mark-explode) (if (file-exists? "mark-0.snd") (let ((ind1 (open-sound "mark-0.snd"))) (if (not (= (framples ind1 0) 10)) (snd-display #__line__ ";mark-0 framples: ~A" (framples ind1 0))) (if (not (vequal (channel->float-vector) (make-float-vector 10 .1))) (snd-display #__line__ ";mark-0 vals: ~A" (channel->float-vector))) (close-sound ind1) (delete-file "mark-0.snd")) (snd-display #__line__ ";mark-explode did not write mark-0.snd?")) (if (file-exists? "mark-1.snd") (let ((ind1 (open-sound "mark-1.snd"))) (if (not (= (framples ind1 0) 10)) (snd-display #__line__ ";mark-1 framples: ~A" (framples ind1 0))) (if (not (vequal (channel->float-vector) (make-float-vector 10 .4))) (snd-display #__line__ ";mark-1 vals: ~A" (channel->float-vector))) (close-sound ind1) (delete-file "mark-1.snd")) (snd-display #__line__ ";mark-explode did not write mark-1.snd?")) (if (file-exists? "mark-2.snd") (let ((ind1 (open-sound "mark-2.snd"))) (if (not (= (framples ind1 0) 10)) (snd-display #__line__ ";mark-2 framples: ~A" (framples ind1 0))) (if (not (vequal (channel->float-vector) (make-float-vector 10 .8))) (snd-display #__line__ ";mark-2 vals: ~A" (channel->float-vector))) (close-sound ind1) (delete-file "mark-2.snd")) (snd-display #__line__ ";mark-explode did not write mark-2.snd?")) (if (file-exists? "mark-3.snd") (snd-display #__line__ ";mark-explode wrote too many files?")) (let ((name (file-name ind))) (close-sound ind) (if (file-exists? name) (delete-file name)))) ) ;;; ---------------- test 11: dialogs ---------------- (define-envelope env1 '(0 0 1 0)) (define-envelope env2 '(0 0 1 1)) (define-envelope ramp-up-env '(0 0 1 1)) (define-envelope env4 '(0 1 1 0)) (define (snd_test_11) (define (string-equal-ignoring-white-space s1 s2) (or (string=? s1 s2) (let ((len1 (length s1)) (len2 (length s2))) (let loop ((i1 0) (i2 0)) (or (and (= i1 len1) (= i2 len2)) (if (and (< i1 len1) (char-whitespace? (s1 i1))) (loop (+ i1 1) i2) (if (and (< i2 len2) (char-whitespace? (s2 i2))) (loop i1 (+ i2 1)) (and (< i1 len1) (< i2 len2) (char=? (s1 i1) (s2 i2)) (loop (+ i1 1) (+ i2 1)))))))))) (if with-gui (begin (without-errors (peaks)) (enved-dialog) (color-orientation-dialog) (transform-dialog) (if with-motif (view-files-dialog)) (view-regions-dialog) (if (not (provided? 'snd-gtk)) (print-dialog)) (without-errors (edit-header-dialog)) (open-file-dialog #f) (mix-file-dialog #f) (insert-file-dialog #f) (help-dialog "Test" "snd-test here") (save-envelopes "hiho.env") (load (string-append cwd "hiho.env")) (if (not (equal? env4 (list 0.0 1.0 1.0 0.0))) (snd-display #__line__ ";save-envelopes: ~A?" env4)) (delete-file "hiho.env") (help-dialog "test2" "this is the next test" (list "string 1{open-sound}" "{env-sound}string2" "string{close-sound}3") (list "extsnd.html#sndopen" "extsnd.html#sndenv" "extsnd.html#sndclose")) (dismiss-all-dialogs) (let ((ind (open-sound "oboe.snd"))) (edit-header-dialog ind) (dismiss-all-dialogs) (close-sound ind)) (if (not (string=? (snd-url 'open-sound) "extsnd.html#opensound")) (snd-display #__line__ ";snd-url 'open-sound: ~A" (snd-url 'open-sound))) (if (not (string=? (snd-url "open-sound") "extsnd.html#opensound")) (snd-display #__line__ ";snd-url \"open-sound\": ~A" (snd-url "open-sound"))) (if (not (list? (snd-urls))) (snd-display #__line__ ";snd-urls: ~A" (snd-urls))) (let ((str1 (snd-help open-sound)) (str2 (snd-help 'open-sound)) (str3 (snd-help "open-sound"))) (if (or (not (string? str1)) ; can happen if we're running -DTIMING (not (string? str2)) (not (string? str3)) (not (string-equal-ignoring-white-space str2 str3))) (snd-display #__line__ ";snd-help open-sound: ~A ~A ~A" str1 str2 str3))) ; (if (not (string? (snd-help 'open-soud))) ; (snd-display #__line__ ";snd-help open-soud (misspelled on purpose) failed")) (if (not (string-equal-ignoring-white-space (snd-help enved-base) "(enved-base): envelope editor exponential base value (1.0)")) (snd-display #__line__ ";snd-help enved-base: ~A?" (snd-help enved-base))) (if (not (string-equal-ignoring-white-space (snd-help 'enved-base) "(enved-base): envelope editor exponential base value (1.0)")) (snd-display #__line__ ";snd-help 'enved-base: ~A?" (snd-help 'enved-base))) (if (not (string-equal-ignoring-white-space (snd-help "enved-base") "(enved-base): envelope editor exponential base value (1.0)")) (snd-display #__line__ ";snd-help \"enved-base\": ~A?" (snd-help "enved-base"))) (let ((old-val hamming-window)) (let ((str1 (snd-help 'hamming-window)) (str2 (snd-help "hamming-window"))) (if (or (not (string? str1)) (not (string? str2)) (not (string-equal-ignoring-white-space str1 str2)) (not (string-equal-ignoring-white-space str1 "A raised cosine"))) (snd-display #__line__ ";snd-help hamming-window: ~A ~A" str1 str2))) (if (not (= hamming-window old-val)) (snd-display #__line__ ";snd-help clobbered out-of-module variable: ~A ~A" old-val hamming-window))) (let ((vals (snd-urls))) (do ((i 0 (+ i 1))) ((= i 25)) ; need to cycle the 8's (if (defined? (string->symbol (car (vals i)))) (snd-help (car (vals i)) #f)))) (set! *show-indices* #t) (let ((ind (open-sound "oboe.snd"))) (if (< (length (sound-widgets ind)) 4) (snd-display #__line__ ";sound-widgets: ~A?" (sound-widgets ind))) (status-report "hi there" ind) (status-report "") (close-sound ind)) (set! *show-indices* #f) (define-envelope test-ramp '(0 0 1 1)) (if (not (equal? test-ramp '(0 0 1 1))) (snd-display #__line__ ";define-envelope test-ramp: ~A" test-ramp)) (define-envelope test-ramp '(0 1 1 0)) (if (not (equal? test-ramp '(0 1 1 0))) (snd-display #__line__ ";re-define-envelope test-ramp: ~A" test-ramp)) (if with-motif (let ((dialog (view-files-dialog #f))) (let ((vfamp (view-files-amp dialog)) (vfs (view-files-speed dialog)) (vfsort (view-files-sort)) (vfsort1 (view-files-sort dialog)) (vfe (view-files-amp-env dialog)) (vffiles (view-files-files dialog)) (vfsel (view-files-selected-files dialog)) (selected-file #f)) (if (fneq vfamp 1.0) (snd-display #__line__ ";vf amp: ~A" vfamp)) (if (fneq vfs 1.0) (snd-display #__line__ ";vf spd: ~A" vfs)) (if (not (= vfsort 0)) (snd-display #__line__ ";vf sort: ~A" vfsort)) (if (not (= vfsort1 0)) (snd-display #__line__ ";vf sort(d): ~A" vfsort1)) (if (not (feql vfe (list 0.0 1.0 1.0 1.0))) (snd-display #__line__ ";vf amp env: ~A" vfe)) (if (not (list? vffiles)) (snd-display #__line__ ";vf files: ~A" vffiles)) (if (not (list? vfsel)) (snd-display #__line__ ";vf selected files: ~A" vfsel)) (if (not (= (view-files-speed-style dialog) *speed-control-style*)) (snd-display #__line__ ";vf speed-style def: ~A ~A" (view-files-speed-style dialog) *speed-control-style*)) (set! (view-files-amp dialog) 0.5) (if (fneq (view-files-amp dialog) 0.5) (snd-display #__line__ ";set vf amp: ~A" (view-files-amp dialog))) (set! (view-files-speed dialog) 0.5) (if (fneq (view-files-speed dialog) 0.5) (snd-display #__line__ ";set vf spd: ~A" (view-files-speed dialog))) (set! (view-files-speed-style dialog) speed-control-as-ratio) (if (not (= (view-files-speed-style dialog) speed-control-as-ratio)) (snd-display #__line__ ";vf speed-style set: ~A" (view-files-speed-style dialog))) (set! (view-files-sort dialog) 2) (if (not (= (view-files-sort) 0)) (snd-display #__line__ ";vf global sort after local set: ~A" (view-files-sort))) (if (not (= (view-files-sort dialog) 2)) (snd-display #__line__ ";vf local sort after local set: ~A" (view-files-sort dialog))) (set! (view-files-sort) 4) (if (not (= (view-files-sort) 4)) (snd-display #__line__ ";vf global sort after global set: ~A" (view-files-sort))) (if (not (= (view-files-sort dialog) 2)) (snd-display #__line__ ";vf local sort after global set: ~A" (view-files-sort dialog))) (set! (view-files-files dialog) (list "oboe.snd" "1a.snd" "pistol.snd" "storm.snd")) (let ((vf-files (view-files-files dialog))) (if (or (and (not (member "1a.snd" vf-files)) (not (member (string-append home-dir "/cl/1a.snd") vf-files)) (not (member (string-append home-dir "/snd-16/1a.snd") vf-files))) (and (not (member "pistol.snd" vf-files)) (not (member (string-append home-dir "/cl/pistol.snd") vf-files)) (not (member (string-append home-dir "/snd-16/pistol.snd") vf-files))) (not (= (length vf-files) 4))) (snd-display #__line__ ";vf files set: ~A (~A, ~A)" vf-files (string-append home-dir "/cl/1a.snd") (length vf-files)))) (set! (hook-functions view-files-select-hook) ()) (hook-push view-files-select-hook (lambda (hook) (if (not (string? (hook 'name))) (snd-display #__line__ ";vf select hook arg: ~A" (hook 'name))) (if (not (hook 'widget)) (snd-display #__line__ ";vf select hook dialog: ~A" (hook 'widget))) (set! selected-file (hook 'name)))) (set! (view-files-selected-files dialog) (list "1a.snd")) (if (or (not (string? selected-file)) (and (not (equal? selected-file "1a.snd")) (not (equal? selected-file (string-append home-dir "/cl/1a.snd"))) (not (equal? selected-file (string-append home-dir "/snd-16/1a.snd"))))) (snd-display #__line__ ";vf set selected select hook arg: ~A" selected-file)) (if (and (not (equal? (view-files-selected-files dialog) (list "1a.snd"))) (not (equal? (view-files-selected-files dialog) (list (string-append home-dir "/cl/1a.snd")))) (not (equal? (view-files-selected-files dialog) (list (string-append home-dir "/snd-16/1a.snd"))))) (snd-display #__line__ ";vf selected files set: ~A" (view-files-selected-files dialog))) (hide-widget dialog) ))) (dismiss-all-dialogs) ))) ;;; ---------------- test 12: extensions ---------------- (define (snd_test_12) (define (spectral-difference snd1 snd2) (let* ((size (max (framples snd1) (framples snd2))) (pow2 (ceiling (log size 2))) (fftlen (expt 2 pow2)) (fdr1 (channel->float-vector 0 fftlen snd1 0)) (fdr2 (channel->float-vector 0 fftlen snd2 0))) (let* ((spectr1 (snd-spectrum fdr1 blackman2-window fftlen #t)) (spectr2 (snd-spectrum fdr2 blackman2-window fftlen #t)) (diffs (float-vector-subtract! spectr1 spectr2)) (len (length diffs)) (incr (make-one-pole 1.0 -1.0))) (float-vector-abs! diffs) (do ((i 0 (+ i 1))) ((= i len) (one-pole incr 0.0)) (one-pole incr (float-vector-ref diffs i)))))) (define (test-spectral-difference snd1 snd2 maxok) (let ((s1 (open-sound snd1)) (s2 (open-sound snd2))) (if (or (not (sound? s1)) (not (sound? s2))) (snd-display #__line__ ";open-sound ~A or ~A failed?" snd1 snd2)) (let ((diff (spectral-difference s1 s2))) (close-sound s1) (close-sound s2) (if (> diff maxok) (snd-display #__line__ ";translate spectral difference ~A ~A: ~A > ~A?" snd1 snd2 diff maxok))))) (define (remove-if p l) (cond ((null? l) ()) ((p (car l)) (remove-if p (cdr l))) (else (cons (car l) (remove-if p (cdr l)))))) (if (null? (sound-file-extensions)) (set! (sound-file-extensions) original-sound-file-extensions)) (let* ((sf-dir-files (and (string? sf-dir) (let ((good-files ())) (for-each ; omit bad headers (test cases) (lambda (file) (catch 'mus-error (lambda () (if (and (< (mus-sound-chans (string-append sf-dir file)) 256) (> (mus-sound-chans (string-append sf-dir file)) 0) (>= (mus-sound-sample-type (string-append sf-dir file)) 0) (> (mus-sound-srate (string-append sf-dir file)) 0) (>= (mus-sound-framples (string-append sf-dir file)) 0)) (set! good-files (cons file good-files)))) (lambda args (car args)))) (sound-files-in-directory sf-dir)) good-files))) (sf-dir-len (if sf-dir-files (length sf-dir-files) 0))) (if (and with-gui (> sf-dir-len 0)) (let ((open-files ()) (open-ctr 0)) (add-sound-file-extension "wave") (let ((exts (sound-file-extensions))) (if (not (member "wave" exts)) (snd-display #__line__ ";sound-file-extensions: ~A" exts)) (set! (sound-file-extensions) (list)) (if (pair? (sound-file-extensions)) (snd-display #__line__ ";sound-file-extesions set to (): ~A" (sound-file-extensions))) (set! (sound-file-extensions) exts) (if (not (member "wave" exts)) (snd-display #__line__ ";sound-file-extensions reset: ~A" (sound-file-extensions)))) (do ((clmtest 0 (+ 1 clmtest))) ((= clmtest tests)) (log-mem clmtest) (do () ((= open-ctr 32)) (let ((len (length open-files))) (if (or (= len 0) (> (random 1.0) .5)) (let* ((choice (floor (random sf-dir-len))) (name (string-append sf-dir (sf-dir-files choice))) (ht (catch #t (lambda () (mus-sound-header-type name)) (lambda args 0))) (df (catch #t (lambda () (mus-sound-sample-type name)) (lambda args 0))) (fd (if (or (= ht mus-raw) (= ht mus-unknown-header) (= df mus-unknown-sample)) -1 (or (catch #t (lambda () (view-sound name)) (lambda args (snd-display #__line__ ";~A ~A ~A" name ht df) -1)) -1)))) (if (not (eqv? fd -1)) (begin (set! open-ctr (+ open-ctr 1)) (set! open-files (cons fd open-files))))) (if (and (> len 0) (> (random 1.0) 0.3)) (let* ((choice (floor (random (* 1.0 (length open-files))))) (fd (open-files choice))) (close-sound fd) (set! open-files (remove-if (lambda (a) (equal? a fd)) open-files))))))) (if open-files (for-each close-sound open-files)) (set! open-files ()) (if (not (= (length (sounds)) 0)) (snd-display #__line__ ";active-sounds: ~A ~A?" (sounds) (map short-file-name (sounds)))) (let ((fd (open-raw-sound :file (string-append sf-dir "addf8.nh") :channels 1 :srate 8012 :sample-type mus-mulaw))) (if (not (= (sample-type fd) mus-mulaw)) (snd-display #__line__ ";open-raw-sound: ~A?" (mus-sample-type-name (sample-type fd)))) (close-sound fd)) (set! (hook-functions bad-header-hook) ()) ; (time (test-spectral-difference "oboe.snd" (string-append sf-dir "oboe.g723_24") 20.0)) ; (test-spectral-difference "oboe.snd" (string-append sf-dir "oboe.g723_40") 3.0) ; (test-spectral-difference "oboe.snd" (string-append sf-dir "oboe.g721") 6.0) (test-spectral-difference (string-append sf-dir "o2.wave") (string-append sf-dir "o2_dvi.wave") 10.0) (test-spectral-difference (string-append sf-dir "wood.riff") (string-append sf-dir "wood.sds") 4.0) (test-spectral-difference (string-append sf-dir "nist-10.wav") (string-append sf-dir "nist-shortpack.wav") 1.0) (hook-push bad-header-hook (lambda (hook) (set! (hook 'result) #t))) ;; dangling readers (overall) (let ((ind (open-sound "oboe.snd"))) (let ((hi (make-sampler 0 ind 0))) (close-sound ind) (if (not (sampler? hi)) (snd-display #__line__ ";dangling reader? ~A" hi)) (let ((name (format #f "~A" hi))) (if (not (string? name)) (snd-display #__line__ ";dangling reader format: ~A" name))) (let ((val (hi)) (val1 (next-sample hi)) (val2 (previous-sample hi)) (val3 (read-sample hi))) (if (or (fneq val 0.0) (fneq val1 0.0) (fneq val2 0.0) (fneq val3 0.0)) (snd-display #__line__ ";dangling read: ~A ~A ~A ~A" val val1 val2 val3)) (if (sampler-home hi) (snd-display #__line__ ";dangling reader home: ~A" (sampler-home hi))) (if (not (= (sampler-position hi) 0)) (snd-display #__line__ ";dangling sampler-position: ~A" (sampler-position hi))) (if (not (sampler-at-end? hi)) (snd-display #__line__ ";dangling reader eof: ~A" (sampler-at-end? hi))) (free-sampler hi)))) ;; same (pruned edit) (let ((ind (open-sound "oboe.snd"))) (delete-samples 100 100) (let ((hi (make-sampler 0 ind 0))) (revert-sound) (delete-samples 100 100) (if (not (sampler? hi)) (snd-display #__line__ ";pruned dangling reader? ~A" hi)) (let ((name (format #f "~A" hi))) (if (not (string? name)) (snd-display #__line__ ";pruned dangling reader format: ~A" name))) (let ((val (hi)) (val1 (next-sample hi)) (val2 (previous-sample hi)) (val3 (read-sample hi))) (if (or (fneq val 0.0) (fneq val1 0.0) (fneq val2 0.0) (fneq val3 0.0)) (snd-display #__line__ ";pruned dangling read: ~A ~A ~A ~A" val val1 val2 val3)) (if (not (equal? (sampler-home hi) (list ind 0))) (snd-display #__line__ ";pruned dangling reader home: ~A" (sampler-home hi))) (if (not (sampler-at-end? hi)) (snd-display #__line__ ";pruned dangling reader eof: ~A" (sampler-at-end? hi))) (free-sampler hi))) (close-sound ind)) ;; region reader (let ((ind (open-sound "2.snd"))) (set! (sync ind) 1) (let ((reg (make-region 90 220 ind #t))) (if (not (= (region-framples reg) (+ 1 (- 220 90)))) (snd-display #__line__ ";make-region framples: ~A" (region-framples reg))) (if (not (= (region-chans reg) 2)) (snd-display #__line__ ";make-region chans: ~A" (region-chans reg))) (if (not (= (region-framples reg 0) (+ 1 (- 220 90)))) (snd-display #__line__ ";make-region framples[0]: ~A" (region-framples reg 0))) (if (not (= (region-framples reg 1) (+ 1 (- 220 90)))) (snd-display #__line__ ";make-region framples[1]: ~A" (region-framples reg 1))) (if (not (= (region-position reg 0) 90)) (snd-display #__line__ ";make-region position[0]: ~A" (region-position reg 0))) (if (not (= (region-position reg 1) 90)) (snd-display #__line__ ";make-region position[1]: ~A" (region-position reg 1))) (if (not (= (region-position reg) 90)) (snd-display #__line__ ";make-region position[]: ~A" (region-position reg))) ;; beg = 0, chan 2 not highlighted (let ((rd1 (make-region-sampler reg 0 0)) (rd2 (make-region-sampler reg 100 1))) (let ((rd11 (copy-sampler rd1)) (rd22 (copy-sampler rd2))) (if (or (not (region-sampler? rd11)) (not (region-sampler? rd22))) (snd-display #__line__ ";copy-sampler (region): ~A ~A" rd11 rd22)) (if (or (mix-sampler? rd11) (mix-sampler? rd22) (sampler? rd11) (sampler? rd22)) (snd-display #__line__ ";copy (region) sampler-p trouble: ~A ~A ~A ~A" (mix-sampler? rd11) (mix-sampler? rd22) (sampler? rd11) (sampler? rd22))) (if (or (not (equal? (sampler-home rd11) (list reg 0))) (not (equal? (sampler-home rd22) (list reg 1)))) (snd-display #__line__ ";copy region reader home: ~A ~A" (sampler-home rd11) (sampler-home rd22))) (if (or (sampler-at-end? rd11) (sampler-at-end? rd22)) (snd-display #__line__ ";copy region reader end?: ~A ~A" (sampler-at-end? rd11) (sampler-at-end? rd22))) (if (or (not (= (sampler-position rd11) (sampler-position rd1) 0)) (not (= (sampler-position rd22) (sampler-position rd2) 100))) (snd-display #__line__ ";copy region reader position: ~A ~A ~A ~A" (sampler-position rd11) (sampler-position rd1) (sampler-position rd22) (sampler-position rd2))) (free-sampler rd1) (free-sampler rd11)))) (close-sound ind)) (let* ((ind (open-sound "oboe.snd")) (reg (make-region 1000 2000 ind 0)) (rd (make-region-sampler reg 0))) (if (mix-sampler? rd) (snd-display #__line__ ";region sampler: mix ~A" rd)) (if (not (region-sampler? rd)) (snd-display #__line__ ";region sampler: region ~A" rd)) (if (sampler? rd) (snd-display #__line__ ";region sampler: normal ~A" rd)) ;(if (not (= (sampler-position rd) 0)) (snd-display #__line__ ";region sampler position: ~A" (sampler-position rd))) (if (not (equal? (sampler-home rd) (list reg 0))) (snd-display #__line__ ";region sampler home: ~A" (sampler-home rd))) (if (sampler-at-end? rd) (snd-display #__line__ ";region sampler at end?: ~A" (sampler-at-end? rd))) (let ((val (rd))) (if (fneq val .0328) (snd-display #__line__ ";region-sampler at start: ~A" val)) (if (not (string? (format #f "~A" rd))) (snd-display #__line__ ";region-sampler: ~A" (format #f "~A" rd))) (close-sound ind) (forget-region reg) (set! val (read-sample rd)) (if (fneq val 0.0) (snd-display #__line__ ";region-sampler at end: ~A" val)) (if (not (sampler-at-end? rd)) (snd-display #__line__ ";region-sampler after deletion?")) (free-sampler rd))) ;; mix reader (let () (mix-click-sets-amp) (let* ((ind (open-sound "oboe.snd")) (reg (make-region 1000 2000 ind 0)) (md (car (mix-region reg 0 ind 0 0))) (rd (make-mix-sampler md))) (set! (mix-property :hi md) "hi") (if (not (string=? (mix-property :hi md) "hi")) (snd-display #__line__ ";mix(9)-property: ~A" (mix-property :hi md))) (let ((val (rd))) (if (fneq val .0328) (snd-display #__line__ ";mix-sampler at start: ~A" val)) (if (not (string? (format #f "~A" rd))) (snd-display #__line__ ";mix-sampler: ~A" (format #f "~A" rd))) (close-sound ind) (let ((tag (catch #t (lambda () (mix-property :hi md)) (lambda args (car args))))) (if (not (eq? tag 'no-such-mix)) (snd-display #__line__ ";mix-property bad mix: ~A" tag))) (let ((str (format #f "~A" rd))) (if (not (string=? str "#")) (snd-display #__line__ ";mix-sampler released: ~A" str)) (free-sampler rd))))) (set! (hook-functions mix-click-hook) ()) (set! (hook-functions close-hook) ()) (let ((sfiles ()) (ffiles ())) (for-each-sound-file (lambda (file) (if (> (mus-sound-chans file) 16) (set! ffiles (cons file ffiles))))) (map-sound-files (lambda (file) (if (> (mus-sound-chans file) 16) (set! sfiles (cons file sfiles))))) (if (and (file-exists? "s24.snd") (or (not (equal? ffiles (list "s24.snd"))) (not (equal? sfiles (list "s24.snd"))))) (snd-display #__line__ ";map|for-each-sound-file(s): ~A ~A" ffiles sfiles))) ) ; (if sf-dir-files ; (for-each (lambda (n) (mus-sound-forget (string-append sf-dir n))) sf-dir-files)) )))) ;;; ---------------- test 13: menus, edit lists, hooks, etc ---------------- (if (and (provided? 'snd-motif) (provided? 'xm) (not (provided? 'snd-effects-utils.scm))) (load "effects-utils.scm")) (if (and (provided? 'snd-motif) (provided? 'xm) (not (provided? 'snd-new-effects.scm))) (load "new-effects.scm")) (if (and (provided? 'snd-gtk) (provided? 'xg) (not (provided? 'snd-gtk-effects.scm))) (load "gtk-effects.scm")) (if (provided? 'snd-ladspa) (define (analyze-ladspa library label) (let* ((descriptor (ladspa-descriptor library label)) (data ()) (names (.PortNames descriptor)) (hints (.PortRangeHints descriptor)) (descriptors (.PortDescriptors descriptor)) (name (.Name descriptor)) (maker (.Maker descriptor)) (copy (.Copyright descriptor))) (for-each (lambda (port ranges port-name) (if (and (not (= (logand port LADSPA_PORT_CONTROL) 0)) (not (= (logand port LADSPA_PORT_INPUT) 0))) (let ((ldata ()) (hint (car ranges)) (lo (cadr ranges)) (hi (caddr ranges))) (if (not (= (logand hint LADSPA_HINT_TOGGLED) 0)) (set! ldata (cons "toggle" ldata))) (if (not (= (logand hint LADSPA_HINT_LOGARITHMIC) 0)) (set! ldata (cons "logarithmic" ldata))) (if (not (= (logand hint LADSPA_HINT_INTEGER) 0)) (set! ldata (cons "integer" ldata))) (if (not (= (logand hint LADSPA_HINT_SAMPLE_RATE) 0)) (set! ldata (cons "sample_rate" ldata))) (if (not (= (logand hint LADSPA_HINT_BOUNDED_ABOVE) 0)) (set! ldata (cons "maximum" (cons hi ldata)))) (if (not (= (logand hint LADSPA_HINT_BOUNDED_BELOW) 0) ) (set! ldata (cons "minimum" (cons lo ldata)))) (set! ldata (cons port-name ldata)) (set! data (cons ldata data))))) descriptors hints names) (append (list name maker copy) data)))) (if (provided? 'snd-ladspa) (define* (ladspa-it library label :rest plugin-parameters) ;; (ladspa-it "delay" "delay_5s" .3 .5) (init-ladspa) (let* ((descriptor (ladspa-descriptor library label)) (handle (ladspa-instantiate descriptor (srate))) (block-size 256) (in-block (make-float-vector block-size)) (out-block (make-float-vector block-size)) (len (framples)) (ra (ladspa-run-adding descriptor handle block-size))) (if ra (snd-display #__line__ ";ladspa-run-adding: ~A" ra)) (ladspa-set-run-adding-gain descriptor handle block-size) (dynamic-wind (lambda () (let ((count 0)) (for-each (lambda (port) (if (not (= (logand port LADSPA_PORT_CONTROL) 0)) (let ((parameter (make-float-vector 1 (car plugin-parameters)))) (set! plugin-parameters (cdr plugin-parameters)) (ladspa-connect-port descriptor handle count parameter)) (if (not (= (logand port LADSPA_PORT_INPUT) 0)) (ladspa-connect-port descriptor handle count in-block) (ladspa-connect-port descriptor handle count out-block))) (set! count (+ 1 count))) (.PortDescriptors descriptor)))) (lambda () (ladspa-activate descriptor handle) (catch #t (lambda () (do ((i 0 (+ i block-size))) ((>= i len)) (set! in-block (channel->float-vector i block-size)) (ladspa-run descriptor handle block-size) ;; here do something with the data )) (lambda args (snd-display #__line__ ";ladspa-it: ~A" args)))) (lambda () (ladspa-deactivate descriptor handle) (ladspa-cleanup descriptor handle)))))) (define ladspa_inited #f) (define clm_buffer_added #f) (define (snd_test_13) (define (test-hooks) (define (arg0 hook) (set! (hook 'result) 32)) (define (arg1 hook) (let ((n (hook (car (hook 'args))))) (set! (hook 'result) (if (number? n) (+ n 32) n)))) (define (arg2 hook) (let ((n (hook (car (hook 'args)))) (m (hook (cadr (hook 'args))))) (set! (hook 'result) (if (and (number? n) (number? m)) (+ n m 32) n)))) (define (arg3 hook) (let ((a (hook (list-ref (hook 'args) 0))) (b (hook (list-ref (hook 'args) 1))) (c (hook (list-ref (hook 'args) 2)))) (set! (hook 'result) (if (and (number? a) (number? b) (number? c)) (+ a b c 32) a)))) (define (arg4 hook) (let ((a (hook (list-ref (hook 'args) 0))) (b (hook (list-ref (hook 'args) 1))) (c (hook (list-ref (hook 'args) 2))) (d (hook (list-ref (hook 'args) 3)))) (set! (hook 'result) (if (and (number? a) (number? b) (number? c) (number? d)) (+ a b c 32) a)))) (define (arg5 hook) (set! (hook 'result) (list 0 0 1 1))) (define (arg6 hook) (let ((a (hook (list-ref (hook 'args) 0))) (b (hook (list-ref (hook 'args) 1))) (c (hook (list-ref (hook 'args) 2))) (d (hook (list-ref (hook 'args) 3))) (e (hook (list-ref (hook 'args) 4))) (f (hook (list-ref (hook 'args) 5)))) (set! (hook 'result) (if (and (number? a) (number? b) (number? c) (number? d) (number? e)) (+ a b c d e f 32) a)))) (reset-all-hooks) (for-each (lambda (n) (if (pair? (hook-functions n)) (snd-display #__line__ ";~A not empty?" n))) (snd-hooks)) ) (define (test-menus) (if (provided? 'xm) (for-each-child (car (menu-widgets)) (lambda (w) (if (not ((*motif* 'XmIsRowColumn) w)) (let ((option-holder (cadr ((*motif* 'XtGetValues) w (list (*motif* 'XmNsubMenuId) 0))))) (for-each-child option-holder (lambda (menu) (if (and ((*motif* 'XmIsPushButton) menu) ((*motif* 'XtIsManaged) menu) ((*motif* 'XtIsSensitive) menu) (not (member ((*motif* 'XtName) menu) (list "Exit" "New" "Save C-x C-s" "Close C-x k" "Close all" "Save current settings" "Mixes" "clm" "fm-violin")))) ((*motif* 'XtCallCallbacks) menu (*motif* 'XmNactivateCallback) (snd-global-state)))))))))) (for-each close-sound (sounds)) (dismiss-all-dialogs)) (define (mdt-test id x time drg) #f) (reset-all-hooks) (let ((fd (view-sound "oboe.snd"))) (if with-gui (let ((mb #f)) (if (not clm_buffer_added) (set! mb (add-to-main-menu "clm"))) (let ((var (catch #t (lambda () (add-to-menu -1 "fm-violin" (lambda () #f))) (lambda args args)))) (if (not (eq? (car var) 'no-such-menu)) (snd-display #__line__ ";add-to-menu bad menu: ~A" var))) (set! (cursor fd) 2000) (set! *transform-graph-type* graph-once) (set! (transform-graph? fd) #t) (if (not clm_buffer_added) (begin (add-to-menu mb "not here" (lambda () (snd-display #__line__ ";oops"))) (remove-from-menu mb "not here") (add-to-menu 3 "Denoise" (lambda () (status-report "denoise"))))) (set! clm_buffer_added #t))) (set! (hook-functions help-hook) ()) (let ((hi (snd-help 'cursor-position))) (hook-push help-hook (lambda (hook) (let ((a (hook (list-ref (hook 'args) 0))) (b (hook (list-ref (hook 'args) 1)))) (if (not (string=? a "cursor-position")) (snd-display #__line__ ";help-hook subject: ~A" a)) (if (not (string=? b "(cursor-position :optional snd chn): current cursor position (x y in pixels) in snd's channel chn")) (snd-display #__line__ ";help-hook text: ~A" b)) (set! (hook 'result) (string-append "hiho:" b))))) (let ((ho (snd-help 'cursor-position))) (if (not (= (length ho) (+ 5 (length hi)))) (snd-display #__line__ ";help-hook ~A -> ~A" hi ho)) (set! (hook-functions help-hook) ()) (hook-push help-hook (lambda (hook) (set! (hook 'result) #f))) (set! ho (snd-help 'cursor-position)) (if (not (string=? hi ho)) (snd-display #__line__ ";help-hook #f: ~A ~A" hi ho)) (set! (hook-functions help-hook) ()))) (set! (transform-size fd 0) 256) (when with-motif (for-each (lambda (dpy-type fft-type) (set! (transform-graph-type fd 0) dpy-type) (set! (transform-type fd 0) fft-type) (update-transform-graph fd 0) (let ((vals (transform->float-vector fd 0))) (if (not vals) (snd-display #__line__ ";transform graph-type: ~A type: ~A -> data: ~A" dpy-type fft-type vals) (begin (if (fneq (transform-sample 0 0 fd 0) (vals 0)) (snd-display #__line__ ";transform-sample ~A ~A -> ~A ~A" dpy-type fft-type (vals 0) (transform-sample 0 0 fd 0))) (if (< (length vals) 256) (snd-display #__line__ ";transform-> float-vector size: ~A" (length vals))))))) (list graph-once graph-as-sonogram graph-as-spectrogram graph-once graph-as-sonogram graph-as-spectrogram) (list fourier-transform fourier-transform fourier-transform autocorrelation autocorrelation autocorrelation))) (when with-gui (let ((tag (catch #t (lambda () (transform-sample 5000 0 fd 0)) (lambda args (car args))))) (if (not (eq? tag 'no-such-sample)) (snd-display #__line__ ";access invalid (bin) transform sample: ~A" tag)))) (close-sound fd) (set! *transform-type* fourier-transform) (hook-push after-open-hook (lambda (hook) (set! (x-axis-style (hook 'snd) #t) x-axis-in-samples))) (set! fd (open-sound "2.snd")) (close-sound fd) (set! (hook-functions after-open-hook) ()) (hook-push after-open-hook (lambda (hook) (set! (x-axis-style (hook 'snd) #t) x-axis-as-percentage))) (hook-push initial-graph-hook (lambda (hook) (let ((snd (hook 'snd)) (chn (hook 'chn)) (dur (hook 'duration))) (if (mus-sound-maxamp-exists? (file-name snd)) (let* ((amp-vals (mus-sound-maxamp (file-name snd))) (max-val (amp-vals (+ (* chn 2) 1)))) (set! (hook 'result) (list 0.0 dur (- max-val) max-val))) (set! (hook 'result) (list 0.0 dur -1.0 1.0)))))) (set! (hook-functions after-open-hook) ()) (set! (hook-functions initial-graph-hook) ()) (hook-push initial-graph-hook (lambda (hook) (set! (hook 'result) (list 0.0 (hook 'duration) -1.0 1.0 "a label" -4.0 4.0)))) (set! fd (open-sound "2.snd")) (let ((ax (axis-info))) (if (and (pair? ax) (or (fneq (ax 2) 0.0) (fneq (ax 3) -1.0) (fneq (ax 4) (mus-sound-duration "2.snd")) (fneq (ax 5) 1.0) (fneq (ax 6) 0.0) (fneq (ax 7) -4.0) (fneq (ax 8) (mus-sound-duration "2.snd")) (fneq (ax 9) 4.0))) (snd-display #__line__ ";initial-graph-hook with ymin/max: ~A" ax)) (set! (hook-functions initial-graph-hook) ())) (set! (selection-position fd 1) 1000) (set! (selection-framples fd 1) 10) (set! (selection-member? fd 1) #t) (if (selection-member? fd 0) (snd-display #__line__ ";chan 0 is selection-member?")) (do ((i 0 (+ i 1))) ((= i 2)) (set! (selection-position fd i) 1000) (set! (selection-framples fd i) 10) (set! (selection-member? fd i) #t)) (scale-selection-to (float-vector .5 .25)) (if (or (fneq (maxamp fd 0) .5) (fneq (maxamp fd 1) .25)) (snd-display #__line__ ";scale-selection-to with vector: ~A" (maxamp fd #t))) (close-sound fd) (set! fd (open-sound "obtest.snd")) (let () (let ((added 0)) (set! (hook-functions close-hook) ()) (set! *with-background-processes* #t) (hook-push new-widget-hook (lambda (hook) (set! added (+ added 1)))) (if (provided? 'snd-motif) (without-errors (test-menus))) (dismiss-all-dialogs) (set! (hook-functions close-hook) ()) (for-each close-sound (sounds)) (if (sound? fd) (begin (snd-display #__line__ ";close all didn't? ~A ~A ~A ~A ~A" fd (sound? fd) (short-file-name fd) (hook-functions close-hook) (sounds)) (close-sound fd))) (set! fd (open-sound "obtest.snd")) (set! *with-background-processes* #f) (set! (hook-functions new-widget-hook) ())) (if (and (not ladspa_inited) (provided? 'snd-ladspa) (file-exists? "/home/bil/test/ladspa/ladspa_sdk/plugins")) (begin (set! ladspa_inited #t) (set! *ladspa-dir* "/home/bil/test/ladspa/ladspa_sdk/plugins") (init-ladspa) (let* ((ptr (ladspa-descriptor "delay" "delay_5s")) (label (.Label ptr)) (name (.Name ptr)) (copy (.Copyright ptr)) (maker (.Maker ptr)) (props (.Properties ptr)) (id (.UniqueID ptr)) (names (.PortNames ptr)) (hints (.PortRangeHints ptr)) (count (.PortCount ptr)) (descs (.PortDescriptors ptr))) (if (not (string=? label "delay_5s")) (snd-display #__line__ ";ladspa .Label: ~A" label)) (if (not (string=? name "Simple Delay Line")) (snd-display #__line__ ";ladspa .Name: ~A" name)) (if (not (string=? maker "Richard Furse (LADSPA example plugins)")) (snd-display #__line__ ";ladspa .Maker: ~A" maker)) (if (not (string=? copy "None")) (snd-display #__line__ ";ladspa .Copyright: ~A" copy)) (if (not (= id 1043)) (snd-display #__line__ ";ladspa .UniqueID: ~A" id)) (if (not (= count 4)) (snd-display #__line__ ";ladspa .PortCount: ~A" count)) (if (not (= props 4)) (snd-display #__line__ ";ladspa .Properties: ~A" prop)) (if (not (equal? names (list "Delay (Seconds)" "Dry/Wet Balance" "Input" "Output"))) (snd-display #__line__ ";ladspa .PortNames: ~A" names)) (if (not (equal? hints (list (list 579 0.0 5.0) (list 195 0.0 1.0) (list 0 0.0 0.0) (list 0 0.0 0.0)))) (snd-display #__line__ ";ladspa .PortRangeHints: ~A" hints)) (if (not (equal? descs (list 5 5 9 10))) (snd-display #__line__ ";ladspa .PortDescriptors: ~A" descs)) (if (not (= (logand (cadr (.PortDescriptors ptr)) LADSPA_PORT_INPUT) 1)) (snd-display #__line__ ";ladspa port hint: ~A" (logand (cadr (.PortDescriptors ptr)) LADSPA_PORT_INPUT)))) (apply-ladspa (make-sampler 0) (list "delay" "delay_5s" .3 .5) 1000 "delayed") (if (not (equal? (analyze-ladspa "delay" "delay_5s") (list "Simple Delay Line" "Richard Furse (LADSPA example plugins)" "None" (list "Dry/Wet Balance" "minimum" 0.0 "maximum" 1.0) (list "Delay (Seconds)" "minimum" 0.0 "maximum" 5.0)))) (snd-display #__line__ ";analyze-ladspa: ~A" (analyze-ladspa "delay" "delay_5s"))) (ladspa-it "delay" "delay_5s" .3 .5) (if (provided? 'xm) (let ((w ((menu-widgets) 5))) (if (and (list? w) (not (XmIsRowColumn w))) (let ((option-holder (cadr (XtGetValues w (list XmNsubMenuId 0))))) (for-each-child option-holder (lambda (menu) (if (and (XmIsPushButton menu) (XtIsSensitive menu) (string=? (XtName menu) "Plugins")) (XtCallCallbacks menu XmNactivateCallback (snd-global-state))))))))) (dismiss-all-dialogs) (let ((tag (catch #t (lambda () (apply-ladspa (make-sampler 0) (list "delay" "delay_4s" .3 .5) 1000 "delayed")) (lambda args args)))) (if (not (eq? (car tag) 'no-such-plugin)) (snd-display #__line__ ";apply-ladspa bad plugin: ~A" tag))) (let ((tag (catch #t (lambda () (apply-ladspa (list (make-sampler 0) (make-sampler 0)) (list "delay" "delay_5s" .3 .5) 1000 "delayed")) (lambda args args)))) (if (not (eq? (car tag) 'plugin-error)) (snd-display #__line__ ";apply-ladspa reader mismatch: ~A" tag))) (let ((vals (list-ladspa))) (if (not (pair? vals)) (snd-display #__line__ ";ladspa list: ~A" vals)) (let ((descr (analyse-ladspa "delay" "delay_5s"))) (if (or (not (pair? descr)) (not (string? (car descr))) (not (string=? (car descr) "Simple Delay Line"))) (snd-display #__line__ ";analyse-ladspa: ~A" descr)))) (let ((tag (catch #t (lambda () (analyse-ladspa "delay" "delay_no_delay")) (lambda args (car args))))) (if (not (eq? tag 'no-such-plugin)) (snd-display #__line__ ";analyse-ladspa tag: ~A" tag))) (let ((tag (catch #t (lambda () (apply-ladspa (list (make-sampler 0) (make-sampler 0)) (list #f) 1000 "delayed")) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";apply-ladspa tag: ~A" tag))) (set! *ladspa-dir* "/home/bil/test/ladspa/vocoder-0.3") (init-ladspa) (if (not (equal? (list-ladspa) (list (list "vocoder" "vocoder")))) (snd-display #__line__ ";list-ladspa vocoder: ~A" (list-ladspa))) (if (not (list? (analyze-ladspa "vocoder" "vocoder"))) (snd-display #__line__ ";analyze-ladspa vocoder: ~A" (analyze-ladspa "vocoder" "vocoder"))) (let ((hi (ladspa-descriptor "vocoder" "vocoder"))) (if (not (string=? (.Name hi) "Vocoder")) (snd-display #__line__ ";ladspa vocoder name: ~A" (.Name hi)))) (let ((snd (open-sound "1a.snd"))) (apply-ladspa (list (make-sampler 0) (make-sampler 0)) (list "vocoder" "vocoder" 12 .5 .5 .5 .5 .5 .5 .5 .5 .5 .5 .5 .5 .5 .5 .5 .5) (framples) "vocoder") (undo) (set! *ladspa-dir* "/home/bil/test/ladspa/lib/ladspa") (init-ladspa) (for-each (lambda (plug) (apply analyse-ladspa plug)) (list-ladspa)) (if (not (list? (analyse-ladspa "amp_1181" "amp"))) (snd-display #__line__ ";analyze-ladspa can't find amp_1181")) (apply-ladspa (make-sampler 0) (list "amp_1181" "amp" -6) (framples) "amp") (apply-ladspa (make-sampler 0) (list "amp_1181" "amp" 6) (framples) "amp") (close-sound snd)) (let ((snd (open-sound "2a.snd"))) (let ((tag (catch #t (lambda () (apply-ladspa (list (make-sampler 0 snd 0) (make-sampler 0 snd 1)) (list "amp_1181" "amp" 6 -6) (framples) "amp")) (lambda args (car args))))) (if (not (eq? tag 'plugin-error)) (snd-display #__line__ ";apply-ladspa bad inputs: ~A" tag))) (apply-ladspa (list (make-sampler 0 snd 0) (make-sampler 0 snd 0)) (list "ringmod_1188" "ringmod_2i1o" 1) (framples) "ringmod") (apply-ladspa #f (list "analogue_osc_1416" "analogueOsc" 2 440.0 0.1 0.0) (framples) "osc") (apply-ladspa #f (list "sin_cos_1881" "sinCos" 440.0 1.0) (framples) "sincos") (apply-ladspa (list (make-sampler 0 snd 0) (make-sampler 0 snd 1)) (list "dj_eq_1901" "dj_eq" -6 0 6) (framples) "djeq") (close-sound snd))) )) (revert-sound fd) (close-sound fd) (for-each close-sound (sounds)) (test-hooks) (hook-push bad-header-hook (lambda (hook) (set! (hook 'result) #t))) (when with-gui (let ((ind (open-sound "oboe.snd"))) (set! (cursor) 2000) (key (char->integer #\u) 4 ind) (key (char->integer #\1) 0 ind) (key (char->integer #\0) 0 ind) (key (char->integer #\0) 0 ind) (key (char->integer #\x) 4 ind) (key (char->integer #\z) 4 ind) (if (not (equal? (edit-fragment) (list "smooth-channel 2000 100" "set" 2000 100))) (snd-display #__line__ ";C-x C-z fragment: ~A" (edit-fragment))) (if (not (vequal (channel->float-vector 2010 10) (float-vector 0.064 0.063 0.063 0.062 0.062 0.061 0.060 0.059 0.059 0.058))) (snd-display #__line__ ";C-x C-z samps: ~A" (channel->float-vector 2010 10))) (set! (cursor) 0) (select-all) (key (char->integer #\x) 4 ind) (key (char->integer #\o) 0 ind) (key (char->integer #\-) 4 ind) (key (char->integer #\x) 4 ind) (key (char->integer #\o) 0 ind) (key (char->integer #\x) 4 ind) (key (char->integer #\o) 0 ind) (key (char->integer #\x) 4 ind) (key (char->integer #\p) 0 ind) (set! (selection-member? #t) #f) (revert-sound ind) (set! (search-procedure) (lambda (n4) (> n4 .1))) (key (char->integer #\a) 4 ind 0) (if (not (= (cursor ind 0) 0)) (snd-display #__line__ ";C-a cursor: ~D?" (cursor ind 0))) (key (char->integer #\s) 4 ind 0) (key (char->integer #\s) 4 ind 0) (if (not (= (cursor ind 0) 4423)) (snd-display #__line__ ";search-procedure C-s C-s cursor: ~D?" (cursor ind 0))) (let ((str (with-output-to-string (lambda () (display (procedure-source (search-procedure))))))) (if (not (string=? str "(lambda (n4) (> n4 0.1))")) (snd-display #__line__ ";search-procedure: ~A?" str))) (set! (search-procedure) (lambda (n) (> n .2))) (set! (cursor ind 0) 0) (key (char->integer #\s) 4 ind 0) (key (char->integer #\s) 4 ind 0) (if (not (= (cursor ind 0) 0)) (snd-display #__line__ ";search-procedure C-s C-s cursor failed: ~D?" (cursor ind 0))) (let ((str (with-output-to-string (lambda () (display (procedure-source (search-procedure))))))) (if (not (string=? str "(lambda (n) (> n 0.2))")) (snd-display #__line__ ";search-procedure (1): ~A?" str))) (set! (hook-functions (edit-hook ind 0)) ()) (hook-push (edit-hook ind 0) (lambda (hook) (set! (hook 'result) #f))) (let ((str (with-output-to-string (lambda () (display (map procedure-source (hook-functions (edit-hook ind 0)))))))) (if (not (string=? str "((lambda (hook) (set! (hook 'result) #f)))")) (snd-display #__line__ ";edit-hook: ~A?" str))) (set! (hook-functions (edit-hook ind 0)) ()) (set! (hook-functions (after-edit-hook ind 0)) ()) (hook-push (after-edit-hook ind 0) (lambda (hook) (set! (hook 'result) #f))) (let ((str (with-output-to-string (lambda () (display (map procedure-source (hook-functions (after-edit-hook ind 0)))))))) (if (not (string=? str "((lambda (hook) (set! (hook 'result) #f)))")) (snd-display #__line__ ";after-edit-hook: ~A?" str))) (set! (hook-functions (after-edit-hook ind 0)) ()) (set! (hook-functions (undo-hook ind 0)) ()) (hook-push (undo-hook ind 0) (lambda (hook) (set! (hook 'result) #f))) (let ((str (with-output-to-string (lambda () (display (map procedure-source (hook-functions (undo-hook ind 0)))))))) (if (not (string=? str "((lambda (hook) (set! (hook 'result) #f)))")) (snd-display #__line__ ";undo-hook: ~A?" str))) (set! (hook-functions (undo-hook ind 0)) ()) (let ((calls 0)) (hook-push (undo-hook ind 0) (lambda (hook) (set! calls (+ 1 calls)))) (delete-sample 0 ind 0) (undo 1) (redo 1) (revert-sound ind) (if (not (= calls 3)) (snd-display #__line__ ";undo-hook called ~A times" calls))) (set! (hook-functions (undo-hook ind 0)) ()) (set! (search-procedure) #f) (close-sound ind) )) (if (pair? (hook-functions open-raw-sound-hook)) (set! (hook-functions open-raw-sound-hook) ())) (hook-push open-raw-sound-hook (lambda (hook) (set! (hook 'result) (list 1 22050 mus-bshort)))) (let ((ind (open-sound "~/sf1/addf8.nh"))) (play ind :wait #t) (set! (hook-functions open-raw-sound-hook) ()) (if (or (not (= (chans ind) 1)) (not (= (srate ind) 22050)) (not (= (sample-type ind) mus-bshort)) (not (= (framples ind) 23808))) (snd-display #__line__ ";open-raw: ~A ~A ~A ~A" (chans ind) (srate ind) (sample-type ind) (framples ind))) (set! (search-procedure) (lambda (n) (> n .2))) (close-sound ind)) (let ((save-as-dialog #t) (save-as-name "hiho") (save-as-index #f)) (set! (hook-functions after-save-as-hook) ()) (hook-push after-save-as-hook (lambda (hook) (let ((ind (hook 'snd)) (name (hook 'name)) (dial (hook 'dialog))) (set! save-as-index ind) (set! save-as-name name) (set! save-as-dialog dial)))) (let ((ind (open-sound "oboe.snd"))) (save-sound-as "test.snd" ind :header-type mus-raw) (close-sound ind) (set! (hook-functions open-raw-sound-hook) ()) (set! (hook-functions after-save-as-hook) ()) (if save-as-dialog (snd-display #__line__ ";after-save-as-hook dialog: ~A" save-as-dialog)) (if (not (equal? ind save-as-index)) (snd-display #__line__ ";after-save-as-hook index: ~A ~A" ind save-as-index)) (if (and (not (string=? (string-append home-dir "/cl/test.snd") save-as-name)) (not (string=? (string-append home-dir "/snd-16/test.snd") save-as-name))) (snd-display #__line__ ";after-save-as-hook name: ~A (~A)" save-as-name (string-append home-dir "/cl/test.snd"))) (hook-push open-raw-sound-hook (lambda (hook) (let ((file (hook 'name)) (choice (hook 'state))) (if (not (string=? (substring file (- (length file) 8)) "test.snd")) (snd-display #__line__ ";open-raw-sound-hook file: ~A?" (substring file (- (length file) 8)))) (if choice (snd-display #__line__ ";open-raw-sound-hook choice: ~A?" choice)) (set! (hook 'result) (list 2 44100 mus-mulaw))))) (set! ind (open-sound "test.snd")) (if (or (not (= (header-type ind) mus-raw)) (not (= (sample-type ind) mus-mulaw)) (not (= (chans ind) 2)) (not (= (srate ind) 44100)) (not (= (framples ind) 50828))) (snd-display #__line__ ";open-raw-sound-hook 1: ~A ~A ~A ~A ~A" (header-type ind) (sample-type ind) (chans ind) (srate ind) (framples ind))) (close-sound ind) (hook-append open-raw-sound-hook (lambda (hook) (if (not (equal? (hook 'name) "/home/bil/cl/test.snd")) (snd-display #__line__ ";open-raw-sound-hook 2: ~A" (hook 'name))) (set! (hook 'result) (list 1 22050 mus-lint)))) (set! ind (open-sound "test.snd")) (if (or (not (= (header-type ind) mus-raw)) (not (= (sample-type ind) mus-lint)) (not (= (chans ind) 1)) (not (= (srate ind) 22050)) (not (= (framples ind) (/ 50828 2)))) (snd-display #__line__ ";open-raw-sound-hook 3: ~A ~A ~A ~A ~A" (header-type ind) (sample-type ind) (chans ind) (srate ind) (framples ind))) (close-sound ind) (set! (hook-functions open-raw-sound-hook) ()) (hook-push open-raw-sound-hook (lambda (hook) (set! (hook 'result) (list 2)))) (set! ind (open-sound "test.snd")) (if (or (not (= (header-type ind) mus-raw)) (not (= (sample-type ind) mus-lint)) (not (= (chans ind) 2)) (not (= (srate ind) 22050))) (snd-display #__line__ ";open-raw-sound-hook 4: ~A ~A ~A ~A" (header-type ind) (sample-type ind) (chans ind) (srate ind))) (close-sound ind) (set! (hook-functions open-raw-sound-hook) ()) (hook-push open-raw-sound-hook (lambda (hook) (set! (hook 'result) (list 1 22050 mus-bshort 120 320)))) (set! ind (open-sound "test.snd")) (if (or (not (= (header-type ind) mus-raw)) (not (= (sample-type ind) mus-bshort)) (not (= (chans ind) 1)) (not (= (srate ind) 22050)) (not (= (data-location ind) 120)) (not (= (data-size ind) 320)) (not (= (framples ind) 160))) (snd-display #__line__ ";open-raw-sound-hook 5: ~A ~A ~A ~A ~A ~A ~A" (header-type ind) (sample-type ind) (chans ind) (srate ind) (data-location ind) (data-size ind) (/ (framples ind) 2))) (close-sound ind) (set! (hook-functions open-raw-sound-hook) ()))) (set! (hook-functions during-open-hook) ()) (let ((ind #f) (op #f) (sl #f) (aop #f) (dop #f) (cl #f) (ig #f) (scl #f) (other #f)) (hook-push open-hook (lambda (hook) (let ((filename (hook 'name))) (if (not (string=? filename (mus-expand-filename "oboe.snd"))) (snd-display #__line__ ";open-hook: ~A?" filename)) (set! op #t) (set! (hook 'result) #f)))) (hook-push after-open-hook (lambda (hook) (set! aop (hook 'snd)))) (hook-push during-open-hook (lambda (hook) (let ((filename (hook 'name)) (reason (hook 'reason))) (set! dop #t) (if (not (string=? filename (mus-expand-filename "oboe.snd"))) (snd-display #__line__ ";during-open-hook filename: ~A?" filename)) (if (not (= reason 1)) (snd-display #__line__ ";during-open-hook reason: ~A?" reason))))) (hook-push initial-graph-hook (lambda (hook) (if (not (= (hook 'chn) 0)) (snd-display #__line__ ";initial-graph-hook (channel): ~A not 0?" (hook 'chn))) (set! ig #t) (set! (hook 'result) #f))) (set! ind (open-sound "oboe.snd")) (if (not op) (snd-display #__line__ ";open-hook not called?")) (if (not dop) (snd-display #__line__ ";during-open-hook not called?")) (when with-gui (if (not ig) (snd-display #__line__ ";initial-graph-hook not called?"))) (if (not (sound? aop)) (snd-display #__line__ ";after-open-hook not called?")) (if (not (equal? aop ind)) (snd-display #__line__ ";after-open-hook ~A but ind: ~A?" aop ind)) (select-all) (set! (hook-functions open-hook) ()) (set! (hook-functions during-open-hook) ()) (set! (hook-functions after-open-hook) ()) (set! (hook-functions initial-graph-hook) ()) (hook-push open-hook (lambda (hook) (set! (hook 'result) #t))) (let ((pistol (open-sound "pistol.snd"))) (if pistol (begin (snd-display #__line__ ";open-hook #t, but open-sound -> ~A" pistol) (if (sound? pistol) (close-sound pistol))))) (set! (hook-functions open-hook) ()) (let ((gr #f) (agr #f) (gbf #f) (abf #f)) (set! (hook-functions before-transform-hook) ()) (set! (hook-functions after-transform-hook) ()) (set! (hook-functions after-graph-hook) ()) (set! (hook-functions graph-hook) ()) (hook-push graph-hook (lambda (hook) (let ((snd (hook 'snd)) (chn (hook 'chn))) (if (not (equal? snd ind)) (snd-display #__line__ ";graph-hook: ~A not ~A?" snd ind)) (if (not (= chn 0)) (snd-display #__line__ ";graph-hook (channel): ~A not 0?" chn)) (set! gr #t) (set! (hook 'result) #f)))) (hook-push after-graph-hook (lambda (hook) (let ((snd (hook 'snd)) (chn (hook 'chn))) (if (not (equal? snd ind)) (snd-display #__line__ ";after-graph-hook: ~A not ~A?" snd ind)) (if (not (= chn 0)) (snd-display #__line__ ";after-graph-hook (channel): ~A not 0?" chn)) (set! agr #t)))) (hook-push before-transform-hook (lambda (hook) (set! gbf #t) (set! (hook 'result) (cursor)))) (hook-push after-transform-hook (lambda (hook) (let ((snd (hook 'snd)) (chn (hook 'chn))) (set! abf #t) (if (and (transform-graph? snd chn) (= (transform-graph-type snd chn) graph-once)) (status-report (number->string (/ (* 2.0 (float-vector-peak (transform->float-vector snd chn))) (transform-size snd chn))) snd) (set! (hook 'result) #f))))) (set! (transform-graph? ind 0) #t) (set! (time-graph? ind 0) #t) (update-time-graph ind 0) (update-transform-graph ind 0) (if (and (not gr) (provided? 'snd-motif) (provided? 'xm)) (with-let (sublet *motif*) (do ((i 0 (+ i 1)) (happy #f) (app (car (main-widgets)))) ((or happy (= i 1000))) (let ((msk (XtAppPending app))) (if (= (logand msk (logior XtIMXEvent XtIMAlternateInput)) 0) (set! happy #t) (XtDispatchEvent (XtAppNextEvent app))))))) (when with-gui (if (and (not gr) (not (provided? 'snd-gtk))) (snd-display #__line__ ";graph-hook not called? ~A ~A ~A ~A" (time-graph? ind) (short-file-name ind) ind (sounds))) (if (and (not agr) (not (provided? 'snd-gtk))) (snd-display #__line__ ";after-graph-hook not called?")) (if (not gbf) (snd-display #__line__ ";before-transform-hook not called?")) (if (and (not abf) (not (provided? 'snd-gtk))) (snd-display #__line__ ";after-transform-hook not called?"))) (set! (hook-functions before-transform-hook) ()) (set! (transform-graph? ind 0) #f) (set! (hook-functions graph-hook) ()) (set! (hook-functions after-graph-hook) ())) (set! other (open-sound "pistol.snd")) (hook-push select-sound-hook (lambda (hook) (if (not (equal? (hook 'snd) ind)) (snd-display #__line__ ";select-sound-hook: ~A not ~A?" (hook 'snd) ind)) (set! sl #t))) (hook-push select-channel-hook (lambda (hook) (let ((snd (hook 'snd)) (chn (hook 'chn))) (if (not (equal? snd ind)) (snd-display #__line__ ";select-channel-hook: ~A not ~A?" snd ind)) (if (not (= chn 0)) (snd-display #__line__ ";select-channel-hook (channel): ~A not 0?" chn)) (set! scl #t)))) (select-sound ind) (if (not sl) (snd-display #__line__ ";select-sound-hook not called?")) (if (not scl) (snd-display #__line__ ";select-channel-hook not called?")) (set! (hook-functions select-sound-hook) ()) (set! (hook-functions select-channel-hook) ()) (let ((spl #f) (stl #f) (ph #f)) (hook-push start-playing-hook (lambda (hook) (if (not (equal? (hook 'snd) ind)) (snd-display #__line__ ";start-playing-hook: ~A not ~A?" (hook 'snd) ind)) (set! spl #t) (set! (hook 'result) #f))) (hook-push stop-playing-hook (lambda (hook) (if (not (equal? (hook 'snd) ind)) (snd-display #__line__ ";stop-playing-hook: ~A not ~A?" (hook 'snd) ind)) (set! stl #t))) (hook-push play-hook (lambda (hook) (if (< (hook 'size) 128) (snd-display #__line__ ";play-hook samps: ~A?" (hook 'size))) (set! ph #t))) (set! (expand-control? ind) #t) (set! (reverb-control? ind) #t) (play ind :wait #t :end 1000) (set! (reverb-control? ind) #f) (set! (expand-control? ind) #f) (when with-gui (if (not spl) (snd-display #__line__ ";start-playing-hook not called?")) (if (not stl) (snd-display #__line__ ";stop-playing-hook not called?")) (if (not ph) (snd-display #__line__ ";play-hook not called?"))) (set! (hook-functions start-playing-hook) ()) (set! (hook-functions start-playing-selection-hook) ()) (set! (hook-functions stop-playing-hook) ()) (set! (hook-functions play-hook) ()) (hook-push play-hook (lambda (hook) (set! *expand-control-hop* .02) (set! *expand-control-length* .02) (set! *expand-control-ramp* .2) (set! *contrast-control-amp* 0.5) (set! *reverb-control-lowpass* .02) (set! *reverb-control-feedback* .02))) (play ind :wait #t :end 1000) (set! (hook-functions play-hook) ()) (hook-push start-playing-hook (lambda (hook) (set! (hook 'result) #t))) (play "4.aiff") (set! (hook-functions start-playing-hook) ()) (let ((ss #f) (old-reg *selection-creates-region*)) (set! *selection-creates-region* #t) (hook-push stop-playing-selection-hook (lambda (hook) (set! ss #t))) (let ((reg (select-all))) (play (selection) :wait #t) (if (region? reg) (play reg :wait #t)) (if (not ss) (snd-display #__line__ ";stop-playing-selection-hook: ~A" ss))) (set! (hook-functions stop-playing-selection-hook) ()) (set! *selection-creates-region* old-reg)) (let ((pl (make-player ind 0))) (free-player pl) (if (player? pl) (snd-display #__line__ ";free-player: ~A" pl))) ) (let ((e0 #f) (e1 #f) (u0 #f) (u1 #f) (a0 #f) (a1 #f)) (hook-push (edit-hook ind 0) (lambda (hook) (set! e0 #t) (set! (hook 'result) #t))) (hook-push (edit-hook other 0) (lambda (hook) (set! e1 #t) (set! (hook 'result) #f))) (hook-push (undo-hook ind 0) (lambda (hook) (set! u0 #t))) (hook-push (undo-hook other 0) (lambda (hook) (set! u1 #t))) (hook-push (after-edit-hook ind 0) (lambda (hook) (set! a0 #t))) (hook-push (after-edit-hook other 0) (lambda (hook) (set! a1 #t))) ;; edit of ind should be disallowed, but not other (delete-sample 0 ind 0) (if (not (= (edit-position ind 0) 0)) (snd-display #__line__ ";edit-hook #t didn't disallow edit!")) (if (not e0) (snd-display #__line__ ";edit-hook #t not called?")) (if a0 (snd-display #__line__ ";after-edit-hook 0 called?")) (undo 1 ind 0) (if u0 (snd-display #__line__ ";undo-hook called?")) (delete-sample 0 other 0) (if (not (= (edit-position other 0) 1)) (snd-display #__line__ ";edit-hook #f didn't allow edit!")) (if (not e1) (snd-display #__line__ ";edit-hook #f not called?")) (if (not a1) (snd-display #__line__ ";after-edit-hook 1 not called?")) (undo 1 other 0) (if (not u1) (snd-display #__line__ ";undo-hook not called?")) (set! (hook-functions (edit-hook ind 0)) ()) (set! (hook-functions (edit-hook other 0)) ()) (set! (hook-functions (after-edit-hook ind 0)) ()) (set! (hook-functions (after-edit-hook other 0)) ()) (set! (hook-functions (undo-hook ind 0)) ()) (set! (hook-functions (undo-hook other 0)) ())) (let ((se #f) (sw #f) (me #f)) (hook-push snd-error-hook (lambda (hook) (set! se #t) (set! (hook 'result) #t))) (hook-push snd-warning-hook (lambda (hook) (set! sw #t) (set! (hook 'result) #t))) (hook-push mus-error-hook (lambda (hook) (set! me #t) (set! (hook 'result) #t))) (snd-error "uhoh") (snd-warning "hiho") (mus-sound-samples "/bad/baddy") (if (not se) (snd-display #__line__ ";snd-error-hook not called?")) (if (not sw) (snd-display #__line__ ";snd-warning-hook not called?")) (if (not me) (snd-display #__line__ ";mus-error-hook not called?")) (set! (hook-functions snd-error-hook) ()) (set! (hook-functions snd-warning-hook) ()) (set! (hook-functions mus-error-hook) ()) (hook-push snd-error-hook (lambda (hook) (set! se (hook 'message)) (set! (hook 'result) #t))) (snd-error "not an error") (if (or (not (string? se)) (not (string=? se "not an error"))) (snd-display #__line__ ";snd-error-hook saw: ~A" se)) (set! (hook-functions snd-error-hook) ())) (hook-push before-exit-hook (lambda (hook) (set! (hook 'result) #t))) (hook-push exit-hook (lambda (hook) #f)) (exit) (set! (hook-functions exit-hook) ()) (set! (hook-functions before-exit-hook) ()) (let ((sh #f)) (if (file-exists? "baddy.snd") (delete-file "baddy.snd")) (hook-push save-hook (lambda (hook) (let ((snd (hook 'snd)) (filename (hook 'name))) (if (or (not (string? filename)) (not (string=? filename (mus-expand-filename "baddy.snd")))) (snd-display #__line__ ";save-hook filename: ~A?" filename)) (if (not (equal? snd ind)) (snd-display #__line__ ";save-hook snd: ~A ~A?" snd ind)) (set! sh #t) (set! (hook 'result) #t)))) (save-sound-as "baddy.snd" ind) (if (not sh) (snd-display #__line__ ";save-hook not called?")) (if (file-exists? "baddy.snd") (begin (snd-display #__line__ ";save-hook didn't cancel save?") (delete-file "baddy.snd"))) (set! (hook-functions save-hook) ())) ;; after-transform-hooks require some way to force the fft to run to completion ;; property-changed hook is similar (seems to happen whenever it's good and ready) (hook-push close-hook (lambda (hook) (if (not (equal? (hook 'snd) ind)) (snd-display #__line__ ";close-hook: ~A not ~A?" (hook 'snd) ind)) (set! cl #t))) (close-sound ind) (if (not cl) (snd-display #__line__ ";close-hook not called?")) (set! (hook-functions close-hook) ()) (close-sound other)) (if (not (provided? 'alsa)) (let ((in1 (open-sound "oboe.snd")) (in2 (open-sound "2.snd"))) (set! (sync in1) 1) (set! (sync in2) 1) (play :with-sync #t :wait #t) (close-sound in1) (close-sound in2))) (let* ((ind (open-sound "oboe.snd")) (edit-hook-ctr 0) (after-edit-hook-ctr 0) (all-tests (list (list 'apply-controls (lambda () (set! (amp-control ind 0) .5) (apply-controls ind) (set! (amp-control ind 0) 1.0))) (list 'clm-channel (lambda () (clm-channel (make-two-zero 1 -1)))) (list 'convolve-selection-with (lambda () (let ((reg (select-all ind 0))) (convolve-selection-with "1a.snd" .5) (if (region? reg) (forget-region reg))))) (list 'convolve-with (lambda () (convolve-with "1a.snd" 0.5 ind 0))) (list 'delete-mix (lambda () (let ((mx (mix-float-vector (make-float-vector 3 .2) 123))) (if (mix? mx) (set! (mix-amp mx) 0.0))))) (list 'delete-sample (lambda () (delete-sample 123 ind 0))) (list 'delete-samples (lambda () (delete-samples 123 123 ind 0))) (list 'delete-selection (lambda () (let ((reg (select-all ind 0))) (delete-selection) (if (region? reg) (forget-region reg))))) (list 'env-channel (lambda () (env-channel '(0 0 1 1)))) (list 'env-selection (lambda () (let ((reg (select-all ind 0))) (env-selection '(0 0 1 1) 1.0) (if (region? reg) (forget-region reg))))) (list 'env-sound (lambda () (env-sound '(0 0 1 1)))) (list 'filter-sound (lambda () (filter-sound '(0 1 1 0) 1024))) (list 'filter-selection (lambda () (let ((reg (select-all ind 0))) (filter-selection '(0 0 1 1) 6) (if (region? reg) (forget-region reg))))) (list 'insert-region (lambda () (let ((reg (make-region 0 100 ind 0))) (insert-region reg 123 ind 0) (if (region? reg) (forget-region reg))))) (list 'insert-sample (lambda () (insert-sample 123 .5 ind 0))) (list 'insert-samples (lambda () (insert-samples 123 3 (make-float-vector 3 1.0) ind 0))) (list 'insert-selection (lambda () (let ((reg (select-all ind 0))) (insert-selection 120 ind 0) (if (region? reg) (forget-region reg))))) (list 'insert-silence (lambda () (insert-silence 123 456 ind 0))) (list 'insert-sound (lambda () (insert-sound "1a.snd" 123))) (list 'map-channel (lambda () (map-channel (lambda (y) (+ y .2))))) (list 'map-channel (lambda () (map-channel (lambda (y) (+ y .2))))) (list 'mix (lambda () (mix "1a.snd" 123))) (list 'mix-amp (lambda () (let ((mx (mix-float-vector (make-float-vector 3 1.0) 123))) (if (mix? mx) (set! (mix-amp mx) .123))))) (list 'mix-amp-env (lambda () (let ((mx (mix-float-vector (make-float-vector 3 1.0) 123))) (if (mix? mx) (set! (mix-amp-env mx) '(0 0 1 1)))))) (list 'mix-position (lambda () (let ((mx (mix-float-vector (make-float-vector 3 1.0) 123))) (if (mix? mx) (set! (mix-position mx) 123))))) (list 'mix-speed (lambda () (let ((mx (mix-float-vector (make-float-vector 3 1.0) 123))) (if (mix? mx) (set! (mix-speed mx) .123))))) (list 'mix-region (lambda () (let ((reg (make-region 0 100 ind 0))) (mix-region reg 123 ind 0) (if (region? reg) (forget-region reg))))) (list 'mix-selection (lambda () (let ((reg (select-all ind 0))) (mix-selection 1234 ind 0) (if (region? reg) (forget-region reg))))) (list 'mix-float-vector (lambda () (mix-float-vector (make-float-vector 10 .3) 123))) (list 'pad-channel (lambda () (pad-channel 123 456 ind 0))) (list 'ramp-channel (lambda () (ramp-channel 0.0 0.5 123 456))) (list 'reverse-channel (lambda () (reverse-channel 123 456 ind 0))) (list 'reverse-sound (lambda () (reverse-sound ind 0))) (list 'reverse-selection (lambda () (let ((reg (select-all ind 0))) (reverse-selection) (if (region? reg) (forget-region reg))))) (list 'scale-by (lambda () (scale-by 2.0))) (list 'scale-channel (lambda () (scale-channel .5 123 456 ind 0))) (list 'scale-selection-by (lambda () (let ((reg (select-all ind 0))) (scale-selection-by 2.0) (if (region? reg) (forget-region reg))))) (list 'scale-selection-to (lambda () (let ((reg (select-all ind 0))) (scale-selection-to 0.5) (if (region? reg) (forget-region reg))))) (list 'scale-to (lambda () (scale-to 0.4))) (list 'scale-sound-to (lambda () (scale-sound-to 0.5))) (list 'smooth-channel (lambda () (smooth-channel 123 456 ind 0))) (list 'smooth-sound (lambda () (smooth-sound 123 456 ind 0))) (list 'smooth-selection (lambda () (let ((reg (select-all ind 0))) (smooth-selection) (if (region? reg) (forget-region reg))))) (list 'src-channel (lambda () (src-channel .5 123 456 ind 0))) (list 'src-sound (lambda () (src-sound '(0 0.5 1 1)))) (list 'src-selection (lambda () (let ((reg (select-all ind 0))) (src-selection 0.5) (if (region? reg) (forget-region reg))))) (list 'swap-channels (lambda () (let ((ind1 (open-sound "1a.snd"))) (swap-channels ind 0 ind1 0) (close-sound ind1)))) (list 'float-vector->channel (lambda () (float-vector->channel (make-float-vector 3) 123 3 ind 0))) (list 'xramp-channel (lambda () (xramp-channel .5 1.0 32.0 123 456 ind 0)))))) (if (and (provided? 'snd-motif) (provided? 'xm)) (let* ((edhist ((channel-widgets ind 0) 7)) (edp ((*motif* 'XtParent) edhist))) ((*motif* 'XtUnmanageChild) edp) ((*motif* 'XtVaSetValues) edp (list (*motif* 'XmNpaneMinimum) 100)) ((*motif* 'XtManageChild) edp))) (hook-push (edit-hook ind 0) (lambda (hook) (set! edit-hook-ctr (+ 1 edit-hook-ctr)) (set! (hook 'result) #t))) (hook-push (after-edit-hook ind 0) (lambda (hook) (set! after-edit-hook-ctr (+ 1 after-edit-hook-ctr)) (set! (hook 'result) #t))) (for-each (lambda (func-and-name) (let ((func (cadr func-and-name)) (name (car func-and-name))) (func) (if (not (= (edit-position ind 0) 0)) (snd-display #__line__ ";~A: blocked edit: ~A" name (edit-position ind 0))) (if (not (= edit-hook-ctr 1)) (snd-display #__line__ ";~A: edit hook calls: ~A" name edit-hook-ctr)) (if (not (= after-edit-hook-ctr 0)) (snd-display #__line__ ";~A: after edit hook calls: ~A" name after-edit-hook-ctr)) (set! edit-hook-ctr 0) (if (not (null? (mixes ind 0))) (snd-display #__line__ ";[27315] ~A: mixes: ~A" name (mixes ind 0))))) all-tests) (set! edit-hook-ctr 0) (set! after-edit-hook-ctr 0) (set! (hook-functions (edit-hook ind 0)) ()) (set! (hook-functions (after-edit-hook ind 0)) ()) (hook-push (edit-hook ind 0) (lambda (hook) (set! edit-hook-ctr (+ 1 edit-hook-ctr)) (set! (hook 'result) #f))) (hook-push (after-edit-hook ind 0) (lambda (hook) (set! after-edit-hook-ctr (+ 1 after-edit-hook-ctr)) (set! (hook 'result) #t))) (for-each (lambda (func-and-name) (let ((func (cadr func-and-name)) (name (car func-and-name))) (func) (if (<= (edit-position ind 0) 0) (snd-display #__line__ ";~A: unblocked edit: ~A" name (edit-position ind 0))) (if (<= edit-hook-ctr 0) (snd-display #__line__ ";~A: unblocked edit hook calls: ~A" name edit-hook-ctr)) (if (<= after-edit-hook-ctr 0) (snd-display #__line__ ";~A: unblocked after edit hook calls: ~A" name after-edit-hook-ctr)) (set! edit-hook-ctr 0) (set! after-edit-hook-ctr 0) (revert-sound ind))) all-tests) (if (and (provided? 'snd-motif) (provided? 'xm)) (let* ((edhist ((channel-widgets ind 0) 7)) (edp ((*motif* 'XtParent) edhist))) ((*motif* 'XtUnmanageChild) edp) ((*motif* 'XtVaSetValues) edp (list (*motif* 'XmNpaneMinimum) 1)) ; not 0 here -- Xt warnings ((*motif* 'XtManageChild) edp))) (close-sound ind)) (hook-push mouse-enter-text-hook (lambda (hook) (focus-widget (hook 'widget)))) (hook-push mouse-leave-text-hook (lambda (hook) (focus-widget (hook 'widget)))) (describe-hook mouse-enter-text-hook) (reset-all-hooks) (let ((ind (open-sound "oboe.snd"))) (scale-by 2.0) (hook-push (edit-hook ind 0) (lambda (hook) (set! (hook 'result) #t))) (mix-float-vector (make-float-vector 10 .1) 0) (if (not (= (edit-position ind 0) 1)) (snd-display #__line__ ";mix-float-vector: blocked edit: ~A" (edit-position ind 0))) (if (not (null? (mixes ind 0))) (snd-display #__line__ ";mix-float-vector edit-hook: mixes: ~A" (mixes ind 0))) (mix "pistol.snd" 1000) (if (not (= (edit-position ind 0) 1)) (snd-display #__line__ ";mix: blocked edit: ~A" (edit-position ind 0))) (if (not (null? (mixes ind 0))) (snd-display #__line__ ";mix edit-hook: mixes: ~A" (mixes ind 0))) (set! (hook-functions (edit-hook ind 0)) ()) (let ((mx (mix-float-vector (make-float-vector 10 .1) 1000))) (if (mix? mx) ; might be no-gui case (begin (if (not (= (edit-position ind 0) 2)) (snd-display #__line__ ";mix-float-vector: unblocked edit: ~A" (edit-position ind 0))) (if (not (equal? (mixes ind 0) (list mx))) (snd-display #__line__ ";mix-float-vector un edit-hook: mixes: ~A" (mixes ind 0))) (hook-push (edit-hook ind 0) (lambda (hook) (set! (hook 'result) #t))) (set! (mix-amp mx) 2.0) (if (not (= (edit-position ind 0) 2)) (snd-display #__line__ ";mix amp: blocked edit: ~A" (edit-position ind 0))) (if (fneq (mix-amp mx) 1.0) (snd-display #__line__ ";mix amp: blocked edit: ~A" (mix-amp mx))) (set! (mix-amp-env mx) '(0 0 1 1 2 0)) (if (not (= (edit-position ind 0) 2)) (snd-display #__line__ ";mix amp env: blocked edit: ~A" (edit-position ind 0))) (if (pair? (mix-amp-env mx)) (snd-display #__line__ ";mix amp env: blocked edit: ~A" (mix-amp-env mx))) (set! (mix-speed mx) 2.0) (if (not (= (edit-position ind 0) 2)) (snd-display #__line__ ";mix speed: blocked edit: ~A" (edit-position ind 0))) (if (fneq (mix-speed mx) 1.0) (snd-display #__line__ ";mix speed: blocked edit: ~A" (mix-speed mx))) (set! (mix-position mx) 2000) (if (not (= (edit-position ind 0) 2)) (snd-display #__line__ ";mix position: blocked edit: ~A" (edit-position ind 0))) (if (not (= (mix-position mx) 1000)) (snd-display #__line__ ";mix position: blocked edit: ~A" (mix-position mx))) (mix-float-vector (make-float-vector 10 .2) 0) (if (not (= (edit-position ind 0) 2)) (snd-display #__line__ ";mix-float-vector 1: blocked edit: ~A" (edit-position ind 0))) (if (not (equal? (mixes ind 0) (list mx))) (snd-display #__line__ ";mix-float-vector 1 edit-hook: mixes: ~A" (mixes ind 0))) ))) (close-sound ind)) (let ((ind (open-sound "oboe.snd"))) (if (pair? (hook-functions (edit-hook ind 0))) (snd-display #__line__ ";edit-hook not cleared at close?")) (if (pair? (hook-functions (after-edit-hook ind 0))) (snd-display #__line__ ";after-edit-hook not cleared at close?")) (close-sound ind)) (reset-all-hooks) ;; before|after-save-as-hook (let ((hook-called #f)) (hook-push before-save-as-hook ; from docs (lambda (hook) (let ((index (hook 'snd)) (filename (hook 'name)) (sr (hook 'sampling-rate)) (type (hook 'header-type)) (dformat (hook 'sample-type)) (comment (hook 'comment))) (if (not (= sr (srate index))) (let ((chns (chans index))) (do ((i 0 (+ i 1))) ((= i chns)) (src-channel (* 1.0 (/ (srate index) sr)) 0 #f index i)) (save-sound-as filename index :header-type type :sample-type dformat :srate sr :comment comment) ;; hook won't be invoked recursively (do ((i 0 (+ i 1))) ((= i chns)) (undo 1 index i)) (set! hook-called #t) (set! (hook 'result) #t)))))) (let ((ind (open-sound "2.snd"))) (save-sound-as "test.snd" :srate 44100) (if (not (= (edit-position ind 0) 0)) (snd-display #__line__ ";before-save-as-hook undo: ~A" (edit-position ind 0))) (if (not hook-called) (snd-display #__line__ ";before-save-as-hook not called?")) (close-sound ind) (set! ind (open-sound "test.snd")) (if (not (= (srate ind) 44100)) (snd-display #__line__ ";before-save-as-hook src: ~A" (srate ind))) (close-sound ind)) (set! (hook-functions before-save-as-hook) ())) (let ((need-save-as-undo #f)) (hook-push before-save-as-hook (lambda (hook) (let ((index (hook 'snd)) ;(filename (hook 'name)) ;(selection (hook 'selection)) (sr (hook 'sampling-rate)) ;(type (hook 'header-type)) ;(dformat (hook 'sample-type)) ;(comment (hook 'comment)) ) (set! need-save-as-undo #f) (if (not (= sr (srate index))) (begin (src-sound (* 1.0 (/ (srate index) sr)) 1.0 index) (set! need-save-as-undo #t)))))) (hook-push after-save-as-hook (lambda (hook) (if need-save-as-undo (undo)))) (let ((ind (open-sound "oboe.snd"))) (save-sound-as "test.snd" :srate 44100) (if (not (= (edit-position ind 0) 0)) (snd-display #__line__ ";after-save-as-hook undo: ~A" (edit-position ind 0))) (close-sound ind) (set! ind (open-sound "test.snd")) (if (not (= (srate ind) 44100)) (snd-display #__line__ ";before|after-save-as-hook src: ~A" (srate ind))) (close-sound ind)) (set! (hook-functions before-save-as-hook) ()) (set! (hook-functions after-save-as-hook) ())) (let ((old-clip *clipping*) (old-mus-clip (mus-clipping))) (set! *clipping* #t) (set! (mus-clipping) #t) (set! (hook-functions clip-hook) ()) (let ((index (new-sound "test.snd" 1 22050 mus-ldouble mus-next "clip-hook test" 10))) (map-channel (lambda (y) (mus-random 0.999))) ; -amp to amp (set! (sample 2) 1.0001) (set! (sample 4) -1.0) (set! (sample 6) 1.5) (set! (sample 8) -1.5) (let ((hook-called 0) (vals (channel->float-vector 0 10 index))) (hook-push clip-hook (lambda (hook) (let ((val (hook 'val))) (if (and (fneq val 1.0) (fneq val 1.5) (fneq val -1.5)) (snd-display #__line__ ";clip-hook called upon: ~A" val)) (set! hook-called (+ 1 hook-called)) (set! (hook 'result) 0.0)))) (save-sound index) (set! (hook-functions clip-hook) ()) (if (not (= hook-called 3)) (snd-display #__line__ ";clip-hook called ~A times" hook-called)) (close-sound index) (set! index (open-sound "test.snd")) (let ((new-vals (channel->float-vector 0 10 index)) (fixed-vals (copy vals))) (set! (fixed-vals 2) 0.0) (set! (fixed-vals 6) 0.0) (set! (fixed-vals 8) 0.0) (if (not (vequal fixed-vals new-vals)) (snd-display #__line__ ";clip-hook results:~% ~A~% ~A~% ~A" new-vals fixed-vals vals))) (close-sound index))) (set! *clipping* old-clip) (set! (mus-clipping) old-mus-clip)) )) ;;; ---------------- test 14: all together now ---------------- (define sfile 0) ; used globally by save-state stuff (... is this a bug?) (define safe-make-selection (let ((documentation "make-region with error checks")) (lambda (beg end snd) ; used in test_15 also (let ((len (framples snd)) (old-choice *selection-creates-region*)) (set! *selection-creates-region* #t) (if (> len 1) (if (< end len) (make-selection beg end snd) (if (< beg len) (make-selection beg (- len 1) snd) (make-selection 0 (- len 1) snd)))) (set! *selection-creates-region* old-choice))))) (define (flatten lst) (cond ((null? lst) ()) ((pair? lst) (if (pair? (car lst)) (append (flatten (car lst)) (flatten (cdr lst))) (cons (car lst) (flatten (cdr lst))))) (#t lst))) (define (snd_test_14) (define (test-panel func name) (if (and (not (feql (func #t) (map func (sounds)))) (not (feql (func #t) (map func (reverse (sounds)))))) (snd-display #__line__ ";test-panel ~A: ~A ~A?" name (func #t) (map func (sounds))))) (define (all-chans-reversed) (let ((sndlist ()) (chnlist ())) (for-each (lambda (snd) (do ((i (- (channels snd) 1) (- i 1))) ((< i 0)) (set! sndlist (cons snd sndlist)) (set! chnlist (cons i chnlist)))) (reverse (sounds))) (list sndlist chnlist))) (define (test-channel func name) (if (and (not (equal? (flatten (func #t #t)) (apply map func (all-chans)))) (not (equal? (flatten (func #t #t)) (apply map func (all-chans-reversed))))) (snd-display #__line__ ";test-channel ~A: ~A ~A?" name (flatten (func #t #t)) (apply map func (all-chans))))) (define duration (lambda (ind) (/ (framples ind) (srate ind)))) (define outputs (make-vector 24)) (define delay-line #f) (define delay-time 0.5) (define rev-funcs-set #f) (let* ((cur-dir-files (remove-if (lambda (file) (<= (catch #t (lambda () (let ((len (mus-sound-framples file)) (chns (mus-sound-chans file))) (if (or (> len 80000) (> chns 2)) -1 len))) (lambda args 0)) 0)) (sound-files-in-directory "."))) (cur-dir-len (length cur-dir-files)) (stereo-files ()) (quad-files ()) (mono-files ()) (octo-files ()) (open-files ()) (s8-snd (if (file-exists? "s8.snd") "s8.snd" "oboe.snd")) (open-ctr 0)) (define* (clone-sound-as new-name snd) ;; copies any edit-sounds to save-dir! (let* ((tmpf (snd-tempnam)) (scm (string-append (substring tmpf 0 (- (length tmpf) 3)) "scm")) (oldsnd (or snd (selected-sound)))) (if (not (string? *save-dir*)) (set! *save-dir* "/tmp")) (save-edit-history scm oldsnd) (copy-file (file-name oldsnd) new-name) (set! sfile (open-sound new-name)) (load scm) (delete-file scm) sfile)) (hook-push after-open-hook (lambda (hook) (set! (hook 'result) (make-player (hook 'snd) 0)))) (do ((i 0 (+ i 1))) ((= i cur-dir-len)) (let* ((name (cur-dir-files i)) (ht (mus-sound-header-type name)) (df (mus-sound-sample-type name)) (len (mus-sound-framples name)) (chans (mus-sound-chans name))) (if (and (not (= ht mus-raw)) (not (= len 0)) (not (= df -1))) (if (= chans 1) (set! mono-files (cons name mono-files)) (if (= chans 2) (set! stereo-files (cons name stereo-files)) (if (= chans 4) (set! quad-files (cons name quad-files)) (if (= chans 8) (set! octo-files (cons name octo-files))))))))) (do ((test-ctr 0 (+ 1 test-ctr))) ((= test-ctr tests)) (if (> (length open-files) 8) (begin (for-each close-sound open-files) (set! open-files ())) (if (> test-ctr 0) (for-each (lambda (snd) (let ((mxpos (edit-position snd 0)) (chns (chans snd))) (if (> chns 1) (do ((chn 1 (+ chn 1))) ((= chn chns)) (set! mxpos (+ mxpos (edit-position snd chn))))) (if (or (> mxpos 100) (> chns 4)) (begin (snd-display #__line__ ";revert ~A at ~A" (file-name snd) mxpos) (revert-sound snd))))) (sounds)))) (log-mem test-ctr) (if (> 10 test-ctr 0) ; this creates too many leftover save-state sound files (let ((files (length (sounds)))) (if (file-exists? "s61.scm") (delete-file "s61.scm")) (for-each (lambda (s) (if (> (chans s) 4) (begin (set! open-files (remove-if (lambda (a) (= a s)) open-files)) (close-sound s)))) (sounds)) (save-state "s61.scm") (for-each close-sound (sounds)) (for-each forget-region (regions)) (catch #t (lambda () (load (string-append cwd "s61.scm"))) (lambda args args)) (if (not (= (length (sounds)) files)) (snd-display #__line__ ";save state restart from ~A to ~A sounds?" files (length (sounds)))) (set! open-files (sounds)))) (let () (let* ((choice (random cur-dir-len)) (name (cur-dir-files choice)) (ht (mus-sound-header-type name)) (df (mus-sound-sample-type name)) (fd (if (or (= ht mus-raw) (= df -1)) -1 (view-sound name)))) (if (and (number? fd) (not (= fd -1))) (set! open-files (cons fd open-files)))) (set! open-ctr (length open-files)) (if (= open-ctr 0) (let ((fd (view-sound "1a.snd"))) (set! open-ctr 1) (set! open-files (cons fd open-files)))) (let ((choose-fd (lambda () (if (zero? test-ctr) ; I think randomness here is messing up my timing comparisons (or (find-sound "1a.snd") (open-sound "1a.snd")) ((sounds) (random (length (sounds)))))))) (let* (;(frame-list (map framples open-files)) (curfd (choose-fd)) (curloc (max 0 (min 1200 (framples curfd 0)))) (old-marks (length (marks curfd 0)))) ;(format *stderr* "~S (~A)~%" (file-name curfd) (duration curfd)) (if (> (duration curfd) 0.0) (begin (set! (x-bounds curfd) (list 0.0 (min (duration curfd) 1.0))) (when with-gui (let ((xb (x-bounds curfd))) (if (or (fneq (car xb) 0.0) (fneq (cadr xb) (min (duration curfd) 1.0))) (snd-display #__line__ ";x-bounds: ~A?" xb)))))) (set! (y-bounds curfd) (list -0.5 0.5)) (let ((yb (y-bounds curfd))) (when with-gui (if (or (fneq (car yb) -0.5) (fneq (cadr yb) 0.5)) (snd-display #__line__ ";y-bounds: ~A?" yb)))) (set! (cursor curfd 0) curloc) (let ((cl (cursor curfd 0))) (if (and (not (= cl curloc)) (> (framples curfd 0) curloc)) (begin (snd-display #__line__ ";cursor ~A is not ~A (framples: ~A)?" cl curloc (framples curfd 0)) (set! curloc (cursor curfd 0))))) (if (>= curloc (framples curfd 0)) (set! curloc 0)) (let ((id (catch #t (lambda () (add-mark curloc curfd)) (lambda args -1)))) (if (and (number? id) (not (= id -1))) (let ((cl (mark-sample id)) (new-marks (length (marks curfd 0)))) (if (not (= cl curloc)) (snd-display #__line__ ";mark ~A is not ~A?" cl curloc)) (if (not (= new-marks (+ 1 old-marks))) (snd-display #__line__ ";marks ~A ~A?" new-marks old-marks)) (let ((new-id (find-mark curloc curfd))) (if (or (not (mark? new-id)) (not (= id new-id))) (snd-display #__line__ ";find-mark (by sample): ~A ~A (~A for ~A ~A)?" id new-id curloc (mark-sample id) (mark-sample new-id)))) (set! (mark-name id) "hiho") (let ((new-id (find-mark "hiho" curfd))) (if (or (not (mark? new-id)) (not (= id new-id))) (snd-display #__line__ ";find-mark (by name): ~A ~A?" id new-id))) (if (not (string=? (mark-name id) "hiho")) (snd-display #__line__ ";mark name: ~A?" (mark-name id))) (set! (mark-sample id) (max 0 (- curloc 100))) (set! cl (mark-sample id)) (if (not (= cl (max 0 (- curloc 100)))) (snd-display #__line__ ";set mark ~A is not ~A?" cl curloc)) (delete-mark id))) (if (> (duration curfd) 1.2) (set! (x-bounds curfd) '(1.0 1.1))) (if (> (framples curfd) 25) (begin (add-mark 10 curfd) (add-mark 20 curfd) (key (char->integer #\m) 0 curfd) (set! (cursor curfd) 0) (let ((new-marks (length (marks curfd 0)))) (delete-marks curfd) (if (> (duration curfd) 0.0) (set! (x-bounds curfd) (list 0.0 (min (duration curfd) 0.1)))) (set! (y-bounds curfd) '(-1.0 1.0)) (if (or (> (length (marks curfd 0)) 0) (not (= new-marks (+ old-marks 3)))) (snd-display #__line__ ";delete marks: ~A ~A?" new-marks old-marks))))) )) (revert-sound) (let ((old-setting *selection-creates-region*)) (set! *selection-creates-region* #t) (let ((reg (select-all))) (without-errors (if (and (region? reg) (selection?)) (let ((r1 (region-rms (car (regions)))) (r2 (selection-rms))) (if (fneq r1 r2) (snd-display #__line__ ";region rms: ~A?" r1)))))) (set! *selection-creates-region* old-setting)) (without-errors (if (region? (cadr (regions))) (play (cadr (regions)) :wait #t))) (without-errors (mix-region (car (regions)))) (if (< (framples) 100000) (play :wait #t)) (scale-to .1 (choose-fd)) (scale-by 2.0 (choose-fd)) (save-controls) (set! (amp-control) .5) (test-panel amp-control 'amp-control) (restore-controls) (status-report "hi") (without-errors (begin (let ((cfd (choose-fd))) (safe-make-selection 1000 2000 cfd) (src-selection .5) (undo 1 cfd)) (let ((cfd (choose-fd))) (safe-make-selection 1000 2000 cfd) (src-selection -1.5) (undo 1 cfd)) (let ((cfd (choose-fd))) (safe-make-selection 1000 2000 cfd) (scale-selection-by .5) (undo 1 cfd)) (let ((cfd (choose-fd))) (safe-make-selection 1000 2000 cfd) (env-selection '(0 0 1 1 2 0)) (undo 1 cfd)) (let ((cfd (choose-fd))) (safe-make-selection 1000 2000 cfd) (scale-selection-to .5) (reverse-selection) (undo 2 cfd)) (if (> (length (regions)) 2) (forget-region ((regions) 2))))) (for-each revert-sound open-files) (without-errors (let ((cfd (car open-files))) (set! (sync cfd) 1) (if (pair? (cdr open-files)) (set! (sync (cadr open-files)) 1)) (safe-make-selection 1000 2000 cfd) (src-selection .5) (undo 1 cfd) (safe-make-selection 1000 2000 cfd) (src-selection -1.5) (undo 1 cfd) (safe-make-selection 1000 2000 cfd) (env-selection '(0 0 1 1 2 0)) (undo 1 cfd) (safe-make-selection 1000 2000 cfd) (reverse-selection) (undo 1 cfd) (safe-make-selection 1000 2000 cfd) (filter-selection '(0 0 .1 1 1 0) 40) (undo 1 cfd) (safe-make-selection 1000 2000 cfd) (convolve-selection-with "oboe.snd") (undo 1 cfd) (safe-make-selection 1000 2000 cfd) (smooth-selection) (undo 1 cfd) (safe-make-selection 1000 2000 cfd) (scale-selection-by .5) (undo 1 cfd) (scale-selection-to .5) (reverse-selection) (undo 2) (src-selection '(0 .5 1 1)) (undo) (revert-sound cfd) (if (pair? (cdr open-files)) (revert-sound (cadr open-files))))) (if (and (> (framples) 1) (< (framples) 10000)) (begin (make-region 0 (framples)) (convolve-selection-with "fyow.snd" .5) (play :wait #t))) (if (and (> (framples) 1) (< (framples) 10000)) (convolve-with "fyow.snd" .25)) (insert-sound "oboe.snd") (set! (hook-functions graph-hook) ()) (set! (hook-functions after-transform-hook) ()) (for-each revert-sound open-files) (let ((ind (choose-fd))) (select-sound ind) (for-each (lambda (func func1) (pad-channel 0 100 ind 0) (func 0) (pad-channel 0 100 ind 0) (func1 0) (revert-sound ind) (if (> (chans ind) 1) (begin (pad-channel 0 100 ind 1) (func 0) (pad-channel 0 100 ind 1) (func1 0) (revert-sound ind))) (delete-samples 0 1000 ind 0) (func (* 2 (framples ind 0))) (delete-samples 0 10000 ind 0) (func1 (* 2 (framples ind 0))) (revert-sound ind) (if (> (chans ind) 1) (begin (delete-samples 0 1000 ind 1) (func (* 2 (framples ind 1))) (delete-samples 0 10000 ind 1) (func1 (* 2 (framples ind 1))) (revert-sound ind)))) (list (lambda (beg) (insert-sound "2a.snd" beg)) (lambda (beg) (reverse-sound)) (lambda (beg) (if (< (framples ind) 10000) (convolve-with "2a.snd" 0.5) (scale-by 2.0))) (lambda (beg) (env-sound '(0 0 1 1 2 0))) (lambda (beg) (smooth-sound))) (list (lambda (beg) (insert-sound "4a.snd" beg)) (lambda (beg) (reverse-sound)) (lambda (beg) (src-sound 2.0)) (lambda (beg) (env-sound '(0 0 1 1))) (lambda (beg) (insert-silence beg 100))))) (let ((ind (open-sound "z.snd"))) (if (not (= (framples ind) 0)) (snd-display #__line__ ";framples z.snd ~A" (framples ind))) (if (samples) (snd-display #__line__ ";samples of empty file (z): ~A" (samples))) (if (channel->float-vector) (snd-display #__line__ ";channel->float-vector of empty file (z): ~A" (channel->float-vector))) (if (fneq (maxamp ind) 0.0) (snd-display #__line__ ";maxamp z.snd ~A" (maxamp ind))) (if (fneq (sample 100 ind) 0.0) (snd-display #__line__ ";sample 100 z.snd ~A" (sample 100 ind))) (scale-by 2.0) (if (not (= (edit-position ind 0) 0)) (snd-display #__line__ ";scale z: ~A" (edit-position ind 0))) (env-sound '(0 0 1 1)) (if (not (= (edit-position ind 0) 0)) (snd-display #__line__ ";env z: ~A" (edit-position ind 0))) (smooth-sound) (if (not (= (edit-position ind 0) 0)) (snd-display #__line__ ";smooth z: ~A" (edit-position ind 0))) (reverse-sound) (if (not (= (edit-position ind 0) 0)) (snd-display #__line__ ";reverse z: ~A" (edit-position ind 0))) (src-sound 2.0) (if (not (= (edit-position ind 0) 0)) (snd-display #__line__ ";src z: ~A" (edit-position ind 0))) (insert-sound "z.snd") (if (not (= (edit-position ind 0) 0)) (snd-display #__line__ ";insert z: ~A" (edit-position ind 0))) (mix "z.snd") (if (not (= (edit-position ind 0) 0)) (snd-display #__line__ ";mix z: ~A" (edit-position ind 0))) (filter-sound (make-one-zero :a0 2.0 :a1 0.0)) (if (not (= (edit-position ind 0) 0)) (snd-display #__line__ ";filter z: ~A" (edit-position ind 0))) (if (not (= (mus-sound-duration "z.snd") 0.0)) (snd-display #__line__ ";duration z.snd: ~A" (mus-sound-duration "z.snd"))) (catch 'IO-error (lambda () (convolve-with "z.snd" 1.0)) (lambda args args)) (if (not (= (edit-position ind 0) 0)) (snd-display #__line__ ";convolve z: ~A" (edit-position ind 0))) (let ((matches (count-matches (lambda (y) (> y .1))))) (if (and matches (> matches 0)) (snd-display #__line__ ";count z: ~A" matches))) (let* ((reader (make-sampler 0)) (val (next-sample reader)) (str (format #f "~A" reader))) (if (fneq val 0.0) (snd-display #__line__ ";sampler z.snd: ~A" val)) (if (not (string? str)) (snd-display #__line__ ";z.snd reader: ~A" str))) (if (not (equal? (cursor-position) (list 0 0))) (snd-display #__line__ ";cursor-position z: ~A" (cursor-position))) (if (not (= (cursor) 0)) (snd-display #__line__ ";cursor z: ~A" (cursor))) (let ((outer (make-player ind 0))) (let ((pl (make-player ind 0))) (add-player pl) (start-playing 1 22050 #f)) (revert-sound ind) (set! (transform-graph? ind 0) #t) (hook-push lisp-graph-hook display-energy) (set! (x-bounds) (list 0.0 .01)) (set! (sample 0) 0.5) (set! (x-bounds) (list 0.0 .001)) (close-sound ind) (let ((tag (catch #t (lambda () (add-player outer)) (lambda args (car args))))) (if (not (eq? tag 'no-such-player)) (snd-display #__line__ ";dangling player: ~A" tag))))) (if (channel-amp-envs "z.snd" 0 100) (snd-display #__line__ ";channel-amp-envs of empty file: ~A" (channel-amp-envs "z.snd" 0 100))) (let ((zz (view-sound "z.snd"))) (select-sound zz) (mix "4.aiff") (add-mark 0) (add-mark 1200) (delete-marks) (revert-sound zz) (let ((editctr (edit-position zz)) (old-selection-choice *selection-creates-region*)) (set! *selection-creates-region* #t) (if (not (= (edit-position) 0)) (snd-display #__line__ ";revert-sound edit-position: ~A" (edit-position))) (as-one-edit (lambda () (mix s8-snd 24000) (let ((reg (select-all))) (if (selection?) (begin (filter-selection '(0 0 .2 1 .5 0 1 0) 40) (delete-selection) (mix-region reg)))))) (if (not (= (edit-position) 1)) (snd-display #__line__ ";as-one-edit mix zz: ~A -> ~A" editctr (edit-position))) (set! *selection-creates-region* old-selection-choice)) (close-sound zz)) (let ((s8 (view-sound s8-snd))) (select-sound s8) (if (= (channels s8) 8) (begin (select-channel 5) (if (or (not (number? (selected-channel))) (not (= (selected-channel) 5))) (snd-display #__line__ ";select-channel: ~A?" (selected-channel))))) (let ((editctr (edit-position))) (as-one-edit (lambda () (let ((reg (select-all))) (delete-selection) (mix "4.aiff") (set! (sync) 1) (mix "oboe.snd" 60000) (scale-by .1) (set! (sync) 1) (if (> (channels s8) 3) (select-channel 3)) (if (region? reg) (insert-region reg 80000))))) (if (not (= (edit-position) (+ 1 editctr))) (snd-display #__line__ ";as-one-edit s8: ~A -> ~A" editctr (edit-position)))) (revert-sound s8) (close-sound s8)) (let ((cfd (choose-fd))) (if (> (chans cfd) 1) (let ((uval (random 3))) (set! (channel-style cfd) uval) (if (not (= uval (channel-style cfd))) (snd-display #__line__ ";channel-style: ~A ~A?" uval (channel-style cfd))))) (if (< (framples cfd) 200000) (begin (src-sound 2.5 1.0 cfd) (src-sound -2.5 1.0 cfd) (src-sound .5 1.0 cfd) (revert-sound cfd) (src-sound -.5 1.0 cfd) (src-sound '(0 .5 1 1.5) 1.0 cfd) (if (> (framples cfd) 0) (src-sound (make-env '(0 .5 1 1.5) :length (framples cfd)) 1.0 cfd)) (revert-sound cfd) (filter-sound '(0 1 .2 0 .5 1 1 0) 20 cfd) (filter-sound '(0 0 .1 0 .11 1 .12 0 1 0) 2048 cfd) (env-sound '(0 0 .5 1 1 0) 0 (framples cfd) 1.0 cfd) (insert-sample 1200 .1 cfd) (if (fneq (sample 1200 cfd) .1) (snd-display #__line__ ";insert-sample(looped): ~A?" (sample 1200 cfd))))) (revert-sound cfd)) (let ((cfd (open-sound "obtest.snd"))) (select-sound cfd) (let ((cfd2 (open-sound "pistol.snd"))) (select-sound cfd2) ;; now run apply a few times (set! (amp-control) .5) (set! (speed-control) 2.0) (test-panel speed-control 'speed-control) (apply-controls) (if (< (framples) 100000) (play :wait #t)) (if (fneq (reverb-control-decay cfd) *reverb-control-decay*) (snd-display #__line__ ";reverb-control-decay local: ~A, global: ~A" (reverb-control-decay cfd) *reverb-control-decay*)) (set! (reverb-control?) #t) (set! (reverb-control-scale) .2) (test-panel reverb-control-scale 'reverb-control-scale) (test-panel reverb-control-length 'reverb-control-length) (test-panel reverb-control-lowpass 'reverb-control-lowpass) (test-panel reverb-control-feedback 'reverb-control-feedback) (apply-controls) (if (< (framples) 100000) (play :wait #t)) (set! (contrast-control?) #t) (set! (contrast-control) .5) (test-panel contrast-control 'contrast-control) (test-panel contrast-control-amp 'contrast-control-amp) (apply-controls) ; (if (< (framples) 100000) (play :wait #t)) (set! (expand-control?) #t) (set! (expand-control) 2.5) (test-panel expand-control 'expand-control) (test-panel expand-control-length 'expand-control-length) (test-panel expand-control-hop 'expand-control-hop) (test-panel expand-control-ramp 'expand-control-ramp) (apply-controls) ; (if (< (framples) 100000) (play :wait #t)) (set! (filter-control?) #t) (set! *filter-control-order* 40) (test-panel filter-control-order 'filter-control-order) (set! (filter-control-envelope) '(0 0 .1 1 .2 0 1 0)) (filter-control-envelope) (apply-controls) ; (if (< (framples) 100000) (play :wait #t)) (set! (amp-control) 1.5) (test-panel amp-control 'amp-control) (apply-controls) ; (if (< (framples) 100000) (play :wait #t)) (swap-channels cfd 0 cfd2 0) (set! (amp-control #t) .75) (test-panel amp-control 'amp-control) (if (> (abs (- (amp-control cfd2) .75)) .05) (snd-display #__line__ ";set-amp .75 #t -> ~A?" (amp-control cfd2))) (set! (contrast-control-amp #t) .75) (if (fneq (contrast-control-amp cfd2) .75) (snd-display #__line__ ";set-contrast-control-amp .75 #t -> ~A?" (contrast-control-amp cfd2))) (set! (contrast-control-bounds cfd2) (list 2.0 3.0)) (if (not (feql (contrast-control-bounds cfd2) (list 2.0 3.0))) (snd-display #__line__ ";cfd2 contrast-control-bounds: ~A" (contrast-control-bounds cfd2))) (set! (expand-control-length #t) .025) (if (fneq (expand-control-length cfd2) .025) (snd-display #__line__ ";set-expand-control-length .025 #t -> ~A?" (expand-control-length cfd2))) (set! (expand-control-hop #t) .025) (if (fneq (expand-control-hop cfd2) .025) (snd-display #__line__ ";set-expand-control-hop .025 #t -> ~A?" (expand-control-hop cfd2))) (set! (expand-control-jitter #t) .025) (if (fneq (expand-control-jitter cfd2) .025) (snd-display #__line__ ";set-expand-control-jitter .025 #t -> ~A?" (expand-control-jitter cfd2))) (set! (expand-control-ramp #t) .025) (if (fneq (expand-control-ramp cfd2) .025) (snd-display #__line__ ";set-expand-control-ramp .025 #t -> ~A?" (expand-control-ramp cfd2))) (let ((clone (clone-sound-as "/tmp/cloned.snd" cfd2))) (if (not (= (framples cfd2) (framples clone))) (snd-display #__line__ ";clone framples: ~A ~A" (framples cfd2) (framples clone))) (close-sound clone)) (delete-file "/tmp/cloned.snd") (mus-sound-forget "/tmp/cloned.snd") (close-sound cfd2) (close-sound cfd))) (hook-push (edit-hook) (lambda (hook) (set! (hook 'result) #f))) (let ((editctr (edit-position))) (as-one-edit (lambda () (set! (sample 200) .2) (set! (sample 300) .3))) (if (not (= (edit-position) (+ 1 editctr))) (snd-display #__line__ ";as-one-edit: ~A -> ~A" editctr (edit-position))) (as-one-edit (lambda () #f)) (if (not (= (edit-position) (+ 1 editctr))) (snd-display #__line__ ";as-one-edit nil: ~A -> ~A" editctr (edit-position)))) (delete-sample 250) (hook-push (undo-hook) (lambda (hook) (set! (hook 'result) #f))) (undo) (delete-sample 250) (undo) (as-one-edit (lambda () (set! (sample 20) .2) (set! (sample 30) .3))) (undo 1) (as-one-edit (lambda () (set! (sample 2) .2) (as-one-edit (lambda () (set! (sample 3) .3))))) (undo 2) (set! (hook-functions (undo-hook)) ()) (set! (hook-functions (edit-hook)) ()) (hook-push snd-warning-hook (lambda (hook) (let ((msg (hook 'message))) (if (not (string=? msg "hiho")) (snd-display #__line__ ";snd-warning-hook: ~A?" msg)) (set! (hook 'result) #t)))) (snd-warning "hiho") (set! (hook-functions snd-error-hook) ()) (set! (hook-functions snd-warning-hook) ()) (hook-push name-click-hook (lambda (hook) (set! (hook 'result) #t))) (redo 1) (set! (hook-functions name-click-hook) ()) (set! (transform-graph?) #t) (test-channel transform-graph? 'transform-graph?) (test-channel time-graph? 'time-graph?) (test-channel lisp-graph? 'lisp-graph?) (test-channel framples 'framples) (test-channel cursor 'cursor) (test-channel cursor-size 'cursor-size) (test-channel cursor-style 'cursor-style) (test-channel tracking-cursor-style 'tracking-cursor-style) (test-channel left-sample 'left-sample) (test-channel right-sample 'right-sample) (test-channel squelch-update 'squelch-update) (test-channel x-zoom-slider 'x-zoom-slider) (test-channel y-zoom-slider 'y-zoom-slider) (test-channel x-position-slider 'x-position-slider) (test-channel y-position-slider 'y-position-slider) (test-channel edit-position 'edit-position) (test-channel maxamp 'maxamp) (test-channel edit-hook 'edit-hook) (test-channel after-edit-hook 'after-edit-hook) (test-channel undo-hook 'undo-hook) (if (<= tests 2) (set! *transform-type* (add-transform "histogram" "bins" 0.0 1.0 (lambda (len fd) (let ((v (make-float-vector len)) (steps (/ len 16)) (step (/ 1.0 len))) (fill! v 0.0) (do ((i 0 (+ i 1))) ((= i len) v) (let ((bin (round (* 16.0 (abs (next-sample fd)))))) (if (< bin steps) (float-vector-offset! (make-shared-vector v (list steps) bin) step))))))))) (set! (x-bounds) '(.1 .2)) (set! *transform-type* fourier-transform) (set! (x-bounds) '(.1 .2)) (hook-push lisp-graph-hook display-energy) (set! (hook-functions graph-hook) ()) (if (= (channels) 2) (begin (hook-push graph-hook display-correlation) (set! (x-bounds) '(.1 .12)) (set! (x-bounds) '(.1 .2)) (hook-remove graph-hook display-correlation))) (set! (lisp-graph?) #f) (map-channel (let ((buffer (make-delay 128)) (gen (make-moving-average 128)) (current-sample 0) (chan-samples (framples))) (set! (mus-feedback gen) 1.0) (lambda (y) (let ((old-y (delay buffer y))) (set! current-sample (+ 1 current-sample)) (and (> (moving-average gen (* y y)) .01) (if (= current-sample chan-samples) ;; at end return trailing samples as long as it looks like sound (let ((temp-buffer (make-delay 128))) (do ((i 0 (+ i 1)) (fy (delay buffer 0.0) (delay buffer 0.0))) ((= i 128) (mus-data temp-buffer)) (delay temp-buffer (if (> (moving-average gen 0.0) .01) fy 0.0)))) old-y))))) 0 20) (let ((maxval1 (+ (maxamp) .01))) (if (not (every-sample? (lambda (y) (< y maxval1)))) (let ((res (scan-channel (lambda (y) (>= y maxval1))))) (snd-display #__line__ ";~A, every-sample: ~A ~A [~A: ~A]?" (short-file-name) maxval1 res (cursor) (sample (cursor))) (do ((i 0 (+ i 1))) ((= i (edit-position))) (snd-display #__line__ ";~D: ~A ~A" i (maxamp #f 0 i) (edit-fragment i)))))) (map-channel (echo .5 .75) 0 60000) (set! (hook-functions after-transform-hook) ()) (set! (hook-functions lisp-graph-hook) ()) (hook-push lisp-graph-hook (lambda (hook) (if (> (random 1.0) .5) (graph (float-vector 0 1 2)) (graph (list (float-vector 0 1 2) (float-vector 3 2 0)))))) (for-each (lambda (snd) (set! (sync snd) (floor (random 3))) (update-lisp-graph snd)) (sounds)) (hook-push graph-hook superimpose-ffts) (do ((i 0 (+ i 1))) ((= i 10)) (for-each (lambda (snd) (if (> (framples snd) 0) (let* ((dur (floor (/ (framples snd) (srate snd)))) (start (max 0.0 (min (- dur .1) (random dur))))) (if (> dur 0.0) (set! (x-bounds snd 0) (list start (min (+ start .1) dur)))))) (update-time-graph snd) (update-lisp-graph snd) (update-transform-graph snd)) (sounds))) (set! (hook-functions graph-hook) ()) (set! (hook-functions lisp-graph-hook) ()) ;; new variable settings (letrec ((reset-vars (lambda (lst) (if (pair? lst) (let* ((name ((car lst) 0)) (index (and ((car lst) 2) (choose-fd))) (getfnc ((car lst) 1)) (setfnc (lambda (val snd) (set! (getfnc snd) val))) (setfnc-1 (lambda (val) (set! (getfnc) val))) (minval ((car lst) 3)) (maxval ((car lst) 4))) (if index (if (not minval) (setfnc #t index) (if (rational? minval) (if (eq? name #t) (setfnc (floor (expt 2 (min 31 (ceiling (log (+ minval (floor (random (- maxval minval)))) 2))))) index) (setfnc (+ minval (floor (random (- maxval minval)))) index)) (setfnc (+ minval (random (- maxval minval))) index))) (if (not minval) (setfnc-1 #t) (if (rational? minval) (if (eq? name #t) (setfnc-1 (floor (expt 2 (min 31 (ceiling (log (+ minval (floor (random (- maxval minval)))) 2)))))) (setfnc-1 (+ minval (floor (random (- maxval minval)))))) (setfnc-1 (+ minval (random (- maxval minval))))))) (reset-vars (cdr lst))))))) (reset-vars (list (list 'amp-control amp-control #t .1 1.0) ;(list 'ask-before-overwrite ask-before-overwrite #f #f #t) (list 'auto-resize auto-resize #f #f #t) (list 'auto-update auto-update #f #f #t) (list 'channel-style channel-style #f 0 2) (list 'color-cutoff color-cutoff #f 0.0 0.2) (list 'color-inverted color-inverted #f #f #t) (list 'color-scale color-scale #f 0.1 1000.0) (list 'contrast-control contrast-control #t 0.0 1.0) (list 'contrast-control-amp contrast-control-amp #t 0.0 1.0) (list 'contrast-control? contrast-control? #t #f #t) (list 'auto-update-interval auto-update-interval #f 60.0 120.0) (list 'cursor-update-interval cursor-update-interval #f 0.05 .1) (list 'cursor-location-offset cursor-location-offset #f 0 1024) (list 'with-tracking-cursor with-tracking-cursor #f #f #t) (list 'cursor-size cursor-size #f 15 25) (list 'cursor-style cursor-style #f cursor-cross cursor-line) (list 'tracking-cursor-style tracking-cursor-style #f cursor-line cursor-cross) (list 'clipping clipping #f #f #t) ;(list 'default-output-chans default-output-chans #f 1 8) ;(list 'default-output-sample-type default-output-sample-type #f 1 12) ;(list 'default-output-srate default-output-srate #f 22050 44100) ;(list 'default-output-header-type default-output-header-type #f 0 2) (list 'dot-size dot-size #f 1 10) (list 'enved-base enved-base #f 0.01 100.0) (list 'enved-clip? enved-clip? #f #f #t) (list 'enved-in-dB enved-in-dB #f #f #t) (list 'enved-style enved-style #f envelope-linear envelope-exponential) (list 'enved-power enved-power #f 3.0 3.5) (list 'enved-target enved-target #f 0 2) (list 'enved-wave? enved-wave? #f #f #t) (list 'expand-control expand-control #t 0.1 5.0) (list 'expand-control-hop expand-control-hop #t 0.01 0.5) (list 'expand-control-jitter expand-control-jitter #t 0.01 0.5) (list 'expand-control-length expand-control-length #t 0.1 0.25) (list 'expand-control-ramp expand-control-ramp #t 0.1 0.4) (list 'expand-control? expand-control? #t #f #t) (list 'fft-window-alpha fft-window-alpha #f 0.0 1.0) (list 'fft-window-beta fft-window-beta #f 0.0 1.0) (list 'fft-log-frequency fft-log-frequency #f #f #t) (list 'fft-log-magnitude fft-log-magnitude #f #f #t) (list 'fft-with-phases fft-with-phases #f #f #t) (list 'transform-size transform-size #f 16 (if (<= tests 10) 4096 128)) (list 'transform-graph-type transform-graph-type #f graph-once graph-as-spectrogram) (list 'fft-window fft-window #f 0 dolph-chebyshev-window) (list 'transform-graph? transform-graph? #t #f #t) (list 'filter-control-in-dB filter-control-in-dB #t #f #t) (list 'filter-control-in-hz filter-control-in-hz #t #f #t) (list 'filter-control-order filter-control-order #t 2 (if (<= tests 10) 400 40)) (list 'filter-control? filter-control? #t #f #t) ; (list 'graph-cursor graph-cursor #f 0 35) (list 'time-graph-style time-graph-style #f 0 4) (list 'lisp-graph-style lisp-graph-style #f 0 4) (list 'transform-graph-style transform-graph-style #f 0 4) (list 'graphs-horizontal graphs-horizontal #f #f #t) (list 'max-transform-peaks max-transform-peaks #f 1 100) (list 'max-regions max-regions #f 1 32) (list 'min-dB min-dB #f -120.0 -30.0) (list 'log-freq-start log-freq-start #f 50.0 5.0) (list 'selection-creates-region selection-creates-region #f #f #t) (list 'transform-normalization transform-normalization #f dont-normalize normalize-globally) (list 'play-arrow-size play-arrow-size #f 2 32) (list 'print-length print-length #f 2 32) (list 'region-graph-style region-graph-style #f graph-lines graph-lollipops) (list 'reverb-control-decay reverb-control-decay #f 0.0 2.0) (list 'reverb-control-feedback reverb-control-feedback #t 1.00 1.1) (list 'reverb-control-length reverb-control-length #t 1.0 2.0) (list 'reverb-control-lowpass reverb-control-lowpass #t 0.2 0.99) (list 'reverb-control-scale reverb-control-scale #t 0.0 0.2) (list 'reverb-control? reverb-control? #t #f #t) (list 'show-axes show-axes #f 0 2) (list 'show-transform-peaks show-transform-peaks #f #f #t) (list 'show-indices show-indices #f #f #t) (list 'show-marks show-marks #f #f #t) (list 'show-mix-waveforms show-mix-waveforms #t #f #t) (list 'show-selection-transform show-selection-transform #f #f #t) (list 'show-y-zero show-y-zero #f #f #t) (list 'show-grid show-grid #f #f #t) (list 'grid-density grid-density 1.0 0.1 4.0) (list 'show-sonogram-cursor show-sonogram-cursor #f #f #t) (list 'sinc-width sinc-width #f 4 100) (list 'spectrum-end spectrum-end #f 0.5 0.8) (list 'spectro-hop spectro-hop #f 2 20) (list 'spectrum-start spectrum-start #f 0.0 0.1) (list 'spectro-x-angle spectro-x-angle #f 0.0 90.0) (list 'spectro-x-scale spectro-x-scale #f 0.1 2.0) (list 'spectro-y-angle spectro-y-angle #f 0.0 90.0) (list 'spectro-y-scale spectro-y-scale #f 0.1 2.0) (list 'spectro-z-angle spectro-z-angle #f 0.0 359.0) (list 'spectro-z-scale spectro-z-scale #f 0.1 0.2) (list 'speed-control speed-control #t 0.1 5.0) (list 'speed-control-style speed-control-style #f 0 2) (list 'speed-control-tones speed-control-tones #f 2 100) (list 'sync sync #t 0 5) (list 'sync-style sync-style #f 0 3) (list 'with-verbose-cursor with-verbose-cursor #f #f #t) (list 'wavelet-type wavelet-type #f 0 10) (list 'time-graph? time-graph? #t #f #t) (list 'x-axis-style x-axis-style #f 0 2) (list 'beats-per-minute beats-per-minute #f 60.0 120.0) (list 'beats-per-measure beats-per-measure #f 4 120) (list 'zero-pad zero-pad #f 0 2) (list 'zoom-focus-style zoom-focus-style #f 0 3)))) (if (not (equal? *transform-type* fourier-transform)) (begin (set! (transform-graph? #t #t) #f) (set! *transform-size* (min *transform-size* 128)))) ))) (set! *sinc-width* 10) (if open-files (for-each close-sound open-files)) (set! *sync-style* sync-none) (set! open-files ()) (set! (mus-rand-seed) 1234) (if (not (= (mus-rand-seed) 1234)) (snd-display #__line__ ";mus-rand-seed: ~A (1234)!" (mus-rand-seed))) (let ((val (mus-random 1.0)) (val1 (mus-random 1.0))) (if (or (fneq val -0.7828) (fneq val1 -0.8804)) (snd-display #__line__ ";mus-random: ~A ~A?" val val1)) (if (= (mus-rand-seed) 1234) (snd-display #__line__ ";mus-rand-seed: ~A!" (mus-rand-seed)))) (set! (mus-rand-seed) 1234) (let ((val (mus-random 1.0)) (val1 (mus-random 1.0))) (if (or (fneq val -0.7828) (fneq val1 -0.8804)) (snd-display #__line__ ";mus-random repeated: ~A ~A?" val val1))) (set! (hook-functions after-open-hook) ()) (set! (hook-functions close-hook) ()) (set! (hook-functions open-hook) ()) (set! *clipping* #f) (for-each close-sound (sounds)) ) ) ;;; ---------------- test 15: chan-local vars ---------------- (require snd-rubber.scm) (define (snd_test_15) (define (smoother y0 y1 num) (let ((v (make-float-vector (+ 1 num))) (angle (if (> y1 y0) pi 0.0)) (off (* .5 (+ y0 y1))) (incr (/ pi num)) (scale (* 0.5 (abs (- y1 y0))))) (do ((i 0 (+ i 1))) ((= i num) v) (set! (v i) (+ off (* scale (cos (+ angle (* i incr))))))))) (define prefix-it (lambda (n id) (let* ((ns (number->string n)) (digits (length ns))) (key (char->integer #\u) 0 id) (do ((i 0 (+ i 1))) ((= i digits)) (key (char->integer (ns i)) 0 id))))) (define prefix-uit (lambda (n id) (let* ((ns (number->string n)) (digits (length ns))) (do ((i 0 (+ i 1))) ((= i digits)) (key (char->integer (ns i)) 0 id))))) (define funcs (list time-graph-type wavo-hop wavo-trace max-transform-peaks show-transform-peaks zero-pad transform-graph-type fft-window with-verbose-cursor fft-log-frequency fft-log-magnitude fft-with-phases min-dB wavelet-type transform-size fft-window-alpha fft-window-beta transform-type transform-normalization show-mix-waveforms graph-style dot-size show-axes show-y-zero show-grid show-marks grid-density spectro-x-angle spectro-x-scale spectro-y-angle spectro-y-scale spectro-z-angle spectro-z-scale spectro-hop spectrum-end spectrum-start graphs-horizontal x-axis-style beats-per-minute beats-per-measure cursor-size cursor-style tracking-cursor-style show-sonogram-cursor )) (define func-names (list 'time-graph-type 'wavo-hop 'wavo-trace 'max-transform-peaks 'show-transform-peaks 'zero-pad 'transform-graph-type 'fft-window 'with-verbose-cursor 'fft-log-frequency 'fft-log-magnitude 'fft-with-phases 'min-dB 'wavelet-type 'transform-size 'fft-window-alpha 'fft-window-beta 'transform-type 'transform-normalization 'show-mix-waveforms 'graph-style 'dot-size 'show-axes 'show-y-zero 'show-grid 'show-marks 'grid-density 'spectro-x-angle 'spectro-x-scale 'spectro-y-angle 'spectro-y-scale 'spectro-z-angle 'spectro-z-scale 'spectro-hop 'spectrum-end 'spectrum-start 'graphs-horizontal 'x-axis-style 'beats-per-minute 'beats-per-measure 'cursor-size 'cursor-style 'tracking-cursor-style 'show-sonogram-cursor )) (define new-values (list graph-as-wavogram 12 512 3 #t 32 graph-as-sonogram cauchy-window #t #t #t #t -120.0 3 32 .5 .5 autocorrelation 0 #t graph-lollipops 8 show-no-axes #t #t #f 1.0 32.0 .5 32.0 .5 32.0 .5 14 .3 .1 #f x-axis-in-samples 120.0 3 15 cursor-cross cursor-cross #t )) (define (test-history-channel func name new-value snd1 snd2 snd3) (define test-equal (lambda (nv new-value) (if (and (number? nv) (not (rational? nv))) (not (fneq nv new-value)) (equal? nv new-value)))) (define chan-equal? (lambda (vals new-value) (cond ((null? vals) #t) ((pair? vals) (and (chan-equal? (car vals) new-value) (chan-equal? (cdr vals) new-value))) (else (test-equal vals new-value))))) (if (and (not (equal? (flatten (func #t #t)) (apply map func (all-chans)))) (not (equal? (flatten (func #t #t)) (apply map func (all-chans-reversed))))) (snd-display #__line__ ";test-history-channel ~A[0]: ~A ~A?" name (flatten (func #t #t)) (apply map func (all-chans)))) (let ((old-value (func))) (func snd1 0) (set! (func snd1 0) new-value) (let ((nv (func snd1 0))) (if (not (test-equal nv new-value)) (snd-display #__line__ ";test-history-channel set-~A[1]: ~A ~A?" name new-value (func snd1 0)))) (set! (func snd3 2) new-value) (let ((nv (func snd3 2))) (if (not (test-equal nv new-value)) (snd-display #__line__ ";test-history-channel set-~A[2]: ~A ~A?" name new-value (func snd3 2)))) (if (not (test-equal old-value new-value)) (let ((nv (func snd3 1))) (if (test-equal nv new-value) (snd-display #__line__ ";test-history-channel set-~A[3]: ~A ~A?" name new-value (func snd3 1))))) (set! (func snd2 #t) new-value) (let ((nv (func snd2 1))) (if (not (test-equal nv new-value)) (snd-display #__line__ ";test-history-channel set-~A[4]: ~A ~A?" name new-value (func snd2 1)))) (set! (func) new-value) (if (not (chan-equal? (flatten (func #t #t)) new-value)) (snd-display #__line__ ";test-history-channel ~A[5]: ~A ~A?" name (flatten (func #t #t)) (apply map func (all-chans)))) (set! (func) old-value) )) ;; test src-* (define (freq-peak beg ind size) (define (interpolated-peak-offset la ca ra) (let* ((pk (+ .001 (max la ca ra))) (logla (log (/ (max la .0000001) pk) 10)) (logca (log (/ (max ca .0000001) pk) 10)) (logra (log (/ (max ra .0000001) pk) 10))) (/ (* 0.5 (- logla logra)) (- (+ logla logra) (* 2 logca))))) (let* ((data (channel->float-vector beg size ind 0)) (spectr (snd-spectrum data blackman2-window size))) (let ((peak0 0.0) (pk0loc 0) (size2 (/ size 2))) (do ((i 0 (+ i 1))) ((= i size2) (list (/ (* (+ pk0loc (if (> pk0loc 0) (interpolated-peak-offset (spectr (- pk0loc 1)) (spectr pk0loc) (spectr (+ 1 pk0loc))) 0.0)) (srate)) size) peak0)) (if (> (spectr i) peak0) (begin (set! peak0 (spectr i)) (set! pk0loc i))))))) (define (test-selection ind beg len scaler) (set! (selection-member? ind 0) #t) (set! (selection-position) beg) (set! (selection-framples) len) (scale-selection-by scaler) (let* ((diff 0.0) (pos (edit-position ind 0)) (old-reader (make-sampler beg ind 0 1 (- pos 1))) (new-reader (make-sampler beg ind 0 1 pos)) (incr (make-one-pole 1.0 -1.0))) (do ((i 0 (+ i 1))) ((= i len)) (one-pole incr (abs (- (* scaler (next-sample old-reader)) (next-sample new-reader))))) (set! diff (one-pole incr 0.0)) (if (> diff 0.0) (snd-display #__line__ ";diff (~D ~D): ~A" beg len diff)) (set! diff 0.0) (set! incr (make-one-pole 1.0 -1.0)) (do ((i 0 (+ i 1))) ((= i 100)) (one-pole incr (abs (- (next-sample old-reader) (next-sample new-reader))))) (set! diff (one-pole incr 0.0)) (if (> diff 0.0) (snd-display #__line__ ";zdiff (~D ~D): ~A" beg len diff)) (free-sampler old-reader) (free-sampler new-reader))) (define (test-selection-to ind beg len maxval) (set! (selection-member? ind 0) #t) (set! (selection-position) beg) (set! (selection-framples) len) (scale-selection-to maxval) (let ((newmax (float-vector-peak (samples beg len ind 0)))) (if (fneq newmax maxval) (snd-display #__line__ ";scale-selection-to (~D ~D) ~A: ~A?" beg len maxval newmax)))) (define play-with-amps (lambda (sound . amps) (let ((chans (chans sound))) (do ((chan 0 (+ 1 chan))) ((= chan chans)) (let ((player (make-player sound chan))) (if (not (player? player)) (snd-display #__line__ ";player? ~A -> #f?" player)) (if (not (member player (players))) (snd-display #__line__ ";player: ~A, but players: ~A" player (players))) (if (not (equal? (player-home player) (list sound chan))) (snd-display #__line__ ";player-home ~A ~A?" (player-home player) (list sound chan))) (set! (amp-control player) (amps chan)) (set! (speed-control player) .5) (set! (expand-control? player) #t) (set! (expand-control player) 2.0) (set! (contrast-control? player) #t) (set! (contrast-control player) 1.0) (set! (reverb-control? player) #t) (set! (reverb-control-scale player) .02) (add-player player))) (start-playing chans (srate sound) #f)))) ;; examp.scm (commented out) (define (sound-via-sound snd1 snd2) ; "sound composition"?? (let ((intrp (make-sound-interp 0 snd1 0)) (len (- (framples snd1 0) 1)) (rd (make-sampler 0 snd2 0)) (mx (/ 1.0 (maxamp snd2 0)))) (map-channel (lambda (val) (sound-interp intrp (floor (* len 0.5 (+ 1.0 (* mx (read-sample rd)))))))))) (set! *transform-type* fourier-transform) (if with-gui (begin (do ((clmtest 0 (+ 1 clmtest))) ((= clmtest tests)) (log-mem clmtest) (let ((obi (open-sound (car (match-sound-files (lambda (file) (and (not (= (mus-sound-header-type file) mus-raw)) (= (mus-sound-chans file) 1)))))))) (if (not (equal? (all-chans) (list (list obi) (list 0)))) (snd-display #__line__ ";all-chans: ~A?" (all-chans))) (let ((s2i (open-sound (car (match-sound-files (lambda (file) (= (mus-sound-chans file) 2))))))) (if (and (not (equal? (all-chans) (list (list obi s2i s2i) (list 0 0 1)))) (not (equal? (all-chans) (list (list s2i s2i obi) (list 0 1 0))))) (snd-display #__line__ ";all-chans(2): ~A?" (all-chans))) (if (not (string=? (finfo "oboe.snd") "oboe.snd: chans: 1, srate: 22050, Sun/Next, big endian short (16 bits), len: 2.305")) (snd-display #__line__ ";finfo: ~A?" (finfo "oboe.snd"))) (close-sound s2i) (close-sound obi) (if (not (equal? (all-chans) '(() ()))) (snd-display #__line__ ";all-chans(0): ~A?" (all-chans))) (set! obi (open-sound "oboe.snd")) (set! (cursor obi) 1000) (let ((tick (locate-zero .001))) (if (not (= tick 1050)) (snd-display #__line__ ";locate-zero: ~A = ~A (second try: ~A)?" tick (sample tick) (locate-zero .001)))) (hook-push graph-hook auto-dot) (hook-push graph-hook superimpose-ffts) (set! (transform-graph? obi 0) #t) ;(update-graphs) (set! s2i (open-sound (car (match-sound-files (lambda (file) (= (mus-sound-chans file) 2)))))) (if (not (= (chans s2i) 2)) (snd-display #__line__ ";match 2 got ~A with ~A chans" (short-file-name s2i) (chans s2i))) ;(update-graphs) (hook-remove graph-hook auto-dot) (hook-remove graph-hook superimpose-ffts) (set! (transform-graph? obi 0) #f) (select-sound obi) (let ((m1 (add-mark 100 obi 0))) (first-mark-in-window-at-left) (if (> (abs (- (left-sample obi 0) 100)) 1) (snd-display #__line__ ";mark-in-window: ~A ~A?" (left-sample obi 0) (mark-sample m1))) (delete-mark m1)) (close-sound s2i) (safe-make-selection 1000 2000 obi) (delete-selection-and-smooth) (if (not (equal? (edit-fragment 0 obi 0) '("" "init" 0 50828))) (snd-display #__line__ ";edit-fragment(0): ~S?" (edit-fragment 0 obi 0))) (if (not (equal? (edit-fragment 1 obi 0) '("delete-samples 1000 1001" "delete" 1000 1001))) (snd-display #__line__ ";edit-fragment(1): ~S?" (edit-fragment 1 obi 0))) (if (not (equal? (edit-fragment 2 obi 0) '("delete-selection-and-smooth" "set" 968 64))) (snd-display #__line__ ";edit-fragment(2): ~S?" (edit-fragment 2 obi 0))) (let ((maxa (maxamp obi))) (normalized-mix "pistol.snd" 1000 0 obi 0) (let ((nmaxa (maxamp obi))) (if (fneq maxa nmaxa) (snd-display #__line__ ";normalized-mix: ~A ~A?" maxa nmaxa))) (revert-sound obi)) (set! s2i (open-sound (car (match-sound-files (lambda (file) (and (= (mus-sound-chans file) 2) (not (= (mus-sound-header-type file) mus-raw)) (> (mus-sound-framples file) 1000))))))) (if (not (= (chans s2i) 2)) (snd-display #__line__ ";match 2+1000 got ~A with ~A chans" (short-file-name s2i) (chans s2i))) (let ((o1 (sample 1000 obi 0)) (s1 (sample 1000 s2i 0)) (s2 (sample 1000 s2i 1))) (do-all-chans (lambda (val) (* val 2.0)) "double all samples") (let ((o11 (sample 1000 obi 0)) (s11 (sample 1000 s2i 0)) (s21 (sample 1000 s2i 1))) (if (or (fneq (* 2.0 o1) o11) (fneq (* 2.0 s1) s11) (fneq (* 2.0 s2) s21)) (snd-display #__line__ ";do-all-chans: ~A?" (list o1 s1 s2 o11 s11 s21))))) (update-graphs) (let ((m1 (maxamp obi 0)) (m2 (maxamp s2i 0)) (m3 (maxamp s2i 1)) (mc (apply map maxamp (list (list obi s2i s2i) (list 0 0 1))))) (if (or (fneq m1 (car mc)) (fneq m2 (cadr mc)) (fneq m3 (caddr mc))) (snd-display #__line__ ";map maxamp all-chans: ~A ~A ~A ~A?" m1 m2 m3 mc)) (set! (sync obi) 1) (set! (sync s2i) 1) (do-chans (lambda (val) (* val 2.0)) "*2") (let ((mc1 (apply map maxamp (list (list obi s2i s2i) (list 0 0 1))))) (if (or (fneq (* 2.0 m1) (car mc1)) (fneq (* 2.0 m2) (cadr mc1)) (fneq (* 2.0 m3) (caddr mc1))) (snd-display #__line__ ";do-chans: ~A ~A?" mc mc1)) (set! (sync obi) 0) (set! (sync s2i) 0) (select-sound s2i) (do-sound-chans (lambda (val) (* val 0.5)) "/2") (let ((mc2 (apply map maxamp (list (list obi s2i s2i) (list 0 0 1))))) (if (or (fneq (* 2.0 m1) (car mc2)) (fneq m2 (cadr mc2)) (fneq m3 (caddr mc2))) (snd-display #__line__ ";do-sound-chans: ~A ~A ~A?" mc mc1 mc2))) ; (if (every-sample? (lambda (val) (> val .5))) (snd-display #__line__ ";every-sample(0)?")) (if (not (every-sample? (lambda (val) (< val 5.0)))) (snd-display #__line__ ";every-sample(1)?")) (select-sound obi) (let ((bins (sort-samples 32))) (if (not (= (vector-ref bins 1) 4504)) (snd-display #__line__ ";sort-samples: ~A?" bins))) )) (revert-sound s2i) (revert-sound obi) (set! (sync obi) 3) (set! (sync s2i) 3) (let* ((half-way (floor (* 0.5 (framples obi)))) (o1 (sample half-way obi 0)) (s1 (sample half-way s2i 0)) (s2 (sample half-way s2i 1))) (place-sound obi s2i '(0 .5 1 .5)) (let ((s21 (sample half-way s2i 0)) (s22 (sample half-way s2i 1))) (revert-sound s2i) (place-sound obi s2i 45.0) (let ((s31 (sample half-way s2i 0)) (s32 (sample half-way s2i 1))) (if (or (fneq (+ s1 (* 0.5 o1)) s21) (fneq (+ s2 (* 0.5 o1)) s22) (fneq s21 s31) (fneq s22 s32)) (snd-display #__line__ ";place: ~A " (list o1 s1 s2 s21 s22 s31 s32)))))) (revert-sound s2i) (revert-sound obi) (set! (sync obi) 0) (set! (sync s2i) 0) (if (or (fneq ((compand) 0.0) 0.0) (fneq ((compand) 1.0) 1.0) (fneq ((compand) .1) .2) (fneq ((compand) .99) .997) (fneq ((compand) .95) .984)) (snd-display #__line__ ";compand: ~A?" (list ((compand) 0.0) ((compand) 1.0) ((compand) .1) ((compand) .99) ((compand) .95)))) (close-sound obi) (revert-sound s2i) (let ((s1 (sample 1000 s2i 0)) (s2 (sample 1000 s2i 1))) (set! (sync s2i) 4) (select-all) (if (not (= (selection-chans) 2)) (begin (snd-display #__line__ ";selection-chans(2): ~A?" (selection-chans)) (for-each (lambda (snd) (do ((i 0 (+ i 1))) ((= i (chans snd))) (if (selection-member? snd i) (snd-display #__line__ "; ~A[~A] at ~A" (short-file-name snd) i (selection-position snd i))))) (sounds)))) (if (not (= (selection-srate) (srate s2i))) (snd-display #__line__ ";selection-srate: ~A ~A?" (selection-srate) (srate s2i))) (if (= (selection-chans) 2) (begin (swap-selection-channels) (if (or (fneq s1 (sample 1000 s2i 1)) (fneq s2 (sample 1000 s2i 0))) (snd-display #__line__ ";swap-selection-channels: ~A?" (list s1 s2 (sample 1000 s2i 0) (sample 1000 s2i 1))))))) (revert-sound s2i) (close-sound s2i) (set! obi (open-sound "oboe.snd")) (select-all) (for-each forget-region (regions)) (if (not (null? (regions))) (snd-display #__line__ ";no regions? ~A" (regions))) (let ((id (make-region 100 200 obi 0))) (if (not (equal? (regions) (list id))) (snd-display #__line__ ";make-region regions: ~A?" (regions)))) (revert-sound obi) (let ((oldlen (framples obi))) (env-sound-interp '(0 0 1 1 2 0) 2.0 obi 0) (let ((newlen (framples obi))) (if (> (abs (- (* 2 oldlen) newlen)) 3) (snd-display #__line__ ";env-sound-interp: ~A ~A?" oldlen newlen)))) (revert-sound obi) (granulated-sound-interp '(0 0 1 .1 2 1) 1.0 0.2 '(0 0 1 1 2 0)) (if (not (= (edit-position obi 0) 1)) (snd-display #__line__ ";granulated-sound-interp no-op 1?")) (if (< (maxamp obi 0) .15) (snd-display #__line__ ";granulated-sound-interp 1 maxamp: ~A" (maxamp obi 0))) (if (> (abs (- (framples obi 0) 50828)) 1000) (snd-display #__line__ ";granulated-sound-interp 1 framples: ~A" (framples obi 0))) (revert-sound obi) (granulated-sound-interp '(0 0 1 1) 2.0) (if (not (= (edit-position obi 0) 1)) (snd-display #__line__ ";granulated-sound-interp no-op 2?")) (if (< (maxamp obi 0) .145) (snd-display #__line__ ";granulated-sound-interp 2 maxamp: ~A" (maxamp obi 0))) (if (> (abs (- (framples obi 0) 101656)) 1000) (snd-display #__line__ ";granulated-sound-interp 2 framples: ~A" (framples obi 0))) (revert-sound obi) (granulated-sound-interp '(0 0 1 .1 2 1) 1.0 0.2 '(0 0 1 1 2 0) 0.02) (if (not (= (edit-position obi 0) 1)) (snd-display #__line__ ";granulated-sound-interp no-op 3?")) (if (< (maxamp obi 0) .2) (snd-display #__line__ ";granulated-sound-interp 3 maxamp: ~A" (maxamp obi 0))) (if (> (abs (- (framples obi 0) 50828)) 1000) (snd-display #__line__ ";granulated-sound-interp 3 framples: ~A" (framples obi 0))) (close-sound obi) ) (let ((old-srate *clm-srate*)) (set! *clm-srate* 22050) (let ((ind (new-sound "test.snd" :size 20))) (if (< *print-length* 20) (set! *print-length* 20)) (offset-channel 1.0) (env-sound '(0 0 1 1)) (let ((osc (make-oscil :frequency 1000.0 :initial-phase (+ pi (/ pi 2)))) (reader (make-sound-interp 0 ind 0)) (len (- (framples ind 0) 1))) (map-channel (lambda (val) (sound-interp reader (* len (+ 0.5 (* 0.5 (oscil osc))))))) (if (not (vequal (channel->float-vector) (float-vector 0.000 0.020 0.079 0.172 0.291 0.427 0.569 0.706 0.825 0.919 0.979 1.000 0.981 0.923 0.831 0.712 0.576 0.434 0.298 0.177))) (snd-display #__line__ ";sound-interp: ~A" (channel->float-vector)))) (undo) (let ((osc (make-oscil :frequency 0.5 :initial-phase (+ pi (/ pi 2)))) (reader (make-sound-interp 0 ind 0)) (len (- (framples ind 0) 1))) (map-channel (lambda (val) (sound-interp reader (* len (+ 0.5 (* 0.5 (oscil osc)))))))) (undo) (env-sound-interp '(0 0 1 1)) (if (not (vequal (channel->float-vector) (float-vector 0.000 0.053 0.105 0.158 0.211 0.263 0.316 0.368 0.421 0.474 0.526 0.579 0.632 0.684 0.737 0.789 0.842 0.895 0.947 1.000))) (snd-display #__line__ ";env-sound-interp no change: ~A" (channel->float-vector))) (undo) (env-sound-interp '(0 0 1 .95 2 0) 2.0) (if (not (vequal (channel->float-vector) (float-vector 0.000 0.050 0.100 0.150 0.200 0.250 0.300 0.350 0.400 0.450 0.500 0.550 0.600 0.650 0.700 0.750 0.800 0.850 0.900 0.950 1.000 0.950 0.900 0.850 0.800 0.750 0.700 0.650 0.600 0.550 0.500 0.450 0.400 0.350 0.300 0.250 0.200 0.150 0.100 0.050))) (snd-display #__line__ ";env-sound-interp twice len and back: ~A" (channel->float-vector))) (revert-sound ind) (set! (sample 10) .5) (remove-clicks) (if (fneq (sample 10) 0.0) (snd-display #__line__ ";remove-clicks: ~A" (channel->float-vector))) (undo) (let ((vals (scan-channel (search-for-click)))) (if (not (= vals 11)) (snd-display #__line__ ";search-for-click: ~A" vals))) (close-sound ind)) (set! *clm-srate* old-srate)) (let ((ind1 (new-sound :size 20 :comment "new-sound for sound-via-sound")) (ind2 (new-sound :size 20 :comment "second new-sound for sound-via-sound"))) (let ((val -0.05)) (map-channel (lambda (y) (set! val (+ val .05))) 0 20 ind1)) (let ((val 1.1)) (map-channel (lambda (y) (set! val (- val .1))) 0 20 ind2)) (select-sound ind1) (sound-via-sound ind1 ind2) (let ((vals (channel->float-vector 0 20 ind1))) (if (not (vequal vals (float-vector 0.95 0.90 0.85 0.80 0.75 0.70 0.65 0.60 0.55 0.50 0.45 0.40 0.35 0.30 0.25 0.20 0.15 0.10 0.05 0.00))) (snd-display #__line__ ";sound-via-sound: ~A" vals))) (let ((new-file-name (file-name ind2))) (close-sound ind2) (if (file-exists? new-file-name) (delete-file new-file-name))) (revert-sound ind1) (let ((val -.5)) (map-channel (lambda (y) (set! val (+ val .05))))) (let ((val (scan-channel (zero+)))) (if (or (not val) (not (= val 10))) (snd-display #__line__ ";zero+: ~A" val))) (set! (sample 8) .8) (let ((val (scan-channel (next-peak)))) (if (or (not val) (not (= val 9))) (snd-display #__line__ ";next-peak: ~A" val))) (let ((val (scan-channel (search-for-click)))) (if (or (not val) (not (= val 9))) (snd-display #__line__ ";search-for-click: ~A" val))) (if (not (= (find-click 0) 8)) (snd-display #__line__ ";find-click: ~A" (find-click 0))) (let ((new-file-name (file-name ind1))) (close-sound ind1) (if (file-exists? new-file-name) (delete-file new-file-name)))) (let* ((id (open-sound "oboe.snd")) (fr (framples id 0)) (mx (maxamp id 0))) (set! (framples id 0) 25000) (if (not (= (framples id 0) 25000)) (snd-display #__line__ ";set-framples 25000: ~A?" (framples id 0))) (if (not (= (edit-position id 0) 1)) (snd-display #__line__ ";set-framples 25000 edit: ~A?" (edit-position id 0))) (set! (framples id 0) 75000) (if (not (= (framples id 0) 75000)) (snd-display #__line__ ";set-framples 75000: ~A?" (framples id 0))) (if (not (= (edit-position id 0) 2)) (snd-display #__line__ ";set-framples 75000 edit: ~A?" (edit-position id 0))) (if (fneq (sample 30000 id 0) 0.0) (snd-display #__line__ ";set-framples 75000 zeros: ~A?" (sample 30000 id 0))) (set! (framples id 0) 0) (if (not (= (framples id 0) 0)) (snd-display #__line__ ";set-framples 0: ~A?" (framples id 0))) (set! (framples id 0) 100) (if (not (= (framples id 0) 100)) (snd-display #__line__ ";set-framples 100: ~A?" (framples id 0))) (revert-sound) (if (fneq (sample 30000 id 0) -0.0844) (snd-display #__line__ ";revert from set-framples: ~A?" (sample 30000 id 0))) (if (not (= fr (framples id 0))) (snd-display #__line__ ";revert set-framples: ~A != ~A?" (framples id 0) fr)) (set! (maxamp id 0) .5) (if (fneq (maxamp id 0) .5) (snd-display #__line__ ";set-maxamp: ~A?" (maxamp id 0))) (if (not (= (edit-position id 0) 1)) (snd-display #__line__ ";set-maxamp edit: ~A?" (edit-position id 0))) (set! (maxamp id 0) .1) (if (fneq (maxamp id 0) .1) (snd-display #__line__ ";set-maxamp .1: ~A?" (maxamp id 0))) (if (not (= (edit-position id 0) 2)) (snd-display #__line__ ";set-maxamp .1 edit: ~A?" (edit-position id 0))) (revert-sound) (if (fneq (maxamp id 0) mx) (snd-display #__line__ ";maxamp after set: ~A ~A?" (maxamp id 0) mx)) (set! (x-position-slider id 0) .1) (if (fneq (x-position-slider id 0) .1) (snd-display #__line__ ";set x-position-slider .1: ~A?" (x-position-slider id 0))) ;(if (> (abs (- (left-sample id 0) 5083)) 3) (snd-display #__line__ ";set x-position-slider sample 5083: ~A?" (left-sample id 0))) (set! (x-zoom-slider id 0) .5) (if (fneq (x-zoom-slider id 0) .5) (snd-display #__line__ ";set x-zoom-slider: ~A?" (x-zoom-slider id 0))) (if (> (abs (- fr (* 2 (- (right-sample id 0) (left-sample id 0))))) 10) (snd-display #__line__ ";set x-zoom-slider: ~A ~A -> ~A?" (left-sample id 0) (right-sample id 0) (abs (- fr (* 2 (right-sample id 0) (left-sample id 0)))))) (set! (y-position-slider id 0) .1) (if (and (not (provided? 'snd-gtk)) (fneq (y-position-slider id 0) .1)) (snd-display #__line__ ";set y-position-slider .1: ~A?" (y-position-slider id 0))) (set! (y-zoom-slider id 0) .5) (if (fneq (y-zoom-slider id 0) .5) (snd-display #__line__ ";set y-zoom-slider: ~A?" (y-zoom-slider id 0))) (let ((vals (channel-amp-envs "oboe.snd" 0 10))) (if (or (not (vequal (car vals) (float-vector -4.8828125e-4 -0.104156494140625 -0.125213623046875 -0.1356201171875 -0.138916015625 -0.14093017578125 -0.14093017578125 -0.131439208984375 -0.11248779296875 -0.080047607421875))) (not (vequal (cadr vals) (float-vector 0.0 0.10955810546875 0.130706787109375 0.14068603515625 0.141204833984375 0.147247314453125 0.145904541015625 0.140289306640625 0.126861572265625 0.08172607421875)))) (snd-display #__line__ ";channel-amp-envs: ~A?" vals))) (let ((len (length (channel-properties id 0)))) (if (channel-property 'hiho id 0) (snd-display #__line__ ";channel-property 'hiho: ~A?" (channel-property 'hiho id 0))) (set! (channel-property 'hiho id 0) 123) (if (not (= (channel-property 'hiho id 0) 123)) (snd-display #__line__ ";channel-property 'hiho (123): ~A?" (channel-property 'hiho id 0))) (if (channel-property 'hi id 0) (snd-display #__line__ ";channel-property 'hi: ~A?" (channel-property 'hi id 0))) (set! (channel-property 'hi id 0) pi) (if (fneq (channel-property 'hi id 0) pi) (snd-display #__line__ ";channel-property 'hi (pi): ~A?" (channel-property 'hi id 0))) (if (not (= (channel-property 'hiho id 0) 123)) (snd-display #__line__ ";channel-property 'second hiho (123): ~A?" (channel-property 'hiho id 0))) (if (not (= (length (channel-properties id 0)) (+ len 2))) (snd-display #__line__ ";channel-properties: ~A?" (channel-properties id 0)))) (let ((len (length (sound-properties id)))) (if (sound-property 'hiho id) (snd-display #__line__ ";sound-property 'hiho: ~A?" (sound-property 'hiho id))) (set! (sound-property 'hiho id) 123) (if (not (= (sound-property 'hiho id) 123)) (snd-display #__line__ ";sound-property 'hiho (123): ~A?" (sound-property 'hiho id))) (if (sound-property 'hi id) (snd-display #__line__ ";sound-property 'hi: ~A?" (sound-property 'hi id))) (set! (sound-property 'hi id) pi) (if (fneq (sound-property 'hi id) pi) (snd-display #__line__ ";sound-property 'hi (pi): ~A?" (sound-property 'hi id))) (if (not (= (sound-property 'hiho id) 123)) (snd-display #__line__ ";sound-property 'second hiho (123): ~A?" (sound-property 'hiho id))) (if (not (= (length (sound-properties id)) (+ len 2))) (snd-display #__line__ ";sound-properties: ~A?" (sound-properties id)))) (let ((tag (catch #t (lambda () (map-channel (lambda (y) "hiho"))) (lambda args args)))) (if (not (eq? (car tag) 'wrong-type-arg)) (snd-display #__line__ ";map-channel bad val: ~A" tag))) (close-sound id)) (let ((ind (open-sound "oboe.snd"))) (if (not (null? (edit-properties ind 0 0))) (snd-display #__line__ ";initial edit-properties: ~A?" (edit-properties ind 0 0))) (let ((tag (catch #t (lambda () (edit-properties ind 0 123)) (lambda args (car args))))) (if (not (eq? tag 'no-such-edit)) (snd-display #__line__ ";edit-properties of non-existent edit: ~A" tag))) (let ((tag (catch #t (lambda () (edit-properties ind 1 0)) (lambda args (car args))))) (if (not (eq? tag 'no-such-channel)) (snd-display #__line__ ";edit-properties of non-existent channel: ~A" tag))) (if (edit-property 'test-key ind 0 0) (snd-display #__line__ ";edit-property never set: ~A?" (edit-property ind 0 0))) (set! (edit-property 'test-key ind 0 0) 3210) (let ((val (edit-property 'test-key ind 0 0))) (if (or (not (number? val)) (not (= val 3210))) (snd-display #__line__ ";edit-property 0: ~A" val))) (pad-channel 0 10 ind 0) (let ((val (edit-property 'test-key ind 0 0))) (if (or (not (number? val)) (not (= val 3210))) (snd-display #__line__ ";edit-property look back to 0: ~A" val))) (let ((val (edit-property 'test-key ind 0 1))) (if val (snd-display #__line__ ";edit-property current: ~A?" val))) (undo) (let ((val (edit-property 'test-key ind 0 0))) (if (or (not (number? val)) (not (= val 3210))) (snd-display #__line__ ";edit-property go back to 0: ~A" val))) (close-sound ind) (set! ind (open-sound "oboe.snd")) (if (edit-property 'test-key ind 0 0) (snd-display #__line__ ";edit-property not cleared: ~A?" (edit-property ind 0 0))) (pad-channel 0 10 ind 0) (set! (edit-property 'test-key ind 0 1) 'hiho) (undo) (pad-channel 0 10 ind 0) (let ((val (edit-property 'test-key ind 0 1))) (if val (snd-display #__line__ ";edit-property not erased upon re-edit: ~A?" val))) (close-sound ind)) (let ((id (open-sound "oboe.snd"))) (prefix-it 1000 id) (key (char->integer #\x) 4 id) (key (char->integer #\b) 4 id) (let ((left (left-sample id))) (if (not (= left 1000)) (snd-display #__line__ ";u1000: ~A" left))) (prefix-it 0 id) (key (char->integer #\x) 4 id) (key (char->integer #\b) 4 id) (let ((left (left-sample id))) (if (not (= left 0)) (snd-display #__line__ ";u0: ~A" left))) (set! (cursor id) 1234) (prefix-it 0 id) (key (char->integer #\f) 4 id) (let ((cr (cursor id))) (if (not (= cr 1234)) (snd-display #__line__ ";0f: ~A" cr))) (prefix-it 100 id) (key (char->integer #\f) 4 id) (let ((cr (cursor id))) (if (not (= cr 1334)) (snd-display #__line__ ";100f: ~A" cr))) (prefix-it -100 id) (key (char->integer #\f) 4 id) (let ((cr (cursor id))) (if (not (= cr 1234)) (snd-display #__line__ ";-100f: ~A" cr))) (prefix-it 1 id) (key (char->integer #\f) 4 id) (let ((cr (cursor id))) (if (not (= cr 1235)) (snd-display #__line__ ";1f: ~A" cr))) (prefix-it 1000 id) (key (char->integer #\x) 4 id) (key (char->integer #\p) 4 id) (let ((left (left-sample id)) (right (right-sample id))) (if (> (abs (- right left 1000)) 2) (snd-display #__line__ ";1000xp: ~A:~A" left right))) (prefix-it 1 id) (key (char->integer #\.) 0 id) (key (char->integer #\2) 0 id) (key (char->integer #\x) 4 id) (key (char->integer #\p) 4 id) (let ((left (left-sample id)) (right (right-sample id))) (if (> (abs (- right left (* 22050 1.2))) 2) (snd-display #__line__ ";1.2xp: ~A:~A" left right))) (prefix-uit 1000 id) (key (char->integer #\x) 4 id) (key (char->integer #\b) 4 id) (let ((left (left-sample id))) (if (and (not (= left 1000)) (not (= left 1001))) (snd-display #__line__ ";uu1000: ~A" left))) (prefix-uit 0 id) (key (char->integer #\x) 4 id) (key (char->integer #\b) 4 id) (let ((left (left-sample id))) (if (not (= left 0)) (snd-display #__line__ ";uu0: ~A" left))) (set! (cursor id) 1234) (prefix-uit 0 id) (key (char->integer #\f) 4 id) (let ((cr (cursor id))) (if (not (= cr 1234)) (snd-display #__line__ ";u0f: ~A" cr))) (prefix-uit 100 id) (key (char->integer #\f) 4 id) (let ((cr (cursor id))) (if (not (= cr 1334)) (snd-display #__line__ ";u100f: ~A" cr))) (prefix-uit -100 id) (key (char->integer #\f) 4 id) (let ((cr (cursor id))) (if (not (= cr 1234)) (snd-display #__line__ ";u-100f: ~A" cr))) (prefix-uit 1 id) (key (char->integer #\f) 4 id) (let ((cr (cursor id))) (if (not (= cr 1235)) (snd-display #__line__ ";u1f: ~A" cr))) (prefix-uit 1000 id) (key (char->integer #\x) 4 id) (key (char->integer #\p) 4 id) (let ((left (left-sample id)) (right (right-sample id))) (if (> (abs (- right left 1000)) 2) (snd-display #__line__ ";u1000xp: ~A:~A" left right))) (prefix-uit 1 id) (key (char->integer #\.) 0 id) (key (char->integer #\2) 0 id) (key (char->integer #\x) 4 id) (key (char->integer #\p) 4 id) (let ((left (left-sample id)) (right (right-sample id))) (if (> (abs (- right left (* 22050 1.2))) 2) (snd-display #__line__ ";u1.2xp: ~A:~A" left right))) (close-sound id)) (let ((id (open-sound (car (match-sound-files (lambda (file) (and (>= (mus-sound-chans file) 2) (not (= (mus-sound-header-type file) mus-raw)) (> (mus-sound-framples file) 1000)))))))) (set! (sync id) 1) (select-sound id) (make-region 200 500 id) (select-channel 1) (key (char->integer #\x) 4 id) (key (char->integer #\v) 0 id) (let ((x0 (x-bounds id 0)) (x1 (x-bounds id 1))) (if (or (fneq (car x0) (car x1)) (fneq (cadr x0) (cadr x1))) (snd-display #__line__ ";C-X v: ~A ~A?" x0 x1))) (key (char->integer #\u) 4 id) (key (char->integer #\1) 0 id) (key (char->integer #\x) 4 id) (key (char->integer #\q) 0 id) (close-sound id)) (let ((snd1 (open-sound "oboe.snd")) (snd2 (or (open-sound "2.snd") (open-sound "4.aiff"))) (snd3 (open-sound "4.aiff"))) (define tests-1 (lambda (f fn nv) (if (pair? f) (begin (test-history-channel (car f) (car fn) (car nv) snd1 snd2 snd3) (tests-1 (cdr f) (cdr fn) (cdr nv)))))) (tests-1 funcs func-names new-values) (close-sound snd1) (close-sound snd2) (set! (time-graph-style snd3 #t) graph-filled) (do ((i 0 (+ i 1))) ((= i 4)) (if (not (= (time-graph-style snd3 i) graph-filled)) (snd-display #__line__ ";set time-graph-style ~A ~A: ~A" snd3 i (time-graph-style snd3 i)))) (set! (time-graph-style snd3 2) graph-lines) (do ((i 0 (+ i 1))) ((= i 4)) (if (and (not (= i 2)) (not (= (time-graph-style snd3 i) graph-filled))) (snd-display #__line__ ";set (2) time-graph-style ~A ~A: ~A" snd3 i (time-graph-style snd3 i)))) (if (not (= (time-graph-style snd3 2) graph-lines)) (snd-display #__line__ ";set time-graph-style (2): ~A" (time-graph-style snd3 2))) (set! (time-graph-style snd3 #t) graph-dots) (do ((i 0 (+ i 1))) ((= i 4)) (if (not (= (time-graph-style snd3 i) graph-dots)) (snd-display #__line__ ";set time-graph-style (all): ~A" (time-graph-style snd3 i)))) (set! *graph-style* graph-dots-and-lines) (do ((i 0 (+ i 1))) ((= i 4)) (if (not (= (time-graph-style snd3 i) graph-dots-and-lines)) (snd-display #__line__ ";set time-graph-style (dal): ~A" (time-graph-style snd3 i)))) (set! (lisp-graph-style snd3 #t) graph-filled) (do ((i 0 (+ i 1))) ((= i 4)) (if (not (= (lisp-graph-style snd3 i) graph-filled)) (snd-display #__line__ ";set lisp-graph-style ~A ~A: ~A" snd3 i (lisp-graph-style snd3 i)))) (set! (lisp-graph-style snd3 2) graph-lines) (do ((i 0 (+ i 1))) ((= i 4)) (if (and (not (= i 2)) (not (= (lisp-graph-style snd3 i) graph-filled))) (snd-display #__line__ ";set (2) lisp-graph-style ~A ~A: ~A" snd3 i (lisp-graph-style snd3 i)))) (if (not (= (lisp-graph-style snd3 2) graph-lines)) (snd-display #__line__ ";set lisp-graph-style (2): ~A" (lisp-graph-style snd3 2))) (set! (lisp-graph-style snd3 #t) graph-lines) (do ((i 0 (+ i 1))) ((= i 4)) (if (not (= (time-graph-style snd3 i) graph-dots-and-lines)) (snd-display #__line__ ";set lisp -> time-graph-style (dal): ~A" (time-graph-style snd3 i)))) (set! (transform-graph-style snd3 #t) graph-filled) (do ((i 0 (+ i 1))) ((= i 4)) (if (not (= (transform-graph-style snd3 i) graph-filled)) (snd-display #__line__ ";set transform-graph-style ~A ~A: ~A" snd3 i (transform-graph-style snd3 i)))) (set! (transform-graph-style snd3 2) graph-lines) (do ((i 0 (+ i 1))) ((= i 4)) (if (and (not (= i 2)) (not (= (transform-graph-style snd3 i) graph-filled))) (snd-display #__line__ ";set (2) transform-graph-style ~A ~A: ~A" snd3 i (transform-graph-style snd3 i)))) (if (not (= (transform-graph-style snd3 2) graph-lines)) (snd-display #__line__ ";set transform-graph-style (2): ~A" (transform-graph-style snd3 2))) (do ((i 0 (+ i 1))) ((= i 4)) (if (not (= (time-graph-style snd3 i) graph-dots-and-lines)) (snd-display #__line__ ";set fft and lisp -> time-graph-style (dal): ~A" (time-graph-style snd3 i)))) (do ((i 0 (+ i 1))) ((= i 4)) (if (not (= (lisp-graph-style snd3 i) graph-lines)) (snd-display #__line__ ";set fft and lisp -> lisp-graph-style (dal): ~A" (lisp-graph-style snd3 i)))) (close-sound snd3)) (let ((snd2 (open-sound "2.snd"))) (if (sound? snd2) (play-with-amps snd2 0.2 0.1)) (close-sound snd2)) (let ((old-bp *with-background-processes*)) (set! *with-background-processes* #f) (let* ((ind (open-sound "1a.snd")) (player (make-player ind 0)) (len (framples ind 0)) (incr *dac-size*) (e (make-env '(0 0 1 1) :length (+ 1 (floor (* 1.0 (/ len incr)))))) (samp 0)) (add-player player 0 -1 -1 (lambda (reason) (set! (hook-functions play-hook) ()) (close-sound ind))) (hook-push play-hook (lambda (hook) (set! (amp-control player) (env e)) (if (fneq (amp-control ind) 1.0) (snd-display #__line__ ";amp-control snd: ~A" (amp-control ind))) (if (> (abs (- (amp-control player) (* 1.0 (/ samp len)))) 1.0) (snd-display #__line__ ";amp-control player: ~A ~A" (amp-control player) (* 1.0 (/ samp len)))) (set! samp (+ samp incr)))) (start-playing 1 (srate ind))) (if (find-sound "1a.snd") (snd-display #__line__ ";stop proc didn't close?")) (set! *with-background-processes* old-bp)) (let ((ind (open-sound "pistol.snd"))) (if (selection-member? ind 0) (snd-display #__line__ ";initial selection-member? ~A ~A?" (selection-member? ind 0) (selection?))) (set! (selection-member? ind 0) #t) (if (or (not (selection-member? ind 0)) (not (selection-member? ind))) (snd-display #__line__ ";selection-member? ~A ~A ~A?" (selection-member? ind 0) (selection-member? ind) (selection?))) (if (not (= (selection-framples) 1)) (snd-display #__line__ ";initial selection-framples: ~A?" (selection-framples))) (set! (selection-framples) 1200) (if (not (= (selection-framples) 1200)) (snd-display #__line__ ";selection-framples: 1200 ~A?" (selection-framples))) (delete-selection) (if (selection?) (snd-display #__line__ ";selection active after cut?")) (undo) (if (not (selection?)) (snd-display #__line__ ";selection inactive after undo?")) (if (or (not (selection-member? ind 0)) (not (selection-member? ind))) (snd-display #__line__ ";selection-member? after undo ~A ~A ~A?" (selection-member? ind 0) (selection-member? ind) (selection?))) (if (or (not (= (selection-framples) 1200)) (not (= (selection-position) 0))) (snd-display #__line__ ";selection after undo: '(0 1200) '(~A ~A)?" (selection-position) (selection-framples))) (set! (selection-position) 1000) (if (or (not (= (selection-framples) 200)) (not (= (selection-position) 1000))) (snd-display #__line__ ";selection after reposition: '(1000 200) '(~A ~A)?" (selection-position) (selection-framples))) (reverse-selection) (if (or (not (= (selection-framples) 200)) (not (= (selection-position) 1000))) (snd-display #__line__ ";selection after reverse: '(1000 200) '(~A ~A)?" (selection-position) (selection-framples))) (let ((old-framples (framples ind))) (src-selection .5) (if (or (> (abs (- (framples ind) (+ 200 old-framples))) 5) (> (abs (- (selection-framples) 400)) 5)) (snd-display #__line__ ";selection after src .5: '(1000 400) '(~A ~A)?" (selection-position) (selection-framples))) (undo) (redo) (if (or (> (abs (- (framples ind) (+ 200 old-framples))) 5) (> (abs (- (selection-framples) 400)) 5)) (snd-display #__line__ ";selection after src .5 with undo/redo: '(1000 400) '(~A ~A)?" (selection-position) (selection-framples))) (undo 3)) (close-sound ind)) (set! *clm-srate* 22050) (let ((ind (new-sound "test.snd" 1 22050 mus-ldouble mus-next "src-* tests" 10000)) (osc (make-oscil 500))) (define f3neq (lambda (a b) (> (abs (- a b)) 10))) (define f4neq (lambda (a b) (> (abs (- a b)) 1))) (define f5neq (lambda (a b) (> (abs (- a b)) (* .05 (max a b))))) ;; src-duration tests (if (or (fneq (src-duration '(0 1 1 2)) 0.693147180559945) (fneq (src-duration '(0 2 1 1)) (src-duration '(0 1 1 2))) (fneq (src-duration '(0 1 .5 2)) (src-duration '(0 1 1 2))) (fneq (src-duration '(.5 1 .75 2)) (src-duration '(0 1 1 2)))) (snd-display #__line__ ";src-duration test1 ~A ~A ~A ~A" (src-duration '(0 1 1 2)) (src-duration '(0 2 1 1)) (src-duration '(0 1 .5 2)) (src-duration '(.5 1 .75 2)))) (if (or (fneq (src-duration '(0 1 1 0.5)) 1.38629436111989) (fneq (src-duration '(0 0.5 1 1)) (src-duration '(0 1 1 0.5))) (fneq (src-duration '(0 1 .5 0.5)) (src-duration '(0 1 1 0.5))) (fneq (src-duration '(.5 1 .75 0.5)) (src-duration '(0 1 1 0.5)))) (snd-display #__line__ ";src-duration test2 ~A ~A ~A ~A" (src-duration '(0 1 1 0.5)) (src-duration '(0 0.5 1 1)) (src-duration '(0 1 .5 0.5)) (src-duration '(.5 1 .75 0.5)))) (if (or (fneq (src-duration '(0 1 1 1)) 1.0) (fneq (src-duration '(0 2 1 2)) 0.5)) (snd-display #__line__ ";src-duration test3: ~A ~A" (src-duration '(0 1 1 1)) (src-duration '(0 2 1 2)))) (if (fneq (src-duration '(0 .5 .5 3 .6 1 .7 .1 .8 1.5 1 1)) 1.02474349685432) (snd-display #__line__ ";src-duration test4 ~A" (src-duration '(0 .5 .5 3 .6 1 .7 .1 .8 1.5 1 1)))) (if (fneq (src-duration '(0 1 1 2 2 1)) 0.693147180559945) (snd-display #__line__ ";src-duration test5: ~A" (src-duration '(0 1 1 2 2 1)))) (if (fneq (src-duration '(0 1 1 1)) 1.0) (snd-display #__line__ ";src-duration test6: ~A" (src-duration '(0 1 1 1)))) (if (fneq (src-duration '(0 2 1 2)) 0.5) (snd-display #__line__ ";src-duration test7: ~A" (src-duration '(0 2 1 2)))) (if (fneq (src-duration '(0 0.5 2 0.5)) 2.0) (snd-display #__line__ ";src-duration test8: ~A" (src-duration '(0 0.5 2 0.5)))) (if (fneq (src-duration (src-fit-envelope '(0 1 1 2) 2.0)) 2.0) (snd-display #__line__ ";src-fit-envelope 2.0: ~A" (src-duration (src-fit-envelope '(0 1 1 2) 2.0)))) (if (fneq (src-duration (src-fit-envelope '(0 1 1 2) 0.5)) 0.5) (snd-display #__line__ ";src-fit-envelope 0.5: ~A" (src-duration (src-fit-envelope '(0 1 1 2) 0.5)))) (if (fneq (fm-parallel-component 100 100.0 (list 100.0 300.0 400.0) (list 1.0 0.5 0.25) () () #t) 0.69287) (snd-display #__line__ ";fm-parallel-component 100: ~A" (fm-parallel-component 100 100.0 (list 100.0 300.0 400.0) (list 1.0 0.5 0.25) () () #t))) (if (fneq (fm-parallel-component 500 100.0 (list 100.0 300.0 400.0) (list 1.0 0.5 0.25) () () #t) 0.17047) (snd-display #__line__ ";fm-parallel-component 500: ~A" (fm-parallel-component 500 100.0 (list 100.0 300.0 400.0) (list 1.0 0.5 0.25) () () #t))) (if (fneq (cheby-hka 3 0.25 (float-vector 0 0 0 0 1.0 1.0)) -0.0732421875) (snd-display #__line__ ";cheby-hka 0: ~A" (cheby-hka 3 0.25 (float-vector 0 0 0 0 1.0 1.0)))) (if (fneq (cheby-hka 2 0.25 (float-vector 0 0 0 0 1.0 1.0)) -0.234375) (snd-display #__line__ ";cheby-hka 1: ~A" (cheby-hka 2 0.25 (float-vector 0 0 0 0 1.0 1.0)))) (if (fneq (cheby-hka 1 0.25 (float-vector 0 0 0 0 1.0 1.0)) 1.025390625) (snd-display #__line__ ";cheby-hka 2: ~A" (cheby-hka 1 0.25 (float-vector 0 0 0 0 1.0 1.0)))) (if (fneq (cheby-hka 0 0.25 (float-vector 0 0 0 0 1.0 1.0)) 1.5234375) (snd-display #__line__ ";cheby-hka 3: ~A" (cheby-hka 0 0.25 (float-vector 0 0 0 0 1.0 1.0)))) (map-channel (lambda (y) (* .5 (oscil osc)))) (let ((vals (freq-peak 0 ind 8192))) (if (or (f4neq (car vals) 500.0) (fneq (cadr vals) 1.0)) (snd-display #__line__ ";src no-test: ~A" vals))) (for-each (lambda (sr dur) (src-sound sr 1.0 ind 0) (if (fneq (/ (framples ind 0) 10000.0) dur) (snd-display #__line__ ";src-sound ~A: ~A (~A)" sr (/ (framples ind 0) 10000.0) dur)) (let ((vals (freq-peak 0 ind 8192))) (if (or (f4neq (car vals) (* 500 sr)) (fneq (cadr vals) 1.0)) (snd-display #__line__ ";src ~A freq: ~A" sr vals))) (undo)) (list 2.0 0.5 5.0 0.2) (list 0.5 2.0 0.2 5.0)) (for-each (lambda (e f0 f1) (src-sound e 1.0 ind 0) (if (fneq (/ (framples ind 0) 10000.0) (src-duration e)) (snd-display #__line__ ";src-sound (env) ~A: ~A (~A)" e (/ (framples ind 0) 10000.0) (src-duration e))) (let ((vals (freq-peak 0 ind 256))) (if (f5neq (car vals) f0) (snd-display #__line__ ";src (env) 0 ~A freq: ~A" f0 vals))) (let ((vals (freq-peak (- (floor (* (src-duration e) 10000.0)) 256) ind 256))) (if (f5neq (car vals) f1) (snd-display #__line__ ";src (env) 1 ~A freq: ~A" f1 vals))) (undo)) (list (list 0 1 1 2) (list 0 2 1 1) (list 0 1 1 2 2 1) (list 0 .5 1 1) (list 0 .5 1 2)) (list 500.0 1000.0 500.0 250.0 250.0) (list 1000.0 500.0 500.0 500.0 1000.0)) (for-each (lambda (e f0 f1) (src-sound (make-env e :length (framples)) 1.0 ind 0) (if (fneq (/ (framples ind 0) 10000.0) (src-duration e)) (snd-display #__line__ ";src-sound (make-env) ~A: ~A (~A)" e (/ (framples ind 0) 10000.0) (src-duration e))) (let ((vals (freq-peak 0 ind 256))) (if (f5neq (car vals) f0) (snd-display #__line__ ";src (make-env) 0 ~A freq: ~A" f0 vals))) (let ((vals (freq-peak (- (floor (* (src-duration e) 10000.0)) 256) ind 256))) (if (f5neq (car vals) f1) (snd-display #__line__ ";src (env) 1 ~A freq: ~A" f1 vals))) (undo)) (list (list 0 1 1 2) (list 0 2 1 1) (list 0 1 1 2 2 1) (list 0 .5 1 1) (list 0 .5 1 2)) (list 500.0 1000.0 500.0 250.0 250.0) (list 1000.0 500.0 500.0 500.0 1000.0)) (for-each (lambda (sr dur) (src-channel sr) (if (fneq (/ (framples ind 0) 10000.0) dur) (snd-display #__line__ ";src-channel ~A: ~A (~A)" sr (/ (framples ind 0) 10000.0) dur)) (let ((vals (freq-peak 0 ind 8192))) (if (or (f4neq (car vals) (* 500 sr)) (fneq (cadr vals) 1.0)) (snd-display #__line__ ";src ~A freq: ~A" sr vals))) (undo)) (list 2.0 0.5 5.0 0.2) (list 0.5 2.0 0.2 5.0)) (for-each (lambda (e f0 f1) (src-channel e) (if (fneq (/ (framples ind 0) 10000.0) (src-duration e)) (snd-display #__line__ ";src-channel (env) ~A: ~A (~A)" e (/ (framples ind 0) 10000.0) (src-duration e))) (let ((vals (freq-peak 0 ind 256))) (if (f5neq (car vals) f0) (snd-display #__line__ ";src-channel (env f0) ~A: ~A" f0 vals))) (let ((vals (freq-peak (- (floor (* (src-duration e) 10000.0)) 256) ind 256))) (if (f5neq (car vals) f1) (snd-display #__line__ ";src-channel (env f1) ~A: ~A" f1 vals))) (undo)) (list (list 0 1 1 2) (list 0 2 1 1) (list 0 1 1 2 2 1) (list 0 .5 1 1) (list 0 .5 1 2)) (list 500.0 1000.0 500.0 250.0 250.0) (list 1000.0 500.0 500.0 500.0 1000.0)) (for-each (lambda (sr dur) (src-channel sr 1000 2500) (if (f4neq (framples ind 0) (+ 7500 (* dur 2500))) (snd-display #__line__ ";src-channel section: ~A ~A" (framples) (+ 7500 (* dur 2500)))) (let ((vals (freq-peak 0 ind 512))) (if (f5neq (car vals) 500.0) (snd-display #__line__ ";src-channel section 0 ~A freq: ~A" sr vals))) (let ((vals (freq-peak (- (+ 7500 (floor (* dur 2500))) 512) ind 512))) (if (f5neq (car vals) 500.0) (snd-display #__line__ ";src-channel section 8000 ~A freq: ~A" sr vals))) (let ((vals (freq-peak 1000 ind 512))) (if (f5neq (car vals) (* sr 500.0)) (snd-display #__line__ ";src-channel section ~A freq: ~A" sr vals))) (undo)) (list 2.0 0.5 5.0 0.2) (list 0.5 2.0 0.2 5.0)) (for-each (lambda (e) (src-channel (make-env e :length 2500) 1000 2500) (if (f3neq (framples ind 0) (+ 7500 (* (src-duration e) 2500))) (snd-display #__line__ ";src-channel section (make-env duration) ~A: ~A (~A ~A)" e (src-duration e) (framples) (+ 7500 (* (src-duration e) 2500)))) (let ((vals (freq-peak 0 ind 256))) (if (f5neq (car vals) 500.0) (snd-display #__line__ ";src-channel section (make-env e) ~A: ~A" e vals))) (let ((vals (freq-peak (- (+ 7500 (floor (* (src-duration e) 2500))) 256) ind 256))) (if (f5neq (car vals) 500.0) (snd-display #__line__ ";src-channel section (make-env e) ~A: ~A" e vals))) (undo)) (list (list 0 1 1 2) (list 0 2 1 1) (list 0 1 1 2 2 1) (list 0 .5 1 1) (list 0 .5 1 2))) (make-selection 1000 3500 ind 0) (for-each (lambda (sr dur) (src-selection sr) (if (f3neq (framples ind 0) (+ 7500 (* dur 2500))) (snd-display #__line__ ";src-selection section: ~A ~A" (framples) (+ 7500 (* dur 2500)))) (let ((vals (freq-peak 0 ind 512))) (if (f5neq (car vals) 500.0) (snd-display #__line__ ";src-selection section 0 ~A freq: ~A" sr vals))) (let ((vals (freq-peak (- (+ 7500 (floor (* dur 2500))) 512) ind 512))) (if (f5neq (car vals) 500.0) (snd-display #__line__ ";src-selection section 8000 ~A freq: ~A" sr vals))) (let ((vals (freq-peak 1000 ind 512))) (if (f5neq (car vals) (* sr 500.0)) (snd-display #__line__ ";src-selection section ~A freq: ~A" sr vals))) (undo)) (list 2.0 0.5 5.0 0.2) (list 0.5 2.0 0.2 5.0)) (for-each (lambda (e) (src-selection (make-env e :length 2500)) (if (f3neq (framples ind 0) (+ 7500 (* (src-duration e) 2500))) (snd-display #__line__ ";src-selection section (make-env duration) ~A: ~A (~A ~A)" e (src-duration e) (framples) (+ 7500 (* (src-duration e) 2500)))) (let ((vals (freq-peak 0 ind 256))) (if (f5neq (car vals) 500.0) (snd-display #__line__ ";src-selection section (make-env e) ~A: ~A" e vals))) (let ((vals (freq-peak (- (+ 7500 (floor (* (src-duration e) 2500))) 256) ind 256))) (if (f5neq (car vals) 500.0) (snd-display #__line__ ";src-selection section (make-env e) ~A: ~A" e vals))) (undo)) (list (list 0 1 1 2) (list 0 2 1 1) (list 0 1 1 2 2 1) (list 0 .5 1 1) (list 0 .5 1 2))) (for-each (lambda (e) (src-selection e) (if (f3neq (framples ind 0) (+ 7500 (* (src-duration e) 2500))) (snd-display #__line__ ";src-selection section (env duration) ~A: ~A (~A ~A)" e (src-duration e) (framples) (+ 7500 (* (src-duration e) 2500)))) (let ((vals (freq-peak 0 ind 256))) (if (f5neq (car vals) 500.0) (snd-display #__line__ ";src-selection section (env e) ~A: ~A" e vals))) (let ((vals (freq-peak (- (+ 7500 (floor (* (src-duration e) 2500))) 256) ind 256))) (if (f5neq (car vals) 500.0) (snd-display #__line__ ";src-selection section (env f1) ~A: ~A" e vals))) (undo)) (list (list 0 1 1 2) (list 0 2 1 1) (list 0 1 1 2 2 1) (list 0 .5 1 1) (list 0 .5 1 2))) (close-sound ind) ) (if (< *print-length* 12) (set! *print-length* 12)) (let ((ind (new-sound "hi.snd"))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (sample i ind) (* i .1))) (select-all ind) (set! (sample 10 ind) 1.0) (smooth-selection) (if (not (vequal (float-vector-subseq (channel->float-vector 0 11 ind) 0 9) (float-vector-subseq (smoother 0.0 1.0 10) 0 9))) (snd-display #__line__ ";smooth-selection: ~A ~A?" (channel->float-vector 0 11 ind) (smoother 0.0 1.0 10))) (revert-sound) (do ((i 0 (+ i 1))) ((= i 10)) (set! (sample i ind) (- 1.0 (* i .1)))) (select-all ind) (set! (sample 10 ind) 0.0) (smooth-selection) (if (not (vequal (float-vector-subseq (channel->float-vector 0 11 ind) 0 9) (float-vector-subseq (smoother 1.0 0.0 10) 0 9))) (snd-display #__line__ ";smooth-selection back: ~A ~A?" (channel->float-vector 0 11 ind) (smoother 1.0 0.0 10))) (close-sound ind)) (let ((ind (new-sound "hi.snd"))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (sample i ind) (* i .1))) (set! (sample 10 ind) 1.0) (smooth-sound 0 10 ind) (if (not (vequal (float-vector-subseq (channel->float-vector 0 11 ind) 0 9) (float-vector-subseq (smoother 0.0 1.0 10) 0 9))) (snd-display #__line__ ";smooth-sound: ~A ~A?" (channel->float-vector 0 11 ind) (smoother 0.0 1.0 10))) (revert-sound) (do ((i 0 (+ i 1))) ((= i 10)) (set! (sample i ind) (- 1.0 (* i .1)))) (set! (sample 10 ind) 0.0) (smooth-sound 0 10 ind) (if (not (vequal (float-vector-subseq (channel->float-vector 0 11 ind) 0 9) (float-vector-subseq (smoother 1.0 0.0 10) 0 9))) (snd-display #__line__ ";smooth-sound back: ~A ~A?" (channel->float-vector 0 11 ind) (smoother 1.0 0.0 10))) (close-sound ind)) (if (file-exists? "hi.snd") (delete-file "hi.snd")) (let* ((ind (open-sound "oboe.snd")) (len (framples ind))) (set! (cursor ind) 1200) (key (char->integer #\u) 4 ind) (key (char->integer #\1) 0 ind) (key (char->integer #\0) 0 ind) (key (char->integer #\0) 0 ind) (key (char->integer #\o) 4 ind) (if (not (= (framples ind) (+ 100 len))) (snd-display #__line__ ";C-o len: ~A? " (framples))) (if with-gui (let ((data (channel->float-vector 1200 100 ind))) (if (fneq (float-vector-peak data) 0.0) (snd-display #__line__ ";C-o: ~A?" (float-vector-peak data))))) (revert-sound ind) (set! (cursor ind) 1200) (key (char->integer #\u) 4 ind) (key (char->integer #\1) 0 ind) (key (char->integer #\0) 0 ind) (key (char->integer #\0) 0 ind) (key (char->integer #\z) 4 ind) (if (not (= (framples ind) len)) (snd-display #__line__ ";C-z len: ~A? " (framples))) (if with-gui (let ((data (channel->float-vector 1200 100 ind))) (if (fneq (float-vector-peak data) 0.0) (snd-display #__line__ ";C-z: ~A?" (float-vector-peak data))))) (set! (cursor ind) 0) (key (char->integer #\u) 4 ind) (key (char->integer #\3) 0 ind) (key (char->integer #\.) 0 ind) (key (char->integer #\0) 0 ind) (key (char->integer #\z) 4 ind) (if (fneq (maxamp ind 0) 0.0) (snd-display #__line__ ";C-z full: ~A" (maxamp))) (revert-sound ind) (set! (cursor ind) 1200) (key (char->integer #\u) 4 ind) (key (char->integer #\1) 0 ind) (key (char->integer #\.) 0 ind) (key (char->integer #\0) 0 ind) (key (char->integer #\o) 4 ind) (if (not (= (framples ind) (+ (srate ind) len))) (snd-display #__line__ ";C-o 1.0 len: ~A? " (framples))) (if with-gui (let ((data (channel->float-vector 1200 (srate ind) ind))) (if (fneq (float-vector-peak data) 0.0) (snd-display #__line__ ";C-o 1.0: ~A?" (float-vector-peak data))))) (revert-sound ind) (set! (cursor ind) 1200) (key (char->integer #\u) 4 ind) (key (char->integer #\1) 0 ind) (key (char->integer #\.) 0 ind) (key (char->integer #\0) 0 ind) (key (char->integer #\z) 4 ind) (if (not (= (framples ind) len)) (snd-display #__line__ ";C-z 1.0 len: ~A? " (framples))) (if with-gui (let ((data (channel->float-vector 1200 (srate ind) ind))) (if (fneq (float-vector-peak data) 0.0) (snd-display #__line__ ";C-z 1.0: ~A?" (float-vector-peak data))))) (close-sound ind)) (let ((ind (open-sound "2.snd"))) (set! (sync ind) 1) (key (char->integer #\>) 4) (key (char->integer #\space) 4) (key (char->integer #\<) 4) (if (or (not (selection-member? ind 0)) (not (selection-member? ind 1)) (not (= (selection-position ind 0) 0)) (not (= (selection-position ind 1) 0)) (not (= (selection-framples ind 0) (framples ind 0))) (not (= (selection-framples ind 1) (framples ind 1)))) (snd-display #__line__ ";sync selection via <-: ~A ~A ~A ~A ~A ~A" (selection-member? ind 0) (selection-member? ind 1) (selection-position ind 0) (selection-position ind 1) (selection-framples ind 0) (selection-framples ind 1))) (key (char->integer #\space) 4) (key (char->integer #\>) 4) (if (or (not (selection-member? ind 0)) (not (selection-member? ind 1)) (not (= (selection-position ind 0) 0)) (not (= (selection-position ind 1) 0)) (not (= (selection-framples ind 0) (framples ind 0))) (not (= (selection-framples ind 1) (framples ind 1)))) (snd-display #__line__ ";sync selection via ->: ~A ~A ~A ~A ~A ~A" (selection-member? ind 0) (selection-member? ind 1) (selection-position ind 0) (selection-position ind 1) (selection-framples ind 0) (selection-framples ind 1))) (set! (cursor ind 1) 0) (set! (cursor ind 0) 1000) (if (not (= (cursor ind 1) 1000)) (snd-display #__line__ ";syncd cursors: ~A ~A" (cursor ind 0) (cursor ind 1))) (close-sound ind)) (let ((ind (open-sound "2a.snd"))) (let ((reg (make-region 100 200 ind #t))) (if (not (= (region-chans reg) 2)) (snd-display #__line__ ";make-region #t for chan in 2a.snd: ~A chans" (region-chans reg))) (mix-region reg 1000) (if (or (not (= (edit-position ind 0) 1)) (not (= (edit-position ind 1) 0))) (snd-display #__line__ ";mix-region default mix: ~A ~A" (edit-position ind 0) (edit-position ind 1))) (undo) (set! (sync ind) 1) (mix-region reg 1000) (if (or (not (= (edit-position ind 0) 1)) (not (= (edit-position ind 1) 1))) (snd-display #__line__ ";mix-region sync mix: ~A ~A" (edit-position ind 0) (edit-position ind 1))) (undo) (set! (sync ind) 0) (mix-region reg 1000 ind 1) (if (or (not (= (edit-position ind 0) 0)) (not (= (edit-position ind 1) 1))) (snd-display #__line__ ";mix-region mix -> chan 1: ~A ~A" (edit-position ind 0) (edit-position ind 1))) (revert-sound ind)) (set! (selection-member? #t #t) #f) (set! (selection-member? ind 0) #t) (set! (selection-member? ind 1) #t) (set! (selection-position ind 0) 1000) (set! (selection-position ind 1) 1000) (set! (selection-framples ind 0) 100) (set! (selection-framples ind 1) 100) (if (not (= (selection-chans) 2)) (snd-display #__line__ ";laboriously make 2 chan selection: ~A" (selection-chans))) (mix-selection 100) (if (or (not (= (edit-position ind 0) 1)) (not (= (edit-position ind 1) 0))) (snd-display #__line__ ";mix-selection default mix: ~A ~A" (edit-position ind 0) (edit-position ind 1))) (undo) (set! (sync ind) 1) (mix-selection 100) (if (or (not (= (edit-position ind 0) 1)) (not (= (edit-position ind 1) 1))) (snd-display #__line__ ";mix-selection sync mix: ~A ~A" (edit-position ind 0) (edit-position ind 1))) (undo) (set! (sync ind) 0) (mix-selection 100 ind 1) (if (or (not (= (edit-position ind 0) 0)) (not (= (edit-position ind 1) 1))) (snd-display #__line__ ";mix-selection mix -> chan 1: ~A ~A" (edit-position ind 0) (edit-position ind 1))) (close-sound ind)) (let ((ind (open-sound "oboe.snd"))) (test-selection ind 1200 100 2.0) (test-selection ind 600 1200 2.0) (test-selection ind 0 100 2.0) (test-selection ind 22500 (- 50827 22500) 0.5) (test-selection ind 0 50828 0.5) (test-selection-to ind 1200 100 1.0) (test-selection-to ind 600 1200 0.1) (test-selection-to ind 0 100 0.5) (test-selection-to ind 22500 (- 50827 22500) 2.0) (test-selection-to ind 0 50828 0.5) (revert-sound ind) (make-selection 1200 1200) (if (not (selection?)) (snd-display #__line__ ";no selection from 1 samp region?")) (if (not (= (selection-framples) 1)) (snd-display #__line__ ";1 samp selection: ~A samps?" (selection-framples))) (scale-selection-to 1.0) (if (fneq (sample 1200 ind 0) 1.0) (snd-display #__line__ ";scale 1 samp selection: ~A?" (sample 1200 ind 0))) (revert-sound ind) (let ((id (make-region 500 1000))) (src-selection .5) (if (> (abs (- (region-framples id) 500)) 1) (snd-display #__line__ ";region-framples after src-selection: ~A?" (region-framples id))) (let ((reg-mix-id (car (mix-region id 1500 ind 0)))) (if (not (= (mix-length reg-mix-id) (region-framples id))) (snd-display #__line__ ";mix-region: ~A != ~A?" (region-framples id) (mix-length reg-mix-id))) (if (not (equal? (mix-home reg-mix-id) (list ind 0 #f 0))) (snd-display #__line__ ";mix-region mix-home ~A (~A 0 #f 0)?" (mix-home reg-mix-id) ind)) (let ((sel-mix-id (car (mix-selection 2500 ind 0)))) (if (not (= (selection-framples) (mix-length sel-mix-id))) (snd-display #__line__ ";mix-selection framples: ~A != ~A?" (selection-framples) (mix-length sel-mix-id))) (if (> (abs (- (* 2 (mix-length reg-mix-id)) (mix-length sel-mix-id))) 3) (snd-display #__line__ ";mix selection and region: ~A ~A (~A ~A)?" (mix-length reg-mix-id) (mix-length sel-mix-id) (region-framples id) (selection-framples))) (if (not (equal? (mix-home sel-mix-id) (list ind 0 #f 0))) (snd-display #__line__ ";mix-selection mix-home: ~A (~A 0 #f 0)?" (mix-home sel-mix-id) ind)) (insert-selection 3000 ind 0) (insert-selection 3000 ind) (mix-selection 3000 ind) (delete-selection) (revert-sound ind)))) (close-sound ind)) (if (file-exists? "storm.snd") (let ((ind (open-sound "storm.snd"))) (set! *sinc-width* 10) (time (src-sound 1.3)) (time (env-sound '(0 0 1 1 2 0))) (time (filter-sound '(0 1 .2 0 .5 1 1 0) 20)) ; FIR direct form (time (filter-sound '(0 0 .1 0 .11 1 .12 0 1 0) 2048)) ; convolution (revert-sound ind) (let ((reg (make-region 0 123000 ind 0))) ; force copy branch to execute (region->float-vector reg 0 10 0 (make-float-vector 10))) (ramp-channel 0.0 1.0) (ramp-channel 0.0 1.0) (ramp-channel 0.0 1.0) (ramp-channel 0.0 1.0) ; force env (close-sound ind))) (if (file-exists? "1a.snd") (let ((ind1 (open-sound "1a.snd"))) (time (rubber-sound 1.25)) (close-sound ind1))) (gc) (let* ((oboe (open-sound "oboe.snd")) (a4 (open-sound "4.aiff")) (sr (srate oboe)) ;(fr (framples oboe 0)) ;(typ (header-type oboe)) ;(frm (sample-type oboe)) ;(loc (data-location oboe)) ;(com (comment oboe)) ) (save-sound-as "test.aif" oboe :header-type mus-aifc) (let ((oboe-aif (open-sound "test.aif"))) (if (not (= (header-type oboe-aif) mus-aifc)) (snd-display #__line__ ";oboe-aif header: ~A?" (mus-header-type-name (header-type oboe-aif)))) (set! (srate oboe-aif) (* sr 2.0)) (if (fneq (* sr 2.0) (srate oboe-aif)) (snd-display #__line__ ";set! srate: ~A ~A" (* sr 2.0) (srate oboe-aif))) (set! (header-type oboe-aif) mus-next) (if (not (= (header-type oboe-aif) mus-next)) (snd-display #__line__ ";set! header: ~A?" (mus-header-type-name (header-type oboe-aif)))) (set! (data-location oboe-aif) 28) (if (not (= (data-location oboe-aif) 28)) (snd-display #__line__ ";set! data-location: ~A?" (data-location oboe-aif))) (set! (sample-type oboe-aif) mus-mulaw) (if (not (= (sample-type oboe-aif) mus-mulaw)) (snd-display #__line__ ";set! format: ~A?" (mus-sample-type-name (sample-type oboe-aif)))) (save-sound-as "test.aif" oboe-aif 22050 mus-bshort mus-aifc 0) (close-sound oboe-aif) (delete-file "test.aif") (set! (selected-sound) a4) (if (not (equal? (selected-sound) a4)) (snd-display #__line__ ";set! selected-sound: ~A ~A?" (selected-sound) a4)) (set! (selected-channel) 2) (if (not (= (selected-channel a4) 2)) (snd-display #__line__ ";set! selected-channel: ~A?" (selected-channel a4))) (set! (selected-channel a4) 3) (if (not (= (selected-channel a4) 3)) (snd-display #__line__ ";set! selected-channel a4: ~A?" (selected-channel a4))) (close-sound a4) (close-sound oboe))) (let ((v1 (envelope-interp 1.0 '(0 0 2.0 1.0))) (v2 (envelope-interp 1.0 '(0 0.0 1 1.0 2 0.0))) (v3 (envelope-interp 2.0 '(0 0.0 1 1.0))) (v4 (envelope-interp 0.0 '(1 .5 2 0)))) (if (fneq v1 0.5) (snd-display #__line__ ";envelope-interp(1): ~F (0.5)?" v1)) (if (fneq v2 1.0) (snd-display #__line__ ";envelope-interp(2): ~F (1.0)?" v2)) (if (fneq v3 1.0) (snd-display #__line__ ";envelope-interp(3): ~F (1.0)?" v3)) (if (fneq v4 0.5) (snd-display #__line__ ";envelope-interp(4): ~F (0.5)?" v4))) (let ((v1 (envelope-interp 0.0 '(-1 0 0 1 1 -1))) (v2 (envelope-interp -0.5 '(-1 0 0 1 1 -1))) (v3 (envelope-interp -0.5 '(-1 -1 0 1 1 -1))) (v4 (envelope-interp -0.5 '(-1 -1 1 1))) (v5 (envelope-interp -1.5 '(-1 -1 1 1))) (v6 (envelope-interp 1.5 '(-1 -1 1 1)))) (if (fneq v1 1.0) (snd-display #__line__ ";envelope-interp(1a): ~A" v1)) (if (fneq v2 0.5) (snd-display #__line__ ";envelope-interp(2a): ~A" v2)) (if (fneq v3 0.0) (snd-display #__line__ ";envelope-interp(3a): ~A" v3)) (if (fneq v4 -0.5) (snd-display #__line__ ";envelope-interp(4a): ~A" v4)) (if (fneq v5 -1.0) (snd-display #__line__ ";envelope-interp(5a): ~A" v5)) (if (fneq v6 1.0) (snd-display #__line__ ";envelope-interp(6a): ~A" v6))) (let ((v1 (multiply-envelopes '(0.0 0.0 2.0 0.5) '(0.0 0.0 1.0 2.0 2.0 1.0))) (v2 (window-envelope 1.0 3.0 '(0.0 0.0 5.0 1.0)))) (if (not (feql v1 (list 0.0 0.0 0.5 0.5 1.0 0.5))) (snd-display #__line__ ";multiply-envelopes: ~A?" v1)) (if (not (feql v2 (list 1.0 0.2 3.0 0.6))) (snd-display #__line__ ";window-envelope: ~A?" v2))) (if (fneq (envelope-interp .1 '(0 0 1 1)) 0.1) (snd-display #__line__ ";envelope-interp .1 -> ~A?" (envelope-interp .1 '(0 0 1 1)))) (if (fneq (envelope-interp .1 '(0 0 1 1) 32.0) 0.01336172) (snd-display #__line__ ";envelope-interp .013 -> ~A?" (envelope-interp .1 '(0 0 1 1) 32.0))) (if (fneq (envelope-interp .1 '(0 0 1 1) .012) 0.36177473) (snd-display #__line__ ";envelope-interp .361 -> ~A?" (envelope-interp .1 '(0 0 1 1) .012))) (if (fneq (envelope-interp .3 '(0 0 .5 1 1 0)) .6) (snd-display #__line__ ";envelope-interp .3 '(0 0 .5 1 1 0)) -> ~A" (envelope-interp .3 '(0 0 .5 1 1 0)))) (if (fneq (envelope-interp .9 '(0 0 1 1)) 0.9) (snd-display #__line__ ";envelope-interp .9 -> ~A?" (envelope-interp .9 '(0 0 1 1)))) (if (fneq (envelope-interp .9 '(0 0 1 1) 32.0) 0.698) (snd-display #__line__ ";envelope-interp .698 -> ~A?" (envelope-interp .9 '(0 0 1 1) 32.0))) (if (fneq (envelope-interp .9 '(0 0 1 1) .012) 0.993) (snd-display #__line__ ";envelope-interp .993 -> ~A?" (envelope-interp .9 '(0 0 1 1) .012))) (if (fneq (envelope-interp 1.1 '(0 0 1 0 2 1)) 0.1) (snd-display #__line__ ";envelope-interp .1 (2) -> ~A?" (envelope-interp 1.1 '(0 0 1 0 2 1)))) (if (fneq (envelope-interp 1.1 '(0 0 1 0 2 1) 32.0) 0.01336172) (snd-display #__line__ ";envelope-interp .013 (2) -> ~A?" (envelope-interp 1.1 '(0 0 1 0 2 1) 32.0))) (if (fneq (envelope-interp 1.1 '(0 0 1 0 2 1) .012) 0.36177473) (snd-display #__line__ ";envelope-interp .361 (2) -> ~A?" (envelope-interp 1.1 '(0 0 1 0 2 1) .012))) (if (fneq (envelope-interp 1.9 '(0 0 1 0 2 1)) 0.9) (snd-display #__line__ ";envelope-interp .9 (2) -> ~A?" (envelope-interp 1.9 '(0 0 1 0 2 1)))) (if (fneq (envelope-interp 1.9 '(0 0 1 0 2 1) 32.0) 0.698) (snd-display #__line__ ";envelope-interp .698 (2) -> ~A?" (envelope-interp 1.9 '(0 0 1 0 2 1) 32.0))) (if (fneq (envelope-interp 1.9 '(0 0 1 0 2 1) .012) 0.993) (snd-display #__line__ ";envelope-interp .993 (2) -> ~A?" (envelope-interp 1.9 '(0 0 1 0 2 1) .012))) (if (fneq (envelope-interp 1.1 '(0 0 0.5 1 1 0 2 1)) 0.1) (snd-display #__line__ ";envelope-interp .1 (3) -> ~A?" (envelope-interp 1.1 '(0 0 0.5 1 1 0 2 1)))) (if (fneq (envelope-interp 1.1 '(0 0 0.5 1 1 0 2 1) 32.0) 0.01336172) (snd-display #__line__ ";envelope-interp .013 (3) -> ~A?" (envelope-interp 1.1 '(0 0 0.5 1 1 0 2 1) 32.0))) (if (fneq (envelope-interp 1.1 '(0 0 0.5 1 1 0 2 1) .012) 0.36177473) (snd-display #__line__ ";envelope-interp .361 (3) -> ~A?" (envelope-interp 1.1 '(0 0 0.5 1 1 0 2 1) .012))) (if (fneq (envelope-interp 1.9 '(0 0 0.5 1 1 0 2 1)) 0.9) (snd-display #__line__ ";envelope-interp .9 (3) -> ~A?" (envelope-interp 1.9 '(0 0 0.5 1 1 0 2 1)))) (if (fneq (envelope-interp 1.9 '(0 0 0.5 1 1 0 2 1) 32.0) 0.698) (snd-display #__line__ ";envelope-interp .698 (3) -> ~A?" (envelope-interp 1.9 '(0 0 0.5 1 1 0 2 1) 32.0))) (if (fneq (envelope-interp 1.9 '(0 0 0.5 1 1 0 2 1) .012) 0.993) (snd-display #__line__ ";envelope-interp .993 (3) -> ~A?" (envelope-interp 1.9 '(0 0 0.5 1 1 0 2 1) .012))) (if (not (feql (window-envelope 1.0 3.0 '(0.0 0.0 5.0 1.0)) (list 1.0 0.2 3.0 0.6))) (snd-display #__line__ ";window-envelope: ~A?" (window-envelope 1.0 3.0 '(0.0 0.0 5.0 1.0)))) (if (not (feql (multiply-envelopes '(0 0 1 1) '(0 0 1 1 2 0)) (list 0 0 0.5 0.5 1 0))) (snd-display #__line__ ";multiply-envelopes: ~A?" (multiply-envelopes '(0 0 1 1) '(0 0 1 1 2 0)))) (if (fneq (max-envelope '(0 0 1 1 2 3 4 0)) 3.0) (snd-display #__line__ ";max-envelope: ~A?" (max-envelope '(0 0 1 1 2 3 4 0)))) (if (fneq (max-envelope '(0 1)) 1.0) (snd-display #__line__ ";1 max-envelope: ~A?" (max-envelope '(0 1)))) (if (fneq (max-envelope '(0 1 1 1 2 2)) 2.0) (snd-display #__line__ ";2 max-envelope: ~A?" (max-envelope '(0 1 1 1 2 2)))) (if (fneq (max-envelope '(0 -1 1 -2)) -1.0) (snd-display #__line__ ";3 max-envelope: ~A?" (max-envelope '(0 -1 1 -2)))) (if (fneq (max-envelope '(0 -2 1 -1)) -1.0) (snd-display #__line__ ";4 max-envelope: ~A?" (max-envelope '(0 -2 1 -1)))) (if (fneq (min-envelope '(0 0 1 1 2 3 4 0)) 0.0) (snd-display #__line__ ";min-envelope: ~A?" (min-envelope '(0 0 1 1 2 3 4 0)))) (if (fneq (min-envelope '(0 1)) 1.0) (snd-display #__line__ ";1 min-envelope: ~A?" (min-envelope '(0 1)))) (if (fneq (min-envelope '(0 1 1 1 2 2)) 1.0) (snd-display #__line__ ";2 min-envelope: ~A?" (min-envelope '(0 1 1 1 2 2)))) (if (fneq (min-envelope '(0 -1 1 -2)) -2.0) (snd-display #__line__ ";3 min-envelope: ~A?" (min-envelope '(0 -1 1 -2)))) (if (fneq (min-envelope '(0 -2 1 -1)) -2.0) (snd-display #__line__ ";4 min-envelope: ~A?" (min-envelope '(0 -2 1 -1)))) (if (fneq (integrate-envelope '(0 0 1 1)) 0.5) (snd-display #__line__ ";integrate-envelope: ~A?" (integrate-envelope '(0 0 1 1)))) (if (fneq (integrate-envelope '(0 1 1 1)) 1.0) (snd-display #__line__ ";integrate-envelope: ~A?" (integrate-envelope '(0 1 1 1)))) (if (fneq (integrate-envelope '(0 0 1 1 2 .5)) 1.25) (snd-display #__line__ ";integrate-envelope: ~A?" (integrate-envelope '(0 0 1 1 2 .5)))) (if (not (feql (stretch-envelope '(0 0 1 1) .1 .2) (list 0 0 0.2 0.1 1.0 1))) (snd-display #__line__ ";stretch-envelope att: ~A?" (stretch-envelope '(0 0 1 1) .1 .2))) (if (not (feql (stretch-envelope '(0 0 1 1 2 0) .1 .2 1.5 1.6) (list 0 0 0.2 0.1 1.1 1 1.6 0.5 2.0 0))) (snd-display #__line__ ";stretch-envelope dec: ~A?" (stretch-envelope '(0 0 1 1 2 0) .1 .2 1.5 1.6))) (if (not (feql (add-envelopes '(0 0 1 1 2 0) '(0 0 1 1)) '(0 0 0.5 1.5 1 1))) (snd-display #__line__ ";add-envelopes: ~A" (add-envelopes '(0 0 1 1 2 0) '(0 0 1 1)))) (if (not (feql (scale-envelope '(0 0 1 1) 2) '(0 0 1 2))) (snd-display #__line__ ";scale-envelope: ~A" (scale-envelope '(0 0 1 1) 2))) (if (not (feql (scale-envelope '(0 0 1 1) 2 1) '(0 1 1 3))) (snd-display #__line__ ";scale-envelope off: ~A" (scale-envelope '(0 0 1 1) 2 1))) (if (not (feql (reverse-envelope '(0 0 1 1)) '(0 1 1 0))) (snd-display #__line__ ";reverse-envelope ramp: ~A" (reverse-envelope '(0 0 1 1)))) (if (not (feql (reverse-envelope '(0 0 .5 1 2 0)) '(0 0 1.5 1 2 0))) (snd-display #__line__ ";reverse-envelope ramp 2: ~A" (reverse-envelope '(0 0 .5 1 2 0)))) (if (not (feql (reverse-envelope '(0 0 .5 1 2 1)) '(0 1 1.5 1 2 0))) (snd-display #__line__ ";reverse-envelope ramp 2: ~A" (reverse-envelope '(0 0 .5 1 2 1)))) (if (not (feql (concatenate-envelopes '(0 0 1 1) '(0 1 1 0)) '(0.0 0 1.0 1 2.0 0))) (snd-display #__line__ ";concatenate-envelopes: ~A" (concatenate-envelopes '(0 0 1 1) '(0 1 1 0)))) (if (not (feql (concatenate-envelopes '(0 0 1 1.5) '(0 1 1 0)) '(0.0 0 1.0 1.5 1.01 1 2.01 0))) (snd-display #__line__ ";concatenate-envelopes: ~A" (concatenate-envelopes '(0 0 1 1.5) '(0 1 1 0)))) (if (not (feql (repeat-envelope '(0 0 1 100) 2) '(0 0 1 100 1.01 0 2.01 100))) (snd-display #__line__ ";repeat-envelope 0: ~A" (repeat-envelope '(0 0 1 100) 2))) (if (not (feql (repeat-envelope '(0 0 1.5 1 2 0) 2) '(0 0 1.5 1 2.0 0 3.5 1 4.0 0))) (snd-display #__line__ ";repeat-envelope 1: ~A" (repeat-envelope '(0 0 1.5 1 2 0) 2))) (if (not (feql (repeat-envelope '(0 0 1.5 1 2 0) 2 #f #t) '(0.0 0 0.75 1 1.0 0 1.75 1 2.0 0))) (snd-display #__line__ ";repeat-envelope 2: ~A" (repeat-envelope '(0 0 1.5 1 2 0) 2 #f #t))) (if (not (feql (repeat-envelope '(0 0 1.5 1 2 0) 2 #t) '(0 0 1.5 1 2.0 0 2.5 1 4.0 0))) (snd-display #__line__ ";repeat-envelope 3: ~A" (repeat-envelope '(0 0 1.5 1 2 0) 2 #t))) (if (not (feql (repeat-envelope '(0 0 1.5 1 2 0) 3) '(0 0 1.5 1 2.0 0 3.5 1 4.0 0 5.5 1 6.0 0))) (snd-display #__line__ ";repeat-envelope 4: ~A" (repeat-envelope '(0 0 1.5 1 2 0) 3))) (if (not (feql (normalize-envelope '(0 0 1 1.5 2.0 1.0)) '(0 0.0 1 1.0 2.0 0.667))) (snd-display #__line__ ";normalize-envelope: ~A" (normalize-envelope '(0 0 1 1.5 2.0 1.0)))) (if (not (feql (normalize-envelope '(0 0 1 .5 2 -.8)) '(0 0.0 1 0.625 2 -1.0))) (snd-display #__line__ ";normalize-envelope: ~A" (normalize-envelope '(0 0 1 .5 2 -.8)))) (let ((val (envelope-exp '(0 0 1 1) 2.0 10))) (if (not (feql val '(0.000 0.000 0.100 0.010 0.200 0.040 0.300 0.090 0.400 0.160 0.500 0.250 0.600 0.360 0.700 0.490 0.800 0.640 0.900 0.810 1.000 1.000))) (snd-display #__line__ ";envelope-exp: ~A" val)) (set! val (envelope-exp '(0 0 1 1 2 0) 1.0 10)) (if (not (feql val '(0.000 0.000 0.200 0.200 0.400 0.400 0.600 0.600 0.800 0.800 1.000 1.000 1.200 0.800 1.400 0.600 1.600 0.400 1.800 0.200 2.000 0.000))) (snd-display #__line__ ";envelope exp 2: ~A" val))) (let ((ind (new-sound "fmv.snd")) (v (make-float-vector 20 1.0))) (float-vector->channel v) (if (selection?) (set! (selection-member? #t) #f)) (make-selection 5 9 ind 0) (scale-selection-to 0.5) (insert-selection 15 ind) (if (not (= (framples ind) 25)) (snd-display #__line__ ";insert-selection 5: ~A" (framples ind))) (if (not (vequal (channel->float-vector 0 25) (float-vector 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 1.0 1.0 1.0 1.0 1.0))) (snd-display #__line__ ";insert-selection: ~A" (channel->float-vector 0 25))) (mix-selection 1 ind 0) ; this is being confused by clipping settings (if (not (vequal (channel->float-vector 0 10 ind 0) (float-vector 1.000 1.500 1.500 1.500 1.500 1.000 0.500 0.500 0.500 0.500))) (snd-display #__line__ ";mix-selection vals: ~A" (channel->float-vector 0 10 ind 0))) (close-sound ind)) (let ((ind (new-sound "fmv.snd")) (v (make-float-vector 2000)) (old-size *transform-size*) (old-type *transform-type*) (old-norm *transform-normalization*) (old-grf *transform-graph-type*) (e (make-env (list 0.0 0.0 1.0 (* 2000 0.2 pi)) :length 2001))) (fill-float-vector v (sin (env e))) (float-vector->channel v 0 2000 ind 0) (set! *transform-size* 256) (set! *transform-type* fourier-transform) (set! *transform-normalization* normalize-by-channel) (set! *transform-graph-type* graph-once) (set! *zero-pad* 0) (set! (transform-graph?) #t) (make-selection 0 200) (set! *show-selection-transform* #t) (set! (selection-framples) 300) (update-transform-graph) (let* ((data (transform->float-vector)) (peak (float-vector-peak data)) (val (transform-sample 0))) (if (= peak 0.0) (snd-display #__line__ ";transform selection peak: ~A" peak)) (if (fneq val (data 0)) (snd-display #__line__ ";transform-sample: ~A, data: ~A" val (data 0))) (if (and (>= (length data) 64) (> (* .5 peak) (data 51))) (snd-display #__line__ ";transform selection at 51: ~A, peak: ~A" (data 51) peak))) (for-each (lambda (pad) (set! *zero-pad* pad) (update-transform-graph) (let* ((data (transform->float-vector)) (peak (float-vector-peak data)) (pval (data (floor (* .1 (length data)))))) (if (> (* .5 peak) pval) (snd-display #__line__ ";transform selection padded ~D: ~A, peak: ~A" pad pval peak)))) (list 1 0 3 31)) (set! *zero-pad* 100000) (if (> *zero-pad* 1000) (snd-display #__line__ ";zero-pad: ~A" *zero-pad*)) (set! *zero-pad* 0) (set! *transform-size* old-size) (set! *transform-type* (if (integer? old-type) (integer->transform old-type) old-type)) (set! *transform-normalization* old-norm) (set! *transform-graph-type* old-grf) (close-sound ind)) (let ((ind (open-sound "storm.snd")) (maxes (float-vector 0.8387 0.5169 0.3318 0.2564 0.1982 0.1532))) (do ((i 0 (+ i 1))) ((= i 5)) (if (fneq (maxamp) (maxes i)) (snd-display #__line__ ";enving storm ~D: ~A ~A" i (maxes i) (maxamp))) (env-sound '(0 0 1 1 2 0)) (if (fneq (maxamp) (maxes (+ i 1))) (snd-display #__line__ ";enving storm ~D: ~A ~A" (+ i 1) (maxes (+ i 1)) (maxamp)))) (close-sound ind)) )) ;; -------------------------------------------------------------------------------- ;; length as generic function: ;; string-length vector-length hash-table-size length ;; framples mus-length framples mix-length region-framples (let ((snd (open-sound "oboe.snd")) (v (float-vector .1 .2 .3)) (vc (vector .1 .2 .3 .4)) (lst (list 1 2 3 4 5)) (hsh (make-hash-table 100)) (sd (make-float-vector (list 1 10) 0.0)) (str "123456")) (let ((mxv (mix-float-vector v 1000)) (reg (make-region 0 100)) (dly (make-delay 32)) (ply (make-player snd 0)) ) (if (not (= (length snd) 50828)) (snd-display #__line__ ";length of sound: ~A" (length snd))) (if (not (= (length v) 3)) (snd-display #__line__ ";length of float-vector: ~A" (length v))) (if (not (= (length vc) 4)) (snd-display #__line__ ";length of vector: ~A" (length vc))) (if (not (= (length lst) 5)) (snd-display #__line__ ";length of list: ~A" (length lst))) (if (not (= (length str) 6)) (snd-display #__line__ ";length of string: ~A" (length str))) (if (not (= (framples sd) 10)) (snd-display #__line__ ";length of vector2: ~A" (framples sd))) (if (< (length hsh) 100) (snd-display #__line__ ";length of hash-table: ~A" (length hsh))) (if (not (= (length mxv) 3)) (snd-display #__line__ ";length of mix: ~A" (length mxv))) (if (not (= (length reg) 101)) (snd-display #__line__ ";length of region: ~A" (length reg))) (if (not (= (length dly) 32)) (snd-display #__line__ ";length of delay: ~A" (length dly))) (if (not (= (length ply) 50828)) (snd-display #__line__ ";length of player: ~A" (length ply))) ) (close-sound snd)) ;; srate as generic: mus-sound-srate region-srate srate (let ((snd (open-sound "oboe.snd")) (str "oboe.snd")) (let ((reg (make-region 0 100)) (ply (make-player snd 0)) ) (if (not (= (srate snd) 22050)) (snd-display #__line__ ";srate of sound: ~A" (srate snd))) (if (not (= (srate str) 22050)) (snd-display #__line__ ";srate of string: ~A" (srate str))) (if (not (= (srate reg) 22050)) (snd-display #__line__ ";srate of region: ~A" (srate reg))) (if (not (= (srate ply) 22050)) (snd-display #__line__ ";srate of player: ~A" (srate ply))) ) (close-sound snd)) ;; channels as generic: mus-sound-chans region-chans chans mus-channels mix/etc (let ((snd (open-sound "oboe.snd")) (v (float-vector .1 .2 .3)) (sd (make-float-vector (list 2 10) 0.0)) (str "oboe.snd")) (let ((mxv (mix-float-vector v 1000)) (reg (make-region 0 100)) (ply (make-player snd 0)) ) (if (not (= (channels snd) 1)) (snd-display #__line__ ";channels of sound: ~A" (channels snd))) (if (not (= (channels v) 1)) (snd-display #__line__ ";channels of float-vector: ~A" (channels v))) (if (not (= (channels str) 1)) (snd-display #__line__ ";channels of string: ~A" (channels str))) (if (not (= (channels sd) 2)) (snd-display #__line__ ";channels of vector2: ~A" (channels sd))) (if (not (= (channels mxv) 1)) (snd-display #__line__ ";channels of mix: ~A" (channels mxv))) (if (not (= (channels reg) 1)) (snd-display #__line__ ";channels of region: ~A" (channels reg))) (if (not (= (channels ply) 1)) (snd-display #__line__ ";channels of player: ~A" (channels ply))) ) (close-sound snd)) ;; framples as generic (let ((snd (open-sound "oboe.snd")) (v (float-vector .1 .2 .3)) (sd (make-float-vector (list 1 10) 0.0)) (str "oboe.snd")) (let ((mxv (mix-float-vector v 1000)) (reg (make-region 0 100)) (dly (make-delay 32)) (ply (make-player snd 0)) ) (if (not (= (framples snd) 50828)) (snd-display #__line__ ";framples of sound: ~A" (framples snd))) (if (not (= (framples v) 3)) (snd-display #__line__ ";framples of float-vector: ~A" (framples v))) (if (not (= (framples str) 50828)) (snd-display #__line__ ";framples of string: ~A" (framples str))) (if (not (= (framples sd) 10)) (snd-display #__line__ ";framples of vector2: ~A" (framples sd))) (if (not (= (framples mxv) 3)) (snd-display #__line__ ";framples of mix: ~A" (framples mxv))) (if (not (= (framples reg) 101)) (snd-display #__line__ ";framples of region: ~A" (framples reg))) (if (not (= (framples dly) 32)) (snd-display #__line__ ";framples of delay: ~A" (framples dly))) (if (not (= (framples ply) 50828)) (snd-display #__line__ ";framples of player: ~A" (framples ply))) ) (close-sound snd)) ;; file-name as generic (let ((snd (open-sound "oboe.snd")) (str "oboe.snd") (frm (make-file->sample "oboe.snd")) (prt (open-output-file "tst.dat"))) (let ((mxv (car (mix "pistol.snd" 1000))) (reg (make-region 0 100)) ) (if (not (string=? (file-name snd) (string-append (getcwd) "/oboe.snd"))) (snd-display #__line__ ";file-name of sound: ~A" (file-name snd))) (if (not (string=? (file-name str) (string-append (getcwd) "/oboe.snd"))) (snd-display #__line__ ";file-name of string: ~A" (file-name str))) (if (not (string=? (file-name frm) "oboe.snd")) (snd-display #__line__ ";file-name of file->sample: ~A" (file-name frm))) (if (not (string=? (file-name prt) "tst.dat")) (snd-display #__line__ ";file-name of output port: ~A" (file-name prt))) (if (not (string=? (file-name mxv) (string-append (getcwd) "/pistol.snd"))) (snd-display #__line__ ";file-name of mix: ~A" (file-name mxv))) (if (not (string=? (file-name reg) "oboe.snd")) (snd-display #__line__ ";file-name of region: ~A" (file-name reg))) ) (close-output-port prt) (mus-close frm) (close-sound snd)) ;; sync as generic: mix-sync mark-sync sync (let ((snd (open-sound "oboe.snd"))) (let ((mrk (add-mark 123)) (mx (mix-float-vector (float-vector .1 .2 .3))) ) (if (not (= (sync snd) 0)) (snd-display #__line__ ";sync of sound (0): ~A" (sync snd))) (if (not (= (sync mrk) 0)) (snd-display #__line__ ";sync of mark (0): ~A" (sync mrk))) (if (not (= (sync mx) 0)) (snd-display #__line__ ";sync of mx (0): ~A" (sync mx))) (set! (sync snd) 12) (set! (sync mrk) 24) (set! (sync mx) 36) (if (not (= (sync snd) 12)) (snd-display #__line__ ";sync of sound (12): ~A" (sync snd))) (if (not (= (sync mrk) 24)) (snd-display #__line__ ";sync of mark (24): ~A" (sync mrk))) (if (not (= (sync mx) 36)) (snd-display #__line__ ";sync of mx (36): ~A" (sync mx))) ) (close-sound snd)) ;; maxamp as generic (let ((snd (open-sound "oboe.snd")) (v (float-vector .1 .2 .3)) (vc (vector .1 .2 .3 .4)) (sd (make-float-vector (list 1 10) 0.0)) (str "pistol.snd")) ; can't use oboe.snd since we messed with mus-sound-maxamp above (let ((mxv (mix-float-vector v 1000)) (reg (make-region 0 900)) (dly (make-delay 32)) ) (set! (sd 0 1) .1) (delay dly .1) (delay dly .2) (if (fneq (maxamp snd) .334) (snd-display #__line__ ";maxamp of sound: ~A" (maxamp snd))) (if (fneq (maxamp snd 0) .334) (snd-display #__line__ ";maxamp of sound (0): ~A" (maxamp snd))) (if (fneq (maxamp snd 0 0) .14724) (snd-display #__line__ ";maxamp of sound (0 0): ~A" (maxamp snd))) (if (fneq (maxamp v) .3) (snd-display #__line__ ";maxamp of float-vector: ~A" (maxamp v))) (if (fneq (maxamp vc) .4) (snd-display #__line__ ";maxamp of vector: ~A" (maxamp vc))) (if (fneq (maxamp str) .49267) (snd-display #__line__ ";maxamp of string: ~A" (maxamp str))) (if (fneq (maxamp sd) 0.1) (snd-display #__line__ ";maxamp of vector2: ~A" (maxamp sd))) (if (fneq (maxamp mxv) .3) (snd-display #__line__ ";maxamp of mix: ~A" (maxamp mxv))) (if (fneq (maxamp reg) .02139) (snd-display #__line__ ";maxamp of region: ~A" (maxamp reg))) (if (fneq (maxamp dly) .2) (snd-display #__line__ ";maxamp of delay: ~A" (maxamp dly))) ) (close-sound snd)) ))) ;;; ---------------- test 16: regularized funcs ---------------- (define (snd_test_16) (define (undo-env s c) (let ((len (car (edits s c)))) (and (> len 0) (let ((unhappy #f)) (do ((i 1 (+ i 1))) ((or unhappy (> i len)) unhappy) (let ((ed (edit-fragment i s c))) (if (and ed (string=? (cadr ed) "env")) (begin (set! (edit-position s c) (- i 1)) (set! unhappy #t))))))))) (define (opt-test choice) (let* ((snds (sounds)) (cursnd (snds (random (length snds)))) (curchn (random (chans cursnd))) (chan-list (all-chans)) (cur-maxamps (apply map maxamp chan-list)) (cur-edits (apply map edit-position chan-list)) (cur-framples (apply map framples chan-list)) (cur-amp (maxamp cursnd curchn)) (cur-edit (edit-position cursnd curchn)) (cur-frame (framples cursnd curchn))) (case choice ;; scale-channel ((0) (let* ((scaler (if (< (maxamp cursnd curchn) 1.0) (+ 1.0 (random 1.0)) (+ 0.5 (random 0.5)))) (cur-loc (random cur-frame)) (cur-samp (sample cur-loc cursnd curchn))) (scale-channel scaler 0 (framples cursnd curchn) cursnd curchn) (if (and (not (= (edit-position cursnd curchn) (+ 1 cur-edit))) (not (= (edit-position cursnd curchn) cur-edit))) (snd-display #__line__ ";scale-channel ~A[~A] edit pos: ~A ~A" (short-file-name cursnd) curchn (edit-position cursnd curchn) cur-edit)) (if (not (= (framples cursnd curchn) cur-frame)) (snd-display #__line__ ";scale-channel ~A[~A] framples: ~A ~A" (short-file-name cursnd) curchn (framples cursnd curchn) cur-frame)) (if (fneq (maxamp cursnd curchn) (* scaler cur-amp)) (snd-display #__line__ ";scale-channel ~A[~A] maxamp: ~A ~A (~A, scaler: ~A)" (short-file-name cursnd) curchn (maxamp cursnd curchn) (* scaler cur-amp) (abs (- (maxamp cursnd curchn) (* scaler cur-amp))) scaler)) (if (fneq (sample cur-loc cursnd curchn) (* scaler cur-samp)) (snd-display #__line__ ";scale-channel ~A[~A] cur-samp: ~A ~A" (short-file-name cursnd) curchn (sample cur-loc cursnd curchn) (* scaler cur-samp))) (for-each (lambda (s c amp ed fr) (if (not (and (equal? s cursnd) (= c curchn))) (begin (if (not (= (edit-position s c) ed)) (snd-display #__line__ ";scale-channel ~A[~A] wrong edit pos: ~A ~A" (short-file-name s) c (edit-position s c) ed)) (if (not (= (framples s c) fr)) (snd-display #__line__ ";scale-channel ~A[~A] wrong framples: ~A ~A" (short-file-name s) c (framples s c) fr)) (if (fneq (maxamp s c) amp) (snd-display #__line__ ";scale-channel ~A[~A] wrong maxamp: ~A ~A" (short-file-name s) c (maxamp s c) amp))))) (car chan-list) (cadr chan-list) cur-maxamps cur-edits cur-framples))) ;; scale-by ((1) (let* ((maxscl (apply max cur-maxamps)) (scaler (if (< maxscl 1.0) (+ 1.0 (random 1.0)) (+ 0.5 (random 0.5))))) (scale-by scaler cursnd curchn) (for-each (lambda (s c amp ed fr) (if (or (and (= (sync cursnd) 0) (or (not (equal? s cursnd)) (not (= c curchn)))) (not (= (sync s) (sync cursnd)))) (begin (if (not (= (edit-position s c) ed)) (snd-display #__line__ ";scale-by ~A[~A] wrong edit pos: ~A ~A" (short-file-name s) c (edit-position s c) ed)) (if (not (= (framples s c) fr)) (snd-display #__line__ ";scale-by ~A[~A] wrong framples: ~A ~A" (short-file-name s) c (framples s c) fr)) (if (fneq (maxamp s c) amp) (snd-display #__line__ ";scale-by ~A[~A] wrong maxamp: ~A ~A" (short-file-name s) c (maxamp s c) amp))) (begin (if (and (not (= (edit-position s c) (+ 1 ed))) (not (= (edit-position s c) ed))) (snd-display #__line__ ";scale-by ~A[~A] edit pos: ~A ~A" (short-file-name s) c (edit-position s c) ed)) (if (not (= (framples s c) fr)) (snd-display #__line__ ";scale-by ~A[~A] framples: ~A ~A" (short-file-name s) c (framples s c) fr)) (if (fneq (maxamp s c) (* scaler amp)) (snd-display #__line__ ";scale-by ~A[~A] maxamp: ~A ~A" (short-file-name s) c (maxamp s c) (* scaler amp)))))) (car chan-list) (cadr chan-list) cur-maxamps cur-edits cur-framples))) ;; scale-sound-by ((4) (let* ((maxscl (apply max cur-maxamps)) (scaler (if (< maxscl 1.0) (+ 1.0 (random 1.0)) (+ 0.5 (random 0.5))))) (scale-sound-by scaler 1000 1000 cursnd) (for-each (lambda (s c amp ed fr) (if (not (equal? s cursnd)) (begin (if (not (= (edit-position s c) ed)) (snd-display #__line__ ";scale-sound-by ~A[~A] wrong edit pos: ~A ~A" (short-file-name s) c (edit-position s c) ed)) (if (not (= (framples s c) fr)) (snd-display #__line__ ";scale-sound-by ~A[~A] wrong framples: ~A ~A" (short-file-name s) c (framples s c) fr)) (if (fneq (maxamp s c) amp) (snd-display #__line__ ";scale-sound-by ~A[~A] wrong maxamp: ~A ~A" (short-file-name s) c (maxamp s c) amp))) (begin (if (and (not (= (edit-position s c) (+ 1 ed))) (not (= (edit-position s c) ed))) (snd-display #__line__ ";scale-sound-by ~A[~A] edit pos: ~A ~A" (short-file-name s) c (edit-position s c) ed)) (if (not (= (framples s c) fr)) (snd-display #__line__ ";scale-sound-by ~A[~A] framples: ~A ~A" (short-file-name s) c (framples s c) fr))))) (car chan-list) (cadr chan-list) cur-maxamps cur-edits cur-framples))) ((5) (let ((pos (edit-position cursnd curchn))) (if (> pos 0) (let ((r (random pos))) (undo r cursnd curchn))))) ((6) (let ((len (framples cursnd curchn))) (if (> len 10000) (let ((beg (random (floor (/ len 2))))) (delete-samples beg (+ 10 (random 100)) cursnd curchn))))) ((7) (let ((beg (random (+ (framples cursnd curchn) 100))) (dur (+ 10 (random 100)))) (set! (samples beg dur cursnd curchn) (make-float-vector dur 1.0)))) ((8) (let ((beg (random (+ (framples cursnd curchn) 100))) (dur (+ 10 (random 100)))) (insert-samples beg dur (make-float-vector dur 1.0) cursnd curchn))) ((9) (add-mark (random (framples cursnd curchn)) cursnd curchn)) ((10) (let ((beg (random (+ (framples cursnd curchn) 100)))) (mix-float-vector (make-float-vector (+ 10 (random 100)) (random 1.0)) beg cursnd curchn))) ((11) (let ((beg (random (+ (framples cursnd curchn) 100)))) (pad-channel beg (+ 10 (random 100)) cursnd curchn))) ((13) (let ((beg (random (- (framples cursnd curchn) 100)))) (scale-channel .5 beg (+ 10 (random 100)) cursnd curchn))) ((14) (let ((beg (random (- (framples cursnd curchn) 200)))) (scale-channel .5 beg (+ 10 (random 100)) cursnd curchn) (scale-channel .5 (+ beg 10) (+ 10 (random 100)) cursnd curchn))) ((15) (let ((beg (random (- (framples cursnd curchn) 200)))) (scale-channel .5 beg (+ 10 (random 100)) cursnd curchn) (scale-channel 2.0 beg (+ 10 (random 100)) cursnd curchn))) ((16) (let ((beg (random (- (framples cursnd curchn) 200)))) (pad-channel beg (+ 10 (random 100)) cursnd curchn) (pad-channel (+ beg 10) (+ 10 (random 100)) cursnd curchn))) ((17) (let ((beg (random (- (framples cursnd curchn) 200)))) (pad-channel beg (+ 10 (random 100)) cursnd curchn) (pad-channel beg (+ 10 (random 100)) cursnd curchn))) ((18) (let ((beg (random (- (framples cursnd curchn) 200)))) (delete-sample beg cursnd curchn) (delete-sample (+ beg (random 100)) cursnd curchn))) ((19) (let ((beg (random (+ (framples cursnd curchn) 200)))) (set! (sample beg cursnd curchn) .1) (set! (sample (+ beg (random 100)) cursnd curchn) .2))) ((20) (let ((beg (random (- (framples cursnd curchn) 200)))) (ramp-channel (- (random 2.0) 1.0) (- (random 2.0) 1.0) beg (+ 10 (random 100)) cursnd curchn))) ((12) (let* ((pts (+ 1 (random 8))) (e (let ((e1 ()) (x 0.0) (y 0.0)) (do ((i 0 (+ i 1))) ((= i pts)) (set! e1 (cons x e1)) (if (> (random 3) 0) (set! y (mus-random 1.0))) (set! e1 (cons y e1)) (set! x (+ x .01 (random 1.0)))) (reverse e1))) (beg (random (- (framples cursnd curchn) 300))) (dur (+ 80 (random 200))) (reader0 (make-sampler beg cursnd curchn))) (env-channel e beg dur cursnd curchn) (let ((reader1 (make-sampler beg cursnd curchn)) (en (make-env e :length dur))) (do ((i 0 (+ i 1))) ((= i dur)) (let* ((e0 (env en)) (val00 (reader0)) (val0 (* e0 val00)) (val1 (reader1))) (if (> (abs (- val0 val1)) .005) (begin (if (file-exists? "baddy.scm") (delete-file "baddy.scm")) (save-state "baddy.scm") (snd-display #__line__ ";read env off by ~A: ~% (~A) at ~A: ~% ~A ~A (~A ~A) [~A ~A]:~% ~A" (abs (- val0 val1)) e i val0 val1 reader0 reader1 e0 val00 (safe-display-edits cursnd curchn)) (error 'mus-error)))))))) ;; env-channel ((2) (let* ((pts (+ 1 (random 6))) (e (let ((e1 ()) (x 0.0) (y 0.0)) (do ((i 0 (+ i 1))) ((= i pts)) (set! e1 (cons x e1)) (if (> (random 3) 0) (set! y (mus-random 1.0))) (set! e1 (cons y e1)) (set! x (+ x .01 (random 1.0)))) (reverse e1)))) (if (undo-env cursnd curchn) (begin (set! cur-maxamps (apply map maxamp chan-list)) (set! cur-edits (apply map edit-position chan-list)) (set! cur-framples (apply map framples chan-list)) (set! cur-amp (maxamp cursnd curchn)) (set! cur-edit (edit-position cursnd curchn)) (set! cur-frame (framples cursnd curchn)))) (env-channel e 0 (framples cursnd curchn) cursnd curchn) ; can be a no-op (if (and (not (= (edit-position cursnd curchn) (+ 1 cur-edit))) (not (= (edit-position cursnd curchn) cur-edit))) (snd-display #__line__ ";env-channel ~A[~A] edit pos: ~A ~A" (short-file-name cursnd) curchn (edit-position cursnd curchn) cur-edit)) (if (not (= (framples cursnd curchn) cur-frame)) (snd-display #__line__ ";env-channel ~A[~A] framples: ~A ~A" (short-file-name cursnd) curchn (framples cursnd curchn) cur-frame)) (for-each (lambda (s c amp ed fr) (if (not (and (equal? s cursnd) (= c curchn))) (begin (if (not (= (edit-position s c) ed)) (snd-display #__line__ ";env-channel ~A[~A] wrong edit pos: ~A ~A" (short-file-name s) c (edit-position s c) ed)) (if (not (= (framples s c) fr)) (snd-display #__line__ ";env-channel ~A[~A] wrong framples: ~A ~A" (short-file-name s) c (framples s c) fr)) (if (fneq (maxamp s c) amp) (snd-display #__line__ ";env-channel ~A[~A] wrong maxamp: ~A ~A" (short-file-name s) c (maxamp s c) amp))))) (car chan-list) (cadr chan-list) cur-maxamps cur-edits cur-framples))) ;; env-sound ((3) (let* ((pts (+ 1 (random 6))) (recalc #f) (e (let ((e1 ()) (x 0.0) (y 0.0)) (do ((i 0 (+ i 1))) ((= i pts)) (set! e1 (cons x e1)) (if (> (random 3) 0) (set! y (mus-random 1.0))) (set! e1 (cons y e1)) (set! x (+ x .01 (random 1.0)))) (reverse e1))) (end (apply min cur-framples)) ; env-sound can lengthen a shorter sound if syncd+multichannel (beg (random (floor (/ end 2))))) (for-each (lambda (s c) (if (not (or (and (= (sync cursnd) 0) (or (not (equal? s cursnd)) (not (= c curchn)))) (not (= (sync s) (sync cursnd))))) (let ((val (undo-env s c))) (set! recalc (or recalc val))))) (car chan-list) (cadr chan-list)) (if recalc (begin (set! cur-maxamps (apply map maxamp chan-list)) (set! cur-edits (apply map edit-position chan-list)) (set! cur-framples (apply map framples chan-list)) (set! cur-amp (maxamp cursnd curchn)) (set! cur-edit (edit-position cursnd curchn)) (set! cur-frame (framples cursnd curchn)))) (env-sound e beg (max pts (- end beg)) 1.0 cursnd curchn) ; dur here, not end point (for-each (lambda (s c amp ed fr) (if (or (and (= (sync cursnd) 0) (or (not (equal? s cursnd)) (not (= c curchn)))) (not (= (sync s) (sync cursnd)))) (begin (if (not (= (edit-position s c) ed)) (snd-display #__line__ ";env-sound ~A[~A] wrong edit pos: ~A ~A" (short-file-name s) c (edit-position s c) ed)) (if (not (= (framples s c) fr)) (snd-display #__line__ ";env-sound ~A[~A] wrong framples: ~A ~A" (short-file-name s) c (framples s c) fr)) (if (fneq (maxamp s c) amp) (snd-display #__line__ ";env-sound ~A[~A] wrong maxamp: ~A ~A" (short-file-name s) c (maxamp s c) amp))) (begin (if (and (not (= (edit-position s c) (+ 1 ed))) (not (= (edit-position s c) ed))) (snd-display #__line__ ";env-sound ~A[~A] edit pos: ~A ~A" (short-file-name s) c (edit-position s c) ed)) (if (not (= (framples s c) fr)) (snd-display #__line__ ";env-sound ~A[~A] framples: ~A ~A" (short-file-name s) c (framples s c) fr))))) (car chan-list) (cadr chan-list) cur-maxamps cur-edits cur-framples))) ))) (define (amp-envs-equal? snd chn pos0 pos1 df) (let* ((env0 (channel-amp-envs snd chn pos0)) (len0 (and env0 (pair? env0) (= (length env0) 2) (length (cadr env0)))) (env1 (channel-amp-envs snd chn pos1)) (len1 (and env1 (pair? env1) (= (length env1) 2) (length (cadr env1)))) (happy #t)) (and len0 len1 (let* ((minlen (min len0 len1)) (minlen1 (- minlen 1)) (inc0 (/ len0 minlen)) (inc1 (/ len1 minlen)) (e0 (cadr env0)) (e1 (cadr env1))) (if (and (integer? inc0) (integer? inc1)) (do ((i 0 (+ i 1))) ((or (not happy) (= i minlen1)) happy) (let ((max0 -1.0) (max1 -1.0)) (if (= inc0 1) (set! max0 (e0 i)) (do ((j 0 (+ j 1)) (j1 (* inc0 i) (+ j1 1))) ((= j inc0)) (if (> (e0 j1) max0) (set! max0 (e0 j1))))) (if (= inc1 1) (set! max1 (e1 i)) (do ((j 0 (+ j 1)) (j1 (* inc1 i) (+ j1 1))) ((= j inc1)) (if (> (e1 j1) max1) (set! max1 (e1 j1))))) (if (> (abs (- max0 max1)) df) (begin (snd-display #__line__ ";amp-env ~A: ~A ~A" i max0 max1) (set! happy #f))))) (begin (snd-display #__line__ ";lens: ~A ~A" len0 len1) #f)))))) (define* (edit-difference s1 c1 e1 e2 (offset 0)) (let* ((N (framples s1 c1 e1)) (d1 (samples 0 N s1 c1 e1)) (d2 (samples 0 N s1 c1 e2))) (float-vector-subtract! d1 d2) (let ((diffs (float-vector-peak-and-location d1))) (and (> (car diffs) 0.0) diffs)))) (define* (edit-distance s1 c1 e1 e2 (offset 0)) (let* ((incr (make-one-pole 1.0 -1.0)) (N (framples s1 c1 e1)) (d1 (samples 0 N s1 c1 e1)) (d2 (samples 0 N s1 c1 e2))) (float-vector-multiply! d1 d1) (float-vector-multiply! d2 d2) (float-vector-subtract! d1 d2) (float-vector-abs! d1) (do ((i 0 (+ i 1))) ((= i N)) (one-pole incr (float-vector-ref d1 i))) (sqrt (one-pole incr 0.0)))) (define (check-edit-tree expected-tree expected-vals name line) (define (vequal-at v0 v1) (call-with-exit (lambda (return) (let ((len (length v0))) (do ((i 0 (+ i 1))) ((= i len) #f) (if (> (abs (- (v0 i) (v1 i))) .001) (return (list i (v0 i) (v1 i))))))))) (define (edits-not-equal? tl0 tl1 pos) (if (null? tl0) (and (not (null? tl1)) (list pos tl0 #f)) (let ((t0 (car tl0)) (t1 (car tl1))) (if (or (not (= (car t0) (car t1))) (not (= (cadr t0) (cadr t1))) (not (= (caddr t0) (caddr t1))) (not (= (cadddr t0) (cadddr t1))) (> (abs (- (t0 4) (t1 4))) .0001) (> (abs (- (t0 5) (t1 5))) .0001) ; rmp0 (> (abs (- (t0 6) (t1 6))) .0001)) ; rmp1 (list pos t0 t1) (edits-not-equal? (cdr tl0) (cdr tl1) (+ 1 pos)))))) (let* ((current-vals (channel->float-vector)) (len (length current-vals))) (if (and expected-vals (not (= len (length expected-vals)))) (snd-display #__line__ ";~A (from ~A): lengths differ: ~A ~A" name line len (length expected-vals)) (if (and expected-vals (not (vequal current-vals expected-vals))) (let ((bad-data (vequal-at current-vals expected-vals))) (snd-display #__line__ ";checking ~A (from ~A), vals disagree (loc cur expect): ~A" name line bad-data)) (let* ((tree (edit-tree)) (bad-data (edits-not-equal? tree expected-tree 0))) (if bad-data (snd-display #__line__ ";checking ~A (from ~A), trees disagree (loc cur expect): ~A~% in~%~A" name line bad-data (edit-tree))) (if (> len 5) (let* ((split-loc (+ 2 (random (- len 3)))) (fread (make-sampler split-loc)) (bread (make-sampler (- split-loc 1) #f #f -1)) (split-vals (make-float-vector len))) (do ((i split-loc (+ i 1))) ((= i len)) (float-vector-set! split-vals i (read-sample fread))) (do ((i (- split-loc 1) (- i 1))) ((< i 0)) (float-vector-set! split-vals i (read-sample bread))) (if (and expected-vals (not (vequal split-vals expected-vals))) (let ((bad-data (vequal-at split-vals expected-vals))) (snd-display #__line__ ";checking ~A (from ~A), split vals disagree (loc cur expect): ~A" name line bad-data) ; (error 'uhoh1) ))))))))) (define (reversed-read snd chn) (let* ((len (framples snd chn)) (data (make-float-vector len)) (sf (make-sampler (- len 1) snd chn -1))) (do ((i (- len 1) (- i 1))) ((< i 0)) (set! (data i) (read-sample sf))) data)) (define (zigzag-read snd chn) (let* ((len (framples snd chn)) (data (make-float-vector len)) (sf (make-sampler 3 snd chn 1))) (do ((i 3 (+ i 1))) ((= i 6)) (set! (data i) (next-sample sf))) (do ((i 6 (- i 1))) ((= i 0)) (set! (data i) (previous-sample sf))) (do ((i 0 (+ i 1))) ((= i len)) (set! (data i) (next-sample sf))) data)) (define (zigzag-check name snd chn) (let ((data (channel->float-vector)) (sf (make-sampler 3 snd chn))) (do ((i 3 (+ i 1))) ((= i 8)) (let ((val (next-sample sf))) (if (fneq (data i) val) (snd-display #__line__ ";~A: forward data[~D]: ~A ~A" name i val (data i))))) (do ((i 7 (- i 1))) ((= i 0)) (let ((val (previous-sample sf))) (if (fneq (data i) val) (snd-display #__line__ ";~A: backward data[~D]: ~A ~A" name i val (data i))))))) (define (init-sound val dur chans) (let ((ind (new-sound "test.snd" chans 22050 mus-ldouble mus-next))) (do ((i 0 (+ i 1))) ((= i chans)) (insert-silence 0 dur ind i) (map-channel (lambda (y) val) 0 (framples) ind i)) ind)) (define (check-back-and-forth ind name v) (let ((happy #t)) (if (not (vequal v (channel->float-vector 0 (framples) ind 0))) (begin (set! happy #f) (snd-display #__line__ ";~A forth:~% current: ~A~% expected: ~A" name (channel->float-vector 0 (framples) ind 0) v))) (if (not (vequal v (reversed-read ind 0))) (begin (set! happy #f) (snd-display #__line__ ";~A back: ~A ~A" name (reversed-read ind 0) v))) happy)) (define (rampx-channel r0 r1) (xramp-channel r0 r1 3.0 0 (framples))) (define (check-both-chans ind name f0 f1) (let ((c0 (scan-channel f0 0 (framples) ind 0)) (c1 (scan-channel f1 0 (framples) ind 1))) (if c0 (snd-display #__line__ ";~A swap c0: ~A" name c0)) (if c1 (snd-display #__line__ ";~A swap c1: ~A" name c1)))) (define (convolve-coeffs v1 v2) (let* ((v1-len (length v1)) (v2-len (length v2)) (res-len (+ v1-len v2-len -1)) (vres (make-float-vector res-len))) (do ((i 0 (+ i 1))) ((= i res-len)) (let ((sum 0.0)) (do ((j (max 0 (+ 1 (- i v2-len))) (+ j 1))) ((> j (min i (- v1-len 1)))) (set! sum (+ sum (* (v1 j) (v2 (- i j)))))) (set! (vres i) sum))) vres)) (do ((test-16 0 (+ 1 test-16))) ((= test-16 tests)) (let ((oboe (open-sound "oboe.snd"))) (log-mem test-16) (for-each (lambda (func name) (func) (if (not (= (edit-position oboe) 0)) (snd-display #__line__ ";dur:0 ~A? ~A ~A" name (edit-position oboe) (edit-fragment)))) (list (lambda () (scale-channel 2.0 0 0 oboe)) (lambda () (env-channel (make-env '(0 0 1 1) :length 124) 0 0 oboe)) (lambda () (clm-channel (make-oscil) 0 0 oboe)) (lambda () (float-vector->channel (make-float-vector 3) 0 0 oboe)) (lambda () (smooth-channel 0 0 oboe)) (lambda () (pad-channel 0 0 oboe)) (lambda () (src-channel 2.0 0 0 oboe)) (lambda () (mix-channel "pistol.snd" 0 0 oboe)) (lambda () (insert-channel "pistol.snd" 0 0 oboe)) (lambda () (reverse-channel 0 0 oboe)) (lambda () (play oboe :start 0 :end 0)) (lambda () (scale-sound-by 2.0 0 0 oboe)) (lambda () (env-sound '(0 0 1 1) 0 0 oboe)) (lambda () (set-samples 0 0 (make-float-vector 3) oboe)) (lambda () (smooth-sound 0 0 oboe)) (lambda () (insert-silence 0 0 oboe))) (list "scale-channel" "env-channel" "clm-channel" "float-vector->channel" "smooth-channel" "pad-channel" "src-channel" "mix-channel" "insert-channel" "reverse-channel" "play" "scale-sound-by" "env-sound" "set-samples" "smooth-sound" "insert-silence")) (for-each (lambda (func name) (let ((tag (catch #t func (lambda args (car args))))) (if (not (eq? tag 'no-such-sample)) (snd-display #__line__ ";~A beg -1->~A" name tag)) (if (not (= (edit-position oboe) 0)) (snd-display #__line__ ";beg:-1 ~A? ~A ~A" name (edit-position oboe) (edit-fragment))))) (list (lambda () (scale-channel 2.0 -1 123 oboe)) (lambda () (env-channel (make-env '(0 0 1 1) :length 124) -1 123 oboe)) (lambda () (clm-channel (make-oscil) -1 123 oboe)) (lambda () (float-vector->channel (make-float-vector 3) -1 123 oboe)) (lambda () (smooth-channel -1 123 oboe)) (lambda () (pad-channel -1 123 oboe)) (lambda () (src-channel 2.0 -1 123 oboe)) (lambda () (mix-channel "pistol.snd" -1 123 oboe)) (lambda () (insert-channel "pistol.snd" -1 123 oboe)) (lambda () (reverse-channel -1 123 oboe)) (lambda () (scale-sound-by 2.0 -1 123 oboe)) (lambda () (env-sound '(0 0 1 1) -1 123 oboe)) (lambda () (set-samples -1 123 (make-float-vector 3) oboe)) (lambda () (smooth-sound -1 123 oboe)) (lambda () (insert-silence -1 123 oboe))) (list "scale-channel" "env-channel" "clm-channel" "float-vector->channel" "smooth-channel" "pad-channel" "src-channel" "mix-channel" "insert-channel" "reverse-channel" "scale-sound-by" "env-sound" "set-samples" "smooth-sound" "insert-silence")) (scale-channel 2.0 12345678 123 oboe) (if (not (= (edit-position oboe) 0)) (snd-display #__line__ ";beg:12345678 scale-channel? ~A ~A" (edit-position oboe) (edit-fragment))) (env-channel (make-env '(0 0 1 1) :length 124) 12345678 123 oboe) (if (not (= (edit-position oboe) 0)) (snd-display #__line__ ";beg:12345678 env-channel? ~A ~A" (edit-position oboe) (edit-fragment))) (smooth-channel 12345678 123 oboe) (if (not (= (edit-position oboe) 0)) (snd-display #__line__ ";beg:12345678 smooth-channel? ~A ~A" (edit-position oboe) (edit-fragment))) (src-channel 2.0 12345678 123 oboe) (if (not (= (edit-position oboe) 0)) (snd-display #__line__ ";beg:12345678 src-channel? ~A ~A" (edit-position oboe) (edit-fragment))) (reverse-channel 12345678 123 oboe) (if (not (= (edit-position oboe) 0)) (snd-display #__line__ ";beg:12345678 reverse-channel? ~A ~A" (edit-position oboe) (edit-fragment))) (play oboe :start 12345678 :end (+ 12345678 123)) (scale-channel 2.0 0 123 oboe 0) (if (not (= (edit-position oboe) 1)) (snd-display #__line__ ";oboe scale-channel? ~A ~A" (edit-position oboe) (edit-fragment))) (env-channel (make-env '(0 0 1 1) :length 124) 0 123 oboe 0) (if (not (= (edit-position oboe) 2)) (snd-display #__line__ ";oboe env-channel? ~A ~A" (edit-position oboe) (edit-fragment))) (clm-channel (make-oscil) 0 123 oboe 0) (if (not (= (edit-position oboe) 3)) (snd-display #__line__ ";oboe clm-channel? ~A ~A" (edit-position oboe) (edit-fragment))) (float-vector->channel (make-float-vector 3) 0 123 oboe 0) (if (not (= (edit-position oboe) 4)) (snd-display #__line__ ";oboe float-vector->channel? ~A ~A" (edit-position oboe) (edit-fragment))) (smooth-channel 0 123 oboe 0) (if (not (= (edit-position oboe) 5)) (snd-display #__line__ ";oboe smooth-channel? ~A ~A" (edit-position oboe) (edit-fragment))) (pad-channel 0 123 oboe 0) (if (not (= (edit-position oboe) 6)) (snd-display #__line__ ";oboe pad-channel? ~A ~A" (edit-position oboe) (edit-fragment))) (src-channel 2.0 0 123 oboe 0) (if (not (= (edit-position oboe) 7)) (snd-display #__line__ ";oboe src-channel? ~A ~A" (edit-position oboe) (edit-fragment))) (mix-channel "pistol.snd" 0 123 oboe 0) (if (not (= (edit-position oboe) 8)) (snd-display #__line__ ";oboe mix-channel? ~A ~A" (edit-position oboe) (edit-fragment))) (insert-channel "pistol.snd" 0 123 oboe 0) (if (not (= (edit-position oboe) 9)) (snd-display #__line__ ";oboe insert-channel? ~A ~A" (edit-position oboe) (edit-fragment))) (reverse-channel 0 123 oboe 0) (if (not (= (edit-position oboe) 10)) (snd-display #__line__ ";oboe reverse-channel? ~A ~A" (edit-position oboe) (edit-fragment))) (let* ((rd (make-sampler 0)) (sr (make-src :srate 2.0 :input (lambda (dir) (read-sample rd))))) (clm-channel sr 0 12345 oboe 0) (if (not (= (edit-position oboe) 11)) (snd-display #__line__ ";oboe clm-channel src? ~A ~A" (edit-position oboe) (edit-fragment)))) (let* ((rd (make-sampler 0)) (sr (make-granulate :expansion 2.0 :input (lambda (dir) (read-sample rd))))) (clm-channel sr 0 12345 oboe 0) (if (not (= (edit-position oboe) 12)) (snd-display #__line__ ";oboe clm-channel granulate? ~A ~A" (edit-position oboe) (edit-fragment)))) (let* ((rd (make-sampler 0)) (flt (float-vector 1.0 0.0 0.0 0.0)) (sr (make-convolve :input (lambda (dir) (read-sample rd)) :filter flt))) (clm-channel sr 0 12345 oboe 0) (if (not (= (edit-position oboe) 13)) (snd-display #__line__ ";oboe clm-channel convolve? ~A ~A" (edit-position oboe) (edit-fragment)))) (let* ((rd (make-sampler 0)) (sr (make-phase-vocoder :input (lambda (dir) (read-sample rd))))) (clm-channel sr 0 12345 oboe 0) (if (not (= (edit-position oboe) 14)) (snd-display #__line__ ";oboe clm-channel phase-vocoder? ~A ~A" (edit-position oboe) (edit-fragment)))) (revert-sound) (catch #t (lambda () (env-channel (make-env '(0 0 1 1) :length 124) 0 123 oboe 0 123)) (lambda args (car args))) (if (not (= (edit-position oboe) 0)) (snd-display #__line__ ";edpos 123 env-channel? ~A ~A" (edit-position oboe) (edit-fragment))) (catch #t (lambda () (clm-channel (make-oscil) 0 123 oboe 0 123)) (lambda args (car args))) (if (not (= (edit-position oboe) 0)) (snd-display #__line__ ";edpos 123 clm-channel? ~A ~A" (edit-position oboe) (edit-fragment))) (catch #t (lambda () (float-vector->channel (make-float-vector 3) 0 123 oboe 0 123)) (lambda args (car args))) (if (not (= (edit-position oboe) 0)) (snd-display #__line__ ";edpos 123 float-vector->channel? ~A ~A" (edit-position oboe) (edit-fragment))) (catch #t (lambda () (smooth-channel 0 123 oboe 0 123)) (lambda args (car args))) (if (not (= (edit-position oboe) 0)) (snd-display #__line__ ";edpos 123 smooth-channel? ~A ~A" (edit-position oboe) (edit-fragment))) (catch #t (lambda () (pad-channel 0 123 oboe 0 123)) (lambda args (car args))) (if (not (= (edit-position oboe) 0)) (snd-display #__line__ ";edpos 123 pad-channel? ~A ~A" (edit-position oboe) (edit-fragment))) (catch #t (lambda () (src-channel 2.0 0 123 oboe 0 123)) (lambda args (car args))) (if (not (= (edit-position oboe) 0)) (snd-display #__line__ ";edpos 123 src-channel? ~A ~A" (edit-position oboe) (edit-fragment))) (catch #t (lambda () (mix-channel "pistol.snd" 0 123 oboe 0 123)) (lambda args (car args))) (if (not (= (edit-position oboe) 0)) (snd-display #__line__ ";edpos 123 mix-channel? ~A ~A" (edit-position oboe) (edit-fragment))) (catch #t (lambda () (insert-channel "pistol.snd" 0 123 oboe 0 123)) (lambda args (car args))) (if (not (= (edit-position oboe) 0)) (snd-display #__line__ ";edpos 123 insert-channel? ~A ~A" (edit-position oboe) (edit-fragment))) (catch #t (lambda () (reverse-channel 0 123 oboe 0 123)) (lambda args (car args))) (if (not (= (edit-position oboe) 0)) (snd-display #__line__ ";edpos 123 reverse-channel? ~A ~A" (edit-position oboe) (edit-fragment))) (revert-sound oboe) (let ((oldv (channel->float-vector 1000 10 oboe))) (mix-channel "oboe.snd" 0) (float-vector-scale! oldv 2.0) (if (not (vequal oldv (channel->float-vector 1000 10 oboe))) (snd-display #__line__ ";mix-channel at 0: ~A ~A" oldv (channel->float-vector 1000 10 oboe))) (revert-sound oboe) (float-vector-scale! oldv 0.5) (insert-channel "oboe.snd" 0) (if (not (vequal oldv (channel->float-vector 1000 10 oboe))) (snd-display #__line__ ";insert-channel at 0: ~A ~A" oldv (channel->float-vector 1000 10 oboe))) (if (not (= (framples oboe 0) (* 2 (framples oboe 0 0)))) (snd-display #__line__ ";insert-channel framples: ~A ~A" (framples oboe 0) (framples oboe 0 0))) (revert-sound oboe)) (close-sound oboe) (let ((ind (new-sound "test.snd" :size 10 :channels 2))) (set! (sample 3 ind 0) .5) (set! (sample 2 ind 1) -.4) (save-sound-as "fmv.snd") (revert-sound ind) (let ((val (mix-channel "fmv.snd"))) (if (mix? val) (snd-display #__line__ ";mix-channel returned a mix: ~A?" val))) (if (not (vequal (channel->float-vector 0 #f ind 1) (make-float-vector 10 0.0))) (snd-display #__line__ ";mix-channel mixed channel 1: ~A?" (channel->float-vector 0 #f ind 1))) (if (not (vequal (channel->float-vector 0 #f ind 0) (float-vector 0 0 0 .5 0 0 0 0 0 0))) (snd-display #__line__ ";mix-channel chan 0: ~A" (channel->float-vector 0 #f ind 0))) (revert-sound ind) (let ((val (mix-channel (list "fmv.snd" 2 1) 0 #f ind 0))) (if (mix? val) (snd-display #__line__ ";mix-channel 2 returned a mix: ~A?" val))) (if (not (vequal (channel->float-vector 0 #f ind 1) (make-float-vector 10 0.0))) (snd-display #__line__ ";mix-channel mixed channel 1a: ~A?" (channel->float-vector 0 #f ind 1))) (if (not (vequal (channel->float-vector 0 #f ind 0) (float-vector -.4 0 0 0 0 0 0 0 0 0))) (snd-display #__line__ ";mix-channel chan 0a: ~A" (channel->float-vector 0 #f ind 0))) (revert-sound ind) (set! (sample 2 ind 1) -.4) (let ((val (mix-channel (list ind 2 1) 0 #f ind 0 -1 #t))) (if (not (mix? val)) (snd-display #__line__ ";mix-channel with-tag: ~A" val))) (if (not (vequal (channel->float-vector 0 #f ind 1) (float-vector 0 0 -.4 0 0 0 0 0 0 0))) (snd-display #__line__ ";mix-channel mixed channel 1b: ~A?" (channel->float-vector 0 #f ind 1))) (if (not (vequal (channel->float-vector 0 #f ind 0) (float-vector -.4 0 0 0 0 0 0 0 0 0))) (snd-display #__line__ ";mix-channel chan 0b: ~A" (channel->float-vector 0 #f ind 0))) (revert-sound ind) (let ((val (car (mix-channel (list "fmv.snd" 2 1) 0 #f ind 0 -1 #t)))) (if (not (mix? val)) (snd-display #__line__ ";mix-channel file with-tag: ~A" val))) (if (not (vequal (channel->float-vector 0 #f ind 1) (make-float-vector 10 0.0))) (snd-display #__line__ ";mix-channel mixed channel 1c: ~A?" (channel->float-vector 0 #f ind 1))) (if (not (vequal (channel->float-vector 0 #f ind 0) (float-vector -.4 0 0 0 0 0 0 0 0 0))) (snd-display #__line__ ";mix-channel chan 0c: ~A" (channel->float-vector 0 #f ind 0))) (revert-sound ind) (let ((val (car (mix-channel (list "fmv.snd") 0 #f ind 1 -1 #t)))) (if (not (mix? val)) (snd-display #__line__ ";mix-channel file 1 with-tag: ~A" val))) (if (not (vequal (channel->float-vector 0 #f ind 0) (make-float-vector 10 0.0))) (snd-display #__line__ ";mix-channel mixed channel 0d: ~A?" (channel->float-vector 0 #f ind 1))) (if (not (vequal (channel->float-vector 0 #f ind 1) (float-vector 0 0 0 .5 0 0 0 0 0 0))) (snd-display #__line__ ";mix-channel chan 1d: ~A" (channel->float-vector 0 #f ind 1))) (revert-sound ind) (if (file-exists? "fmv.snd") (delete-file "fmv.snd")) (close-sound ind)) (if (not (= *default-output-chans* 1)) (set! *default-output-chans* 1)) (let ((ind (new-sound "fmv.snd")) (v0 (make-float-vector 20 1.0))) (float-vector->channel v0) (if (not (= (framples) 20)) (snd-display #__line__ ";float-vector->channel new 20: ~A" (framples))) (if (fneq (maxamp) 1.0) (snd-display #__line__ ";float-vector 1->new: ~A" (maxamp))) (env-channel (make-env '(0 0 1 1 2 1) :base 0 :length 20)) (let ((v1 (channel->float-vector))) (if (not (vequal v1 (float-vector 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1))) (snd-display #__line__ ";env-channel step 1: ~A" v1))) (undo) (env-channel (make-env '(0 0 1 1 2 1) :base 0 :length 20) 8) (let ((v1 (channel->float-vector))) (if (not (vequal v1 (float-vector 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 1 1))) (snd-display #__line__ ";env-channel step 1 at 8: ~A" v1))) (undo) (env-channel (make-env '(0 0 1 1 2 1) :base 0 :length 12)) (let ((v1 (channel->float-vector))) (if (not (vequal v1 (float-vector 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1))) (snd-display #__line__ ";env-channel step 1 at 0: ~A" v1))) (undo) (env-channel (make-env '(0 0 1 1 2 1) :base 0 :length 12) 4) (let ((v1 (channel->float-vector))) (if (not (vequal v1 (float-vector 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1))) (snd-display #__line__ ";env-channel step 1 at 4: ~A" v1))) (undo) (env-channel (make-env '(0 0 1 1 2 1) :base 0 :length 12) 4 3) (let ((v1 (channel->float-vector))) (if (not (vequal v1 (float-vector 1 1 1 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1))) (snd-display #__line__ ";env-channel step 1 at 4 by 3: ~A" v1))) (undo) (env-channel (make-env '(0 1 1 0 2 0) :base 0 :length 8) 0 12) (let ((v1 (channel->float-vector))) (if (not (vequal v1 (float-vector 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1))) (snd-display #__line__ ";env-channel step 1 at 0 for 7: ~A" v1))) (undo) (env-channel (make-env '(0 0 1 1 2 1 3 0 4 0) :base 0 :length 20)) (let ((v1 (channel->float-vector))) (if (not (vequal v1 (float-vector 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0))) (snd-display #__line__ ";env-channel step 1: ~A" v1))) (env-channel (make-env '(0 0 1 .5 2 .25 3 0 4 0) :base 0 :length 21)) (let ((v1 (channel->float-vector))) (if (not (vequal v1 (float-vector 0 0 0 0 0 0 .5 .5 .5 .5 .5 .25 .25 .25 .25 0 0 0 0 0))) (snd-display #__line__ ";env-channel step 1 (.5): ~A" v1))) (close-sound ind)) (set! *x-axis-style* x-axis-as-percentage) (let* ((ind (open-sound "2.snd")) (fr (framples)) (m0 (maxamp ind 0)) (m1 (maxamp ind 1))) (set! (sync ind) 64) (insert-sound "2.snd") (insert-sound "2.snd") (if (not (= (framples) (* 3 fr))) (snd-display #__line__ ";2.snd 3x = ~A ~A" fr (framples))) (if (not (= (framples ind 0) (framples ind 1))) (snd-display #__line__ ";insert sync'd: ~A ~A" (framples ind 0) (framples ind 1))) (swap-channels) (if (or (fneq m0 (maxamp ind 1)) (fneq m1 (maxamp ind 0))) (snd-display #__line__ ";swapped: ~A ~A -> ~A ~A" m0 m1 (maxamp ind 0) (maxamp ind 1))) (close-sound ind)) (set! *x-axis-style* x-axis-in-seconds) (let ((new-snd (mono-files->stereo "test.snd" "oboe.snd" "pistol.snd"))) (if (not (= (channels new-snd) 2)) (snd-display #__line__ ";mono-files->stereo not stereo? ~A" (channels new-snd))) (if (not (string=? (short-file-name new-snd) "test.snd")) (snd-display #__line__ ";mono-files->stereo filename: ~A" (short-file-name new-snd))) (if (not (= (framples new-snd) 50828)) (snd-display #__line__ ";mono-files->stereo framples: ~A" (framples new-snd))) (close-sound new-snd)) (let ((oboe0 (open-sound "oboe.snd")) (oboe1 (open-sound "oboe.snd"))) (define (funcs-equal? name func0 func1) (func0 #f #f oboe0) (func1 #f #f oboe1) (if (not (vequal (channel->float-vector 1000 100 oboe0) (channel->float-vector 1000 100 oboe1))) (snd-display #__line__ ";~A via #f: ~A ~A" name (channel->float-vector 1000 100 oboe0) (channel->float-vector 1000 100 oboe1))) (revert-sound oboe0) (revert-sound oboe1) (select-sound oboe0) (func0) (select-sound oboe1) (func1) (if (not (vequal (channel->float-vector 1000 100 oboe0) (channel->float-vector 1000 100 oboe1))) (snd-display #__line__ ";~A via none: ~A ~A" name (channel->float-vector 1000 100 oboe0) (channel->float-vector 1000 100 oboe1))) (revert-sound oboe0) (revert-sound oboe1) (func0 0 (framples oboe0) oboe0) (func1 0 (framples oboe1) oboe1) (if (not (vequal (channel->float-vector 1000 100 oboe0) (channel->float-vector 1000 100 oboe1))) (snd-display #__line__ ";~A via framples: ~A ~A" name (channel->float-vector 1000 100 oboe0) (channel->float-vector 1000 100 oboe1))) (revert-sound oboe0) (revert-sound oboe1)) (funcs-equal? "scale-sound-by" (lambda args (apply scale-sound-by (cons 2.0 args))) (lambda args (apply scale-channel (cons 2.0 args)))) (funcs-equal? "scale-and-ramp" (lambda args (apply scale-sound-by (cons 0.0 args))) (lambda args (apply ramp-channel (cons 0.0 (cons 0.0 args))))) (funcs-equal? "scale-and-ramp" (lambda args (apply scale-sound-by (cons 2.0 args))) (lambda args (apply ramp-channel (cons 2.0 (cons 2.0 args))))) (funcs-equal? "smooth-sound" smooth-sound smooth-channel) (funcs-equal? "env-sound" (lambda args (apply env-sound (list (list 0 0 1 1) (if (> (length args) 0) (car args) 0) (and (> (length args) 1) (number? (cadr args)) (- (cadr args) 1)) 1.0 (if (> (length args) 2) (caddr args) (selected-sound))))) (lambda args (apply env-channel (cons (make-env :envelope (list 0 0 1 1) :length (if (and (> (length args) 1) (number? (cadr args))) (cadr args) (framples (if (> (length args) 2) (caddr args) (selected-sound))))) args)))) (funcs-equal? "src-sound" (lambda args (src-sound 2.0 1.0 (and (> (length args) 2) (caddr args)))) (lambda args (apply src-channel (cons 2.0 args)))) (funcs-equal? "reverse-sound" (lambda args (reverse-sound (and (> (length args) 2) (caddr args)))) reverse-channel) (funcs-equal? "mix" (lambda args (mix "pistol.snd" 0 0 (and (> (length args) 2) (caddr args)))) (lambda args (apply mix-channel "pistol.snd" args))) (funcs-equal? "insert-sound" (lambda args (insert-sound "pistol.snd" 0 0 (and (> (length args) 2) (caddr args)))) (lambda args (apply insert-channel "pistol.snd" args))) (close-sound oboe0) (close-sound oboe1)) (let ((ind (open-sound "oboe.snd")) (ind1 (new-sound "test.snd")) (old-save-dir *save-dir*)) (set! *save-dir* #f) (map-channel (lambda (y) 0.5) 0 100 ind1 0) (save-sound ind1) (close-sound ind1) (insert-sound "test.snd" 12345) (let ((vals (channel->float-vector (- 12345 50) 200 ind 0))) (if (file-exists? "hiho.scm") (delete-file "hiho.scm")) (save-state "hiho.scm") (close-sound ind) (for-each forget-region (regions)) (load (string-append cwd "hiho.scm")) (set! ind (find-sound "oboe.snd")) (if (not (sound? ind)) (snd-display #__line__ ";save hiho failed?") (let ((new-vals (channel->float-vector (- 12345 50) 200 ind 0))) (if (not (vequal vals new-vals)) (snd-display #__line__ ";save state hiho vals: ~A ~A" vals new-vals)))) (close-sound ind)) (set! *save-dir* old-save-dir)) (let ((ind (new-sound "test.snd"))) (map-channel (lambda (y) (random 1.0)) 0 10) (ramp-channel 0.0 1.0) (zigzag-check "ramp" ind 0) (undo) (revert-sound ind) (close-sound ind)) (set! *x-axis-style* x-axis-in-beats) (let ((ind (open-sound "storm.snd"))) (reverse-channel 500000 1000000) (set! (sample 0 ind 0 current-edit-position) .1) (if (fneq (sample 0 ind 0 current-edit-position) .1) (snd-display #__line__ ";set sample + edpos: ~A" (sample 0 ind 0 current-edit-position))) (close-sound ind)) (set! *x-axis-style* x-axis-in-seconds) (for-each (lambda (out-chans) (let ((ind (new-sound "new.snd" out-chans 22050 mus-ldouble mus-next "edpos testing")) (mx (apply max (map sync (sounds))))) (set! (sync ind) (+ mx 1)) (for-each (lambda (in-sound) (for-each (lambda (func) (for-each (lambda (edpos) (func edpos) (revert-sound ind)) (list (lambda () current-edit-position) (lambda () 0) (lambda () (- (edit-position ind 0) 1)) (lambda () (edit-position ind 0))))) (list (lambda (posfunc) (let ((chn (min (random (+ 1 out-chans)) (- out-chans 1)))) (if (not (vequal (channel->float-vector 0 (framples ind chn) ind chn 0) (float-vector 0.0))) (snd-display #__line__ ";start bad: ~A" (channel->float-vector 0 (framples ind chn) ind chn 0))) (set! (sample 0 ind chn) .1) (if (not (vequal (channel->float-vector 0 (framples ind chn) ind chn) (float-vector 0.1))) (snd-display #__line__ ";set bad: ~A" (channel->float-vector 0 (framples ind chn) ind chn))) (pad-channel 0 1 ind chn (posfunc)) (let ((pos (posfunc))) (if (procedure? pos) (set! pos (pos ind chn))) (let ((data (channel->float-vector 0 (framples ind chn) ind chn))) (if (or (and (= pos 0) (not (vequal data (float-vector 0.0 0.0)))) (and (or (= pos current-edit-position) (= pos (edit-position ind chn))) (not (vequal data (float-vector 0.0 0.1)))) (and (= pos (- (edit-position ind chn) 1)) (not (vequal data (float-vector 0.0 0.0))))) (snd-display #__line__ ";pos[~A]: edpos ~A of ~A, pad result[~A, ~A]: ~A" chn pos (edit-position ind chn) (framples ind chn pos) (framples ind chn) data)) (if (> (chans ind) 1) (do ((i 0 (+ i 1))) ((= i (chans ind))) (if (not (= i chn)) (let ((data (channel->float-vector 0 (framples ind i) ind i))) (if (not (vequal data (float-vector 0.0))) (snd-display #__line__ ";pad[~A / ~A] empty: ~A" i chn data)))))))))) (lambda (posfunc) (let ((chn (min (random (+ 1 out-chans)) (- out-chans 1)))) (set! (sample 0 ind chn) .1) (set! (sample 0 ind chn (posfunc)) (* 2 (sample 0 ind chn (posfunc)))) ; not scale since it checks for zeros (let ((pos (posfunc))) (if (procedure? pos) (set! pos (pos ind chn))) (let ((data (channel->float-vector 0 (framples ind chn) ind chn))) (if (or (and (= pos 0) (not (vequal data (float-vector 0.0)))) (and (or (= pos current-edit-position) (= pos (edit-position ind chn))) (not (vequal data (float-vector 0.2)))) (and (= pos (- (edit-position ind chn) 1)) (not (vequal data (float-vector 0.0))))) (snd-display #__line__ ";pos[~A]: edpos ~A of ~A, set *2 result[~A, ~A]: ~A" chn pos (edit-position ind chn) (framples ind chn pos) (framples ind chn) data)) (if (> (chans ind) 1) (do ((i 0 (+ i 1))) ((= i (chans ind))) (if (not (= i chn)) (let ((data (channel->float-vector 0 (framples ind i) ind i))) (if (not (vequal data (float-vector 0.0))) (snd-display #__line__ ";scale[~A / ~A] empty: ~A" i chn data))))))))))))) (list "2a.snd" "1a.snd" "4a.snd")) (close-sound ind))) (list 1 2 4)) (let ((ind (open-sound "oboe.snd"))) (map-channel (lambda (y) #f)) (if (not (= (framples ind) 0)) (snd-display #__line__ ";map-channel #f framples: ~A" (framples ind))) (if (equal? (edits ind) (list 0 0)) (snd-display #__line__ ";map-channel #f edits backed up")) (undo 1 ind) (if (= (framples ind) 0) (snd-display #__line__ ";map-channel #f framples after undo: ~A" (framples ind))) (let ((tag (catch #t (lambda () (map-channel (lambda (y) "hiho"))) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";map-channel bad-type: ~A" tag))) (let* ((ctr 0) (tag (catch #t (lambda () (scan-channel (lambda (y) (set! ctr (+ ctr 1)) (asdf)))) (lambda args (car args))))) (if (not (= ctr 1)) (snd-display #__line__ ";scan-channel error exit: ~A" ctr)) (if (and (not (eq? tag 'unbound-variable)) (not (eq? tag 'syntax-error)) (not (eq? tag 'error))) (snd-display #__line__ ";scan-channel unbound: ~A" tag))) (let ((val (scan-channel (lambda (y) #f)))) (if val (snd-display #__line__ ";scan-channel func #f: ~A" val))) (let ((val (scan-channel (lambda (y) #f) 1234))) (if val (snd-display #__line__ ";scan-channel func #f with beg: ~A" val))) (let ((val (scan-channel (lambda (y) #f) 1234 4321))) (if val (snd-display #__line__ ";scan-channel func #f with beg+dur: ~A" val))) (revert-sound ind) (let ((del (make-delay 1000)) (len (framples))) (clm-channel del 0 (framples) ind 0 0 2000) (if (not (= (framples ind) (+ 2000 len))) (snd-display #__line__ ";clm-channel overlap length: ~A ~A" len (framples))) (if (not (equal? (edit-tree) '((0 1 0 52827 1.0 0.0 0.0 0) (52828 -2 0 0 0.0 0.0 0.0 0)))) (snd-display #__line__ ";clm-channel overlaps: ~A" (edit-tree))) (let ((reader (make-sampler 0)) (preader (make-sampler 0 ind 0 1 0)) (happy #t)) (do ((i 0 (+ i 1))) ((or (not happy) (= i 1000))) (let ((val (reader))) (if (fneq val 0.0) (begin (snd-display #__line__ ";clm-channel overlap delayed: ~A: ~A" i val) (set! happy #f))))) (let ((v0 (make-float-vector len)) (v1 (make-float-vector len))) (do ((i 0 (+ i 1))) ((= i len)) (set! (v0 i) (read-sample preader))) (do ((i 0 (+ i 1))) ((= i len)) (float-vector-set! v1 i (read-sample reader))) (if (not (vequal v0 v1)) (snd-display #__line__ ";clm-channel overlap main: ~A ~A" v0 v1))) (do ((i 0 (+ i 1))) ((or (not happy) (= i 1000))) (if (fneq (reader) 0.0) (begin (snd-display #__line__ ";clm-channel overlap trailing garbage") (set! happy #f)))))) (close-sound ind)) (let ((ind (open-sound "oboe.snd")) (oldamp 0.0) (oldloc 0) (ctr 0)) (scan-channel (lambda (y) (if (>= (abs y) oldamp) (begin (set! oldloc ctr) (set! oldamp (abs y)))) (set! ctr (+ ctr 1)) #f)) (scale-by 10.0) (scale-by 0.1) (reverse-channel 0 #f ind 0 1) (let ((amp 0.0) (loc 0) (ctr (- (framples) 1))) (scan-channel (lambda (y) (if (> (abs y) amp) (begin (set! amp (abs y)) (set! loc ctr))) (set! ctr (- ctr 1)) #f)) ;; can't use maxamp here because it may be set by scaling process (if (or (fneq oldamp (* .1 amp)) (not (= loc oldloc))) (snd-display #__line__ ";reverse edpos screwup: ~A at ~A, ~A at ~A" oldamp oldloc amp loc))) (undo) (reverse-channel 0 #f ind 0 2) (let ((amp 0.0) (loc 0) (ctr (- (framples) 1))) (scan-channel (lambda (y) (if (> (abs y) amp) (begin (set! amp (abs y)) (set! loc ctr))) (set! ctr (- ctr 1)) #f)) ;; can't use maxamp here because it may be set by scaling process (if (or (fneq oldamp amp) (not (= loc oldloc))) (snd-display #__line__ ";reverse unscaled edpos screwup: ~A at ~A, ~A at ~A" oldamp oldloc amp loc))) (close-sound ind)) (if (mus-clipping) (set! (mus-clipping) #f)) (if *clipping* (set! *clipping* #f)) (let ((ind (new-sound "fmv.snd" 1 22050 mus-ldouble mus-next "edit trees")) (vals (make-float-vector 100))) (select-sound ind) (select-channel 0) (check-edit-tree '((0 0 0 0 0.0 0.0 0.0 1) (1 -2 0 0 0.0 0.0 0.0 0)) (make-float-vector 1) "initial new-sound" #__line__) (fill! vals 1.0) (set! (samples 0 100) vals) (check-edit-tree '((0 1 0 99 1.0 0.0 0.0 0) (100 -2 0 0 0.0 0.0 0.0 0)) vals "set first samps to one" #__line__) (scale-channel 0.5 10 20) (do ((i 10 (+ i 1))) ((= i 30)) (set! (vals i) 0.5)) (check-edit-tree '((0 1 0 9 1.0 0.0 0.0 0) (10 1 10 29 0.5 0.0 0.0 0) (30 1 30 99 1.0 0.0 0.0 0) (100 -2 0 0 0.0 0.0 0.0 0)) vals "scale-channel 0.5 10 20" #__line__) (env-channel (make-env '(0 0 1 1) :length 11) 15 10) (let ((e (make-env '(0 0 1 1) :length 11))) (do ((i 15 (+ i 1))) ((= i 25)) (set! (vals i) (* (vals i) (env e))))) (check-edit-tree '((0 1 0 9 1.0 0.0 0.0 0) (10 1 10 14 0.5 0.0 0.0 0) (15 1 15 24 0.5 0.0 0.1 1) (25 1 25 29 0.5 0.0 0.0 0) (30 1 30 99 1.0 0.0 0.0 0) (100 -2 0 0 0.0 0.0 0.0 0)) vals "env-channel 15 10" #__line__) (normalize-channel 1.0) (check-edit-tree '((0 1 0 9 1.0 0.0 0.0 0) (10 1 10 14 0.5 0.0 0.0 0) (15 1 15 24 0.5 0.0 0.1 1) (25 1 25 29 0.5 0.0 0.0 0) (30 1 30 99 1.0 0.0 0.0 0) (100 -2 0 0 0.0 0.0 0.0 0)) vals "env-channel 15 10 a" #__line__) (select-all) (if (fneq (selection-maxamp) 1.0) (snd-display #__line__ ";selection-maxamp in checker: ~A" (selection-maxamp))) (scale-selection-to 1.0) (check-edit-tree '((0 1 0 9 1.0 0.0 0.0 0) (10 1 10 14 0.5 0.0 0.0 0) (15 1 15 24 0.5 0.0 0.1 1) (25 1 25 29 0.5 0.0 0.0 0) (30 1 30 99 1.0 0.0 0.0 0) (100 -2 0 0 0.0 0.0 0.0 0)) vals "env-channel 15 10 b" #__line__) (set! (selection-position) 5) (set! (selection-framples) 10) (scale-selection-to .5) (do ((i 5 (+ i 1))) ((= i 15)) (set! (vals i) (* (vals i) 0.5))) (check-edit-tree '((0 1 0 4 1.0 0.0 0.0 0) (5 1 5 9 0.5 0.0 0.0 0) (10 1 10 14 0.25 0.0 0.0 0) (15 1 15 24 0.5 0.0 0.1 1) (25 1 25 29 0.5 0.0 0.0 0) (30 1 30 99 1.0 0.0 0.0 0) (100 -2 0 0 0.0 0.0 0.0 0)) vals "scale-selection-to .5" #__line__) (set! (sample 20) .1) (set! (vals 20) .1) (check-edit-tree '((0 1 0 4 1.0 0.0 0.0 0) (5 1 5 9 0.5 0.0 0.0 0) (10 1 10 14 0.25 0.0 0.0 0) (15 1 15 19 0.5 0.0 0.1 1) (20 2 0 0 1.0 0.0 0.0 0) (21 1 21 24 0.5 0.6 0.1 4) (25 1 25 29 0.5 0.0 0.0 0) (30 1 30 99 1.0 0.0 0.0 0) (100 -2 0 0 0.0 0.0 0.0 0)) vals "set 20 .1" #__line__) (reverse-channel 5 10) (do ((i 5 (+ i 1)) (j 14 (- j 1))) ((= i 10)) (let ((temp (vals i))) (set! (vals i) (vals j)) (set! (vals j) temp))) (check-edit-tree '((0 1 0 4 1.0 0.0 0.0 0) (5 3 0 9 1.0 0.0 0.0 0) (15 1 15 19 0.5 0.0 0.1 1) (20 2 0 0 1.0 0.0 0.0 0) (21 1 21 24 0.5 0.6 0.1 4) (25 1 25 29 0.5 0.0 0.0 0) (30 1 30 99 1.0 0.0 0.0 0) (100 -2 0 0 0.0 0.0 0.0 0)) vals "reverse-channel 5 10" #__line__) (if (fneq (selection-maxamp) .5) (snd-display #__line__ ";selection-maxamp before: ~A" (selection-maxamp))) (let ((mixvals (make-float-vector 10)) (old-sample4 (sample 4)) (old-sample5 (sample 5))) (fill! mixvals .1) (let ((id (mix-float-vector mixvals 4))) (do ((i 4 (+ i 1)) (j 0 (+ j 1))) ((= i 14)) (set! (vals i) (+ (vals i) (mixvals j)))) (check-edit-tree '((0 1 0 3 1.0 0.0 0.0 0) (4 1 4 4 1.0 0.0 0.0 1) (5 3 0 8 1.0 0.0 0.0 1) (14 3 9 9 1.0 0.0 0.0 0) (15 1 15 19 0.5 0.0 0.1 4) (20 2 0 0 1.0 0.0 0.0 0) (21 1 21 24 0.5 0.6 0.1 4) (25 1 25 29 0.5 0.0 0.0 0) (30 1 30 99 1.0 0.0 0.0 0) (100 -2 0 0 0.0 0.0 0.0 0)) vals (format #f "mix-float-vector (id: ~A (~A) [~A ~A] + .1 -> [~A ~A] [~A ~A]) 4 (.1)" id ind old-sample4 old-sample5 (sample 4) (sample 5) (vals 4) (vals 5)) #__line__))) ; (list global-position data-number local-position local-end scaler ramp0 ramp1 type) (delete-samples 28 12) (insert-silence 28 12) (do ((i 28 (+ i 1))) ((= i 40)) (set! (vals i) 0.0)) (let ((old-vals (copy vals))) (check-edit-tree '((0 1 0 3 1.0 0.0 0.0 0) (4 1 4 4 1.0 0.0 0.0 1) (5 3 0 8 1.0 0.0 0.0 1) (14 3 9 9 1.0 0.0 0.0 0) (15 1 15 19 0.5 0.0 0.1 4) (20 2 0 0 1.0 0.0 0.0 0) (21 1 21 24 0.5 0.6 0.1 4) (25 1 25 27 0.5 0.0 0.0 0) (28 -1 0 11 0.0 0.0 0.0 2) (40 1 40 99 1.0 0.0 0.0 0) (100 -2 0 0 0.0 0.0 0.0 0)) vals "delete/insert" #__line__) (if (fneq (selection-maxamp) .6) (snd-display #__line__ ";selection-maxamp after: ~A" (selection-maxamp))) (set! (selection-position) 50) (set! (selection-framples) 10) (scale-selection-by .1) (if (fneq (selection-maxamp) .1) (snd-display #__line__ ";re-selection-maxamp: ~A" (selection-maxamp))) (do ((i 50 (+ i 1))) ((= i 60)) (set! (vals i) .1)) (check-edit-tree '((0 1 0 3 1.0 0.0 0.0 0) (4 1 4 4 1.0 0.0 0.0 1) (5 3 0 8 1.0 0.0 0.0 1) (14 3 9 9 1.0 0.0 0.0 0) (15 1 15 19 0.5 0.0 0.1 4) (20 2 0 0 1.0 0.0 0.0 0) (21 1 21 24 0.5 0.6 0.1 4) (25 1 25 27 0.5 0.0 0.0 0) (28 -1 0 11 0.0 0.0 0.0 2) (40 1 40 49 1.0 0.0 0.0 0) (50 1 50 59 0.100000001490116 0.0 0.0 0) (60 1 60 99 1.0 0.0 0.0 0) (100 -2 0 0 0.0 0.0 0.0 0)) vals "scale-selection-by .1" #__line__) (env-channel (make-env '(0 0 1 1 2 0 3 0) :length 31 :base 0) 50 30) (let ((e (make-env '(0 0 1 1 2 0 3 0) :length 31 :base 0))) (do ((i 50 (+ i 1))) ((= i 80)) (set! (vals i) (* (vals i) (env e))))) (check-edit-tree '((0 1 0 3 1.0 0.0 0.0 0) (4 1 4 4 1.0 0.0 0.0 1) (5 3 0 8 1.0 0.0 0.0 1) (14 3 9 9 1.0 0.0 0.0 0) (15 1 15 19 0.5 0.0 0.1 4) (20 2 0 0 1.0 0.0 0.0 0) (21 1 21 24 0.5 0.6 0.1 4) (25 1 25 27 0.5 0.0 0.0 0) (28 -1 0 11 0.0 0.0 0.0 2) (40 1 40 49 1.0 0.0 0.0 0) (50 1 50 59 0.0 0.0 0.0 2) (60 1 60 60 0.0 0.0 0.0 2) (61 1 61 70 1.0 0.0 0.0 0) (71 1 71 79 0.0 0.0 0.0 2) (80 1 80 99 1.0 0.0 0.0 0) (100 -2 0 0 0.0 0.0 0.0 0)) vals "step env 30" #__line__) (undo-channel 2) (check-edit-tree '((0 1 0 3 1.0 0.0 0.0 0) (4 1 4 4 1.0 0.0 0.0 1) (5 3 0 8 1.0 0.0 0.0 1) (14 3 9 9 1.0 0.0 0.0 0) (15 1 15 19 0.5 0.0 0.1 4) (20 2 0 0 1.0 0.0 0.0 0) (21 1 21 24 0.5 0.6 0.1 4) (25 1 25 27 0.5 0.0 0.0 0) (28 -1 0 11 0.0 0.0 0.0 2) (40 1 40 99 1.0 0.0 0.0 0) (100 -2 0 0 0.0 0.0 0.0 0)) old-vals "undo to delete/insert (over step env)" #__line__)) (redo-channel 2) (check-edit-tree '((0 1 0 3 1.0 0.0 0.0 0) (4 1 4 4 1.0 0.0 0.0 1) (5 3 0 8 1.0 0.0 0.0 1) (14 3 9 9 1.0 0.0 0.0 0) (15 1 15 19 0.5 0.0 0.1 4) (20 2 0 0 1.0 0.0 0.0 0) (21 1 21 24 0.5 0.6 0.1 4) (25 1 25 27 0.5 0.0 0.0 0) (28 -1 0 11 0.0 0.0 0.0 2) (40 1 40 49 1.0 0.0 0.0 0) (50 1 50 59 0.0 0.0 0.0 2) (60 1 60 60 0.0 0.0 0.0 2) (61 1 61 70 1.0 0.0 0.0 0) (71 1 71 79 0.0 0.0 0.0 2) (80 1 80 99 1.0 0.0 0.0 0) (100 -2 0 0 0.0 0.0 0.0 0)) vals "redo past step env 30" #__line__) (set! (sample 75) -.5) (set! (vals 75) -.5) (let ((flt (make-one-zero 0.5 0.5)) (flt1 (make-one-zero 0.5 0.5))) (clm-channel flt 75 10) (do ((i 75 (+ i 1))) ((= i 85)) (set! (vals i) (one-zero flt1 (vals i)))) (check-edit-tree '((0 1 0 3 1.0 0.0 0.0 0) (4 1 4 4 1.0 0.0 0.0 1) (5 3 0 8 1.0 0.0 0.0 1) (14 3 9 9 1.0 0.0 0.0 0) (15 1 15 19 0.5 0.0 0.1 4) (20 2 0 0 1.0 0.0 0.0 0) (21 1 21 24 0.5 0.6 0.1 4) (25 1 25 27 0.5 0.0 0.0 0) (28 -1 0 11 0.0 0.0 0.0 2) (40 1 40 49 1.0 0.0 0.0 0) (50 1 50 59 0.0 0.0 0.0 2) (60 1 60 60 0.0 0.0 0.0 2) (61 1 61 70 1.0 0.0 0.0 0) (71 1 71 74 0.0 0.0 0.0 2) (75 6 0 9 1.0 0.0 0.0 0) (85 1 85 99 1.0 0.0 0.0 0) (100 -2 0 0 0.0 0.0 0.0 0)) vals "clm-channel 75 10" #__line__)) (map-channel (lambda (y) (* y 1 .5)) 3 11) ; extra "1" is needed for the tree expectation (do ((i 3 (+ i 1))) ((= i 14)) (set! (vals i) (* .5 (vals i)))) (check-edit-tree '((0 1 0 2 1.0 0.0 0.0 0) (3 8 0 10 1.0 0.0 0.0 0) (14 7 10 11 1.0 0.0 0.0 0) (16 1 16 19 0.5 0.1 0.1 4) (20 2 0 0 1.0 0.0 0.0 0) (21 1 21 24 0.5 0.6 0.1 4) (25 1 25 27 0.5 0.0 0.0 0) (28 -1 0 11 0.0 0.0 0.0 2) (40 1 40 49 1.0 0.0 0.0 0) (50 1 50 59 0.0 0.0 0.0 2) (60 1 60 60 0.0 0.0 0.0 2) (61 1 61 70 1.0 0.0 0.0 0) (71 1 71 74 0.0 0.0 0.0 2) (75 6 0 9 1.0 0.0 0.0 0) (85 1 85 99 1.0 0.0 0.0 0) (100 -2 0 0 0.0 0.0 0.0 0)) vals "map-channel 3 14" #__line__) (map-channel (let ((reader (make-sampler 50))) (lambda (y) (- y (next-sample reader)))) 0 25) (do ((i 0 (+ i 1)) (j 50 (+ j 1))) ((= i 25)) (set! (vals i) (- (vals i) (vals j)))) (check-edit-tree '((0 9 0 24 1.0 0.0 0.0 0) (25 1 25 27 0.5 0.0 0.0 0) (28 -1 0 11 0.0 0.0 0.0 2) (40 1 40 49 1.0 0.0 0.0 0) (50 1 50 59 0.0 0.0 0.0 2) (60 1 60 60 0.0 0.0 0.0 2) (61 1 61 70 1.0 0.0 0.0 0) (71 1 71 74 0.0 0.0 0.0 2) (75 6 0 9 1.0 0.0 0.0 0) (85 1 85 99 1.0 0.0 0.0 0) (100 -2 0 0 0.0 0.0 0.0 0)) vals "back set via map-channel" #__line__) (set! (selection-position) 20) (set! (selection-framples) 70) (env-selection '(0 0 1 1)) (if (fneq (selection-maxamp ind 0) 1.0) (snd-display #__line__ ";selection-maxamp after env-selection: ~A" (selection-maxamp ind 0))) (do ((i 20 (+ i 1)) (x 0.0) (incr (/ 1.0 69.0))) ((= i 90)) (set! (vals i) (* (vals i) x)) (set! x (+ x incr))) (check-edit-tree '((0 9 0 19 1.0 0.0 0.0 0) (20 9 20 24 1.0 0.0 0.014492753893137 4) (25 1 25 27 0.5 0.0724637657403946 0.014492753893137 4) (28 -1 0 11 0.0 0.0 0.0 2) (40 1 40 49 1.0 0.289855062961578 0.014492753893137 4) (50 1 50 59 0.0 0.0 0.0 2) (60 1 60 60 0.0 0.0 0.0 2) (61 1 61 70 1.0 0.594202876091003 0.014492753893137 4) (71 1 71 74 0.0 0.0 0.0 2) (75 6 0 9 1.0 0.797101438045502 0.014492753893137 4) (85 1 85 89 1.0 0.942028999328613 0.014492753893137 4) (90 1 90 99 1.0 0.0 0.0 0) (100 -2 0 0 0.0 0.0 0.0 0)) vals "env-selection" #__line__) (normalize-channel .5) (float-vector-scale! vals .5) (check-edit-tree '((0 9 0 19 0.5 0.0 0.0 0) (20 9 20 24 0.5 0.0 0.014492753893137 4) (25 1 25 27 0.25 0.0724637657403946 0.014492753893137 4) (28 -1 0 11 0.0 0.0 0.0 2) (40 1 40 49 0.5 0.289855062961578 0.014492753893137 4) (50 1 50 59 0.0 0.0 0.0 2) (60 1 60 60 0.0 0.0 0.0 2) (61 1 61 70 0.5 0.594202876091003 0.014492753893137 4) (71 1 71 74 0.0 0.0 0.0 2) (75 6 0 9 0.5 0.797101438045502 0.014492753893137 4) (85 1 85 89 0.5 0.942028999328613 0.014492753893137 4) (90 1 90 99 0.5 0.0 0.0 0) (100 -2 0 0 0.0 0.0 0.0 0)) vals "scale-to" #__line__) (if (fneq (selection-maxamp) .5) (snd-display #__line__ ";selection-maxamp after scale: ~A" (selection-maxamp))) (delete-samples 0 100) (insert-silence 0 100) (fill! vals 0.0) (check-edit-tree '((0 -1 0 99 0.0 0.0 0.0 0) (100 -2 0 0 0.0 0.0 0.0 0)) vals "second set..." #__line__) (set! (sample 50) .5) (set! (vals 50) .5) (check-edit-tree '((0 -1 0 49 0.0 0.0 0.0 2) (50 10 0 0 1.0 0.0 0.0 0) (51 -1 51 99 0.0 0.0 0.0 2) (100 -2 0 0 0.0 0.0 0.0 0)) vals "split silence" #__line__) (map-channel (lambda (y) 1.0) 0 25) (fill! vals 1.0 0 25) (check-edit-tree '((0 11 0 24 1.0 0.0 0.0 0) (25 -1 25 49 0.0 0.0 0.0 2) (50 10 0 0 1.0 0.0 0.0 0) (51 -1 51 99 0.0 0.0 0.0 2) (100 -2 0 0 0.0 0.0 0.0 0)) vals "clobber silence start" #__line__) (map-channel (lambda (y) 1.0) 75 25) (fill! vals 1.0 75 100) (check-edit-tree '((0 11 0 24 1.0 0.0 0.0 0) (25 -1 25 49 0.0 0.0 0.0 2) (50 10 0 0 1.0 0.0 0.0 0) (51 -1 51 74 0.0 0.0 0.0 2) (75 12 0 24 1.0 0.0 0.0 0) (100 -2 0 0 0.0 0.0 0.0 0)) vals "clobber silence end" #__line__) (scale-channel 0.0 0 100) (fill! vals 0.0) (check-edit-tree '((0 0 0 99 0.0 0.0 0.0 1) (100 -2 0 0 0.0 0.0 0.0 0)) vals "scale all to 0.0" #__line__) (let ((e (make-env '(0 0 1 1) :length 101)) (e1 (make-env '(0 0 1 1) :length 101))) (map-channel (lambda (y) (env e))) (do ((i 0 (+ i 1))) ((= i 100)) (set! (vals i) (env e1)))) (check-edit-tree '((0 13 0 99 1.0 0.0 0.0 0) (100 -2 0 0 0.0 0.0 0.0 0)) vals "env start" #__line__) (set! (sample 50) -.5) (set! (vals 50) -.5) (check-edit-tree '((0 13 0 49 1.0 0.0 0.0 0) (50 14 0 0 1.0 0.0 0.0 0) (51 13 51 99 1.0 0.0 0.0 0) (100 -2 0 0 0.0 0.0 0.0 0)) vals "split env segment" #__line__) (map-channel (lambda (y) 1.0) 0 25) (fill! vals 1.0 0 25) (check-edit-tree '((0 15 0 24 1.0 0.0 0.0 0) (25 13 25 49 1.0 0.0 0.0 0) (50 14 0 0 1.0 0.0 0.0 0) (51 13 51 99 1.0 0.0 0.0 0) (100 -2 0 0 0.0 0.0 0.0 0)) vals "clobber env start" #__line__) (map-channel (lambda (y) 1.0) 75 25) (fill! vals 1.0 75 100) (check-edit-tree '((0 15 0 24 1.0 0.0 0.0 0) (25 13 25 49 1.0 0.0 0.0 0) (50 14 0 0 1.0 0.0 0.0 0) (51 13 51 74 1.0 0.0 0.0 0) (75 16 0 24 1.0 0.0 0.0 0) (100 -2 0 0 0.0 0.0 0.0 0)) vals "clobber env end" #__line__) ;; this can't be expected to work anymore -- internal backup can change edit tree bounds ; (save-edit-history "hiho.scm") ; (revert-sound ind) ; (set! sfile ind) ; (load (string-append cwd "hiho.scm")) ; (check-edit-tree '((0 14 0 24 1.0 0.0 0.0 0) (25 12 25 49 1.0 0.0 0.0 0) (50 13 0 0 1.0 0.0 0.0 0) (51 12 51 74 1.0 0.0 0.0 0) (75 15 0 24 1.0 0.0 0.0 0) (100 -2 0 0 0.0 0.0 0.0 0)) ; vals "reload edits" #__line__) ; (if (not (equal? (edits) (list 27 0))) (snd-display #__line__ ";edits after reload: ~A" (edits))) ; (delete-file "hiho.scm") (env-channel (make-env '(0 1 1 0 2 1) :length 20) 50 20) (let ((e (make-env '(0 1 1 0 2 1) :length 20))) (do ((i 50 (+ i 1))) ((= i 70)) (set! (vals i) (* (env e) (vals i))))) (check-edit-tree '((0 15 0 24 1.0 0.0 0.0 0) (25 13 25 49 1.0 0.0 0.0 0) (50 14 0 0 1.0 1.0 -0.100000001490116 4) (51 13 51 59 1.0 0.899999976158142 -0.100000001490116 4) (60 13 60 69 1.0 0.0 0.111111111938953 4) (70 13 70 74 1.0 0.0 0.0 0) (75 16 0 24 1.0 0.0 0.0 0) (100 -2 0 0 0.0 0.0 0.0 0)) vals "env on env" #__line__) (env-channel (make-env '(0 1 1 0 2 1) :length 80) 10 80) (let ((e (make-env '(0 1 1 0 2 1) :length 80))) (do ((i 10 (+ i 1))) ((= i 90)) (set! (vals i) (* (env e) (vals i))))) (check-edit-tree '((0 15 0 9 1.0 0.0 0.0 0) (10 15 10 24 1.0 1.0 -0.025000000372529 4) (25 13 25 49 1.0 0.625 -0.025000000372529 4) (50 14 0 0 1.0 1.0 -0.100000001490116 6) (51 13 51 59 1.0 0.899999976158142 -0.100000001490116 6) (60 13 60 69 1.0 0.0 0.111111111938953 6) (70 13 70 74 1.0 0.512820541858673 0.0256410259753466 4) (75 16 0 14 1.0 0.64102566242218 0.0256410259753466 4) (90 16 15 24 1.0 0.0 0.0 0) (100 -2 0 0 0.0 0.0 0.0 0)) vals "env on env 2" #__line__) (env-channel (make-env '(0 1 1 0 2 1) :length 20) 50 20) (let ((e (make-env '(0 1 1 0 2 1) :length 20))) (do ((i 50 (+ i 1))) ((= i 70)) (set! (vals i) (* (env e) (vals i))))) (check-edit-tree '((0 15 0 9 1.0 0.0 0.0 0) (10 15 10 24 1.0 1.0 -0.025000000372529 4) (25 13 25 49 1.0 0.625 -0.025000000372529 4) (50 14 0 0 1.0 1.0 -0.100000001490116 10) (51 13 51 59 1.0 0.899999976158142 -0.100000001490116 10) (60 13 60 69 1.0 0.0 0.111111111938953 10) (70 13 70 74 1.0 0.512820541858673 0.0256410259753466 4) (75 16 0 14 1.0 0.64102566242218 0.0256410259753466 4) (90 16 15 24 1.0 0.0 0.0 0) (100 -2 0 0 0.0 0.0 0.0 0)) vals "env on env 3" #__line__) (delete-samples 10 20) (insert-silence 10 20) (fill! vals 0.0 10 30) (check-edit-tree '((0 15 0 9 1.0 0.0 0.0 0) (10 -1 0 19 0.0 0.0 0.0 2) (30 13 30 49 1.0 0.5 -0.025000000372529 4) (50 14 0 0 1.0 1.0 -0.100000001490116 10) (51 13 51 59 1.0 0.899999976158142 -0.100000001490116 10) (60 13 60 69 1.0 0.0 0.111111111938953 10) (70 13 70 74 1.0 0.512820541858673 0.0256410259753466 4) (75 16 0 14 1.0 0.64102566242218 0.0256410259753466 4) (90 16 15 24 1.0 0.0 0.0 0) (100 -2 0 0 0.0 0.0 0.0 0)) vals "env preclobbered" #__line__) (close-sound ind)) (for-each (lambda (dur) (let ((i1 (new-sound)) (v (make-float-vector dur 1.0))) (define (check-env name r e) (let ((v0 (make-float-vector dur)) (v1 (make-float-vector dur))) (do ((i 0 (+ i 1))) ((= i dur)) (set! (v0 i) (read-sample r))) (if (env? e) (do ((i 0 (+ i 1))) ((= i dur)) (float-vector-set! v1 i (env e))) (if (sampler? e) (do ((i 0 (+ i 1))) ((= i dur)) (float-vector-set! v1 i (read-sample e))) (do ((i 0 (+ i 1))) ((= i dur)) (float-vector-set! v1 i (e))))) (if (not (vequal v0 v1)) (snd-display #__line__ ";~A env check [~A]: ~A ~A" name r rv ev)))) (float-vector->channel v) (env-sound '(0 0 1 1)) (check-env 'ramp (make-sampler 0) (make-env '(0 0 1 1) :length dur)) (reverse-channel) (check-env 'rev-ramp (make-sampler 0) (make-env '(0 1 1 0) :length dur)) (undo 2) (env-sound '(0 0 1 1 2 0)) (check-env 'ramp (make-sampler 0) (make-env '(0 0 1 1 2 0) :length dur)) (let ((cur-read (make-sampler 0))) (reverse-channel) (let ((rev-read (make-sampler (- dur 1) i1 0 -1))) (check-env 'rev-pyr cur-read rev-read))) (undo 2) (env-sound '(0 0 1 1 2 0 3 1)) (check-env '3-ramp (make-sampler 0) (make-env '(0 0 1 1 2 0 3 1) :length dur)) (let ((cur-read (make-sampler 0))) (reverse-channel) (let ((rev-read (make-sampler (- dur 1) i1 0 -1))) (check-env 'rev-pyr cur-read rev-read))) (undo 2) (env-sound '(0 0 1 1 2 1 3 0)) (check-env 'sqoff (make-sampler 0) (make-env '(0 0 1 1 2 1 3 0) :length dur)) (undo 1) (env-sound '(0 0 1 .5 2 .5 3 0)) (check-env '5sqoff (make-sampler 0) (make-env '(0 0 1 .5 2 .5 3 0) :length dur)) (undo 1) (scale-channel .5) (env-sound '(0 0 1 1)) (check-env 'scl-ramp (make-sampler 0) (make-env '(0 0 1 1) :length dur :scaler .5)) (reverse-channel) (check-env 'scl-rev-ramp (make-sampler 0) (make-env '(0 1 1 0) :length dur :scaler .5)) (undo 2) (env-sound '(0 0 1 1 2 0)) (check-env 'scl-3-ramp (make-sampler 0) (make-env '(0 0 1 1 2 0) :length dur :scaler .5)) (let ((cur-read (make-sampler 0))) (reverse-channel) (let ((rev-read (make-sampler (- dur 1) i1 0 -1))) (check-env 'scl-rev-pyr cur-read rev-read))) (undo 3) (when (= dur 10000) (for-each (lambda (beg local-dur) (let ((bend (+ beg local-dur 1))) (env-sound '(0 0 1 1 2 0)) (scale-channel .5 beg local-dur) (check-env 'env+scl (make-sampler 0) (let ((e (make-env '(0 0 1 1 2 0) :length dur)) (ctr 0)) (lambda () (let ((val (env e))) (set! ctr (+ ctr 1)) (if (< beg ctr bend) (* val .5) val))))) (undo 2))) (list 0 0 1000 1000 4000 5000 6000 5000) (list 1000 6000 1000 4000 2000 1000 1000 5000))) (if (= dur 10000) (for-each (lambda (env-beg env-dur scl-beg scl-dur) (let ((eend (+ env-beg env-dur 1)) (send (+ scl-beg scl-dur 1))) (env-channel '(0 0 1 1 2 1 3 0) env-beg env-dur) (scale-channel .5 scl-beg scl-dur) (check-env 'env+scl-partial (make-sampler 0) (let ((e (make-env '(0 0 1 1 2 1 3 0) :length env-dur)) (ctr 0)) (lambda () (let ((val 1.0)) (set! ctr (+ ctr 1)) (if (< env-beg ctr eend) (set! val (env e))) (if (< scl-beg ctr send) (set! val (* val 0.5))) val)))) (undo 2))) (list 0 0 1000 1000 4000 5000 6000 5000) (list 1000 6000 1000 4000 2000 1000 1000 5000) (list 500 0 0 2000 5000 4000 0 8000) (list 200 10000 1500 1000 500 2000 2000 2000))) (env-sound '(0 0 1 1)) (env-sound '(0 0 1 1)) (check-env 'unenv-ramp (make-sampler 0) (let ((e (make-env '(0 0 1 1) :length dur))) (lambda () (let ((val (env e))) (* val val))))) (undo 2) (env-sound '(0 0 1 1)) (let ((v1 (make-float-vector 3 1.0))) (float-vector->channel v1 3 3) (let ((vals (channel->float-vector 0 10))) (if (not (vequal vals (float-vector 0.0 (/ 1.111 dur) (/ 2.222 dur) 1 1 1 (/ 6.66 dur) (/ 7.77 dur) (/ 8.88 dur) (/ 10.0 dur)))) (snd-display #__line__ "; 1 vals: ~A" vals)))) (undo 2) (env-sound '(0 0 1 1)) (let ((v1 (make-float-vector 3 1.0))) (delete-samples 3 3) (insert-samples 3 3 v1) (let ((vals (channel->float-vector 0 10))) (if (not (vequal vals (float-vector 0.0 (/ 1.111 dur) (/ 2.222 dur) 1 1 1 (/ 6.66 dur) (/ 7.77 dur) (/ 8.88 dur) (/ 10.0 dur)))) (snd-display #__line__ "; 2 vals: ~A" vals)))) (undo 3) (env-sound '(0 0 1 1)) (let ((v1 (make-float-vector 3 1.0))) (insert-samples 3 3 v1) (delete-samples 3 3)) (check-env '5-ramp (make-sampler 0) (make-env '(0 0 1 1) :length dur)) (undo 3) (env-sound '(0 0 1 1 2 0)) (let ((v1 (make-float-vector 3 1.0))) (if (= dur 10) (begin (float-vector->channel v1 3 3) (let ((vals (channel->float-vector 0 10))) (if (not (vequal vals (float-vector 0.0 .2 .4 1 1 1 .75 .5 .25 0))) (snd-display #__line__ "; 4 vals (~A): ~A" dur vals)))) (begin (fill! v1 0.0) (float-vector->channel v1 4998 3) (let ((vals (channel->float-vector 4995 10))) (if (not (vequal vals (float-vector 0.999 0.999 1.000 0.000 0.000 0.000 1.000 0.999 0.999 0.999))) (snd-display #__line__ "; 4 vals big: ~A" vals)))))) (undo 2) (if (= dur 10) (begin (env-sound '(0 0 1 1 2 0)) (let ((v1 (make-float-vector 3 1.0))) (delete-samples 3 3) (insert-samples 3 3 v1) (let ((vals (channel->float-vector 0 10))) (if (not (vequal vals (float-vector 0.0 .2 .4 1 1 1 .75 .5 .25 0))) (snd-display #__line__ "; 2 vals: ~A" vals)))) (undo 3) (env-sound '(0 0 1 1 2 0)) (let ((v1 (make-float-vector 3 1.0))) (float-vector->channel v1 0 3) (let ((vals (channel->float-vector 0 10))) (if (not (vequal vals (float-vector 1.000 1.000 1.000 0.600 0.800 1.000 0.750 0.500 0.250 0.000))) (snd-display #__line__ "; 4 vals: ~A" vals)))) (undo 2) (env-sound '(0 0 1 1 2 0)) (let ((v1 (make-float-vector 3 1.0))) (float-vector->channel v1 7 3) (let ((vals (channel->float-vector 0 10))) (if (not (vequal vals (float-vector 0.000 0.200 0.400 0.600 0.800 1.000 0.750 1.000 1.000 1.000))) (snd-display #__line__ "; 5 vals: ~A" vals)))) (undo 2))) (let ((file (file-name i1))) (close-sound i1) (if (file-exists? file) (delete-file file))) )) (list 10 10000)) (let ((ind (new-sound "fmv.snd" 1 22050 mus-ldouble mus-next "envd edit trees")) (vals (make-float-vector 10000))) (select-sound ind) (select-channel 0) (check-edit-tree '((0 0 0 0 0.0 0.0 0.0 1) (1 -2 0 0 0.0 0.0 0.0 0)) (make-float-vector 1) "initial new-sound" #__line__) (fill! vals 1.0) (set! (samples 0 10000) vals) (check-edit-tree '((0 1 0 9999 1.0 0.0 0.0 0) (10000 -2 0 0 0.0 0.0 0.0 0)) vals "envd set first samps to one" #__line__) (env-sound '(0 0 1 1)) (let ((e (make-env '(0 0 1 1) :length 10000))) (fill-float-vector vals (env e))) (check-edit-tree '((0 1 0 9999 1.0 0.0 1.00010001915507e-4 4) (10000 -2 0 0 0.0 0.0 0.0 0)) vals "env frag '(0 0 1 1)" #__line__) (delete-samples 1000 1000) (let ((v1 (make-float-vector 9000))) (do ((i 0 (+ i 1))) ((= i 1000)) (set! (v1 i) (vals i))) (do ((i 1000 (+ i 1)) (j 2000 (+ j 1))) ((= i 9000)) (set! (v1 i) (vals j))) (check-edit-tree '((0 1 0 999 1.0 0.0 1.00010001915507e-4 4) (1000 1 2000 9999 1.0 0.200020000338554 1.00010001915507e-4 4) (9000 -2 0 0 0.0 0.0 0.0 0)) v1 "env frag del" #__line__)) (undo 1) (delete-samples 9000 1000) (insert-samples 3000 1000 (make-float-vector 1000)) (do ((i 9999 (- i 1))) ((< i 4000)) (set! (vals i) (vals (- i 1000)))) (fill! vals 0.0 3000 4000) (check-edit-tree '((0 1 0 2999 1.0 0.0 1.00010001915507e-4 4) (3000 2 0 999 1.0 0.0 0.0 0) (4000 1 3000 8999 1.0 0.300029993057251 1.00010001915507e-4 4) (10000 -2 0 0 0.0 0.0 0.0 0)) vals "envd ins/del" #__line__) (delete-samples 0 1000) (insert-samples 0 1000 (make-float-vector 1000)) (fill! vals 0.0 0 1000) (check-edit-tree '((0 3 0 999 1.0 0.0 0.0 0) (1000 1 1000 2999 1.0 0.100010000169277 1.00010001915507e-4 4) (3000 2 0 999 1.0 0.0 0.0 0) (4000 1 3000 8999 1.0 0.300029993057251 1.00010001915507e-4 4) (10000 -2 0 0 0.0 0.0 0.0 0)) vals "envd predel" #__line__) (scale-by 0.5) (float-vector-scale! vals 0.5) (check-edit-tree '((0 3 0 999 0.5 0.0 0.0 0) (1000 1 1000 2999 0.5 0.100010000169277 1.00010001915507e-4 4) (3000 2 0 999 0.5 0.0 0.0 0) (4000 1 3000 8999 0.5 0.300029993057251 1.00010001915507e-4 4) (10000 -2 0 0 0.0 0.0 0.0 0)) vals "envd scl" #__line__) (reverse-channel) (do ((i 0 (+ i 1)) (j 9999 (- j 1))) ((= i 5000)) (let ((temp (vals i))) (set! (vals i) (vals j)) (set! (vals j) temp))) (check-edit-tree '((0 4 0 9999 1.0 0.0 0.0 0) (10000 -2 0 0 0.0 0.0 0.0 0)) vals "envd rev" #__line__) (revert-sound ind) (set! vals (make-float-vector 100000)) (fill! vals 1.0) (float-vector->channel vals 0 100000) (env-channel (make-env '(0 0 1 1 2 0) :length 10000) 30000 10000) (let ((e (make-env '(0 0 1 1 2 0) :length 10000))) (do ((i 30000 (+ i 1))) ((= i 40000)) (float-vector-set! vals i (env e)))) (check-edit-tree '((0 1 0 29999 1.0 0.0 0.0 0) (30000 1 30000 34999 1.0 0.0 1.99999994947575e-4 4) (35000 1 35000 39999 1.0 1.0 -2.00040012714453e-4 4) (40000 1 40000 99999 1.0 0.0 0.0 0) (100000 -2 0 0 0.0 0.0 0.0 0)) vals "partial env" #__line__) (scale-channel .5 10000 10000) (env-channel (make-env '(0 0 1 1 2 0) :length 10000) 30000 10000) ; env over env (let ((e (make-env '(0 0 1 1 2 0) :length 10000))) (do ((i 30000 (+ i 1))) ((= i 40000)) (float-vector-set! vals i (* (float-vector-ref vals i) (env e))))) (do ((i 10000 (+ i 1))) ((= i 20000)) (float-vector-set! vals i (* (float-vector-ref vals i) 0.5))) (check-edit-tree '((0 1 0 9999 1.0 0.0 0.0 0) (10000 1 10000 19999 0.5 0.0 0.0 0) (20000 1 20000 29999 1.0 0.0 0.0 0) (30000 1 30000 34999 1.0 0.0 1.99999994947575e-4 6) (35000 1 35000 39999 1.0 1.0 -2.00040012714453e-4 6) (40000 1 40000 99999 1.0 0.0 0.0 0) (100000 -2 0 0 0.0 0.0 0.0 0)) vals "env over env" #__line__) (env-channel (make-env '(0 0 1 1 2 0) :length 10000) 5000 10000) ; env over scl (let ((e (make-env '(0 0 1 1 2 0) :length 10000))) (do ((i 5000 (+ i 1))) ((= i 15000)) (float-vector-set! vals i (* (float-vector-ref vals i) (env e))))) (check-edit-tree '((0 1 0 4999 1.0 0.0 0.0 0) (5000 1 5000 9999 1.0 0.0 1.99999994947575e-4 4) (10000 1 10000 14999 0.5 1.0 -2.00040012714453e-4 4) (15000 1 15000 19999 0.5 0.0 0.0 0) (20000 1 20000 29999 1.0 0.0 0.0 0) (30000 1 30000 34999 1.0 0.0 1.99999994947575e-4 6) (35000 1 35000 39999 1.0 1.0 -2.00040012714453e-4 6) (40000 1 40000 99999 1.0 0.0 0.0 0) (100000 -2 0 0 0.0 0.0 0.0 0)) vals "env over scl" #__line__) (ramp-channel .5 -.5 25000 1000) (let ((e (make-env '(0 .5 1 -.5) :length 1000))) (do ((i 25000 (+ i 1))) ((= i 26000)) (float-vector-set! vals i (* (float-vector-ref vals i) (env e))))) (check-edit-tree '((0 1 0 4999 1.0 0.0 0.0 0) (5000 1 5000 9999 1.0 0.0 1.99999994947575e-4 4) (10000 1 10000 14999 0.5 1.0 -2.00040012714453e-4 4) (15000 1 15000 19999 0.5 0.0 0.0 0) (20000 1 20000 24999 1.0 0.0 0.0 0) (25000 1 25000 25999 1.0 0.5 -0.00100100098643452 4) (26000 1 26000 29999 1.0 0.0 0.0 0) (30000 1 30000 34999 1.0 0.0 1.99999994947575e-4 6) (35000 1 35000 39999 1.0 1.0 -2.00040012714453e-4 6) (40000 1 40000 99999 1.0 0.0 0.0 0) (100000 -2 0 0 0.0 0.0 0.0 0)) vals "ramp" #__line__) (scale-by -1.0) (float-vector-scale! vals -1.0) (check-edit-tree '((0 1 0 4999 -1.0 0.0 0.0 0) (5000 1 5000 9999 -1.0 0.0 1.99999994947575e-4 4) (10000 1 10000 14999 -0.5 1.0 -2.00040012714453e-4 4) (15000 1 15000 19999 -0.5 0.0 0.0 0) (20000 1 20000 24999 -1.0 0.0 0.0 0) (25000 1 25000 25999 -1.0 0.5 -0.00100100098643452 4) (26000 1 26000 29999 -1.0 0.0 0.0 0) (30000 1 30000 34999 -1.0 0.0 1.99999994947575e-4 6) (35000 1 35000 39999 -1.0 1.0 -2.00040012714453e-4 6) (40000 1 40000 99999 -1.0 0.0 0.0 0) (100000 -2 0 0 -0.0 0.0 0.0 0)) vals "invert" #__line__) (let ((reader (make-sampler 0 ind 0 1 (- (edit-position) 1)))) (map-channel (lambda (y) (+ (next-sample reader) y))) (check-edit-tree '((0 2 0 99999 1.0 0.0 0.0 0) (100000 -2 0 0 0.0 0.0 0.0 0)) (make-float-vector 100000) "invert and add" #__line__) (if (fneq (maxamp) 0.0) (snd-display #__line__ ";invert-and-add maxamp: ~A" (maxamp)))) (undo 1) (ramp-channel -1.0 1.0 50000 30000) (let ((e (make-env '(0 -1.0 1 1.0) :length 30000))) (do ((i 50000 (+ i 1))) ((= i 80000)) (float-vector-set! vals i (* (float-vector-ref vals i) (env e))))) (check-edit-tree '((0 1 0 4999 -1.0 0.0 0.0 0) (5000 1 5000 9999 -1.0 0.0 1.99999994947575e-4 4) (10000 1 10000 14999 -0.5 1.0 -2.00040012714453e-4 4) (15000 1 15000 19999 -0.5 0.0 0.0 0) (20000 1 20000 24999 -1.0 0.0 0.0 0) (25000 1 25000 25999 -1.0 0.5 -0.00100100098643452 4) (26000 1 26000 29999 -1.0 0.0 0.0 0) (30000 1 30000 34999 -1.0 0.0 1.99999994947575e-4 6) (35000 1 35000 39999 -1.0 1.0 -2.00040012714453e-4 6) (40000 1 40000 49999 -1.0 0.0 0.0 0) (50000 1 50000 79999 -1.0 -1.0 6.66688865749165e-5 4) (80000 1 80000 99999 -1.0 0.0 0.0 0) (100000 -2 0 0 -0.0 0.0 0.0 0)) vals "ramp" #__line__) (env-sound '(0 0 1 1)) (reverse-channel) (delete-samples 1 99999) (if (fneq (sample 0) -1.0) (snd-display #__line__ ";sample at end: ~A" (sample 0))) (if (not (= (framples) 1)) (snd-display #__line__ ";length at end: ~A" (framples))) (check-edit-tree '((0 2 0 0 1.0 0.0 0.0 0) (1 -2 0 0 0.0 0.0 0.0 0)) (make-float-vector 1 -1.0) "at end" #__line__) (close-sound ind)) ;; a special case that catches the round-off problem (let ((ind (open-sound "oboe.snd"))) (env-channel '(0.0 0.984011617147162 0.644050741979388 0.110976689002195 1.17272046995914 0.384709990674106 1.25650287720397 0.551452668245628 1.4389507801877 0.843827758574229 2.16614272265275 0.226832341237953)) (let ((val (sample 50827))) (if (or (not (number? val)) (fneq val 0.0)) (snd-display #__line__ ";round-off env: ~A" val))) (check-edit-tree '((0 0 0 15111 1.0 0.984011590480804 -5.77709688514005e-5 4) (15112 0 15112 27516 1.0 0.110976688563824 2.20663678192068e-5 4) (27517 0 27517 29482 1.0 0.384709984064102 8.4813182184007e-5 4) (29483 0 29483 33763 1.0 0.551452696323395 6.82959798723459e-5 4) (33764 0 33764 50827 1.0 0.843827784061432 -3.61598467861768e-5 4) (50828 -2 0 0 0.0 0.0 0.0 0)) #f "round-off test" #__line__) (revert-sound ind) (map-channel (lambda (y) 1.0)) (env-channel '(0 0 1 1 2 0)) (scale-channel .5 1000 1000) (let ((val (sample 800))) (if (fneq val .0314) (snd-display #__line__ ";scl on env trouble: ~A" val))) (check-edit-tree '((0 1 0 999 1.0 0.0 3.93483896914404e-5 4) (1000 1 1000 1999 0.5 0.0393483899533749 3.93483896914404e-5 4) (2000 1 2000 25413 1.0 0.0786967799067497 3.93483896914404e-5 4) (25414 1 25414 50827 1.0 1.0 -3.93499394704122e-5 4) (50828 -2 0 0 0.0 0.0 0.0 0)) #f "scl on env" #__line__) (revert-sound ind) (map-channel (lambda (y) 1.0)) (ramp-channel 0.0 1.0) (ramp-channel 0.0 1.0) (ramp-channel 0.0 1.0) (let ((val (sample 20000))) (if (fneq val (expt (/ 20000.0 50828) 3)) (snd-display #__line__ ";ramp-channels piled up: ~A" val))) (check-edit-tree '((0 1 0 50827 1.0 0.0 1.96745822904631e-5 10) (50828 -2 0 0 0.0 0.0 0.0 0)) #f "ramp upon ramp" #__line__) (revert-sound ind) (map-channel (lambda (y) 1.0)) (ramp-channel 0.5 1.0) ; val = 0.5 + (20000/50828)*0.5 (ramp-channel 0.0 0.5) ; val * (20000/50828)*0.5 (ramp-channel 0.1 0.4) ; val * (0.1 + (20000/50828)*0.3) (let* ((val (sample 20000)) (ratio (/ 20000.0 50828)) (val1 (+ 0.5 (* 0.5 ratio))) (val2 (* val1 0.5 ratio)) (val3 (* val2 (+ 0.1 (* ratio 0.3))))) (if (fneq val val3) (snd-display #__line__ ";ramp-channels piled up (2): ~A ~A" val val3))) (revert-sound ind) (env-channel '(0 0 1 1 2 0)) (check-edit-tree '((0 0 0 25413 1.0 0.0 3.93483896914404e-5 4) (25414 0 25414 50827 1.0 1.0 -3.93499394704122e-5 4) (50828 -2 0 0 0.0 0.0 0.0 0)) #f "env+scl 0" #__line__) (scale-channel .5 0 1000) (check-edit-tree '((0 0 0 999 0.5 0.0 3.93483896914404e-5 4) (1000 0 1000 25413 1.0 0.0393483899533749 3.93483896914404e-5 4) (25414 0 25414 50827 1.0 1.0 -3.93499394704122e-5 4) (50828 -2 0 0 0.0 0.0 0.0 0)) #f "env+scl 1" #__line__) (undo) (scale-channel .5 1000 1000) (check-edit-tree '((0 0 0 999 1.0 0.0 3.93483896914404e-5 4) (1000 0 1000 1999 0.5 0.0393483899533749 3.93483896914404e-5 4) (2000 0 2000 25413 1.0 0.0786967799067497 3.93483896914404e-5 4) (25414 0 25414 50827 1.0 1.0 -3.93499394704122e-5 4) (50828 -2 0 0 0.0 0.0 0.0 0)) #f "env+scl 2" #__line__) (undo) (scale-channel .5 0 25415) (check-edit-tree '((0 0 0 25413 0.5 0.0 3.93483896914404e-5 4) (25414 0 25414 25414 0.5 1.0 -3.93499394704122e-5 4) (25415 0 25415 50827 1.0 0.999960660934448 -3.93499394704122e-5 4) (50828 -2 0 0 0.0 0.0 0.0 0)) #f "env+scl 3" #__line__) (undo) (scale-channel .5 20000 10000) (check-edit-tree '((0 0 0 19999 1.0 0.0 3.93483896914404e-5 4) (20000 0 20000 25413 0.5 0.786967813968658 3.93483896914404e-5 4) (25414 0 25414 29999 0.5 1.0 -3.93499394704122e-5 4) (30000 0 30000 50827 1.0 0.819541156291962 -3.93499394704122e-5 4) (50828 -2 0 0 0.0 0.0 0.0 0)) #f "env+scl 4" #__line__) (undo) (scale-channel .5 30000 1000) (check-edit-tree '((0 0 0 25413 1.0 0.0 3.93483896914404e-5 4) (25414 0 25414 29999 1.0 1.0 -3.93499394704122e-5 4) (30000 0 30000 30999 0.5 0.819541156291962 -3.93499394704122e-5 4) (31000 0 31000 50827 1.0 0.780191242694855 -3.93499394704122e-5 4) (50828 -2 0 0 0.0 0.0 0.0 0)) #f "env+scl 5" #__line__) (undo) (scale-channel .5 25415 1000) (check-edit-tree '((0 0 0 25413 1.0 0.0 3.93483896914404e-5 4) (25414 0 25414 25414 1.0 1.0 -3.93499394704122e-5 4) (25415 0 25415 26414 0.5 0.999960660934448 -3.93499394704122e-5 4) (26415 0 26415 50827 1.0 0.960610687732697 -3.93499394704122e-5 4) (50828 -2 0 0 0.0 0.0 0.0 0)) #f "env+scl 6" #__line__) (undo) (scale-channel .5 40000 10828) (check-edit-tree '((0 0 0 25413 1.0 0.0 3.93483896914404e-5 4) (25414 0 25414 39999 1.0 1.0 -3.93499394704122e-5 4) (40000 0 40000 50827 0.5 0.426041781902313 -3.93499394704122e-5 4) (50828 -2 0 0 0.0 0.0 0.0 0)) #f "env+scl 7" #__line__) (close-sound ind)) (for-each (lambda (dur) (let ((i1 (new-sound)) (i2 (new-sound "fmv1.snd" 2 44100 mus-ldouble mus-next)) (v (make-float-vector dur 1.0))) (define (check-env name r e) (let ((v0 (make-float-vector dur)) (v1 (make-float-vector dur))) (if (env? e) (do ((i 0 (+ i 1))) ((= i dur)) (set! (v0 i) (env e))) (do ((i 0 (+ i 1))) ((= i dur)) (set! (v0 i) (e)))) (if (sampler? r) (do ((i 0 (+ i 1))) ((= i dur)) (float-vector-set! v1 i (read-sample r))) (do ((i 0 (+ i 1))) ((= i dur)) (float-vector-set! v1 i (r)))) (if (not (vequal v0 v1)) (snd-display #__line__ ";~A env check: ~A ~A" name v0 v1)))) (define (check-envs name r-maker e-maker) (check-env (format #f "~A-1-0" name) (r-maker i1 0) (e-maker i1 0)) (check-env (format #f "~A-2-0" name) (r-maker i2 0) (e-maker i2 0)) (check-env (format #f "~A-2-1" name) (r-maker i2 1) (e-maker i2 1))) (float-vector->channel v 0 dur i1) (float-vector->channel v 0 dur i2 0) (float-vector->channel v 0 dur i2 1) (set! (sync i1) 1) (set! (sync i2) 1) (env-sound '(0 0 1 1)) (check-envs 'ramps (lambda (s c) (make-sampler 0 s c)) (lambda (s c) (make-env '(0 0 1 1) :length dur))) (reverse-sound) (check-envs 'rev-ramps (lambda (s c) (make-sampler 0 s c)) (lambda (s c) (make-env '(0 1 1 0) :length dur))) (undo 2) (env-sound '(0 0 1 1 2 0)) (check-envs 'ramps (lambda (s c) (make-sampler 0 s c)) (lambda (s c) (make-env '(0 0 1 1 2 0) :length dur))) (undo 1) (scale-by .5) (env-sound '(0 0 1 1)) (check-envs 'scl-ramps (lambda (s c) (make-sampler 0 s c)) (lambda (s c) (make-env '(0 0 1 1) :length dur :scaler .5))) (reverse-sound) (check-envs 'scl-rev-ramps (lambda (s c) (make-sampler 0)) (lambda (s c) (make-env '(0 1 1 0) :length dur :scaler .5))) (undo 3) (env-sound '(0 0 1 1)) (env-sound '(0 0 1 1)) (check-envs 'unenv-ramps (lambda (s c) (make-sampler 0 s c)) (lambda (s c) (let ((e (make-env '(0 0 1 1) :length dur))) (lambda () (let ((val (env e))) (* val val)))))) (undo 2) (env-sound '(0 0 1 1)) (let ((v1 (make-float-vector 3 1.0))) (float-vector->channel v1 3 3 i1) (float-vector->channel v1 3 3 i2 0) (float-vector->channel v1 3 3 i2 1) (let ((vals (channel->float-vector 0 10 i1 0))) (if (not (vequal vals (float-vector 0.0 (/ 1.111 dur) (/ 2.222 dur) 1 1 1 (/ 6.66 dur) (/ 7.77 dur) (/ 8.88 dur) (/ 10.0 dur)))) (snd-display #__line__ "; 1 0 vals: ~A" vals)) (set! vals (channel->float-vector 0 10 i2 0)) (if (not (vequal vals (float-vector 0.0 (/ 1.111 dur) (/ 2.222 dur) 1 1 1 (/ 6.66 dur) (/ 7.77 dur) (/ 8.88 dur) (/ 10.0 dur)))) (snd-display #__line__ "; 2 0 vals: ~A" vals)) (set! vals (channel->float-vector 0 10 i2 1)) (if (not (vequal vals (float-vector 0.0 (/ 1.111 dur) (/ 2.222 dur) 1 1 1 (/ 6.66 dur) (/ 7.77 dur) (/ 8.88 dur) (/ 10.0 dur)))) (snd-display #__line__ "; 2 1 vals: ~A" vals)))) (let ((file (file-name i1))) (close-sound i1) (if (file-exists? file) (delete-file file))) (close-sound i2) )) (list 10 10000)) (if (null? (hook-functions initial-graph-hook)) (begin (set! (hook-functions update-hook) ()) (set! (hook-functions close-hook) ()) (set! (hook-functions exit-hook) ()))) (let ((data (map (lambda (sound) (if (file-exists? sound) (let ((ind (view-sound sound))) (set! (squelch-update ind) #t) (let ((times (map (lambda (function) (let ((start (real-time))) (function) (revert-sound) (- (real-time) start))) (list (lambda () (scale-channel 2.0)) reverse-channel (lambda () (env-channel '(0 0 1 1))) (lambda () (map-channel (lambda (y) (* y 2.0)))) (lambda () (scan-channel (lambda (y) (> y 1.0)))) (lambda () (pad-channel 0 2000)) (lambda () (float-vector->channel (make-float-vector 1000 .1) 0 1000)) (lambda () (clm-channel (make-two-zero .5 .5))) (lambda () (mix "pistol.snd" 12345)) (lambda () (src-channel 2.0)) (lambda () (delete-samples 10 200)) )))) (close-sound ind) times)))) (let ((away (string-append home-dir "/test/sound/away.snd"))) (if (file-exists? away) (list "1a.snd" "oboe.snd" "storm.snd" away) (list "1a.snd" "oboe.snd" "storm.snd" "lola.snd")))))) (snd-display #__line__ "; scl rev env map scn pad wrt clm mix src del") (snd-display #__line__ ";1a: ~{~A ~}" (map (lambda (a) (if (< a .005) " 0.0" (format #f "~6,2F" a))) (car data))) (snd-display #__line__ ";oboe: ~{~A ~}" (map (lambda (a) (if (< a .005) " 0.0" (format #f "~6,2F" a))) (cdar data))) (snd-display #__line__ ";storm:~{~A ~}" (map (lambda (a) (if (< a .005) " 0.0" (format #f "~6,2F" a))) (caddr data))) (if (pair? (cadddr data)) (snd-display #__line__ ";away: ~{~A ~}" (map (lambda (a) (if (< a .005) " 0.0" (format #f "~6,2F" a))) (cadddr data)))) ) (if (and all-args with-big-file) (let ((ind (view-sound big-file-name))) (catch #t (lambda () (set! (squelch-update ind) #t) (set! *selection-creates-region* #f) (let ((times (map (lambda (function) (let ((start (real-time))) (function) (update-time-graph) (revert-sound) (- (real-time) start))) (list (lambda () (let ((ma (maxamp))) (scale-channel 2.0) (if (fneq (maxamp) (* 2 ma)) (snd-display #__line__ ";bigger scale max: ~A ~A" ma (maxamp))))) (lambda () (let ((ma (maxamp))) (env-channel '(0 0 1 1)) (if (fneq (maxamp) ma) (snd-display #__line__ ";bigger env max: ~A ~A" ma (maxamp))))) (lambda () (pad-channel 0 2000)) (lambda () (pad-channel 1336909605 297671280)) (lambda () (insert-silence (+ (framples ind) 100) 100)) (lambda () (float-vector->channel (make-float-vector 1000 .1) 0 1000)) (lambda () (float-vector->channel (make-float-vector 1000 .1) (/ (framples ind) 2) 1000)) (lambda () (float-vector->channel (make-float-vector 1000 .1) (- (framples ind) 2000) 1000)) (lambda () (mix "pistol.snd" 12345)) (lambda () (delete-samples 10 200)) (lambda () (delete-samples 1336909605 297671280)) (lambda () (delete-samples (- (framples ind) 100) 10)) )))) (set! (squelch-update ind) #f) (snd-display #__line__ ";big: ~{~6,2F~}" times) )) (lambda args (set! (squelch-update) #f))) (close-sound ind))) (if with-big-file (letrec ((fieql (lambda (a b) (if (null? a) (null? b) (and (not (null? b)) (if (and (integer? (car a)) (not (= (car a) (car b)))) #f (if (and (number? (car a)) (fneq (car a) (car b))) #f (fieql (cdr a) (cdr b))))))))) (set! (hook-functions after-graph-hook) ()) (set! (hook-functions mouse-click-hook) ()) (let ((ind (open-sound big-file-name)) (vals (make-float-vector 100)) (old-vals #f) (new-vals #f) (maxa 0.0)) (if (= big-file-framples 0) (set! big-file-framples (framples ind))) (select-sound ind) (select-channel 0) (set! (squelch-update) #t) (if (not (fieql (edit-tree) (list (list 0 0 0 (- big-file-framples 1) 1.0 0.0 0.0 0) (list big-file-framples -2 0 0 0.0 0.0 0.0 0)))) (snd-display #__line__ ";bigger initial tree: ~A" (edit-tree))) (fill! vals 1.0) (set! maxa (maxamp)) (scale-channel 0.5) (set! old-vals (channel->float-vector (- (* (floor *clm-srate*) 50000) 50) 200)) (if (fneq (maxamp) (* 0.5 maxa)) (snd-display #__line__ ";bigger scale: ~A ~A" maxa (maxamp))) (set! (samples (* (floor *clm-srate*) 50000) 100) vals) (if (not (fieql (edit-tree) (list (list 0 0 0 2204999999 0.5 0.0 0.0 0) (list 2205000000 1 0 99 1.0 0.0 0.0 0) (list 2205000100 0 2205000100 (- big-file-framples 1) 0.5 0.0 0.0 0) (list big-file-framples -2 0 0 0.0 0.0 0.0 0)))) (snd-display #__line__ ";bigger set tree: ~A" (edit-tree))) (set! new-vals (channel->float-vector (- (* (floor *clm-srate*) 50000) 50) 200)) (do ((i 50 (+ i 1))) ((= i 150)) (set! (old-vals i) 1.0)) (if (not (vequal new-vals old-vals)) (snd-display #__line__ ";bigger set ~A ~A" old-vals new-vals)) (env-channel (make-env '(0 0 1 1) :length (* (floor *clm-srate*) 60000)) 1000 (* (floor *clm-srate*) 60000)) (if (not (fieql (edit-tree) (list (list 0 0 0 999 0.5 0.0 0.0 0) (list 1000 0 1000 2204999999 0.5 1.12130420080871e-17 0.83333295583725 1) (list 2205000000 1 0 99 1.0 0.83333295583725 0.833333015441895 1) (list 2205000100 0 2205000100 2646000999 0.5 0.833333015441895 1.0 1) (list 2646001000 0 2646001000 (- big-file-framples 1) 0.5 0.0 0.0 0) (list big-file-framples -2 0 0 0.0 0.0 0.0 0)))) (snd-display #__line__ ";bigger with env: ~A" (edit-tree))) (revert-sound ind) (env-channel (make-env '(0 0 1 1 2 0) :length 101) (* (floor *clm-srate*) 50000) 100) (if (not (fieql (edit-tree) (list (list 0 0 0 2204999999 1.0 0.0 0.0 0) (list 2205000000 0 2205000000 2205000050 1.0 4.47034825823422e-10 1.0 2) (list 2205000051 0 2205000051 2205000099 1.0 0.979591846466064 -5.55111512312578e-17 2) (list 2205000100 0 2205000100 (- big-file-framples 1) 1.0 0.0 0.0 0) (list big-file-framples -2 0 0 0.0 0.0 0.0 0)))) (snd-display #__line__ ";bigger short env: ~A" (edit-tree))) (let ((r (make-sampler (+ 75 (* (floor *clm-srate*) 50000)))) (v (make-float-vector 10))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v i) (read-sample r))) (if (not (vequal v (float-vector -0.021 -0.020 -0.020 -0.019 -0.018 -0.017 -0.016 -0.016 -0.015 -0.014))) (snd-display #__line__ ";bigger short env vals: ~A" v))) (revert-sound) (let ((v (channel->float-vector (+ 75 (* (floor *clm-srate*) 50000)) 10))) (if (not (vequal v (float-vector -0.042 -0.043 -0.044 -0.045 -0.045 -0.045 -0.045 -0.045 -0.045 -0.046))) (snd-display #__line__ ";bigger no env vals: ~A" v))) (scale-to 1.0) (if (fneq (maxamp) 1.0) (snd-display #__line__ ";bigger scale-to 1.0 maxamp: ~A" (maxamp))) (set! (sample (* (floor *clm-srate*) 51000)) 0.0) (if (not (fieql (edit-tree) (list (list 0 0 0 2249099999 1.18574941158295 0.0 0.0 0) (list 2249100000 1 0 0 1.0 0.0 0.0 0) (list 2249100001 0 2249100001 (- big-file-framples 1) 1.18574941158295 0.0 0.0 0) (list big-file-framples -2 0 0 0.0 0.0 0.0 0)))) (snd-display #__line__ ";bigger set 0 samp: ~A" (edit-tree))) (if (fneq (sample (* (floor *clm-srate*) 51000)) 0.0) (snd-display #__line__ ";bigger 0 samp: ~A" (sample (* (floor *clm-srate*) 51000)))) (delete-samples (* (floor *clm-srate*) 52000) 100) (if (not (= (framples) (- big-file-framples 100))) (snd-display #__line__ ";bigger deletion framples: ~A (~A)" (framples) (- big-file-framples 100))) (if (not (= (framples ind 0 0) big-file-framples)) (snd-display #__line__ ";bigger edpos deletion framples: ~A (~A)" (framples ind 0 0) big-file-framples)) (if (not (= (framples ind 0 (edit-position)) (- big-file-framples 100))) (snd-display #__line__ ";bigger ed deletion framples: ~A (~A)" (framples ind 0 (edit-position)) (- big-file-framples 100))) (if (not (fieql (edit-tree) (list (list 0 0 0 2249099999 1.18574941158295 0.0 0.0 0) (list 2249100000 1 0 0 1.0 0.0 0.0 0) (list 2249100001 0 2249100001 2293199999 1.18574941158295 0.0 0.0 0) (list 2293200000 0 2293200100 (- big-file-framples 1) 1.18574941158295 0.0 0.0 0) (list (- big-file-framples 100) -2 0 0 0.0 0.0 0.0 0)))) (snd-display #__line__ ";bigger deletion: ~A" (edit-tree))) (delete-samples 954624868 67) (revert-sound) (delete-samples 1000 (* (floor *clm-srate*) 50000)) (if (not (= (framples) (- big-file-framples (* (floor *clm-srate*) 50000)))) (snd-display #__line__ ";bigger big deletion: ~A" (framples))) (if (not (fieql (edit-tree) (list (list 0 0 0 999 1.0 0.0 0.0 0) (list 1000 0 1085232704 (- big-file-framples 1) 1.0 0.0 0.0 0) (list 970200000 -2 0 0 0.0 0.0 0.0 0)))) (snd-display #__line__ ";bigger big delete: ~A" (edit-tree))) (insert-silence 0 (* (floor *clm-srate*) 50000)) (if (not (= (framples) big-file-framples)) (snd-display #__line__ ";bigger silence: ~A (~A)" (framples) big-file-framples)) (if (not (fieql (edit-tree) (list (list 0 -1 0 2204999999 0.0 0.0 0.0 0) (list 2205000000 0 0 999 1.0 0.0 0.0 0) (list 2205001000 0 1085232704 (- big-file-framples 1) 1.0 0.0 0.0 0) (list big-file-framples -2 0 0 0.0 0.0 0.0 0)))) (snd-display #__line__ ";bigger pad: ~A" (edit-tree))) (revert-sound) (pad-channel (* (floor *clm-srate*) 50000) 100) (if (fneq (sample (+ (* (floor *clm-srate*) 50000) 10)) 0.0) (snd-display #__line__ ";bigger pad samp: ~A" (sample (+ (* (floor *clm-srate*) 50000) 10)))) (if (not (= (framples) (+ big-file-framples 100))) (snd-display #__line__ ";bigger pad framples: ~A (~A)" (framples) (+ big-file-framples 100))) (map-channel (lambda (y) (+ y .2)) (* (floor *clm-srate*) 50000) 10) (if (fneq (sample (+ (* (floor *clm-srate*) 50000) 1)) 0.2) (snd-display #__line__ ";bigger map samp: ~A" (sample (+ (* (floor *clm-srate*) 50000) 1)))) (if (not (fieql (edit-tree) (list (list 0 0 0 2204999999 1.0 0.0 0.0 0) (list 2205000000 1 0 9 1.0 0.0 0.0 0) (list 2205000010 -1 10 99 0.0 0.0 0.0 0) (list 2205000100 0 2205000000 (- big-file-framples 1) 1.0 0.0 0.0 0) (list (+ big-file-framples 100) -2 0 0 0.0 0.0 0.0 0)))) (snd-display #__line__ ";bigger map: ~A" (edit-tree))) (save-edit-history "hiho.scm") (revert-sound) (set! sfile ind) (load (string-append cwd "hiho.scm")) (if (not (fieql (edit-tree) (list (list 0 0 0 2204999999 1.0 0.0 0.0 0) (list 2205000000 1 0 9 1.0 0.0 0.0 0) (list 2205000010 -1 10 99 0.0 0.0 0.0 0) (list 2205000100 0 2205000000 (- big-file-framples 1) 1.0 0.0 0.0 0) (list (+ big-file-framples 100) -2 0 0 0.0 0.0 0.0 0)))) (snd-display #__line__ ";bigger reload: ~A" (edit-tree))) (delete-file "hiho.scm") (let ((flt (make-one-zero 0.5 0.5))) (let ((lvals (channel->float-vector (+ 1000 (* (floor *clm-srate*) 65000)) 10 ind 0 0))) (if (not (vequal lvals (float-vector -0.006 0.052 0.103 0.146 0.182 0.210 0.232 0.249 0.262 0.272))) (snd-display #__line__ ";bigger (orig) vals: ~A" lvals)) (clm-channel flt (+ (* (floor *clm-srate*) 65000) 1000) 10) (if (not (fieql (edit-tree) (list (list 0 0 0 2204999999 1.0 0.0 0.0 0) (list 2205000000 1 0 9 1.0 0.0 0.0 0) (list 2205000010 -1 10 99 0.0 0.0 0.0 0) (list 2205000100 0 2205000000 2866499899 1.0 0.0 0.0 0) (list 2866500000 2 0 9 1.0 0.0 0.0 0) (list 2866500010 0 2866499910 (- big-file-framples 1) 1.0 0.0 0.0 0) (list (+ big-file-framples 100) -2 0 0 0.0 0.0 0.0 0)))) (snd-display #__line__ ";bigger clm: ~A" (edit-tree))) (if (not (vequal (channel->float-vector (+ 1000 (* (floor *clm-srate*) 65000)) 10) (float-vector -0.006 0.015 0.065 0.107 0.142 0.169 0.190 0.205 0.216 0.222))) (snd-display #__line__ ";bigger clm vals: ~A" (channel->float-vector (+ 1000 (* (floor *clm-srate*) 65000)) 10))) (let ((r (make-readin big-file-name :start (+ 1000 (* (floor *clm-srate*) 65000)))) (v (make-float-vector 10))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v i) (readin r))) (if (not (vequal v lvals)) (snd-display #__line__ ";bigger (orig) readin vals: ~A (~A)" v lvals))))) (revert-sound) (let ((found (scan-channel (lambda (y) (> y .5)) (* (floor *clm-srate*) 50000)))) (if (not (equal? found (list #t 2205000925))) (snd-display #__line__ ";bigger scan: ~A" found))) (set! (squelch-update) #f) (close-sound ind)))) (let ((ind (new-sound "fmv.snd" :header-type mus-next :sample-type mus-ldouble))) (set! *sinc-width* 10) (pad-channel 0 1000 ind) (set! (sample 100) 0.5) (if (fneq (sample 100 ind 0 2) 0.5) (snd-display #__line__ ";sample 100 (2): ~A" (sample 100 ind 0 2))) (if (fneq (sample 100 ind 0 1) 0.0) (snd-display #__line__ ";sample 100 (1): ~A" (sample 100 ind 0 1))) (src-channel 0.5) (let ((mx (maxamp ind 0))) (if (fneq mx 0.5) (snd-display #__line__ ";src-channel max .5: ~A" mx))) (if (fneq (sample 200) 0.5) (snd-display #__line__ ";src-channel 0.5 200: ~A" (sample 200))) (if (not (vequal (channel->float-vector 180 40 ind 0) (float-vector 0.000 -0.000 0.000 0.001 -0.000 -0.003 0.000 0.007 -0.000 -0.012 0.000 0.020 -0.000 -0.033 0.000 0.054 -0.000 -0.100 -0.000 0.316 0.500 0.316 -0.000 -0.100 -0.000 0.054 0.000 -0.033 -0.000 0.020 0.000 -0.012 -0.000 0.007 0.000 -0.003 -0.000 0.001 0.000 -0.000))) (snd-display #__line__ ";src-channel 0.5 -> ~A" (channel->float-vector 180 40 ind 0))) (undo 1 ind 0) (src-channel 0.25) (let ((mx (maxamp ind 0))) (if (fneq mx 0.5) (snd-display #__line__ ";src-channel max .25: ~A" mx))) (if (fneq (sample 400) 0.5) (snd-display #__line__ ";src-channel 0.25 400: ~A" (sample 400))) (if (not (vequal (channel->float-vector 360 80 ind 0) (float-vector 0.000 -0.000 -0.000 -0.000 0.000 0.000 0.001 0.001 -0.000 -0.002 -0.003 -0.003 0.000 0.004 0.007 0.006 -0.000 -0.008 -0.012 -0.010 0.000 0.013 0.020 0.016 -0.000 -0.021 -0.033 -0.026 0.000 0.034 0.054 0.044 -0.000 -0.060 -0.100 -0.087 -0.000 0.148 0.316 0.449 0.500 0.449 0.316 0.148 -0.000 -0.087 -0.100 -0.060 -0.000 0.044 0.054 0.034 0.000 -0.026 -0.033 -0.021 -0.000 0.016 0.020 0.013 0.000 -0.010 -0.012 -0.008 -0.000 0.006 0.007 0.004 0.000 -0.003 -0.003 -0.002 -0.000 0.001 0.001 0.000 0.000 -0.000 -0.000 -0.000))) (snd-display #__line__ ";src-channel 0.25 -> ~A" (channel->float-vector 360 80 ind 0))) (undo 2 ind 0) ;(map-channel (let ((i 0)) (lambda (y) (let ((val (sin (* i (/ pi 100))))) (set! i (+ i 1)) (* .5 val))))) (let ((e (make-env (list 0.0 0.0 1.0 1.0) :scaler (* .01 pi (- (framples) 1.0)) :length (framples)))) (map-channel (lambda (y) (* .5 (sin (env e)))))) (for-each (lambda (sr df) (src-channel sr) (if (> (abs (- (maxamp ind 0) .5)) df) (snd-display #__line__ ";src-channel sine ~A: ~A" sr (maxamp ind 0))) (if (integer? sr) (let ((r0 (make-sampler 0)) (r1 (make-sampler 0 ind 0 1 (- (edit-position) 1))) (sri (floor sr))) (do ((i 0 (+ i 1))) ((= i 500)) (let ((diff (abs (- (r0) (r1))))) (if (> diff df) (snd-display #__line__ ";src-channel ~A diff ~D: ~A" sr i diff)) (do ((j 1 (+ j 1))) ((= j sri)) (r1)))))) (do ((i 0 (+ i 1))) ((= i 50)) (let ((s1 (sample i ind 0 (edit-position))) (s2 (sample (round (* sr i)) ind 0 (- (edit-position) 1))) (s3 (sample i ind 0 1))) (if (> (abs (- s1 s2)) df) (snd-display #__line__ ";sample ~D src(~A): ~A ~A" i sr s1 s2)) (if (fneq s3 0.0) (snd-display #__line__ ";sample ~D (1): ~A" i s3)))) (undo 1 ind 0)) (list 2.0 1.5 3.0 3.14) (list 0.008 0.01 0.015 0.025)) (close-sound ind) (set! ind (open-sound "oboe.snd")) (let ((orig-max (maxamp ind 0))) (for-each (lambda (sr df) (src-channel sr) (if (> (abs (- (maxamp ind 0) orig-max)) df) (snd-display #__line__ ";src-channel oboe ~A: ~A ~A" sr orig-max (maxamp ind 0))) (if (integer? sr) (let ((r0 (make-sampler 0)) (r1 (make-sampler 0 ind 0 1 (- (edit-position) 1))) (sri (floor sr))) (do ((i 0 (+ i 1))) ((= i 5000)) (let ((diff (abs (- (r0) (r1))))) (if (> diff df) (snd-display #__line__ ";src-channel oboe ~A diff ~D: ~A" sr i diff)) (do ((j 1 (+ j 1))) ((= j sri)) (r1)))))) (undo 1 ind 0)) (list 2.0 1.5 3.0 3.14) (list 0.008 0.01 0.015 0.025)) (for-each (lambda (sr df) (src-channel sr) (if (> (abs (- (maxamp ind 0) orig-max)) df) (snd-display #__line__ ";src-channel oboe ~A: ~A ~A" sr orig-max (maxamp ind 0))) (do ((i 0 (+ i 1))) ((= i 50)) (let* ((samp (* i 100)) (s1 (sample samp ind 0 (edit-position))) (s2 (sample (floor (* sr samp)) ind 0 (- (edit-position) 1)))) (if (> (abs (- s1 s2)) df) (snd-display #__line__ ";sample ~D oboe src(~A): ~A ~A" i sr s1 s2)))) (undo 1 ind 0) (amp-envs-equal? ind 0 (edit-position) (+ 1 (edit-position)) .01)) (list 0.5 0.25 0.9 0.1) (list 0.001 0.001 0.001 0.001))) (revert-sound ind) (scale-by 2.0) (scale-by 0.5) (amp-envs-equal? ind 0 (edit-position) (- (edit-position) 2) .001) (revert-sound ind) (close-sound ind)) ;; recursion tests (let ((ind (open-sound "oboe.snd"))) (for-each (lambda (n) (let ((val (scan-channel (lambda (y) (let ((bigger (scan-channel (lambda (n5) (> n5 .1))))) bigger))))) (if (not (eqv? val 0)) (snd-display #__line__ ";scan-channel in scan-channel (opt ~A): ~A" n val))) (let ((hi (make-float-vector 3)) (ho (make-float-vector 3))) (fill-float-vector hi (if (scan-channel (lambda (y) (> y .1))) 1.0 0.0)) (if (not (vequal hi (float-vector 1.0 1.0 1.0))) (snd-display #__line__ ";fill-float-vector with scan-channel (opt ~A): ~A" n hi))) (let ((val (scan-channel (lambda (y) (scan-channel (lambda (n6) (> n6 .1))))))) (if (not (= val 0)) (snd-display #__line__ ";find with find: ~A" val))) (let ((val (scan-channel (lambda (y) (scan-channel (lambda (n7) (> n7 .1))))))) (if (not (= val 0)) (snd-display #__line__ ";find with scan-channel: ~A" val))) (let ((mx (maxamp ind 0)) (val (scan-channel (lambda (y) (map-channel (lambda (n) (* n 2.0))) #t)))) (if (not (eqv? val 0)) (snd-display #__line__ ";scan-channel with map-channel: ~A" val)) (if (fneq mx (/ (maxamp ind 0) 2)) (snd-display #__line__ ";scan+map max: ~A ~A" mx (maxamp ind 0))) (if (not (= (edit-position ind 0) 1)) (snd-display #__line__ ";scan+map edit-pos: ~A" (edit-position ind 0))) (revert-sound ind) (map-channel (let ((ctr 0)) (lambda (y) (if (= ctr 0) (map-channel (lambda (n) (* n 2.0)))) (set! ctr 1) y)) 0 3) (if (fneq mx (maxamp ind 0)) (snd-display #__line__ ";map+map max 2: ~A ~A" mx (maxamp ind 0))) (if (not (= (edit-position ind 0) 2)) (snd-display #__line__ ";map+map edit-pos: ~A" (edit-position ind 0))) (if (fneq mx (/ (maxamp ind 0 1) 2)) (snd-display #__line__ ";map+map max 1: ~A ~A" mx (maxamp ind 0 1))) (revert-sound ind)) ) (list 0 5)) (close-sound ind)) (let ((ind (open-sound "oboe.snd"))) (for-each (lambda (func beg dur len) (let ((old-len (framples ind))) (func beg dur) (if (not (= (framples ind) len)) (snd-display #__line__ ";(~A ~A ~A) with ~A -> ~A (~A)?" func beg dur old-len (framples ind) len)))) (list (lambda (beg dur) (env-channel '(0 0 1 1) beg dur)) (lambda (beg dur) (map-channel (lambda (y) (* y .5)) beg dur)) reverse-channel (lambda (beg dur) (scale-channel 2.0 beg dur)) (lambda (beg dur) (float-vector->channel (make-float-vector dur) beg dur)) smooth-channel pad-channel (lambda (beg dur) (src-channel 0.5 beg dur)) insert-silence) (list 0 0 0 0 0 0 0 0 0) (list 1000 1000 1000 1000 1000 1000 1000 1000 1000) (list 50828 50828 50828 50828 50828 50828 51828 52829 53829)) (revert-sound ind) (for-each (lambda (beg dur len) (let ((old-len (framples ind))) (pad-channel beg dur) (if (not (= (framples ind) len)) (snd-display #__line__ ";(pad-channel ~A ~A) with ~A -> ~A (~A)?" beg dur old-len (framples ind) len)))) (list 1000 60000 0 62000 62000 62004) (list 1000 1000 1000 1 2 1) (list 51828 61000 62000 62001 62003 62005)) (revert-sound ind) (for-each (lambda (func dur len) (let ((old-len (framples ind))) (func (+ old-len 100) dur) (if (not (= (framples ind) len)) (snd-display #__line__ ";(~A ~A) with ~A -> ~A (~A)?" func dur old-len (framples ind) len)))) (list (lambda (beg dur) (env-channel '(0 0 1 1) beg dur)) reverse-channel (lambda (beg dur) (scale-channel 2.0 beg dur)) (lambda (beg dur) (scale-sound-by 2.0 beg dur)) (lambda (beg dur) (float-vector->channel (make-float-vector dur) beg dur)) smooth-channel pad-channel (lambda (beg dur) (src-channel 0.5 beg dur)) insert-silence (lambda (beg dur) (env-sound '(0 0 1 1) beg dur)) ) (list 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000) (list 50828 50828 50828 50828 51928 51928 53028 53028 54028 54028)) (revert-sound ind) (let ((len (floor (* 1.25 (framples))))) (do ((i 0 (+ i 1))) ((= i 100)) (case (if (zero? test-16) 3 (floor (random 10))) ((0) (pad-channel (random len) (random 1000))) ((1) (env-channel '(0 0 1 1 2 0) (random len) (random 1000))) ((2) (env-sound '(0 0 1 1 2 0) (random len) (random 1000))) ((3) (scale-channel (random 1.0) (random len) (random 1000))) ((4) (scale-sound-by (random 1.0) (random len) (random 1000))) ((5) (src-channel (+ .9 (random .2)) (random len) (random 1000))) ((6) (ramp-channel (random 1.0) (random 1.0) (random len) (random 1000))) ((7) (reverse-channel (random len) (random 1000))) ((8) (let ((dur (max 2 (floor (random 100))))) (float-vector->channel (make-float-vector dur) (random len) dur))) ((9) (map-channel (lambda (y) (* y 2.0)) (random (floor (/ (framples) 2))) (random 1000)))))) (close-sound ind)) (let ((ind (open-sound "oboe.snd"))) (if (fneq (maxamp) 0.14724731445312) (snd-display #__line__ ";oboe max: ~A (should be ~A)~%" (maxamp) 0.14724731445312)) (if (not (= (maxamp-position) 24971)) (snd-display #__line__ ";oboe max pos: ~A (should be ~A)~%" (maxamp-position) 24971)) (if (fneq (abs (sample (maxamp-position))) (maxamp)) (snd-display #__line__ ";oboe maxes: ~A ~A~%" (maxamp) (abs (sample (maxamp-position))))) ;; insert zeros (pad-channel 0 100) (if (fneq (maxamp) 0.14724731445312) (snd-display #__line__ ";oboe pad 0 100 max: ~A (should be ~A)~%" (maxamp) 0.14724731445312)) (if (not (= (maxamp-position) 25071)) (snd-display #__line__ ";oboe pad 0 100 max pos: ~A (should be ~A)~%" (maxamp-position) 25071)) (if (fneq (abs (sample (maxamp-position))) (maxamp)) (snd-display #__line__ ";oboe maxes: ~A ~A~%" (maxamp) (abs (sample (maxamp-position))))) (revert-sound) (pad-channel 25000 100) (if (fneq (maxamp) 0.14724731445312) (snd-display #__line__ ";oboe pad 25000 100 max: ~A (should be ~A)~%" (maxamp) 0.14724731445312)) (if (not (= (maxamp-position) 24971)) (snd-display #__line__ ";oboe pad 25000 100 max pos: ~A (should be ~A)~%" (maxamp-position) 24971)) (if (fneq (abs (sample (maxamp-position))) (maxamp)) (snd-display #__line__ ";oboe maxes: ~A ~A~%" (maxamp) (abs (sample (maxamp-position))))) (revert-sound) (pad-channel 24971 100) (if (fneq (maxamp) 0.14724731445312) (snd-display #__line__ ";oboe pad 24971 100 max: ~A (should be ~A)~%" (maxamp) 0.14724731445312)) (if (not (= (maxamp-position) 25071)) (snd-display #__line__ ";oboe pad 24971 100 max pos: ~A (should be ~A)~%" (maxamp-position) 25071)) (if (fneq (abs (sample (maxamp-position))) (maxamp)) (snd-display #__line__ ";oboe maxes: ~A ~A~%" (maxamp) (abs (sample (maxamp-position))))) (revert-sound) (pad-channel 24972 100) (if (fneq (maxamp) 0.14724731445312) (snd-display #__line__ ";oboe pad 24972 100 max: ~A (should be ~A)~%" (maxamp) 0.14724731445312)) (if (not (= (maxamp-position) 24971)) (snd-display #__line__ ";oboe pad 24972 100 max pos: ~A (should be ~A)~%" (maxamp-position) 24971)) (if (fneq (abs (sample (maxamp-position))) (maxamp)) (snd-display #__line__ ";oboe maxes: ~A ~A~%" (maxamp) (abs (sample (maxamp-position))))) (revert-sound) (pad-channel 65000 100) (if (fneq (maxamp) 0.14724731445312) (snd-display #__line__ ";oboe pad 65000 100 max: ~A (should be ~A)~%" (maxamp) 0.14724731445312)) (if (not (= (maxamp-position) 24971)) (snd-display #__line__ ";oboe pad 65000 100 max pos: ~A (should be ~A)~%" (maxamp-position) 24971)) (if (fneq (abs (sample (maxamp-position))) (maxamp)) (snd-display #__line__ ";oboe maxes: ~A ~A~%" (maxamp) (abs (sample (maxamp-position))))) ;; set sample (revert-sound) (set-sample 100 .1) (if (fneq (maxamp) 0.14724731445312) (snd-display #__line__ ";oboe set 100 .1 max: ~A (should be ~A)~%" (maxamp) 0.14724731445312)) (if (not (= (maxamp-position) 24971)) (snd-display #__line__ ";oboe set 100 .1 max pos: ~A (should be ~A)~%" (maxamp-position) 24971)) (if (fneq (abs (sample (maxamp-position))) (maxamp)) (snd-display #__line__ ";oboe maxes: ~A ~A~%" (maxamp) (abs (sample (maxamp-position))))) (revert-sound) (set-sample 100 .2) (if (fneq (maxamp) 0.2) (snd-display #__line__ ";oboe set 100 .2 max: ~A (should be ~A)~%" (maxamp) 0.2)) (if (not (= (maxamp-position) 100)) (snd-display #__line__ ";oboe set 100 .2 max pos: ~A (should be ~A)~%" (maxamp-position) 100)) (if (fneq (abs (sample (maxamp-position))) (maxamp)) (snd-display #__line__ ";oboe maxes: ~A ~A~%" (maxamp) (abs (sample (maxamp-position))))) (revert-sound) (set-sample 25000 .1) (if (fneq (maxamp) 0.14724731445312) (snd-display #__line__ ";oboe set 25000 .1 max: ~A (should be ~A)~%" (maxamp) 0.14724731445312)) (if (not (= (maxamp-position) 24971)) (snd-display #__line__ ";oboe set 25000 .1 max pos: ~A (should be ~A)~%" (maxamp-position) 24971)) (if (fneq (abs (sample (maxamp-position))) (maxamp)) (snd-display #__line__ ";oboe maxes: ~A ~A~%" (maxamp) (abs (sample (maxamp-position))))) (revert-sound) (set-sample 25000 .2) (if (fneq (maxamp) 0.2) (snd-display #__line__ ";oboe set 25000 .2 max: ~A (should be ~A)~%" (maxamp) 0.2)) (if (not (= (maxamp-position) 25000)) (snd-display #__line__ ";oboe set 25000 .2 max pos: ~A (should be ~A)~%" (maxamp-position) 25000)) (if (fneq (abs (sample (maxamp-position))) (maxamp)) (snd-display #__line__ ";oboe maxes: ~A ~A~%" (maxamp) (abs (sample (maxamp-position))))) (revert-sound) (set-sample 24971 .1) (if (fneq (maxamp) 0.14724731445312) (snd-display #__line__ ";oboe set 24971 .1 max: ~A (should be ~A)~%" (maxamp) 0.14724731445312)) (if (not (= (maxamp-position) 25368)) (snd-display #__line__ ";oboe set 24971 .1 max pos: ~A (should be ~A)~%" (maxamp-position) 25368)) (if (fneq (abs (sample (maxamp-position))) (maxamp)) (snd-display #__line__ ";oboe maxes: ~A ~A~%" (maxamp) (abs (sample (maxamp-position))))) (revert-sound) (set-sample 24971 .2) (if (fneq (maxamp) 0.2) (snd-display #__line__ ";oboe set 24971 .2 max: ~A (should be ~A)~%" (maxamp) 0.2)) (if (not (= (maxamp-position) 24971)) (snd-display #__line__ ";oboe set 24971 .2 max pos: ~A (should be ~A)~%" (maxamp-position) 24971)) (if (fneq (abs (sample (maxamp-position))) (maxamp)) (snd-display #__line__ ";oboe maxes: ~A ~A~%" (maxamp) (abs (sample (maxamp-position))))) (revert-sound) (set-sample 24971 -.2) (if (fneq (maxamp) 0.2) (snd-display #__line__ ";oboe set 24971 -.2 max: ~A (should be ~A)~%" (maxamp) 0.2)) (if (not (= (maxamp-position) 24971)) (snd-display #__line__ ";oboe set 24971 .2 max pos: ~A (should be ~A)~%" (maxamp-position) 24971)) (if (fneq (abs (sample (maxamp-position))) (maxamp)) (snd-display #__line__ ";oboe maxes: ~A ~A~%" (maxamp) (abs (sample (maxamp-position))))) ;; delete-samples (revert-sound) (delete-samples 0 100) (if (fneq (maxamp) 0.14724731445312) (snd-display #__line__ ";oboe delete 0 100 max: ~A (should be ~A)~%" (maxamp) 0.14724731445312)) (if (not (= (maxamp-position) 24871)) (snd-display #__line__ ";oboe delete 0 100 max pos: ~A (should be ~A)~%" (maxamp-position) 24871)) (if (fneq (abs (sample (maxamp-position))) (maxamp)) (snd-display #__line__ ";oboe maxes: ~A ~A~%" (maxamp) (abs (sample (maxamp-position))))) (revert-sound) (delete-samples 25000 100) (if (fneq (maxamp) 0.14724731445312) (snd-display #__line__ ";oboe delete 25000 100 max: ~A (should be ~A)~%" (maxamp) 0.14724731445312)) (if (not (= (maxamp-position) 24971)) (snd-display #__line__ ";oboe delete 25000 100 max pos: ~A (should be ~A)~%" (maxamp-position) 24971)) (if (fneq (abs (sample (maxamp-position))) (maxamp)) (snd-display #__line__ ";oboe maxes: ~A ~A~%" (maxamp) (abs (sample (maxamp-position))))) (revert-sound) (delete-samples 24900 100) (if (fneq (maxamp) 0.14724731445312) (snd-display #__line__ ";oboe delete 24900 100 max: ~A (should be ~A)~%" (maxamp) 0.14724731445312)) (if (not (= (maxamp-position) 25268)) (snd-display #__line__ ";oboe delete 24900 100 max pos: ~A (should be ~A)~%" (maxamp-position) 25268)) (if (fneq (abs (sample (maxamp-position))) (maxamp)) (snd-display #__line__ ";oboe maxes: ~A ~A~%" (maxamp) (abs (sample (maxamp-position))))) ;; insert samples (revert-sound) (insert-samples 0 100 (make-float-vector 100 0.1)) (if (fneq (maxamp) 0.14724731445312) (snd-display #__line__ ";oboe insert 0 100 max: ~A (should be ~A)~%" (maxamp) 0.14724731445312)) (if (not (= (maxamp-position) 25071)) (snd-display #__line__ ";oboe insert 0 100 max pos: ~A (should be ~A)~%" (maxamp-position) 25071)) (if (fneq (abs (sample (maxamp-position))) (maxamp)) (snd-display #__line__ ";oboe maxes: ~A ~A~%" (maxamp) (abs (sample (maxamp-position))))) (revert-sound) (insert-samples 25000 100 (make-float-vector 100 0.1)) (if (fneq (maxamp) 0.14724731445312) (snd-display #__line__ ";oboe insert 25000 100 max: ~A (should be ~A)~%" (maxamp) 0.14724731445312)) (if (not (= (maxamp-position) 24971)) (snd-display #__line__ ";oboe insert 25000 100 max pos: ~A (should be ~A)~%" (maxamp-position) 24971)) (if (fneq (abs (sample (maxamp-position))) (maxamp)) (snd-display #__line__ ";oboe maxes: ~A ~A~%" (maxamp) (abs (sample (maxamp-position))))) (revert-sound) (insert-samples 24971 100 (make-float-vector 100 0.1)) (if (fneq (maxamp) 0.14724731445312) (snd-display #__line__ ";oboe insert 24971 100 max: ~A (should be ~A)~%" (maxamp) 0.14724731445312)) (if (not (= (maxamp-position) 25071)) (snd-display #__line__ ";oboe insert 24971 100 max pos: ~A (should be ~A)~%" (maxamp-position) 25971)) (if (fneq (abs (sample (maxamp-position))) (maxamp)) (snd-display #__line__ ";oboe maxes: ~A ~A~%" (maxamp) (abs (sample (maxamp-position))))) (revert-sound) (insert-samples 0 100 (make-float-vector 100 0.2)) (if (fneq (maxamp) 0.2) (snd-display #__line__ ";oboe insert 0 100 .2 max: ~A (should be ~A)~%" (maxamp) 0.2)) (if (not (= (maxamp-position) 0)) (snd-display #__line__ ";oboe insert 0 100 .2 max pos: ~A (should be ~A)~%" (maxamp-position) 0)) (if (fneq (abs (sample (maxamp-position))) (maxamp)) (snd-display #__line__ ";oboe maxes: ~A ~A~%" (maxamp) (abs (sample (maxamp-position))))) (revert-sound) (insert-samples 25000 100 (make-float-vector 100 0.2)) (if (fneq (maxamp) 0.2) (snd-display #__line__ ";oboe insert 25000 100 .2 max: ~A (should be ~A)~%" (maxamp) 0.2)) (if (not (= (maxamp-position) 25000)) (snd-display #__line__ ";oboe insert 25000 100 .2 max pos: ~A (should be ~A)~%" (maxamp-position) 25000)) (if (fneq (abs (sample (maxamp-position))) (maxamp)) (snd-display #__line__ ";oboe maxes: ~A ~A~%" (maxamp) (abs (sample (maxamp-position))))) ;; set samples (revert-sound) (set-samples 0 100 (make-float-vector 100 0.1)) (if (fneq (maxamp) 0.14724731445312) (snd-display #__line__ ";oboe change 0 100 max: ~A (should be ~A)~%" (maxamp) 0.14724731445312)) (if (not (= (maxamp-position) 24971)) (snd-display #__line__ ";oboe change 0 100 max pos: ~A (should be ~A)~%" (maxamp-position) 24971)) (if (fneq (abs (sample (maxamp-position))) (maxamp)) (snd-display #__line__ ";oboe maxes: ~A ~A~%" (maxamp) (abs (sample (maxamp-position))))) (revert-sound) (set-samples 25000 100 (make-float-vector 100 0.1)) (if (fneq (maxamp) 0.14724731445312) (snd-display #__line__ ";oboe change 25000 100 max: ~A (should be ~A)~%" (maxamp) 0.14724731445312)) (if (not (= (maxamp-position) 24971)) (snd-display #__line__ ";oboe change 25000 100 max pos: ~A (should be ~A)~%" (maxamp-position) 24971)) (if (fneq (abs (sample (maxamp-position))) (maxamp)) (snd-display #__line__ ";oboe maxes: ~A ~A~%" (maxamp) (abs (sample (maxamp-position))))) (revert-sound) (set-samples 24900 100 (make-float-vector 100 0.1)) (if (fneq (maxamp) 0.14724731445312) (snd-display #__line__ ";oboe change 24900 100 max: ~A (should be ~A)~%" (maxamp) 0.14724731445312)) (if (not (= (maxamp-position) 25368)) (snd-display #__line__ ";oboe change 24900 100 max pos: ~A (should be ~A)~%" (maxamp-position) 25368)) (if (fneq (abs (sample (maxamp-position))) (maxamp)) (snd-display #__line__ ";oboe maxes: ~A ~A~%" (maxamp) (abs (sample (maxamp-position))))) (revert-sound) (set-samples 0 100 (make-float-vector 100 0.2)) (if (fneq (maxamp) 0.2) (snd-display #__line__ ";oboe change 0 100 .2 max: ~A (should be ~A)~%" (maxamp) 0.2)) (if (not (= (maxamp-position) 0)) (snd-display #__line__ ";oboe change 0 100 .2 max pos: ~A (should be ~A)~%" (maxamp-position) 0)) (if (fneq (abs (sample (maxamp-position))) (maxamp)) (snd-display #__line__ ";oboe maxes: ~A ~A~%" (maxamp) (abs (sample (maxamp-position))))) (revert-sound) (set-samples 25000 100 (make-float-vector 100 0.2)) (if (fneq (maxamp) 0.2) (snd-display #__line__ ";oboe change 25000 100 .2 max: ~A (should be ~A)~%" (maxamp) 0.2)) (if (not (= (maxamp-position) 25000)) (snd-display #__line__ ";oboe change 25000 100 .2 max pos: ~A (should be ~A)~%" (maxamp-position) 25000)) (if (fneq (abs (sample (maxamp-position))) (maxamp)) (snd-display #__line__ ";oboe maxes: ~A ~A~%" (maxamp) (abs (sample (maxamp-position))))) ;; scale samples (revert-sound) (scale-channel 2.0) (if (fneq (maxamp) 0.29449462890625) (snd-display #__line__ ";oboe scale 2 0 max: ~A (should be ~A)~%" (maxamp) 0.29449462890625)) (if (not (= (maxamp-position) 24971)) (snd-display #__line__ ";oboe scale 2 0 max pos: ~A (should be ~A)~%" (maxamp-position) 24971)) (if (fneq (abs (sample (maxamp-position))) (maxamp)) (snd-display #__line__ ";oboe maxes: ~A ~A~%" (maxamp) (abs (sample (maxamp-position))))) (revert-sound) (scale-channel 0.0) (if (fneq (maxamp) 0.0) (snd-display #__line__ ";oboe scale 0 0 max: ~A (should be ~A)~%" (maxamp) 0.0)) (if (not (= (maxamp-position) 0)) (snd-display #__line__ ";oboe scale 0 0 max pos: ~A (should be ~A)~%" (maxamp-position) 0)) (if (fneq (abs (sample (maxamp-position))) (maxamp)) (snd-display #__line__ ";oboe maxes: ~A ~A~%" (maxamp) (abs (sample (maxamp-position))))) (revert-sound) (scale-channel 0.1 0 100) (if (fneq (maxamp) 0.14724731445312) (snd-display #__line__ ";oboe scale .1 0 100 max: ~A (should be ~A)~%" (maxamp) 0.14724731445312)) (if (not (= (maxamp-position) 24971)) (snd-display #__line__ ";oboe scale .1 0 100 max pos: ~A (should be ~A)~%" (maxamp-position) 24971)) (if (fneq (abs (sample (maxamp-position))) (maxamp)) (snd-display #__line__ ";oboe maxes: ~A ~A~%" (maxamp) (abs (sample (maxamp-position))))) (revert-sound) (scale-channel -0.9 0 100) (if (fneq (maxamp) 0.14724731445312) (snd-display #__line__ ";oboe scale -.9 0 100 max: ~A (should be ~A)~%" (maxamp) 0.14724731445312)) (if (not (= (maxamp-position) 24971)) (snd-display #__line__ ";oboe scale -.9 0 100 max pos: ~A (should be ~A)~%" (maxamp-position) 24971)) (if (fneq (abs (sample (maxamp-position))) (maxamp)) (snd-display #__line__ ";oboe maxes: ~A ~A~%" (maxamp) (abs (sample (maxamp-position))))) (revert-sound) (scale-channel 0.1 25000 100) (if (fneq (maxamp) 0.14724731445312) (snd-display #__line__ ";oboe scale .1 25000 100 max: ~A (should be ~A)~%" (maxamp) 0.14724731445312)) (if (not (= (maxamp-position) 24971)) (snd-display #__line__ ";oboe scale .1 25000 100 max pos: ~A (should be ~A)~%" (maxamp-position) 24971)) (if (fneq (abs (sample (maxamp-position))) (maxamp)) (snd-display #__line__ ";oboe maxes: ~A ~A~%" (maxamp) (abs (sample (maxamp-position))))) (revert-sound) (scale-channel -2.0 24900 100) (if (fneq (maxamp) 0.29449462890625) (snd-display #__line__ ";oboe scale -2 24900 100 max: ~A (should be ~A)~%" (maxamp) 0.29449462890625)) (if (not (= (maxamp-position) 24971)) (snd-display #__line__ ";oboe scale -2 24900 100 max pos: ~A (should be ~A)~%" (maxamp-position) 24971)) (if (fneq (abs (sample (maxamp-position))) (maxamp)) (snd-display #__line__ ";oboe maxes: ~A ~A~%" (maxamp) (abs (sample (maxamp-position))))) (revert-sound) (scale-channel 0.1 24900 100) (if (fneq (maxamp) 0.14724731445312) (snd-display #__line__ ";oboe scale 0.1 24900 100 max: ~A (should be ~A)~%" (maxamp) 0.14724731445312)) (if (not (= (maxamp-position) 25368)) (snd-display #__line__ ";oboe scale 0.1 24900 100 max pos: ~A (should be ~A)~%" (maxamp-position) 25368)) (if (fneq (abs (sample (maxamp-position))) (maxamp)) (snd-display #__line__ ";oboe maxes: ~A ~A~%" (maxamp) (abs (sample (maxamp-position))))) ;; ramp/xramp samples (revert-sound) (ramp-channel 0.0 1.0) (if (fneq (maxamp) 0.091239139496063) (snd-display #__line__ ";oboe ramp 0 1 max: ~A (should be ~A)~%" (maxamp) 0.091239139496063)) (if (not (= (maxamp-position) 35062)) (snd-display #__line__ ";oboe ramp 0 1 max pos: ~A (should be ~A)~%" (maxamp-position) 35062)) (if (fneq (abs (sample (maxamp-position))) (maxamp)) (snd-display #__line__ ";oboe maxes: ~A ~A~%" (maxamp) (abs (sample (maxamp-position))))) (revert-sound) (xramp-channel 0.0 1.0 3.0) (if (fneq (maxamp) 0.074973157321056) (snd-display #__line__ ";oboe xramp 0 1 max: ~A (should be ~A)~%" (maxamp) 0.074973157321056)) (if (not (= (maxamp-position) 35062)) (snd-display #__line__ ";oboe xramp 0 1 max pos: ~A (should be ~A)~%" (maxamp-position) 35062)) (if (fneq (abs (sample (maxamp-position))) (maxamp)) (snd-display #__line__ ";oboe maxes: ~A ~A~%" (maxamp) (abs (sample (maxamp-position))))) (revert-sound) (ramp-channel 0.0 -1.0 0 100) (if (fneq (maxamp) 0.14724731445312) (snd-display #__line__ ";oboe ramp 0 -1 0 100 max: ~A (should be ~A)~%" (maxamp) 0.14724731445312)) (if (not (= (maxamp-position) 24971)) (snd-display #__line__ ";oboe ramp 0 -1 0 100 max pos: ~A (should be ~A)~%" (maxamp-position) 24971)) (if (fneq (abs (sample (maxamp-position))) (maxamp)) (snd-display #__line__ ";oboe maxes: ~A ~A~%" (maxamp) (abs (sample (maxamp-position))))) (revert-sound) (ramp-channel 1.0 9.0 10000 100) (if (fneq (maxamp) 1.057239571003) (snd-display #__line__ ";oboe ramp 1 9 10000 100 max: ~A (should be ~A)~%" (maxamp) 1.057239571003)) (if (not (= (maxamp-position) 10089)) (snd-display #__line__ ";oboe ramp 1 9 10000 100 max pos: ~A (should be ~A)~%" (maxamp-position) 10089)) (if (fneq (abs (sample (maxamp-position))) (maxamp)) (snd-display #__line__ ";oboe maxes: ~A ~A~%" (maxamp) (abs (sample (maxamp-position))))) (close-sound ind)) (let ((ind0 (open-sound "oboe.snd")) (ind1 (open-sound "2.snd")) (ind2 (open-sound "4.aiff"))) (set! (squelch-update ind0 #t) #t) (set! (squelch-update ind1 #t) #t) (set! (squelch-update ind2 #t) #t) (catch 'mus-error (lambda () (do ((i 0 (+ i 1))) ((= i 500)) (set! (sync ind0) (random 3)) (set! (sync ind1) (random 3)) (set! (sync ind2) (random 3)) (opt-test (random 22)))) (lambda args (snd-display #__line__ ";caught mus-error") #f)) (set! (squelch-update ind0 #t) #f) (set! (squelch-update ind1 #t) #f) (set! (squelch-update ind2 #t) #f) (close-sound ind0) (close-sound ind1) (close-sound ind2)) (catch #t (lambda () (let* ((ind (open-sound (string-append home-dir "/test/sound/away.snd"))) (start (real-time)) (mxs (maxamp ind #t))) (swap-channels) (update-time-graph) (let ((tm (- (real-time) start))) (if (> tm .1) (snd-display #__line__ ";swap-channels not optimized? ~A" tm))) (let ((new-mxs (maxamp ind #t))) (if (or (fneq (car mxs) (cadr new-mxs)) (fneq (cadr mxs) (car new-mxs))) (snd-display #__line__ ";swap-channels amps: ~A -> ~A" mxs new-mxs))) (revert-sound ind) (close-sound ind))) (lambda args args)) ; away.snd may not exist (let ((ind (init-sound 0.5 10 2))) (save-sound ind) (scale-channel 2.0 0 (framples) ind 1) (swap-channels) (check-both-chans ind "1" (lambda (y) (fneq y 1.0)) (lambda (y) (fneq y 0.5))) (undo 1 ind 0) (undo 2 ind 1) (scale-channel 0.5 0 (framples) ind 0) (scale-channel 2.0 0 (framples) ind 1) (swap-channels) (check-both-chans ind "2" (lambda (y) (fneq y 1.0)) (lambda (y) (fneq y 0.25))) (undo 2 ind 0) (undo 2 ind 1) (delete-samples 2 3 ind 0) (env-channel '(0 0 1 1 2 0) 0 (framples ind 1) ind 1) (swap-channels) (undo 2 ind 0) (undo 2 ind 1) (delete-samples 2 7 ind 0) (swap-channels ind 0 ind 1 5 4) (revert-sound ind) (let ((m0 (add-mark 3 ind 0)) (m1 (add-mark 4 ind 1)) (m2 (add-mark 5 ind 1))) (scale-channel 0.5) (swap-channels) (if (not (= (mark-sample m0) 3)) (snd-display #__line__ ";swapped m0: ~A" (mark-sample m0))) (if (not (= (mark-sample m1) 4)) (snd-display #__line__ ";swapped m1: ~A" (mark-sample m1))) (if (not (= (mark-sample m2) 5)) (snd-display #__line__ ";swapped m2: ~A" (mark-sample m2))) (if (not (equal? (mark-home m0) (list ind 1))) (snd-display #__line__ ";mark-home m0: ~A" (mark-home m0))) (if (not (equal? (mark-home m1) (list ind 0))) (snd-display #__line__ ";mark-home m1: ~A" (mark-home m1))) (if (not (equal? (mark-home m2) (list ind 0))) (snd-display #__line__ ";mark-home m2: ~A" (mark-home m2))) (undo 1 ind 0) (undo 1 ind 1) (if (not (= (mark-sample m0) 3)) (snd-display #__line__ ";swapped m0 2: ~A" (mark-sample m0))) (if (not (= (mark-sample m1) 4)) (snd-display #__line__ ";swapped m1 2: ~A" (mark-sample m1))) (if (not (= (mark-sample m2) 5)) (snd-display #__line__ ";swapped m2 2: ~A" (mark-sample m2))) (if (not (equal? (mark-home m0) (list ind 0))) (snd-display #__line__ ";mark-home m0 2: ~A" (mark-home m0))) (if (not (equal? (mark-home m1) (list ind 1))) (snd-display #__line__ ";mark-home m1 2: ~A" (mark-home m1))) (if (not (equal? (mark-home m2) (list ind 1))) (snd-display #__line__ ";mark-home m2 2: ~A" (mark-home m2)))) (close-sound ind) (delete-file "test.snd")) (let ((ind (init-sound 0.5 10 4))) (scale-channel 0.5 0 (framples) ind 1) (scale-channel 0.25 0 (framples) ind 2) (scale-channel 0.125 0 (framples) ind 3) (swap-channels ind 1 ind 2) (let ((maxs (maxamp ind #t))) (if (or (fneq (maxs 0) 0.5) (fneq (maxs 1) 0.125) (fneq (maxs 2) 0.25) (fneq (maxs 3) 0.0625)) (snd-display #__line__ ";swap midchans: ~A" maxs)) (close-sound ind))) (let* ((ind0 (open-sound "oboe.snd")) (ind1 (open-sound "pistol.snd")) (mx0 (maxamp ind0 0)) (mx1 (maxamp ind1 0))) (swap-channels ind0 0 ind1 0) (if (fneq (maxamp ind0 0) mx1) (snd-display #__line__ ";maxamp cross swap 0: ~A" (maxamp ind0 0))) (if (fneq (maxamp ind1 0) mx0) (snd-display #__line__ ";maxamp cross swap 1: ~A" (maxamp ind1 0))) (close-sound ind1) (if (not (string=? (display-edits) (string-append " EDITS: 1 (begin) [0:2]: (at 0, cp->sounds[0][0:50827, 1.000]) [file: " cwd "oboe.snd[0]] (at 50828, end_mark) (set 0 41623) ; swap-channels [1:2]: (at 0, cp->sounds[1][0:41622, 1.000]) [file: " cwd "pistol.snd[0]] (at 41623, end_mark) "))) (snd-display #__line__ ";cross swap state: ~A" (display-edits))) (close-sound ind0)) (let ((ind (init-sound 1.0 10 1))) ;; -------- ramp+ramp (ramp-channel 0.0 1.0) (check-back-and-forth ind "ramp 1" (float-vector 0.000 0.100 0.200 0.300 0.400 0.500 0.600 0.700 0.800 0.900 1.000)) (ramp-channel 0.0 1.0) (check-back-and-forth ind "ramp 2" (float-vector 0.000 0.010 0.040 0.090 0.160 0.250 0.360 0.490 0.640 0.810 1.000)) (undo) (ramp-channel 1.0 0.0) (check-back-and-forth ind "ramp 3" (float-vector 0.000 0.090 0.160 0.210 0.240 0.250 0.240 0.210 0.160 0.090 0.000)) (undo) (env-channel '(0 0 1 1 2 0)) (check-back-and-forth ind "ramp 4" (float-vector 0.000 0.020 0.080 0.180 0.320 0.500 0.480 0.420 0.320 0.180 0.000)) (undo 2) (env-channel '(0 0 1 1 2 0)) (check-back-and-forth ind "ramp 5" (float-vector 0.000 0.200 0.400 0.600 0.800 1.000 0.800 0.600 0.400 0.200 0.000)) (ramp-channel 0.0 1.0) (check-back-and-forth ind "ramp 6" (float-vector 0.000 0.020 0.080 0.180 0.320 0.500 0.480 0.420 0.320 0.180 0.000)) (scale-channel 0.5) (check-back-and-forth ind "ramp 7" (float-vector 0.000 0.010 0.040 0.090 0.160 0.250 0.240 0.210 0.160 0.090 0.000)) (undo 3) (scale-channel 0.5) (env-channel '(0 0 1 1 2 0)) (check-back-and-forth ind "ramp 8" (float-vector 0.000 0.100 0.200 0.300 0.400 0.500 0.400 0.300 0.200 0.100 0.000)) (ramp-channel 0.0 1.0) (check-back-and-forth ind "ramp 9" (float-vector 0.000 0.010 0.040 0.090 0.160 0.250 0.240 0.210 0.160 0.090 0.000)) (undo 3) (ramp-channel 0.0 1.0) (ramp-channel 0.0 1.0) (ramp-channel 0.0 1.0) (check-back-and-forth ind "ramp 10" (float-vector 0.000 0.001 0.008 0.027 0.064 0.125 0.216 0.343 0.512 0.729 1.000)) (undo 3) ;; ramp+scl (checking split loc) (let ((start-pos (edit-position ind 0))) (for-each (lambda (func) (ramp-channel 0.0 1.0 0 5) (let ((edpos (edit-position ind 0))) (check-back-and-forth ind "ramp+scl setup" (float-vector 0.000 0.250 0.500 0.750 1.000 1.000 1.000 1.000 1.000 1.000 1.000)) (let ((happy #t)) (do ((start 0 (+ 1 start))) ((or (not happy) (= start 10))) (do ((len 1 (+ 1 len))) ((or (not happy) (= (+ start len) 11))) (let ((v (float-vector 0.000 0.250 0.500 0.750 1.000 1.000 1.000 1.000 1.000 1.000 1.000))) (do ((i 0 (+ i 1))) ((= i len)) (set! (v (+ start i)) (* (v (+ start i)) 0.5))) (func 0.5 start len) (set! happy (check-back-and-forth ind (format #f "ramp+scl 0-1 [~A ~A] with ~A" start len func) v)) (set! (edit-position ind 0) edpos) ))))) (set! (edit-position ind 0) start-pos) (ramp-channel 1.0 0.0 5 5) (let ((edpos (edit-position ind 0))) (check-back-and-forth ind "ramp+scl 2 setup" (float-vector 1.000 1.000 1.000 1.000 1.000 1.000 0.750 0.500 0.250 0.000 1.000)) (let ((happy #t)) (do ((start 0 (+ 1 start))) ((or (not happy) (= start 10))) (do ((len 1 (+ 1 len))) ((or (not happy) (= (+ start len) 11))) (let ((v (float-vector 1.000 1.000 1.000 1.000 1.000 1.000 0.750 0.500 0.250 0.000 1.000))) (do ((i 0 (+ i 1))) ((= i len)) (set! (v (+ start i)) (* (v (+ start i)) 0.5))) (func 0.5 start len) (set! happy (check-back-and-forth ind (format #f "ramp+scl 1-0 [~A ~A] with ~A" start len func) v)) (set! (edit-position ind 0) edpos) ))))) (set! (edit-position ind 0) start-pos) (ramp-channel 0.0 1.0 0 5) (ramp-channel 1.0 0.0 5 5) (let ((edpos (edit-position ind 0))) (check-back-and-forth ind "ramp+scl 3 setup" (float-vector 0.000 0.250 0.500 0.750 1.000 1.000 0.750 0.500 0.250 0.000 1.000)) (let ((happy #t)) (do ((start 0 (+ 1 start))) ((or (not happy) (= start 10))) (do ((len 1 (+ 1 len))) ((or (not happy) (= (+ start len) 11))) (let ((v (float-vector 0.000 0.250 0.500 0.750 1.000 1.000 0.750 0.500 0.250 0.000 1.000))) (do ((i 0 (+ i 1))) ((= i len)) (set! (v (+ start i)) (* (v (+ start i)) 0.5))) (func 0.5 start len) (set! happy (check-back-and-forth ind (format #f "ramp+scl 0-1-1-0 [~A ~A] with ~A" start len func) v)) (set! (edit-position ind 0) edpos) ))))) (set! (edit-position ind 0) start-pos) (ramp-channel 1.0 0.0 3 5) (let ((edpos (edit-position ind 0))) (check-back-and-forth ind "ramp+scl 4 setup" (float-vector 1.000 1.000 1.000 1.000 0.750 0.500 0.250 0.000 1.000 1.000 1.000)) (let ((happy #t)) (do ((start 0 (+ 1 start))) ((or (not happy) (= start 10))) (do ((len 1 (+ 1 len))) ((or (not happy) (= (+ start len) 11))) (let ((v (float-vector 1.000 1.000 1.000 1.000 0.750 0.500 0.250 0.000 1.000 1.000 1.000))) (do ((i 0 (+ i 1))) ((= i len)) (set! (v (+ start i)) (* (v (+ start i)) 0.5))) (func 0.5 start len) (set! happy (check-back-and-forth ind (format #f "ramp+scl mid 1-0 [~A ~A] with ~A" start len func) v)) (set! (edit-position ind 0) edpos) ))))) (set! (edit-position ind 0) start-pos) (env-channel '(0 1 1 0 2 0 3 1)) (let ((edpos (edit-position ind 0))) (check-back-and-forth ind "ramp+scl setup" (float-vector 1.000 0.667 0.333 0.000 0.000 0.000 0.000 0.000 0.333 0.667 1.000)) (let ((happy #t)) (do ((start 0 (+ 1 start))) ((or (not happy) (= start 10))) (do ((len 1 (+ 1 len))) ((or (not happy) (= (+ start len) 11))) (let ((v (float-vector 1.000 0.667 0.333 0.000 0.000 0.000 0.000 0.000 0.333 0.667 1.000))) (do ((i 0 (+ i 1))) ((= i len)) (set! (v (+ start i)) (* (v (+ start i)) 0.5))) (func 0.5 start len) (set! happy (check-back-and-forth ind (format #f "ramp+scl 0-1-0-1 [~A ~A] with ~A" start len func) v)) (set! (edit-position ind 0) edpos) ))))) (set! (edit-position ind 0) start-pos)) (list scale-channel (lambda (scl beg dur) (map-channel (lambda (y) (* y scl)) beg dur))))) (close-sound ind) ) (if (and all-args (= test-16 0)) (let ((tries 256)) (snd-display #__line__ ";framples: ~,2F ~,2F" (* 1.0 (/ (mus-sound-framples "1.snd") (mus-sound-framples "oboe.snd"))) (* 1.0 (/ (mus-sound-framples "1.snd") (mus-sound-framples "1a.snd")))) (snd-display #__line__ ";~12T~A~28T~A~44T~A~56T(1/oboe, 1/1a)" "1.snd" "oboe.snd" "1a.snd") (for-each (lambda (name func) (let ((ind (open-sound "1.snd")) (start-time-1 (real-time))) (set! (squelch-update ind 0) #t) (do ((i 0 (+ i 1))) ((= i tries)) (if (= (modulo i 10) 0) (revert-sound ind)) (func ind i)) (let ((mid-time-1 (real-time))) (revert-sound ind) (set! (squelch-update ind 0) #f) (close-sound ind) (let ((end-time-1 (real-time))) (let ((ind (open-sound "oboe.snd")) (start-time-2 (real-time))) (set! (squelch-update ind 0) #t) (do ((i 0 (+ i 1))) ((= i tries)) (if (= (modulo i 10) 0) (revert-sound ind)) (func ind i)) (let ((mid-time-2 (real-time))) (revert-sound ind) (set! (squelch-update ind 0) #f) (close-sound ind) (let ((end-time-2 (real-time))) (let ((ind (open-sound "1a.snd")) (start-time (real-time))) (set! (squelch-update ind 0) #t) (do ((i 0 (+ i 1))) ((= i tries)) (if (= (modulo i 10) 0) (revert-sound ind)) (func ind i)) (let ((mid-time (real-time))) (revert-sound ind) (set! (squelch-update ind 0) #f) (close-sound ind) (let ((end-time (real-time))) (snd-display #__line__ ";~A:~12T~A~18T~A~28T~A~34T~A~44T~A~50T~A~56T(~,2F, ~,2F)" name (hundred (- mid-time-1 start-time-1)) (hundred (- end-time-1 mid-time-1)) (hundred (- mid-time-2 start-time-2)) (hundred (- end-time-2 mid-time-2)) (hundred (- mid-time start-time)) (hundred (- end-time mid-time)) (* 1.0 (/ (+ (hundred (- mid-time-1 start-time-1)) (hundred (- end-time-1 mid-time-1))) (max 1 (+ (hundred (- mid-time-2 start-time-2)) (hundred (- end-time-2 mid-time-2)))))) (* 1.0 (/ (+ (hundred (- mid-time-1 start-time-1)) (hundred (- end-time-1 mid-time-1))) (max 1 (+ (hundred (- mid-time start-time)) (hundred (- end-time mid-time))))))))))))))))) (list "scale" "set!" "env" "env-exp" "env-step" "delete" "insert" "pad" "mix-no-tag" "mix-tag" "mix-amp" "mix-scale" "src-2" "src" "filter" "filter-sym" "f10" "f10sym" "clm" "reverse" ) (list (lambda (snd i) (scale-channel (* i .01))) (lambda (snd i) (set! (sample i) .5)) (lambda (snd i) (env-channel '(0 0 1 1))) (lambda (snd i) (env-channel-with-base '(0 0 1 1) 32.0)) (lambda (snd i) (env-channel-with-base '(0 0 1 1) 0.0)) (lambda (snd i) (delete-sample (* 10 i))) (lambda (snd i) (insert-sample (* 10 i) .5)) (lambda (snd i) (pad-channel (* 10 i) (* 10 i))) (lambda (snd i) (mix "pistol.snd" (* i 10) 0 snd 0 #f)) (lambda (snd i) (mix "pistol.snd" (* i 10) 0 snd 0 #t)) (lambda (snd i) (let ((mx (car (mix "pistol.snd" (* i 100))))) (set! (mix-amp mx) .01))) (lambda (snd i) (mix "pistol.snd" (* i 100)) (scale-by .5)) ; scale-to before but that forces channel-maxamp which forces a full read which skews everything (lambda (snd i) (src-sound 2.0) (undo)) (lambda (snd i) (src-sound 2.01) (undo)) (lambda (snd i) (filter-channel (float-vector .25 .5 .25 .1) 4)) (lambda (snd i) (filter-channel (float-vector .25 .5 .5 .25) 4)) (lambda (snd i) (filter-channel (float-vector .1 .2 .1 .1 .1 .1 .1 .2 .1 .1) 10)) (lambda (snd i) (filter-channel (float-vector .1 .1 .1 .1 .1 .1 .1 .1 .1 .1) 10)) (lambda (snd i) (clm-channel (make-two-zero .5 .5))) (lambda (snd i) (reverse-channel (* i 10) (* i 100))) )))) (let ((ind (new-sound "fmv.snd" :size 50))) (set! *sinc-width* 10) (set! (sample 20 ind 0) 0.5) (let ((edpos (edit-position ind 0))) ;; -------- no-ops (src-channel 1) (if (not (= (edit-position ind 0) edpos)) (snd-display #__line__ ";src-channel 1 as no-op: ~A ~A" edpos (edit-position ind 0))) (src-sound 1) (if (not (= (edit-position ind 0) edpos)) (snd-display #__line__ ";src-sound 1 as no-op: ~A ~A" edpos (edit-position ind 0))) (select-all) (src-selection 1) (if (not (= (edit-position ind 0) edpos)) (snd-display #__line__ ";src-selection 1 as no-op: ~A ~A" edpos (edit-position ind 0))) (filter-channel (float-vector 1.0)) (if (not (= (edit-position ind 0) edpos)) (snd-display #__line__ ";filter-channel 1 as no-op: ~A ~A" edpos (edit-position ind 0))) (env-channel '(0 1 1 1)) (if (not (= (edit-position ind 0) edpos)) (snd-display #__line__ ";env-channel 1 as no-op: ~A ~A" edpos (edit-position ind 0))) (env-sound '(0 1 1 1)) (if (not (= (edit-position ind 0) edpos)) (snd-display #__line__ ";env-sound 1 as no-op: ~A ~A" edpos (edit-position ind 0))) (env-selection '(0 1 1 1)) (if (not (= (edit-position ind 0) edpos)) (snd-display #__line__ ";env-selection 1 as no-op: ~A ~A" edpos (edit-position ind 0))) (scale-channel 1) (if (not (= (edit-position ind 0) edpos)) (snd-display #__line__ ";scale-channel 1 as no-op: ~A ~A" edpos (edit-position ind 0))) (scale-by 1) (if (not (= (edit-position ind 0) edpos)) (snd-display #__line__ ";scale-by 1 as no-op: ~A ~A" edpos (edit-position ind 0))) (scale-selection-by 1) (if (not (= (edit-position ind 0) edpos)) (snd-display #__line__ ";scale-selection 1 as no-op: ~A ~A" edpos (edit-position ind 0))) ;; -------- other special cases (src-channel -1) (reverse-channel) (let ((diff (edit-difference ind 0 edpos (edit-position ind 0)))) (if diff (snd-display #__line__ ";src -1 and reverse diff: ~A" diff))) (set! (edit-position ind 0) edpos) (scale-by 2) (filter-channel (float-vector 2) 1 0 #f ind 0 edpos) (let ((diff (edit-difference ind 0 (+ 1 edpos) (+ edpos 2)))) (if diff (snd-display #__line__ ";scale and filter 2 diff: ~A" diff))) ;; -------- not no-ops! (scale-channel 1.0 0 #f ind 0 edpos) (let ((diff (edit-difference ind 0 edpos (edit-position ind 0)))) (if diff (snd-display #__line__ ";edpos scale 1 diff: ~A" diff))) (if (fneq (maxamp ind 0) 0.5) (snd-display #__line__ ";scale 1 of original: ~A" (maxamp ind 0))) (if (= (edit-position ind 0) (+ edpos 2)) (snd-display #__line__ ";edpos scl copy opted out?") (undo)) (filter-channel (float-vector 1) 1 0 #f ind 0 edpos) (let ((diff (edit-difference ind 0 edpos (edit-position ind 0)))) (if diff (snd-display #__line__ ";edpos flt 1 diff: ~A" diff))) (if (= (edit-position ind 0) (+ edpos 2)) (snd-display #__line__ ";edpos flt copy opted out?") (undo)) (env-channel '(0 1 1 1) 0 #f ind 0 edpos) (let ((diff (edit-difference ind 0 edpos (edit-position ind 0)))) (if diff (snd-display #__line__ ";edpos env 1 diff: ~A" diff))) (if (= (edit-position ind 0) (+ edpos 2)) (snd-display #__line__ ";edpos env copy opted out?") (undo)) (src-channel 1.0 0 #f ind 0 edpos) (let ((diff (edit-difference ind 0 edpos (edit-position ind 0)))) (if (and diff (> (car diff) .0001)) (snd-display #__line__ ";edpos src 1 diff: ~A" diff))) (if (= (edit-position ind 0) (+ edpos 2)) (snd-display #__line__ ";edpos src copy opted out?") (undo)) (set! edpos (edit-position ind 0)) (let ((len (framples ind 0))) (src-channel 0.5) (scale-channel 1.0 0 #f ind 0 edpos) (let ((diff (edit-difference ind 0 edpos (edit-position ind 0)))) (if diff (snd-display #__line__ ";1 edpos scale 1 diff: ~A" diff))) (if (not (= (framples ind 0) len)) (snd-display #__line__ ";scl len edpos: ~A ~A" len (framples ind 0))) (undo) (filter-channel (float-vector 1) 1 0 #f ind 0 edpos) (let ((diff (edit-difference ind 0 edpos (edit-position ind 0)))) (if diff (snd-display #__line__ ";1 edpos flt 1 diff: ~A" diff))) (if (not (= (framples ind 0) len)) (snd-display #__line__ ";flt len edpos: ~A ~A" len (framples ind 0))) (undo) (env-channel '(0 1 1 1) 0 #f ind 0 edpos) (let ((diff (edit-difference ind 0 edpos (edit-position ind 0)))) (if diff (snd-display #__line__ ";1 edpos env 1 diff: ~A" diff))) (if (not (= (framples ind 0) len)) (snd-display #__line__ ";env len edpos: ~A ~A" len (framples ind 0))) (undo) (reverse-channel 0 #f ind 0 edpos) (reverse-channel 0 #f ind 0) (let ((diff (edit-difference ind 0 edpos (edit-position ind 0)))) (if diff (snd-display #__line__ ";1 edpos rev 1 diff: ~A" diff))) (if (not (= (framples ind 0) len)) (snd-display #__line__ ";rev len edpos: ~A ~A" len (framples ind 0))) (undo 2) (src-channel 1.0 0 #f ind 0 edpos) (let ((diff (edit-difference ind 0 edpos (edit-position ind 0)))) (if (and diff (> (car diff) .0001)) (snd-display #__line__ ";1 edpos src 1 diff: ~A" diff))) (if (> (abs (- (framples ind 0) len)) 2) (snd-display #__line__ ";src len edpos: ~A ~A" len (framples ind 0))) (undo) (smooth-channel 0 len ind 0 edpos) (if (not (= (framples ind 0) len)) (snd-display #__line__ ";smooth len edpos: ~A ~A" len (framples ind 0))) (undo) (clm-channel (make-one-zero 1.0 0.0) 0 #f ind 0 edpos) (let ((diff (edit-difference ind 0 edpos (edit-position ind 0)))) (if diff (snd-display #__line__ ";1 edpos clm 1 diff: ~A" diff))) (if (not (= (framples ind 0) len)) (snd-display #__line__ ";clm len edpos: ~A ~A" len (framples ind 0))) (undo)) ;; dur of 0 is ignored no matter what -- else I have a million special cases ;; -> insert 0 at other edpos, delete 0, change 0 (x|ramp-channel) (map? etc) (revert-sound ind) (close-sound ind) ;; -------- reach back with partial edit (set! ind (new-sound "fmv.snd" :size 10)) (as-one-edit (lambda () (do ((i 0 (+ i 1))) ((= i 10)) (set! (sample i) (* i .01))))) (set! edpos (edit-position ind 0)) (pad-channel 0 10 ind 0) (pad-channel 20 10 ind 0) (set! (samples 0 10 ind 0) (make-float-vector 10 .5)) (set! (samples 20 10 ind 0) (make-float-vector 10 -.75)) (pad-channel 0 10 ind 0 edpos) (if (not (= (framples ind 0) 20)) (snd-display #__line__ ";pad edpos len: ~A" (framples ind 0))) (if (fneq (maxamp ind 0) .09) (snd-display #__line__ ";pad edpos max: ~A" (maxamp ind 0))) (undo) (delete-samples 0 5 ind 0 edpos) (if (not (= (framples ind 0) 5)) (snd-display #__line__ ";del edpos len: ~A" (framples ind 0))) (if (fneq (maxamp ind 0) .09) (snd-display #__line__ ";del edpos max: ~A" (maxamp ind 0))) (undo) (set! (samples 5 5 ind 0 #f "set" 0 edpos) (make-float-vector 5 0.0)) (if (not (= (framples ind 0) 10)) (snd-display #__line__ ";set edpos len: ~A" (framples ind 0))) (if (fneq (maxamp ind 0) .04) (snd-display #__line__ ";set edpos max: ~A" (maxamp ind 0))) (undo) (ramp-channel 0.0 1.0 0 5 ind 0 edpos) (if (not (= (framples ind 0) 10)) (snd-display #__line__ ";rmp edpos len: ~A" (framples ind 0))) (if (fneq (maxamp ind 0) .09) (snd-display #__line__ ";rmp edpos max: ~A" (maxamp ind 0))) (undo) (xramp-channel 0.0 1.0 32.0 5 5 ind 0 edpos) (if (not (= (framples ind 0) 10)) (snd-display #__line__ ";xrmp edpos len: ~A" (framples ind 0))) (if (fneq (maxamp ind 0) .09) (snd-display #__line__ ";xrmp edpos max: ~A" (maxamp ind 0))) (undo) (env-channel '(0 0 1 1) 0 5 ind 0 edpos) (if (not (= (framples ind 0) 10)) (snd-display #__line__ ";env edpos len: ~A" (framples ind 0))) (if (fneq (maxamp ind 0) .09) (snd-display #__line__ ";env edpos max: ~A" (maxamp ind 0))) (undo) (smooth-channel 0 5 ind 0 edpos) (if (not (= (framples ind 0) 10)) (snd-display #__line__ ";smooth edpos len: ~A" (framples ind 0))) (if (fneq (maxamp ind 0) .09) (snd-display #__line__ ";smooth edpos max: ~A" (maxamp ind 0))) (undo) (src-channel 0.5 0 5 ind 0 edpos) (if (not (= (framples ind 0) 16)) (snd-display #__line__ ";src edpos len: ~A" (framples ind 0))) (if (fneq (maxamp ind 0) .09) (snd-display #__line__ ";src edpos max: ~A" (maxamp ind 0))) (undo) (reverse-channel 0 5 ind 0 edpos) (if (not (= (framples ind 0) 10)) (snd-display #__line__ ";rev edpos len: ~A" (framples ind 0))) (if (fneq (maxamp ind 0) .09) (snd-display #__line__ ";rev edpos max: ~A" (maxamp ind 0))) (undo) (filter-channel (float-vector .1 .2 .1) 3 0 5 ind 0 edpos #t) ; truncate (if (not (= (framples ind 0) 10)) (snd-display #__line__ ";flt edpos len: ~A" (framples ind 0))) (if (fneq (maxamp ind 0) .09) (snd-display #__line__ ";flt edpos max: ~A" (maxamp ind 0))) (undo) (scale-channel 1.5 0 5 ind 0 edpos) (if (not (= (framples ind 0) 10)) (snd-display #__line__ ";scl edpos len: ~A" (framples ind 0))) (if (fneq (maxamp ind 0) .09) (snd-display #__line__ ";scl edpos max: ~A" (maxamp ind 0))) (undo) (close-sound ind))) (let ((ind (new-sound "fmv.snd" :size 20))) (map-channel (lambda (y) 1.0)) (let ((edpos (edit-position ind 0))) (delete-samples 5 10) (delete-samples 15 5 ind 0 edpos) (if (not (= (framples ind 0) 15)) (snd-display #__line__ ";delete-samples edpos len: ~A" (framples ind 0))) (undo) (float-vector->channel (make-float-vector 5 0.5) 15 5 ind 0 edpos) (if (not (= (framples ind 0) 20)) (snd-display #__line__ ";delete-samples edpos len: ~A" (framples ind 0))) (if (not (vequal (channel->float-vector 10 10) (float-vector 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5))) (snd-display #__line__ ";set samples edpos: ~A" (channel->float-vector 10 10))) (undo) (env-channel '(0 0 1 1) 0 #f ind 0 edpos) (if (not (= (framples ind 0) 20)) (snd-display #__line__ ";env edpos len: ~A" (framples ind 0))) (if (not (vequal (channel->float-vector 0 20) (float-vector 0.000 0.053 0.105 0.158 0.211 0.263 0.316 0.368 0.421 0.474 0.526 0.579 0.632 0.684 0.737 0.789 0.842 0.895 0.947 1.000))) (snd-display #__line__ ";env edpos: ~A" (channel->float-vector 0 20))) (undo) (close-sound ind))) (let ((ind (new-sound "fmv.snd" :size 20))) (set! (sample 5) 1.0) (filter-channel (float-vector 1.0 0.5)) (filter-channel (float-vector 1.0 0.5)) (let ((data (channel->float-vector 0 20))) (undo 2) (let ((v (convolve-coeffs (float-vector 1.0 0.5) (float-vector 1.0 0.5)))) (filter-channel v) (let ((vdata (channel->float-vector 0 20))) (if (not (vequal data vdata)) (snd-display #__line__ ";filter convolved: ~% standard: ~A~% virtual: ~A~%" data vdata))) (undo))) (let ((v1 (make-float-vector 8)) (v2 (make-float-vector 5))) (do ((i 0 (+ i 1))) ((= i 8)) (float-vector-set! v1 i (random 1.0))) (do ((i 0 (+ i 1))) ((= i 5)) (float-vector-set! v2 i (random 1.0))) (filter-channel v1) (filter-channel v2) (let ((data (channel->float-vector 0 20))) (undo 2) (let ((v (convolve-coeffs v1 v2))) (filter-channel v) (let ((vdata (channel->float-vector 0 20))) (if (not (vequal data vdata)) (snd-display #__line__ ";random filter convolved: ~% standard: ~A~% virtual: ~A~%" data vdata))) (undo)))) (let ((v1 (make-float-vector 18)) (v2 (make-float-vector 15))) (do ((i 0 (+ i 1))) ((= i 18)) (float-vector-set! v1 i (random 1.0))) (do ((i 0 (+ i 1))) ((= i 15)) (float-vector-set! v2 i (random 1.0))) (filter-channel v1) (filter-channel v2) (let ((data (channel->float-vector 0 20))) (undo 2) (let ((v (convolve-coeffs v1 v2))) (filter-channel v) (let ((vdata (channel->float-vector 0 20))) (if (not (vequal data vdata)) (snd-display #__line__ ";big random filter convolved: ~% standard: ~A~% virtual: ~A~%" data vdata))) (undo)))) (close-sound ind)) (let ((ind (new-sound "fmv.snd" :size 100))) (set! (sample 5) .5) (set! (sample 85) .5) (src-channel -1.001) (src-channel '(0 -1.0 1 -1.0) 0 #f ind 0 2) (let ((dis (edit-distance ind 0 3 4))) (if (> dis .2) (snd-display #__line__ ";src-channel -1, distance: ~A" dis))) (undo 2) (src-channel 1.001) (src-channel '(0 1.0 1 1.0) 0 #f ind 0 2) (let ((dis (edit-distance ind 0 3 4))) (if (> dis .2) (snd-display #__line__ ";src-channel 1, distance: ~A" dis))) (undo 2) (for-each (lambda (rate) (src-channel rate) (src-channel (list 0 rate 1 rate) 0 #f ind 0 2) (let ((dis (edit-distance ind 0 3 4))) (if (> dis .2) (snd-display #__line__ ";src-channel ~A, distance: ~A" rate dis))) (undo 2)) (list 2.0 -2.0 0.5 -0.5 1.5 -1.5 3.0 -3.0 0.2 -0.2)) (src-sound -1.001) (src-sound '(0 -1.0 1 -1.0) 1.0 ind 0 2) (let ((dis (edit-distance ind 0 3 4))) (if (> dis .2) (snd-display #__line__ ";src-sound -1, distance: ~A" dis))) (undo 2) (src-sound 1.001) (src-sound '(0 1.0 1 1.0) 1.0 ind 0 2) (let ((dis (edit-distance ind 0 3 4))) (if (> dis .2) (snd-display #__line__ ";src-sound 1, distance: ~A" dis))) (undo 2) (for-each (lambda (rate) (src-sound rate) (src-sound (list 0 rate 1 rate) 1.0 ind 0 2) (let ((dis (edit-distance ind 0 3 4))) (if (> dis .2) (snd-display #__line__ ";src-sound ~A, distance: ~A" rate dis))) (undo 2)) (list 2.0 -2.0 0.5 -0.5 1.5 -1.5 3.0 -3.0 0.2 -0.2)) (close-sound ind)) ;; additional coverage tests (let ((ind (new-sound "test.snd" :size 10))) (float-vector->channel (make-float-vector 10 .4)) (make-selection 3 7) ; beg end just for confusion (env-selection '(0 0.5 1 0.5)) (let ((data (channel->float-vector))) (if (not (vequal data (float-vector .4 .4 .4 .2 .2 .2 .2 .2 .4 .4))) (snd-display #__line__ ";env-selection constant: ~A" data))) (undo) (let ((edpos (edit-position ind 0))) (smooth-channel 10 10 ind 0) (if (not (= (edit-position ind 0) edpos)) (snd-display #__line__ ";smooth past end: ~A ~A" (edit-position ind 0) edpos)) (let ((ctr 0)) (map-channel (lambda (y) (set! ctr (+ ctr 1)) (or (> ctr 3) (* y 2))))) (if (not (= (framples ind 0) 3)) (snd-display #__line__ ";map-channel -> #t at 3: ~A" (framples ind 0)) (if (not (vequal (channel->float-vector) (float-vector 0.8 0.8 0.8))) (snd-display #__line__ ";map-channel #t result: ~A" (channel->float-vector)))) (undo) (let ((ctr 0)) (map-channel (lambda (y) (set! ctr (+ ctr 1)) (if (= ctr 3) (make-float-vector 5 .1) (* y .5))))) (if (not (= (framples ind 0) 14)) (snd-display #__line__ ";map-channel -> float-vector at 3: ~A" (framples ind 0)) (if (not (vequal (channel->float-vector) (float-vector 0.200 0.200 0.100 0.100 0.100 0.100 0.100 0.200 0.200 0.200 0.200 0.200 0.200 0.200))) (snd-display #__line__ ";map-channel float-vector result: ~A" (channel->float-vector)))) (undo) (let ((data (make-float-vector 2 0.0))) (map-channel (lambda (y) (float-vector-set! data 0 y) data))) (if (not (= (framples ind 0) 20)) (snd-display #__line__ ";map-channel -> float-vector: ~A" (framples ind 0)) (if (not (vequal (channel->float-vector) (float-vector 0.400 0.000 0.400 0.000 0.400 0.000 0.400 0.000 0.400 0.000 0.400 0.000 0.400 0.000 0.400 0.000 0.400 0.000 0.400 0.000))) (snd-display #__line__ ";map-channel float-vector result: ~A" (channel->float-vector)))) (undo)) (set! (amp-control ind) 2.0) (apply-controls ind 1 0) (if (> (abs (- (maxamp ind 0) .8)) .01) (snd-display #__line__ ";apply-controls 10: ~A" (channel->float-vector))) (undo) (set! (amp-control ind) 2.0) (apply-controls ind 1 5) (if (not (vequal (channel->float-vector 0 5) (float-vector 0.4 0.4 0.4 0.4 0.4))) (snd-display #__line__ ";apply controls from 5: ~A" (channel->float-vector))) (if (ffneq (sample 5) .8) (snd-display #__line__ ";apply-controls at 5: ~A" (sample 5))) (let ((tag (catch 'no-such-edit (lambda () (save-sound-as "nope.snd" :edit-position 21)) (lambda args (car args))))) (if (not (eq? tag 'no-such-edit)) (snd-display #__line__ ";save-sound-as at bad edpos: ~A" tag))) (let ((tag (catch 'no-such-file (lambda () (channel-amp-envs "/baddy/hiho")) (lambda args (car args))))) (if (not (eq? tag 'no-such-file)) (snd-display #__line__ ";channel-amp-envs bad file: ~A" tag))) (close-sound ind)) (let ((ind (open-sound "oboe.snd"))) (let ((ctr 0)) (map-channel (lambda (y) (or (> (set! ctr (+ ctr 1)) 3) (* y 2))))) (if (not (= (framples ind 0) 3)) (snd-display #__line__ ";map-channel oboe -> #t at 3: ~A" (framples ind 0)) (if (not (vequal (channel->float-vector) (float-vector 0.0 -.001 -.001))) (snd-display #__line__ ";map-channel #t oboe result: ~A" (channel->float-vector)))) (undo) (let ((ctr 0)) (map-channel (lambda (y) (if (= (set! ctr (+ ctr 1)) 3) (make-float-vector 5 .1) (* y .5))))) (if (not (= (framples ind 0) (+ 50828 4))) (snd-display #__line__ ";map-channel oboe -> float-vector at 3: ~A" (framples ind 0)) (if (not (vequal (channel->float-vector 0 10) (float-vector 0.000 -0.000 0.100 0.100 0.100 0.100 0.100 -0.000 -0.000 -0.000))) (snd-display #__line__ ";map-channel float-vector result: ~A" (channel->float-vector 0 10)))) (undo) (let ((data (make-float-vector 2 0.0))) (map-channel (lambda (y) (set! (data 0) y) data))) (if (not (= (framples ind 0) (* 2 50828))) (snd-display #__line__ ";map-channel oboe -> float-vector: ~A" (framples ind 0)) (if (not (vequal (channel->float-vector 0 10) (float-vector 0.000 0.000 -0.000 0.000 -0.000 0.000 -0.000 0.000 -0.000 0.0))) (snd-display #__line__ ";map-channel float-vector result: ~A" (channel->float-vector 0 10)))) (revert-sound) (close-sound ind)) (let ((ind (open-sound "2.snd"))) (ramp-channel 0.9 1.0) (ramp-channel 0.9 1.0) (xramp-channel 0.9 1.0 32.0) (xramp-channel 0.9 1.0 32.0) (mix-float-vector (float-vector .01 .02) 10000 ind 0 #t) (set! (sync ind) 1) (let ((mxs (maxamp ind #t))) (env-sound '(0 .25 1 0.5)) (let ((mxs1 (maxamp ind #t))) (if (or (fneq (car mxs) (* 2.0 (car mxs1))) (fneq (cadr mxs) (* 2.0 (cadr mxs1)))) (snd-display #__line__ ";env-sound sync'd maxes: ~A -> ~A" mxs mxs1))) (undo 1)) (close-sound ind)) (let ((ind (new-sound :channels 2 :size 10 :comment "new-sound for ramp2-xramp2"))) (map-channel (lambda (y) 1.0)) (ramp-channel 0.9 1.0) (ramp-channel 0.9 1.0) (xramp-channel 0.9 1.0 32.0) (xramp-channel 0.9 1.0 32.0) (mix-float-vector (float-vector .1 .2) 1 ind 0 #t) (set! (sync ind) 1) (let ((mxs (maxamp ind #t))) (env-sound '(0 .25 1 0.5)) (let ((mxs1 (maxamp ind #t))) (if (or (fneq (car mxs) (* 2.0 (car mxs1))) (fneq (cadr mxs) (* 2.0 (cadr mxs1)))) (snd-display #__line__ ";env-sound sync'd maxes buf: ~A -> ~A" mxs mxs1))) (undo 1)) (let ((name (file-name ind))) (if (not (= (srate ind) *default-output-srate*)) (snd-display #__line__ ";new-sound default srate: ~A ~A" (srate ind) *default-output-srate*)) (close-sound ind) (if (not (file-exists? name)) (snd-display #__line__ ";new-sound temp? ~A" name) (delete-file name)))) (let ((ind (new-sound "test.snd" :size 40000))) (let ((gen (make-triangle-wave 10.0 0.5))) (clm-channel gen) (src-channel 2)) (let ((ind1 (new-sound "test.snd" :size 40000))) (let ((gen (make-triangle-wave 10.0 0.5))) (clm-channel gen) (src-channel 2.00001)) (let ((dist (channel-distance ind 0 ind1 0))) (if (> dist 0.5) (snd-display #__line__ ";src 2/2.0001: ~A" dist))) (close-sound ind) (close-sound ind1))) (let ((old-width *sinc-width*)) (set! *sinc-width* 10) (let ((res (new-sound :size 10))) (set! (sample 3) .5) (src-channel 2.0) (let ((v (channel->float-vector))) (if (not (vvequal v (float-vector -0.05016523320247118 0.1581800948824515 0.1581800948824515 -0.05016523320247118 0.02716944826115516 -0.01652926966015632))) (snd-display #__line__ ";src 2, 10 3 10: ~A" v))) (close-sound res)) (let ((res (new-sound :size 10))) (set! (sample 2) .5) (src-channel 2.0) (let ((v (channel->float-vector))) (if (not (vvequal v (float-vector 0.0 0.25 0.0 0.0 0.0 0.0))) (snd-display #__line__ ";src 2, 10 2 10: ~A" v))) (close-sound res)) (let ((res (new-sound :size 10))) (set! (sample 0) .5) (src-channel 2.0) (let ((v (channel->float-vector))) (if (not (vvequal v (float-vector 0.25 0.0 0.0 0.0 0.0 0.0))) (snd-display #__line__ ";src 2, 10 0 10: ~A" v))) (close-sound res)) (let ((res (new-sound :size 11))) (set! (sample 3) .5) (src-channel 2.0) (let ((v (channel->float-vector))) (if (not (vvequal v (float-vector -0.05016523320247118 0.1581800948824515 0.1581800948824515 -0.05016523320247118 0.02716944826115516 -0.01652926966015632 0.01022512563738671))) (snd-display #__line__ ";src 2, 11 3 10: ~A" v))) (close-sound res)) (let ((res (new-sound :size 11))) (set! (sample 2) .5) (src-channel 2.0) (let ((v (channel->float-vector))) (if (not (vvequal v (float-vector 0.0 0.25 0.0 0.0 0.0 0.0 0.0))) (snd-display #__line__ ";src 2, 11 2 10: ~A" v))) (close-sound res)) (let ((res (new-sound :size 11))) (set! (sample 0) .5) (src-channel 2.0) (let ((v (channel->float-vector))) (if (not (vvequal v (float-vector 0.25 0.0 0.0 0.0 0.0 0.0 0.0))) (snd-display #__line__ ";src 2, 11 0 10: ~A" v))) (close-sound res)) (let ((res (new-sound :size 40))) (do ((i 0 (+ i 1))) ((= i 20)) (set! (sample i) (* i .05)) (set! (sample (- 39 i)) (* i .05))) (src-channel 2.0) (let ((v (channel->float-vector))) (if (not (vvequal v (float-vector 0.01198528796961999 0.1035793306415383 0.2059748594814547 0.3060708098272395 0.4072307780331241 0.5077603318367317 0.6062448605128621 0.7086656575233007 0.8045885470214085 0.9128440616541418 0.9536620711423869 0.8562080426776515 0.7579855746854125 0.6566287955350736 0.5575138524566664 0.4569842986530586 0.3574772574131896 0.2546643622412894 0.1572853567216201 0.04987330456145658 -0.0009027286222166014))) (format *stderr* "src 2, 40 0 10: ~A~%" v))) (close-sound res)) (set! *sinc-width* 11) (let ((res (new-sound :size 15))) (set! (sample 3) .5) (src-channel 2.0) (let ((v (channel->float-vector))) (if (not (vvequal v (float-vector -0.05103248958541851 0.1584755057631961 0.1584755057631961 -0.05103248958541851 0.02854464095499105 -0.01828991864619797 0.01222560572178551 -0.008180460967128276 0.0))) (snd-display #__line__ ";src 2, 15 3 11: ~A" v))) (close-sound res)) (let ((res (new-sound :size 15))) (set! (sample 0) .5) (src-channel 2.0) (let ((v (channel->float-vector))) (if (not (vvequal v (float-vector 0.25 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0))) (snd-display #__line__ ";src 2, 15 0 11: ~A" v))) (close-sound res)) (set! *sinc-width* old-width)) (let ((old-width *sinc-width*)) (set! *sinc-width* 10) (let ((res (new-sound :size 10))) (set! (sample 3) .5) (src-channel 0.5) (let ((v (channel->float-vector))) (if (not (vvequal v (float-vector 0.0 0.05433889652231032 0.0 -0.1003304664049424 0.0 0.316360189764903 0.5 0.316360189764903 0.0 -0.1003304664049424 0.0 0.05433889652231032 0.0 -0.03305853932031265 0.0 0.02045025127477342 0.0 -0.01220523861007159 0.0 0.006688908032246622 0.0))) (format *stderr* "src 1/2, 10 3 10: ~A~%" v))) (close-sound res)) (let ((res (new-sound :size 10))) (set! (sample 2) .5) (src-channel 0.5) (let ((v (channel->float-vector))) (if (not (vvequal v (float-vector 0.0 -0.1003304664049424 0.0 0.316360189764903 0.5 0.316360189764903 0.0 -0.1003304664049424 0.0 0.05433889652231032 0.0 -0.03305853932031265 0.0 0.02045025127477342 0.0 -0.01220523861007159 0.0 0.006688908032246622 0.0 -0.003110640428161881 0.0))) (format *stderr* "src 1/2, 10 2 10: ~A~%" v))) (close-sound res)) (let ((res (new-sound :size 10))) (set! (sample 0) .5) (src-channel 0.5) (let ((v (channel->float-vector))) (if (not (vvequal v (float-vector 0.5 0.316360189764903 0.0 -0.1003304664049424 0.0 0.05433889652231032 0.0 -0.03305853932031265 0.0 0.02045025127477342 0.0 -0.01220523861007159 0.0 0.006688908032246622 0.0 -0.003110640428161881 0.0 0.001022072692939124 0.0 -0.000103644775079492 0.0))) (format *stderr* "src 1/2, 10 0 10: ~A~%" v))) (close-sound res)) (let ((res (new-sound :size 11))) (set! (sample 3) .5) (src-channel 0.5) (let ((v (channel->float-vector))) (if (not (vvequal v (float-vector 0.0 0.05433889652231032 0.0 -0.1003304664049424 0.0 0.316360189764903 0.5 0.316360189764903 0.0 -0.1003304664049424 0.0 0.05433889652231032 0.0 -0.03305853932031265 0.0 0.02045025127477342 0.0 -0.01220523861007159 0.0 0.006688908032246622 0.0 -0.003110640428161881 0.0))) (format *stderr* "src 1/2, 11 3 10: ~A~%" v))) (close-sound res)) (let ((res (new-sound :size 11))) (set! (sample 2) .5) (src-channel 0.5) (let ((v (channel->float-vector))) (if (not (vvequal v (float-vector 0.0 -0.1003304664049424 0.0 0.316360189764903 0.5 0.316360189764903 0.0 -0.1003304664049424 0.0 0.05433889652231032 0.0 -0.03305853932031265 0.0 0.02045025127477342 0.0 -0.01220523861007159 0.0 0.006688908032246622 0.0 -0.003110640428161881 0.0 0.001022072692939124 0.0))) (format *stderr* "src 1/2, 11 2 10: ~A~%" v))) (close-sound res)) (let ((res (new-sound :size 11))) (set! (sample 0) .5) (src-channel 0.5) (let ((v (channel->float-vector))) (if (not (vvequal v (float-vector 0.5 0.316360189764903 0.0 -0.1003304664049424 0.0 0.05433889652231032 0.0 -0.03305853932031265 0.0 0.02045025127477342 0.0 -0.01220523861007159 0.0 0.006688908032246622 0.0 -0.003110640428161881 0.0 0.001022072692939124 0.0 -0.000103644775079492 0.0 0.0 0.0))) (format *stderr* "src 1/2, 11 0 10: ~A~%" v))) (close-sound res)) (let ((res (new-sound :size 40))) (do ((i 0 (+ i 1))) ((= i 20)) (set! (sample i) (* i .05)) (set! (sample (- 39 i)) (* i .05))) (src-channel 0.5) (let ((v (channel->float-vector))) (if (not (vvequal v (float-vector 0.0 0.02056010532402247 0.05 0.07720130317537323 0.1 0.1238094543862298 0.15 0.1758514952493174 0.2 0.2245876821803736 0.25 0.2753688942389073 0.3 0.3249295824364337 0.35 0.3751591614371849 0.4 0.4250776763951197 0.45 0.4750983986223486 0.5 0.5251191208495776 0.55 0.5750480002850203 0.6000000000000001 0.6251857364939857 0.65 0.6749656459425423 0.7000000000000001 0.7252971884488815 0.75 0.7748042296887507 0.8 0.8255720997331736 0.8500000000000001 0.8742119340573964 0.9 0.9274509253698831 0.9500000000000001 0.9590869443463733 0.9500000000000001 0.9274509253698828 0.9 0.8742119340573966 0.8500000000000001 0.8255720997331734 0.8 0.7748042296887506 0.75 0.7252971884488812 0.7000000000000001 0.6749656459425423 0.65 0.6251857364939858 0.6000000000000001 0.5750480002850203 0.55 0.5251191208495776 0.5 0.4750983986223486 0.45 0.4250776763951198 0.4 0.3751591614371849 0.35 0.3249295824364337 0.3 0.2753688942389073 0.25 0.2245876821803736 0.2 0.1758514952493173 0.15 0.1238094543862298 0.1 0.07720130317537324 0.05 0.02056010532402247 0.0 -0.004445073550837984 0.0))) (format *stderr* "src 1/2, 40 0 10: ~A~%" v))) (close-sound res)) (set! *sinc-width* 11) (let ((res (new-sound :size 15))) (set! (sample 3) .5) (src-channel 0.5) (let ((v (channel->float-vector))) (if (not (vvequal v (float-vector 0.0 0.05588873297652781 0.0 -0.1013169884822853 0.0 0.3166955736757819 0.5 0.3166955736757819 0.0 -0.1013169884822853 0.0 0.05588873297652781 0.0 -0.03503207135776369 0.0 0.02267085373675465 0.0 -0.01446863119016991 0.0 0.008794782253203336 0.0 -0.004875864375201019 0.0 0.002288656235197179 0.0 -0.0007570986863940245 0.0 7.729542250127452e-05 0.0 0.0 0.0))) (format *stderr* "src 1/2, 15 3 11: ~A~%" v))) (close-sound res)) (let ((res (new-sound :size 15))) (set! (sample 0) .5) (src-channel 0.5) (let ((v (channel->float-vector))) (if (not (vvequal v (float-vector 0.5 0.3166955736757819 0.0 -0.1013169884822853 0.0 0.05588873297652781 0.0 -0.03503207135776369 0.0 0.02267085373675465 0.0 -0.01446863119016991 0.0 0.008794782253203336 0.0 -0.004875864375201019 0.0 0.002288656235197179 0.0 -0.0007570986863940245 0.0 7.729542250127452e-05 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0))) (format *stderr* "src 1/2, 15 0 11: ~A~%" v))) (close-sound res)) (set! *sinc-width* 10) (let ((res (new-sound :size 10))) (set! (sample 2) .5) (src-channel 1.5) (let ((v (channel->float-vector))) (if (not (vvequal v (float-vector -0.0659173000292574 0.2750218141864232 0.1361775290259087 -0.05140008051946586 0.02873817799080515 -0.01761592377597271 0.01086818222156537 -0.006418849681280971))) (format *stderr* "src 1.5, 10 0 10: ~A~%" v))) (close-sound res)) (let ((res (new-sound :size 10))) (set! (sample 2) .5) (src-channel 0.3) (let ((v (channel->float-vector))) (if (not (vvequal v (float-vector -2.309626927862667e-14 -0.07046687722856798 -0.1029821798386912 -0.04339187529883121 0.1151049838606023 0.316360189764903 0.4672831482919799 0.4916944808321784 0.3769307110649516 0.1817344234767786 1.953289539319582e-14 -0.09498013189693179 -0.08875244041152466 -0.0236470298331755 0.03764309466867966 0.05433889652231032 0.02735343920407904 -0.01239124709348501 -0.03298325840652785 -0.02431019463203471 4.869902458307762e-14 0.01823801988763548 0.01851483195191724 0.005176164589977362 -0.008430282938941011 -0.01220523861007159 -0.006058987580643592 0.002667220356124145 0.006794601943645224 0.004720812682785585 -3.100277189828097e-14 -0.002989527299513507 -0.002701674743876624 -0.0006539461337230524 0.0008891857488267552))) (format *stderr* "src 0.3, 10 0 10: ~A~%" v))) (close-sound res)) (let ((res (new-sound :size 10)) (e (make-env '(0 1 1 2) :length 11))) (set! (sample 1) .5) (set! (sample 8) .5) (src-channel e) (let ((v (channel->float-vector))) (if (not (vvequal v (float-vector 3.511360236100833e-14 0.499999999999969 0.03245693012152732 -0.04426423670248926 0.05693627592759216 -0.06869987735399859 0.1364034106143399 0.2654607053632132 -0.04771168369895742))) (format *stderr* "src e, 10 0 10: ~A~%" v))) (close-sound res)) (set! *sinc-width* old-width)) (let ((ind (new-sound "test.snd" :size 40000))) (let ((gen (make-triangle-wave 10.0 0.5))) (clm-channel gen) (src-channel 0.5)) (let ((ind1 (new-sound "test.snd" :size 40000))) (let ((gen (make-triangle-wave 10.0 0.5))) (clm-channel gen) (src-channel 0.50001)) (let ((dist (channel-distance ind 0 ind1 0))) (if (> dist 0.5) (snd-display #__line__ ";src 0.5/0.5001: ~A" dist))) (close-sound ind) (close-sound ind1))) )) ) ;;; ---------------- test 17: dialogs and graphics ---------------- (require snd-draw.scm) (if with-gui (require snd-musglyphs.scm)) (require snd-enved.scm) (define (snd_test_17) (define -> (let ((documentation "draw an arrow pointing (from the left) at the point (x0 y0)")) (lambda (x0 y0 size snd chn cr) (let ((points (make-vector 8))) (define (point i x y) (set! (points (* i 2)) x) (set! (points (+ (* i 2) 1)) y)) (define (arrow-head x y) (point 0 x y) (point 1 (- x (* 2 size)) (- y size)) (point 2 (- x (* 2 size)) (+ y size)) (point 3 x y) (fill-polygon points snd chn time-graph cr)) (arrow-head x0 y0) (fill-rectangle (- x0 (* 4 size)) (floor (- y0 (* .4 size))) (* 2 size) (floor (* .8 size)) snd chn time-graph #f cr))))) (if with-gui (begin (require snd-musglyphs.scm) (hook-push after-graph-hook (lambda (hook) (display-previous-edits (hook 'snd) (hook 'chn)))) (hook-push lisp-graph-hook (lambda (hook) (let ((snd (hook 'snd)) (chn (hook 'chn))) (set! (hook 'result) (lambda () (let ((cr (make-cairo (car (channel-widgets snd chn))))) (draw-string "hi" (x->position .5 snd chn lisp-graph) (y->position .5 snd chn lisp-graph) snd chn lisp-graph cr) (free-cairo cr))))))) (let ((ind (open-sound "oboe.snd")) (wids (channel-widgets)) (wids1 (channel-widgets (selected-sound))) (wids2 (channel-widgets (selected-sound) (selected-channel)))) (do ((i 1 (+ i 1))) ((= i 4)) (scale-by 0.5) (set! (x-bounds) (list 0 (* i .3)))) (revert-sound ind) (draw-bass-clef 100 100 100 0 ind 0) (update-time-graph ind 0) (draw-fermata 200 100 60 0 ind 0) (let ((cr (make-cairo (car (channel-widgets ind 0))))) (draw-line 100 100 200 200 ind 0 time-graph cr) (draw-dot 300 300 10 ind 0 time-graph cr) (draw-string "hiho" 20 20 ind 0 time-graph cr) (draw-dots #(25 25 50 50 100 100) 10 ind 0 time-graph cr) (-> 100 50 10 ind 0 cr) (fill-rectangle 20 20 100 100 ind 0 time-graph #f cr) (free-cairo cr)) (make-bezier 0 0 20 20 40 30 60 10 10) (update-time-graph ind 0) ;(fill-rectangle 20 20 100 100 ind 0 time-graph #t) (set! (hook-functions after-graph-hook) ()) (set! (hook-functions lisp-graph-hook) ()) (set! (hook-functions lisp-graph-hook) ()) (let ((ind (open-sound "oboe.snd"))) (set! (time-graph? ind 0) #f) (graph (list (float-vector 0 1 2) (float-vector 3 2 1) (float-vector 1 2 3) (float-vector 1 1 1) (float-vector 0 1 0) (float-vector 3 1 2))) (update-lisp-graph) (hook-push lisp-graph-hook (lambda (hook) (set! (hook 'result) (list *basic-color* *zoom-color* *data-color* *selected-data-color* *mix-color*)))) (graph (list (float-vector 0 1 2) (float-vector 3 2 1) (float-vector 1 2 3) (float-vector 1 1 1) (float-vector 0 1 0) (float-vector 3 1 2))) (update-lisp-graph) (set! (hook-functions lisp-graph-hook) ()) (close-sound ind)) (let* ((ind1 (open-sound "2.snd")) (wids3 (channel-widgets ind1 0)) (wids4 (channel-widgets ind1 1))) (if (or (not (pair? wids)) (not (pair? wids3)) (and (provided? 'snd-motif) (not (= (length wids1) 11 (length wids2))))) (snd-display #__line__ ";channel-widgets confused: ~A ~A ~A ~A ~A" wids wids1 wids2 wids3 wids4)) (hide-widget (car (channel-widgets))) (show-widget (car (channel-widgets))) (close-sound ind1)) (close-sound ind)))) (if with-gui (begin (start-enveloping) (let ((nind (open-sound "oboe.snd"))) (if (not (equal? (channel-envelope nind 0) (list 0.0 1.0 1.0 1.0))) (snd-display #__line__ ";channel-envelope: ~A?" (channel-envelope nind 0))) (set! (channel-envelope nind 0) (list 0 0 1 1 2 0)) (if (not (equal? (channel-envelope nind 0) (list 0 0 1 1 2 0))) (snd-display #__line__ ";set channel-envelope: ~A?" (channel-envelope nind 0))) (close-sound nind) (stop-enveloping)) )) (reset-all-hooks) ) ;;; ---------------- test 18: save and restore ---------------- (require snd-fade.scm) (define* (clm-channel-test snd chn) ; edit-list->function wants this to be global?? (clm-channel (make-two-zero 1 -1) 0 #f snd chn #f #f "clm-channel-test")) (define* (make-v-mix snd chn) (mix-float-vector (float-vector .1 .2 .3) 100 snd chn #t "mix-float-vector (float-vector .1 .2 .3)")) (define* (insert-float-vector v (beg 0) dur snd chn edpos) (if (not (float-vector? v)) (error 'wrong-type-arg "insert-float-vector: ~A" v) (let ((len (or dur (length v)))) (insert-samples beg len v snd chn edpos #f (format #f "insert-float-vector ~A ~A ~A" (float-vector->string v) beg dur))))) (define (snd_test_18) (define hilbert-transform-via-fft (let ((documentation "same as FIR version but use FFT and change phases by hand")) (lambda* (snd chn) (let* ((size (framples snd chn)) (len (expt 2 (ceiling (log size 2.0)))) (rl (make-float-vector len)) (im (make-float-vector len)) (rd (make-sampler 0 snd chn)) (pi2 (* 0.5 pi))) (do ((i 0 (+ i 1))) ((= i size)) (set! (rl i) (rd))) (mus-fft rl im len) (rectangular->polar rl im) (float-vector-offset! im (- pi2)) (do ((i (/ len 2) (+ i 1))) ((= i len)) (float-vector-set! im i (+ (float-vector-ref im i) pi))) (polar->rectangular rl im) (mus-fft rl im len -1) (float-vector-scale! rl (/ 1.0 len)) (float-vector->channel rl 0 len snd chn #f "hilbert-transform-via-fft"))))) ;; echoes with each echo at a new pitch via ssb-am etc #| ;; old form (define* (make-ssb-transposer old-freq new-freq pairs (order 40) (bw 50.0)) (let ((ssbs (make-vector pairs)) (bands (make-vector pairs)) (factor (/ (- new-freq old-freq) old-freq))) (do ((i 1 (+ i 1))) ((> i pairs)) (let ((aff (* i old-freq)) (bwf (* bw (+ 1.0 (/ i (* 2 pairs)))))) (set! (ssbs (- i 1)) (make-ssb-am (* i factor old-freq))) (set! (bands (- i 1)) (make-bandpass (hz->radians (- aff bwf)) (hz->radians (+ aff bwf)) order)))) (list ssbs bands))) (define (ssb-transpose transposer input) (let* ((sum 0.0) (ssbs (car transposer)) (bands (cadr transposer)) (pairs (length ssbs))) (do ((i 0 (+ i 1))) ((= i pairs) sum) (set! sum (+ sum (ssb-am (vector-ref ssbs i) (bandpass (vector-ref bands i) input))))))) (define (make-fdelay len pitch scaler) (let ((dly (make-delay len)) (ssb (make-ssb-transposer 440.0 (* 440.0 pitch) 10))) (lambda (input) (delay dly (+ input (* scaler (ssb-transpose ssb (tap dly)))))))) (define (transposed-echo pitch scaler secs) (map-channel (make-fdelay (round (* secs (srate))) pitch scaler))) |# (define-macro (make-fdelay len pitch scaler) `(let ((body ()) (closure (list (list 'dly (list 'make-delay ,len)))) (old-freq 440.0) (new-freq (* 440.0 ,pitch)) (pairs 10) (order 40) (bw 50.0)) (let ((factor (/ (- new-freq old-freq) old-freq))) (do ((i 1 (+ i 4))) ((> i pairs)) (let ((inner-body ()) (n (+ 1 (min 3 (- pairs i))))) (do ((k 0 (+ k 1))) ; the inner loop is dividing up large sums for the optimizer's benefit (it can handle 4 at a time currently) ((= k n)) (let ((aff (* (+ i k) old-freq)) (bwf (* bw (+ 1.0 (/ (+ i k) (* 2 pairs))))) (ssb (string->symbol (format #f "s~D" (+ i k)))) (flt (string->symbol (format #f "g~D" (+ i k))))) (set! closure (cons (list ssb (list 'make-ssb-am (* (+ i k) old-freq factor))) (cons (list flt (list 'make-bandpass (hz->radians (- aff bw)) (hz->radians (+ aff bw)) order)) closure))) (set! inner-body (cons (list 'ssb-am ssb (list 'bandpass flt 'y)) inner-body)))) (set! body (cons (append (list '+) inner-body) body)))) (apply let closure `((lambda (y) (+ y (delay dly (* ,,scaler (+ ,@body)))))))))) (define (transposed-echo pitch scaler secs) (map-channel (make-fdelay (round (* secs (srate))) pitch scaler))) (define (local-eq? a b) (if (number? a) (if (rational? a) (= a b) (< (abs (- a b)) .001)) (eq? a b))) ;; from dsp.scm (commented out) (define (repitch-sound old-freq new-freq) (ssb-bank old-freq new-freq 10)) (define (retime-sound new-time) (let* ((old-time (/ (framples) (srate))) (factor (/ new-time old-time))) (ssb-bank 557 (* 557 factor) 10) (src-sound (/ 1.0 factor)))) (let ((nind (open-sound "oboe.snd"))) (add-mark 123) (delete-sample 12) (set! (x-bounds) (list .2 .4)) (let ((old-bounds (x-bounds))) (set! *show-axes* show-all-axes) (set! *transform-graph-type* graph-as-sonogram) (set! *speed-control-style* speed-control-as-ratio) (set! *channel-style* channels-superimposed) (set! *enved-target* enved-srate) (set! (sound-property :hi nind) "hi") (set! (sound-property 'ho nind) 1234) (set! (channel-property :ha nind 0) 3.14) (set! (hook-functions after-save-state-hook) ()) (hook-push before-save-state-hook (lambda (hook) (with-output-to-file (hook 'name) (lambda () (format #t ";this comment will be at the top of the saved state file.~%~%") (set! (hook 'result) #t))))) (if (file-exists? *save-state-file*) (delete-file *save-state-file*)) (save-state *save-state-file*) (close-sound nind) (for-each forget-region (regions)) (load (string-append cwd *save-state-file*)) (let ((ind (find-sound "oboe.snd"))) (if (not (sound? ind)) (snd-display #__line__ ";can't restore oboe.snd from ~A?" *save-state-file*) (begin (if (or (> (abs (- (car old-bounds) (car (x-bounds ind 0)))) .05) (> (abs (- (cadr old-bounds) (cadr (x-bounds ind 0)))) .05)) (snd-display #__line__ ";save bounds: ~A" (x-bounds ind 0))) (if (not (= (length (marks ind 0)) 1)) (snd-display #__line__ ";save marks: ~A (~A)?" (marks ind 0) *save-state-file*) (begin (if (not (= (mark-sample (car (marks ind 0))) 122)) (snd-display #__line__ ";save mark: ~A?" (mark-sample (car (marks ind 0))))) (if (not (= (edit-position ind 0) 1)) (snd-display #__line__ ";save edit-position: ~A" (edit-position ind 0))))) (if (not (equal? (edit-fragment 1 ind 0) (list "delete-samples 12 1" "delete" 12 1))) (snd-display #__line__ ";save edits: ~A" (edit-fragment 1 ind 0))) (if (not (equal? (edit-tree ind 0) (list (list 0 0 0 11 1.0 0.0 0.0 0) (list 12 0 13 50827 1.0 0.0 0.0 0) (list 50827 -2 0 0 0.0 0.0 0.0 0)))) (snd-display #__line__ ";save edit tree: ~A" (edit-tree ind 0))) (if (or (not (number? (sound-property 'ho ind))) (not (= (sound-property 'ho ind) 1234))) (snd-display #__line__ ";sound-property saved: 1234 -> ~A" (sound-property 'ho ind))) (if (or (not (string? (sound-property :hi ind))) (not (string=? (sound-property :hi ind) "hi"))) (snd-display #__line__ ";sound-property saved: hi -> ~A" (sound-property :hi ind))) (if (or (not (number? (channel-property :ha ind 0))) (fneq (channel-property :ha ind 0) 3.14)) (snd-display #__line__ ";channel-property saved: 3.14 -> ~A" (channel-property :ha ind 0))) (close-sound ind))) (set! (hook-functions after-save-state-hook) ()) (set! (hook-functions before-save-state-hook) ()) (let ((err (catch 'cannot-save (lambda () (save-state "/bad/bad.save")) (lambda args 12345)))) (if (not (= err 12345)) (snd-display #__line__ ";save-state err: ~A?" err))) (let ((err (catch 'cannot-save (lambda () (save-listener "/bad/bad.save")) (lambda args 12345)))) (if (not (= err 12345)) (snd-display #__line__ ";save-listener err: ~A?" err))) )) (set! nind (open-sound "oboe.snd")) (set! (sample 1) .5) (delete-sample 100) (insert-sample 10 .5) (scale-channel 2.0) (insert-silence 100 20) (save-edit-history "hiho.scm") (revert-sound nind) (set! sfile nind) (load (string-append cwd "hiho.scm")) (if (not (equal? (edit-fragment 1) '("set-sample 1 0.5000" "set" 1 1))) (snd-display #__line__ ";save-edit-history 1: ~A?" (edit-fragment 1))) (if (not (equal? (edit-fragment 2) '("delete-samples 100 1" "delete" 100 1))) (snd-display #__line__ ";save-edit-history 2: ~A?" (edit-fragment 2))) (if (not (equal? (edit-fragment 3) '("insert-sample 10 0.5000" "insert" 10 1))) (snd-display #__line__ ";save-edit-history 3: ~A?" (edit-fragment 3))) (if (not (equal? (edit-fragment 4) '("scale-channel 2.000 0 #f" "scale" 0 50828))) (snd-display #__line__ ";save-edit-history 4: ~A?" (edit-fragment 4))) (if (not (equal? (edit-fragment 5) '("pad-channel" "zero" 100 20))) (snd-display #__line__ ";save-edit-history 5: ~A?" (edit-fragment 5))) (save-edit-history "hiho.scm" nind 0) (scale-sound-to 1.0 0 (framples nind 0) nind 0) (let ((eds (edit-position nind 0)) (val (insert-sound "zero.snd"))) (if (or (not (= 0 val)) (not (= eds (edit-position nind 0)))) (snd-display #__line__ ";insert-sound zero.snd was an edit? ~A ~A ~A" val eds (edit-position nind 0)))) (revert-sound nind) (scale-sound-to 0.5 0 (framples nind 0) nind 0) (if (fneq (maxamp nind 0) 0.5) (snd-display #__line__ ";scale-sound-to 0.5: ~A" (maxamp nind))) (close-sound nind) (let ((nind (open-sound "oboe.snd"))) (ramp-channel 0.0 1.0) (xramp-channel 0.0 1.0 32.0) (save-edit-history "hiho.scm") (revert-sound nind) (set! sfile nind) (load (string-append cwd "hiho.scm")) (if (not (equal? (edit-fragment 1) '("ramp-channel 0.000 1.000 0 #f" "env" 0 50828))) (snd-display #__line__ ";save-edit-history ramp 1: ~A?" (edit-fragment 1))) (if (not (equal? (edit-fragment 2) '("xramp-channel 0.000 1.000 32.000 0 #f" "env" 0 50828))) (snd-display #__line__ ";save-edit-history xramp 2: ~A?" (edit-fragment 2))) (revert-sound nind) (let ((str (file->string "hiho.scm"))) (if (not (string=? str " (ramp-channel 0.000 1.000 0 #f sfile 0 #f) (xramp-channel 0.000 1.000 32.000 0 #f sfile 0 #f) ")) (snd-display #__line__ ";file->string: ~A" str))) (close-sound nind)) (add-sound-file-extension "ogg") (add-sound-file-extension "OGG") (add-sound-file-extension "sf") (add-sound-file-extension "SF2") (add-sound-file-extension "mp3") (add-sound-file-extension "MP3") (add-sound-file-extension "W01") (add-sound-file-extension "W02") (add-sound-file-extension "W03") (add-sound-file-extension "W04") (add-sound-file-extension "W05") (add-sound-file-extension "W06") (add-sound-file-extension "W07") (add-sound-file-extension "W08") (add-sound-file-extension "W09") (add-sound-file-extension "W10") (add-sound-file-extension "w01") (add-sound-file-extension "w02") (add-sound-file-extension "w03") (add-sound-file-extension "w04") (add-sound-file-extension "w05") (add-source-file-extension "gad") (let ((ind (new-sound "fmv.snd"))) (set! (sample 10) .1) (save-sound ind) (set! (sample 1) .1) (let () (safe-display-edits ind) (if (file-exists? "t1.scm") (delete-file "t1.scm")) (save-state "t1.scm") (close-sound ind) (for-each forget-region (regions)) (load (string-append cwd "t1.scm")) (set! ind (find-sound "fmv.snd")) (if (not (sound? ind)) (snd-display #__line__ ";save-state restored but no sound?")) (do ((i 3 (+ i 1))) ((= i 6)) (set! (sample i) (* i .1)) (safe-display-edits ind) (if (file-exists? "t1.scm") (delete-file "t1.scm")) (save-state "t1.scm") (close-sound ind) (for-each forget-region (regions)) (load (string-append cwd "t1.scm")) (set! ind (find-sound "fmv.snd")) (if (not (sound? ind)) (snd-display #__line__ ";save-state ~A restored but no sound?" i)))) (close-sound ind) (delete-file "t1.scm")) (let ((ind (new-sound "fmv.snd" 8 22050 mus-ldouble mus-next "this is an 8-channel save-state test")) (ind1 (new-sound "fmv1.snd" 2 22050 mus-ldouble mus-next "this is a 2-channel save-state test"))) (set! (sample 10 ind 0) .1) (set! (sample 10 ind 1) .2) (set! (sample 10 ind 2) .3) (set! (sample 10 ind 3) .4) (set! (sample 10 ind1 0) -.1) (set! (sample 10 ind1 1) -.2) (save-sound ind) (save-sound ind1) (set! (sample 1 ind 0) .1) (set! (sample 1 ind 1) .2) (set! (sample 1 ind 2) .3) (set! (sample 1 ind 3) .4) (set! (sample 1 ind1 0) -.1) (set! (sample 1 ind1 1) -.2) (safe-display-edits ind) (safe-display-edits ind1) (if (file-exists? "t1.scm") (delete-file "t1.scm")) (save-state "t1.scm") (close-sound ind) (close-sound ind1) (for-each forget-region (regions)) (load (string-append cwd "t1.scm")) (set! ind (find-sound "fmv.snd")) (set! ind1 (find-sound "fmv1.snd")) (if (or (not (sound? ind)) (not (sound? ind1))) (snd-display #__line__ ";save-state(2) restored but no sound? ~A ~A" ind ind1)) (close-sound ind) (close-sound ind1) (delete-file "t1.scm")) (let ((ind (open-sound "oboe.snd")) (old-save-dir *save-dir*) (old-eps-file *eps-file*)) (set! *save-dir* #f) (let ((v (make-float-vector 32 1.0))) (set! (samples 100 32) v)) (map-channel (lambda (y) (+ y .1)) 1000 10000) (set! (show-axes ind 0) show-no-axes) (set! *zoom-focus-style* zoom-focus-middle) (set! (transform-normalization ind 0) dont-normalize) (set! (graph-style ind 0) graph-filled) (set! (transform-graph-type ind 0) graph-as-spectrogram) (set! (time-graph-type ind 0) graph-as-wavogram) (set! (x-axis-style ind 0) x-axis-as-percentage) (set! (speed-control-style ind) speed-control-as-semitone) (set! (cursor ind 0) 1234) (set! *eps-file* "hiho.eps") (set! (amp-control-bounds ind) (list 0.0 2.5)) (set! (speed-control-bounds ind) (list 1.0 2.5)) (set! (reverb-control-scale-bounds ind) (list 0.0 2.5)) (set! (reverb-control-length-bounds ind) (list 0.0 2.5)) (set! (contrast-control-bounds ind) (list 0.0 2.5)) (set! (x-axis-label ind 0 time-graph) "time-x") (set! (y-axis-label ind 0 time-graph) "amp-y") (let ((old-srate *clm-srate*) (old-file-buffer-size *clm-file-buffer-size*) (old-array-print-length *mus-array-print-length*) (old-clm-table-size *clm-table-size*)) (set! *clm-srate* 48000) (set! *mus-array-print-length* 24) (set! *clm-file-buffer-size* 4096) (set! *clm-table-size* 256) (if (file-exists? "s61.scm") (delete-file "s61.scm")) (save-state "s61.scm") (close-sound ind) (for-each forget-region (regions)) (load (string-append cwd "s61.scm")) (if (fneq *clm-srate* 48000.0) (snd-display #__line__ ";save/restore mus-srate: ~A" *clm-srate*)) (if (not (= *clm-file-buffer-size* 4096)) (snd-display #__line__ ";save/restore mus-file-buffer-size: ~A" *clm-file-buffer-size*)) (if (not (= *mus-array-print-length* 24)) (snd-display #__line__ ";save/restore mus-array-print-length: ~A" *mus-array-print-length*)) (if (not (= *clm-table-size* 256)) (snd-display #__line__ ";save/restore clm-table-size: ~A" *clm-table-size*)) (set! *clm-srate* old-srate) (set! *mus-array-print-length* old-array-print-length) (set! *clm-file-buffer-size* old-file-buffer-size) (set! *clm-table-size* old-clm-table-size)) (set! *save-dir* old-save-dir) (set! ind (find-sound "oboe.snd")) (if (not (= (show-axes ind 0) show-no-axes)) (snd-display #__line__ ";save show-no-axes: ~A" (show-axes ind 0))) (if (not (= *zoom-focus-style* zoom-focus-middle)) (snd-display #__line__ ";save zoom-focus-middle: ~A" *zoom-focus-style*)) (if (not (= (transform-normalization ind 0) dont-normalize)) (snd-display #__line__ ";save dont-normalize: ~A" (transform-normalization ind 0))) (if (not (= (graph-style ind 0) graph-filled)) (snd-display #__line__ ";save graph-filled: ~A" (graph-style ind 0))) (if (not (= (transform-graph-type ind 0) graph-as-spectrogram)) (snd-display #__line__ ";save graph-as-spectrogram: ~A" (transform-graph-type ind 0))) (if (not (= (time-graph-type ind 0) graph-as-wavogram)) (snd-display #__line__ ";save graph-as-wavogram: ~A" (time-graph-type ind 0))) (if (not (= (x-axis-style ind 0) x-axis-as-percentage)) (snd-display #__line__ ";save x-axis-as-percentage: ~A" (x-axis-style ind 0))) (if (not (= (speed-control-style ind) speed-control-as-semitone)) (snd-display #__line__ ";save speed-control-style: ~A" (speed-control-style ind))) (if (not (= (cursor ind 0) 1234)) (snd-display #__line__ ";save cursor 1234: ~A" (cursor ind 0))) (if (not (string=? *eps-file* "hiho.eps")) (snd-display #__line__ ";save eps-file: ~A" *eps-file*)) (when with-gui (if (not (string=? (x-axis-label ind 0 time-graph) "time-x")) (snd-display #__line__ ";save x-axis-label: ~A" (x-axis-label ind 0 time-graph))) (if (not (string=? (y-axis-label ind 0 time-graph) "amp-y")) (snd-display #__line__ ";save y-axis-label: ~A" (y-axis-label ind 0 time-graph)))) (if (not (feql (amp-control-bounds ind) (list 0 2.5))) (snd-display #__line__ ";save amp-control-bounds: ~A" (amp-control-bounds ind))) (if (not (feql (speed-control-bounds ind) (list 1.0 2.5))) (snd-display #__line__ ";save speed-control-bounds: ~A" (speed-control-bounds ind))) (if (not (feql (contrast-control-bounds ind) (list 0 2.5))) (snd-display #__line__ ";save contrast-control-bounds: ~A" (contrast-control-bounds ind))) (if (not (feql (reverb-control-scale-bounds ind) (list 0 2.5))) (snd-display #__line__ ";save reverb-control-scale-bounds: ~A" (reverb-control-scale-bounds ind))) (if (not (feql (reverb-control-length-bounds ind) (list 0 2.5))) (snd-display #__line__ ";save reverb-control-length-bounds: ~A" (reverb-control-length-bounds ind))) (set! *eps-file* old-eps-file) (delete-file "s61.scm") (close-sound ind)) (let ((ind (open-sound "oboe.snd")) (old-tiny-font *tiny-font*) (old-peaks-font *peaks-font*) (old-bold-peaks-font *bold-peaks-font*) (old-amp (amp-control-bounds)) (old-speed (speed-control-bounds)) (old-contrast (contrast-control-bounds)) (old-revlen (reverb-control-length-bounds)) (old-revscl (reverb-control-scale-bounds))) (set! *tiny-font* "8x13") (set! *peaks-font* "8x13") (set! *bold-peaks-font* "8x13") (set! (amp-control-bounds) (list 0.0 2.5)) (set! (speed-control-bounds) (list 1.0 2.5)) (set! (reverb-control-scale-bounds) (list 0.0 2.5)) (set! (reverb-control-length-bounds) (list 0.0 2.5)) (set! (contrast-control-bounds) (list 0.0 2.5)) (save-state "s61.scm") (close-sound ind) (for-each forget-region (regions)) (load (string-append cwd "s61.scm")) (if (not (string=? *tiny-font* "8x13")) (snd-display #__line__ ";save tiny-font: ~A" *tiny-font*)) (if (not (string=? *peaks-font* "8x13")) (snd-display #__line__ ";save peaks-font: ~A" *peaks-font*)) (if (not (string=? *bold-peaks-font* "8x13")) (snd-display #__line__ ";save bold-peaks-font: ~A" *bold-peaks-font*)) (if (not (feql (amp-control-bounds) (list 0 2.5))) (snd-display #__line__ ";save amp-control-bounds: ~A" (amp-control-bounds))) (if (not (feql (speed-control-bounds) (list 1.0 2.5))) (snd-display #__line__ ";save speed-control-bounds: ~A" (speed-control-bounds))) (if (not (feql (contrast-control-bounds) (list 0 2.5))) (snd-display #__line__ ";save contrast-control-bounds: ~A" (contrast-control-bounds))) (if (not (feql (reverb-control-scale-bounds) (list 0 2.5))) (snd-display #__line__ ";save reverb-control-scale-bounds: ~A" (reverb-control-scale-bounds))) (if (not (feql (reverb-control-length-bounds) (list 0 2.5))) (snd-display #__line__ ";save reverb-control-length-bounds: ~A" (reverb-control-length-bounds))) (set! *tiny-font* old-tiny-font) (set! *peaks-font* old-peaks-font) (set! *bold-peaks-font* old-bold-peaks-font) (set! (amp-control-bounds) old-amp) (set! (speed-control-bounds) old-speed) (set! (contrast-control-bounds) old-contrast) (set! (reverb-control-scale-bounds) old-revscl) (set! (reverb-control-length-bounds) old-revlen) (delete-file "s61.scm") (close-sound ind)) (let* ((ind (open-sound "oboe.snd")) (funcs (list transform-graph-type time-graph-type show-axes transform-normalization graph-style x-axis-style spectro-x-scale transform-size fft-window dot-size max-transform-peaks with-verbose-cursor zero-pad min-dB spectro-hop spectrum-end cursor-size cursor-style)) (func-names (list 'transform-graph-type 'time-graph-type 'show-axes 'transform-normalization 'graph-style 'x-axis-style 'spectro-x-scale 'transform-size 'fft-window 'dot-size 'max-transform-peaks 'with-verbose-cursor 'zero-pad 'min-dB 'spectro-hop 'spectrum-end 'cursor-size 'cursor-style)) (old-globals (map (lambda (func) (func)) funcs)) (new-globals (list graph-as-sonogram graph-as-wavogram show-all-axes normalize-by-sound graph-dots x-axis-in-samples 0.1 32 bartlett-window 4 10 #t 1 -90 12 .1 15 cursor-cross)) (new-locals (list graph-once graph-once show-x-axis normalize-by-channel graph-lines x-axis-in-seconds 1.0 256 blackman2-window 1 100 #f 0 -60 4 1.0 25 cursor-line))) (for-each (lambda (func func-name global local) (set! (func) global) (set! (func ind 0) local)) funcs func-names new-globals new-locals) (set! *zoom-focus-style* zoom-focus-right) (set! *channel-style* channels-combined) (set! (channel-style ind) channels-separate) (if (file-exists? "s61.scm") (delete-file "s61.scm")) (save-state "s61.scm") (close-sound ind) (for-each forget-region (regions)) (load (string-append cwd "s61.scm")) (set! ind (find-sound "oboe.snd")) (when with-gui (for-each (lambda (func func-name global local) (if (or (not (local-eq? (func) global)) (not (local-eq? (func ind 0) local))) (snd-display #__line__ "; save ~A reversed: ~A [~A] ~A [~A]" func-name (func) global (func ind 0) local))) funcs func-names new-globals new-locals)) (if (not (= (channel-style ind) channels-separate)) (snd-display #__line__ ";save channel-style reversed: ~A ~A" *channel-style* (channel-style ind))) (for-each (lambda (func val) (set! (func) val)) funcs old-globals) (close-sound ind) (set! *zoom-focus-style* zoom-focus-active) (set! *channel-style* channels-separate) (delete-file "s61.scm")) (let ((ind0 (open-sound "oboe.snd")) (ind1 (open-sound "oboe.snd"))) (if (not (member (find-sound "oboe.snd" 0) (list ind0 ind1))) (snd-display #__line__ ";find-sound 0: ~A ~A" (list ind0 ind1) (find-sound "oboe.snd" 0))) (if (not (member (find-sound "oboe.snd" 1) (list ind0 ind1))) (snd-display #__line__ ";find-sound 1: ~A ~A" (list ind0 ind1) (find-sound "oboe.snd" 1))) (add-mark 123 ind0) (add-mark 321 ind1) (if (file-exists? "s61.scm") (delete-file "s61.scm")) (save-state "s61.scm") (close-sound ind0) (close-sound ind1) (load (string-append cwd "s61.scm")) (set! ind0 (find-sound "oboe.snd" 0)) (set! ind1 (find-sound "oboe.snd" 1)) (if (or (not ind0) (not ind1)) (snd-display #__line__ ";saved 2oboes, found: ~A" (map short-file-name (sounds)))) (if (not (find-mark 123 ind0)) (snd-display #__line__ ";saved 2oboes mark 0?")) (if (find-mark 123 ind1) (snd-display #__line__ ";saved 2oboes mark 1->0?")) (if (not (find-mark 321 ind1)) (snd-display #__line__ ";saved 2oboes mark 1?")) (if (find-mark 321 ind0) (snd-display #__line__ ";saved 2oboes mark 0->1?")) (close-sound ind0) (close-sound ind1)) (let ((ctr 1)) (for-each (lambda (func test) (let ((ind (new-sound "test.snd" 1 22050 mus-ldouble mus-next "mono save-state tests" 100))) (func ind) (if (file-exists? "s61.scm") (delete-file "s61.scm")) (save-state "s61.scm") (close-sound ind) (load (string-append cwd "s61.scm")) (set! ind (find-sound "test.snd")) (if (not (sound? ind)) (snd-display #__line__ ";save-state test ~D no test.snd?" ctr) (begin (test ind) (close-sound ind))) (set! ctr (+ ctr 1)))) (list ;; basic choices (lambda (ind) (insert-sample 10 .5 ind 0)) (lambda (ind) (delete-sample 10 ind 0)) (lambda (ind) (set! (sample 10 ind 0) .5)) (lambda (ind) (set! (sample 10 ind 0) .5) (scale-channel .5)) (lambda (ind) (float-vector->channel (make-float-vector 10 .5) 10 5 ind 0) (pad-channel 12 5 ind 0)) (lambda (ind) (map-channel (lambda (y) 1.0)) (env-channel '(0 0 1 1) 0 11 ind 0)) (lambda (ind) (map-channel (lambda (y) (+ y .1)))) ;; map-channel as backup (lambda (ind) (let ((p (make-one-pole 1.0 -1.0))) (map-channel (lambda (y) (and (even? (floor (one-pole p 1.0))) .1))))) ;; as-one-edit (lambda (ind) ;; change (as-one-edit (lambda () (float-vector->channel (float-vector .1 .2 .3 .4 .5 .6 .7 .8 .9 1.0) 0 10 ind 0) (float-vector->channel (float-vector .1 .2 .3 .4 .5 .6 .7 .8 .9 1.0) 20 10 ind 0)))) (lambda (ind) ;; scale (as-one-edit (lambda () (float-vector->channel (float-vector .1 .2 .3 .4 .5 .6 .7 .8 .9 1.0) 0 10 ind 0) (scale-by .5)))) (lambda (ind) ;; delete (as-one-edit (lambda () (float-vector->channel (float-vector .1 .2 .3 .4 .5 .6 .7 .8 .9 1.0) 0 10 ind 0) (delete-samples 5 5)))) (lambda (ind) ;; insert (as-one-edit (lambda () (delete-samples 5 5) (insert-samples 5 2 (float-vector .1 .2))))) ) (list ;; basic cases (lambda (ind) (if (fneq (sample 10) .5) (snd-display #__line__ ";insert-sample save-state: ~A" (channel->float-vector 5 10 ind 0))) (if (not (= (framples ind 0) 101)) (snd-display #__line__ ";insert-sample save-state len: ~A" (framples ind 0)))) (lambda (ind) (if (fneq (sample 10) 0.0) (snd-display #__line__ ";delete-sample save-state: ~A" (channel->float-vector 5 10 ind 0))) (if (not (= (framples ind 0) 99)) (snd-display #__line__ ";delete-sample save-state len: ~A" (framples ind 0)))) (lambda (ind) (if (fneq (sample 10) .5) (snd-display #__line__ ";set sample save-state: ~A" (channel->float-vector 5 10 ind 0))) (if (not (= (framples ind 0) 100)) (snd-display #__line__ ";set sample save-state len: ~A" (framples ind 0)))) (lambda (ind) (if (fneq (sample 10) .25) (snd-display #__line__ ";scl sample save-state: ~A" (channel->float-vector 5 10 ind 0))) (if (not (= (framples ind 0) 100)) (snd-display #__line__ ";scl sample save-state len: ~A" (framples ind 0))) (if (not (= (edit-position ind 0) 2)) (snd-display #__line__ ";scl sample save-state edpos: ~A" (edit-position ind 0)))) (lambda (ind) (if (not (= (framples ind 0) 105)) (snd-display #__line__ ";pad sample save-state len: ~A" (framples ind 0))) (if (not (= (edit-position ind 0) 2)) (snd-display #__line__ ";pad sample save-state edpos: ~A" (edit-position ind 0))) (if (not (vequal (float-vector .5 .5 0 0 0 0 0 .5 .5 .5) (channel->float-vector 10 10 ind 0))) (snd-display #__line__ ";pad sample save-state: ~A" (channel->float-vector 10 10 ind 0)))) (lambda (ind) (if (not (= (framples ind 0) 100)) (snd-display #__line__ ";env sample save-state len: ~A" (framples ind 0))) (if (not (= (edit-position ind 0) 2)) (snd-display #__line__ ";env sample save-state edpos: ~A" (edit-position ind 0))) (if (not (vequal (float-vector 0 .1 .2 .3 .4 .5 .6 .7 .8 .9 1.0 1.0 1.0 1.0 1.0) (channel->float-vector 0 15 ind 0))) (snd-display #__line__ ";env sample save-state: ~A" (channel->float-vector 0 15 ind 0)))) (lambda (ind) (if (not (= (framples ind 0) 100)) (snd-display #__line__ "; sample save-state len: ~A" (framples ind 0))) (if (not (= (edit-position ind 0) 1)) (snd-display #__line__ "; sample save-state edpos: ~A" (edit-position ind 0))) (if (fneq (maxamp ind 0) .1) (snd-display #__line__ "; save-state max: ~A" (maxamp ind 0))) (if (not (vequal (make-float-vector 10 .1) (channel->float-vector 0 10))) (snd-display #__line__ "; save-state vals: ~A" (channel->float-vector 0 10 ind 0)))) ;; map-channel as backup (lambda (ind) (if (not (= (framples ind 0) 50)) (snd-display #__line__ ";map #f save-state len: ~A" (framples ind 0))) (if (not (= (edit-position ind 0) 1)) (snd-display #__line__ ";map #f save-state edpos: ~A" (edit-position ind 0))) (if (fneq (maxamp ind 0) .1) (snd-display #__line__ ";map #f save-state max: ~A" (maxamp ind 0))) (if (not (vequal (make-float-vector 10 .1) (channel->float-vector 0 10))) (snd-display #__line__ ";map #f save-state vals: ~A" (channel->float-vector 0 10 ind 0)))) ;; as-one-edit (lambda (ind) (if (not (= (edit-position ind 0) 1)) (snd-display #__line__ ";save-state backup 2 float-vectors edpos: ~A" (edit-position ind 0))) (if (not (vequal (channel->float-vector 0 10 ind 0) (float-vector .1 .2 .3 .4 .5 .6 .7 .8 .9 1.0))) (snd-display #__line__ ";as-one-edit save-state 1: ~A" (channel->float-vector 0 10 ind 0))) (if (not (vequal (channel->float-vector 20 10 ind 0) (float-vector .1 .2 .3 .4 .5 .6 .7 .8 .9 1.0))) (snd-display #__line__ ";as-one-edit save-state 2: ~A" (channel->float-vector 0 10 ind 0)))) (lambda (ind) (if (not (= (edit-position ind 0) 1)) (snd-display #__line__ ";save-state backup float-vector+scl edpos: ~A" (edit-position ind 0))) (if (not (vequal (channel->float-vector 0 10 ind 0) (float-vector-scale! (float-vector .1 .2 .3 .4 .5 .6 .7 .8 .9 1.0) .5))) (snd-display #__line__ ";as-one-edit save-state 3: ~A" (channel->float-vector 0 10 ind 0)))) (lambda (ind) (if (not (= (edit-position ind 0) 1)) (snd-display #__line__ ";save-state backup float-vector+del edpos: ~A" (edit-position ind 0))) (if (not (vequal (channel->float-vector 0 10 ind 0) (float-vector .1 .2 .3 .4 .5 0 0 0 0 0))) (snd-display #__line__ ";as-one-edit save-state 4: ~A" (channel->float-vector 0 10 ind 0)))) (lambda (ind) (if (not (= (edit-position ind 0) 1)) (snd-display #__line__ ";save-state backup del+insert edpos: ~A" (edit-position ind 0))) (if (not (vequal (channel->float-vector 0 10 ind 0) (float-vector 0 0 0 0 0 .1 .2 0 0 0))) (snd-display #__line__ ";as-one-edit save-state 5: ~A" (channel->float-vector 0 10 ind 0))) (if (not (= (framples ind 0) 97)) (snd-display #__line__ ";save-state backup del+insert len: ~A" (framples ind 0)))) ))) ;; ---------------- edit-list->function ---------------- (let ((ind (open-sound "oboe.snd"))) (let ((mx0 (maxamp)) (frs (framples))) ;; ---- simple scale (scale-channel 2.0) (if (fneq (* 2 mx0) (maxamp)) (snd-display #__line__ ";edit-list->function off to a bad start: ~A" (maxamp))) (let ((func (edit-list->function))) (if (not (procedure? func)) (snd-display #__line__ ";edit-list->function 1: ~A" func)) (if (not (equal? (procedure-source func) '(lambda (snd chn) (scale-channel 2.0 0 #f snd chn)))) (snd-display #__line__ ";edit-list->function 1: ~A" (procedure-source func))) (func ind 0) (let ((mx (maxamp))) (if (fneq (* 4 mx0) mx) (snd-display #__line__ ";edit-list->function called (1): ~A ~A" mx mx0)))) (revert-sound ind) (scale-by 2.0) (let ((func (edit-list->function))) (if (not (procedure? func)) (snd-display #__line__ ";edit-list->function 1a: ~A" func)) (if (not (equal? (procedure-source func) '(lambda (snd chn) (scale-channel 2.0 0 #f snd chn)))) (snd-display #__line__ ";edit-list->function 1a: ~A" (procedure-source func)))) (revert-sound ind) (normalize-channel 1.0) (let ((func (edit-list->function))) (if (not (procedure? func)) (snd-display #__line__ ";edit-list->function 1c: ~A" func)) (if (not (equal? (procedure-source func) '(lambda (snd chn) (normalize-channel 1.0 0 #f snd chn)))) (snd-display #__line__ ";edit-list->function 1c: ~A" (procedure-source func)))) (revert-sound ind) ;; ---- simple delete (delete-samples 10 100) (if (not (= (framples) (- frs 100))) (snd-display #__line__ ";edit-list->function delete: ~A ~A" frs (framples))) (let ((func (edit-list->function))) (if (not (procedure? func)) (snd-display #__line__ ";edit-list->function 2: ~A" func)) (if (not (equal? (procedure-source func) '(lambda (snd chn) (delete-samples 10 100 snd chn)))) (snd-display #__line__ ";edit-list->function 2: ~A" (procedure-source func))) (func ind 0) (if (not (= (framples) (- frs 200))) (snd-display #__line__ ";edit-list->function called (2): ~A ~A" frs (framples)))) (revert-sound ind) ;; ---- simple delete (a) (delete-sample 100) (if (not (= (framples) (- frs 1))) (snd-display #__line__ ";edit-list->function delete (2a): ~A ~A" frs (framples))) (let ((func (edit-list->function))) (if (not (procedure? func)) (snd-display #__line__ ";edit-list->function 2a: ~A" func)) (if (not (equal? (procedure-source func) '(lambda (snd chn) (delete-samples 100 1 snd chn)))) (snd-display #__line__ ";edit-list->function 2a: ~A" (procedure-source func))) (func ind 0) (if (not (= (framples) (- frs 2))) (snd-display #__line__ ";edit-list->function called (2a): ~A ~A" frs (framples)))) (revert-sound ind) ;; ---- simple zero pad (pad-channel 10 100) (if (not (= (framples) (+ frs 100))) (snd-display #__line__ ";edit-list->function pad: ~A ~A" frs (framples))) (let ((func (edit-list->function))) (if (not (procedure? func)) (snd-display #__line__ ";edit-list->function 3: ~A" func)) (if (not (equal? (procedure-source func) '(lambda (snd chn) (pad-channel 10 100 snd chn)))) (snd-display #__line__ ";edit-list->function 3: ~A" (procedure-source func))) (func ind 0) (if (not (= (framples) (+ frs 200))) (snd-display #__line__ ";edit-list->function called (3): ~A ~A" frs (framples)))) (revert-sound ind) ;; ---- simple zero pad (a) (insert-silence 10 100) (if (not (= (framples) (+ frs 100))) (snd-display #__line__ ";edit-list->function pad (3a): ~A ~A" frs (framples))) (let ((func (edit-list->function))) (if (not (procedure? func)) (snd-display #__line__ ";edit-list->function 3a: ~A" func)) (if (not (equal? (procedure-source func) '(lambda (snd chn) (pad-channel 10 100 snd chn)))) (snd-display #__line__ ";edit-list->function 3a: ~A" (procedure-source func))) (func ind 0) (if (not (= (framples) (+ frs 200))) (snd-display #__line__ ";edit-list->function called (3a): ~A ~A" frs (framples)))) (revert-sound ind) ;; --- simple ramp (ramp-channel 0.2 0.9) (if (fneq (maxamp) 0.0899) (snd-display #__line__ ";edit-list ramp: ~A" (maxamp))) (let ((func (edit-list->function))) (if (not (procedure? func)) (snd-display #__line__ ";edit-list->function 4: ~A" func)) (if (not (equal? (procedure-source func) '(lambda (snd chn) (ramp-channel 0.2 0.9 0 #f snd chn)))) (snd-display #__line__ ";edit-list->function 4: ~A" (procedure-source func))) (func ind 0) (let ((mx (maxamp))) (if (fneq mx 0.061) (snd-display #__line__ ";edit-list->function called (4): ~A" mx)))) (revert-sound ind) ;; --- simple xramp (xramp-channel 0.2 0.9 32.0) (if (and (fneq (maxamp) 0.055) (fneq (maxamp) .056)) (snd-display #__line__ ";edit-list xramp: ~A" (maxamp))) (let ((func (edit-list->function))) (if (not (procedure? func)) (snd-display #__line__ ";edit-list->function 5: ~A" func)) (if (not (equal? (procedure-source func) '(lambda (snd chn) (xramp-channel 0.2 0.9 32.0 0 #f snd chn)))) (snd-display #__line__ ";edit-list->function 5: ~A" (procedure-source func))) (func ind 0) (let ((mx (maxamp))) (if (fneq mx 0.0266) (snd-display #__line__ ";edit-list->function called (5): ~A" mx)))) (revert-sound ind) ;; ---- simple env (env-sound '(0 0 1 1)) (if (fneq (maxamp) 0.0906) (snd-display #__line__ ";edit-list env: ~A" (maxamp))) (let ((func (edit-list->function))) (if (not (procedure? func)) (snd-display #__line__ ";edit-list->function 6: ~A" func)) (if (not (equal? (procedure-source func) '(lambda (snd chn) (env-channel '(0.0 0.0 1.0 1.0) 0 #f snd chn)))) (snd-display #__line__ ";edit-list->function 6: ~A" (procedure-source func))) (func ind 0) (let ((mx (maxamp))) (if (fneq mx 0.0634) (snd-display #__line__ ";edit-list->function called (6): ~A" mx)))) (revert-sound ind) ;; ---- less simple env (env-sound '(0 0 1 .3 2 .8 3 0)) (if (fneq (maxamp) 0.107) (snd-display #__line__ ";edit-list env: ~A" (maxamp))) (let ((func (edit-list->function))) (if (not (procedure? func)) (snd-display #__line__ ";edit-list->function 7: ~A" func)) (if (not (equal? (procedure-source func) '(lambda (snd chn) (env-channel '(0.0 0.0 1.0 0.3 2.0 0.8 3.0 0.0) 0 #f snd chn)))) (snd-display #__line__ ";edit-list->function 7: ~A" (procedure-source func))) (func ind 0) (let ((mx (maxamp))) (if (fneq mx 0.0857) (snd-display #__line__ ";edit-list->function called (7): ~A" mx)))) (revert-sound ind) (env-channel '(0 0 1 .3 2 .8 3 0)) (let ((func (edit-list->function))) (if (not (procedure? func)) (snd-display #__line__ ";edit-list->function 7a: ~A" func)) (if (not (equal? (procedure-source func) '(lambda (snd chn) (env-channel '(0.0 0.0 1.0 0.3 2.0 0.8 3.0 0.0) 0 #f snd chn)))) (snd-display #__line__ ";edit-list->function 7a: ~A" (procedure-source func)))) (revert-sound ind) (env-channel '(0 0 1 .3 2 .8 3 0) 1000 2000) (let ((func (edit-list->function))) (if (not (procedure? func)) (snd-display #__line__ ";edit-list->function 7b: ~A" func)) (if (not (equal? (procedure-source func) '(lambda (snd chn) (env-channel (make-env '(0.0 0.0 1.0 0.3 2.0 0.8 3.0 0.0) :base 1.0 :end 1999) 1000 2000 snd chn)))) (snd-display #__line__ ";edit-list->function 7b: ~A" (procedure-source func)))) (revert-sound ind) (env-channel (make-env '(0.0 0.0 1.0 0.3 2.0 0.8 3.0 0.0) :base 32.0 :length 2000) 1000 2000) (let ((func (edit-list->function)) (mxenv0 (maxamp))) (if (not (procedure? func)) (snd-display #__line__ ";edit-list->function 7c: ~A" func)) (if (not (equal? (procedure-source func) '(lambda (snd chn) (env-channel (make-env '(0.0 0.0 1.0 0.3 2.0 0.8 3.0 0.0) :base 32.0 :end 1999) 1000 2000 snd chn)))) (snd-display #__line__ ";edit-list->function 7c: ~A" (procedure-source func))) (revert-sound ind) (env-channel (make-env '(0.0 0.0 1.0 0.3 2.0 0.8 3.0 0.0) :length 2000 :offset 2.0 :scaler 3.0) 1000 2000) (let ((func (edit-list->function)) (mxenv1 (maxamp))) (if (not (procedure? func)) (snd-display #__line__ ";edit-list->function 7d: ~A" func)) (if (not (equal? (procedure-source func) '(lambda (snd chn) (env-channel (make-env '(0.0 2.0 1.0 2.9 2.0 4.4 3.0 2.0) :base 1.0 :end 1999) 1000 2000 snd chn)))) (snd-display #__line__ ";edit-list->function 7d: ~A" (procedure-source func))) (revert-sound ind) (func ind 0) (let ((nmx (maxamp))) (if (fneq nmx mxenv1) (snd-display #__line__ ";edit-list->function 7d max: ~A ~A ~A" nmx mxenv1 mxenv0))))) (revert-sound ind) (do ((i 0 (+ i 1))) ((= i 5)) ; get to unrampable case (env-channel '(0 0 1 1 2 0))) (let ((func (edit-list->function))) (if (not (procedure? func)) (snd-display #__line__ ";edit-list->function 7e: ~A" func)) (if (not (equal? (procedure-source func) '(lambda (snd chn) (env-channel '(0.0 0.0 1.0 1.0 2.0 0.0) 0 #f snd chn) (env-channel '(0.0 0.0 1.0 1.0 2.0 0.0) 0 #f snd chn) (env-channel '(0.0 0.0 1.0 1.0 2.0 0.0) 0 #f snd chn) (env-channel '(0.0 0.0 1.0 1.0 2.0 0.0) 0 #f snd chn) (env-channel '(0.0 0.0 1.0 1.0 2.0 0.0) 0 #f snd chn)))) (snd-display #__line__ ";edit-list->function 7e: ~A" (procedure-source func))) (revert-sound ind) (func ind 0) (if (fneq (maxamp) 0.1459) (snd-display #__line__ ";edit-list->function 7e max: ~A" (maxamp))) (if (not (= (edit-position) 5)) (snd-display #__line__ ";edit-list->function 7e edpos: ~A" (edit-position)))) (revert-sound ind) (env-sound '(0 0 1 1 2 0) 0 (framples) 32.0) (if (fneq (maxamp) 0.146) (snd-display #__line__ ";edit-list env 7f: ~A" (maxamp))) (let ((func (edit-list->function))) (if (not (procedure? func)) (snd-display #__line__ ";edit-list->function 7f: ~A" func)) (if (not (equal? (procedure-source func) '(lambda (snd chn) (env-channel-with-base '(0.0 0.0 1.0 1.0 2.0 0.0) 32.0 0 #f snd chn)))) (snd-display #__line__ ";edit-list->function 7f: ~A" (procedure-source func))) (revert-sound ind) (func ind 0) (let ((mx (maxamp))) (if (fneq mx 0.146) (snd-display #__line__ ";edit-list->function called (7f): ~A" mx)))) (revert-sound ind) (env-sound '(0 0 1 1 2 1 3 0) 0 (framples) 0.0) (if (fneq (sample 4000) 0.0) (snd-display #__line__ ";edit-list env 7g: ~A" (sample 4000))) (let ((func (edit-list->function))) (if (not (procedure? func)) (snd-display #__line__ ";edit-list->function 7g: ~A" func)) (if (not (equal? (procedure-source func) '(lambda (snd chn) (env-channel-with-base '(0.0 0.0 1.0 1.0 2.0 1.0 3.0 0.0) 0.0 0 #f snd chn)))) (snd-display #__line__ ";edit-list->function 7g: ~A" (procedure-source func))) (revert-sound ind) (func ind 0) (if (fneq (sample 4000) 0.0) (snd-display #__line__ ";edit-list function 7g: ~A" (sample 4000)))) (revert-sound ind) ;; ---- simple 1 sample insert (insert-sample 100 .1) (if (not (= (framples) (+ frs 1))) (snd-display #__line__ ";edit-list->function insert-sample: ~A ~A" frs (framples))) (let ((func (edit-list->function))) (if (not (procedure? func)) (snd-display #__line__ ";edit-list->function 9: ~A" func)) (if (not (equal? (procedure-source func) '(lambda (snd chn) (insert-sample 100 0.1 snd chn)))) (snd-display #__line__ ";edit-list->function 9: ~A" (procedure-source func))) (func ind 0) (if (not (vequal (channel->float-vector 99 4) (float-vector 0.0 0.1 0.1 0.0))) (snd-display #__line__ ";edit-list->function func 9: ~A" (channel->float-vector 99 4))) (if (not (= (framples) (+ frs 2))) (snd-display #__line__ ";edit-list->function called (9): ~A ~A" frs (framples)))) (revert-sound ind) ;; ---- insert-samples with data (insert-samples 0 100 (make-float-vector 100 .1)) (if (not (= (framples) (+ frs 100))) (snd-display #__line__ ";edit-list->function insert-samples (100): ~A ~A" frs (framples))) (let ((func (edit-list->function))) (if (not (procedure? func)) (snd-display #__line__ ";edit-list->function 9a: ~A" func)) (func ind 0) (if (not (= (framples) (+ frs 200))) (snd-display #__line__ ";edit-list->function insert-samples (200): ~A ~A" frs (framples))) (if (not (vequal (channel->float-vector 0 5) (float-vector 0.1 0.1 0.1 0.1 0.1))) (snd-display #__line__ ";edit-list->function func 9a: ~A" (channel->float-vector 0 5)))) (revert-sound ind) ;; ---- set-samples with data (set! (samples 0 100) (make-float-vector 100 .1)) (if (not (= (framples) frs)) (snd-display #__line__ ";edit-list->function set-samples (1): ~A ~A" frs (framples))) (let ((func (edit-list->function))) (if (not (procedure? func)) (snd-display #__line__ ";edit-list->function 9b: ~A" func)) (func ind 0) (if (not (= (framples) frs)) (snd-display #__line__ ";edit-list->function set-samples (2): ~A ~A" frs (framples))) (if (not (vequal (channel->float-vector 0 5) (float-vector 0.1 0.1 0.1 0.1 0.1))) (snd-display #__line__ ";edit-list->function func 9b: ~A" (channel->float-vector 0 5)))) (revert-sound ind) ;; ---- simple 1 sample set (let ((val (sample 100))) (set! (sample 100) .1) (if (not (= (framples) frs)) (snd-display #__line__ ";edit-list->function set-sample framples: ~A ~A" frs (framples))) (if (fneq (sample 100) .1) (snd-display #__line__ ";edit-list->function set-sample val: ~A ~A" val (sample 100))) (let ((func (edit-list->function))) (revert-sound) (if (fneq val (sample 100)) (snd-display #__line__ ";edit-list->function unset-sample val: ~A ~A" val (sample 100))) (if (not (procedure? func)) (snd-display #__line__ ";edit-list->function 10: ~A" func)) (if (not (equal? (procedure-source func) '(lambda (snd chn) (set-sample 100 0.1 snd chn)))) (snd-display #__line__ ";edit-list->function 10: ~A" (procedure-source func))) (func ind 0) (if (not (vequal (channel->float-vector 99 4) (float-vector 0.0 0.1 0.0 0.0))) (snd-display #__line__ ";edit-list->function func 10: ~A" (channel->float-vector 99 4))))) (revert-sound ind) (let ((pfrs (mus-sound-framples "pistol.snd"))) (insert-sound "pistol.snd" 1000) (if (not (= (framples) (+ frs pfrs))) (snd-display #__line__ ";edit-list->function insert-sound: ~A ~A" frs (framples))) (let ((func (edit-list->function))) (if (not (procedure? func)) (snd-display #__line__ ";edit-list->function 10a: ~A" func)) (if (and (not (equal? (procedure-source func) '(lambda (snd chn) (insert-sound "/home/bil/cl/pistol.snd" 1000 0 snd chn)))) (not (equal? (procedure-source func) '(lambda (snd chn) (insert-sound "/home/bil/snd-16/pistol.snd" 1000 0 snd chn))))) (snd-display #__line__ ";edit-list->function 10a: ~A" (procedure-source func))) (revert-sound ind) (func ind 0) (if (not (= (framples) (+ frs pfrs))) (snd-display #__line__ ";edit-list->function called (10): ~A ~A" frs (framples))))) (revert-sound ind) (let ((pfrs (mus-sound-framples "pistol.snd"))) (insert-samples 1000 pfrs "pistol.snd") (if (not (= (framples) (+ frs pfrs))) (snd-display #__line__ ";edit-list->function insert-samples: ~A ~A" frs (framples))) (let ((func (edit-list->function))) (if (not (procedure? func)) (snd-display #__line__ ";edit-list->function 11: ~A" func)) (if (and (not (equal? (procedure-source func) '(lambda (snd chn) (insert-samples 1000 41623 "/home/bil/cl/pistol.snd" snd chn)))) (not (equal? (procedure-source func) '(lambda (snd chn) (insert-samples 1000 41623 "/home/bil/snd-16/pistol.snd" snd chn))))) (snd-display #__line__ ";edit-list->function 11: ~A" (procedure-source func))) (revert-sound ind) (func ind 0) (if (not (= (framples) (+ frs pfrs))) (snd-display #__line__ ";edit-list->function called (11): ~A ~A" frs (framples))))) (revert-sound ind) (smooth-channel 1000 100) (let ((func (edit-list->function)) (val (sample 1050))) (if (not (procedure? func)) (snd-display #__line__ ";edit-list->function 12: ~A" func)) (if (not (equal? (procedure-source func) '(lambda (snd chn) (smooth-channel 1000 100 snd chn)))) (snd-display #__line__ ";edit-list->function 12: ~A" (procedure-source func))) (revert-sound ind) (func ind 0) (if (fneq (sample 1050) val) (snd-display #__line__ ";edit-list->function 12: ~A ~A" (sample 1050) val))) (revert-sound ind) (smooth-sound 1000 100) (let ((func (edit-list->function))) (if (not (procedure? func)) (snd-display #__line__ ";edit-list->function 12a: ~A" func)) (if (not (equal? (procedure-source func) '(lambda (snd chn) (smooth-channel 1000 100 snd chn)))) (snd-display #__line__ ";edit-list->function 12a: ~A" (procedure-source func)))) (revert-sound ind) ;; ---- selection stuff (make-selection 1000 11000) (scale-selection-by 2.0) (let ((func (edit-list->function))) (if (not (procedure? func)) (snd-display #__line__ ";edit-list->function 13: ~A" func)) (if (not (equal? (procedure-source func) '(lambda (snd chn) (scale-channel 2.0 1000 10001 snd chn)))) (snd-display #__line__ ";edit-list->function 13: ~A" (procedure-source func))) (revert-sound ind) (func ind 0) (let ((mx (maxamp))) (if (fneq mx .269) (snd-display #__line__ ";edit-list->function called (13): ~A" mx)))) (revert-sound ind) (scale-selection-to 1.0) (let ((func (edit-list->function))) (if (not (procedure? func)) (snd-display #__line__ ";edit-list->function 13a: ~A" func)) (if (not (equal? (procedure-source func) '(lambda (snd chn) (normalize-channel 1.0 1000 10001 snd chn)))) (snd-display #__line__ ";edit-list->function 13a: ~A" (procedure-source func)))) (revert-sound ind) (env-selection '(0 0 1 1 2 0)) (let ((func (edit-list->function))) (if (fneq (sample 4000) 0.0173) (snd-display #__line__ ";edit-list->function 14 samp: ~A" (sample 4000))) (if (not (procedure? func)) (snd-display #__line__ ";edit-list->function 14: ~A" func)) (if (not (equal? (procedure-source func) '(lambda (snd chn) (env-channel (make-env '(0.0 0.0 1.0 1.0 2.0 0.0) :base 1.0 :end 10000) 1000 10001 snd chn)))) (snd-display #__line__ ";edit-list->function 14: ~A" (procedure-source func))) (revert-sound ind) (func ind 0) (if (fneq (sample 4000) 0.0173) (snd-display #__line__ ";edit-list->function 14 re-samp: ~A" (sample 4000)))) (revert-sound ind) (make-selection 1000 1100) (smooth-selection) (let ((func (edit-list->function)) (val (sample 1050))) (if (not (procedure? func)) (snd-display #__line__ ";edit-list->function 14a: ~A" func)) (if (not (equal? (procedure-source func) '(lambda (snd chn) (smooth-channel 1000 101 snd chn)))) (snd-display #__line__ ";edit-list->function 14a: ~A" (procedure-source func))) (revert-sound ind) (func ind 0) (if (fneq (sample 1050) val) (snd-display #__line__ ";edit-list->function 14a: ~A ~A" (sample 1050) val))) (revert-sound ind) (reverse-selection) (let ((func (edit-list->function))) (if (not (procedure? func)) (snd-display #__line__ ";edit-list->function 14b: ~A" func)) (if (not (equal? (procedure-source func) '(lambda (snd chn) (reverse-channel 1000 101 snd chn)))) (snd-display #__line__ ";edit-list->function 14b: ~A" (procedure-source func))) (revert-sound ind) (func ind 0)) (revert-sound ind) (delete-selection) (let ((func (edit-list->function))) (if (not (procedure? func)) (snd-display #__line__ ";edit-list->function 14c: ~A" func)) (if (not (equal? (procedure-source func) '(lambda (snd chn) (delete-samples 1000 101 snd chn)))) (snd-display #__line__ ";edit-list->function 14c: ~A" (procedure-source func))) (revert-sound ind) (func ind 0)) (revert-sound ind) ;; ---- simple reapply (env-channel '(0 0 1 1 2 0)) (let ((func (edit-list->function))) (close-sound ind) (set! ind (new-sound "tmp.snd" 1 22050 mus-ldouble mus-next :size 20 :comment #f)) (map-channel (lambda (y) 1.0)) (func ind 0) (let ((data (channel->float-vector))) (if (not (vequal data (float-vector 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 0.889 0.778 0.667 0.556 0.444 0.333 0.222 0.111 0.0))) (snd-display #__line__ ";edit-list->function env reapply: ~A" data))) (close-sound ind) (set! ind (open-sound "oboe.snd"))) ;; ---- insert-region (let ((reg (make-region 1000 1100))) (insert-region reg 2000) (let ((func (edit-list->function)) (val (sample 2050))) (if (not (procedure? func)) (snd-display #__line__ ";edit-list->function 16: ~A" func)) (revert-sound ind) (func ind 0) (if (fneq (sample 2050) val) (snd-display #__line__ ";edit-list->function 16: ~A ~A" (sample 2050) val)))) (revert-sound ind) ;; ---- reverse (reverse-channel) (let ((func (edit-list->function)) (val (sample 2000))) (if (not (procedure? func)) (snd-display #__line__ ";edit-list->function 17: ~A" func)) (if (not (equal? (procedure-source func) '(lambda (snd chn) (reverse-channel 0 #f snd chn)))) (snd-display #__line__ ";edit-list->function 17: ~A" (procedure-source func))) (if (fneq val -.002) (snd-display #__line__ ";edit-list->function val: ~A" val)) (revert-sound ind) (func ind 0) (if (fneq val -.002) (snd-display #__line__ ";edit-list->function 17 re-val: ~A" val))) (revert-sound ind) (reverse-sound) (let ((func (edit-list->function)) (val (sample 2000))) (if (not (procedure? func)) (snd-display #__line__ ";edit-list->function 17a: ~A" func)) (if (not (equal? (procedure-source func) '(lambda (snd chn) (reverse-channel 0 #f snd chn)))) (snd-display #__line__ ";edit-list->function 17a: ~A" (procedure-source func))) (if (fneq val -.002) (snd-display #__line__ ";edit-list->function 17a val: ~A" val))) (revert-sound ind) (reverse-channel 1000 500) (let ((func (edit-list->function))) (if (not (procedure? func)) (snd-display #__line__ ";edit-list->function 17b: ~A" func)) (if (not (equal? (procedure-source func) '(lambda (snd chn) (reverse-channel 1000 500 snd chn)))) (snd-display #__line__ ";edit-list->function 17b: ~A" (procedure-source func)))) (revert-sound ind) ;; ---- src (src-sound 2.0) (if (> (abs (- (framples) 25415)) 2) (snd-display #__line__ ";edit-list->function 18 len: ~A" (framples))) (let ((func (edit-list->function))) (if (not (procedure? func)) (snd-display #__line__ ";edit-list->function 18: ~A" func)) (if (not (equal? (procedure-source func) '(lambda (snd chn) (src-channel 2.0 0 #f snd chn)))) (snd-display #__line__ ";edit-list->function 18: ~A" (procedure-source func))) (revert-sound ind) (func ind 0) (if (> (abs (- (framples) 25415)) 2) (snd-display #__line__ ";edit-list->function 18 re-len: ~A" (framples)))) (revert-sound ind) (src-channel 2.0 1000 500) (let ((func (edit-list->function)) (frs (framples))) (if (not (procedure? func)) (snd-display #__line__ ";edit-list->function 18a: ~A" func)) (if (not (equal? (procedure-source func) '(lambda (snd chn) (src-channel 2.0 1000 500 snd chn)))) (snd-display #__line__ ";edit-list->function 18a: ~A" (procedure-source func))) (revert-sound ind) (func ind 0) (if (not (= frs (framples))) (snd-display #__line__ ";edit-list->function 18a re-len: ~A ~A" frs (framples)))) (revert-sound) (src-sound '(0 1 1 2 2 1)) (let ((func (edit-list->function)) (frs (framples))) (if (not (procedure? func)) (snd-display #__line__ ";edit-list->function 18b: ~A" func)) (if (not (equal? (procedure-source func) '(lambda (snd chn) (src-channel '(0.0 1.0 1.0 2.0 2.0 1.0) 0 #f snd chn)))) (snd-display #__line__ ";edit-list->function 18b: ~A" (procedure-source func))) (revert-sound ind) (func ind 0) (if (not (= frs (framples))) (snd-display #__line__ ";edit-list->function 18b re-len: ~A ~A" frs (framples)))) (revert-sound) (src-channel '(0 1 1 2) 1000 500) (let ((func (edit-list->function)) (frs (framples))) (if (not (procedure? func)) (snd-display #__line__ ";edit-list->function 18c: ~A" func)) (if (not (equal? (procedure-source func) '(lambda (snd chn) (src-channel '(0.0 1.0 1.0 2.0) 1000 500 snd chn)))) (snd-display #__line__ ";edit-list->function 18c: ~A" (procedure-source func))) (revert-sound ind) (func ind 0) (if (not (= frs (framples))) (snd-display #__line__ ";edit-list->function 18c re-len: ~A ~A" frs (framples)))) (revert-sound) ;; ---- filter-channel (filter-channel '(0 1 1 0) 10) (let ((func (edit-list->function)) (mx (maxamp))) (if (not (procedure? func)) (snd-display #__line__ ";edit-list->function 19: ~A" func)) (if (not (equal? (procedure-source func) '(lambda (snd chn) (filter-channel '(0.0 1.0 1.0 0.0) 10 0 #f snd chn)))) (snd-display #__line__ ";edit-list->function 19: ~A" (procedure-source func))) (revert-sound ind) (func ind 0) (if (fneq mx (maxamp)) (snd-display #__line__ ";edit-list->function 19 re-filter: ~A ~A" mx (maxamp)))) (revert-sound) (let ((op (make-one-zero .5 .5))) (filter-fft op)) (float-vector->channel (fft-smoother .1 (cursor) 400) (cursor) 400) (revert-sound) (let ((ind (new-sound :size 32))) (select-sound ind) (let ((ang 0.0)) (map-channel (lambda (y) (let ((val (+ (* .5 (sin ang)) (* .5 (sin (* ang 4)))))) (set! ang (+ ang (/ (* 2 pi) 16.0))) val)))) (let ((vals (fft-env-data '(0 0 .3 0 .4 1 1 1)))) (float-vector->channel vals) (if (not (vequal vals (float-vector -0.000 0.500 0.000 -0.500 0.000 0.500 0.000 -0.500 0.000 0.500 -0.000 -0.500 -0.000 0.500 -0.000 -0.500 -0.000 0.500 0.000 -0.500 0.000 0.500 0.000 -0.500 0.000 0.500 -0.000 -0.500 -0.000 0.500 -0.000 -0.500))) (snd-display #__line__ ";fft-env-data: ~A" vals))) (hilbert-transform-via-fft) (let ((vals (channel->float-vector))) (let ((nvals (float-vector -0.500 -0.000 0.500 -0.000 -0.500 0.000 0.500 0.000 -0.500 0.000 0.500 0.000 -0.500 -0.000 0.500 -0.000 -0.500 -0.000 0.500 -0.000 -0.500 0.000 0.500 0.000 -0.500 0.000 0.500 0.000 -0.500 -0.000 0.500 -0.000))) (if (not (vequal vals nvals)) (snd-display #__line__ ";hilbert via dft: ~A" vals)))) (revert-sound ind) (map-channel (lambda (y) 1.0)) (powenv-channel '(0 0 .325 1 1 32.0 2 0 32.0)) (let ((vals (channel->float-vector))) (if (not (vequal vals (float-vector 0.000 0.107 0.206 0.298 0.384 0.463 0.536 0.605 0.668 0.727 0.781 0.832 0.879 0.922 0.963 1.000 1.000 0.787 0.618 0.484 0.377 0.293 0.226 0.173 0.130 0.097 0.070 0.049 0.032 0.019 0.008 0.000))) (snd-display #__line__ ";powenv-channel: ~A" vals))) (undo) (revert-sound ind) (map-channel (lambda (y) 1.0)) (env-sound '(0 0 1 1)) (set! (cursor ind 0) 10) (make-selection 0 7 ind 0) (if (not (selection?)) (snd-display #__line__ ";make-selection failed??") (begin (replace-with-selection) (let ((vals (channel->float-vector))) (if (not (vequal vals (float-vector 0.000 0.032 0.065 0.097 0.129 0.161 0.194 0.226 0.258 0.290 0.000 0.032 0.065 0.097 0.129 0.161 0.194 0.226 0.581 0.613 0.645 0.677 0.710 0.742 0.774 0.806 0.839 0.871 0.903 0.935 0.968 1.000))) (snd-display #__line__ ";replace-with-selection: ~A" vals))))) (set! (cursor ind 0) 2) (replace-with-selection) (let ((vals (channel->float-vector))) (if (not (vequal vals (float-vector 0.000 0.032 0.000 0.032 0.065 0.097 0.129 0.161 0.194 0.226 0.000 0.032 0.065 0.097 0.129 0.161 0.194 0.226 0.581 0.613 0.645 0.677 0.710 0.742 0.774 0.806 0.839 0.871 0.903 0.935 0.968 1.000))) (snd-display #__line__ ";replace-with-selection (at 2): ~A" vals))) (revert-sound ind) (map-channel (lambda (y) 1.0)) (env-sound '(0 0 1 1)) (let ((m1 (add-mark 10)) (m2 (add-mark 20))) (make-selection 0 9) (fit-selection-between-marks m1 m2) (let ((vals (channel->float-vector))) (if (not (vequal vals (float-vector 0.000 0.032 0.065 0.097 0.129 0.161 0.194 0.226 0.258 0.290 0.323 0.387 0.452 0.516 0.581 0.645 0.710 0.774 0.839 0.903 0.645 0.677 0.710 0.742 0.774 0.806 0.839 0.871 0.903 0.935 0.968 1.000))) (snd-display #__line__ ";fit-selection-between-marks: ~A" vals)))) (revert-sound ind) (map-channel (lambda (y) 1.0)) (let ((ramper (make-ramp 10))) (map-channel (lambda (y) (ramp ramper y))) (let ((vals (channel->float-vector 0 20))) (if (not (vequal vals (float-vector 0.100 0.200 0.300 0.400 0.500 0.600 0.700 0.800 0.900 1.000 1.0 1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000))) (snd-display #__line__ ";make-ramp: ~A" vals)))) (revert-sound ind) (float-vector->channel (with-sound ((make-float-vector 44100)) (cross-fade 0 2 1.0 "oboe.snd" "trumpet.snd" 0.5 1.0 0 .1 256 2))) (if (and (ffneq (maxamp) .142) (ffneq (maxamp) .155)) (snd-display #__line__ ";cross fade maxamp: ~A" (maxamp))) (revert-sound) (float-vector->channel (with-sound ((make-float-vector 44100)) (dissolve-fade 0 2 1.0 "oboe.snd" "trumpet.snd" 512 2 2 #f))) (let ((new-file-name (file-name ind))) (close-sound ind) (if (file-exists? new-file-name) (delete-file new-file-name)))) (let ((vals (apply float-vector (rms-envelope "oboe.snd" :rfreq 4)))) (if (not (vequal vals (float-vector 0.0 0.0430 0.25 0.0642 0.5 0.0695 0.75 0.0722 1.0 0.0738 1.25 0.0713 1.5 0.065 1.75 0.0439 2.0 0.01275 2.25 0.007))) (snd-display #__line__ ";rms-envelope: ~A" vals))) (let ((ind (open-sound "2a.snd"))) (hook-push graph-hook display-correlation) (update-time-graph) (set! (hook-functions graph-hook) ()) (stereo->mono ind "hi1.snd" "hi2.snd") (let ((hi1 (find-sound "hi1.snd")) (hi2 (find-sound "hi2.snd"))) (if (or (not hi1) (not hi2) (not (= (chans hi1) 1)) (not (= (chans hi2) 1))) (snd-display #__line__ ";stereo->mono: ~A ~A" (map file-name (sounds)) (map chans (sounds))) (let ((dist1 (channel-distance ind 0 hi1 0)) (dist2 (channel-distance ind 1 hi2 0))) (if (or (fneq dist1 0.0) (fneq dist2 0.0)) (snd-display #__line__ ";stereo->mono distances: ~A ~A" dist1 dist2)) (mono->stereo "ho2.snd" hi1 0 hi2 0) (let ((ho2 (find-sound "ho2.snd"))) (if (or (not ho2) (not (= (chans ho2) 2))) (snd-display #__line__ ";mono->stereo: ~A" (map file-name (sounds))) (let ((dist1 (channel-distance ho2 0 ind 0)) (dist2 (channel-distance ho2 1 ind 1))) (if (or (fneq dist1 0.0) (fneq dist2 0.0)) (snd-display #__line__ ";stereo->mono->stereo distances: ~A ~A" dist1 dist2)))) (close-sound ho2)))) (close-sound hi1) (close-sound hi2)) (close-sound ind)) (if (file-exists? "hi1.snd") (delete-file "hi1.snd")) (if (file-exists? "hi2.snd") (delete-file "hi2.snd")) (if (file-exists? "ho2.snd") (delete-file "ho2.snd")) (let ((ind (new-sound :size 1000))) (map-channel (lambda (y) 0.5)) (map-channel (vibro 1000.0 .5)) (let ((vals (channel->float-vector 0 20))) (if (and (not (vequal vals (float-vector 0.375 0.410 0.442 0.469 0.489 0.499 0.499 0.489 0.470 0.443 0.411 0.376 0.341 0.308 0.281 0.262 0.251 0.251 0.261 0.280))) (not (vequal vals (float-vector 0.375 0.393 0.410 0.427 0.442 0.457 0.469 0.480 0.489 0.495 0.499 0.500 0.499 0.495 0.489 0.480 0.470 0.457 0.443 0.428)))) (snd-display #__line__ ";no vibro? ~A" vals))) (let ((new-file-name (file-name ind))) (close-sound ind) (if (file-exists? new-file-name) (delete-file new-file-name)))) (let ((ind (open-sound "pistol.snd"))) (transposed-echo 1.1 .95 .25) (play :wait #t) (set! (channel-property 'colored-samples ind 0) (list (list *cursor-color* 0 100))) (hook-push after-graph-hook display-samples-in-color) (update-time-graph) (repitch-sound 220.0 440.0) (uncolor-samples) (retime-sound 1.0) (close-sound ind)) (hook-remove after-graph-hook display-samples-in-color) (let ((val 0)) (tree-for-each (lambda (n) (set! val (+ val n))) (list (list 1 0) (list 2) 3)) (if (not (= val 6)) (snd-display #__line__ ";tree-for-each: ~A" val))) (let ((ind (new-sound :channels 4 :size 32))) (set! (sample 0 ind 0) 0.5) (set! (sample 10 ind 1) 0.25) (set! (sample 20 ind 2) 0.125) (set! (sample 30 ind 3) 0.0625) (scramble-channels 3 2 0 1) ; 3->0, 2->1, 0->2 1->3 (if (or (fneq (sample 0 ind 2) .5) ; chan 0 is 2 after swaps (fneq (sample 10 ind 3) .25) (fneq (sample 20 ind 1) .125) (fneq (sample 30 ind 0) .0625)) (snd-display #__line__ ";scramble-channels: ~A ~A ~A ~A (~A ~A ~A ~A)" (sample 0 ind 2) (sample 10 ind 3) (sample 20 ind 1) (sample 30 ind 2) (sample 0 ind 0) (sample 10 ind 1) (sample 20 ind 2) (sample 30 ind 3))) (do ((i 0 (+ i 1))) ((= i 4)) (set! (edit-position ind i) 1)) (scramble-channels 3 0 1 2) (if (or (fneq (sample 0 ind 1) .5) (fneq (sample 10 ind 2) .25) (fneq (sample 20 ind 3) .125) (fneq (sample 30 ind 0) .0625)) (snd-display #__line__ ";scramble-channels (1): ~A ~A ~A ~A (~A ~A ~A ~A)" (sample 0 ind 1) (sample 10 ind 2) (sample 20 ind 3) (sample 30 ind 0) (sample 0 ind 0) (sample 10 ind 1) (sample 20 ind 2) (sample 30 ind 3))) (do ((i 0 (+ i 1))) ((= i 4)) (set! (edit-position ind i) 1)) (scramble-channels 0 1 3 2) (if (or (fneq (sample 0 ind 0) .5) (fneq (sample 10 ind 1) .25) (fneq (sample 20 ind 3) .125) (fneq (sample 30 ind 2) .0625)) (snd-display #__line__ ";scramble-channels (2): ~A ~A ~A ~A (~A ~A ~A ~A)" (sample 0 ind 0) (sample 10 ind 1) (sample 20 ind 3) (sample 30 ind 2) (sample 0 ind 0) (sample 10 ind 1) (sample 20 ind 2) (sample 30 ind 3))) (do ((i 0 (+ i 1))) ((= i 4)) (set! (edit-position ind i) 1)) (scramble-channels 1 2 3 0) (if (or (fneq (sample 0 ind 3) .5) (fneq (sample 10 ind 0) .25) (fneq (sample 20 ind 1) .125) (fneq (sample 30 ind 2) .0625)) (snd-display #__line__ ";scramble-channels (3): ~A ~A ~A ~A (~A ~A ~A ~A)" (sample 0 ind 3) (sample 10 ind 0) (sample 20 ind 1) (sample 30 ind 2) (sample 0 ind 0) (sample 10 ind 1) (sample 20 ind 2) (sample 30 ind 3))) (do ((i 0 (+ i 1))) ((= i 4)) (set! (edit-position ind i) 1)) (let ((new-file-name (file-name ind))) (close-sound ind) (if (file-exists? new-file-name) (delete-file new-file-name)))) (let ((ind (new-sound :channels 8 :size 10 :comment "new-sound for scramble-channels"))) (do ((i 0 (+ i 1))) ((= i 8)) (set! (sample i ind i) .5)) (scramble-channels 1 2 3 4 7 6 5 0) (if (or (fneq (sample 1 ind 0) .5) (fneq (sample 2 ind 1) .5) (fneq (sample 3 ind 2) .5) (fneq (sample 4 ind 3) .5) (fneq (sample 7 ind 4) .5) (fneq (sample 6 ind 5) .5) (fneq (sample 5 ind 6) .5) (fneq (sample 0 ind 7) .5)) (snd-display #__line__ ";scramble-channels 8 ways: ~A" (list (sample 1 ind 0) (sample 2 ind 1) (sample 3 ind 2) (sample 4 ind 3) (sample 7 ind 4) (sample 6 ind 5) (sample 5 ind 6) (sample 0 ind 7)))) (let ((new-file-name (file-name ind))) (close-sound ind) (if (file-exists? new-file-name) (delete-file new-file-name)))) ;; ---- *.scm (if (and (defined? 'effects-squelch-channel) (or (provided? 'xm) (provided? 'xg))) (let ((ctr 1)) (for-each (lambda (func1 descr) (func1) (let ((func (edit-list->function))) (if (not (equal? (procedure-source func) descr)) (snd-display #__line__ ";edit-list->function 20[~D]:~%; [~A]~%; [~A]" ctr descr (procedure-source func))) (revert-sound ind) (func ind 0)) (set! ctr (+ ctr 1)) (revert-sound ind)) (list (lambda () (insert-float-vector (float-vector 1.0 0.5) 0 2)) clm-channel-test ;; examp.scm (lambda () (fft-edit 1000 3000)) (lambda () (fft-squelch .01)) (lambda () (fft-cancel 1000 3000)) squelch-vowels (lambda () (fft-env-edit '(0 0 1 1 2 0))) (lambda () (fft-env-interp '(0 0 1 1 2 0) '(0 1 1 0 2 0) '(0 0 1 1))) (lambda () (hello-dentist 10.0 .1)) (lambda () (fp 1.0 0.3 20.0)) (lambda () (expsnd '(0 1 1 2))) (lambda () (env-sound-interp '(0 0 1 1 2 0) 2.0)) (lambda () (add-notes '(("1a.snd") ("pistol.snd" 1.0 2.0)))) (lambda () (filtered-env '(0 0 1 1 2 0))) (lambda () (reverse-by-blocks .1)) (lambda () (reverse-within-blocks .1)) ;; extensions.scm (lambda () (mix-channel "1a.snd" 1200)) (lambda () (insert-channel "1a.snd" 1200)) (lambda () (sine-ramp 0.5 0.9)) (lambda () (sine-env-channel '(0 0 1 1 2 -0.5 3 1))) (lambda () (blackman4-ramp 0.0 1.0)) (lambda () (blackman4-env-channel '(0 0 1 1 2 -0.5 3 1))) (lambda () (ramp-squared 0.2 0.8 #t)) (lambda () (env-squared-channel '(0.0 0.0 1.0 1.0) #t)) (lambda () (ramp-expt 0.2 0.8 32.0 #t)) (lambda () (env-expt-channel '(0.0 0.0 1.0 1.0) 32.0 #t)) (lambda () (offset-channel .1)) (lambda () (dither-channel .1)) (lambda () (contrast-channel .1)) ;; dsp.scm (lambda () (ssb-bank 550 600 10)) (lambda () (ssb-bank-env 550 600 '(0 1 1 2) 10)) (lambda () (down-oct 1)) spike zero-phase (lambda () (rotate-phase (lambda (x) (random pi)))) (lambda () (brighten-slightly .5)) (lambda () (shift-channel-pitch 100)) (lambda () (channel-polynomial (float-vector 0.0 0.5))) (lambda () (spectral-polynomial (float-vector 0.0 1.0))) (lambda () (notch-channel (list 60.0 120.0 240.0) #f #f #f)) ;; ---- new-effects.scm (lambda () (effects-squelch-channel .1 128)) (lambda () (effects-echo #f 0.5 0.1 0 #f)) (lambda () (effects-flecho-1 0.5 0.1 #f 0 #f)) (lambda () (effects-zecho-1 0.75 0.75 6.0 10.0 #f 0 #f)) ;; (lambda () (effects-comb-filter 0.1 50 0 #f)) (lambda () (effects-moog 10000 0.5 0 #f)) effects-remove-dc effects-compand (lambda () (effects-am 100.0 #f)) (lambda () (effects-rm 100.0 #f)) (lambda () (effects-bbp 1000.0 100.0 0 #f)) (lambda () (effects-bbr 1000.0 100.0 0 #f)) (lambda () (effects-bhp 1000.0 0 #f)) (lambda () (effects-blp 1000.0 0 #f)) (lambda () (effects-hello-dentist 50.0 0.5 0 #f)) (lambda () (effects-fp 1.0 0.3 20.0 0 #f)) (lambda () (effects-flange 5.0 2.0 0.001 0 #f)) (lambda () (effects-jc-reverb-1 0.1 0 #f)) ) (list '(lambda (snd chn) (insert-float-vector (float-vector 1.0 0.5) 0 2 snd chn)) '(lambda (snd chn) (clm-channel-test snd chn)) '(lambda (snd chn) (fft-edit 1000 3000 snd chn)) '(lambda (snd chn) (fft-squelch 0.01 snd chn)) '(lambda (snd chn) (fft-cancel 1000 3000 snd chn)) '(lambda (snd chn) (squelch-vowels snd chn)) '(lambda (snd chn) (fft-env-edit '(0 0 1 1 2 0) snd chn)) '(lambda (snd chn) (fft-env-interp '(0 0 1 1 2 0) '(0 1 1 0 2 0) '(0 0 1 1) snd chn)) '(lambda (snd chn) (hello-dentist 10.0 0.1 snd chn)) '(lambda (snd chn) (fp 1.0 0.3 20.0 snd chn)) '(lambda (snd chn) (expsnd '(0 1 1 2) snd chn)) '(lambda (snd chn) (env-sound-interp '(0 0 1 1 2 0) 2.0 snd chn)) '(lambda (snd chn) (add-notes '(("1a.snd") ("pistol.snd" 1.0 2.0)) snd chn)) '(lambda (snd chn) (filtered-env '(0 0 1 1 2 0) snd chn)) '(lambda (snd chn) (reverse-by-blocks 0.1 snd chn)) '(lambda (snd chn) (reverse-within-blocks 0.1 snd chn)) '(lambda (snd chn) (mix-channel "1a.snd" 1200 #f snd chn)) '(lambda (snd chn) (insert-channel "1a.snd" 1200 #f snd chn)) '(lambda (snd chn) (sine-ramp 0.5 0.9 0 #f snd chn)) '(lambda (snd chn) (sine-env-channel '(0 0 1 1 2 -0.5 3 1) 0 #f snd chn)) '(lambda (snd chn) (blackman4-ramp 0.0 1.0 0 #f snd chn)) '(lambda (snd chn) (blackman4-env-channel '(0 0 1 1 2 -0.5 3 1) 0 #f snd chn)) '(lambda (snd chn) (ramp-squared 0.2 0.8 #t 0 #f snd chn)) '(lambda (snd chn) (env-squared-channel '(0.0 0.0 1.0 1.0) #t 0 #f snd chn)) '(lambda (snd chn) (ramp-expt 0.2 0.8 32.0 #t 0 #f snd chn)) '(lambda (snd chn) (env-expt-channel '(0.0 0.0 1.0 1.0) 32.0 #t 0 #f snd chn)) '(lambda (snd chn) (offset-channel 0.1 0 #f snd chn)) '(lambda (snd chn) (dither-channel 0.1 0 #f snd chn)) '(lambda (snd chn) (contrast-channel 0.1 0 #f snd chn)) '(lambda (snd chn) (ssb-bank 550 600 10 40 50.0 0 #f snd chn)) '(lambda (snd chn) (ssb-bank-env 550 600 '(0 1 1 2) 10 40 50.0 0 #f snd chn)) '(lambda (snd chn) (down-oct 1 snd chn)) '(lambda (snd chn) (spike snd chn)) '(lambda (snd chn) (zero-phase snd chn)) '(lambda (snd chn) (rotate-phase (lambda (x) (random pi)) snd chn)) '(lambda (snd chn) (brighten-slightly 0.5 snd chn)) '(lambda (snd chn) (shift-channel-pitch 100 40 0 #f snd chn)) '(lambda (snd chn) (channel-polynomial (float-vector 0.0 0.5) snd chn)) '(lambda (snd chn) (spectral-polynomial (float-vector 0.0 1.0) snd chn)) '(lambda (snd chn) (notch-channel '(60.0 120.0 240.0) #f #f #f snd chn)) '(lambda (snd chn) (effects-squelch-channel 0.1 128 snd chn)) '(lambda (snd chn) (effects-echo #f 0.5 0.1 0 #f snd chn)) '(lambda (snd chn) (effects-flecho-1 0.5 0.1 #f 0 #f snd chn)) '(lambda (snd chn) (effects-zecho-1 0.75 0.75 6.0 10.0 #f 0 #f snd chn)) ;; '(lambda (snd chn) (effects-comb-filter 0.1 50 0 #f snd chn)) '(lambda (snd chn) (effects-moog 10000 0.5 0 #f snd chn)) '(lambda (snd chn) (effects-remove-dc snd chn)) '(lambda (snd chn) (effects-compand snd chn)) '(lambda (snd chn) (effects-am 100.0 #f #f #f snd chn)) '(lambda (snd chn) (effects-rm 100.0 #f #f #f snd chn)) '(lambda (snd chn) (effects-bbp 1000.0 100.0 0 #f snd chn)) '(lambda (snd chn) (effects-bbr 1000.0 100.0 0 #f snd chn)) '(lambda (snd chn) (effects-bhp 1000.0 0 #f snd chn)) '(lambda (snd chn) (effects-blp 1000.0 0 #f snd chn)) '(lambda (snd chn) (effects-hello-dentist 50.0 0.5 0 #f snd chn)) '(lambda (snd chn) (effects-fp 1.0 0.3 20.0 0 #f snd chn)) '(lambda (snd chn) (effects-flange 5.0 2.0 0.001 0 #f snd chn)) '(lambda (snd chn) (effects-jc-reverb-1 0.1 0 #f snd chn)) )))) (close-sound ind) )) ;; ---- apply controls edit lists (let ((ind (open-sound "oboe.snd")) (original-maxamp (maxamp))) (reset-controls) (controls->channel (list 2.0)) (if (fneq (amp-control ind) 1.0) (snd-display #__line__ ";controls->channel amp: ~A" (amp-control ind))) (if (fneq (maxamp) (* 2 original-maxamp)) (snd-display #__line__ ";controls->channel maxamp: ~A" (maxamp))) (let ((func (edit-list->function))) (if (not (equal? (procedure-source func) '(lambda (snd chn) (scale-channel 2.0 0 #f snd chn)))) (snd-display #__line__ ";edit-list->function controls->channel 1: ~A" (procedure-source func))) (func ind 0) (revert-sound ind)) (controls->channel (list #f 2.0)) (let ((pk (float-vector-peak (channel->float-vector 22000 22100)))) (if (fneq pk 0.0479) (snd-display #__line__ ";dp->end screwed up again!?!: ~A" pk))) (let ((func (edit-list->function))) (if (not (equal? (procedure-source func) '(lambda (snd chn) (controls->channel '(#f 2.0) 0 #f snd chn)))) (snd-display #__line__ ";edit-list->function controls->channel 2: ~A" (procedure-source func))) (revert-sound ind) (func ind 0) (revert-sound ind) (if (fneq (speed-control ind) 1.0) (snd-display #__line__ ";controls->channel speed: ~A" (speed-control ind)))) (controls->channel (list #f #f (list 0.5))) (let ((func (edit-list->function))) (if (not (equal? (procedure-source func) '(lambda (snd chn) (controls->channel '(#f #f (0.5)) 0 #f snd chn)))) (snd-display #__line__ ";edit-list->function controls->channel 3: ~A" (procedure-source func))) (revert-sound ind) (func ind 0) (revert-sound ind) (if (fneq (contrast-control ind) 0.0) (snd-display #__line__ ";controls->channel contrast: ~A" (contrast-control ind)))) (controls->channel (list #f #f (list 0.5 2.0))) (let ((func (edit-list->function))) (if (not (equal? (procedure-source func) '(lambda (snd chn) (controls->channel '(#f #f (0.5 2.0)) 0 #f snd chn)))) (snd-display #__line__ ";edit-list->function controls->channel 3a: ~A" (procedure-source func))) (revert-sound ind) (func ind 0) (revert-sound ind) (if (fneq (contrast-control ind) 0.0) (snd-display #__line__ ";controls->channel contrast 3a: ~A" (contrast-control ind)))) (controls->channel (list #f #f #f (list 0.5))) (let ((func (edit-list->function))) (if (not (equal? (procedure-source func) '(lambda (snd chn) (controls->channel '(#f #f #f (0.5)) 0 #f snd chn)))) (snd-display #__line__ ";edit-list->function controls->channel 4: ~A" (procedure-source func))) (revert-sound ind) (func ind 0) (revert-sound ind) (if (ffneq (expand-control ind) 1.0) (snd-display #__line__ ";controls->channel expand: ~A" (expand-control ind)))) (controls->channel (list #f #f #f (list 0.5 .1 .2 .06 0.0))) (let ((func (edit-list->function))) (if (not (equal? (procedure-source func) '(lambda (snd chn) (controls->channel '(#f #f #f (0.5 0.1 0.2 0.06 0.0)) 0 #f snd chn)))) (snd-display #__line__ ";edit-list->function controls->channel 4a: ~A" (procedure-source func))) (revert-sound ind) (func ind 0) (revert-sound ind) (if (ffneq (expand-control ind) 1.0) (snd-display #__line__ ";controls->channel expand 4a: ~A" (expand-control ind)))) (controls->channel (list #f #f #f #f (list 0.1))) (let ((func (edit-list->function))) (if (not (equal? (procedure-source func) '(lambda (snd chn) (controls->channel '(#f #f #f #f (0.1)) 0 #f snd chn)))) (snd-display #__line__ ";edit-list->function controls->channel 5: ~A" (procedure-source func))) (revert-sound ind) (func ind 0) (revert-sound ind) (if (fneq (reverb-control-scale ind) 0.0) (snd-display #__line__ ";controls->channel reverb: ~A" (reverb-control-scale ind)))) (controls->channel (list #f #f #f #f (list 0.1 1.2 0.9 0.9 2.0))) (let ((func (edit-list->function))) (if (not (equal? (procedure-source func) '(lambda (snd chn) (controls->channel '(#f #f #f #f (0.1 1.2 0.9 0.9 2.0)) 0 #f snd chn)))) (snd-display #__line__ ";edit-list->function controls->channel 5a: ~A" (procedure-source func))) (revert-sound ind) (func ind 0) (revert-sound ind) (if (fneq (reverb-control-scale ind) 0.0) (snd-display #__line__ ";controls->channel reverb 5a: ~A" (reverb-control-scale ind)))) (let ((order (filter-control-order ind))) (controls->channel (list #f #f #f #f #f (list 10 '(0 0 1 1)))) (let ((func (edit-list->function))) (if (not (equal? (procedure-source func) '(lambda (snd chn) (controls->channel '(#f #f #f #f #f (10 (0 0 1 1))) 0 #f snd chn)))) (snd-display #__line__ ";edit-list->function controls->channel 6: ~A" (procedure-source func))) (revert-sound ind) (func ind 0) (revert-sound ind) (if (not (= (filter-control-order ind) order)) (snd-display #__line__ ";controls->channel filter: ~A" (filter-control-order ind))))) (close-sound ind)) (let ((ind (open-sound "2.snd"))) (src-sound 3.0 1.0 ind) (save-sound-as "test.snd") (close-sound ind) (set! ind (open-sound "test.snd")) (if (not (= (chans ind) 2)) (snd-display #__line__ ";src-sound/save-sound-as-> ~D chans" (chans ind))) (let ((tag (scan-channel (lambda (y) (> (abs y) 0.0)) 8000 #f))) (if tag (snd-display #__line__ ";src-sound/save-sound-as not zeros: ~A ~A" tag (sample (cadr tag) ind 0)))) (close-sound ind)) (let ((ind (open-sound "oboe.snd"))) (let ((tag (catch #t (lambda () (save-sound-as "test.snd" :edit-position 1)) (lambda args args)))) (if (or (not tag) (not (eq? (car tag) 'no-such-edit))) (snd-display #__line__ ";save-sound-as bad edpos: ~A" tag))) (let ((tag (catch #t (lambda () (save-sound-as "test.snd" :channel 1 :edit-position 1)) (lambda args args)))) (if (or (not tag) (not (eq? (car tag) 'no-such-channel))) (snd-display #__line__ ";save-sound-as bad chan: ~A" tag))) (save-sound-as "test.snd" :comment "this is a comment") (close-sound ind) (set! ind (open-sound "test.snd")) (if (not (string=? (comment ind) "this is a comment")) (snd-display #__line__ ";save-sound-as with comment: ~A" (comment ind))) (close-sound ind)) (mus-sound-prune) )) ;;; ---------------- test 19: transforms ---------------- (define (snd_test_19) (define (bes-j0-1 x) ;returns J0(x) for any real x (if (< (abs x) 8.0) ;direct rational function fit (let* ((y (* x x)) (ans1 (+ 57568490574.0 (* y (+ -13362590354.0 (* y (+ 651619640.7 (* y (+ -11214424.18 (* y (+ 77392.33017 (* y -184.9052456))))))))))) (ans2 (+ 57568490411.0 (* y (+ 1029532985.0 (* y (+ 9494680.718 (* y (+ 59272.64853 (* y (+ 267.8532712 y))))))))))) (/ ans1 ans2)) (let* ((ax (abs x)) (z (/ 8.0 ax)) (y (* z z)) (xx (- ax 0.785398164)) (ans1 (+ 1.0 (* y (+ -0.1098628627e-2 (* y (+ 0.2734510407e-4 (* y (+ -0.2073370639e-5 (* y 0.2093887211e-6))))))))) (ans2 (+ -0.1562499995e-1 (* y (+ 0.1430488765e-3 (* y (+ -0.6911147651e-5 (* y (+ 0.7621095161e-6 (* y -0.934945152e-7)))))))))) (* (sqrt (/ 0.636619772 ax)) (- (* ans1 (cos xx)) (* z (sin xx) ans2)))))) (define (test-j0) (for-each (lambda (x) (if (fneq (bes-j0 x) (bes-j0-1 x)) (snd-display #__line__ ";(bes-j0 ~A) -> ~A ~A" x (bes-j0 x) (bes-j0-1 x)))) (list 0.0 0.5 1.0 2.0 20.0)) (do ((i 0 (+ i 1))) ((= i 10)) (let ((x (random 100.0))) (if (fneq (bes-j0 x) (bes-j0-1 x)) (snd-display #__line__ ";(bes-j0 ~A) -> ~A ~A" x (bes-j0 x) (bes-j0-1 x)))))) (define (bes-j1-1 x) ;returns J1(x) for any real x (define (signum x) (if (= x 0.0) 0 (if (< x 0.0) -1 1))) (if (< (abs x) 8.0) (let* ((y (* x x)) (ans1 (* x (+ 72362614232.0 (* y (+ -7895059235.0 (* y (+ 242396853.1 (* y (+ -2972611.439 (* y (+ 15704.48260 (* y -30.16036606)))))))))))) (ans2 (+ 144725228442.0 (* y (+ 2300535178.0 (* y (+ 18583304.74 (* y (+ 99447.43394 (* y (+ 376.9991397 y))))))))))) (/ ans1 ans2)) (let* ((ax (abs x)) (z (/ 8.0 ax)) (y (* z z)) (xx (- ax 2.356194491)) (ans1 (+ 1.0 (* y (+ 0.183105e-2 (* y (+ -0.3516396496e-4 (* y (+ 0.2457520174e-5 (* y -0.240337019e-6))))))))) (ans2 (+ 0.04687499995 (* y (+ -0.2002690873e-3 (* y (+ 0.8449199096e-5 (* y (+ -0.88228987e-6 (* y 0.105787412e-6)))))))))) (* (signum x) (sqrt (/ 0.636619772 ax)) (- (* ans1 (cos xx)) (* z (sin xx) ans2)))))) (define (test-j1) (for-each (lambda (x) (if (fneq (bes-j1 x) (bes-j1-1 x)) (snd-display #__line__ ";(bes-j1 ~A) -> ~A ~A" x (bes-j1 x) (bes-j1-1 x)))) (list 0.0 0.5 1.0 2.0 20.0)) (do ((i 0 (+ i 1))) ((= i 10)) (let ((x (random 100.0))) (if (fneq (bes-j1 x) (bes-j1-1 x)) (snd-display #__line__ ";(bes-j1 ~A) -> ~A ~A" x (bes-j1 x) (bes-j1-1 x)))))) (define (bes-jn-1 nn x) ;return Jn(x) for any integer n, real x (let* ((n (abs nn)) (besn (if (= n 0) (bes-j0-1 x) (if (= n 1) (bes-j1-1 x) (if (= x 0.0) 0.0 (let ((iacc 40) ;make iacc larger to increase accuracy (ans 0.0) (bigno 1.0e10) (bigni 1.0e-10)) (if (> (abs x) n) ;can use upward recurrence from J0 and J1 (do ((tox (/ 2.0 (abs x))) (bjm (bes-j0-1 (abs x))) (bj (bes-j1-1 (abs x))) (j 1 (+ j 1)) (bjp 0.0)) ((= j n) (set! ans bj)) (set! bjp (- (* j tox bj) bjm)) (set! bjm bj) (set! bj bjp)) (let ((tox (/ 2.0 (abs x))) ;else use downward recurrence from even value (m) (m (* 2 (floor (/ (+ n (sqrt (* iacc n))) 2)))) (jsum 0) ;alternate 0 and 1 -- when 1, accumulate even terms in sum (bjm 0.0) (sum 0.0) (bjp 0.0) (bj 1.0)) (do ((j m (- j 1))) ;the downward recurrence ((= j 0)) (set! bjm (- (* j tox bj) bjp)) (set! bjp bj) (set! bj bjm) (if (> (abs bj) bigno) ;renormalize (may not be necessary in common lisp) (begin (set! bj (* bj bigni)) (set! bjp (* bjp bigni)) (set! ans (* ans bigni)) (set! sum (* sum bigni)))) (if (not (= 0 jsum)) (set! sum (+ sum bj))) (set! jsum (- 1 jsum)) (if (= j n) (set! ans bjp))) (set! sum (- (* 2.0 sum) bj)) (set! ans (/ ans sum)))) (if (and (< x 0.0) (odd? n)) (- ans) ans))))))) (if (and (< nn 0) (odd? nn)) (- besn) besn))) (define (test-jn) (do ((k 0 (+ k 1))) ((= k 10)) (do ((i 0 (+ i 1))) ((= i 10)) (let ((x (random 100.0))) (if (fneq (bes-jn k x) (bes-jn-1 k x)) (snd-display #__line__ ";(bes-jn ~A ~A) -> ~A ~A" k x (bes-jn k x) (bes-jn-1 k x))))))) (define (bes-y0-1 x) ;Bessel function Y0(x) (if (< x 8.0) (let* ((y (* x x)) (ans1 (+ -2957821389.0 (* y (+ 7062834065.0 (* y (+ -512359803.6 (* y (+ 10879881.29 (* y (+ -86327.92757 (* y 228.4622733))))))))))) (ans2 (+ 40076544269.0 (* y (+ 745249964.8 (* y (+ 7189466.438 (* y (+ 47447.26470 (* y (+ 226.1030244 y))))))))))) (+ (/ ans1 ans2) (* 0.636619772 (bes-j0 x) (log x)))) (let* ((z (/ 8.0 x)) (y (* z z)) (xx (- x 0.785398164)) (ans1 (+ 1.0 (* y (+ -0.1098628627e-2 (* y (+ 0.2734510407e-4 (* y (+ -0.2073370639e-5 (* y 0.2093887211e-6))))))))) (ans2 (+ -0.1562499995e-1 (* y (+ 0.1430488765e-3 (* y (+ -0.6911147651e-5 (* y (+ 0.7621095161e-6 (* y -0.934945152e-7))))))))) (ans (+ (* ans1 (sin xx)) (* z (cos xx) ans2)))) (* (sqrt (/ 0.636619772 x)) ans)))) (define (test-y0) (for-each (lambda (x) (if (fneq (bes-y0 x) (bes-y0-1 x)) (snd-display #__line__ ";(bes-y0 ~A) -> ~A ~A" x (bes-y0 x) (bes-y0-1 x)))) (list 0.5 1.0 2.0 20.0)) (do ((i 0 (+ i 1))) ((= i 10)) (let ((x (random 100.0))) (if (fneq (bes-y0 x) (bes-y0-1 x)) (snd-display #__line__ ";(bes-y0 ~A) -> ~A ~A" x (bes-y0 x) (bes-y0-1 x)))))) (define (bes-y1-1 x) ;Bessel function Y1(x) (if (= x 0.0) (real-part (log 0.0)) ; -inf.0 (if (< x 8.0) (let* ((y (* x x)) (ans1 (* x (+ -0.4900604943e13 (* y (+ 0.1275274390e13 (* y (+ -0.5153438139e11 (* y (+ 0.7349264551e9 (* y (+ -0.4237922726e7 (* y 0.8511937935e4)))))))))))) (ans2 (+ 0.2499580570e14 (* y (+ 0.4244419664e12 (* y (+ 0.3733650367e10 (* y (+ 0.2245904002e8 (* y (+ 0.1020426050e6 (* y (+ 0.3549632885e3 y))))))))))))) (+ (/ ans1 ans2) (* 0.636619772 (- (* (bes-j1 x) (log x)) (/ 1.0 x))))) (let* ((z (/ 8.0 x)) (y (* z z)) (xx (- x 2.356194491)) (ans1 (+ 1.0 (* y (+ 0.183105e-2 (* y (+ -0.3516396496e-4 (* y (+ 0.2457520174e-5 (* y -0.240337019e-6))))))))) (ans2 (+ 0.04687499995 (* y (+ -0.200269087e-3 (* y (+ 0.8449199096e-5 (* y (+ -0.88228987e-6 (* y 0.105787412e-6)))))))))) (* (sqrt (/ 0.636619772 x)) (+ (* ans1 (sin xx)) (* z (cos xx) ans2))))))) (define (test-y1) (for-each (lambda (x) (if (fneq (bes-y1 x) (bes-y1-1 x)) (snd-display #__line__ ";(bes-y1 ~A) -> ~A ~A" x (bes-y1 x) (bes-y1-1 x)))) (list 0.01 0.5 1.0 2.0 20.0)) (do ((i 0 (+ i 1))) ((= i 10)) (let ((x (random 100.0))) (if (fneq (bes-y1 x) (bes-y1-1 x)) (snd-display #__line__ ";(bes-y1 ~A) -> ~A ~A" x (bes-y1 x) (bes-y1-1 x)))))) (define (bes-yn-1 n x) ;return Yn(x) for any integer n, real x (if (= n 0) (bes-y0-1 x) (if (= n 1) (bes-y1-1 x) (do ((tox (/ 2.0 x)) (byp 0.0) (by (bes-y1-1 x)) (bym (bes-y0-1 x)) (j 1 (+ j 1))) ((= j n) by) (set! byp (- (* j tox by) bym)) (set! bym by) (set! by byp))))) (define (test-yn) (do ((k 0 (+ k 1))) ((= k 10)) (do ((i 0 (+ i 1))) ((= i 10)) (let ((x (random 100.0))) (if (fneq (/ (bes-yn k x) (bes-yn-1 k x)) 1.0) (snd-display #__line__ ";(bes-yn ~A ~A) -> ~A ~A" k x (bes-yn k x) (bes-yn-1 k x))))))) (define (bes-i0-1 x) ;I0(x) (if (< (abs x) 3.75) (let ((y (expt (/ x 3.75) 2))) (+ 1.0 (* y (+ 3.5156229 (* y (+ 3.0899424 (* y (+ 1.2067492 (* y (+ 0.2659732 (* y (+ 0.360768e-1 (* y 0.45813e-2))))))))))))) (let* ((ax (abs x)) (y (/ 3.75 ax))) (* (/ (exp ax) (sqrt ax)) (+ 0.39894228 (* y (+ 0.1328592e-1 (* y (+ 0.225319e-2 (* y (+ -0.157565e-2 (* y (+ 0.916281e-2 (* y (+ -0.2057706e-1 (* y (+ 0.2635537e-1 (* y (+ -0.1647633e-1 (* y 0.392377e-2)))))))))))))))))))) (define (test-i0) (for-each (lambda (x) (if (fneq (bes-i0 x) (bes-i0-1 x)) (snd-display #__line__ ";(bes-i0 ~A) -> ~A ~A" x (bes-i0 x) (bes-i0-1 x)))) (list 0.0 0.5 1.0 2.0 0.01)) (do ((i 0 (+ i 1))) ((= i 10)) (let ((x (random 1.0))) (if (fneq (bes-i0 x) (bes-i0-1 x)) (snd-display #__line__ ";(bes-i0 ~A) -> ~A ~A" x (bes-i0 x) (bes-i0-1 x)))))) (define (bes-i1 x) ;I1(x) (if (< (abs x) 3.75) (let ((y (expt (/ x 3.75) 2))) (* x (+ 0.5 (* y (+ 0.87890594 (* y (+ 0.51498869 (* y (+ 0.15084934 (* y (+ 0.2658733e-1 (* y (+ 0.301532e-2 (* y 0.32411e-3)))))))))))))) (let* ((ax (abs x)) (y (/ 3.75 ax)) (ans1 (+ 0.2282967e-1 (* y (+ -0.2895312e-1 (* y (+ 0.1787654e-1 (* y -0.420059e-2))))))) (ans2 (+ 0.39894228 (* y (+ -0.3988024e-1 (* y (+ -0.362018e-2 (* y (+ 0.163801e-2 (* y (+ -0.1031555e-1 (* y ans1))))))))))) (sign (if (< x 0.0) -1.0 1.0))) (* (/ (exp ax) (sqrt ax)) ans2 sign)))) (define (test-i1) (if (fneq (bes-i1 1.0) 0.565159) (snd-display #__line__ ";bes-i1 1.0: ~A" (bes-i1 1.0))) (if (fneq (bes-i1 2.0) 1.59063685) (snd-display #__line__ ";bes-i1 2.0: ~A" (bes-i1 2.0))) (if (fneq (bes-i1 5.0) 24.33564) (snd-display #__line__ ";bes-i1 5.0: ~A" (bes-i1 5.0))) (if (fneq (bes-i1 10.0) 2670.9883) (snd-display #__line__ ";bes-i1 10.0: ~A" (bes-i1 10.0)))) (define (bes-in n x) ;return In(x) for any integer n, real x (if (= n 0) (bes-i0 x) (if (= n 1) (bes-i1 x) (if (= x 0.0) 0.0 (let* ((iacc 40) (bigno 1.0e10) (bigni 1.0e-10) (ans 0.0) (tox (/ 2.0 (abs x))) (bip 0.0) (bi 1.0) (m (* 2 (+ n (truncate (sqrt (* iacc n)))))) (bim 0.0)) (do ((j m (- j 1))) ((= j 0)) (set! bim (+ bip (* j tox bi))) (set! bip bi) (set! bi bim) (if (> (abs bi) bigno) (begin (set! ans (* ans bigni)) (set! bi (* bi bigni)) (set! bip (* bip bigni)))) (if (= j n) (set! ans bip))) (if (and (< x 0.0) (odd? n)) (set! ans (- ans))) (* ans (/ (bes-i0 x) bi))))))) (define (test-in) (if (fneq (bes-in 1 1.0) 0.565159) (snd-display #__line__ ";bes-in 1 1.0: ~A" (bes-in 1 1.0))) (if (fneq (bes-in 2 1.0) 0.13574767) (snd-display #__line__ ";bes-in 2 1.0: ~A" (bes-in 2 1.0))) (if (fneq (bes-in 3 1.0) 0.02216842) (snd-display #__line__ ";bes-in 3 1.0: ~A" (bes-in 3 1.0))) (if (fneq (bes-in 5 1.0) 2.71463e-4) (snd-display #__line__ ";bes-in 5 1.0: ~A" (bes-in 5 1.0))) (if (fneq (bes-in 10 1.0) 2.752948e-10) (snd-display #__line__ ";bes-in 10 1.0: ~A" (bes-in 10 1.0))) (if (fneq (bes-in 1 2.0) 1.5906368) (snd-display #__line__ ";bes-in 1 2.0: ~A" (bes-in 1 2.0))) (if (fneq (bes-in 2 2.0) 0.6889484) (snd-display #__line__ ";bes-in 2 2.0: ~A" (bes-in 2 2.0))) (if (fneq (bes-in 3 2.0) 0.21273995) (snd-display #__line__ ";bes-in 3 2.0: ~A" (bes-in 3 2.0))) (if (fneq (bes-in 5 2.0) 0.009825679) (snd-display #__line__ ";bes-in 5 2.0: ~A" (bes-in 5 2.0))) (if (fneq (bes-in 10 2.0) 3.016963e-7) (snd-display #__line__ ";bes-in 10 2.0: ~A" (bes-in 10 2.0))) (if (fneq (bes-in 1 5.0) 24.33564) (snd-display #__line__ ";bes-in 1 5.0: ~A" (bes-in 1 5.0))) (if (fneq (bes-in 2 5.0) 17.505615) (snd-display #__line__ ";bes-in 2 5.0: ~A" (bes-in 2 5.0))) (if (fneq (bes-in 3 5.0) 10.331150) (snd-display #__line__ ";bes-in 3 5.0: ~A" (bes-in 3 5.0))) (if (fneq (bes-in 5 5.0) 2.157974) (snd-display #__line__ ";bes-in 5 5.0: ~A" (bes-in 5 5.0))) (if (fneq (bes-in 10 5.0) 0.004580044) (snd-display #__line__ ";bes-in 10 5.0: ~A" (bes-in 10 5.0)))) (define (bes-k0 x) ;K0(x) (if (<= x 2.0) (let ((y (* x (/ x 4.0)))) (+ (* (- (log (/ x 2.0))) (bes-i0 x)) -0.57721566 (* y (+ 0.42278420 (* y (+ 0.23069756 (* y (+ 0.3488590e-1 (* y (+ 0.262698e-2 (* y (+ 0.10750e-3 (* y 0.74e-5))))))))))))) (let ((y (/ 2.0 x))) (* (/ (exp (- x)) (sqrt x)) (+ 1.25331414 (* y (+ -0.7832358e-1 (* y (+ 0.2189568e-1 (* y (+ -0.1062446e-1 (* y (+ 0.587872e-2 (* y (+ -0.251540e-2 (* y -0.53208e-3)))))))))))))))) (define (test-k0) (if (fneq (bes-k0 1.0) 0.4210244) (snd-display #__line__ ";bes-k0 1.0: ~A" (bes-k0 1.0))) (if (fneq (bes-k0 2.0) 0.1138938) (snd-display #__line__ ";bes-k0 2.0: ~A" (bes-k0 2.0))) (if (fneq (bes-k0 10.0) 1.7780e-5) (snd-display #__line__ ";bes-k0 10.0: ~A" (bes-k0 10.0)))) (define (bes-k1 x) ;K1(x) (if (<= x 2.0) (let ((y (* x (/ x 4.0)))) (+ (* (log (/ x 2)) (bes-i1 x)) (* (/ 1.0 x) (+ 1.0 (* y (+ 0.15443144 (* y (+ -0.67278579 (* y (+ -0.18156897 (* y (+ -0.1919402e-1 (* y (+ -0.110404e-2 (* y -0.4686e-4))))))))))))))) (let ((y (/ 2.0 x))) (* (/ (exp (- x)) (sqrt x)) (+ 1.25331414 (* y (+ 0.23498619 (* y (+ -0.3655620e-1 (* y (+ 0.1504268e-1 (* y (+ -0.780353e-2 (* y (+ 0.325614e-2 (* y -0.68245e-3)))))))))))))))) (define (test-k1) (if (fneq (bes-k1 1.0) 0.60190723) (snd-display #__line__ ";bes-k1 1.0: ~A" (bes-k1 1.0))) (if (fneq (bes-k1 2.0) 0.1398658) (snd-display #__line__ ";bes-k1 2.0: ~A" (bes-k1 2.0))) (if (fneq (bes-k1 10.0) 1.86487e-5) (snd-display #__line__ ";bes-k1 10.0: ~A" (bes-k1 10.0)))) (define (bes-kn n x) ;return Kn(x) for any integer n, real x (if (= n 0) (bes-k0 x) (if (= n 1) (bes-k1 x) (do ((tox (/ 2.0 x)) (bkm (bes-k0 x)) (bk (bes-k1 x)) (bkp 0.0) (j 1 (+ j 1))) ((= j n) bk) (set! bkp (+ bkm (* j tox bk))) (set! bkm bk) (set! bk bkp))))) (define (test-kn) (if (fneq (bes-kn 1 1.0) 0.6019072) (snd-display #__line__ ";bes-kn 1 1.0: ~A" (bes-kn 1 1.0))) (if (fneq (bes-kn 2 1.0) 1.6248389) (snd-display #__line__ ";bes-kn 2 1.0: ~A" (bes-kn 2 1.0))) (if (fneq (bes-kn 3 1.0) 7.1012629) (snd-display #__line__ ";bes-kn 3 1.0: ~A" (bes-kn 3 1.0))) (if (fneq (bes-kn 5 1.0) 360.96059) (snd-display #__line__ ";bes-kn 5 1.0: ~A" (bes-kn 5 1.0))) (if (fneq (bes-kn 1 2.0) 0.139865) (snd-display #__line__ ";bes-kn 1 2.0: ~A" (bes-kn 1 2.0))) (if (fneq (bes-kn 2 2.0) 0.2537597) (snd-display #__line__ ";bes-kn 2 2.0: ~A" (bes-kn 2 2.0))) (if (fneq (bes-kn 3 2.0) 0.6473854) (snd-display #__line__ ";bes-kn 3 2.0: ~A" (bes-kn 3 2.0))) (if (fneq (bes-kn 5 2.0) 9.431049) (snd-display #__line__ ";bes-kn 5 2.0: ~A" (bes-kn 5 2.0))) (if (fneq (bes-kn 1 5.0) 0.00404461) (snd-display #__line__ ";bes-kn 1 5.0: ~A" (bes-kn 1 5.0))) (if (fneq (bes-kn 2 5.0) 0.0053089) (snd-display #__line__ ";bes-kn 2 5.0: ~A" (bes-kn 2 5.0))) (if (fneq (bes-kn 3 5.0) 0.0082917) (snd-display #__line__ ";bes-kn 3 5.0: ~A" (bes-kn 3 5.0))) (if (fneq (bes-kn 5 5.0) 0.0327062) (snd-display #__line__ ";bes-kn 5 5.0: ~A" (bes-kn 5 5.0)))) (define (gammln xx) ;Ln(gamma(xx)), xx>0 (let* ((stp 2.5066282746310005e0) (x xx) (tmp (+ x 5.5)) (tmp1 (- tmp (* (+ x 0.5) (log tmp)))) (ser (+ 1.000000000190015 (/ 76.18009172947146 (+ x 1.0)) (/ -86.50532032941677 (+ x 2.0)) (/ 24.01409824083091 (+ x 3.0)) (/ -1.231739572450155 (+ x 4)) (/ 0.1208650973866179e-2 (+ x 5.0)) (/ -0.5395239384953e-5 (+ x 6.0))))) (- (log (/ (* stp ser) x)) tmp1))) (define (test-lgamma) (do ((i 0 (+ i 1))) ((= i 10)) (let ((x (random 100.0))) (if (fneq (lgamma x) (gammln x)) (snd-display #__line__ ";(lgamma ~A) -> ~A ~A" x (lgamma x) (gammln x)))))) (define (test-erf) (if (fneq (erf 0.0) 0.0) (snd-display #__line__ ";erf 0.0: ~A" (erf 0.0))) (if (fneq (erf 0.5) 0.5204998) (snd-display #__line__ ";erf 0.5: ~A" (erf 0.5))) (if (fneq (erf 1.0) 0.8427007) (snd-display #__line__ ";erf 0.0: ~A" (erf 1.0))) (do ((i 0 (+ i 1))) ((= i 10)) (let ((val (random 2.0))) (if (fneq (+ (erf val) (erfc val)) 1.0) (snd-display #__line__ ";erf+erfc: ~A (~A + ~A)" (+ (erf val) (erfc val)) (erf val) (erfc val)))))) (define (inverse-haar f) (let* ((n (length f)) (g (make-float-vector n)) (s2 (sqrt 2.0)) (v (/ 1.0 (sqrt n)))) (set! (f 0) (* (f 0) v)) (do ((m 2 (* m 2))) ((> m n)) (let ((mh (/ m 2))) (do ((j 0 (+ j 2)) (k 0 (+ k 1))) ((= j m)) (let ((x (f k)) (y (* (f (+ mh k)) v))) (set! (g j) (+ x y)) (set! (g (+ j 1)) (- x y)))) (do ((i (- m 1) (- i 1))) ((< i 0)) (set! (f i) (g i))) (set! v (* v s2)))) f)) (define (wavelet data n isign wf cc) (let* ((cc-size (length cc)) (ccr (make-float-vector cc-size)) (sig -1.0)) (do ((i 0 (+ i 1)) (j (- cc-size 1) (- j 1))) ((= i cc-size)) (set! (ccr j) (* sig (cc i))) (set! sig (- sig))) (if (>= n 4) (if (>= isign 0) (do ((nn n (/ nn 2))) ((< nn 4)) (wf data nn isign cc ccr)) (do ((nn 4 (* nn 2))) ((> nn n)) (wf data nn isign cc ccr)))))) (define (pwt data n isign cc cr) (let* ((data1 (make-float-vector n)) (n1 (- n 1)) (ncof (length cc)) (nmod (* ncof n)) (nh (floor (/ n 2))) (joff (- (floor (/ ncof 2)))) (ioff joff)) (if (>= isign 0) (do ((ii 0 (+ 1 ii)) (i 1 (+ i 2))) ((> i n)) (let ((ni (+ i nmod ioff)) (nj (+ i nmod joff)) (ii+nh (+ ii nh))) (do ((k 1 (+ k 1))) ((> k ncof)) (let ((jf (logand n1 (+ ni k))) ;gad wotta kludge... (jr (logand n1 (+ nj k)))) (set! (data1 ii) (+ (data1 ii) (* (cc (- k 1)) (data jf)))) (set! (data1 ii+nh) (+ (data1 ii+nh) (* (cr (- k 1)) (data jr)))))))) (do ((ii 0 (+ 1 ii)) (i 1 (+ i 2))) ((> i n)) (let ((ai (data ii)) (ai1 (data (+ ii nh))) (ni (+ i nmod ioff)) (nj (+ i nmod joff))) (do ((k 1 (+ k 1))) ((> k ncof)) (let ((jf (logand n1 (+ ni k))) (jr (logand n1 (+ nj k)))) (set! (data1 jf) (+ (data1 jf) (* ai (cc (- k 1))))) (set! (data1 jr) (+ (data1 jr) (* ai1 (cr (- k 1)))))))))) (copy data1 data) data)) (define (corr x y N M) ;; correlation from Orfanidis (let ((R (make-float-vector (+ 1 M)))) (do ((k 0 (+ k 1))) ((> k M)) (set! (R k) 0.0) (do ((n 0 (+ 1 n))) ((= n (- N k))) (set! (R k) (+ (R k) (* (x (+ n k)) (y n)))))) R)) ;; this returns the same results as the fft-based version below, modulo float-vector lengths (define (cross-correlate-1 snd0 chn0 snd1 chn1) (let* ((len0 (framples snd0 chn0)) (len1 (framples snd1 chn1)) (clen (min len0 len1)) (dlen (max len0 len1)) (corr (make-float-vector clen)) (data0 (channel->float-vector 0 dlen snd0 chn0)) (data1 (channel->float-vector 0 dlen snd1 chn1))) (do ((lag 0 (+ 1 lag))) ((= lag clen) corr) (let ((mdata (float-vector-multiply! (copy data0) data1)) (sum (make-one-pole 1.0 -1.0))) (do ((i 0 (+ i 1))) ((= i dlen)) (one-pole sum (float-vector-ref mdata i))) (set! (corr lag) (one-pole sum 0.0)) (let ((orig (data0 0))) (float-vector-move! data0 0 1) (set! (data0 (- dlen 1)) orig)))))) (define (cross-correlate-2 snd0 chn0 snd1 chn1) (let* ((len0 (framples snd0 chn0)) (len1 (framples snd1 chn1)) (ilen (max len0 len1)) (pow2 (ceiling (log ilen 2))) (fftlen (expt 2 pow2)) (fftscale (/ 1.0 fftlen)) (rl1 (channel->float-vector 0 fftlen snd1 chn1)) (rl2 (channel->float-vector 0 fftlen snd0 chn0)) (im1 (make-float-vector fftlen)) (im2 (make-float-vector fftlen))) (fft rl1 im1 1) (fft rl2 im2 1) (let ((tmprl (copy rl1)) (tmpim (copy im1))) (float-vector-multiply! tmprl rl2) ; (* tempr1 tempr2) (float-vector-multiply! tmpim im2) ; (* tempi1 tempi2) (float-vector-multiply! im2 rl1) ; (* tempr1 tempi2) (float-vector-multiply! rl2 im1) ; (* tempr2 tempi1) (float-vector-add! tmprl tmpim) ; add the first two (float-vector-subtract! im2 rl2) ; subtract the fourth from the third (float-vector-scale! (fft tmprl im2 -1) fftscale)))) (define (cross-correlate-3 rl1 rl2 fftlen) (let ((fftscale (/ 1.0 fftlen)) (im1 (make-float-vector fftlen)) (im2 (make-float-vector fftlen))) (fft rl1 im1 1) (fft rl2 im2 1) (let ((tmprl (copy rl1)) (tmpim (copy im1))) (float-vector-multiply! tmprl rl2) ; (* tempr1 tempr2) (float-vector-multiply! tmpim im2) ; (* tempi1 tempi2) (float-vector-multiply! im2 rl1) ; (* tempr1 tempi2) (float-vector-multiply! rl2 im1) ; (* tempr2 tempi1) (float-vector-add! tmprl tmpim) ; add the first two (float-vector-subtract! im2 rl2) ; subtract the fourth from the third (float-vector-scale! (fft tmprl im2 -1) fftscale)))) (define* (automorph a b c d snd chn) (let* ((len (framples snd chn)) (pow2 (ceiling (log len 2))) (fftlen (expt 2 pow2)) (fftlen2 (/ fftlen 2)) (fftscale (/ 1.0 fftlen)) (rl (channel->float-vector 0 fftlen snd chn)) (im (make-float-vector fftlen)) (c1 #f)) (fft rl im 1) (float-vector-scale! rl fftscale) (float-vector-scale! im fftscale) ;; handle 0 case by itself (set! c1 (complex (rl 0) (im 0))) (set! c1 (/ (+ (* a c1) b) (+ (* c c1) d))) (set! (rl 0) (real-part c1)) (set! (im 0) (imag-part c1)) (do ((i 1 (+ i 1)) (k (- fftlen 1) (- k 1))) ((= i fftlen2)) (set! c1 (complex (float-vector-ref rl i) (float-vector-ref im i))) (set! c1 (/ (+ (* a c1) b) (+ (* c c1) d))) (float-vector-set! rl k (float-vector-set! rl i (real-part c1))) (float-vector-set! im k (- (float-vector-set! im i (imag-part c1))))) (fft rl im -1) (float-vector->channel rl 0 len snd chn #f (format #f "automorph ~A ~A ~A ~A" a b c d)))) (let* ((daub4 (float-vector 0.4829629131445341 0.8365163037378079 0.2241438680420134 -0.1294095225512604)) (daub6 (float-vector 0.332670552950 0.806891509311 0.459877502118 -0.135011020010 -0.085441273882 0.035226291886)) (daub8 (float-vector 0.230377813309 0.714846570553 0.630880767930 -0.027983769417 -0.187034811719 0.030841381836 0.032883011667 -0.010597401785)) (daub10 (float-vector 0.160102397974 0.603829269797 0.724308528438 0.138428145901 -0.242294887066 -0.032244869585 0.077571493840 -0.006241490213 -0.012580751999 0.003335725285)) (daub12 (float-vector 0.111540743350 0.494623890398 0.751133908021 0.315250351709 -0.226264693965 -0.129766867567 0.097501605587 0.027522865530 -0.031582039317 0.000553842201 0.004777257511 -0.001077301085)) (daub14 (float-vector 0.077852054085 0.396539319482 0.729132090846 0.469782287405 -0.143906003929 -0.224036184994 0.071309219267 0.080612609151 -0.038029936935 -0.016574541631 0.012550998556 0.000429577973 -0.001801640704 0.000353713800)) (daub16 (float-vector 0.054415842243 0.312871590914 0.675630736297 0.585354683654 -0.015829105256 -0.284015542962 0.000472484574 0.128747426620 -0.017369301002 -0.044088253931 0.013981027917 0.008746094047 -0.004870352993 -0.000391740373 0.000675449406 -0.000117476784)) (daub18 (float-vector 0.038077947364 0.243834674613 0.604823123690 0.657288078051 0.133197385825 -0.293273783279 -0.096840783223 0.148540749338 0.030725681479 -0.067632829061 0.000250947115 0.022361662124 -0.004723204758 -0.004281503682 0.001847646883 0.000230385764 -0.000251963189 0.000039347320)) (daub20 (float-vector 0.026670057901 0.188176800077 0.527201188931 0.688459039453 0.281172343661 -0.249846424327 -0.195946274377 0.127369340336 0.093057364604 -0.071394147166 -0.029457536822 0.033212674059 0.003606553567 -0.010733175483 0.001395351747 0.001992405295 -0.000685856695 -0.000116466855 0.000093588670 -0.000013264203)) (SQRT2 1.41421356237309504880168872420969808) (Battle-Lemarie (float-vector (* SQRT2 -0.002) (* SQRT2 -0.003) (* SQRT2 0.006) (* SQRT2 0.006) (* SQRT2 -0.013) (* SQRT2 -0.012) (* SQRT2 0.030) (* SQRT2 0.023) (* SQRT2 -0.078) (* SQRT2 -0.035) (* SQRT2 0.307) (* SQRT2 0.542) (* SQRT2 0.307) (* SQRT2 -0.035) (* SQRT2 -0.078) (* SQRT2 0.023) (* SQRT2 0.030) (* SQRT2 -0.012) (* SQRT2 -0.013) (* SQRT2 0.006) (* SQRT2 0.006) (* SQRT2 -0.003) (* SQRT2 -0.002) 0.0)) (Burt-Adelson (float-vector (* SQRT2 (/ -1.0 20.0)) (* SQRT2 (/ 5.0 20.0)) (* SQRT2 (/ 12.0 20.0)) (* SQRT2 (/ 5.0 20.0)) (* SQRT2 (/ -1.0 20.0)) 0.0)) (Beylkin (float-vector 0.099305765374353 0.424215360812961 0.699825214056600 0.449718251149468 -.110927598348234 -.264497231446384 0.026900308803690 0.155538731877093 -.017520746266529 -.088543630622924 0.019679866044322 0.042916387274192 -.017460408696028 -.014365807968852 0.010040411844631 .0014842347824723 -.002736031626258 .0006404853285212)) (SQRT15 3.87298334620741688517927) (coif2 (float-vector (/ (* SQRT2 (- SQRT15 3)) 32.0) (/ (* SQRT2 (- 1 SQRT15)) 32.0) (/ (* SQRT2 (- 6 (* 2 SQRT15))) 32.0) (/ (* SQRT2 (+ (* 2 SQRT15) 6)) 32.0) (/ (* SQRT2 (+ SQRT15 13)) 32.0) (/ (* SQRT2 (- 9 SQRT15)) 32.0))) (coif4 (float-vector 0.0011945726958388 -0.01284557955324 0.024804330519353 0.050023519962135 -0.15535722285996 -0.071638282295294 0.57046500145033 0.75033630585287 0.28061165190244 -0.0074103835186718 -0.014611552521451 -0.0013587990591632)) (coif6 (float-vector -0.0016918510194918 -0.00348787621998426 0.019191160680044 0.021671094636352 -0.098507213321468 -0.056997424478478 0.45678712217269 0.78931940900416 0.38055713085151 -0.070438748794943 -0.056514193868065 0.036409962612716 0.0087601307091635 -0.011194759273835 -0.0019213354141368 0.0020413809772660 0.00044583039753204 -0.00021625727664696)) (sym2 (float-vector (* SQRT2 -0.125) (* SQRT2 0.25) (* SQRT2 0.75) (* SQRT2 0.25) (* SQRT2 -0.125))) (sym3 (float-vector (/ (* SQRT2 1.0) 8.0) (/ (* SQRT2 3.0) 8.0) (/ (* SQRT2 3.0) 8.0) (/ (* SQRT2 1.0) 8.0))) (sym4 (float-vector (/ (* SQRT2 3.0) 128.0) (/ (* SQRT2 -6.0) 128.0) (/ (* SQRT2 -16.0) 128.0) (/ (* SQRT2 38.0) 128.0) (/ (* SQRT2 90.0) 128.0) (/ (* SQRT2 38.0) 128.0) (/ (* SQRT2 -16.0) 128.0) (/ (* SQRT2 -6.0) 128.0) (/ (* SQRT2 3.0) 128.0) 0.0)) (sym5 (float-vector (/ (* SQRT2 3.0) 64.0) (/ (* SQRT2 -9.0) 64.0) (/ (* SQRT2 -7.0) 64.0) (/ (* SQRT2 45.0) 64.0) (/ (* SQRT2 45.0) 64.0) (/ (* SQRT2 -7.0) 64.0) (/ (* SQRT2 -9.0) 64.0) (/ (* SQRT2 3.0) 64.0))) (sym6 (float-vector (/ (* SQRT2 -35.0) 16384.0) (/ (* SQRT2 -105.0) 16384.0) (/ (* SQRT2 -195.0) 16384.0) (/ (* SQRT2 865.0) 16384.0) (/ (* SQRT2 363.0) 16384.0) (/ (* SQRT2 -3489.0) 16384.0) (/ (* SQRT2 -307.0) 16384.0) (/ (* SQRT2 11025.0) 16384.0) (/ (* SQRT2 11025.0) 16384.0) (/ (* SQRT2 -307.0) 16384.0) (/ (* SQRT2 -3489.0) 16384.0) (/ (* SQRT2 363.0) 16384.0) (/ (* SQRT2 865.0) 16384.0) (/ (* SQRT2 -195.0) 16384.0) (/ (* SQRT2 -105.0) 16384.0) (/ (* SQRT2 -35.0) 16384.0)))) (define wts (list daub4 daub6 daub8 daub10 daub12 daub14 daub16 daub18 daub20 Battle-Lemarie Burt-Adelson Beylkin coif2 coif4 coif6 sym2 sym3 sym4 sym5 sym6)) (if (defined? 'bes-j0) ; dependent on mus-config.h HAVE_SPECIAL_FUNCTIONS (begin (test-j0) (test-j1) (test-jn) (test-y0) (test-y1) (test-yn) (test-k0) (test-k1) (test-kn) (test-i0) (test-i1) (test-in) (test-erf) (test-lgamma))) (do ((clmtest 0 (+ 1 clmtest))) ((= clmtest tests)) (log-mem clmtest) (let ((d0 #f) (d1 #f) (fn #f)) (let ((index (open-sound "oboe.snd"))) ;; check small transform cases (set! (transform-graph?) #t) (for-each (lambda (transform) (set! *transform-type* transform) (for-each (lambda (size) (catch #t (lambda () (set! *transform-size* size) (update-transform-graph)) (lambda args args))) (list 8 7 -7 4 3 2 1 0))) (list fourier-transform wavelet-transform autocorrelation walsh-transform cepstrum haar-transform)) (close-sound index)) ;; -------- fft (set! d0 (make-float-vector 16)) (set! (d0 0) 1.0) (snd-transform fourier-transform d0 0) (do ((i 0 (+ i 1))) ((= i 16)) (if (fneq (d0 i) 1.0) (snd-display #__line__ ";fourier (1.0) [~D]: ~A?" i (d0 i)))) (set! d0 (make-float-vector 19)) (set! (d0 0) 1.0) (snd-transform fourier-transform d0 0) (let ((happy #t)) (do ((i 0 (+ i 1))) ((or (not happy) (= i 16))) (if (fneq (d0 i) 1.0) (begin (snd-display #__line__ ";fourier (1.0) [~D]: ~A?" i (d0 i)) (set! happy #f))))) (snd-transform fourier-transform d0 0) (if (and (fneq (d0 0) 256.0) (fneq (d0 0) 361.0)) ; fftw funny length (snd-display #__line__ ";fourier (256.0): ~A?" (d0 0))) (let ((happy #t)) (do ((i 1 (+ i 1))) ((or (not happy) (= i 16))) (if (fneq (d0 i) 0.0) (begin (snd-display #__line__ ";fourier (0.0) [~D]: ~A?" i (d0 i)) (set! happy #f))))) (let ((r0 (make-float-vector 8)) (i0 (make-float-vector 8)) (r1 (make-float-vector 8)) (i1 (make-float-vector 8)) (r2 (make-float-vector 8)) (i2 (make-float-vector 8))) (set! (r0 1) .5) (set! (r1 3) .75) (set! (r2 1) .25) ; 1/2 (set! (r2 3) .25) ; 1/3 (mus-fft r0 i0) (mus-fft r1 i1) (mus-fft r2 i2) (float-vector-scale! r0 .5) (float-vector-scale! i0 .5) (float-vector-scale! r1 .3333) (float-vector-scale! i1 .3333) (float-vector-add! r0 r1) (float-vector-add! i0 i1) (if (or (not (vequal r0 r2)) (not (vequal i0 i2))) (snd-display #__line__ ";fft additions/scaling: ~A ~A: ~A ~A" r2 i2 r0 i0))) (set! d0 (make-float-vector 8)) (set! d1 (make-float-vector 8)) (set! (d0 2) 1.0) (mus-fft d0 d1 8 1) (if (or (not (vequal d0 (float-vector 1.000 0.000 -1.000 0.000 1.000 0.000 -1.000 0.000))) (not (vequal d1 (float-vector 0.000 1.000 0.000 -1.000 0.000 1.000 0.000 -1.000)))) (snd-display #__line__ ";mus-fft 1: ~A ~A?" d0 d1)) (mus-fft d0 d1 8 -1) (if (or (not (vequal d0 (float-vector 0.000 0.000 8.000 0.000 0.000 0.000 0.000 0.000))) (not (vequal d1 (float-vector 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000)))) (snd-display #__line__ ";mus-fft -1: ~A ~A?" d0 d1)) (fill! d0 1.0) (fill! d1 0.0) (mus-fft d0 d1 8) (if (or (not (vequal d0 (float-vector 8.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) (not (vequal d1 (float-vector 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000)))) (snd-display #__line__ ";mus-fft 2: ~A ~A?" d0 d1)) (mus-fft d0 d1 8 -1) (if (or (not (vequal d0 (float-vector 8.000 8.000 8.000 8.000 8.000 8.000 8.000 8.000))) (not (vequal d1 (float-vector 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000)))) (snd-display #__line__ ";mus-fft -2: ~A ~A?" d0 d1)) (fill! d1 0.0) (fill-float-vector d0 (random 1.0)) (set! fn (copy d0)) (mus-fft d0 d1 8) (mus-fft d0 d1 8 -1) (float-vector-scale! d0 (/ 1.0 8.0)) (if (not (vequal d0 fn)) (snd-display #__line__ ";mus-fft 3: ~A ~A?" d0 fn)) (let ((d0 (make-float-vector 8)) (d1 (make-float-vector 8))) (do ((i 0 (+ i 1))) ((= i 8)) (set! (d0 i) (- 1.0 (random 2.0))) (set! (d1 i) (- 1.0 (random 2.0)))) (let ((save-d0 (copy d0)) (save-d1 (copy d1)) (reversed-d0 (make-float-vector 8)) (reversed-d1 (make-float-vector 8))) (do ((i 0 (+ i 1))) ((= i 8)) (set! (reversed-d0 i) (d0 (- 7 i))) (set! (reversed-d1 i) (d1 (- 7 i)))) (mus-fft d0 d1 8) (mus-fft d0 d1 8) (float-vector-scale! d0 .125) (float-vector-scale! d1 .125) (do ((i 0 (+ i 1))) ; one sample rotation here ((= i 7)) (if (fneq (d0 (+ i 1)) (reversed-d0 i)) (snd-display #__line__ ";mus-fft d0 reversed: ~A ~A" d0 reversed-d0)) (if (fneq (d1 (+ i 1)) (reversed-d1 i)) (snd-display #__line__ ";mus-fft d1 reversed: ~A ~A" d1 reversed-d1))) (mus-fft d0 d1 8) (mus-fft d0 d1 8) (float-vector-scale! d0 .125) (float-vector-scale! d1 .125) (if (not (vequal d0 save-d0)) (snd-display #__line__ ";mus-fft d0 saved: ~A ~A" d0 save-d0)) (if (not (vequal d1 save-d1)) (snd-display #__line__ ";mus-fft d1 saved: ~A ~A" d1 save-d1)))) (for-each (lambda (size) (let ((dcopy #f)) (set! d0 (make-float-vector size)) (set! (d0 0) 1.0) (set! dcopy (copy d0)) (set! d1 (snd-spectrum d0 rectangular-window size)) (if (not (vequal d0 dcopy)) (snd-display #__line__ ";snd-spectrum not in-place? ~A ~A" d0 dcopy))) (let ((happy #t)) (do ((i 0 (+ i 1))) ((or (not happy) (= i (/ size 2)))) (if (fneq (d1 i) 1.0) (begin (snd-display #__line__ ";snd-spectrum (1.0) [~D: ~D]: ~A?" i size (d1 i)) (set! happy #f))))) (set! d0 (make-float-vector size 1.0)) (set! d1 (snd-spectrum d0 rectangular-window)) (if (fneq (d1 0) 1.0) (snd-display #__line__ ";snd-spectrum back (1.0 ~D): ~A?" size (d1 0))) (let ((happy #t)) (do ((i 1 (+ i 1))) ((or (not happy) (= i (/ size 2)))) (if (fneq (d1 i) 0.0) (begin (snd-display #__line__ ";snd-spectrum (0.0) [~D: ~D]: ~A?" i size (d1 i)) (set! happy #f))))) (set! d0 (make-float-vector size)) (set! (d0 0) 1.0) (set! d1 (snd-spectrum d0 rectangular-window size #f)) ; dB (0.0 = max) (let ((happy #t)) (do ((i 0 (+ i 1))) ((or (not happy) (= i (/ size 2)))) (if (fneq (d1 i) 0.0) (begin (snd-display #__line__ ";snd-spectrum dB (0.0) [~D: ~D]: ~A?" i size (d1 i)) (set! happy #f))))) (set! d0 (make-float-vector size 1.0)) (set! d1 (snd-spectrum d0 rectangular-window size #f)) (if (fneq (d1 0) 0.0) (snd-display #__line__ ";snd-spectrum dB back (0.0 ~D): ~A?" size (d1 0))) (let ((happy #t)) (do ((i 1 (+ i 1))) ((or (not happy) (= i (/ size 2)))) (if (fneq (d1 i) -90.0) ; currently ignores min-dB (snd-sig.c 5023) (begin (snd-display #__line__ ";snd-spectrum dB (1.0) [~D: ~D]: ~A?" i size (d1 i)) (set! happy #f))))) (let ((dcopy #f)) (set! d0 (make-float-vector size)) (set! (d0 0) 1.0) (set! dcopy (copy d0)) (set! d1 (snd-spectrum d0 rectangular-window size #t 1.0 #t)) ; in-place (if (vequal d0 dcopy) (snd-display #__line__ ";snd-spectrum in-place? ~A ~A" d0 dcopy)) (if (not (vequal d0 d1)) (snd-display #__line__ ";snd-spectrum returns in-place? ~A ~A" d0 d1))) (let ((happy #t)) (do ((i 0 (+ i 1))) ((or (not happy) (= i (/ size 2)))) (if (fneq (d1 i) 1.0) (begin (snd-display #__line__ ";snd-spectrum (1.0 #t) [~D: ~D]: ~A?" i size (d1 i)) (set! happy #f))))) (let ((dcopy #f)) (set! d0 (make-float-vector size)) (set! (d0 0) 1.0) (set! dcopy (copy d0)) (set! d1 (snd-spectrum d0 rectangular-window size #f 1.0 #t)) ; in-place dB (if (vequal d0 dcopy) (snd-display #__line__ ";snd-spectrum dB in-place? ~A ~A" d0 dcopy)) (if (not (vequal d0 d1)) (snd-display #__line__ ";snd-spectrum dB returns in-place? ~A ~A" d0 d1))) (let ((happy #t)) (do ((i 0 (+ i 1))) ((or (not happy) (= i (/ size 2)))) (if (fneq (d1 i) 0.0) (begin (snd-display #__line__ ";snd-spectrum dB (1.0 #t) [~D: ~D]: ~A?" i size (d1 i)) (set! happy #f))))) (set! d0 (make-float-vector size 1.0)) (set! d1 (snd-spectrum d0 rectangular-window size #t 0.0 #f #f)) ; linear (in-place) not normalized (if (fneq (d1 0) size) (snd-display #__line__ ";snd-spectrum no norm 0: ~A" d1)) (let ((happy #t)) (do ((i 1 (+ i 1))) ((or (not happy) (= i (/ size 2)))) (if (fneq (d1 i) 0.0) (begin (snd-display #__line__ ";snd-spectrum no norm (0.0) [~D: ~D]: ~A?" i size (d1 i)) (set! happy #f))))) (set! d0 (make-float-vector size 1.0)) (set! d1 (snd-spectrum d0 blackman2-window size)) (if (and (not (vequal d1 (float-vector 1.000 0.721 0.293 0.091))) (not (vequal d1 (float-vector 1.000 0.647 0.173 0.037 0.024 0.016 0.011 0.005)))) (snd-display #__line__ ";blackman2 snd-spectrum: ~A~%" d1)) (set! d0 (make-float-vector size 1.0)) (set! d1 (snd-spectrum d0 gaussian-window size #t 0.5)) (if (and (not (vequal d1 (float-vector 1.000 0.900 0.646 0.328))) (not (vequal d1 (float-vector 1.000 0.870 0.585 0.329 0.177 0.101 0.059 0.028)))) (snd-display #__line__ ";gaussian 0.5 snd-spectrum: ~A~%" d1)) (set! d0 (make-float-vector size 1.0)) (set! d1 (snd-spectrum d0 gaussian-window size #t 0.85)) (if (and (not (vequal d1 (float-vector 1.000 0.924 0.707 0.383))) (not (vequal d1 (float-vector 1.000 0.964 0.865 0.725 0.566 0.409 0.263 0.128)))) (snd-display #__line__ ";gaussian 0.85 snd-spectrum: ~A~%" d1)) ) (list 8 16)) (for-each (lambda (len) (let ((rl (make-float-vector len)) (xrl (make-float-vector len)) (len2 (/ len 2))) (fill! rl 1.0) (fill! xrl 1.0) (snd-transform fourier-transform rl) (snd-transform fourier-transform xrl #t) (let ((happy #t)) (do ((i 0 (+ i 1))) ((or (not happy) (= i len2))) (if (fneq (rl i) (xrl i)) (begin (snd-display #__line__ ";flat fft: ~A at ~A: ~A ~A" len i (rl i) (xrl i)) (set! happy #f))))) (if (fneq (rl 0) (* len len)) (snd-display #__line__ ";snd-transform ~A at 0: ~A" len (rl 0))) (set! (rl 0) 0.0) (if (> (float-vector-peak rl) .001) (snd-display #__line__ ";snd-transform ~A impulse: ~A" len (float-vector-peak rl))))) (list 16 128 512 1024)) (for-each (lambda (len) (let ((rl (make-float-vector len)) (xrl (make-float-vector len)) (len2 (/ len 2))) (set! (rl len2) 1.0) (set! (xrl len2) 1.0) (snd-transform fourier-transform rl) (snd-transform fourier-transform xrl #t) (let ((happy #t)) (do ((i 0 (+ i 1))) ((or (not happy) (= i len2))) (if (fneq (rl i) (xrl i)) (begin (snd-display #__line__ ";impulse fft: ~A at ~A: ~A ~A" len i (rl i) (xrl i)) (set! happy #f))))) (if (fneq (rl 0) 1.0) (snd-display #__line__ ";flat ~A at 0: ~A" len (rl 0))))) (list 16 128 512 1024)) (for-each (lambda (len) (let ((rl (make-float-vector len)) (xrl (make-float-vector len))) (do ((i 0 (+ i 1))) ((= i len)) (float-vector-set! rl i (random 1.0))) (copy rl xrl) (snd-transform fourier-transform rl) (float-vector-scale! rl (/ 1.0 len)) (snd-transform fourier-transform xrl #t) (float-vector-scale! xrl (/ 1.0 len)) (if (not (vequal rl xrl)) (snd-display #__line__ ";random fft: ~A: ~A ~A" len rl xrl)))) (list 16 128 512 1024 4096)) (for-each (lambda (len) (let ((rl (make-float-vector len)) (xrl (make-float-vector len)) (g (make-oscil (/ 220500.0 len)))) (do ((i 0 (+ i 1))) ((= i len)) (float-vector-set! rl i (oscil g))) (copy rl xrl) (snd-transform fourier-transform rl) (float-vector-scale! rl (/ 1.0 len)) (snd-transform fourier-transform xrl #t) (float-vector-scale! xrl (/ 1.0 len)) (if (not (vequal rl xrl)) (snd-display #__line__ ";random fft: ~A: ~A ~A" len rl xrl)))) (list 16 128 512 1024 4096)) ;; -------- autocorrelation (let ((rl (make-float-vector 16 0.0))) (set! (rl 0) 1.0) (autocorrelate rl) (if (not (vequal rl (float-vector 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0))) (snd-display #__line__ ";autocorrelate 1: ~A" rl))) (let ((rl (make-float-vector 16 0.0))) (set! (rl 0) 1.0) (set! (rl 1) -1.0) (autocorrelate rl) (if (not (vequal rl (float-vector 2 -1 0 0 0 0 0 0 0 0 0 0 0 0 0 0))) (snd-display #__line__ ";autocorrelate 1 -1: ~A" rl))) (let ((rl (make-float-vector 16 0.0))) (set! (rl 0) 1.0) (set! (rl 4) -1.0) (autocorrelate rl) (if (not (vequal rl (float-vector 2 0 0 0 -1 0 0 0 0 0 0 0 0 0 0 0))) (snd-display #__line__ ";autocorrelate 1 0 0 0 -1: ~A" rl))) (let ((rl (make-float-vector 16)) (rl1 (make-float-vector 16))) (do ((i 0 (+ i 1))) ((= i 8)) (set! (rl i) (- 8.0 i))) (copy rl rl1) (let ((nr (float-vector-subseq (corr rl rl 16 16) 0 15))) (autocorrelate rl1) (if (not (vequal rl1 nr)) (snd-display #__line__ ";autocorrelate/corr (ramp):~%; ~A~%; ~A" rl1 nr)))) (let ((rl (make-float-vector 16)) (rl1 (make-float-vector 16))) (do ((i 0 (+ i 1))) ((= i 8)) (set! (rl i) (- 1.0 (random 2.0)))) (copy rl rl1) (let ((nr (float-vector-subseq (corr rl rl 16 16) 0 15))) (autocorrelate rl1) (if (not (vequal rl1 nr)) (snd-display #__line__ ";autocorrelate/corr:~%; ~A~%; ~A" rl1 nr)))) (let ((ind0 (new-sound "test.snd" :size 16)) (ind1 (new-sound "fmv.snd" :size 16))) (set! (sample 3 ind0 0) .75) (set! (sample 6 ind1 0) -.5) (let ((data0 (cross-correlate-1 ind0 0 ind1 0)) (data1 (cross-correlate-2 ind0 0 ind1 0))) (if (not (vequal data0 data1)) (snd-display #__line__ ";cross-correlate: ~A ~A" data0 data1))) (set! (sample 3 ind0 0) 0.0) (set! (sample 8 ind0 0) 1.0) (let ((data0 (cross-correlate-1 ind0 0 ind1 0)) (data1 (cross-correlate-2 ind0 0 ind1 0))) (if (not (vequal data0 data1)) (snd-display #__line__ ";cross-correlate 1: ~A ~A" data0 data1))) (close-sound ind0) (close-sound ind1)) (let ((v1 (make-float-vector 16)) (v2 (make-float-vector 16)) (v3 (make-float-vector 16)) (v4 (make-float-vector 16))) (set! (v1 0) 1.0) (set! (v2 3) 1.0) (set! (v3 0) 1.0) (set! (v4 3) 1.0) (set! v1 (cross-correlate-3 v1 v2 16)) (set! v3 (correlate v3 v4)) (if (not (vequal v1 v3)) (snd-display #__line__ ";correlate 16:~%; ~A~%; ~A" v1 v3))) (let ((v1 (make-float-vector 128)) (v2 (make-float-vector 128)) (v3 (make-float-vector 128)) (v4 (make-float-vector 128))) (set! (v1 0) 1.0) (set! (v2 32) 1.0) (set! (v3 0) 1.0) (set! (v4 32) 1.0) (set! v1 (cross-correlate-3 v1 v2 128)) (set! v3 (correlate v3 v4)) (if (not (vequal v1 v3)) (snd-display #__line__ ";correlate 128:~%; ~A~%; ~A" v1 v3))) (let ((v1 (make-float-vector 128)) (v2 (make-float-vector 128)) (v3 #f) (v4 #f)) (do ((i 0 (+ i 1))) ((= i 128)) (float-vector-set! v1 i (mus-random 5.0)) (float-vector-set! v2 i (mus-random 0.5))) (set! v3 (copy v1)) (set! v4 (copy v2)) (set! v1 (cross-correlate-3 v1 v2 128)) (set! v3 (correlate v3 v4)) (if (not (vequal v1 v3)) (snd-display #__line__ ";correlate 128 at random:~%; ~A~%; ~A" v1 v3))) (let ((v1 (make-float-vector 16)) (v2 (make-float-vector 16))) (set! (v1 3) 1.0) (set! (v2 3) 1.0) (set! v1 (correlate v1 (copy v1))) (set! v2 (autocorrelate v2)) (if (not (vequal v1 v2)) (snd-display #__line__ ";auto/correlate 16:~%; ~A~%; ~A" v1 v2))) (for-each (lambda (len) (let ((rl (make-float-vector len)) (rla (make-float-vector len)) (xim (make-float-vector len)) (xrl (make-float-vector len)) (len2 (/ len 2))) (set! (rl 0) 1.0) (set! (rl 4) 1.0) (snd-transform autocorrelation rl 0) ; this is exactly the same as (autocorrelate rl) (if (fneq (rl 0) 2.0) (snd-display #__line__ ";autocorrelation ~A 0: ~A" len (rl 0))) (if (fneq (rl 4) 1.0) (snd-display #__line__ ";autocorrelation ~A 4: ~A" len (rl 4))) (set! (rla 0) 1.0) (set! (rla 4) 1.0) (autocorrelate rla) (if (fneq (rla 0) 2.0) (snd-display #__line__ ";autocorrelate ~A 0: ~A" len (rla 0))) (if (fneq (rla 4) 1.0) (snd-display #__line__ ";autocorrelate ~A 4: ~A" len (rla 4))) (set! (xrl 0) 1.0) (set! (xrl 4) 1.0) (mus-fft xrl xim len 1) (do ((i 0 (+ i 1))) ((= i len)) (set! (xrl i) (+ (* (xrl i) (xrl i)) (* (xim i) (xim i))))) (float-vector-scale! xim 0.0) (mus-fft xrl xim len -1) (float-vector-scale! xrl (/ 1.0 len)) (let ((happy #t)) (do ((i 0 (+ i 1))) ((or (not happy) (= i len2))) (if (fneq (rl i) (xrl i)) (begin (snd-display #__line__ ";mus-fft? ~A at ~A: ~A ~A" len i (rl i) (xrl i)) (set! happy #f))))) (set! (rl 0) 0.0) (set! (rl 4) 0.0) (fill! rl 0.0 (/ len 2) len) (if (> (float-vector-peak rl) .001) (snd-display #__line__ ";autocorrelate peak: ~A" (float-vector-peak rl))))) (list 16 64 256 512)) (for-each (lambda (len) (let* ((rl (make-float-vector len)) (xim (make-float-vector len)) (xrl (make-float-vector len)) (len2 (/ len 2)) (ones (max 2 (random len2)))) (do ((i 0 (+ i 1))) ((= i ones)) (let ((val (random 1.0)) (ind (random len))) (set! (rl ind) val) (set! (xrl ind) val))) (snd-transform autocorrelation rl 0) (mus-fft xrl xim len 1) (set! (xrl 0) (* (xrl 0) (xrl 0))) (set! (xrl len2) (* (xrl len2) (xrl len2))) (do ((i 1 (+ i 1)) (j (- len 1) (- j 1))) ((= i len2)) (set! (xrl i) (+ (* (xrl i) (xrl i)) (* (xim j) (xim j)))) (set! (xrl j) (xrl i))) (float-vector-scale! xim 0.0) (mus-fft xrl xim len -1) (float-vector-scale! xrl (/ 1.0 len)) (let ((happy #t)) (do ((i 0 (+ i 1))) ((or (not happy) (= i len2))) (if (fneq (rl i) (xrl i)) (begin (snd-display #__line__ ";random ~A at ~A: ~A ~A" len i (rl i) (xrl i)) (set! happy #f))))))) (list 16 64 256 512)) ;; -------- cepstrum ;; these values from Octave real(ifft(log(abs(fft(x))))) (let ((rl (make-float-vector 16)) (lst '( 0.423618 0.259318 -0.048365 1.140571 -0.811856 -0.994098 -0.998613 -2.453642 -0.438549 -1.520463 -0.312065 -0.724707 1.154010 1.466936 0.110463 -1.520854))) (do ((i 0 (+ i 1))) ((= i 16)) (set! (rl i) (lst i))) (let ((nrl (float-vector-scale! (snd-transform cepstrum rl 0) 1.399))) (if (not (vequal nrl (float-vector 1.3994950 0.1416877 0.0952407 0.0052814 -0.0613192 0.0082986 -0.0233993 -0.0476585 0.0259498 -0.0476585 -0.0233993 0.0082986 -0.0613192 0.0052814 0.0952407 0.1416877))) (snd-display #__line__ ";cepstrum 16: ~A" nrl)))) (let ((rl (make-float-vector 16))) (do ((i 0 (+ i 1))) ((= i 16)) (set! (rl i) i)) (let ((nrl (float-vector-scale! (snd-transform cepstrum rl 0) 2.72))) (if (not (vequal nrl (float-vector 2.720 0.452 0.203 0.122 0.082 0.061 0.048 0.041 0.039 0.041 0.048 0.061 0.082 0.122 0.203 0.452))) (snd-display #__line__ ";cepstrum 16 by ones: ~A" nrl)))) (for-each (lambda (len) (let ((rl (make-float-vector len)) (xim (make-float-vector len)) (xrl (make-float-vector len))) (set! (rl 0) 1.0) (set! (rl 4) 1.0) (snd-transform cepstrum rl 0) (set! (xrl 0) 1.0) (set! (xrl 4) 1.0) (mus-fft xrl xim len 1) (do ((i 0 (+ i 1))) ((= i len)) (let ((val (+ (* (xrl i) (xrl i)) (* (xim i) (xim i))))) (if (> val .0000001) (set! val (log (sqrt val))) (set! val -10.0)) (set! (xrl i) val))) (float-vector-scale! xim 0.0) (mus-fft xrl xim len -1) (let ((fscl (float-vector-peak xrl))) (float-vector-scale! xrl (/ 1.0 fscl))) (if (not (vequal rl xrl)) (snd-display #__line__ ";mus-fft?? ~A: ~A ~A" len rl xrl)))) (list 16 64 256 512)) ;; -------- walsh (set! d0 (make-float-vector 8)) (set! (d0 0) 1.0) (snd-transform walsh-transform d0) (if (not (vequal d0 (float-vector 1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000))) (snd-display #__line__ ";walsh 1: ~A" d0)) (snd-transform walsh-transform d0) (if (not (vequal d0 (float-vector 8.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";walsh -1: ~A" d0)) (set! d0 (make-float-vector 8)) (set! (d0 1) 1.0) (snd-transform walsh-transform d0) (if (not (vequal d0 (float-vector 1.000 -1.000 1.000 -1.000 1.000 -1.000 1.000 -1.000))) (snd-display #__line__ ";walsh 2: ~A" d0)) (snd-transform walsh-transform d0) (if (not (vequal d0 (float-vector 0.000 8.000 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";walsh -2: ~A" d0)) (set! d0 (make-float-vector 8)) (set! (d0 1) 1.0) (set! (d0 0) 0.5) (snd-transform walsh-transform d0) (if (not (vequal d0 (float-vector 1.500 -0.500 1.500 -0.500 1.500 -0.500 1.500 -0.500))) (snd-display #__line__ ";walsh 3: ~A" d0)) (snd-transform walsh-transform d0) (if (not (vequal d0 (float-vector 4.000 8.000 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";walsh -3: ~A" d0)) (set! d0 (make-float-vector 8)) (fill-float-vector d0 (random 1.0)) (set! d1 (copy d0)) (snd-transform walsh-transform d0) (snd-transform walsh-transform d0) (float-vector-scale! d0 (/ 1.0 8.0)) (if (not (vequal d0 d1)) (snd-display #__line__ ";walsh 4: ~A ~A" d0 d1)) (set! d0 (float-vector 1 1 1 -1 1 1 1 -1 1 1 1 -1 -1 -1 -1 1)) (set! d1 (snd-transform walsh-transform d0)) (if (not (vequal d1 (float-vector 4.00 4.00 4.00 -4.00 4.00 4.00 4.00 -4.00 4.00 4.00 4.00 -4.00 -4.00 -4.00 -4.00 4.00))) (snd-display #__line__ ";walsh 5: ~A" d1)) (set! d0 (float-vector 1 0 0 -1 0 0 0 0 0 0 0 0 0 0 0 0)) (set! d1 (snd-transform walsh-transform d0)) (if (not (vequal d1 (float-vector 0.000 2.000 2.000 0.000 0.000 2.000 2.000 0.000 0.000 2.000 2.000 0.000 0.000 2.000 2.000 0.000))) (snd-display #__line__ ";walsh 6: ~A" d1)) (set! d0 (float-vector 0.174 -0.880 -0.555 -0.879 0.038 0.696 -0.612 0.006 -0.613 0.334 -0.111 -0.821 0.130 0.030 -0.229 0.170)) (set! d1 (snd-transform walsh-transform d0)) (if (not (vequal d1 (float-vector -3.122 -0.434 2.940 -0.468 -3.580 2.716 -0.178 -1.386 -0.902 0.638 1.196 1.848 -0.956 2.592 -1.046 2.926))) (snd-display #__line__ ";walsh 7: ~A" d1)) ;; -------- haar (set! d0 (make-float-vector 8)) (set! (d0 2) 1.0) (snd-transform haar-transform d0) (if (not (vequal d0 (float-vector 0.354 0.354 -0.500 0.000 0.000 0.707 0.000 0.000))) (snd-display #__line__ ";haar 1: ~A" d0)) (inverse-haar d0) (if (not (vequal d0 (float-vector 0.000 0.000 1.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";inverse haar 1: ~A" d0)) (set! d0 (make-float-vector 8)) (set! (d0 0) 1.0) (snd-transform haar-transform d0) (if (not (vequal d0 (float-vector 0.354 0.354 0.500 0.000 0.707 0.000 0.000 0.000))) (snd-display #__line__ ";haar 2: ~A" d0)) (inverse-haar d0) (if (not (vequal d0 (float-vector 1.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";inverse haar 2: ~A" d0)) (set! d0 (snd-transform haar-transform (float-vector -0.483 0.174 -0.880 -0.555 -0.879 0.038 0.696 -0.612))) (if (not (vequal d0 (float-vector -0.884 -0.349 0.563 -0.462 -0.465 -0.230 -0.648 0.925))) (snd-display #__line__ ";haar 3: ~A" d0)) ;; from "A Primer on Wavelets" (let ((sq2 (sqrt 2.0))) (set! d0 (snd-transform haar-transform (float-vector 4 6 10 12 8 6 5 5))) (if (not (vequal d0 (float-vector (* 14 sq2) (* 2 sq2) -6 2 (- sq2) (- sq2) sq2 0))) (snd-display #__line__ ";haar 4: ~A" d0)) (set! d0 (snd-transform haar-transform (float-vector 2 4 6 8 10 12 14 16))) (if (not (vequal d0 (float-vector (* 18 sq2) (* -8 sq2) -4 -4 (- sq2) (- sq2) (- sq2) (- sq2)))) (snd-display #__line__ ";haar 5: ~A" d0))) (set! d0 (make-float-vector 8)) (set! d1 (make-float-vector 8)) (do ((i 0 (+ i 1))) ((= i 8)) (float-vector-set! d0 i (random 1.0))) (copy d0 d1) (snd-transform haar-transform d0) (inverse-haar d0) (if (not (vequal d0 d1)) (snd-display #__line__ ";inverse haar 6: ~A ~A" d0 d1)) ;; --------- wavelet ;; test against fxt output (set! d0 (snd-transform wavelet-transform (float-vector 1 1 0 0 0 0 0 0) 0)) ;"daub4" (if (not (vequal d0 (float-vector 0.625 0.375 -0.217 1.083 -0.354 0.000 0.000 0.354))) (snd-display #__line__ ";fxt wavelet 1: ~A" d0)) (for-each (lambda (size) (do ((i 0 (+ i 1))) ((= i 20)) (let ((d1 (make-float-vector size)) (d2 (make-float-vector size))) (set! (d1 2) 1.0) (set! (d2 2) 1.0) (wavelet d1 size 0 pwt (wts i)) (snd-transform wavelet-transform d2 i) (if (not (vequal d1 d2)) (snd-display #__line__ ";wavelet ~D: ~A ~A" i d1 d2)) (wavelet d2 size -1 pwt (wts i)) (fill! d1 0.0) (set! (d1 2) 1.0) (if (not (vequal d1 d2)) (if (or (= i 9) (= i 10)) (begin (set! (d2 2) 0.0) (if (> (float-vector-peak d2) .1) (snd-display #__line__ ";inverse wavelet ~D: ~A ~A" i d1 d2))) (if (> i 14) (let ((pk (d2 2))) (set! (d2 2) 0.0) (if (> (float-vector-peak d2) pk) (snd-display #__line__ ";inverse wavelet ~D: ~A ~A" i d1 d2))) (snd-display #__line__ ";inverse wavelet ~D: ~A ~A" i d1 d2)))))) (do ((i 0 (+ i 1))) ((= i 9)) (let ((d1 #f) (d2 (make-float-vector size))) (fill-float-vector d2 (random 1.0)) (set! d1 (copy d2)) (snd-transform wavelet-transform d2 i) (wavelet d2 size -1 pwt (wts i)) (if (not (vequal d1 d2)) (snd-display #__line__ ";random wavelet ~D: ~A ~A" i d1 d2))))) (list 16 64)) (set! *max-transform-peaks* 100) (let ((ind (open-sound "oboe.snd")) (ftype (add-transform "low-pass" "filtered" 0.0 1.0 (lambda (len fd) (let ((flt (make-fir-filter :order 8 :xcoeffs (let ((v1 (make-float-vector 8))) (fill! v1 .0125) v1))) (v (make-float-vector len))) (fill-float-vector v (fir-filter flt (read-sample fd)))))))) (if (not (transform? ftype)) (snd-display #__line__ ";transform added: ~A?" ftype)) (set! *transform-normalization* dont-normalize) (set! (transform-type ind 0) ftype) (set! (transform-size ind 0) 16) (set! (transform-graph-type ind 0) graph-once) (set! (transform-graph? ind 0) #t) (set! (cursor ind 0) 12000) (if (file-exists? "s61.scm") (delete-file "s61.scm")) (save-state "s61.scm") (delete-file "s61.scm") ; added transform needs to be saved somehow? (close-sound ind)) (let ((ind (open-sound "oboe.snd")) (ftype (add-transform "abs-it" "absit" 0.0 1.0 (lambda (len fd) (let ((v (make-float-vector len))) (fill-float-vector v (read-sample fd))))))) (set! *transform-normalization* dont-normalize) (set! (transform-type ind 0) ftype) (set! (transform-size ind 0) 256) (set! (transform-graph-type ind 0) graph-once) (set! (transform-graph? ind 0) #t) (set! (cursor ind 0) 12000) (let ((samps (transform->float-vector ind 0)) (orig (channel->float-vector (left-sample ind 0) 256)) (happy #t)) (do ((i 0 (+ i 1))) ((or (not happy) (= i 256))) (if (fneq (samps i) (orig i)) (begin (snd-display #__line__ ";add-transform same (~A): ~D ~A ~A" ftype i (samps i) (orig i)) (set! happy #f))))) (set! (dot-size ind 0) 60) (set! (graph-style ind 0) graph-lollipops) (set! (x-bounds) (list 2.579 2.580)) (update-time-graph) (delete-transform ftype) (if (transform? ftype) (snd-display #__line__ ";transform deleted: ~A" ftype)) (if (transform? -1) (snd-display #__line__ ";transform? -1")) (if (transform? (integer->transform 123)) (snd-display #__line__ ";transform? 123")) (if (not (equal? (transform-type ind 0) fourier-transform)) (snd-display #__line__ ";after delete-transform ~A -> ~A" ftype (transform-type ind 0))) (close-sound ind)) (if (defined? 'bignum-fft) (let () (define* (vectors-equal? v1 v2 (error 1e-30)) (let ((len (length v1))) (and (= (length v2) len) (let ((happy #t)) (do ((i 0 (+ i 1))) ((or (= i len) (not happy)) happy) (set! happy (< (magnitude (- (vector-ref v1 i) (vector-ref v2 i))) error))))))) (define* (bignum-vector :rest args) (let* ((len (length args)) (v (make-vector len))) (do ((i 0 (+ i 1)) (arg args (cdr arg))) ((= i len) v) (if (bignum? (car arg)) (vector-set! v i (car arg)) (vector-set! v i (bignum (number->string (car arg)))))))) ;; -------- -1 -1 at 1 (let ((rl (make-vector 8)) (im (make-vector 8))) (do ((i 0 (+ i 1))) ((= i 8)) (set! (rl i) (bignum "0.0")) (set! (im i) (bignum "0.0"))) (set! (rl 1) (bignum "-1.0")) (set! (im 1) (bignum "-1.0")) (bignum-fft rl im 8) ; third arg is size (let ((crl (bignum-vector -1.000 0.000 1.000 (sqrt (bignum "2")) 1.000 0.000 -1.000 (- (sqrt (bignum "2"))))) (cim (bignum-vector -1.000 (- (sqrt (bignum "2"))) -1.000 0.000 1.000 (sqrt (bignum "2")) 1.000 0.000))) (if (or (not (vectors-equal? rl crl)) (not (vectors-equal? im cim))) (snd-display #__line__ ";big-fft -1 -1 at 1:~%rl: ~A~% ~A~%im: ~A~% ~A~%" rl crl im cim))) (bignum-fft rl im 8 -1) (let ((crl (bignum-vector 0.0 -8.0 0.0 0.0 0.0 0.0 0.0 0.0)) (cim (bignum-vector 0.0 -8.0 0.0 0.0 0.0 0.0 0.0 0.0))) (if (or (not (vectors-equal? rl crl)) (not (vectors-equal? im cim))) (snd-display #__line__ ";big-fft -1 -1 at 1 inverse:~%rl: ~A~% ~A~%im: ~A~% ~A~%" rl crl im cim)) (set! (rl 1) (bignum "-1.0")) (set! (im 1) (bignum "-1.0")) (do ((i 0 (+ i 1))) ((= i 4)) (bignum-fft rl im 8)) (set! (crl 1) (bignum "-64.0")) (set! (cim 1) (bignum "-64.0")) (if (or (not (vectors-equal? rl crl)) (not (vectors-equal? im cim))) (snd-display #__line__ ";big-fft -1 -1 at 1 rotate:~%rl: ~A~% ~A~%im: ~A~% ~A~%" rl crl im cim)))) ;; -------- -1 1 at 3 (let ((rl (make-vector 8)) (im (make-vector 8))) (do ((i 0 (+ i 1))) ((= i 8)) (set! (rl i) (bignum "0.0")) (set! (im i) (bignum "0.0"))) (set! (rl 3) (bignum "-1.0")) (set! (im 3) (bignum "1.0")) (bignum-fft rl im 8) (let ((crl (bignum-vector -1.000 0.000 1.000 (- (sqrt (bignum "2"))) 1.000 0.000 -1.000 (sqrt (bignum "2")))) (cim (bignum-vector 1.000 (- (sqrt (bignum "2"))) 1.000 0.000 -1.000 (sqrt (bignum "2")) -1.000 0.000))) (if (or (not (vectors-equal? rl crl)) (not (vectors-equal? im cim))) (snd-display #__line__ ";big-fft -1 1 at 3:~%rl: ~A~% ~A~%im: ~A~% ~A~%" rl crl im cim)))) ;; -------- 1 0 at 0 with bignum arg to make-vector (so it should copy) (let ((rl (make-vector 8 (bignum "0.0"))) (im (make-vector 8 (bignum "0.0")))) (set! (rl 0) (bignum "1.0")) (bignum-fft rl im 8) (let ((crl (bignum-vector 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0)) (cim (bignum-vector 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0))) (if (or (not (vectors-equal? rl crl)) (not (vectors-equal? im cim))) (snd-display #__line__ ";big-fft 1 0 at 0 (and copied fill):~%rl: ~A~% ~A~%im: ~A~% ~A~%" rl crl im cim)))) ;; -------- cos/sin (let ((rl (make-vector 64)) (im (make-vector 64))) (do ((i 0 (+ i 1))) ((= i 64)) (set! (rl i) (bignum "0.0")) (set! (im i) (bignum "0.0"))) (set! (rl 1) (bignum "1.0")) (bignum-fft rl im 64 -1) (let ((happy #t)) (do ((i 0 (+ i 1))) ((or (= i 64) (not happy))) (let ((cerr (magnitude (- (vector-ref rl i) (cos (/ (* 2 pi i) 64))))) (serr (magnitude (- (vector-ref im i) (sin (/ (* -2 pi i) 64)))))) (set! happy (and (< cerr 1e-30) (< serr 1e-30))) (if (not happy) (snd-display #__line__ ";big fft 1 at 0 (sin/cos) differs by ~A in ~A at ~A (~A ~A)~%" (max cerr serr) (if (> cerr serr) "cos" "sin") i (if (> cerr serr) (cos (/ (* 2 pi i) 64)) (sin (/ (* -2 pi i) 64))) (if (> cerr serr) (vector-ref rl i) (vector-ref im i))))))) (bignum-fft rl im 64) (let ((crl (make-vector 64 (bignum "0.0"))) (cim (make-vector 64 (bignum "0.0")))) (set! (crl 1) (bignum "64")) (if (or (not (vectors-equal? rl crl)) (not (vectors-equal? im cim))) (snd-display #__line__ ";big-fft 1 at 0 fill cos/sin inverse:~%rl: ~A~% ~A~%im: ~A~% ~A~%" rl crl im cim)))) ;; -------- random (let ((rl (make-vector 64)) (im (make-vector 64)) (crl (make-vector 64)) (cim (make-vector 64)) (rs (random-state (bignum "12345678")))) (do ((i 0 (+ i 1))) ((= i 64)) (set! (rl i) (random (bignum "1.0") rs)) (set! (crl i) (+ (vector-ref rl i) 0.0)) ; try to force a copy (set! (im i) (random (bignum "1.0") rs)) (set! (cim i) (+ (vector-ref im i) 0.0))) (bignum-fft rl im 64 1) (if (or (vectors-equal? rl crl) (vectors-equal? im cim)) (snd-display #__line__ ";big-fft random not copied?:~%rl: ~A~% ~A~%im: ~A~% ~A~%" rl crl im cim)) (bignum-fft rl im 64 -1) (do ((i 0 (+ i 1))) ((= i 64)) (set! (rl i) (/ (vector-ref rl i) 64.0)) (set! (im i) (/ (vector-ref im i) 64.0))) (if (or (not (vectors-equal? rl crl)) (not (vectors-equal? im cim))) (snd-display #__line__ ";big-fft random:~%rl: ~A~% ~A~%im: ~A~% ~A~%" rl crl im cim))) )) (let ((ind1 (open-sound "oboe.snd"))) (set! (time-graph-style ind1 0) graph-lollipops) (graph->ps "aaa.eps") (set! (transform-graph? ind1 0) #t) (set! (transform-graph-type ind1 0) graph-as-sonogram) (set! *transform-size* 256) (update-transform-graph) (when with-gui (let ((size (transform-framples ind1 0))) (if (or (number? size) (not (= (length size) 3))) (snd-display #__line__ ";transform-framples of sonogram: ~A" size)))) (graph->ps "aaa.eps") (let ((old-colormap *colormap*)) (if (and (defined? 'integer->colormap) (integer? old-colormap)) (set! old-colormap (integer->colormap old-colormap))) (set! *colormap* black-and-white-colormap) (update-transform-graph) (set! (transform-graph-type ind1 0) graph-as-spectrogram) (update-transform-graph) (graph->ps "aaa.eps") (set! *colormap* old-colormap)) (close-sound ind1)) (let ((ind (new-sound "test.snd" :header-type mus-next :sample-type mus-ldouble))) (pad-channel 0 1000) (set! (transform-graph-type ind 0) graph-once) (set! (show-transform-peaks ind 0) #t) (set! (fft-log-magnitude ind 0) #t) (set! (fft-log-frequency ind 0) #f) (set! (transform-graph? ind 0) #t) (set! (x-bounds) (list 0.0 .04)) (update-time-graph) (update-transform-graph) (close-sound ind)) (let* ((ind (open-sound "oboe.snd")) (size 8192) (v (channel->float-vector 1000 size ind 0))) (set! (show-listener) #f) (set! (window-height) 800) (set! (lisp-graph? ind 0) #t) (graph v "biggy" 0.0 1.0 0.0 1.0 ind 0) (set! (transform-graph-type ind 0) graph-once) (set! (show-transform-peaks ind 0) #t) (set! (fft-log-magnitude ind 0) #t) (set! (fft-log-frequency ind 0) #f) (set! (transform-graph? ind 0) #t) (graph->ps "aaa.eps") (set! (x-bounds) (list 0.0 1.0)) (set! (max-transform-peaks ind 0) 3) (update-time-graph) (update-transform-graph) (update-lisp-graph) (scale-by 0.0) (update-time-graph) (update-transform-graph) (undo) (set! (transform-graph-type ind 0) graph-as-sonogram) (set! (fft-log-magnitude ind 0) #f) (update-transform-graph) (graph->ps "aaa.eps") (set! *with-gl* #f) (set! (spectrum-end ind 0) .2) (set! (transform-graph-type ind 0) graph-as-spectrogram) (update-transform-graph) (update-lisp-graph) (graph->ps "aaa.eps") (set! (show-listener) #t) (close-sound ind)) (let ((v (dolph 16 2.5))) (if (not (vequal v (float-vector 0.097 0.113 0.221 0.366 0.536 0.709 0.860 0.963 1.000 0.963 0.860 0.709 0.536 0.366 0.221 0.113))) (snd-display #__line__ ";dolph 16 2.5 (dsp.scm): ~A" v))) (let ((v (make-float-vector 8)) (v0 (make-float-vector 8))) (do ((i 0 (+ i 1))) ((= i 8)) (set! (v i) (mus-random 1.0)) (set! (v0 i) (float-vector-ref v i))) (set! v (float-vector-scale! (dht (dht v)) (/ 1.0 8.0))) (if (not (vvequal v v0)) (snd-display #__line__ ";dht twice: ~A ~A" v v0)) (fill! v 0.0) (set! (v 1) 1.0) (set! v (dht v)) (if (not (vequal v (float-vector 1.000 1.414 1.000 0.000 -1.000 -1.414 -1.000 0.000))) (snd-display #__line__ ";dht of pulse: ~A" v))) (let* ((ind (open-sound "oboe.snd")) (val1 (car (find-sine 553.0 2000 3000 ind))) (val2 (car (find-sine 620.0 2000 3000 ind)))) (if (or (fneq val1 .03835) (fneq val2 .0012)) (snd-display #__line__ ";find-sine: ~A ~A" val1 val2)) (let ((frq (spot-freq 2000 ind 0))) (if (not (= (round frq) 553)) (snd-display #__line__ ";spot-freq: ~A" frq))) (down-oct 2) (let ((frq (spot-freq 2000 ind 0))) (if (and (not (= (round frq) 276)) (not (= (round frq) 277))) (snd-display #__line__ ";spot-freq down oct: ~A" frq))) (undo) (zero-phase) (if (fneq (sample 0) .1472) (snd-display #__line__ ";zero-phase: ~A" (sample 0))) (undo) (rotate-phase (lambda (x) x)) (undo) (brighten-slightly .5) (undo) (spike) (close-sound ind)) (let* ((ind (open-sound "1a.snd")) (valf (car (find-sine 440.0 0 (framples) ind))) (valg (* 2 (/ (goertzel 440.0 0 (framples) ind) (framples)))) (valf1 (car (find-sine 100.0 0 (framples) ind))) (valg1 (* 2 (/ (goertzel 100.0 0 (framples) ind) (framples)))) (valf2 (car (find-sine 440.0 0 (framples) ind))) (valg2 (* 2 (/ (goertzel 440.0 0 (framples) ind) (framples)))) (valf3 (car (find-sine 437.0 0 (framples) ind))) (valg3 (* 2 (/ (goertzel 437.0 0 (framples) ind) (framples))))) (if (fneq valf valg) (snd-display #__line__ ";goertzel 0: ~A ~A" valf valg)) (if (fneq valf1 valg1) (snd-display #__line__ ";goertzel 1: ~A ~A" valf1 valg1)) (if (fneq valf2 valg2) (snd-display #__line__ ";goertzel 2: ~A ~A" valf2 valg2)) (if (fneq valf3 valg3) (snd-display #__line__ ";goertzel 3: ~A ~A" valf3 valg3)) (close-sound ind)) (let ((v (float-vector-polynomial (float-vector 0.0 2.0) (float-vector 1.0 2.0)))) (if (not (vequal v (float-vector 1.0 5.0))) (snd-display #__line__ ";float-vector-polynomial 0: ~A" v))) (let ((v (float-vector-polynomial (float-vector 0 1 2) (float-vector 0 2 1)))) (if (not (vequal v (float-vector 0.000 3.000 8.000))) (snd-display #__line__ ";float-vector-polynomial 1: ~A" v))) (let ((v (float-vector-polynomial (float-vector 0 1 2) (float-vector 0 2 1 .5)))) (if (not (vequal v (float-vector 0.000 3.500 12.000))) (snd-display #__line__ ";float-vector-polynomial 2: ~A" v))) (let ((v (float-vector-polynomial (float-vector 0 1 2) (float-vector 1)))) (if (not (vequal v (float-vector 1 1 1))) (snd-display #__line__ ";float-vector-polynomial 3: ~A" v))) (let* ((ind (open-sound "pistol.snd")) (mx (maxamp ind 0))) (channel-polynomial (float-vector 0.0 2.0) ind 0) (if (fneq (maxamp) (* mx 2)) (snd-display #__line__ ";channel-polynomial 2: ~A" (maxamp))) (undo) (channel-polynomial (float-vector 0.0 0.5 0.25 0.25) ind 0) (if (fneq (maxamp) .222) (snd-display #__line__ ";channel-polynomial 3: ~A" (maxamp))) (undo) (channel-polynomial (float-vector 0.0 0.0 1.0) ind 0) (let ((pos (scan-channel (lambda (y) (< y 0.0))))) (if pos (snd-display #__line__ ";channel-polynomial squares: ~A" pos))) (undo) (channel-polynomial (float-vector 0.5 1.0) ind 0) (let ((pos (scan-channel (lambda (y) (< y 0.0))))) (if pos (snd-display #__line__ ";channel-polynomial offset: ~A" pos))) (if (fneq (maxamp) .8575) (snd-display #__line__ ";channel-polynomial off mx: ~A" (maxamp))) (undo) (spectral-polynomial (float-vector 0.0 1.0) ind 0) (if (fneq (maxamp) .493) (snd-display #__line__ ";spectral-polynomial 0 mx: ~A" (maxamp))) (if (not (= (framples ind 0) 41623)) (snd-display #__line__ ";spectral-polynomial 0 len: ~A" (framples))) (undo) (spectral-polynomial (float-vector 0.0 0.5 0.5) ind 0) (if (fneq (maxamp) .493) (snd-display #__line__ ";spectral-polynomial 1: ~A" (maxamp))) (if (not (= (framples ind 0) (* 2 41623))) (snd-display #__line__ ";spectral-polynomial 1 len: ~A" (framples))) (undo) (spectral-polynomial (float-vector 0.0 0.0 0.0 1.0) ind 0) (if (fneq (maxamp) .493) (snd-display #__line__ ";spectral-polynomial 2: ~A" (maxamp))) (if (not (= (framples ind 0) (* 3 41623))) (snd-display #__line__ ";spectral-polynomial 1 len: ~A" (framples))) (close-sound ind)) (let ((vals (scentroid "oboe.snd"))) (if (or (fneq (vals 0) 1876.085) (fneq (vals 1) 1447.004)) (snd-display #__line__ ";scentroid: ~A" vals))) (let ((flt (make-fir-filter 3 (float-vector 0.5 0.25 0.125))) (data (make-float-vector 10)) (undata (make-float-vector 10))) (set! (data 0) 1.0) (do ((i 0 (+ i 1))) ((= i 10)) (set! (undata i) (fir-filter flt (data i)))) (let ((fdata (invert-filter (float-vector 0.5 0.25 0.125)))) (set! flt (make-fir-filter (length fdata) fdata)) (do ((i 0 (+ i 1))) ((= i 10)) (set! (undata i) (fir-filter flt (undata i)))) (if (not (vequal undata data)) (snd-display #__line__ ";invert-filter: ~A" undata)))) (let ((coeffs (make-float-vector 6))) (do ((i 0 (+ i 1)) (top .8 (- top .1))) ((= i 6)) (set! (coeffs i) (+ top (random .2)))) (let ((flt (make-fir-filter 6 coeffs)) (data (make-float-vector 20)) (undata (make-float-vector 20))) (set! (data 0) 1.0) (do ((i 0 (+ i 1))) ((= i 20)) (set! (undata i) (fir-filter flt (data i)))) (let ((fdata (invert-filter coeffs))) (set! flt (make-fir-filter (length fdata) fdata)) (do ((i 0 (+ i 1))) ((= i 20)) (set! (undata i) (fir-filter flt (undata i)))) (if (not (vequal undata data)) (snd-display #__line__ ";invert-filter (6): ~A" undata))))) (let ((flt (make-volterra-filter (float-vector 1.0 .4) (float-vector .3 .2 .1))) (data (make-float-vector 10)) (x 0.0)) (do ((i 0 (+ i 1))) ((= i 10)) (set! (data i) (volterra-filter flt x)) (if (= i 0) (set! x 0.5) (set! x 0.0))) (if (not (vequal data (float-vector 0.000 0.575 0.250 0.025 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";volterra-filter: ~A" data))) (let ((flt (make-volterra-filter (float-vector 1.0) (float-vector 1.0))) (data (make-float-vector 10))) (do ((i 0 (+ i 1)) (x 1.0 0.0)) ((= i 10)) (set! (data i) (volterra-filter flt x))) (if (not (vequal data (float-vector 2.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";volterra-filter x + x^2: ~A" data))) (let ((flt (make-volterra-filter (float-vector 1.0) (float-vector 1.0))) (data (make-float-vector 10))) (do ((i 0 (+ i 1)) (x 1.0 (- x 0.1))) ((= i 10)) (set! (data i) (volterra-filter flt x))) (if (not (vequal data (float-vector 2.000 1.710 1.440 1.190 0.960 0.750 0.560 0.390 0.240 0.110))) (snd-display #__line__ ";volterra-filter x + x^2 by -0.1: ~A" data))) (let ((flt (make-volterra-filter (float-vector 1.0 0.5) (float-vector 1.0))) (data (make-float-vector 10))) (do ((i 0 (+ i 1)) (x 1.0 0.0)) ((= i 10)) (set! (data i) (volterra-filter flt x))) (if (not (vequal data (float-vector 2.000 0.500 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";volterra-filter x + .5x(n-1) + x^2: ~A" data))) (let ((flt (make-volterra-filter (float-vector 1.0 0.5) (float-vector 1.0 0.6))) (data (make-float-vector 10))) (do ((i 0 (+ i 1)) (x 0.9 0.0)) ((= i 10)) (set! (data i) (volterra-filter flt x))) (if (not (vequal data (float-vector 1.710 0.936 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";volterra-filter x + .5x(n-1) + x^2 + 0.6: ~A" data))) (let ((ind (new-sound "test.snd" :size 100)) (gen (make-oscil 440.0))) (map-channel (lambda (y) (oscil gen))) (down-oct 2) (if (not (= (framples) 200)) (snd-display #__line__ ";down-oct new len: ~A" (framples))) (let ((r1 (make-sampler 0 ind 0 1 1)) (r2 (make-sampler 0 ind 0 1 2))) (do ((i 0 (+ i 2))) ((= i 200)) (let ((val1 (r1)) (val2 (r2)) (val3 (r2))) (if (and (fneq val1 val2) (fneq val1 val3)) (snd-display #__line__ ";down-oct: ~A ~A ~A ~A" i val1 val2 val3))))) (kalman-filter-channel) ; just make sure it runs (close-sound ind)) (let ((d0 (make-float-vector 8)) (d1 (make-float-vector 8))) (set! (d0 2) 1.0) (let ((vals (fractional-fourier-transform d0 d1 8 1.0))) (if (or (not (vequal (car vals) (float-vector 1.000 0.000 -1.000 -0.000 1.000 0.000 -1.000 -0.000))) (not (vequal (cadr vals) (float-vector 0.000 1.000 0.000 -1.000 0.000 1.000 0.000 -1.000)))) (snd-display #__line__ ";fractional-fft: ~A?" vals)))) (let ((d0 (make-float-vector 8)) (d1 (make-float-vector 8))) (let ((val (z-transform (vector 0 0 1.0 0 0 0 0 0) 8 (exp (complex 0.0 (* .25 pi)))))) (do ((i 0 (+ i 1))) ((= i 8)) (set! (d0 i) (real-part (vector-ref val i))) (set! (d1 i) (imag-part (vector-ref val i)))) (if (or (not (vequal d0 (float-vector 1.000 0.000 -1.000 -0.000 1.000 0.000 -1.000 -0.000))) (not (vequal d1 (float-vector 0.000 1.000 0.000 -1.000 0.000 1.000 0.000 -1.000)))) (snd-display #__line__ ";z-transform: ~A ~A?" d0 d1)))) (let ((v1 (make-float-vector 16))) (set! (v1 0) 1.0) (let ((res (z-transform v1 16 0.5))) (if (not (vequal res (make-float-vector 16 1.0))) (snd-display #__line__ ";z 0.5 0=1: ~A" res))) (let ((res (z-transform v1 16 -1.0))) (if (not (vequal res (make-float-vector 16 1.0))) (snd-display #__line__ ";z -1.0 0=1: ~A" res))) (set! (v1 0) 0.0) (set! (v1 1) 1.0) (let ((res (z-transform v1 16 0.5))) (if (not (vequal res (float-vector 1.000 0.500 0.250 0.125 0.062 0.031 0.016 0.008 0.004 0.002 0.001 0.0 0.0 0.0 0.0 0.0))) (snd-display #__line__ ";z 0.5 1=1: ~A" res))) (let ((res (z-transform v1 16 2.0))) (if (not (vequal res (float-vector 1.0 2.0 4.0 8.0 16.0 32.0 64.0 128.0 256.0 512.0 1024.0 2048.0 4096.0 8192.0 16384.0 32768.0))) (snd-display #__line__ ";z 2.0 1=1: ~A" res))) (set! (v1 2) 1.0) (let ((res (z-transform v1 16 0.5))) (if (not (vequal res (float-vector 2.0 0.75 0.3125 0.140 0.0664 0.0322 0.0158 0.00787 0.0039 0.0019 0 0 0 0 0 0))) (snd-display #__line__ ";z 0.5 1=1 2=1: ~A" res))) (let ((res (z-transform v1 16 2.0))) (if (not (vequal res (float-vector 2.0 6.0 20.0 72.0 272.0 1056.0 4160.0 16512.0 65792.0 262656.0 1049600.0 4196352.0 16781312.0 67117056.0 268451840.0 1073774592.0))) (snd-display #__line__ ";z 2.0 1=1 2=1: ~A" res))) (do ((i 0 (+ i 1)) (j 1.0 (* j 0.4))) ((= i 16)) (float-vector-set! v1 i j)) (let ((res (z-transform v1 16 1.0))) (if (not (vequal res (make-float-vector 16 (/ 1.0 (- 1.0 0.4))))) ; this is confusing (snd-display #__line__ ";z 1 0.4g: ~A" res)))) (let ((ind (open-sound "oboe.snd"))) (automorph 0.0+1.0i 0 0 1) (automorph 0.0+1.0i 0 0 1) (automorph 0.0+1.0i 0 0 1) (automorph 0.0+1.0i 0 0 1) (let ((mxdiff (float-vector-peak (float-vector-subtract! (channel->float-vector 0 #f ind 0 0) (channel->float-vector 0 #f ind 0) )))) (if (> mxdiff .003) (snd-display #__line__ ";automorph rotation: ~A" mxdiff))) (revert-sound ind) (periodogram 256) (if (not (lisp-graph? ind)) (snd-display #__line__ ";periodogram not graphed?")) (close-sound ind)) )) (do ((i 0 (+ i 1))) ((= i 10)) (let* ((len (expt 2 (+ 2 (random 8)))) (v0 (make-float-vector len)) (v1 (make-float-vector len)) (v2 (make-vector len))) (do ((k 0 (+ k 1))) ((= k len)) (float-vector-set! v0 k (mus-random 0.5)) (float-vector-set! v1 k (mus-random 0.5)) (vector-set! v2 k (complex (v0 k) (v1 k)))) (let ((sum 0.0) (mx 0.0)) (mus-fft v0 v1 len 1) (cfft! v2 len 1) (do ((m 0 (+ m 1))) ((= m len)) (let ((diffr (abs (- (v0 m) (real-part (v2 m))))) (diffi (abs (- (v1 m) (imag-part (v2 m)))))) (set! sum (+ sum diffr diffi)) (if (> (max diffr diffi) mx) (set! mx (max diffr diffi))))) (if (or (> mx 1e-6) (> sum 1e-6)) (snd-display #__line__ ";cfft! ~A: ~A ~A~%" len mx sum))))) (let ((val (cfft! (cfft! (cfft! (cfft! (vector 0.0 1+i 0.0 0.0))))))) (if (or (> (magnitude (val 0)) 1e-12) (> (magnitude (val 2)) 1e-12) (> (magnitude (val 3)) 1e-12) (fneq 16.0 (real-part (val 1))) (fneq 16.0 (imag-part (val 1)))) (snd-display #__line__ ";cfft! 4x: ~A" val))) (do ((i 0 (+ i 1))) ((= i 10)) (let* ((len (expt 2 (+ 2 (random 8)))) (v0 (make-float-vector len)) (v1 (make-float-vector len)) (v2 (make-float-vector len)) (v3 (make-float-vector len))) (do ((k 0 (+ k 1))) ((= k len)) (float-vector-set! v0 k (mus-random 0.5)) (float-vector-set! v1 k (mus-random 0.5)) (set! (v2 k) (v0 k)) (set! (v3 k) (v1 k))) (let () (mus-fft v0 v1 len 1) (fft! v2 v3 len 1) (let ((sum 0.0) (mx 0.0)) (do ((m 0 (+ m 1))) ((= m len)) (let ((diffr (abs (- (v0 m) (v2 m)))) (diffi (abs (- (v1 m) (v3 m))))) (set! sum (+ sum diffr diffi)) (if (> (max diffr diffi) mx) (set! mx (max diffr diffi))))) (if (or (> mx 1e-6) (> sum 1e-6)) (snd-display #__line__ ";fft! ~A: ~A ~A~%" len mx sum)))))) )) ;;; ---------------- test 20: new stuff ---------------- (if (not (defined? 'load-font)) (define (load-font name) #f)) (require snd-clean.scm snd-snddiff.scm) (define (snd_test_20) (define* (add-comment sample comment snd1 chn1) (let* ((snd (or snd1 (selected-sound))) (chn (or chn1 (selected-channel))) (old-comments (or (channel-property 'comments snd chn) ()))) (set! (channel-property 'comments snd chn) (cons (list sample comment) old-comments)))) (define (show-comments snd chn) (let ((comments (or (channel-property 'comments snd chn) ()))) (for-each (lambda (comment) (let* ((samp (car comment)) (text (cadr comment)) (text-width (* 6 (length text))) (ls (left-sample snd chn)) (rs (right-sample snd chn))) (if (< ls samp rs) (let ((xpos (x->position (/ samp (srate)))) (ypos (y->position (sample samp)))) (catch #t (lambda () (let ((cr (make-cairo (car (channel-widgets snd chn))))) (draw-line xpos 20 xpos (- ypos 4) snd chn time-graph cr) (draw-string text (- xpos (/ text-width 2)) 18 snd chn time-graph cr) (free-cairo cr))) (lambda args (snd-display #__line__ ";draw error: ~A" args))))))) comments))) (define display-samps-in-red (let ((documentation "display samples 1000 to 2000 in red whenever they're in the current view")) (lambda (snd chn) (catch #t (lambda () (let ((left (left-sample snd chn)) (right (right-sample snd chn)) (old-color (foreground-color snd chn)) (red (make-color-with-catch 1 0 0))) (if (and (< left 2000) (> right 1000)) (let ((data (make-graph-data snd chn))) (if data (if (float-vector? data) ;the simple, one-sided graph case (let* ((samps (- (min right 2000) (max left 1000))) (offset (max 0 (- 1000 left))) (new-data (float-vector-subseq data offset (+ offset samps))) (cr (make-cairo (car (channel-widgets snd chn))))) (set! (foreground-color snd chn) red) (graph-data new-data snd chn copy-context (max 1000 left) (min 2000 right) graph-lines cr) (free-cairo cr) (set! (foreground-color snd chn) old-color)) (let* ((low-data (car data)) ;the two-sided envelope graph case (high-data (cadr data)) ;; we need to place the red portion correctly in the current graph ;; so the following is getting the "bin" numbers associated with ;; samples 1000 and 2000 (size (length low-data)) (samps (- right left)) (left-offset (max 0 (- 1000 left))) (left-bin (round (/ (* size left-offset) samps))) (right-offset (- (min 2000 right) left)) (right-bin (round (/ (* size right-offset) samps))) (new-low-data (float-vector-subseq low-data left-bin right-bin)) (new-high-data (float-vector-subseq high-data left-bin right-bin)) (cr (make-cairo (car (channel-widgets snd chn))))) (set! (foreground-color snd chn) red) (graph-data (list new-low-data new-high-data) snd chn copy-context left-bin right-bin graph-lines cr) (free-cairo cr) (set! (foreground-color snd chn) old-color)))))))) (lambda args (snd-display #__line__ ";draw error: ~A" args)))))) (define* (show-greeting (snd 0) (chn 0)) (let ((ls (left-sample snd chn)) (rs (right-sample snd chn))) (if (< ls 1000 rs) (let ((pos (x->position (/ 1000.0 (srate)))) (old-color (foreground-color)) (cr (make-cairo (car (channel-widgets snd chn))))) (set! (foreground-color) (make-color .75 .75 .75)) (fill-rectangle pos 10 50 20 snd chn time-graph #f cr) (set! (foreground-color) (make-color 1 0 0)) (draw-string "hi!" (+ pos 5) 12 snd chn time-graph cr) (set! (foreground-color) old-color) (free-cairo cr))))) (do ((test-ctr 0 (+ 1 test-ctr))) ((= test-ctr tests)) (log-mem test-ctr) (if (not (sound-file? "oboe.snd")) (snd-display #__line__ ";oboe.snd not a sound file?")) (if (not (sound-file? "4.aiff")) (snd-display #__line__ ";4.aiff not a sound file?")) (if (sound-file? "snd.h") (snd-display #__line__ ";snd.h is a sound-file?")) (let ((ind1 (open-sound "oboe.snd"))) (save-sound-as "test.snd" ind1) (let ((ind2 (open-sound "test.snd"))) (if (not (channels-equal? ind1 0 ind2 0)) (snd-display #__line__ ";channels-equal? of copy")) (if (not (channels=? ind1 0 ind2 0)) (snd-display #__line__ ";channels=? of copy")) (pad-channel (framples ind2 0) 100) (if (channels-equal? ind1 0 ind2 0) (snd-display #__line__ ";channels-equal? of pad")) (if (not (channels=? ind1 0 ind2 0)) (snd-display #__line__ ";channels=? of pad")) (set! (sample 50900 ind2 0) .1) (if (channels-equal? ind1 0 ind2 0) (snd-display #__line__ ";channels-equal? of pad+set")) (if (channels=? ind1 0 ind2 0) (snd-display #__line__ ";channels=? of pad+set 0 err")) (if (not (channels=? ind1 0 ind2 0 .2)) (snd-display #__line__ ";channels=? of pad+set .2 err")) (if with-gui (begin (add-comment 1234 "sample 1234" ind1 0) (let ((comments (show-comments ind1 0))) (update-time-graph) (if (null? comments) (snd-display #__line__ ";add-comment failed?"))) (display-samps-in-red ind1 0) (update-time-graph) (catch #t (lambda () (show-greeting ind1 0)) (lambda args args)) (update-time-graph) (color-samples *highlight-color* 0 100 ind1 0) (update-time-graph) (power-env-channel (make-power-env '(0 0 .325 1 1 32.0 2 0 32.0) :duration 2.0)) (update-time-graph) (revert-sound ind1) (make-selection 10000 20000 ind1 0) (if (not (selection?)) (snd-display #__line__ ";make-selection for show failed?") (begin (show-selection) (let ((vals (x-bounds ind1 0))) (if (and (pair? vals) (or (fneq (car vals) (/ 10000.0 (srate ind1))) (fneq (cadr vals) (/ 20000.0 (srate ind1))))) (snd-display #__line__ ";show-selection: ~A (~A)" vals (list (/ 10000.0 (srate ind1)) (/ 20000.0 (srate ind1)))))))) (hook-push graph-hook zoom-spectrum) (set! (transform-graph? ind1 0) #t) (let ((ind3 (open-sound "pistol.snd"))) (overlay-sounds ind2 ind1 ind3) (update-time-graph ind2 0) (set! (hook-functions after-graph-hook) ()) (close-sound ind3)) (samples-via-colormap ind1 0))) (close-sound ind1) (hook-remove graph-hook zoom-spectrum) (close-sound ind2))) (let ((ns (open-sound "1.snd"))) (set! (sync ns) 0) (set! (selection-member? ns 0) #t) (set! (selection-position ns 0) 1000) (set! (selection-framples ns 0) 3000) (show-selection) (if (not (equal? (list (left-sample ns 0) (right-sample ns 0)) '(1000 3999))) (snd-display #__line__ ";show-selection 1.snd: ~A ~A" (left-sample ns 0) (right-sample ns 0))) (unselect-all) (let ((ns1 (open-sound "1234.snd"))) (set! (sync ns1) 0) (set! (selection-member? ns 0) #t) (set! (selection-position ns 0) 10000) (set! (selection-framples ns 0) 30000) (set! (selection-member? ns1 0) #t) (set! (selection-position ns1 0) 10000) (set! (selection-framples ns1 0) 30000) (set! (selection-member? ns1 1) #t) (set! (selection-position ns1 1) 10000) (set! (selection-framples ns1 1) 30000) (show-selection) (if (or (not (eqv? (left-sample ns 0) 10000)) (not (member (right-sample ns 0) '(39999 39998))) (not (eqv? (left-sample ns1 0) 10000)) (not (member (right-sample ns1 0) '(39999 39998))) (not (eqv? (left-sample ns1 1) 10000)) (not (member (right-sample ns1 1) '(39999 39998)))) (snd-display #__line__ ";show-selection 1234.snd: ~A" (list (left-sample ns 0) (right-sample ns 0) (left-sample ns1 0) (right-sample ns1 0) (left-sample ns1 1) (right-sample ns1 1)))) (close-sound ns1) (close-sound ns))) (let ((pe (make-power-env '(0 0 32.0 1 1 32.0 2 0 0.0) :duration .1))) (if (not (penv? pe)) (snd-display #__line__ ";penv? ~A" pe)) (let ((x (power-env pe))) (if (fneq x 0.0) (snd-display #__line__ ";power-env start: ~A" x))) (if (> (abs (- (pe 'current-pass) 2203)) 2) (snd-display #__line__ ";power-env pass: ~A" (pe 'current-pass))) ; 4410/2 - 1 because x1=2 (if (not (= (pe 'current-env) 0)) (snd-display #__line__ ";power-env seg: ~A" (pe 'current-env))) ) (let ((old-srate *clm-srate*)) (set! *print-length* (max *print-length* 48)) (set! *clm-srate* 22050) (let ((ind (new-sound :size 33 :srate 22050))) (map-channel (lambda (y) 1.0)) (let ((pe (make-power-env '(0 0 32.0 1 1 0.0312 2 0 1) :duration (/ 34.0 22050.0)))) (map-channel (lambda (y) (* y (power-env pe)))) (if (and (not (vequal1 (channel->float-vector) (float-vector 0.000 0.008 0.017 0.030 0.044 0.063 0.086 0.115 0.150 0.194 0.249 0.317 0.402 0.507 0.637 0.799 1.000 0.992 0.983 0.971 0.956 0.937 0.914 0.885 0.850 0.806 0.751 0.683 0.598 0.493 0.363 0.201 0.000))) (not (vequal1 (channel->float-vector) (float-vector 0.000 0.008 0.019 0.032 0.049 0.070 0.097 0.130 0.173 0.226 0.293 0.377 0.484 0.618 0.787 1.000 0.992 0.981 0.968 0.951 0.930 0.903 0.870 0.828 0.774 0.707 0.623 0.516 0.382 0.213 0.000 0.000 0.000)))) (snd-display #__line__ ";power-env: ~A" (channel->float-vector)))) (map-channel (lambda (y) 1.0)) (let ((pe (make-power-env '(0 0 1.0 1 1 0.0 2 0 1 3 0 1) :duration (/ 34.0 22050.0)))) (map-channel (lambda (y) (* y (power-env pe)))) (if (not (vequal1 (channel->float-vector) (float-vector 0.000 0.100 0.200 0.300 0.400 0.500 0.600 0.700 0.800 0.900 1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";power-env 0 and 1: ~A" (channel->float-vector)))) (map-channel (lambda (y) 1.0)) (let ((pe (make-power-env '(0 0 .01 1 1 1) :duration (/ 34.0 22050.0)))) (map-channel (lambda (y) (* y (power-env pe)))) (if (and (not (vequal1 (channel->float-vector) (float-vector 0.000 0.132 0.246 0.346 0.432 0.507 0.573 0.630 0.679 0.722 0.760 0.792 0.821 0.845 0.867 0.886 0.902 0.916 0.928 0.939 0.948 0.956 0.963 0.969 0.975 0.979 0.983 0.987 0.990 0.992 0.995 0.997 0.998))) (not (vequal1 (channel->float-vector) (float-vector 0.000 0.135 0.253 0.354 0.442 0.518 0.584 0.641 0.691 0.733 0.771 0.803 0.830 0.855 0.875 0.893 0.909 0.923 0.934 0.945 0.953 0.961 0.968 0.973 0.978 0.982 0.986 0.987 0.990 0.992 0.995 0.997 0.998)))) (snd-display #__line__ ";power-env .01: ~A" (channel->float-vector)))) (let ((name (file-name ind))) (close-sound ind) (if (file-exists? name) (delete-file name)))) (set! *clm-srate* old-srate)) (let ((ind (new-sound "tmp.snd" 1 22050 mus-ldouble mus-next :size 50))) (set! (sample 3) 1.0) (filter-channel (float-vector .5 1.0 .5) 3) (let ((data (channel->float-vector 0 10))) (if (not (vequal data (float-vector 0.000 0.000 0.000 0.500 1.000 0.500 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";filter (sym 3): ~A" data))) (undo) (filter-channel (float-vector .5 1.0 .25) 3) (let ((data (channel->float-vector 0 10))) (if (not (vequal data (float-vector 0.000 0.000 0.000 0.500 1.000 0.250 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";filter (3): ~A" data))) (undo) (filter-channel (float-vector .5 1.0 1.0 .5) 4) (let ((data (channel->float-vector 0 10))) (if (not (vequal data (float-vector 0.000 0.000 0.000 0.500 1.000 1.000 0.500 0.000 0.000 0.000))) (snd-display #__line__ ";filter (sym 4): ~A" data))) (undo) (filter-channel (float-vector .5 1.0 1.0 .25) 4) (let ((data (channel->float-vector 0 10))) (if (not (vequal data (float-vector 0.000 0.000 0.000 0.500 1.000 1.000 0.250 0.000 0.000 0.000))) (snd-display #__line__ ";filter (4): ~A" data))) (undo) (close-sound ind)) (let () (new-sound "tmp.snd" 1 22050 mus-ldouble mus-next #f 100) (set! (sample 10) 0.5) (filter-sound (float-vector 1.0 0.0 1.0) 3) (if (not (vequal (channel->float-vector 5 10) (float-vector 0.000 0.000 0.000 0.000 0.000 0.500 0.000 0.500 0.000 0.000))) (snd-display #__line__ ";filter-sound 1 0 1: ~A" (channel->float-vector 5 10))) (undo) (filter-channel (float-vector 1.0 0.0 1.0) 3) (if (not (vequal (channel->float-vector 5 10) (float-vector 0.000 0.000 0.000 0.000 0.000 0.500 0.000 0.500 0.000 0.000))) (snd-display #__line__ ";filter-channel (v) 1 0 1: ~A" (channel->float-vector 5 10))) (undo) (filter-sound '(0 1 1 1) 100) (let ((coeffs (make-fir-coeffs 100 (make-float-vector 100 0.5))) (data (channel->float-vector 10 100)) (happy #t)) (do ((i 0 (+ i 1))) ((or (not happy) (= i 100))) (if (fneq (data i) (coeffs i)) (begin (snd-display #__line__ ";coeffs '(0 1 1 1): ~A ~A ~A" i (coeffs i) (data i)) (set! happy #f))))) (undo) (filter-sound '(0 1 1 1) 1000) (if (not (vequal (channel->float-vector 5 10) (float-vector 0.000 0.000 0.000 0.000 0.000 0.500 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";filter-sound 1 (1000): ~A" (channel->float-vector 5 10))) (undo) (make-selection 5 15) (filter-selection '(0 1 1 1) 100) (if (and (not (equal? (edit-fragment 2) (list "filter-selection '(0.000 1.000 1.000 1.000) 100" "set" 5 11))) (not (equal? (edit-fragment 2) (list "filter-selection '(0.000 1.000 1.000 1.000) 100" "set" 5 111)))) (snd-display #__line__ ";filter-selection truncated: ~S" (edit-fragment 2))) (undo) (filter-selection '(0 1 1 1) 100 #f) (if (not (equal? (edit-fragment 2) (list "filter-selection '(0.000 1.000 1.000 1.000) 100" "set" 5 111))) (snd-display #__line__ ";filter-selection not truncated: ~S" (edit-fragment 2))) (if (not (vequal (channel->float-vector 50 10) (float-vector -0.016 0.018 -0.021 0.024 -0.029 0.035 -0.045 0.064 -0.106 0.318))) (snd-display #__line__ ";filter-selection no trunc: ~A" (channel->float-vector 50 10))) (undo) (filter-selection '(0 1 1 1) 1024 #t) (if (not (equal? (edit-fragment 2) (list "filter-selection '(0.000 1.000 1.000 1.000) 1024" "set" 5 11))) (snd-display #__line__ ";filter-selection truncated (1000): ~S" (edit-fragment 2))) (if (fneq (maxamp) 0.0) (snd-display #__line__ ";filter-selection 1000 untrunc? ~A" (maxamp))) (undo) (filter-selection '(0 1 1 1) 1024 #f) (if (not (equal? (edit-fragment 2) (list "filter-selection '(0.000 1.000 1.000 1.000) 1024" "set" 5 1035))) (snd-display #__line__ ";filter-selection not truncated (1000): ~S" (edit-fragment 2))) (if (fneq (maxamp) 0.318) (snd-display #__line__ ";filter-selection 1000 no trunc? ~A" (maxamp))) (if (not (vequal (channel->float-vector 517 10) (float-vector 0.035 -0.045 0.064 -0.106 0.318 0.318 -0.106 0.064 -0.045 0.035))) (snd-display #__line__ ";filter-selection 1000 no trunc: ~A" (channel->float-vector 505 10))) (undo) (filter-channel '(0 1 1 1) 10) (if (not (vequal (channel->float-vector 10 10) (float-vector 0.008 -0.025 0.050 -0.098 0.316 0.316 -0.098 0.050 -0.025 0.008))) (snd-display #__line__ ";filter-channel 10: ~A" (channel->float-vector 10 10))) (undo) (filter-channel '(0 1 1 1) 1000) (if (not (vequal (channel->float-vector 5 10) (float-vector 0.000 0.000 0.000 0.000 0.000 0.500 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";filter-channel 1 (1000): ~A" (channel->float-vector 5 10))) (undo) (filter-channel '(0 1 1 0) 10) (if (not (vequal (channel->float-vector 0 30) (float-vector 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.005 0.010 0.006 0.038 0.192 0.192 0.038 0.006 0.010 0.005 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";filter-channel lp: ~A ~A ~A" (channel->float-vector 0 10) (channel->float-vector 10 10) (channel->float-vector 20 10))) (undo) (filter-channel '(0 1 1 0) 10 0 20 #f #f #f #f) (if (not (vequal (channel->float-vector 0 30) (float-vector 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.005 0.010 0.006 0.038 0.192 0.192 0.038 0.006 0.010 0.005 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";filter-channel lp no trunc: ~A ~A ~A" (channel->float-vector 0 10) (channel->float-vector 10 10) (channel->float-vector 20 10))) (undo) (close-sound)) (let ((ind (new-sound "tmp.snd" 2 22050 mus-ldouble mus-next #f 100))) (set! (sample 10) 0.5) (set! (sample 5 ind 1) -0.5) (set! (sync ind) 1) (filter-sound (float-vector 1.0 0.0 1.0) 3) (if (not (vequal (channel->float-vector 5 10 ind 0) (float-vector 0.000 0.000 0.000 0.000 0.000 0.500 0.000 0.500 0.000 0.000))) (snd-display #__line__ ";(2) filter-sound 1 0 1: ~A" (channel->float-vector 5 10))) (if (not (vequal (channel->float-vector 0 10 ind 1) (float-vector 0.000 0.000 0.000 0.000 0.000 -0.500 0.000 -0.500 0.000 0.000))) (snd-display #__line__ ";(2) filter-sound 1 0 2: ~A" (channel->float-vector 0 10 ind 1))) (undo) (filter-sound '(0 1 1 1) 1000) (if (not (vequal (channel->float-vector 5 10 ind 0) (float-vector 0.000 0.000 0.000 0.000 0.000 0.500 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";(2) filter-sound 1 (1000): ~A" (channel->float-vector 5 10))) (if (not (vequal (channel->float-vector 0 10 ind 1) (float-vector 0.000 0.000 0.000 0.000 0.000 -0.500 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";(2) filter-sound 2 (1000): ~A" (channel->float-vector 0 10))) (undo) (make-selection 0 20) (filter-selection (float-vector 1.0 0.0 1.0) 3) (if (not (vequal (channel->float-vector 5 10 ind 0) (float-vector 0.000 0.000 0.000 0.000 0.000 0.500 0.000 0.500 0.000 0.000))) (snd-display #__line__ ";(2) filter-selection 1 0 1: ~A" (channel->float-vector 5 10))) (if (not (vequal (channel->float-vector 0 10 ind 1) (float-vector 0.000 0.000 0.000 0.000 0.000 -0.500 0.000 -0.500 0.000 0.000))) (snd-display #__line__ ";(2) filter-selection 1 0 2: ~A" (channel->float-vector 0 10 ind 1))) (undo) (set! (sync ind) 0) (filter-selection (float-vector 1.0 0.0 1.0) 3) (if (not (vequal (channel->float-vector 5 10 ind 0) (float-vector 0.000 0.000 0.000 0.000 0.000 0.500 0.000 0.500 0.000 0.000))) (snd-display #__line__ ";(2) filter-selection 1 0 1 (no sync): ~A" (channel->float-vector 5 10))) (if (not (vequal (channel->float-vector 0 10 ind 1) (float-vector 0.000 0.000 0.000 0.000 0.000 -0.500 0.000 -0.500 0.000 0.000))) (snd-display #__line__ ";(2) filter-selection 1 0 2 (no sync): ~A" (channel->float-vector 0 10 ind 1))) (undo 1 ind 0) (undo 1 ind 1) (if (not (= (edit-position ind 0) 1)) (snd-display #__line__ ";edpos filter-sel undo: ~A" (edit-position ind 0))) (if (not (= (edit-position ind 1) 1)) (snd-display #__line__ ";edpos filter-sel undo 1: ~A" (edit-position ind 1))) (filter-sound (float-vector 1.0 0.0 1.0) 3) (if (not (vequal (channel->float-vector 5 10 ind 0) (float-vector 0.000 0.000 0.000 0.000 0.000 0.500 0.000 0.500 0.000 0.000))) (snd-display #__line__ ";(2) filter-sound 1 0 1 no sync: ~A" (channel->float-vector 5 10))) (if (not (vequal (channel->float-vector 0 10 ind 1) (float-vector 0.000 0.000 0.000 0.000 0.000 -0.500 0.000 0.000 0.000 0.000))) (snd-display #__line__ ";(2) filter-sound 1 0 2 no sync: ~A" (channel->float-vector 0 10 ind 1))) (undo 1 ind 0) (filter-channel '(0 1 1 0) 10 #f #f ind 1) (if (not (vequal (channel->float-vector 0 30 ind 1) (float-vector 0.000 0.000 0.000 0.000 0.000; 0.000 0.000 0.000 0.000 0.000 -0.005 -0.010 -0.006 -0.038 -0.192 -0.192 -0.038 -0.006 -0.010 -0.005 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0 0 0 0 0))) (snd-display #__line__ ";filter-channel lp: ~A ~A ~A" (channel->float-vector 0 10 ind 1) (channel->float-vector 10 10 ind 1) (channel->float-vector 20 10 ind 1))) (undo 1 ind 1) (close-sound ind)) (let ((ind (new-sound "tmp.snd" 1 22050 mus-bshort mus-next :size 100))) ; short out needed here (set! (sample 10) 0.5) (set! (sample 20) -0.5) (scale-to 1.0) (if (fneq (sample 10) .999) (snd-display #__line__ ";scale-to 1.0 short (10): ~A" (sample 10))) (if (fneq (sample 20) -.999) (snd-display #__line__ ";scale-to 1.0 short (20): ~A" (sample 10))) (close-sound ind)) (let ((ind (new-sound "tmp.snd" 1 22050 mus-byte mus-next :size 100))) (set! (sample 10) 0.5) (set! (sample 20) -0.5) (scale-to 1.0) (if (fneq (sample 10) .992) (snd-display #__line__ ";scale-to 1.0 byte (10): ~A" (sample 10))) (if (fneq (sample 20) -.992) (snd-display #__line__ ";scale-to 1.0 byte (20): ~A" (sample 10))) (close-sound ind)) (when with-gui (set! *transform-graph-type* graph-once) (set! *fft-window* 6) (set! *show-y-zero* #f) (set! *show-transform-peaks* #f) (set! *fft-log-frequency* #f) (set! *fft-log-magnitude* #f) (set! *with-verbose-cursor* #f) (set! *show-grid* #f) (set! *show-sonogram-cursor* #f) (set! *with-tracking-cursor* #f) (set! *show-controls* #f) (set! *speed-control-tones* 12) (set! *wavelet-type* 0) (set! *spectrum-start* 0.0) (set! *spectro-hop* 4) (set! *fft-window-alpha* 0.0) (set! *fft-window-beta* 0.0) (set! *min-dB* -60.0) (set! *reverb-control-decay* 1.0) (letrec ((test-sound-func-1 (lambda (func name ind-1 ind-2 new-val eq-func leq-func settable channel global) (let* ((old-val (func)) (old-vals (func #t)) (old-default (func #f)) (old-1 (func ind-1)) (old-2 (func ind-2)) (sel-snd (selected-sound)) (unsel-snd (if (equal? sel-snd ind-1) ind-2 ind-1)) (caller (if channel "channel" "sound"))) (if (not (eq-func old-val old-default)) (snd-display #__line__ ";~A sound-func: no arg: ~A, #f: ~A" name old-val old-default)) (if (not (or (leq-func old-vals (list old-1 old-2)) (leq-func old-vals (list old-2 old-1)))) (snd-display #__line__ ";~A sound-func #t: ~A, sep: ~A" name old-vals (list old-1 old-2))) (if settable (begin (set! (func) new-val) (if (not (eq-func (func) new-val)) (snd-display #__line__ ";~A set no arg: ~A ~A" name (func) new-val)) (if (not (eq-func (func) (func sel-snd))) (snd-display #__line__ ";~A set no arg sel: ~A ~A" name (func) (func sel-snd))) (if (or (and global (not (eq-func (func) (func unsel-snd)))) (and (not global) (eq-func (func) (func unsel-snd)))) (snd-display #__line__ ";~A set no arg unsel: ~A ~A (sel: ~A)" name (func) (func unsel-snd) (func sel-snd))) (if (not (or (leq-func (func #t) (list (func sel-snd) (func unsel-snd))) (leq-func (func #t) (list (func unsel-snd) (func sel-snd))))) (snd-display #__line__ ";~A ~A-func #t set: ~A, sep: ~A" name caller (func #t) (list (func sel-snd) (func unsel-snd)))) (set! (func) old-val) (set! (func ind-1) new-val) (if (not (eq-func (func ind-1) new-val)) (snd-display #__line__ ";~A set arg: ~A ~A" name (func ind-1) new-val)) (if (eq-func (func ind-2) new-val) (snd-display #__line__ ";~A set arg (2): ~A ~A" name (func ind-2) new-val)) (if (not (or (leq-func (func #t) (list (func ind-1) (func ind-2))) (leq-func (func #t) (list (func ind-2) (func ind-1))))) (snd-display #__line__ ";~A ~A-func arg set: ~A, sep: ~A" name caller (func #t) (list (func ind-1) (func ind-2)))) (set! (func ind-1) old-1) (set! (func #t) new-val) (if (not (leq-func (func #t) (list new-val new-val))) (snd-display #__line__ ";~A ~A-func arg set #t: ~A, sep: ~A" name caller (func #t) (list new-val new-val))) (if (not (eq-func (func ind-1) new-val)) (snd-display #__line__ ";~A set arg #t: ~A ~A" name (func ind-1) new-val)) (if (not (eq-func (func ind-2) new-val)) (snd-display #__line__ ";~A set arg #t (2): ~A ~A" name (func ind-2) new-val)) (set! (func ind-1) old-1) (set! (func ind-2) old-2) (if (not (eq-func (func ind-1) old-1)) (snd-display #__line__ ";~A set arg #t old: ~A ~A" name (func ind-1) old-1)) (if (not (eq-func (func ind-2) old-2)) (snd-display #__line__ ";~A set arg #t (2): ~A ~A" name (func ind-2) old-2))))))) (test-sound-func (lambda (func name ind-1 ind-2 new-val eq-func leq-func settable) (test-sound-func-1 func name ind-1 ind-2 new-val eq-func leq-func settable #f #f)))) (let ((ind-1 (new-sound "test-1.snd" 1 22050 mus-lfloat mus-next "mono testing" 100)) (ind-2 (new-sound "test-2.snd" 2 44100 mus-bshort mus-aifc "stereo testing" 300))) (for-each (lambda (data) (apply test-sound-func data)) (list (list srate 'srate ind-1 ind-2 48000 = equal? #t) (list sample-type 'sample-type ind-1 ind-2 mus-byte = equal? #t) (list data-location 'data-location ind-1 ind-2 123 = equal? #t) (list data-size 'data-size ind-1 ind-2 12348 = equal? #t) (list framples 'framples ind-1 ind-2 12348 = equal? #t) (list sync 'sync ind-1 ind-2 2 = equal? #t) (list sample-type 'sample-type ind-1 ind-2 mus-byte = equal? #t) (list channels 'channels ind-1 ind-2 0 = equal? #f) (list chans 'chans ind-1 ind-2 0 = equal? #f) (list header-type 'header-type ind-1 ind-2 0 = equal? #f) (reader-cond (with-gui (list amp-control 'amp-control ind-1 ind-2 .5 within-.01? feql #t) (list contrast-control 'contrast-control ind-1 ind-2 .5 within-.01? feql #t) (list expand-control 'expand-control ind-1 ind-2 .5 within-.01? ffeql #t) (list speed-control 'speed-control ind-1 ind-2 .5 within-.01? feql #t) (list reverb-control-length 'reverb-control-length ind-1 ind-2 .5 within-.01? feql #t) (list reverb-control-scale 'reverb-control-scale ind-1 ind-2 .5 within-.01? feql #t) (list contrast-control? 'contrast-control? ind-1 ind-2 #t equal? equal? #t) (list expand-control? 'expand-control? ind-1 ind-2 #t equal? equal? #t) (list filter-control? 'filter-control? ind-1 ind-2 #t equal? equal? #t) (list reverb-control? 'reverb-control? ind-1 ind-2 #t equal? equal? #t) (list read-only 'read-only ind-1 ind-2 #t equal? equal? #t))) (list file-name 'file-name ind-1 ind-2 #f string=? equal? #f) (list short-file-name 'short-file-name ind-1 ind-2 #f string=? equal? #f) (list comment 'comment ind-1 ind-2 #f string=? equal? #f))) (save-controls #t) (restore-controls #t) (reset-controls #t) (close-sound #t) (if (not (null? (sounds))) (snd-display #__line__ ";sounds after close-sound #t: ~A" (sounds))) ;; snd chn cases (letrec ((test-channel-func-1 (lambda (func name ind-1 ind-2 new-val eq-func leq-func settable global) (let ((old-1-0 (func ind-1 0)) (old-2-0 (func ind-2 0)) (old-2-1 (func ind-2 1)) (old-1-all (func ind-1 #t)) (old-2-all (func ind-2 #t)) (old-all-all (func #t #t))) (if (not (eq-func old-1-0 (car old-1-all))) (snd-display #__line__ ";~A channel-func old 1/#t: ~A ~A" name old-1-0 old-1-all)) (if (not (eq-func old-2-0 (car old-2-all))) (snd-display #__line__ ";~A channel-func old 2/#t: ~A ~A" name old-2-0 old-2-all)) (if (not (eq-func old-2-1 (cadr old-2-all))) (snd-display #__line__ ";~A channel-func old 2-2/#t: ~A ~A" name old-2-1 old-2-all)) (if (not (leq-func old-1-all (list old-1-0))) (snd-display #__line__ ";~A channel-func #t list: ~A ~A" name old-1-all old-1-0)) (if (not (leq-func old-2-all (list old-2-0 old-2-1))) (snd-display #__line__ ";~A channel-func (2) #t list: ~A ~A ~A" name old-2-all old-2-0 old-2-1)) (if (not (and (or (leq-func (car old-all-all) old-1-all) (leq-func (car old-all-all) old-2-all)) (or (leq-func (cadr old-all-all) old-1-all) (leq-func (cadr old-all-all) old-2-all)))) (snd-display #__line__ ";~A channel-func #t #t: ~A ~A ~A" name old-all-all old-1-all old-2-all)) (if settable (begin (set! (func ind-1 0) new-val) (if (not (eq-func (func ind-1 0) new-val)) (snd-display #__line__ ";~A set channel-func: ~A ~A" name (func ind-1 0) new-val)) (if (eq-func (func ind-2 0) new-val) (snd-display #__line__ ";~A set 2 channel-func: ~A ~A" name (func ind-2 0) new-val)) (set! (func ind-1 0) old-1-0) (set! (func ind-2 1) new-val) (if (eq-func (func ind-1 0) new-val) (snd-display #__line__ ";~A set (2) channel-func: ~A ~A" name (func ind-1 0) new-val)) (if (not (eq-func (func ind-2 1) new-val)) (snd-display #__line__ ";~A set (2) 2 channel-func: ~A ~A" name (func ind-2 0) new-val)) (set! (func ind-2 0) new-val) (set! (func ind-2 #t) old-2-0) (if (not (eq-func (func ind-2 0) old-2-0)) (snd-display #__line__ ";~A set (#t 0) 2 channel-func: ~A ~A" name (func ind-2 0) old-2-0)) (if (not (eq-func (func ind-2 1) old-2-0)) (snd-display #__line__ ";~A set (#t 1) 2 channel-func: ~A ~A" name (func ind-2 1) old-2-0)) (set! (func ind-2 0) old-2-0) (set! (func ind-2 1) old-2-1))) ))) (test-channel-func (lambda (func name ind-1 ind-2 new-val eq-func leq-func settable global) (test-sound-func-1 func name ind-1 ind-2 new-val eq-func leq-func settable #t global) (test-channel-func-1 func name ind-1 ind-2 new-val eq-func leq-func settable global)))) (let ((ind-1 (new-sound "test-1.snd" 1 22050 mus-ldouble mus-next "mono testing" 100)) (ind-2 (new-sound "test-2.snd" 2 44100 mus-bshort mus-aifc "stereo testing" 300))) (set! (sample 1 ind-1 0) .1) (set! (sample 2 ind-2 0) .2) (set! (sample 3 ind-2 1) .3) (for-each (lambda (data) (apply test-channel-func data)) (list (list min-dB 'min-dB ind-1 ind-2 -100.0 within-.01? feql #t #t) (list x-position-slider 'x-position-slider ind-1 ind-2 .1 within-.01? feql #t #f) ;; (list y-position-slider 'y-position-slider ind-1 ind-2 0.5 within-.01? feql #t #f) (list x-zoom-slider 'x-zoom-slider ind-1 ind-2 0.2 within-.01? feql #t #f) (list y-zoom-slider 'y-zoom-slider ind-1 ind-2 0.2 within-.01? feql #t #f) (list fft-window-alpha 'fft-window-alpha ind-1 ind-2 0.5 (lambda (a b) (< (abs (- a b)) .02)) feql #t #t) (list fft-window-beta 'fft-window-beta ind-1 ind-2 0.5 (lambda (a b) (< (abs (- a b)) .02)) feql #t #t) (list spectrum-end 'spectrum-end ind-1 ind-2 0.2 within-.01? feql #t #t) (list spectrum-start 'spectrum-start ind-1 ind-2 0.1 within-.01? feql #t #t) (list spectro-x-angle 'spectro-x-angle ind-1 ind-2 10.0 within-.01? feql #t #t) (list spectro-x-scale 'spectro-x-scale ind-1 ind-2 0.2 within-.01? feql #t #t) (list spectro-y-angle 'spectro-y-angle ind-1 ind-2 10.0 within-.01? feql #t #t) (list spectro-y-scale 'spectro-y-scale ind-1 ind-2 0.1 within-.01? feql #t #t) (list spectro-z-angle 'spectro-z-angle ind-1 ind-2 10.0 within-.01? feql #t #t) (list spectro-z-scale 'spectro-z-scale ind-1 ind-2 0.3 within-.01? feql #t #t) (list beats-per-minute 'beats-per-minute ind-1 ind-2 100.0 within-.01? feql #t #t) (list dot-size 'dot-size ind-1 ind-2 10 = equal? #t #t) (list x-axis-style 'x-axis-style ind-1 ind-2 1 = equal? #t #t) ;; (list left-sample 'left-sample ind-1 ind-2 1 (lambda (a b) (< (abs (- a b)) 2)) equal? #t #f) ;; (list right-sample 'right-sample ind-1 ind-2 50 (lambda (a b) (< (abs (- a b)) 2)) equal? #t #f) (list show-axes 'show-axes ind-1 ind-2 2 = equal? #t #t) (list transform-graph? 'transform-graph? ind-1 ind-2 #t equal? equal? #t #f) (list time-graph? 'time-graph? ind-1 ind-2 #f equal? equal? #t #f) (list lisp-graph? 'lisp-graph? ind-1 ind-2 #t equal? equal? #t #f) (list squelch-update 'squelch-update ind-1 ind-2 #t equal? equal? #t #f) (list show-y-zero 'show-y-zero ind-1 ind-2 #t equal? equal? #t #t) (list show-grid 'show-grid ind-1 ind-2 #t equal? equal? #t #t) (list grid-density 'grid-density ind-1 ind-2 0.5 within-.01? feql #t #t) (list show-sonogram-cursor 'show-sonogram-cursor ind-1 ind-2 #t equal? equal? #t #t) (list show-marks 'show-marks ind-1 ind-2 #f equal? equal? #t #t) (list show-transform-peaks 'show-transform-peaks ind-1 ind-2 #t equal? equal? #t #t) (list fft-log-frequency 'fft-log-frequency ind-1 ind-2 #t equal? equal? #t #t) (list fft-log-magnitude 'fft-log-magnitude ind-1 ind-2 #t equal? equal? #t #t) (list show-mix-waveforms 'show-mix-waveforms ind-1 ind-2 #f equal? equal? #t #t) (list with-verbose-cursor 'with-verbose-cursor ind-1 ind-2 #t equal? equal? #t #t) (list max-transform-peaks 'max-transform-peaks ind-1 ind-2 10 = equal? #t #t) (list wavelet-type 'wavelet-type ind-1 ind-2 1 = equal? #t #t) (list transform-size 'transform-size ind-1 ind-2 64 = equal? #t #t) (list transform-graph-type 'transform-graph-type ind-1 ind-2 1 = equal? #t #t) (list transform-normalization 'transform-normalization ind-1 ind-2 2 = equal? #t #t) (list time-graph-type 'time-graph-type ind-1 ind-2 graph-as-wavogram = equal? #t #t) (list wavo-hop 'wavo-hop ind-1 ind-2 10 = equal? #t #t) (list wavo-trace 'wavo-trace ind-1 ind-2 10 = equal? #t #t) (list spectro-hop 'spectro-hop ind-1 ind-2 10 = equal? #t #t) (list cursor 'cursor ind-1 ind-2 50 = equal? #t #f) (list cursor-style 'cursor-style ind-1 ind-2 1 = equal? #t #t) (list cursor-size 'cursor-size ind-1 ind-2 10 = equal? #t #t) (list framples 'framples ind-1 ind-2 50 = equal? #t #f) (list zero-pad 'zero-pad ind-1 ind-2 1 = equal? #t #t) (list fft-window 'fft-window ind-1 ind-2 1 = equal? #t #t) ; (list transform-type 'transform-type ind-1 ind-2 1 equal? equal? #t #t) ))) (update-time-graph #t #t) (update-transform-graph #t #t) (update-lisp-graph #t #t) (close-sound #f) (close-sound #f) (if (not (null? (sounds))) (snd-display #__line__ ";sounds after close-sound #t: ~A" (sounds))))) (letrec ((test-sound-func-2 (lambda (func name ind-1 ind-2 new-val eq-func leq-func) (let* ((old-global-val (func)) (old-vals (func #t)) (old-1 (func ind-1)) (old-2 (func ind-2)) (sel-snd (selected-sound)) (unsel-snd (if (equal? sel-snd ind-1) ind-2 ind-1))) (if (not (or (leq-func old-vals (list old-1 old-2)) (leq-func old-vals (list old-2 old-1)))) (snd-display #__line__ ";~A sound-func #t: ~A, sep: ~A" name old-vals (list old-1 old-2))) (set! (func) new-val) (if (not (eq-func (func) new-val)) (snd-display #__line__ ";~A global set no arg: ~A ~A" name (func) new-val)) (if (not (eq-func (func) (func sel-snd))) (snd-display #__line__ ";~A global set no arg sel: ~A ~A" name (func) (func sel-snd))) (if (not (eq-func (func) (func unsel-snd))) (snd-display #__line__ ";~A set global no arg unsel: ~A ~A (sel: ~A)" name (func) (func unsel-snd) (func sel-snd))) (if (not (or (leq-func (func #t) (list (func sel-snd) (func unsel-snd))) (leq-func (func #t) (list (func unsel-snd) (func sel-snd))))) (snd-display #__line__ ";~A func #t set: ~A, sep: ~A" name (func #t) (list (func sel-snd) (func unsel-snd)))) (set! (func) old-global-val) (set! (func ind-1) new-val) (if (not (eq-func (func ind-1) new-val)) (snd-display #__line__ ";~A set arg: ~A ~A" name (func ind-1) new-val)) (if (eq-func (func ind-2) new-val) (snd-display #__line__ ";~A set arg (2): ~A ~A" name (func ind-2) new-val)) (if (not (or (leq-func (func #t) (list (func ind-1) (func ind-2))) (leq-func (func #t) (list (func ind-2) (func ind-1))))) (snd-display #__line__ ";~A func arg set: ~A, sep: ~A" name (func #t) (list (func ind-1) (func ind-2)))) (set! (func ind-1) old-1) (set! (func #t) new-val) (if (not (leq-func (func #t) (list new-val new-val))) (snd-display #__line__ ";~A func arg set #t: ~A, sep: ~A" name (func #t) (list new-val new-val))) (if (not (eq-func (func ind-1) new-val)) (snd-display #__line__ ";~A set arg #t: ~A ~A" name (func ind-1) new-val)) (if (not (eq-func (func ind-2) new-val)) (snd-display #__line__ ";~A set arg #t (2): ~A ~A" name (func ind-2) new-val)) (if (eq-func (func) new-val) (snd-display #__line__ ";~A overwrote global: ~A ~A" name (func) new-val)) (set! (func ind-1) old-1) (set! (func ind-2) old-2) (if (not (eq-func (func ind-1) old-1)) (snd-display #__line__ ";~A set arg #t old: ~A ~A" name (func ind-1) old-1)) (if (not (eq-func (func ind-2) old-2)) (snd-display #__line__ ";~A set arg #t (2): ~A ~A" name (func ind-2) old-2)))))) (let ((ind-1 (new-sound "test-1.snd" 1 22050 mus-ldouble mus-next "mono testing" 100)) (ind-2 (new-sound "test-2.snd" 2 44100 mus-bshort mus-aifc "stereo testing" 300))) (for-each (lambda (data) (apply test-sound-func-2 data)) (list (list filter-control-in-dB 'filter-control-in-dB ind-1 ind-2 #t eq? equal?) (list filter-control-in-hz 'filter-control-in-hz ind-1 ind-2 #t eq? equal?) (list show-controls 'show-controls ind-1 ind-2 #t eq? equal?) (list speed-control-tones 'speed-control-tones ind-1 ind-2 14 = equal?) (list speed-control-style 'speed-control-style ind-1 ind-2 speed-control-as-semitone = equal?) (list filter-control-order 'filter-control-order ind-1 ind-2 14 = equal?) (list expand-control-length 'expand-control-length ind-1 ind-2 .25 within-.01? feql) (list expand-control-ramp 'expand-control-ramp ind-1 ind-2 .25 within-.01? feql) (list expand-control-hop 'expand-control-hop ind-1 ind-2 .25 within-.01? feql) (list expand-control-jitter 'expand-control-jitter ind-1 ind-2 .25 within-.01? feql) (list contrast-control-amp 'contrast-control-amp ind-1 ind-2 .25 within-.01? feql) (list reverb-control-feedback 'reverb-control-feedback ind-1 ind-2 .25 within-.01? feql) (list reverb-control-lowpass 'reverb-control-lowpass ind-1 ind-2 .25 within-.01? feql) (list reverb-control-decay 'reverb-control-decay ind-1 ind-2 .25 within-.01? feql) (list amp-control-bounds 'amp-control-bounds ind-1 ind-2 (list 0.0 2.0) feql (lambda (a b) (and (feql (car a) (car b)) (feql (cadr a) (cadr b))))) (list contrast-control-bounds 'contrast-control-bounds ind-1 ind-2 (list 0.0 2.0) feql (lambda (a b) (and (feql (car a) (car b)) (feql (cadr a) (cadr b))))) (list expand-control-bounds 'expand-control-bounds ind-1 ind-2 (list 0.1 2.0) feql (lambda (a b) (and (feql (car a) (car b)) (feql (cadr a) (cadr b))))) (list speed-control-bounds 'speed-control-bounds ind-1 ind-2 (list 0.1 2.0) feql (lambda (a b) (and (feql (car a) (car b)) (feql (cadr a) (cadr b))))) (list reverb-control-length-bounds 'reverb-control-length-bounds ind-1 ind-2 (list 0.0 2.0) feql (lambda (a b) (and (feql (car a) (car b)) (feql (cadr a) (cadr b))))) (list reverb-control-scale-bounds 'reverb-control-scale-bounds ind-1 ind-2 (list 0.0 2.0) feql (lambda (a b) (and (feql (car a) (car b)) (feql (cadr a) (cadr b))))))) (close-sound ind-1) (close-sound ind-2))))) (set! *remember-sound-state* #t) (let ((ind (open-sound "oboe.snd"))) (set! (transform-graph? ind 0) #t) (set! (show-transform-peaks ind 0) #t) (set! (show-y-zero ind 0) #t) (close-sound ind)) (let ((ind (open-sound "oboe.snd"))) (if (or (not (transform-graph? ind 0)) (not (show-transform-peaks ind 0)) (not (show-y-zero ind 0))) (snd-display #__line__ ";remember-sound-state: ~A ~A ~A" (transform-graph? ind 0) (show-transform-peaks ind 0) (show-y-zero ind 0))) (close-sound ind)) (reset-all-hooks) (set! *remember-sound-state* #f) (if (file-exists? "remembered-oboe.snd.scm") (delete-file "remembered-oboe.snd.scm")) (map-sound-files (lambda (n) (if (> (mus-sound-duration n) 1000.0) (snd-display #__line__ ";~A is pretty long! ~A" n (mus-sound-duration n))))) (if (string? sf-dir) (map-sound-files (lambda (n) (catch #t (lambda () (if (> (mus-sound-duration (string-append sf-dir n)) 1000.0) (snd-display #__line__ ";~A is pretty long! ~A" n (mus-sound-duration (string-append sf-dir n))))) (lambda args #f)) (mus-sound-forget (string-append sf-dir n))) sf-dir)) (let ((snd (new-sound "test.snd"))) (pad-channel 0 20) (map-channel (lambda (y) 1.0)) (env-channel-with-base '(0 0 1 1) 1.0) (let ((data (channel->float-vector 0 20))) (if (not (vequal data (float-vector 0.0 0.05 0.10 0.15 0.20 0.25 0.30 0.35 0.40 0.45 0.50 0.55 0.60 0.65 0.70 0.75 0.80 0.85 0.90 0.95))) (snd-display #__line__ ";env-chan 1.0: ~A" data))) (undo) (env-channel-with-base '(0 0 1 1 2 1 3 0) 0.0) (let ((data (channel->float-vector 0 20))) (if (not (vequal data (float-vector 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0))) (snd-display #__line__ ";env-chan 0.0: ~A" data))) (undo) (env-channel-with-base '(0 0 1 1) 100.0) (let ((data (channel->float-vector 0 20))) (if (not (vequal data (float-vector 0.0 0.003 0.006 0.010 0.015 0.022 0.030 0.041 0.054 0.070 0.091 0.117 0.150 0.191 0.244 0.309 0.392 0.496 0.627 0.792))) (snd-display #__line__ ";env-chan 100.0: ~A" data))) (undo) (env-channel-with-base '(0 0 1 1) 0.01) (let ((data (channel->float-vector 0 20))) (if (not (vequal data (float-vector 0.0 0.208 0.373 0.504 0.608 0.691 0.756 0.809 0.850 0.883 0.909 0.930 0.946 0.959 0.970 0.978 0.985 0.990 0.994 0.997))) (snd-display #__line__ ";env-chan 0.01: ~A" data))) (undo) (env-channel-with-base '(0 0 1 1) 1.0 5 10) (let ((data (channel->float-vector 0 20))) (if (not (vequal data (float-vector 1.0 1.0 1.0 1.0 1.0 0.0 0.111 0.222 0.333 0.444 0.556 0.667 0.778 0.889 1.0 1.0 1.0 1.0 1.0 1.0))) (snd-display #__line__ ";env-chan 1.0 seg: ~A" data))) (undo) (env-channel-with-base '(0 0 1 1 2 1 3 0) 0.0 5 10) (let ((data (channel->float-vector 0 20))) (if (not (vequal data (float-vector 1.0 1.0 1.0 1.0 1.0 0.0 0.0 0.0 0.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0))) (snd-display #__line__ ";env-chan 0.0 seg: ~A" data))) (undo) (env-channel-with-base '(0 0 1 1) 100.0 5 10) (let ((data (channel->float-vector 0 20))) (if (not (vequal data (float-vector 1.0 1.0 1.0 1.0 1.0 0.0 0.007 0.018 0.037 0.068 0.120 0.208 0.353 0.595 1.0 1.0 1.0 1.0 1.0 1.0))) (snd-display #__line__ ";env-chan 100.0 seg: ~A" data))) (undo) (env-channel-with-base '(0 0 1 1) 0.01 5 10) (let ((data (channel->float-vector 0 20))) (if (not (vequal data (float-vector 1.0 1.0 1.0 1.0 1.0 0.0 0.405 0.647 0.792 0.880 0.932 0.963 0.982 0.993 1.0 1.0 1.0 1.0 1.0 1.0))) (snd-display #__line__ ";env-chan 0.01 seg: ~A" data))) (undo) (close-sound snd)) (let ((ind1 (open-sound "now.snd")) (ind2 (open-sound "oboe.snd"))) (let ((val (channel-mean ind1 0))) (if (fneq val 5.02560673308833e-5) (snd-display #__line__ ";channel-mean: ~A" val))) (let ((val (channel-total-energy ind1 0))) (if (fneq val 50.7153476262465) (snd-display #__line__ ";channel-total-energy: ~A" val))) (let ((val (channel-average-power ind1 0))) (if (fneq val 0.00155078578803922) (snd-display #__line__ ";channel-average-power: ~A" val))) (let ((val (channel-rms ind1 0))) (if (fneq val 0.039380017623653) (snd-display #__line__ ";channel-rms: ~A" val))) (let ((val (channel-norm ind1 0))) (if (fneq val 7.12147088923675) (snd-display #__line__ ";channel-norm: ~A" val))) (let ((val (channel-variance ind1 0))) (if (fneq val 50.7153476237207) (snd-display #__line__ ";channel-variance: ~A" val))) (let ((val (channel-lp 2 ind1 0))) (if (fneq val 7.12147088923675) (snd-display #__line__ ";channel-lp 2: ~A" val))) (let ((val (channel-lp 1 ind1 0))) (if (fneq val 775.966033935547) (snd-display #__line__ ";channel-lp 1: ~A" val))) (let ((val (channel2-inner-product ind1 0 ind2 0))) (if (fneq val 1.52892031334341) (snd-display #__line__ ";channel2-inner-product: ~A" val))) (let ((val (channel2-angle ind1 0 ind2 0))) (if (fneq val 1.55485084385627) (snd-display #__line__ ";channel2-angle: ~A" val))) (let ((val (channel2-orthogonal? ind1 0 ind2 0))) (if val (snd-display #__line__ ";channel2-orthogonal: ~A" val))) (let ((val (channel2-coefficient-of-projection ind1 0 ind2 0))) (if (fneq val 0.0301470932351876) (snd-display #__line__ ";channel2-coefficient-of-projection: ~A" val))) (close-sound ind1) (set! ind1 (open-sound "oboe.snd")) (scale-by .99 ind1 0) (let ((dist (channel-distance ind1 0 ind2 0))) (if (fneq dist .1346) (snd-display #__line__ ";channel-distance: ~A" dist))) (close-sound ind1) (close-sound ind2)) (let ((loboe (string-append (getcwd) "/oboe.snd")) (ltest (string-append (getcwd) "/test.snd"))) (copy-file loboe ltest) (mus-sound-forget ltest) (let* ((ind (open-sound ltest)) (mx (maxamp ind 0)) (chns (chans ind)) (sr (srate ind)) (fr (framples ind 0))) (if (or (not (= (chans ind) (mus-sound-chans loboe))) (not (= (srate ind) (mus-sound-srate loboe))) (not (= (framples ind) (mus-sound-framples loboe)))) (snd-display #__line__ ";copy oboe -> test seems to have failed? ~A ~A ~A" (chans ind) (srate ind) (framples ind)) (with-local-hook update-hook (list (lambda (orig-ind) (lambda (new-ind) (set! ind new-ind)))) (lambda () (do ((i 0 (+ i 1))) ((= i 10)) (let ((v (channel->float-vector))) (if (not (float-vector? v)) (snd-display #__line__ ";channel->float-vector of oboe copy is null??") (array->file ltest v fr sr chns)) (update-sound ind) (let ((mx1 (maxamp ind 0))) (if (fneq mx mx1) (snd-display #__line__ ";update-sound looped maxamp: ~A ~A ~A ~A ~A (~A)" i ind (framples ind) mx1 mx (/ mx1 mx)))) (if (not (= (chans ind) chns)) (snd-display #__line__ ";update-sound looped chans: ~A ~A" chns (chans ind))) (if (not (= (srate ind) sr)) (snd-display #__line__ ";update-sound looped srate: ~A ~A" sr (srate ind))) (if (not (= (framples ind) fr)) (snd-display #__line__ ";update-sound looped framples: ~A ~A" fr (framples ind 0))))) (let ((old-ind (open-sound "oboe.snd"))) (let ((mxdiff (float-vector-peak (float-vector-subtract! (channel->float-vector 0 #f ind 0 0) (channel->float-vector 0 #f old-ind 0))))) (if (fneq mxdiff 0.0) (snd-display #__line__ ";update-sound looped overall max diff: ~A, sounds: ~A, ind: ~A, old-ind: ~A, rd: ~A" mxdiff (sounds) ind old-ind home))) (close-sound old-ind))))) (close-sound ind))) (if (file-exists? "test.snd") (delete-file "test.snd")) (let* ((ind (open-sound "oboe.snd")) (data (channel->float-vector)) (len (framples ind))) (do ((i 0 (+ i 1))) ((= i 5)) (array->file "test.snd" data len 22050 1) (file->array "test.snd" 0 0 len data) (let ((d2 (samples 0 len ind 0))) (float-vector-subtract! d2 data) (let ((diff (float-vector-peak d2))) (if (fneq diff 0.0) (snd-display #__line__ ";arr->file->array overall max diff: ~A" diff))))) ;; now clear sono bins if possible (set! *colormap-size* 16) (set! (transform-size ind 0) 8) (set! (transform-graph-type ind 0) graph-as-sonogram) (set! (transform-graph? ind 0) #t) (update-transform-graph) (set! (x-bounds) (list 0.0 .04)) (update-time-graph) (update-transform-graph) (set! *zoom-focus-style* (lambda (s c z x0 x1 range) 0)) (if (not (procedure? *zoom-focus-style*)) (snd-display #__line__ ";zoom-focus-style as func: ~A" *zoom-focus-style*)) (set! *zoom-focus-style* zoom-focus-right) (if (not (= *zoom-focus-style* zoom-focus-right)) (snd-display #__line__ ";unset zoom-focus-style as func: ~A" *zoom-focus-style*)) (close-sound ind)) (if (file-exists? "test.snd") (delete-file "test.snd")) (if (file-exists? "fmv.snd") (delete-file "fmv.snd")) (mus-sound-forget "fmv.snd") (mus-sound-forget "test.snd") (let ((rdin #f) (rdout #f) (len (mus-sound-framples "oboe.snd")) (types (list mus-riff mus-aifc mus-next mus-nist mus-ircam)) (forms (list mus-lshort mus-bshort mus-b24int mus-l24int mus-bint))) (system "cp oboe.snd fmv.snd") (do ((i 0 (+ i 1))) ((= i 5)) (set! rdin (make-readin :file "fmv.snd")) (set! rdout (make-sample->file "test.snd" 1 (forms i) (types i))) (do ((k 0 (+ k 1))) ((= k len)) (sample->file rdout k 0 (readin rdin))) (mus-close rdout) (mus-close rdin) (system "mv test.snd fmv.snd") (mus-sound-forget "test.snd") (mus-sound-forget "fmv.snd")) (let ((diff 0.0) (ctr 0) (ind1 (open-sound "oboe.snd")) (ind2 (make-file->sample "fmv.snd"))) (scan-channel (lambda (y) (set! diff (max diff (abs (- y (file->sample ind2 ctr 0))))) (set! ctr (+ ctr 1)) ;; if this happens it is almost certainly a problem with mus-sound-forget above #f)) (if (fneq diff 0.0) (snd-display #__line__ ";file->sample->file overall max diff: ~A" diff)) (close-sound ind1))) (let ((ind (open-sound "1a.snd")) (mx (maxamp))) ;; jokes from extsnd.html (make sure they run) (for-each (lambda (name-and-func) (let ((name (car name-and-func))) ((cadr name-and-func)) (if (and (fneq (/ (maxamp) mx) 2.0) (not (eq? name 'set-samples)) (not (eq? name 'coroutines))) (snd-display #__line__ ";silly scalers: ~A ~A" name (/ (maxamp) mx))) (revert-sound))) (list (list 'scale-by (lambda () (scale-by 2.0))) (list 'scale-channel (lambda () (scale-channel 2.0))) (list 'map-channel (lambda () (map-channel (lambda (val) (* val 2.0))))) (list 'set-max (lambda () (set! (maxamp) (* 2 (maxamp))))) (list 'env-sound (lambda () (env-sound '(0 2 1 2)))) (list 'env-channel (lambda () (env-channel (make-env '(0 1 1 1) :scaler 2.0 :length (framples))))) (list 'clm-channel (lambda () (clm-channel (make-one-zero :a0 2.0 :a1 0.0)))) (list 'filter-channel (lambda () (filter-channel (float-vector 2.0) 1))) (list 'float-vector->channel (lambda () (float-vector->channel (float-vector-scale! (channel->float-vector) 2.0) 0))) (list 'mix-selection (lambda () (select-all) (mix-selection 0))) (list 'scale-selection (lambda () (select-all) (scale-selection-by 2.0))) (list 'mix (lambda () (save-sound-as "temp.snd") (mix "temp.snd" 0) (delete-file "temp.snd"))) (list 'vector2 (lambda () (let ((sd (make-shared-vector (channel->float-vector) (list 1 (framples))))) (float-vector-scale! (sd 0) 2.0) (float-vector->channel (sd 0))))) (list 'convolve (lambda () (let ((flt (make-float-vector 8)) (sf (make-sampler 0))) (set! (flt 0) 2.0) (let ((cnv (make-convolve :filter flt :input (lambda (dir) (read-sample sf))))) (map-channel (lambda (val) (convolve cnv))))))) (list 'fft (lambda () (let* ((len (framples)) (fsize (expt 2 (ceiling (log len 2)))) (rl (channel->float-vector 0 fsize)) (im (make-float-vector fsize))) (mus-fft rl im fsize) (mus-fft rl im fsize) (mus-fft rl im fsize) (mus-fft rl im fsize) (float-vector->channel (float-vector-scale! rl (/ 2.0 (* fsize fsize))) 0 len)))) (list 'set-samples (lambda () ; too slow for some reason, so cut it short at 100 (set! (squelch-update) #t) (do ((i 0 (+ i 1))) ((= i 100)) (set! (sample i) (* 2 (sample i)))) (set! (squelch-update) #f))) (list 'coroutines (lambda () (set! (squelch-update) #t) (let ((make-scaler (lambda (start end) (letrec ((ctr start) (us (lambda (them) (set! (sample ctr) (* 2.0 (sample ctr))) (set! ctr (+ ctr 2)) (if (<= ctr end) (them us))))) us)))) ((make-scaler 0 100) (make-scaler 1 100))) (set! (squelch-update) #f) )) )) (close-sound ind)) (let ((ind1 (open-sound "1a.snd")) (data1 (file->floats "1a.snd")) (ind2 (open-sound "2a.snd")) (data2 (file->floats "2a.snd"))) (if (not (equal? data1 (channel->float-vector 0 #f ind1 0))) (snd-display #__line__ ";file->floats 1a.snd")) (if (not (equal? data2 (channel->float-vector 0 #f ind2 0))) (snd-display #__line__ ";file->floats 2a.snd")) (floats->file data1 "tmp.snd") (let ((ind3 (open-sound "tmp.snd"))) (if (not (equal? data1 (channel->float-vector 0 #f ind3 0))) (snd-display #__line__ ";floats->file 1a")) (close-sound ind3)) (mus-sound-forget "tmp.snd") (floats->file data2 "tmp.snd" 44100 "this is a comment") (let ((ind3 (open-sound "tmp.snd"))) (if (not (= (srate ind3) 44100)) (snd-display #__line__ ";floats->file srate: ~A" (srate ind3))) (close-sound ind3)) (mus-sound-forget "tmp.snd") (let ((tag (catch #t (lambda () (floats->file 32 "tmp.snd")) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";floats->file bad arg: ~A" tag)))) (for-each close-sound (sounds)) (let ((ind (new-sound "test.snd" 1 22050 mus-ldouble mus-next "insert-* tests" 10))) (map-channel (lambda (y) 1.0) 0 10 ind 0) (insert-float-vector (make-float-vector 5 .1) 2) (if (not (= (framples ind) 15)) (snd-display #__line__ ";insert-float-vector len: ~A" (framples ind))) (let ((vals (channel->float-vector 0 #f ind 0))) (if (not (vequal vals (float-vector 1 1 .1 .1 .1 .1 .1 1 1 1 1 1 1 1 1))) (snd-display #__line__ ";insert-float-vector vals: ~A" vals))) (let ((tag (catch #t (lambda () (insert-float-vector 32)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";insert-float-vector bad arg: ~A" tag))) (insert-float-vector (make-float-vector 1 1.5) 0 1 ind 0) (if (not (= (framples ind) 16)) (snd-display #__line__ ";insert-float-vector 1 len: ~A" (framples ind))) (let ((vals (channel->float-vector 0 #f ind 0))) (if (not (vequal vals (float-vector 1.5 1 1 .1 .1 .1 .1 .1 1 1 1 1 1 1 1 1))) (snd-display #__line__ ";insert-float-vector 1 vals: ~A" vals))) (close-sound ind)) (let ((ind (new-sound "test.snd" 4 22050 mus-ldouble mus-next "insert-* tests" 5))) (map-channel (lambda (y) 0.4) 0 5 ind 0) (map-channel (lambda (y) 0.5) 0 5 ind 1) (map-channel (lambda (y) 0.6) 0 5 ind 2) (map-channel (lambda (y) 0.7) 0 5 ind 3) (insert-float-vector (make-float-vector 20 .1) 2 2 ind 2) (if (not (= (framples ind 0) 5)) (snd-display #__line__ ";4chn insert-float-vector (0) len: ~A" (framples ind 0))) (if (not (= (framples ind 2) 7)) (snd-display #__line__ ";4chn insert-float-vector (2) len: ~A" (framples ind 2))) (if (not (vequal (channel->float-vector 0 7 ind 0) (float-vector .4 .4 .4 .4 .4 0 0))) (snd-display #__line__ ";4chn insert-float-vector 0: ~A" (channel->float-vector 0 7 ind 0))) (if (not (vequal (channel->float-vector 0 7 ind 1) (float-vector .5 .5 .5 .5 .5 0 0))) (snd-display #__line__ ";4chn insert-float-vector 1: ~A" (channel->float-vector 0 7 ind 1))) (if (not (vequal (channel->float-vector 0 7 ind 2) (float-vector .6 .6 .1 .1 .6 .6 .6))) (snd-display #__line__ ";4chn insert-float-vector 2: ~A" (channel->float-vector 0 7 ind 2))) (if (not (vequal (channel->float-vector 0 7 ind 3) (float-vector .7 .7 .7 .7 .7 0 0))) (snd-display #__line__ ";4chn insert-float-vector 3: ~A" (channel->float-vector 0 7 ind 3))) (insert-float-vector (make-float-vector 20 .2) 0 2 ind 0) (if (not (= (framples ind 0) 7)) (snd-display #__line__ ";4chn insert-float-vector (0 0) len: ~A" (framples ind 0))) (if (not (= (framples ind 1) 5)) (snd-display #__line__ ";4chn insert-float-vector (0 1) len: ~A" (framples ind 1))) (if (not (= (framples ind 2) 7)) (snd-display #__line__ ";4chn insert-float-vector (2 2) len: ~A" (framples ind 2))) (if (not (vequal (channel->float-vector 0 7 ind 0) (float-vector .2 .2 .4 .4 .4 .4 .4))) (snd-display #__line__ ";4chn insert-float-vector 1 0: ~A" (channel->float-vector 0 7 ind 0))) (if (not (vequal (channel->float-vector 0 7 ind 1) (float-vector .5 .5 .5 .5 .5 0 0))) (snd-display #__line__ ";4chn insert-float-vector 1 1: ~A" (channel->float-vector 0 7 ind 1))) (if (not (vequal (channel->float-vector 0 7 ind 2) (float-vector .6 .6 .1 .1 .6 .6 .6))) (snd-display #__line__ ";4chn insert-float-vector 1 2: ~A" (channel->float-vector 0 7 ind 2))) (if (not (vequal (channel->float-vector 0 7 ind 3) (float-vector .7 .7 .7 .7 .7 0 0))) (snd-display #__line__ ";4chn insert-float-vector 1 3: ~A" (channel->float-vector 0 7 ind 3))) (revert-sound ind) (map-channel (lambda (y) 0.4) 0 5 ind 0) (map-channel (lambda (y) 0.5) 0 5 ind 1) (map-channel (lambda (y) 0.6) 0 5 ind 2) (map-channel (lambda (y) 0.7) 0 5 ind 3) (close-sound ind)) (let ((ind (new-sound "test.snd" 4 22050 mus-ldouble mus-next "mix-* tests" 5))) (map-channel (lambda (y) 0.4) 0 5 ind 0) (map-channel (lambda (y) 0.5) 0 5 ind 1) (map-channel (lambda (y) 0.6) 0 5 ind 2) (map-channel (lambda (y) 0.7) 0 5 ind 3) (revert-sound ind) (map-channel (lambda (y) 0.4) 0 5 ind 0) (map-channel (lambda (y) 0.5) 0 5 ind 1) (map-channel (lambda (y) 0.6) 0 5 ind 2) (map-channel (lambda (y) 0.7) 0 5 ind 3) (close-sound ind)) ;; tests from clean.scm (test-remove-single-clicks) (test-remove-pops) (test-notch-hum) (test-remove-DC) ;; check 0 cases (let ((ind (open-sound "oboe.snd"))) (scale-by 0.0) (if (fneq (maxamp) 0.0) (snd-display #__line__ ";scale-by 0 amp: ~A" (maxamp))) (scale-by 3.0) (if (not (= (edit-position) 1)) (snd-display #__line__ ";scale-by over 0: ~A" (edit-position))) (scale-to 1.0) (if (not (= (edit-position) 1)) (snd-display #__line__ ";scale-to 1.0 over 0: ~A" (edit-position))) (if (fneq (maxamp) 0.0) (snd-display #__line__ ";scale-to 1.0 over 0 amp: ~A" (maxamp))) (ramp-channel 0 1) (if (not (= (edit-position) 1)) (snd-display #__line__ ";ramp over 0: ~A" (edit-position))) (env-channel '(0 0 1 1 2 0)) (if (not (= (edit-position) 1)) (snd-display #__line__ ";ramp over 0: ~A" (edit-position))) (if (not (string=? (car (edit-fragment 1)) "scale-channel 0.000 0 #f")) (snd-display #__line__ ";ramp over 0 clobbered origin: ~A" (edit-fragment 1))) (xramp-channel 0 1 32.0) (if (not (= (edit-position) 1)) (snd-display #__line__ ";ramp over 0: ~A" (edit-position))) (env-channel-with-base '(0 0 1 1 2 0 3 1) 0.0) (if (not (= (edit-position) 1)) (snd-display #__line__ ";ramp over 0: ~A" (edit-position))) (close-sound ind)) ;; snddiff.scm (let ((ind0 (open-sound "oboe.snd")) (ind1 (open-sound "oboe.snd"))) (let ((diff (snddiff ind0 0 ind1 0))) (if (not (eq? diff 'no-difference)) (snd-display #__line__ ";snddiff of same sound: ~A" diff))) (scale-channel 2.0 0 #f ind1) (let ((diff (snddiff ind0 0 ind1 0))) (if (or (not (eq? (car diff) 'scale)) (fneq (cadr diff) 2.0)) (snd-display #__line__ ";snddiff scale by 2: ~A" diff))) (revert-sound ind1) (set! (sample 100 ind0 0) 1.0) (let* ((diff (snddiff ind0 0 ind1 0)) (info (and diff (list? diff) (= (length diff) 2) (= (length (car (cadr diff))) 3) (car (cadr diff))))) (if (or (not (eq? (car diff) 'differences)) (not info) (not (= (car info) 100)) (fneq (cadr info) 1.0) (fneq (caddr info) -3.051e-4)) (snd-display #__line__ ";snddiff change sample 100: ~A" diff))) (revert-sound ind0) (pad-channel 0 100 ind0 0) (let ((diff (snddiff ind0 0 ind1 0))) (if (or (not (eq? (diff 0) 'lag)) (not (= (diff 1) 100)) (not (eq? (diff 2) 'no-difference)) (fneq (diff 3) 0.0) (diff 4) (diff 5) (diff 6)) (snd-display #__line__ ";snddiff + lag: ~A" diff))) (revert-sound ind0) (filter-channel (float-vector 1.0 0.5 0.25) 3 0 #f ind1 0) (let* ((diff (snddiff ind0 0 ind1 0)) (info (and (cadr diff) (= (length (cadr diff)) 3) (cadr diff)))) (if (or (not (list? info)) (not (list? diff)) (not (eq? (car diff) 'filter)) (fneq (caar info) 1.0) (fneq (caadr info) 0.5) (fneq (caaddr info) 0.25) (not (= (cadar info) 0)) (not (= (cadadr info) 1)) (not (= (cadr (caddr info)) 1))) (snd-display #__line__ ";snddiff filter: ~A ~A" diff info))) (revert-sound ind1) (close-sound ind0) (close-sound ind1)) (let ((ind (open-sound "oboe.snd"))) (let ((g550 (goertzel-channel 550.0)) (g1700 (goertzel-channel 1700.0))) (if (> (* 1000 g1700) g550) (snd-display #__line__ ";goertzel-channel oboe: ~A ~A" g550 g1700)) (close-sound ind))) )) ;;; ---------------- test 21: optimizer ---------------- (define (snd_test_21) (let () (define (for-each-permutation func vals) ; for-each-combination -- use for-each-subset below "(for-each-permutation func vals) applies func to every permutation of vals" ;; (for-each-permutation (lambda args (format-logged #t "~{~A~^ ~}~%" args)) '(1 2 3)) (define (pinner cur nvals len) (if (= len 1) (apply func (cons (car nvals) cur)) (do ((i 0 (+ i 1))) ; I suppose a named let would be more Schemish ((= i len)) (let ((start nvals)) (set! nvals (cdr nvals)) (let ((cur1 (cons (car nvals) cur))) ; add (car nvals) to our arg list (set! (cdr start) (cdr nvals)) ; splice out that element and (pinner cur1 (cdr start) (- len 1)) ; pass a smaller circle on down (set! (cdr start) nvals)))))) ; restore original circle (let ((len (length vals))) (set-cdr! (list-tail vals (- len 1)) vals) ; make vals into a circle (pinner () vals len) (set-cdr! (list-tail vals (- len 1)) ()))) ; restore its original shape (define (for-each-subset func args) (define (subset source dest len) (if (null? source) (if (aritable? func len) (apply func dest)) (begin (subset (cdr source) (cons (car source) dest) (+ len 1)) (subset (cdr source) dest len)))) (subset args () 0)) (define-macro (test tst expected) `(let ((val ,tst)) (if (not (morally-equal? val ,expected)) (format *stderr* "~S: ~S but expected ~S~%" ',tst val ,expected)))) (define (fv0) (let ((fv (make-float-vector 3)) (g (make-oscil 1000))) (do ((i 0 (+ i 1))) ((= i 3) fv) (float-vector-set! fv i (oscil g))))) (test (fv0) (float-vector 0.0 0.1419943179576268 0.2811111133316549)) (define (fv00) (let ((fv (make-float-vector 3)) (g (make-oscil 1000))) (do ((i 0 (+ i 1))) ((= i 3) fv) (set! (fv i) (oscil g))))) (test (fv00) (float-vector 0.0 0.1419943179576268 0.2811111133316549)) (define (fv01) (let ((fv (make-float-vector 3)) (g (make-oscil 1000))) (do ((i 0 (+ i 1))) ((= i 5) fv) (float-vector-set! fv i (oscil g))))) (test (catch #t fv01 (lambda args (apply format #f (cadr args)))) ; float-vector-set! argument 2, 3, is out of range (it is too large) "float-vector-set! argument 2, 3, is out of range (it is too large)") (define (fv02) (let ((fv (make-float-vector 3)) (g (make-oscil 1000))) (do ((i 0 (+ i 1/2))) ((= i 2) fv) (float-vector-set! fv i (oscil g))))) (test (catch #t (lambda () (display (fv02)) (newline)) (lambda args (apply format #f (cadr args)))) ; float-vector-set! argument 2, 1/2, is a ratio but should be an integer "float-vector-set! argument 2, 1/2, is a ratio but should be an integer") ;; (+ (* s1 s2) (* (- 1.0 s1) s3)) (define (fv1 s1 s2 s3) (let ((fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (float-vector-set! fv i (+ (* s1 s2) (* (- 1.0 s1) s3)))))) (test (fv1 1 2 3) (float-vector 2.0 2.0 2.0 2.0)) (test (fv1 2 3 4) (float-vector 2.0 2.0 2.0 2.0)) (test (fv1 1.0 2.0 3.0) (float-vector 2.0 2.0 2.0 2.0)) (test (fv1 2.0 3.0 4.0) (float-vector 2.0 2.0 2.0 2.0)) (test (fv1 1/2 5/4 3/4) (float-vector 1.0 1.0 1.0 1.0)) (test (catch #t (lambda () (fv1 1+i 2+2i 3+3i)) ; 'error? -- 3+i (lambda args (apply format #f (cadr args)))) ; float-vector-set! argument 3, 3+1i, is a complex number but should be a real "float-vector-set! argument 3, 3+1i, is a complex number but should be a real") (define (fv2 s1 s2 s3) (let ((fv (make-float-vector 4))) (do ((i 0 (+ i 1)) (x 1.0 (+ x 0+i))) ((= i 4) fv) (float-vector-set! fv i (+ (* x s2) (* (- 1.0 x) s3)))))) (test (catch #t (lambda () (fv2 1 2 3)) ; 'error again #(2.0 2-1i 2-2i 2-3i) (lambda args (car args))) 'wrong-type-arg) (set! (*s7* 'print-length) 123) (define (fv3) (let ((gens (vector (make-oscil 100) (make-oscil 200 1.7) (make-oscil 300 5.0)))) (let ((fv (make-float-vector 3)) (iter (make-iterator gens))) (do ((i 0 (+ i 1)) (g (iterate iter) (iterate iter))) ((= i 3) fv) (float-vector-set! fv i (oscil g)))))) (test (fv3) (float-vector 0.0 0.9916648104524686 -0.9589242746631385)) (define (fv4) (let ((fv-a (make-float-vector 4)) (fv-b (make-float-vector 4)) (g (make-oscil 1000))) (do ((i 0 (+ i 1))) ((= i 4) (list fv-a fv-b)) (float-vector-set! fv-a i (float-vector-set! fv-b i (oscil g)))))) (test (fv4) (list (float-vector 0.0 0.1419943179576268 0.2811111133316549 0.4145311766902953) (float-vector 0.0 0.1419943179576268 0.2811111133316549 0.4145311766902953))) (define (fv5) (let ((fv-a (make-float-vector 4)) (g1 (make-oscil 1000)) (g2 (make-oscil 1000))) (do ((i 0 (+ i 1))) ((= i 4) fv-a) (float-vector-set! fv-a i (oscil g1 (oscil g2)))))) (test (fv5) (float-vector 0.0 0.1419943179576268 0.4140929109323406 0.7516320715399403)) (define (fv6) (let ((g1 (make-oscil 1000)) (g2 (make-oscil 1000))) (list (oscil g1 (oscil g2)) (oscil g1 (oscil g2)) (oscil g1 (oscil g2)) (oscil g1 (oscil g2))))) (test (fv6) '(0.0 0.1419943179576268 0.4140929109323406 0.7516320715399403)) (define (fv7) (let ((g0 (make-oscil 1000)) (g1 (make-oscil 1000)) (x 0.1)) (let ((fv (make-float-vector 6))) (do ((i 0 (+ i 1))) ((= i 3)) (float-vector-set! fv i (oscil g0 0.1))) (do ((i 3 (+ i 1))) ((= i 6)) (float-vector-set! fv i (oscil g1 x))) fv))) (test (fv7) (float-vector 0.0 0.2401067896488338 0.4661656420314379 0.0 0.2401067896488338 0.4661656420314379)) (define (fv8) (let ((g (make-oscil 1000))) (do ((i 0 (+ i 1))) ((= i 4)) (oscil g)) (oscil g))) (test (morally-equal? (fv8) 0.5395507431861811) #t) (define (fv9) (let ((g (make-oscil 1000))) (do ((i 0 (+ i 1))) ((= i 4)) (oscil g 0.1)) (oscil g 0.1))) (test (morally-equal? (fv9) 0.8248311180769614) #t) (define (fv10) (let ((fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (float-vector-set! fv i (* i i))))) (test (fv10) (float-vector 0.0 1.0 4.0 9.0)) (define (fv11) (let ((fv (make-float-vector 4)) (g0 (make-oscil 1000)) (g1 (make-oscil 1000))) (do ((i 0 (+ i 1))) ((= i 4) fv) (float-vector-set! fv i (* (oscil g0) (oscil g1)))))) (test (fv11) (float-vector 0.0 0.02016238633225161 0.07902345803856255 0.1718360964482408)) (define (fv12) (let ((fv (make-float-vector 4)) (g0 (make-oscil 1000))) (do ((i 0 (+ i 1))) ((= i 4) fv) (float-vector-set! fv i (* 2.0 (oscil g0)))))) (test (fv12) (float-vector 0.0 0.2839886359152535 0.5622222266633099 0.8290623533805906)) (define (fv13) (let ((fv (make-float-vector 4)) (x 2.0) (g0 (make-oscil 1000))) (do ((i 0 (+ i 1))) ((= i 4) fv) (float-vector-set! fv i (* (oscil g0) x))))) (test (fv13) (float-vector 0.0 0.2839886359152535 0.5622222266633099 0.8290623533805906)) (define (fv14) (let ((fv (make-float-vector 4)) (g0 (make-oscil 1000)) (g1 (make-oscil 1000)) (s0 2.0) (s1 3.0)) (do ((i 0 (+ i 1))) ((= i 4) fv) (float-vector-set! fv i (* s0 (oscil g0 (* s1 (oscil g1)))))))) (test (fv14) (float-vector 0.0 0.2839886359152535 1.305084606281564 1.984158175327229)) (define (fv15) (let ((fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (float-vector-set! fv i (+ i i))))) (test (fv15) (float-vector 0.0 2.0 4.0 6.0)) (define (fv16) (let ((fv (make-float-vector 4)) (g0 (make-oscil 1000)) (g1 (make-oscil 1000))) (do ((i 0 (+ i 1))) ((= i 4) fv) (float-vector-set! fv i (+ (oscil g0) (oscil g1)))))) (test (fv16) (float-vector 0.0 0.2839886359152535 0.5622222266633099 0.8290623533805906)) (define (fv17) (let ((fv (make-float-vector 4)) (g0 (make-oscil 1000))) (do ((i 0 (+ i 1))) ((= i 4) fv) (float-vector-set! fv i (+ 2.0 (oscil g0)))))) (test (fv17) (float-vector 2.0 2.141994317957627 2.281111113331655 2.414531176690295)) (define (fv18) (let ((fv (make-float-vector 4)) (x 2.0) (g0 (make-oscil 1000))) (do ((i 0 (+ i 1))) ((= i 4) fv) (float-vector-set! fv i (+ (oscil g0) x))))) (test (fv18) (float-vector 2.0 2.141994317957627 2.281111113331655 2.414531176690295)) (define (fv19) (let ((fv (make-float-vector 4)) (g0 (make-oscil 1000)) (g1 (make-oscil 1000)) (s0 2.0) (s1 3.0)) (do ((i 0 (+ i 1))) ((= i 4) fv) (float-vector-set! fv i (+ s0 (oscil g0 (* s1 (oscil g1)))))))) (test (fv19) (float-vector 2.0 2.141994317957627 2.652542303140782 2.992079087663615)) (define (fv20) (let ((fv (make-float-vector 4)) (g0 (make-oscil 1000)) (g1 (make-oscil 1000)) (g2 (make-oscil 1000))) (do ((i 0 (+ i 1))) ((= i 4) fv) (float-vector-set! fv i (+ (oscil g0) (oscil g1) (oscil g2)))))) (test (fv20) (float-vector 0.0 0.4259829538728803 0.8433333399949648 1.243593530070886)) (define (fv21) (let ((fv (make-float-vector 4)) (g0 (make-oscil 1000)) (g1 (make-oscil 1000)) (s1 1.0)) (do ((i 0 (+ i 1))) ((= i 4) fv) (float-vector-set! fv i (+ (oscil g0) (oscil g1) s1))))) (test (fv21) (float-vector 1.0 1.283988635915253 1.56222222666331 1.829062353380591)) (define (fv22) (let ((fv (make-float-vector 4)) (g0 (make-oscil 1000)) (g1 (make-oscil 1000))) (do ((i 0 (+ i 1))) ((= i 4) fv) (float-vector-set! fv i (+ (oscil g0) 1.0 (oscil g1)))))) (test (fv22) (float-vector 1.0 1.283988635915253 1.56222222666331 1.829062353380591)) (define (fv23) (let ((fv (make-float-vector 4)) (g0 (make-oscil 1000)) (s1 1.0)) (do ((i 0 (+ i 1))) ((= i 4) fv) (float-vector-set! fv i (+ s1 1.0 (oscil g0)))))) (test (fv23) (float-vector 2.0 2.141994317957627 2.281111113331655 2.414531176690295)) (define (fv24) (let ((fv (make-float-vector 4)) (g0 (make-oscil 1000)) (s1 1.0) (s2 2.0)) (do ((i 0 (+ i 1))) ((= i 4) fv) (float-vector-set! fv i (+ s1 (oscil g0) s2))))) (test (fv24) (float-vector 3.0 3.141994317957627 3.281111113331655 3.414531176690295)) (define (fv25) (let ((fv (make-float-vector 4)) (g0 (make-oscil 1000)) (s1 1.0) (s2 2.0)) (do ((i 0 (+ i 1))) ((= i 4) fv) (float-vector-set! fv i (+ s1 s2 (oscil g0)))))) (test (fv25) (float-vector 3.0 3.141994317957627 3.281111113331655 3.414531176690295)) (define (fv26) (let ((fv (make-float-vector 4)) (g0 (make-oscil 1000)) (s1 1.0) (s2 2.0)) (do ((i 0 (+ i 1))) ((= i 4) fv) (float-vector-set! fv i (+ (oscil g0) s1 s2))))) (test (fv26) (float-vector 3.0 3.141994317957627 3.281111113331655 3.414531176690295)) (define (fv27) (let ((fv (make-float-vector 4)) (s3 4.0) (s1 1.0) (s2 2.0)) (do ((i 0 (+ i 1))) ((= i 4) fv) (float-vector-set! fv i (+ s3 s1 s2))))) (test (fv27) (float-vector 7.0 7.0 7.0 7.0)) (define (fv28) (let ((fv (make-float-vector 4)) (s1 1.0) (s2 2.0)) (do ((i 0 (+ i 1))) ((= i 4) fv) (float-vector-set! fv i (+ 4.0 s1 s2))))) (test (fv28) (float-vector 7.0 7.0 7.0 7.0)) (define (fv29) (let ((fv (make-float-vector 4)) (s1 1.0) (s2 2.0)) (do ((i 0 (+ i 1))) ((= i 4) fv) (float-vector-set! fv i (+ s1 s2 4.0))))) (test (fv29) (float-vector 7.0 7.0 7.0 7.0)) (define (fv30) (let ((fv (make-float-vector 4)) (g0 (make-oscil 1000)) (g1 (make-oscil 1000)) (g2 (make-oscil 1000))) (do ((i 0 (+ i 1))) ((= i 4) fv) (float-vector-set! fv i (* (oscil g0) (oscil g1) (oscil g2)))))) (test (fv30) (float-vector 0.0 0.002862944295646243 0.02221437226853764 0.07123141925855635)) (define (fv31) (let ((fv (make-float-vector 4)) (g0 (make-oscil 1000 4.0))) (do ((i 0 (+ i 1))) ((= i 4) fv) (float-vector-set! fv i (abs (oscil g0)))))) (test (fv31) (float-vector 0.7568024953079282 0.8419478535558946 0.9100310927158114 0.9596725022396432)) (define (fv32) (let ((fv (make-float-vector 4)) (s0 -1.5)) (do ((i 0 (+ i 1))) ((= i 4) fv) (float-vector-set! fv i (abs s0))))) (test (fv32) (float-vector 1.5 1.5 1.5 1.5)) (define (fv31a) (let ((g0 (make-oscil 1000)) (fv (make-float-vector 4)) (g1 (make-oscil 1000))) (do ((i 0 (+ i 1))) ((= i 4) fv) (let ((x (oscil g0))) (float-vector-set! fv i (oscil g1 x)))))) (test (fv31a) (float-vector 0.0 0.1419943179576268 0.4140929109323406 0.7516320715399403)) (define (fv32a) (let ((g0 (make-oscil 1000)) (fv (make-float-vector 4)) (g1 (make-oscil 1000))) (do ((i 0 (+ i 1))) ((= i 4) fv) (let ((x (oscil g0))) (float-vector-set! fv i (oscil g1 x)))))) (test (fv32a) (float-vector 0.0 0.1419943179576268 0.4140929109323406 0.7516320715399403)) (define (fv33) (let ((g0 (make-oscil 1000)) (fv (make-float-vector 4)) (g1 (make-oscil 1000))) (do ((i 0 (+ i 1))) ((= i 4) fv) (let ((x (oscil g0)) (y (oscil g0))) (float-vector-set! fv i (* y (oscil g1 x))))))) (test (fv33) (float-vector 0.0 0.05886107170631096 0.3505537450231597 0.7966641560805439)) (define (fv34) (let ((g0 (make-oscil 1000)) (fv (make-float-vector 4)) (g1 (make-oscil 1000))) (do ((i 0 (+ i 1))) ((= i 4) fv) (let* ((x (oscil g0)) (y (oscil g0))) (float-vector-set! fv i (* y (oscil g1 x))))))) (test (fv34) (float-vector 0.0 0.05886107170631096 0.3505537450231597 0.7966641560805439)) (define (fv35) (let ((g0 (make-oscil 1000)) (fv (make-float-vector 4)) (g1 (make-oscil 1000))) (do ((i 0 (+ i 1))) ((= i 4) fv) (let* ((x (oscil g0)) (y x)) (float-vector-set! fv i (+ y (oscil g1))))))) (test (fv35) (float-vector 0.0 0.2839886359152535 0.5622222266633099 0.8290623533805906)) (define (fv36) (let ((g0 (make-oscil 1000)) (fv (make-float-vector 4)) (g1 (make-oscil 1000)) (x 1.0)) (do ((i 0 (+ i 1))) ((= i 4) fv) (let ((x (oscil g0)) (y x)) (float-vector-set! fv i (+ y (oscil g1))))))) (test (fv36) (float-vector 1.0 1.141994317957627 1.281111113331655 1.414531176690295)) (define (fv37) (let ((g0 (make-oscil 1000)) (fv (make-float-vector 4)) (x0 1.0)) (do ((i 0 (+ i 1))) ((= i 4) fv) (float-vector-set! fv i (odd-weight (+ x0 (oscil g0))))))) (test (fv37) (float-vector 1.0 0.8580056820423732 0.7188888866683452 0.5854688233097047)) (define (fv38) (let ((g0 (make-oscil 1000)) (fv (make-float-vector 4)) (x0 1.0)) (do ((i 0 (+ i 1))) ((= i 4) fv) (float-vector-set! fv i (even-weight (+ x0 (oscil g0))))))) (test (fv38) (float-vector 0.0 0.1419943179576268 0.2811111133316548 0.4145311766902953)) (define (fv39) (let ((g0 (make-oscil 1000)) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (float-vector-set! fv i (max (oscil g0) 0.25))))) (test (fv39) (float-vector 0.25 0.25 0.2811111133316549 0.4145311766902953)) (define (fv40) (let ((g0 (make-file->sample "oboe.snd")) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (float-vector-set! fv i (ina i g0))))) (test (fv40) (float-vector 0.0 -0.00030517578125 -0.00030517578125 -0.000274658203125)) (define (fv41) (let ((g0 (make-float-vector 3 0.5)) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (float-vector-set! fv i (ina i g0))))) (test (fv41) (float-vector 0.5 0.5 0.5 0.0)) (define (fv42) (let ((g0 (make-float-vector 3 0.5)) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (float-vector-set! fv i (- (ina i g0)))))) (test (fv42) (float-vector -0.5 -0.5 -0.5 0.0)) (define (fv43) (let ((g0 (make-float-vector 3 0.5)) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (float-vector-set! fv i (- i))))) (test (fv43) (float-vector 0 -1 -2 -3)) (define (permute op . args) (let ((body (copy `(let () (define (t1) (let ((x 1.5) (y 3.5) (g0 (make-oscil 1000)) (g1 (make-oscil 2000)) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (float-vector-set! fv i (,op ,@args))))) (define (t2) (let ((x 1.5) (y 3.5) (g0 (make-oscil 1000)) (g1 (make-oscil 2000)) (v (make-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) v) (vector-set! v i (,op ,@args))))) (let ((v1 (t1)) (v2 (copy (t2) (make-float-vector 4)))) (if (not (morally-equal? v1 v2)) (format *stderr* "~D: ~A -> ~A ~A~%" #__line__ args v1 v2)))) :readable))) (eval body))) (set! (*s7* 'morally-equal-float-epsilon) 1e-12) (for-each (lambda (op) (for-each-subset (lambda s-args (if (pair? s-args) (for-each-permutation (lambda args (apply permute op args)) s-args))) (list 'x '(oscil g0) 2.0 '(oscil g1) 'y))) (list '+ '* '-)) (for-each-subset (lambda s-args (if (pair? s-args) (for-each-permutation (lambda args (apply permute '/ args)) s-args))) (list 'x '(+ .01 (oscil g0)) 2.0 '(+ .01 (oscil g1)) 'y)) (define (fv44) (let ((g0 (make-float-vector 3 1.0)) (fv (make-float-vector 4)) (x 2.0)) (do ((i 0 (+ i 1))) ((= i 4) fv) (float-vector-set! fv i (polynomial g0 x))))) (test (fv44) (float-vector 7.0 7.0 7.0 7.0)) (define (fv45) (let ((g0 (make-float-vector 3 1.0)) (fv (make-float-vector 4)) (x (make-oscil 1000))) (do ((i 0 (+ i 1))) ((= i 4) fv) (float-vector-set! fv i (polynomial g0 (* 2.0 (oscil x))))))) (test (fv45) (float-vector 1.0 1.36463818124426 1.87831605881756 2.516406739173554)) (define (fv46) (let ((g0 (make-float-vector 4 1.0)) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (float-vector-set! fv i (float-vector-ref g0 i))))) (test (fv46) (float-vector 1.0 1.0 1.0 1.0)) (define (fv47) (let ((g0 (make-oscil 1000)) (fv (make-float-vector 4)) (x 1.0)) (do ((i 0 (+ i 1))) ((= i 4) fv) (float-vector-set! fv i (amplitude-modulate 1.0 x (oscil g0)))))) (test (fv47) (float-vector 1.0 1.141994317957627 1.281111113331655 1.414531176690295)) (define (fv48) (let ((g0 (make-oscil 1000)) (fv (make-float-vector 4)) (x 1.0)) (do ((i 0 (+ i 1))) ((= i 4) fv) (float-vector-set! fv i (remainder (* 10 (oscil g0)) 1.0))))) (test (fv48) (float-vector 0.0 0.4199431795762676 0.8111111333165493 0.1453117669029531)) (define (fv49) (let ((g0 (float-vector 1 2 3 4 5 6)) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (float-vector-set! fv i (float-vector-ref g0 (+ i 2)))))) (test (fv49) (float-vector 3 4 5 6)) (define (fv49) (let ((fv (make-float-vector 4)) (g0 (make-oscil 1000)) (g1 (make-oscil 1000)) (g2 (make-oscil 1000)) (g3 (make-oscil 1000))) (do ((i 0 (+ i 1))) ((= i 4) fv) (float-vector-set! fv i (+ (oscil g0) (oscil g1) (oscil g2) (oscil g3)))))) (test (fv49) (float-vector 0.0 0.5679772718305071 1.12444445332662 1.658124706761181)) (define (fv50) (let ((iv (int-vector 0 1 2 3 4 5 6)) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (float-vector-set! fv (vector-ref iv i) 1.0)))) (test (fv50) (float-vector 1.0 1.0 1.0 1.0)) (define (fv51) (let ((fv (make-float-vector 4)) (g (make-oscil 1000))) (do ((i 0 (+ i 1))) ((> i 4) fv) (float-vector-set! fv i (oscil g))))) (test (catch #t fv51 (lambda args (car args))) 'out-of-range) (define (fv52) (let ((fv (make-float-vector 4)) (g (make-oscil 1000))) (do ((i 0 (+ i 1.1))) ((= i 4) fv) (float-vector-set! fv i (oscil g))))) (test (catch #t fv52 (lambda args (car args))) 'wrong-type-arg) (define (fv53) (let ((fv (make-float-vector 4)) (g (make-oscil 1000))) (do ((i 0 (+ i 2))) ((= i 3) fv) (float-vector-set! fv i (oscil g))))) (test (catch #t fv53 (lambda args (car args))) 'out-of-range) (define (fv54) (let ((fv (make-float-vector 4)) (g (make-oscil 1000))) (do ((i 0 (+ i 1)) (x 0.0 (+ x 0.1))) ((> i 4) fv) (float-vector-set! fv i (oscil g))))) (test (catch #t fv54 (lambda args (car args))) 'out-of-range) (define (fv55) (let ((fv (make-float-vector 4)) (g (make-oscil 1000))) (do ((i 0 (+ i 1.1)) (x 0.0 (+ x 0.1))) ((= i 4) fv) (float-vector-set! fv i (oscil g))))) (test (catch #t fv55 (lambda args (car args))) 'wrong-type-arg) (define (fv56) (let ((fv (make-float-vector 4)) (g (make-oscil 1000))) (do ((i 0 (+ i 2)) (x 0.0 (+ x 0.1))) ((= i 3) fv) (float-vector-set! fv i (oscil g))))) (test (catch #t fv56 (lambda args (car args))) 'out-of-range) (define (fv57) (let ((g (make-oscil 1000)) (e (make-env '(0 0 1 1) :length 5)) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (float-vector-set! fv i (* (env e) (oscil g)))))) (test (fv57) (float-vector 0.0 0.03549857948940669 0.1405555566658275 0.3108983825177215)) (define (fv58) (let ((fv (make-float-vector 4)) (g (make-oscil 1000))) (do ((i 0 (+ i 1))) ((= i 4) fv) (let ((j i)) ; no rf here (float-vector-set! fv j (oscil g)))))) (test (fv58) (float-vector 0.0 0.1419943179576268 0.2811111133316549 0.4145311766902953)) (define (fv59) (let ((fv (make-float-vector 4)) (g (make-oscil 1000))) (do ((i 0 (+ i 1))) ((= i 4) fv) (let ((j (abs i))) ; j is not an integer! so is_fv_set_rf rejects it -- yow (float-vector-set! fv j (oscil g)))))) (test (fv59) (float-vector 0.0 0.1419943179576268 0.2811111133316549 0.4145311766902953)) (define (fv60) (let ((xv (float-vector 0 1 2 3 4)) (fv (make-float-vector 4)) (g (make-oscil 1000)) (len 5)) (do ((i 0 (+ i 1))) ((= i 4) fv) (float-vector-set! fv i (array-interp xv (* 4 (abs (oscil g))) len))))) (test (fv60) (float-vector 0.0 0.5679772718305071 1.12444445332662 1.658124706761181)) (define (fv60a) (let ((xv (float-vector 0 1 2 3 4)) (fv (make-float-vector 4)) (g (make-oscil 1000)) (len 5)) (do ((i 0 (+ i 1))) ((= i 4) fv) (float-vector-set! fv i (array-interp xv (* 4 (abs (oscil g))) len))))) (test (fv60a) (float-vector 0.0 0.5679772718305071 1.12444445332662 1.658124706761181)) (define (fv61) (let ((fv (make-float-vector 4)) (g (make-oscil 1000))) (do ((i 0 (+ i 1))) ((= i 4) fv) (float-vector-set! fv i (+ (oscil g) (oscil g)))))) (test (fv61) (float-vector 0.1419943179576268 0.6956422900219503 1.193187027684375 1.594501774071586)) (define (fv62) (let ((fv (make-float-vector 4)) (g (make-oscil 1000)) (x .1)) (do ((i 0 (+ i 1))) ((= i 4) fv) (float-vector-set! fv i (+ (oscil g) (oscil g x)))))) (test (fv62) (float-vector 0.1419943179576268 0.8788265473477139 1.4870276868047 1.877577239959861)) (define (fv63) (let ((fv (make-float-vector 4)) (g (make-oscil 1000)) (x .1)) (do ((i 0 (+ i 1))) ((= i 4) fv) (float-vector-set! fv i (+ (oscil g x) (oscil g)))))) (test (fv63) (float-vector 0.2401067896488338 0.962578603769539 1.544160801705073 1.899729018207357)) (define (fv64) (set! (mus-rand-seed) 1234) (let ((fv (make-float-vector 10)) (e (make-env '(0 0 1 1) :length 10)) (r (make-rand-interp 1000 .1))) (do ((i 0 (+ i 1))) ((= i 10) fv) (float-vector-set! fv i (+ (env e) (rand-interp r)))))) (test (fv64) (float-vector -0.001775140394296145 0.1075608303225188 0.2168968010393338 0.3262327717561487 0.4355687424729637 0.5449047131897787 0.6542406839065937 0.7635766546234087 0.8729126253402237 0.9822485960570387)) (define (fv65) (set! (mus-rand-seed) 1234) (let ((fv (make-float-vector 10)) (e (make-triangle-wave 1000 .5)) (r (make-rand-interp 1000 .1))) (do ((i 0 (+ i 1))) ((= i 10) fv) (float-vector-set! fv i (+ (triangle-wave e) (rand-interp r)))))) (test (fv65) (float-vector -0.001775140394296145 0.0418011931343102 0.08537752666291655 0.1289538601915229 0.1725301937201293 0.2161065272487356 0.2596828607773419 0.3032591943059482 0.3468355278345545 0.3904118613631609)) (define (fv66) (let ((fv (make-float-vector 8)) (gv (make-vector 8)) (g0 (make-oscil 1000)) (g1 (make-oscil 1000))) (do ((i 0 (+ i 2))) ((= i 8)) (set! (gv i) g0) (set! (gv (+ i 1)) g1)) (do ((i 0 (+ i 1))) ((= i 8) fv) (float-vector-set! fv i (oscil (vector-ref gv i)))))) (test (fv66) (float-vector 0.0 0.0 0.1419943179576268 0.1419943179576268 0.2811111133316549 0.2811111133316549 0.4145311766902953 0.4145311766902953)) (define (fv67) (let ((fv (make-float-vector 8)) (g (make-oscil 1000)) (v (make-vector 8))) (fill! v g) (do ((i 0 (+ i 1))) ((= i 8) fv) (float-vector-set! fv i (oscil (vector-ref v i)))))) (test (fv67) (float-vector 0.0 0.1419943179576268 0.2811111133316549 0.4145311766902953 0.5395507431861811 0.6536362844981936 0.7544758509208143 0.8400259231507713)) (define (fv68) (let ((fv (make-float-vector 8)) (gv (make-vector 8)) (g0 (make-oscil 1000)) (g1 (make-oscil 1000)) (x .1)) (do ((i 0 (+ i 2))) ((= i 8)) (set! (gv i) g0) (set! (gv (+ i 1)) g1)) (do ((i 0 (+ i 1))) ((= i 8) fv) (float-vector-set! fv i (oscil (vector-ref gv i) x))))) (test (fv68) (float-vector 0.0 0.0 0.2401067896488338 0.2401067896488338 0.4661656420314379 0.4661656420314379 0.6649505230927522 0.6649505230927522)) (define (fv69) (let ((fv (make-float-vector 4)) (g (make-formant 440 .9)) (e (make-env '(0 440 1 880) :length 10))) (do ((i 0 (+ i 1))) ((= i 4) fv) (float-vector-set! fv i (mus-set-formant-frequency g (env e)))))) (test (fv69) (float-vector 440.0 488.8888888888889 537.7777777777778 586.6666666666667)) (define (fv70) (let ((fv1 (make-float-vector 4)) (fv2 (make-float-vector 4)) (g1 (make-oscil 1000)) (g2 (make-oscil 1000)) (e (make-env '(0 2.0 1 2.0) :length 10))) (do ((i 0 (+ i 1))) ((= i 4) (list fv1 fv2)) (let ((x (env e))) (float-vector-set! fv1 i (oscil g1)) (float-vector-set! fv2 i (* x (oscil g2))))))) (test (fv70) (list (float-vector 0.0 0.1419943179576268 0.2811111133316549 0.4145311766902953) (float-vector 0.0 0.2839886359152535 0.5622222266633099 0.8290623533805906))) (define (fv71) (let ((fv (make-float-vector 8)) (gv (make-vector 8)) (g0 (make-env '(0 0 1 1) :length 5)) (g1 (make-env '(0 0 1 1) :length 5))) (do ((i 0 (+ i 2))) ((= i 8)) (set! (gv i) g0) (set! (gv (+ i 1)) g1)) (do ((i 0 (+ i 1))) ((= i 8) fv) (float-vector-set! fv i (env (vector-ref gv i)))))) (test (fv71) (float-vector 0.0 0.0 0.25 0.25 0.5 0.5 0.75 0.75)) (define (fv72) (let ((fv (make-float-vector 10)) (ls (make-list 10)) (g (make-square-wave 2205)) (x 0.0)) (let ((g (make-square-wave 2205))) (do ((i 0 (+ i 1))) ((= i 10)) (float-vector-set! fv i (+ (square-wave g) (square-wave g x))))) (let ((g (make-square-wave 2205))) (do ((i 0 (+ i 1))) ((= i 10)) (list-set! ls i (+ (square-wave g) (square-wave g x))))) (list fv ls))) (test (fv72) (list (float-vector 2.0 2.0 2.0 2.0 2.0 0.0 0.0 0.0 0.0 0.0) (list 2.0 2.0 2.0 2.0 2.0 0.0 0.0 0.0 0.0 0.0))) (define (fv73) (let ((fv (make-float-vector 10)) (ls (make-list 10)) (g (make-square-wave 2205)) (x 0.5)) (let ((g (make-square-wave 2205))) (do ((i 0 (+ i 1))) ((= i 10)) (float-vector-set! fv i (+ (square-wave g) (square-wave g x))))) (newline *stderr*) (let ((g (make-square-wave 2205))) (do ((i 0 (+ i 1))) ((= i 10)) (list-set! ls i (+ (square-wave g) (square-wave g x))))) (list fv ls))) (test (fv73) (list (float-vector 2.0 2.0 2.0 0.0 0.0 0.0 2.0 2.0 2.0 0.0) (list 2.0 2.0 2.0 0.0 0.0 0.0 2.0 2.0 2.0 0.0))) (define (fv74) (let ((fv (make-float-vector 4)) (g (make-r2k!cos 1000 :r 0.5 :k 3.0))) (do ((i 0 (+ i 1))) ((= i 4) fv) (float-vector-set! fv i (r2k!cos g))))) (test (fv74) (float-vector 0.008 0.01148666785741709 0.01717900881454179 0.02679348967895129)) (define (fv75) (let ((fv (make-float-vector 4)) (g (make-r2k!cos 1000 :r 0.5 :k 3.0))) (do ((i 0 (+ i 1))) ((= i 4) fv) (float-vector-set! fv i (r2k!cos g .1))))) (test (fv75) (float-vector 0.008 0.01517028252035849 0.03244495213443228 0.07802652038780451)) (define (fv76) (let ((fv (make-float-vector 4)) (g (make-r2k!cos 1000 :r 0.5 :k 3.0)) (x .1)) (do ((i 0 (+ i 1))) ((= i 4) fv) (float-vector-set! fv i (r2k!cos g x))))) (test (fv76) (float-vector 0.008 0.01517028252035849 0.03244495213443228 0.07802652038780451)) (define (fv77) (let ((fv (make-float-vector 4)) (g (make-r2k!cos 1000 :r 0.5 :k 3.0)) (x (make-env '(0 .1 1 .1) :length 10))) (do ((i 0 (+ i 1))) ((= i 4) fv) (float-vector-set! fv i (r2k!cos g (env x)))))) (test (fv77) (float-vector 0.008 0.01517028252035849 0.03244495213443228 0.07802652038780451)) (define (fv80) (let ((x 0.0)) (do ((i 0 (+ i 1))) ((= i 4) x) (set! x .1)))) (test (fv80) .1) (define (fv81) (let ((x 0.0)) (do ((i 0 (+ i 1)) (y .1 .1)) ((= i 4) x) (set! x y)))) (test (fv81) .1) (define (fv82) (let ((x 0.0) (y 0.1)) (do ((i 0 (+ i 1))) ((= i 4) x) (set! x y)))) (test (fv82) .1) (define (fv83) (let ((x 0.0) (y 0.1)) (do ((i 0 (+ i 1))) ((= i 4) x) (set! x (+ x y))))) (test (fv83) .4) (define (fv84) (let ((x 1.0)) (do ((i 0 (+ i 1))) ((= i 10) x) (set! x (+ x (* i 2.0)))))) (test (fv84) 91.0) (define (fv85) (let ((fv1 (make-float-vector 4 1.5)) (fv2 (make-float-vector 4 0.0))) (do ((i 0 (+ i 1))) ((= i 10) fv2) (float-vector-add! fv2 fv1)))) (test (fv85) (make-float-vector 4 15.0)) (define (fv86) (let ((g0 (make-float-vector 4 1.0)) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (g0 i))))) (test (fv86) (float-vector 1.0 1.0 1.0 1.0)) (define (fv87) (let ((fv1 (make-float-vector 4 1.5)) (fv2 (make-float-vector 4 0.0))) (do ((i 0 (+ i 1)) (j 0 (+ j 1))) ((= i 4) fv2) (float-vector-add! fv2 fv1) (float-vector-set! fv1 j 2.5)))) (test (fv87) (float-vector 9 8 7 6)) (define (fv88) (let ((fv (make-float-vector 4)) (ifv (make-float-vector 1)) (g (make-file->frample "oboe.snd"))) (do ((i 0 (+ i 1)) (j 1000 (+ j 1))) ((= i 4) fv) (file->frample g j ifv) (float-vector-set! fv i (ifv 0))))) (test (fv88) (float-vector 0.0328369140625 0.0347900390625 0.0340576171875 0.031036376953125)) (define (fv89) (let ((fv0 (make-float-vector 4)) (fv1 (make-float-vector 4)) (ifv (make-float-vector 2)) (g (make-file->frample "2.snd"))) (do ((i 0 (+ i 1)) (j 1000 (+ j 1))) ((= i 4) (list fv0 fv1)) (file->frample g j ifv) (float-vector-set! fv0 i (ifv 0)) (float-vector-set! fv1 i (ifv 1))))) (test (fv89) (list (float-vector 0.002227783203125 0.00634765625 0.00787353515625 0.007293701171875) (float-vector 0.004425048828125 0.012664794921875 0.015777587890625 0.014556884765625))) (define (fv90) (let ((fv (make-float-vector 4))) (do ((i 0 (+ i 1)) (x 1.0 (+ x 0.5))) ((= i 4) fv) (set! (fv i) x)))) (test (fv90) (float-vector 1.0 1.5 2.0 2.5)) (define (fv91) (let ((f1 (float-vector 1.0 2.0 3.0)) (f2 (float-vector 0.0 0.0 0.0)) (m1 (float-vector 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0)) (f1-len 3) (f2-len 3)) (do ((i 0 (+ i 1)) (x 0 (+ x 2))) ; currently needed to trigger optimizer ((= i 1) f2) (frample->frample m1 f1 f1-len f2 f2-len)))) (test (fv91) (float-vector 30.0 36.0 42.0)) (define (fv92) (let ((sf (make-frample->file "fmv.snd" 2 mus-lfloat mus-riff "this is a comment")) (fv (float-vector .1 .2)) (fv1 (make-float-vector 4)) (fv2 (make-float-vector 4))) (do ((i 0 (+ i 1)) (x 0 (+ x 2))) ((= i 4)) (frample->file sf i fv)) (mus-close sf) (list (file->array "fmv.snd" 0 0 4 fv1) (file->array "fmv.snd" 1 0 4 fv2)))) (let ((old-fudge (*s7* 'morally-equal-float-epsilon))) (set! (*s7* 'morally-equal-float-epsilon) 1e-5) (test (fv92) (list (make-float-vector 4 .1) (make-float-vector 4 .2))) (set! (*s7* 'morally-equal-float-epsilon) old-fudge)) (define (fv93) (let ((sf (make-frample->file "fmv.snd" 2 mus-lfloat mus-riff "this is a comment")) (fv (float-vector .01 .02)) (fv1 (make-float-vector 4)) (fv2 (make-float-vector 4))) (do ((i 0 (+ i 1)) (x 0 (+ x 2))) ((= i 4)) (frample->file sf i (float-vector-add! fv fv))) (mus-close sf) (list (file->array "fmv.snd" 0 0 4 fv1) (file->array "fmv.snd" 1 0 4 fv2)))) (let ((old-fudge (*s7* 'morally-equal-float-epsilon))) (set! (*s7* 'morally-equal-float-epsilon) 1e-5) (test (fv93) (list (float-vector .02 .04 .08 .16) (float-vector .04 .08 .16 .32))) (set! (*s7* 'morally-equal-float-epsilon) old-fudge)) (define (fv94) (let ((fv0 (float-vector 0 1 2 3 4 5)) (fv (make-float-vector 4))) (do ((i 0 (+ i 1)) (x 0.4 (+ x 0.7))) ((= i 4) fv) (float-vector-set! fv i (float-vector-ref fv0 (floor x)))))) (test (fv94) (float-vector 0.0 1.0 1.0 2.0)) (define (fv94a) (let ((fv0 (float-vector 0 1 2 3 4 5)) (fv (make-float-vector 4))) (do ((i 0 (+ i 1)) (x 0.4 (+ x 0.7))) ((= i 4) fv) (float-vector-set! fv i (float-vector-ref fv0 (ceiling x)))))) (test (fv94a) (float-vector 1.0 2.0 2.0 3.0)) (define (fv95) (let ((fv (make-float-vector 4))) (do ((i 0 (+ i 1)) (x 0 (+ x 1))) ((= i 4) fv) (if (even? i) (float-vector-set! fv i (+ i 10.0)) (float-vector-set! fv i (- i 10.0)))))) (test (fv95) (float-vector 10.0 -9.0 12.0 -7.0)) (define (fv95a) (let ((fv (make-float-vector 4))) (do ((i 0 (+ i 1)) (x 0 (+ x 1))) ((= i 4) fv) (if (odd? i) (float-vector-set! fv i (+ i 10.0)) (float-vector-set! fv i (- i 10.0)))))) (test (fv95a) (float-vector -10.0 11.0 -8.0 13.0)) (define (fv95b) (let ((fv (make-float-vector 4))) (do ((i 0 (+ i 1)) (x 0 (+ x 1))) ((= i 4) fv) (if (not (odd? i)) (float-vector-set! fv i (+ i 10.0)) (float-vector-set! fv i (- i 10.0)))))) (test (fv95b) (float-vector 10.0 -9.0 12.0 -7.0)) (define (fv96) (let ((fv (make-float-vector 4)) (fv1 (make-float-vector 4))) (do ((i 0 (+ i 1)) (x 0 (+ x 1))) ((= i 4) (list fv fv1)) (float-vector-set! fv1 i 3.0) (if (even? i) (float-vector-set! fv i (+ i 10.0)) (float-vector-set! fv i (- i 10.0))) (float-vector-set! fv1 i (+ (float-vector-ref fv1 i) 1.0))))) (test (fv96) (list (float-vector 10.0 -9.0 12.0 -7.0) (float-vector 4.0 4.0 4.0 4.0))) (define (fv97) (let ((fv (make-float-vector 4)) (j 0)) (do ((i 0 (+ i 1)) (x 0.4 (+ x 0.7))) ((= i 4) fv) (set! j (floor x)) (float-vector-set! fv i (* j 2.0))))) (test (fv97) (float-vector 0.0 2.0 2.0 4.0)) (define (fv98) (let ((fv (make-float-vector 4))) (do ((i 0 (+ i 1)) (x 0.0 (+ x 0.1))) ((not (= i 0)) fv) (set! i (* i 0.5)) (set! (fv i) x)))) (test (catch #t fv98 (lambda args (apply format #f (cadr args)))) "vector-set!: index must be an integer: ((fv i) x)") (define (fv99) (let ((fv (make-float-vector 4))) (do ((i 0 (+ i 1)) (x 0 (+ x 1))) ((= i 4) fv) (if (zero? i) (float-vector-set! fv i (+ i 10.0)) (float-vector-set! fv i (- i 10.0)))))) (test (fv99) (float-vector 10.0 -9.0 -8.0 -7.0)) (define (fv100) (let ((fv (make-float-vector 4))) (do ((i 0 (+ i 1)) (x 0 (+ x 1))) ((= i 4) fv) (if (zero? (modulo i 2)) (float-vector-set! fv i (+ i 10.0)) (float-vector-set! fv i (- i 10.0)))))) (test (fv100) (float-vector 10.0 -9.0 12.0 -7.0)) (define (fv101) (let ((fv (make-float-vector 4)) (ctr 0)) (do ((i 0 (+ i 1)) (x 0 (+ x 1))) ((= i 4) ctr) (if (zero? (modulo i 2)) (set! ctr (+ ctr 1)))))) (test (fv101) 2) (define (fv103) (let ((fv (make-float-vector 100)) (n 100)) (do ((i 0 (+ i 1))) ((= i n)) (do ((j 0 (+ j 1)) (k i (+ k 1))) ((= j n)) (float-vector-set! fv i (+ (float-vector-ref fv i) 1.0)))))) (fv103) ; just run without overflow (define (fv104) (let ((fv (make-float-vector 10))) (do ((i 0 (+ i 1))) ((= i 10) fv) (do ((j 0 (+ j 1))) ((= j i)) (float-vector-set! fv i (+ (float-vector-ref fv j) 1.0)))))) (test (fv104) (float-vector 0 1 2 3 4 5 6 7 8 9)) (define (fv104) (let ((fv (make-float-vector 10))) (do ((i 0 (+ i 1))) ((= i 10) fv) (do ((j 0 (+ j 1))) ((= j i)) (float-vector-set! fv i (+ (float-vector-ref fv j) 1.0)))))) (test (fv104) (float-vector 0 1 2 3 4 5 6 7 8 9)) (when all-args (define (do-permute init step end) (let ((body (copy `(let () (define (t1) (let ((fv (make-float-vector 4))) (if (<= ,step 0) (error 'out-of-range "step > 0")) (do ((i ,init (+ i ,step)) (x 1.0 (+ x 1.0))) ((>= i ,end) fv) (float-vector-set! fv i x)))) (define (t2) (let ((fv (make-float-vector 4))) (if (<= ,step 0) (error 'out-of-range "step > 0")) (do ((i ,init (+ i ,step)) (x 1.0 (+ x 1.0))) ((>= i ,end) fv) (float-vector-set! fv i x)))) (let ((v1 (catch #t t1 (lambda args 'error))) (v2 (catch #t (lambda () (copy (t2) (make-float-vector 4))) (lambda args 'error)))) (if (not (morally-equal? v1 v2)) (format *stderr* "~D: permute ~A, ~A -> ~A ~A, ~A~%" #__line__ op args v1 v2 (float-vector-peak (float-vector-subtract! v1 v2)))))) :readable))) (eval body))) (set! (*s7* 'morally-equal-float-epsilon) 1e-12) (for-each-subset (lambda (a b c) (for-each-permutation do-permute (list a b c))) (list 0 4 1 2 0.0 4.0 1.0 2.0 1/2 1+i 2/3 #\a "hi" #f))) (define (fv107) (let ((g0 (make-hash-table))) (do ((i 0 (+ i 1)) (x 0.0 (+ x 10.0))) ((= i 4) g0) (hash-table-set! g0 i x)))) (test (fv107) (hash-table* 0 0.0 1 10.0 2 20.0 3 30.0)) (define (fv108) (let ((fv (make-float-vector 10))) (let ((locs (make-locsig :output fv)) (k 0)) (do ((i 0 (- i 1))) ((= i -10) fv) (set! k (abs i)) (locsig locs k (* .1 i)))))) (test (fv108) (float-vector 0 -.1 -.2 -.3 -.4 -.5 -.6 -.7 -.8 -.9)) (define (fv109) (let ((fv (make-float-vector 10))) (let ((locs (make-locsig :output fv)) (k 0)) (do ((i 0 (+ i 1))) ((= i 10) fv) (locsig locs k (* .1 i)) (set! k (+ k 1)))))) (test (fv109) (float-vector 0 .1 .2 .3 .4 .5 .6 .7 .8 .9)) (define (fv110) (let ((fv (make-float-vector 10)) (k 0)) (set! *output* fv) (do ((i 0 (+ i 1))) ((= i 10) fv) (outa k (* .1 i)) (set! k (+ k 1))))) (test (fv110) (float-vector 0 .1 .2 .3 .4 .5 .6 .7 .8 .9)) (define (fv111) (let ((fv (make-float-vector 10)) (k 0)) (set! *output* fv) (do ((i 0 (+ i 1)) (x 0.0 (+ x 0.1))) ((= i 10) fv) (outa k x) (set! k (+ k 1))))) (test (fv111) (float-vector 0 .1 .2 .3 .4 .5 .6 .7 .8 .9)) (define (fv112) (let ((fv (make-float-vector 10)) (k 0)) (set! *output* fv) (do ((i 0 (+ i 1)) (x 0.0 (+ x 0.1))) ((= i 10) fv) (outa k x) (set! k (+ k 1.2))))) (test (catch #t fv112 (lambda args 'error)) 'error) (define (fv113) (let ((fv (make-float-vector 10))) (let ((locs (make-locsig :output fv)) (k 0)) (do ((i 0 (+ i 1))) ((= i 10) fv) (locsig locs k (* .1 i)) (set! k (+ k 1.2)))))) (test (catch #t fv113 (lambda args 'error)) 'error) (define (fv114) (let ((fv (make-float-vector 10000)) (k 0) (x 1.2)) (set! *output* fv) (do ((i 0 (+ i 1))) ((= i 10000) fv) (outa k (* .001 i)) (set! k (+ k x))))) (test (catch #t fv114 (lambda args 'error)) 'error) (define (fv115) (let ((g0 (make-float-vector 4 1.0)) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (let ((x (g0 i))) (set! (fv i) x))))) (test (fv115) (float-vector 1.0 1.0 1.0 1.0)) (define (fv116) (let ((fv (make-float-vector 4)) (g (make-oscil 100))) (do ((i 0 (+ i 1)) (x 0 (+ x 1))) ((= i 4) fv) (if (oscil? g) (float-vector-set! fv i (+ i 10.0)) (float-vector-set! fv i (- i 10.0)))))) (test (fv116) (float-vector 10.0 11.0 12.0 13.0)) (define (fv117) (let ((fv (make-float-vector 4))) (do ((i 0 (+ i 1)) (x 0 (+ x 1))) ((= i 4) fv) (if (even? (round i)) (float-vector-set! fv i (+ i 10.0)) (float-vector-set! fv i (- i 10.0)))))) (test (fv117) (float-vector 10.0 -9.0 12.0 -7.0)) (define (fv118) (let ((fv (make-float-vector 4)) (lst '(1 2 3))) (do ((i 0 (+ i 1)) (x 0 (+ x 1))) ((= i 4) fv) (if (even? (car lst)) (float-vector-set! fv i (+ i 10.0)) (float-vector-set! fv i (- i 10.0)))))) (test (fv118) (float-vector -10.0 -9.0 -8.0 -7.0)) (define (fv119) (let ((fv (make-float-vector 4)) (lst '(1 2 3))) (do ((i 0 (+ i 1)) (x 0 (+ x 1))) ((= i 4) fv) (if (eqv? i (car lst)) (float-vector-set! fv i (+ i 10.0)) (float-vector-set! fv i (- i 10.0)))))) (test (fv119) (float-vector -10.0 11.0 -8.0 -7.0)) (define (fv120) (let ((fv (make-float-vector 4)) (j 2)) (do ((i 0 (+ i 1)) (x 0 (+ x 1))) ((= i 4) fv) (if (= i j) (float-vector-set! fv i (+ i 10.0)) (float-vector-set! fv i (- i 10.0)))))) (test (fv120) (float-vector -10.0 -9.0 12.0 -7.0)) (define (fv121) (let ((fv (make-float-vector 4)) (j 2)) (do ((i 0 (+ i 1)) (x 0 (+ x 1))) ((= i 4) fv) (if (< i j) (float-vector-set! fv i (+ i 10.0)) (float-vector-set! fv i (- i 10.0)))))) (test (fv121) (float-vector 10.0 11.0 -8.0 -7.0)) (define (fv122) (let ((fv (make-float-vector 4)) (j 2)) (do ((i 0 (+ i 1)) (x 0 (+ x 1))) ((= i 4) fv) (if (<= i j) (float-vector-set! fv i (+ i 10.0)) (float-vector-set! fv i (- i 10.0)))))) (test (fv122) (float-vector 10.0 11.0 12.0 -7.0)) (define (fv123) (let ((fv (make-float-vector 4)) (j 2)) (do ((i 0 (+ i 1)) (x 0 (+ x 1))) ((= i 4) fv) (if (>= i j) (float-vector-set! fv i (+ i 10.0)) (float-vector-set! fv i (- i 10.0)))))) (test (fv123) (float-vector -10.0 -9.0 12.0 13.0)) (define (fv124) (let ((fv (make-float-vector 4)) (j 2)) (do ((i 0 (+ i 1)) (x 0 (+ x 1))) ((= i 4) fv) (if (> i j) (float-vector-set! fv i (+ i 10.0)) (float-vector-set! fv i (- i 10.0)))))) (test (fv124) (float-vector -10.0 -9.0 -8.0 13.0)) (define (fv125) (let ((gen (make-delay 5))) (do ((i 0 (+ i 1))) ((= i 3)) (float-vector-set! (mus-data gen) i 0.3)) (let ((fv (make-float-vector 5))) (do ((i 0 (+ i 1))) ((= i 5) fv) (float-vector-set! fv i (float-vector-ref (mus-data gen) i)))))) (test (fv125) (float-vector 0.3 0.3 0.3 0.0 0.0)) (define (fv126) (let ((d0 (float-vector 1 0 -1 0 1 0 -1 0)) (d1 (float-vector 0 1 0 -1 0 1 0 -1)) (e0 (float-vector 0 0 8 0 0 0 0 0)) (e1 (float-vector 0 0 0 0 0 0 0 0)) (rl (make-float-vector 8)) (im (make-float-vector 8))) (set! (rl 2) 1.0) (mus-fft rl im 8 1) (if (or (not (morally-equal? d0 rl)) (not (morally-equal? d1 im))) (format *stderr* ";fv126 mus-fft 0: ~A ~A~%" rl im)) (mus-fft rl im 8 -1) (if (or (not (morally-equal? e0 rl)) (not (morally-equal? e1 im))) (format *stderr* ";fv126 mus-fft 1: ~A ~A~%" rl im)) (set! (rl 2) 1.0) (do ((i 0 (+ i 1))) ((= i 1)) (mus-fft rl im)) (if (or (not (morally-equal? d0 rl)) (not (morally-equal? d1 im))) (format *stderr* ";fv126 mus-fft 2: ~A ~A~%" rl im)) (let ((loc 2) (val 1.0)) (do ((i 0 (+ i 1))) ((= i 1)) (mus-fft rl im 8 -1) (float-vector-set! rl loc val) (mus-fft rl im 8)) (if (or (not (morally-equal? d0 rl)) (not (morally-equal? d1 im))) (format *stderr* ";fv126 mus-fft 2: ~A ~A~%" rl im))))) (fv126) (define (fv127) (let ((fv (make-float-vector 4)) (j 2)) (do ((i 0 (+ i 1))) ((= i 4) fv) (if (or (> i j) (= i 3)) (float-vector-set! fv i (+ i 10.0)) (float-vector-set! fv i (- i 10.0)))))) (test (fv127) (float-vector -10.0 -9.0 -8.0 13.0)) (define (fv128) (let ((fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (if (or (= i 1) (= i 3)) (float-vector-set! fv i (+ i 10.0)) (float-vector-set! fv i (- i 10.0)))))) (test (fv128) (float-vector -10.0 11.0 -8.0 13.0)) (define (fv129) (let ((fv (make-float-vector 4)) (j 2)) (do ((i 0 (+ i 1))) ((= i 4) fv) (if (and (= i j) (< i 3)) (float-vector-set! fv i (+ i 10.0)) (float-vector-set! fv i (- i 10.0)))))) (test (fv129) (float-vector -10.0 -9.0 12.0 -7.0)) (define (fv130) (let ((fv (make-float-vector 4)) (j #\a)) (do ((i 0 (+ i 1))) ((= i 4) fv) (if (char=? j #\a) (float-vector-set! fv i (+ i 10.0)) (float-vector-set! fv i (- i 10.0)))))) (test (fv130) (float-vector 10.0 11.0 12.0 13.0)) (define (char-permute op . args) (let ((body (copy `(let () (define (t1) (let ((x #\a) (y #\A) (fv (make-float-vector 4))) (do ((i 0 (+ i 1)) (x1 1.0 (+ x1 1.0))) ((= i 4) fv) (if (,op ,@args) (float-vector-set! fv i x1) (float-vector-set! fv i 0.0))))) (define (t2) (let ((x #\a) (y #\A) (fv (make-float-vector 4))) (do ((i 0 (+ i 1)) (x1 1.0 (+ x1 1.0))) ((= i 4) fv) (if (apply ,op (list ,@args)) (float-vector-set! fv i x1) (float-vector-set! fv i 0.0))))) (let ((v1 (t1)) (v2 (t2))) (if (not (morally-equal? v1 v2)) (format *stderr* "char-permute ~A, ~A -> ~A ~A~%" op args v1 v2)))) :readable))) (eval body))) (for-each (lambda (op) (for-each-subset (lambda s-args (if (= (length s-args) 2) (for-each-permutation (lambda args (apply char-permute op args)) s-args))) (list 'x 'y #\b #\newline))) (if (provided? 'pure-s7) (list 'char=? 'char? 'char>=?) (list 'char=? 'char? 'char>=? 'char-ci=? 'char-ci? 'char-ci>=?))) (define (string-permute op . args) (let ((body (copy `(let () (define (t1) (let ((x "a") (y "A") (fv (make-float-vector 4))) (do ((i 0 (+ i 1)) (x1 1.0 (+ x1 1.0))) ((= i 4) fv) (if (,op ,@args) (float-vector-set! fv i x1) (float-vector-set! fv i 0.0))))) (define (t2) (let ((x "a") (y "A") (fv (make-float-vector 4))) (do ((i 0 (+ i 1)) (x1 1.0 (+ x1 1.0))) ((= i 4) fv) (if (apply ,op (list ,@args)) (float-vector-set! fv i x1) (float-vector-set! fv i 0.0))))) (let ((v1 (t1)) (v2 (t2))) (if (not (morally-equal? v1 v2)) (format *stderr* "string-permute ~A, ~A -> ~A ~A~%" op args v1 v2)))) :readable))) (eval body))) (for-each (lambda (op) (for-each-subset (lambda s-args (if (= (length s-args) 2) (for-each-permutation (lambda args (apply string-permute op args)) s-args))) (list 'x 'y "ab" "b"))) (if (provided? 'pure-s7) (list 'string=? 'string? 'string>=?) (list 'string=? 'string? 'string>=? 'string-ci=? 'string-ci? 'string-ci>=?))) (unless (provided? 'pure-s7) (define (fv131) (let ((fv1 (make-float-vector 10)) (fv2 #f) (coeffs (float-vector 0.0 0.5 0.25 0.125))) (do ((i 0 (+ i 1)) (x 0.0 (+ x 0.1))) ((= i 10)) (float-vector-set! fv1 i (mus-chebyshev-t-sum x coeffs))) (do ((i 0 (+ i 1)) (x 0.0 (+ x 0.1)) (lst ())) ((= i 10) (set! fv2 (list->vector (reverse lst)))) (set! lst (cons (mus-chebyshev-t-sum x coeffs) lst))) (if (not (morally-equal? fv1 fv2)) (format *stderr* ";t-sum: ~A ~A~%" fv1 fv2)))) (fv131) (define (fv132) (let ((fv1 (make-float-vector 10)) (fv2 #f) (t-coeffs (float-vector 0.0 0.5 0.25 0.125)) (u-coeffs (float-vector 0.0 0.2 0.1 0.05))) (do ((i 0 (+ i 1)) (x 0.0 (+ x 0.1))) ((= i 10)) (float-vector-set! fv1 i (mus-chebyshev-tu-sum x t-coeffs u-coeffs))) (do ((i 0 (+ i 1)) (x 0.0 (+ x 0.1)) (lst ())) ((= i 10) (set! fv2 (list->vector (reverse lst)))) (set! lst (cons (mus-chebyshev-tu-sum x t-coeffs u-coeffs) lst))) (if (not (morally-equal? fv1 fv2)) (format *stderr* ";tu-sum: ~A ~A~%" fv1 fv2)))) (fv132)) (define (fv132a) (let ((fv (make-float-vector 10))) (let ((o1 (make-oscil 1000)) (o2 (make-oscil 1000)) (s1 (make-sawtooth-wave 1000)) (s2 (make-sawtooth-wave 1000)) (s3 (make-sawtooth-wave 1000)) (s4 (make-sawtooth-wave 1000)) (t1 (make-triangle-wave 1000)) (t2 (make-triangle-wave 1000)) (p1 (make-polywave 1000 '(1 .4 2 .6))) (p2 (make-polywave 1000 '(1 .4 2 .6))) (p3 (make-polywave 1000 '(1 .4 2 .6))) (p4 (make-polywave 1000 '(1 .4 2 .6)))) (do ((i 0 (+ i 1))) ((= i 10) fv) (set! (fv i) (if (even? i) (+ (oscil o1) (* (triangle-wave t1) (if (zero? (modulo i 2)) (polywave p1) (polywave p2))) (if (odd? i) (sawtooth-wave s1) (sawtooth-wave s2))) (+ (oscil o2) (* (triangle-wave t2) (if (zero? (modulo i 2)) (polywave p3) (polywave p4))) (if (odd? i) (sawtooth-wave s3) (sawtooth-wave s4))))))))) (test (fv132a) (float-vector 0.0 0.0 0.2754865742400099 0.2754865742400099 0.5330915108442034 0.5330915108442034 0.7567925994733748 0.7567925994733748 0.9340879688376413 0.9340879688376413)) (define (fv133) (let ((fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) ((lambda () (set! (fv i) i)))))) (test (fv133) (float-vector 0.0 1.0 2.0 3.0)) (define (fv134) (let ((fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (let ((y 1.0)) ((lambda () (set! (fv i) i))))))) (test (fv134) (float-vector 0.0 1.0 2.0 3.0)) (define (fv135) (let ((fv (make-float-vector 4))) (do ((i 0 (+ i 1)) (x 0.0 (+ x 1.0))) ((= i 4) fv) ((lambda () (set! (fv i) i)))))) (test (fv135) (float-vector 0.0 1.0 2.0 3.0)) (define (fv136) (let ((fv (make-vector 4))) (do ((i 0 (+ i 1)) (x 0.0 (+ x 1.0))) ((= i 4) fv) (vector-set! fv i (cons i x))))) (test (fv136) (vector '(0 . 0.0) '(1 . 1.0) '(2 . 2.0) '(3 . 3.0))) (define (fv137) (let ((fv (make-vector 4))) (do ((i 0 (+ i 1)) (x 0.0 (+ x 0.6))) ((= i 4) fv) (vector-set! fv i (asin x))))) (test (fv137) (vector (asin 0.0) (asin 0.6) (asin 1.2) (asin 1.8))) (define (fv138) (let ((fv (make-vector 4)) (fv1 (vector 0.0 0.6 1.2 1.8))) (do ((i 0 (+ i 1)) (x 0.0 (+ x 0.6))) ((= i 4) fv) (vector-set! fv i (asin (vector-ref fv1 i)))))) (test (fv138) (vector (asin 0.0) (asin 0.6) (asin 1.2) (asin 1.8))) (define (fv138a) (let ((fv (make-vector 4)) (fv1 (vector 0.0 0.6 1.2 1.8))) (do ((i 0 (+ i 1)) (x 0.0 (+ x 0.6))) ((= i 4) fv) (vector-set! fv i (asin (floor i)))))) (test (fv138a) (vector (asin 0) (asin 1) (asin 2) (asin 3))) (define (fv138b) (let ((fv (make-vector 4)) (fv1 (vector 0.0 0.6 1.2 1.8))) (do ((i 0 (+ i 1)) (x 0.0 (+ x 0.6))) ((= i 4) fv) (vector-set! fv i (asin (complex x i)))))) (test (fv138b) (vector (asin 0.0) (asin 0.6+i) (asin 1.2+2i) (asin 1.8+3i))) (define (fv139) (with-output-to-string (lambda () (do ((i 80 (+ i 1))) ((= i 84)) (write-char (integer->char i)))))) (test (fv139) "PQRS") (define (fv140) (with-output-to-string (lambda () (do ((i 80 (+ i 1))) ((= i 84)) (write-byte i))))) (test (fv140) "PQRS") (define (fv141) (let ((g0 (make-hash-table)) (v (vector 0 1 2 3 4 5))) (do ((i 0 (+ i 1)) (x 0.0 (+ x 10.0))) ((= i 4) g0) (hash-table-set! g0 (vector-ref v i) x)))) (test (fv141) (hash-table* 0 0.0 1 10.0 2 20.0 3 30.0)) (define (fv142) (let ((g0 (make-hash-table))) (do ((i 0 (+ i 1)) (x 0.0 (+ x 10.0))) ((= i 4) g0) (hash-table-set! g0 i (list x))))) (test (fv142) (hash-table* 0 '(0.0) 1 '(10.0) 2 '(20.0) 3 '(30.0))) (define (fv143) (let ((g0 (make-hash-table)) (v (vector 0 1 2 3 4 5))) (do ((i 0 (+ i 1)) (x 0.0 (+ x 10.0))) ((= i 4) g0) (hash-table-set! g0 (vector-ref v i) (list x))))) (test (fv143) (hash-table* 0 '(0.0) 1 '(10.0) 2 '(20.0) 3 '(30.0))) (define (fv144) (let ((g0 (make-iterator (list 0 1 2 3 4))) (v (make-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) v) (vector-set! v i (iterate g0))))) (test (fv144) (vector 0 1 2 3)) (define (fv145) (let ((g0 (list (make-iterator (list 0 1 2 3 4)))) (v (make-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) v) (vector-set! v i (iterate (car g0)))))) (test (fv145) (vector 0 1 2 3)) (define (fv146) (let ((x 0)) (do ((i 0 (+ i 1))) ((= i 4) x) (do ((k 0 (+ k 1))) ((= k 4)) (set! x (+ x k)))))) (test (fv146) 24) (define (fv147a) (let ((x 0) (lst '(1 2 3))) (for-each (lambda (y) (if (= x y) (display "fv147 oops"))) lst))) (test (fv147a) #) (define (fv147b) (let ((s "012345") (lst '(1 2 3))) (map (lambda (y) (string-ref s y)) lst))) (test (fv147b) '(#\1 #\2 #\3)) (define (fv147c) (let ((lst '(1 2 3))) (map (lambda (y) (* y 2.0)) lst))) (test (fv147c) '(2.0 4.0 6.0)) (define (fv148) (let ((g0 (list 0 1 2 3 4)) (v (make-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) v) (vector-set! v i (g0 i))))) (test (fv148) (vector 0 1 2 3)) (define (fv149) (let ((g0 "012345") (v (make-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) v) (vector-set! v i (g0 i))))) (test (fv149) (vector #\0 #\1 #\2 #\3)) (define (fv150) (let ((g0 (int-vector 0 1 2 3 4)) (v (make-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) v) (vector-set! v i (g0 i))))) (test (fv150) (vector 0 1 2 3)) (define (fv151) (let ((g0 (float-vector 0 1 2 3 4)) (v (make-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) v) (vector-set! v i (g0 i))))) (test (fv151) (vector 0 1 2 3)) (define (fv152) (let ((g0 (inlet 'a 0 'b 1 'c 2 'd 3)) (syms (vector 'a 'b 'c 'd)) (v (make-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) v) (vector-set! v i (g0 (syms i)))))) (test (fv152) (vector 0 1 2 3)) (define (fv153) (let ((g0 (list 0 1 2 3 4)) (v (make-list 4 #f))) (do ((i 0 (+ i 1))) ((= i 4) v) (set! (v i) (g0 i))))) (test (fv153) (list 0 1 2 3)) (define (fv154) (let ((g0 "012345") (v (make-string 4))) (do ((i 0 (+ i 1))) ((= i 4) v) (set! (v i) (g0 i))))) (test (fv154) "0123") (define (fv155) (let ((g0 (int-vector 0 1 2 3 4)) (v (make-int-vector 4 -1))) (do ((i 0 (+ i 1))) ((= i 4) v) (set! (v i) (g0 i))))) (test (fv155) (int-vector 0 1 2 3)) (define (fv156) (let ((g0 (float-vector 0 1 2 3 4)) (v (make-float-vector 4 pi))) (do ((i 0 (+ i 1))) ((= i 4) v) (set! (v i) (g0 i))))) (test (fv156) (float-vector 0 1 2 3)) (define (fv157) (let ((g0 (inlet 'a 0 'b 1 'c 2 'd 3)) (syms (vector 'a 'b 'c 'd)) (v (inlet 'a -1 'b -1 'c -1 'd -1))) (do ((i 0 (+ i 1))) ((= i 4) v) (set! (v (syms i)) (g0 (syms i)))))) (test (fv157) (inlet 'a 0 'b 1 'c 2 'd 3)) (define (fv158) (let ((g0 (hash-table* 'a 0 'b 1 'c 2 'd 3)) (syms (vector 'a 'b 'c 'd)) (v (hash-table* 'a -1 'b -1 'c -1 'd -1))) (do ((i 0 (+ i 1))) ((= i 4) v) (set! (v (syms i)) (g0 (syms i)))))) (test (fv158) (hash-table* 'a 0 'b 1 'c 2 'd 3)) (define (fv159) (let ((o (make-oscil 1000)) (oscs (vector (make-oscil 400) (make-oscil 500) (make-oscil 600))) (v1 (make-float-vector 10)) (v2 (make-float-vector 10)) (v3 (float-vector 0.1419943179576268 1.008255926858552 -0.3982998307862416 -0.4953385977530639 1.122094083214508 0.6986797544826313 -0.5752063448650614 0.5489621715396582 1.499234145268148 0.1194943083560847)) (k 1)) (do ((i 0 (+ i 1))) ((= i 10)) (let ((x (oscil o))) (set! (v1 i) (+ (oscil (vector-ref oscs k)) (oscil o 1.5))))) (set! o (make-oscil 1000)) (set! oscs (vector (make-oscil 400) (make-oscil 500) (make-oscil 600))) (set! (v2 0) ((lambda () (let ((x (oscil o))) (+ (oscil (vector-ref oscs k)) (oscil o 1.5)))))) (set! (v2 1) ((lambda () (let ((x (oscil o))) (+ (oscil (vector-ref oscs k)) (oscil o 1.5)))))) (set! (v2 2) ((lambda () (let ((x (oscil o))) (+ (oscil (vector-ref oscs k)) (oscil o 1.5)))))) (set! (v2 3) ((lambda () (let ((x (oscil o))) (+ (oscil (vector-ref oscs k)) (oscil o 1.5)))))) (set! (v2 4) ((lambda () (let ((x (oscil o))) (+ (oscil (vector-ref oscs k)) (oscil o 1.5)))))) (set! (v2 5) ((lambda () (let ((x (oscil o))) (+ (oscil (vector-ref oscs k)) (oscil o 1.5)))))) (set! (v2 6) ((lambda () (let ((x (oscil o))) (+ (oscil (vector-ref oscs k)) (oscil o 1.5)))))) (set! (v2 7) ((lambda () (let ((x (oscil o))) (+ (oscil (vector-ref oscs k)) (oscil o 1.5)))))) (set! (v2 8) ((lambda () (let ((x (oscil o))) (+ (oscil (vector-ref oscs k)) (oscil o 1.5)))))) (set! (v2 9) ((lambda () (let ((x (oscil o))) (+ (oscil (vector-ref oscs k)) (oscil o 1.5)))))) (if (or (not (morally-equal? v1 v2)) (not (morally-equal? v1 v3))) (format *stderr* "~A~%~A~%~A~%" v1 v2 v3)))) (fv159) (define (fv160) (let ((fv (make-float-vector 4)) (g (make-oscil 1000))) (do ((i 0 (+ i 1)) (x 0.1 0.0)) ((= i 4) fv) (float-vector-set! fv i (oscil g x))))) (test (fv160) (let ((g (make-oscil 1000))) (float-vector (oscil g 0.1) (oscil g) (oscil g) (oscil g)))) #| (define (fv161) (let ((log2 (*libm* 'log2))) (let ((fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (log2 2.5)))))) (test (fv161) (float-vector (log 2.5 2) (log 2.5 2) (log 2.5 2) (log 2.5 2))) |# (define (fv162) (let ((fv (make-int-vector 4)) (iter (make-iterator (list 1 2 3 4)))) (do ((i 0 (+ i 1))) ((= i 4) fv) (int-vector-set! fv i (iterate iter))))) (test (fv162) (int-vector 1 2 3 4)) (define (fv163) (let ((fv (make-float-vector 4))) (do ((i 0 (+ i 1)) (x 0.0 (+ x 0.25))) ((= i 4) fv) (set! (fv i) (sin x))))) (test (fv163) (float-vector (sin 0.0) (sin 0.25) (sin 0.5) (sin 0.75))) (define (fv164) (let ((fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (+ 1.0 2.0 3.0))))) (test (fv164) (float-vector 6.0 6.0 6.0 6.0)) (define (fv165) (let ((fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (+ 4.5 3/2))))) (test (fv165) (float-vector 6.0 6.0 6.0 6.0)) (define (fv166) (let ((x 1/2) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (+ 1 x))))) (test (fv166) (float-vector 1.5 1.5 1.5 1.5)) (define (fv167) (let ((fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (+ 6.0))))) (test (fv167) (float-vector 6.0 6.0 6.0 6.0)) (define (fv168) (let ((x 1.0) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (+ x 5.0))))) (test (fv168) (float-vector 6.0 6.0 6.0 6.0)) (define (fv169) (let ((x 1.0) (y 5.0) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (+ x y))))) (test (fv169) (float-vector 6.0 6.0 6.0 6.0)) (define (fv170) (let ((x 1.0) (y 6.0) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (+ x y -1.0))))) (test (fv170) (float-vector 6.0 6.0 6.0 6.0)) (define (fv171) (let ((x 1.0) (y 6.0) (z -1.0) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (+ x y z))))) (test (fv171) (float-vector 6.0 6.0 6.0 6.0)) (define (fv172) (let ((x 1.0) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (+ x -1.0 6.0))))) (test (fv172) (float-vector 6.0 6.0 6.0 6.0)) (define (fv173) (let ((x 3.0) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (+ x (abs x)))))) (test (fv173) (float-vector 6.0 6.0 6.0 6.0)) (define (fv174) (let ((x 2.0) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (+ x 2 (abs x)))))) (test (fv174) (float-vector 6.0 6.0 6.0 6.0)) (define (fv175) (let ((x 2.0) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (+ 2.0 2 (abs x)))))) (test (fv175) (float-vector 6.0 6.0 6.0 6.0)) (define (fv176) (let ((x 2.0) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (+ 2.0 (abs x) (abs x)))))) (test (fv176) (float-vector 6.0 6.0 6.0 6.0)) (define (fv177) (let ((x 2.0) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (+ (abs x) (abs x) (abs x)))))) (test (fv177) (float-vector 6.0 6.0 6.0 6.0)) (define (fv178) (let ((x 2.0) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (+ (abs x) x (abs x)))))) (test (fv178) (float-vector 6.0 6.0 6.0 6.0)) (define (fv178) (let ((x 2.0) (y 2.0) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (+ (abs x) x y))))) (test (fv178) (float-vector 6.0 6.0 6.0 6.0)) (define (fv179) (let ((fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (* 1.0 2.0 3.0))))) (test (fv179) (float-vector 6.0 6.0 6.0 6.0)) (define (fv180) (let ((x 1.0) (y 6.0) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (* x y -1.0))))) (test (fv180) (float-vector -6.0 -6.0 -6.0 -6.0)) (define (fv181) (let ((x 1.0) (y 6.0) (z -1.0) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (* x y z))))) (test (fv181) (float-vector -6.0 -6.0 -6.0 -6.0)) (define (fv182) (let ((x 1.0) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (* x -1.0 6.0))))) (test (fv182) (float-vector -6.0 -6.0 -6.0 -6.0)) (define (fv183) (let ((x 3.0) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (* x (abs x)))))) (test (fv183) (float-vector 9.0 9.0 9.0 9.0)) (define (fv184) (let ((x 2.0) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (* x 2 (abs x)))))) (test (fv184) (float-vector 8.0 8.0 8.0 8.0)) (define (fv185) (let ((x 2.0) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (* 2.0 2 (abs x)))))) (test (fv185) (float-vector 8.0 8.0 8.0 8.0)) (define (fv186) (let ((x 2.0) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (* 2.0 (abs x) (abs x)))))) (test (fv186) (float-vector 8.0 8.0 8.0 8.0)) (define (fv187) (let ((x 2.0) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (* (abs x) (abs x) (abs x)))))) (test (fv187) (float-vector 8.0 8.0 8.0 8.0)) (define (fv188) (let ((x 2.0) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (* (abs x) x (abs x)))))) (test (fv188) (float-vector 8.0 8.0 8.0 8.0)) (define (fv188) (let ((x 2.0) (y 2.0) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (* (abs x) x y))))) (test (fv188) (float-vector 8.0 8.0 8.0 8.0)) (define (fv189) (let ((fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (* 4.5 3/2))))) (test (fv189) (float-vector 6.75 6.75 6.75 6.75)) (define (fv190) (let ((x 1/2) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (* 1 x))))) (test (fv190) (float-vector 0.5 0.5 0.5 0.5)) (define (fv191) (let ((fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (* 6.0))))) (test (fv191) (float-vector 6.0 6.0 6.0 6.0)) (define (fv192) (let ((x 1.0) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (* x 5.0))))) (test (fv192) (float-vector 5.0 5.0 5.0 5.0)) (define (fv193) (let ((x 1.0) (y 5.0) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (* x y))))) (test (fv193) (float-vector 5.0 5.0 5.0 5.0)) (define (fvi164) (let ((fv (make-int-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (+ 1 2 3))))) (test (fvi164) (int-vector 6 6 6 6)) (define (fvi165) (let ((fv (make-int-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (+ 4.5 3/2))))) (test (catch #t fvi165 (lambda args 'error)) 'error) (define (fvi166) (let ((x 1/2) (fv (make-int-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (+ 1 x))))) (test (catch #t fvi166 (lambda args 'error))'error) (define (fvi167) (let ((fv (make-int-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (+ 6))))) (test (fvi167) (int-vector 6 6 6 6)) (define (fvi168) (let ((x 1) (fv (make-int-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (+ x 5))))) (test (fvi168) (int-vector 6 6 6 6)) (define (fvi169) (let ((x 1) (y 5) (fv (make-int-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (+ x y))))) (test (fvi169) (int-vector 6 6 6 6)) (define (fvi170) (let ((x 1) (y 6) (fv (make-int-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (+ x y -1))))) (test (fvi170) (int-vector 6 6 6 6)) (define (fvi171) (let ((x 1) (y 6) (z -1) (fv (make-int-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (+ x y z))))) (test (fvi171) (int-vector 6 6 6 6)) (define (fvi172) (let ((x 1) (fv (make-int-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (+ x -1 6))))) (test (fvi172) (int-vector 6 6 6 6)) (define (fvi173) (let ((x 3) (fv (make-int-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (+ x (abs x)))))) (test (fvi173) (int-vector 6 6 6 6)) (define (fvi174) (let ((x 2) (fv (make-int-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (+ x 2 (abs x)))))) (test (fvi174) (int-vector 6 6 6 6)) (define (fvi175) (let ((x 2) (fv (make-int-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (+ 2 2 (abs x)))))) (test (fvi175) (int-vector 6 6 6 6)) (define (fvi176) (let ((x 2) (fv (make-int-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (+ 2 (abs x) (abs x)))))) (test (fvi176) (int-vector 6 6 6 6)) (define (fvi177) (let ((x 2) (fv (make-int-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (+ (abs x) (abs x) (abs x)))))) (test (fvi177) (int-vector 6 6 6 6)) (define (fvi178) (let ((x 2) (fv (make-int-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (+ (abs x) x (abs x)))))) (test (fvi178) (int-vector 6 6 6 6)) (define (fvi178) (let ((x 2) (y 2) (fv (make-int-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (+ (abs x) x y))))) (test (fvi178) (int-vector 6 6 6 6)) (define (fvi179) (let ((fv (make-int-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (* 1 2 3))))) (test (fvi179) (int-vector 6 6 6 6)) (define (fvi180) (let ((x 1) (y 6) (fv (make-int-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (* x y -1))))) (test (fvi180) (int-vector -6 -6 -6 -6)) (define (fvi181) (let ((x 1) (y 6) (z -1) (fv (make-int-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (* x y z))))) (test (fvi181) (int-vector -6 -6 -6 -6)) (define (fvi182) (let ((x 1) (fv (make-int-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (* x -1 6))))) (test (fvi182) (int-vector -6 -6 -6 -6)) (define (fvi183) (let ((x 3) (fv (make-int-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (* x (abs x)))))) (test (fvi183) (int-vector 9 9 9 9)) (define (fvi184) (let ((x 2) (fv (make-int-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (* x 2 (abs x)))))) (test (fvi184) (int-vector 8 8 8 8)) (define (fvi185) (let ((x 2) (fv (make-int-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (* 2 2 (abs x)))))) (test (fvi185) (int-vector 8 8 8 8)) (define (fvi186) (let ((x 2) (fv (make-int-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (* 2 (abs x) (abs x)))))) (test (fvi186) (int-vector 8 8 8 8)) (define (fvi187) (let ((x 2) (fv (make-int-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (* (abs x) (abs x) (abs x)))))) (test (fvi187) (int-vector 8 8 8 8)) (define (fvi188) (let ((x 2) (fv (make-int-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (* (abs x) x (abs x)))))) (test (fvi188) (int-vector 8 8 8 8)) (define (fvi188) (let ((x 2) (y 2) (fv (make-int-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (* (abs x) x y))))) (test (fvi188) (int-vector 8 8 8 8)) (define (fvi191) (let ((fv (make-int-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (* 6))))) (test (fvi191) (int-vector 6 6 6 6)) (define (fvi192) (let ((x 1) (fv (make-int-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (* x 5))))) (test (fvi192) (int-vector 5 5 5 5)) (define (fvi193) (let ((x 1) (y 5) (fv (make-int-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (* x y))))) (test (fvi193) (int-vector 5 5 5 5)) (define (fv194) (let ((fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (+ 1.0 2.0 3.0 4.0))))) (test (fv194) (float-vector 10.0 10.0 10.0 10.0)) (define (fv195) (let ((x 1.0) (y 2.0) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (+ x y (+ x 2.0) 4.0))))) (test (fv195) (float-vector 10.0 10.0 10.0 10.0)) (define (fv196) (let ((fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (+ 1.0 2.0 3.0 4.0 5.0))))) (test (fv196) (float-vector 15.0 15.0 15.0 15.0)) (define (fv197) (let ((fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (+ 1.0 2.0 3.0 4.0 5.0 6.0))))) (test (fv197) (float-vector 21.0 21.0 21.0 21.0)) (define (fv198) (let ((fv (make-float-vector 4)) (a 1.0) (b 2.0) (c 4.0)) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (+ a b 3.0 c (+ a c) (+ b c) (+ a b c) (+ a b c a b c a b c) a b c))))) (test (fv198) (float-vector 56.0 56.0 56.0 56.0)) (define (fv164) (let ((fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (- 1.0 2.0 3.0))))) (test (fv164) (float-vector -4.0 -4.0 -4.0 -4.0)) (define (fv165) (let ((fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (- 4.5 3/2))))) (test (fv165) (float-vector 3.0 3.0 3.0 3.0)) (define (fv166) (let ((x 1/2) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (- 1 x))))) (test (fv166) (float-vector .5 .5 .5 .5)) (define (fv167) (let ((fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (- 6.0))))) (test (fv167) (float-vector -6.0 -6.0 -6.0 -6.0)) (define (fv168) (let ((x 1.0) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (- x 5.0))))) (test (fv168) (float-vector -4.0 -4.0 -4.0 -4.0)) (define (fv169) (let ((x 1.0) (y 5.0) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (- x y))))) (test (fv169) (float-vector -4.0 -4.0 -4.0 -4.0)) (define (fv170) (let ((x 1.0) (y 6.0) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (- x y -1.0))))) (test (fv170) (float-vector -4.0 -4.0 -4.0 -4.0)) (define (fv171) (let ((x 1.0) (y 6.0) (z -1.0) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (- x y z))))) (test (fv171) (float-vector -4.0 -4.0 -4.0 -4.0)) (define (fv172) (let ((x 1.0) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (- x -1.0 6.0))))) (test (fv172) (float-vector -4.0 -4.0 -4.0 -4.0)) (define (fv173) (let ((x 3.0) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (- x (abs x)))))) (test (fv173) (float-vector 0.0 0.0 0.0 0.0)) (define (fv174) (let ((x 2.0) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (- x 2 (abs x)))))) (test (fv174) (float-vector -2.0 -2.0 -2.0 -2.0)) (define (fv175) (let ((x 2.0) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (- 2.0 2 (abs x)))))) (test (fv175) (float-vector -2.0 -2.0 -2.0 -2.0)) (define (fv176) (let ((x 2.0) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (- 2.0 (abs x) (abs x)))))) (test (fv176) (float-vector -2.0 -2.0 -2.0 -2.0)) (define (fv177) (let ((x 2.0) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (- (abs x) (abs x) (abs x)))))) (test (fv177) (float-vector -2.0 -2.0 -2.0 -2.0)) (define (fv178) (let ((x 2.0) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (- (abs x) x (abs x)))))) (test (fv178) (float-vector -2.0 -2.0 -2.0 -2.0)) (define (fv178) (let ((x 2.0) (y 2.0) (fv (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (- (abs x) x y))))) (test (fv178) (float-vector -2.0 -2.0 -2.0 -2.0)) (define (fvi164) (let ((fv (make-int-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (- 1 2 3))))) (test (fvi164) (int-vector -4 -4 -4 -4)) (define (fvi165) (let ((fv (make-int-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (- 4.5 3/2))))) (test (catch #t fvi165 (lambda args 'error)) 'error) (define (fvi166) (let ((x 1/2) (fv (make-int-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (- 1 x))))) (test (catch #t fvi166 (lambda args 'error))'error) (define (fvi167) (let ((fv (make-int-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (- 6))))) (test (fvi167) (int-vector -6 -6 -6 -6)) (define (fvi168) (let ((x 1) (fv (make-int-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (- x 5))))) (test (fvi168) (int-vector -4 -4 -4 -4)) (define (fvi169) (let ((x 1) (y 5) (fv (make-int-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (- x y))))) (test (fvi169) (int-vector -4 -4 -4 -4)) (define (fvi170) (let ((x 1) (y 6) (fv (make-int-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (- x y -1))))) (test (fvi170) (int-vector -4 -4 -4 -4)) (define (fvi171) (let ((x 1) (y 6) (z -1) (fv (make-int-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (- x y z))))) (test (fvi171) (int-vector -4 -4 -4 -4)) (define (fvi172) (let ((x 1) (fv (make-int-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (- x -1 6))))) (test (fvi172) (int-vector -4 -4 -4 -4)) (define (fvi173) (let ((x 3) (fv (make-int-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (- x (abs x)))))) (test (fvi173) (int-vector 0 0 0 0)) (define (fvi174) (let ((x 2) (fv (make-int-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (- x 2 (abs x)))))) (test (fvi174) (int-vector -2 -2 -2 -2)) (define (fvi175) (let ((x 2) (fv (make-int-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (- 2 2 (abs x)))))) (test (fvi175) (int-vector -2 -2 -2 -2)) (define (fvi176) (let ((x 2) (fv (make-int-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (- 2 (abs x) (abs x)))))) (test (fvi176) (int-vector -2 -2 -2 -2)) (define (fvi177) (let ((x 2) (fv (make-int-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (- (abs x) (abs x) (abs x)))))) (test (fvi177) (int-vector -2 -2 -2 -2)) (define (fvi178) (let ((x 2) (fv (make-int-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (- (abs x) x (abs x)))))) (test (fvi178) (int-vector -2 -2 -2 -2)) (define (fvi178) (let ((x 2) (y 2) (fv (make-int-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) fv) (set! (fv i) (- (abs x) x y))))) (test (fvi178) (int-vector -2 -2 -2 -2)) ) (if all-args (let ((old-size *clm-file-buffer-size*)) (set! *clm-file-buffer-size* 100) (set! *mus-float-equal-fudge-factor* 1e-4) (define v-1 (make-float-vector 100 .25)) (do ((i 0 (+ i 1)) (x 0.0 (+ x .01))) ((= i 100)) (float-vector-set! v-1 i x)) (define v0 (make-float-vector 10)) (define args1 (list 1.5 '(oscil o1) '(env e1) 'x 'i '(oscil o) '(- 1.0 x) '(oscil (vector-ref oscs k)))) (define args2 (list 1.5 '(oscil o2) '(env e2) 'y 'i '(float-vector-ref v-1 i))) (define args3 (list 1.5 '(oscil o3) '(env e3) 'z 'i '(cos x))) ;(define args4 (list 1.5 '(oscil o4) '(env e4) 'x 'i)) (define (try str) (eval-string (call-with-output-string (lambda (p) (format p "(let ()~%") (format p " (let ((o (make-oscil 1000.0))~%") (format p " (o1 (make-oscil 1000.0))~%") (format p " (o2 (make-oscil 1000.0))~%") (format p " (o3 (make-oscil 1000.0))~%") (format p " (o4 (make-oscil 1000.0))~%") (format p " (oscs (vector (make-oscil 400.0) (make-oscil 500.0) (make-oscil 600.0)))~%") (format p " (e1 (make-env '(0 .1 1 1) :length 100))~%") (format p " (e2 (make-env '(0 .1 1 1) :length 100))~%") (format p " (e3 (make-env '(0 .1 1 1) :length 100))~%") (format p " (e4 (make-env '(0 .1 1 1) :length 100))~%") (format p " (x 3.14)~%") (format p " (y -0.5)~%") (format p " (z 0.1)~%") (format p " (k 1)~%") (format p " (i 0)~%") (format p " (v (make-float-vector 10)))~%") (format p " (set! (v0 0) ~A) (set! i (+ i 1))~%" str) (format p " (set! (v0 1) ~A) (set! i (+ i 1))~%" str) (format p " (set! (v0 2) ~A) (set! i (+ i 1))~%" str) (format p " (set! (v0 3) ~A) (set! i (+ i 1))~%" str) (format p " (set! (v0 4) ~A) (set! i (+ i 1))~%" str) (format p " (set! (v0 5) ~A) (set! i (+ i 1))~%" str) (format p " (set! (v0 6) ~A) (set! i (+ i 1))~%" str) (format p " (set! (v0 7) ~A) (set! i (+ i 1))~%" str) (format p " (set! (v0 8) ~A) (set! i (+ i 1))~%" str) (format p " (set! (v0 9) ~A))~%" str) (format p "(define (tester-1)~%") (format p " (let ((o (make-oscil 1000.0))~%") (format p " (o1 (make-oscil 1000.0))~%") (format p " (o2 (make-oscil 1000.0))~%") (format p " (o3 (make-oscil 1000.0))~%") (format p " (o4 (make-oscil 1000.0))~%") (format p " (oscs (vector (make-oscil 400.0) (make-oscil 500.0) (make-oscil 600.0)))~%") (format p " (e1 (make-env '(0 .1 1 1) :length 100))~%") (format p " (e2 (make-env '(0 .1 1 1) :length 100))~%") (format p " (e3 (make-env '(0 .1 1 1) :length 100))~%") (format p " (e4 (make-env '(0 .1 1 1) :length 100))~%") (format p " (x 3.14)~%") (format p " (y -0.5)~%") (format p " (z 0.1)~%") (format p " (k 1)~%") (format p " (v (make-float-vector 10)))~%") (format p " (do ((i 0 (+ i 1)))~%") (format p " ((= i 10) v)~%") (format p " (set! (v i) ~A))))~%~%" str) (format p "(define (tester-2)~%") (format p " (let ((o (make-oscil 1000.0))~%") (format p " (o1 (make-oscil 1000.0))~%") (format p " (o2 (make-oscil 1000.0))~%") (format p " (o3 (make-oscil 1000.0))~%") (format p " (o4 (make-oscil 1000.0))~%") (format p " (oscs (vector (make-oscil 400.0) (make-oscil 500.0) (make-oscil 600.0)))~%") (format p " (e1 (make-env '(0 .1 1 1) :length 100))~%") (format p " (e2 (make-env '(0 .1 1 1) :length 100))~%") (format p " (e3 (make-env '(0 .1 1 1) :length 100))~%") (format p " (e4 (make-env '(0 .1 1 1) :length 100))~%") (format p " (x 3.14)~%") (format p " (y -0.5)~%") (format p " (z 0.1)~%") (format p " (k 1)~%") (format p " (v (make-float-vector 10)))~%") (format p " (with-sound (v :clipped #f :to-snd #f)~%") (format p " (do ((i 0 (+ i 1)))~%") (format p " ((= i 10) v)~%") (format p " (outa i ~A)))~%" str) (format p " v))~%~%") (format p "(define (tester-3)~%") (format p " (let ((o (make-oscil 1000.0))~%") (format p " (o1 (make-oscil 1000.0))~%") (format p " (o2 (make-oscil 1000.0))~%") (format p " (o3 (make-oscil 1000.0))~%") (format p " (o4 (make-oscil 1000.0))~%") (format p " (oscs (vector (make-oscil 400.0) (make-oscil 500.0) (make-oscil 600.0)))~%") (format p " (e1 (make-env '(0 .1 1 1) :length 100))~%") (format p " (e2 (make-env '(0 .1 1 1) :length 100))~%") (format p " (e3 (make-env '(0 .1 1 1) :length 100))~%") (format p " (e4 (make-env '(0 .1 1 1) :length 100))~%") (format p " (x 3.14)~%") (format p " (y -0.5)~%") (format p " (z 0.1)~%") (format p " (k 1)~%") (format p " (v (make-float-vector 10)))~%") (format p " (with-sound (v :clipped #f :to-snd #f)~%") (format p " (do ((i 0 (+ i 1)))~%") (format p " ((= i 10) v)~%") (format p " (outa i ~A)))~%" str) (format p " ;(file->array \"try-test.snd\" 0 0 10 v)~%") (format p " v))~%~%") (format p "(define (tester-4)~%") (format p " (let ((o (make-oscil 1000.0))~%") (format p " (o1 (make-oscil 1000.0))~%") (format p " (o2 (make-oscil 1000.0))~%") (format p " (o3 (make-oscil 1000.0))~%") (format p " (o4 (make-oscil 1000.0))~%") (format p " (oscs (vector (make-oscil 400.0) (make-oscil 500.0) (make-oscil 600.0)))~%") (format p " (e1 (make-env '(0 .1 1 1) :length 100))~%") (format p " (e2 (make-env '(0 .1 1 1) :length 100))~%") (format p " (e3 (make-env '(0 .1 1 1) :length 100))~%") (format p " (e4 (make-env '(0 .1 1 1) :length 100))~%") (format p " (v (make-float-vector 10))~%") (format p " (x 3.14)~%") (format p " (y -0.5)~%") (format p " (k 1)~%") (format p " (z 0.1))~%") (format p " (do ((i 0 (+ i 1))~%") (format p " (lst (make-list 10)))~%") (format p " ((= i 10) (apply float-vector lst))~%") (format p " (set! (lst i) ~A))))~%~%" str) (format p "(define (tester-5)~%") (format p " (let ((o (make-oscil 1000.0))~%") (format p " (o1 (make-oscil 1000.0))~%") (format p " (o2 (make-oscil 1000.0))~%") (format p " (o3 (make-oscil 1000.0))~%") (format p " (o4 (make-oscil 1000.0))~%") (format p " (oscs (vector (make-oscil 400.0) (make-oscil 500.0) (make-oscil 600.0)))~%") (format p " (e1 (make-env '(0 .1 1 1) :length 100))~%") (format p " (e2 (make-env '(0 .1 1 1) :length 100))~%") (format p " (e3 (make-env '(0 .1 1 1) :length 100))~%") (format p " (e4 (make-env '(0 .1 1 1) :length 100))~%") (format p " (y -0.5)~%") (format p " (k 1)~%") (format p " (z 0.1)~%") (format p " (v (make-float-vector 10)))~%") (format p " (with-sound (v :clipped #f :to-snd #f)~%") (format p " (do ((i 0 (+ i 1))~%") (format p " (x 0.0 (+ x 0.1)))~%") (format p " ((= i 10) v)~%") (format p " (outa i ~A)))~%" str) (format p " ;(file->array \"try-test.snd\" 0 0 10 v)~%") (format p " v))~%~%") (format p "(define (tester-6)~%") (format p " (let ((o (make-oscil 1000.0))~%") (format p " (o1 (make-oscil 1000.0))~%") (format p " (o2 (make-oscil 1000.0))~%") (format p " (o3 (make-oscil 1000.0))~%") (format p " (o4 (make-oscil 1000.0))~%") (format p " (oscs (vector (make-oscil 400.0) (make-oscil 500.0) (make-oscil 600.0)))~%") (format p " (e1 (make-env '(0 .1 1 1) :length 100))~%") (format p " (e2 (make-env '(0 .1 1 1) :length 100))~%") (format p " (e3 (make-env '(0 .1 1 1) :length 100))~%") (format p " (e4 (make-env '(0 .1 1 1) :length 100))~%") (format p " (k 1)~%") (format p " (v (make-float-vector 10)))~%") (format p " (do ((i 0 (+ i 1))~%") (format p " (y -0.5)~%") (format p " (z 0.1)~%") (format p " (x 0.0 (+ x 0.1)))~%") (format p " ((= i 10) v)~%") (format p " (set! (v i) ~A))))~%~%" str) (format p "(define (tester-7)~%") (format p " (let ((o (make-oscil 1000.0))~%") (format p " (o1 (make-oscil 1000.0))~%") (format p " (o2 (make-oscil 1000.0))~%") (format p " (o3 (make-oscil 1000.0))~%") (format p " (o4 (make-oscil 1000.0))~%") (format p " (oscs (vector (make-oscil 400.0) (make-oscil 500.0) (make-oscil 600.0)))~%") (format p " (e1 (make-env '(0 .1 1 1) :length 100))~%") (format p " (e2 (make-env '(0 .1 1 1) :length 100))~%") (format p " (e3 (make-env '(0 .1 1 1) :length 100))~%") (format p " (e4 (make-env '(0 .1 1 1) :length 100))~%") (format p " (x 3.14)~%") (format p " (y -0.5)~%") (format p " (k 1)~%") (format p " (z 0.1)~%") (format p " (v (make-float-vector 10)))~%") (format p " (do ((i 0 (+ i 1)))~%") (format p " ((= i 10) v)~%") (format p " (let ((zz ~A))~%" str) (format p " (set! (v i) (oscil o zz))))))~%") (format p "(define (tester-8)~%") (format p " (let ((o (make-oscil 1000.0))~%") (format p " (o1 (make-oscil 1000.0))~%") (format p " (o2 (make-oscil 1000.0))~%") (format p " (o3 (make-oscil 1000.0))~%") (format p " (o4 (make-oscil 1000.0))~%") (format p " (oscs (vector (make-oscil 400.0) (make-oscil 500.0) (make-oscil 600.0)))~%") (format p " (e1 (make-env '(0 .1 1 1) :length 100))~%") (format p " (e2 (make-env '(0 .1 1 1) :length 100))~%") (format p " (e3 (make-env '(0 .1 1 1) :length 100))~%") (format p " (e4 (make-env '(0 .1 1 1) :length 100))~%") (format p " (x 3.14)~%") (format p " (y -0.5)~%") (format p " (z 0.1)~%") (format p " (k 1)~%") (format p " (v (make-float-vector 10)))~%") (format p " (with-sound (v :clipped #f :to-snd #f)~%") (format p " (do ((i 0 (+ i 1)))~%") (format p " ((= i 10) v)~%") (format p " (let ((zz ~A))~%" str) (format p " (outa i (oscil o zz)))))~%") (format p " v))~%~%") (format p "(define (tester-9)~%") (format p " (let ((o (make-oscil 1000.0))~%") (format p " (o1 (make-oscil 1000.0))~%") (format p " (o2 (make-oscil 1000.0))~%") (format p " (o3 (make-oscil 1000.0))~%") (format p " (o4 (make-oscil 1000.0))~%") (format p " (oscs (vector (make-oscil 400.0) (make-oscil 500.0) (make-oscil 600.0)))~%") (format p " (e1 (make-env '(0 .1 1 1) :length 100))~%") (format p " (e2 (make-env '(0 .1 1 1) :length 100))~%") (format p " (e3 (make-env '(0 .1 1 1) :length 100))~%") (format p " (e4 (make-env '(0 .1 1 1) :length 100))~%") (format p " (x 3.14)~%") (format p " (y -0.5)~%") (format p " (z 0.1)~%") (format p " (k 1)~%") (format p " (v (make-float-vector 10)))~%") (format p " (do ((i 0 (+ i 1)))~%") (format p " ((= i 10) v)~%") (format p " (let ((zz ~A))~%" str) (format p " (set! (v i) (* (env e1) (oscil o zz)))))))~%") (format p "(define (tester-10)~%") (format p " (let ((o (make-oscil 1000.0))~%") (format p " (o1 (make-oscil 1000.0))~%") (format p " (o2 (make-oscil 1000.0))~%") (format p " (o3 (make-oscil 1000.0))~%") (format p " (o4 (make-oscil 1000.0))~%") (format p " (oscs (vector (make-oscil 400.0) (make-oscil 500.0) (make-oscil 600.0)))~%") (format p " (e1 (make-env '(0 .1 1 1) :length 100))~%") (format p " (e2 (make-env '(0 .1 1 1) :length 100))~%") (format p " (e3 (make-env '(0 .1 1 1) :length 100))~%") (format p " (e4 (make-env '(0 .1 1 1) :length 100))~%") (format p " (x 3.14)~%") (format p " (y -0.5)~%") (format p " (z 0.1)~%") (format p " (k 1)~%") (format p " (v (make-float-vector 10)))~%") (format p " (with-sound (v :clipped #f :to-snd #f)~%") (format p " (do ((i 0 (+ i 1)))~%") (format p " ((= i 10) v)~%") (format p " (let ((zz ~A))~%" str) (format p " (outa i (* (env e1) (oscil o zz))))))~%") (format p " v))~%~%") (format p "(define (tester-11)~%") (format p " (let ((o (make-oscil 1000.0))~%") (format p " (o1 (make-oscil 1000.0))~%") (format p " (o2 (make-oscil 1000.0))~%") (format p " (o3 (make-oscil 1000.0))~%") (format p " (o4 (make-oscil 1000.0))~%") (format p " (oscs (vector (make-oscil 400.0) (make-oscil 500.0) (make-oscil 600.0)))~%") (format p " (e1 (make-env '(0 .1 1 1) :length 100))~%") (format p " (e2 (make-env '(0 .1 1 1) :length 100))~%") (format p " (e3 (make-env '(0 .1 1 1) :length 100))~%") (format p " (e4 (make-env '(0 .1 1 1) :length 100))~%") (format p " (y -0.5)~%") (format p " (z 0.1)~%") (format p " (k 1)~%") (format p " (v (make-float-vector 10)))~%") (format p " (do ((i 0 (+ i 1)))~%") (format p " ((= i 10) v)~%") (format p " (let ((x (oscil o)))~%") (format p " (set! (v i) ~A)))))~%" str) (format p "(define (tester-12)~%") (format p " (let ((o (make-oscil 1000.0))~%") (format p " (o1 (make-oscil 1000.0))~%") (format p " (o2 (make-oscil 1000.0))~%") (format p " (o3 (make-oscil 1000.0))~%") (format p " (o4 (make-oscil 1000.0))~%") (format p " (oscs (vector (make-oscil 400.0) (make-oscil 500.0) (make-oscil 600.0)))~%") (format p " (e1 (make-env '(0 .1 1 1) :length 100))~%") (format p " (e2 (make-env '(0 .1 1 1) :length 100))~%") (format p " (e3 (make-env '(0 .1 1 1) :length 100))~%") (format p " (e4 (make-env '(0 .1 1 1) :length 100))~%") (format p " (y -0.5)~%") (format p " (z 0.1)~%") (format p " (k 1)~%") (format p " (v (make-float-vector 10)))~%") (format p " (with-sound (v :clipped #f :to-snd #f)~%") (format p " (do ((i 0 (+ i 1)))~%") (format p " ((= i 10) v)~%") (format p " (let ((x (oscil o)))~%") (format p " (outa i ~A))))~%" str) (format p " v))~%~%") (format p "(let ((v1 (tester-1))~%") (format p " (v2 (tester-2))~%") (format p " (v3 (tester-3))~%") (format p " (v4 (tester-4))~%") (format p " (v5 (tester-5))~%") (format p " (v6 (tester-6))~%") (format p " (v7 (tester-7))~%") (format p " (v8 (tester-8))~%") (format p " (v9 (tester-9))~%") (format p " (v10 (tester-10))~%") (format p " (v11 (tester-11))~%") (format p " (v12 (tester-12)))~%") (format p " (if (or (not (vequal v0 v1)) (not (vequal v1 v2)) (not (vequal v1 v3)) (not (vequal v1 v4)))~%") (format p " (format *stderr* \"~A:~~% no do: ~~A~~% float-vector-set: ~~A~~% outa->v:~~A~~% outa: ~~A~~% list: ~~A~~%\" v0 v1 v2 v3 v4))~%" str) (format p " (if (not (vequal v5 v6))~%") (format p " (format *stderr* \"dox ~A:~~% float-vector-set: ~~A~~% outa->v:~~A~~%\" v5 v6))~%" str) (format p " (if (not (vequal v7 v8))~%") (format p " (format *stderr* \"let ~A:~~% ~~A~~% ~~A~~%\" v7 v8))~%" str) (format p " (if (not (vequal v9 v10))~%") (format p " (format *stderr* \"env let ~A:~~% ~~A~~% ~~A~~%\" v9 v10))~%~%" str) (format p " (if (not (vequal v11 v12))~%") (format p " (format *stderr* \"letx ~A:~~% ~~A~~% ~~A~~%\" v11 v12))))~%~%" str))))) (define (out-args) (for-each (lambda (a) (try (format #f "~A" a)) (try (format #f "(oscil o ~A)" a)) (try (format #f "(abs (oscil o ~A))" a)) ) args1) (for-each (lambda (a) (for-each (lambda (b) (try (format #f "(+ ~A ~A)" a b)) (try (format #f "(- ~A ~A)" a b)) (try (format #f "(* ~A ~A)" a b)) (try (format #f "(cos (+ ~A ~A))" a b)) (try (format #f "(sin (* ~A ~A))" a b)) (try (format #f "(abs (* ~A ~A))" a b)) (try (format #f "(* ~A (abs ~A))" a b)) (try (format #f "(oscil o (+ ~A ~A))" a b)) (try (format #f "(oscil o (* ~A ~A))" a b)) (try (format #f "(+ ~A (oscil o ~A))" a b)) (try (format #f "(* ~A (oscil o ~A))" a b)) (try (format #f "(+ (oscil o ~A) ~A)" a b)) (try (format #f "(* (oscil o ~A) ~A)" a b)) (try (format #f "(oscil o ~A ~A)" a b)) (try (format #f "(abs (oscil o ~A ~A))" a b)) (try (format #f "(* (abs (oscil o ~A)) ~A)" a b)) ) args2)) args1) (for-each (lambda (c) (for-each (lambda (b) (for-each (lambda (a) (try (format #f "(+ ~A ~A ~A)" a b c)) (try (format #f "(+ (* ~A ~A) ~A)" a b c)) (try (format #f "(+ ~A (* ~A ~A))" a b c)) (try (format #f "(* ~A ~A ~A)" a b c)) (try (format #f "(* ~A (+ ~A ~A))" a b c)) (try (format #f "(* (+ ~A ~A) ~A)" a b c)) (try (format #f "(oscil o (+ ~A ~A ~A))" a b c)) (try (format #f "(oscil o (* ~A ~A ~A))" a b c)) (try (format #f "(oscil o (* ~A (+ ~A ~A)))" a b c)) (try (format #f "(oscil o (+ ~A (* ~A ~A)))" a b c)) (try (format #f "(oscil o (* (+ ~A ~A) ~A))" a b c)) (try (format #f "(oscil o (+ (* ~A ~A) ~A))" a b c)) (try (format #f "(+ ~A (oscil o (+ ~A ~A)))" a b c)) (try (format #f "(+ ~A (oscil o (* ~A ~A)))" a b c)) (try (format #f "(* ~A (oscil o (+ ~A ~A)))" a b c)) (try (format #f "(* ~A (oscil o (* ~A ~A)))" a b c)) (try (format #f "(+ ~A ~A (oscil o ~A))" a b c)) (try (format #f "(* ~A ~A (oscil o ~A))" a b c)) (try (format #f "(+ (* ~A ~A) (oscil o ~A))" a b c)) (try (format #f "(* (+ ~A ~A) (oscil o ~A))" a b c)) (try (format #f "(+ ~A (* ~A (oscil o ~A)))" a b c)) (try (format #f "(* ~A (+ ~A (oscil o ~A)))" a b c)) (try (format #f "(+ ~A (oscil o ~A) ~A)" a b c)) (try (format #f "(* ~A (oscil o ~A) ~A)" a b c)) (try (format #f "(+ (* ~A (oscil o ~A)) ~A)" a b c)) (try (format #f "(* (+ ~A (oscil o ~A)) ~A)" a b c)) (try (format #f "(+ ~A (* (oscil o ~A) ~A))" a b c)) (try (format #f "(* ~A (+ (oscil o ~A) ~A))" a b c)) (try (format #f "(+ (oscil o ~A) ~A ~A)" a b c)) (try (format #f "(+ (oscil o ~A) (* ~A ~A))" a b c)) (try (format #f "(* (oscil o ~A) (+ ~A ~A))" a b c)) (try (format #f "(* (oscil o ~A) ~A ~A)" a b c)) (try (format #f "(+ ~A (abs ~A) ~A)" a b c)) (try (format #f "(+ ~A (sin ~A) ~A)" a b c)) (try (format #f "(+ ~A (cos ~A) ~A)" a b c)) (try (format #f "(* (cos ~A) (oscil o ~A ~A))" a b c)) (try (format #f "(+ (oscil o ~A ~A) ~A)" a b c)) (try (format #f "(+ (abs (oscil o ~A ~A)) ~A)" a b c)) (try (format #f "(+ (cos (oscil o ~A ~A)) ~A)" a b c)) (try (format #f "(+ (sin (oscil o ~A ~A)) ~A)" a b c)) ) args3)) args2)) args1)) (out-args) (set! *clm-file-buffer-size* old-size) ))) ;;; ---------------- test 22: with-sound ---------------- (require snd-prc95.scm snd-jcrev.scm snd-maraca.scm snd-singer.scm snd-strad.scm snd-noise.scm snd-clm-ins.scm snd-jcvoi.scm) (require snd-piano.scm snd-play.scm snd-zip.scm snd-clm23.scm snd-freeverb.scm snd-grani.scm snd-animals.scm snd-big-gens.scm) (require snd-dlocsig.scm snd-sndwarp.scm) (defgenerator st1 one two) (defgenerator st2 (one 11) (two 22)) (defgenerator grab-bag (flt 0.0) (flt1 1.0) (i 0) (i1 123) (bool #f) (bool1 #t) (ch #\c) (ch1 #\c) (str "hi") (str1 "hi1") (lst ()) (sym 'hi) (v #f) (rd #f) (mxrd #f) (sd #f) (gen #f) (fvect #f) (ivect #f) (vvect #f) (cvect #f)) (define (snd_test_22) (definstrument (green3 start dur freq amp amp-env noise-freq noise-width noise-max-step) ;; brownian noise on amp env (let ((grn (make-green-noise-interp :frequency noise-freq :amplitude noise-max-step :high (* 0.5 noise-width) :low (* -0.5 noise-width))) (osc (make-oscil freq)) (e (make-env amp-env :scaler amp :duration dur)) (beg (floor (* start *clm-srate*))) (end (floor (* (+ start dur) *clm-srate*)))) (do ((i beg (+ i 1))) ((= i end)) (outa i (* (env e) (+ 1.0 (green-noise-interp grn 0.0)) (oscil osc)))))) ;(with-sound () (green3 0 2.0 440 .5 '(0 0 1 1 2 1 3 0) 100 .2 .02)) (definstrument (green4 start dur freq amp freq-env gliss noise-freq noise-width noise-max-step) ;; same but on freq env (let ((grn (make-green-noise-interp :frequency noise-freq :amplitude (hz->radians noise-max-step) :high (hz->radians (* 0.5 noise-width)) :low (hz->radians (* -0.5 noise-width)))) (osc (make-oscil freq)) (e (make-env freq-env :scaler (hz->radians gliss) :duration dur)) (beg (seconds->samples start)) (end (seconds->samples (+ start dur)))) (do ((i beg (+ i 1))) ((= i end)) (outa i (* amp (oscil osc (+ (env e) (green-noise-interp grn 0.0)))))))) (define (ws-sine freq) (let ((o (make-oscil freq))) (do ((i 0 (+ i 1))) ((= i 100)) (outa i (oscil o))))) (define (step-src) (let* ((rd (make-sampler 0)) (o (make-oscil 2205.0)) (s (make-src :srate 0.0 :input rd)) (incr (+ 2.0 (oscil o))) (tempfile (with-sound ((snd-tempnam) :srate (srate) :to-snd #f :comment "step-src") (do ((samp 0 (+ samp 1))) ((sampler-at-end? rd)) (outa samp (src s incr)) (if (= (modulo samp 2205) 0) (set! incr (+ 2.0 (oscil o))))))) (len (mus-sound-framples tempfile))) (set-samples 0 (- len 1) tempfile #f #f #t "step-src" 0 #f #t))) (define* (clm-reverb-sound reverb-amount reverb (reverb-data ()) snd) (let ((output (snd-tempnam)) (revout (snd-tempnam)) (len (+ (framples snd) (srate snd)))) (scale-by (- 1.0 reverb-amount) snd) (save-sound-as output snd) (undo 1 snd) (scale-by reverb-amount snd) (save-sound-as revout snd) (undo 1 snd) (dynamic-wind (lambda () (set! *output* (continue-sample->file output)) (set! *clm-srate* (srate snd)) (set! *reverb* (make-file->sample revout))) (lambda () (apply reverb reverb-data)) (lambda () (mus-close *reverb*) (mus-close *output*) (set! *reverb* #f) (set! *output* #f) (delete-file revout) (set! (samples 0 len snd #f #f #f 0 #f #t) output))))) (define* (optkey-1 a) a) (define* (optkey-2 (a 3) b) (list a b)) (define* (optkey-3 a b c) (list a b c)) (define* (optkey-4 (a 1) (b 2) (c 3) d) (list a b c d)) (define (fir+comb beg dur freq amp size) (let ((dly (make-comb :scaler .9 :size size))) (let ((start (floor (* *clm-srate* beg))) (end (floor (* *clm-srate* (+ beg dur)))) (flt (make-fir-filter :order size :xcoeffs (mus-data dly))) (r (make-rand freq))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (fir-filter flt (comb dly (rand r))))))))) (definstrument (dloc-sinewave start-time duration freq amp (amp-env '(0 1 1 1)) (path (make-path :path '(-10 10 0 5 10 10)))) (let* ((vals (make-dlocsig :start-time start-time :duration duration :path path)) (dloc (car vals)) (beg (cadr vals)) (end (caddr vals))) (let ((osc (make-oscil :frequency freq)) (aenv (make-env :envelope amp-env :scaler amp :duration duration))) (do ((i beg (+ i 1))) ((= i end)) (dlocsig dloc i (* (env aenv) (oscil osc))))))) (definstrument (dlocsig-sinewave-1 start-time duration freq amp (amp-env '(0 1 1 1)) (path (make-path :path '(-10 10 0 5 10 10))) (decode amplitude-panning) initdly) (let* ((vals (make-dlocsig :start-time start-time :duration duration :render-using decode :initial-delay initdly :path path)) (dloc (car vals)) (beg (cadr vals)) (end (caddr vals))) (let ((osc (make-oscil :frequency freq)) (aenv (make-env :envelope amp-env :scaler amp :duration duration))) (do ((i beg (+ i 1))) ((= i end)) (dlocsig dloc i (* (env aenv) (oscil osc))))))) (define (mix-move-sound start-time file path) (let* ((duration (mus-sound-duration file)) (rd (make-sampler 0 file)) (start (round (* *clm-srate* start-time))) (tmp-sound (with-temp-sound (:channels 4 :srate (mus-sound-srate file)) (let* ((vals (make-dlocsig :start-time 0 :duration duration :path path)) (dloc (car vals)) (beg (cadr vals)) (end (caddr vals))) (do ((i beg (+ i 1))) ((= i end)) (dlocsig dloc i (read-sample rd))))))) (mix tmp-sound start #t #f #f *with-mix-tags* #t))) (definstrument (defopt-simp beg dur (frequency 440.0) (amplitude 0.1)) (let ((os (make-oscil frequency)) (end (+ beg dur))) (do ((i beg (+ i 1))) ((= i end)) (outa i (* amplitude (oscil os)))))) (definstrument (jcrev2) (let ((allpass11 (make-all-pass -0.700 0.700 1051)) (allpass21 (make-all-pass -0.700 0.700 337)) (allpass31 (make-all-pass -0.700 0.700 113)) (comb11 (make-comb 0.742 4799)) (comb21 (make-comb 0.733 4999)) (comb31 (make-comb 0.715 5399)) (comb41 (make-comb 0.697 5801)) (outdel11 (make-delay (seconds->samples .01))) (allpass12 (make-all-pass -0.700 0.700 1051)) (allpass22 (make-all-pass -0.700 0.700 337)) (allpass32 (make-all-pass -0.700 0.700 113)) (comb12 (make-comb 0.742 4799)) (comb22 (make-comb 0.733 4999)) (comb32 (make-comb 0.715 5399)) (comb42 (make-comb 0.697 5801)) (outdel12 (make-delay (seconds->samples .01))) (len (floor (+ (framples *reverb*) *clm-srate*)))) (let ((combs1 (make-comb-bank (vector comb11 comb21 comb31 comb41))) (combs2 (make-comb-bank (vector comb12 comb22 comb32 comb42))) (allpasses1 (make-all-pass-bank (vector allpass11 allpass21 allpass31))) (allpasses2 (make-all-pass-bank (vector allpass12 allpass22 allpass32)))) (do ((i 0 (+ i 1))) ((= i len)) (outa i (delay outdel11 (comb-bank combs1 (all-pass-bank allpasses1 (ina i *reverb*)))))) (do ((i 0 (+ i 1))) ((= i len)) (outb i (delay outdel12 (comb-bank combs2 (all-pass-bank allpasses2 (inb i *reverb*))))))))) (definstrument (floc-simp beg dur (amp 0.5) (freq 440.0) (ramp 2.0) (rfreq 1.0) offset) (let ((os (make-pulse-train freq amp)) (floc (make-flocsig :reverb-amount 0.1 :frequency rfreq :amplitude ramp :offset offset)) (start (seconds->samples beg)) (end (seconds->samples (+ beg dur)))) (do ((i start (+ i 1))) ((= i end)) (flocsig floc i (pulse-train os))))) (define (test-ws-errors) ;; since we only catch 'mus-error and 'with-sound-interrupt above, any other error ;; closes *output* and returns to the top-level (define (bad-ins start) (set! (playing) #f)) (let ((prev (find-sound "test.snd"))) (if (sound? prev) (close-sound prev))) (if (mus-output? *output*) (begin (snd-display #__line__ ";ws-error start: *output*: ~A" *output*) (mus-close *output*) (set! *output* #f))) ;; ---------------- catch 'wrong-type-arg (not handled by with-sound) ---------------- (let ((tag (catch #t (lambda () (with-sound ("test.snd") (fm-violin 0 1 440 .1) (fm-violin .1 1 660 .1) (fm-violin .2 1 880 .1) (fm-violin .3 1 -220 .1))) (lambda args args)))) (if (or (not (list? tag)) (not (eq? (car tag) 'wrong-type-arg))) (snd-display #__line__ ";ws-error -220: ~A" tag)) (if (mus-output? *output*) (begin (snd-display #__line__ ";ws-error -220: *output*: ~A" *output*) (mus-close *output*) (set! *output* #f))) (let ((prev (find-sound "test.snd"))) (if (sound? prev) (begin (snd-display #__line__ ";ws error -220 opened test.snd?") (close-sound prev))))) ;; ---------------- catch 'mus-error (handled by with-sound, but no continuation -- appears to exit after cleaning up) ---------------- (snd-display #__line__ ";error printout expected.....") (let ((tag (catch #t (lambda () (with-sound ("test.snd") (fm-violin 0 1 440 .1) (fm-violin .1 1 660 .1) (fm-violin .2 1 880 .1) (fm-violin .3 1 220 .1 :amp-env '(0 0 1 1 .5 1 0 0)))) (lambda args args)))) (if (or (not (string? tag)) (not (string=? tag "test.snd"))) (snd-display #__line__ ";ws-error bad env: ~A" tag)) (if (mus-output? *output*) (begin (snd-display #__line__ ";ws-error bad env: *output*: ~A" *output*) (mus-close *output*) (set! *output* #f))) (let ((prev (find-sound "test.snd"))) (if (not (sound? prev)) (snd-display #__line__ ";ws error bad env did not open test.snd?") (close-sound prev)))) (if (sound? (find-sound "test.snd")) (close-sound (find-sound "test.snd"))) (delete-file "test.snd") ) (dismiss-all-dialogs) (do ((clmtest 0 (+ 1 clmtest))) ((= clmtest tests)) (log-mem clmtest) ; (set! *clm-notehook* (lambda args (display args) (newline))) ;; check clm output for bad zero case (for-each (lambda (type) (let ((ind (find-sound (with-sound (:sample-type type :srate 22050) (fm-violin 0 .1 440 .1) (fm-violin 10 .1 440 .1) (fm-violin 100 .1 440 .1) (fm-violin 250 .1 440 .1))))) (let ((mx (maxamp ind))) (if (ffneq mx .1) ; mus-byte -> 0.093 (snd-display #__line__ ";max: ~A, format: ~A" mx (mus-sample-type->string type)))))) (list mus-bshort mus-lshort mus-mulaw mus-alaw mus-byte mus-lfloat mus-bint mus-lint mus-b24int mus-l24int mus-ubshort mus-ulshort mus-ubyte mus-bfloat mus-bdouble mus-ldouble)) (with-sound () (fm-violin 0 .1 440 .1)) (with-sound (:continue-old-file #t) (fm-violin .2 .1 660 .04)) (let ((ind (find-sound "test.snd"))) (if (fneq (maxamp ind 0) .1) (snd-display #__line__ ";maxamp after continued sound: ~A" (maxamp ind 0))) (if (fneq (/ (framples ind) (srate ind)) .3) (snd-display #__line__ ";duration after continued sound: ~A" (/ (framples ind) (srate ind)))) (close-sound ind)) (with-sound (:srate 22050 :channels 2 :output "test1.snd") (fm-violin 0 .1 440 .1 :degree 45.0)) (let ((ind (find-sound "test1.snd"))) (if (not ind) (snd-display #__line__ ";with-sound (1): ~A" (map file-name (sounds)))) (let ((mx (maxamp))) (if (fneq mx .05) (snd-display #__line__ ";with-sound max (1): ~A" (maxamp))) (if (or (not (= (srate ind) 22050)) (not (= (mus-sound-srate "test1.snd") 22050))) (snd-display #__line__ ";with-sound srate (1): ~A (~A, ~A)" (srate ind) *clm-srate* (mus-sound-srate "test1.snd"))) (if (and (not (= (framples ind) 2205)) (not (= (framples ind) 2206))) (snd-display #__line__ ";with-sound framples (1): ~A" (framples ind))) (if (or (not (= (chans ind) 2)) (not (= (mus-sound-chans "test1.snd") 2))) (snd-display #__line__ ";with-sound chans (1): ~A" (chans ind)))) (close-sound ind) (delete-file "test1.snd")) (with-sound (:srate 48000 :channels 2 :header-type mus-riff :sample-type mus-lshort :output "test1.snd") (fm-violin 0 .1 440 .1)) (let ((ind (find-sound "test1.snd"))) (if (or (not (= (srate ind) 48000)) (not (= (mus-sound-srate "test1.snd") 48000))) (snd-display #__line__ ";with-sound srate (48000, r): ~A (~A, ~A)" (srate ind) *clm-srate* (mus-sound-srate "test1.snd"))) (if (not (= (header-type ind) mus-riff)) (snd-display #__line__ ";with-sound type (~A, r): ~A" mus-riff (header-type ind))) (if (not (= (chans ind) 2)) (snd-display #__line__ ";with-sound chans (2, r): ~A" (chans ind))) (close-sound ind) (delete-file "test1.snd")) (with-sound (:srate 48000 :channels 2 :header-type mus-rf64 :sample-type mus-lshort :output "test1.snd") (fm-violin 0 .1 440 .1)) (let ((ind (find-sound "test1.snd"))) (if (or (not (= (srate ind) 48000)) (not (= (mus-sound-srate "test1.snd") 48000))) (snd-display #__line__ ";with-sound srate (48000, r): ~A (~A, ~A)" (srate ind) *clm-srate* (mus-sound-srate "test1.snd"))) (if (not (= (header-type ind) mus-rf64)) (snd-display #__line__ ";with-sound type (~A, r): ~A" mus-rf64 (header-type ind))) (if (not (= (chans ind) 2)) (snd-display #__line__ ";with-sound chans (2, r): ~A" (chans ind))) (close-sound ind) (delete-file "test1.snd")) (with-sound (:srate 48000 :channels 2 :header-type mus-caff :sample-type mus-lshort :output "test1.snd") (fm-violin 0 .1 440 .1)) (let ((ind (find-sound "test1.snd"))) (if (or (not (= (srate ind) 48000)) (not (= (mus-sound-srate "test1.snd") 48000))) (snd-display #__line__ ";with-sound mus-caff srate (48000, r): ~A (~A, ~A)" (srate ind) *clm-srate* (mus-sound-srate "test1.snd"))) (if (not (= (header-type ind) mus-caff)) (snd-display #__line__ ";with-sound type (~A, r): ~A" mus-caff (header-type ind))) (if (not (= (chans ind) 2)) (snd-display #__line__ ";with-sound mus-caff chans (2, r): ~A" (chans ind))) (close-sound ind) (delete-file "test1.snd")) (with-sound (:srate 8000 :channels 3 :header-type mus-next :output "test1.snd") (fm-violin 0 .1 440 .1)) (let ((ind (find-sound "test1.snd"))) (if (not (= (srate ind) 8000)) (snd-display #__line__ ";with-sound srate (8000, s): ~A (~A, ~A)" (srate ind) *clm-srate* (mus-sound-srate "test1.snd"))) (if (not (= (header-type ind) mus-next)) (snd-display #__line__ ";with-sound type (~A, s): ~A" mus-next (header-type ind))) (if (not (= (chans ind) 3)) (snd-display #__line__ ";with-sound chans (3, s): ~A" (chans ind))) (close-sound ind) (delete-file "test1.snd")) (with-sound (:srate 96000 :channels 4 :header-type mus-aifc :output "test1.snd") (fm-violin 0 .1 440 .1)) (let ((ind (find-sound "test1.snd"))) (if (not (= (srate ind) 96000)) (snd-display #__line__ ";with-sound srate (96000, t): ~A (~A, ~A)" (srate ind) *clm-srate* (mus-sound-srate "test1.snd"))) (if (not (= (header-type ind) mus-aifc)) (snd-display #__line__ ";with-sound type (~A, t): ~A" mus-aifc (header-type ind))) (if (not (= (chans ind) 4)) (snd-display #__line__ ";with-sound chans (4, t): ~A" (chans ind))) (close-sound ind) (delete-file "test1.snd")) (with-sound (:srate 22050 :channels 1 :header-type mus-raw :output "test1.snd") (fm-violin 0 .1 440 .1)) (let ((ind (find-sound "test1.snd"))) (if (not (= (srate ind) 22050)) (snd-display #__line__ ";with-sound srate (22050, u): ~A (~A, ~A)" (srate ind) *clm-srate* (mus-sound-srate "test1.snd"))) (if (not (= (header-type ind) mus-raw)) (snd-display #__line__ ";with-sound type (~A, u): ~A" mus-raw (header-type ind))) (if (not (= (chans ind) 1)) (snd-display #__line__ ";with-sound chans (1, u): ~A" (chans ind))) (close-sound ind) (delete-file "test1.snd")) (with-sound (:srate 22050 :channels 2 :output "test1.snd" :reverb jc-reverb) (if (not (= (mus-sound-srate (mus-file-name *output*)) 22050)) (snd-display #__line__ ";srate file *output*: ~A" (mus-sound-srate (mus-file-name *output*)))) (if (not (= (mus-sound-srate (mus-file-name *reverb*)) 22050)) (snd-display #__line__ ";srate file *reverb*: ~A" (mus-sound-srate (mus-file-name *reverb*)))) (fm-violin 0 .1 440 .1 :degree 45.0)) (let ((ind (find-sound "test1.snd"))) (if (not ind) (snd-display #__line__ ";with-sound (2): ~A" (map file-name (sounds))) (if (> (- (framples ind) (+ 22050 2205)) 1) (snd-display #__line__ ";with-sound reverbed framples (2): ~A" (framples ind)))) (close-sound ind)) (with-sound (:srate 22050 :comment "Snd+Run!" :scaled-to .5) (fm-violin 0 .1 440 .1)) (let ((ind (find-sound "test.snd"))) (if (not ind) (snd-display #__line__ ";with-sound: ~A" (map file-name (sounds)))) (let ((mx (maxamp))) (if (fneq mx .5) (snd-display #__line__ ";with-sound scaled-to: ~A" (maxamp))) (if (not (string=? (comment ind) "Snd+Run!")) (snd-display #__line__ ";with-sound comment: ~A (~A)" (comment ind) (mus-sound-comment "test.snd")))) (close-sound ind)) (with-sound (:scaled-to .9 :channels 2) (fm-violin 0 .1 440 1.5 :degree 90)) (let ((ind (find-sound "test.snd"))) (if (not ind) (snd-display #__line__ ";with-sound: ~A" (map file-name (sounds)))) (let ((mx0 (maxamp ind 0)) (mx1 (maxamp ind 1))) (if (> (max mx0 mx1) .9) (snd-display #__line__ ";with-sound scaled-to: ~A" (maxamp)))) (close-sound ind)) (with-sound (:scaled-to .9 :channels 2) (fm-violin 0 .1 440 1.5 :degree 0)) (let ((ind (find-sound "test.snd"))) (if (not ind) (snd-display #__line__ ";with-sound: ~A" (map file-name (sounds)))) (let ((mx0 (maxamp ind 0)) (mx1 (maxamp ind 1))) (if (> (max mx0 mx1) .9) (snd-display #__line__ ";with-sound scaled-to: ~A" (maxamp)))) (close-sound ind)) (with-sound (:srate 22050 :scaled-by .5 :header-type mus-aifc :sample-type mus-bfloat) (fm-violin 0 .1 440 .1)) (let ((ind (find-sound "test.snd"))) (if (not ind) (snd-display #__line__ ";with-sound: ~A" (map file-name (sounds)))) (let ((mx (maxamp))) (if (fneq mx .05) (snd-display #__line__ ";with-sound scaled-by: ~A" (maxamp))) (if (not (= (header-type ind) mus-aifc)) (snd-display #__line__ ";with-sound type: ~A (~A)" (header-type ind) (mus-header-type-name (header-type ind)))) (if (not (= (sample-type ind) mus-bfloat)) (snd-display #__line__ ";with-sound format: ~A (~A)" (sample-type ind) (mus-sample-type-name (sample-type ind))))) (close-sound ind)) (hook-push open-raw-sound-hook (lambda (hook) (set! (hook 'result) (list 1 22050 mus-bshort)))) (with-sound (:header-type mus-raw) (fm-violin 0 1 440 .1)) (set! (hook-functions open-raw-sound-hook) ()) (let ((ind (find-sound "test.snd"))) (if (not ind) (snd-display #__line__ ";with-sound (raw out): ~A" (map file-name (sounds)))) (if (not (= (header-type ind) mus-raw)) (snd-display #__line__ ";with-sound type raw: ~A (~A)" (header-type ind) (mus-header-type-name (header-type ind)))) (if (and (not (= (sample-type ind) mus-bshort)) (not (= (sample-type ind) mus-bfloat)) (not (= (sample-type ind) mus-lfloat))) (snd-display #__line__ ";with-sound format raw: ~A (~A)" (sample-type ind) (mus-sample-type-name (sample-type ind)))) (close-sound ind)) (with-sound (:srate 44100 :statistics #t) (ws-sine 1000)) (let ((ind (find-sound "test.snd"))) (let ((i -1)) (scan-channel (lambda (y) (set! i (+ i 1)) (and (< i 100) (fneq y (sin (* 2 pi i (/ 1000.0 44100.0)))) (begin (format #t "~%;with-sound sine: ~D ~A ~A" i y (sin (* 2 pi i (/ 1000.0 44100.0)))) #t))))) (close-sound ind)) (with-sound () (do ((i 0 (+ i 1))) ((= i 3)) (let ((gen (make-oscil 440.0)) (e (make-env (float-vector 0.0 0.0 1.0 1.0 2.0 0.0) 0.1 1.0)) (beg (* i 50000)) (end (+ 44100 (* i 50000)))) (do ((k beg (+ k 1))) ((= k end)) (outa k (* (env e) (oscil gen))))))) (let ((ind (find-sound "test.snd"))) (if (> (abs (- (framples ind) 144100)) 2) (snd-display #__line__ ";with-sound make-oscil framples: ~A" (framples))) (if (fneq (maxamp ind) .1) (snd-display #__line__ ";with-sound make-oscil maxamp: ~A" (maxamp ind))) (close-sound ind)) (let ((old-srate *clm-srate*)) (with-sound () (if (not (= old-srate *clm-srate*)) (format #t ";srates: ~A ~A~%" old-srate, *clm-srate*)) (with-sound (:srate 12345) (if (not (= *clm-srate* 12345)) (format #t ";clm-srate: ~A (12345)~%" *clm-srate*))) (if (not (= old-srate *clm-srate*)) (format #t ";returned srates: ~A ~A~%" old-srate, *clm-srate*)))) (for-each close-sound (sounds)) (if (file-exists? "ii.scm") (begin (time (load "ii.scm")) (for-each close-sound (sounds)) (delete-file "test.snd") (delete-file "test.rev"))) (let ((var (make-st1 :one 1 :two 2))) (if (not (= (var 'one) 1)) (snd-display #__line__ ";st1-one: ~A" (var 'one))) (if (not (= (var 'two) 2)) (snd-display #__line__ ";st1-two: ~A" (var 'two))) (if (not (st1? var)) (snd-display #__line__ ";st1? ~A (~A)" (st1? var) var)) (set! (var 'one) 321) (set! (var 'two) "hiho") (if (not (= (var 'one) 321)) (snd-display #__line__ ";st1-one (321): ~A" (var 'one))) (if (not (string=? (var 'two) "hiho")) (snd-display #__line__ ";st1-two (hiho): ~A" (var 'two))) (set! var (make-st1)) (if (fneq (var 'one) 0.0) (snd-display #__line__ ";st1-one #f: ~A" (var 'one))) (if (fneq (var 'two) 0.0) (snd-display #__line__ ";st1-two #f: ~A" (var 'two))) (set! var (make-st1 :two 3)) (if (fneq (var 'one) 0.0) (snd-display #__line__ ";st1-one #f (def): ~A" (var 'one))) (if (not (= (var 'two) 3)) (snd-display #__line__ ";st1-two (3): ~A" (var 'two)))) (let ((var (make-st2 :one 1 :two 2))) (if (not (= (var 'one) 1)) (snd-display #__line__ ";st2-one: ~A" (var 'one))) (if (not (= (var 'two) 2)) (snd-display #__line__ ";st2-two: ~A" (var 'two))) (if (not (st2? var)) (snd-display #__line__ ";st2? ~A (~A)" (st1? var) var)) (if (st1? var) (snd-display #__line__ ";st1? (not ~A): ~A" (st1? var) var)) (set! (var 'one) 321) (set! (var 'two) "hiho") (if (not (= (var 'one) 321)) (snd-display #__line__ ";st2-one (321): ~A" (var 'one))) (if (not (string=? (var 'two) "hiho")) (snd-display #__line__ ";st2-two (hiho): ~A" (var 'two))) (set! var (make-st2)) (if (not (= (var 'one) 11)) (snd-display #__line__ ";st2-one 11: ~A" (var 'one))) (if (not (= (var 'two) 22)) (snd-display #__line__ ";st2-two 22: ~A" (var 'two))) (set! var (make-st2 :two 3)) (if (not (= (var 'one) 11)) (snd-display #__line__ ";st2-one 11 (def): ~A" (var 'one))) (if (not (= (var 'two) 3)) (snd-display #__line__ ";st2-two (3): ~A" (var 'two)))) (let ((gad (make-grab-bag))) (if (not (= (gad 'i) 0)) (snd-display #__line__ ";grab-bag-i: ~A" (gad 'i))) (set! (gad 'flt) 123.0) (set! (gad 'v) (float-vector .1 .2 .3)) (set! (gad 'fvect) (vector .1 .2 .3)) (set! (gad 'ivect) (make-vector 3 1)) (set! (gad 'cvect) (make-vector 3 #f)) (do ((i 0 (+ i 1))) ((= i 3)) (vector-set! (gad 'cvect) i (make-oscil 440.0))) (set! (gad 'gen) (make-oscil 440.0)) (let ((val 0.0)) (set! val (gad 'flt)) (if (fneq val 123.0) (snd-display #__line__ ";defgenerator flt: ~A ~A" val (gad 'flt)))) (if (fneq (gad 'flt1) 1.0) (snd-display #__line__ ";defgenerator flt1: ~A" (gad 'flt1))) (if (not (= (gad 'i) 0)) (snd-display #__line__ ";defgenerator i: ~A" (gad 'i))) (if (not (= (gad 'i1) 123)) (snd-display #__line__ ";defgenerator i1: ~A" (gad 'i1)))) (let () (defgenerator (g1 :methods (list (cons 'g1-method (lambda (g) 440))))) (let ((g (make-g1))) (if (not (g1? g)) (format #t ";not g1: ~A~%" (reverse (map values g)))) (if (not (= ((g 'g1-method) g) 440)) (format #t ";g1-method: ~A~%" ((g 'g1-method) g))))) (if (file-exists? "test.snd") (delete-file "test.snd")) (set! *clm-srate* 22050) (set! *default-output-srate* 22050) (let ((outer (with-sound () (sound-let ((a () (fm-violin 0 .1 440 .1))) (mus-file-mix *output* a))))) (if (not (string=? outer "test.snd")) (snd-display #__line__ ";with-sound returns: ~A" outer)) (let ((ind (find-sound outer))) (if (or (not (sound? ind)) (> (- (framples ind) (floor (* *clm-srate* .1))) 1)) (snd-display #__line__ ";sound-let: ~A ~A" (framples ind) (floor (* *clm-srate* .1)))) (close-sound ind))) (if (file-exists? "test.snd") (delete-file "test.snd")) (let ((outer (with-sound () (sound-let ((a () (fm-violin 0 .1 440 .1)) (b 100)) (mus-file-mix *output* a b) (sound-let ((c (:channels 1 :output "temp.snd") (fm-violin 0 .1 110.0 .1))) (mus-file-mix *output* c)))))) (if (not (string=? outer "test.snd")) (snd-display #__line__ ";with-sound (2) returns: ~A" outer)) (let ((ind (find-sound outer))) (if (or (not (sound? ind)) (> (- (framples ind) (+ 100 (floor (* *clm-srate* .1)))) 1)) (snd-display #__line__ ";sound-let (2): ~A ~A" (framples ind) (+ 100 (floor (* *clm-srate* .1))))) (if (file-exists? "temp.snd") (snd-display #__line__ ";sound-let explicit output exists?")) (close-sound ind))) (let ((w (init-with-sound))) (fm-violin 0 1 440 .1) (let ((outer (finish-with-sound w))) (if (not (string=? outer "test.snd")) (snd-display #__line__ ";finish-with-sound returns: ~A" outer)) (let ((ind (find-sound outer))) (if (not (sound? ind)) (snd-display #__line__ ";init-with-sound: ~A" (map short-file-name (sounds))) (begin (if (fneq (maxamp ind 0) .1) (snd-display #__line__ ";init-with-sound max: ~A" (maxamp ind 0))) (close-sound ind)))))) (let ((w (init-with-sound :output "test.aiff" :header-type mus-aifc :scaled-to .5))) (fm-violin 0 1 440 .1) (let ((outer (finish-with-sound w))) (if (not (string=? outer "test.aiff")) (snd-display #__line__ ";finish-with-sound (2) returns: ~A ~A" outer w)) (let ((ind (find-sound outer))) (if (not (sound? ind)) (snd-display #__line__ ";init-with-sound (2): ~A" (map short-file-name (sounds))) (begin (if (fneq (maxamp ind 0) .5) (snd-display #__line__ ";init-with-sound scaled-to: ~A ~A" (maxamp ind 0) w)) (if (not (= (header-type ind) mus-aifc)) (snd-display #__line__ ";init-with-sound type: ~A ~A" (header-type ind) w)) (close-sound ind)))))) (with-sound ("test1.snd" :reverb freeverb :reverb-data '(:output-gain 3.0)) (fm-violin 0 .1 440 .1 :reverb-amount .1)) (let ((ind (find-sound "test1.snd"))) (if (not ind) (snd-display #__line__ ";with-sound (freeverb): ~A" (map file-name (sounds)))) (if (<= (maxamp ind) .1) (snd-display #__line__ ";freeverb 3.0: ~A" (maxamp ind))) (close-sound ind) (delete-file "test1.snd")) (with-sound ("test1.snd" :reverb freeverb :reverb-data '(:output-gain 3.0 :global 0.5)) (fm-violin 0 .1 440 .1 :reverb-amount .1)) (let ((ind (find-sound "test1.snd"))) (if (not ind) (snd-display #__line__ ";with-sound (freeverb): ~A" (map file-name (sounds)))) (if (<= (maxamp ind) .16) (snd-display #__line__ ";freeverb 3.0 global 0.5: ~A" (maxamp ind))) (close-sound ind) (delete-file "test1.snd")) (set! *clm-srate* 22050) (set! *default-output-srate* 22050) (let ((fmt1 '(0 1200 100 1000)) (fmt2 '(0 2250 100 1800)) (fmt3 '(0 4500 100 4500)) (fmt4 '(0 6750 100 8100)) (amp1 '(0 .67 100 .7)) (amp2 '(0 .95 100 .95)) (amp3 '(0 .28 100 .33)) (amp4 '(0 .14 100 .15)) (ind1 '(0 .75 100 .65)) (ind2 '(0 .75 100 .75)) (ind3 '(0 1 100 1)) (ind4 '(0 1 100 1)) (skwf '(0 0 100 0)) (ampf '(0 0 25 1 75 1 100 0)) (ranf '(0 .5 100 .5)) (index '(0 1 100 1)) (solid '(0 0 5 1 95 1 100 0)) (bassdr2 '(.5 .06 1 .62 1.5 .07 2.0 .6 2.5 .08 3.0 .56 4.0 .24 5 .98 6 .53 7 .16 8 .33 9 .62 10 .12 12 .14 14 .86 16 .12 23 .14 24 .17)) (tenordr '(.3 .04 1 .81 2 .27 3 .2 4 .21 5 .18 6 .35 7 .03 8 .07 9 .02 10 .025 11 .035))) ;; a partial of .3 makes a click (or a buzz in this case) -- can this be right? ;; we currently get away with it because it is normalized out of existence ;; the .5 business in the bassdr2 works because it is like adding abs(sin) (with-sound (:reverb nrev :play #f) (drone .000 4.000 115.000 (* .25 .500) solid bassdr2 .100 .500 .030 45.000 1 .010 10) (drone .000 4.000 229.000 (* .25 .500) solid tenordr .100 .500 .030 45.000 1 .010 11) (drone .000 4.000 229.500 (* .25 .500) solid tenordr .100 .500 .030 45.000 1 .010 9) (canter .000 2.100 918 (* .25 .700) 45.000 1 .050 ampf ranf skwf .050 .010 10 index .005 .005 amp1 ind1 fmt1 amp2 ind2 fmt2 amp3 ind3 fmt3 amp4 ind4 fmt4 ) (canter 2.100 .300 688.5 (* .25 .700) 45.000 1 .050 ampf ranf skwf .050 .010 10 index .005 .005 amp1 ind1 fmt1 amp2 ind2 fmt2 amp3 ind3 fmt3 amp4 ind4 fmt4 ) (canter 2.400 .040 826.2 (* .25 .700) 45.000 1 .050 ampf ranf skwf .050 .010 10 index .005 .005 amp1 ind1 fmt1 amp2 ind2 fmt2 amp3 ind3 fmt3 amp4 ind4 fmt4 ) (canter 2.440 .560 459 (* .25 .700) 45.000 1 .050 ampf ranf skwf .050 .010 10 index .005 .005 amp1 ind1 fmt1 amp2 ind2 fmt2 amp3 ind3 fmt3 amp4 ind4 fmt4 ) (canter 3.000 .040 408 (* .25 .700) 45.000 1 .050 ampf ranf skwf .050 .010 10 index .005 .005 amp1 ind1 fmt1 amp2 ind2 fmt2 amp3 ind3 fmt3 amp4 ind4 fmt4 ) (canter 3.040 .040 619.65 (* .25 .700) 45.000 1 .050 ampf ranf skwf .050 .010 10 index .005 .005 amp1 ind1 fmt1 amp2 ind2 fmt2 amp3 ind3 fmt3 amp4 ind4 fmt4 ) (canter 3.080 .040 408 (* .25 .700) 45.000 1 .050 ampf ranf skwf .050 .010 10 index .005 .005 amp1 ind1 fmt1 amp2 ind2 fmt2 amp3 ind3 fmt3 amp4 ind4 fmt4 ) (canter 3.120 .040 688.5 (* .25 .700) 45.000 1 .050 ampf ranf skwf .050 .010 10 index .005 .005 amp1 ind1 fmt1 amp2 ind2 fmt2 amp3 ind3 fmt3 amp4 ind4 fmt4 ) (canter 3.160 .290 459 (* .25 .700) 45.000 1 .050 ampf ranf skwf .050 .010 10 index .005 .005 amp1 ind1 fmt1 amp2 ind2 fmt2 amp3 ind3 fmt3 amp4 ind4 fmt4 ) (canter 3.450 .150 516.375 (* .25 .700) 45.000 1 .050 ampf ranf skwf .050 .010 10 index .005 .005 amp1 ind1 fmt1 amp2 ind2 fmt2 amp3 ind3 fmt3 amp4 ind4 fmt4 ) (canter 3.600 .040 826.2 (* .25 .700) 45.000 1 .050 ampf ranf skwf .050 .010 10 index .005 .005 amp1 ind1 fmt1 amp2 ind2 fmt2 amp3 ind3 fmt3 amp4 ind4 fmt4 ) (canter 3.640 .040 573.75 (* .25 .700) 45.000 1 .050 ampf ranf skwf .050 .010 10 index .005 .005 amp1 ind1 fmt1 amp2 ind2 fmt2 amp3 ind3 fmt3 amp4 ind4 fmt4 ) (canter 3.680 .040 619.65 (* .25 .700) 45.000 1 .050 ampf ranf skwf .050 .010 10 index .005 .005 amp1 ind1 fmt1 amp2 ind2 fmt2 amp3 ind3 fmt3 amp4 ind4 fmt4 ) (canter 3.720 .180 573.75 (* .25 .700) 45.000 1 .050 ampf ranf skwf .050 .010 10 index .005 .005 amp1 ind1 fmt1 amp2 ind2 fmt2 amp3 ind3 fmt3 amp4 ind4 fmt4 ) (canter 3.900 .040 688.5 (* .25 .700) 45.000 1 .050 ampf ranf skwf .050 .010 10 index .005 .005 amp1 ind1 fmt1 amp2 ind2 fmt2 amp3 ind3 fmt3 amp4 ind4 fmt4 ) (canter 3.940 .260 459 (* .25 .700) 45.000 1 .050 ampf ranf skwf .050 .010 10 index .005 .005 amp1 ind1 fmt1 amp2 ind2 fmt2 amp3 ind3 fmt3 amp4 ind4 fmt4 ))) (with-sound (:srate 22050 :play #f) (fm-violin 0 .01 440 .1 :noise-amount 0.0) (pluck 0.05 .01 330 .1 .95 .95) (maraca .1 .1) (big-maraca .2 .5 .25 0.95 0.9985 .03125 '(2300 5600 8100) '(0.96 0.995 0.995) .01) (fm-bell 0.3 1.0 220.0 .5 '(0 0 .1000 1 10 .6000 25 .3000 50 .1500 90 .1000 100 0 ) '(0 1 2 1.1000 25 .7500 75 .5000 100 .2000 ) 1.0) (singer .4 .1 (list (list .4 ehh.shp test.glt 523.0 .8 0.0 .01) (list .6 oo.shp test.glt 523.0 .7 .1 .01))) (stereo-flute .6 .2 440 .55 :flow-envelope '(0 0 1 1 2 1 3 0)) (fofins 1 .3 270 .4 .001 730 .6 1090 .3 2440 .1) (bow 1.2 .3 400 0.5 :vb 0.15 :fb 0.1 :inharm 0.25) (pqw-vox 1.5 1 300 300 .1 '(0 0 50 1 100 0) '(0 0 100 0) 0 '(0 L 100 L) '(.33 .33 .33) '((1 1 2 .5) (1 .5 2 .5 3 1) (1 1 4 .5))) (fm-noise 2 0.5 500 0.25 '(0 0 25 1 75 1 100 0) 0.1 0.1 1000 '(0 0 100 1) 0.1 0.1 10 1000 '(0 0 100 1) 0 0 100 500 '(0 0 100 1) 0 0) (bes-fm 2.5 .5 440 5.0 1.0 8.0) (chain-dsps 3 0.5 '(0 0 1 .1 2 0) (make-oscil 440)) (chain-dsps 3.5 1.0 '(0 0 1 1 2 0) (make-one-zero .5) (make-readin "oboe.snd")) (vox 4 2 170 .4 '(0 0 25 1 75 1 100 0) '(0 0 5 .5 10 0 100 1) .1 '(0 E 25 AE 35 ER 65 ER 75 I 100 UH) '(.8 .15 .05) '(.005 .0125 .025) .05 .1) (p 5.0 :duration .5 :keyNum 36 :strike-velocity .5 :amp .4 :DryPedalResonanceFactor .25) ;(bobwhite 5.5) (scissor 2.0) (plucky 3.25 .3 440 .2 1.0) (bowstr 3.75 .3 220 .2 1.0) (brass 4.2 .3 440 .2 1.0) (clarinet 5.75 .3 440 .2 1.0) (flute 6 .3 440 .2 1.0) (fm-trumpet 6.5 .25) (touch-tone 6.75 '(7 2 3 4 9 7 1)) (pins 7.0 1.0 "now.snd" 1.0 :time-scaler 2.0) (let ((locust '(0 0 40 1 95 1 100 .5)) (bug_hi '(0 1 25 .7 75 .78 100 1)) (amp '(0 0 25 1 75 .7 100 0))) (fm-insect 7 1.699 4142.627 .015 amp 60 -16.707 locust 500.866 bug_hi .346 .500) (fm-insect 7.195 .233 4126.284 .030 amp 60 -12.142 locust 649.490 bug_hi .407 .500) (fm-insect 7.217 2.057 3930.258 .045 amp 60 -3.011 locust 562.087 bug_hi .591 .500) (fm-insect 9.100 1.500 900.627 .06 amp 40 -16.707 locust 300.866 bug_hi .346 .500) (fm-insect 10.000 1.500 900.627 .06 amp 40 -16.707 locust 300.866 bug_hi .046 .500) (fm-insect 10.450 1.500 900.627 .09 amp 40 -16.707 locust 300.866 bug_hi .006 .500) (fm-insect 10.950 1.500 900.627 .12 amp 40 -10.707 locust 300.866 bug_hi .346 .500) (fm-insect 11.300 1.500 900.627 .09 amp 40 -20.707 locust 300.866 bug_hi .246 .500)) (fm-drum 7.5 1.5 55 .3 5 #f) (fm-drum 8 1.5 66 .3 4 #t) (gong 9 3 261.61 .6) (attract 10 .25 .5 2.0) (pqw 11 .5 200 1000 .2 '(0 0 25 1 100 0) '(0 1 100 0) '(2 .1 3 .3 6 .5)) (zn 10 1 100 .1 20 100 .995) (zn 11.5 1 100 .1 100 20 .995) (zc 11 1 100 .1 20 100 .95) (zc 12.5 1 100 .1 100 20 .95) (za 13 1 100 .1 20 100 .95 .95) (za 14.5 1 100 .1 100 20 .95 .95) (tubebell 12 2 440 .2) (wurley 12.5 .25 440 .2) (rhodey 12.75 .25 440 .2) (hammondoid 13 .25 440 .2) (metal 13.5 .25 440 .2) (reson 14.0 1.0 440 .1 2 '(0 0 100 1) '(0 0 100 1) .1 .1 .1 5 .01 5 .01 0 1.0 0.01 '(((0 0 100 1) 1200 .5 .1 .1 0 1.0 .1 .1) ((0 1 100 0) 2400 .5 .1 .1 0 1.0 .1 .1))) (cellon 14.5 1 220 .1 '(0 0 25 1 75 1 100 0) '(0 0 25 1 75 1 100 0) .75 1.0 0 0 0 0 1 0 0 220 '(0 0 25 1 75 1 100 0) 0 0 0 0 '(0 0 100 0) 0 0 0 0 '(0 0 100 0)) (clm-expsrc 14.75 2.5 "oboe.snd" 2.0 1.0 1.0) (scratch 15.0 "now.snd" 1.5 '(0.0 .5 .25 1.0)) (two-tab 15 1 440 .1) (exp-snd "fyow.snd" 15 1.5 1 '(0 1 1 3) 0.4 .15 '(0 2 1 .5) 0.05) (exp-snd "oboe.snd" 16 1 1 '(0 1 1 3) 0.4 .15 '(0 2 1 .5) 0.2) (gran-synth 15.5 1 300 .0189 .03 .4) (spectra 16 1 440.0 .1 '(1.0 .4 2.0 .2 3.0 .2 4.0 .1 6.0 .1) '(0.0 0.0 1.0 1.0 5.0 0.9 12.0 0.5 25.0 0.25 100.0 0.0)) (lbj-piano 16.5 1 440.0 .2) (resflt 17 1.0 0 0 0 #f .1 200 230 10 '(0 0 50 1 100 0) '(0 0 100 1) 500 .995 .1 1000 .995 .1 2000 .995 .1) (resflt 17.5 1.0 1 10000 .01 '(0 0 50 1 100 0) 0 0 0 0 #f #f 500 .995 .1 1000 .995 .1 2000 .995 .1) (bes-fm 18 1 440 10.0 1.0 4.0) (green3 19 2.0 440 .5 '(0 0 1 1 2 1 3 0) 100 .2 .02) (green4 21 2.0 440 .5 '(0 0 1 1 2 1 3 0) 440 100 100 10) (fir+comb 20 2 10000 .001 200) (fir+comb 22 2 1000 .0005 400) (fir+comb 24 2 3000 .001 300) (fir+comb 26 2 3000 .0005 1000) (sndwarp 28 1.0 "pistol.snd") (expandn 29 .5 "oboe.snd" .2) (expandn 30 2 "2.snd" 1.0 '(0.0 1.0 1.0 4.0 2.0 1.0)) (let ((ampf '(0 0 1 1 2 1 3 0))) (fm-voice 0 1 300 .8 3 1 ampf ampf ampf ampf ampf ampf ampf 1 0 0 .25 1 .01 ampf .01)) (graphEq "oboe.snd") ) (with-sound (:channels 4) (expandn 0 .1 "4.aiff" 1 :expand 4)) (with-sound (:channels 4 :reverb jc-reverb) (expandn 0 .1 "4.aiff" 1 :expand 4)) (with-sound (:channels 2 :reverb freeverb :reverb-channels 2) (expandn 0 .1 "4.aiff" 1 :expand 4)) (with-sound (:play #f) (defopt-simp 0 10000) (defopt-simp 10000 10000 550.0 0.1) (defopt-simp 20000 10000 :amplitude .2)) (with-sound (:channels 2 :reverb-channels 2 :reverb jcrev2 :play #f) (floc-simp 0 1)) (with-sound (:channels 2 :statistics #t) (fullmix "pistol.snd") (fullmix "oboe.snd" 1 2 0 (list (list .1 (make-env '(0 0 1 1) :duration 2 :scaler .5))))) (let ((ind (find-sound "test.snd"))) (if (sound? ind) (close-sound ind))) (with-sound (:channels 2) (fullmix "4.aiff" 0.0 0.1 36.4 '((0.0 0.0) (0.0 0.0) (1.0 0.0) (0.0 1.0)))) (let ((ind (find-sound "test.snd"))) (if (fneq (maxamp) 0.8865) (snd-display #__line__ ";4->2(0) fullmix: ~A" (maxamp))) (close-sound ind)) (with-sound (:channels 1) (fullmix "4.aiff" 0.0 0.1 36.4 '((1.0) (0.0) (0.0) (0.0)))) (let ((ind (find-sound "test.snd"))) (if (fneq (maxamp) 0.221649169921875) (snd-display #__line__ ";4->1(0) fullmix: ~A" (maxamp))) (close-sound ind)) (with-sound (:channels 1) (fullmix "4.aiff" 0.0 0.1 36.4 '((0.0) (1.0) (0.0) (0.0)))) (let ((ind (find-sound "test.snd"))) (if (fneq (maxamp) 0.44329833984375) (snd-display #__line__ ";4->1(1) fullmix: ~A" (maxamp))) (close-sound ind)) (with-sound (:channels 1) (fullmix "4.aiff" 0.0 0.1 36.4 '((0.0) (0.0) (1.0) (0.0)))) (let ((ind (find-sound "test.snd"))) (if (fneq (maxamp) 0.664947509765625) (snd-display #__line__ ";4->1(2) fullmix: ~A" (maxamp))) (close-sound ind)) (with-sound (:channels 1) (fullmix "4.aiff" 0.0 0.1 36.4 '((0.0) (0.0) (0.0) (1.0)))) (let ((ind (find-sound "test.snd"))) (if (fneq (maxamp) 0.8865966796875) (snd-display #__line__ ";4->1(3) fullmix: ~A" (maxamp))) (close-sound ind)) (with-sound (:channels 2) (fullmix "4.aiff" 0.0 0.1 36.4 '((0.0 0.0) (0.0 0.0) (1.0 0.0) (0.0 1.0)))) (let* ((ind (find-sound "test.snd")) (mxs (maxamp ind #t))) (if (or (fneq (car mxs) 0.664947509765625) (fneq (cadr mxs) 0.8865966796875)) (snd-display #__line__ ";4->2(1) fullmix: ~A" mxs)) (close-sound ind)) (with-sound (:channels 2) (fullmix "4.aiff" 0.0 0.1 36.4 '((0.0 0.0) (0.0 0.0) (0.0 1.0) (1.0 0.0)))) (let* ((ind (find-sound "test.snd")) (mxs (maxamp ind #t))) (if (or (fneq (car mxs) 0.8865966796875) (fneq (cadr mxs) 0.664947509765625)) (snd-display #__line__ ";4->2(2) fullmix: ~A" mxs)) (close-sound ind)) (with-sound (:channels 2 :reverb nrev) (fullmix "pistol.snd" 0.0 2.0 0.25 #f 2.0 0.1) (fullmix "pistol.snd" 1.0 2.0 0.25 0.2 2.0 0.1) (fullmix "2a.snd" #f #f #f '((0.5 0.0) (0.0 0.75))) (fullmix "oboe.snd" #f #f #f (list (list (list 0 0 1 1 2 0) 0.5))) (fullmix "oboe.snd" 3 2 0 (list (list .1 (make-env '(0 0 1 1) :duration 2 :scaler .5))))) (load "fullmix.scm") ; this is also in clm-ins.scm so we need a separate set of tests (with-sound (:channels 2 :statistics #t) (fullmix "pistol.snd") (fullmix "oboe.snd" 1 2 0 (list (list .1 (make-env '(0 0 1 1) :duration 2 :scaler .5))))) (let ((ind (find-sound "test.snd"))) (if (sound? ind) (close-sound ind) (snd-display #__line__ ";fullmix.scm no output?"))) (with-sound (:channels 2) (fullmix "4.aiff" 0.0 0.1 36.4 '((0.0 0.0) (0.0 0.0) (1.0 0.0) (0.0 1.0)))) (let ((ind (find-sound "test.snd"))) (if (fneq (maxamp) 0.8865) (snd-display #__line__ ";4->2(0) fullmix.scm: ~A" (maxamp))) (close-sound ind)) (with-sound (:channels 1) (fullmix "4.aiff" 0.0 0.1 36.4 '((1.0) (0.0) (0.0) (0.0)))) (let ((ind (find-sound "test.snd"))) (if (fneq (maxamp) 0.221649169921875) (snd-display #__line__ ";4->1(0) fullmix.scm: ~A" (maxamp))) (close-sound ind)) (with-sound (:statistics #t :scaled-to .5 :srate 44100 :channels 1) (cnvrev "oboe.snd" "fyow.snd")) (let ((ind (find-sound "test.snd"))) (if (sound? ind) (close-sound ind) (snd-display #__line__ ";cnvrev no output?"))) (with-sound () (sound-let ((temp-1 () (fm-violin 0 1 440 .1)) (temp-2 () (fm-violin 0 2 660 .1 :base 32.0) (fm-violin .125 .5 880 .1))) (mus-file-mix *output* temp-1 0) (mus-file-mix *output* temp-2 22050))) (let ((ind (find-sound "test.snd"))) (if (not (sound? ind)) (snd-display #__line__ ";with-sound+sound-lets init: no test.snd?")) (if (or (> (maxamp ind) .2) (< (maxamp ind) .15)) (snd-display #__line__ ";with-mix+sound-lets maxamp: ~A" (maxamp ind))) (if (fneq 3.0 (/ (framples ind) (srate ind))) (snd-display #__line__ ";with-sound+sound-lets dur: ~A" (/ (framples ind) (srate ind)))) (close-sound ind)) (with-sound (:srate 44100 :play #f) (bigbird 0 2 60 0 .5 '(0 0 1 1) '(0 0 1 1 2 1 3 0) '(1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 1 10 1))) (let ((ind (or (find-sound "test.snd") (open-sound "oboe.snd")))) (let ((mx (maxamp))) (notch-sound (let ((freqs ())) (do ((i 60 (+ i 60))) ((= i 3000)) (set! freqs (cons i freqs))) (reverse freqs))) (if (or (fneq mx .5) (ffneq (maxamp) .027)) (snd-display #__line__ ";notch 60 Hz: ~A to ~A" mx (maxamp))) (undo) (notch-sound (let ((freqs ())) (do ((i 60 (+ i 60))) ((= i 3000)) (set! freqs (cons i freqs))) (reverse freqs)) #f ind 0 10) (if (ffneq (maxamp) .011) (snd-display #__line__ ";notch-sound 60 hz 2: ~A" (maxamp))) (undo) (notch-channel (let ((freqs ())) (do ((i 60 (+ i 60))) ((= i 3000)) (set! freqs (cons i freqs))) (reverse freqs)) #f #f #f ind 0 #f #f 10) (if (ffneq (maxamp) .004) (snd-display #__line__ ";notch-channel 60 hz 2: ~A" (maxamp))) (undo) ; (select-all) (make-selection 10000 11000) (notch-selection (let ((freqs ())) (do ((i 60 (+ i 60))) ((= i 3000)) (set! freqs (cons i freqs))) (reverse freqs)) #f 10) ; (if (ffneq (maxamp) .066) ; (snd-display #__line__ ";notch-selection 60 hz 2: ~A" (maxamp))) (close-sound ind))) (with-sound (:srate 44100 :play #f) (bigbird 0 30 60 0 .5 '(0 0 1 1) '(0 0 1 1 2 1 3 0) '(1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 1 10 1))) (let ((ind (find-sound "test.snd"))) (notch-sound (let ((freqs ())) (do ((i 60 (+ i 60))) ((= i 3000)) (set! freqs (cons i freqs))) (reverse freqs)) #f ind 0 10) (if (ffneq (maxamp) .011) (snd-display #__line__ ";notch-sound 60 hz 2 60: ~A" (maxamp))) (close-sound ind)) (play-sine 440 .1) (play-sines '((425 .05) (450 .01) (470 .01) (546 .02) (667 .01) (789 .034) (910 .032))) (with-sound (:channels 2 :reverb jc-reverb :reverb-channels 1 :statistics #t) (grani 0 1 .5 "oboe.snd" :grain-envelope '(0 0 0.2 0.2 0.5 1 0.8 0.2 1 0)) (grani 0 4 1 "oboe.snd") (grani 0 4 1 "oboe.snd" :grains 10) (grani 0 4 1 "oboe.snd" :grain-start 0.11 :amp-envelope '(0 1 1 1) :grain-density 8 :grain-envelope '(0 0 0.2 0.2 0.5 1 0.8 0.2 1 0) :grain-envelope-end '(0 0 0.01 1 0.99 1 1 0) :grain-envelope-transition '(0 0 0.4 1 0.8 0 1 0)) (grani 0 3 1 "oboe.snd" :grain-start 0.1 :amp-envelope '(0 1 1 1) :grain-density 20 :grain-duration '(0 0.003 0.2 0.01 1 0.3)) (grani 0 3 1 "oboe.snd" :grain-start 0.1 :amp-envelope '(0 1 1 1) :grain-density 20 :grain-duration '(0 0.003 0.2 0.01 1 0.3) :grain-duration-limit 0.02) (grani 0 2 1 "oboe.snd" :amp-envelope '(0 1 1 1) :grain-density 40 :grain-start '(0 0.1 0.3 0.1 1 0.6)) (grani 0 2 1 "oboe.snd" :amp-envelope '(0 1 1 1) :grain-density 40 :grain-start '(0 0.1 0.3 0.1 1 0.6) :grain-start-spread 0.01) (grani 0 2.6 1 "oboe.snd" :grain-start 0.1 :grain-start-spread 0.01 :amp-envelope '(0 1 1 1) :grain-density 40 :srate '(0 0 0.2 0 0.6 5 1 5)) (grani 0 2.6 1 "oboe.snd" :grain-start 0.1 :grain-start-spread 0.01 :amp-envelope '(0 1 1 1) :grain-density 40 :srate-base 2 :srate '(0 0 0.2 0 0.6 -1 1 -1)) (grani 0 2.6 1 "oboe.snd" :grain-start 0.1 :grain-start-spread 0.01 :amp-envelope '(0 1 1 1) :grain-density 40 :srate-linear #t :srate (list 0 1 0.2 1 0.6 (expt 2 5/12) 1 (expt 2 5/12))) (grani 0 2 1 "oboe.snd" :grain-start 0.1 :grain-start-spread 0.01 :amp-envelope '(0 1 1 1) :grain-density 40 :grain-duration '(0 0.02 1 0.1) :grain-duration-spread '(0 0 0.5 0.1 1 0) :where-to grani-to-grain-duration ; from grani.scm :where-bins (float-vector 0 0.05 1)) (grani 0 2 1 "oboe.snd" :grain-start 0.1 :grain-start-spread 0.01 :amp-envelope '(0 1 1 1) :grain-density 40 :grain-degree '(0 0 1 90) :grain-degree-spread 10)) (let ((ind (open-sound "oboe.snd"))) (with-sound ("test1.snd" :to-snd #f) (fm-violin 0 .1 440 .1)) (set-samples 0 2205 "test1.snd" ind 0 #f "set-samples auto-delete test" 0 #f #t) (if (not (file-exists? "test1.snd")) (snd-display #__line__ ";oops: auto-delete test1.snd?")) (undo 1 ind) (with-sound ("test2.snd" :to-snd #f) (fm-violin 0 .1 440 .1)) (insert-sound "test2.snd" 0 0 ind 0 #f #t) (if (file-exists? "test1.snd") (snd-display #__line__ ";auto-delete set-samples?")) (undo 1 ind) (with-sound ("test3.snd" :to-snd #f) (fm-violin 0 .1 440 .1)) (insert-samples 0 2205 "test3.snd" ind 0 #f #t) (if (file-exists? "test2.snd") (snd-display #__line__ ";auto-delete insert-sound?")) (undo 1 ind) (with-sound ("test4.snd" :to-snd #f) (fm-violin 0 .1 440 .1)) (mix "test4.snd" 0 0 ind 0 #f #t) (if (file-exists? "test3.snd") (snd-display #__line__ ";auto-delete insert-samples?")) (undo 1 ind) (delete-sample 100) (if (file-exists? "test4.snd") (snd-display #__line__ ";auto-delete mix?")) (with-sound ("test5.snd" :to-snd #f) (fm-violin 0 .1 440 .1)) (mix "test5.snd" 0 0 ind 0 #t #t) (revert-sound ind) (close-sound ind) (if (file-exists? "test5.snd") (snd-display #__line__ ";auto-delete mix (with-tag)?"))) ) (let ((o2 (optkey-1 1))) (if (not (eqv? o2 1)) (snd-display #__line__ ";optkey-1: ~A" o2))) (let ((o2 (optkey-1 :a 1))) (if (not (eqv? o2 1)) (snd-display #__line__ ";optkey-1 1: ~A" o2))) (let ((o2 (optkey-1))) (if o2 (snd-display #__line__ ";optkey-1 2: ~A" o2))) (let ((o2 (optkey-2 1 2))) (if (not (equal? o2 (list 1 2))) (snd-display #__line__ ";optkey-2: ~A" o2))) (let ((o2 (optkey-2 :a 1 :b 2))) (if (not (equal? o2 (list 1 2))) (snd-display #__line__ ";optkey-2 1: ~A" o2))) (let ((o2 (optkey-2))) (if (not (equal? o2 (list 3 #f))) (snd-display #__line__ ";optkey-2 2: ~A" o2))) (let ((o2 (optkey-2 1 :b 2))) (if (not (equal? o2 (list 1 2))) (snd-display #__line__ ";optkey-2 3: ~A" o2))) (let ((o2 (optkey-3 1 2 3))) (if (not (equal? o2 (list 1 2 3))) (snd-display #__line__ ";optkey-3: ~A" o2))) (let ((o2 (optkey-3 1 :b 2 :c 3))) (if (not (equal? o2 (list 1 2 3))) (snd-display #__line__ ";optkey-3 1: ~A" o2))) (let ((o2 (optkey-3 1 2 :c 3))) (if (not (equal? o2 (list 1 2 3))) (snd-display #__line__ ";optkey-3 2: ~A" o2))) (let ((o2 (optkey-4))) (if (not (equal? o2 (list 1 2 3 #f))) (snd-display #__line__ ";optkey-4: ~A" o2))) (let ((o2 (optkey-4 1 :b 3 :c 4 :d 5))) (if (not (equal? o2 (list 1 3 4 5))) (snd-display #__line__ ";optkey-4 1: ~A 1" o2))) (let ((o2 (optkey-4 1 :d 5 :c 4 :b 3))) (if (not (equal? o2 (list 1 3 4 5))) (snd-display #__line__ ";optkey-4 2: ~A 1" o2))) (let ((o2 (optkey-4 1 3 4 5))) (if (not (equal? o2 (list 1 3 4 5))) (snd-display #__line__ ";optkey-4 3: ~A 2" o2))) (if (and (or (provided? 'snd-motif) (and (provided? 'snd-gtk) (defined? 'gtk_box_new))) (defined? 'variable-display)) (let ((wid1 (make-variable-display "do-loop" "i*1" 'text)) (wid2 (make-variable-display "do-loop" "i*2" 'scale '(-1.0 1.0))) (wid3 (make-variable-display "do-loop" "i3" 'spectrum)) (wid4 (make-variable-display "do-loop" "i4" 'graph))) (do ((i 0 (+ i 1))) ((= i 1000)) (variable-display (variable-display (* (variable-display (sin (* (variable-display i wid1) .1)) wid3) .5) wid2) wid4)) (let ((tag (catch #t (lambda () (set! (sample 0 (car wid3) 0) .5)) (lambda args (car args))))) (if (> (edit-position (car wid3) 0) 0) (snd-display #__line__ ";edited variable graph? ~A ~A" tag (edit-position (car wid3) 0)))) (if (provided? 'snd-motif) ((*motif* 'XtUnmanageChild) variables-dialog) ((*gtk* 'gtk_widget_hide) variables-dialog)) (close-sound (car wid3)) (close-sound (car wid4)) )) (if (not (= *clm-srate* *default-output-srate*)) (snd-display #__line__ ";*clm-srate*: ~A ~A" *clm-srate* *default-output-srate*)) (if (not (= *clm-channels* *default-output-chans*)) (snd-display #__line__ ";*clm-channels*: ~A ~A" *clm-channels* *default-output-chans*)) (if (not (= *clm-header-type* *default-output-header-type*)) (snd-display #__line__ ";*clm-header-type*: ~A ~A" *clm-header-type* *default-output-header-type*)) ; (if (not (= *clm-sample-type* *default-output-sample-type*)) (snd-display #__line__ ";*clm-sample-type*: ~A ~A" *clm-sample-type* *default-output-sample-type*)) (if (not (= *clm-reverb-channels* 1)) (snd-display #__line__ ";*clm-reverb-channels*: ~A" *clm-reverb-channels*)) (if (not (string=? *clm-file-name* "test.snd")) (snd-display #__line__ ";*clm-file-name*: ~A" *clm-file-name*)) (if *clm-play* (snd-display #__line__ ";*clm-play*: ~A" *clm-play*)) (if *clm-verbose* (snd-display #__line__ ";*clm-verbose*: ~A" *clm-verbose*)) (if *clm-statistics* (snd-display #__line__ ";*clm-statistics*: ~A" *clm-statistics*)) (if *clm-reverb* (snd-display #__line__ ";*clm-reverb*: ~A" *clm-reverb*)) (if (pair? *clm-reverb-data*) (snd-display #__line__ ";*clm-reverb-data*: ~A?" *clm-reverb-data*)) (if *clm-delete-reverb* (snd-display #__line__ ";*clm-delete-reverb*: ~A" *clm-delete-reverb*)) (let ((old-stats *clm-statistics*)) (set! *clm-channels* 2) (set! *clm-srate* 44100) (set! *clm-file-name* "test.wav") (set! *clm-verbose* #t) (set! *clm-statistics* #t) (set! *clm-play* #t) (set! *clm-sample-type* mus-mulaw) (set! *clm-header-type* mus-riff) (set! *clm-delete-reverb* #t) (set! *clm-reverb* jc-reverb) (set! *clm-reverb-data* (list #t 2.0 (list 0 1 3.0 1 4.0 0))) (with-sound () (fm-violin 0 1 440 .1 :reverb-amount .1)) (let ((ind (find-sound "test.wav"))) (if (not (sound? ind)) (snd-display #__line__ ";default output in ws: ~A" (map file-name (sounds))) (begin (if (not (= (srate ind) 44100)) (snd-display #__line__ ";default srate in ws: ~A ~A" (srate ind) *clm-srate*)) (if (not (= (channels ind) 2)) (snd-display #__line__ ";default chans in ws: ~A ~A" (channels ind) *clm-channels*)) (if (not (= (sample-type ind) mus-mulaw)) (snd-display #__line__ ";default format in ws: ~A ~A" (sample-type ind) *clm-sample-type*)) (if (not (= (header-type ind) mus-riff)) (snd-display #__line__ ";default type in ws: ~A ~A" (header-type ind) *clm-header-type*)) (if (> (abs (- (framples ind) 88200)) 1) (snd-display #__line__ ";reverb+1 sec out in ws: ~A" (framples ind))) (if (file-exists? "test.rev") (snd-display #__line__ ";perhaps reverb not deleted in ws?")) (close-sound ind)))) (let ((val 0) (old-hook *clm-notehook*)) (set! *clm-notehook* (lambda args (set! val 1))) (with-sound () (fm-violin 0 .1 440 .1)) (if (not (= val 1)) (snd-display #__line__ ";*clm-notehook*: ~A ~A" val *clm-notehook*)) (with-sound (:notehook (lambda args (set! val 2))) (fm-violin 0 .1 440 .1)) (if (not (= val 2)) (snd-display #__line__ ";:notehook: ~A" val)) (with-sound () (fm-violin 0 .1 440 .1)) (if (not (= val 1)) (snd-display #__line__ ";*clm-notehook* (1): ~A ~A" val *clm-notehook*)) (set! *clm-notehook* old-hook)) (set! *clm-channels* 1) (set! *clm-srate* 22050) (set! *clm-file-name* "test.snd") (set! *clm-verbose* #f) (set! *clm-statistics* old-stats) (set! *clm-play* #f) (set! *clm-sample-type* mus-ldouble) (set! *clm-header-type* mus-next) (set! *clm-delete-reverb* #f) (set! *clm-reverb* #f) (set! *clm-reverb-data* ())) (with-sound (:reverb jl-reverb) (attract 0 1 0.1 2.0) (expfil 0 2 .2 .01 .1 "oboe.snd" "fyow.snd") (fm-violin 0 .1 660 .1 :reverb-amount .1) (anoi "oboe.snd" 1 1) (let* ((ind (open-sound "oboe.snd")) (ind1 (open-sound "now.snd")) (zp (make-zipper (make-env '(0 0 1 1) :length 22050) 0.05 (make-env (list 0 (* *clm-srate* 0.05)) :length 22050))) (reader0 (make-sampler 0 ind 0)) (reader1 (make-sampler 0 ind1 0))) (do ((i 0 (+ i 1))) ((= i 22050)) (outa i (zipper zp reader0 reader1))) (close-sound ind) (close-sound ind1))) (zip-sound 1 1 "fyow.snd" "now.snd" '(0 0 1 1) .05) (zip-sound 2 3 "mb.snd" "fyow.snd" '(0 0 1.0 0 1.5 1.0 3.0 1.0) .025) (if all-args (let ((ind (open-sound "oboe.snd")) (pv (make-pvocoder 256 4 64)) (rd (make-sampler 0))) (map-channel (lambda (y) (pvocoder pv rd))) (clm-reverb-sound .1 jc-reverb) (close-sound ind))) (let ((old-play *clm-play*)) (set! *clm-play* #f) (make-birds) (set! *clm-play* old-play)) (for-each close-sound (sounds)) (with-sound (:play #f :srate 22050) (simple-ssb 0 .2 440 .1) (simple-nsin .6 .2 .1) (simple-ncos 0.7 .2 440 .1) (simple-nrxysin .6 .2 .1) (simple-nrxycos 0.7 .2 440 .1) (simple-osc 0.75 .2 440 .1) (simple-asy 1.25 .2 .1) (simple-saw 1.5 .2 .1) (simple-tri 1.75 .2 .1) (simple-pul 2.0 .2 .1) (simple-sqr 2.25 .2 .1) (simple-oz 2.75 .2 440.0 .1) (simple-op 3.0 .2 440.0 .1) (simple-tz 3.25 .2 440.0 .1) (simple-tp 3.5 .2 440.0 .1) (simple-frm 3.75 .2 440.0 .1) (simple-firm 3.875 .2 440.0 .1) (simple-firm2 4.0 .2 440.0 .1) (simple-poly 4.25 .2 440.0 .1) (simple-polyw 4.5 .2 440.0 .1) (simple-dly 4.75 .2 440.0 .1) (simple-cmb 5.0 .2 440.0 .1) (simple-filtered-cmb 5.125 .2 440.0 .1) (simple-not 5.25 .2 440.0 .1) (simple-alp 5.5 .2 440.0 .1) (simple-ave 5.75 .2 440.0 .1) (simple-tab 6.0 .2 440.0 .1) (simple-flt 6.25 .2 440.0 .1) (simple-fir 6.5 .2 440.0 .1) (simple-iir 6.5 .2 440.0 .3) (simple-ran 7.0 .2 440.0 .1) (simple-ri 7.25 .2 440.0 .1) (simple-env 7.5 .2 440.0 .1) (simple-amb 7.75 .2 440.0 .1) (simple-fof 8 1 270 .1 .001 730 .6 1090 .3 2440 .1) ;"Ahh" (simple-fof 9 4 270 .1 0.005 730 .6 1090 .3 2440 .1 '(0 0 40 0 75 .2 100 1) '(0 0 .5 1 3 .5 10 .2 20 .1 50 .1 60 .2 85 1 100 0)) (simple-fof 9 4 (* 6/5 540) .1 0.005 730 .6 1090 .3 2440 .1 '(0 0 40 0 75 .2 100 1) '(0 0 .5 .5 3 .25 6 .1 10 .1 50 .1 60 .2 85 1 100 0)) (simple-fof 9 4 135 .1 0.005 730 .6 1090 .3 2440 .1 '(0 0 40 0 75 .2 100 1) '(0 0 1 3 3 1 6 .2 10 .1 50 .1 60 .2 85 1 100 0)) (simple-src-f 13 .45 1.0 2.0 "oboe.snd") (simple-rd 13.5 .45 .75 "oboe.snd") (simple-rd-start 13.65 .25 .75 "oboe.snd" 0 0) (simple-rd-start 13.8 .25 .75 "oboe.snd" 0 12345) (simple-rd-start 13.9 .25 .75 "oboe.snd" 0 12345678) (simple-cnv 14.0 .45 .75 "oboe.snd") (simple-cnf 14.5 .45 .75 "oboe.snd") (simple-lrg 15.0 .45 .75 "oboe.snd") (simple-cn2 15.5 .45 .4 "oboe.snd") (simple-src 16 .45 1.0 2.0 "oboe.snd") (simple-sr2 16.5 .45 1.0 2.0 "oboe.snd") (simple-sr2a 16.75 .45 1.0 2.0 "oboe.snd") (simple-rndist 17.0 .2 440.0 .1) (simple-ridist 17.25 .2 440.0 .1) (simple-sro 17.5 .45 .1 .5 440) (simple-grn 18 .2 .1 1.0 440) (simple-pvoc 18.25 .2 .4 256 "oboe.snd") (simple-ina 18.5 .45 1 "oboe.snd") (simple-rdf 19 .45 1 "oboe.snd") (simple-f2s 19.5 .45 1 "oboe.snd") (simple-loc 20 .2 440 .1) (simple-dloc 20.1 .2 440 .1) (simple-out 20.25 .2 440 .1) (simple-fm 20 1 440 .1 2 1.0) (simple-dup 20.5 .2 440 .1) (simple-du1 20.75 .2 440 .1) (simple-grn-f1 21 .45 .1 2 440) (simple-grn-f2 21.5 .45 1 2 "oboe.snd") (simple-grn-f3 22 .45 1 2 "oboe.snd") (simple-grn-f4 22.5 .45 1 2 "oboe.snd") (simple-grn-f5 23 .45 1 2 "oboe.snd") (simple-multiarr 23.5 .5 440 .1)) (with-sound (:channels 4 :play #f :srate 22050) (simple-dloc-4 0 2 440 .5)) (with-sound (:play #f :srate 22050) (or1) (or2) (or3) (or4) (sample-desc 0 .2 440 .1) (sample-mdat .25 .2 440 .1) (sample-xtab .5 .2 440 .1) (sample-xts .75 .2 440 .1) (sample-srl2 1 .2 .2 .5 (* 440 2)) (sample-srll 1.25 .2 .1 .5 (* 440 4)) (sample-srl3 1.5 .2 .1 .5 880) (sample-grn2 1.75 .2 .1 .5 880) (sample-grn3 2 .45 1 1 "oboe.snd") (sample-cnv 2.5 .45 1 1 "oboe.snd") (sample-cnv1 3.0 .45 1 1 "oboe.snd") (sample-pvoc1 3.5 .45 1 512 "oboe.snd") (sample-pvoc2 4.0 .45 1 512 "oboe.snd") (sample-pvoc3 4.5 .001 1 512 "oboe.snd") (sample-osc 5.25 .2 440 .1) (if all-args (sample-ardcl 5.5 .2 440 .1)) (sample-flt 6 .2 440 .1) (sample-arrintp 6.25 .2 440 .1) (sample-if 6.5 .2 440 .1) (sample-arrfile 6.75 .2 440 .15) (sample-pvoc5 7.25 .2 .1 256 "oboe.snd" 440.0) ) (let* ((file (with-sound (:clipped #f :sample-type mus-lfloat :header-type mus-next) (fm-violin 0 .1 440 pi))) (ind (find-sound file)) (mx (maxamp ind))) (if (fneq mx pi) (snd-display #__line__ ";clipped #f: ~A" mx)) (close-sound ind) (set! file (with-sound (:clipped #t :sample-type mus-lfloat :header-type mus-next) (fm-violin 0 .1 440 pi))) (set! ind (find-sound file)) (set! mx (maxamp ind)) (if (fneq mx 1.0) (snd-display #__line__ ";clipped #t: ~A" mx)) (close-sound ind) (set! file (with-sound (:sample-type mus-lfloat :header-type mus-next :scaled-by .1 :clipped #f) (fm-violin 0 .1 440 pi))) (set! ind (find-sound file)) (set! mx (maxamp ind)) (if (fneq mx .314159) (snd-display #__line__ ";scaled-by ~A" mx)) (close-sound ind) (set! file (with-sound (:sample-type mus-lfloat :header-type mus-next :scaled-to .1 :clipped #f) (fm-violin 0 .1 440 pi))) (set! ind (find-sound file)) (set! mx (maxamp ind)) (if (fneq mx .1) (snd-display #__line__ ";scaled-to ~A" mx)) (close-sound ind) (let ((old-bufsize *clm-file-buffer-size*) (old-tsize *clm-table-size*) (old-arrp *clm-array-print-length*)) (set! *clm-file-buffer-size* (* 1024 1024)) (set! *clm-table-size* 256) (set! *clm-array-print-length* 123) (let ((tsize 0) (arrp 0)) (set! file (with-sound (:sample-type mus-lfloat :header-type mus-next) (set! mx *clm-file-buffer-size*) (set! tsize *clm-table-size*) (set! arrp *mus-array-print-length*) (fm-violin 0 .1 440 .1))) (set! ind (find-sound file)) (if (not (= mx (* 1024 1024))) (snd-display #__line__ ";*clm-file-buffer-size*: ~A" mx)) (if (not (= tsize 256)) (snd-display #__line__ ";*clm-table-size*: ~A" tsize)) (if (not (= arrp 123)) (snd-display #__line__ ";*clm-array-print-length*: ~A" arrp)) (set! *clm-file-buffer-size* old-bufsize) (set! *clm-table-size* old-tsize) (set! *clm-array-print-length* old-arrp) (close-sound ind))) (set! file (with-sound () (fm-violin 0 3.0 440 .1))) (set! ind (find-sound file)) (set! (amp-control ind) .5) (set! (x-bounds ind 0) (list 1.0 2.0)) (set! file (with-sound () (fm-violin 0 4.0 440 .1))) (set! ind (find-sound file)) (if (fneq (amp-control ind) .5) (snd-display #__line__ ";update ws amp: ~A" (amp-control ind))) (if (or (fneq (car (x-bounds ind 0)) 1.0) (fneq (cadr (x-bounds ind 0)) 2.0)) (snd-display #__line__ ";update ws bounds: ~A" (x-bounds ind))) (if (not (= (->sample 1.0) (srate))) (snd-display #__line__ ";1.0->sample: ~A" (->sample 1.0))) (close-sound ind) (set! file (with-sound (:reverb jc-reverb) (fm-violin 0 .1 440 .1 :reverb-amount .1))) (set! ind (find-sound file)) (set! mx (maxamp ind)) (set! file (with-sound (:reverb jc-reverb :reverb-data '(#f 12.0 (0 0 1 1 20 1 21 0))) (fm-violin 0 .1 440 .1 :reverb-amount .1))) (set! ind (find-sound file)) (if (<= (maxamp ind) mx) (snd-display #__line__ ";reverb-data: ~A ~A" mx (maxamp ind))) (close-sound ind)) (let ((ind (open-sound "oboe.snd"))) (step-src) (if (> (abs (- (framples) 24602)) 100) (snd-display #__line__ ";step-src framples: ~A (~A)" (framples) (edits))) (close-sound ind)) (let ((file (with-sound (:channels 3) (let ((rg (make-rmsgain)) (rg1 (make-rmsgain 40)) (rg2 (make-rmsgain 2)) (e (make-env '(0 0 1 1 2 0) :length 10000)) (e1 (make-env '(0 0 1 1) :length 10000)) (e2 (make-env '(0 0 1 1 2 0 10 0) :length 10000)) (o (make-oscil 440.0))) (do ((i 0 (+ i 1))) ((= i 10000)) (let ((sig (env e))) (outa i (balance rg sig (env e2))) (outb i (balance rg1 sig (env e1))) (outc i (balance rg2 (* .1 (oscil o)) (env e2))))) (if (fneq (gain-avg rg) 0.98402) (snd-display #__line__ ";rmsgain gain-avg: ~A" (gain-avg rg))) (if (not (= (rg2 'avgc) 10000)) (snd-display #__line__ ";rmsgain count: ~A" (rg2 'avgc))))))) (let ((ind (find-sound file))) (if (not (sound? ind)) (snd-display #__line__ ";with-sound balance?") (close-sound ind)))) (let ((mg (make-oscil 100.0)) (gen (make-ssb-fm 1000)) (ind (new-sound "tmp.snd" 1 22050 mus-ldouble mus-next))) (pad-channel 0 1000 ind 0) (catch #t (lambda () (map-channel (lambda (y) (ssb-fm gen (* .02 (oscil mg)))))) (lambda arg (display arg) arg)) (close-sound ind)) ;; dlocsig tests (if (not (provided? 'snd-dlocsig.scm)) (catch #t (lambda () (load "dlocsig.scm")) (lambda args (snd-display #__line__ ";load dlocsig: ~A" args)))) (if (not (defined? 'make-spiral-path)) (snd-display #__line__ ";make-spiral-path is not defined, dlocsig is ~Aloaded" (if (provided? 'snd-dlocsig.scm) "" "not ")) (begin (let ((file (new-sound "tmp.snd" 4 22050 mus-ldouble mus-next))) (mix-move-sound 0 "oboe.snd" (make-spiral-path :turns 3)) (close-sound file)) (let ((ind 0)) (with-sound (:channels 2) (dloc-sinewave 0 1.0 440 .5 :path (make-path '((-10 10) (0.5 0.5) (10 10)) :3d #f))) (with-sound (:channels 4) (dloc-sinewave 0 1.0 440 .5 :path (make-path '((-10 10) (0.5 0.5) (10 10)) :3d #f))) (with-sound (:channels 8) (dloc-sinewave 0 1.0 440 .5 :path (make-path '((-10 10) (0.5 0.5) (10 10)) :3d #f))) (with-sound (:channels 4) (dloc-sinewave 0 1.0 440 .5 :path (make-path '((-10 10) (0.5 0.5) (10 10)) :3d #t))) (with-sound (:channels 4 :reverb jc-reverb) (dloc-sinewave 0 1.0 440 .5 :path (make-path '((-10 10) (0.5 0.5) (10 10)) :error .001 :3d #f))) (with-sound (:channels 2) (dloc-sinewave 0 1.0 440 .5 :path (make-path :path '((-10 10 0 1) (0 5 0 0) (10 10 10 1)) :3d #t))) (with-sound (:channels 4) (dloc-sinewave 0 1.0 440 .5 :path (make-spiral-path :total-angle 360))) (with-sound (:channels 8) (dloc-sinewave 0 3.0 440 .5 :path (make-spiral-path :turns 3))) (with-sound (:channels 4) (dloc-sinewave 0 1.0 440 .5 :path (make-literal-path '((-10 10) (10 10)) :polar #f))) (with-sound (:channels 3) (dloc-sinewave 0 1.0 440 .5 :path (make-literal-path '((-10 10) (10 10)) :polar #t))) (with-sound (:channels 4) (dloc-sinewave 0 1.0 440 .5 :path (make-spiral-path :total-angle 360 :distance '(0 10 1 30 2 10)))) (set-speaker-configuration (arrange-speakers :speakers '(-45 45 90 135 225) :delays '(.010 .020 .030 .040 .050) :channel-map '(0 1 3 2 4))) (with-sound (:channels 5) (dloc-sinewave 0 1.0 440 .5 :path (make-spiral-path :turns 2))) (with-sound (:channels 5 :reverb freeverb :reverb-channels 5 :reverb-data '(:decay-time .9)) (dloc-sinewave 0 1.0 440 .5 :path (make-spiral-path :turns 2))) (set-speaker-configuration (arrange-speakers :speakers '(-45 45 90 135 225) :delays '(.010 .020 .030 .040 .050) :channel-map '(4 3 2 1 0))) (with-sound (:channels 5 :reverb freeverb :reverb-channels 5) (dloc-sinewave 0 1.0 440 .5 :path (make-spiral-path :turns 2))) (with-sound (:channels 4) (dlocsig-sinewave-1 0 1.0 440 .5 :path (make-path '((-10 10) (0.5 0.5) (10 10)) :3d #f) :decode b-format-ambisonics)) (with-sound (:channels 4) (dlocsig-sinewave-1 0 1.0 440 .5 :path (make-path '((-10 10) (0.5 0.5) (10 10)) :3d #f) :decode decoded-ambisonics)) ))) (let ((f (with-sound (:channels 5 :reverb freeverb :reverb-channels 5 :srate 44100 :reverb-data '(:decay-time .1)) (frample->file *reverb* 0 (float-vector .2 .1 .05 .025 .0125))))) (define (frample n) (let ((ind (selected-sound))) (let ((c (channels ind))) (let ((v (make-float-vector c))) (do ((i 0 (+ i 1))) ((= i c) v) (set! (v i) (sample n ind i))))))) (if (not (vvequal (frample 2438) (make-float-vector 5))) (snd-display #__line__ ";freeverb 2438: ~A" (frample 2438))) (if (not (vvequal (frample 2439) (float-vector 0.04276562482118607 -0.0009843750158324838 0.00995312537997961 -0.0009843750158324838 0.001750000054016709))) (format *stderr* ";freeverb 2439: ~A" (frample 2439))) (if (not (vvequal (frample 4305) (float-vector 0.03010422177612782 -0.00203015236184001 0.007028832100331783 -0.001004761666990817 0.00125998433213681))) (format *stderr* ";freeverb 4305: ~A" (frample 4305))) (close-sound)) (let ((a4 (->frequency 'a4)) (a440 (->frequency 440.0)) (cs5 (->frequency 'cs5)) (df3 (->frequency 'df3)) (c1 (->frequency 'cn1)) (b8 (->frequency 'b8))) (if (fneq a4 440.0) (snd-display #__line__ ";a4->frequency: ~A" a4)) (if (fneq a440 440.0) (snd-display #__line__ ";a440->frequency: ~A" a440)) (if (fneq cs5 554.365) (snd-display #__line__ ";cs5->frequency: ~A" cs5)) (if (fneq df3 138.591) (snd-display #__line__ ";df3->frequency: ~A" df3)) (if (fneq c1 32.703) (snd-display #__line__ ";c1->frequency: ~A" c1)) (if (fneq b8 7902.132) (snd-display #__line__ ";b8->frequency: ~A" b8))) (let ((violins (make-sample->file "violins.snd" 1 mus-ldouble mus-next)) (cellos (make-sample->file "cellos.snd" 1 mus-ldouble mus-next))) (define (violin beg dur freq amp) (with-temp-sound (:continue-old-file #t :output "violins.snd") (fm-violin beg dur (->frequency freq #t) amp))) (define (cello beg dur freq amp) (with-temp-sound (:continue-old-file #t :output "cellos.snd") (fm-violin beg dur (->frequency freq #t) amp :fm-index 1.5))) (violin 0 1 'e4 .2) (violin 1 1.5 'g4 .2) (violin 2.5 .5 'g3 .2) (cello 0 1 'c3 .2) (cello 1 1.5 'e3 .2) (cello 2.5 .5 'g2 .2) (let* ((index (new-sound "test.snd" :channels 1)) ; our overall output file (vs1 (mix "violins.snd")) (cs1 (mix "cellos.snd")) (vs (and (pair? vs1) (car vs1))) (cs (and (pair? cs1) (car cs1)))) (mus-close violins) (mus-close cellos) (if (mix? vs) (let ((vsr (make-mix-sampler vs)) (csr (make-mix-sampler cs)) (fsr (make-sampler 0 index))) (do ((i 0 (+ i 1))) ((= i 1000)) (let ((v (vsr)) (c (csr)) (f (fsr))) (if (fneq f (+ c v)) (snd-display #__line__ ";multi temp output: ~A != ~A + ~A" f v c)))) (free-sampler vsr) (free-sampler csr) (free-sampler fsr))) (close-sound index) (if (file-exists? "violins.snd") (delete-file "violins.snd")) (if (file-exists? "cellos.snd") (delete-file "cellos.snd")))) (let ((v1 (with-sound ((make-float-vector 2210)) (fm-violin 0 .1 440 .1 :random-vibrato-amplitude 0.0)))) (if (fneq (float-vector-peak v1) .1) (snd-display #__line__ ";with-sound -> float-vector fm-violin maxamp (opt): ~A" (float-vector-peak v1))) (let ((v2 (with-sound ((make-float-vector 2210)) (fm-violin 0 .1 440 .1 :random-vibrato-amplitude 0.0)))) (if (fneq (float-vector-peak v2) .1) (snd-display #__line__ ";with-sound -> float-vector fm-violin maxamp: ~A" (float-vector-peak v2))) (if (not (vequal v1 v2)) (snd-display #__line__ ";with-sound -> float-vector v1 v2 not equal?")) (sound-let ((tmp () (fm-violin 0 .1 440 .1 :random-vibrato-amplitude 0.0))) (let ((v3 (make-float-vector 2210))) (file->array tmp 0 0 2205 v3) (if (not (vequal v1 v3)) (snd-display #__line__ ";with-sound -> float-vector v1 v3 not equal?")))) (with-sound (v1) (fm-violin 0 .1 440 .1 :random-vibrato-amplitude 0.0) (fm-violin 0 .1 440 .1 :random-vibrato-amplitude 0.0)) (if (fneq (float-vector-peak v1) .2) (snd-display #__line__ ";with-sound -> float-vector fm-violin maxamp (opt 2): ~A" (float-vector-peak v1))))) (let ((v1 (with-sound ((make-float-vector (list 1 2210) 0.0)) (fm-violin 0 .1 440 .1 :random-vibrato-amplitude 0.0)))) (if (fneq (maxamp v1) .1) (snd-display #__line__ ";with-sound -> vector2 fm-violin maxamp (opt): ~A" (maxamp v1))) (let ((v2 (with-sound ((make-float-vector (list 1 2210) 0.0)) (fm-violin 0 .1 440 .1 :random-vibrato-amplitude 0.0)))) (if (fneq (maxamp v2) .1) (snd-display #__line__ ";with-sound -> vector2 fm-violin maxamp: ~A" (maxamp v2))) (if (not (sd-equal v1 v2)) (snd-display #__line__ ";with-sound -> vector2 v1 v2 not equal?")) (with-sound (v1) (fm-violin 0 .1 440 .1 :random-vibrato-amplitude 0.0) (fm-violin 0 .1 440 .1 :random-vibrato-amplitude 0.0)) (if (fneq (maxamp v1) .2) (snd-display #__line__ ";with-sound -> vector2 fm-violin maxamp (opt 2): ~A" (maxamp v1))))) (set! (locsig-type) mus-interp-linear) (let ((v1 (with-sound ((make-float-vector (list 2 2210) 0.0)) (if (not (= (mus-channels *output*) 2)) (snd-display #__line__ ";with-sound *output* chans: ~A" (mus-channels *output*))) (fm-violin 0 .1 440 .1 :degree 45 :random-vibrato-amplitude 0.0)))) (if (fneq (maxamp v1) .05) (snd-display #__line__ ";with-sound -> vector2 fm-violin maxamp (1 opt): ~A" (maxamp v1))) (if (fneq (maxamp v1) .05) (snd-display #__line__ ";with-sound -> vector2 fm-violin maxamp (2 opt): ~A" (maxamp v1))) (let ((v2 (with-sound ((make-float-vector (list 2 2210) 0.0)) (fm-violin 0 .1 440 .1 :degree 45 :random-vibrato-amplitude 0.0)))) (if (fneq (maxamp v2) .05) (snd-display #__line__ ";with-sound -> vector2 fm-violin maxamp (2): ~A" (maxamp v2))) (if (fneq (maxamp v2) .05) (snd-display #__line__ ";with-sound -> vector2 fm-violin maxamp (2 2): ~A" (maxamp v2))) (if (not (sd-equal v1 v2)) (snd-display #__line__ ";with-sound (2 chans) -> vector2 v1 v2 not equal?")) (with-sound (v1) (fm-violin 0 .1 440 .1 :degree 0 :random-vibrato-amplitude 0.0) (fm-violin 0 .1 440 .1 :degree 0 :random-vibrato-amplitude 0.0)) (if (fneq (maxamp v1) .2) (snd-display #__line__ ";with-sound -> vector2 fm-violin maxamp (opt 2): ~A" (maxamp v1))))) (let ((v1 (with-sound ((make-float-vector 2210) :scaled-to .3) (fm-violin 0 .1 440 .1 :random-vibrato-amplitude 0.0)))) (if (fneq (float-vector-peak v1) .3) (snd-display #__line__ ";with-sound -> float-vector fm-violin maxamp (opt, scaled-to): ~A" (float-vector-peak v1))) (let ((v2 (with-sound ((make-float-vector 2210) :scaled-to .3) (fm-violin 0 .1 440 .1 :random-vibrato-amplitude 0.0)))) (if (fneq (float-vector-peak v2) .3) (snd-display #__line__ ";with-sound -> float-vector fm-violin maxamp scaled-to: ~A" (float-vector-peak v2))) (if (not (vequal v1 v2)) (snd-display #__line__ ";with-sound (scaled-to) -> float-vector v1 v2 not equal?")) (with-sound (v1 :scaled-by 2.0) (fm-violin 0 .1 440 .1 :random-vibrato-amplitude 0.0) (fm-violin 0 .1 440 .1 :random-vibrato-amplitude 0.0)) (if (fneq (float-vector-peak v1) .4) (snd-display #__line__ ";with-sound -> float-vector fm-violin maxamp (opt 2 scaled-by): ~A" (float-vector-peak v1))))) (let ((v1 (with-sound ((make-float-vector (list 1 2210) 0.0) :scaled-to .5) (fm-violin 0 .1 440 .1 :random-vibrato-amplitude 0.0)))) (if (fneq (maxamp v1) .5) (snd-display #__line__ ";with-sound -> vector2 fm-violin maxamp (opt, scaled-to): ~A" (maxamp v1))) (let ((v2 (with-sound ((make-float-vector (list 1 2210) 0.0) :scaled-to .5) (fm-violin 0 .1 440 .1 :random-vibrato-amplitude 0.0)))) (if (fneq (maxamp v2) .5) (snd-display #__line__ ";with-sound -> vector2 fm-violin maxamp scaled-to: ~A" (maxamp v2))) (if (not (sd-equal v1 v2)) (snd-display #__line__ ";with-sound scaled-to -> vector2 v1 v2 not equal?")) (with-sound (v1 :scaled-by 0.5) (fm-violin 0 .1 440 .1 :random-vibrato-amplitude 0.0) (fm-violin 0 .1 440 .1 :random-vibrato-amplitude 0.0)) (if (fneq (maxamp v1) .1) (snd-display #__line__ ";with-sound -> vector2 fm-violin maxamp (opt 2 scaled-by): ~A" (maxamp v1))))) (let ((stats-string "")) (with-sound ((make-float-vector 2210) :statistics (lambda (str) (set! stats-string str))) (fm-violin 0 .1 440 .1 :random-vibrato-amplitude 0.0)) (if (and (not (string=? stats-string "\n;vector:\n maxamp: 0.1000\n compute time: 0.000\n")) (not (string=? stats-string "\n;vector:\n maxamp: 0.1000\n compute time: 0.001\n")) (not (string=? stats-string "\n;vector:\n maxamp: 0.1000\n compute time: 0.002\n")) (not (string=? stats-string "\n;vector:\n maxamp: 0.1000\n compute time: 0.010\n")) (not (string=? stats-string "\n;vector:\n maxamp: 0.09999998\n compute time: 0.001\n")) (not (string=? stats-string "\n;vector:\n maxamp: 0.09999998\n compute time: 0.000\n")) (not (string=? stats-string "\n;vector:\n maxamp: 0.1000\n compute time: 0.180\n"))) (snd-display #__line__ ";with-sound to float-vector stats: [~A]" stats-string)) (with-sound ((make-float-vector (list 1 2210) 0.0) :scaled-to .5 :statistics (lambda (str) (set! stats-string str))) (fm-violin 0 .1 440 .1 :random-vibrato-amplitude 0.0)) (if (and (not (string=? stats-string "\n;vector:\n maxamp (before scaling): 0.1000\n compute time: 0.000\n")) (not (string=? stats-string "\n;vector:\n maxamp (before scaling): 0.1000\n compute time: 0.001\n")) (not (string=? stats-string "\n;vector:\n maxamp (before scaling): 0.1000\n compute time: 0.002\n")) (not (string=? stats-string "\n;vector:\n maxamp (before scaling): 0.1000\n compute time: 0.010\n")) (not (string=? stats-string "\n;vector:\n maxamp (before scaling): 0.09999998\n compute time: 0.001\n")) (not (string=? stats-string "\n;vector:\n maxamp (before scaling): 0.09999998\n compute time: 0.000\n")) (not (string=? stats-string "\n;vector:\n maxamp (before scaling): 0.1000\n compute time: 0.009\n"))) (snd-display #__line__ ";with-sound to float-vector stats: [~A]" stats-string)) (with-sound ((make-float-vector (list 4 2210) 0.0) :channels 4 :statistics (lambda (str) (set! stats-string str))) (fm-violin 0 .1 440 .1 :degree 0 :random-vibrato-amplitude 0.0) (fm-violin 0 .1 440 .2 :degree 90 :random-vibrato-amplitude 0.0) (fm-violin 0 .1 440 .3 :degree 180 :random-vibrato-amplitude 0.0) (fm-violin 0 .1 440 .4 :degree 270 :random-vibrato-amplitude 0.0)) ) (for-each (lambda (n) ;; testing overwrites here -- just hope we don't crash... (let ((v1 (with-sound ((make-float-vector 20) :channels 1) (fm-violin 0 .1 440 .1 :random-vibrato-amplitude 0.0)))) (if (fneq (v1 0) 0.0) (snd-display #__line__ ";overwrite float-vector with-sound: ~A (~A)" (v1 0) (float-vector-peak v1)))) (let ((v1 (with-sound ((make-float-vector 20) 4) (fm-violin 0 .1 440 .1 :degree 45 :random-vibrato-amplitude 0.0)))) (if (fneq (v1 0) 0.0) (snd-display #__line__ ";overwrite float-vector with-sound (4): ~A (~A)" (v1 0) (float-vector-peak v1)))) (let ((v1 (with-sound ((make-float-vector (list 4 20) 0.0) :channels 4) (fm-violin 0 .1 440 .1 :degree 0 :random-vibrato-amplitude 0.0) (fm-violin 0 .1 440 .2 :degree 90 :random-vibrato-amplitude 0.0) (fm-violin 0 .1 440 .3 :degree 180 :random-vibrato-amplitude 0.0) (fm-violin 0 .1 440 .4 :degree 270 :random-vibrato-amplitude 0.0)))) (do ((i 0 (+ i 1))) ((= i 4)) (if (fneq (v1 i 0) 0.0) (snd-display #__line__ ";overwrite sd ~D with-sound: ~A" i (v1 i 0))))) (let ((v1 (with-sound ((make-float-vector (list 2 20) 0.0) 4) (fm-violin 0 .1 440 .1 :degree 0 :random-vibrato-amplitude 0.0) (fm-violin 0 .1 440 .2 :degree 90 :random-vibrato-amplitude 0.0) (fm-violin 0 .1 440 .3 :degree 180 :random-vibrato-amplitude 0.0) (fm-violin 0 .1 440 .4 :degree 270 :random-vibrato-amplitude 0.0)))) (do ((i 0 (+ i 1))) ((= i 2)) (if (fneq (v1 i 0) 0.0) (snd-display #__line__ ";overwrite sd (2) ~D with-sound: ~A" i (v1 i 0))))) (let ((v1 (with-sound ((make-float-vector (list 4 20) 0.0) :channels 1) (fm-violin 0 .1 440 .1 :degree 0 :random-vibrato-amplitude 0.0) (fm-violin 0 .1 440 .2 :degree 90 :random-vibrato-amplitude 0.0) (fm-violin 0 .1 440 .3 :degree 180 :random-vibrato-amplitude 0.0) (fm-violin 0 .1 440 .4 :degree 270 :random-vibrato-amplitude 0.0)))) (do ((i 0 (+ i 1))) ((= i 4)) (if (fneq (v1 i 0) 0.0) (snd-display #__line__ ";overwrite sd (4) ~D with-sound: ~A" i (v1 i 0))))) ) (list 0 3 6)) ;; reverb cases parallel to above (let ((v1 (with-sound ((make-float-vector 44100) :reverb jc-reverb) (if (not (= (mus-length *output*) 44100)) (snd-display #__line__ ";ws mus-length float-vector: ~A" (mus-length *output*))) (fm-violin 0 .1 440 .1 :random-vibrato-amplitude 0.0 :reverb-amount 0.9))) (v4 (with-sound ((make-float-vector 44100)) (fm-violin 0 .1 440 .1 :random-vibrato-amplitude 0.0)))) (if (vequal v1 v4) (snd-display #__line__ ";reverb output not written to float-vector?")) (if (< (float-vector-peak v1) .28) (snd-display #__line__ ";rev with-sound -> float-vector fm-violin maxamp (opt): ~A" (float-vector-peak v1))) (let ((v2 (with-sound ((make-float-vector 44100) :reverb jc-reverb) (fm-violin 0 .1 440 .1 :reverb-amount 0.9)))) (if (< (float-vector-peak v2) .28) (snd-display #__line__ ";rev with-sound -> float-vector fm-violin maxamp: ~A" (float-vector-peak v2))) (with-sound (v1 :channels 1 :reverb jc-reverb) (fm-violin 0 .1 440 .1 :reverb-amount 0.9) (fm-violin 0 .1 440 .1 :reverb-amount 0.9)) (if (< (float-vector-peak v1) .28) (snd-display #__line__ ";rev with-sound -> float-vector fm-violin maxamp (opt 2): ~A" (float-vector-peak v1))))) (let ((v1 (with-sound ((make-float-vector (list 1 44100) 0.0) :reverb jc-reverb) (if (not (= (mus-length *output*) 44100)) (snd-display #__line__ ";ws mus-length sd: ~A" (mus-length *output*))) (fm-violin 0 .1 440 .1 :reverb-amount 0.9 :random-vibrato-amplitude 0.0))) (v4 (with-sound ((make-float-vector (list 1 44100) 0.0)) (fm-violin 0 .1 440 .1 :random-vibrato-amplitude 0.0)))) (if (sd-equal v1 v4) (snd-display #__line__ ";reverb output not written to sd?")) (if (< (maxamp v1) .23) (snd-display #__line__ ";rev with-sound -> vector2 fm-violin maxamp (opt): ~A" (maxamp v1))) (let ((v2 (with-sound ((make-float-vector (list 1 44100) 0.0) :reverb jc-reverb) (fm-violin 0 .1 440 .1 :reverb-amount 0.9)))) (if (< (maxamp v2) .23) (snd-display #__line__ ";rev with-sound -> vector2 fm-violin maxamp: ~A" (maxamp v2))) (with-sound (v1 :reverb jc-reverb) (fm-violin 0 .1 440 .1 :reverb-amount 0.9) (fm-violin 0 .1 440 .1 :reverb-amount 0.9)) (if (< (maxamp v1) .52) (snd-display #__line__ ";with-sound -> vector2 fm-violin maxamp (opt 2): ~A" (maxamp v1))))) (set! (locsig-type) mus-interp-linear) (let ((v1 (with-sound ((make-float-vector (list 2 44100) 0.0) :reverb jc-reverb) (if (not (= (mus-channels *output*) 2)) (snd-display #__line__ ";rev with-sound *output* chans: ~A" (mus-channels *output*))) (fm-violin 0 .1 440 .1 :degree 45 :reverb-amount 0.9)))) (if (< (maxamp v1) .23) (snd-display #__line__ ";rev with-sound -> vector2 fm-violin maxamp (1 opt): ~A" (maxamp v1))) (if (< (maxamp v1) .23) (snd-display #__line__ ";rev with-sound -> vector2 fm-violin maxamp (2 opt): ~A" (maxamp v1))) (let ((v2 (with-sound ((make-float-vector (list 2 44100) 0.0) :reverb jc-reverb) (fm-violin 0 .1 440 .1 :degree 45 :reverb-amount 0.9)))) (if (< (maxamp v2) .23) (snd-display #__line__ ";rev with-sound -> vector2 fm-violin maxamp (2): ~A" (maxamp v2))) (if (< (maxamp v2) .23) (snd-display #__line__ ";rev with-sound -> vector2 fm-violin maxamp (2 2): ~A" (maxamp v2))) (with-sound (v1 :reverb jc-reverb) (fm-violin 0 .1 440 .1 :degree 0 :reverb-amount 0.9) (fm-violin 0 .1 440 .1 :degree 0 :reverb-amount 0.9)) (if (< (maxamp v1) .5) (snd-display #__line__ ";rev with-sound -> vector2 fm-violin maxamp (opt 2): ~A" (maxamp v1))))) (let ((v1 (with-sound ((make-float-vector 44100) :revfile (make-float-vector 44100) :reverb jc-reverb) (if (not (= (mus-length *output*) 44100)) (snd-display #__line__ ";1 ws mus-length float-vector: ~A" (mus-length *output*))) (if (not (= (mus-length *reverb*) 44100)) (snd-display #__line__ ";1 ws mus-length float-vector rev: ~A" (mus-length *reverb*))) (fm-violin 0 .1 440 .1 :random-vibrato-amplitude 0.0 :reverb-amount 0.9))) (v4 (with-sound ((make-float-vector 44100)) (fm-violin 0 .1 440 .1 :random-vibrato-amplitude 0.0)))) (if (vequal v1 v4) (snd-display #__line__ ";1 reverb output not written to float-vector?")) (if (< (float-vector-peak v1) .28) (snd-display #__line__ ";1 rev with-sound -> float-vector fm-violin maxamp (opt): ~A" (float-vector-peak v1))) (let ((v2 (with-sound ((make-float-vector 44100) :revfile (make-float-vector 44100) :reverb jc-reverb) (fm-violin 0 .1 440 .1 :reverb-amount 0.9)))) (if (< (float-vector-peak v2) .28) (snd-display #__line__ ";1 rev with-sound -> float-vector fm-violin maxamp: ~A" (float-vector-peak v2))) (with-sound (v1 :revfile v2 :channels 1 :reverb jc-reverb) (fm-violin 0 .1 440 .1 :reverb-amount 0.9) (fm-violin 0 .1 440 .1 :reverb-amount 0.9)) (if (< (float-vector-peak v1) .28) (snd-display #__line__ ";1 rev with-sound -> float-vector fm-violin maxamp (opt 2): ~A" (float-vector-peak v1))))) (let ((v1 (with-sound ((make-float-vector (list 1 44100) 0.0) :revfile (make-float-vector (list 1 44100) 0.0) :reverb jc-reverb) (if (not (= (mus-length *output*) 44100)) (snd-display #__line__ ";ws mus-length sd: ~A" (mus-length *output*))) (fm-violin 0 .1 440 .1 :reverb-amount 0.9 :random-vibrato-amplitude 0.0))) (v4 (with-sound ((make-float-vector (list 1 44100) 0.0)) (fm-violin 0 .1 440 .1 :random-vibrato-amplitude 0.0)))) (if (sd-equal v1 v4) (snd-display #__line__ ";2 reverb output not written to sd?")) (if (< (maxamp v1) .28) (snd-display #__line__ ";2 rev with-sound -> vector2 fm-violin maxamp (opt): ~A" (maxamp v1))) (let ((v2 (with-sound ((make-float-vector (list 1 44100) 0.0) :revfile (make-float-vector (list 1 44100) 0.0) :reverb jc-reverb) (fm-violin 0 .1 440 .1 :reverb-amount 0.9)))) (if (< (maxamp v2) .28) (snd-display #__line__ ";2 rev with-sound -> vector2 fm-violin maxamp: ~A" (maxamp v2))) (with-sound (v1 :revfile v2 :reverb jc-reverb) (fm-violin 0 .1 440 .1 :reverb-amount 0.9) (fm-violin 0 .1 440 .1 :reverb-amount 0.9)) (if (< (maxamp v1) .5) (snd-display #__line__ ";2 with-sound -> vector2 fm-violin maxamp (opt 2): ~A" (maxamp v1))))) (let ((v1 (with-sound ((make-float-vector (list 1 44100) 0.0) :revfile (make-float-vector (list 1 44100) 0.0) :reverb jc-reverb) (if (not (= (mus-length *output*) 44100)) (snd-display #__line__ ";ws mus-length sd: ~A" (mus-length *output*))) (fm-violin 0 .1 440 .1 :reverb-amount 0.9 :random-vibrato-amplitude 0.0))) (v4 (with-sound ((make-float-vector (list 1 44100) 0.0)) (fm-violin 0 .1 440 .1 :random-vibrato-amplitude 0.0)))) (if (sd-equal v1 v4) (snd-display #__line__ ";2 reverb output not written to sd?")) (if (< (maxamp v1) .28) (snd-display #__line__ ";2 rev with-sound -> vector2 fm-violin maxamp (opt): ~A" (maxamp v1))) (let ((v2 (with-sound ((make-float-vector (list 1 44100) 0.0) :revfile (make-float-vector (list 1 44100) 0.0) :reverb jc-reverb) (fm-violin 0 .1 440 .1 :reverb-amount 0.9)))) (if (< (maxamp v2) .28) (snd-display #__line__ ";2 rev with-sound -> vector2 fm-violin maxamp: ~A" (maxamp v2))) (with-sound (v1 :revfile v2 :reverb jc-reverb) (fm-violin 0 .1 440 .1 :reverb-amount 0.9) (fm-violin 0 .1 440 .1 :reverb-amount 0.9)) (if (< (maxamp v1) .5) (snd-display #__line__ ";2 with-sound -> vector2 fm-violin maxamp (opt 2): ~A" (maxamp v1))))) (set! (locsig-type) mus-interp-linear) (let ((v1 (with-sound ((make-float-vector (list 2 44100) 0.0) :revfile (make-float-vector (list 1 44100) 0.0) :reverb jc-reverb) (if (not (= (mus-channels *output*) 2)) (snd-display #__line__ ";3 rev with-sound *output* chans: ~A" (mus-channels *output*))) (fm-violin 0 .1 440 .1 :degree 45 :reverb-amount 0.9)))) (if (< (maxamp v1) .23) (snd-display #__line__ ";3 rev with-sound -> vector2 fm-violin maxamp (1 opt): ~A" (maxamp v1))) (if (< (maxamp v1) .23) (snd-display #__line__ ";3 rev with-sound -> vector2 fm-violin maxamp (2 opt): ~A" (maxamp v1))) (let ((v2 (with-sound ((make-float-vector (list 2 44100) 0.0) :revfile (make-float-vector (list 1 44100) 0.0) :reverb jc-reverb) (fm-violin 0 .1 440 .1 :degree 45 :reverb-amount 0.9)))) (if (< (maxamp v2) .23) (snd-display #__line__ ";3 rev with-sound -> vector2 fm-violin maxamp (2): ~A" (maxamp v2))) (if (< (maxamp v2) .23) (snd-display #__line__ ";3 rev with-sound -> vector2 fm-violin maxamp (2 2): ~A" (maxamp v2))) (with-sound (v1 :revfile v2 :reverb jc-reverb) (fm-violin 0 .1 440 .1 :degree 0 :reverb-amount 0.9) (fm-violin 0 .1 440 .1 :degree 0 :reverb-amount 0.9)) (if (< (maxamp v1) .55) (snd-display #__line__ ";3 rev with-sound -> vector2 fm-violin maxamp (opt 2): ~A" (maxamp v1))))) (for-each (lambda (n) (let ((v1 (with-sound ((make-float-vector 4410)) (simple-outn 0 .01 440 .1 .2 .3 .4 0.0 0.0))) (v2 (with-sound ((make-float-vector 400)) (simple-outn 0 .01 440 .1 .2 .3 .4 0.0 0.0))) (v3 (with-sound ((make-float-vector 400)) (simple-outn 0 .01 440 0.0 .5 0.0 0.0 0.0 0.0))) (v4 (with-sound ((make-float-vector 4410) :reverb jc-reverb) (simple-outn 0 .01 440 0.2 0.0 0.0 0.0 0.05 0.0))) (v5 (with-sound ((make-float-vector 4410) :reverb simple-in-rev :reverb-data '(0.0 1.0 1.0 0.0)) (simple-outn 0 .01 440 0.0 0.0 0.0 0.0 0.5 0.0))) (v6 (with-sound ((make-float-vector 400)) (simple-outn 0 .01 440 0.5 0.0 0.0 0.0 0.0 0.0) (simple-outn 0 .01 440 0.2 0.0 0.0 0.0 0.0 0.0))) (sd1 (with-sound ((make-float-vector (list 1 4410) 0.0)) (simple-outn 0 .01 440 .1 .2 .3 .4 0.0 0.0))) (sd2 (with-sound ((make-float-vector (list 4 4410) 0.0)) (simple-outn 0 .01 440 .1 .2 .3 .4 0.0 0.0))) (sd3 (with-sound ((make-float-vector (list 2 4410) 0.0)) (simple-outn 0 .01 440 0.0 0.0 .3 .4 0.0 0.0))) (sd4 (with-sound ((make-float-vector (list 4 4410) 0.0) :reverb simple-in-rev :reverb-channels 2 :reverb-data '(0.0 1.0 1.0 1.0)) (simple-outn 0 .01 440 0.0 0.0 0.0 0.0 0.5 0.25))) (sd5 (with-sound ((make-float-vector (list 4 4410) 0.0) :reverb simple-in-rev :reverb-channels 1 :reverb-data '(0.0 1.0 1.0 1.0)) (simple-outn 0 .01 440 0.0 0.0 0.0 0.0 0.5 0.25))) (sd6 (with-sound ((make-float-vector (list 4 4410) 0.0)) (simple-outn 0 .01 440 .1 .2 .3 .4 0.0 0.0) (simple-outn 0 .01 440 .1 .2 .3 .4 0.0 0.0)))) (if (fneq (float-vector-peak v1) 0.1) (snd-display #__line__ ";outa tests 1 ~A: ~A" n (float-vector-peak v1))) (if (fneq (float-vector-peak v2) 0.1) (snd-display #__line__ ";outa tests 2 ~A: ~A" n (float-vector-peak v2))) (if (fneq (float-vector-peak v3) 0.0) (snd-display #__line__ ";outa tests 3 ~A: ~A" n (float-vector-peak v3))) (if (fneq (float-vector-peak v4) 0.2) (snd-display #__line__ ";outa tests 4 ~A: ~A" n (float-vector-peak v4))) (if (fneq (float-vector-peak v5) 0.5) (snd-display #__line__ ";outa tests 5 ~A: ~A" n (float-vector-peak v5))) (if (fneq (float-vector-peak v6) 0.7) (snd-display #__line__ ";outa tests 11 ~A: ~A" n (float-vector-peak v6))) (let ((mx1 (maxamp sd1))) (if (fneq mx1 .1) (snd-display #__line__ ";outa tests 6 ~A: ~A" n mx1))) (let ((mx2 (maxamp sd2))) (if (fneq mx2 .4) (snd-display #__line__ ";outa tests 7 ~A: ~A" n mx2))) (let ((mx3 (maxamp sd3))) (if (fneq mx3 0.0) (snd-display #__line__ ";outa tests 8 ~A: ~A" n mx3))) (let ((mx4 (maxamp sd4))) (if (fneq mx4 0.5) (snd-display #__line__ ";outa tests 9 ~A: ~A" n mx4))) (let ((mx5 (maxamp sd5))) (if (fneq mx5 0.5) (snd-display #__line__ ";outa tests 10 ~A: ~A" n mx5))) (let ((mx6 (maxamp sd6))) (if (fneq mx6 .8) (snd-display #__line__ ";outa tests 12 ~A: ~A" n mx6))) (with-sound (v1 :continue-old-file #t) (simple-outn 0 .1 440 .1 .2 .3 .4 0.0 0.0)) (if (fneq (float-vector-peak v1) 0.2) (snd-display #__line__ ";outa tests 13 ~A: ~A" n (float-vector-peak v1))) (with-sound (sd2 :continue-old-file #t) (simple-outn 0 .1 440 .1 .2 .3 .4 0.0 0.0)) (let ((mx7 (maxamp sd2))) (if (fneq mx7 .8) (snd-display #__line__ ";outa tests 14 ~A: ~A" n mx7))))) (list 0 6)) (let* ((file (with-sound () (fm-violin 0 .1 880 .1 :random-vibrato-amplitude 0.0) (let ((v1 (with-temp-sound (:output (make-float-vector 2210)) (fm-violin 0 .1 440 .1 :random-vibrato-amplitude 0.0))) (sd1 (with-temp-sound (:output (make-float-vector (list 1 2210) 0.0)) (fm-violin 0 .1 660 .1 :random-vibrato-amplitude 0.0)))) (do ((i 0 (+ i 1))) ((= i 2205)) (outa i (+ (v1 i) (sd1 0 i))))) (fm-violin 0 .1 220.0 .1 :random-vibrato-amplitude 0.0))) (ind (find-sound file))) (if (not (sound? ind)) (snd-display #__line__ ";can't find mixed with-sound output") (let ((mx (maxamp ind 0))) (if (< mx .35) (snd-display #__line__ ";mixed with-sound max: ~A" mx)) (if (not (vequal (channel->float-vector 1000 10) (float-vector 0.255 0.275 0.316 0.364 0.391 0.379 0.337 0.283 0.228 0.170))) (snd-display #__line__ ";mixed with-sound: ~A" (channel->float-vector 1000 10))) (close-sound ind)))) (let* ((file (with-sound () (fm-violin 0 .1 880 .1 :random-vibrato-amplitude 0.0) (sound-let ((v1 (:output (make-float-vector 2210)) (fm-violin 0 .1 440 .1 :random-vibrato-amplitude 0.0)) (sd1 (:output (make-float-vector (list 1 2210) 0.0)) (fm-violin 0 .1 660 .1 :random-vibrato-amplitude 0.0)) (fs1 () (fm-violin 0 .1 110 .1 :random-vibrato-amplitude 0.0))) (mus-file-mix *output* fs1) (do ((i 0 (+ i 1))) ((= i 2205)) (outa i (+ (v1 i) (sd1 0 i))))) (fm-violin 0 .1 220.0 .1 :random-vibrato-amplitude 0.0))) (ind (find-sound file))) (if (not (sound? ind)) (snd-display #__line__ ";can't find mixed with-sound sound-let output") (let ((mx (maxamp ind 0))) (if (< mx .375) (snd-display #__line__ ";mixed with-sound max: ~A" mx)) (if (not (vequal (channel->float-vector 1000 10) (float-vector 0.349 0.370 0.412 0.461 0.489 0.478 0.436 0.383 0.328 0.270))) (snd-display #__line__ ";mixed with-sound via sound-let: ~A" (channel->float-vector 1000 10))) (close-sound ind)))) (let* ((res (with-mixed-sound () (fm-violin 0 .1 440 .1))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";with-mixed-sound (1): ~A?" res)) (let ((mxs (mixes snd 0)) (info (sound-property 'with-mixed-sound-info snd))) (if (not (list? mxs)) (snd-display #__line__ ";with-mixed-sound (1) mixes: ~A" mxs)) (if (or (not (equal? (car (info 0)) (car mxs))) (not (= (cadr (info 0)) 0)) (not (= (caddr (info 0)) 1))) (snd-display #__line__ ";with-mixed-sound info (1) 0: ~A" (info 0))) (if (ffneq (maxamp snd) .1) (snd-display #__line__ ";with-mixed-sound (1) 0: ~A" (maxamp snd))) (close-sound snd))) (let* ((res (with-mixed-sound (:srate 44100) (fm-violin 0 .1 440 .1) (fm-violin 1 .1 660 .1))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";with-mixed-sound (2): ~A?" res)) (let ((mxs (mixes snd 0)) (info (sound-property 'with-mixed-sound-info snd))) (if (or (not (list? mxs)) (not (= (length mxs) 2))) (snd-display #__line__ ";with-mixed-sound mixes (2): ~A" mxs)) (if (or (not (equal? (car (info 0)) (car mxs))) (not (= (cadr (info 0)) 0)) (not (= (caddr (info 0)) 1))) (snd-display #__line__ ";with-mixed-sound info (2) 0: ~A" (info 0))) (if (or (not (equal? (car (info 1)) (cadr mxs))) (not (= (cadr (info 1)) 44100)) (not (= (caddr (info 1)) 1))) (snd-display #__line__ ";with-mixed-sound info (2) 1: ~A" (info 1))) (if (or (and (not (= (framples snd) 48510)) (not (= (framples snd) 48511))) (fneq (maxamp snd) .1)) (snd-display #__line__ ";with-mixed-sound 0 (2): ~A ~A" (framples snd) (maxamp snd))) (close-sound snd))) (let* ((res (with-mixed-sound (:channels 2 :srate 44100) (fm-violin 0 .1 440 .1 :degree 0) (fm-violin 1 .1 660 .1 :degree 45))) (snd (find-sound res)) (mxs (mixes snd)) (info (sound-property 'with-mixed-sound-info snd))) (if (or (not (= (length mxs) 2)) (not (= (length (car mxs)) 2)) (not (= (length info) 2)) (not (equal? (caar info) (caar mxs)))) (snd-display #__line__ ";with-mixed-sound (3) 1: ~A ~A" mxs info)) (close-sound snd)) (let* ((res (with-marked-sound () (fm-violin 0 .1 440 .1) (fm-violin 1 .1 660 .1))) (snd (find-sound res)) (mxs (marks snd 0))) (if (not (= (length mxs) 2)) (snd-display #__line__ ";with-marked-sound marks: ~A " mxs) (begin (if (not (string=? (mark-name (car mxs)) "fm-violin 0 0.1")) (snd-display #__line__ ";with-marked-sound name: ~A" (mark-name (car mxs)))) (if (fneq (maxamp snd) .1) (snd-display #__line__ ";with-marked-sound maxamp: ~A" (maxamp snd))))) (close-sound snd)) (set! (hook-functions mark-click-hook) ()) (set! (hook-functions mix-click-hook) ()) (set! (hook-functions mix-drag-hook) ()) ;; generators.scm (let* ((res (with-sound (:clipped #f) (let ((gen (make-ercos 100 :r 1.0))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (ercos gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";ercos: ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";ercos max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-ercos 100 :r 0.1))) (with-let gen (let ((g (curlet)) (t-env (make-env '(0 .1 1 2) :length 20000)) (poly-coeffs (mus-data osc))) (do ((i 0 (+ i 1))) ((= i 20000)) (set! r (env t-env)) (set! cosh-t (cosh r)) (float-vector-set! poly-coeffs 0 cosh-t) (let ((exp-t (exp (- r)))) (set! offset (/ (- 1.0 exp-t) (* 2.0 exp-t))) (set! scaler (* (sinh r) offset))) (outa i (ercos g)))))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";ercos 1: ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";ercos 1 max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-erssb 1000.0 0.1 1.0))) (do ((i 0 (+ i 1))) ((= i 20000)) (outa i (erssb gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";erssb: ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";erssb max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-noddsin 100 :n 10))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (noddsin gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";noddsin: ~A" snd)) (if (ffneq (maxamp snd) 1.0) (snd-display #__line__ ";noddsin max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-noddcos 100 :n 10))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (noddcos gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";noddcos: ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";noddcos max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-noddssb 1000.0 0.1 5))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (noddssb gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";noddssb: ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";noddssb max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-asyfm 2000.0 :ratio .1))) (do ((i 0 (+ i 1))) ((= i 1000)) (outa i (asyfm-J gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";asyfm-J ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";asyfm-J max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-asyfm 2000.0 :ratio .1 :index 1)) (r-env (make-env '(0 -4 1 -1) :length 20000))) (do ((i 0 (+ i 1))) ((= i 20000)) (set! (gen 'r) (env r-env)) (outa i (asyfm-J gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";asyfm-J1 ~A" snd)) (if (ffneq (maxamp snd) 1.0) (snd-display #__line__ ";asyfm-J1 max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-asyfm 2000.0 :ratio .1))) (do ((i 0 (+ i 1))) ((= i 1000)) (outa i (asyfm-I gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";asyfm-I ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";asyfm-I max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f :statistics #t) (let ((gen (make-nrcos 400.0 :n 5 :r 0.5))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (nrcos gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";nrcos ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";nrcos max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((samps 44100) (gen (make-noid 100.0 3 'min-peak))) (do ((i 0 (+ i 1))) ((= i samps)) (outa i (noid gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";noid ~A" snd)) (if (ffneq (maxamp snd) 0.6599) (snd-display #__line__ ";noid min-peak max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((samps 44100) (gen (make-noid 100.0 3 'max-peak))) (do ((i 0 (+ i 1))) ((= i samps)) (outa i (noid gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";noid ~A" snd)) (if (ffneq (maxamp snd) 1.0) (snd-display #__line__ ";noid max-peak max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-nrcos 100 :n 15 :r 0.5)) (indr (make-env '(0 -1 1 1) :length 40000 :scaler 0.9999))) (let ((set-nrcos-scaler (procedure-setter (gen 'mus-scaler)))) (do ((i 0 (+ i 1))) ((= i 40000)) (set-nrcos-scaler gen (env indr)) (outa i (nrcos gen))))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";nrcos with scaler ~A" snd)) ;(if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";nrcos with scaler max: ~A" (maxamp snd))) ;; this is not a new problem -- was the scaler supposed to fix maxamp? ) (let* ((res (with-sound (:clipped #f) (let ((gen (make-ncos2 100.0 :n 10))) (do ((i 0 (+ i 1))) ((= i 20000)) (outa i (ncos2 gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";ncos2 ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";ncos2 max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-ncos4 100.0 :n 10))) (do ((i 0 (+ i 1))) ((= i 20000)) (outa i (ncos4 gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";ncos4 ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";ncos4 max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-npcos 100.0 :n 10))) (do ((i 0 (+ i 1))) ((= i 20000)) (outa i (npcos gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";npcos ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";npcos max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-n1cos 100.0 :n 10))) (do ((i 0 (+ i 1))) ((= i 20000)) (outa i (n1cos gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";n1cos ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";n1cos max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-rcos 100.0 :r 0.5))) (do ((i 0 (+ i 1))) ((= i 20000)) (outa i (rcos gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";rcos ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";rcos max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-bess 100.0 :n 0))) (do ((i 0 (+ i 1))) ((= i 1000)) (outa i (bess gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";bess ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";bess max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen1 (make-bess 400.0 :n 1)) (gen2 (make-bess 400.0 :n 1)) (vol (make-env '(0 0 1 1 9 1 10 0) :scaler 2.0 :length 20000))) (do ((i 0 (+ i 1))) ((= i 20000)) (outa i (bess gen1 (* (env vol) (bess gen2 0.0)))))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";bess 1 ~A" snd)) (if (ffneq (maxamp snd) 1.0) (snd-display #__line__ ";bess 1 max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen1 (make-bess 400.0 :n 1)) (gen2 (make-oscil 400.0)) (vol (make-env '(0 1 1 0) :scaler 1.0 :length 20000))) (do ((i 0 (+ i 1))) ((= i 20000)) (outa i (bess gen1 (* (env vol) (oscil gen2 0.0)))))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";bess 2 ~A" snd)) (if (ffneq (maxamp snd) 1.0) (snd-display #__line__ ";bess 2 max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-eoddcos 400.0 :r 1.0))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (eoddcos gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";eoddcos ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";eoddcos max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-eoddcos 400.0 :r 0.0)) (a-env (make-env '(0 0 1 1) :length 10000))) (do ((i 0 (+ i 1))) ((= i 10000)) (set! (gen 'r) (env a-env)) (outa i (eoddcos gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";eoddcos 1 ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";eoddcos 1 max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen1 (make-eoddcos 400.0 :r 0.0)) (gen2 (make-oscil 400.0)) (a-env (make-env '(0 0 1 1) :length 10000))) (do ((i 0 (+ i 1))) ((= i 10000)) (set! (gen1 'r) (env a-env)) (outa i (eoddcos gen1 (* .1 (oscil gen2)))))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";eoddcos 2 ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";eoddcos 2 max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-nssb 2000.0 0.05 3))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (* .3 (nssb gen))))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";nssb ~A" snd)) (if (fneq (maxamp snd) 0.3) (snd-display #__line__ ";nssb max: ~A" (maxamp snd)))) (let () (define (test-nssb-0) (let ((g1 (make-nssb 10.0 1.0 10)) (g2 (make-nssb 10.0 1.0 10))) (do ((i 0 (+ i 1))) ((= i 10)) (let ((v1 (nssb g1 1.0)) (v2 (nssb g2 1.0))) (if (> (abs (- v1 v2)) 1e-6) (snd-display #__line__ ";nssb ~D (0): ~A ~A" i v1 v2))) (let ((v1 (nssb g1 0.0)) (v2 (nssb g2))) (if (> (abs (- v1 v2)) 1e-6) (snd-display #__line__ ";nssb ~D (1): ~A ~A" i v1 v2)))))) (test-nssb-0) (test-nssb-0) (define (test-nssb-1) (let ((g1 (make-nssb 10.0 1.0 1.0))) (nssb g1 1.0) (if (not (= (g1 'fm) 1.0)) (snd-display #__line__ ";nssb 1: ~A" (g1 'fm))) (nssb g1 0.0) (if (not (= (g1 'fm) 0.0)) (snd-display #__line__ ";nssb 2: ~A" (g1 'fm))) (nssb g1 1.0) (if (not (= (g1 'fm) 1.0)) (snd-display #__line__ ";nssb 3: ~A" (g1 'fm))) (nssb g1) (if (not (= (g1 'fm) 0.0)) (snd-display #__line__ ";nssb 4: ~A" (g1 'fm))) )) (test-nssb-1) (test-nssb-1)) (let* ((res (with-sound (:clipped #f) (let ((gen (make-nrssb 2000.0 0.05 3 0.5))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (nrssb gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";nrssb ~A" snd)) (if (fneq (maxamp snd) 0.777) (snd-display #__line__ ";nrssb max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-rkcos 440.0 :r 0.5))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (rkcos gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";rkcos ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";rkcos max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-rk!cos 440.0 :r 0.5))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (rk!cos gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";rk!cos ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";rk!cos max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-r2k!cos 440.0 :r 0.5 :k 3.0))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (r2k!cos gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";r2k!cos ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";r2k!cos max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-k2sin 440.0))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (k2sin gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";k2sin ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";k2sin max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-k2cos 440.0))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (k2cos gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";k2cos ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";k2cos max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-k2ssb 1000.0 0.1))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (k2ssb gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";k2ssb ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";k2ssb max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-rssb 1000 0.1 0.5))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (rssb gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";rssb ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";rssb max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-dblsum 100 0.5))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (* .47 (dblsum gen))))))) ; k starts at 0, so maxamp would be 2 except something else is wrong (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";dblsum ~A" snd)) (if (> (maxamp snd) 1.0) (snd-display #__line__ ";dblsum max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-nkssb 1000.0 0.1 5))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (nkssb gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";nkssb ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";nkssb max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-nkssb 1000.0 0.1 5)) (vib (make-polywave 5.0 (list 1 (hz->radians 50.0)) mus-chebyshev-second-kind))) (do ((i 0 (+ i 1))) ((= i 30000)) (outa i (nkssb gen (polywave vib))))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";nkssb 1 ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";nkssb 1 max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-nkssb 1000.0 0.1 5)) (move (make-env '(0 1 1 -1) :length 30000)) (vib (make-polywave 5.0 (list 1 (hz->radians 50.0)) mus-chebyshev-second-kind))) (do ((i 0 (+ i 1))) ((= i 30000)) (outa i (nkssb-interp gen (polywave vib) (env move))))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";nkssb 2 ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";nkssb 2 max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-rkoddssb 1000.0 0.1 0.5))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (rkoddssb gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";rkoddssb ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";rkoddssb max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-krksin 440.0 0.5))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (krksin gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";krksin ~A" snd))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-abcos 100.0 0.5 0.25))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (abcos gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";abcos ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";abcos max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f :statistics #t) (let ((gen (make-absin 100.0 0.5 0.25))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (absin gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";absin ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";absin max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-r2k2cos 100.0 1.0))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (r2k2cos gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";r2k2cos ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";r2k2cos max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-jjcos 100.0 :a 1.0 :r 1.0 :k 1))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (jjcos gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";jjcos ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";jjcos max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-j0evencos 100.0 1.0))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (j0evencos gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";j0evencos ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";j0evencos max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-rksin 100.0 :r 0.5))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (rksin gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";rksin ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";rksin max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-rkssb 1000.0 0.1 :r 0.5))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (rkssb gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";rkssb ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";rkssb max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-rk!ssb 1000.0 0.1 :r 0.5))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (rk!ssb gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";rk!ssb ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";rk!ssb max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-jpcos 100.0 :a 1.0 :r 0.99 :k 1))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (jpcos gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";jpcos ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";jpcos max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-j2cos 100.0 :r 1.0 :n 0))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (j2cos gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";j2cos ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";j2cos max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-nxysin 300 1/3 3))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (nxysin gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";nxysin ~A" snd))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-nxycos 300 1/3 3))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (nxycos gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";nxycos ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";nxycos max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-nxy1cos 300 1/3 3))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (nxy1cos gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";nxy1cos ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";nxy1cos max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-nxy1sin 300 1/3 3))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (nxy1sin gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";nxy1sin ~A" snd)) (if (fneq (maxamp snd) 0.951) (snd-display #__line__ ";nxy1sin max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f :statistics #t) (let ((gen (make-nrxysin 1000 0.1 5 0.5))) (do ((i 0 (+ i 1))) ((= i 2000)) (outa i (nrxysin gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";nrxysin ~A" snd)) (if (fneq (maxamp snd) 0.985) (snd-display #__line__ ";nrxysin max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-nrxycos 1000 0.1 5 0.5))) (do ((i 0 (+ i 1))) ((= i 2000)) (outa i (nrxycos gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";nrxycos ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";nrxycos max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-nrxycos 1000 0.1 15 0.5)) (indr (make-env '(0 -1 1 1) :length 40000 :scaler 0.9999))) (do ((i 0 (+ i 1))) ((= i 40000)) (set! (mus-scaler gen) (env indr)) (outa i (nrxycos gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";nrxycos with scaler ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";nrxycos with scaler max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((black4 (make-blackman 440.0))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (blackman black4 0.0)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";blackman ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";blackman max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((black4 (make-sinc-train 440.0 10))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (sinc-train black4 0.0)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";sinc-train ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";sinc-train max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-k3sin 100.0))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (k3sin gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";k3sin ~A" snd)) (if (ffneq (maxamp snd) 1.0) (snd-display #__line__ ";k3sin max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f :statistics #t) (let ((gen (make-izcos 100.0 1.0))) (do ((i 0 (+ i 1))) ((= i 30000)) (outa i (izcos gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";izcos ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";izcos max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-rxysin 1000 0.1 0.5))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (* .5 (rxysin gen))))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";rxysin ~A" snd)) (if (> (maxamp snd) 1.0) (snd-display #__line__ ";rxysin max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-rxycos 1000 0.1 0.5))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (rxycos gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";rxycos ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";rxycos max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f :srate 44100) (let ((gen (make-safe-rxycos 1000 0.1 0.5))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (safe-rxycos gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";safe-rxycos ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";safe-rxycos max: ~A" (maxamp snd)))) (let* ((base-r 0.0) (end-r 0.0) (res (with-sound (:clipped #f :channels 2 :srate 44100) (let ((gen1 (make-safe-rxycos 1000 1 0.99)) (gen2 (make-safe-rxycos 1000 1 0.99)) (frqf (make-env '(0 0 1 1) :length 10000 :scaler (hz->radians 1000)))) (let ((set-freq (procedure-setter (gen2 'mus-frequency)))) (set! base-r (gen1 'r)) (do ((i 0 (+ i 1))) ((= i 10000)) (let ((fm (env frqf))) (set-freq gen2 (+ 1000 (radians->hz fm))) (outa i (safe-rxycos gen1 fm)) (outb i (safe-rxycos gen2 0.0)) (set! end-r (clamp-rxycos-r gen2 0.0)))))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";safe-rxycos 1 ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";safe-rxycos 1 max: ~A" (maxamp snd))) (if (fneq base-r .588) (snd-display #__line__ ";safe-rxycos-r 1 base: ~A" base-r)) (if (fneq end-r .316) (snd-display #__line__ ";safe-rxycos-r 1 end: ~A" end-r))) (let* ((base-r 0.0) (end-r 0.0) (res (with-sound (:clipped #f :channels 2 :srate 44100) (let ((gen1 (make-safe-rxycos 1000 .1 0.99)) (gen2 (make-safe-rxycos 1000 .1 0.99)) (frqf (make-env '(0 0 1 1) :length 10000 :scaler (hz->radians 1000)))) (let ((set-freq (procedure-setter (gen2 'mus-frequency)))) (set! base-r (gen1 'r)) (do ((i 0 (+ i 1))) ((= i 10000)) (let ((fm (env frqf))) (set-freq gen2 (+ 1000 (radians->hz fm))) (outa i (safe-rxycos gen1 fm)) (outb i (safe-rxycos gen2 0.0)) (set! end-r (clamp-rxycos-r gen2 0.0)))))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";safe-rxycos 2 ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";safe-rxycos 2 max: ~A" (maxamp snd))) (if (fneq base-r .951) (snd-display #__line__ ";safe-rxycos-r 2 base: ~A" base-r)) (if (fneq end-r .896) (snd-display #__line__ ";safe-rxycos-r 2 end: ~A" end-r))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-rxyk!sin 1000 0.1 0.5))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (rxyk!sin gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";rxyk!sin ~A" snd)) (if (fneq (maxamp snd) 0.992) (snd-display #__line__ ";rxyk!sin max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-rxyk!cos 1000 0.1 0.5))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (rxyk!cos gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";rxyk!cos ~A" snd)) (if (ffneq (maxamp snd) 1.0) (snd-display #__line__ ";rxyk!cos max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f :statistics #t :play #f) (let ((gen (make-nsincos 100.0 3))) (do ((i 0 (+ i 1))) ((= i 20000)) (outa i (nsincos gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";nsincos ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";nsincos max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f :play #f) (let ((gen (make-nchoosekcos 2000.0 0.05 10))) (do ((i 0 (+ i 1))) ((= i 30000)) (outa i (nchoosekcos gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";nchoosekcos ~A" snd)) (if (ffneq (maxamp snd) 1.0) (snd-display #__line__ ";nchoosekcos max: ~A" (maxamp snd)))) (let* ((res (with-sound () (let ((gen (make-adjustable-square-wave 100 .2 .5))) (do ((i 0 (+ i 1))) ((= i 200)) (outa i (adjustable-square-wave gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";adj sq ~A" snd)) (if (fneq (maxamp snd) 0.5) (snd-display #__line__ ";adj sq max: ~A" (maxamp snd)))) (let* ((res (with-sound () (let ((gen (make-adjustable-triangle-wave 100 .2 .5))) (do ((i 0 (+ i 1))) ((= i 22050)) (outa i (adjustable-triangle-wave gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";adj tri ~A" snd)) (if (ffneq (maxamp snd) 0.5) (snd-display #__line__ ";adj tri max: ~A" (maxamp snd)))) (let* ((res (with-sound () (let ((gen (make-adjustable-sawtooth-wave 100 .2 .5))) (do ((i 0 (+ i 1))) ((= i 22050)) (outa i (adjustable-sawtooth-wave gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";adj saw ~A" snd)) (if (ffneq (maxamp snd) 0.5) (snd-display #__line__ ";adj saw max: ~A" (maxamp snd)))) (with-sound (:clipped #f) ; at least run the thing -- not sure how to test this automatically (let ((gen (make-pink-noise 12))) (do ((i 0 (+ i 1))) ((= i 44100)) (outa i (pink-noise gen))))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-brown-noise 100.0))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (brown-noise gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";brown-noise ~A" snd)) (if (< (maxamp snd) 0.01) (snd-display #__line__ ";brown-noise max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-green-noise 100.0))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (green-noise gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";green-noise ~A" snd)) (if (or (< (maxamp snd) 0.01) (> (maxamp snd) 1.0)) (snd-display #__line__ ";green-noise max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-green-noise 100.0 0.1 -0.1 0.5))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (green-noise gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";green-noise .5 ~A" snd)) (if (or (< (maxamp snd) 0.01) (> (maxamp snd) 0.5)) (snd-display #__line__ ";green-noise .5 max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-green-noise-interp 100.0))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (green-noise-interp gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";green-noise-interp ~A" snd)) (if (or (< (maxamp snd) 0.01) (> (maxamp snd) 1.0)) (snd-display #__line__ ";green-noise-interp max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-green-noise-interp 100.0 0.1 -0.1 0.5))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (green-noise-interp gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";green-noise-interp .5 ~A" snd)) (if (or (< (maxamp snd) 0.01) (> (maxamp snd) 0.5)) (snd-display #__line__ ";green-noise-interp .5 max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen (make-tanhsin 440.0 2.0))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (tanhsin gen)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";tanhsin ~A" snd)) (if (> (abs (- 1.0 (maxamp snd))) 0.1) (snd-display #__line__ ";tanhsin max: ~A" (maxamp snd)))) (if (not (provided? 'snd-nogui)) (let* ((snd (new-sound)) (rd (make-readin "oboe.snd")) (ft (make-moving-fft rd)) (data (make-float-vector 256))) (set! (lisp-graph?) #t) (do ((i 0 (+ i 1))) ((= i 10000)) (if (moving-fft ft) (begin (float-vector-subseq (mus-xcoeffs ft) 0 255 data) (graph data "fft" 0.0 11025.0 0.0 0.1 snd 0 #t)))) (close-sound snd))) (test-sv) (let ((rd (make-readin "1a.snd")) (cur-srate (mus-sound-srate "1a.snd")) (old-srate *clm-srate*)) (set! *clm-srate* cur-srate) (let* ((scn (make-moving-pitch rd)) (pitch (moving-pitch scn))) (if (or (> pitch 443.0) (< pitch 439.0)) (snd-display #__line__ ";moving-pitch 1a: ~A" pitch))) (set! *clm-srate* old-srate)) (let ((val (make-vector 3)) (frq 0.0)) (set! (val 0) (make-nrcos 100)) (set! (val 1) (make-nrcos 200)) (set! (val 2) (make-nrcos 300)) (set! frq (mus-frequency (vector-ref val 1))) (if (fneq frq 200.0) (snd-display #__line__ ";defgen vect freq: ~A" frq))) (let ((val (make-vector 3)) (frq 0.0)) (set! (val 0) (make-nrcos 100)) (set! (val 1) (make-nrcos 200)) (set! (val 2) (make-nrcos 300)) (set! frq (+ (mus-frequency (vector-ref val 0)) (mus-frequency (vector-ref val 1)) (mus-frequency (vector-ref val 2)))) (if (fneq frq 600.0) (snd-display #__line__ ";defgen vect freq 1: ~A" frq))) (let ((val (make-vector 3)) (frq 0.0)) (set! (val 0) (make-nrcos 100)) (set! (val 1) (make-nrcos 200)) (set! (val 2) (make-nrcos 300)) (set! (mus-frequency (vector-ref val 1)) 500.0) (set! frq (mus-frequency (vector-ref val 1))) (if (fneq frq 500.0) (snd-display #__line__ ";defgen set freq: ~A ~A" frq (mus-frequency (vector-ref val 1))))) (let* ((res (with-sound (:clipped #f) (let ((v (make-vector 2 #f))) (set! (v 0) (make-nrcos 440 10 .5)) (set! (v 1) (make-nrcos 440 10 .5)) (do ((i 0 (+ i 1))) ((= i 1000)) (outa i (nrcos (vector-ref v 0) 0.0)))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";vect nrcos ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";vect nrcos max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((val (make-vector 2))) (set! (val 0) (make-nrcos 100 1 .1)) (set! (val 1) (make-nrcos 200 1 .1)) (do ((i 0 (+ i 1))) ((= i 2000)) (outa i (* .5 (+ (nrcos (vector-ref val 0) 0.0) (nrcos (vector-ref val 1) 0.0)))))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";vect 2 nrcos ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";vect 2 nrcos max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((gen1 (make-nrcos 100 1 .1)) (gen2 (make-nrcos 200 1 .1))) (do ((i 0 (+ i 1))) ((= i 2000)) (outa i (* .5 (+ (nrcos gen1 0.0) (nrcos gen2 0.0)))))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";no vect 2 nrcos ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";no vect 2 nrcos max: ~A" (maxamp snd)))) (let* ((res (with-sound (:clipped #f) (let ((v (make-vector 2 #f))) (set! (v 0) (make-nrcos 440 10 .5)) (set! (v 1) (make-nrcos 440 10 .5)) (do ((i 0 (+ i 1))) ((= i 2000)) (let ((gen (vector-ref v 0))) (outa i (nrcos gen))))))) (snd (find-sound res))) (if (not (sound? snd)) (snd-display #__line__ ";vect let nrcos ~A" snd)) (if (fneq (maxamp snd) 1.0) (snd-display #__line__ ";vect let nrcos max: ~A" (maxamp snd)))) (with-sound (:play #t) (let* ((exp-amt 8.0) (dur 2.0) (samps (seconds->samples dur)) (ampf (make-env '(0.000 0.000 0.011 0.147 0.023 0.131 0.028 0.034 0.059 0.000 0.063 0.153 0.067 0.113 0.072 0.391 0.081 0.095 0.088 0.052 0.102 0.025 0.124 0.000 0.131 0.452 0.139 0.327 0.144 0.099 0.156 0.097 0.160 0.048 0.186 0.000 0.194 0.438 0.200 0.366 0.201 0.156 0.211 0.063 0.247 0.000 0.256 0.628 0.268 0.154 0.274 0.190 0.285 0.027 0.296 0.059 0.309 0.031 0.312 0.481 0.322 0.939 0.331 0.314 0.351 0.061 0.363 0.099 0.374 0.056 0.377 0.438 0.389 0.858 0.394 0.467 0.403 0.241 0.414 0.197 0.415 0.127 0.425 0.075 0.436 0.090 0.441 0.526 0.454 0.869 0.471 0.239 0.490 0.029 0.503 0.117 0.505 0.485 0.514 0.811 0.528 0.415 0.538 0.088 0.552 0.056 0.561 0.106 0.580 0.075 0.597 0.000 0.776 0.000 0.777 0.573 0.786 0.145 0.801 0.054 0.826 0.000 0.827 0.632 0.844 1.000 0.856 0.524 0.866 0.031 0.883 0.074 0.891 0.136 0.896 0.745 0.907 0.424 0.915 0.765 0.934 0.059 0.951 0.048 0.962 0.079 0.970 0.436 0.986 0.266 1.000 0.000) :duration 0.25 :scaler 0.5)) (frqf (make-env '(0.000 0.220 0.074 0.249 0.133 0.249 0.194 0.240 0.258 0.252 0.324 0.264 0.389 0.267 0.456 0.270 0.520 0.264 0.847 0.270 0.920 0.273 1.000 0.279) :duration 0.25 :scaler (hz->radians (* 0.5 0.205 22050.0)))) (gen1 (make-polywave :partials (list 2 .35 3 .1 4 .8 5 .01 6 .03 8 .005))) (rnd (make-rand-interp 600 (hz->radians 50)))) (define (ifunc dir) (* (env ampf) (polywave gen1 (+ (env frqf) (rand-interp rnd))))) (let ((gran (make-granulate :expansion exp-amt :input ifunc))) (do ((i 0 (+ i 1))) ((= i samps)) (outa i (granulate gran)))))) (calling-all-animals) (calling-all-generators) (let () (define gen-list (list make-nssb make-nxysin make-nxycos make-nxy1cos make-nxy1sin make-noddsin make-noddcos make-noddssb make-ncos2 make-npcos make-nrsin make-nrcos make-nrssb make-nkssb make-nsincos make-rcos make-rssb make-rxysin make-rxycos make-rxyk!sin make-rxyk!cos make-ercos make-erssb make-eoddcos make-rkcos make-rksin make-rkssb make-rk!cos make-rk!ssb make-r2k!cos make-k2sin make-k2cos make-k2ssb make-dblsum make-rkoddssb make-krksin make-abcos make-absin make-r2k2cos make-bess make-jjcos make-j0evencos make-j2cos make-jpcos make-jncos make-j0j1cos make-jycos make-blackman make-fmssb make-k3sin make-izcos make-nchoosekcos make-n1cos make-adjustable-square-wave make-adjustable-triangle-wave make-adjustable-sawtooth-wave make-adjustable-oscil make-round-interp make-sinc-train make-pink-noise make-green-noise make-brown-noise make-green-noise-interp make-moving-max make-moving-norm make-moving-sum make-moving-rms make-moving-length make-weighted-moving-average make-exponentially-weighted-moving-average make-tanhsin (lambda args (make-moving-fft (make-readin "oboe.snd"))) make-moving-scentroid (lambda args (make-moving-autocorrelation (make-readin "oboe.snd"))) (lambda args (make-moving-pitch (make-readin "oboe.snd"))))) (for-each (lambda (name maker isit run) (let ((gen (maker))) (if (not (isit gen)) (format *stderr* ";~A is not a ~A?" gen name)) (run gen) (run gen))) (list 'nssb 'nxysin 'nxycos 'nxy1cos 'nxy1sin 'noddsin 'noddcos 'noddssb 'ncos2 'npcos 'nrsin 'nrcos 'nrssb 'nkssb 'nsincos 'rcos 'rssb 'rxysin 'rxycos 'rxyk!sin 'rxyk!cos 'ercos 'erssb 'eoddcos 'rkcos 'rksin 'rkssb 'rk!cos 'rk!ssb 'r2k!cos 'k2sin 'k2cos 'k2ssb 'dblsum 'rkoddssb 'krksin 'abcos 'absin 'r2k2cos 'bess 'jjcos 'j0evencos 'j2cos 'jpcos 'jncos 'j0j1cos 'jycos 'blackman 'fmssb 'k3sin 'izcos 'nchoosekcos 'n1cos 'adjustable-square-wave 'adjustable-triangle-wave 'adjustable-sawtooth-wave 'adjustable-oscil 'round-interp 'sinc-train 'pink-noise 'green-noise 'brown-noise 'green-noise-interp 'moving-max 'moving-norm 'moving-sum 'moving-rms 'moving-length 'weighted-moving-average 'exponentially-weighted-moving-average 'tanhsin 'moving-fft 'moving-scentroid 'moving-autocorrelation 'moving-pitch ) gen-list (list nssb? nxysin? nxycos? nxy1cos? nxy1sin? noddsin? noddcos? noddssb? ncos2? npcos? nrsin? nrcos? nrssb? nkssb? nsincos? rcos? rssb? rxysin? rxycos? rxyk!sin? rxyk!cos? ercos? erssb? eoddcos? rkcos? rksin? rkssb? rk!cos? rk!ssb? r2k!cos? k2sin? k2cos? k2ssb? dblsum? rkoddssb? krksin? abcos? absin? r2k2cos? bess? jjcos? j0evencos? j2cos? jpcos? jncos? j0j1cos? jycos? blackman? fmssb? k3sin? izcos? nchoosekcos? n1cos? adjustable-square-wave? adjustable-triangle-wave? adjustable-sawtooth-wave? adjustable-oscil? round-interp? sinc-train? pink-noise? green-noise? brown-noise? green-noise-interp? moving-max? moving-norm? moving-sum? moving-rms? moving-length? weighted-moving-average? exponentially-weighted-moving-average? tanhsin? moving-fft? moving-scentroid? moving-autocorrelation? moving-pitch? ) (list nssb nxysin nxycos nxy1cos nxy1sin noddsin noddcos noddssb ncos2 npcos nrsin nrcos nrssb nkssb nsincos rcos rssb rxysin rxycos rxyk!sin rxyk!cos ercos erssb eoddcos rkcos rksin rkssb rk!cos rk!ssb r2k!cos k2sin k2cos k2ssb dblsum rkoddssb krksin abcos absin r2k2cos bess jjcos j0evencos j2cos jpcos jncos j0j1cos jycos blackman fmssb k3sin izcos nchoosekcos n1cos adjustable-square-wave adjustable-triangle-wave adjustable-sawtooth-wave adjustable-oscil round-interp sinc-train pink-noise green-noise brown-noise green-noise-interp moving-max moving-norm (lambda (g) (moving-sum g 0.0)) (lambda (g) (moving-rms g 0.0)) (lambda (g) (moving-length g 0.0)) (lambda (g) (weighted-moving-average g 0.0)) exponentially-weighted-moving-average tanhsin moving-fft moving-scentroid moving-autocorrelation moving-pitch ))) (let ((gen1 (make-oscil 440.0)) (gen2 (make-oscil 440.0))) (do ((i 0 (+ i 1))) ((= i 1000)) (let* ((pm (mus-random 1.0)) (val1 (oscil gen1 0.0 pm)) (val2 (run-with-fm-and-pm gen2 0.0 pm))) ; generators.scm (if (fneq val1 val2) (snd-display #__line__ ";run-with-fm-and-pm: ~A ~A" val1 val2))))) (let ((gen1 (make-oscil 440.0)) (gen2 (make-oscil 440.0)) (happy #t)) (do ((i 0 (+ i 1))) ((or (not happy) (= i 1000))) (let* ((pm (mus-random 1.0)) (val1 (oscil gen1 0.0 pm)) (val2 (run-with-fm-and-pm gen2 0.0 pm))) (if (fneq val1 val2) (set! happy #f)))) (if (not happy) (snd-display #__line__ ";run-with-fm-and-pm unhappy"))) (if (pair? (sounds)) (for-each close-sound (sounds))) (test-documentation-instruments) ; clm23.scm ) ;;; ---------------- test 23: X/Xt/Xm -------------------- (define (snd_test_23) (when (and (provided? 'snd-motif) (provided? 'xm)) (with-let (sublet *motif*) (define x->snd-color (let ((documentation "(x->snd-color color-name) returns a Snd color object corresponding to the X11 color name 'color-name'")) (lambda (color-name) (let* ((col (XColor)) (dpy (XtDisplay (cadr (main-widgets)))) (scr (DefaultScreen dpy)) (cmap (DefaultColormap dpy scr))) (if (= (XAllocNamedColor dpy cmap color-name col col) 0) (snd-error (format #f "can't allocate ~A" color-name)) (make-color-with-catch (/ (.red col) 65535.0) (/ (.green col) 65535.0) (/ (.blue col) 65535.0))))))) (define (snd-test-clean-string str) ;; full file name should be unique, so I think we need only fix it up to look like a flat name (let* ((len (length str)) (new-str (make-string len #\.))) (do ((i 0 (+ i 1))) ((= i len) new-str) (let ((c (str i))) (if (memv c '(#\\ #\/)) (string-set! new-str i #\_) (string-set! new-str i c)))))) (define (tagged-p val sym) (or (not val) (and (list? val) (pair? val) (eq? (car val) sym)))) (define (array-p val type) (and (list? val) (or (null? val) (type (car val))))) (define XM_INT integer?) (define (XM_ULONG val) (and (integer? val) (>= val 0))) (define (XM_UCHAR val) (or (char? val) (and (integer? val) (>= val 0) (< val 65536)))) (define XM_FLOAT real?) (define (XM_STRING val) (or (not val) (string? val) (and (number? val) (= val 0)))) (define (XM_XMSTRING val) (or (tagged-p val 'XmString) (and (number? val) (= val 0)))) (define (XM_STRING_TABLE val) (or (array-p val (lambda (n) (eq? (car n) 'XmString))) (and (number? val) (= val 0)))) (define (XM_INT_TABLE val) (or (array-p val integer?) (and (number? val) (= val 0)))) (define (XM_BOOLEAN val) (or (boolean? val) (and (number? val) (= val 0)))) (define (XM_RENDER_TABLE val) (or (tagged-p val 'XmRenderTable) (and (number? val) (= val 0)))) (define (XM_TRANSFER_ENTRY_LIST val) (or (list? val) (and (number? val) (= val 0)))) (define (XM_RECTANGLE_LIST val) (or (array-p val (lambda (n) (eq? (car n) 'XRectangle))) (and (number? val) (= val 0)))) (define (XM_TAB_LIST val) (or (tagged-p val 'XmTabList) (and (number? val) (= val 0)))) (define (XM_WIDGET_LIST val) (or (array-p val (lambda (n) (eq? (car n) 'Widget))) (and (number? val) (= val 0)))) (define (XM_ATOM_LIST val) (or (not val) (array-p val (lambda (n) (eq? (car n) 'Atom))) (and (number? val) (= val 0)))) (define (XM_STRING_LIST val) (or (array-p val (lambda (n) (eq? (car n) 'XmString))) (and (number? val) (= val 0)))) (define (XM_CHARSET_TABLE val) (or (array-p val (lambda (n) (eq? (car n) 'CharSet))) (and (number? val) (= val 0)))) (define (XM_KEYSYM_TABLE val) (or (array-p val (lambda (n) (eq? (car n) 'KeySym))) (and (number? val) (= val 0)))) (define (XM_WIDGET val) (or (tagged-p val 'Widget) (and (number? val) (= val 0)))) (define (XM_PIXEL val) (or (tagged-p val 'Pixel) (and (number? val) (= val 0)))) (define (XM_PIXMAP val) (or (tagged-p val 'Pixmap) (and (number? val) (= val 0)))) (define (XM_XFONTSTRUCT val) (or (tagged-p val 'XFontStruct) (and (number? val) (= val 0)))) (define (XM_DIMENSION val) (and (integer? val) (>= val 0) (< val 65536))) (define (XM_ATOM val) (or (tagged-p val 'Atom) (and (number? val) (= val 0)))) (define (XM_TEXT_SOURCE val) (or (tagged-p val 'XmTextSource) (and (number? val) (= val 0)))) (define (XM_COLORMAP val) (or (tagged-p val 'Colormap) (and (number? val) (= val 0)))) (define (XM_KEYSYM val) (or (tagged-p val 'KeySym) (and (number? val) (= val 0)))) (define (XM_SCREEN val) (or (tagged-p val 'Screen) (and (number? val) (= val 0)))) (define (XM_WINDOW val) (or (tagged-p val 'Window) (and (number? val) (= val 0)))) (define (XM_VISUAL val) (or (tagged-p val 'Visual) (and (number? val) (= val 0)))) (define (XM_WIDGET_CLASS val) (or (tagged-p val 'WidgetClass) (and (number? val) (= val 0)))) (define (XM_STRING_OR_INT val) (or (string? val) (integer? val) (not val))) (define (XM_STRING_OR_XMSTRING val) (or (string? val) (not val) (and (list? val) (pair? val) (eq? (car val) 'XmString)) (and (number? val) (= val 0)))) (define (XM_POSITION val) (and (integer? val) (< (abs val) 65536))) (define (XM_SHORT val) (and (integer? val) (< (abs val) 65536))) (define (XM_CALLBACK val) (or (procedure? val) (not val) (integer? val))) (define (XM_TRANSFER_CALLBACK val) (or (procedure? val) (not val) (integer? val) (and (list? val) (pair? val) (procedure? (car val))))) (define (XM_CONVERT_CALLBACK val) (or (procedure? val) (not val) (integer? val) (and (list? val) (pair? val) (procedure? (car val))))) (define (XM_SEARCH_CALLBACK val) (or (procedure? val) (not val) (integer? val))) (define (XM_ORDER_CALLBACK val) (or (procedure? val) (not val) (integer? val))) (define (XM_QUALIFY_CALLBACK val) (or (procedure? val) (not val) (integer? val))) (define (XM_ALLOC_COLOR_CALLBACK val) (or (procedure? val) (not val) (integer? val))) (define (XM_POPUP_CALLBACK val) (or (procedure? val) (not val) (integer? val))) (define (XM_SCREEN_COLOR_CALLBACK val) (or (procedure? val) (not val) (integer? val))) (define (XM_DROP_CALLBACK val) (or (procedure? val) (not val) (integer? val))) (define (XM_PARSE_CALLBACK val) (or (procedure? val) (not val) (integer? val))) ;; check some resource stuff first (let ((hgt (cadr (XtVaGetValues (cadr (main-widgets)) (list XmNheight 0)))) (wid (cadr (XtVaGetValues (cadr (main-widgets)) (list XmNwidth 0))))) (if (or (<= wid 0) (<= hgt 0) (> wid 65535) (> hgt 65535)) (snd-display #__line__ ";Dimension miscast: ~A ~A" wid hgt))) ;; ---------------- X tests ---------------- (let ((scr (current-screen)) (dpy (XtDisplay (cadr (main-widgets))))) (if (and (not (= (.height scr) 1200)) (not (= (.height scr) 1600))) (snd-display #__line__ ";screen height: ~A" (.height scr))) (if (and (not (= (.width scr) 1600)) (not (= (.width scr) 2560))) (snd-display #__line__ ";screen width: ~A" (.width scr))) (if (not (= (.ndepths scr) 7)) (snd-display #__line__ ";screen ndepths: ~A" (.ndepths scr))) (let ((dps (.depths scr))) (if (or (not (= (length dps) (.ndepths scr))) (not (Depth? (car dps)))) (snd-display #__line__ ";depths: ~A" (.depths scr))) (if (not (= (.depth (car dps)) 24)) (snd-display #__line__ ";.depths val: ~A" (map .depth dps))) (if (pair? (.visuals (car dps))) (if (not (Visual? (car (.visuals (car dps))))) (snd-display #__line__ ";visuals: ~A" (map .visuals dps)) (if (not (= (.bits_per_rgb (car (.visuals (car dps)))) 8)) (snd-display #__line__ ";bits/visuals: ~A" (map .bits_per_rgb (.visuals (car dps)))))) (if (and (cadr dps) (pair? (.visuals (cadr dps)))) (if (not (Visual? (car (.visuals (cadr dps))))) (snd-display #__line__ ";visuals: ~A" (map .visuals dps)) (if (not (= (.bits_per_rgb (car (.visuals (cadr dps)))) 8)) (snd-display #__line__ ";bits/visuals: ~A" (map .bits_per_rgb (.visuals (cadr dps))))))))) (if (not (= (cadr (.white_pixel scr)) 16777215)) (snd-display #__line__ ";screen white_pixel: ~A" (.white_pixel scr))) (if (not (= (cadr (.black_pixel scr)) 0)) (snd-display #__line__ ";screen black_pixel: ~A" (.black_pixel scr))) (if (.backing_store scr) (snd-display #__line__ ";screen backing_store: ~A" (.backing_store scr))) (if (not (= (.min_maps scr) 1)) (snd-display #__line__ ";screen min_maps: ~A" (.min_maps scr))) (if (not (= (.max_maps scr) 1)) (snd-display #__line__ ";screen max_maps: ~A" (.max_maps scr))) (if (.save_unders scr) (snd-display #__line__ ";screen save_unders: ~A" (.save_unders scr))) (if (not (GC? (.default_gc scr))) (snd-display #__line__ ";screen default_gc: ~A" (.default_gc scr))) (if (not (Window? (.root scr))) (snd-display #__line__ ";screen root: ~A" (.root scr))) (if (not (Colormap? (.cmap scr))) (snd-display #__line__ ";screen colormap: ~A" (.cmap scr))) (if (not (equal? (DisplayOfScreen scr) (.display scr))) (snd-display #__line__ ";DisplayOfScreen: ~A ~A" (DisplayOfScreen scr) (.display scr))) (if (not (equal? (RootWindowOfScreen scr) (.root scr))) (snd-display #__line__ ";RootWindowOfScreen: ~A ~A" (RootWindowOfScreen scr) (.root scr))) (if (not (equal? (BlackPixelOfScreen scr) (.black_pixel scr))) (snd-display #__line__ ";BlackPixelOfScreen: ~A ~A" (BlackPixelOfScreen scr) (.black_pixel scr))) (if (not (equal? (WhitePixelOfScreen scr) (.white_pixel scr))) (snd-display #__line__ ";WhitePixelOfScreen: ~A ~A" (WhitePixelOfScreen scr) (.white_pixel scr))) (if (not (equal? (DefaultColormapOfScreen scr) (.cmap scr))) (snd-display #__line__ ";DefaultColormapOfScreen: ~A ~A" (DefaultColormapOfScreen scr) (.cmap scr))) (if (not (equal? (DefaultDepthOfScreen scr) (.root_depth scr))) (snd-display #__line__ ";DefaultDepthOfScreen: ~A ~A" (DefaultDepthOfScreen scr) (.root_depth scr))) (if (not (equal? (DefaultGCOfScreen scr) (.default_gc scr))) (snd-display #__line__ ";DefaultGCOfScreen: ~A ~A" (DefaultGCOfScreen scr) (.default_gc scr))) (if (not (equal? (DefaultVisualOfScreen scr) (.root_visual scr))) (snd-display #__line__ ";DefaultVisualOfScreen: ~A ~A" (DefaultVisualOfScreen scr) (.root_visual scr))) (if (not (equal? (WidthOfScreen scr) (.width scr))) (snd-display #__line__ ";WidthOfScreen: ~A ~A" (WidthOfScreen scr) (.width scr))) (if (not (equal? (HeightOfScreen scr) (.height scr))) (snd-display #__line__ ";HeightOfScreen: ~A ~A" (HeightOfScreen scr) (.height scr))) (if (not (equal? (WidthMMOfScreen scr) (.mwidth scr))) (snd-display #__line__ ";WidthMMOfScreen: ~A ~A" (WidthMMOfScreen scr) (.mwidth scr))) (if (not (equal? (HeightMMOfScreen scr) (.mheight scr))) (snd-display #__line__ ";HeightMMOfScreen: ~A ~A" (HeightMMOfScreen scr) (.mheight scr))) (if (not (equal? (PlanesOfScreen scr) (.root_depth scr))) (snd-display #__line__ ";PlanesOfScreen: ~A ~A" (PlanesOfScreen scr) (.root_depth scr))) (if (not (equal? (MinCmapsOfScreen scr) (.min_maps scr))) (snd-display #__line__ ";MinCmapsOfScreen: ~A ~A" (MinCmapsOfScreen scr) (.min_maps scr))) (if (not (equal? (MaxCmapsOfScreen scr) (.max_maps scr))) (snd-display #__line__ ";MaxCmapsOfScreen: ~A ~A" (MaxCmapsOfScreen scr) (.max_maps scr))) (if (not (equal? (DoesSaveUnders scr) (.save_unders scr))) (snd-display #__line__ ";DoesSaveUnders: ~A ~A" (DoesSaveUnders scr) (.save_unders scr))) (if (not (equal? (DoesBackingStore scr) (.backing_store scr))) (snd-display #__line__ ";DoesBackingStore: ~A ~A" (DoesBackingStore scr) (.backing_store scr))) (if (not (equal? (EventMaskOfScreen scr) (.root_input_mask scr))) (snd-display #__line__ ";EventMaskOfScreen: ~A ~A" (EventMaskOfScreen scr) (.root_input_mask scr))) (if (not (equal? (XDisplayOfScreen scr) (.display scr))) (snd-display #__line__ ";XDisplayOfScreen: ~A ~A" (XDisplayOfScreen scr) (.display scr))) (if (not (equal? (XDisplayOfScreen (XScreenOfDisplay dpy 0)) dpy)) (snd-display #__line__ ";XScreenOfDisplay ~A ~A" (XDisplayOfScreen (XScreenOfDisplay dpy 0)) dpy)) (if (not (equal? (XDefaultScreenOfDisplay dpy) scr)) (snd-display #__line__ ";XDefaultScreenOfDisplay ~A ~A" (XDefaultScreenOfDisplay dpy) scr)) (if (not (equal? (XRootWindowOfScreen scr) (.root scr))) (snd-display #__line__ ";XRootWindowOfScreen: ~A ~A" (XRootWindowOfScreen scr) (.root scr))) (if (not (equal? (XBlackPixelOfScreen scr) (.black_pixel scr))) (snd-display #__line__ ";XBlackPixelOfScreen: ~A ~A" (XBlackPixelOfScreen scr) (.black_pixel scr))) (if (not (equal? (XWhitePixelOfScreen scr) (.white_pixel scr))) (snd-display #__line__ ";XWhitePixelOfScreen: ~A ~A" (XWhitePixelOfScreen scr) (.white_pixel scr))) (if (not (equal? (XDefaultColormapOfScreen scr) (.cmap scr))) (snd-display #__line__ ";XDefaultColormapOfScreen: ~A ~A" (XDefaultColormapOfScreen scr) (.cmap scr))) (if (not (equal? (XDefaultDepthOfScreen scr) (.root_depth scr))) (snd-display #__line__ ";XDefaultDepthOfScreen: ~A ~A" (XDefaultDepthOfScreen scr) (.root_depth scr))) (if (not (equal? (XDefaultGCOfScreen scr) (.default_gc scr))) (snd-display #__line__ ";XDefaultGCOfScreen: ~A ~A" (XDefaultGCOfScreen scr) (.default_gc scr))) (if (not (equal? (XDefaultVisualOfScreen scr) (.root_visual scr))) (snd-display #__line__ ";XDefaultVisualOfScreen: ~A ~A" (XDefaultVisualOfScreen scr) (.root_visual scr))) (if (not (equal? (XWidthOfScreen scr) (.width scr))) (snd-display #__line__ ";XWidthOfScreen: ~A ~A" (XWidthOfScreen scr) (.width scr))) (if (not (equal? (XHeightOfScreen scr) (.height scr))) (snd-display #__line__ ";XHeightOfScreen: ~A ~A" (XHeightOfScreen scr) (.height scr))) (if (not (equal? (XWidthMMOfScreen scr) (.mwidth scr))) (snd-display #__line__ ";XWidthMMOfScreen: ~A ~A" (XWidthMMOfScreen scr) (.mwidth scr))) (if (not (equal? (XHeightMMOfScreen scr) (.mheight scr))) (snd-display #__line__ ";XHeightMMOfScreen: ~A ~A" (XHeightMMOfScreen scr) (.mheight scr))) (if (not (equal? (XPlanesOfScreen scr) (.root_depth scr))) (snd-display #__line__ ";XPlanesOfScreen: ~A ~A" (XPlanesOfScreen scr) (.root_depth scr))) (if (not (equal? (XMinCmapsOfScreen scr) (.min_maps scr))) (snd-display #__line__ ";XMinCmapsOfScreen: ~A ~A" (XMinCmapsOfScreen scr) (.min_maps scr))) (if (not (equal? (XMaxCmapsOfScreen scr) (.max_maps scr))) (snd-display #__line__ ";XMaxCmapsOfScreen: ~A ~A" (XMaxCmapsOfScreen scr) (.max_maps scr))) (if (not (equal? (XDoesSaveUnders scr) (.save_unders scr))) (snd-display #__line__ ";XDoesSaveUnders: ~A ~A" (XDoesSaveUnders scr) (.save_unders scr))) (if (not (equal? (XDoesBackingStore scr) (.backing_store scr))) (snd-display #__line__ ";XDoesBackingStore: ~A ~A" (XDoesBackingStore scr) (.backing_store scr))) (if (not (equal? (XEventMaskOfScreen scr) (.root_input_mask scr))) (snd-display #__line__ ";XEventMaskOfScreen: ~A ~A" (XEventMaskOfScreen scr) (.root_input_mask scr))) ) (let* ((scr (current-screen)) (scrn (XScreenNumberOfScreen scr)) (dpy (XtDisplay (cadr (main-widgets)))) (vis (DefaultVisual dpy scrn)) (win (XtWindow (cadr (main-widgets))))) (if (not (equal? (RootWindow dpy scrn) (.root scr))) (snd-display #__line__ ";RootWindow: ~A ~A" (RootWindow dpy scrn) (.root scr))) (if (not (equal? (DefaultRootWindow dpy) (.root (ScreenOfDisplay dpy (DefaultScreen dpy))))) (snd-display #__line__ ";DefaultRootWindow: ~A ~A" (DefaultRootWindow dpy) (.root (ScreenOfDisplay dpy (DefaultScreen dpy))))) (if (not (equal? (DefaultVisual dpy scrn) (.root_visual scr))) (snd-display #__line__ ";DefaultVisual: ~A ~A" (DefaultVisual dpy scrn) (.root_visual scr))) (if (not (equal? (DefaultGC dpy scrn) (.default_gc scr))) (snd-display #__line__ ";DefaultGC: ~A ~A" (DefaultGC dpy scrn) (.default_gc scr))) (if (not (equal? (BlackPixel dpy scrn) (.black_pixel scr))) (snd-display #__line__ ";BlackPixel: ~A ~A" (BlackPixel dpy scrn) (.black_pixel scr))) (if (not (equal? (WhitePixel dpy scrn) (.white_pixel scr))) (snd-display #__line__ ";WhitePixel ~A ~A" (WhitePixel dpy scrn) (.white_pixel scr))) (if (not (equal? (DisplayWidth dpy scrn) (.width scr))) (snd-display #__line__ ";DisplayWidth: ~A ~A" (DisplayWidth dpy scrn) (.width scr))) (if (not (equal? (DisplayHeight dpy scrn) (.height scr))) (snd-display #__line__ ";DisplayHeight: ~A ~A" (DisplayHeight dpy scrn) (.height scr))) (if (not (equal? (DisplayWidthMM dpy scrn) (.mwidth scr))) (snd-display #__line__ ";DisplayWidthMM: ~A ~A" (DisplayWidthMM dpy scrn) (.mwidth scr))) (if (not (equal? (DisplayHeightMM dpy scrn) (.mheight scr))) (snd-display #__line__ ";DisplayHeightMM: ~A ~A" (DisplayHeightMM dpy scrn) (.mheight scr))) (if (not (equal? (DisplayPlanes dpy scrn) (.root_depth scr))) (snd-display #__line__ ";DisplayPlanes: ~A ~A" (DisplayPlanes dpy scrn) (.root_depth scr))) (if (not (equal? (DefaultDepth dpy scrn) (.root_depth scr))) (snd-display #__line__ ";DefaultDepth: ~A ~A" (DefaultDepth dpy scrn) (.root_depth scr))) (if (not (equal? (DefaultColormap dpy scrn) (.cmap scr))) (snd-display #__line__ ";DefaultColormap: ~A ~A" (DefaultColormap dpy scrn) (.cmap scr))) (if (not (equal? (XRootWindow dpy scrn) (.root scr))) (snd-display #__line__ ";XRootWindow: ~A ~A" (XRootWindow dpy scrn) (.root scr))) (if (not (equal? (XDefaultRootWindow dpy) (.root (ScreenOfDisplay dpy (DefaultScreen dpy))))) (snd-display #__line__ ";XDefaultRootWindow: ~A ~A" (XDefaultRootWindow dpy) (.root (ScreenOfDisplay dpy (DefaultScreen dpy))))) (if (not (equal? (XDefaultVisual dpy scrn) (.root_visual scr))) (snd-display #__line__ ";XDefaultVisual: ~A ~A" (XDefaultVisual dpy scrn) (.root_visual scr))) (if (not (equal? (XDefaultGC dpy scrn) (.default_gc scr))) (snd-display #__line__ ";XDefaultGC: ~A ~A" (XDefaultGC dpy scrn) (.default_gc scr))) (if (not (equal? (XBlackPixel dpy scrn) (.black_pixel scr))) (snd-display #__line__ ";XBlackPixel: ~A ~A" (XBlackPixel dpy scrn) (.black_pixel scr))) (if (not (equal? (XWhitePixel dpy scrn) (.white_pixel scr))) (snd-display #__line__ ";XWhitePixel ~A ~A" (XWhitePixel dpy scrn) (.white_pixel scr))) (if (not (equal? (XDisplayWidth dpy scrn) (.width scr))) (snd-display #__line__ ";XDisplayWidth: ~A ~A" (XDisplayWidth dpy scrn) (.width scr))) (if (not (equal? (XDisplayHeight dpy scrn) (.height scr))) (snd-display #__line__ ";XDisplayHeight: ~A ~A" (XDisplayHeight dpy scrn) (.height scr))) (if (not (equal? (XDisplayWidthMM dpy scrn) (.mwidth scr))) (snd-display #__line__ ";XDisplayWidthMM: ~A ~A" (XDisplayWidthMM dpy scrn) (.mwidth scr))) (if (not (equal? (XDisplayHeightMM dpy scrn) (.mheight scr))) (snd-display #__line__ ";XDisplayHeightMM: ~A ~A" (XDisplayHeightMM dpy scrn) (.mheight scr))) (if (not (equal? (XDisplayPlanes dpy scrn) (.root_depth scr))) (snd-display #__line__ ";XDisplayPlanes: ~A ~A" (XDisplayPlanes dpy scrn) (.root_depth scr))) (if (not (equal? (XDefaultDepth dpy scrn) (.root_depth scr))) (snd-display #__line__ ";XDefaultDepth: ~A ~A" (XDefaultDepth dpy scrn) (.root_depth scr))) (if (not (equal? (XDefaultColormap dpy scrn) (.cmap scr))) (snd-display #__line__ ";XDefaultColormap: ~A ~A" (XDefaultColormap dpy scrn) (.cmap scr))) (if (not (equal? (XDefaultVisual dpy scrn) vis)) (snd-display #__line__ ";XDefaultVisual: ~A ~A" (XDefaultVisual dpy scrn) vis)) (if (not (equal? (DisplayCells dpy scrn) (.map_entries vis))) (snd-display #__line__ ";DisplayCells: ~A ~A" (DisplayCells dpy scrn) (.map_entries vis))) (if (not (equal? (CellsOfScreen scr) (.map_entries (DefaultVisualOfScreen scr)))) (snd-display #__line__ ";CellsOfScreen: ~A ~A" (CellsOfScreen scr) (.map_entries (DefaultVisualOfScreen scr)))) (if (not (equal? (XDisplayCells dpy scrn) (.map_entries vis))) (snd-display #__line__ ";XDisplayCells: ~A ~A" (XDisplayCells dpy scrn) (.map_entries vis))) (if (not (equal? (XCellsOfScreen scr) (.map_entries (DefaultVisualOfScreen scr)))) (snd-display #__line__ ";XCellsOfScreen: ~A ~A" (XCellsOfScreen scr) (.map_entries (DefaultVisualOfScreen scr)))) (if (< (XNextRequest dpy) (XLastKnownRequestProcessed dpy)) (snd-display #__line__ ";XRequests: ~A ~A" (XNextRequest dpy) (XLastKnownRequestProcessed dpy))) (if (< (NextRequest dpy) (LastKnownRequestProcessed dpy)) (snd-display #__line__ ";Requests: ~A ~A" (NextRequest dpy) (LastKnownRequestProcessed dpy))) (if (not (= (XDisplayMotionBufferSize dpy) 256)) (snd-display #__line__ ";XDisplayMotionBufferSize: ~A" (XDisplayMotionBufferSize dpy))) (XGetMotionEvents dpy win (list 'Time 100) (list 'Time CurrentTime)) (let ((lmapk (XNewModifiermap 2)) (kcd (list 'KeyCode 50))) (if (not (XModifierKeymap? lmapk)) (snd-display #__line__ ";xNewModifiermap: ~A" lmapk) (begin (set! lmapk (XInsertModifiermapEntry lmapk kcd ShiftMapIndex)) (set! lmapk (XDeleteModifiermapEntry lmapk kcd ShiftMapIndex)) ; (XFreeModifiermap lmapk) ;prone to segfault in X ))) (if (not (= (XExtendedMaxRequestSize dpy) 4194303)) (snd-display #__line__ ";XExtendedMaxRequestSize ~A" (XExtendedMaxRequestSize dpy))) (if (not (= (XMaxRequestSize dpy) 65535)) (snd-display #__line__ ";XMaxRequestSize ~A" (XMaxRequestSize dpy))) (if (not (member (list 'Atom 40) (XListProperties dpy win))) (snd-display #__line__ ";XListProperties: ~A" (XListProperties dpy win))) (if (not (member "SHAPE" (XListExtensions dpy))) (snd-display #__line__ ";XListExtensions: ~A" (XListExtensions dpy))) (let ((val (XListInstalledColormaps dpy win))) (if (or (not val) (null? val) (not (Colormap? (car val)))) (snd-display #__line__ ";XListInstalledColormaps: ~A" (XListInstalledColormaps dpy win)))) (if (not (string=? (XKeysymToString (list 'KeySym 80)) "P")) (snd-display #__line__ ";XKeysymToString: ~A" (XKeysymToString (list 'KeySym 80)))) (if (not (string=? (XGetAtomName dpy (list 'Atom 40)) "WM_NORMAL_HINTS")) (snd-display #__line__ ";XGetAtomName: ~A" (XGetAtomName dpy (list 'Atom 40)))) (if (not (= (.bits_per_rgb vis) 8)) (snd-display #__line__ ";bits_per_rgb: ~A" (.bits_per_rgb vis))) (if (not (= (.blue_mask vis) 255)) (snd-display #__line__ ";blue_mask: ~A" (.blue_mask vis))) (if (not (= (.green_mask vis) 65280)) (snd-display #__line__ ";green_mask: ~A" (.green_mask vis))) (if (not (= (.red_mask vis) 16711680)) (snd-display #__line__ ";red_mask: ~A" (.red_mask vis))) (if (not (= AllPlanes 4294967295)) (snd-display #__line__ ";AllPlanes: ~A" AllPlanes)) (if (< (QLength dpy) 0) (snd-display #__line__ ";QLength: ~A" (QLength dpy))) (if (not (= (ScreenCount dpy) 1)) (snd-display #__line__ ";ScreenCount: ~A" (ScreenCount dpy))) (if (not (string=? (ServerVendor dpy) "The X.Org Foundation")) (snd-display #__line__ ";ServerVendor: ~A" (ServerVendor dpy))) (if (not (= (ProtocolRevision dpy) 0)) (snd-display #__line__ ";ProtocolRevision: ~A" (ProtocolRevision dpy))) (if (not (= (ProtocolVersion dpy) 11)) (snd-display #__line__ ";ProtocolVersion: ~A" (ProtocolVersion dpy))) (if (not (number? (VendorRelease dpy))) (snd-display #__line__ ";VendorRelease: ~A" (VendorRelease dpy))) (if (not (string=? (DisplayString dpy) ":0.0")) (snd-display #__line__ ";DisplayString: ~A" (DisplayString dpy))) (if (not (= (BitmapUnit dpy) 32)) (snd-display #__line__ ";BitmapUnit: ~A" (BitmapUnit dpy))) (if (not (= (BitmapPad dpy) 32)) (snd-display #__line__ ";BitmapPad: ~A" (BitmapPad dpy))) (if (not (= (BitmapBitOrder dpy) 0)) (snd-display #__line__ ";BitmapBitOrder: ~A" (BitmapBitOrder dpy))) (if (not (= (ImageByteOrder dpy) 0)) (snd-display #__line__ ";ImageByteOrder: ~A" (ImageByteOrder dpy))) (if (not (= (DefaultScreen dpy) 0)) (snd-display #__line__ ";DefaultScreen: ~A" (DefaultScreen dpy))) (let* ((col (XColor)) (col1 (XColor)) (dpy (XtDisplay (cadr (main-widgets)))) (scr (DefaultScreen dpy)) (cmap (DefaultColormap dpy scr))) (if (= (XAllocNamedColor dpy cmap "blue" col col) 0) (snd-display #__line__ ";XAllocNamedColor blue ~A?" col)) (if (not (= (.red col) 0)) (snd-display #__line__ ";XAllocNamedColor: ~A" (.red col))) (if (= (XAllocColor dpy cmap col) 0) (snd-display #__line__ ";XAllocColor?")) (if (not (= (.red col) 0)) (snd-display #__line__ ";XAllocColor: ~A" (.red col))) (if (= (XParseColor dpy cmap "blue" col) 0) (snd-display #__line__ ";XParseColor?")) (if (not (= (.red col) 0)) (snd-display #__line__ ";XParseColor: ~A" (.red col))) (if (= (XAllocNamedColor dpy cmap "green" col1 col1) 0) (snd-display #__line__ ";XAllocNamedColor green ~A?" col1)) (XQueryColor dpy cmap col) (XQueryColors dpy cmap (list col col1))) (XSetAfterFunction dpy (lambda (n) 0)) (XSetAfterFunction dpy #f) (if (not (equal? (XDisplayKeycodes dpy) (list 1 8 255))) (snd-display #__line__ ";XDisplayKeycodes: ~A" (XDisplayKeycodes dpy))) (let ((str (XFetchName dpy win))) (if (not (string=? (substring str 0 3) "snd")) (snd-display #__line__ ";XFetchName: ~A" str))) (XStoreName dpy win "hiho") (let ((str (XFetchName dpy win))) (if (not (string=? str "hiho")) (snd-display #__line__ ";XStoreName: ~A" str))) (XStoreName dpy win "snd") (let ((str (XGetIconName dpy win))) (if (not (string=? str "snd")) (snd-display #__line__ ";XGetIconName: ~A" str))) (XSetIconName dpy win "hiho") (let ((str (XGetIconName dpy win))) (if (not (string=? str "hiho")) (snd-display #__line__ ";XSetIconName: ~A" str))) (let ((geo (XGetGeometry dpy win))) (if (or (not (= (window-width) (geo 4))) (not (= (window-height) (geo 5)))) (snd-display #__line__ ";XGetGeometry: ~A (~A ~A)" geo (window-width) (window-height)))) (let ((focus (XGetInputFocus dpy))) (if (or (not (= (car focus) 1)) (not (Window? (cadr focus)))) (snd-display #__line__ ";XGetInputFocus: ~A" focus))) (let ((vals (XGetPointerControl dpy))) (if (not (equal? vals (list 1 2 1 4))) (snd-display #__line__ ";pointer state: ~A" vals)) (XChangePointerControl dpy #f #t 2 1 8) (set! vals (XGetPointerControl dpy)) (if (not (equal? vals (list 1 2 1 8))) (snd-display #__line__ ";set pointer state: ~A" vals)) (XChangePointerControl dpy #f #t 2 1 4)) (XAutoRepeatOff dpy) (if (not (= ((XGetKeyboardControl dpy) 5) 0)) (snd-display #__line__ ";AutoRepeatOff?")) (XAutoRepeatOn dpy) (if (not (= ((XGetKeyboardControl dpy) 5) 1)) (snd-display #__line__ ";AutoRepeatOn?")) (let ((vals (XGetPointerMapping dpy 0 3))) (if (not (equal? vals (list 1 2 3))) (snd-display #__line__ ";XGetPointerMapping: ~A" vals))) (XGetScreenSaver dpy) (XMoveWindow dpy win 100 10) (XSync dpy #f) (XResizeWindow dpy win 400 400) (XSync dpy #f) (XMoveResizeWindow dpy win 120 20 500 500) (XSync dpy #f) (let ((attr (XGetWindowAttributes dpy win))) (if (> (abs (- (.x attr) 120)) 200) (snd-display #__line__ ";XMoveWindow x etc: ~A" (.x attr))) (if (> (abs (- (.y attr) 20)) 200) (snd-display #__line__ ";XMoveWindow y etc: ~A" (.y attr))) (if (> (abs (- (.width attr) 500)) 20) (snd-display #__line__ ";XMoveWindow width etc: ~A" (.width attr))) (if (> (abs (- (.height attr) 500)) 20) (snd-display #__line__ ";XMoveWindow height etc: ~A" (.height attr))) (if (not (= (.border_width attr) 0)) (snd-display #__line__ ";XGetWindowAttributes border_width: ~A" (.border_width attr))) (if (not (= (.depth attr) 24)) (snd-display #__line__ ";XGetWindowAttributes depth: ~A" (.depth attr))) (if (not (= (.bit_gravity attr) 0)) (snd-display #__line__ ";XGetWindowAttributes bit_gravity: ~A" (.bit_gravity attr))) (if (not (= (.win_gravity attr) 1)) (snd-display #__line__ ";XGetWindowAttributes win_gravity: ~A" (.win_gravity attr))) (if (.backing_store attr) (snd-display #__line__ ";XGetWindowAttributes backing_store: ~A" (.backing_store attr))) (if (.override_redirect attr) (snd-display #__line__ ";XGetWindowAttributes override_redirect: ~A" (.override_redirect attr))) (if (.save_under attr) (snd-display #__line__ ";XGetWindowAttributes save_under: ~A" (.save_under attr))) ; (if (.map_installed attr) (snd-display #__line__ ";XGetWindowAttributes map_installed: ~A" (.map_installed attr))) (if (not (equal? (.backing_pixel attr) (list 'Pixel 0))) (snd-display #__line__ ";XGetWindowAttributes backing_pixel: ~A" (.backing_pixel attr))) (if (not (= (.map_state attr) 2)) (snd-display #__line__ ";XGetWindowAttributes map_state: ~A" (.map_state attr))) (if (not (= (.your_event_mask attr) #x628033)) (snd-display #__line__ ";your_event_mask: ~X" (.your_event_mask attr))) (if (and (not (= (.all_event_masks attr) #x628033)) (not (= (.all_event_masks attr) #xe28033)) (not (= (.all_event_masks attr) #xea8033))) (snd-display #__line__ ";all_event_masks: ~X" (.all_event_masks attr))) (if (not (Screen? (.screen attr))) (snd-display #__line__ ";XGetWindowAttributes screen: ~A" (.screen attr))) (if (and (not (= (.do_not_propagate_mask attr) 0)) (not (= (.do_not_propagate_mask attr) 8204))) (snd-display #__line__ ";XGetWindowAttributes do_not_propagate_mask: ~A" (.do_not_propagate_mask attr))) (if (not (= (.backing_planes attr) AllPlanes)) (snd-display #__line__ ";XGetWindowAttributes backing_planes: ~A" (.backing_planes attr))) (if (not (= (.win_gravity attr) 1)) (snd-display #__line__ ";XGetWindowAttributes win_gravity: ~A" (.win_gravity attr))) (if (not (= (.bit_gravity attr) 0)) (snd-display #__line__ ";XGetWindowAttributes bit_gravity: ~A" (.bit_gravity attr))) ;(segfault) (XFree (cadr attr)) ) (XResetScreenSaver dpy) (if (< (XPending dpy) 0) (snd-display #__line__ ";XPending: ~A" (XPending dpy))) (XNoOp dpy) (XQueryBestStipple dpy win 100 100) (XQueryBestTile dpy win 100 100) (XQueryBestSize dpy 0 win 100 100) (let ((ext (XQueryExtension dpy "SHAPE"))) (if (not (eq? (car ext) #t)) (snd-display #__line__ ";XQueryExtension: ~A" ext))) (XQueryKeymap dpy) (let ((tree (XQueryTree dpy win))) (if (or (not (= (car tree) 1)) (not (equal? (XRootWindow dpy 0) (cadr tree)))) (snd-display #__line__ ";XQueryTree: ~A (~A)" tree (XRootWindow dpy 0)))) (if (< (XQLength dpy) 0) (snd-display #__line__ ";XQLength: ~A" (XQLength dpy))) (if (not (= (XScreenCount dpy) 1)) (snd-display #__line__ ";XScreenCount: ~A" (XScreenCount dpy))) (if (not (string=? (XServerVendor dpy) "The X.Org Foundation")) (snd-display #__line__ ";XServerVendor: ~A" (XServerVendor dpy))) (if (not (= (XProtocolRevision dpy) 0)) (snd-display #__line__ ";XProtocolRevision: ~A" (XProtocolRevision dpy))) (if (not (= (XProtocolVersion dpy) 11)) (snd-display #__line__ ";XProtocolVersion: ~A" (XProtocolVersion dpy))) (if (not (number? (XVendorRelease dpy))) (snd-display #__line__ ";XVendorRelease: ~A" (XVendorRelease dpy))) (if (not (string=? (XDisplayString dpy) ":0.0")) (snd-display #__line__ ";XDisplayString: ~A" (XDisplayString dpy))) (if (not (= (XBitmapUnit dpy) 32)) (snd-display #__line__ ";XBitmapUnit: ~A" (XBitmapUnit dpy))) (if (not (= (XBitmapPad dpy) 32)) (snd-display #__line__ ";XBitmapPad: ~A" (XBitmapPad dpy))) (if (not (= (XBitmapBitOrder dpy) 0)) (snd-display #__line__ ";XBitmapBitOrder: ~A" (XBitmapBitOrder dpy))) (if (not (= (XImageByteOrder dpy) 0)) (snd-display #__line__ ";XImageByteOrder: ~A" (XImageByteOrder dpy))) (if (not (= (XDefaultScreen dpy) 0)) (snd-display #__line__ ";XDefaultScreen: ~A" (XDefaultScreen dpy))) (if (XGetIconSizes dpy win) (snd-display #__line__ ";XGetIconSizes: ~A" (XGetIconSizes dpy win))) (if (XGetRGBColormaps dpy win XA_RGB_DEFAULT_MAP) (snd-display #__line__ ";XGetRGBColormaps: ~A!" (XGetRGBColormaps dpy win XA_RGB_DEFAULT_MAP))) (let ((cmap (XAllocStandardColormap))) (for-each (lambda (func name) (if (not (= (func cmap) 0)) (snd-display #__line__ ";standardcolormap ~A: ~A" name (func cmap)))) (list .visualid .red_max .red_mult .green_max .green_mult .blue_max .blue_mult) (list 'visualid 'red_max 'red_mult 'green_max 'green_mult 'blue_max 'blue_mult)) (if (.colormap cmap) (snd-display #__line__ ";colormap: ~A" (.colormap cmap))) (XtFree (cadr cmap)) ) (let ((icon (XAllocIconSize))) (for-each (lambda (func name) (if (not (= (func icon) 0)) (snd-display #__line__ ";iconsize ~A: ~A" name (func icon)))) (list .min_width .min_height .max_width .max_height .width_inc .height_inc) (list 'min_width 'min_height 'max_width 'max_height 'width_inc 'height_inc)) (XFree icon)) (let ((fs (XCreateFontSet dpy "*-*-*-*-Normal-*-*-*-*-*-*"))) (if (or (not (XFontSet? fs)) (= (cadr fs) 0)) (snd-display #__line__ ";XCreateFontSet: ~A" fs) (let* ((fnts (XFontsOfFontSet fs)) (fnt (caar fnts))) (if (not (XFontStruct? fnt)) (snd-display #__line__ ";XFontsOfFontSet: ~A" fnts)) (if (XContextualDrawing fs) (snd-display #__line__ ";XContextualDrawing: ~A" (XContextualDrawing fs))) (if (XContextDependentDrawing fs) (snd-display #__line__ ";XContextDependentDrawing: ~A" (XContextDependentDrawing fs))) (if (XDirectionalDependentDrawing fs) (snd-display #__line__ ";XDirectionalDependentDrawing: ~A" (XDirectionalDependentDrawing fs))) (if (not (string=? (XLocaleOfFontSet fs) "en_US")) (snd-display #__line__ ";XLocaleOfFontSet: ~A" (XLocaleOfFontSet fs))) (if (not (string=? (XBaseFontNameListOfFontSet fs) "*-*-*-*-Normal-*-*-*-*-*-*")) (snd-display #__line__ ";XBaseFontNameListOfFontSet: ~A" (XBaseFontNameListOfFontSet fs))) (if fnt (let ((wgt (XGetFontProperty fnt XA_WEIGHT)) (siz (XGetFontProperty fnt XA_POINT_SIZE))) (if (or (not (= (cadr wgt) 10)) (not (= (cadr siz) 120))) (snd-display #__line__ ";XGetFontProperty: ~A ~A" wgt siz)) (if (not (= (.descent fnt) 2)) (snd-display #__line__ ";descent: ~A" (.descent fnt))) (if (not (= (.ascent fnt) 11)) (snd-display #__line__ ";ascent: ~A" (.ascent fnt))) (if (not (XCharStruct? (.per_char fnt))) (snd-display #__line__ ";per_char: ~A" (.per_char fnt))) (if (not (XCharStruct? (.max_bounds fnt))) (snd-display #__line__ ";max_bounds: ~A" (.max_bounds fnt))) (if (not (XCharStruct? (.min_bounds fnt))) (snd-display #__line__ ";min_bounds: ~A" (.min_bounds fnt))) (if (not (XFontProp? (car (.properties fnt)))) (snd-display #__line__ ";properties ~A" (.properties fnt))) (if (not (= (.card32 (car (.properties fnt))) 7)) (snd-display #__line__ ";card32: ~A" (.card32 (car (.properties fnt))))))) (XFreeFontSet dpy fs)))) (XBell dpy 10) (let ((cmd (XGetCommand dpy win))) (if (or (<= (length cmd) 0) (not (string=? (substring (car cmd) (- (length (car cmd)) 3)) "snd"))) (snd-display #__line__ ";XGetCommand: ~A" cmd))) (XSetCommand dpy win (list "hiho" "away") 2) (if (not (equal? (XGetCommand dpy win) (list "hiho" "away"))) (snd-display #__line__ ";XSetCommand: ~A" (XGetCommand dpy win))) (let ((wmp (map (lambda (w) (XGetAtomName dpy w)) (XGetWMProtocols dpy win)))) (if (not (equal? wmp (list "_MOTIF_WM_MESSAGES" "WM_DELETE_WINDOW"))) (snd-display #__line__ ";XGetWMProtocols: ~A" wmp))) (if (not (equal? (XListDepths dpy 0) (list 24 1 4 8 15 16 32))) (snd-display #__line__ ";XListDepths: ~A" (XListDepths dpy 0))) (if (not (equal? (XListPixmapFormats dpy) '((1 1 32) (4 8 32) (8 8 32) (15 16 32) (16 16 32) (24 32 32) (32 32 32)))) (snd-display #__line__ ";XListPixmapFormats: ~A" (XListPixmapFormats dpy))) (XWarpPointer dpy (list 'Window None) (list 'Window None) 0 0 10 10 100 100) (let ((cs (XQueryBestCursor dpy win 10 10))) (if (not (equal? cs (list 1 10 10))) (snd-display #__line__ ";XQueryBestCursor: ~A" cs))) (let ((pt (XQueryPointer dpy win))) (if (not (Window? (cadr pt))) (snd-display #__line__ ";XQueryPointer: ~A" pt))) (XRaiseWindow dpy win) (XRotateBuffers dpy 1) (XSetWindowBorderWidth dpy win 10) (XSetWindowBorder dpy win (black-pixel)) (XSetWindowBackground dpy win *basic-color*) (let* ((vis (XGetVisualInfo dpy 0 (list 'XVisualInfo 0))) (depth (.depth (car vis)))) (XSetWindowBorderPixmap dpy win (XCreatePixmap dpy win 10 10 depth)) (XSetWindowBackgroundPixmap dpy win (XCreatePixmap dpy win 10 10 depth)) (XSetWindowBorderPixmap dpy win CopyFromParent) (XSetWindowBackgroundPixmap dpy win ParentRelative) ;(segfault) (XFree (cadr vis)) ) (let ((hints (XGetWMHints dpy win))) (if (or (not hints) (not (XWMHints? hints))) (snd-display #__line__ ";XGetWMHints?")) (if (not (= (.flags hints) 7)) (snd-display #__line__ ";flags wmhints: ~A" (.flags hints))) (if (not (= (.initial_state hints) 1)) (snd-display #__line__ ";initial_state wmhints: ~A" (.initial_state hints))) (if (not (.input hints)) (snd-display #__line__ ";input wmhints: ~A" (.input hints))) (if (not (Pixmap? (.icon_pixmap hints))) (snd-display #__line__ ";icon_pixmap wmhints: ~A" (.icon_pixmap hints))) (if (.icon_window hints) (snd-display #__line__ ";icon_window: ~A" (.icon_window hints))) (if (not (equal? (.icon_mask hints) (list 'Pixmap 0))) (snd-display #__line__ ";icon_mask: ~A" (.icon_mask hints))) (if (not (number? (.window_group hints))) (snd-display #__line__ ";window_group: ~A" (.window_group hints))) (XtFree (cadr hints)) (let ((st (XAllocWMHints))) (if (not (XWMHints? st)) (snd-display #__line__ ";XAllocWMHints: ~A" st)) (XFree st)))) (if (not (IsKeypadKey (list 'KeySym XK_KP_Space))) (snd-display #__line__ ";IsKeypadKey kp-space")) (if (IsKeypadKey (list 'KeySym XK_A)) (snd-display #__line__ ";IsKeypadKey A")) (if (IsPrivateKeypadKey (list 'KeySym XK_A)) (snd-display #__line__ ";IsPrivateKeypadKey A")) (if (not (IsCursorKey (list 'KeySym XK_Home))) (snd-display #__line__ ";IsCursorKey Home")) (if (IsCursorKey (list 'KeySym XK_S)) (snd-display #__line__ ";IsCursorKey S")) (if (not (IsPFKey (list 'KeySym XK_KP_F1))) (snd-display #__line__ ";IsPFKey F1")) (if (IsPFKey (list 'KeySym XK_S)) (snd-display #__line__ ";IsPFKey S")) (if (not (IsFunctionKey (list 'KeySym XK_F1))) (snd-display #__line__ ";IsFunctionKey F1")) (if (IsFunctionKey (list 'KeySym XK_S)) (snd-display #__line__ ";IsFunctionKey S")) (if (not (IsMiscFunctionKey (list 'KeySym XK_Select))) (snd-display #__line__ ";IsMiscFunctionKey Select")) (if (IsMiscFunctionKey (list 'KeySym XK_S)) (snd-display #__line__ ";IsMiscFunctionKey S")) (if (not (IsModifierKey (list 'KeySym XK_Shift_L))) (snd-display #__line__ ";IsModifierKey Shift")) (if (IsModifierKey (list 'KeySym XK_S)) (snd-display #__line__ ";IsModifierKey S")) (let (;(scr (current-screen)) (dpy (XtDisplay (cadr (main-widgets)))) (val (XGCValues)) (wn (XtWindow (cadr (main-widgets))))) (set! (.function val) GXclear) (if (not (equal? (.function val) GXclear)) (snd-display #__line__ ";function: ~A ~A" (.function val) GXclear)) (set! (.line_width val) 10) (if (not (eqv? (.line_width val) 10)) (snd-display #__line__ ";line_width: ~A ~A" (.line_width val) 10)) (set! (.line_style val) LineSolid) (if (not (equal? (.line_style val) LineSolid)) (snd-display #__line__ ";line_style: ~A ~A" (.line_style val) LineSolid)) (set! (.background val) (WhitePixelOfScreen (current-screen))) (if (not (equal? (.background val) (WhitePixelOfScreen (current-screen)))) (snd-display #__line__ ";background: ~A ~A" (.background val) (WhitePixelOfScreen (current-screen)))) (set! (.foreground val) (BlackPixelOfScreen (current-screen))) (if (not (equal? (.foreground val) (BlackPixelOfScreen (current-screen)))) (snd-display #__line__ ";foreground: ~A ~A" (.foreground val) (BlackPixelOfScreen (current-screen)))) ;; plane_mask? (set! (.cap_style val) CapRound) (if (not (equal? (.cap_style val) CapRound)) (snd-display #__line__ ";cap_style: ~A ~A" (.cap_style val) CapRound)) (set! (.join_style val) JoinMiter) (if (not (equal? (.join_style val) JoinMiter)) (snd-display #__line__ ";join_style: ~A ~A" (.join_style val) JoinMiter)) (set! (.fill_style val) FillSolid) (if (not (equal? (.fill_style val) FillSolid)) (snd-display #__line__ ";fill_style: ~A ~A" (.fill_style val) FillSolid)) (set! (.fill_rule val) EvenOddRule) (if (not (equal? (.fill_rule val) EvenOddRule)) (snd-display #__line__ ";fill_rule: ~A ~A" (.fill_rule val) EvenOddRule)) (set! (.arc_mode val) ArcChord) (if (not (equal? (.arc_mode val) ArcChord)) (snd-display #__line__ ";arc_mode: ~A ~A" (.arc_mode val) ArcChord)) ;; tile stipple clip_mask are Pixmaps (set! (.ts_x_origin val) 1) (if (not (eqv? (.ts_x_origin val) 1)) (snd-display #__line__ ";ts_x_origin: ~A ~A" (.ts_x_origin val) 1)) (set! (.ts_y_origin val) 1) (if (not (eqv? (.ts_y_origin val) 1)) (snd-display #__line__ ";ts_y_origin: ~A ~A" (.ts_y_origin val) 1)) ;; font is Font (set! (.subwindow_mode val) ClipByChildren) (if (not (equal? (.subwindow_mode val) ClipByChildren)) (snd-display #__line__ ";subwindow_mode: ~A ~A" (.subwindow_mode val) ClipByChildren)) (set! (.graphics_exposures val) #f) (if (.graphics_exposures val) (snd-display #__line__ ";graphics_exposures: ~A ~A" (.graphics_exposures val) #f)) (set! (.clip_x_origin val) 0) (if (not (eqv? (.clip_x_origin val) 0)) (snd-display #__line__ ";clip_x_origin: ~A ~A" (.clip_x_origin val) 0)) (set! (.clip_y_origin val) 0) (if (not (eqv? (.clip_y_origin val) 0)) (snd-display #__line__ ";clip_y_origin: ~A ~A" (.clip_y_origin val) 0)) (set! (.dash_offset val) 1) (if (not (eqv? (.dash_offset val) 1)) (snd-display #__line__ ";dash_offset: ~A ~A" (.dash_offset val) 1)) (if (not (number? (XConnectionNumber dpy))) (snd-display #__line__ ";XConnectionNumber: ~A" (XConnectionNumber dpy))) (let ((sgc (XCreateGC dpy wn (+ GCFunction GCForeground GCBackground GCLineWidth GCLineStyle GCCapStyle GCJoinStyle GCFillStyle GCFillRule GCTileStipXOrigin GCTileStipYOrigin GCSubwindowMode GCGraphicsExposures GCClipXOrigin GCClipYOrigin GCDashOffset GCArcMode) val))) (if (not (GC? sgc)) (snd-display #__line__ ";XCreateGC returned ~A" sgc)) (XSetArcMode dpy sgc ArcPieSlice) (XSetFunction dpy sgc GXcopy) (XSetLineAttributes dpy sgc 3 LineDoubleDash CapButt JoinMiter) (XSetClipOrigin dpy sgc 1 1) (XSetTSOrigin dpy sgc 0 0) (XSetFillRule dpy sgc WindingRule) (XSetFillStyle dpy sgc FillStippled) (XSetForeground dpy sgc (WhitePixelOfScreen (current-screen))) (XSetBackground dpy sgc (BlackPixelOfScreen (current-screen))) (XSetGraphicsExposures dpy sgc #t) (XSetSubwindowMode dpy sgc IncludeInferiors) (let ((owner (XGetSelectionOwner dpy XA_PRIMARY))) (if (and owner (not (Window? owner))) (snd-display #__line__ ";XGetSelectionOwner: ~A" owner))) (let ((mods (XGetModifierMapping dpy))) (if (not (XModifierKeymap? mods)) (snd-display #__line__ ";XGetModifierMapping: ~A" mods))) (let ((vis (XGetVisualInfo dpy 0 (list 'XVisualInfo 0)))) (if (or (not vis) (not (XVisualInfo? (car vis)))) (snd-display #__line__ ";XGetVisualInfo: ~A" vis)) (if (not (= (.depth (car vis)) 24)) (snd-display #__line__ ";depth vis: ~A" (.depth (car vis)))) (if (not (= (.screen (car vis)) 0)) (snd-display #__line__ ";screen vis: ~A" (.screen (car vis)))) (catch #t ; in c++ no class field (lambda () (if (not (= (.class (car vis)) TrueColor)) (snd-display #__line__ ";class vis: ~A (~A)" (.class (car vis)) TrueColor))) (lambda args args)) (if (not (= (.colormap_size (car vis)) 256)) (snd-display #__line__ ";colormap_size vis: ~A" (.colormap_size (car vis)))) (if (and (not (XVisualInfo? (XMatchVisualInfo dpy 0 24 TrueColor))) (not (XVisualInfo? (XMatchVisualInfo dpy 0 16 TrueColor)))) (snd-display #__line__ ";XMatchVisualInfo: ~A" (XMatchVisualInfo dpy 0 24 TrueColor)))) (XCheckMaskEvent dpy KeyPressMask) (let* ((vals (XGetGCValues dpy sgc (+ GCFunction GCForeground GCBackground GCLineWidth GCLineStyle GCCapStyle GCJoinStyle GCFillStyle GCFillRule GCTileStipXOrigin GCTileStipYOrigin GCSubwindowMode GCGraphicsExposures GCClipXOrigin GCClipYOrigin GCDashOffset GCArcMode))) (val1 (cadr vals))) (if (= (car vals) 0) (snd-display #__line__ ";XGetGCValues failed")) (if (not (equal? (.function val1) GXcopy)) (snd-display #__line__ ";function: ~A ~A" (.function val1) GXcopy)) (if (not (eqv? (.line_width val1) 3)) (snd-display #__line__ ";line_width: ~A ~A" (.line_width val1) 3)) (if (not (equal? (.line_style val1) LineDoubleDash)) (snd-display #__line__ ";line_style: ~A ~A" (.line_style val1) LineDoubleDash)) (if (not (equal? (.background val1) (BlackPixelOfScreen (current-screen)))) (snd-display #__line__ ";background: ~A ~A" (.background val1) (BlackPixelOfScreen (current-screen)))) (if (not (equal? (.foreground val1) (WhitePixelOfScreen (current-screen)))) (snd-display #__line__ ";foreground: ~A ~A" (.foreground val1) (WhitePixelOfScreen (current-screen)))) (if (not (equal? (.cap_style val1) CapButt)) (snd-display #__line__ ";cap_style: ~A ~A" (.cap_style val1) CapButt)) (if (not (equal? (.join_style val1) JoinMiter)) (snd-display #__line__ ";join_style: ~A ~A" (.join_style val1) JoinMiter)) (if (not (equal? (.fill_style val1) FillStippled)) (snd-display #__line__ ";fill_style: ~A ~A" (.fill_style val1) FillStippled)) (if (not (equal? (.fill_rule val1) WindingRule)) (snd-display #__line__ ";fill_rule: ~A ~A" (.fill_rule val1) WindingRule)) (if (not (equal? (.arc_mode val1) ArcPieSlice)) (snd-display #__line__ ";arc_mode: ~A ~A" (.arc_mode val1) ArcPieSlice)) (if (not (eqv? (.ts_x_origin val1) 0)) (snd-display #__line__ ";ts_x_origin: ~A ~A" (.ts_x_origin val1) 0)) (if (not (eqv? (.ts_y_origin val1) 0)) (snd-display #__line__ ";ts_y_origin: ~A ~A" (.ts_y_origin val1) 0)) (if (not (equal? (.subwindow_mode val1) IncludeInferiors)) (snd-display #__line__ ";subwindow_mode: ~A ~A" (.subwindow_mode val1) IncludeInferiors)) (if (not (.graphics_exposures val1)) (snd-display #__line__ ";graphics_exposures: ~A ~A" (.graphics_exposures val1) #t)) (if (not (eqv? (.clip_x_origin val1) 1)) (snd-display #__line__ ";clip_x_origin: ~A ~A" (.clip_x_origin val1) 1)) (if (not (eqv? (.clip_y_origin val1) 1)) (snd-display #__line__ ";clip_y_origin: ~A ~A" (.clip_y_origin val1) 1)) (if (not (eqv? (.dash_offset val1) 1)) (snd-display #__line__ ";dash_offset: ~A ~A" (.dash_offset val1) 1)) (set! (.plane_mask val) 0) (if (not (eqv? (.plane_mask val) 0)) (snd-display #__line__ ";plane_mask: ~A ~A" (.plane_mask val) 0)) (set! (.tile val) (list 'Pixmap 0)) (if (not (equal? (.tile val) (list 'Pixmap 0))) (snd-display #__line__ ";tile: ~A" (.tile val))) (set! (.stipple val) (list 'Pixmap 0)) (if (not (equal? (.stipple val) (list 'Pixmap 0))) (snd-display #__line__ ";stipple: ~A" (.stipple val))) (let* ((dpy (XtDisplay (cadr (main-widgets)))) (win (XtWindow (cadr (main-widgets)))) (attr (XSetWindowAttributes #f *basic-color* #f *highlight-color*)) (newwin (XCreateWindow dpy win 10 10 100 100 3 CopyFromParent InputOutput (list 'Visual CopyFromParent) (logior CWBackPixel CWBorderPixel) attr))) (if (not (= (.do_not_propagate_mask attr) 0)) (snd-display #__line__ ";do_not_propagate_mask: ~A" (.do_not_propagate_mask attr))) (if (not (= (.event_mask attr) 0)) (snd-display #__line__ ";event_mask: ~A" (.event_mask attr))) (if (not (Pixel? (.backing_pixel attr))) (snd-display #__line__ ";backing_pixel: ~A" (.backing_pixel attr))) (if (not (Pixel? (.border_pixel attr))) (snd-display #__line__ ";border_pixel: ~A" (.border_pixel attr))) (if (not (= (cadr (.border_pixmap attr)) 0)) (snd-display #__line__ ";border_pixmap: ~A" (.border_pixmap attr))) (if (not (Pixel? (.background_pixel attr))) (snd-display #__line__ ";background_pixel: ~A" (.background_pixel attr))) (if (not (= (cadr (.background_pixmap attr)) 0)) (snd-display #__line__ ";background_pixmap: ~A" (.background_pixmap attr))) (if (not (= (.backing_planes attr) 0)) (snd-display #__line__ ";backing_planes: ~A" (.backing_planes attr))) (if (.save_under attr) (snd-display #__line__ ";save_under: ~A" (.save_under attr))) (if (not (= (cadr (.cursor attr)) 0)) (snd-display #__line__ ";cursor: ~A" (.cursor attr))) (if (not (Window? newwin)) (snd-display #__line__ ";XCreateWindow: ~A" newwin)) (if (not (= (.bit_gravity attr) 0)) (snd-display #__line__ ";bit_gravity: ~A" (.bit_gravity attr))) (XChangeWindowAttributes dpy newwin CWBackPixel (XSetWindowAttributes #f *basic-color*)) (XDestroyWindow dpy newwin) (set! newwin (XCreateSimpleWindow dpy win 10 10 100 100 3 *basic-color* *highlight-color*)) (XDestroyWindow dpy newwin)) (XSetRegion dpy sgc (XPolygonRegion (list (XPoint 0 0) (XPoint 10 0) (XPoint 10 10) (XPoint 0 10)) 4 WindingRule)) (let ((pix (make-pixmap (cadr (main-widgets)) arrow-strs))) (if (not (Pixmap? pix)) (snd-display #__line__ ";make-pixmap?") (begin (XSetTile dpy sgc pix) (XSetStipple dpy sgc (XCreateBitmapFromData dpy wn right-arrow 16 12)) (XSetClipMask dpy sgc None) (XSetState dpy sgc *basic-color* *mark-color* GXcopy 0) (XSetPlaneMask dpy sgc 0) (XSetDashes dpy sgc 0 '(3 4 3 1)) (XSetClipRectangles dpy sgc 0 0 (list (XRectangle 0 0 10 10) (XRectangle 10 10 100 100)) 2 Unsorted) (let ((err (XWriteBitmapFile dpy "testx.data" pix 16 12 -1 -1))) (if (not (= BitmapSuccess err)) (snd-display #__line__ ";XWriteBitmapFile: ~A" err))) ;(let ((vals (XReadBitmapFile dpy (XtWindow (cadr (main-widgets))) "testx.data"))) ; (if (not (= (car vals BitmapSuccess))) (snd-display #__line__ ";XReadBitmapFile: ~A" vals))) ;(let ((vals (XReadBitmapFileData "testx.data"))) ; (if (not (= (car vals BitmapSuccess))) (snd-display #__line__ ";XReadBitmapFileData: ~A" vals))) (let* ((fid (XLoadFont dpy "cursor")) (col (XColor)) (col1 (XColor)) (scr (DefaultScreen dpy)) (cmap (DefaultColormap dpy scr))) (XAllocNamedColor dpy cmap "blue" col col) (XAllocNamedColor dpy cmap "green" col1 col1) (let ((vals (XCreateGlyphCursor dpy fid None XC_dot 0 col col1))) (if (not (Cursor? vals)) (snd-display #__line__ ";XCreateGlyphCursor: ~A" vals))) (let ((vals (XCreatePixmapCursor dpy pix None col col1 5 5))) (if (not (Cursor? vals)) (snd-display #__line__ ";XCreatePixmapCursor: ~A" vals)) (XRecolorCursor dpy vals col1 col)) (XAllocColorPlanes dpy cmap #f 2 1 1 1) (XAllocColorCells dpy cmap #f 1 1)) ))) (let* ((fid (XLoadFont dpy "-*-times-medium-r-*-*-14-*-*-*-*-*-*-*")) (fnt (XLoadQueryFont dpy "-*-times-medium-r-*-*-14-*-*-*-*-*-*-*")) (chs (XQueryTextExtents dpy fid "hiho")) (struct (chs 4)) (fnt1 (XQueryFont dpy fid))) (if (not (Font? fid)) (snd-display #__line__ ";XLoadFont: ~A" fid)) (if (not (XFontStruct? fnt)) (snd-display #__line__ ";XLoadQueryFont: ~A" fnt)) (if (not (XFontStruct? fnt1)) (snd-display #__line__ ";XQueryFont: ~A" fnt1)) (if (not (XCharStruct? struct)) (snd-display #__line__ ";XQueryTextExtents: ~A" chs)) (if (not (= (chs 2) 12)) (snd-display #__line__ ";XQueryTextExtents max ascent: ~A" (chs 2))) (if (not (= (chs 3) 3)) (snd-display #__line__ ";XQueryTextExtents max descent: ~A" (chs 3))) (if (not (= (.lbearing struct) 0)) (snd-display #__line__ ";lbearing: ~A" (.lbearing struct))) (if (not (= (.rbearing struct) 23)) (snd-display #__line__ ";rbearing: ~A" (.rbearing struct))) (if (not (= (.width struct) 24)) (snd-display #__line__ ";width: ~A" (.width struct))) (if (not (= (.ascent struct) 10)) (snd-display #__line__ ";ascent: ~A" (.ascent struct))) (if (not (= (.descent struct) 0)) (snd-display #__line__ ";descent: ~A" (.descent struct))) (if (not (= (.attributes struct) 0)) (snd-display #__line__ ";attributes: ~A" (.attributes struct))) (let ((fid (load-font "-*-helvetica-bold-r-*-*-14-*-*-*-*-*-*-*"))) (if (not (Font? fid)) (snd-display #__line__ ";load-font -> ~A" fid))) ) (XFreeGC (XtDisplay (cadr (main-widgets))) sgc) ))) (let ((atoms (list XA_PRIMARY XA_SECONDARY XA_ARC XA_ATOM XA_BITMAP XA_CARDINAL XA_COLORMAP XA_CURSOR XA_CUT_BUFFER0 XA_CUT_BUFFER1 XA_CUT_BUFFER2 XA_CUT_BUFFER3 XA_CUT_BUFFER4 XA_CUT_BUFFER5 XA_CUT_BUFFER6 XA_CUT_BUFFER7 XA_DRAWABLE XA_FONT XA_INTEGER XA_PIXMAP XA_POINT XA_RECTANGLE XA_RESOURCE_MANAGER XA_RGB_COLOR_MAP XA_RGB_BEST_MAP XA_RGB_BLUE_MAP XA_RGB_DEFAULT_MAP XA_RGB_GRAY_MAP XA_RGB_GREEN_MAP XA_RGB_RED_MAP XA_STRING XA_VISUALID XA_WINDOW XA_WM_COMMAND XA_WM_HINTS XA_WM_CLIENT_MACHINE XA_WM_ICON_NAME XA_WM_ICON_SIZE XA_WM_NAME XA_WM_NORMAL_HINTS XA_WM_SIZE_HINTS XA_WM_ZOOM_HINTS XA_MIN_SPACE XA_NORM_SPACE XA_MAX_SPACE XA_END_SPACE XA_SUPERSCRIPT_X XA_SUPERSCRIPT_Y XA_SUBSCRIPT_X XA_SUBSCRIPT_Y XA_UNDERLINE_POSITION XA_UNDERLINE_THICKNESS XA_STRIKEOUT_ASCENT XA_STRIKEOUT_DESCENT XA_ITALIC_ANGLE XA_X_HEIGHT XA_QUAD_WIDTH XA_WEIGHT XA_POINT_SIZE XA_RESOLUTION XA_COPYRIGHT XA_NOTICE XA_FONT_NAME XA_FAMILY_NAME XA_FULL_NAME XA_CAP_HEIGHT XA_WM_CLASS XA_WM_TRANSIENT_FOR)) (atom-names (list 'XA_PRIMARY 'XA_SECONDARY 'XA_ARC 'XA_ATOM 'XA_BITMAP 'XA_CARDINAL 'XA_COLORMAP 'XA_CURSOR 'XA_CUT_BUFFER0 'XA_CUT_BUFFER1 'XA_CUT_BUFFER2 'XA_CUT_BUFFER3 'XA_CUT_BUFFER4 'XA_CUT_BUFFER5 'XA_CUT_BUFFER6 'XA_CUT_BUFFER7 'XA_DRAWABLE 'XA_FONT 'XA_INTEGER 'XA_PIXMAP 'XA_POINT 'XA_RECTANGLE 'XA_RESOURCE_MANAGER 'XA_RGB_COLOR_MAP 'XA_RGB_BEST_MAP 'XA_RGB_BLUE_MAP 'XA_RGB_DEFAULT_MAP 'XA_RGB_GRAY_MAP 'XA_RGB_GREEN_MAP 'XA_RGB_RED_MAP 'XA_STRING 'XA_VISUALID 'XA_WINDOW 'XA_WM_COMMAND 'XA_WM_HINTS 'XA_WM_CLIENT_MACHINE 'XA_WM_ICON_NAME 'XA_WM_ICON_SIZE 'XA_WM_NAME 'XA_WM_NORMAL_HINTS 'XA_WM_SIZE_HINTS 'XA_WM_ZOOM_HINTS 'XA_MIN_SPACE 'XA_NORM_SPACE 'XA_MAX_SPACE 'XA_END_SPACE 'XA_SUPERSCRIPT_X 'XA_SUPERSCRIPT_Y 'XA_SUBSCRIPT_X 'XA_SUBSCRIPT_Y 'XA_UNDERLINE_POSITION 'XA_UNDERLINE_THICKNESS 'XA_STRIKEOUT_ASCENT 'XA_STRIKEOUT_DESCENT 'XA_ITALIC_ANGLE 'XA_X_HEIGHT 'XA_QUAD_WIDTH 'XA_WEIGHT 'XA_POINT_SIZE 'XA_RESOLUTION 'XA_COPYRIGHT 'XA_NOTICE 'XA_FONT_NAME 'XA_FAMILY_NAME 'XA_FULL_NAME 'XA_CAP_HEIGHT 'XA_WM_CLASS 'XA_WM_TRANSIENT_FOR))) (for-each (lambda (n name) (if (not (Atom? n)) (snd-display #__line__ ";Atom: ~A -> ~A" name (Atom? n)))) atoms atom-names)) (let ((r (XRectangle 10 20 100 110))) (if (not (= (.width r) 100)) (snd-display #__line__ ";XRectangle width: ~A" (.width r))) (if (not (= (.height r) 110)) (snd-display #__line__ ";XRectangle height: ~A" (.height r))) (if (not (= (.x r) 10)) (snd-display #__line__ ";XRectangle x: ~A" (.x r))) (if (not (= (.y r) 20)) (snd-display #__line__ ";XRectangle y: ~A" (.y r))) (set! (.width r) 10) (if (not (= (.width r) 10)) (snd-display #__line__ ";set XRectangle width: ~A" (.width r))) (set! (.height r) 11) (if (not (= (.height r) 11)) (snd-display #__line__ ";set XRectangle height: ~A" (.height r))) (set! (.x r) 1) (if (not (= (.x r) 1)) (snd-display #__line__ ";set XRectangle x: ~A" (.x r))) (set! (.y r) 2) (if (not (= (.y r) 2)) (snd-display #__line__ ";XRectangle y: ~A" (.y r)))) (let ((r (XArc 10 20 100 110 0 235))) (if (not (= (.width r) 100)) (snd-display #__line__ ";XArc width: ~A" (.width r))) (if (not (= (.height r) 110)) (snd-display #__line__ ";XArc height: ~A" (.height r))) (if (not (= (.x r) 10)) (snd-display #__line__ ";XArc x: ~A" (.x r))) (if (not (= (.y r) 20)) (snd-display #__line__ ";XArc y: ~A" (.y r))) (if (not (= (.angle1 r) 0)) (snd-display #__line__ ";XArc angle1: ~A" (.angle1 r))) (if (not (= (.angle2 r) 235)) (snd-display #__line__ ";XArc angle2: ~A" (.angle2 r))) (set! (.width r) 10) (if (not (= (.width r) 10)) (snd-display #__line__ ";set XArc width: ~A" (.width r))) (set! (.height r) 11) (if (not (= (.height r) 11)) (snd-display #__line__ ";set XArc height: ~A" (.height r))) (set! (.x r) 1) (if (not (= (.x r) 1)) (snd-display #__line__ ";set XArc x: ~A" (.x r))) (set! (.y r) 2) (if (not (= (.y r) 2)) (snd-display #__line__ ";set XArc y: ~A" (.y r))) (set! (.angle1 r) 123) (if (not (= (.angle1 r) 123)) (snd-display #__line__ ";set XArc angle1: ~A" (.angle1 r))) (set! (.angle2 r) 321) (if (not (= (.angle2 r) 321)) (snd-display #__line__ ";set XArc angle2: ~A" (.angle2 r)))) (let ((r (XPoint 10 20))) (if (not (= (.x r) 10)) (snd-display #__line__ ";XPoint x: ~A" (.x r))) (if (not (= (.y r) 20)) (snd-display #__line__ ";XPoint y: ~A" (.y r))) (set! (.x r) 1) (if (not (= (.x r) 1)) (snd-display #__line__ ";set XPoint x: ~A" (.x r))) (set! (.y r) 2) (if (not (= (.y r) 2)) (snd-display #__line__ ";set XPoint y: ~A" (.y r)))) (let ((r (XSegment 10 20 100 110))) (if (not (= (.x1 r) 10)) (snd-display #__line__ ";XSegment x1: ~A" (.x1 r))) (if (not (= (.y1 r) 20)) (snd-display #__line__ ";XSegment y1: ~A" (.y1 r))) (if (not (= (.x2 r) 100)) (snd-display #__line__ ";XSegment x2: ~A" (.x2 r))) (if (not (= (.y2 r) 110)) (snd-display #__line__ ";XSegment y2: ~A" (.y2 r))) (set! (.x1 r) 1) (if (not (= (.x1 r) 1)) (snd-display #__line__ ";set XSegment x1: ~A" (.x1 r))) (set! (.y1 r) 2) (if (not (= (.y1 r) 2)) (snd-display #__line__ ";set XSegment y1: ~A" (.y1 r))) (set! (.x2 r) 10) (if (not (= (.x2 r) 10)) (snd-display #__line__ ";set XSegment x2: ~A" (.x2 r))) (set! (.y2 r) 11) (if (not (= (.y2 r) 11)) (snd-display #__line__ ";set XSegment y2: ~A" (.y2 r)))) (let ((c (XColor))) (set! (.red c) 1) (if (not (= (.red c) 1)) (snd-display #__line__ ";Xcolor red: ~A" (.red c))) (set! (.green c) 1) (if (not (= (.green c) 1)) (snd-display #__line__ ";Xcolor green: ~A" (.green c))) (set! (.blue c) 1) (if (not (= (.blue c) 1)) (snd-display #__line__ ";Xcolor blue: ~A" (.blue c))) (set! (.flags c) DoRed) (if (not (= (.flags c) DoRed)) (snd-display #__line__ ";Xcolor flags: ~A" (.flags c))) (if (not (= (.pad c) 0)) (snd-display #__line__ ";pad: ~A" (.pad c))) (set! (.pixel c) *basic-color*) (if (not (equal? (.pixel c) *basic-color*)) (snd-display #__line__ ";Xcolor pixel: ~A" (.pixel c)))) (let ((obj (XTextItem "hiho" 4 3 (list 'Font 1)))) (if (not (XTextItem? obj)) (snd-display #__line__ ";XTextItem -> ~A" obj)) (if (not (equal? (.font obj) (list 'Font 1))) (snd-display #__line__ ";font ~A" (.font obj))) (set! (.font obj) (list 'Font 2)) (if (not (equal? (.font obj) (list 'Font 2))) (snd-display #__line__ ";set font ~A" (.font obj))) (if (not (string=? (.chars obj) "hiho")) (snd-display #__line__ ";chars: ~A" (.chars obj))) (if (not (= (.nchars obj) 4)) (snd-display #__line__ ";chars: ~A" (.nchars obj))) (set! (.chars obj) "away!") (set! (.nchars obj) 5) (if (not (string=? (.chars obj) "away!")) (snd-display #__line__ ";set chars: ~A" (.chars obj))) (if (not (= (.nchars obj) 5)) (snd-display #__line__ ";set chars: ~A" (.nchars obj))) (if (not (= (.delta obj) 3)) (snd-display #__line__ ";delta ~A" (.delta obj))) (set! (.delta obj) 4) (if (not (= (.delta obj) 4)) (snd-display #__line__ ";set delta ~A" (.delta obj))) ) (let ((reg (XPolygonRegion (list (XPoint 0 0) (XPoint 10 0) (XPoint 10 10) (XPoint 0 10)) 4 WindingRule))) (if (not (XPointInRegion reg 4 4)) (snd-display #__line__ ";XPointInRegion")) (XShrinkRegion reg 1 2) (if (not (XPointInRegion reg 4 7)) (snd-display #__line__ ";t XShrinkRegion")) (if (XPointInRegion reg 4 9) (snd-display #__line__ ";f XShrinkRegion")) (XOffsetRegion reg 1 2) (if (not (XPointInRegion reg 4 9)) (snd-display #__line__ ";t XOffsetRegion")) (if (XPointInRegion reg 1 9) (snd-display #__line__ ";f XOffsetRegion")) (let ((reg2 (XCreateRegion)) (reg1 (XPolygonRegion (list (XPoint 2 2) (XPoint 10 2) (XPoint 10 10) (XPoint 2 10)) 4 WindingRule))) (if (XEqualRegion reg reg1) (snd-display #__line__ ";f XEqualRegion")) (if (XEmptyRegion reg) (snd-display #__line__ ";f XEmptyRegion")) (XXorRegion reg reg1 reg2) (let ((box (XClipBox reg2))) (if (or (not (= (.x (cadr box)) 2)) (not (= (.y (cadr box)) 2)) (not (= (.width (cadr box)) 8)) (not (= (.height (cadr box)) 2))) (snd-display #__line__ ";XXorRegion: ~A ~A ~A ~A" (.x (cadr box)) (.y (cadr box)) (.width (cadr box)) (.height (cadr box))))) (XUnionRegion reg reg1 reg2) (let ((box (XClipBox reg2))) (if (or (not (= (.x (cadr box)) 2)) (not (= (.y (cadr box)) 2)) (not (= (.width (cadr box)) 8)) (not (= (.height (cadr box)) 8))) (snd-display #__line__ ";XUnionRegion: ~A ~A ~A ~A" (.x (cadr box)) (.y (cadr box)) (.width (cadr box)) (.height (cadr box))))) (XSubtractRegion reg reg1 reg2) (let ((box (XClipBox reg2))) (if (or (not (= (.x (cadr box)) 0)) (not (= (.y (cadr box)) 0)) (not (= (.width (cadr box)) 0)) (not (= (.height (cadr box)) 0))) (snd-display #__line__ ";XSubtractRegion: ~A ~A ~A ~A" (.x (cadr box)) (.y (cadr box)) (.width (cadr box)) (.height (cadr box))))) (XIntersectRegion reg reg1 reg2) (let ((box (XClipBox reg2))) (if (or (not (= (.x (cadr box)) 2)) (not (= (.y (cadr box)) 4)) (not (= (.width (cadr box)) 8)) (not (= (.height (cadr box)) 6))) (snd-display #__line__ ";XIntersectRegion: ~A ~A ~A ~A" (.x (cadr box)) (.y (cadr box)) (.width (cadr box)) (.height (cadr box))))) (XUnionRectWithRegion (XRectangle 1 3 100 100) reg1 reg2) (let ((box (XClipBox reg2))) (if (or (not (= (.x (cadr box)) 1)) (not (= (.y (cadr box)) 2)) (not (= (.width (cadr box)) 100)) (not (= (.height (cadr box)) 101))) (snd-display #__line__ ";XUnionRectWithRegion: ~A ~A ~A ~A" (.x (cadr box)) (.y (cadr box)) (.width (cadr box)) (.height (cadr box))))) (XRectInRegion reg 0 0 100 100) (let ((box (XClipBox reg1))) (if (or (not (= (.x (cadr box)) 2)) (not (= (.y (cadr box)) 2)) (not (= (.width (cadr box)) 8)) (not (= (.height (cadr box)) 8))) (snd-display #__line__ ";XClipBox: ~A ~A ~A ~A" (.x (cadr box)) (.y (cadr box)) (.width (cadr box)) (.height (cadr box))))) (XDestroyRegion reg1) )) (let ((xid (XUniqueContext)) (dpy (XtDisplay (cadr (main-widgets))))) (if (not (eq? (car xid) 'XContext)) (snd-display #__line__ ";XUniqueContext: ~A" xid)) (XSaveContext dpy 123 xid "hiho") (let ((val (XFindContext dpy 123 xid))) (if (or (not (= 0 (car val))) (not (string=? (cadr val) "hiho"))) (snd-display #__line__ ";XFindContext: ~A" val))) (XDeleteContext dpy 123 xid) (XStoreBytes dpy "hiho" 4) (if (not (string=? (XFetchBytes dpy) "hiho")) (snd-display #__line__ ";XStoreBytes: ~A" (XFetchBytes dpy))) (XStoreBuffer dpy "hiho" 4 1) (if (not (string=? (XFetchBuffer dpy 1) "hiho")) (snd-display #__line__ ";XStoreBuffer: ~A" (XFetchBuffer dpy 1))) ) ;; ---------------- Xt tests ---------------- (let ((name (XtGetApplicationNameAndClass (XtDisplay (cadr (main-widgets)))))) (if (not (equal? name (list "snd" "Snd"))) (snd-display #__line__ ";XtGetApplicationNameAndClass: ~A?" name))) (let ((dpys (XtGetDisplays (car (main-widgets))))) (if (not (Display? (car dpys))) (snd-display #__line__ ";XtGetDisplays: ~A?" dpys))) (let ((app (XtDisplayToApplicationContext (XtDisplay (cadr (main-widgets))))) (orig (car (main-widgets))) (wid (XtWidgetToApplicationContext (cadr (main-widgets))))) (if (not (equal? app orig)) (snd-display #__line__ ";XtDisplayToApplicationContext: ~A ~A?" app orig)) (if (not (equal? app wid)) (snd-display #__line__ ";XtWidgetToApplicationContext: ~A ~A?" app wid))) (if (not (string=? (XtName (caddr (main-widgets))) "mainpane")) (snd-display #__line__ ";XtName main pane: ~A" (XtName (caddr (main-widgets))))) (if (not (= (XtGetMultiClickTime (XtDisplay (cadr (main-widgets)))) 200)) (snd-display #__line__ ";XtGetMultiClickTime: ~A" (XtGetMultiClickTime (XtDisplay (cadr (main-widgets)))))) (XtSetMultiClickTime (XtDisplay (cadr (main-widgets))) 250) (if (not (= (XtGetMultiClickTime (XtDisplay (cadr (main-widgets)))) 250)) (snd-display #__line__ ";XtSetMultiClickTime: ~A" (XtGetMultiClickTime (XtDisplay (cadr (main-widgets)))))) (XtGetResourceList xmListWidgetClass) (let ((wid1 (XtCreateWidget "wid1" xmPushButtonWidgetClass (cadr (main-widgets)) ()))) (XtDestroyWidget wid1)) (let ((hook-id (XtAppAddActionHook (car (main-widgets)) (lambda (w data name e p) (format #t "~A ~A ~A ~A ~A~%" w data name e p)) #f))) (XtRemoveActionHook hook-id)) (let* ((shell (cadr (main-widgets))) (wid (XtCreateWidget "wid" xmFormWidgetClass shell ())) (wid1 (XtCreateWidget "wid1" xmPushButtonWidgetClass wid ())) (wid2 (XtVaCreateWidget "wid" xmFormWidgetClass shell ()))) (if (XtIsApplicationShell wid) (snd-display #__line__ ";XtIsApplicationShell")) (if (not (XtIsApplicationShell shell)) (snd-display #__line__ ";XtIsApplicationShell of appshell")) (if (not (XtIsComposite wid)) (snd-display #__line__ ";XtIsComposite")) (if (not (XtIsConstraint wid)) (snd-display #__line__ ";XtIsConstraint")) (if (XtIsManaged wid) (snd-display #__line__ ";XtIsManaged")) (if (not (XtIsObject wid)) (snd-display #__line__ ";XtIsObject")) (if (XtIsOverrideShell wid) (snd-display #__line__ ";XtIsOverrideShell")) (if (XtIsRealized wid) (snd-display #__line__ ";XtIsRealized")) (if (not (XtIsRealized shell)) (snd-display #__line__ ";XtIsRealized main shell")) (if (not (XtIsRectObj wid)) (snd-display #__line__ ";XtIsRectObj")) (if (not (XtIsSensitive wid)) (snd-display #__line__ ";XtIsSensitive")) (if (not (XtIsSensitive shell)) (snd-display #__line__ ";XtIsSensitive of main shell")) (XtSetSensitive wid1 #t) (if (not (XtIsSensitive wid1)) (snd-display #__line__ ";XtIsSensitive of button")) (if (XtIsSessionShell wid) (snd-display #__line__ ";XtIsSessionShell")) (if (XtIsShell wid) (snd-display #__line__ ";XtIsShell")) (if (not (XtIsShell shell)) (snd-display #__line__ ";XtIsShell of main shell")) (if (XtIsTopLevelShell wid) (snd-display #__line__ ";XtIsTopLevelShell")) (if (not (XtIsTopLevelShell shell)) (snd-display #__line__ ";XtIsTopLevelShell of main shell")) (if (XtIsTransientShell wid) (snd-display #__line__ ";XtIsTransientShell")) (if (XtIsVendorShell wid) (snd-display #__line__ ";XtIsVendorShell")) (if (not (XtIsVendorShell shell)) (snd-display #__line__ ";XtIsVendorShell of main shell")) (if (XtIsWMShell wid) (snd-display #__line__ ";XtIsWMShell")) (if (not (XtIsWidget wid)) (snd-display #__line__ ";XtIsWidget")) (if (not (XtIsWidget wid2)) (snd-display #__line__ ";XtIsWidget 2")) (XtRealizeWidget wid) (if (not (XtIsRealized wid)) (snd-display #__line__ ";XtRealizeWidget?")) (XtAddGrab shell #f #f) (XtRemoveGrab shell) (XtMakeResizeRequest wid 200 200) (XtMapWidget wid) (XtUnmapWidget wid) (XtUnrealizeWidget wid) ;(XtDestroyWidget wid1) ) ; (XtFree 0) (XtCalloc 0 0) (XtMalloc 0) (XtRealloc 0 0) (XtSetLanguageProc (car (main-widgets)) (lambda (dpy str data) (snd-display #__line__ ";YOW: language proc: got ~A ~A" str data)) "who called us?") (XtSetLanguageProc (car (main-widgets)) #f "oops") (XtSetLanguageProc #f #f "oops") (XtMergeArgLists (list 1 2) 2 (list 1) 1) (let* ((shell (cadr (main-widgets))) (dpy (XtDisplay shell))) (if (not (equal? (XtClass shell) applicationShellWidgetClass)) (snd-display #__line__ ";XtClass shell: ~A" (XtClass shell))) (if (not (equal? (XtSuperclass shell) topLevelShellWidgetClass)) (snd-display #__line__ ";XtSuperclass shell: ~A" (XtClass shell))) (if (not (string=? (XtName shell) "snd")) (snd-display #__line__ ";XtName: ~A" (XtName shell))) (if (not (equal? (XtWindow shell) (XtWindowOfObject shell))) (snd-display #__line__ ";XtWindow: ~A ~A" (XtWindow shell) (XtWindowOfObject shell))) (if (not (equal? (XtScreen shell) (XtScreenOfObject shell))) (snd-display #__line__ ";XtScreen: ~A ~A" (XtScreen shell) (XtScreenOfObject shell))) (if (not (equal? (XtDisplay shell) (XtDisplayOfObject shell))) (snd-display #__line__ ";XtDisplay: ~A ~A" (XtDisplay shell) (XtDisplayOfObject shell))) (if (not (Time? (XtLastTimestampProcessed dpy))) (snd-display #__line__ ";XtLastTimestampProcessed: ~A" (XtLastTimestampProcessed dpy))) (if (not (XEvent? (XtLastEventProcessed dpy))) (snd-display #__line__ ";XtLastEventProcessed: ~A" (XtLastEventProcessed dpy))) (XtBuildEventMask shell) (let ((val 0)) (XtRegisterCaseConverter dpy (lambda (dp key) (set! val 123) (list (list 'KeySym 65) (list 'KeySym 97))) (list 'KeySym 65) (list 'KeySym 65)) (XtConvertCase dpy (list 'KeySym 65)) (if (not (= val 123)) (snd-display #__line__ ";XtRegisterCaseConverter: ~A" val))) (XtRegisterGrabAction (lambda (a b c) #f) #f ColormapChangeMask GrabModeSync GrabModeAsync) (let ((vals (XtTranslateKeycode dpy (list 'KeyCode XK_B) 0))) (if (or (not (= (car vals) 0)) (not (KeySym? (cadr vals)))) (snd-display #__line__ ";XtTranslateKeycode: ~A" vals)) (if (not (equal? vals (XtTranslateKey dpy (list 'KeyCode XK_B) 0))) (snd-display #__line__ ";XtTranslateKey: ~A ~A" vals (XtTranslateKey dpy (list 'KeyCode XK_B) 0))) (XtSetKeyTranslator dpy #f) (if (not (equal? vals (XtTranslateKeycode dpy (list 'KeyCode XK_B) 0))) (snd-display #__line__ ";XtSetKeyTranslator #f: ~A ~A" vals (XtTranslateKeycode dpy (list 'KeyCode XK_B) 0))) (XtSetKeyTranslator dpy (lambda (d k m) (if (not (equal? d dpy)) (snd-display #__line__ ";d in keyproc: ~A ~A" d dpy)) (XtTranslateKey d k m))) (let ((newvals (XtTranslateKeycode dpy (list 'KeyCode XK_B) 0))) (if (not (equal? vals newvals)) (snd-display #__line__ ";XtSetKeyTranslator: ~A ~A" vals newvals))) (XtSetKeyTranslator dpy #f)) (if (not (KeySym? (cadr (XmTranslateKey dpy (list 'KeyCode XK_B) 0)))) (snd-display #__line__ ";XmTranslateKey: ~A" (XmTranslateKey dpy XK_B 0))) (let ((kv (XtKeysymToKeycodeList dpy (list 'KeySym 65509)))) (if (not (equal? (car kv) (list 'KeyCode 66))) (snd-display #__line__ ";XtKeysymToKeycodeList: ~A ~A" kv (XtKeysymToKeycodeList dpy (list 'KeySym 65509))))) (XtInstallAllAccelerators (cadr (main-widgets)) (caddr (main-widgets))) (XtInstallAccelerators (cadr (main-widgets)) (caddr (main-widgets))) (if (not (equal? (list 0 1 2) (XtSetArg 0 1 2))) (snd-display #__line__ ";XtSetArg: ~A" (XtSetArg 0 1 2))) (if (not (Widget? (XtGetKeyboardFocusWidget (cadr (main-widgets))))) (snd-display #__line__ ";XtGetKeyboardFocusWidget: ~A" (XtGetKeyboardFocusWidget (cadr (main-widgets))))) (let ((id (XtAppAddInput (car (main-widgets)) 1 XtInputReadMask (lambda (a b c) #f) #f))) (XtRemoveInput id)) (let ((id (XtAppAddWorkProc (car (main-widgets)) (lambda (me) #f) #f))) (XtRemoveWorkProc id)) (if (not (equal? (caddr (main-widgets)) (XtNameToWidget (cadr (main-widgets)) "mainpane"))) (snd-display #__line__ ";XtNameToWidget: ~A ~A" (caddr (main-widgets)) (XtNameToWidget (cadr (main-widgets)) "mainpane"))) (XtVaCreatePopupShell "hiho" vendorShellWidgetClass (cadr (main-widgets)) ()) (XtResolvePathname (XtDisplay (cadr (main-widgets))) "app-defaults" #f #f #f #f 0 #f) (XtFindFile ".snd" #f 0 #f) (XtAppLock (car (main-widgets))) (XtAppUnlock (car (main-widgets))) (let ((acts (XtGetActionList xmLabelWidgetClass))) (if (or (not (= (length acts) 4)) (not (string=? (caar acts) "Enter"))) (snd-display #__line__ ";XtGetActionList: ~A" acts))) ) (let ((pop (XtCreatePopupShell "hiho" xmGrabShellWidgetClass (cadr (main-widgets)) (list XmNiconNameEncoding XA_STRING)))) (XtPopup pop XtGrabNone) (XtPopdown pop)) (XtAppSetWarningHandler (car (main-widgets)) (lambda (n) (if (not (string=? n "hiho")) (snd-display #__line__ ";XtWarning: ~A" n)))) (XtAppSetWarningMsgHandler (car (main-widgets)) (lambda (name type klass def pars num) (snd-display #__line__ ";ignore: ~A ~A ~A~%" name def pars))) (let ((listener ((main-widgets) 4))) (XtCallActionProc listener "text-transpose" (XEvent) #f 0) (XtCallActionProc listener "begin-of-line" (XEvent) #f 0) (XtCallActionProc listener "kill-line" (XEvent) #f 0) (XtCallActionProc listener "yank" (XEvent) #f 0) (XtCallActionProc listener "name-completion" (XEvent) #f 0) (XtCallActionProc listener "listener-completion" (XEvent) #f 0) (XtCallActionProc listener "no-op" (XEvent) #f 0) (XtCallActionProc listener "delete-region" (XEvent) #f 0) (XtCallActionProc listener "listener-g" (XEvent) #f 0) (XtCallActionProc listener "listener-clear" (XEvent) #f 0) (XtCallActionProc listener "b1-press" (XEvent) #f 0) (XtCallActionProc listener "delete-to-previous-command" (XEvent) #f 0) (let ((BEvent (XEvent ButtonPress))) (set! (.x BEvent) 10) (set! (.y BEvent) 10) (XtCallActionProc listener "b1-press" BEvent #f 0) (XtCallActionProc listener "b1-release" BEvent #f 0)) (XtCallActionProc listener "word-upper" (XEvent) (list "u") 1)) (let ((ind (open-sound "oboe.snd"))) (set! (show-controls ind) #t) (let* ((swids (sound-widgets ind)) (sctrls (swids 2)) (wh (widget-size sctrls))) (XtUnmanageChild sctrls) (set! (widget-size sctrls) (list (car wh) (* (cadr wh) 3))) (XtManageChild sctrls) (let ((tag (catch #t (lambda () (XtVaGetValues (car (sound-widgets)) (list "XmNpaneMaximum" 0))) (lambda args (car args))))) (if (not (eq? tag 'no-such-resource)) (snd-display #__line__ ";XtVaGetValues of incorrectly quoted resource name: ~A" tag))) ) (close-sound ind)) ;; ---------------- XM tests ---------------- (let* ((label-render-table (cadr (XtVaGetValues (cadr (main-widgets)) (list XmNlabelRenderTable 0)))) (renditions (and label-render-table (XmRenderTableGetRenditions label-render-table (XmRenderTableGetTags label-render-table)))) (default-font-name (and renditions (cadr (XmRenditionRetrieve (car renditions) (list XmNfontName 0))))) (default-font-info (and renditions (XmRenditionRetrieve (car renditions) (list XmNfont 0 XmNfontType 0))))) (if (not (string=? default-font-name "fixed")) (snd-display #__line__ ";XmRenderTableGetRenditions name: ~A" default-font-name)) (if (not (XFontStruct? (default-font-info 1))) (snd-display #__line__ ";XmRenderTableGetRenditions font struct: ~A" default-font-info)) (if (not (= (default-font-info 3) XmFONT_IS_FONT)) (snd-display #__line__ ";XmRenderTableGetRenditions font type: ~A" default-font-info))) (let* ((button-render-table (cadr (XtVaGetValues (cadr (main-widgets)) (list XmNbuttonRenderTable 0)))) (default-rendition (and button-render-table (XmRenderTableGetRendition button-render-table XmFONTLIST_DEFAULT_TAG))) (default-font-info (and default-rendition (XmRenditionRetrieve default-rendition (list XmNfont 0 XmNfontType 0))))) (if (and default-font-info (= (default-font-info 3) XmFONT_IS_FONT)) (let ((font (cadr default-font-info)) (dpy (XtDisplay (cadr (main-widgets)))) (data ())) (for-each (lambda (name atom?) (let ((val (XGetFontProperty font name))) (if (car val) (set! data (cons (list (XGetAtomName (XtDisplay (cadr (main-widgets))) name) (if atom? (XGetAtomName (XtDisplay (cadr (main-widgets))) (list 'Atom (cadr val))) (cadr val))) data))))) (list XA_POINT_SIZE XA_FONT XA_FULL_NAME (XInternAtom dpy "XA_SLANT" #f) (XInternAtom dpy "XA_WEIGHT_NAME" #f) XA_FAMILY_NAME (XInternAtom dpy "XA_FOUNDRY" #f) XA_CAP_HEIGHT) (list #f #t #t #t #t #t #t #f)) (if (not (string=? "Fixed" (cadr (data 1)))) (snd-display #__line__ ";XmRenderTableGetRendition: ~A" data))))) (let* ((tabs (let ((ctr 0)) (map (lambda (n) (set! ctr (+ ctr 1)) (XmTabCreate n XmINCHES (if (= ctr 1) XmABSOLUTE XmRELATIVE) XmALIGNMENT_BEGINNING ".")) (list 1.5 1.5 1.5 1.5)))) (tablist (XmTabListInsertTabs #f tabs (length tabs) 0))) (if (not (= (XmTabListTabCount tablist) (length tabs))) (snd-display #__line__ ";tablist len: ~A ~A~%" (XmTabListTabCount tablist) (length tabs))) (if (not (equal? (XmTabGetValues (XmTabListGetTab tablist 0)) (list 1.5 5 0 0 "."))) (snd-display #__line__ ";XmTabs 0: ~A" (XmTabGetValues (XmTabListGetTab tablist 0)))) (if (not (equal? (XmTabGetValues (XmTabListGetTab tablist 2)) (list 1.5 5 1 0 "."))) (snd-display #__line__ ";XmTabs 2: ~A" (XmTabGetValues (XmTabListGetTab tablist 2)))) (let ((copytab (XmTabListCopy tablist 0 0))) (if (not (equal? (XmTabGetValues (XmTabListGetTab copytab 0)) (list 1.5 5 0 0 "."))) (snd-display #__line__ ";XmTabListCopy 0: ~A" (XmTabGetValues (XmTabListGetTab copytab 0)))) (let ((another (XmTabListRemoveTabs copytab (list 0 1))) (atab (XmTabCreate 3.0 XmINCHES XmABSOLUTE XmALIGNMENT_BEGINNING "."))) (if (not (equal? (XmTabGetValues (XmTabListGetTab another 0)) (list 1.5 5 1 0 "."))) (snd-display #__line__ ";XmTabListRemoveTabs: ~A" (XmTabGetValues (XmTabListGetTab another 0)))) (XmTabListReplacePositions (XmTabListCopy tablist 0 0) (list 1) (list atab)) ;; this (replacepositions) is very prone to segfaults -- *very* poorly implemented! (XmTabSetValue atab 6.0) (XmTabFree atab) (XmTabListFree another)) (let ((tabl (XmStringTableProposeTablist (list (XmStringCreateLocalized "a-string") (XmStringCreateLocalized "another")) 2 (cadr (main-widgets)) 1.0 XmABSOLUTE))) (if (not (XmTabList? tabl)) (snd-display #__line__ ";XmStringTableProposeTabList: ~A" tabl)) (XmTabListFree tabl))) (let ((hname (host-name))) ; from snd-motif.scm (if (not (equal? hname (getenv "HOSTNAME"))) (snd-display #__line__ ";host name appears to be ~A or maybe ~A" hname (getenv "HOSTNAME")))) (let ((blu (x->snd-color "blue"))) (if (not (Pixel? blu)) (snd-display #__line__ ";x->snd-color can't find blue! ~A" blu)) (if (not (equal? (color->list blu) (list 0.0 0.0 1.0))) (snd-display #__line__ ";x->snd-color blue: ~A" (color->list blu)))) (let* ((tmp (XmStringCreateLocalized "h")) (pm (XmParseMappingCreate (list XmNincludeStatus XmINSERT XmNsubstitute tmp XmNpattern "i" XmNpatternType XmCHARSET_TEXT)))) (XmStringFree tmp) (XmParseMappingFree pm) (set! pm (XmParseMappingCreate (list XmNinvokeParseProc (lambda (txt end type tag entry pattern str call) #f)))) (XmParseMappingFree pm) (let ((tag (catch #t (lambda () (set! pm (XmParseMappingCreate (list XmNinvokeParseProc (lambda (txt end type tag entry pattern) #f))))) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";XmNinvokeParseProc wrong arity: ~A" tag)))) (let* ((fonts (list "fixed" "-*-times-bold-r-*-*-14-*-*-*-*-*-*-*" "-*-*-medium-i-*-*-18-*-*-*-*-*-*-*" "-*-helvetica-*-*-*-*-18-*-*-*-*-*-*-*")) (tags (list "one" "two" "three" "four")) (colors (list "red" "green" "blue" "orange")) (pixels (let* ((dpy (XtDisplay (cadr (main-widgets)))) (scr (DefaultScreen dpy)) (cmap (DefaultColormap dpy scr))) (let ((col (XColor))) (XParseColor dpy cmap "blue" col) (if (or (not (= (.red col) 0)) (not (= (.green col) 0)) (not (= (.blue col) 65535))) (snd-display #__line__ ";XParseColor: ~A ~A ~A ~A" col (.red col) (.blue col) (.green col))) (XLookupColor dpy cmap "red" col (XColor)) (if (or (not (= (.red col) 65535)) (not (= (.green col) 0)) (not (= (.blue col) 0))) (snd-display #__line__ ";XLookupColor: ~A ~A ~A ~A" col (.red col) (.blue col) (.green col)))) (map (lambda (color) (let ((col (XColor))) (if (= (XAllocNamedColor dpy cmap color col col) 0) (snd-error (format #f "can't allocate ~A" color)) (.pixel col)))) colors))) (rendertable (XmRenderTableAddRenditions #f (let ((ctr 0)) (map (lambda (r) (set! ctr (+ ctr 1)) (XmRenditionCreate (cadr (main-widgets)) r (append (if (= ctr 1) (list XmNtabList tablist) ()) (list XmNrenditionForeground (pixels (- ctr 1)) XmNfontName (fonts (- ctr 1)) XmNfontType XmFONT_IS_FONT)))) tags)) (length tags) XmMERGE_NEW))) (if (file-exists? "hiho") (delete-file "hiho")) (let* ((dpy (XtDisplay (cadr (main-widgets)))) (scr (DefaultScreenOfDisplay dpy)) (p1 (XmGetPixmap scr "hiho" (car pixels) (cadr pixels)))) (if (not (Pixmap? p1)) (snd-display #__line__ ";XmGetPixmap: ~A" p1)) (set! p1 (XmGetPixmapByDepth scr "hoho" (car pixels) (cadr pixels) (XDefaultDepth dpy (XScreenNumberOfScreen scr)))) (if (not (Pixmap? p1)) (snd-display #__line__ ";XmGetPixmapByDepth: ~A" p1)) (XmDestroyPixmap scr p1)) (let ((tabl (XmStringTableParseStringArray (list "hi" "ho") 2 "hiho" XmCHARSET_TEXT #f 0 #f))) (if (not (XmString? (car tabl))) (snd-display #__line__ ";XmStringTableParseStringArray: ~A" tabl)) (let ((strs (XmStringTableUnparse tabl 2 "hiho" XmCHARSET_TEXT XmCHARSET_TEXT #f 0 XmOUTPUT_ALL))) (if (not (equal? strs (list "hi" "ho"))) (snd-display #__line__ ";XmStringTableUnparse: ~A" strs))) (let ((str (XmStringTableToXmString tabl 2 #f))) (if (not (XmString? str)) (snd-display #__line__ ";XmStringTableToXmString: ~A" str)) (XmStringToXmStringTable str #f) (let ((val (XmStringUnparse str "hiho" XmCHARSET_TEXT XmCHARSET_TEXT #f 0 XmOUTPUT_ALL))) (if (not (string=? val "hiho")) (snd-display #__line__ ";XmStringUnparse: ~A" val)) (set! val (XmStringUnparse (XmStringCreateLocalized "hi") #f XmCHARSET_TEXT XmCHARSET_TEXT #f 0 XmOUTPUT_ALL)) (if (not (string=? val "hi")) (snd-display #__line__ ";XmStringUnparse null tag: ~A" val))) ;; XmCvtXmStringToByteStream test deleted because it seems to be buggy in memory handling (let* ((ind (open-sound "oboe.snd")) (grf1 (car (channel-widgets))) (dpy (XtDisplay grf1)) (win (XtWindow grf1)) (scr (DefaultScreenOfDisplay dpy)) (scrn (XScreenNumberOfScreen scr)) (gv (XGCValues))) (if (not (Font? (current-font ind))) (snd-display #__line__ ";current-font: ~A" (current-font ind))) (let ((old-font (current-font)) (a-font (load-font "6x12"))) (set! (current-font) a-font) (if (not (equal? a-font (current-font))) (snd-display #__line__ ";set current-font: ~A ~A" a-font (current-font))) (set! (current-font ind) old-font) (if (not (equal? old-font (current-font ind))) (snd-display #__line__ ";set current-font with ind: ~A ~A" old-font (current-font ind))) (set! (current-font) a-font) (set! (current-font ind 0) old-font) (if (not (equal? old-font (current-font ind 0))) (snd-display #__line__ ";set current-font with ind/0: ~A ~A" old-font (current-font ind 0))) (set! (current-font) old-font)) (set! (.foreground gv) *data-color*) (set! (.background gv) *basic-color*) (set! (.function gv) GXcopy) (let ((sgc (XtAllocateGC grf1 (XDefaultDepth dpy scrn) (logior GCForeground GCBackground GCFunction) gv (logior GCFont GCDashList) 0)) (str2 (XmStringCreateLocalized "hiho"))) (XmStringDraw dpy win rendertable str2 sgc 10 10 100 XmALIGNMENT_END XmSTRING_DIRECTION_L_TO_R (XRectangle 0 0 100 100)) (XmStringDrawImage dpy win rendertable str2 sgc 10 10 100 XmALIGNMENT_END XmSTRING_DIRECTION_L_TO_R (XRectangle 0 0 100 100)) (XmStringDrawUnderline dpy win rendertable str2 sgc 10 10 100 XmALIGNMENT_END XmSTRING_DIRECTION_L_TO_R (XRectangle 0 0 100 100) str2) (XtGetGC (cadr (main-widgets)) GCForeground gv) (XCopyGC dpy sgc GCFunction sgc) (XCopyArea dpy win win sgc 0 0 100 100 0 0) (XCopyPlane dpy win win sgc 0 0 100 100 0 0 1) (XtReleaseGC grf1 sgc)) (close-sound ind)) (let ((lc (XmStringLineCount (XmStringCreateLocalized "hiho")))) (if (not (= lc 1)) (snd-display #__line__ ";XmStringLineCount: ~A" lc))) (if (not (XmStringHasSubstring str (XmStringCreateLocalized "hi"))) (snd-display #__line__ ";XmStringHasSubstring?")))) (if (not (equal? (XmRenderTableGetTags rendertable) (list "one" "two" "three" "four"))) (snd-display #__line__ ";tags: ~A~%" (XmRenderTableGetTags rendertable))) (let* ((rend (XmRenderTableGetRendition rendertable "one")) (r (and rend (XmRenditionRetrieve rend (list XmNrenditionForeground 0 XmNfontName 0 XmNfontType 0 XmNtag 0))))) (if (and rend r) (begin (if (or (not (string=? (r 7) "one")) (not (string=? (r 3) "fixed"))) (snd-display #__line__ ";rendertable: ~A" r)) (XmRenditionUpdate rend (list XmNstrikethruType XmSINGLE_LINE)) (if (not (= (cadr (XmRenditionRetrieve rend (list XmNstrikethruType 0))) XmSINGLE_LINE)) (snd-display #__line__ ";XmRenditionUpdate: ~A ~A" (cadr (XtGetValues rend (list XmNstrikethruType 0))) XmSINGLE_LINE))) (snd-display #__line__ ";r and rend: ~A ~A~%" r rend))) (let ((r1 (XmRenditionCreate (cadr (main-widgets)) "r1" (list XmNfontName "fixed")))) (XmRenditionFree r1)) (if (not (equal? (XmDropSiteQueryStackingOrder ((main-widgets) 4)) (list #f))) (snd-display #__line__ ";XmDropSiteQueryStackingOrder: ~A" (XmDropSiteQueryStackingOrder ((main-widgets) 4)))) (let ((tab (XmStringComponentCreate XmSTRING_COMPONENT_TAB 0 #f)) (row #f) (table ()) (our-tags tags)) (for-each (lambda (word) (let ((entry (XmStringGenerate word #f XmCHARSET_TEXT (car our-tags)))) (if (XmStringIsVoid entry) (snd-display #__line__ ";~A is void?" entry)) (if (XmStringEmpty entry) (snd-display #__line__ ";~A is empty?" entry)) (if row (let ((tmp (XmStringConcat row tab))) (XmStringFree row) (set! row (XmStringConcatAndFree tmp entry))) (set! row entry)) (set! our-tags (cdr our-tags)) (if (null? our-tags) (begin (set! our-tags tags) (set! table (cons row table)) (set! row #f))))) (list "this" "is" "a" "test" "of" "the" "renditions" "and" "rendertables" "perhaps" "all" "will" "go" "well" "and" "then" "again" "perhaps" "not")) (let* ((n (car table)) (c (XmStringInitContext n)) (happy #t)) (do ((i 0 (+ i 1))) ((not happy)) (let ((type (XmStringGetNextTriple (cadr c)))) (if (= (car type) XmSTRING_COMPONENT_TEXT) (if (or (not (= (cadr type) ((list 0 0 2 0 0 0 4 0 0 0 3 0 0 0 4) i))) (not (string=? (caddr type) ((list "o" "o" "go" "o" "o" "o" "well" "o" "o" "o" "and" "o" "o" "o" "then") i)))) (snd-display #__line__ ";component ~A -> ~A" i (cdr type))) (if (and (not (= (car type) XmSTRING_COMPONENT_TAB)) (= (car type) XmSTRING_COMPONENT_END)) (set! happy #f))))) (XmStringFreeContext (cadr c)))))) (XtAppAddActions (car (main-widgets)) (list (list "try1" (lambda (w e strs) (snd-display #__line__ ";try1: ~A~%" strs))) (list "try2" (lambda (w e strs) (snd-display #__line__ ";try2: ~A~%" strs))))) (let ((tab (XtParseTranslationTable (format #f "Ctrl osfLeft: try1()~%Ctrl osfRight: try2()~%Ctrl osfUp: try1(hiho)~%Ctrl osfDown: try2(down, up)~%"))) (pane (add-main-pane "hiho" xmTextWidgetClass ()))) (XtOverrideTranslations pane tab)) (let ((XmNhiho (add-resource "hiho" 0))) (if (not (string=? XmNhiho "hiho")) (snd-display #__line__ ";add-resource XmNhiho: ~A" XmNhiho))) (open-sound "cardinal.snd") (let* ((mouse_width 32) (mouse_height 32) (mouse_bits (list #x00 #x00 #x00 #x00 #x00 #x00 #x00 #x00 #x00 #x00 #x00 #x00 #x00 #x00 #x00 #x00 #x00 #x00 #x00 #x00 #x00 #x00 #x00 #x00 #x80 #xff #xff #x01 #x80 #x00 #x01 #x01 #x80 #x00 #x01 #x01 #x80 #x00 #x01 #x01 #x80 #x00 #x01 #x01 #x80 #x00 #x01 #x01 #x80 #x00 #x01 #x01 #x80 #xff #xff #x01 #x80 #x00 #x00 #x01 #x80 #x00 #x00 #x01 #x80 #x00 #x00 #x01 #x80 #x00 #x00 #x01 #x80 #x00 #x00 #x01 #x80 #x00 #x00 #x01 #x80 #x00 #x00 #x01 #x80 #x00 #x00 #x01 #x00 #x01 #x80 #x00 #x00 #x01 #x80 #x00 #x00 #x06 #x60 #x00 #x00 #xf8 #x1f #x00 #x00 #x00 #x00 #x00 #x00 #x00 #x00 #x00 #x00 #x00 #x00 #x00 #x00 #x00 #x00 #x00 #x00 #x00 #x00 #x00 #x00 #x00 #x00 #x00)) (rb (list #x00 #x04 #x10 #x08 #x00 #x10 #x04 #x20 #x00 #x40 #xa5 #xbf #x00 #x40 #x04 #x20 #x00 #x10 #x10 #x08 #x00 #x04 #x00 #x00)) (iconw ((sound-widgets) 8)) (dpy (XtDisplay iconw)) (win (XtWindow iconw))) (XCreateBitmapFromData dpy win rb 16 12) (XCreateBitmapFromData dpy win mouse_bits mouse_width mouse_height) (XCreatePixmapFromBitmapData dpy win mouse_bits 32 32 (white-pixel) (black-pixel) 8)) (let* ((grf1 (car (channel-widgets))) (dpy (XtDisplay grf1)) (win (XtWindow grf1)) (sgc (car (snd-gcs))) (shell (cadr (main-widgets))) (scr (DefaultScreen dpy)) (vis (DefaultVisual dpy scr)) (depth (cadr (XtGetValues grf1 (list XmNdepth 0)))) (pix (XCreatePixmap dpy win 10 10 depth)) (rotpix (XCreatePixmap dpy win 10 10 depth))) (XDrawText dpy win sgc 50 50 (list (XTextItem "hi" 2 2 '(Font 0)) (XTextItem "ho" 2 3 '(Font 0)))) (let ((cmap (XCreateColormap dpy win vis AllocNone))) (set! cmap (XCopyColormapAndFree dpy cmap)) (XFreeColormap dpy cmap) (if (XCheckTypedWindowEvent dpy win ExposureMask) (snd-display #__line__ ";XCheckTypedWindowEvent: ~A" (XCheckTypedWindowEvent dpy win ExposureMask))) (if (XCheckTypedEvent dpy ExposureMask) (snd-display #__line__ ";XCheckTypedEvent: ~A" (XCheckTypedEvent dpy ExposureMask))) (XCheckWindowEvent dpy win ExposureMask) ; (if (XCheckIfEvent dpy (lambda (d e data) #f) #f) ; (snd-display #__line__ ";XCheckIfEvent: ~A" (XCheckIfEvent dpy (lambda (d e data) #f) #f))) (XCirculateSubwindows dpy win RaiseLowest) (XCirculateSubwindowsUp dpy win) (XCirculateSubwindowsDown dpy win) (let ((wc (XWindowChanges 10 10 100 100 10 win 0))) (if (not (= (.stack_mode wc) 0)) (snd-display #__line__ ";stack_mode wc: ~A" (.stack_mode wc))) (if (not (equal? (.sibling wc) win)) (snd-display #__line__ ";sibling wc: ~A" (.sibling wc))) (if (not (= (.x wc) 10)) (snd-display #__line__ ";x wc: ~A" (.x wc))) (if (not (= (.y wc) 10)) (snd-display #__line__ ";y wc: ~A" (.y wc))) (if (not (= (.width wc) 100)) (snd-display #__line__ ";width wc: ~A" (.width wc))) (if (not (= (.height wc) 100)) (snd-display #__line__ ";height wc: ~A" (.height wc))) (if (not (= (.border_width wc) 10)) (snd-display #__line__ ";border_width wc: ~A" (.border_width wc)))) (if (defined? 'XpmImage) (let ((xp (XpmImage 10 10 0 1 0))) (if (not (= (.cpp xp) 0)) (snd-display #__line__ ";cpp xp: ~A" (.cpp xp))) (if (not (= (.ncolors xp) 1)) (snd-display #__line__ ";ncolors xp: ~A" (.ncolors xp))))) ) (XmObjectAtPoint shell 100 100) (if (not (string=? (XmGetAtomName dpy XA_STRING) "STRING")) (snd-display #__line__ ";XmGetAtomName: ~A" (XmGetAtomName dpy XA_STRING))) (if (not (XmTargetsAreCompatible dpy (list XA_STRING) 1 (list XA_STRING) 1)) (snd-display #__line__ ";XmTargetsAreCompatible")) (XmUpdateDisplay grf1) (let ((lines (XmWidgetGetBaselines ((main-widgets) 4)))) (if (not lines) (snd-display #__line__ ";XmWidgetGetBaselines?")) (if (< (length lines) 4) (snd-display #__line__ ";no listener text?? ~A" lines))) (let ((r (XmWidgetGetDisplayRect ((sound-widgets) 8)))) (if (not (XRectangle? r)) (snd-display #__line__ ";XmWidgetGetDisplayRect: ~A" r))) (XDrawImageString dpy (list 'Window (cadr pix)) sgc 0 10 "hiho" 4) (let* ((data (XtCalloc (* 11 11 depth) 1)) (before (XCreateImage dpy vis depth XYPixmap 0 data 10 10 8 0)) (newimage (XGetSubImage dpy (list 'Window (cadr pix)) 0 0 10 10 AllPlanes XYPixmap before 0 0))) (XSubImage newimage 0 0 3 3) (if (not (= (.bytes_per_line newimage) 2)) (snd-display #__line__ ";bytes_per_line: ~A" (.bytes_per_line newimage))) (if (not (= (.byte_order newimage) 0)) (snd-display #__line__ ";byte_order: ~A" (.byte_order newimage))) (if (not (= (.bitmap_pad newimage) 8)) (snd-display #__line__ ";bitmap_pad: ~A" (.bitmap_pad newimage))) (if (not (= (.bitmap_bit_order newimage) 0)) (snd-display #__line__ ";bitmap_bit_order: ~A" (.bitmap_bit_order newimage))) (if (not (= (.bitmap_unit newimage) 32)) (snd-display #__line__ ";bitmap_unit: ~A" (.bitmap_unit newimage))) ; (if (not (= (.obdata newimage) 0)) (snd-display #__line__ ";obdata: ~A" (.obdata newimage))) (if (not (= (.xoffset newimage) 0)) (snd-display #__line__ ";xoffset: ~A" (.xoffset newimage))) (XPutPixel before 1 1 *basic-color*) (XGetPixel before 1 1) (XPutImage dpy (list 'Window (cadr rotpix)) sgc before 0 0 0 0 10 10) (XAddPixel before 1) (if (> (.bits_per_pixel before) 123) (snd-display #__line__ ";bits_per_pixel: ~A" (.bits_per_pixel before))) (XmInstallImage before "before_image") (XmUninstallImage before) (if (defined? 'XpmAttributes) (let ((i11 (XGetImage dpy (list 'Window (cadr pix)) 0 0 10 10 AllPlanes XYPixmap)) (attr (XpmAttributes)) (vals (XtGetValues (cadr (main-widgets)) (list XmNcolormap 0 XmNdepth 0))) (sym (XpmColorSymbol "basiccolor" #f *basic-color*))) (if (not (string=? (.name sym) "basiccolor")) (snd-display #__line__ ";.name colorsymbol: ~A" (.name sym))) (set! (.name sym) "hiho") (if (not (string=? (.name sym) "hiho")) (snd-display #__line__ ";set .name colorsymbol: ~A" (.name sym))) (set! (.visual attr) vis) (if (not (equal? vis (.visual attr))) (snd-display #__line__ ";visual xpm attr: ~A" (.visual attr))) (if (not (list? (.colorsymbols attr))) (snd-display #__line__ ";.colorsymbols attr: ~A" (.colorsymbols attr))) (set! (.colorsymbols attr) (list sym)) (set! (.pixel sym) *basic-color*) (set! (.numsymbols attr) 1) (if (not (eqv? 1 (.numsymbols attr))) (snd-display #__line__ ";numsymbols xpm attr: ~A" (.numsymbols attr))) (set! (.depth attr) (vals 3)) (if (not (equal? (vals 3) (.depth attr))) (snd-display #__line__ ";depth xpm attr: ~A" (.depth attr))) (set! (.colormap attr) (vals 1)) (if (not (equal? (vals 1) (.colormap attr))) (snd-display #__line__ ";colormap xpm attr: ~A" (.colormap attr))) (set! (.valuemask attr) (logior XpmColorSymbols XpmDepth XpmColormap XpmVisual)) (if (not (= (.valuemask attr) (logior XpmColorSymbols XpmDepth XpmColormap XpmVisual))) (snd-display #__line__ ";valuemask: ~A" (.valuemask attr))) (if (not (= (.x_hotspot attr) 0)) (snd-display #__line__ ";x_hotspot: ~A" (.x_hotspot attr))) (if (not (= (.y_hotspot attr) 0)) (snd-display #__line__ ";y_hotspot: ~A" (.y_hotspot attr))) (if (not (= (.npixels attr) 0)) (snd-display #__line__ ";npixels: ~A" (.npixels attr))) (let ((err (XpmCreatePixmapFromData dpy win (list "16 14 6 1" " c None s None" ". c gray50" "X c black" "o c white" "O c yellow" "- c ivory2 s basiccolor" "------.XXX.-----" "-----X.ooo.X----" "----..oXXXo..---" "----XoX...XoX---" "----XoX.--XoX.--" "----XoX.--XoX.--" "---XXXXXXXXXXX--" "---XOOOOOOOOOX.-" "---XO.......OX.-" "---XOOOOOOOOOX.-" "---XO.......OX.-" "---XOOOOOOOOOX.-" "---XXXXXXXXXXX.-" "----...........-") attr))) (if (or (not (= (car err) XpmSuccess)) (not (Pixmap? (cadr err)))) (snd-display #__line__ ";XpmCreatePixmapFromData: ~A" err))) (let* ((shell (cadr (main-widgets))) (dpy (XtDisplay shell)) (button (XmCreatePushButton shell "button" ())) (status-and-whatnot (XpmReadFileToPixmap dpy (XRootWindowOfScreen (XtScreen shell)) "bullet.xpm" #f)) (status (car status-and-whatnot)) (pixmap (cadr status-and-whatnot)) (pixmap1 (caddr status-and-whatnot))) (if (not (string=? (XpmGetErrorString XpmSuccess) "XpmSuccess")) (snd-display #__line__ ";XpmGetErrorString: ~A" (XpmGetErrorString XpmSuccess))) (if (not (= status XpmSuccess)) (snd-display #__line__ "; XpmError ReadFileToPixmap: ~A" (XpmGetErrorString status))) (XtVaSetValues button (list XmNlabelType XmPIXMAP XmNlabelPixmap pixmap)) (XpmWriteFileFromPixmap dpy "test.xpm" pixmap pixmap1 #f) (XpmCreateDataFromPixmap dpy pixmap pixmap1 #f) (let ((status (XpmReadFileToXpmImage "bullet.xpm")) (symb (XpmColorSymbol "Foreground" "green" *basic-color*)) (attr (XpmAttributes))) (if (not (XpmImage? status)) (snd-display #__line__ "; XpmError ReadFileToXpmImage: ~A ~A" symb (XpmGetErrorString status))) (set! (.valuemask attr) XpmColorSymbols) (XpmCreatePixmapFromXpmImage dpy (XRootWindowOfScreen (XtScreen shell)) status attr) (XpmCreateXpmImageFromPixmap dpy pixmap pixmap1 attr) (for-each (lambda (func val name) (set! (func attr) val) (if (not (equal? (func attr) val)) (snd-display #__line__ ";attr ~A ~A" name (func attr)))) (list .valuemask .depth .width .x_hotspot .y_hotspot .cpp .npixels .ncolors) (list 0 0 0 0 0 0 0 0) (list 'valuemask 'depth 'width 'x_hotspot 'y_hotspot 'cpp 'npixels 'ncolors))) ) (XDestroyImage i11))) (XDestroyImage before) (XFreePixmap dpy pix) (XVisualIDFromVisual vis) (XGrabServer dpy) (XUngrabServer dpy) (XGrabPointer dpy win #t ButtonPressMask GrabModeSync GrabModeSync (list 'Window None) (list 'Cursor None) (list 'Time CurrentTime)) (XUngrabPointer dpy (list 'Time CurrentTime)) (XGrabKeyboard dpy win #t GrabModeSync GrabModeSync (list 'Time CurrentTime)) (XUngrabKeyboard dpy (list 'Time CurrentTime)) (XGrabKey dpy AnyKey AnyModifier win #t GrabModeSync GrabModeSync) (XUngrabKey dpy AnyKey AnyModifier win) (XGrabButton dpy AnyButton AnyModifier win #t ButtonPressMask GrabModeSync GrabModeSync (list 'Window None) (list 'Cursor None)) (XUngrabButton dpy AnyButton AnyModifier win) (XtGrabPointer shell #t ButtonPressMask GrabModeSync GrabModeSync (list 'Window None) (list 'Cursor None) (list 'Time CurrentTime)) (XtUngrabPointer shell (list 'Time CurrentTime)) (XtGrabKeyboard shell #t GrabModeSync GrabModeSync (list 'Time CurrentTime)) (XtUngrabKeyboard shell (list 'Time CurrentTime)) (XtGrabKey shell (list 'KeyCode AnyKey) AnyModifier #t GrabModeSync GrabModeSync) (XtUngrabKey shell (list 'KeyCode AnyKey) AnyModifier) (XtGrabButton shell AnyButton AnyModifier #t ButtonPressMask GrabModeSync GrabModeSync (list 'Window None) (list 'Cursor None)) (XtUngrabButton shell AnyButton AnyModifier) )) (let* ((sgc (car (snd-gcs))) (grf1 (car (channel-widgets))) (dpy (XtDisplay grf1)) (win (XtWindow grf1)) (shl (cadr (main-widgets)))) (let ((wid (XtWindowToWidget dpy win))) (if (not (equal? wid grf1)) (snd-display #__line__ ";XtWindowToWidget: ~A ~A" grf1 win))) ; these are causing: X Error of failed request: BadAccess (attempt to access private resource denied) ; (if (not (equal? (XGetTransientForHint dpy win) (list 0 #f))) ; (snd-display #__line__ ";XGetTransientForHint: ~A" (XGetTransientForHint dpy win))) (if (not (equal? (XGetErrorText dpy BadColor #f 9) (list 0 "BadColor"))) (snd-display #__line__ ";XGetErrorText: ~A" (XGetErrorText dpy BadColor #f 9))) (if (not (equal? (XGeometry dpy 0 "500x400" "500x400+10+10" 4 7 14 2 2) (list 12 10 10 500 400))) (snd-display #__line__ ";XGeometry: ~A" (XGeometry dpy 0 "500x400" "500x400+10+10" 4 7 14 2 2))) (if (< (XEventsQueued dpy QueuedAlready) 0) (snd-display #__line__ ";XEventsQueued: ~A" (XEventsQueued dpy QueuedAlready))) ; (let ((coords (XTranslateCoordinates dpy (XtWindow shl) win 10 10))) ; (if (not (car coords)) ; (snd-display #__line__ ";XTranslateCoordinates: ~A" coords))) (let ((coords (XtTranslateCoords shl 10 10))) (if (not (number? (car coords))) (snd-display #__line__ ";XtTranslateCoords: ~A" coords))) (if (not (XmIsVendorShell shl)) (snd-display #__line__ ";XmIsVendorShell?")) (if (XmIsPrimitive shl) (snd-display #__line__ ";XmIsPrimitive?")) (if (XmIsManager shl) (snd-display #__line__ ";XmIsManager?")) (if (XmIsIconGadget shl) (snd-display #__line__ ";XmIsIconGadget?")) (if (XmIsGadget shl) (snd-display #__line__ ";XmIsGadget?")) (if (XmIsIconHeader shl) (snd-display #__line__ ";XmIsHeader?")) (if (XmIsDropTransfer shl) (snd-display #__line__ ";XmIsDropTransfer?")) (if (XmIsDropSiteManager shl) (snd-display #__line__ ";XmIsDropSiteManager?")) (if (XmIsDragContext shl) (snd-display #__line__ ";XmIsDragContext?")) (if (XmIsDragIconObjectClass shl) (snd-display #__line__ ";XmIsDragIconObjectClass?")) (if (XmIsMessageBox shl) (snd-display #__line__ ";XmIsMessageBox?")) (if (XmIsScreen shl) (snd-display #__line__ ";XmIsScreen?")) (if (XmIsDisplay shl) (snd-display #__line__ ";XmIsDisplay?")) (let ((val 0)) (XSetErrorHandler (lambda (dpy e) (set! val (.error_code e)))) (XGetAtomName dpy '(Atom 0)) (if (not (= val 5)) (snd-display #__line__ ";XSetErrorHandler: ~A" val))) (XDrawImageString dpy win sgc 10 10 "hiho" 4) (XDrawRectangle dpy win sgc 0 0 10 10) (XDrawString dpy win sgc 10 10 "hi" 2) (XDrawSegments dpy win sgc (list (XSegment 1 1 2 20) (XSegment 3 3 40 4)) 2) (XDrawRectangles dpy win sgc (list (XRectangle 0 0 10 10) (XRectangle 20 20 30 30)) 2) (XFillRectangles dpy win sgc (list (XRectangle 0 0 10 10) (XRectangle 20 20 30 30)) 2) (XDrawRectangle dpy win sgc 10 10 10 10) (XFillRectangle dpy win sgc 10 10 10 10) (XDrawPoints dpy win sgc (list (XPoint 23 23) (XPoint 109 10)) 2 CoordModeOrigin) (XDrawPoint dpy win sgc 10 10) (XDrawLines dpy win sgc (list (XPoint 23 23) (XPoint 109 10)) 2 CoordModeOrigin) (XDrawLine dpy win sgc 10 10 20 20) (XDrawArcs dpy win sgc (list (XArc 10 10 4 4 0 360) (XArc 20 20 1 23 0 123)) 2) (XFillArcs dpy win sgc (list (XArc 10 10 4 4 0 360) (XArc 20 20 1 23 0 123)) 2) (XDrawArc dpy win sgc 0 0 10 10 45 90) (XFillArc dpy win sgc 0 0 10 10 45 90) (XFillPolygon dpy win sgc (list (XPoint 0 0) (XPoint 0 10) (XPoint 10 10) (XPoint 10 0) (XPoint 0 0)) 5 Convex CoordModeOrigin) (XClearArea dpy win 10 10 20 20 #f) (XClearWindow dpy win)) (close-sound) (let ((button (XtCreateManagedWidget "button" xmPushButtonWidgetClass (cadr (main-widgets)) () 0)) (val1 0)) (define (call1 w c i) (set! val1 (+ 1 val1))) (let ((descr (XtAddCallback button XmNactivateCallback call1 #f))) (XtCallCallbacks button XmNactivateCallback #f) (if (not (= val1 1)) (snd-display #__line__ ";XtCallCallbacks val1: ~A" val1)) (XtRemoveCallback button XmNactivateCallback descr) (let ((calls (XtHasCallbacks button XmNactivateCallback))) (if (not (= calls XtCallbackHasNone)) (snd-display #__line__ ";XtRemoveCallbacks: ~A" calls)))) (XtUnmanageChild button) ;(XtDestroyWidget button) ) (let ((button (XtCreateManagedWidget "button" xmPushButtonWidgetClass (cadr (main-widgets)) () 0)) (val1 0) (val2 0)) (define (call1 w c i) (set! val1 (+ 1 val1))) (define (call2 w c i) (set! val2 (+ 1 val2))) (let ((descr1 (XtAddCallback button XmNactivateCallback call1 #f)) (descr2 (XtAddCallback button XmNactivateCallback call2 #f))) (XtCallCallbacks button XmNactivateCallback #f) (if (and (not (= val1 1)) (not (= val2 1))) (snd-display #__line__ ";XtCallCallbacks val12: ~A ~A" val1 val2)) (XtRemoveCallbacks button XmNactivateCallback (list descr1 descr2)) (let ((calls (XtHasCallbacks button XmNactivateCallback))) (if (not (= calls XtCallbackHasNone)) (snd-display #__line__ ";XtRemoveCallbacks: ~A" calls)))) (XtUnmanageChild button) ;(XtDestroyWidget button) ) (let ((button (XtCreateManagedWidget "button" xmPushButtonWidgetClass (cadr (main-widgets)) () 0)) (val1 0) (val2 0)) (define (call1 w c i) (set! val1 (+ 1 val1))) (define (call2 w c i) (set! val2 (+ 1 val2))) (let ((descrs (XtAddCallbacks button XmNactivateCallback (list (list call1 #f) (list call2 #f))))) (XtCallCallbacks button XmNactivateCallback #f) (if (and (not (= val1 1)) (not (= val2 1))) (snd-display #__line__ ";XtCallCallbacks add val12: ~A ~A" val1 val2)) (XtRemoveCallbacks button XmNactivateCallback descrs) (let ((calls (XtHasCallbacks button XmNactivateCallback))) (if (not (= calls XtCallbackHasNone)) (snd-display #__line__ ";XtRemoveCallbacks (add): ~A" calls)))) (XtUnmanageChild button) ;(XtDestroyWidget button) ) (let* ((frm (add-main-pane "hi" xmFormWidgetClass (list XmNpaneMinimum 120))) (browsed 0) (lst (XtCreateManagedWidget "lst" xmListWidgetClass frm (list XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_FORM XmNautomaticSelection XmNO_AUTO_SELECT XmNdoubleClickInterval 100 XmNitemCount 3 XmNitems (list (XmStringCreate "one" XmFONTLIST_DEFAULT_TAG) (XmStringCreate "two" XmFONTLIST_DEFAULT_TAG) (XmStringCreate "three" XmFONTLIST_DEFAULT_TAG)) XmNlistMarginHeight 4 XmNlistMarginWidth 1 XmNlistSizePolicy XmVARIABLE XmNlistSpacing 2 XmNmatchBehavior XmQUICK_NAVIGATE XmNprimaryOwnership XmOWN_NEVER XmNscrollBarDisplayPolicy XmAS_NEEDED XmNselectColor *basic-color* XmNselectedPositions (list 0 1) XmNselectionMode XmNORMAL_MODE XmNselectionPolicy XmBROWSE_SELECT)))) (XtAddCallback lst XmNbrowseSelectionCallback (lambda (w c i) (set! browsed 123))) (let ((vals (XtVaGetValues lst (list XmNautomaticSelection 0 XmNdoubleClickInterval 0 XmNitemCount 0 XmNitems 0 XmNlistMarginHeight 0 XmNlistMarginWidth 0 XmNlistSizePolicy 0 XmNlistSpacing 0 XmNmatchBehavior 0 XmNprimaryOwnership 0 XmNscrollBarDisplayPolicy 0 XmNselectColor 0 XmNselectionMode 0 XmNselectionPolicy 0 XmNhorizontalScrollBar 0 XmNselectedItemCount 0 XmNtopItemPosition 0)))) (if (not (= (vals 1) XmNO_AUTO_SELECT)) (snd-display #__line__ ";XmNautomaticSelection: ~A" (vals 1))) (if (not (= (vals 3) 100)) (snd-display #__line__ ";XmNdoubleClickInterval: ~A" (vals 3))) (if (not (= (vals 5) 3)) (snd-display #__line__ ";XmNitemCount: ~A" (vals 5))) (if (or (null? (vals 7)) (not (XmString? (car (vals 7))))) (snd-display #__line__ ";XmNitems: ~A" (vals 7))) (if (not (= (vals 9) 4)) (snd-display #__line__ ";XmNlistMarginHeight: ~A" (vals 9))) (if (not (= (vals 11) 1)) (snd-display #__line__ ";XmNlistMarginWidth: ~A" (vals 11))) (if (not (= (vals 13) XmVARIABLE)) (snd-display #__line__ ";XmNlistSizePolicy: ~A" (vals 13))) (if (not (= (vals 15) 2)) (snd-display #__line__ ";XmNlistSpacing: ~A" (vals 15))) (if (not (= (vals 17) XmQUICK_NAVIGATE)) (snd-display #__line__ ";XmNmatchBehavior: ~A" (vals 17))) (if (not (= (vals 19) XmOWN_NEVER)) (snd-display #__line__ ";XmNprimaryOwnership : ~A" (vals 19))) (if (not (= (vals 21) XmAS_NEEDED)) (snd-display #__line__ ";XmNscrollBarDisplayPolicy: ~A" (vals 21))) (if (not (Pixel? (vals 23))) (snd-display #__line__ ";XmNselectColor: ~A" (vals 23))) (if (not (= (vals 25) XmNORMAL_MODE)) (snd-display #__line__ ";XmNselectionMode: ~A" (vals 25))) (if (not (= (vals 27) XmBROWSE_SELECT)) (snd-display #__line__ ";XmNselectionPolicy: ~A" (vals 27))) (if (vals 29) (snd-display #__line__ ";XmNhorizontalScrollBar: ~A" (vals 29))) (if (not (= (vals 31) 0)) (snd-display #__line__ ";XmNselectedItemCount : ~A" (vals 31))) (if (not (= (vals 33) 1)) (snd-display #__line__ ";XmNtopItemPosition: ~A" (vals 33))) (let ((tag (catch #t (lambda () (XmListAddItem frm (XmStringCreate "four" XmFONTLIST_DEFAULT_TAG) 0)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";list type check: ~A" tag))) (XmListAddItem lst (XmStringCreate "four" XmFONTLIST_DEFAULT_TAG) 0) ; 0 -> last position (set! vals (XtGetValues lst (list XmNitemCount 0 XmNitems 0))) (if (not (= (vals 1) 4)) (snd-display #__line__ ";XmAddItem len: ~A" (vals 1))) (XmListAddItems lst (list (XmStringCreateLocalized "five") (XmStringCreateLocalized "six")) 2 0) (let ((tag (catch #t (lambda () (XmListAddItems lst (list (XmStringCreateLocalized "seven") 123) 2 0)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";xstrings->list add: ~A" tag))) (set! vals (XtGetValues lst (list XmNitemCount 0 XmNitems 0))) (if (not (= (vals 1) 6)) (snd-display #__line__ ";XmAddItems len: ~A" (vals 1))) (XmListDeletePos lst 1) (set! vals (XtGetValues lst (list XmNitemCount 0 XmNitems 0))) (if (not (= (vals 1) 5)) (snd-display #__line__ ";XmListDeletePos len: ~A" (vals 1))) (XmListDeletePositions lst (list 2 4)) (set! vals (XtGetValues lst (list XmNitemCount 0 XmNitems 0))) (if (not (= (vals 1) 3)) (snd-display #__line__ ";XmListDeletePositions len: ~A" (vals 1))) (XmListAddItemUnselected lst (XmStringCreate "seven" XmFONTLIST_DEFAULT_TAG) 0) ; 0 -> last position (set! vals (XtGetValues lst (list XmNitemCount 0 XmNitems 0))) (if (not (= (vals 1) 4)) (snd-display #__line__ ";XmListAddItemUnselected len: ~A" (vals 1))) (XmListAddItemsUnselected lst (list (XmStringCreateLocalized "eight") (XmStringCreateLocalized "nine")) 2 0) (set! vals (XtGetValues lst (list XmNitemCount 0 XmNitems 0))) (if (not (= (vals 1) 6)) (snd-display #__line__ ";XmListAddItemsUnselected len: ~A" (vals 1))) (XmListDeleteAllItems lst) (set! vals (XtGetValues lst (list XmNitemCount 0 XmNitems 0))) (if (not (= (vals 1) 0)) (snd-display #__line__ ";XmListDeleteAllItems len: ~A" (vals 1))) (if (pair? (vals 3)) (snd-display #__line__ ";deleted all items: ~A" (vals 3))) (let ((item1 (XmStringCreate "one" XmFONTLIST_DEFAULT_TAG)) (item2 (XmStringCreate "two" XmFONTLIST_DEFAULT_TAG)) (item3 (XmStringCreate "three" XmFONTLIST_DEFAULT_TAG)) (item4 (XmStringCreate "four" XmFONTLIST_DEFAULT_TAG)) (item5 (XmStringCreate "five" XmFONTLIST_DEFAULT_TAG))) (XtVaSetValues lst (list XmNitemCount 5 XmNitems (list item1 item2 item3 item4 item5))) (set! vals (XtGetValues lst (list XmNitemCount 0 XmNitems 0))) (if (not (= (vals 1) 5)) (snd-display #__line__ ";Xt set items len: ~A" (vals 1))) (XmListSelectItem lst item3 #t) (if (not (= browsed 123)) (snd-display #__line__ ";XmListSelectItem callback: ~A" browsed)) (if (XmListPosSelected lst 1) (snd-display #__line__ ";XmList selected pos 1?")) (if (not (XmListPosSelected lst 3)) (snd-display #__line__ ";XmList didn't select pos 3?")) (set! vals (XtVaGetValues lst (list XmNselectedItemCount 0 XmNselectedItems 0))) (if (not (= (vals 1) 1)) (snd-display #__line__ ";selected count: ~A" (vals 1))) (set! vals (XmListGetSelectedPos lst)) (if (not (= (length vals) 1)) (snd-display #__line__ ";XmListGetSelectedPos: ~A" vals)) (if (not (= (car vals) 3)) (snd-display #__line__ ";XmListGetSelectedPos: ~A" vals)) (set! browsed 0) (XmListSelectPos lst 1 #f) (if (not (= browsed 0)) (snd-display #__line__ ";XmListSelectPos callback: ~A" browsed)) (if (not (XmListPosSelected lst 1)) (snd-display #__line__ ";XmList select pos?")) (if (not (= (XmListItemPos lst item3) 3)) (snd-display #__line__ ";XmListItemPos: ~A" (XmListItemPos lst item3))) (if (not (= (car (XmListGetMatchPos lst item3)) 3)) (snd-display #__line__ ";XmListGetMatchPos: ~A" (XmListGetMatchPos lst item3))) (if (not (XmListItemExists lst item3)) (snd-display #__line__ ";XmListItemExists?")) (if (not (= (XmListYToPos lst 40) 2)) (snd-display #__line__ ";XmListYToPos: ~A" (XmListYToPos lst 40))) (let ((box (XmListPosToBounds lst 2))) (if (and (not (= (cadr box) 3)) (not (= (cadr box) 2))) (snd-display #__line__ ";XmListPosToBounds: ~A" box))) (XmListDeselectPos lst 1) (if (XmListPosSelected lst 1) (snd-display #__line__ ";XmList deselected pos?")) (XmListSelectItem lst item3 #t) (XmListDeselectAllItems lst) (if (XmListPosSelected lst 3) (snd-display #__line__ ";XmList deselect all pos?")) (XmListSelectItem lst item3 #f) (XmListDeselectItem lst item3) (if (XmListPosSelected lst 3) (snd-display #__line__ ";XmList deselect item?")) (XmListDeleteItem lst item2) (set! vals (XtGetValues lst (list XmNitemCount 0 XmNitems 0))) (if (not (= (vals 1) 4)) (snd-display #__line__ ";XmDeleteItem len: ~A" (vals 1))) (XmListDeleteItems lst (list item1 item4)) (set! vals (XtGetValues lst (list XmNitemCount 0 XmNitems 0))) (if (not (= (vals 1) 2)) (snd-display #__line__ ";XmDeleteItems len: ~A" (vals 1))) (XmListDeleteAllItems lst) (XtVaSetValues lst (list XmNitemCount 5 XmNitems (list item1 item2 item3 item4 item5))) (XtUnmanageChild frm)))) (let* ((frm (add-main-pane "hi" xmFormWidgetClass (list XmNpaneMinimum 120))) (current-time (list 'Time CurrentTime)) (calls (make-vector 10 "none")) (txt (XtCreateManagedWidget "text" xmTextWidgetClass frm (list XmNeditable #t XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_NONE XmNdestinationCallback (list (lambda (w c i) (set! (calls c) "dest") (if (< (.location_data i) 0) (snd-display #__line__ ";location_data: ~A" (.location_data i)))) 1) XmNactivateCallback (list (lambda (w c i) (set! (calls c) "act")) 2) XmNfocusCallback (list (lambda (w c i) (set! (calls c) "focus")) 3) XmNlosingFocusCallback (list (lambda (w c i) (set! (calls c) "losingfocus")) 4) XmNgainPrimaryCallback (list (lambda (w c i) (set! (calls c) "gain")) 5) XmNlosePrimaryCallback (list (lambda (w c i) (set! (calls c) "lose")) 6) XmNmodifyVerifyCallback (list (lambda (w c i) (set! (calls c) "modify") (if (< (.currInsert i) 0) (snd-display #__line__ ";currInsert: ~A" (.currInsert i))) (if (< (.newInsert i) 0) (snd-display #__line__ ";newInsert: ~A" (.newInsert i))) (if (string? (.doit i)) (snd-display #__line__ ";doit: ~A" (.doit i))) (if (< (.startPos i) 0) (snd-display #__line__ ";startPos: ~A" (.startPos i))) (if (< (.endPos i) 0) (snd-display #__line__ ";endPos: ~A" (.endPos i)))) 7) XmNmotionVerifyCallback (list (lambda (w c i) (set! (calls c) "motion")) 8) XmNvalueChangedCallback (list (lambda (w c i) (set! (calls c) "value")) 9))))) (letrec ((transfer-proc (lambda (w c info) (let* ((dpy (XtDisplay w)) (TARGETS (XmInternAtom dpy "TARGETS" #f)) (CB_TARGETS (XmInternAtom dpy "_MOTIF_CLIPBOARD_TARGETS" #f))) (if (equal? (.target info) XA_STRING) (XmTransferDone (.transfer_id info) XmTRANSFER_DONE_SUCCEED) (if (and (or (equal? (.target info) TARGETS) (equal? (.target info) CB_TARGETS)) (equal? (.type info) XA_ATOM)) (let ((targets (->Atoms (.value info) (.length info))) (happy #f)) (for-each (lambda (targ) (if (equal? targ XA_STRING) (set! happy #t))) targets) (if happy (XmTransferValue (.transfer_id info) XA_STRING transfer-proc #f (XtLastTimestampProcessed dpy))))))))) (txtf (XtVaCreateManagedWidget "textfield" xmTextFieldWidgetClass frm (list XmNeditable #t XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_WIDGET XmNtopWidget txt XmNbottomAttachment XmATTACH_FORM)))) (let ((vals (XtVaGetValues txt (list XmNrenderTable 0 XmNselectionArray 0)))) (if (not (XmRenderTable? (vals 1))) (snd-display #__line__ ";XmNrenderTable: ~A" (vals 1))) (if (not (pair? (vals 3))) (snd-display #__line__ ";XmNselectionArray: ~A" (vals 3)))) (if (not (XmTextGetEditable txt)) (snd-display #__line__ ";XmTextGetEditable?")) (if (not (XmTextFieldGetEditable txtf)) (snd-display #__line__ ";XmTextFieldGetEditable?")) (XmTextSetEditable txt #f) (XmTextFieldSetEditable txtf #f) (if (XmTextGetEditable txt) (snd-display #__line__ ";XmTextSetEditable?")) (if (XmTextFieldGetEditable txtf) (snd-display #__line__ ";XmTextFieldSetEditable?")) (XmTextSetEditable txt #t) (XmTextFieldSetEditable txtf #t) (XmTextSetString txt "0123456789") (XmTextFieldSetString txtf "0123456789") (XmTextFieldCopyLink txtf (list 'Time CurrentTime)) (let ((val (XmTextGetString txt)) (valf (XmTextFieldGetString txtf)) (val1 (cadr (XtVaGetValues txt (list XmNvalue 0)))) (val1f (cadr (XtVaGetValues txtf (list XmNvalue 0))))) (if (not (string=? val "0123456789")) (snd-display #__line__ ";XmTextSetString: ~A" val)) (if (not (string=? valf "0123456789")) (snd-display #__line__ ";XmTextFieldSetString: ~A" valf)) (if (not (string=? val1 "0123456789")) (snd-display #__line__ ";text value: ~A" val1)) (if (not (string=? val1f "0123456789")) (snd-display #__line__ ";text field value: ~A" val))) (let ((untext (XtCreateWidget "untext" xmTextWidgetClass frm ())) (source (XmTextGetSource txt))) (XmTextSetSource untext source 0 3) (if (not (XmTextSource? source)) (snd-display #__line__ ";XmTextSource? ~A" source)) (if (not (equal? (XmTextGetSource untext) source)) (snd-display #__line__ ";XmTextSetSource: ~A ~A" source (XmTextGetSource untext))) (if (XtIsSubclass untext xmFormWidgetClass) (snd-display #__line__ ";XtIsSubclass thinks untext is a form?")) (if (not (XtIsSubclass untext coreWidgetClass)) (snd-display #__line__ ";XtIsSubclass thinks untext is not a core widget")) (XmTextCopyLink untext (list 'Time CurrentTime)) (XmTextPasteLink untext)) (let ((val (XmTextGetSubstring txt 2 3)) (valf (XmTextFieldGetSubstring txtf 2 3))) (if (or (not (string? val)) (not (string=? val "234"))) (snd-display #__line__ ";XmTextGetSubstring: ~A" val)) (if (or (not (string? valf)) (not (string=? valf "234"))) (snd-display #__line__ ";XmTextFieldGetSubstring: ~A" valf))) (XmTextSetSelection txt 2 5 current-time) (let ((val (XmTextGetSelection txt))) (if (or (not (string? val)) (not (string=? val "234"))) (snd-display #__line__ ";XmTextGetSelection: ~A" val))) (XmTextClearSelection txt current-time) (let ((val (XmTextGetSelection txt))) (if val (snd-display #__line__ ";XmTextClearSelection: ~A" val))) (XmTextFieldSetSelection txtf 2 5 current-time) (let ((tag (catch #t (lambda () (XmTextFieldSetSelection txt 2 3 current-time)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";text field type check: ~A" tag))) (let ((tag (catch #t (lambda () (XmTextSetSelection frm 2 3 current-time)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";text type check: ~A" tag))) (let ((dpy (XtDisplay (cadr (main-widgets)))) (win (XtWindow (cadr (main-widgets)))) (app (car (main-widgets)))) (let ((tag (catch #t (lambda () (XmTransferSetParameters 123 123 123 123 "hiho")) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";XmTransferSetParameters type check: ~A" tag))) (let ((tag (catch #t (lambda () (XmDropSiteConfigureStackingOrder txtf txtf "hiho")) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";XmDropSiteConfigureStackingOrder type check: ~A" tag))) (let ((tag (catch #t (lambda () (XmScrollVisible txtf txtf 5 "hiho")) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";XmScrollVisible type check: ~A" tag))) (let ((tag (catch #t (lambda () (XmDragStart txtf (XEvent KeyPress) (list 0 1) "hiho")) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";XmDragStart type check: ~A" tag))) (let ((tag (catch #t (lambda () (XmClipboardStartRetrieve dpy win 1)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";XmClipboardStartRetrieve type check: ~A" tag))) (let ((tag (catch #t (lambda () (XmClipboardCopyByName dpy win 1 "hi" "hi" 1)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";XmClipboardCopyByName type check: ~A" tag))) (let ((tag (catch #t (lambda () (XmClipboardBeginCopy dpy win "hi" txtf #f)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";XmClipboardBeginCopy type check: ~A" tag))) (let ((tag (catch #t (lambda () (XmRemoveProtocolCallback txtf XA_STRING XA_STRING #f 1)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";XmRemoveProtocolCallback type check: ~A" tag))) (let ((tag (catch #t (lambda () (XSetRGBColormaps dpy win (list 'XStandardColormap 0) 1 #f)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";XSetRGBColormap type check: ~A" tag))) (let ((tag (catch #t (lambda () (XSetWMHints dpy win 1)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";XSetWMHints type check: ~A" tag))) (let ((tag (catch #t (lambda () (XWindowEvent dpy win #f)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";XWindowEvent type check: ~A" tag))) (let ((tag (catch #t (lambda () (XStoreNamedColor dpy (list 'Colormap 0) "hi" 0 #f)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";XStoreNamedColor type check: ~A" tag))) (let ((tag (catch #t (lambda () (XStoreColors dpy (list 'Colormap 0) (list 1 2) #f)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";XStoreColors type check: ~A" tag))) (let ((tag (catch #t (lambda () (XStoreColor dpy (list 'Colormap 0) (list 1 2))) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";XStoreColor type check: ~A" tag))) (let ((tag (catch #t (lambda () (XtDisplayInitialize app dpy "hi" "ho" 1 1)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";XtDisplayInitialize type check: ~A" tag))) (let ((tag (catch #t (lambda () (XtOwnSelectionIncremental txtf '(Atom 0) '(Time 0) #f #f #f #f #f)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";XtOwnSelectionIncremental type check: ~A" tag))) (let ((tag (catch #t (lambda () (XtOwnSelection txtf '(Atom 0) '(Time 0) #f #f #f)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";XtOwnSelection type check: ~A" tag))) (let ((tag (catch #t (lambda () (XtGetSelectionValue txtf '(Atom 0) '(Atom 0) #f #f #f)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";XtGetSelectionValue type check: ~A" tag))) (let ((tag (catch #t (lambda () (XtGetSelectionValues txtf '(Atom 0) (list (list 'Atom 0)) #f #f #f #f)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";XtGetSelectionValues type check: ~A" tag))) (let ((tag (catch #t (lambda () (XtDisownSelection txtf '(Atom 0) #f)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";XtDisownSelection type check: ~A" tag))) (let ((tag (catch #t (lambda () (XtGetSelectionRequest txtf '(Atom 0) #f)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";XtGetSelectionRequest type check: ~A" tag))) (let ((tag (catch #t (lambda () (XtGetSelectionValueIncremental txtf '(Atom 0) (list (list 'Atom 0)) 1 #f #f)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";XtGetSelectionValueIncremental type check: ~A" tag))) (let ((tag (catch #t (lambda () (XtGetSelectionValuesIncremental txtf '(Atom 0) '(Atom 0) 1 #f #f #f)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";XtGetSelectionValuesIncremental type check: ~A" tag))) (let ((tag (catch #t (lambda () (XtSendSelectionRequest txtf '(Atom 0) #f)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";XtSendSelectionRequest type check: ~A" tag))) (let ((tag (catch #t (lambda () (XReconfigureWMWindow dpy win 1 1 #f)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";XReconfigureWMWindow type check: ~A" tag))) (let ((tag (catch #t (lambda () (XSetWMProtocols dpy win 1 1)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";XSetWMProtocols type check: ~A" tag))) (let ((tag (catch #t (lambda () (XIconifyWindow dpy win #f)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";XIconifyWindow type check: ~A" tag))) (let ((tag (catch #t (lambda () (XWithdrawWindow dpy win #f)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";XWithdrawWindow type check: ~A" tag))) (let ((tag (catch #t (lambda () (XSetWMColormapWindows dpy win #f 1)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";XSetWMColormapWindows type check: ~A" tag))) (let ((tag (catch #t (lambda () (XSetTransientForHint dpy win #f)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";XSetTransientForHint type check: ~A" tag))) (let ((tag (catch #t (lambda () (XAllowEvents dpy 1 #f)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";XAllowEvents type check: ~A" tag))) (let ((tag (catch #t (lambda () (XChangeActivePointerGrab dpy 1 '(Cursor 0) #f)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";XChangeActivePointerGrab type check: ~A" tag))) (let ((tag (catch #t (lambda () (XChangeGC dpy '(GC 0) 1 #f)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";XChangeGC type check: ~A" tag))) (let ((tag (catch #t (lambda () (XChangeKeyboardMapping dpy 1 1 (list 1 1) #f)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";XChangeKeyboardMapping type check: ~A" tag))) (let ((tag (catch #t (lambda () (XConfigureWindow dpy win 1 #f)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";XConfigureWindow type check: ~A" tag))) (let ((tag (catch #t (lambda () (XConvertSelection dpy '(Atom 0) '(Atom 0) '(Atom 0) win #f)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";XConvertSelection type check: ~A" tag))) (let ((tag (catch #t (lambda () (XReparentWindow dpy win win 1 #f)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";XReparentWindow type check: ~A" tag))) (let ((tag (catch #t (lambda () (XFreeColors dpy '(Colormap 0) (list 0) 1 #f)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";XFreeColors type check: ~A" tag))) (let ((tag (catch #t (lambda () (XReadBitmapFile dpy win #f)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";XReadBitmapFile type check: ~A" tag))) (let ((tag (catch #t (lambda () (XRebindKeysym dpy '(KeySym 0) (list 0) 1 "hi" #f)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";XRebindKeysym type check: ~A" tag))) (let ((tag (catch #t (lambda () (XRestackWindows dpy (list 0) #f)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";XRestackWindows type check: ~A" tag))) (let ((tag (catch #t (lambda () (XRotateWindowProperties dpy win (list 0) 1 #f)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";XRotateWindowProperties type check: ~A" tag))) (let ((tag (catch #t (lambda () (XSelectInput dpy win #f)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";XSelectInput type check: ~A" tag))) (let ((tag (catch #t (lambda () (XSetFontPath dpy (list 0) #f)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";XSetFontPath type check: ~A" tag))) (let ((tag (catch #t (lambda () (XSetInputFocus dpy win 1 #f)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";XSetInputFocus type check: ~A" tag))) (let ((tag (catch #t (lambda () (XSetSelectionOwner dpy '(Atom 0) win #f)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";XSetSelectionOwner type check: ~A" tag))) (let ((tag (catch #t (lambda () (XSetWindowColormap dpy win #f)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";XSetWindowColormap type check: ~A" tag))) (let ((tag (catch #t (lambda () (XmClipboardCancelCopy dpy win #f)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";XmClipboardCancelCopy type check: ~A" tag))) ) (let ((valf (XmTextFieldGetSelection txtf))) (if (not (string=? valf "234")) (snd-display #__line__ ";XmTextFieldGetSelection: ~A" valf))) (XmTextFieldClearSelection txtf current-time) (let ((valf (XmTextFieldGetSelection txtf))) (if valf (snd-display #__line__ ";XmTextFieldClearSelection: ~A" valf))) (let ((val (XmTextGetInsertionPosition txt)) (valf (XmTextFieldGetInsertionPosition txtf))) (if (not (= val 5)) (snd-display #__line__ ";XmTextGetInsertionPosition: ~A" val)) (if (not (= valf 5)) (snd-display #__line__ ";XmTextFieldGetInsertionPosition: ~A" val))) (XmTextScroll txt 1) (XmTextScroll txt -1) (let ((pos (XmTextGetTopCharacter txt))) (if (not (= pos 0)) (snd-display #__line__ ";XmTextGetTopCharacter after scroll: ~A" pos))) (XmTextShowPosition txt 0) (XmTextFieldShowPosition txtf 0) (XmTextSetTopCharacter txt 0) (XmTextXYToPos txt 10 10) (XmTextFieldXYToPos txtf 10 10) (XmTextSetHighlight txt 3 6 XmHIGHLIGHT_SELECTED) (XmTextFieldSetHighlight txtf 3 6 XmHIGHLIGHT_SELECTED) (XmTextFieldGetBaseline txtf) (XmTextSetAddMode txt #t) (if (not (XmTextGetAddMode txt)) (snd-display #__line__ ";XmTextSetAddMode?")) (XmTextFieldSetAddMode txtf #t) (if (not (XmTextFieldGetAddMode txtf)) (snd-display #__line__ ";XmTextFieldSetAddMode?")) (if (not (string=? (vector-ref calls 5) "gain")) (snd-display #__line__ ";gain callback: ~A" (vector-ref calls 5))) (if (not (string=? (vector-ref calls 7) "modify")) (snd-display #__line__ ";modify callback: ~A" (vector-ref calls 7))) (if (not (string=? (vector-ref calls 8) "motion")) (snd-display #__line__ ";motion callback: ~A" (vector-ref calls 8))) (if (not (string=? (vector-ref calls 9) "value")) (snd-display #__line__ ";value callback: ~A" (vector-ref calls 9))) (let ((txtf1 (XtVaCreateManagedWidget "textfield" xmTextFieldWidgetClass frm (list XmNeditable #t XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_WIDGET XmNtopWidget txt XmNbottomAttachment XmATTACH_FORM XmNdestinationCallback (list (lambda (w c info) (let* ((dpy (XtDisplay w)) (TARGETS (XmInternAtom dpy "TARGETS" #f))) (XmTransferValue (.transfer_id info) TARGETS transfer-proc #f (XtLastTimestampProcessed dpy)))) #f))))) (focus-widget txtf1) (XmTextFieldPaste txtf1) (XmTextFieldPasteLink txtf1) (if (not (Widget? (XmGetTabGroup txtf1))) (snd-display #__line__ ";XmGetTabGroup: ~A " (XmGetTabGroup txtf1))) (let ((fw (XmGetFocusWidget (cadr (main-widgets))))) (if (not (equal? fw txtf1)) (snd-display #__line__ ";XmGetFocusWidget: ~A" fw))) (let ((callback (lambda (w context ev flag) (XtSetValues w (list XmNbackground (white-pixel)))))) (XtAddEventHandler txtf1 EnterWindowMask #f callback #f) (XtRemoveEventHandler txtf1 EnterWindowMask #f callback #f) (XtAddRawEventHandler txtf1 EnterWindowMask #f callback #f) (XtRemoveRawEventHandler txtf1 EnterWindowMask #f callback #f) (XtInsertEventHandler txtf1 EnterWindowMask #f callback #f XtListHead) (XtRemoveEventHandler txtf1 EnterWindowMask #f callback #f) (XtInsertRawEventHandler txtf1 EnterWindowMask #f callback #f XtListTail) (XtRemoveRawEventHandler txtf1 EnterWindowMask #f callback #f)) (XtRemoveAllCallbacks txtf1 XmNdestinationCallback)) (XtAppAddActions (car (main-widgets)) (list (list "hiho" (lambda args (snd-print "hiho"))))) (XtAugmentTranslations txt (XtParseTranslationTable "Ctrl i: hiho()\n")) (XtCallActionProc txt "hiho" (XEvent) #f 0) (XtUninstallTranslations txt) (XtUnmanageChild frm))) (let* ((shell (cadr (main-widgets))) (dpy (XtDisplay shell)) (win (XtWindow shell)) (err (XmClipboardRegisterFormat dpy "SND_DATA" 8))) (if (not (= err ClipboardSuccess)) (snd-display #__line__ ";XmClipboardRegisterFormat: ~A" err) (let ((vals (XmClipboardStartCopy dpy win (XmStringCreateLocalized "SND_DATA") (list 'Time CurrentTime) shell (lambda (w id pid reason) (XmClipboardCopyByName dpy win id "copy this" 10 123))))) (if (not (= (car vals) ClipboardSuccess)) (snd-display #__line__ ";XmClipboardStartCopy: ~A" vals) (let ((data-id (cadr vals))) (set! err (XmClipboardCopy dpy win data-id "SND_DATA" "copy this" 10 0)) (if (not (= (car err) ClipboardSuccess)) (snd-display #__line__ ";XmClipboardCopy: ~A" err)) (let ((item-id (cadr err))) (set! err (XmClipboardEndCopy dpy win data-id)) (if (not (= err ClipboardSuccess)) (snd-display #__line__ ";copy ~A" err)) (if (not (= (cadr (XmClipboardInquireLength dpy win "SND_DATA")) 10)) (snd-display #__line__ ";clip len: ~A" (XmClipboardInquireLength dpy win "SND_DATA"))) (let ((pend (XmClipboardInquirePendingItems dpy win "SND_DATA"))) (if (not (= (car pend) ClipboardSuccess)) (snd-display #__line__ ";XmClipboardInquirePendingItems: ~A" pend))) (let ((formats1 (XmClipboardInquireCount dpy win))) (if (= (cadr formats1) 0) (snd-display #__line__ ";XmClipboardInquireCount: ~A" formats1)) (XmClipboardInquireFormat dpy win 1 10) (let ((clip (XmClipboardRetrieve dpy win "SND_DATA" 10))) (if (not (string=? (cadr clip) "copy this")) (snd-display #__line__ ";XmClipboardRetrieve: ~A" clip)) (XmClipboardWithdrawFormat dpy win item-id)))))))) (let ((val (XmClipboardLock dpy win))) (if (not (= val ClipboardLocked)) (XmClipboardUnlock dpy win #t))) (let ((selbox (XmCreateSelectionBox shell "selbox" () 0))) (XmSelectionBoxGetChild selbox XmDIALOG_APPLY_BUTTON))) (let* ((frm (add-main-pane "hi" xmFormWidgetClass (list XmNpaneMinimum 120))) (current-time (list 'Time CurrentTime)) (box (XtCreateManagedWidget "box" xmContainerWidgetClass frm ())) (tgl (XtCreateManagedWidget "tgl" xmToggleButtonWidgetClass frm (list XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_NONE))) (tgg (XtCreateManagedWidget "tgg" xmToggleButtonGadgetClass frm (list XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_WIDGET XmNtopWidget tgl XmNbottomAttachment XmATTACH_NONE))) (spn (XtCreateManagedWidget "spn" xmSimpleSpinBoxWidgetClass frm (list XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_WIDGET XmNtopWidget tgg XmNbottomAttachment XmATTACH_NONE))) (cmd (XtCreateManagedWidget "cmd" xmCommandWidgetClass frm (list XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_WIDGET XmNtopWidget spn XmNbottomAttachment XmATTACH_NONE))) (scl (XtCreateManagedWidget "scl" xmScaleWidgetClass frm (list XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_WIDGET XmNtopWidget cmd XmNbottomAttachment XmATTACH_NONE))) (notes (XtCreateManagedWidget "notes" xmNotebookWidgetClass frm (list XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_WIDGET XmNtopWidget scl XmNbottomAttachment XmATTACH_NONE))) (cmb (XtCreateManagedWidget "cmb" xmComboBoxWidgetClass frm (list XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_WIDGET XmNtopWidget notes XmNbottomAttachment XmATTACH_FORM))) (toggled 0)) (XtCreateManagedWidget "one" xmPushButtonWidgetClass notes ()) (XtCreateManagedWidget "two" xmPushButtonWidgetClass notes ()) (let ((info (cadr (XmNotebookGetPageInfo notes 1)))) (if (not (= (.page_number info) 1)) (snd-display #__line__ ";page_number: ~A" (.page_number info))) (if (.page_widget info) (snd-display #__line__ ";page_widget: ~A" (.page_widget info))) (if (.status_area_widget info) (snd-display #__line__ ";status_area_widget: ~A" (.status_area_widget info))) (if (not (Widget? (.major_tab_widget info))) (snd-display #__line__ ";major_tab_widget: ~A" (.major_tab_widget info))) (if (.minor_tab_widget info) (snd-display #__line__ ";minor_tab_widget: ~A" (.minor_tab_widget info))) ;(segfault) (XtFree (cadr info)) ) (XmSimpleSpinBoxAddItem spn (XmStringCreateLocalized "hiho") 0) (XmSimpleSpinBoxAddItem spn (XmStringCreateLocalized "away") 0) (XmSimpleSpinBoxDeletePos spn 0) (let ((vals (XtVaGetValues spn (list XmNvalues 0)))) (XmSimpleSpinBoxSetItem spn (caadr vals))) (XmSimpleSpinBoxAddItem spn (XmStringCreateLocalized "another") 0) (let ((vals (XtGetValues spn (list XmNeditable 0 XmNtextField 0)))) (if (not (vals 1)) (snd-display #__line__ ";XmNeditable spin box")) (if (not (Widget? (vals 3))) (snd-display #__line__ ";XmNtextField: ~A" (vals 3)))) (XtAddCallback tgl XmNvalueChangedCallback (lambda (w c i) (set! toggled 123)) #f) (XmToggleButtonSetState tgl #f #f) (XmToggleButtonGadgetSetState tgg #f #f) (if (not (= toggled 0)) (snd-display #__line__ ";toggle calledback: ~A?" toggled)) (if (XmToggleButtonGetState tgl) (snd-display #__line__ ";XmToggleButtonSetState #f")) (if (XmToggleButtonGadgetGetState tgg) (snd-display #__line__ ";XmToggleButtonGadgetSetState #f")) (XtVaSetValues tgl (list XmNtoggleMode XmTOGGLE_INDETERMINATE)) (XmToggleButtonSetValue tgl XmINDETERMINATE #t) (XmToggleButtonGadgetSetValue tgg XmINDETERMINATE #t) (if (not (= toggled 123)) (snd-display #__line__ ";toggle not calledback: ~A?" toggled)) (XmCommandAppendValue cmd (XmStringCreateLocalized "hiho")) (XmCommandError cmd (XmStringCreateLocalized "hiho")) (if (not (Widget? (XmCommandGetChild cmd XmDIALOG_COMMAND_TEXT))) (snd-display #__line__ ";XmCommandGetChild: ~A" (XmCommandGetChild cmd XmDIALOG_COMMAND_TEXT))) (XmCommandSetValue cmd (XmStringCreateLocalized "hiho")) (let ((one1 (XmStringCreateLocalized "one")) (two1 (XmStringCreateLocalized "two")) (three1 (XmStringCreateLocalized "three"))) (XmComboBoxAddItem cmb one1 0 #f) (XmComboBoxAddItem cmb two1 0 #f) (XmComboBoxAddItem cmb three1 0 #f) (XmComboBoxDeletePos cmb 1) (XmComboBoxSelectItem cmb three1) (XmComboBoxSetItem cmb three1) ; hunh?? (XmComboBoxUpdate cmb) (let ((vals (cadr (XtGetValues cmb (list XmNitems 0))))) (if (not (equal? vals (list two1 three1))) (snd-display #__line__ ";XmComboBox: ~A" vals)))) (XmContainerCut box current-time) (XmContainerCopy box current-time) (XmContainerPaste box) (XmContainerCopyLink box (list 'Time CurrentTime)) (XmContainerPasteLink box) (let ((vals (XtVaGetValues box (list XmNlargeIconX 0 XmNlargeIconY 0)))) (if (or (null? (cdr vals)) (not (real? (cadr vals))) (fneq (cadr vals) 0.0) (null? (cdddr vals)) (not (real? (cadddr vals))) (fneq (cadddr vals) 0.0)) (snd-display #__line__ ";xm-float resource vals: ~A" vals))) (XtAddCallback scl XmNvalueChangedCallback (lambda (w c i) #f)) (XmScaleSetValue scl 25) (if (not (= (XmScaleGetValue scl) 25)) (snd-display #__line__ ";XmScaleSetValue: ~A" (XmScaleGetValue scl))) (if (XmGetTearOffControl (car (menu-widgets))) (snd-display #__line__ ";XmGetTearOffControl: ~A" (XmGetTearOffControl (car (menu-widgets))))) (let ((children (cadr (XtGetValues scl (list XmNchildren 0))))) (for-each (lambda (w) (let ((name (XtName w))) (if (and (XmIsSeparatorGadget w) (member name '("BigTic" "MedTic" "SmallTic") string=?)) (XtDestroyWidget w)))) children)) (XmScaleSetTicks scl 5 2 0 10 5 0) ) (XmSetColorCalculation #f) (let* ((dpy (XtDisplay (cadr (main-widgets)))) (scr1 (DefaultScreen dpy)) (cmap (DefaultColormap dpy scr1)) (screen (XDefaultScreenOfDisplay dpy)) (scr (XmGetXmScreen (XDefaultScreenOfDisplay dpy))) ;(old-h (cadr (XtVaGetValues scr (list XmNhorizontalFontUnit 0)))) ;(old-v (cadr (XtVaGetValues scr (list XmNverticalFontUnit 0)))) ) (if (not (XmIsScreen scr)) (snd-display #__line__ ";XmIsScreen: ~A" scr)) (let ((colors (XmGetColors screen cmap *basic-color*))) (if (not (Pixel? (car colors))) (snd-display #__line__ ";colors: ~A " colors)) (let ((color-proc (lambda (bg) (list (white-pixel) (black-pixel) (white-pixel) (black-pixel))))) (XmSetColorCalculation color-proc) (if (not (equal? (XmGetColorCalculation) color-proc)) (snd-display #__line__ ";XmSetColorcalulcation ~A" (XmGetColorCalculation))))) (let ((vals (XtVaGetValues scr (list XmNbitmapConversionModel 0 XmNdarkThreshold 0 XmNfont 0 XmNunpostBehavior 0)))) (if (not (= (vals 1) XmMATCH_DEPTH)) (snd-display #__line__ ";XmNbitmapConversionModel: ~A" (vals 1))) (if (not (= (vals 3) 0)) (snd-display #__line__ ";XmNdarkThreshold: ~A" (vals 3))) (if (not (XFontStruct? (vals 5))) (snd-display #__line__ ";XmNfont: ~A" (vals 5))) (if (not (= (vals 7) XmUNPOST_AND_REPLAY)) (snd-display #__line__ ";XmNunpostBehavior: ~A" (vals 7))) (XSetScreenSaver dpy -1 5 DefaultBlanking DefaultExposures) )) (let ((dpy (XtDisplay (cadr (main-widgets))))) (let* ((dp (XmGetXmDisplay dpy)) (vals (XtVaGetValues dp (list XmNdragInitiatorProtocolStyle 0 XmNenableThinThickness 0 XmNmotifVersion 0)))) (if (not (XmIsDisplay dp)) (snd-display #__line__ ";XmIsDisplay: ~A" dp)) (if (not (= (vals 1) XmDRAG_PREFER_RECEIVER)) (snd-display #__line__ ";XmNdragInitiatorProtocolStyle: ~A" (vals 1))) (if (not (vals 3)) (snd-display #__line__ ";XmNenableThinThickness?")) (if (not (= (vals 5) 2002)) (snd-display #__line__ ";XmGetXmDisplay motif version: ~A" (vals 5))) (XtAddCallback dp XmNdragStartCallback (lambda (w c i) #f))) (if (not (string=? (XmCvtXmStringToCT (XmStringCreateLocalized "hiho")) "hiho")) (snd-display #__line__ ";XmCvtXmStringToCT: ~A" (XmCvtXmStringToCT (XmStringCreateLocalized "hiho")))) (let ((val (XmConvertStringToUnits (XDefaultScreenOfDisplay dpy) "3.14 in" XmHORIZONTAL XmINCHES))) (if (not (= val 3)) (snd-display #__line__ ";XmConvertStringToUnits in->in ~A" val))) (let ((val (XmConvertStringToUnits (XDefaultScreenOfDisplay dpy) "3.14 in" XmHORIZONTAL XmPOINTS))) (if (not (= val 225)) (snd-display #__line__ ";XmConvertStringToUnits in->pts ~A" val))) (let ((val (XmConvertStringToUnits (XDefaultScreenOfDisplay dpy) "3.14 in" XmHORIZONTAL XmCENTIMETERS))) (if (not (= val 7)) (snd-display #__line__ ";XmConvertStringToUnits in->cm ~A" val))) (let ((val (XmConvertUnits (cadr (main-widgets)) XmHORIZONTAL XmCENTIMETERS 7 XmMILLIMETERS))) (if (not (= val 70)) (snd-display #__line__ ";XmConvertUnits cm->mm ~A" val))) (let ((val (XmConvertUnits (cadr (main-widgets)) XmHORIZONTAL XmCENTIMETERS 7 XmPIXELS))) (if (and (not (= val 278)) (not (= val 273))) (snd-display #__line__ ";XmConvertUnits cm->pix ~A" val))) (XmVaCreateSimpleRadioBox (caddr (main-widgets)) "hiho" 0 (lambda (w c i) #f) ()) (XmVaCreateSimpleCheckBox (caddr (main-widgets)) "hiho" (lambda (w c i) #f) ()) (XmVaCreateSimplePulldownMenu (caddr (main-widgets)) "hiho" 0 (lambda (w c i) #f) ()) (XmVaCreateSimplePopupMenu (caddr (main-widgets)) "hiho" (lambda (w c i) #f) ()) (XmVaCreateSimpleMenuBar (caddr (main-widgets)) "hiho" ()) (zync) (make-pixmap (cadr (main-widgets)) arrow-strs) ;(display-scanned-synthesis) -- needs updating (add-mark-pane) (let ((ind (open-sound "oboe.snd"))) (snd-clock-icon ind 6) (add-tooltip (cadr (channel-widgets)) "the w button") (with-minmax-button ind) (make-channel-drop-site ind 0) (set-channel-drop (lambda (file s c) (snd-print file)) ind 0) (let ((drop-site (find-child (XtParent (XtParent ((channel-widgets ind 0) 7))) "drop here"))) (if drop-site (begin (XtVaGetValues drop-site (list XmNdropRectangles 0)) (let ((val (XmDropSiteRetrieve drop-site (list XmNnumImportTargets 0)))) (if (not (= (cadr val) 1)) (snd-display #__line__ ";XmDropSiteRetrieve num: ~A" val))) (XmDropSiteRetrieve drop-site (list XmNimportTargets 0)) (if (not (XmDropSiteRegistered drop-site)) (snd-display #__line__ ";XmDropSiteRegistered?")) (XmDropSiteUnregister drop-site)) (snd-display #__line__ ";no drop site?")))) (add-mark 123) (let ((container (make-sound-box "sounds" ((main-widgets) 3) (lambda (file) (mix file)) (lambda (file chn) (define (without-directories filename) (call-with-exit (lambda (return) (do ((i (- (length filename) 1) (- i 1))) ((= i 0) filename) (if (char=? (filename i) #\/) (return (substring filename (+ i 1)))))))) (format #f "~~/peaks/~A-peaks-~D" (snd-test-clean-string (mus-expand-filename file)) chn)) (list "oboe.snd" "pistol.snd" "cardinal.snd" "storm.snd") ()))) (XmContainerRelayout container) (let ((vals (XtVaGetValues container (list XmNlargeCellHeight 0 XmNcollapsedStatePixmap 0 XmNdetailOrder 0 XmNdetailTabList 0 XmNselectedObjects 0 XmNconvertCallback 0 XmNdestinationCallback 0 XmNselectionCallback 0)))) (if (not (= (vals 1) 0)) (snd-display #__line__ ";XmNlargeCellHeight: ~A" (vals 1))) (if (not (Pixmap? (vals 3))) (snd-display #__line__ ";XmNcollapsedStatePixmap: ~A" (vals 3))) (let ((children ())) (for-each-child container (lambda (w) (if (XmIsIconGadget w) (set! children (cons w children))))) (XmContainerReorder container children (length children))) (let ((func (lambda (w) 0))) (XtSetValues container (list XmNinsertPosition func)) (let ((func1 (cadr (XtGetValues container (list XmNinsertPosition 0))))) (if (not (equal? func func1)) (snd-display #__line__ ";XmNinsertPosition: ~A ~A" func func1)))))) (close-sound)) ;; qualify proc is causing a segfault somehow ; (let ((box (XmCreateFileSelectionBox (cadr (main-widgets)) "box" ; (list XmNfileSearchProc (lambda (w c) #f) ; XmNqualifySearchDataProc (lambda (w c i) ; (display "qualifier was called!") ; ))))) ; (XtUnmanageChild box)) (let ((hi (XtCreateManagedWidget "hi" xmTextWidgetClass (cadr (main-widgets)) (list XmNqualifySearchDataProc (lambda (w c i) "hi") XmNtransferProc (lambda (a b c d e f g) "ho") XmNcolorAllocationProc (lambda (a b c) #f) XmNcolorCalculationProc (lambda (a b) #f) XmNcreatePopupChildProc (lambda (a) #f) XmNlargeIconX 0.5 )))) (XtVaSetValues hi (list XmNqualifySearchDataProc (lambda (w c i) "hi") XmNtransferProc (lambda (a b c d e f g) "ho") XmNcolorAllocationProc (lambda (a b c) #f) XmNcolorCalculationProc (lambda (a b) #f) XmNcreatePopupChildProc (lambda (a) #f))) (XtVaSetValues hi (list XmNqualifySearchDataProc #f XmNcolorAllocationProc #f XmNcolorCalculationProc #f XmNcreatePopupChildProc #f XmNx 10 XmNsource (XmTextGetSource hi) )) (XtUnmanageChild hi)) (if (and (defined? 'XmCreateFontSelector) (defined? 'XmCreateColorSelector)) (let ((fonts-dialog #f) (colors-dialog #f)) (for-each (lambda (make-dialog) (let* ((xdismiss (XmStringCreate "Dismiss" XmFONTLIST_DEFAULT_TAG)) (xhelp (XmStringCreate "Help" XmFONTLIST_DEFAULT_TAG)) (xok (XmStringCreate "DoIt" XmFONTLIST_DEFAULT_TAG)) (titlestr (XmStringCreate "Fonts" XmFONTLIST_DEFAULT_TAG)) (new-dialog (XmCreateTemplateDialog (cadr (main-widgets)) "Fonts" (list XmNcancelLabelString xdismiss XmNhelpLabelString xhelp XmNokLabelString xok XmNautoUnmanage #f XmNdialogTitle titlestr XmNresizePolicy XmRESIZE_GROW XmNnoResize #f XmNbackground *basic-color* XmNtransient #f)))) (XtAddCallback new-dialog XmNcancelCallback (lambda (w c i) (XtUnmanageChild w))) (XtAddCallback new-dialog XmNhelpCallback (lambda (w c i) (help-dialog "Fonts" "no help yet"))) (XtAddCallback new-dialog XmNokCallback (lambda (w c i) (XtUnmanageChild w))) (XmStringFree xhelp) (XmStringFree xok) (XmStringFree xdismiss) (XmStringFree titlestr) (if (not fonts-dialog) (set! fonts-dialog new-dialog) (set! colors-dialog new-dialog)) (let* ((mainform (XtCreateManagedWidget "mainform" xmFormWidgetClass new-dialog (list XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_WIDGET XmNbottomWidget (XmMessageBoxGetChild new-dialog XmDIALOG_SEPARATOR) XmNbackground *basic-color*))) (fnts (make-dialog mainform))) (XtManageChild fnts) (if (not colors-dialog) (XtManageChild fonts-dialog) (XtManageChild colors-dialog))))) (list (lambda (mainform) (XmCreateFontSelector mainform "Fonts" (list XmNbackground *basic-color* XmNcurrentFont "-*-times-bold-r-*-*-14-140-*-*-*-*-*-*" XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_NONE))) (lambda (mainform) (XmCreateColorSelector mainform "Colors" (list XmNbackground *basic-color* XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_NONE))))) (XtUnmanageChild fonts-dialog) (XtUnmanageChild colors-dialog))) (let* ((xdismiss (XmStringCreate "Dismiss" XmFONTLIST_DEFAULT_TAG)) (xhelp (XmStringCreate "Help" XmFONTLIST_DEFAULT_TAG)) (xok (XmStringCreate "DoIt" XmFONTLIST_DEFAULT_TAG)) (titlestr (XmStringCreate "Fonts" XmFONTLIST_DEFAULT_TAG)) (new-dialog (XmCreateTemplateDialog (cadr (main-widgets)) "Fonts" (list XmNcancelLabelString xdismiss XmNhelpLabelString xhelp XmNokLabelString xok XmNautoUnmanage #f XmNdialogTitle titlestr XmNresizePolicy XmRESIZE_GROW XmNnoResize #f XmNbackground *basic-color* XmNtransient #f)))) (XmStringFree xhelp) (XmStringFree xok) (XmStringFree xdismiss) (XmStringFree titlestr) (let* ((mainform (XtCreateManagedWidget "mainform" xmFormWidgetClass new-dialog (list XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_WIDGET XmNbottomWidget (XmMessageBoxGetChild new-dialog XmDIALOG_SEPARATOR) XmNbackground *basic-color*))) (fnts (and (defined? 'XmIsColumn) (let* ((w1 (XmCreateColumn mainform "column" ())) (w1-child (XtCreateManagedWidget "hihi" xmLabelWidgetClass w1 () 0)) (w2 (XtCreateManagedWidget "column1" xmColumnWidgetClass mainform () 0))) (if (or (not (XmIsColumn w1)) (not (XmIsColumn w2)) (not (XmColumn? w1))) (snd-display #__line__ ";XmIsColumn: ~A ~A" w1 w2)) (if (defined? 'XmColumnGetChildLabel) (let ((child (XmColumnGetChildLabel w1))) (if (or (not (child)) (not (equal? child w1-child))) (snd-display #__line__ ";XmColumn child: ~A ~A" child w1-child)))) (XtManageChild w1) w1))) (fntt (and (defined? 'XmIsButtonBox) (let ((w1 (XmCreateButtonBox mainform "box" (list XmNfillOption XmFillMajor)))) (if (or (not (XmIsButtonBox w1)) (not (XmButtonBox? w1))) (snd-display #__line__ ";XmIsButtonBox: ~A ~A ~A" w1 (XmIsButtonBox w1) (XmButtonBox? w1))) (XtManageChild w1) w1))) (fntd (and (defined? 'XmIsDropDown) (let ((w1 (XmCreateDropDown mainform "drop" ()))) (if (or (not (XmIsDropDown w1)) (not (XmDropDown? w1))) (snd-display #__line__ ";XmIsDropDown: ~A ~A ~A" w1 (XmIsDropDown w1) (XmDropDown? w1))) (XtManageChild w1) (let ((text (XmDropDownGetText w1)) (label (XmDropDownGetLabel w1)) (arrow (XmDropDownGetArrow w1)) (lst (XmDropDownGetList w1))) (XmDropDownGetValue w1) (if (not (XmTextField? text)) (snd-display #__line__ ";dropdown text: ~A" text)) (if (not (XmLabel? label)) (snd-display #__line__ ";dropdown label: ~A" label)) (if (not (XmArrowButton? arrow)) (snd-display #__line__ ";dropdown arrow: ~A" arrow)) (if (not (XmList? lst)) (snd-display #__line__ ";dropdown lst: ~A" text)) w1)))) (fntda (and (defined? 'XmIsDataField) (let ((w1 (XmCreateDataField mainform "data" ()))) (if (or (not (XmIsDataField w1)) (not (XmDataField? w1))) (snd-display #__line__ ";XmIsDataField: ~A ~A ~A" w1 (XmIsDataField w1) (XmDataField? w1))) (XmDataFieldGetString w1) (XmDataFieldGetSelection w1) (XmDataFieldSetString w1 "hiho") (XmDataFieldSetEditable w1 #t) (XmDataFieldSetAddMode w1 #f) (XmDataFieldShowPosition w1 0) (XmDataFieldXYToPos w1 0 0) (XmDataFieldSetHighlight w1 0 0 0) (XmDataFieldGetSelectionPosition w1) (XmDataFieldSetSelection w1 0 0 '(Time 0)) (XmDataFieldCopy w1 '(Time 0)) (XmDataFieldCut w1 '(Time 0)) w1))) (fnttab (and (defined? 'XmIsTabStack) (let ((w1 (XmCreateTabStack mainform "hi" ()))) (if (or (not (XmIsTabStack w1)) (not (XmTabStack? w1))) (snd-display #__line__ ";XmIsTabStack: ~A ~A ~A" w1 (XmIsTabStack w1) (XmTabStack? w1))) (XmTabStackGetSelectedTab w1) (XmTabStackSelectTab w1 #f) w1)))) (if (and (defined? 'XmToolTipGetLabel) (defined? 'XmNtoolTipString)) (let ((wid1 (XtCreateManagedWidget "wid1" xmPushButtonWidgetClass mainform (list XmNtoolTipString (XmStringCreateLocalized "tooltip") XmNtoolTipPostDelay 100 XmNtoolTipPostDuration 500 XmNtoolTipEnable #t XmNanimate #f)))) (let ((tip (XmToolTipGetLabel wid1))) (if (not (Widget? tip)) (snd-display #__line__ ";tooltip label: ~A ~A ~A ~A ~A ~A" tip fnttab fntda fntd fntt fnts))))) (XtManageChild new-dialog) (XtUnmanageChild new-dialog))) (let* ((shell (cadr (main-widgets))) (dpy (XtDisplay shell)) (prop (XmInternAtom dpy "TESTING" #f)) (proto1 (XmInternAtom dpy "TEST1" #f)) (proto2 (XmInternAtom dpy "TEST2" #f)) (val 0)) (if (not (Atom? prop)) (snd-display #__line__ ";XmInternAtom: ~A" prop)) (if (not (string=? (XmGetAtomName dpy prop) "TESTING")) (snd-display #__line__ ";XmGetAtomName: ~A" (XmGetAtomName dpy prop))) (XmAddProtocols shell prop (list proto1 proto2)) (XmSetProtocolHooks shell (XmInternAtom dpy "WM_PROTOCOLS" #f) prop (lambda (w c i) (snd-display #__line__ ";prehook: ~A ~A ~A" w c i)) 12345 (lambda (w c i) (snd-display #__line__ ";posthook: ~A ~A ~A" w c i)) 54321) (XmDeactivateProtocol shell prop proto2) (XmRemoveProtocols shell prop (list proto2)) (XmAddProtocolCallback shell prop proto1 (lambda (w c i) (set! val c)) 123) (XmActivateProtocol shell prop proto1) (let ((e (XEvent ClientMessage)) (window (XtWindow shell))) (set! (.window e) window) (set! (.display e) dpy) (set! (.format e) (if val 8)) (set! (.message_type e) XA_STRING) (set! (.data e) "hiho") (XSendEvent dpy window #f 0 e)) (XmRemoveProtocols shell prop (list proto1))) (XmCascadeButtonHighlight (XmCreateCascadeButton (cadr (main-widgets)) "cascade" ()) #f) ;(XmCascadeButtonGadgetHighlight (XmCreateCascadeButtonGadget (cadr (main-widgets)) "gadget" ()) #f) (let ((callbacks (list (list XmAnyCallbackStruct (list .reason 'int '.reason) (list .event 'XEvent '.event)) (list XmArrowButtonCallbackStruct (list .reason 'int '.reason) (list .event 'XEvent '.event) (list .click_count 'int '.click_count)) (list XmCommandCallbackStruct (list .reason 'int '.reason) (list .event 'XEvent '.event) (list .value 'XmString '.value) (list .length 'int '.length #f)) (list XmDragDropFinishCallbackStruct (list .reason 'int '.reason) (list .event 'XEvent '.event) (list .timeStamp 'Time '.timeStamp)) (list XmDragMotionCallbackStruct (list .reason 'int '.reason) (list .event 'XEvent '.event) (list .timeStamp 'Time '.timeStamp) (list .operation 'uchar '.operation) (list .operations 'uchar '.operations #f) (list .dropSiteStatus 'uchar '.dropSiteStatus) (list .x 'Position '.x #f) (list .y 'Position '.y #f)) (list XmDragProcCallbackStruct (list .reason 'int '.reason) (list .event 'XEvent '.event) (list .timeStamp 'Time '.timeStamp) (list .dragContext 'Widget '.dragContext #f) (list .x 'Position '.x #f) (list .y 'Position '.y #f) (list .dropSiteStatus 'uchar '.dropSiteStatus) (list .operation 'uchar '.operation) (list .operations 'uchar '.operations #f) (list .animate 'Boolean '.animate #f)) (list XmDrawingAreaCallbackStruct (list .reason 'int '.reason) (list .event 'XEvent '.event) (list .window 'Window '.window)) (list XmDrawnButtonCallbackStruct (list .reason 'int '.reason) (list .event 'XEvent '.event) (list .window 'Window '.window) (list .click_count 'int '.click_count)) (list XmDropFinishCallbackStruct (list .reason 'int '.reason) (list .event 'XEvent '.event) (list .timeStamp 'Time '.timeStamp) (list .operation 'uchar '.operation) (list .operations 'uchar '.operations #f) (list .dropSiteStatus 'uchar '.dropSiteStatus) (list .dropAction 'uchar '.dropAction #f) (list .completionStatus 'uchar '.completionStatus #f)) (list XmDropProcCallbackStruct (list .reason 'int '.reason) (list .event 'XEvent '.event) (list .timeStamp 'Time '.timeStamp) (list .dragContext 'Widget '.dragContext #f) (list .x 'Position '.x #f) (list .y 'Position '.y #f) (list .dropSiteStatus 'uchar '.dropSiteStatus) (list .operation 'uchar '.operation) (list .operations 'uchar '.operations #f) (list .dropAction 'uchar '.dropAction #f)) (list XmDropSiteEnterCallbackStruct (list .reason 'int '.reason) (list .event 'XEvent '.event) (list .timeStamp 'Time '.timeStamp) (list .operation 'uchar '.operation) (list .operations 'uchar '.operations #f) (list .dropSiteStatus 'uchar '.dropSiteStatus) (list .x 'Position '.x #f) (list .y 'Position '.y #f)) (list XmDropSiteLeaveCallbackStruct (list .reason 'int '.reason) (list .event 'XEvent '.event) (list .timeStamp 'Time '.timeStamp)) (list XmDropStartCallbackStruct (list .reason 'int '.reason) (list .event 'XEvent '.event) (list .timeStamp 'Time '.timeStamp) (list .operation 'uchar '.operation) (list .operations 'uchar '.operations #f) (list .dropSiteStatus 'uchar '.dropSiteStatus) (list .dropAction 'uchar '.dropAction #f)) (list XmFileSelectionBoxCallbackStruct (list .reason 'int '.reason) (list .event 'XEvent '.event) (list .value 'XmString '.value) (list .length 'int '.length #f) (list .mask 'XmString '.mask #f) (list .mask_length 'int '.mask_length #f) (list .dir 'XmString '.dir #f) (list .dir_length 'int '.dir_length #f) (list .pattern 'XmString '.pattern #f) (list .pattern_length 'int '.pattern_length #f)) (list XmListCallbackStruct (list .reason 'int '.reason) (list .event 'XEvent '.event) (list .item 'XmString '.item #f) (list .item_length 'int '.item_length #f) (list .item_position 'int '.item_position #f) (list .selected_items 'XmString* '.selected_items) (list .selected_item_count 'int '.selected_item_count #f) (list .selected_item_positions 'int* '.selected_item_positions) (list .selection_type 'char '.selection_type #f) (list .auto_selection_type 'char '.auto_selection_type #f)) (list XmOperationChangedCallbackStruct (list .reason 'int '.reason) (list .event 'XEvent '.event) (list .timeStamp 'Time '.timeStamp) (list .operation 'uchar '.operation) (list .operations 'uchar '.operations #f) (list .dropSiteStatus 'uchar '.dropSiteStatus)) (list XmPushButtonCallbackStruct (list .reason 'int '.reason) (list .event 'XEvent '.event) (list .click_count 'int '.click_count)) (list XmRowColumnCallbackStruct (list .reason 'int '.reason) (list .event 'XEvent '.event) (list .widget 'Widget '.widget #f) (list .data 'char* '.data #f) (list .callbackstruct 'char* '.callbackstruct #f)) (list XmScaleCallbackStruct (list .reason 'int '.reason) (list .event 'XEvent '.event) (list .value 'int '.value)) (list XmScrollBarCallbackStruct (list .reason 'int '.reason) (list .event 'XEvent '.event) (list .value 'int '.value) (list .pixel 'int '.pixel #f)) (list XmSelectionBoxCallbackStruct (list .reason 'int '.reason) (list .event 'XEvent '.event) (list .value 'XmString '.value) (list .length 'int '.length #f)) (list XmTextVerifyCallbackStruct (list .reason 'int '.reason) (list .event 'XEvent '.event) (list .doit 'Boolean '.doit) (list .currInsert 'int '.currInsert #f) (list .newInsert 'int '.newInsert #f) (list .startPos 'int '.startPos #f) (list .endPos 'int '.endPos #f) (list .text 'XmTextBlock '.text #f)) (list XmToggleButtonCallbackStruct (list .reason 'int '.reason) (list .event 'XEvent '.event) (list .set 'int '.set)) (list XmDestinationCallbackStruct (list .reason 'int '.reason) (list .event 'XEvent '.event) (list .selection 'Atom '.selection #f) (list .operation 'uchar '.operation) (list .flags 'int '.flags #f) (list .transfer_id 'XtPointer '.transfer_id #f) (list .destination_data 'XtPointer '.destination_data #f) (list .location_data 'XtPointer '.location_data #f) (list .time 'Time '.time)) (list XmConvertCallbackStruct (list .reason 'int '.reason) (list .event 'XEvent '.event) (list .selection 'Atom '.selection #f) (list .target 'Atom '.target #f) (list .source_data 'XtPointer '.source_data #f) (list .location_data 'XtPointer '.location_data #f) (list .flags 'int '.flags #f) (list .parm 'XtPointer '.parm #f) (list .parm_format 'int '.parm_format #f) (list .parm_length 'int '.parm_length #f) (list .parm_type 'Atom '.parm_type #f) (list .status 'int '.status #f) (list .value 'XtPointer '.value #f) (list .type 'Atom '.type #f) (list .format 'int '.format #f) (list .length 'int '.length #f)) (list XmComboBoxCallbackStruct (list .reason 'int '.reason) (list .event 'XEvent '.event) (list .item_or_text 'XmString '.item_or_text #f) (list .item_position 'int '.item_position #f)) (list XmContainerOutlineCallbackStruct (list .reason 'int '.reason) (list .event 'XEvent '.event) (list .item 'Widget '.item #f) (list .new_outline_state 'uchar '.new_outline_state #f)) (list XmContainerSelectCallbackStruct (list .reason 'int '.reason) (list .event 'XEvent '.event) (list .selected_items 'Widget* '.selected_items) (list .selected_item_count 'int '.selected_item_count #f) (list .auto_selection_type 'uchar '.auto_selection_type #f)) (list XmNotebookCallbackStruct (list .reason 'int '.reason) (list .event 'XEvent '.event) (list .page_number 'int '.page_number #f) (list .page_widget 'Widget '.page_widget #f) (list .prev_page_number 'int '.prev_page_number #f) (list .prev_page_widget 'Widget '.prev_page_widget #f)) (list XmSpinBoxCallbackStruct (list .reason 'int '.reason) (list .event 'XEvent '.event) (list .widget 'Widget '.widget #f) (list .doit 'Boolean '.doit) (list .position 'int '.position #f) (list .value 'XmString '.value #f) (list .crossed_boundary 'Boolean '.crossed-boundary #f)) (list XmTraverseObscuredCallbackStruct (list .reason 'int '.reason) (list .event 'XEvent '.event) (list .traversal_destination 'Widget '.traversal_destination #f)) (list XmTopLevelLeaveCallbackStruct (list .reason 'int '.reason) (list .event 'XEvent '.event) (list .timeStamp 'Time '.timeStamp) (list .screen 'Screen '.screen) (list .window 'Window '.window)) (list XmTopLevelEnterCallbackStruct (list .reason 'int '.reason) (list .event 'XEvent '.event) (list .timeStamp 'Time '.timeStamp) (list .screen 'Screen '.screen) (list .window 'Window '.window) (list .x 'Position '.x #f) (list .y 'Position '.y #f) (list .dragProtocolStyle 'uchar '.dragProtocolStyle #f)) (list XmPopupHandlerCallbackStruct (list .reason 'int '.reason) (list .event 'XEvent '.event) (list .menuToPost 'Widget '.menuToPost) (list .postIt 'Boolean '.postIt) (list .target 'Widget '.target #f)) (list XmSelectionCallbackStruct (list .reason 'int '.reason) (list .event 'XEvent '.event) (list .selection 'Atom '.selection #f) (list .target 'Atom '.target #f) (list .type 'Atom '.type #f) (list .transfer_id 'XtPointer '.transfer_id #f) (list .flags 'int '.flags #f) (list .remaining 'int '.remaining #f) (list .value 'XtPointer '.value #f) (list .length 'int '.length #f) (list .format 'int '.format #f)) (list XmTransferDoneCallbackStruct (list .reason 'int '.reason) (list .event 'XEvent '.event) (list .selection 'Atom '.selection #f) (list .transfer_id 'XtPointer '.transfer_id #f) (list .status 'int '.status #f) (list .client_data 'XtPointer '.client_data #f)) (list XmDisplayCallbackStruct (list .reason 'int '.reason) (list .event 'XEvent '.event) (list .font_name 'char* '.font_name #f) (list .tag 'int '.tag #f) (list .render_table 'XmRenderTable '.render_table #f) (list .rendition 'XmRendition '.rendition #f)) (list XmDragStartCallbackStruct (list .reason 'int '.reason) (list .event 'XEvent '.event) (list .widget 'Widget '.widget #f) (list .doit 'Boolean '.doit)) ))) (for-each (lambda (call) (let ((struct ((car call))) (val #f)) (set! (.event struct) (XEvent)) (for-each (lambda (field) (if (not (pair? field)) (snd-display #__line__ ";~A: ~A" struct field)) (set! val ((car field) struct)) (if (< (length field) 4) (case (cadr field) ((int Position XtPointer char) (set! ((car field) struct) 0)) ((Atom) (set! ((car field) struct) XA_STRING)) ((uchar) (set! ((car field) struct) val)) ((Widget) (set! ((car field) struct) (list 'Widget 0))) ((XmString) (set! ((car field) struct) (list 'XmString 0))) ((char*) (set! ((car field) struct) "hi")) ((XEvent Boolean XmString* int* Time Window Widget* Screen) #f) ))) (cdr call)))) callbacks) ) (let ((shell (cadr (main-widgets))) (resource-list (list (list XmNaccelerator XM_STRING) (list XmNacceleratorText XM_XMSTRING) (list XmNaccelerators XM_ULONG) (list XmNactivateCallback XM_CALLBACK) (list XmNadjustLast XM_BOOLEAN) (list XmNadjustMargin XM_BOOLEAN) (list XmNalignment XM_UCHAR) (list XmNallowOverlap XM_BOOLEAN) (list XmNallowResize XM_BOOLEAN) (list XmNallowShellResize XM_BOOLEAN) (list XmNancestorSensitive XM_BOOLEAN) (list XmNanimationMask XM_PIXMAP) (list XmNanimationPixmap XM_PIXMAP) (list XmNanimationPixmapDepth XM_INT) (list XmNanimationStyle XM_UCHAR) (list XmNapplyCallback XM_CALLBACK) (list XmNapplyLabelString XM_XMSTRING) (list XmNargc XM_INT) (list XmNargv XM_STRING_LIST) (list XmNarmCallback XM_CALLBACK) (list XmNarmColor XM_PIXEL) (list XmNarmPixmap XM_PIXMAP) (list XmNarrowDirection XM_UCHAR) (list XmNattachment XM_UCHAR) (list XmNaudibleWarning XM_UCHAR) (list XmNautoShowCursorPosition XM_BOOLEAN) (list XmNautoUnmanage XM_BOOLEAN) (list XmNautomaticSelection XM_UCHAR) (list XmNbackground XM_PIXEL) (list XmNbackgroundPixmap XM_PIXMAP) (list XmNbaseHeight XM_INT) (list XmNbaseWidth XM_INT) (list XmNbitmap XM_PIXMAP) (list XmNblendModel XM_ULONG) (list XmNblinkRate XM_INT) (list XmNborderColor XM_PIXEL) (list XmNborderPixmap XM_PIXMAP) (list XmNborderWidth XM_DIMENSION) (list XmNbottomAttachment XM_UCHAR) (list XmNbottomOffset XM_INT) (list XmNbottomPosition XM_INT) (list XmNbottomShadowColor XM_PIXEL) (list XmNbottomShadowPixmap XM_PIXMAP) (list XmNbottomWidget XM_WIDGET) (list XmNbrowseSelectionCallback XM_CALLBACK) (list XmNbuttonAcceleratorText XM_STRING_TABLE) (list XmNbuttonAccelerators XM_STRING_TABLE) (list XmNbuttonCount XM_INT) (list XmNbuttonMnemonicCharSets XM_CHARSET_TABLE) (list XmNbuttonMnemonics XM_KEYSYM_TABLE) (list XmNbuttonSet XM_INT) (list XmNbuttonType XM_ULONG) (list XmNbuttons XM_STRING_TABLE) (list XmNcancelButton XM_WIDGET) (list XmNcancelCallback XM_CALLBACK) (list XmNcancelLabelString XM_XMSTRING) (list XmNcascadePixmap XM_PIXMAP) (list XmNcascadingCallback XM_CALLBACK) (list XmNchildHorizontalAlignment XM_UCHAR) (list XmNchildHorizontalSpacing XM_DIMENSION) (list XmNchildPlacement XM_UCHAR) (list XmNchildVerticalAlignment XM_UCHAR) (list XmNchildren XM_WIDGET_LIST) (list XmNclientData XM_ULONG) (list XmNclipWindow XM_WIDGET) (list XmNcolormap XM_COLORMAP) (list XmNcolumns XM_SHORT) (list XmNcommand XM_XMSTRING) (list XmNcommandChangedCallback XM_CALLBACK) (list XmNcommandEnteredCallback XM_CALLBACK) (list XmNcommandWindow XM_WIDGET) (list XmNcommandWindowLocation XM_UCHAR) (list XmNconvertProc XM_CONVERT_CALLBACK) (list XmNcreatePopupChildProc XM_POPUP_CALLBACK) (list XmNcursorBackground XM_PIXEL) (list XmNcursorForeground XM_PIXEL) (list XmNcursorPosition XM_INT) (list XmNcursorPositionVisible XM_BOOLEAN) (list XmNdarkThreshold XM_INT) (list XmNdecimalPoints XM_SHORT) (list XmNdecrementCallback XM_CALLBACK) (list XmNdefaultActionCallback XM_CALLBACK) (list XmNdefaultButton XM_WIDGET) (list XmNdefaultButtonShadowThickness XM_DIMENSION) (list XmNdefaultButtonType XM_UCHAR) (list XmNdefaultCopyCursorIcon XM_WIDGET) (list XmNdefaultInvalidCursorIcon XM_WIDGET) (list XmNdefaultLinkCursorIcon XM_WIDGET) (list XmNdefaultMoveCursorIcon XM_WIDGET) (list XmNdefaultNoneCursorIcon XM_WIDGET) (list XmNdefaultPosition XM_BOOLEAN) (list XmNdefaultSourceCursorIcon XM_WIDGET) (list XmNdefaultValidCursorIcon XM_WIDGET) (list XmNdeleteResponse XM_UCHAR) (list XmNdepth XM_INT) (list XmNdestroyCallback XM_CALLBACK) (list XmNdialogStyle XM_UCHAR) (list XmNdialogTitle XM_XMSTRING) (list XmNdialogType XM_UCHAR) (list XmNdirListItemCount XM_INT) (list XmNdirListItems XM_STRING_TABLE) (list XmNdirListLabelString XM_XMSTRING) (list XmNdirMask XM_XMSTRING) (list XmNdirSearchProc XM_SEARCH_CALLBACK) (list XmNdirSpec XM_XMSTRING) (list XmNdirectory XM_XMSTRING) (list XmNdirectoryValid XM_BOOLEAN) (list XmNdisarmCallback XM_CALLBACK) (list XmNdoubleClickInterval XM_INT) (list XmNdragDropFinishCallback XM_CALLBACK) (list XmNdragInitiatorProtocolStyle XM_UCHAR) (list XmNdragMotionCallback XM_CALLBACK) (list XmNdragOperations XM_UCHAR) (list XmNdragReceiverProtocolStyle XM_UCHAR) (list XmNdropFinishCallback XM_CALLBACK) (list XmNdropProc XM_DROP_CALLBACK) (list XmNdropRectangles XM_RECTANGLE_LIST) (list XmNdropSiteActivity XM_UCHAR) (list XmNdropSiteEnterCallback XM_CALLBACK) (list XmNdropSiteLeaveCallback XM_CALLBACK) (list XmNdropSiteOperations XM_UCHAR) (list XmNdropSiteType XM_UCHAR) (list XmNdropStartCallback XM_CALLBACK) (list XmNdropTransfers XM_TRANSFER_ENTRY_LIST) (list XmNeditMode XM_INT) (list XmNeditable XM_BOOLEAN) (list XmNentryAlignment XM_UCHAR) (list XmNentryBorder XM_DIMENSION) (list XmNentryCallback XM_CALLBACK) (list XmNentryClass XM_WIDGET_CLASS) (list XmNentryVerticalAlignment XM_UCHAR) (list XmNexportTargets XM_ATOM_LIST) (list XmNexposeCallback XM_CALLBACK) (list XmNextendedSelectionCallback XM_CALLBACK) (list XmNfileListItemCount XM_INT) (list XmNfileListItems XM_STRING_TABLE) (list XmNfileListLabelString XM_XMSTRING) (list XmNfileSearchProc XM_SEARCH_CALLBACK) (list XmNfileTypeMask XM_UCHAR) (list XmNfillOnArm XM_BOOLEAN) (list XmNfillOnSelect XM_BOOLEAN) (list XmNfilterLabelString XM_XMSTRING) (list XmNfocusCallback XM_CALLBACK) (list XmNfont XM_XFONTSTRUCT) (list XmNforeground XM_PIXEL) (list XmNforegroundThreshold XM_INT) (list XmNfractionBase XM_INT) (list XmNgainPrimaryCallback XM_CALLBACK) (list XmNgeometry XM_STRING) (list XmNheight XM_DIMENSION) (list XmNheightInc XM_INT) (list XmNhelpCallback XM_CALLBACK) (list XmNhelpLabelString XM_XMSTRING) (list XmNhighlightColor XM_PIXEL) (list XmNhighlightOnEnter XM_BOOLEAN) (list XmNhighlightPixmap XM_PIXMAP) (list XmNhighlightThickness XM_DIMENSION) (list XmNhistoryItemCount XM_INT) (list XmNhistoryItems XM_STRING_TABLE) (list XmNhistoryMaxItems XM_INT) (list XmNhistoryVisibleItemCount XM_INT) (list XmNhorizontalFontUnit XM_INT) (list XmNhorizontalScrollBar XM_WIDGET) (list XmNhorizontalSpacing XM_DIMENSION) (list XmNhotX XM_POSITION) (list XmNhotY XM_POSITION) (list XmNiconMask XM_PIXMAP) (list XmNiconName XM_STRING) (list XmNiconNameEncoding XM_ATOM) (list XmNiconPixmap XM_PIXMAP) (list XmNiconWindow XM_WIDGET) (list XmNiconX XM_INT) (list XmNiconY XM_INT) (list XmNiconic XM_BOOLEAN) (list XmNimportTargets XM_ATOM_LIST) (list XmNincrement XM_INT) (list XmNincrementCallback XM_CALLBACK) (list XmNincremental XM_BOOLEAN) (list XmNindicatorOn XM_INT) (list XmNindicatorSize XM_DIMENSION) (list XmNindicatorType XM_UCHAR) (list XmNinitialDelay XM_INT) (list XmNinitialFocus XM_WIDGET) (list XmNinitialResourcesPersistent XM_BOOLEAN) (list XmNinitialState XM_INT) (list XmNinput XM_BOOLEAN) (list XmNinputCallback XM_CALLBACK) (list XmNinputMethod XM_STRING) (list XmNinsertPosition XM_ORDER_CALLBACK) (list XmNinvalidCursorForeground XM_PIXEL) (list XmNisAligned XM_BOOLEAN) (list XmNisHomogeneous XM_BOOLEAN) (list XmNitemCount XM_INT) (list XmNitems XM_STRING_TABLE) (list XmNkeyboardFocusPolicy XM_UCHAR) (list XmNlabelInsensitivePixmap XM_PIXMAP) (list XmNlabelPixmap XM_PIXMAP) (list XmNlabelString XM_XMSTRING) (list XmNlabelType XM_UCHAR) (list XmNleftAttachment XM_UCHAR) (list XmNleftOffset XM_INT) (list XmNleftPosition XM_INT) (list XmNleftWidget XM_WIDGET) (list XmNlightThreshold XM_INT) (list XmNlistItemCount XM_INT) (list XmNlistItems XM_STRING_TABLE) (list XmNlistLabelString XM_XMSTRING) (list XmNlistMarginHeight XM_DIMENSION) (list XmNlistMarginWidth XM_DIMENSION) (list XmNlistSizePolicy XM_UCHAR) (list XmNlistSpacing XM_DIMENSION) (list XmNlistUpdated XM_BOOLEAN) (list XmNlistVisibleItemCount XM_INT) (list XmNlosePrimaryCallback XM_CALLBACK) (list XmNlosingFocusCallback XM_CALLBACK) (list XmNmainWindowMarginHeight XM_DIMENSION) (list XmNmainWindowMarginWidth XM_DIMENSION) (list XmNmapCallback XM_CALLBACK) (list XmNmappedWhenManaged XM_BOOLEAN) (list XmNmappingDelay XM_INT) (list XmNmargin XM_DIMENSION) (list XmNmarginBottom XM_DIMENSION) (list XmNmarginHeight XM_DIMENSION) (list XmNmarginLeft XM_DIMENSION) (list XmNmarginRight XM_DIMENSION) (list XmNmarginTop XM_DIMENSION) (list XmNmarginWidth XM_DIMENSION) (list XmNmask XM_PIXMAP) (list XmNmaxAspectX XM_INT) (list XmNmaxAspectY XM_INT) (list XmNmaxHeight XM_INT) (list XmNmaxLength XM_INT) (list XmNmaxWidth XM_INT) (list XmNmaximum XM_INT) (list XmNmenuAccelerator XM_STRING) (list XmNmenuBar XM_WIDGET) (list XmNmenuCursor XM_STRING) (list XmNmenuHelpWidget XM_WIDGET) (list XmNmenuHistory XM_WIDGET) (list XmNmenuPost XM_STRING) (list XmNmessageAlignment XM_UCHAR) (list XmNmessageString XM_XMSTRING) (list XmNmessageWindow XM_WIDGET) (list XmNminAspectX XM_INT) (list XmNminAspectY XM_INT) (list XmNminHeight XM_INT) (list XmNminWidth XM_INT) (list XmNminimizeButtons XM_BOOLEAN) (list XmNminimum XM_INT) (list XmNmnemonic XM_KEYSYM) (list XmNmnemonicCharSet XM_STRING) (list XmNmodifyVerifyCallback XM_CALLBACK) (list XmNmotionVerifyCallback XM_CALLBACK) (list XmNmoveOpaque XM_BOOLEAN) (list XmNmultiClick XM_UCHAR) (list XmNmultipleSelectionCallback XM_CALLBACK) (list XmNmustMatch XM_BOOLEAN) (list XmNmwmDecorations XM_INT) (list XmNmwmFunctions XM_INT) (list XmNmwmInputMode XM_INT) (list XmNmwmMenu XM_STRING) (list XmNnavigationType XM_UCHAR) (list XmNnoMatchCallback XM_CALLBACK) (list XmNnoMatchString XM_XMSTRING) (list XmNnoResize XM_BOOLEAN) (list XmNnoneCursorForeground XM_PIXEL) (list XmNnumChildren XM_INT) (list XmNnumColumns XM_SHORT) (list XmNnumDropRectangles XM_INT) (list XmNnumDropTransfers XM_INT) (list XmNnumExportTargets XM_INT) (list XmNnumImportTargets XM_INT) (list XmNoffsetX XM_POSITION) (list XmNoffsetY XM_POSITION) (list XmNokCallback XM_CALLBACK) (list XmNokLabelString XM_XMSTRING) (list XmNoperationChangedCallback XM_CALLBACK) (list XmNoperationCursorIcon XM_WIDGET) (list XmNoptionLabel XM_XMSTRING) (list XmNoptionMnemonic XM_KEYSYM) (list XmNorientation XM_UCHAR) (list XmNoverrideRedirect XM_BOOLEAN) (list XmNpacking XM_UCHAR) (list XmNpageDecrementCallback XM_CALLBACK) (list XmNpageIncrement XM_INT) (list XmNpageIncrementCallback XM_CALLBACK) (list XmNpaneMaximum XM_DIMENSION) (list XmNpaneMinimum XM_DIMENSION) (list XmNpattern XM_STRING_OR_XMSTRING) (list XmNpendingDelete XM_BOOLEAN) (list XmNpixmap XM_PIXMAP) (list XmNpopdownCallback XM_CALLBACK) (list XmNpopupCallback XM_CALLBACK) (list XmNpopupEnabled XM_INT) (list XmNpositionIndex XM_SHORT) (list XmNpostFromButton XM_INT) (list XmNpreeditType XM_STRING) (list XmNprocessingDirection XM_UCHAR) (list XmNpromptString XM_XMSTRING) (list XmNpushButtonEnabled XM_BOOLEAN) (list XmNqualifySearchDataProc XM_QUALIFY_CALLBACK) (list XmNradioAlwaysOne XM_BOOLEAN) (list XmNradioBehavior XM_BOOLEAN) (list XmNrecomputeSize XM_BOOLEAN) (list XmNrefigureMode XM_BOOLEAN) (list XmNrepeatDelay XM_INT) (list XmNresizable XM_BOOLEAN) (list XmNresizeCallback XM_CALLBACK) (list XmNresizeHeight XM_BOOLEAN) (list XmNresizePolicy XM_UCHAR) (list XmNresizeWidth XM_BOOLEAN) (list XmNrightAttachment XM_UCHAR) (list XmNrightOffset XM_INT) (list XmNrightPosition XM_INT) (list XmNrightWidget XM_WIDGET) (list XmNrowColumnType XM_UCHAR) (list XmNrows XM_SHORT) (list XmNrubberPositioning XM_BOOLEAN) (list XmNsashHeight XM_DIMENSION) (list XmNsashIndent XM_POSITION) (list XmNsashShadowThickness XM_DIMENSION) (list XmNsashWidth XM_DIMENSION) (list XmNsaveUnder XM_BOOLEAN) (list XmNscaleHeight XM_DIMENSION) (list XmNscaleMultiple XM_INT) (list XmNscaleWidth XM_DIMENSION) (list XmNscreen XM_SCREEN) (list XmNscrollBarDisplayPolicy XM_UCHAR) (list XmNscrollBarPlacement XM_UCHAR) (list XmNscrollHorizontal XM_BOOLEAN) (list XmNscrollLeftSide XM_BOOLEAN) (list XmNscrollTopSide XM_BOOLEAN) (list XmNscrollVertical XM_BOOLEAN) (list XmNscrolledWindowMarginHeight XM_DIMENSION) (list XmNscrolledWindowMarginWidth XM_DIMENSION) (list XmNscrollingPolicy XM_UCHAR) (list XmNselectColor XM_PIXEL) (list XmNselectInsensitivePixmap XM_PIXMAP) (list XmNselectPixmap XM_PIXMAP) (list XmNselectThreshold XM_INT) (list XmNselectedItemCount XM_INT) (list XmNselectedItems XM_STRING_TABLE) (list XmNselectionArray XM_INT_TABLE) (list XmNselectionArrayCount XM_INT) (list XmNselectionLabelString XM_XMSTRING) (list XmNselectionPolicy XM_UCHAR) (list XmNsensitive XM_BOOLEAN) (list XmNseparatorOn XM_BOOLEAN) (list XmNseparatorType XM_UCHAR) (list XmNset XM_UCHAR) (list XmNshadowThickness XM_DIMENSION) (list XmNshadowType XM_UCHAR) (list XmNshowArrows XM_BOOLEAN) (list XmNshowAsDefault XM_DIMENSION) (list XmNshowSeparator XM_BOOLEAN) (list XmNsimpleCallback XM_CALLBACK) (list XmNsingleSelectionCallback XM_CALLBACK) (list XmNskipAdjust XM_BOOLEAN) (list XmNsliderSize XM_INT) (list XmNsliderVisual XM_INT) (list XmNslidingMode XM_INT) (list XmNsource XM_TEXT_SOURCE) (list XmNsourceCursorIcon XM_WIDGET) (list XmNsourcePixmapIcon XM_WIDGET) (list XmNspacing XM_DIMENSION) (list XmNspotLocation XM_INT) (list XmNstateCursorIcon XM_WIDGET) (list XmNsubMenuId XM_WIDGET) (list XmNsymbolPixmap XM_PIXMAP) (list XmNtearOffMenuActivateCallback XM_CALLBACK) (list XmNtearOffMenuDeactivateCallback XM_CALLBACK) (list XmNtearOffModel XM_UCHAR) (list XmNtextAccelerators XM_ULONG) (list XmNtextColumns XM_SHORT) (list XmNtextString XM_XMSTRING) (list XmNtextTranslations XM_CALLBACK) (list XmNtitle XM_STRING) (list XmNtitleEncoding XM_ATOM) (list XmNtitleString XM_XMSTRING) (list XmNtoBottomCallback XM_CALLBACK) (list XmNtoTopCallback XM_CALLBACK) (list XmNtopAttachment XM_UCHAR) (list XmNtopCharacter XM_INT) (list XmNtopItemPosition XM_INT) (list XmNtopLevelEnterCallback XM_CALLBACK) (list XmNtopLevelLeaveCallback XM_CALLBACK) (list XmNtopOffset XM_INT) (list XmNtopPosition XM_INT) (list XmNtopShadowColor XM_PIXEL) (list XmNtopShadowPixmap XM_PIXMAP) (list XmNtopWidget XM_WIDGET) (list XmNtransferProc XM_TRANSFER_CALLBACK) (list XmNtransferStatus XM_UCHAR) (list XmNtransient XM_BOOLEAN) (list XmNtransientFor XM_WIDGET) (list XmNtranslations XM_CALLBACK) (list XmNtraversalOn XM_BOOLEAN) (list XmNtraverseObscuredCallback XM_CALLBACK) (list XmNtroughColor XM_PIXEL) (list XmNunitType XM_UCHAR) (list XmNunmapCallback XM_CALLBACK) (list XmNunpostBehavior XM_UCHAR) (list XmNuseAsyncGeometry XM_BOOLEAN) (list XmNuserData XM_ULONG) (list XmNvalidCursorForeground XM_PIXEL) (list XmNvalue XM_STRING_OR_INT) (list XmNvalueChangedCallback XM_CALLBACK) (list XmNverifyBell XM_BOOLEAN) (list XmNverticalFontUnit XM_INT) (list XmNverticalScrollBar XM_WIDGET) (list XmNverticalSpacing XM_DIMENSION) (list XmNvisibleItemCount XM_INT) (list XmNvisibleWhenOff XM_BOOLEAN) (list XmNvisual XM_VISUAL) (list XmNvisualPolicy XM_UCHAR) (list XmNwidth XM_DIMENSION) (list XmNwidthInc XM_INT) (list XmNwinGravity XM_INT) (list XmNwindow XM_WIDGET) (list XmNwindowGroup XM_WINDOW) (list XmNwmTimeout XM_INT) (list XmNwordWrap XM_BOOLEAN) (list XmNworkWindow XM_WIDGET) (list XmNx XM_POSITION) (list XmNy XM_POSITION) (list XmNarrowLayout XM_UCHAR) (list XmNarrowOrientation XM_UCHAR) (list XmNarrowSensitivity XM_UCHAR) (list XmNarrowSize XM_INT) (list XmNarrowSpacing XM_INT) (list XmNautoDragModel XM_INT) (list XmNbackPageBackground XM_PIXEL) (list XmNbackPageForeground XM_PIXEL) (list XmNbackPageNumber XM_INT) (list XmNbackPagePlacement XM_UCHAR) (list XmNbackPageSize XM_DIMENSION) (list XmNbindingPixmap XM_PIXMAP) (list XmNbindingType XM_UCHAR) (list XmNbindingWidth XM_INT) (list XmNbitmapConversionModel XM_INT) (list XmNbuttonRenderTable XM_RENDER_TABLE) (list XmNcollapsedStatePixmap XM_PIXMAP) (list XmNcolorAllocationProc XM_ALLOC_COLOR_CALLBACK) (list XmNcolorCalculationProc XM_SCREEN_COLOR_CALLBACK) (list XmNcomboBoxType XM_UCHAR) (list XmNconvertCallback XM_CALLBACK) (list XmNcurrentPageNumber XM_INT) (list XmNdecimal XM_STRING) (list XmNdefaultArrowSensitivity XM_UCHAR) (list XmNdefaultButtonEmphasis XM_INT) (list XmNdefaultVirtualBindings XM_STRING) (list XmNdestinationCallback XM_CALLBACK) (list XmNdetail XM_STRING_TABLE) (list XmNdetailColumnHeading XM_INT) (list XmNdetailColumnHeadingCount XM_INT) (list XmNdetailCount XM_INT) (list XmNdetailOrder XM_INT_TABLE) (list XmNdetailOrderCount XM_INT) (list XmNdetailShadowThickness XM_INT) (list XmNdetailTabList XM_TAB_LIST) (list XmNdirTextLabelString XM_XMSTRING) (list XmNdragStartCallback XM_CALLBACK) (list XmNenableBtn1Transfer XM_INT) (list XmNenableButtonTab XM_BOOLEAN) (list XmNenableDragIcon XM_BOOLEAN) (list XmNenableEtchedInMenu XM_BOOLEAN) (list XmNenableMultiKeyBindings XM_BOOLEAN) (list XmNenableThinThickness XM_BOOLEAN) (list XmNenableToggleColor XM_BOOLEAN) (list XmNenableToggleVisual XM_BOOLEAN) (list XmNenableUnselectableDrag XM_BOOLEAN) (list XmNenableWarp XM_INT) (list XmNentryParent XM_WIDGET) (list XmNentryViewType XM_UCHAR) (list XmNexpandedStatePixmap XM_PIXMAP) (list XmNfileFilterStyle XM_INT) (list XmNfirstPageNumber XM_INT) (list XmNfontName XM_STRING) (list XmNfontType XM_UCHAR) (list XmNframeBackground XM_PIXEL) (list XmNframeChildType XM_UCHAR) (list XmNframeShadowThickness XM_DIMENSION) (list XmNgrabStyle XM_INT) (list XmNincludeStatus XM_INT) (list XmNincrementValue XM_INT) (list XmNindeterminateInsensitivePixmap XM_PIXMAP) (list XmNindeterminatePixmap XM_PIXMAP) (list XmNinnerMarginHeight XM_DIMENSION) (list XmNinnerMarginWidth XM_DIMENSION) (list XmNinputPolicy XM_ULONG) (list XmNinsensitiveStippleBitmap XM_PIXMAP) (list XmNinvokeParseProc XM_PARSE_CALLBACK) (list XmNlabelRenderTable XM_RENDER_TABLE) (list XmNlargeCellHeight XM_DIMENSION) (list XmNlargeCellWidth XM_DIMENSION) (list XmNlargeIconMask XM_PIXMAP) (list XmNlargeIconPixmap XM_PIXMAP) (list XmNlargeIconX XM_FLOAT) (list XmNlargeIconY XM_FLOAT) (list XmNlastPageNumber XM_INT) (list XmNlayoutDirection XM_UCHAR) (list XmNlayoutType XM_UCHAR) (list XmNlist XM_WIDGET) (list XmNloadModel XM_UCHAR) (list XmNmajorTabSpacing XM_DIMENSION) (list XmNmatchBehavior XM_UCHAR) (list XmNmaximumValue XM_INT) (list XmNminimumValue XM_INT) (list XmNminorTabSpacing XM_DIMENSION) (list XmNmotifVersion XM_INT) (list XmNnoFontCallback XM_CALLBACK) (list XmNnoRenditionCallback XM_CALLBACK) (list XmNnotebookChildType XM_UCHAR) (list XmNnumValues XM_INT) (list XmNoutlineButtonPolicy XM_UCHAR) (list XmNoutlineChangedCallback XM_CALLBACK) (list XmNoutlineColumnWidth XM_DIMENSION) (list XmNoutlineIndentation XM_DIMENSION) (list XmNoutlineLineStyle XM_UCHAR) (list XmNoutlineState XM_UCHAR) (list XmNpageChangedCallback XM_CALLBACK) (list XmNpageNumber XM_INT) (list XmNpathMode XM_INT) (list XmNpatternType XM_UCHAR) (list XmNpopupHandlerCallback XM_CALLBACK) (list XmNposition XM_INT) (list XmNpositionMode XM_INT) (list XmNpositionType XM_UCHAR) (list XmNprimaryOwnership XM_UCHAR) (list XmNrenderTable XM_RENDER_TABLE) (list XmNrenditionBackground XM_PIXEL) (list XmNrenditionForeground XM_PIXEL) (list XmNscrolledWindowChildType XM_UCHAR) (list XmNselectedItem XM_XMSTRING) (list XmNselectedObjectCount XM_INT) (list XmNselectedObjects XM_WIDGET_LIST) (list XmNselectedPosition XM_INT) (list XmNselectedPositionCount XM_INT) (list XmNselectedPositions XM_INT_TABLE) (list XmNselectionCallback XM_CALLBACK) (list XmNselectionMode XM_UCHAR) (list XmNselectionTechnique XM_UCHAR) (list XmNsliderMark XM_INT) (list XmNsmallCellHeight XM_DIMENSION) (list XmNsmallCellWidth XM_DIMENSION) (list XmNsmallIconMask XM_PIXMAP) (list XmNsmallIconPixmap XM_PIXMAP) (list XmNsmallIconX XM_FLOAT) (list XmNsmallIconY XM_FLOAT) (list XmNsnapBackMultiple XM_SHORT) (list XmNspatialIncludeModel XM_UCHAR) (list XmNspatialResizeModel XM_UCHAR) (list XmNspatialSnapModel XM_UCHAR) (list XmNspatialStyle XM_UCHAR) (list XmNspinBoxChildType XM_UCHAR) (list XmNstrikethruType XM_UCHAR) (list XmNsubstitute XM_XMSTRING) (list XmNtabList XM_TAB_LIST) (list XmNtag XM_STRING) (list XmNtearOffTitle XM_XMSTRING) (list XmNtextField XM_WIDGET) (list XmNtextRenderTable XM_RENDER_TABLE) (list XmNtoggleMode XM_UCHAR) (list XmNunderlineType XM_UCHAR) (list XmNunselectColor XM_PIXEL) (list XmNtabValue XM_FLOAT) (list XmNoffsetModel XM_INT) (list XmNcallback XM_CALLBACK) (list XmNwaitForWm XM_BOOLEAN) (list XmNuseColorObj XM_BOOLEAN) (list XmNvalues XM_STRING_TABLE) (list XmNviewType XM_UCHAR) (list XmNvisualEmphasis XM_UCHAR) (list XmNwrap XM_BOOLEAN) ))) (for-each (lambda (n) (if (not (string? (car n))) (snd-display #__line__ ";resource ~A is not a string?" (car n))) (XtVaGetValues shell (list (car n) 0))) resource-list) ) (if (not (XEvent? (XEvent))) (snd-display #__line__ ";xevent type trouble! ~A -> ~A" (XEvent) (XEvent? (XEvent)))) (if (not (XGCValues? (XGCValues))) (snd-display #__line__ ";xgcvalues type trouble! ~A -> ~A" (XGCValues) (XGCValues? (XGCValues)))) (if (not (= (.direction (XmTraverseObscuredCallbackStruct)) 0)) (snd-display #__line__ ";.direction: ~A" (.direction (XmTraverseObscuredCallbackStruct)))) (if (.ptr (XmTextBlock)) (snd-display #__line__ ";.ptr block: ~A" (.ptr (XmTextBlock)))) (let ((hi (XmTextBlock))) (set! (.ptr hi) "hi") (if (not (string=? (.ptr hi) "hi")) (snd-display #__line__ ";.ptr set block: ~A" (.ptr hi))) (if (not (= (.length hi) 0)) (snd-display #__line__ ";.length block: ~A" (.length hi))) (set! (.length hi) 3) (if (not (= (.length hi) 3)) (snd-display #__line__ ";set .length block: ~A" (.length hi)))) (if (not (= (.dashes (XGCValues)) 0)) (snd-display #__line__ ";dashes: ~A" (.dashes (XGCValues)))) (set! (.dashes (XGCValues)) 1) (set! (.clip_mask (XGCValues)) (list 'Pixmap 0)) (set! (.resourceid (XEvent -1)) 0) (set! (.error_code (XEvent -1)) 0) (set! (.request_code (XEvent -1)) 0) (if (not (= (.resourceid (XEvent -1)) 0)) (snd-display #__line__ ";error resourceid: ~A" (.resourceid (XEvent -1)))) (if (not (= (.request_code (XEvent -1)) 0)) (snd-display #__line__ ";error request_code: ~A" (.request_code (XEvent -1)))) (set! (.pad (XColor)) 1) ;;) (if (defined? 'XShapeQueryExtents) (let* ((dpy (XtDisplay (cadr (main-widgets)))) (win (XtWindow (cadr (main-widgets)))) (vals (XShapeQueryExtents dpy win))) (if (not (= (car vals) 1)) (snd-display #__line__ ";XShapeQueryExtents: ~A" vals)) (set! vals (XShapeGetRectangles dpy win 0)) (if (not (list? vals)) (snd-display #__line__ ";XShapeGetRectangles: ~A" vals)) ;(segfault) (XtFree (cadr vals)) (set! vals (XShapeQueryExtension dpy)) (if (not (equal? vals (list #t 64 0))) (snd-display #__line__ ";XShapeQueryExtension: ~A" vals)) (set! vals (XShapeQueryVersion dpy)) (if (and (not (equal? vals (list #t 1 0))) (not (equal? vals (list #t 1 1)))) (snd-display #__line__ ";XShapeQueryVersion: ~A" vals)) (if (XShapeOffsetShape dpy win 0 0 0) (snd-display #__line__ ";XShapeOffsetShape?")) (let* ((attr (XSetWindowAttributes #f *basic-color* #f *highlight-color*)) (newwin (XCreateWindow dpy win 10 10 100 100 3 CopyFromParent InputOutput (list 'Visual CopyFromParent) (logior CWBackPixel CWBorderPixel) attr)) (bitmap (XCreateBitmapFromData dpy win right-arrow 16 12))) ; right-arrow is in snd-motif.scm (XShapeCombineMask dpy newwin ShapeClip 0 0 bitmap ShapeSet) (XShapeCombineRectangles dpy newwin ShapeUnion 0 0 (list (XRectangle 0 0 10 10) (XRectangle 0 0 10 30)) 2 ShapeSet ShapeBounding) (let ((newerwin (XCreateWindow dpy win 10 10 100 100 3 CopyFromParent InputOutput (list 'Visual CopyFromParent) (logior CWBackPixel CWBorderPixel) attr))) (XShapeCombineShape dpy newerwin ShapeIntersect 0 0 newwin ShapeSet ShapeClip)) (let ((reg1 (XPolygonRegion (list (XPoint 2 2) (XPoint 10 2) (XPoint 10 10) (XPoint 2 10)) 4 WindingRule))) (XShapeCombineRegion dpy newwin ShapeUnion 0 0 reg1 ShapeSet))))) (let ((classes (list xmArrowButtonWidgetClass xmBulletinBoardWidgetClass xmCascadeButtonWidgetClass xmCommandWidgetClass xmDrawingAreaWidgetClass xmDrawnButtonWidgetClass xmFileSelectionBoxWidgetClass xmFormWidgetClass xmFrameWidgetClass xmLabelWidgetClass xmListWidgetClass xmMainWindowWidgetClass xmManagerWidgetClass xmMessageBoxWidgetClass xmPanedWindowWidgetClass xmPrimitiveWidgetClass xmPushButtonWidgetClass xmRowColumnWidgetClass xmScaleWidgetClass xmScrollBarWidgetClass xmScrolledWindowWidgetClass xmSelectionBoxWidgetClass xmSeparatorWidgetClass xmTextFieldWidgetClass xmTextWidgetClass xmToggleButtonWidgetClass xmContainerWidgetClass xmComboBoxWidgetClass xmNotebookWidgetClass)) (wids ())) (for-each (lambda (class) (let* ((shell (cadr (main-widgets))) (wid (XtCreateWidget "hiho" class shell ()))) (set! wids (cons wid wids)) (XtAddCallback wid XmNhelpCallback (lambda (w c i) "help!")))) classes) (for-each (lambda (w) (XtCallCallbacks w XmNhelpCallback #f)) wids)) (let ((key (XStringToKeysym "Cancel"))) (if (not (= (cadr key) XK_Cancel)) (snd-display #__line__ ";XStringToKeysym ~A ~A" key XK_Cancel))) (let* ((win (XtWindow (cadr (main-widgets)))) (xm-procs-1 (list XPutBackEvent XNextEvent XtAppProcessEvent XtAppMainLoop XtAppAddActions XtAppNextEvent XtAppPeekEvent XtSetArg XtManageChildren XtManageChild XtUnmanageChildren XtUnmanageChild XtDispatchEvent XtCallAcceptFocus XtIsSubclass XtIsObject XtIsManaged XtIsRealized XtIsSensitive XtOwnSelection XtOwnSelectionIncremental XtMakeResizeRequest XtTranslateCoords XtKeysymToKeycodeList XtParseTranslationTable XtParseAcceleratorTable XtOverrideTranslations XtAugmentTranslations XtInstallAccelerators XtInstallAllAccelerators XtUninstallTranslations XtAppAddActionHook XtRemoveActionHook XtGetActionList XtCallActionProc XtRegisterGrabAction XtSetMultiClickTime XtGetMultiClickTime XtGetActionKeysym XtTranslateKeycode XtTranslateKey XtSetKeyTranslator XtRegisterCaseConverter XtConvertCase XtAddEventHandler XtRemoveEventHandler XtAddRawEventHandler XtRemoveRawEventHandler XtInsertEventHandler XtInsertRawEventHandler XtDispatchEventToWidget XtBuildEventMask XtAddGrab XtRemoveGrab XtAddExposureToRegion XtSetKeyboardFocus XtGetKeyboardFocusWidget XtLastEventProcessed XtLastTimestampProcessed XtAppAddTimeOut XtRemoveTimeOut XtAppAddInput XtRemoveInput XtAppPending XtRealizeWidget XtUnrealizeWidget XtSetSensitive XtNameToWidget XtWindowToWidget XtMergeArgLists XtVaCreateArgsList XtDisplay XtDisplayOfObject XtScreen XtScreenOfObject XtWindow XtWindowOfObject XtName XtSuperclass XtClass XtParent XtAddCallback XtRemoveCallback XtAddCallbacks XtRemoveCallbacks XtRemoveAllCallbacks XtCallCallbacks XtHasCallbacks XtCreatePopupShell XtVaCreatePopupShell XtPopup XtPopupSpringLoaded XtCallbackNone XtCallbackNonexclusive XtCallbackExclusive XtPopdown XtCallbackPopdown XtCreateWidget XtCreateManagedWidget XtVaCreateWidget XtVaCreateManagedWidget XtAppCreateShell XtVaAppCreateShell XtDisplayToApplicationContext XtSetValues XtVaSetValues XtGetValues XtVaGetValues XtAppSetErrorMsgHandler XtAppSetWarningMsgHandler XtAppErrorMsg XtAppWarningMsg XtAppSetErrorHandler XtAppSetWarningHandler XtAppError XtAppAddWorkProc XtGetGC XtAllocateGC XtDestroyGC XtReleaseGC XtFindFile XtResolvePathname XtDisownSelection XtGetSelectionValue XtGetSelectionValues XtAppSetSelectionTimeout XtAppGetSelectionTimeout XtGetSelectionRequest XtGetSelectionValueIncremental XtGetSelectionValuesIncremental XtCreateSelectionRequest XtSendSelectionRequest XtCancelSelectionRequest XtGrabKey XtUngrabKey XtGrabKeyboard XtUngrabKeyboard XtGrabButton XtUngrabButton XtGrabPointer XtUngrabPointer XtGetApplicationNameAndClass XtGetDisplays XtToolkitThreadInitialize XtAppLock XtAppUnlock XtIsRectObj XtIsWidget XtIsComposite XtIsConstraint XtIsShell XtIsOverrideShell XtIsWMShell XtIsVendorShell XtIsTransientShell XtIsTopLevelShell XtIsApplicationShell XtIsSessionShell XtMapWidget XtUnmapWidget XLoadQueryFont XQueryFont XGetMotionEvents XDeleteModifiermapEntry XGetModifierMapping XInsertModifiermapEntry XNewModifiermap XCreateImage XGetImage XGetSubImage XOpenDisplay XFetchBytes XFetchBuffer XGetAtomName XDisplayName XUniqueContext XKeysymToString XSynchronize XSetAfterFunction XInternAtom XCopyColormapAndFree XCreateColormap XCreatePixmapCursor XCreateGlyphCursor XCreateFontCursor XLoadFont XCreateGC XFlushGC XCreatePixmap XCreateBitmapFromData XCreatePixmapFromBitmapData XCreateSimpleWindow XGetSelectionOwner XCreateWindow XListInstalledColormaps XListFonts XListFontsWithInfo XListExtensions XListProperties ;XKeycodeToKeysym XLookupKeysym XGetKeyboardMapping ;XStringToKeysym XDisplayMotionBufferSize XVisualIDFromVisual XMaxRequestSize XExtendedMaxRequestSize XRootWindow XDefaultRootWindow XRootWindowOfScreen XDefaultVisual XDefaultVisualOfScreen XDefaultGC XDefaultGCOfScreen XBlackPixel XWhitePixel XAllPlanes XBlackPixelOfScreen XWhitePixelOfScreen XNextRequest XLastKnownRequestProcessed XServerVendor XDisplayString XDefaultColormap XDefaultColormapOfScreen XDisplayOfScreen XScreenOfDisplay XDefaultScreenOfDisplay XEventMaskOfScreen XScreenNumberOfScreen XSetErrorHandler XSetIOErrorHandler XListPixmapFormats XListDepths XReconfigureWMWindow XGetWMProtocols XSetWMProtocols XIconifyWindow XWithdrawWindow XGetCommand XGetWMColormapWindows XSetTransientForHint XActivateScreenSaver XAllocColor XAllocColorCells XAllocColorPlanes XAllocNamedColor XAllowEvents XAutoRepeatOff XAutoRepeatOn XBell XBitmapBitOrder XBitmapPad XBitmapUnit XCellsOfScreen XChangeActivePointerGrab XChangeGC XChangeKeyboardControl XChangeKeyboardMapping XChangePointerControl XChangeProperty XChangeWindowAttributes ; XCheckIfEvent XCheckMaskEvent XCheckTypedEvent XCheckTypedWindowEvent XCheckWindowEvent XCirculateSubwindows XCirculateSubwindowsDown XCirculateSubwindowsUp XClearArea XClearWindow XCloseDisplay XConfigureWindow XConnectionNumber XConvertSelection XCopyArea XCopyGC XCopyPlane XDefaultDepth XDefaultDepthOfScreen XDefaultScreen XDefineCursor XDeleteProperty XDestroyWindow XDestroySubwindows XDoesBackingStore XDoesSaveUnders XDisableAccessControl XDisplayCells XDisplayHeight XDisplayHeightMM XDisplayKeycodes XDisplayPlanes XDisplayWidth XDisplayWidthMM XDrawArc XDrawArcs XDrawImageString XDrawLine XDrawLines XDrawLinesDirect XDrawPoint XDrawPoints XDrawRectangle XDrawRectangles XDrawSegments XDrawString XDrawText XEnableAccessControl XEventsQueued XFetchName XFillArc XFillArcs XFillPolygon XFillRectangle XFillRectangles XFlush XForceScreenSaver XFreeColormap XFreeColors XFreeCursor XFreeExtensionList XFreeFont XFreeFontInfo XFreeFontNames XFreeFontPath XFreeGC XFreeModifiermap XFreePixmap XGeometry XGetErrorText XGetFontProperty XGetGCValues XGCValues XEvent XGetGeometry XGetIconName XGetInputFocus XGetKeyboardControl XGetPointerControl XGetPointerMapping XGetScreenSaver XGetTransientForHint XGetWindowProperty XGetWindowAttributes XGrabButton XGrabKey XGrabKeyboard XGrabPointer XGrabServer XHeightMMOfScreen XHeightOfScreen XIfEvent XImageByteOrder XInstallColormap XKeysymToKeycode XKillClient XLookupColor XLowerWindow XMapRaised XMapSubwindows XMapWindow XMaskEvent XMaxCmapsOfScreen XMinCmapsOfScreen XMoveResizeWindow XMoveWindow XNoOp XParseColor XParseGeometry XPeekEvent XPeekIfEvent XPending XPlanesOfScreen XProtocolRevision XProtocolVersion XPutImage XQLength XQueryBestCursor XQueryBestSize XQueryBestStipple XQueryBestTile XQueryColor XQueryColors XQueryExtension XQueryKeymap XQueryPointer XQueryTextExtents XQueryTree XRaiseWindow XRebindKeysym XRecolorCursor XRefreshKeyboardMapping XReparentWindow XResetScreenSaver XResizeWindow XRestackWindows XRotateBuffers XRotateWindowProperties XScreenCount XSelectInput XSendEvent XSetAccessControl XSetArcMode XSetBackground XSetClipMask XSetClipOrigin XSetClipRectangles XSetCloseDownMode XSetCommand XSetDashes XSetFillRule XSetFillStyle XSetFont XSetFontPath XSetForeground XSetFunction XSetGraphicsExposures XSetIconName XSetInputFocus XSetLineAttributes XSetModifierMapping XSetPlaneMask XSetPointerMapping XSetScreenSaver XSetSelectionOwner XSetState XSetStipple XSetSubwindowMode XSetTSOrigin XSetTile XSetWindowBackground XSetWindowBackgroundPixmap XSetWindowBorder XSetWindowBorderPixmap XSetWindowBorderWidth XSetWindowColormap XStoreBuffer XStoreBytes XStoreColor XStoreColors XStoreName XStoreNamedColor XSync XTextExtents XTextWidth XTranslateCoordinates XUndefineCursor XUngrabButton XUngrabKey XUngrabKeyboard XUngrabPointer XUngrabServer XUninstallColormap XUnloadFont XUnmapSubwindows XUnmapWindow XVendorRelease XWarpPointer XWidthMMOfScreen XWidthOfScreen XWindowEvent XWriteBitmapFile XSupportsLocale XSetLocaleModifiers XCreateFontSet XFreeFontSet XFontsOfFontSet XBaseFontNameListOfFontSet XLocaleOfFontSet XContextDependentDrawing XDirectionalDependentDrawing XContextualDrawing XFilterEvent XAllocIconSize XAllocStandardColormap XAllocWMHints XClipBox XCreateRegion XDefaultString XDeleteContext XDestroyRegion XEmptyRegion XEqualRegion ;XFindContext XGetIconSizes XGetRGBColormaps XGetVisualInfo XGetWMHints XIntersectRegion XConvertCase XLookupString XMatchVisualInfo XOffsetRegion XPointInRegion XPolygonRegion XRectInRegion XSaveContext XSetRGBColormaps XSetWMHints XSetRegion XShrinkRegion XSubtractRegion XUnionRectWithRegion XUnionRegion XXorRegion DefaultScreen DefaultRootWindow QLength ScreenCount ServerVendor ProtocolVersion ProtocolRevision VendorRelease DisplayString BitmapUnit BitmapBitOrder BitmapPad ImageByteOrder NextRequest LastKnownRequestProcessed DefaultScreenOfDisplay DisplayOfScreen RootWindowOfScreen BlackPixelOfScreen WhitePixelOfScreen DefaultColormapOfScreen DefaultDepthOfScreen DefaultGCOfScreen DefaultVisualOfScreen WidthOfScreen HeightOfScreen WidthMMOfScreen HeightMMOfScreen PlanesOfScreen CellsOfScreen MinCmapsOfScreen MaxCmapsOfScreen DoesSaveUnders DoesBackingStore EventMaskOfScreen RootWindow DefaultVisual DefaultGC BlackPixel WhitePixel DisplayWidth DisplayHeight DisplayWidthMM DisplayHeightMM DisplayPlanes DisplayCells DefaultColormap ScreenOfDisplay DefaultDepth IsKeypadKey IsPrivateKeypadKey IsCursorKey IsPFKey IsFunctionKey IsMiscFunctionKey IsModifierKey XmCreateMessageBox XmCreateMessageDialog XmCreateErrorDialog XmCreateInformationDialog XmCreateQuestionDialog XmCreateWarningDialog XmCreateWorkingDialog XmCreateTemplateDialog XmMessageBoxGetChild XmCreateArrowButtonGadget XmCreateArrowButton XmCreateNotebook XmNotebookGetPageInfo XmTransferSetParameters XmTransferValue XmCreateComboBox XmCreateDropDownComboBox XmCreateDropDownList XmComboBoxAddItem XmComboBoxDeletePos XmComboBoxSelectItem XmComboBoxSetItem XmComboBoxUpdate XmCreateContainer XmContainerGetItemChildren XmContainerRelayout XmContainerReorder XmContainerCut XmContainerCopy XmContainerPaste XmContainerCopyLink XmContainerPasteLink XmCreateSpinBox XmSpinBoxValidatePosition XmCreateSimpleSpinBox XmSimpleSpinBoxAddItem XmSimpleSpinBoxDeletePos XmSimpleSpinBoxSetItem XmDropSiteRegistered XmTextFieldCopyLink XmTextFieldPasteLink XmTextGetCenterline XmToggleButtonGadgetSetValue XmCreateIconGadget XmCreateIconHeader XmObjectAtPoint XmConvertStringToUnits XmCreateGrabShell XmToggleButtonSetValue XmTextPasteLink XmTextCopyLink XmScaleSetTicks XmInternAtom XmGetAtomName XmCreatePanedWindow XmCreateBulletinBoard XmCreateBulletinBoardDialog XmCreateCascadeButtonGadget XmCascadeButtonGadgetHighlight XmAddProtocols XmRemoveProtocols XmAddProtocolCallback XmRemoveProtocolCallback XmActivateProtocol XmDeactivateProtocol XmSetProtocolHooks XmCreateCascadeButton XmCascadeButtonHighlight XmCreatePushButtonGadget XmCreatePushButton XmCreateCommand XmCommandGetChild XmCommandSetValue XmCommandAppendValue XmCommandError XmCreateCommandDialog XmMenuPosition XmCreateRowColumn XmCreateWorkArea XmCreateRadioBox XmCreateOptionMenu XmOptionLabelGadget XmOptionButtonGadget XmCreateMenuBar XmCreatePopupMenu XmCreatePulldownMenu XmGetPostedFromWidget XmGetTearOffControl XmScaleSetValue XmScaleGetValue XmCreateScale XmClipboardStartCopy XmClipboardCopy XmClipboardEndCopy XmClipboardCancelCopy XmClipboardWithdrawFormat XmClipboardCopyByName XmClipboardUndoCopy XmClipboardLock XmClipboardUnlock XmClipboardStartRetrieve XmClipboardEndRetrieve XmClipboardRetrieve XmClipboardInquireCount XmClipboardInquireFormat XmClipboardInquireLength XmClipboardInquirePendingItems XmClipboardRegisterFormat XmGetXmScreen XmCreateScrollBar XmScrollBarGetValues XmScrollBarSetValues XmCreateDialogShell XmCreateScrolledWindow XmScrollVisible XmGetDragContext XmGetXmDisplay XmSelectionBoxGetChild XmCreateSelectionBox XmCreateSelectionDialog XmCreatePromptDialog XmDragStart XmDragCancel XmTargetsAreCompatible XmCreateSeparatorGadget XmCreateDragIcon XmCreateSeparator XmCreateDrawingArea XmCreateDrawnButton XmDropSiteRegister XmDropSiteUnregister XmDropSiteStartUpdate XmDropSiteUpdate XmDropSiteEndUpdate XmDropSiteRetrieve XmDropSiteQueryStackingOrder XmDropSiteConfigureStackingOrder XmDropTransferStart XmDropTransferAdd XmTextFieldGetString XmTextFieldGetSubstring XmTextFieldGetLastPosition XmTextFieldSetString XmTextFieldReplace XmTextFieldInsert XmTextFieldSetAddMode XmTextFieldGetAddMode XmTextFieldGetEditable XmTextFieldSetEditable XmTextFieldGetMaxLength XmTextFieldSetMaxLength XmTextFieldGetCursorPosition XmTextFieldGetInsertionPosition XmTextFieldSetCursorPosition XmTextFieldSetInsertionPosition XmTextFieldGetSelectionPosition XmTextFieldGetSelection XmTextFieldRemove XmTextFieldCopy XmTextFieldCut XmTextFieldPaste XmTextFieldClearSelection XmTextFieldSetSelection XmTextFieldXYToPos XmTextFieldPosToXY XmTextFieldShowPosition XmTextFieldSetHighlight XmTextFieldGetBaseline XmCreateTextField XmFileSelectionBoxGetChild XmFileSelectionDoSearch XmCreateFileSelectionBox XmCreateFileSelectionDialog XmTextSetHighlight XmCreateScrolledText XmCreateText XmTextGetSubstring XmTextGetString XmTextGetLastPosition XmTextSetString XmTextReplace XmTextInsert XmTextSetAddMode XmTextGetAddMode XmTextGetEditable XmTextSetEditable XmTextGetMaxLength XmTextSetMaxLength XmTextGetTopCharacter XmTextSetTopCharacter XmTextGetCursorPosition XmTextGetInsertionPosition XmTextSetInsertionPosition XmTextSetCursorPosition XmTextRemove XmTextCopy XmTextCut XmTextPaste XmTextGetSelection XmTextSetSelection XmTextClearSelection XmTextGetSelectionPosition XmTextXYToPos XmTextPosToXY XmTextGetSource XmTextSetSource XmTextShowPosition XmTextScroll XmTextGetBaseline XmTextDisableRedisplay XmTextEnableRedisplay XmTextFindString XmCreateForm XmCreateFormDialog XmCreateFrame XmToggleButtonGadgetGetState XmToggleButtonGadgetSetState XmCreateToggleButtonGadget XmToggleButtonGetState XmToggleButtonSetState XmCreateToggleButton XmCreateLabelGadget XmCreateLabel XmIsMotifWMRunning XmListAddItem XmListAddItems XmListAddItemsUnselected XmListAddItemUnselected XmListDeleteItem XmListDeleteItems XmListDeletePositions XmListDeletePos XmListDeleteItemsPos XmListDeleteAllItems XmListReplaceItems XmListReplaceItemsPos XmListReplaceItemsUnselected XmListReplaceItemsPosUnselected XmListReplacePositions XmListSelectItem XmListSelectPos XmListDeselectItem XmListDeselectPos XmListDeselectAllItems XmListSetPos XmListSetBottomPos XmListSetItem XmListSetBottomItem XmListSetAddMode XmListItemExists XmListItemPos XmListGetKbdItemPos XmListSetKbdItemPos XmListYToPos XmListPosToBounds XmListGetMatchPos XmListGetSelectedPos XmListSetHorizPos XmListUpdateSelectedList XmListPosSelected XmCreateList XmCreateScrolledList XmTranslateKey XmInstallImage XmUninstallImage XmGetPixmap XmGetPixmapByDepth XmDestroyPixmap XmUpdateDisplay XmWidgetGetBaselines XmRegisterSegmentEncoding XmMapSegmentEncoding XmCvtCTToXmString XmCvtXmStringToCT XmConvertUnits XmCreateSimpleMenuBar XmCreateSimplePopupMenu XmCreateSimplePulldownMenu XmCreateSimpleOptionMenu XmCreateSimpleRadioBox XmCreateSimpleCheckBox XmVaCreateSimpleMenuBar XmVaCreateSimplePopupMenu XmVaCreateSimplePulldownMenu XmVaCreateSimpleOptionMenu XmVaCreateSimpleRadioBox XmVaCreateSimpleCheckBox XmTrackingEvent XmSetColorCalculation XmGetColorCalculation XmGetColors XmChangeColor XmStringCreate XmStringCreateLocalized XmStringDirectionCreate XmStringSeparatorCreate XmStringInitContext XmStringFreeContext XmStringConcatAndFree XmStringIsVoid XmStringPeekNextTriple XmStringGetNextTriple XmStringComponentCreate XmStringUnparse XmStringParseText XmStringToXmStringTable XmStringTableToXmString XmStringTableUnparse XmStringTableParseStringArray XmDirectionToStringDirection XmStringDirectionToDirection XmStringGenerate XmStringPutRendition XmParseMappingGetValues XmParseMappingFree XmParseTableFree XmStringTableProposeTablist XmTabSetValue XmTabGetValues XmTabFree XmTabCreate XmTabListTabCount XmTabListRemoveTabs XmTabListReplacePositions XmTabListGetTab XmTabListCopy XmTabListInsertTabs ; XmRenderTableCvtFromProp XmRenderTableCvtToProp XmRenditionUpdate XmRenditionRetrieve XmRenditionFree XmRenditionCreate XmRenderTableGetRenditions XmRenderTableGetRendition XmRenderTableGetTags XmRenderTableFree XmRenderTableCopy XmRenderTableRemoveRenditions XmRenderTableAddRenditions XmStringEmpty XmStringHasSubstring XmStringFree XmStringBaseline XmStringWidth XmStringHeight XmStringExtent XmStringLineCount XmStringDraw XmStringDrawImage XmStringDrawUnderline XmGetDestination XmIsTraversable XmGetVisibility XmGetTabGroup XmGetFocusWidget XmProcessTraversal XmCreateMenuShell XmIsMessageBox XmIsArrowButtonGadget XmIsArrowButton XmIsNotebook XmIsComboBox XmIsContainer XmIsGrabShell XmIsIconGadget XmIsIconHeader XmIsPanedWindow XmIsBulletinBoard XmIsPrimitive XmIsCascadeButtonGadget XmIsCascadeButton XmIsPushButtonGadget XmIsPushButton XmIsCommand XmIsRowColumn XmIsScale XmIsScreen XmIsScrollBar XmIsDialogShell XmIsScrolledWindow XmIsDisplay XmIsSelectionBox XmIsDragContext XmIsSeparatorGadget XmIsDragIconObjectClass XmIsSeparator XmIsDrawingArea XmIsDrawnButton XmIsDropSiteManager XmIsDropTransfer XmIsTextField XmIsFileSelectionBox XmIsText XmIsForm XmIsFrame XmIsGadget XmIsToggleButtonGadget XmIsToggleButton XmIsLabelGadget XmIsLabel XmIsVendorShell XmIsList XmIsManager XmIsMenuShell XGetPixel XDestroyImage XPutPixel XSubImage XAddPixel XtAppContext? XtRequestId? XtWorkProcId? XtInputId? XtIntervalId? Screen? XEvent? XRectangle? XArc? XPoint? XSegment? XColor? Atom? Colormap? XModifierKeymap? Depth? Display? Drawable? Font? GC? KeySym? Pixel? Pixmap? Region? Time? Visual? Window? XFontProp? XFontSet? XFontStruct? XGCValues? XImage? XVisualInfo? XWMHints? XWindowAttributes? XWindowChanges? KeyCode? XContext? XCharStruct? XTextItem? Widget? XmStringContext? WidgetClass? XmString? XmToggleButton? XmDrawingArea? XmPushButton? XmTextField? XmFileSelectionBox? XmText? XmFrame? XmLabel? XmList? XmArrowButton? XmScrollBar? XmCommand? XmScale? XmRowColumn? XmTab? XmNotebook? XmComboBox? XmContainer? XmIconHeader? XmGrabShell? XmRendition? XmRenderTable? XmIconGadget? XmTabList? XmParseMapping? XmPanedWindow? XmScrolledWindow? XmCascadeButton? XmForm? XmBulletinBoard? XmScreen? XmDialogShell? XmDisplay? XmSelectionBox? XmDragContext? XmDragIconObjectClass? XmSeparator? XmDropSiteManager? XmDropTransfer? XmVendorShell? XmMessageBox? XmManager? XmMenuShell? XmLabelGadget? XmPushButtonGadget? XmSeparatorGadget? XmArrowButtonGadget? XmCascadeButtonGadget? XmToggleButtonGadget? XmDrawnButton? XmPrimitive? XmTextSource? XButtonEvent? XCirculateEvent? XCirculateRequestEvent? XClientMessageEvent? XColormapEvent? XConfigureEvent? XConfigureRequestEvent? XCreateWindowEvent? XCrossingEvent? XDeleteProperty XDestroyWindowEvent? XErrorEvent? XExposeEvent? XFocusChangeEvent? XGraphicsExposeEvent? XGravityEvent? XIconSize? XKeyEvent? XKeymapEvent? XMapEvent? XMapRequestEvent? XMappingEvent? XMotionEvent? XNoExposeEvent? XPropertyEvent? XReparentEvent? XResizeRequestEvent? XSelectionClearEvent? XSelectionEvent? XSelectionRequestEvent? XSetWindowAttributes? XStandardColormap? XUnmapEvent? XVisibilityEvent? )) (xm-procs (if (defined? 'XpmImage?) (append xm-procs-1 (list XpmCreatePixmapFromData XpmCreateDataFromPixmap XpmReadFileToPixmap XpmReadPixmapFile XpmWriteFileFromPixmap XpmWritePixmapFile XpmCreatePixmapFromXpmImage XpmCreateXpmImageFromPixmap XpmAttributes? XpmImage? XpmColorSymbol?)) xm-procs-1)) (xm-procs0 (remove-if (lambda (n) (not (aritable? n 0))) xm-procs)) (xm-procs1 (remove-if (lambda (n) (not (aritable? n 1))) xm-procs)) (xm-procs2 (remove-if (lambda (n) (not (aritable? n 2))) xm-procs)) (xm-procs3 (remove-if (lambda (n) (not (aritable? n 3))) xm-procs)) ) ;; ---------------- 0 Args (for-each (lambda (n) (catch #t n (lambda args (car args)))) xm-procs0) ;; ---------------- 1 Arg (for-each (lambda (arg) (for-each (lambda (n) (catch #t (lambda () (n arg)) (lambda args (car args)))) xm-procs1)) (list win 1.5 "/hiho" (list 0 1) 1234 (make-float-vector 3) (make-color-with-catch .95 .95 .95) #(0 1) 3/4 'mus-error 0+i (make-delay 32) (lambda () #t) (curlet) (make-float-vector (list 2 3) 0.0) :order 0 1 -1 #f #t () (make-vector 0))) ;; ---------------- 2 Args (for-each (lambda (arg1) (for-each (lambda (arg2) (for-each (lambda (n) (catch #t (lambda () (n arg1 arg2)) (lambda args (car args)))) xm-procs2)) (list win 1.5 "/hiho" (list 0 1) 1234 (make-float-vector 3) (make-color-with-catch .95 .95 .95) #(0 1) 3/4 0+i (make-delay 32) :feedback -1 0 #f #t () (make-vector 0)))) (list win 1.5 "/hiho" (list 0 1) 1234 (make-float-vector 3) (make-color-with-catch .95 .95 .95) #(0 1) 3/4 0+i (make-delay 32) :frequency -1 0 #f #t () (make-vector 0))) (if all-args ;; ---------------- 3 Args (for-each (lambda (arg1) (for-each (lambda (arg2) (for-each (lambda (arg3) (for-each (lambda (n) (catch #t (lambda () (n arg1 arg2 arg3)) (lambda args (car args)))) xm-procs3)) (list win 1.5 "/hiho" (list 0 1) 1234 (make-float-vector 3) #(0 1) 0+i (make-delay 32) :start -1 0 #f #t () (make-vector 0)))) (list win 1.5 "/hiho" (list 0 1) 1234 (make-float-vector 3) #(0 1) 0+i (make-delay 32) :phase -1 0 #f #t () (make-vector 0)))) (list win 1.5 "/hiho" (list 0 1) 1234 (make-float-vector 3) #(0 1) 0+i (make-delay 32) :channels -1 0 #f #t () (make-vector 0))) ) (let* ((struct-accessors-1 (list .pixel .red .green .blue .flags .pad .x .y .width .height .angle1 .angle2 .ptr .x1 .y1 .x2 .y2 .dashes .dash_offset .clip_mask .clip_y_origin .clip_x_origin .graphics_exposures .subwindow_mode .font .ts_y_origin .ts_x_origin .stipple .tile .arc_mode .fill_rule .fill_style .join_style .cap_style .line_style .line_width .background .foreground .plane_mask .function .delta .nchars .chars .name .depth .visual .mwidth .mheight .ndepths .depths .root_depth .root_visual .default_gc .cmap .white_pixel .black_pixel .max_maps .min_maps .backing_store .save_unders .root_input_mask .lbearing .rbearing .ascent .descent .attributes .card32 .fid .properties .min_bounds .max_bounds .per_char .input .initial_state .icon_pixmap .icon_window .icon_x .icon_y .icon_mask .window_group .visualid .class .red_mask .green_mask .blue_mask .bits_per_rgb .map_entries .nvisuals .visuals .bits_per_pixel .background_pixmap .background_pixel .border_pixmap .border_pixel .bit_gravity .win_gravity .backing_planes .backing_pixel .save_under .event_mask .do_not_propagate_mask .cursor .map_installed .map_state .all_event_masks .your_event_mask .screen .xoffset .byte_order .bitmap_unit .bitmap_bit_order .bitmap_pad .bytes_per_line .obdata .sibling .stack_mode .red_max .red_mult .green_max .green_mult .blue_max .blue_mult .base_pixel .killid .data .min_height .max_height .min_width .max_width .height_inc .width_inc .page_number .page_widget .status_area_widget .major_tab_widget .minor_tab_widget .source_data .location_data .parm .parm_format .parm_length .parm_type .transfer_id .destination_data .remaining .item_or_text .auto_selection_type .new_outline_state .prev_page_number .prev_page_widget .rendition .render_table ; .last_page .crossed_boundary .client_data .status .font_name .tag .traversal_destination .dragProtocolStyle .direction .reason .timeStamp .operation .operations .dropSiteStatus .dropAction .iccHandle .completionStatus .dragContext .animate .length .click_count .widget .item_position .callbackstruct .set .item .item_length .selected_items .selected_item_count .selected_item_positions .selection_type .mask .mask_length .dir .dir_length .pattern .pattern_length .position .currInsert .newInsert .startPos .endPos .text .request_code .error_code .first_keycode .request .resourceid .format .message_type .new .property .display .target .requestor .owner .selection .atom .place .value_mask .above .from_configure .event .override_redirect .border_width .parent .minor_code .major_code .drawable .count .key_vector .focus .detail .mode .is_hint .button .same_screen .keycode .state .y_root .x_root .root .time .subwindow .window .send_event .serial .type .value .doit .colormap .menuToPost .postIt)) (struct-accessors (if (defined? 'XpmImage?) (append struct-accessors-1 (list .valuemask .ncolors .cpp .numsymbols .colorsymbols .npixels .y_hotspot .x_hotspot .colormap_size)) struct-accessors-1)) (struct-accessor-names-1 (list '.pixel '.red '.green '.blue '.flags '.pad '.x '.y '.width '.height '.angle1 '.angle2 '.ptr '.x1 '.y1 '.x2 '.y2 '.dashes '.dash_offset '.clip_mask '.clip_y_origin '.clip_x_origin '.graphics_exposures '.subwindow_mode '.font '.ts_y_origin '.ts_x_origin '.stipple '.tile '.arc_mode '.fill_rule '.fill_style '.join_style '.cap_style '.line_style '.line_width '.background '.foreground '.plane_mask '.function '.delta '.nchars '.chars '.name '.depth '.visual '.mwidth '.mheight '.ndepths '.depths '.root_depth '.root_visual '.default_gc '.cmap '.white_pixel '.black_pixel '.max_maps '.min_maps '.backing_store '.save_unders '.root_input_mask '.lbearing '.rbearing '.ascent '.descent '.attributes '.card32 '.fid '.properties '.min_bounds '.max_bounds '.per_char '.input '.initial_state '.icon_pixmap '.icon_window '.icon_x '.icon_y '.icon_mask '.window_group '.visualid '.class '.red_mask '.green_mask '.blue_mask '.bits_per_rgb '.map_entries '.nvisuals '.visuals '.bits_per_pixel '.background_pixmap '.background_pixel '.border_pixmap '.border_pixel '.bit_gravity '.win_gravity '.backing_planes '.backing_pixel '.save_under '.event_mask '.do_not_propagate_mask '.cursor '.map_installed '.map_state '.all_event_masks '.your_event_mask '.screen '.xoffset '.byte_order '.bitmap_unit '.bitmap_bit_order '.bitmap_pad '.bytes_per_line '.obdata '.sibling '.stack_mode '.red_max '.red_mult '.green_max '.green_mult '.blue_max '.blue_mult '.base_pixel '.killid '.data '.min_height '.max_height '.min_width '.max_width '.height_inc '.width_inc '.page_number '.page_widget '.status_area_widget '.major_tab_widget '.minor_tab_widget '.source_data '.location_data '.parm '.parm_format '.parm_length '.parm_type '.transfer_id '.destination_data '.remaining '.item_or_text '.auto_selection_type '.new_outline_state '.prev_page_number '.prev_page_widget '.rendition '.render_table ; '.last_page '.crossed_boundary '.client_data '.status '.font_name '.tag '.traversal_destination '.dragProtocolStyle '.direction '.reason '.timeStamp '.operation '.operations '.dropSiteStatus '.dropAction '.iccHandle '.completionStatus '.dragContext '.animate '.length '.click_count '.widget '.item_position '.callbackstruct '.set '.item '.item_length '.selected_items '.selected_item_count '.selected_item_positions '.selection_type '.mask '.mask_length '.dir '.dir_length '.pattern '.pattern_length '.position '.currInsert '.newInsert '.startPos '.endPos '.text '.request_code '.error_code '.first_keycode '.request '.resourceid '.format '.message_type '.new '.property '.display '.target '.requestor '.owner '.selection '.atom '.place '.value_mask '.above '.from_configure '.event '.override_redirect '.border_width '.parent '.minor_code '.major_code '.drawable '.count '.key_vector '.focus '.detail '.mode '.is_hint '.button '.same_screen '.keycode '.state '.y_root '.x_root '.root '.time '.subwindow '.window '.send_event '.serial '.type '.value '.doit '.colormap '.menuToPost '.postIt)) (struct-accessor-names (if (defined? 'XpmImage?) (append struct-accessor-names-1 (list '.valuemask '.ncolors '.cpp '.numsymbols '.colorsymbols '.npixels '.y_hotspot '.x_hotspot '.colormap_size)) struct-accessor-names-1)) (dpy (XtDisplay (cadr (main-widgets)))) (win (XtWindow (cadr (main-widgets))))) ;; ---------------- 0 Args (for-each (lambda (n name) (let ((tag (catch #t n (lambda args (car args))))) (if (not (memq tag '(wrong-type-arg wrong-number-of-args))) (snd-display #__line__ ";(~A) -> ~A" name tag))) (if (dilambda? n) (let ((tag (catch #t (lambda () (set! (n) 0)) (lambda args (car args))))) (if (not (eq? tag 'wrong-number-of-args)) (snd-display #__line__ ";(~A) -> ~A" name tag))))) struct-accessors struct-accessor-names) ;; ---------------- 1 Arg (for-each (lambda (arg) (for-each (lambda (n name) (let ((tag (catch #t (lambda () (n arg)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";(~A ~A) -> ~A" name arg tag))) (if (dilambda? n) (begin (let ((tag (catch #t (lambda () (set! (n arg) 0)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";(~A ~A) -> ~A" name arg tag))) (let ((tag (catch #t (lambda () (set! (n 0) arg)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";(set ~A ~A) -> ~A" name arg tag)))))) struct-accessors struct-accessor-names)) (list dpy win '(Atom 0) '(Colormap 0) 1.5 "/hiho" 1234 #f #\c '(Time 0) '(Font 0) (make-vector 0) '(Cursor 1)))) ) (show-sounds-in-directory) ;(show-all-atoms) ))) ;;; ---------------- test 24: GL -------------------- (define (snd_test_24) (if (and (provided? 'snd-motif) (provided? 'gl) (provided? 'xm)) (with-let (sublet *gl*) (require snd-snd-gl.scm) (gl-info) (if all-args (gl-dump-state)) (let ((gl-procs (list glXChooseVisual glXCopyContext glXCreateContext glXCreateGLXPixmap glXDestroyContext glXDestroyGLXPixmap glXGetConfig glXGetCurrentContext glXGetCurrentDrawable glXIsDirect glXMakeCurrent glXQueryExtension glXQueryVersion glXSwapBuffers glXUseXFont glXWaitGL glXWaitX glXGetClientString glXQueryServerString glXQueryExtensionsString glClearIndex glClearColor glClear glIndexMask glColorMask glAlphaFunc glBlendFunc glLogicOp glCullFace glFrontFace glPointSize glLineWidth glLineStipple glPolygonMode glPolygonOffset glPolygonStipple glEdgeFlag glScissor glClipPlane glGetClipPlane glDrawBuffer glReadBuffer glEnable glDisable glIsEnabled glEnableClientState glDisableClientState glGetBooleanv glGetDoublev glGetFloatv glGetIntegerv glPushAttrib glPopAttrib glPushClientAttrib glPopClientAttrib glRenderMode glGetError glGetString glFinish glFlush glHint glClearDepth glDepthFunc glDepthMask glDepthRange glClearAccum glAccum glMatrixMode glOrtho glFrustum glViewport glPushMatrix glPopMatrix glLoadIdentity glLoadMatrixd glLoadMatrixf glMultMatrixd glMultMatrixf glRotated glRotatef glScaled glScalef glTranslated glTranslatef glIsList glDeleteLists glGenLists glNewList glEndList glCallList glCallLists glListBase glBegin glEnd glVertex2d glVertex2f glVertex2i glVertex2s glVertex3d glVertex3f glVertex3i glVertex3s glVertex4d glVertex4f glVertex4i glVertex4s glNormal3b glNormal3d glNormal3f glNormal3i glNormal3s glIndexd glIndexf glIndexi glIndexs glIndexub glColor3b glColor3d glColor3f glColor3i glColor3s glColor3ub glColor3ui glColor3us glColor4b glColor4d glColor4f glColor4i glColor4s glColor4ub glColor4ui glColor4us glTexCoord1d glTexCoord1f glTexCoord1i glTexCoord1s glTexCoord2d glTexCoord2f glTexCoord2i glTexCoord2s glTexCoord3d glTexCoord3f glTexCoord3i glTexCoord3s glTexCoord4d glTexCoord4f glTexCoord4i glTexCoord4s glRasterPos2d glRasterPos2f glRasterPos2i glRasterPos2s glRasterPos3d glRasterPos3f glRasterPos3i glRasterPos3s glRasterPos4d glRasterPos4f glRasterPos4i glRasterPos4s glRectd glRectf glRecti glRects glVertexPointer glNormalPointer glColorPointer glIndexPointer glTexCoordPointer glEdgeFlagPointer glGetPointerv glArrayElement glDrawArrays glDrawElements glInterleavedArrays glShadeModel glLightf glLighti glGetLightfv glGetLightiv glLightModelf glLightModeli glMaterialf glMateriali glGetMaterialfv glGetMaterialiv glColorMaterial glPixelZoom glPixelStoref glPixelStorei glPixelTransferf glPixelTransferi glGetPixelMapfv glGetPixelMapuiv glGetPixelMapusv glBitmap glReadPixels glDrawPixels glCopyPixels glStencilFunc glStencilMask glStencilOp glClearStencil glTexGend glTexGenf glTexGeni glGetTexGendv glGetTexGenfv glGetTexGeniv glTexEnvf glTexEnvi glGetTexEnvfv glGetTexEnviv glTexParameterf glTexParameteri glGetTexParameterfv glGetTexParameteriv glGetTexLevelParameterfv glGetTexLevelParameteriv glTexImage1D glTexImage2D glGenTextures glDeleteTextures glBindTexture glAreTexturesResident glIsTexture glTexSubImage1D glTexSubImage2D glCopyTexImage1D glCopyTexImage2D glCopyTexSubImage1D glCopyTexSubImage2D glMap1d glMap1f glMap2d glMap2f glGetMapdv glGetMapfv glGetMapiv glEvalCoord1d glEvalCoord1f glEvalCoord2d glEvalCoord2f glMapGrid1d glMapGrid1f glMapGrid2d glMapGrid2f glEvalPoint1 glEvalPoint2 glEvalMesh1 glEvalMesh2 glFogf glFogi glFeedbackBuffer glPassThrough glSelectBuffer glInitNames glLoadName glPushName glPopName glDrawRangeElements glTexImage3D glTexSubImage3D glCopyTexSubImage3D glColorTable glColorSubTable glCopyColorSubTable glCopyColorTable glGetColorTableParameterfv glGetColorTableParameteriv glBlendEquation glBlendColor glHistogram glResetHistogram glGetHistogram glGetHistogramParameterfv glGetHistogramParameteriv glMinmax glResetMinmax glGetMinmax glGetMinmaxParameterfv glGetMinmaxParameteriv glConvolutionFilter1D glConvolutionFilter2D glConvolutionParameterf glConvolutionParameteri glCopyConvolutionFilter1D glCopyConvolutionFilter2D glSeparableFilter2D )) (glu-procs (if (defined? 'gluBeginPolygon) (list gluBeginPolygon gluBuild1DMipmaps gluLookAt gluNewTess gluNextContour gluTessEndContour gluBuild2DMipmaps gluDeleteTess gluEndPolygon gluErrorString gluGetString gluGetTessProperty gluOrtho2D gluPerspective gluPickMatrix gluProject gluScaleImage gluTessBeginContour gluTessBeginPolygon gluTessEndPolygon gluTessNormal gluTessProperty gluTessVertex gluUnProject) ()))) ;; ---------------- 1 Arg (for-each (lambda (arg) (for-each (lambda (n) (catch #t (lambda () (n arg)) (lambda args (car args)))) gl-procs)) (list (list 0 1) 0+i)) (if (pair? glu-procs) (begin (for-each (lambda (arg) (for-each (lambda (n) (catch #t (lambda () (n arg)) (lambda args (car args)))) gl-procs)) (list (list 0 1) 0+i)) (let ((ind (open-sound "oboe.snd"))) (glXMakeCurrent ((*motif* 'XtDisplay) (cadr (main-widgets))) ((*motif* 'XtWindow) (car (channel-widgets))) (snd-gl-context)) (glEnable GL_DEPTH_TEST) (glDepthFunc GL_LEQUAL) (glClearDepth 1.0) (glClearColor 0.0 0.0 0.0 0.0) (glLoadIdentity) (gluPerspective 40.0 1.0 10.0 200.0) (glTranslatef 0.0 0.0 -50.0) (glRotatef -58.0 0.0 1.0 0.0) (let ((vals ((*motif* 'XtVaGetValues) (car (channel-widgets)) (list (*motif* 'XmNwidth) 0 (*motif* 'XmNheight) 0)))) (glViewport 0 0 (vals 1) (vals 3))) (glClear (logior GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT)) (glBegin GL_POLYGON) (glColor3f 0.0 0.0 0.0) (glVertex3f -10.0 -10.0 0.0) (glColor3f 0.7 0.7 0.7) (glVertex3f 10.0 -10.0 0.0) (glColor3f 1.0 1.0 1.0) (glVertex3f -10.0 10.0 0.0) (glEnd) (glBegin GL_POLYGON) (glColor3f 1.0 1.0 0.0) (glVertex3f 0.0 -10.0 -10.0) (glColor3f 0.0 1.0 0.7) (glVertex3f 0.0 -10.0 10.0) (glColor3f 0.0 0.0 1.0) (glVertex3f 0.0 5.0 -10.0) (glEnd) (glBegin GL_POLYGON) (glColor3f 1.0 1.0 0.0) (glVertex3f -10.0 6.0 4.0) (glColor3f 1.0 0.0 1.0) (glVertex3f -10.0 3.0 4.0) (glColor3f 0.0 0.0 1.0) (glVertex3f 4.0 -9.0 -10.0) (glColor3f 1.0 0.0 1.0) (glVertex3f 4.0 -6.0 -10.0) (glEnd) (glXSwapBuffers ((*motif* 'XtDisplay) (cadr (main-widgets))) ((*motif* 'XtWindow) (car (channel-widgets)))) (glFlush) (close-sound ind))))) ))) (if (and with-gui (provided? 'xm) (= snd-test 25) (file-exists? "misc.scm")) (load "misc.scm")) ;;; ---------------- test 25: errors ---------------- (define-macro (simple-time a) `(let ((start (get-internal-real-time))) ,a (- (get-internal-real-time) start))) (define (snd_test_25) (define (traced a) (+ 2 a)) (define (extract-channel filename snd chn) (save-sound-as filename snd :channel chn)) (define* (extract-channels :rest chans) ;; extract a list of channels from the current sound and save as test.snd: (extract-channels 0 2) (let ((snd (or (selected-sound) (car (sounds))))) (if (sound? snd) (begin (for-each (lambda (chan) (set! (selection-member? snd chan) #t) (set! (selection-position snd chan) 0) (set! (selection-framples snd chan) (framples snd chan))) chans) (save-selection "test.snd"))))) (define notch-out-rumble-and-hiss (let ((documentation "(notch-out-rumble-and-hiss s c) applies a bandpass filter with cutoffs at 40 Hz and 3500 Hz")) (lambda* (snd chn) (let ((cur-srate (* 1.0 (srate snd)))) (filter-sound (list 0.0 0.0 ; get rid of DC (/ 80.0 cur-srate) 0.0 ; get rid of anything under 40 Hz (1.0=srate/2 here) (/ 90.0 cur-srate) 1.0 ; now the passband (/ 7000.0 cur-srate) 1.0 (/ 8000.0 cur-srate) 0.0 ; end passband (40..4000) 1.0 0.0) ; get rid of some of the hiss ;; since the minimum band is 10 Hz here, ;; cur-srate/10 rounded up to next power of 2 seems a safe filter size ;; filter-sound will actually use overlap-add convolution in this case (expt 2 (ceiling (log (/ cur-srate 10.0) 2.0))) snd chn))))) (define* (reverse-channels snd) (let* ((ind (or snd (selected-sound) (car (sounds)))) (chns (chans ind))) (let ((swaps (floor (/ chns 2)))) (as-one-edit (lambda () (do ((i 0 (+ i 1)) (j (- chns 1) (- j 1))) ((= i swaps)) (swap-channels ind i ind j))))))) (define* (rotate-channel (samps 1) snd chn) (let ((ind (or snd (selected-sound) (car (sounds)))) (chan (or chn (selected-channel) 0))) (let ((reg (make-region 0 (- samps 1) ind chan))) (as-one-edit (lambda () (delete-samples 0 samps ind chan) (insert-region reg (framples ind chan)))) (forget-region reg)))) (define (randomize-list lst) (let* ((len (length lst)) (vals (make-vector len #f)) (nlst ())) (do ((i 0 (+ i 1))) ((= i len)) (let ((loc (random len))) (if (vector-ref vals loc) (do ((j 0 (+ j 1))) ((or (= j len) (not (vector-ref vals j))) (set! (vals j) (car lst)))) (set! (vals loc) (car lst))) (set! lst (cdr lst)))) (do ((i 0 (+ i 1))) ((= i len)) (set! nlst (cons (vector-ref vals i) nlst))) nlst)) (define (check-error-tag expected-tag thunk) (let ((tag (catch #t thunk (lambda args args)))) (if (or (and (not (list? tag)) (not (pair? tag))) (not (eq? (car tag) expected-tag))) (snd-display #__line__ ";check-error-tag ~A from ~A: ~A" expected-tag (procedure-source thunk) tag)))) (set! *with-background-processes* #t) (set! *remember-sound-state* #f) (if with-gui (let* ((delay-32 (make-delay 32)) (color-95 (make-color-with-catch .95 .95 .95)) (vector-0 (make-vector 0)) (str-3 "/hiho") (float-vector-3 (make-float-vector 3)) (float-vector-5 (make-float-vector 5)) (car-main (and with-gui (car (main-widgets)))) (cadr-main (and with-gui (cadr (main-widgets)))) (a-hook (make-hook 'a 'b)) (exts (sound-file-extensions)) ; save across possible set below (procs (list add-mark add-sound-file-extension add-source-file-extension sound-file-extensions sound-file? add-to-main-menu add-to-menu add-transform amp-control ask-about-unsaved-edits as-one-edit ask-before-overwrite auto-resize auto-update autocorrelate axis-color axis-info axis-label-font axis-numbers-font basic-color bind-key apply-controls change-samples-with-origin channel-style channel-widgets channels chans peaks-font bold-peaks-font close-sound combined-data-color color-cutoff color-orientation-dialog colormap-ref add-colormap delete-colormap colormap-size colormap-name colormap? color-inverted color-scale color->list colormap color? comment contrast-control contrast-control-amp contrast-control? convolve-selection-with convolve-with channel-properties channel-property controls->channel amp-control-bounds speed-control-bounds expand-control-bounds contrast-control-bounds reverb-control-length-bounds reverb-control-scale-bounds cursor-update-interval cursor-location-offset auto-update-interval current-font cursor cursor-color with-tracking-cursor cursor-size cursor-style tracking-cursor-style dac-combines-channels dac-size clipping data-color sample-type data-location data-size default-output-chans default-output-sample-type default-output-srate default-output-header-type define-envelope delete-mark delete-marks forget-region delete-sample delete-samples delete-samples-and-smooth delete-selection delete-selection-and-smooth dialog-widgets display-edits dot-size draw-dot draw-dots draw-line draw-lines draw-string edit-header-dialog edit-fragment edit-list->function edit-position edit-tree edits env-selection env-sound enved-envelope enved-base enved-clip? enved-in-dB enved-dialog enved-style enved-power enved-target enved-waveform-color enved-wave? eps-file eps-left-margin eps-bottom-margin eps-size expand-control expand-control-hop expand-control-jitter expand-control-length expand-control-ramp expand-control? fft fft-window-alpha fft-window-beta fft-log-frequency fft-log-magnitude fft-with-phases transform-size disk-kspace transform-graph-type fft-window transform-graph? mix-file-dialog file-name fill-polygon fill-rectangle filter-sound filter-control-in-dB filter-control-envelope enved-filter-order enved-filter filter-control-in-hz filter-control-order filter-selection filter-channel filter-control-waveform-color filter-control? find-mark find-sound finish-progress-report foreground-color insert-file-dialog file-write-date framples free-sampler graph transform? delete-transform graph-color graph-cursor graph-data graph->ps gl-graph->ps graph-style lisp-graph? graphs-horizontal header-type help-dialog info-dialog highlight-color insert-region insert-sample insert-samples insert-samples-with-origin insert-selection insert-silence insert-sound just-sounds key key-binding left-sample listener-color listener-font listener-prompt listener-selection listener-text-color main-widgets make-color make-graph-data make-mix-sampler make-player make-region make-region-sampler make-sampler mark-color mark-name mark-properties mark-property mark-sample mark-sync mark-sync-max mark-home marks mark? max-transform-peaks max-regions maxamp maxamp-position menu-widgets min-dB log-freq-start mix mixes mix-amp mix-amp-env mix-color mix-length mix? view-mixes-dialog mix-position mix-dialog-mix mix-name mix-sync-max mix-sync mix-properties mix-property mix-region mix-sampler? mix-selection mix-sound mix-home mix-speed mix-tag-height mix-tag-width mark-tag-height mark-tag-width mix-tag-y mix-float-vector mix-waveform-height time-graph-style lisp-graph-style transform-graph-style ;new-sound in read-mix-sample next-sample read-region-sample show-full-duration show-full-range initial-beg initial-dur transform-normalization open-file-dialog-directory open-raw-sound open-sound previous-sample peaks player? players play-arrow-size position-color position->x position->y print-length progress-report read-only read-sample-with-direction redo region-chans view-regions-dialog region-home region-graph-style region-framples region-position region-maxamp region-maxamp-position remember-sound-state selection-maxamp selection-maxamp-position region-sample region->float-vector region-srate regions region? remove-from-menu status-report reset-controls restore-controls restore-region reverb-control-decay reverb-control-feedback reverb-control-length reverb-control-lowpass reverb-control-scale reverb-control? reverse-sound reverse-selection revert-sound right-sample sample sampler-at-end? sampler? samples sampler-position sash-color save-controls ladspa-dir peak-env-dir save-dir save-edit-history save-envelopes save-listener save-marks save-region save-selection save-sound save-sound-as save-state save-state-file scale-by scale-selection-by scale-selection-to scale-to search-procedure select-all select-channel select-sound selected-channel selected-data-color selected-graph-color selected-sound selection-position selection-color selection-creates-region selection-framples selection-member? selection? short-file-name show-axes show-controls show-transform-peaks show-indices show-listener show-selection unselect-all show-marks show-mix-waveforms show-selection-transform show-y-zero sinc-width show-grid show-sonogram-cursor grid-density smooth-sound smooth-selection snd-print snd-spectrum snd-tempnam snd-version sound-files-in-directory sound-loop-info sound-widgets soundfont-info sound? sounds spectrum-end spectro-hop spectrum-start spectro-x-angle spectro-x-scale spectro-y-angle spectro-y-scale spectro-z-angle spectro-z-scale speed-control speed-control-style speed-control-tones squelch-update srate src-sound src-selection ;start-playing start-progress-report stop-player stop-playing swap-channels syncd-marks sync sync-max sound-properties sound-property temp-dir text-focus-color tiny-font region-sampler? transform-dialog transform-sample transform->float-vector transform-framples transform-type with-file-monitor unbind-key undo update-transform-graph update-time-graph update-lisp-graph update-sound clm-table-size clm-default-frequency with-verbose-cursor view-sound wavelet-type with-inset-graph with-interrupts with-pointer-focus with-smpte-label with-toolbar with-tooltips with-menu-icons save-as-dialog-src save-as-dialog-auto-comment time-graph? time-graph-type wavo-hop wavo-trace window-height window-width window-x window-y with-mix-tags with-relative-panes with-gl x-axis-style beats-per-measure beats-per-minute x-bounds x-position-slider x->position x-zoom-slider mus-header-type->string mus-sample-type->string y-bounds y-position-slider y->position y-zoom-slider zero-pad zoom-color zoom-focus-style sync-style mus-set-formant-radius-and-frequency mus-sound-samples mus-sound-framples mus-sound-duration mus-sound-datum-size mus-sound-data-location data-size mus-sound-chans mus-sound-srate mus-sound-header-type mus-sound-sample-type mus-sound-length mus-sound-type-specifier mus-header-type-name mus-sample-type-name mus-sound-comment mus-sound-write-date mus-bytes-per-sample mus-sound-loop-info mus-sound-mark-info ;mus-alsa-buffers mus-alsa-buffer-size mus-apply mus-alsa-squelch-warning ;mus-alsa-device mus-alsa-playback-device mus-alsa-capture-device mus-sound-maxamp mus-sound-maxamp-exists? mus-clipping mus-file-clipping mus-header-raw-defaults moving-average moving-average? make-moving-average moving-max moving-max? make-moving-max make-moving-norm moving-norm moving-norm? mus-expand-filename all-pass all-pass? amplitude-modulate array->file array-interp mus-interpolate asymmetric-fm asymmetric-fm? comb comb? filtered-comb filtered-comb? contrast-enhancement convolution convolve convolve? db->linear degrees->radians delay delay? dot-product env env-interp env? file->array file->frample file->frample? file->sample even-multiple even-weight odd-multiple odd-weight file->sample? filter filter? fir-filter fir-filter? formant formant-bank formant-bank? formant? firmant firmant? comb-bank make-comb-bank comb-bank? all-pass-bank make-all-pass-bank all-pass-bank? filtered-comb-bank make-filtered-comb-bank filtered-comb-bank? granulate granulate? hz->radians iir-filter iir-filter? linear->db locsig ; in-any ina inb locsig-ref locsig-reverb-ref locsig-reverb-set! locsig-set! locsig? make-all-pass make-asymmetric-fm make-comb make-filtered-comb make-convolve make-delay make-env make-fft-window make-file->frample make-file->sample make-filter make-fir-filter make-formant make-firmant make-frample->file make-granulate make-iir-filter make-locsig move-locsig make-notch make-one-pole make-one-pole-all-pass make-one-zero make-oscil make-pulse-train make-rand make-rand-interp make-readin make-sample->file make-sawtooth-wave make-nrxysin make-nrxycos make-square-wave make-src make-ncos make-rxyk!cos make-rxyk!sin make-nsin make-ssb-am make-table-lookup make-triangle-wave make-two-pole make-two-zero make-wave-train move-sound make-move-sound move-sound? mus-float-equal-fudge-factor mus-array-print-length mus-channel mus-channels make-polyshape polyshape polyshape? make-polywave polywave polywave? mus-close mus-data mus-feedback mus-feedforward mus-fft mus-frequency mus-hop mus-increment mus-input? mus-file-name mus-length mus-location mus-file-mix mus-order mus-output? mus-phase mus-ramp mus-random mus-scaler mus-srate mus-xcoeff mus-xcoeffs mus-ycoeff mus-ycoeffs notch notch? one-pole one-pole? one-pole-all-pass one-pole-all-pass? one-zero one-zero? oscil oscil? out-any outa outb outc outd partials->polynomial normalize-partials partials->wave phase-partials->wave polynomial pulse-train pulse-train? radians->degrees radians->hz rand rand-interp rand-interp? rand? readin readin? rectangular->polar rectangular->magnitudes ring-modulate sample->file sample->file? sawtooth-wave sawtooth-wave? nrxysin nrxysin? nrxycos nrxycos? rxyk!cos rxyk!cos? rxyk!sin rxyk!sin? spectrum square-wave square-wave? src src? ncos nsin ssb-am ncos? nsin? ssb-am? table-lookup table-lookup? tap tap? triangle-wave triangle-wave? two-pole two-pole? two-zero two-zero? wave-train wave-train? make-float-vector float-vector-add! float-vector-subtract! float-vector-multiply! float-vector-offset! float-vector-ref float-vector-scale! float-vector-set! float-vector-peak float-vector-max float-vector-min float-vector? float-vector-move! float-vector-subseq float-vector little-endian? float-vector->string clm-channel env-channel env-channel-with-base map-channel scan-channel reverse-channel seconds->samples samples->seconds smooth-channel float-vector->channel channel->float-vector src-channel scale-channel ramp-channel pad-channel normalize-channel cursor-position clear-listener mus-sound-prune mus-sound-forget xramp-channel snd->sample snd->sample? make-snd->sample beats-per-minute beats-per-measure channel-amp-envs convolve-files filter-control-coeffs locsig-type make-phase-vocoder mus-describe mus-error-type->string mus-file-buffer-size mus-name mus-offset mus-out-format mus-reset mus-rand-seed mus-width phase-vocoder? polar->rectangular phase-vocoder-amp-increments phase-vocoder-amps phase-vocoder-freqs phase-vocoder-phase-increments phase-vocoder-phases mus-generator? read-sample reset-listener-cursor goto-listener-end sampler-home selection-chans selection-srate snd-gcs snd-font snd-color snd-warning x-axis-label variable-graph? y-axis-label snd-url snd-urls free-player delay-tick playing pausing draw-axes copy-sampler html-dir html-program make-fir-coeffs mus-interp-type mus-run phase-vocoder player-home redo-edit undo-edit widget-position widget-size focus-widget )) (set-procs (list amp-control ask-about-unsaved-edits ask-before-overwrite auto-resize auto-update axis-color axis-label-font axis-numbers-font ;basic-color channel-style peaks-font bold-peaks-font sound-file-extensions show-full-duration show-full-range initial-beg initial-dur color-cutoff color-inverted color-scale contrast-control contrast-control-amp combined-data-color amp-control-bounds speed-control-bounds expand-control-bounds contrast-control-bounds reverb-control-length-bounds reverb-control-scale-bounds cursor-update-interval cursor-location-offset contrast-control? auto-update-interval current-font cursor cursor-color channel-properties channel-property with-tracking-cursor cursor-size cursor-style tracking-cursor-style dac-combines-channels dac-size clipping data-color default-output-chans default-output-sample-type default-output-srate default-output-header-type dot-size enved-envelope enved-base enved-clip? enved-in-dB enved-style enved-power enved-target enved-waveform-color enved-wave? eps-file eps-left-margin eps-bottom-margin eps-size expand-control expand-control-hop expand-control-jitter expand-control-length expand-control-ramp expand-control? fft-window-alpha fft-window-beta fft-log-frequency fft-log-magnitude fft-with-phases transform-size transform-graph-type fft-window transform-graph? filter-control-in-dB filter-control-envelope enved-filter-order enved-filter filter-control-in-hz filter-control-order filter-control-waveform-color filter-control? foreground-color graph-color graph-cursor graph-style lisp-graph? graphs-horizontal highlight-color just-sounds left-sample listener-color listener-font listener-prompt listener-text-color mark-color mark-name mark-properties mark-property mark-sample mark-sync max-transform-peaks max-regions min-dB log-freq-start mix-amp mix-amp-env mix-color mix-name mix-position mix-sync mix-properties mix-property mix-speed mix-tag-height mix-tag-width mix-tag-y mark-tag-width mark-tag-height mix-waveform-height transform-normalization open-file-dialog-directory position-color print-length play-arrow-size region-graph-style reverb-control-decay reverb-control-feedback reverb-control-length reverb-control-lowpass reverb-control-scale time-graph-style lisp-graph-style transform-graph-style reverb-control? sash-color ladspa-dir peak-env-dir save-dir save-state-file selected-data-color selected-graph-color selection-color selection-creates-region show-axes show-controls show-transform-peaks show-indices show-marks show-mix-waveforms show-selection-transform show-listener show-y-zero show-grid show-sonogram-cursor sinc-width spectrum-end spectro-hop spectrum-start spectro-x-angle grid-density spectro-x-scale spectro-y-angle spectro-y-scale spectro-z-angle spectro-z-scale speed-control speed-control-style speed-control-tones squelch-update sync sound-properties sound-property temp-dir text-focus-color tiny-font y-bounds transform-type with-file-monitor with-verbose-cursor with-inset-graph with-interrupts with-pointer-focus wavelet-type x-bounds with-smpte-label with-toolbar with-tooltips with-menu-icons save-as-dialog-src save-as-dialog-auto-comment time-graph? wavo-hop wavo-trace with-gl with-mix-tags x-axis-style beats-per-minute zero-pad zoom-color zoom-focus-style sync-style with-relative-panes window-x window-y window-width window-height mix-dialog-mix beats-per-measure channels chans colormap comment sample-type data-location data-size edit-position framples header-type maxamp read-only right-sample sample samples selected-channel colormap-size colormap? selected-sound selection-position selection-framples selection-member? sound-loop-info srate time-graph-type x-position-slider x-zoom-slider y-position-slider y-zoom-slider mus-array-print-length mus-float-equal-fudge-factor ;mus-data mus-feedback mus-feedforward mus-frequency mus-hop mus-increment mus-length mus-location mus-name mus-phase mus-ramp mus-scaler x-axis-label filter-control-coeffs locsig-type mus-file-buffer-size mus-rand-seed mus-width clm-table-size clm-default-frequency mus-offset mus-reset phase-vocoder-amp-increments phase-vocoder-amps phase-vocoder-freqs phase-vocoder-phase-increments phase-vocoder-phases html-dir html-program mus-interp-type widget-position widget-size mus-clipping mus-file-clipping mus-header-raw-defaults )) (make-procs (list make-all-pass make-asymmetric-fm make-snd->sample make-moving-average make-moving-max make-moving-norm make-comb make-filtered-comb make-convolve make-delay make-env make-fft-window make-file->frample make-file->sample make-filter make-fir-filter make-formant make-firmant make-frample->file make-granulate make-iir-filter make-locsig make-notch make-one-pole make-one-pole-all-pass make-one-zero make-oscil make-pulse-train make-rand make-rand-interp make-readin make-sample->file make-sawtooth-wave make-nrxysin make-nrxycos make-rxyk!cos make-rxyk!sin make-square-wave make-src make-ncos make-nsin make-table-lookup make-triangle-wave make-two-pole make-two-zero make-wave-train make-phase-vocoder make-ssb-am make-polyshape make-polywave make-color make-player make-region )) (keyargs (list :frequency :initial-phase :wave :cosines :amplitude :ratio :size :a0 :a1 :a2 :b1 :b2 :input :srate :file :channel :start :initial-contents :initial-element :scaler :feedforward :feedback :max-size :radius :gain :partials :r :a :n :fill-time :order :xcoeffs :ycoeffs :envelope :base :duration :offset :end :direction :degree :distance :reverb :output :fft-size :expansion :length :hop :ramp :jitter :type :format :comment :channels :filter :revout :width :edit :synthesize :analyze :interp :overlap :pitch :distribution :sines :dur)) (procs0 (remove-if (lambda (n) (or (not (procedure? n)) (not (aritable? n 0)))) procs)) (set-procs0 (remove-if (lambda (n) (or (not (procedure? n)) (not (set-arity-ok n 1)))) set-procs)) (procs1 (remove-if (lambda (n) (or (not (procedure? n)) (not (aritable? n 1)))) procs)) (set-procs1 (remove-if (lambda (n) (or (not (procedure? n)) (not (set-arity-ok n 2)))) set-procs)) (procs2 (remove-if (lambda (n) (or (not (procedure? n)) (not (aritable? n 2)))) procs)) (set-procs2 (remove-if (lambda (n) (or (not (procedure? n)) (not (set-arity-ok n 3)))) set-procs)) ) (reset-all-hooks) (do ((test-28 0 (+ 1 test-28))) ((= test-28 tests)) (log-mem test-28) (if (= test-28 1) (begin (set! delay-32 (make-oscil 440)) (set! color-95 (vector 1 2 3)) (set! vector-0 (make-comb .1 3)) (set! float-vector-3 (make-notch .1 101)) (set! car-main (make-all-pass .4 .5 2)) (set! cadr-main (make-table-lookup 101)) (set! a-hook (make-triangle-wave 220))) (if (= test-28 2) (begin (set! delay-32 (make-sawtooth-wave 440)) (set! color-95 123+123i) (set! vector-0 (make-rand 100)) (set! float-vector-3 (make-rand-interp 100)) (set! car-main (make-asymmetric-fm 100)) (set! a-hook (make-one-pole .1 .1))) (if (= test-28 3) (begin (set! delay-32 (make-two-zero .5 .5 .1)) (set! color-95 (list 1 2 3)) (set! vector-0 (make-formant 100 .1)) (set! float-vector-3 (make-polyshape :frequency 300 :partials '(1 1 2 1))) (set! car-main (make-oscil)) (set! cadr-main (vector 1 2 3)) (set! a-hook (float-vector .2 .1))) (if (= test-28 4) (begin (set! delay-32 (make-filter 3 (float-vector 3 1 2 3) (float-vector 3 1 2 3))) (set! color-95 (make-float-vector (list 2 1) 0.0)) (set! vector-0 (make-iir-filter 3 (float-vector 1 2 3))) (set! float-vector-3 (make-ncos)) (set! car-main (make-env '(0 0 1 1) :length 101)) (set! cadr-main (make-nsin 100 4)) (set! a-hook (make-nsin 100 3))) (if (= test-28 5) (begin (set! delay-32 '(1 2)) (set! color-95 (make-color-with-catch .9 .9 .9)) (set! vector-0 (make-vector 1)) (set! car-main (make-moving-average 3)) (set! cadr-main (make-oscil 440)) (set! a-hook (make-shared-vector (float-vector .1 .2 .1 .2) (list 2 2))) )))))) (for-each (lambda (n) (let ((tag (catch #t (lambda () (n (integer->sound 123))) (lambda args (car args))))) (if (not (eq? tag 'no-such-sound)) (snd-display #__line__ ";snd no-such-sound ~A: ~A" n tag)))) (list amp-control apply-controls channels chans comment contrast-control amp-control-bounds speed-control-bounds expand-control-bounds contrast-control-bounds reverb-control-length-bounds reverb-control-scale-bounds contrast-control-amp contrast-control? sample-type data-location data-size expand-control expand-control-hop expand-control-jitter expand-control-length expand-control-ramp expand-control? file-name filter-control-in-dB filter-control-in-hz filter-control-envelope filter-control-order filter-control? finish-progress-report framples header-type progress-report read-only reset-controls restore-controls reverb-control-decay reverb-control-feedback reverb-control-length reverb-control-lowpass reverb-control-scale reverb-control? save-controls select-sound short-file-name sound-loop-info soundfont-info speed-control speed-control-style speed-control-tones srate channel-style start-progress-report sync sound-properties sound-property swap-channels)) (for-each (lambda (arg) (for-each (lambda (n) (let ((tag (catch #t (lambda () (n arg)) (lambda args (car args))))) (if (and (not (eq? tag 'wrong-type-arg)) (not (eq? tag 'mus-error))) (snd-display #__line__ ";snd wrong-type-arg ~A: ~A ~A" n tag arg)))) (list amp-control apply-controls close-sound comment contrast-control amp-control-bounds speed-control-bounds expand-control-bounds contrast-control-bounds reverb-control-length-bounds reverb-control-scale-bounds contrast-control-amp contrast-control? sample-type data-location data-size expand-control expand-control-hop expand-control-jitter expand-control-length expand-control-ramp expand-control? filter-control-in-dB filter-control-in-hz filter-control-envelope filter-control-order filter-control? finish-progress-report header-type read-only reset-controls restore-controls reverb-control-decay reverb-control-feedback reverb-control-length reverb-control-lowpass reverb-control-scale reverb-control? save-controls select-sound short-file-name sound-loop-info soundfont-info speed-control speed-control-style speed-control-tones srate channel-style start-progress-report sync sound-properties swap-channels))) (list float-vector-5 0+i 1.5 "hiho" delay-32)) (for-each (lambda (arg) (for-each (lambda (n) (let ((tag (catch #t (lambda () (set! (n arg) 0)) (lambda args (car args))))) (if (and (not (eq? tag 'wrong-type-arg)) (not (eq? tag 'syntax-error)) (not (eq? tag 'error))) (snd-display #__line__ ";snd set wrong-type-arg: ~A: ~A ~A" n tag arg)))) (list amp-control channels chans comment contrast-control contrast-control-amp amp-control-bounds speed-control-bounds expand-control-bounds contrast-control-bounds reverb-control-length-bounds reverb-control-scale-bounds contrast-control? sample-type data-location data-size expand-control expand-control-hop expand-control-jitter expand-control-length expand-control-ramp expand-control? filter-control-in-dB filter-control-in-hz filter-control-envelope filter-control-order filter-control? framples header-type read-only reverb-control-decay reverb-control-feedback reverb-control-length reverb-control-lowpass reverb-control-scale reverb-control? sound-loop-info soundfont-info speed-control speed-control-style speed-control-tones srate channel-style sync))) (list float-vector-5 0+i 1.5 "hiho" delay-32)) (let ((index (open-sound "obtest.snd"))) (for-each (lambda (arg) (for-each (lambda (n) (let ((tag (catch #t (lambda () (set! (n index) arg)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";snd safe set wrong-type-arg: ~A ~A ~A" n tag arg)))) (list amp-control contrast-control contrast-control-amp contrast-control? expand-control amp-control-bounds speed-control-bounds expand-control-bounds contrast-control-bounds reverb-control-length-bounds reverb-control-scale-bounds expand-control-hop expand-control-jitter expand-control-length expand-control-ramp expand-control? filter-control-in-dB filter-control-in-hz filter-control-envelope filter-control-order filter-control? reverb-control-decay reverb-control-feedback reverb-control-length reverb-control-lowpass reverb-control-scale reverb-control? speed-control speed-control-style speed-control-tones channel-style sync))) (list float-vector-5 0+i "hiho" delay-32)) (close-sound index)) (for-each (lambda (arg) (for-each (lambda (n) (let ((tag (catch #t (lambda () (n arg)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";float-vector 0 wrong-type-arg ~A: ~A ~A" n tag arg)))) (list make-float-vector float-vector-peak float-vector-max float-vector-min))) (list (make-vector 1) "hiho" 0+i 1.5 #(0 1) delay-32)) (for-each (lambda (arg1) (for-each (lambda (arg2) (for-each (lambda (n) (let ((tag (catch #t (lambda () (n arg1 arg2)) (lambda args (car args))))) (if (not (memq tag '(wrong-type-arg wrong-number-of-args mus-error))) (snd-display #__line__ ";float-vector 1 wrong-whatever ~A: ~A ~A ~A" n tag arg1 arg2)))) (list float-vector-add! float-vector-subtract! float-vector-multiply! float-vector-ref float-vector-scale!))) (list float-vector-5 "hiho" 0+i 1.5 (list 1 0) #(0 1) delay-32))) (list (make-vector 1) "hiho" 0+i 1.5 (list 1 0) #(0 1) delay-32)) (for-each (lambda (arg) (for-each (lambda (n) (let ((tag (catch #t (lambda () (n float-vector-3 arg)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";float-vector arg 2 (scaler) wrong-type-arg ~A: ~A ~A" n arg tag)))) (list float-vector-add! float-vector-subtract! float-vector-multiply! float-vector-ref float-vector-scale!))) (list (make-vector 1) "hiho" 0+i (list 1 0) #(0 1) delay-32)) (let ((v float-vector-3)) (let ((tag (catch #t (lambda () (v 12)) (lambda args (car args))))) (if (not (eq? tag 'out-of-range)) (snd-display #__line__ ";float-vector[12]: ~A" tag)))) (for-each (lambda (arg) (for-each (lambda (n) (let ((tag (catch #t (lambda () (n arg)) (lambda args (car args))))) (if tag (snd-display #__line__ ";?proc ~A: ~A" n tag)))) (list all-pass? asymmetric-fm? comb? filtered-comb? convolve? delay? env? file->frample? file->sample? snd->sample? filter? fir-filter? formant? formant-bank? firmant? frample->file? granulate? iir-filter? locsig? move-sound? mus-input? mus-output? notch? one-pole? one-pole-all-pass? one-zero? oscil? phase-vocoder? pulse-train? rand-interp? rand? readin? sample->file? sawtooth-wave? nrxysin? nrxycos? rxyk!cos? rxyk!sin? square-wave? src? ncos? nsin? tap? table-lookup? triangle-wave? two-pole? two-zero? wave-train? color? mix-sampler? moving-average? moving-max? moving-norm? ssb-am? sampler? region-sampler? float-vector? ))) (list (make-vector 1) "hiho" 0+i 1.5 (list 1 0) #(0 1))) (for-each (lambda (n) (let ((tag (catch #t (lambda () (n (make-oscil 440))) (lambda args (car args))))) (if tag (snd-display #__line__ ";oscil?proc ~A: ~A" n tag)))) (list all-pass? asymmetric-fm? comb? filtered-comb? convolve? delay? env? file->frample? file->sample? snd->sample? filter? fir-filter? formant? formant-bank? firmant? frample->file? granulate? iir-filter? locsig? move-sound? mus-input? mus-output? notch? one-pole? one-pole-all-pass? one-zero? phase-vocoder? pulse-train? rand-interp? rand? readin? sample->file? sawtooth-wave? nrxysin? nrxycos? rxyk!cos? rxyk!sin? square-wave? src? ncos? nsin? tap? table-lookup? triangle-wave? two-pole? two-zero? wave-train? sound? color? mix-sampler? moving-average? moving-max? moving-norm? ssb-am? sampler? region-sampler? float-vector?)) (for-each (lambda (n) (let ((tag (catch #t n (lambda args (car args))))) (if (not (eq? tag 'no-active-selection)) (snd-display #__line__ ";selection ~A: ~A" n tag)))) (list reverse-selection selection-position selection-framples smooth-selection scale-selection-to insert-selection delete-selection delete-selection-and-smooth mix-selection)) (for-each (lambda (n) (let ((tag (catch #t (lambda () (n 0.0)) (lambda args (car args))))) (if (not (eq? tag 'no-active-selection)) (snd-display #__line__ ";selection ~A: ~A" n tag)))) (list src-selection filter-selection env-selection)) (for-each (lambda (arg) (for-each (lambda (n) (let ((tag (catch #t (lambda () (n arg)) (lambda args (car args))))) (if (not (member tag '(wrong-type-arg no-data no-such-method bad-type error arg-error) eq?)) (snd-display #__line__ ";clm ~A: tag: ~A arg: ~A" n tag arg)))) (list all-pass asymmetric-fm comb filtered-comb convolve db->linear moving-average moving-max moving-norm degrees->radians delay env formant firmant granulate hz->radians linear->db even-weight odd-weight make-all-pass make-asymmetric-fm make-comb make-filtered-comb make-convolve make-delay make-env make-file->frample make-file->sample make-filter make-fir-filter make-formant make-firmant make-granulate make-iir-filter make-locsig make-notch make-one-pole make-one-zero make-oscil make-pulse-train make-rand make-rand-interp make-readin make-sawtooth-wave make-nrxysin make-nrxycos make-rxyk!cos make-rxyk!sin make-square-wave make-src make-ncos make-nsin make-table-lookup make-triangle-wave make-two-pole make-two-zero make-wave-train make-ssb-am mus-channel mus-channels make-polyshape make-polywave mus-data mus-feedback mus-feedforward mus-frequency mus-hop mus-increment mus-length mus-file-name mus-location mus-name mus-order mus-phase mus-ramp mus-random mus-run mus-scaler mus-xcoeffs mus-ycoeffs notch one-pole one-pole-all-pass one-zero make-moving-average make-moving-max make-moving-norm seconds->samples samples->seconds oscil partials->polynomial partials->wave phase-partials->wave phase-vocoder pulse-train radians->degrees radians->hz rand rand-interp readin sawtooth-wave nrxysin nrxycos rxyk!cos rxyk!sin square-wave src ncos nsin table-lookup tap triangle-wave two-pole two-zero wave-train ssb-am))) (list (make-vector 1) color-95 (list 1.0))) (for-each (lambda (n) (let ((tag (catch #t (lambda () (n (make-oscil) float-vector-5) ) (lambda args (car args))))) (if (not (member tag '(wrong-type-arg bad-arity error mus-error) eq?)) (snd-display #__line__ ";clm-1 ~A: ~A" n tag)))) (list all-pass array-interp asymmetric-fm comb filtered-comb contrast-enhancement convolution convolve moving-average moving-max moving-norm convolve-files delay dot-product env-interp file->sample snd->sample filter fir-filter formant firmant formant-bank granulate iir-filter ina inb locsig-ref locsig-reverb-ref make-all-pass make-asymmetric-fm make-comb make-filtered-comb make-delay make-env make-fft-window make-filter make-fir-filter make-formant make-firmant make-granulate make-iir-filter make-locsig make-notch make-one-pole make-one-pole-all-pass make-one-zero make-oscil make-phase-vocoder make-pulse-train make-rand make-rand-interp make-readin make-sawtooth-wave make-moving-average make-moving-max make-moving-norm make-nrxysin make-nrxycos make-rxyk!cos make-rxyk!sin make-square-wave make-src make-ncos make-nsin make-table-lookup make-triangle-wave make-two-pole make-two-zero make-wave-train notch one-pole one-pole-all-pass one-zero oscil partials->polynomial partials->wave make-polyshape make-polywave phase-partials->wave phase-vocoder polynomial pulse-train rand rand-interp rectangular->polar rectangular->magnitudes ring-modulate sawtooth-wave nrxysin nrxycos rxyk!cos rxyk!sin square-wave src ncos nsin table-lookup tap triangle-wave two-pole two-zero wave-train ssb-am make-ssb-am)) (for-each (lambda (n) (let ((tag (catch #t (lambda () (set! (n (make-oscil)) vector-0)) (lambda args (car args))))) (if (not (member tag '(wrong-type-arg syntax-error error) eq?)) (snd-display #__line__ ";mus-gen ~A: ~A" n tag)))) (list mus-channel mus-channels mus-data mus-feedback mus-feedforward mus-frequency mus-hop mus-increment mus-length mus-location mus-file-mix mus-name mus-order mus-phase mus-ramp mus-random mus-run mus-scaler mus-xcoeffs mus-ycoeffs)) (for-each (lambda (n) (let ((tag (catch #t (lambda () (n float-vector-5)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ ";mus-sound ~A: ~A" n tag)))) (list mus-sound-samples mus-sound-framples mus-sound-duration mus-sound-datum-size mus-sound-data-location mus-sound-chans mus-sound-srate mus-sound-header-type mus-sound-sample-type mus-sound-length mus-sound-type-specifier mus-header-type-name mus-sample-type-name mus-sound-comment mus-sound-write-date mus-bytes-per-sample mus-sound-loop-info mus-sound-mark-info mus-sound-maxamp mus-sound-maxamp-exists? mus-header-type->string mus-sample-type->string)) (for-each (lambda (n) (let ((tag (catch #t (lambda () (n "/bad/baddy")) (lambda args (car args))))) (if (not (eq? tag 'mus-error)) (snd-display #__line__ ";bad file mus-sound ~A: ~A" n tag)))) (list mus-sound-samples mus-sound-framples mus-sound-duration mus-sound-datum-size mus-sound-data-location mus-sound-chans mus-sound-srate mus-sound-header-type mus-sound-sample-type mus-sound-length mus-sound-type-specifier mus-sound-comment mus-sound-write-date mus-sound-maxamp mus-sound-maxamp-exists?)) (mus-sound-forget "/bad/baddy") ; for possible second time around (for-each (lambda (n) (let ((tag (catch #t (lambda () (n float-vector-5)) (lambda args (car args))))) (if (not (member tag '(wrong-type-arg error no-such-sound) eq?)) (snd-display #__line__ "; chn (no snd) procs ~A: ~A" n tag)))) (list channel-widgets cursor channel-properties channel-property cursor-position cursor-size cursor-style tracking-cursor-style delete-sample display-edits dot-size draw-dots draw-lines edit-fragment edit-position edit-tree edits fft-window-alpha fft-window-beta fft-log-frequency fft-log-magnitude fft-with-phases transform-size transform-graph-type fft-window transform-graph? graph graph-style lisp-graph? (lambda (a) (insert-region 0 a)) insert-sound time-graph-style lisp-graph-style transform-graph-style left-sample make-graph-data max-transform-peaks maxamp-position min-dB mix-region transform-normalization peaks ;play position->x position->y reverse-sound revert-sound right-sample sample save-sound save-sound-as select-channel show-axes show-transform-peaks show-marks show-mix-waveforms show-y-zero show-grid show-sonogram-cursor spectrum-end spectro-hop spectrum-start spectro-x-angle spectro-x-scale spectro-y-angle grid-density spectro-y-scale spectro-z-angle spectro-z-scale squelch-update transform-sample transform->float-vector transform-framples transform-type update-transform-graph update-time-graph update-lisp-graph update-sound wavelet-type time-graph? time-graph-type wavo-hop wavo-trace x-bounds x-position-slider x-zoom-slider x-axis-label y-axis-label y-bounds y-position-slider y-zoom-slider zero-pad)) (for-each (lambda (n) (let ((tag (catch #t (lambda () (n 0 float-vector-5)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ "; chn (no chn) procs ~A: ~A" n tag)))) (list channel-widgets cursor channel-properties channel-property combined-data-color cursor-position cursor-size cursor-style tracking-cursor-style delete-sample display-edits dot-size draw-dots draw-lines edit-fragment edit-position edit-tree edits fft-window-alpha fft-window-beta fft-log-frequency fft-log-magnitude fft-with-phases transform-size transform-graph-type fft-window transform-graph? graph graph-style lisp-graph? insert-region insert-sound left-sample time-graph-style lisp-graph-style transform-graph-style make-graph-data max-transform-peaks maxamp maxamp-position min-dB mix-region transform-normalization peaks play position->x position->y reverse-sound right-sample sample save-sound-as show-axes show-transform-peaks show-marks show-mix-waveforms show-y-zero show-grid show-sonogram-cursor spectrum-end spectro-hop spectrum-start spectro-x-angle spectro-x-scale spectro-y-angle spectro-y-scale spectro-z-angle spectro-z-scale squelch-update grid-density transform-sample transform->float-vector transform-framples transform-type update-transform-graph update-time-graph update-lisp-graph wavelet-type time-graph? time-graph-type wavo-hop wavo-trace x-bounds x-position-slider x-zoom-slider x-axis-label y-axis-label y-bounds y-position-slider y-zoom-slider zero-pad)) (for-each (lambda (n) (let ((tag (catch #t (lambda () (n (integer->sound 1234))) (lambda args (car args))))) (if (not (eq? tag 'no-such-sound)) (snd-display #__line__ "; chn procs ~A: ~A" n tag)))) (list channel-widgets cursor channel-properties cursor-position cursor-size cursor-style tracking-cursor-style (lambda (snd) (delete-sample 0 snd)) display-edits dot-size (lambda (snd) (edit-fragment 0 snd)) edit-position edit-tree edits env-sound fft-window-alpha fft-window-beta fft-log-frequency fft-log-magnitude fft-with-phases transform-size transform-graph-type fft-window transform-graph? filter-sound graph-data graph-style lisp-graph? left-sample time-graph-style lisp-graph-style transform-graph-style make-graph-data max-transform-peaks maxamp maxamp-position min-dB transform-normalization (lambda (snd) (position->x 0 snd)) (lambda (snd) (position->y 0 snd)) (lambda (snd) (redo 1 snd)) reverse-sound revert-sound right-sample (lambda (snd) (sample 0 snd)) save-sound scale-by scale-to show-axes show-transform-peaks show-marks show-mix-waveforms show-y-zero show-grid show-sonogram-cursor spectrum-end spectro-hop spectrum-start spectro-x-angle spectro-x-scale spectro-y-angle spectro-y-scale spectro-z-angle spectro-z-scale squelch-update grid-density src-sound (lambda (snd) (transform-sample 0 0 snd)) transform->float-vector transform-framples transform-type (lambda (snd) (undo 1 snd)) update-transform-graph update-time-graph update-lisp-graph update-sound wavelet-type time-graph? time-graph-type wavo-hop wavo-trace x-bounds x-position-slider (lambda (snd) (normalize-channel 0.5 0 #f snd)) (lambda (snd) (x->position 0 snd)) x-zoom-slider y-bounds y-position-slider x-axis-label y-axis-label (lambda (snd) (y->position 0 snd)) y-zoom-slider zero-pad (lambda (snd) (scale-channel 2.0 0 #f snd)) )) (for-each (lambda (n) (let ((tag (catch #t (lambda () (n 0 1234)) (lambda args (car args))))) (if (not (eq? tag 'no-such-sound)) (snd-display #__line__ "; snd(1) chn procs ~A: ~A" n tag)))) (list delete-sample edit-fragment graph-data graph-style play position->x position->y redo time-graph-style lisp-graph-style transform-graph-style scale-by scale-to undo x->position y->position x-axis-label)) (let ((index (open-sound "oboe.snd"))) (for-each (lambda (n) (let ((tag (catch #t (lambda () (n 0 index 1234)) (lambda args (car args))))) (if (not (eq? tag 'no-such-channel)) (snd-display #__line__ "; snd(1 1234) chn procs ~A: ~A" n tag)))) (list delete-sample edit-fragment graph-data position->x position->y redo scale-by scale-to undo x->position y->position)) (close-sound index)) (if (sound? (find-sound "oboe.snd")) (snd-display #__line__ ";oboe.snd is still open?")) (let ((index (open-sound "oboe.snd"))) (for-each (lambda (n) (let ((tag (catch #t (lambda () (n index 1234)) (lambda args (car args))))) (if (not (member tag '(no-such-channel no-such-sound) eq?)) (snd-display #__line__ "; chn procs ~A: ~A" n tag)))) (list channel-widgets cursor cursor-position cursor-size cursor-style tracking-cursor-style display-edits dot-size edit-position edit-tree edits fft-window-alpha fft-window-beta fft-log-frequency fft-log-magnitude fft-with-phases transform-size transform-graph-type fft-window transform-graph? graph-style lisp-graph? left-sample time-graph-style lisp-graph-style transform-graph-style combined-data-color make-graph-data max-transform-peaks maxamp maxamp-position min-dB transform-normalization reverse-sound right-sample show-axes show-transform-peaks show-marks show-mix-waveforms show-y-zero show-grid show-sonogram-cursor grid-density spectrum-end spectro-hop spectrum-start spectro-x-angle spectro-x-scale spectro-y-angle spectro-y-scale spectro-z-angle spectro-z-scale squelch-update transform->float-vector transform-framples transform-type update-transform-graph update-time-graph update-lisp-graph wavelet-type time-graph? time-graph-type wavo-hop wavo-trace x-bounds x-position-slider x-axis-label x-zoom-slider y-bounds y-position-slider y-zoom-slider zero-pad channel-properties channel-property )) (close-sound index)) (if (sound? (find-sound "oboe.snd")) (snd-display #__line__ ";oboe.snd is still open?")) (let ((index (open-sound "oboe.snd"))) (for-each (lambda (n) (let ((tag (catch #t (lambda () (set! (n index 0) float-vector-5)) (lambda args (car args))))) (if (not (member tag '(wrong-type-arg syntax-error error) eq?)) (snd-display #__line__ "; set chn procs ~A: ~A" n tag)))) (list channel-widgets cursor cursor-position display-edits dot-size edit-tree edits fft-window-alpha fft-window-beta fft-log-frequency fft-log-magnitude fft-with-phases transform-size transform-graph-type fft-window transform-graph? graph-style lisp-graph? left-sample make-graph-data max-transform-peaks maxamp maxamp-position time-graph-style lisp-graph-style transform-graph-style combined-data-color min-dB transform-normalization reverse-sound right-sample show-axes grid-density show-transform-peaks show-marks show-mix-waveforms show-y-zero show-grid show-sonogram-cursor spectrum-end spectro-hop spectrum-start spectro-x-angle spectro-x-scale spectro-y-angle spectro-y-scale spectro-z-angle spectro-z-scale squelch-update transform->float-vector transform-framples transform-type update-transform-graph update-time-graph update-lisp-graph wavelet-type time-graph? time-graph-type wavo-hop wavo-trace x-bounds x-position-slider x-zoom-slider y-bounds y-position-slider y-zoom-slider zero-pad x-axis-label )) (close-sound index)) (if (sound? (find-sound "oboe.snd")) (snd-display #__line__ ";oboe.snd is still open?")) (for-each (lambda (n b) (let ((tag (catch #t (lambda () (n float-vector-5)) (lambda args (car args))))) (if (not (member tag '(error wrong-type-arg syntax-error) eq?)) (snd-display #__line__ ";[0]: mix procs ~A: ~A (~A)" b tag float-vector-5)))) (list mix-amp mix-amp-env mix-length mix-name mix-position mix-home mix-speed mix-tag-y) (list 'mix-amp 'mix-amp-env 'mix-length 'mix-name 'mix-position 'mix-home 'mix-speed 'mix-tag-y)) (for-each (lambda (n) (let ((tag (catch #t (lambda () (n (integer->mix 1234))) (lambda args (car args))))) (if (not (eq? tag 'no-such-mix)) (snd-display #__line__ ";[1]: mix procs ~A: ~A" n tag)))) (list mix-amp mix-length mix-name mix-position mix-home mix-speed mix-tag-y)) (for-each (lambda (n) (let ((tag (catch #t (lambda () (set! (n (integer->mix 1234)) float-vector-5)) (lambda args (car args))))) (if (not (member tag '(error wrong-type-arg syntax-error no-such-mix) eq?)) (snd-display #__line__ ";[2]: mix procs ~A: ~A" n tag)))) (list mix-name mix-position mix-home mix-speed mix-tag-y)) (let ((index (open-sound "oboe.snd")) (id (mix-sound "oboe.snd" 10))) (for-each (lambda (n b) (let ((tag (catch #t (lambda () (set! (n id) float-vector-5)) (lambda args (car args))))) (if (not (member tag '(error wrong-type-arg syntax-error) eq?)) (snd-display #__line__ ";[3]: mix procs ~A: ~A (~A)" b tag float-vector-5)))) (list mix-name mix-position mix-home mix-speed mix-tag-y) (list 'mix-name 'mix-position 'mix-home 'mix-speed 'mix-tag-y)) (close-sound index)) (if (sound? (find-sound "oboe.snd")) (snd-display #__line__ ";oboe.snd is still open?")) (for-each (lambda (n) (let ((tag (catch #t (lambda () (n float-vector-5)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ "; mark procs ~A: ~A" n tag)))) (list add-mark mark-name mark-sample mark-sync mark-home delete-mark delete-marks find-mark)) (for-each (lambda (n) (let ((tag (catch #t (lambda () (n (integer->mark 1234))) (lambda args (car args))))) (if (not (eq? tag 'no-such-mark)) (snd-display #__line__ "; no mark procs ~A: ~A" n tag)))) (list mark-name mark-sample mark-sync mark-home delete-mark)) (let* ((index (open-sound "oboe.snd")) (id (add-mark 0 index 0))) (for-each (lambda (n) (let ((tag (catch #t (lambda () (set! (n id) float-vector-5)) (lambda args (car args))))) (if (not (eq? tag 'wrong-type-arg)) (snd-display #__line__ "; set mark procs ~A: ~A" n tag)))) (list mark-name mark-sample mark-sync)) (close-sound index)) (if (sound? (find-sound "oboe.snd")) (snd-display #__line__ ";oboe.snd is still open?")) (for-each (lambda (arg) (for-each (lambda (n) (let ((tag (catch #t (lambda () (n arg)) (lambda args (car args))))) (if (not (member tag '(wrong-type-arg wrong-number-of-args) eq?)) (snd-display #__line__ "; region procs ~A: ~A ~A" n tag arg)))) (list region-chans region-home region-framples region-position region-maxamp region-maxamp-position region-sample region->float-vector region-srate forget-region))) (list float-vector-5 #(0 1) 0+i "hiho" (list 0 1))) (for-each (lambda (n) (let ((tag (catch #t (lambda () (n (integer->region 1234))) (lambda args (car args))))) (if (not (eq? tag 'no-such-region)) (snd-display #__line__ "; (no) region procs ~A: ~A" n tag)))) (list region-chans region-home region-framples region-position region-maxamp region-maxamp-position region-srate forget-region)) (for-each (lambda (n) (let ((tag (catch #t (lambda () (set! (n) float-vector-5)) (lambda args (car args))))) (if (not (member tag '(error wrong-type-arg syntax-error) eq?)) (snd-display #__line__ "; misc procs ~A: ~A" n tag)))) (list axis-color enved-filter-order enved-filter filter-control-waveform-color ask-before-overwrite ask-about-unsaved-edits auto-resize auto-update axis-label-font axis-numbers-font basic-color bind-key show-full-duration show-full-range initial-beg initial-dur channel-style color-cutoff color-orientation-dialog color-inverted color-scale cursor-color dac-combines-channels dac-size clipping data-color default-output-chans default-output-sample-type default-output-srate default-output-header-type enved-envelope enved-base enved-clip? enved-in-dB enved-dialog enved-style enved-power enved-target enved-waveform-color enved-wave? eps-file eps-left-margin eps-bottom-margin eps-size foreground-color graph-color graph-cursor highlight-color just-sounds key-binding listener-color listener-font listener-prompt listener-text-color max-regions mix-waveform-height region-graph-style position-color time-graph-style lisp-graph-style transform-graph-style peaks-font bold-peaks-font print-length play-arrow-size sash-color ladspa-dir peak-env-dir save-dir save-state-file selected-channel selected-data-color selected-graph-color selected-sound selection-creates-region show-controls show-indices show-listener show-selection-transform sinc-width temp-dir text-focus-color tiny-font with-file-monitor unbind-key with-verbose-cursor with-inset-graph with-interrupts with-pointer-focus window-height beats-per-measure with-smpte-label with-toolbar with-tooltips with-menu-icons remember-sound-state save-as-dialog-src save-as-dialog-auto-comment window-width window-x window-y with-gl with-mix-tags x-axis-style beats-per-minute zoom-color mix-tag-height mix-tag-width with-relative-panes clm-table-size clm-default-frequency mark-tag-width mark-tag-height )) (set! *ask-about-unsaved-edits* #f) (set! *remember-sound-state* #f) (if (= test-28 0) (begin (check-error-tag 'no-such-envelope (lambda () (set! (enved-envelope) "not-an-env"))) (check-error-tag 'wrong-type-arg (lambda () (envelope-interp 1.0 '(0 0 .5)))) (check-error-tag 'cannot-save (lambda () (save-envelopes "/bad/baddy"))) (check-error-tag 'cannot-save (lambda () (mus-sound-report-cache "/bad/baddy"))) (check-error-tag 'bad-arity (lambda () (set! (search-procedure) (lambda (a b c) a)))) (check-error-tag 'no-such-channel (lambda () (make-sampler 0 "oboe.snd" 1))) (check-error-tag 'no-such-channel (lambda () (make-sampler 0 "oboe.snd" -1))) (check-error-tag 'bad-arity (lambda () (bind-key (char->integer #\p) 0 (lambda (a b) (play-often (max 1 a)))))) (check-error-tag 'bad-arity (lambda () (set! *zoom-focus-style* (lambda (a) 0)))) (check-error-tag 'bad-header (lambda () (mus-file-mix "oboe.snd" (string-append sf-dir "bad_chans.aifc")))) (check-error-tag 'mus-error (lambda () (mus-file-mix "oboe.snd" (string-append sf-dir "bad_length.aifc")))) (check-error-tag 'bad-header (lambda () (mus-file-mix (string-append sf-dir "bad_chans.aifc") "oboe.snd"))) (check-error-tag 'no-such-sound (lambda () (set! (sound-loop-info 123) '(0 0 1 1)))) (check-error-tag 'bad-header (lambda () (new-sound "fmv.snd" 2 22050 mus-bfloat mus-nist "this is a comment"))) (check-error-tag 'wrong-type-arg (lambda () (player-home 123))) (check-error-tag 'no-such-file (lambda () (set! *temp-dir* "/hiho"))) (check-error-tag 'no-such-file (lambda () (set! *save-dir* "/hiho"))) (check-error-tag 'out-of-range (lambda () (snd-transform (integer->transform 20) (make-float-vector 4)))) (check-error-tag 'bad-header (lambda () (mus-sound-maxamp (string-append sf-dir "bad_chans.snd")))) (check-error-tag 'mus-error (lambda () (make-iir-filter :order 32 :ycoeffs (make-float-vector 4)))) (check-error-tag 'mus-error (lambda () (make-iir-filter :coeffs (make-float-vector 4) :ycoeffs (make-float-vector 4)))) (check-error-tag 'mus-error (lambda () (make-fir-filter :coeffs (make-float-vector 4) :xcoeffs (make-float-vector 4)))) (check-error-tag 'out-of-range (lambda () (make-table-lookup :size 123456789))) ; (check-error-tag 'out-of-range (lambda () (make-src :srate -0.5))) (check-error-tag 'out-of-range (lambda () (make-granulate :ramp -0.5))) (check-error-tag 'out-of-range (lambda () (make-granulate :ramp 1.5))) (check-error-tag 'mus-error (lambda () (make-granulate :expansion 32000.0))) (check-error-tag 'out-of-range (lambda () (new-sound "test.snd" :channels 0))) (check-error-tag 'out-of-range (lambda () (new-sound "test.snd" :srate 0))) (check-error-tag 'out-of-range (lambda () (new-sound "test.snd" :size -1))) (check-error-tag 'out-of-range (lambda () (make-readin "oboe.snd" :size 0))) (check-error-tag 'out-of-range (lambda () (make-readin "oboe.snd" :size -1))) (check-error-tag 'out-of-range (lambda () (make-file->sample "oboe.snd" 0))) (check-error-tag 'out-of-range (lambda () (make-file->sample "oboe.snd" -1))) (check-error-tag 'out-of-range (lambda () (make-file->frample "oboe.snd" 0))) (check-error-tag 'out-of-range (lambda () (make-file->frample "oboe.snd" -1))) (check-error-tag 'out-of-range (lambda () (set! *default-output-sample-type* -1))) (check-error-tag 'out-of-range (lambda () (set! *default-output-header-type* mus-soundfont))) (check-error-tag 'mus-error (lambda () (mus-sound-chans (string-append sf-dir "bad_location.nist")))) (check-error-tag 'mus-error (lambda () (mus-sound-chans (string-append sf-dir "bad_field.nist")))) (check-error-tag 'mus-error (lambda () (make-locsig 1/0 :channels 2))) (if (provided? 'snd-motif) (begin (check-error-tag 'no-such-widget (lambda () (widget-position (list 'Widget 0)))) ; dubious -- not sure these should be supported (check-error-tag 'no-such-widget (lambda () (widget-size (list 'Widget 0)))) (check-error-tag 'no-such-widget (lambda () (widget-text (list 'Widget 0)))) (check-error-tag 'no-such-widget (lambda () (set! (widget-position (list 'Widget 0)) (list 0 0)))) (check-error-tag 'no-such-widget (lambda () (set! (widget-size (list 'Widget 0)) (list 10 10)))) (check-error-tag 'no-such-widget (lambda () (set! (widget-text (list 'Widget 0)) "hiho"))) )) (check-error-tag 'no-such-menu (lambda () (main-menu -1))) (check-error-tag 'no-such-menu (lambda () (main-menu 111))) (check-error-tag 'out-of-range (lambda () (new-sound "hiho" :header-type 123))) (check-error-tag 'out-of-range (lambda () (new-sound "hiho" :header-type mus-nist :sample-type 123))) (check-error-tag 'bad-header (lambda () (new-sound "hiho" :header-type mus-nist :sample-type mus-bfloat))) (check-error-tag 'out-of-range (lambda () (set! *mus-array-print-length* -1))) (check-error-tag 'out-of-range (lambda () (set! *print-length* -1))) (check-error-tag 'out-of-range (lambda () (set! *play-arrow-size* -1))) (check-error-tag 'out-of-range (lambda () (set! *enved-style* 12))) (check-error-tag 'out-of-range (lambda () (make-color 1.5 0.0 0.0))) (check-error-tag 'out-of-range (lambda () (make-color -0.5 0.0 0.0))) (check-error-tag 'wrong-type-arg (lambda () (make-variable-graph #f))) (check-error-tag 'cannot-print graph->ps) (let ((ind (open-sound "oboe.snd"))) (set! *selection-creates-region* #t) (select-all) (check-error-tag 'mus-error (lambda () (save-selection "sel0.snd" :not-a-key 3))) (check-error-tag 'wrong-type-arg (lambda () (read-only (list ind)))) (check-error-tag 'wrong-type-arg (lambda () (framples ind (list 0)))) (check-error-tag 'wrong-type-arg (lambda () (smooth-sound 0 -10))) (check-error-tag 'no-such-channel (lambda () (mix-selection 0 ind 123))) (check-error-tag 'no-such-channel (lambda () (insert-selection 0 ind 123))) (check-error-tag 'out-of-range (lambda () (set! (channels ind) 0))) (check-error-tag 'wrong-type-arg (lambda () (set! (channels ind) -1))) (check-error-tag 'out-of-range (lambda () (set! (channels ind) 12340))) (check-error-tag 'out-of-range (lambda () (set! (sample-type ind) 12340))) (check-error-tag 'out-of-range (lambda () (set! (header-type ind) 12340))) (check-error-tag 'out-of-range (lambda () (set! (srate ind) 0))) (check-error-tag 'wrong-type-arg (lambda () (set! (data-location ind) -1))) (check-error-tag 'wrong-type-arg (lambda () (set! (data-size ind) -1))) (check-error-tag 'no-such-sample (lambda () (set! (sample -1) -1))) (check-error-tag 'no-such-sample (lambda () (sample -1))) (check-error-tag 'out-of-range (lambda () (set! (framples) -10))) (check-error-tag 'out-of-range (lambda () (set! *min-dB* 0.0))) (check-error-tag 'out-of-range (lambda () (set! (min-dB ind 0) 0.0))) (check-error-tag 'out-of-range (lambda () (start-playing 1 -22))) (check-error-tag 'out-of-range (lambda () (start-playing 1 0))) (check-error-tag 'out-of-range (lambda () (set! (filter-control-envelope ind) (list 0.0 1.0 0.1 -0.1 1.0 0.0)))) (check-error-tag 'out-of-range (lambda () (set! (filter-control-envelope ind) (list 0.0 1.0 0.1 1.1 1.0 0.0)))) (check-error-tag 'env-error (lambda () (filter-sound '(0 0 .1 .1 .05 .1 1 1) 32))) (check-error-tag 'out-of-range (lambda () (apply-controls ind 123))) (check-error-tag 'out-of-range (lambda () (set! (speed-control-bounds) (list 0.0 2.0)))) (check-error-tag 'out-of-range (lambda () (set! (expand-control-bounds) (list 0.0 2.0)))) (check-error-tag 'out-of-range (lambda () (set! (speed-control-bounds) (list 2.0 0.0)))) (check-error-tag 'out-of-range (lambda () (set! (expand-control-bounds) (list 2.0 0.0)))) (check-error-tag 'bad-header (lambda () (insert-sound (string-append sf-dir "bad_chans.snd")))) (check-error-tag 'IO-error (lambda () (convolve-with (string-append sf-dir "bad_chans.snd")))) (check-error-tag 'cannot-save (lambda () (save-sound-as "hiho.snd" ind -12))) (check-error-tag 'cannot-save (lambda () (save-sound-as "hiho.snd" ind :header-type mus-next :sample-type -12))) (check-error-tag 'cannot-save (lambda () (save-sound-as "test.snd" ind :header-type mus-nist :sample-type mus-bdouble))) (check-error-tag 'cannot-save (lambda () (save-sound-as "test.snd" ind :header-type mus-aifc :sample-type mus-lfloat))) (check-error-tag 'cannot-save (lambda () (save-sound-as "test.snd" ind :header-type mus-riff :sample-type mus-bshort))) (check-error-tag 'cannot-save (lambda () (save-sound-as "test.snd" ind :header-type mus-voc :sample-type mus-bshort))) (check-error-tag 'cannot-save (lambda () (save-selection "test.snd" 22050 mus-bshort mus-riff))) (check-error-tag 'cannot-save (lambda () (save-selection "test.snd" 22050 mus-bshort mus-voc))) (check-error-tag 'out-of-range (lambda () (src-channel (make-env '(0 0 1 1) :length 11)))) (check-error-tag 'out-of-range (lambda () (src-channel (make-env '(0 1 1 0) :length 11)))) (check-error-tag 'out-of-range (lambda () (src-channel (make-env '(0 1 1 -1) :length 11)))) (check-error-tag 'out-of-range (lambda () (src-channel (make-env '(0 -1 1 1) :length 11)))) (check-error-tag 'out-of-range (lambda () (src-sound (make-env '(0 0 1 1) :length 11)))) (check-error-tag 'out-of-range (lambda () (src-sound (make-env '(0 1 1 0) :length 11)))) (check-error-tag 'out-of-range (lambda () (src-sound (make-env '(0 1 1 -1) :length 11)))) (check-error-tag 'out-of-range (lambda () (src-sound (make-env '(0 -1 1 1) :length 11)))) (check-error-tag 'mus-error (lambda () (make-readin 0.0 0.0 0.0 0.0 0.0 0.0 0.0))) (check-error-tag 'out-of-range (lambda () (filter-sound float-vector-3 32))) (check-error-tag 'out-of-range (lambda () (filter-sound '(0 0 1 1) 0))) (check-error-tag 'no-such-sound (lambda () (swap-channels ind 0 12345 0))) (check-error-tag 'no-such-sample (lambda () (mix-float-vector (float-vector 0.1 0.2 0.3) -1 ind 0 #t))) (check-error-tag 'out-of-range (lambda () (snd-spectrum (make-float-vector 8) 0 -123))) (check-error-tag 'out-of-range (lambda () (snd-spectrum (make-float-vector 8) 0 0))) (check-error-tag 'no-such-file (lambda () (play "/baddy/hiho"))) (check-error-tag 'bad-sample-type (lambda () (play (string-append sf-dir "nist-shortpack.wav")))) ; (check-error-tag 'no-such-channel (lambda () (play ind 0 :channel 123))) (check-error-tag 'no-such-channel (lambda () (make-player ind 123))) (check-error-tag 'no-such-file (lambda () (mix "/baddy/hiho"))) (check-error-tag 'no-such-channel (lambda () (mix "oboe.snd" 0 2))) (check-error-tag 'no-such-file (lambda () (mix-sound "/baddy/hiho" 0))) (check-error-tag 'no-such-file (lambda () (insert-sound "/baddy/hiho.snd"))) (check-error-tag 'no-such-file (lambda () (insert-samples 0 10 "/baddy/hiho.snd"))) (check-error-tag 'no-data (lambda () (set! (filter-control-envelope ind) ()))) (check-error-tag 'out-of-range (lambda () (set! (sample-type ind) 123))) (check-error-tag 'out-of-range (lambda () (set! (header-type ind) 123))) (check-error-tag 'no-such-channel (lambda () (set! (selected-channel ind) 123))) (check-error-tag 'bad-arity (lambda () (set! (search-procedure) (lambda (a b c) #t)))) (check-error-tag 'bad-arity (lambda () (map-channel (lambda (a b c) 1.0)))) (check-error-tag 'bad-arity (lambda () (scan-channel (lambda (a b c) 1.0)))) (check-error-tag 'bad-arity (lambda () (set! (cursor-style ind 0) (lambda (a) 32)))) (check-error-tag 'no-such-graphics-context (lambda () (draw-line 0 0 1 1 ind 0 1234))) (check-error-tag 'no-such-graphics-context (lambda () (foreground-color ind 0 1234))) (check-error-tag 'no-such-graphics-context (lambda () (current-font ind 0 1234))) (check-error-tag 'no-such-graphics-context (lambda () (graph-data (list float-vector-3 float-vector-3) ind 0 1234 0 1 0))) (check-error-tag 'no-such-axis (lambda () (position->x 100 ind 0 1234))) (check-error-tag 'no-such-axis (lambda () (position->y 100 ind 0 1234))) (check-error-tag 'no-such-axis (lambda () (x->position 100 ind 0 1234))) (check-error-tag 'no-such-axis (lambda () (y->position 100 ind 0 1234))) (check-error-tag 'no-such-axis (lambda () (axis-info ind 0 1234))) (check-error-tag 'out-of-range (lambda () (draw-axes (car (channel-widgets)) (car (snd-gcs)) "hiho" 0.0 1.0 -1.0 1.0 x-axis-in-seconds 1234))) (check-error-tag 'out-of-range (lambda () (draw-axes (car (channel-widgets)) (car (snd-gcs)) "hiho" 0.0 1.0 -1.0 1.0 1234))) (check-error-tag 'no-such-channel (lambda () (axis-info ind 1234))) (check-error-tag 'no-such-sound (lambda () (axis-info 1234))) (set! *time-graph-type* graph-once) ; (check-error-tag 'out-of-range (lambda () (set! (x-bounds) (list 0 0)))) (check-error-tag 'out-of-range (lambda () (set! (x-bounds) (list .1 -.1)))) ; (check-error-tag 'out-of-range (lambda () (set! (y-bounds) (list .2 .1)))) (check-error-tag 'out-of-range (lambda () (make-region 100 0))) (check-error-tag 'no-such-sample (lambda () (delete-sample -1))) (check-error-tag 'no-such-sample (lambda () (delete-sample (* 2 (framples ind))))) (check-error-tag 'no-such-file (lambda () (play "/bad/baddy.snd"))) (check-error-tag 'no-such-sound (lambda () (play 1234 0))) ; (check-error-tag 'no-such-channel (lambda () (play ind 0 :channel 1234))) (if (= (length (regions)) 0) (make-region 0 100)) (check-error-tag 'no-such-channel (lambda () (region-sample (car (regions)) 0 1234))) (check-error-tag 'no-such-channel (lambda () (region-framples (car (regions)) 1234))) (check-error-tag 'no-such-channel (lambda () (region-position (car (regions)) 1234))) ; (check-error-tag 'no-such-region (lambda () (region->float-vector #f 0 1))) ; (check-error-tag 'no-such-channel (lambda () (region->float-vector (car regions) 0 1 1234))) (check-error-tag 'cannot-save (lambda () (save-sound-as "/bad/baddy.snd"))) (check-error-tag 'no-such-sound (lambda () (transform-sample 0 1 1234))) (check-error-tag 'no-such-channel (lambda () (transform-sample 0 1 ind 1234))) (check-error-tag 'no-such-sound (lambda () (graph (float-vector 0 1) "hi" 0 1 0 1 1234))) (check-error-tag 'no-such-channel (lambda () (graph (float-vector 0 1) "hi" 0 1 0 1 ind 1234))) (set! (selection-member? #t) #f) (check-error-tag 'no-active-selection (lambda () (filter-selection (float-vector 0 0 1 1) 4))) (check-error-tag 'no-active-selection (lambda () (save-selection "/bad/baddy.snd"))) (check-error-tag 'no-active-selection (lambda () (env-selection '(0 0 1 1)))) (check-error-tag 'no-such-region (lambda () (save-region (integer->region 1234) "/bad/baddy.snd"))) (make-region 0 100 ind 0) (check-error-tag 'cannot-save (lambda () (save-selection "/bad/baddy.snd"))) (check-error-tag 'cannot-save (lambda () (save-region (car (regions)) "/bad/baddy.snd"))) (check-error-tag 'no-such-mix (lambda () (make-mix-sampler (integer->mix 1234)))) (check-error-tag 'no-such-sound (lambda () (make-region 0 12 1234 #t))) (set! (read-only ind) #t) (check-error-tag 'cannot-save (lambda () (set! (sound-loop-info ind) '(0 0 1 1)))) (check-error-tag 'no-such-direction (lambda () (make-sampler 0 ind 0 123))) (check-error-tag 'no-such-direction (lambda () (make-sampler 0 ind 0 0))) (check-error-tag 'no-such-direction (lambda () (make-sampler 0 ind 0 -2))) (check-error-tag 'no-data (lambda () (scale-by ()))) (check-error-tag 'no-data (lambda () (scale-to ()))) (check-error-tag 'no-such-sample (lambda () (set! (selection-position ind 0) -999))) (check-error-tag 'wrong-type-arg (lambda () (set! (selection-framples ind 0) -999))) (check-error-tag 'wrong-type-arg (lambda () (set! (selection-framples ind 0) 0))) (check-error-tag 'no-such-edit (lambda () (edit-fragment -1))) (check-error-tag 'no-such-edit (lambda () (edit-fragment 101 ind 0))) (check-error-tag 'no-such-edit (lambda () (edit-tree ind 0 -2))) (check-error-tag 'no-such-edit (lambda () (edit-tree ind 0 101))) (check-error-tag 'no-such-sample (lambda () (add-mark -1))) (check-error-tag 'no-such-sample (lambda () (add-mark (* 2 (framples))))) (check-error-tag 'no-such-file (lambda () (convolve-with "/bad/baddy"))) (check-error-tag 'no-such-file (lambda () (mix "/bad/baddy"))) (check-error-tag 'no-such-sound (lambda () (swap-channels ind 0 123))) (check-error-tag 'out-of-range (lambda () (set! (show-axes ind 0) 123))) (check-error-tag 'out-of-range (lambda () (set! (show-axes ind 0) -123))) (check-error-tag 'out-of-range (lambda () (set! (x-axis-style ind 0) 123))) (check-error-tag 'out-of-range (lambda () (set! (x-axis-style ind 0) -123))) (check-error-tag 'out-of-range (lambda () (set! (graph-style ind 0) 123))) (check-error-tag 'out-of-range (lambda () (set! (graph-style ind 0) -123))) (check-error-tag 'out-of-range (lambda () (env-sound '(0 0 1 1) 0 #f -1.5))) (check-error-tag 'out-of-range (lambda () (xramp-channel 0.0 1.0 -1.6))) (check-error-tag 'wrong-type-arg (lambda () (set! (samples 0 2) -1))) (check-error-tag 'wrong-type-arg (lambda () (left-sample (list 0)))) (check-error-tag 'wrong-type-arg (lambda () (amp-control (list 0)))) (check-error-tag 'wrong-type-arg (lambda () (sound-loop-info (list 0)))) (check-error-tag 'wrong-type-arg (lambda () (add-mark 123 (list 0)))) (check-error-tag 'no-such-sound (lambda () (filter-channel '(0 0 1 1) 100 #f #f 1234 0))) (check-error-tag 'no-such-channel (lambda () (filter-channel '(0 0 1 1) 100 #f #f ind 1))) (check-error-tag 'no-such-channel (lambda () (filter-channel (float-vector 0 0 1 1) 4 #f #f ind 1))) (check-error-tag 'out-of-range (lambda () (filter-sound (float-vector 0 0 1 1) 0))) (check-error-tag 'out-of-range (lambda () (filter-sound (float-vector 0 0 1 1) 10))) (check-error-tag 'bad-arity (lambda () (play (selected-sound) 0 :stop (lambda () #f)))) (check-error-tag 'out-of-range (lambda () (set! (reverb-control-length-bounds ind) (list .1 .01)))) (check-error-tag 'out-of-range (lambda () (set! (reverb-control-scale-bounds ind) (list .1 .01)))) (check-error-tag 'wrong-type-arg (lambda () (scale-by #f))) (check-error-tag 'wrong-type-arg (lambda () (src-sound 3.0 1.0 #t))) (check-error-tag 'wrong-type-arg (lambda () (src-sound 3.0 1.0 ind #t))) (check-error-tag 'no-such-edit (lambda () (display-edits ind 0 123))) (check-error-tag 'no-such-edit (lambda () (marks ind 0 123))) (check-error-tag 'no-such-edit (lambda () (save-sound-as "test.snd" :edit-position 123))) (check-error-tag 'no-such-auto-delete-choice (lambda () (insert-sound "1a.snd" 0 0 ind 0 0 123))) (close-sound ind)) (check-error-tag 'bad-arity (lambda () (add-transform "hiho" "time" 0 1 (lambda () 1.0)))) (check-error-tag 'cannot-save (lambda () (save-state "/bad/baddy"))) (check-error-tag 'no-such-menu (lambda () (add-to-menu 1234 "hi" (lambda () #f)))) (check-error-tag 'bad-arity (lambda () (add-to-main-menu "hi" (lambda (a b) #f)))) (check-error-tag 'bad-arity (lambda () (add-to-menu 1 "hi" (lambda (a b) #f)))) (check-error-tag 'wrong-type-arg (lambda () (set! *transform-type* (integer->transform -1)))) (check-error-tag 'out-of-range (lambda () (set! *transform-type* (integer->transform 123)))) (check-error-tag 'wrong-type-arg (lambda () (help-dialog (list 0 1) "hiho"))) (check-error-tag 'wrong-type-arg (lambda () (info-dialog (list 0 1) "hiho"))) (check-error-tag 'no-such-sound (lambda () (edit-header-dialog 1234))) (check-error-tag 'no-such-file (lambda () (open-sound "/bad/baddy.snd"))) (check-error-tag 'no-such-file (lambda () (open-raw-sound "/bad/baddy.snd" 1 22050 mus-lshort))) (check-error-tag 'no-such-file (lambda () (view-sound "/bad/baddy.snd"))) (check-error-tag 'no-such-file (lambda () (make-sampler 0 "/bad/baddy.snd"))) (check-error-tag 'no-such-region (lambda () (make-region-sampler (integer->region 1234567) 0))) (check-error-tag 'no-such-key (lambda () (bind-key 12345678 0 #f))) (check-error-tag 'no-such-key (lambda () (bind-key -1 0 #f))) (check-error-tag 'no-such-key (lambda () (bind-key 12 17 #f))) (check-error-tag 'no-such-key (lambda () (bind-key 12 -1 #f))) (check-error-tag 'no-such-key (lambda () (key-binding 12345678 0))) (check-error-tag 'no-such-key (lambda () (key-binding -1 0))) (check-error-tag 'no-such-key (lambda () (key-binding 12 17))) (check-error-tag 'no-such-key (lambda () (key-binding 12 -1))) (check-error-tag 'bad-header (lambda () (file->array (string-append sf-dir "bad_chans.snd") 0 0 123 (make-float-vector 123)))) (check-error-tag 'bad-header (lambda () (make-readin (string-append sf-dir "bad_chans.snd")))) (check-error-tag 'mus-error (lambda () (make-iir-filter 30 (make-float-vector 3)))) (check-error-tag 'out-of-range (lambda () (make-wave-train :size (expt 2 30)))) (check-error-tag 'out-of-range (lambda () (set! *clm-srate* 0.0))) (check-error-tag 'out-of-range (lambda () (set! *clm-srate* -1000))) (check-error-tag 'out-of-range (lambda () (dot-product (make-float-vector 3) (make-float-vector 3) -1))) (check-error-tag 'out-of-range (lambda () (make-delay 3 :initial-element 0.0 :initial-contents (float-vector .1 .2 .3)))) (check-error-tag 'out-of-range (lambda () (make-delay 3 :max-size 100 :initial-contents (float-vector .1 .2 .3)))) (check-error-tag 'out-of-range (lambda () (make-table-lookup :size 100 :wave (make-float-vector 3)))) (check-error-tag 'out-of-range (lambda () (make-wave-train :size 100 :wave (make-float-vector 3)))) ; (check-error-tag 'out-of-range (lambda () (make-granulate :max-size (expt 2 30)))) (check-error-tag 'out-of-range (lambda () (make-ssb-am 100 12345678))) (check-error-tag 'mus-error (lambda () (make-rand :envelope '(0 0 1 1) :distribution (make-float-vector 10)))) (check-error-tag 'mus-error (lambda () (make-rand :envelope '(0 0 1)))) (check-error-tag 'out-of-range (lambda () (make-rand :envelope '(0 0 1 1) :size -2))) (check-error-tag 'out-of-range (lambda () (make-rand :envelope '(0 0 1 1) :size 1234567890))) (check-error-tag 'mus-error (lambda () (let ((f (make-filter 3 :xcoeffs float-vector-3 :ycoeffs float-vector-3))) (mus-xcoeff f 4)))) (check-error-tag 'mus-error (lambda () (let ((f (make-filter 3 :xcoeffs float-vector-3 :ycoeffs float-vector-3))) (mus-ycoeff f 4)))) (check-error-tag 'mus-error (lambda () (let ((f (make-filter 3 :xcoeffs float-vector-3 :ycoeffs float-vector-3))) (set! (mus-xcoeff f 4) 1.0)))) (check-error-tag 'mus-error (lambda () (let ((f (make-filter 3 :xcoeffs float-vector-3 :ycoeffs float-vector-3))) (set! (mus-ycoeff f 4) 1.0)))) (check-error-tag 'mus-error (lambda () (make-filter :ycoeffs (make-float-vector 4) :order 12))) (check-error-tag 'mus-error (lambda () (let ((hi (make-oscil))) (set! (mus-offset hi) 1)))) (check-error-tag 'out-of-range (lambda () (make-locsig :channels (expt 2 30)))) (check-error-tag 'out-of-range (lambda () (make-src :width 3000))) (check-error-tag 'bad-arity (lambda () (add-colormap "baddy" (lambda () #f)))) (check-error-tag 'bad-arity (lambda () (add-colormap "baddy" (lambda (a b c) #f)))) ; (check-error-tag 'out-of-range (lambda () (make-phase-vocoder :fft-size (expt 2 30)))) (check-error-tag 'out-of-range (lambda () (let ((sr (make-src :input (lambda (dir) 1.0)))) (src sr 2000000.0)))) (check-error-tag 'out-of-range (lambda () (partials->polynomial '(1 1) -1))) (check-error-tag 'out-of-range (lambda () (partials->polynomial '(1 1) 3))) (check-error-tag 'out-of-range (lambda () (make-polyshape 440.0 :partials '(1 1) :kind -1))) (check-error-tag 'out-of-range (lambda () (make-polyshape 440.0 :partials '(1 1) :kind 3))) (check-error-tag 'wrong-type-arg (lambda () (normalize-partials 32))) (check-error-tag 'wrong-type-arg (lambda () (normalize-partials ()))) (check-error-tag 'bad-type (lambda () (normalize-partials '(1 2 3)))) (check-error-tag 'bad-type (lambda () (normalize-partials (float-vector 3)))) (check-error-tag 'no-data (lambda () (make-polyshape 440.0 :partials (float-vector 1 1 -2 1)))) (check-error-tag 'no-data (lambda () (make-polyshape 440.0 :partials (list 1 1 -2 1)))) ;(check-error-tag 'wrong-type-arg (lambda () (make-polyshape 440.0 :partials (list 1 1 "hi" 1)))) ; can be 'no-data etc ;(check-error-tag 'wrong-type-arg (lambda () (make-polyshape 440.0 :partials (list 1 1 2 "hi")))) (check-error-tag 'no-data (lambda () (make-polyshape 440.0 :partials (list)))) (check-error-tag 'wrong-type-arg (lambda () (set! (mus-header-raw-defaults) 1234))) (check-error-tag 'wrong-type-arg (lambda () (set! (mus-header-raw-defaults) (list 44100 2.123 "hi")))) (check-error-tag 'wrong-type-arg (lambda () (set! *with-toolbar* 123))) (check-error-tag 'wrong-type-arg (lambda () (set! *with-tooltips* 123))) (check-error-tag 'wrong-type-arg (lambda () (set! *with-menu-icons* 123))) (check-error-tag 'wrong-type-arg (lambda () (set! *save-as-dialog-src* 123))) (check-error-tag 'wrong-type-arg (lambda () (set! *save-as-dialog-auto-comment* 123))) (check-error-tag 'wrong-type-arg (lambda () (set! *with-smpte-label* 123))) (check-error-tag 'wrong-type-arg (lambda () (set! *ask-about-unsaved-edits* 123))) (check-error-tag 'no-such-mix (lambda () (mix-properties (integer->mix (+ 1 (mix-sync-max)))))) (check-error-tag 'no-such-mix (lambda () (set! (mix-properties (integer->mix (+ 1 (mix-sync-max)))) 1))) )) ;; xen.h over-optimization regression check (catch #t (lambda () (set! (x-zoom-slider -1) 123)) (lambda args (let ((str (apply format #f (cadr args)))) (if (not (string=? str "set! x-zoom-slider: no such sound: -1")) (snd-display #__line__ ";x-zoom-slider error: ~S~%" str))))) (catch #t (lambda () (set! (y-zoom-slider -1) 123)) (lambda args (let ((str (apply format #f (cadr args)))) (if (not (string=? str "set! y-zoom-slider: no such sound: -1")) (snd-display #__line__ ";y-zoom-slider error: ~S~%" str))))) (catch #t (lambda () (set! (beats-per-measure -1) 123)) (lambda args (let ((str (apply format #f (cadr args)))) (if (not (string=? str "set! beats-per-measure: no such sound: -1")) (snd-display #__line__ ";beats-per-measure error: ~S~%" str))))) (if (pair? (sounds)) (snd-display #__line__ ";sounds after error checks: ~A~%" (map short-file-name (sounds)))) (if (provided? 'snd-motif) (for-each (lambda (n name) (let ((tag (catch #t (lambda () (n (list 'Widget 0))) (lambda args (car args))))) (if (not (eq? tag 'no-such-widget)) (snd-display #__line__ ";~A of null widget -> ~A" name tag)))) (list widget-position widget-size widget-text hide-widget show-widget focus-widget) (list 'widget-position 'widget-size 'widget-text 'hide-widget 'show-widget 'focus-widget))) ;; ---------------- key args (for-each (lambda (arg1) (for-each (lambda (arg2) (for-each (lambda (n) (catch #t (lambda () (n arg1 arg2)) (lambda args (car args)))) make-procs)) (list 1.5 str-3 (list 0 1) 12 float-vector-3 :wave -1 0 1 #f #t () vector-0 delay-32))) keyargs) (if (and all-args (= test-28 0)) (begin (for-each (lambda (arg1) (for-each (lambda (arg2) (for-each (lambda (arg3) (for-each (lambda (n) (catch #t (lambda () (n arg1 arg2 arg3)) (lambda args (car args)))) make-procs)) (list 1.5 str-3 (list 0 1) 12 float-vector-3 :wave -1 0 1 #f #t () vector-0 delay-32))) keyargs)) (list 1.5 str-3 (list 0 1) 12 float-vector-3 :wave -1 0 1 #f #t () vector-0 delay-32)) (for-each (lambda (arg1) (for-each (lambda (arg2) (for-each (lambda (arg3) (for-each (lambda (arg4) (for-each (lambda (n) (catch #t (lambda () (n arg1 arg2 arg3 arg4)) (lambda args (car args)))) make-procs)) keyargs)) (list 1.5 str-3 (list 0 1) 12 float-vector-3 :wave -1 0 1 #f #t () vector-0 delay-32))) keyargs)) (list 1.5 str-3 (list 0 1) 12 float-vector-3 :wave -1 0 1 #f #t () vector-0 delay-32)))) ; (if all-args (snd-display #__line__ ";args: ~A~%" (strftime "%d-%b %H:%M %Z" (localtime (current-time))))) ;; ---------------- 0 Args (for-each (lambda (n) (let ((err (catch #t n (lambda args (car args))))) (if (eq? err 'wrong-number-of-args) (snd-display #__line__ ";procs0: ~A ~A" err (procedure-documentation n))))) procs0) (dismiss-all-dialogs) (for-each close-sound (sounds)) (let* ((main-args (list 1.5 str-3 (list 0 1) 12 float-vector-3 color-95 #(0 1) 3/4 'mus-error 0+i delay-32 (lambda () #t) float-vector-5 :order 0 1 -1 a-hook #f #t #\c 0.0 -1.0 () 3 64 -64 vector-0 '(1 . 2) (expt 2.0 21.5) (expt 2.0 -18.0) car-main cadr-main (lambda (a) #f) abs 1.0+1.0i (cons 1 2) '((1 2) (3 4)) '((1 (2)) (((3) 4))) (vector 1 #\a '(3)) (make-vector 0) (let ((x 3)) (lambda (y) (+ x y))) (lambda args args) "" (make-hash-table 256) # # # (random-state 12) (float-vector) (vector))) (few-args (list 1.5 str-3 (list 0 1) 12 float-vector-3 color-95 #(0 1) 3/4 -1.0 (float-vector) (vector) (list) (string) 0+i delay-32 :feedback -1 0 1 'hi (lambda (a) (+ a 1)) -64 #f #t vector-0)) (less-args (if all-args main-args few-args))) ;; ---------------- 1 Arg (for-each (lambda (arg) (for-each (lambda (n) (catch #t (lambda () (n arg)) (lambda args (if (eq? (car args) 'wrong-number-of-args) (snd-display #__line__ ";procs1 wna: ~A" (procedure-documentation n)))))) procs1)) main-args) (for-each close-sound (sounds)) ;; ---------------- 2 Args (for-each (lambda (arg1) (for-each (lambda (arg2) (for-each (lambda (n) (catch #t (lambda () (n arg1 arg2)) (lambda args (if (eq? (car args) 'wrong-number-of-args) (snd-display #__line__ ";procs2: ~A" (procedure-documentation n)))))) procs2)) main-args)) main-args) (for-each close-sound (sounds)) ;; ---------------- set! no Args (for-each (lambda (arg) (for-each (lambda (n) (catch #t (lambda () (set! (n) arg)) (lambda args (if (eq? (car args) 'wrong-number-of-args) (snd-display #__line__ ";set-procs0: ~A" (procedure-documentation n)))))) set-procs0)) main-args) (for-each close-sound (sounds)) ;; ---------------- set! 1 Arg (for-each (lambda (arg1) (for-each (lambda (arg2) (for-each (lambda (n) (catch #t (lambda () (set! (n arg1) arg2)) (lambda args (if (eq? (car args) 'wrong-number-of-args) (snd-display #__line__ ";set-procs1: ~A" (procedure-documentation n)))))) set-procs1)) main-args)) main-args) (for-each close-sound (sounds)) ;; ---------------- set! 2 Args (for-each (lambda (arg1) (for-each close-sound (sounds)) (for-each (lambda (arg2) (for-each (lambda (arg3) (for-each (lambda (n) (catch #t (lambda () (set! (n arg1 arg2) arg3)) (lambda args (if (eq? (car args) 'wrong-number-of-args) (snd-display #__line__ ";set-procs2: ~A" (procedure-documentation n)))))) set-procs2)) less-args)) less-args)) less-args) (set! delay-32 #f) (set! color-95 #f) (set! vector-0 #f) (set! float-vector-3 #f) (set! *clm-srate* 22050) (set! *print-length* 12) (set! *mus-array-print-length* 12) (set! (sound-file-extensions) exts) (set! car-main #f) (set! cadr-main #f) (set! a-hook #f) (set! float-vector-5 #f) ))))) ;;; ---------------- test 26: s7 ---------------- (define (snd_test_26) (load "s7test.scm")) (define test-funcs (make-vector (+ 1 total-tests))) (set! (test-funcs 0) snd_test_0) (set! (test-funcs 1) snd_test_1) (set! (test-funcs 2) snd_test_2) (set! (test-funcs 3) snd_test_3) (set! (test-funcs 4) snd_test_4) (set! (test-funcs 5) snd_test_5) (set! (test-funcs 6) snd_test_6) (set! (test-funcs 7) snd_test_7) (set! (test-funcs 8) snd_test_8) (set! (test-funcs 9) snd_test_9) (set! (test-funcs 10) snd_test_10) (set! (test-funcs 11) snd_test_11) (set! (test-funcs 12) snd_test_12) (if (or (and (not (provided? 'openbsd)) (not (provided? 'freebsd))) (not (provided? 'snd-gtk))) (begin (set! (test-funcs 13) snd_test_13) (set! (test-funcs 14) snd_test_14) (set! (test-funcs 15) snd_test_15)) (begin (set! (test-funcs 13) (lambda () #f)) (set! (test-funcs 14) (lambda () #f)) (set! (test-funcs 15) (lambda () #f)))) (set! (test-funcs 16) snd_test_16) (set! (test-funcs 17) snd_test_17) (set! (test-funcs 18) snd_test_18) (set! (test-funcs 19) snd_test_19) (set! (test-funcs 20) snd_test_20) (set! (test-funcs 21) snd_test_21) (set! (test-funcs 22) snd_test_22) (set! (test-funcs 23) snd_test_23) (set! (test-funcs 24) snd_test_24) (set! (test-funcs 25) snd_test_25) (set! (test-funcs 26) snd_test_26) (if (> test-at-random 0) (do ((i 0 (+ i 1))) ; run tests in any random order ((= i test-at-random)) (set! snd-test (random 23)) (if (> snd-test 22) (set! snd-test 22)) (format *stderr* "~%~A: ~A~%" i snd-test) (before-test-hook snd-test) ((vector-ref test-funcs snd-test)) (after-test-hook snd-test)) (if (and (not full-test) (not keep-going) (>= snd-test 0)) (begin ; run one test (before-test-hook snd-test) ((vector-ref test-funcs snd-test)) (after-test-hook snd-test)) (do ((i 0 (+ i 1))) ; run all tests except the irritating ones ((> i total-tests)) (if (and (or (< i 23) (> i 24)) (or full-test (and keep-going (<= snd-test i)))) (begin (before-test-hook i) ((vector-ref test-funcs i)) (after-test-hook i)))))) ;;; ---------------- test all done (for-each forget-region (regions)) (if with-motif (set! (view-files-sort) 0)) (stop-playing) (mus-oss-set-buffers 4 12) (reset-all-hooks) (set! *ask-about-unsaved-edits* #f) (set! *remember-sound-state* #f) ;(save-listener "test.output") (set! *listener-prompt* original-prompt) (clear-listener) (set! (show-listener) #t) (format #t "~%;all done!~%~A" original-prompt) (set! *print-length* 64) (format *stderr* "~%;times: ~A~%;total: ~A~%" timings (round (- (real-time) overall-start-time))) ;; #(59 58 114 95 2244 5373 613 134 11680 2892 609 743 868 976 815 1288 3020 197 168 2952 758 1925 4997 6567 846 183 0 242 6696 0))) ; 571 ;; ;; 19-Dec-12: #(1 1 2 2 69 240 6 1 583 1 23 1 1 17 70 1 233 1 1 271 89 119 1 1877 0 0 0 1 1 73) ; 37 ;; 23-Dec-12: #(1 1 2 1 67 243 7 1 586 1 16 1 2 18 63 1 223 1 1 270 92 115 1 1821 0 0 0 1 1 80) ; 36 ;; 26-Dec-12: #(1 1 2 1 65 199 6 1 556 1 15 1 1 12 26 1 229 1 1 276 52 108 1 1777 0 0 0 1 2 75) ; 34 ;; 1-Jan-13: #(1 1 2 2 64 200 7 1 575 1 17 1 2 12 84 1 246 1 1 215 45 111 1 1552 0 0 0 1 2 77) ; 32 ;; 3-Jan-13: #(1 1 2 1 65 185 6 1 564 1 20 1 2 11 26 1 202 1 1 213 45 109 1 1545 0 0 0 1 1 80) ; 31 ;; 9-Jan-13: #(1 1 2 1 63 181 7 1 540 1 19 1 2 11 22 1 201 1 1 207 44 107 1 1504 0 0 0 1 1 79) ; 30 ;; 25-Jan-13: #(1 1 2 1 58 178 6 1 505 1 13 1 2 10 20 1 205 1 1 198 44 111 1 1487 0 0 0 1 1 75) ; 29 ;; 11-Feb-13: #(1 1 3 2 49 170 5 1 463 1 15 1 1 11 46 1 216 1 2 158 42 110 1 1456 0 0 0 1 1 80) ; 28 ;; 15-Feb-13: #(1 1 2 2 42 160 5 1 450 1 18 1 1 10 21 1 196 1 1 158 42 107 1 1407 0 0 0 1 1 79) ; 27 ;; 21-Feb-13: #(1 1 2 2 43 159 6 1 448 1 12 1 2 10 20 1 189 1 2 156 41 106 1 1331 0 0 0 1 1 76) ; 26 ;; 26-Feb-13: #(1 1 2 2 42 118 5 1 450 1 16 1 2 11 19 1 97 1 1 161 42 105 1 1323 0 0 0 1 2 74) ; 25 ;; 1-Mar-13: #(1 1 3 1 40 117 5 1 439 1 16 1 2 11 20 1 109 1 2 159 43 100 1 1263 0 0 0 1 2 78) ; 24 ;; 7-Mar-13: #(1 1 2 2 41 119 6 1 396 1 16 1 2 10 23 1 103 1 1 144 41 85 1 1215 0 0 0 1 1 80) ; 23 ;; 8-Mar-13: #(1 1 3 2 32 102 5 1 363 1 15 1 2 10 21 1 90 1 1 144 41 87 1 1219 0 0 0 1 2 78) ; 22 ;; 14-Mar-13: #(1 1 2 2 31 92 4 1 316 1 19 1 2 12 17 1 80 1 1 121 40 81 1 1174 0 0 0 1 1 75) ; 21 ;; 20-Mar-13: #(1 1 2 2 30 90 4 1 317 1 12 1 1 10 22 1 79 1 1 115 40 78 1 1131 0 0 0 1 2 79) ; 20 ;; 3-Apr-13: #(1 1 2 2 30 89 4 1 297 1 11 1 2 10 9 1 81 1 1 110 41 73 1 1048 0 0 0 1 2 80) ; 19 ;; 14-Apr-13: #(1 1 2 2 31 88 4 1 288 1 16 1 2 10 17 1 77 1 1 110 39 73 1 975 0 0 0 1 2 75) ; 18 ;; 21-Apr-13: #(1 1 2 2 27 88 4 1 266 1 15 1 2 10 15 1 78 1 1 97 39 69 1 917 0 0 0 1 2 77) ; 17 ;; 24-Feb-14: #(1 1 2 1 22 74 2 1 162 2 9 1 3 8 9 2 54 2 70 33 24 2 791 0 0 1 82) ; 14 ;; 15-Mar-14: #(1 2 3 2 25 71 3 2 129 1 8 1 2 8 14 2 45 2 74 32 25 1 781 0 0 2 81) ; 13 ;; 1-Oct-14: #(1 2 2 2 22 68 2 2 114 2 9 1 3 8 50 1 45 2 70 32 26 2 749 0 0 2 113) ; 13 ;; 9-Mar-15: #(1 1 3 2 86 69 3 3 131 1 8 2 2 8 8 3 43 2 71 30 33 2 697 0 0 3 130) ; 13 ;; 29-May-15: #(2 3 3 3 22 79 3 3 130 3 8 3 4 9 9 3 49 3 75 30 28 3 708 0 0 3 144) ; 13 ;;; -------- cleanup temp files (if (provided? 'snd-nogui) (set! *max-regions* 0)) (if (file-exists? "saved-snd.scm") (delete-file "saved-snd.scm")) (if (file-exists? original-save-dir) (begin ;(format #t "ls ~A/snd_* | wc~%" original-save-dir) ;(system (format #f "ls ~A/snd_* | wc" original-save-dir)) (system (format #f "rm -f ~A/snd_*" original-save-dir)))) (if (file-exists? original-temp-dir) (begin ;(format #t "ls ~A/snd_* | wc~%" original-temp-dir) ;(system (format #f "ls ~A/snd_* | wc" original-temp-dir)) (system (format #f "rm -f ~A/snd_*" original-temp-dir)))) (if (file-exists? "/tmp") (begin ;(format #t "ls /tmp/snd_* | wc~%") ;(system "ls /tmp/snd_* | wc") (system "rm -f /tmp/snd_*") ;(system "ls /tmp/file*.snd | wc") (system "rm -f /tmp/file*.snd"))) (if (file-exists? "/var/tmp") (begin ;(format #t "ls /var/tmp/snd_* | wc~%") ;(system "ls /var/tmp/snd_* | wc") (system "rm -f /var/tmp/snd_*") ;(system "ls /var/tmp/file*.snd | wc") (system "rm -f /var/tmp/file*.snd"))) (if (defined? 'dlocsig-speaker-configs) (set! dlocsig-speaker-configs #f)) (for-each (lambda (f) (if (file-exists? f) (delete-file f))) (list "aaa.eps" "envs.save" "fmv.snd" "fmv.wav" "fmv0.snd" "fmv1.snd" "fmv2.snd" "fmv3.snd" "fmv4.reverb" "fmv4.snd" "hiho.marks" "hiho.snd" "hiho.snd" "hiho.tmp" "hiho.wave" "ho" "new.snd" "oboe.marks" "obtest.snd.stereo" "snd.eps" "test-1.snd" "test-2.snd" "test-macros.scm" "test.aiff" "testx.data" "test.output" "test.rev" "test.reverb" "test.snd" "test.snd.snd" "test.wav" "test.xpm" "test2.snd" "test3.snd" "tmp.snd" "with-mix.snd" "1" "gtk-errors" "accelmap" ".snd-remember-sound" "test.clm" "hiho.scm" (string-append sf-dir "mus10.snd.snd") (string-append sf-dir "ieee-text-16.snd.snd") (string-append sf-dir "trumps22.adp.snd") (string-append sf-dir "oki.wav.snd") (string-append sf-dir "nasahal.avi.snd") (string-append sf-dir "hcom-16.snd.snd") (string-append sf-dir "ce-c3.w02.snd") ; (string-append sf-dir "oboe.g723_24.snd") ; (string-append sf-dir "oboe.g723_40.snd") ; (string-append sf-dir "oboe.g721.snd") (string-append sf-dir "wood.sds.snd") (string-append sf-dir "o2_dvi.wave.snd") (string-append sf-dir "nist-shortpack.wav.snd") (string-append sf-dir "bad_data_format.snd.snd") )) (if (file-exists? "/home/bil/peaks") (system "rm /home/bil/peaks/*")) (for-each close-sound (sounds)) (mus-sound-prune) (if (and with-motif (dialog-widgets)) (let ((vfs ((dialog-widgets) 5))) ; view-files (possible list) (if vfs (if (symbol? (car vfs)) (set! (view-files-files vfs) ()) (for-each (lambda (d) (set! (view-files-files d) ())) vfs))))) #| (let ((st (symbol-table))) (for-each (lambda (sym) (if (defined? sym) (let ((val (symbol->value sym))) (if (and (procedure? val) (string=? "" (procedure-documentation val))) (snd-display #__line__ "~A " sym))))) st)) |# (gc) (gc) (s7-version) (if with-exit (exit)) ;;; ---------------- test the end #| valgrind --tool=callgrind snd -l snd-test callgrind_annotate --auto=yes callgrind.out. > hi 10-Feb-10 (full snd-test, not just test 23): 372,028,372,850 45,638,227,518 io.c:mus_read_any_1 [/home/bil/snd-11/snd] 44,386,146,639 s7.c:eval [/home/bil/snd-11/snd] 26,599,493,642 s7.c:eval'2 [/home/bil/snd-11/snd] 20,950,395,846 s7.c:gc [/home/bil/snd-11/snd] 20,800,612,761 snd-edits.c:next_sample_value_unscaled [/home/bil/snd-11/snd] 17,699,734,242 snd-edits.c:channel_local_maxamp [/home/bil/snd-11/snd] 14,661,979,458 io.c:mus_write_1 [/home/bil/snd-11/snd] 14,486,041,393 snd-sig.c:direct_filter [/home/bil/snd-11/snd] 10,836,543,187 run.c:eval_ptree [/home/bil/snd-11/snd] 10-Dec-10 (64-bit) 224,005,122,781 32,349,320,555 s7.c:eval [/home/bil/snd-11/snd] 24,560,182,751 s7.c:eval'2 [/home/bil/snd-11/snd] 19,534,468,570 ???:sin [/lib64/libm-2.12.so] 16,408,681,106 io.c:mus_read_any_1 [/home/bil/snd-11/snd] 11,540,583,151 snd-edits.c:channel_local_maxamp [/home/bil/snd-11/snd] 11,175,405,494 s7.c:gc [/home/bil/snd-11/snd] 8,937,855,502 run.c:eval_ptree [/home/bil/snd-11/snd] 8,913,093,185 snd-sig.c:direct_filter [/home/bil/snd-11/snd] 14-Dec-11: 153,472,402,051 15,964,352,672 ???:sin [/lib64/libm-2.12.so] 15,349,566,001 io.c:mus_read_any_1 [/home/bil/snd-16/snd] 9,724,315,504 s7.c:eval [/home/bil/snd-16/snd] 9,340,050,109 snd-edits.c:channel_local_maxamp [/home/bil/snd-16/snd] 8,904,652,480 snd-sig.c:direct_filter [/home/bil/snd-16/snd] 8,727,766,020 run.c:eval_ptree [/home/bil/snd-16/snd] 7,219,826,287 io.c:mus_write_1 [/home/bil/snd-16/snd] 5,925,019,812 s7.c:eval'2 [/home/bil/snd-16/snd] 2,960,895,840 clm.c:mus_fir_filter [/home/bil/snd-16/snd] 2,765,667,308 clm.c:mus_out_any_to_file [/home/bil/snd-16/snd] 2,732,722,538 ???:cos [/lib64/libm-2.12.so] 2,654,002,973 clm.c:mus_src [/home/bil/snd-16/snd] 2,216,029,830 s7.c:find_symbol_or_bust [/home/bil/snd-16/snd] 2,051,926,172 s7.c:gc [/home/bil/snd-16/snd] 2-Jul-12: 152,015,041,884 15,958,491,763 ???:sin [/lib64/libm-2.12.so] 14,742,080,012 io.c:mus_read_any_1 [/home/bil/snd-16/snd] 10,457,919,006 s7.c:eval [/home/bil/snd-16/snd] 9,312,647,839 snd-edits.c:channel_local_maxamp [/home/bil/snd-16/snd] 8,913,093,185 snd-sig.c:direct_filter [/home/bil/snd-16/snd] 8,725,479,212 run.c:eval_ptree [/home/bil/snd-16/snd] 7,219,930,929 io.c:mus_write_1 [/home/bil/snd-16/snd] 4,366,174,949 s7.c:eval'2 [/home/bil/snd-16/snd] 3,042,551,502 clm.c:mus_src [/home/bil/snd-16/snd] 2,960,895,840 clm.c:mus_fir_filter [/home/bil/snd-16/snd] 2,762,641,235 clm.c:mus_out_any_to_file [/home/bil/snd-16/snd] 2,745,046,475 ???:cos [/lib64/libm-2.12.so] 2,227,836,598 s7.c:find_symbol_or_bust [/home/bil/snd-16/snd] 1,839,006,887 s7.c:gc [/home/bil/snd-16/snd] 1,306,950,910 run.c:eval_ptree'2 [/home/bil/snd-16/snd] 1,273,733,564 ???:t2_32 [/home/bil/snd-16/snd] 1,259,047,832 clm.c:mus_formant_bank [/home/bil/snd-16/snd] 1,204,213,789 snd-edits.c:next_sample_value [/home/bil/snd-16/snd] 1,129,624,275 clm.c:mus_ssb_am_unmodulated [/home/bil/snd-16/snd] 1,116,765,922 clm.c:mus_phase_vocoder_with_editors [/home/bil/snd-16/snd] 6-Jul-12: 314,557,435,854 96,266,822,080 s7.c:eval [/home/bil/snd-16/snd] 20,140,459,790 s7.c:find_symbol_or_bust [/home/bil/snd-16/snd] 15,094,536,285 ???:sin [/lib64/libm-2.12.so] 14,561,228,879 io.c:mus_read_any_1 [/home/bil/snd-16/snd] 13,267,844,138 s7.c:gc [/home/bil/snd-16/snd] 10,735,806,413 s7.c:s7_make_real [/home/bil/snd-16/snd] 9,597,104,099 snd-edits.c:channel_local_maxamp [/home/bil/snd-16/snd] 8,903,732,430 snd-sig.c:direct_filter [/home/bil/snd-16/snd] 8,756,184,253 s7.c:eval'2 [/home/bil/snd-16/snd] 6,939,439,659 io.c:mus_write_1 [/home/bil/snd-16/snd] 4,221,129,319 s7.c:g_add [/home/bil/snd-16/snd] 3,790,496,511 s7.c:g_multiply_2 [/home/bil/snd-16/snd] 2,960,895,524 clm.c:mus_fir_filter [/home/bil/snd-16/snd] 2,866,346,964 s7.c:g_equal_2 [/home/bil/snd-16/snd] 2,647,149,349 clm.c:mus_src [/home/bil/snd-16/snd] 2,373,255,704 s7.c:g_add_2 [/home/bil/snd-16/snd] 2,365,017,452 s7.c:g_add_1s [/home/bil/snd-16/snd] 2,014,711,657 ???:cos [/lib64/libm-2.12.so] 23-Apr-13: 52,886,592,302 6,697,050,795 s7.c:eval [/home/bil/snd-16/snd] 6,228,616,918 ???:sin [/lib64/libm-2.12.so] 2,546,631,823 clm.c:mus_src [/home/bil/snd-16/snd] 2,496,647,180 ???:cos [/lib64/libm-2.12.so] 2,176,750,987 s7.c:find_symbol_or_bust [/home/bil/snd-16/snd] 1,263,726,083 s7.c:eval'2 [/home/bil/snd-16/snd] 1,248,608,065 s7.c:gc [/home/bil/snd-16/snd] 1,021,282,278 io.c:mus_read_any_1 [/home/bil/snd-16/snd] 1,003,986,022 clm.c:mus_phase_vocoder_with_editors [/home/bil/snd-16/snd] 933,290,098 clm.c:mus_formant_bank [/home/bil/snd-16/snd] 911,248,552 clm.c:fir_8 [/home/bil/snd-16/snd] 885,305,356 ???:t2_32 [/home/bil/snd-16/snd] 796,412,317 snd-edits.c:channel_local_maxamp [/home/bil/snd-16/snd] 785,981,295 ???:t2_64 [/home/bil/snd-16/snd] 693,360,038 clm.c:run_hilbert [/home/bil/snd-16/snd] 507,150,000 clm.c:mus_formant_bank_with_inputs [/home/bil/snd-16/snd] 459,853,855 clm.c:mus_src_20 [/home/bil/snd-16/snd] 449,476,048 ???:n1_64 [/home/bil/snd-16/snd] 444,970,752 io.c:mus_write_1 [/home/bil/snd-16/snd] 428,928,818 float-vector.c:g_float-vector_add [/home/bil/snd-16/snd] 27-Apr-14: 35,390,341,125 5,444,441,772 s7.c:eval [/home/bil/gtk-snd/snd] 2,255,959,839 ???:sin [/lib64/libm-2.12.so] 2,027,776,135 ???:cos [/lib64/libm-2.12.so] 1,266,976,906 clm.c:fir_ge_20 [/home/bil/gtk-snd/snd] 1,041,138,903 clm.c:mus_src [/home/bil/gtk-snd/snd] 886,288,100 ???:t2_32 [/home/bil/gtk-snd/snd] 784,981,866 s7.c:gc [/home/bil/gtk-snd/snd] 781,643,274 ???:t2_64 [/home/bil/gtk-snd/snd] 653,499,001 snd-edits.c:channel_local_maxamp [/home/bil/gtk-snd/snd] 648,406,214 clm.c:mus_phase_vocoder_with_editors [/home/bil/gtk-snd/snd] 592,801,688 clm.c:fb_one_with_amps_c1_c2 [/home/bil/gtk-snd/snd] 558,124,334 io.c:mus_read_any_1 [/home/bil/gtk-snd/snd] 449,476,076 ???:n1_64 [/home/bil/gtk-snd/snd] 418,857,421 s7.c:eval'2 [/home/bil/gtk-snd/snd] 414,027,948 vct.c:g_vct_add [/home/bil/gtk-snd/snd] 394,639,129 clm.c:mus_src_to_buffer [/home/bil/gtk-snd/snd] 372,681,428 clm.c:mus_env_linear [/home/bil/gtk-snd/snd] 338,359,320 clm.c:run_hilbert [/home/bil/gtk-snd/snd] 327,141,926 clm.c:fb_many_with_amps_c1_c2 [/home/bil/gtk-snd/snd] 14-Aug-14: 35,133,061,231 5,365,681,646 s7.c:eval [/home/bil/gtk-snd/snd] 2,256,581,832 ???:sin [/lib64/libm-2.12.so] 2,050,537,059 ???:cos [/lib64/libm-2.12.so] 1,266,976,906 clm.c:fir_ge_20 [/home/bil/gtk-snd/snd] 1,095,141,759 clm.c:mus_src [/home/bil/gtk-snd/snd] 901,140,028 ???:t2_32 [/home/bil/gtk-snd/snd] 795,199,572 s7.c:gc [/home/bil/gtk-snd/snd] 720,395,914 ???:t2_64 [/home/bil/gtk-snd/snd] 648,414,838 clm.c:mus_phase_vocoder_with_editors [/home/bil/gtk-snd/snd] 592,801,688 clm.c:fb_one_with_amps_c1_c2 [/home/bil/gtk-snd/snd] 573,460,056 snd-edits.c:channel_local_maxamp [/home/bil/gtk-snd/snd] 557,892,664 io.c:mus_read_any_1 [/home/bil/gtk-snd/snd] 452,423,080 s7.c:eval'2 [/home/bil/gtk-snd/snd] 435,066,604 ???:n1_64 [/home/bil/gtk-snd/snd] 414,027,948 vct.c:g_vct_add [/home/bil/gtk-snd/snd] 405,194,494 clm.c:mus_src_to_buffer [/home/bil/gtk-snd/snd] 379,588,776 clm.c:mus_env_linear [/home/bil/gtk-snd/snd] 338,359,320 clm.c:run_hilbert [/home/bil/gtk-snd/snd] 327,141,926 clm.c:fb_many_with_amps_c1_c2 [/home/bil/gtk-snd/snd] 18-Jan-15: 34,313,456,123 5,020,772,013 s7.c:eval [/home/bil/motif-snd/snd] 2,260,969,439 ???:sin [/lib64/libm-2.12.so] 2,034,364,836 ???:cos [/lib64/libm-2.12.so] 1,267,013,962 clm.c:fir_ge_20 [/home/bil/motif-snd/snd] 1,031,565,836 clm.c:mus_src [/home/bil/motif-snd/snd] 902,070,908 ???:t2_32 [/home/bil/motif-snd/snd] 736,726,776 ???:t2_64 [/home/bil/motif-snd/snd] 703,948,457 s7.c:gc [/home/bil/motif-snd/snd] 638,189,523 clm.c:mus_phase_vocoder_with_editors [/home/bil/motif-snd/snd] 602,023,066 snd-edits.c:channel_local_maxamp [/home/bil/motif-snd/snd] 594,199,460 clm.c:fb_one_with_amps_c1_c2 [/home/bil/motif-snd/snd] 488,422,860 io.c:mus_read_any_1 [/home/bil/motif-snd/snd] 439,946,024 ???:n1_64 [/home/bil/motif-snd/snd] 428,393,510 s7.c:eval'2 [/home/bil/motif-snd/snd] 414,054,253 vct.c:g_vct_add [/home/bil/motif-snd/snd] 365,408,166 clm.c:mus_env_linear [/home/bil/motif-snd/snd] 362,204,844 clm.c:mus_src_to_buffer [/home/bil/motif-snd/snd] 345,704,896 clm.c:run_hilbert [/home/bil/motif-snd/snd] 330,406,288 clm.c:fb_many_with_amps_c1_c2 [/home/bil/motif-snd/snd] 15-Feb-15: 33,895,270,323 5,048,563,075 s7.c:eval [/home/bil/motif-snd/snd] 2,109,026,775 ???:sin [/lib64/libm-2.12.so] 2,024,119,795 ???:cos [/lib64/libm-2.12.so] 1,267,013,962 clm.c:fir_ge_20 [/home/bil/motif-snd/snd] 1,033,000,931 clm.c:mus_src [/home/bil/motif-snd/snd] 902,016,316 ???:t2_32 [/home/bil/motif-snd/snd] 736,981,999 ???:t2_64 [/home/bil/motif-snd/snd] 698,073,576 s7.c:gc [/home/bil/motif-snd/snd] 627,011,081 clm.c:mus_phase_vocoder_with_editors [/home/bil/motif-snd/snd] 594,199,460 clm.c:fb_one_with_amps_c1_c2 [/home/bil/motif-snd/snd] 584,394,041 snd-edits.c:channel_local_maxamp [/home/bil/motif-snd/snd] 489,621,727 io.c:mus_read_any_1 [/home/bil/motif-snd/snd] 440,021,064 ???:n1_64 [/home/bil/motif-snd/snd] 434,398,893 s7.c:eval'2 [/home/bil/motif-snd/snd] 412,021,596 vct.c:g_vct_add [/home/bil/motif-snd/snd] 379,620,192 clm.c:mus_src_to_buffer [/home/bil/motif-snd/snd] 358,009,460 clm.c:mus_env_linear [/home/bil/motif-snd/snd] 345,704,896 clm.c:run_hilbert [/home/bil/motif-snd/snd] 330,406,288 clm.c:fb_many_with_amps_c1_c2 [/home/bil/motif-snd/snd] |# snd-16.1/snd-forth-docs.fs0000644000076400007640000001666312327306343013536 0ustar bilbil\ snd-forth-docs.fs -- examples from sndclm.html \ Usage: snd-forth-nogui -noinit snd-forth-docs.fs require clm require examp \ OSCIL lambda: ( -- ) 440.0 make-oscil { gen } 44100 0 do i gen 0 0 oscil f2/ *output* outa drop loop ; :play #t with-sound drop \ ENV lambda: ( -- ) 440.0 make-oscil { gen } '( 0 0 0.01 1 0.25 0.1 0.5 0.01 1 0 ) :scaler 0.5 :length 44100 make-env { ampf } 44100 0 do i gen 0 0 oscil ampf env f* *output* outa drop loop ; :play #t with-sound drop \ TABLE-LOOKUP lambda: ( -- ) 440.0 :wave '( 1 0.5 2 0.5 ) #f #f partials->wave make-table-lookup { gen } 44100 0 do i gen 0 table-lookup f2/ *output* outa drop loop ; :play #t with-sound drop \ POLYWAVE lambda: ( -- ) 440.0 :partials '( 1 0.5 2 0.5 ) make-polywave { gen } 44100 0 do i gen 0 polywave f2/ *output* outa drop loop ; :play #t with-sound drop \ TRIANBLE-WAVE lambda: ( -- ) 440.0 make-triangle-wave { gen } 44100 0 do i gen 0 triangle-wave f2/ *output* outa drop loop ; :play #t with-sound drop \ NCOS lambda: ( -- ) 440.0 10 make-ncos { gen } 44100 0 do i gen 0 ncos f2/ *output* outa drop loop ; :play #t with-sound drop \ NRXYCOS lambda: ( -- ) 440.0 :n 10 make-nrxycos { gen } 44100 0 ?do i gen 0 nrxycos f2/ *output* outa drop loop ; :play #t with-sound drop \ SSB-AM lambda: ( -- ) 440.0 20 make-ssb-am { shifter } 440.0 make-oscil { osc } 44100 0 ?do i shifter osc 0 0 oscil 0 ssb-am f2/ *output* outa drop loop ; :play #t :statistics #t :srate 44100 with-sound drop \ WAVE-TRAIN lambda: ( -- ) 400 10 make-ncos { g } g -0.5 pi f* set-mus-phase drop 64 make-vct map! g 0 ncos end-map { v } 440.0 :wave v make-wave-train { gen } 44100 0 do i gen 0 wave-train f2/ *output* outa drop loop ; :play #t with-sound drop \ RAND lambda: ( -- ) 5.0 220.0 hz->radians make-rand { ran1 } 5.0 330.0 hz->radians make-rand-interp { ran2 } 440.0 make-oscil { osc1 } 1320.0 make-oscil { osc2 } 88200 0 do i osc1 ran1 0 rand 0 oscil f2/ *output* outa drop i osc2 ran2 0 rand-interp 0 oscil f2/ *output* outb drop loop ; :channels 2 :play #t with-sound drop \ TWO-POLE lambda: ( -- ) 1000.0 0.999 make-two-pole { flt } 10000.0 0.002 make-rand { ran1 } 44100 0 do i flt ran1 0 rand two-pole f2/ *output* outa drop loop ; :play #t with-sound drop \ FIRMANT lambda: ( -- ) 1000.0 0.999 make-firmant { flt } 10000.0 5.0 make-rand { ran1 } 44100 0 do i flt ran1 0 rand #f firmant f2/ *output* outa drop loop ; :play #t with-sound drop \ IIR-FILTER lambda: ( -- ) 3 vct( 0.0 -1.978 0.998 ) make-iir-filter { flt } 10000.0 0.002 make-rand { ran1 } 44100 0 do i flt ran1 0 rand iir-filter f2/ *output* outa drop loop ; :play #t with-sound drop \ DELAY lambda: ( -- ) 0.5 seconds->samples make-delay { dly } 440.0 make-oscil { osc1 } 660.0 make-oscil { osc2 } 44100 0 do i osc1 0 0 oscil dly osc2 0 0 oscil 0 delay f+ f2/ *output* outa drop loop ; :play #t with-sound drop \ COMB lambda: ( -- ) 0.4 0.4 seconds->samples make-comb { cmb } 440.0 make-oscil { osc } '( 0 0 1 1 2 1 3 0 ) :length 4410 make-env { ampf } 88200 0 do i cmb ( gen ) ampf env osc 0 0 oscil f* ( val ) 0 ( pm ) comb f2/ *output* outa drop loop ; :play #t with-sound drop \ ALL-PASS lambda: ( -- ) -0.4 0.4 0.4 seconds->samples make-all-pass { alp } 440.0 make-oscil { osc } '( 0 0 1 1 2 1 3 0 ) :length 4410 make-env { ampf } 88200 0 do i alp ( gen ) ampf env osc 0 0 oscil f* ( val ) 0 ( pm ) all-pass f2/ *output* outa drop loop ; :play #t with-sound drop \ MOVING-AVERAGE lambda: ( -- ) 4410 make-moving-average { avg } 440.0 make-oscil { osc } 44100 4410 - { stop } 0.0 { val } stop 0 do osc 0 0 oscil to val i avg val fabs moving-average val f* *output* outa drop loop 44100 stop do i avg 0.0 moving-average osc 0 0 oscil f* *output* outa drop loop ; :play #t with-sound drop \ SRC1 lambda: ( -- ) "oboe.snd" make-readin { rd } rd 0.5 make-src { sr } "oboe.snd" mus-sound-framples 2* ( len ) 0 do i sr 0 #f src *output* outa drop loop ; :play #t :srate 22050 with-sound drop \ SRC2 : make-src-proc { osc -- prc; dir self -- val } 1 proc-create osc , ( prc ) does> { dir self -- val } self @ ( osc ) 0 0 oscil ; lambda: ( -- ) 440.0 make-oscil { osc } osc make-src-proc { prc } :srate 2.0 make-src { sr } 44100 0 do i sr 0 prc src *output* outa drop loop ; :play #t with-sound drop \ CONVOLVE1 lambda: ( -- ) "pistol.snd" make-readin ( rd ) "oboe.snd" file->vct ( v ) make-convolve { cnv } 88200 0 do i cnv #f convolve 0.25 f* *output* outa drop loop ; :play #t :statistics #t with-sound drop \ CONVOLVE2 lambda: ( -- ) "oboe.snd" "pistol.snd" 0.5 "convolved.snd" convolve-files { tempfile } tempfile make-readin { reader } tempfile mus-sound-framples ( len ) 0 do i reader readin *output* outa drop loop tempfile file-delete ; :play #t with-sound drop \ GRANULATE1 lambda: ( -- ) "oboe.snd" make-readin 2.0 make-granulate { grn } 44100 0 do i grn #f #f granulate *output* outa drop loop ; :play #t with-sound drop \ GRANULATE2 : make-granulate-proc { osc sweep -- prc; dir self -- val } 1 proc-create osc , sweep , ( prc ) does> { dir self -- val } self @ ( osc ) self cell+ @ ( sweep ) env 0 oscil 0.2 f* ; lambda: ( -- ) 440.0 make-oscil { osc } '( 0 0 1 1 ) :scaler 440.0 hz->radians :length 44100 make-env { sweep } osc sweep make-granulate-proc :expansion 2.0 :length 0.5 make-granulate { grn } 88200 0 do i grn #f #f granulate *output* outa drop loop ; :play #t with-sound drop \ PHASE-VOCODER1 lambda: ( -- ) "oboe.snd" make-readin :pitch 2.0 make-phase-vocoder { pv } 44100 0 do i pv #f #f #f #f phase-vocoder *output* outa drop loop ; :play #t with-sound drop \ PHASE-VOCODER2 lambda: ( -- ) "oboe.snd" make-readin :interp 256 make-phase-vocoder { pv } "oboe.snd" mus-sound-framples 2* ( samps ) 0 do i pv #f #f #f #f phase-vocoder *output* outa drop loop ; :play #t :srate 22050 with-sound drop \ ASYMMETRIC-FM lambda: ( -- ) 440.0 0.0 0.9 0.5 make-asymmetric-fm { fm } 44100 0 do i fm 1.0 0 asymmetric-fm f2/ *output* outa drop loop ; :play #t with-sound drop \ FILE->FRAME->FILE lambda: ( -- ) "stereo.snd" make-file->frame { input } 2 make-frame { frm } "stereo.snd" mus-sound-framples ( len ) 0 do input i frm file->frame ( frm ) 1 frame-ref ( val1 ) frm 0 frame-ref ( val0 ) frm 1 rot frame-set! drop ( val1 ) frm 0 rot frame-set! drop *output* i frm frame->file drop loop ; :channels 2 :play #t with-sound drop \ READIN lambda: ( -- ) "oboe.snd" make-readin { reader } 44100 0 do i reader readin f2/ *output* outa drop loop ; :play #t with-sound drop \ IN-OUT-ANY lambda: ( -- ) "oboe.snd" make-file->sample { infile } 44100 0 do i i 0 infile in-any 0 *output* out-any drop loop ; :play #t with-sound drop \ LOCSIG lambda: ( -- ) 60.0 make-locsig { loc } 440.0 make-oscil { osc } 44100 0 do loc i osc 0 0 oscil f2/ locsig drop loop ; :play #t :channels 2 with-sound drop \ AMPLITUDE-MODULATE lambda: ( -- ) 440.0 make-oscil { osc1 } 220.0 make-oscil { osc2 } 44100 0 do i 0.3 ( car ) osc1 0 0 oscil ( in1 ) osc2 0 0 oscil ( in2 ) amplitude-modulate f2/ *output* outa drop loop ; :play #t with-sound drop bye \ snd-forth-docs.fs ends here snd-16.1/dlocsig.rb0000644000076400007640000026470212462277004012323 0ustar bilbil# dlocsig.rb -- CLM -> Snd/Ruby translation of dlocsig.lisp # Translator/Author: Michael Scholz # Copyright (c) 2003-2012 Michael Scholz # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # Original Copyright of Fernando Lopez Lezcano: # ;;; Copyright (c) 92, 93, 94, 98, 99, 2000, 2001 Fernando Lopez Lezcano. # ;;; All rights reserved. # ;;; Use and copying of this software and preparation of derivative works # ;;; based upon this software are permitted and may be copied as long as # ;;; no fees or compensation are charged for use, copying, or accessing # ;;; this software and all copies of this software include this copyright # ;;; notice. Suggestions, comments and bug reports are welcome. Please # ;;; address email to: nando@ccrma.stanford.edu # ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; # ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; # ;;; Dynamic multichannel three-dimentional signal locator # ;;; (wow that sound good! :-) # ;;; # ;;; by Fernando Lopez Lezcano # ;;; CCRMA, Stanford University # ;;; nando@ccrma.stanford.edu # ;;; # ;;; Thanks to Juan Pampin for help in the initial coding of the new version # ;;; and for prodding me to finish it. To Joseph L. Anderson and Marcelo Perticone # ;;; for insights into the Ambisonics coding and decoding process. # ;;; http://www.york.ac.uk/inst/mustech/3d_audio/ambison.htm for more details... # Commentary: # Tested with Snd 7.10, Motif 2.2.2, Gtk+ 2.2.1, Ruby 1.6.6, 1.6.8 and 1.9.0. # # The code is a translation of the Lisp code of Fernando Lopez Lezcano # found in clm-2/dlocsig of the CLM distribution. An extensive # documentation of the purpose and usage of it can be found in # clm-2/dlocsig/dlocsig.html. # # Note: dlocsig.rb handles not more rev_channels than out_channels; # B_format_ambisonics handles only 4 out_channels and 0, 1, or 4 # rev_channels. # # The simple example # # [[-10, 10], [0, 5], [10, 10]].to_path.snd_plot # # draws trajectory, velocity, doppler curve, and the acceleration in # Snd's lisp-graph. If you have gnuplot installed, the example # # [[-10, 10], [0, 5], [10, 10]].to_path.pplot # # draws all four curves in one gnuplot window. # DL.make_path # DL.make_polar_path # DL.make_closed_path # and to_path take the following options # # Open_bezier_path.new(path, *args) # :d3, true # :polar, false # :error, 0.01 # :curvature, nil # :initial_direction, [0.0, 0.0, 0.0] # :final_direction, [0.0, 0.0, 0.0] # # Closed_bezier_path.new(path, *args) # :d3, true # :polar, false # :error, 0.01 # :curvature, nil # # DL.make_literal_path # DL.make_literal_polar_path take the following options # # Literal_path.new(path, *args) # :d3, true # :polar, false # # DL.make_spiral_path takes these options # # Spiral_path.new :start_angle, 0 # :turns, 2 # # The make_locsig-replacement make_dlocsig takes these arguments: # # DL.make_dlocsig(startime, dur, *args) # :path, nil # :scaler, 1.0 # :reverb_amount, 0.05 # :rbm_output, $output # :rbm_reverb, $reverb # :output_power, 1.5 # :reverb_power, 0.5 # :render_using, :amplitude_panning # or :b_format_ambisonics # or :decoded_ambisonics # # Sample instruments (sinewave() and move() below) show how to replace # the usual make_locsig() and locsig() by DL.make_dlocsig() and # DL.dlocsig(). # Example functions at the end of the file: # class Instrument # sinewave(start, dur, freq, amp, path, amp_env, *dlocsig_args) # move(start, file, path, *dlocsig_args) # move_sound(path, *dlocsig_args) do ... end # # class With_sound # run_dlocsig(start, dur, *dlocsig_args) do |samp| ... end # Classes and Modules: # module Inject # inject(n) # sum(initial) # product(initial) # # class Array # to_trias # to_path(*args) # # class Sndplot # initialize(chns) # snd # open # close # # class Gnuplot # initialize # open # close # command(*args) # reset # set_autoscale # set_x_range(range) # set_y_range(range) # set_z_range(range) # set_grid # set_surface # set_parametric # set_ticslevel(level) # set_title(title) # set_label(label) # set_margins(margin) # set_border(border) # start_multiplot # end_multiplot # size(xorigin, yorigin, xsize, ysize) # data(data, *args) # plot_2d_curve(curve, *args) # plot_2d_curves(curves, *args) # plot_3d_curve(curve, *args) # # module DL # class Dlocsig < Dlocs # initialize(start, dur, *args) # one_turn # one_turn=(val) # speed_of_sound # speed_of_sound=(val) # run_beg # run_end # angles_in_degree # angles_in_radians # angles_in_turns # distance_in_meters # distance_in_feet # # class Path # initialize(path, *args) # path_x # path_y # path_z # path_time # scale_path(scaling) # translate_path(translation) # rotate_path(rotation, *args) # # path_trajectory # path_2d_trajectory # path_velocity # path_doppler # path_acceleration # # plot_open # plot_close # cmd(*args) # plot_trajectory(*args) # plot_velocity(reset) # plot_doppler(reset) # plot_acceleration(reset) # pplot(normalize) # # snd_open(chns) # snd_close # snd_trajectory(chn, label) # snd_velocity(chn, label) # snd_doppler(chn, label) # snd_acceleration(chn, label) # snd_plot # # DL.make_dlocsig(start, dur, *args) # DL.dlocsig(dl, loc, input) # # DL.make_path(path, *args) # DL.make_polar_path(path, *args) # DL.make_closed_path(path, *args) # DL.make_literal_path(path, *args) # DL.make_literal_polar_path(path, *args) # DL.make_spiral_path(*args) # # class Dlocsig_menu # initialize(label, snd_p) # post_dialog # Code: require "ws" require "matrix" include Math provided?(:snd_motif) and (not provided?(:xm)) and require("libxm.so") provided?(:snd_gtk) and (not provided?(:xg)) and require("libxg.so") class DlocsigError < StandardError end Ruby_exceptions[:dlocsig_error] = DlocsigError def dl_error(*msg) Snd.raise(:dlocsig_error, (msg.empty? ? "" : format(*msg))) end # module Inject, see Thomas, David, Hunt, Andrew: Programming Ruby -- # The Pragmatic Programmer's Guide, 2001 Addison-Wesley, page 102n module Inject def inject(n) each do |x| n = yield(n, x) end n end def sum(initial = 0) inject(initial) do |n, v| n + v end end def product(initial = 1) inject(initial) do |n, v| n * v end end end unless defined? Inject # used by plotting curves # to_trias: [0, 1, 2, 3, 4, 5] --> [[0, 1, 2], [3, 4, 5]] # to_path: [[-10, 10], [0, 5], [10, 10]].to_path <=> DL.make_path([[-10, 10], [0, 5], [10, 10]]) # uses the same options as DL.make_path() class Array include Inject def to_trias ary = [] unless self.length.divmod(3).last.nonzero? 0.step(self.length - 2, 3) do |i| ary.push([self[i], self[i + 1], self[i + 2]]) end end ary end def to_path(*args) DL.make_path(self, *args) end end class Sndplot def initialize(chns = 1) @chns = chns @snd = open end attr_reader :snd def inspect format("#<%s: snd: %d, chns: %d>", self.class, @snd, @chns) end def open if snds = sounds() snds.each do |s| set_sound_property(:selected, false, s) end set_sound_property(:selected, true, selected_sound) end if @snd = snds.detect do |s| channels(s) >= @chns end set_sound_property(:dlocsig_created, false, @snd) select_sound(@snd) else @snd = new_sound(snd_tempnam, @chns, default_output_srate, default_output_sample_type, default_output_header_type) set_sound_property(:dlocsig_created, true, @snd) end channels(@snd).times do |chn| set_channel_property(:time_graph, time_graph?(@snd, chn), @snd, chn) set_channel_property(:transform_graph, transform_graph?(@snd, chn), @snd, chn) set_channel_property(:lisp_graph, lisp_graph?(@snd, chn), @snd, chn) set_time_graph?(false, @snd, chn) set_transform_graph?(false, @snd, chn) set_lisp_graph?(true, @snd, chn) end $exit_hook.add_hook!("dlocsig-hook") do | | close false end @snd end def close if snds = sounds() snds.each do |snd| set_sound_property(:selected, false, snd) unless sound_property(:dlocsig_created, snd).nil? if sound_property(:dlocsig_created, snd) close_sound_extend(snd) else channels(snd).times do |chn| set_time_graph?(channel_property(:time_graph, snd, chn), snd, chn) set_transform_graph?(channel_property(:transform_graph, snd, chn), snd, chn) set_lisp_graph?(channel_property(:lisp_graph, snd, chn), snd, chn) end end end end end $exit_hook.remove_hook!("dlocsig-hook") self end end class Gnuplot @@plot_stream = nil def initialize if (not @@plot_stream) or @@plot_stream.closed? open end end def inspect format("#<%s: plot_stream: %s>", self.class, @@plot_stream.inspect) end def open if (gnuplot = `which gnuplot`).empty? dl_error("gnuplot not found?") else @@plot_stream = IO.popen(gnuplot, "w") end end def close unless @@plot_stream.closed? @@plot_stream.puts("quit") @@plot_stream.close @@plot_stream = nil end end def command(*args) open if @@plot_stream.closed? @@plot_stream.printf(*args) format(*args).chomp rescue Snd.warning("%s#%s", self.class, get_func_name) end def reset command "reset\n" end def set_autoscale command "set autoscale\n" end def set_x_range(range = []) command("set xrange [%f:%f]\n", range[0], range[1]) if range.length == 2 end def set_y_range(range = []) command("set yrange [%f:%f]\n", range[0], range[1]) if range.length == 2 end def set_z_range(range = []) command("set zrange [%f:%f]\n", range[0], range[1]) if range.length == 2 end def set_grid command "set grid xtics; set grid ytics; set grid ztics\n" end def set_surface command "set surface\n" end def set_parametric command "set parametric\n" end def set_ticslevel(level = 0) command("set ticslevel %.2f\n", level) end def set_title(title = "") command("set title \"%s\"\n", title) unless title.empty? end def set_label(label = "") command("set label \"%s\"\n", label) unless label.empty? end def set_margins(margin = 1) command("set tmargin %f\n", margin) command("set lmargin %f\n", margin) command("set rmargin %f\n", margin) command("set bmargin %f\n", margin) end def set_border(border = nil) command("set border %d\n", border.to_i) if border end def start_multiplot command "set multiplot\n" end def end_multiplot command "set nomultiplot\n" end def size(xorigin, yorigin, xsize, ysize) command("set origin %f,%f\n", xorigin.to_f, yorigin.to_f) command("set size %f,%f\n", xsize.to_f, ysize.to_f) end def data(data, *args) style, label = nil optkey(args, binding, [:style, "linespoints"], [:label, ""]) command("plot '-' %s %s\n", label.empty? ? "" : "title \"#{label}\"", style.empty? ? "" : "with #{style}") data.each_with_index do |y, x| command("%f %f\n", x, y) end command "e\n" end def plot_2d_curve(curve, *args) style, label = nil optkey(args, binding, [:style, "linespoints"], [:label, ""]) set_grid() command("plot '-' %s %s\n", label.empty? ? "" : "title \"#{label}\"", style.empty? ? "" : "with #{style}") curve.each_pair do |x, y| command("%.8f %.8f\n", x, y) end command "e\n" end def plot_2d_curves(curves, *args) styles, labels = nil optkey(args, binding, [:styles, "linespoints"], [:labels, ""]) set_grid() styles = curves.map do |i| styles end unless array?(styles) labels = curves.map do |i| labels end unless array?(labels) command "plot" curves.each_with_index do |x, i| style = styles[i] label = labels[i] command " '-' " command(" title \"%s\"", label) if label or (not label.empty?) command(" with %s", style) if style or (not style.empty?) command(", ") if i != (curves.length - 1) end command "\n" curves.each do |curve| curve.each_pair do |x, y| command("%.8f %.8f\n", x, y) end command "e\n" end end def plot_3d_curve(curve, *args) style, label, zstyle, xrot, zrot, scale, zscale = nil optkey(args, binding, [:style, "linespoints"], [:label, ""], [:zstyle, "impulses"], :xrot, :zrot, :scale, :zscale) set_border(127 + 256 + 512) set_grid() set_surface() set_parametric() set_ticslevel(0) if xrot or zrot or scale or zscale command("set view %s,%s,%s,%s\n", xrot, zrot, scale, zscale) end command "splot '-'" command(" title \"%s\"", label) unless label.empty? command(" with %s 1", style) unless style.empty? command(", '-' notitle with %s 1", zstyle) unless zstyle.empty? command "\n" curve.to_trias.each do |x, y, z| command("%.8f %.8f %.8f\n", x, y, z) end command "e\n" if zstyle curve.to_trias.each do |x, y, z| command("%.8f %.8f %.8f\n", x, y, z) end command "e\n" end end end module DL Path_maxcoeff = 8 Point707 = cos(TWO_PI / 8.0) Amplitude_panning = 1 B_format_ambisonics = 2 Decoded_ambisonics = 3 def which_render(val) case val when :amplitude_panning, Amplitude_panning Amplitude_panning when :b_format_ambisonics, B_format_ambisonics B_format_ambisonics when :decoded_ambisonics, Decoded_ambisonics Decoded_ambisonics else Amplitude_panning end end def cis(r) Complex(cos(r), sin(r)) end def distance(x, y, z) sqrt(x * x + y * y + z * z) end def nearest_point(x0, y0, z0, x1, y1, z1, px, py, pz) if same?(x0, y0, z0, px, py, pz) [x0, y0, z0] elsif same?(x1, y1, z1, px, py, pz) [x1, y1, z1] elsif same?(x0, y0, z0, x1, y1, z1) [x0, y0, z0] else xm0 = x1 - x0 ym0 = y1 - y0 zm0 = z1 - z0 xm1 = px - x0 ym1 = py - y0 zm1 = pz - z0 d0 = distance(xm0, ym0, zm0) d1 = distance(xm1, ym1, zm1) p = d1 * ((xm0 * xm1 + ym0 * ym1 + zm0 * zm1) / (d0 * d1)) ratio = p / d0 [x0 + xm0 * ratio, y0 + ym0 * ratio, z0 + zm0 * ratio] end end def same?(a0, b0, c0, a1, b1, c1) a0 == a1 and b0 == b1 and c0 == c1 end def rotation_matrix(x, y, z, angle) mag = distance(x, y, z) dx = x / mag dy = y / mag dz = z / mag ri = Matrix.I(3) ra = Matrix.rows([[0.0, dz, -dy], [-dz, 0.0, dx], [dy, -dx, 0.0]]) raa = ra * ra sn = sin(-angle) omcs = 1 - cos(-angle) raa = raa.map do |xx| omcs * xx end ra = ra.map do |xx| sn * xx end (ri + ra + raa) end class Dlocsig_base include DL def initialize @one_turn = 360.0 @speed_of_sound = 344.0 end attr_accessor :one_turn, :speed_of_sound def angles_in_degree @one_turn = 360.0 end def angles_in_radians @one_turn = TWO_PI end def angles_in_turns @one_turn = 1.0 end def distances_in_meters @speed_of_sound = 344.0 end def distances_in_feet @speed_of_sound = 1128.0 end end class Speaker_config < Dlocsig_base Groups = Struct.new("Groups", :size, :vertices, :speakers, :matrix) def initialize super @number = nil @coords = nil @groups = nil end protected def set_speakers(channels, d3) if channels.between?(1, 8) d3 = false if channels < 4 arrange_speakers(unless d3 case channels when 1 [[0]] when 2 [[-60, 60]] when 3 [[-45, 45, 180]] when 4 [[-45, 45, 135, 225]] when 5 [[-45, 0, 45, 135, -135]] when 6 [[-60, 0, 60, 120, 180, 240]] when 7 [[-45, 0, 45, 100, 140, -140, -100]] when 8 [[-22.5, 22.5, 67.5, 112.5, 157.5, 202.5, 247.5, 292.5]] end else case channels when 4 [[[-60, 0], [60, 0], [180, 0], [0, 90]], [[0, 1, 3], [1, 2, 3], [2, 0, 3], [0, 1, 2]]] when 5 [[[-45, 0], [45, 0], [135, 0], [-135, 0], [0, 90]], [[0, 1, 4], [1, 2, 4], [2, 3, 4], [3, 0, 4], [0, 1, 2], [2, 3, 0]]] when 6 [[[-45, 0], [45, 0], [135, 0], [-135, 0], [-90, 60], [90, 60]], [[0, 1, 4], [1, 4, 5], [1, 2, 5], [2, 3, 5], [3, 4, 5], [3, 0, 4], [0, 1, 2], [2, 3, 0]]] when 7 [[[-45, 0], [45, 0], [135, 0], [-135, 0], [-60, 60], [60, 60], [180, 60]], [[0, 1, 4], [1, 4, 5], [1, 2, 5], [2, 6, 5], [2, 3, 6], [3, 4, 6], [3, 0, 4], [4, 5, 6], [0, 1, 2], [2, 3, 0]]] when 8 [[[-45, 10], [45, -10], [135, -10], [225, -10], [-45, 45], [45, 45], [135, 45], [225, 45]], [[0, 4, 5], [0, 5, 1], [5, 1, 2], [2, 6, 5], [6, 7, 2], [2, 3, 7], [3, 7, 4], [3, 0, 4], [4, 7, 6], [6, 5, 4], [0, 1, 2], [2, 3, 0]]] end end) else dl_error(channels, "only 1 to 8 channels possible") end end private def arrange_speakers(args) speakers = args.shift groups = args.shift @number = speakers.length @coords = speakers.map do |s| a = (array?(s) ? s[0] : s).to_f e = (array?(s) ? s[1] : 0).to_f evec = cis((e / @one_turn) * TWO_PI) dxy = evec.real avec = cis((a / @one_turn) * TWO_PI) x = (dxy * avec.imag) y = (dxy * avec.real) z = evec.imag mag = distance(x, y, z) [x / mag, y / mag, z / mag] end unless groups if @number == 1 groups = [[0]] else groups = make_array(@number) do |i| [i, i + 1] end groups[-1][-1] = 0 end end @groups = groups.map do |group| size = group.length vertices = group.map do |vertice| @coords[vertice] end matrix = case size when 3 if (m = Matrix[vertices[0], vertices[1], vertices[2]]).regular? m.inverse.to_a else nil end when 2 if (m = Matrix[vertices[0][0, 2], vertices[1][0, 2]]).regular? m.inverse.to_a else nil end else nil end Groups.new(size, vertices, group, matrix) end end end class Dlocsig < Speaker_config def initialize super @render_using = Amplitude_panning @output_power = 1.5 @reverb_power = 0.5 @rbm_output = nil @rbm_reverb = nil @out_channels = 4 @rev_channels = 1 @clm = true @delay = [] @prev_time = @prev_dist = @prev_group = @prev_x = @prev_y = @prev_z = false @first_dist = @last_dist = 0.0 @min_dist = @max_dist = 0.0 @start = nil @end = nil @output_gains = nil @reverb_gains = nil @path = nil @run_beg = @run_end = nil end attr_reader :run_beg, :run_end, :out_channels, :rev_channels def inspect format("#<%s: channels: %d, reverb: %s>", self.class, @out_channels, @rev_channels.inspect) end def each (@run_beg...@run_end).each do |i| yield(i) end end alias run each # general clm version # dl.dlocsig(loc, val) def dlocsig(loc, input) if loc < @start delay(@path, (loc >= @end ? 0.0 : input), 0.0) @out_channels.times do |chn| out_any(loc, 0.0, chn, @rbm_output) end else sample = delay(@path, (loc >= @end ? 0.0 : input), env(@delays)) @out_channels.times do |chn| out_any(loc, sample * env(@output_gains[chn]), chn, @rbm_output) end @rev_channels.times do |chn| out_any(loc, sample * env(@reverb_gains[chn]), chn, @rbm_reverb) end end end # dl.ws_dlocsig do |loc| ...; val; end # @clm == true @rbm_output/@rbm_reverb: sample2files # @clm == false @rbm_output/@rbm_reverb: sound index numbers # With_sound#run_dlocsig below uses this method def ws_dlocsig len = @run_end - @run_beg out_data = make_vct(len) len.times do |i| loc = i + @run_beg input = yield(loc) if loc < @start delay(@path, (loc >= @end ? 0.0 : input), 0.0) else out_data[i] = delay(@path, (loc >= @end ? 0.0 : input), env(@delays)) end end @out_channels.times do |chn| if @clm (@run_beg...@run_end).each do |i| out_any(i, out_data[i - @run_beg] * env(@output_gains[chn]), chn, @rbm_output) end else out = vct_multiply!(vct_copy(out_data), Vct.new(len) do |x| env(@output_gains[chn]) end) mix_vct(out, @run_beg, @rbm_output, chn, false) end end @rev_channels.times do |chn| if @clm (@run_beg...@run_end).each do |i| out_any(i, out_data[i - @run_beg] * env(@reverb_gains[chn]), chn, @rbm_reverb) end else out = vct_multiply!(vct_copy(out_data), Vct.new(len) do |x| env(@reverb_gains[chn]) end) mix_vct(out, @run_beg, @rbm_reverb, chn, false) end end end # :amplitude_panning # :b_format_ambisonics # :decoded_ambisonics def make_dlocsig(startime, dur, *args) path, scaler, reverb_amount, output_power, reverb_power, render_using = nil rbm_output, rbm_reverb, out_channels, rev_channels, clm = nil optkey(args, binding, :path, [:scaler, 1.0], [:reverb_amount, 0.05], [:output_power, 1.5], [:reverb_power, 0.5], [:render_using, Amplitude_panning], [:rbm_output, $output], [:rbm_reverb, $reverb], [:out_channels, 4], [:rev_channels, 1], [:clm, true]) @output_power = output_power @reverb_power = reverb_power @render_using = which_render(render_using) @rbm_output = rbm_output @rbm_reverb = rbm_reverb @out_channels = out_channels @rev_channels = rev_channels @clm = clm if @render_using == B_format_ambisonics and @out_channels != 4 dl_error("B_format_ambisonics requires 4 output channels") end if @render_using == B_format_ambisonics and @rev_channels.nonzero? and (@rev_channels != 1 and @rev_channels != 4) dl_error("B_format_ambisonics accepts only 0, 1 or 4 rev_channels") end if @rev_channels > @out_channels dl_error("more rev_channels than out_channels") end if @render_using == B_format_ambisonics scaler *= 0.8 end unless path.kind_of?(Path) if array?(path) and !path.empty? path = make_path(path) else dl_error(path, "sorry, need a path") end end xpoints = path.path_x ypoints = path.path_y zpoints = path.path_z tpoints = path.path_time @channel_gains = make_array(@out_channels) do [] end @channel_rev_gains = make_array(@rev_channels) do [] end self.set_speakers(@out_channels, (not zpoints.detect do |x| x.nonzero? end.nil?)) @speed_limit = (@speed_of_sound * (tpoints[-1] - tpoints[0])) / dur if xpoints.length == 1 walk_all_rooms(xpoints[0], ypoints[0], zpoints[0], tpoints[0]) else xb = yb = zb = tb = 0.0 (tpoints.length - 1).times do |i| xa, xb = xpoints[i, 2] ya, yb = ypoints[i, 2] za, zb = zpoints[i, 2] ta, tb = tpoints[i, 2] minimum_segment_length(xa, ya, za, ta, xb, yb, zb, tb) end walk_all_rooms(xb, yb, zb, tb) end @start = dist2samples(@first_dist - @min_dist) @end = seconds2samples(startime + dur) min_delay = dist2samples(@min_dist) @run_beg = seconds2samples(startime) @run_end = @end + dist2samples(@last_dist) - min_delay real_dur = dur + dist2seconds(@last_dist - @first_dist) min_dist_unity = [@min_dist, 1.0].max unity_gain = scaler * min_dist_unity ** @output_power @output_gains = make_array(@number) do |i| make_env(:envelope, @channel_gains[i], :scaler, unity_gain, :duration, real_dur) end if @rev_channels.nonzero? unity_rev_gain = reverb_amount * scaler * min_dist_unity ** @reverb_power @reverb_gains = make_array(@rev_channels) do |i| make_env(:envelope, @channel_rev_gains[i], :scaler, unity_rev_gain, :duration, real_dur) end end @delays = make_env(:envelope, @delay, :offset, -min_delay, :duration, real_dur) @path = make_delay(:size, 1, :max_size, [1, dist2samples(@max_dist)].max) self end private def dist2samples(d) (d * (mus_srate() / @speed_of_sound)).round end def dist2seconds(d) d / @speed_of_sound.to_f end def transition_point_3(vert_a, vert_b, xa, ya, za, xb, yb, zb) line_b = vct(xa, ya, za) line_m = tr3_sub(vct(xb, yb, zb), line_b) normal = tr3_cross(vert_a, vert_b) if (denominator = tr3_dot(normal, line_m)).abs <= 0.000001 false else vct2list(tr3_add(line_b, tr3_scale(line_m, -tr3_dot(normal, line_b) / denominator))) end end def tr3_cross(v1, v2) vct(v1[1] * v2[2] - v1[2] * v2[1], v1[2] * v2[0] - v1[0] * v2[2], v1[0] * v2[1] - v1[1] * v2[0]) end def tr3_dot(v1, v2) dot_product(v1, v2) end def tr3_sub(v1, v2) vct_subtract!(vct_copy(v1), v2) end def tr3_add(v1, v2) vct_add!(vct_copy(v1), v2) end def tr3_scale(v1, c) vct_scale!(vct_copy(v1), c) end def transition_point_2(vert, xa, ya, xb, yb) ax = vert[0] bx = xa - xb ay = vert[1] by = ya - yb cx = -xa cy = -ya d = by * cx - bx * cy f = ay * bx - ax * by if f.zero? false else [(d * ax) / f, (d * ay) / f] end end def calculate_gains(x, y, z, group) zero_coord = 1e-10 zero_gain = 1e-10 size = group.size if mat = group.matrix if x.abs < zero_coord and y.abs < zero_coord and z.abs < zero_coord [true, [1.0, 1.0, 1.0]] else case size when 3 gain_a = mat[0][0] * x + mat[0][1] * y + mat[0][2] * z gain_b = mat[1][0] * x + mat[1][1] * y + mat[1][2] * z gain_c = mat[2][0] * x + mat[2][1] * y + mat[2][2] * z mag = distance(gain_a, gain_b, gain_c) if gain_a.abs < zero_gain then gain_a = 0.0 end if gain_b.abs < zero_gain then gain_b = 0.0 end if gain_c.abs < zero_gain then gain_c = 0.0 end [(gain_a >= 0 and gain_b >= 0 and gain_c >= 0), [gain_a / mag, gain_b / mag, gain_c / mag]] when 2 gain_a = mat[0][0] * x + mat[0][1] * y gain_b = mat[1][0] * x + mat[1][1] * y mag = distance(gain_a, gain_b, 0.0) if gain_a.abs < zero_gain then gain_a = 0.0 end if gain_b.abs < zero_gain then gain_b = 0.0 end [(gain_a >= 0 and gain_b >= 0), [gain_a / mag, gain_b / mag]] when 1 [true, [1.0]] end end else [true, [1.0, 1.0, 1.0]] end end def find_group(x, y, z) grp = gns = false @groups.detect do |group| inside, gains = calculate_gains(x, y, z, group) if inside grp, gns = group, gains true end end [grp, gns] end def push_zero_gains(time) @out_channels.times do |i| @channel_gains[i].push(time, 0.0) end @rev_channels.times do |i| @channel_rev_gains[i].push(time, 0.0) end end def push_gains(group, gains, dist, time) outputs = make_vct(@out_channels) revputs = if @rev_channels > 0 make_vct(@rev_channels) else false end if dist >= 1.0 att = 1.0 / dist ** @output_power ratt = 1.0 / dist ** @reverb_power else att = 1.0 - dist ** (1.0 / @output_power) ratt = 1.0 - dist ** (1.0 / @reverb_power) end if dist >= 1.0 group.speakers.each_with_index do |speaker, i| gain = gains[i] outputs[speaker] = gain * att if @rev_channels > 1 revputs[speaker] = gain * ratt end end else @number.times do |speaker| if found = group.speakers.index(speaker) gain = gains[found] outputs[speaker] = gain + (1.0 - gain) * att if @rev_channels > 1 revputs[speaker] = gain + (1.0 - gain) * ratt end else outputs[speaker] = att if @rev_channels > 1 revputs[speaker] = ratt end end end end vct2list(outputs).each_with_index do |val, i| @channel_gains[i].push(time, val) end if @rev_channels == 1 @channel_rev_gains[0].push(time, ratt) elsif @rev_channels > 1 vct2list(revputs).each_with_index do |val, i| @channel_rev_gains[i].push(time, val) end end end def amplitude_panning(x, y, z, dist, time) if @prev_group if time != @prev_time and ((dist - @prev_dist) / (time - @prev_time)) > @speed_limit Snd.display("%s#%s: supersonic radial movement", self.class, get_func_name) end inside, gains = calculate_gains(x, y, z, @prev_group) if inside push_gains(@prev_group, gains, dist, time) @prev_x, @prev_y, @prev_z = x, y, z else group, gains = find_group(x, y, z) if group edge = group.vertices & @prev_group.vertices if edge.length == 2 if pint = transition_point_3(edge[0], edge[1], x, y, z, @prev_x, @prev_y, @prev_z) xi, yi, zi = pint di = distance(xi, yi, zi) ti = @prev_time + (distance(xi - @prev_x, yi - @prev_y, zi - @prev_z) / \ distance(x - @prev_x, y - @prev_y, z - @prev_z)) * (time - @prev_time) if ti < @prev_time inside, gains = calculate_gains(xi, yi, zi, @prev_group) if inside push_gains(@prev_group, gains, di, ti) else inside, gains = calculate_gains(xi, yi, zi, group) if inside push_gains(group, gains, di, ti) else dl_error("outside of both adjacent groups") end end else if $DEBUG Snd.warning("%s#%s: current time <= previous time", self.class, get_func_name) end end end elsif edge.length == 1 and group.size == 2 if pint = transition_point_2(edge[0], x, y, @prev_x, @prev_y) xi, yi = pint di = distance(xi, yi, 0.0) ti = @prev_time + (distance(xi - @prev_x, yi - @prev_y, 0.0) / \ distance(x - @prev_x, y - @prev_y, 0.0)) * (time - @prev_time) if ti < @prev_time inside, gains = calculate_gains(xi, yi, 0.0, @prev_group) if inside push_gains(@prev_group, gains, di, ti) inside, gains = calculate_gains(xi, yi, 0.0, group) if inside push_gains(group, gains, di, ti) else dl_error("outside of both adjacent groups") end end else if $DEBUG Snd.warning("%s#%s: current time <= previous time", self.class, get_func_name) end end end elsif edge.length == 1 Snd.display("%s#%s: only one point in common", self.class, get_func_name) elsif edge.length.zero? Snd.display("%s#%s: with no common points", self.class, get_func_name) end push_gains(group, gains, dist, time) @prev_group, @prev_x, @prev_y, @prev_z = group, x, y, z else push_zero_gains(time) @prev_group = false end end else group, gains = find_group(x, y, z) if group push_gains(group, gains, dist, time) @prev_group, @prev_x, @prev_y, @prev_z = group, x, y, z else push_zero_gains(time) @prev_group = false end end @prev_time = time @prev_dist = dist end def b_format_ambisonics(x, y, z, dist, time) if dist > 1.0 att = (1.0 / dist) ** @output_power @channel_gains[0].push(time, Point707 * att) @channel_gains[1].push(time, (y / dist) * att) @channel_gains[2].push(time, (-x / dist) * att) @channel_gains[3].push(time, (z / dist) * att) if @rev_channels == 1 @channel_rev_gains[0].push(time, 1.0 / (dist ** @reverb_power)) elsif @rev_channels == 4 ratt = (1.0 / dist) ** @reverb_power @channel_rev_gains[0].push(time, Point707 * ratt) @channel_rev_gains[1].push(time, (y / dist) * ratt) @channel_rev_gains[2].push(time, (-x / dist) * ratt) @channel_rev_gains[3].push(time, (z / dist) * ratt) end elsif dist.zero? @channel_gains[0].push(time, 1.0) (1..3).each do |i| @channel_gains[i].push(time, 0.0) end if @rev_channels >= 1 @channel_rev_gains[0].push(time, 1.0) end if @rev_channels == 4 (1..3).each do |i| @channel_rev_gains[i].push(time, 0.0) end end else att = dist ** (1.0 / @output_power) @channel_gains[0].push(time, 1.0 - (1.0 - Point707) * dist ** @output_power) @channel_gains[1].push(time, (y / dist) * att) @channel_gains[2].push(time, (-x / dist) * att) @channel_gains[3].push(time, (z / dist) * att) if @rev_channels == 1 @channel_rev_gains[0].push(time, 1.0 - dist ** (1.0 / @reverb_power)) elsif @rev_channels == 4 ratt = dist ** (1.0 / @reverb_power) @channel_rev_gains[0].push(time, 1.0 - (1.0 - Point707) * dist ** @reverb_power) @channel_rev_gains[1].push(time, (y / dist) * ratt) @channel_rev_gains[2].push(time, (-x / dist) * ratt) @channel_rev_gains[3].push(time, (z / dist) * ratt) end end end def decoded_ambisonics(x, y, z, dist, time) if dist > 1.0 att = (1.0 / dist) ** @output_power attw = Point707 * Point707 * att attx = att * (x / dist) atty = att * (y / dist) attz = att * (z / dist) @coords.each_with_index do |s, i| @channel_gains[i].push(time, Point707 * (attw + attx * s[0] + atty * s[1] + attz * s[2])) end if @rev_channels == 1 @channel_rev_gains[0].push(time, 1.0 / (dist ** @reverb_power)) elsif @rev_channels == 4 ratt = (1.0 / dist) ** @reverb_power rattw = Point707 * Point707 * ratt rattx = ratt * (x / dist) ratty = ratt * (y / dist) rattz = ratt * (z / dist) @rev_channels.times do |i| s = @coords[i] @channel_rev_gains[i].push(time, Point707 * \ (rattw + rattx * s[0] + ratty * s[1] + rattz * s[2])) end end elsif dist.zero? att = Point707 * Point707 @coords.each_index do |i| @channel_gains[i].push(time, att) end if @rev_channels == 1 @channel_rev_gains[0].push(time, 1.0) else @rev_channels.times do |i| @channel_rev_gains[i].push(time, att) end end else att = dist ** (1.0 / @output_power) attw = Point707 * (1.0 - (1.0 - Point707) * dist ** @output_power) attx = att * (x / dist) atty = att * (y / dist) attz = att * (z / dist) @coords.each_with_index do |s, i| @channel_gains[i].push(time, Point707 * (attw + attx * s[0] + atty * s[1] + attz * s[2])) end if @rev_channels == 1 @channel_rev_gains[0].push(time, 1.0 - dist ** (1.0 / @reverb_power)) elsif @rev_channels == 4 ratt = dist ** (1.0 / @reverb_power) rattw = Point707 * (1.0 - (1.0 - Point707) * dist ** @reverb_power) rattx = ratt * (x / dist) ratty = ratt * (y / dist) rattz = ratt * (z / dist) @rev_channels.times do |i| s = @coords[i] @channel_rev_gains[i].push(time, Point707 * \ (rattw + rattx * s[0] + ratty * s[1] + rattz * s[2])) end end end end def walk_all_rooms(x, y, z, time) dist = distance(x, y, z) if @first_dist.zero? @first_dist = dist end @last_dist = dist if @min_dist.zero? or dist < @min_dist @min_dist = dist end if @max_dist.zero? or dist > @max_dist @max_dist = dist end @delay.push(time, dist2samples(dist)) case @render_using when Amplitude_panning amplitude_panning(x, y, z, dist, time) when B_format_ambisonics b_format_ambisonics(x, y, z, dist, time) when Decoded_ambisonics decoded_ambisonics(x, y, z, dist, time) end end def change_direction(xa, ya, za, ta, xb, yb, zb, tb) walk_all_rooms(xa, ya, za, ta) if xa != xb or ya != yb or za != zb or ta != tb xi, yi, zi = nearest_point(xa, ya, za, xb, yb, zb, 0.0, 0.0, 0.0) if (((xa < xb) ? (xa <= xi and xi <= xb) : (xb <= xi and xi <= xa)) and ((ya < yb) ? (ya <= yi and yi <= yb) : (yb <= yi and yi <= ya)) and ((za < zb) ? (za <= zi and zi <= zb) : (zb <= zi and zi <= za))) walk_all_rooms(xi, yi, zi, tb + (ta - tb) * (distance(xb - xi, yb - yi, zb - zi) / \ distance(xb - xa, yb - ya, zb - za))) end end end def intersects_inside_radius(xa, ya, za, ta, xb, yb, zb, tb) mag = distance(xb - xa, yb - ya, zb - za) vx = (xb - xa) / mag vy = (yb - ya) / mag vz = (zb - za) / mag bsq = xa * vx + ya * vy + za * vz disc = bsq * bsq - ((xa * xa + ya * ya + za * za) - 1.0) if disc >= 0.0 root = sqrt(disc) rin = -bsq - root rout = -bsq + root xi = xo = nil if rin > 0 and rin < mag xi = xa + vx * rin yi = ya + vy * rin zi = za + vz * rin ti = tb + (ta - tb) * (distance(xb - xi, yb - yi, zb - zi) / distance(xb - xa, yb - ya, zb - za)) end if rout > 0 and rout.abs < mag xo = xa + vx * rout yo = ya + vy * rout zo = za + vz * rout to = tb + (ta - tb) * (distance(xb - xo, yb - yo, zb - zo) / distance(xb - xa, yb - ya, zb - za)) end if xi change_direction(xa, ya, za, ta, xi, yi, zi, ti) if xo change_direction(xi, yi, zi, ti, xo, yo, zo, to) change_direction(xo, yo, zo, to, xb, yb, zb, tb) else change_direction(xi, yi, zi, ti, xb, yb, zb, tb) end else if xo change_direction(xa, ya, za, ta, xo, yo, zo, to) change_direction(xo, yo, zo, to, xb, yb, zb, tb) else change_direction(xa, ya, za, ta, xb, yb, zb, tb) end end else change_direction(xa, ya, za, ta, xb, yb, zb, tb) end end def minimum_segment_length(xa, ya, za, ta, xb, yb, zb, tb) if distance(xb - xa, yb - ya, zb - za) < 1.0 intersects_inside_radius(xa, ya, za, ta, xb, yb, zb, tb) else xi = (xa + xb) * 0.5 yi = (ya + yb) * 0.5 zi = (za + zb) * 0.5 ti = tb + (ta - tb) * (distance(xb - xi, yb - yi, zb - zi) / distance(xb - xa, yb - ya, zb - za)) minimum_segment_length(xa, ya, za, ta, xi, yi, zi, ti) minimum_segment_length(xi, yi, zi, ti, xb, yb, zb, tb) end end end class Path < Dlocsig_base def initialize super @rx = @ry = @rz = @rv = @rt = @tx = @ty = @tz = @tt = nil @gnuplot = @sndplot = nil end def path_x (@tx or (@rx or (render_path(); @rx))) end def path_y (@ty or (@ry or (render_path(); @ry))) end def path_z (@tz or (@rz or (render_path(); @rz))) end def path_time (@tt or (@rt or (render_path(); @rt))) end def scale_path(scaling) assert_type((number?(scaling) or array?(scaling)), 0, scaling, "a number or an array") if number?(scaling) then scaling = [scaling, scaling, scaling] end transform_path(:scaling, scaling) end def translate_path(translation) assert_type((number?(translation) or array?(translation)), 0, translation, "a number or an array") if number?(translation) then translation = [translation, translation, translation] end transform_path(:translation, translation) end def rotate_path(rotation, *args) assert_type(number?(rotation), 0, rotation, "a number") rotation_center, rotation_axis = nil optkey(args, binding, :rotation_center, [:rotation_axis, [0.0, 0.0, 1.0]]) transform_path(:rotation, rotation, :rotation_center, rotation_center, :rotation_axis, rotation_axis) end def path_trajectory path_x.map_with_index do |d, i| [d, path_y[i], path_z[i]] end.flatten end def path_2d_trajectory path_x.map_with_index do |d, i| [d, path_y[i]] end.flatten end # if velocity is zero, ti == tf Secure_distance = 0.0001 def path_velocity xp, yp, zp, tp = path_x, path_y, path_z, path_time (0...(tp.length - 1)).map do |i| xi, xf = xp[i, 2] yi, yf = yp[i, 2] zi, zf = zp[i, 2] ti, tf = tp[i, 2] if tf == ti tf += Secure_distance end [(ti + tf) / 2.0, distance(xf - xi, yf - yi, zf - zi) / (tf - ti)] end.flatten end def path_doppler xp, yp, zp, tp = path_x, path_y, path_z, path_time (0...(tp.length - 1)).map do |i| xi, xf = xp[i, 2] yi, yf = yp[i, 2] zi, zf = zp[i, 2] ti, tf = tp[i, 2] if tf == ti tf += Secure_distance end [(tf + ti) / 2.0, -((distance(xf, yf, zf) - distance(xi, yi, zi)) / (tf - ti))] end.flatten end def path_acceleration v = path_velocity() result = [] 0.step(v.length - 3, 2) do |i| ti, vi, tf, vf = v[i, 4] if tf == ti tf += Secure_distance end am = (vf - vi) / (tf - ti) result << ti << am << tf << am end result end # Gnuplot def plot_open if @gnuplot.kind_of?(Gnuplot) @gnuplot else @gnuplot = Gnuplot.new end end def plot_close @gnuplot.close if @gnuplot.kind_of?(Gnuplot) end def cmd(*args) @gnuplot = plot_open @gnuplot.command(format(*args) << "\n") end def plot_trajectory(*args) @gnuplot = plot_open label, reset = nil optkey(args, binding, [:label, "trajectory"], [:reset, true]) @gnuplot.reset() if reset @gnuplot.set_autoscale() if path_z.detect do |z| z.nonzero? end @gnuplot.plot_3d_curve(path_trajectory(), :label, label, *args) else @gnuplot.plot_2d_curve(path_2d_trajectory(), :label, label, *args) end end def plot_velocity(reset = true) @gnuplot = plot_open @gnuplot.reset() if reset @gnuplot.set_autoscale() @gnuplot.plot_2d_curve(path_velocity(), :label, "velocity", :style, "steps") end def plot_doppler(reset = true) @gnuplot = plot_open @gnuplot.reset() if reset @gnuplot.set_autoscale() @gnuplot.plot_2d_curve(path_doppler(), :label, "doppler", :style, "steps") end def plot_acceleration(reset = true) @gnuplot = plot_open @gnuplot.reset() if reset @gnuplot.set_autoscale() @gnuplot.plot_2d_curve(path_acceleration(), :label, "acceleration", :style, "steps") end def pplot(normalize = true) @gnuplot = plot_open norm = lambda do |env, nrm| unless nrm env else mx = env.each_pair do |x, y| y end.max if mx.zero? env else env.each_pair do |x, y| [x, y / mx.to_f] end.flatten end end end @gnuplot.reset() @gnuplot.size(0, 0, 1, 1) @gnuplot.start_multiplot() @gnuplot.size(0.0, 0.333, 1.0, 0.667) plot_trajectory(:reset, false) @gnuplot.size(0.0, 0.0, 1.0, 0.333) @gnuplot.plot_2d_curves([norm.call(path_velocity(), normalize), norm.call(path_acceleration(), normalize), norm.call(path_doppler(), normalize)], :labels, ["velocity", "acceleration", "doppler"], :styles, ["steps", "steps", "steps"]) @gnuplot.end_multiplot() end # Sndplot def snd_open(chns = 1) if @sndplot.kind_of?(Sndplot) @sndplot else @sndplot = Sndplot.new(chns) end end def snd_close @sndplot.close if @sndplot.kind_of?(Sndplot) end def snd_trajectory(chn = 0, label = "trajectory") @sndplot = snd_open graph(path_2d_trajectory(), label, false, false, false, false, @sndplot.snd, chn) @sndplot end def snd_velocity(chn = 0, label = "velocity") @sndplot = snd_open graph(path_velocity(), label, false, false, false, false, @sndplot.snd, chn) @sndplot end def snd_doppler(chn = 0, label = "doppler") @sndplot = snd_open graph(path_doppler(), label, false, false, false, false, @sndplot.snd, chn) @sndplot end def snd_acceleration(chn = 0, label = "acceleration") @sndplot = snd_open graph(path_acceleration(), label, false, false, false, false, @sndplot.snd, chn) @sndplot end def snd_plot @sndplot = snd_open(4) snd_trajectory(0) snd_velocity(1) snd_acceleration(2) snd_doppler(3) @sndplot end private def transform_path(*args) scaling, translation, rotation, rotation_center, rotation_axis = nil optkey(args, binding, :scaling, :translation, :rotation, :rotation_center, [:rotation_axis, [0.0, 0.0, 1.0]]) render_path() if @rx.nil? if scaling or translation or rotation rotation = TWO_PI * (rotation / @one_turn) if rotation if rotation_axis and (rotation_axis.length != 3) dl_error(rotation_axis, "rotation axis has to have all three coordinates") end matrix = if rotation rotation_matrix(rotation_axis[0], rotation_axis[1], rotation_axis[2], rotation) end xc = path_x() yc = path_y() zc = path_z() if rotation_center and (rotation_center.length != 3) dl_error(rotation_center, "rotation center has to have all three coordinates") end xtr = [] ytr = [] ztr = [] xc.each_with_index do |x, i| y = yc[i] z = zc[i] xw, yw, zw = x, y, z if rotation_center and rotation xw -= rotation_center[0] yw -= rotation_center[1] zw -= rotation_center[2] end if rotation mc = [xw, yw, zw] xv, yv, zv = matrix.column_vectors xr = xv.to_a.map_with_index do |xx, ii| xx * mc[ii] end.to_a.sum yr = yv.to_a.map_with_index do |xx, ii| xx * mc[ii] end.to_a.sum zr = zv.to_a.map_with_index do |xx, ii| xx * mc[ii] end.to_a.sum xw, yw, zw = xr, yr, zr end if rotation_center and rotation xw += rotation_center[0] yw += rotation_center[1] zw += rotation_center[2] end if scaling xw *= scaling[0] yw *= scaling[1] if scaling[1] zw *= scaling[2] if scaling[2] end if translation xw += translation[0] yw += translation[1] if translation[1] zw += translation[2] if translation[2] end xtr << xw ytr << yw ztr << zw end @tx, @ty, @tz = xtr, ytr, ztr else @tt = @rt.dup @tx = @rx.dup @ty = @ry.dup @tz = @rz.dup end end def reset_transformation @tt = @tx = @ty = @tz = nil end def reset_rendering @rt = @rv = @rx = @ry = @rz = nil reset_transformation() end def parse_cartesian_coordinates(points, d3) if array?(points[0]) x = points.map do |p| p[0] end y = points.map do |p| p[1] end z = points.map do |p| d3 ? (p[2] or 0.0) : 0.0 end v = points.map do |p| d3 ? p[3] : p[2] end [x, y, z, v] else if d3 x = [] y = [] z = [] 0.step(points.length - 3, 3) do |i| x += [points[i]] y += [points[i + 1]] z += [points[i + 2]] end [x, y, z, x.map do |i| nil end] else x = [] y = [] 0.step(points.length - 2, 2) do |i| x += [points[i]] y += [points[i + 1]] end [x, y, x.map do |i| 0.0 end, x.map do |i| nil end] end end end def parse_polar_coordinates(points, d3) if array?(points[0]) x = [] y = [] z = [] v = [] points.each do |p| d = p[0] a = p[1] e = (d3 ? (p[2] or 0.0) : 0.0) evec = cis((e / @one_turn) * TWO_PI) dxy = d * evec.real avec = cis((a / @one_turn) * TWO_PI) z << (d * evec.imag) x << (dxy * avec.imag) y << (dxy * avec.real) v << (d3 ? p[3] : p[2]) end [x, y, z, v] else if d3 x = [] y = [] z = [] 0.step(points.length - 1, 3) do |i| d, a, e = points[i, 3] evec = cis((e / @one_turn) * TWO_PI) dxy = (d * evec.real) avec = cis((a / @one_turn) * TWO_PI) z << (d * evec.imag) x << (dxy * avec.imag) y << (dxy * avec.real) end [x, y, z, x.map do |i| nil end] else x = [] y = [] 0.step(points.length - 1, 2) do |i| d, a = points[i, 2] avec = cis((a / @one_turn) * TWO_PI) x << (d * avec.imag) y << (d * avec.real) end [x, y, x.map do |i| 0.0 end, x.map do |i| nil end] end end end end class Bezier_path < Path def initialize(path, *args) @path = path if (not @path) or (array?(@path) and @path.empty?) dl_error("can't define a path with no points in it") end super() d3, polar, error, curvature = nil optkey(args, binding, [:d3, true], [:polar, false], [:error, 0.01], :curvature) @d3 = d3 @polar = polar @error = error @curvature = curvature @x = @y = @z = @v = @bx = @by = @bz = nil # for ac() and a() @path_ak_even = nil @path_ak_odd = nil @path_gtab = nil @path_ftab = nil end private def parse_path if @polar @x, @y, @z, @v = parse_polar_coordinates(@path, @d3) else @x, @y, @z, @v = parse_cartesian_coordinates(@path, @d3) end if @v[0] and @v.min < 0.1 if @v.min < 0.0 Snd.warning("%s#%s: velocities must be all positive, corrected", self.class, get_func_name) end @v.map! do |x| [0.1, x].max end end @bx = @by = @bz = nil reset_rendering() end def fit_path parse_path() if @x.nil? end def bezier_point(u, c) u1 = 1.0 - u cr = make_array(3) do |i| make_array(3) do |j| u1 * c[i][j] + u * c[i][j + 1] end end 1.downto(0) do |i| 0.upto(i) do |j| 3.times do |k| cr[k][j] = u1 * cr[k][j] + u * cr[k][j + 1] end end end [cr[0][0], cr[1][0], cr[2][0]] end def berny(xl, yl, zl, xh, yh, zh, ul, u, uh, c) x, y, z = bezier_point(u, c) xn, yn, zn = nearest_point(xl, yl, zl, xh, yh, zh, x, y, z) if distance(xn - x, yn - y, zn - z) > @error xi, yi, zi = berny(xl, yl, zl, x, y, z, ul, (ul + u) / 2.0, u, c) xj, yj, zj = berny(x, y, z, xh, yh, zh, u, (u + uh) / 2.0, uh, c) [xi + [x] + xj, yi + [y] + yj, zi + [z] + zj] else [[], [], []] end end def render_path fit_path() if @bx.nil? rx = [] ry = [] rz = [] rv = [] if (not @v[0]) or @v[0].zero? @v[0] = 1.0 @v[-1] = 1.0 end if @x.length == 1 @rx = @x @ry = @y @rz = @z @rt = [0.0] return end xf_bz = yf_bz = zf_bz = vf_bz = 0.0 (@v.length - 1).times do |i| x_bz = @bx[i] y_bz = @by[i] z_bz = @bz[i] vi_bz, vf_bz = @v[i, 2] xi_bz = x_bz[0] xf_bz = x_bz[-1] yi_bz = y_bz[0] yf_bz = y_bz[-1] zi_bz = z_bz[0] zf_bz = z_bz[-1] xs, ys, zs = berny(xi_bz, yi_bz, zi_bz, xf_bz, yf_bz, zf_bz, 0, 0.5, 1, [x_bz, y_bz, z_bz]) rx += [xi_bz] + xs ry += [yi_bz] + ys rz += [zi_bz] + zs rv += [vi_bz] + xs.map do nil end end rx << xf_bz ry << yf_bz rz << zf_bz rv << vf_bz xseg = [rx[0]] yseg = [ry[0]] zseg = [rz[0]] vi = rv[0] ti = 0.0 times = [ti] (1...rx.length).each do |i| x = rx[i] y = ry[i] z = rz[i] v = rv[i] xseg << x yseg << y zseg << z if v sofar = 0.0 dseg = (0...xseg.length - 1).map do |j| xsi, xsf = xseg[j, 2] ysi, ysf = yseg[j, 2] zsi, zsf = zseg[j, 2] sofar += distance(xsf - xsi, ysf - ysi, zsf - zsi) end df = dseg[-1] vf = v aa = ((vf - vi) * (vf + vi)) / (df * 4.0) tseg = dseg.map do |d| ti + (if vi and vi.nonzero? and vf == vi d / vi elsif aa.nonzero? ((vi * vi + 4.0 * aa * d) ** 0.5 - vi) / (2.0 * aa) else 0.0 end) end times += tseg xseg = [x] yseg = [y] zseg = [z] vi = v ti = tseg[-1] end end @rx = rx @ry = ry @rz = rz tf = times[-1] @rt = times.map do |tii| tii / tf end reset_transformation() end # called in Closed_bezier_path#calculate_fit def a(k, n) if ([Path_maxcoeff * 2.0 + 1, n].min).odd? make_a_odd() unless @path_ak_odd @path_ak_odd[(n - 3) / 2][k - 1] else make_a_even() unless @path_ak_even @path_ak_even[(n - 4) / 2][k - 1] end end # called in Open_bezier_path#calculate_fit def ac(k, n) n = [n, Path_maxcoeff].min make_a_even() unless @path_ak_even @path_ak_even[n - 2][k - 1] end def make_a_even g = lambda do |m| @path_gtab = make_array(Path_maxcoeff) unless @path_gtab @path_gtab[0] = 1.0 @path_gtab[1] = -4.0 (2...Path_maxcoeff).each do |i| @path_gtab[i] = -4.0 * @path_gtab[i - 1] - @path_gtab[i - 2] end @path_gtab[m] end @path_ak_even = make_array(Path_maxcoeff - 1) (1...Path_maxcoeff).each do |m| @path_ak_even[m - 1] = make_array(m) (1..m).each do |k| @path_ak_even[m - 1][k - 1] = (-g.call(m - k) / g.call(m)).to_f end end end def make_a_odd f = lambda do |m| @path_ftab = make_array(Path_maxcoeff) unless @path_ftab @path_ftab[0] = 1.0 @path_ftab[1] = -3.0 (2...Path_maxcoeff).each do |i| @path_ftab[i] = -4.0 * @path_ftab[i - 1] - @path_ftab[i - 2] end @path_ftab[m] end @path_ak_odd = make_array(Path_maxcoeff - 1) (1...Path_maxcoeff).each do |m| @path_ak_odd[m - 1] = make_array(m) (1..m).each do |k| @path_ak_odd[m - 1][k - 1] = (-f.call(m - k) / f.call(m)).to_f end end end end class Open_bezier_path < Bezier_path def initialize(path, *args) super initial_direction, final_direction = nil optkey(args, binding, [:initial_direction, [0.0, 0.0, 0.0]], [:final_direction, [0.0, 0.0, 0.0]]) @initial_direction = initial_direction @final_direction = final_direction end private def calculate_fit n = @x.length - 1 m = n - 1 p = [@x, @y, @z] d = make_array(3) do make_array(n + 1, 0.0) end d = Matrix[d[0], d[1], d[2]].to_a ref = lambda do |z, j, i| if i > n z[j][i - n] elsif i < 0 z[j][i + n] elsif i == n z[j][n] - d[j][n] elsif i == 0 z[j][0] + d[j][0] else z[j][i] end end d[0][0] = (@initial_direction[0] or 0.0) d[1][0] = (@initial_direction[1] or 0.0) d[2][0] = (@initial_direction[2] or 0.0) d[0][n] = (@final_direction[0] or 0.0) d[1][n] = (@final_direction[1] or 0.0) d[2][n] = (@final_direction[2] or 0.0) (1...n).each do |i| (1..[Path_maxcoeff - 1, m].min).each do |j| 3.times do |k| d[k][i] = d[k][i] + ac(j, n) * (ref.call(p, k, i + j) - ref.call(p, k, i - j)) end end end [n, p, d] end def fit_path parse_path() if @x.nil? case points = @x.length when 1 @bx = @by = @bz = nil when 2 x1, x2 = @x[0, 2] y1, y2 = @y[0, 2] z1, z2 = @z[0, 2] @bx = [[x1, x1, x2, x2]] @by = [[y1, y1, y2, y2]] @bz = [[z1, z1, z2, z2]] else n, p, d = calculate_fit() c = @curvature cs = make_array(n) if c.kind_of?(NilClass) or (array?(c) and c.empty?) n.times do |i| cs[i] = [1.0, 1.0] end elsif number?(c) n.times do |i| cs[i] = [c, c] end elsif array?(c) and c.length == n c.each_with_index do |ci, i| cs[i] = if array?(ci) if ci.length != 2 dl_error(ci, "curvature sublist must have two elements") else ci end else [ci, ci] end end else dl_error(c, "bad curvature argument to path, need #{n} elements") end @bx = (0...n).map do |i| [p[0][i], p[0][i] + d[0][i] * cs[i][0], p[0][i + 1] - d[0][i + 1] * cs[i][1], p[0][i + 1]] end @by = (0...n).map do |i| [p[1][i], p[1][i] + d[1][i] * cs[i][0], p[1][i + 1] - d[1][i + 1] * cs[i][1], p[1][i + 1]] end @bz = (0...n).map do |i| [p[2][i], p[2][i] + d[2][i] * cs[i][0], p[2][i + 1] - d[2][i + 1] * cs[i][1], p[2][i + 1]] end end reset_rendering() end end class Closed_bezier_path < Bezier_path def initialize(path, *args) super end private def calculate_fit n = @x.length - 1 m = (n - (n.odd? ? 3 : 4)) / 2 p = [@x, @y, @z] d = make_array(3) do make_array(n, 0.0) end ref = lambda do |z, j, i| if i > (n - 1) z[j][i - n] elsif i < 0 z[j][i + n] else z[j][i] end end n.times do |i| (1..m).each do |j| 3.times do |k| d[k][i] = d[k][i] + a(j, n) * (ref.call(p, k, i + j) - ref.call(p, k, i - j)) end end end if @curvature n.times do |i| curve = @curvature[i] d[0][i] *= curve d[1][i] *= curve d[2][i] *= curve end end [n - 1, p, d] end def fit_path parse_path() if @x.nil? if @x.length > 4 n, p, d = calculate_fit() xc = (0...n).map do |i| [p[0][i], p[0][i] + d[0][i], p[0][i + 1] - d[0][i + 1], p[0][i + 1]] end yc = (0...n).map do |i| [p[1][i], p[1][i] + d[1][i], p[1][i + 1] - d[1][i + 1], p[1][i + 1]] end zc = (0...n).map do |i| [p[2][i], p[2][i] + d[2][i], p[2][i + 1] - d[2][i + 1], p[2][i + 1]] end @bx = xc + [[p[0][n], p[0][n] + d[0][n], p[0][0] - d[0][0], p[0][0]]] @by = yc + [[p[1][n], p[1][n] + d[1][n], p[1][0] - d[1][0], p[1][0]]] @bz = zc + [[p[2][n], p[2][n] + d[2][n], p[2][0] - d[2][0], p[2][0]]] else xc = [] yc = [] zc = [] (@x.length - 1).times do |i| x1, x2 = @x[i, 2] y1, y2 = @y[i, 2] z1, z2 = @z[i, 2] xc << [x1, x1, x2, x2] yc << [y1, y1, y2, y2] zc << [z1, z1, z2, z2] end @bx = xc @by = yc @bz = zc end reset_rendering() end end class Literal_path < Path def initialize(path, *args) @path = path if (not @path) or (array?(@path) and @path.empty?) dl_error("can't define a path with no points in it") end super() d3, polar = nil optkey(args, binding, [:d3, true], [:polar, false]) @d3 = d3 @polar = polar end private def render_path if @polar @rx, @ry, @rz, @rv = parse_polar_coordinates(@path, @d3) else @rx, @ry, @rz, @rv = parse_cartesian_coordinates(@path, @d3) end if (not @rv[0]) or @rv[0].zero? @rv[0] = 1.0 @rv[-1] = 1.0 end if @rx.length == 1 @rt = [0.0] return end rx = @rx ry = @ry rz = @rz rv = @rv xseg = [rx[0]] yseg = [ry[0]] zseg = [rz[0]] vi = rv[0] ti = 0.0 times = [ti] (1...rx.length).each do |i| x = rx[i] y = ry[i] z = rz[i] v = rv[i] xseg << x yseg << y zseg << z if v sofar = 0.0 dseg = (0...xseg.length - 1).map do |j| xsi, xsf = xseg[j, 2] ysi, ysf = yseg[j, 2] zsi, zsf = zseg[j, 2] sofar += distance(xsf - xsi, ysf - ysi, zsf - zsi) end df = dseg[-1] vf = v aa = ((vf - vi) * (vf + vi)) / (df * 4.0) tseg = dseg.map do |d| ti + (if vi and vi.nonzero? and vf == vi d / vi elsif aa.nonzero? ((vi * vi + 4.0 * aa * d) ** 0.5 - vi) / (2.0 * aa) else 0.0 end) end times += tseg xseg = [x] yseg = [y] zseg = [z] vi = v ti = tseg[-1] end end tf = times[-1] @rt = times.map do |tii| tii / tf end reset_transformation() end end class Spiral_path < Literal_path def initialize(*args) # to fool Literal_path.new super([nil]) start_angle, turns = nil optkey(args, binding, [:start_angle, 0], [:turns, 2]) @start_angle = start_angle @turns = turns end private def render_path start = (@start_angle / @one_turn.to_f) * TWO_PI total = (@turns.zero? ? TWO_PI : (@turns * TWO_PI)) step_angle = @one_turn / 100.0 steps = (total / ((step_angle / @one_turn.to_f) * TWO_PI)).abs step = total / (steps.ceil * (step_angle < 0 ? -1 : 1)) x = [] y = [] z = [] (total / step).round.abs.times do xy = cis(start) x << (10.0 * xy.imag) y << (10.0 * xy.real) z << 0.0 start += step end sofar = 0.0 dp = (0...x.length - 1).map do |i| xi, xf = x[i, 2] yi, yf = y[i, 2] zi, zf = z[i, 2] sofar += distance(xf - xi, yf - yi, zf - zi) end td = 0.0 times = (0...dp.length - 1).map do |i| di, df = dp[i, 2] td = td + (df - di) / 4.0 end @rx = x @ry = y @rz = z tf = times[-1] @rt = times.map do |ti| ti / tf end reset_transformation() end end module_function def make_dlocsig(start, dur, *args) dl = Dlocsig.new dl.make_dlocsig(start, dur, *args) dl end def dlocsig(dl, dloc, input) dl.dlocsig(dloc, input) end def make_path(path, *args) Open_bezier_path.new(path, *args) end def make_polar_path(path, *args) Open_bezier_path.new(path, :polar, true, *args) end def make_closed_path(path, *args) d3 = nil optkey(args, binding, [:d3, true]) len = d3 ? 3 : 2 unless path[0][0, len] == path[-1][0, len] path += [path[0]] end Closed_bezier_path.new(path, *args) end def make_literal_path(path, *args) Literal_path.new(path, *args) end def make_literal_polar_path(path, *args) Literal_path.new(path, :polar, true, *args) end def make_spiral_path(*args) Spiral_path.new(*args) end end # example functions (see clm-2/dlocsig/move-sound.ins and # clm-2/dlocsig/dlocsig.html) class Instrument def sinewave(start, dur, freq, amp, path, amp_env = [0, 1, 1, 1], *dlocsig_args) os = make_oscil(:frequency, freq) en = make_env(:envelope, amp_env, :scaler, amp, :duration, dur) run_dlocsig(start, dur, :path, path, *dlocsig_args) do env(en) * oscil(os) end end def move(start, file, path, *dlocsig_args) dl_error(path, "need a path") unless path.kind_of?(DL::Path) dur = ws_duration(file) chns = ws_channels(file) rds = make_array(chns) do |chn| make_ws_reader(file, :start, start, :channel, chn) end run_dlocsig(start, dur, :path, path, *dlocsig_args) do rds.map do |rd| ws_readin(rd) end.sum / chns end end add_help(:move_sound, "move_sound(path, *args) do ... end sound_let-args: :channels, 1 # channels to move start time in output file: :startime, 0 rest args: make_dlocsig") def move_sound(path, *args, &body) chns = get_shift_args(args, :channels, 1) start = get_shift_args(args, :startime, 0) sound_let([:channels, chns, body]) do |to_move| if @verbose Snd.display("%s: moving sound on %d channel%s", get_func_name, chns, (chns > 1 ? "s" : "")) end move(0, to_move, path, *args) rbm_mix(to_move, :output_frame, seconds2samples(start)) end end end class With_sound def run_dlocsig(start, dur, *dlocsig_args, &body) with_sound_info(get_func_name(2), start, dur) dl = DL.make_dlocsig(start, dur, :clm, @clm, :rbm_output, @ws_output, :rbm_reverb, @ws_reverb, :out_channels, @channels, :rev_channels, @reverb_channels, *dlocsig_args) dl.ws_dlocsig(&body) end end # Dlocsig menu # # require 'snd-xm' # # make_snd_menu("Dlocsig") do # cascade("Dlocsig (Snd)") do # entry(Dlocsig_bezier, "Bezier path (Snd)", true) # entry(Dlocsig_spiral, "Spiral path (Snd)", true) # end # cascade("Dlocsig (CLM)") do # entry(Dlocsig_bezier, "Bezier path (CLM)", false) # entry(Dlocsig_spiral, "Spiral path (CLM)", false) # end # end if provided? :snd_motif or provided? :snd_gtk class Dlocsig_menu require "snd-xm" include Snd_XM require "xm-enved" include DL def initialize(label, snd_p) @label = label @snd_p = snd_p @dialog = nil @out_chans = 4 @rev_chans = 1 @path = nil @sliders = [] @init_out_chans = 4 @output_power = @init_power = 1.5 @reverb_power = @init_rev_power = 0.5 @render_using = Amplitude_panning end private def with_sound_target(*comment_args) if @render_using == B_format_ambisonics set_scale_value(@sliders[0].scale, @out_chans = 4) end comment_string = if string?($clm_comment) and !$clm_comment.empty? format("%s; %s", $clm_comment, format(*comment_args)) else format(*comment_args) end snd_path, snd_name = File.split(file_name(selected_sound)) snd_name = snd_name.split("moved-").last snd_to_move = format("%s/%s", snd_path, snd_name) snd_moved = format("%s/moved-%s", snd_path, snd_name) path = @path output_power = @output_power reverb_power = @reverb_power render_using = @render_using f = with_sound(:clm, (not @snd_p), :output, snd_moved, :channels, @out_chans, :reverb_channels, @rev_chans, :comment, comment_string, :info, (not $clm_notehook), :statistics, true, :play, true) do move(0, snd_to_move, path, :output_power, output_power, :reverb_power, reverb_power, :render_using, render_using) end Snd.display(f.output.inspect) rescue Snd.warning("%s#%s: %s", self.class, get_func_name, comment_string) end def add_with_sound_sliders(parent = @dialog.parent) @sliders << @dialog.add_slider("output channels", 2, @init_out_chans, 8, 1, :linear, parent) do |w, c, i| @out_chans = get_scale_value(w, i).round end @sliders << @dialog.add_slider("output power", 0, @init_power, 10, 100, :linear, parent) do |w, c, i| @output_power = get_scale_value(w, i, 100.0) end @sliders << @dialog.add_slider("reverb power", 0, @init_rev_power, 10, 100, :linear, parent) do |w, c, i| @reverb_power = get_scale_value(w, i, 100.0) end end def reset_with_sound_sliders(reverb_p = true) set_scale_value(@sliders[0].scale, @out_chans = @init_out_chans) @output_power = @init_power set_scale_value(@sliders[1].scale, @output_power, 100.0) @reverb_power = @init_rev_power set_scale_value(@sliders[2].scale, @reverb_power, 100.0) end def add_with_sound_targets @dialog.add_target([["amplitude panning", :amplitude, true], ["b format ambisonics", :b_format, false], ["decoded ambisonics", :decoded, false]]) do |val| @render_using = case val when :amplitude Amplitude_panning when :b_format set_scale_value(@sliders[0].scale, @out_chans = 4) B_format_ambisonics when :decoded Decoded_ambisonics end end @dialog.add_target([["no reverb", :no_reverb, false], ["1 rev chan", :one_rev_chan, true], ["4 rev chans", :four_rev_chans, false]]) do |val| case val when :no_reverb @rev_chans = 0 when :one_rev_chan @rev_chans = 1 when :four_rev_chans @rev_chans = 4 end end end def set_xm_enveds_hooks(*enveds) enveds.each do |e| e.before_enved_hook.reset_hook! # to prevent running $enved_hook e.before_enved_hook.add_hook!("dlocsig-hook") do |pos, x, y, reason| if reason == Enved_move_point if e.in_range?(x) old_x = e.point(pos).first e.stretch!(old_x, x) e.point(pos, :y, y) else false end else false end end e.after_enved_hook.add_hook!("dlocsig-hook") do |pos, reason| show_values end end end # comment string def dlocsig_strings dlstr = ["", :amplitude_panning, :b_format_ambisonics, :decoded_ambisonics] format("%s, output_power: %1.2f, reverb_power: %1.2f", dlstr[@render_using], @output_power, @reverb_power) end def help_cb help_dialog(@label, "\ The current sound will be moved through the chosen path. You can set \ the reverberator via the global with-sound-variable $clm_reverb \ (#{$clm_reverb.inspect}). If you want four reverb channels, you \ may try freeverb from freeverb.rb. reverb reverb-channels output-channels source jc_reverb 1 4 examp.rb jl_reverb 1 2 clm-ins.rb nrev 1 4 clm-ins.rb freeverb 4 > 4 freeverb.rb Amplitude-panning: generates amplitude panning between adjacent speakers. B-format-ambisonics: generates a four channel first order b-format encoded soundfile. Decoded-ambisonics: the ambisonics encoded information is decoded to the number of selected speakers. Note: reverb on spiral path generates noise if turns is less than 2.6 For detailed information see clm-2/dlocsig.html.", ["{Libxm}: graphics module", "{Ruby}: extension language", "{Motif}: Motif extensions via Libxm", "{dlocsig}: Fernando Lopez Lezcano's multichannel locator"]) end end class Dlocsig_bezier < Dlocsig_menu require "xm-enved" def initialize(label, snd_p = false) super @target = :with_sound @which_path = :open_bezier_path @snd_path = [[-10.0, 10.0, 0.0, 1.0], [0.0, 5.0, 1.0, 1.0], [10.0, 10.0, 0.0, 1.0]] @trajectory = nil @z_value = nil @velocity = nil @label_list = [] end def inspect str = @snd_path.inspect new_str = "" [str.length, 20].min.times do |i| new_str << str[i] end new_str << "..." if str.length > 20 format("%s (%s)", @label, new_str) end def post_dialog unless @dialog.kind_of?(Dialog) and widget?(@dialog.dialog) init_traj = [0, 1, 0.5, 0.5, 1, 1] init_z_traj = [0, 0, 0.5, 0.1, 1, 0] init_vel = [0, 0.5, 1, 0.5] @dialog = make_dialog(@label, :help_cb, lambda do |w, c, i| help_cb() end, :clear_cb, lambda do |w, c, i| create_path @path.pplot end, :reset_cb, lambda do |w, c, i| reset_with_sound_sliders @trajectory.envelope = init_traj @z_value.envelope = init_z_traj @velocity.envelope = init_vel show_values end) do |w, c, i| create_path with_sound_target("%s: %s, path: %s", @which_path, dlocsig_strings, @snd_path.inspect) end if provided? :xm frame_args = [RXmNshadowThickness, 4, RXmNshadowType, RXmSHADOW_ETCHED_OUT, RXmNbackground, basic_color, RXmNheight, 170, RXmNwidth, 400] pane = RXtCreateManagedWidget("pane", RxmPanedWindowWidgetClass, @dialog.parent, [RXmNsashHeight, 1, RXmNsashWidth, 1, RXmNorientation, RXmHORIZONTAL, RXmNbackground, basic_color]) xepane = RXtCreateManagedWidget("xepane", RxmPanedWindowWidgetClass, pane, [RXmNsashHeight, 1, RXmNsashWidth, 1, RXmNorientation, RXmVERTICAL, RXmNbackground, basic_color]) trfr = RXtCreateManagedWidget("trfr", RxmFrameWidgetClass, xepane, frame_args) zfr = RXtCreateManagedWidget("zfr", RxmFrameWidgetClass, xepane, frame_args) vefr = RXtCreateManagedWidget("vefr", RxmFrameWidgetClass, xepane, frame_args) vepane = RXtCreateManagedWidget("vpane", RxmPanedWindowWidgetClass, pane, [RXmNsashHeight, 1, RXmNsashWidth, 1, RXmNseparatorOn, true, RXmNorientation, RXmVERTICAL, RXmNbackground, basic_color]) add_with_sound_sliders(vepane) rc = RXtCreateManagedWidget("form", RxmRowColumnWidgetClass, vepane, [RXmNorientation, RXmVERTICAL, RXmNalignment, RXmALIGNMENT_CENTER]) @label_list = make_array(8) do |i| RXtCreateManagedWidget("W" * 30, RxmLabelWidgetClass, rc, []) end add_with_sound_targets @dialog.add_target([["open bezier", :open_bezier_path, true], ["closed bezier", :closed_bezier_path, false], ["literal", :literal_path, false]]) do |val| @which_path = val create_path end activate_dialog(@dialog.dialog) @trajectory = make_xenved("x, y", trfr, :envelope, init_traj, :axis_bounds, [0.0, 1.0, 0.0, 1.0], :axis_label, [-10.0, 10.0, 0.0, 10.0]) @z_value = make_xenved("z", zfr, :envelope, init_z_traj, :axis_bounds, [0.0, 1.0, 0.0, 1.0], :axis_label, [-10.0, 10.0, 0.0, 10.0]) @velocity = make_xenved("velocity v", vefr, :envelope, init_vel, :axis_bounds, [0.0, 1.0, 0.05, 1.0], :axis_label, [-10.0, 10.0, 0.0, 2.0]) else pane = Rgtk_hbox_new(false, 0) Rgtk_box_pack_start(RGTK_BOX(@dialog.parent), pane, false, false, 4) Rgtk_widget_show(pane) xepane = Rgtk_vbox_new(true, 0) Rgtk_box_pack_start(RGTK_BOX(pane), xepane, true, true, 4) Rgtk_widget_show(xepane) activate_dialog(@dialog.dialog) @trajectory = make_xenved("x, y", xepane, :envelope, init_traj, :axis_bounds, [0.0, 1.0, 0.0, 1.0], :axis_label, [-10.0, 10.0, 0.0, 10.0]) @z_value = make_xenved("z", xepane, :envelope, init_z_traj, :axis_bounds, [0.0, 1.0, 0.0, 1.0], :axis_label, [-10.0, 10.0, 0.0, 10.0]) @velocity = make_xenved("velocity v", xepane, :envelope, init_vel, :axis_bounds, [0.0, 1.0, 0.05, 1.0], :axis_label, [-10.0, 10.0, 0.0, 2.0]) vepane = Rgtk_vbox_new(false, 0) Rgtk_box_pack_start(RGTK_BOX(pane), vepane, false, false, 4) Rgtk_widget_show(vepane) add_with_sound_sliders(vepane) @label_list = make_array(8) do |i| lab = Rgtk_label_new("W" * 30) Rgtk_box_pack_start(RGTK_BOX(vepane), lab, false, false, 4) Rgtk_widget_show(lab) lab end add_with_sound_targets @dialog.add_target([["open bezier", :open_bezier_path, true], ["closed bezier", :closed_bezier_path, false], ["literal", :literal_path, false]]) do |val| @which_path = val create_path end end set_xm_enveds_hooks(@trajectory, @z_value, @velocity) @dialog.clear_string("Gnuplot") @dialog.doit_string((@snd_p ? "With_Snd" : "With_Sound")) show_values else activate_dialog(@dialog.dialog) end end private def create_path test_path @path = case @which_path when :open_bezier_path make_path(@snd_path) when :closed_bezier_path make_closed_path(@snd_path) when :literal_path make_literal_path(@snd_path) end end def test_path if @snd_path.length == 2 Snd.display("%s#%s: path has only two points, one added", self.class, get_func_name) @snd_path.insert(1, [0.0, @snd_path[0][1] - 0.1, 0.0, @snd_path[0][3] + 0.1]) end unless @snd_path.detect do |pnt| pnt[1].nonzero? end Snd.display("%s#%s: y-values are all zero, changed to mid-point 0.1", self.class, get_func_name) @snd_path[@snd_path.length / 2][1] = 0.1 end end def points_to_path @snd_path = [] @trajectory.each do |x, y| z = @z_value.interp(x) vel = @velocity.interp(x) @snd_path.push([x * 20.0 - 10.0, y * 10.0, z * 10.0, vel * 2.0]) end end def show_values points_to_path @label_list.each_with_index do |w, i| if i.zero? change_label(w, format("%6s %6s %6s %6s", "x", "y", "z", "v")) else x, y, z, v = @snd_path[i - 1] if x change_label(w, format("%s %s %s %s", to_f_str(x), to_f_str(y), to_f_str(z), to_f_str(v))) else change_label(w, "") end end end end def to_f_str(val) "%6s" % ("% 3.1f" % val) end end class Dlocsig_spiral < Dlocsig_menu def initialize(label, snd_p = false) super @start = 0 @turns = 3.0 end def inspect format("%s (%d %1.1f)", @label, @start, @turns) end def post_dialog unless @dialog.kind_of?(Dialog) and widget?(@dialog.dialog) sliders = [] init_start = 0 init_turns = 3.0 @dialog = make_dialog(@label, :help_cb, lambda do |w, c, i| help_cb end, :clear_cb, lambda do |w, c, i| make_spiral_path(:start_angle, @start, :turns, @turns).pplot end, :reset_cb, lambda do |w, c, i| reset_with_sound_sliders set_scale_value(sliders[0].scale, @start = init_start) @turns = init_turns set_scale_value(sliders[1].scale, init_turns, 10.0) end) do |w, c, i| @path = make_spiral_path(:start_angle, @start, :turns, @turns) with_sound_target("spiral_path: %s, start: %d, turns: %1.1f", dlocsig_strings, @start, @turns) end add_with_sound_sliders(if provided? :xg @dialog.dialog else @dialog.parent end) sliders << @dialog.add_slider("start angle", 0, init_start, 360) do |w, c, i| @start = get_scale_value(w, i) end # turns below 2.6 together with reverb create noise sliders << @dialog.add_slider("turns", 2.6, init_turns, 10.0, 10) do |w, c, i| @turns = get_scale_value(w, i, 10.0) end add_with_sound_targets @dialog.clear_string("Gnuplot") @dialog.doit_string((@snd_p ? "With_Snd" : "With_Sound")) end activate_dialog(@dialog.dialog) end end unless defined? $__private_dlocsig_menu__ and $__private_dlocsig_menu__ snd_main = make_snd_menu("Dlocsig") do cascade("Dlocsig (Snd)") do entry(Dlocsig_bezier, "Bezier path (Snd)", true) entry(Dlocsig_spiral, "Spiral path (Snd)", true) end cascade("Dlocsig (CLM)") do entry(Dlocsig_bezier, "Bezier path (CLM)", false) entry(Dlocsig_spiral, "Spiral path (CLM)", false) end end if provided? :xm set_label_sensitive(menu_widgets[Top_menu_bar], "Dlocsig", ((sounds() or []).length > 1)) else set_sensitive(snd_main.menu, ((sounds() or []).length > 1)) end unless $open_hook.member?("dlocsig-menu-hook") $open_hook.add_hook!("dlocsig-menu-hook") do |snd| if provided? :xm set_label_sensitive(menu_widgets[Top_menu_bar], "Dlocsig", true) else set_sensitive(snd_main.menu, true) end false end $close_hook.add_hook!("dlocsig-menu-hook") do |snd| if provided? :xm set_label_sensitive(menu_widgets[Top_menu_bar], "Dlocsig", ((sounds() or []).length > 1)) else set_sensitive(snd_main.menu, ((sounds() or []).length > 1)) end false end end end end # JC_REVERB (examp.rb) default options # # :low_pass, false # :volume, 1.0 # :amp_env, false # :delay1, 0.013 # :delay2, 0.011 # :delay3, 0.015 # :delay4, 0.017 # :double, false # # $clm_reverb = :jc_reverb_rb # $clm_reverb_data = [:low_pass, false, :volume, 1.0, :amp_env, false, # :delay1, 0.013, :delay2, 0.011, :delay3, 0.015, :delay4, 0.017] # require "clm-ins" # # JL_REVERB has no options # # $clm_reverb = :jl_reverb # $clm_reverb_data = [] # NREV default options # # :reverb_factor, 1.09 # :lp_coeff, 0.7 # :volume, 1.0 # # $clm_reverb = :nrev_rb # $clm_reverb_data = [:volume, 1.0, :lp_coeff, 0.7] # INTERN or N_REV default options (only with_snd) # # :amount, 0.1 # :filter, 0.5 # :feedback, 1.09 # # $clm_reverb = :intern # $clm_reverb_data = [:amount, 0.1, :filter, 0.5, :feedback, 1.09] # require "freeverb" # # FREEVERB default options # # :room_decay, 0.5, # :damping, 0.5, # :global, 0.3, # :predelay, 0.03, # :output_gain, 1.0, # :output_mixer, nil, # :scale_room_decay, 0.28, # :offset_room_decay, 0.7, # :combtuning, [1116, 1188, 1277, 1356, 1422, 1491, 1557, 1617], # :allpasstuning, [556, 441, 341, 225], # :scale_damping, 0.4, # :stereo_spread, 23, # # $clm_reverb = :freeverb # $clm_reverb_data = [:room_decay, 0.5, :damping, 0.5, :global, 0.3, :predelay, 0.03, # :output_gain, 1.0, :output_mixer, nil, :scale_room_decay, 0.7, # :scale_damping, 0.4, :stereo_spread, 23] =begin # (snd-ruby-mode) # Examples: (with_sound(:channels, 4, :output, "rdloc04.snd") do sinewave(0, 1, 440, 0.5, [[-10, 10], [0, 5], [10, 10]].to_path) end) (with_sound(:channels, 4, :output, "rdlocspiral.snd") do move(0, "/usr/gnu/sound/SFiles/bell.snd", DL.make_spiral_path(:start_angle, 180, :turns, 3.5)) end) ([[-10, 10, 0, 0], [0, 5, 0, 1], [10, 10, 0, 0]].to_path(:error, 0.01).plot_velocity) (with_sound(:channels, 4, :output, "rdlocmove.snd") do move_sound(DL.make_path([[-10, 10], [0.1, 0.1], [10, -10]])) do fm_violin_rb(0, 1, 440, 0.1) fm_violin_rb(0.3, 2, 1020, 0.05) end end) =end # dlocsig.rb ends here snd-16.1/tools/0000755000076400007640000000000012531621317011474 5ustar bilbilsnd-16.1/tools/valcall.scm0000644000076400007640000000430012571166502013617 0ustar bilbil(define file-names '(("teq.scm" . "v-eq") ("titer.scm" . "v-iter") ("tmap.scm" . "v-map") ("tform.scm" . "v-form") ("thash.scm" . "v-hash") ("tcopy.scm" . "v-cop") ("lg.scm" . "v-lg") ("tgen.scm" . "v-gen") ("tauto.scm" . "v-auto") ("make-index.scm" . "v-index") ("snd-test.scm" . "v-call") ("tall.scm" . "v-all") ("s7test.scm" . "v-test") )) (define (last-callg) (let ((name (system "ls callg*" #t))) (let ((len (length name))) (do ((i 0 (+ i 1))) ((or (= i len) (char-whitespace? (name i))) (substring name 0 i)))))) (define (next-file f) (let ((name (system (format #f "ls -t ~A*" f) #t))) (let ((len (length name))) (do ((i 0 (+ i 1))) ((or (= i len) (and (char-numeric? (name i)) (char-numeric? (name (+ i 1))))) (+ 1 (string->number (substring name i (+ i 2))))))))) (define (call-valgrind) (for-each (lambda (caller+file) (system "rm callg*") (format *stderr* "~%~NC~%~NC ~A ~NC~%~NC~%" 40 #\- 16 #\- (cadr caller+file) 16 #\- 40 #\-) (system (format #f "valgrind --tool=callgrind ./~A ~A" (car caller+file) (cadr caller+file))) (let ((outfile (cdr (assoc (cadr caller+file) file-names)))) (let ((next (next-file outfile))) (system (format #f "callgrind_annotate --auto=yes --threshold=100 ~A > ~A~D" (last-callg) outfile next)) (format *stderr* "~NC ~A~D -> ~A~D: ~NC~%" 8 #\space outfile (- next 1) outfile next 8 #\space) (system (format #f "./snd compare-calls.scm -e '(compare-calls \"~A~D\" \"~A~D\")'" outfile (- next 1) outfile next))))) (list (list "repl" "teq.scm") (list "repl" "s7test.scm") (list "snd -noinit" "make-index.scm") (list "repl" "tmap.scm") (list "repl" "tform.scm") (list "repl" "tcopy.scm") (list "repl" "tauto.scm") (list "repl" "titer.scm") (list "repl" "lg.scm") (list "repl" "thash.scm") (list "snd -noinit" "tgen.scm") ; repl here + cload sndlib was slower (list "snd -noinit" "tall.scm") (list "snd -l" "snd-test.scm") ))) (call-valgrind) (when (file-exists? "test.table") (system "mv test.table old-test.table") (load "compare-calls.scm") (combine-latest)) (exit)snd-16.1/tools/teq.scm0000644000076400007640000001004112603035275012767 0ustar bilbil;;; cyclic/shared timing tests ;;; equal? write/object->string/format cyclic-sequences ;(set! (*s7* 'default-hash-table-length) 15) (define* (make-circular-list n init) (let ((l (make-list n init))) (set-cdr! (list-tail l (- n 1)) l))) (define list-0 (list 1 2 3 4)) (define vect-0 (vector 1 2 3 4)) (define let-0 (inlet :a 1 :b 2)) (define hash-0 (hash-table* :a 1 :b 2)) (define list-1 (make-circular-list 1)) (set-car! list-1 #t) (define hash-1 (hash-table* :a list-1)) (define vect-1 (vector list-1)) (define let-1 (inlet :a list-1)) (define list-2 (list list-1 list-1)) (define list-3 (make-circular-list 3)) (define vect-2 (let ((z (vector 1 2))) (let ((y (list 1 z 2))) (let ((x (hash-table (cons 'x y)))) (set! (z 1) x) z)))) (define vect-3 (let ((x '(1 2))) (let ((y (list x x))) (let ((z (vector x y))) z)))) (define vect-4 (let ((v (vector 1 2 3 4))) (let ((lst (list 1 2))) (set-cdr! (cdr lst) lst) (set! (v 0) v) (set! (v 3) lst)))) (define hash-2 (let ((h1 (make-hash-table 11))) (hash-table-set! h1 "hi" h1))) (define list-4 (let () (define make-node list) (define prev (dilambda (lambda (node) (node 0)) (lambda (node val) (set! (node 0) val)))) (define next (dilambda (lambda (node) (node 2)) (lambda (node val) (set! (node 2) val)))) ;(define data (dilambda (lambda (node) (node 1)) (lambda (node val) (set! (node 1) val)))) (let* ((head (make-node () 0 ())) (cur head)) (do ((i 1 (+ i 1))) ((= i 8)) (let ((next-node (make-node cur i ()))) (set! (next cur) next-node) (set! cur (next cur)))) (set! (next cur) head) (set! (prev head) cur) head))) (define let-2 (let ((hi 3)) (let ((e (curlet))) (set! hi (curlet)) e))) (define let-3 (let ((e (inlet 'a 0 'b 1))) (let ((e1 (inlet 'a e))) (set! (e 'b) e1) e))) (define let-4 (inlet :a vect-0 :b list-0)) (define hash-3 (hash-table* :a vect-0 :b list-0)) (define hash-4 (hash-table* :a hash-1)) (define-constant vars (vector list-0 list-1 list-2 list-3 list-4 vect-0 vect-1 vect-2 vect-3 vect-4 hash-0 hash-1 hash-2 hash-3 hash-4 let-0 let-1 let-2 let-3 let-4)) ;(format *stderr* "~A ~A ~A ~A ~A~%" (length hash-0) (length hash-1) (length hash-2) (length hash-3) (length hash-4)) (set! (*s7* 'initial-string-port-length) 64) (define (tests size) (let ((str #f) (p (open-output-string)) (iter #f)) (do ((i 0 (+ i 1))) ((= i size)) (set! iter (make-iterator vars)) (do ((j 0 (+ j 1)) (vj (iterate iter) (iterate iter))) ((= j 20)) (do ((k 0 (+ k 1))) ((= k 20)) (if (equal? vj (vector-ref vars k)) (if (not (= j k)) (format *stderr* "oops! (~D ~D): ~A ~A~%" j k vj (vector-ref vars k))))) ;;(display "oops")))) (write vj p) (set! str (get-output-string p #t)) (set! str (object->string vj)) (set! str (format #f "~A~%" vj)) (set! str (cyclic-sequences vj)))) (close-output-port p))) #| (define (tests size) (let ((str #f) (vj #f) (p (open-output-string))) (do ((i 0 (+ i 1))) ((= i size)) (do ((a vars (cdr a))) ((null? a)) (set! vj (car a)) (do ((b vars (cdr b))) ((null? b)) (if (equal? vj (car b)) (if (not (eq? a b)) (format *stderr* "oops!: ~A ~A~%" a b)))) (write vj p) (set! str (get-output-string p #t)) (set! str (object->string vj)) (set! str (format #f "~A~%" vj)) (set! str (cyclic-sequences vj)))) (close-output-port p))) ;; almost as fast (define (tests size) (let ((str #f) (p (open-output-string)) (k 0) (j 0)) (do ((i 0 (+ i 1))) ((= i size)) (set! k 0) (for-each (lambda (vj) (set! j 0) (for-each (lambda (w) (if (equal? vj w) (if (not (= j k)) (format *stderr* "oops! (~D ~D): ~A ~A~%" j k vj w))) (set! j (+ j 1))) vars) (set! k (+ k 1)) (write vj p) (set! str (get-output-string p #t)) (set! str (object->string vj)) (set! str (format #f "~A~%" vj)) (set! str (cyclic-sequences vj))) vars)) (close-output-port p))) |# (tests 10000) (s7-version) (exit) snd-16.1/tools/profile.h0000644000076400007640000001063412545516515013321 0ustar bilbil#if 0 #if 1 #define NUM_COUNTS 65536 static int counts[NUM_COUNTS]; static void clear_counts(void) {int i; for (i = 0; i < NUM_COUNTS; i++) counts[i] = 0;} void tick(int this) {counts[this]++;} static void report_counts(s7_scheme *sc) { int i, mx, mxi, total = 0; bool happy = true; for (i = 0; i < NUM_COUNTS; i++) total += counts[i]; fprintf(stderr, "total: %d\n", total); while (happy) { mx = 0; for (i = 0; i < NUM_COUNTS; i++) { if (counts[i] > mx) { mx = counts[i]; mxi = i; } } if (mx > 0) { /* if (mx > total/100) */ fprintf(stderr, "%d: %d (%f)\n", mxi, mx, 100.0*mx/(float)total); counts[mxi] = 0; } else happy = false; } } #else #if 1 #define NUM_COUNTS 500 static int counts[70000][NUM_COUNTS]; static void clear_counts(void) {int i, j; for (i = 0; i < NUM_COUNTS; i++) for (j = 0; j < NUM_COUNTS; j++) counts[i][j] = 0;} static void tick(int line, int op) {counts[line][op]++; } static void report_counts(s7_scheme *sc) { int j, mx, mxi, mxj; fprintf(stderr, "\n"); for (mxi = 0; mxi < 70000; mxi++) { int k, ctotal = 0; for (k = 0; k < 500; k++) ctotal += counts[mxi][k]; if (ctotal > 0) { mx = 0; for (j = 0; j < NUM_COUNTS; j++) { if (counts[mxi][j] > mx) { mx = counts[mxi][j]; mxj = j; } } fprintf(stderr, "%d: %d %d of %d\n", mxi, mxj, counts[mxi][mxj], ctotal); } } #if 0 { int i; bool happy = true; while (happy) { mx = 0; for (i = 0; i < 70000; i++) for (j = 0; j < NUM_COUNTS; j++) { if (counts[i][j] > mx) { mx = counts[i][j]; mxi = i; mxj = j; } } if (mx > 0) { int k, ctotal = 0; for (k = 0; k < 500; k++) ctotal += counts[mxi][k]; fprintf(stderr, "%d: %d %d of %d\n", mxi, mxj, counts[mxi][mxj], ctotal); counts[mxi][mxj] = 0; } else happy = false; } } #endif } #else #define NUM_COUNTS 1000 static int counts[NUM_COUNTS]; static void clear_counts(void) {int i; for (i = 0; i < NUM_COUNTS; i++) counts[i] = 0;} static void tick(int op) {counts[op]++;} static void report_counts(s7_scheme *sc) { int k, i, mx; bool happy = true; fprintf(stderr, "\n"); while (happy) { mx = 0; for (k = 0; k < OP_MAX_DEFINED; k++) { if (counts[k] > mx) { mx = counts[k]; i = k; } } if (mx > 0) { fprintf(stderr, "%d: %d\n", i, counts[i]); counts[i] = 0; } else happy = false; } /* fprintf(stderr, "\n"); */ } #endif #endif static void init_hashes(s7_scheme *sc) {} #else void clear_counts(void) {} static s7_pointer hashes; void add_expr(s7_scheme *sc, s7_pointer expr); void add_expr(s7_scheme *sc, s7_pointer expr) { s7_pointer val; /* expr = sc->cur_code; */ val = s7_hash_table_ref(sc, hashes, expr); if (val == sc->F) { if (!is_any_closure(expr)) s7_hash_table_set(sc, hashes, expr, s7_make_integer(sc, 1)); } else { s7_hash_table_set(sc, hashes, expr, s7_make_integer(sc, 1 + s7_integer(val))); } } static void init_hashes(s7_scheme *sc) { hashes = s7_make_hash_table(sc, 65536); s7_gc_protect(sc, hashes); } typedef struct { s7_int count; s7_pointer expr; } datum; static datum *new_datum(s7_int ctr, s7_pointer e) { datum *d; d = calloc(1, sizeof(datum)); d->count = ctr; d->expr = e; return(d); } static int sort_data(const void *v1, const void *v2) { datum *d1 = *(datum **)v1; datum *d2 = *(datum **)v2; if (d1->count > d2->count) return(-1); return(1); } static void report_counts(s7_scheme *sc) { int len, i, loc = 0, entries; hash_entry_t **elements; datum **data; len = hash_table_length(hashes); elements = hash_table_elements(hashes); entries = hash_table_entries(hashes); if (entries == 0) { fprintf(stderr, "no counts\n"); return; } data = (datum **)calloc(entries, sizeof(datum *)); for (i = 0; i < len; i++) { hash_entry_t *x; for (x = elements[i]; x; x = x->next) data[loc++] = new_datum(s7_integer(x->value), x->key); } qsort((void *)data, loc, sizeof(datum *), sort_data); if (loc > 400) loc = 400; fprintf(stderr, "\n"); for (i = 0; i < loc; i++) if (data[i]->count > 0) fprintf(stderr, "%lld: %s\n", data[i]->count, DISPLAY_80(data[i]->expr)); free(data); } void add_code(s7_scheme *sc); void add_code(s7_scheme *sc) { add_expr(sc, sc->code); } /* use xen.h and s7 here */ #endif snd-16.1/tools/tmap.scm0000644000076400007640000002235412600075747013156 0ustar bilbil;;; sequence tests (define (less-than a b) (or (< a b) #f)) (define (less-than-2 a b) (if (not (real? a)) (display "oops")) (cond ((< a b) #t) (#t #f))) (define (char-less-than a b) (cond ((char (float-vector-ref fv (- i 1)) (float-vector-ref fv i)) (display "oops"))) (do ((i 1 (+ i 1))) ((= i len)) (if (> (fv (- i 1)) (fv i)) (display "oops"))) ;(format *stderr* "float-vector: ~A > ~A at ~D~%" (float-vector-ref fv (- i 1)) (float-vector-ref fv i) i))) (sort! fv-ran (lambda (a b) (< a b))) (if (not (morally-equal? fv fv-ran)) (format *stderr* "float-vector closure not equal~%")) (sort! fv-ran1 less-than) (if (not (morally-equal? fv fv-ran1)) (format *stderr* "float-vector cond closure not equal~%"))) (let ((fv-copy (copy fv))) (reverse! fv) (if (and (not (morally-equal? fv-copy fv)) (morally-equal? fv fv-orig)) (format *stderr* "float-vector reverse!: ~A ~A~%" fv fv-orig)) (reverse! fv) (if (not (morally-equal? fv-copy fv)) (format *stderr* "float-vector reverse! twice: ~A ~A~%" fv fv-copy)) (let ((fv1 (apply float-vector (make-list len 1.0)))) (if (or (not (= (length fv1) len)) (not (= (fv1 (- len 1)) 1.0))) (format *stderr* "float-vector apply: ~A ~A~%" len (fv (- len 1))))) )))) (define (iv-tst len) (let ((fv (make-int-vector len 0))) (if (not (= (length fv) len)) (format *stderr* "int-vector length ~A: ~A~%" fv (length fv))) (fill! fv 0) (let ((fv-orig (copy fv))) (do ((i 0 (+ i 1))) ((= i len)) (int-vector-set! fv i (- (random 1000000) 500000))) (do ((i 0 (+ i 1))) ((= i len)) (set! (fv i) (- (random 1000000) 500000))) (let ((fv-ran (copy fv)) (fv-ran1 (copy fv))) (sort! fv <) (do ((i 1 (+ i 1))) ((= i len)) (if (> (int-vector-ref fv (- i 1)) (int-vector-ref fv i)) (display "oops"))) (do ((i 1 (+ i 1))) ((= i len)) (if (> (fv (- i 1)) (fv i)) (display "oops"))) (sort! fv-ran (lambda (a b) (< a b))) (if (not (equal? fv fv-ran)) (format *stderr* "int-vector closure not equal~%")) (sort! fv-ran1 less-than) (if (not (equal? fv fv-ran1)) (format *stderr* "int-vector cond closure not equal~%"))) (let ((fv-copy (copy fv))) (reverse! fv) (if (and (not (equal? fv-copy fv)) (equal? fv fv-orig)) (format *stderr* "int-vector reverse!: ~A ~A~%" fv fv-orig)) (reverse! fv) (if (not (equal? fv-copy fv)) (format *stderr* "int-vector reverse! twice: ~A ~A~%" fv fv-copy)) )))) (define (v-tst len) (let ((fv (make-vector len))) (if (not (= (length fv) len)) (format *stderr* "vector length ~A: ~A~%" fv (length fv))) (fill! fv 0) (let ((fv-orig (copy fv))) (do ((i 0 (+ i 1))) ((= i len)) (vector-set! fv i (- (random 1000000) 500000))) (do ((i 0 (+ i 1))) ((= i len)) (set! (fv i) (- (random 1000000) 500000))) (let ((fv-ran (copy fv)) (fv-ran1 (copy fv))) (sort! fv <) (do ((i 1 (+ i 1))) ((= i len)) (if (> (vector-ref fv (- i 1)) (vector-ref fv i)) (display "oops"))) (do ((i 1 (+ i 1))) ((= i len)) (if (> (fv (- i 1)) (fv i)) (display "oops"))) (sort! fv-ran (lambda (a b) (< a b))) (if (not (equal? fv fv-ran)) (format *stderr* "vector closure not equal~%")) (sort! fv-ran1 less-than-2) (if (not (equal? fv fv-ran1)) (format *stderr* "vector cond closure not equal~%"))) (let ((fv-copy (copy fv))) (reverse! fv) (if (and (not (equal? fv-copy fv)) (equal? fv fv-orig)) (format *stderr* "vector reverse!: ~A ~A~%" fv fv-orig)) (reverse! fv) (if (not (equal? fv-copy fv)) (format *stderr* "vector reverse! twice: ~A ~A~%" fv fv-copy)) (let ((fv1 (apply vector (make-list len 1)))) (if (or (not (= (length fv1) len)) (not (= (fv1 (- len 1)) 1))) (format *stderr* "vector apply: ~A ~A~%" len (fv (- len 1))))) )))) (define (s-tst len) (let ((fv (make-string len))) (if (not (= (length fv) len)) (format *stderr* "string length ~A: ~A~%" fv (length fv))) (fill! fv #\a) (let ((fv-orig (copy fv))) (do ((i 0 (+ i 1))) ((= i len)) (string-set! fv i (integer->char (+ 20 (random 100))))) (do ((i 0 (+ i 1))) ((= i len)) (set! (fv i) (integer->char (+ 20 (random 100))))) (let ((fv-ran (copy fv)) (fv-ran1 (copy fv))) (sort! fv char? (string-ref fv (- i 1)) (string-ref fv i)) (display "oops"))) (do ((i 1 (+ i 1))) ((= i len)) (if (char>? (fv (- i 1)) (fv i)) (display "oops"))) (sort! fv-ran (lambda (a b) (char (car p0) (car p1)) (format *stderr* "list: ~A > ~A at ~D~%" (car p0) (car p1) i) (quit))))) (sort! fv-ran (lambda (a b) (< a b))) (if (not (equal? fv fv-ran)) (format *stderr* "pair closure not equal~%"))) (let ((fv-copy (copy fv))) (set! fv (reverse! fv)) (if (and (not (equal? fv-copy fv)) (equal? fv fv-orig)) (format *stderr* "list reverse!: ~A ~A~%" fv fv-orig)) (set! fv (reverse! fv)) (if (not (equal? fv-copy fv)) (format *stderr* "list reverse! twice: ~A ~A~%" fv fv-copy)) )))) (define (e-tst len) (let ((ht (make-hash-table len)) (lst (make-list len))) (do ((i 0 (+ i 1))) ((= i len)) (list-set! lst i i)) (do ((i 0 (+ i 1))) ((= i len)) (if (not (= (list-ref lst i) i)) (display "oops"))) (do ((i 0 (+ i 1))) ((= i len)) (set! (lst i) i)) (do ((i 0 (+ i 1))) ((= i len)) (if (not (= (lst i) i)) (display "oops"))) (do ((i 0 (+ i 1))) ((= i len)) (hash-table-set! ht i i)) (do ((i 0 (+ i 1))) ((= i len)) (if (not (= (hash-table-ref ht i) i)) (display "oops"))) (do ((i 0 (+ i 1))) ((= i len)) (set! (ht i) i)) (do ((i 0 (+ i 1))) ((= i len)) (if (not (= (ht i) i)) (display "oops"))))) (define (test-it) (for-each (lambda (b p) (do ((k 0 (+ k 1))) ((= k 1000)) (fv-tst b) (iv-tst b) (v-tst b) (s-tst b) (p-tst b) (e-tst b)) (do ((i 0 (+ i 1))) ((= i p)) (format *stderr* "~D " (expt b i)) (fv-tst (expt b i)) (iv-tst (expt b i)) (v-tst (expt b i)) (s-tst (expt b i)) (p-tst (expt b i)))) (list 2 3 4 7 10) (list 12 4 3 6 6))) (test-it) (newline *stderr*) (let ((size 1000000)) (define (fe1 x) (if (not (char=? x #\1)) (display x))) (define (fe2) (for-each fe1 (make-string size #\1))) (define (fe20) (for-each char-upcase (make-string size #\1))) (fe2) (fe20) (define (fe3 x) (if (not (char=? x #\1)) (display x))) (define (fe4) (for-each fe3 (make-list size #\1))) (define (fe40) (for-each char? (make-list size #\1))) (fe4) (fe40) (define (fe5 x) (if (not (char=? x #\1)) (display x))) (define (fe6) (for-each fe5 (make-vector size #\1))) (define (fe60) (for-each char-alphabetic? (make-vector size #\1))) (fe6) (fe60) (define (fe7 x) (if (not (= x 1)) (display x))) (define (fe8) (for-each fe7 (make-int-vector size 1))) (define (fe80) (for-each abs (make-int-vector size 1))) (fe8) (fe80) (define (fe9 x) (if (not (= x 1.0)) (display x))) (define (fe10) (for-each fe9 (make-float-vector size 1.0))) (define (fe100) (for-each real? (make-float-vector size 1.0))) (fe10) (fe100) (define (fe11 p) (if (member 1 (make-list p 2) >) (display "oops"))) (fe11 size) (fe11 1) (define (less a b) (> a b)) (define (fe12 p) (if (member 1 (make-list p 2) less) (display "oops"))) (fe12 size) (fe12 1) (define (fe13 p) (if (member 1 (make-list p 2) (lambda (a b) (cond ((> a b) #t) (#t #f)))) (display "oops"))) (fe13 size) (fe13 1)) (s7-version) (exit) ;;; unsafe, strings, precheck types in vect casessnd-16.1/tools/makegl.scm0000755000076400007640000007271212625630555013464 0ustar bilbil;;; makegl.scm creates the GL/GLU bindings using gldata.scm, writes gl.c (define gl-file (open-output-file "gl.c")) (define-expansion (hey . args) `(format gl-file ,@args)) (define (heyc arg) (display arg gl-file)) (define names ()) (define types ()) (define ints ()) (define funcs ()) (define x-types ()) (define x-funcs ()) (define x-ints ()) ;(define g-types ()) ;(define g-funcs ()) ;(define g-ints ()) ;(define g5-funcs ()) ;(define g5-ints ()) (define in-glu #f) (define (check-glu name) (if in-glu (if (not (string=? "glu" (substring name 0 3))) (begin (set! in-glu #f) (hey "#endif~%"))) (if (string=? "glu" (substring name 0 3)) (begin (set! in-glu #t) (hey "#if HAVE_GLU~%"))))) (define (uncheck-glu) (if in-glu (begin (hey "#endif~%") (set! in-glu #f)))) (define (cadr-str data) (let ((sp1 (char-position #\space data))) (let ((sp2 (char-position #\space data (+ sp1 1)))) (if sp2 (substring data (+ sp1 1) sp2) (substring data sp1))))) (define (caddr-str data) (let ((sp1 (char-position #\space data))) (let ((sp2 (char-position #\space data (+ sp1 1)))) (let ((sp3 (char-position #\space data (+ sp2 1)))) (if sp3 (substring data (+ sp2 1)) (substring data sp2)))))) (define (car-str data) (let ((sp (char-position #\space data))) (if sp (substring data 0 sp) data))) (define (cdr-str data) (let ((sp (char-position #\space data))) (if sp (substring data (+ sp 1)) data))) (define (ref-arg? arg) (and (= (length arg) 3) (string? (caddr arg)))) (define (null-arg? arg) (and (= (length arg) 3) (eq? (caddr arg) 'null))) (define (opt-arg? arg) (and (= (length arg) 3) (eq? (caddr arg) 'opt))) (define (ref-args args) (let ((ctr 0)) (for-each (lambda (arg) (if (ref-arg? arg) (set! ctr (+ 1 ctr)))) args) ctr)) (define (opt-args args) (let ((ctr 0)) (for-each (lambda (arg) (if (opt-arg? arg) (set! ctr (+ 1 ctr)))) args) ctr)) (define (deref-type arg) (let ((type (car arg))) (substring type 0 (- (length type) 1)))) (define (deref-name arg) (let ((name (cadr arg))) (string-append "ref_" name))) (define (derefable type) (let ((len (length type))) (call-with-exit (lambda (return) (do ((i (- len 1) (- i 1)) (ctr 0 (+ 1 ctr))) ((= i 0) #f) (if (not (char=? (type i) #\*)) (return (> ctr 1)))))))) (define (has-stars type) (let ((len (length type))) (call-with-exit (lambda (return) (do ((i (- len 1) (- i 1))) ((= i 0) #f) (if (char=? (type i) #\*) (return #t))) #f)))) (define (no-stars type) (if (string=? type "Display*") "Display" (if (string=? type "XVisualInfo*") "XVisualInfo" (let ((len (length type)) (val (string-copy type))) (do ((i 0 (+ i 1))) ((= i len) val) (if (char=? (val i) #\*) (set! (val i) #\_))))))) (define (no-arg-or-stars name) (let ((len (length name))) (call-with-exit (lambda (return) (do ((i 0 (+ i 1))) ((= i len) name) (if (or (char=? (name i) #\() (char=? (name i) #\*)) (return (substring name 0 i)))))))) (define* (parse-args args x) (let ((data ()) (sp -1) (type #f) (len (length args))) (if (string=? args "void") () (do ((i 0 (+ i 1))) ((= i len) (reverse data)) (let ((ch (args i))) (if (or (char=? ch #\space) (= i (- len 1))) (begin (if type (let ((given-name (substring args (+ 1 sp) (if (= i (- len 1)) (+ i 1) i))) (reftype #f)) (if (char=? (given-name 0) #\@) (set! data (cons (list type (substring given-name 1 (length given-name)) 'null) data)) (if (char=? (given-name 0) #\#) (set! data (cons (list type (substring given-name 1 (length given-name)) 'opt) data)) (if (char=? (given-name 0) #\[) (begin (set! reftype (deref-type (list type))) (set! data (cons (list type (substring given-name 1 (- (length given-name) 1)) given-name) data))) (set! data (cons (list type given-name) data))))) (if reftype (set! type reftype)) (if (eq? x 'x) (if (not (member type x-types)) (set! x-types (cons type x-types))) (if (and (not (eq? x 'g)) (not (member type types))) (set! types (cons type types)))) (set! type #f)) (if (> i (+ 1 sp)) (set! type (substring args (+ 1 sp) i)))) (set! sp i)))))))) (define (helpify name type args) (let* ((initial (format #f " #define H_~A \"~A ~A(" name type name)) (line-len (length initial)) (len (length args)) (typed #f) (help-max 100)) (hey initial) (do ((i 0 (+ i 1))) ((= i len)) (let ((ch (args i))) (if (char=? ch #\space) (if typed (begin (heyc ", ") (set! line-len (+ line-len 2)) (if (> line-len help-max) (begin (hey "\\~%") (set! line-len 0))) (set! typed #f)) (begin (set! line-len (+ 1 line-len)) (heyc " ") (set! typed #t))) (if (and (not (char=? ch #\@)) (not (char=? ch #\#))) (begin (set! line-len (+ 1 line-len)) (heyc ch)))))) (hey ")\"~%"))) (define direct-types (list (cons "void" #f) (cons "GLvoid" #f) (cons "int" "INT") (cons "GLint" "INT") (cons "GLsizei" "INT") (cons "GLenum" "INT") (cons "GLfloat" "DOUBLE") (cons "GLclampf" "DOUBLE") (cons "GLdouble" "DOUBLE") (cons "GLclampd" "DOUBLE") (cons "double" "DOUBLE") (cons "char" "CHAR") (cons "char*" "STRING") (cons "GLbyte" "INT") (cons "GLshort" "INT") (cons "GLbitfield" "ULONG") (cons "GLboolean" "BOOLEAN") (cons "GLushort" "INT") (cons "GLuint" "ULONG") (cons "GLubyte" "INT") (cons "unsigned_long" "ULONG") (cons "Bool" "BOOLEAN") (cons "xen" #t) (cons "constchar*" "STRING") (cons "guint" "INT") (cons "gint" "INT") (cons "gboolean" "BOOLEAN") )) (define glu-1-2 '("GLUtesselator*" "gluBeginPolygon" "gluDeleteTess" "gluEndPolygon" "gluNextContour" "gluTessVertex" "gluGetTessProperty" "gluTessBeginContour" "gluTessBeginPolygon" "gluTessEndContour" "gluTessEndPolygon" "gluTessNormal" "gluTessProperty" "gluNewTess")) (define (c-to-xen-macro-name typ str) (if (string=? str "INT") "C_int_to_Xen_integer" (if (string=? str "DOUBLE") "C_double_to_Xen_real" (if (string=? str "BOOLEAN") "C_bool_to_Xen_boolean" (if (string=? str "ULONG") "C_ulong_to_Xen_ulong" (if (string-ci=? str "String") (if (string=? (car typ) "guchar*") "C_to_Xen_String" "C_string_to_Xen_string") (format #f "~A unknown" str))))))) (define (xen-to-c-macro-name str) (if (string=? str "INT") "Xen_integer_to_C_int" (if (string=? str "DOUBLE") "Xen_real_to_C_double" (if (string=? str "BOOLEAN") "Xen_boolean_to_C_bool" (if (string=? str "ULONG") "Xen_ulong_to_C_ulong" (if (string-ci=? str "String") "Xen_string_to_C_string" (format #f "~A unknown" str))))))) (define (type-it type) (let ((typ (assoc type direct-types))) (if typ (if (cdr typ) (begin (if (string? (cdr typ)) (begin (if (not (member (car typ) (list "Display*" "XVisualInfo*" "int*" "Pixmap" "Font" "GLubyte*" "GLdouble*" "GLfloat*" "GLvoid*" "GLuint*" "GLboolean*" "void*" "GLint*" "GLshort*" "GLsizei" "GLclampd" "GLclampf" "GLbitfield" "GLshort" "GLbyte" "unsigned_long" "void**"))) (if (string=? (car typ) "constchar*") (hey "#define C_to_Xen_~A(Arg) C_string_to_Xen_string((char *)(Arg))~%" (no-stars (car typ))) (hey "#define C_to_Xen_~A(Arg) ~A(Arg)~%" (no-stars (car typ)) (c-to-xen-macro-name typ (cdr typ))))) (if (not (string=? (car typ) "constchar*")) (hey "#define Xen_to_C_~A(Arg) (~A)(~A(Arg))~%" (no-stars (car typ)) (car typ) (xen-to-c-macro-name (cdr typ)))) (if (not (string=? (car typ) "constchar*")) (hey "#define Xen_is_~A(Arg) Xen_is_~A(Arg)~%" (no-stars (car typ)) (if (string=? (cdr typ) "INT") "integer" (if (string=? (cdr typ) "ULONG") "ulong" (if (string=? (cdr typ) "DOUBLE") "number" (apply string (map char-downcase (cdr typ))))))))) (begin (hey "#define Xen_is_~A(Arg) 1~%" (no-stars (car typ))) (hey "#define Xen_to_C_~A(Arg) ((gpointer)Arg)~%" (no-stars (car typ))))))) (if (not (or (string=? type "Display*") ; why are these 2 handled specially? (string=? type "XVisualInfo*") (string=? type "GLXContext"))) ; Snd g_snd_gl_context (snd-motif.c) calls this a pointer (begin (if (member type glu-1-2) (hey "#ifdef GLU_VERSION_1_2~%") (if (member type (list "GLUnurbs*" "GLUtesselator*" "GLUquadric*" "_GLUfuncptr")) (hey "#if HAVE_GLU~%"))) (hey "XL_TYPE~A~A(~A, ~A)~%" (if (has-stars type) "_PTR" "") (if (member type (list "int*" "Pixmap" "Font" "GLubyte*" "GLdouble*" "GLfloat*" "GLvoid*" "GLuint*" "GLboolean*" "GLint*" "GLshort*" "PangoFontDescription*" "GtkWidget*" "GdkGLConfigMode" )) "_1" (if (member type (list "GdkVisual*" "PangoFont*" "GdkColormap*")) "_2" "")) (no-stars type) type) (if (or (member type glu-1-2) (member type (list "GLUnurbs*" "GLUtesselator*" "GLUquadric*" "_GLUfuncptr"))) (hey "#endif~%"))) (if (string=? type "Display*") (hey "XL_TYPE_PTR(Display, Display*)~%") (if (string=? type "XVisualInfo*") (hey "XL_TYPE_PTR(XVisualInfo, XVisualInfo*)~%") (hey "XL_TYPE_PTR(GLXContext, GLXContext)~%") )))))) (define* (CFNC data spec spec-name) (let ((name (cadr-str data)) (args (caddr-str data))) (if (assoc name names) (format #t "~A CFNC~%" name) (let ((type (car-str data))) (if (not (member type types)) (set! types (cons type types))) (let ((strs (parse-args args))) (if spec (set! funcs (cons (list name type strs args spec spec-name) funcs)) (set! funcs (cons (list name type strs args) funcs))) (set! names (cons (cons name 'fnc) names))))))) (define* (CINT name type) (if (assoc name names) (format #t "~A CINT~%" name) (begin (set! ints (cons name ints)) (set! names (cons (cons name 'int) names))))) (define* (CFNC-X data spec spec-name) (let ((name (cadr-str data)) (args (caddr-str data))) (if (assoc name names) (format #t "~A CFNC-X~%" name) (let ((type (car-str data))) (if (not (member type x-types)) (set! x-types (cons type x-types))) (let ((strs (parse-args args 'x))) (if spec (set! x-funcs (cons (list name type strs args spec spec-name) x-funcs)) (set! x-funcs (cons (list name type strs args) x-funcs))) (set! names (cons (cons name 'fnc) names))))))) (define* (CINT-X name type) (if (assoc name names) (format #t "~A CINT-X~%" name) (begin (set! x-ints (cons name x-ints)) (set! names (cons (cons name 'int) names))))) (define (no-arg name) (let ((len (length name))) (call-with-exit (lambda (return) (do ((i 0 (+ i 1))) ((= i len) name) (if (char=? (name i) #\() (return (substring name 0 i)))))))) ;;; ---------------------------------------- read data ---------------------------------------- (load "gldata.scm") ;;; ---------------------------------------- write output file ---------------------------------------- (hey "/* gl.c: s7, Ruby, and Forth bindings for GL, GLU~%") (hey " * generated automatically from makegl.scm and gldata.scm~%") (hey " * needs xen.h~%") (hey " *~%") (hey " * reference args are ignored if passed, resultant values are returned in a list.~%") (hey " * the various \"v\" forms are omitted for now -- are they needed in this context?~%") (hey " * 'gl is added to *features*~%") (hey " *~%") (hey " * HISTORY:~%") (hey " *~%") (hey " * 16-Apr-14: changed max-args to 8.~%") (hey " * --------~%") (hey " * 16-Dec-09: removed Guile support.~%") (hey " * --------~%") (hey " * 17-Oct-08: removed gtkglext bindings.~%") (hey " * --------~%") (hey " * 30-Mar-06: check for glu.h, omit GLU_* if necessary. Add Forth support.~%") (hey " * --------~%") (hey " * 13-Jun-05: merged gl-ruby.c into gl.c.~%") (hey " * --------~%") (hey " * 10-Mar: Gl_Version.~%") (hey " * 1-Feb-03: glGet* funcs now try to handle multiple return values correctly.~%") (hey " * --------~%") (hey " * 18-Nov: added more GtkGlext bindings.~%") (hey " * 1-Aug: removed all 'EXT' junk.~%") (hey " * 24-July: changed Guile prefix (R5RS reserves vertical-bar).~%") (hey " * 18-June: GL 1.1 stubs.~%") (hey " * 4-June: GtkGLext support.~%") (hey " * 20-May-02: initial version.~%") (hey " */~%~%") (hey "#include \"mus-config.h\"~%~%") (hey "#if HAVE_EXTENSION_LANGUAGE~%") (hey "#include ~%") (hey "#if HAVE_GLU~%") (hey " #include ~%") (hey "#endif~%") (hey "#if USE_MOTIF~%") (hey " #include ~%") (hey "#endif~%") (hey "#include ~%~%") (hey "#if USE_SND~%") (hey " /* USE_SND causes xm to use Snd's error handlers which are much smarter than xen's fallback versions */~%") (hey " #include \"snd.h\"~%") (hey "#else~%") (hey " #include \"xen.h\"~%") (hey "#endif~%") (hey "#ifndef unsigned_long~%") (hey " /* for FreeBSD (thanks to Michael Scholz) (can't use ulong here due to collisions elsewhere) */~%") (hey " typedef unsigned long unsigned_long;~%") (hey "#endif~%~%") (hey "/* prefix for all names */~%") (hey "#if HAVE_SCHEME~%") (hey " #define XL_PRE \"\"~%") (hey " #define XL_POST \"\"~%") (hey "#endif~%") (hey "#if HAVE_RUBY~%") (hey "/* for Ruby, XG PRE needs to be uppercase */~%") (hey " #define XL_PRE \"R\"~%") (hey " #define XL_POST \"\"~%") (hey "#endif~%") (hey "#if HAVE_FORTH~%") (hey " #define XL_PRE \"F\"~%") (hey " #define XL_POST \"\"~%") (hey "#endif~%") (hey "~%") (hey "#define wrap_for_Xen(Name, Value) Xen_list_2(C_string_to_Xen_symbol(Name), Xen_wrap_C_pointer(Value))~%") (hey "#define is_wrapped(Name, Value) (Xen_is_list(Value) && \\~%") (hey " (Xen_list_length(Value) >= 2) && \\~%") (hey " (Xen_is_symbol(Xen_car(Value))) && \\~%") (hey " (strcmp(Name, Xen_symbol_to_C_string(Xen_car(Value))) == 0))~%") (hey "~%") ;;; these have to match the choices in xm.c (hey "#define XL_TYPE(Name, XType) \\~%") (hey " static Xen C_to_Xen_ ## Name (XType val) {return(Xen_list_2(C_string_to_Xen_symbol(#Name), C_ulong_to_Xen_ulong(val)));} \\~%") (hey " static XType Xen_to_C_ ## Name (Xen val) {return((XType)Xen_ulong_to_C_ulong(Xen_cadr(val)));} \\~%") (hey " static bool Xen_is_ ## Name (Xen val) {return(is_wrapped(#Name, val));}~%") (hey "#define XL_TYPE_1(Name, XType) \\~%") (hey " static XType Xen_to_C_ ## Name (Xen val) {return((XType)Xen_ulong_to_C_ulong(Xen_cadr(val)));} \\~%") (hey " static bool Xen_is_ ## Name (Xen val) {return(is_wrapped(#Name, val));}~%") (hey "~%") (hey "#define XL_TYPE_PTR(Name, XType) \\~%") (hey " static Xen C_to_Xen_ ## Name (XType val) {if (val) return(wrap_for_Xen(#Name, val)); return(Xen_false);} \\~%") (hey " static XType Xen_to_C_ ## Name (Xen val) {if (Xen_is_false(val)) return(NULL); return((XType)Xen_unwrap_C_pointer(Xen_cadr(val)));} \\~%") (hey " static bool Xen_is_ ## Name (Xen val) {return(is_wrapped(#Name, val));} /* if NULL ok, should be explicit */~%") (hey "#define XL_TYPE_PTR_1(Name, XType) \\~%") (hey " static XType Xen_to_C_ ## Name (Xen val) {if (Xen_is_false(val)) return(NULL); return((XType)Xen_unwrap_C_pointer(Xen_cadr(val)));} \\~%") (hey " static bool Xen_is_ ## Name (Xen val) {return(is_wrapped(#Name, val));} /* if NULL ok, should be explicit */~%") ;XL_TYPE_PTR_2 was for "GdkVisual*" "PangoFont*" "GdkColormap*" ;(hey "#define XL_TYPE_PTR_2(Name, XType) \\~%") ;(hey " static Xen C_to_Xen_ ## Name (XType val) {if (val) return(wrap_for_Xen(#Name, val)); return(Xen_false);}~%") (hey "~%~%/* ---------------------------------------- types ---------------------------------------- */~%~%") (hey "#if USE_MOTIF~%") (for-each type-it (reverse x-types)) (hey "#endif~%") ;(hey "#if USE_GTK~%") ;(for-each type-it (reverse g-types)) ;(hey "#endif~%") (for-each type-it (reverse types)) (hey "~%~%/* ---------------------------------------- state readback confusion ---------------------------------------- */~%~%") (hey "static int how_many_vals(GLenum gl)~%") (hey "{~%") (hey " switch (gl)~%") (hey " {~%") (hey " case GL_CURRENT_COLOR:~%") (hey " case GL_CURRENT_TEXTURE_COORDS:~%") (hey " case GL_CURRENT_RASTER_POSITION:~%") (hey " case GL_CURRENT_RASTER_COLOR:~%") (hey " case GL_CURRENT_RASTER_TEXTURE_COORDS:~%") (hey " case GL_VIEWPORT:~%") (hey " case GL_FOG_COLOR:~%") (hey " case GL_AMBIENT:~%") (hey " case GL_DIFFUSE:~%") (hey " case GL_SPECULAR:~%") (hey " case GL_EMISSION:~%") (hey " case GL_LIGHT_MODEL_AMBIENT:~%") (hey " case GL_SCISSOR_BOX:~%") (hey " case GL_COLOR_WRITEMASK:~%") (hey " case GL_COLOR_CLEAR_VALUE:~%") (hey " return(4);~%") (hey " break;~%") (hey " case GL_MODELVIEW_MATRIX:~%") (hey " case GL_PROJECTION_MATRIX:~%") (hey " case GL_TEXTURE_MATRIX:~%") (hey " return(16);~%") (hey " break;~%") (hey " case GL_CURRENT_NORMAL:~%") (hey " case GL_SPOT_DIRECTION:~%") (hey " return(3);~%") (hey " break;~%") (hey " case GL_DEPTH_RANGE:~%") (hey " case GL_LINE_WIDTH_RANGE:~%") (hey " return(2);~%") (hey " break;~%") (hey " default: return(1); break; /* try to squelch c++ babbling */~%") (hey " }~%") (hey " return(1);~%") (hey "}~%") (define need-vals-check (list "glGetIntegerv" "glGetFloatv" "glGetMaterialfv" "glGetLightfv" "glGetBooleanv")) (define max-args 8) (hey "~%~%/* ---------------------------------------- functions ---------------------------------------- */~%~%") (define handle-func (lambda (data) (let* ((name (car data)) (return-type (cadr data)) (args (caddr data)) (cargs (length args)) (refargs (ref-args args)) (xgargs (- cargs refargs)) (argstr (cadddr data)) ;(lambda-type (cdr (assoc name names))) (arg-start 0) (line-len 0) (line-max 120)) (define (hey-start) ;; start of checked line (set! line-len 0)) (define (hey-mark) ;; start of checked line (set! arg-start line-len)) (define (hey-on . args) ;; no cr -- just append (let ((line (apply format #f args))) (set! line-len (+ line-len (length line))) (heyc line))) (define (hey-ok arg) ;; cr ok after arg (set! line-len (+ line-len (length arg))) (heyc arg) (if (> line-len line-max) (begin (hey "~%") (do ((i 0 (+ i 1))) ((= i arg-start)) (heyc " ")) (set! line-len arg-start)))) (check-glu name) (if (member name glu-1-2) (hey "#ifdef GLU_VERSION_1_2~%")) (if (and (> (length data) 4) (eq? (data 4) 'if)) (hey "#if HAVE_~A~%" (string-upcase (symbol->string (data 5))))) (hey "static Xen gxg_~A(" name) (if (= (length args) 0) (heyc "void") (if (>= (length args) max-args) (heyc "Xen arglist") (let ((previous-arg #f)) (for-each (lambda (arg) (let ((argname (cadr arg)) ;(argtype (car arg)) ) (if previous-arg (heyc ", ")) (set! previous-arg #t) (hey "Xen ~A" argname))) args)))) (hey ")~%{~%") (helpify name return-type argstr) (if (> refargs 0) (for-each (lambda (arg) (if (ref-arg? arg) (if (member name need-vals-check) (hey " ~A ~A[16];~%" (deref-type arg) (deref-name arg)) (hey " ~A ~A[1];~%" (deref-type arg) (deref-name arg))))) args)) (if (and (>= (length args) max-args) (> xgargs 0)) (let ((previous-arg #f)) (heyc " Xen ") (for-each (lambda (arg) (if (not (ref-arg? arg)) ;(< (length arg) 3) (begin (if previous-arg (heyc ", ")) (set! previous-arg #t) (hey "~A" (cadr arg))))) args) (hey ";~%") (let ((ctr 0)) ; list-ref counts from 0 (for-each (lambda (arg) (if (not (ref-arg? arg)) (hey " ~A = Xen_list_ref(arglist, ~D);~%" (cadr arg) ctr)) (set! ctr (+ 1 ctr))) args)))) (if (> (length args) 0) (let ((ctr 1)) (for-each (lambda (arg) (let ((argname (cadr arg)) (argtype (car arg))) (if (not (ref-arg? arg)) (if (null-arg? arg) (hey " Xen_check_type(Xen_is_~A(~A) || Xen_is_false(~A), ~A, ~D, ~S, ~S);~%" (no-stars argtype) argname argname argname ctr name argtype) (if (opt-arg? arg) (begin (hey " if (!Xen_is_bound(~A)) ~A = Xen_false; ~%" argname argname) (hey " else Xen_check_type(Xen_is_~A(~A), ~A, ~D, ~S, ~S);~%" (no-stars argtype) argname argname ctr name argtype)) (hey " Xen_check_type(Xen_is_~A(~A), ~A, ~D, ~S, ~S);~%" (no-stars argtype) argname argname ctr name argtype)))) (set! ctr (+ 1 ctr)))) args))) (let ((using-result #f)) (set! using-result (and (> refargs 0) (not (string=? return-type "void")))) (if using-result (begin (hey " {~%") (hey " Xen result;~%"))) (hey-start) (if (not (string=? return-type "void")) (if (= refargs 0) (hey-on " return(C_to_Xen_~A(" (no-stars return-type)) (hey-on " result = C_to_Xen_~A(" (no-stars return-type))) (hey-on " ")) (hey-on "~A(" name) (hey-mark) (if (> (length args) 0) (let ((previous-arg #f)) (for-each (lambda (arg) (let ((argname (cadr arg)) (argtype (car arg))) (if previous-arg (hey-ok ", ")) (if (and (not previous-arg) (> (length data) 4) (eq? (data 4) 'const)) (hey "(const ~A)" argtype)) (set! previous-arg #t) (if (ref-arg? arg) (hey-on "~A" (deref-name arg)) (hey-on "Xen_to_C_~A(~A)" (no-stars argtype) argname)))) args))) (if (> refargs 0) (let ((previous-arg using-result)) (if (not (string=? return-type "void")) (heyc ")")) (hey ");~%") (if using-result (heyc " ")) (if (member name need-vals-check) (begin (hey " {~%") (if (not using-result) (hey " Xen result;~%")) (hey " int i, vals;~%") (hey " vals = how_many_vals(Xen_to_C_GLenum(pname));~%") (hey " result = Xen_empty_list;~%") (hey " for (i = 0; i < vals; i++)~%") (hey " result = Xen_cons(C_to_Xen_~A(~A[i]), result);~%" (no-stars (deref-type (args (- (length args) 1)))) (deref-name (args (- (length args) 1)))) (hey " return(result);~%") (hey " }~%")) (begin (hey " return(Xen_list_~D(" (+ refargs (if using-result 1 0))) (if using-result (heyc "result")) (for-each (lambda (arg) (if (ref-arg? arg) (begin (if previous-arg (heyc ", ")) (hey "C_to_Xen_~A(~A[0])" (no-stars (deref-type arg)) (deref-name arg)) (set! previous-arg #t)))) args) (hey "));~%"))) (if using-result (hey " }~%"))) (if (string=? return-type "void") (begin (hey ");~%") (hey " return(Xen_false);~%")) (hey ")));~%"))) ) (hey "}~%") (if (member name glu-1-2) (hey "#endif~%")) (hey "~%") ))) (hey "#if USE_MOTIF~%") (for-each handle-func (reverse x-funcs)) (hey "#endif~%") (for-each handle-func (reverse funcs)) (uncheck-glu) ;;; ---------------- argify linkages (define (argify-func func) (let ((cargs (length (caddr func))) (name (car func)) (refargs (+ (ref-args (caddr func)) (opt-args (caddr func)))) ;(args (- cargs refargs)) (if-fnc (and (> (length func) 4) (eq? (func 4) 'if)))) (check-glu name) (if (member name glu-1-2) (hey "#ifdef GLU_VERSION_1_2~%")) (if if-fnc (hey "#if HAVE_~A~%" (string-upcase (symbol->string (func 5))))) (hey "Xen_wrap_~A(gxg_~A_w, gxg_~A)~%" (if (>= cargs max-args) "any_args" (if (> refargs 0) (format #f "~D_optional_arg~A" cargs (if (= cargs 1) "" "s")) (format #f "~A_arg~A" (if (zero? cargs) "no" (number->string cargs)) (if (= cargs 1) "" "s")))) (car func) (car func)) (if if-fnc (hey "#endif~%")) (if (member (car func) glu-1-2) (hey "#endif~%")))) (hey "#if USE_MOTIF~%") (for-each argify-func (reverse x-funcs)) (hey "#endif~%") (for-each argify-func (reverse funcs)) (uncheck-glu) ;;; ---------------- procedure linkages (define (gtk-type->s7-type gtk) (let ((dt (assoc gtk direct-types))) (if (and (pair? dt) (string? (cdr dt))) (let ((direct (cdr dt))) (cond ((member direct '("INT" "ULONG") string=?) 'integer?) ((string=? direct "BOOLEAN") 'boolean?) ((string=? direct "DOUBLE") 'real?) ((string=? direct "CHAR") 'char?) ((string=? direct "String") 'string?) (#t #t))) #t))) (define (make-signature fnc) (define (compress sig) (if (and (pair? sig) (pair? (cdr sig)) (or (not (eq? (car sig) 'pair?)) (not (null? (cddr sig)))) (eq? (car sig) (cadr sig))) (compress (cdr sig)) sig)) (let ((sig (list (gtk-type->s7-type (cadr fnc))))) (for-each (lambda (arg) (set! sig (cons (gtk-type->s7-type (car arg)) sig))) (caddr fnc)) (reverse (compress sig)))) (define signatures (make-hash-table)) (define (make-signatures lst) (for-each (lambda (f) (let ((sig (make-signature f))) (if (pair? sig) (let ((count (signatures sig))) (if (not count) (set! (signatures sig) 0) (set! (signatures sig) (+ count 1))))))) lst)) (make-signatures funcs) (make-signatures x-funcs) ;(format *stderr* "~D entries, ~D funcs~%" (hash-table-entries signatures) (length funcs)) (hey "static void define_functions(void)~%") (hey "{~%") (hey "#if HAVE_SCHEME~%") (hey "static s7_pointer s_boolean, s_integer, s_real, s_any;~%") (hey "static s7_pointer ") (define (sig-name sig) (call-with-output-string (lambda (p) (display "pl_" p) (for-each (lambda (typ) (display (case typ ((integer?) "i") ((boolean?) "b") ((real?) "r") (else "t")) p)) sig)))) (for-each (lambda (sigc) (let ((sig (car sigc))) (hey (sig-name sig)) (hey ", "))) signatures) (hey "pl_unused;~%") (hey " s_boolean = s7_make_symbol(s7, \"boolean?\");~%") (hey " s_integer = s7_make_symbol(s7, \"integer?\");~%") (hey " s_real = s7_make_symbol(s7, \"real?\");~%") (hey " s_any = s7_t(s7);~%~%") (for-each (lambda (sigc) (let ((sig (car sigc))) (hey " ") (hey (sig-name sig)) (hey " = s7_make_circular_signature(s7, ") (let ((len (length sig))) (hey (number->string (- len 1))) (hey ", ") (hey (number->string len)) (hey ", ") (do ((i 0 (+ i 1)) (s sig (cdr s))) ((= i len)) (let ((typ (car s))) (hey (case typ ((integer?) "s_integer") ((boolean?) "s_boolean") ((real?) "s_real") (else "s_any")))) (if (< i (- len 1)) (hey ", ")))) (hey ");~%"))) signatures) (hey "pl_unused = NULL;~%") (hey "#endif~%~%") (hey "#if HAVE_SCHEME~%") (hey " #define gl_define_procedure(Name, Value, A1, A2, A3, Help, Sig) s7_define_typed_function(s7, XL_PRE #Name XL_POST, Value, A1, A2, A3, Help, Sig)~%") (hey "#else~%") (hey " #define gl_define_procedure(Name, Value, A1, A2, A3, Help, Sig) Xen_define_safe_procedure(XL_PRE #Name XL_POST, Value, A1, A2, A3, Help)~%") (hey "#endif~%") (hey "~%") (define (defun func) (let* ((cargs (length (caddr func))) (name (car func)) (refargs (+ (ref-args (caddr func)) (opt-args (caddr func)))) (args (- cargs refargs))) (check-glu name) (if (member name glu-1-2) (hey "#ifdef GLU_VERSION_1_2~%")) (hey " gl_define_procedure(~A, gxg_~A_w, ~D, ~D, ~D, H_~A, ~A);~%" (car func) (car func) (if (>= cargs max-args) 0 args) (if (>= cargs max-args) 0 refargs) ; optional ignored (if (>= cargs max-args) 1 0) (car func) (sig-name (make-signature func))) (if (member (car func) glu-1-2) (hey "#endif~%")) )) (hey "#if USE_MOTIF~%") (for-each defun (reverse x-funcs)) (hey "#endif~%") (for-each defun (reverse funcs)) (uncheck-glu) (hey "}~%~%") (hey "/* ---------------------------------------- constants ---------------------------------------- */~%~%") (hey "static void define_integers(void)~%") (hey "{~%~%") (hey "#define DEFINE_INTEGER(Name) Xen_define(XL_PRE #Name XL_POST, C_int_to_Xen_integer(Name))~%") (hey "~%") (hey "#if USE_MOTIF~%") (for-each (lambda (val) (hey " DEFINE_INTEGER(~A);~%" val)) (reverse x-ints)) (hey "#endif~%") (for-each (lambda (val) (if in-glu (if (not (string=? "GLU" (substring val 0 3))) (begin (set! in-glu #f) (hey "#endif~%"))) (if (string=? "GLU" (substring val 0 3)) (begin (set! in-glu #t) (hey "#if HAVE_GLU~%")))) (hey " DEFINE_INTEGER(~A);~%" val)) (reverse ints)) (if in-glu (begin (hey "#endif~%") (set! in-glu #f))) (hey "}~%~%") (hey "/* -------------------------------- initialization -------------------------------- */~%~%") (hey "static bool gl_already_inited = false;~%~%") (hey "void Init_libgl(void);~%") (hey "void Init_libgl(void)~%") (hey "{~%") (hey " if (!gl_already_inited)~%") (hey " {~%") (hey " define_integers();~%") (hey " define_functions();~%") (hey " Xen_provide_feature(\"gl\");~%") (hey " Xen_define(\"gl-version\", C_string_to_Xen_string(\"~A\"));~%" (strftime "%d-%b-%y" (localtime (current-time)))) (hey " gl_already_inited = true;~%") (hey " }~%") (hey "}~%") (hey "#else~%") (hey " void Init_libgl(void);~%") (hey " void Init_libgl(void)~%") (hey "{~%") (hey "}~%") (hey "#endif~%") (close-output-port gl-file) (exit) snd-16.1/tools/sed.scm0000644000076400007640000000077712426010477012770 0ustar bilbil (define (sed in-file out-file source-text dest-text) (let ((source-len (length source-text))) (call-with-output-file out-file (lambda (p) (call-with-input-file in-file (lambda (file) (let loop ((line (read-line file))) (or (eof-object? line) (let ((pos (string-position source-text line))) (if pos (format p "~A~A~A~%" (substring line 0 pos) dest-text (substring line (+ pos source-len))) (format p "~A~%" line)) (loop (read-line file))))))))) (exit))) snd-16.1/tools/tauto.scm0000644000076400007640000001704612623430031013335 0ustar bilbil(set! (hook-functions *unbound-variable-hook*) ()) (set! (*s7* 'print-length) 6) ;(set! (*s7* 'gc-stats) #t) (if (provided? 'snd) (begin (format *stderr* "this won't work in Snd!~%") ; see t705.scm (exit))) ;(load "stuff.scm") ;(load "r7rs.scm") (require mockery.scm) (define max-args 3) (define-constant one 1) (define mock-number (*mock-number* 'mock-number)) (define mock-pair (*mock-pair* 'mock-pair)) (define mock-string (*mock-string* 'mock-string)) (define mock-char (*mock-char* 'mock-char)) (define mock-vector (*mock-vector* 'mock-vector)) (define mock-symbol (*mock-symbol* 'mock-symbol)) (define mock-hash-table* (*mock-hash-table* 'mock-hash-table*)) (define np (list 0 1 2 3 4)) (define mp (mock-pair '(0 1 2 3 4))) (define nv (vector 0 1 2 3 4)) (define mv (mock-vector 0 1 2 3 4)) (define ns "01234") (define ms (mock-string #\0 #\1 #\2 #\3 #\4)) ;(define value 1) ; this causes an infinite loop somewhere ;(openlet (inlet 'i 0 'list-set! (lambda (l . args) (apply #_list-set! l ((car args) 'i) (cdr args)))))) (define-constant constants (list #f #t () #\a (/ most-positive-fixnum) (/ -1 most-positive-fixnum) 1.5+i "hi455" :key hi: 'hi (list 1) (list 1 2) (cons 1 2) (list (list 1 2)) (list (list 1)) (list ()) #() 1/0+i 0+0/0i 0+1/0i 1+0/0i 0/0+0i 0/0+0/0i 1+1/0i 0/0+i cons ''2 1+i 1+1e10i 1e15+1e15i 0+1e18i 1e18 (integer->char 255) (string (integer->char 255)) 1e308 most-positive-fixnum most-negative-fixnum (- most-positive-fixnum 1) (+ most-negative-fixnum 1) -1 0 0.0 1 1.5 1.0-1.0i 3/4 #\null -63 (make-hash-table) (hash-table '(a . 2) '(b . 3)) '((1 2) (3 4)) '((1 (2)) (((3) 4))) "" (list #(1) "1") '(1 2 . 3) (list (cons 'a 2) (cons 'b 3)) #(1 2) (vector 1 '(3)) (let ((x 3)) (lambda (y) (+ x y))) abs 'a 'b one (lambda args args) (lambda* ((a 3) (b 2)) (+ a b)) (lambda () 3) (sublet () 'a 1) (rootlet) *load-hook* *error-hook* (random-state 123) quasiquote macroexpand begin let letrec* if case cond (call-with-exit (lambda (goto) goto)) (with-baffle (call/cc (lambda (cc) cc))) (string #\a #\null #\b) #2d((1 2) (3 4)) (inlet 'a 2 'b 3) # # (make-int-vector 3 0) (make-float-vector 3 -1.4) (make-vector '(2 3) "hi") #("hiho" "hi" "hoho") (make-shared-vector (make-int-vector '(2 3) 1) '(6)) (make-shared-vector (make-shared-vector (make-float-vector '(2 3) 1.0) '(6)) '(2 2)) (vector-ref #2d((#(1 2 3)) (#(3 4 5))) 0 0) (define-macro (m a) `(+ ,a 1)) (c-pointer 0) (c-pointer -1) :readable :else (define-bacro* (m (a 1)) `(+ ,a 1)) (byte-vector 0 1 2) (byte-vector) (byte-vector 255 0 127) (make-iterator (vector '(a . 2))) (lambda (dir) 1.0) (float-vector) (make-float-vector '(2 32)) '((a . 1)) #(1) '((((A . B) C . D) (E . F) G . H) ((I . J) K . L) (M . N) O . P) (mock-number 0) (mock-number 1-i) (mock-number 4/3) (mock-number 2.0) (mock-string #\h #\o #\h #\o) (mock-pair '(2 3 4)) (mock-char #\b) (mock-symbol 'c) (mock-vector 1 2 3 4) (mock-hash-table* 'b 2) np mp nv mv ns ms (gensym) )) (define car-constants (car constants)) (define-constant cdr-constants (cdr constants)) (define low 0) (define-constant arglists (vector (make-list 1) (make-list 2) (make-list 3) (make-list 4) (make-list 5) (make-list 6))) (define-constant (autotest func args args-now args-left sig) ;; args-left is at least 1, args-now starts at 0, args starts at () ;; (format *stderr* "~A: ~D ~D (~D ~D): ~A~%" func (length args) args-now low args-left args) ;(if (pair? args) (format *stderr* "~A " (car args))) (call-with-exit (lambda (quit) (if (>= args-now low) (catch #t (lambda () ;(format *stderr* "args: ~A~%" args) (apply func args)) (lambda any (if (and (positive? args-now) (memq (car any) '(wrong-type-arg wrong-number-of-args syntax-error))) (quit))))) (let ((c-args (vector-ref arglists args-now))) (copy args c-args) (let ((p (list-tail c-args args-now))) (if (= args-left 1) (call-with-exit (lambda (quit) (set-car! p car-constants) (catch #t (lambda () (apply func c-args)) (lambda any (if (and (memq (car any) '(wrong-type-arg wrong-number-of-args syntax-error)) (pair? (cdadr any)) (pair? (cddadr any)) (integer? (caddr (cadr any))) ; if just 1 arg, arg num can be omitted (< (caddr (cadr any)) low)) (quit)))) (let ((checker (and (pair? sig) (car sig)))) (if checker (for-each (lambda (c) (when (checker c) (catch #t (lambda () (set-car! p c) (apply func c-args)) (lambda any 'error)))) cdr-constants) (for-each (lambda (c) (catch #t (lambda () (set-car! p c) (apply func c-args)) (lambda any 'error))) cdr-constants))))) (let ((checker (and (pair? sig) (car sig)))) (if checker (for-each (lambda (c) (when (checker c) (set-car! p c) (autotest func c-args (+ args-now 1) (- args-left 1) (if (pair? sig) (cdr sig) ())))) constants) (for-each (lambda (c) (set-car! p c) (autotest func c-args (+ args-now 1) (- args-left 1) (if (pair? sig) (cdr sig) ()))) constants))))))))) (define safe-fill! (let ((signature '(#t sequence? #t))) (lambda (obj arg) (if (not (let? obj)) (fill! obj arg))))) (define (map-values lst) (if (or (not (pair? lst)) (not (car lst)) (procedure? (car lst))) lst (begin (if (symbol? (car lst)) (set-car! lst (symbol->value (car lst))) (if (pair? (car lst)) (set-car! lst (apply lambda '(x) `((or (,(caar lst) x) (,(cadar lst) x))))) (set-car! lst #f))) (map-values (cdr lst))))) (define baddies '(exit emergency-exit abort autotest all delete-file system set-cdr! stacktrace test-sym cutlet varlet gc cond-expand reader-cond openlet coverlet eval vector list cons hash-table* hash-table values throw symbol-table load global-environment current-environment make-procedure-with-setter procedure-with-setter? make-rectangular copy fill! hash-table-set! vector-set! let-set! hash-table-size mock-number mock-pair mock-string mock-char mock-vector mock-symbol mock-port mock-hash-table m *mock-number* *mock-pair* *mock-string* *mock-char* *mock-vector* *mock-symbol* *mock-port* *mock-hash-table* c-define-1 apropos map-values ;set-current-output-port outlet-member make-method make-object)) (define (test-sym sym) (if (and (not (memq sym baddies)) (defined? sym)) (let ((f (symbol->value sym))) (let ((argn (and (or (procedure? f) (let? f)) (arity f)))) (if argn (let ((bottom (car argn)) (top (min (cdr argn) max-args)) (strname (symbol->string sym))) (if (not (memq (strname 0) '(#\{ #\[ #\())) (begin (if (< top bottom) (format *stderr* ";~A (bottom: ~A, top: ~A)...~%" sym bottom top)) ;(format *stderr* ";~A...~%" sym) (set! low bottom) (if (positive? (cdr argn)) (let ((sig (if (eq? sym 'append) (let ((lst (list 'list?))) (set-cdr! lst lst)) (copy (procedure-signature f))))) (map-values sig) (autotest f () 0 top (if (pair? sig) (cdr sig) ())))))))))))) (define (all) (let ((st (symbol-table))) (for-each test-sym st) ;(do ((i 0 (+ i 1)) (len (length st))) ((= i 1000)) (test-sym (st (random len)))) ;(test-sym 'object->string) ;(test-sym 'for-each) (format *stderr* "~%all done~%") (s7-version) )) ;(test-sym 'write) (all) (exit) snd-16.1/tools/make-snd-diffs0000755000076400007640000000361512306421674014223 0ustar bilbil#!/usr/bin/env ruby -w # make-snd-diffs -- create snd-diffs and patch them in new snd path # make-snd-diffs --patch --snd-path "./test-snd" require "getoptlong" require "ftools" file = File.basename(__FILE__, ".rb") diff = false patch = false diff_path = "./snd-diffs" snd_path = "./new-snd" help = false GetoptLong.new(["--diff", "-d", GetoptLong::NO_ARGUMENT], ["--patch", "-p", GetoptLong::NO_ARGUMENT], ["--diff-path", "-D", GetoptLong::REQUIRED_ARGUMENT], ["--snd-path", "-P", GetoptLong::REQUIRED_ARGUMENT], ["--help", "-h", GetoptLong::NO_ARGUMENT]).each do |name, arg| case name when "--diff" diff = true when "--patch" patch = true when "--diff-path" diff_path = arg when "--snd-path" snd_path = arg when "--help" help = true end end if help || !(diff || patch) puts "Usage: #{file} [ options ] -d, --diff create diffs -p, --patch patch diffs -D, --diff-path PATH diffs path (#{diff_path}) -P, --snd-path PATH snd path (#{snd_path}) -h, --help display this help message and exit" exit 0 end unless File.directory?(diff_path = File.expand_path(diff_path)) puts "path #{diff_path} does not exist!" exit 1 end unless File.directory?(snd_path = File.expand_path(snd_path)) puts "path #{snd_path} does not exist!" exit 1 end if diff File.makedirs(diff_path, true) Dir["#{diff_path}/*.diff"].each do |f| File.unlink(f) end Dir.chdir(snd_path) Dir["*.orig"].each do |orig| new = File.basename(orig, ".orig") system("diff --context=5 #{orig} #{new} > #{new}.diff") end elsif patch dirs = Dir["#{diff_path}/*.diff"] Dir.chdir(snd_path) # patch defaults to --fuzz=2 # one hunk to xm.c has problems with --fuzz=2 resp. 3 dirs.each do |patch| system("patch --silent --fuzz=4 -i #{patch}") end end # make-snd-diffs ends here snd-16.1/tools/testsnd0000755000076400007640000002735312626144465013131 0ustar bilbil#!/bin/csh -f cp tools/ffitest.c . echo ' -------------------------------- without-gui -------------------------------- ' rm -f snd rm -f config.cache ./configure --quiet CFLAGS="-Wall -I/usr/local/include" --without-gui make echo ' ' echo ' ' ./snd --version ./snd -l snd-test echo ' ' echo ' ' echo ' -------------------------------- that was snd-test without-gui (also s7test) -------------------------------- ' echo ' ' echo ' ' ./snd -noinit s7test.scm ./snd lint.scm -e '(begin (lint "s7test.scm" #f) (exit))' valgrind ./snd -noinit -l snd-test echo ' ' echo ' ' echo ' -------------------------------- that was valgrind without-gui (also s7test) -------------------------------- ' echo ' ' echo ' ' gcc s7.c -o repl -DWITH_MAIN -DUSE_SND=0 -I. -O2 -g -Wl,-export-dynamic -ldl -lm ./repl tools/tauto.scm echo ' ' echo ' ' echo ' -------------------------------- that was s7 tauto -------------------------------- ' echo ' ' echo ' ' echo ' -------------------------------- without-gui sanitized -------------------------------- ' rm -f snd rm -f config.cache ./configure --quiet CFLAGS="-g3 -Wall -I/usr/local/include -Wbool-compare -Wsign-compare -fsanitize=bounds -fsanitize=address -fsanitize=undefined" --without-gui make echo ' ' echo ' ' ./snd --version ./snd s7test.scm ./snd -l snd-test echo ' ' echo ' ' echo ' -------------------------------- that was snd-test without-gui sanitized?? -------------------------------- ' echo ' ' echo ' ' echo ' -------------------------------- without-gui DEBUGGING=1 -------------------------------- ' make allclean rm -f snd rm -f config.cache ./configure --quiet CFLAGS="-Wall -I/usr/local/include -DDEBUGGING" --without-gui --disable-deprecated make echo ' ' echo ' ' ./snd --version ./snd -l snd-test ./snd lint.scm -e '(begin (lint "s7test.scm" #f) (exit))' cp s7test.scm tmptest.scm ./snd tools/sed.scm -e '(sed "tmptest.scm" "tmp" "(define full-test #f)" "(define full-test #t)")' mv tmp tmptest.scm ./snd tmptest.scm echo ' ' echo ' ' echo ' -------------------------------- that was snd-test without-gui debugging disable deprecated -------------------------------- ' echo ' ' echo ' ' echo ' -------------------------------- pure-s7 -------------------------------- ' make allclean rm -f snd rm -f config.cache ./configure --quiet CFLAGS="-Wall -I/usr/local/include -DWITH_PURE_S7=1" --without-gui --disable-deprecated make echo ' ' echo ' ' ./snd --version ./snd -l snd-test echo ' ' echo ' ' echo ' -------------------------------- that was snd-test pure-s7 -------------------------------- ' echo ' ' echo ' ' echo ' -------------------------------- no opt -------------------------------- ' make allclean rm -f snd rm -f config.cache ./configure --quiet CFLAGS="-Wall -I/usr/local/include -DWITH_OPTIMIZATION=0" --without-gui --disable-deprecated make echo ' ' echo ' ' ./snd --version ./snd -l snd-test echo ' ' echo ' ' echo ' -------------------------------- that was snd-test without optimization -------------------------------- ' echo ' ' echo ' ' echo ' -------------------------------- no choosers -------------------------------- ' make allclean rm -f snd rm -f config.cache ./configure --quiet CFLAGS="-Wall -I/usr/local/include -DWITHOUT_CHOOSERS=1" --without-gui --disable-deprecated make echo ' ' echo ' ' ./snd --version ./snd -l snd-test echo ' ' echo ' ' echo ' -------------------------------- that was snd-test without choosers -------------------------------- ' echo ' ' echo ' ' echo ' -------------------------------- without-gui CC=g++ --disable-deprecated -------------------------------- ' make allclean rm -f snd rm -f config.cache ./configure --quiet CFLAGS="-Wall -DWITH_EXTRA_EXPONENT_MARKERS=1 -DWITH_QUASIQUOTE_VECTOR=1" --without-gui --disable-deprecated CC=g++ make echo ' ' echo ' ' ./snd --version ./snd -l snd-test echo ' ' echo ' ' echo ' -------------------------------- that was snd-test g++/disable-deprecated -------------------------------- ' echo ' ' echo ' ' valgrind ./snd -l snd-test echo ' ' echo ' ' echo ' -------------------------------- that was valgrind g++ -------------------------------- ' echo ' ' echo ' ' echo ' -------------------------------- without-gui --with-gmp -------------------------------- ' make allclean rm -f snd rm -f config.cache ./configure --quiet CFLAGS="-Wall" --without-gui --with-gmp --disable-deprecated make echo ' ' echo ' ' ./snd --version ./snd -l snd-test echo ' ' echo ' ' echo ' -------------------------------- that was snd-test --with-gmp -------------------------------- ' echo ' ' echo ' ' # valgrind ./snd -l snd-test # echo ' ' # echo ' ' # echo ' -------------------------------- that was valgrind --with-gmp -------------------------------- ' # echo ' ' # echo ' ' # gcc s7.c -o repl -DWITH_MAIN -I. -O2 -g -Wl,-export-dynamic -ldl -lm -lgmp -lmpfr -lmpc # ./repl tools/tauto.scm echo ' -------------------------------- without-gui --with-gmp debugging -------------------------------- ' make allclean rm -f snd rm -f config.cache ./configure --quiet CFLAGS="-Wall -DDEBUGGING=1" --without-gui --with-gmp --disable-deprecated make echo ' ' echo ' ' ./snd --version ./snd -l snd-test echo ' ' echo ' ' echo ' -------------------------------- that was snd-test --with-gmp debugging -------------------------------- ' echo ' ' echo ' ' echo ' -------------------------------- motif -------------------------------- ' make allclean rm -f snd rm -f config.cache ./configure --quiet --with-motif CFLAGS="-Wall -I/usr/X11R6/include" LDFLAGS="-L/usr/X11R6/lib" make echo ' ' echo ' ' ./snd --version ./snd -l snd-test 23 ./snd -noinit -l snd-test make clmclean make sndinfo ./sndinfo oboe.snd make sndplay ./sndplay oboe.snd echo ' ' echo ' ' echo ' -------------------------------- that was motif? and test 23 -------------------------------- ' echo ' ' echo ' ' valgrind ./snd -l snd-test echo ' ' echo ' ' echo ' -------------------------------- that was valgrind --with-motif? -------------------------------- ' echo ' ' echo ' ' echo ' -------------------------------- motif + gl -------------------------------- ' make allclean rm -f snd rm -f config.cache ./configure --quiet --with-gl --with-motif CFLAGS="-Wall -I/usr/X11R6/include" LDFLAGS="-L/usr/X11R6/lib" make echo ' ' echo ' ' ./snd --version ./snd -l snd-test 24 ./snd -l snd-test echo ' ' echo ' ' echo ' -------------------------------- that was motif? and gl -------------------------------- ' echo ' ' echo ' ' valgrind ./snd -l snd-test echo ' ' echo ' ' echo ' -------------------------------- that was valgrind --with-motif and gl -------------------------------- ' echo ' ' echo ' ' echo ' -------------------------------- motif + gl + debug -------------------------------- ' make allclean rm -f snd rm -f config.cache ./configure --quiet --with-gl --with-motif CFLAGS="-DDEBUGGING -Wall -I/usr/X11R6/include" LDFLAGS="-L/usr/X11R6/lib" make echo ' ' echo ' ' ./snd --version ./snd -l snd-test 24 ./snd -l snd-test echo ' ' echo ' ' echo ' -------------------------------- that was motif? and gl and debugging -------------------------------- ' echo ' ' echo ' ' make allclean rm -f snd rm -f config.cache ./configure --without-gui --quiet CC=/home/bil/test/llvm-3.1.src/build/Release+Asserts/bin/clang CFLAGS="-Wall" LDFLAGS="-Wl,-export-dynamic" make ./snd --version ./snd -l snd-test echo ' ' echo ' ' echo ' -------------------------------- that was clang? -------------------------------- ' echo ' ' echo ' ' echo ' -------------------------------- with-gtk -------------------------------- ' make allclean rm -f snd rm -f config.cache ./configure --quiet CFLAGS="-Wall" --with-gtk --disable-deprecated make echo ' ' echo ' ' ./snd --version ./snd tools/va.scm ./snd -noinit -l snd-test echo ' ' echo ' ' echo ' -------------------------------- that was snd-test --with-gtk -------------------------------- ' echo ' ' echo ' ' # echo ' -------------------------------- valgrind --with-gtk takes forever! -------------------------------- ' # valgrind ./snd -l snd-test # echo ' ' # echo ' ' # echo ' -------------------------------- that was valgrind --with-gtk -------------------------------- ' # echo ' ' # echo ' ' echo ' -------------------------------- with-gtk + debug -------------------------------- ' make allclean rm -f snd rm -f config.cache ./configure --quiet CFLAGS="-DDEBUGGING -Wall" --with-gtk --disable-deprecated make echo ' ' echo ' ' ./snd -l snd-test echo ' ' echo ' ' echo ' -------------------------------- that was snd-test --with-gtk + debug -------------------------------- ' echo ' ' echo ' ' cp snd-test.scm orig-snd-test.scm ./snd tools/sed.scm -e '(sed "snd-test.scm" "tmp" "(define tests 1)" "(define tests 5)")' # sed snd-test.scm -e 's/(define tests 1)/(define tests 5)/g' > tmp # sed differs so much between systems that it is useless mv tmp snd-test.scm echo ' -------------------------------- without-gui -------------------------------- ' make allclean rm -f snd rm -f config.cache ./configure --quiet CFLAGS="-Wall" --without-gui make echo ' ' echo ' ' ./snd --version ./snd -l snd-test echo ' ' echo ' ' echo ' -------------------------------- that was snd-test mult without-gui -------------------------------- ' echo ' ' echo ' ' valgrind ./snd -l snd-test echo ' ' echo ' ' echo ' -------------------------------- that was valgrind mult -------------------------------- ' echo ' ' echo ' ' cp orig-snd-test.scm snd-test.scm ./snd tools/sed.scm -e '(sed "snd-test.scm" "tmp" "(define test-at-random 0)" "(define test-at-random 100)")' # sed snd-test.scm -e 's/(define test-at-random 0)/(define test-at-random 100)/g' > tmp mv tmp snd-test.scm echo ' ' echo ' ' ./snd --version ./snd -l snd-test echo ' ' echo ' ' echo ' -------------------------------- that was snd-test at-random without-gui -------------------------------- ' echo ' ' echo ' ' valgrind ./snd -l snd-test echo ' ' echo ' ' echo ' -------------------------------- that was valgrind at-random -------------------------------- ' echo ' ' echo ' ' cp orig-snd-test.scm snd-test.scm ./snd tools/sed.scm -e '(sed "snd-test.scm" "tmp" "(define all-args #f)" "(define all-args #t)")' # sed snd-test.scm -e 's/(define all-args #f)/(define all-args #t)/g' > tmp mv tmp snd-test.scm echo ' ' echo ' ' ./snd --version ./snd -l snd-test echo ' ' echo ' ' echo ' -------------------------------- that was snd-test full without-gui -------------------------------- ' echo ' ' echo ' ' valgrind ./snd -l snd-test echo ' ' echo ' ' echo ' -------------------------------- that was valgrind full -------------------------------- ' echo ' ' echo ' ' make allclean rm -f snd rm -f config.cache ./configure --quiet CFLAGS="-Wall" CC=g++ make echo ' ' echo ' ' ./snd --version ./snd -l snd-test echo ' ' echo ' ' echo ' -------------------------------- that was snd-test full g++ -------------------------------- ' echo ' ' echo ' ' make allclean rm -f snd rm -f config.cache ./configure --quiet CFLAGS="-Wall" --with-gtk --with-ladspa --without-audio make echo ' ' echo ' ' ./snd --version ./snd -l snd-test echo ' ' echo ' ' echo ' -------------------------------- that was snd-test full gtk ladspa-------------------------------- ' echo ' ' echo ' ' make allclean rm -f snd rm -f config.cache ./configure --quiet CFLAGS="-Wall" --with-gmp --without-gui make echo ' ' echo ' ' ./snd --version ./snd -l snd-test echo ' ' echo ' ' echo ' -------------------------------- that was snd-test full gmp -------------------------------- ' echo ' ' echo ' ' ./snd tools/sed.scm -e '(sed "snd-test.scm" "tmp" "(define tests 1)" "(define tests 7)")' # sed snd-test.scm -e 's/(define tests 1)/(define tests 7)/g' > tmp mv tmp snd-test.scm make allclean rm -f snd rm -f config.cache ./configure --quiet CFLAGS="-Wall" --without-gui make echo ' ' echo ' ' ./snd -l snd-test echo ' ' echo ' ' echo ' -------------------------------- that was snd-test full mult no-gui -------------------------------- ' echo ' ' echo ' ' cp orig-snd-test.scm snd-test.scm snd-16.1/tools/ffitest.c0000644000076400007640000015572312562176543013333 0ustar bilbil/* s7 ffi tester * * gcc -o ffitest ffitest.c -g3 -Wall s7.o -lm -I. -ldl */ #include #include #include #include #include "s7.h" #define TO_STR(x) s7_object_to_c_string(sc, x) #define TO_S7_INT(x) s7_make_integer(sc, x) static s7_pointer a_function(s7_scheme *sc, s7_pointer args) { return(s7_car(args)); } static s7_pointer test_hook_function(s7_scheme *sc, s7_pointer args) { s7_pointer val; val = s7_symbol_local_value(sc, s7_make_symbol(sc, "a"), s7_car(args)); if ((!s7_is_integer(val)) || (s7_integer(val) != 1)) { char *s1; s1 = TO_STR(val); fprintf(stderr, "%d: (hook 'a) is %s\n", __LINE__, s1); free(s1); } return(val); } static char last_c; static void my_print(s7_scheme *sc, unsigned char c, s7_pointer port) { last_c = c; } static s7_pointer my_read(s7_scheme *sc, s7_read_t peek, s7_pointer port) { return(s7_make_character(sc, '0')); } static bool tested_begin_hook = false; static void test_begin_hook(s7_scheme *sc, bool *val) { tested_begin_hook = true; } static s7_pointer test_error_handler(s7_scheme *sc, s7_pointer args) { s7_display(sc, s7_make_symbol(sc, "error!"), s7_current_error_port(sc)); return(s7_f(sc)); } static s7_pointer set_sym, set_val; static s7_pointer scheme_set_notification(s7_scheme *sc, s7_pointer args) { set_sym = s7_car(args); set_val = s7_cadr(args); return(set_val); } typedef struct { s7_double x; s7_pointer data; } dax; static char *print_dax(s7_scheme *sc, void *val) { char *data_str, *str; int data_str_len; dax *o = (dax *)val; data_str = s7_object_to_c_string(sc, o->data); data_str_len = strlen(data_str); str = (char *)calloc(data_str_len + 32, sizeof(char)); snprintf(str, data_str_len + 32, "#", o->x, data_str); free(data_str); return(str); } static void free_dax(void *val) { if (val) free(val); } static bool equal_dax(void *val1, void *val2) { return(val1 == val2); } static void mark_dax(void *val) { dax *o = (dax *)val; if (o) s7_mark_object(o->data); } static int dax_type_tag = 0; static s7_pointer make_dax(s7_scheme *sc, s7_pointer args) { dax *o; o = (dax *)malloc(sizeof(dax)); o->x = s7_real(s7_car(args)); if (s7_cdr(args) != s7_nil(sc)) o->data = s7_car(s7_cdr(args)); else o->data = s7_nil(sc); return(s7_make_object(sc, dax_type_tag, (void *)o)); } static s7_pointer is_dax(s7_scheme *sc, s7_pointer args) { return(s7_make_boolean(sc, s7_is_object(s7_car(args)) && s7_object_type(s7_car(args)) == dax_type_tag)); } static s7_pointer dax_x(s7_scheme *sc, s7_pointer args) { dax *o; o = (dax *)s7_object_value(s7_car(args)); return(s7_make_real(sc, o->x)); } static s7_pointer set_dax_x(s7_scheme *sc, s7_pointer args) { dax *o; o = (dax *)s7_object_value(s7_car(args)); o->x = s7_real(s7_car(s7_cdr(args))); return(s7_car(s7_cdr(args))); } static s7_pointer dax_data(s7_scheme *sc, s7_pointer args) { dax *o; o = (dax *)s7_object_value(s7_car(args)); return(o->data); } static s7_pointer set_dax_data(s7_scheme *sc, s7_pointer args) { dax *o; o = (dax *)s7_object_value(s7_car(args)); o->data = s7_car(s7_cdr(args)); return(o->data); } static s7_pointer plus(s7_scheme *sc, s7_pointer args) { /* (define* (plus (red 32) blue) (+ (* 2 red) blue)) */ return(TO_S7_INT(2 * s7_integer(s7_car(args)) + s7_integer(s7_car(s7_cdr(args))))); } static s7_pointer mac_plus(s7_scheme *sc, s7_pointer args) { /* (define-macro (plus a b) `(+ ,a ,b)) */ s7_pointer a, b; a = s7_car(args); b = s7_cadr(args); return(s7_list(sc, 3, s7_make_symbol(sc, "+"), a, b)); } static s7_pointer mac_plus_mv(s7_scheme *sc, s7_pointer args) { /* (define-macro (plus-mv a b) (values `(define a ,a) `(define b ,b))) */ return(s7_values(sc, args)); } static s7_pointer open_plus(s7_scheme *sc, s7_pointer args) { #define plus_help "(plus obj ...) applies obj's plus method to obj and any trailing arguments." s7_pointer obj, method; obj = s7_car(args); if (s7_is_openlet(obj)) { method = s7_method(sc, obj, s7_make_symbol(sc, "plus")); if (s7_is_procedure(method)) return(s7_apply_function(sc, method, s7_cdr(args))); } return(s7_f(sc)); } static s7_pointer multivector_ref(s7_scheme *sc, s7_pointer vector, int indices, ...) { /* multivector_ref returns an element of a multidimensional vector */ int ndims; ndims = s7_vector_rank(vector); if (ndims == indices) { va_list ap; s7_int index = 0; va_start(ap, indices); if (ndims == 1) { index = va_arg(ap, s7_int); va_end(ap); return(s7_vector_ref(sc, vector, index)); } else { int i; s7_pointer *elements; s7_int *offsets, *dimensions; elements = s7_vector_elements(vector); dimensions = s7_vector_dimensions(vector); offsets = s7_vector_offsets(vector); for (i = 0; i < indices; i++) { int ind; ind = va_arg(ap, int); if ((ind < 0) || (ind >= dimensions[i])) { va_end(ap); return(s7_out_of_range_error(sc, "multivector_ref", i, s7_make_integer(sc, ind), "index should be between 0 and the dimension size")); } index += (ind * offsets[i]); } va_end(ap); return(elements[index]); } } return(s7_wrong_number_of_args_error(sc, "multivector_ref: wrong number of indices: ~A", s7_make_integer(sc, indices))); } typedef struct { size_t size; double *data; } g_block; static int g_block_type = 0; static s7_pointer g_block_methods; static s7_pointer g_make_block(s7_scheme *sc, s7_pointer args) { #define g_make_block_help "(make-block size) returns a new block of the given size" g_block *g; s7_pointer new_g; g = (g_block *)calloc(1, sizeof(g_block)); g->size = (size_t)s7_integer(s7_car(args)); g->data = (double *)calloc(g->size, sizeof(double)); new_g = s7_make_object(sc, g_block_type, (void *)g); s7_object_set_let(new_g, g_block_methods); s7_openlet(sc, new_g); return(new_g); } static s7_pointer g_to_block(s7_scheme *sc, s7_pointer args) { #define g_block_help "(block ...) returns a block object with the arguments as its contents." s7_pointer p, b; size_t i, len; g_block *gb; len = s7_list_length(sc, args); b = g_make_block(sc, s7_cons(sc, s7_make_integer(sc, len), s7_nil(sc))); gb = (g_block *)s7_object_value(b); for (i = 0, p = args; i < len; i++, p = s7_cdr(p)) gb->data[i] = s7_number_to_real(sc, s7_car(p)); return(b); } static char *g_block_display(s7_scheme *sc, void *value) { return(strdup("#")); } static void g_block_free(void *value) { g_block *g = (g_block *)value; free(g->data); free(g); } static bool g_block_is_equal(void *val1, void *val2) { return(val1 == val2); } static void g_block_mark(void *val) { /* nothing to mark */ } static s7_pointer g_block_ref(s7_scheme *sc, s7_pointer obj, s7_pointer args) { g_block *g = (g_block *)s7_object_value(obj); size_t index; index = (size_t)s7_integer(s7_car(args)); if (index < g->size) return(s7_make_real(sc, g->data[index])); return(s7_out_of_range_error(sc, "block-ref", 2, s7_car(args), "should be less than block length")); } static s7_pointer g_block_set(s7_scheme *sc, s7_pointer obj, s7_pointer args) { g_block *g = (g_block *)s7_object_value(obj); s7_int index; index = s7_integer(s7_car(args)); if ((index >= 0) && (index < g->size)) { g->data[index] = s7_number_to_real(sc, s7_cadr(args)); return(s7_cadr(args)); } return(s7_out_of_range_error(sc, "block-set", 2, s7_car(args), "should be less than block length")); } static s7_pointer g_block_length(s7_scheme *sc, s7_pointer obj) { g_block *g = (g_block *)s7_object_value(obj); return(s7_make_integer(sc, g->size)); } static s7_pointer g_block_copy(s7_scheme *sc, s7_pointer args) { s7_pointer obj, new_g; g_block *g, *g1; obj = s7_car(args); g = (g_block *)s7_object_value(obj); new_g = g_make_block(sc, s7_cons(sc, s7_make_integer(sc, g->size), s7_nil(sc))); g1 = (g_block *)s7_object_value(new_g); memcpy((void *)(g1->data), (void *)(g->data), g->size * sizeof(double)); return(new_g); } static s7_pointer g_block_reverse(s7_scheme *sc, s7_pointer obj) { size_t i, j; g_block *g = (g_block *)s7_object_value(obj); g_block *g1; s7_pointer new_g; new_g = g_make_block(sc, s7_cons(sc, s7_make_integer(sc, g->size), s7_nil(sc))); g1 = (g_block *)s7_object_value(new_g); for (i = 0, j = g->size - 1; i < g->size; i++, j--) g1->data[i] = g->data[j]; return(new_g); } static s7_pointer g_block_fill(s7_scheme *sc, s7_pointer args) { s7_pointer obj; size_t i; double fill_val; g_block *g; obj = s7_car(args); g = (g_block *)s7_object_value(obj); fill_val = s7_number_to_real(sc, s7_cadr(args)); for (i = 0; i < g->size; i++) g->data[i] = fill_val; return(obj); } int main(int argc, char **argv) { s7_scheme *sc; s7_pointer p, p1; int i, gc_loc; char *s1, *s2; sc = s7_init(); /* try each straight (no errors) case */ if (!s7_is_null(sc, s7_nil(sc))) {fprintf(stderr, "%d: %s is not null?\n", __LINE__, s1 = TO_STR(s7_nil(sc))); free(s1);} if (s7_is_pair(s7_nil(sc))) {fprintf(stderr, "%d: %s is a pair?\n", __LINE__, s1 = TO_STR(s7_nil(sc))); free(s1);} if (!s7_is_boolean(s7_t(sc))) {fprintf(stderr, "%d: %s is not boolean?\n", __LINE__, s1 = TO_STR(s7_t(sc))); free(s1);} if (!s7_is_boolean(s7_f(sc))) {fprintf(stderr, "%d: %s is not boolean?\n", __LINE__, s1 = TO_STR(s7_f(sc))); free(s1);} if (s7_boolean(sc, s7_f(sc))) {fprintf(stderr, "%d: %s is #t?\n", __LINE__, s1 = TO_STR(s7_f(sc))); free(s1);} if (!s7_boolean(sc, s7_t(sc))) {fprintf(stderr, "%d: %s is #f?\n", __LINE__, s1 = TO_STR(s7_t(sc))); free(s1);} p = s7_make_boolean(sc, true); if (p != s7_t(sc)) {fprintf(stderr, "%d: %s is not #t?\n", __LINE__, s1 = TO_STR(p)); free(s1);} p = s7_make_boolean(sc, false); if (p != s7_f(sc)) {fprintf(stderr, "%d: %s is not #f?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (!s7_is_eq(s7_f(sc), s7_f(sc))) {fprintf(stderr, "%d: (eq? %s %s) -> #f?\n", __LINE__, s1 = TO_STR(s7_f(sc)), s2 = TO_STR(s7_f(sc))); free(s1); free(s2);} if (!s7_is_eqv(s7_f(sc), s7_f(sc))) {fprintf(stderr, "%d: (eqv? %s %s) -> #f?\n", __LINE__, s1 = TO_STR(s7_f(sc)), s2 = TO_STR(s7_f(sc))); free(s1); free(s2);} if (!s7_is_equal(sc, s7_f(sc), s7_f(sc))) {fprintf(stderr, "%d: (equal? %s %s) -> #f?\n", __LINE__, s1 = TO_STR(s7_f(sc)), s2 = TO_STR(s7_f(sc))); free(s1); free(s2);} if (!s7_is_unspecified(sc, s7_unspecified(sc))) {fprintf(stderr, "%d: %s is not #?\n", __LINE__, s1 = TO_STR(s7_unspecified(sc))); free(s1);} if (s7_is_eq(s7_eof_object(sc), s7_undefined(sc))) {fprintf(stderr, "%d: (eq? %s %s) -> #t?\n", __LINE__, s1 = TO_STR(s7_eof_object(sc)), s2 = TO_STR(s7_undefined(sc))); free(s1); free(s2);} if (s7_is_eqv(s7_eof_object(sc), s7_undefined(sc))) {fprintf(stderr, "%d: (eqv? %s %s) -> #t?\n", __LINE__, s1 = TO_STR(s7_eof_object(sc)), s2 = TO_STR(s7_undefined(sc))); free(s1); free(s2);} if (s7_is_equal(sc, s7_eof_object(sc), s7_undefined(sc))) {fprintf(stderr, "%d: (equal? %s %s) -> #t?\n", __LINE__, s1 = TO_STR(s7_eof_object(sc)), s2 = TO_STR(s7_undefined(sc))); free(s1); free(s2);} if (!s7_is_valid(sc, s7_t(sc))) {fprintf(stderr, "%d: %s is not valid?\n", __LINE__, s1 = TO_STR(s7_t(sc))); free(s1);} if (s7_is_c_pointer(s7_t(sc))) {fprintf(stderr, "%d: %s is a raw c pointer?\n", __LINE__, s1 = TO_STR(s7_t(sc))); free(s1);} i = 32; p = s7_make_c_pointer(sc, (void *)(&i)); if (!s7_is_c_pointer(p)) {fprintf(stderr, "%d: %s is not a raw c pointer?\n", __LINE__, s1 = TO_STR(p)); free(s1);} i = (*((int *)s7_c_pointer(p))); if (i != 32) fprintf(stderr, "%d: 32 -> %d via raw c pointer?\n", __LINE__, i); s7_provide(sc, "ffitest"); if (!s7_is_provided(sc, "ffitest")) {fprintf(stderr, "%d: *features* %s doesn't provide 'ffitest?\n", __LINE__, s1 = TO_STR(s7_name_to_value(sc, "*features*"))); free(s1);} p = s7_cons(sc, s7_f(sc), s7_t(sc)); gc_loc = s7_gc_protect(sc, p); if (p != s7_gc_protected_at(sc, gc_loc)) {fprintf(stderr, "%d: %s is not gc protected at %d: %s?\n", __LINE__, s1 = TO_STR(p), gc_loc, s2 = TO_STR(s7_gc_protected_at(sc, gc_loc))); free(s1); free(s2);} if (s7_car(p) != s7_f(sc)) {fprintf(stderr, "%d: (car %s) is not #f?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_cdr(p) != s7_t(sc)) {fprintf(stderr, "%d: (cdr %s) is not #t?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (!s7_is_pair(p)) {fprintf(stderr, "%d: %s is not a pair?\n", __LINE__, s1 = TO_STR(p)); free(s1);} s7_set_car(p, s7_eof_object(sc)); if (s7_car(p) != s7_eof_object(sc)) {fprintf(stderr, "%d: (car %s) is not #?\n", __LINE__, s1 = TO_STR(p)); free(s1);} s7_set_cdr(p, s7_unspecified(sc)); if (s7_cdr(p) != s7_unspecified(sc)) {fprintf(stderr, "%d: (cdr %s) is not #?\n", __LINE__, s1 = TO_STR(p)); free(s1);} s7_gc_unprotect_at(sc, gc_loc); p = TO_S7_INT(123); gc_loc = s7_gc_protect(sc, p); if (!s7_is_integer(p)) {fprintf(stderr, "%d: %s is not integral?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (!s7_is_rational(p)) {fprintf(stderr, "%d: %s is not rational?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_is_ratio(p)) {fprintf(stderr, "%d: %s is a ratio?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (!s7_is_real(p)) {fprintf(stderr, "%d: %s is not real?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (!s7_is_complex(p)) {fprintf(stderr, "%d: %s is not complex?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (!s7_is_number(p)) {fprintf(stderr, "%d: %s is not complex?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_integer(p) != 123) {fprintf(stderr, "%d: %s is not 123?\n", __LINE__, s1 = TO_STR(p)); free(s1);} s2 = s7_number_to_string(sc, p, 10); if (strcmp(s2, "123") != 0) {fprintf(stderr, "%d: (number->string %s) is not \"123\"?\n", __LINE__, s1 = TO_STR(p)); free(s1);} free(s2); if (s7_number_to_integer(sc, p) != 123) {fprintf(stderr, "%d: s7_number_to_integer %s is not 123?\n", __LINE__, s1 = TO_STR(p)); free(s1);} s7_gc_unprotect_at(sc, gc_loc); p = s7_make_ratio(sc, 123, 5); gc_loc = s7_gc_protect(sc, p); if (s7_is_integer(p)) {fprintf(stderr, "%d: %s is integral?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (!s7_is_rational(p)) {fprintf(stderr, "%d: %s is not rational?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (!s7_is_ratio(p)) {fprintf(stderr, "%d: %s is not a ratio?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (!s7_is_real(p)) {fprintf(stderr, "%d: %s is not real?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (!s7_is_complex(p)) {fprintf(stderr, "%d: %s is not complex?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (!s7_is_number(p)) {fprintf(stderr, "%d: %s is not complex?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_numerator(p) != 123) {fprintf(stderr, "%d: (numerator %s) is not 123?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_denominator(p) != 5) {fprintf(stderr, "%d: (denominator %s) is not 5?\n", __LINE__, s1 = TO_STR(p)); free(s1);} s2 = s7_number_to_string(sc, p, 10); if (strcmp(s2, "123/5") != 0) {fprintf(stderr, "%d: (number->string %s) is not \"123/5\"?\n", __LINE__, s1 = TO_STR(p)); free(s1);} free(s2); s7_gc_unprotect_at(sc, gc_loc); p = s7_make_real(sc, 1.5); gc_loc = s7_gc_protect(sc, p); if (s7_is_integer(p)) {fprintf(stderr, "%d: %s is integral?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_is_rational(p)) {fprintf(stderr, "%d: %s is rational?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_is_ratio(p)) {fprintf(stderr, "%d: %s is a ratio?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (!s7_is_real(p)) {fprintf(stderr, "%d: %s is not real?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (!s7_is_complex(p)) {fprintf(stderr, "%d: %s is not complex?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (!s7_is_number(p)) {fprintf(stderr, "%d: %s is not complex?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_real(p) != 1.5) {fprintf(stderr, "%d: %s is not 1.5?\n", __LINE__, s1 = TO_STR(p)); free(s1);} s2 = s7_number_to_string(sc, p, 10); if (strcmp(s2, "1.5") != 0) {fprintf(stderr, "%d: (number->string %s) is not \"1.5\"?\n", __LINE__, s1 = TO_STR(p)); free(s1);} free(s2); if (s7_number_to_real(sc, p) != 1.5) {fprintf(stderr, "%d: s7_number_to_real %s is not 1.5?\n", __LINE__, s1 = TO_STR(p)); free(s1);} s7_gc_unprotect_at(sc, gc_loc); p = s7_make_complex(sc, 1.0, 1.0); gc_loc = s7_gc_protect(sc, p); if (s7_is_integer(p)) {fprintf(stderr, "%d: %s is integral?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_is_rational(p)) {fprintf(stderr, "%d: %s is rational?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_is_ratio(p)) {fprintf(stderr, "%d: %s is a ratio?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_is_real(p)) {fprintf(stderr, "%d: %s is real?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (!s7_is_complex(p)) {fprintf(stderr, "%d: %s is not complex?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (!s7_is_number(p)) {fprintf(stderr, "%d: %s is not complex?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_real_part(p) != 1.0) {fprintf(stderr, "%d: (real-part %s) is not 1.0?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_imag_part(p) != 1.0) {fprintf(stderr, "%d: (imag-part %s) is not 1.0?\n", __LINE__, s1 = TO_STR(p)); free(s1);} s2 = s7_number_to_string(sc, p, 10); if (strcmp(s2, "1+1i") != 0) {fprintf(stderr, "%d: (number->string %s) is not \"1+1i\"?\n", __LINE__, s1 = TO_STR(p)); free(s1);} free(s2); s7_gc_unprotect_at(sc, gc_loc); p = s7_rationalize(sc, 1.5, 1e-12); gc_loc = s7_gc_protect(sc, p); s1 = TO_STR(p); if (strcmp(s1, "3/2") != 0) fprintf(stderr, "%d: ratio is %s?\n", __LINE__, s1); free(s1); s7_gc_unprotect_at(sc, gc_loc); p = s7_make_vector(sc, 12); gc_loc = s7_gc_protect(sc, p); if (!s7_is_vector(p)) {fprintf(stderr, "%d: %s is not a vector?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_vector_rank(p) != 1) {fprintf(stderr, "%d: (dimensions %s) is not 1?\n", __LINE__, s1 = TO_STR(p)); free(s1);} s7_vector_set(sc, p, 1, s7_t(sc)); if (s7_vector_ref(sc, p, 1) != s7_t(sc)) {fprintf(stderr, "%d: (%s 1) is not #t?\n", __LINE__, s1 = TO_STR(p)); free(s1);} s7_vector_fill(sc, p, TO_S7_INT(123)); if (s7_integer(s7_vector_ref(sc, p, 1)) != 123) {fprintf(stderr, "%d: (%s 1) is not 123?\n", __LINE__, s1 = TO_STR(p)); free(s1);} s7_gc_unprotect_at(sc, gc_loc); p = s7_make_and_fill_vector(sc, 3, TO_S7_INT(3)); gc_loc = s7_gc_protect(sc, p); if (s7_integer(s7_vector_ref(sc, p, 1)) != 3) {fprintf(stderr, "%d: (%s 1) is not 3?\n", __LINE__, s1 = TO_STR(p)); free(s1);} p1 = s7_vector_copy(sc, p); if ((p == p1) || (!s7_is_vector(p1))) {fprintf(stderr, "%d: copied vector: %s\n", __LINE__, s1 = TO_STR(p1)); free(s1);} s7_gc_unprotect_at(sc, gc_loc); p = s7_make_string(sc, "1234"); gc_loc = s7_gc_protect(sc, p); if (!s7_is_string(p)) {fprintf(stderr, "%d: %s is not a string?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_string_length(p) != 4) {fprintf(stderr, "%d: (length %s) is 4?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (strcmp(s7_string(p), "1234") != 0) {fprintf(stderr, "%d: %s is \"1234\"?\n", __LINE__, s1 = TO_STR(p)); free(s1);} s7_gc_unprotect_at(sc, gc_loc); p = s7_make_character(sc, 65); if (!s7_is_character(p)) {fprintf(stderr, "%d: %s is not a character?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_character(p) != 'A') {fprintf(stderr, "%d: %s is not #\\A?\n", __LINE__, s1 = TO_STR(p)); free(s1);} p = s7_list(sc, 3, TO_S7_INT(1), TO_S7_INT(2), TO_S7_INT(3)); gc_loc = s7_gc_protect(sc, p); if (!s7_is_list(sc, p)) {fprintf(stderr, "%d: %s is not a list?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_list_length(sc, p) != 3) {fprintf(stderr, "%d: (length %s) is not 3?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_integer(s7_list_ref(sc, p, 1)) != 2) {fprintf(stderr, "%d: (%s 1) is not 2?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_integer(s7_car(p)) != 1) {fprintf(stderr, "%d: (car %s) is not 1?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_integer(s7_cadr(p)) != 2) {fprintf(stderr, "%d: (cadr %s) is not 2?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_integer(s7_caddr(p)) != 3) {fprintf(stderr, "%d: (caddr %s) is not 2?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_integer(s7_car(s7_cddr(p))) != 3) {fprintf(stderr, "%d: (car (cddr %s)) is not 2?\n", __LINE__, s1 = TO_STR(p)); free(s1);} s7_list_set(sc, p, 1, s7_f(sc)); if (s7_list_ref(sc, p, 1) != s7_f(sc)) {fprintf(stderr, "%d: (%s 1) is not #f?\n", __LINE__, s1 = TO_STR(p)); free(s1);} s7_gc_unprotect_at(sc, gc_loc); { s7_pointer c1, c2, c3, c12, c23, c123, c1234, c1d2, c2d3, c3d4, c12d3, c23d4, c123d4, c1234d5; s7_gc_on(sc, false); c1 = s7_list(sc, 1, TO_S7_INT(1)); /* (1) */ c2 = s7_list(sc, 1, TO_S7_INT(2)); /* (2) */ c3 = s7_list(sc, 1, TO_S7_INT(3)); /* (3) */ c12 = s7_list(sc, 2, TO_S7_INT(1), TO_S7_INT(2)); /* (1 2) */ c23 = s7_list(sc, 2, TO_S7_INT(2), TO_S7_INT(3)); /* (2 3) */ c123 = s7_list(sc, 3, TO_S7_INT(1), TO_S7_INT(2), TO_S7_INT(3)); /* (1 2 3) */ c1234 = s7_list(sc, 4, TO_S7_INT(1), TO_S7_INT(2), TO_S7_INT(3), TO_S7_INT(4)); /* (1 2 3 4) */ c1d2 = s7_cons(sc, TO_S7_INT(1), TO_S7_INT(2)); /* (1 . 2) */ c2d3 = s7_cons(sc, TO_S7_INT(2), TO_S7_INT(3)); /* (2 . 3) */ c3d4 = s7_cons(sc, TO_S7_INT(3), TO_S7_INT(4)); /* (3 . 4) */ c12d3 = s7_cons(sc, TO_S7_INT(1), s7_cons(sc, TO_S7_INT(2), TO_S7_INT(3))); /* (1 2 . 3) */ c23d4 = s7_cons(sc, TO_S7_INT(2), s7_cons(sc, TO_S7_INT(3), TO_S7_INT(4))); /* (2 3 . 4) */ c123d4 = s7_cons(sc, TO_S7_INT(1), s7_cons(sc, TO_S7_INT(2), s7_cons(sc, TO_S7_INT(3), TO_S7_INT(4)))); /* (1 2 3 . 4) */ c1234d5 = s7_cons(sc, TO_S7_INT(1), s7_cons(sc, TO_S7_INT(2), s7_cons(sc, TO_S7_INT(3), s7_cons(sc, TO_S7_INT(4), TO_S7_INT(5))))); /* (1 2 3 4 . 5) */ if (s7_integer(p = s7_caar(s7_list(sc, 1, c1))) != 1) {fprintf(stderr, "%d: caar is %s?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_integer(p = s7_cadr(c12)) != 2) {fprintf(stderr, "%d: cadr is %s?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_integer(p = s7_cdar(s7_list(sc, 1, c1d2))) != 2) {fprintf(stderr, "%d: cdar is %s?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_integer(p = s7_cddr(c12d3)) != 3) {fprintf(stderr, "%d: cddr is %s?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_integer(p = s7_caaar(s7_list(sc, 1, s7_list(sc, 1, c1)))) != 1) {fprintf(stderr, "%d: caaar is %s?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_integer(p = s7_caadr(s7_list(sc, 2, TO_S7_INT(1), c2))) != 2) {fprintf(stderr, "%d: caadr is %s?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_integer(p = s7_cadar(s7_list(sc, 1, c12))) != 2) {fprintf(stderr, "%d: cadar is %s?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_integer(p = s7_cdaar(s7_list(sc, 1, s7_list(sc, 1, c1d2)))) != 2) {fprintf(stderr, "%d: cdaar is %s?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_integer(p = s7_caddr(c123)) != 3) {fprintf(stderr, "%d: caddr is %s?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_integer(p = s7_cdddr(c123d4)) != 4) {fprintf(stderr, "%d: cdddr is %s?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_integer(p = s7_cdadr(s7_list(sc, 2, TO_S7_INT(1), c2d3))) != 3) {fprintf(stderr, "%d: cdadr is %s?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_integer(p = s7_cddar(s7_list(sc, 1, c12d3))) != 3) {fprintf(stderr, "%d: cddar is %s?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_integer(p = s7_caaaar(s7_list(sc, 1, s7_list(sc, 1, s7_list(sc, 1, c1))))) != 1) {fprintf(stderr, "%d: caaaar is %s?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_integer(p = s7_caaadr(s7_list(sc, 2, TO_S7_INT(1), s7_list(sc, 1, c2)))) != 2) {fprintf(stderr, "%d: caaadr is %s?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_integer(p = s7_caadar(s7_list(sc, 1, s7_list(sc, 2, TO_S7_INT(1), c2)))) != 2) {fprintf(stderr, "%d: caadar is %s?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_integer(p = s7_cadaar(s7_list(sc, 1, s7_list(sc, 1, c12)))) != 2) {fprintf(stderr, "%d: cadaar is %s?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_integer(p = s7_caaddr(s7_list(sc, 3, TO_S7_INT(1), TO_S7_INT(2), c3))) != 3) {fprintf(stderr, "%d: caaddr is %s?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_integer(p = s7_cadddr(c1234)) != 4) {fprintf(stderr, "%d: cadddr is %s?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_integer(p = s7_cadadr(s7_list(sc, 2, TO_S7_INT(1), c23))) != 3) {fprintf(stderr, "%d: cadadr is %s?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_integer(p = s7_caddar(s7_list(sc, 1, c123))) != 3) {fprintf(stderr, "%d: caddar is %s?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_integer(p = s7_cdaaar(s7_list(sc, 1, s7_list(sc, 1, s7_list(sc, 1, c1d2))))) != 2) {fprintf(stderr, "%d: cdaaar is %s?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_integer(p = s7_cdaadr(s7_list(sc, 2, TO_S7_INT(1), s7_list(sc, 1, c2d3)))) != 3) {fprintf(stderr, "%d: cdaadr is %s?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_integer(p = s7_cdadar(s7_list(sc, 1, s7_list(sc, 2, TO_S7_INT(1), c2d3)))) != 3) {fprintf(stderr, "%d: cdadar is %s?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_integer(p = s7_cddaar(s7_list(sc, 1, s7_list(sc, 1, c12d3)))) != 3) {fprintf(stderr, "%d: cddaar is %s?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_integer(p = s7_cdaddr(s7_list(sc, 3, TO_S7_INT(1), TO_S7_INT(2), c3d4))) != 4) {fprintf(stderr, "%d: cdaddr is %s?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_integer(p = s7_cddddr(c1234d5)) != 5) {fprintf(stderr, "%d: cdddd is %s?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_integer(p = s7_cddadr(s7_list(sc, 2, TO_S7_INT(1), c23d4))) != 4) {fprintf(stderr, "%d: cddadr is %s?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_integer(p = s7_cdddar(s7_list(sc, 1, c123d4))) != 4) {fprintf(stderr, "%d: cdddar is %s?\n", __LINE__, s1 = TO_STR(p)); free(s1);} p = s7_reverse(sc, c123); s1 = TO_STR(p); if (strcmp(s1, "(3 2 1)") != 0) {fprintf(stderr, "%d: (reverse '(1 2 3)) is %s?\n", __LINE__, s1);} free(s1); p = s7_append(sc, c1, c2); s1 = TO_STR(p); if (strcmp(s1, "(1 2)") != 0) {fprintf(stderr, "%d: (append '(1) '(2)) is %s?\n", __LINE__, s1);} free(s1); p = s7_list(sc, 2, s7_cons(sc, s7_make_symbol(sc, "a"), TO_S7_INT(32)), s7_cons(sc, s7_make_symbol(sc, "b"), TO_S7_INT(1))); p1 = s7_assq(sc, s7_make_symbol(sc, "a"), p); s1 = TO_STR(p1); if (strcmp(s1, "(a . 32)") != 0) {fprintf(stderr, "%d: (assq 'a '((a . 32) (b . 1)))) is %s?\n", __LINE__, s1);} free(s1); p1 = s7_assoc(sc, s7_make_symbol(sc, "b"), p); s1 = TO_STR(p1); if (strcmp(s1, "(b . 1)") != 0) {fprintf(stderr, "%d: (assoc 'b '((a . 32) (b . 1))) is %s?\n", __LINE__, s1);} free(s1); p = s7_member(sc, TO_S7_INT(2), c1234); s1 = TO_STR(p); if (strcmp(s1, "(2 3 4)") != 0) {fprintf(stderr, "%d: (member 2 '(1 2 3 4)) is %s?\n", __LINE__, s1);} free(s1); p = s7_list(sc, 2, s7_make_symbol(sc, "a"), s7_make_symbol(sc, "b")); p1 = s7_memq(sc, s7_make_symbol(sc, "b"), p); s1 = TO_STR(p1); if (strcmp(s1, "(b)") != 0) {fprintf(stderr, "%d: (memq 'b '(a b)) is %s?\n", __LINE__, s1);} free(s1); s7_set_car(c1234, s7_make_symbol(sc, "+")); p = s7_eval(sc, s7_list(sc, 2, s7_make_symbol(sc, "quote"), c1234), s7_sublet(sc, s7_rootlet(sc), s7_nil(sc))); if (s7_integer(p) != 9) {fprintf(stderr, "%d: (eval '(+ 2 3 4)) is %s?\n", __LINE__, s1 = TO_STR(p)); free(s1);} p = s7_eval_form(sc, c1234, s7_sublet(sc, s7_rootlet(sc), s7_nil(sc))); if (s7_integer(p) != 9) {fprintf(stderr, "%d: (eval(form) '(+ 2 3 4)) is %s?\n", __LINE__, s1 = TO_STR(p)); free(s1);} s7_gc_on(sc, true); } p = s7_make_ulong(sc, 123); gc_loc = s7_gc_protect(sc, p); if (!s7_is_ulong(p)) {fprintf(stderr, "%d: %s is not a ulong?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_ulong(p) != (unsigned long)123) {fprintf(stderr, "%d: %s is not 123?\n", __LINE__, s1 = TO_STR(p)); free(s1);} s7_gc_unprotect_at(sc, gc_loc); p = s7_make_ulong_long(sc, 123); gc_loc = s7_gc_protect(sc, p); if (!s7_is_ulong_long(p)) {fprintf(stderr, "%d: %s is not a ulong_long?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_ulong_long(p) != (unsigned long long)123) {fprintf(stderr, "%d: %s is not 123?\n", __LINE__, s1 = TO_STR(p)); free(s1);} s7_gc_unprotect_at(sc, gc_loc); p = s7_make_hash_table(sc, 255); gc_loc = s7_gc_protect(sc, p); if (!s7_is_hash_table(p)) {fprintf(stderr, "%d: %s is not a hash-table?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_hash_table_ref(sc, p, s7_eof_object(sc)) != s7_f(sc)) {fprintf(stderr, "%d: (hash-table-ref %s #) is not #f?\n", __LINE__, s1 = TO_STR(p)); free(s1);} s7_hash_table_set(sc, p, s7_eof_object(sc), s7_unspecified(sc)); if (s7_hash_table_ref(sc, p, s7_eof_object(sc)) != s7_unspecified(sc)) {fprintf(stderr, "%d: (hash-table-ref %s #) is not #?\n", __LINE__, s1 = TO_STR(p)); free(s1);} s7_gc_unprotect_at(sc, gc_loc); p = s7_current_input_port(sc); if (!s7_is_input_port(sc, p)) {fprintf(stderr, "%d: %s is not an input port?\n", __LINE__, s1 = TO_STR(p)); free(s1);} p = s7_current_output_port(sc); if (!s7_is_output_port(sc, p)) {fprintf(stderr, "%d: %s is not an output port?\n", __LINE__, s1 = TO_STR(p)); free(s1);} p = s7_name_to_value(sc, "abs"); if (!s7_is_procedure(p)) {fprintf(stderr, "%d: %s is not a procedure?\n", __LINE__, s1 = TO_STR(p)); free(s1);} p = s7_make_symbol(sc, "abs"); if (!s7_is_symbol(p)) {fprintf(stderr, "%d: %s is not a symbol?\n", __LINE__, s1 = TO_STR(p)); free(s1);} p = s7_gensym(sc, "abs"); if (!s7_is_symbol(p)) {fprintf(stderr, "%d: %s is not a symbol?\n", __LINE__, s1 = TO_STR(p)); free(s1);} p = s7_make_keyword(sc, "key"); if (!s7_is_keyword(p)) {fprintf(stderr, "%d: %s is not a keyword?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (!s7_is_eq(p, p)) {fprintf(stderr, "%d: %s is not a self-eq??\n", __LINE__, s1 = TO_STR(p)); free(s1);} p = s7_rootlet(sc); if (!s7_is_let(p)) {fprintf(stderr, "%d: %s is not an environment?\n", __LINE__, s1 = TO_STR(p)); free(s1);} p = s7_curlet(sc); if ((!s7_is_null(sc, p)) && (!s7_is_let(p))) {fprintf(stderr, "%d: %s is not an environment?\n", __LINE__, s1 = TO_STR(p)); free(s1);} s7_define_constant(sc, "a_constant", s7_t(sc)); if (!s7_is_constant(s7_name_to_value(sc, "a_constant"))) {fprintf(stderr, "%d: a_constant is not a constant?\n", __LINE__);} if (!s7_is_defined(sc, "a_constant")) {fprintf(stderr, "%d: a_constant is not defined?\n", __LINE__);} s7_define_function(sc, "a_function", a_function, 1, 0, false, "a function"); if (!s7_is_defined(sc, "a_function")) {fprintf(stderr, "%d: a_function is not defined?\n", __LINE__);} if (!s7_is_function(s7_name_to_value(sc, "a_function"))) {fprintf(stderr, "%d: a_function is not a function?\n", __LINE__);} p = s7_apply_function(sc, s7_name_to_value(sc, "a_function"), s7_cons(sc, TO_S7_INT(32), s7_nil(sc))); if (!s7_is_integer(p)) {fprintf(stderr, "%d: %s is not an integer?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_integer(p) != 32) {fprintf(stderr, "%d: %s is not 32?\n", __LINE__, s1 = TO_STR(p)); free(s1);} dax_type_tag = s7_new_type("dax", print_dax, free_dax, equal_dax, mark_dax, NULL, NULL); s7_define_function(sc, "make-dax", make_dax, 2, 0, false, "(make-dax x data) makes a new dax"); s7_define_function(sc, "dax?", is_dax, 1, 0, false, "(dax? anything) returns #t if its argument is a dax object"); s7_define_variable(sc, "dax-x", s7_dilambda(sc, "dax-x", dax_x, 1, 0, set_dax_x, 2, 0, "dax x field (a real)")); s7_define_variable(sc, "dax-data", s7_dilambda(sc, "dax-data", dax_data, 1, 0, set_dax_data, 2, 0, "dax data field")); if (!s7_is_procedure_with_setter(s7_name_to_value(sc, "dax-x"))) {fprintf(stderr, "%d: dax-x is not a pws?\n", __LINE__);} p = make_dax(sc, s7_cons(sc, s7_make_real(sc, 1.0), s7_cons(sc, TO_S7_INT(2), s7_nil(sc)))); gc_loc = s7_gc_protect(sc, p); if (!s7_is_object(p)) {fprintf(stderr, "%d: %s is not an object?\n", __LINE__, s1 = TO_STR(p)); free(s1);} p1 = s7_apply_function(sc, s7_name_to_value(sc, "dax?"), s7_cons(sc, p, s7_nil(sc))); if (p1 != s7_t(sc)) {fprintf(stderr, "%d: %s is not a dax object?\n", __LINE__, s1 = TO_STR(p)); free(s1);} s1 = TO_STR(p); if (strcmp(s1, "#") != 0) {fprintf(stderr, "%d: dax prints as %s?\n", __LINE__, s2 = TO_STR(p)); free(s2);} free(s1); p1 = s7_apply_function(sc, s7_name_to_value(sc, "dax-data"), s7_cons(sc, p, s7_nil(sc))); if (!s7_is_integer(p1)) {fprintf(stderr, "%d: %s is not an integer?\n", __LINE__, s1 = TO_STR(p1)); free(s1);} if (s7_integer(p1) != 2) {fprintf(stderr, "%d: %s is not 2?\n", __LINE__, s1 = TO_STR(p1)); free(s1);} s7_apply_function(sc, s7_procedure_setter(sc, s7_name_to_value(sc, "dax-data")), s7_cons(sc, p, s7_cons(sc, TO_S7_INT(32), s7_nil(sc)))); p1 = s7_apply_function(sc, s7_name_to_value(sc, "dax-data"), s7_cons(sc, p, s7_nil(sc))); if (!s7_is_integer(p1)) {fprintf(stderr, "%d: %s is not an integer?\n", __LINE__, s1 = TO_STR(p1)); free(s1);} if (s7_integer(p1) != 32) {fprintf(stderr, "%d: %s is not 32?\n", __LINE__, s1 = TO_STR(p1)); free(s1);} s7_gc_unprotect_at(sc, gc_loc); s7_define_function_star(sc, "plus", plus, "(red 32) blue", "an example of define* from C"); if (!s7_is_procedure(s7_name_to_value(sc, "plus"))) {fprintf(stderr, "%d: plus is not a function?\n", __LINE__);} p = s7_apply_function(sc, s7_name_to_value(sc, "plus"), s7_cons(sc, TO_S7_INT(1), s7_cons(sc, TO_S7_INT(2), s7_nil(sc)))); if (!s7_is_integer(p)) {fprintf(stderr, "%d: %s is not an integer?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_integer(p) != 4) {fprintf(stderr, "%d: %s is not 4?\n", __LINE__, s1 = TO_STR(p)); free(s1);} p = s7_apply_function(sc, s7_name_to_value(sc, "plus"), s7_cons(sc, s7_make_keyword(sc, "blue"), s7_cons(sc, TO_S7_INT(2), s7_nil(sc)))); if (!s7_is_integer(p)) {fprintf(stderr, "%d: %s is not an integer?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_integer(p) != 66) {fprintf(stderr, "%d: %s is not 66?\n", __LINE__, s1 = TO_STR(p)); free(s1);} s7_define_variable(sc, "my-1", s7_make_integer(sc, 1)); p = s7_name_to_value(sc, "my-1"); if (!s7_is_integer(p)) {fprintf(stderr, "%d: %s is not an integer?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_integer(p) != 1) {fprintf(stderr, "%d: %s is not 1?\n", __LINE__, s1 = TO_STR(p)); free(s1);} s7_symbol_set_value(sc, s7_make_symbol(sc, "my-1"), s7_make_integer(sc, 32)); p = s7_name_to_value(sc, "my-1"); if (s7_integer(p) != 32) {fprintf(stderr, "%d: %s is not 32?\n", __LINE__, s1 = TO_STR(p)); free(s1);} s7_define_macro(sc, "mac-plus", mac_plus, 2, 0, false, "plus adds its two arguments"); p = s7_eval_c_string(sc, "(mac-plus 2 3)"); if (s7_integer(p) != 5) {fprintf(stderr, "%d: %s is not 5?\n", __LINE__, s1 = TO_STR(p)); free(s1);} p1 = s7_apply_function(sc, s7_name_to_value(sc, "mac-plus"), s7_list(sc, 2, s7_make_integer(sc, 3), s7_make_integer(sc, 4))); p = s7_eval_form(sc, p1, s7_rootlet(sc)); if ((!s7_is_integer(p)) || (s7_integer(p) != 7)) {char *s2; fprintf(stderr, "%d: %s -> %s is not 7?\n", __LINE__, s1 = TO_STR(p1), s2 = TO_STR(p)); free(s1); free(s2);} s7_define_macro(sc, "mac-plus-mv", mac_plus_mv, 2, 0, false, "macro values test"); p = s7_eval_c_string(sc, "(let () (+ (mac-plus-mv 2 3)))"); if (s7_integer(p) != 5) {fprintf(stderr, "%d: %s is not 5?\n", __LINE__, s1 = TO_STR(p)); free(s1);} s7_define_function(sc, "open-plus", open_plus, 1, 0, true, plus_help); p = s7_sublet(sc, s7_nil(sc), s7_cons(sc, s7_cons(sc, s7_make_symbol(sc, "plus"), s7_name_to_value(sc, "plus")), s7_nil(sc))); s7_openlet(sc, p); p1 = s7_apply_function(sc, s7_name_to_value(sc, "open-plus"), s7_list(sc, 3, p, s7_make_integer(sc, 2), s7_make_integer(sc, 3))); if ((!s7_is_integer(p1)) || (s7_integer(p1) != 7)) {fprintf(stderr, "%d: %s is not 7?\n", __LINE__, s1 = TO_STR(p1)); free(s1);} s7_eval_c_string(sc, "(define my-vect (make-vector '(2 3 4) 0))"); s7_eval_c_string(sc, "(set! (my-vect 1 1 1) 32)"); p1 = s7_name_to_value(sc, "my-vect"); p = multivector_ref(sc, p1, 3, 0, 0, 0); if (s7_integer(p) != 0) {fprintf(stderr, "%d: %s is not 0?\n", __LINE__, s1 = TO_STR(p)); free(s1);} p = s7_vector_ref_n(sc, p1, 3, 0, 0, 0); if (s7_integer(p) != 0) {fprintf(stderr, "%d: %s is not 0?\n", __LINE__, s1 = TO_STR(p)); free(s1);} p = multivector_ref(sc, p1, 3, 1, 1, 1); if (s7_integer(p) != 32) {fprintf(stderr, "%d: %s is not 32?\n", __LINE__, s1 = TO_STR(p)); free(s1);} p = s7_vector_ref_n(sc, p1, 3, 1, 1, 1); if (s7_integer(p) != 32) {fprintf(stderr, "%d: %s is not 32?\n", __LINE__, s1 = TO_STR(p)); free(s1);} s7_vector_set_n(sc, p1, TO_S7_INT(12), 3, 1, 1, 2); p = s7_vector_ref_n(sc, p1, 3, 1, 1, 2); if (s7_integer(p) != 12) {fprintf(stderr, "%d: %s is not 12?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_vector_length(p1) != 24) {fprintf(stderr, "%d: (length %s) is not 24?\n", __LINE__, s1 = TO_STR(p1)); free(s1);} if (s7_vector_rank(p1) != 3) {fprintf(stderr, "%d: (vector-dimensions %s) is not 3?\n", __LINE__, s1 = TO_STR(p1)); free(s1);} { s7_int *dims, *offs; s7_pointer *els; dims = s7_vector_dimensions(p1); offs = s7_vector_offsets(p1); els = s7_vector_elements(p1); if (dims[0] != 2) fprintf(stderr, "%d: dims[0]: %lld?\n", __LINE__, dims[0]); if (dims[1] != 3) fprintf(stderr, "%d: dims[1]: %lld?\n", __LINE__, dims[1]); if (dims[2] != 4) fprintf(stderr, "%d: dims[2]: %lld?\n", __LINE__, dims[2]); if (offs[0] != 12) fprintf(stderr, "%d: offs[0]: %lld?\n", __LINE__, offs[0]); if (offs[1] != 4) fprintf(stderr, "%d: offs[1]: %lld?\n", __LINE__, offs[1]); if (s7_integer(p = els[12 + 4 + 1]) != 32) {fprintf(stderr, "%d: %s is not 32?\n", __LINE__, s1 = TO_STR(p)); free(s1);} } s7_vector_fill(sc, p1, s7_t(sc)); p = s7_vector_ref_n(sc, p1, 3, 1, 1, 1); if (p != s7_t(sc)) {fprintf(stderr, "%d: %s is not #t?\n", __LINE__, s1 = TO_STR(p)); free(s1);} { s7_pointer new_env, old_env; new_env = s7_sublet(sc, old_env = s7_curlet(sc), s7_nil(sc)); gc_loc = s7_gc_protect(sc, new_env); s7_define(sc, new_env, s7_make_symbol(sc, "var1"), s7_make_integer(sc, 32)); if (new_env == s7_curlet(sc)) {fprintf(stderr, "%d: %s is the current env?\n", __LINE__, s1 = TO_STR(new_env)); free(s1);} s1 = TO_STR(s7_let_to_list(sc, new_env)); if (strcmp(s1, "((var1 . 32))") != 0) {fprintf(stderr, "%d: new-env is %s?\n", __LINE__, s1);} free(s1); p = s7_let_ref(sc, new_env, s7_make_symbol(sc, "var1")); if (s7_integer(p) != 32) {fprintf(stderr, "%d: %s is not 32?\n", __LINE__, s1 = TO_STR(p)); free(s1);} s7_let_set(sc, new_env, s7_make_symbol(sc, "var1"), TO_S7_INT(3)); p = s7_let_ref(sc, new_env, s7_make_symbol(sc, "var1")); if (s7_integer(p) != 3) {fprintf(stderr, "%d: %s is not 3?\n", __LINE__, s1 = TO_STR(p)); free(s1);} s7_set_curlet(sc, new_env); p = s7_slot(sc, s7_make_symbol(sc, "var1")); if (s7_integer(s7_slot_value(p)) != 3) {fprintf(stderr, "%d: slot-value %s is not 3?\n", __LINE__, s1 = TO_STR(p)); free(s1);} s7_slot_set_value(sc, p, s7_f(sc)); p = s7_let_ref(sc, new_env, s7_make_symbol(sc, "var1")); if (p != s7_f(sc)) {fprintf(stderr, "%d: set slot-value %s is not #f?\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_outlet(sc, new_env) != old_env) {fprintf(stderr, "%d: outer-env %s?\n", __LINE__, s1 = TO_STR(old_env)); free(s1);} s7_make_slot(sc, new_env, s7_make_symbol(sc, "var2"), TO_S7_INT(-1)); p = s7_let_ref(sc, new_env, s7_make_symbol(sc, "var2")); if (s7_integer(p) != -1) {fprintf(stderr, "%d: make_slot %s is not -1?\n", __LINE__, s1 = TO_STR(p)); free(s1);} s7_symbol_set_value(sc, s7_make_symbol(sc, "var2"), s7_t(sc)); p = s7_symbol_local_value(sc, s7_make_symbol(sc, "var2"), new_env); if (p != s7_t(sc)) {fprintf(stderr, "%d: set symbol-value %s is not #t?\n", __LINE__, s1 = TO_STR(p)); free(s1);} p = s7_let_to_list(sc, new_env); { int gloc; gloc = s7_gc_protect(sc, p); s1 = TO_STR(p); if (strcmp(s1, "((var1 . #f) (var2 . #t))") != 0) {fprintf(stderr, "%d: env->list: %s\n", __LINE__, s1);} free(s1); s7_gc_unprotect_at(sc, gloc); } s7_set_curlet(sc, old_env); s7_gc_unprotect_at(sc, gc_loc); } if (!s7_is_list(sc, p = s7_load_path(sc))) {fprintf(stderr, "%d: %s is not a list?\n", __LINE__, s1 = TO_STR(p)); free(s1);} { s7_pointer port; port = s7_open_output_file(sc, "ffitest.scm", "w"); if (!s7_is_output_port(sc, port)) {fprintf(stderr, "%d: %s is not an output port?\n", __LINE__, s1 = TO_STR(port)); free(s1);} else { /* (define loaded_var 321) hopefully */ gc_loc = s7_gc_protect(sc, port); s7_write_char(sc, (int)'(', port); s7_write(sc, s7_make_symbol(sc, "define"), port); s7_write_char(sc, (int)' ', port); s7_display(sc, s7_make_symbol(sc, "loaded_var"), port); s7_write_char(sc, (int)' ', port); s7_format(sc, s7_list(sc, 3, port, s7_make_string(sc, "~A)"), TO_S7_INT(321))); s7_newline(sc, port); s7_flush_output_port(sc, port); s7_close_output_port(sc, port); s7_gc_unprotect_at(sc, gc_loc); s7_load(sc, "ffitest.scm"); if (!s7_is_defined(sc, "loaded_var")) {fprintf(stderr, "%d: load unhappy?\n", __LINE__);} else { int c; if (s7_integer(p = s7_name_to_value(sc, "loaded_var")) != 321) {fprintf(stderr, "%d: %s is not 321?\n", __LINE__, s1 = TO_STR(p)); free(s1);} port = s7_open_input_file(sc, "ffitest.scm", "r"); if (!s7_is_input_port(sc, port)) {fprintf(stderr, "%d: %s is not an input port?\n", __LINE__, s1 = TO_STR(port)); free(s1);} else { gc_loc = s7_gc_protect(sc, port); c = s7_peek_char(sc, port); if (c != (int)'(') {fprintf(stderr, "%d: peek-char sees %c?\n", __LINE__, (unsigned char)c);} c = s7_read_char(sc, port); if (c != (int)'(') {fprintf(stderr, "%d: read-char sees %c?\n", __LINE__, (unsigned char)c);} s7_close_input_port(sc, port); s7_gc_unprotect_at(sc, gc_loc); port = s7_open_input_file(sc, "ffitest.scm", "r"); gc_loc = s7_gc_protect(sc, port); p = s7_read(sc, port); s1 = TO_STR(p); if (strcmp(s1, "(define loaded_var 321)") != 0) {fprintf(stderr, "%d: read file sees %s?\n", __LINE__, s1);} free(s1); s7_close_input_port(sc, port); s7_gc_unprotect_at(sc, gc_loc); } } } port = s7_open_input_string(sc, "(+ 1 2)"); if (!s7_is_input_port(sc, port)) {fprintf(stderr, "%d: %s is not an input port?\n", __LINE__, s1 = TO_STR(port)); free(s1);} gc_loc = s7_gc_protect(sc, port); p = s7_read(sc, port); s1 = TO_STR(p); if (strcmp(s1, "(+ 1 2)") != 0) {fprintf(stderr, "%d: read string sees %s?\n", __LINE__, s1);} free(s1); s7_close_input_port(sc, port); s7_gc_unprotect_at(sc, gc_loc); port = s7_open_output_string(sc); if (!s7_is_output_port(sc, port)) {fprintf(stderr, "%d: %s is not an output port?\n", __LINE__, s1 = TO_STR(port)); free(s1);} gc_loc = s7_gc_protect(sc, port); s7_display(sc, s7_make_string(sc, "(+ 2 3)"), port); { const char *s2; s2 = s7_get_output_string(sc, port); if (strcmp(s2, "(+ 2 3)") != 0) {fprintf(stderr, "%d: read output string sees %s?\n", __LINE__, s2);} } s7_close_output_port(sc, port); s7_gc_unprotect_at(sc, gc_loc); p = s7_set_current_output_port(sc, s7_open_output_function(sc, my_print)); p1 = s7_open_input_function(sc, my_read); gc_loc = s7_gc_protect(sc, p1); s7_display(sc, s7_make_character(sc, '3'), s7_current_output_port(sc)); if (last_c != '3') {fprintf(stderr, "%d: last_c: %c, c: %c\n", __LINE__, last_c, '3');} last_c = s7_read_char(sc, p1); if (last_c != '0') {fprintf(stderr, "%d: last_c: %c\n", __LINE__, last_c);} s7_set_current_output_port(sc, p); s7_gc_unprotect_at(sc, gc_loc); } { s7_pointer port, val; s7_autoload(sc, s7_make_symbol(sc, "auto_var"), s7_make_string(sc, "ffitest.scm")); port = s7_open_output_file(sc, "ffitest.scm", "w"); gc_loc = s7_gc_protect(sc, port); s7_display(sc, s7_make_string(sc, "(define auto_var 123)"), port); s7_newline(sc, port); s7_close_output_port(sc, port); s7_gc_unprotect_at(sc, gc_loc); val = s7_eval_c_string(sc, "(+ auto_var 1)"); if ((!s7_is_integer(val)) || (s7_integer(val) != 124)) {fprintf(stderr, "%d: auto_var+1 = %s?\n", __LINE__, s1 = TO_STR(val)); free(s1);} } { s7_pointer test_hook; test_hook = s7_eval_c_string(sc, "(make-hook 'a 'b)"); s7_define_constant(sc, "test-hook", test_hook); s7_hook_set_functions(sc, test_hook, s7_cons(sc, s7_make_function(sc, "test-hook-function", test_hook_function, 1, 0, false, "a test-hook function"), s7_hook_functions(sc, test_hook))); s7_call(sc, test_hook, s7_list(sc, 2, TO_S7_INT(1), TO_S7_INT(2))); s7_call_with_location(sc, test_hook, s7_list(sc, 2, TO_S7_INT(1), TO_S7_INT(2)), "ffitest", "ffitest.c", __LINE__); } { s7_pointer x, y, funcs; funcs = s7_eval_c_string(sc, "(let ((x 0)) (list (lambda () (set! x 1)) (lambda () (set! x (+ x 1))) (lambda () (set! x (+ x 1))) (lambda () x)))"); gc_loc = s7_gc_protect(sc, funcs); y = s7_dynamic_wind(sc, s7_car(funcs), s7_cadr(funcs), s7_caddr(funcs)); x = s7_call(sc, s7_cadddr(funcs), s7_nil(sc)); if ((!s7_is_integer(x)) || (!s7_is_integer(y)) || (s7_integer(x) != 3) || (s7_integer(y) != 2)) fprintf(stderr, "s7_dynamic_wind: x: %s, y: %s\n", s7_object_to_c_string(sc, x), s7_object_to_c_string(sc, y)); y = s7_dynamic_wind(sc, s7_f(sc), s7_car(funcs), s7_cadr(funcs)); x = s7_call(sc, s7_cadddr(funcs), s7_nil(sc)); if ((!s7_is_integer(x)) || (!s7_is_integer(y)) || (s7_integer(x) != 2) || (s7_integer(y) != 1)) fprintf(stderr, "s7_dynamic_wind (init #f): x: %s, y: %s\n", s7_object_to_c_string(sc, x), s7_object_to_c_string(sc, y)); y = s7_dynamic_wind(sc, s7_f(sc), s7_cadr(funcs), s7_f(sc)); x = s7_call(sc, s7_cadddr(funcs), s7_nil(sc)); if ((!s7_is_integer(x)) || (!s7_is_integer(y)) || (s7_integer(x) != 3) || (s7_integer(y) != 3)) fprintf(stderr, "s7_dynamic_wind (init #f, finish #f): x: %s, y: %s\n", s7_object_to_c_string(sc, x), s7_object_to_c_string(sc, y)); y = s7_dynamic_wind(sc, s7_cadr(funcs), s7_cadr(funcs), s7_f(sc)); x = s7_call(sc, s7_cadddr(funcs), s7_nil(sc)); if ((!s7_is_integer(x)) || (!s7_is_integer(y)) || (s7_integer(x) != 5) || (s7_integer(y) != 5)) fprintf(stderr, "s7_dynamic_wind (finish #f): x: %s, y: %s\n", s7_object_to_c_string(sc, x), s7_object_to_c_string(sc, y)); s7_gc_unprotect_at(sc, gc_loc); } if (s7_begin_hook(sc) != NULL) {fprintf(stderr, "%d: begin_hook is not null?\n", __LINE__);} tested_begin_hook = false; s7_set_begin_hook(sc, test_begin_hook); s7_eval_c_string(sc, "(begin (+ 1 2))"); if (!tested_begin_hook) {fprintf(stderr, "%d: begin_hook not called?\n", __LINE__);} if (s7_begin_hook(sc) != test_begin_hook) {fprintf(stderr, "%d: begin_hook was not set?\n", __LINE__);} s7_set_begin_hook(sc, NULL); p1 = s7_name_to_value(sc, "abs"); if (!s7_is_procedure(p1)) {fprintf(stderr, "%d: (procedure? abs) = #f?\n", __LINE__);} if (s7_is_macro(sc, p1)) {fprintf(stderr, "%d: (macro? abs) = #t?\n", __LINE__);} if (!s7_is_aritable(sc, p1, 1)) {fprintf(stderr, "%d: (aritable? abs 1) = #f?\n", __LINE__);} if (s7_is_aritable(sc, p1, 2)) {fprintf(stderr, "%d: (aritable? abs 2) = #t?\n", __LINE__);} p = s7_funclet(sc, p1); if (p != s7_rootlet(sc)) {fprintf(stderr, "%d: (funclet abs) = %s?\n", __LINE__, s1 = TO_STR(p)); free(s1);} { const char *s3; s3 = s7_procedure_documentation(sc, p1); if (strcmp(s3, "(abs x) returns the absolute value of the real number x") != 0) {fprintf(stderr, "%d: (procedure-documentation abs) = %s?\n", __LINE__, s3);} s3 = s7_help(sc, p1); if (strcmp(s3, "(abs x) returns the absolute value of the real number x") != 0) {fprintf(stderr, "%d: (help abs) = %s?\n", __LINE__, s3);} } p = s7_eval_c_string(sc, "(lambda (a b . c) (+ a b (apply * c)))"); gc_loc = s7_gc_protect(sc, p); if (!s7_is_procedure(p)) {fprintf(stderr, "%d: %s is not a procedure?\n", __LINE__, s1 = TO_STR(p)); free(s1);} s1 = TO_STR(s7_closure_body(sc, p)); if (strcmp(s1, "((+ a b (apply * c)))") != 0) {fprintf(stderr, "%d: s7_closure_body is %s?\n", __LINE__, s1);} free(s1); s1 = TO_STR(s7_closure_args(sc, p)); if (strcmp(s1, "(a b . c)") != 0) {fprintf(stderr, "%d: s7_closure_args is %s?\n", __LINE__, s1);} free(s1); s1 = TO_STR(s7_closure_let(sc, p)); if (strcmp(s1, "()") != 0) {fprintf(stderr, "%d: s7_closure_let is %s?\n", __LINE__, s1);} free(s1); if (!s7_is_aritable(sc, p, 2)) {fprintf(stderr, "%d: aritable? lambda 2 = #f?\n", __LINE__);} if (s7_is_aritable(sc, p, 1)) {fprintf(stderr, "%d: aritable? lambda 1 = #t?\n", __LINE__);} s7_gc_unprotect_at(sc, gc_loc); { /* iterators */ s7_pointer iter, x; iter = s7_make_iterator(sc, s7_list(sc, 3, TO_S7_INT(1), TO_S7_INT(2), TO_S7_INT(3))); if (!s7_is_iterator(iter)) fprintf(stderr, "%d: %s is not an interator\n", __LINE__, TO_STR(iter)); if (s7_iterator_is_at_end(iter)) fprintf(stderr, "%d: %s is prematurely done\n", __LINE__, TO_STR(iter)); x = s7_iterate(sc, iter); if ((!s7_is_integer(x)) || (s7_integer(x) != 1)) fprintf(stderr, "%d: %s should be 1\n", __LINE__, TO_STR(x)); x = s7_iterate(sc, iter); if ((!s7_is_integer(x)) || (s7_integer(x) != 2)) fprintf(stderr, "%d: %s should be 2\n", __LINE__, TO_STR(x)); x = s7_iterate(sc, iter); if ((!s7_is_integer(x)) || (s7_integer(x) != 3)) fprintf(stderr, "%d: %s should be 3\n", __LINE__, TO_STR(x)); x = s7_iterate(sc, iter); if ((x != s7_eof_object(sc)) || (!s7_iterator_is_at_end(iter))) fprintf(stderr, "%d: %s should be # and iter should be done\n", __LINE__, TO_STR(x)); } g_block_type = s7_new_type_x(sc, "#", g_block_display, g_block_free, g_block_is_equal, g_block_mark, g_block_ref, g_block_set, g_block_length, g_block_copy, g_block_reverse, g_block_fill); s7_define_function(sc, "make-block", g_make_block, 1, 0, false, g_make_block_help); s7_define_function(sc, "block", g_to_block, 0, 0, true, g_block_help); g_block_methods = s7_eval_c_string(sc, "(inlet (cons 'vector? (lambda (p) #t)))"); s7_gc_protect(sc, g_block_methods); { g_block *g; s7_pointer gp; gp = g_make_block(sc, s7_list(sc, 1, TO_S7_INT(32))); gc_loc = s7_gc_protect(sc, gp); if (!s7_is_object(gp)) {fprintf(stderr, "%d: g_block %s is not an object?\n", __LINE__, s1 = TO_STR(gp)); free(s1);} g = (g_block *)s7_object_value(gp); if (s7_object_type(gp) != g_block_type) {fprintf(stderr, "%d: g_block types: %d %d\n", __LINE__, g_block_type, s7_object_type(gp));} if (s7_object_value_checked(gp, g_block_type) != g) {fprintf(stderr, "%d: checked g_block types: %d %d\n", __LINE__, g_block_type, s7_object_type(gp));} s7_gc_unprotect_at(sc, gc_loc); } { s7_pointer old_port; const char *errmsg = NULL; old_port = s7_set_current_error_port(sc, s7_open_output_string(sc)); gc_loc = s7_gc_protect(sc, old_port); s7_eval_c_string(sc, "(+ 1 #\\c)"); errmsg = s7_get_output_string(sc, s7_current_error_port(sc)); if (!errmsg) fprintf(stderr, "%d: no error!\n", __LINE__); s7_close_output_port(sc, s7_current_error_port(sc)); s7_set_current_error_port(sc, old_port); s7_gc_unprotect_at(sc, gc_loc); } { s7_pointer old_port, result; const char *errmsg = NULL; s7_define_function(sc, "error-handler", test_error_handler, 1, 0, false, "our error handler"); s7_eval_c_string(sc, "(set! (hook-functions *error-hook*) \n\ (list (lambda (hook) \n\ (error-handler \n\ (string-append \"hook: \" (apply format #f (hook 'data)))) \n\ (set! (hook 'result) 'our-error))))"); old_port = s7_set_current_error_port(sc, s7_open_output_string(sc)); gc_loc = s7_gc_protect(sc, old_port); result = s7_eval_c_string(sc, "(+ 1 #\\c)"); if (result != s7_make_symbol(sc, "our-error")) {fprintf(stderr, "%d: error hook result: %s\n", __LINE__, s1 = TO_STR(result)); free(s1);} errmsg = s7_get_output_string(sc, s7_current_error_port(sc)); if ((errmsg) && (*errmsg)) { if (strcmp(errmsg, "error!") != 0) fprintf(stderr, "%d: error: %s\n", __LINE__, errmsg); } else fprintf(stderr, "%d: no error!\n", __LINE__); s7_close_output_port(sc, s7_current_error_port(sc)); s7_set_current_error_port(sc, old_port); s7_gc_unprotect_at(sc, gc_loc); s7_eval_c_string(sc, "(set! (hook-functions *error-hook*) ())"); } s7_define_function(sc, "notify-C", scheme_set_notification, 2, 0, false, "called if notified-var is set!"); s7_define_variable(sc, "notified-var", s7_make_integer(sc, 0)); s7_symbol_set_access(sc, s7_make_symbol(sc, "notified-var"), s7_name_to_value(sc, "notify-C")); s7_eval_c_string(sc, "(set! notified-var 32)"); p = s7_name_to_value(sc, "notified-var"); if (s7_integer(p) != 32) {fprintf(stderr, "%d: sym set: %s\n", __LINE__, s1 = TO_STR(p)); free(s1);} if (s7_integer(set_val) != 32) {fprintf(stderr, "%d: sym val: %s\n", __LINE__, s1 = TO_STR(set_val)); free(s1);} if (set_sym != s7_make_symbol(sc, "notified-var")) {fprintf(stderr, "%d: sym: %s\n", __LINE__, s1 = TO_STR(set_sym)); free(s1);} return(0); } snd-16.1/tools/makexg.scm0000755000076400007640000033365512625110635013476 0ustar bilbil;;; makexg.scm creates the gtk2|3/gdk/pango/glib/cairo bindings using xgdata.scm, writes xg.c (define xg-file (open-output-file "xg.c")) (define-macro (hey . args) `(format xg-file ,@args)) (define (heyc arg) (display arg xg-file)) (define names (make-hash-table)) (define types ()) (define ints ()) (define dbls ()) (define funcs ()) (define casts ()) (define checks ()) (define atoms ()) (define strings ()) (define all-types ()) ;;; preset some types that are getting confused (set! types (list "GdkEventMotion*" "gdouble*" "GdkEventAny*" "GdkEvent*" "gboolean*" "cairo_t*" "cairo_font_options_t*" "PangoFontDescription*")) (set! all-types (list "GdkEventMotion*" "gdouble*" "GdkEventAny*" "GdkEvent*" "cairo_t*" "cairo_font_options_t*" "PangoFontDescription*")) (define idlers (list "g_source_remove" "g_idle_remove_by_data" "gtk_quit_remove" "gtk_quit_remove_by_data" ;"gtk_key_snooper_remove" )) (define no-c-to-xen (list "CellLayoutDataFunc" "GClosureNotify" "GDestroyNotify" "GError**" "GParamSpec*" "GQuark*" "GSignalAccumulator" "GSignalCMarshaller" "GSignalEmissionHook" "GSignalQuery*" "GSourceFunc" "GString*" "GTimeVal*" "GType*" "GdkBitmap**" "GdkDragProtocol*" "GdkEventButton*" "GdkEventConfigure*" "GdkEventCrossing*" "GdkEventDND*" "GdkEventExpose*" "GdkEventFocus*" "GdkEventMotion*" "GdkEventNoExpose*" "GdkEventProperty*" "GdkEventProximity*" "GdkEventScroll*" "GdkEventSelection*" "GdkEventSetting*" "GdkEventVisibility*" "GdkEventWindowState*" "GdkGCValues*" "GdkGeometry*" "GdkInterpType" "GdkModifierType*" "GdkPixbufDestroyNotify" "GdkScreen**" "GdkSegment*" "GdkWChar*" "GdkWMDecoration*" "GdkWindowAttr*" "GtkAccelLabel*" "GtkAccelMapForeach" "GtkAccessible*" "GtkActionEntry*" "GtkAlignment*" "GtkAllocation*" "GtkArrow*" "GtkAspectFrame*" "GtkBin*" "GtkBox*" "GtkButton*" "GtkButtonBox*" "GtkCalendar*" "GtkCellLayout*" "GtkCellLayoutDataFunc" "GtkCellRendererPixbuf*" "GtkCellRendererText*" "GtkCellRendererToggle*" "GtkCheckMenuItem*" "GtkClipboardTargetsReceivedFunc" "GtkCombo*" "GtkComboBox*" "GtkComboBoxEntry*" "GtkContainer*" "GtkCurve*" "GtkDialog*" "GtkDrawingArea*" "GtkEditable*" "GtkEventBox*" "GtkExpander*" "GtkFileChooser*" "GtkFileFilterFunc" "GtkFileSelection*" "GtkFixed*" "GtkFontButton*" "GtkFontSelection*" "GtkFontSelectionDialog*" "GtkFrame*" "GtkGammaCurve*" "GtkHandleBox*" "GtkIMContextSimple*" "GtkIMMulticontext*" "GtkIconLookupFlags" "GtkImage*" "GtkImageMenuItem*" "GtkInputDialog*" "GtkInvisible*" "GtkItem*" "GtkItemFactoryEntry*" "GtkLabel*" "GtkLayout*" "GtkMenuDetachFunc" "GtkMenuItem*" "GtkMenuShell*" "GtkMessageDialog*" "GtkMisc*" "GtkNotebook*" "GtkOptionMenu*" "GtkPackType*" "GtkPaned*" "GtkPlug*" "GtkProgressBar*" "GtkRadioButton*" "GtkRadioMenuItem*" "GtkRadioToolButton*" "GtkRange*" "GtkRcPropertyParser" "GtkRuler*" "GtkScale*" "GtkScrolledWindow*" "GtkSeparatorToolItem*" "GtkSettingsValue*" "GtkSocket*" "GtkSortType*" "GtkSpinButton*" "GtkStatusbar*" "GtkTable*" "GtkTextCharPredicate" "GtkTextTagTableForeach" "GtkTextView*" "GtkToggleActionEntry*" "GtkToggleButton*" "GtkToggleToolButton*" "GtkToolButton*" "GtkToolbar*" "GtkTreeDragDest*" "GtkTreeDragSource*" "GtkTreeModel**" "GtkTreeModelFilter*" "GtkTreeModelSort*" "GtkTreeSortable*" "GtkUIManagerItemType" "GtkViewport*" "PangoAnalysis*" "PangoAttrList**" "PangoFontDescription**" "PangoRectangle*" "gchar***" "gfloat*" "gint8*" "gssize" "guint16*" "gunichar*" "GtkFileChooserButton*" "GtkPathPriorityType" "GtkCellView*" "GValue*" "GtkAboutDialog*" "PangoAttrFilterFunc" "PangoScript*" "GtkMenuToolButton*" "GtkClipboardImageReceivedFunc" "PangoMatrix*" "GdkTrapezoid*" "GdkPangoRenderer*" "PangoRenderPart" "GLogFunc" "GError*" "guint32*" "GConnectFlags" "GSignalFlags" "GSignalMatchType" ;"GdkAxisUse" "GdkFillRule" "GdkGCValuesMask" "GdkPropMode" "GdkRgbDither" "GdkWMFunction" "GdkWindowEdge" "GdkWindowHints" "GtkAccelFlags" ; "GtkArrowType" "GtkAttachOptions" "GtkCellRendererState" "GtkCurveType" "GtkDestDefaults" "GtkDestroyNotify" "GtkDialogFlags" "GtkDirectionType" "GtkExpanderStyle" "GtkIconLookupFlags" ;"GtkMenuPositionFunc" "GtkPathType" "GtkSpinType" "GtkTextSearchFlags" "GtkTreeIterCompareFunc" "GtkTreeSelectionFunc" "GtkUIManagerItemType" "GtkWindowPosition" "PangoGlyph" "PangoUnderline" "gssize" "GtkMenuBar*" "GtkTranslateFunc" ;"GtkMenuPositionFunc" "GtkTreeIterCompareFunc" "GtkTreeSelectionFunc" "GtkDestroyNotify" "GtkAssistant*" "GtkRecentChooser*" "GtkRecentChooserMenu*" "GtkTextBufferSerializeFunc" "GtkTextBufferDeserializeFunc" "GtkRecentData*" "GtkNotebookWindowCreationFunc" "GtkUnit" "GtkPageSetupDoneFunc" "GtkPrintOperationPreview*" "GtkPrintSettingsFunc" "cairo_matrix_t*" "cairo_font_extents_t*" "cairo_text_extents_t*" "cairo_user_data_key_t*" "cairo_destroy_func_t" "GtkPrintOperationAction" "GtkTooltip*" "GtkCalendarDetailFunc" "GtkScaleButton*" "GtkEntryIconPosition" "GdkDragAction" "GdkImageType" "gdouble*" "GdkFill" "GdkSubwindowMode" "GdkLineStyle" "GdkCapStyle" "GdkJoinStyle" "GtkInfoBar*" "GtkSpinner*" "GtkToolShell*" "GtkToolPalette*" "GtkToolPaletteDragTargets" "GdkFunction" "GtkWrapBoxPacking" "GtkLinkButton*" "GtkActivatable*" "GtkOrientable*" "GtkCellArea*" "GdkNativeWindow" "GdkRectangle*" "PangoRenderer*" "cairo_glyph_t**" "cairo_text_cluster_t**" ; "cairo_text_cluster_flags_t" ; "cairo_rectangle_int_t" "cairo_rectangle_t*" "double*" "GtkContainerClass*" "GtkComboBoxText*" "GtkGrid*" "GtkScrollable*" "GtkSwitch*" "cairo_text_cluster_flags_t" "cairo_text_cluster_flags_t*" "cairo_rectangle_int_t*" "GtkOverlay*" "cairo_pattern_t**" "GtkStyleProperties*" "GtkSymbolicColor*" "GtkWidgetPath*" "GtkFontChooser*" "GtkFontChooserDialog*" "GdkModifierIntent" "guint**" "GtkApplication*" "GVariant*" "GtkApplicationWindow*" "GdkEventKey*" "GtkColorChooser*" "GtkLevelBar*" "GtkMenuButton*" "GNormalizeMode" ; "GIcon*" "GBytes" "GtkPlacesSidebar*" "GtkStackSwitcher*" "GtkRevealer*" "GtkHeaderBar*" "GtkListBox*" "GtkSearchBar*" "GtkFlowBox*" "GtkActionBar*" "GtkPopover*" "GtkGestureDrag*" "GtkGesturePan*" "GtkGestureMultiPress*" "GtkGestureRotate*" "GtkGestureSingle*" "GtkGestureSwipe*" "GtkGestureZoom*" "GtkGestureController*" "GtkEventController*" "GtkGLArea*" "GtkStyleContext*" "GtkPopoverMenu*" "GtkSearchEntry*" "GtkStackSidebar*" )) (define no-xen-p (list "GdkXEvent*" "GdkVisualType*" "GError*" "GSignalInvocationHint*" "GtkAccelGroupEntry*" "GtkIconSize*" "AtkObject*" "GtkWidgetAuxInfo*" "PangoFontFamily**" "PangoFontset*" "PangoEngineShape*" "PangoLayoutRun*" "GdkDeviceAxis*" "GdkDeviceKey*" "GtkWidget**" "GtkLabelSelectionInfo*" "GtkItemFactoryCallback" "GtkNotebookPage*" "GtkRangeLayout*" "GData*" "GtkRangeStepTimer*" "GtkRcContext*" "GdkGC**" "GdkPixmap**" "GArray*" "GtkTextBTree*" "GtkTextLogAttrCache*" "GtkTableRowCol*" "GtkAccelMap*" "GtkTooltipsData*" "PangoScript" "PangoFontFace**" "GValue*" "GdkByteOrder" "GdkCrossingMode" "GdkEventType" "GdkGrabStatus" "GdkNotifyType" ;"GdkOverlapType" "GdkScrollDirection" "GdkSettingAction" "GdkVisibilityState" "GdkWindowState" "GdkWindowType" "GtkImageType" "GtkTreeModelFlags" "gint8" "gshort" "guint8" "lambda" "gboolean*" "time_t" ;"GtkWindowGroup*" "GtkSettings*" ;"GdkDevice*" "GtkScaleButton*" "GtkPrintOperationResult" "GtkPrintStatus" "GtkSizeRequestMode" "GdkEventAny*" "GdkDeviceManager*" "cairo_font_type_t" "cairo_pattern_type_t" "cairo_surface_type_t" "cairo_bool_t" "cairo_region_overlap_t" "glong" "double" )) (define no-xen-to-c (list "GdkXEvent*" "GSignalInvocationHint*" "GdkVisualType*" "GError*" "GtkAccelGroupEntry*" "GtkIconSize*" "AtkObject*" "GtkWidgetAuxInfo*" "PangoFontFamily**" "PangoFontset*" "PangoEngineShape*" "PangoLayoutRun*" "GdkDeviceAxis*" "GdkDeviceKey*" "GtkWidget**" "GtkItemFactoryCallback" "GtkLabelSelectionInfo*" "GtkNotebookPage*" "GtkRangeLayout*" "GtkRangeStepTimer*" "GData*" "GtkRcContext*" "GdkGC**" "GdkPixmap**" "GArray*" "GtkTableRowCol*" "GtkTextBTree*" "GtkTextLogAttrCache*" "GtkAccelMap*" "GtkTooltipsData*" "PangoScript" "PangoFontFace**" "GValue*" "GdkByteOrder" "GdkCrossingMode" "GdkEventType" "GdkGrabStatus" "GdkNotifyType" ;"GdkOverlapType" "GdkScrollDirection" "GdkSettingAction" "GdkVisibilityState" "GdkWindowState" "GdkWindowType" "GtkImageType" "GtkTreeModelFlags" "etc" "gshort" "gboolean*" ;"GtkWindowGroup*" "time_t" "GtkSettings*" ;"GdkDevice*" "GtkScaleButton*" "GtkPrintOperationResult" "GtkPrintStatus" "GdkDeviceManager*" "GdkEventAny*" "GtkSizeRequestMode" "cairo_surface_type_t" "cairo_pattern_type_t" "cairo_font_type_t" "cairo_bool_t" "cairo_region_overlap_t" "cairo_device_type_t" "glong" )) (define (cadr-str data) (let ((sp1 (char-position #\space data))) (let ((sp2 (char-position #\space data (+ sp1 1)))) (if sp2 (substring data (+ sp1 1) sp2) (substring data sp1))))) (define (caddr-str data) (let ((sp1 (char-position #\space data))) (let ((sp2 (char-position #\space data (+ sp1 1)))) (let ((sp3 (char-position #\space data (+ sp2 1)))) (if sp3 (substring data (+ sp2 1)) (substring data sp2)))))) (define (car-str data) (let ((sp (char-position #\space data))) (if sp (substring data 0 sp) data))) (define (cdr-str data) (let ((sp (char-position #\space data))) (if sp (substring data (+ sp 1)) data))) (define (remove-if p l) (cond ((null? l) ()) ((p (car l)) (remove-if p (cdr l))) (else (cons (car l) (remove-if p (cdr l)))))) (define (ref-arg? arg) (and (= (length arg) 3) (string? (caddr arg)))) (define (null-arg? arg) (and (= (length arg) 3) (eq? (caddr arg) 'null))) (define (opt-arg? arg) (and (= (length arg) 3) (eq? (caddr arg) 'opt))) (define (settable-field? arg) (and (= (length arg) 3) (eq? (caddr arg) 'set))) (define (ref-args args) (let ((ctr 0)) (for-each (lambda (arg) (if (ref-arg? arg) (set! ctr (+ ctr 1)))) args) ctr)) (define (opt-args args) (let ((ctr 0)) (for-each (lambda (arg) (if (opt-arg? arg) (set! ctr (+ ctr 1)))) args) ctr)) (define (deref-type arg) (let ((type (car arg))) (substring type 0 (- (length type) 1)))) (define (deref-element-type arg) (let ((type (car arg))) (substring type 0 (- (length type) 2)))) (define (deref-name arg) (let ((name (cadr arg))) (string-append "ref_" name))) (define (derefable type) (let ((st (char-position #\* type))) (and st (char-position #\* type (+ st 1))))) (define (has-stars type) (char-position #\* type)) (define (no-stars type) (let ((len (length type)) (val (copy type))) (do ((i 0 (+ i 1))) ((= i len) val) (if (char=? (val i) #\*) (set! (val i) #\_))))) (define (no-arg-or-stars name) (let ((pos (char-position "(*" name))) (if pos (substring name 0 pos) name))) (define (parse-args args extra) (let ((data ()) (sp -1) (type #f) (len (length args))) (if (string=? args "void") () (do ((i 0 (+ i 1))) ((= i len) (reverse data)) (let ((ch (args i))) (if (or (char=? ch #\space) (= i (- len 1))) (begin (if type (let ((given-name (substring args (+ 1 sp) (if (= i (- len 1)) (+ i 1) i))) (reftype #f)) (if (char=? (given-name 0) #\@) (set! data (cons (list type (substring given-name 1 (length given-name)) 'null) data)) (if (char=? (given-name 0) #\#) (set! data (cons (list type (substring given-name 1 (length given-name)) 'opt) data)) (if (or (char=? (given-name 0) #\[) (char=? (given-name 0) #\{) (char=? (given-name 0) #\|)) (begin (set! reftype (deref-type (list type))) (set! data (cons (list type (substring given-name 1 (- (length given-name) 1)) given-name) data))) (if (char=? (given-name 0) #\&) (set! data (cons (list type (substring given-name 1 (length given-name)) 'set) data)) (set! data (cons (list type given-name) data)))))) (if reftype (set! type reftype)) (if (not (member type all-types)) (begin (set! all-types (cons type all-types)) (case extra ((g-2.14) (set! types-2.14 (cons type types-2.14))) ((g-2.16) (set! types-2.16 (cons type types-2.16))) ((g-2.18) (set! types-2.18 (cons type types-2.18))) ((g-2.20) (set! types-2.20 (cons type types-2.20))) ((g-3.0) (set! types-3.0 (cons type types-3.0))) ((g-3.2) (set! types-3.2 (cons type types-3.2))) ((g-3.4) (set! types-3.4 (cons type types-3.4))) ((g-3.6) (set! types-3.6 (cons type types-3.6))) ((g-3.8) (set! types-3.8 (cons type types-3.8))) ((g-3.10) (set! types-3.10 (cons type types-3.10))) ((g-3.12) (set! types-3.12 (cons type types-3.12))) ((g-3.14) (set! types-3.14 (cons type types-3.14))) ((g-3.16) (set! types-3.16 (cons type types-3.16))) ((g-3.18) (set! types-3.18 (cons type types-3.18))) ((g-3.20) (set! types-3.20 (cons type types-3.20))) ((cairo) (set! cairo-types (cons type cairo-types))) ((cairo-810) (set! cairo-types-810 (cons type cairo-types-810))) ((cairo-912) (set! cairo-types-912 (cons type cairo-types-912))) (else (if (not (member type types)) (set! types (cons type types))))))) (set! type #f)) (if (> i (+ 1 sp)) (set! type (substring args (+ 1 sp) i)))) (set! sp i)))))))) (define callbacks (list ; (list 'lambda2 ; unnamed gdk_window_invalidate_maybe_recurse argument (2.90.6 now) ; "gboolean" ; "child_func" ; (parse-args "GdkWindow* window lambda_data func_info" 'callback) ; 'temporary) (list 'lambda3 ; unnamed gtk_accel_group_find argument "gboolean" "find_func" (parse-args "GtkAccelKey* key GClosure* closure lambda_data func_info" 'callback) 'temporary) ; ?? (list 'GtkCallback "void" "func2" (parse-args "GtkWidget* w lambda_data func_info" 'callback) 'temporary) (list 'GSourceFunc "gboolean" "timer_func" (parse-args "lambda_data func_info" 'callback) 'semi-permanent) (list 'GtkDestroyNotify "void" "destroy_func" (parse-args "lambda_data func_info" 'callback) 'permanent) (list 'GdkFilterFunc "GdkFilterReturn" "filter_func" (parse-args "GdkXEvent* xevent GdkEvent* event lambda_data func_info" 'callback) 'permanent) (list 'GdkEventFunc "void" "event_func" (parse-args "GdkEvent* event lambda_data func_info" 'callback) 'permanent) ; (list 'GdkSpanFunc ; "void" ; "span_func" ; (parse-args "GdkSpan* span lambda_data func_info" 'callback) ; 'temporary) ; (list 'GtkFunction ; "gboolean" ; "func1" ; (parse-args "lambda_data func_info" 'callback) ; 'semi-permanent) ; (list 'GtkKeySnoopFunc ; "gint" ; "snoop_func" ; (parse-args "GtkWidget* widget GdkEventKey* event lambda_data func_info" 'callback) ; 'semi-permanent) (list 'GtkMenuPositionFunc "void" "menu_position_func" (parse-args "GtkMenu* menu gint* [x] gint* [y] gboolean* [push] lambda_data func_info" 'callback) 'permanent) (list 'GtkTextTagTableForeach "void" "text_tag_table_foreach" (parse-args "GtkTextTag* tag lambda_data func_info" 'callback) 'temporary) (list 'GtkAccelMapForeach "void" "accel_map_foreach" (parse-args "lambda_data func_info gchar* accel_path guint accel_key GdkModifierType accel_mods gboolean changed" 'callback) 'temporary) (list 'GtkTreeModelForeachFunc "gboolean" "model_func" (parse-args "GtkTreeModel* model GtkTreePath* path GtkTreeIter* iter lambda_data func_info" 'callback) 'temporary) (list 'GtkTreeSelectionForeachFunc "void" "tree_selection_func" (parse-args "GtkTreeModel* model GtkTreePath* path GtkTreeIter* iter lambda_data func_info" 'callback) 'temporary) (list 'GtkClipboardReceivedFunc "void" "clip_received" (parse-args "GtkClipboard* clipboard GtkSelectionData* selection_data lambda_data func_info" 'callback) 'temporary) (list 'GtkClipboardTextReceivedFunc "void" "clip_text_received" (parse-args "GtkClipboard* clipboard gchar* text lambda_data func_info" 'callback) 'temporary) (list 'GtkClipboardTargetsReceivedFunc "void" "clip_targets_received" (parse-args "GtkClipboard* clipboard GdkAtom* atoms gint n_atoms lambda_data func_info" 'callback) 'temporary) ; (list 'GtkMenuDetachFunc ; "void" ; "menu_detach_func" ; (parse-args "GtkWidget* attach_widget GtkMenu* menu" 'callback) ; 'permanent) ;;; detach func is not passed user-data, so it would have to be implemented by hand (list 'GtkTextCharPredicate "gboolean" "text_char_predicate" (parse-args "gunichar ch lambda_data func_info" 'callback) 'temporary) (list 'GtkTreeViewColumnDropFunc "gboolean" "tree_column" (parse-args "GtkTreeView* tree_view GtkTreeViewColumn* column GtkTreeViewColumn* prev_column GtkTreeViewColumn* next_column lambda_data func_info" 'callback) 'temporary) (list 'GtkTreeViewMappingFunc "void" "tree_mapping" (parse-args "GtkTreeView* tree_view GtkTreePath* path lambda_data func_info" 'callback) 'temporary) (list 'GtkTreeViewSearchEqualFunc "gboolean" "tree_search" (parse-args "GtkTreeModel* model gint column gchar* key GtkTreeIter* iter lambda_data func_info" 'callback) 'temporary) (list 'GtkTreeCellDataFunc "void" "cell_data" (parse-args "GtkTreeViewColumn* tree_column GtkCellRenderer* cell GtkTreeModel* tree_model GtkTreeIter* iter lambda_data func_info" 'callback) 'permanent) (list 'GtkTreeIterCompareFunc "gint" "iter_compare" (parse-args "GtkTreeModel* model GtkTreeIter* a GtkTreeIter* b lambda_data func_info" 'callback) 'permanent) (list 'GtkTreeSelectionFunc "gboolean" "tree_selection" (parse-args "GtkTreeSelection* selection GtkTreeModel* model GtkTreePath* path gboolean path_currently_selected lambda_data func_info" 'callback) 'permanent) (list 'GtkClipboardGetFunc "void" "clip_get" (parse-args "GtkClipboard* clipboard GtkSelectionData* selection_data guint info lambda_data func_info" 'callback) 'permanent) (list 'GtkClipboardClearFunc "void" "clip_clear" (parse-args "GtkClipboard* clipboard lambda_data func_info" 'callback) 'permanent) ; GCallback 'lambda can be whatever is indicated by caller (2 or more args) (list 'GtkFileFilterFunc "gboolean" "file_filter" (parse-args "GtkFileFilterInfo* info lambda_data func_info" 'callback) 'permanent) (list 'GtkEntryCompletionMatchFunc "gboolean" "entry_completion_match" (parse-args "GtkEntryCompletion* completion gchar* key GtkTreeIter* iter lambda_data func_info" 'callback) 'permanent) (list 'GtkTreeViewRowSeparatorFunc "gboolean" "row_separator" (parse-args "GtkTreeModel* model GtkTreeIter* iter lambda_data func_info" 'callback) 'permanent) (list 'GtkIconViewForeachFunc "void" "icon_view_foreach" (parse-args "GtkIconView* icon_view GtkTreePath* path lambda_data func_info" 'callback) 'permanent) (list 'GtkClipboardImageReceivedFunc "void" "clip_image_received" (parse-args "GtkClipboard* clipboard GdkPixbuf* pixbuf lambda_data func_info" 'callback) ; 'callback) ;; these arg types are not new in 256, but this parse-args precedes the basic ones, so comment out the callback ;; the problem here (and below callback) is that parse-args sees a new type (new to it so far), ;; and chooses which type list to put it on based on the "extra" arg -- since these types ;; are not new in version 2.5.6, we don't want the callback flag to sequester them ;; on the 256-type list. 'permanent) (list 'GLogFunc "void" "g_message_log_func" (parse-args "gchar* domain GLogLevelFlags log_level gchar* message lambda_data func_info" 'callback) 'permanent) (list 'GtkClipboardRichTextReceivedFunc "void" "clip_rich_text_received" (parse-args "GtkClipboard* clipboard GdkAtom format guint8* text gsize length lambda_data func_info" 'callback); 'callback) ;; guint8* is const 'permanent-gcc) ; (list 'GtkRecentFilterFunc ; "gboolean" ; "recent_filter" ; (parse-args "GtkRecentFilterInfo* filter_info lambda_data func_info" 'callback) ; ;; const filter info ; 'permanent-gcc) (list 'GtkTreeViewSearchPositionFunc "void" "search_position" (parse-args "GtkTreeView* tree_view GtkWidget* search_dialog lambda_data func_info" 'callback) 'permanent) (list 'GtkAssistantPageFunc "gint" "page_func" (parse-args "gint current_page lambda_data func_info" 'callback) 'permanent) ; (list 'GtkLinkButtonUriFunc ; "void" ; "link_button_uri" ; (parse-args "GtkLinkButton* button gchar* link lambda_data func_info" 'callback) ; ;; const gchar *link ; 'permanent) (list 'GtkRecentSortFunc "gint" "recent_sort" (parse-args "GtkRecentInfo* a GtkRecentInfo* b lambda_data func_info" 'callback) 'permanent) )) (define callback-name car) (define callback-type cadr) (define callback-func caddr) (define callback-args cadddr) (define (callback-gc func) (func 4)) (define (find-callback test) (define (find-callback-1 test funcs) (and (pair? funcs) (or (test (car funcs)) (find-callback-1 test (cdr funcs))))) (find-callback-1 test callbacks)) (define direct-types (list (cons "void" #f) (cons "int" "INT") (cons "gint" "INT") (cons "gint32" "INT") (cons "guint32" "ULONG") (cons "gunichar" "ULONG") (cons "gunichar2" "INT") (cons "gulong" "ULONG") (cons "glong" "INT") (cons "gboolean" "BOOLEAN") (cons "gdouble" "DOUBLE") (cons "double" "DOUBLE") (cons "gfloat" "DOUBLE") (cons "char" "CHAR") (cons "gchar" "CHAR") (cons "char*" "String") (cons "gchar*" "String") (cons "guchar*" "String") ; added 30-Jul-02 then removed then put back... -- this is a real mess! (cons "guint" "ULONG") (cons "guint16" "INT") (cons "gint" "INT") (cons "gshort" "INT") ; (cons "gint16" "INT") ; (cons "guint8" "INT") (cons "guchar" "INT") (cons "gint8" "INT") (cons "gssize" "INT") (cons "gsize" "INT") (cons "xen" #t) (cons "etc" #t) ;; since the various enums are handled directly (as ints) below, the associated types ;; need also to be direct (so that (= GDK_WHATEVER func-return-val) makes sense) ;; or should the constants be tagged? -- seems kinda silly (cons "GType" "ULONG") (cons "GQuark" "ULONG") (cons "GConnectFlags" "INT") (cons "GSignalMatchType" "INT") (cons "GSignalFlags" "INT") (cons "GdkInputCondition" "INT") (cons "GdkCursorType" "INT") (cons "GdkDragAction" "INT") (cons "GdkDragProtocol" "INT") ;(cons "GdkAxisUse" "INT") (cons "GdkGCValuesMask" "INT") (cons "GdkFill" "INT") (cons "GdkFunction" "INT") (cons "GdkLineStyle" "INT") (cons "GdkCapStyle" "INT") (cons "GdkJoinStyle" "INT") (cons "GdkGrabStatus" "INT") (cons "GdkEventMask" "INT") (cons "GdkImageType" "INT") ;(cons "GdkInputSource" "INT") ;(cons "GdkInputMode" "INT") (cons "GdkNativeWindow" "ULONG") (cons "GdkModifierType" "INT") ;(cons "GdkExtensionMode" "INT") (cons "PangoDirection" "INT") (cons "GdkRgbDither" "INT") (cons "GdkPixbufAlphaMode" "INT") (cons "GdkPropMode" "INT") (cons "GdkFillRule" "INT") ;(cons "GdkOverlapType" "INT") (cons "GdkVisualType" "INT") (cons "GdkWindowType" "INT") (cons "GdkWindowState" "INT") (cons "GdkWMDecoration" "INT") (cons "GdkWMFunction" "INT") (cons "GdkWindowEdge" "INT") (cons "GtkAccelFlags" "INT") (cons "GtkArrowType" "INT") (cons "GtkShadowType" "INT") (cons "GtkButtonBoxStyle" "INT") (cons "GtkPathType" "INT") (cons "GtkPathPriorityType" "INT") (cons "GtkPackType" "INT") (cons "GtkReliefStyle" "INT") (cons "GtkCalendarDisplayOptions" "INT") (cons "GtkCellRendererState" "INT") (cons "GtkResizeMode" "INT") (cons "GtkCurveType" "INT") (cons "GtkDialogFlags" "INT") (cons "GtkDestDefaults" "INT") (cons "GtkPositionType" "INT") (cons "GtkTextDirection" "INT") (cons "GtkStateFlags" "INT") (cons "GtkImageType" "INT") ; (cons "GtkIconSize" "INT") (cons "GtkJustification" "INT") (cons "GtkMessageType" "INT") (cons "GtkButtonsType" "INT") (cons "GtkTargetFlags" "INT") ;(cons "GtkProgressBarOrientation" "INT") (cons "GtkUpdateType" "INT") (cons "GtkMetricType" "INT") (cons "GtkPolicyType" "INT") (cons "GtkCornerType" "INT") (cons "GtkSizeGroupMode" "INT") (cons "GtkSpinButtonUpdatePolicy" "INT") (cons "GtkSpinType" "INT") (cons "GtkOrientation" "INT") (cons "GtkExpanderStyle" "INT") (cons "GtkAttachOptions" "INT") (cons "GtkTextSearchFlags" "INT") (cons "GtkTextWindowType" "INT") (cons "GtkWrapMode" "INT") (cons "GtkWindowPosition" "INT") (cons "GtkTreeViewColumnSizing" "INT") (cons "GtkTreeViewDropPosition" "INT") ;(cons "GtkToolbarChildType" "INT") (cons "GtkToolbarStyle" "INT") (cons "GtkTreeModelFlags" "INT") (cons "GtkSelectionMode" "INT") (cons "GtkSortType" "INT") (cons "GtkDirectionType" "INT") (cons "GtkWindowType" "INT") (cons "GdkWindowTypeHint" "INT") (cons "GdkGravity" "INT") (cons "GdkWindowHints" "INT") (cons "GtkSizeRequestMode" "INT") (cons "GtkEntryIconPosition" "INT") (cons "PangoAttrType" "INT") (cons "PangoStyle" "INT") (cons "PangoWeight" "INT") (cons "PangoVariant" "INT") (cons "PangoStretch" "INT") (cons "PangoUnderline" "INT") (cons "PangoFontMask" "INT") (cons "PangoWrapMode" "INT") (cons "PangoEllipsizeMode" "INT") (cons "PangoAlignment" "INT") (cons "PangoCoverageLevel" "INT") (cons "PangoGlyph" "ULONG") (cons "PangoScript" "INT") (cons "GdkEventType" "INT") (cons "GdkVisibilityState" "INT") (cons "GdkScrollDirection" "INT") (cons "GdkCrossingMode" "INT") (cons "GdkNotifyType" "INT") (cons "GdkSettingAction" "INT") (cons "GdkByteOrder" "INT") ;(cons "GdkWChar" "ULONG") (cons "GtkFileChooserAction" "INT") (cons "GtkUIManagerItemType" "INT") (cons "GtkFileFilterFlags" "INT") (cons "GtkIconLookupFlags" "INT") (cons "GtkIconThemeError" "INT") (cons "GtkScrollStep" "INT") (cons "GLogLevelFlags" "INT") (cons "GtkPackDirection" "INT") (cons "GtkIconViewDropPosition" "INT") (cons "GtkFileChooserConfirmation" "INT") (cons "GtkFileChooserProp" "INT") (cons "GtkFileChooserError" "INT") (cons "GtkLicense" "INT") (cons "GtkWrapAllocationMode" "INT") (cons "GtkWrapBoxSpreading" "INT") (cons "GtkWrapBoxPacking" "INT") (cons "GtkSensitivityType" "INT") (cons "GtkTextBufferTargetInfo" "INT") (cons "GtkAssistantPageType" "INT") (cons "GtkCellRendererAccelMode" "INT") (cons "GtkRecentSortType" "INT") (cons "GtkRecentChooserError" "INT") (cons "GtkRecentFilterFlags" "INT") (cons "GtkRecentManagerError" "INT") (cons "GtkTreeViewGridLines" "INT") (cons "GNormalizeMode" "INT") (cons "gunichar" "INT") (cons "gunichar*" "String") ;(cons "GtkPrintCapabilities" "INT") (cons "GtkPrintStatus" "INT") (cons "GtkPrintOperationResult" "INT") (cons "GtkPrintOperationAction" "INT") (cons "GtkPrintError" "INT") (cons "GtkRevealerTransitionType" "INT") (cons "GtkStackTransitionType" "INT") (cons "GtkTextViewLayer" "INT") (cons "GdkTouchpadGesturePhase" "INT") (cons "GtkLevelBarMode" "INT") (cons "GdkWindowClass" "INT") (cons "GdkColorspace" "INT") (cons "GtkNotebookTab" "INT") (cons "GdkPixbufError" "INT") (cons "PangoRenderPart" "INT") (cons "GtkDragResult" "INT") (cons "GtkToolPaletteDragTargets" "INT") (cons "GtkInputPurpose" "INT") (cons "GtkInputHints" "INT") (cons "GdkFullscreenMode" "INT") (cons "GtkBaselinePosition" "INT") (cons "GtkPlacesOpenFlags" "INT") (cons "GtkRegionFlags" "INT") (cons "cairo_status_t" "INT") (cons "cairo_content_t" "INT") (cons "cairo_operator_t" "INT") (cons "cairo_antialias_t" "INT") (cons "cairo_fill_rule_t" "INT") (cons "cairo_line_cap_t" "INT") (cons "cairo_line_join_t" "INT") (cons "cairo_font_slant_t" "INT") (cons "cairo_font_weight_t" "INT") (cons "cairo_subpixel_order_t" "INT") (cons "cairo_hint_style_t" "INT") (cons "cairo_hint_metrics_t" "INT") (cons "cairo_font_type_t" "INT") (cons "cairo_path_data_type_t" "INT") (cons "cairo_surface_type_t" "INT") (cons "cairo_format_t" "INT") (cons "cairo_pattern_type_t" "INT") (cons "cairo_extend_t" "INT") (cons "cairo_filter_t" "INT") (cons "cairo_bool_t" "INT") (cons "bool" "BOOLEAN") ;(cons "PangoRenderPart" "INT") (cons "PangoTabAlign" "INT") (cons "GtkWidgetHelpType" "INT") (cons "GtkWidgetFlags" "INT") (cons "GtkRcTokenType" "INT") (cons "GtkTextExtendSelection" "INT") ;(cons "GtkNotebookTab" "INT") (cons "GtkScrollType" "INT") (cons "GtkMovementStep" "INT") (cons "GtkMenuDirectionType" "INT") (cons "GtkDeleteType" "INT") (cons "GtkResponseType" "INT") (cons "GdkInterpType" "INT") ;(cons "GdkPixbufError" "INT") ;(cons "GdkColorspace" "INT") (cons "GdkWindowAttributesType" "INT") ;(cons "GdkWindowClass" "INT") (cons "GdkStatus" "INT") (cons "GdkSubwindowMode" "INT") (cons "GdkPropertyState" "INT") (cons "GtkScrollablePolicy" "INT") (cons "GdkModifierIntent" "INT") (cons "GtkAlign" "INT") (cons "GdkGLFlags" "INT") (cons "GtkShortcutType" "INT") )) (define (c-to-xen-macro-name typ str) (if (string=? str "INT") "C_int_to_Xen_integer" (if (string=? str "DOUBLE") "C_double_to_Xen_real" (if (string=? str "BOOLEAN") "C_bool_to_Xen_boolean" (if (string=? str "ULONG") "C_ulong_to_Xen_ulong" (if (string=? str "String") (if (string=? (car typ) "guchar*") "C_to_Xen_String" "C_string_to_Xen_string") (format #f "~A unknown" str))))))) (define (xen-to-c-macro-name str) (if (string=? str "INT") "Xen_integer_to_C_int" (if (string=? str "DOUBLE") "Xen_real_to_C_double" (if (string=? str "BOOLEAN") "Xen_boolean_to_C_bool" (if (string=? str "ULONG") "Xen_ulong_to_C_ulong" (if (string=? str "String") "Xen_string_to_C_string" (format #f "~A unknown" str))))))) (define (type-it type) (let ((typ (assoc type direct-types))) (if typ (when (cdr typ) (if (string? (cdr typ)) (begin (if (not (member type no-c-to-xen)) (hey "#define C_to_Xen_~A(Arg) ~A(Arg)~%" (no-stars (car typ)) (c-to-xen-macro-name typ (cdr typ)))) (if (not (member type no-xen-to-c)) (hey "#define Xen_to_C_~A(Arg) (~A)(~A(Arg))~%" (no-stars (car typ)) (car typ) (xen-to-c-macro-name (cdr typ)))) (if (not (member type no-xen-p)) (hey "#define Xen_is_~A(Arg) Xen_is_~A(Arg)~%" (no-stars (car typ)) (if (string=? (cdr typ) "INT") "integer" (if (string=? (cdr typ) "DOUBLE") "number" (if (string=? (cdr typ) "ULONG") "ulong" (apply string (map char-downcase (cdr typ))))))))) (if (not (cdr typ)) ; void special case (begin (if (not (member type no-xen-p)) (hey "#define Xen_is_~A(Arg) 1~%" (no-stars (car typ)))) (if (not (member type no-xen-to-c)) (hey "#define Xen_to_C_~A(Arg) ((gpointer)Arg)~%" (no-stars (car typ))))) (if (string=? type "etc") ; xen special case (hey "#define Xen_is_etc(Arg) (Xen_is_list(Arg))~%") (begin (if (not (member type no-xen-p)) (hey "#define Xen_is_~A(Arg) ((Xen_is_list(Arg)) && (Xen_list_length(Arg) > 2))~%" (no-stars (car typ)))) (if (not (member type no-xen-to-c)) (hey "#define Xen_to_C_~A(Arg) ((gpointer)Arg)~%" (no-stars (car typ))))))))) (if (and (not (string=? type "lambda")) (not (string=? type "lambda_data")) (not (string=? type "GError*")) (not (find-callback (lambda (func) (string=? type (symbol->string (car func)))))) (not (string=? type "GCallback"))) (hey "Xm_type~A(~A, ~A)~%" (if (or (has-stars type) (string=? type "gpointer") (string=? type "GClosureNotify")) (if (member type no-c-to-xen) "_Ptr_1" (if (member type no-xen-p) (if (member type no-xen-to-c) "_Ptr_2" "_Ptr_no_P") (if (or (string=? type "guint8*") (string=? type "GtkRecentFilterInfo*")) "_Ptr_const" "_Ptr"))) (if (member type no-c-to-xen) "_1" (if (member type no-xen-p) (if (member type no-xen-to-c) "_no_p_2" "_no_p") ""))) (no-stars type) type))))) (define (func-type strs) (call-with-exit (lambda (return) (for-each (lambda (arg) (let ((callb (find-callback (lambda (func) (and (string=? (car arg) (symbol->string (callback-name func))) func))))) (if callb (return (callback-name callb)) (if (string=? (car arg) "lambda") (return 'lambda) (if (string=? (car arg) "GCallback") (return 'GCallback)))))) strs) 'fnc))) (define (no-way str arg) (format #t str arg)) (define-macro (make-fnc vname) (let* ((cfnc-name (string-append "CFNC-" vname)) (cfnc (string->symbol cfnc-name)) (g-fnc (string->symbol (string-append "g-" vname))) (types (string->symbol (string-append "types-" vname))) (funcs (string->symbol (string-append "funcs-" vname))) (strfnc (string->symbol (string-append "CSTR-" vname))) (strings (string->symbol (string-append "strings-" vname))) (names (string->symbol (string-append "names-" vname))) (intfnc (string->symbol (string-append "CINT-" vname))) (ints (string->symbol (string-append "ints-" vname))) (castfnc (string->symbol (string-append "CCAST-" vname))) (casts (string->symbol (string-append "casts-" vname))) (chkfnc (string->symbol (string-append "CCHK-" vname))) (checks (string->symbol (string-append "checks-" vname))) (withfnc (string->symbol (string-append "with-" vname))) ) `(begin (define ,funcs ()) (define ,strings ()) (define ,ints ()) (define ,names ()) (define ,types ()) (define ,casts ()) (define ,checks ()) (define* (,cfnc data spec) ; CFNC-2.12 (let ((name (cadr-str data)) (args (caddr-str data))) (if (hash-table-ref names name) (format #t "~A: ~A ~A~%" ',cfnc name data) (let ((type (car-str data))) (if (not (member type all-types)) (begin (set! all-types (cons type all-types)) (set! ,types (cons type ,types)))) (let ((strs (parse-args args ',g-fnc))) (if spec (set! ,funcs (cons (list name type strs args spec) ,funcs)) (set! ,funcs (cons (list name type strs args) ,funcs))) (hash-table-set! names name (func-type strs))))))) (define (,strfnc name) ; CSTR-2.12 (if (assoc name ,names) (format #t "~A ~A~%" name ',strfnc) (begin (set! ,strings (cons name ,strings)) (set! ,names (cons (cons name 'string) ,names))))) (define* (,intfnc name type) ; CINT-2.12 (save-declared-type type) (if (and type (not (assoc type direct-types))) (format *stderr* "could be direct int: ~S (~S)~%" type name)) (if (hash-table-ref names name) (format #t "~A ~A~%" name ',intfnc) (begin (set! ,ints (cons name ,ints)) (hash-table-set! names name 'int)))) (define (,castfnc name type) ; CCAST-2.12 (if (hash-table-ref names name) (format #t "~A ~A~%" name ',castfnc) (begin (set! ,casts (cons (list name type) ,casts)) (hash-table-set! names name 'def)))) (define (,chkfnc name type) ; CCHK-2.12 (if (hash-table-ref names name) (format #t "~A ~A~%" name ',chkfnc) (begin (set! ,checks (cons (list name type) ,checks)) (hash-table-set! names name 'def)))) (define (,withfnc dpy thunk) ; with-2.12 (dpy (string-append "#if GTK_CHECK_VERSION(" (substring ,vname 0 1) ", " (substring ,vname 2) ", 0)~%")) (thunk) (dpy "#endif~%~%")) ))) (make-fnc "2.14") (make-fnc "2.16") (make-fnc "2.18") (make-fnc "2.20") (make-fnc "3.0") (make-fnc "3.2") (make-fnc "3.4") (make-fnc "3.6") (make-fnc "3.8") (make-fnc "3.10") (make-fnc "3.12") (make-fnc "3.14") (make-fnc "3.16") (make-fnc "3.18") (make-fnc "3.20") (define cairo-funcs ()) (define cairo-png-funcs ()) (define cairo-ints ()) (define cairo-types ()) (define cairo-funcs-810 ()) (define cairo-ints-810 ()) (define cairo-types-810 ()) (define cairo-funcs-912 ()) (define cairo-ints-912 ()) (define cairo-types-912 ()) (define cairo-strings-912 ()) (define cairo-names-912 ()) (define* (CFNC data spec spec-data) ; 'const -> const for arg cast, 'etc for ... args, 'free -> must free C val before return (let ((name (cadr-str data)) (args (caddr-str data))) (if (hash-table-ref names name) (no-way "~A CFNC~%" name) (let ((type (car-str data))) (if (not (member type all-types)) (set! all-types (cons type all-types))) (if (not (member type types)) (set! types (cons type types))) (let ((strs (parse-args args 'ok))) (if spec (set! funcs (cons (list name type strs args spec spec-data) funcs)) (set! funcs (cons (list name type strs args) funcs))) (hash-table-set! names name (func-type strs))))))) (define (CFNC-PA data min-len max-len types) (CFNC data 'etc (list min-len max-len types))) (define (CFNC-23-PA data min-len max-len types) (CFNC data 'etc (list min-len max-len types))) (define* (CAIRO-FUNC data spec) (let ((name (cadr-str data)) (args (caddr-str data))) (if (hash-table-ref names name) (no-way "CAIRO-FUNC: ~A~%" (list name data)) (let ((type (car-str data))) (if (not (member type all-types)) (begin (set! all-types (cons type all-types)) (set! cairo-types (cons type cairo-types)))) (let ((strs (parse-args args 'cairo))) (if spec (set! cairo-funcs (cons (list name type strs args spec) cairo-funcs)) (set! cairo-funcs (cons (list name type strs args) cairo-funcs))) (hash-table-set! names name (func-type strs))))))) (define* (CAIRO-PNG-FUNC data spec) (let ((name (cadr-str data)) (args (caddr-str data))) (if (hash-table-ref names name) (no-way "CAIRO-PNG-FUNC: ~A~%" (list name data)) (let ((type (car-str data))) (if (not (member type all-types)) (begin (set! all-types (cons type all-types)) (set! cairo-types (cons type cairo-types)))) (let ((strs (parse-args args 'cairo))) (if spec (set! cairo-png-funcs (cons (list name type strs args spec) cairo-png-funcs)) (set! cairo-png-funcs (cons (list name type strs args) cairo-png-funcs))) (hash-table-set! names name (func-type strs))))))) (define* (CAIRO-FUNC-810 data spec) (let ((name (cadr-str data)) (args (caddr-str data))) (if (hash-table-ref names name) (no-way "CAIRO-FUNC-810: ~A~%" (list name data)) (let ((type (car-str data))) (if (not (member type all-types)) (begin (set! all-types (cons type all-types)) (set! cairo-types-810 (cons type cairo-types-810)))) (let ((strs (parse-args args 'cairo-810))) (if spec (set! cairo-funcs-810 (cons (list name type strs args spec) cairo-funcs-810)) (set! cairo-funcs-810 (cons (list name type strs args) cairo-funcs-810))) (hash-table-set! names name (func-type strs))))))) (define* (CAIRO-FUNC-912 data spec) (let ((name (cadr-str data)) (args (caddr-str data))) (if (hash-table-ref names name) (no-way "CAIRO-FUNC-912: ~A~%" (list name data)) (let ((type (car-str data))) (if (not (member type all-types)) (begin (set! all-types (cons type all-types)) (set! cairo-types-912 (cons type cairo-types-912)))) (let ((strs (parse-args args 'cairo-912))) (if spec (set! cairo-funcs-912 (cons (list name type strs args spec) cairo-funcs-912)) (set! cairo-funcs-912 (cons (list name type strs args) cairo-funcs-912))) (hash-table-set! names name (func-type strs))))))) (define (helpify name type args) (let* ((initial (format #f " #define H_~A \"~A ~A(" name type name)) (line-len (length initial)) (len (length args)) (typed #f) (help-max 100)) (hey initial) (do ((i 0 (+ i 1))) ((= i len)) (let ((ch (args i))) (if (char=? ch #\space) (if typed (begin (heyc ", ") (set! line-len (+ line-len 2)) (if (> line-len help-max) (begin (hey "\\~%") (set! line-len 0))) (set! typed #f)) (begin (set! line-len (+ 1 line-len)) (heyc " ") (set! typed #t))) (if (and (not (char=? ch #\@)) (not (char=? ch #\#))) (begin (set! line-len (+ 1 line-len)) (heyc ch)))))) (hey ")\"~%"))) (define (CATOM name) (if (hash-table-ref names name) (no-way "~A CATOM~%" name) (begin (set! atoms (cons name atoms)) (hash-table-set! names name 'atom)))) (define (CSTR name) (if (hash-table-ref names name) (no-way "~A CSTR~%" name) (begin (set! strings (cons name strings)) (hash-table-set! names name 'string)))) (define (CDBL name) (if (hash-table-ref names name) (no-way "~A CDBL~%" name) (begin (set! dbls (cons name dbls)) (hash-table-set! names name 'dbl)))) (define declared-types ()) (define (save-declared-type type) (if (and type (not (member type declared-types))) (set! declared-types (cons type declared-types)))) (define* (CINT name type) (save-declared-type type) (if (and type (not (assoc type direct-types))) (format *stderr* "could be direct int: ~S (~S)~%" type name)) (if (hash-table-ref names name) (no-way "~A CINT~%" name) (begin (set! ints (cons name ints)) (hash-table-set! names name 'int)))) (define* (CAIRO-INT name type) (save-declared-type type) (if (hash-table-ref names name) (no-way "~A CAIRO-INT~%" name) (begin (set! cairo-ints (cons name cairo-ints)) (hash-table-set! names name 'int)))) (define* (CAIRO-INT-810 name type) (save-declared-type type) (if (hash-table-ref names name) (no-way "~A CAIRO-INT-810~%" name) (begin (set! cairo-ints-810 (cons name cairo-ints-810)) (hash-table-set! names name 'int)))) (define* (CAIRO-INT-912 name type) (save-declared-type type) (if (hash-table-ref names name) (no-way "~A CAIRO-INT-912~%" name) (begin (set! cairo-ints-912 (cons name cairo-ints-912)) (hash-table-set! names name 'int)))) (define (CAIRO-STRING-912 name) (if (hash-table-ref names name) (no-way "~A CAIRO-STRING-912~%" name) (begin (set! cairo-strings-912 (cons name cairo-strings-912)) (hash-table-set! names name 'string)))) (define (CCAST name type) ; this is the cast (type *)obj essentially but here it's (list type* (cadr obj)) (if (hash-table-ref names name) (no-way "~A CCAST~%" name) (begin ;;(if (not (member type types)) ;; (set! types (cons type types))) (set! casts (cons (list name type) casts)) (hash-table-set! names name 'def)))) (define (CCHK name type) (if (hash-table-ref names name) (no-way "~A CCHK~%" name) (begin (set! checks (cons (list name type) checks)) (hash-table-set! names name 'def)))) (define (no-arg name) (let ((len (length name))) (call-with-exit (lambda (return) (do ((i 0 (+ i 1))) ((= i len) name) (if (char=? (name i) #\() (return (substring name 0 i)))))))) ;;; ---------------------------------------- read data ---------------------------------------- (load "xgdata.scm") ;(define listable-types (list "gint8*" "int*" "gint*" "gdouble*")) (define listable-types ()) (for-each (lambda (type) (let* ((len (length type)) (dereftype (and (char=? (type (- len 1)) #\*) (not (string=? type "char*")) ; these are surely strings (and set would need Xen_to_C_gchar etc) (not (string=? type "GError*")) (not (string=? type "GError**")) (not (string=? type "gchar*")) (substring type 0 (- len 1))))) (if (and dereftype (assoc dereftype direct-types)) (set! listable-types (cons type listable-types))))) types) (define (with-cairo dpy thunk) (thunk) ) (define (with-cairo-png dpy thunk) (thunk) ) (define (with-cairo-810 dpy thunk) (dpy "#if HAVE_CAIRO_1_8~%") (thunk) (dpy "#endif~%~%")) (define (with-cairo-912 dpy thunk) (dpy "#if HAVE_CAIRO_1_9_12 && GTK_CHECK_VERSION(3, 0, 0)~%") (thunk) (dpy "#endif~%~%")) (define all-ntypes (list types-2.14 types-2.16 types-2.18 types-2.20 types-3.0 types-3.2 types-3.4 types-3.6 types-3.8 types-3.10 types-3.12 types-3.14 types-3.16 types-3.18 types-3.20 cairo-types cairo-types-810 cairo-types-912)) (define all-ntype-withs (list with-2.14 with-2.16 with-2.18 with-2.20 with-3.0 with-3.2 with-3.4 with-3.6 with-3.8 with-3.10 with-3.12 with-3.14 with-3.16 with-3.18 with-3.20 with-cairo with-cairo-810 with-cairo-912)) (define all-funcs (list funcs-2.14 funcs-2.16 funcs-2.18 funcs-2.20 funcs-3.0 funcs-3.2 funcs-3.4 funcs-3.6 funcs-3.8 funcs-3.10 funcs-3.12 funcs-3.14 funcs-3.16 funcs-3.18 funcs-3.20 cairo-funcs cairo-png-funcs cairo-funcs-810 cairo-funcs-912)) (define all-func-withs (list with-2.14 with-2.16 with-2.18 with-2.20 with-3.0 with-3.2 with-3.4 with-3.6 with-3.8 with-3.10 with-3.12 with-3.14 with-3.16 with-3.18 with-3.20 with-cairo with-cairo-png with-cairo-810 with-cairo-912)) (define all-ints (list ints-2.14 ints-2.16 ints-2.18 ints-3.0 ints-3.2 ints-3.4 ints-3.6 ints-3.8 ints-3.10 ints-3.12 ints-3.14 ints-3.16 ints-3.18 ints-3.20 cairo-ints cairo-ints-810 cairo-ints-912)) (define all-int-withs (list with-2.14 with-2.16 with-2.18 with-3.0 with-3.2 with-3.4 with-3.6 with-3.8 with-3.10 with-3.12 with-3.14 with-3.16 with-3.18 with-3.20 with-cairo with-cairo-810 with-cairo-912)) (define all-casts (list casts-2.14 casts-2.16 casts-2.18 casts-2.20 casts-3.0 casts-3.2 casts-3.4 casts-3.6 casts-3.8 casts-3.10 casts-3.12 casts-3.14 casts-3.16 casts-3.18 casts-3.20 )) (define all-cast-withs (list with-2.14 with-2.16 with-2.18 with-2.20 with-3.0 with-3.2 with-3.4 with-3.6 with-3.8 with-3.10 with-3.12 with-3.14 with-3.16 with-3.18 with-3.20 )) (define all-checks (list checks-2.14 checks-2.16 checks-2.18 checks-2.20 checks-3.0 checks-3.2 checks-3.4 checks-3.6 checks-3.8 checks-3.10 checks-3.12 checks-3.14 checks-3.16 checks-3.18 checks-3.20 )) (define all-check-withs (list with-2.14 with-2.16 with-2.18 with-2.20 with-3.0 with-3.2 with-3.4 with-3.6 with-3.8 with-3.10 with-3.12 with-3.14 with-3.16 with-3.18 with-3.20 )) (define all-strings (list strings-2.14 strings-2.16 strings-3.0 strings-3.2 strings-3.4 strings-3.6 strings-3.8 strings-3.10 strings-3.12 strings-3.14 strings-3.16 strings-3.18 strings-3.20 cairo-strings-912)) (define all-string-withs (list with-2.14 with-2.16 with-3.0 with-3.2 with-3.4 with-3.6 with-3.8 with-3.10 with-3.12 with-3.14 with-3.16 with-3.18 with-3.20 with-cairo-912)) ;;; ---------------------------------------- write output file ---------------------------------------- (hey "/* xg.c: s7, Ruby, and Forth bindings for gtk/pango/cairo, some of glib~%") (hey " * this file generated automatically from makexg.scm and xgdata.scm~%") (hey " * needs xen.h~%") (hey " *~%") (hey " * reference args initial values are usually ignored, resultant values are returned in a list.~%") (hey " * null ptrs are passed and returned as #f, trailing \"user_data\" callback function arguments are optional (default: #f).~%") (hey " * where supported, \"...\" args are passed as a list, trailing NULL or -1 should be omitted.~%") (hey " * 'xg is added to *features*~%") (hey " *~%") (hey " * added funcs:~%") (hey " * (xg-version): date string.~%") (hey " * (c-array->list arr len) derefs each member of arr, returning lisp list, len=#f: null terminated array~%") (hey " * (list->c-array lst ctype) packages each member of list as c-type \"type\" returning (wrapped) c array~%") (hey " * (make-target-entry lst) returns a GtkTargetEntry table, each member of 'lst' should be (list target flags info)~%") (hey " * (GtkTextIter): GtkTextIter struct~%") (hey " * (GtkTreeIter): GtkTreeIter struct~%") (hey " * (PangoRectangle): PangoRectangle struct~%") (hey " * (cairo_matrix_t): cairo_matrix_t struct (if cairo)~%") (hey " *~%") (hey " * omitted functions and macros:~%") (hey " * anything with a va_list or GtkArg* argument.~%") (hey " * most of the unusual keysym names~%") (hey " * all *_CLASS, *_IFACE macros, *_get_type functions~%") (hey " * win32-specific functions~%") (hey " *~%") (hey " * HISTORY:~%") (hey " *~%") (hey " * 29-Oct: removed ->string.~%") (hey " * 21-Aug-15: procedure-signature changes.~%") (hey " * --------~%") (hey " * 27-Dec: integer procedure stuff.~%") (hey " * 16-Apr: changed max-args to 8.~%") (hey " * 6-Mar: changed most macros.~%") (hey " * 21-Feb-14: changed _p to _is_.~%") (hey " * --------~%") (hey " * 3-Sep: use symbol directly in type checks, not the symbol name.~%") (hey " * 18-Aug: changed the gtk version macros to reflect the version number.~%") (hey " * 7-Jun-13: added mixed arg types to the ... arg lists.~%") (hey " * --------~%") (hey " * 19-Aug-10: removed lots of Gdk stuff -- we assume Gtk 2.9 and cairo now.~%") (hey " * 28-Jan-10: removed the rest of the struct accessors.~%") (hey " * --------~%") (hey " * 16-Dec-09: removed Guile support.~%") (hey " * --------~%") (hey " * 16-Oct: removed Gauche support.~%") (hey " * 1-Sep: s7 support.~%") (hey " * 8-Jul-08: started removing all struct accessors (for Gtk 3).~%") (hey " * --------~%") (hey " * 9-Mar: removed all *_get_type functions (nearly 300!).~%") (hey " * 5-Mar-07: cairo and more gtkprint.~%") (hey " * --------~%") (hey " * 26-Aug: removed --with-x11, WITH_GTK_AND_X11, xg-x11.h.~%") (hey " * 4-Aug: added a form of g_object_get and gtk_settings_get_for_screen.~%") (hey " * 20-Jul: gtkprint stuff.~%") (hey " * 17-Jul: g_signal_connect and other related macros.~%") (hey " * 21-Apr: Gauche support.~%") (hey " * 29-Mar: Forth support.~%") (hey " * 7-Mar-06: if g_set_error, return the error message, not the GError pointer~%") (hey " * --------~%") (hey " * 9-Jul: Collapse 2.3.* into 2.3.6, 2.5.* into 2.5.6.~%") (hey " * 13-Jun: folded xg-ruby.c into xg.c.~%") (hey " * 21-Feb: changed libxm to libxg, xm-version to xg-version.~%") (hey " * 10-Jan: plugged some memory leaks.~%") (hey " * 4-Jan-05: removed deprecated Xen_VECTOR_ELEMENTS.~%") (hey " * --------~%") (hey " * 8-Dec: added some g_log handler funcs.~%") (hey " * 6-Dec: check for lost callback context.~%") (hey " * tightened type (pointer) checking considerably (#f only acceptable if explicit @ used in xgdata.scm).~%") (hey " * 3-Dec: changed GPOINTER cast func to accept non-lists.~%") (hey " * 27-Aug: removed the PANGO_ENGINE and PANGO_BACKEND stuff.~%") (hey " * 2-Jun: gdk_atom_name needs to free return value~%") (hey " * 28-May: GtkFileSelection struct support put back in -- need ok_button et al.~%") (hey " * 14-Apr: make-target-entry.~%") (hey " * 4-Apr: various additions, deletions, and bugfixes for snd-test 26~%") (hey " * 29-Mar: support for some ... args.~%") (hey " * 22-Mar: g_source_remove and related changes.~%") (hey " * 12-Feb-04: g_list_nth_data (Kjetil S. Matheussen).~%") (hey " * --------~%") (hey " * 15-Sep: removed client_window GtkIMMulticontext struct field.~%") (hey " * 26-May: removed nugatory GdkInputFunction stuff and some unused type converters.~%") (hey " * 1-Apr: gdk_property_get uses scm_mem2string in some cases now.~%") (hey " * 31-Mar: gchar* -> xen string bugfix (thanks to Friedrich Delgado Friedrichs).~%") (hey " * 10-Mar-03: Ruby Xm_Version.~%") (hey " * --------~%") (hey " * 18-Nov: Ruby/Gtk bugfixes.~%") (hey " * 25-Oct: removed (deprecated) gdk_set_pointer_hooks~%") (hey " * 31-Jul: removed GTK 1.n support~%") (hey " * 24-Jul: changed Guile prefix (R5RS reserves vertical-bar).~%") (hey " * 19-Jul: XG_FIELD_PRE for change from using vertical-bar (reserved in R5RS)~%") (hey " * 2-Jun: removed deprecated and broken stuff~%") (hey " * 12-Mar: support for GtkDestroyNotify callbacks~%") (hey " * Ruby support via xg-ruby.c~%") (hey " * 21-Feb: #f=NULL throughout, gdk-pixbuf, GTypes.~%") (hey " * 11-Feb-02: initial version.~%") (hey " */~%~%") (hey "#include \"mus-config.h\"~%~%") (hey "#define HAVE_CAIRO_1_8 ((CAIRO_VERSION_MAJOR >= 1) && (CAIRO_VERSION_MINOR >= 8))~%") (hey "#define HAVE_CAIRO_1_9_12 ((CAIRO_VERSION_MAJOR >= 1) && (CAIRO_VERSION_MINOR >= 9) && (CAIRO_VERSION_MICRO >= 12))~%~%") (hey "#if ((!__NetBSD__) && ((_MSC_VER) || (!defined(__STC__)) || (defined(__STDC_VERSION__) && (__STDC_VERSION__ < 199901L))))~%") (hey " #define __func__ __FUNCTION__~%") (hey "#endif~%~%") (hey "#if HAVE_EXTENSION_LANGUAGE~%~%") ;(hey "#if UNDEF_USE_SND~% #undef USE_SND~% #define USE_SND 0~%#endif~%~%") (hey "#include ~%") (hey "#include ~%~%") (hey "#include ~%") (hey "#include ~%") (hey "#include ~%") (hey "#if (!GTK_CHECK_VERSION(3, 0, 0))~%") (hey " #include ~%") (hey "#endif~%") (hey "#include ~%") (hey "#include ~%") (with-cairo hey (lambda () (hey "#include ~%"))) (hey "#if USE_SND~%") (hey " /* USE_SND causes xm to use Snd's error handlers which are much smarter than xen's fallback versions */~%") (hey " #include \"snd.h\"~%") (hey "#else~%") (hey " #include \"xen.h\"~%") (hey " #define NOT_A_GC_LOC -1~%") (hey "#endif~%") (hey "~%#ifndef PROC_FALSE~%") (hey " #if HAVE_RUBY~%") (hey " #define PROC_FALSE \"false\"~%") (hey " #define PROC_TRUE \"true\"~%") (hey " #else~%") (hey " #define PROC_FALSE \"#f\"~%") (hey " #define PROC_TRUE \"#t\"~%") (hey " #endif~%") (hey "#endif~%~%") (hey "/* -------------------------------- GC -------------------------------- */~%") (hey "static Xen_object_type_t xm_obj_tag;~%") (hey "#if HAVE_RUBY~%") (hey "static void *xm_obj_free(Xen obj)~%") (hey "{~%") (hey " void *xobj;~%") (hey " xobj = (void *)obj;~%") (hey " free(xobj);~%") (hey " return(NULL);~%") (hey "}~%") (hey "#endif~%") (hey "#if HAVE_FORTH~%") (hey "static void xm_obj_free(Xen obj)~%") (hey "{~%") (hey " void *val;~%") (hey " val = (void *)Xen_object_ref(obj);~%") (hey " free(val);~%") (hey "}~%") (hey "#endif~%") (hey "#if HAVE_SCHEME~%") (hey "static void xm_obj_free(void *val)~%") (hey "{~%") (hey " free(val);~%") (hey "}~%") (hey "static bool s7_equalp_xm(void *x1, void *x2)~%") (hey "{~%") (hey " return(x1 == x2);~%") (hey "}~%") (hey "#endif~%") (hey "static Xen make_xm_obj(void *ptr)~%") (hey "{~%") (hey " return(Xen_make_object(xm_obj_tag, ptr, 0, xm_obj_free));~%") (hey "}~%") (hey "static void define_xm_obj(void)~%") (hey "{~%") (hey "#if HAVE_SCHEME~%") (hey " xm_obj_tag = s7_new_type_x(s7, \"\", NULL, xm_obj_free, s7_equalp_xm, NULL, NULL, NULL, NULL, NULL, NULL, NULL);~%") (hey "#else~%") (hey " xm_obj_tag = Xen_make_object_type(\"XmObj\", sizeof(void *));~%") (hey "#endif~%") (hey "#if HAVE_FORTH~%") (hey " fth_set_object_free(xm_obj_tag, xm_obj_free);~%") (hey "#endif~%") (hey "} ~%") (hey "~%") (hey "/* prefix for all names */~%") (hey "#if HAVE_SCHEME~%") (hey " #define Xg_pre \"\"~%") (hey " #define Xg_field_pre \".\"~%") (hey " #define Xg_post \"\"~%") (hey "#endif~%") (hey "#if HAVE_RUBY~%") (hey "/* for Ruby, XG PRE needs to be uppercase */~%") (hey " #define Xg_pre \"R\"~%") (hey " #define Xg_post \"\"~%") (hey " #define Xg_field_pre \"R\"~%") (hey "#endif~%") (hey "#if HAVE_FORTH~%") (hey " #define Xg_pre \"F\"~%") (hey " #define Xg_post \"\"~%") (hey " #define Xg_field_pre \"F\"~%") (hey "#endif~%") (hey "~%") (hey "static Xen xg_~A_symbol" (no-stars (car all-types))) (for-each (lambda (typ) (hey ", xg_~A_symbol" (no-stars typ))) (cdr all-types)) (define other-types (list 'idler 'GtkCellRendererPixbuf_ 'GtkCheckButton_ 'GtkDrawingArea_ 'GtkScrollbar_ 'GtkSeparator_ 'GtkSeparatorMenuItem_ 'GdkEventExpose_ 'GdkEventNoExpose_ 'GdkEventVisibility_ 'GdkEventButton_ 'GdkEventScroll_ 'GdkEventCrossing_ 'GdkEventFocus_ 'GdkEventConfigure_ 'GdkEventProperty_ 'GdkEventSelection_ 'GdkEventProximity_ 'GdkEventSetting_ 'GdkEventWindowState_ 'GdkEventDND_ 'GtkFileChooserDialog_ 'GtkFileChooserWidget_ 'GtkColorButton_ 'GtkAccelMap 'GtkCellRendererCombo_ 'GtkCellRendererProgress_ 'GtkCellRendererAccel_ 'GtkCellRendererSpin_ 'GtkRecentChooserDialog_ 'GtkRecentChooserWidget_ 'GtkCellRendererSpinner_ 'gboolean_ 'GtkFontChooserDialog_ 'GtkFontChooserWidget_ 'GtkColorChooserDialog_ 'GtkColorChooserWidget_ 'GtkColorWidget_ 'GtkGestureLongPress_ )) (for-each (lambda (typ) (hey ", xg_~A_symbol" typ)) other-types) (hey ";~%~%") (hey "#define wrap_for_Xen(Name, Value) Xen_list_2(xg_ ## Name ## _symbol, Xen_wrap_C_pointer(Value))~%") (hey "#define is_wrapped(Name, Value) (Xen_is_pair(Value) && (Xen_car(Value) == xg_ ## Name ## _symbol))~%") (hey "~%") (hey "#define Xm_type(Name, XType) \\~%") ;; these are not pointers, so should not use wrap_c_pointer and friends (hey " static Xen C_to_Xen_ ## Name (XType val) {return(Xen_list_2(xg_ ## Name ## _symbol, C_ulong_to_Xen_ulong(val)));} \\~%") (hey " static XType Xen_to_C_ ## Name (Xen val) {return((XType)Xen_ulong_to_C_ulong(Xen_cadr(val)));} \\~%") (hey " static bool Xen_is_ ## Name (Xen val) {return(is_wrapped(Name, val));}~%") (hey "~%") (hey "#define Xm_type_1(Name, XType) \\~%") (hey " static XType Xen_to_C_ ## Name (Xen val) {return((XType)Xen_ulong_to_C_ulong(Xen_cadr(val)));} \\~%") (hey " static bool Xen_is_ ## Name (Xen val) {return(is_wrapped(Name, val));}~%") (hey "~%") ;(hey "#define Xm_type_no_P(Name, XType) \\~%") ;(hey " static Xen C_to_Xen_ ## Name (XType val) {return(wrap_for_Xen(Name, val));} \\~%") ;(hey " static XType Xen_to_C_ ## Name (Xen val) {return((XType)Xen_unwrap_C_pointer(Xen_cadr(val)));} \\~%") ;(hey "~%") (hey "#define Xm_type_no_p_2(Name, XType) \\~%") (hey " static Xen C_to_Xen_ ## Name (XType val) {return(wrap_for_Xen(Name, val));}~%") (hey "~%") (hey "#define Xm_type_Ptr(Name, XType) \\~%") (hey " static Xen C_to_Xen_ ## Name (XType val) {if (val) return(wrap_for_Xen(Name, val)); return(Xen_false);} \\~%") (hey " static XType Xen_to_C_ ## Name (Xen val) {if (Xen_is_false(val)) return(NULL); return((XType)Xen_unwrap_C_pointer(Xen_cadr(val)));} \\~%") (hey " static bool Xen_is_ ## Name (Xen val) {return(is_wrapped(Name, val));}~%") (hey "~%") (hey "#define Xm_type_Ptr_const(Name, XType) \\~%") (hey " static Xen C_to_Xen_ ## Name (const XType val) {if (val) return(wrap_for_Xen(Name, val)); return(Xen_false);} \\~%") (hey " static const XType Xen_to_C_ ## Name (Xen val) {if (Xen_is_false(val)) return(NULL); return((const XType)Xen_unwrap_C_pointer(Xen_cadr(val)));} \\~%") (hey " static bool Xen_is_ ## Name (Xen val) {return(is_wrapped(Name, val));}~%") (hey "~%") (hey "#define Xm_type_Ptr_1(Name, XType) \\~%") (hey " static XType Xen_to_C_ ## Name (Xen val) {if (Xen_is_false(val)) return(NULL); return((XType)Xen_unwrap_C_pointer(Xen_cadr(val)));} \\~%") (hey " static bool Xen_is_ ## Name (Xen val) {return(is_wrapped(Name, val));}~%") (hey "~%") (hey "#define Xm_type_Ptr_2(Name, XType) \\~%") (hey " static Xen C_to_Xen_ ## Name (XType val) {if (val) return(wrap_for_Xen(Name, val)); return(Xen_false);} \\~%") (hey "~%") (hey "/* type checks for callback wrappers */~%") (define (callback-p func) (hey "#define Xen_is_~A(Arg) Xen_is_false(Arg) || (Xen_is_procedure(Arg) && (Xen_is_aritable(Arg, ~D)))~%" (symbol->string (callback-name func)) (length (callback-args func)))) (for-each callback-p callbacks) ;(hey "#define Xen_is_lambda(Arg) Xen_is_procedure(Arg)~%") (hey "#define Xen_is_GCallback(Arg) (Xen_is_procedure(Arg) && ((Xen_is_aritable(Arg, 2)) || (Xen_is_aritable(Arg, 3)) || (Xen_is_aritable(Arg, 4))))~%") (define (xen-callback func) (hey "#define Xen_to_C_~A(Arg) Xen_is_false(Arg) ? NULL : gxg_~A~%" (symbol->string (callback-name func)) (callback-func func))) (for-each xen-callback callbacks) (hey "#define Xen_to_C_GCallback(Arg) ((Xen_is_aritable(Arg, 4)) ? (GCallback)gxg_func4 : ((Xen_is_aritable(Arg, 3)) ? (GCallback)gxg_func3 : (GCallback)gxg_func2))~%") ;; (hey "#define Xen_to_C_GCallback(Arg) ((Xen_is_aritable(Arg, 3)) ? (GCallback)gxg_func3 : (GCallback)gxg_func2)~%") (hey "#define Xen_to_C_lambda_data(Arg) (gpointer)gxg_ptr~%") (hey "#define Xen_is_lambda_data(Arg) 1~%") ;; needed if func returns func of this type (hey "#define C_to_Xen_GtkTreeViewSearchPositionFunc(Arg) wrap_for_Xen(GtkTreeViewSearchPositionFunc, Arg)~%") (hey "#define C_to_Xen_GtkTreeViewSearchEqualFunc(Arg) wrap_for_Xen(GtkTreeViewSearchEqualFunc, Arg)~%") ;(hey "#define C_to_Xen_GtkLinkButtonUriFunc(Arg) wrap_for_Xen(GtkLinkButtonUriFunc, Arg)~%") ;(hey "#define C_to_Xen_GtkTreeIterCompareFunc(Arg) wrap_for_Xen(GtkTreeViewSearchEqualFunc, Arg)~%") ;(hey "#define C_to_Xen_GtkTreeSelectionFunc(Arg) wrap_for_Xen(GtkTreeSelectionFunc, Arg)~%") ;(hey "#define C_to_Xen_GtkMenuPositionFunc(Arg) wrap_for_Xen(GtkMenuPositionFunc, Arg)~%") ;(hey "#define C_to_Xen_GtkDestroyNotify(Arg) wrap_for_Xen(GtkDestroyNotify, Arg)~%") (hey "#define Xen_to_C_GdkFilterReturn(Arg) (GdkFilterReturn)Xen_integer_to_C_int(Arg)~%") ;(hey "#define Xen_to_C_String(Arg) Xen_string_to_C_string(Arg)~%") (hey "#define C_to_Xen_String(Arg) C_string_to_Xen_string((char *)Arg)~%") (hey "static Xen C_to_Xen_GError_(GError *err)~%") (hey "{~%") (hey " if (err)~%") (hey " {~%") (hey " Xen msg;~%") (hey " msg = C_string_to_Xen_string(err->message);~%") (hey " g_error_free(err);~%") (hey " return(msg);~%") (hey " }~%") (hey " return(Xen_false);~%") (hey "}~%") (hey "~%~%/* ---------------------------------------- types ---------------------------------------- */~%~%") (for-each type-it (reverse types)) (for-each (lambda (type-list with-func) (if (pair? type-list) (with-func hey (lambda () (for-each type-it (reverse type-list)))))) all-ntypes all-ntype-withs) (hey "#define XLS(a, b) Xen_to_C_gchar_(Xen_list_ref(a, b))~%") (hey "#define XLI(a, b) ((int)Xen_integer_to_C_int(Xen_list_ref(a, b)))~%") (hey "#define XLL(a, b) (Xen_llong_to_C_llong(Xen_list_ref(a, b)))~%") (hey "#define XLG(a, b) Xen_to_C_GType(Xen_list_ref(a, b))~%") (hey "#define XLT(a, b) Xen_to_C_GtkTextTag_(Xen_list_ref(a, b))~%") (hey "#define XLA(a, b) ((Xen_is_integer(Xen_list_ref(a, b))) ? ((gpointer)XLL(a, b)) : ((Xen_is_string(Xen_list_ref(a, b))) ? ((gpointer)XLS(a, b)) : ((gpointer)XLG(a, b))))~%~%") (hey "/* -------------------------------- gc protection -------------------------------- */~%") (hey "~%") (hey "static Xen xm_protected;~%") (hey "static int xm_protected_size = 0;~%") (hey "static Xen xm_gc_table;~%") (hey "static int last_xm_unprotect = NOT_A_GC_LOC;~%") (hey "~%") (hey "static int xm_protect(Xen obj)~%") (hey "{~%") (hey " int i, new_size;~%") (hey " Xen new_table;~%") (hey " if (last_xm_unprotect >= 0)~%") (hey " {~%") (hey " i = last_xm_unprotect;~%") (hey " if (Xen_is_false(Xen_vector_ref(xm_protected, i)))~%") (hey " {~%") (hey " Xen_vector_set(xm_protected, i, obj);~%") (hey " last_xm_unprotect = NOT_A_GC_LOC;~%") (hey " return(i);~%") (hey " }~%") (hey " last_xm_unprotect = NOT_A_GC_LOC;~%") (hey " }~%") (hey " for (i = 0; i < xm_protected_size; i++)~%") (hey " if (Xen_is_false(Xen_vector_ref(xm_protected, i)))~%") (hey " {~%") (hey " Xen_vector_set(xm_protected, i, obj);~%") (hey " return(i);~%") (hey " }~%") (hey " new_size = xm_protected_size * 2;~%") (hey " new_table = Xen_make_vector(new_size, Xen_false);~%") (hey " for (i = 0; i < xm_protected_size; i++)~%") (hey " {~%") (hey " Xen_vector_set(new_table, i, Xen_vector_ref(xm_protected, i));~%") (hey " Xen_vector_set(xm_protected, i, Xen_false);~%") (hey " }~%") (hey " Xen_vector_set(new_table, xm_protected_size, obj);~%") (hey " Xen_vector_set(xm_gc_table, 0, new_table);~%") (hey " i = xm_protected_size;~%") (hey " xm_protected_size = new_size;~%") (hey " xm_protected = new_table;~%") (hey " return(i);~%") (hey "}~%") (hey "~%") (hey "static void xm_unprotect_at(int ind)~%") (hey "{~%") (hey " Xen_vector_set(xm_protected, ind, Xen_false);~%") (hey " last_xm_unprotect = ind;~%") (hey "}~%~%") (hey "~%~%/* ---------------------------------------- callback handlers ---------------------------------------- */~%~%") (let ((funcs-done ())) (let ((xc (lambda (func) (let* ((name (callback-func func)) (type (callback-type func)) (args (callback-args func)) (gctype (callback-gc func)) (fname (callback-name func)) (void? (string=? type "void"))) (if (not (member name funcs-done)) (begin (set! funcs-done (cons name funcs-done)) (hey "static ~A gxg_~A(" type name) (let ((previous-arg #f) (ctr 0)) (for-each (lambda (arg) (if previous-arg (hey ", ")) ;; ctr is 0-based here (if (or (and (memq fname '(GtkClipboardTextReceivedFunc GtkAccelMapForeach GtkEntryCompletionMatchFunc)) (= ctr 1)) (and (memq fname '(GtkTreeViewSearchEqualFunc GLogFunc GtkClipboardRichTextReceivedFunc)) (= ctr 2)) (and (memq fname '(GtkFileFilterFunc GtkRecentFilterFunc GLogFunc)) (= ctr 0))) (hey "const ")) (set! ctr (+ ctr 1)) (set! previous-arg #t) (hey "~A ~A" (if (not (string=? (car arg) "lambda_data")) (car arg) "gpointer") (cadr arg))) args) (hey ")~%")) (hey "{~% ") ;; I tried to use Xen_error here but it was a no-op for some reason?? (hey "if (!Xen_is_list((Xen)func_info)) return~A;~% " (if void? "" (format #f "((~A)0)" (no-stars type)))) (if (eq? gctype 'permanent-gcc) (hey "#if (!(defined(__cplusplus)))~% ")) ; const arg conversion causes trouble if g++ (let ((castlen (+ 12 (if (not void?) (+ 2 (length (format #f "return(Xen_to_C_~A" (no-stars type)))) 1)))) (if (not void?) (hey "return(Xen_to_C_~A(" (no-stars type))) (hey "Xen_call_with_~A_arg~A(~A((Xen)func_info),~%" (if (zero? (length args)) "no" (length args)) (if (= (length args) 1) "" "s") (if (eq? fname 'GtkClipboardClearFunc) "Xen_caddr" (if (eq? fname 'GtkDestroyNotify) "Xen_cadddr" "Xen_car"))) (for-each (lambda (arg) (hey (substring " " 0 castlen)) (if (not (string=? (car arg) "lambda_data")) (hey "C_to_Xen_~A(~A~A),~%" (no-stars (car arg)) (if (string=? (car arg) "GtkFileFilterInfo*") "(GtkFileFilterInfo *)" "") (cadr arg)) (hey "Xen_cadr((Xen)func_info),~%"))) args) (hey (substring " " 0 castlen)) (hey "__func__)") (if void? (hey ";~%") (hey "));~%"))) (if (eq? gctype 'permanent-gcc) (begin (if (not void?) (begin (hey " #else~%") (hey " return((~A)0);~%" (no-stars type)))) (hey " #endif~%"))) (hey "}~%~%"))))))) (for-each xc callbacks) )) (hey "~%static gboolean gxg_func3(GtkWidget *w, GdkEventAny *ev, gpointer data)~%") (hey "{~%") (hey " return(Xen_boolean_to_C_bool(Xen_call_with_3_args(Xen_car((Xen)data),~%") (hey " C_to_Xen_GtkWidget_(w),~%") (hey " C_to_Xen_GdkEventAny_(ev),~%") (hey " Xen_cadr((Xen)data),~%") (hey " __func__)));~%") (hey "}~%") (hey "~%static gboolean gxg_func4(GtkPrintOperation *op, GtkPrintContext *context, gint page_nr, gpointer data)~%") (hey "{~%") (hey " return(Xen_boolean_to_C_bool(Xen_call_with_4_args(Xen_car((Xen)data),~%") (hey " C_to_Xen_GtkPrintOperation_(op),~%") (hey " C_to_Xen_GtkPrintContext_(context),~%") (hey " C_int_to_Xen_integer(page_nr),~%") (hey " Xen_cadr((Xen)data),~%") (hey " __func__)));~%") (hey "}~%~%") (hey "~%~%/* ---------------------------------------- functions ---------------------------------------- */~%~%") (define max-args 8) (define handle-func (lambda (data) (let* ((name (car data)) (return-type (cadr data)) (args (caddr data)) (cargs (length args)) (refargs (ref-args args)) (xgargs (- cargs refargs)) (argstr (cadddr data)) (lambda-type (hash-table-ref names name)) (callback-data (and (not (eq? lambda-type 'fnc)) (find-callback (lambda (func) (and (eq? (callback-name func) lambda-type) func))))) (spec (and (> (length data) 4) (data 4))) (spec-data (and (> (length data) 5) (data 5))) (arg-start 0) (line-len 0) (line-max 120)) (define (hey-start) ;; start of checked line (set! line-len 0)) (define (hey-mark) ;; start of checked line (set! arg-start line-len)) (define (hey-on . args) ;; no cr -- just append (let ((line (apply format #f args))) (set! line-len (+ line-len (length line))) (heyc line))) (define (hey-ok arg) ;; cr ok after arg (set! line-len (+ line-len (length arg))) (heyc arg) (if (> line-len line-max) (begin (hey "~%") (do ((i 0 (+ i 1))) ((= i arg-start)) (heyc " ")) (set! line-len arg-start)))) (hey "static Xen gxg_~A(" name) (if (= (length args) 0) (heyc "void") (if (>= (length args) max-args) (heyc "Xen arglist") (let ((previous-arg #f)) (for-each (lambda (arg) (let ((argname (cadr arg)) ;(argtype (car arg)) ) (if previous-arg (heyc ", ")) (set! previous-arg #t) (if (and (ref-arg? arg) (not (member name (list "gdk_init" "gdk_init_check" "gtk_init" "gtk_init_check" "gtk_parse_args")))) (hey "Xen ignore_~A" argname) (hey "Xen ~A" argname)))) args)))) (hey ")~%{~%") (helpify name return-type argstr) (if (> refargs 0) (for-each (lambda (arg) (if (ref-arg? arg) (if (has-stars (deref-type arg)) (hey " ~A ~A = NULL;~%" (deref-type arg) (deref-name arg)) (hey " ~A ~A;~%" (deref-type arg) (deref-name arg))))) args)) (if (and (>= (length args) max-args) (> xgargs 0)) (let ((previous-arg #f)) (heyc " Xen ") (for-each (lambda (arg) (if (not (ref-arg? arg)) ;(< (length arg) 3) (begin (if previous-arg (heyc ", ")) (set! previous-arg #t) (hey "~A" (cadr arg))))) args) (hey ";~%") (let ((ctr 0)) ; list-ref counts from 0 (for-each (lambda (arg) (if (not (ref-arg? arg)) (hey " ~A = Xen_list_ref(arglist, ~D);~%" (cadr arg) ctr)) (set! ctr (+ ctr 1))) args)))) (if (> (length args) 0) (let ((ctr 1) (argc #f)) (for-each (lambda (arg) (let ((argname (cadr arg)) (argtype (car arg))) (if (not (ref-arg? arg)) (if (null-arg? arg) (hey " Xen_check_type(Xen_is_~A(~A) || Xen_is_false(~A), ~A, ~D, ~S, ~S);~%" (no-stars argtype) argname argname argname ctr name argtype) (if (opt-arg? arg) (begin (hey " if (!Xen_is_bound(~A)) ~A = Xen_false; ~%" argname argname) (hey " else Xen_check_type(Xen_is_~A(~A), ~A, ~D, ~S, ~S);~%" (no-stars argtype) argname argname ctr name argtype)) (hey " Xen_check_type(Xen_is_~A(~A), ~A, ~D, ~S, ~S);~%" (no-stars argtype) argname argname ctr name argtype))) (if (>= (length arg) 3) (if (char=? ((arg 2) 0) #\{) (begin (set! argc (deref-name arg)) (hey " ~A = Xen_to_C_~A(~A);~%" (deref-name arg) (deref-type arg) argname)) (if (char=? ((arg 2) 0) #\|) (begin (hey " ~A = (~A)calloc(~A, sizeof(~A));~%" (deref-name arg) (deref-type arg) argc (deref-element-type arg)) (hey " {~% int i;~% Xen lst;~% lst = Xen_copy_arg(~A);~%" argname) (hey " for (i = 0; i < ~A; i++, lst = Xen_cdr(lst)) ~A[i] = Xen_to_C_~A(Xen_car(lst));~%" argc (deref-name arg) (no-stars (deref-element-type arg))) (hey " }~%")))))) (set! ctr (+ ctr 1)))) args))) (let ((using-result #f) (using-loc #f)) (if (not (eq? lambda-type 'fnc)) (begin (set! using-loc (or (eq? lambda-type 'GCallback) (and callback-data (or (eq? (callback-gc callback-data) 'temporary) (eq? (callback-gc callback-data) 'semi-permanent))))) (set! using-result (and (not (string=? return-type "void")) (not (eq? lambda-type 'lambda)))) (hey " {~%") (if using-result (hey " Xen result;~%")) (if using-loc (hey " int loc;~%")) (hey " Xen gxg_ptr = Xen_list_5(~A, func_info, Xen_false, Xen_false, Xen_false);~%" (call-with-exit (lambda (name-it) (for-each (lambda (arg) (let ((argname (cadr arg)) ;(argtype (car arg)) ) (if (string=? argname "func") (name-it "func")))) args) "Xen_false"))) (if using-loc (hey " loc = xm_protect(gxg_ptr);~%") (hey " xm_protect(gxg_ptr);~%")) (if using-loc (hey " Xen_list_set(gxg_ptr, 2, C_int_to_Xen_integer(loc));~%") (if (eq? lambda-type 'GtkClipboardGetFunc) (hey " Xen_list_set(gxg_ptr, 2, clear_func);~%"))) (for-each (lambda (arg) (let ((argname (cadr arg)) (argtype (car arg))) (if (string=? argtype "GtkDestroyNotify") (hey " Xen_list_set(gxg_ptr, 3, ~A);~%" argname)))) args) (hey-start) (if using-result (hey-on " result = C_to_Xen_~A(" (no-stars return-type)) (heyc " "))) (begin ; lambda-type = 'fnc (set! using-result (and (> refargs 0) (not (string=? return-type "void")))) (if using-result (begin (hey " {~%") (hey " Xen result;~%"))) (hey-start) (if (not (eq? spec 'etc)) (if (not (string=? return-type "void")) (if (= refargs 0) (if (eq? spec 'free) (hey-on " {~% ~A result;~% Xen rtn;~% result = " return-type) (if (eq? spec 'const-return) (hey " return(C_to_Xen_~A((~A)" (no-stars return-type) return-type) (begin (if (member name idlers) (begin (hey " xm_unprotect_at(Xen_integer_to_C_int(Xen_caddr(~A)));~%" (cadar args)) (set! idlers (remove-if (lambda (x) (string=? x name)) idlers)))) (hey-on " return(C_to_Xen_~A(" (no-stars return-type))))) (hey-on " result = C_to_Xen_~A(" (no-stars return-type))) (hey-on " "))))) ;; pass args (if (eq? spec 'etc) (begin ;; goes to end ;; need to check ... list, set up locals, send out switch, return result (let* ((list-name (cadr (args (- cargs 1)))) (min-len (car spec-data)) (max-len (cadr spec-data)) (types (caddr spec-data)) (with-minus-one (or (string=? name "gtk_list_store_set") (string=? name "gtk_tree_store_set"))) (with-null (and (not with-minus-one) (not (and (= (length types) 1) (string=? (car types) "GType"))))) (modlen (length types))) (hey " {~%") (hey " int etc_len = 0;~%") (if (not (string=? return-type "void")) (hey " ~A result = ~A;~%" return-type (if (has-stars return-type) "NULL" "0"))) (do ((i 0 (+ i 1))) ((= i (- cargs 1))) (let ((arg (args i))) (hey " ~A p_arg~D;~%" (car arg) i))) (hey " if (Xen_is_list(~A)) etc_len = Xen_list_length(~A);~%" list-name list-name) (if (> min-len 0) (hey " if (etc_len < ~D) Xen_out_of_range_error(~S, ~A, ~A, \"... list must have at least ~D entr~A\");~%" min-len name (- cargs 1) list-name min-len (if (= min-len 1) "y" "ies"))) (hey " if (etc_len > ~D) Xen_out_of_range_error(~S, ~A, ~A, \"... list too long (max len: ~D)\");~%" max-len name (- cargs 1) list-name max-len) (if (not (= modlen 1)) (hey " if ((etc_len % ~D) != 0) Xen_out_of_range_error(~S, ~A, ~A, \"... list len must be multiple of ~D\");~%" modlen name (- cargs 1) list-name modlen)) (do ((i 0 (+ i 1))) ((= i (- cargs 1))) (let ((arg (args i))) (hey " p_arg~D = Xen_to_C_~A(~A);~%" i (no-stars (car arg)) (cadr arg)))) (hey " switch (etc_len)~%") (hey " {~%") (do ((i min-len (+ i modlen))) ((> i max-len)) (if (not (string=? return-type "void")) (hey " case ~D: result = ~A(" i name) (hey " case ~D: ~A(" i name)) (do ((j 0 (+ 1 j))) ((= j (- cargs 1))) (let () ;(arg (args j))) (hey "p_arg~D, " j))) ;; assume ending null for now (let ((modctr 0)) (do ((j 0 (+ 1 j))) ((= j i)) (let ((type (types modctr))) (set! modctr (+ 1 modctr)) (if (>= modctr modlen) (set! modctr 0)) (if (string=? type "int") (hey "XLI(") (if (string=? type "gchar*") (hey "XLS(") (if (string=? type "GtkTextTag*") (hey "XLT(") (if (string=? type "GType") (hey "XLG(") (hey "XLA(")))))) (hey "~A, ~D)" list-name j) (if (or with-null with-minus-one (< j (- i 1))) (hey ", ")))) (if with-null (if (and (= i 0) (string=? name "gtk_file_chooser_dialog_new")) (hey "NULL, NULL); break;~%") ; extra NULL needed I guess for the valist pass-through -- gcc 4.1 grumbles about it (hey "NULL); break;~%")) (if with-minus-one (hey "-1); break;~%") (hey "); break;~%")))) (hey " }~%") (if (not (string=? return-type "void")) (hey " return(C_to_Xen_~A(result));~%" (no-stars return-type)) (hey " return(Xen_false);~%")) (hey " }~%") )) (begin (if (not (eq? lambda-type 'lambda)) (begin (hey-on "~A(" name) (hey-mark) (if (> (length args) 0) (let ((previous-arg #f)) (for-each (lambda (arg) (let ((argname (cadr arg)) (argtype (car arg))) (if previous-arg (hey-ok ", ")) (if (and (eq? spec 'const) (member argtype '("char**" "gchar**" "gchar*" "char*" "GValue*") string=?)) (hey "(const ~A)" argtype)) (set! previous-arg #t) (if (ref-arg? arg) (hey-on "&~A" (deref-name arg)) (hey-on "Xen_to_C_~A(~A)" (no-stars argtype) argname)))) args))) (if (not (eq? lambda-type 'fnc)) (if (not (string=? return-type "void")) (heyc ")")) (if (not (string=? return-type "void")) (if (= refargs 0) (if (not (eq? spec 'free)) (heyc "))")) (heyc ")")))) (hey ");~%") (if (not (eq? lambda-type 'fnc)) (begin (if (and callback-data (eq? (callback-gc callback-data) 'temporary)) (hey " xm_unprotect_at(loc);~%")) (if (and callback-data (eq? (callback-gc callback-data) 'semi-permanent)) (hey " Xen_list_set(gxg_ptr, 2, Xen_list_3(xg_idler_symbol, ~A, C_int_to_Xen_integer(loc)));~%" (if (string=? return-type "void") "Xen_false" "result"))) (if using-result (hey " return(result);~%") (hey " return(Xen_false);~%")) (hey " }~%")) (begin ;'fnc (if (> refargs 0) (let ((previous-arg using-result)) (if using-result (heyc " ")) (if (string=? name "gdk_property_get") (begin ;; special case -- type returned is dependent to some extent on atom (hey " {~% Xen data_val = Xen_false;~%\ if (ref_actual_property_type == GDK_TARGET_STRING)~%\ data_val = C_string_to_Xen_string((char *)ref_data);~%\ else if (ref_actual_length > 0) data_val = C_string_to_Xen_string_with_length((char *)ref_data, ref_actual_length * ref_actual_format / 8);~%\ return(Xen_list_5(result, C_to_Xen_GdkAtom(ref_actual_property_type), C_to_Xen_gint(ref_actual_format), ~%\ C_to_Xen_gint(ref_actual_length), data_val));~%\ }~% }~%") ) (begin (hey " return(Xen_list_~D(" (+ refargs (if using-result 1 0))) (if using-result (heyc "result")) (for-each (lambda (arg) (if (ref-arg? arg) (begin (if previous-arg (heyc ", ")) (hey "C_to_Xen_~A(~A)" (no-stars (deref-type arg)) (deref-name arg)) (set! previous-arg #t)))) args) (hey "));~%") (if using-result (hey " }~%"))))) ;; refargs = 0 (begin (if (member name idlers) (hey " xm_unprotect_at(Xen_integer_to_C_int(Xen_caddr(~A)));~%" (cadar args))) (if (string=? return-type "void") (hey " return(Xen_false);~%"))))))) (begin ; 'lambda (see line 1846) (hey "if (Xen_is_aritable(func, 2))~%") (hey-start) (if (not (string=? return-type "void")) (hey-on " return(C_to_Xen_~A(~A(" (no-stars return-type) name) (hey-on " ~A(" name)) (hey-mark) (let ((previous-arg #f)) (for-each (lambda (arg) (let ((argname (cadr arg)) (argtype (car arg))) (if previous-arg (hey-ok ", ")) (set! previous-arg #t) (hey-on "Xen_to_C_~A(~A)" (no-stars argtype) argname))) args)) (if (not (string=? return-type "void")) (hey ")));~%") (hey ");~%")) (hey " else~%") (hey-start) (if (not (string=? return-type "void")) (hey-on " return(C_to_Xen_~A(~A(" (no-stars return-type) name) (hey-on " ~A(" name)) (hey-mark) (let ((previous-arg #f)) (for-each (lambda (arg) (let ((argname (cadr arg)) (argtype (car arg))) (if previous-arg (hey-ok ", ")) (set! previous-arg #t) (hey-on "Xen_to_C_~A(~A)" (no-stars argtype) argname))) args)) (if (string=? return-type "void") (begin (hey ");~%") (hey " return(Xen_false);~%")) (hey ")));~%")) (hey " }~%")) ;'lambda ))) ; 'begin (if (eq? spec 'free) (hey " rtn = C_to_Xen_~A(result);~% g_free(result);~% return(rtn);~% }~%" (no-stars return-type))) (hey "}~%~%") )))) (for-each handle-func (reverse funcs)) (for-each (lambda (func-list with-func) (if (pair? func-list) (with-func hey (lambda () (for-each handle-func (reverse func-list)))))) all-funcs all-func-withs) (hey "#define Xen_is_wrapped_object(Obj) (Xen_is_list(Obj) && (Xen_list_length(Obj) >= 2) && (Xen_is_symbol(Xen_car(Obj))))~%~%") (define cast-it (lambda (cast) (let ((cast-name (car cast)) (cast-type (cadr cast))) (hey "static Xen gxg_~A(Xen obj)" (no-arg cast-name)) (hey " {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_~A_symbol, Xen_cadr(obj)) : Xen_false);}~%" (no-stars cast-type))))) (hey "static Xen gxg_GPOINTER(Xen obj)") (hey " {return(Xen_list_2(xg_gpointer_symbol, (Xen_is_wrapped_object(obj)) ? Xen_cadr(obj) : Xen_wrap_C_pointer(obj)));}~%") (for-each cast-it (reverse casts)) (for-each (lambda (cast-list cast-func) (if (pair? cast-list) (cast-func hey (lambda () (for-each cast-it (reverse cast-list)))))) all-casts all-cast-withs) ;;; checks have to use the built-in macros, not local symbol-based type checks (define (make-check func) (hey "static Xen gxg_~A(Xen obj)" (no-arg (car func))) (hey " {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && ~A((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));}~%" (no-arg (car func)))) (for-each make-check (reverse checks)) (for-each (lambda (check-list check-func) (if (pair? check-list) (check-func hey (lambda () (for-each make-check (reverse check-list)))))) all-checks all-check-withs) (hey "~%~%/* ---------------------------------------- special functions ---------------------------------------- */~%~%") ;;; from Mike Scholz -- improve the error checking (hey "static Xen gxg_gtk_init(Xen argc, Xen argv) ~%") (hey "{ ~%") (hey " #define H_gtk_init \"void gtk_init(int* argc, char*** argv)\" ~%") (hey " int ref_argc = 0; ~%") (hey " char** ref_argv = NULL; ~%") (hey " if (Xen_is_bound(argv)) ~%") (hey " { ~%") (hey " if (Xen_is_bound(argc) && Xen_is_integer(argc) && Xen_to_C_int(argc) <= Xen_list_length(argv)) ~%") (hey " ref_argc = Xen_to_C_int(argc); ~%") (hey " else ref_argc = Xen_list_length(argv); ~%") (hey " } ~%") (hey " ref_argv = (char**)calloc(ref_argc, sizeof(char*)); ~%") (hey " { ~%") (hey " int i; ~%") (hey " Xen lst; ~%") (hey " lst = Xen_copy_arg(argv); ~%") (hey " for (i = 0; i < ref_argc; i++, lst = Xen_cdr(lst)) ref_argv[i] = Xen_to_C_char_(Xen_car(lst));~%") (hey " }~%") (hey " gtk_init(&ref_argc, &ref_argv);~%") (hey " return(Xen_list_2(C_to_Xen_int(ref_argc), C_to_Xen_char__(ref_argv)));~%") (hey "} ~%") (hey "~%") (hey "static Xen gxg_gtk_init_check(Xen argc, Xen argv) ~%") (hey "{ ~%") (hey " #define H_gtk_init_check \"gboolean gtk_init_check(int* argc, char*** argv)\" ~%") (hey " int ref_argc = 0; ~%") (hey " char** ref_argv = NULL; ~%") (hey " if (Xen_is_bound(argc) && Xen_is_list(argc)) ~%") (hey " { ~%") (hey " argv = argc; ~%") (hey " ref_argc = Xen_list_length(argv); ~%") (hey " } ~%") (hey " else ~%") (hey " {~%") (hey " if (Xen_is_bound(argv)) ~%") (hey " { ~%") (hey " int len; ~%") (hey " Xen_check_type(Xen_is_integer(argc), argc, 1, \"gtk_init_check\", \"int argc\"); ~%") (hey " Xen_check_type(Xen_is_list(argv), argv, 2, \"gtk_init_check\", \"char *argv[]\"); ~%") (hey " len = Xen_list_length(argv); ~%") (hey " ref_argc = Xen_to_C_int(argc); ~%") (hey " if (ref_argc > len) ref_argc = len; ~%") (hey " }~%") (hey " }~%") (hey " ref_argv = (char**)calloc(ref_argc, sizeof(char*)); ~%") (hey " { ~%") (hey " int i; ~%") (hey " Xen lst; ~%") (hey " lst = Xen_copy_arg(argv); ~%") (hey " for (i = 0; i < ref_argc; i++, lst = Xen_cdr(lst)) ref_argv[i] = Xen_to_C_char_(Xen_car(lst));~%") (hey " }~%") (hey " {~%") (hey " Xen result;~%") (hey " result = C_to_Xen_gboolean(gtk_init_check(&ref_argc, &ref_argv));~%") (hey " return(Xen_list_3(result, C_to_Xen_int(ref_argc), C_to_Xen_char__(ref_argv)));~%") (hey " }~%") (hey "}~%~%") (hey "static Xen gxg_make_target_entry(Xen lst)~%") (hey "{~%") (hey " GtkTargetEntry* targets;~%") (hey " int i, len;~%") (hey " #define H_make_target_entry \"(make-target-entry lst): GtkTargetEntry*, each member of 'lst' should be (list target flags info)\"~%") (hey " Xen_check_type(Xen_is_list(lst), lst, 1, \"make-target-entry\", \"a list of lists describing each target\");~%") (hey " len = Xen_list_length(lst);~%") (hey " if (len == 0) return(Xen_false);~%") (hey " targets = (GtkTargetEntry *)calloc(len, sizeof(GtkTargetEntry));~%") (hey " for (i = 0; i < len; i++)~%") (hey " {~%") (hey " Xen val;~%") (hey " val = Xen_list_ref(lst, i);~%") (hey " targets[i].target = xen_strdup(Xen_string_to_C_string(Xen_list_ref(val, 0)));~%") (hey " targets[i].flags = (guint)Xen_ulong_to_C_ulong(Xen_list_ref(val, 1));~%") (hey " targets[i].info = (guint)Xen_ulong_to_C_ulong(Xen_list_ref(val, 2));~%") (hey " }~%") (hey " return(C_to_Xen_GtkTargetEntry_(targets));~%") (hey "}~%") (define (array->list type) (hey " if (ctype == xg_~A_symbol)~%" (no-stars type)) (hey " {~%") (hey " ~A arr; arr = (~A)Xen_unwrap_C_pointer(Xen_cadr(val)); ~%" type type) (hey " if (len == -1) {for (i = 0; arr[i]; i++) {}; len = i;}~%") (hey " for (i = len - 1; i >= 0; i--) result = Xen_cons(C_to_Xen_~A(arr[i]), result);~%" (no-stars (deref-type (list type)))) (hey " }~%")) (define (list->array type) (hey " if (type == xg_~A_symbol)~%" (no-stars type)) (hey " {~%") (hey " ~A arr; arr = (~A)calloc(len + 1, sizeof(~A));~%" type type (deref-type (list type))) (hey " for (i = 0; i < len; i++, val = Xen_cdr(val)) arr[i] = Xen_to_C_~A(Xen_car(val));~%" (no-stars (deref-type (list type)))) (hey " return(Xen_list_3(xg_~A_symbol, Xen_wrap_C_pointer(arr), make_xm_obj(arr)));~%" (no-stars type)) (hey " }~%")) (hey "/* conversions */~%") (hey "static Xen c_array_to_xen_list(Xen val_1, Xen clen)~%") (hey "{~%") (hey " Xen result = Xen_empty_list;~%") (hey " Xen val, ctype;~%") (hey " int i, len = -1;~%") (hey " if (Xen_is_integer(clen))~%") (hey " len = Xen_integer_to_C_int(clen);~%") (hey " if (!(Xen_is_list(val_1))) return(Xen_false); /* type:location cons */~%") (hey " val = Xen_copy_arg(val_1); /* protect Ruby arg */~%") (hey " ctype = Xen_car(val);~%") (for-each array->list listable-types) (for-each (lambda (type) (if (and (derefable type) (not (member type listable-types)) (not (string=? type "GError*")) (not (string=? type "GError**")) (member (deref-type (list type)) types)) (array->list type))) types) ;;; gotta handle GList* by hand (hey " if (ctype == xg_GList__symbol)~%") (hey " { /* tagging these pointers is currently up to the caller */~%") (hey " GList* lst;~%") (hey " lst = (GList*)Xen_unwrap_C_pointer(Xen_cadr(val));~%") (hey " len = g_list_length(lst);~%") (hey " for (i = len - 1; i >= 0; i--) result = Xen_cons(C_ulong_to_Xen_ulong(g_list_nth_data(lst, i)), result);~%") (hey " }~%") (hey " return(result);~%") (hey "}~%~%") (hey "static Xen xg_object_get(Xen val, Xen name, Xen string_type)~%") (hey "{~%") (hey " gint temp; gchar *str;~%") (hey " Xen_check_type(Xen_is_gpointer(val), val, 1, \"g_object_get\", \"gpointer\");~%") (hey " Xen_check_type(Xen_is_string(name), name, 2, \"g_object_get\", \"string\");~%") (hey " if (Xen_is_false(string_type))~%") (hey " {g_object_get(Xen_to_C_gpointer(val), (const gchar *)(Xen_string_to_C_string(name)), &temp, NULL); return(C_int_to_Xen_integer(temp));}~%") (hey " else {g_object_get(Xen_to_C_gpointer(val), (const gchar *)(Xen_string_to_C_string(name)), &str, NULL); return(C_string_to_Xen_string(str));}~%") (hey "}~%~%") ;;; (g_object_get (GPOINTER (gtk_settings_get_default)) "gtk-enable-tooltips" #f) (hey "static Xen xg_object_set(Xen val, Xen name, Xen new_val)~%") (hey "{~%") (hey " Xen_check_type(Xen_is_gpointer(val), val, 1, \"g_object_set\", \"gpointer\");~%") (hey " Xen_check_type(Xen_is_string(name), name, 2, \"g_object_set\", \"string\");~%") (hey " if (Xen_is_boolean(new_val))~%") (hey " g_object_set(Xen_to_C_gpointer(val), (const gchar *)(Xen_string_to_C_string(name)), Xen_boolean_to_C_bool(new_val), NULL);~%") (hey " else~%") (hey " {~%") (hey " if (Xen_is_number(new_val))~%") (hey " g_object_set(Xen_to_C_gpointer(val), (const gchar *)(Xen_string_to_C_string(name)), Xen_integer_to_C_int(new_val), NULL);~%") (hey " else g_object_set(Xen_to_C_gpointer(val), (const gchar *)(Xen_string_to_C_string(name)), Xen_string_to_C_string(new_val), NULL);~%") (hey " }~%") (hey " return(new_val);~%") (hey "}~%~%") (hey "static Xen xg_gtk_event_keyval(Xen event)~%") (hey "{~%") (hey " GdkEventKey *e;~%") (hey " e = Xen_to_C_GdkEventKey_(event);~%") (hey " if (e) return(C_int_to_Xen_integer((int)(e->keyval))); return(XEN_ZERO);~%") (hey "}~%~%") (hey "static Xen xen_list_to_c_array(Xen val, Xen type)~%") (hey "{~%") (hey " int i, len;~%") (hey " len = Xen_list_length(val);~%") (for-each list->array listable-types) (for-each (lambda (type) (if (and (derefable type) (not (member type listable-types)) (not (string=? type "GError*")) (not (string=? type "GError**")) (member (deref-type (list type)) types)) (list->array type))) types) (hey " return(Xen_false);~%") (hey "}~%") (hey "static Xen gxg_make_GtkTextIter(void)~%") (hey "{~%") (hey " GtkTextIter* result;~%") (hey " result = (GtkTextIter*)calloc(1, sizeof(GtkTextIter));~%") (hey " return(Xen_list_3(C_string_to_Xen_symbol(\"GtkTextIter_\"), Xen_wrap_C_pointer(result), make_xm_obj(result)));~%") (hey "}~%") (hey "~%") (hey "static Xen gxg_make_GtkTreeIter(void)~%") (hey "{~%") (hey " GtkTreeIter* result;~%") (hey " result = (GtkTreeIter*)calloc(1, sizeof(GtkTreeIter));~%") (hey " return(Xen_list_3(C_string_to_Xen_symbol(\"GtkTreeIter_\"), Xen_wrap_C_pointer(result), make_xm_obj(result)));~%") (hey "}~%") (hey "~%") (hey "static Xen gxg_make_PangoRectangle(void)~%") (hey "{~%") (hey " PangoRectangle* result;~%") (hey " result = (PangoRectangle*)calloc(1, sizeof(PangoRectangle));~%") (hey " return(Xen_list_3(C_string_to_Xen_symbol(\"PangoRectangle_\"), Xen_wrap_C_pointer(result), make_xm_obj(result)));~%") (hey "}~%") (hey "~%") (hey "static Xen gxg_make_cairo_matrix_t(void)~%") (hey "{~%") (hey " cairo_matrix_t* result;~%") (hey " result = (cairo_matrix_t*)calloc(1, sizeof(cairo_matrix_t));~%") (hey " return(Xen_list_3(C_string_to_Xen_symbol(\"cairo_matrix_t_\"), Xen_wrap_C_pointer(result), make_xm_obj(result)));~%") (hey "}~%~%") (hey "#if GTK_CHECK_VERSION(3, 0, 0)~%") (hey "static Xen gxg_make_GdkRGBA(void)~%") (hey "{~%") (hey " GdkRGBA* result;~%") (hey " result = (GdkRGBA*)calloc(1, sizeof(GdkRGBA));~%") (hey " return(Xen_list_3(C_string_to_Xen_symbol(\"GdkRGBA_\"), Xen_wrap_C_pointer(result), make_xm_obj(result)));~%") (hey "}~%") (hey "#endif~%~%") (hey "#if HAVE_SCHEME~%") (hey " #define Xg_define_procedure(Name, Value, A1, A2, A3, Help, Sig) s7_define_typed_function(s7, Xg_pre #Name Xg_post, Value, A1, A2, A3, Help, Sig)~%") (hey "#else~%") (hey " #define Xg_define_procedure(Name, Value, A1, A2, A3, Help, Sig) Xen_define_safe_procedure(Xg_pre #Name Xg_post, Value, A1, A2, A3, Help)~%") (hey "#endif~%") (hey "~%") (hey "Xen_wrap_no_args(gxg_make_GtkTextIter_w, gxg_make_GtkTextIter)~%") (hey "Xen_wrap_no_args(gxg_make_GtkTreeIter_w, gxg_make_GtkTreeIter)~%") (hey "Xen_wrap_no_args(gxg_make_PangoRectangle_w, gxg_make_PangoRectangle)~%") (hey "Xen_wrap_no_args(gxg_make_cairo_matrix_t_w, gxg_make_cairo_matrix_t)~%") (hey "#if GTK_CHECK_VERSION(3, 0, 0)~%") (hey "Xen_wrap_no_args(gxg_make_GdkRGBA_w, gxg_make_GdkRGBA)~%") (hey "#endif~%") (hey "~%~%") (hey "static void define_structs(void)~%") (hey "{~%") (hey " Xg_define_procedure(GtkTextIter, gxg_make_GtkTextIter_w, 0, 0, 0, \"(GtkTextIter): a new GtkTextIter struct\", NULL);~%") (hey " Xg_define_procedure(GtkTreeIter, gxg_make_GtkTreeIter_w, 0, 0, 0, \"(GtkTreeIter): a new GtkTreeIter struct\", NULL);~%") (hey " Xg_define_procedure(PangoRectangle, gxg_make_PangoRectangle_w, 0, 0, 0, \"(PangoRectangle): a new PangoRectangle struct\", NULL);~%") (hey " Xg_define_procedure(cairo_matrix_t, gxg_make_cairo_matrix_t_w, 0, 0, 0, \"(cairo_matrix_t): a new cairo_matrix_t struct\", NULL);~%") (hey "#if GTK_CHECK_VERSION(3, 0, 0)~%") (hey " Xg_define_procedure(GdkRGBA, gxg_make_GdkRGBA_w, 0, 0, 0, \"(GdkRGBA): a new GdkRGBA struct\", NULL);~%") (hey "#endif~%") (hey "}~%~%") ;;; ---------------- argify ---------------- (define (argify-func func) (let ((cargs (length (caddr func))) (refargs (+ (ref-args (caddr func)) (opt-args (caddr func)))) ;(args (- cargs refargs)) ) (hey "Xen_wrap_~A(gxg_~A_w, gxg_~A)~%" (if (>= cargs max-args) "any_args" (if (> refargs 0) (format #f "~D_optional_arg~A" cargs (if (= cargs 1) "" "s")) (format #f "~A_arg~A" (if (zero? cargs) "no" (number->string cargs)) (if (= cargs 1) "" "s")))) (car func) (car func)))) (define (unargify-func func) (let (;(cargs (length (caddr func))) ;(refargs (+ (ref-args (caddr func)) (opt-args (caddr func)))) ;(args (- cargs refargs)) ) (hey "#define gxg_~A_w gxg_~A~%" (car func) (car func)))) (for-each argify-func (reverse funcs)) (for-each (lambda (func-list with-func) (if (pair? func-list) (with-func hey (lambda () (for-each argify-func (reverse func-list)))))) all-funcs all-func-withs) (hey "Xen_wrap_1_arg(gxg_GPOINTER_w, gxg_GPOINTER)~%") (hey "Xen_wrap_2_args(c_array_to_xen_list_w, c_array_to_xen_list)~%") (hey "Xen_wrap_2_args(xen_list_to_c_array_w, xen_list_to_c_array)~%") (hey "Xen_wrap_1_arg(gxg_make_target_entry_w, gxg_make_target_entry)~%") (hey "Xen_wrap_3_args(xg_object_get_w, xg_object_get)~%") (hey "Xen_wrap_3_args(xg_object_set_w, xg_object_set)~%") (hey "Xen_wrap_1_arg(xg_gtk_event_keyval_w, xg_gtk_event_keyval)~%") (hey "Xen_wrap_2_optional_args(gxg_gtk_init_w, gxg_gtk_init)~%") (hey "Xen_wrap_2_optional_args(gxg_gtk_init_check_w, gxg_gtk_init_check)~%") (define (ruby-cast func) (hey "Xen_wrap_1_arg(gxg_~A_w, gxg_~A)~%" (no-arg (car func)) (no-arg (car func)))) (for-each ruby-cast (reverse casts)) (for-each (lambda (cast-list cast-func) (if (pair? cast-list) (cast-func hey (lambda () (for-each ruby-cast (reverse cast-list)))))) all-casts all-cast-withs) (define (ruby-check func) (hey "Xen_wrap_1_arg(gxg_~A_w, gxg_~A)~%" (no-arg (car func)) (no-arg (car func)))) (for-each ruby-check (reverse checks)) (for-each (lambda (check-list check-func) (if (pair? check-list) (check-func hey (lambda () (for-each ruby-check (reverse check-list)))))) all-checks all-check-withs) ;;; -------------------------------------------------------------------------------- (hey "#if HAVE_SCHEME~%") (define (gtk-type->s7-type gtk) (let ((dt (assoc gtk direct-types))) (if (and (pair? dt) (string? (cdr dt))) (let ((direct (cdr dt))) (cond ((member direct '("INT" "ULONG") string=?) 'integer?) ((string=? direct "BOOLEAN") 'boolean?) ((string=? direct "DOUBLE") 'real?) ((string=? direct "String") 'string?) (#t #t))) (or (not (has-stars gtk)) 'pair?)))) (define (make-signature fnc) (define (compress sig) (if (and (pair? sig) (pair? (cdr sig)) (or (not (eq? (car sig) 'pair?)) (not (null? (cddr sig)))) (eq? (car sig) (cadr sig))) (compress (cdr sig)) sig)) (let ((sig (list (gtk-type->s7-type (cadr fnc))))) (for-each (lambda (arg) (set! sig (cons (gtk-type->s7-type (car arg)) sig))) (caddr fnc)) (reverse (compress sig)))) (define signatures (make-hash-table)) (define (make-signatures lst) (for-each (lambda (f) (let ((sig (make-signature f))) (if (pair? sig) (let ((count (signatures sig))) (if (not count) (set! (signatures sig) 0) (set! (signatures sig) (+ count 1))))))) lst)) (make-signatures funcs) (for-each make-signatures all-funcs) ;(format *stderr* "~D entries, ~D funcs~%" (hash-table-entries signatures) (length funcs)) (hey "static s7_pointer s_boolean, s_integer, s_real, s_string, s_any, s_pair, s_float, s_pair_false;~%") (hey "static s7_pointer ") (define (sig-name sig) (call-with-output-string (lambda (p) (display "pl_" p) (display (case (car sig) ((integer?) "i") ((boolean?) "b") ((real?) "d") ((string?) "s") ((pair?) "p") (else "t")) p) (for-each (lambda (typ) (display (case typ ((integer?) "i") ((boolean?) "b") ((real?) "r") ((string?) "s") ((pair?) "u") ; because we're stupidly using #f=null (else "t")) p)) (cdr sig))))) (for-each (lambda (sigc) (let ((sig (car sigc))) (hey (sig-name sig)) (hey ", "))) signatures) (hey "pl_unused;~%") (hey "#endif~%~%") ;;; -------------------------------------------------------------------------------- (hey "static void define_functions(void)~%") (hey "{~%") (hey " xm_gc_table = Xen_make_vector(1, Xen_false);~%") (hey " Xen_GC_protect(xm_gc_table);~%") (hey " xm_protected_size = 512;~%") (hey " xm_protected = Xen_make_vector(xm_protected_size, Xen_false);~%") (hey " Xen_vector_set(xm_gc_table, 0, xm_protected);~%~%") (hey "#if HAVE_SCHEME~%") (hey " s_boolean = s7_make_symbol(s7, \"boolean?\");~%") (hey " s_integer = s7_make_symbol(s7, \"integer?\");~%") (hey " s_real = s7_make_symbol(s7, \"real?\");~%") (hey " s_float = s7_make_symbol(s7, \"float?\");~%") (hey " s_string = s7_make_symbol(s7, \"string?\");~%") (hey " s_pair = s7_make_symbol(s7, \"pair?\");~%") (hey " s_pair_false = s7_make_signature(s7, 2, s_pair, s_boolean);~%") (hey " s_any = s7_t(s7);~%~%") (for-each (lambda (sigc) (let ((sig (car sigc))) (hey " ") (hey (sig-name sig)) (hey " = s7_make_circular_signature(s7, ") (let ((len (length sig))) (hey (number->string (- len 1))) (hey ", ") (hey (number->string len)) (hey ", ") (hey (case (car sig) ((integer?) "s_integer") ((boolean?) "s_boolean") ((real?) "s_float") ((string?) "s_string") ((pair?) "s_pair") (else "s_any"))) (if (> len 1) (hey ", ")) (do ((i 1 (+ i 1)) (s (cdr sig) (cdr s))) ((= i len)) (let ((typ (car s))) (hey (case typ ((integer?) "s_integer") ((boolean?) "s_boolean") ((real?) "s_real") ((string?) "s_string") ((pair?) "s_pair_false") (else "s_any")))) (if (< i (- len 1)) (hey ", ")))) (hey ");~%"))) signatures) (hey "pl_unused = NULL;~%") (hey "#endif~%~%") (define (defun func) (let* ((cargs (length (caddr func))) (refargs (+ (ref-args (caddr func)) (opt-args (caddr func)))) (args (- cargs refargs)) ;(return-type (cadr func)) ;(typ (assoc return-type direct-types)) ) (hey " Xg_define_procedure(~A, gxg_~A_w, ~D, ~D, ~D, H_~A, ~A);~%" (car func) (car func) (if (>= cargs max-args) 0 args) (if (>= cargs max-args) 0 refargs) (if (>= cargs max-args) 1 0) (car func) (sig-name (make-signature func))))) (for-each defun (reverse funcs)) (for-each (lambda (func-list with-func) (if (pair? func-list) (with-func hey (lambda () (for-each defun (reverse func-list)))))) all-funcs all-func-withs) (define (cast-out func) (hey " Xg_define_procedure(~A, gxg_~A_w, 1, 0, 0, \"(~A obj) casts obj to ~A\", NULL);~%" (no-arg (car func)) (no-arg (car func)) (no-arg (car func)) (no-arg (car func)))) (hey " Xg_define_procedure(GPOINTER, gxg_GPOINTER_w, 1, 0, 0, \"(GPOINTER obj) casts obj to GPOINTER\", NULL);~%") (for-each cast-out (reverse casts)) (for-each (lambda (cast-list cast-func) (if (pair? cast-list) (cast-func hey (lambda () (for-each cast-out (reverse cast-list)))))) all-casts all-cast-withs) (hey " Xg_define_procedure(c-array->list, c_array_to_xen_list_w, 2, 0, 0, NULL, NULL);~%") (hey " Xg_define_procedure(list->c-array, xen_list_to_c_array_w, 2, 0, 0, NULL, NULL);~%") (hey " Xg_define_procedure(make-target-entry, gxg_make_target_entry_w, 1, 0, 0, H_make_target_entry, NULL);~%") (hey " Xg_define_procedure(g_object_get, xg_object_get_w, 3, 0, 0, NULL, NULL);~%") (hey " Xg_define_procedure(g_object_set, xg_object_set_w, 3, 0, 0, NULL, NULL);~%") (hey " Xg_define_procedure(gtk_event_keyval, xg_gtk_event_keyval_w, 1, 0, 0, NULL, NULL);~%") (hey " Xg_define_procedure(gtk_init, gxg_gtk_init_w, 0, 2, 0, H_gtk_init, NULL);~%") (hey " Xg_define_procedure(gtk_init_check, gxg_gtk_init_check_w, 0, 2, 0, H_gtk_init_check, NULL);~%") (define (check-out func) (hey " Xg_define_procedure(~A, gxg_~A_w, 1, 0, 0, \"(~A obj): \" PROC_TRUE \" if obj is a ~A\", NULL);~%" (no-arg (car func)) (no-arg (car func)) (no-arg (car func)) (no-arg (car func)))) (for-each check-out (reverse checks)) (for-each (lambda (check-list check-func) (if (pair? check-list) (check-func hey (lambda () (for-each check-out (reverse check-list)))))) all-checks all-check-withs) (hey "}~%~%") (hey "/* ---------------------------------------- constants ---------------------------------------- */~%~%") (hey "static void define_integers(void)~%") (hey "{~%") (hey "#define define_integer(Name) Xen_define(Xg_pre #Name Xg_post, C_int_to_Xen_integer(Name))~%") (hey "~%") (hey "#if !GLIB_CHECK_VERSION(2,35,0)~%") (hey " g_type_init();~%") (hey "#endif~%") (for-each (lambda (val) (hey " define_integer(~A);~%" val)) (reverse ints)) (for-each (lambda (ints-list with-ints) (if (pair? ints-list) (with-ints hey (lambda () (for-each (lambda (val) (hey " define_integer(~A);~%" val)) (reverse ints-list)))))) all-ints all-int-withs) (hey "}~%~%") (hey "static void define_doubles(void)~%") (hey "{~%") (hey "#define define_double(Name) Xen_define(Xg_pre #Name Xg_post, C_double_to_Xen_real(Name))~%") (hey "~%") (for-each (lambda (val) (hey " define_double(~A);~%" val)) (reverse dbls)) (hey "}~%~%") (hey "/* -------------------------------- predefined Atoms -------------------------------- */~%") (hey "~%") (hey "static void define_atoms(void)~%") (hey "{~%") (hey "#define define_atom(Name) Xen_define(Xg_pre #Name Xg_post, C_to_Xen_GdkAtom(Name))~%") (hey "~%") (for-each (lambda (atom) (hey " define_atom(~A);~%" atom)) (reverse atoms)) (hey "}~%~%") (hey "/* -------------------------------- symbols -------------------------------- */~%") (hey "~%") (hey "static void define_symbols(void)~%") (hey "{~%") (for-each (lambda (typ) (hey " xg_~A_symbol = C_string_to_Xen_symbol(\"~A\");~%" (no-stars typ) (no-stars typ))) all-types) (for-each (lambda (typ) (hey " xg_~A_symbol = C_string_to_Xen_symbol(\"~A\");~%" typ typ)) other-types) (hey "}~%~%") (hey "/* -------------------------------- strings -------------------------------- */~%") (hey "~%") (hey "static void define_strings(void)~%") (hey "{~%") (hey " ~%") (hey "#define define_string(Name) Xen_define(Xg_pre #Name Xg_post, C_string_to_Xen_string(Name))~%") (for-each (lambda (str) (hey " define_string(~A);~%" str)) (reverse strings)) (for-each (lambda (strings-list with-strings) (if (pair? strings-list) (with-strings hey (lambda () (for-each (lambda (str) (hey " define_string(~A);~%" str)) (reverse strings-list)))))) all-strings all-string-withs) (hey "}~%~%") (hey "/* -------------------------------- initialization -------------------------------- */~%~%") (hey "static bool xg_already_inited = false;~%~%") (hey "void Init_libxg(void);~%") (hey "void Init_libxg(void)~%") (hey "{~%") (hey " if (!xg_already_inited)~%") (hey " {~%") (hey " define_symbols();~%") (hey " define_xm_obj();~%") (hey " define_integers();~%") (hey " define_doubles();~%") (hey " define_functions();~%") (hey " define_atoms();~%") (hey " define_strings();~%") (hey " define_structs();~%") (hey " Xen_provide_feature(\"xg\");~%") (hey " #if GTK_CHECK_VERSION(3, 0, 0)~%") (hey " Xen_provide_feature(\"gtk3\");~%") (hey " #else~%") (hey " Xen_provide_feature(\"gtk2\");~%") (hey " #endif~%") (hey " Xen_define(\"xg-version\", C_string_to_Xen_string(\"~A\"));~%" (strftime "%d-%b-%y" (localtime (current-time)))) (hey " xg_already_inited = true;~%") (hey "#if HAVE_SCHEME~%") (hey "#if USE_SND~%") (hey " /* these are macros in glib/gobject/gsignal.h, but we want the types handled in some convenient way in the extension language */~%") (hey " s7_define(s7, s7_nil(s7), s7_make_symbol(s7, \"g_signal_connect\"),\n Xen_eval_C_string(\"(lambda (obj name func . data)\\\n ((*gtk* 'g_signal_connect_data) ((*gtk* 'GPOINTER) obj) name func (and (pair? data) (car data)) #f 0))\"));~%") (hey " s7_define(s7, s7_nil(s7), s7_make_symbol(s7, \"g_signal_connect_after\"),\n Xen_eval_C_string(\"(lambda (obj name func . data)\\\n ((*gtk* 'g_signal_connect_data) ((*gtk* 'GPOINTER) obj) name func (and (pair? data) (car data)) #f (*gtk* 'G_CONNECT_AFTER)))\"));~%") (hey " s7_define(s7, s7_nil(s7), s7_make_symbol(s7, \"g_signal_connect_swapped\"),\n Xen_eval_C_string(\"(lambda (obj name func . data)\\\n ((*gtk* 'g_signal_connect_data) ((*gtk* 'GPOINTER) obj) name func (and (pair? data) (car data)) #f (*gtk* 'G_CONNECT_SWAPPED)))\"));~%") (hey "#else~%") (hey " Xen_eval_C_string(\"(define (g_signal_connect obj name func . data) (g_signal_connect_data (GPOINTER obj) name func (and (pair? data) (car data)) #f 0))\");~%") (hey " Xen_eval_C_string(\"(define (g_signal_connect_after obj name func . data) (g_signal_connect_data (GPOINTER obj) name func (and (pair? data) (car data)) #f G_CONNECT_AFTER))\");~%") (hey " Xen_eval_C_string(\"(define (g_signal_connect_swapped obj name func . data) (g_signal_connect_data (GPOINTER obj) name func (and (pair? data) (car data)) #f G_CONNECT_SWAPPED))\");~%") (hey "#endif~%") (hey "#endif~%") (hey "#if HAVE_RUBY ~%") (hey " Xen_eval_C_string(\"def Rg_signal_connect(obj, name, func, data = false); Rg_signal_connect_data(RGPOINTER(obj), name, func, data, false, 0); end\"); ~%") (hey " Xen_eval_C_string(\"def Rg_signal_connect_after(obj, name, func, data = false); Rg_signal_connect_data(RGPOINTER(obj), name, func, data, false, RG_CONNECT_AFTER); end\"); ~%") (hey " Xen_eval_C_string(\"def Rg_signal_connect_swapped(obj, name, func, data = false); Rg_signal_connect_data(RGPOINTER(obj), name, func, data, false, RG_CONNECT_SWAPPED); end\"); ~%") (hey "#endif ~%") (hey "#if HAVE_FORTH ~%") (hey " Xen_eval_C_string(\": Fg_signal_connect <{ obj name func :optional data #f -- n }> obj FGPOINTER name func data #f 0 Fg_signal_connect_data ;\"); ~%") (hey " Xen_eval_C_string(\": Fg_signal_connect_after <{ obj name func :optional data #f -- n }> obj FGPOINTER name func data #f FG_CONNECT_AFTER Fg_signal_connect_data ;\"); ~%") (hey " Xen_eval_C_string(\": Fg_signal_connect_swapped <{ obj name func :optional data #f -- n }> obj FGPOINTER name func data #f FG_CONNECT_SWAPPED Fg_signal_connect_data ;\"); ~%") (hey "#endif ~%") (hey " }~%") (hey "}~%") (hey "#else~%") (hey " void Init_libxg(void);~%") (hey " void Init_libxg(void)~%") (hey "{~%") (hey "}~%") (hey "#endif~%") ; have_extension_language (close-output-port xg-file) #| (for-each (lambda (type) (if (not (assoc type direct-types)) (format #t ";not direct: ~A~%" type))) declared-types) (for-each (lambda (v) (if (not (member (car v) declared-types)) (format #t "~A " (car v)))) direct-types) |# (exit) snd-16.1/tools/sam.c0000644000076400007640000023616112371741424012435 0ustar bilbil/* a samson box emulator */ /* I assume what people really want is a good rendition from their ancient SAM files, * not an exact replica of the Samson box output. The latter used 12, 14, 20, 24, 28, and 30-bit * fractional and integer fields, which are a pain to deal with when we would rather use doubles. * * gcc sam.c -o sam -lm -O2 * sam TEST.SAM * -> TEST.wav ("wav" or "riff" header, quad, little-endian float data at box srate) * * to include a read-data file, convert the old SAD file to a raw file of little-endian floats, * then sam TEST.SAM test.snd * * here's the Snd code I use to turn quad into stereo and scale the result to .9: * (define* (quad->stereo (snd 0)) "turn a quad sound into a (new) stereo sound by mixing 4->1 and 3->2" (let ((r0 (make-sampler 0 snd 0)) (r1 (make-sampler 0 snd 1)) (r2 (make-sampler 0 snd 2)) (r3 (make-sampler 0 snd 3))) (let ((new-snd (new-sound :channels 2 :srate (srate snd) :size (frames snd) :header-type (header-type snd) :sample-type (sample-type snd)))) (map-channel (lambda (y) (+ (next-sample r0) (next-sample r3))) 0 (frames snd) new-snd 0) (map-channel (lambda (y) (+ (next-sample r1) (next-sample r2))) 0 (frames snd) new-snd 1) (let* ((mx (apply max (maxamp new-snd #t))) (scl (/ 0.9 mx))) (map-channel (lambda (y) (* y scl)) 0 (frames snd) new-snd 0) (map-channel (lambda (y) (* y scl)) 0 (frames snd) new-snd 1))))) * * * Thanks to Michael McNabb for bug fixes and enhancements! * And thanks to Peter Samson for going back to the schematics to answer our questions! */ #include #include #include #include #include #define TOTAL_SAMPLES -1 /* set TOTAL_SAMPLES to the number of samples you want computed, or -1 to compute all of them */ #define DEFAULT_DESCRIBE_COMMANDS false #define REPORT_BAD_COMMANDS true #define FLUSH_BAD_COMMANDS false #define FLUSH_TRAILING_LINGERS false static bool describe_commands = DEFAULT_DESCRIBE_COMMANDS; static int start_describing = -1, stop_describing = -1; static int dump_patch_at = -1; #define LDB(Cmd, Size, Position) ((Cmd >> Position) & ((1 << Size) - 1)) #define BIT(Cmd, Position) ((Cmd >> Position) & 1) #define TWOS_12(N) ((N < (1 << 11)) ? N : ((N & 0x7ff) - (1 << 11))) #define TWOS_20(N) ((N < (1 << 19)) ? N : ((N & 0x7ffff) - (1 << 19))) #define TWOS_24(N) ((N < (1 << 23)) ? N : ((N & 0x7fffff) - (1 << 23))) #define TWOS_28(N) ((N < (1 << 27)) ? N : ((N & 0x7ffffff) - (1 << 27))) #define TWOS_30(N) ((N < (1 << 29)) ? N : ((N & 0x1fffffff) - (1 << 29))) #define TWOS_12_TO_DOUBLE(N) ((double)TWOS_12(N) / (double)(1 << 11)) #define TWOS_20_TO_DOUBLE(N) ((double)TWOS_20(N) / (double)(1 << 19)) #define DOUBLE_12(N) ((double)N / (double)(1 << 11)) #define DOUBLE_20(N) ((double)N / (double)(1 << 19)) #define DOUBLE_24(N) ((double)N / (double)(1 << 23)) #define DOUBLE_28(N) ((double)N / (double)(1 << 27)) #define DOUBLE_30(N) ((double)N / (double)(1 << 29)) /* mmm -- slightly more accurate to use 1<<12-1, I think */ #define UNSIGNED_12_TO_DOUBLE(N) ((double)N / (double)((1 << 12) - 1)) #define DOUBLE_TO_TWOS_20(X) ((X >= 0.0) ? (int)(X * (1 << 19)) : (int)((X + 1.0) * (1 << 19))) #if (!defined(M_PI)) #define M_PI 3.14159265358979323846264338327 #define M_PI_2 (M_PI / 2.0) #endif typedef struct { int GO, GJ, GK, GN, GM, GP, GQ, GL, GSUM, GFM, GS, GMODE; double f_GO, f_GJ, f_GK, f_GM, f_GP, f_GQ, f_GL; } generator; typedef struct { int M0, M1, L0, L1, MIN, MRM, MSUM, MMODE, MMMMM, T, mult_scl_1, mult_scl_0, o_M0, o_M1; double f_M0, f_M1, f_L0, f_L1, o_f_M0, o_f_M1; /* by "2nd multiplication" I think Pete means M0 since it follows M1 so AA -> M0 and BB -> M1 */ } modifier; typedef struct { int P, Z, Y, X, I; /* "I" = table lookup index received from modifier */ double xd1, xd2; /* mmm - accounts for "extra" hidden delay */ } delay; #define SUM_MEMORY_SIZE 64 static double gen_outs[SUM_MEMORY_SIZE], gen_ins[SUM_MEMORY_SIZE], mod_outs[SUM_MEMORY_SIZE], mod_ins[SUM_MEMORY_SIZE]; /* "sum memory" */ static double prev_gen_ins[SUM_MEMORY_SIZE], prev_mod_ins[SUM_MEMORY_SIZE]; /* some debugging info */ static double peak_gen_ins[SUM_MEMORY_SIZE], peak_mod_ins[SUM_MEMORY_SIZE]; #define GENERATORS 256 #define MODIFIERS 128 #define DELAYS 32 static generator *gens[GENERATORS]; static modifier *mods[MODIFIERS]; static delay *dlys[DELAYS]; #define DELAY_MEMORY_SIZE 65536 static double delay_memory[DELAY_MEMORY_SIZE]; static float dac_out[4], dac_out_peak[4]; static int tick, pass, DX, processing_ticks, highest_tick_per_pass, samples = 0, srate = 1, total_commands = 0, current_command = 0; FILE *snd_file = NULL; /* for now just riff/wave quad, but srate depends on tick setting */ FILE *read_data_file = NULL; static char *filename = NULL; /* mmm - Keep SAM filename around */ static char *output_filename = NULL; /* mmm - And generate matching output file name == .wav */ static void start_clean(void) { int i; for (i = 0; i < SUM_MEMORY_SIZE; i++) { gen_outs[i] = 0.0; /* "outs" are this pass */ gen_ins[i] = 0.0; /* "ins" are last pass */ mod_outs[i] = 0.0; mod_ins[i] = 0.0; prev_mod_ins[i] = 0.0; prev_gen_ins[i] = 0.0; peak_mod_ins[i] = 0.0; peak_gen_ins[i] = 0.0; } for (i = 0; i < GENERATORS; i++) gens[i] = (generator *)calloc(1, sizeof(generator)); for (i = 0; i < MODIFIERS; i++) { mods[i] = (modifier *)calloc(1, sizeof(modifier)); mods[i]->mult_scl_1 = 1; mods[i]->mult_scl_0 = 1; } for (i = 0; i < DELAYS; i++) dlys[i] = (delay *)calloc(1, sizeof(delay)); for (i = 0; i < DELAY_MEMORY_SIZE; i++) delay_memory[i] = 0.0; for (i = 0; i < 4; i++) { dac_out[i] = 0.0; dac_out_peak[i] = 0.0; } tick = 0; pass = 0; } static void all_done(void) { if (snd_file) { int header_info[1]; fclose(snd_file); snd_file = fopen(output_filename, "r+"); /* mmm */ fseek(snd_file, 4L, SEEK_SET); header_info[0] = 88 + samples * 4 * 4; /* total data bytes 4 chans, 4 bytes/float */ fwrite((void *)header_info, 4, 1, snd_file); fseek(snd_file, 76L, SEEK_SET); header_info[0] = samples * 4 * 4; fwrite((void *)header_info, 4, 1, snd_file); fclose(snd_file); fprintf(stderr, "%s: %dHz, %d samples, %.4f secs", output_filename, srate, samples, (double)samples / (double)srate); /* mmm */ fprintf(stderr, ", maxamps: %.3f %.3f %.3f %.3f\n", dac_out_peak[0], dac_out_peak[1], dac_out_peak[2], dac_out_peak[3]); } exit(0); } static void dac_write(double data, int chan) { /* during a given pass we accumulate output to the dac */ dac_out[chan] += (float)(data / 2.0); /* mmm - /2 seems best now that other scalings have been adjusted */ } /* ---------------------------------------- generator processing ---------------------------------------- */ /* * DAJ - Here is JOS's translation into english of the generator processing. * * Associated with each generator are the following quantities: * FrqSwp20 (20 bits) alpha -- oscillator frequency sweep rate * OscFrq28 (28 bits) omega -- oscillator frequency * OscAng20 (20 bits) theta -- oscillator angle * NumCos11 (11 bits) number of cosines to be summed * CosScl4 (4 bits) binary scale of cosine or sum of cosines * AmpSwp20 (20 bits) delta -- decay rate * CurAmp24 (24 bits) phi -- decay exponent * AmpOff12 (12 bits) asymptote * OutSum6 (6 bits) sum memory address into which output is added * FmSum7 (7 bits) sum memory address from which frequency modulation data is taken * FmSum7 = QAAAAAA * Q: 0 generator-last-pass quadrant * 1 modifier-last-pass quadrant * AAAAAA: sum address within quadrant * Gmode10 (10 bits) generator mode * Gmode10 = RRRREESSSS * * Processing * ---------- * * Calculations performed for a generator, governed by its * mode, proceed as detailed below. * * 1) The word in sum memory addressed by FmSum7 is read (20 bits); * the sum is formed of it and the high-order 20 bits of * OscFrq28 (call the result FmPhase20). * * 2) If the oscillator side is running, FrqSwp20, right-adjusted with * sign extended, is added into OscFrq28. * * 3) If the oscillator mode is SIN(J+Fm), FmPhase20 is taken; otherwise OscAng20. * Call the 20-bit result Phase20, and its high-order 13 bits * Phase13. * * 4) If the oscillator side is running, FmPhase20 is added into OscAng20. * * 5) If the run mode is WRITEDATA, the word in sum memory addressed by FmSum7 * is sent to the CPU as the next write-data item; if the run * mode is DACOUT it is sent to the DAC addressed by the low-order * 4 bits of FrqSwp20. * * 6) In oscillator modes other than SIN(K) and SIN(J+Fm), Phase13 is multiplied * by NumCos11. Call the low-order 12 bits of the product, with two bits * equal to 01 appended to the right, the 14-bit result SinAdr. * In oscillator modes SIN(K) and SIN(J+Fm), SinAdr is the high-order 13 * bits of Phase20, with a bit equal to 1 appended to the right. * * 7) If the oscillator mode is SIN(K) or SIN(J+Fm), pi/2 is taken (the binary * number 010...0); otherwise Phase13. Call the result CscAdr. * * 8) In floating point, the product csc (CscAdr) * sin (SinAdr) is * formed; then converted to fixed point with a scale factor * of 2**(-CosScl4). Call the result (13 bits) TblOut13. * * * 9) The result of the oscillator side (13 bits, call it OscOut13) is * then determined according to the oscillator mode. * SSSS: SUMCOS TblOut13 * SAWTOOTH Phase13 (but 0 when Phase13 is 1000000000000) * SQUARE -1/2 (on a scale from -1 to +1) if Phase13 is negative, * else +1/2 * PULSE +1/2 if overflow occured in step 1) or 4) above; * else 0. * SIN(K) TblOut13 * SIN(J+Fm) TblOut13 * * 10) The high-order 12 bits of CurAmp24 are taken (call the result CurAmp12). * * 11) If the envelope side is running, AmpSwp20 right-adjusted, sign * extended, is added into CurAmp24 (overflow dealt with according * to the run mode). (The overflow condition is CurAmp24 changing * sign such that the high-order bit of the resultant CurAmp24 equals * the sign bit of AmpSwp20.) * * 12) If the envelope mode is 10 or 11, 2**(-CurAmp12) is looked up; * otherwise CurAmp12 is taken. Call the resulting 12 bits NewAmp12. * Scaling is such that if CurAmp12 is 0 then 2**(-CurAmp12) is * 111 111 111 101 binary; if CurAmp12 is 000 100 000 000 binary, * then 2**(-CurAmp12) is 011 111 111 110. * * 13) If the envelope mode is 01 or 11, NewAmp12 is added to AmpOff12; else * it is subtracted from AmpOff12. This creates Env12, the result * of the envelope side. * * 14) OscOut13 is multiplied by Env12. If the run mode specifies adding * into sum memory, the high-order 19 bits of the rounded product, * right-adjusted with sign extended, are added into the sum * memory location designated by OutSum6; except that in run mode * READDATA, the product is added to the next read-data item from the * CPU and the sum replaces the contents of the sum memory * location addressed. */ #define osc_mode(gmode) (gmode & 0xf) /* SSSS: 0100 sum of cosines 0001 sawtooth 0010 square 0011 pulse train 0000 sin (K) 1000 sin (J + fm) */ #define SUMCOS 4 #define SAWTOOTH 1 #define SQUARE 2 #define PULSE 3 #define SIN_K 0 #define SIN_FM 8 #define osc_env(gmode) ((gmode >> 4) & 0x3) /* EE: 00 L - Q 01 L + Q 10 L - 2**(-Q) 11 L + 2**(-Q) */ #define L_PLUS_Q 1 #define L_MINUS_Q 0 #define L_MINUS_2_TO_MINUS_Q 2 #define L_PLUS_2_TO_MINUS_Q 3 #define osc_run(gmode) ((gmode >> 6) & 0xf) static void set_osc_run(int gen, int RRRR) { generator *g; if (gen >= GENERATORS) {fprintf(stderr, "gen mode set overflow\n"); gen = 0;} g = gens[gen]; /* RRRREESSSS */ g->GMODE = (g->GMODE & 0x3f) | (RRRR << 6); if (g->GMODE == 3) g->GMODE = 2; /* if write data, send it to the DAC outputs instead */ } /* osc. run? env. run? add to sum? RRRR:0000 inactive no no no 0001 pause no no no 1111 running A yes yes, sticky yes 1110 running B yes yes, free; yes triggers subseq. on overflow 1001 wait yes no no 1101 running C yes yes, free; yes stops and triggers subseq. on overflow 0111 read data from computer no yes yes 0011 write data to computer no no no 0010 write data to DAC no no no (address in GO) */ static bool osc_is_running(int mode) { int RRRR; RRRR = osc_run(mode); return((RRRR == 15) || (RRRR == 14) || (RRRR == 9) || (RRRR == 13)); } static bool env_is_running(int mode) { int RRRR; RRRR = osc_run(mode); return((RRRR == 15) || (RRRR == 14) || (RRRR == 7) || (RRRR == 13)); } static bool adding_to_sum(int mode) { int RRRR; RRRR = osc_run(mode); return((RRRR == 15) || (RRRR == 14) || (RRRR == 7) || (RRRR == 13)); } static bool gen_is_active(generator *g) { return((osc_is_running(g->GMODE)) && (g->GQ != 0) && (g->GJ != 0)); } static double gen_amp(generator *g) { int emode; double Q; if (osc_run(g->GMODE) == 0) return(0.0); emode = osc_env(g->GMODE); if ((emode == L_PLUS_2_TO_MINUS_Q) || (emode == L_MINUS_2_TO_MINUS_Q)) Q = pow(2.0, -16.0 * g->f_GQ); else Q = g->f_GQ; if ((emode == L_PLUS_Q) || (emode == L_PLUS_2_TO_MINUS_Q)) return(g->f_GL + Q); return(g->f_GL - Q); } static bool read_data_warned = false; static void process_gen(int gen) { #define FmSum7 g->GFM #define OutSum6 g->GSUM #define FrqSwp20 g->f_GO #define OscFreq28 g->f_GJ #define OscAng20 g->f_GK #define NumCos11 g->GN #define AmpSwp20 g->f_GP #define AmpOff12 g->f_GL #define Gmode10 g->GMODE #define CurAmp24 g->f_GQ #define CosScl4 g->GM #define ShiftOut g->GS generator *g; double fm, FmPhase20, Phase20, SinAdr, CscAdr, TblOut13, OscOut13, CurAmp12, NewAmp12, Env12, temp; g = gens[gen]; if (osc_run(g->GMODE) == 0) /* inactive */ return; if (osc_run(Gmode10) == 3) { /* mmm - just ignore write-data generators since everything is being written out anyway */ return; } if ((FmSum7 >> 6) == 0) fm = gen_ins[FmSum7 & 0x3f]; else fm = mod_ins[FmSum7 & 0x3f]; /* fm *= 0.5; */ FmPhase20 = fm + OscFreq28; if (osc_is_running(Gmode10)) OscFreq28 += (FrqSwp20 / 256.0); /* right adjusted 20 bit */ if (osc_mode(Gmode10) == SIN_FM) /* sin(J+fm) */ Phase20 = FmPhase20; else Phase20 = OscAng20; if (osc_is_running(Gmode10)) OscAng20 += FmPhase20; /* mmm - dac write goes here and does not stop the processing (probably makes no diff) */ if (osc_run(Gmode10) == 2) { dac_write(fm, g->GO & 0xf); /* in this case, we need the integer value of GO */ return; } /* probably should be osc_mode(Gmode10) == SUMCOS */ if ((osc_mode(Gmode10) != SIN_K) && (osc_mode(Gmode10) != SIN_FM)) { SinAdr = (Phase20 * NumCos11); /* was & 0xfff) << 2) + 1 */ CscAdr = Phase20; if (fmod(CscAdr, 1.0) != 0.0) temp = sin(M_PI * SinAdr) / sin(M_PI * CscAdr); /* was (1 << 13)) */ else temp = (double)NumCos11; } else { SinAdr = Phase20; /* was >> 6) | 1 */ temp = sin(M_PI * SinAdr); } TblOut13 = temp / (double)(1 << CosScl4); switch (osc_mode(Gmode10)) { case SUMCOS: case SIN_K: case SIN_FM: OscOut13 = TblOut13; break; case SAWTOOTH: OscOut13 = fmod(Phase20, 2.0) - 1.0; break; case SQUARE: if (fmod(Phase20, 2.0) < 1.0) OscOut13 = -0.5; else OscOut13 = 0.5; break; case PULSE: /* pulse mode was primarily used for triggered noise */ if ((OscAng20 >= 2.0) || (OscAng20 < -2.0)) { OscAng20 = fmod(OscAng20, 2.0); OscOut13 = 0.5; } else OscOut13 = 0.0; break; } CurAmp12 = CurAmp24; if (env_is_running(Gmode10)) { double old_amp; old_amp = CurAmp24; CurAmp24 += (AmpSwp20 / 32.0); /* was 16.0 */ /* mmm - don't know why 32 but it seems to be more accurate than 16 */ /* The envelope side of the generator can be sticky, which means that rather than overflow it will stay at the last value it attained before it would have overflowed; or it can be free, in which case it wraps around. Transitions between run modes can be accomplished in various ways. 1) A command can output a new GMODE. 2) A MISC command can specify "clear all pause bits", which will cause any generator in run mode 0001 to change to mode 1111. 3) A MISC command can specify "clear all wait bits", which will cause any generator in run mode 1001 to change to mode 1111. 4) If the envelope side of a generator in run mode 1101 overflows, that generator goes to run mode 1001. 5) A generator in run mode 1001 will go to run mode 1101 if on the same pass the preceding generator (the one whose generator number is one less) caused a trigger (was in run mode 1110 or 1101 and envelope overflowed). */ if ((CurAmp24 > 1.0) || (CurAmp24 < 0.0)) /* if ((BIT(CurAmp24, 23) != BIT(old_amp, 23)) && (BIT(CurAmp24, 22) == BIT(AmpSwp20, 19))) */ { /* overflow */ if (osc_run(Gmode10) == 15) /* "running A" */ CurAmp24 = old_amp; else { if (osc_run(Gmode10) == 13) /* "running C" */ { set_osc_run(gen, 9); if (osc_run(gens[gen + 1]->GMODE) == 9) set_osc_run(gen + 1, 13); } else { if ((osc_run(Gmode10) == 14) && /* "running B" */ (osc_run(gens[gen + 1]->GMODE) == 9)) set_osc_run(gen + 1, 13); } } } } if ((osc_env(Gmode10) == L_PLUS_2_TO_MINUS_Q) || (osc_env(Gmode10) == L_MINUS_2_TO_MINUS_Q)) NewAmp12 = pow(2.0, -16.0 * CurAmp12); else NewAmp12 = CurAmp12; /* was / 4 */ /* mmm - no scaling called for here */ /* I think this matches the spec: * if temp6 is 0, then 2^(-temp6) is 1, the specs say #b111111111101, * which assuming 12 bit unsigned fractions is 4093/4096, * if temp6 is #b000100000000 (256), 2^(-temp6) is #b011111111110, * which is .5 (fractional) so we really want 2^(-16*temp6) = 2^-1 */ /* in the notes: "The scaling involved is a left shift of temp6 by 4 bits". * This scaling matters in FM since it is a multiplier on the index, and in pluck. */ if ((osc_env(Gmode10) == L_PLUS_Q) || (osc_env(Gmode10) == L_PLUS_2_TO_MINUS_Q)) Env12 = AmpOff12 + NewAmp12; else Env12 = AmpOff12 - NewAmp12; OscOut13 *= Env12; if (adding_to_sum(Gmode10)) { if (osc_run(Gmode10) != 7) { /* "If GS is 0, the high-order 19 bits of the rounded product are taken, right-adjusted with sign extended; if GS is 1, the high-order 20 bits of the rounded product are taken." */ if (g->GS == 0) gen_outs[OutSum6] += OscOut13 / 2.0; /* mmm - right-shifted high order 19 bits so divide by 2 */ else gen_outs[OutSum6] += OscOut13; /* mmm - no shift, so leave value alone */ } else { /* read-data: assume we're reading floats from a raw file */ if (read_data_file) { float read_data_value; fread((void *)(&read_data_value), 4, 1, read_data_file); gen_outs[OutSum6] = OscOut13 + read_data_value; /* was * 2 */ /* "If the run mode specifies adding into sum memory, Temp9 is added into the sum memory location designated by GSUM; except that in run mode 0111, the product is added to the next read-data item from the CPU and the sum replaces the contents of the sum memory location addressed." */ } else { if (!read_data_warned) { fprintf(stderr, "read data?!?\n"); read_data_warned = true; } } } } } /* ---------------------------------------- modifier processing ---------------------------------------- */ /* * Each modifier has the following numeric parameters. * M0 (30 bits) coefficient * M1 (30 bits) other coefficient * L0 (20 bits) running term * L1 (20 bits) other running term * MIN (8 bits) address in sum memory where modifier reads "A" data * MRM (8 bits) address in sum memory where modifier reads "B" data * MIN, MRM = QQAAAAAA * QQ: * 00 generator-last-pass quadrant * 01 modifier-last-pass quadrant * 10 modifier-this-pass quadrant * 11 (reserved) * AAAAAA: sum address within quadrant * MSUM (7 bits) result address in sum memory * MSUM = RAAAAAA * R: 0 add to sum * 1 replace sum * AAAAAA: sum address in modifier-this-pass quadrant */ static void print_mod_read_name(int m) { char *mem_names[4] = {"gen-ins", "mod-ins", "mod-outs", "oops"}; fprintf(stderr, "%s[", mem_names[(m >> 6) & 0x3]); if (((m & 0x3f) == 0) && (((m >> 6) & 0x3) != 0)) fprintf(stderr, "zero"); else fprintf(stderr, "%d", m & 0x3f); fprintf(stderr, "]"); } static double mod_read(int addr) { int QQ, A; A = addr & 0x3f; QQ = LDB(addr, 2, 6); switch (QQ) { case 0: return(gen_ins[A]); case 1: return(mod_ins[A]); case 2: return(mod_outs[A]); case 3: /* "reserved", but it seems to happen in MARS.SAM, and Pete says: * * "Thanks to Al Kossow of the Computer History Museum for putting scans * of the (preliminary) synthesizer schematics and the theory-of- * operation manual up on bitsavers.org. * * It appears that QQ=3 will work the same as QQ=1, i.e. modifier last * pass quadrant." */ return(mod_ins[A]); } return(0); } static void mod_write(int addr, double val) { int R, AAAAAA; if (isnan(val)) { fprintf(stderr, "write %d %d NaN!\n", addr >> 6, addr & 0x3f); } AAAAAA = addr & 0x3f; R = BIT(addr, 6); if (R == 0) mod_outs[AAAAAA] += val; else mod_outs[AAAAAA] = val; } /* * MMODE (9 bits) modifier mode * MMODE = MMMMMAABB * AA: scale of second multiplication * BB: scale of first multiplication * For fraction multiplications: * 00: x 1 * 01: x 2 * 10: x 4 * 11: x 8 * For integer multiplications: * 00: x 1/4 * 01: x 1/2 * 10: x 1 * 11: x 2 * A multiplication involving parameter M1 will be the first * multiplication; one involving M0 will be the second. * * MMMMM: function * 00000: inactive * 00010: uniform noise * 00011: triggered uniform noise * 00100: latch * 00110: threshold * 00111: invoke delay unit * * 01000: two poles * 01001: two poles, M0 variable * 01011: two poles, M1 variable * 01100: two zeros * 01101: two zeros, M0 variable * 01111: two zeros, M1 variable * * 10000: integer mixing * 10001: one pole * 10100: mixing * 10110: one zero * * 11000: four-quadrant multiplication * 11001: amplitude modulation * 11010: maximum * 11011: minimum * 11100: signum * 11101: zero-crossing pulser * * others: (reserved) */ #define mod_mode(M) ((M >> 4) & 0x1f) #define M_INACTIVE 0 #define M_NOISE 2 #define M_TRIGGERED_NOISE 3 #define M_LATCH 4 #define M_THRESHOLD 6 #define M_DELAY 7 #define M_TWO_POLE 8 #define M_TWO_POLE_M0 9 #define M_TWO_POLE_M1 11 #define M_TWO_ZERO 12 #define M_TWO_ZERO_M0 13 #define M_TWO_ZERO_M1 15 #define M_INTEGER_MIXING 16 #define M_ONE_POLE 17 #define M_MIXING 20 #define M_ONE_ZERO 22 #define M_MULTIPLY 24 #define M_AMP_MOD 25 #define M_MAX 26 #define M_MIN 27 #define M_SIGNUM 28 #define M_ZERO_CROSS 29 static double delay_read(int dly); static void delay_write(int dly, double val); static void process_mod(int mod) { modifier *m; int mode, IS; double S, A, B, tmp0, tmp1; m = mods[mod]; mode = mod_mode(m->MMODE); if (mode == M_INACTIVE) { /* technically, mod_write(m->MSUM, 0.0) which might be in "replace" mode if BIT(m->MSUM, 6) is not 0 */ return; } A = mod_read(m->MIN); B = mod_read(m->MRM); switch (mode) { case M_INACTIVE: /* 00000: inactive. S := 0 */ break; case M_NOISE: /* 00010: uniform noise. S := L0 + L1*M0 (integer multiply, low-order * 20 bits of product used; overflow ignored); L1 := S * * see below -- I don't think this is correct. */ /* IS = (m->L0 + (m->L1 * m->M0)) & 0xfffff; */ IS = (m->L0 + ((m->L1 * m->M0) >> 10)) & 0xfffff; mod_write(m->MSUM, TWOS_20_TO_DOUBLE(IS)); m->L1 = IS; break; case M_TRIGGERED_NOISE: /* 00011: triggered uniform noise. S := L0 + L1*M0 (integer multiply, * low-order 20 bits of product used; overflow ignored); * if B*M1 (integer multiply, low-order 20 bits of product * used; overflow ignored) is not 0, L1 := S */ /* IS = (m->L0 + (m->L1 * m->M0)) & 0xfffff; */ /* I'm getting an immediate fixed-point from the SAM files that used triggered noise! */ /* they used the M0 seed of 359035904, (L1: 204282), which immediately cycles. */ /* perhaps the spec is wrong... -- I'll try taking the middle bits */ IS = (m->L0 + ((m->L1 * m->M0) >> 10)) & 0xfffff; mod_write(m->MSUM, TWOS_20_TO_DOUBLE(IS)); if ((B != 0.0) && (m->M1 != 0)) m->L1 = IS; break; case M_LATCH: /* 00100: latch (sample and hold). S := L1; If B*M1 is not 0, L1 := A * but in the errata: * "BIL has discovered empirically that the modifier latch mode operation should actually read * 00100: latch (sample and hold). S := L1; If B*M1 is not 0, L1 := A*M0" */ mod_write(m->MSUM, m->f_L1); if ((B * m->f_M1) != 0.0) m->f_L1 = A * m->f_M0; break; case M_THRESHOLD: /* 00110: threshold. If A*M0 + L0 is less than 0, then S := 0; * if A*M0 + L0 is equal to or greater than 0, then S := B*M1 */ tmp0 = A * m->f_M0 + m->f_L0; if (tmp0 < 0.0) mod_write(m->MSUM, 0.0); else mod_write(m->MSUM, B * m->f_M1); break; case M_DELAY: /* 00111: invoke delay unit. * Unit # := MRM (low-order 5 bits); * S := L0 + L1*M0; L0 := DM; Temp0 := A + DM*M1; * L1 := Temp0; DM := Temp0 */ /* to handle table lookups, we need the integer side here */ /* fprintf(stderr, "d%d, m%d: %.4f = %.4f + %.4f * %.4f\n", m->MRM & 0x1f, mod, m->f_L0 + m->f_L1 * m->f_M0, m->f_L0, m->f_L1, m->f_M0); */ mod_write(m->MSUM, m->f_L0 + m->f_L1 * m->f_M0); m->f_L0 = delay_read(m->MRM & 0x1f); m->f_L1 = A + m->f_L0 * m->f_M1; delay_write(m->MRM & 0x1f, m->f_L1); break; case M_TWO_POLE: case M_TWO_POLE_M0: case M_TWO_POLE_M1: /* 01000: two poles. S := L1*M1 + L0*M0 + A; L0 := L1; L1 := S * * 01001: two poles, M0 variable. S := L1*M1 + L0*M0 + A; L0 := L1; L1 := S; M0 := M0 + B * * 01011: two poles, M1 variable. S := L1*M1 + L0*M0 + A; L0 := L1; L1 := S; M1 := M1 + B */ tmp0 = m->f_L1 * m->f_M1; tmp1 = m->f_L0 * m->f_M0; S = tmp0 + tmp1 + A; /* divide A by 1024.0 here probably */ mod_write(m->MSUM, S); m->f_L0 = m->f_L1; m->f_L1 = S; if (mode == M_TWO_POLE_M0) m->f_M0 += (B / 1024.0); /* "when a quantity is added to M0 or M1 it is added right-justified, with sign extended" * does that include "A" above? I think it does... (see one and two_zero below). */ if (mode == M_TWO_POLE_M1) m->f_M1 += (B / 1024.0); break; case M_TWO_ZERO: case M_TWO_ZERO_M0: case M_TWO_ZERO_M1: /* 01100: two zeros. S := L1*M1 + L0*M0 + A; L0 := L1; L1 := A * * 01101: two zeros, M0 variable. S := L1*M1 + L0*M0 + A; L0 := L1; L1 := A; M0 := M0 + B * * 01101: two zeros, M0 variable. S := L1*M1 + L0*M0 + A; L0 := L1; L1 := A; M1 := M1 + B */ tmp0 = m->f_L1 * m->f_M1; tmp1 = m->f_L0 * m->f_M0; mod_write(m->MSUM, tmp0 + tmp1 + A); /* divide A by 1024.0 here probably */ m->f_L0 = m->f_L1; m->f_L1 = A / 1024.0; if (mode == M_TWO_ZERO_M0) m->f_M0 += (B / 1024.0); if (mode == M_TWO_ZERO_M1) m->f_M1 += (B / 1024.0); break; case M_INTEGER_MIXING: /* 10000: integer mixing. S := A*M0 + B*M1 (integer multiply, low-order * 20 bits of product used; overflow ignored) */ /* I don't remember how we used this -- I'll assume the M's are the ints */ mod_write(m->MSUM, A * m->M0 + B * m->M1); break; case M_MIXING: /* 10100: mixing. S := A*M0 + B*M1 */ mod_write(m->MSUM, A * m->f_M0 + B * m->f_M1); break; case M_ONE_POLE: /* 10001: one pole. S := L1*M1 + B*M0; L1 := S * * but in the errata: * "DAJ - It seems that the modifier mode one pole is really * 10001: one pole. S := L1*M1 + B*L0; L1 := S" * * but I think that is incorrect; old reverbs are definitely using the spec form of the 1-pole filter */ tmp0 = m->f_L1 * m->f_M1; /* tmp1 = B * m->f_L0; */ tmp1 = B * m->f_M0; m->f_L1 = tmp0 + tmp1; mod_write(m->MSUM, m->f_L1); break; case M_ONE_ZERO: /* 10110: one zero. S := L1*M1 + L0*M0; L0 := L1; L1 := A */ tmp0 = m->f_L1 * m->f_M1; tmp1 = m->f_L0 * m->f_M0; m->f_L0 = m->f_L1; m->f_L1 = A / 1024.0; mod_write(m->MSUM, tmp0 + tmp1); break; case M_MULTIPLY: /* 11000: four-quadrant multiplication. S := L1*M1; L1 := A*B */ mod_write(m->MSUM, m->f_L1 * m->f_M1); m->f_L1 = A * B; break; case M_AMP_MOD: /* 11001: amplitude modulation. S := L1*M1; L1 := A * ((B+1)/2) * (The term ((B+1)/2) interprets B as a signed two's-complement * fraction ranging in value from -1 to +1-epsilon.) */ mod_write(m->MSUM, m->f_L1 * m->f_M1); m->f_L1 = A * (B + 1.0) * 0.5; break; case M_MAX: /* 11010: maximum. S := max (A*M0, B*M1) */ tmp0 = A * m->f_M0; tmp1 = B * m->f_M1; mod_write(m->MSUM, (tmp0 > tmp1) ? tmp0 : tmp1); break; case M_MIN: /* 11011: minimum. S := min (A*M0, B*M1) */ tmp0 = A * m->f_M0; tmp1 = B * m->f_M1; mod_write(m->MSUM, (tmp0 < tmp1) ? tmp0 : tmp1); break; case M_SIGNUM: /* 11100: signum. If A*M0 is less than B*M1, then S := -1 (integer) * if A*M0 equals B*M1, then S := 0; * if A*M0 is greater than B*M1, the S := 1 (integer) */ tmp0 = A * m->f_M0; tmp1 = B * m->f_M1; if (tmp0 < tmp1) mod_write(m->MSUM, TWOS_20_TO_DOUBLE(-1)); else if (tmp0 == tmp1) mod_write(m->MSUM, 0.0); else mod_write(m->MSUM, TWOS_20_TO_DOUBLE(1)); break; case M_ZERO_CROSS: /* 11101: zero-crossing pulser. Temp0 := B*M0; Temp1 := L1*M1; * if Temp1 is not 0 and either Temp0 is 0 or Temp0*Temp1 is * negative then S := -epsilon, else S := 0; L1 := Temp0 * (The term -epsilon is a binary number with all bits set.) */ tmp0 = B * m->f_M0; tmp1 = m->f_L1 * m->f_M0; if ((tmp1 != 0) && ((tmp0 == 0) || (tmp0 * tmp1 < 0))) mod_write(m->MSUM, TWOS_20_TO_DOUBLE(-1)); m->f_L1 = tmp0; break; default: fprintf(stderr, "reserved modifier mode?\n"); break; } } /* ---------------------------------------- delay processing ---------------------------------------- */ /* Each delay unit has the following numeric parameters. * * P mode (4 bits). The mode is interpreted as follows: * mode: 0000 inactive * 1000 delay line * 1010 table look-up * 1011 table look-up, argument rounded * 1100 delay tap * others: (reserved) */ #define D_INACTIVE 0 #define D_LINE 8 #define D_TABLE_LOOKUP 10 #define D_TABLE_LOOKUP_ROUNDED 11 #define D_TAP 12 /* * Z unit length (16 bits) or binary scale factor (4 bits). * In delay line and delay tap modes, Z gives 1 less than the * total number of locations in delay memory used by the delay * unit, i.e. the index of the last delay memory address for * this unit. In table look-up modes, the low-order four bits * of Z specify the number of binary places that the argument * is shifted to the right before it is used to address the * memory; if rounding is specified, the address after shifting * is incremented by 1 if the most-significant bit shifted out * was a 1. * * Y index (16 bits). In delay line and delay tap modes, this is the * running index on the memory area for the unit. * * X base address (16 bits). The base address is the lowest-numbered * delay memory location used by this unit. * * In inactive mode, delay memory is not modified and the unit * returns indeterminate results. Delay units not accommodated due * to the number of ticks in a pass act as if in the inactive mode. * If the number of processing ticks is 4*n + m where m is 1, 2, or 3, * delay unit number n should be put in the inactive mode. * * In delay line mode, a 20-bit data word is received from * the modifier that calls for the delay unit, and another 20-bit * word is sent to it. The word received is put into the next slot * in the delay line. It will be retrieved and sent back to the * modifier Z+3 passes later. In delay tap mode, a word is sent to * the modifier but delay memory is not written into. * * In table look-up mode, the 20-bit data word received * from the modifier is shifted to the right Z bits, bringing in zeros, * and the right 16 bits of the result are used to address the memory * area assigned to the unit. The 20-bit word in the addressed memory * location is returned to the modifier three passes later. */ static bool table_read_warned = false, table_write_warned = false; static double delay_read(int dly) { delay *d; d = dlys[dly]; switch (d->P) { case D_INACTIVE: return(0.0); case D_LINE: case D_TAP: /* return the value with a hidden 2 sample delay (Z+3 == total delay length + 2) */ #if 0 return(delay_memory[d->X + d->Y]); #else { /* I originally thought this was making a raspy or crackling sound in the reverbs, but now I don't hear it (bil) */ double val; val = d->xd2; d->xd2 = d->xd1; d->xd1 = delay_memory[d->X + d->Y]; return val; } #endif case D_TABLE_LOOKUP: case D_TABLE_LOOKUP_ROUNDED: { int Z_shift, dY; if (!table_read_warned) { fprintf(stderr, "table lookup read is unlikely to work.\n"); table_read_warned = true; } Z_shift = d->Z & 0xf; dY = (d->I >> Z_shift) & 0xffff; return(delay_memory[d->X + dY]); } } return(0); } static void delay_write(int dly, double val) { delay *d; d = dlys[dly]; switch (d->P) { case D_INACTIVE: case D_TAP: break; case D_LINE: delay_memory[d->X + d->Y] = val; break; case D_TABLE_LOOKUP: case D_TABLE_LOOKUP_ROUNDED: if (!table_write_warned) { fprintf(stderr, "table lookup write is unlikely to work.\n"); table_write_warned = true; } d->I = DOUBLE_TO_TWOS_20(val); /* can this work? */ break; } } static void process_dly(int dly) { delay *d; d = dlys[dly]; d->Y += 1; if (d->Y > d->Z) /* unit size - 1 so not >= ? */ d->Y = 0; } /* ---------------------------------------- run! ---------------------------------------- */ static void dump_patch(void); static void linger(int time) { /* process each sample ("pass") until pass == time */ /* but linger was a 20-bit number, so it wrapped around I believe, so pass should be mod 2^20? */ if (!snd_file) { fprintf(stderr, "no ticks setting found!\n"); exit(0); } if (time < pass) pass = pass - (1 << 20); /* old SAM files had endless strings of lingers at the end generating enormous empty sound files, but * * mmm - this was causing the long trailing reverb of some of my files to be cut off. */ if ((FLUSH_TRAILING_LINGERS) && ((total_commands - current_command) < 100) && (total_commands > 1000) && ((time - pass) > (6 * srate))) { fprintf(stderr, "ignore trailing %d sample (%.3f second) linger (%d)\n", time - pass, (double)(time - pass) / (double)srate, total_commands - current_command); pass = time; return; } while (pass < time) { /* run through all available ticks, processing gen+mod+dly, * then write accumulated dac_outs, clear, update memories (this-pass -> last-pass), * and increment pass */ int i, tick, gen = 0, mod = 0, dly = 0; for (tick = 0; tick < processing_ticks; tick++) { /* given the timing info I'll simplify a bit and run 1 gen per tick, 1 mod every 2 ticks, and 1 delay every 4 ticks */ if (gen < GENERATORS) process_gen(gen++); /* I'm guessing... */ if (((tick & 1) == 0) && (mod < MODIFIERS)) process_mod(mod++); if (((tick & 3) == 0) && (dly < DELAYS)) process_dly(dly++); } if (dump_patch_at == samples) dump_patch(); for (i = 0; i < SUM_MEMORY_SIZE; i++) { if (fabs(gen_ins[i]) > peak_gen_ins[i]) peak_gen_ins[i] = fabs(gen_ins[i]); prev_gen_ins[i] = gen_ins[i]; gen_ins[i] = gen_outs[i]; gen_outs[i] = 0.0; if (fabs(mod_ins[i]) > peak_mod_ins[i]) peak_mod_ins[i] = fabs(mod_ins[i]); prev_mod_ins[i] = mod_ins[i]; mod_ins[i] = mod_outs[i]; mod_outs[i] = 0.0; } fwrite(dac_out, 4, 4, snd_file); samples++; for (i = 0; i < 4; i++) { if (fabs(dac_out[i]) > dac_out_peak[i]) dac_out_peak[i] = fabs(dac_out[i]); dac_out[i] = 0.0; } pass++; if (samples == TOTAL_SAMPLES) all_done(); } } /* ---------------------------------------- commands ---------------------------------------- */ /* * ----------------------------------------------------------------- * : (20) data : 0 0 0 0 0: RR : x x: W: P: S: * ----------------------------------------------------------------- * MISC * RR: 00 no effect * 01 load DX from data * 10 load TTL buffer A from left 16 bits of data * 11 load TTL buffer B from left 16 bits of data * set analog output filters from right 4 bits of data: * 01xx Mode 0 * 00nn Mode 1, frequency f0, f1, f2, or f3 according * to nn * W: if 1, clear all wait bits * P: if 1, clear all pause bits * S: if 1, stop clock */ static void misc_command(int cmd) { int data, RR, W, P, S; char *RR_name[4] = {"noop", "load DX", "TTL-A", "TTL-B"}; data = LDB(cmd, 20, 12); RR = LDB(cmd, 2, 5); W = BIT(cmd, 2); P = BIT(cmd, 1); S = BIT(cmd, 0); if (describe_commands) fprintf(stderr, "sam: %d, %s%s%s%s\n", data, RR_name[RR], (W == 1) ? "" : ", clear waits", (P == 1) ? "" : ", clear pauses", (S == 1) ? "" : ", stop clock"); if (RR == 1) DX = data; if (W == 1) { /* cause any generator in run mode 1001 to change to mode 1111 */ int i; for (i = 0; i < GENERATORS; i++) if ((gens[i]) && (osc_run(gens[i]->GMODE) == 9)) set_osc_run(i, 15); } if (P == 1) { /* cause any generator in run mode 0001 to change to mode 1111 */ int i; for (i = 0; i < GENERATORS; i++) if ((gens[i]) && (osc_run(gens[i]->GMODE) == 1)) set_osc_run(i, 15); } if (REPORT_BAD_COMMANDS) { if ((S == 1) && ((total_commands - current_command) > 1000)) fprintf(stderr, "sam: %x: stop clock?\n", cmd); } } /* * ----------------------------------------------------------------- * : (16) data :(4)data: 0 0 0 0 1: U U: (5) unit # : * ----------------------------------------------------------------- * DLY X, Y, Z * UU: 00 X 16 bits base address; clear Y * 01 Y 16 bits one's complement of index * 10 Z,P 16 bits delay unit size minus 1, or scale (low * 4 bits of 16); 4 bits mode * 11 (unused) */ static const char *P_name(int P) { switch (P) { case D_INACTIVE: return("inactive"); case D_LINE: return("line"); case D_TAP: return("tap"); case D_TABLE_LOOKUP: return("table"); case D_TABLE_LOOKUP_ROUNDED: return("rtable"); default: return("unknown"); } } static void dly_command(int cmd) { int unit, UU, data_4, data_16; delay *d; char *UU_name[4] = {"set base, clear index", "set index", "set size", "un-used!"}; unit = (cmd & 0x1f); UU = LDB(cmd, 2, 5); if (UU == 3) { fprintf(stderr, "unknown delay command!\n"); return; } data_4 = LDB(cmd, 4, 12); data_16 = LDB(cmd, 16, 16); d = dlys[unit]; switch (UU) { case 0: d->X = data_16; d->Y = 0; break; case 1: d->Y = data_16; break; case 2: d->Z = data_16; d->P = data_4; break; } if (describe_commands) { fprintf(stderr, "d%d %s", unit, UU_name[UU]); if (UU == 0) fprintf(stderr, ": X: %d", d->X); else { if (UU == 1) fprintf(stderr, ": Y: %d", d->Y); else fprintf(stderr, ": Z: %d, P: %s", d->Z, P_name(d->P)); } fprintf(stderr, "\n"); } } /* * ----------------------------------------------------------------- * : (20) data : 0 0 0 1 0: x x: T T: x x x: * ----------------------------------------------------------------- * TIMER * TT: 00 no effect * 10 Linger: process no further commands until pass counter * equals data * 11 clear pass counter, then Linger as for 10 * 01 set pass counter from data */ static void timer_command(int cmd) { int data, TT; char *TT_name[4] = {"noop", "set pass", "linger", "clear pass and linger"}; TT = LDB(cmd, 2, 3); data = LDB(cmd, 20, 12); if (describe_commands) fprintf(stderr, "sam %s: %d at sample %d %.4f\n", TT_name[TT], data, samples, (double)samples / (double)srate); switch (TT) { case 0: break; case 1: pass = data; break; case 2: linger(data); break; case 3: pass = 0; linger(data); break; } } /* * ----------------------------------------------------------------- * : xxx xxx xxx x : (10) data : 0 0 0 1 1: x x: 0: Q: x x x: * ----------------------------------------------------------------- * TICKS * Q: 0 designate highest-numbered processing tick per pass * (should not exceed 255 [See appendix - DAJ]) * 1 designate next-to-highest-numbered tick (processing * plus overhead plus update) per pass */ static bool bit_31_warned = false; static void ticks_command(int cmd) { int Q, data, bit_31; char *Q_name[2] = {"set highest processing tick", "set highest tick"}; bit_31 = BIT(cmd, 4); Q = BIT(cmd, 3); data = LDB(cmd, 10, 12); if (REPORT_BAD_COMMANDS) { if (bit_31 != 0) { if (!bit_31_warned) { fprintf(stderr, "ticks bit 31 is on?\n"); bit_31_warned = true; } return; /* what is going on here? */ } } if (data != 0) /* used at end of some box sequences, but that confuses srate */ { if (Q == 0) processing_ticks = data + 1; /* mmm - data is highest numbered processing tick per pass, so processing_ticks is 1 greater. */ else { if (srate <= 1) { /* mmm - srate can now be set from the command line in certain cases. I had some weird tick settings for some reason. * mmm - highest_tick_per_pass is actually being set here to the max *number* of ticks per pass, including overhead */ highest_tick_per_pass = data + 2; /* why isn't this 9? */ /* "It's not clear from the documentation, so to clarify: On the # TICKS * command, the number to be supplied for Q=1 is the total number of ticks * per pass minus 2. (TVR - 7 August 1984)" */ /* it's a 10 bit field, and higher bits are ignored, so the slowest we * can run is 5010Hz or thereabouts */ if (highest_tick_per_pass > GENERATORS) highest_tick_per_pass = GENERATORS; /* mmm - could it not be higher in some cases? */ srate = (int)(1000000000.0 / (double)(highest_tick_per_pass * 195)); } else { highest_tick_per_pass = (1000000000.0 / (double)srate / 195.0); } } } if (describe_commands) { fprintf(stderr, "sam %s: %d", Q_name[Q], data); if (Q == 1) fprintf(stderr, " (%d Hz)", srate); fprintf(stderr, "\n"); } if ((data != 0) && (srate != 0)) { if ((snd_file) && (samples == 0) && (Q == 1)) /* 2 tick commands at the start? */ { fclose(snd_file); /* start over... */ snd_file = NULL; } if (snd_file == NULL) { /* now that we know the sampling rate, open the output file */ int header_info[24] = {1179011410, 88, 1163280727, 1263424842, 28, 0, 0, 0, 0, 0, 0, 0, 544501094, 16, 262147, 44100, 705600, 2097168, 1635017060, 16, 0, 0, 0, 0}; header_info[15] = srate; /* mmm - generate output filename based on input filename */ { char *dot; int i, len; len = strlen(filename); output_filename = malloc(len + 1); strcpy(output_filename, filename); /* dot = strchr(output_filename, '.'); * can be confused by ../test/TEST.SAM */ for (i = len - 1; i > 0; i--) if (filename[i] == '.') { dot = (char *)(output_filename + i); break; } strcpy(dot + 1, "wav"); snd_file = fopen(output_filename, "w"); } if (!snd_file) { fprintf(stderr, "can't open test.snd!\n"); exit(0); } fwrite((void *)header_info, 4, 24, snd_file); } } } static int last_GMODE_command = 0; /* GQ (24 bits) phi -- decay exponent * ----------------------------------------------------------------- * GQ : (20) data : 0 0 1: E: (8) gen # : * ----------------------------------------------------------------- * * E: 0 Q right-adjusted, sign extended * 1 Q left-adjusted, low bits from left of DX; clear DX */ static void gq_command(int cmd) { /* GQ is 24 bits */ int data, E, gen, old_DX = 0, old_GQ; double old_f_GQ; generator *g; char *E_name[2] = {"right adjusted", "left adjusted + DX"}; gen = LDB(cmd, 8, 0); E = BIT(cmd, 8); data = LDB(cmd, 20, 12); g = gens[gen]; old_GQ = g->GQ; old_f_GQ = g->f_GQ; /* spec says "sign extended" which makes me think this number is signed, but I think it is unsigned in exp modes */ /* mmm - I also believe it is unsigned. */ /* pete: * Hmm, it looks like it makes more sense to call it unsigned. Certainly * the multiplication of envelope times waveform treats the envelope as * unsigned (i.e. non-negative). */ if (E == 0) g->GQ = data; /* mmm */ else { g->GQ = (data << 4) | ((DX >> 16) & 0xf); /* mmm */ old_DX = DX; DX = 0; } g->f_GQ = (double)(g->GQ) / (double)(1 << 24); /* mmm - proper scaling of unsigned value */ if (describe_commands) { if (E == 0) fprintf(stderr, "g%d amp: %s, %d %.4f\n", gen, E_name[E], g->GQ, g->f_GQ); else fprintf(stderr, "g%d amp: %s, %d = %d %.4f (DX: %d)\n", gen, E_name[E], data, g->GQ, g->f_GQ, old_DX); } #if 0 if ((gen_is_active(g)) && (samples > last_GMODE_command)) { if (REPORT_BAD_COMMANDS) fprintf(stderr, "sample %d (%.3f), command %d, stray amp: g%d %.4f from %.4f (last mode sample: %d)\n", samples, (double)samples / (double)srate, current_command, gen, g->f_GQ, old_f_GQ, last_GMODE_command); if (FLUSH_BAD_COMMANDS) { g->GQ = old_GQ; g->f_GQ = old_f_GQ; } } #endif } /* GJ (28 bits) omega -- oscillator frequency * ----------------------------------------------------------------- * GJ : (20) data : 0 1 0: E: (8) gen # : * ----------------------------------------------------------------- * * E: 0 J right-adjusted, sign extended * 1 J left-adjusted, low bits from left of DX; clear DX */ static void gj_command(int cmd) { /* GJ is 28 bits */ int data, E, gen, old_DX = 0, old_GJ; double old_f_GJ; generator *g; char *E_name[2] = {"right adjusted", "left adjusted + DX"}; gen = LDB(cmd, 8, 0); E = BIT(cmd, 8); data = LDB(cmd, 20, 12); g = gens[gen]; old_GJ = g->GJ; old_f_GJ = g->GJ; if (E == 0) g->GJ = TWOS_20(data); else { g->GJ = TWOS_28(((data << 8) + (DX >> 12))); /* need 28 - 20 = 8 bits? */ old_DX = DX; DX = 0; } g->f_GJ = DOUBLE_28(g->GJ); if (describe_commands) { if (E == 0) fprintf(stderr, "g%d freq: %s, %d %.4f (%.4f Hz)\n", gen, E_name[E], g->GJ, g->f_GJ, g->f_GJ * 0.5 * srate); else fprintf(stderr, "g%d freq: %s (DX: %d), %d = %d %.4f (%.4f Hz)\n", gen, E_name[E], old_DX, data, g->GJ, g->f_GJ, g->f_GJ * 0.5 * srate); } if ((gen_is_active(g)) && (g->GJ != old_GJ) && (samples > last_GMODE_command)) { if (REPORT_BAD_COMMANDS) fprintf(stderr, "sample %d (%.3f), command %d, stray freq: g%d %.4f from %.4f (last mode sample: %d), data: %d\n", samples, (double)samples / (double)srate, current_command, gen, g->f_GJ * 0.5 * srate, DOUBLE_28(old_GJ) * 0.5 *srate, last_GMODE_command, data); if (FLUSH_BAD_COMMANDS) { g->GJ = old_GJ; g->f_GJ = old_f_GJ; } } } /* GP (20 bits) delta -- decay rate * ----------------------------------------------------------------- * GP : (20) data : 0 1 1 0: (8) gen # : * ----------------------------------------------------------------- */ static void gp_command(int cmd) { /* GP is 20 bits */ int data, gen; generator *g; gen = LDB(cmd, 8, 0); data = LDB(cmd, 20, 12); g = gens[gen]; g->GP = TWOS_20(data); g->f_GP = DOUBLE_20(g->GP); if (describe_commands) fprintf(stderr, "g%d amp change: %d (%.4f/sec), amp: %.4f\n", gen, g->GP, g->f_GP * srate, g->f_GQ); } /* GN (11 bits) number of cosines to be summed * GM (4 bits) binary scale of cosine or sum of cosines * GS (1 bit) whether to shift output when adding to sum memory * GN, ----------------------------------------------------------------- * GM, :N:M:S S:x: (11) GN :(4) GM : 0 1 1 1: (8) gen # : * GS ----------------------------------------------------------------- * * N: if 1, disable loading GN * M: if 1, disable loading GM * SS: 00 clear GS to 0 * 01 set GS to 1 * 10 no effect * 11 (reserved) */ static void gn_command(int cmd) { int N, M, SS, GN, GM, gen; generator *g; char *SS_name[4] = {", clear GS", ", set GS to 1", "", ", GS reserved?"}; gen = LDB(cmd, 8, 0); GM = LDB(cmd, 4, 12); GN = LDB(cmd, 11, 16); SS = LDB(cmd, 2, 28); M = BIT(cmd, 30); N = BIT(cmd, 31); if (describe_commands) { if (N == 1) { if (M == 1) fprintf(stderr, "g%d sum-memory shift:%s\n", gen, SS_name[SS]); else fprintf(stderr, "g%d ncos scale: %d%s\n", gen, GM, SS_name[SS]); } else { if (M == 1) fprintf(stderr, "g%d ncos: %d%s\n", gen, GN, SS_name[SS]); else fprintf(stderr, "g%d ncos: %d%s, scale: %d\n", gen, GN, SS_name[SS], GM); } } g = gens[gen]; if (N == 0) g->GN = GN; if (M == 0) g->GM = GM; switch(SS) { case 0: g->GS = 0; break; case 1: g->GS = 1; break; } } /* GL (12 bits) asymptote * GSUM (6 bits) sum memory address into which output is added * ----------------------------------------------------------------- * GL, :L:S: (12) GL : (6) GSUM : 1 0 0 0: (8) gen # : * GSUM ----------------------------------------------------------------- * * L: if 1, disable loading GL * S: if 1, disable loading GSUM */ static void gl_command(int cmd) { int GL, GSUM, L, S, gen, old_GSUM; generator *g; gen = LDB(cmd, 8, 0); GSUM = LDB(cmd, 6, 12); GL = LDB(cmd, 12, 18); L = BIT(cmd, 31); S = BIT(cmd, 30); g = gens[gen]; old_GSUM = g->GSUM; if (L == 0) { /* is this signed? -- posies treats it as unsigned, I believe */ #if 1 g->GL = GL; g->f_GL = UNSIGNED_12_TO_DOUBLE(GL); #else g->GL = TWOS_12(GL); g->f_GL = DOUBLE_12(g->GL); #endif } if (S == 0) g->GSUM = GSUM; if (describe_commands) { if (L == 1) { if (S == 1) fprintf(stderr, "g%d: noop\n", gen); else fprintf(stderr, "g%d outloc: gen-outs[%d]\n", gen, g->GSUM); } else { if (S == 0) fprintf(stderr, "g%d amp offset: %d = %.4f\n", gen, g->GL, g->f_GL); else fprintf(stderr, "g%d outloc: gen-outs[%d] + amp offset: %d = %.4f\n", gen, g->GSUM, g->GL, g->f_GL); } } if (REPORT_BAD_COMMANDS) { if ((GL == 1) && (L == 1) && (S == 0)) fprintf(stderr, "sample %d (%.3f), command %d, possible gen output loc overflow: g%d %d\n", samples, (double)samples / (double)srate, current_command, gen, GSUM); if ((gen_is_active(g)) && (g->GSUM != old_GSUM) && (samples > last_GMODE_command) && (S == 0)) fprintf(stderr, "sample %d (%.3f), command %d, stray output loc: g%d %d from %d (last mode sample: %d)\n", samples, (double)samples / (double)srate, current_command, gen, g->GSUM, old_GSUM, last_GMODE_command); } } /* (20 bits) theta -- oscillator angle * ----------------------------------------------------------------- * GK : (20) data : 1 0 0 1: (8) gen # : * ----------------------------------------------------------------- */ static void gk_command(int cmd) { /* GK is 20 bits */ int data, gen, old_GK; double old_f_GK; generator *g; gen = LDB(cmd, 8, 0); data = LDB(cmd, 20, 12); g = gens[gen]; old_GK = g->GK; old_f_GK = g->f_GK; g->GK = TWOS_20(data); g->f_GK = DOUBLE_20(g->GK); if (describe_commands) fprintf(stderr, "g%d phase: %d %.4f\n", gen, g->GK, g->f_GK); if ((gen_is_active(g)) && (samples > last_GMODE_command)) { if (REPORT_BAD_COMMANDS) fprintf(stderr, "sample %d (%.3f), command %d, stray phase: g%d %.4f (last mode sample: %d)\n", samples, (double)samples / (double)srate, current_command, gen, g->f_GK, last_GMODE_command); if (FLUSH_BAD_COMMANDS) { g->GK = old_GK; g->f_GK = old_f_GK; } } } /* GFM (7 bits) sum memory address from which frequency modulation * GMODE (10 bits) generator mode * ----------------------------------------------------------------- * :M:F:C: (10) GMODE :(7) GFM: 1 0 1 0: (8) gen # : * ----------------------------------------------------------------- * GMODE, * GFM M: if 1, disable loading GMODE * F: if 1, disable loading GFM * C: if 1, clear GK */ static bool bad_mode(int mode) { int R, E, S; R = osc_run(mode); E = osc_env(mode); S = osc_mode(mode); if ((R != 2) && (R != 7) && (R != 3) && (R != 0)) switch (S) { case SUMCOS: case SAWTOOTH: case SQUARE: case PULSE: case SIN_K: case SIN_FM: break; default: return(true); } switch (R) { case 0: case 1: case 15: case 14: case 9: case 13: case 7: case 3: case 2: break; default: return(true); } return(false); } static void print_gmode_name(int mode) { /* RRRREESSSS */ int R, E, S; char *E_name[4] = {"L-Q", "L+Q", "L-2^Q", "L+2^Q"}; R = osc_run(mode); E = osc_env(mode); S = osc_mode(mode); if (R == 0) { fprintf(stderr, "inactive"); return; } if ((R != 2) && (R != 7) && (R != 3)) { switch (S) { case SUMCOS: fprintf(stderr, "ncos"); break; case SAWTOOTH: fprintf(stderr, "saw"); break; case SQUARE: fprintf(stderr, "square"); break; case PULSE: fprintf(stderr, "pulse"); break; case SIN_K: fprintf(stderr, "sin"); break; case SIN_FM: fprintf(stderr, "sin+fm"); break; default: fprintf(stderr, "unknown"); break; } fprintf(stderr, "-%s-", E_name[E]); } switch (R) { case 1: fprintf(stderr, "pause"); break; case 15: fprintf(stderr, "A"); break; case 14: fprintf(stderr, "B"); break; case 9: fprintf(stderr, "wait"); break; case 13: fprintf(stderr, "C"); break; case 7: fprintf(stderr, "rd"); break; case 3: fprintf(stderr, "wrt"); break; case 2: fprintf(stderr, "DAC"); break; default: fprintf(stderr, "unknown"); break; } } static void gmode_command(int cmd) { int gen, M, F, C, GMODE, GFM, old_GMODE, old_GFM; bool gen_was_active; generator *g; last_GMODE_command = samples; gen = LDB(cmd, 8, 0); GFM = LDB(cmd, 7, 12); GMODE = LDB(cmd, 10, 19); M = BIT(cmd, 31); F = BIT(cmd, 30); C = BIT(cmd, 29); g = gens[gen]; old_GFM = g->GFM; old_GMODE = g->GMODE; gen_was_active = gen_is_active(g); if (M == 0) g->GMODE = GMODE; if (F == 0) g->GFM = GFM; if (C == 1) g->GK = 0; /* if (osc_env(GMODE) > 1) fprintf(stderr, "expt %d ", samples); */ if (describe_commands) { fprintf(stderr, "g%d ", gen); if (M == 0) { fprintf(stderr, "mode: "); print_gmode_name(g->GMODE); } if (F == 0) { if (M == 0) fprintf(stderr, ", "); fprintf(stderr, "inloc: %s[%d]", ((g->GFM >> 6) == 0) ? "gen-ins" : "mod-ins", g->GFM & 0x3f); } if (C == 1) { if ((M == 0) || (F == 0)) fprintf(stderr, ", "); fprintf(stderr, "clear phase"); } fprintf(stderr, "\n"); } if (REPORT_BAD_COMMANDS) { if (bad_mode(GMODE)) fprintf(stderr, "sample %d (%.3f), command %d, bad mode: g%d %x\n", samples, (double)samples / (double)srate, current_command, gen, GMODE); if ((gen_is_active(g)) && (gen >= processing_ticks)) fprintf(stderr, "sample %d (%.3f), command %d, g%d cannot actually run (procticks: %d)\n", samples, (double)samples / (double)srate, current_command, gen, processing_ticks); #if 0 if ((gen_was_active) && (!gen_is_active(g)) && (g->f_GQ != 0.0)) fprintf(stderr, "sample %d (%.3f), command %d, g%d turned off with amp %.4f\n", samples, (double)samples / (double)srate, current_command, gen, g->f_GQ); #endif if ((gen_was_active) && ((g->GFM != old_GFM) || (g->GMODE != old_GMODE)) && (samples > last_GMODE_command)) { if (g->GFM != old_GFM) fprintf(stderr, "sample %d (%.3f), command %d, stray input loc: g%d %d from %d (last mode sample: %d)\n", samples, (double)samples / (double)srate, current_command, gen, g->GFM, old_GFM, last_GMODE_command); else { fprintf(stderr, "sample %d (%.3f), command %d, stray mode: g%d ", samples, (double)samples / (double)srate, current_command, gen); print_gmode_name(g->GMODE); fprintf(stderr, " from "); print_gmode_name(old_GMODE); fprintf(stderr, " (last mode sample: %d)\n", last_GMODE_command); } } } } /* GO (20 bits) alpha -- oscillator frequency sweep rate * ----------------------------------------------------------------- * GO : (20) data : 1 0 1 1: (8) gen # : * ----------------------------------------------------------------- */ static void go_command(int cmd) { /* GO is 20 bits */ int data, gen; generator *g; gen = LDB(cmd, 8, 0); data = LDB(cmd, 20, 12); g = gens[gen]; g->GO = TWOS_20(data); g->f_GO = DOUBLE_20(g->GO); if (describe_commands) { if (osc_run(g->GMODE) == 2) fprintf(stderr, "g%d DAC out: %d\n", gen, data); else fprintf(stderr, "g%d freq change: %d %.4f (%.4f Hz/sec), freq: %.4f\n", gen, g->GO, g->f_GO, g->f_GO * 0.5 * srate * srate / 256.0, g->f_GJ * srate * 0.5); } } /* M0 (30 bits) coefficient * M1 (30 bits) other coefficient * ----------------------------------------------------------------- * MM : (20) data : 1 1 0: V V: (7) mod # : * ----------------------------------------------------------------- * * VV: 00 M0 right-adjusted, sign extended * 01 M1 right-adjusted, sign extended * 10 M0 left-adjusted, low bits from left of DX; clear DX * 11 M1 left-adjusted, low bits from left of DX; clear DX */ /* To avoid endless repetition in the modifier processing, I'll incorporate the scalers * into M0 and M1 when they are set, or when the scalers are changed, but this means * (for simplicity) keeping track of the original M0 and M1 values: ("o_M0" and friends) */ static void mm_command(int cmd) { /* M0 and M1 are 30 bits */ int mod, VV, data, old_DX = 0; modifier *m; mod = LDB(cmd, 7, 0); VV = LDB(cmd, 2, 7); data = LDB(cmd, 20, 12); m = mods[mod]; switch (VV) { case 0: m->M0 = TWOS_20(data); m->f_M0 = DOUBLE_30(m->M0); m->o_M0 = m->M0; m->o_f_M0 = m->f_M0; m->M0 = m->M0 * m->mult_scl_0 / 4; m->f_M0 *= m->mult_scl_0; break; case 1: m->M1 = TWOS_20(data); m->f_M1 = DOUBLE_30(m->M1); m->o_M1 = m->M1; m->o_f_M1 = m->f_M1; m->M1 = m->M1 * m->mult_scl_1 / 4; m->f_M1 *= m->mult_scl_1; break; case 2: m->M0 = TWOS_30(((data << 10) + ((DX >> 10) & 0x3ff))); m->f_M0 = DOUBLE_30(m->M0); m->o_M0 = m->M0; m->o_f_M0 = m->f_M0; old_DX = DX; DX = 0; m->M0 = (m->M0 / 4) * m->mult_scl_0; /* try not to set the sign bit */ m->f_M0 *= m->mult_scl_0; break; case 3: m->M1 = TWOS_30(((data << 10) + ((DX >> 10) & 0x3ff))); m->f_M1 = DOUBLE_30(m->M1); m->o_M1 = m->M1; m->o_f_M1 = m->f_M1; old_DX = DX; DX = 0; m->M1 = (m->M1 / 4) * m->mult_scl_1; m->f_M1 *= m->mult_scl_1; break; } if (describe_commands) { switch (VV) { case 0: fprintf(stderr, "m%d M0: %d: %d %.6f\n", mod, data, m->M0, m->f_M0); break; case 1: fprintf(stderr, "m%d M1: %d: %d %.6f\n", mod, data, m->M1, m->f_M1); break; case 2: fprintf(stderr, "m%d M0+DX: data: %d + DX: %d (scl: %d), %d -> %d, %.6f -> %.6f\n", mod, data, old_DX, m->mult_scl_0, m->o_M0, m->M0, m->o_f_M0, m->f_M0); break; case 3: fprintf(stderr, "m%d M1+DX: data: %d + DX: %d (scl: %d), %d -> %d, %.6f -> %.6f\n", mod, data, old_DX, m->mult_scl_1, m->o_M1, m->M1, m->o_f_M1, m->f_M1); break; } } } /* L0 (20 bits) running term * L1 (20 bits) other running term * ----------------------------------------------------------------- * ML : (20) data : 1 1 1 0: N: (7) mod # : * ----------------------------------------------------------------- * * N: 0 L0 * 1 L1 */ static void ml_command(int cmd) { int mod, N, data; modifier *m; mod = LDB(cmd, 7, 0); data = LDB(cmd, 20, 12); N = BIT(cmd, 7); m = mods[mod]; if (N == 0) { m->L0 = TWOS_20(data); m->f_L0 = DOUBLE_20(m->L0); } else { m->L1 = TWOS_20(data); m->f_L1 = DOUBLE_20(m->L1); } if (describe_commands) { if (N == 0) fprintf(stderr, "m%d L0: %d: %d %.6f\n", mod, data, m->L0, m->f_L0); else fprintf(stderr, "m%d L1: %d: %d %.6f\n", mod, data, m->L1, m->f_L1); } } /* MSUM (7 bits) result address in sum memory * MMODE (9 bits) modifier mode * ----------------------------------------------------------------- * :M:S:C:H: (9) MMODE :(7)MSUM: 1 1 1 1 0: (7) mod # : * ----------------------------------------------------------------- * * MMODE, * MSUM M: if 1, disable loading MMMMM bits of MMODE * S: if 1, disable loading MSUM * C: if 1, clear L0 * H: if 1, disable loading AABB bits of MMODE */ static const char *mode_name(int m) { switch (m) { case M_INACTIVE: return("inactive"); case M_NOISE: return("noise"); case M_TRIGGERED_NOISE: return("triggered-noise"); case M_LATCH: return("latch"); case M_THRESHOLD: return("thresh"); case M_DELAY: return("delay"); case M_TWO_POLE: return("2pole"); case M_TWO_POLE_M0: return("2pole-M0"); case M_TWO_POLE_M1: return("2pole-M1"); case M_TWO_ZERO: return("2zero"); case M_TWO_ZERO_M0: return("2zero-M0"); case M_TWO_ZERO_M1: return("2zero-M1"); case M_INTEGER_MIXING: return("int-mix"); case M_ONE_POLE: return("1pole"); case M_MIXING: return("mix"); case M_ONE_ZERO: return("1zero"); case M_MULTIPLY: return("multiply"); case M_AMP_MOD: return("am"); case M_MAX: return("max"); case M_MIN: return("min"); case M_SIGNUM: return("signum"); case M_ZERO_CROSS: return("0cross"); } return("unknown"); } static void mmode_command(int cmd) { int mod, MSUM, MMODE, M, S, C, H; modifier *m; mod = LDB(cmd, 7, 0); MSUM = LDB(cmd, 7, 12); MMODE = LDB(cmd, 9, 19); M = BIT(cmd, 31); S = BIT(cmd, 30); C = BIT(cmd, 29); H = BIT(cmd, 28); m = mods[mod]; if (S == 0) m->MSUM = MSUM; if (C == 1) { m->L0 = 0; m->f_L0 = 0.0; } /* MMODE is MMMMMAABB */ if (H == 0) { /* set up the scale factors now, so we don't have to futz around later */ /* BB = first (!) */ m->mult_scl_1 = (1 << (MMODE & 0x3)); m->mult_scl_0 = (1 << ((MMODE >> 2) & 0x3)); /* whenever M0/M1 are set, we will include these factors */ m->M0 = (m->o_M0 / 4) * m->mult_scl_0; /* order matters -- don't want to set sign bit by accident */ m->M1 = (m->o_M1 / 4) * m->mult_scl_1; m->f_M0 = m->o_f_M0 * m->mult_scl_0; m->f_M1 = m->o_f_M1 * m->mult_scl_1; if (M == 0) m->MMODE = MMODE; /* set both */ else m->MMODE = (MMODE & 0xf) + (m->MMODE & 0x1f0); /* H is 0, so set AABB */ } else { if (M == 0) m->MMODE = (MMODE & 0x1f0) + (m->MMODE & 0xf); /* M is 0, so set MMMMM */ } if (describe_commands) { fprintf(stderr, "m%d ", mod); if (M == 0) fprintf(stderr, "mode: %s", mode_name(MMODE >> 4)); if (H == 0) { if (M == 0) fprintf(stderr, ", "); fprintf(stderr, "AA: %d, BB: %d (M0: %d, %.3f, M1: %d, %.3f)", (MMODE >> 2) & 0x3, MMODE & 0x3, m->M0, m->f_M0, m->M1, m->f_M1); } if (S == 0) { if ((H == 0) || (M == 0)) fprintf(stderr, ", "); fprintf(stderr, "outloc(%s): mod-outs[%d]", ((MSUM >> 6) == 0) ? "+" : "=", MSUM & 0x3f); } if (C == 1) { if ((S == 0) || (H == 0) || (M == 0)) fprintf(stderr, ", "); fprintf(stderr, "L0=0"); } fprintf(stderr, "\n"); } if (REPORT_BAD_COMMANDS) { if (((MMODE >> 4) != M_INACTIVE) && ((mod * 2) >= processing_ticks)) fprintf(stderr, "sample %d (%.3f), command %d, m%d cannot actually run (procticks: %d)\n", samples, (double)samples / (double)srate, current_command, mod, processing_ticks); } } /* MIN (8 bits) address in sum memory where modifier reads "A" data * MRM (8 bits) address in sum memory where modifier reads "B" data * ----------------------------------------------------------------- * :R:I:C C: (8) MRM : (8) MIN : 1 1 1 1 1: (7) mod # : * ----------------------------------------------------------------- * * MRM, * MIN, R: if 1, disable loading MRM * MT I: if 1, disable loading MIN * CC: 00 turn off truncation * 01 turn on truncation * 10 clear L1 * 11 no effect */ static void mrm_command(int cmd) { int mod, MRM, MIN, R, I, CC; modifier *m; mod = LDB(cmd, 7, 0); MIN = LDB(cmd, 8, 12); MRM = LDB(cmd, 8, 20); R = BIT(cmd, 31); I = BIT(cmd, 30); CC = LDB(cmd, 2, 28); m = mods[mod]; if (R == 0) m->MRM = MRM; if (I == 0) m->MIN = MIN; switch (CC) { case 0: m->T = 0; break; case 1: m->T = 1; break; case 2: m->L1 = 0; m->f_L1 = 0.0; break; } if (describe_commands) { fprintf(stderr, "m%d inlocs:", mod); if (R == 0) { if (mod_mode(m->MMODE) == M_DELAY) fprintf(stderr, ", delay: %d", MRM & 0x1f); else { fprintf(stderr, ", MRM: "); print_mod_read_name(MRM); } } if (I == 0) { fprintf(stderr, ", MIN: "); print_mod_read_name(MIN); } if (CC == 0) fprintf(stderr, ", trunc off"); if (CC == 1) fprintf(stderr, ", trunc on"); if (CC == 2) fprintf(stderr, ", L1=0"); fprintf(stderr, "\n"); } } static void handle_command(int cmd) { /* actually we should take highest_tick - processing_ticks - 8 commands at a time, then run a sample */ int op; if ((start_describing <= samples) && (stop_describing >= samples)) describe_commands = true; else describe_commands = DEFAULT_DESCRIBE_COMMANDS; op = LDB(cmd, 4, 8); switch (op) { case 0: if (BIT(cmd, 7) == 1) dly_command(cmd); else misc_command(cmd); break; case 1: if (BIT(cmd, 7) == 1) ticks_command(cmd); else timer_command(cmd); break; case 2: case 3: gq_command(cmd); break; case 4: case 5: gj_command(cmd); break; case 6: gp_command(cmd); break; case 7: gn_command(cmd); break; case 8: gl_command(cmd); break; case 9: gk_command(cmd); break; case 10: gmode_command(cmd); break; case 11: go_command(cmd); break; case 12: case 13: mm_command(cmd); break; case 14: ml_command(cmd); break; case 15: if (BIT(cmd, 7) == 0) mmode_command(cmd); else mrm_command(cmd); break; default: fprintf(stderr, "impossible command\n"); break; } current_command++; } /* ---------------------------------------- debugging ---------------------------------------- */ #if 0 static void dump_gens(void) { int i; for (i = 0; i < GENERATORS; i++) if (gens[i]->GMODE != 0) fprintf(stderr, "g%d GMODE: %d, %d [%.3f] -> %d [%.3f], GQ: %.3f, GP: %.3f, GL: %.3f, GJ: %.3f, GO: %.3f, GN: %d, GS: %d\n", i, gens[i]->GMODE, gens[i]->GFM, ((gens[i]->GFM >> 6) == 0) ? gen_ins[gens[i]->GFM & 0x3f] : mod_ins[gens[i]->GFM & 0x3f], gens[i]->GSUM, gen_outs[gens[i]->GSUM], gens[i]->f_GQ, gens[i]->f_GP, gens[i]->f_GL, gens[i]->f_GJ, gens[i]->f_GO, gens[i]->GN, gens[i]->GS); } static void dump_mods(void) { int i; for (i = 0; i < MODIFIERS; i++) if (mods[i]->MMODE != 0) fprintf(stderr, "m%d MMODE: %d, (%d [%.3f] %d [%.3f]) -> %d [%.3f], M0: %.3f, M1: %.3f, L0: %.3f, L1: %.3f\n", i, mods[i]->MMODE, mods[i]->MIN, mod_read(mods[i]->MIN), mods[i]->MRM, mod_read(mods[i]->MRM), mods[i]->MSUM, mod_outs[mods[i]->MSUM], mods[i]->f_M0, mods[i]->f_M1, mods[i]->f_L0, mods[i]->f_L1); } #endif static void dump_gen_sum(int addr) { int i; /* show prev-ins : ins : out, g%d for all writers */ fprintf(stderr, "g-sum%d: %.3f %.3f %.3f [max: %.3f]", addr, prev_gen_ins[addr], gen_ins[addr], gen_outs[addr], peak_gen_ins[addr]); for (i = 0; i < GENERATORS; i++) if ((gens[i]->GMODE != 0) && (gens[i]->GSUM == addr)) fprintf(stderr, " g%d", i); } static void dump_mod_sum(int addr) { int i; /* show prev-ins : ins : out, m%d for all writers */ fprintf(stderr, "m-sum%d: %.3f %.3f %.3f [max: %.3f]", addr, prev_mod_ins[addr], mod_ins[addr], mod_outs[addr], peak_mod_ins[addr]); for (i = 0; i < MODIFIERS; i++) if ((mod_mode(mods[i]->MMODE) != M_INACTIVE) && ((mods[i]->MSUM &0x3f) == addr)) fprintf(stderr, " m%d", i); } static void print_mod_sum(int addr) { int loc; loc = addr & 0x3f; switch ((addr >> 6) & 0x3) { case 0: fprintf(stderr, "["); dump_gen_sum(loc); break; case 1: fprintf(stderr, "["); if (loc == 0) { if ((prev_mod_ins[0] != 0.0) || (mod_ins[0] != 0.0) || (mod_outs[0] != 0.0) || (peak_mod_ins[0] != 0)) dump_mod_sum(0); else fprintf(stderr, "zero"); } else dump_mod_sum(loc); break; case 2: fprintf(stderr, "-out["); if (loc == 0) { if ((prev_mod_ins[0] != 0.0) || (mod_ins[0] != 0.0) || (mod_outs[0] != 0.0) || (peak_mod_ins[0] != 0)) dump_mod_sum(0); else fprintf(stderr, "zero"); } else dump_mod_sum(loc); break; case 3: fprintf(stderr, "[illegal: %d", addr); break; } } static int gen_mem_readers(int addr) { int i, rds = 0; for (i = 0; i < GENERATORS; i++) if ((gens[i]->GMODE != 0) && (gens[i]->GFM == addr)) /* Q bit 0 = gen */ rds++; for (i = 0; i < MODIFIERS; i++) if (mod_mode(mods[i]->MMODE) != M_INACTIVE) { if (mods[i]->MIN == addr) /* QQ bits = 0 = gen */ rds++; if ((mod_mode(mods[i]->MMODE) != M_DELAY) && (mods[i]->MRM == addr)) rds++; } return(rds); } static int mod_mem_readers(int addr) { int i, rds = 0; for (i = 0; i < GENERATORS; i++) if ((gens[i]->GMODE != 0) && (gens[i]->GFM == 64 + addr)) /* Q bit 1 = mod */ rds++; for (i = 0; i < MODIFIERS; i++) if (mod_mode(mods[i]->MMODE) != M_INACTIVE) { if ((mods[i]->MIN == 64 + addr) || (mods[i]->MIN == 128 + addr)) rds++; if ((mod_mode(mods[i]->MMODE) != M_DELAY) && ((mods[i]->MRM == 64 + addr) || (mods[i]->MRM == 128 + addr))) rds++; } return(rds); } static void dump_patch(void) { /* try to show all currently active elements and memory with some history */ int i, p; fprintf(stderr, "sample: %d, command: %d, ", samples, current_command); for (i = 0, p = 0; i < GENERATORS; i++) if (gens[i]->GMODE != 0) p++; fprintf(stderr, "active gens: %d, ", p); for (i = 0, p = 0; i < MODIFIERS; i++) if (mod_mode(mods[i]->MMODE) != M_INACTIVE) p++; fprintf(stderr, "active mods: %d, ", p); for (i = 0, p = 0; i < DELAYS; i++) if (dlys[i]->P != 0) p++; fprintf(stderr, "active delays: %d\n\n", p); for (i = 0; i < GENERATORS; i++) if (gens[i]->GMODE != 0) { generator *g; g = gens[i]; fprintf(stderr, "g%d ", i); print_gmode_name(g->GMODE); fprintf(stderr, " ["); if ((g->GFM >> 6) == 0) dump_gen_sum(g->GFM & 0x3f); else print_mod_sum(g->GFM); fprintf(stderr, "]->["); if (osc_run(g->GMODE) == 2) fprintf(stderr, "OUT%d", g->GO & 0xf); else dump_gen_sum(g->GSUM); fprintf(stderr, " (%d)], (amp: %.3f, freq: %.3f", gen_mem_readers(g->GSUM), gen_amp(g), g->f_GJ * 0.5 * srate); if (g->f_GJ == 0.0) fprintf(stderr, ", phase: %.3f", g->f_GK); fprintf(stderr, ")\n"); } fprintf(stderr, "\n"); for (i = 0; i < MODIFIERS; i++) if (mod_mode(mods[i]->MMODE) != M_INACTIVE) { modifier *m; m = mods[i]; fprintf(stderr, "m%d %s ", i, mode_name(mod_mode(m->MMODE))); if (mod_mode(m->MMODE) == M_MIXING) fprintf(stderr, "%.4f * ", m->f_M0); fprintf(stderr, "A"); print_mod_sum(m->MIN); fprintf(stderr, "], "); if (mod_mode(m->MMODE) == M_MIXING) fprintf(stderr, "%.4f * ", m->f_M1); fprintf(stderr, "B"); if (mod_mode(m->MMODE) == M_DELAY) { delay *d; d = dlys[m->MRM & 0x1f]; fprintf(stderr, "[delay: %d (%.4f)", m->MRM & 0x1f, delay_memory[d->X + d->Y]); fprintf(stderr, ", M0: %.4f, M1: %.4f, L0: %.4f, L1: %.4f", m->f_M0, m->f_M1, m->f_L0, m->f_L1); } else print_mod_sum(m->MRM); fprintf(stderr, "]->["); if ((m->MSUM >> 6) != 0) fprintf(stderr, "-replace"); dump_mod_sum(m->MSUM & 0x3f); fprintf(stderr, " (%d)]\n", mod_mem_readers(m->MSUM)); } fprintf(stderr, "\n"); for (i = 0; i < DELAYS; i++) if (dlys[i]->P != D_INACTIVE) { delay *d; d = dlys[i]; fprintf(stderr, "d%d %s %.3f (%d + %d of %d)\n", i, P_name(d->P), delay_memory[d->X + d->Y], d->X, d->Y, d->Z); } { double dmax; dmax = fabs(delay_memory[0]); for (i = 1; i < DELAY_MEMORY_SIZE; i++) if (fabs(delay_memory[i]) > dmax) dmax = fabs(delay_memory[i]); fprintf(stderr, "delay memory peak: %.4f\n\n", dmax); } } /* ---------------------------------------- main program ---------------------------------------- */ int main(int argc, char **argv) { if (argc < 2) fprintf(stderr, "sam filename [read_data file] [srate]\n"); /* mmm */ else { FILE *sam_file; filename = argv[1]; sam_file = fopen(filename, "r"); if (!sam_file) fprintf(stderr, "can't find %s\n", filename); else { long size; fseek(sam_file, 0, SEEK_END); size = ftell(sam_file); rewind(sam_file); if (size <= 0) { fprintf(stderr, "%s is empty\n", filename); fclose(sam_file); } else { size_t bytes; unsigned char *command; int i; if (argc > 2) { read_data_file = fopen(argv[2], "r"); if (argc > 3) { /* mmm - set srate explicitly. I had an inexplicably high max tick setting in one sam file with read data input. */ sscanf(argv[3], "%d", &srate); } } start_clean(); command = (unsigned char *)calloc(size + 1, sizeof(unsigned char)); bytes = fread(command, sizeof(unsigned char), size, sam_file); fclose(sam_file); /* these were stored in at least 2 different formats * * FASTF.SAM: "Type: 32BITR BADSAM ;Looks like a SAM command file but has questionable data" * MACDON.SAM: "Type: SAM SIMPLE ;Simple SAM command file (corresponding sound file possible)" * * FASTF was written as 32 bits (using the 1st case below), and MACDON as 36 (using the 2nd case). * it looks like someone got a flag backwards, and wrote the known-good 32-bit files as 36, * and the possibly not-32 bit files as 32. I can't find the corresponding code in the writers * that Nando found on the exabyte tapes. * * The *.SAM.snd files are raw big-endian 24-bit int data (stereo?) * with many (6?) renditions? */ #if 1 if ((command[0] != 0) || /* just a first guess */ (command[1] != 0)) { fprintf(stderr, "32\n"); total_commands = bytes / 4; current_command = 0; for (i = 0; i < bytes; i += 4) { int cmd; int b1, b2, b3, b4; b1 = command[i + 0]; b2 = command[i + 1]; b3 = command[i + 2]; b4 = command[i + 3]; cmd = b4 + (b3 << 8) + (b2 << 16) + (b1 << 24); handle_command(cmd); } } else { fprintf(stderr, "36\n"); total_commands = bytes / 5; current_command = 0; for (i = 0; i < bytes; i += 5) { int cmd; int b1, b2, b3, b4, b5; b1 = command[i + 0]; b2 = command[i + 1]; b3 = command[i + 2]; b4 = command[i + 3]; b5 = command[i + 4]; cmd = ((b5 >> 4) & 0xff) + (b4 << 4) + (b3 << 12) + (b2 << 20) + ((b1 & 0xff) << 28); handle_command(cmd); } } #else /* another format that Mike used: * cmd = (b1 << 28) | (b2 << 24) | (b3 << 16) | (b4 << 8) | b5; */ total_commands = bytes / 5; current_command = 0; for (i = 0; i < bytes; i += 5) { int cmd; int b1, b2, b3, b4, b5; b1 = command[i + 0]; b2 = command[i + 1]; b3 = command[i + 2]; b4 = command[i + 3]; b5 = command[i + 4]; cmd = (b1 << 28) | (b2 << 24) | (b3 << 16) | (b4 << 8) | b5; handle_command(cmd); } #endif } all_done(); } } return(0); } /* on the cover of an old copy of the specs: NOT TO LEAVE THE MUSIC ROOM [red ink and underlined] Would be an awful fate, [pencilled in below] Said Cleopatra to her groom, and struck him on the pate! */ snd-16.1/tools/sarchive0000755000076400007640000001110612600533415013223 0ustar bilbil#!/bin/csh -f date > /home/bil/cl/hi echo ' ' >> /home/bil/cl/hi chdir /home/bil/s7 foreach file (*.h *.c *.html *.scm gdbinit) if (-e /home/bil/cl/$file) then find /home/bil/cl/$file -newer /home/bil/s7/$file -exec echo ' updating ' $file \; find /home/bil/cl/$file -newer /home/bil/s7/$file -exec cp /home/bil/cl/$file /home/bil/s7 \; else echo $file 'does not exist in /home/bil/cl' endif end chdir /home/bil/dist/snd foreach file (*.h *.c *.cl *.el *.clm *.html makefile.* make.* *.in *.scm *.lisp *.fs *.fsm *.js *.Snd snd.1 configure.ac *.rb *.m4 config.guess config.sub NEWS *.tex COPYING DotEmacs *.f music5-examples) if (-e /home/bil/cl/$file) then diff -bcw /home/bil/cl/$file /home/bil/dist/snd/$file >> /home/bil/cl/hi find /home/bil/cl/$file -newer /home/bil/dist/snd/$file -exec echo ' updating ' $file \; find /home/bil/cl/$file -newer /home/bil/dist/snd/$file -exec cp /home/bil/dist/snd/$file /home/bil/old-dist \; find /home/bil/cl/$file -newer /home/bil/dist/snd/$file -exec cp /home/bil/cl/$file /home/bil/dist/snd \; else echo $file 'does not exist in /home/bil/cl' endif end chdir /home/bil/dist/snd/pix foreach file (*.png) if (-e /home/bil/cl/pix/$file) then find /home/bil/cl/pix/$file -newer /home/bil/dist/snd/pix/$file -exec echo ' updating ' pix/$file \; find /home/bil/cl/pix/$file -newer /home/bil/dist/snd/pix/$file -exec cp /home/bil/dist/snd/pix/$file /home/bil/old-dist \; find /home/bil/cl/pix/$file -newer /home/bil/dist/snd/pix/$file -exec cp /home/bil/cl/pix/$file /home/bil/dist/snd/pix \; else echo pix/$file 'does not exist in /home/bil/cl/pix' endif end chdir /home/bil/cl/tools foreach file (*) if (-e /home/bil/cl/$file) then find /home/bil/cl/$file -newer /home/bil/cl/tools/$file -exec echo ' updating ' cl/tools/$file \; find /home/bil/cl/$file -newer /home/bil/cl/tools/$file -exec cp /home/bil/cl/tools/$file /home/bil/old-dist \; find /home/bil/cl/$file -newer /home/bil/cl/tools/$file -exec cp /home/bil/cl/$file /home/bil/cl/tools \; endif end chdir /home/bil/dist/snd/tools foreach file (*) if (-e /home/bil/cl/tools/$file) then diff -bcw /home/bil/cl/tools/$file /home/bil/dist/snd/tools/$file >> /home/bil/cl/hi find /home/bil/cl/tools/$file -newer /home/bil/dist/snd/tools/$file -exec echo ' updating ' snd/tools/$file \; find /home/bil/cl/tools/$file -newer /home/bil/dist/snd/tools/$file -exec cp /home/bil/dist/snd/tools/$file /home/bil/old-dist \; find /home/bil/cl/tools/$file -newer /home/bil/dist/snd/tools/$file -exec cp /home/bil/cl/tools/$file /home/bil/dist/snd/tools \; else echo $file '(snd tools) does not exist in /home/bil/cl/tools' endif end chdir /home/bil/dist/snd/sndins foreach file (*.h *.c *.in README) if (-e /home/bil/cl/sndins/$file) then diff -bcw /home/bil/cl/sndins/$file /home/bil/dist/snd/sndins/$file >> /home/bil/cl/hi find /home/bil/cl/sndins/$file -newer /home/bil/dist/snd/sndins/$file -exec echo ' updating ' sndins/$file \; find /home/bil/cl/sndins/$file -newer /home/bil/dist/snd/sndins/$file -exec cp /home/bil/dist/snd/sndins/$file /home/bil/old-dist \; find /home/bil/cl/sndins/$file -newer /home/bil/dist/snd/sndins/$file -exec cp /home/bil/cl/sndins/$file /home/bil/dist/snd/sndins \; else echo $file '(snd sndins) does not exist in /home/bil/cl/sndins' endif end chdir /home/bil/dist/snd/sndins/samples foreach file (*.rb *.scm *.fth *.fs) if (-e /home/bil/cl/sndins/samples/$file) then diff -bcw /home/bil/cl/sndins/samples/$file /home/bil/dist/snd/sndins/samples/$file >> /home/bil/cl/hi find /home/bil/cl/sndins/samples/$file -newer /home/bil/dist/snd/sndins/samples/$file -exec echo ' updating ' sndins/samples/$file \; find /home/bil/cl/sndins/samples/$file -newer /home/bil/dist/snd/sndins/samples/$file -exec cp /home/bil/dist/snd/sndins/samples/$file /home/bil/old-dist \; find /home/bil/cl/sndins/samples/$file -newer /home/bil/dist/snd/sndins/samples/$file -exec cp /home/bil/cl/sndins/samples/$file /home/bil/dist/snd/sndins/samples \; else echo $file '(snd sndins/samples) does not exist in /home/bil/cl/sndins/samples' endif end chdir /home/bil/cl foreach file (*.rb *.fth *.fs) if (-e /home/bil/dist/snd/$file) then else echo $file ' does not exist in /home/bil/dist/snd' endif end chdir /home/bil/cl/pix foreach file (*.png) if (-e /home/bil/dist/snd/pix/$file) then else echo $file ' does not exist in /home/bil/dist/snd/pix' endif end chdir /home/bil/dist/snd cp /home/bil/cl/configure /home/bil/dist/snd rm snd.tar tar -chf snd.tar * chdir /home/bil/cl wc hi snd-16.1/tools/table.scm0000755000076400007640000000143412563466222013303 0ustar bilbil(define (no-dashes-or-cr str) (let ((len (length str)) (newstr (make-string 0)) (last-ch #\-)) (do ((i 0 (+ i 1))) ((= i (- len 1))) (let ((ch (string-ref str i))) (if (and (or (not (char=? ch #\-)) (char-alphabetic? last-ch)) (not (char=? ch #\newline))) (set! newstr (string-append newstr (make-string 1 ch)))) (set! last-ch ch))) newstr)) (let ((ctr 0)) (call-with-input-file "snd-test.scm" (lambda (file) (let loop ((line (read-line file #t))) (set! ctr (+ ctr 1)) (or (eof-object? line) (let ((len (length line))) (if (and (> len 30) (string=? ";;; ---------------- test " (substring line 0 26))) (format #t "~A ~48,1T[~D]~%" (no-dashes-or-cr line) ctr)) (loop (read-line file #t)))))))) (exit) snd-16.1/tools/gdbinit0000644000076400007640000002361112614526510013043 0ustar bilbildefine s7print print s7_object_to_c_string(sc, $arg0) end document s7print interpret the argument as an s7 value and display it end # the current expression is sc->cur_code # the current environment is sc->envir # the error environment is sc->owlet # so for example, to see the current local variables, s7p sc->envir # source ~/.gdbinit reloads define s7eval print s7_object_to_c_string(sc, s7_eval_c_string(sc, $arg0)) end document s7eval eval the argument (a string) end define s7stack print s7_object_to_c_string(sc, s7_stacktrace(sc)) end document s7stack display the currently active local environments end define s7value print s7_object_to_c_string(sc, s7_name_to_value(sc, $arg0)) end document s7value print the value of the variable passed by its print name: s7v "*features*" end define s7bt set logging overwrite on set logging redirect on set logging on bt set logging off # now gdb.txt has the backtrace print s7_decode_bt() end document s7bt print a backtrace with s7 objects decoded as much as possible end define s7btfull set logging overwrite on set logging redirect on set logging on bt full set logging off print s7_decode_bt() end document s7btfull print a full backtrace with s7 objects decoded as much as possible end # this requires -g3 compilation define s7cell set $escape = 27 set $cell = (s7_cell *)$arg0 set $type = $cell.tf.type_field set $is_bad_type = (($type <= T_FREE) || ($type >= NUM_TYPES)) printf "%s\n", describe_type_bits(sc, $cell) printf "hloc: %d, ", $cell.hloc printf "fields: %p %p %p %p %p\n",\ $cell.object.cons.car, $cell.object.cons.cdr, $cell.object.cons.opt1, $cell.object.cons.opt2, $cell.object.cons.opt3 if (($type == T_NIL) || ($type == T_BOOLEAN) || ($type == T_UNIQUE)) printf "constant: %s\n", $cell.object.unq.name end if (($type == T_INTEGER) || ($is_bad_type)) printf "integer_value: %lld\n", $cell.object.number.integer_value end if (($type == T_REAL) || ($is_bad_type)) printf "real_value: %f\n", $cell.object.number.real_value end if (($type == T_RATIO) || ($is_bad_type)) printf "fraction_value: %lld / %lld\n", $cell.object.number.fraction_value.numerator, $cell.object.number.fraction_value.denominator end if (($type == T_COMPLEX) || ($is_bad_type)) printf "complex_value: %f + %fi\n", $cell.object.number.complex_value.rl, $cell.object.number.complex_value.im end if ($type == T_BIG_INTEGER) if (WITH_GMP) printf "big integer: %p\n", $cell.object.number.big_integer else printf "big integer??\n" end end if ($type == T_BIG_RATIO) if (WITH_GMP) printf "big ratio: %p\n", $cell.object.number.big_ratio else printf "big ratio??\n" end end if ($type == T_BIG_REAL) if (WITH_GMP) printf "big real: %p\n", $cell.object.number.big_real else printf "big real??\n" end end if ($type == T_BIG_COMPLEX) if (WITH_GMP) printf "big complex: %p\n", $cell.object.number.big_complex else printf "big complex??\n" end end if (($is_bad_type) || (($cell.tf.flag & T_PRINT_NAME) != 0)) printf "pval: padding: %s, name: %s\n", $cell.object.number.pval.padding, $cell.object.number.pval.name end if ($is_bad_type) printf "ul_value: %ld, %lld\n", $cell.object.number.ul_value, $cell.object.number.ull_value end if ($type == T_BAFFLE) printf "baffle: %d\n", $cell.object.baffle_key end if ($type == T_C_POINTER) printf "c_pointer: %p\n", $cell.object.c_pointer end if ($type == T_RANDOM_STATE) if (WITH_GMP) printf "random-state\n" else printf "random-state: seed: %lld, carry: %lld\n", $cell.object.rng.seed, $cell.object.rng.carry end end if (($type == T_PAIR) || ($is_bad_type)) printf "cons: car: %p, cdr: %p, opt1: %p, opt2: %p, opt3: %p\n", \ $cell.object.cons.car, $cell.object.cons.cdr, $cell.object.cons.opt1, $cell.object.cons.opt2, $cell.object.cons.opt3 printf " line: %d, op: %d\n", \ $cell.object.sym_cons.line, $cell.object.sym_cons.op end if (($type == T_CHARACTER) || ($is_bad_type)) printf "chr: c: %c, up_c: %c, alpha_c: %d, digit_c: %d, space_c: %d, upper_c: %d, lower_c: %d", \ $cell.object.chr.c, $cell.object.chr.up_c, \ $cell.object.chr.alpha_c, $cell.object.chr.digit_c, $cell.object.chr.space_c, $cell.object.chr.upper_c, $cell.object.chr.lower_c if ($type == T_CHARACTER) printf ", c_name: %s, length: %d", $cell.object.chr.c_name, $cell.object.chr.length end end if ($type == T_SLOT) printf "slt: sym: %p, val: %p, nxt: %p, pending_value: %p, expr: %p\n", \ $cell.object.slt.sym, $cell.object.slt.val, $cell.object.slt.nxt, $cell.object.slt.pending_value, $cell.object.slt.expr end if ($type == T_LET) printf "envr: slots: %p, nxt: %p, id: %lld\n", $cell.object.envr.slots, $cell.object.envr.nxt, $cell.object.envr.id end if ($type == T_ITERATOR) printf "iter: obj: %p, cur: %p, loc: %lld\n", $cell.object.iter.obj, $cell.object.iter.cur, $cell.object.iter.lc.loc end if ($type == T_COUNTER) printf "ctr: result: %p, list: %p, env: %p, cap: %lld, len: %lld\n", \ $cell.object.ctr.result, $cell.object.ctr.list, $cell.object.ctr.env, $cell.object.ctr.cap, $cell.object.ctr.len end if ($type == T_C_OBJECT) if (num_types >= $cell.object.c_obj.type) printf "c_obj: %c[31mtype: %d%c[0m, value: %p, e: %p\n", $escape, $cell.object.c_obj.type, $escape, $cell.object.c_obj.value ,$cell.object.c_obj.e else printf "c_obj: type: %d, value: %p, e: %p\n", $cell.object.c_obj.type, $cell.object.c_obj.value ,$cell.object.c_obj.e end end if (($type == T_STRING) || ($is_bad_type)) if (($cell.tf.type_field & T_BYTE_VECTOR) != 0) printf "byte-vector: " else printf "string: " end printf "length: %d, hash: %d, needs_free: %d, initial_slot: %p", \ $cell.object.string.length, $cell.object.string.hash, $cell.object.string.str_ext.needs_free, $cell.object.string.initial_slot if ($type == T_STRING) printf ", svalue: %s", $cell.object.string.svalue end printf "\n" end if (($type == T_SYMBOL) || ($is_bad_type)) printf "sym: name: %p, global_slot: %p, local_slot: %p, \n id: %d, tag: %d, accessor: %d\n", \ $cell.object.sym.name, $cell.object.sym.global_slot, $cell.object.sym.local_slot, $cell.object.sym.id, $cell.object.sym.tag, $cell.object.string.str_ext.accessor end if (($type == T_SYNTAX) || ($is_bad_type)) printf "syn: symbol: %p, op: %d\n", $cell.object.syn.symbol, $cell.object.syn.op end if (($type == T_CONTINUATION) || ($is_bad_type)) printf "continuation: continuation: %p, stack: %p, start_start: %p, stack_end: %p, op_stack: %p, key: %d\n", \ $cell.object.cwcc.continuation, $cell.object.cwcc.stack, $cell.object.cwcc.stack_start, $cell.object.cwcc.stack_end, $cell.object.cwcc.op_stack, \ $cell.object.cwcc.continuation->local_key end if (($type == T_VECTOR) || ($is_bad_type) || ($type == T_INT_VECTOR) || ($type == T_FLOAT_VECTOR)) printf "\nvector: length: %lld, dim_info: %p, vget: %p, vset: %p, objects: %p\n", \ $cell.object.vector.length, $cell.object.vector.dim_info, $cell.object.vector.vget, $cell.object.vector.vset, $cell.object.vector.elements.objects end if (($type == T_HASH_TABLE) || ($is_bad_type)) printf "hasher: mask: %lld, elements: %p, entries: %d,\n hash_func: %p, loc: %p, dproc: %p\n", \ $cell.object.hasher.mask, $cell.object.hasher.elements, $cell.object.hasher.entries, $cell.object.hasher.hash_func, $cell.object.hasher.loc, $cell.object.hasher.dproc end if (($type == T_INPUT_PORT) || ($type == T_OUTPUT_PORT)) printf "prt: port: %p, data: %p, size: %d, point: %d,\n line_number: %d, file_number: %d, is_closed: %d, ptype: %d\n", \ $cell.object.prt.port, $cell.object.prt.data, $cell.object.prt.size, $cell.object.prt.point, \ $cell.object.prt.line_number, $cell.object.prt.file_number, $cell.object.prt.is_closed, $cell.object.prt.ptype end if (($type == T_CATCH) || ($is_bad_type)) printf "rcatch: goto_loc: %d, op_stack_loc: %d, tag: %p, handler: %p\n", \ $cell.object.rcatch.goto_loc, $cell.object.rcatch.op_stack_loc, $cell.object.rcatch.tag, $cell.object.rcatch.handler end if (($type == T_GOTO) || ($is_bad_type)) printf "rexit: goto_loc: %d, op_stack_loc: %d, active: %d\n", $cell.object.rexit.goto_loc, $cell.object.rexit.op_stack_loc, $cell.object.rexit.active end if (($type == T_DYNAMIC_WIND) || ($is_bad_type)) printf "winder: in: %p, out: %p, body: %p, state: %d\n", \ $cell.object.winder.in, $cell.object.winder.out, $cell.object.winder.body, $cell.object.winder.state end if (($type == T_CLOSURE) || ($type == T_CLOSURE_STAR) || ($type == T_MACRO) || ($type == T_BACRO) || ($is_bad_type)) printf "func: args: %p, body: %p, env: %p, setter: %p, arity: %d\n", \ $cell.object.func.args, $cell.object.func.body, $cell.object.func.env, $cell.object.func.setter, $cell.object.func.arity end if (($type >= T_C_FUNCTION_STAR) || ($is_bad_type)) printf "c-fnc: c_proc: %p, ff: %p, setter: %p,\n required_args: %d, optional_args: %d, all_args: %d, rest_arg: %d\n", \ $cell.object.fnc.c_proc, $cell.object.fnc.ff, $cell.object.fnc.setter, \ $cell.object.fnc.required_args, $cell.object.fnc.optional_args, $cell.object.fnc.all_args, $cell.object.fnc.rest_arg if ((!$is_bad_type) && ($cell.object.fnc.c_proc != 0)) printf " name: %s\n", $cell.object.fnc.c_proc->name end end snd-16.1/tools/compare-calls.scm0000644000076400007640000001452712571434533014741 0ustar bilbil;; find where two callgrind runs differ, also combine n callgrind runs (define (compare-calls f1 f2) (let ((h1 (with-input-from-file f1 read-calls)) (total-diff 0) (diffs ()) (scl 1e-6)) (let ((h2 (with-input-from-file f2 read-calls))) (for-each (lambda (kv1) (let ((kv2 (h2 (car kv1)))) (let ((diff (if kv2 (- kv2 (cdr kv1)) (- (cdr kv1))))) (if (> (abs diff) 3e6) (begin (set! diffs (cons (list diff (car kv1) (cdr kv1) (or kv2 0)) diffs)) (set! total-diff (+ total-diff diff))))))) h1) (for-each (lambda (kv2) (let ((kv1 (h1 (car kv2)))) (if (not kv1) (let ((diff (cdr kv2))) (if (> (abs diff) 3e6) (begin (set! diffs (cons (list diff (car kv2) 0 (cdr kv2)) diffs)) (set! total-diff (+ total-diff diff)))))))) h2)) (let ((vals (sort! diffs (lambda (a b) (> (car a) (car b)))))) (format *stderr* "total: ~,3F~%" (* scl total-diff)) (for-each (lambda (entry) (format *stderr* "~A~,3F~12T(~,3F~24T~,3F)~40T~A~%" (if (negative? (entry 0)) "" " ") (* scl (entry 0)) (* scl (entry 2)) (* scl (entry 3)) (entry 1))) vals))) (exit)) (define (string->number-ignoring-commas str) (let ((num 0) (tens 1) (len (length str))) (do ((i (- len 1) (- i 1))) ((< i 0) num) (if (char-numeric? (str i)) (begin (set! num (+ num (* tens (- (char->integer (str i)) 48)))) (set! tens (* 10 tens))))))) (define (read-calls) ;; throw away the header (do ((i 0 (+ i 1))) ((= i 25)) (read-line)) ;; read about 500 lines and store in a hash table as (func . timing) (let ((h (make-hash-table))) (call-with-exit (lambda (quit) (do ((i 0 (+ i 1))) ((= i 500)) (let ((line (read-line))) (if (eof-object? line) (quit)) (let ((len (length line))) (do ((k 0 (+ k 1))) ((or (= k len) (not (char-whitespace? (line k)))) (if (< k len) (let ((end (char-position #\space line k))) (if end (let ((num (string->number-ignoring-commas (substring line k end)))) (when num (let ((func-end (char-position #\space line (+ end 2)))) (when (and (number? func-end) (> func-end (+ end 2))) (let ((func (string->symbol (substring line (+ end 2) func-end)))) (set! (h func) num)))))))))))))))) h)) (define (get-overheads file) (with-input-from-file file (lambda () (let ((overheads ()) (total 0)) (define (get-overheads-1 file line) (let ((len (min 20 (length line)))) (do ((i 0 (+ i 1))) ((or (= i len) (not (char-whitespace? (line i)))) (if (and (< i (- len 4)) (char=? (line i) #\.) (char=? (line (+ i 1)) #\space) (char=? (line (+ i 2)) #\space) (char-alphabetic? (line (+ i 3)))) (let ((next-line (read-line))) (let ((nlen (length next-line))) (if (char=? (next-line (- nlen 1)) #\{) (do ((j 0 (+ j 1))) ((or (= j nlen) (and (char-numeric? (next-line j)) (let ((cost (string->number-ignoring-commas (substring next-line j (- nlen 3))))) (set! total (+ total cost)) (set! overheads (cons (list cost (substring line (+ i 3) (min 80 (length line)))) overheads))))))) (get-overheads-1 file next-line))))))))) (do ((line (read-line) (read-line))) ((eof-object? line) overheads) (get-overheads-1 file line)) (set! overheads (sort! overheads (lambda (a b) (< (car a) (car b))))) (format *stderr* "~{~^~A~%~}" (list-tail overheads (max 10 (- (length overheads) 40)))) (format *stderr* "total: ~A~%" total))))) (define (read-all-calls) ;; throw away the header (do ((i 0 (+ i 1))) ((= i 25)) (read-line)) (let ((h (make-hash-table))) (call-with-exit (lambda (quit) (do () () (let ((line (read-line))) (if (or (eof-object? line) (and (= (length line) 80) (char=? (line 0) #\-))) (quit)) (let ((len (length line))) (do ((k 0 (+ k 1))) ((or (= k len) (not (char-whitespace? (line k)))) (if (< k len) (let ((end (char-position #\space line k))) (if end (let ((num (string->number-ignoring-commas (substring line k end)))) (when num (let ((func-end (char-position #\space line (+ end 2)))) (when (and (number? func-end) (> func-end (+ end 2))) (let* ((name (substring line (+ end 2) func-end)) (len (length name))) (if (and ;(not (char=? (name 0) #\?)) (not (char=? (name 0) #\/)) (or (< len 3) (not (char=? (name (- len 2)) #\'))) (or (< len 8) (not (string=? "libgsl_" (substring name 0 7))))) (set! (h (string->symbol name)) num))))))))))))))))) h)) (define (combine . files) (let ((tables (map (lambda (file) (with-input-from-file file read-all-calls)) files))) (let ((h (make-hash-table))) (for-each (lambda (file table) (for-each (lambda (entry) (let ((current-entry (h (car entry)))) (if current-entry (set! (h (car entry)) (cons (max (cdr entry) (car current-entry)) (cons (list file (cdr entry)) (cdr current-entry)))) (set! (h (car entry)) (cons (cdr entry) (list (list file (cdr entry)))))))) table)) files tables) (let ((v (copy h (make-vector (hash-table-entries h))))) (set! v (sort! v (lambda (a b) (> (cadr a) (cadr b))))) (call-with-output-file "test.table" (lambda (p) (for-each (lambda (entry) (format p "~A: ~A ~{~%~16T~{~A~32T ~A~}~}~%" (car entry) (cadr entry) (cddr entry))) v))))))) (define (combine-latest) (let ((file-names (list "v-eq" "v-iter" "v-map" "v-form" "v-hash" "v-cop" "v-lg" "v-gen" "v-auto" "v-index" "v-call" "v-all" "v-test" "/home/bil/test/bench/src/v-b"))) (define (next-file f) (let ((name (system (format #f "ls -t ~A*" f) #t))) (let ((len (length name))) (do ((i 0 (+ i 1))) ((or (= i len) (and (char-numeric? (name i)) (char-numeric? (name (+ i 1))))) (string-append f (substring name i (+ i 2)))))))) (apply combine (map next-file file-names)))) #| (combine "v-call53" "v-map52" "v-all98" "v-hash31" "v-gen72" "v-auto51" "v-lg73" "v-cop55" "v-form66" "v-eq46" "v-test57" "v-iter70" "v-index22" "/home/bil/test/bench/src/v-b28") |# snd-16.1/tools/compsnd0000755000076400007640000010141512626144465013100 0ustar bilbil#!/bin/csh -f # cp ~/dist/snd/snd.tar . # tar xf snd.tar # words I constantly missppelll fgrep decrip *.html fgrep accomoda *.html fgrep pysical *.html fgrep decrip *.c fgrep maake *.c fgrep maake *.html fgrep accomoda *.c fgrep decrip *.scm fgrep accomoda *.scm fgrep -e "the the " *.c fgrep -e "the the " *.html fgrep udpate *.c fgrep udpate *.html fgrep udpate *.scm fgrep -e "Float* " *.[ch] fgrep -e "float* " *.h fgrep -e "double* " *.h fgrep -e "int* " *.h fgrep -e "off_t* " *.[ch] fgrep -e " long* " *.[ch] grep ' \-\-$' *.html /home/bil/cl/snd tools/va.scm echo ' ' echo ' ' rm -f snd rm -f config.cache echo ' -------------------------------------------------------------------------------- ' echo ' ---- basic configure test ----- ' echo ' -------------------------------------------------------------------------------- ' ./configure --quiet --with-motif CFLAGS="-O3 -Wall -I/usr/X11R6/include" LDFLAGS="-L/usr/X11R6/lib" make echo ' ' echo ' ' ./snd --version ./snd -noinit --features "'clm 'snd-s7 'snd-motif 'sndlib" ./snd -e '(begin (load "cload.scm") (set! *cload-cflags* "-Wall"))' libm.scm libc.scm libgdbm.scm libdl.scm libgsl.scm -e '(exit)' echo ' -------------------------------------------------------------------------------- ' echo ' ---- ffitest ----- ' echo ' -------------------------------------------------------------------------------- ' cp tools/ffitest.c . gcc -o ffitest ffitest.c -g3 -Wall s7.o -lm -I. -ldl ffitest gcc s7.c -o repl -Wall -DWITH_MAIN -DUSE_SND=0 -I. -O2 -g3 -Wl,-export-dynamic -ldl -lm echo '#define WITH_SYSTEM_EXTRAS 0' >mus-config.h cc -c s7.c -o s7.o -Wall rm s7.o echo '#define WITH_QUASIQUOTE_VECTOR 1' >mus-config.h cc -c s7.c -o s7.o -Wall rm s7.o echo '#define WITH_C_LOADER 0' >mus-config.h cc -c s7.c -o s7.o -Wall rm s7.o echo '#define WITH_EXTRA_EXPONENT_MARKERS 1' >mus-config.h cc -c s7.c -o s7.o -Wall rm s7.o make clmclean make sndinfo make sndplay make allclean ./configure --quiet --with-motif CFLAGS="-Wall -I/usr/X11R6/include -Wdeclaration-after-statement" LDFLAGS="-L/usr/X11R6/lib" make allclean make echo ' ' echo ' ' make clmclean make sndinfo make sndplay make allclean echo ' ' echo ' ' echo ' -------------------------------------------------------------------------------- ' echo ' ---- g++ ---- ' echo ' -------------------------------------------------------------------------------- ' ./configure --quiet CC=g++ CFLAGS="-Wall -I/usr/X11R6/include" LDFLAGS="-L/usr/X11R6/lib" make ./snd --version ./snd -noinit --features "'clm" make allclean rm -f snd rm -f config.cache echo ' ' echo ' ' echo ' -------------------------------------------------------------------------------- ' echo ' ---- clang ---- ' echo ' -------------------------------------------------------------------------------- ' ./configure --quiet CC=/home/bil/test/llvm-3.1.src/build/Release+Asserts/bin/clang CFLAGS="-Wall -I/usr/X11R6/include" LDFLAGS="-L/usr/X11R6/lib" make ./snd --version ./snd -noinit --features "'clm" make allclean rm -f snd rm -f config.cache ./configure --quiet CC=clang CFLAGS="-Wall -I/usr/X11R6/include" LDFLAGS="-L/usr/X11R6/lib" make make allclean rm -f snd rm -f config.cache echo ' ' echo ' ' echo ' -------------------------------------------------------------------------------- ' echo ' ----- --without-gui ---- ' echo ' -------------------------------------------------------------------------------- ' ./configure --quiet LDFLAGS="-L/usr/X11R6/lib" CFLAGS="-Wall -I/usr/X11R6/include" --without-gui make echo ' ' echo ' ' ./snd --version ./snd -noinit --features "'clm 'snd-nogui" make allclean rm -f snd rm -f config.cache echo ' ' echo ' ' echo ' -------------------------------------------------------------------------------- ' echo ' ----- --without-gui --- ' echo ' -------------------------------------------------------------------------------- ' ./configure --quiet LDFLAGS="-L/usr/X11R6/lib" CFLAGS="-Wall -I/usr/X11R6/include -DWITH_MAIN" --without-gui make echo ' ' echo ' ' ./snd --version ./snd -noinit --features "'clm 'snd-nogui" make allclean rm -f snd rm -f config.cache echo ' ' echo ' ' echo ' -------------------------------------------------------------------------------- ' echo ' ----- --without-audio ---- ' echo ' -------------------------------------------------------------------------------- ' ./configure --quiet LDFLAGS="-L/usr/X11R6/lib" CFLAGS="-Wall -I/usr/X11R6/include" --without-audio make echo ' ' echo ' ' ./snd --version ./snd -noinit --features "'clm" make allclean rm -f snd rm -f config.cache echo ' ' echo ' ' echo ' -------------------------------------------------------------------------------- ' echo ' ----- --without-audio C++ ---- ' echo ' -------------------------------------------------------------------------------- ' ./configure --quiet LDFLAGS="-L/usr/X11R6/lib" CFLAGS="-Wall -I/usr/X11R6/include" --without-audio CC=g++ make echo ' ' echo ' ' ./snd --version ./snd -noinit --features "'clm" make allclean rm -f snd rm -f config.cache echo ' ' echo ' ' echo ' -------------------------------------------------------------------------------- ' echo ' ----- --without-gui --with-oss ---- ' echo ' -------------------------------------------------------------------------------- ' ./configure --quiet LDFLAGS="-L/usr/X11R6/lib" CFLAGS="-Wall -I/usr/X11R6/include" --without-gui --with-oss make echo ' ' echo ' ' ./snd --version ./snd -noinit --features "'clm 'snd-nogui 'oss" make allclean rm -f snd rm -f config.cache echo ' -------------------------------------------------------------------------------- ' echo ' ----- --without-gui --with-gmp ---- ' echo ' -------------------------------------------------------------------------------- ' ./configure --quiet --without-gui --with-gmp --with-ladspa CFLAGS="-Wall -I/usr/local/include" make echo ' ' echo ' ' ./snd --version ./snd -noinit --features "'clm 'snd-nogui 'gmp" make allclean rm -f snd rm -f config.cache echo ' ' echo ' ' echo ' -------------------------------------------------------------------------------- ' echo ' ---- -without-gui --with-ladspa ---- ' echo ' -------------------------------------------------------------------------------- ' ./configure --quiet LDFLAGS="-L/usr/X11R6/lib" CFLAGS="-Wall -I/usr/X11R6/include -I/usr/local/include" --without-gui --with-ladspa make echo ' ' echo ' ' ./snd --version ./snd -noinit --features "'clm 'snd-nogui 'snd-s7" make allclean rm -f snd rm -f config.cache echo ' ' echo ' ' echo ' -------------------------------------------------------------------------------- ' echo ' ---- --with-gtk ---- ' echo ' -------------------------------------------------------------------------------- ' ./configure --quiet LDFLAGS="-L/usr/X11R6/lib" CFLAGS="-O3 -Wall -I/usr/X11R6/include" --with-gtk make echo ' ' echo ' ' ./snd --version /home/bil/cl/snd tools/va.scm ./snd -noinit --features "'clm 'snd-gtk 'snd-s7" make allclean rm -f snd rm -f config.cache echo ' ' echo ' ' echo ' -------------------------------------------------------------------------------- ' echo ' ---- g++ --with-gtk --disable-deprecated ---- ' echo ' -------------------------------------------------------------------------------- ' ./configure --quiet CC=g++ CFLAGS="-Wall -I/usr/X11R6/include" --with-gtk --disable-deprecated make allclean make ./snd --version ./snd -noinit --features "'clm 'snd-gtk 'snd-s7" make allclean echo ' ' echo ' ' echo ' -------------------------------------------------------------------------------- ' echo ' ----- g++ --with-gtk --std=c++11 --- ' echo ' -------------------------------------------------------------------------------- ' ./configure --quiet CC=g++ --with-gtk CFLAGS="-std=c++11 -Wall -I/usr/X11R6/include" make ./snd --version ./snd -noinit --features "'clm 'snd-gtk" make allclean echo ' ' echo ' ' echo ' -------------------------------------------------------------------------------- ' echo ' ----- g++ --with-gtk --with-gsl --- ' echo ' -------------------------------------------------------------------------------- ' ./configure --quiet CC=g++ --with-gtk --with-gsl CFLAGS="-Wall -I/usr/X11R6/include" make ./snd --version ./snd -noinit --features "'clm 'snd-gtk 'gsl" make allclean echo ' ' echo ' ' echo ' -------------------------------------------------------------------------------- ' echo ' ----- --with-forth ---- ' echo ' -------------------------------------------------------------------------------- ' ./configure LDFLAGS="-L/usr/X11R6/lib" CFLAGS="-Wall -I/usr/X11R6/include" --quiet --with-motif --with-forth make ./snd --version ./snd -noinit --features "'clm 'snd-forth 'snd-motif" make allclean echo ' ' echo ' ' echo ' -------------------------------------------------------------------------------- ' echo ' ----- --with-forth --with-motif --with-editres --with-gl ---- ' echo ' -------------------------------------------------------------------------------- ' ./configure --quiet --with-forth --with-motif --with-editres --with-gl LDFLAGS="-L/usr/X11R6/lib" CFLAGS="-Wall -I/usr/X11R6/include" make ./snd --version ./snd -noinit --features "'clm 'snd-forth 'xm 'gl" make allclean echo ' ' echo ' ' echo ' -------------------------------------------------------------------------------- ' echo ' ----- --with-forth --with-gtk --- ' echo ' -------------------------------------------------------------------------------- ' ./configure --quiet --with-forth --with-gtk LDFLAGS="-L/usr/X11R6/lib" CFLAGS="-Wall -I/usr/X11R6/include" make ./snd --version ./snd -noinit --features "'clm 'snd-gtk 'xg 'gl" make allclean echo ' ' echo ' ' echo ' -------------------------------------------------------------------------------- ' echo ' ----- --with-forth --without-gui --- ' echo ' -------------------------------------------------------------------------------- ' ./configure --quiet --with-forth --without-gui LDFLAGS="-L/usr/X11R6/lib" CFLAGS="-Wall -I/usr/X11R6/include" make ./snd --version ./snd -noinit --features "'clm 'snd-forth 'snd-nogui" make allclean echo ' ' echo ' ' echo ' -------------------------------------------------------------------------------- ' echo ' ---- --without-extension-language ---- ' echo ' -------------------------------------------------------------------------------- ' ./configure LDFLAGS="-L/usr/X11R6/lib" CFLAGS="-I/usr/X11R6/include" --quiet --without-extension-language make echo ' ' echo ' ' ./snd --version make allclean echo ' -------------------------------------------------------------------------------- ' echo ' ----- --without-extension-language --with-gtk ---- ' echo ' -------------------------------------------------------------------------------- ' ./configure --quiet --without-extension-language --with-gtk make echo ' ' echo ' ' ./snd --version rm -f sndinfo make sndinfo ./sndinfo test.snd make allclean echo ' -------------------------------------------------------------------------------- ' echo ' ---- --without-extension-language --with-gl ------ ' echo ' -------------------------------------------------------------------------------- ' ./configure LDFLAGS="-L/usr/X11R6/lib" CFLAGS="-I/usr/X11R6/include" --quiet --without-extension-language --with-motif --with-gl make echo ' ' echo ' ' ./snd --version make allclean echo ' -------------------------------------------------------------------------------- ' echo ' ----- --without-extension-language g++ ---- ' echo ' -------------------------------------------------------------------------------- ' ./configure --quiet --without-extension-language CC=g++ LDFLAGS="-L/usr/X11R6/lib" CFLAGS="-I/usr/X11R6/include" make echo ' ' echo ' ' ./snd --version make allclean rm -f snd rm -f config.cache echo ' -------------------------------------------------------------------------------- ' echo ' ---- --with-gtk ---- ' echo ' -------------------------------------------------------------------------------- ' ./configure --quiet LDFLAGS="-L/usr/X11R6/lib" CFLAGS="-Wall -I/usr/X11R6/include" --with-gtk make echo ' ' echo ' ' ./snd --version ./snd -noinit --features "'clm 'snd-gtk" make allclean rm -f snd rm -f config.cache echo ' -------------------------------------------------------------------------------- ' echo ' ----- GTK_DISABLE_DEPRECATED G_DISABLE_DEPRECATED GDK_DISABLE_DEPRECATED --with-gtk ' echo ' -------------------------------------------------------------------------------- ' ./configure --quiet --disable-deprecated CFLAGS="-Wall -I/usr/X11R6/include -D_FORTIFY_SOURCE=2" --with-gtk make echo ' ' echo ' ' ./snd --version ./snd -noinit --features "'clm 'snd-gtk 'xg" make allclean rm -f snd rm -f sndinfo rm -f config.cache echo ' -------------------------------------------------------------------------------- ' echo ' ---- --with-gsl ---- ' echo ' -------------------------------------------------------------------------------- ' ./configure --quiet LDFLAGS="-L/usr/X11R6/lib" CFLAGS="-Wall -I/usr/X11R6/include -DDEBUGGING" --with-motif --with-gsl make echo ' ' echo ' ' ./snd --version ./snd -noinit --features "'clm 'gsl 'snd-motif" make allclean echo ' -------------------------------------------------------------------------------- ' echo ' ---- --with-gmp ---- ' echo ' -------------------------------------------------------------------------------- ' ./configure --quiet LDFLAGS="-L/usr/X11R6/lib" CFLAGS="-Wall -I/usr/X11R6/include" --with-gmp make echo ' ' echo ' ' ./snd --version ./snd -noinit --features "'clm 'snd-motif 'gmp" make allclean echo ' -------------------------------------------------------------------------------- ' echo ' ---- WITH_PURE_S7 --- ' echo ' -------------------------------------------------------------------------------- ' ./configure --quiet LDFLAGS="-L/usr/X11R6/lib" CFLAGS="-Wall -I/usr/X11R6/include -DWITH_PURE_S7=1" make echo ' ' echo ' ' ./snd --version ./snd -noinit --features "'clm 'snd-motif" make allclean echo ' -------------------------------------------------------------------------------- ' echo ' ----- editres ---- ' echo ' -------------------------------------------------------------------------------- ' ./configure --quiet LDFLAGS="-L/usr/X11R6/lib" CFLAGS="-Wall -I/usr/X11R6/include" --with-motif --with-editres --disable-deprecated make make allclean echo ' ' echo ' ' echo ' -------------------------------------------------------------------------------- ' echo ' ----- g++ ---- ' echo ' -------------------------------------------------------------------------------- ' ./configure --with-motif LDFLAGS="-L/usr/X11R6/lib" --quiet CC=g++ CFLAGS="-Wall -I/usr/X11R6/include" make make allclean rm -f snd rm -f config.cache echo ' -------------------------------------------------------------------------------- ' echo ' ---- --with-gtk --with-gmp ---- ' echo ' -------------------------------------------------------------------------------- ' ./configure --quiet --with-gtk --with-gmp CFLAGS="-Wall" make echo ' ' echo ' ' ./snd --version ./snd -noinit --features "'clm 'snd-gtk 'gmp" echo ' ' echo ' ' make allclean rm -f snd rm -f config.cache echo ' -------------------------------------------------------------------------------- ' echo ' ----- --with-ruby ---- ' echo ' -------------------------------------------------------------------------------- ' ./configure --quiet LDFLAGS="-L/usr/X11R6/lib" CFLAGS="-Wall -I/usr/X11R6/include" --with-ruby --with-motif make echo ' ' echo ' ' ./snd --version ./snd -noinit --features ":clm, :snd_ruby, :snd_motif" make allclean echo ' -------------------------------------------------------------------------------- ' echo ' ---- g++ --with-ruby ---- ' echo ' -------------------------------------------------------------------------------- ' ./configure --quiet CC=g++ LDFLAGS="-L/usr/X11R6/lib" CFLAGS="-Wall -I/usr/X11R6/include" --with-ruby make ./snd --version ./snd -noinit --features ":clm, :snd_ruby" make allclean echo ' -------------------------------------------------------------------------------- ' echo ' ----- --with-ruby --with-gl --with-alsa ' echo ' -------------------------------------------------------------------------------- ' ./configure --quiet LDFLAGS="-L/usr/X11R6/lib" CFLAGS="-Wall -I/usr/X11R6/include -DDEBUGGING" --with-ruby --with-motif --with-gl --with-alsa make echo ' ' echo ' ' ./snd --version ./snd -noinit --features ":clm, :alsa, :snd_ruby, :gl" make allclean rm -f snd rm -f config.cache echo ' -------------------------------------------------------------------------------- ' echo ' ---- --with-ruby --with-gtk ---- ' echo ' -------------------------------------------------------------------------------- ' ./configure --quiet LDFLAGS="-L/usr/X11R6/lib" CFLAGS="-Wall -I/usr/X11R6/include" --with-ruby --with-gtk make echo ' ' echo ' ' ./snd --version ./snd -noinit --features ":clm, :snd_gtk, :snd_ruby" make allclean echo ' -------------------------------------------------------------------------------- ' echo ' ----- g++ --with-ruby --with-gtk --with-alsa ---- ' echo ' -------------------------------------------------------------------------------- ' ./configure --quiet CC=g++ --with-ruby --with-gtk --with-alsa make echo ' ' echo ' ' ./snd --version ./snd -noinit --features ":clm, :alsa, :snd_gtk, :snd_ruby" make allclean echo ' -------------------------------------------------------------------------------- ' echo ' ---- --with-ruby --with-gtk --without-gsl ' echo ' -------------------------------------------------------------------------------- ' ./configure --quiet LDFLAGS="-L/usr/X11R6/lib" CFLAGS="-Wall -I/usr/X11R6/include -DDEBUGGING" --with-ruby --with-gtk --without-gsl make echo ' ' echo ' ' ./snd --version ./snd -noinit --features ":clm, :snd_ruby, :snd_gtk" make allclean echo ' -------------------------------------------------------------------------------- ' echo ' ---- GTK_DISABLE_DEPRECATED G_DISABLE_DEPRECATED GDK_DISABLE_DEPRECATED --with-ruby --with-gtk ' echo ' -------------------------------------------------------------------------------- ' ./configure --quiet --disable-deprecated LDFLAGS="-L/usr/X11R6/lib" CFLAGS="-Wall -I/usr/X11R6/include -D_FORTIFY_SOURCE=2" --with-ruby --with-gtk make echo ' ' echo ' ' ./snd --version ./snd -noinit --features ":clm, :snd-gtk, :xg" make allclean rm -f snd rm -f config.cache echo ' -------------------------------------------------------------------------------- ' echo ' ---- --with-ruby --without-gui --without-fftw --- ' echo ' -------------------------------------------------------------------------------- ' ./configure --quiet LDFLAGS="-L/usr/X11R6/lib" CFLAGS="-Wall -I/usr/X11R6/include" --with-ruby --without-gui --without-fftw make echo ' ' echo ' ' ./snd --version ./snd -noinit --features ":clm, :snd_nogui, :snd_ruby" make allclean echo ' -------------------------------------------------------------------------------- ' echo ' ----- --with-ruby --without-gui ----- ' echo ' -------------------------------------------------------------------------------- ' ./configure --quiet LDFLAGS="-L/usr/X11R6/lib" CFLAGS="-Wall -I/usr/X11R6/include -DDEBUGGING" --with-ruby --without-gui make echo ' ' echo ' ' ./snd --version ./snd -noinit --features ":clm, :snd_nogui, :snd_ruby" make allclean echo ' -------------------------------------------------------------------------------- ' echo ' ---- g++ --with-ruby --without-gui ---- ' echo ' -------------------------------------------------------------------------------- ' ./configure --quiet CC=g++ LDFLAGS="-L/usr/X11R6/lib" CFLAGS="-Wall -I/usr/X11R6/include -DDEBUGGING" --with-ruby --without-gui make echo ' ' echo ' ' ./snd --version ./snd -noinit --features ":clm, :snd_nogui, :snd_ruby" make allclean rm -f snd rm -f config.cache echo ' -------------------------------------------------------------------------------- ' echo ' ---- g++ --- ' echo ' -------------------------------------------------------------------------------- ' ./configure --quiet --with-motif --with-ladspa CC=g++ LDFLAGS="-L/usr/X11R6/lib" CFLAGS="-Wall -I/usr/X11R6/include -I/usr/local/include" make ./snd --version ./snd -noinit --features "'clm 'snd-s7 'snd-motif 'snd-ladspa 'sndlib" make sndinfo make sndplay ./sndinfo test.snd make allclean echo ' ' echo ' ' echo ' -------------------------------------------------------------------------------- ' echo ' ---- g++ --with-gtk ---- ' echo ' -------------------------------------------------------------------------------- ' ./configure --quiet CC=g++ --with-gtk CFLAGS="-Wall" make ./snd --version ./snd -noinit --features "'clm 'snd-gtk" make allclean echo ' ' echo ' ' echo ' -------------------------------------------------------------------------------- ' echo ' ---- g++ --without-gui ---- ' echo ' -------------------------------------------------------------------------------- ' ./configure LDFLAGS="-L/usr/X11R6/lib" CFLAGS="-Wall -I/usr/X11R6/include" --quiet CC=g++ --without-gui make ./snd --version ./snd -noinit --features "'clm 'snd-nogui 'snd-s7" make allclean echo ' -------------------------------------------------------------------------------- ' echo ' ----- g++ --without-extension-language ---- ' echo ' -------------------------------------------------------------------------------- ' ./configure LDFLAGS="-L/usr/X11R6/lib" CFLAGS="-I/usr/X11R6/include" --quiet CC=g++ --without-extension-language make ./snd --version make allclean echo ' ' echo ' ' echo ' -------------------------------------------------------------------------------- ' echo ' ----- g++ --without-gsl --with-alsa ' echo ' -------------------------------------------------------------------------------- ' ./configure LDFLAGS="-L/usr/X11R6/lib" CFLAGS="-Wall -I/usr/X11R6/include" --quiet CC=g++ --without-gsl --with-alsa make ./snd --version ./snd -noinit --features "'clm 'alsa 'xm" make allclean echo ' ' echo ' ' make allclean rm -f snd rm -f config.cache rm -f sndinfo echo ' -------------------------------------------------------------------------------- ' echo ' ----- sndlib ---- ' echo ' -------------------------------------------------------------------------------- ' ./configure --quiet LDFLAGS="-L/usr/X11R6/lib" CFLAGS="-Wall -I/usr/X11R6/include" make sndinfo sndinfo oboe.snd sndinfo test.snd make allclean echo ' ' echo ' ' echo ' -------------------------------------------------------------------------------- ' echo ' ---- --without-gui ---- ' echo ' -------------------------------------------------------------------------------- ' ./configure --quiet LDFLAGS="-L/usr/X11R6/lib" CFLAGS="-Wall -I/usr/X11R6/include" --without-gui make echo ' ' echo ' ' ./snd --version ./snd -noinit --features "'clm 'snd-nogui 'snd-s7" make allclean rm -f snd rm -f config.cache rm -f makefile rm -f mus-config.h echo ' ' echo ' ' echo ' -------------------------------------------------------------------------------- ' echo ' ----- -DXM_DISABLE_DEPRECATED ----- ' echo ' -------------------------------------------------------------------------------- ' ./configure --quiet LDFLAGS="-L/usr/X11R6/lib" CFLAGS="-Wall -DXM_DISABLE_DEPRECATED -Wall -I/usr/X11R6/include" make ./snd --version ./snd -noinit --features "'clm 'xm" make allclean echo ' ' echo ' ' echo ' -------------------------------------------------------------------------------- ' echo ' ----- --with-ruby -DXM_DISABLE_DEPRECATED ---- ' echo ' -------------------------------------------------------------------------------- ' ./configure --quiet --with-ruby LDFLAGS="-L/usr/X11R6/lib" CFLAGS="-Wall -DXM_DISABLE_DEPRECATED -Wall -I/usr/X11R6/include" make ./snd --version ./snd -noinit --features ":clm, :snd_ruby" make allclean echo ' ' echo ' ' echo ' -------------------------------------------------------------------------------- ' echo ' ----- --without-gui --without-extension-language ----- ' echo ' -------------------------------------------------------------------------------- ' ./configure LDFLAGS="-L/usr/X11R6/lib" CFLAGS="-I/usr/X11R6/include" --without-gui --without-extension-language --quiet make ./snd --version make allclean echo ' ' echo ' ' echo ' -------------------------------------------------------------------------------- ' echo ' ---- --without-extension-language --with-gl ' echo ' -------------------------------------------------------------------------------- ' ./configure LDFLAGS="-L/usr/X11R6/lib" CFLAGS="-I/usr/X11R6/include" --without-extension-language --with-motif --with-gl --quiet make ./snd --version make allclean echo ' ' echo ' ' echo ' -------------------------------------------------------------------------------- ' echo ' ----- --with-gl --with-gl2ps ------ ' echo ' -------------------------------------------------------------------------------- ' ./configure LDFLAGS="-L/usr/X11R6/lib" CFLAGS="-Wall -I/usr/X11R6/include" --with-motif --with-gl --quiet --with-gl2ps make ./snd --version ./snd -noinit --features "'clm 'xm 'gl2ps" make allclean echo ' ' echo ' ' echo ' -------------------------------------------------------------------------------- ' echo ' ----- --without-extension-language --with-gtk ---- ' echo ' -------------------------------------------------------------------------------- ' ./configure --without-extension-language --with-gtk --quiet make ./snd --version make allclean echo ' ' echo ' ' echo ' -------------------------------------------------------------------------------- ' echo ' ---- --with-portaudio ---- ' echo ' -------------------------------------------------------------------------------- ' ./configure --with-portaudio --quiet make ./snd --version ./snd -noinit --features "'clm 'snd-gtk" make allclean echo ' -------------------------------------------------------------------------------- ' echo ' ---- --with-jack ---- ' echo ' -------------------------------------------------------------------------------- ' ./configure --with-jack --with-alsa --quiet make ./snd --version ./snd -noinit --features "'clm 'snd-gtk" make allclean echo ' -------------------------------------------------------------------------------- ' echo ' ---- --with-pulseaudio ---- ' echo ' -------------------------------------------------------------------------------- ' ./configure --with-pulseaudio --quiet make ./snd --version ./snd -noinit --features "'clm 'snd-gtk" make allclean cp ~/sndlib/* . echo ' -------------------------------------------------------------------------------- ' echo ' ----- sndlib tests ---- ' echo ' -------------------------------------------------------------------------------- ' ./configure --quiet CFLAGS="-Wall" make cp tools/exs7.c . echo ' -------------------------------------------------------------------------------- ' echo ' -------------------------------- ex 1 -------------------------------- ' echo ' -------------------------------------------------------------------------------- ' gcc -o exs7 exs7.c s7.o -lm -DEX1 -ldl echo ' -------------------------------------------------------------------------------- ' echo ' -------------------------------- ex 2 -------------------------------- ' echo ' -------------------------------------------------------------------------------- ' gcc -o exs7 exs7.c s7.o -lm -DEX2 -ldl echo ' -------------------------------------------------------------------------------- ' echo ' -------------------------------- ex 3 -------------------------------- ' echo ' -------------------------------------------------------------------------------- ' gcc -o exs7 exs7.c s7.o -lm -DEX3 -ldl echo ' -------------------------------------------------------------------------------- ' echo ' -------------------------------- ex 4 -------------------------------- ' echo ' -------------------------------------------------------------------------------- ' gcc -o exs7 exs7.c s7.o -lm -DEX4 -ldl echo ' -------------------------------------------------------------------------------- ' echo ' -------------------------------- ex 5 -------------------------------- ' echo ' -------------------------------------------------------------------------------- ' gcc -o exs7 exs7.c s7.o -lm -DEX5 -ldl echo ' -------------------------------------------------------------------------------- ' echo ' -------------------------------- ex 6 -------------------------------- ' echo ' -------------------------------------------------------------------------------- ' gcc -o exs7 exs7.c s7.o -lm -DEX6 -ldl # make clean # echo ' -------------------------------------------------------------------------------- ' # echo ' -------------------------------- sndlib ruby -------------------------------- ' # echo ' -------------------------------------------------------------------------------- ' # ./configure --quiet --with-ruby # make make clean echo ' -------------------------------------------------------------------------------- ' echo ' -------------------------------- sndlib forth -------------------------------- ' echo ' -------------------------------------------------------------------------------- ' ./configure --quiet --with-forth make make clean echo ' -------------------------------------------------------------------------------- ' echo ' -------------------------------- sndlib s7 c++ -------------------------------- ' echo ' -------------------------------------------------------------------------------- ' ./configure --quiet CC=g++ make echo ' -------------------------------------------------------------------------------- ' echo ' -------------------------------- ex 1 -------------------------------- ' echo ' -------------------------------------------------------------------------------- ' g++ -o exs7 exs7.c s7.o -lm -DEX1 -ldl echo ' -------------------------------------------------------------------------------- ' echo ' -------------------------------- ex 2 -------------------------------- ' echo ' -------------------------------------------------------------------------------- ' g++ -o exs7 exs7.c s7.o -lm -DEX2 -ldl echo ' -------------------------------------------------------------------------------- ' echo ' -------------------------------- ex 3 -------------------------------- ' echo ' -------------------------------------------------------------------------------- ' g++ -o exs7 exs7.c s7.o -lm -DEX3 -ldl echo ' -------------------------------------------------------------------------------- ' echo ' -------------------------------- ex 4 -------------------------------- ' echo ' -------------------------------------------------------------------------------- ' g++ -o exs7 exs7.c s7.o -lm -DEX4 -ldl /home/bil/test/sndlib/libsndlib.a -lgsl -lgslcblas -lasound echo ' -------------------------------------------------------------------------------- ' echo ' -------------------------------- ex 5 -------------------------------- ' echo ' -------------------------------------------------------------------------------- ' g++ -o exs7 exs7.c s7.o -lm -DEX5 -ldl echo ' -------------------------------------------------------------------------------- ' echo ' -------------------------------- ex 6 -------------------------------- ' echo ' -------------------------------------------------------------------------------- ' g++ -o exs7 exs7.c s7.o -lm -DEX6 -ldl rm exs7 rm exs7.o make clean snd-16.1/tools/thash.scm0000644000076400007640000001217612615151312013312 0ustar bilbil;(set! (*s7* 'gc-stats) 6) ;heap ca 30*size! (define-constant symbols (make-vector 1000000)) (define-constant strings (make-vector 1000000)) (define (test-hash size) (format *stderr* "~D " size) (let ((int-hash (make-hash-table size)) (p (cons #f #f))) (do ((i 0 (+ i 1))) ((= i size)) (hash-table-set! int-hash i i)) (do ((i 0 (+ i 1))) ((= i size)) (if (not (= (hash-table-ref int-hash i) i)) (display "oops"))) (for-each (lambda (key&value) (if (not (= (car key&value) (cdr key&value))) (display "oops"))) ;(format *stderr* "hash iter ~A~%" key&value))) (make-iterator int-hash p)) (fill! int-hash #f)) (let ((int-hash (make-hash-table size =))) (do ((i 0 (+ i 1))) ((= i size)) (hash-table-set! int-hash i i)) (do ((i 0 (+ i 1))) ((= i size)) (if (not (= (hash-table-ref int-hash i) i)) (display "oops"))) (fill! int-hash #f)) (let ((flt-hash (make-hash-table size))) (do ((i 0 (+ i 1))) ((= i size)) (hash-table-set! flt-hash (* i 2.0) i)) (do ((i 0 (+ i 1))) ((= i size)) (if (not (= (hash-table-ref flt-hash (* 2.0 i)) i)) (display "oops"))) (fill! flt-hash #f)) (let ((sym-hash (make-hash-table size))) (do ((i 0 (+ i 1))) ((= i size)) (hash-table-set! sym-hash (vector-set! symbols i (string->symbol (vector-set! strings i (number->string i)))) i)) (do ((i 0 (+ i 1))) ((= i size)) (if (not (= (hash-table-ref sym-hash (vector-ref symbols i)) i)) (display "oops"))) (fill! sym-hash #f)) (let ((str-hash (make-hash-table size eq?))) (do ((i 0 (+ i 1))) ((= i size)) (hash-table-set! str-hash (vector-ref strings i) i)) (do ((i 0 (+ i 1))) ((= i size)) (if (not (= (hash-table-ref str-hash (vector-ref strings i)) i)) (display "oops"))) (fill! str-hash #f)) (let ((sym-hash (make-hash-table size eq?))) (do ((i 0 (+ i 1))) ((= i size)) (hash-table-set! sym-hash (vector-ref symbols i) i)) (do ((i 0 (+ i 1))) ((= i size)) (if (not (= (hash-table-ref sym-hash (vector-ref symbols i)) i)) (display "oops"))) (fill! sym-hash #f)) (let ((chr-hash (make-hash-table 256))) (do ((i 0 (+ i 1))) ((= i 256)) (hash-table-set! chr-hash (integer->char i) i)) (do ((i 0 (+ i 1))) ((= i 256)) (if (not (= (hash-table-ref chr-hash (integer->char i)) i)) (display "oops"))) (fill! chr-hash #f)) (let ((any-hash (make-hash-table size eq?))) (if (= size 1) (hash-table-set! any-hash (vector-set! strings 0 (list 0)) 0) (do ((i 0 (+ i 2)) (j 1 (+ j 2))) ((= i size)) (hash-table-set! any-hash (vector-set! strings i (list i)) i) (hash-table-set! any-hash (vector-set! strings j (int-vector j)) j))) (do ((i 0 (+ i 1))) ((= i size)) (if (not (= i (hash-table-ref any-hash (vector-ref strings i)))) (display "oops"))) (fill! any-hash #f)) (let ((any-hash1 (make-hash-table size eq?))) (if (= size 1) (hash-table-set! any-hash1 (vector-set! strings 0 (inlet :a 0)) 0) (do ((i 0 (+ i 2)) (j 1 (+ j 2)) (x 0.0 (+ x 2.0))) ((= i size)) (hash-table-set! any-hash1 (vector-set! strings i (inlet :a i)) i) (hash-table-set! any-hash1 (vector-set! strings j (float-vector x)) j))) (do ((i 0 (+ i 1))) ((= i size)) (if (not (= i (hash-table-ref any-hash1 (vector-ref strings i)))) (display "oops"))) (vector-fill! strings #f) (fill! any-hash1 #f)) (let ((cmp-hash (make-hash-table size))) (do ((i 0 (+ i 1))) ((= i size)) (hash-table-set! cmp-hash (complex i i) i)) (do ((i 0 (+ i 1))) ((= i size)) (if (not (= (hash-table-ref cmp-hash (complex i i)) i)) (display "oops"))) (fill! cmp-hash #f)) ) (for-each test-hash (list 1 10 100 1000 10000 100000 1000000)) ;;; ---------------------------------------- (format *stderr* "reader~%") (define data "/home/bil/test/bench/src/bib") (define counts (make-hash-table (expt 2 18) string=?)) (define (reader) (let ((port (open-input-file data)) (new-pos 0)) (do ((line (read-line port) (read-line port))) ((eof-object? line)) (set! new-pos 0) (do ((pos (char-position #\space line) (char-position #\space line (+ pos 1)))) ((not pos)) (unless (= pos new-pos) (let* ((start (do ((k new-pos (+ k 1))) ; char-position here is slower! ((or (= k pos) (char-alphabetic? (string-ref line k))) k))) (end (do ((k (- pos 1) (- k 1))) ((or (= k start) (char-alphabetic? (string-ref line k))) (+ k 1))))) (when (> end start) (let ((word (substring line start end))) (let ((refs (or (hash-table-ref counts word) 0))) (hash-table-set! counts word (+ refs 1))))))) (set! new-pos (+ pos 1)))) (close-input-port port) (sort! (copy counts (make-vector (hash-table-entries counts))) (lambda (a b) (> (cdr a) (cdr b)))))) (set! counts (reader)) (if (or (not (string=? (car (counts 0)) "the")) (not (= (cdr (counts 0)) 62063))) (do ((i 0 (+ i 1))) ((= i 40)) (format *stderr* "~A: ~A~%" (car (counts i)) (cdr (counts i))))) ;;; ---------------------------------------- ;(gc) (s7-version) (exit) snd-16.1/tools/va.scm0000755000076400007640000001561012515276602012621 0ustar bilbil;;; various lint-like checks (define (find-if pred l) (cond ((null? l) #f) ((pred (car l)) (car l)) (else (find-if pred (cdr l))))) (define (va) (for-each (lambda (func) (system (format #f "fgrep ~A *.c > vahi" func)) (call-with-input-file "vahi" (lambda (file) (let loop ((line (read-line file #t))) (or (eof-object? line) (let ((len (length line)) (precount 0) (ok #f) (count 0) (flen (length func))) ;; look for * miscounts (call-with-exit (lambda (return) (do ((i 0 (+ i 1))) ((= i len)) (case (string-ref line i) ((#\*) (set! count (+ 1 count))) ((#\=) (set! count 0)) (else (if (and (< i (- len 2)) (string=? (substring line i (+ i 2)) "/*")) (return #f) (if (and (< i (- len flen)) (string=? (substring line i (+ i flen)) func)) (begin (set! precount count) (set! count 0)) (if (and (< i (- len 6)) (string=? (substring line i (+ i 6)) "sizeof")) (begin (set! ok #t) (set! count 0)))))))))) (if (and ok (not (= precount count 0)) (not (= count (- precount 1)))) (format #t "calloc ~D->~D: ~A~%" precount count line)) (loop (read-line file #t)))))))) (list "calloc" "malloc" "realloc")) (load "lint.scm") (for-each (lambda (filename) (if (and (provided? 'gtk3) (provided? 'xg)) (call-with-input-file filename (lambda (file) (let ((line-number 0)) (let loop ((line (read-line file #t))) (or (eof-object? line) (let ((len (length line))) (set! line-number (+ line-number 1)) (if (> len 8) (let ((start 0)) (do ((i 1 (+ i 1))) ((>= i len)) (let ((chr (line i))) (if (or (char-whitespace? chr) (char=? chr #\))) (let* ((name (substring line (+ 1 start) i)) (name-len (length name))) (if (and (or (and (> name-len 4) (or (string-ci=? "gtk_" (substring name 0 4)) (string-ci=? "gdk_" (substring name 0 4)))) (and (> name-len 6) (or (string-ci=? "pango_" (substring name 0 6)) (string-ci=? "cairo_" (substring name 0 6))))) (not (defined? (string->symbol name) *gtk*))) (format #t "~A (~A[~D]) is not defined~%" name filename line-number)))) (if (and (not (char=? chr #\_)) (not (char-alphabetic? chr)) (not (char-numeric? chr))) (set! start i)))))) (loop (read-line file #t))))))))) ; (if (string=? (substring filename (- (length filename) 3)) "scm") ; (lint filename)) ) (list "analog-filter.scm" "animals.scm" "autosave.scm" "bess.scm" "bess1.scm" "big-gens.scm" "binary-io.scm" "bird.scm" "clean.scm" "clm-ins.scm" "clm23.scm" "dlocsig.scm" "draw.scm" "dsp.scm" "edit-menu.scm" "edit123.scm" "effects-utils.scm" "env.scm" "enved.scm" "examp.scm" "expandn.scm" "extensions.scm" "fade.scm" "fft-menu.scm" "fmv.scm" ; "frame.scm" "freeverb.scm" "fullmix.scm" "generators.scm" "grani.scm" "gtk-effects-utils.scm" "gtk-effects.scm" "hooks.scm" "index.scm" "jcrev.scm" "jcvoi.scm" "lint.scm" "maraca.scm" "marks-menu.scm" "marks.scm" "maxf.scm" "misc.scm" "mix.scm" ; "mixer.scm" "moog.scm" "musglyphs.scm" "nb.scm" "new-backgrounds.scm" "new-effects.scm" "noise.scm" "nrev.scm" "numerics.scm" "peak-phases.scm" "piano.scm" "play.scm" "poly.scm" "prc95.scm" "primes.scm" "pvoc.scm" "rgb.scm" ; "rtio.scm" "rubber.scm" "s7-slib-init.scm" "s7test.scm" "selection.scm" "singer.scm" "snd-gl.scm" "snd-gtk.scm" "snd-motif.scm" "snd-test.scm" ; "snd11.scm" ; "snd12.scm" "snddiff.scm" "sndlib-ws.scm" "sndwarp.scm" "special-menu.scm" "spectr.scm" "spokenword.scm" "stochastic.scm" "strad.scm" "v.scm" "write.scm" "ws.scm" "xm-enved.scm" "zip.scm" "snd.html" "sndscm.html" "grfsnd.html" "extsnd.html" "sndclm.html" "fm.html" "s7.html" "sndlib.html" ))) (va) #| (for-each (lambda (filename) (call-with-input-file filename (lambda (file) (let ((line-number 0) (last-name "")) (let loop ((line (read-line file #t))) (or (eof-object? line) (let ((len (length line))) (set! line-number (+ line-number 1)) (if (> len 0) (let ((start #f)) (do ((i 0 (+ i 1))) ((>= i len)) (let ((chr (line i))) (if (not (char-whitespace? chr)) (if (not start) (set! start i)) (if start (let* ((name (substring line start i)) (name-len (length name))) ;(format #t "~C: ~A~%" chr name) (if (and (> name-len 0) (char-alphabetic? (name 0)) (string=? name last-name)) (format #t ";~A[~D]: ~A repeats in ~A~%" filename line-number name line)) (set! last-name name) (set! start #f)))))))) (loop (read-line file #t))))))))) (list "snd.html" "sndscm.html" "grfsnd.html" "extsnd.html" "sndclm.html" "fm.html" "s7.html" "sndlib.html" )) |# #| (format #t "--------------------------------------------------------------------------------~%") (let ((png-files (directory->list "/home/bil/cl/pix")) (baddies ())) (for-each (lambda (file) (if (and (not (directory? file)) (not (zero? (system (format #f "fgrep ~A *.html" file))))) (set! baddies (cons file baddies)))) png-files) (if (not (null? baddies)) (begin (format #t "--------------------------------------------------------------------------------~%") (format #t ";unused pix/png: ~{~A ~}~%" baddies) (format #t "--------------------------------------------------------------------------------~%")))) |# #| ;;; check for incorrect port_write_string lengths -- is confused by \" (call-with-input-file "s7.c" (lambda (file) (let ((count 0)) (let loop ((line (read-line file #t))) (or (eof-object? line) (let ((pos (string-position "port_write_string(" line))) (set! count (+ count 1)) (if pos (let ((qpos (char-position #\" (substring line (+ pos 1))))) (if qpos (let ((npos (char-position #\, (substring line (+ pos qpos 2))))) (if npos (let ((len (- npos 1)) (new-line (substring line (+ pos qpos 2 npos)))) (let ((ccpos (char-position #\, (substring new-line 1)))) (if ccpos (let ((clen (string->number (substring new-line 2 (+ ccpos 1))))) (if (and clen (not (= clen len))) (format *stderr* "[~D]: ~A: length ~A ~A~%" count (substring line (char-position #\p line) (char-position #\; line)) len clen))))))))))) (loop (read-line file #t)))))))) |# (exit) snd-16.1/tools/tgen.scm0000644000076400007640000006304412611552663013152 0ustar bilbil(if (and (not (provided? 'snd)) (not (provided? 'sndlib))) (begin (format *stderr* "tgen depends on sndlib...~%") (system "./snd -noinit tgen.scm") (exit))) (if (provided? 'snd) (begin (load "ws.scm") (load "hooks.scm") (reset-all-hooks) (set! (auto-update) #f) (set! (auto-update-interval) 0.0) (set! *to-snd* #f)) (load "sndlib-ws.scm")) (load "generators.scm") (set! *clm-file-buffer-size* 16) (set! *clm-table-size* 16) (set! *clm-clipped* #f) ;(set! (*s7* 'gc-stats) #t) (define start-run (get-internal-real-time)) (define M (float-vector 0 0 1 10)) (define P (float-vector 0 0 1 1)) (set! (*s7* 'initial-string-port-length) 8192) (mus-sound-preload "1a.snd") (define* (env-1 g f) (env g)) (define (make-env-1 size) (make-env M :length 10)) (define pulsed-env-1 pulsed-env) (define (make-pulsed-env-1 size) (make-pulsed-env P .01 1000.0)) (define delay-1 delay) (define (make-delay-1 size) (make-delay 4)) (define comb-1 comb) (define (make-comb-1 size) (make-comb .9 4)) (define filtered-comb-1 filtered-comb) (define (make-filtered-comb-1 size) (make-filtered-comb .9 4)) (define notch-1 notch) (define (make-notch-1 size) (make-notch .9 4)) (define all-pass-1 all-pass) (define (make-all-pass-1 size) (make-all-pass .9 .4 4)) (define one-pole-all-pass-1 one-pole-all-pass) (define (make-one-pole-all-pass-1 size) (make-one-pole-all-pass 4 .5)) (define moving-average-1 moving-average) (define (make-moving-average-1 size) (make-moving-average 4)) (define moving-max-1 moving-max) (define (make-moving-max-1 size) (make-moving-max 3)) (define moving-norm-1 moving-norm) (define (make-moving-norm-1 size) (make-moving-norm 3)) (define one-pole-1 one-pole) (define (make-one-pole-1 size) (make-one-pole .9 .4)) (define two-pole-1 two-pole) (define (make-two-pole-1 size) (make-two-pole .9 .4 .1)) (define one-zero-1 one-zero) (define (make-one-zero-1 size) (make-one-zero .9 .4)) (define two-zero-1 two-zero) (define (make-two-zero-1 size) (make-two-zero .9 .4 .1)) (define table-lookup-1 table-lookup) (define table-lookup-table (partials->wave '(1 1.0))) (define (make-table-lookup-1 size) (make-table-lookup 16 :wave table-lookup-table)) (define formant-1 formant) (define (make-formant-1 size) (make-formant size .1)) (define firmant-1 firmant) (define (make-firmant-1 size) (make-firmant size .1)) (define fx (float-vector .1 -.2 .3)) (define fy (float-vector -.1 .02 -.3)) (define filter-1 filter) (define (make-filter-1 size) (make-filter 3 fx fy)) (define fir-filter-1 fir-filter) (define (make-fir-filter-1 size) (make-fir-filter 3 fx)) (define iir-filter-1 iir-filter) (define (make-iir-filter-1 size) (make-iir-filter 3 fx)) (define readin-1 readin) (define (make-readin-1 size) (make-readin "1a.snd")) (define (io dir) .1) (define src-1 src) (define (make-src-1 size) (make-src io 2.0)) (define granulate-1 granulate) (define (make-granulate-1 size) (make-granulate io 2.0 0.001 0.6 0.001 .4 0.0)) (define phase-vocoder-1 phase-vocoder) (define (make-phase-vocoder-1 size) (make-phase-vocoder io 16)) (define ssb-am-1 ssb-am) (define (make-ssb-am-1 size) (make-ssb-am 100.0 20)) (define wave-train-1 wave-train) (define wt-train (make-float-vector 20 0.1)) (define (make-wave-train-1 size) (make-wave-train 1000.0 0.0 wt-train)) (define convolve-1 convolve) (define (make-convolve-1 size) (make-convolve io (make-float-vector 16 .2) 16)) (define oscil-bank-1 oscil-bank) (define ob-freqs (float-vector 100.0 200.0)) (define ob-amps (float-vector 0.5 0.5)) (define (make-oscil-bank-1 size) (make-oscil-bank ob-freqs (float-vector 0.0 0.0) ob-amps)) (define formant-bank-1 formant-bank) (define (make-formant-bank-1 size) (make-formant-bank (vector (make-formant 440.0 .95)))) (define comb-bank-1 comb-bank) (define (make-comb-bank-1 size) (make-comb-bank (vector (make-comb .5 6)))) (define filtered-comb-bank-1 filtered-comb-bank) (define (make-filtered-comb-bank-1 size) (make-filtered-comb-bank (vector (make-filtered-comb .5 6)))) (define all-pass-bank-1 all-pass-bank) (define (make-all-pass-bank-1 size) (make-all-pass-bank (vector (make-all-pass .5 .4 6)))) (define rand-1 rand) (define (make-rand-1 size) (set! (mus-rand-seed) 12345) (make-rand 5.0 0.1)) (define rand-interp-1 rand-interp) (define (make-rand-interp-1 size) (set! (mus-rand-seed) 12345) (make-rand-interp 5.0 0.1)) ;;; we are creating millions of functions here, so we need to keep them from ;;; being removed from the heap, and make sure they're GC'd -- *safety*=1 ;;; keeps them in the heap, but s7 continues to allocate space for each redefinition, ;;; hence the extra let below. (define-constant (vequal v1 v2) (or (morally-equal? v1 v2) (float-vector-equal? v1 v2 1e-5))) ; "relative" equality: diff/mx ;(set! (*s7* 'morally-equal-float-epsilon) 1e-5) ;(define vequal morally-equal?) (define-constant (checkout str V v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12) (if (or (not (vequal V v1)) (not (vequal v1 v2)) (not (vequal v1 v3)) (not (vequal v1 v4))) (format *stderr* "~S:~% no do: ~A~% fv-set: ~A~% outa->v:~A~% outa: ~A~% list: ~A~%" str V v1 v2 v3 v4)) (if (not (vequal v5 v6)) (format *stderr* "dox ~S:~% fv-set: ~A~% outa->v:~A~%" str v5 v6)) (if (not (vequal v7 v8)) (format *stderr* "let ~S:~% ~A~% ~A~%" str v7 v8)) (if (not (vequal v9 v10)) (format *stderr* "env let ~S:~% ~A~% ~A~%" str v9 v10)) (if (not (vequal v11 v12)) (format *stderr* "letx ~S:~% ~A~% ~A~%" str v11 v12))) (define-constant (checkout-1 str V v1 v2 v3 v4 v5 v6 v11 v12) (if (or (not (vequal V v1)) (not (vequal v1 v2)) (not (vequal v1 v3)) (not (vequal v1 v4))) (format *stderr* "~S:~% no do: ~A~% fv-set: ~A~% outa->v:~A~% outa: ~A~% list: ~A~%" str V v1 v2 v3 v4)) (if (not (vequal v5 v6)) (format *stderr* "dox ~S:~% fv-set: ~A~% outa->v:~A~%" str v5 v6)) (if (not (vequal v11 v12)) (format *stderr* "letx ~S:~% ~A~% ~A~%" str v11 v12))) (define-constant F (make-env (float-vector 0.0 .1 1.0 1.0) :length 100)) (define-constant K (float-vector 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0)) (define-constant V (make-float-vector 10)) (define (try1 form gen) (let ((make-gen (string->symbol (string-append "make-" (symbol->string gen))))) (let ((body `(let () (define G (,make-gen 1000)) (define I (,make-gen 500)) (define (O) (vector #f (mus-copy I) #f)) (define (Q) (mus-copy G)) (define (Z) (mus-copy F)) (let ((o (Q)) (p (Q)) (q (Q)) (oscs (O)) (a (Z)) (b (Z)) (x 3.14) (y -0.5) (k 1)) (do ((i 0 (+ i 1))) ((= i 10)) (set! (V i) ,(copy form)))) (define (tester-1) (let ((o (Q)) (p (Q)) (q (Q)) (oscs (O)) (a (Z)) (b (Z)) (x 3.14) (y -0.5) (k 1) (v (make-float-vector 10))) (do ((i 0 (+ i 1))) ((= i 10) v) (float-vector-set! v i ,(copy form))))) (define (tester-2) (let ((o (Q)) (p (Q)) (q (Q)) (oscs (O)) (a (Z)) (b (Z)) (x 3.14) (y -0.5) (k 1)) (set! *output* (make-float-vector 10)) (do ((i 0 (+ i 1))) ((= i 10) *output*) (outa i ,(copy form))))) (define (tester-3) (let ((o (Q)) (p (Q)) (q (Q)) (oscs (O)) (a (Z)) (b (Z)) (x 3.14) (y -0.5) (k 1)) (set! *output* (make-float-vector 10)) (do ((i 0 (+ i 1))) ((= i 10) *output*) (out-any i ,(copy form) 0)))) (define (tester-4) (let ((o (Q)) (p (Q)) (q (Q)) (oscs (O)) (a (Z)) (b (Z)) (x 3.14) (y -0.5) (k 1)) (do ((i 0 (+ i 1)) (lst ())) ((= i 10) (apply float-vector (reverse! lst))) (set! lst (cons ,(copy form) lst))))) (define (tester-5) (let ((o (Q)) (p (Q)) (q (Q)) (oscs (O)) (a (Z)) (b (Z)) (y -0.5) (k 1) (v (make-float-vector 10))) (set! *output* (make-sample->file "test.snd" 1 mus-ldouble mus-next "t816")) (do ((i 0 (+ i 1)) (x 0.0 (+ x 0.1))) ((= i 10)) (outa i ,(copy form))) (mus-close *output*) (file->array "test.snd" 0 0 10 v))) (define (tester-6) (let ((o (Q)) (p (Q)) (q (Q)) (oscs (O)) (a (Z)) (b (Z)) (k 1) (v (make-float-vector 10))) (do ((i 0 (+ i 1)) (y -0.5) (x 0.0 (+ x 0.1))) ((= i 10) v) (float-vector-set! v i ,(copy form))))) (define (tester-11) (let ((o (Q)) (p (Q)) (q (Q)) (oscs (O)) (a (Z)) (b (Z)) (y -0.5) (k 1) (v (make-float-vector 10))) (do ((i 0 (+ i 1))) ((= i 10) v) (let ((x (,gen o))) (set! (v i) ,(copy form)))))) (define (tester-12) (let ((o (Q)) (p (Q)) (q (Q)) (oscs (O)) (a (Z)) (b (Z)) (y -0.5) (k 1)) (set! *output* (make-float-vector 10)) (do ((i 0 (+ i 1))) ((= i 10) *output*) (let ((x (,gen o))) (outa i ,(copy form)))))) (checkout-1 ',form V (tester-1) (tester-2) (tester-3) (tester-4) (tester-5) (tester-6) (tester-11) (tester-12)) ))) (define the-body (apply lambda () (list (copy body :readable)))) (the-body)))) (define (try2 form gen) (let ((make-gen (string->symbol (string-append "make-" (symbol->string gen))))) (let ((body `(let () (define G (,make-gen 1000)) (define I (,make-gen 500)) (define (O) (vector #f (mus-copy I) #f)) (define (Q) (mus-copy G)) (define (Z) (mus-copy F)) (let ((o (Q)) (p (Q)) (q (Q)) (oscs (O)) (a (Z)) (b (Z)) (x 3.14) (y -0.5) (k 1)) (do ((i 0 (+ i 1))) ((= i 10)) (set! (V i) ,(copy form)))) (define (tester-1) (let ((o (Q)) (p (Q)) (q (Q)) (oscs (O)) (a (Z)) (b (Z)) (x 3.14) (y -0.5) (k 1) (v (make-float-vector 10))) (do ((i 0 (+ i 1))) ((= i 10) v) (float-vector-set! v i ,(copy form))))) (define (tester-2) (let ((o (Q)) (p (Q)) (q (Q)) (oscs (O)) (a (Z)) (b (Z)) (x 3.14) (y -0.5) (k 1)) (set! *output* (make-float-vector 10)) (do ((i 0 (+ i 1))) ((= i 10) *output*) (outa i ,(copy form))))) (define (tester-3) (let ((o (Q)) (p (Q)) (q (Q)) (oscs (O)) (a (Z)) (b (Z)) (x 3.14) (y -0.5) (k 1)) (set! *output* (make-float-vector 10)) (do ((i 0 (+ i 1))) ((= i 10) *output*) (out-any i ,(copy form) 0)))) (define (tester-4) (let ((o (Q)) (p (Q)) (q (Q)) (oscs (O)) (a (Z)) (b (Z)) (x 3.14) (y -0.5) (k 1)) (do ((i 0 (+ i 1)) (lst ())) ((= i 10) (apply float-vector (reverse! lst))) (set! lst (cons ,(copy form) lst))))) (define (tester-5) (let ((o (Q)) (p (Q)) (q (Q)) (oscs (O)) (a (Z)) (b (Z)) (y -0.5) (k 1) (v (make-float-vector 10))) (set! *output* (make-sample->file "test.snd" 1 mus-ldouble mus-next "t816")) (do ((i 0 (+ i 1)) (x 0.0 (+ x 0.1))) ((= i 10)) (outa i ,(copy form))) (mus-close *output*) (file->array "test.snd" 0 0 10 v))) (define (tester-6) (let ((o (Q)) (p (Q)) (q (Q)) (oscs (O)) (a (Z)) (b (Z)) (k 1) (v (make-float-vector 10))) (do ((i 0 (+ i 1)) (y -0.5) (x 0.0 (+ x 0.1))) ((= i 10) v) (float-vector-set! v i ,(copy form))))) (define (tester-7) (let ((o (Q)) (p (Q)) (q (Q)) (oscs (O)) (a (Z)) (b (Z)) (x 3.14) (y -0.5) (k 1) (v (make-float-vector 10))) (do ((i 0 (+ i 1))) ((= i 10) v) (let ((z ,(copy form))) (float-vector-set! v i (,gen o z)))))) (define (tester-8) (let ((o (Q)) (p (Q)) (q (Q)) (oscs (O)) (a (Z)) (b (Z)) (x 3.14) (y -0.5) (k 1)) (set! *output* (make-float-vector 10)) (do ((i 0 (+ i 1))) ((= i 10) *output*) (let ((z ,(copy form))) (outa i (,gen o z)))))) (define (tester-9) (let ((o (Q)) (p (Q)) (q (Q)) (oscs (O)) (a (Z)) (b (Z)) (x 3.14) (y -0.5) (k 1) (v (make-float-vector 10))) (do ((i 0 (+ i 1))) ((= i 10) v) (let ((z ,(copy form))) (float-vector-set! v i (* (env a) (,gen o z))))))) (define (tester-10) (let ((o (Q)) (p (Q)) (q (Q)) (oscs (O)) (a (Z)) (b (Z)) (x 3.14) (y -0.5) (k 1)) (set! *output* (make-float-vector 10)) (do ((i 0 (+ i 1))) ((= i 10) *output*) (let ((z ,(copy form))) (outa i (* (env a) (,gen o z))))))) (define (tester-11) (let ((o (Q)) (p (Q)) (q (Q)) (oscs (O)) (a (Z)) (b (Z)) (y -0.5) (k 1) (v (make-float-vector 10))) (do ((i 0 (+ i 1))) ((= i 10) v) (let ((x (,gen o))) (set! (v i) ,(copy form)))))) (define (tester-12) (let ((o (Q)) (p (Q)) (q (Q)) (oscs (O)) (a (Z)) (b (Z)) (y -0.5) (k 1)) (set! *output* (make-float-vector 10)) (do ((i 0 (+ i 1))) ((= i 10) *output*) (let ((x (,gen o))) (outa i ,(copy form)))))) (checkout ',form V (tester-1) (tester-2) (tester-3) (tester-4) (tester-5) (tester-6) (tester-7) (tester-8) (tester-9) (tester-10) (tester-11) (tester-12)) ))) (define the-body (apply lambda () (list (copy body :readable)))) (the-body)))) (define (try34 form gen args) (let ((make-gen (string->symbol (string-append "make-" (symbol->string gen))))) (let ((body `(let () (define G (,make-gen 1000)) (define I (,make-gen 500)) (define (O) (vector #f (mus-copy I) #f)) (define (Q) (mus-copy G)) (define (Z) (mus-copy F)) (let ((o (Q)) (p (Q)) (q (Q)) (s (Q)) (t (Q)) (oscs (O)) (a (Z)) (b (Z)) (c (Z)) (d (Z)) (x 3.14) (y -0.5) (z 0.1) (k 1)) (do ((i 0 (+ i 1))) ((= i 10)) (float-vector-set! V i ,(copy form)))) (define (tester-1) (let ((o (Q)) (p (Q)) (q (Q)) (s (Q)) (t (Q)) (oscs (O)) (a (Z)) (b (Z)) (c (Z)) (d (Z)) (x 3.14) (y -0.5) (z 0.1) (k 1) (v (make-float-vector 10))) (do ((i 0 (+ i 1))) ((= i 10) v) (float-vector-set! v i ,(copy form))))) (define (tester-2) (let ((o (Q)) (p (Q)) (q (Q)) (s (Q)) (t (Q)) (oscs (O)) (a (Z)) (b (Z)) (c (Z)) (d (Z)) (x 3.14) (y -0.5) (z 0.1) (k 1)) (set! *output* (make-float-vector 10)) (do ((i 0 (+ i 1))) ((= i 10) *output*) (outa i ,(copy form))))) (define (tester-3) (let ((o (Q)) (p (Q)) (q (Q)) (s (Q)) (t (Q)) (oscs (O)) (a (Z)) (b (Z)) (c (Z)) (d (Z)) (x 3.14) (y -0.5) (z 0.1) (k 1)) (set! *output* (make-float-vector 10)) (do ((i 0 (+ i 1))) ((= i 10) *output*) (out-any i ,(copy form) 0)))) (define (tester-4) (let ((o (Q)) (p (Q)) (q (Q)) (s (Q)) (t (Q)) (oscs (O)) (a (Z)) (b (Z)) (c (Z)) (d (Z)) (x 3.14) (y -0.5) (k 1) (z 0.1)) (do ((i 0 (+ i 1)) (lst ())) ((= i 10) (apply float-vector (reverse! lst))) (set! lst (cons ,(copy form) lst))))) (define (tester-5) (let ((o (Q)) (p (Q)) (q (Q)) (s (Q)) (t (Q)) (oscs (O)) (a (Z)) (b (Z)) (c (Z)) (d (Z)) (y -0.5) (k 1) (z 0.1) (v (make-float-vector 10))) (set! *output* (make-sample->file "test.snd" 1 mus-ldouble mus-next "t816")) (do ((i 0 (+ i 1)) (x 0.0 (+ x 0.1))) ((= i 10)) (outa i ,(copy form))) (mus-close *output*) (file->array "test.snd" 0 0 10 v))) (define (tester-6) (let ((o (Q)) (p (Q)) (q (Q)) (s (Q)) (t (Q)) (oscs (O)) (a (Z)) (b (Z)) (c (Z)) (d (Z)) (k 1) (v (make-float-vector 10))) (do ((i 0 (+ i 1)) (y -0.5) (z 0.1) (x 0.0 (+ x 0.1))) ((= i 10) v) (set! (v i) ,(copy form))))) (define (tester-7) (let ((o (Q)) (p (Q)) (q (Q)) (s (Q)) (t (Q)) (oscs (O)) (a (Z)) (b (Z)) (c (Z)) (d (Z)) (x 3.14) (y -0.5) (k 1) (z 0.1) (v (make-float-vector 10))) (do ((i 0 (+ i 1))) ((= i 10) v) (let ((zz ,(copy form))) (float-vector-set! v i (,gen o zz)))))) (define (tester-8) (let ((o (Q)) (p (Q)) (q (Q)) (s (Q)) (t (Q)) (oscs (O)) (a (Z)) (b (Z)) (c (Z)) (d (Z)) (x 3.14) (y -0.5) (z 0.1) (k 1)) (set! *output* (make-float-vector 10)) (do ((i 0 (+ i 1))) ((= i 10) *output*) (let ((zz ,(copy form))) (outa i (,gen o zz)))))) (define (tester-9) (let ((o (Q)) (p (Q)) (q (Q)) (s (Q)) (t (Q)) (oscs (O)) (a (Z)) (b (Z)) (c (Z)) (d (Z)) (x 3.14) (y -0.5) (z 0.1) (k 1) (v (make-float-vector 10))) (do ((i 0 (+ i 1))) ((= i 10) v) (let ((zz ,(copy form))) (float-vector-set! v i (* (env a) (,gen o zz))))))) (define (tester-10) (let ((o (Q)) (p (Q)) (q (Q)) (s (Q)) (t (Q)) (oscs (O)) (a (Z)) (b (Z)) (c (Z)) (d (Z)) (x 3.14) (y -0.5) (z 0.1) (k 1)) (set! *output* (make-float-vector 10)) (do ((i 0 (+ i 1))) ((= i 10) *output*) (let ((zz ,(copy form))) (outa i (* (env a) (,gen o zz))))))) (define (tester-11) (let ((o (Q)) (p (Q)) (q (Q)) (s (Q)) (t (Q)) (oscs (O)) (a (Z)) (b (Z)) (c (Z)) (d (Z)) (y -0.5) (z 0.1) (k 1) (v (make-float-vector 10))) (do ((i 0 (+ i 1))) ((= i 10) v) (let ((x (,gen o))) (float-vector-set! v i ,(copy form)))))) (define (tester-12) (let ((o (Q)) (p (Q)) (q (Q)) (s (Q)) (t (Q)) (oscs (O)) (a (Z)) (b (Z)) (c (Z)) (d (Z)) (y -0.5) (z 0.1) (k 1)) (set! *output* (make-float-vector 10)) (do ((i 0 (+ i 1))) ((= i 10) *output*) (let ((x (,gen o))) (outa i ,(copy form)))))) (if (= args 1) (checkout-1 ',form V (tester-1) (tester-2) (tester-3) (tester-4) (tester-5) (tester-6) (tester-11) (tester-12)) (checkout ',form V (tester-1) (tester-2) (tester-3) (tester-4) (tester-5) (tester-6) (tester-7) (tester-8) (tester-9) (tester-10) (tester-11) (tester-12)) )))) (define the-body (apply lambda () (list (copy body :readable)))) (the-body)))) (define (test-gen gen nargs) (define args1 (list 1.5 (list gen 'p) '(env a) 'x 'i (list gen 'o) '(- 1.0 x) (list gen '(vector-ref oscs k)))) (define args2 (list 1.5 (list gen 'q) '(env b) 'y 'i '(ina i K))) (define args3 (list 1.5 (list gen 's) '(env c) 'z 'i '(cos x))) (define args4 (list 1.5 (list gen 't) '(env d) 'x 'i)) (if (= nargs 1) (begin (for-each (lambda (a) (try1 a gen) (when (> nargs 1) (try1 `(,gen o ,a) gen) (try1 `(abs (,gen o ,a)) gen))) args1) (for-each (lambda (a) (for-each (lambda (b) (try1 `(+ ,a ,b) gen) (try1 `(- ,a ,b) gen) (try1 `(* ,a ,b) gen) (try1 `(cos (+ ,a ,b)) gen) (try1 `(sin (* ,a ,b)) gen) (try1 `(abs (* ,a ,b)) gen) (try1 `(* ,a (abs ,b)) gen) (when (> nargs 1) (try1 `(,gen o (+ ,a ,b)) gen) (try1 `(,gen o (* ,a ,b)) gen) (try1 `(+ ,a (,gen o ,b)) gen) (try1 `(* ,a (,gen o ,b)) gen) (try1 `(+ (,gen o ,a) ,b) gen) (try1 `(* (,gen o ,a) ,b) gen) (try1 `(* (abs (,gen o ,a)) ,b) gen))) args2)) args1)) (begin (for-each (lambda (a) (try2 a gen) (when (> nargs 1) (try2 `(,gen o ,a) gen) (try2 `(abs (,gen o ,a)) gen))) args1) (for-each (lambda (a) (for-each (lambda (b) (try2 `(+ ,a ,b) gen) (try2 `(- ,a ,b) gen) (try2 `(* ,a ,b) gen) (try2 `(cos (+ ,a ,b)) gen) (try2 `(sin (* ,a ,b)) gen) (try2 `(abs (* ,a ,b)) gen) (try2 `(* ,a (abs ,b)) gen) (when (> nargs 1) (try2 `(,gen o (+ ,a ,b)) gen) (try2 `(,gen o (* ,a ,b)) gen) (try2 `(+ ,a (,gen o ,b)) gen) (try2 `(* ,a (,gen o ,b)) gen) (try2 `(+ (,gen o ,a) ,b) gen) (try2 `(* (,gen o ,a) ,b) gen) (try2 `(* (abs (,gen o ,a)) ,b) gen))) args2)) args1))) #| (for-each (lambda (c) (for-each (lambda (b) (for-each (lambda (a) (try34 `(+ ,a ,b ,c) gen nargs) (try34 `(+ (* ,a ,b) ,c) gen nargs) (try34 `(+ ,a (* ,b ,c)) gen nargs) (try34 `(* ,a ,b ,c) gen nargs) (try34 `(* ,a (+ ,b ,c)) gen nargs) (try34 `(* (+ ,a ,b) ,c) gen nargs) (when (> nargs 1) (try34 `(,gen o (+ ,a ,b ,c)) gen nargs) (try34 `(,gen o (* ,a ,b ,c)) gen nargs) (try34 `(,gen o (* ,a (+ ,b ,c))) gen nargs) (try34 `(,gen o (+ ,a (* ,b ,c))) gen nargs) (try34 `(,gen o (* (+ ,a ,b) ,c)) gen nargs) (try34 `(,gen o (+ (* ,a ,b) ,c)) gen nargs) (try34 `(+ ,a (,gen o (+ ,b ,c))) gen nargs) (try34 `(+ ,a (,gen o (* ,b ,c))) gen nargs) (try34 `(* ,a (,gen o (+ ,b ,c))) gen nargs) (try34 `(* ,a (,gen o (* ,b ,c))) gen nargs) (try34 `(+ ,a ,b (,gen o ,c)) gen nargs) (try34 `(* ,a ,b (,gen o ,c)) gen nargs) (try34 `(+ (* ,a ,b) (,gen o ,c)) gen nargs) (try34 `(* (+ ,a ,b) (,gen o ,c)) gen nargs) (try34 `(+ ,a (* ,b (,gen o ,c))) gen nargs) (try34 `(* ,a (+ ,b (,gen o ,c))) gen nargs) (try34 `(+ ,a (,gen o ,b) ,c) gen nargs) (try34 `(* ,a (,gen o ,b) ,c) gen nargs) (try34 `(+ (* ,a (,gen o ,b)) ,c) gen nargs) (try34 `(* (+ ,a (,gen o ,b)) ,c) gen nargs) (try34 `(+ ,a (* (,gen o ,b) ,c)) gen nargs) (try34 `(* ,a (+ (,gen o ,b) ,c)) gen nargs) (try34 `(+ (,gen o ,a) ,b ,c) gen nargs) (try34 `(+ (,gen o ,a) (* ,b ,c)) gen nargs) (try34 `(* (,gen o ,a) (+ ,b ,c)) gen nargs) (try34 `(* (,gen o ,a) ,b ,c) gen nargs)) (try34 `(+ ,a (abs ,b) ,c) gen nargs) (try34 `(+ ,a (sin ,b) ,c) gen nargs) (try34 `(+ ,a (cos ,b) ,c) gen nargs)) args3)) args2)) args1) (for-each (lambda (d) (for-each (lambda (c) (for-each (lambda (b) (for-each (lambda (a) (try34 `(+ ,a ,b ,c ,d) gen nargs) (try34 `(* ,a ,b ,c ,d) gen nargs) (try34 `(+ (* ,a ,b) (* ,c ,d)) gen nargs) (try34 `(* (+ ,a ,b) (+ ,c ,d)) gen nargs) (try34 `(+ ,a (* ,b ,c ,d)) gen nargs) (try34 `(* ,a (+ ,b ,c ,d)) gen nargs) (try34 `(+ ,a (* ,b (+ ,c ,d))) gen nargs) (try34 `(* ,a (+ ,b (* ,c ,d))) gen nargs) (try34 `(+ (* ,a ,b ,c) ,d) gen nargs) (try34 `(* (+ ,a ,b ,c) ,d) gen nargs) (try34 `(+ (* ,a (+ ,b ,c)) ,d) gen nargs) (try34 `(* (+ ,a (* ,b ,c)) ,d) gen nargs) (when (> nargs 1) (try34 `(+ (,gen o ,a) ,b ,c ,d) gen nargs) (try34 `(* (,gen o ,a) ,b ,c ,d) gen nargs) (try34 `(+ (* (,gen o ,a) ,b) (* ,c ,d)) gen nargs) (try34 `(* (+ (,gen o ,a) ,b) (+ ,c ,d)) gen nargs) (try34 `(+ (,gen o ,a) (* ,b ,c ,d)) gen nargs) (try34 `(* (,gen o ,a) (+ ,b ,c ,d)) gen nargs) (try34 `(+ (,gen o ,a) (* ,b (+ ,c ,d))) gen nargs) (try34 `(* (,gen o ,a) (+ ,b (* ,c ,d))) gen nargs) (try34 `(+ (* (,gen o ,a) ,b ,c) ,d) gen nargs) (try34 `(* (+ (,gen o ,a) ,b ,c) ,d) gen nargs) (try34 `(+ (* (,gen o ,a) (+ ,b ,c)) ,d) gen nargs) (try34 `(* (+ (,gen o ,a) (* ,b ,c)) ,d) gen nargs) (try34 `(+ ,a (,gen o ,b) ,c ,d) gen nargs) (try34 `(* ,a (,gen o ,b) ,c ,d) gen nargs) (try34 `(+ (* ,a (,gen o ,b)) (* ,c ,d)) gen nargs) (try34 `(* (+ ,a (,gen o ,b)) (+ ,c ,d)) gen nargs) (try34 `(+ ,a (* (,gen o ,b) ,c ,d)) gen nargs) (try34 `(* ,a (+ (,gen o ,b) ,c ,d)) gen nargs) (try34 `(+ ,a (* (,gen o ,b) (+ ,c ,d))) gen nargs) (try34 `(* ,a (+ (,gen o ,b) (* ,c ,d))) gen nargs) (try34 `(+ (* ,a (,gen o ,b) ,c) ,d) gen nargs) (try34 `(* (+ ,a (,gen o ,b) ,c) ,d) gen nargs) (try34 `(+ (* ,a (+ (,gen o ,b) ,c)) ,d) gen nargs) (try34 `(* (+ ,a (* (,gen o ,b) ,c)) ,d) gen nargs) (try34 `(+ ,a ,b (,gen o ,c) ,d) gen nargs) (try34 `(* ,a ,b (,gen o ,c) ,d) gen nargs) (try34 `(+ (* ,a ,b) (* (,gen o ,c) ,d)) gen nargs) (try34 `(* (+ ,a ,b) (+ (,gen o ,c) ,d)) gen nargs) (try34 `(+ ,a (* ,b (,gen o ,c) ,d)) gen nargs) (try34 `(* ,a (+ ,b (,gen o ,c) ,d)) gen nargs) (try34 `(+ ,a (* ,b (+ (,gen o ,c) ,d))) gen nargs) (try34 `(* ,a (+ ,b (* (,gen o ,c) ,d))) gen nargs) (try34 `(+ (* ,a ,b (,gen o ,c)) ,d) gen nargs) (try34 `(* (+ ,a ,b (,gen o ,c)) ,d) gen nargs) (try34 `(+ (* ,a (+ ,b (,gen o ,c))) ,d) gen nargs) (try34 `(* (+ ,a (* ,b (,gen o ,c))) ,d) gen nargs) (try34 `(+ ,a ,b ,c (,gen o ,d)) gen nargs) (try34 `(* ,a ,b ,c (,gen o ,d)) gen nargs) (try34 `(+ (* ,a ,b) (* ,c (,gen o ,d))) gen nargs) (try34 `(* (+ ,a ,b) (+ ,c (,gen o ,d))) gen nargs) (try34 `(+ ,a (* ,b ,c (,gen o ,d))) gen nargs) (try34 `(* ,a (+ ,b ,c (,gen o ,d))) gen nargs) (try34 `(+ ,a (* ,b (+ ,c (,gen o ,d)))) gen nargs) (try34 `(* ,a (+ ,b (* ,c (,gen o ,d)))) gen nargs) (try34 `(+ (* ,a ,b ,c) (,gen o ,d)) gen nargs) (try34 `(* (+ ,a ,b ,c) (,gen o ,d)) gen nargs) (try34 `(+ (* ,a (+ ,b ,c)) (,gen o ,d)) gen nargs) (try34 `(* (+ ,a (* ,b ,c)) (,gen o ,d)) gen nargs) (try34 `(,gen o (+ ,a ,b ,c ,d)) gen nargs) (try34 `(,gen o (* ,a ,b ,c ,d)) gen nargs) (try34 `(,gen o (+ (* ,a ,b) (* ,c ,d))) gen nargs) (try34 `(,gen o (* (+ ,a ,b) (+ ,c ,d))) gen nargs) (try34 `(,gen o (+ ,a (* ,b ,c ,d))) gen nargs) (try34 `(,gen o (* ,a (+ ,b ,c ,d))) gen nargs) (try34 `(,gen o (+ ,a (* ,b (+ ,c ,d)))) gen nargs) (try34 `(,gen o (* ,a (+ ,b (* ,c ,d)))) gen nargs) (try34 `(,gen o (+ (* ,a ,b ,c) ,d)) gen nargs) (try34 `(,gen o (* (+ ,a ,b ,c) ,d)) gen nargs) (try34 `(,gen o (+ (* ,a (+ ,b ,c)) ,d)) gen nargs) (try34 `(,gen o (* (+ ,a (* ,b ,c)) ,d)) gen nargs) (try34 `(+ (,gen o (* ,a ,b)) (* ,c ,d)) gen nargs) (try34 `(* (,gen o (+ ,a ,b)) (+ ,c ,d)) gen nargs) (try34 `(,gen o (+ (* ,a ,b) (* ,c ,d))) gen nargs) (try34 `(+ ,a (* ,b (,gen o (+ ,c ,d)))) gen nargs) (try34 `(* ,a (+ ,b (,gen o (* ,c ,d)))) gen nargs) (try34 `(+ (* ,a (,gen o (+ ,b ,c))) ,d) gen nargs) (try34 `(* (+ ,a (,gen o (* ,b ,c))) ,d) gen nargs)) (try34 `(+ ,a ,b ,c ,d (,gen o)) gen nargs) (try34 `(* ,a ,b ,c ,d (,gen o)) gen nargs)) args4)) args3)) args2)) args1) |# ) (for-each (lambda (gen nargs) ;(gc) (set! start-run (get-internal-real-time)) (test-gen gen nargs) (format *stderr* "~A: ~20T~,3F~%" gen (* 1.0 (/ (- (get-internal-real-time) start-run) internal-time-units-per-second)))) ; '(adjustable-oscil) ; '(2) '(;rand-1 rand-interp-1 ; the y-as-fm case will be different (ignore printout) r2k!cos filter-1 fir-filter-1 iir-filter-1 oscil one-pole-all-pass-1 env-1 pulsed-env-1 formant-1 firmant-1 polywave polyshape ncos nsin nrxycos nrxysin rxyk!sin rxyk!cos asymmetric-fm square-wave triangle-wave pulse-train sawtooth-wave one-pole-1 one-zero-1 two-pole-1 two-zero-1 oscil-bank-1 delay-1 comb-1 notch-1 all-pass-1 filtered-comb-1 moving-max-1 moving-norm-1 moving-average-1 table-lookup-1 wave-train-1 formant-bank-1 comb-bank-1 filtered-comb-bank-1 all-pass-bank-1 adjustable-oscil readin-1 convolve-1 src-1 granulate-1 ssb-am-1 phase-vocoder-1 ) '(;2 2 2 2 2 2 2 2 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 2 1 2 1 ) ) ;(gc) (s7-version) (exit) snd-16.1/tools/tform.scm0000644000076400007640000001270212610307045013326 0ustar bilbil(let ((new-env (sublet (curlet) (cons 'init_func 'block_init)))) ; load calls init_func if possible (load "s7test-block.so" new-env)) (load "mockery.scm") (define-constant one 1) (define mock-number (*mock-number* 'mock-number)) (define mock-pair (*mock-pair* 'mock-pair)) (define mock-string (*mock-string* 'mock-string)) (define mock-char (*mock-char* 'mock-char)) (define mock-vector (*mock-vector* 'mock-vector)) (define mock-symbol (*mock-symbol* 'mock-symbol)) (define mock-hash-table* (*mock-hash-table* 'mock-hash-table*)) (define np (list 0 1 2 3 4)) (define mp (mock-pair '(0 1 2 3 4))) (define nv (vector 0 1 2 3 4)) (define mv (mock-vector 0 1 2 3 4)) (define ns "01234") (define ms (mock-string #\0 #\1 #\2 #\3 #\4)) ;;(openlet (inlet 'i 0 'list-set! (lambda (l . args) (apply #_list-set! l ((car args) 'i) (cdr args)))))) (define-constant constants (vector #f #t () #\a (/ most-positive-fixnum) (/ -1 most-positive-fixnum) 1.5+i "hi455" :key hi: 'hi (list 1) (list 1 2) (cons 1 2) (list (list 1 2)) (list (list 1)) (list ()) #() 1/0+i 0+0/0i 0+1/0i 1+0/0i 0/0+0i 0/0+0/0i 1+1/0i 0/0+i cons ''2 1+i 1+1e10i 1e15+1e15i 0+1e18i 1e18 (integer->char 255) (string (integer->char 255)) 1e308 most-positive-fixnum most-negative-fixnum (- most-positive-fixnum 1) (+ most-negative-fixnum 1) -1 0 0.0 1 1.5 1.0-1.0i 3/4 #\null -63 (make-hash-table) (hash-table '(a . 2) '(b . 3)) '((1 2) (3 4)) '((1 (2)) (((3) 4))) "" (list #(1) "1") '(1 2 . 3) (list (cons 'a 2) (cons 'b 3)) #(1 2) (vector 1 '(3)) (let ((x 3)) (lambda (y) (+ x y))) abs 'a 'b one apply (lambda args args) (lambda* ((a 3) (b 2)) (+ a b)) (lambda () 3) (sublet () (cons 'a 1)) (rootlet) *load-hook* *error-hook* (random-state 123) quasiquote macroexpand cond-expand begin let letrec* if case cond (call-with-exit (lambda (goto) goto)) (with-baffle (call/cc (lambda (cc) cc))) (string #\a #\null #\b) #2d((1 2) (3 4)) (inlet 'a 2 'b 3) # # (make-vector 3 0 #t) (make-vector 3 -1.4 #t) (make-vector '(2 3) "hi") #("hiho" "hi" "hoho") (make-shared-vector (make-vector '(2 3) 1 #t) '(6)) (make-shared-vector (make-shared-vector (make-vector '(2 3) 1.0 #t) '(6)) '(2 2)) (vector-ref #2d((#(1 2 3)) (#(3 4 5))) 0 0) (define-macro (m a) `(+ ,a 1)) (c-pointer 0) (c-pointer -1) :readable *s7* else (define-bacro* (m (a 1)) `(+ ,a 1)) (byte-vector 0 1 2) (byte-vector) (byte-vector 255 0 127) (make-iterator (vector '(a . 2))) (lambda (dir) 1.0) (float-vector) (make-float-vector '(2 32)) (int-vector 1 2 3) (int-vector) (inlet 'value 1 '+ (lambda args 1)) (inlet) (make-iterator (inlet 'a 1 'b 2) (cons #f #f)) (make-iterator "123456") (make-iterator '(1 2 3)) (make-iterator (hash-table* 'a 1 'b 2) (cons #f #f)) (open-input-string "123123") (open-input-file "/home/bil/cl/4.aiff") (open-output-file "test.test") (open-output-string) (mock-number 0) (mock-number 2) (mock-number 1-i) (mock-number 4/3) (mock-number 2.0) (mock-string #\h #\o #\h #\o) (mock-pair '(2 3 4)) (mock-char #\b) (mock-symbol 'c) (mock-vector 1 2 3 4) (mock-hash-table* 'b 2) (make-block 32) (block) (make-iterator (block 1 2 3 4 5 6)) )) (define-constant constants-len (length constants)) (define-constant ctrl-chars (string ;#\A #\S #\C #\F #\E #\G #\O #\D #\B #\X #\W #\, #\{ #\} #\@ #\P #\* #\a #\s #\c #\f #\e #\g #\o #\d #\b #\x #\p #\n #\w #\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9 #\~ #\T #\& #\% #\^ #\| #\~ #\~ #\~ #\~ #\, #\, #\, #\, #\" #\" #\\ #\' #\+ #\- #\@ #\. #\/ #\; #\: )) (define-constant ctrl-chars-len (length ctrl-chars)) (define (test-chars) (let ((op (open-output-string)) (x #f) (y #f) (z #f)) (do ((size 2 (+ size 1))) ((= size 15)) (let ((tries (* size 2000)) (size1 (+ size 1))) (format *stderr* "~D " size) (let ((ctrl-str (make-string size1)) (pos 0)) (string-set! ctrl-str 0 #\~) (do ((i 0 (+ i 1))) ((= i tries)) (do ((j 1 (+ j 1))) ((= j size1)) (string-set! ctrl-str j (string-ref ctrl-chars (random ctrl-chars-len)))) (set! x (constants (random constants-len))) (set! y (constants (random constants-len))) (set! z (constants (random constants-len))) (object->string x) (display x op) (catch #t (lambda () (format #f "~{~^~S ~} ~{~|~S ~} ~W" x y z)) (lambda arg 'error)) (catch #t (lambda () (format #f ctrl-str)) (lambda arg 'error)) (catch #t (lambda () (format #f ctrl-str x)) (lambda arg 'error)) (catch #t (lambda () (format #f ctrl-str y)) (lambda arg 'error)) (catch #t (lambda () (format #f ctrl-str z)) (lambda arg 'error)) (set! pos (char-position #\~ ctrl-str 1)) (when pos (catch #t (lambda () (format #f ctrl-str x z)) (lambda arg 'error)) (catch #t (lambda () (format #f ctrl-str x y)) (lambda arg 'error)) (catch #t (lambda () (format #f ctrl-str y z)) (lambda arg 'error)) (catch #t (lambda () (format #f ctrl-str z x)) (lambda arg 'error)) (when (char-position #\~ ctrl-str (+ pos 1)) (catch #t (lambda () (format #f ctrl-str x y z)) (lambda arg 'error)) (catch #t (lambda () (format #f ctrl-str z y x)) (lambda arg 'error)))))) (get-output-string op #t))) (close-output-port op))) (test-chars) (s7-version) (exit) #| valgrind --vgdb=yes --vgdb-error=0 repl gdb repl target remote | /usr/local/lib/valgrind/../../bin/vgdb continue |# snd-16.1/tools/snd.supp0000644000076400007640000010524112515276602013201 0ustar bilbil# Snd valgrind suppressions file # valgrind --error-limit=no -v --gen-suppressions=yes --suppressions=/home/bil/cl/snd.supp snd # valgrind --error-limit=no -v --gen-suppressions=yes --suppressions=/home/bil/cl/snd.supp --leak-check=yes --show-reachable=no --num-callers=6 snd # valgrind --error-limit=no -v --gen-suppressions=no --suppressions=/home/bil/cl/snd.supp --leak-check=yes --leak-resolution=high --show-reachable=no --num-callers=12 snd # valgrind --error-limit=no -v --gen-suppressions=no --suppressions=/home/bil/cl/snd.supp --leak-check=yes --show-reachable=no --track-origins=yes --track-fds=yes --read-var-info=yes snd -l snd-test # valgrind --error-limit=no -v --gen-suppressions=no --suppressions=/home/bil/cl/snd.supp --leak-check=yes --show-reachable=no --track-origins=yes snd -l snd-test # # --tool=exp-ptrcheck # # valgrind --tool=helgrind snd # # valgrind --tool=callgrind snd # writes callgrind.out. # (remember -g switch) # callgrind_annotate --auto=yes callgrind.out. > hi # --inclusive=yes|no # --threshold=100 # first section copied (unnecessarily) from default: /usr/local/lib/valgrind/default.supp # This is a generated file, composed of the following suppression rules: # # glibc-2.3.supp xfree-4.supp xfree-3.supp # ##----------------------------------------------------------------------## # Errors to suppress by default with glibc 2.3.x # Format of this file is: # { # name_of_suppression # skin_name:supp_kind # (optional extra info for some suppression types) # caller0 name, or /name/of/so/file.so # caller1 name, or ditto # (optionally: caller2 name) # (optionally: caller3 name) # } # # For Memcheck, the supp_kinds are: # # Param Value1 Value2 Value4 Value8 Value16 # Free Addr1 Addr2 Addr4 Addr8 Addr16 # Cond (previously known as Value0) # # and the optional extra info is: # if Param: name of system call param # if Free: name of free-ing fn) { __GI___stpcpy/* Memcheck:Cond fun:__GI___stpcpy fun:* } { strlen/__GI__dl_open/dlopen_doit Memcheck:Cond fun:strlen fun:__GI__dl_open fun:dlopen_doit } { strlen/_dl_signal_cerror/_dl_lookup_symbol_internal/do_dlsym Memcheck:Cond fun:_dl_signal_cerror fun:_dl_lookup_symbol_internal fun:do_dlsym } { strlen/*dl_map_object*(Cond) Memcheck:Cond fun:strlen fun:*dl_map_object* } { strlen/*dl_open_worker*(Cond) Memcheck:Cond fun:strlen fun:*dl_open_worker* } { strlen/_dl_sym/dlsym_doit Memcheck:Cond fun:strlen fun:_dl_sym fun:dlsym_doit } { realpath is inefficiently coded Addrcheck,Memcheck:Overlap fun:memcpy fun:realpath* } { realpath stupidity part II Addrcheck,Memcheck:Overlap fun:strcpy fun:realpath* } { strlen/decompose_rpath/_dl_map_object Memcheck:Cond fun:strlen fun:decompose_rpath fun:*dl_map_object* } { stpcpy/_dl_sym* Memcheck:Cond fun:__stpcpy fun:_dl_* } #-------- For R H 8.0 { elf_dynamic_do_rel.7/_dl_relocate_object_internal/dl_open_worker(Cond) Memcheck:Cond fun:elf_dynamic_do_rel.7 fun:_dl_relocate_object_internal fun:dl_open_worker } { dl_relocate/dl_open_worker Memcheck:Cond fun:_dl_relocate_object_internal fun:dl_open_worker } ##----------------------------------------------------------------------## ## For a leak in Valgrind's own libpthread.so :( { my_malloc/get_or_allocate_specifics_ptr/__pthread_key_create(Leak) Memcheck:Leak fun:my_malloc fun:get_or_allocate_specifics_ptr fun:__pthread_key_create } ##----------------------------------------------------------------------## ## Bugs in helper library supplied with Intel Icc 7.0 (65) ## in /opt/intel/compiler70/ia32/lib/libcxa.so.3 { Intel compiler70/ia32/lib/libcxa.so.3 below-esp accesses Addrcheck,Memcheck:Addr4 obj:/opt/intel/compiler70/ia32/lib/libcxa.so.3 } ##----------------------------------------------------------------------## # Errors to suppress by default with XFree86 4.1.0) # Format of this file is: # { # name_of_suppression # skin_name:supp_kind # (optional extra info for some suppression types) # caller0 name, or /name/of/so/file.so # caller1 name, or ditto # (optionally: caller2 name) # (optionally: caller3 name) # } # # For memcheck, the supp_kinds are: # # Param Value1 Value2 Value4 Value8 Value16 # Free Addr1 Addr2 Addr4 Addr8 Addr16 # Cond (previously known as Value0) # # and the optional extra info is: # if Param: name of system call param # if Free: name of free-ing fn) # Resulting from R H 8.0 { *libc_write/libX11.so.6.2/*X11TransWrite(Param) Addrcheck,Memcheck:Param write(buf) fun:*libc_write obj:/usr/X11R6/lib/libX11.so.6.2 fun:*X11TransWrite } { libX11.so.6.2/libX11.so.6.2/libX11.so.6.2(Cond) Memcheck:Cond obj:/usr/X11R6/lib/libX11.so.6.2 obj:/usr/X11R6/lib/libX11.so.6.2 obj:/usr/X11R6/lib/libX11.so.6.2 } { libXt.so.6.2/libXt.so.6.2/libXt.so.6.2(Cond) Memcheck:Cond obj:/usr/X11R6/lib/libXt.so.6.0 obj:/usr/X11R6/lib/libXt.so.6.0 obj:/usr/X11R6/lib/libXt.so.6.0 } { libXaw.so.7.0/libXaw.so.7.0/libXaw.so.7.0(Cond) Memcheck:Cond obj:/usr/X11R6/lib/libXaw.so.7.0 obj:/usr/X11R6/lib/libXaw.so.7.0 obj:/usr/X11R6/lib/libXaw.so.7.0 } { libXmu.so.6.2/libXmu.so.6.2/libXmu.so.6.2(Cond) Memcheck:Cond obj:/usr/X11R6/lib/libXmu.so.6.2 obj:/usr/X11R6/lib/libXmu.so.6.2 obj:/usr/X11R6/lib/libXmu.so.6.2 } { libXt.so.6.0/libXt.so.6.0/libXaw.so.7.0(Cond) Memcheck:Cond obj:/usr/X11R6/lib/libXt.so.6.0 obj:/usr/X11R6/lib/libXt.so.6.0 obj:/usr/X11R6/lib/libXaw.so.7.0 } { libXaw.so.7.0/libXaw.so.7.0/libXt.so.6.0(Value4) Memcheck:Value4 obj:/usr/X11R6/lib/libXaw.so.7.0 obj:/usr/X11R6/lib/libXaw.so.7.0 obj:/usr/X11R6/lib/libXt.so.6.0 } { libXaw.so.7.0/libXaw.so.7.0/libXt.so.6.0(Cond) Memcheck:Cond obj:/usr/X11R6/lib/libXaw.so.7.0 obj:/usr/X11R6/lib/libXaw.so.7.0 obj:/usr/X11R6/lib/libXt.so.6.0 } { libX11.so.6.2/libX11.so.6.2/libXaw.so.7.0(Cond) Memcheck:Cond obj:/usr/X11R6/lib/libX11.so.6.2 obj:/usr/X11R6/lib/libX11.so.6.2 obj:/usr/X11R6/lib/libXaw.so.7.0 } { libX11.so.6.2/libXaw.so.7.0/libXaw.so.7.0(Cond) Memcheck:Cond obj:/usr/X11R6/lib/libX11.so.6.2 obj:/usr/X11R6/lib/libXaw.so.7.0 obj:/usr/X11R6/lib/libXaw.so.7.0 } { libXpm.so.4.11/libXpm.so.4.11/libXpm.so.4.11 Memcheck:Cond obj:/usr/X11R6/lib/libXpm.so.4.11 obj:/usr/X11R6/lib/libXpm.so.4.11 obj:/usr/X11R6/lib/libXpm.so.4.11 } ##----------------------------------------------------------------------## ##----------------------------------------------------------------------## # Errors to suppress by default with XFree86 3.3.6) # Format of this file is: # { # name_of_suppression # skin_name:supp_kind # (optional extra info for some suppression types) # caller0 name, or /name/of/so/file.so # caller1 name, or ditto # (optionally: caller2 name) # (optionally: caller3 name) # } # # For Memcheck, the supp_kinds are: # # Param Value1 Value2 Value4 Value8 Value16 # Free Addr1 Addr2 Addr4 Addr8 Addr16 # Cond (previously known as Value0) # # and the optional extra info is: # if Param: name of system call param # if Free: name of free-ing fn) ##----------------------------------------------------------------------## { X11-Cond-0 Memcheck:Cond obj:*libXt.so.6.0 obj:*libXt.so.6.0 obj:*libXt.so.6.0 } { X11-Cond-1 Memcheck:Cond fun:__rawmemchr obj:*libXt.so.6.0 obj:*libXt.so.6.0 } # Suppressions for XFree86-3.3.X { X11-Addr4-1 Addrcheck,Memcheck:Addr4 obj:/usr/X11R6/lib/libX11.so.6.1 obj:/usr/X11R6/lib/libX11.so.6.1 obj:/usr/X11R6/lib/libX11.so.6.1 } { X11-Addr4-2 Addrcheck,Memcheck:Addr4 obj:/usr/X11R6/lib/libX11.so.6.1 obj:/usr/X11R6/lib/libX11.so.6.1 obj:/usr/X11R6/lib/libXt.so.6.0 } { X11-Addr4-3 Addrcheck,Memcheck:Addr4 obj:/usr/X11R6/lib/libXt.so.6.0 obj:/usr/X11R6/lib/libXt.so.6.0 obj:/usr/X11R6/lib/libXt.so.6.0 } { X11-Addr4-4 Addrcheck,Memcheck:Addr4 obj:/usr/X11R6/lib/libX11.so.6.1 obj:/usr/X11R6/lib/libXt.so.6.0 obj:/usr/X11R6/lib/libXt.so.6.0 } { X11-Addr4-5 Addrcheck,Memcheck:Addr4 fun:__rawmemchr obj:/usr/X11R6/lib/libXt.so.6.0 obj:/usr/X11R6/lib/libXt.so.6.0 } { X11-Addr4-6 Addrcheck,Memcheck:Addr4 obj:/usr/X11R6/lib/libXmu.so.6.0 obj:/usr/X11R6/lib/libXmu.so.6.0 obj:/usr/X11R6/lib/libXt.so.6.0 } { X11-Addr4-7 Addrcheck,Memcheck:Addr4 obj:/usr/X11R6/lib/libXt.so.6.0 obj:/usr/X11R6/lib/libXt.so.6.0 obj:/usr/X11R6/lib/libXawXpm_posing_as_Xaw.so.6.1 } { X11-Param-1 Addrcheck,Memcheck:Param write(buf) fun:__libc_write obj:/usr/X11R6/lib/libX11.so.6.1 obj:/usr/X11R6/lib/libX11.so.6.1 } { X11-Addr4-8 Addrcheck,Memcheck:Addr4 obj:/usr/X11R6/lib/libX11.so.6.1 obj:/usr/X11R6/lib/libXpm.so.4.11 obj:/usr/X11R6/lib/libXpm.so.4.11 } { X11-Addr4-8 Addrcheck,Memcheck:Addr4 obj:/usr/X11R6/lib/libXt.so.6.0 obj:/usr/X11R6/lib/libXawXpm_posing_as_Xaw.so.6.1 obj:/usr/X11R6/lib/libXt.so.6.0 } { X11-Addr4-9 Addrcheck,Memcheck:Addr4 obj:/usr/X11R6/lib/libXaw.so.6.1 obj:/usr/X11R6/lib/libXt.so.6.0 obj:/usr/X11R6/lib/libXt.so.6.0 } { X11-Addr4-10 Addrcheck,Memcheck:Addr4 obj:/usr/X11R6/lib/libXaw.so.6.1 obj:/usr/X11R6/lib/libXaw.so.6.1 obj:/usr/X11R6/lib/libXt.so.6.0 } { X11-Addr4-11 Addrcheck,Memcheck:Addr4 obj:/usr/X11R6/lib/libXt.so.6.0 obj:/usr/X11R6/lib/libXt.so.6.0 obj:/usr/X11R6/lib/libXaw.so.6.1 } { Xt-1 Memcheck:Overlap fun:memcpy obj:/usr/X11R6/lib/libXt.so.6.0 fun:_XtGetResources obj:/usr/X11R6/lib/libXt.so.6.0 } { Xt-2 Memcheck:Overlap fun:memcpy obj:/usr/X11R6/lib/libXt.so.6.0 fun:_XtGetSubresources fun:XtGetSubresources } { Xt-3 Memcheck:Cond obj:/usr/X11R6/lib/libXm.so.3.0.1 obj:/usr/X11R6/lib/libXm.so.3.0.1 obj:/usr/X11R6/lib/libXm.so.3.0.1 obj:/usr/X11R6/lib/libXm.so.3.0.1 } { Xt-4 Memcheck:Cond obj:/usr/X11R6/lib/libXm.so.3.0.1 obj:/usr/X11R6/lib/libXm.so.3.0.1 obj:/usr/X11R6/lib/libXm.so.3.0.1 fun:_XtMakeGeometryRequest } { Xt-5 Memcheck:Cond fun:_XtMakeGeometryRequest fun:* obj:/usr/X11R6/lib/libXm.so.3.0.1 obj:/usr/X11R6/lib/libXm.so.3.0.1 } { Xt-6 Memcheck:Param write(buf) fun:__write_nocancel obj:/usr/X11R6/lib/libX11.so.6.2 fun:_X11TransWrite obj:/usr/X11R6/lib/libX11.so.6.2 } { X11-1 Memcheck:Param writev(vector[...]) fun:vgAllRoadsLeadToRome_writev fun:__writev obj:/usr/X11R6/lib/libX11.so.6.2 fun:_X11TransWritev } { Xm-1 Memcheck:Addr4 fun:_XmTextFindScroll obj:/usr/X11R6/lib/libXm.so.3.0.1 obj:/usr/X11R6/lib/libXm.so.3.0.1 obj:/usr/X11R6/lib/libXm.so.3.0.1 } { Xm-2 Memcheck:Cond fun:_XmTextFindScroll obj:/usr/X11R6/lib/libXm.so.3.0.1 obj:/usr/X11R6/lib/libXm.so.3.0.1 obj:/usr/X11R6/lib/libXm.so.3.0.1 } { Xm-3 Memcheck:Cond obj:/usr/X11R6/lib/libXm.so.3.0.1 fun:_XmTextShowPosition fun:XmTextShowPosition fun:command_return } { Xm-4 Memcheck:Addr4 fun:XmRenderTableGetRendition fun:help_font fun:help_text_width fun:word_wrap } { Xbug-1 Memcheck:Addr1 obj:/usr/X11R6/lib/libX11.so.6.2 fun:change_pixmap_background fun:make_sound_icons_transparent_again fun:g_set_basic_color } { Xbug-2 Memcheck:Param write(buf) fun:__GI___libc_write fun:_X11TransWrite obj:/usr/X11R6/lib/libX11.so.6.2 fun:_XFlush } { Xbug-3 Memcheck:Param write(buf) fun:__GI___libc_write fun:_X11TransWrite obj:/usr/X11R6/lib/libX11.so.6.2 fun:_XReply } { Xm-5 Memcheck:Cond obj:/usr/X11R6/lib/libXm.so.3.0.1 fun:_XmTextShowPosition fun:XmTextShowPosition fun:listener_append_and_prompt } { Xm-6 Memcheck:Cond fun:strlen fun:_XmStringNCreate fun:XmStringCreate fun:set_label } { Xm-7 Memcheck:Cond fun:XTextExtents obj:/usr/X11R6/lib/libXm.so.3.0.1 obj:/usr/X11R6/lib/libXm.so.3.0.1 fun:XmStringExtent } { Xm-8 Memcheck:Value4 fun:XTextExtents obj:/usr/X11R6/lib/libXm.so.3.0.1 obj:/usr/X11R6/lib/libXm.so.3.0.1 fun:XmStringExtent } { Xm-9 Memcheck:Cond fun:XInsertModifiermapEntry fun:gxm_XInsertModifiermapEntry fun:* } { Xm-10 Memcheck:Cond fun:XmStringTableProposeTablist fun:gxm_XmStringTableProposeTablist fun:* } { Xm-11 Memcheck:Addr4 fun:XmRenderTableCvtFromProp fun:gxm_XmRenderTableCvtFromProp fun:* } { Xm-12 Memcheck:Cond fun:XDeleteModifiermapEntry fun:gxm_XDeleteModifiermapEntry fun:* } { Xm-13 Memcheck:Addr1 obj:/usr/X11R6/lib/libXm.so.3.0.1 obj:/usr/X11R6/lib/libXm.so.3.0.1 fun:XmCvtByteStreamToXmString fun:XmStringNCopy } { Xm-14 Memcheck:Addr1 obj:/usr/X11R6/lib/libXm.so.3.0.1 fun:XmCvtByteStreamToXmString fun:XmStringNCopy fun:XmStringNConcat } { Xm-15 Memcheck:Addr1 fun:strncmp fun:_XmStringIndexCacheTag fun:_XmStringCacheTag obj:/usr/X11R6/lib/libXm.so.3.0.1 } { Glibc-1 Memcheck:Cond fun:strlen fun:_IO_str_init_static_internal fun:_IO_vsscanf fun:__GI_sscanf } { Glibc-2 Memcheck:Value4 fun:_IO_vfprintf_internal fun:* } { Glibc-3 Memcheck:Cond fun:_IO_vfprintf_internal fun:* } { Glibc-4 Memcheck:Cond fun:_IO_vfscanf_internal fun:_IO_vsscanf fun:__GI_sscanf fun:* } # -------------------------------------------------------------------------------- # I don't think any of these are actually my bugs -- everything is initialized and so forth in my code { snd-1 Memcheck:Value4 fun:_IO_vfscanf_internal fun:_IO_vsscanf fun:__GI_sscanf fun:read_nist_header } { snd-2 Memcheck:Cond fun:_IO_sputbackc_internal fun:_IO_vfscanf_internal fun:_IO_vsscanf fun:__GI_sscanf } { snd-4 Memcheck:Cond fun:rawmemchr fun:_IO_vsscanf fun:__GI_sscanf fun:read_nist_header } { snd-5 Memcheck:Cond fun:rawmemchr fun:_IO_vsscanf fun:__GI_sscanf fun:read_nist_header } # ==4291== Syscall param statfs64(buf) contains unaddressable byte(s) # ==4291== at 0x1C051B9F: statfs64 (in /lib/tls/libc-2.3.3.so) # ==4291== by 0x80D4E59: disk_kspace (snd-file.c:63) # ==4291== by 0x80B8215: close_temp_file (snd-io.c:580) # ==4291== by 0x80ED0C0: snd_make_file (snd-edits.c:4387) # ==4291== Address 0x54 is not stack'd, malloc'd or (recently) free'd { snd-6 Memcheck:Param statfs64(buf) fun:statfs64 fun:disk_kspace fun:* } # ==4291== Conditional jump or move depends on uninitialised value(s) # ==4291== at 0x80D4E79: disk_kspace (snd-file.c:68) # ==4291== by 0x80B8215: close_temp_file (snd-io.c:580) # ==4291== by 0x80ED0C0: snd_make_file (snd-edits.c:4387) # ==4291== by 0x80F4DB0: save_edits_without_display (snd-edits.c:6915) { snd-7 Memcheck:Cond fun:disk_kspace fun:* } # ==4291== Use of uninitialised value of size 4 # ==4291== at 0x80D4EB8: disk_kspace (snd-file.c:70) # ==4291== by 0x80B8215: close_temp_file (snd-io.c:580) # ==4291== by 0x80ED0C0: snd_make_file (snd-edits.c:4387) # ==4291== by 0x80F4DB0: save_edits_without_display (snd-edits.c:6915) { snd-8 Memcheck:Value4 fun:disk_kspace fun:* } # ==4291== Use of uninitialised value of size 8 # ==4291== at 0x80D4EC1: disk_kspace (snd-file.c:70) # ==4291== by 0x80B8215: close_temp_file (snd-io.c:580) # ==4291== by 0x80ED0C0: snd_make_file (snd-edits.c:4387) # ==4291== by 0x80F4DB0: save_edits_without_display (snd-edits.c:6915) { snd-10 Memcheck:Value8 fun:disk_kspace fun:* } { gtk-1 Memcheck:Addr1 fun:g_option_context_parse fun:gtk_parse_args fun:* } { gtk-3 Memcheck:Cond fun:g_strdup fun:* } { gtk-3111 Memcheck:Leak fun:malloc fun:g_malloc fun:* } { gtk-3112 Memcheck:Leak fun:calloc fun:g_malloc0 fun:* } { gtk-315 Memcheck:Leak fun:malloc fun:cairo_font_options_copy fun:* } { gtk-317 Memcheck:Leak fun:malloc fun:cairo_font_options_create fun:* } { gtk-320 Memcheck:Leak fun:malloc fun:FT_New_Memory fun:* } { gtk-321 Memcheck:Leak fun:malloc fun:ft_mem_qalloc fun:* } { gtk-322 Memcheck:Leak fun:calloc fun:XkbGetMap fun:* } { gtk-329 Memcheck:Leak fun:calloc fun:XkbGetNames fun:* } { gtk-323 Memcheck:Leak fun:calloc fun:XkbAllocServerMap fun:* } { gtk-324 Memcheck:Leak fun:malloc fun:XOpenDevice fun:* } { gtk-325 Memcheck:Leak fun:calloc fun:_XkbReadGetMapReply fun:* } { gtk-326 Memcheck:Leak fun:memalign fun:posix_memalign fun:* } { gtk-327 Memcheck:Leak fun:calloc fun:XkbAllocClientMap fun:* } { gtk-319 Memcheck:Leak fun:realloc fun:g_realloc fun:* } { gtk-318 Memcheck:Leak fun:malloc fun:FcPatternCreate fun:* } { gtk-316 Memcheck:Leak fun:realloc fun:g_realloc fun:* } { gtk-311 Memcheck:Leak fun:malloc fun:g_malloc fun:g_strdup fun:* } { gtk-312 Memcheck:Leak fun:malloc fun:g_malloc fun:g_pattern_spec_new fun:* } { gtk-313 Memcheck:Leak fun:malloc fun:g_malloc fun:g_strjoinv fun:* } { gtk-314 Memcheck:Leak fun:malloc fun:realloc fun:g_realloc fun:* } { gtk-4 Memcheck:Cond fun:g_utf8_validate fun:pango_layout_set_text fun:* } { gtk-000 Memcheck:Leak fun:malloc fun:XInitExtension fun:* } { snd-000 Memcheck:Leak fun:malloc fun:new_xen_transform } { gtk-5 Memcheck:Value4 fun:g_strdup fun:gtk_label_set_text fun:* } { gtk-6 Memcheck:Value4 fun:g_strdup fun:gtk_label_recalculate fun:* } { gtk-7 Memcheck:Value4 fun:ps_set_color fun:* } { gtk-10 Memcheck:Addr4 fun:gtk_file_filter_set_name fun:* } { gtk-11 Memcheck:Addr4 fun:gtk_file_filter_add_mime_type fun:* } { gtk-12 Memcheck:Addr4 fun:gtk_file_filter_add_pattern fun:* } { gtk-13 Memcheck:Cond fun:gtk_entry_insert_text fun:* } { ladspa-1 Memcheck:Free fun:__builtin_vec_delete fun:* obj:/home/bil/test/ladspa_sdk/plugins/sine.so } # ==6650== 4080 bytes in 255 blocks are definitely lost in loss record 394 of 448 # ==6650== at 0x40029B2A: calloc (vg_replace_malloc.c:284) # ==6650== by 0x81CD4AC: make_xen_value (snd-run.c:521) # ==6650== by 0x81D2535: add_global_var_to_ptree (snd-run.c:2094) # ==6650== by 0x8211920: walk (snd-run.c:10240) # but I don't immediately see why... { gtk-14 Memcheck:Addr4 fun:gtk_file_filter_get_needed fun:* } { gtk-15 Memcheck:Addr4 fun:g_type_check_instance_is_a fun:gtk_file_filter_set_name fun:gxg_gtk_file_filter_set_name fun:* } { gtk-16 Memcheck:Addr4 fun:g_type_check_instance_is_a fun:gtk_file_filter_add_mime_type fun:gxg_gtk_file_filter_add_mime_type fun:* } { gtk-17 Memcheck:Addr4 fun:g_type_check_instance_is_a fun:gtk_file_filter_add_pattern fun:gxg_gtk_file_filter_add_pattern fun:* } { gtk-18 Memcheck:Cond fun:pango_attr_list_change fun:gxg_pango_attr_list_change fun:* } { gtk-19 Memcheck:Cond fun:pango_attr_list_insert_internal fun:pango_attr_list_insert fun:gxg_pango_attr_list_insert fun:* } { gtk-20 Memcheck:Cond fun:pango_attr_list_insert_internal fun:pango_attr_list_insert_before fun:gxg_pango_attr_list_insert_before fun:* } { gtk-21 Memcheck:Cond fun:pango_attr_list_change fun:pango_attr_list_splice fun:gxg_pango_attr_list_splice fun:* } { gtk-22 Memcheck:Cond fun:pango_attr_iterator_next fun:pango_attr_list_get_iterator fun:gxg_pango_attr_list_get_iterator fun:* } { gtk-23 Memcheck:Cond fun:pango_attr_iterator_next fun:gxg_pango_attr_iterator_next fun:* } { gtk-24 Memcheck:Cond fun:pango_xft_font_get_glyph_extents fun:pango_font_get_glyph_extents fun:pango_glyph_string_extents_range fun:pango_glyph_string_extents } { gtk-25 Memcheck:Cond fun:pango_glyph_string_extents_range fun:pango_glyph_string_extents fun:gxg_pango_glyph_string_extents fun:* } { gtk-26 Memcheck:Cond fun:XftFontCheckGlyph fun:XftGlyphExtents fun:get_glyph_extents_xft fun:pango_font_get_glyph_extents } { gtk-27 Memcheck:Cond fun:XftGlyphExtents fun:get_glyph_extents_xft fun:pango_font_get_glyph_extents fun:pango_glyph_string_extents_range } { gtk-28 Memcheck:Addr1 fun:gdk_rgb_convert_0888 fun:gdk_draw_rgb_image_core fun:gdk_draw_rgb_image fun:gxg_gdk_draw_rgb_image } { gtk-29 Memcheck:Addr1 fun:gdk_rgb_32_to_stage fun:gdk_rgb_convert_32_generic fun:gdk_draw_rgb_image_core fun:gdk_draw_rgb_32_image } { gtk-30 Memcheck:Addr4 fun:gtk_icon_size_register_alias fun:gxg_gtk_icon_size_register_alias fun:* } { gtk-31 Memcheck:Cond fun:pango_font_description_from_string fun:* } { gtk-32 Memcheck:Value4 fun:pango_font_description_from_string fun:* } { gtk-33 Memcheck:Value4 fun:getword fun:pango_font_description_from_string fun:* } { gtk-34 Memcheck:Value4 fun:__GI___strtod_internal fun:g_ascii_strtod fun:pango_font_description_from_string fun:* } { gtk-35 Memcheck:Cond fun:__GI___strtod_internal fun:g_ascii_strtod fun:pango_font_description_from_string fun:* } { gtk-36 Memcheck:Value4 fun:__GI___strtod_internal fun:g_ascii_strtod fun:pango_font_description_from_string fun:* } { gtk-37 Memcheck:Cond fun:g_ascii_strcasecmp fun:find_field_any fun:pango_font_description_from_string fun:* } { gtk-38 Memcheck:Cond fun:find_field_any fun:pango_font_description_from_string fun:* } { gtk-39 Memcheck:Cond fun:g_ascii_strncasecmp fun:find_field fun:find_field_any fun:pango_font_description_from_string } { gtk-40 Memcheck:Cond fun:find_field fun:find_field_any fun:pango_font_description_from_string fun:* } { gtk-41 Memcheck:Cond fun:strncpy fun:g_strndup fun:pango_font_description_from_string fun:* } { ruby-1 Memcheck:Cond fun:mark_locations_array fun:rb_gc fun:* } { ruby-2 Memcheck:Cond fun:rb_gc_mark fun:mark_locations_array fun:* } { ruby-3 Memcheck:Value4 fun:rb_gc_mark fun:mark_locations_array fun:* } { ruby-4 Memcheck:Value4 fun:st_lookup fun:rb_mark_generic_ivar fun:rb_gc_mark fun:* } { ruby-5 Memcheck:Cond fun:st_lookup fun:rb_mark_generic_ivar fun:rb_gc_mark fun:* } { ruby-6 Memcheck:Cond fun:rb_gc_mark_children fun:mark_locations_array fun:* } { ruby-7 Memcheck:Value4 fun:rb_gc_mark_children fun:mark_locations_array fun:* } { r1 Memcheck:Cond obj:/usr/lib/libruby.so.1.8.4 obj:* } { r2 Memcheck:Cond obj:/usr/lib/libruby.so.1.8.4 obj:/usr/lib/libruby.so.1.8.4 obj:/usr/lib/libruby.so.1.8.4 obj:/usr/lib/libruby.so.1.8.4 fun:rb_newobj obj:/usr/lib/libruby.so.1.8.4 fun:rb_hash_new fun:* } { r3 Memcheck:Value4 obj:/usr/lib/libruby.so.1.8.4 obj:* } { r4 Memcheck:Value4 obj:/usr/lib/libruby.so.1.8.4 obj:/usr/lib/libruby.so.1.8.4 fun:rb_gc_mark_locations obj:/usr/lib/libruby.so.1.8.4 fun:rb_newobj fun:* } { r5 Memcheck:Value4 obj:/usr/lib/libruby.so.1.8.4 obj:/usr/lib/libruby.so.1.8.4 obj:/usr/lib/libruby.so.1.8.4 obj:/usr/lib/libruby.so.1.8.4 fun:rb_newobj fun:* } { r6 Memcheck:Cond fun:mark_current_machine_context fun:garbage_collect fun:rb_newobj fun:* } { r7 Memcheck:Cond fun:gc_mark_children fun:mark_current_machine_context fun:garbage_collect fun:rb_newobj fun:* } { r8 Memcheck:Value8 fun:mark_current_machine_context fun:garbage_collect fun:rb_newobj fun:* } { r9 Memcheck:Value8 fun:gc_mark_children fun:mark_current_machine_context fun:garbage_collect fun:rb_newobj fun:* } { r10 Memcheck:Cond fun:mark_current_machine_context fun:garbage_collect fun:rb_node_newnode fun:* } { r11 Memcheck:Value8 fun:mark_current_machine_context fun:garbage_collect fun:rb_node_newnode fun:* } { r12 Memcheck:Cond fun:gc_mark_children fun:mark_current_machine_context fun:garbage_collect fun:rb_node_newnode fun:* } { r13 Memcheck:Value8 fun:gc_mark_children fun:mark_current_machine_context fun:garbage_collect fun:rb_node_newnode fun:* } # addcheck { addr1 Addrcheck:Overlap fun:memcpy obj:/usr/X11R6/lib/libXt.so.6.0 fun:_XtGetResources } { addr2 Addrcheck:Overlap fun:memcpy obj:/usr/X11R6/lib/libXt.so.6.0 fun:_XtGetSubresources fun:XtGetSubresources } { mem-1 Memcheck:Leak fun:malloc fun:_XlcDefaultMapModifiers fun:XSetLocaleModifiers obj:/usr/X11R6/lib/libXt.so.6.0 } { mem-2 Memcheck:Leak fun:malloc obj:/usr/X11R6/lib/X11/locale/lib/common/ximcp.so.2 fun:_XimOpenIM obj:/usr/X11R6/lib/libX11.so.6.2 } { mem-3 Memcheck:Leak fun:malloc obj:/usr/X11R6/lib/libX11.so.6.2 obj:/usr/X11R6/lib/libX11.so.6.2 fun:_X11TransOpenCOTSClient } { mem-4 Memcheck:Leak fun:malloc obj:/usr/X11R6/lib/libX11.so.6.2 obj:/usr/X11R6/lib/libX11.so.6.2 fun:XrmPutLineResource } { mem-5 Memcheck:Leak fun:malloc obj:/usr/X11R6/lib/X11/locale/lib/common/ximcp.so.2 fun:_XimOpenIM obj:/usr/X11R6/lib/libX11.so.6.2 } { mem-6 Memcheck:Leak fun:malloc fun:_XimOpenIM obj:/usr/X11R6/lib/libX11.so.6.2 fun:XOpenIM } { mem-7 Memcheck:Leak fun:malloc fun:_XimOpenIM obj:/usr/X11R6/lib/libX11.so.6.2 fun:XOpenIM } { mem-8 Memcheck:Leak fun:malloc fun:_X11TransConnectDisplay fun:XOpenDisplay fun:* } { mem-9 Memcheck:Leak fun:malloc fun:_XlcCreateLC fun:_XlcDefaultLoader fun:_XlcDynamicLoad } { mem-10 Memcheck:Leak fun:realloc obj:/usr/X11R6/lib/libX11.so.6.2 obj:/usr/X11R6/lib/libX11.so.6.2 obj:/usr/X11R6/lib/libX11.so.6.2 } { mem-11 Memcheck:Leak fun:malloc fun:XCreateRegion fun:* } { mem-12 Memcheck:Leak fun:malloc obj:/usr/X11R6/lib/libX11.so.6.2 obj:/usr/X11R6/lib/libX11.so.6.2 fun:XrmCombineFileDatabase } { mem-13 Memcheck:Leak fun:malloc fun:_XrmDefaultInitParseInfo fun:_XrmInitParseInfo obj:/usr/X11R6/lib/libX11.so.6.2 } { mem-14 Memcheck:Leak fun:malloc obj:/usr/X11R6/lib/libX11.so.6.2 obj:/usr/X11R6/lib/libX11.so.6.2 obj:/usr/X11R6/lib/libX11.so.6.2 } { mem-17 Memcheck:Leak fun:malloc fun:_XOpenLC fun:_XrmInitParseInfo obj:/usr/X11R6/lib/libX11.so.6.2 } { mem-18 Memcheck:Leak fun:malloc obj:/usr/X11R6/lib/libX11.so.6.2 fun:_XlcCreateLC fun:_XlcDefaultLoader } { mem-19 Memcheck:Leak fun:malloc fun:XtMalloc fun:XmRenderTableCopy fun:* } { mem20 Memcheck:Leak fun:malloc fun:XtMalloc fun:_XmCachePixmap fun:* } { mem21 Memcheck:Leak fun:malloc fun:XtMalloc fun:Xm* } { mem22 Memcheck:Leak fun:malloc fun:XtMalloc fun:_XmStringSourceCreate } { mem24 Memcheck:Leak fun:malloc fun:XtMalloc fun:Xt* } { mem25 Memcheck:Leak fun:malloc fun:XtMalloc fun:_Xm* } { alsa-1 Memcheck:Leak fun:malloc fun:strdup obj:/lib64/libasound.so.2.0.0 obj:* fun:* } { alsa-2 Memcheck:Leak fun:malloc obj:/lib64/libasound.so.2.0.0 obj:* fun:* } { alsa-3 Memcheck:Leak fun:calloc obj:/lib64/libasound.so.2.0.0 obj:* fun:* } { transform-1 Memcheck:Leak fun:malloc fun:xen_transform_make fun:* } { colormap-1 Memcheck:Leak fun:malloc fun:xen_colormap_make fun:* } { mem27 Memcheck:Leak fun:malloc fun:XtMalloc obj:/usr/X11R6/lib/libXm.so.3.0.1 fun:Xm* } { mem28 Memcheck:Leak fun:calloc fun:XtCalloc obj:/usr/X11R6/lib/libXm.so.3.0.1 obj:/usr/X11R6/lib/libXt.so.6.0 } { s71a Memcheck:Leak fun:alloc_pointer fun:s7_make_permanent_string fun:* } { s71a1 Memcheck:Leak fun:malloc fun:s7_init fun:* } { s71a11 Memcheck:Leak fun:malloc fun:new_symbol fun:* } { s71ab Memcheck:Leak fun:calloc fun:alloc_pointer fun:* } { s71af Memcheck:Leak fun:calloc fun:store_choices fun:* } { s71abcd Memcheck:Leak fun:calloc fun:s7_make_function fun:* } { s71abcd1 Memcheck:Leak fun:malloc fun:s7_make_function fun:* } { s71abcde Memcheck:Leak fun:calloc fun:make_permanent_string fun:* } { s71abcde Memcheck:Leak fun:malloc fun:make_permanent_string fun:* } { s71abcde1 Memcheck:Leak fun:malloc fun:s7_make_permanent_string fun:* } { s71abcde1 Memcheck:Leak fun:calloc fun:init_ctables fun:* } { s71abcde1 Memcheck:Leak fun:malloc fun:copy_string_with_length fun:copy_string fun:s7_define_constant_with_documentation fun:* } { s71abcde2 Memcheck:Leak fun:malloc fun:make_permanent_string_with_length fun:* } { s71abcde3 Memcheck:Leak fun:malloc fun:make_permanent_string_with_length_and_hash fun:* } { s71abcdef Memcheck:Leak fun:calloc fun:s7_make_permanent_string fun:* } { s71abc Memcheck:Leak fun:calloc fun:make_choices fun:* } { s71abcd Memcheck:Leak fun:malloc fun:copy_string_with_len fun:* } { s71ac Memcheck:Leak fun:malloc fun:alloc_pointer fun:* } { s71aa Memcheck:Leak fun:calloc fun:make_permanent_integer fun:* } { s71b Memcheck:Leak fun:alloc_pointer fun:s7_remove_from_heap fun:* } { s71 Memcheck:Leak fun:calloc fun:s7_remove_from_heap fun:* } { s72 Memcheck:Leak fun:malloc fun:s7_remove_from_heap fun:* } { s73 Memcheck:Leak fun:realloc fun:s7_remove_from_heap fun:* } { s76 Memcheck:Leak fun:malloc fun:s7_make_string_with_length fun:* } { s77 Memcheck:Leak fun:malloc fun:copy_string_with_len fun:copy_string fun:make_standard_ports fun:s7_init fun:s7_xen_initialize } { walker-1 Memcheck:Leak fun:calloc fun:make_walker fun:* } { walker-2 Memcheck:Leak fun:calloc fun:walker_with_declare fun:* } { pws-1 Memcheck:Leak fun:malloc fun:copy_string_with_len fun:copy_string fun:s7_dilambda fun:* } { pws-2 Memcheck:Leak fun:calloc fun:s7_dilambda fun:* } { s75 Memcheck:Leak fun:calloc fun:permanent_calloc fun:* } { Xm_entry Memcheck:Addr8 fun:_XmEntryTextGet fun:_XmStringDrawSegment fun:* } { run-1 Memcheck:Leak fun:malloc fun:make_walker } { run-1a Memcheck:Leak fun:calloc fun:clm_make_function fun:* } { run-2 Memcheck:Leak fun:calloc fun:add_clm_type fun:g_add_clm_field fun:g_add_clm_field_w fun:eval fun:s7_load } { xmn1 Memcheck:Cond fun:XmRenderTableCopy fun:* } { xn1 Memcheck:Param write(buf) fun:__write_nocancel fun:_X11TransWrite fun:* } { xn2 Memcheck:Cond fun:_XmXftDrawCreate fun:* } { xmn2 Memcheck:Cond fun:XmRenderTableFree fun:* } { xn3 Memcheck:Param writev(vector[...]) fun:writev obj:/usr/lib/libX11.so.6.2.0 fun:_X11TransWritev fun:* } { xmn3 Memcheck:Cond fun:XmRenderTableAddRenditions fun:* } { g1 Memcheck:Cond fun:XInitImage obj:* } { xmn4 Memcheck:Cond fun:MakePositionVisible fun:_XmTextShowPosition fun:* } { lad1 Memcheck:Free fun:__builtin_vec_delete fun:__static_initialization_and_destruction_0 fun:* } { xmn5 Memcheck:Cond fun:MakePositionVisible fun:* } { xmn6 Memcheck:Cond fun:_XmRenderTableRemoveRenditions fun:* } { xmn7 Memcheck:Addr1 fun:_read_asn1_length fun:XmStringNCopy fun:* } { xmn8 Memcheck:Addr1 fun:XmCvtByteStreamToXmString fun:XmStringNCopy fun:* } { xmn9 Memcheck:Addr1 fun:strncmp fun:_XmStringIndexCacheTag fun:* } { xmn10 Memcheck:Addr1 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:gxm_XSubImage fun:* } { xmn11 Memcheck:Addr1 obj:/usr/lib/libXm.so.4.0.0 fun:XmStringNCopy fun:XmStringNConcat fun:* } { xmn12 Memcheck:Cond obj:/usr/lib/libXm.so.4.0.0 obj:/usr/lib/libXm.so.4.0.0 obj:/usr/lib/libXm.so.4.0.0 fun:_XtMakeGeometryRequest fun:* } { xmn13 Memcheck:Cond fun:_XtMakeGeometryRequest fun:* } { gl1 Memcheck:Cond fun:smooth_8R8G8B_z_triangle fun:_swrast_validate_triangle fun:_swrast_Triangle fun:* } { gl2 Memcheck:Cond fun:smooth_8R8G8B_z_triangle fun:_swrast_Triangle fun:* } { gl3 Memcheck:Cond fun:_swrast_depth_test_span fun:_swrast_write_rgba_span fun:* } { xmn14 Memcheck:Cond obj:/usr/lib/libXm.so.4.0.0 fun:_XmTextShowPosition fun:* } { init-1 Memcheck:Leak fun:calloc fun:g_init_edits fun:* } { init-2 Memcheck:Leak fun:malloc fun:make_vector_1 fun:s7_make_and_fill_vector fun:define_procedures fun:* } { init-3 Memcheck:Leak fun:malloc fun:XtMalloc fun:CopyRendition fun:XmRenderTableAddRenditions fun:get_xm_font fun:* } { init-4 Memcheck:Leak fun:malloc fun:s7_make_terminated_string_with_length fun:read_string_constant fun:eval fun:s7_eval_c_string fun:Init_libxm fun:* } { init-5 Memcheck:Leak fun:calloc fun:XtCalloc fun:XmSetToolTipString fun:* } { init-6 Memcheck:Leak fun:malloc fun:__gmp_default_allocate fun:* } { init-7 Memcheck:Leak fun:malloc fun:XtMalloc fun:LookupContextBlock fun:* } { init-8 Memcheck:Leak fun:malloc fun:xen_make_vct fun:g_init_edits fun:* } { init-9 Memcheck:Leak fun:realloc fun:XtRealloc fun:* } { init-10 Memcheck:Leak fun:calloc fun:XtCalloc fun:CreateInfo fun:* } { init-11 Memcheck:Leak fun:calloc fun:XtCalloc fun:InsertInfo fun:* } { init-12 Memcheck:Leak fun:malloc fun:XtMalloc fun:InitializePrehook fun:* } { init-13 Memcheck:Leak fun:malloc fun:XCreateGC fun:* } { init-14 Memcheck:Leak fun:malloc obj:/usr/lib64/libX11.so.6.3.0 fun:XLoadQueryFont fun:* } { init-15 Memcheck:Leak fun:malloc fun:XtMalloc fun:InitializeImageSet fun:* } { heap-1 Memcheck:Leak fun:calloc fun:s7_init fun:s7_xen_initialize fun:xen_initialize fun:main } { init-16 Memcheck:Leak fun:calloc fun:gxm_XGCValues fun:* } snd-16.1/tools/gtest.scm0000644000076400007640000001206312327744263013341 0ustar bilbil;;; glistener test suite ;;; see gcall.c (set-prompt *g2* "!!") (define (simple-test expr rtn) (clear *g2*) (let ((bpos (cursor-position *g2*)) (len (length expr))) (append-text *g2* expr) (if (char-whitespace? (expr 0)) (begin (set-cursor-position *g2* bpos) (evaluate *g2*))) (do ((i bpos (+ i 1))) ((> i (+ bpos len))) (set-cursor-position *g2* i) (let ((result (evaluate *g2*))) (if (not (string=? result rtn)) (append-text *g1* (format #f "~%~S, cursor at ~D:~%~S~%~S~%" expr i result rtn))))))) (simple-test "(+ 1 2)" "(+ 1 2)\n3") (simple-test "#\\a" "#\\a\n#\\a") (simple-test "#\\x12" "#\\x12\n#\\x12") (simple-test "123" "123\n123") (simple-test "1.5+i" "1.5+i\n1.5+1i") (simple-test "\"asdf\"" "\"asdf\"\n\"asdf\"") (simple-test "\"as df\"" "\"as df\"\n\"as df\"") (simple-test "1/2" "1/2\n1/2") (simple-test "'(+ 1 2)" "'(+ 1 2)\n(+ 1 2)") (simple-test "\"12;34\"" "\"12;34\"\n\"12;34\"") (simple-test "#(1 2)" "#(1 2)\n#(1 2)") (simple-test ":hi" ":hi\n:hi") (simple-test "\"\"" "\"\"\n\"\"") (simple-test "()" "()\n()") (simple-test "( )" "( )\n()") (simple-test "'()" "'()\n()") (simple-test "(eqv? #i3/5 #i3/5)" "(eqv? #i3/5 #i3/5)\n#t") (simple-test "*gc-stats*" "*gc-stats*\n#f") (simple-test "#" "#\n#") (simple-test "(cons 1 2)" "(cons 1 2)\n(1 . 2)") (simple-test "(+ 1 (* 2 3))" "(+ 1 (* 2 3))\n7") (simple-test "(char? #\\a)" "(char? #\\a)\n#t") (simple-test "(char? #\\))" "(char? #\\))\n#t") (simple-test "(char? #\\()" "(char? #\\()\n#t") (simple-test "(char? #\\;)" "(char? #\\;)\n#t") (simple-test "(char? #\\\")" "(char? #\\\")\n#t") (simple-test "(char? #\\#)" "(char? #\\#)\n#t") (simple-test "#2d((1 2) (3 4))" "#2d((1 2) (3 4))\n#2D((1 2) (3 4))") (simple-test "`(1 2)" "`(1 2)\n(1 2)") (simple-test "((if (< 3 2) * +) 3 2)" "((if (< 3 2) * +) 3 2)\n5") (simple-test "(if (char? #\\\") 0 1)" "(if (char? #\\\") 0 1)\n0") (simple-test " (+ 1 2) " "(+ 1 2)\n3") (simple-test "(+ #| 1 2 3 |# 4 5)" "(+ #| 1 2 3 |# 4 5)\n9") (simple-test "(char? \"\")" "(char? \"\")\n#f") (simple-test "(equal? \"\" \"\")" "(equal? \"\" \"\")\n#t") (simple-test "\"\"" "\"\"\n\"\"") (simple-test "(#||#)" "(#||#)\n()") (simple-test "(#|()|#)" "(#|()|#)\n()") (simple-test "(#|#\\a|#)" "(#|#\\a|#)\n()") (simple-test "(#|\"\"|#)" "(#|\"\"|#)\n()") (simple-test "(+ 1 #|\"\"|# 2 3)" "(+ 1 #|\"\"|# 2 3)\n6") (simple-test "(char?\n #\\a\n)" "(char?\n #\\a\n)\n#t") (simple-test "(+ 1 2 ; a test\n3)" "(+ 1 2 ; a test\n3)\n6") (simple-test "(+ 1 2 #| a test\n|#3)" "(+ 1 2 #| a test\n|#3)\n6") (simple-test "\"a;b\"" "\"a;b\"\n\"a;b\"") (simple-test "\"a)b\"" "\"a)b\"\n\"a)b\"") (simple-test "\"a(b\"" "\"a(b\"\n\"a(b\"") (simple-test "'(a #|foo|||||# b)" "'(a #|foo|||||# b)\n(a b)") (simple-test "(let ((@,@'[1] 1) (\\,| 2)) (+ @,@'[1] \\,|))" "(let ((@,@'[1] 1) (\\,| 2)) (+ @,@'[1] \\,|))\n3") (simple-test "(length \";\")" "(length \";\")\n1") (simple-test "(cons \";\" 1)" "(cons \";\" 1)\n(\";\" . 1)") (simple-test "(length \")\")" "(length \")\")\n1") (simple-test "\"a\\\"b\"" "\"a\\\"b\"\n\"a\\\"b\"") (simple-test "(length \"#|\")" "(length \"#|\")\n2") (simple-test "(length \"(\")" "(length \"(\")\n1") ; works outside this test?? (simple-test "(length '(#xA\"\"#(1)))" "(length '(#xA\"\"#(1)))\n3") (simple-test "(+ #| 1 ( 2 3 |# 4 5)" "(+ #| 1 ( 2 3 |# 4 5)\n9") (simple-test "(+ #| 1 ; 2 3 |# 4 5)" "(+ #| 1 ; 2 3 |# 4 5)\n9") (simple-test "(map /\"\"'(123))" "(map /\"\"'(123))\n()") (simple-test "(eq? ()#())" "(eq? ()#())\n#f") (simple-test "(eq? \"\"1)" "(eq? \"\"1)\n#f") (simple-test "(eq? #()#())" "(eq? #()#())\n#f") (simple-test "#(#(1) #((1 2)))" "#(#(1) #((1 2)))\n#(#(1) #((1 2)))") (simple-test "'''3" "'''3\n''3") (define (multi-test exprs pos rtn0 rtn1 rtn2) (clear *g2*) (let ((bpos (cursor-position *g2*)) (len (length exprs))) (append-text *g2* exprs) (set-cursor-position *g2* bpos) (let ((result (evaluate *g2*))) (if (not (string=? result rtn0)) (append-text *g1* (format #f "~%~S, cursor at ~D (pos: ~D): ~S~%" exprs bpos pos result)))) (do ((i (+ bpos 1) (+ i 1))) ((> i (+ bpos len))) (set-cursor-position *g2* i) (let ((result (evaluate *g2*))) (if (not (string=? result (if (< (- i bpos) pos) rtn1 rtn2))) (append-text *g1* (format #f "~%~S, cursor at ~D (pos: ~D): ~S~%" exprs i pos result))))))) (multi-test "123 432" 4 "123 432\n123" "123\n123" "432\n432") (multi-test "123 #\\a" 4 "123 #\\a\n123" "123\n123" "#\\a\n#\\a") (multi-test "123 \"a\"" 4 "123 \"a\"\n123" "123\n123" "\"a\"\n\"a\"") (multi-test "(+ 1 2) 123" 9 "(+ 1 2) 123\n3" "(+ 1 2)\n3" "123\n123") (multi-test "(+ 1 2)123" 8 "(+ 1 2)123\n3" "(+ 1 2)\n3" "123\n123") (multi-test "(+ 1 2)(* 2 3)" 8 "(+ 1 2)(* 2 3)\n3" "(+ 1 2)\n3" "(* 2 3)\n6") ;;; gtk_text_buffer_backspace -- try at start and make sure pos unchanged (define (completion-test text rtn) (clear *g2*) (append-text *g2* text) (let ((result (complete *g2*))) (if (not (string=? result rtn)) (append-text *g1* (format #f "~S -> ~S~%" text result))))) (completion-test "(trunc" "(truncate") (completion-test "\"card" "\"cardinal.snd\"") snd-16.1/tools/tcopy.scm0000644000076400007640000001741412606170502013343 0ustar bilbil(let ((new-env (sublet (curlet) (cons 'init_func 'block_init)))) ; load calls init_func if possible (load "s7test-block.so" new-env)) (define (test-copy size) (let ((old-string (make-string size #\a)) (old-bvect (make-byte-vector size 1)) (old-pair (make-list size #\a)) (old-vector (make-vector size #\a)) (old-vectorf (make-vector size 1.0)) (old-vectori (make-vector size 1)) (old-fvect (make-float-vector size 1.0)) (old-ivect (make-int-vector size 1)) (old-hash (make-hash-table size)) (old-let #f) (old-block (make-block size))) (set! old-let (inlet)) (do ((i 0 (+ i 1))) ((= i size)) (hash-table-set! old-hash i #\a)) (do ((i 0 (+ i 1))) ((= i size)) (varlet old-let (string->symbol (number->string i)) #\a)) (let ((new-string (make-string size #\space)) (new-bvect (make-byte-vector size 0)) (new-pair (make-list size 1)) (new-vector (make-vector size 1)) (new-fvect (make-float-vector size 1.0)) (new-ivect (make-int-vector size 1)) (new-hash (make-hash-table (* size 2))) (new-let (inlet)) (new-block (make-block size))) (copy old-string) (copy old-pair) (copy old-vector) (copy old-fvect) (copy old-ivect) (copy old-hash) (copy old-let) (copy old-bvect) (copy old-block) (length old-string) (length old-pair) (length old-vector) (length old-fvect) (length old-ivect) (length old-hash) (length old-let) (length old-bvect) (length old-block) (fill! old-string #\a) (fill! new-string #\space) (fill! old-pair #\a) (fill! new-pair 1) (fill! old-vector #\a) (fill! new-vector 1) (fill! old-fvect 1.0) (fill! new-fvect 1.0) (fill! old-ivect 1) (fill! new-ivect 1) (fill! old-bvect 1) (fill! new-bvect 0) (fill! old-block 0.0) (fill! new-block 1.0) (copy old-string new-string) (copy old-vector new-string) (copy old-pair new-string) (copy old-bvect new-string) (copy old-bvect new-bvect) (copy old-ivect new-bvect) (copy old-vectori new-bvect) (copy old-string new-bvect) (copy old-pair new-pair) (copy old-string new-pair) (copy old-vector new-pair) (copy old-hash new-pair) (copy old-fvect new-pair) (copy old-ivect new-pair) (copy old-let new-pair) (copy old-block new-pair) (copy old-vector new-vector) (copy old-pair new-vector) (copy old-string new-vector) (copy old-fvect new-vector) (copy old-ivect new-vector) (copy old-hash new-vector) (copy old-let new-vector) (copy old-block new-vector) (copy old-fvect new-fvect) (copy old-ivect new-fvect) (copy old-vectorf new-fvect) (copy old-block new-fvect) (copy old-ivect new-ivect) (copy old-fvect new-ivect) (copy old-vectori new-ivect) (copy old-bvect new-ivect) (copy old-hash new-hash) (copy old-let new-hash) (copy old-let new-let) (copy old-fvect new-block) (copy old-block new-block)) (let ((nsize (/ size 2)) (start (/ size 4))) (let ((new-string (make-string size #\space)) (new-pair (make-list size 1)) (new-vector (make-vector size 1)) (new-fvect (make-float-vector size 1.0)) (new-ivect (make-int-vector size 1)) (new-hash (make-hash-table (* size 2))) (new-let (inlet)) (new-bvect (make-byte-vector size 255)) (new-block (make-block size))) (copy old-string new-string start (+ start nsize)) (copy old-vector new-string start (+ start nsize)) (copy old-pair new-string start (+ start nsize)) (copy old-bvect new-bvect start (+ start nsize)) (copy old-vectori new-bvect start (+ start nsize)) (copy old-ivect new-bvect start (+ start nsize)) (copy old-string new-bvect start (+ start nsize)) (copy old-pair new-pair start (+ start nsize)) (copy old-string new-pair start (+ start nsize)) (copy old-vector new-pair start (+ start nsize)) (copy old-hash new-pair start (+ start nsize)) (copy old-fvect new-pair start (+ start nsize)) (copy old-ivect new-pair start (+ start nsize)) (copy old-let new-pair start (+ start nsize)) (copy old-block new-pair start (+ start nsize)) (copy old-vector new-vector start (+ start nsize)) (copy old-pair new-vector start (+ start nsize)) (copy old-string new-vector start (+ start nsize)) (copy old-fvect new-vector start (+ start nsize)) (copy old-ivect new-vector start (+ start nsize)) (copy old-hash new-vector start (+ start nsize)) (copy old-let new-vector start (+ start nsize)) (copy old-block new-vector start (+ start nsize)) (copy old-fvect new-fvect start (+ start nsize)) (copy old-ivect new-fvect start (+ start nsize)) (copy old-vectorf new-fvect start (+ start nsize)) (copy old-block new-fvect start (+ start nsize)) (copy old-ivect new-ivect start (+ start nsize)) (copy old-fvect new-ivect start (+ start nsize)) (copy old-vectori new-ivect start (+ start nsize)) (copy old-bvect new-ivect start (+ start nsize)) (copy old-hash new-hash start (+ start nsize)) (copy old-let new-hash start (+ start nsize)) (copy old-let new-let start (+ start nsize)) (copy old-fvect new-block start (+ start nsize)) (copy old-block new-block start (+ start nsize)))) (reverse old-string) (reverse old-pair) (reverse old-vector) (reverse old-fvect) (reverse old-ivect) (reverse old-hash) (reverse old-bvect) (reverse old-block) (reverse! old-string) (reverse! old-pair) (reverse! old-vector) (reverse! old-fvect) (reverse! old-ivect) (reverse! old-bvect) (reverse! old-block) )) (define-expansion (test tst expected) `(let ((val ,tst)) (if (not (equal? val ,expected)) (format *stderr* "~S: ~S but expected ~S~%" ',tst val ,expected)))) (define (test-append size) (let ((strs ()) (vecs ()) (fvecs ()) (ivecs ()) (ifvecs ()) (allvecs ()) (bvecs ()) (lsts ())) (do ((i 0 (+ i 1))) ((= i size)) (set! strs (cons (make-string size (integer->char (+ 1 (random 255)))) strs)) (set! bvecs (cons (->byte-vector (make-string size (integer->char (random 256)))) bvecs)) (set! vecs (cons (make-vector size i) vecs)) (set! ivecs (cons (make-int-vector size i) ivecs)) (set! fvecs (cons (make-float-vector size (* i 1.0)) fvecs)) (set! ifvecs (cons (make-vector size (if (even? i) (* i 1.0) i) #t) ifvecs)) (set! allvecs (cons (make-vector size (if (even? i) (* i 1.0) i) (not (zero? (modulo i 3)))) allvecs)) (set! lsts (cons (make-list size i) lsts))) (let ((lst (apply append lsts)) (vec (apply vector-append vecs)) (fvec (apply vector-append fvecs)) (ivec (apply vector-append ivecs)) (ifvec (apply vector-append ifvecs)) (allvec (apply vector-append allvecs)) (str (apply string-append strs)) (bvec (->byte-vector (apply string-append bvecs)))) (test (vector? vec) #t) (test (length vec) (* size size)) (test (float-vector? fvec) #t) (test (length fvec) (* size size)) (test (int-vector? ivec) #t) (test (length ivec) (* size size)) (test (vector? allvec) #t) (test (length allvec) (* size size)) (test (vector? ifvec) #t) (test (length ifvec) (* size size)) ; (test (float-vector? ifvec) #t) ; (test (int-vector? ifvec) #f) (test (pair? lst) #t) (test (length lst) (* size size)) (test (string? str) #t) (test (length str) (* size size)) (test (byte-vector? bvec) #t) (test (length bvec) (* size size)) ))) (define (t) (do ((i 0 (+ i 1))) ((= i 10000)) (test-copy 100)) (do ((i 1 (* i 10))) ((> i 1000)) (test-append i))) (t) (s7-version) (exit) snd-16.1/tools/t101.scm0000644000076400007640000001071312570674255012703 0ustar bilbil;;; try each s7test test macro (using repl, not snd) (system "make-repl") (for-each (lambda (test-case) (call-with-output-file "t101-aux.scm" (lambda (p) (format p "(define-macro (test tst expected) ~A)~%(load \"s7test.scm\")~%(exit)~%" test-case))) (format *stderr* "test: ~S~%" test-case) (system "./repl t101-aux.scm")) (list "`(ok? ',tst (lambda () (eval ',tst)) ,expected)" "`(ok? ',tst (lambda () ,tst) ,expected)" "`(ok? ',tst (let () (define (_s7_) ,tst)) ,expected)" "`(ok? ',tst (lambda () (let ((_s7_ #f)) (set! _s7_ ,tst))) ,expected)" "`(ok? ',tst (lambda () (let ((_s7_ ,tst)) _s7_)) ,expected)" "`(ok? ',tst (catch #t (lambda () (lambda* ((_a_ ,tst)) _a_)) (lambda any (lambda () 'error))) ,expected)" "`(ok? ',tst (lambda () (do ((_a_ ,tst)) (#t _a_))) ,expected)" "`(ok? ',tst (lambda () (do ((__i__ 0 (+ __i__ 1))) ((= __i__ 1) ,expected) ,tst)) ,expected)" "`(ok? ',tst (lambda () (define ($f$) (let (($v$ (vector #f))) (do (($i$ 0 (+ $i$ 1))) ((= $i$ 1) ($v$ 0)) (vector-set! $v$ 0 ,tst)))) ($f$)) ,expected)" "`(ok? ',tst (lambda () (define ($f$) (let (($v$ #f)) (do (($i$ 0 (+ $i$ 1))) ((= $i$ 1) $v$) (set! $v$ ,tst)))) ($f$)) ,expected)" "`(ok? ',tst (lambda () (define ($f$) (let ((x (map (lambda (a) ,tst) '(0)))) (car x))) ($f$)) ,expected)" "`(ok? ',tst (lambda () (call-with-exit (lambda (_a_) (_a_ ,tst)))) ,expected)" "`(ok? ',tst (lambda () (call/cc (lambda (_a_) (_a_ ,tst)))) ,expected)" "`(ok? ',tst (lambda () (values ,tst)) ,expected)" "`(ok? ',tst (lambda () ((lambda (a b) b) (values #f ,tst))) ,expected)" "`(ok? ',tst (lambda () (define (_s7_ _a_) _a_) (_s7_ ,tst)) ,expected)" "`(ok? ',tst (lambda () (let ((___x #f)) (set! ___x ,tst))) ,expected)" "`(ok? ',tst (lambda () (let ((___x #(#f))) (set! (___x 0) ,tst))) ,expected)" "`(ok? ',tst (lambda () (let ((___x #(#f))) (vector-set! ___x 0 ,tst))) ,expected)" "`(ok? ',tst (lambda () (define* (_s7_ (_a_ #f)) (or _a_)) (_s7_ ,tst)) ,expected)" "`(ok? ',tst (lambda () (dynamic-wind (lambda () #f) (lambda () ,tst) (lambda () #f))) ,expected)" "({list} 'ok? ({list} quote tst) ({list} lambda () tst) expected)" )) (format *stderr* "~NC ffitest ~NC~%" 20 #\- 20 #\-) (if (provided? 'linux) (begin (system "gcc -o ffitest ffitest.c -g -Wall s7.o -lm -I. -ldl") (system "ffitest")) (if (provided? 'freebsd) (begin (system "cc -o ffitest ffitest.c -g -Wall s7.o -lm -I. -ldl") (system "ffitest")) (if (provided? 'osx) (begin (system "gcc -o ffitest ffitest.c -g -Wall s7.o -lm -I.") (system "ffitest")) ))) (format *stderr* "~%~NC lint ~NC~%" 20 #\- 20 #\-) (catch #t (lambda () (lint "s7test.scm" #f)) (lambda args #f)) ;; lint clobbers reader-cond (define-expansion (reader-cond . clauses) (call-with-exit (lambda (return) (for-each (lambda (clause) (let ((val (eval (car clause)))) (if val (if (null? (cdr clause)) (return val) (if (null? (cddr clause)) (return (cadr clause)) (return (apply values (map quote (cdr clause))))))))) clauses) (values)))) (format *stderr* "~%~NC local s7test ~NC~%" 20 #\- 20 #\-) (system "./snd -e '(let () (catch #t (lambda () (load \"s7test.scm\" (curlet))) (lambda args #f)) (exit))'") (format *stderr* "~NC tcopy ~NC~%" 20 #\- 20 #\-) (system "./repl tcopy.scm") (format *stderr* "~NC tmap ~NC~%" 20 #\- 20 #\-) (system "./repl tmap.scm") (format *stderr* "~NC teq ~NC~%" 20 #\- 20 #\-) (system "./repl teq.scm") (format *stderr* "~NC titer ~NC~%" 20 #\- 20 #\-) (system "./repl titer.scm") (format *stderr* "~%~NC tform ~NC~%" 20 #\- 20 #\-) (system "./repl tform.scm") (format *stderr* "~%~NC thash ~NC~%" 20 #\- 20 #\-) (system "./repl thash.scm") (format *stderr* "~NC tauto ~NC~%" 20 #\- 20 #\-) (system "./repl tauto.scm") (format *stderr* "~NC index ~NC~%" 20 #\- 20 #\-) (system "./snd make-index.scm") (format *stderr* "~NC makexg ~NC~%" 20 #\- 20 #\-) (system "./snd makexg.scm") (format *stderr* "~NC makegl ~NC~%" 20 #\- 20 #\-) (system "./snd makegl.scm") (format *stderr* "~NC lg ~NC~%" 20 #\- 20 #\-) (system "./snd lg.scm") (format *stderr* "~NC tgen ~NC~%" 20 #\- 20 #\-) (system "./snd tgen.scm") (format *stderr* "~NC tall ~NC~%" 20 #\- 20 #\-) (system "./snd tall.scm") (format *stderr* "~NC snd-test ~NC~%" 20 #\- 20 #\-) (system "./snd -l snd-test.scm") (format *stderr* "~NC bench ~NC~%" 20 #\- 20 #\-) (system "(cd /home/bil/test/bench/src ; /home/bil/cl/snd test-all.scm)") (exit) snd-16.1/tools/titer.scm0000644000076400007640000000657012600617077013344 0ustar bilbil;; iteration tests ;(set! (*s7* 'gc-stats) 2) ;;; do/let/rec/tc/iter (define with-blocks #f) (when with-blocks (let ((new-env (sublet (curlet) (cons 'init_func 'block_init)))) ; load calls init_func if possible (load "s7test-block.so" new-env))) (define-constant (find-if-a iter) (or (string? (iterate iter)) (and (not (iterator-at-end? iter)) (find-if-a iter)))) (define-constant (find-if-b iter) (call-with-exit (lambda (return) (for-each (lambda (arg) (if (string? arg) (return #t))) iter) #f))) (define-constant (find-if-c iter) (let loop () (or (string? (iterate iter)) (and (not (iterator-at-end? iter)) (loop))))) (define-constant (find-if-d iter) (do () ((or (string? (iterate iter)) (iterator-at-end? iter)) (not (iterator-at-end? iter))))) (define (test) (for-each (lambda (size) (format *stderr* "~D: " size) (let ((a (let ((lst (make-list size #f))) (list (find-if-a (make-iterator lst)) (find-if-b (make-iterator lst)) (find-if-c (make-iterator lst)) (find-if-d (make-iterator lst))))) (b (let ((str (make-string size #\space))) (list (find-if-a (make-iterator str)) (find-if-b (make-iterator str)) (find-if-c (make-iterator str)) (find-if-d (make-iterator str))))) (c (let ((vc (make-vector size #f))) (list (find-if-a (make-iterator vc)) (find-if-b (make-iterator vc)) (find-if-c (make-iterator vc)) (find-if-d (make-iterator vc))))) (d (let ((fv (make-float-vector size 0.0))) (list (find-if-a (make-iterator fv)) (find-if-b (make-iterator fv)) (find-if-c (make-iterator fv)) (find-if-d (make-iterator fv))))) (e (let ((iv (make-int-vector size 0))) (list (find-if-a (make-iterator iv)) (find-if-b (make-iterator iv)) (find-if-c (make-iterator iv)) (find-if-d (make-iterator iv))))) (f (let ((ht (let ((ht1 (make-hash-table size))) (do ((i 0 (+ i 1))) ((= i size) ht1) (hash-table-set! ht1 i i)))) (p (cons #f #f))) (list (find-if-a (make-iterator ht p)) (find-if-b (make-iterator ht p)) (find-if-c (make-iterator ht p)) (find-if-d (make-iterator ht p))))) (g (let ((lt (apply inlet (make-list (* 2 size) 'abc))) (p (cons #f #f))) (list (find-if-a (make-iterator lt p)) (find-if-b (make-iterator lt p)) (find-if-c (make-iterator lt p)) (find-if-d (make-iterator lt p))))) (h (if with-blocks (let ((blk (make-block size))) (list (find-if-a (make-iterator blk)) (find-if-b (make-iterator blk)) (find-if-c (make-iterator blk)) (find-if-d (make-iterator blk)))) #f))) (if (not (equal? a '(#f #f #f #f))) (format *stderr* "a: ~A " a)) (if (not (equal? b '(#f #f #f #f))) (format *stderr* "b: ~A " b)) (if (not (equal? c '(#f #f #f #f))) (format *stderr* "c: ~A " c)) (if (not (equal? d '(#f #f #f #f))) (format *stderr* "d: ~A " d)) (if (not (equal? e '(#f #f #f #f))) (format *stderr* "e: ~A " e)) (if (not (equal? f '(#f #f #f #f))) (format *stderr* "f: ~A " f)) (if (not (equal? g '(#f #f #f #f))) (format *stderr* "g: ~A " g)) (if (and with-blocks (not (equal? h '(#f #f #f #f)))) (format *stderr* "h: ~A " h)) )) (list 1 10 100 1000 10000 100000 1000000))) (test) (s7-version) (exit) snd-16.1/tools/gldata.scm0000644000076400007640000016005712434721721013447 0ustar bilbil(define (CFNC-multi . args) #f) (define (CINT-multi . args) #f) (CFNC-X "XVisualInfo* glXChooseVisual Display* dpy int screen int* attribList") (CFNC-X "void glXCopyContext Display* dpy GLXContext src GLXContext dst unsigned_long mask") (CFNC-X "GLXContext glXCreateContext Display* dpy XVisualInfo* vis GLXContext shareList Bool direct") (CFNC-X "GLXPixmap glXCreateGLXPixmap Display* dpy XVisualInfo* vis Pixmap pixmap") (CFNC-X "void glXDestroyContext Display* dpy GLXContext ctx") (CFNC-X "void glXDestroyGLXPixmap Display* dpy GLXPixmap pix") (CFNC-X "int glXGetConfig Display* dpy XVisualInfo* vis int attrib int* [value]") (CFNC-X "GLXContext glXGetCurrentContext void") (CFNC-X "Window glXGetCurrentDrawable void") (CFNC-X "Bool glXIsDirect Display* dpy GLXContext ctx") (CFNC-X "Bool glXMakeCurrent Display* dpy Window drawable GLXContext ctx") (CFNC-X "Bool glXQueryExtension Display* dpy int* [errorBase] int* [eventBase]") (CFNC-X "Bool glXQueryVersion Display* dpy int* [major] int* [minor]") (CFNC-X "void glXSwapBuffers Display* dpy Window drawable") (CFNC-X "void glXUseXFont Font font int first int count int listBase") (CFNC-X "void glXWaitGL void") (CFNC-X "void glXWaitX void") (CFNC-X "char* glXGetClientString Display* dpy int name") (CFNC-X "char* glXQueryServerString Display* dpy int screen int name") (CFNC-X "char* glXQueryExtensionsString Display* dpy int screen") ;(CFNC-X "GLXFBConfig* glXGetFBConfigs Display* dpy int screen int* nelements") ;(CFNC-X "GLXFBConfig* glXChooseFBConfig Display* dpy int screen int* attrib_list int* nelements") ;(CFNC-X "int glXGetFBConfigAttrib Display* dpy GLXFBConfig config int attribute int* value") ;(CFNC-X "XVisualInfo* glXGetVisualFromFBConfig Display* dpy GLXFBConfig config") ;(CFNC-X "GLXWindow glXCreateWindow Display* dpy GLXFBConfig config Window win int* attrib_list") ;(CFNC-X "void glXDestroyWindow Display* dpy GLXWindow win") ;(CFNC-X "GLXPixmap glXCreatePixmap Display* dpy GLXFBConfig config Pixmap pixmap int* attrib_list") ;(CFNC-X "void glXDestroyPixmap Display* dpy GLXPixmap pixmap") ;(CFNC-X "GLXPbuffer glXCreatePbuffer Display* dpy GLXFBConfig config int* attrib_list") ;(CFNC-X "void glXDestroyPbuffer Display* dpy GLXPbuffer pbuf") ;(CFNC-X "void glXQueryDrawable Display* dpy Window draw int attribute ulong* value") ;(CFNC-X "GLXContext glXCreateNewContext Display* dpy GLXFBConfig config int render_type GLXContext share_list Bool direct") ;(CFNC-X "Bool glXMakeContextCurrent Display* display Window draw Window read GLXContext ctx") ;(CFNC-X "Window glXGetCurrentReadDrawable void") ;(CFNC-X "Display* glXGetCurrentDisplay void") ;(CFNC-X "int glXQueryContext Display* dpy GLXContext ctx int attribute int* value") ;(CFNC-X "void glXSelectEvent Display* dpy Window draw ulong event_mask") ;(CFNC-X "void glXGetSelectedEvent Display* dpy Window draw ulong* event_mask") (CFNC "void glClearIndex GLfloat c") (CFNC "void glClearColor GLclampf red GLclampf green GLclampf blue GLclampf alpha") (CFNC "void glClear GLbitfield mask") (CFNC "void glIndexMask GLuint mask") (CFNC "void glColorMask GLboolean red GLboolean green GLboolean blue GLboolean alpha") (CFNC "void glAlphaFunc GLenum func GLclampf ref") (CFNC "void glBlendFunc GLenum sfactor GLenum dfactor") (CFNC "void glLogicOp GLenum opcode") (CFNC "void glCullFace GLenum mode") (CFNC "void glFrontFace GLenum mode") (CFNC "void glPointSize GLfloat size") (CFNC "void glLineWidth GLfloat width") (CFNC "void glLineStipple GLint factor GLushort pattern") (CFNC "void glPolygonMode GLenum face GLenum mode") (CFNC "void glPolygonOffset GLfloat factor GLfloat units") (CFNC "void glPolygonStipple GLubyte* mask") ;(CFNC "void glGetPolygonStipple GLubyte* [mask]") ; mask is of unknown size (1 = segfault, code looks like it uses 128) (CFNC "void glEdgeFlag GLboolean flag") ;(CFNC "void glEdgeFlagv GLboolean* flag") (CFNC "void glScissor GLint x GLint y GLsizei width GLsizei height") (CFNC "void glClipPlane GLenum plane GLdouble* equation") (CFNC "void glGetClipPlane GLenum plane GLdouble* [equation]") (CFNC "void glDrawBuffer GLenum mode") (CFNC "void glReadBuffer GLenum mode") (CFNC "void glEnable GLenum cap") (CFNC "void glDisable GLenum cap") (CFNC "GLboolean glIsEnabled GLenum cap") (CFNC "void glEnableClientState GLenum cap") (CFNC "void glDisableClientState GLenum cap") (CFNC "void glGetBooleanv GLenum pname GLboolean* [params]") (CFNC "void glGetDoublev GLenum pname GLdouble* [params]") (CFNC "void glGetFloatv GLenum pname GLfloat* [params]") (CFNC "void glGetIntegerv GLenum pname GLint* [params]") (CFNC "void glPushAttrib GLbitfield mask") (CFNC "void glPopAttrib void") (CFNC "void glPushClientAttrib GLbitfield mask") (CFNC "void glPopClientAttrib void") (CFNC "GLint glRenderMode GLenum mode") (CFNC "GLenum glGetError void") (CFNC "constchar* glGetString GLenum name") (CFNC "void glFinish void") (CFNC "void glFlush void") (CFNC "void glHint GLenum target GLenum mode") (CFNC "void glClearDepth GLclampd depth") (CFNC "void glDepthFunc GLenum func") (CFNC "void glDepthMask GLboolean flag") (CFNC "void glDepthRange GLclampd near_val GLclampd far_val") (CFNC "void glClearAccum GLfloat red GLfloat green GLfloat blue GLfloat alpha") (CFNC "void glAccum GLenum op GLfloat value") (CFNC "void glMatrixMode GLenum mode") (CFNC "void glOrtho GLdouble left GLdouble right GLdouble bottom GLdouble top GLdouble near_val GLdouble far_val") (CFNC "void glFrustum GLdouble left GLdouble right GLdouble bottom GLdouble top GLdouble near_val GLdouble far_val") (CFNC "void glViewport GLint x GLint y GLsizei width GLsizei height") (CFNC "void glPushMatrix void") (CFNC "void glPopMatrix void") (CFNC "void glLoadIdentity void") (CFNC "void glLoadMatrixd GLdouble* m") (CFNC "void glLoadMatrixf GLfloat* m") (CFNC "void glMultMatrixd GLdouble* m") (CFNC "void glMultMatrixf GLfloat* m") (CFNC "void glRotated GLdouble angle GLdouble x GLdouble y GLdouble z") (CFNC "void glRotatef GLfloat angle GLfloat x GLfloat y GLfloat z") (CFNC "void glScaled GLdouble x GLdouble y GLdouble z") (CFNC "void glScalef GLfloat x GLfloat y GLfloat z") (CFNC "void glTranslated GLdouble x GLdouble y GLdouble z") (CFNC "void glTranslatef GLfloat x GLfloat y GLfloat z") (CFNC "GLboolean glIsList GLuint list") (CFNC "void glDeleteLists GLuint list GLsizei range") (CFNC "GLuint glGenLists GLsizei range") (CFNC "void glNewList GLuint list GLenum mode") (CFNC "void glEndList void") (CFNC "void glCallList GLuint list") (CFNC "void glCallLists GLsizei n GLenum type GLvoid* lists") (CFNC "void glListBase GLuint base") (CFNC "void glBegin GLenum mode") (CFNC "void glEnd void") (CFNC "void glVertex2d GLdouble x GLdouble y") (CFNC "void glVertex2f GLfloat x GLfloat y") (CFNC "void glVertex2i GLint x GLint y") (CFNC "void glVertex2s GLshort x GLshort y") (CFNC "void glVertex3d GLdouble x GLdouble y GLdouble z") (CFNC "void glVertex3f GLfloat x GLfloat y GLfloat z") (CFNC "void glVertex3i GLint x GLint y GLint z") (CFNC "void glVertex3s GLshort x GLshort y GLshort z") (CFNC "void glVertex4d GLdouble x GLdouble y GLdouble z GLdouble w") (CFNC "void glVertex4f GLfloat x GLfloat y GLfloat z GLfloat w") (CFNC "void glVertex4i GLint x GLint y GLint z GLint w") (CFNC "void glVertex4s GLshort x GLshort y GLshort z GLshort w") ;(CFNC "void glVertex2dv GLdouble* v") ;(CFNC "void glVertex2fv GLfloat* v") ;(CFNC "void glVertex2iv GLint* v") ;(CFNC "void glVertex2sv GLshort* v") ;(CFNC "void glVertex3dv GLdouble* v") ;(CFNC "void glVertex3fv GLfloat* v") ;(CFNC "void glVertex3iv GLint* v") ;(CFNC "void glVertex3sv GLshort* v") ;(CFNC "void glVertex4dv GLdouble* v") ;(CFNC "void glVertex4fv GLfloat* v") ;(CFNC "void glVertex4iv GLint* v") ;(CFNC "void glVertex4sv GLshort* v") (CFNC "void glNormal3b GLbyte nx GLbyte ny GLbyte nz") (CFNC "void glNormal3d GLdouble nx GLdouble ny GLdouble nz") (CFNC "void glNormal3f GLfloat nx GLfloat ny GLfloat nz") (CFNC "void glNormal3i GLint nx GLint ny GLint nz") (CFNC "void glNormal3s GLshort nx GLshort ny GLshort nz") ;(CFNC "void glNormal3bv GLbyte* v") ;(CFNC "void glNormal3dv GLdouble* v") ;(CFNC "void glNormal3fv GLfloat* v") ;(CFNC "void glNormal3iv GLint* v") ;(CFNC "void glNormal3sv GLshort* v") (CFNC "void glIndexd GLdouble c") (CFNC "void glIndexf GLfloat c") (CFNC "void glIndexi GLint c") (CFNC "void glIndexs GLshort c") (CFNC "void glIndexub GLubyte c") ;(CFNC "void glIndexdv GLdouble* c") ;(CFNC "void glIndexfv GLfloat* c") ;(CFNC "void glIndexiv GLint* c") ;(CFNC "void glIndexsv GLshort* c") ;(CFNC "void glIndexubv GLubyte* c") (CFNC "void glColor3b GLbyte red GLbyte green GLbyte blue") (CFNC "void glColor3d GLdouble red GLdouble green GLdouble blue") (CFNC "void glColor3f GLfloat red GLfloat green GLfloat blue") (CFNC "void glColor3i GLint red GLint green GLint blue") (CFNC "void glColor3s GLshort red GLshort green GLshort blue") (CFNC "void glColor3ub GLubyte red GLubyte green GLubyte blue") (CFNC "void glColor3ui GLuint red GLuint green GLuint blue") (CFNC "void glColor3us GLushort red GLushort green GLushort blue") (CFNC "void glColor4b GLbyte red GLbyte green GLbyte blue GLbyte alpha") (CFNC "void glColor4d GLdouble red GLdouble green GLdouble blue GLdouble alpha") (CFNC "void glColor4f GLfloat red GLfloat green GLfloat blue GLfloat alpha") (CFNC "void glColor4i GLint red GLint green GLint blue GLint alpha") (CFNC "void glColor4s GLshort red GLshort green GLshort blue GLshort alpha") (CFNC "void glColor4ub GLubyte red GLubyte green GLubyte blue GLubyte alpha") (CFNC "void glColor4ui GLuint red GLuint green GLuint blue GLuint alpha") (CFNC "void glColor4us GLushort red GLushort green GLushort blue GLushort alpha") ;(CFNC "void glColor3bv GLbyte* v") ;(CFNC "void glColor3dv GLdouble* v") ;(CFNC "void glColor3fv GLfloat* v") ;(CFNC "void glColor3iv GLint* v") ;(CFNC "void glColor3sv GLshort* v") ;(CFNC "void glColor3ubv GLubyte* v") ;(CFNC "void glColor3uiv GLuint* v") ;(CFNC "void glColor3usv GLushort* v") ;(CFNC "void glColor4bv GLbyte* v") ;(CFNC "void glColor4dv GLdouble* v") ;(CFNC "void glColor4fv GLfloat* v") ;(CFNC "void glColor4iv GLint* v") ;(CFNC "void glColor4sv GLshort* v") ;(CFNC "void glColor4ubv GLubyte* v") ;(CFNC "void glColor4uiv GLuint* v") ;(CFNC "void glColor4usv GLushort* v") (CFNC "void glTexCoord1d GLdouble s") (CFNC "void glTexCoord1f GLfloat s") (CFNC "void glTexCoord1i GLint s") (CFNC "void glTexCoord1s GLshort s") (CFNC "void glTexCoord2d GLdouble s GLdouble t") (CFNC "void glTexCoord2f GLfloat s GLfloat t") (CFNC "void glTexCoord2i GLint s GLint t") (CFNC "void glTexCoord2s GLshort s GLshort t") (CFNC "void glTexCoord3d GLdouble s GLdouble t GLdouble r") (CFNC "void glTexCoord3f GLfloat s GLfloat t GLfloat r") (CFNC "void glTexCoord3i GLint s GLint t GLint r") (CFNC "void glTexCoord3s GLshort s GLshort t GLshort r") (CFNC "void glTexCoord4d GLdouble s GLdouble t GLdouble r GLdouble q") (CFNC "void glTexCoord4f GLfloat s GLfloat t GLfloat r GLfloat q") (CFNC "void glTexCoord4i GLint s GLint t GLint r GLint q") (CFNC "void glTexCoord4s GLshort s GLshort t GLshort r GLshort q") ;(CFNC "void glTexCoord1dv GLdouble* v") ;(CFNC "void glTexCoord1fv GLfloat* v") ;(CFNC "void glTexCoord1iv GLint* v") ;(CFNC "void glTexCoord1sv GLshort* v") ;(CFNC "void glTexCoord2dv GLdouble* v") ;(CFNC "void glTexCoord2fv GLfloat* v") ;(CFNC "void glTexCoord2iv GLint* v") ;(CFNC "void glTexCoord2sv GLshort* v") ;(CFNC "void glTexCoord3dv GLdouble* v") ;(CFNC "void glTexCoord3fv GLfloat* v") ;(CFNC "void glTexCoord3iv GLint* v") ;(CFNC "void glTexCoord3sv GLshort* v") ;(CFNC "void glTexCoord4dv GLdouble* v") ;(CFNC "void glTexCoord4fv GLfloat* v") ;(CFNC "void glTexCoord4iv GLint* v") ;(CFNC "void glTexCoord4sv GLshort* v") (CFNC "void glRasterPos2d GLdouble x GLdouble y") (CFNC "void glRasterPos2f GLfloat x GLfloat y") (CFNC "void glRasterPos2i GLint x GLint y") (CFNC "void glRasterPos2s GLshort x GLshort y") (CFNC "void glRasterPos3d GLdouble x GLdouble y GLdouble z") (CFNC "void glRasterPos3f GLfloat x GLfloat y GLfloat z") (CFNC "void glRasterPos3i GLint x GLint y GLint z") (CFNC "void glRasterPos3s GLshort x GLshort y GLshort z") (CFNC "void glRasterPos4d GLdouble x GLdouble y GLdouble z GLdouble w") (CFNC "void glRasterPos4f GLfloat x GLfloat y GLfloat z GLfloat w") (CFNC "void glRasterPos4i GLint x GLint y GLint z GLint w") (CFNC "void glRasterPos4s GLshort x GLshort y GLshort z GLshort w") ;(CFNC "void glRasterPos2dv GLdouble* v") ;(CFNC "void glRasterPos2fv GLfloat* v") ;(CFNC "void glRasterPos2iv GLint* v") ;(CFNC "void glRasterPos2sv GLshort* v") ;(CFNC "void glRasterPos3dv GLdouble* v") ;(CFNC "void glRasterPos3fv GLfloat* v") ;(CFNC "void glRasterPos3iv GLint* v") ;(CFNC "void glRasterPos3sv GLshort* v") ;(CFNC "void glRasterPos4dv GLdouble* v") ;(CFNC "void glRasterPos4fv GLfloat* v") ;(CFNC "void glRasterPos4iv GLint* v") ;(CFNC "void glRasterPos4sv GLshort* v") (CFNC "void glRectd GLdouble x1 GLdouble y1 GLdouble x2 GLdouble y2") (CFNC "void glRectf GLfloat x1 GLfloat y1 GLfloat x2 GLfloat y2") (CFNC "void glRecti GLint x1 GLint y1 GLint x2 GLint y2") (CFNC "void glRects GLshort x1 GLshort y1 GLshort x2 GLshort y2") ;(CFNC "void glRectdv GLdouble* v1 GLdouble* v2") ;(CFNC "void glRectfv GLfloat* v1 GLfloat* v2") ;(CFNC "void glRectiv GLint* v1 GLint* v2") ;(CFNC "void glRectsv GLshort* v1 GLshort* v2") (CFNC "void glVertexPointer GLint size GLenum type GLsizei stride GLvoid* ptr") (CFNC "void glNormalPointer GLenum type GLsizei stride GLvoid* ptr") (CFNC "void glColorPointer GLint size GLenum type GLsizei stride GLvoid* ptr") (CFNC "void glIndexPointer GLenum type GLsizei stride GLvoid* ptr") (CFNC "void glTexCoordPointer GLint size GLenum type GLsizei stride GLvoid* ptr") (CFNC "void glEdgeFlagPointer GLsizei stride GLvoid* ptr") (CFNC "void glGetPointerv GLenum pname void** [params]") (CFNC "void glArrayElement GLint i") (CFNC "void glDrawArrays GLenum mode GLint first GLsizei count") (CFNC "void glDrawElements GLenum mode GLsizei count GLenum type GLvoid* indices") (CFNC "void glInterleavedArrays GLenum format GLsizei stride GLvoid* pointer") (CFNC "void glShadeModel GLenum mode") (CFNC "void glLightf GLenum light GLenum pname GLfloat param") (CFNC "void glLighti GLenum light GLenum pname GLint param") ;(CFNC "void glLightfv GLenum light GLenum pname GLfloat* params") ;(CFNC "void glLightiv GLenum light GLenum pname GLint* params") (CFNC "void glGetLightfv GLenum light GLenum pname GLfloat* [params]") (CFNC "void glGetLightiv GLenum light GLenum pname GLint* [params]") (CFNC "void glLightModelf GLenum pname GLfloat param") (CFNC "void glLightModeli GLenum pname GLint param") ;(CFNC "void glLightModelfv GLenum pname GLfloat* params") ;(CFNC "void glLightModeliv GLenum pname GLint* params") (CFNC "void glMaterialf GLenum face GLenum pname GLfloat param") (CFNC "void glMateriali GLenum face GLenum pname GLint param") ;(CFNC "void glMaterialfv GLenum face GLenum pname GLfloat* params") ;(CFNC "void glMaterialiv GLenum face GLenum pname GLint* params") (CFNC "void glGetMaterialfv GLenum face GLenum pname GLfloat* [params]") (CFNC "void glGetMaterialiv GLenum face GLenum pname GLint* [params]") (CFNC "void glColorMaterial GLenum face GLenum mode") (CFNC "void glPixelZoom GLfloat xfactor GLfloat yfactor") (CFNC "void glPixelStoref GLenum pname GLfloat param") (CFNC "void glPixelStorei GLenum pname GLint param") (CFNC "void glPixelTransferf GLenum pname GLfloat param") (CFNC "void glPixelTransferi GLenum pname GLint param") ;(CFNC "void glPixelMapfv GLenum map GLint mapsize GLfloat* values") ;(CFNC "void glPixelMapuiv GLenum map GLint mapsize GLuint* values") ;(CFNC "void glPixelMapusv GLenum map GLint mapsize GLushort* values") (CFNC "void glGetPixelMapfv GLenum map GLfloat* [values]") (CFNC "void glGetPixelMapuiv GLenum map GLuint* [values]") (CFNC "void glGetPixelMapusv GLenum map GLushort* [values]") (CFNC "void glBitmap GLsizei width GLsizei height GLfloat xorig GLfloat yorig GLfloat xmove GLfloat ymove GLubyte* bitmap") (CFNC "void glReadPixels GLint x GLint y GLsizei width GLsizei height GLenum format GLenum type GLvoid* pixels") (CFNC "void glDrawPixels GLsizei width GLsizei height GLenum format GLenum type GLvoid* pixels") (CFNC "void glCopyPixels GLint x GLint y GLsizei width GLsizei height GLenum type") (CFNC "void glStencilFunc GLenum func GLint ref GLuint mask") (CFNC "void glStencilMask GLuint mask") (CFNC "void glStencilOp GLenum fail GLenum zfail GLenum zpass") (CFNC "void glClearStencil GLint s") (CFNC "void glTexGend GLenum coord GLenum pname GLdouble param") (CFNC "void glTexGenf GLenum coord GLenum pname GLfloat param") (CFNC "void glTexGeni GLenum coord GLenum pname GLint param") ;(CFNC "void glTexGendv GLenum coord GLenum pname GLdouble* params") ;(CFNC "void glTexGenfv GLenum coord GLenum pname GLfloat* params") ;(CFNC "void glTexGeniv GLenum coord GLenum pname GLint* params") (CFNC "void glGetTexGendv GLenum coord GLenum pname GLdouble* [params]") (CFNC "void glGetTexGenfv GLenum coord GLenum pname GLfloat* [params]") (CFNC "void glGetTexGeniv GLenum coord GLenum pname GLint* [params]") (CFNC "void glTexEnvf GLenum target GLenum pname GLfloat param") (CFNC "void glTexEnvi GLenum target GLenum pname GLint param") ;(CFNC "void glTexEnvfv GLenum target GLenum pname GLfloat* params") ;(CFNC "void glTexEnviv GLenum target GLenum pname GLint* params") (CFNC "void glGetTexEnvfv GLenum target GLenum pname GLfloat* [params]") (CFNC "void glGetTexEnviv GLenum target GLenum pname GLint* [params]") (CFNC "void glTexParameterf GLenum target GLenum pname GLfloat param") (CFNC "void glTexParameteri GLenum target GLenum pname GLint param") ;(CFNC "void glTexParameterfv GLenum target GLenum pname GLfloat* params") ;(CFNC "void glTexParameteriv GLenum target GLenum pname GLint* params") (CFNC "void glGetTexParameterfv GLenum target GLenum pname GLfloat* [params]") (CFNC "void glGetTexParameteriv GLenum target GLenum pname GLint* [params]") (CFNC "void glGetTexLevelParameterfv GLenum target GLint level GLenum pname GLfloat* [params]") (CFNC "void glGetTexLevelParameteriv GLenum target GLint level GLenum pname GLint* [params]") (CFNC "void glTexImage1D GLenum target GLint level GLint internalFormat GLsizei width GLint border GLenum format GLenum type GLvoid* pixels") (CFNC "void glTexImage2D GLenum target GLint level GLint internalFormat GLsizei width GLsizei height GLint border GLenum format GLenum type GLvoid* pixels") ;(CFNC "void glGetTexImage GLenum target GLint level GLenum format GLenum type GLvoid* [pixels]") (CFNC "void glGenTextures GLsizei n GLuint* textures") (CFNC "void glDeleteTextures GLsizei n GLuint* textures") (CFNC "void glBindTexture GLenum target GLuint texture") ;(CFNC "void glPrioritizeTextures GLsizei n GLuint* textures GLclampf* priorities") (CFNC "GLboolean glAreTexturesResident GLsizei n GLuint* textures GLboolean* residences") (CFNC "GLboolean glIsTexture GLuint texture") (CFNC "void glTexSubImage1D GLenum target GLint level GLint xoffset GLsizei width GLenum format GLenum type GLvoid* pixels") (CFNC "void glTexSubImage2D GLenum target GLint level GLint xoffset GLint yoffset GLsizei width GLsizei height GLenum format GLenum type GLvoid* pixels") (CFNC "void glCopyTexImage1D GLenum target GLint level GLenum internalformat GLint x GLint y GLsizei width GLint border") (CFNC "void glCopyTexImage2D GLenum target GLint level GLenum internalformat GLint x GLint y GLsizei width GLsizei height GLint border") (CFNC "void glCopyTexSubImage1D GLenum target GLint level GLint xoffset GLint x GLint y GLsizei width") (CFNC "void glCopyTexSubImage2D GLenum target GLint level GLint xoffset GLint yoffset GLint x GLint y GLsizei width GLsizei height") (CFNC "void glMap1d GLenum target GLdouble u1 GLdouble u2 GLint stride GLint order GLdouble* points") (CFNC "void glMap1f GLenum target GLfloat u1 GLfloat u2 GLint stride GLint order GLfloat* points") (CFNC "void glMap2d GLenum target GLdouble u1 GLdouble u2 GLint ustride GLint uorder GLdouble v1 GLdouble v2 GLint vstride GLint vorder GLdouble* points") (CFNC "void glMap2f GLenum target GLfloat u1 GLfloat u2 GLint ustride GLint uorder GLfloat v1 GLfloat v2 GLint vstride GLint vorder GLfloat* points") (CFNC "void glGetMapdv GLenum target GLenum query GLdouble* [v]") (CFNC "void glGetMapfv GLenum target GLenum query GLfloat* [v]") (CFNC "void glGetMapiv GLenum target GLenum query GLint* [v]") (CFNC "void glEvalCoord1d GLdouble u") (CFNC "void glEvalCoord1f GLfloat u") ;(CFNC "void glEvalCoord1dv GLdouble* u") ;(CFNC "void glEvalCoord1fv GLfloat* u") (CFNC "void glEvalCoord2d GLdouble u GLdouble v") (CFNC "void glEvalCoord2f GLfloat u GLfloat v") ;(CFNC "void glEvalCoord2dv GLdouble* u") ;(CFNC "void glEvalCoord2fv GLfloat* u") (CFNC "void glMapGrid1d GLint un GLdouble u1 GLdouble u2") (CFNC "void glMapGrid1f GLint un GLfloat u1 GLfloat u2") (CFNC "void glMapGrid2d GLint un GLdouble u1 GLdouble u2 GLint vn GLdouble v1 GLdouble v2") (CFNC "void glMapGrid2f GLint un GLfloat u1 GLfloat u2 GLint vn GLfloat v1 GLfloat v2") (CFNC "void glEvalPoint1 GLint i") (CFNC "void glEvalPoint2 GLint i GLint j") (CFNC "void glEvalMesh1 GLenum mode GLint i1 GLint i2") (CFNC "void glEvalMesh2 GLenum mode GLint i1 GLint i2 GLint j1 GLint j2") (CFNC "void glFogf GLenum pname GLfloat param") (CFNC "void glFogi GLenum pname GLint param") ;(CFNC "void glFogfv GLenum pname GLfloat* params") ;(CFNC "void glFogiv GLenum pname GLint* params") (CFNC "void glFeedbackBuffer GLsizei size GLenum type GLfloat* buffer") (CFNC "void glPassThrough GLfloat token") (CFNC "void glSelectBuffer GLsizei size GLuint* buffer") (CFNC "void glInitNames void") (CFNC "void glLoadName GLuint name") (CFNC "void glPushName GLuint name") (CFNC "void glPopName void") (CFNC "void glDrawRangeElements GLenum mode GLuint start GLuint end GLsizei count GLenum type GLvoid* indices") (CFNC "void glTexImage3D GLenum target GLint level GLint internalFormat GLsizei width GLsizei height GLsizei depth GLint border GLenum format GLenum type GLvoid* pixels") (CFNC "void glTexSubImage3D GLenum target GLint level GLint xoffset GLint yoffset GLint zoffset GLsizei width GLsizei height GLsizei depth GLenum format GLenum type GLvoid* pixels") (CFNC "void glCopyTexSubImage3D GLenum target GLint level GLint xoffset GLint yoffset GLint zoffset GLint x GLint y GLsizei width GLsizei height") (CFNC "void glColorTable GLenum target GLenum internalformat GLsizei width GLenum format GLenum type GLvoid* table") (CFNC "void glColorSubTable GLenum target GLsizei start GLsizei count GLenum format GLenum type GLvoid* data") ;(CFNC "void glColorTableParameteriv GLenum target GLenum pname GLint* params") ;(CFNC "void glColorTableParameterfv GLenum target GLenum pname GLfloat* params") (CFNC "void glCopyColorSubTable GLenum target GLsizei start GLint x GLint y GLsizei width") (CFNC "void glCopyColorTable GLenum target GLenum internalformat GLint x GLint y GLsizei width") ;(CFNC "void glGetColorTable GLenum target GLenum format GLenum type GLvoid* [table]") (CFNC "void glGetColorTableParameterfv GLenum target GLenum pname GLfloat* [params]") (CFNC "void glGetColorTableParameteriv GLenum target GLenum pname GLint* [params]") (CFNC "void glBlendEquation GLenum mode") (CFNC "void glBlendColor GLclampf red GLclampf green GLclampf blue GLclampf alpha") (CFNC "void glHistogram GLenum target GLsizei width GLenum internalformat GLboolean sink") (CFNC "void glResetHistogram GLenum target") (CFNC "void glGetHistogram GLenum target GLboolean reset GLenum format GLenum type GLvoid* values") (CFNC "void glGetHistogramParameterfv GLenum target GLenum pname GLfloat* [params]") (CFNC "void glGetHistogramParameteriv GLenum target GLenum pname GLint* [params]") (CFNC "void glMinmax GLenum target GLenum internalformat GLboolean sink") (CFNC "void glResetMinmax GLenum target") (CFNC "void glGetMinmax GLenum target GLboolean reset GLenum format GLenum types GLvoid* values") (CFNC "void glGetMinmaxParameterfv GLenum target GLenum pname GLfloat* [params]") (CFNC "void glGetMinmaxParameteriv GLenum target GLenum pname GLint* [params]") (CFNC "void glConvolutionFilter1D GLenum target GLenum internalformat GLsizei width GLenum format GLenum type GLvoid* image") (CFNC "void glConvolutionFilter2D GLenum target GLenum internalformat GLsizei width GLsizei height GLenum format GLenum type GLvoid* image") (CFNC "void glConvolutionParameterf GLenum target GLenum pname GLfloat params") ;(CFNC "void glConvolutionParameterfv GLenum target GLenum pname GLfloat* params") (CFNC "void glConvolutionParameteri GLenum target GLenum pname GLint params") ;(CFNC "void glConvolutionParameteriv GLenum target GLenum pname GLint* params") (CFNC "void glCopyConvolutionFilter1D GLenum target GLenum internalformat GLint x GLint y GLsizei width") (CFNC "void glCopyConvolutionFilter2D GLenum target GLenum internalformat GLint x GLint y GLsizei width GLsizei height") ;(CFNC "void glGetConvolutionFilter GLenum target GLenum format GLenum type GLvoid* [image]") ;(CFNC "void glGetConvolutionParameterfv GLenum target GLenum pname GLfloat* params") ;(CFNC "void glGetConvolutionParameteriv GLenum target GLenum pname GLint* params") (CFNC "void glSeparableFilter2D GLenum target GLenum internalformat GLsizei width GLsizei height GLenum format GLenum type GLvoid* row GLvoid* column") ;(CFNC "void glGetSeparableFilter GLenum target GLenum format GLenum type GLvoid* [row] GLvoid* [column] GLvoid* [span]") (CFNC "void gluBeginCurve GLUnurbs* nurb") (CFNC "void gluBeginPolygon GLUtesselator* tess") (CFNC "void gluBeginSurface GLUnurbs* nurb")(CFNC "void gluBeginTrim GLUnurbs* nurb") (CFNC "GLint gluBuild1DMipmapLevels GLenum target GLint internalFormat GLsizei width GLenum format GLenum type GLint level GLint base GLint max void* data") (CFNC "GLint gluBuild1DMipmaps GLenum target GLint internalFormat GLsizei width GLenum format GLenum type void* data") (CFNC "GLint gluBuild2DMipmapLevels GLenum target GLint internalFormat GLsizei width GLsizei height GLenum format GLenum type GLint level GLint base GLint max void* data") (CFNC "GLint gluBuild2DMipmaps GLenum target GLint internalFormat GLsizei width GLsizei height GLenum format GLenum type void* data") (CFNC "GLint gluBuild3DMipmapLevels GLenum target GLint internalFormat GLsizei width GLsizei height GLsizei depth GLenum format GLenum type GLint level GLint base GLint max void* data") (CFNC "GLint gluBuild3DMipmaps GLenum target GLint internalFormat GLsizei width GLsizei height GLsizei depth GLenum format GLenum type void* data") (CFNC "GLboolean gluCheckExtension GLubyte* extName GLubyte* extString") (CFNC "void gluCylinder GLUquadric* quad GLdouble base GLdouble top GLdouble height GLint slices GLint stacks") (CFNC "void gluDeleteNurbsRenderer GLUnurbs* nurb") (CFNC "void gluDeleteQuadric GLUquadric* quad") (CFNC "void gluDeleteTess GLUtesselator* tess") (CFNC "void gluDisk GLUquadric* quad GLdouble inner GLdouble outer GLint slices GLint loops") (CFNC "void gluEndCurve GLUnurbs* nurb") (CFNC "void gluEndPolygon GLUtesselator* tess") (CFNC "void gluEndSurface GLUnurbs* nurb") (CFNC "void gluEndTrim GLUnurbs* nurb") (CFNC "constchar* gluErrorString GLenum error") (CFNC "void gluGetNurbsProperty GLUnurbs* nurb GLenum property GLfloat* data") (CFNC "constchar* gluGetString GLenum name") (CFNC "void gluGetTessProperty GLUtesselator* tess GLenum which GLdouble* data") (CFNC "void gluLoadSamplingMatrices GLUnurbs* nurb GLfloat* model GLfloat* perspective GLint* view") (CFNC "void gluLookAt GLdouble eyeX GLdouble eyeY GLdouble eyeZ GLdouble centerX GLdouble centerY GLdouble centerZ GLdouble upX GLdouble upY GLdouble upZ") (CFNC "GLUnurbs* gluNewNurbsRenderer void") (CFNC "GLUquadric* gluNewQuadric void") (CFNC "GLUtesselator* gluNewTess void") (CFNC "void gluNextContour GLUtesselator* tess GLenum type") (CFNC "void gluNurbsCallback GLUnurbs* nurb GLenum which _GLUfuncptr CallBackFunc") (CFNC "void gluNurbsCallbackData GLUnurbs* nurb GLvoid* userData") (CFNC "void gluNurbsCurve GLUnurbs* nurb GLint knotCount GLfloat* knots GLint stride GLfloat* control GLint order GLenum type") (CFNC "void gluNurbsProperty GLUnurbs* nurb GLenum property GLfloat value") (CFNC "void gluNurbsSurface GLUnurbs* nurb GLint sKnotCount GLfloat* sKnots GLint tKnotCount GLfloat* tKnots GLint sStride GLint tStride GLfloat* control GLint sOrder GLint tOrder GLenum type") (CFNC "void gluOrtho2D GLdouble left GLdouble right GLdouble bottom GLdouble top") (CFNC "void gluPartialDisk GLUquadric* quad GLdouble inner GLdouble outer GLint slices GLint loops GLdouble start GLdouble sweep") (CFNC "void gluPerspective GLdouble fovy GLdouble aspect GLdouble zNear GLdouble zFar") (CFNC "void gluPickMatrix GLdouble x GLdouble y GLdouble delX GLdouble delY GLint* viewport") (CFNC "GLint gluProject GLdouble objX GLdouble objY GLdouble objZ GLdouble* model GLdouble* proj GLint* view GLdouble* [winX] GLdouble* [winY] GLdouble* [winZ]") (CFNC "void gluPwlCurve GLUnurbs* nurb GLint count GLfloat* data GLint stride GLenum type") (CFNC "void gluQuadricCallback GLUquadric* quad GLenum which _GLUfuncptr CallBackFunc") (CFNC "void gluQuadricDrawStyle GLUquadric* quad GLenum draw") (CFNC "void gluQuadricNormals GLUquadric* quad GLenum normal") (CFNC "void gluQuadricOrientation GLUquadric* quad GLenum orientation") (CFNC "void gluQuadricTexture GLUquadric* quad GLboolean texture") (CFNC "GLint gluScaleImage GLenum format GLsizei wIn GLsizei hIn GLenum typeIn void* dataIn GLsizei wOut GLsizei hOut GLenum typeOut GLvoid* dataOut") (CFNC "void gluSphere GLUquadric* quad GLdouble radius GLint slices GLint stacks") (CFNC "void gluTessBeginContour GLUtesselator* tess") (CFNC "void gluTessBeginPolygon GLUtesselator* tess GLvoid* data") (CFNC "void gluTessCallback GLUtesselator* tess GLenum which _GLUfuncptr CallBackFunc") (CFNC "void gluTessEndContour GLUtesselator* tess") (CFNC "void gluTessEndPolygon GLUtesselator* tess") (CFNC "void gluTessNormal GLUtesselator* tess GLdouble valueX GLdouble valueY GLdouble valueZ") (CFNC "void gluTessProperty GLUtesselator* tess GLenum which GLdouble data") (CFNC "void gluTessVertex GLUtesselator* tess GLdouble* location GLvoid* data") (CFNC "GLint gluUnProject GLdouble winX GLdouble winY GLdouble winZ GLdouble* model GLdouble* proj GLint* view GLdouble* [objX] GLdouble* [objY] GLdouble* [objZ]") (CFNC "GLint gluUnProject4 GLdouble winX GLdouble winY GLdouble winZ GLdouble clipW GLdouble* model GLdouble* proj GLint* view GLdouble near GLdouble far GLdouble* [objX] GLdouble* [objY] GLdouble* [objZ] GLdouble* [objW]") (CFNC-multi "void glActiveTextureARB GLenum texture") (CFNC-multi "void glClientActiveTextureARB GLenum texture") (CFNC-multi "void glMultiTexCoord1dARB GLenum target GLdouble s") (CFNC-multi "void glMultiTexCoord1dvARB GLenum target GLdouble* v") (CFNC-multi "void glMultiTexCoord1fARB GLenum target GLfloat s") (CFNC-multi "void glMultiTexCoord1fvARB GLenum target GLfloat* v") (CFNC-multi "void glMultiTexCoord1iARB GLenum target GLint s") (CFNC-multi "void glMultiTexCoord1ivARB GLenum target GLint* v") (CFNC-multi "void glMultiTexCoord1sARB GLenum target GLshort s") (CFNC-multi "void glMultiTexCoord1svARB GLenum target GLshort* v") (CFNC-multi "void glMultiTexCoord2dARB GLenum target GLdouble s GLdouble t") (CFNC-multi "void glMultiTexCoord2dvARB GLenum target GLdouble* v") (CFNC-multi "void glMultiTexCoord2fARB GLenum target GLfloat s GLfloat t") (CFNC-multi "void glMultiTexCoord2fvARB GLenum target GLfloat* v") (CFNC-multi "void glMultiTexCoord2iARB GLenum target GLint s GLint t") (CFNC-multi "void glMultiTexCoord2ivARB GLenum target GLint* v") (CFNC-multi "void glMultiTexCoord2sARB GLenum target GLshort s GLshort t") (CFNC-multi "void glMultiTexCoord2svARB GLenum target GLshort* v") (CFNC-multi "void glMultiTexCoord3dARB GLenum target GLdouble s GLdouble t GLdouble r") (CFNC-multi "void glMultiTexCoord3dvARB GLenum target GLdouble* v") (CFNC-multi "void glMultiTexCoord3fARB GLenum target GLfloat s GLfloat t GLfloat r") (CFNC-multi "void glMultiTexCoord3fvARB GLenum target GLfloat* v") (CFNC-multi "void glMultiTexCoord3iARB GLenum target GLint s GLint t GLint r") (CFNC-multi "void glMultiTexCoord3ivARB GLenum target GLint* v") (CFNC-multi "void glMultiTexCoord3sARB GLenum target GLshort s GLshort t GLshort r") (CFNC-multi "void glMultiTexCoord3svARB GLenum target GLshort* v") (CFNC-multi "void glMultiTexCoord4dARB GLenum target GLdouble s GLdouble t GLdouble r GLdouble q") (CFNC-multi "void glMultiTexCoord4dvARB GLenum target GLdouble* v") (CFNC-multi "void glMultiTexCoord4fARB GLenum target GLfloat s GLfloat t GLfloat r GLfloat q") (CFNC-multi "void glMultiTexCoord4fvARB GLenum target GLfloat* v") (CFNC-multi "void glMultiTexCoord4iARB GLenum target GLint s GLint t GLint r GLint q") (CFNC-multi "void glMultiTexCoord4ivARB GLenum target GLint* v") (CFNC-multi "void glMultiTexCoord4sARB GLenum target GLshort s GLshort t GLshort r GLshort q") (CFNC-multi "void glMultiTexCoord4svARB GLenum target GLshort* v") (CINT-X "GLX_USE_GL") (CINT-X "GLX_BUFFER_SIZE") (CINT-X "GLX_LEVEL") (CINT-X "GLX_RGBA") (CINT-X "GLX_DOUBLEBUFFER") (CINT-X "GLX_STEREO") (CINT-X "GLX_AUX_BUFFERS") (CINT-X "GLX_RED_SIZE") (CINT-X "GLX_GREEN_SIZE") (CINT-X "GLX_BLUE_SIZE") (CINT-X "GLX_ALPHA_SIZE") (CINT-X "GLX_DEPTH_SIZE") (CINT-X "GLX_STENCIL_SIZE") (CINT-X "GLX_ACCUM_RED_SIZE") (CINT-X "GLX_ACCUM_GREEN_SIZE") (CINT-X "GLX_ACCUM_BLUE_SIZE") (CINT-X "GLX_ACCUM_ALPHA_SIZE") ;(CINT-X "GLX_X_VISUAL_TYPE") ;(CINT-X "GLX_CONFIG_CAVEAT") ;(CINT-X "GLX_TRANSPARENT_TYPE") ;(CINT-X "GLX_TRANSPARENT_INDEX_VALUE") ;(CINT-X "GLX_TRANSPARENT_RED_VALUE") ;(CINT-X "GLX_TRANSPARENT_GREEN_VALUE") ;(CINT-X "GLX_TRANSPARENT_BLUE_VALUE") ;(CINT-X "GLX_TRANSPARENT_ALPHA_VALUE") ;(CINT-X "GLX_DRAWABLE_TYPE") ;(CINT-X "GLX_RENDER_TYPE") ;(CINT-X "GLX_X_RENDERABLE") ;(CINT-X "GLX_FBCONFIG_ID") ;(CINT-X "GLX_MAX_PBUFFER_WIDTH") ;(CINT-X "GLX_MAX_PBUFFER_HEIGHT") ;(CINT-X "GLX_MAX_PBUFFER_PIXELS") ;(CINT-X "GLX_VISUAL_ID") (CINT-X "GLX_BAD_SCREEN") (CINT-X "GLX_BAD_ATTRIBUTE") (CINT-X "GLX_NO_EXTENSION") (CINT-X "GLX_BAD_VISUAL") (CINT-X "GLX_BAD_CONTEXT") (CINT-X "GLX_BAD_VALUE") (CINT-X "GLX_BAD_ENUM") ;(CINT-X "GLX_DONT_CARE") ;(CINT-X "GLX_RGBA_BIT") ;(CINT-X "GLX_COLOR_INDEX_BIT") ;(CINT-X "GLX_WINDOW_BIT") ;(CINT-X "GLX_PIXMAP_BIT") ;(CINT-X "GLX_PBUFFER_BIT") ;(CINT-X "GLX_NONE") ;(CINT-X "GLX_SLOW_CONFIG") ;(CINT-X "GLX_NON_CONFORMANT_CONFIG") ;(CINT-X "GLX_TRUE_COLOR") ;(CINT-X "GLX_DIRECT_COLOR") ;(CINT-X "GLX_PSEUDO_COLOR") ;(CINT-X "GLX_STATIC_COLOR") ;(CINT-X "GLX_GRAY_SCALE") ;(CINT-X "GLX_STATIC_GRAY") ;(CINT-X "GLX_TRANSPARENT_RGB") ;(CINT-X "GLX_TRANSPARENT_INDEX") ;(CINT-X "GLX_PRESERVED_CONTENTS") ;(CINT-X "GLX_LARGEST_PBUFFER") ;(CINT-X "GLX_PBUFFER_HEIGHT") ;(CINT-X "GLX_PBUFFER_WIDTH") ;(CINT-X "GLX_WIDTH") ;(CINT-X "GLX_HEIGHT") ;(CINT-X "GLX_EVENT_MASK") ;(CINT-X "GLX_RGBA_TYPE") ;(CINT-X "GLX_COLOR_INDEX_TYPE") ;(CINT-X "GLX_SCREEN") ;(CINT-X "GLX_PBUFFER_CLOBBER_MASK") ;(CINT-X "GLX_DAMAGED") ;(CINT-X "GLX_SAVED") ;(CINT-X "GLX_WINDOW") ;(CINT-X "GLX_PBUFFER") ;(CINT-X "GLX_FRONT_LEFT_BUFFER_BIT") ;(CINT-X "GLX_FRONT_RIGHT_BUFFER_BIT") ;(CINT-X "GLX_BACK_LEFT_BUFFER_BIT") ;(CINT-X "GLX_BACK_RIGHT_BUFFER_BIT") ;(CINT-X "GLX_AUX_BUFFERS_BIT") ;(CINT-X "GLX_DEPTH_BUFFER_BIT") ;(CINT-X "GLX_STENCIL_BUFFER_BIT") ;(CINT-X "GLX_ACCUM_BUFFER_BIT") (CINT-X "GLX_VENDOR") (CINT-X "GLX_VERSION") (CINT-X "GLX_EXTENSIONS") (CINT "GL_FALSE") (CINT "GL_TRUE") (CINT "GL_BYTE") (CINT "GL_UNSIGNED_BYTE") (CINT "GL_SHORT") (CINT "GL_UNSIGNED_SHORT") (CINT "GL_INT") (CINT "GL_UNSIGNED_INT") (CINT "GL_FLOAT") (CINT "GL_DOUBLE") (CINT "GL_2_BYTES") (CINT "GL_3_BYTES") (CINT "GL_4_BYTES") (CINT "GL_POINTS") (CINT "GL_LINES") (CINT "GL_LINE_LOOP") (CINT "GL_LINE_STRIP") (CINT "GL_TRIANGLES") (CINT "GL_TRIANGLE_STRIP") (CINT "GL_TRIANGLE_FAN") (CINT "GL_QUADS") (CINT "GL_QUAD_STRIP") (CINT "GL_POLYGON") (CINT "GL_VERTEX_ARRAY") (CINT "GL_NORMAL_ARRAY") (CINT "GL_COLOR_ARRAY") (CINT "GL_INDEX_ARRAY") (CINT "GL_TEXTURE_COORD_ARRAY") (CINT "GL_EDGE_FLAG_ARRAY") (CINT "GL_VERTEX_ARRAY_SIZE") (CINT "GL_VERTEX_ARRAY_TYPE") (CINT "GL_VERTEX_ARRAY_STRIDE") (CINT "GL_NORMAL_ARRAY_TYPE") (CINT "GL_NORMAL_ARRAY_STRIDE") (CINT "GL_COLOR_ARRAY_SIZE") (CINT "GL_COLOR_ARRAY_TYPE") (CINT "GL_COLOR_ARRAY_STRIDE") (CINT "GL_INDEX_ARRAY_TYPE") (CINT "GL_INDEX_ARRAY_STRIDE") (CINT "GL_TEXTURE_COORD_ARRAY_SIZE") (CINT "GL_TEXTURE_COORD_ARRAY_TYPE") (CINT "GL_TEXTURE_COORD_ARRAY_STRIDE") (CINT "GL_EDGE_FLAG_ARRAY_STRIDE") (CINT "GL_VERTEX_ARRAY_POINTER") (CINT "GL_NORMAL_ARRAY_POINTER") (CINT "GL_COLOR_ARRAY_POINTER") (CINT "GL_INDEX_ARRAY_POINTER") (CINT "GL_TEXTURE_COORD_ARRAY_POINTER") (CINT "GL_EDGE_FLAG_ARRAY_POINTER") (CINT "GL_V2F") (CINT "GL_V3F") (CINT "GL_C4UB_V2F") (CINT "GL_C4UB_V3F") (CINT "GL_C3F_V3F") (CINT "GL_N3F_V3F") (CINT "GL_C4F_N3F_V3F") (CINT "GL_T2F_V3F") (CINT "GL_T4F_V4F") (CINT "GL_T2F_C4UB_V3F") (CINT "GL_T2F_C3F_V3F") (CINT "GL_T2F_N3F_V3F") (CINT "GL_T2F_C4F_N3F_V3F") (CINT "GL_T4F_C4F_N3F_V4F") (CINT "GL_MATRIX_MODE") (CINT "GL_MODELVIEW") (CINT "GL_PROJECTION") (CINT "GL_TEXTURE") (CINT "GL_POINT_SMOOTH") (CINT "GL_POINT_SIZE") (CINT "GL_POINT_SIZE_GRANULARITY") (CINT "GL_POINT_SIZE_RANGE") (CINT "GL_LINE_SMOOTH") (CINT "GL_LINE_STIPPLE") (CINT "GL_LINE_STIPPLE_PATTERN") (CINT "GL_LINE_STIPPLE_REPEAT") (CINT "GL_LINE_WIDTH") (CINT "GL_LINE_WIDTH_GRANULARITY") (CINT "GL_LINE_WIDTH_RANGE") (CINT "GL_POINT") (CINT "GL_LINE") (CINT "GL_FILL") (CINT "GL_CW") (CINT "GL_CCW") (CINT "GL_FRONT") (CINT "GL_BACK") (CINT "GL_POLYGON_MODE") (CINT "GL_POLYGON_SMOOTH") (CINT "GL_POLYGON_STIPPLE") (CINT "GL_EDGE_FLAG") (CINT "GL_CULL_FACE") (CINT "GL_CULL_FACE_MODE") (CINT "GL_FRONT_FACE") (CINT "GL_POLYGON_OFFSET_FACTOR") (CINT "GL_POLYGON_OFFSET_UNITS") (CINT "GL_POLYGON_OFFSET_POINT") (CINT "GL_POLYGON_OFFSET_LINE") (CINT "GL_POLYGON_OFFSET_FILL") (CINT "GL_COMPILE") (CINT "GL_COMPILE_AND_EXECUTE") (CINT "GL_LIST_BASE") (CINT "GL_LIST_INDEX") (CINT "GL_LIST_MODE") (CINT "GL_NEVER") (CINT "GL_LESS") (CINT "GL_EQUAL") (CINT "GL_LEQUAL") (CINT "GL_GREATER") (CINT "GL_NOTEQUAL") (CINT "GL_GEQUAL") (CINT "GL_ALWAYS") (CINT "GL_DEPTH_TEST") (CINT "GL_DEPTH_BITS") (CINT "GL_DEPTH_CLEAR_VALUE") (CINT "GL_DEPTH_FUNC") (CINT "GL_DEPTH_RANGE") (CINT "GL_DEPTH_WRITEMASK") (CINT "GL_DEPTH_COMPONENT") (CINT "GL_LIGHTING") (CINT "GL_LIGHT0") (CINT "GL_LIGHT1") (CINT "GL_LIGHT2") (CINT "GL_LIGHT3") (CINT "GL_LIGHT4") (CINT "GL_LIGHT5") (CINT "GL_LIGHT6") (CINT "GL_LIGHT7") (CINT "GL_SPOT_EXPONENT") (CINT "GL_SPOT_CUTOFF") (CINT "GL_CONSTANT_ATTENUATION") (CINT "GL_LINEAR_ATTENUATION") (CINT "GL_QUADRATIC_ATTENUATION") (CINT "GL_AMBIENT") (CINT "GL_DIFFUSE") (CINT "GL_SPECULAR") (CINT "GL_SHININESS") (CINT "GL_EMISSION") (CINT "GL_POSITION") (CINT "GL_SPOT_DIRECTION") (CINT "GL_AMBIENT_AND_DIFFUSE") (CINT "GL_COLOR_INDEXES") (CINT "GL_LIGHT_MODEL_TWO_SIDE") (CINT "GL_LIGHT_MODEL_LOCAL_VIEWER") (CINT "GL_LIGHT_MODEL_AMBIENT") (CINT "GL_FRONT_AND_BACK") (CINT "GL_SHADE_MODEL") (CINT "GL_FLAT") (CINT "GL_SMOOTH") (CINT "GL_COLOR_MATERIAL") (CINT "GL_COLOR_MATERIAL_FACE") (CINT "GL_COLOR_MATERIAL_PARAMETER") (CINT "GL_NORMALIZE") (CINT "GL_CLIP_PLANE0") (CINT "GL_CLIP_PLANE1") (CINT "GL_CLIP_PLANE2") (CINT "GL_CLIP_PLANE3") (CINT "GL_CLIP_PLANE4") (CINT "GL_CLIP_PLANE5") (CINT "GL_ACCUM_RED_BITS") (CINT "GL_ACCUM_GREEN_BITS") (CINT "GL_ACCUM_BLUE_BITS") (CINT "GL_ACCUM_ALPHA_BITS") (CINT "GL_ACCUM_CLEAR_VALUE") (CINT "GL_ACCUM") (CINT "GL_ADD") (CINT "GL_LOAD") (CINT "GL_MULT") (CINT "GL_RETURN") (CINT "GL_ALPHA_TEST") (CINT "GL_ALPHA_TEST_REF") (CINT "GL_ALPHA_TEST_FUNC") (CINT "GL_BLEND") (CINT "GL_BLEND_SRC") (CINT "GL_BLEND_DST") (CINT "GL_ZERO") (CINT "GL_ONE") (CINT "GL_SRC_COLOR") (CINT "GL_ONE_MINUS_SRC_COLOR") (CINT "GL_DST_COLOR") (CINT "GL_ONE_MINUS_DST_COLOR") (CINT "GL_SRC_ALPHA") (CINT "GL_ONE_MINUS_SRC_ALPHA") (CINT "GL_DST_ALPHA") (CINT "GL_ONE_MINUS_DST_ALPHA") (CINT "GL_SRC_ALPHA_SATURATE") (CINT "GL_CONSTANT_COLOR") (CINT "GL_ONE_MINUS_CONSTANT_COLOR") (CINT "GL_CONSTANT_ALPHA") (CINT "GL_ONE_MINUS_CONSTANT_ALPHA") (CINT "GL_FEEDBACK") (CINT "GL_RENDER") (CINT "GL_SELECT") (CINT "GL_2D") (CINT "GL_3D") (CINT "GL_3D_COLOR") (CINT "GL_3D_COLOR_TEXTURE") (CINT "GL_4D_COLOR_TEXTURE") (CINT "GL_POINT_TOKEN") (CINT "GL_LINE_TOKEN") (CINT "GL_LINE_RESET_TOKEN") (CINT "GL_POLYGON_TOKEN") (CINT "GL_BITMAP_TOKEN") (CINT "GL_DRAW_PIXEL_TOKEN") (CINT "GL_COPY_PIXEL_TOKEN") (CINT "GL_PASS_THROUGH_TOKEN") (CINT "GL_FEEDBACK_BUFFER_POINTER") (CINT "GL_FEEDBACK_BUFFER_SIZE") (CINT "GL_FEEDBACK_BUFFER_TYPE") (CINT "GL_SELECTION_BUFFER_POINTER") (CINT "GL_SELECTION_BUFFER_SIZE") (CINT "GL_FOG") (CINT "GL_FOG_MODE") (CINT "GL_FOG_DENSITY") (CINT "GL_FOG_COLOR") (CINT "GL_FOG_INDEX") (CINT "GL_FOG_START") (CINT "GL_FOG_END") (CINT "GL_LINEAR") (CINT "GL_EXP") (CINT "GL_EXP2") (CINT "GL_LOGIC_OP") (CINT "GL_INDEX_LOGIC_OP") (CINT "GL_COLOR_LOGIC_OP") (CINT "GL_LOGIC_OP_MODE") (CINT "GL_CLEAR") (CINT "GL_SET") (CINT "GL_COPY") (CINT "GL_COPY_INVERTED") (CINT "GL_NOOP") (CINT "GL_INVERT") (CINT "GL_AND") (CINT "GL_NAND") (CINT "GL_OR") (CINT "GL_NOR") (CINT "GL_XOR") (CINT "GL_EQUIV") (CINT "GL_AND_REVERSE") (CINT "GL_AND_INVERTED") (CINT "GL_OR_REVERSE") (CINT "GL_OR_INVERTED") (CINT "GL_STENCIL_TEST") (CINT "GL_STENCIL_WRITEMASK") (CINT "GL_STENCIL_BITS") (CINT "GL_STENCIL_FUNC") (CINT "GL_STENCIL_VALUE_MASK") (CINT "GL_STENCIL_REF") (CINT "GL_STENCIL_FAIL") (CINT "GL_STENCIL_PASS_DEPTH_PASS") (CINT "GL_STENCIL_PASS_DEPTH_FAIL") (CINT "GL_STENCIL_CLEAR_VALUE") (CINT "GL_STENCIL_INDEX") (CINT "GL_KEEP") (CINT "GL_REPLACE") (CINT "GL_INCR") (CINT "GL_DECR") (CINT "GL_NONE") (CINT "GL_LEFT") (CINT "GL_RIGHT") (CINT "GL_FRONT_LEFT") (CINT "GL_FRONT_RIGHT") (CINT "GL_BACK_LEFT") (CINT "GL_BACK_RIGHT") (CINT "GL_AUX0") (CINT "GL_AUX1") (CINT "GL_AUX2") (CINT "GL_AUX3") (CINT "GL_COLOR_INDEX") (CINT "GL_RED") (CINT "GL_GREEN") (CINT "GL_BLUE") (CINT "GL_ALPHA") (CINT "GL_LUMINANCE") (CINT "GL_LUMINANCE_ALPHA") (CINT "GL_ALPHA_BITS") (CINT "GL_RED_BITS") (CINT "GL_GREEN_BITS") (CINT "GL_BLUE_BITS") (CINT "GL_INDEX_BITS") (CINT "GL_SUBPIXEL_BITS") (CINT "GL_AUX_BUFFERS") (CINT "GL_READ_BUFFER") (CINT "GL_DRAW_BUFFER") (CINT "GL_DOUBLEBUFFER") (CINT "GL_STEREO") (CINT "GL_BITMAP") (CINT "GL_COLOR") (CINT "GL_DEPTH") (CINT "GL_STENCIL") (CINT "GL_DITHER") (CINT "GL_RGB") (CINT "GL_RGBA") (CINT "GL_MAX_LIST_NESTING") (CINT "GL_MAX_ATTRIB_STACK_DEPTH") (CINT "GL_MAX_MODELVIEW_STACK_DEPTH") (CINT "GL_MAX_NAME_STACK_DEPTH") (CINT "GL_MAX_PROJECTION_STACK_DEPTH") (CINT "GL_MAX_TEXTURE_STACK_DEPTH") (CINT "GL_MAX_EVAL_ORDER") (CINT "GL_MAX_LIGHTS") (CINT "GL_MAX_CLIP_PLANES") (CINT "GL_MAX_TEXTURE_SIZE") (CINT "GL_MAX_PIXEL_MAP_TABLE") (CINT "GL_MAX_VIEWPORT_DIMS") (CINT "GL_MAX_CLIENT_ATTRIB_STACK_DEPTH") (CINT "GL_ATTRIB_STACK_DEPTH") (CINT "GL_CLIENT_ATTRIB_STACK_DEPTH") (CINT "GL_COLOR_CLEAR_VALUE") (CINT "GL_COLOR_WRITEMASK") (CINT "GL_CURRENT_INDEX") (CINT "GL_CURRENT_COLOR") (CINT "GL_CURRENT_NORMAL") (CINT "GL_CURRENT_RASTER_COLOR") (CINT "GL_CURRENT_RASTER_DISTANCE") (CINT "GL_CURRENT_RASTER_INDEX") (CINT "GL_CURRENT_RASTER_POSITION") (CINT "GL_CURRENT_RASTER_TEXTURE_COORDS") (CINT "GL_CURRENT_RASTER_POSITION_VALID") (CINT "GL_CURRENT_TEXTURE_COORDS") (CINT "GL_INDEX_CLEAR_VALUE") (CINT "GL_INDEX_MODE") (CINT "GL_INDEX_WRITEMASK") (CINT "GL_MODELVIEW_MATRIX") (CINT "GL_MODELVIEW_STACK_DEPTH") (CINT "GL_NAME_STACK_DEPTH") (CINT "GL_PROJECTION_MATRIX") (CINT "GL_PROJECTION_STACK_DEPTH") (CINT "GL_RENDER_MODE") (CINT "GL_RGBA_MODE") (CINT "GL_TEXTURE_MATRIX") (CINT "GL_TEXTURE_STACK_DEPTH") (CINT "GL_VIEWPORT") (CINT "GL_AUTO_NORMAL") (CINT "GL_MAP1_COLOR_4") (CINT "GL_MAP1_GRID_DOMAIN") (CINT "GL_MAP1_GRID_SEGMENTS") (CINT "GL_MAP1_INDEX") (CINT "GL_MAP1_NORMAL") (CINT "GL_MAP1_TEXTURE_COORD_1") (CINT "GL_MAP1_TEXTURE_COORD_2") (CINT "GL_MAP1_TEXTURE_COORD_3") (CINT "GL_MAP1_TEXTURE_COORD_4") (CINT "GL_MAP1_VERTEX_3") (CINT "GL_MAP1_VERTEX_4") (CINT "GL_MAP2_COLOR_4") (CINT "GL_MAP2_GRID_DOMAIN") (CINT "GL_MAP2_GRID_SEGMENTS") (CINT "GL_MAP2_INDEX") (CINT "GL_MAP2_NORMAL") (CINT "GL_MAP2_TEXTURE_COORD_1") (CINT "GL_MAP2_TEXTURE_COORD_2") (CINT "GL_MAP2_TEXTURE_COORD_3") (CINT "GL_MAP2_TEXTURE_COORD_4") (CINT "GL_MAP2_VERTEX_3") (CINT "GL_MAP2_VERTEX_4") (CINT "GL_COEFF") (CINT "GL_DOMAIN") (CINT "GL_ORDER") (CINT "GL_FOG_HINT") (CINT "GL_LINE_SMOOTH_HINT") (CINT "GL_PERSPECTIVE_CORRECTION_HINT") (CINT "GL_POINT_SMOOTH_HINT") (CINT "GL_POLYGON_SMOOTH_HINT") (CINT "GL_DONT_CARE") (CINT "GL_FASTEST") (CINT "GL_NICEST") (CINT "GL_SCISSOR_TEST") (CINT "GL_SCISSOR_BOX") (CINT "GL_MAP_COLOR") (CINT "GL_MAP_STENCIL") (CINT "GL_INDEX_SHIFT") (CINT "GL_INDEX_OFFSET") (CINT "GL_RED_SCALE") (CINT "GL_RED_BIAS") (CINT "GL_GREEN_SCALE") (CINT "GL_GREEN_BIAS") (CINT "GL_BLUE_SCALE") (CINT "GL_BLUE_BIAS") (CINT "GL_ALPHA_SCALE") (CINT "GL_ALPHA_BIAS") (CINT "GL_DEPTH_SCALE") (CINT "GL_DEPTH_BIAS") (CINT "GL_PIXEL_MAP_S_TO_S_SIZE") (CINT "GL_PIXEL_MAP_I_TO_I_SIZE") (CINT "GL_PIXEL_MAP_I_TO_R_SIZE") (CINT "GL_PIXEL_MAP_I_TO_G_SIZE") (CINT "GL_PIXEL_MAP_I_TO_B_SIZE") (CINT "GL_PIXEL_MAP_I_TO_A_SIZE") (CINT "GL_PIXEL_MAP_R_TO_R_SIZE") (CINT "GL_PIXEL_MAP_G_TO_G_SIZE") (CINT "GL_PIXEL_MAP_B_TO_B_SIZE") (CINT "GL_PIXEL_MAP_A_TO_A_SIZE") (CINT "GL_PIXEL_MAP_S_TO_S") (CINT "GL_PIXEL_MAP_I_TO_I") (CINT "GL_PIXEL_MAP_I_TO_R") (CINT "GL_PIXEL_MAP_I_TO_G") (CINT "GL_PIXEL_MAP_I_TO_B") (CINT "GL_PIXEL_MAP_I_TO_A") (CINT "GL_PIXEL_MAP_R_TO_R") (CINT "GL_PIXEL_MAP_G_TO_G") (CINT "GL_PIXEL_MAP_B_TO_B") (CINT "GL_PIXEL_MAP_A_TO_A") (CINT "GL_PACK_ALIGNMENT") (CINT "GL_PACK_LSB_FIRST") (CINT "GL_PACK_ROW_LENGTH") (CINT "GL_PACK_SKIP_PIXELS") (CINT "GL_PACK_SKIP_ROWS") (CINT "GL_PACK_SWAP_BYTES") (CINT "GL_UNPACK_ALIGNMENT") (CINT "GL_UNPACK_LSB_FIRST") (CINT "GL_UNPACK_ROW_LENGTH") (CINT "GL_UNPACK_SKIP_PIXELS") (CINT "GL_UNPACK_SKIP_ROWS") (CINT "GL_UNPACK_SWAP_BYTES") (CINT "GL_ZOOM_X") (CINT "GL_ZOOM_Y") (CINT "GL_TEXTURE_ENV") (CINT "GL_TEXTURE_ENV_MODE") (CINT "GL_TEXTURE_1D") (CINT "GL_TEXTURE_2D") (CINT "GL_TEXTURE_WRAP_S") (CINT "GL_TEXTURE_WRAP_T") (CINT "GL_TEXTURE_MAG_FILTER") (CINT "GL_TEXTURE_MIN_FILTER") (CINT "GL_TEXTURE_ENV_COLOR") (CINT "GL_TEXTURE_GEN_S") (CINT "GL_TEXTURE_GEN_T") (CINT "GL_TEXTURE_GEN_MODE") (CINT "GL_TEXTURE_BORDER_COLOR") (CINT "GL_TEXTURE_WIDTH") (CINT "GL_TEXTURE_HEIGHT") (CINT "GL_TEXTURE_BORDER") (CINT "GL_TEXTURE_COMPONENTS") (CINT "GL_TEXTURE_RED_SIZE") (CINT "GL_TEXTURE_GREEN_SIZE") (CINT "GL_TEXTURE_BLUE_SIZE") (CINT "GL_TEXTURE_ALPHA_SIZE") (CINT "GL_TEXTURE_LUMINANCE_SIZE") (CINT "GL_TEXTURE_INTENSITY_SIZE") (CINT "GL_NEAREST_MIPMAP_NEAREST") (CINT "GL_NEAREST_MIPMAP_LINEAR") (CINT "GL_LINEAR_MIPMAP_NEAREST") (CINT "GL_LINEAR_MIPMAP_LINEAR") (CINT "GL_OBJECT_LINEAR") (CINT "GL_OBJECT_PLANE") (CINT "GL_EYE_LINEAR") (CINT "GL_EYE_PLANE") (CINT "GL_SPHERE_MAP") (CINT "GL_DECAL") (CINT "GL_MODULATE") (CINT "GL_NEAREST") (CINT "GL_REPEAT") (CINT "GL_CLAMP") (CINT "GL_S") (CINT "GL_T") (CINT "GL_R") (CINT "GL_Q") (CINT "GL_TEXTURE_GEN_R") (CINT "GL_TEXTURE_GEN_Q") (CINT "GL_PROXY_TEXTURE_1D") (CINT "GL_PROXY_TEXTURE_2D") (CINT "GL_TEXTURE_PRIORITY") (CINT "GL_TEXTURE_RESIDENT") (CINT "GL_TEXTURE_BINDING_1D") (CINT "GL_TEXTURE_BINDING_2D") (CINT "GL_TEXTURE_INTERNAL_FORMAT") (CINT "GL_PACK_SKIP_IMAGES") (CINT "GL_PACK_IMAGE_HEIGHT") (CINT "GL_UNPACK_SKIP_IMAGES") (CINT "GL_UNPACK_IMAGE_HEIGHT") (CINT "GL_TEXTURE_3D") (CINT "GL_PROXY_TEXTURE_3D") (CINT "GL_TEXTURE_DEPTH") (CINT "GL_TEXTURE_WRAP_R") (CINT "GL_MAX_3D_TEXTURE_SIZE") (CINT "GL_TEXTURE_BINDING_3D") (CINT "GL_ALPHA4") (CINT "GL_ALPHA8") (CINT "GL_ALPHA12") (CINT "GL_ALPHA16") (CINT "GL_LUMINANCE4") (CINT "GL_LUMINANCE8") (CINT "GL_LUMINANCE12") (CINT "GL_LUMINANCE16") (CINT "GL_LUMINANCE4_ALPHA4") (CINT "GL_LUMINANCE6_ALPHA2") (CINT "GL_LUMINANCE8_ALPHA8") (CINT "GL_LUMINANCE12_ALPHA4") (CINT "GL_LUMINANCE12_ALPHA12") (CINT "GL_LUMINANCE16_ALPHA16") (CINT "GL_INTENSITY") (CINT "GL_INTENSITY4") (CINT "GL_INTENSITY8") (CINT "GL_INTENSITY12") (CINT "GL_INTENSITY16") (CINT "GL_R3_G3_B2") (CINT "GL_RGB4") (CINT "GL_RGB5") (CINT "GL_RGB8") (CINT "GL_RGB10") (CINT "GL_RGB12") (CINT "GL_RGB16") (CINT "GL_RGBA2") (CINT "GL_RGBA4") (CINT "GL_RGB5_A1") (CINT "GL_RGBA8") (CINT "GL_RGB10_A2") (CINT "GL_RGBA12") (CINT "GL_RGBA16") (CINT "GL_VENDOR") (CINT "GL_RENDERER") (CINT "GL_VERSION") (CINT "GL_EXTENSIONS") (CINT "GL_NO_ERROR") (CINT "GL_INVALID_VALUE") (CINT "GL_INVALID_ENUM") (CINT "GL_INVALID_OPERATION") (CINT "GL_STACK_OVERFLOW") (CINT "GL_STACK_UNDERFLOW") (CINT "GL_OUT_OF_MEMORY") (CINT "GL_RESCALE_NORMAL") (CINT "GL_CLAMP_TO_EDGE") (CINT "GL_MAX_ELEMENTS_VERTICES") (CINT "GL_MAX_ELEMENTS_INDICES") (CINT "GL_BGR") (CINT "GL_BGRA") (CINT "GL_UNSIGNED_BYTE_3_3_2") (CINT "GL_UNSIGNED_BYTE_2_3_3_REV") (CINT "GL_UNSIGNED_SHORT_5_6_5") (CINT "GL_UNSIGNED_SHORT_5_6_5_REV") (CINT "GL_UNSIGNED_SHORT_4_4_4_4") (CINT "GL_UNSIGNED_SHORT_4_4_4_4_REV") (CINT "GL_UNSIGNED_SHORT_5_5_5_1") (CINT "GL_UNSIGNED_SHORT_1_5_5_5_REV") (CINT "GL_UNSIGNED_INT_8_8_8_8") (CINT "GL_UNSIGNED_INT_8_8_8_8_REV") (CINT "GL_UNSIGNED_INT_10_10_10_2") (CINT "GL_UNSIGNED_INT_2_10_10_10_REV") (CINT "GL_LIGHT_MODEL_COLOR_CONTROL") (CINT "GL_SINGLE_COLOR") (CINT "GL_SEPARATE_SPECULAR_COLOR") (CINT "GL_TEXTURE_MIN_LOD") (CINT "GL_TEXTURE_MAX_LOD") (CINT "GL_TEXTURE_BASE_LEVEL") (CINT "GL_TEXTURE_MAX_LEVEL") ;(CINT "GL_SMOOTH_POINT_SIZE_RANGE") ;(CINT "GL_SMOOTH_POINT_SIZE_GRANULARITY") ;(CINT "GL_SMOOTH_LINE_WIDTH_RANGE") ;(CINT "GL_SMOOTH_LINE_WIDTH_GRANULARITY") ;(CINT "GL_ALIASED_POINT_SIZE_RANGE") ;(CINT "GL_ALIASED_LINE_WIDTH_RANGE") (CINT "GL_COLOR_TABLE") (CINT "GL_POST_CONVOLUTION_COLOR_TABLE") (CINT "GL_POST_COLOR_MATRIX_COLOR_TABLE") (CINT "GL_PROXY_COLOR_TABLE") (CINT "GL_PROXY_POST_CONVOLUTION_COLOR_TABLE") (CINT "GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE") (CINT "GL_COLOR_TABLE_SCALE") (CINT "GL_COLOR_TABLE_BIAS") (CINT "GL_COLOR_TABLE_FORMAT") (CINT "GL_COLOR_TABLE_WIDTH") (CINT "GL_COLOR_TABLE_RED_SIZE") (CINT "GL_COLOR_TABLE_GREEN_SIZE") (CINT "GL_COLOR_TABLE_BLUE_SIZE") (CINT "GL_COLOR_TABLE_ALPHA_SIZE") (CINT "GL_COLOR_TABLE_LUMINANCE_SIZE") (CINT "GL_COLOR_TABLE_INTENSITY_SIZE") (CINT "GL_CONVOLUTION_1D") (CINT "GL_CONVOLUTION_2D") (CINT "GL_SEPARABLE_2D") (CINT "GL_CONVOLUTION_BORDER_MODE") (CINT "GL_CONVOLUTION_FILTER_SCALE") (CINT "GL_CONVOLUTION_FILTER_BIAS") (CINT "GL_REDUCE") (CINT "GL_CONVOLUTION_FORMAT") (CINT "GL_CONVOLUTION_WIDTH") (CINT "GL_CONVOLUTION_HEIGHT") (CINT "GL_MAX_CONVOLUTION_WIDTH") (CINT "GL_MAX_CONVOLUTION_HEIGHT") (CINT "GL_POST_CONVOLUTION_RED_SCALE") (CINT "GL_POST_CONVOLUTION_GREEN_SCALE") (CINT "GL_POST_CONVOLUTION_BLUE_SCALE") (CINT "GL_POST_CONVOLUTION_ALPHA_SCALE") (CINT "GL_POST_CONVOLUTION_RED_BIAS") (CINT "GL_POST_CONVOLUTION_GREEN_BIAS") (CINT "GL_POST_CONVOLUTION_BLUE_BIAS") (CINT "GL_POST_CONVOLUTION_ALPHA_BIAS") (CINT "GL_CONSTANT_BORDER") (CINT "GL_REPLICATE_BORDER") (CINT "GL_CONVOLUTION_BORDER_COLOR") (CINT "GL_COLOR_MATRIX") (CINT "GL_COLOR_MATRIX_STACK_DEPTH") (CINT "GL_MAX_COLOR_MATRIX_STACK_DEPTH") (CINT "GL_POST_COLOR_MATRIX_RED_SCALE") (CINT "GL_POST_COLOR_MATRIX_GREEN_SCALE") (CINT "GL_POST_COLOR_MATRIX_BLUE_SCALE") (CINT "GL_POST_COLOR_MATRIX_ALPHA_SCALE") (CINT "GL_POST_COLOR_MATRIX_RED_BIAS") (CINT "GL_POST_COLOR_MATRIX_GREEN_BIAS") (CINT "GL_POST_COLOR_MATRIX_BLUE_BIAS") (CINT "GL_POST_COLOR_MATRIX_ALPHA_BIAS") (CINT "GL_HISTOGRAM") (CINT "GL_PROXY_HISTOGRAM") (CINT "GL_HISTOGRAM_WIDTH") (CINT "GL_HISTOGRAM_FORMAT") (CINT "GL_HISTOGRAM_RED_SIZE") (CINT "GL_HISTOGRAM_GREEN_SIZE") (CINT "GL_HISTOGRAM_BLUE_SIZE") (CINT "GL_HISTOGRAM_ALPHA_SIZE") (CINT "GL_HISTOGRAM_LUMINANCE_SIZE") (CINT "GL_HISTOGRAM_SINK") (CINT "GL_MINMAX") (CINT "GL_MINMAX_FORMAT") (CINT "GL_MINMAX_SINK") (CINT "GL_TABLE_TOO_LARGE") (CINT "GL_BLEND_EQUATION") (CINT "GL_MIN") (CINT "GL_MAX") (CINT "GL_FUNC_ADD") (CINT "GL_FUNC_SUBTRACT") (CINT "GL_FUNC_REVERSE_SUBTRACT") (CINT "GL_BLEND_COLOR") (CINT "GL_CURRENT_BIT") (CINT "GL_POINT_BIT") (CINT "GL_LINE_BIT") (CINT "GL_POLYGON_BIT") (CINT "GL_POLYGON_STIPPLE_BIT") (CINT "GL_PIXEL_MODE_BIT") (CINT "GL_LIGHTING_BIT") (CINT "GL_FOG_BIT") (CINT "GL_DEPTH_BUFFER_BIT") (CINT "GL_ACCUM_BUFFER_BIT") (CINT "GL_STENCIL_BUFFER_BIT") (CINT "GL_VIEWPORT_BIT") (CINT "GL_TRANSFORM_BIT") (CINT "GL_ENABLE_BIT") (CINT "GL_COLOR_BUFFER_BIT") (CINT "GL_HINT_BIT") (CINT "GL_EVAL_BIT") (CINT "GL_LIST_BIT") (CINT "GL_TEXTURE_BIT") (CINT "GL_SCISSOR_BIT") (CINT "GL_ALL_ATTRIB_BITS") (CINT "GL_CLIENT_PIXEL_STORE_BIT") (CINT "GL_CLIENT_VERTEX_ARRAY_BIT") ;(CINT "GL_ALL_CLIENT_ATTRIB_BITS") (CINT-multi "GL_TEXTURE0_ARB") (CINT-multi "GL_TEXTURE1_ARB") (CINT-multi "GL_TEXTURE2_ARB") (CINT-multi "GL_TEXTURE3_ARB") (CINT-multi "GL_TEXTURE4_ARB") (CINT-multi "GL_TEXTURE5_ARB") (CINT-multi "GL_TEXTURE6_ARB") (CINT-multi "GL_TEXTURE7_ARB") (CINT-multi "GL_TEXTURE8_ARB") (CINT-multi "GL_TEXTURE9_ARB") (CINT-multi "GL_TEXTURE10_ARB") (CINT-multi "GL_TEXTURE11_ARB") (CINT-multi "GL_TEXTURE12_ARB") (CINT-multi "GL_TEXTURE13_ARB") (CINT-multi "GL_TEXTURE14_ARB") (CINT-multi "GL_TEXTURE15_ARB") (CINT-multi "GL_TEXTURE16_ARB") (CINT-multi "GL_TEXTURE17_ARB") (CINT-multi "GL_TEXTURE18_ARB") (CINT-multi "GL_TEXTURE19_ARB") (CINT-multi "GL_TEXTURE20_ARB") (CINT-multi "GL_TEXTURE21_ARB") (CINT-multi "GL_TEXTURE22_ARB") (CINT-multi "GL_TEXTURE23_ARB") (CINT-multi "GL_TEXTURE24_ARB") (CINT-multi "GL_TEXTURE25_ARB") (CINT-multi "GL_TEXTURE26_ARB") (CINT-multi "GL_TEXTURE27_ARB") (CINT-multi "GL_TEXTURE28_ARB") (CINT-multi "GL_TEXTURE29_ARB") (CINT-multi "GL_TEXTURE30_ARB") (CINT-multi "GL_TEXTURE31_ARB") (CINT-multi "GL_ACTIVE_TEXTURE_ARB") (CINT-multi "GL_CLIENT_ACTIVE_TEXTURE_ARB") (CINT-multi "GL_MAX_TEXTURE_UNITS_ARB") (CINT "GLU_FALSE") (CINT "GLU_TRUE") ;(CINT "GLU_VERSION_1_1") ;(CINT "GLU_VERSION_1_2") ;(CINT "GLU_VERSION_1_3") (CINT "GLU_VERSION") (CINT "GLU_EXTENSIONS") (CINT "GLU_INVALID_ENUM") (CINT "GLU_INVALID_VALUE") (CINT "GLU_OUT_OF_MEMORY") (CINT "GLU_INVALID_OPERATION") (CINT "GLU_OUTLINE_POLYGON") (CINT "GLU_OUTLINE_PATCH") (CINT "GLU_NURBS_ERROR") (CINT "GLU_ERROR") (CINT "GLU_NURBS_BEGIN") (CINT "GLU_NURBS_VERTEX") (CINT "GLU_NURBS_NORMAL") (CINT "GLU_NURBS_COLOR") (CINT "GLU_NURBS_TEXTURE_COORD") (CINT "GLU_NURBS_END") (CINT "GLU_NURBS_BEGIN_DATA") (CINT "GLU_NURBS_VERTEX_DATA") (CINT "GLU_NURBS_NORMAL_DATA") (CINT "GLU_NURBS_COLOR_DATA") (CINT "GLU_NURBS_TEXTURE_COORD_DATA") (CINT "GLU_NURBS_END_DATA") (CINT "GLU_NURBS_ERROR1") (CINT "GLU_NURBS_ERROR2") (CINT "GLU_NURBS_ERROR3") (CINT "GLU_NURBS_ERROR4") (CINT "GLU_NURBS_ERROR5") (CINT "GLU_NURBS_ERROR6") (CINT "GLU_NURBS_ERROR7") (CINT "GLU_NURBS_ERROR8") (CINT "GLU_NURBS_ERROR9") (CINT "GLU_NURBS_ERROR10") (CINT "GLU_NURBS_ERROR11") (CINT "GLU_NURBS_ERROR12") (CINT "GLU_NURBS_ERROR13") (CINT "GLU_NURBS_ERROR14") (CINT "GLU_NURBS_ERROR15") (CINT "GLU_NURBS_ERROR16") (CINT "GLU_NURBS_ERROR17") (CINT "GLU_NURBS_ERROR18") (CINT "GLU_NURBS_ERROR19") (CINT "GLU_NURBS_ERROR20") (CINT "GLU_NURBS_ERROR21") (CINT "GLU_NURBS_ERROR22") (CINT "GLU_NURBS_ERROR23") (CINT "GLU_NURBS_ERROR24") (CINT "GLU_NURBS_ERROR25") (CINT "GLU_NURBS_ERROR26") (CINT "GLU_NURBS_ERROR27") (CINT "GLU_NURBS_ERROR28") (CINT "GLU_NURBS_ERROR29") (CINT "GLU_NURBS_ERROR30") (CINT "GLU_NURBS_ERROR31") (CINT "GLU_NURBS_ERROR32") (CINT "GLU_NURBS_ERROR33") (CINT "GLU_NURBS_ERROR34") (CINT "GLU_NURBS_ERROR35") (CINT "GLU_NURBS_ERROR36") (CINT "GLU_NURBS_ERROR37") (CINT "GLU_AUTO_LOAD_MATRIX") (CINT "GLU_CULLING") (CINT "GLU_SAMPLING_TOLERANCE") (CINT "GLU_DISPLAY_MODE") (CINT "GLU_PARAMETRIC_TOLERANCE") (CINT "GLU_SAMPLING_METHOD") (CINT "GLU_U_STEP") (CINT "GLU_V_STEP") (CINT "GLU_NURBS_MODE") (CINT "GLU_NURBS_TESSELLATOR") (CINT "GLU_NURBS_RENDERER") (CINT "GLU_OBJECT_PARAMETRIC_ERROR") (CINT "GLU_OBJECT_PATH_LENGTH") (CINT "GLU_PATH_LENGTH") (CINT "GLU_PARAMETRIC_ERROR") (CINT "GLU_DOMAIN_DISTANCE") (CINT "GLU_MAP1_TRIM_2") (CINT "GLU_MAP1_TRIM_3") (CINT "GLU_POINT") (CINT "GLU_LINE") (CINT "GLU_FILL") (CINT "GLU_SILHOUETTE") (CINT "GLU_SMOOTH") (CINT "GLU_FLAT") (CINT "GLU_NONE") (CINT "GLU_OUTSIDE") (CINT "GLU_INSIDE") (CINT "GLU_TESS_BEGIN") (CINT "GLU_BEGIN") (CINT "GLU_TESS_VERTEX") (CINT "GLU_VERTEX") (CINT "GLU_TESS_END") (CINT "GLU_END") (CINT "GLU_TESS_ERROR") (CINT "GLU_TESS_EDGE_FLAG") (CINT "GLU_EDGE_FLAG") (CINT "GLU_TESS_COMBINE") (CINT "GLU_TESS_BEGIN_DATA") (CINT "GLU_TESS_VERTEX_DATA") (CINT "GLU_TESS_END_DATA") (CINT "GLU_TESS_ERROR_DATA") (CINT "GLU_TESS_EDGE_FLAG_DATA") (CINT "GLU_TESS_COMBINE_DATA") (CINT "GLU_CW") (CINT "GLU_CCW") (CINT "GLU_INTERIOR") (CINT "GLU_EXTERIOR") (CINT "GLU_UNKNOWN") (CINT "GLU_TESS_WINDING_RULE") (CINT "GLU_TESS_BOUNDARY_ONLY") (CINT "GLU_TESS_TOLERANCE") (CINT "GLU_TESS_ERROR1") (CINT "GLU_TESS_ERROR2") (CINT "GLU_TESS_ERROR3") (CINT "GLU_TESS_ERROR4") (CINT "GLU_TESS_ERROR5") (CINT "GLU_TESS_ERROR6") (CINT "GLU_TESS_ERROR7") (CINT "GLU_TESS_ERROR8") (CINT "GLU_TESS_MISSING_BEGIN_POLYGON") (CINT "GLU_TESS_MISSING_BEGIN_CONTOUR") (CINT "GLU_TESS_MISSING_END_POLYGON") (CINT "GLU_TESS_MISSING_END_CONTOUR") (CINT "GLU_TESS_COORD_TOO_LARGE") (CINT "GLU_TESS_NEED_COMBINE_CALLBACK") (CINT "GLU_TESS_WINDING_ODD") (CINT "GLU_TESS_WINDING_NONZERO") (CINT "GLU_TESS_WINDING_POSITIVE") (CINT "GLU_TESS_WINDING_NEGATIVE") (CINT "GLU_TESS_WINDING_ABS_GEQ_TWO") ;(CINT "GLU_TESS_MAX_COORD") ; this is a float (1e150) snd-16.1/tools/xgdata.scm0000644000076400007640000223441712625110635013465 0ustar bilbil;;; [] for ref args, @ for ptr args that can be null, # are optional (default #f) ;;; || for ref arg list, {} for ref arg int as list len ;;; & in struct for settable field (CFNC "gboolean g_unichar_validate gunichar ch") (CFNC "gboolean g_unichar_isalnum gunichar c") (CFNC "gboolean g_unichar_isalpha gunichar c") (CFNC "gboolean g_unichar_iscntrl gunichar c") (CFNC "gboolean g_unichar_isdefined gunichar c") (CFNC "gboolean g_unichar_isdigit gunichar c") (CFNC "gboolean g_unichar_isgraph gunichar c") (CFNC "gboolean g_unichar_islower gunichar c") (CFNC "gboolean g_unichar_ismark gunichar c") (CFNC "gboolean g_unichar_isprint gunichar c") (CFNC "gboolean g_unichar_ispunct gunichar c") (CFNC "gboolean g_unichar_isspace gunichar c") (CFNC "gboolean g_unichar_istitle gunichar c") (CFNC "gboolean g_unichar_isupper gunichar c") (CFNC "gboolean g_unichar_isxdigit gunichar c") (CFNC "gboolean g_unichar_iswide gunichar c") (CFNC "gboolean g_unichar_iswide_cjk gunichar c") (CFNC "gboolean g_unichar_iszerowidth gunichar c") (CFNC "gunichar g_unichar_toupper gunichar c") (CFNC "gunichar g_unichar_tolower gunichar c") (CFNC "gunichar g_unichar_totitle gunichar c") (CFNC "gint g_unichar_digit_value gunichar c") (CFNC "gint g_unichar_xdigit_value gunichar c") ;(CFNC "gboolean g_unichar_compose gunichar a gunichar b gunichar* [ch]") ;(CFNC "gboolean g_unichar_decompose gunichar ch gunichar* a gunichar* [b]") ;(CFNC "gsize g_unichar_fully_decompose gunichar ch gboolean compat gunichar* [result] gsize result_len") (CFNC "gint g_unichar_combining_class gunichar uc") (CFNC "void g_unicode_canonical_ordering gunichar* string gsize len") ;(CFNC "gunichar* g_unicode_canonical_decomposition gunichar ch gsize* [result_len]") ;(CFNC "gboolean g_unichar_get_mirror_char gunichar ch gunichar* mirrored_ch") (CFNC "gunichar g_utf8_get_char gchar* p" 'const) (CFNC "gunichar g_utf8_get_char_validated gchar* p gssize max_len" 'const) (CFNC "gchar* g_utf8_prev_char gchar* p" 'const) (CFNC "gchar* g_utf8_find_next_char gchar* p gchar* end" 'const) (CFNC "gchar* g_utf8_find_prev_char gchar* str gchar* p" 'const) (CFNC "glong g_utf8_strlen gchar* p gssize max" 'const) ;(CFNC "gchar* g_utf8_strncpy gchar* dest gchar* src gsize n" 'const) (CFNC "gchar* g_utf8_strchr gchar* p gssize len gunichar c" 'const) (CFNC "gchar* g_utf8_strrchr gchar* p gssize len gunichar c" 'const) (CFNC "gchar* g_utf8_strreverse gchar* str gssize len" 'const) ;(CFNC "gchar* g_utf8_substring gchar* str glong start_pos glong end_pos" 'const) (CFNC "gboolean g_utf8_validate gchar* str gssize max_len gchar** [end]" 'const) (CFNC "gchar* g_utf8_strup gchar* str gssize len" 'const) (CFNC "gchar* g_utf8_strdown gchar* str gssize len" 'const) (CFNC "gchar* g_utf8_casefold gchar* str gssize len" 'const) (CFNC "gchar* g_utf8_normalize gchar* str gssize len GNormalizeMode mode" 'const) (CFNC "gint g_utf8_collate gchar* str1 gchar* str2" 'const) (CFNC "gchar* g_utf8_collate_key gchar* str gssize len" 'const) (CFNC "gchar* g_utf8_collate_key_for_filename gchar* str gssize len" 'const) (CINT "G_NORMALIZE_DEFAULT" "GNormalizeMode") (CINT "G_NORMALIZE_NFD" "GNormalizeMode") (CINT "G_NORMALIZE_DEFAULT_COMPOSE" "GNormalizeMode") (CINT "G_NORMALIZE_NFC" "GNormalizeMode") (CINT "G_NORMALIZE_ALL" "GNormalizeMode") (CINT "G_NORMALIZE_NFKD" "GNormalizeMode") (CINT "G_NORMALIZE_ALL_COMPOSE" "GNormalizeMode") (CINT "G_NORMALIZE_NFKC" "GNormalizeMode") ;gunichar is int ;(CFNC "gchar* g_type_name GType type") ;(CFNC "GQuark g_type_qname GType type") ;(CFNC "GType g_type_from_name gchar* name") ;(CFNC "GType g_type_parent GType type") ;(CFNC "gboolean g_type_is_a GType type GType is_a_type") (CINT "G_SIGNAL_RUN_FIRST" "GSignalFlags") (CINT "G_SIGNAL_RUN_LAST" "GSignalFlags") (CINT "G_SIGNAL_RUN_CLEANUP" "GSignalFlags") (CINT "G_SIGNAL_NO_RECURSE" "GSignalFlags") (CINT "G_SIGNAL_DETAILED" "GSignalFlags") (CINT "G_SIGNAL_ACTION" "GSignalFlags") (CINT "G_SIGNAL_NO_HOOKS" "GSignalFlags") (CINT "G_CONNECT_AFTER" "GConnectFlags") (CINT "G_CONNECT_SWAPPED" "GConnectFlags") (CINT "G_SIGNAL_MATCH_ID" "GSignalMatchType") (CINT "G_SIGNAL_MATCH_DETAIL" "GSignalMatchType") (CINT "G_SIGNAL_MATCH_CLOSURE" "GSignalMatchType") (CINT "G_SIGNAL_MATCH_FUNC" "GSignalMatchType") (CINT "G_SIGNAL_MATCH_DATA" "GSignalMatchType") (CINT "G_SIGNAL_MATCH_UNBLOCKED" "GSignalMatchType") (CFNC "GClosure* g_cclosure_new GCallback func lambda_data func_info GClosureNotify @destroy_data") (CFNC "guint g_signal_newv gchar* signal_name GType itype GSignalFlags signal_flags GClosure* @class_closure GSignalAccumulator accumulator gpointer accu_data GSignalCMarshaller c_marshaller GType return_type guint n_params GType* param_types") ;;;(CFNC "guint g_signal_new_valist gchar* signal_name GType itype GSignalFlags signal_flags GClosure* @class_closure GSignalAccumulator accumulator gpointer accu_data GSignalCMarshaller c_marshaller GType return_type guint n_params va_list args") ;;; (CFNC "guint g_signal_new gchar* signal_name GType itype GSignalFlags signal_flags guint class_offset GSignalAccumulator accumulator gpointer accu_data GSignalCMarshaller c_marshaller GType return_type guint n_params ...") ;; typedef GClosureMarshal GSignalCMarshaller; ;; typedef void (*GClosureNotify) (gpointer data, GClosure *closure) ;; typedef void (*GClosureMarshal)(GClosure *closure,GValue *return_value,guint n_param_values,const GValue *param_values,gpointer invocation_hint,gpointer marshal_data) ;;; (CFNC "void g_signal_emitv GValue* instance_and_params guint signal_id GQuark detail GValue* [return_value]") ;;; the [retval] business causes type cast trouble with GValue ;;;;(CFNC "void g_signal_emit_valist gpointer instance guint signal_id GQuark detail va_list var_args") ;;; (CFNC "void g_signal_emit gpointer instance guint signal_id GQuark detail ...") ;;; (CFNC "void g_signal_emit_by_name gpointer instance gchar* detailed_signal ...") (CFNC "guint g_signal_lookup gchar* name GType itype") (CFNC "gchar* g_signal_name guint signal_id") (CFNC "void g_signal_query guint signal_id GSignalQuery* query") (CFNC "guint* g_signal_list_ids GType itype guint* n_ids") (CFNC "gboolean g_signal_parse_name gchar* detailed_signal GType itype guint* [signal_id_p] GQuark* [detail_p] gboolean force_detail_quark") (CFNC "GSignalInvocationHint* g_signal_get_invocation_hint gpointer instance") (CFNC "void g_signal_stop_emission gpointer instance guint signal_id GQuark detail") (CFNC "void g_signal_stop_emission_by_name gpointer instance gchar* detailed_signal") (CFNC "gulong g_signal_add_emission_hook guint signal_id GQuark quark GSignalEmissionHook hook_func lambda_data func_info GtkDestroyNotify data_destroy") (CFNC "void g_signal_remove_emission_hook guint signal_id gulong hook_id") (CFNC "gboolean g_signal_has_handler_pending gpointer instance guint signal_id GQuark detail gboolean may_be_blocked") (CFNC "gulong g_signal_connect_closure_by_id gpointer instance guint signal_id GQuark detail GClosure* closure gboolean after") (CFNC "gulong g_signal_connect_closure gpointer instance gchar* detailed_signal GClosure* closure gboolean after") (CFNC "gulong g_signal_connect_data gpointer instance gchar* detailed_signal GCallback func lambda_data func_info GClosureNotify @destroy_data GConnectFlags connect_flags") ;; these are macros in glib/gobject/gsignal.h, but we can't use them directly here due to infinite type troubles ;; (CFNC "gulong g_signal_connect gpointer instance gchar* detailed_signal GCallback func lambda_data #func_info") ;; (CFNC "gulong g_signal_connect_after gpointer instance gchar* detailed_signal GCallback func lambda_data #func_info") ;; (CFNC "gulong g_signal_connect_swapped gpointer instance gchar* detailed_signal GCallback func lambda_data #func_info") ;; (CFNC "guint g_signal_handlers_disconnect_by_func gpointer instance GCallback func lambda_data #func_info") ;; (CFNC "guint g_signal_handlers_block_by_func gpointer instance GCallback func lambda_data #func_info") ;; (CFNC "guint g_signal_handlers_unblock_by_func gpointer instance GCallback func lambda_data #func_info") (CFNC "void g_signal_handler_block gpointer instance gulong handler_id") (CFNC "void g_signal_handler_unblock gpointer instance gulong handler_id") (CFNC "void g_signal_handler_disconnect gpointer instance gulong handler_id") (CFNC "gboolean g_signal_handler_is_connected gpointer instance gulong handler_id") (CFNC "gulong g_signal_handler_find gpointer instance GSignalMatchType mask guint signal_id GQuark detail GClosure* @closure gpointer func gpointer data") (CFNC "guint g_signal_handlers_block_matched gpointer instance GSignalMatchType mask guint signal_id GQuark detail GClosure* @closure gpointer func gpointer data") (CFNC "guint g_signal_handlers_unblock_matched gpointer instance GSignalMatchType mask guint signal_id GQuark detail GClosure* @closure gpointer func gpointer data") (CFNC "guint g_signal_handlers_disconnect_matched gpointer instance GSignalMatchType mask guint signal_id GQuark detail GClosure* @closure gpointer func gpointer data") (CFNC "void g_signal_handlers_destroy gpointer instance") ;(CFNC "void _g_signals_destroy GType itype") (CFNC "gpointer g_object_ref gpointer object") (CFNC "void g_object_unref gpointer object") ;;; (CCAST-gtk2 "GDK_COLORMAP(object)" "GdkColormap*") ;;; (CCHK-gtk2 "GDK_IS_COLORMAP(object)" "GdkColormap*") ;;;;(CFNC "GType gdk_colormap_get_type void") (CFNC "GdkVisual* gdk_visual_get_system void") ; -- moved ahead of the gtk2 stuff ;;; (CFNC-gtk2 "GdkColor* gdk_color_copy GdkColor* color") ;;; (CFNC-gtk2 "GdkColormap* gdk_colormap_new GdkVisual* visual gboolean allocate") ;;; (CFNC-gtk2 "GdkColormap* gdk_colormap_get_system void") ;;; (CFNC-gtk2 "gint gdk_colormap_alloc_colors GdkColormap* colormap GdkColor* colors gint ncolors gboolean writeable gboolean best_match gboolean* [success]") ;;; (CFNC-gtk2 "gboolean gdk_colormap_alloc_color GdkColormap* colormap GdkColor* color gboolean writeable gboolean best_match") ;;; 2.91.0 ;(CFNC "void gdk_colormap_free_colors GdkColormap* colormap GdkColor* colors gint ncolors") ;can't currently pass the color struct as array element ;;; 2.90.6 (CFNC "void gdk_colormap_query_color GdkColormap* colormap gulong pixel GdkColor* result") ;;; (CFNC-gtk2 "GdkVisual* gdk_colormap_get_visual GdkColormap* colormap") ;;; (CFNC-gtk2 "void gdk_color_free GdkColor* color") ;;; (CFNC-gtk2 "gint gdk_color_parse gchar* spec GdkColor* color") ;;; (CFNC-gtk2 "guint gdk_color_hash GdkColor* colora") ;;; (CFNC-gtk2 "gboolean gdk_color_equal GdkColor* colora GdkColor* colorb") ;;;;(CFNC "GType gdk_color_get_type void") (CINT "GDK_X_CURSOR" "GdkCursorType") (CINT "GDK_ARROW" "GdkCursorType") (CINT "GDK_BASED_ARROW_DOWN" "GdkCursorType") (CINT "GDK_BASED_ARROW_UP" "GdkCursorType") (CINT "GDK_BOAT" "GdkCursorType") (CINT "GDK_BOGOSITY" "GdkCursorType") (CINT "GDK_BOTTOM_LEFT_CORNER" "GdkCursorType") (CINT "GDK_BOTTOM_RIGHT_CORNER" "GdkCursorType") (CINT "GDK_BOTTOM_SIDE" "GdkCursorType") (CINT "GDK_BOTTOM_TEE" "GdkCursorType") (CINT "GDK_BOX_SPIRAL" "GdkCursorType") (CINT "GDK_CENTER_PTR" "GdkCursorType") (CINT "GDK_CIRCLE" "GdkCursorType") (CINT "GDK_CLOCK" "GdkCursorType") (CINT "GDK_COFFEE_MUG" "GdkCursorType") (CINT "GDK_CROSS" "GdkCursorType") (CINT "GDK_CROSS_REVERSE" "GdkCursorType") (CINT "GDK_CROSSHAIR" "GdkCursorType") (CINT "GDK_DIAMOND_CROSS" "GdkCursorType") (CINT "GDK_DOT" "GdkCursorType") (CINT "GDK_DOTBOX" "GdkCursorType") (CINT "GDK_DOUBLE_ARROW" "GdkCursorType") (CINT "GDK_DRAFT_LARGE" "GdkCursorType") (CINT "GDK_DRAFT_SMALL" "GdkCursorType") (CINT "GDK_DRAPED_BOX" "GdkCursorType") (CINT "GDK_EXCHANGE" "GdkCursorType") (CINT "GDK_FLEUR" "GdkCursorType") (CINT "GDK_GOBBLER" "GdkCursorType") (CINT "GDK_GUMBY" "GdkCursorType") (CINT "GDK_HAND1" "GdkCursorType") (CINT "GDK_HAND2" "GdkCursorType") (CINT "GDK_HEART" "GdkCursorType") (CINT "GDK_ICON" "GdkCursorType") (CINT "GDK_IRON_CROSS" "GdkCursorType") (CINT "GDK_LEFT_PTR" "GdkCursorType") (CINT "GDK_LEFT_SIDE" "GdkCursorType") (CINT "GDK_LEFT_TEE" "GdkCursorType") (CINT "GDK_LEFTBUTTON" "GdkCursorType") (CINT "GDK_LL_ANGLE" "GdkCursorType") (CINT "GDK_LR_ANGLE" "GdkCursorType") (CINT "GDK_MAN" "GdkCursorType") (CINT "GDK_MIDDLEBUTTON" "GdkCursorType") (CINT "GDK_MOUSE" "GdkCursorType") (CINT "GDK_PENCIL" "GdkCursorType") (CINT "GDK_PIRATE" "GdkCursorType") (CINT "GDK_PLUS" "GdkCursorType") (CINT "GDK_QUESTION_ARROW" "GdkCursorType") (CINT "GDK_RIGHT_PTR" "GdkCursorType") (CINT "GDK_RIGHT_SIDE" "GdkCursorType") (CINT "GDK_RIGHT_TEE" "GdkCursorType") (CINT "GDK_RIGHTBUTTON" "GdkCursorType") (CINT "GDK_RTL_LOGO" "GdkCursorType") (CINT "GDK_SAILBOAT" "GdkCursorType") (CINT "GDK_SB_DOWN_ARROW" "GdkCursorType") (CINT "GDK_SB_H_DOUBLE_ARROW" "GdkCursorType") (CINT "GDK_SB_LEFT_ARROW" "GdkCursorType") (CINT "GDK_SB_RIGHT_ARROW" "GdkCursorType") (CINT "GDK_SB_UP_ARROW" "GdkCursorType") (CINT "GDK_SB_V_DOUBLE_ARROW" "GdkCursorType") (CINT "GDK_SHUTTLE" "GdkCursorType") (CINT "GDK_SIZING" "GdkCursorType") (CINT "GDK_SPIDER" "GdkCursorType") (CINT "GDK_SPRAYCAN" "GdkCursorType") (CINT "GDK_STAR" "GdkCursorType") (CINT "GDK_TARGET" "GdkCursorType") (CINT "GDK_TCROSS" "GdkCursorType") (CINT "GDK_TOP_LEFT_ARROW" "GdkCursorType") (CINT "GDK_TOP_LEFT_CORNER" "GdkCursorType") (CINT "GDK_TOP_RIGHT_CORNER" "GdkCursorType") (CINT "GDK_TOP_SIDE" "GdkCursorType") (CINT "GDK_TOP_TEE" "GdkCursorType") (CINT "GDK_TREK" "GdkCursorType") (CINT "GDK_UL_ANGLE" "GdkCursorType") (CINT "GDK_UMBRELLA" "GdkCursorType") (CINT "GDK_UR_ANGLE" "GdkCursorType") (CINT "GDK_WATCH" "GdkCursorType") (CINT "GDK_XTERM" "GdkCursorType") (CINT "GDK_LAST_CURSOR " "GdkCursorType") ;;; 2.91.0 (CINT "GDK_CURSOR_IS_PIXMAP" "GdkCursorType") ;;; these were missed at some point: (CFNC "GdkCursor* gdk_cursor_new_for_display GdkDisplay* display GdkCursorType cursor_type") (CFNC "GdkDisplay* gdk_cursor_get_display GdkCursor* cursor") ;;;;(CFNC "GType gdk_cursor_get_type void") ;;; 3.15.2 (CFNC "GdkCursor* gdk_cursor_new GdkCursorType cursor_type") ;;; 2.91.0 (CFNC "GdkCursor* gdk_cursor_new_from_pixmap GdkPixmap* source GdkPixmap* mask GdkColor* fg GdkColor* bg gint x gint y") ;;; (CFNC-gtk2 "GdkCursor* gdk_cursor_ref GdkCursor* cursor") ;;; (CFNC-gtk2 "void gdk_cursor_unref GdkCursor* cursor") (CINT "GDK_ACTION_DEFAULT" "GdkDragAction") (CINT "GDK_ACTION_COPY" "GdkDragAction") (CINT "GDK_ACTION_MOVE" "GdkDragAction") (CINT "GDK_ACTION_LINK" "GdkDragAction") (CINT "GDK_ACTION_PRIVATE" "GdkDragAction") (CINT "GDK_ACTION_ASK" "GdkDragAction") ;;; ;;; 3.9.0 (CINT-gtk2 "GDK_DRAG_PROTO_MOTIF" "GdkDragProtocol") ;;; (CINT-gtk2 "GDK_DRAG_PROTO_XDND" "GdkDragProtocol") ;;; (CINT-gtk2 "GDK_DRAG_PROTO_ROOTWIN" "GdkDragProtocol") ;;; (CINT-gtk2 "GDK_DRAG_PROTO_NONE" "GdkDragProtocol") ;;; (CINT-gtk2 "GDK_DRAG_PROTO_WIN32_DROPFILES" "GdkDragProtocol") ;;; (CINT-gtk2 "GDK_DRAG_PROTO_OLE2" "GdkDragProtocol") ;;; (CINT-gtk2 "GDK_DRAG_PROTO_LOCAL" "GdkDragProtocol") (CCAST "GDK_DRAG_CONTEXT(object)" "GdkDragContext*") (CCHK "GDK_IS_DRAG_CONTEXT(object)" "GdkDragContext*") ;;;;(CFNC "GType gdk_drag_context_get_type void") (CFNC "void gdk_drag_status GdkDragContext* context GdkDragAction action guint32 time") (CFNC "void gdk_drop_reply GdkDragContext* context gboolean ok guint32 time") (CFNC "void gdk_drop_finish GdkDragContext* context gboolean success guint32 time") (CFNC "GdkAtom gdk_drag_get_selection GdkDragContext* context") (CFNC "GdkDragContext* gdk_drag_begin GdkWindow* window GList* targets") ;;; (CFNC-gtk2 "GdkDragContext* gdk_drag_context_new void") ;;; (CFNC-gtk2 "guint32 gdk_drag_get_protocol guint32 xid GdkDragProtocol* [protocol]") ;;; (CFNC-gtk2 "void gdk_drag_find_window GdkDragContext* context GdkWindow* drag_window gint x_root gint y_root GdkWindow** [dest_window] GdkDragProtocol* [protocol]") ;;; (CFNC-gtk2 "gboolean gdk_drag_motion GdkDragContext* context GdkWindow* dest_window GdkDragProtocol protocol gint x_root gint y_root GdkDragAction suggested_action GdkDragAction possible_actions guint32 time") (CFNC "void gdk_drag_drop GdkDragContext* context guint32 time") (CFNC "void gdk_drag_abort GdkDragContext* context guint32 time") ;;; (CCAST-gtk2 "GDK_DRAWABLE(object)" "GdkDrawable*") ;;; (CCHK-gtk2 "GDK_IS_DRAWABLE(object)" "GdkDrawable*") (CFNC-3.0 "cairo_t* gdk_cairo_create GdkWindow* window") ;-- moved up ;;; (CFNC-gtk2 "cairo_t* gdk_cairo_create GdkDrawable* drawable") ;-- moved up ;;;;(CFNC "GType gdk_drawable_get_type void") ;;; (CFNC-gtk2 "void gdk_drawable_get_size GdkDrawable* drawable gint* [width] gint* [height]") ;;; (CFNC-gtk2 "void gdk_drawable_set_colormap GdkDrawable* drawable GdkColormap* colormap") ;;; (CFNC-gtk2 "GdkColormap* gdk_drawable_get_colormap GdkDrawable* drawable") ;;; (CFNC-gtk2 "GdkVisual* gdk_drawable_get_visual GdkDrawable* drawable") ;;; (CFNC-gtk2 "gint gdk_drawable_get_depth GdkDrawable* drawable") ;;; 2.90.6 (CFNC "void gdk_draw_point GdkDrawable* drawable GdkGC* gc gint x gint y") ;;; 2.90.6 (CFNC "void gdk_draw_line GdkDrawable* drawable GdkGC* gc gint x1 gint y1 gint x2 gint y2") ;;; 2.90.6 (CFNC "void gdk_draw_rectangle GdkDrawable* drawable GdkGC* gc gboolean filled gint x gint y gint width gint height") ;;; 2.90.6 (CFNC "void gdk_draw_arc GdkDrawable* drawable GdkGC* gc gboolean filled gint x gint y gint width gint height gint angle1 gint angle2") ;;; 2.90.6 (CFNC "void gdk_draw_polygon GdkDrawable* drawable GdkGC* gc gboolean filled GdkPoint* points gint npoints") ;;; the "filled" arg is declared gint in gdkdrawable.h, but treated as a boolean in x11/gdkdrawable.c ;;; 2.90.6 (CFNC "void gdk_draw_drawable GdkDrawable* drawable GdkGC* gc GdkDrawable* src gint xsrc gint ysrc gint xdest gint ydest gint width gint height") ;;; 2.90.6 (CFNC "void gdk_draw_image GdkDrawable* drawable GdkGC* gc GdkImage* image gint xsrc gint ysrc gint xdest gint ydest gint width gint height") ;;; 2.90.6 (CFNC "void gdk_draw_points GdkDrawable* drawable GdkGC* gc GdkPoint* points gint npoints") ;;; 2.90.6 (CFNC "void gdk_draw_segments GdkDrawable* drawable GdkGC* gc GdkSegment* segs gint nsegs") ;;; 2.90.6 (CFNC "void gdk_draw_lines GdkDrawable* drawable GdkGC* gc GdkPoint* points gint npoints") ;;; 2.90.6 (CFNC "void gdk_draw_glyphs GdkDrawable* drawable GdkGC* gc PangoFont* font gint x gint y PangoGlyphString* glyphs") ;;; 2.90.6 (CFNC "void gdk_draw_layout_line GdkDrawable* drawable GdkGC* gc gint x gint y PangoLayoutLine* line") ;;; 2.90.6 (CFNC "void gdk_draw_layout GdkDrawable* drawable GdkGC* gc gint x gint y PangoLayout* layout") ;;; 2.90.6 (CFNC "void gdk_draw_layout_line_with_colors GdkDrawable* drawable GdkGC* gc gint x gint y PangoLayoutLine* line GdkColor* @foreground GdkColor* @background") ;;; 2.90.6 (CFNC "void gdk_draw_layout_with_colors GdkDrawable* drawable GdkGC* gc gint x gint y PangoLayout* layout GdkColor* @foreground GdkColor* @background") ;;; 2.90.6 (CFNC "GdkImage* gdk_drawable_get_image GdkDrawable* drawable gint x gint y gint width gint height") ;;; out 2.90.5 ;;; (CFNC "GdkRegion* gdk_drawable_get_clip_region GdkDrawable* drawable") ;;; (CFNC "GdkRegion* gdk_drawable_get_visible_region GdkDrawable* drawable") ;;; 2.90.6 (CFNC "GdkImage* gdk_drawable_copy_to_image GdkDrawable* drawable GdkImage* image gint src_x gint src_y gint dest_x gint dest_y gint width gint height") ;;;; are these actually needed? ;;;;;;;; (CFNC "GType gdk_cursor_type_get_type void") ;;;;;;;; (CFNC "GType gdk_drag_action_get_type void") ;;;;;;;; (CFNC "GType gdk_drag_protocol_get_type void") ;;;;;;;; (CFNC "GType gdk_filter_return_get_type void") ;;;;;;;; (CFNC "GType gdk_event_type_get_type void") ;;;;;;;; (CFNC "GType gdk_event_mask_get_type void") ;;;;;;;; (CFNC "GType gdk_visibility_state_get_type void") ;;;;;;;; (CFNC "GType gdk_scroll_direction_get_type void") ;;;;;;;; (CFNC "GType gdk_notify_type_get_type void") ;;;;;;;; (CFNC "GType gdk_crossing_mode_get_type void") ;;;;;;;; (CFNC "GType gdk_property_state_get_type void") ;;;;;;;; (CFNC "GType gdk_window_state_get_type void") ;;;;;;;; (CFNC "GType gdk_setting_action_get_type void") ;;;;;;;; (CFNC "GType gdk_font_type_get_type void") ;;;;;;;; (CFNC "GType gdk_cap_style_get_type void") ;;;;;;;; (CFNC "GType gdk_fill_get_type void") ;;;;;;;; (CFNC "GType gdk_function_get_type void") ;;;;;;;; (CFNC "GType gdk_join_style_get_type void") ;;;;;;;; (CFNC "GType gdk_line_style_get_type void") ;;;;;;;; (CFNC "GType gdk_subwindow_mode_get_type void") ;;;;;;;; (CFNC "GType gdk_gc_values_mask_get_type void") ;;;;;;;; (CFNC "GType gdk_image_type_get_type void") ;;;;;;;; (CFNC "GType gdk_extension_mode_get_type void") ;;;;;;;; (CFNC "GType gdk_input_source_get_type void") ;;;;;;;; (CFNC "GType gdk_input_mode_get_type void") ;;;;;;;; (CFNC "GType gdk_axis_use_get_type void") ;;;;;;;; (CFNC "GType gdk_prop_mode_get_type void") ;;;;;;;; (CFNC "GType gdk_fill_rule_get_type void") ;;;;;;;; (CFNC "GType gdk_overlap_type_get_type void") ;;;;;;;; (CFNC "GType gdk_rgb_dither_get_type void") ;;;;;;;; (CFNC "GType gdk_byte_order_get_type void") ;;;;;;;; (CFNC "GType gdk_modifier_type_get_type void") ;;;;;;;; (CFNC "GType gdk_input_condition_get_type void") ;;;;;;;; (CFNC "GType gdk_status_get_type void") ;;;;;;;; (CFNC "GType gdk_grab_status_get_type void") ;;;;;;;; (CFNC "GType gdk_visual_type_get_type void") ;;;;;;;; (CFNC "GType gdk_window_class_get_type void") ;;;;;;;; (CFNC "GType gdk_window_type_get_type void") ;;;;;;;; (CFNC "GType gdk_window_attributes_type_get_type void") ;;;;;;;; (CFNC "GType gdk_window_hints_get_type void") ;;;;;;;; (CFNC "GType gdk_window_type_hint_get_type void") ;;;;;;;; (CFNC "GType gdk_wm_decoration_get_type void") ;;;;;;;; (CFNC "GType gdk_wm_function_get_type void") ;;;;;;;; (CFNC "GType gdk_gravity_get_type void") ;;;;;;;; (CFNC "GType gdk_window_edge_get_type void") (CINT "GDK_PRIORITY_EVENTS") (CINT "GDK_PRIORITY_REDRAW") (CINT "GDK_NOTHING" "GdkEventType") (CINT "GDK_DELETE" "GdkEventType") (CINT "GDK_DESTROY" "GdkEventType") (CINT "GDK_EXPOSE" "GdkEventType") (CINT "GDK_MOTION_NOTIFY" "GdkEventType") (CINT "GDK_BUTTON_PRESS" "GdkEventType") (CINT "GDK_2BUTTON_PRESS" "GdkEventType") (CINT "GDK_3BUTTON_PRESS" "GdkEventType") (CINT "GDK_BUTTON_RELEASE" "GdkEventType") (CINT "GDK_KEY_PRESS" "GdkEventType") (CINT "GDK_KEY_RELEASE" "GdkEventType") (CINT "GDK_ENTER_NOTIFY" "GdkEventType") (CINT "GDK_LEAVE_NOTIFY" "GdkEventType") (CINT "GDK_FOCUS_CHANGE" "GdkEventType") (CINT "GDK_CONFIGURE" "GdkEventType") (CINT "GDK_MAP" "GdkEventType") (CINT "GDK_UNMAP" "GdkEventType") (CINT "GDK_PROPERTY_NOTIFY" "GdkEventType") (CINT "GDK_SELECTION_CLEAR" "GdkEventType") (CINT "GDK_SELECTION_REQUEST" "GdkEventType") (CINT "GDK_SELECTION_NOTIFY" "GdkEventType") (CINT "GDK_PROXIMITY_IN" "GdkEventType") (CINT "GDK_PROXIMITY_OUT" "GdkEventType") (CINT "GDK_DRAG_ENTER" "GdkEventType") (CINT "GDK_DRAG_LEAVE" "GdkEventType") (CINT "GDK_DRAG_MOTION" "GdkEventType") (CINT "GDK_DRAG_STATUS" "GdkEventType") (CINT "GDK_DROP_START" "GdkEventType") (CINT "GDK_DROP_FINISHED" "GdkEventType") (CINT "GDK_CLIENT_EVENT" "GdkEventType") (CINT "GDK_VISIBILITY_NOTIFY" "GdkEventType") ;;; (CINT-gtk2 "GDK_NO_EXPOSE" "GdkEventType") (CINT "GDK_SCROLL" "GdkEventType") (CINT "GDK_WINDOW_STATE" "GdkEventType") (CINT "GDK_SETTING" "GdkEventType") (CINT "GDK_OWNER_CHANGE" "GdkEventType") (CINT "GDK_GRAB_BROKEN" "GdkEventType") ;;; these may be out 2.90.1 (CINT "GDK_EXPOSURE_MASK" "GdkEventMask") (CINT "GDK_POINTER_MOTION_MASK" "GdkEventMask") ;;; 3.12 (CINT "GDK_POINTER_MOTION_HINT_MASK" "GdkEventMask") (CINT "GDK_BUTTON_MOTION_MASK" "GdkEventMask") (CINT "GDK_BUTTON1_MOTION_MASK" "GdkEventMask") (CINT "GDK_BUTTON2_MOTION_MASK" "GdkEventMask") (CINT "GDK_BUTTON3_MOTION_MASK" "GdkEventMask") (CINT "GDK_BUTTON_PRESS_MASK" "GdkEventMask") (CINT "GDK_BUTTON_RELEASE_MASK" "GdkEventMask") (CINT "GDK_KEY_PRESS_MASK" "GdkEventMask") (CINT "GDK_KEY_RELEASE_MASK" "GdkEventMask") (CINT "GDK_ENTER_NOTIFY_MASK" "GdkEventMask") (CINT "GDK_LEAVE_NOTIFY_MASK" "GdkEventMask") (CINT "GDK_FOCUS_CHANGE_MASK" "GdkEventMask") (CINT "GDK_STRUCTURE_MASK" "GdkEventMask") (CINT "GDK_PROPERTY_CHANGE_MASK" "GdkEventMask") (CINT "GDK_VISIBILITY_NOTIFY_MASK" "GdkEventMask") (CINT "GDK_PROXIMITY_IN_MASK" "GdkEventMask") (CINT "GDK_PROXIMITY_OUT_MASK" "GdkEventMask") (CINT "GDK_SUBSTRUCTURE_MASK" "GdkEventMask") (CINT "GDK_SCROLL_MASK" "GdkEventMask") (CINT "GDK_ALL_EVENTS_MASK" "GdkEventMask") ;;; 3.11.8 (CINT "GDK_VISIBILITY_UNOBSCURED " "GdkVisibilityState") ;;; 3.11.8 (CINT "GDK_VISIBILITY_PARTIAL " "GdkVisibilityState") ;;; 3.11.8 (CINT "GDK_VISIBILITY_FULLY_OBSCURED" "GdkVisibilityState") (CINT "GDK_SCROLL_UP" "GdkScrollDirection") (CINT "GDK_SCROLL_DOWN" "GdkScrollDirection") (CINT "GDK_SCROLL_LEFT" "GdkScrollDirection") (CINT "GDK_SCROLL_RIGHT" "GdkScrollDirection") (CINT "GDK_NOTIFY_ANCESTOR" "GdkNotifyType") (CINT "GDK_NOTIFY_VIRTUAL" "GdkNotifyType") (CINT "GDK_NOTIFY_INFERIOR" "GdkNotifyType") (CINT "GDK_NOTIFY_NONLINEAR" "GdkNotifyType") (CINT "GDK_NOTIFY_NONLINEAR_VIRTUAL" "GdkNotifyType") (CINT "GDK_NOTIFY_UNKNOWN" "GdkNotifyType") (CINT "GDK_CROSSING_NORMAL" "GdkCrossingMode") (CINT "GDK_CROSSING_GRAB" "GdkNotifyType") (CINT "GDK_CROSSING_UNGRAB" "GdkNotifyType") (CINT "GDK_PROPERTY_NEW_VALUE" "GdkPropertyState") (CINT "GDK_PROPERTY_DELETE" "GdkPropertyState") (CINT "GDK_WINDOW_STATE_WITHDRAWN" "GdkWindowState") (CINT "GDK_WINDOW_STATE_ICONIFIED" "GdkWindowState") (CINT "GDK_WINDOW_STATE_MAXIMIZED" "GdkWindowState") (CINT "GDK_WINDOW_STATE_STICKY" "GdkWindowState") (CINT "GDK_SETTING_ACTION_NEW" "GdkSettingAction") (CINT "GDK_SETTING_ACTION_CHANGED" "GdkSettingAction") (CINT "GDK_SETTING_ACTION_DELETED" "GdkSettingAction") ;;;;(CFNC "GType gdk_event_get_type void") (CFNC "gboolean gdk_events_pending void") (CFNC "GdkEvent* gdk_event_get void") (CFNC "GdkEvent* gdk_event_peek void") ;;; (CFNC "GdkEvent* gdk_event_get_graphics_expose GdkWindow* window") ;;; out 2.18.0 (CFNC "void gdk_event_put GdkEvent* event") (CFNC "GdkEvent* gdk_event_copy GdkEvent* event") (CFNC "void gdk_event_free GdkEvent* event") (CFNC "guint32 gdk_event_get_time GdkEvent* @event") (CFNC "gboolean gdk_event_get_state GdkEvent* event GdkModifierType* [state]") (CFNC "gboolean gdk_event_get_coords GdkEvent* event gdouble* [x_win] gdouble* [y_win]") (CFNC "gboolean gdk_event_get_root_coords GdkEvent* event gdouble* [x_root] gdouble* [y_root]") ;;;; (CFNC "gboolean gdk_event_get_axis GdkEvent* event GdkAxisUse axis_use gdouble* [value]") (CFNC "void gdk_event_handler_set GdkEventFunc func lambda_data func_info GtkDestroyNotify notify") (CFNC "void gdk_set_show_events gboolean show_events") (CFNC "gboolean gdk_get_show_events void") ;;; 2.99.3 (CFNC "void gdk_add_client_message_filter GdkAtom message_type GdkFilterFunc func lambda_data #func_info") ;;; 2.91.1 ;(CFNC "gboolean gdk_setting_get gchar* name GValue* value") ;;; 2.90.6 (CINT "GDK_CAP_NOT_LAST" "GdkCapStyle") ;;; 2.90.6 (CINT "GDK_CAP_BUTT" "GdkCapStyle") ;;; 2.90.6 (CINT "GDK_CAP_ROUND" "GdkCapStyle") ;;; 2.90.6 (CINT "GDK_CAP_PROJECTING" "GdkCapStyle") ;;; 2.90.6 (CINT "GDK_SOLID" "GdkFill") ;;; 2.90.6 (CINT "GDK_TILED" "GdkFill") ;;; 2.90.6 (CINT "GDK_STIPPLED" "GdkFill") ;;; 2.90.6 (CINT "GDK_OPAQUE_STIPPLED" "GdkFill") ;;; 2.90.6 (CINT "GDK_COPY" "GdkFunction") ;;; 2.90.6 (CINT "GDK_INVERT" "GdkFunction") ;;; 2.90.6 (CINT "GDK_XOR" "GdkFunction") ;;; 2.90.6 (CINT "GDK_CLEAR" "GdkFunction") ;;; 2.90.6 (CINT "GDK_AND" "GdkFunction") ;;; 2.90.6 (CINT "GDK_AND_REVERSE" "GdkFunction") ;;; 2.90.6 (CINT "GDK_AND_INVERT" "GdkFunction") ;;; 2.90.6 (CINT "GDK_NOOP" "GdkFunction") ;;; 2.90.6 (CINT "GDK_OR" "GdkFunction") ;;; 2.90.6 (CINT "GDK_EQUIV" "GdkFunction") ;;; 2.90.6 (CINT "GDK_OR_REVERSE" "GdkFunction") ;;; 2.90.6 (CINT "GDK_COPY_INVERT" "GdkFunction") ;;; 2.90.6 (CINT "GDK_OR_INVERT" "GdkFunction") ;;; 2.90.6 (CINT "GDK_NAND" "GdkFunction") ;;; 2.90.6 (CINT "GDK_NOR" "GdkFunction") ;;; 2.90.6 (CINT "GDK_SET" "GdkFunction") ;;; 2.90.6 (CINT "GDK_JOIN_MITER" "GdkJoinStyle") ;;; 2.90.6 (CINT "GDK_JOIN_ROUND" "GdkJoinStyle") ;;; 2.90.6 (CINT "GDK_JOIN_BEVEL" "GdkJoinStyle") ;;; 2.90.6 (CINT "GDK_LINE_SOLID" "GdkLineStyle") ;;; 2.90.6 (CINT "GDK_LINE_ON_OFF_DASH" "GdkLineStyle") ;;; 2.90.6 (CINT "GDK_LINE_DOUBLE_DASH" "GdkLineStyle") ;;; 2.90.6 (CINT "GDK_CLIP_BY_CHILDREN" "GdkSubwindowMode") ;;; 2.90.6 (CINT "GDK_INCLUDE_INFERIORS" "GdkSubwindowMode") ;;; 2.90.6 (CINT "GDK_GC_FOREGROUND" "GdkGCValuesMask") ;;; 2.90.6 (CINT "GDK_GC_BACKGROUND" "GdkGCValuesMask") ;;; 2.90.6 ;;; (CINT "GDK_GC_FONT" "GdkGCValuesMask") ;;; 2.90.6 (CINT "GDK_GC_FUNCTION" "GdkGCValuesMask") ;;; 2.90.6 (CINT "GDK_GC_FILL" "GdkGCValuesMask") ;;; 2.90.6 (CINT "GDK_GC_TILE" "GdkGCValuesMask") ;;; 2.90.6 (CINT "GDK_GC_STIPPLE" "GdkGCValuesMask") ;;; 2.90.6 (CINT "GDK_GC_CLIP_MASK" "GdkGCValuesMask") ;;; 2.90.6 (CINT "GDK_GC_SUBWINDOW" "GdkGCValuesMask") ;;; 2.90.6 (CINT "GDK_GC_TS_X_ORIGIN" "GdkGCValuesMask") ;;; 2.90.6 (CINT "GDK_GC_TS_Y_ORIGIN" "GdkGCValuesMask") ;;; 2.90.6 (CINT "GDK_GC_CLIP_X_ORIGIN" "GdkGCValuesMask") ;;; 2.90.6 (CINT "GDK_GC_CLIP_Y_ORIGIN" "GdkGCValuesMask") ;;; 2.90.6 (CINT "GDK_GC_EXPOSURES" "GdkGCValuesMask") ;;; 2.90.6 (CINT "GDK_GC_LINE_WIDTH" "GdkGCValuesMask") ;;; 2.90.6 (CINT "GDK_GC_LINE_STYLE" "GdkGCValuesMask") ;;; 2.90.6 (CINT "GDK_GC_CAP_STYLE" "GdkGCValuesMask") ;;; 2.90.6 (CINT "GDK_GC_JOIN_STYLE" "GdkGCValuesMask") ;;; 2.90.6 (CCAST "GDK_GC(object)" "GdkGC*") ;;; 2.90.6 (CCHK "GDK_IS_GC(object)" "GdkGC*") ;;;;(CFNC "GType gdk_gc_get_type void") ;;; 2.90.6 (CFNC "GdkGC* gdk_gc_new GdkDrawable* drawable") ;;; 2.90.6 (CFNC "GdkGC* gdk_gc_new_with_values GdkDrawable* drawable GdkGCValues* values GdkGCValuesMask values_mask") ;;; 2.90.6 (CFNC "void gdk_gc_get_values GdkGC* gc GdkGCValues* values") ;;; 2.90.6 (CFNC "void gdk_gc_set_values GdkGC* gc GdkGCValues* values GdkGCValuesMask values_mask") ;;; 2.90.6 (CFNC "void gdk_gc_set_foreground GdkGC* gc GdkColor* color") ;;; 2.90.6 (CFNC "void gdk_gc_set_background GdkGC* gc GdkColor* color") ;;; 2.90.6 (CFNC "void gdk_gc_set_function GdkGC* gc GdkFunction function") ;;; 2.90.6 (CFNC "void gdk_gc_set_fill GdkGC* gc GdkFill fill") ;;; 2.90.6 (CFNC "void gdk_gc_set_tile GdkGC* gc GdkPixmap* tile") ;;; 2.90.6 (CFNC "void gdk_gc_set_stipple GdkGC* gc GdkPixmap* stipple") ;;; 2.90.6 (CFNC "void gdk_gc_set_ts_origin GdkGC* gc gint x gint y") ;;; 2.90.6 (CFNC "void gdk_gc_set_clip_origin GdkGC* gc gint x gint y") ;;; 2.90.6 (CFNC "void gdk_gc_set_clip_mask GdkGC* gc GdkBitmap* mask") ;;; 2.90.6 (CFNC "void gdk_gc_set_clip_rectangle GdkGC* gc GdkRectangle* rectangle") ;;; 2.90.6 ;;; 2.90.5 (CFNC "void gdk_gc_set_clip_region GdkGC* gc GdkRegion* region") ;;; 2.90.6 (CFNC "void gdk_gc_set_subwindow GdkGC* gc GdkSubwindowMode mode") ;;; 2.90.6 (CFNC "void gdk_gc_set_exposures GdkGC* gc gboolean exposures") ;;; 2.90.6 (CFNC "void gdk_gc_set_line_attributes GdkGC* gc gint line_width GdkLineStyle line_style GdkCapStyle cap_style GdkJoinStyle join_style") ;;; 2.90.6 ;;;(CFNC "void gdk_gc_set_dashes GdkGC* gc gint dash_offset gint8* dash_list gint n") ;;; gint8* is a problem (23-Feb-09) ;;; 2.90.6 (CFNC "void gdk_gc_offset GdkGC* gc gint x_offset gint y_offset") ;;; 2.90.6 (CFNC "void gdk_gc_copy GdkGC* dst_gc GdkGC* src_gc") ;;; 2.90.6 (CFNC "void gdk_gc_set_colormap GdkGC* gc GdkColormap* colormap") ;;; 2.90.6 (CFNC "GdkColormap* gdk_gc_get_colormap GdkGC* gc") ;;; 2.90.6 (CFNC "void gdk_gc_set_rgb_fg_color GdkGC* gc GdkColor* color") ;;; 2.90.6 (CFNC "void gdk_gc_set_rgb_bg_color GdkGC* gc GdkColor* color") (CFNC "void gdk_init gint* {argc} gchar*** |argv|") (CFNC "gboolean gdk_init_check gint* {argc} gchar*** |argv|") ;;; (CFNC-gtk2 "gchar* gdk_set_locale void") (CFNC "char* gdk_get_program_class void") (CFNC "void gdk_set_program_class char* program_class") (CFNC "void gdk_error_trap_push void") (CFNC "gint gdk_error_trap_pop void") ;;; 3.9.0 (CFNC "gchar* gdk_get_display void" 'free) (CFNC "gchar* gdk_get_display_arg_name void") (CFNC "void gdk_notify_startup_complete void") ;;; 2.99.0 (CFNC "GdkGrabStatus gdk_pointer_grab GdkWindow* window gboolean owner_events GdkEventMask event_mask GdkWindow* confine_to GdkCursor* cursor guint32 time") ;;; 2.99.0 (CFNC "void gdk_pointer_ungrab guint32 time") ;;; 2.99.0 (CFNC "GdkGrabStatus gdk_keyboard_grab GdkWindow* window gboolean owner_events guint32 time") ;;; 2.99.0 (CFNC "void gdk_keyboard_ungrab guint32 time") ;;; 2.99.0 (CFNC "gboolean gdk_pointer_is_grabbed void") (CFNC "gint gdk_screen_width void") (CFNC "gint gdk_screen_height void") (CFNC "gint gdk_screen_width_mm void") (CFNC "gint gdk_screen_height_mm void") (CFNC "void gdk_flush void") (CFNC "void gdk_beep void") (CFNC "void gdk_set_double_click_time guint msec") (CFNC "gboolean gdk_rectangle_intersect GdkRectangle* src1 GdkRectangle* src2 GdkRectangle* dest") (CFNC "void gdk_rectangle_union GdkRectangle* src1 GdkRectangle* src2 GdkRectangle* dest") ;;;;(CFNC "GType gdk_rectangle_get_type void") ;;; out 2.3 (CFNC "gchar* gdk_wcstombs GdkWChar* src") ;;; out 2.3 (CFNC "gint gdk_mbstowcs GdkWChar* dest gchar* src gint dest_max") ;;; 2.99.3 (CFNC "void gdk_event_send_clientmessage_toall GdkEvent* event") ;;; 2.99.3 (CFNC "gboolean gdk_event_send_client_message GdkEvent* event guint32 xid") ;;; 3.5.10 (CFNC "void gdk_threads_enter void") ;;; 3.5.10 (CFNC "void gdk_threads_leave void") ;;; 3.5.10 (CFNC "void gdk_threads_init void") ;;; 2.90.6 (CINT "GDK_IMAGE_NORMAL" "GdkImageType") ;;; 2.90.6 (CINT "GDK_IMAGE_SHARED" "GdkImageType") ;;; 2.90.6 (CINT "GDK_IMAGE_FASTEST" "GdkImageType") ;;; 2.90.6 (CCAST "GDK_IMAGE(object)" "GdkImage*") ;;; 2.90.6 (CCHK "GDK_IS_IMAGE(object)" "GdkImage*") ;;;;(CFNC "GType gdk_image_get_type void") ;;; 2.90.6 (CFNC "GdkImage* gdk_image_new GdkImageType type GdkVisual* visual gint width gint height") (CCAST "GDK_DEVICE(object)" "GdkDevice*") (CCHK "GDK_IS_DEVICE(object)" "GdkDevice*") ;;;; (CINT "GDK_EXTENSION_EVENTS_NONE" "GdkExtensionMode") ;;;; (CINT "GDK_EXTENSION_EVENTS_ALL" "GdkExtensionMode") ;;;; (CINT "GDK_EXTENSION_EVENTS_CURSOR" "GdkExtensionMode") ;;;; (CINT "GDK_SOURCE_MOUSE" "GdkInputSource") ;;;; (CINT "GDK_SOURCE_PEN" "GdkInputSource") ;;;; (CINT "GDK_SOURCE_ERASER" "GdkInputSource") ;;;; (CINT "GDK_SOURCE_CURSOR" "GdkInputSource") ;;;; (CINT "GDK_MODE_DISABLED" "GdkInputMode") ;;;; (CINT "GDK_MODE_SCREEN" "GdkInputMode") ;;;; (CINT "GDK_MODE_WINDOW" "GdkInputMode") ;;;; (CINT "GDK_AXIS_IGNORE" "GdkAxisUse") ;;;; (CINT "GDK_AXIS_X" "GdkAxisUse") ;;;; (CINT "GDK_AXIS_Y" "GdkAxisUse") ;;;; (CINT "GDK_AXIS_PRESSURE" "GdkAxisUse") ;;;; (CINT "GDK_AXIS_XTILT" "GdkAxisUse") ;;;; (CINT "GDK_AXIS_YTILT" "GdkAxisUse") ;;;; (CINT "GDK_AXIS_WHEEL" "GdkAxisUse") ;;;; (CINT "GDK_AXIS_LAST" "GdkAxisUse") ;;; (CINT "GDK_EVEN_ODD_RULE" "GdkFillRule") ;;; (CINT "GDK_WINDING_RULE" "GdkFillRule") ;;;; (CINT "GDK_OVERLAP_RECTANGLE_IN" "GdkOverlapType") ;;;; (CINT "GDK_OVERLAP_RECTANGLE_OUT" "GdkOverlapType") ;;;; (CINT "GDK_OVERLAP_RECTANGLE_PART" "GdkOverlapType") ;;;; (CINT "GDK_MAX_TIMECOORD_AXES") ;;;;;;;; (CFNC "GType gdk_device_get_type void") ;;;; (CFNC "GList* gdk_devices_list void") ;;;; (CFNC "void gdk_device_set_source GdkDevice* device GdkInputSource source") ;;;; (CFNC "gboolean gdk_device_set_mode GdkDevice* device GdkInputMode mode") ;;;; (CFNC "void gdk_device_set_key GdkDevice* device guint index guint keyval GdkModifierType modifiers") ;;;; (CFNC "void gdk_device_set_axis_use GdkDevice* device guint index GdkAxisUse use") ;;;; (CFNC "void gdk_device_get_state GdkDevice* device GdkWindow* window gdouble* axes GdkModifierType* [mask]") ;;;; (CFNC "gboolean gdk_device_get_history GdkDevice* device GdkWindow* window guint32 start guint32 stop GdkTimeCoord*** [events] gint* [n_events]") ;;;; (CFNC "void gdk_device_free_history GdkTimeCoord** events gint n_events") ;;;; (CFNC "gboolean gdk_device_get_axis GdkDevice* device gdouble* axes GdkAxisUse use gdouble* value") ;;;; (CFNC "void gdk_input_set_extension_events GdkWindow* window gint mask GdkExtensionMode mode") ;;;; (CFNC "GdkDevice* gdk_device_get_core_pointer void") (CCAST "GDK_KEYMAP(object)" "GdkKeymap*") (CCHK "GDK_IS_KEYMAP(object)" "GdkKeymap*") ;;;;(CFNC "GType gdk_keymap_get_type void") (CFNC "GdkKeymap* gdk_keymap_get_default void") (CFNC "guint gdk_keymap_lookup_key GdkKeymap* keymap GdkKeymapKey* key") ;(CFNC "gboolean gdk_keymap_translate_keyboard_state GdkKeymap* keymap guint hardware_keycode GdkModifierType state gint group guint* [keyval] gint* [effective_group] gint* [level] GdkModifierType* [unused_modifiers]") (CFNC "gboolean gdk_keymap_get_entries_for_keyval GdkKeymap* keymap guint keyval GdkKeymapKey** [keys] gint* [n_keys]") (CFNC "gboolean gdk_keymap_get_entries_for_keycode GdkKeymap* keymap guint hardware_keycode GdkKeymapKey** [keys] guint** [keyvals] gint* [n_entries]") (CFNC "PangoDirection gdk_keymap_get_direction GdkKeymap* keymap") (CFNC "gchar* gdk_keyval_name guint keyval") (CFNC "guint gdk_keyval_from_name gchar* keyval_name") (CFNC "void gdk_keyval_convert_case guint symbol guint* [lower] guint* [upper]") (CFNC "guint gdk_keyval_to_upper guint keyval") (CFNC "guint gdk_keyval_to_lower guint keyval") (CFNC "gboolean gdk_keyval_is_upper guint keyval") (CFNC "gboolean gdk_keyval_is_lower guint keyval") (CFNC "guint32 gdk_keyval_to_unicode guint keyval") (CFNC "guint gdk_unicode_to_keyval guint32 wc") ;;; these all changed 2.90.7 (CINT-3.0 "GDK_KEY_VoidSymbol") (CINT-3.0 "GDK_KEY_BackSpace") (CINT-3.0 "GDK_KEY_Tab") (CINT-3.0 "GDK_KEY_Linefeed") (CINT-3.0 "GDK_KEY_Clear") (CINT-3.0 "GDK_KEY_Return") (CINT-3.0 "GDK_KEY_Pause") (CINT-3.0 "GDK_KEY_Scroll_Lock") (CINT-3.0 "GDK_KEY_Sys_Req") (CINT-3.0 "GDK_KEY_Escape") (CINT-3.0 "GDK_KEY_Delete") (CINT-3.0 "GDK_KEY_Home") (CINT-3.0 "GDK_KEY_Left") (CINT-3.0 "GDK_KEY_Up") (CINT-3.0 "GDK_KEY_Right") (CINT-3.0 "GDK_KEY_Down") (CINT-3.0 "GDK_KEY_Prior") (CINT-3.0 "GDK_KEY_Page_Up") (CINT-3.0 "GDK_KEY_Next") (CINT-3.0 "GDK_KEY_Page_Down") (CINT-3.0 "GDK_KEY_End") (CINT-3.0 "GDK_KEY_Begin") (CINT-3.0 "GDK_KEY_Select") (CINT-3.0 "GDK_KEY_Print") (CINT-3.0 "GDK_KEY_Execute") (CINT-3.0 "GDK_KEY_Insert") (CINT-3.0 "GDK_KEY_Undo") (CINT-3.0 "GDK_KEY_Redo") (CINT-3.0 "GDK_KEY_Menu") (CINT-3.0 "GDK_KEY_Find") (CINT-3.0 "GDK_KEY_Cancel") (CINT-3.0 "GDK_KEY_Help") (CINT-3.0 "GDK_KEY_Break") (CINT-3.0 "GDK_KEY_Mode_switch") (CINT-3.0 "GDK_KEY_script_switch") (CINT-3.0 "GDK_KEY_Num_Lock") (CINT-3.0 "GDK_KEY_KP_Space") (CINT-3.0 "GDK_KEY_KP_Tab") (CINT-3.0 "GDK_KEY_KP_Enter") (CINT-3.0 "GDK_KEY_KP_F1") (CINT-3.0 "GDK_KEY_KP_F2") (CINT-3.0 "GDK_KEY_KP_F3") (CINT-3.0 "GDK_KEY_KP_F4") (CINT-3.0 "GDK_KEY_KP_Home") (CINT-3.0 "GDK_KEY_KP_Left") (CINT-3.0 "GDK_KEY_KP_Up") (CINT-3.0 "GDK_KEY_KP_Right") (CINT-3.0 "GDK_KEY_KP_Down") (CINT-3.0 "GDK_KEY_KP_Prior") (CINT-3.0 "GDK_KEY_KP_Page_Up") (CINT-3.0 "GDK_KEY_KP_Next") (CINT-3.0 "GDK_KEY_KP_Page_Down") (CINT-3.0 "GDK_KEY_KP_End") (CINT-3.0 "GDK_KEY_KP_Begin") (CINT-3.0 "GDK_KEY_KP_Insert") (CINT-3.0 "GDK_KEY_KP_Delete") (CINT-3.0 "GDK_KEY_KP_Equal") (CINT-3.0 "GDK_KEY_KP_Multiply") (CINT-3.0 "GDK_KEY_KP_Add") (CINT-3.0 "GDK_KEY_KP_Separator") (CINT-3.0 "GDK_KEY_KP_Subtract") (CINT-3.0 "GDK_KEY_KP_Decimal") (CINT-3.0 "GDK_KEY_KP_Divide") (CINT-3.0 "GDK_KEY_KP_0") (CINT-3.0 "GDK_KEY_KP_1") (CINT-3.0 "GDK_KEY_KP_2") (CINT-3.0 "GDK_KEY_KP_3") (CINT-3.0 "GDK_KEY_KP_4") (CINT-3.0 "GDK_KEY_KP_5") (CINT-3.0 "GDK_KEY_KP_6") (CINT-3.0 "GDK_KEY_KP_7") (CINT-3.0 "GDK_KEY_KP_8") (CINT-3.0 "GDK_KEY_KP_9") (CINT-3.0 "GDK_KEY_F1") (CINT-3.0 "GDK_KEY_F2") (CINT-3.0 "GDK_KEY_F3") (CINT-3.0 "GDK_KEY_F4") (CINT-3.0 "GDK_KEY_F5") (CINT-3.0 "GDK_KEY_F6") (CINT-3.0 "GDK_KEY_F7") (CINT-3.0 "GDK_KEY_F8") (CINT-3.0 "GDK_KEY_F9") (CINT-3.0 "GDK_KEY_F10") (CINT-3.0 "GDK_KEY_F11") (CINT-3.0 "GDK_KEY_L1") (CINT-3.0 "GDK_KEY_F12") (CINT-3.0 "GDK_KEY_L2") (CINT-3.0 "GDK_KEY_F13") (CINT-3.0 "GDK_KEY_L3") (CINT-3.0 "GDK_KEY_F14") (CINT-3.0 "GDK_KEY_L4") (CINT-3.0 "GDK_KEY_F15") (CINT-3.0 "GDK_KEY_L5") (CINT-3.0 "GDK_KEY_F16") (CINT-3.0 "GDK_KEY_L6") (CINT-3.0 "GDK_KEY_F17") (CINT-3.0 "GDK_KEY_L7") (CINT-3.0 "GDK_KEY_F18") (CINT-3.0 "GDK_KEY_L8") (CINT-3.0 "GDK_KEY_F19") (CINT-3.0 "GDK_KEY_L9") (CINT-3.0 "GDK_KEY_F20") (CINT-3.0 "GDK_KEY_L10") (CINT-3.0 "GDK_KEY_F21") (CINT-3.0 "GDK_KEY_R1") (CINT-3.0 "GDK_KEY_F22") (CINT-3.0 "GDK_KEY_R2") (CINT-3.0 "GDK_KEY_F23") (CINT-3.0 "GDK_KEY_R3") (CINT-3.0 "GDK_KEY_F24") (CINT-3.0 "GDK_KEY_R4") (CINT-3.0 "GDK_KEY_F25") (CINT-3.0 "GDK_KEY_R5") (CINT-3.0 "GDK_KEY_F26") (CINT-3.0 "GDK_KEY_R6") (CINT-3.0 "GDK_KEY_F27") (CINT-3.0 "GDK_KEY_R7") (CINT-3.0 "GDK_KEY_F28") (CINT-3.0 "GDK_KEY_R8") (CINT-3.0 "GDK_KEY_F29") (CINT-3.0 "GDK_KEY_R9") (CINT-3.0 "GDK_KEY_F30") (CINT-3.0 "GDK_KEY_R10") (CINT-3.0 "GDK_KEY_F31") (CINT-3.0 "GDK_KEY_R11") (CINT-3.0 "GDK_KEY_F32") (CINT-3.0 "GDK_KEY_R12") (CINT-3.0 "GDK_KEY_F33") (CINT-3.0 "GDK_KEY_R13") (CINT-3.0 "GDK_KEY_F34") (CINT-3.0 "GDK_KEY_R14") (CINT-3.0 "GDK_KEY_F35") (CINT-3.0 "GDK_KEY_R15") (CINT-3.0 "GDK_KEY_Shift_L") (CINT-3.0 "GDK_KEY_Shift_R") (CINT-3.0 "GDK_KEY_Control_L") (CINT-3.0 "GDK_KEY_Control_R") (CINT-3.0 "GDK_KEY_Caps_Lock") (CINT-3.0 "GDK_KEY_Shift_Lock") (CINT-3.0 "GDK_KEY_Meta_L") (CINT-3.0 "GDK_KEY_Meta_R") (CINT-3.0 "GDK_KEY_Alt_L") (CINT-3.0 "GDK_KEY_Alt_R") (CINT-3.0 "GDK_KEY_space") (CINT-3.0 "GDK_KEY_exclam") (CINT-3.0 "GDK_KEY_quotedbl") (CINT-3.0 "GDK_KEY_numbersign") (CINT-3.0 "GDK_KEY_dollar") (CINT-3.0 "GDK_KEY_percent") (CINT-3.0 "GDK_KEY_ampersand") (CINT-3.0 "GDK_KEY_apostrophe") (CINT-3.0 "GDK_KEY_quoteright") (CINT-3.0 "GDK_KEY_parenleft") (CINT-3.0 "GDK_KEY_parenright") (CINT-3.0 "GDK_KEY_asterisk") (CINT-3.0 "GDK_KEY_plus") (CINT-3.0 "GDK_KEY_comma") (CINT-3.0 "GDK_KEY_minus") (CINT-3.0 "GDK_KEY_period") (CINT-3.0 "GDK_KEY_slash") (CINT-3.0 "GDK_KEY_0") (CINT-3.0 "GDK_KEY_1") (CINT-3.0 "GDK_KEY_2") (CINT-3.0 "GDK_KEY_3") (CINT-3.0 "GDK_KEY_4") (CINT-3.0 "GDK_KEY_5") (CINT-3.0 "GDK_KEY_6") (CINT-3.0 "GDK_KEY_7") (CINT-3.0 "GDK_KEY_8") (CINT-3.0 "GDK_KEY_9") (CINT-3.0 "GDK_KEY_colon") (CINT-3.0 "GDK_KEY_semicolon") (CINT-3.0 "GDK_KEY_less") (CINT-3.0 "GDK_KEY_equal") (CINT-3.0 "GDK_KEY_greater") (CINT-3.0 "GDK_KEY_question") (CINT-3.0 "GDK_KEY_at") (CINT-3.0 "GDK_KEY_A") (CINT-3.0 "GDK_KEY_B") (CINT-3.0 "GDK_KEY_C") (CINT-3.0 "GDK_KEY_D") (CINT-3.0 "GDK_KEY_E") (CINT-3.0 "GDK_KEY_F") (CINT-3.0 "GDK_KEY_G") (CINT-3.0 "GDK_KEY_H") (CINT-3.0 "GDK_KEY_I") (CINT-3.0 "GDK_KEY_J") (CINT-3.0 "GDK_KEY_K") (CINT-3.0 "GDK_KEY_L") (CINT-3.0 "GDK_KEY_M") (CINT-3.0 "GDK_KEY_N") (CINT-3.0 "GDK_KEY_O") (CINT-3.0 "GDK_KEY_P") (CINT-3.0 "GDK_KEY_Q") (CINT-3.0 "GDK_KEY_R") (CINT-3.0 "GDK_KEY_S") (CINT-3.0 "GDK_KEY_T") (CINT-3.0 "GDK_KEY_U") (CINT-3.0 "GDK_KEY_V") (CINT-3.0 "GDK_KEY_W") (CINT-3.0 "GDK_KEY_X") (CINT-3.0 "GDK_KEY_Y") (CINT-3.0 "GDK_KEY_Z") (CINT-3.0 "GDK_KEY_bracketleft") (CINT-3.0 "GDK_KEY_backslash") (CINT-3.0 "GDK_KEY_bracketright") (CINT-3.0 "GDK_KEY_asciicircum") (CINT-3.0 "GDK_KEY_underscore") (CINT-3.0 "GDK_KEY_grave") (CINT-3.0 "GDK_KEY_quoteleft") (CINT-3.0 "GDK_KEY_a") (CINT-3.0 "GDK_KEY_b") (CINT-3.0 "GDK_KEY_c") (CINT-3.0 "GDK_KEY_d") (CINT-3.0 "GDK_KEY_e") (CINT-3.0 "GDK_KEY_f") (CINT-3.0 "GDK_KEY_g") (CINT-3.0 "GDK_KEY_h") (CINT-3.0 "GDK_KEY_i") (CINT-3.0 "GDK_KEY_j") (CINT-3.0 "GDK_KEY_k") (CINT-3.0 "GDK_KEY_l") (CINT-3.0 "GDK_KEY_m") (CINT-3.0 "GDK_KEY_n") (CINT-3.0 "GDK_KEY_o") (CINT-3.0 "GDK_KEY_p") (CINT-3.0 "GDK_KEY_q") (CINT-3.0 "GDK_KEY_r") (CINT-3.0 "GDK_KEY_s") (CINT-3.0 "GDK_KEY_t") (CINT-3.0 "GDK_KEY_u") (CINT-3.0 "GDK_KEY_v") (CINT-3.0 "GDK_KEY_w") (CINT-3.0 "GDK_KEY_x") (CINT-3.0 "GDK_KEY_y") (CINT-3.0 "GDK_KEY_z") (CINT-3.0 "GDK_KEY_braceleft") (CINT-3.0 "GDK_KEY_bar") (CINT-3.0 "GDK_KEY_braceright") (CINT-3.0 "GDK_KEY_asciitilde") ;; gtk2 versions ;;; (CINT-gtk2 "GDK_VoidSymbol") ;;; (CINT-gtk2 "GDK_BackSpace") ;;; (CINT-gtk2 "GDK_Tab") ;;; (CINT-gtk2 "GDK_Linefeed") ;;; (CINT-gtk2 "GDK_Clear") ;;; (CINT-gtk2 "GDK_Return") ;;; (CINT-gtk2 "GDK_Pause") ;;; (CINT-gtk2 "GDK_Scroll_Lock") ;;; (CINT-gtk2 "GDK_Sys_Req") ;;; (CINT-gtk2 "GDK_Escape") ;;; (CINT-gtk2 "GDK_Delete") ;;; (CINT-gtk2 "GDK_Home") ;;; (CINT-gtk2 "GDK_Left") ;;; (CINT-gtk2 "GDK_Up") ;;; (CINT-gtk2 "GDK_Right") ;;; (CINT-gtk2 "GDK_Down") ;;; (CINT-gtk2 "GDK_Prior") ;;; (CINT-gtk2 "GDK_Page_Up") ;;; (CINT-gtk2 "GDK_Next") ;;; (CINT-gtk2 "GDK_Page_Down") ;;; (CINT-gtk2 "GDK_End") ;;; (CINT-gtk2 "GDK_Begin") ;;; (CINT-gtk2 "GDK_Select") ;;; (CINT-gtk2 "GDK_Print") ;;; (CINT-gtk2 "GDK_Execute") ;;; (CINT-gtk2 "GDK_Insert") ;;; (CINT-gtk2 "GDK_Undo") ;;; (CINT-gtk2 "GDK_Redo") ;;; (CINT-gtk2 "GDK_Menu") ;;; (CINT-gtk2 "GDK_Find") ;;; (CINT-gtk2 "GDK_Cancel") ;;; (CINT-gtk2 "GDK_Help") ;;; (CINT-gtk2 "GDK_Break") ;;; (CINT-gtk2 "GDK_Mode_switch") ;;; (CINT-gtk2 "GDK_script_switch") ;;; (CINT-gtk2 "GDK_Num_Lock") ;;; (CINT-gtk2 "GDK_KP_Space") ;;; (CINT-gtk2 "GDK_KP_Tab") ;;; (CINT-gtk2 "GDK_KP_Enter") ;;; (CINT-gtk2 "GDK_KP_F1") ;;; (CINT-gtk2 "GDK_KP_F2") ;;; (CINT-gtk2 "GDK_KP_F3") ;;; (CINT-gtk2 "GDK_KP_F4") ;;; (CINT-gtk2 "GDK_KP_Home") ;;; (CINT-gtk2 "GDK_KP_Left") ;;; (CINT-gtk2 "GDK_KP_Up") ;;; (CINT-gtk2 "GDK_KP_Right") ;;; (CINT-gtk2 "GDK_KP_Down") ;;; (CINT-gtk2 "GDK_KP_Prior") ;;; (CINT-gtk2 "GDK_KP_Page_Up") ;;; (CINT-gtk2 "GDK_KP_Next") ;;; (CINT-gtk2 "GDK_KP_Page_Down") ;;; (CINT-gtk2 "GDK_KP_End") ;;; (CINT-gtk2 "GDK_KP_Begin") ;;; (CINT-gtk2 "GDK_KP_Insert") ;;; (CINT-gtk2 "GDK_KP_Delete") ;;; (CINT-gtk2 "GDK_KP_Equal") ;;; (CINT-gtk2 "GDK_KP_Multiply") ;;; (CINT-gtk2 "GDK_KP_Add") ;;; (CINT-gtk2 "GDK_KP_Separator") ;;; (CINT-gtk2 "GDK_KP_Subtract") ;;; (CINT-gtk2 "GDK_KP_Decimal") ;;; (CINT-gtk2 "GDK_KP_Divide") ;;; (CINT-gtk2 "GDK_KP_0") ;;; (CINT-gtk2 "GDK_KP_1") ;;; (CINT-gtk2 "GDK_KP_2") ;;; (CINT-gtk2 "GDK_KP_3") ;;; (CINT-gtk2 "GDK_KP_4") ;;; (CINT-gtk2 "GDK_KP_5") ;;; (CINT-gtk2 "GDK_KP_6") ;;; (CINT-gtk2 "GDK_KP_7") ;;; (CINT-gtk2 "GDK_KP_8") ;;; (CINT-gtk2 "GDK_KP_9") ;;; (CINT-gtk2 "GDK_F1") ;;; (CINT-gtk2 "GDK_F2") ;;; (CINT-gtk2 "GDK_F3") ;;; (CINT-gtk2 "GDK_F4") ;;; (CINT-gtk2 "GDK_F5") ;;; (CINT-gtk2 "GDK_F6") ;;; (CINT-gtk2 "GDK_F7") ;;; (CINT-gtk2 "GDK_F8") ;;; (CINT-gtk2 "GDK_F9") ;;; (CINT-gtk2 "GDK_F10") ;;; (CINT-gtk2 "GDK_F11") ;;; (CINT-gtk2 "GDK_L1") ;;; (CINT-gtk2 "GDK_F12") ;;; (CINT-gtk2 "GDK_L2") ;;; (CINT-gtk2 "GDK_F13") ;;; (CINT-gtk2 "GDK_L3") ;;; (CINT-gtk2 "GDK_F14") ;;; (CINT-gtk2 "GDK_L4") ;;; (CINT-gtk2 "GDK_F15") ;;; (CINT-gtk2 "GDK_L5") ;;; (CINT-gtk2 "GDK_F16") ;;; (CINT-gtk2 "GDK_L6") ;;; (CINT-gtk2 "GDK_F17") ;;; (CINT-gtk2 "GDK_L7") ;;; (CINT-gtk2 "GDK_F18") ;;; (CINT-gtk2 "GDK_L8") ;;; (CINT-gtk2 "GDK_F19") ;;; (CINT-gtk2 "GDK_L9") ;;; (CINT-gtk2 "GDK_F20") ;;; (CINT-gtk2 "GDK_L10") ;;; (CINT-gtk2 "GDK_F21") ;;; (CINT-gtk2 "GDK_R1") ;;; (CINT-gtk2 "GDK_F22") ;;; (CINT-gtk2 "GDK_R2") ;;; (CINT-gtk2 "GDK_F23") ;;; (CINT-gtk2 "GDK_R3") ;;; (CINT-gtk2 "GDK_F24") ;;; (CINT-gtk2 "GDK_R4") ;;; (CINT-gtk2 "GDK_F25") ;;; (CINT-gtk2 "GDK_R5") ;;; (CINT-gtk2 "GDK_F26") ;;; (CINT-gtk2 "GDK_R6") ;;; (CINT-gtk2 "GDK_F27") ;;; (CINT-gtk2 "GDK_R7") ;;; (CINT-gtk2 "GDK_F28") ;;; (CINT-gtk2 "GDK_R8") ;;; (CINT-gtk2 "GDK_F29") ;;; (CINT-gtk2 "GDK_R9") ;;; (CINT-gtk2 "GDK_F30") ;;; (CINT-gtk2 "GDK_R10") ;;; (CINT-gtk2 "GDK_F31") ;;; (CINT-gtk2 "GDK_R11") ;;; (CINT-gtk2 "GDK_F32") ;;; (CINT-gtk2 "GDK_R12") ;;; (CINT-gtk2 "GDK_F33") ;;; (CINT-gtk2 "GDK_R13") ;;; (CINT-gtk2 "GDK_F34") ;;; (CINT-gtk2 "GDK_R14") ;;; (CINT-gtk2 "GDK_F35") ;;; (CINT-gtk2 "GDK_R15") ;;; (CINT-gtk2 "GDK_Shift_L") ;;; (CINT-gtk2 "GDK_Shift_R") ;;; (CINT-gtk2 "GDK_Control_L") ;;; (CINT-gtk2 "GDK_Control_R") ;;; (CINT-gtk2 "GDK_Caps_Lock") ;;; (CINT-gtk2 "GDK_Shift_Lock") ;;; (CINT-gtk2 "GDK_Meta_L") ;;; (CINT-gtk2 "GDK_Meta_R") ;;; (CINT-gtk2 "GDK_Alt_L") ;;; (CINT-gtk2 "GDK_Alt_R") ;;; (CINT-gtk2 "GDK_space") ;;; (CINT-gtk2 "GDK_exclam") ;;; (CINT-gtk2 "GDK_quotedbl") ;;; (CINT-gtk2 "GDK_numbersign") ;;; (CINT-gtk2 "GDK_dollar") ;;; (CINT-gtk2 "GDK_percent") ;;; (CINT-gtk2 "GDK_ampersand") ;;; (CINT-gtk2 "GDK_apostrophe") ;;; (CINT-gtk2 "GDK_quoteright") ;;; (CINT-gtk2 "GDK_parenleft") ;;; (CINT-gtk2 "GDK_parenright") ;;; (CINT-gtk2 "GDK_asterisk") ;;; (CINT-gtk2 "GDK_plus") ;;; (CINT-gtk2 "GDK_comma") ;;; (CINT-gtk2 "GDK_minus") ;;; (CINT-gtk2 "GDK_period") ;;; (CINT-gtk2 "GDK_slash") ;;; (CINT-gtk2 "GDK_0") ;;; (CINT-gtk2 "GDK_1") ;;; (CINT-gtk2 "GDK_2") ;;; (CINT-gtk2 "GDK_3") ;;; (CINT-gtk2 "GDK_4") ;;; (CINT-gtk2 "GDK_5") ;;; (CINT-gtk2 "GDK_6") ;;; (CINT-gtk2 "GDK_7") ;;; (CINT-gtk2 "GDK_8") ;;; (CINT-gtk2 "GDK_9") ;;; (CINT-gtk2 "GDK_colon") ;;; (CINT-gtk2 "GDK_semicolon") ;;; (CINT-gtk2 "GDK_less") ;;; (CINT-gtk2 "GDK_equal") ;;; (CINT-gtk2 "GDK_greater") ;;; (CINT-gtk2 "GDK_question") ;;; (CINT-gtk2 "GDK_at") ;;; (CINT-gtk2 "GDK_A") ;;; (CINT-gtk2 "GDK_B") ;;; (CINT-gtk2 "GDK_C") ;;; (CINT-gtk2 "GDK_D") ;;; (CINT-gtk2 "GDK_E") ;;; (CINT-gtk2 "GDK_F") ;;; (CINT-gtk2 "GDK_G") ;;; (CINT-gtk2 "GDK_H") ;;; (CINT-gtk2 "GDK_I") ;;; (CINT-gtk2 "GDK_J") ;;; (CINT-gtk2 "GDK_K") ;;; (CINT-gtk2 "GDK_L") ;;; (CINT-gtk2 "GDK_M") ;;; (CINT-gtk2 "GDK_N") ;;; (CINT-gtk2 "GDK_O") ;;; (CINT-gtk2 "GDK_P") ;;; (CINT-gtk2 "GDK_Q") ;;; (CINT-gtk2 "GDK_R") ;;; (CINT-gtk2 "GDK_S") ;;; (CINT-gtk2 "GDK_T") ;;; (CINT-gtk2 "GDK_U") ;;; (CINT-gtk2 "GDK_V") ;;; (CINT-gtk2 "GDK_W") ;;; (CINT-gtk2 "GDK_X") ;;; (CINT-gtk2 "GDK_Y") ;;; (CINT-gtk2 "GDK_Z") ;;; (CINT-gtk2 "GDK_bracketleft") ;;; (CINT-gtk2 "GDK_backslash") ;;; (CINT-gtk2 "GDK_bracketright") ;;; (CINT-gtk2 "GDK_asciicircum") ;;; (CINT-gtk2 "GDK_underscore") ;;; (CINT-gtk2 "GDK_grave") ;;; (CINT-gtk2 "GDK_quoteleft") ;;; (CINT-gtk2 "GDK_a") ;;; (CINT-gtk2 "GDK_b") ;;; (CINT-gtk2 "GDK_c") ;;; (CINT-gtk2 "GDK_d") ;;; (CINT-gtk2 "GDK_e") ;;; (CINT-gtk2 "GDK_f") ;;; (CINT-gtk2 "GDK_g") ;;; (CINT-gtk2 "GDK_h") ;;; (CINT-gtk2 "GDK_i") ;;; (CINT-gtk2 "GDK_j") ;;; (CINT-gtk2 "GDK_k") ;;; (CINT-gtk2 "GDK_l") ;;; (CINT-gtk2 "GDK_m") ;;; (CINT-gtk2 "GDK_n") ;;; (CINT-gtk2 "GDK_o") ;;; (CINT-gtk2 "GDK_p") ;;; (CINT-gtk2 "GDK_q") ;;; (CINT-gtk2 "GDK_r") ;;; (CINT-gtk2 "GDK_s") ;;; (CINT-gtk2 "GDK_t") ;;; (CINT-gtk2 "GDK_u") ;;; (CINT-gtk2 "GDK_v") ;;; (CINT-gtk2 "GDK_w") ;;; (CINT-gtk2 "GDK_x") ;;; (CINT-gtk2 "GDK_y") ;;; (CINT-gtk2 "GDK_z") ;;; (CINT-gtk2 "GDK_braceleft") ;;; (CINT-gtk2 "GDK_bar") ;;; (CINT-gtk2 "GDK_braceright") ;;; (CINT-gtk2 "GDK_asciitilde") (CFNC "PangoContext* gdk_pango_context_get void") ;;; out 2.5.6 (CFNC "void gdk_pango_context_set_colormap PangoContext* context GdkColormap* colormap") ;;; 2.90.5 (CFNC "GdkRegion* gdk_pango_layout_line_get_clip_region PangoLayoutLine* line gint x_origin gint y_origin gint* index_ranges gint n_ranges") ;;; (CFNC "GdkRegion* gdk_pango_layout_get_clip_region PangoLayout* layout gint x_origin gint y_origin gint* index_ranges gint n_ranges") ;;; 2.90.6 (CFNC "PangoAttribute* gdk_pango_attr_stipple_new GdkBitmap* stipple") ;;; 2.90.6 (CFNC "PangoAttribute* gdk_pango_attr_embossed_new gboolean embossed") ;;; (CFNC-gtk2 "void gdk_pixbuf_render_threshold_alpha GdkPixbuf* pixbuf GdkBitmap* bitmap int src_x int src_y int dest_x int dest_y int width int height int alpha_threshold") ;;; 2.90.6 ;;; out 2.3 (CFNC "void gdk_pixbuf_render_to_drawable GdkPixbuf* pixbuf GdkDrawable* drawable GdkGC* gc int src_x int src_y int dest_x int dest_y int width int height GdkRgbDither dither int x_dither int y_dither") ;;; out 2.3 (CFNC "void gdk_pixbuf_render_to_drawable_alpha GdkPixbuf* pixbuf GdkDrawable* drawable int src_x int src_y int dest_x int dest_y int width int height GdkPixbufAlphaMode alpha_mode int alpha_threshold GdkRgbDither dither int x_dither int y_dither") ;;; (CFNC-gtk2 "void gdk_pixbuf_render_pixmap_and_mask_for_colormap GdkPixbuf* pixbuf GdkColormap* colormap GdkPixmap** [pixmap_return] GdkBitmap** [mask_return] int alpha_threshold") ;;; (CFNC-gtk2 "void gdk_pixbuf_render_pixmap_and_mask GdkPixbuf* pixbuf GdkPixmap** [pixmap_return] GdkBitmap** [mask_return] int alpha_threshold") ;;; (CFNC-gtk2 "GdkPixbuf* gdk_pixbuf_get_from_drawable GdkPixbuf* @dest GdkDrawable* src GdkColormap* @cmap int src_x int src_y int dest_x int dest_y int width int height") ;;; 2.90.6 (CFNC "GdkPixbuf* gdk_pixbuf_get_from_image GdkPixbuf* @dest GdkImage* src GdkColormap* @cmap int src_x int src_y int dest_x int dest_y int width int height") ;;; (CCAST-gtk2 "GDK_PIXMAP(object)" "GdkPixmap*") ;;; (CCHK-gtk2 "GDK_IS_PIXMAP(object)" "GdkPixmap*") ;;; 2.91.0 ;(CCAST2 "GDK_PIXMAP_OBJECT(object)") ;;;;(CFNC "GType gdk_pixmap_get_type void") ;; GdkWindow -> GdkDrawable in gtk 2.2 ;;; 2.90.6 (CFNC "GdkPixmap* gdk_pixmap_new GdkDrawable* window gint width gint height gint depth") ;;; 2.90.6 (CFNC "GdkBitmap* gdk_bitmap_create_from_data GdkDrawable* window gchar* data gint width gint height") ;;; 2.90.6 (CFNC "GdkPixmap* gdk_pixmap_create_from_data GdkDrawable* window gchar* data gint width gint height gint depth GdkColor* fg GdkColor* bg") ;;; 2.90.6 (CFNC "GdkPixmap* gdk_pixmap_create_from_xpm GdkDrawable* window GdkBitmap** @mask GdkColor* transparent_color gchar* filename") ;;; 2.90.6 (CFNC "GdkPixmap* gdk_pixmap_colormap_create_from_xpm GdkDrawable* window GdkColormap* @colormap GdkBitmap** @mask GdkColor* transparent_color gchar* filename") ;;; 2.90.6 (CFNC "GdkPixmap* gdk_pixmap_create_from_xpm_d GdkDrawable* window GdkBitmap** @mask GdkColor* transparent_color gchar** data") ;;; 2.90.6 (CFNC "GdkPixmap* gdk_pixmap_colormap_create_from_xpm_d GdkDrawable* window GdkColormap* @colormap GdkBitmap** @mask GdkColor* transparent_color gchar** data") ;;; 2.91.0 (CFNC "GdkPixmap* gdk_pixmap_foreign_new GdkNativeWindow anid") ;;; 2.91.0 (CFNC "GdkPixmap* gdk_pixmap_lookup GdkNativeWindow anid") (CINT "GDK_PROP_MODE_REPLACE" "GdkPropMode") (CINT "GDK_PROP_MODE_PREPEND" "GdkPropMode") (CINT "GDK_PROP_MODE_APPEND" "GdkPropMode") (CFNC "GdkAtom gdk_atom_intern gchar* atom_name gboolean only_if_exists") (CFNC "gchar* gdk_atom_name GdkAtom atom" 'free) (CFNC "gboolean gdk_property_get GdkWindow* window GdkAtom property GdkAtom type gulong offset gulong length gint pdelete GdkAtom* [actual_property_type] gint* [actual_format] gint* [actual_length] guchar** [data]") (CFNC "void gdk_property_change GdkWindow* window GdkAtom property GdkAtom type gint format GdkPropMode mode guchar* data gint nelements") (CFNC "void gdk_property_delete GdkWindow* window GdkAtom property") ;;; ;(CFNC-gtk2 "gint gdk_text_property_to_text_list GdkAtom encoding gint format guchar* text gint length gchar*** list") ;;; ;(CFNC-gtk2 "gint gdk_text_property_to_utf8_list GdkAtom encoding gint format guchar* text gint length gchar*** list") (CFNC "gchar* gdk_utf8_to_string_target gchar* str" 'free) ;;; ;(CFNC-gtk2 "gboolean gdk_utf8_to_compound_text gchar* str GdkAtom* encoding gint* format guchar** [ctext] gint* [length]") ;;; ;(CFNC-gtk2 "void gdk_free_text_list gchar** list") ;;; ;(CFNC-gtk2 "gint gdk_string_to_compound_text gchar* str GdkAtom* encoding gint* format guchar** [ctext] gint* [length]") ;;; ;(CFNC-gtk2 "void gdk_free_compound_text guchar* ctext") ;;; 2.90.5 ;;; (CFNC "GdkRegion* gdk_region_new void") ;;; (CFNC "GdkRegion* gdk_region_polygon GdkPoint* points gint npoints GdkFillRule fill_rule") ;;; (CFNC "GdkRegion* gdk_region_copy GdkRegion* region") ;;; (CFNC "GdkRegion* gdk_region_rectangle GdkRectangle* rectangle") ;;; (CFNC "void gdk_region_destroy GdkRegion* region") ;;; (CFNC "void gdk_region_get_clipbox GdkRegion* region GdkRectangle* rectangle") ;;; (CFNC "void gdk_region_get_rectangles GdkRegion* region GdkRectangle** [rectangles] gint* [n_rectangles]") ; FREE: returned rect arr ;;; (CFNC "gboolean gdk_region_empty GdkRegion* region") ;;; (CFNC "gboolean gdk_region_equal GdkRegion* region1 GdkRegion* region2") ;;; (CFNC "gboolean gdk_region_point_in GdkRegion* region int x int y") ;;;; (CFNC "GdkOverlapType gdk_region_rect_in GdkRegion* region GdkRectangle* rect") ;;; (CFNC "void gdk_region_offset GdkRegion* region gint dx gint dy") ;;; (CFNC "void gdk_region_shrink GdkRegion* region gint dx gint dy") ;;; (CFNC "void gdk_region_union_with_rect GdkRegion* region GdkRectangle* rect") ;;; (CFNC "void gdk_region_intersect GdkRegion* source1 GdkRegion* source2") ;;; (CFNC "void gdk_region_union GdkRegion* source1 GdkRegion* source2") ;;; (CFNC "void gdk_region_subtract GdkRegion* source1 GdkRegion* source2") ;;; (CFNC "void gdk_region_xor GdkRegion* source1 GdkRegion* source2") ;;; ;(CFNC "void gdk_region_spans_intersect_foreach GdkRegion* region GdkSpan* spans int n_spans gboolean sorted GdkSpanFunc func lambda_data #func_info") ;;; (CFNC-gtk2 "void gdk_rgb_find_color GdkColormap* colormap GdkColor* color") ;;; 2.90.6 (CINT "GDK_RGB_DITHER_NONE" "GdkRgbDither") ;;; 2.90.6 (CINT "GDK_RGB_DITHER_NORMAL" "GdkRgbDither") ;;; 2.90.6 (CINT "GDK_RGB_DITHER_MAX" "GdkRgbDither") ;;; 2.90.6 (CFNC "void gdk_draw_rgb_image GdkDrawable* drawable GdkGC* gc gint x gint y gint width gint height GdkRgbDither dith guchar* rgb_buf gint rowstride") ;;; 2.90.6 (CFNC "void gdk_draw_rgb_image_dithalign GdkDrawable* drawable GdkGC* gc gint x gint y gint width gint height GdkRgbDither dith guchar* rgb_buf gint rowstride gint xdith gint ydith") ;;; 2.90.6 (CFNC "void gdk_draw_rgb_32_image GdkDrawable* drawable GdkGC* gc gint x gint y gint width gint height GdkRgbDither dith guchar* buf gint rowstride") ;;; 2.90.6 (CFNC "void gdk_draw_rgb_32_image_dithalign GdkDrawable* drawable GdkGC* gc gint x gint y gint width gint height GdkRgbDither dith guchar* buf gint rowstride gint xdith gint ydith") ;;; 2.90.6 (CFNC "void gdk_draw_gray_image GdkDrawable* drawable GdkGC* gc gint x gint y gint width gint height GdkRgbDither dith guchar* buf gint rowstride") ;;; 2.90.6 (CFNC "void gdk_draw_indexed_image GdkDrawable* drawable GdkGC* gc gint x gint y gint width gint height GdkRgbDither dith guchar* buf gint rowstride GdkRgbCmap* cmap") ;;; 2.90.6 (CFNC "GdkRgbCmap* gdk_rgb_cmap_new guint32* colors gint n_colors") ;;; 2.90.6 (CFNC "void gdk_rgb_cmap_free GdkRgbCmap* cmap") ;;; 2.90.6 (CFNC "gboolean gdk_rgb_ditherable void") ;;; 2.90.6 (CFNC "void gdk_rgb_set_verbose gboolean verbose") ;;; 2.90.6 (CFNC "void gdk_rgb_set_install gboolean install") ;;; 2.90.6 (CFNC "void gdk_rgb_set_min_colors gint min_colors") ;;; 2.90.6 (CFNC "GdkColormap* gdk_rgb_get_colormap void") ;;; 2.90.6 (CFNC "GdkVisual* gdk_rgb_get_visual void") ;;; atoms from gdk/gdkselection.h (CATOM "GDK_SELECTION_PRIMARY") (CATOM "GDK_SELECTION_SECONDARY") (CATOM "GDK_SELECTION_CLIPBOARD") (CATOM "GDK_TARGET_BITMAP") ;;; 2.91.0 (CATOM "GDK_TARGET_COLORMAP") (CATOM "GDK_TARGET_DRAWABLE") ;;; 2.91.0 (CATOM "GDK_TARGET_PIXMAP") (CATOM "GDK_TARGET_STRING") (CATOM "GDK_SELECTION_TYPE_ATOM") (CATOM "GDK_SELECTION_TYPE_BITMAP") ;;; 2.91.0 (CATOM "GDK_SELECTION_TYPE_COLORMAP") (CATOM "GDK_SELECTION_TYPE_DRAWABLE") (CATOM "GDK_SELECTION_TYPE_INTEGER") ;;; 2.91.0 (CATOM "GDK_SELECTION_TYPE_PIXMAP") (CATOM "GDK_SELECTION_TYPE_WINDOW") (CATOM "GDK_SELECTION_TYPE_STRING") (CFNC "gboolean gdk_selection_owner_set GdkWindow* owner GdkAtom selection guint32 time gboolean send_event") (CFNC "GdkWindow* gdk_selection_owner_get GdkAtom selection") (CFNC "void gdk_selection_convert GdkWindow* requestor GdkAtom selection GdkAtom target guint32 time") (CFNC "gboolean gdk_selection_property_get GdkWindow* requestor guchar** [data] GdkAtom* [prop_type] gint* [prop_format]") ;;; 2.99.3 (CFNC "void gdk_selection_send_notify guint32 requestor GdkAtom selection GdkAtom target GdkAtom property guint32 time") (CINT "GDK_CURRENT_TIME") (CINT "GDK_PARENT_RELATIVE") ;(CCAST2 "GDK_ATOM_TO_POINTER(atom)") ;(CCAST2 "GDK_POINTER_TO_ATOM(ptr)") (CATOM "GDK_NONE") (CINT "GDK_LSB_FIRST" "GdkByteOrder") (CINT "GDK_MSB_FIRST" "GdkByteOrder") (CINT "GDK_SHIFT_MASK" "GdkModifierType") (CINT "GDK_LOCK_MASK" "GdkModifierType") (CINT "GDK_CONTROL_MASK" "GdkModifierType") (CINT "GDK_MOD1_MASK" "GdkModifierType") (CINT "GDK_MOD2_MASK" "GdkModifierType") (CINT "GDK_MOD3_MASK" "GdkModifierType") (CINT "GDK_MOD4_MASK" "GdkModifierType") (CINT "GDK_MOD5_MASK" "GdkModifierType") (CINT "GDK_BUTTON1_MASK" "GdkModifierType") (CINT "GDK_BUTTON2_MASK" "GdkModifierType") (CINT "GDK_BUTTON3_MASK" "GdkModifierType") (CINT "GDK_BUTTON4_MASK" "GdkModifierType") (CINT "GDK_BUTTON5_MASK" "GdkModifierType") (CINT "GDK_RELEASE_MASK" "GdkModifierType") (CINT "GDK_MODIFIER_MASK" "GdkModifierType") ;;; 2.90.4 ;;; (CINT "GDK_INPUT_READ" "GdkInputCondition") ;;; (CINT "GDK_INPUT_WRITE" "GdkInputCondition") ;;; (CINT "GDK_INPUT_EXCEPTION" "GdkInputCondition") (CINT "GDK_OK" "GdkStatus") (CINT "GDK_ERROR" "GdkStatus") (CINT "GDK_ERROR_PARAM" "GdkStatus") (CINT "GDK_ERROR_FILE" "GdkStatus") (CINT "GDK_ERROR_MEM" "GdkStatus") (CINT "GDK_GRAB_SUCCESS" "GdkGrabStatus") (CINT "GDK_GRAB_ALREADY_GRABBED" "GdkGrabStatus") (CINT "GDK_GRAB_INVALID_TIME" "GdkGrabStatus") (CINT "GDK_GRAB_NOT_VIEWABLE" "GdkGrabStatus") (CINT "GDK_GRAB_FROZEN" "GdkGrabStatus") (CCAST "GDK_VISUAL(object)" "GdkVisual*") (CCHK "GDK_IS_VISUAL(object)" "GdkVisual*") (CINT "GDK_VISUAL_STATIC_GRAY" "GdkVisualType") (CINT "GDK_VISUAL_GRAYSCALE" "GdkVisualType") (CINT "GDK_VISUAL_STATIC_COLOR" "GdkVisualType") (CINT "GDK_VISUAL_PSEUDO_COLOR" "GdkVisualType") (CINT "GDK_VISUAL_TRUE_COLOR" "GdkVisualType") (CINT "GDK_VISUAL_DIRECT_COLOR" "GdkVisualType") ;;;;(CFNC "GType gdk_visual_get_type void") (CFNC "gint gdk_visual_get_best_depth void") (CFNC "GdkVisualType gdk_visual_get_best_type void") ;(CFNC "GdkVisual* gdk_visual_get_system void") -- moved up (CFNC "GdkVisual* gdk_visual_get_best void") (CFNC "GdkVisual* gdk_visual_get_best_with_depth gint depth") (CFNC "GdkVisual* gdk_visual_get_best_with_type GdkVisualType visual_type") (CFNC "GdkVisual* gdk_visual_get_best_with_both gint depth GdkVisualType visual_type") (CFNC "void gdk_query_depths gint** [depths] gint* [count]") (CFNC "void gdk_query_visual_types GdkVisualType** [visual_types] gint* [count]") (CFNC "GList* gdk_list_visuals void") (CINT "GDK_INPUT_OUTPUT" "GdkWindowClass") ; GdkWindowWindowClass in gtk 3 (CINT "GDK_INPUT_ONLY" "GdkWindowClass") (CINT "GDK_WINDOW_ROOT" "GdkWindowType") (CINT "GDK_WINDOW_TOPLEVEL" "GdkWindowType") (CINT "GDK_WINDOW_CHILD" "GdkWindowType") ;;; 2.90.7 (CINT "GDK_WINDOW_DIALOG" "GdkWindowType") (CINT "GDK_WINDOW_TEMP" "GdkWindowType") (CINT "GDK_WINDOW_FOREIGN" "GdkWindowType") (CINT "GDK_WA_TITLE" "GdkWindowAttributesType") (CINT "GDK_WA_X" "GdkWindowAttributesType") (CINT "GDK_WA_Y" "GdkWindowAttributesType") (CINT "GDK_WA_CURSOR" "GdkWindowAttributesType") ;;; 2.91.0 (CINT "GDK_WA_COLORMAP" "GdkWindowAttributesType") (CINT "GDK_WA_VISUAL" "GdkWindowAttributesType") (CINT "GDK_WA_WMCLASS" "GdkWindowAttributesType") (CINT "GDK_WA_NOREDIR" "GdkWindowAttributesType") (CINT "GDK_HINT_POS" "GdkWindowHints") (CINT "GDK_HINT_MIN_SIZE" "GdkWindowHints") (CINT "GDK_HINT_MAX_SIZE" "GdkWindowHints") (CINT "GDK_HINT_BASE_SIZE" "GdkWindowHints") (CINT "GDK_HINT_ASPECT" "GdkWindowHints") (CINT "GDK_HINT_RESIZE_INC" "GdkWindowHints") (CINT "GDK_HINT_WIN_GRAVITY" "GdkWindowHints") (CINT "GDK_HINT_USER_POS" "GdkWindowHints") (CINT "GDK_HINT_USER_SIZE" "GdkWindowHints") (CINT "GDK_WINDOW_TYPE_HINT_NORMAL" "GdkWindowTypeHint") (CINT "GDK_WINDOW_TYPE_HINT_DIALOG" "GdkWindowTypeHint") (CINT "GDK_WINDOW_TYPE_HINT_MENU" "GdkWindowTypeHint") (CINT "GDK_WINDOW_TYPE_HINT_TOOLBAR" "GdkWindowTypeHint") (CINT "GDK_DECOR_ALL" "GdkWMDecoration") (CINT "GDK_DECOR_BORDER" "GdkWMDecoration") (CINT "GDK_DECOR_RESIZEH" "GdkWMDecoration") (CINT "GDK_DECOR_TITLE" "GdkWMDecoration") (CINT "GDK_DECOR_MENU" "GdkWMDecoration") (CINT "GDK_DECOR_MINIMIZE" "GdkWMDecoration") (CINT "GDK_DECOR_MAXIMIZE" "GdkWMDecoration") (CINT "GDK_FUNC_ALL" "GdkWMFunction") (CINT "GDK_FUNC_RESIZE" "GdkWMFunction") (CINT "GDK_FUNC_MOVE" "GdkWMFunction") (CINT "GDK_FUNC_MINIMIZE" "GdkWMFunction") (CINT "GDK_FUNC_MAXIMIZE" "GdkWMFunction") (CINT "GDK_FUNC_CLOSE" "GdkWMFunction") (CINT "GDK_GRAVITY_NORTH_WEST" "GdkGravity") (CINT "GDK_GRAVITY_NORTH" "GdkGravity") (CINT "GDK_GRAVITY_NORTH_EAST" "GdkGravity") (CINT "GDK_GRAVITY_WEST" "GdkGravity") (CINT "GDK_GRAVITY_CENTER" "GdkGravity") (CINT "GDK_GRAVITY_EAST" "GdkGravity") (CINT "GDK_GRAVITY_SOUTH_WEST" "GdkGravity") (CINT "GDK_GRAVITY_SOUTH" "GdkGravity") (CINT "GDK_GRAVITY_SOUTH_EAST" "GdkGravity") (CINT "GDK_GRAVITY_STATIC" "GdkGravity") (CINT "GDK_WINDOW_EDGE_NORTH_WEST" "GdkWindowEdge") (CINT "GDK_WINDOW_EDGE_NORTH" "GdkWindowEdge") (CINT "GDK_WINDOW_EDGE_NORTH_EAST" "GdkWindowEdge") (CINT "GDK_WINDOW_EDGE_WEST" "GdkWindowEdge") (CINT "GDK_WINDOW_EDGE_EAST" "GdkWindowEdge") (CINT "GDK_WINDOW_EDGE_SOUTH_WEST" "GdkWindowEdge") (CINT "GDK_WINDOW_EDGE_SOUTH" "GdkWindowEdge") (CINT "GDK_WINDOW_EDGE_SOUTH_EAST" "GdkWindowEdge") (CCAST "GDK_WINDOW(object)" "GdkWindow*") (CCHK "GDK_IS_WINDOW(object)" "GdkWindow*") ;(CCAST "GDK_WINDOW_OBJECT(object)" "GdkWindowObject*") ;;;;;(CFNC "GType gdk_window_object_get_type void") ;can't find any use for this -- out 2.17.11 (CFNC "GdkWindow* gdk_window_new GdkWindow* parent GdkWindowAttr* attributes gint attributes_mask") (CFNC "void gdk_window_destroy GdkWindow* window") (CFNC "GdkWindowType gdk_window_get_window_type GdkWindow* window") ;;; 3.3.2 (CFNC "GdkWindow* gdk_window_at_pointer gint* [win_x] gint* [win_y]") (CFNC "void gdk_window_show GdkWindow* window") (CFNC "void gdk_window_hide GdkWindow* window") (CFNC "void gdk_window_withdraw GdkWindow* window") (CFNC "void gdk_window_show_unraised GdkWindow* window") (CFNC "void gdk_window_move GdkWindow* window gint x gint y") (CFNC "void gdk_window_resize GdkWindow* window gint width gint height") (CFNC "void gdk_window_move_resize GdkWindow* window gint x gint y gint width gint height") (CFNC "void gdk_window_reparent GdkWindow* window GdkWindow* new_parent gint x gint y") ;;; (CFNC-gtk2 "void gdk_window_clear GdkWindow* window") ;;; (CFNC-gtk2 "void gdk_window_clear_area GdkWindow* window gint x gint y gint width gint height") ;;; (CFNC-gtk2 "void gdk_window_clear_area_e GdkWindow* window gint x gint y gint width gint height") (CFNC "void gdk_window_raise GdkWindow* window") (CFNC "void gdk_window_lower GdkWindow* window") (CFNC "void gdk_window_focus GdkWindow* window guint32 timestamp") (CFNC "void gdk_window_set_user_data GdkWindow* @window gpointer user_data") (CFNC "void gdk_window_set_override_redirect GdkWindow* window gboolean override_redirect") (CFNC "void gdk_window_add_filter GdkWindow* window GdkFilterFunc func lambda_data #func_info") (CFNC "void gdk_window_remove_filter GdkWindow* window GdkFilterFunc func lambda_data #func_info") (CFNC "void gdk_window_scroll GdkWindow* window gint dx gint dy") ;;; (CFNC-gtk2 "void gdk_window_shape_combine_mask GdkWindow* window GdkBitmap* mask gint x gint y") ;;; (CFNC "void gdk_window_shape_combine_region GdkWindow* window GdkRegion* shape_region gint offset_x gint offset_y") (CFNC "void gdk_window_set_child_shapes GdkWindow* window") (CFNC "void gdk_window_merge_child_shapes GdkWindow* window") (CFNC "gboolean gdk_window_is_visible GdkWindow* window") (CFNC "gboolean gdk_window_is_viewable GdkWindow* window") (CFNC "GdkWindowState gdk_window_get_state GdkWindow* window") ;;; 3.15 (CFNC "gboolean gdk_window_set_static_gravities GdkWindow* window gboolean use_static") ;;; (CFNC-gtk2 "GdkWindow* gdk_window_foreign_new GdkNativeWindow anid") ;;; (CFNC-gtk2 "GdkWindow* gdk_window_lookup GdkNativeWindow anid") (CFNC "void gdk_window_get_root_origin GdkWindow* window gint* [x] gint* [y]") (CFNC "void gdk_window_get_frame_extents GdkWindow* window GdkRectangle* rect") ;;; 3.3.2 (CFNC "GdkWindow* gdk_window_get_pointer GdkWindow* window gint* [x] gint* [y] GdkModifierType* [mask]") (CFNC "GdkWindow* gdk_window_get_parent GdkWindow* window") (CFNC "GdkWindow* gdk_window_get_toplevel GdkWindow* window") (CFNC "GList* gdk_window_get_children GdkWindow* window") (CFNC "GList* gdk_window_peek_children GdkWindow* window") (CFNC "GdkEventMask gdk_window_get_events GdkWindow* window") (CFNC "void gdk_window_set_events GdkWindow* window GdkEventMask event_mask") (CFNC "void gdk_window_set_icon_list GdkWindow* window GList* pixbufs") ;;; (CFNC-gtk2 "void gdk_window_set_icon GdkWindow* window GdkWindow* icon_window GdkPixmap* pixmap GdkBitmap* mask") (CFNC "void gdk_window_set_icon_name GdkWindow* window gchar* name") (CFNC "void gdk_window_set_group GdkWindow* window GdkWindow* leader") (CFNC "void gdk_window_set_decorations GdkWindow* window GdkWMDecoration decorations") (CFNC "gboolean gdk_window_get_decorations GdkWindow* window GdkWMDecoration* [decorations]") (CFNC "void gdk_window_set_functions GdkWindow* window GdkWMFunction functions") ;;; out 2.15.0 (CFNC "GList* gdk_window_get_toplevels void") (CFNC "void gdk_window_iconify GdkWindow* window") (CFNC "void gdk_window_deiconify GdkWindow* window") (CFNC "void gdk_window_stick GdkWindow* window") (CFNC "void gdk_window_unstick GdkWindow* window") (CFNC "void gdk_window_maximize GdkWindow* window") (CFNC "void gdk_window_unmaximize GdkWindow* window") (CFNC "void gdk_window_register_dnd GdkWindow* window") (CFNC "void gdk_window_begin_resize_drag GdkWindow* window GdkWindowEdge edge gint button gint root_x gint root_y guint32 timestamp") (CFNC "void gdk_window_begin_move_drag GdkWindow* window gint button gint root_x gint root_y guint32 timestamp") (CFNC "void gdk_window_invalidate_rect GdkWindow* window GdkRectangle* rect gboolean invalidate_children") ;;; (CFNC "void gdk_window_invalidate_region GdkWindow* window GdkRegion* region gboolean invalidate_children") ;;; (CFNC "void gdk_window_invalidate_maybe_recurse GdkWindow* window GdkRegion* region lambda2 func lambda_data #func_info") ;;; (CFNC "GdkRegion* gdk_window_get_update_area GdkWindow* window") (CFNC "void gdk_window_freeze_updates GdkWindow* window") (CFNC "void gdk_window_thaw_updates GdkWindow* window") (CFNC "void gdk_window_process_all_updates void") (CFNC "void gdk_window_process_updates GdkWindow* window gboolean update_children") (CFNC "void gdk_window_set_debug_updates gboolean setting") (CFNC "void gdk_window_constrain_size GdkGeometry* geometry GdkWindowHints flags gint width gint height gint* [new_width] gint* [new_height]") ;;; (CFNC-gtk2 "void gdk_window_get_internal_paint_info GdkWindow* window GdkDrawable** [real_drawable] gint* [x_offset] gint* [y_offset]") (CFNC "void gdk_window_set_type_hint GdkWindow* window GdkWindowTypeHint hint") (CFNC "void gdk_window_set_modal_hint GdkWindow* window gboolean modal") (CFNC "void gdk_window_set_geometry_hints GdkWindow* window GdkGeometry* geometry GdkWindowHints geom_mask") ;;; (CFNC-gtk2 "void gdk_set_sm_client_id gchar* sm_client_id") (CFNC "void gdk_window_begin_paint_rect GdkWindow* window GdkRectangle* rectangle") ;;; (CFNC "void gdk_window_begin_paint_region GdkWindow* window GdkRegion* region") (CFNC "void gdk_window_end_paint GdkWindow* window") (CFNC "void gdk_window_set_title GdkWindow* window gchar* title") (CFNC "void gdk_window_set_role GdkWindow* window gchar* role") (CFNC "void gdk_window_set_transient_for GdkWindow* window GdkWindow* parent") ;;; (CFNC-gtk2 "void gdk_window_set_background GdkWindow* window GdkColor* color") ;;; (CFNC-gtk2 "void gdk_window_set_back_pixmap GdkWindow* window GdkPixmap* pixmap gboolean parent_relative") (CFNC "void gdk_window_set_cursor GdkWindow* window GdkCursor* cursor") (CFNC "void gdk_window_get_user_data GdkWindow* window gpointer* [data]") ;;; (CFNC-gtk2 "void gdk_window_get_geometry GdkWindow* window gint* [x] gint* [y] gint* [width] gint* [height] gint* [depth]") (CFNC-3.0 "void gdk_window_get_geometry GdkWindow* window gint* [x] gint* [y] gint* [width] gint* [height]") (CFNC "void gdk_window_get_position GdkWindow* window gint* [x] gint* [y]") (CFNC "gint gdk_window_get_origin GdkWindow* window gint* [x] gint* [y]") ;;; 2.99.0 ;(CFNC "GdkPointerHooks* gdk_set_pointer_hooks GdkPointerHooks* @new_hooks") (CFNC "GdkWindow* gdk_get_default_root_window void") ;;; gdk-pixbuf (CFNC "GQuark gdk_pixbuf_error_quark void") ;;;;(CFNC "GType gdk_pixbuf_get_type void") (CFNC "GdkColorspace gdk_pixbuf_get_colorspace GdkPixbuf* pixbuf") (CFNC "int gdk_pixbuf_get_n_channels GdkPixbuf* pixbuf") (CFNC "gboolean gdk_pixbuf_get_has_alpha GdkPixbuf* pixbuf") (CFNC "int gdk_pixbuf_get_bits_per_sample GdkPixbuf* pixbuf") (CFNC "guchar* gdk_pixbuf_get_pixels GdkPixbuf* pixbuf") (CFNC "int gdk_pixbuf_get_width GdkPixbuf* pixbuf") (CFNC "int gdk_pixbuf_get_height GdkPixbuf* pixbuf") (CFNC "int gdk_pixbuf_get_rowstride GdkPixbuf* pixbuf") (CFNC "GdkPixbuf* gdk_pixbuf_new GdkColorspace colorspace gboolean has_alpha int bits_per_sample int width int height") (CFNC "GdkPixbuf* gdk_pixbuf_copy GdkPixbuf* pixbuf") (CFNC "GdkPixbuf* gdk_pixbuf_new_subpixbuf GdkPixbuf* src_pixbuf int src_x int src_y int width int height") (CFNC "GdkPixbuf* gdk_pixbuf_new_from_file char* filename GError** [error]") (CFNC "GdkPixbuf* gdk_pixbuf_new_from_data guchar* data GdkColorspace colorspace gboolean has_alpha int bits_per_sample int width int height int rowstride GdkPixbufDestroyNotify destroy_fn gpointer destroy_fn_data") (CFNC "GdkPixbuf* gdk_pixbuf_new_from_xpm_data char** data" 'const) ;;; 3.16.0 (CFNC "GdkPixbuf* gdk_pixbuf_new_from_inline gint data_length guint8* data gboolean copy_pixels GError** [error]") (CFNC "void gdk_pixbuf_fill GdkPixbuf* pixbuf guint32 pixel") ;;; (CFNC "gboolean gdk_pixbuf_save GdkPixbuf* pixbuf char* filename char* type GError** [error] ...") (CFNC "gboolean gdk_pixbuf_savev GdkPixbuf* pixbuf char* filename char* type char** option_keys char** option_values GError** [error]") (CFNC "GdkPixbuf* gdk_pixbuf_add_alpha GdkPixbuf* pixbuf gboolean substitute_color guchar r guchar g guchar b") (CFNC "void gdk_pixbuf_copy_area GdkPixbuf* src_pixbuf int src_x int src_y int width int height GdkPixbuf* dest_pixbuf int dest_x int dest_y") (CFNC "void gdk_pixbuf_saturate_and_pixelate GdkPixbuf* src GdkPixbuf* dest gfloat saturation gboolean pixelate") (CFNC "void gdk_pixbuf_scale GdkPixbuf* src GdkPixbuf* dest int dest_x int dest_y int dest_width int dest_height double offset_x double offset_y double scale_x double scale_y GdkInterpType interp_type") (CFNC "void gdk_pixbuf_composite GdkPixbuf* src GdkPixbuf* dest int dest_x int dest_y int dest_width int dest_height double offset_x double offset_y double scale_x double scale_y GdkInterpType interp_type int overall_alpha") (CFNC "void gdk_pixbuf_composite_color GdkPixbuf* src GdkPixbuf* dest int dest_x int dest_y int dest_width int dest_height double offset_x double offset_y double scale_x double scale_y GdkInterpType interp_type int overall_alpha int check_x int check_y int check_size guint32 color1 guint32 color2") (CFNC "GdkPixbuf* gdk_pixbuf_scale_simple GdkPixbuf* src int dest_width int dest_height GdkInterpType interp_type") (CFNC "GdkPixbuf* gdk_pixbuf_composite_color_simple GdkPixbuf* src int dest_width int dest_height GdkInterpType interp_type int overall_alpha int check_size guint32 color1 guint32 color2") ;;;;(CFNC "GType gdk_pixbuf_animation_get_type void") (CFNC "GdkPixbufAnimation* gdk_pixbuf_animation_new_from_file char* filename GError** [error]") (CFNC "int gdk_pixbuf_animation_get_width GdkPixbufAnimation* animation") (CFNC "int gdk_pixbuf_animation_get_height GdkPixbufAnimation* animation") (CFNC "gboolean gdk_pixbuf_animation_is_static_image GdkPixbufAnimation* animation") (CFNC "GdkPixbuf* gdk_pixbuf_animation_get_static_image GdkPixbufAnimation* animation") (CFNC "GdkPixbufAnimationIter* gdk_pixbuf_animation_get_iter GdkPixbufAnimation* animation GTimeVal* start_time") ;;;;(CFNC "GType gdk_pixbuf_animation_iter_get_type void") (CFNC "int gdk_pixbuf_animation_iter_get_delay_time GdkPixbufAnimationIter* iter") (CFNC "GdkPixbuf* gdk_pixbuf_animation_iter_get_pixbuf GdkPixbufAnimationIter* iter") (CFNC "gboolean gdk_pixbuf_animation_iter_on_currently_loading_frame GdkPixbufAnimationIter* iter") (CFNC "gboolean gdk_pixbuf_animation_iter_advance GdkPixbufAnimationIter* iter GTimeVal* current_time") (CFNC "gchar* gdk_pixbuf_get_option GdkPixbuf* pixbuf gchar* key") ;;; (CFNC "gboolean gdk_pixbuf_set_option GdkPixbuf* pixbuf gchar* key gchar* value") ; surely these loaders are internal? ;;;;(CFNC "GType gdk_pixbuf_loader_get_type void") ;(CFNC "GdkPixbufLoader* gdk_pixbuf_loader_new void") ;(CFNC "GdkPixbufLoader* gdk_pixbuf_loader_new_with_type char* image_type GError** [error]") ;(CFNC "gboolean gdk_pixbuf_loader_write GdkPixbufLoader* loader guchar* buf gsize count GError** [error]") ;(CFNC "GdkPixbuf* gdk_pixbuf_loader_get_pixbuf GdkPixbufLoader* loader") ;(CFNC "GdkPixbufAnimation* gdk_pixbuf_loader_get_animation GdkPixbufLoader* loader") ;(CFNC "gboolean gdk_pixbuf_loader_close GdkPixbufLoader* loader GError** [error]") ;;; 2.91.6 ;(CLNG "GDK_TYPE_PIXBUF_LOADER") ;(CCAST "GDK_PIXBUF_LOADER(obj)" "GdkPixbufLoader*") ;(CCHK "GDK_IS_PIXBUF_LOADER(obj)" "GdkPixbufLoader*") (CINT "GDK_PIXBUF_ALPHA_BILEVEL" "GdkPixbufAlphaMode") (CINT "GDK_PIXBUF_ALPHA_FULL" "GdkPixbufAlphaMode") (CINT "GDK_COLORSPACE_RGB" "GdkColorspace") ;;; 2.91.6 (CLNG "GDK_TYPE_PIXBUF") (CCAST "GDK_PIXBUF(object)" "GdkPixbuf*") (CCHK "GDK_IS_PIXBUF(object)" "GdkPixbuf*") ;;; 2.91.6 (CLNG "GDK_TYPE_PIXBUF_ANIMATION") (CCAST "GDK_PIXBUF_ANIMATION(object)" "GdkPixbufAnimation*") (CCHK "GDK_IS_PIXBUF_ANIMATION(object)" "GdkPixbufAnimation*") ;;; 2.91.6 (CLNG "GDK_TYPE_PIXBUF_ANIMATION_ITER") (CCAST "GDK_PIXBUF_ANIMATION_ITER(object)" "GdkPixbufAnimationIter*") (CCHK "GDK_IS_PIXBUF_ANIMATION_ITER(object)" "GdkPixbufAnimationIter*") ;;; (CLNG "GDK_PIXBUF_ERROR") (CINT "GDK_PIXBUF_ERROR_CORRUPT_IMAGE" "GdkPixbufError") (CINT "GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY" "GdkPixbufError") (CINT "GDK_PIXBUF_ERROR_BAD_OPTION" "GdkPixbufError") (CINT "GDK_PIXBUF_ERROR_UNKNOWN_TYPE" "GdkPixbufError") (CINT "GDK_PIXBUF_ERROR_UNSUPPORTED_OPERATION" "GdkPixbufError") (CINT "GDK_PIXBUF_ERROR_FAILED" "GdkPixbufError") (CINT "GDK_INTERP_NEAREST" "GdkInterpType") (CINT "GDK_INTERP_TILES" "GdkInterpType") (CINT "GDK_INTERP_BILINEAR" "GdkInterpType") (CINT "GDK_INTERP_HYPER" "GdkInterpType") ;;;; (CINT "GDK_PIXBUF_MAJOR") ;;;; (CINT "GDK_PIXBUF_MINOR") ;;;; (CINT "GDK_PIXBUF_MICRO") ;;;; (CSTR "GDK_PIXBUF_VERSION") ;;;;(CFNC "GType gdk_pixbuf_alpha_mode_get_type void") ;;; 2.91.6 (CLNG "GDK_TYPE_PIXBUF_ALPHA_MODE") ;;;;(CFNC "GType gdk_colorspace_get_type void") ;;; 2.91.6 (CLNG "GDK_TYPE_COLORSPACE") ;;;;(CFNC "GType gdk_pixbuf_error_get_type void") ;;; 2.91.6 (CLNG "GDK_TYPE_PIXBUF_ERROR") ;;;;(CFNC "GType gdk_interp_type_get_type void") ;;; 2.91.6 (CLNG "GDK_TYPE_INTERP_TYPE") ;;; 3.1.6 (CCAST "GTK_VBOX(obj)" "GtkVBox*") ;;; 3.1.6 (CCHK "GTK_IS_VBOX(obj)" "GtkVBox*") ;;; 3.1.6 ;;;;(CFNC "GType gtk_vbox_get_type void") ;;; 3.1.6 (CFNC "GtkWidget* gtk_vbox_new gboolean homogeneous gint spacing") (CCAST "GTK_ACCEL_GROUP(object)" "GtkAccelGroup*") (CCHK "GTK_IS_ACCEL_GROUP(object)" "GtkAccelGroup*") (CINT "GTK_ACCEL_VISIBLE" "GtkAccelFlags") (CINT "GTK_ACCEL_LOCKED" "GtkAccelFlags") (CINT "GTK_ACCEL_MASK" "GtkAccelFlags") ;;;;(CFNC "GType gtk_accel_group_get_type void") (CFNC "GtkAccelGroup* gtk_accel_group_new void") (CFNC "void gtk_accel_group_lock GtkAccelGroup* accel_group") (CFNC "void gtk_accel_group_unlock GtkAccelGroup* accel_group") (CFNC "void gtk_accel_group_connect GtkAccelGroup* accel_group guint accel_key GdkModifierType accel_mods GtkAccelFlags accel_flags GClosure* @closure") (CFNC "void gtk_accel_group_connect_by_path GtkAccelGroup* accel_group gchar* accel_path GClosure* @closure") (CFNC "gboolean gtk_accel_group_disconnect GtkAccelGroup* accel_group GClosure* @closure") (CFNC "gboolean gtk_accel_group_disconnect_key GtkAccelGroup* accel_group guint accel_key GdkModifierType accel_mods") (CFNC "gboolean gtk_accel_groups_activate GObject* object guint accel_key GdkModifierType accel_mods") (CFNC "GSList* gtk_accel_groups_from_object GObject* object") (CFNC "GtkAccelKey* gtk_accel_group_find GtkAccelGroup* accel_group lambda3 func lambda_data #func_info") (CFNC "GtkAccelGroup* gtk_accel_group_from_accel_closure GClosure* @closure") (CFNC "gboolean gtk_accelerator_valid guint keyval GdkModifierType modifiers") (CFNC "void gtk_accelerator_parse gchar* accelerator guint* [accelerator_key] GdkModifierType* [accelerator_mods]") (CFNC "gchar* gtk_accelerator_name guint accelerator_key GdkModifierType accelerator_mods" 'free) (CFNC "void gtk_accelerator_set_default_mod_mask GdkModifierType default_mod_mask") ;;; 2.91.1 (CFNC "guint gtk_accelerator_get_default_mod_mask void") (CFNC "GtkAccelGroupEntry* gtk_accel_group_query GtkAccelGroup* accel_group guint accel_key GdkModifierType accel_mods guint* [n_entries]") (CFNC "gboolean gtk_accel_group_activate GtkAccelGroup* accel_group GQuark accel_quark GObject* acceleratable guint accel_key GdkModifierType accel_mods") (CCAST "GTK_ACCEL_LABEL(obj)" "GtkAccelLabel*") (CCHK "GTK_IS_ACCEL_LABEL(obj)" "GtkAccelLabel*") ;;;;(CFNC "GType gtk_accel_label_get_type void") (CFNC "GtkWidget* gtk_accel_label_new gchar* string") (CFNC "GtkWidget* gtk_accel_label_get_accel_widget GtkAccelLabel* accel_label") (CFNC "guint gtk_accel_label_get_accel_width GtkAccelLabel* accel_label") (CFNC "void gtk_accel_label_set_accel_widget GtkAccelLabel* accel_label GtkWidget* accel_widget") (CFNC "void gtk_accel_label_set_accel_closure GtkAccelLabel* accel_label GClosure* @closure") (CFNC "gboolean gtk_accel_label_refetch GtkAccelLabel* accel_label") (CFNC "void gtk_accel_map_add_entry gchar* accel_path guint accel_key GdkModifierType accel_mods") (CFNC "gboolean gtk_accel_map_lookup_entry gchar* accel_path GtkAccelKey* key") (CFNC "gboolean gtk_accel_map_change_entry gchar* accel_path guint accel_key GdkModifierType accel_mods gboolean replace") (CFNC "void gtk_accel_map_load gchar* file_name") (CFNC "void gtk_accel_map_save gchar* file_name") (CFNC "void gtk_accel_map_foreach lambda_data func_info GtkAccelMapForeach func") (CFNC "void gtk_accel_map_load_fd gint fd") ;;; (CFNC "void gtk_accel_map_load_scanner GScanner* scanner") (CFNC "void gtk_accel_map_save_fd gint fd") (CFNC "void gtk_accel_map_add_filter gchar* filter_pattern") (CFNC "void gtk_accel_map_foreach_unfiltered lambda_data func_info GtkAccelMapForeach func") (CCAST "GTK_ACCESSIBLE(obj)" "GtkAccessible*") (CCHK "GTK_IS_ACCESSIBLE(obj)" "GtkAccessible*") ;;;;(CFNC "GType gtk_accessible_get_type void") ;;; 3.3.6 (CFNC "void gtk_accessible_connect_widget_destroyed GtkAccessible* accessible") (CCAST "GTK_ADJUSTMENT(obj)" "GtkAdjustment*") (CCHK "GTK_IS_ADJUSTMENT(obj)" "GtkAdjustment*") ;;;;(CFNC "GType gtk_adjustment_get_type void") ;;; (CFNC-gtk2 "GtkObject* gtk_adjustment_new gdouble value gdouble lower gdouble upper gdouble step_increment gdouble page_increment gdouble page_size") ;;; 3.18.0 (CFNC "void gtk_adjustment_changed GtkAdjustment* adjustment") ;;; 3.18.0 (CFNC "void gtk_adjustment_value_changed GtkAdjustment* adjustment") (CFNC "void gtk_adjustment_clamp_page GtkAdjustment* adjustment gdouble lower gdouble upper") (CFNC "gdouble gtk_adjustment_get_value GtkAdjustment* adjustment") (CFNC "void gtk_adjustment_set_value GtkAdjustment* adjustment gdouble value") ;;; 3.13.2 (CCAST "GTK_ALIGNMENT(obj)" "GtkAlignment*") ;;; 3.13.2 (CCHK "GTK_IS_ALIGNMENT(obj)" "GtkAlignment*") ;;; 3.13.2 ;;;;(CFNC "GType gtk_alignment_get_type void") ;;; 3.13.2 (CFNC "GtkWidget* gtk_alignment_new gfloat xalign gfloat yalign gfloat xscale gfloat yscale") ;;; 3.13.2 (CFNC "void gtk_alignment_set GtkAlignment* alignment gfloat xalign gfloat yalign gfloat xscale gfloat yscale") ;;; 3.13.2 (CCAST "GTK_ARROW(obj)" "GtkArrow*") ;;; 3.13.2 (CCHK "GTK_IS_ARROW(obj)" "GtkArrow*") ;;;;(CFNC "GType gtk_arrow_get_type void") ;;; 3.13.2 (CFNC "GtkWidget* gtk_arrow_new GtkArrowType arrow_type GtkShadowType shadow_type") ;;; 3.13.2 (CFNC "void gtk_arrow_set GtkArrow* arrow GtkArrowType arrow_type GtkShadowType shadow_type") (CCAST "GTK_ASPECT_FRAME(obj)" "GtkAspectFrame*") (CCHK "GTK_IS_ASPECT_FRAME(obj)" "GtkAspectFrame*") ;;;;(CFNC "GType gtk_aspect_frame_get_type void") (CFNC "GtkWidget* gtk_aspect_frame_new gchar* label gfloat xalign gfloat yalign gfloat ratio gboolean obey_child") (CFNC "void gtk_aspect_frame_set GtkAspectFrame* aspect_frame gfloat xalign gfloat yalign gfloat ratio gboolean obey_child") (CCAST "GTK_BUTTON_BOX(obj)" "GtkButtonBox*") (CCHK "GTK_IS_BUTTON_BOX(obj)" "GtkButtonBox*") ;;; 2.90.6 (CINT "GTK_BUTTONBOX_DEFAULT") ;;;;(CFNC "GType gtk_button_box_get_type void") (CFNC "GtkButtonBoxStyle gtk_button_box_get_layout GtkButtonBox* widget") (CFNC "void gtk_button_box_set_layout GtkButtonBox* widget GtkButtonBoxStyle layout_style") (CFNC "void gtk_button_box_set_child_secondary GtkButtonBox* widget GtkWidget* child gboolean is_secondary") (CFNC "GtkBindingSet* gtk_binding_set_new gchar* set_name") (CFNC "GtkBindingSet* gtk_binding_set_by_class gpointer object_class") (CFNC "GtkBindingSet* gtk_binding_set_find gchar* set_name") ;;; (CFNC-gtk2 "gboolean gtk_bindings_activate GtkObject* object guint keyval GdkModifierType modifiers") ;;; (CFNC-gtk2 "gboolean gtk_binding_set_activate GtkBindingSet* binding_set guint keyval GdkModifierType modifiers GtkObject* object") ;;; (CFNC "void gtk_binding_entry_clear GtkBindingSet* binding_set guint keyval GdkModifierType modifiers") ; out 2.11.0 ;;; (CFNC "void gtk_binding_entry_add_signal GtkBindingSet* binding_set guint keyval GdkModifierType modifiers gchar* signal_name guint n_args ...") ;;; 2.99.3 (CFNC "void gtk_binding_set_add_path GtkBindingSet* binding_set GtkPathType path_type gchar* path_pattern GtkPathPriorityType priority") (CFNC "void gtk_binding_entry_remove GtkBindingSet* binding_set guint keyval GdkModifierType modifiers") ;;; (CFNC "void gtk_binding_entry_add_signall GtkBindingSet* binding_set guint keyval GdkModifierType modifiers gchar* signal_name GSList* binding_args") ; out 2.11.0 ;;; (CFNC "guint gtk_binding_parse_binding GScanner* scanner") (CCAST "GTK_BIN(obj)" "GtkBin*") (CCHK "GTK_IS_BIN(obj)" "GtkBin*") ;;;;(CFNC "GType gtk_bin_get_type void") (CFNC "GtkWidget* gtk_bin_get_child GtkBin* bin") (CCAST "GTK_BOX(obj)" "GtkBox*") (CCHK "GTK_IS_BOX(obj)" "GtkBox*") ;;;;(CFNC "GType gtk_box_get_type void") (CFNC "void gtk_box_pack_start GtkBox* box GtkWidget* child gboolean expand gboolean fill guint padding") (CFNC "void gtk_box_pack_end GtkBox* box GtkWidget* child gboolean expand gboolean fill guint padding") ;;; out 2.13.5 (CFNC "void gtk_box_pack_start_defaults GtkBox* box GtkWidget* widget") ;;; out 2.13.5 (CFNC "void gtk_box_pack_end_defaults GtkBox* box GtkWidget* widget") (CFNC "void gtk_box_set_homogeneous GtkBox* box gboolean homogeneous") (CFNC "gboolean gtk_box_get_homogeneous GtkBox* box") (CFNC "void gtk_box_set_spacing GtkBox* box gint spacing") (CFNC "gint gtk_box_get_spacing GtkBox* box") (CFNC "void gtk_box_reorder_child GtkBox* box GtkWidget* child gint position") (CFNC "void gtk_box_query_child_packing GtkBox* box GtkWidget* child gboolean* [expand] gboolean* [fill] guint* [padding] GtkPackType* [pack_type]") (CFNC "void gtk_box_set_child_packing GtkBox* box GtkWidget* child gboolean expand gboolean fill guint padding GtkPackType pack_type") (CCAST "GTK_BUTTON(obj)" "GtkButton*") (CCHK "GTK_IS_BUTTON(obj)" "GtkButton*") ;;;;(CFNC "GType gtk_button_get_type void") (CFNC "GtkWidget* gtk_button_new void") (CFNC "GtkWidget* gtk_button_new_with_label gchar* label") ;;; 3.9.8 (CFNC "GtkWidget* gtk_button_new_from_stock gchar* stock_id") (CFNC "GtkWidget* gtk_button_new_with_mnemonic gchar* label") ;;; out 2.19.0 (CFNC "void gtk_button_pressed GtkButton* button") ;;; (CFNC "void gtk_button_released GtkButton* button") (CFNC "void gtk_button_clicked GtkButton* button") ;;; (CFNC "void gtk_button_enter GtkButton* button") ;;; (CFNC "void gtk_button_leave GtkButton* button") (CFNC "void gtk_button_set_relief GtkButton* button GtkReliefStyle newstyle") (CFNC "GtkReliefStyle gtk_button_get_relief GtkButton* button") (CFNC "void gtk_button_set_label GtkButton* button gchar* label") (CFNC "gchar* gtk_button_get_label GtkButton* button") (CFNC "void gtk_button_set_use_underline GtkButton* button gboolean use_underline") (CFNC "gboolean gtk_button_get_use_underline GtkButton* button") ;;; 3.9.8 (CFNC "void gtk_button_set_use_stock GtkButton* button gboolean use_stock") ;;; 3.9.8 (CFNC "gboolean gtk_button_get_use_stock GtkButton* button") (CCAST "GTK_CALENDAR(obj)" "GtkCalendar*") (CCHK "GTK_IS_CALENDAR(obj)" "GtkCalendar*") (CINT "GTK_CALENDAR_SHOW_HEADING" "GtkCalendarDisplayOptions") (CINT "GTK_CALENDAR_SHOW_DAY_NAMES" "GtkCalendarDisplayOptions") (CINT "GTK_CALENDAR_NO_MONTH_CHANGE" "GtkCalendarDisplayOptions") (CINT "GTK_CALENDAR_SHOW_WEEK_NUMBERS" "GtkCalendarDisplayOptions") ;;; 2.90.7 (CINT "GTK_CALENDAR_WEEK_START_MONDAY" "GtkCalendarDisplayOptions") ;;;;(CFNC "GType gtk_calendar_get_type void") (CFNC "GtkWidget* gtk_calendar_new void") ;(CFNC "gboolean gtk_calendar_select_month GtkCalendar* calendar guint month guint year") (CFNC "void gtk_calendar_select_day GtkCalendar* calendar guint day") ;(CFNC "gboolean gtk_calendar_mark_day GtkCalendar* calendar guint day") ;(CFNC "gboolean gtk_calendar_unmark_day GtkCalendar* calendar guint day") ;;; these now are void funcs (2.90.3) (CFNC "void gtk_calendar_clear_marks GtkCalendar* calendar") ;;; out 2.3 (CFNC "void gtk_calendar_display_options GtkCalendar* calendar GtkCalendarDisplayOptions flags") (CFNC "void gtk_calendar_get_date GtkCalendar* calendar guint* [year] guint* [month] guint* [day]") ;;; out 2.7.0 (CFNC "void gtk_calendar_freeze GtkCalendar* calendar") ;;; out 2.7.0 (CFNC "void gtk_calendar_thaw GtkCalendar* calendar") (CCAST "GTK_CELL_EDITABLE(obj)" "GtkCellEditable*") (CCHK "GTK_IS_CELL_EDITABLE(obj)" "GtkCellEditable*") ;;;;(CFNC "GType gtk_cell_editable_get_type void") (CFNC "void gtk_cell_editable_start_editing GtkCellEditable* cell_editable GdkEvent* @event") (CFNC "void gtk_cell_editable_editing_done GtkCellEditable* cell_editable") (CFNC "void gtk_cell_editable_remove_widget GtkCellEditable* cell_editable") (CINT "GTK_CELL_RENDERER_SELECTED" "GtkCellRendererState") (CINT "GTK_CELL_RENDERER_PRELIT" "GtkCellRendererState") (CINT "GTK_CELL_RENDERER_INSENSITIVE" "GtkCellRendererState") (CINT "GTK_CELL_RENDERER_SORTED" "GtkCellRendererState") (CINT "GTK_CELL_RENDERER_FOCUSED" "GtkCellRendererState") ;(CINT "GTK_CELL_RENDERER_MODE_INERT" "GtkCellRendererMode") ;(CINT "GTK_CELL_RENDERER_MODE_ACTIVATABLE" "GtkCellRendererMode") ;(CINT "GTK_CELL_RENDERER_MODE_EDITABLE" "GtkCellRendererMode") (CCAST "GTK_CELL_RENDERER(obj)" "GtkCellRenderer*") (CCHK "GTK_IS_CELL_RENDERER(obj)" "GtkCellRenderer*") ;;;;(CFNC "GType gtk_cell_renderer_get_type void") (CFNC "gboolean gtk_cell_renderer_activate GtkCellRenderer* cell GdkEvent* event GtkWidget* widget gchar* path GdkRectangle* background_area GdkRectangle* cell_area GtkCellRendererState flags") ;;; (CFNC-gtk2 "void gtk_cell_renderer_get_size GtkCellRenderer* cell GtkWidget* widget GdkRectangle* @cell_area gint* [x_offset] gint* [y_offset] gint* [width] gint* [height]") ;;; (CFNC-gtk2 "void gtk_cell_renderer_render GtkCellRenderer* cell GdkWindow* window GtkWidget* widget GdkRectangle* background_area GdkRectangle* cell_area GdkRectangle* expose_area GtkCellRendererState flags") (CFNC "GtkCellEditable* gtk_cell_renderer_start_editing GtkCellRenderer* cell GdkEvent* @event GtkWidget* widget gchar* path GdkRectangle* background_area GdkRectangle* cell_area GtkCellRendererState flags") (CFNC "void gtk_cell_renderer_set_fixed_size GtkCellRenderer* cell gint width gint height") (CFNC "void gtk_cell_renderer_get_fixed_size GtkCellRenderer* cell gint* [width] gint* [height]") (CCAST "GTK_CELL_RENDERER_PIXBUF(obj)" "GtkCellRendererPixbuf*") (CCHK "GTK_IS_CELL_RENDERER_PIXBUF(obj)" "GtkCellRendererPixbuf*") ;;;;(CFNC "GType gtk_cell_renderer_pixbuf_get_type void") (CFNC "GtkCellRenderer* gtk_cell_renderer_pixbuf_new void") (CCAST "GTK_CELL_RENDERER_TEXT(obj)" "GtkCellRendererText*") (CCHK "GTK_IS_CELL_RENDERER_TEXT(obj)" "GtkCellRendererText*") ;;;;(CFNC "GType gtk_cell_renderer_text_get_type void") (CFNC "GtkCellRenderer* gtk_cell_renderer_text_new void") (CFNC "void gtk_cell_renderer_text_set_fixed_height_from_font GtkCellRendererText* renderer gint number_of_rows") (CCAST "GTK_CELL_RENDERER_TOGGLE(obj)" "GtkCellRendererToggle*") (CCHK "GTK_IS_CELL_RENDERER_TOGGLE(obj)" "GtkCellRendererToggle*") ;;;;(CFNC "GType gtk_cell_renderer_toggle_get_type void") (CFNC "GtkCellRenderer* gtk_cell_renderer_toggle_new void") (CFNC "gboolean gtk_cell_renderer_toggle_get_radio GtkCellRendererToggle* toggle") (CFNC "void gtk_cell_renderer_toggle_set_radio GtkCellRendererToggle* toggle gboolean radio") (CFNC "gboolean gtk_cell_renderer_toggle_get_active GtkCellRendererToggle* toggle") (CFNC "void gtk_cell_renderer_toggle_set_active GtkCellRendererToggle* toggle gboolean setting") (CCAST "GTK_CHECK_BUTTON(obj)" "GtkCheckButton*") (CCHK "GTK_IS_CHECK_BUTTON(obj)" "GtkCheckButton*") ;;;;(CFNC "GType gtk_check_button_get_type void") (CFNC "GtkWidget* gtk_check_button_new void") (CFNC "GtkWidget* gtk_check_button_new_with_label gchar* label") (CFNC "GtkWidget* gtk_check_button_new_with_mnemonic gchar* label") (CCAST "GTK_CHECK_MENU_ITEM(obj)" "GtkCheckMenuItem*") (CCHK "GTK_IS_CHECK_MENU_ITEM(obj)" "GtkCheckMenuItem*") ;;;;(CFNC "GType gtk_check_menu_item_get_type void") (CFNC "GtkWidget* gtk_check_menu_item_new void") (CFNC "GtkWidget* gtk_check_menu_item_new_with_label gchar* label") ; null label => segfault (CFNC "GtkWidget* gtk_check_menu_item_new_with_mnemonic gchar* label") (CFNC "void gtk_check_menu_item_set_active GtkCheckMenuItem* check_menu_item gboolean is_active") (CFNC "gboolean gtk_check_menu_item_get_active GtkCheckMenuItem* check_menu_item") (CFNC "void gtk_check_menu_item_toggled GtkCheckMenuItem* check_menu_item") (CFNC "void gtk_check_menu_item_set_inconsistent GtkCheckMenuItem* check_menu_item gboolean setting") (CFNC "gboolean gtk_check_menu_item_get_inconsistent GtkCheckMenuItem* check_menu_item") (CFNC "GtkClipboard* gtk_clipboard_get GdkAtom selection") ; might be on GDK_MULTIHEAD_SAFE switch? (CFNC "gboolean gtk_clipboard_set_with_data GtkClipboard* clipboard GtkTargetEntry* targets guint n_targets GtkClipboardGetFunc func GtkClipboardClearFunc clear_func lambda_data #func_info") ;(CFNC "gboolean gtk_clipboard_set_with_owner GtkClipboard* clipboard GtkTargetEntry* targets guint n_targets GtkClipboardGetFunc func GtkClipboardClearFunc clear_func GObject* owner") (CFNC "GObject* gtk_clipboard_get_owner GtkClipboard* clipboard") (CFNC "void gtk_clipboard_clear GtkClipboard* clipboard") (CFNC "void gtk_clipboard_set_text GtkClipboard* clipboard gchar* text gint len") (CFNC "void gtk_clipboard_request_contents GtkClipboard* clipboard GdkAtom target GtkClipboardReceivedFunc func lambda_data #func_info") (CFNC "void gtk_clipboard_request_text GtkClipboard* clipboard GtkClipboardTextReceivedFunc func lambda_data #func_info") (CFNC "GtkSelectionData* gtk_clipboard_wait_for_contents GtkClipboard* clipboard GdkAtom target") (CFNC "gchar* gtk_clipboard_wait_for_text GtkClipboard* clipboard" 'free) (CFNC "gboolean gtk_clipboard_wait_is_text_available GtkClipboard* clipboard") ;;; 3.3.16 (CCAST "GTK_COLOR_SELECTION_DIALOG(obj)" "GtkColorSelectionDialog*") ;;; 3.3.16 (CCHK "GTK_IS_COLOR_SELECTION_DIALOG(obj)" "GtkColorSelectionDialog*") ;;; 3.3.16 ;;;;(CFNC "GType gtk_color_selection_dialog_get_type void") ;;; 3.3.16 (CFNC "GtkWidget* gtk_color_selection_dialog_new gchar* title") ;;; 3.3.16 (CCAST "GTK_COLOR_SELECTION(obj)" "GtkColorSelection*") ;;; 3.3.16 (CCHK "GTK_IS_COLOR_SELECTION(obj)" "GtkColorSelection*") ;;; 3.3.16 ;;;;(CFNC "GType gtk_color_selection_get_type void") ;;; 3.3.16 (CFNC "GtkWidget* gtk_color_selection_new void") ;;; 3.3.16 (CFNC "gboolean gtk_color_selection_get_has_opacity_control GtkColorSelection* colorsel") ;;; 3.3.16 (CFNC "void gtk_color_selection_set_has_opacity_control GtkColorSelection* colorsel gboolean has_opacity") ;;; 3.3.16 (CFNC "gboolean gtk_color_selection_get_has_palette GtkColorSelection* colorsel") ;;; 3.3.16 (CFNC "void gtk_color_selection_set_has_palette GtkColorSelection* colorsel gboolean has_palette") ;;; ;;; 3.3.16 (CFNC-gtk2 "void gtk_color_selection_set_current_color GtkColorSelection* colorsel GdkColor* color") ;;; 3.3.16 (CFNC "void gtk_color_selection_set_current_alpha GtkColorSelection* colorsel guint16 alpha") ;;; ;;; 3.3.16 (CFNC-gtk2 "void gtk_color_selection_get_current_color GtkColorSelection* colorsel GdkColor* color") ;;; 3.3.16 (CFNC "guint16 gtk_color_selection_get_current_alpha GtkColorSelection* colorsel") ;;; ;;; 3.3.16 (CFNC-gtk2 "void gtk_color_selection_set_previous_color GtkColorSelection* colorsel GdkColor* color") ;;; 3.3.16 (CFNC "void gtk_color_selection_set_previous_alpha GtkColorSelection* colorsel guint16 alpha") ;;; ;;; 3.3.16 (CFNC-gtk2 "void gtk_color_selection_get_previous_color GtkColorSelection* colorsel GdkColor* color") ;;; 3.3.16 (CFNC "guint16 gtk_color_selection_get_previous_alpha GtkColorSelection* colorsel") ;;; 3.3.16 (CFNC "gboolean gtk_color_selection_is_adjusting GtkColorSelection* colorsel") ;;; ;;; 3.3.16 (CFNC-gtk2 "gboolean gtk_color_selection_palette_from_string gchar* str GdkColor** [colors] gint* [n_colors]") ;;; ;;; 3.3.16 (CFNC-gtk2 "gchar* gtk_color_selection_palette_to_string GdkColor* colors gint n_colors" 'free) ;;; out 2.3 (CFNC "GtkColorSelectionChangePaletteFunc gtk_color_selection_set_change_palette_hook GtkColorSelectionChangePaletteFunc func") ;;; out 2.3 (CCAST "GTK_COMBO(obj)" "GtkCombo*") ;;; out 2.3 (CCHK "GTK_IS_COMBO(obj)" "GtkCombo*") ;;;;;;; out 2.3 (CFNC "GType gtk_combo_get_type void") ;;; out 2.3 (CFNC "GtkWidget* gtk_combo_new void") ;;; out 2.3 (CFNC "void gtk_combo_set_value_in_list GtkCombo* combo gboolean val gboolean ok_if_empty") ;;; out 2.3 (CFNC "void gtk_combo_set_use_arrows GtkCombo* combo gboolean val") ;;; out 2.3 (CFNC "void gtk_combo_set_use_arrows_always GtkCombo* combo gboolean val") ;;; out 2.3 (CFNC "void gtk_combo_set_case_sensitive GtkCombo* combo gboolean val") ;;; out 2.3 (CFNC "void gtk_combo_set_item_string GtkCombo* combo GtkItem* item gchar* item_value") ;;; out 2.3 (CFNC "void gtk_combo_set_popdown_strings GtkCombo* combo GList* strings") ;;; out 2.3 (CFNC "void gtk_combo_disable_activate GtkCombo* combo") (CCAST "GTK_CONTAINER(obj)" "GtkContainer*") (CCHK "GTK_IS_CONTAINER(obj)" "GtkContainer*") ;;; (CFNC "gboolean GTK_IS_RESIZE_CONTAINER GtkWidget* widget") ;;;;(CFNC "GType gtk_container_get_type void") (CFNC "void gtk_container_set_border_width GtkContainer* container guint border_width") (CFNC "guint gtk_container_get_border_width GtkContainer* container") (CFNC "void gtk_container_add GtkContainer* container GtkWidget* widget") (CFNC "void gtk_container_remove GtkContainer* container GtkWidget* widget") ;;; 3.12.0 (CFNC "void gtk_container_set_resize_mode GtkContainer* container GtkResizeMode resize_mode") ;;; 3.12.0 (CFNC "GtkResizeMode gtk_container_get_resize_mode GtkContainer* container") (CFNC "void gtk_container_check_resize GtkContainer* container") (CFNC "void gtk_container_foreach GtkContainer* container GtkCallback func lambda_data #func_info") (CFNC "GList* gtk_container_get_children GtkContainer* container") ; FREE (g_list_free) ;;; out 2.19.0 (CCAST "GTK_CURVE(obj)" "GtkCurve*") ;;; (CCHK "GTK_IS_CURVE(obj)" "GtkCurve*") ;;;;(CFNC "GType gtk_curve_get_type void") ;;; (CFNC "GtkWidget* gtk_curve_new void") ;;; (CFNC "void gtk_curve_reset GtkCurve* curve") ;;; (CFNC "void gtk_curve_set_gamma GtkCurve* curve gfloat gamma") ;;; (CFNC "void gtk_curve_set_range GtkCurve* curve gfloat min_x gfloat max_x gfloat min_y gfloat max_y") ;;; (CFNC "void gtk_curve_get_vector GtkCurve* curve int veclen gfloat* vector") ;;; (CFNC "void gtk_curve_set_vector GtkCurve* curve int veclen gfloat* vector") ;;; (CFNC "void gtk_curve_set_curve_type GtkCurve* curve GtkCurveType type") ;(CINT "GTK_DEBUG_MISC") ;(CINT "GTK_DEBUG_PLUGSOCKET") ;(CINT "GTK_DEBUG_TEXT") ;(CINT "GTK_DEBUG_TREE") ;(CINT "GTK_DEBUG_UPDATES") (CINT "GTK_DIALOG_MODAL" "GtkDialogFlags") (CINT "GTK_DIALOG_DESTROY_WITH_PARENT" "GtkDialogFlags") ;;; 2.90.7 (CINT "GTK_DIALOG_NO_SEPARATOR" "GtkDialogFlags") (CINT "GTK_RESPONSE_NONE" "GtkResponseType") (CINT "GTK_RESPONSE_REJECT" "GtkResponseType") (CINT "GTK_RESPONSE_ACCEPT" "GtkResponseType") (CINT "GTK_RESPONSE_DELETE_EVENT" "GtkResponseType") (CINT "GTK_RESPONSE_OK" "GtkResponseType") (CINT "GTK_RESPONSE_CANCEL" "GtkResponseType") (CINT "GTK_RESPONSE_CLOSE" "GtkResponseType") (CINT "GTK_RESPONSE_YES" "GtkResponseType") (CINT "GTK_RESPONSE_NO" "GtkResponseType") (CINT "GTK_RESPONSE_APPLY" "GtkResponseType") (CINT "GTK_RESPONSE_HELP" "GtkResponseType") (CCAST "GTK_DIALOG(obj)" "GtkDialog*") (CCHK "GTK_IS_DIALOG(obj)" "GtkDialog*") ;;;;(CFNC "GType gtk_dialog_get_type void") (CFNC "GtkWidget* gtk_dialog_new void") ;;; in 3.3.4 this is generating a warning (CFNC-PA "GtkWidget* gtk_dialog_new_with_buttons gchar* title GtkWindow* @parent GtkDialogFlags flags etc #buttons" 0 10 '("gchar*" "int")) ;;; ... at init arg, then list arg name, min len, max len, step, then types within step (CFNC "void gtk_dialog_add_action_widget GtkDialog* dialog GtkWidget* child gint response_id") (CFNC "GtkWidget* gtk_dialog_add_button GtkDialog* dialog gchar* button_text gint response_id") (CFNC-PA "void gtk_dialog_add_buttons GtkDialog* dialog etc buttons" 2 10 '("gchar*" "int")) ; must have at least 1 button (CFNC "void gtk_dialog_set_response_sensitive GtkDialog* dialog gint response_id gboolean setting") (CFNC "void gtk_dialog_set_default_response GtkDialog* dialog gint response_id") ;;; 2.90.7 (CFNC "void gtk_dialog_set_has_separator GtkDialog* dialog gboolean setting") ;;; 2.90.7 (CFNC "gboolean gtk_dialog_get_has_separator GtkDialog* dialog") (CFNC "void gtk_dialog_response GtkDialog* dialog gint response_id") (CFNC "gint gtk_dialog_run GtkDialog* dialog") (CINT "GTK_DEST_DEFAULT_MOTION" "GtkDestDefaults") (CINT "GTK_DEST_DEFAULT_HIGHLIGHT" "GtkDestDefaults") (CINT "GTK_DEST_DEFAULT_DROP" "GtkDestDefaults") (CINT "GTK_DEST_DEFAULT_ALL" "GtkDestDefaults") ;(CINT "GTK_TARGET_SAME_APP" "GtkTargetFlags") ;(CINT "GTK_TARGET_SAME_WIDGET" "GtkTargetFlags") (CFNC "void gtk_drag_get_data GtkWidget* widget GdkDragContext* context GdkAtom target guint32 time") (CFNC "void gtk_drag_finish GdkDragContext* context gboolean success gboolean del guint32 time") (CFNC "GtkWidget* gtk_drag_get_source_widget GdkDragContext* context") (CFNC "void gtk_drag_highlight GtkWidget* widget") (CFNC "void gtk_drag_unhighlight GtkWidget* widget") (CFNC "void gtk_drag_dest_set GtkWidget* widget GtkDestDefaults flags GtkTargetEntry* targets gint n_targets GdkDragAction actions") ;;; (CFNC-gtk2 "void gtk_drag_dest_set_proxy GtkWidget* widget GdkWindow* proxy_window GdkDragProtocol protocol gboolean use_coordinates") (CFNC "void gtk_drag_dest_unset GtkWidget* widget") (CFNC "GdkAtom gtk_drag_dest_find_target GtkWidget* widget GdkDragContext* context GtkTargetList* @target_list") (CFNC "GtkTargetList* gtk_drag_dest_get_target_list GtkWidget* widget") (CFNC "void gtk_drag_dest_set_target_list GtkWidget* widget GtkTargetList* @target_list") (CFNC "void gtk_drag_source_set GtkWidget* widget GdkModifierType start_button_mask GtkTargetEntry* targets gint n_targets GdkDragAction actions") (CFNC "void gtk_drag_source_unset GtkWidget* widget") ;;; (CFNC-gtk2 "void gtk_drag_source_set_icon GtkWidget* widget GdkColormap* colormap GdkPixmap* pixmap GdkBitmap* mask") (CFNC "void gtk_drag_source_set_icon_pixbuf GtkWidget* widget GdkPixbuf* pixbuf") ;;; 3.9.8 (CFNC "void gtk_drag_source_set_icon_stock GtkWidget* widget gchar* stock_id") ;;; (CFNC "GdkDragContext* gtk_drag_begin GtkWidget* widget GtkTargetList* targets GdkDragAction actions gint button GdkEvent* event") (CFNC "void gtk_drag_set_icon_widget GdkDragContext* context GtkWidget* widget gint hot_x gint hot_y") ;;; (CFNC-gtk2 "void gtk_drag_set_icon_pixmap GdkDragContext* context GdkColormap* colormap GdkPixmap* pixmap GdkBitmap* mask gint hot_x gint hot_y") (CFNC "void gtk_drag_set_icon_pixbuf GdkDragContext* context GdkPixbuf* pixbuf gint hot_x gint hot_y") ;;; (CFNC "void gtk_drag_set_icon_stock GdkDragContext* context gchar* stock_id gint hot_x gint hot_y") (CFNC "void gtk_drag_set_icon_default GdkDragContext* context") (CFNC "gboolean gtk_drag_check_threshold GtkWidget* widget gint start_x gint start_y gint current_x gint current_y") (CCAST "GTK_DRAWING_AREA(obj)" "GtkDrawingArea*") (CCHK "GTK_IS_DRAWING_AREA(obj)" "GtkDrawingArea*") ;;;;(CFNC "GType gtk_drawing_area_get_type void") (CFNC "GtkWidget* gtk_drawing_area_new void") (CCAST "GTK_EDITABLE(obj)" "GtkEditable*") (CCHK "GTK_IS_EDITABLE(obj)" "GtkEditable*") ;;;;(CFNC "GType gtk_editable_get_type void") (CFNC "void gtk_editable_select_region GtkEditable* editable gint start gint end") (CFNC "gboolean gtk_editable_get_selection_bounds GtkEditable* editable gint* [start] gint* [end]") (CFNC "void gtk_editable_insert_text GtkEditable* editable gchar* new_text gint new_text_length gint* [position]") (CFNC "void gtk_editable_delete_text GtkEditable* editable gint start_pos gint end_pos") (CFNC "gchar* gtk_editable_get_chars GtkEditable* editable gint start_pos gint end_pos" 'free) (CFNC "void gtk_editable_cut_clipboard GtkEditable* editable") (CFNC "void gtk_editable_copy_clipboard GtkEditable* editable") (CFNC "void gtk_editable_paste_clipboard GtkEditable* editable") (CFNC "void gtk_editable_delete_selection GtkEditable* editable") (CFNC "void gtk_editable_set_position GtkEditable* editable gint position") (CFNC "gint gtk_editable_get_position GtkEditable* editable") (CFNC "void gtk_editable_set_editable GtkEditable* editable gboolean is_editable") (CFNC "gboolean gtk_editable_get_editable GtkEditable* editable") (CCAST "GTK_ENTRY(obj)" "GtkEntry*") (CCHK "GTK_IS_ENTRY(obj)" "GtkEntry*") ;;;;(CFNC "GType gtk_entry_get_type void") (CFNC "GtkWidget* gtk_entry_new void") (CFNC "void gtk_entry_set_visibility GtkEntry* entry gboolean visible") (CFNC "gboolean gtk_entry_get_visibility GtkEntry* entry") (CFNC "void gtk_entry_set_invisible_char GtkEntry* entry gunichar ch") (CFNC "gunichar gtk_entry_get_invisible_char GtkEntry* entry") (CFNC "void gtk_entry_set_has_frame GtkEntry* entry gboolean setting") (CFNC "gboolean gtk_entry_get_has_frame GtkEntry* entry") (CFNC "void gtk_entry_set_max_length GtkEntry* entry gint max") (CFNC "gint gtk_entry_get_max_length GtkEntry* entry") (CFNC "void gtk_entry_set_activates_default GtkEntry* entry gboolean setting") (CFNC "gboolean gtk_entry_get_activates_default GtkEntry* entry") (CFNC "void gtk_entry_set_width_chars GtkEntry* entry gint n_chars") (CFNC "gint gtk_entry_get_width_chars GtkEntry* entry") (CFNC "void gtk_entry_set_text GtkEntry* entry gchar* text") (CFNC "gchar* gtk_entry_get_text GtkEntry* entry") (CFNC "PangoLayout* gtk_entry_get_layout GtkEntry* entry") (CFNC "void gtk_entry_get_layout_offsets GtkEntry* entry gint* [x] gint* [y]") ;;; these out 2.90.7 I think ;(CINT "GTK_ANCHOR_CENTER" "GtkAnchorType") ;(CINT "GTK_ANCHOR_NORTH" "GtkAnchorType") ;(CINT "GTK_ANCHOR_NORTH_WEST" "GtkAnchorType") ;(CINT "GTK_ANCHOR_NORTH_EAST" "GtkAnchorType") ;(CINT "GTK_ANCHOR_SOUTH" "GtkAnchorType") ;(CINT "GTK_ANCHOR_SOUTH_WEST" "GtkAnchorType") ;(CINT "GTK_ANCHOR_SOUTH_EAST" "GtkAnchorType") ;(CINT "GTK_ANCHOR_WEST" "GtkAnchorType") ;(CINT "GTK_ANCHOR_EAST" "GtkAnchorType") ;(CINT "GTK_ANCHOR_N" "GtkAnchorType") ;(CINT "GTK_ANCHOR_NW" "GtkAnchorType") ;(CINT "GTK_ANCHOR_NE" "GtkAnchorType") ;(CINT "GTK_ANCHOR_S" "GtkAnchorType") ;(CINT "GTK_ANCHOR_SW" "GtkAnchorType") ;(CINT "GTK_ANCHOR_SE" "GtkAnchorType") ;(CINT "GTK_ANCHOR_W" "GtkAnchorType") ;(CINT "GTK_ANCHOR_E" "GtkAnchorType") ;;; 3.13.2 (CINT "GTK_ARROW_UP" "GtkArrowType") ;;; 3.13.2 (CINT "GTK_ARROW_DOWN" "GtkArrowType") ;;; 3.13.2 (CINT "GTK_ARROW_LEFT" "GtkArrowType") ;;; 3.13.2 (CINT "GTK_ARROW_RIGHT" "GtkArrowType") ;;; 3.15.0 (CINT "GTK_EXPAND" "GtkAttachOptions") ;;; 3.15.0 (CINT "GTK_SHRINK" "GtkAttachOptions") ;;; 3.15.0 (CINT "GTK_FILL" "GtkAttachOptions") ;;; 2.90.6 (CINT "GTK_BUTTONBOX_DEFAULT_STYLE" "GtkButtonBoxStyle") (CINT "GTK_BUTTONBOX_SPREAD" "GtkButtonBoxStyle") (CINT "GTK_BUTTONBOX_EDGE" "GtkButtonBoxStyle") (CINT "GTK_BUTTONBOX_START" "GtkButtonBoxStyle") (CINT "GTK_BUTTONBOX_END" "GtkButtonBoxStyle") (CINT "GTK_BUTTONBOX_CENTER" "GtkButtonBoxStyle") ;;; (CINT "GTK_CURVE_TYPE_LINEAR" "GtkCurveType") ;;; (CINT "GTK_CURVE_TYPE_SPLINE" "GtkCurveType") ;;; (CINT "GTK_CURVE_TYPE_FREE" "GtkCurveType") (CINT "GTK_DELETE_CHARS" "GtkDeleteType") (CINT "GTK_DELETE_WORD_ENDS" "GtkDeleteType") (CINT "GTK_DELETE_WORDS" "GtkDeleteType") (CINT "GTK_DELETE_DISPLAY_LINES" "GtkDeleteType") (CINT "GTK_DELETE_DISPLAY_LINE_ENDS" "GtkDeleteType") (CINT "GTK_DELETE_PARAGRAPH_ENDS" "GtkDeleteType") (CINT "GTK_DELETE_PARAGRAPHS" "GtkDeleteType") (CINT "GTK_DELETE_WHITESPACE" "GtkDeleteType") (CINT "GTK_DIR_TAB_FORWARD" "GtkDirectionType") (CINT "GTK_DIR_TAB_BACKWARD" "GtkDirectionType") (CINT "GTK_DIR_UP" "GtkDirectionType") (CINT "GTK_DIR_DOWN" "GtkDirectionType") (CINT "GTK_DIR_LEFT" "GtkDirectionType") (CINT "GTK_DIR_RIGHT" "GtkDirectionType") ;;; 3.15.0 (CINT "GTK_EXPANDER_COLLAPSED" "GtkExpanderStyle") ;;; 3.15.0 (CINT "GTK_EXPANDER_SEMI_COLLAPSED" "GtkExpanderStyle") ;;; 3.15.0 (CINT "GTK_EXPANDER_SEMI_EXPANDED" "GtkExpanderStyle") ;;; 3.15.0 (CINT "GTK_EXPANDER_EXPANDED" "GtkExpanderStyle") ;;; 3.9.8 ;;; (CINT "GTK_ICON_SIZE_INVALID" "GtkIconSize") ;;; (CINT "GTK_ICON_SIZE_MENU" "GtkIconSize") ;;; (CINT "GTK_ICON_SIZE_SMALL_TOOLBAR" "GtkIconSize") ;;; (CINT "GTK_ICON_SIZE_LARGE_TOOLBAR" "GtkIconSize") ;;; (CINT "GTK_ICON_SIZE_BUTTON" "GtkIconSize") ;;; (CINT "GTK_ICON_SIZE_DND" "GtkIconSize") ;;; (CINT "GTK_ICON_SIZE_DIALOG" "GtkIconSize") (CINT "GTK_TEXT_DIR_NONE" "GtkTextDirection") (CINT "GTK_TEXT_DIR_LTR" "GtkTextDirection") (CINT "GTK_TEXT_DIR_RTL" "GtkTextDirection") (CINT "GTK_JUSTIFY_LEFT" "GtkJustification") (CINT "GTK_JUSTIFY_RIGHT" "GtkJustification") (CINT "GTK_JUSTIFY_CENTER" "GtkJustification") (CINT "GTK_JUSTIFY_FILL" "GtkJustification") (CINT "GTK_MENU_DIR_PARENT" "GtkMenuDirectionType") (CINT "GTK_MENU_DIR_CHILD" "GtkMenuDirectionType") (CINT "GTK_MENU_DIR_NEXT" "GtkMenuDirectionType") (CINT "GTK_MENU_DIR_PREV" "GtkMenuDirectionType") ;;; 2.91.5 (CINT "GTK_PIXELS" "GtkMetricType") ;;; 2.91.5 (CINT "GTK_INCHES" "GtkMetricType") ;;; 2.91.5 (CINT "GTK_CENTIMETERS" "GtkMetricType") (CINT "GTK_MOVEMENT_LOGICAL_POSITIONS" "GtkMovementStep") (CINT "GTK_MOVEMENT_VISUAL_POSITIONS" "GtkMovementStep") (CINT "GTK_MOVEMENT_WORDS" "GtkMovementStep") (CINT "GTK_MOVEMENT_DISPLAY_LINES" "GtkMovementStep") (CINT "GTK_MOVEMENT_DISPLAY_LINE_ENDS" "GtkMovementStep") (CINT "GTK_MOVEMENT_PARAGRAPHS" "GtkMovementStep") (CINT "GTK_MOVEMENT_PARAGRAPH_ENDS" "GtkMovementStep") (CINT "GTK_MOVEMENT_PAGES" "GtkMovementStep") (CINT "GTK_MOVEMENT_BUFFER_ENDS" "GtkMovementStep") (CINT "GTK_ORIENTATION_HORIZONTAL" "GtkOrientation") (CINT "GTK_ORIENTATION_VERTICAL" "GtkOrientation") (CINT "GTK_CORNER_TOP_LEFT" "GtkCornerType") (CINT "GTK_CORNER_BOTTOM_LEFT" "GtkCornerType") (CINT "GTK_CORNER_TOP_RIGHT" "GtkCornerType") (CINT "GTK_CORNER_BOTTOM_RIGHT" "GtkCornerType") (CINT "GTK_PACK_START" "GtkPackType") (CINT "GTK_PACK_END" "GtkPackType") ;;; 3.15.0 (CINT "GTK_PATH_PRIO_LOWEST" "GtkPathPriorityType") ;;; 3.15.0 (CINT "GTK_PATH_PRIO_GTK") ;;; 3.15.0 (CINT "GTK_PATH_PRIO_APPLICATION" "GtkPathPriorityType") ;;; 3.15.0 (CINT "GTK_PATH_PRIO_THEME" "GtkPathPriorityType") ;;; 3.15.0 (CINT "GTK_PATH_PRIO_RC" "GtkPathPriorityType") ;;; 3.15.0 (CINT "GTK_PATH_PRIO_HIGHEST" "GtkPathPriorityType") ;;; 3.15.0 (CINT "GTK_PATH_PRIO_MASK") ;;; 3.15.0 (CINT "GTK_PATH_WIDGET" "GtkPathType") ;;; 3.15.0 (CINT "GTK_PATH_WIDGET_CLASS" "GtkPathType") ;;; 3.15.0 (CINT "GTK_PATH_CLASS" "GtkPathType") (CINT "GTK_POLICY_ALWAYS" "GtkPolicyType") (CINT "GTK_POLICY_AUTOMATIC" "GtkPolicyType") (CINT "GTK_POLICY_NEVER" "GtkPolicyType") (CINT "GTK_POS_LEFT" "GtkPositionType") (CINT "GTK_POS_RIGHT" "GtkPositionType") (CINT "GTK_POS_TOP" "GtkPositionType") (CINT "GTK_POS_BOTTOM" "GtkPositionType") (CINT "GTK_RELIEF_NORMAL" "GtkReliefStyle") (CINT "GTK_RELIEF_HALF" "GtkReliefStyle") (CINT "GTK_RELIEF_NONE" "GtkReliefStyle") (CINT "GTK_RESIZE_PARENT" "GtkResizeMode") (CINT "GTK_RESIZE_QUEUE" "GtkResizeMode") (CINT "GTK_RESIZE_IMMEDIATE" "GtkResizeMode") (CINT "GTK_SCROLL_NONE" "GtkScrollType") (CINT "GTK_SCROLL_JUMP" "GtkScrollType") (CINT "GTK_SCROLL_STEP_BACKWARD" "GtkScrollType") (CINT "GTK_SCROLL_STEP_FORWARD" "GtkScrollType") (CINT "GTK_SCROLL_PAGE_BACKWARD" "GtkScrollType") (CINT "GTK_SCROLL_PAGE_FORWARD" "GtkScrollType") (CINT "GTK_SCROLL_STEP_UP" "GtkScrollType") (CINT "GTK_SCROLL_STEP_DOWN" "GtkScrollType") (CINT "GTK_SCROLL_PAGE_UP" "GtkScrollType") (CINT "GTK_SCROLL_PAGE_DOWN" "GtkScrollType") (CINT "GTK_SCROLL_STEP_LEFT" "GtkScrollType") (CINT "GTK_SCROLL_STEP_RIGHT" "GtkScrollType") (CINT "GTK_SCROLL_PAGE_LEFT" "GtkScrollType") (CINT "GTK_SCROLL_PAGE_RIGHT" "GtkScrollType") (CINT "GTK_SCROLL_START" "GtkScrollType") (CINT "GTK_SCROLL_END" "GtkScrollType") (CINT "GTK_SELECTION_NONE" "GtkSelectionMode") (CINT "GTK_SELECTION_SINGLE" "GtkSelectionMode") (CINT "GTK_SELECTION_BROWSE" "GtkSelectionMode") (CINT "GTK_SELECTION_MULTIPLE" "GtkSelectionMode") ;;; 2.90.7 (CINT "GTK_SELECTION_EXTENDED" "GtkSelectionMode") (CINT "GTK_SHADOW_NONE" "GtkShadowType") (CINT "GTK_SHADOW_IN" "GtkShadowType") (CINT "GTK_SHADOW_OUT" "GtkShadowType") (CINT "GTK_SHADOW_ETCHED_IN" "GtkShadowType") (CINT "GTK_SHADOW_ETCHED_OUT" "GtkShadowType") ;(CINT "GTK_STATE_NORMAL" "GtkStateType") ;(CINT "GTK_STATE_ACTIVE" "GtkStateType") ;(CINT "GTK_STATE_PRELIGHT" "GtkStateType") ;(CINT "GTK_STATE_SELECTED" "GtkStateType") ;(CINT "GTK_STATE_INSENSITIVE" "GtkStateType") ;(CINT-3.0 "GTK_STATE_INCONSISTENT" "GtkStateType") ;(CINT-3.0 "GTK_STATE_FOCUSED" "GtkStateType") (CINT "GTK_TOOLBAR_ICONS" "GtkToolbarStyle") (CINT "GTK_TOOLBAR_TEXT" "GtkToolbarStyle") (CINT "GTK_TOOLBAR_BOTH" "GtkToolbarStyle") (CINT "GTK_TOOLBAR_BOTH_HORIZ" "GtkToolbarStyle") ;;; (CINT-gtk2 "GTK_UPDATE_CONTINUOUS" "GtkUpdateType") ;;; (CINT-gtk2 "GTK_UPDATE_DISCONTINUOUS" "GtkUpdateType") ;;; (CINT-gtk2 "GTK_UPDATE_DELAYED" "GtkUpdateType") ;(CINT "GTK_VISIBILITY_NONE" "GtkVisibility") ;(CINT "GTK_VISIBILITY_PARTIAL" "GtkVisibility") ;(CINT "GTK_VISIBILITY_FULL" "GtkVisibility") ;these are from clist/ctree (deprecated widgets) (CINT "GTK_WIN_POS_NONE" "GtkWindowPosition") (CINT "GTK_WIN_POS_CENTER" "GtkWindowPosition") (CINT "GTK_WIN_POS_MOUSE" "GtkWindowPosition") (CINT "GTK_WIN_POS_CENTER_ALWAYS" "GtkWindowPosition") (CINT "GTK_WIN_POS_CENTER_ON_PARENT" "GtkWindowPosition") (CINT "GTK_WINDOW_TOPLEVEL" "GtkWindowType") (CINT "GTK_WINDOW_POPUP" "GtkWindowType") (CINT "GTK_WRAP_NONE" "GtkWrapMode") (CINT "GTK_WRAP_CHAR" "GtkWrapMode") (CINT "GTK_WRAP_WORD" "GtkWrapMode") (CINT "GTK_SORT_ASCENDING" "GtkSortType") (CINT "GTK_SORT_DESCENDING" "GtkSortType") (CCAST "GTK_EVENT_BOX(obj)" "GtkEventBox*") (CCHK "GTK_IS_EVENT_BOX(obj)" "GtkEventBox*") ;;;;(CFNC "GType gtk_event_box_get_type void") (CFNC "GtkWidget* gtk_event_box_new void") ;;; entire thing deprecated 2.11.0 ;;; (CCAST "GTK_FILE_SELECTION(obj)" "GtkFileSelection*") ;;; (CCHK "GTK_IS_FILE_SELECTION(obj)" "GtkFileSelection*") ;;; ;;;;(CFNC "GType gtk_file_selection_get_type void") ;;; (CFNC "GtkWidget* gtk_file_selection_new gchar* title") ;;; (CFNC "void gtk_file_selection_set_filename GtkFileSelection* filesel gchar* filename") ;;; (CFNC "gchar* gtk_file_selection_get_filename GtkFileSelection* filesel") ;;; (CFNC "void gtk_file_selection_complete GtkFileSelection* filesel gchar* pattern") ;;; (CFNC "void gtk_file_selection_show_fileop_buttons GtkFileSelection* filesel") ;;; (CFNC "void gtk_file_selection_hide_fileop_buttons GtkFileSelection* filesel") ;;; ;;; added 1.3.15: ;;; (CFNC "gchar** gtk_file_selection_get_selections GtkFileSelection* filesel") ; FREE (g_strfreev) ;;; (CFNC "void gtk_file_selection_set_select_multiple GtkFileSelection* filesel gboolean select_multiple") ;;; (CFNC "gboolean gtk_file_selection_get_select_multiple GtkFileSelection* filesel") ;;; added 2.0.0 ;;; 2.91.6 (CLNG "GTK_TYPE_ICON_SET") ;;; 2.91.6 (CLNG "GTK_TYPE_ICON_SOURCE") ;;; 2.91.6 (CLNG "GTK_TYPE_SELECTION_DATA") ;;; 2.91.6 (CLNG "GTK_TYPE_BORDER") ;;; 2.91.6 (CLNG "GTK_TYPE_TREE_ITER") ;;; 2.91.6 (CLNG "GTK_TYPE_TREE_PATH") ;;; 2.91.6 (CLNG "GTK_TYPE_IDENTIFIER") ;;; 2.91.6 (CLNG "GTK_TYPE_REQUISITION") ;;;;(CFNC "GType gtk_icon_set_get_type void") ;;;;(CFNC "GType gtk_icon_source_get_type void") ;;;;(CFNC "GType gtk_selection_data_get_type void") ;;;;(CFNC "GType gtk_border_get_type void") ;;;;(CFNC "GType gtk_tree_path_get_type void") ;;;;(CFNC "GType gtk_tree_iter_get_type void") ;;;;(CFNC "GType gtk_identifier_get_type void") ;;;;(CFNC "GType gtk_requisition_get_type void") ;;;; (CCAST "GTK_FIXED(obj)" "GtkFixed*") (CCHK "GTK_IS_FIXED(obj)" "GtkFixed*") ;;;;(CFNC "GType gtk_fixed_get_type void") (CFNC "GtkWidget* gtk_fixed_new void") (CFNC "void gtk_fixed_put GtkFixed* fixed GtkWidget* widget gint x gint y") (CFNC "void gtk_fixed_move GtkFixed* fixed GtkWidget* widget gint x gint y") ;;; out 2.19.3 (CFNC "void gtk_fixed_set_has_window GtkFixed* fixed gboolean has_window") ;;; (CFNC "gboolean gtk_fixed_get_has_window GtkFixed* fixed") ;;; (CCAST-gtk2 "GTK_FONT_SELECTION(obj)" "GtkFontSelection*") ;;; (CCHK-gtk2 "GTK_IS_FONT_SELECTION(obj)" "GtkFontSelection*") ;;; (CCAST-gtk2 "GTK_FONT_SELECTION_DIALOG(obj)" "GtkFontSelectionDialog*") ;;; (CCHK-gtk2 "GTK_IS_FONT_SELECTION_DIALOG(obj)" "GtkFontSelectionDialog*") ;;; (CFNC-gtk2 "GtkWidget* gtk_font_selection_new void") ;;; (CFNC-gtk2 "gchar* gtk_font_selection_get_font_name GtkFontSelection* fontsel" 'free) ;;; (CFNC-gtk2 "gboolean gtk_font_selection_set_font_name GtkFontSelection* fontsel gchar* fontname") ;;; (CFNC-gtk2 "gchar* gtk_font_selection_get_preview_text GtkFontSelection* fontsel") ;;; (CFNC-gtk2 "void gtk_font_selection_set_preview_text GtkFontSelection* fontsel gchar* text") ;;; (CFNC-gtk2 "GtkWidget* gtk_font_selection_dialog_new gchar* title") ;;; (CFNC-gtk2 "gchar* gtk_font_selection_dialog_get_font_name GtkFontSelectionDialog* fsd" 'free) ;;; (CFNC-gtk2 "gboolean gtk_font_selection_dialog_set_font_name GtkFontSelectionDialog* fsd gchar* fontname") ;;; (CFNC-gtk2 "gchar* gtk_font_selection_dialog_get_preview_text GtkFontSelectionDialog* fsd") ;;; (CFNC-gtk2 "void gtk_font_selection_dialog_set_preview_text GtkFontSelectionDialog* fsd gchar* text") (CCAST "GTK_FRAME(obj)" "GtkFrame*") (CCHK "GTK_IS_FRAME(obj)" "GtkFrame*") ;;;;(CFNC "GType gtk_frame_get_type void") (CFNC "GtkWidget* gtk_frame_new gchar* label") (CFNC "void gtk_frame_set_label GtkFrame* frame gchar* label") (CFNC "gchar* gtk_frame_get_label GtkFrame* frame") (CFNC "void gtk_frame_set_label_widget GtkFrame* frame GtkWidget* label_widget") (CFNC "GtkWidget* gtk_frame_get_label_widget GtkFrame* frame") (CFNC "void gtk_frame_set_label_align GtkFrame* frame gfloat xalign gfloat yalign") (CFNC "void gtk_frame_get_label_align GtkFrame* frame gfloat* [xalign] gfloat* [yalign]") (CFNC "void gtk_frame_set_shadow_type GtkFrame* frame GtkShadowType type") (CFNC "GtkShadowType gtk_frame_get_shadow_type GtkFrame* frame") ;;; (CCAST "GTK_GAMMA_CURVE(obj)" "GtkGammaCurve*") ;;; (CCHK "GTK_IS_GAMMA_CURVE(obj)" "GtkGammaCurve*") ;;;;(CFNC "GType gtk_gamma_curve_get_type void") ;;; (CFNC "GtkWidget* gtk_gamma_curve_new void") ;;; 2.90.6 (CFNC "GdkGC* gtk_gc_get gint depth GdkColormap* colormap GdkGCValues* values GdkGCValuesMask values_mask") ;;; 2.90.6 (CFNC "void gtk_gc_release GdkGC* gc") ;;; 3.3.2 (CCAST "GTK_HANDLE_BOX(obj)" "GtkHandleBox*") ;;; 3.3.2 (CCHK "GTK_IS_HANDLE_BOX(obj)" "GtkHandleBox*") ;;;;(CFNC "GType gtk_handle_box_get_type void") ;;; 3.3.2 (CFNC "GtkWidget* gtk_handle_box_new void") ;;; 3.3.2 (CFNC "void gtk_handle_box_set_shadow_type GtkHandleBox* handle_box GtkShadowType type") ;;; 3.3.2 (CFNC "GtkShadowType gtk_handle_box_get_shadow_type GtkHandleBox* handle_box") ;;; 3.3.2 (CFNC "void gtk_handle_box_set_handle_position GtkHandleBox* handle_box GtkPositionType position") ;;; 3.3.2 (CFNC "GtkPositionType gtk_handle_box_get_handle_position GtkHandleBox* handle_box") ;;; 3.3.2 (CFNC "void gtk_handle_box_set_snap_edge GtkHandleBox* handle_box GtkPositionType edge") ;;; 3.3.2 (CFNC "GtkPositionType gtk_handle_box_get_snap_edge GtkHandleBox* handle_box") ;;; 3.1.6 (CCAST "GTK_HBUTTON_BOX(obj)" "GtkHButtonBox*") ;;; 3.1.6 (CCHK "GTK_IS_HBUTTON_BOX(obj)" "GtkHButtonBox*") ;;; 3.1.6 ;;;;(CFNC "GType gtk_hbutton_box_get_type void") ;;; 3.1.6 (CFNC "GtkWidget* gtk_hbutton_box_new void") ;;; 3.1.6 (CCAST "GTK_HBOX(obj)" "GtkHBox*") ;;; 3.1.6 (CCHK "GTK_IS_HBOX(obj)" "GtkHBox*") ;;; 3.1.6 ;;;;(CFNC "GType gtk_hbox_get_type void") ;;; 3.1.6 (CFNC "GtkWidget* gtk_hbox_new gboolean homogeneous gint spacing") ;;; 3.1.6 (CCAST "GTK_HPANED(obj)" "GtkHPaned*") ;;; 3.1.6 (CCHK "GTK_IS_HPANED(obj)" "GtkHPaned*") ;;; 3.1.6 ;;;;(CFNC "GType gtk_hpaned_get_type void") ;;; 3.1.6 (CFNC "GtkWidget* gtk_hpaned_new void") ;;; 2.91.5 (CCAST "GTK_HRULER(obj)" "GtkHRuler*") ;;; 2.91.5 (CCHK "GTK_IS_HRULER(obj)" "GtkHRuler*") ;;;;(CFNC "GType gtk_hruler_get_type void") ;;; 2.91.5 (CFNC "GtkWidget* gtk_hruler_new void") ;;; 3.1.6 (CCAST "GTK_HSCALE(obj)" "GtkHScale*") ;;; 3.1.6 (CCHK "GTK_IS_HSCALE(obj)" "GtkHScale*") ;;; 3.1.6 ;;;;(CFNC "GType gtk_hscale_get_type void") ;;; 3.1.6 (CFNC "GtkWidget* gtk_hscale_new GtkAdjustment* @adjustment") ;;; 3.1.6 (CFNC "GtkWidget* gtk_hscale_new_with_range gdouble min gdouble max gdouble step") ;;; 3.1.6 (CCAST "GTK_HSCROLLBAR(obj)" "GtkHScrollbar*") ;;; 3.1.6 (CCHK "GTK_IS_HSCROLLBAR(obj)" "GtkHScrollbar*") ;;; 3.1.6 ;;;;(CFNC "GType gtk_hscrollbar_get_type void") ;;; 3.1.6 (CFNC "GtkWidget* gtk_hscrollbar_new GtkAdjustment* @adjustment") ;;; 3.1.6 (CCAST "GTK_HSEPARATOR(obj)" "GtkHSeparator*") ;;; 3.1.6 (CCHK "GTK_IS_HSEPARATOR(obj)" "GtkHSeparator*") ;;; 3.1.6 ;;;;(CFNC "GType gtk_hseparator_get_type void") ;;; 3.1.6 (CFNC "GtkWidget* gtk_hseparator_new void") ;;; all of these deprecated 3.9.8 ;;; (CCAST "GTK_ICON_FACTORY(object)" "GtkIconFactory*") ;;; (CCHK "GTK_IS_ICON_FACTORY(object)" "GtkIconFactory*") ;;;;(CFNC "GType gtk_icon_factory_get_type void") ;;; (CFNC "GtkIconFactory* gtk_icon_factory_new void") ;;; (CFNC "void gtk_icon_factory_add GtkIconFactory* factory gchar* stock_id GtkIconSet* icon_set") ;;; (CFNC "GtkIconSet* gtk_icon_factory_lookup GtkIconFactory* factory gchar* stock_id") ;;; (CFNC "void gtk_icon_factory_add_default GtkIconFactory* factory") ;;; (CFNC "void gtk_icon_factory_remove_default GtkIconFactory* factory") ;;; (CFNC "GtkIconSet* gtk_icon_factory_lookup_default gchar* stock_id") ;;; (CFNC "gboolean gtk_icon_size_lookup GtkIconSize size gint* [width] gint* [height]") ;;; (CFNC "GtkIconSize gtk_icon_size_register gchar* name gint width gint height") ;;; (CFNC "void gtk_icon_size_register_alias gchar* alias GtkIconSize target") ;;; (CFNC "GtkIconSize gtk_icon_size_from_name gchar* name") ; null = segfault ;;; (CFNC "gchar* gtk_icon_size_get_name GtkIconSize size") ;;; (CFNC "GtkIconSet* gtk_icon_set_new void") ;;; (CFNC "GtkIconSet* gtk_icon_set_new_from_pixbuf GdkPixbuf* pixbuf") ;;; (CFNC "GtkIconSet* gtk_icon_set_ref GtkIconSet* icon_set") ;;; (CFNC "void gtk_icon_set_unref GtkIconSet* icon_set") ;;; (CFNC "GtkIconSet* gtk_icon_set_copy GtkIconSet* icon_set") ;;; ;;; (CFNC-gtk2 "GdkPixbuf* gtk_icon_set_render_icon GtkIconSet* icon_set GtkStyle* @style GtkTextDirection direction GtkStateType state GtkIconSize size GtkWidget* @widget char* detail") ;;; (CFNC "void gtk_icon_set_add_source GtkIconSet* icon_set GtkIconSource* source") ;;; (CFNC "void gtk_icon_set_get_sizes GtkIconSet* icon_set GtkIconSize** [sizes] gint* [n_sizes]") ;;; (CFNC "GtkIconSource* gtk_icon_source_new void") ;;; (CFNC "GtkIconSource* gtk_icon_source_copy GtkIconSource* source") ;;; (CFNC "void gtk_icon_source_free GtkIconSource* source") ;;; (CFNC "void gtk_icon_source_set_filename GtkIconSource* source gchar* filename") ;;; (CFNC "void gtk_icon_source_set_pixbuf GtkIconSource* source GdkPixbuf* @pixbuf") ;;; (CFNC "gchar* gtk_icon_source_get_filename GtkIconSource* source") ;;; (CFNC "GdkPixbuf* gtk_icon_source_get_pixbuf GtkIconSource* source") ;;; (CFNC "void gtk_icon_source_set_direction_wildcarded GtkIconSource* source gboolean setting") ;;; (CFNC "void gtk_icon_source_set_state_wildcarded GtkIconSource* source gboolean setting") ;;; (CFNC "void gtk_icon_source_set_size_wildcarded GtkIconSource* source gboolean setting") ;;; (CFNC "gboolean gtk_icon_source_get_size_wildcarded GtkIconSource* source") ;;; (CFNC "gboolean gtk_icon_source_get_state_wildcarded GtkIconSource* source") ;;; (CFNC "gboolean gtk_icon_source_get_direction_wildcarded GtkIconSource* source") ;;; (CFNC "void gtk_icon_source_set_direction GtkIconSource* source GtkTextDirection direction") ;;; (CFNC "void gtk_icon_source_set_state GtkIconSource* source GtkStateType state") ;;; (CFNC "void gtk_icon_source_set_size GtkIconSource* source GtkIconSize size") ;;; (CFNC "GtkTextDirection gtk_icon_source_get_direction GtkIconSource* source") ;;; (CFNC "GtkStateType gtk_icon_source_get_state GtkIconSource* source") ;;; (CFNC "GtkIconSize gtk_icon_source_get_size GtkIconSource* source") ;;; !! (CCAST "GTK_IMAGE(obj)" "GtkImage*") (CCHK "GTK_IS_IMAGE(obj)" "GtkImage*") (CINT "GTK_IMAGE_EMPTY" "GtkImageType") ;;; 2.91.0 (CINT "GTK_IMAGE_PIXMAP" "GtkImageType") ;;; 2.90.6 (CINT "GTK_IMAGE_IMAGE" "GtkImageType") (CINT "GTK_IMAGE_PIXBUF" "GtkImageType") (CINT "GTK_IMAGE_STOCK" "GtkImageType") (CINT "GTK_IMAGE_ICON_SET" "GtkImageType") (CINT "GTK_IMAGE_ANIMATION" "GtkImageType") ;;;;(CFNC "GType gtk_image_get_type void") (CFNC "GtkWidget* gtk_image_new void") ;;; 2.91.0 (CFNC "GtkWidget* gtk_image_new_from_pixmap GdkPixmap* @pixmap GdkBitmap* @mask") ;;; 2.90.6 (CFNC "GtkWidget* gtk_image_new_from_image GdkImage* @image GdkBitmap* @mask") (CFNC "GtkWidget* gtk_image_new_from_file gchar* filename") (CFNC "GtkWidget* gtk_image_new_from_pixbuf GdkPixbuf* @pixbuf") ;;; (CFNC "GtkWidget* gtk_image_new_from_stock gchar* stock_id GtkIconSize size") ;;; (CFNC "GtkWidget* gtk_image_new_from_icon_set GtkIconSet* icon_set GtkIconSize size") (CFNC "GtkWidget* gtk_image_new_from_animation GdkPixbufAnimation* animation") ;;; 2.91.0 (CFNC "void gtk_image_set_from_pixmap GtkImage* image GdkPixmap* @pixmap GdkBitmap* @mask") ;;; 2.90.6 (CFNC "void gtk_image_set_from_image GtkImage* image GdkImage* @gdk_image GdkBitmap* @mask") (CFNC "void gtk_image_set_from_file GtkImage* image gchar* filename") (CFNC "void gtk_image_set_from_pixbuf GtkImage* image GdkPixbuf* @pixbuf") ;;; (CFNC "void gtk_image_set_from_stock GtkImage* image gchar* stock_id GtkIconSize size") ;;; (CFNC "void gtk_image_set_from_icon_set GtkImage* image GtkIconSet* icon_set GtkIconSize size") (CFNC "void gtk_image_set_from_animation GtkImage* image GdkPixbufAnimation* @animation") (CFNC "GtkImageType gtk_image_get_storage_type GtkImage* image") ;;; 2.91.0 (CFNC "void gtk_image_get_pixmap GtkImage* image GdkPixmap** [pixmap] GdkBitmap** [mask]") ;;; 2.90.6 (CFNC "void gtk_image_get_image GtkImage* image GdkImage** [gdk_image] GdkBitmap** [mask]") (CFNC "GdkPixbuf* gtk_image_get_pixbuf GtkImage* image") ;;; (CFNC "void gtk_image_get_stock GtkImage* image gchar** [stock_id] GtkIconSize* [size]") ;;; (CFNC "void gtk_image_get_icon_set GtkImage* image GtkIconSet** [icon_set] GtkIconSize* [size]") (CFNC "GdkPixbufAnimation* gtk_image_get_animation GtkImage* image") ;;; out 3.9.8 ;;; (CCAST "GTK_IMAGE_MENU_ITEM(obj)" "GtkImageMenuItem*") ;;; (CCHK "GTK_IS_IMAGE_MENU_ITEM(obj)" "GtkImageMenuItem*") ;;; ;;;;(CFNC "GType gtk_image_menu_item_get_type void") ;;; (CFNC "GtkWidget* gtk_image_menu_item_new void") ;;; (CFNC "GtkWidget* gtk_image_menu_item_new_with_label gchar* label") ; null = segfault ;;; (CFNC "GtkWidget* gtk_image_menu_item_new_with_mnemonic gchar* label") ;;; (CFNC "GtkWidget* gtk_image_menu_item_new_from_stock gchar* stock_id GtkAccelGroup* @accel_group") ;;; (CFNC "void gtk_image_menu_item_set_image GtkImageMenuItem* image_menu_item GtkWidget* image") ;;; (CFNC "GtkWidget* gtk_image_menu_item_get_image GtkImageMenuItem* image_menu_item") (CCAST "GTK_IM_CONTEXT(obj)" "GtkIMContext*") (CCHK "GTK_IS_IM_CONTEXT(obj)" "GtkIMContext*") ;;;;(CFNC "GType gtk_im_context_get_type void") (CFNC "void gtk_im_context_set_client_window GtkIMContext* context GdkWindow* @window") (CFNC "void gtk_im_context_get_preedit_string GtkIMContext* context gchar** [str] PangoAttrList** [attrs] gint* [cursor_pos]") ; FREE (str) (CFNC "gboolean gtk_im_context_filter_keypress GtkIMContext* context GdkEventKey* event") (CFNC "void gtk_im_context_focus_in GtkIMContext* context") (CFNC "void gtk_im_context_focus_out GtkIMContext* context") (CFNC "void gtk_im_context_reset GtkIMContext* context") (CFNC "void gtk_im_context_set_cursor_location GtkIMContext* context GdkRectangle* area") (CFNC "void gtk_im_context_set_use_preedit GtkIMContext* context gboolean use_preedit") (CFNC "void gtk_im_context_set_surrounding GtkIMContext* context gchar* text gint len gint cursor_index") (CFNC "gboolean gtk_im_context_get_surrounding GtkIMContext* context gchar** [text] gint* [cursor_index]") (CFNC "gboolean gtk_im_context_delete_surrounding GtkIMContext* context gint offset gint n_chars") (CCAST "GTK_IM_CONTEXT_SIMPLE(obj)" "GtkIMContextSimple*") (CCHK "GTK_IS_IM_CONTEXT_SIMPLE(obj)" "GtkIMContextSimple*") (CINT "GTK_MAX_COMPOSE_LEN") ;;;;(CFNC "GType gtk_im_context_simple_get_type void") (CFNC "GtkIMContext* gtk_im_context_simple_new void") (CFNC "void gtk_im_context_simple_add_table GtkIMContextSimple* context_simple guint16* data gint max_seq_len gint n_seqs") ;;; (CCAST "GTK_IM_MULTICONTEXT(obj)" "GtkIMMulticontext*") ;;; (CCHK "GTK_IS_IM_MULTICONTEXT(obj)" "GtkIMMulticontext*") ;;;;(CFNC "GType gtk_im_multicontext_get_type void") ;;; (CFNC "GtkIMContext* gtk_im_multicontext_new void") ;;; 3.11 (CFNC "void gtk_im_multicontext_append_menuitems GtkIMMulticontext* context GtkMenuShell* menushell") ;;; (CCAST "GTK_INPUT_DIALOG(obj)" "GtkInputDialog*") ;;; (CCHK "GTK_IS_INPUT_DIALOG(obj)" "GtkInputDialog*") ;;;;(CFNC "GType gtk_input_dialog_get_type void") ;;; (CFNC "GtkWidget* gtk_input_dialog_new void") (CCAST "GTK_INVISIBLE(obj)" "GtkInvisible*") (CCHK "GTK_IS_INVISIBLE(obj)" "GtkInvisible*") ;;;;(CFNC "GType gtk_invisible_get_type void") (CFNC "GtkWidget* gtk_invisible_new void") ;;; out 2.3 (CCAST "GTK_ITEM_FACTORY(object)" "GtkItemFactory*") ;;; out 2.3 (CCHK "GTK_IS_ITEM_FACTORY(object)" "GtkItemFactory*") ;;;;;;; out 2.3 (CFNC "GType gtk_item_factory_get_type void") ;;; out 2.3 (CFNC "GtkItemFactory* gtk_item_factory_new GType container_type gchar* path GtkAccelGroup* @accel_group") ;;; out 2.3 (CFNC "void gtk_item_factory_construct GtkItemFactory* ifactory GType container_type gchar* path GtkAccelGroup* @accel_group") ;;; out 2.3 (CFNC "void gtk_item_factory_add_foreign GtkWidget* accel_widget gchar* full_path GtkAccelGroup* accel_group guint keyval GdkModifierType modifiers;;; out 2.3 ") ;;; out 2.3 (CFNC "GtkItemFactory* gtk_item_factory_from_widget GtkWidget* widget") ;;; out 2.3 (CFNC "gchar* gtk_item_factory_path_from_widget GtkWidget* widget") ;;; out 2.3 (CFNC "GtkWidget* gtk_item_factory_get_item GtkItemFactory* ifactory gchar* path") ;;; out 2.3 (CFNC "GtkWidget* gtk_item_factory_get_widget GtkItemFactory* ifactory gchar* path") ;;; out 2.3 (CFNC "GtkWidget* gtk_item_factory_get_widget_by_action GtkItemFactory* ifactory guint action") ;;; out 2.3 (CFNC "GtkWidget* gtk_item_factory_get_item_by_action GtkItemFactory* ifactory guint action") ;;; out 2.3 (CFNC "void gtk_item_factory_create_item GtkItemFactory* ifactory GtkItemFactoryEntry* entry gpointer callback_data guint callback_type") ;;; out 2.3 (CFNC "void gtk_item_factory_create_items GtkItemFactory* ifactory guint n_entries GtkItemFactoryEntry* entries gpointer callback_data") ;;; out 2.3 (CFNC "void gtk_item_factory_delete_item GtkItemFactory* ifactory gchar* path") ;;; out 2.3 (CFNC "void gtk_item_factory_delete_entry GtkItemFactory* ifactory GtkItemFactoryEntry* entry") ;;; out 2.3 (CFNC "void gtk_item_factory_delete_entries GtkItemFactory* ifactory guint n_entries GtkItemFactoryEntry* entries") ;;; out 2.3 (CFNC "void gtk_item_factory_popup GtkItemFactory* ifactory guint x guint y guint mouse_button guint32 time") ;;; out 2.3 (CFNC "void gtk_item_factory_popup_with_data GtkItemFactory* ifactory lambda_data func_info GtkDestroyNotify destroy guint x guint y guint mouse_button guint32 time") ;;; out 2.3 (CFNC "gpointer gtk_item_factory_popup_data GtkItemFactory* ifactory") ;;; out 2.3 (CFNC "gpointer gtk_item_factory_popup_data_from_widget GtkWidget* widget") ;;; out 2.3 (CFNC "void gtk_item_factory_set_translate_func GtkItemFactory* ifactory GtkTranslateFunc func lambda_data func_info GtkDestroyNotify notify") ;;; 2.90.7 (CCAST "GTK_ITEM(obj)" "GtkItem*") ;;; 2.90.7 (CCHK "GTK_IS_ITEM(obj)" "GtkItem*") ;;; 2.90.7 ;;;;(CFNC "GType gtk_item_get_type void") ;;; 2.90.7 (CFNC "void gtk_item_select GtkItem* item") ;;; 2.90.7 (CFNC "void gtk_item_deselect GtkItem* item") ;;; 2.90.7 (CFNC "void gtk_item_toggle GtkItem* item") (CCAST "GTK_LABEL(obj)" "GtkLabel*") (CCHK "GTK_IS_LABEL(obj)" "GtkLabel*") ;;;;(CFNC "GType gtk_label_get_type void") (CFNC "GtkWidget* gtk_label_new char* str") (CFNC "GtkWidget* gtk_label_new_with_mnemonic char* str") (CFNC "void gtk_label_set_text GtkLabel* label char* str") (CFNC "gchar* gtk_label_get_text GtkLabel* label") (CFNC "void gtk_label_set_attributes GtkLabel* label PangoAttrList* attrs") (CFNC "PangoAttrList* gtk_label_get_attributes GtkLabel* label") (CFNC "void gtk_label_set_label GtkLabel* label gchar* str") (CFNC "gchar* gtk_label_get_label GtkLabel* label") (CFNC "void gtk_label_set_markup GtkLabel* label gchar* str") (CFNC "void gtk_label_set_use_markup GtkLabel* label gboolean setting") (CFNC "gboolean gtk_label_get_use_markup GtkLabel* label") (CFNC "void gtk_label_set_use_underline GtkLabel* label gboolean setting") (CFNC "gboolean gtk_label_get_use_underline GtkLabel* label") (CFNC "void gtk_label_set_markup_with_mnemonic GtkLabel* label gchar* str") (CFNC "guint gtk_label_get_mnemonic_keyval GtkLabel* label") (CFNC "void gtk_label_set_mnemonic_widget GtkLabel* label GtkWidget* widget") (CFNC "GtkWidget* gtk_label_get_mnemonic_widget GtkLabel* label") (CFNC "void gtk_label_set_text_with_mnemonic GtkLabel* label gchar* str") (CFNC "void gtk_label_set_justify GtkLabel* label GtkJustification jtype") (CFNC "GtkJustification gtk_label_get_justify GtkLabel* label") (CFNC "void gtk_label_set_pattern GtkLabel* label gchar* pattern") (CFNC "void gtk_label_set_line_wrap GtkLabel* label gboolean wrap") (CFNC "gboolean gtk_label_get_line_wrap GtkLabel* label") (CFNC "void gtk_label_set_selectable GtkLabel* label gboolean setting") (CFNC "gboolean gtk_label_get_selectable GtkLabel* label") (CFNC "void gtk_label_select_region GtkLabel* label gint start_offset gint end_offset") (CFNC "gboolean gtk_label_get_selection_bounds GtkLabel* label gint* [start] gint* [end]") (CFNC "PangoLayout* gtk_label_get_layout GtkLabel* label") (CFNC "void gtk_label_get_layout_offsets GtkLabel* label gint* [x] gint* [y]") (CCAST "GTK_LAYOUT(obj)" "GtkLayout*") (CCHK "GTK_IS_LAYOUT(obj)" "GtkLayout*") ;;;;(CFNC "GType gtk_layout_get_type void") (CFNC "GtkWidget* gtk_layout_new GtkAdjustment* @hadjustment GtkAdjustment* @vadjustment") (CFNC "void gtk_layout_put GtkLayout* layout GtkWidget* child_widget gint x gint y") (CFNC "void gtk_layout_move GtkLayout* layout GtkWidget* child_widget gint x gint y") (CFNC "void gtk_layout_set_size GtkLayout* layout guint width guint height") (CFNC "void gtk_layout_get_size GtkLayout* layout guint* [width] guint* [height]") ;;; 2.91.2 (CFNC "GtkAdjustment* gtk_layout_get_hadjustment GtkLayout* layout") ;;; 2.91.2 (CFNC "GtkAdjustment* gtk_layout_get_vadjustment GtkLayout* layout") ;;; 2.91.2 (CFNC "void gtk_layout_set_hadjustment GtkLayout* layout GtkAdjustment* @adjustment") ;;; 2.91.2 (CFNC "void gtk_layout_set_vadjustment GtkLayout* layout GtkAdjustment* @adjustment") (CCAST "GTK_LIST_STORE(obj)" "GtkListStore*") (CCHK "GTK_IS_LIST_STORE(obj)" "GtkListStore*") ;;;;(CFNC "GType gtk_list_store_get_type void") (CFNC-PA "GtkListStore* gtk_list_store_new gint n_columns etc types" 1 6 '("GType")) (CFNC "GtkListStore* gtk_list_store_newv gint n_columns GType* types") (CFNC "void gtk_list_store_set_column_types GtkListStore* list_store gint n_columns GType* types") ;(CFNC "void gtk_list_store_set_value GtkListStore* list_store GtkTreeIter* iter gint column GValue* value") (CFNC-PA "void gtk_list_store_set GtkListStore* list_store GtkTreeIter* iter etc values" 2 10 '("int" "gchar*")) ; just string values for now ;;; ideally any types here ;;;;(CFNC "void gtk_list_store_set_valist GtkListStore* list_store GtkTreeIter* iter va_list var_args") ;;; (CFNC "void gtk_list_store_remove GtkListStore* list_store GtkTreeIter* iter") ;;; this now returns gboolean! (CFNC "void gtk_list_store_insert GtkListStore* list_store GtkTreeIter* iter gint position") (CFNC "void gtk_list_store_insert_before GtkListStore* list_store GtkTreeIter* iter GtkTreeIter* @sibling") (CFNC "void gtk_list_store_insert_after GtkListStore* list_store GtkTreeIter* iter GtkTreeIter* @sibling") (CFNC "void gtk_list_store_prepend GtkListStore* list_store GtkTreeIter* iter") (CFNC "void gtk_list_store_append GtkListStore* list_store GtkTreeIter* iter") (CFNC "void gtk_list_store_clear GtkListStore* list_store") (CINT "GTK_PRIORITY_RESIZE") (CFNC "gchar* gtk_check_version guint required_major guint required_minor guint required_micro" 'const-return) ;;; (CFNC "void gtk_init int* {argc} char*** |argv|") ;;; (CFNC "gboolean gtk_init_check int* {argc} char*** |argv|") ;;; these two are done by hand in makexg.scm to improve error handling ;(CFNC "void gtk_init_abi_check int* argc char*** argv int num_checks size_t sizeof_GtkWindow") ;(CFNC "gboolean gtk_init_check_abi_check int* argc char*** argv int num_checks size_t sizeof_GtkWindow") (CFNC "void gtk_disable_setlocale void") ;;; (CFNC-gtk2 "gchar* gtk_set_locale void") (CFNC "PangoLanguage* gtk_get_default_language void") (CFNC "gint gtk_events_pending void") (CFNC "void gtk_main_do_event GdkEvent* event") (CFNC "void gtk_main void") (CFNC "guint gtk_main_level void") (CFNC "void gtk_main_quit void") (CFNC "gboolean gtk_main_iteration void") (CFNC "gboolean gtk_main_iteration_do gboolean blocking") (CFNC "gboolean gtk_true void") (CFNC "gboolean gtk_false void") (CFNC "void gtk_grab_add GtkWidget* widget") (CFNC "GtkWidget* gtk_grab_get_current void") (CFNC "void gtk_grab_remove GtkWidget* widget") ;;; 2.91.1 (CFNC "void gtk_init_add GtkFunction func lambda_data #func_info") ;;; 2.91.1 (CFNC "void gtk_quit_add_destroy guint main_level GtkObject* object") ;;; 2.91.1 (CFNC "guint gtk_quit_add guint main_level GtkFunction func lambda_data #func_info") ;;; 2.91.1 (CFNC "guint gtk_quit_add_full guint main_level GtkFunction func GtkCallbackMarshal marshal lambda_data func_info GtkDestroyNotify destroy") ;;; 2.91.1 (CFNC "void gtk_quit_remove guint quit_handler_id") ;;; 2.91.1 (CFNC "void gtk_quit_remove_by_data xen data") ;;; out 2.3 (CFNC "guint gtk_timeout_add guint32 interval GtkTimeoutFunction func lambda_data #func_info") ;;; out 2.3 ;(CFNC "guint gtk_timeout_add_full guint32 interval GtkTimeoutFunction func GtkCallbackMarshal marshal lambda_data func_info GtkDestroyNotify destroy") ;;; out 2.3 (CFNC "void gtk_timeout_remove guint timeout_handler_id") ;;; out 2.3 (CFNC "guint gtk_idle_add GtkFunction func lambda_data #func_info") ;;; out 2.3 (CFNC "guint gtk_idle_add_priority gint priority GtkFunction func lambda_data #func_info") ;;; out 2.3 ;(CFNC "guint gtk_idle_add_full gint priority GtkFunction func GtkCallbackMarshal marshal lambda_data func_info GtkDestroyNotify destroy") ;;; out 2.3 (CFNC "void gtk_idle_remove guint idle_handler_id") ;;; out 2.3 (CFNC "void gtk_idle_remove_by_data xen data") ;;; out 2.3 ;(CFNC "guint gtk_input_add_full gint source GdkInputCondition condition GdkInputFunction func GtkCallbackMarshal marshal lambda_data func_info GtkDestroyNotify destroy") ;;; out 2.3 (CFNC "void gtk_input_remove guint input_handler_id") ;;; 3.3.8 (CFNC "guint gtk_key_snooper_install GtkKeySnoopFunc func lambda_data #func_info") ;;; 3.3.8 (CFNC "void gtk_key_snooper_remove guint snooper_handler_id") (CFNC "GdkEvent* gtk_get_current_event void") (CFNC "guint32 gtk_get_current_event_time void") (CFNC "gboolean gtk_get_current_event_state GdkModifierType* [state]") (CFNC "GtkWidget* gtk_get_event_widget GdkEvent* @event") (CFNC "void gtk_propagate_event GtkWidget* widget GdkEvent* event") (CCAST "GTK_MENU_BAR(obj)" "GtkMenuBar*") (CCHK "GTK_IS_MENU_BAR(obj)" "GtkMenuBar*") ;;;;(CFNC "GType gtk_menu_bar_get_type void") (CFNC "GtkWidget* gtk_menu_bar_new void") (CCAST "GTK_MENU(obj)" "GtkMenu*") (CCHK "GTK_IS_MENU(obj)" "GtkMenu*") ;;;;(CFNC "GType gtk_menu_get_type void") (CFNC "GtkWidget* gtk_menu_new void") (CFNC "void gtk_menu_popup GtkMenu* menu GtkWidget* @parent_menu_shell GtkWidget* @parent_menu_item GtkMenuPositionFunc func lambda_data func_info guint button guint32 activate_time") (CFNC "void gtk_menu_reposition GtkMenu* menu") (CFNC "void gtk_menu_popdown GtkMenu* menu") (CFNC "GtkWidget* gtk_menu_get_active GtkMenu* menu") (CFNC "void gtk_menu_set_active GtkMenu* menu guint index") (CFNC "void gtk_menu_set_accel_group GtkMenu* menu GtkAccelGroup* @accel_group") (CFNC "GtkAccelGroup* gtk_menu_get_accel_group GtkMenu* menu") (CFNC "void gtk_menu_set_accel_path GtkMenu* menu gchar* accel_path") ; 1.3.13 ;;(CFNC "void gtk_menu_attach_to_widget GtkMenu* menu GtkWidget* attach_widget GtkMenuDetachFunc func") ;; see note in makexg.scm -- no user data here, so this requires special handling (CFNC "void gtk_menu_detach GtkMenu* menu") (CFNC "GtkWidget* gtk_menu_get_attach_widget GtkMenu* menu") ;;; 3.3.2 (CFNC "void gtk_menu_set_tearoff_state GtkMenu* menu gboolean torn_off") ;;; 3.3.2 (CFNC "gboolean gtk_menu_get_tearoff_state GtkMenu* menu") ;;; 3.10 (CFNC "void gtk_menu_set_title GtkMenu* menu gchar* title") ;;; 3.10 (CFNC "gchar* gtk_menu_get_title GtkMenu* menu") (CFNC "void gtk_menu_reorder_child GtkMenu* menu GtkWidget* child gint position") (CFNC "void gtk_menu_set_monitor GtkMenu* menu gint monitor_num") (CCAST "GTK_MENU_ITEM(obj)" "GtkMenuItem*") (CCHK "GTK_IS_MENU_ITEM(obj)" "GtkMenuItem*") ;;;;(CFNC "GType gtk_menu_item_get_type void") (CFNC "GtkWidget* gtk_menu_item_new void") (CFNC "GtkWidget* gtk_menu_item_new_with_label gchar* label") ; null -> segfault (CFNC "GtkWidget* gtk_menu_item_new_with_mnemonic gchar* label") (CFNC "void gtk_menu_item_set_submenu GtkMenuItem* menu_item GtkWidget* submenu") (CFNC "GtkWidget* gtk_menu_item_get_submenu GtkMenuItem* menu_item") ;;; (CFNC "void gtk_menu_item_remove_submenu GtkMenuItem* menu_item") ; out 2.11.3 (CFNC "void gtk_menu_item_select GtkMenuItem* menu_item") (CFNC "void gtk_menu_item_deselect GtkMenuItem* menu_item") (CFNC "void gtk_menu_item_activate GtkMenuItem* menu_item") (CFNC "void gtk_menu_item_toggle_size_request GtkMenuItem* menu_item gint* requisition") (CFNC "void gtk_menu_item_toggle_size_allocate GtkMenuItem* menu_item gint allocation") ;;; 3.1.4 (CFNC "void gtk_menu_item_set_right_justified GtkMenuItem* menu_item gboolean right_justified") ;;; 3.1.4 (CFNC "gboolean gtk_menu_item_get_right_justified GtkMenuItem* menu_item") (CFNC "void gtk_menu_item_set_accel_path GtkMenuItem* menu_item gchar* accel_path") (CCAST "GTK_MENU_SHELL(obj)" "GtkMenuShell*") (CCHK "GTK_IS_MENU_SHELL(obj)" "GtkMenuShell*") ;;;;(CFNC "GType gtk_menu_shell_get_type void") (CFNC "void gtk_menu_shell_append GtkMenuShell* menu_shell GtkWidget* child") (CFNC "void gtk_menu_shell_prepend GtkMenuShell* menu_shell GtkWidget* child") (CFNC "void gtk_menu_shell_insert GtkMenuShell* menu_shell GtkWidget* child gint position") (CFNC "void gtk_menu_shell_deactivate GtkMenuShell* menu_shell") (CFNC "void gtk_menu_shell_select_item GtkMenuShell* menu_shell GtkWidget* menu_item") (CFNC "void gtk_menu_shell_deselect GtkMenuShell* menu_shell") (CFNC "void gtk_menu_shell_activate_item GtkMenuShell* menu_shell GtkWidget* menu_item gboolean force_deactivate") (CINT "GTK_MESSAGE_INFO" "GtkMessageType") (CINT "GTK_MESSAGE_WARNING" "GtkMessageType") (CINT "GTK_MESSAGE_QUESTION" "GtkMessageType") (CINT "GTK_MESSAGE_ERROR" "GtkMessageType") (CINT "GTK_BUTTONS_NONE" "GtkButtonsType") (CINT "GTK_BUTTONS_OK" "GtkButtonsType") (CINT "GTK_BUTTONS_CLOSE" "GtkButtonsType") (CINT "GTK_BUTTONS_CANCEL" "GtkButtonsType") (CINT "GTK_BUTTONS_YES_NO" "GtkButtonsType") (CINT "GTK_BUTTONS_OK_CANCEL" "GtkButtonsType") ;(CCAST "GTK_MESSAGE_DIALOG(obj)" "GtkMessageDialog*") ;(CCHK "GTK_IS_MESSAGE_DIALOG(obj)" "GtkMessageDialog*") ;;;;(CFNC "GType gtk_message_dialog_get_type void") ;;;(CFNC "GtkWidget* gtk_message_dialog_new GtkWindow* parent GtkDialogFlags flags GtkMessageType type GtkButtonsType buttons gchar* message_format ...") ;;; the ... arg here would have to be a vnprintf style arg ;;; 3.13.2 (CCAST "GTK_MISC(obj)" "GtkMisc*") ;;; 3.13.2 (CCHK "GTK_IS_MISC(obj)" "GtkMisc*") ;;; 3.13.2 ;;;;(CFNC "GType gtk_misc_get_type void") ;;; 3.13.2 (CFNC "void gtk_misc_set_alignment GtkMisc* misc gfloat xalign gfloat yalign") ;;; 3.13.2 (CFNC "void gtk_misc_get_alignment GtkMisc* misc gfloat* [xalign] gfloat* [yalign]") ;;; 3.13.2 (CFNC "void gtk_misc_set_padding GtkMisc* misc gint xpad gint ypad") ;;; 3.13.2 (CFNC "void gtk_misc_get_padding GtkMisc* misc gint* [xpad] gint* [ypad]") (CCAST "GTK_NOTEBOOK(obj)" "GtkNotebook*") (CCHK "GTK_IS_NOTEBOOK(obj)" "GtkNotebook*") (CINT "GTK_NOTEBOOK_TAB_FIRST" "GtkNotebookTab") (CINT "GTK_NOTEBOOK_TAB_LAST" "GtkNotebookTab") ;;;;(CFNC "GType gtk_notebook_get_type void") (CFNC "GtkWidget* gtk_notebook_new void") (CFNC "void gtk_notebook_remove_page GtkNotebook* notebook gint page_num") (CFNC "gint gtk_notebook_get_current_page GtkNotebook* notebook") (CFNC "GtkWidget* gtk_notebook_get_nth_page GtkNotebook* notebook gint page_num") (CFNC "gint gtk_notebook_page_num GtkNotebook* notebook GtkWidget* child") (CFNC "void gtk_notebook_set_current_page GtkNotebook* notebook gint page_num") (CFNC "void gtk_notebook_next_page GtkNotebook* notebook") (CFNC "void gtk_notebook_prev_page GtkNotebook* notebook") (CFNC "void gtk_notebook_set_show_border GtkNotebook* notebook gboolean show_border") (CFNC "gboolean gtk_notebook_get_show_border GtkNotebook* notebook") (CFNC "void gtk_notebook_set_show_tabs GtkNotebook* notebook gboolean show_tabs") (CFNC "gboolean gtk_notebook_get_show_tabs GtkNotebook* notebook") (CFNC "void gtk_notebook_set_tab_pos GtkNotebook* notebook GtkPositionType pos") (CFNC "GtkPositionType gtk_notebook_get_tab_pos GtkNotebook* notebook") (CFNC "void gtk_notebook_set_scrollable GtkNotebook* notebook gboolean scrollable") (CFNC "gboolean gtk_notebook_get_scrollable GtkNotebook* notebook") (CFNC "void gtk_notebook_popup_enable GtkNotebook* notebook") (CFNC "void gtk_notebook_popup_disable GtkNotebook* notebook") (CFNC "GtkWidget* gtk_notebook_get_tab_label GtkNotebook* notebook GtkWidget* child") (CFNC "void gtk_notebook_set_tab_label GtkNotebook* notebook GtkWidget* child GtkWidget* @tab_label") (CFNC "void gtk_notebook_set_tab_label_text GtkNotebook* notebook GtkWidget* child gchar* tab_text") (CFNC "gchar* gtk_notebook_get_tab_label_text GtkNotebook* notebook GtkWidget* child") (CFNC "GtkWidget* gtk_notebook_get_menu_label GtkNotebook* notebook GtkWidget* child") (CFNC "void gtk_notebook_set_menu_label GtkNotebook* notebook GtkWidget* child GtkWidget* menu_label") (CFNC "void gtk_notebook_set_menu_label_text GtkNotebook* notebook GtkWidget* child gchar* menu_text") (CFNC "gchar* gtk_notebook_get_menu_label_text GtkNotebook* notebook GtkWidget* child") ;;; out 2.19.0 (CFNC "void gtk_notebook_query_tab_label_packing GtkNotebook* notebook GtkWidget* child gboolean* [expand] gboolean* [fill] GtkPackType* [pack_type]") ;;; (CFNC "void gtk_notebook_set_tab_label_packing GtkNotebook* notebook GtkWidget* child gboolean expand gboolean fill GtkPackType pack_type") (CFNC "void gtk_notebook_reorder_child GtkNotebook* notebook GtkWidget* child gint position") ;;; the following changed returned type 2.3.2 (CFNC "gint gtk_notebook_append_page GtkNotebook* notebook GtkWidget* child GtkWidget* @tab_label") (CFNC "gint gtk_notebook_append_page_menu GtkNotebook* notebook GtkWidget* child GtkWidget* @tab_label GtkWidget* @menu_label") (CFNC "gint gtk_notebook_prepend_page GtkNotebook* notebook GtkWidget* child GtkWidget* @tab_label") (CFNC "gint gtk_notebook_prepend_page_menu GtkNotebook* notebook GtkWidget* child GtkWidget* @tab_label GtkWidget* @menu_label") (CFNC "gint gtk_notebook_insert_page GtkNotebook* notebook GtkWidget* child GtkWidget* @tab_label gint position") (CFNC "gint gtk_notebook_insert_page_menu GtkNotebook* notebook GtkWidget* child GtkWidget* @tab_label GtkWidget* @menu_label gint position") ;;; 2.91.0 (CCAST "GTK_OBJECT(object)" "GtkObject*") ;;; 2.91.0 (CCHK "GTK_IS_OBJECT(object)" "GtkObject*") ;;; (CCAST-gtk2 "GTK_OBJECT(object)" "GtkObject*") ;;; (CCHK-gtk2 "GTK_IS_OBJECT(object)" "GtkObject*") ;;; 2.91.0 ;(CCAST2 "GTK_OBJECT_TYPE(object)") ;;; 2.19.3 (CFNC "char* GTK_OBJECT_TYPE_NAME GtkObject* object") ;;;(CINT "GTK_IN_DESTRUCTION") ; out 2.90.3 ;(CINT "GTK_FLOATING") ; out 2.9.0 ;(CINT "GTK_RESERVED_1") ;(CINT "GTK_RESERVED_2") ;;;(CFNC "int GTK_OBJECT_FLAGS GtkObject* obj") ; 2.90.3 ;(CFNC "gboolean GTK_OBJECT_FLOATING GtkObject* obj") ; out 2.9.0 ;;;(CFNC "void GTK_OBJECT_SET_FLAGS GtkObject* obj int flag") ;;;(CFNC "void GTK_OBJECT_UNSET_FLAGS GtkObject* obj int flag") ;;;;(CFNC "GType gtk_object_get_type void") ;;; out 2.3 (CFNC "GtkObject* gtk_object_new GType type gchar* first_property_name etc") ;;; out 2.9.0 (CFNC "void gtk_object_sink GtkObject* object") ;;; 2.91.0 (CFNC "void gtk_object_destroy GtkObject* object") ;;; out 2.3 (CCAST "GTK_OPTION_MENU(obj)" "GtkOptionMenu*") ;;; out 2.3 (CCHK "GTK_IS_OPTION_MENU(obj)" "GtkOptionMenu*") ;;;;;;; out 2.3 (CFNC "GType gtk_option_menu_get_type void") ;;; out 2.3 (CFNC "GtkWidget* gtk_option_menu_new void") ;;; out 2.3 (CFNC "GtkWidget* gtk_option_menu_get_menu GtkOptionMenu* option_menu") ;;; out 2.3 (CFNC "void gtk_option_menu_set_menu GtkOptionMenu* option_menu GtkWidget* menu") ;;; out 2.3 (CFNC "void gtk_option_menu_remove_menu GtkOptionMenu* option_menu") ;;; out 2.3 (CFNC "gint gtk_option_menu_get_history GtkOptionMenu* option_menu") ;;; out 2.3 (CFNC "void gtk_option_menu_set_history GtkOptionMenu* option_menu guint index") (CCAST "GTK_PANED(obj)" "GtkPaned*") (CCHK "GTK_IS_PANED(obj)" "GtkPaned*") ;;;;(CFNC "GType gtk_paned_get_type void") (CFNC "void gtk_paned_add1 GtkPaned* paned GtkWidget* child") (CFNC "void gtk_paned_add2 GtkPaned* paned GtkWidget* child") (CFNC "void gtk_paned_pack1 GtkPaned* paned GtkWidget* child gboolean resize gboolean shrink") (CFNC "void gtk_paned_pack2 GtkPaned* paned GtkWidget* child gboolean resize gboolean shrink") (CFNC "gint gtk_paned_get_position GtkPaned* paned") (CFNC "void gtk_paned_set_position GtkPaned* paned gint position") ;;; out 2.3 (CFNC "void gtk_paned_compute_position GtkPaned* paned gint allocation gint child1_req gint child2_req") ;;; 2.99.3 (CCAST "GTK_PLUG(obj)" "GtkPlug*") ;;; 2.99.3 (CCHK "GTK_IS_PLUG(obj)" "GtkPlug*") ;;;;(CFNC "GType gtk_plug_get_type void") ;;; 2.99.3 (CFNC "void gtk_plug_construct GtkPlug* plug GdkNativeWindow socket_id") ;;; 2.99.3 (CFNC "GtkWidget* gtk_plug_new GdkNativeWindow socket_id") ;;; 2.99.3 (CFNC "GdkNativeWindow gtk_plug_get_id GtkPlug* plug") (CCAST "GTK_PROGRESS_BAR(obj)" "GtkProgressBar*") (CCHK "GTK_IS_PROGRESS_BAR(obj)" "GtkProgressBar*") ;(CINT "GTK_PROGRESS_CONTINUOUS" "GtkProgressBarStyle") ;(CINT "GTK_PROGRESS_DISCRETE" "GtkProgressBarStyle") ;deprecated 2.4 ; out 2.90.7 ;(CINT "GTK_PROGRESS_LEFT_TO_RIGHT" "GtkProgressBarOrientation") ;(CINT "GTK_PROGRESS_RIGHT_TO_LEFT" "GtkProgressBarOrientation") ;(CINT "GTK_PROGRESS_BOTTOM_TO_TOP" "GtkProgressBarOrientation") ;(CINT "GTK_PROGRESS_TOP_TO_BOTTOM" "GtkProgressBarOrientation") ;;;;(CFNC "GType gtk_progress_bar_get_type void") (CFNC "GtkWidget* gtk_progress_bar_new void") (CFNC "void gtk_progress_bar_pulse GtkProgressBar* pbar") (CFNC "void gtk_progress_bar_set_text GtkProgressBar* pbar gchar* text") (CFNC "void gtk_progress_bar_set_fraction GtkProgressBar* pbar gdouble fraction") (CFNC "void gtk_progress_bar_set_pulse_step GtkProgressBar* pbar gdouble fraction") ;;; 2.90.7 (CFNC "void gtk_progress_bar_set_orientation GtkProgressBar* pbar GtkProgressBarOrientation orientation") (CFNC "gchar* gtk_progress_bar_get_text GtkProgressBar* pbar") (CFNC "gdouble gtk_progress_bar_get_fraction GtkProgressBar* pbar") (CFNC "gdouble gtk_progress_bar_get_pulse_step GtkProgressBar* pbar") ;;; 2.90.7 (CFNC "GtkProgressBarOrientation gtk_progress_bar_get_orientation GtkProgressBar* pbar") (CCAST "GTK_RADIO_BUTTON(obj)" "GtkRadioButton*") (CCHK "GTK_IS_RADIO_BUTTON(obj)" "GtkRadioButton*") ;;;;(CFNC "GType gtk_radio_button_get_type void") (CFNC "GtkWidget* gtk_radio_button_new GSList* @group") (CFNC "GtkWidget* gtk_radio_button_new_from_widget GtkRadioButton* group") (CFNC "GtkWidget* gtk_radio_button_new_with_label GSList* @group gchar* label") (CFNC "GtkWidget* gtk_radio_button_new_with_label_from_widget GtkRadioButton* group gchar* label") (CFNC "GtkWidget* gtk_radio_button_new_with_mnemonic GSList* @group gchar* label") (CFNC "GtkWidget* gtk_radio_button_new_with_mnemonic_from_widget GtkRadioButton* group gchar* label") (CFNC "GSList* gtk_radio_button_get_group GtkRadioButton* radio_button") (CFNC "void gtk_radio_button_set_group GtkRadioButton* radio_button GSList* @group") (CCAST "GTK_RADIO_MENU_ITEM(obj)" "GtkRadioMenuItem*") (CCHK "GTK_IS_RADIO_MENU_ITEM(obj)" "GtkRadioMenuItem*") ;;;;(CFNC "GType gtk_radio_menu_item_get_type void") (CFNC "GtkWidget* gtk_radio_menu_item_new GSList* @group") (CFNC "GtkWidget* gtk_radio_menu_item_new_with_label GSList* @group gchar* label") (CFNC "GtkWidget* gtk_radio_menu_item_new_with_mnemonic GSList* @group gchar* label") (CFNC "GSList* gtk_radio_menu_item_get_group GtkRadioMenuItem* radio_menu_item") (CFNC "void gtk_radio_menu_item_set_group GtkRadioMenuItem* radio_menu_item GSList* @group") (CCAST "GTK_RANGE(obj)" "GtkRange*") (CCHK "GTK_IS_RANGE(obj)" "GtkRange*") ;;;;(CFNC "GType gtk_range_get_type void") (CFNC "void gtk_range_set_adjustment GtkRange* range GtkAdjustment* @adjustment") (CFNC "GtkAdjustment* gtk_range_get_adjustment GtkRange* range") (CFNC "void gtk_range_set_inverted GtkRange* range gboolean setting") (CFNC "gboolean gtk_range_get_inverted GtkRange* range") (CFNC "void gtk_range_set_increments GtkRange* range gdouble step gdouble page") (CFNC "void gtk_range_set_range GtkRange* range gdouble min gdouble max") (CFNC "void gtk_range_set_value GtkRange* range gdouble value") (CFNC "gdouble gtk_range_get_value GtkRange* range") ;;; (CFNC-gtk2 "void gtk_range_set_update_policy GtkRange* range GtkUpdateType policy") ;;; (CFNC-gtk2 "GtkUpdateType gtk_range_get_update_policy GtkRange* range") ;(CINT "GTK_RBNODE_BLACK") ;(CINT "GTK_RBNODE_RED") ;(CINT "GTK_RBNODE_IS_PARENT") ;(CINT "GTK_RBNODE_IS_SELECTED") ;(CINT "GTK_RBNODE_IS_PRELIT") ;(CINT "GTK_RBNODE_IS_SEMI_COLLAPSED") ;(CINT "GTK_RBNODE_IS_SEMI_EXPANDED") ;(CINT "GTK_RBNODE_INVALID") ;(CINT "GTK_RBNODE_COLUMN_INVALID") ;(CINT "GTK_RBNODE_DESCENDANTS_INVALID") ;(CINT "GTK_RBNODE_NON_COLORS") ;(CCAST2 "GTK_RBNODE_GET_COLOR(node)") ;(CCAST4 "GTK_RBNODE_SET_COLOR(node color)") ;(CCAST2 "GTK_RBNODE_GET_HEIGHT(node)") ;(CCAST2 "GTK_RBNODE_SET_FLAG(node") ;(CCAST2 "GTK_RBNODE_UNSET_FLAG(node") ;(CCAST2 "GTK_RBNODE_FLAG_SET(node") ;;; (CCAST "GTK_RC_STYLE(object)" "GtkRcStyle*") ;;; this collides with GTK_RC_STYLE defined in gtkwidget.h! ;;; (CCHK-gtk2 "GTK_IS_RC_STYLE(object)" "GtkRcStyle*") ;;; (CINT-gtk2 "GTK_RC_FG") ;;; (CINT-gtk2 "GTK_RC_BG") ;;; (CINT-gtk2 "GTK_RC_TEXT") ;;; (CINT-gtk2 "GTK_RC_BASE") ;;; (CFNC-gtk2 "void gtk_rc_add_default_file gchar* filename") ;;; (CFNC-gtk2 "void gtk_rc_set_default_files gchar** filenames") ;;; (CFNC-gtk2 "gchar** gtk_rc_get_default_files void") ;;; (CFNC-gtk2 "GtkStyle* gtk_rc_get_style GtkWidget* widget") ;(CFNC "GtkStyle* gtk_rc_get_style_by_paths GtkSettings* settings char* widget_path char* class_path GType type") ;(CFNC "gboolean gtk_rc_reparse_all_for_settings GtkSettings* settings gboolean force_load") ;(CFNC "gchar* gtk_rc_find_pixmap_in_path GtkSettings* settings GScanner* @scanner gchar* pixmap_file") ;;; (CFNC-gtk2 "void gtk_rc_parse gchar* filename") ;;; (CFNC-gtk2 "void gtk_rc_parse_string gchar* rc_string") ;;; (CFNC-gtk2 "gboolean gtk_rc_reparse_all void") ;;; ;;;;(CFNC-gtk2 "GType gtk_rc_style_get_type void") ;;; (CFNC-gtk2 "GtkRcStyle* gtk_rc_style_new void") ;;; (CFNC-gtk2 "GtkRcStyle* gtk_rc_style_copy GtkRcStyle* orig") ;;; ;;;-gtk2 (CFNC "void gtk_rc_style_ref GtkRcStyle* rc_style") ; out 2.11.0 ;;; ;;;-gtk2 (CFNC "void gtk_rc_style_unref GtkRcStyle* rc_style") ;;; (CFNC-gtk2 "gchar* gtk_rc_find_module_in_path gchar* module_file" 'free) ;;; (CFNC-gtk2 "gchar* gtk_rc_get_theme_dir void" 'free) ;;; (CFNC-gtk2 "gchar* gtk_rc_get_module_dir void" 'free) ;;; (CFNC-gtk2 "gchar* gtk_rc_get_im_module_path void" 'free) ;;; (CFNC-gtk2 "gchar* gtk_rc_get_im_module_file void" 'free) ;; these are for "theme engines" -- I can't see any use for them in this context (deprecated 2.91.6) ;(CINT "GTK_RC_TOKEN_INVALID" "GtkRcTokenType") ;(CINT "GTK_RC_TOKEN_INCLUDE" "GtkRcTokenType") ;(CINT "GTK_RC_TOKEN_NORMAL" "GtkRcTokenType") ;(CINT "GTK_RC_TOKEN_ACTIVE" "GtkRcTokenType") ;(CINT "GTK_RC_TOKEN_PRELIGHT" "GtkRcTokenType") ;(CINT "GTK_RC_TOKEN_SELECTED" "GtkRcTokenType") ;(CINT "GTK_RC_TOKEN_INSENSITIVE" "GtkRcTokenType") ;(CINT "GTK_RC_TOKEN_FG" "GtkRcTokenType") ;(CINT "GTK_RC_TOKEN_BG" "GtkRcTokenType") ;(CINT "GTK_RC_TOKEN_TEXT" "GtkRcTokenType") ;(CINT "GTK_RC_TOKEN_BASE" "GtkRcTokenType") ;(CINT "GTK_RC_TOKEN_XTHICKNESS" "GtkRcTokenType") ;(CINT "GTK_RC_TOKEN_YTHICKNESS" "GtkRcTokenType") ;(CINT "GTK_RC_TOKEN_FONT" "GtkRcTokenType") ;(CINT "GTK_RC_TOKEN_FONTSET" "GtkRcTokenType") ;(CINT "GTK_RC_TOKEN_FONT_NAME" "GtkRcTokenType") ;(CINT "GTK_RC_TOKEN_BG_PIXMAP" "GtkRcTokenType") ;(CINT "GTK_RC_TOKEN_PIXMAP_PATH" "GtkRcTokenType") ;(CINT "GTK_RC_TOKEN_STYLE" "GtkRcTokenType") ;(CINT "GTK_RC_TOKEN_BINDING" "GtkRcTokenType") ;(CINT "GTK_RC_TOKEN_BIND" "GtkRcTokenType") ;(CINT "GTK_RC_TOKEN_WIDGET" "GtkRcTokenType") ;(CINT "GTK_RC_TOKEN_WIDGET_CLASS" "GtkRcTokenType") ;(CINT "GTK_RC_TOKEN_CLASS" "GtkRcTokenType") ;(CINT "GTK_RC_TOKEN_LOWEST" "GtkRcTokenType") ;(CINT "GTK_RC_TOKEN_GTK" "GtkRcTokenType") ;(CINT "GTK_RC_TOKEN_APPLICATION" "GtkRcTokenType") ;(CINT "GTK_RC_TOKEN_THEME" "GtkRcTokenType") ;(CINT "GTK_RC_TOKEN_RC" "GtkRcTokenType") ;(CINT "GTK_RC_TOKEN_HIGHEST" "GtkRcTokenType") ;(CINT "GTK_RC_TOKEN_ENGINE" "GtkRcTokenType") ;(CINT "GTK_RC_TOKEN_MODULE_PATH" "GtkRcTokenType") ;(CINT "GTK_RC_TOKEN_IM_MODULE_PATH" "GtkRcTokenType") ;(CINT "GTK_RC_TOKEN_IM_MODULE_FILE" "GtkRcTokenType") ;(CINT "GTK_RC_TOKEN_STOCK" "GtkRcTokenType") ;(CINT "GTK_RC_TOKEN_LTR" "GtkRcTokenType") ;(CINT "GTK_RC_TOKEN_RTL" "GtkRcTokenType") ;(CINT "GTK_RC_TOKEN_LAST" "GtkRcTokenType") ;(CFNC "GScanner* gtk_rc_scanner_new void") ;(CFNC "guint gtk_rc_parse_color GScanner* scanner GdkColor* color") ;(CFNC "guint gtk_rc_parse_state GScanner* scanner GtkStateType* [state]") ;(CFNC "guint gtk_rc_parse_priority GScanner* scanner GtkPathPriorityType* [priority]") ;(CFNC "gchar* gtk_win32_get_installation_directory void") ;;; 2.91.5 (CCAST "GTK_RULER(obj)" "GtkRuler*") ;;; 2.91.5 (CCHK "GTK_IS_RULER(obj)" "GtkRuler*") ;;;;(CFNC "GType gtk_ruler_get_type void") ;;; 2.91.5 (CFNC "void gtk_ruler_set_metric GtkRuler* ruler GtkMetricType metric") ;;; 2.91.5 (CFNC "void gtk_ruler_set_range GtkRuler* ruler gdouble lower gdouble upper gdouble position gdouble max_size") ;;; ;;; 2.91.5 (CFNC-gtk2 "void gtk_ruler_draw_ticks GtkRuler* ruler") ;;; ;;; 2.91.5 (CFNC-gtk2 "void gtk_ruler_draw_pos GtkRuler* ruler") ;;; 2.91.5 (CFNC "GtkMetricType gtk_ruler_get_metric GtkRuler* ruler") ;;; 2.91.5 (CFNC "void gtk_ruler_get_range GtkRuler* ruler gdouble* [lower] gdouble* [upper] gdouble* [position] gdouble* [max_size]") (CCAST "GTK_SCALE(obj)" "GtkScale*") (CCHK "GTK_IS_SCALE(obj)" "GtkScale*") ;;;;(CFNC "GType gtk_scale_get_type void") (CFNC "void gtk_scale_set_digits GtkScale* scale gint digits") (CFNC "gint gtk_scale_get_digits GtkScale* scale") (CFNC "void gtk_scale_set_draw_value GtkScale* scale gboolean draw_value") (CFNC "gboolean gtk_scale_get_draw_value GtkScale* scale") (CFNC "void gtk_scale_set_value_pos GtkScale* scale GtkPositionType pos") (CFNC "GtkPositionType gtk_scale_get_value_pos GtkScale* scale") (CCAST "GTK_SCROLLBAR(obj)" "GtkScrollbar*") (CCHK "GTK_IS_SCROLLBAR(obj)" "GtkScrollbar*") ;;;;(CFNC "GType gtk_scrollbar_get_type void") (CCAST "GTK_SCROLLED_WINDOW(obj)" "GtkScrolledWindow*") (CCHK "GTK_IS_SCROLLED_WINDOW(obj)" "GtkScrolledWindow*") ;;;;(CFNC "GType gtk_scrolled_window_get_type void") (CFNC "GtkWidget* gtk_scrolled_window_new GtkAdjustment* @hadjustment GtkAdjustment* @vadjustment") (CFNC "void gtk_scrolled_window_set_hadjustment GtkScrolledWindow* scrolled_window GtkAdjustment* @hadjustment") (CFNC "void gtk_scrolled_window_set_vadjustment GtkScrolledWindow* scrolled_window GtkAdjustment* @hadjustment") (CFNC "GtkAdjustment* gtk_scrolled_window_get_hadjustment GtkScrolledWindow* scrolled_window") (CFNC "GtkAdjustment* gtk_scrolled_window_get_vadjustment GtkScrolledWindow* scrolled_window") (CFNC "void gtk_scrolled_window_set_policy GtkScrolledWindow* scrolled_window GtkPolicyType hscrollbar_policy GtkPolicyType vscrollbar_policy") (CFNC "void gtk_scrolled_window_get_policy GtkScrolledWindow* scrolled_window GtkPolicyType* [hscrollbar_policy] GtkPolicyType* [vscrollbar_policy]") (CFNC "void gtk_scrolled_window_set_placement GtkScrolledWindow* scrolled_window GtkCornerType window_placement") (CFNC "GtkCornerType gtk_scrolled_window_get_placement GtkScrolledWindow* scrolled_window") (CFNC "void gtk_scrolled_window_set_shadow_type GtkScrolledWindow* scrolled_window GtkShadowType type") (CFNC "GtkShadowType gtk_scrolled_window_get_shadow_type GtkScrolledWindow* scrolled_window") ;;; 3.8 (CFNC "void gtk_scrolled_window_add_with_viewport GtkScrolledWindow* scrolled_window GtkWidget* child") (CFNC "GtkTargetList* gtk_target_list_new GtkTargetEntry* @targets guint ntargets") ;;; return type changed 290 ;;;(CFNC "void gtk_target_list_ref GtkTargetList* list") (CFNC "void gtk_target_list_unref GtkTargetList* list") (CFNC "void gtk_target_list_add GtkTargetList* list GdkAtom target guint flags guint info") (CFNC "void gtk_target_list_add_table GtkTargetList* list GtkTargetEntry* targets guint ntargets") (CFNC "void gtk_target_list_remove GtkTargetList* list GdkAtom target") (CFNC "gboolean gtk_target_list_find GtkTargetList* list GdkAtom target guint* [info]") (CFNC "gboolean gtk_selection_owner_set GtkWidget* @widget GdkAtom selection guint32 time") (CFNC "void gtk_selection_add_target GtkWidget* widget GdkAtom selection GdkAtom target guint info") (CFNC "void gtk_selection_add_targets GtkWidget* widget GdkAtom selection GtkTargetEntry* targets guint ntargets") (CFNC "void gtk_selection_clear_targets GtkWidget* widget GdkAtom selection") (CFNC "gboolean gtk_selection_convert GtkWidget* widget GdkAtom selection GdkAtom target guint32 time") (CFNC "void gtk_selection_data_set GtkSelectionData* selection_data GdkAtom type gint format guchar* data gint length") (CFNC "gboolean gtk_selection_data_set_text GtkSelectionData* selection_data gchar* str gint len") (CFNC "guchar* gtk_selection_data_get_text GtkSelectionData* selection_data" 'free) (CFNC "gboolean gtk_selection_data_get_targets GtkSelectionData* selection_data GdkAtom** [targets] gint* [n_atoms]") ; FREE (targets) (CFNC "gboolean gtk_selection_data_targets_include_text GtkSelectionData* selection_data") (CFNC "void gtk_selection_remove_all GtkWidget* widget") ;;; out 2.3 (CFNC "gboolean gtk_selection_clear GtkWidget* widget GdkEventSelection* event") ;;; removed 2.1 (CFNC "gboolean gtk_selection_request GtkWidget* widget GdkEventSelection* event") ;;; removed 2.1 (CFNC "gboolean gtk_selection_incr_event GdkWindow* window GdkEventProperty* event") ;;; removed 2.1 (CFNC "gboolean gtk_selection_notify GtkWidget* widget GdkEventSelection* event") ;;; removed 2.1 (CFNC "gboolean gtk_selection_property_notify GtkWidget* widget GdkEventProperty* event") (CFNC "GtkSelectionData* gtk_selection_data_copy GtkSelectionData* data") (CFNC "void gtk_selection_data_free GtkSelectionData* data") (CCAST "GTK_SEPARATOR(obj)" "GtkSeparator*") (CCHK "GTK_IS_SEPARATOR(obj)" "GtkSeparator*") ;;;;(CFNC "GType gtk_separator_get_type void") (CCAST "GTK_SEPARATOR_MENU_ITEM(obj)" "GtkSeparatorMenuItem*") (CCHK "GTK_IS_SEPARATOR_MENU_ITEM(obj)" "GtkSeparatorMenuItem*") ;;;;(CFNC "GType gtk_separator_menu_item_get_type void") (CFNC "GtkWidget* gtk_separator_menu_item_new void") (CCAST "GTK_SETTINGS(obj)" "GtkSettings*") (CCHK "GTK_IS_SETTINGS(obj)" "GtkSettings*") ;;;;;(CFNC "GType gtk_settings_get_type void") (CFNC "GtkSettings* gtk_settings_get_default void") ;(CFNC "void gtk_settings_install_property GParamSpec* pspec") ;(CFNC "void gtk_settings_install_property_parser GParamSpec* pspec GtkRcPropertyParser parser") ;(CFNC "gboolean gtk_rc_property_parse_color GParamSpec* pspec GString* gstring GValue* property_value") ;(CFNC "gboolean gtk_rc_property_parse_enum GParamSpec* pspec GString* gstring GValue* property_value") ;(CFNC "gboolean gtk_rc_property_parse_flags GParamSpec* pspec GString* gstring GValue* property_value") ;(CFNC "gboolean gtk_rc_property_parse_requisition GParamSpec* pspec GString* gstring GValue* property_value") ;(CFNC "gboolean gtk_rc_property_parse_border GParamSpec* pspec GString* gstring GValue* property_value") ;(CFNC "void gtk_settings_set_property_value GtkSettings* settings gchar* name GtkSettingsValue* svalue") ;(CFNC "void gtk_settings_set_string_property GtkSettings* settings gchar* name gchar* v_string gchar* origin") ;(CFNC "void gtk_settings_set_long_property GtkSettings* settings gchar* name glong v_long gchar* origin") ;(CFNC "void gtk_settings_set_double_property GtkSettings* settings gchar* name gdouble v_double gchar* origin") (CCAST "GTK_SIZE_GROUP(obj)" "GtkSizeGroup*") (CCHK "GTK_IS_SIZE_GROUP(obj)" "GtkSizeGroup*") (CINT "GTK_SIZE_GROUP_NONE" "GtkSizeGroupMode") (CINT "GTK_SIZE_GROUP_HORIZONTAL" "GtkSizeGroupMode") (CINT "GTK_SIZE_GROUP_VERTICAL" "GtkSizeGroupMode") (CINT "GTK_SIZE_GROUP_BOTH" "GtkSizeGroupMode") ;;;;(CFNC "GType gtk_size_group_get_type void") (CFNC "GtkSizeGroup* gtk_size_group_new GtkSizeGroupMode mode") (CFNC "void gtk_size_group_set_mode GtkSizeGroup* size_group GtkSizeGroupMode mode") (CFNC "GtkSizeGroupMode gtk_size_group_get_mode GtkSizeGroup* size_group") (CFNC "void gtk_size_group_add_widget GtkSizeGroup* size_group GtkWidget* widget") (CFNC "void gtk_size_group_remove_widget GtkSizeGroup* size_group GtkWidget* widget") ;;; 2.99.3 (CCAST "GTK_SOCKET(obj)" "GtkSocket*") ;;; 2.99.3 (CCHK "GTK_IS_SOCKET(obj)" "GtkSocket*") ;;; 2.99.3 (CFNC "GtkWidget* gtk_socket_new void") ;;; 2.99.3 ;;;;(CFNC "GType gtk_socket_get_type void") ;;; 2.99.3 (CFNC "void gtk_socket_add_id GtkSocket* socket GdkNativeWindow window_id") ;;; 2.99.3 (CFNC "GdkNativeWindow gtk_socket_get_id GtkSocket* socket") (CCAST "GTK_SPIN_BUTTON(obj)" "GtkSpinButton*") (CCHK "GTK_IS_SPIN_BUTTON(obj)" "GtkSpinButton*") (CINT "GTK_INPUT_ERROR") (CINT "GTK_UPDATE_ALWAYS" "GtkSpinButtonUpdatePolicy") (CINT "GTK_UPDATE_IF_VALID" "GtkSpinButtonUpdatePolicy") (CINT "GTK_SPIN_STEP_FORWARD" "GtkSpinType") (CINT "GTK_SPIN_STEP_BACKWARD" "GtkSpinType") (CINT "GTK_SPIN_PAGE_FORWARD" "GtkSpinType") (CINT "GTK_SPIN_PAGE_BACKWARD" "GtkSpinType") (CINT "GTK_SPIN_HOME" "GtkSpinType") (CINT "GTK_SPIN_END" "GtkSpinType") (CINT "GTK_SPIN_USER_DEFINED") ;;;;(CFNC "GType gtk_spin_button_get_type void") (CFNC "void gtk_spin_button_configure GtkSpinButton* spin_button GtkAdjustment* @adjustment gdouble climb_rate guint digits") (CFNC "GtkWidget* gtk_spin_button_new GtkAdjustment* @adjustment gdouble climb_rate guint digits") (CFNC "GtkWidget* gtk_spin_button_new_with_range gdouble min gdouble max gdouble step") (CFNC "void gtk_spin_button_set_adjustment GtkSpinButton* spin_button GtkAdjustment* @adjustment") (CFNC "GtkAdjustment* gtk_spin_button_get_adjustment GtkSpinButton* spin_button") (CFNC "void gtk_spin_button_set_digits GtkSpinButton* spin_button guint digits") (CFNC "guint gtk_spin_button_get_digits GtkSpinButton* spin_button") (CFNC "void gtk_spin_button_set_increments GtkSpinButton* spin_button gdouble step gdouble page") (CFNC "void gtk_spin_button_get_increments GtkSpinButton* spin_button gdouble* [step] gdouble* [page]") (CFNC "void gtk_spin_button_set_range GtkSpinButton* spin_button gdouble min gdouble max") (CFNC "void gtk_spin_button_get_range GtkSpinButton* spin_button gdouble* [min] gdouble* [max]") (CFNC "gdouble gtk_spin_button_get_value GtkSpinButton* spin_button") (CFNC "gint gtk_spin_button_get_value_as_int GtkSpinButton* spin_button") (CFNC "void gtk_spin_button_set_value GtkSpinButton* spin_button gdouble value") (CFNC "void gtk_spin_button_set_update_policy GtkSpinButton* spin_button GtkSpinButtonUpdatePolicy policy") (CFNC "GtkSpinButtonUpdatePolicy gtk_spin_button_get_update_policy GtkSpinButton* spin_button") (CFNC "void gtk_spin_button_set_numeric GtkSpinButton* spin_button gboolean numeric") (CFNC "gboolean gtk_spin_button_get_numeric GtkSpinButton* spin_button") (CFNC "void gtk_spin_button_spin GtkSpinButton* spin_button GtkSpinType direction gdouble increment") (CFNC "void gtk_spin_button_set_wrap GtkSpinButton* spin_button gboolean wrap") (CFNC "gboolean gtk_spin_button_get_wrap GtkSpinButton* spin_button") (CFNC "void gtk_spin_button_set_snap_to_ticks GtkSpinButton* spin_button gboolean snap_to_ticks") (CFNC "gboolean gtk_spin_button_get_snap_to_ticks GtkSpinButton* spin_button") (CFNC "void gtk_spin_button_update GtkSpinButton* spin_button") (CCAST "GTK_STATUSBAR(obj)" "GtkStatusbar*") (CCHK "GTK_IS_STATUSBAR(obj)" "GtkStatusbar*") ;;;;(CFNC "GType gtk_statusbar_get_type void") (CFNC "GtkWidget* gtk_statusbar_new void") (CFNC "guint gtk_statusbar_get_context_id GtkStatusbar* statusbar gchar* context_description") (CFNC "guint gtk_statusbar_push GtkStatusbar* statusbar guint context_id gchar* text") (CFNC "void gtk_statusbar_pop GtkStatusbar* statusbar guint context_id") (CFNC "void gtk_statusbar_remove GtkStatusbar* statusbar guint context_id guint message_id") ;;; 2.91.1 (CFNC "void gtk_statusbar_set_has_resize_grip GtkStatusbar* statusbar gboolean setting") ;;; 2.91.1 (CFNC "gboolean gtk_statusbar_get_has_resize_grip GtkStatusbar* statusbar") ;;; all out 3.9.8 ;;; (CFNC "void gtk_stock_add GtkStockItem* items guint n_items") ;;; (CFNC "void gtk_stock_add_static GtkStockItem* items guint n_items") ;;; (CFNC "gboolean gtk_stock_lookup gchar* stock_id GtkStockItem* item") ;;; (CFNC "GSList* gtk_stock_list_ids void") ;;; (CFNC "GtkStockItem* gtk_stock_item_copy GtkStockItem* item") ;;; (CFNC "void gtk_stock_item_free GtkStockItem* item") ;;; (CSTR "GTK_STOCK_DIALOG_INFO") ;;; (CSTR "GTK_STOCK_DIALOG_WARNING") ;;; (CSTR "GTK_STOCK_DIALOG_ERROR") ;;; (CSTR "GTK_STOCK_DIALOG_QUESTION") ;;; (CSTR "GTK_STOCK_DND") ;;; (CSTR "GTK_STOCK_DND_MULTIPLE") ;;; (CSTR "GTK_STOCK_ADD") ;;; (CSTR "GTK_STOCK_APPLY") ;;; (CSTR "GTK_STOCK_BOLD") ;;; (CSTR "GTK_STOCK_CANCEL") ;;; (CSTR "GTK_STOCK_CDROM") ;;; (CSTR "GTK_STOCK_CLEAR") ;;; (CSTR "GTK_STOCK_CLOSE") ;;; (CSTR "GTK_STOCK_COLOR_PICKER") ;;; (CSTR "GTK_STOCK_CONVERT") ;;; (CSTR "GTK_STOCK_COPY") ;;; (CSTR "GTK_STOCK_CUT") ;;; (CSTR "GTK_STOCK_DELETE") ;;; (CSTR "GTK_STOCK_EXECUTE") ;;; (CSTR "GTK_STOCK_FIND") ;;; (CSTR "GTK_STOCK_FIND_AND_REPLACE") ;;; (CSTR "GTK_STOCK_FLOPPY") ;;; (CSTR "GTK_STOCK_GOTO_BOTTOM") ;;; (CSTR "GTK_STOCK_GOTO_FIRST") ;;; (CSTR "GTK_STOCK_GOTO_LAST") ;;; (CSTR "GTK_STOCK_GOTO_TOP") ;;; (CSTR "GTK_STOCK_GO_BACK") ;;; (CSTR "GTK_STOCK_GO_DOWN") ;;; (CSTR "GTK_STOCK_GO_FORWARD") ;;; (CSTR "GTK_STOCK_GO_UP") ;;; (CSTR "GTK_STOCK_HARDDISK") ;;; (CSTR "GTK_STOCK_HELP") ;;; (CSTR "GTK_STOCK_HOME") ;;; (CSTR "GTK_STOCK_INDEX") ;;; (CSTR "GTK_STOCK_ITALIC") ;;; (CSTR "GTK_STOCK_INDENT") ;;; (CSTR "GTK_STOCK_UNINDENT") ;;; (CSTR "GTK_STOCK_NETWORK") ;;; (CSTR "GTK_STOCK_JUMP_TO") ;;; (CSTR "GTK_STOCK_JUSTIFY_CENTER") ;;; (CSTR "GTK_STOCK_JUSTIFY_FILL") ;;; (CSTR "GTK_STOCK_JUSTIFY_LEFT") ;;; (CSTR "GTK_STOCK_JUSTIFY_RIGHT") ;;; (CSTR "GTK_STOCK_MISSING_IMAGE") ;;; (CSTR "GTK_STOCK_NEW") ;;; (CSTR "GTK_STOCK_NO") ;;; (CSTR "GTK_STOCK_OK") ;;; (CSTR "GTK_STOCK_OPEN") ;;; (CSTR "GTK_STOCK_PASTE") ;;; (CSTR "GTK_STOCK_PREFERENCES") ;;; (CSTR "GTK_STOCK_PRINT") ;;; (CSTR "GTK_STOCK_PRINT_PREVIEW") ;;; (CSTR "GTK_STOCK_PROPERTIES") ;;; (CSTR "GTK_STOCK_QUIT") ;;; (CSTR "GTK_STOCK_REDO") ;;; (CSTR "GTK_STOCK_REFRESH") ;;; (CSTR "GTK_STOCK_REMOVE") ;;; (CSTR "GTK_STOCK_REVERT_TO_SAVED") ;;; (CSTR "GTK_STOCK_SAVE") ;;; (CSTR "GTK_STOCK_SAVE_AS") ;;; (CSTR "GTK_STOCK_SELECT_COLOR") ;;; (CSTR "GTK_STOCK_SELECT_FONT") ;;; (CSTR "GTK_STOCK_SORT_ASCENDING") ;;; (CSTR "GTK_STOCK_SORT_DESCENDING") ;;; (CSTR "GTK_STOCK_SPELL_CHECK") ;;; (CSTR "GTK_STOCK_STOP") ;;; (CSTR "GTK_STOCK_STRIKETHROUGH") ;;; (CSTR "GTK_STOCK_UNDELETE") ;;; (CSTR "GTK_STOCK_UNDERLINE") ;;; (CSTR "GTK_STOCK_UNDO") ;;; (CSTR "GTK_STOCK_YES") ;;; (CSTR "GTK_STOCK_ZOOM_100") ;;; (CSTR "GTK_STOCK_ZOOM_FIT") ;;; (CSTR "GTK_STOCK_ZOOM_IN") ;;; (CSTR "GTK_STOCK_ZOOM_OUT") ;;; ;;; ;(CSTR "GTK_STOCK_DIALOG_AUTHENTICATION") ;;; (CSTR "GTK_STOCK_ABOUT") ;;; (CSTR "GTK_STOCK_CONNECT") ;;; (CSTR "GTK_STOCK_DIRECTORY") ;;; (CSTR "GTK_STOCK_DISCONNECT") ;;; (CSTR "GTK_STOCK_EDIT") ;;; (CSTR "GTK_STOCK_FILE") ;;; (CSTR "GTK_STOCK_MEDIA_FORWARD") ;;; (CSTR "GTK_STOCK_MEDIA_NEXT") ;;; (CSTR "GTK_STOCK_MEDIA_PAUSE") ;;; (CSTR "GTK_STOCK_MEDIA_PLAY") ;;; (CSTR "GTK_STOCK_MEDIA_PREVIOUS") ;;; (CSTR "GTK_STOCK_MEDIA_RECORD") ;;; (CSTR "GTK_STOCK_MEDIA_REWIND") ;;; (CSTR "GTK_STOCK_MEDIA_STOP") ;;; ;;; (CSTR "GTK_STOCK_FULLSCREEN") ;;; (CSTR "GTK_STOCK_INFO") ;;; (CSTR "GTK_STOCK_LEAVE_FULLSCREEN") ;;; ;;; (CSTR "GTK_STOCK_ORIENTATION_PORTRAIT") ;;; (CSTR "GTK_STOCK_ORIENTATION_LANDSCAPE") ;;; (CSTR "GTK_STOCK_ORIENTATION_REVERSE_LANDSCAPE") ;;; (CSTR "GTK_STOCK_SELECT_ALL") ;;; ;;; (CSTR "GTK_STOCK_ORIENTATION_REVERSE_PORTRAIT") ;;; (CCAST-gtk2 "GTK_STYLE(object)" "GtkStyle*") ;;; (CCHK-gtk2 "GTK_IS_STYLE(object)" "GtkStyle*") ;;; ;(CCAST2-gtk2 "GTK_STYLE_ATTACHED(style)") ;;; ;;;;(CFNC-gtk2 "GType gtk_style_get_type void") ;;; (CFNC-gtk2 "GtkStyle* gtk_style_new void") ;;; (CFNC-gtk2 "GtkStyle* gtk_style_copy GtkStyle* style") ;;; (CFNC-gtk2 "GtkStyle* gtk_style_attach GtkStyle* style GdkWindow* window") ;;; (CFNC-gtk2 "void gtk_style_detach GtkStyle* style") ;;; (CFNC-gtk2 "void gtk_style_set_background GtkStyle* style GdkWindow* window GtkStateType state_type") ;;; (CFNC-gtk2 "void gtk_style_apply_default_background GtkStyle* style GdkWindow* window gboolean set_bg GtkStateType state_type GdkRectangle* area gint x gint y gint width gint height") ;;; ;;; (CFNC-gtk2 "GtkIconSet* gtk_style_lookup_icon_set GtkStyle* style gchar* stock_id") ;;; ;;; (CFNC-gtk2 "GdkPixbuf* gtk_style_render_icon GtkStyle* style GtkIconSource* source GtkTextDirection direction GtkStateType state GtkIconSize size GtkWidget* widget gchar* detail") ;;; ;(CFNC-gtk2 "void gtk_paint_hline GtkStyle* style GdkWindow* window GtkStateType state_type GdkRectangle* area GtkWidget* widget gchar* detail gint x1 gint x2 gint y") ;;; ;(CFNC-gtk2 "void gtk_paint_vline GtkStyle* style GdkWindow* window GtkStateType state_type GdkRectangle* area GtkWidget* widget gchar* detail gint y1 gint y2 gint x") ;;; ;(CFNC-gtk2 "void gtk_paint_shadow GtkStyle* style GdkWindow* window GtkStateType state_type GtkShadowType shadow_type GdkRectangle* area GtkWidget* widget gchar* detail gint x gint y gint width gint height") ;;;; 2.90.6 (CFNC "void gtk_paint_polygon GtkStyle* style GdkWindow* window GtkStateType state_type GtkShadowType shadow_type GdkRectangle* area GtkWidget* widget gchar* detail GdkPoint* points gint npoints gboolean fill") ;;; ;(CFNC-gtk2 "void gtk_paint_arrow GtkStyle* style GdkWindow* window GtkStateType state_type GtkShadowType shadow_type GdkRectangle* area GtkWidget* widget gchar* detail GtkArrowType arrow_type gboolean fill gint x gint y gint width gint height") ;;; ;(CFNC-gtk2 "void gtk_paint_diamond GtkStyle* style GdkWindow* window GtkStateType state_type GtkShadowType shadow_type GdkRectangle* area GtkWidget* widget gchar* detail gint x gint y gint width gint height") ;;; ;(CFNC-gtk2 "void gtk_paint_box GtkStyle* style GdkWindow* window GtkStateType state_type GtkShadowType shadow_type GdkRectangle* area GtkWidget* widget gchar* detail gint x gint y gint width gint height") ;;; ;(CFNC-gtk2 "void gtk_paint_flat_box GtkStyle* style GdkWindow* window GtkStateType state_type GtkShadowType shadow_type GdkRectangle* area GtkWidget* widget gchar* detail gint x gint y gint width gint height") ;;; ;(CFNC-gtk2 "void gtk_paint_check GtkStyle* style GdkWindow* window GtkStateType state_type GtkShadowType shadow_type GdkRectangle* area GtkWidget* widget gchar* detail gint x gint y gint width gint height") ;;; ;(CFNC-gtk2 "void gtk_paint_option GtkStyle* style GdkWindow* window GtkStateType state_type GtkShadowType shadow_type GdkRectangle* area GtkWidget* widget gchar* detail gint x gint y gint width gint height") ;;; ;(CFNC-gtk2 "void gtk_paint_tab GtkStyle* style GdkWindow* window GtkStateType state_type GtkShadowType shadow_type GdkRectangle* area GtkWidget* widget gchar* detail gint x gint y gint width gint height") ;;; ;(CFNC-gtk2 "void gtk_paint_shadow_gap GtkStyle* style GdkWindow* window GtkStateType state_type GtkShadowType shadow_type GdkRectangle* area GtkWidget* widget gchar* detail gint x gint y gint width gint height GtkPositionType gap_side gint gap_x gint gap_width") ;;; ;(CFNC-gtk2 "void gtk_paint_box_gap GtkStyle* style GdkWindow* window GtkStateType state_type GtkShadowType shadow_type GdkRectangle* area GtkWidget* widget gchar* detail gint x gint y gint width gint height GtkPositionType gap_side gint gap_x gint gap_width") ;;; ;(CFNC-gtk2 "void gtk_paint_extension GtkStyle* style GdkWindow* window GtkStateType state_type GtkShadowType shadow_type GdkRectangle* area GtkWidget* widget gchar* detail gint x gint y gint width gint height GtkPositionType gap_side") ;;; ;(CFNC-gtk2 "void gtk_paint_focus GtkStyle* style GdkWindow* window GtkStateType state_type GdkRectangle* area GtkWidget* widget gchar* detail gint x gint y gint width gint height") ;;; ;(CFNC-gtk2 "void gtk_paint_slider GtkStyle* style GdkWindow* window GtkStateType state_type GtkShadowType shadow_type GdkRectangle* area GtkWidget* widget gchar* detail gint x gint y gint width gint height GtkOrientation orientation") ;;; ;(CFNC-gtk2 "void gtk_paint_handle GtkStyle* style GdkWindow* window GtkStateType state_type GtkShadowType shadow_type GdkRectangle* area GtkWidget* widget gchar* detail gint x gint y gint width gint height GtkOrientation orientation") ;;; ;;(CFNC-gtk2 "void gtk_paint_expander GtkStyle* style GdkWindow* window GtkStateType state_type GdkRectangle* area GtkWidget* widget gchar* detail gint x gint y GtkExpanderStyle expander_style") ;;; ;(CFNC-gtk2 "void gtk_paint_layout GtkStyle* style GdkWindow* window GtkStateType state_type gboolean use_text GdkRectangle* area GtkWidget* widget gchar* detail gint x gint y PangoLayout* layout") ;;; ;(CFNC-gtk2 "void gtk_paint_resize_grip GtkStyle* style GdkWindow* window GtkStateType state_type GdkRectangle* area GtkWidget* widget gchar* detail GdkWindowEdge edge gint x gint y gint width gint height") ;;; ;;; (CFNC-gtk2 "GtkBorder* gtk_border_copy GtkBorder* border") ;;; ;;; (CFNC-gtk2 "void gtk_border_free GtkBorder* border") ;;; 3.3.2 (CCAST "GTK_TABLE(obj)" "GtkTable*") ;;; 3.3.2 (CCHK "GTK_IS_TABLE(obj)" "GtkTable*") ;;; 3.3.2 ;;;;(CFNC "GType gtk_table_get_type void") ;;; 3.3.2 (CFNC "GtkWidget* gtk_table_new guint rows guint columns gboolean homogeneous") ;;; 3.3.2 (CFNC "void gtk_table_resize GtkTable* table guint rows guint columns") ;;; 3.3.2 (CFNC "void gtk_table_attach GtkTable* table GtkWidget* child guint left_attach guint right_attach guint top_attach guint bottom_attach GtkAttachOptions xoptions GtkAttachOptions yoptions guint xpadding guint ypadding") ;;; 3.3.2 (CFNC "void gtk_table_attach_defaults GtkTable* table GtkWidget* widget guint left_attach guint right_attach guint top_attach guint bottom_attach") ;;; 3.3.2 (CFNC "void gtk_table_set_row_spacing GtkTable* table guint row guint spacing") ;;; 3.3.2 (CFNC "guint gtk_table_get_row_spacing GtkTable* table guint row") ;;; 3.3.2 (CFNC "void gtk_table_set_col_spacing GtkTable* table guint column guint spacing") ;;; 3.3.2 (CFNC "guint gtk_table_get_col_spacing GtkTable* table guint column") ;;; 3.3.2 (CFNC "void gtk_table_set_row_spacings GtkTable* table guint spacing") ;;; 3.3.2 (CFNC "guint gtk_table_get_default_row_spacing GtkTable* table") ;;; 3.3.2 (CFNC "void gtk_table_set_col_spacings GtkTable* table guint spacing") ;;; 3.3.2 (CFNC "guint gtk_table_get_default_col_spacing GtkTable* table") ;;; 3.3.2 (CFNC "void gtk_table_set_homogeneous GtkTable* table gboolean homogeneous") ;;; 3.3.2 (CFNC "gboolean gtk_table_get_homogeneous GtkTable* table") ;;; 3.3.2 (CCAST "GTK_TEAROFF_MENU_ITEM(obj)" "GtkTearoffMenuItem*") ;;; 3.3.2 (CCHK "GTK_IS_TEAROFF_MENU_ITEM(obj)" "GtkTearoffMenuItem*") ;;; 3.3.2 ;;;;(CFNC "GType gtk_tearoff_menu_item_get_type void") ;;; 3.3.2 (CFNC "GtkWidget* gtk_tearoff_menu_item_new void") (CCAST "GTK_TEXT_BUFFER(obj)" "GtkTextBuffer*") (CCHK "GTK_IS_TEXT_BUFFER(obj)" "GtkTextBuffer*") ;;;;(CFNC "GType gtk_text_buffer_get_type void") (CFNC "GtkTextBuffer* gtk_text_buffer_new GtkTextTagTable* @table") (CFNC "gint gtk_text_buffer_get_line_count GtkTextBuffer* buffer") (CFNC "gint gtk_text_buffer_get_char_count GtkTextBuffer* buffer") (CFNC "GtkTextTagTable* gtk_text_buffer_get_tag_table GtkTextBuffer* buffer") (CFNC "void gtk_text_buffer_set_text GtkTextBuffer* buffer gchar* text gint len") (CFNC "void gtk_text_buffer_insert GtkTextBuffer* buffer GtkTextIter* iter gchar* text gint len") (CFNC "void gtk_text_buffer_insert_at_cursor GtkTextBuffer* buffer gchar* text gint len") (CFNC "gboolean gtk_text_buffer_insert_interactive GtkTextBuffer* buffer GtkTextIter* iter gchar* text gint len gboolean default_editable") (CFNC "gboolean gtk_text_buffer_insert_interactive_at_cursor GtkTextBuffer* buffer gchar* text gint len gboolean default_editable") (CFNC "void gtk_text_buffer_insert_range GtkTextBuffer* buffer GtkTextIter* iter GtkTextIter* start GtkTextIter* end") (CFNC "gboolean gtk_text_buffer_insert_range_interactive GtkTextBuffer* buffer GtkTextIter* iter GtkTextIter* start GtkTextIter* end gboolean default_editable") (CFNC-PA "void gtk_text_buffer_insert_with_tags GtkTextBuffer* buffer GtkTextIter* iter gchar* text gint len etc tags" 1 6 '("GtkTextTag*")) (CFNC-PA "void gtk_text_buffer_insert_with_tags_by_name GtkTextBuffer* buffer GtkTextIter* iter gchar* text gint len etc tags" 1 6 '("gchar*" "int")) (CFNC "void gtk_text_buffer_delete GtkTextBuffer* buffer GtkTextIter* start GtkTextIter* end") (CFNC "gboolean gtk_text_buffer_delete_interactive GtkTextBuffer* buffer GtkTextIter* start_iter GtkTextIter* end_iter gboolean default_editable") (CFNC "gchar* gtk_text_buffer_get_text GtkTextBuffer* buffer GtkTextIter* start GtkTextIter* end gboolean include_hidden_chars" 'free) (CFNC "gchar* gtk_text_buffer_get_slice GtkTextBuffer* buffer GtkTextIter* start GtkTextIter* end gboolean include_hidden_chars" 'free) (CFNC "void gtk_text_buffer_insert_pixbuf GtkTextBuffer* buffer GtkTextIter* iter GdkPixbuf* pixbuf") (CFNC "void gtk_text_buffer_insert_child_anchor GtkTextBuffer* buffer GtkTextIter* iter GtkTextChildAnchor* anchor") (CFNC "GtkTextChildAnchor* gtk_text_buffer_create_child_anchor GtkTextBuffer* buffer GtkTextIter* iter") (CFNC "GtkTextMark* gtk_text_buffer_create_mark GtkTextBuffer* buffer gchar* mark_name GtkTextIter* where gboolean left_gravity") (CFNC "void gtk_text_buffer_move_mark GtkTextBuffer* buffer GtkTextMark* mark GtkTextIter* where") (CFNC "void gtk_text_buffer_delete_mark GtkTextBuffer* buffer GtkTextMark* mark") (CFNC "GtkTextMark* gtk_text_buffer_get_mark GtkTextBuffer* buffer gchar* name") (CFNC "void gtk_text_buffer_move_mark_by_name GtkTextBuffer* buffer gchar* name GtkTextIter* where") (CFNC "void gtk_text_buffer_delete_mark_by_name GtkTextBuffer* buffer gchar* name") (CFNC "GtkTextMark* gtk_text_buffer_get_insert GtkTextBuffer* buffer") (CFNC "GtkTextMark* gtk_text_buffer_get_selection_bound GtkTextBuffer* buffer") (CFNC "void gtk_text_buffer_place_cursor GtkTextBuffer* buffer GtkTextIter* where") (CFNC "void gtk_text_buffer_apply_tag GtkTextBuffer* buffer GtkTextTag* tag GtkTextIter* start GtkTextIter* end") (CFNC "void gtk_text_buffer_remove_tag GtkTextBuffer* buffer GtkTextTag* tag GtkTextIter* start GtkTextIter* end") (CFNC "void gtk_text_buffer_apply_tag_by_name GtkTextBuffer* buffer gchar* name GtkTextIter* start GtkTextIter* end") (CFNC "void gtk_text_buffer_remove_tag_by_name GtkTextBuffer* buffer gchar* name GtkTextIter* start GtkTextIter* end") (CFNC "void gtk_text_buffer_remove_all_tags GtkTextBuffer* buffer GtkTextIter* start GtkTextIter* end") (CFNC-PA "GtkTextTag* gtk_text_buffer_create_tag GtkTextBuffer* buffer gchar* tag_name etc #tags" 0 6 '("gchar*" "any")) (CFNC "void gtk_text_buffer_get_iter_at_line_offset GtkTextBuffer* buffer GtkTextIter* iter gint line_number gint char_offset") (CFNC "void gtk_text_buffer_get_iter_at_line_index GtkTextBuffer* buffer GtkTextIter* iter gint line_number gint byte_index") (CFNC "void gtk_text_buffer_get_iter_at_offset GtkTextBuffer* buffer GtkTextIter* iter gint char_offset") (CFNC "void gtk_text_buffer_get_iter_at_line GtkTextBuffer* buffer GtkTextIter* iter gint line_number") (CFNC "void gtk_text_buffer_get_start_iter GtkTextBuffer* buffer GtkTextIter* iter") (CFNC "void gtk_text_buffer_get_end_iter GtkTextBuffer* buffer GtkTextIter* iter") (CFNC "void gtk_text_buffer_get_bounds GtkTextBuffer* buffer GtkTextIter* start GtkTextIter* end") (CFNC "void gtk_text_buffer_get_iter_at_mark GtkTextBuffer* buffer GtkTextIter* iter GtkTextMark* mark") (CFNC "void gtk_text_buffer_get_iter_at_child_anchor GtkTextBuffer* buffer GtkTextIter* iter GtkTextChildAnchor* anchor") (CFNC "gboolean gtk_text_buffer_get_modified GtkTextBuffer* buffer") (CFNC "void gtk_text_buffer_set_modified GtkTextBuffer* buffer gboolean setting") (CFNC "void gtk_text_buffer_add_selection_clipboard GtkTextBuffer* buffer GtkClipboard* clipboard") (CFNC "void gtk_text_buffer_remove_selection_clipboard GtkTextBuffer* buffer GtkClipboard* clipboard") (CFNC "void gtk_text_buffer_cut_clipboard GtkTextBuffer* buffer GtkClipboard* clipboard gboolean default_editable") (CFNC "void gtk_text_buffer_copy_clipboard GtkTextBuffer* buffer GtkClipboard* clipboard") (CFNC "void gtk_text_buffer_paste_clipboard GtkTextBuffer* buffer GtkClipboard* clipboard GtkTextIter* @override_location gboolean default_editable") (CFNC "gboolean gtk_text_buffer_get_selection_bounds GtkTextBuffer* buffer GtkTextIter* start GtkTextIter* end") (CFNC "gboolean gtk_text_buffer_delete_selection GtkTextBuffer* buffer gboolean interactive gboolean default_editable") (CFNC "void gtk_text_buffer_begin_user_action GtkTextBuffer* buffer") (CFNC "void gtk_text_buffer_end_user_action GtkTextBuffer* buffer") (CCAST "GTK_TEXT_CHILD_ANCHOR(object)" "GtkTextChildAnchor*") (CCHK "GTK_IS_TEXT_CHILD_ANCHOR(object)" "GtkTextChildAnchor*") ;;;;(CFNC "GType gtk_text_child_anchor_get_type void") (CFNC "GtkTextChildAnchor* gtk_text_child_anchor_new void") (CFNC "GList* gtk_text_child_anchor_get_widgets GtkTextChildAnchor* anchor") (CFNC "gboolean gtk_text_child_anchor_get_deleted GtkTextChildAnchor* anchor") (CFNC "GtkTextBuffer* gtk_text_iter_get_buffer GtkTextIter* iter") (CFNC "GtkTextIter* gtk_text_iter_copy GtkTextIter* iter") (CFNC "void gtk_text_iter_free GtkTextIter* iter") (CFNC "gint gtk_text_iter_get_offset GtkTextIter* iter") (CFNC "gint gtk_text_iter_get_line GtkTextIter* iter") (CFNC "gint gtk_text_iter_get_line_offset GtkTextIter* iter") (CFNC "gint gtk_text_iter_get_line_index GtkTextIter* iter") (CFNC "gint gtk_text_iter_get_visible_line_offset GtkTextIter* iter") (CFNC "gint gtk_text_iter_get_visible_line_index GtkTextIter* iter") (CFNC "gunichar gtk_text_iter_get_char GtkTextIter* iter") (CFNC "gchar* gtk_text_iter_get_slice GtkTextIter* start GtkTextIter* end" 'free) (CFNC "gchar* gtk_text_iter_get_text GtkTextIter* start GtkTextIter* end" 'free) (CFNC "gchar* gtk_text_iter_get_visible_slice GtkTextIter* start GtkTextIter* end" 'free) (CFNC "gchar* gtk_text_iter_get_visible_text GtkTextIter* start GtkTextIter* end" 'free) (CFNC "GdkPixbuf* gtk_text_iter_get_pixbuf GtkTextIter* iter") (CFNC "GSList* gtk_text_iter_get_marks GtkTextIter* iter") (CFNC "GtkTextChildAnchor* gtk_text_iter_get_child_anchor GtkTextIter* iter") (CFNC "GSList* gtk_text_iter_get_toggled_tags GtkTextIter* iter gboolean toggled_on") (CFNC "gboolean gtk_text_iter_begins_tag GtkTextIter* iter GtkTextTag* @tag") (CFNC "gboolean gtk_text_iter_ends_tag GtkTextIter* iter GtkTextTag* @tag") (CFNC "gboolean gtk_text_iter_toggles_tag GtkTextIter* iter GtkTextTag* @tag") (CFNC "gboolean gtk_text_iter_has_tag GtkTextIter* iter GtkTextTag* tag") (CFNC "GSList* gtk_text_iter_get_tags GtkTextIter* iter") (CFNC "gboolean gtk_text_iter_editable GtkTextIter* iter gboolean default_setting") (CFNC "gboolean gtk_text_iter_can_insert GtkTextIter* iter gboolean default_editability") (CFNC "gboolean gtk_text_iter_starts_word GtkTextIter* iter") (CFNC "gboolean gtk_text_iter_ends_word GtkTextIter* iter") (CFNC "gboolean gtk_text_iter_inside_word GtkTextIter* iter") (CFNC "gboolean gtk_text_iter_starts_sentence GtkTextIter* iter") (CFNC "gboolean gtk_text_iter_ends_sentence GtkTextIter* iter") (CFNC "gboolean gtk_text_iter_inside_sentence GtkTextIter* iter") (CFNC "gboolean gtk_text_iter_starts_line GtkTextIter* iter") (CFNC "gboolean gtk_text_iter_ends_line GtkTextIter* iter") (CFNC "gboolean gtk_text_iter_is_cursor_position GtkTextIter* iter") (CFNC "gint gtk_text_iter_get_chars_in_line GtkTextIter* iter") (CFNC "gint gtk_text_iter_get_bytes_in_line GtkTextIter* iter") (CFNC "gboolean gtk_text_iter_get_attributes GtkTextIter* iter GtkTextAttributes* values") (CFNC "PangoLanguage* gtk_text_iter_get_language GtkTextIter* iter") (CFNC "gboolean gtk_text_iter_is_end GtkTextIter* iter") (CFNC "gboolean gtk_text_iter_is_start GtkTextIter* iter") (CFNC "gboolean gtk_text_iter_forward_char GtkTextIter* iter") (CFNC "gboolean gtk_text_iter_backward_char GtkTextIter* iter") (CFNC "gboolean gtk_text_iter_forward_chars GtkTextIter* iter gint count") (CFNC "gboolean gtk_text_iter_backward_chars GtkTextIter* iter gint count") (CFNC "gboolean gtk_text_iter_forward_line GtkTextIter* iter") (CFNC "gboolean gtk_text_iter_backward_line GtkTextIter* iter") (CFNC "gboolean gtk_text_iter_forward_lines GtkTextIter* iter gint count") (CFNC "gboolean gtk_text_iter_backward_lines GtkTextIter* iter gint count") (CFNC "gboolean gtk_text_iter_forward_word_end GtkTextIter* iter") (CFNC "gboolean gtk_text_iter_backward_word_start GtkTextIter* iter") (CFNC "gboolean gtk_text_iter_forward_word_ends GtkTextIter* iter gint count") (CFNC "gboolean gtk_text_iter_backward_word_starts GtkTextIter* iter gint count") (CFNC "gboolean gtk_text_iter_forward_sentence_end GtkTextIter* iter") (CFNC "gboolean gtk_text_iter_backward_sentence_start GtkTextIter* iter") (CFNC "gboolean gtk_text_iter_forward_sentence_ends GtkTextIter* iter gint count") (CFNC "gboolean gtk_text_iter_backward_sentence_starts GtkTextIter* iter gint count") (CFNC "gboolean gtk_text_iter_forward_cursor_position GtkTextIter* iter") (CFNC "gboolean gtk_text_iter_backward_cursor_position GtkTextIter* iter") (CFNC "gboolean gtk_text_iter_forward_cursor_positions GtkTextIter* iter gint count") (CFNC "gboolean gtk_text_iter_backward_cursor_positions GtkTextIter* iter gint count") (CFNC "void gtk_text_iter_set_offset GtkTextIter* iter gint char_offset") (CFNC "void gtk_text_iter_set_line GtkTextIter* iter gint line_number") (CFNC "void gtk_text_iter_set_line_offset GtkTextIter* iter gint char_on_line") (CFNC "void gtk_text_iter_set_line_index GtkTextIter* iter gint byte_on_line") (CFNC "void gtk_text_iter_forward_to_end GtkTextIter* iter") (CFNC "gboolean gtk_text_iter_forward_to_line_end GtkTextIter* iter") (CFNC "void gtk_text_iter_set_visible_line_offset GtkTextIter* iter gint char_on_line") (CFNC "void gtk_text_iter_set_visible_line_index GtkTextIter* iter gint byte_on_line") (CFNC "gboolean gtk_text_iter_forward_to_tag_toggle GtkTextIter* iter GtkTextTag* @tag") (CFNC "gboolean gtk_text_iter_backward_to_tag_toggle GtkTextIter* iter GtkTextTag* @tag") (CFNC "gboolean gtk_text_iter_forward_find_char GtkTextIter* iter GtkTextCharPredicate pred lambda_data func_info GtkTextIter* @limit") (CFNC "gboolean gtk_text_iter_backward_find_char GtkTextIter* iter GtkTextCharPredicate pred lambda_data func_info GtkTextIter* @limit") (CFNC "gboolean gtk_text_iter_forward_search GtkTextIter* iter gchar* str GtkTextSearchFlags flags GtkTextIter* @match_start GtkTextIter* @match_end GtkTextIter* @limit") (CFNC "gboolean gtk_text_iter_backward_search GtkTextIter* iter gchar* str GtkTextSearchFlags flags GtkTextIter* @match_start GtkTextIter* @match_end GtkTextIter* @limit") (CINT "GTK_TEXT_SEARCH_VISIBLE_ONLY" "GtkTextSearchFlags") (CINT "GTK_TEXT_SEARCH_TEXT_ONLY" "GtkTextSearchFlags") (CFNC "gboolean gtk_text_iter_equal GtkTextIter* lhs GtkTextIter* rhs") (CFNC "gint gtk_text_iter_compare GtkTextIter* lhs GtkTextIter* rhs") (CFNC "gboolean gtk_text_iter_in_range GtkTextIter* iter GtkTextIter* start GtkTextIter* end") (CFNC "void gtk_text_iter_order GtkTextIter* first GtkTextIter* second") (CCAST "GTK_TEXT_MARK(object)" "GtkTextMark*") (CCHK "GTK_IS_TEXT_MARK(object)" "GtkTextMark*") ;;;;(CFNC "GType gtk_text_mark_get_type void") (CFNC "void gtk_text_mark_set_visible GtkTextMark* mark gboolean setting") (CFNC "gboolean gtk_text_mark_get_visible GtkTextMark* mark") (CFNC "char* gtk_text_mark_get_name GtkTextMark* mark") (CFNC "gboolean gtk_text_mark_get_deleted GtkTextMark* mark") (CFNC "GtkTextBuffer* gtk_text_mark_get_buffer GtkTextMark* mark") (CFNC "gboolean gtk_text_mark_get_left_gravity GtkTextMark* mark") (CCAST "GTK_TEXT_TAG(obj)" "GtkTextTag*") (CCHK "GTK_IS_TEXT_TAG(obj)" "GtkTextTag*") ;;;;(CFNC "GType gtk_text_tag_get_type void") (CFNC "GtkTextTag* gtk_text_tag_new gchar* name") (CFNC "gint gtk_text_tag_get_priority GtkTextTag* tag") (CFNC "void gtk_text_tag_set_priority GtkTextTag* tag gint priority") (CFNC "gboolean gtk_text_tag_event GtkTextTag* tag GObject* event_object GdkEvent* event GtkTextIter* iter") (CFNC "GtkTextAttributes* gtk_text_attributes_new void") (CFNC "GtkTextAttributes* gtk_text_attributes_copy GtkTextAttributes* src") (CFNC "void gtk_text_attributes_copy_values GtkTextAttributes* src GtkTextAttributes* dest") (CFNC "void gtk_text_attributes_unref GtkTextAttributes* values") ;;;(CFNC "void gtk_text_attributes_ref GtkTextAttributes* values") ;;; return type changed 2.8.6 (CCAST "GTK_TEXT_TAG_TABLE(obj)" "GtkTextTagTable*") (CCHK "GTK_IS_TEXT_TAG_TABLE(obj)" "GtkTextTagTable*") ;;;;(CFNC "GType gtk_text_tag_table_get_type void") (CFNC "GtkTextTagTable* gtk_text_tag_table_new void") (CFNC "void gtk_text_tag_table_add GtkTextTagTable* table GtkTextTag* tag") (CFNC "void gtk_text_tag_table_remove GtkTextTagTable* table GtkTextTag* tag") (CFNC "GtkTextTag* gtk_text_tag_table_lookup GtkTextTagTable* table gchar* name") (CFNC "void gtk_text_tag_table_foreach GtkTextTagTable* table GtkTextTagTableForeach func lambda_data #func_info") (CFNC "gint gtk_text_tag_table_get_size GtkTextTagTable* table") ;(CFNC "gboolean gtk_text_byte_begins_utf8_char gchar* byte") (CCAST "GTK_TEXT_VIEW(obj)" "GtkTextView*") (CCHK "GTK_IS_TEXT_VIEW(obj)" "GtkTextView*") (CINT "GTK_TEXT_WINDOW_PRIVATE" "GtkTextWindowType") (CINT "GTK_TEXT_WINDOW_WIDGET" "GtkTextWindowType") (CINT "GTK_TEXT_WINDOW_TEXT" "GtkTextWindowType") (CINT "GTK_TEXT_WINDOW_LEFT" "GtkTextWindowType") (CINT "GTK_TEXT_WINDOW_RIGHT" "GtkTextWindowType") (CINT "GTK_TEXT_WINDOW_TOP" "GtkTextWindowType") (CINT "GTK_TEXT_WINDOW_BOTTOM" "GtkTextWindowType") (CINT "GTK_TEXT_VIEW_PRIORITY_VALIDATE") ;;;;(CFNC "GType gtk_text_view_get_type void") (CFNC "GtkWidget* gtk_text_view_new void") (CFNC "GtkWidget* gtk_text_view_new_with_buffer GtkTextBuffer* buffer") (CFNC "void gtk_text_view_set_buffer GtkTextView* text_view GtkTextBuffer* buffer") (CFNC "GtkTextBuffer* gtk_text_view_get_buffer GtkTextView* text_view") (CFNC "gboolean gtk_text_view_scroll_to_iter GtkTextView* text_view GtkTextIter* iter gdouble within_margin gboolean use_align gdouble xalign gdouble yalign") (CFNC "void gtk_text_view_scroll_to_mark GtkTextView* text_view GtkTextMark* mark gdouble within_margin gboolean use_align gdouble xalign gdouble yalign") (CFNC "void gtk_text_view_scroll_mark_onscreen GtkTextView* text_view GtkTextMark* mark") (CFNC "gboolean gtk_text_view_move_mark_onscreen GtkTextView* text_view GtkTextMark* mark") (CFNC "gboolean gtk_text_view_place_cursor_onscreen GtkTextView* text_view") (CFNC "void gtk_text_view_get_visible_rect GtkTextView* text_view GdkRectangle* visible_rect") (CFNC "void gtk_text_view_set_cursor_visible GtkTextView* text_view gboolean setting") (CFNC "gboolean gtk_text_view_get_cursor_visible GtkTextView* text_view") (CFNC "void gtk_text_view_get_iter_location GtkTextView* text_view GtkTextIter* iter GdkRectangle* location") (CFNC "void gtk_text_view_get_iter_at_location GtkTextView* text_view GtkTextIter* iter gint x gint y") (CFNC "void gtk_text_view_get_line_yrange GtkTextView* text_view GtkTextIter* iter gint* [y] gint* [height]") (CFNC "void gtk_text_view_get_line_at_y GtkTextView* text_view GtkTextIter* target_iter gint y gint* [line_top]") (CFNC "void gtk_text_view_buffer_to_window_coords GtkTextView* text_view GtkTextWindowType win gint buffer_x gint buffer_y gint* [window_x] gint* [window_y]") (CFNC "void gtk_text_view_window_to_buffer_coords GtkTextView* text_view GtkTextWindowType win gint window_x gint window_y gint* [buffer_x] gint* [buffer_y]") (CFNC "GdkWindow* gtk_text_view_get_window GtkTextView* text_view GtkTextWindowType win") (CFNC "GtkTextWindowType gtk_text_view_get_window_type GtkTextView* text_view GdkWindow* window") (CFNC "void gtk_text_view_set_border_window_size GtkTextView* text_view GtkTextWindowType type gint size") (CFNC "gint gtk_text_view_get_border_window_size GtkTextView* text_view GtkTextWindowType type") (CFNC "gboolean gtk_text_view_forward_display_line GtkTextView* text_view GtkTextIter* iter") (CFNC "gboolean gtk_text_view_backward_display_line GtkTextView* text_view GtkTextIter* iter") (CFNC "gboolean gtk_text_view_forward_display_line_end GtkTextView* text_view GtkTextIter* iter") (CFNC "gboolean gtk_text_view_backward_display_line_start GtkTextView* text_view GtkTextIter* iter") (CFNC "gboolean gtk_text_view_starts_display_line GtkTextView* text_view GtkTextIter* iter") (CFNC "gboolean gtk_text_view_move_visually GtkTextView* text_view GtkTextIter* iter gint count") (CFNC "void gtk_text_view_add_child_at_anchor GtkTextView* text_view GtkWidget* child GtkTextChildAnchor* anchor") (CFNC "void gtk_text_view_add_child_in_window GtkTextView* text_view GtkWidget* child GtkTextWindowType which_window gint xpos gint ypos") (CFNC "void gtk_text_view_move_child GtkTextView* text_view GtkWidget* child gint xpos gint ypos") (CFNC "void gtk_text_view_set_wrap_mode GtkTextView* text_view GtkWrapMode wrap_mode") (CFNC "GtkWrapMode gtk_text_view_get_wrap_mode GtkTextView* text_view") (CFNC "void gtk_text_view_set_editable GtkTextView* text_view gboolean setting") (CFNC "gboolean gtk_text_view_get_editable GtkTextView* text_view") (CFNC "void gtk_text_view_set_pixels_above_lines GtkTextView* text_view gint pixels_above_lines") (CFNC "gint gtk_text_view_get_pixels_above_lines GtkTextView* text_view") (CFNC "void gtk_text_view_set_pixels_below_lines GtkTextView* text_view gint pixels_below_lines") (CFNC "gint gtk_text_view_get_pixels_below_lines GtkTextView* text_view") (CFNC "void gtk_text_view_set_pixels_inside_wrap GtkTextView* text_view gint pixels_inside_wrap") (CFNC "gint gtk_text_view_get_pixels_inside_wrap GtkTextView* text_view") (CFNC "void gtk_text_view_set_justification GtkTextView* text_view GtkJustification justification") (CFNC "GtkJustification gtk_text_view_get_justification GtkTextView* text_view") (CFNC "void gtk_text_view_set_left_margin GtkTextView* text_view gint left_margin") (CFNC "gint gtk_text_view_get_left_margin GtkTextView* text_view") (CFNC "void gtk_text_view_set_right_margin GtkTextView* text_view gint right_margin") (CFNC "gint gtk_text_view_get_right_margin GtkTextView* text_view") (CFNC "void gtk_text_view_set_indent GtkTextView* text_view gint indent") (CFNC "gint gtk_text_view_get_indent GtkTextView* text_view") (CFNC "void gtk_text_view_set_tabs GtkTextView* text_view PangoTabArray* @tabs") (CFNC "PangoTabArray* gtk_text_view_get_tabs GtkTextView* text_view") (CFNC "GtkTextAttributes* gtk_text_view_get_default_attributes GtkTextView* text_view") ;(CCAST "GTK_THEME_ENGINE(theme_engine)" "GtkThemeEngine*") ;(CCHK "GTK_IS_THEME_ENGINE(theme_engine)" "GtkThemeEngine*") ;;;;;(CFNC "GType gtk_theme_engine_get_type void") ;(CFNC "GtkThemeEngine* gtk_theme_engine_get gchar* name") ;;; ;(CFNC-gtk2 "GtkRcStyle* gtk_theme_engine_create_rc_style GtkThemeEngine* engine") (CCAST "GTK_TOGGLE_BUTTON(obj)" "GtkToggleButton*") (CCHK "GTK_IS_TOGGLE_BUTTON(obj)" "GtkToggleButton*") ;;;;(CFNC "GType gtk_toggle_button_get_type void") (CFNC "GtkWidget* gtk_toggle_button_new void") (CFNC "GtkWidget* gtk_toggle_button_new_with_label gchar* label") (CFNC "GtkWidget* gtk_toggle_button_new_with_mnemonic gchar* label") (CFNC "void gtk_toggle_button_set_mode GtkToggleButton* toggle_button gboolean draw_indicator") (CFNC "gboolean gtk_toggle_button_get_mode GtkToggleButton* toggle_button") (CFNC "void gtk_toggle_button_set_active GtkToggleButton* toggle_button gboolean is_active") (CFNC "gboolean gtk_toggle_button_get_active GtkToggleButton* toggle_button") (CFNC "void gtk_toggle_button_toggled GtkToggleButton* toggle_button") (CFNC "void gtk_toggle_button_set_inconsistent GtkToggleButton* toggle_button gboolean setting") (CFNC "gboolean gtk_toggle_button_get_inconsistent GtkToggleButton* toggle_button") (CCAST "GTK_TOOLBAR(obj)" "GtkToolbar*") (CCHK "GTK_IS_TOOLBAR(obj)" "GtkToolbar*") ;;; out 2.3 (CINT "GTK_TOOLBAR_CHILD_SPACE" "GtkToolbarChildType") ;;; out 2.3 (CINT "GTK_TOOLBAR_CHILD_BUTTON" "GtkToolbarChildType") ;;; out 2.3 (CINT "GTK_TOOLBAR_CHILD_TOGGLEBUTTON" "GtkToolbarChildType") ;;; out 2.3 (CINT "GTK_TOOLBAR_CHILD_RADIOBUTTON" "GtkToolbarChildType") ;;; out 2.3 (CINT "GTK_TOOLBAR_CHILD_WIDGET" "GtkToolbarChildType") ;;; out 2.3 (CINT "GTK_TOOLBAR_SPACE_EMPTY" "GtkToolbarSpaceStyle") ;;; out 2.3 (CINT "GTK_TOOLBAR_SPACE_LINE" "GtkToolbarSpaceStyle") ;;;;(CFNC "GType gtk_toolbar_get_type void") (CFNC "GtkWidget* gtk_toolbar_new void") ;;; out 2.3 (CFNC "GtkWidget* gtk_toolbar_append_item GtkToolbar* toolbar char* text char* tooltip_text char* tooltip_private_text GtkWidget* icon GCallback func lambda_data #func_info") ;;; out 2.3 (CFNC "GtkWidget* gtk_toolbar_prepend_item GtkToolbar* toolbar char* text char* tooltip_text char* tooltip_private_text GtkWidget* icon GCallback func lambda_data #func_info") ;;; out 2.3 (CFNC "GtkWidget* gtk_toolbar_insert_item GtkToolbar* toolbar char* text char* tooltip_text char* tooltip_private_text GtkWidget* icon GCallback func lambda_data func_info gint position") ;;; out 2.3 (CFNC "GtkWidget* gtk_toolbar_insert_stock GtkToolbar* toolbar gchar* stock_id char* tooltip_text char* tooltip_private_text GCallback func lambda_data func_info gint position") ;;; out 2.3 (CFNC "void gtk_toolbar_append_space GtkToolbar* toolbar") ;;; out 2.3 (CFNC "void gtk_toolbar_prepend_space GtkToolbar* toolbar") ;;; out 2.3 (CFNC "void gtk_toolbar_insert_space GtkToolbar* toolbar gint position") ;;; out 2.3 (CFNC "void gtk_toolbar_remove_space GtkToolbar* toolbar gint position") ;;; out 2.3 (CFNC "GtkWidget* gtk_toolbar_append_element GtkToolbar* toolbar GtkToolbarChildType type GtkWidget* widget char* text char* tooltip_text char* tooltip_private_text GtkWidget* icon GCallback func lambda_data #func_info") ;;; out 2.3 (CFNC "GtkWidget* gtk_toolbar_prepend_element GtkToolbar* toolbar GtkToolbarChildType type GtkWidget* widget char* text char* tooltip_text char* tooltip_private_text GtkWidget* icon GCallback func lambda_data #func_info") ;;; out 2.3 (CFNC "GtkWidget* gtk_toolbar_insert_element GtkToolbar* toolbar GtkToolbarChildType type GtkWidget* @widget char* text char* tooltip_text char* tooltip_private_text GtkWidget* icon GCallback func lambda_data func_info gint position") ;;; out 2.3 (CFNC "void gtk_toolbar_append_widget GtkToolbar* toolbar GtkWidget* widget char* tooltip_text char* tooltip_private_text") ;;; out 2.3 (CFNC "void gtk_toolbar_prepend_widget GtkToolbar* toolbar GtkWidget* widget char* tooltip_text char* tooltip_private_text") ;;; out 2.3 (CFNC "void gtk_toolbar_insert_widget GtkToolbar* toolbar GtkWidget* widget char* tooltip_text char* tooltip_private_text gint position") ;;; out 2.15.0 (CFNC "void gtk_toolbar_set_orientation GtkToolbar* toolbar GtkOrientation orientation") (CFNC "void gtk_toolbar_set_style GtkToolbar* toolbar GtkToolbarStyle style") (CFNC "void gtk_toolbar_unset_style GtkToolbar* toolbar") ;;; out 2.3 (CFNC "void gtk_toolbar_unset_icon_size GtkToolbar* toolbar") ;;; out 2.15.0 (CFNC "GtkOrientation gtk_toolbar_get_orientation GtkToolbar* toolbar") (CFNC "GtkToolbarStyle gtk_toolbar_get_style GtkToolbar* toolbar") ;;; (CFNC "GtkIconSize gtk_toolbar_get_icon_size GtkToolbar* toolbar") ;;; out 2.13.4 (CFNC "gboolean gtk_toolbar_get_tooltips GtkToolbar* toolbar") ;;; out 2.13.4 (CFNC "void gtk_toolbar_set_tooltips GtkToolbar* toolbar gboolean enable") ;;; 2.11.6 (CCAST "GTK_TOOLTIPS(obj)" "GtkTooltips*") ;;; 2.11.6 (CCHK "GTK_IS_TOOLTIPS(obj)" "GtkTooltips*") ;;; 2.11.6 ;;;;(CFNC "GType gtk_tooltips_get_type void") ;;; 2.11.6 (CFNC "GtkTooltips* gtk_tooltips_new void") ;;; 2.11.6 (CFNC "void gtk_tooltips_enable GtkTooltips* tooltips") ;;; 2.11.6 (CFNC "void gtk_tooltips_disable GtkTooltips* tooltips") ;;; 2.11.6 (CFNC "void gtk_tooltips_set_tip GtkTooltips* tooltips GtkWidget* widget gchar* tip_text gchar* tip_private") ;;; 2.11.6 (CFNC "GtkTooltipsData* gtk_tooltips_data_get GtkWidget* widget") ;;; 2.11.6 (CFNC "void gtk_tooltips_force_window GtkTooltips* tooltips") (CCAST "GTK_TREE_DRAG_SOURCE(obj)" "GtkTreeDragSource*") (CCHK "GTK_IS_TREE_DRAG_SOURCE(obj)" "GtkTreeDragSource*") ;;;;(CFNC "GType gtk_tree_drag_source_get_type void") (CFNC "gboolean gtk_tree_drag_source_row_draggable GtkTreeDragSource* drag_source GtkTreePath* path") (CFNC "gboolean gtk_tree_drag_source_drag_data_delete GtkTreeDragSource* drag_source GtkTreePath* path") (CFNC "gboolean gtk_tree_drag_source_drag_data_get GtkTreeDragSource* drag_source GtkTreePath* path GtkSelectionData* selection_data") (CCAST "GTK_TREE_DRAG_DEST(obj)" "GtkTreeDragDest*") (CCHK "GTK_IS_TREE_DRAG_DEST(obj)" "GtkTreeDragDest*") ;;;;(CFNC "GType gtk_tree_drag_dest_get_type void") (CFNC "gboolean gtk_tree_drag_dest_drag_data_received GtkTreeDragDest* drag_dest GtkTreePath* dest GtkSelectionData* selection_data") (CFNC "gboolean gtk_tree_drag_dest_row_drop_possible GtkTreeDragDest* drag_dest GtkTreePath* dest_path GtkSelectionData* selection_data") (CFNC "gboolean gtk_tree_set_row_drag_data GtkSelectionData* selection_data GtkTreeModel* tree_model GtkTreePath* path") (CFNC "gboolean gtk_tree_get_row_drag_data GtkSelectionData* selection_data GtkTreeModel** [tree_model] GtkTreePath** [path]") (CCAST "GTK_TREE_MODEL(obj)" "GtkTreeModel*") (CCHK "GTK_IS_TREE_MODEL(obj)" "GtkTreeModel*") (CINT "GTK_TREE_MODEL_ITERS_PERSIST" "GtkTreeModelFlags") (CINT "GTK_TREE_MODEL_LIST_ONLY" "GtkTreeModelFlags") (CFNC "GtkTreePath* gtk_tree_path_new void") (CFNC "GtkTreePath* gtk_tree_path_new_from_string gchar* path") ; FREE (CFNC "gchar* gtk_tree_path_to_string GtkTreePath* path" 'free) ;;;(CFNC "GtkTreePath* gtk_tree_path_new_root void") ;;; gone 2.3.2 (CFNC "GtkTreePath* gtk_tree_path_new_first void") (CFNC "void gtk_tree_path_append_index GtkTreePath* path gint index") (CFNC "void gtk_tree_path_prepend_index GtkTreePath* path gint index") (CFNC "gint gtk_tree_path_get_depth GtkTreePath* path") (CFNC "gint* gtk_tree_path_get_indices GtkTreePath* path") (CFNC "void gtk_tree_path_free GtkTreePath* path") (CFNC "GtkTreePath* gtk_tree_path_copy GtkTreePath* path") (CFNC "gint gtk_tree_path_compare GtkTreePath* a GtkTreePath* b") (CFNC "void gtk_tree_path_next GtkTreePath* path") (CFNC "gboolean gtk_tree_path_prev GtkTreePath* path") (CFNC "gboolean gtk_tree_path_up GtkTreePath* path") (CFNC "void gtk_tree_path_down GtkTreePath* path") (CFNC "gboolean gtk_tree_path_is_ancestor GtkTreePath* path GtkTreePath* descendant") (CFNC "gboolean gtk_tree_path_is_descendant GtkTreePath* path GtkTreePath* ancestor") (CFNC "GtkTreeRowReference* gtk_tree_row_reference_new GtkTreeModel* model GtkTreePath* path") ; FREE ;;;;;;; where is this function? (CFNC "GType gtk_tree_row_reference_get_type void") (CFNC "GtkTreeRowReference* gtk_tree_row_reference_new_proxy GObject* proxy GtkTreeModel* model GtkTreePath* path") ; FREE (CFNC "GtkTreePath* gtk_tree_row_reference_get_path GtkTreeRowReference* reference") (CFNC "gboolean gtk_tree_row_reference_valid GtkTreeRowReference* reference") (CFNC "void gtk_tree_row_reference_free GtkTreeRowReference* reference") (CFNC "void gtk_tree_row_reference_inserted GObject* proxy GtkTreePath* path") (CFNC "void gtk_tree_row_reference_deleted GObject* proxy GtkTreePath* path") (CFNC "void gtk_tree_row_reference_reordered GObject* proxy GtkTreePath* path GtkTreeIter* iter gint* new_order") (CFNC "GtkTreeIter* gtk_tree_iter_copy GtkTreeIter* iter") (CFNC "void gtk_tree_iter_free GtkTreeIter* iter") ;;;;(CFNC "GType gtk_tree_model_get_type void") (CFNC "GtkTreeModelFlags gtk_tree_model_get_flags GtkTreeModel* tree_model") (CFNC "gint gtk_tree_model_get_n_columns GtkTreeModel* tree_model") (CFNC "GType gtk_tree_model_get_column_type GtkTreeModel* tree_model gint index") (CFNC "gboolean gtk_tree_model_get_iter GtkTreeModel* tree_model GtkTreeIter* iter GtkTreePath* path") (CFNC "gboolean gtk_tree_model_get_iter_from_string GtkTreeModel* tree_model GtkTreeIter* iter gchar* path_string") ;;; (CFNC "gboolean gtk_tree_model_get_iter_root GtkTreeModel* tree_model GtkTreeIter* iter") ;;; deprecated 2.3.2 (CFNC "gboolean gtk_tree_model_get_iter_first GtkTreeModel* tree_model GtkTreeIter* iter") (CFNC "GtkTreePath* gtk_tree_model_get_path GtkTreeModel* tree_model GtkTreeIter* iter") ;(CFNC "void gtk_tree_model_get_value GtkTreeModel* tree_model GtkTreeIter* iter gint column GValue* value") (CFNC "gboolean gtk_tree_model_iter_next GtkTreeModel* tree_model GtkTreeIter* iter") (CFNC "gboolean gtk_tree_model_iter_children GtkTreeModel* tree_model GtkTreeIter* iter GtkTreeIter* @parent") (CFNC "gboolean gtk_tree_model_iter_has_child GtkTreeModel* tree_model GtkTreeIter* iter") (CFNC "gint gtk_tree_model_iter_n_children GtkTreeModel* tree_model GtkTreeIter* @iter") (CFNC "gboolean gtk_tree_model_iter_nth_child GtkTreeModel* tree_model GtkTreeIter* iter GtkTreeIter* @parent gint n") (CFNC "gboolean gtk_tree_model_iter_parent GtkTreeModel* tree_model GtkTreeIter* iter GtkTreeIter* child") (CFNC "void gtk_tree_model_ref_node GtkTreeModel* tree_model GtkTreeIter* iter") (CFNC "void gtk_tree_model_unref_node GtkTreeModel* tree_model GtkTreeIter* iter") ;;; (CFNC "void gtk_tree_model_get GtkTreeModel* tree_model GtkTreeIter* iter ...") ;;;;(CFNC "void gtk_tree_model_get_valist GtkTreeModel* tree_model GtkTreeIter* iter va_list var_args") (CFNC "void gtk_tree_model_foreach GtkTreeModel* model GtkTreeModelForeachFunc func lambda_data #func_info") (CFNC "void gtk_tree_model_row_changed GtkTreeModel* tree_model GtkTreePath* path GtkTreeIter* iter") (CFNC "void gtk_tree_model_row_inserted GtkTreeModel* tree_model GtkTreePath* path GtkTreeIter* iter") (CFNC "void gtk_tree_model_row_has_child_toggled GtkTreeModel* tree_model GtkTreePath* path GtkTreeIter* iter") (CFNC "void gtk_tree_model_row_deleted GtkTreeModel* tree_model GtkTreePath* path") (CFNC "void gtk_tree_model_rows_reordered GtkTreeModel* tree_model GtkTreePath* path GtkTreeIter* iter gint* new_order") (CCAST "GTK_TREE_MODEL_SORT(obj)" "GtkTreeModelSort*") (CCHK "GTK_IS_TREE_MODEL_SORT(obj)" "GtkTreeModelSort*") ;;;;(CFNC "GType gtk_tree_model_sort_get_type void") (CFNC "GtkTreeModel* gtk_tree_model_sort_new_with_model GtkTreeModel* child_model") (CFNC "GtkTreeModel* gtk_tree_model_sort_get_model GtkTreeModelSort* tree_model") (CFNC "GtkTreePath* gtk_tree_model_sort_convert_child_path_to_path GtkTreeModelSort* tree_model_sort GtkTreePath* child_path") ; FREE (CFNC "void gtk_tree_model_sort_convert_child_iter_to_iter GtkTreeModelSort* tree_model_sort GtkTreeIter* sort_iter GtkTreeIter* child_iter") (CFNC "GtkTreePath* gtk_tree_model_sort_convert_path_to_child_path GtkTreeModelSort* tree_model_sort GtkTreePath* sorted_path") ; FREE (CFNC "void gtk_tree_model_sort_convert_iter_to_child_iter GtkTreeModelSort* tree_model_sort GtkTreeIter* child_iter GtkTreeIter* sorted_iter") (CFNC "void gtk_tree_model_sort_reset_default_sort_func GtkTreeModelSort* tree_model_sort") (CFNC "void gtk_tree_model_sort_clear_cache GtkTreeModelSort* tree_model_sort") (CCAST "GTK_TREE_SELECTION(obj)" "GtkTreeSelection*") (CCHK "GTK_IS_TREE_SELECTION(obj)" "GtkTreeSelection*") ;;;;(CFNC "GType gtk_tree_selection_get_type void") (CFNC "void gtk_tree_selection_set_mode GtkTreeSelection* selection GtkSelectionMode type") (CFNC "GtkSelectionMode gtk_tree_selection_get_mode GtkTreeSelection* selection") (CFNC "void gtk_tree_selection_set_select_function GtkTreeSelection* selection GtkTreeSelectionFunc func lambda_data func_info GtkDestroyNotify destroy") (CFNC "gpointer gtk_tree_selection_get_user_data GtkTreeSelection* selection") (CFNC "GtkTreeView* gtk_tree_selection_get_tree_view GtkTreeSelection* selection") (CFNC "gboolean gtk_tree_selection_get_selected GtkTreeSelection* selection GtkTreeModel** model GtkTreeIter* iter") (CFNC "void gtk_tree_selection_selected_foreach GtkTreeSelection* selection GtkTreeSelectionForeachFunc func lambda_data #func_info") (CFNC "void gtk_tree_selection_select_path GtkTreeSelection* selection GtkTreePath* path") (CFNC "void gtk_tree_selection_unselect_path GtkTreeSelection* selection GtkTreePath* path") (CFNC "void gtk_tree_selection_select_iter GtkTreeSelection* selection GtkTreeIter* iter") (CFNC "void gtk_tree_selection_unselect_iter GtkTreeSelection* selection GtkTreeIter* iter") (CFNC "gboolean gtk_tree_selection_path_is_selected GtkTreeSelection* selection GtkTreePath* path") (CFNC "gboolean gtk_tree_selection_iter_is_selected GtkTreeSelection* selection GtkTreeIter* iter") (CFNC "void gtk_tree_selection_select_all GtkTreeSelection* selection") (CFNC "void gtk_tree_selection_unselect_all GtkTreeSelection* selection") (CFNC "void gtk_tree_selection_select_range GtkTreeSelection* selection GtkTreePath* start_path GtkTreePath* end_path") (CCAST "GTK_TREE_SORTABLE(obj)" "GtkTreeSortable*") (CCHK "GTK_IS_TREE_SORTABLE(obj)" "GtkTreeSortable*") ;;;;(CFNC "GType gtk_tree_sortable_get_type void") (CFNC "void gtk_tree_sortable_sort_column_changed GtkTreeSortable* sortable") (CFNC "gboolean gtk_tree_sortable_get_sort_column_id GtkTreeSortable* sortable gint* [sort_column_id] GtkSortType* [order]") (CFNC "void gtk_tree_sortable_set_sort_column_id GtkTreeSortable* sortable gint sort_column_id GtkSortType order") (CFNC "void gtk_tree_sortable_set_sort_func GtkTreeSortable* sortable gint sort_column_id GtkTreeIterCompareFunc func lambda_data func_info GtkDestroyNotify destroy") ;; typedef void (*GtkCallbackMarshal) (GtkObject *object,gpointer data,guint n_args,GtkArg *args) (CFNC "void gtk_tree_sortable_set_default_sort_func GtkTreeSortable* sortable GtkTreeIterCompareFunc func lambda_data func_info GtkDestroyNotify destroy") (CFNC "gboolean gtk_tree_sortable_has_default_sort_func GtkTreeSortable* sortable") (CCAST "GTK_TREE_STORE(obj)" "GtkTreeStore*") (CCHK "GTK_IS_TREE_STORE(obj)" "GtkTreeStore*") ;;;;(CFNC "GType gtk_tree_store_get_type void") (CFNC-PA "GtkTreeStore* gtk_tree_store_new gint n_columns etc types" 1 6 '("GType")) (CFNC "GtkTreeStore* gtk_tree_store_newv gint n_columns GType* types") (CFNC "void gtk_tree_store_set_column_types GtkTreeStore* tree_store gint n_columns GType* types") ;(CFNC "void gtk_tree_store_set_value GtkTreeStore* tree_store GtkTreeIter* iter gint column GValue* value") (CFNC-PA "void gtk_tree_store_set GtkTreeStore* tree_store GtkTreeIter* iter etc values" 2 10 '("int" "gchar*")) ; just string values for now ;;; any type values here, ideally ;;;;(CFNC "void gtk_tree_store_set_valist GtkTreeStore* tree_store GtkTreeIter* iter va_list var_args") (CFNC "void gtk_tree_store_remove GtkTreeStore* tree_store GtkTreeIter* iter") (CFNC "void gtk_tree_store_insert GtkTreeStore* tree_store GtkTreeIter* iter GtkTreeIter* @parent gint position") (CFNC "void gtk_tree_store_insert_before GtkTreeStore* tree_store GtkTreeIter* iter GtkTreeIter* @parent GtkTreeIter* @sibling") (CFNC "void gtk_tree_store_insert_after GtkTreeStore* tree_store GtkTreeIter* iter GtkTreeIter* @parent GtkTreeIter* @sibling") (CFNC "void gtk_tree_store_prepend GtkTreeStore* tree_store GtkTreeIter* iter GtkTreeIter* @parent") (CFNC "void gtk_tree_store_append GtkTreeStore* tree_store GtkTreeIter* iter GtkTreeIter* @parent") (CFNC "gboolean gtk_tree_store_is_ancestor GtkTreeStore* tree_store GtkTreeIter* iter GtkTreeIter* descendant") (CFNC "gint gtk_tree_store_iter_depth GtkTreeStore* tree_store GtkTreeIter* iter") (CFNC "void gtk_tree_store_clear GtkTreeStore* tree_store") (CCAST "GTK_TREE_VIEW_COLUMN(obj)" "GtkTreeViewColumn*") (CCHK "GTK_IS_TREE_VIEW_COLUMN(obj)" "GtkTreeViewColumn*") (CINT "GTK_TREE_VIEW_COLUMN_GROW_ONLY" "GtkTreeViewColumnSizing") (CINT "GTK_TREE_VIEW_COLUMN_AUTOSIZE" "GtkTreeViewColumnSizing") (CINT "GTK_TREE_VIEW_COLUMN_FIXED" "GtkTreeViewColumnSizing") ;;;;(CFNC "GType gtk_tree_view_column_get_type void") (CFNC "GtkTreeViewColumn* gtk_tree_view_column_new void") (CFNC-PA "GtkTreeViewColumn* gtk_tree_view_column_new_with_attributes gchar* title GtkCellRenderer* cell etc attributes" 2 10 '("gchar*" "int")) (CFNC "void gtk_tree_view_column_pack_start GtkTreeViewColumn* tree_column GtkCellRenderer* cell gboolean expand") (CFNC "void gtk_tree_view_column_pack_end GtkTreeViewColumn* tree_column GtkCellRenderer* cell gboolean expand") (CFNC "void gtk_tree_view_column_clear GtkTreeViewColumn* tree_column") ;;; out 2.17.2 (CFNC "GList* gtk_tree_view_column_get_cell_renderers GtkTreeViewColumn* tree_column") (CFNC "void gtk_tree_view_column_add_attribute GtkTreeViewColumn* tree_column GtkCellRenderer* cell_renderer gchar* attribute gint column") (CFNC-PA "void gtk_tree_view_column_set_attributes GtkTreeViewColumn* tree_column GtkCellRenderer* cell_renderer etc attributes" 2 10 '("gchar*" "int")) (CFNC "void gtk_tree_view_column_set_cell_data_func GtkTreeViewColumn* tree_column GtkCellRenderer* cell_renderer GtkTreeCellDataFunc func lambda_data func_info GtkDestroyNotify destroy") (CFNC "void gtk_tree_view_column_clear_attributes GtkTreeViewColumn* tree_column GtkCellRenderer* cell_renderer") (CFNC "void gtk_tree_view_column_set_spacing GtkTreeViewColumn* tree_column gint spacing") (CFNC "gint gtk_tree_view_column_get_spacing GtkTreeViewColumn* tree_column") (CFNC "void gtk_tree_view_column_set_visible GtkTreeViewColumn* tree_column gboolean visible") (CFNC "gboolean gtk_tree_view_column_get_visible GtkTreeViewColumn* tree_column") (CFNC "void gtk_tree_view_column_set_resizable GtkTreeViewColumn* tree_column gboolean resizable") (CFNC "gboolean gtk_tree_view_column_get_resizable GtkTreeViewColumn* tree_column") (CFNC "void gtk_tree_view_column_set_sizing GtkTreeViewColumn* tree_column GtkTreeViewColumnSizing type") (CFNC "GtkTreeViewColumnSizing gtk_tree_view_column_get_sizing GtkTreeViewColumn* tree_column") (CFNC "gint gtk_tree_view_column_get_width GtkTreeViewColumn* tree_column") (CFNC "gint gtk_tree_view_column_get_fixed_width GtkTreeViewColumn* tree_column") (CFNC "void gtk_tree_view_column_set_fixed_width GtkTreeViewColumn* tree_column gint fixed_width") (CFNC "void gtk_tree_view_column_set_min_width GtkTreeViewColumn* tree_column gint min_width") (CFNC "gint gtk_tree_view_column_get_min_width GtkTreeViewColumn* tree_column") (CFNC "void gtk_tree_view_column_set_max_width GtkTreeViewColumn* tree_column gint max_width") (CFNC "gint gtk_tree_view_column_get_max_width GtkTreeViewColumn* tree_column") (CFNC "void gtk_tree_view_column_clicked GtkTreeViewColumn* tree_column") (CFNC "void gtk_tree_view_column_set_title GtkTreeViewColumn* tree_column gchar* title") (CFNC "gchar* gtk_tree_view_column_get_title GtkTreeViewColumn* tree_column") (CFNC "void gtk_tree_view_column_set_clickable GtkTreeViewColumn* tree_column gboolean clickable") (CFNC "gboolean gtk_tree_view_column_get_clickable GtkTreeViewColumn* tree_column") (CFNC "void gtk_tree_view_column_set_widget GtkTreeViewColumn* tree_column GtkWidget* @widget") (CFNC "GtkWidget* gtk_tree_view_column_get_widget GtkTreeViewColumn* tree_column") (CFNC "void gtk_tree_view_column_set_alignment GtkTreeViewColumn* tree_column gfloat xalign") (CFNC "gfloat gtk_tree_view_column_get_alignment GtkTreeViewColumn* tree_column") (CFNC "void gtk_tree_view_column_set_reorderable GtkTreeViewColumn* tree_column gboolean reorderable") (CFNC "gboolean gtk_tree_view_column_get_reorderable GtkTreeViewColumn* tree_column") (CFNC "void gtk_tree_view_column_set_sort_column_id GtkTreeViewColumn* tree_column gint sort_column_id") (CFNC "gint gtk_tree_view_column_get_sort_column_id GtkTreeViewColumn* tree_column") (CFNC "void gtk_tree_view_column_set_sort_indicator GtkTreeViewColumn* tree_column gboolean setting") (CFNC "gboolean gtk_tree_view_column_get_sort_indicator GtkTreeViewColumn* tree_column") (CFNC "void gtk_tree_view_column_set_sort_order GtkTreeViewColumn* tree_column GtkSortType order") (CFNC "GtkSortType gtk_tree_view_column_get_sort_order GtkTreeViewColumn* tree_column") (CFNC "void gtk_tree_view_column_cell_set_cell_data GtkTreeViewColumn* tree_column GtkTreeModel* tree_model GtkTreeIter* iter gboolean is_expander gboolean is_expanded") (CFNC "void gtk_tree_view_column_cell_get_size GtkTreeViewColumn* tree_column GdkRectangle* cell_area gint* [x_offset] gint* [y_offset] gint* [width] gint* [height]") ;(CFNC "void gtk_tree_view_column_cell_render GtkTreeViewColumn* tree_column GdkWindow* window GdkRectangle* background_area GdkRectangle* cell_area GdkRectangle* expose_area guint flags") ;(CFNC "gboolean gtk_tree_view_column_cell_focus GtkTreeViewColumn* tree_column gint direction") ;(CFNC "void gtk_tree_view_column_cell_draw_focus GtkTreeViewColumn* tree_column GdkWindow* window GdkRectangle* background_area GdkRectangle* cell_area GdkRectangle* expose_area guint flags") (CFNC "gboolean gtk_tree_view_column_cell_is_visible GtkTreeViewColumn* tree_column") ;(CFNC "void gtk_tree_view_column_cell_set_dirty GtkTreeViewColumn* tree_column") (CFNC "gboolean gtk_tree_view_column_cell_get_position GtkTreeViewColumn* tree_column GtkCellRenderer* cell_renderer gint* [start_pos] gint* [width]") (CINT "GTK_TREE_VIEW_DROP_BEFORE" "GtkTreeViewDropPosition") (CINT "GTK_TREE_VIEW_DROP_AFTER" "GtkTreeViewDropPosition") (CINT "GTK_TREE_VIEW_DROP_INTO_OR_BEFORE" "GtkTreeViewDropPosition") (CINT "GTK_TREE_VIEW_DROP_INTO_OR_AFTER" "GtkTreeViewDropPosition") (CCAST "GTK_TREE_VIEW(obj)" "GtkTreeView*") (CCHK "GTK_IS_TREE_VIEW(obj)" "GtkTreeView*") ;;;;(CFNC "GType gtk_tree_view_get_type void") (CFNC "GtkWidget* gtk_tree_view_new void") (CFNC "GtkWidget* gtk_tree_view_new_with_model GtkTreeModel* model") (CFNC "GtkTreeModel* gtk_tree_view_get_model GtkTreeView* tree_view") (CFNC "void gtk_tree_view_set_model GtkTreeView* tree_view GtkTreeModel* @model") (CFNC "GtkTreeSelection* gtk_tree_view_get_selection GtkTreeView* tree_view") ;;; 2.91.2 (CFNC "GtkAdjustment* gtk_tree_view_get_hadjustment GtkTreeView* tree_view") ;;; 2.91.2 (CFNC "void gtk_tree_view_set_hadjustment GtkTreeView* tree_view GtkAdjustment* @adjustment") ;;; 2.91.2 (CFNC "GtkAdjustment* gtk_tree_view_get_vadjustment GtkTreeView* tree_view") ;;; 2.91.2 (CFNC "void gtk_tree_view_set_vadjustment GtkTreeView* tree_view GtkAdjustment* @adjustment") (CFNC "gboolean gtk_tree_view_get_headers_visible GtkTreeView* tree_view") (CFNC "void gtk_tree_view_set_headers_visible GtkTreeView* tree_view gboolean headers_visible") (CFNC "void gtk_tree_view_columns_autosize GtkTreeView* tree_view") (CFNC "void gtk_tree_view_set_headers_clickable GtkTreeView* tree_view gboolean setting") ;;; 3.13.6 (CFNC "void gtk_tree_view_set_rules_hint GtkTreeView* tree_view gboolean setting") ;;; 3.13.6 (CFNC "gboolean gtk_tree_view_get_rules_hint GtkTreeView* tree_view") (CFNC "gint gtk_tree_view_append_column GtkTreeView* tree_view GtkTreeViewColumn* column") (CFNC "gint gtk_tree_view_remove_column GtkTreeView* tree_view GtkTreeViewColumn* column") (CFNC "gint gtk_tree_view_insert_column GtkTreeView* tree_view GtkTreeViewColumn* column gint position") (CFNC-PA "gint gtk_tree_view_insert_column_with_attributes GtkTreeView* tree_view gint position gchar* title GtkCellRenderer* cell etc attributes" 2 10 '("gchar*" "int")) (CFNC "gint gtk_tree_view_insert_column_with_data_func GtkTreeView* tree_view gint position gchar* title GtkCellRenderer* cell GtkTreeCellDataFunc func lambda_data func_info GtkDestroyNotify dnotify") (CFNC "GtkTreeViewColumn* gtk_tree_view_get_column GtkTreeView* tree_view gint n") (CFNC "GList* gtk_tree_view_get_columns GtkTreeView* tree_view") (CFNC "void gtk_tree_view_move_column_after GtkTreeView* tree_view GtkTreeViewColumn* column GtkTreeViewColumn* @base_column") (CFNC "void gtk_tree_view_set_expander_column GtkTreeView* tree_view GtkTreeViewColumn* @column") (CFNC "GtkTreeViewColumn* gtk_tree_view_get_expander_column GtkTreeView* tree_view") (CFNC "void gtk_tree_view_set_column_drag_function GtkTreeView* tree_view GtkTreeViewColumnDropFunc func lambda_data func_info GtkDestroyNotify destroy") (CFNC "void gtk_tree_view_scroll_to_point GtkTreeView* tree_view gint tree_x gint tree_y") (CFNC "void gtk_tree_view_scroll_to_cell GtkTreeView* tree_view GtkTreePath* @path GtkTreeViewColumn* @column gboolean use_align gfloat row_align gfloat col_align") (CFNC "void gtk_tree_view_row_activated GtkTreeView* tree_view GtkTreePath* path GtkTreeViewColumn* column") (CFNC "void gtk_tree_view_expand_all GtkTreeView* tree_view") (CFNC "void gtk_tree_view_collapse_all GtkTreeView* tree_view") (CFNC "gboolean gtk_tree_view_expand_row GtkTreeView* tree_view GtkTreePath* path gboolean open_all") (CFNC "gboolean gtk_tree_view_collapse_row GtkTreeView* tree_view GtkTreePath* path") (CFNC "void gtk_tree_view_map_expanded_rows GtkTreeView* tree_view GtkTreeViewMappingFunc func lambda_data #func_info") (CFNC "gboolean gtk_tree_view_row_expanded GtkTreeView* tree_view GtkTreePath* path") (CFNC "void gtk_tree_view_set_reorderable GtkTreeView* tree_view gboolean reorderable") (CFNC "gboolean gtk_tree_view_get_reorderable GtkTreeView* tree_view") (CFNC "void gtk_tree_view_set_cursor GtkTreeView* tree_view GtkTreePath* path GtkTreeViewColumn* focus_column gboolean start_editing") (CFNC "void gtk_tree_view_get_cursor GtkTreeView* tree_view GtkTreePath** [path] GtkTreeViewColumn** [focus_column]") (CFNC "GdkWindow* gtk_tree_view_get_bin_window GtkTreeView* tree_view") (CFNC "gboolean gtk_tree_view_get_path_at_pos GtkTreeView* tree_view gint x gint y GtkTreePath** [path] GtkTreeViewColumn** [column] gint* [cell_x] gint* [cell_y]") (CFNC "void gtk_tree_view_get_cell_area GtkTreeView* tree_view GtkTreePath* @path GtkTreeViewColumn* @column GdkRectangle* rect") (CFNC "void gtk_tree_view_get_background_area GtkTreeView* tree_view GtkTreePath* @path GtkTreeViewColumn* @column GdkRectangle* rect") (CFNC "void gtk_tree_view_get_visible_rect GtkTreeView* tree_view GdkRectangle* visible_rect") ;;; (out 2.11.3) (CFNC "void gtk_tree_view_widget_to_tree_coords GtkTreeView* tree_view gint wx gint wy gint* [tx] gint* [ty]") ;;; (out 2.11.3) (CFNC "void gtk_tree_view_tree_to_widget_coords GtkTreeView* tree_view gint tx gint ty gint* [wx] gint* [wy]") (CFNC "void gtk_tree_view_enable_model_drag_source GtkTreeView* tree_view GdkModifierType start_button_mask GtkTargetEntry* targets gint n_targets GdkDragAction actions") (CFNC "void gtk_tree_view_enable_model_drag_dest GtkTreeView* tree_view GtkTargetEntry* targets gint n_targets GdkDragAction actions") (CFNC "void gtk_tree_view_unset_rows_drag_source GtkTreeView* tree_view") (CFNC "void gtk_tree_view_unset_rows_drag_dest GtkTreeView* tree_view") (CFNC "void gtk_tree_view_set_drag_dest_row GtkTreeView* tree_view GtkTreePath* path GtkTreeViewDropPosition pos") (CFNC "void gtk_tree_view_get_drag_dest_row GtkTreeView* tree_view GtkTreePath** [path] GtkTreeViewDropPosition* [pos]") (CFNC "gboolean gtk_tree_view_get_dest_row_at_pos GtkTreeView* tree_view gint drag_x gint drag_y GtkTreePath** [path] GtkTreeViewDropPosition* [pos]") ;;; (CFNC-gtk2 "GdkPixmap* gtk_tree_view_create_row_drag_icon GtkTreeView* tree_view GtkTreePath* path") (CFNC "void gtk_tree_view_set_enable_search GtkTreeView* tree_view gboolean enable_search") (CFNC "gboolean gtk_tree_view_get_enable_search GtkTreeView* tree_view") (CFNC "gint gtk_tree_view_get_search_column GtkTreeView* tree_view") (CFNC "void gtk_tree_view_set_search_column GtkTreeView* tree_view gint column") (CFNC "GtkTreeViewSearchEqualFunc gtk_tree_view_get_search_equal_func GtkTreeView* tree_view") (CFNC "void gtk_tree_view_set_search_equal_func GtkTreeView* tree_view GtkTreeViewSearchEqualFunc func lambda_data func_info GtkDestroyNotify search_destroy") ;;;;(CFNC "void gtk_tree_view_set_destroy_count_func GtkTreeView* tree_view GtkTreeDestroyCountFunc func lambda_data func_info GtkDestroyNotify destroy") ;(CCAST2 "GTK_CLASS_NAME(class)") ;(CCAST2 "GTK_CLASS_TYPE(class)") ;(CCAST2 "GTK_FUNDAMENTAL_TYPE") ;(CINT"GTK_STRUCT_OFFSET") ;(CINT "GTK_CHECK_CAST") ;(CINT "GTK_CHECK_CLASS_CAST") ;(CINT "GTK_CHECK_GET_CLASS") ;(CINT "GTK_CHECK_TYPE") ;(CINT "GTK_CHECK_CLASS_TYPE") ;(CFNC "gpointer gtk_type_class GType type") ;(CFNC "GType gtk_type_unique GType parent_type GTypeInfo* gtkinfo") ;(CFNC "gpointer gtk_type_new GType type") ;(CFNC "GtkEnumValue* gtk_type_enum_get_values GType enum_type") ;(CFNC "GtkFlagValue* gtk_type_flags_get_values GType flags_type") ;(CFNC "GtkEnumValue* gtk_type_enum_find_value GType enum_type gchar* value_name") ;(CFNC "GtkFlagValue* gtk_type_flags_find_value GType flags_type gchar* value_name") ;;; 3.1.6 (CCAST "GTK_VBUTTON_BOX(obj)" "GtkVButtonBox*") ;;; 3.1.6 (CCHK "GTK_IS_VBUTTON_BOX(obj)" "GtkVButtonBox*") ;;; 3.1.6 ;;;;(CFNC "GType gtk_vbutton_box_get_type void") ;;; 3.1.6 (CFNC "GtkWidget* gtk_vbutton_box_new void") ;;;; (CINT "GTK_MAJOR_VERSION") ;;;; (CINT "GTK_MINOR_VERSION") ;;;; (CINT "GTK_MICRO_VERSION") ;;;; (CINT "GTK_BINARY_AGE") ;;;; (CINT "GTK_INTERFACE_AGE") (CCAST "GTK_VIEWPORT(obj)" "GtkViewport*") (CCHK "GTK_IS_VIEWPORT(obj)" "GtkViewport*") ;;;;(CFNC "GType gtk_viewport_get_type void") (CFNC "GtkWidget* gtk_viewport_new GtkAdjustment* @hadjustment GtkAdjustment* @vadjustment") ;;; 2.91.2 (CFNC "GtkAdjustment* gtk_viewport_get_hadjustment GtkViewport* viewport") ;;; 2.91.2 (CFNC "GtkAdjustment* gtk_viewport_get_vadjustment GtkViewport* viewport") ;;; 2.91.2 (CFNC "void gtk_viewport_set_hadjustment GtkViewport* viewport GtkAdjustment* @adjustment") ;;; 2.91.2 (CFNC "void gtk_viewport_set_vadjustment GtkViewport* viewport GtkAdjustment* @adjustment") (CFNC "void gtk_viewport_set_shadow_type GtkViewport* viewport GtkShadowType type") (CFNC "GtkShadowType gtk_viewport_get_shadow_type GtkViewport* viewport") ;;; 3.1.6 (CCAST "GTK_VPANED(obj)" "GtkVPaned*") ;;; 3.1.6 (CCHK "GTK_IS_VPANED(obj)" "GtkVPaned*") ;;; 3.1.6 ;;;;(CFNC "GType gtk_vpaned_get_type void") ;;; 3.1.6 (CFNC "GtkWidget* gtk_vpaned_new void") ;;; 2.91.5 (CCAST "GTK_VRULER(obj)" "GtkVRuler*") ;;; 2.91.5 (CCHK "GTK_IS_VRULER(obj)" "GtkVRuler*") ;;;;(CFNC "GType gtk_vruler_get_type void") ;;; 2.91.5 (CFNC "GtkWidget* gtk_vruler_new void") ;;; 3.1.6 (CCAST "GTK_VSCALE(obj)" "GtkVScale*") ;;; 3.1.6 (CCHK "GTK_IS_VSCALE(obj)" "GtkVScale*") ;;; 3.1.6 ;;;;(CFNC "GType gtk_vscale_get_type void") ;;; 3.1.6 (CFNC "GtkWidget* gtk_vscale_new GtkAdjustment* @adjustment") ;;; 3.1.6 (CFNC "GtkWidget* gtk_vscale_new_with_range gdouble min gdouble max gdouble step") ;;; 3.1.6 (CCAST "GTK_VSCROLLBAR(obj)" "GtkVScrollbar*") ;;; 3.1.6 (CCHK "GTK_IS_VSCROLLBAR(obj)" "GtkVScrollbar*") ;;; 3.1.6 ;;;;(CFNC "GType gtk_vscrollbar_get_type void") ;;; 3.1.6 (CFNC "GtkWidget* gtk_vscrollbar_new GtkAdjustment* @adjustment") ;;; 3.1.6 (CCAST "GTK_VSEPARATOR(obj)" "GtkVSeparator*") ;;; 3.1.6 (CCHK "GTK_IS_VSEPARATOR(obj)" "GtkVSeparator*") ;;;;(CFNC "GType gtk_vseparator_get_type void") ;;; 3.1.6 (CFNC "GtkWidget* gtk_vseparator_new void") ;;; all out 2.90.3 ? ;;; 2.91.0 (CINT "GTK_TOPLEVEL" "GtkWidgetFlags") ;;; 2.91.0 (CINT "GTK_NO_WINDOW" "GtkWidgetFlags") ;;; 2.91.0 (CINT "GTK_REALIZED" "GtkWidgetFlags") ;;; 2.91.0 (CINT "GTK_MAPPED" "GtkWidgetFlags") ;;; 2.91.0 (CINT "GTK_VISIBLE" "GtkWidgetFlags") ;;; 2.91.0 (CINT "GTK_SENSITIVE" "GtkWidgetFlags") ;;; 2.91.0 (CINT "GTK_PARENT_SENSITIVE" "GtkWidgetFlags") ;;; 2.91.0 (CINT "GTK_CAN_FOCUS" "GtkWidgetFlags") ;;; 2.91.0 (CINT "GTK_HAS_FOCUS" "GtkWidgetFlags") ;;; 2.91.0 (CINT "GTK_CAN_DEFAULT" "GtkWidgetFlags") ;;; 2.91.0 (CINT "GTK_HAS_DEFAULT" "GtkWidgetFlags") ;;; 2.91.0 (CINT "GTK_HAS_GRAB" "GtkWidgetFlags") ;;; 2.91.0 (CINT "GTK_RC_STYLE" "GtkWidgetFlags") ;;; this is also defined in gtkrc.h ;;; 2.91.0 (CINT "GTK_COMPOSITE_CHILD" "GtkWidgetFlags") ;;; out 2.90.2 (CINT "GTK_NO_REPARENT" "GtkWidgetFlags") ;;; 2.91.0 (CINT "GTK_APP_PAINTABLE" "GtkWidgetFlags") ;;; 2.91.0 (CINT "GTK_RECEIVES_DEFAULT" "GtkWidgetFlags") ;;; 2.91.0 (CINT "GTK_DOUBLE_BUFFERED" "GtkWidgetFlags") ;;; 2.91.0 (CINT "GTK_WIDGET_HELP_TOOLTIP" "GtkWidgetHelpType") ;;; 2.91.0 (CINT "GTK_WIDGET_HELP_WHATS_THIS" "GtkWidgetHelpType") (CCAST "GTK_WIDGET(widget)" "GtkWidget*") (CCHK "GTK_IS_WIDGET(widget)" "GtkWidget*") ;(CCAST2 "GTK_WIDGET_TYPE(wid)") ;;; 2.19.3 (CFNC "int GTK_WIDGET_STATE GtkWidget* wid") ;;; (CFNC "int GTK_WIDGET_SAVED_STATE GtkWidget* wid") ;;; (CFNC "int GTK_WIDGET_FLAGS GtkWidget* wid") ;;; (CFNC "gboolean GTK_WIDGET_TOPLEVEL GtkWidget* wid") ;;; (CFNC "gboolean GTK_WIDGET_NO_WINDOW GtkWidget* wid") ;;; (CFNC "gboolean GTK_WIDGET_REALIZED GtkWidget* wid") ;;; (CFNC "gboolean GTK_WIDGET_MAPPED GtkWidget* wid") ;;; (CFNC "gboolean GTK_WIDGET_VISIBLE GtkWidget* wid") ;;; (CFNC "gboolean GTK_WIDGET_DRAWABLE GtkWidget* wid") ;;; (CFNC "gboolean GTK_WIDGET_SENSITIVE GtkWidget* wid") ;;; (CFNC "gboolean GTK_WIDGET_PARENT_SENSITIVE GtkWidget* wid") ;;; (CFNC "gboolean GTK_WIDGET_IS_SENSITIVE GtkWidget* wid") ;;; (CFNC "gboolean GTK_WIDGET_CAN_FOCUS GtkWidget* wid") ;;; (CFNC "gboolean GTK_WIDGET_HAS_FOCUS GtkWidget* wid") ;;; (CFNC "gboolean GTK_WIDGET_CAN_DEFAULT GtkWidget* wid") ;;; (CFNC "gboolean GTK_WIDGET_HAS_DEFAULT GtkWidget* wid") ;;; (CFNC "gboolean GTK_WIDGET_HAS_GRAB GtkWidget* wid") ;;; (CFNC "gboolean GTK_WIDGET_RC_STYLE GtkWidget* wid") ;;; (CFNC "gboolean GTK_WIDGET_COMPOSITE_CHILD GtkWidget* wid") ;;; (CFNC "gboolean GTK_WIDGET_APP_PAINTABLE GtkWidget* wid") ;;; (CFNC "gboolean GTK_WIDGET_RECEIVES_DEFAULT GtkWidget* wid") ;;; (CFNC "gboolean GTK_WIDGET_DOUBLE_BUFFERED GtkWidget* wid") ;;; (CFNC "void GTK_WIDGET_SET_FLAGS GtkWidget* wid int flag") ;;; (CFNC "void GTK_WIDGET_UNSET_FLAGS GtkWidget* wid int flag") ;;;;(CFNC "GType gtk_widget_get_type void") ;;; (CFNC "GtkWidget* gtk_widget_new GType type gchar* first_property_name ...") ;;; any type vals here ;;; (out 2.11.3) (CFNC "GtkWidget* gtk_widget_ref GtkWidget* widget") ;;; (out 2.11.3) (CFNC "void gtk_widget_unref GtkWidget* widget") (CFNC "void gtk_widget_destroy GtkWidget* widget") (CFNC "void gtk_widget_destroyed GtkWidget* widget GtkWidget** [widget_pointer]") (CFNC "void gtk_widget_unparent GtkWidget* widget") (CFNC "void gtk_widget_show GtkWidget* widget") (CFNC "void gtk_widget_show_now GtkWidget* widget") (CFNC "void gtk_widget_hide GtkWidget* widget") (CFNC "void gtk_widget_show_all GtkWidget* widget") ;;; (CFNC-gtk2 "void gtk_widget_hide_all GtkWidget* widget") (CFNC "void gtk_widget_map GtkWidget* widget") (CFNC "void gtk_widget_unmap GtkWidget* widget") (CFNC "void gtk_widget_realize GtkWidget* widget") (CFNC "void gtk_widget_unrealize GtkWidget* widget") (CFNC "void gtk_widget_queue_draw GtkWidget* widget") (CFNC "void gtk_widget_queue_draw_area GtkWidget* widget gint x gint y gint width gint height") (CFNC "void gtk_widget_queue_resize GtkWidget* widget") ;;; (CFNC-gtk2 "void gtk_widget_size_request GtkWidget* widget GtkRequisition* requisition") (CFNC "void gtk_widget_size_allocate GtkWidget* widget GtkAllocation* allocation") ;;; (CFNC-gtk2 "void gtk_widget_get_child_requisition GtkWidget* widget GtkRequisition* requisition") (CFNC "void gtk_widget_add_accelerator GtkWidget* widget gchar* accel_signal GtkAccelGroup* accel_group guint accel_key GdkModifierType accel_mods GtkAccelFlags accel_flags") (CFNC "gboolean gtk_widget_remove_accelerator GtkWidget* widget GtkAccelGroup* accel_group guint accel_key GdkModifierType accel_mods") (CFNC "GList* gtk_widget_list_accel_closures GtkWidget* widget") ; FREE (g_list_free) (CFNC "gboolean gtk_widget_mnemonic_activate GtkWidget* widget gboolean group_cycling") (CFNC "gboolean gtk_widget_event GtkWidget* widget GdkEvent* event") (CFNC "gint gtk_widget_send_expose GtkWidget* widget GdkEvent* event") (CFNC "gboolean gtk_widget_activate GtkWidget* widget") ;;; 2.91.2 (CFNC "gboolean gtk_widget_set_scroll_adjustments GtkWidget* widget GtkAdjustment* @hadjustment GtkAdjustment* @vadjustment") ;;; 3.13.2 (CFNC "void gtk_widget_reparent GtkWidget* widget GtkWidget* new_parent") (CFNC "gboolean gtk_widget_intersect GtkWidget* widget GdkRectangle* area GdkRectangle* @intersection") ;;; 3.13.2 ;;; (CFNC "GdkRegion* gtk_widget_region_intersect GtkWidget* widget GdkRegion* region") ; FREE (CFNC "void gtk_widget_freeze_child_notify GtkWidget* widget") (CFNC "void gtk_widget_child_notify GtkWidget* widget gchar* child_property") (CFNC "void gtk_widget_thaw_child_notify GtkWidget* widget") (CFNC "gboolean gtk_widget_is_focus GtkWidget* widget") (CFNC "void gtk_widget_grab_focus GtkWidget* widget") (CFNC "void gtk_widget_grab_default GtkWidget* widget") (CFNC "void gtk_widget_set_name GtkWidget* widget gchar* name") (CFNC "gchar* gtk_widget_get_name GtkWidget* widget") ;;; (CFNC "void gtk_widget_set_state GtkWidget* widget GtkStateType state") (CFNC "void gtk_widget_set_sensitive GtkWidget* widget gboolean sensitive") (CFNC "void gtk_widget_set_app_paintable GtkWidget* widget gboolean app_paintable") ;;; 3.13.3 (CFNC "void gtk_widget_set_double_buffered GtkWidget* widget gboolean double_buffered") (CFNC "void gtk_widget_set_redraw_on_allocate GtkWidget* widget gboolean redraw_on_allocate") (CFNC "void gtk_widget_set_parent GtkWidget* widget GtkWidget* parent") (CFNC "void gtk_widget_set_parent_window GtkWidget* widget GdkWindow* parent_window") (CFNC "void gtk_widget_set_child_visible GtkWidget* widget gboolean is_visible") (CFNC "void gtk_widget_set_accel_path GtkWidget* widget gchar* accel_path GtkAccelGroup* accel_group") (CFNC "gboolean gtk_widget_get_child_visible GtkWidget* widget") (CFNC "GtkWidget* gtk_widget_get_parent GtkWidget* widget") (CFNC "GdkWindow* gtk_widget_get_parent_window GtkWidget* widget") (CFNC "gboolean gtk_widget_child_focus GtkWidget* widget GtkDirectionType direction") (CFNC "void gtk_widget_set_size_request GtkWidget* widget gint width gint height") (CFNC "void gtk_widget_get_size_request GtkWidget* widget gint* [width] gint* [height]") (CFNC "void gtk_widget_set_events GtkWidget* widget gint events") (CFNC "void gtk_widget_add_events GtkWidget* widget gint events") ;;;; (CFNC "void gtk_widget_set_extension_events GtkWidget* widget GdkExtensionMode mode") ;;;; (CFNC "GdkExtensionMode gtk_widget_get_extension_events GtkWidget* widget") (CFNC "GtkWidget* gtk_widget_get_toplevel GtkWidget* widget") (CFNC "GtkWidget* gtk_widget_get_ancestor GtkWidget* widget GType widget_type") ;;; (CFNC-gtk2 "GdkColormap* gtk_widget_get_colormap GtkWidget* widget") (CFNC "GdkVisual* gtk_widget_get_visual GtkWidget* widget") (CFNC "GtkSettings* gtk_widget_get_settings GtkWidget* widget") (CFNC "AtkObject* gtk_widget_get_accessible GtkWidget* widget") ;;; (CFNC-gtk2 "void gtk_widget_set_colormap GtkWidget* widget GdkColormap* colormap") (CFNC "gint gtk_widget_get_events GtkWidget* widget") ;;; (CFNC-gtk2 "void gtk_widget_get_pointer GtkWidget* widget gint* [x] gint* [y]") (CFNC "gboolean gtk_widget_is_ancestor GtkWidget* widget GtkWidget* ancestor") (CFNC "gboolean gtk_widget_translate_coordinates GtkWidget* src_widget GtkWidget* dest_widget gint src_x gint src_y gint* [dest_x] gint* [dest_y]") (CFNC "gboolean gtk_widget_hide_on_delete GtkWidget* widget") ;;; (CFNC-gtk2 "void gtk_widget_set_style GtkWidget* widget GtkStyle* @style") ;;; (CFNC-gtk2 "void gtk_widget_ensure_style GtkWidget* widget") ;;; (CFNC-gtk2 "GtkStyle* gtk_widget_get_style GtkWidget* widget") ;;; (CFNC-gtk2 "void gtk_widget_modify_style GtkWidget* widget GtkRcStyle* style") ;;; (CFNC-gtk2 "GtkRcStyle* gtk_widget_get_modifier_style GtkWidget* widget") ;;; (CFNC-gtk2 "void gtk_widget_modify_fg GtkWidget* widget GtkStateType state GdkColor* color") ;;; (CFNC-gtk2 "void gtk_widget_modify_bg GtkWidget* widget GtkStateType state GdkColor* color") ;;; (CFNC-gtk2 "void gtk_widget_modify_text GtkWidget* widget GtkStateType state GdkColor* color") ;;; (CFNC-gtk2 "void gtk_widget_modify_base GtkWidget* widget GtkStateType state GdkColor* color") ;;; (CFNC-gtk2 "void gtk_widget_modify_font GtkWidget* widget PangoFontDescription* font_desc") (CFNC "PangoContext* gtk_widget_create_pango_context GtkWidget* widget") (CFNC "PangoContext* gtk_widget_get_pango_context GtkWidget* widget") (CFNC "PangoLayout* gtk_widget_create_pango_layout GtkWidget* widget gchar* text") ;;; ;;; (CFNC-gtk2 "GdkPixbuf* gtk_widget_render_icon GtkWidget* widget gchar* stock_id GtkIconSize size gchar* detail") ;;; 3.9.0 (CFNC "void gtk_widget_set_composite_name GtkWidget* widget gchar* name") ;;; 3.9.0 (CFNC "gchar* gtk_widget_get_composite_name GtkWidget* widget") ;;; (CFNC-gtk2 "void gtk_widget_reset_rc_styles GtkWidget* widget") ;;; (CFNC-gtk2 "void gtk_widget_push_colormap GdkColormap* cmap") ;;; 3.9.0 (CFNC "void gtk_widget_push_composite_child void") ;;; 3.9.0 (CFNC "void gtk_widget_pop_composite_child void") ;;; (CFNC-gtk2 "void gtk_widget_pop_colormap void") ;(CFNC "void gtk_widget_class_install_style_property GtkWidgetClass* klass GParamSpec* pspec") ;(CFNC "void gtk_widget_class_install_style_property_parser GtkWidgetClass* klass GParamSpec* pspec GtkRcPropertyParser parser") ;(CFNC "void gtk_widget_style_get_property GtkWidget* widget gchar* property_name GValue* value") ;;;;(CFNC "void gtk_widget_style_get_valist GtkWidget* widget gchar* first_property_name va_list var_args") ;;; (CFNC "void gtk_widget_style_get GtkWidget* widget gchar* first_property_name ...") ;;; gtype vals ;;; (CFNC-gtk2 "void gtk_widget_set_default_colormap GdkColormap* colormap") ;;; (CFNC-gtk2 "GtkStyle* gtk_widget_get_default_style void") ;;; (CFNC-gtk2 "GdkColormap* gtk_widget_get_default_colormap void") ;;; (CFNC-gtk2 "GdkVisual* gtk_widget_get_default_visual void") (CFNC "void gtk_widget_set_direction GtkWidget* widget GtkTextDirection dir") (CFNC "GtkTextDirection gtk_widget_get_direction GtkWidget* widget") (CFNC "void gtk_widget_set_default_direction GtkTextDirection dir") (CFNC "GtkTextDirection gtk_widget_get_default_direction void") ;;; (CFNC-gtk2 "void gtk_widget_shape_combine_mask GtkWidget* widget GdkBitmap* @shape_mask gint offset_x gint offset_y") ;;; (CFNC-gtk2 "void gtk_widget_reset_shapes GtkWidget* widget") ;;; ;;; (CFNC-gtk2 "void gtk_widget_path GtkWidget* widget guint* path_length gchar** [path] gchar** [path_reversed]") ;;; ;;; (CFNC-gtk2 "void gtk_widget_class_path GtkWidget* widget guint* path_length gchar** [path] gchar** [path_reversed]") ;;; (CFNC-gtk2 "GtkRequisition* gtk_requisition_copy GtkRequisition* requisition") ;;; (CFNC-gtk2 "void gtk_requisition_free GtkRequisition* requisition") ;;;(CFNC "GtkWidgetAuxInfo* _gtk_widget_get_aux_info GtkWidget* widget gboolean create") ;(CFNC "void gtk_decorated_window_init GtkWindow* window") ;(CFNC "void gtk_decorated_window_calculate_frame_size GtkWindow* window") ;(CFNC "void gtk_decorated_window_set_title GtkWindow* window gchar* title") ;(CFNC "void gtk_decorated_window_move_resize_window GtkWindow* window gint x gint y gint width gint height") (CFNC "gboolean gtk_widget_can_activate_accel GtkWidget* widget guint signal_id") (CFNC "gboolean gtk_window_is_active GtkWindow* window") (CFNC "gboolean gtk_window_has_toplevel_focus GtkWindow* window") (CCAST "GTK_WINDOW(obj)" "GtkWindow*") (CCHK "GTK_IS_WINDOW(obj)" "GtkWindow*") ;;;;(CFNC "GType gtk_window_get_type void") (CFNC "GtkWidget* gtk_window_new GtkWindowType type") (CFNC "void gtk_window_set_title GtkWindow* window gchar* title") (CFNC "void gtk_window_set_auto_startup_notification gboolean setting") (CFNC "gchar* gtk_window_get_title GtkWindow* window") (CFNC "void gtk_window_set_wmclass GtkWindow* window gchar* wmclass_name gchar* wmclass_class") (CFNC "void gtk_window_set_role GtkWindow* window gchar* role") (CFNC "gchar* gtk_window_get_role GtkWindow* window") (CFNC "void gtk_window_add_accel_group GtkWindow* window GtkAccelGroup* accel_group") (CFNC "void gtk_window_remove_accel_group GtkWindow* window GtkAccelGroup* accel_group") (CFNC "void gtk_window_set_position GtkWindow* window GtkWindowPosition position") (CFNC "gboolean gtk_window_activate_focus GtkWindow* window") (CFNC "void gtk_window_set_focus GtkWindow* window GtkWidget* @focus") (CFNC "GtkWidget* gtk_window_get_focus GtkWindow* window") (CFNC "void gtk_window_set_default GtkWindow* window GtkWidget* @default_widget") (CFNC "gboolean gtk_window_activate_default GtkWindow* window") (CFNC "void gtk_window_set_transient_for GtkWindow* window GtkWindow* @parent") (CFNC "GtkWindow* gtk_window_get_transient_for GtkWindow* window") (CFNC "void gtk_window_set_type_hint GtkWindow* window GdkWindowTypeHint hint") (CFNC "GdkWindowTypeHint gtk_window_get_type_hint GtkWindow* window") (CFNC "void gtk_window_set_destroy_with_parent GtkWindow* window gboolean setting") (CFNC "gboolean gtk_window_get_destroy_with_parent GtkWindow* window") (CFNC "void gtk_window_set_resizable GtkWindow* window gboolean resizable") (CFNC "gboolean gtk_window_get_resizable GtkWindow* window") (CFNC "void gtk_window_set_gravity GtkWindow* window GdkGravity gravity") (CFNC "GdkGravity gtk_window_get_gravity GtkWindow* window") (CFNC "void gtk_window_set_geometry_hints GtkWindow* window GtkWidget* geometry_widget GdkGeometry* geometry GdkWindowHints geom_mask") ;;; (CFNC-gtk2 "void gtk_window_set_has_frame GtkWindow* window gboolean setting") ;;; (CFNC-gtk2 "gboolean gtk_window_get_has_frame GtkWindow* window") ;;; (CFNC-gtk2 "void gtk_window_set_frame_dimensions GtkWindow* window gint left gint top gint right gint bottom") ;;; (CFNC-gtk2 "void gtk_window_get_frame_dimensions GtkWindow* window gint* [left] gint* [top] gint* [right] gint* [bottom]") (CFNC "void gtk_window_set_decorated GtkWindow* window gboolean setting") (CFNC "gboolean gtk_window_get_decorated GtkWindow* window") (CFNC "void gtk_window_set_icon_list GtkWindow* window GList* @list") (CFNC "GList* gtk_window_get_icon_list GtkWindow* window") (CFNC "void gtk_window_set_icon GtkWindow* window GdkPixbuf* @icon") (CFNC "GdkPixbuf* gtk_window_get_icon GtkWindow* window") (CFNC "void gtk_window_set_default_icon_list GList* @list") (CFNC "GList* gtk_window_get_default_icon_list void") (CFNC "void gtk_window_set_modal GtkWindow* window gboolean modal") (CFNC "gboolean gtk_window_get_modal GtkWindow* window") (CFNC "GList* gtk_window_list_toplevels void") (CFNC "void gtk_window_add_mnemonic GtkWindow* window guint keyval GtkWidget* target") (CFNC "void gtk_window_remove_mnemonic GtkWindow* window guint keyval GtkWidget* target") (CFNC "gboolean gtk_window_mnemonic_activate GtkWindow* window guint keyval GdkModifierType modifier") (CFNC "void gtk_window_set_mnemonic_modifier GtkWindow* window GdkModifierType modifier") (CFNC "GdkModifierType gtk_window_get_mnemonic_modifier GtkWindow* window") (CFNC "void gtk_window_present GtkWindow* window") (CFNC "void gtk_window_iconify GtkWindow* window") (CFNC "void gtk_window_deiconify GtkWindow* window") (CFNC "void gtk_window_stick GtkWindow* window") (CFNC "void gtk_window_unstick GtkWindow* window") (CFNC "void gtk_window_maximize GtkWindow* window") (CFNC "void gtk_window_unmaximize GtkWindow* window") (CFNC "void gtk_window_begin_resize_drag GtkWindow* window GdkWindowEdge edge gint button gint root_x gint root_y guint32 timestamp") (CFNC "void gtk_window_begin_move_drag GtkWindow* window gint button gint root_x gint root_y guint32 timestamp") (CFNC "void gtk_window_set_default_size GtkWindow* window gint width gint height") (CFNC "void gtk_window_get_default_size GtkWindow* window gint* [width] gint* [height]") (CFNC "void gtk_window_resize GtkWindow* window gint width gint height") (CFNC "void gtk_window_get_size GtkWindow* window gint* [width] gint* [height]") (CFNC "void gtk_window_move GtkWindow* window gint x gint y") (CFNC "void gtk_window_get_position GtkWindow* window gint* [root_x] gint* [root_y]") (CFNC "gboolean gtk_window_parse_geometry GtkWindow* window gchar* geometry") ;;; (CFNC "void gtk_window_reshow_with_initial_size GtkWindow* window") ;;; (CFNC-gtk2 "void gtk_window_remove_embedded_xid GtkWindow* window guint xid") ;;; (CFNC-gtk2 "void gtk_window_add_embedded_xid GtkWindow* window guint xid") ;;;;(CFNC "GType pango_color_get_type void") (CFNC "PangoColor* pango_color_copy PangoColor* src") (CFNC "void pango_color_free PangoColor* color") (CFNC "gboolean pango_color_parse PangoColor* color char* spec") (CINT "PANGO_ATTR_INVALID" "PangoAttrType") (CINT "PANGO_ATTR_LANGUAGE" "PangoAttrType") (CINT "PANGO_ATTR_FAMILY" "PangoAttrType") (CINT "PANGO_ATTR_STYLE" "PangoAttrType") (CINT "PANGO_ATTR_WEIGHT" "PangoAttrType") (CINT "PANGO_ATTR_VARIANT" "PangoAttrType") (CINT "PANGO_ATTR_STRETCH" "PangoAttrType") (CINT "PANGO_ATTR_SIZE" "PangoAttrType") (CINT "PANGO_ATTR_FONT_DESC" "PangoAttrType") (CINT "PANGO_ATTR_FOREGROUND" "PangoAttrType") (CINT "PANGO_ATTR_BACKGROUND" "PangoAttrType") (CINT "PANGO_ATTR_UNDERLINE" "PangoAttrType") (CINT "PANGO_ATTR_STRIKETHROUGH" "PangoAttrType") (CINT "PANGO_ATTR_RISE" "PangoAttrType") (CINT "PANGO_ATTR_SHAPE" "PangoAttrType") (CINT "PANGO_ATTR_SCALE" "PangoAttrType") (CINT "PANGO_UNDERLINE_NONE" "PangoUnderline") (CINT "PANGO_UNDERLINE_SINGLE" "PangoUnderline") (CINT "PANGO_UNDERLINE_DOUBLE" "PangoUnderline") (CINT "PANGO_UNDERLINE_LOW" "PangoUnderline") (CFNC "PangoAttrType pango_attr_type_register gchar* name") (CFNC "PangoAttribute* pango_attribute_copy PangoAttribute* attr") ; FREE (CFNC "void pango_attribute_destroy PangoAttribute* attr") (CFNC "gboolean pango_attribute_equal PangoAttribute* attr1 PangoAttribute* attr2") (CFNC "PangoAttribute* pango_attr_language_new PangoLanguage* language") (CFNC "PangoAttribute* pango_attr_family_new char* family") (CFNC "PangoAttribute* pango_attr_foreground_new guint16 red guint16 green guint16 blue") (CFNC "PangoAttribute* pango_attr_background_new guint16 red guint16 green guint16 blue") (CFNC "PangoAttribute* pango_attr_size_new int size") (CFNC "PangoAttribute* pango_attr_style_new PangoStyle style") (CFNC "PangoAttribute* pango_attr_weight_new PangoWeight weight") (CFNC "PangoAttribute* pango_attr_variant_new PangoVariant variant") (CFNC "PangoAttribute* pango_attr_stretch_new PangoStretch stretch") (CFNC "PangoAttribute* pango_attr_font_desc_new PangoFontDescription* desc") (CFNC "PangoAttribute* pango_attr_underline_new PangoUnderline underline") (CFNC "PangoAttribute* pango_attr_strikethrough_new gboolean strikethrough") (CFNC "PangoAttribute* pango_attr_rise_new int rise") (CFNC "PangoAttribute* pango_attr_shape_new PangoRectangle* ink_rect PangoRectangle* logical_rect") ; FREE (CFNC "PangoAttribute* pango_attr_scale_new double scale_factor") ;;;;(CFNC "GType pango_attr_list_get_type void") (CFNC "PangoAttrList* pango_attr_list_new void") ; FREE ;;; (CFNC "void pango_attr_list_ref PangoAttrList* list") ;;; changed in 1.9.1 (CFNC "void pango_attr_list_unref PangoAttrList* list") (CFNC "PangoAttrList* pango_attr_list_copy PangoAttrList* list") (CFNC "void pango_attr_list_insert PangoAttrList* list PangoAttribute* attr") (CFNC "void pango_attr_list_insert_before PangoAttrList* list PangoAttribute* attr") (CFNC "void pango_attr_list_change PangoAttrList* list PangoAttribute* attr") (CFNC "void pango_attr_list_splice PangoAttrList* list PangoAttrList* other gint pos gint len") (CFNC "PangoAttrIterator* pango_attr_list_get_iterator PangoAttrList* list") (CFNC "void pango_attr_iterator_range PangoAttrIterator* iterator gint* [start] gint* [end]") (CFNC "gboolean pango_attr_iterator_next PangoAttrIterator* iterator") (CFNC "PangoAttrIterator* pango_attr_iterator_copy PangoAttrIterator* iterator") (CFNC "void pango_attr_iterator_destroy PangoAttrIterator* iterator") (CFNC "PangoAttribute* pango_attr_iterator_get PangoAttrIterator* iterator PangoAttrType type") (CFNC "void pango_attr_iterator_get_font PangoAttrIterator* iterator PangoFontDescription* desc PangoLanguage** [language] GSList** [extra_attrs]") (CFNC "gboolean pango_parse_markup char* markup_text int length gunichar accel_marker PangoAttrList** attr_list char** text gunichar* accel_char GError** [error]") (CFNC "void pango_break gchar* text int length PangoAnalysis* analysis PangoLogAttr* attrs int attrs_len") (CFNC "void pango_find_paragraph_boundary gchar* text gint length gint* [paragraph_delimiter_index] gint* [next_paragraph_start]") (CFNC "void pango_get_log_attrs char* text int length int level PangoLanguage* language PangoLogAttr* log_attrs int attrs_len") ;(CFNC-extra "void pango_default_break gchar* text int length PangoAnalysis* analysis PangoLogAttr* attrs int attrs_len") (CCAST "PANGO_CONTEXT(object)" "PangoContext*") ;(cdef "PANGO_CONTEXT_CLASS(klass)") (CCHK "PANGO_IS_CONTEXT(object)" "PangoContext*") ;(cdef "PANGO_CONTEXT_GET_CLASS(obj)") ;;;;(CFNC "GType pango_context_get_type void") ;;; (CFNC "PangoContext* pango_context_new void") ;backend (CFNC "void pango_context_list_families PangoContext* context PangoFontFamily*** [families] int* [n_families]") ; FREE (families) (CFNC "PangoFont* pango_context_load_font PangoContext* context PangoFontDescription* desc") (CFNC "PangoFontset* pango_context_load_fontset PangoContext* context PangoFontDescription* desc PangoLanguage* language") (CFNC "PangoFontMetrics* pango_context_get_metrics PangoContext* context PangoFontDescription* desc PangoLanguage* language") (CFNC "void pango_context_set_font_description PangoContext* context PangoFontDescription* desc") (CFNC "PangoFontDescription* pango_context_get_font_description PangoContext* context") (CFNC "PangoLanguage* pango_context_get_language PangoContext* context") (CFNC "void pango_context_set_language PangoContext* context PangoLanguage* language") (CFNC "void pango_context_set_base_dir PangoContext* context PangoDirection direction") (CFNC "PangoDirection pango_context_get_base_dir PangoContext* context") (CFNC "GList* pango_itemize PangoContext* context char* text int start_index int length PangoAttrList* attrs PangoAttrIterator* cached_iter") (CINT "PANGO_COVERAGE_NONE" "PangoCoverageLevel") (CINT "PANGO_COVERAGE_FALLBACK" "PangoCoverageLevel") (CINT "PANGO_COVERAGE_APPROXIMATE" "PangoCoverageLevel") (CINT "PANGO_COVERAGE_EXACT" "PangoCoverageLevel") (CFNC "PangoCoverage* pango_coverage_new void") (CFNC "PangoCoverage* pango_coverage_ref PangoCoverage* coverage") (CFNC "void pango_coverage_unref PangoCoverage* coverage") (CFNC "PangoCoverage* pango_coverage_copy PangoCoverage* coverage") (CFNC "PangoCoverageLevel pango_coverage_get PangoCoverage* coverage int index") (CFNC "void pango_coverage_set PangoCoverage* coverage int index PangoCoverageLevel level") (CFNC "void pango_coverage_max PangoCoverage* coverage PangoCoverage* other") (CFNC "void pango_coverage_to_bytes PangoCoverage* coverage guchar** [bytes] int* [n_bytes]") ; FREE (bytes) (CFNC "PangoCoverage* pango_coverage_from_bytes guchar* bytes int n_bytes") ; FREE ;(CSTR-extra "PANGO_ENGINE_TYPE_LANG") ;(CSTR-extra "PANGO_ENGINE_TYPE_SHAPE") ;(CSTR-extra "PANGO_RENDER_TYPE_NONE") ;(CFNC "void script_engine_list PangoEngineInfo** [engines] int* [n_engines]") ;(CFNC "PangoEngine* script_engine_load char* id") ;(CFNC "void script_engine_unload PangoEngine* engine") ;;;;(CFNC "GType pango_attr_type_get_type void") ;;;;(CFNC "GType pango_underline_get_type void") ;;;;(CFNC "GType pango_coverage_level_get_type void") ;;;;(CFNC "GType pango_style_get_type void") ;;;;(CFNC "GType pango_variant_get_type void") ;;;;(CFNC "GType pango_weight_get_type void") ;;;;(CFNC "GType pango_stretch_get_type void") ;;;;(CFNC "GType pango_font_mask_get_type void") ;;;;(CFNC "GType pango_alignment_get_type void") ;;;;(CFNC "GType pango_wrap_mode_get_type void") ;;;;(CFNC "GType pango_tab_align_get_type void") ;;;;(CFNC "GType pango_direction_get_type void") (CINT "PANGO_STYLE_NORMAL" "PangoStyle") (CINT "PANGO_STYLE_OBLIQUE" "PangoStyle") (CINT "PANGO_STYLE_ITALIC" "PangoStyle") (CINT "PANGO_VARIANT_NORMAL" "PangoVariant") (CINT "PANGO_VARIANT_SMALL_CAPS" "PangoVariant") (CINT "PANGO_WEIGHT_ULTRALIGHT" "PangoWeight") (CINT "PANGO_WEIGHT_LIGHT" "PangoWeight") (CINT "PANGO_WEIGHT_NORMAL" "PangoWeight") (CINT "PANGO_WEIGHT_BOLD" "PangoWeight") (CINT "PANGO_WEIGHT_ULTRABOLD" "PangoWeight") (CINT "PANGO_WEIGHT_HEAVY" "PangoWeight") (CINT "PANGO_STRETCH_ULTRA_CONDENSED" "PangoStretch") (CINT "PANGO_STRETCH_EXTRA_CONDENSED" "PangoStretch") (CINT "PANGO_STRETCH_CONDENSED" "PangoStretch") (CINT "PANGO_STRETCH_SEMI_CONDENSED" "PangoStretch") (CINT "PANGO_STRETCH_NORMAL" "PangoStretch") (CINT "PANGO_STRETCH_SEMI_EXPANDED" "PangoStretch") (CINT "PANGO_STRETCH_EXPANDED" "PangoStretch") (CINT "PANGO_STRETCH_EXTRA_EXPANDED" "PangoStretch") (CINT "PANGO_STRETCH_ULTRA_EXPANDED" "PangoStretch") (CINT "PANGO_FONT_MASK_FAMILY" "PangoFontMask") (CINT "PANGO_FONT_MASK_STYLE" "PangoFontMask") (CINT "PANGO_FONT_MASK_VARIANT" "PangoFontMask") (CINT "PANGO_FONT_MASK_WEIGHT" "PangoFontMask") (CINT "PANGO_FONT_MASK_STRETCH" "PangoFontMask") (CINT "PANGO_FONT_MASK_SIZE" "PangoFontMask") (CDBL "PANGO_SCALE_XX_SMALL") (CDBL "PANGO_SCALE_X_SMALL") (CDBL "PANGO_SCALE_SMALL") (CDBL "PANGO_SCALE_MEDIUM") (CDBL "PANGO_SCALE_LARGE") (CDBL "PANGO_SCALE_X_LARGE") (CDBL "PANGO_SCALE_XX_LARGE") ;;;;(CFNC "GType pango_font_description_get_type void") (CFNC "PangoFontDescription* pango_font_description_new void") (CFNC "PangoFontDescription* pango_font_description_copy PangoFontDescription* desc") ; FREE with pango_font_description_free (CFNC "PangoFontDescription* pango_font_description_copy_static PangoFontDescription* desc") ; FREE with pango_font_description_free (CFNC "guint pango_font_description_hash PangoFontDescription* desc") (CFNC "gboolean pango_font_description_equal PangoFontDescription* desc1 PangoFontDescription* desc2") (CFNC "void pango_font_description_free PangoFontDescription* desc") (CFNC "void pango_font_descriptions_free PangoFontDescription** descs int n_descs") (CFNC "void pango_font_description_set_family PangoFontDescription* desc char* family") (CFNC "void pango_font_description_set_family_static PangoFontDescription* desc char* family") (CFNC "char* pango_font_description_get_family PangoFontDescription* desc") (CFNC "void pango_font_description_set_style PangoFontDescription* desc PangoStyle style") (CFNC "PangoStyle pango_font_description_get_style PangoFontDescription* desc") (CFNC "void pango_font_description_set_variant PangoFontDescription* desc PangoVariant variant") (CFNC "PangoVariant pango_font_description_get_variant PangoFontDescription* desc") (CFNC "void pango_font_description_set_weight PangoFontDescription* desc PangoWeight weight") (CFNC "PangoWeight pango_font_description_get_weight PangoFontDescription* desc") (CFNC "void pango_font_description_set_stretch PangoFontDescription* desc PangoStretch stretch") (CFNC "PangoStretch pango_font_description_get_stretch PangoFontDescription* desc") (CFNC "void pango_font_description_set_size PangoFontDescription* desc gint size") (CFNC "gint pango_font_description_get_size PangoFontDescription* desc") (CFNC "PangoFontMask pango_font_description_get_set_fields PangoFontDescription* desc") (CFNC "void pango_font_description_unset_fields PangoFontDescription* desc PangoFontMask to_unset") (CFNC "void pango_font_description_merge PangoFontDescription* desc PangoFontDescription* desc_to_merge gboolean replace_existing") (CFNC "void pango_font_description_merge_static PangoFontDescription* desc PangoFontDescription* desc_to_merge gboolean replace_existing") (CFNC "gboolean pango_font_description_better_match PangoFontDescription* desc PangoFontDescription* old_match PangoFontDescription* new_match") (CFNC "PangoFontDescription* pango_font_description_from_string char* str") (CFNC "char* pango_font_description_to_string PangoFontDescription* desc" 'free) (CFNC "char* pango_font_description_to_filename PangoFontDescription* desc" 'free) ;;;;(CFNC "GType pango_font_metrics_get_type void") (CFNC "PangoFontMetrics* pango_font_metrics_ref PangoFontMetrics* metrics") (CFNC "void pango_font_metrics_unref PangoFontMetrics* metrics") (CFNC "int pango_font_metrics_get_ascent PangoFontMetrics* metrics") (CFNC "int pango_font_metrics_get_descent PangoFontMetrics* metrics") (CFNC "int pango_font_metrics_get_approximate_char_width PangoFontMetrics* metrics") (CFNC "int pango_font_metrics_get_approximate_digit_width PangoFontMetrics* metrics") ;;; (CFNC "PangoFontMetrics* pango_font_metrics_new void") ; backend (CCAST "PANGO_FONT_FAMILY(object)" "PangoFontFamily*") (CCHK "PANGO_IS_FONT_FAMILY(object)" "PangoFontFamily*") ;;;;(CFNC "GType pango_font_family_get_type void") (CFNC "void pango_font_family_list_faces PangoFontFamily* family PangoFontFace*** [faces] int* [n_faces]") (CFNC "char* pango_font_family_get_name PangoFontFamily* family") (CCAST "PANGO_FONT_FACE(object)" "PangoFontFace*") (CCHK "PANGO_IS_FONT_FACE(object)" "PangoFontFace*") ;;;;(CFNC "GType pango_font_face_get_type void") (CFNC "PangoFontDescription* pango_font_face_describe PangoFontFace* face") (CFNC "char* pango_font_face_get_face_name PangoFontFace* face") (CCAST "PANGO_FONT(object)" "PangoFont*") (CCHK "PANGO_IS_FONT(object)" "PangoFont*") ;;;;(CFNC "GType pango_font_get_type void") (CFNC "PangoFontDescription* pango_font_describe PangoFont* font") (CFNC "PangoCoverage* pango_font_get_coverage PangoFont* font PangoLanguage* language") ;(CFNC "PangoEngineShape* pango_font_find_shaper PangoFont* font PangoLanguage* language guint32 ch") (CFNC "PangoFontMetrics* pango_font_get_metrics PangoFont* font PangoLanguage* language") (CFNC "void pango_font_get_glyph_extents PangoFont* font PangoGlyph glyph PangoRectangle* ink_rect PangoRectangle* logical_rect") (CCAST "PANGO_FONT_MAP(object)" "PangoFontMap*") (CCHK "PANGO_IS_FONT_MAP(object)" "PangoFontMap*") ;;;;(CFNC "GType pango_font_map_get_type void") (CFNC "PangoFont* pango_font_map_load_font PangoFontMap* fontmap PangoContext* context PangoFontDescription* desc") (CFNC "PangoFontset* pango_font_map_load_fontset PangoFontMap* fontmap PangoContext* context PangoFontDescription* desc PangoLanguage* language") (CFNC "void pango_font_map_list_families PangoFontMap* fontmap PangoFontFamily*** [families] int* [n_families]") ; FREE (families) ;;; (CFNC "void pango_context_set_font_map PangoContext* context PangoFontMap* font_map") ;backend (CFNC "PangoGlyphString* pango_glyph_string_new void") (CFNC "void pango_glyph_string_set_size PangoGlyphString* string gint new_len") ;;;;(CFNC "GType pango_glyph_string_get_type void") (CFNC "PangoGlyphString* pango_glyph_string_copy PangoGlyphString* string") (CFNC "void pango_glyph_string_free PangoGlyphString* string") (CFNC "void pango_glyph_string_extents PangoGlyphString* glyphs PangoFont* font PangoRectangle* ink_rect PangoRectangle* logical_rect") (CFNC "void pango_glyph_string_extents_range PangoGlyphString* glyphs int start int end PangoFont* font PangoRectangle* ink_rect PangoRectangle* logical_rect") (CFNC "void pango_glyph_string_get_logical_widths PangoGlyphString* glyphs char* text int length int embedding_level int* [logical_widths]") (CFNC "void pango_glyph_string_index_to_x PangoGlyphString* glyphs char* text int length PangoAnalysis* analysis int index gboolean trailing int* [x_pos]") (CFNC "void pango_glyph_string_x_to_index PangoGlyphString* glyphs char* text int length PangoAnalysis* analysis int x_pos int* [index] int* [trailing]") (CFNC "void pango_shape gchar* text gint length PangoAnalysis* analysis PangoGlyphString* glyphs") (CFNC "GList* pango_reorder_items GList* logical_items") (CFNC "PangoItem* pango_item_new void") (CFNC "PangoItem* pango_item_copy PangoItem* item") (CFNC "void pango_item_free PangoItem* item") (CFNC "PangoItem* pango_item_split PangoItem* orig int split_index int split_offset") (CINT "PANGO_ALIGN_LEFT" "PangoAlignment") (CINT "PANGO_ALIGN_CENTER" "PangoAlignment") (CINT "PANGO_ALIGN_RIGHT" "PangoAlignment") (CINT "PANGO_WRAP_WORD" "PangoWrapMode") (CINT "PANGO_WRAP_CHAR" "PangoWrapMode") (CCAST "PANGO_LAYOUT(object)" "PangoLayout*") (CCHK "PANGO_IS_LAYOUT(object)" "PangoLayout*") ;;;;(CFNC "GType pango_layout_get_type void") (CFNC "PangoLayout* pango_layout_new PangoContext* context") (CFNC "PangoLayout* pango_layout_copy PangoLayout* src") (CFNC "PangoContext* pango_layout_get_context PangoLayout* layout") (CFNC "void pango_layout_set_attributes PangoLayout* layout PangoAttrList* attrs") (CFNC "PangoAttrList* pango_layout_get_attributes PangoLayout* layout") (CFNC "void pango_layout_set_text PangoLayout* layout char* text int length") (CFNC "char* pango_layout_get_text PangoLayout* layout") (CFNC "void pango_layout_set_markup PangoLayout* layout char* markup int length") (CFNC "void pango_layout_set_markup_with_accel PangoLayout* layout char* markup int length gunichar accel_marker gunichar* accel_char") (CFNC "void pango_layout_set_font_description PangoLayout* layout PangoFontDescription* desc") (CFNC "void pango_layout_set_width PangoLayout* layout int width") (CFNC "int pango_layout_get_width PangoLayout* layout") (CFNC "void pango_layout_set_wrap PangoLayout* layout PangoWrapMode wrap") (CFNC "PangoWrapMode pango_layout_get_wrap PangoLayout* layout") (CFNC "void pango_layout_set_indent PangoLayout* layout int indent") (CFNC "int pango_layout_get_indent PangoLayout* layout") (CFNC "void pango_layout_set_spacing PangoLayout* layout int spacing") (CFNC "int pango_layout_get_spacing PangoLayout* layout") (CFNC "void pango_layout_set_justify PangoLayout* layout gboolean justify") (CFNC "gboolean pango_layout_get_justify PangoLayout* layout") (CFNC "void pango_layout_set_alignment PangoLayout* layout PangoAlignment alignment") (CFNC "PangoAlignment pango_layout_get_alignment PangoLayout* layout") (CFNC "void pango_layout_set_tabs PangoLayout* layout PangoTabArray* @tabs") (CFNC "PangoTabArray* pango_layout_get_tabs PangoLayout* layout") (CFNC "void pango_layout_set_single_paragraph_mode PangoLayout* layout gboolean setting") (CFNC "gboolean pango_layout_get_single_paragraph_mode PangoLayout* layout") (CFNC "void pango_layout_context_changed PangoLayout* layout") (CFNC "void pango_layout_get_log_attrs PangoLayout* layout PangoLogAttr** [attrs] gint* [n_attrs]") ; FREE (attrs) (CFNC "void pango_layout_index_to_pos PangoLayout* layout int index PangoRectangle* pos") (CFNC "void pango_layout_get_cursor_pos PangoLayout* layout int index PangoRectangle* strong_pos PangoRectangle* weak_pos") (CFNC "void pango_layout_move_cursor_visually PangoLayout* layout gboolean strong int old_index int old_trailing int direction int* new_index int* new_trailing") (CFNC "gboolean pango_layout_xy_to_index PangoLayout* layout int x int y int* [index] int* [trailing]") (CFNC "void pango_layout_get_extents PangoLayout* layout PangoRectangle* ink_rect PangoRectangle* logical_rect") (CFNC "void pango_layout_get_pixel_extents PangoLayout* layout PangoRectangle* ink_rect PangoRectangle* logical_rect") (CFNC "void pango_layout_get_size PangoLayout* layout int* [width] int* [height]") (CFNC "void pango_layout_get_pixel_size PangoLayout* layout int* [width] int* [height]") (CFNC "int pango_layout_get_line_count PangoLayout* layout") (CFNC "PangoLayoutLine* pango_layout_get_line PangoLayout* layout int line") (CFNC "GSList* pango_layout_get_lines PangoLayout* layout") ;;; (CFNC "void pango_layout_line_ref PangoLayoutLine* line") ;;; changed 1.9 or thereabouts (CFNC "void pango_layout_line_unref PangoLayoutLine* line") (CFNC "gboolean pango_layout_line_x_to_index PangoLayoutLine* line int x_pos int* [index] int* [trailing]") (CFNC "void pango_layout_line_index_to_x PangoLayoutLine* line int index gboolean trailing int* [x_pos]") (CFNC "void pango_layout_line_get_x_ranges PangoLayoutLine* line int start_index int end_index int** [ranges] int* [n_ranges]") ; FREE (ranges) (CFNC "void pango_layout_line_get_extents PangoLayoutLine* line PangoRectangle* ink_rect PangoRectangle* logical_rect") (CFNC "void pango_layout_line_get_pixel_extents PangoLayoutLine* layout_line PangoRectangle* ink_rect PangoRectangle* logical_rect") (CFNC "PangoLayoutIter* pango_layout_get_iter PangoLayout* layout") (CFNC "void pango_layout_iter_free PangoLayoutIter* iter") (CFNC "int pango_layout_iter_get_index PangoLayoutIter* iter") (CFNC "PangoLayoutRun* pango_layout_iter_get_run PangoLayoutIter* iter") (CFNC "PangoLayoutLine* pango_layout_iter_get_line PangoLayoutIter* iter") (CFNC "gboolean pango_layout_iter_at_last_line PangoLayoutIter* iter") (CFNC "gboolean pango_layout_iter_next_char PangoLayoutIter* iter") (CFNC "gboolean pango_layout_iter_next_cluster PangoLayoutIter* iter") (CFNC "gboolean pango_layout_iter_next_run PangoLayoutIter* iter") (CFNC "gboolean pango_layout_iter_next_line PangoLayoutIter* iter") (CFNC "void pango_layout_iter_get_char_extents PangoLayoutIter* iter PangoRectangle* logical_rect") (CFNC "void pango_layout_iter_get_cluster_extents PangoLayoutIter* iter PangoRectangle* ink_rect PangoRectangle* logical_rect") (CFNC "void pango_layout_iter_get_run_extents PangoLayoutIter* iter PangoRectangle* ink_rect PangoRectangle* logical_rect") (CFNC "void pango_layout_iter_get_line_extents PangoLayoutIter* iter PangoRectangle* ink_rect PangoRectangle* logical_rect") (CFNC "void pango_layout_iter_get_line_yrange PangoLayoutIter* iter int* [y0] int* [y1]") (CFNC "void pango_layout_iter_get_layout_extents PangoLayoutIter* iter PangoRectangle* ink_rect PangoRectangle* logical_rect") (CFNC "int pango_layout_iter_get_baseline PangoLayoutIter* iter") ;(CFNC "int PANGO_ASCENT PangoRectangle rect)") ;(CFNC "int PANGO_DESCENT PangoRectangle rect)") ;(CFNC "int PANGO_LBEARING PangoRectangle rect)") ;(CFNC "int PANGO_RBEARING PangoRectangle rect)") (CINT "PANGO_DIRECTION_LTR" "PangoDirection") (CINT "PANGO_DIRECTION_RTL" "PangoDirection") (CINT "PANGO_DIRECTION_TTB_LTR" "PangoDirection") (CINT "PANGO_DIRECTION_TTB_RTL" "PangoDirection") ;;;;(CFNC "GType pango_language_get_type void") (CFNC "PangoLanguage* pango_language_from_string char* language") (CFNC "gboolean pango_language_matches PangoLanguage* language char* range_list") ;;; are these of any use?? ;;; 2.91.6 (CLNG "GTK_TYPE_ACCEL_GROUP") ;;; 2.91.6 (CLNG "GTK_TYPE_ACCEL_LABEL") ;;; 2.91.6 (CLNG "GTK_TYPE_ACCESSIBLE") ;;; 2.91.6 (CLNG "GTK_TYPE_ADJUSTMENT") ;;; 2.91.6 (CLNG "GTK_TYPE_ALIGNMENT") ;;; 2.91.6 (CLNG "GTK_TYPE_ARROW") ;;; 2.91.6 (CLNG "GTK_TYPE_ASPECT_FRAME") ;;; 2.91.6 (CLNG "GTK_TYPE_BUTTON_BOX") ;;; 2.91.6 (CLNG "GTK_TYPE_BIN") ;;; 2.91.6 (CLNG "GTK_TYPE_BOX") ;;; 2.91.6 (CLNG "GTK_TYPE_BUTTON") ;;; 2.91.6 (CLNG "GTK_TYPE_CALENDAR") ;;; 2.91.6 (CLNG "GTK_TYPE_CELL_EDITABLE") ;;; 2.91.6 (CLNG "GTK_TYPE_CELL_RENDERER") ;;; 2.91.6 (CLNG "GTK_TYPE_CELL_RENDERER_PIXBUF") ;;; 2.91.6 (CLNG "GTK_TYPE_CELL_RENDERER_TEXT") ;;; 2.91.6 (CLNG "GTK_TYPE_CELL_RENDERER_TOGGLE") ;;; 2.91.6 (CLNG "GTK_TYPE_CHECK_BUTTON") ;;; 2.91.6 (CLNG "GTK_TYPE_CHECK_MENU_ITEM") ;;; 2.91.6 (CLNG "GTK_TYPE_COLOR_SELECTION_DIALOG") ;;; 2.91.6 (CLNG "GTK_TYPE_COLOR_SELECTION") ;;; 2.91.6 ;;; out 2.3 (CLNG "GTK_TYPE_COMBO") ;;; 2.91.6 (CLNG "GTK_TYPE_CONTAINER") ;;; 2.91.6 ;;; (CLNG "GTK_TYPE_CURVE") ;;; 2.91.6 (CLNG "GTK_TYPE_DIALOG") ;;; 2.91.6 (CLNG "GTK_TYPE_DRAWING_AREA") ;;; 2.91.6 (CLNG "GTK_TYPE_EDITABLE") ;;; 2.91.6 (CLNG "GTK_TYPE_ENTRY") ;;; 2.91.6 (CLNG "GTK_TYPE_EVENT_BOX") ;;; 2.91.6 ;;; (CLNG "GTK_TYPE_FILE_SELECTION") ;;; 2.91.6 (CLNG "GTK_TYPE_FIXED") ;;; 2.91.6 (CLNG "GTK_TYPE_FONT_SELECTION") ;;; 2.91.6 (CLNG "GTK_TYPE_FONT_SELECTION_DIALOG") ;;; 2.91.6 (CLNG "GTK_TYPE_FRAME") ;;; 2.91.6 ;;; (CLNG "GTK_TYPE_GAMMA_CURVE") ;;; 2.91.6 (CLNG "GTK_TYPE_HANDLE_BOX") ;;; 2.91.6 (CLNG "GTK_TYPE_HBUTTON_BOX") ;;; 2.91.6 (CLNG "GTK_TYPE_HBOX") ;;; 2.91.6 (CLNG "GTK_TYPE_HPANED") ;;; 2.91.6 ;;; 2.91.5 (CLNG "GTK_TYPE_HRULER") ;;; 2.91.6 (CLNG "GTK_TYPE_HSCALE") ;;; 2.91.6 (CLNG "GTK_TYPE_HSCROLLBAR") ;;; 2.91.6 (CLNG "GTK_TYPE_HSEPARATOR") ;;; 2.91.6 ;;; out 2.3 (CLNG "GTK_TYPE_ICON_FACTORY") ;;; 2.91.6 (CLNG "GTK_TYPE_IMAGE") ;;; 2.91.6 (CLNG "GTK_TYPE_IMAGE_MENU_ITEM") ;;; 2.91.6 (CLNG "GTK_TYPE_IM_CONTEXT") ;;; 2.91.6 (CLNG "GTK_TYPE_IM_CONTEXT_SIMPLE") ;;; 2.91.6 (CLNG "GTK_TYPE_IM_MULTICONTEXT") ;;; 2.91.6 ;;; (CLNG "GTK_TYPE_INPUT_DIALOG") ;;; 2.91.6 (CLNG "GTK_TYPE_INVISIBLE") ;;; 2.91.6 ;;; out 2.3 (CLNG "GTK_TYPE_ITEM_FACTORY") ;;; 2.91.6 ;;; 2.90.7 (CLNG "GTK_TYPE_ITEM") ;;; 2.91.6 (CLNG "GTK_TYPE_LABEL") ;;; 2.91.6 (CLNG "GTK_TYPE_LAYOUT") ;;; 2.91.6 (CLNG "GTK_TYPE_LIST_STORE") ;;; 2.91.6 (CLNG "GTK_TYPE_MENU_BAR") ;;; 2.91.6 (CLNG "GTK_TYPE_MENU") ;;; 2.91.6 (CLNG "GTK_TYPE_MENU_ITEM") ;;; 2.91.6 (CLNG "GTK_TYPE_MENU_SHELL") ;;; 2.91.6 (CLNG "GTK_TYPE_MESSAGE_DIALOG") ;;; 2.91.6 (CLNG "GTK_TYPE_MISC") ;;; 2.91.6 (CLNG "GTK_TYPE_NOTEBOOK") ;;; 2.91.6 ;;; 2.91.0 (CLNG "GTK_TYPE_OBJECT") ;;; 2.91.6 ;;; out 2.3 (CLNG "GTK_TYPE_OPTION_MENU") ;;; 2.91.6 (CLNG "GTK_TYPE_PANED") ;;; 2.91.6 (CLNG "GTK_TYPE_PLUG") ;;; 2.91.6 (CLNG "GTK_TYPE_PROGRESS_BAR") ;;; 2.91.6 (CLNG "GTK_TYPE_RADIO_BUTTON") ;;; 2.91.6 (CLNG "GTK_TYPE_RADIO_MENU_ITEM") ;;; 2.91.6 (CLNG "GTK_TYPE_RANGE") ;;; 2.91.6 (CLNG "GTK_TYPE_RC_STYLE") ;;; 2.91.6 ;;; 2.91.5 (CLNG "GTK_TYPE_RULER") ;;; 2.91.6 (CLNG "GTK_TYPE_SCALE") ;;; 2.91.6 (CLNG "GTK_TYPE_SCROLLBAR") ;;; 2.91.6 (CLNG "GTK_TYPE_SCROLLED_WINDOW") ;;; 2.91.6 (CLNG "GTK_TYPE_SEPARATOR") ;;; 2.91.6 (CLNG "GTK_TYPE_SEPARATOR_MENU_ITEM") ;;; 2.91.6 ;(CLNG "GTK_TYPE_SETTINGS") ;;; 2.91.6 (CLNG "GTK_TYPE_SIZE_GROUP") ;;; 2.91.6 (CLNG "GTK_TYPE_SOCKET") ;;; 2.91.6 (CLNG "GTK_TYPE_SPIN_BUTTON") ;;; 2.91.6 (CLNG "GTK_TYPE_STATUSBAR") ;;; 2.91.6 (CLNG "GTK_TYPE_STYLE") ;;; 2.91.6 (CLNG "GTK_TYPE_TABLE") ;;; 2.91.6 (CLNG "GTK_TYPE_TEAROFF_MENU_ITEM") ;;; 2.91.6 (CLNG "GTK_TYPE_TEXT_BUFFER") ;;; 2.91.6 (CLNG "GTK_TYPE_TEXT_CHILD_ANCHOR") ;;; 2.91.6 (CLNG "GTK_TYPE_TEXT_MARK") ;;; 2.91.6 (CLNG "GTK_TYPE_TEXT_TAG") ;;; 2.91.6 (CLNG "GTK_TYPE_TEXT_TAG_TABLE") ;;; 2.91.6 (CLNG "GTK_TYPE_TEXT_VIEW") ;;; 2.91.6 (CLNG "GTK_TYPE_TOGGLE_BUTTON") ;;; 2.91.6 (CLNG "GTK_TYPE_TOOLBAR") ;;; 2.91.6 ;;; (CLNG "GTK_TYPE_TOOLTIPS") ;;; 2.91.6 (CLNG "GTK_TYPE_TREE_DRAG_SOURCE") ;;; 2.91.6 (CLNG "GTK_TYPE_TREE_DRAG_DEST") ;;; 2.91.6 (CLNG "GTK_TYPE_TREE_MODEL") ;;; 2.91.6 (CLNG "GTK_TYPE_TREE_MODEL_SORT") ;;; 2.91.6 (CLNG "GTK_TYPE_TREE_SELECTION") ;;; 2.91.6 (CLNG "GTK_TYPE_TREE_SORTABLE") ;;; 2.91.6 (CLNG "GTK_TYPE_TREE_STORE") ;;; 2.91.6 (CLNG "GTK_TYPE_TREE_VIEW_COLUMN") ;;; 2.91.6 (CLNG "GTK_TYPE_TREE_VIEW") ;;; 2.91.6 (CLNG "GTK_TYPE_VBUTTON_BOX") ;;; 3.1.6 ;;; 2.91.6 (CLNG "GTK_TYPE_VBOX") ;;; 2.91.6 (CLNG "GTK_TYPE_VIEWPORT") ;;; 2.91.6 (CLNG "GTK_TYPE_VPANED") ;;; 2.91.6 ;;; 2.91.5 (CLNG "GTK_TYPE_VRULER") ;;; 2.91.6 (CLNG "GTK_TYPE_VSCALE") ;;; 2.91.6 (CLNG "GTK_TYPE_VSCROLLBAR") ;;; 2.91.6 (CLNG "GTK_TYPE_VSEPARATOR") ;;; 2.91.6 (CLNG "GTK_TYPE_WIDGET") ;;; 2.91.6 (CLNG "GTK_TYPE_WINDOW") ;;; 2.91.6 (CLNG "GTK_TYPE_WINDOW_GROUP") ;;; 2.91.6 ;;; 2.91.0 (CLNG "GDK_TYPE_COLORMAP") ;;; 2.91.6 (CLNG "GDK_TYPE_COLOR") ;;; 2.91.6 (CLNG "GDK_TYPE_CURSOR") ;;; 2.91.6 (CLNG "GDK_TYPE_DRAG_CONTEXT") ;;; 2.91.6 ;;; (CLNG "GDK_TYPE_DRAWABLE") ;;; 2.91.6 (CLNG "GDK_TYPE_CURSOR_TYPE") ;;; 2.91.6 (CLNG "GDK_TYPE_DRAG_ACTION") ;;; 2.91.6 (CLNG "GDK_TYPE_DRAG_PROTOCOL") ;;; 2.91.6 (CLNG "GDK_TYPE_FILTER_RETURN") ;;; 2.91.6 (CLNG "GDK_TYPE_EVENT_TYPE") ;;; 2.91.6 (CLNG "GDK_TYPE_EVENT_MASK") ;;; 2.91.6 (CLNG "GDK_TYPE_VISIBILITY_STATE") ;;; 2.91.6 (CLNG "GDK_TYPE_SCROLL_DIRECTION") ;;; 2.91.6 (CLNG "GDK_TYPE_NOTIFY_TYPE") ;;; 2.91.6 (CLNG "GDK_TYPE_CROSSING_MODE") ;;; 2.91.6 (CLNG "GDK_TYPE_PROPERTY_STATE") ;;; 2.91.6 (CLNG "GDK_TYPE_WINDOW_STATE") ;;; 2.91.6 (CLNG "GDK_TYPE_SETTING_ACTION") ;;; 2.91.6 ;;; (CLNG "GDK_TYPE_FONT_TYPE") ;;; 2.91.6 ;;; 2.90.6 (CLNG "GDK_TYPE_CAP_STYLE") ;;; 2.91.6 ;;; 2.90.6 (CLNG "GDK_TYPE_FILL") ;;; 2.91.6 ;;; 2.90.6 (CLNG "GDK_TYPE_FUNCTION") ;;; 2.91.6 ;;; 2.90.6 (CLNG "GDK_TYPE_JOIN_STYLE") ;;; 2.91.6 ;;; 2.90.6 (CLNG "GDK_TYPE_LINE_STYLE") ;;; 2.91.6 ;;; 2.90.6 (CLNG "GDK_TYPE_SUBWINDOW_MODE") ;;; 2.91.6 ;;; 2.90.6 (CLNG "GDK_TYPE_GC_VALUES_MASK") ;;; 2.91.6 ;;; 2.90.6 (CLNG "GDK_TYPE_IMAGE_TYPE") ;;; 2.91.6 (CLNG "GDK_TYPE_EXTENSION_MODE") ;;; 2.91.6 (CLNG "GDK_TYPE_INPUT_SOURCE") ;;; 2.91.6 (CLNG "GDK_TYPE_INPUT_MODE") ;;; 2.91.6 (CLNG "GDK_TYPE_AXIS_USE") ;;; 2.91.6 (CLNG "GDK_TYPE_PROP_MODE") ;;; 2.91.6 ;;; (CLNG "GDK_TYPE_FILL_RULE") ;;; 2.91.6 ;;; (CLNG "GDK_TYPE_OVERLAP_TYPE") ;;; 2.91.6 ;;; 2.90.6 (CLNG "GDK_TYPE_RGB_DITHER") ;;; 2.91.6 (CLNG "GDK_TYPE_BYTE_ORDER") ;;; 2.91.6 (CLNG "GDK_TYPE_MODIFIER_TYPE") ;;; 2.91.6 ;;; (CLNG "GDK_TYPE_INPUT_CONDITION") ;;; 2.91.6 (CLNG "GDK_TYPE_STATUS") ;;; 2.91.6 (CLNG "GDK_TYPE_GRAB_STATUS") ;;; 2.91.6 (CLNG "GDK_TYPE_VISUAL_TYPE") ;;; 2.91.6 ;;; (CLNG "GDK_TYPE_WINDOW_CLASS") ;;; 2.91.6 (CLNG "GDK_TYPE_WINDOW_TYPE") ;;; 2.91.6 (CLNG "GDK_TYPE_WINDOW_ATTRIBUTES_TYPE") ;;; 2.91.6 (CLNG "GDK_TYPE_WINDOW_HINTS") ;;; 2.91.6 (CLNG "GDK_TYPE_WINDOW_TYPE_HINT") ;;; 2.91.6 (CLNG "GDK_TYPE_WM_DECORATION") ;;; 2.91.6 (CLNG "GDK_TYPE_WM_FUNCTION") ;;; 2.91.6 (CLNG "GDK_TYPE_GRAVITY") ;;; 2.91.6 (CLNG "GDK_TYPE_WINDOW_EDGE") ;;; 2.91.6 (CLNG "GDK_TYPE_EVENT") ;;; 2.91.6 ;;; 2.90.6 (CLNG "GDK_TYPE_GC") ;;; 2.91.6 (CLNG "GDK_TYPE_RECTANGLE") ;;; 2.91.6 ;;; 2.90.6 (CLNG "GDK_TYPE_IMAGE") ;;; 2.91.6 (CLNG "GDK_TYPE_DEVICE") ;;; 2.91.6 (CLNG "GDK_TYPE_KEYMAP") ;;; 2.91.6 ;;; 2.91.0 (CLNG "GDK_TYPE_PIXMAP") ;;; 2.91.6 (CLNG "GDK_TYPE_VISUAL") ;;; 2.91.6 (CLNG "GDK_TYPE_WINDOW") (CCAST "G_OBJECT(object)" "GObject*") (CFNC "GType G_OBJECT_TYPE GObject* object") (CCHK "G_IS_OBJECT(object)" "GObject*") #| ;;; where are these used? gtk_binding_entry_add_signal, but that is commented out (CLNG "G_TYPE_IO_CONDITION") ;(CLNG "G_TYPE_FUNDAMENTAL(type)") ;(CLNG "G_TYPE_FUNDAMENTAL_MAX") (CLNG "G_TYPE_INVALID") (CLNG "G_TYPE_NONE") (CLNG "G_TYPE_INTERFACE") (CLNG "G_TYPE_CHAR") (CLNG "G_TYPE_UCHAR") (CLNG "G_TYPE_BOOLEAN") (CLNG "G_TYPE_INT") (CLNG "G_TYPE_UINT") (CLNG "G_TYPE_LONG") (CLNG "G_TYPE_ULONG") (CLNG "G_TYPE_INT64") (CLNG "G_TYPE_UINT64") (CLNG "G_TYPE_ENUM") (CLNG "G_TYPE_FLAGS") (CLNG "G_TYPE_FLOAT") (CLNG "G_TYPE_DOUBLE") (CLNG "G_TYPE_STRING") (CLNG "G_TYPE_POINTER") (CLNG "G_TYPE_BOXED") (CLNG "G_TYPE_PARAM") (CLNG "G_TYPE_OBJECT") |# ;;; 2.90.6 (CFNC "void gdk_draw_pixbuf GdkDrawable* drawable GdkGC* gc GdkPixbuf* pixbuf int src_x int src_y int dest_x int dest_y int width int height GdkRgbDither dither int x_dither int y_dither") (CFNC "gchar* gtk_tree_model_get_string_from_iter GtkTreeModel* tree_model GtkTreeIter* iter" 'free) (CFNC "gboolean gtk_tree_model_sort_iter_is_valid GtkTreeModelSort* tree_model_sort GtkTreeIter* iter") (CFNC "void gtk_tree_view_expand_to_path GtkTreeView* tree_view GtkTreePath* path") (CFNC "GList* gtk_tree_selection_get_selected_rows GtkTreeSelection* selection GtkTreeModel** model") (CFNC "int gtk_tree_selection_count_selected_rows GtkTreeSelection* selection") (CFNC "void gtk_menu_shell_select_first GtkMenuShell* menu_shell gboolean search_sensitive") (CFNC "int gtk_notebook_get_n_pages GtkNotebook* notebook") (CFNC "void gtk_list_store_reorder GtkListStore* store int* new_order") (CFNC "void gtk_list_store_swap GtkListStore* store GtkTreeIter* a GtkTreeIter* b") (CFNC "void gtk_list_store_move_after GtkListStore* store GtkTreeIter* iter GtkTreeIter* @position") (CFNC "void gtk_list_store_move_before GtkListStore* store GtkTreeIter* iter GtkTreeIter* @position") (CFNC "void gtk_tree_store_reorder GtkTreeStore* tree_store GtkTreeIter* parent int* new_order") (CFNC "void gtk_tree_store_swap GtkTreeStore* tree_store GtkTreeIter* a GtkTreeIter* b") ;;; removed in 2.2 (CFNC "void gtk_tree_store_move GtkTreeStore* tree_store GtkTreeIter* iter GtkTreePath* position") ;;;;(CFNC "GType gdk_display_get_type void") (CFNC "GdkDisplay* gdk_display_open gchar* display_name") (CFNC "gchar* gdk_display_get_name GdkDisplay* display") ;;; 3.9.0 (CFNC "int gdk_display_get_n_screens GdkDisplay* display") (CFNC "GdkScreen* gdk_display_get_screen GdkDisplay* display int screen_num") (CFNC "GdkScreen* gdk_display_get_default_screen GdkDisplay* display") ;;; 2.99.0 (CFNC "void gdk_display_pointer_ungrab GdkDisplay* display guint32 time") ;;; 2.99.0 (CFNC "void gdk_display_keyboard_ungrab GdkDisplay* display guint32 time") ;;; 2.99.0 (CFNC "gboolean gdk_display_pointer_is_grabbed GdkDisplay* display") (CFNC "void gdk_display_beep GdkDisplay* display") (CFNC "void gdk_display_sync GdkDisplay* display") (CFNC "void gdk_display_close GdkDisplay* display") ;;;; 2-90.1 (CFNC "GList* gdk_display_list_devices GdkDisplay* display") (CFNC "GdkEvent* gdk_display_get_event GdkDisplay* display") (CFNC "GdkEvent* gdk_display_peek_event GdkDisplay* display") (CFNC "void gdk_display_put_event GdkDisplay* display GdkEvent* event") ;;; 2.99.3 (CFNC "void gdk_display_add_client_message_filter GdkDisplay* display GdkAtom message_type GdkFilterFunc func lambda_data #func_info") (CFNC "void gdk_display_set_double_click_time GdkDisplay* display guint msec") (CFNC "GdkDisplay* gdk_display_get_default void") ;;;; (CFNC "GdkDevice* gdk_display_get_core_pointer GdkDisplay* display") ;;; 2.99.0 (CFNC "void gdk_display_get_pointer GdkDisplay* display GdkScreen** [screen] int* [x] int* [y] GdkModifierType* [mask]") ;;; 2.99.0 (CFNC "GdkWindow* gdk_display_get_window_at_pointer GdkDisplay* display int* [win_x] int* [win_y]") ;;; 2.99.0 (CFNC "GdkDisplayPointerHooks* gdk_display_set_pointer_hooks GdkDisplay* display GdkDisplayPointerHooks* new_hooks") ;;;;(CFNC "GType gdk_screen_get_type void") ;;; (CFNC-gtk2 "GdkColormap* gdk_screen_get_default_colormap GdkScreen* screen") ;;; (CFNC-gtk2 "void gdk_screen_set_default_colormap GdkScreen* screen GdkColormap* colormap") ;;; (CFNC-gtk2 "GdkColormap* gdk_screen_get_system_colormap GdkScreen* screen") (CFNC "GdkVisual* gdk_screen_get_system_visual GdkScreen* screen") ;;; 2.90.6 (CFNC "GdkColormap* gdk_screen_get_rgb_colormap GdkScreen* screen") ;;; 2.90.6 (CFNC "GdkVisual* gdk_screen_get_rgb_visual GdkScreen* screen") (CFNC "GdkWindow* gdk_screen_get_root_window GdkScreen* screen") (CFNC "GdkDisplay* gdk_screen_get_display GdkScreen* screen") (CFNC "int gdk_screen_get_number GdkScreen* screen") (CFNC "int gdk_screen_get_width GdkScreen* screen") (CFNC "int gdk_screen_get_height GdkScreen* screen") (CFNC "int gdk_screen_get_width_mm GdkScreen* screen") (CFNC "int gdk_screen_get_height_mm GdkScreen* screen") (CFNC "GList* gdk_screen_list_visuals GdkScreen* screen") (CFNC "GList* gdk_screen_get_toplevel_windows GdkScreen* screen") (CFNC "gchar* gdk_screen_make_display_name GdkScreen* screen" 'free) (CFNC "int gdk_screen_get_n_monitors GdkScreen* screen") (CFNC "void gdk_screen_get_monitor_geometry GdkScreen* screen int monitor_num GdkRectangle* dest") (CFNC "int gdk_screen_get_monitor_at_point GdkScreen* screen int x int y") (CFNC "int gdk_screen_get_monitor_at_window GdkScreen* screen GdkWindow* window") ;;; 2.99.3 (CFNC "void gdk_screen_broadcast_client_message GdkScreen* screen GdkEvent* event") (CFNC "GdkScreen* gdk_screen_get_default void") ;(CFNC "gboolean gdk_screen_get_setting GdkScreen* screen gchar* name GValue* value") ;;; 2.91.6 (CLNG "GDK_TYPE_SCREEN") ;;; 2.91.6 (CLNG "GDK_TYPE_DISPLAY") (CCAST "GDK_SCREEN(object)" "GdkScreen*") ;GDK_SCREEN_CLASS(klass) (CCHK "GDK_IS_SCREEN(object)" "GdkScreen*") ;GDK_IS_SCREEN_CLASS(klass) ;GDK_SCREEN_GET_CLASS(obj) (CCAST "GDK_DISPLAY_OBJECT(object)" "GdkDisplay*") ;GDK_DISPLAY_CLASS(klass) (CCHK "GDK_IS_DISPLAY(object)" "GdkDisplay*") ;GDK_IS_DISPLAY_CLASS(klass) ;GDK_DISPLAY_GET_CLASS(obj) (CFNC "GtkClipboard* gtk_clipboard_get_for_display GdkDisplay* display GdkAtom selection") (CFNC "GdkDisplay* gtk_clipboard_get_display GtkClipboard* clipboard") (CFNC "GdkScreen* gtk_widget_get_screen GtkWidget* widget") (CFNC "gboolean gtk_widget_has_screen GtkWidget* widget") (CFNC "GdkDisplay* gtk_widget_get_display GtkWidget* widget") ;;; 3.11.5 (CFNC "GdkWindow* gtk_widget_get_root_window GtkWidget* widget") (CFNC "GtkClipboard* gtk_widget_get_clipboard GtkWidget* widget GdkAtom selection") ;;; -------- end gtk 2.1 additions ;;; glist additions (CFNC "void g_list_free GList* list") (CFNC "GList* g_list_reverse GList* @list") (CFNC "GList* g_list_copy GList* @list") (CFNC "GList* g_list_last GList* list") (CFNC "GList* g_list_first GList* list") (CFNC "guint g_list_length GList* @list") (CFNC "void g_free gpointer mem") (CFNC "GList* g_list_remove_link GList* list GList* llink") (CFNC "gpointer g_object_get_data GObject* object gchar* key" 'const) (CFNC "void g_object_set_data GObject* object gchar* key gpointer data" 'const) ;(CCAST "GPOINTER(obj)" "gpointer") ; do this by hand... (CCAST "GDK_EVENT(obj)" "GdkEvent*") (CCAST "GDK_EVENT_ANY(obj)" "GdkEventAny*") (CCAST "GDK_EVENT_EXPOSE(obj)" "GdkEventExpose*") (CCAST "GDK_EVENT_NOEXPOSE(obj)" "GdkEventNoExpose*") (CCAST "GDK_EVENT_VISIBILITY(obj)" "GdkEventVisibility*") (CCAST "GDK_EVENT_MOTION(obj)" "GdkEventMotion*") (CCAST "GDK_EVENT_BUTTON(obj)" "GdkEventButton*") (CCAST "GDK_EVENT_SCROLL(obj)" "GdkEventScroll*") (CCAST "GDK_EVENT_KEY(obj)" "GdkEventKey*") (CCAST "GDK_EVENT_CROSSING(obj)" "GdkEventCrossing*") (CCAST "GDK_EVENT_FOCUS(obj)" "GdkEventFocus*") (CCAST "GDK_EVENT_CONFIGURE(obj)" "GdkEventConfigure*") (CCAST "GDK_EVENT_PROPERTY(obj)" "GdkEventProperty*") (CCAST "GDK_EVENT_SELECTION(obj)" "GdkEventSelection*") (CCAST "GDK_EVENT_PROXIMITY(obj)" "GdkEventProximity*") (CCAST "GDK_EVENT_SETTING(obj)" "GdkEventSetting*") (CCAST "GDK_EVENT_WINDOWSTATE(obj)" "GdkEventWindowState*") (CCAST "GDK_EVENT_DND(obj)" "GdkEventDND*") ;;; -------- begin gtk 2.3 additions (CFNC "GdkCursor* gdk_cursor_new_from_pixbuf GdkDisplay* display GdkPixbuf* pixbuf gint x gint y") (CFNC "void gdk_display_flush GdkDisplay* display") (CFNC "gboolean gdk_display_supports_cursor_alpha GdkDisplay* display") (CFNC "gboolean gdk_display_supports_cursor_color GdkDisplay* display") (CFNC "guint gdk_display_get_default_cursor_size GdkDisplay* display") (CFNC "void gdk_display_get_maximal_cursor_size GdkDisplay* display guint* [width] guint* [height]") (CFNC "void gdk_window_set_keep_above GdkWindow* window gboolean setting") (CFNC "void gdk_window_set_keep_below GdkWindow* window gboolean setting") ;;; (CFNC "void gtk_alignment_set_padding GtkAlignment* alignment guint padding_top guint padding_bottom guint padding_left guint padding_right") ;;; (CFNC "void gtk_alignment_get_padding GtkAlignment* alignment guint* [padding_top] guint* [padding_bottom] guint* [padding_left] guint* [padding_right]") (CFNC "gboolean gtk_button_box_get_child_secondary GtkButtonBox* widget GtkWidget* child") ;;; 3.19.2 (CFNC "void gtk_button_set_focus_on_click GtkButton* button gboolean focus_on_click") ;;; 3.19.2 (CFNC "gboolean gtk_button_get_focus_on_click GtkButton* button") (CFNC "void gtk_calendar_set_display_options GtkCalendar* calendar GtkCalendarDisplayOptions flags") (CFNC "GtkCalendarDisplayOptions gtk_calendar_get_display_options GtkCalendar* calendar") (CFNC "void gtk_check_menu_item_set_draw_as_radio GtkCheckMenuItem* check_menu_item gboolean draw_as_radio") (CFNC "gboolean gtk_check_menu_item_get_draw_as_radio GtkCheckMenuItem* check_menu_item") (CFNC "void gtk_entry_set_completion GtkEntry* entry GtkEntryCompletion* completion") (CFNC "GtkEntryCompletion* gtk_entry_get_completion GtkEntry* entry") (CFNC "gboolean gtk_event_box_get_visible_window GtkEventBox* event_box") (CFNC "void gtk_event_box_set_visible_window GtkEventBox* event_box gboolean visible_window") (CFNC "gboolean gtk_event_box_get_above_child GtkEventBox* event_box") (CFNC "void gtk_event_box_set_above_child GtkEventBox* event_box gboolean above_child") ;;; (CFNC "void gtk_icon_source_set_icon_name GtkIconSource* source gchar* icon_name") ;;; (CFNC "gchar* gtk_icon_source_get_icon_name GtkIconSource* source") ;const return (CFNC "void gtk_menu_attach GtkMenu* menu GtkWidget* child guint left_attach guint right_attach guint top_attach guint bottom_attach") (CFNC "void gtk_text_buffer_select_range GtkTextBuffer* buffer GtkTextIter* ins GtkTextIter* bound") (CFNC "void gtk_text_view_set_overwrite GtkTextView* text_view gboolean overwrite") (CFNC "gboolean gtk_text_view_get_overwrite GtkTextView* text_view") (CFNC "void gtk_text_view_set_accepts_tab GtkTextView* text_view gboolean accepts_tab") (CFNC "gboolean gtk_text_view_get_accepts_tab GtkTextView* text_view") (CFNC "void gtk_toolbar_insert GtkToolbar* toolbar GtkToolItem* item gint pos") (CFNC "gint gtk_toolbar_get_item_index GtkToolbar* toolbar GtkToolItem* item") (CFNC "gint gtk_toolbar_get_n_items GtkToolbar* toolbar") (CFNC "GtkToolItem* gtk_toolbar_get_nth_item GtkToolbar* toolbar gint n") (CFNC "void gtk_toolbar_set_show_arrow GtkToolbar* toolbar gboolean show_arrow") (CFNC "gboolean gtk_toolbar_get_show_arrow GtkToolbar* toolbar") (CFNC "GtkReliefStyle gtk_toolbar_get_relief_style GtkToolbar* toolbar") (CFNC "gint gtk_toolbar_get_drop_index GtkToolbar* toolbar gint x gint y") ;;;(CFNC "void gtk_toolbar_highlight_drop_location GtkToolbar* toolbar gint x gint y gint width gint height") ;;;(CFNC "void gtk_toolbar_unhighlight_drop_location GtkToolbar* toolbar") (CFNC "void gtk_tree_view_column_set_expand GtkTreeViewColumn* tree_column gboolean expand") (CFNC "gboolean gtk_tree_view_column_get_expand GtkTreeViewColumn* tree_column") (CFNC "void gtk_widget_set_no_show_all GtkWidget* widget gboolean no_show_all") (CFNC "gboolean gtk_widget_get_no_show_all GtkWidget* widget") (CFNC "void gtk_widget_queue_resize_no_redraw GtkWidget* widget") (CFNC "void gtk_window_set_default_icon GdkPixbuf* icon") (CFNC "void gtk_window_set_keep_above GtkWindow* window gboolean setting") (CFNC "void gtk_window_set_keep_below GtkWindow* window gboolean setting") (CINT "GDK_WINDOW_STATE_FULLSCREEN" "GdkWindowState") (CINT "GDK_WINDOW_STATE_ABOVE" "GdkWindowState") (CINT "GDK_WINDOW_STATE_BELOW" "GdkWindowState") (CINT "GTK_MOVEMENT_HORIZONTAL_PAGES" "GtkMovementStep") (CINT "GTK_SCROLL_STEPS" "GtkScrollStep") (CINT "GTK_SCROLL_PAGES" "GtkScrollStep") (CINT "GTK_SCROLL_ENDS" "GtkScrollStep") (CINT "GTK_SCROLL_HORIZONTAL_STEPS" "GtkScrollStep") (CINT "GTK_SCROLL_HORIZONTAL_PAGES" "GtkScrollStep") (CINT "GTK_SCROLL_HORIZONTAL_ENDS" "GtkScrollStep") (CINT "GTK_WRAP_WORD_CHAR" "GtkWrapMode") ;;; 2.91.0 (CINT "GTK_NO_SHOW_ALL" "GtkWidgetFlags") ;;; 2.91.6 (CLNG "GTK_TYPE_FILE_CHOOSER_DIALOG") ;;; 2.91.6 (CLNG "GTK_TYPE_FILE_CHOOSER_WIDGET") ;;; 2.91.6 (CLNG "GTK_TYPE_TREE_MODEL_FILTER") ;;; 2.91.6 (CLNG "GTK_TYPE_ACTION") ;;; 2.91.6 (CLNG "GTK_TYPE_ACTION_GROUP") ;;; 2.91.6 (CLNG "GTK_TYPE_COMBO_BOX") ;;; 2.91.6 ;;; 2.91.1 (CLNG "GTK_TYPE_COMBO_BOX_ENTRY") ;;; 2.91.6 (CLNG "GTK_TYPE_EXPANDER") ;;; 2.91.6 (CLNG "GTK_TYPE_FONT_BUTTON") ;;; 2.91.6 (CLNG "GTK_TYPE_COLOR_BUTTON") ;;; 2.91.6 (CLNG "GTK_TYPE_ENTRY_COMPLETION") ;;; 2.91.6 (CLNG "GTK_TYPE_UI_MANAGER") ;;; 2.91.6 (CLNG "GTK_TYPE_RADIO_TOOL_BUTTON") ;;; 2.91.6 (CLNG "GTK_TYPE_RADIO_ACTION") ;;; 2.91.6 (CLNG "GTK_TYPE_SEPARATOR_TOOL_ITEM") ;;; 2.91.6 (CLNG "GTK_TYPE_TOGGLE_ACTION") ;;; 2.91.6 (CLNG "GTK_TYPE_TOGGLE_TOOL_BUTTON") ;;; 2.91.6 (CLNG "GTK_TYPE_FILE_FILTER") ;;; 2.91.6 (CLNG "GTK_TYPE_CELL_LAYOUT") ;;; 2.91.6 (CLNG "GTK_TYPE_CLIPBOARD") ;;; 2.91.6 (CLNG "GTK_TYPE_FILE_CHOOSER") ;;; 2.91.6 (CLNG "GTK_TYPE_ICON_INFO") ;;; 2.91.6 (CLNG "GTK_TYPE_ICON_THEME") ;;; 2.91.6 (CLNG "GTK_TYPE_TOOL_BUTTON") ;;; 2.91.6 (CLNG "GTK_TYPE_TOOL_ITEM") (CCAST "GTK_FILE_CHOOSER_DIALOG(obj)" "GtkFileChooserDialog*") (CCHK "GTK_IS_FILE_CHOOSER_DIALOG(obj)" "GtkFileChooserDialog*") (CCAST "GTK_FILE_CHOOSER_WIDGET(obj)" "GtkFileChooserWidget*") (CCHK "GTK_IS_FILE_CHOOSER_WIDGET(obj)" "GtkFileChooserWidget*") (CCAST "GTK_TREE_MODEL_FILTER(obj)" "GtkTreeModelFilter*") (CCHK "GTK_IS_TREE_MODEL_FILTER(obj)" "GtkTreeModelFilter*") ;;; 3.9.8 (CCAST "GTK_ACTION(obj)" "GtkAction*") ;;; (CCHK "GTK_IS_ACTION(obj)" "GtkAction*") ;;; (CCAST "GTK_ACTION_GROUP(obj)" "GtkActionGroup*") ;;; (CCHK "GTK_IS_ACTION_GROUP(obj)" "GtkActionGroup*") (CCAST "GTK_COMBO_BOX(obj)" "GtkComboBox*") (CCHK "GTK_IS_COMBO_BOX(obj)" "GtkComboBox*") ;;; 2.91.1 (CCAST "GTK_COMBO_BOX_ENTRY(obj)" "GtkComboBoxEntry*") ;;; 2.91.1 (CCHK "GTK_IS_COMBO_BOX_ENTRY(obj)" "GtkComboBoxEntry*") (CCAST "GTK_EXPANDER(obj)" "GtkExpander*") (CCHK "GTK_IS_EXPANDER(obj)" "GtkExpander*") (CCAST "GTK_FONT_BUTTON(obj)" "GtkFontButton*") (CCHK "GTK_IS_FONT_BUTTON(obj)" "GtkFontButton*") (CCAST "GTK_COLOR_BUTTON(obj)" "GtkColorButton*") (CCHK "GTK_IS_COLOR_BUTTON(obj)" "GtkColorButton*") (CCAST "GTK_ENTRY_COMPLETION(obj)" "GtkEntryCompletion*") (CCHK "GTK_IS_ENTRY_COMPLETION(obj)" "GtkEntryCompletion*") ;(CCAST "GTK_UI_MANAGER(obj)" "GtkUIManager*") ;(CCHK "GTK_IS_UI_MANAGER(obj)" "GtkUIManager*") (CCAST "GTK_RADIO_TOOL_BUTTON(obj)" "GtkRadioToolButton*") (CCHK "GTK_IS_RADIO_TOOL_BUTTON(obj)" "GtkRadioToolButton*") ;;; (CCAST "GTK_RADIO_ACTION(obj)" "GtkRadioAction*") ;;; (CCHK "GTK_IS_RADIO_ACTION(obj)" "GtkRadioAction*") (CCAST "GTK_SEPARATOR_TOOL_ITEM(obj)" "GtkSeparatorToolItem*") (CCHK "GTK_IS_SEPARATOR_TOOL_ITEM(obj)" "GtkSeparatorToolItem*") ;;; (CCAST "GTK_TOGGLE_ACTION(obj)" "GtkToggleAction*") ;;; (CCHK "GTK_IS_TOGGLE_ACTION(obj)" "GtkToggleAction*") (CCAST "GTK_TOGGLE_TOOL_BUTTON(obj)" "GtkToggleToolButton*") (CCHK "GTK_IS_TOGGLE_TOOL_BUTTON(obj)" "GtkToggleToolButton*") (CCAST "GTK_FILE_FILTER(obj)" "GtkFileFilter*") (CCHK "GTK_IS_FILE_FILTER(obj)" "GtkFileFilter*") (CCAST "GTK_CELL_LAYOUT(obj)" "GtkCellLayout*") (CCHK "GTK_IS_CELL_LAYOUT(obj)" "GtkCellLayout*") (CCAST "GTK_CLIPBOARD(obj)" "GtkClipboard*") (CCHK "GTK_IS_CLIPBOARD(obj)" "GtkClipboard*") (CCAST "GTK_FILE_CHOOSER(obj)" "GtkFileChooser*") (CCHK "GTK_IS_FILE_CHOOSER(obj)" "GtkFileChooser*") (CCAST "GTK_ICON_THEME(obj)" "GtkIconTheme*") (CCHK "GTK_IS_ICON_THEME(obj)" "GtkIconTheme*") (CCAST "GTK_TOOL_BUTTON(obj)" "GtkToolButton*") (CCHK "GTK_IS_TOOL_BUTTON(obj)" "GtkToolButton*") (CCAST "GTK_TOOL_ITEM(o)" "GtkToolItem*") (CCHK "GTK_IS_TOOL_ITEM(o)" "GtkToolItem*") ;;; out 3.9.8 ;(CINT "GTK_UI_MANAGER_AUTO" "GtkUIManagerItemType") ;(CINT "GTK_UI_MANAGER_MENUBAR" "GtkUIManagerItemType") ;(CINT "GTK_UI_MANAGER_MENU" "GtkUIManagerItemType") ;(CINT "GTK_UI_MANAGER_TOOLBAR" "GtkUIManagerItemType") ;(CINT "GTK_UI_MANAGER_PLACEHOLDER" "GtkUIManagerItemType") ;(CINT "GTK_UI_MANAGER_POPUP" "GtkUIManagerItemType") ;(CINT "GTK_UI_MANAGER_MENUITEM" "GtkUIManagerItemType") ;(CINT "GTK_UI_MANAGER_TOOLITEM" "GtkUIManagerItemType") ;(CINT "GTK_UI_MANAGER_SEPARATOR" "GtkUIManagerItemType") ;(CINT "GTK_UI_MANAGER_ACCELERATOR" "GtkUIManagerItemType") (CINT "GTK_FILE_FILTER_FILENAME" "GtkFileFilterFlags") (CINT "GTK_FILE_FILTER_URI" "GtkFileFilterFlags") (CINT "GTK_FILE_FILTER_DISPLAY_NAME" "GtkFileFilterFlags") (CINT "GTK_FILE_FILTER_MIME_TYPE" "GtkFileFilterFlags") (CINT "GTK_ICON_LOOKUP_NO_SVG" "GtkIconLookupFlags") (CINT "GTK_ICON_LOOKUP_FORCE_SVG" "GtkIconLookupFlags") (CINT "GTK_ICON_LOOKUP_USE_BUILTIN" "GtkIconLookupFlags") (CINT "GTK_ICON_LOOKUP_GENERIC_FALLBACK" "GtkIconLookupFlags") (CINT "GTK_FILE_CHOOSER_ACTION_OPEN" "GtkFileChooserAction") (CINT "GTK_FILE_CHOOSER_ACTION_SAVE" "GtkFileChooserAction") (CFNC-23-PA "GtkWidget* gtk_file_chooser_dialog_new gchar* title GtkWindow* @parent GtkFileChooserAction action etc #buttons" 0 10 '("gchar*" "int")) ;;;;(CFNC "GType gtk_file_chooser_dialog_get_type void") ;;;;(CFNC "GType gtk_file_chooser_widget_get_type void") (CFNC "GtkWidget* gtk_file_chooser_widget_new GtkFileChooserAction action") ;;;;(CFNC "GType gtk_tree_model_filter_get_type void") (CFNC "GtkTreeModel* gtk_tree_model_filter_new GtkTreeModel* child_model GtkTreePath* @root") ;(CFNC "void gtk_tree_model_filter_set_visible_func GtkTreeModelFilter* filter GtkTreeModelFilterVisibleFunc func lambda_data func_info GtkDestroyNotify destroy") ;(CFNC "void gtk_tree_model_filter_set_modify_func GtkTreeModelFilter* filter gint n_columns GType* types GtkTreeModelFilterModifyFunc func lambda_data func_info GtkDestroyNotify destroy") (CFNC "void gtk_tree_model_filter_set_visible_column GtkTreeModelFilter* filter gint column") (CFNC "GtkTreeModel* gtk_tree_model_filter_get_model GtkTreeModelFilter* filter") ;(CFNC "void gtk_tree_model_filter_convert_child_iter_to_iter GtkTreeModelFilter* filter GtkTreeIter* filter_iter GtkTreeIter* child_iter") ; rtn type change 210 (CFNC "void gtk_tree_model_filter_convert_iter_to_child_iter GtkTreeModelFilter* filter GtkTreeIter* child_iter GtkTreeIter* filter_iter") (CFNC "GtkTreePath* gtk_tree_model_filter_convert_child_path_to_path GtkTreeModelFilter* filter GtkTreePath* child_path") ; FREE (CFNC "GtkTreePath* gtk_tree_model_filter_convert_path_to_child_path GtkTreeModelFilter* path GtkTreePath* filter_path") ; FREE (CFNC "void gtk_tree_model_filter_refilter GtkTreeModelFilter* filter") (CFNC "void gtk_tree_model_filter_clear_cache GtkTreeModelFilter* filter") ;;; 3.9.8 ;;;;(CFNC "GType gtk_action_get_type void") ;;; (CFNC "gchar* gtk_action_get_name GtkAction* action") ;;; (CFNC "void gtk_action_activate GtkAction* action") ;;; (CFNC "GtkWidget* gtk_action_create_icon GtkAction* action GtkIconSize icon_size") ;;; (CFNC "GtkWidget* gtk_action_create_menu_item GtkAction* action") ;;; (CFNC "GtkWidget* gtk_action_create_tool_item GtkAction* action") ;;; out 2.15.1 (CFNC "void gtk_action_connect_proxy GtkAction* action GtkWidget* proxy") ;;; (CFNC "void gtk_action_disconnect_proxy GtkAction* action GtkWidget* proxy") ;;; (CFNC "GSList* gtk_action_get_proxies GtkAction* action") ;;; (CFNC "void gtk_action_connect_accelerator GtkAction* action") ;;; (CFNC "void gtk_action_disconnect_accelerator GtkAction* action") ;;;;(CFNC "GType gtk_action_group_get_type void") ;;; (CFNC "GtkActionGroup* gtk_action_group_new gchar* name") ;;; (CFNC "gchar* gtk_action_group_get_name GtkActionGroup* action_group") ;;; (CFNC "GtkAction* gtk_action_group_get_action GtkActionGroup* action_group gchar* action_name") ;;; (CFNC "GList* gtk_action_group_list_actions GtkActionGroup* action_group") ;;; (CFNC "void gtk_action_group_add_action GtkActionGroup* action_group GtkAction* action") ;;; (CFNC "void gtk_action_group_remove_action GtkActionGroup* action_group GtkAction* action") ;;; (CFNC "void gtk_action_group_add_actions GtkActionGroup* action_group GtkActionEntry* entries guint n_entries gpointer user_data") ;;; (CFNC "void gtk_action_group_add_toggle_actions GtkActionGroup* action_group GtkToggleActionEntry* entries guint n_entries gpointer user_data") ;;; ;(CFNC "void gtk_action_group_add_radio_actions GtkActionGroup* action_group GtkRadioActionEntry* entries guint n_entries gint value GCallback on_change gpointer user_data") ;;; ;(CFNC "void gtk_action_group_add_actions_full GtkActionGroup* action_group GtkActionEntry* entries guint n_entries lambda_data func_info GtkDestroyNotify destroy") ;;; (CFNC "void gtk_action_group_add_toggle_actions_full GtkActionGroup* action_group GtkToggleActionEntry* entries guint n_entries lambda_data func_info GtkDestroyNotify destroy") ;;; ;(CFNC "void gtk_action_group_add_radio_actions_full GtkActionGroup* action_group GtkRadioActionEntry* entries guint n_entries gint value GCallback on_change gpointer user_data GtkDestroyNotify destroy") ;;; ;(CFNC "void gtk_action_group_set_translate_func GtkActionGroup* action_group GtkTranslateFunc func lambda_data func_info GtkDestroyNotify notify") ;;; (CFNC "void gtk_action_group_set_translation_domain GtkActionGroup* action_group gchar* domain") ;;;;(CFNC "GType gtk_combo_box_get_type void") ;;; (CFNC "GtkWidget* gtk_combo_box_new GtkTreeModel* model") ;;; changed 2.3.1 (CFNC "GtkWidget* gtk_combo_box_new void") (CFNC "GtkWidget* gtk_combo_box_new_with_model GtkTreeModel* model") (CFNC "void gtk_combo_box_set_model GtkComboBox* combo_box GtkTreeModel* @model") ;;; 2.91.1 (CFNC "void gtk_combo_box_remove_text GtkComboBox* combo_box gint position") (CFNC "void gtk_combo_box_set_wrap_width GtkComboBox* combo_box gint width") (CFNC "void gtk_combo_box_set_row_span_column GtkComboBox* combo_box gint row_span") (CFNC "void gtk_combo_box_set_column_span_column GtkComboBox* combo_box gint column_span") (CFNC "gint gtk_combo_box_get_active GtkComboBox* combo_box") (CFNC "void gtk_combo_box_set_active GtkComboBox* combo_box gint index") (CFNC "gboolean gtk_combo_box_get_active_iter GtkComboBox* combo_box GtkTreeIter* iter") (CFNC "void gtk_combo_box_set_active_iter GtkComboBox* combo_box GtkTreeIter* iter") (CFNC "GtkTreeModel* gtk_combo_box_get_model GtkComboBox* combo_box") ;;; 2.91.1 (CFNC "GtkWidget* gtk_combo_box_new_text void") ;;; 2.91.1 (CFNC "void gtk_combo_box_append_text GtkComboBox* combo_box gchar* text") ;;; 2.91.1 (CFNC "void gtk_combo_box_insert_text GtkComboBox* combo_box gint position gchar* text") ;;; 2.91.1 (CFNC "void gtk_combo_box_prepend_text GtkComboBox* combo_box gchar* text") ;;;;(CFNC "GType gtk_combo_box_entry_get_type void") ;;; (CFNC "GtkWidget* gtk_combo_box_entry_new GtkTreeModel* model gint text_column") ;;; changed in 2.3.1 ;;; 2.91.1 (CFNC "GtkWidget* gtk_combo_box_entry_new void") ;;; 2.91.1 (CFNC "GtkWidget* gtk_combo_box_entry_new_with_model GtkTreeModel* model gint text_column") ;;; 2.91.1 (CFNC "void gtk_combo_box_entry_set_text_column GtkComboBoxEntry* entry_box gint text_column") ;;; 2.91.1 (CFNC "gint gtk_combo_box_entry_get_text_column GtkComboBoxEntry* entry_box") ;;;;(CFNC "GType gtk_expander_get_type void") (CFNC "GtkWidget* gtk_expander_new gchar* label") (CFNC "GtkWidget* gtk_expander_new_with_mnemonic gchar* label") (CFNC "void gtk_expander_set_expanded GtkExpander* expander gboolean expanded") (CFNC "gboolean gtk_expander_get_expanded GtkExpander* expander") (CFNC "void gtk_expander_set_spacing GtkExpander* expander gint spacing") (CFNC "gint gtk_expander_get_spacing GtkExpander* expander") (CFNC "void gtk_expander_set_label GtkExpander* expander gchar* label") (CFNC "gchar* gtk_expander_get_label GtkExpander* expander") (CFNC "void gtk_expander_set_use_underline GtkExpander* expander gboolean use_underline") (CFNC "gboolean gtk_expander_get_use_underline GtkExpander* expander") (CFNC "void gtk_expander_set_label_widget GtkExpander* expander GtkWidget* label_widget") (CFNC "GtkWidget* gtk_expander_get_label_widget GtkExpander* expander") (CFNC "void gtk_expander_set_use_markup GtkExpander* expander gboolean use_markup") (CFNC "gboolean gtk_expander_get_use_markup GtkExpander* expander") ;;;;(CFNC "GType gtk_font_button_get_type void") (CFNC "GtkWidget* gtk_font_button_new void") (CFNC "GtkWidget* gtk_font_button_new_with_font gchar* fontname") (CFNC "gchar* gtk_font_button_get_title GtkFontButton* font_button") (CFNC "void gtk_font_button_set_title GtkFontButton* font_button gchar* title") (CFNC "gboolean gtk_font_button_get_use_font GtkFontButton* font_button") (CFNC "void gtk_font_button_set_use_font GtkFontButton* font_button gboolean use_font") (CFNC "gboolean gtk_font_button_get_use_size GtkFontButton* font_button") (CFNC "void gtk_font_button_set_use_size GtkFontButton* font_button gboolean use_size") (CFNC "gchar* gtk_font_button_get_font_name GtkFontButton* font_button") (CFNC "gboolean gtk_font_button_set_font_name GtkFontButton* font_button gchar* fontname") (CFNC "gboolean gtk_font_button_get_show_style GtkFontButton* font_button") (CFNC "void gtk_font_button_set_show_style GtkFontButton* font_button gboolean show_style") (CFNC "gboolean gtk_font_button_get_show_size GtkFontButton* font_button") (CFNC "void gtk_font_button_set_show_size GtkFontButton* font_button gboolean show_size") ;;;;(CFNC "GType gtk_color_button_get_type void") ;;; ;;; 3.3.16 (CFNC-gtk2 "GtkWidget* gtk_color_button_new void") ;;; ;;; 3.3.16 (CFNC-gtk2 "GtkWidget* gtk_color_button_new_with_color GdkColor* color") ;;; 3.3.16 (CFNC "void gtk_color_button_set_alpha GtkColorButton* color_button guint16 alpha") ;;; ;;; 3.3.16 (CFNC-gtk2 "void gtk_color_button_set_color GtkColorButton* color_button GdkColor* color") ;;; ;;; 3.3.16 (CFNC-gtk2 "void gtk_color_button_get_color GtkColorButton* color_button GdkColor* color") ;;; 3.3.16 (CFNC "guint16 gtk_color_button_get_alpha GtkColorButton* color_button") ;;; 3.3.16 (CFNC "void gtk_color_button_set_use_alpha GtkColorButton* color_button gboolean use_alpha") ;;; 3.3.16 (CFNC "gboolean gtk_color_button_get_use_alpha GtkColorButton* color_button") ;;; ;;; 3.3.16 (CFNC-gtk2 "void gtk_color_button_set_title GtkColorButton* color_button gchar* title") ;;; ;;; 3.3.16 (CFNC-gtk2 "gchar* gtk_color_button_get_title GtkColorButton* color_button") ;;;;(CFNC "GType gtk_entry_completion_get_type void") (CFNC "GtkEntryCompletion* gtk_entry_completion_new void") (CFNC "GtkWidget* gtk_entry_completion_get_entry GtkEntryCompletion* entry") (CFNC "void gtk_entry_completion_set_model GtkEntryCompletion* completion GtkTreeModel* @model") (CFNC "GtkTreeModel* gtk_entry_completion_get_model GtkEntryCompletion* completion") (CFNC "void gtk_entry_completion_set_match_func GtkEntryCompletion* completion GtkEntryCompletionMatchFunc func lambda_data func_info GtkDestroyNotify func_notify") (CFNC "void gtk_entry_completion_set_minimum_key_length GtkEntryCompletion* completion gint length") (CFNC "gint gtk_entry_completion_get_minimum_key_length GtkEntryCompletion* completion") (CFNC "void gtk_entry_completion_complete GtkEntryCompletion* completion") (CFNC "void gtk_entry_completion_insert_action_text GtkEntryCompletion* completion gint index gchar* text") (CFNC "void gtk_entry_completion_insert_action_markup GtkEntryCompletion* completion gint index gchar* markup") (CFNC "void gtk_entry_completion_delete_action GtkEntryCompletion* completion gint index") (CFNC "void gtk_entry_completion_set_text_column GtkEntryCompletion* completion gint column") ;;;;(CFNC "GType gtk_ui_manager_get_type void") ;(CFNC "GtkUIManager* gtk_ui_manager_new void") ;;; 3.3.2 ;(CFNC "void gtk_ui_manager_set_add_tearoffs GtkUIManager* self gboolean add_tearoffs") ;;; 3.3.2 ;(CFNC "gboolean gtk_ui_manager_get_add_tearoffs GtkUIManager* self") ;(CFNC "void gtk_ui_manager_insert_action_group GtkUIManager* self GtkActionGroup* action_group gint pos") ;(CFNC "void gtk_ui_manager_remove_action_group GtkUIManager* self GtkActionGroup* action_group") ;(CFNC "GList* gtk_ui_manager_get_action_groups GtkUIManager* self") ;(CFNC "GtkAccelGroup* gtk_ui_manager_get_accel_group GtkUIManager* self") ;(CFNC "GtkWidget* gtk_ui_manager_get_widget GtkUIManager* self gchar* path") ;(CFNC "GtkAction* gtk_ui_manager_get_action GtkUIManager* self gchar* path") ;(CFNC "guint gtk_ui_manager_add_ui_from_string GtkUIManager* self gchar* buffer gssize length GError** [error]") ;(CFNC "guint gtk_ui_manager_add_ui_from_file GtkUIManager* self gchar* filename GError** [error]") ;(CFNC "void gtk_ui_manager_add_ui GtkUIManager* self guint merge_id gchar* path gchar* name gchar* action GtkUIManagerItemType type gboolean top") ;(CFNC "void gtk_ui_manager_remove_ui GtkUIManager* self guint merge_id") ;(CFNC "gchar* gtk_ui_manager_get_ui GtkUIManager* self" 'free) ;(CFNC "void gtk_ui_manager_ensure_update GtkUIManager* self") ;(CFNC "guint gtk_ui_manager_new_merge_id GtkUIManager* self") ;;;;(CFNC "GType gtk_radio_tool_button_get_type void") (CFNC "GtkToolItem* gtk_radio_tool_button_new GSList* @group") ;;; (CFNC "GtkToolItem* gtk_radio_tool_button_new_from_stock GSList* @group gchar* stock_id") ;;; (CFNC "GtkToolItem* gtk_radio_tool_button_new_from_widget GtkWidget* group") ;;; changed 2.3.1 (CFNC "GtkToolItem* gtk_radio_tool_button_new_from_widget GtkRadioToolButton* group") ;;; (CFNC "GtkToolItem* gtk_radio_tool_button_new_with_stock_from_widget GtkRadioToolButton* group gchar* stock_id") ;;; arg1 type changed 2.3.2 (CFNC "GSList* gtk_radio_tool_button_get_group GtkRadioToolButton* button") (CFNC "void gtk_radio_tool_button_set_group GtkRadioToolButton* button GSList* @group") ;;;;(CFNC "GType gtk_radio_action_get_type void") ;;; (CFNC "GSList* gtk_radio_action_get_group GtkRadioAction* action") ;;; (CFNC "void gtk_radio_action_set_group GtkRadioAction* action GSList* @group") ;;; (CFNC "gint gtk_radio_action_get_current_value GtkRadioAction* action") ;;;;(CFNC "GType gtk_separator_tool_item_get_type void") (CFNC "GtkToolItem* gtk_separator_tool_item_new void") (CFNC "gboolean gtk_separator_tool_item_get_draw GtkSeparatorToolItem* item") (CFNC "void gtk_separator_tool_item_set_draw GtkSeparatorToolItem* tool_item gboolean draw") ;;;;(CFNC "GType gtk_toggle_action_get_type void") ;;; (CFNC "void gtk_toggle_action_toggled GtkToggleAction* action") ;;; (CFNC "void gtk_toggle_action_set_active GtkToggleAction* action gboolean is_active") ;;; (CFNC "gboolean gtk_toggle_action_get_active GtkToggleAction* action") ;;; (CFNC "void gtk_toggle_action_set_draw_as_radio GtkToggleAction* action gboolean draw_as_radio") ;;; (CFNC "gboolean gtk_toggle_action_get_draw_as_radio GtkToggleAction* action") ;;; ;;;;(CFNC "GType gtk_toggle_tool_button_get_type void") (CFNC "GtkToolItem* gtk_toggle_tool_button_new void") ;;; (CFNC "GtkToolItem* gtk_toggle_tool_button_new_from_stock gchar* stock_id") (CFNC "void gtk_toggle_tool_button_set_active GtkToggleToolButton* button gboolean is_active") (CFNC "gboolean gtk_toggle_tool_button_get_active GtkToggleToolButton* button") (CFNC "guint g_timeout_add_full gint priority guint interval GSourceFunc func lambda_data func_info GtkDestroyNotify notify") (CFNC "guint g_timeout_add guint interval GSourceFunc func lambda_data #func_info") (CFNC "guint g_idle_add GSourceFunc func lambda_data #func_info") (CFNC "guint g_idle_add_full gint priority GSourceFunc func lambda_data func_info GtkDestroyNotify notify") (CFNC "gboolean g_idle_remove_by_data gpointer data") (CFNC "gboolean g_source_remove guint tag") ;;;;(CFNC "GType gtk_file_filter_get_type void") (CFNC "GtkFileFilter* gtk_file_filter_new void") (CFNC "void gtk_file_filter_set_name GtkFileFilter* filter gchar* name") (CFNC "gchar* gtk_file_filter_get_name GtkFileFilter* filter") (CFNC "void gtk_file_filter_add_mime_type GtkFileFilter* filter gchar* mime_type") (CFNC "void gtk_file_filter_add_pattern GtkFileFilter* filter gchar* pattern") (CFNC "void gtk_file_filter_add_custom GtkFileFilter* filter GtkFileFilterFlags needed GtkFileFilterFunc func lambda_data func_info GtkDestroyNotify notify") (CFNC "GtkFileFilterFlags gtk_file_filter_get_needed GtkFileFilter* filter") (CFNC "gboolean gtk_file_filter_filter GtkFileFilter* filter GtkFileFilterInfo* filter_info") ;;;;(CFNC "GType gtk_cell_layout_get_type void") (CFNC "void gtk_cell_layout_pack_start GtkCellLayout* cell_layout GtkCellRenderer* cell gboolean expand") (CFNC "void gtk_cell_layout_pack_end GtkCellLayout* cell_layout GtkCellRenderer* cell gboolean expand") (CFNC "void gtk_cell_layout_clear GtkCellLayout* cell_layout") (CFNC-23-PA "void gtk_cell_layout_set_attributes GtkCellLayout* cell_layout GtkCellRenderer* cell etc attributes" 2 10 '("gchar*" "int")) (CFNC "void gtk_cell_layout_add_attribute GtkCellLayout* cell_layout GtkCellRenderer* cell gchar* attribute gint column") (CFNC "void gtk_cell_layout_set_cell_data_func GtkCellLayout* cell_layout GtkCellRenderer* cell GtkCellLayoutDataFunc func lambda_data func_info GtkDestroyNotify destroy") (CFNC "void gtk_cell_layout_clear_attributes GtkCellLayout* cell_layout GtkCellRenderer* cell") ;;;;(CFNC "GType gtk_file_chooser_get_type void") (CFNC "void gtk_file_chooser_set_action GtkFileChooser* chooser GtkFileChooserAction action") (CFNC "GtkFileChooserAction gtk_file_chooser_get_action GtkFileChooser* chooser") ;;; (CFNC "void gtk_file_chooser_set_folder_mode GtkFileChooser* chooser gboolean folder_mode") ;;; (CFNC "gboolean gtk_file_chooser_get_folder_mode GtkFileChooser* chooser") ;;; 2.3.5 (CFNC "void gtk_file_chooser_set_local_only GtkFileChooser* chooser gboolean files_only") (CFNC "gboolean gtk_file_chooser_get_local_only GtkFileChooser* chooser") (CFNC "void gtk_file_chooser_set_select_multiple GtkFileChooser* chooser gboolean select_multiple") (CFNC "gboolean gtk_file_chooser_get_select_multiple GtkFileChooser* chooser") (CFNC "void gtk_file_chooser_set_current_name GtkFileChooser* chooser gchar* name") (CFNC "gchar* gtk_file_chooser_get_filename GtkFileChooser* chooser" 'free) (CFNC "gboolean gtk_file_chooser_set_filename GtkFileChooser* chooser char* filename") (CFNC "gboolean gtk_file_chooser_select_filename GtkFileChooser* chooser char* filename") (CFNC "void gtk_file_chooser_unselect_filename GtkFileChooser* chooser char* filename") (CFNC "void gtk_file_chooser_select_all GtkFileChooser* chooser") (CFNC "void gtk_file_chooser_unselect_all GtkFileChooser* chooser") (CFNC "GSList* gtk_file_chooser_get_filenames GtkFileChooser* chooser") ; FREE and result with g_slist_free (CFNC "gboolean gtk_file_chooser_set_current_folder GtkFileChooser* chooser gchar* filename") (CFNC "gchar* gtk_file_chooser_get_current_folder GtkFileChooser* chooser" 'free) (CFNC "gchar* gtk_file_chooser_get_uri GtkFileChooser* chooser" 'free) (CFNC "gboolean gtk_file_chooser_set_uri GtkFileChooser* chooser char* uri") (CFNC "gboolean gtk_file_chooser_select_uri GtkFileChooser* chooser char* uri") (CFNC "void gtk_file_chooser_unselect_uri GtkFileChooser* chooser char* uri") (CFNC "GSList* gtk_file_chooser_get_uris GtkFileChooser* chooser") ; FREE (g_slist_free) (CFNC "gboolean gtk_file_chooser_set_current_folder_uri GtkFileChooser* chooser gchar* uri") (CFNC "gchar* gtk_file_chooser_get_current_folder_uri GtkFileChooser* chooser" 'free) (CFNC "void gtk_file_chooser_set_preview_widget GtkFileChooser* chooser GtkWidget* preview_widget") (CFNC "GtkWidget* gtk_file_chooser_get_preview_widget GtkFileChooser* chooser") (CFNC "void gtk_file_chooser_set_preview_widget_active GtkFileChooser* chooser gboolean active") (CFNC "gboolean gtk_file_chooser_get_preview_widget_active GtkFileChooser* chooser") (CFNC "char* gtk_file_chooser_get_preview_filename GtkFileChooser* file_chooser" 'free) (CFNC "char* gtk_file_chooser_get_preview_uri GtkFileChooser* file_chooser" 'free) (CFNC "void gtk_file_chooser_set_extra_widget GtkFileChooser* chooser GtkWidget* extra_widget") (CFNC "GtkWidget* gtk_file_chooser_get_extra_widget GtkFileChooser* chooser") (CFNC "void gtk_file_chooser_add_filter GtkFileChooser* chooser GtkFileFilter* filter") (CFNC "void gtk_file_chooser_remove_filter GtkFileChooser* chooser GtkFileFilter* filter") (CFNC "GSList* gtk_file_chooser_list_filters GtkFileChooser* chooser") (CFNC "void gtk_file_chooser_set_filter GtkFileChooser* chooser GtkFileFilter* filter") (CFNC "GtkFileFilter* gtk_file_chooser_get_filter GtkFileChooser* chooser") (CFNC "gboolean gtk_file_chooser_add_shortcut_folder GtkFileChooser* chooser char* folder GError** [error]") (CFNC "gboolean gtk_file_chooser_remove_shortcut_folder GtkFileChooser* chooser char* folder GError** [error]") (CFNC "GSList* gtk_file_chooser_list_shortcut_folders GtkFileChooser* chooser") (CFNC "gboolean gtk_file_chooser_add_shortcut_folder_uri GtkFileChooser* chooser char* folder GError** [error]") (CFNC "gboolean gtk_file_chooser_remove_shortcut_folder_uri GtkFileChooser* chooser char* folder GError** [error]") (CFNC "GSList* gtk_file_chooser_list_shortcut_folder_uris GtkFileChooser* chooser") ;;;;(CFNC "GType gtk_icon_theme_get_type void") (CFNC "GtkIconTheme* gtk_icon_theme_new void") (CFNC "GtkIconTheme* gtk_icon_theme_get_default void") (CFNC "GtkIconTheme* gtk_icon_theme_get_for_screen GdkScreen* screen") (CFNC "void gtk_icon_theme_set_screen GtkIconTheme* icon_theme GdkScreen* @screen") ;(CFNC "void gtk_icon_theme_set_search_path GtkIconTheme* icon_theme gchar** path gint n_elements") (CFNC "void gtk_icon_theme_get_search_path GtkIconTheme* icon_theme gchar*** [path] gint* [n_elements]") (CFNC "void gtk_icon_theme_append_search_path GtkIconTheme* icon_theme gchar* path") (CFNC "void gtk_icon_theme_prepend_search_path GtkIconTheme* icon_theme gchar* path") (CFNC "void gtk_icon_theme_set_custom_theme GtkIconTheme* icon_theme gchar* theme_name") (CFNC "gboolean gtk_icon_theme_has_icon GtkIconTheme* icon_theme gchar* icon_name") (CFNC "GtkIconInfo* gtk_icon_theme_lookup_icon GtkIconTheme* icon_theme gchar* icon_name gint size GtkIconLookupFlags flags") (CFNC "GdkPixbuf* gtk_icon_theme_load_icon GtkIconTheme* icon_theme gchar* icon_name gint size GtkIconLookupFlags flags GError** [error]") (CFNC "GList* gtk_icon_theme_list_icons GtkIconTheme* icon_theme gchar* context") (CFNC "char* gtk_icon_theme_get_example_icon_name GtkIconTheme* icon_theme") (CFNC "gboolean gtk_icon_theme_rescan_if_needed GtkIconTheme* icon_theme") ;;; 3.13.4 (CFNC "void gtk_icon_theme_add_builtin_icon gchar* icon_name gint size GdkPixbuf* pixbuf") ;;;;(CFNC "GType gtk_icon_info_get_type void") ;;; 3.7.10 (CFNC "GtkIconInfo* gtk_icon_info_copy GtkIconInfo* icon_info") ;;; 3.7.10 (CFNC "void gtk_icon_info_free GtkIconInfo* icon_info") (CFNC "gint gtk_icon_info_get_base_size GtkIconInfo* icon_info") (CFNC "gchar* gtk_icon_info_get_filename GtkIconInfo* icon_info") ;;; 3.13.4 (CFNC "GdkPixbuf* gtk_icon_info_get_builtin_pixbuf GtkIconInfo* icon_info") (CFNC "GdkPixbuf* gtk_icon_info_load_icon GtkIconInfo* icon_info GError** [error]") ;;; 3.13.3 (CFNC "void gtk_icon_info_set_raw_coordinates GtkIconInfo* icon_info gboolean raw_coordinates") ;;; 3.13.3 (CFNC "gboolean gtk_icon_info_get_embedded_rect GtkIconInfo* icon_info GdkRectangle* rectangle") ;;; 3.13.3 ;;; (CFNC "gboolean gtk_icon_info_get_attach_points GtkIconInfo* icon_info GdkPoint** [points] gint* [n_points]") ;;; 3.13.3 (CFNC "gchar* gtk_icon_info_get_display_name GtkIconInfo* icon_info") ;;;;(CFNC "GType gtk_tool_button_get_type void") (CFNC "GtkToolItem* gtk_tool_button_new GtkWidget* @icon_widget gchar* label") ;;; (CFNC "GtkToolItem* gtk_tool_button_new_from_stock gchar* stock_id") (CFNC "void gtk_tool_button_set_label GtkToolButton* button gchar* label") (CFNC "gchar* gtk_tool_button_get_label GtkToolButton* button") (CFNC "void gtk_tool_button_set_use_underline GtkToolButton* button gboolean use_underline") (CFNC "gboolean gtk_tool_button_get_use_underline GtkToolButton* button") ;;; (CFNC "void gtk_tool_button_set_stock_id GtkToolButton* button gchar* stock_id") ;;; (CFNC "gchar* gtk_tool_button_get_stock_id GtkToolButton* button") (CFNC "void gtk_tool_button_set_icon_widget GtkToolButton* button GtkWidget* @icon_widget") (CFNC "GtkWidget* gtk_tool_button_get_icon_widget GtkToolButton* button") (CFNC "void gtk_tool_button_set_label_widget GtkToolButton* button GtkWidget* @label_widget") (CFNC "GtkWidget* gtk_tool_button_get_label_widget GtkToolButton* button") ;;;;(CFNC "GType gtk_tool_item_get_type void") (CFNC "GtkToolItem* gtk_tool_item_new void") (CFNC "void gtk_tool_item_set_homogeneous GtkToolItem* tool_item gboolean homogeneous") (CFNC "gboolean gtk_tool_item_get_homogeneous GtkToolItem* tool_item") (CFNC "void gtk_tool_item_set_expand GtkToolItem* tool_item gboolean expand") (CFNC "gboolean gtk_tool_item_get_expand GtkToolItem* tool_item") ;;;(CFNC "void gtk_tool_item_set_pack_end GtkToolItem* tool_item gboolean pack_end") ;;;(CFNC "gboolean gtk_tool_item_get_pack_end GtkToolItem* tool_item") ;;; out 2.11.6 (CFNC "void gtk_tool_item_set_tooltip GtkToolItem* tool_item GtkTooltips* tooltips gchar* tip_text gchar* tip_private") (CFNC "void gtk_tool_item_set_use_drag_window GtkToolItem* toolitem gboolean use_drag_window") (CFNC "gboolean gtk_tool_item_get_use_drag_window GtkToolItem* toolitem") (CFNC "void gtk_tool_item_set_visible_horizontal GtkToolItem* toolitem gboolean visible_horizontal") (CFNC "gboolean gtk_tool_item_get_visible_horizontal GtkToolItem* toolitem") (CFNC "void gtk_tool_item_set_visible_vertical GtkToolItem* toolitem gboolean visible_vertical") (CFNC "gboolean gtk_tool_item_get_visible_vertical GtkToolItem* toolitem") (CFNC "gboolean gtk_tool_item_get_is_important GtkToolItem* tool_item") (CFNC "void gtk_tool_item_set_is_important GtkToolItem* tool_item gboolean is_important") ;;; (CFNC "GtkIconSize gtk_tool_item_get_icon_size GtkToolItem* tool_item") (CFNC "GtkOrientation gtk_tool_item_get_orientation GtkToolItem* tool_item") (CFNC "GtkToolbarStyle gtk_tool_item_get_toolbar_style GtkToolItem* tool_item") (CFNC "GtkReliefStyle gtk_tool_item_get_relief_style GtkToolItem* tool_item") (CFNC "GtkWidget* gtk_tool_item_retrieve_proxy_menu_item GtkToolItem* tool_item") (CFNC "GtkWidget* gtk_tool_item_get_proxy_menu_item GtkToolItem* tool_item gchar* menu_item_id") (CFNC "void gtk_tool_item_set_proxy_menu_item GtkToolItem* @tool_item gchar* menu_item_id GtkWidget* @menu_item") (CFNC "gboolean gtk_list_store_remove GtkListStore* list_store GtkTreeIter* iter") ;;; type changed at some point (CFNC "void gdk_display_set_double_click_distance GdkDisplay* display guint distance") (CFNC "GdkWindow* gdk_display_get_default_group GdkDisplay* display") ;;; changed return type 2.90.1 (CFNC "void gdk_window_set_accept_focus GdkWindow* window gboolean accept_focus") (CFNC "GdkWindow* gdk_window_get_group GdkWindow* window") ;;; 3.9.8 ;;; (CFNC "gboolean gtk_action_group_get_sensitive GtkActionGroup* action_group") ;;; (CFNC "void gtk_action_group_set_sensitive GtkActionGroup* action_group gboolean sensitive") ;;; (CFNC "gboolean gtk_action_group_get_visible GtkActionGroup* action_group") ;;; (CFNC "void gtk_action_group_set_visible GtkActionGroup* action_group gboolean visible") ;;; (CFNC "void gtk_action_group_add_action_with_accel GtkActionGroup* action_group GtkAction* action gchar* accelerator") ;;; (CFNC "GtkAction* gtk_action_new gchar* name gchar* label gchar* tooltip gchar* stock_id") ;;; (CFNC "gboolean gtk_action_is_sensitive GtkAction* action") ;;; (CFNC "gboolean gtk_action_get_sensitive GtkAction* action") ;;; (CFNC "gboolean gtk_action_is_visible GtkAction* action") ;;; (CFNC "gboolean gtk_action_get_visible GtkAction* action") ;;; 3.13.2 (CFNC "void gtk_button_set_alignment GtkButton* button gfloat xalign gfloat yalign") ;;; 3.13.2 (CFNC "void gtk_button_get_alignment GtkButton* button gfloat* [xalign] gfloat* [yalign]") (CFNC "void gtk_cell_layout_reorder GtkCellLayout* cell_layout GtkCellRenderer* cell gint position") (CFNC "void gtk_clipboard_request_targets GtkClipboard* clipboard GtkClipboardTargetsReceivedFunc func lambda_data #func_info") (CFNC "gboolean gtk_clipboard_wait_for_targets GtkClipboard* clipboard GdkAtom** [targets] gint* [n_targets]") ; FREE (targets) (CFNC "void gtk_menu_shell_cancel GtkMenuShell* menu_shell") (CFNC "GtkWidget* gtk_paned_get_child1 GtkPaned* paned") (CFNC "GtkWidget* gtk_paned_get_child2 GtkPaned* paned") ;;; (CFNC "GtkRadioAction* gtk_radio_action_new gchar* name gchar* label gchar* tooltip gchar* stock_id gint value") ;;; (CFNC "GtkToggleAction* gtk_toggle_action_new gchar* name gchar* label gchar* tooltip gchar* stock_id") (CFNC "void gtk_window_set_accept_focus GtkWindow* window gboolean setting") (CFNC "gboolean gtk_window_get_accept_focus GtkWindow* window") (CFNC "gpointer g_list_nth_data GList* list guint n") (CCAST "GTK_ACCEL_MAP(obj)" "GtkAccelMap") (CCHK "GTK_IS_ACCEL_MAP(obj)" "GtkAccelMap") ;;;;(CFNC "GType gtk_accel_map_get_type void") (CFNC "GtkAccelMap* gtk_accel_map_get void") (CFNC "void gtk_combo_box_popup GtkComboBox* combo_box") (CFNC "void gtk_combo_box_popdown GtkComboBox* combo_box") (CFNC "GtkWidget* gtk_radio_menu_item_new_from_widget GtkRadioMenuItem* group") (CFNC "GtkWidget* gtk_radio_menu_item_new_with_mnemonic_from_widget GtkRadioMenuItem* group gchar* label") (CFNC "GtkWidget* gtk_radio_menu_item_new_with_label_from_widget GtkRadioMenuItem* group gchar* label") (CFNC "PangoLayout* gtk_scale_get_layout GtkScale* scale") (CFNC "void gtk_scale_get_layout_offsets GtkScale* scale gint* [x] gint* [y]") ;;; (CFNC "gboolean gtk_tooltips_get_info_from_tip_window GtkWindow* tip_window GtkTooltips** [tooltips] GtkWidget** [current_widget]") (CINT "GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER" "GtkFileChooserAction") (CINT "GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER" "GtkFileChooserAction") ;;; 2.91.1 (CFNC "GtkWidget* gtk_combo_box_entry_new_text void") (CFNC "GtkTargetList* gtk_drag_source_get_target_list GtkWidget* widget") (CFNC "void gtk_drag_source_set_target_list GtkWidget* widget GtkTargetList* @target_list") (CFNC "void gtk_entry_set_alignment GtkEntry* entry gfloat xalign") (CFNC "gfloat gtk_entry_get_alignment GtkEntry* entry") (CFNC "void gtk_file_chooser_set_use_preview_label GtkFileChooser* chooser gboolean use_label") (CFNC "gboolean gtk_file_chooser_get_use_preview_label GtkFileChooser* chooser") ;;; 2.13.6. (CFNC "GtkWidget* gtk_file_chooser_widget_new_with_backend GtkFileChooserAction action gchar* backend") ;;; ;(CFNC-gtk2 "void gtk_rc_reset_styles GtkSettings* settings") ;;;(CFNC "void gtk_text_layout_set_keyboard_direction GtkTextLayout* layout GtkTextDirection keyboard_dir") ;;;GtkTextLayout is buggy (CFNC "GList* gtk_widget_list_mnemonic_labels GtkWidget* widget") ; FREE (g_list_free) (CFNC "void gtk_widget_add_mnemonic_label GtkWidget* widget GtkWidget* label") (CFNC "void gtk_widget_remove_mnemonic_label GtkWidget* widget GtkWidget* label") (CFNC "gboolean gtk_window_activate_key GtkWindow* window GdkEventKey* event") (CFNC "gboolean gtk_window_propagate_key_event GtkWindow* window GdkEventKey* event") (CINT "G_PRIORITY_HIGH" "gint") (CINT "G_PRIORITY_DEFAULT" "gint") (CINT "G_PRIORITY_HIGH_IDLE" "gint") (CINT "G_PRIORITY_DEFAULT_IDLE" "gint") (CINT "G_PRIORITY_LOW" "gint") (CFNC "GQuark g_quark_from_string gchar* string") (CFNC "gchar* g_quark_to_string GQuark quark") ;;; 2.91.6 (CLNG "GTK_TYPE_CELL_VIEW") (CCAST "GTK_CELL_VIEW(obj)" "GtkCellView*") (CCHK "GTK_IS_CELL_VIEW(obj)" "GtkCellView*") ;;; 2.91.6 (CLNG "GTK_TYPE_ABOUT_DIALOG") (CCAST "GTK_ABOUT_DIALOG(obj)" "GtkAboutDialog*") (CCHK "GTK_IS_ABOUT_DIALOG(obj)" "GtkAboutDialog*") ;;; 2.91.6 (CLNG "GTK_TYPE_CELL_RENDERER_COMBO") (CCAST "GTK_CELL_RENDERER_COMBO(obj)" "GtkCellRendererCombo*") (CCHK "GTK_IS_CELL_RENDERER_COMBO(obj)" "GtkCellRendererCombo*") ;;; 2.91.6 (CLNG "GTK_TYPE_CELL_RENDERER_PROGRESS") (CCAST "GTK_CELL_RENDERER_PROGRESS(obj)" "GtkCellRendererProgress*") (CCHK "GTK_IS_CELL_RENDERER_PROGRESS(obj)" "GtkCellRendererProgress*") ;;; 2.91.6 (CLNG "GTK_TYPE_ICON_VIEW") (CCAST "GTK_ICON_VIEW(obj)" "GtkIconView*") (CCHK "GTK_IS_ICON_VIEW(obj)" "GtkIconView*") ;;;;(CFNC "GType gtk_cell_view_get_type void") (CFNC "GtkWidget* gtk_cell_view_new void") (CFNC "GtkWidget* gtk_cell_view_new_with_text gchar* text") (CFNC "GtkWidget* gtk_cell_view_new_with_markup gchar* markup") (CFNC "GtkWidget* gtk_cell_view_new_with_pixbuf GdkPixbuf* pixbuf") ;;;(CFNC "void gtk_cell_view_set_value GtkCellView* cell_view GtkCellRenderer* renderer gchar* property GValue* value") ;;;(CFNC "void gtk_cell_view_set_values GtkCellView* cell_view GtkCellRenderer* renderer ...") (CFNC "void gtk_cell_view_set_model GtkCellView* cell_view GtkTreeModel* @model") (CFNC "void gtk_cell_view_set_displayed_row GtkCellView* cell_view GtkTreePath* path") (CFNC "GtkTreePath* gtk_cell_view_get_displayed_row GtkCellView* cell_view") ;;; (CFNC-gtk2 "gboolean gtk_cell_view_get_size_of_row GtkCellView* cell_view GtkTreePath* path GtkRequisition* requisition") ; assumes requisition is alloc'd ;;; (CFNC-gtk2 "void gtk_cell_view_set_background_color GtkCellView* cell_view GdkColor* color") ;;; out 2.5.6 (CFNC "void gtk_cell_view_set_cell_data GtkCellView* cellview") ;;; out 2.17.2 (CFNC "GList* gtk_cell_view_get_cell_renderers GtkCellView* cellview") ; FREE (g_list_free) ;;; changed return type 2.90.1 (CFNC "void gdk_window_set_focus_on_map GdkWindow* window gboolean focus_on_map") ;;; 3.7.10 (CFNC "void gdk_window_enable_synchronized_configure GdkWindow* window") ;;; 3.7.10 (CFNC "void gdk_window_configure_finished GdkWindow* window") ;;;(CFNC "gchar* gtk_action_group_translate_string GtkActionGroup* action_group gchar* string") -- out 2.5.2 (CFNC "gint gtk_combo_box_get_wrap_width GtkComboBox* combo_box") (CFNC "gint gtk_combo_box_get_row_span_column GtkComboBox* combo_box") (CFNC "gint gtk_combo_box_get_column_span_column GtkComboBox* combo_box") ;;; 3.3.2 (CFNC "gboolean gtk_combo_box_get_add_tearoffs GtkComboBox* combo_box") ;;; 3.3.2 (CFNC "void gtk_combo_box_set_add_tearoffs GtkComboBox* combo_box gboolean add_tearoffs") ;;; (CFNC "void gtk_combo_box_set_row_separator_column GtkComboBox* combo_box gint column") ;;; (CFNC "gint gtk_combo_box_get_row_separator_column GtkComboBox* combo_box") ;;; changed in 2.5.1 ;;; 2.91.1 (CFNC "gchar* gtk_combo_box_get_active_text GtkComboBox* combo_box" 'free) (CFNC "void gtk_drag_dest_add_text_targets GtkWidget* widget") (CFNC "void gtk_drag_source_add_text_targets GtkWidget* widget") (CFNC "void gtk_entry_completion_insert_prefix GtkEntryCompletion* completion") (CFNC "void gtk_entry_completion_set_inline_completion GtkEntryCompletion* completion gboolean inline_completion") (CFNC "gboolean gtk_entry_completion_get_inline_completion GtkEntryCompletion* completion") (CFNC "void gtk_entry_completion_set_popup_completion GtkEntryCompletion* completion gboolean popup_completion") (CFNC "gboolean gtk_entry_completion_get_popup_completion GtkEntryCompletion* completion") (CFNC "gint gtk_entry_completion_get_text_column GtkEntryCompletion* completion") (CFNC "gint* gtk_icon_theme_get_icon_sizes GtkIconTheme* icon_theme gchar* icon_name") ; FREE (CFNC "GList* gtk_menu_get_for_attach_widget GtkWidget* widget ") ;;; (CFNC "void gtk_target_list_add_text_targets GtkTargetList* list") -- added arg in 2.5.4 (CFNC "void gtk_tree_view_set_fixed_height_mode GtkTreeView* tree_view gboolean enable") (CFNC "gboolean gtk_tree_view_get_fixed_height_mode GtkTreeView* tree_view") (CFNC "void gtk_tree_view_set_hover_selection GtkTreeView* tree_view gboolean hover") (CFNC "gboolean gtk_tree_view_get_hover_selection GtkTreeView* tree_view") ;;; this can't work in this context without more effort than its worth ;;; (CFNC "GtkTreeViewRowSeparatorFunc gtk_tree_view_get_row_separator_func GtkTreeView* tree_view") (CFNC "void gtk_tree_view_set_row_separator_func GtkTreeView* tree_view GtkTreeViewRowSeparatorFunc func lambda_data func_info GtkDestroyNotify destroy") (CFNC "void gtk_window_set_focus_on_map GtkWindow* window gboolean setting") (CFNC "gboolean gtk_window_get_focus_on_map GtkWindow* window") (CFNC "void gtk_window_set_icon_name GtkWindow* window gchar* name") (CFNC "gchar* gtk_window_get_icon_name GtkWindow* window") (CFNC "void gtk_window_set_default_icon_name gchar* name") ;;;;(CFNC "GType gtk_about_dialog_get_type void") (CFNC "GtkWidget* gtk_about_dialog_new void") ;;; (CFNC "gchar* gtk_about_dialog_get_name GtkAboutDialog* about") ; name changed in 2.11.0 ;;; (CFNC "void gtk_about_dialog_set_name GtkAboutDialog* about gchar* name") (CFNC "gchar* gtk_about_dialog_get_version GtkAboutDialog* about") (CFNC "void gtk_about_dialog_set_version GtkAboutDialog* about gchar* version") (CFNC "gchar* gtk_about_dialog_get_copyright GtkAboutDialog* about") (CFNC "void gtk_about_dialog_set_copyright GtkAboutDialog* about gchar* copyright") (CFNC "gchar* gtk_about_dialog_get_comments GtkAboutDialog* about") (CFNC "void gtk_about_dialog_set_comments GtkAboutDialog* about gchar* comments") ;(CFNC "gchar* gtk_about_dialog_get_license GtkAboutDialog* about") ;(CFNC "void gtk_about_dialog_set_license GtkAboutDialog* about gchar* license") (CFNC "gchar* gtk_about_dialog_get_website GtkAboutDialog* about") (CFNC "void gtk_about_dialog_set_website GtkAboutDialog* about gchar* website") (CFNC "gchar* gtk_about_dialog_get_website_label GtkAboutDialog* about") (CFNC "void gtk_about_dialog_set_website_label GtkAboutDialog* about gchar* website_label") (CFNC "gchar** gtk_about_dialog_get_authors GtkAboutDialog* about" 'const-return) (CFNC "void gtk_about_dialog_set_authors GtkAboutDialog* about gchar** authors" 'const) (CFNC "gchar** gtk_about_dialog_get_documenters GtkAboutDialog* about" 'const-return) (CFNC "void gtk_about_dialog_set_documenters GtkAboutDialog* about gchar** documenters" 'const) (CFNC "gchar** gtk_about_dialog_get_artists GtkAboutDialog* about" 'const-return) (CFNC "void gtk_about_dialog_set_artists GtkAboutDialog* about gchar** artists" 'const) (CFNC "gchar* gtk_about_dialog_get_translator_credits GtkAboutDialog* about") (CFNC "void gtk_about_dialog_set_translator_credits GtkAboutDialog* about gchar* translator_credits") (CFNC "GdkPixbuf* gtk_about_dialog_get_logo GtkAboutDialog* about") (CFNC "void gtk_about_dialog_set_logo GtkAboutDialog* about GdkPixbuf* @logo") ;;; order matters here (CFNC "gchar* gtk_about_dialog_get_program_name GtkAboutDialog* about") (CFNC "void gtk_about_dialog_set_program_name GtkAboutDialog* about gchar* name") ;;;;(CFNC "GType gtk_icon_view_get_type void") (CFNC "GtkWidget* gtk_icon_view_new void") (CFNC "GtkWidget* gtk_icon_view_new_with_model GtkTreeModel* model") (CFNC "void gtk_icon_view_set_model GtkIconView* icon_view GtkTreeModel* @model") (CFNC "GtkTreeModel* gtk_icon_view_get_model GtkIconView* icon_view") (CFNC "void gtk_icon_view_set_text_column GtkIconView* icon_view gint column") (CFNC "gint gtk_icon_view_get_text_column GtkIconView* icon_view") (CFNC "void gtk_icon_view_set_markup_column GtkIconView* icon_view gint column") (CFNC "gint gtk_icon_view_get_markup_column GtkIconView* icon_view") (CFNC "void gtk_icon_view_set_pixbuf_column GtkIconView* icon_view gint column") (CFNC "gint gtk_icon_view_get_pixbuf_column GtkIconView* icon_view") ;;; 2.90.7 (CFNC "void gtk_icon_view_set_orientation GtkIconView* icon_view GtkOrientation orientation") ;;; 2.90.7 (CFNC "GtkOrientation gtk_icon_view_get_orientation GtkIconView* icon_view") (CFNC "GtkTreePath* gtk_icon_view_get_path_at_pos GtkIconView* icon_view gint x gint y") (CFNC "void gtk_icon_view_selected_foreach GtkIconView* icon_view GtkIconViewForeachFunc func lambda_data #func_info") (CFNC "void gtk_icon_view_set_selection_mode GtkIconView* icon_view GtkSelectionMode mode") (CFNC "GtkSelectionMode gtk_icon_view_get_selection_mode GtkIconView* icon_view") ;;;; these two are in the header file but not the c file -- out 2.5.2 ;;; (CFNC "gboolean gtk_icon_view_get_text_beside_icon GtkIconView* icon_view") ;;; (CFNC "void gtk_icon_view_set_text_beside_icon GtkIconView* icon_view gboolean text_beside_icon") (CFNC "void gtk_icon_view_select_path GtkIconView* icon_view GtkTreePath* path") (CFNC "void gtk_icon_view_unselect_path GtkIconView* icon_view GtkTreePath* path") (CFNC "gboolean gtk_icon_view_path_is_selected GtkIconView* icon_view GtkTreePath* path") (CFNC "GList* gtk_icon_view_get_selected_items GtkIconView* icon_view") (CFNC "void gtk_icon_view_select_all GtkIconView* icon_view") (CFNC "void gtk_icon_view_unselect_all GtkIconView* icon_view") (CFNC "void gtk_icon_view_item_activated GtkIconView* icon_view GtkTreePath* path") ;;;;(CFNC "GType gtk_cell_renderer_combo_get_type void") (CFNC "GtkCellRenderer* gtk_cell_renderer_combo_new void") ;;;;(CFNC "GType gtk_cell_renderer_progress_get_type void") (CFNC "GtkCellRenderer* gtk_cell_renderer_progress_new void") (CFNC "void gtk_combo_box_set_row_separator_func GtkComboBox* combo_box GtkTreeViewRowSeparatorFunc func lambda_data func_info GtkDestroyNotify destroy") (CFNC "void gtk_label_set_ellipsize GtkLabel* label PangoEllipsizeMode mode") (CFNC "PangoEllipsizeMode gtk_label_get_ellipsize GtkLabel* label") (CINT "PANGO_ATTR_FALLBACK" "PangoAttrType") (CINT "PANGO_ATTR_LETTER_SPACING" "PangoAttrType") (CINT "PANGO_UNDERLINE_ERROR" "PangoUnderline") (CINT "PANGO_WRAP_WORD_CHAR" "PangoWrapMode") (CINT "PANGO_ELLIPSIZE_NONE" "PangoEllipsizeMode") (CINT "PANGO_ELLIPSIZE_START" "PangoEllipsizeMode") (CINT "PANGO_ELLIPSIZE_MIDDLE" "PangoEllipsizeMode") (CINT "PANGO_ELLIPSIZE_END" "PangoEllipsizeMode") (CINT "PANGO_SCRIPT_INVALID_CODE" "PangoScript") (CINT "PANGO_SCRIPT_COMMON" "PangoScript") (CINT "PANGO_SCRIPT_INHERITED" "PangoScript") (CINT "PANGO_SCRIPT_ARABIC" "PangoScript") (CINT "PANGO_SCRIPT_ARMENIAN" "PangoScript") (CINT "PANGO_SCRIPT_BENGALI" "PangoScript") (CINT "PANGO_SCRIPT_BOPOMOFO" "PangoScript") (CINT "PANGO_SCRIPT_CHEROKEE" "PangoScript") (CINT "PANGO_SCRIPT_COPTIC" "PangoScript") (CINT "PANGO_SCRIPT_CYRILLIC" "PangoScript") (CINT "PANGO_SCRIPT_DESERET" "PangoScript") (CINT "PANGO_SCRIPT_DEVANAGARI" "PangoScript") (CINT "PANGO_SCRIPT_ETHIOPIC" "PangoScript") (CINT "PANGO_SCRIPT_GEORGIAN" "PangoScript") (CINT "PANGO_SCRIPT_GOTHIC" "PangoScript") (CINT "PANGO_SCRIPT_GREEK" "PangoScript") (CINT "PANGO_SCRIPT_GUJARATI" "PangoScript") (CINT "PANGO_SCRIPT_GURMUKHI" "PangoScript") (CINT "PANGO_SCRIPT_HAN" "PangoScript") (CINT "PANGO_SCRIPT_HANGUL" "PangoScript") (CINT "PANGO_SCRIPT_HEBREW" "PangoScript") (CINT "PANGO_SCRIPT_HIRAGANA" "PangoScript") (CINT "PANGO_SCRIPT_KANNADA" "PangoScript") (CINT "PANGO_SCRIPT_KATAKANA" "PangoScript") (CINT "PANGO_SCRIPT_KHMER" "PangoScript") (CINT "PANGO_SCRIPT_LAO" "PangoScript") (CINT "PANGO_SCRIPT_LATIN" "PangoScript") (CINT "PANGO_SCRIPT_MALAYALAM" "PangoScript") (CINT "PANGO_SCRIPT_MONGOLIAN" "PangoScript") (CINT "PANGO_SCRIPT_MYANMAR" "PangoScript") (CINT "PANGO_SCRIPT_OGHAM" "PangoScript") (CINT "PANGO_SCRIPT_OLD_ITALIC" "PangoScript") (CINT "PANGO_SCRIPT_ORIYA" "PangoScript") (CINT "PANGO_SCRIPT_RUNIC" "PangoScript") (CINT "PANGO_SCRIPT_SINHALA" "PangoScript") (CINT "PANGO_SCRIPT_SYRIAC" "PangoScript") (CINT "PANGO_SCRIPT_TAMIL" "PangoScript") (CINT "PANGO_SCRIPT_TELUGU" "PangoScript") (CINT "PANGO_SCRIPT_THAANA" "PangoScript") (CINT "PANGO_SCRIPT_THAI" "PangoScript") (CINT "PANGO_SCRIPT_TIBETAN" "PangoScript") (CINT "PANGO_SCRIPT_CANADIAN_ABORIGINAL" "PangoScript") (CINT "PANGO_SCRIPT_YI" "PangoScript") (CINT "PANGO_SCRIPT_TAGALOG" "PangoScript") (CINT "PANGO_SCRIPT_HANUNOO" "PangoScript") (CINT "PANGO_SCRIPT_BUHID" "PangoScript") (CINT "PANGO_SCRIPT_TAGBANWA" "PangoScript") (CINT "PANGO_SCRIPT_BRAILLE" "PangoScript") (CINT "PANGO_SCRIPT_CYPRIOT" "PangoScript") (CINT "PANGO_SCRIPT_LIMBU" "PangoScript") (CINT "PANGO_SCRIPT_OSMANYA" "PangoScript") (CINT "PANGO_SCRIPT_SHAVIAN" "PangoScript") (CINT "PANGO_SCRIPT_LINEAR_B" "PangoScript") (CINT "PANGO_SCRIPT_TAI_LE" "PangoScript") (CINT "PANGO_SCRIPT_UGARITIC" "PangoScript") (CINT "PANGO_TAB_LEFT" "PangoTabAlign") (CINT "PANGO_DIRECTION_WEAK_LTR" "PangoDirection") (CINT "PANGO_DIRECTION_WEAK_RTL" "PangoDirection") (CINT "PANGO_DIRECTION_NEUTRAL" "PangoDirection") ;; picked up from various headers -- not necessarily new in 1.5.2 (CFNC "PangoAttribute* pango_attr_fallback_new gboolean enable_fallback") (CFNC "PangoAttribute* pango_attr_letter_spacing_new int letter_spacing") (CFNC "PangoAttrList* pango_attr_list_filter PangoAttrList* list PangoAttrFilterFunc func gpointer data") ; FREE (CFNC "GSList* pango_attr_iterator_get_attrs PangoAttrIterator* iterator") ;; (CFNC "PangoFontMap* pango_context_get_font_map PangoContext* context") ;;; see below (CFNC "void pango_context_set_matrix PangoContext* context PangoMatrix* matrix") ;;; -- needs const on return I think (CFNC "PangoMatrix* pango_context_get_matrix PangoContext* context") (CFNC "int pango_font_metrics_get_underline_position PangoFontMetrics* metrics") (CFNC "int pango_font_metrics_get_underline_thickness PangoFontMetrics* metrics") (CFNC "int pango_font_metrics_get_strikethrough_position PangoFontMetrics* metrics") (CFNC "int pango_font_metrics_get_strikethrough_thickness PangoFontMetrics* metrics") (CFNC "gboolean pango_font_family_is_monospace PangoFontFamily* family") (CFNC "void pango_font_face_list_sizes PangoFontFace* face int** [sizes] int* [n_sizes]") ;; (CFNC "void pango_fontset_foreach PangoFontset* fontset PangoFontsetForeachFunc func gpointer data") (CFNC "void pango_layout_set_auto_dir PangoLayout* layout gboolean auto_dir") (CFNC "gboolean pango_layout_get_auto_dir PangoLayout* layout") ;;;;;;; (CFNC "GType pango_matrix_get_type void") ;;; changed my mind -- these matrix functions appear to be internal (pango-utils.h) (need PANGO_MATRIX_INIT to get new (static) struct) ;;;(CFNC "PangoMatrix* pango_matrix_copy PangoMatrix* matrix") ;;;(CFNC "void pango_matrix_free PangoMatrix* matrix") ;;;(CFNC "void pango_matrix_translate PangoMatrix* matrix double tx double ty") ;;;(CFNC "void pango_matrix_scale PangoMatrix* matrix double scale_x double scale_y") ;;;(CFNC "void pango_matrix_rotate PangoMatrix* matrix double degrees") ;;;(CFNC "void pango_matrix_concat PangoMatrix* matrix PangoMatrix* new_matrix") (CFNC "PangoScript pango_script_for_unichar gunichar ch") (CFNC "PangoScriptIter* pango_script_iter_new char* text int length") (CFNC "void pango_script_iter_get_range PangoScriptIter* iter char** [start] char** [end] PangoScript* [script]" 'const) (CFNC "gboolean pango_script_iter_next PangoScriptIter* iter") (CFNC "void pango_script_iter_free PangoScriptIter* iter") ;;; (CFNC "PangoLanguage* pango_script_get_sample_language PangoScript script") ;;; (CFNC "gboolean pango_language_includes_script PangoLanguage* language PangoScript script") (CINT "GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID" "void") ;;; 2.91.6 (CLNG "GTK_TYPE_FILE_CHOOSER_BUTTON") (CCAST "GTK_FILE_CHOOSER_BUTTON(obj)" "GtkFileChooserButton*") (CCHK "GTK_IS_FILE_CHOOSER_BUTTON(obj)" "GtkFileChooserButton*") ;;;;(CFNC "GType gtk_file_chooser_button_get_type void") ;;; (CFNC "GtkWidget* gtk_file_chooser_button_new gchar* title") ;;; args changed 2.6.0 ;;; (CFNC "GtkWidget* gtk_file_chooser_button_new_with_backend gchar* title gchar* backend") (CFNC "GtkWidget* gtk_file_chooser_button_new_with_dialog GtkWidget* dialog") (CFNC "gchar* gtk_file_chooser_button_get_title GtkFileChooserButton* button") (CFNC "void gtk_file_chooser_button_set_title GtkFileChooserButton* button gchar* title") ;;; out in 256 (CFNC "gboolean gtk_file_chooser_button_get_active GtkFileChooserButton* button") ;;; ditto (CFNC "void gtk_file_chooser_button_set_active GtkFileChooserButton* button gboolean is_active") (CFNC "gboolean gdk_drag_drop_succeeded GdkDragContext* context") ;;; 2.90.6 (CFNC "gboolean gdk_rgb_colormap_ditherable GdkColormap* cmap") ;;; (CFNC "void gtk_action_set_sensitive GtkAction* action gboolean sensitive") ;;; (CFNC "void gtk_action_set_visible GtkAction* action gboolean visible") ;;; 3.19.2 (CFNC "gboolean gtk_combo_box_get_focus_on_click GtkComboBox* combo") ;;; 3.19.2 (CFNC "void gtk_combo_box_set_focus_on_click GtkComboBox* combo gboolean focus_on_click") ;;; already included? (CFNC "PangoLayout* gtk_entry_get_layout GtkEntry* entry") (CFNC "gint gtk_entry_layout_index_to_text_index GtkEntry* entry gint layout_index") (CFNC "gint gtk_entry_text_index_to_layout_index GtkEntry* entry gint text_index") (CFNC "void gtk_file_chooser_set_show_hidden GtkFileChooser* chooser gboolean show_hidden") (CFNC "gboolean gtk_file_chooser_get_show_hidden GtkFileChooser* chooser") (CFNC "void gtk_tree_view_set_hover_expand GtkTreeView* tree_view gboolean expand") (CFNC "gboolean gtk_tree_view_get_hover_expand GtkTreeView* tree_view") ;;; actually 2.5.3 here (CFNC "void gtk_tool_item_rebuild_menu GtkToolItem* tool_item") (CINT "GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID" "void") ;;; there was also gtk_init_with_args ;;; 2.5.4 (CINT "GTK_IMAGE_ICON_NAME" "GtkImageType") ;;; 2.91.6 (CLNG "GTK_TYPE_MENU_TOOL_BUTTON") (CCAST "GTK_MENU_TOOL_BUTTON(obj)" "GtkMenuToolButton*") (CCHK "GTK_IS_MENU_TOOL_BUTTON(obj)" "GtkMenuToolButton*") ;;;;(CFNC "GType gtk_menu_tool_button_get_type void") (CFNC "GtkToolItem* gtk_menu_tool_button_new GtkWidget* @icon_widget gchar* label") ;;; (CFNC "GtkToolItem* gtk_menu_tool_button_new_from_stock gchar* stock_id") (CFNC "void gtk_menu_tool_button_set_menu GtkMenuToolButton* button GtkWidget* menu") (CFNC "GtkWidget* gtk_menu_tool_button_get_menu GtkMenuToolButton* button") ;;; out 2.11.6 (CFNC "void gtk_menu_tool_button_set_arrow_tooltip GtkMenuToolButton* button GtkTooltips* tooltips gchar* tip_text gchar* tip_private") (CFNC "gboolean gdk_display_supports_clipboard_persistence GdkDisplay* display") ;;; (CFNC "void gdk_display_store_clipboard GdkDisplay* display GdkWindow* clipboard_window guint32 time_ GdkAtom* targets gint n_targets") (CFNC "gchar* gtk_about_dialog_get_logo_icon_name GtkAboutDialog* about") (CFNC "void gtk_about_dialog_set_logo_icon_name GtkAboutDialog* about gchar* icon_name") (CFNC "gchar* gtk_accelerator_get_label guint accelerator_key GdkModifierType accelerator_mods" 'free) (CFNC "gboolean gtk_clipboard_wait_is_target_available GtkClipboard* clipboard GdkAtom target") (CFNC "void gtk_clipboard_set_can_store GtkClipboard* clipboard GtkTargetEntry* @targets gint n_targets") (CFNC "void gtk_clipboard_store GtkClipboard* clipboard") ;;; 3.12? (CFNC "gboolean gtk_alternative_dialog_button_order GdkScreen* @screen") ;;;(CFNC "void gtk_dialog_set_alternative_button_order GtkDialog* dialog gint first_response_id ...") (CFNC "void gtk_drag_dest_add_image_targets GtkWidget* widget") (CFNC "void gtk_drag_dest_add_uri_targets GtkWidget* widget") (CFNC "void gtk_drag_source_add_image_targets GtkWidget* widget") (CFNC "void gtk_drag_source_add_uri_targets GtkWidget* widget") (CFNC "gint gtk_file_chooser_button_get_width_chars GtkFileChooserButton* button") (CFNC "void gtk_file_chooser_button_set_width_chars GtkFileChooserButton* button gint n_chars") ;;; (CFNC "GtkWidget* gtk_image_new_from_icon_name gchar* icon_name GtkIconSize size") ;;; (CFNC "void gtk_image_set_from_icon_name GtkImage* image gchar* icon_name GtkIconSize size") (CFNC "void gtk_image_set_pixel_size GtkImage* image gint pixel_size") ;;;(CFNC "void gtk_image_get_icon_name GtkImage* image gchar** [icon_name] GtkIconSize* [size]" 'const) ;; no free here -- need const (CFNC "gint gtk_image_get_pixel_size GtkImage* image") (CFNC "void gtk_label_set_width_chars GtkLabel* label gint n_chars") (CFNC "gint gtk_label_get_width_chars GtkLabel* label") ;;;(CFNC "void gtk_message_dialog_format_secondary_text GtkMessageDialog* message_dialog gchar* message_format ...") ;;;(CFNC "void gtk_message_dialog_format_secondary_markup GtkMessageDialog* message_dialog gchar* message_format ...") (CFNC "void gtk_target_list_add_text_targets GtkTargetList* list guint info") (CFNC "void gtk_target_list_add_image_targets GtkTargetList* list guint info gboolean writable") (CFNC "void gtk_target_list_add_uri_targets GtkTargetList* list guint info") (CFNC "gboolean gtk_selection_data_set_pixbuf GtkSelectionData* selection_data GdkPixbuf* pixbuf") (CFNC "GdkPixbuf* gtk_selection_data_get_pixbuf GtkSelectionData* selection_data") ; FREE with g_object_unref (CFNC "gboolean gtk_selection_data_set_uris GtkSelectionData* selection_data gchar** uris") (CFNC "gchar** gtk_selection_data_get_uris GtkSelectionData* selection_data") ; FREE with g_strfreev (CFNC "gboolean gtk_text_buffer_backspace GtkTextBuffer* buffer GtkTextIter* iter gboolean interactive gboolean default_editable") (CFNC "void gtk_clipboard_set_image GtkClipboard* clipboard GdkPixbuf* pixbuf") (CFNC "void gtk_clipboard_request_image GtkClipboard* clipboard GtkClipboardImageReceivedFunc func lambda_data #func_info") (CFNC "GdkPixbuf* gtk_clipboard_wait_for_image GtkClipboard* clipboard") (CFNC "gboolean gtk_clipboard_wait_is_image_available GtkClipboard* clipboard") (CFNC "void gtk_file_filter_add_pixbuf_formats GtkFileFilter* filter") (CFNC "void gtk_label_set_single_line_mode GtkLabel* label gboolean single_line_mode") (CFNC "gboolean gtk_label_get_single_line_mode GtkLabel* label") (CFNC "void gtk_progress_bar_set_ellipsize GtkProgressBar* pbar PangoEllipsizeMode mode") (CFNC "PangoEllipsizeMode gtk_progress_bar_get_ellipsize GtkProgressBar* pbar") (CFNC "gboolean gtk_selection_data_targets_include_image GtkSelectionData* selection_data gboolean writable") ;;; 2.91.6 ;;; 2.90.6 (CLNG "GDK_TYPE_PANGO_RENDERER") ;;; 2.90.6 (CCAST "GDK_PANGO_RENDERER" "GdkPangoRenderer") ;;; 2.90.6 (CCHK "GDK_IS_PANGO_RENDERER" "GdkPangoRenderer") ;;; 2.90.6 (CLNG "PANGO_TYPE_RENDERER") ;;; 2.90.6 (CCAST "PANGO_RENDERER" "PangoRenderer") ;;; 2.90.6 (CCHK "PANGO_IS_RENDERER" "PangoRenderer") ;;; 2.90.6 (CLNG "PANGO_TYPE_RENDER_PART") ;;; -- not defined? (CFNC "void gdk_display_add_client_message_filter_full GdkDisplay* display GdkAtom message_type GdkFilterFunc func lambda_data func_info GtkDestroyNotify destroy") ;;; actually GDestroyNotify ;;; 2.90.6 (CFNC "void gdk_draw_glyphs_transformed GdkDrawable* drawable GdkGC* gc PangoMatrix* matrix PangoFont* font gint x gint y PangoGlyphString* glyphs") ;;; 2.90.6 (CFNC "void gdk_draw_trapezoids GdkDrawable* drawable GdkGC* gc GdkTrapezoid* trapezoids gint n_trapezoids") ;;;;(CFNC "GType gdk_pango_renderer_get_type void") ;;; 2.90.6 (CFNC "PangoRenderer* gdk_pango_renderer_new GdkScreen* screen") ;;; 2.90.6 (CFNC "PangoRenderer* gdk_pango_renderer_get_default GdkScreen* screen") ;;; 2.90.6 (CFNC "void gdk_pango_renderer_set_drawable GdkPangoRenderer* gdk_renderer GdkDrawable* drawable") ;;; 2.90.6 (CFNC "void gdk_pango_renderer_set_gc GdkPangoRenderer* gdk_renderer GdkGC* gc") ;;; 2.90.6 (CFNC "void gdk_pango_renderer_set_stipple GdkPangoRenderer* gdk_renderer PangoRenderPart part GdkBitmap* stipple") ;;; 2.90.6 (CFNC "void gdk_pango_renderer_set_override_color GdkPangoRenderer* gdk_renderer PangoRenderPart part GdkColor* color") (CFNC "void gtk_button_set_image GtkButton* button GtkWidget* image") (CFNC "GtkWidget* gtk_button_get_image GtkButton* button") ;;; 3.12? (CFNC "void gtk_dialog_set_alternative_button_order_from_array GtkDialog* dialog gint n_params gint* new_order") (CFNC "void gtk_label_set_angle GtkLabel* label gdouble angle") (CFNC "gdouble gtk_label_get_angle GtkLabel* label") ;;; missed earlier somehow (CFNC "void gtk_menu_set_screen GtkMenu* menu GdkScreen* @screen") (CINT "PANGO_ATTR_UNDERLINE_COLOR" "PangoAttrType") (CINT "PANGO_ATTR_STRIKETHROUGH_COLOR" "PangoAttrType") (CINT "PANGO_RENDER_PART_FOREGROUND" "PangoRenderPart") (CINT "PANGO_RENDER_PART_BACKGROUND" "PangoRenderPart") (CINT "PANGO_RENDER_PART_UNDERLINE" "PangoRenderPart") (CINT "PANGO_RENDER_PART_STRIKETHROUGH" "PangoRenderPart") (CFNC "PangoAttribute* pango_attr_underline_color_new guint16 red guint16 green guint16 blue") (CFNC "PangoAttribute* pango_attr_strikethrough_color_new guint16 red guint16 green guint16 blue") ;;;;(CFNC "GType pango_render_part_get_type void") ;;;;(CFNC "GType pango_renderer_get_type void") (CFNC "void pango_renderer_draw_layout PangoRenderer* renderer PangoLayout* layout int x int y") (CFNC "void pango_renderer_draw_layout_line PangoRenderer* renderer PangoLayoutLine* line int x int y") (CFNC "void pango_renderer_draw_glyphs PangoRenderer* renderer PangoFont* font PangoGlyphString* glyphs int x int y") (CFNC "void pango_renderer_draw_rectangle PangoRenderer* renderer PangoRenderPart part int x int y int width int height") (CFNC "void pango_renderer_draw_error_underline PangoRenderer* renderer int x int y int width int height") (CFNC "void pango_renderer_draw_trapezoid PangoRenderer* renderer PangoRenderPart part double y1 double x11 double x21 double y2 double x12 double x22") (CFNC "void pango_renderer_draw_glyph PangoRenderer* renderer PangoFont* font PangoGlyph glyph double x double y") (CFNC "void pango_renderer_activate PangoRenderer* renderer") (CFNC "void pango_renderer_deactivate PangoRenderer* renderer") (CFNC "void pango_renderer_part_changed PangoRenderer* renderer PangoRenderPart part") (CFNC "void pango_renderer_set_color PangoRenderer* renderer PangoRenderPart part PangoColor* color") (CFNC "PangoColor* pango_renderer_get_color PangoRenderer* renderer PangoRenderPart part") (CFNC "void pango_renderer_set_matrix PangoRenderer* renderer PangoMatrix* matrix") ;;; (needs const on return) (CFNC "PangoMatrix* pango_renderer_get_matrix PangoRenderer* renderer") (CINT "G_LOG_FLAG_RECURSION" "GLogLevelFlags") (CINT "G_LOG_FLAG_FATAL" "GLogLevelFlags") (CINT "G_LOG_LEVEL_ERROR" "GLogLevelFlags") (CINT "G_LOG_LEVEL_CRITICAL" "GLogLevelFlags") (CINT "G_LOG_LEVEL_WARNING" "GLogLevelFlags") (CINT "G_LOG_LEVEL_MESSAGE" "GLogLevelFlags") (CINT "G_LOG_LEVEL_INFO" "GLogLevelFlags") (CINT "G_LOG_LEVEL_DEBUG" "GLogLevelFlags") (CINT "G_LOG_LEVEL_MASK" "GLogLevelFlags") (CINT "G_LOG_FATAL_MASK" "GLogLevelFlags") (CFNC "guint g_log_set_handler gchar* log_domain GLogLevelFlags log_levels GLogFunc func lambda_data #func_info") (CFNC "void g_log_remove_handler gchar* log_domain guint handler_id") (CFNC "void gtk_cell_renderer_stop_editing GtkCellRenderer* cell gboolean canceled") (CFNC "GtkWidget* gtk_file_chooser_button_new gchar* title GtkFileChooserAction action" 'const) ;;; 2.13.6 (CFNC "GtkWidget* gtk_file_chooser_button_new_with_backend gchar* title GtkFileChooserAction action gchar* backend" 'const) (CFNC "void gtk_icon_view_set_columns GtkIconView* icon_view gint columns") (CFNC "gint gtk_icon_view_get_columns GtkIconView* icon_view") (CFNC "void gtk_icon_view_set_item_width GtkIconView* icon_view gint item_width") (CFNC "gint gtk_icon_view_get_item_width GtkIconView* icon_view") (CFNC "void gtk_icon_view_set_spacing GtkIconView* icon_view gint spacing") (CFNC "gint gtk_icon_view_get_spacing GtkIconView* icon_view") (CFNC "void gtk_icon_view_set_row_spacing GtkIconView* icon_view gint row_spacing") (CFNC "gint gtk_icon_view_get_row_spacing GtkIconView* icon_view") (CFNC "void gtk_icon_view_set_column_spacing GtkIconView* icon_view gint column_spacing") (CFNC "gint gtk_icon_view_get_column_spacing GtkIconView* icon_view") (CFNC "void gtk_icon_view_set_margin GtkIconView* icon_view gint margin") (CFNC "gint gtk_icon_view_get_margin GtkIconView* icon_view") (CFNC "void gtk_label_set_max_width_chars GtkLabel* label gint n_chars") (CFNC "gint gtk_label_get_max_width_chars GtkLabel* label") (CFNC "void gtk_list_store_insert_with_values GtkListStore* list_store GtkTreeIter* iter gint position ...") (CFNC "void gtk_list_store_insert_with_valuesv GtkListStore* list_store GtkTreeIter* iter gint position gint* columns GValue* values gint n_values") ;;; (CFNC "void gtk_text_layout_get_iter_at_position GtkTextLayout* layout GtkTextIter* iter gint* [trailing] gint x gint y") ;;; apparently buggy (CFNC "void gtk_text_view_get_iter_at_position GtkTextView* text_view GtkTextIter* iter gint* [trailing] gint x gint y") (CFNC "PangoAttribute* pango_attr_size_new_absolute int size") (CFNC "void pango_font_description_set_absolute_size PangoFontDescription* desc double size") ;;; (CFNC "gboolean pango_font_description_get_size_is_absolute const PangoFontDescription* desc") (CFNC "PangoFontDescription* pango_layout_get_font_description PangoLayout* layout" 'const-return) (CINT "PANGO_WEIGHT_SEMIBOLD") (CINT "GTK_PACK_DIRECTION_LTR" "GtkPackDirection") (CINT "GTK_PACK_DIRECTION_RTL" "GtkPackDirection") (CINT "GTK_PACK_DIRECTION_TTB" "GtkPackDirection") (CINT "GTK_PACK_DIRECTION_BTT" "GtkPackDirection") (CINT "GTK_ICON_VIEW_NO_DROP" "GtkIconViewDropPosition") (CINT "GTK_ICON_VIEW_DROP_INTO" "GtkIconViewDropPosition") (CINT "GTK_ICON_VIEW_DROP_LEFT" "GtkIconViewDropPosition") (CINT "GTK_ICON_VIEW_DROP_RIGHT" "GtkIconViewDropPosition") (CINT "GTK_ICON_VIEW_DROP_ABOVE" "GtkIconViewDropPosition") (CINT "GTK_ICON_VIEW_DROP_BELOW" "GtkIconViewDropPosition") (CFNC "GdkCursor* gdk_cursor_new_from_name GdkDisplay* display gchar* name" 'const) (CFNC "GdkPixbuf* gdk_cursor_get_image GdkCursor* cursor") ;;; 2.99.0 (CFNC "void gdk_display_warp_pointer GdkDisplay* display GdkScreen* screen gint x gint y") ;;; 2.91.0 (CFNC "GdkColormap* gdk_screen_get_rgba_colormap GdkScreen* screen") (CFNC "GdkVisual* gdk_screen_get_rgba_visual GdkScreen* screen") (CFNC "void gdk_window_set_urgency_hint GdkWindow* window gboolean urgent") ;;; (CFNC "GClosure* gtk_action_get_accel_closure GtkAction* action") (CFNC "gint gtk_dialog_get_response_for_widget GtkDialog* dialog GtkWidget* widget") (CFNC "void gtk_drag_source_set_icon_name GtkWidget* widget gchar* icon_name" 'const) (CFNC "void gtk_drag_set_icon_name GdkDragContext* context gchar* icon_name gint hot_x gint hot_y" 'const) (CFNC "void gtk_entry_completion_set_popup_set_width GtkEntryCompletion* completion gboolean popup_set_width") (CFNC "gboolean gtk_entry_completion_get_popup_set_width GtkEntryCompletion* completion") (CFNC "void gtk_entry_completion_set_popup_single_match GtkEntryCompletion* completion gboolean popup_single_match") (CFNC "gboolean gtk_entry_completion_get_popup_single_match GtkEntryCompletion* completion") (CFNC "gboolean gtk_icon_view_get_item_at_pos GtkIconView* icon_view gint x gint y GtkTreePath** [path] GtkCellRenderer** [cell]") (CFNC "gboolean gtk_icon_view_get_visible_range GtkIconView* icon_view GtkTreePath** [start_path] GtkTreePath** [end_path]") (CFNC "void gtk_icon_view_set_cursor GtkIconView* icon_view GtkTreePath* path GtkCellRenderer* cell gboolean start_editing") (CFNC "gboolean gtk_icon_view_get_cursor GtkIconView* icon_view GtkTreePath** [path] GtkCellRenderer** [cell]") (CFNC "void gtk_icon_view_scroll_to_path GtkIconView* icon_view GtkTreePath* path gboolean use_align gfloat row_align gfloat col_align") (CFNC "void gtk_icon_view_enable_model_drag_source GtkIconView* icon_view GdkModifierType start_button_mask GtkTargetEntry* targets gint n_targets GdkDragAction actions") (CFNC "void gtk_icon_view_enable_model_drag_dest GtkIconView* icon_view GtkTargetEntry* targets gint n_targets GdkDragAction actions") (CFNC "void gtk_icon_view_unset_model_drag_source GtkIconView* icon_view") (CFNC "void gtk_icon_view_unset_model_drag_dest GtkIconView* icon_view") (CFNC "void gtk_icon_view_set_reorderable GtkIconView* icon_view gboolean reorderable") (CFNC "gboolean gtk_icon_view_get_reorderable GtkIconView* icon_view") (CFNC "void gtk_icon_view_set_drag_dest_item GtkIconView* icon_view GtkTreePath* path GtkIconViewDropPosition pos") (CFNC "void gtk_icon_view_get_drag_dest_item GtkIconView* icon_view GtkTreePath** [path] GtkIconViewDropPosition* [pos]") (CFNC "gboolean gtk_icon_view_get_dest_item_at_pos GtkIconView* icon_view gint drag_x gint drag_y GtkTreePath** [path] GtkIconViewDropPosition* [pos]") ;;; 2.91.0 (CFNC "GdkPixmap* gtk_icon_view_create_drag_icon GtkIconView* icon_view GtkTreePath* path") (CFNC "void gtk_image_clear GtkImage* image") (CFNC "GtkPackDirection gtk_menu_bar_get_pack_direction GtkMenuBar* menubar") (CFNC "void gtk_menu_bar_set_pack_direction GtkMenuBar* menubar GtkPackDirection pack_dir") (CFNC "GtkPackDirection gtk_menu_bar_get_child_pack_direction GtkMenuBar* menubar") (CFNC "void gtk_menu_bar_set_child_pack_direction GtkMenuBar* menubar GtkPackDirection child_pack_dir") (CFNC "gboolean gtk_menu_shell_get_take_focus GtkMenuShell* menu_shell") (CFNC "void gtk_menu_shell_set_take_focus GtkMenuShell* menu_shell gboolean take_focus") ;;; 3.1.6 (CFNC "GtkWidget* gtk_scrolled_window_get_hscrollbar GtkScrolledWindow* scrolled_window") ;;; 3.1.6 (CFNC "GtkWidget* gtk_scrolled_window_get_vscrollbar GtkScrolledWindow* scrolled_window") (CFNC "void gtk_size_group_set_ignore_hidden GtkSizeGroup* size_group gboolean ignore_hidden") (CFNC "gboolean gtk_size_group_get_ignore_hidden GtkSizeGroup* size_group") ;(CFNC "void gtk_stock_set_translate_func gchar* domain GtkTranslateFunc func lambda_data func_info GtkDestroyNotify notify" 'const) (CFNC "gboolean gtk_text_iter_forward_visible_line GtkTextIter* iter") (CFNC "gboolean gtk_text_iter_backward_visible_line GtkTextIter* iter") (CFNC "gboolean gtk_text_iter_forward_visible_lines GtkTextIter* iter gint count") (CFNC "gboolean gtk_text_iter_backward_visible_lines GtkTextIter* iter gint count") (CFNC "void gtk_tool_button_set_icon_name GtkToolButton* button gchar* icon_name" 'const) (CFNC "gchar* gtk_tool_button_get_icon_name GtkToolButton* button" 'const-return) (CFNC "void gtk_window_set_urgency_hint GtkWindow* window gboolean setting") (CFNC "gboolean gtk_window_get_urgency_hint GtkWindow* window") (CFNC "void gtk_window_present_with_time GtkWindow* window guint32 timestamp") ;(CFNC "PangoFontMap* pango_font_get_font_map PangoFont* font") ;;; (CFNC "void gdk_window_move_region GdkWindow* window GdkRegion* region gint dx gint dy") ;;; from gtkitemfactory: ;typedef gchar * (*GtkTranslateFunc) (const gchar *path, ; gpointer func_info); ; sets label translation func -- not sure how to handle this ; currently all uses are commented out ;;; gtk 2.7.2 ;(CFNC "gboolean gtk_about_dialog_get_wrap_license GtkAboutDialog* about") ;(CFNC "void gtk_about_dialog_set_wrap_license GtkAboutDialog* about gboolean wrap_license") ;;; 2.7.3 (CINT "GTK_FILE_CHOOSER_CONFIRMATION_CONFIRM" "GtkFileChooserConfirmation") (CINT "GTK_FILE_CHOOSER_CONFIRMATION_ACCEPT_FILENAME" "GtkFileChooserConfirmation") (CINT "GTK_FILE_CHOOSER_CONFIRMATION_SELECT_AGAIN" "GtkFileChooserConfirmation") ;;; (CINT "GTK_FILE_CHOOSER_PROP_DO_OVERWRITE_CONFIRMATION" "GtkFileChooserProp") ;;; (CINT "GTK_FILE_CHOOSER_ACTION" "GtkFileChooserProp") ;;; (CINT "GTK_FILE_CHOOSER_PROP_FILE_SYSTEM_BACKEND" "GtkFileChooserProp") ;;; (CINT "GTK_FILE_CHOOSER_PROP_FILTER" "GtkFileChooserProp") ;;; (CINT "GTK_FILE_CHOOSER_PROP_FOLDER_MODE" "GtkFileChooserProp") ;;; (CINT "GTK_FILE_CHOOSER_PROP_LOCAL_ONLY" "GtkFileChooserProp") ;;; (CINT "GTK_FILE_CHOOSER_PROP_PREVIEW_WIDGET" "GtkFileChooserProp") ;;; (CINT "GTK_FILE_CHOOSER_PROP_PREVIEW_WIDGET_ACTIVE" "GtkFileChooserProp") ;;; (CINT "GTK_FILE_CHOOSER_PROP_EXTRA_WIDGET" "GtkFileChooserProp") ;;; (CINT "GTK_FILE_CHOOSER_PROP_SELECT_MULTIPLE" "GtkFileChooserProp") ;;; (CINT "GTK_FILE_CHOOSER_PROP_SHOW_HIDDEN" "GtkFileChooserProp") (CFNC "void gtk_file_chooser_set_do_overwrite_confirmation GtkFileChooser* chooser gboolean do_overwrite_confirmation") (CFNC "gboolean gtk_file_chooser_get_do_overwrite_confirmation GtkFileChooser* chooser") (CFNC "GtkTreeModel* gtk_tree_row_reference_get_model GtkTreeRowReference* reference") (CFNC "void gtk_tree_view_column_queue_resize GtkTreeViewColumn* tree_column") (CFNC "gboolean gtk_tree_view_get_visible_range GtkTreeView* tree_view GtkTreePath** [start_path] GtkTreePath** [end_path]") (CFNC "GtkTextAttributes* gtk_text_attributes_ref GtkTextAttributes* values") (CINT "PANGO_SCRIPT_NEW_TAI_LUE" "PangoScript") (CINT "PANGO_SCRIPT_BUGINESE" "PangoScript") (CINT "PANGO_SCRIPT_GLAGOLITIC" "PangoScript") (CINT "PANGO_SCRIPT_TIFINAGH" "PangoScript") (CINT "PANGO_SCRIPT_SYLOTI_NAGRI" "PangoScript") (CINT "PANGO_SCRIPT_OLD_PERSIAN" "PangoScript") (CINT "PANGO_SCRIPT_KHAROSHTHI" "PangoScript") ;;; (CLNG "PANGO_TYPE_ITEM") ;;; (CLNG "PANGO_TYPE_LAYOUT_LINE") ;; 11.2: + double pango_matrix_get_font_scale_factor (PangoMatrix *matrix); (CFNC "PangoAttrList* pango_attr_list_ref PangoAttrList* list") ;;;;(CFNC "GType pango_item_get_type void") ;;;;(CFNC "GType pango_layout_line_get_type void") (CFNC "PangoLayoutLine* pango_layout_line_ref PangoLayoutLine* line") ;(CFNC "gboolean pango_is_zero_width gunichar ch" 'const-return) (CFNC "void pango_layout_index_to_line_x PangoLayout* layout int index_ gboolean trailing int* [line] int* [x_pos]") ;;; 2.91.6 (CLNG "GTK_TYPE_RECENT_INFO") ;;; 2.91.6 (CLNG "GTK_TYPE_CELL_RENDERER_ACCEL") ;;; 2.91.6 (CLNG "GTK_TYPE_ASSISTANT") ;;; 2.91.6 (CLNG "GTK_TYPE_CELL_RENDERER_SPIN") ;;; 2.91.6 (CLNG "GTK_TYPE_LINK_BUTTON") ;;; 2.91.6 (CLNG "GTK_TYPE_RECENT_CHOOSER_DIALOG") ;;; 2.91.6 (CLNG "GTK_TYPE_RECENT_CHOOSER") ;;; 2.91.6 (CLNG "GTK_TYPE_RECENT_CHOOSER_MENU") ;;; 2.91.6 (CLNG "GTK_TYPE_RECENT_CHOOSER_WIDGET") ;;; 2.91.6 (CLNG "GTK_TYPE_STATUS_ICON") ;;; 2.91.6 (CLNG "GTK_TYPE_RECENT_MANAGER") ;;; 2.91.6 (CLNG "GTK_TYPE_RECENT_FILTER") (CCAST "GTK_ASSISTANT(obj)" "GtkAssistant*") (CCHK "GTK_IS_ASSISTANT(obj)" "GtkAssistant*") (CCAST "GTK_CELL_RENDERER_ACCEL(obj)" "GtkCellRendererAccel*") (CCHK "GTK_IS_CELL_RENDERER_ACCEL(obj)" "GtkCellRendererAccel*") (CCAST "GTK_CELL_RENDERER_SPIN(obj)" "GtkCellRendererSpin*") (CCHK "GTK_IS_CELL_RENDERER_SPIN(obj)" "GtkCellRendererSpin*") (CCAST "GTK_LINK_BUTTON(obj)" "GtkLinkButton*") (CCHK "GTK_IS_LINK_BUTTON(obj)" "GtkLinkButton*") (CCAST "GTK_RECENT_CHOOSER_DIALOG(obj)" "GtkRecentChooserDialog*") (CCHK "GTK_IS_RECENT_CHOOSER_DIALOG(obj)" "GtkRecentChooserDialog*") (CCAST "GTK_RECENT_CHOOSER(obj)" "GtkRecentChooser*") (CCHK "GTK_IS_RECENT_CHOOSER(obj)" "GtkRecentChooser*") (CCAST "GTK_RECENT_CHOOSER_MENU(obj)" "GtkRecentChooserMenu*") (CCHK "GTK_IS_RECENT_CHOOSER_MENU(obj)" "GtkRecentChooserMenu*") (CCAST "GTK_RECENT_CHOOSER_WIDGET(obj)" "GtkRecentChooserWidget*") (CCHK "GTK_IS_RECENT_CHOOSER_WIDGET(obj)" "GtkRecentChooserWidget*") (CCAST "GTK_RECENT_FILTER(obj)" "GtkRecentFilter*") (CCHK "GTK_IS_RECENT_FILTER(obj)" "GtkRecentFilter*") (CCAST "GTK_RECENT_MANAGER(obj)" "GtkRecentManager*") (CCHK "GTK_IS_RECENT_MANAGER(obj)" "GtkRecentManager*") ;;; 3.14.0 (CCAST "GTK_STATUS_ICON(obj)" "GtkStatusIcon*") ;;; 3.14.0 (CCHK "GTK_IS_STATUS_ICON(obj)" "GtkStatusIcon*") (CFNC "GtkTargetList* gtk_target_list_ref GtkTargetList* list") (CINT "GDK_SUPER_MASK" "GdkModifierType") (CINT "GDK_HYPER_MASK" "GdkModifierType") (CINT "GDK_META_MASK" "GdkModifierType") (CINT "GTK_SENSITIVITY_AUTO" "GtkSensitivityType") (CINT "GTK_SENSITIVITY_ON" "GtkSensitivityType") (CINT "GTK_SENSITIVITY_OFF" "GtkSensitivityType") (CINT "GTK_TEXT_BUFFER_TARGET_INFO_BUFFER_CONTENTS" "GtkTextBufferTargetInfo") (CINT "GTK_TEXT_BUFFER_TARGET_INFO_RICH_TEXT" "GtkTextBufferTargetInfo") (CINT "GTK_TEXT_BUFFER_TARGET_INFO_TEXT" "GtkTextBufferTargetInfo") (CINT "GTK_ASSISTANT_PAGE_CONTENT" "GtkAssistantPageType") (CINT "GTK_ASSISTANT_PAGE_INTRO" "GtkAssistantPageType") (CINT "GTK_ASSISTANT_PAGE_CONFIRM" "GtkAssistantPageType") (CINT "GTK_ASSISTANT_PAGE_SUMMARY" "GtkAssistantPageType") (CINT "GTK_ASSISTANT_PAGE_PROGRESS" "GtkAssistantPageType") (CINT "GTK_CELL_RENDERER_ACCEL_MODE_GTK" "GtkCellRendererAccelMode") (CINT "GTK_CELL_RENDERER_ACCEL_MODE_OTHER" "GtkCellRendererAccelMode") (CINT "GTK_RECENT_SORT_NONE" "GtkRecentSortType") (CINT "GTK_RECENT_SORT_MRU" "GtkRecentSortType") (CINT "GTK_RECENT_SORT_LRU" "GtkRecentSortType") (CINT "GTK_RECENT_SORT_CUSTOM" "GtkRecentSortType") (CINT "GTK_RECENT_CHOOSER_ERROR_NOT_FOUND" "GtkRecentChooserError") (CINT "GTK_RECENT_CHOOSER_ERROR_INVALID_URI" "GtkRecentChooserError") ;(CINT "GTK_RECENT_FILTER_URI" "GtkRecentFilterFlags") ;(CINT "GTK_RECENT_FILTER_DISPLAY_NAME" "GtkRecentFilterFlags") ;(CINT "GTK_RECENT_FILTER_MIME_TYPE" "GtkRecentFilterFlags") ;(CINT "GTK_RECENT_FILTER_APPLICATION" "GtkRecentFilterFlags") ;(CINT "GTK_RECENT_FILTER_GROUP" "GtkRecentFilterFlags") ;(CINT "GTK_RECENT_FILTER_AGE" "GtkRecentFilterFlags") (CINT "GTK_RECENT_MANAGER_ERROR_NOT_FOUND" "GtkRecentManagerError") (CINT "GTK_RECENT_MANAGER_ERROR_INVALID_URI" "GtkRecentManagerError") ;out 2.9.1 (CINT "GTK_RECENT_MANAGER_ERROR_INVALID_MIME" "GtkRecentManagerError") (CINT "GTK_RECENT_MANAGER_ERROR_INVALID_ENCODING" "GtkRecentManagerError") (CINT "GTK_RECENT_MANAGER_ERROR_NOT_REGISTERED" "GtkRecentManagerError") ;out 2.9.1 (CINT "GTK_RECENT_MANAGER_ERROR_BAD_EXEC_STRING" "GtkRecentManagerError") (CINT "GTK_RECENT_MANAGER_ERROR_READ" "GtkRecentManagerError") (CINT "GTK_RECENT_MANAGER_ERROR_WRITE" "GtkRecentManagerError") (CINT "GTK_RECENT_MANAGER_ERROR_UNKNOWN" "GtkRecentManagerError") ;;;void gtk_tree_store_insert_with_values GtkTreeStore* tree_store GtkTreeIter* iter GtkTreeIter* parent gint position ... (CFNC "gboolean gdk_display_supports_shapes GdkDisplay* display") (CFNC "gboolean gdk_display_supports_input_shapes GdkDisplay* display") (CFNC "gboolean gdk_screen_is_composited GdkScreen* screen") (CFNC "void gdk_screen_set_resolution GdkScreen* screen gdouble dpi") (CFNC "gdouble gdk_screen_get_resolution GdkScreen* screen") (CFNC "GdkWindow* gdk_screen_get_active_window GdkScreen* screen") (CFNC "GList* gdk_screen_get_window_stack GdkScreen* screen") (CFNC "GdkWindowTypeHint gdk_window_get_type_hint GdkWindow* window") (CFNC "void gtk_clipboard_request_rich_text GtkClipboard* clipboard GtkTextBuffer* buffer GtkClipboardRichTextReceivedFunc func lambda_data #func_info") (CFNC "guint8* gtk_clipboard_wait_for_rich_text GtkClipboard* clipboard GtkTextBuffer* buffer GdkAtom* format gsize* [length]") (CFNC "gboolean gtk_clipboard_wait_is_rich_text_available GtkClipboard* clipboard GtkTextBuffer* buffer") ;;; 3.10 (CFNC "gchar* gtk_combo_box_get_title GtkComboBox* combo_box") ; 'const ;;; 3.10 (CFNC "void gtk_combo_box_set_title GtkComboBox* combo_box gchar* title") (CFNC "void gtk_drag_dest_set_track_motion GtkWidget* widget gboolean track_motion") (CFNC "gboolean gtk_drag_dest_get_track_motion GtkWidget* widget") ;(CFNC "GtkBorder* gtk_entry_get_inner_border GtkEntry* entry") ; 'const ;(CFNC "void gtk_entry_set_inner_border GtkEntry* entry GtkBorder* border") ; arg is const ;;; 3.19.2 (CFNC "gboolean gtk_file_chooser_button_get_focus_on_click GtkFileChooserButton* button") ;;; 3.19.2 (CFNC "void gtk_file_chooser_button_set_focus_on_click GtkFileChooserButton* button gboolean focus_on_click") ;(CFNC "void gtk_file_info_set_icon_name GtkFileInfo* info gchar* con_name") ;(CFNC "gchar* gtk_file_info_get_icon_name GtkFileInfo* info") ; 'const ;(CFNC "GdkPixbuf* gtk_file_info_render_icon GtkFileInfo* info GtkWidget* widget gint pixel_size GError** [error]") ;;; (CFNC "void gtk_notebook_set_group_id GtkNotebook* notebook gint group_id") ; out 2.11.0 ;;; (CFNC "gint gtk_notebook_get_group_id GtkNotebook* notebook") ;;; 2.91.0 (CFNC "void gtk_notebook_set_group GtkNotebook* notebook gpointer group") ;;; 2.91.0 (CFNC "gpointer gtk_notebook_get_group GtkNotebook* notebook") (CFNC "gboolean gtk_notebook_get_tab_reorderable GtkNotebook* notebook GtkWidget* child") (CFNC "void gtk_notebook_set_tab_reorderable GtkNotebook* notebook GtkWidget* child gboolean reorderable") (CFNC "gboolean gtk_notebook_get_tab_detachable GtkNotebook* notebook GtkWidget* child") (CFNC "void gtk_notebook_set_tab_detachable GtkNotebook* notebook GtkWidget* child gboolean detachable") ;;; (CFNC "void gtk_radio_action_set_current_value GtkRadioAction* action gint current_value") (CFNC "void gtk_range_set_lower_stepper_sensitivity GtkRange* range GtkSensitivityType sensitivity") (CFNC "GtkSensitivityType gtk_range_get_lower_stepper_sensitivity GtkRange* range") (CFNC "void gtk_range_set_upper_stepper_sensitivity GtkRange* range GtkSensitivityType sensitivity") (CFNC "GtkSensitivityType gtk_range_get_upper_stepper_sensitivity GtkRange* range") (CFNC "void gtk_scrolled_window_unset_placement GtkScrolledWindow* scrolled_window") (CFNC "void gtk_target_list_add_rich_text_targets GtkTargetList* list guint info gboolean deserializable GtkTextBuffer* buffer") (CFNC "GtkTargetEntry* gtk_target_table_new_from_list GtkTargetList* list gint* [n_targets]") (CFNC "void gtk_target_table_free GtkTargetEntry* targets gint n_targets") (CFNC "gboolean gtk_selection_data_targets_include_rich_text GtkSelectionData* selection_data GtkTextBuffer* buffer") (CFNC "gboolean gtk_selection_data_targets_include_uri GtkSelectionData* selection_data") (CFNC "gboolean gtk_targets_include_text GdkAtom* targets gint n_targets") (CFNC "gboolean gtk_targets_include_rich_text GdkAtom* targets gint n_targets GtkTextBuffer* buffer") (CFNC "gboolean gtk_targets_include_image GdkAtom* targets gint n_targets gboolean writable") (CFNC "gboolean gtk_targets_include_uri GdkAtom* targets gint n_targets") ;;;;(CFNC "GType gtk_target_list_get_type void") (CFNC "GSList* gtk_size_group_get_widgets GtkSizeGroup* size_group") ;;; (CFNC-gtk2 "gboolean gtk_style_lookup_color GtkStyle* style gchar* color_name GdkColor* color") (CFNC "gboolean gtk_text_buffer_get_has_selection GtkTextBuffer* buffer") (CFNC "GtkTargetList* gtk_text_buffer_get_copy_target_list GtkTextBuffer* buffer") (CFNC "GtkTargetList* gtk_text_buffer_get_paste_target_list GtkTextBuffer* buffer") ;(CFNC "void gtk_tree_store_insert_with_valuesv GtkTreeStore* tree_store GtkTreeIter* iter GtkTreeIter* parent gint position gint* columns GValue* values gint n_values") (CFNC "gboolean gtk_tree_view_get_headers_clickable GtkTreeView* tree_view") (CFNC "GtkEntry* gtk_tree_view_get_search_entry GtkTreeView* tree_view") (CFNC "void gtk_tree_view_set_search_entry GtkTreeView* tree_view GtkEntry* entry") (CFNC "GtkTreeViewSearchPositionFunc gtk_tree_view_get_search_position_func GtkTreeView* tree_view") (CFNC "void gtk_tree_view_set_search_position_func GtkTreeView* tree_view GtkTreeViewSearchPositionFunc func lambda_data #func_info GDestroyNotify destroy") (CFNC "gboolean gtk_widget_is_composited GtkWidget* widget") ;;; 2.91.0 (CFNC "void gtk_widget_input_shape_combine_mask GtkWidget* widget GdkBitmap* shape_mask gint offset_x gint offset_y") (CFNC "void gtk_window_set_deletable GtkWindow* window gboolean setting") (CFNC "gboolean gtk_window_get_deletable GtkWindow* window") ;;;;(CFNC "GType gtk_assistant_get_type void") (CFNC "GtkWidget* gtk_assistant_new void") (CFNC "gint gtk_assistant_get_current_page GtkAssistant* assistant") (CFNC "void gtk_assistant_set_current_page GtkAssistant* assistant gint page_num") (CFNC "gint gtk_assistant_get_n_pages GtkAssistant* assistant") (CFNC "GtkWidget* gtk_assistant_get_nth_page GtkAssistant* assistant gint page_num") (CFNC "gint gtk_assistant_prepend_page GtkAssistant* assistant GtkWidget* page") (CFNC "gint gtk_assistant_append_page GtkAssistant* assistant GtkWidget* page") (CFNC "gint gtk_assistant_insert_page GtkAssistant* assistant GtkWidget* page gint position") (CFNC "void gtk_assistant_set_forward_page_func GtkAssistant* assistant GtkAssistantPageFunc page_func lambda_data #func_info GDestroyNotify destroy") (CFNC "void gtk_assistant_set_page_type GtkAssistant* assistant GtkWidget* page GtkAssistantPageType type") (CFNC "GtkAssistantPageType gtk_assistant_get_page_type GtkAssistant* assistant GtkWidget* page") (CFNC "void gtk_assistant_set_page_title GtkAssistant* assistant GtkWidget* page gchar* title") (CFNC "gchar* gtk_assistant_get_page_title GtkAssistant* assistant GtkWidget* page") ; 'const ;;; 3.1.4 (CFNC "void gtk_assistant_set_page_header_image GtkAssistant* assistant GtkWidget* page GdkPixbuf* pixbuf") ;;; 3.1.4 (CFNC "GdkPixbuf* gtk_assistant_get_page_header_image GtkAssistant* assistant GtkWidget* page") ;;; 3.1.4 (CFNC "void gtk_assistant_set_page_side_image GtkAssistant* assistant GtkWidget* page GdkPixbuf* pixbuf") ;;; 3.1.4 (CFNC "GdkPixbuf* gtk_assistant_get_page_side_image GtkAssistant* assistant GtkWidget* page") (CFNC "void gtk_assistant_set_page_complete GtkAssistant* assistant GtkWidget* page gboolean complete") (CFNC "gboolean gtk_assistant_get_page_complete GtkAssistant* assistant GtkWidget* page") (CFNC "void gtk_assistant_add_action_widget GtkAssistant* assistant GtkWidget* child") (CFNC "void gtk_assistant_remove_action_widget GtkAssistant* assistant GtkWidget* child") (CFNC "void gtk_assistant_update_buttons_state GtkAssistant* assistant") ;;;;(CFNC "GType gtk_cell_renderer_accel_get_type void") (CFNC "GtkCellRenderer* gtk_cell_renderer_accel_new void") ;;;;(CFNC "GType gtk_cell_renderer_spin_get_type void") (CFNC "GtkCellRenderer* gtk_cell_renderer_spin_new void") ;;;;(CFNC "GType gtk_link_button_get_type void") (CFNC "GtkWidget* gtk_link_button_new gchar* uri") (CFNC "GtkWidget* gtk_link_button_new_with_label gchar* uri gchar* label") (CFNC "gchar* gtk_link_button_get_uri GtkLinkButton* link_button") ; 'const (CFNC "void gtk_link_button_set_uri GtkLinkButton* link_button gchar* uri") ;;; 2.90.1 (CFNC "GtkLinkButtonUriFunc gtk_link_button_set_uri_hook GtkLinkButtonUriFunc func lambda_data #func_info GDestroyNotify destroy") ;;;;(CFNC "GType gtk_recent_chooser_dialog_get_type void") ;;;(CFNC "GtkWidget* gtk_recent_chooser_dialog_new gchar* title GtkWindow* parent gchar* first_button_text ... G_GNUC_NULL_TERMINATED") ;;;(CFNC "GtkWidget* gtk_recent_chooser_dialog_new_for_manager gchar* title GtkWindow* parent GtkRecentManager* manager gchar* first_button_text ... G_GNUC_NULL_TERMINATED") (CFNC "GQuark gtk_recent_chooser_error_quark void") (CFNC "void gtk_recent_chooser_set_show_private GtkRecentChooser* chooser gboolean show_private") (CFNC "gboolean gtk_recent_chooser_get_show_private GtkRecentChooser* chooser") (CFNC "void gtk_recent_chooser_set_show_not_found GtkRecentChooser* chooser gboolean show_not_found") (CFNC "gboolean gtk_recent_chooser_get_show_not_found GtkRecentChooser* chooser") (CFNC "void gtk_recent_chooser_set_select_multiple GtkRecentChooser* chooser gboolean select_multiple") (CFNC "gboolean gtk_recent_chooser_get_select_multiple GtkRecentChooser* chooser") (CFNC "void gtk_recent_chooser_set_limit GtkRecentChooser* chooser gint limit") (CFNC "gint gtk_recent_chooser_get_limit GtkRecentChooser* chooser") (CFNC "void gtk_recent_chooser_set_local_only GtkRecentChooser* chooser gboolean local_only") (CFNC "gboolean gtk_recent_chooser_get_local_only GtkRecentChooser* chooser") (CFNC "void gtk_recent_chooser_set_show_tips GtkRecentChooser* chooser gboolean show_tips") (CFNC "gboolean gtk_recent_chooser_get_show_tips GtkRecentChooser* chooser") ;;; out 12.0 (CFNC "void gtk_recent_chooser_set_show_numbers GtkRecentChooser* chooser gboolean show_numbers") ;;; (CFNC "gboolean gtk_recent_chooser_get_show_numbers GtkRecentChooser* chooser") (CFNC "void gtk_recent_chooser_set_show_icons GtkRecentChooser* chooser gboolean show_icons") (CFNC "gboolean gtk_recent_chooser_get_show_icons GtkRecentChooser* chooser") (CFNC "void gtk_recent_chooser_set_sort_type GtkRecentChooser* chooser GtkRecentSortType sort_type") (CFNC "GtkRecentSortType gtk_recent_chooser_get_sort_type GtkRecentChooser* chooser") (CFNC "void gtk_recent_chooser_set_sort_func GtkRecentChooser* chooser GtkRecentSortFunc func lambda_data #func_info GDestroyNotify data_destroy") (CFNC "gboolean gtk_recent_chooser_set_current_uri GtkRecentChooser* chooser gchar* uri GError** [error]") (CFNC "gchar* gtk_recent_chooser_get_current_uri GtkRecentChooser* chooser") (CFNC "GtkRecentInfo* gtk_recent_chooser_get_current_item GtkRecentChooser* chooser") (CFNC "gboolean gtk_recent_chooser_select_uri GtkRecentChooser* chooser gchar* uri GError** [error]") (CFNC "void gtk_recent_chooser_unselect_uri GtkRecentChooser* chooser gchar* uri") (CFNC "void gtk_recent_chooser_select_all GtkRecentChooser* chooser") (CFNC "void gtk_recent_chooser_unselect_all GtkRecentChooser* chooser") (CFNC "GList* gtk_recent_chooser_get_items GtkRecentChooser* chooser") (CFNC "gchar** gtk_recent_chooser_get_uris GtkRecentChooser* chooser gsize* [length]") (CFNC "void gtk_recent_chooser_add_filter GtkRecentChooser* chooser GtkRecentFilter* filter") (CFNC "void gtk_recent_chooser_remove_filter GtkRecentChooser* chooser GtkRecentFilter* filter") (CFNC "GSList* gtk_recent_chooser_list_filters GtkRecentChooser* chooser") (CFNC "void gtk_recent_chooser_set_filter GtkRecentChooser* chooser GtkRecentFilter* filter") (CFNC "GtkRecentFilter* gtk_recent_chooser_get_filter GtkRecentChooser* chooser") ;;;;(CFNC "GType gtk_recent_chooser_menu_get_type void") (CFNC "GtkWidget* gtk_recent_chooser_menu_new void") (CFNC "GtkWidget* gtk_recent_chooser_menu_new_for_manager GtkRecentManager* manager") (CFNC "gboolean gtk_recent_chooser_menu_get_show_numbers GtkRecentChooserMenu* menu") (CFNC "void gtk_recent_chooser_menu_set_show_numbers GtkRecentChooserMenu* menu gboolean show_numbers") ;;;;(CFNC "GType gtk_recent_chooser_widget_get_type void") (CFNC "GtkWidget* gtk_recent_chooser_widget_new void") (CFNC "GtkWidget* gtk_recent_chooser_widget_new_for_manager GtkRecentManager* manager") ;;;;(CFNC "GType gtk_recent_filter_get_type void") (CFNC "GtkRecentFilter* gtk_recent_filter_new void") (CFNC "void gtk_recent_filter_set_name GtkRecentFilter* filter gchar* name") (CFNC "gchar* gtk_recent_filter_get_name GtkRecentFilter* filter" 'const-return) (CFNC "void gtk_recent_filter_add_mime_type GtkRecentFilter* filter gchar* mime_type") (CFNC "void gtk_recent_filter_add_pattern GtkRecentFilter* filter gchar* pattern") (CFNC "void gtk_recent_filter_add_pixbuf_formats GtkRecentFilter* filter") (CFNC "void gtk_recent_filter_add_application GtkRecentFilter* filter gchar* application") (CFNC "void gtk_recent_filter_add_group GtkRecentFilter* filter gchar* group") (CFNC "void gtk_recent_filter_add_age GtkRecentFilter* filter gint days") ;(CFNC "void gtk_recent_filter_add_custom GtkRecentFilter* filter GtkRecentFilterFlags needed GtkRecentFilterFunc func lambda_data #func_info GDestroyNotify data_destroy") ;(CFNC "GtkRecentFilterFlags gtk_recent_filter_get_needed GtkRecentFilter* filter") ;(CFNC "gboolean gtk_recent_filter_filter GtkRecentFilter* filter GtkRecentFilterInfo* filter_info") (CFNC "GQuark gtk_recent_manager_error_quark void") ;;;;(CFNC "GType gtk_recent_manager_get_type void") (CFNC "GtkRecentManager* gtk_recent_manager_new void") (CFNC "GtkRecentManager* gtk_recent_manager_get_default void") ;;; out 2.11.4 (CFNC "GtkRecentManager* gtk_recent_manager_get_for_screen GdkScreen* screen") ;;; out 2.11.4 (CFNC "void gtk_recent_manager_set_screen GtkRecentManager* manager GdkScreen* screen") (CFNC "gboolean gtk_recent_manager_remove_item GtkRecentManager* manager gchar* uri GError** [error]") (CFNC "GtkRecentInfo* gtk_recent_manager_lookup_item GtkRecentManager* manager gchar* uri GError** [error]") (CFNC "gboolean gtk_recent_manager_has_item GtkRecentManager* manager gchar* uri") (CFNC "gboolean gtk_recent_manager_move_item GtkRecentManager* manager gchar* uri gchar* new_uri GError** [error]") ;;; 2.90.6 (CFNC "void gtk_recent_manager_set_limit GtkRecentManager* manager gint limit") ;;; 2.90.6 (CFNC "gint gtk_recent_manager_get_limit GtkRecentManager* manager") (CFNC "GList* gtk_recent_manager_get_items GtkRecentManager* manager") (CFNC "gint gtk_recent_manager_purge_items GtkRecentManager* manager GError** [error]") ;;;;(CFNC "GType gtk_recent_info_get_type void") (CFNC "GtkRecentInfo* gtk_recent_info_ref GtkRecentInfo* info") (CFNC "void gtk_recent_info_unref GtkRecentInfo* info") (CFNC "gchar* gtk_recent_info_get_uri GtkRecentInfo* info") ; 'const (CFNC "gchar* gtk_recent_info_get_display_name GtkRecentInfo* info" 'const-return) (CFNC "gchar* gtk_recent_info_get_description GtkRecentInfo* info" 'const-return) (CFNC "gchar* gtk_recent_info_get_mime_type GtkRecentInfo* info" 'const-return) (CFNC "time_t gtk_recent_info_get_added GtkRecentInfo* info") (CFNC "time_t gtk_recent_info_get_modified GtkRecentInfo* info") (CFNC "time_t gtk_recent_info_get_visited GtkRecentInfo* info") (CFNC "gboolean gtk_recent_info_get_private_hint GtkRecentInfo* info") ;(CFNC "gboolean gtk_recent_info_get_application_info GtkRecentInfo* info gchar* app_name gchar** [app_exec] guint* [count] time_t* [time]") ; const args (CFNC "gchar** gtk_recent_info_get_applications GtkRecentInfo* info gsize* [length]") (CFNC "gchar* gtk_recent_info_last_application GtkRecentInfo* info") (CFNC "gboolean gtk_recent_info_has_application GtkRecentInfo* info gchar* app_name") (CFNC "gchar** gtk_recent_info_get_groups GtkRecentInfo* info gsize* [length]") (CFNC "gboolean gtk_recent_info_has_group GtkRecentInfo* info gchar* group_name") (CFNC "GdkPixbuf* gtk_recent_info_get_icon GtkRecentInfo* info gint size") (CFNC "gchar* gtk_recent_info_get_short_name GtkRecentInfo* info") (CFNC "gchar* gtk_recent_info_get_uri_display GtkRecentInfo* info") (CFNC "gint gtk_recent_info_get_age GtkRecentInfo* info") (CFNC "gboolean gtk_recent_info_is_local GtkRecentInfo* info") (CFNC "gboolean gtk_recent_info_exists GtkRecentInfo* info") (CFNC "gboolean gtk_recent_info_match GtkRecentInfo* info_a GtkRecentInfo* info_b") ;;;;(CFNC "GType gtk_status_icon_get_type void") ;;; 3.14.0 (CFNC "GtkStatusIcon* gtk_status_icon_new void") ;;; 3.14.0 (CFNC "GtkStatusIcon* gtk_status_icon_new_from_pixbuf GdkPixbuf* pixbuf") ;;; 3.14.0 (CFNC "GtkStatusIcon* gtk_status_icon_new_from_file gchar* filename") ;;; 3.14.0 ;;; (CFNC "GtkStatusIcon* gtk_status_icon_new_from_stock gchar* stock_id") ;;; 3.14.0 (CFNC "GtkStatusIcon* gtk_status_icon_new_from_icon_name gchar* icon_name") ;;; 3.14.0 (CFNC "void gtk_status_icon_set_from_pixbuf GtkStatusIcon* status_icon GdkPixbuf* pixbuf") ;;; 3.14.0 (CFNC "void gtk_status_icon_set_from_file GtkStatusIcon* status_icon gchar* filename") ;;; 3.14.0 ;;; (CFNC "void gtk_status_icon_set_from_stock GtkStatusIcon* status_icon gchar* stock_id") ;;; 3.14.0 (CFNC "void gtk_status_icon_set_from_icon_name GtkStatusIcon* status_icon gchar* icon_name") ;;; 3.14.0 (CFNC "GtkImageType gtk_status_icon_get_storage_type GtkStatusIcon* status_icon") ;;; 3.14.0 (CFNC "GdkPixbuf* gtk_status_icon_get_pixbuf GtkStatusIcon* status_icon") ;;; 3.14.0 ;;; (CFNC "gchar* gtk_status_icon_get_stock GtkStatusIcon* status_icon") ; 'const ;;; 3.14.0 (CFNC "gchar* gtk_status_icon_get_icon_name GtkStatusIcon* status_icon") ; 'const ;;; 3.14.0 (CFNC "gint gtk_status_icon_get_size GtkStatusIcon* status_icon") ;;; 3.14.0 ;;; out 2.15.0 (CFNC "void gtk_status_icon_set_tooltip GtkStatusIcon* status_icon gchar* tooltip_text") ;;; 3.14.0 (CFNC "void gtk_status_icon_set_visible GtkStatusIcon* status_icon gboolean visible") ;;; 3.14.0 (CFNC "gboolean gtk_status_icon_get_visible GtkStatusIcon* status_icon") ;;; 3.14.0 ;;; 2.90.7 (CFNC "void gtk_status_icon_set_blinking GtkStatusIcon* status_icon gboolean blinking") ;;; 3.14.0 ;;; 2.90.7 (CFNC "gboolean gtk_status_icon_get_blinking GtkStatusIcon* status_icon") ;;; 3.14.0 (CFNC "gboolean gtk_status_icon_is_embedded GtkStatusIcon* status_icon") ;;; 3.14.0 (CFNC "void gtk_status_icon_position_menu GtkMenu* menu gint* [x] gint* [y] gboolean* [push_in] gpointer user_data") (CFNC "GdkAtom gtk_text_buffer_register_serialize_format GtkTextBuffer* buffer gchar* mime_type GtkTextBufferSerializeFunc function gpointer user_data GDestroyNotify user_data_destroy") (CFNC "GdkAtom gtk_text_buffer_register_serialize_tagset GtkTextBuffer* buffer gchar* tagset_name") (CFNC "GdkAtom gtk_text_buffer_register_deserialize_format GtkTextBuffer* buffer gchar* mime_type GtkTextBufferDeserializeFunc function gpointer user_data GDestroyNotify user_data_destroy") (CFNC "GdkAtom gtk_text_buffer_register_deserialize_tagset GtkTextBuffer* buffer gchar* tagset_name") (CFNC "void gtk_text_buffer_unregister_serialize_format GtkTextBuffer* buffer GdkAtom format") (CFNC "void gtk_text_buffer_unregister_deserialize_format GtkTextBuffer* buffer GdkAtom format") (CFNC "void gtk_text_buffer_deserialize_set_can_create_tags GtkTextBuffer* buffer GdkAtom format gboolean can_create_tags") (CFNC "gboolean gtk_text_buffer_deserialize_get_can_create_tags GtkTextBuffer* buffer GdkAtom format") (CFNC "GdkAtom* gtk_text_buffer_get_serialize_formats GtkTextBuffer* buffer gint* [n_formats]") (CFNC "GdkAtom* gtk_text_buffer_get_deserialize_formats GtkTextBuffer* buffer gint* [n_formats]") (CFNC "guint8* gtk_text_buffer_serialize GtkTextBuffer* register_buffer GtkTextBuffer* content_buffer GdkAtom format GtkTextIter* start GtkTextIter* end gsize* [length]") (CFNC "gboolean gtk_text_buffer_deserialize GtkTextBuffer* register_buffer GtkTextBuffer* content_buffer GdkAtom format GtkTextIter* iter guint8* data gsize length GError** [error]") ;;; 2.90.1 (CFNC "void gtk_notebook_set_window_creation_hook GtkNotebookWindowCreationFunc func gpointer data GDestroyNotify destroy") ;; destroy arg added later (CFNC "gboolean gtk_recent_manager_add_item GtkRecentManager* manager gchar* uri") (CFNC "gboolean gtk_recent_manager_add_full GtkRecentManager* manager gchar* uri GtkRecentData* recent_data") ;; error arg removed (CINT "GTK_MESSAGE_OTHER" "GtkMessageType") ;(CFNC "void gtk_message_dialog_set_image GtkMessageDialog* dialog GtkWidget* image") ;; messagedialog is commented out above so this needs to wait until it is "real" ;; 2.9.2: ;(CFNC "gboolean gtk_status_icon_get_geometry GtkStatusIcon* status_icon GdkScreen** [screen] GdkRectangle* [area] GtkOrientation* [orientation]") ;rectangle ref arg to xen needs explicit conversion here ;(CFNC "gboolean gdk_color_parse gchar* spec GdkColor* color"); -- need both versions somehow (gint above) ;; 2.9.3: (CINT "GTK_TREE_VIEW_GRID_LINES_NONE" "GtkTreeViewGridLines") (CINT "GTK_TREE_VIEW_GRID_LINES_HORIZONTAL" "GtkTreeViewGridLines") (CINT "GTK_TREE_VIEW_GRID_LINES_VERTICAL" "GtkTreeViewGridLines") (CINT "GTK_TREE_VIEW_GRID_LINES_BOTH" "GtkTreeViewGridLines") ;;; rtn type (CFNC "gboolean gtk_tree_model_filter_convert_child_iter_to_iter GtkTreeModelFilter* filter GtkTreeIter* filter_iter GtkTreeIter* child_iter") (CFNC "GtkTreeViewGridLines gtk_tree_view_get_grid_lines GtkTreeView* tree_view") (CFNC "void gtk_tree_view_set_grid_lines GtkTreeView* tree_view GtkTreeViewGridLines grid_lines") (CFNC "gboolean gtk_tree_view_get_enable_tree_lines GtkTreeView* tree_view") (CFNC "void gtk_tree_view_set_enable_tree_lines GtkTreeView* tree_view gboolean enabled") ;; 2.9.4: (CFNC "void gtk_label_set_line_wrap_mode GtkLabel* label PangoWrapMode wrap_mode") (CFNC "PangoWrapMode gtk_label_get_line_wrap_mode GtkLabel* label") ;;; printer stuff -- only include gtkprintoperation for now (it's in gtk.h) -> settings context preview as well ;(CCAST "GTK_PRINTER(obj)" "GtkPrinter*") ;(CCHK "GTK_IS_PRINTER(obj)" "GtkPrinter*") ;(CCAST "GTK_PRINTER_OPTION_WIDGET(obj)" "GtkPrinterOptionWidget*") ;(CCHK "GTK_IS_PRINTER_OPTION_WIDGET(obj)" "GtkPrinterOptionWidget*") (CCAST "GTK_PRINT_CONTEXT(obj)" "GtkPrintContext*") (CCHK "GTK_IS_PRINT_CONTEXT(obj)" "GtkPrintContext*") ;(CCAST "GTK_PRINT_JOB(obj)" "GtkPrintJob*") ;(CCHK "GTK_IS_PRINT_JOB(obj)" "GtkPrintJob*") (CCAST "GTK_PRINT_OPERATION(obj)" "GtkPrintOperation*") (CCHK "GTK_IS_PRINT_OPERATION(obj)" "GtkPrintOperation*") (CCAST "GTK_PRINT_OPERATION_PREVIEW(obj)" "GtkPrintOperationPreview*") (CCHK "GTK_IS_PRINT_OPERATION_PREVIEW(obj)" "GtkPrintOperationPreview*") (CCAST "GTK_PRINT_SETTINGS(obj)" "GtkPrintSettings*") (CCHK "GTK_IS_PRINT_SETTINGS(obj)" "GtkPrintSettings*") ;(CCAST "GTK_PRINT_UNIX_DIALOG(obj)" "GtkPrintUnixDialog*") ;(CCHK "GTK_IS_PRINT_UNIX_DIALOG(obj)" "GtkPrintUnixDialog*") ;(CINT "GTK_PRINT_CAPABILITY_PAGE_SET" "GtkPrintCapabilities") ;(CINT "GTK_PRINT_CAPABILITY_COPIES" "GtkPrintCapabilities") ;(CINT "GTK_PRINT_CAPABILITY_COLLATE" "GtkPrintCapabilities") ;(CINT "GTK_PRINT_CAPABILITY_REVERSE" "GtkPrintCapabilities") ;(CINT "GTK_PRINT_CAPABILITY_SCALE" "GtkPrintCapabilities") ;(CINT "GTK_PRINT_CAPABILITY_GENERATE_PDF" "GtkPrintCapabilities") ;(CINT "GTK_PRINT_CAPABILITY_GENERATE_PS" "GtkPrintCapabilities") ;(CINT "GTK_PRINT_CAPABILITY_PREVIEW" "GtkPrintCapabilities") (CINT "GTK_PRINT_STATUS_INITIAL" "GtkPrintStatus") (CINT "GTK_PRINT_STATUS_PREPARING" "GtkPrintStatus") (CINT "GTK_PRINT_STATUS_GENERATING_DATA" "GtkPrintStatus") (CINT "GTK_PRINT_STATUS_SENDING_DATA" "GtkPrintStatus") (CINT "GTK_PRINT_STATUS_PENDING" "GtkPrintStatus") (CINT "GTK_PRINT_STATUS_PENDING_ISSUE" "GtkPrintStatus") (CINT "GTK_PRINT_STATUS_PRINTING" "GtkPrintStatus") (CINT "GTK_PRINT_STATUS_FINISHED" "GtkPrintStatus") (CINT "GTK_PRINT_STATUS_FINISHED_ABORTED" "GtkPrintStatus") (CINT "GTK_PRINT_OPERATION_RESULT_ERROR" "GtkPrintOperationResult") (CINT "GTK_PRINT_OPERATION_RESULT_APPLY" "GtkPrintOperationResult") (CINT "GTK_PRINT_OPERATION_RESULT_CANCEL" "GtkPrintOperationResult") (CINT "GTK_PRINT_OPERATION_RESULT_IN_PROGRESS" "GtkPrintOperationResult") (CINT "GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG" "GtkPrintOperationAction") (CINT "GTK_PRINT_OPERATION_ACTION_PRINT" "GtkPrintOperationAction") (CINT "GTK_PRINT_OPERATION_ACTION_PREVIEW" "GtkPrintOperationAction") (CINT "GTK_PRINT_OPERATION_ACTION_EXPORT" "GtkPrintOperationAction") (CINT "GTK_PRINT_ERROR_GENERAL" "GtkPrintError") (CINT "GTK_PRINT_ERROR_INTERNAL_ERROR" "GtkPrintError") (CINT "GTK_PRINT_ERROR_NOMEM" "GtkPrintError") (CINT "GTK_PRINT_ERROR_INVALID_FILE" "GtkPrintError") (CSTR "GTK_PRINT_SETTINGS_PRINTER") (CSTR "GTK_PRINT_SETTINGS_ORIENTATION") (CSTR "GTK_PRINT_SETTINGS_PAPER_FORMAT") (CSTR "GTK_PRINT_SETTINGS_PAPER_WIDTH") (CSTR "GTK_PRINT_SETTINGS_PAPER_HEIGHT") (CSTR "GTK_PRINT_SETTINGS_N_COPIES") (CSTR "GTK_PRINT_SETTINGS_DEFAULT_SOURCE") (CSTR "GTK_PRINT_SETTINGS_QUALITY") (CSTR "GTK_PRINT_SETTINGS_RESOLUTION") (CSTR "GTK_PRINT_SETTINGS_USE_COLOR") (CSTR "GTK_PRINT_SETTINGS_DUPLEX") (CSTR "GTK_PRINT_SETTINGS_COLLATE") (CSTR "GTK_PRINT_SETTINGS_REVERSE") (CSTR "GTK_PRINT_SETTINGS_MEDIA_TYPE") (CSTR "GTK_PRINT_SETTINGS_DITHER") (CSTR "GTK_PRINT_SETTINGS_SCALE") (CSTR "GTK_PRINT_SETTINGS_PRINT_PAGES") (CSTR "GTK_PRINT_SETTINGS_PAGE_RANGES") (CSTR "GTK_PRINT_SETTINGS_PAGE_SET") (CSTR "GTK_PRINT_SETTINGS_FINISHINGS") (CSTR "GTK_PRINT_SETTINGS_NUMBER_UP") (CSTR "GTK_PRINT_SETTINGS_OUTPUT_BIN") (CSTR "GTK_PRINT_SETTINGS_OUTPUT_FILE_FORMAT") (CSTR "GTK_PRINT_SETTINGS_OUTPUT_URI") (CAIRO-FUNC "cairo_t* cairo_create cairo_surface_t* target") ; try to make cairo_t declaration independent of 210 ;;;;;(CFNC "GType gtk_printer_get_type void") ;(CFNC "GtkPrinter* gtk_printer_new gchar* name GtkPrintBackend* backend gboolean virtual_") ;(CFNC "GtkPrintBackend* gtk_printer_get_backend GtkPrinter* printer") ;(CFNC "gchar* gtk_printer_get_name GtkPrinter* printer") ;(CFNC "gchar* gtk_printer_get_state_message GtkPrinter* printer") ;(CFNC "gchar* gtk_printer_get_description GtkPrinter* printer") ;(CFNC "gchar* gtk_printer_get_location GtkPrinter* printer") ;(CFNC "gchar* gtk_printer_get_icon_name GtkPrinter* printer") ;(CFNC "gint gtk_printer_get_job_count GtkPrinter* printer") ;(CFNC "gboolean gtk_printer_is_active GtkPrinter* printer") ;(CFNC "gboolean gtk_printer_is_virtual GtkPrinter* printer") ;(CFNC "gboolean gtk_printer_is_default GtkPrinter* printer") ;(CFNC "gboolean gtk_printer_accepts_pdf GtkPrinter* printer") ;(CFNC "gboolean gtk_printer_accepts_ps GtkPrinter* printer") ;(CFNC "gint gtk_printer_compare GtkPrinter* a GtkPrinter* b") ;(CFNC "void gtk_enumerate_printers GtkPrinterFunc func gpointer data GDestroyNotify destroy gboolean wait") ;;;;(CFNC "GType gtk_print_context_get_type void") (CFNC "cairo_t* gtk_print_context_get_cairo_context GtkPrintContext* context") (CFNC "GtkPageSetup* gtk_print_context_get_page_setup GtkPrintContext* context") (CFNC "gdouble gtk_print_context_get_width GtkPrintContext* context") (CFNC "gdouble gtk_print_context_get_height GtkPrintContext* context") (CFNC "gdouble gtk_print_context_get_dpi_x GtkPrintContext* context") (CFNC "gdouble gtk_print_context_get_dpi_y GtkPrintContext* context") ;(CFNC "PangoFontMap* gtk_print_context_get_pango_fontmap GtkPrintContext* context") (CFNC "PangoContext* gtk_print_context_create_pango_context GtkPrintContext* context") (CFNC "PangoLayout* gtk_print_context_create_pango_layout GtkPrintContext* context") (CFNC "void gtk_print_context_set_cairo_context GtkPrintContext* context cairo_t* cr double dpi_x double dpi_y") ;;;;;(CFNC "GType gtk_printer_option_widget_get_type void") ;(CFNC "GtkWidget* gtk_printer_option_widget_new GtkPrinterOption* source") ;(CFNC "void gtk_printer_option_widget_set_source GtkPrinterOptionWidget* setting GtkPrinterOption* source") ;(CFNC "gboolean gtk_printer_option_widget_has_external_label GtkPrinterOptionWidget* setting") ;(CFNC "GtkWidget* gtk_printer_option_widget_get_external_label GtkPrinterOptionWidget* setting") ;(CFNC "gchar* gtk_printer_option_widget_get_value GtkPrinterOptionWidget* setting") ; const return ;;;;;(CFNC "GType gtk_print_job_get_type void") ;(CFNC "GtkPrintJob* gtk_print_job_new gchar* title GtkPrinter* printer GtkPrintSettings* settings GtkPageSetup* page_setup") ;(CFNC "GtkPrintSettings* gtk_print_job_get_settings GtkPrintJob* job") ;(CFNC "GtkPrinter* gtk_print_job_get_printer GtkPrintJob* job") ;(CFNC "gchar* gtk_print_job_get_title GtkPrintJob* job") ;(CFNC "GtkPrintStatus gtk_print_job_get_status GtkPrintJob* job") ;(CFNC "gboolean gtk_print_job_set_source_file GtkPrintJob* job gchar* filename GError** [error]") ;(CFNC "cairo_surface_t* gtk_print_job_get_surface GtkPrintJob* job GError** [error]") ;(CFNC "void gtk_print_job_set_track_print_status GtkPrintJob* job gboolean track_status") ;(CFNC "gboolean gtk_print_job_get_track_print_status GtkPrintJob* job") ;(CFNC "void gtk_print_job_send GtkPrintJob* job GtkPrintJobCompleteFunc callback gpointer user_data GDestroyNotify dnotify") ;;;;;(CFNC "GType gtk_print_capabilities_get_type void") ;(CFNC "GQuark gtk_print_error_quark void") ;;;;(CFNC "GType gtk_print_operation_get_type void") (CFNC "GtkPrintOperation* gtk_print_operation_new void") (CFNC "void gtk_print_operation_set_default_page_setup GtkPrintOperation* op GtkPageSetup* default_page_setup") (CFNC "GtkPageSetup* gtk_print_operation_get_default_page_setup GtkPrintOperation* op") (CFNC "void gtk_print_operation_set_print_settings GtkPrintOperation* op GtkPrintSettings* print_settings") (CFNC "GtkPrintSettings* gtk_print_operation_get_print_settings GtkPrintOperation* op") (CFNC "void gtk_print_operation_set_job_name GtkPrintOperation* op gchar* job_name") (CFNC "void gtk_print_operation_set_n_pages GtkPrintOperation* op gint n_pages") (CFNC "void gtk_print_operation_set_current_page GtkPrintOperation* op gint current_page") (CFNC "void gtk_print_operation_set_use_full_page GtkPrintOperation* op gboolean full_page") (CFNC "void gtk_print_operation_set_unit GtkPrintOperation* op GtkUnit unit") (CFNC "void gtk_print_operation_set_export_filename GtkPrintOperation* op gchar* filename") (CFNC "void gtk_print_operation_set_track_print_status GtkPrintOperation* op gboolean track_status") (CFNC "void gtk_print_operation_set_show_progress GtkPrintOperation* op gboolean show_progress") (CFNC "void gtk_print_operation_set_allow_async GtkPrintOperation* op gboolean allow_async") (CFNC "void gtk_print_operation_set_custom_tab_label GtkPrintOperation* op gchar* label") (CFNC "GtkPrintOperationResult gtk_print_operation_run GtkPrintOperation* op GtkPrintOperationAction action GtkWindow* parent GError** [error]") (CFNC "void gtk_print_operation_get_error GtkPrintOperation* op GError** [error]") (CFNC "GtkPrintStatus gtk_print_operation_get_status GtkPrintOperation* op") (CFNC "gchar* gtk_print_operation_get_status_string GtkPrintOperation* op") (CFNC "gboolean gtk_print_operation_is_finished GtkPrintOperation* op") (CFNC "void gtk_print_operation_cancel GtkPrintOperation* op") (CFNC "GtkPageSetup* gtk_print_run_page_setup_dialog GtkWindow* parent GtkPageSetup* page_setup GtkPrintSettings* settings") (CFNC "void gtk_print_run_page_setup_dialog_async GtkWindow* parent GtkPageSetup* page_setup GtkPrintSettings* settings GtkPageSetupDoneFunc done_cb gpointer data") ;;;;(CFNC "GType gtk_print_operation_preview_get_type void") (CFNC "void gtk_print_operation_preview_render_page GtkPrintOperationPreview* preview gint page_nr") (CFNC "void gtk_print_operation_preview_end_preview GtkPrintOperationPreview* preview") (CFNC "gboolean gtk_print_operation_preview_is_selected GtkPrintOperationPreview* preview gint page_nr") ;;;;(CFNC "GType gtk_print_settings_get_type void") (CFNC "GtkPrintSettings* gtk_print_settings_new void") (CFNC "GtkPrintSettings* gtk_print_settings_copy GtkPrintSettings* other") (CFNC "gboolean gtk_print_settings_has_key GtkPrintSettings* settings gchar* key") (CFNC "gchar* gtk_print_settings_get GtkPrintSettings* settings gchar* key") (CFNC "void gtk_print_settings_set GtkPrintSettings* settings gchar* key gchar* value") (CFNC "void gtk_print_settings_unset GtkPrintSettings* settings gchar* key") (CFNC "void gtk_print_settings_foreach GtkPrintSettings* settings GtkPrintSettingsFunc func gpointer user_data") (CFNC "gboolean gtk_print_settings_get_bool GtkPrintSettings* settings gchar* key") (CFNC "void gtk_print_settings_set_bool GtkPrintSettings* settings gchar* key gboolean value") (CFNC "gdouble gtk_print_settings_get_double GtkPrintSettings* settings gchar* key") (CFNC "gdouble gtk_print_settings_get_double_with_default GtkPrintSettings* settings gchar* key gdouble def") (CFNC "void gtk_print_settings_set_double GtkPrintSettings* settings gchar* key gdouble value") (CFNC "gdouble gtk_print_settings_get_length GtkPrintSettings* settings gchar* key GtkUnit unit") (CFNC "void gtk_print_settings_set_length GtkPrintSettings* settings gchar* key gdouble value GtkUnit unit") (CFNC "gint gtk_print_settings_get_int GtkPrintSettings* settings gchar* key") (CFNC "gint gtk_print_settings_get_int_with_default GtkPrintSettings* settings gchar* key gint def") (CFNC "void gtk_print_settings_set_int GtkPrintSettings* settings gchar* key gint value") (CFNC "gchar* gtk_print_settings_get_printer GtkPrintSettings* settings") (CFNC "void gtk_print_settings_set_printer GtkPrintSettings* settings gchar* printer") (CFNC "GtkPageOrientation gtk_print_settings_get_orientation GtkPrintSettings* settings") (CFNC "void gtk_print_settings_set_orientation GtkPrintSettings* settings GtkPageOrientation orientation") (CFNC "GtkPaperSize* gtk_print_settings_get_paper_size GtkPrintSettings* settings") (CFNC "void gtk_print_settings_set_paper_size GtkPrintSettings* settings GtkPaperSize* paper_size") (CFNC "gdouble gtk_print_settings_get_paper_width GtkPrintSettings* settings GtkUnit unit") (CFNC "void gtk_print_settings_set_paper_width GtkPrintSettings* settings gdouble width GtkUnit unit") (CFNC "gdouble gtk_print_settings_get_paper_height GtkPrintSettings* settings GtkUnit unit") (CFNC "void gtk_print_settings_set_paper_height GtkPrintSettings* settings gdouble height GtkUnit unit") (CFNC "gboolean gtk_print_settings_get_use_color GtkPrintSettings* settings") (CFNC "void gtk_print_settings_set_use_color GtkPrintSettings* settings gboolean use_color") (CFNC "gboolean gtk_print_settings_get_collate GtkPrintSettings* settings") (CFNC "void gtk_print_settings_set_collate GtkPrintSettings* settings gboolean collate") (CFNC "gboolean gtk_print_settings_get_reverse GtkPrintSettings* settings") (CFNC "void gtk_print_settings_set_reverse GtkPrintSettings* settings gboolean reverse") (CFNC "GtkPrintDuplex gtk_print_settings_get_duplex GtkPrintSettings* settings") (CFNC "void gtk_print_settings_set_duplex GtkPrintSettings* settings GtkPrintDuplex duplex") (CFNC "GtkPrintQuality gtk_print_settings_get_quality GtkPrintSettings* settings") (CFNC "void gtk_print_settings_set_quality GtkPrintSettings* settings GtkPrintQuality quality") (CFNC "gint gtk_print_settings_get_n_copies GtkPrintSettings* settings") (CFNC "void gtk_print_settings_set_n_copies GtkPrintSettings* settings gint num_copies") (CFNC "gint gtk_print_settings_get_number_up GtkPrintSettings* settings") (CFNC "void gtk_print_settings_set_number_up GtkPrintSettings* settings gint number_up") (CFNC "gint gtk_print_settings_get_resolution GtkPrintSettings* settings") (CFNC "void gtk_print_settings_set_resolution GtkPrintSettings* settings gint resolution") (CFNC "gdouble gtk_print_settings_get_scale GtkPrintSettings* settings") (CFNC "void gtk_print_settings_set_scale GtkPrintSettings* settings gdouble scale") (CFNC "GtkPrintPages gtk_print_settings_get_print_pages GtkPrintSettings* settings") (CFNC "void gtk_print_settings_set_print_pages GtkPrintSettings* settings GtkPrintPages pages") (CFNC "GtkPageRange* gtk_print_settings_get_page_ranges GtkPrintSettings* settings gint* num_ranges") (CFNC "void gtk_print_settings_set_page_ranges GtkPrintSettings* settings GtkPageRange* page_ranges gint num_ranges") (CFNC "GtkPageSet gtk_print_settings_get_page_set GtkPrintSettings* settings") (CFNC "void gtk_print_settings_set_page_set GtkPrintSettings* settings GtkPageSet page_set") (CFNC "gchar* gtk_print_settings_get_default_source GtkPrintSettings* settings") (CFNC "void gtk_print_settings_set_default_source GtkPrintSettings* settings gchar* default_source") (CFNC "gchar* gtk_print_settings_get_media_type GtkPrintSettings* settings") (CFNC "void gtk_print_settings_set_media_type GtkPrintSettings* settings gchar* media_type") (CFNC "gchar* gtk_print_settings_get_dither GtkPrintSettings* settings") (CFNC "void gtk_print_settings_set_dither GtkPrintSettings* settings gchar* dither") (CFNC "gchar* gtk_print_settings_get_finishings GtkPrintSettings* settings") (CFNC "void gtk_print_settings_set_finishings GtkPrintSettings* settings gchar* finishings") (CFNC "gchar* gtk_print_settings_get_output_bin GtkPrintSettings* settings") (CFNC "void gtk_print_settings_set_output_bin GtkPrintSettings* settings gchar* output_bin") ;;;;;(CFNC "GType gtk_print_unix_dialog_get_type void") ;(CFNC "GtkWidget* gtk_print_unix_dialog_new gchar* title GtkWindow* parent") ;(CFNC "void gtk_print_unix_dialog_set_page_setup GtkPrintUnixDialog* dialog GtkPageSetup* page_setup") ;(CFNC "GtkPageSetup* gtk_print_unix_dialog_get_page_setup GtkPrintUnixDialog* dialog") ;(CFNC "void gtk_print_unix_dialog_set_current_page GtkPrintUnixDialog* dialog gint current_page") ;(CFNC "gint gtk_print_unix_dialog_get_current_page GtkPrintUnixDialog* dialog") ;(CFNC "void gtk_print_unix_dialog_set_settings GtkPrintUnixDialog* dialog GtkPrintSettings* settings") ;(CFNC "GtkPrintSettings* gtk_print_unix_dialog_get_settings GtkPrintUnixDialog* dialog") ;(CFNC "GtkPrinter* gtk_print_unix_dialog_get_selected_printer GtkPrintUnixDialog* dialog") ;(CFNC "void gtk_print_unix_dialog_add_custom_tab GtkPrintUnixDialog* dialog GtkWidget* child GtkWidget* tab_label") ;(CFNC "void gtk_print_unix_dialog_set_manual_capabilities GtkPrintUnixDialog* dialog GtkPrintCapabilities capabilities") (CFNC "GtkSettings* gtk_settings_get_for_screen GdkScreen* screen") ;;; maybe someday... ;(CFNC "gboolean G_VALUE_HOLDS_CHAR GValue* value") ;(CFNC "gboolean G_VALUE_HOLDS_UCHAR GValue* value") ;(CFNC "gboolean G_VALUE_HOLDS_BOOLEAN GValue* value") ;(CFNC "gboolean G_VALUE_HOLDS_INT GValue* value") ;(CFNC "gboolean G_VALUE_HOLDS_UINT GValue* value") ;(CFNC "gboolean G_VALUE_HOLDS_LONG GValue* value") ;(CFNC "gboolean G_VALUE_HOLDS_ULONG GValue* value") ;(CFNC "gboolean G_VALUE_HOLDS_INT64 GValue* value") ;(CFNC "gboolean G_VALUE_HOLDS_UINT64 GValue* value") ;(CFNC "gboolean G_VALUE_HOLDS_FLOAT GValue* value") ;(CFNC "gboolean G_VALUE_HOLDS_DOUBLE GValue* value") ;(CFNC "gboolean G_VALUE_HOLDS_STRING GValue* value") ;(CFNC "gboolean G_VALUE_HOLDS_POINTER GValue* value") ;(CFNC "gchar g_value_get_char GValue* value" 'const) ;(CFNC "guchar g_value_get_uchar GValue* value" 'const) ;(CFNC "gboolean g_value_get_boolean GValue* value" 'const) ;(CFNC "gint g_value_get_int GValue* value" 'const) ;(CFNC "guint g_value_get_uint GValue* value" 'const) ;(CFNC "glong g_value_get_long GValue* value" 'const) ;(CFNC "gulong g_value_get_ulong GValue* value" 'const) ;(CFNC "gint64 g_value_get_int64 GValue* value" 'const) ;(CFNC "guint64 g_value_get_uint64 GValue* value" 'const) ;(CFNC "gfloat g_value_get_float GValue* value" 'const) ;(CFNC "gdouble g_value_get_double GValue* value" 'const) ;(CFNC "gpointer g_value_get_pointer GValue* value" 'const) ;(CFNC "gchar* g_value_get_string GValue* value" 'const) ;;; cairo 1.2.6 (CAIRO-INT "CAIRO_STATUS_SUCCESS" "cairo_status_t") (CAIRO-INT "CAIRO_STATUS_NO_MEMORY" "cairo_status_t") (CAIRO-INT "CAIRO_STATUS_INVALID_RESTORE" "cairo_status_t") (CAIRO-INT "CAIRO_STATUS_INVALID_POP_GROUP" "cairo_status_t") (CAIRO-INT "CAIRO_STATUS_NO_CURRENT_POINT" "cairo_status_t") (CAIRO-INT "CAIRO_STATUS_INVALID_MATRIX" "cairo_status_t") (CAIRO-INT "CAIRO_STATUS_INVALID_STATUS" "cairo_status_t") (CAIRO-INT "CAIRO_STATUS_NULL_POINTER" "cairo_status_t") (CAIRO-INT "CAIRO_STATUS_INVALID_STRING" "cairo_status_t") (CAIRO-INT "CAIRO_STATUS_INVALID_PATH_DATA" "cairo_status_t") (CAIRO-INT "CAIRO_STATUS_READ_ERROR" "cairo_status_t") (CAIRO-INT "CAIRO_STATUS_WRITE_ERROR" "cairo_status_t") (CAIRO-INT "CAIRO_STATUS_SURFACE_FINISHED" "cairo_status_t") (CAIRO-INT "CAIRO_STATUS_SURFACE_TYPE_MISMATCH" "cairo_status_t") (CAIRO-INT "CAIRO_STATUS_PATTERN_TYPE_MISMATCH" "cairo_status_t") (CAIRO-INT "CAIRO_STATUS_INVALID_CONTENT" "cairo_status_t") (CAIRO-INT "CAIRO_STATUS_INVALID_FORMAT" "cairo_status_t") (CAIRO-INT "CAIRO_STATUS_INVALID_VISUAL" "cairo_status_t") (CAIRO-INT "CAIRO_STATUS_FILE_NOT_FOUND" "cairo_status_t") (CAIRO-INT "CAIRO_STATUS_INVALID_DASH" "cairo_status_t") (CAIRO-INT "CAIRO_STATUS_INVALID_DSC_COMMENT" "cairo_status_t") (CAIRO-INT "CAIRO_STATUS_INVALID_INDEX" "cairo_status_t") (CAIRO-INT "CAIRO_STATUS_CLIP_NOT_REPRESENTABLE" "cairo_status_t") (CAIRO-INT "CAIRO_STATUS_TEMP_FILE_ERROR" "cairo_status_t") (CAIRO-INT "CAIRO_STATUS_INVALID_STRIDE" "cairo_status_t") (CAIRO-INT "CAIRO_CONTENT_COLOR" "cairo_content_t") (CAIRO-INT "CAIRO_CONTENT_ALPHA" "cairo_content_t") (CAIRO-INT "CAIRO_CONTENT_COLOR_ALPHA" "cairo_content_t") (CAIRO-INT "CAIRO_OPERATOR_CLEAR" "cairo_operator_t") (CAIRO-INT "CAIRO_OPERATOR_SOURCE" "cairo_operator_t") (CAIRO-INT "CAIRO_OPERATOR_OVER" "cairo_operator_t") (CAIRO-INT "CAIRO_OPERATOR_IN" "cairo_operator_t") (CAIRO-INT "CAIRO_OPERATOR_OUT" "cairo_operator_t") (CAIRO-INT "CAIRO_OPERATOR_ATOP" "cairo_operator_t") (CAIRO-INT "CAIRO_OPERATOR_DEST" "cairo_operator_t") (CAIRO-INT "CAIRO_OPERATOR_DEST_OVER" "cairo_operator_t") (CAIRO-INT "CAIRO_OPERATOR_DEST_IN" "cairo_operator_t") (CAIRO-INT "CAIRO_OPERATOR_DEST_OUT" "cairo_operator_t") (CAIRO-INT "CAIRO_OPERATOR_DEST_ATOP" "cairo_operator_t") (CAIRO-INT "CAIRO_OPERATOR_XOR" "cairo_operator_t") (CAIRO-INT "CAIRO_OPERATOR_ADD" "cairo_operator_t") (CAIRO-INT "CAIRO_OPERATOR_SATURATE" "cairo_operator_t") (CAIRO-INT "CAIRO_ANTIALIAS_DEFAULT" "cairo_antialias_t") (CAIRO-INT "CAIRO_ANTIALIAS_NONE" "cairo_antialias_t") (CAIRO-INT "CAIRO_ANTIALIAS_GRAY" "cairo_antialias_t") (CAIRO-INT "CAIRO_ANTIALIAS_SUBPIXEL" "cairo_antialias_t") (CAIRO-INT "CAIRO_FILL_RULE_WINDING" "cairo_fill_rule_t") (CAIRO-INT "CAIRO_FILL_RULE_EVEN_ODD" "cairo_fill_rule_t") (CAIRO-INT "CAIRO_LINE_CAP_BUTT" "cairo_line_cap_t") (CAIRO-INT "CAIRO_LINE_CAP_ROUND" "cairo_line_cap_t") (CAIRO-INT "CAIRO_LINE_CAP_SQUARE" "cairo_line_cap_t") (CAIRO-INT "CAIRO_LINE_JOIN_MITER" "cairo_line_join_t") (CAIRO-INT "CAIRO_LINE_JOIN_ROUND" "cairo_line_join_t") (CAIRO-INT "CAIRO_LINE_JOIN_BEVEL" "cairo_line_join_t") (CAIRO-INT "CAIRO_FONT_SLANT_NORMAL" "cairo_font_slant_t") (CAIRO-INT "CAIRO_FONT_SLANT_ITALIC" "cairo_font_slant_t") (CAIRO-INT "CAIRO_FONT_SLANT_OBLIQUE" "cairo_font_slant_t") (CAIRO-INT "CAIRO_FONT_WEIGHT_NORMAL" "cairo_font_weight_t") (CAIRO-INT "CAIRO_FONT_WEIGHT_BOLD" "cairo_font_weight_t") (CAIRO-INT "CAIRO_SUBPIXEL_ORDER_DEFAULT" "cairo_subpixel_order_t") (CAIRO-INT "CAIRO_SUBPIXEL_ORDER_RGB" "cairo_subpixel_order_t") (CAIRO-INT "CAIRO_SUBPIXEL_ORDER_BGR" "cairo_subpixel_order_t") (CAIRO-INT "CAIRO_SUBPIXEL_ORDER_VRGB" "cairo_subpixel_order_t") (CAIRO-INT "CAIRO_SUBPIXEL_ORDER_VBGR" "cairo_subpixel_order_t") (CAIRO-INT "CAIRO_HINT_STYLE_DEFAULT" "cairo_hint_style_t") (CAIRO-INT "CAIRO_HINT_STYLE_NONE" "cairo_hint_style_t") (CAIRO-INT "CAIRO_HINT_STYLE_SLIGHT" "cairo_hint_style_t") (CAIRO-INT "CAIRO_HINT_STYLE_MEDIUM" "cairo_hint_style_t") (CAIRO-INT "CAIRO_HINT_STYLE_FULL" "cairo_hint_style_t") (CAIRO-INT "CAIRO_HINT_METRICS_DEFAULT" "cairo_hint_metrics_t") (CAIRO-INT "CAIRO_HINT_METRICS_OFF" "cairo_hint_metrics_t") (CAIRO-INT "CAIRO_HINT_METRICS_ON" "cairo_hint_metrics_t") (CAIRO-INT "CAIRO_FONT_TYPE_TOY" "cairo_font_type_t") (CAIRO-INT "CAIRO_FONT_TYPE_FT" "cairo_font_type_t") (CAIRO-INT "CAIRO_FONT_TYPE_WIN32" "cairo_font_type_t") ;;; (CAIRO-INT "CAIRO_FONT_TYPE_ATSUI" "cairo_font_type_t") ; replaced by QUARTZ in 1.6.4 (CAIRO-INT "CAIRO_FONT_TYPE_QUARTZ" "cairo_font_type_t") (CAIRO-INT "CAIRO_PATH_MOVE_TO" "cairo_path_data_type_t") (CAIRO-INT "CAIRO_PATH_LINE_TO" "cairo_path_data_type_t") (CAIRO-INT "CAIRO_PATH_CURVE_TO" "cairo_path_data_type_t") (CAIRO-INT "CAIRO_PATH_CLOSE_PATH" "cairo_path_data_type_t") (CAIRO-INT "CAIRO_SURFACE_TYPE_IMAGE" "cairo_surface_type_t") (CAIRO-INT "CAIRO_SURFACE_TYPE_PDF" "cairo_surface_type_t") (CAIRO-INT "CAIRO_SURFACE_TYPE_PS" "cairo_surface_type_t") (CAIRO-INT "CAIRO_SURFACE_TYPE_XLIB" "cairo_surface_type_t") (CAIRO-INT "CAIRO_SURFACE_TYPE_XCB" "cairo_surface_type_t") (CAIRO-INT "CAIRO_SURFACE_TYPE_GLITZ" "cairo_surface_type_t") (CAIRO-INT "CAIRO_SURFACE_TYPE_QUARTZ" "cairo_surface_type_t") (CAIRO-INT "CAIRO_SURFACE_TYPE_WIN32" "cairo_surface_type_t") (CAIRO-INT "CAIRO_SURFACE_TYPE_BEOS" "cairo_surface_type_t") (CAIRO-INT "CAIRO_SURFACE_TYPE_DIRECTFB" "cairo_surface_type_t") (CAIRO-INT "CAIRO_SURFACE_TYPE_SVG" "cairo_surface_type_t") (CAIRO-INT "CAIRO_SURFACE_TYPE_OS2" "cairo_surface_type_t") (CAIRO-INT "CAIRO_SURFACE_TYPE_WIN32_PRINTING" "cairo_surface_type_t") (CAIRO-INT "CAIRO_SURFACE_TYPE_QUARTZ_IMAGE" "cairo_surface_type_t") (CAIRO-INT "CAIRO_FORMAT_ARGB32" "cairo_format_t") (CAIRO-INT "CAIRO_FORMAT_RGB24" "cairo_format_t") (CAIRO-INT "CAIRO_FORMAT_A8" "cairo_format_t") (CAIRO-INT "CAIRO_FORMAT_A1" "cairo_format_t") ;;; (CAIRO-INT "CAIRO_FORMAT_RGB16_565" "cairo_format_t") ; out 1.4.0 (CAIRO-INT "CAIRO_PATTERN_TYPE_SOLID" "cairo_pattern_type_t") (CAIRO-INT "CAIRO_PATTERN_TYPE_SURFACE" "cairo_pattern_type_t") (CAIRO-INT "CAIRO_PATTERN_TYPE_LINEAR" "cairo_pattern_type_t") (CAIRO-INT "CAIRO_PATTERN_TYPE_RADIAL" "cairo_pattern_type_t") (CAIRO-INT "CAIRO_EXTEND_NONE" "cairo_extend_t") (CAIRO-INT "CAIRO_EXTEND_REPEAT" "cairo_extend_t") (CAIRO-INT "CAIRO_EXTEND_REFLECT" "cairo_extend_t") (CAIRO-INT "CAIRO_EXTEND_PAD" "cairo_extend_t") (CAIRO-INT "CAIRO_FILTER_FAST" "cairo_filter_t") (CAIRO-INT "CAIRO_FILTER_GOOD" "cairo_filter_t") (CAIRO-INT "CAIRO_FILTER_BEST" "cairo_filter_t") (CAIRO-INT "CAIRO_FILTER_NEAREST" "cairo_filter_t") (CAIRO-INT "CAIRO_FILTER_BILINEAR" "cairo_filter_t") (CAIRO-INT "CAIRO_FILTER_GAUSSIAN" "cairo_filter_t") ;typedef void(*cairo_destroy_func_t)(void *data) ;typedef struct { unsigned long index double x double y} cairo_glyph_t ;typedef struct { double x_bearing double y_bearing double width double height double x_advance double y_advance} cairo_text_extents_t ;typedef struct { double ascent double descent double height double max_x_advance double max_y_advance} cairo_font_extents_t ;typedef struct cairo_path { cairo_status_t status cairo_path_data_t *data int num_data} cairo_path_t (CAIRO-FUNC "int cairo_version void") (CAIRO-FUNC "char* cairo_version_string void" 'const) ;moved up a ways to get cairo_t under HAVE_CAIRO_CREATE (CAIRO-FUNC "cairo_t* cairo_create cairo_surface_t* target") (CAIRO-FUNC "cairo_t* cairo_reference cairo_t* cr") (CAIRO-FUNC "void cairo_destroy cairo_t* cr") (CAIRO-FUNC "void cairo_save cairo_t* cr") (CAIRO-FUNC "void cairo_restore cairo_t* cr") (CAIRO-FUNC "void cairo_push_group cairo_t* cr") (CAIRO-FUNC "void cairo_push_group_with_content cairo_t* cr cairo_content_t content") (CAIRO-FUNC "cairo_pattern_t* cairo_pop_group cairo_t* cr") (CAIRO-FUNC "void cairo_pop_group_to_source cairo_t* cr") (CAIRO-FUNC "void cairo_set_operator cairo_t* cr cairo_operator_t op") (CAIRO-FUNC "void cairo_set_source cairo_t* cr cairo_pattern_t* source") (CAIRO-FUNC "void cairo_set_source_rgb cairo_t* cr double red double green double blue") (CAIRO-FUNC "void cairo_set_source_rgba cairo_t* cr double red double green double blue double alpha") (CAIRO-FUNC "void cairo_set_source_surface cairo_t* cr cairo_surface_t* surface double x double y") (CAIRO-FUNC "void cairo_set_tolerance cairo_t* cr double tolerance") (CAIRO-FUNC "void cairo_set_antialias cairo_t* cr cairo_antialias_t antialias") (CAIRO-FUNC "void cairo_set_fill_rule cairo_t* cr cairo_fill_rule_t fill_rule") (CAIRO-FUNC "void cairo_set_line_width cairo_t* cr double width") (CAIRO-FUNC "void cairo_set_line_cap cairo_t* cr cairo_line_cap_t line_cap") (CAIRO-FUNC "void cairo_set_line_join cairo_t* cr cairo_line_join_t line_join") (CAIRO-FUNC "void cairo_set_dash cairo_t* cr gdouble* dashes int num_dashes double offset") (CAIRO-FUNC "void cairo_set_miter_limit cairo_t* cr double limit") (CAIRO-FUNC "void cairo_translate cairo_t* cr double tx double ty") (CAIRO-FUNC "void cairo_scale cairo_t* cr double sx double sy") (CAIRO-FUNC "void cairo_rotate cairo_t* cr double angle") (CAIRO-FUNC "void cairo_transform cairo_t* cr cairo_matrix_t* matrix") (CAIRO-FUNC "void cairo_set_matrix cairo_t* cr cairo_matrix_t* matrix") (CAIRO-FUNC "void cairo_identity_matrix cairo_t* cr") (CAIRO-FUNC "void cairo_user_to_device cairo_t* cr gdouble* [x] gdouble* [y]") (CAIRO-FUNC "void cairo_user_to_device_distance cairo_t* cr gdouble* [dx] gdouble* [dy]") (CAIRO-FUNC "void cairo_device_to_user cairo_t* cr gdouble* [x] gdouble* [y]") (CAIRO-FUNC "void cairo_device_to_user_distance cairo_t* cr gdouble* [dx] gdouble* [dy]") (CAIRO-FUNC "void cairo_new_path cairo_t* cr") (CAIRO-FUNC "void cairo_move_to cairo_t* cr double x double y") (CAIRO-FUNC "void cairo_new_sub_path cairo_t* cr") (CAIRO-FUNC "void cairo_line_to cairo_t* cr double x double y") (CAIRO-FUNC "void cairo_curve_to cairo_t* cr double x1 double y1 double x2 double y2 double x3 double y3") (CAIRO-FUNC "void cairo_arc cairo_t* cr double xc double yc double radius double angle1 double angle2") (CAIRO-FUNC "void cairo_arc_negative cairo_t* cr double xc double yc double radius double angle1 double angle2") (CAIRO-FUNC "void cairo_rel_move_to cairo_t* cr double dx double dy") (CAIRO-FUNC "void cairo_rel_line_to cairo_t* cr double dx double dy") (CAIRO-FUNC "void cairo_rel_curve_to cairo_t* cr double dx1 double dy1 double dx2 double dy2 double dx3 double dy3") (CAIRO-FUNC "void cairo_rectangle cairo_t* cr double x double y double width double height") (CAIRO-FUNC "void cairo_close_path cairo_t* cr") (CAIRO-FUNC "void cairo_paint cairo_t* cr") (CAIRO-FUNC "void cairo_paint_with_alpha cairo_t* cr double alpha") (CAIRO-FUNC "void cairo_mask cairo_t* cr cairo_pattern_t* pattern") (CAIRO-FUNC "void cairo_mask_surface cairo_t* cr cairo_surface_t* surface double surface_x double surface_y") (CAIRO-FUNC "void cairo_stroke cairo_t* cr") (CAIRO-FUNC "void cairo_stroke_preserve cairo_t* cr") (CAIRO-FUNC "void cairo_fill cairo_t* cr") (CAIRO-FUNC "void cairo_fill_preserve cairo_t* cr") (CAIRO-FUNC "void cairo_copy_page cairo_t* cr") (CAIRO-FUNC "void cairo_show_page cairo_t* cr") (CAIRO-FUNC "bool cairo_in_stroke cairo_t* cr double x double y") (CAIRO-FUNC "bool cairo_in_fill cairo_t* cr double x double y") ;(CAIRO-FUNC "void cairo_stroke_extents cairo_t* cr double* x1 double* y1 double* x2 double* y2") ;(CAIRO-FUNC "void cairo_fill_extents cairo_t* cr double* x1 double* y1 double* x2 double* y2") (CAIRO-FUNC "void cairo_reset_clip cairo_t* cr") (CAIRO-FUNC "void cairo_clip cairo_t* cr") (CAIRO-FUNC "void cairo_clip_preserve cairo_t* cr") (CAIRO-FUNC "cairo_font_options_t* cairo_font_options_create void") (CAIRO-FUNC "cairo_font_options_t* cairo_font_options_copy cairo_font_options_t* original") (CAIRO-FUNC "void cairo_font_options_destroy cairo_font_options_t* options") (CAIRO-FUNC "cairo_status_t cairo_font_options_status cairo_font_options_t* options") (CAIRO-FUNC "void cairo_font_options_merge cairo_font_options_t* options cairo_font_options_t* other") (CAIRO-FUNC "bool cairo_font_options_equal cairo_font_options_t* options cairo_font_options_t* other") (CAIRO-FUNC "gulong cairo_font_options_hash cairo_font_options_t* options") (CAIRO-FUNC "void cairo_font_options_set_antialias cairo_font_options_t* options cairo_antialias_t antialias") (CAIRO-FUNC "cairo_antialias_t cairo_font_options_get_antialias cairo_font_options_t* options") (CAIRO-FUNC "void cairo_font_options_set_subpixel_order cairo_font_options_t* options cairo_subpixel_order_t subpixel_order") (CAIRO-FUNC "cairo_subpixel_order_t cairo_font_options_get_subpixel_order cairo_font_options_t* options") (CAIRO-FUNC "void cairo_font_options_set_hint_style cairo_font_options_t* options cairo_hint_style_t hint_style") (CAIRO-FUNC "cairo_hint_style_t cairo_font_options_get_hint_style cairo_font_options_t* options") (CAIRO-FUNC "void cairo_font_options_set_hint_metrics cairo_font_options_t* options cairo_hint_metrics_t hint_metrics") (CAIRO-FUNC "cairo_hint_metrics_t cairo_font_options_get_hint_metrics cairo_font_options_t* options") (CAIRO-FUNC "void cairo_select_font_face cairo_t* cr char* family cairo_font_slant_t slant cairo_font_weight_t weight") (CAIRO-FUNC "void cairo_set_font_size cairo_t* cr double size") (CAIRO-FUNC "void cairo_set_font_matrix cairo_t* cr cairo_matrix_t* matrix") (CAIRO-FUNC "void cairo_get_font_matrix cairo_t* cr cairo_matrix_t* matrix") (CAIRO-FUNC "void cairo_set_font_options cairo_t* cr cairo_font_options_t* options") (CAIRO-FUNC "void cairo_get_font_options cairo_t* cr cairo_font_options_t* options") (CAIRO-FUNC "void cairo_set_scaled_font cairo_t* cr cairo_scaled_font_t* scaled_font") (CAIRO-FUNC "void cairo_show_text cairo_t* cr char* utf8") (CAIRO-FUNC "void cairo_show_glyphs cairo_t* cr cairo_glyph_t* glyphs int num_glyphs") (CAIRO-FUNC "cairo_font_face_t* cairo_get_font_face cairo_t* cr") (CAIRO-FUNC "void cairo_font_extents cairo_t* cr cairo_font_extents_t* extents") (CAIRO-FUNC "void cairo_set_font_face cairo_t* cr cairo_font_face_t* font_face") (CAIRO-FUNC "void cairo_text_extents cairo_t* cr char* utf8 cairo_text_extents_t* extents") (CAIRO-FUNC "void cairo_glyph_extents cairo_t* cr cairo_glyph_t* glyphs int num_glyphs cairo_text_extents_t* extents") (CAIRO-FUNC "void cairo_text_path cairo_t* cr char* utf8") (CAIRO-FUNC "void cairo_glyph_path cairo_t* cr cairo_glyph_t* glyphs int num_glyphs") (CAIRO-FUNC "cairo_font_face_t* cairo_font_face_reference cairo_font_face_t* font_face") (CAIRO-FUNC "void cairo_font_face_destroy cairo_font_face_t* font_face") (CAIRO-FUNC "cairo_status_t cairo_font_face_status cairo_font_face_t* font_face") (CAIRO-FUNC "gpointer cairo_font_face_get_user_data cairo_font_face_t* font_face cairo_user_data_key_t* key") (CAIRO-FUNC "cairo_status_t cairo_font_face_set_user_data cairo_font_face_t* font_face cairo_user_data_key_t* key gpointer user_data cairo_destroy_func_t destroy") (CAIRO-FUNC "cairo_scaled_font_t* cairo_scaled_font_create cairo_font_face_t* font_face cairo_matrix_t* font_matrix cairo_matrix_t* ctm cairo_font_options_t* options") (CAIRO-FUNC "cairo_scaled_font_t* cairo_scaled_font_reference cairo_scaled_font_t* scaled_font") (CAIRO-FUNC "void cairo_scaled_font_destroy cairo_scaled_font_t* scaled_font") (CAIRO-FUNC "cairo_status_t cairo_scaled_font_status cairo_scaled_font_t* scaled_font") (CAIRO-FUNC "void cairo_scaled_font_extents cairo_scaled_font_t* scaled_font cairo_font_extents_t* extents") (CAIRO-FUNC "void cairo_scaled_font_text_extents cairo_scaled_font_t* scaled_font char* utf8 cairo_text_extents_t* extents") (CAIRO-FUNC "void cairo_scaled_font_glyph_extents cairo_scaled_font_t* scaled_font cairo_glyph_t* glyphs int num_glyphs cairo_text_extents_t* extents") (CAIRO-FUNC "cairo_font_face_t* cairo_scaled_font_get_font_face cairo_scaled_font_t* scaled_font") (CAIRO-FUNC "void cairo_scaled_font_get_font_matrix cairo_scaled_font_t* scaled_font cairo_matrix_t* font_matrix") (CAIRO-FUNC "void cairo_scaled_font_get_ctm cairo_scaled_font_t* scaled_font cairo_matrix_t* ctm") (CAIRO-FUNC "void cairo_scaled_font_get_font_options cairo_scaled_font_t* scaled_font cairo_font_options_t* options") (CAIRO-FUNC "cairo_operator_t cairo_get_operator cairo_t* cr") (CAIRO-FUNC "cairo_pattern_t* cairo_get_source cairo_t* cr") (CAIRO-FUNC "gdouble cairo_get_tolerance cairo_t* cr") (CAIRO-FUNC "cairo_antialias_t cairo_get_antialias cairo_t* cr") (CAIRO-FUNC "void cairo_get_current_point cairo_t* cr gdouble* [x] gdouble* [y]") (CAIRO-FUNC "cairo_fill_rule_t cairo_get_fill_rule cairo_t* cr") (CAIRO-FUNC "gdouble cairo_get_line_width cairo_t* cr") (CAIRO-FUNC "cairo_line_cap_t cairo_get_line_cap cairo_t* cr") (CAIRO-FUNC "cairo_line_join_t cairo_get_line_join cairo_t* cr") (CAIRO-FUNC "gdouble cairo_get_miter_limit cairo_t* cr") (CAIRO-FUNC "void cairo_get_matrix cairo_t* cr cairo_matrix_t* matrix") (CAIRO-FUNC "cairo_surface_t* cairo_get_target cairo_t* cr") (CAIRO-FUNC "cairo_surface_t* cairo_get_group_target cairo_t* cr") (CAIRO-FUNC "cairo_path_t* cairo_copy_path cairo_t* cr") (CAIRO-FUNC "cairo_path_t* cairo_copy_path_flat cairo_t* cr") (CAIRO-FUNC "void cairo_append_path cairo_t* cr cairo_path_t* path") (CAIRO-FUNC "void cairo_path_destroy cairo_path_t* path") (CAIRO-FUNC "cairo_status_t cairo_status cairo_t* cr") (CAIRO-FUNC "char* cairo_status_to_string cairo_status_t status" 'const) (CAIRO-FUNC "cairo_surface_t* cairo_surface_create_similar cairo_surface_t* other cairo_content_t content int width int height") (CAIRO-FUNC "cairo_surface_t* cairo_surface_reference cairo_surface_t* surface") (CAIRO-FUNC "void cairo_surface_finish cairo_surface_t* surface") (CAIRO-FUNC "void cairo_surface_destroy cairo_surface_t* surface") (CAIRO-FUNC "cairo_status_t cairo_surface_status cairo_surface_t* surface") (CAIRO-FUNC "cairo_content_t cairo_surface_get_content cairo_surface_t* surface") (CAIRO-FUNC "gpointer cairo_surface_get_user_data cairo_surface_t* surface cairo_user_data_key_t* key") (CAIRO-FUNC "cairo_status_t cairo_surface_set_user_data cairo_surface_t* surface cairo_user_data_key_t* key gpointer user_data cairo_destroy_func_t destroy") (CAIRO-FUNC "void cairo_surface_get_font_options cairo_surface_t* surface cairo_font_options_t* options") (CAIRO-FUNC "void cairo_surface_flush cairo_surface_t* surface") (CAIRO-FUNC "void cairo_surface_mark_dirty cairo_surface_t* surface") (CAIRO-FUNC "void cairo_surface_mark_dirty_rectangle cairo_surface_t* surface int x int y int width int height") (CAIRO-FUNC "void cairo_surface_set_device_offset cairo_surface_t* surface double x_offset double y_offset") (CAIRO-FUNC "void cairo_surface_get_device_offset cairo_surface_t* surface gdouble* [x_offset] gdouble* [y_offset]") (CAIRO-FUNC "void cairo_surface_set_fallback_resolution cairo_surface_t* surface double x_pixels_per_inch double y_pixels_per_inch") (CAIRO-FUNC "cairo_surface_t* cairo_image_surface_create cairo_format_t format int width int height") (CAIRO-FUNC "cairo_surface_t* cairo_image_surface_create_for_data guchar* data cairo_format_t format int width int height int stride") (CAIRO-FUNC "guchar* cairo_image_surface_get_data cairo_surface_t* surface") (CAIRO-FUNC "cairo_format_t cairo_image_surface_get_format cairo_surface_t* surface") (CAIRO-FUNC "int cairo_image_surface_get_width cairo_surface_t* surface") (CAIRO-FUNC "int cairo_image_surface_get_height cairo_surface_t* surface") (CAIRO-FUNC "int cairo_image_surface_get_stride cairo_surface_t* surface") (CAIRO-FUNC "cairo_pattern_t* cairo_pattern_create_rgb double red double green double blue") (CAIRO-FUNC "cairo_pattern_t* cairo_pattern_create_rgba double red double green double blue double alpha") (CAIRO-FUNC "cairo_pattern_t* cairo_pattern_create_for_surface cairo_surface_t* surface") (CAIRO-FUNC "cairo_pattern_t* cairo_pattern_create_linear double x0 double y0 double x1 double y1") (CAIRO-FUNC "cairo_pattern_t* cairo_pattern_create_radial double cx0 double cy0 double radius0 double cx1 double cy1 double radius1") (CAIRO-FUNC "cairo_pattern_t* cairo_pattern_reference cairo_pattern_t* pattern") (CAIRO-FUNC "void cairo_pattern_destroy cairo_pattern_t* pattern") (CAIRO-FUNC "cairo_status_t cairo_pattern_status cairo_pattern_t* pattern") (CAIRO-FUNC "void cairo_pattern_add_color_stop_rgb cairo_pattern_t* pattern double offset double red double green double blue") (CAIRO-FUNC "void cairo_pattern_add_color_stop_rgba cairo_pattern_t* pattern double offset double red double green double blue double alpha") (CAIRO-FUNC "void cairo_pattern_set_matrix cairo_pattern_t* pattern cairo_matrix_t* matrix") (CAIRO-FUNC "void cairo_pattern_get_matrix cairo_pattern_t* pattern cairo_matrix_t* matrix") (CAIRO-FUNC "void cairo_pattern_set_extend cairo_pattern_t* pattern cairo_extend_t extend") (CAIRO-FUNC "cairo_extend_t cairo_pattern_get_extend cairo_pattern_t* pattern") (CAIRO-FUNC "void cairo_pattern_set_filter cairo_pattern_t* pattern cairo_filter_t filter") (CAIRO-FUNC "cairo_filter_t cairo_pattern_get_filter cairo_pattern_t* pattern") (CAIRO-FUNC "void cairo_matrix_init cairo_matrix_t* matrix double xx double yx double xy double yy double x0 double y0") (CAIRO-FUNC "void cairo_matrix_init_identity cairo_matrix_t* matrix") (CAIRO-FUNC "void cairo_matrix_init_translate cairo_matrix_t* matrix double tx double ty") (CAIRO-FUNC "void cairo_matrix_init_scale cairo_matrix_t* matrix double sx double sy") (CAIRO-FUNC "void cairo_matrix_init_rotate cairo_matrix_t* matrix double radians") (CAIRO-FUNC "void cairo_matrix_translate cairo_matrix_t* matrix double tx double ty") (CAIRO-FUNC "void cairo_matrix_scale cairo_matrix_t* matrix double sx double sy") (CAIRO-FUNC "void cairo_matrix_rotate cairo_matrix_t* matrix double radians") (CAIRO-FUNC "cairo_status_t cairo_matrix_invert cairo_matrix_t* matrix") (CAIRO-FUNC "void cairo_matrix_multiply cairo_matrix_t* result cairo_matrix_t* a cairo_matrix_t* b") (CAIRO-FUNC "void cairo_matrix_transform_distance cairo_matrix_t* matrix gdouble* [dx] gdouble* [dy]") (CAIRO-FUNC "void cairo_matrix_transform_point cairo_matrix_t* matrix gdouble* [x] gdouble* [y]") ;(CAIRO-STRUCT-make "cairo_matrix_t") (CAIRO-PNG-FUNC "cairo_surface_t* cairo_image_surface_create_from_png char* filename" 'const) (CAIRO-PNG-FUNC "cairo_status_t cairo_surface_write_to_png cairo_surface_t* surface char* filename" 'const) (CFNC "PangoLayout* pango_cairo_create_layout cairo_t* cr") (CFNC "void pango_cairo_update_layout cairo_t* cr PangoLayout* layout") (CFNC "void pango_cairo_update_context cairo_t* cr PangoContext* context") (CFNC "void pango_cairo_context_set_font_options PangoContext* context cairo_font_options_t* options") (CFNC "cairo_font_options_t* pango_cairo_context_get_font_options PangoContext* context" 'const-return) (CFNC "void pango_cairo_context_set_resolution PangoContext* context gdouble dpi") (CFNC "gdouble pango_cairo_context_get_resolution PangoContext* context") (CFNC "void pango_cairo_show_glyph_string cairo_t* cr PangoFont* font PangoGlyphString* glyphs") (CFNC "void pango_cairo_show_layout_line cairo_t* cr PangoLayoutLine* line") (CFNC "void pango_cairo_show_layout cairo_t* cr PangoLayout* layout") (CFNC "void pango_cairo_show_error_underline cairo_t* cr gdouble x gdouble y gdouble width gdouble height") (CFNC "void pango_cairo_glyph_string_path cairo_t* cr PangoFont* font PangoGlyphString* glyphs") (CFNC "void pango_cairo_layout_line_path cairo_t* cr PangoLayoutLine* line") (CFNC "void pango_cairo_layout_path cairo_t* cr PangoLayout* layout") (CFNC "void pango_cairo_error_underline_path cairo_t* cr gdouble x gdouble y gdouble width gdouble height") ;(CFNC "cairo_t* gdk_cairo_create GdkDrawable* drawable") -- moved up ;;; (CFNC-gtk2 "void gdk_cairo_set_source_color cairo_t* cr GdkColor* color") (CFNC "void gdk_cairo_set_source_pixbuf cairo_t* cr GdkPixbuf* pixbuf gdouble pixbuf_x gdouble pixbuf_y") ;;; 2.91.0 (CFNC "void gdk_cairo_set_source_pixmap cairo_t* cr GdkPixmap* pixmap double pixmap_x double pixmap_y") (CFNC "void gdk_cairo_rectangle cairo_t* cr GdkRectangle* rectangle") ;;; (CFNC "void gdk_cairo_region cairo_t* cr GdkRegion* region") (CAIRO-FUNC "guint cairo_get_reference_count cairo_t* cr") (CAIRO-FUNC "void* cairo_get_user_data cairo_t* cr cairo_user_data_key_t* key") (CAIRO-FUNC "cairo_status_t cairo_set_user_data cairo_t* cr cairo_user_data_key_t* key void* user_data cairo_destroy_func_t destroy") (CAIRO-FUNC "void cairo_clip_extents cairo_t* cr double* [x1] double* [y1] double* [x2] double* [y2]") (CAIRO-FUNC "cairo_rectangle_list_t* cairo_copy_clip_rectangle_list cairo_t* cr") (CAIRO-FUNC "void cairo_rectangle_list_destroy cairo_rectangle_list_t* rectangle_list") (CAIRO-FUNC "guint cairo_font_face_get_reference_count cairo_font_face_t* font_face") (CAIRO-FUNC "guint cairo_scaled_font_get_reference_count cairo_scaled_font_t* scaled_font") (CAIRO-FUNC "void* cairo_scaled_font_get_user_data cairo_scaled_font_t* scaled_font cairo_user_data_key_t* key") (CAIRO-FUNC "cairo_status_t cairo_scaled_font_set_user_data cairo_scaled_font_t* scaled_font cairo_user_data_key_t* key void* user_data cairo_destroy_func_t destroy") (CAIRO-FUNC "int cairo_get_dash_count cairo_t* cr") (CAIRO-FUNC "void cairo_get_dash cairo_t* cr double* [dashes] double* [offset]") (CAIRO-FUNC "guint cairo_surface_get_reference_count cairo_surface_t* surface") (CAIRO-FUNC "guint cairo_pattern_get_reference_count cairo_pattern_t* pattern") (CAIRO-FUNC "void* cairo_pattern_get_user_data cairo_pattern_t* pattern cairo_user_data_key_t* key") (CAIRO-FUNC "cairo_status_t cairo_pattern_set_user_data cairo_pattern_t* pattern cairo_user_data_key_t* key void* user_data cairo_destroy_func_t destroy") (CAIRO-FUNC "cairo_status_t cairo_pattern_get_rgba cairo_pattern_t* pattern double* [red] double* [green] double* [blue] double* [alpha]") (CAIRO-FUNC "cairo_status_t cairo_pattern_get_surface cairo_pattern_t* pattern cairo_surface_t** [surface]") (CAIRO-FUNC "cairo_status_t cairo_pattern_get_color_stop_rgba cairo_pattern_t* pattern int index double* [offset] double* [red] double* [green] double* [blue] double* [alpha]") (CAIRO-FUNC "cairo_status_t cairo_pattern_get_color_stop_count cairo_pattern_t* pattern int* [count]") (CAIRO-FUNC "cairo_status_t cairo_pattern_get_linear_points cairo_pattern_t* pattern double* [x0] double* [y0] double* [x1] double* [y1]") (CAIRO-FUNC "cairo_status_t cairo_pattern_get_radial_circles cairo_pattern_t* pattern double* [x0] double* [y0] double* [r0] double* [x1] double* [y1] double* [r1]") (CAIRO-FUNC "cairo_scaled_font_t* cairo_get_scaled_font cairo_t* cr") (CINT "GTK_DRAG_RESULT_SUCCESS" "GtkDragResult") (CINT "GTK_DRAG_RESULT_NO_TARGET" "GtkDragResult") (CINT "GTK_DRAG_RESULT_USER_CANCELLED" "GtkDragResult") (CINT "GTK_DRAG_RESULT_TIMEOUT_EXPIRED" "GtkDragResult") (CINT "GTK_DRAG_RESULT_GRAB_BROKEN" "GtkDragResult") (CINT "GTK_DRAG_RESULT_ERROR" "GtkDragResult") ;;; (CFNC-gtk2 "gchar* gdk_color_to_string GdkColor* color") (CFNC "void gdk_event_request_motions GdkEventMotion* event") (CFNC "void gdk_notify_startup_complete_with_id gchar* startup_id") (CFNC "guint gdk_threads_add_idle_full gint priority GSourceFunc func lambda_data func_info GDestroyNotify notify") (CFNC "guint gdk_threads_add_idle GSourceFunc func lambda_data #func_info") (CFNC "guint gdk_threads_add_timeout_full gint priority guint interval GSourceFunc func lambda_data func_info GDestroyNotify notify") (CFNC "guint gdk_threads_add_timeout guint interval GSourceFunc func lambda_data #func_info") (CFNC "void gdk_window_set_startup_id GdkWindow* window gchar* startup_id") (CFNC "void gdk_window_beep GdkWindow* window") (CFNC "void gdk_window_set_opacity GdkWindow* window gdouble opacity") ;;; (CFNC "GtkWidget* gtk_action_create_menu GtkAction* action") (CFNC "void gtk_binding_entry_skip GtkBindingSet* binding_set guint keyval GdkModifierType modifiers") (CFNC "GList* gtk_cell_layout_get_cells GtkCellLayout* cell_layout") (CFNC "void gtk_entry_completion_set_inline_selection GtkEntryCompletion* completion gboolean inline_selection") (CFNC "gboolean gtk_entry_completion_get_inline_selection GtkEntryCompletion* completion") (CFNC "gchar* gtk_entry_completion_get_completion_prefix GtkEntryCompletion* completion" 'const) (CFNC "void gtk_entry_set_cursor_hadjustment GtkEntry* entry GtkAdjustment* adjustment") (CFNC "GtkAdjustment* gtk_entry_get_cursor_hadjustment GtkEntry* entry") (CFNC "GList* gtk_icon_theme_list_contexts GtkIconTheme* icon_theme") ;(CFNC "GtkPageSetup* gtk_page_setup_new_from_file gchar* file_name GError** [error]") ;(CFNC "gboolean gtk_page_setup_to_file GtkPageSetup* setup char* file_name GError** [error]") ;(CFNC "GtkPageSetup* gtk_page_setup_new_from_key_file GKeyFile* key_file gchar* group_name GError** [error]") ;(CFNC "void gtk_page_setup_to_key_file GtkPageSetup* setup GKeyFile* key_file gchar* group_name") ;(CFNC "GtkPaperSize* gtk_paper_size_new_from_key_file GKeyFile* key_file gchar* group_name GError** [error]") ;(CFNC "void gtk_paper_size_to_key_file GtkPaperSize* size GKeyFile* key_file gchar* group_name") ;(CFNC "GList* gtk_printer_list_papers GtkPrinter* printer") ;(CFNC "gboolean gtk_printer_has_details GtkPrinter* printer") ;(CFNC "void gtk_printer_request_details GtkPrinter* printer") ;(CFNC "GtkPrintCapabilities gtk_printer_get_capabilities GtkPrinter* printer") (CFNC "GtkPrintSettings* gtk_print_settings_new_from_file gchar* file_name GError** [error]") (CFNC "gboolean gtk_print_settings_to_file GtkPrintSettings* settings gchar* file_name GError** [error]") ;(CFNC "GtkPrintSettings* gtk_print_settings_new_from_key_file GKeyFile* key_file gchar* group_name GError** [error]") ;(CFNC "void gtk_print_settings_to_key_file GtkPrintSettings* settings GKeyFile* key_file gchar* group_name") (CFNC "void gtk_range_set_show_fill_level GtkRange* range gboolean show_fill_level") (CFNC "gboolean gtk_range_get_show_fill_level GtkRange* range") (CFNC "void gtk_range_set_restrict_to_fill_level GtkRange* range gboolean restrict_to_fill_level") (CFNC "gboolean gtk_range_get_restrict_to_fill_level GtkRange* range") (CFNC "void gtk_range_set_fill_level GtkRange* range gdouble fill_level") (CFNC "gdouble gtk_range_get_fill_level GtkRange* range") ;;; 3.14.0 (CFNC "void gtk_status_icon_set_screen GtkStatusIcon* status_icon GdkScreen* screen") ;;; 3.14.0 (CFNC "GdkScreen* gtk_status_icon_get_screen GtkStatusIcon* status_icon") (CFNC "void gtk_tree_view_set_show_expanders GtkTreeView* tree_view gboolean enabled") (CFNC "gboolean gtk_tree_view_get_show_expanders GtkTreeView* tree_view") (CFNC "void gtk_tree_view_set_level_indentation GtkTreeView* tree_view gint indentation") (CFNC "gint gtk_tree_view_get_level_indentation GtkTreeView* tree_view") (CFNC "gboolean gtk_widget_keynav_failed GtkWidget* widget GtkDirectionType direction") (CFNC "void gtk_widget_error_bell GtkWidget* widget") (CFNC "void gtk_widget_set_tooltip_window GtkWidget* widget GtkWindow* custom_window") (CFNC "GtkWindow* gtk_widget_get_tooltip_window GtkWidget* widget") (CFNC "void gtk_widget_trigger_tooltip_query GtkWidget* widget") (CFNC "void gtk_window_set_startup_id GtkWindow* window gchar* startup_id") ;;; 3.7.10 (CFNC "void gtk_window_set_opacity GtkWindow* window gdouble opacity") ;;; 3.7.10 (CFNC "gdouble gtk_window_get_opacity GtkWindow* window") ;;; for 2.11.1: ;;; 3.15 (CFNC "gboolean gdk_display_supports_composite GdkDisplay* display") ;;; 3.15 (CFNC "void gdk_window_set_composited GdkWindow* window gboolean composited") (CFNC "void gtk_text_buffer_add_mark GtkTextBuffer* buffer GtkTextMark* mark GtkTextIter* where") ;;;(CFNC "void gtk_text_layout_invalidate_cursors GtkTextLayout* layout GtkTextIter* start GtkTextIter* end") ;;;(CFNC "void gtk_text_layout_cursors_changed GtkTextLayout* layout gint y gint old_height gint new_height") (CFNC "GtkTextMark* gtk_text_mark_new gchar* name gboolean left_gravity") ;;; this enum is commented out above (CINT "GTK_PRINT_CAPABILITY_NUMBER_UP" "GtkPrintCapabilities") ;;; for 2.11.2: (CFNC "GtkWidget* gtk_tree_view_column_get_tree_view GtkTreeViewColumn* tree_column") ;;; for 2.11.3 ;;; new headers gtkbuildable builder (XML UI builder -- not important) ;;; (CSTR "GTK_STOCK_DISCARD") ;;;(CFNC "void gtk_text_layout_set_overwrite_mode GtkTextLayout* layout gboolean overwrite") (CFNC "void gtk_tooltip_set_text GtkTooltip* tooltip gchar* text" 'const) (CFNC "void gtk_tree_view_convert_widget_to_tree_coords GtkTreeView* tree_view gint wx gint wy gint* [tx] gint* [ty]") (CFNC "void gtk_tree_view_convert_tree_to_widget_coords GtkTreeView* tree_view gint tx gint ty gint* [wx] gint* [wy]") (CFNC "void gtk_tree_view_convert_widget_to_bin_window_coords GtkTreeView* tree_view gint wx gint wy gint* [bx] gint* [by]") (CFNC "void gtk_tree_view_convert_bin_window_to_widget_coords GtkTreeView* tree_view gint bx gint by gint* [wx] gint* [wy]") (CFNC "void gtk_tree_view_convert_tree_to_bin_window_coords GtkTreeView* tree_view gint tx gint ty gint* [bx] gint* [by]") (CFNC "void gtk_tree_view_convert_bin_window_to_tree_coords GtkTreeView* tree_view gint bx gint by gint* [tx] gint* [ty]") ;;; ;this could be added when 211 is required (CFNC-gtk2 "void gtk_widget_modify_cursor GtkWidget* widget GdkColor* primary GdkColor* secondary") (CFNC "void gtk_widget_set_tooltip_text GtkWidget* widget gchar* text" 'const) (CFNC "gchar* gtk_widget_get_tooltip_text GtkWidget* widget") (CFNC "void gtk_widget_set_tooltip_markup GtkWidget* widget gchar* markup" 'const) (CFNC "gchar* gtk_widget_get_tooltip_markup GtkWidget* widget") ;;; for 2.11.5 (CFNC "gboolean gtk_tree_view_is_rubber_banding_active GtkTreeView* tree_view") ;;; for 2.11.6 (CFNC "void gtk_icon_view_convert_widget_to_bin_window_coords GtkIconView* icon_view gint wx gint wy gint* [bx] gint* [by]") (CFNC "void gtk_icon_view_set_tooltip_item GtkIconView* icon_view GtkTooltip* tooltip GtkTreePath* path") (CFNC "void gtk_icon_view_set_tooltip_cell GtkIconView* icon_view GtkTooltip* tooltip GtkTreePath* path GtkCellRenderer* cell") (CFNC "gboolean gtk_icon_view_get_tooltip_context GtkIconView* icon_view gint* [x] gint* [y] gboolean keyboard_tip GtkTreeModel** [model] GtkTreePath** [path] GtkTreeIter* @iter") (CFNC "void gtk_icon_view_set_tooltip_column GtkIconView* icon_view gint column") (CFNC "gint gtk_icon_view_get_tooltip_column GtkIconView* icon_view ") (CFNC "void gtk_menu_tool_button_set_arrow_tooltip_text GtkMenuToolButton* button gchar* text" 'const) (CFNC "void gtk_menu_tool_button_set_arrow_tooltip_markup GtkMenuToolButton* button gchar* markup" 'const) (CFNC "void gtk_tool_item_set_tooltip_text GtkToolItem* tool_item gchar* text" 'const) (CFNC "void gtk_tool_item_set_tooltip_markup GtkToolItem* tool_item gchar* markup" 'const) (CFNC "void gtk_tooltip_set_tip_area GtkTooltip* tooltip GdkRectangle* rect") (CFNC "void gtk_tree_view_set_tooltip_row GtkTreeView* tree_view GtkTooltip* tooltip GtkTreePath* path") (CFNC "void gtk_tree_view_set_tooltip_cell GtkTreeView* tree_view GtkTooltip* tooltip GtkTreePath* path GtkTreeViewColumn* column GtkCellRenderer* cell") (CFNC "gboolean gtk_tree_view_get_tooltip_context GtkTreeView* tree_view gint* [x] gint* [y] gboolean keyboard_tip GtkTreeModel** [model] GtkTreePath** [path] GtkTreeIter* @iter") (CFNC "void gtk_tree_view_set_tooltip_column GtkTreeView* tree_view gint column") (CFNC "gint gtk_tree_view_get_tooltip_column GtkTreeView* tree_view ") (CFNC "void gtk_widget_set_has_tooltip GtkWidget* widget gboolean has_tooltip") (CFNC "gboolean gtk_widget_get_has_tooltip GtkWidget* widget") ;;; 2.91.6 (CLNG "GTK_TYPE_TOOLTIP") (CCAST "GTK_TOOLTIP(obj)" "GtkTooltip*") (CCHK "GTK_IS_TOOLTIP(obj)" "GtkTooltip*") ;;; for 2.13.0, mostly deprecated in 3.19 (CINT-2.14 "GTK_CALENDAR_SHOW_DETAILS" "GtkCalendarDisplayOptions") (CFNC-2.14 "void gtk_calendar_set_detail_func GtkCalendar* calendar GtkCalendarDetailFunc func gpointer data GDestroyNotify destroy") (CFNC-2.14 "void gtk_calendar_set_detail_width_chars GtkCalendar* calendar gint chars") (CFNC-2.14 "void gtk_calendar_set_detail_height_rows GtkCalendar* calendar gint rows") (CFNC-2.14 "gint gtk_calendar_get_detail_width_chars GtkCalendar* calendar") (CFNC-2.14 "gint gtk_calendar_get_detail_height_rows GtkCalendar* calendar") (CFNC-2.14 "gint gdk_screen_get_monitor_width_mm GdkScreen* screen gint monitor_num") (CFNC-2.14 "gint gdk_screen_get_monitor_height_mm GdkScreen* screen gint monitor_num") (CFNC-2.14 "gchar* gdk_screen_get_monitor_plug_name GdkScreen* screen gint monitor_num") ;;; (CFNC-2.14 "void gtk_tooltip_set_icon_from_icon_name GtkTooltip* tooltip gchar* icon_name GtkIconSize size" 'const) ;(CFNC-2.14 "void gtk_test_init int* argcp char*** argvp ...") ;(CFNC-2.14 "GtkWidget* gtk_test_find_widget GtkWidget* widget gchar* label_pattern GType widget_type" 'const) ;(CFNC-2.14 "GtkWidget* gtk_test_create_widget GType widget_type gchar* first_property_name ..." 'const) ;(CFNC-2.14 "GtkWidget* gtk_test_create_simple_window gchar* window_title gchar* dialog_text" 'const) ;(CFNC-2.14 "GtkWidget* gtk_test_display_button_window gchar* window_title gchar* dialog_text ..." 'const) ;(CFNC-2.14 "void gtk_test_slider_set_perc GtkWidget* widget double percentage") ;(CFNC-2.14 "double gtk_test_slider_get_value GtkWidget* widget") ;(CFNC-2.14 "gboolean gtk_test_spin_button_click GtkSpinButton* widget guint button gboolean upwards") ;(CFNC-2.14 "gboolean gtk_test_widget_click GtkWidget* widget guint button GdkModifierType modifiers") ;(CFNC-2.14 "gboolean gtk_test_widget_send_key GtkWidget* widget guint keyval GdkModifierType modifiers") ;(CFNC-2.14 "void gtk_test_text_set GtkWidget* widget gchar* string" 'const) ;(CFNC-2.14 "gchar* gtk_test_text_get GtkWidget* widget") (CAIRO-FUNC "void cairo_path_extents cairo_t* cr double* [x1] double* [y1] double* [x2] double* [y2]") (CAIRO-FUNC "bool cairo_has_current_point cairo_t* cr") (CAIRO-FUNC "void cairo_surface_copy_page cairo_surface_t* surface") (CAIRO-FUNC "void cairo_surface_show_page cairo_surface_t* surface") (CAIRO-FUNC "int cairo_format_stride_for_width cairo_format_t format int width") ;;; someday, get configure switches and incorporate these changes in Pango: ;;; pango 1.15.0 ;;; (CINT-2108 "PANGO_FONT_MASK_GRAVITY") ;;; pango 1.15.4: ;;; (CINT-2108 "PANGO_ATTR_ABSOLUTE_SIZE" "PangoAttrType") ;;; (CINT-2108 "PANGO_ATTR_GRAVITY" "PangoAttrType") ;;; (CINT-2108 "PANGO_ATTR_GRAVITY_HINT" "PangoAttrType") ;;; (CFNC-2108 "gboolean pango_layout_is_wrapped PangoLayout* layout") ;;; (CFNC-2108 "gboolean pango_layout_is_ellipsized PangoLayout* layout") ;;; pango 19.3: ;(CFNC-2xx "void pango_layout_set_height PangoLayout* layout int height") ;(CFNC-2xx "int pango_layout_get_height PangoLayout* layout") ;;; Pango 1.21.0 ;;; (CFNC-2xx "PangoContext* pango_cairo_create_context cairo_t* cr") ;;; (CFNC-2xx "int pango_layout_get_baseline PangoLayout* layout") ;;; gtk 2.13.4 (CFNC-2.14 "gboolean gtk_accel_group_get_is_locked GtkAccelGroup* accel_group") ;;; 3.3.16 (CFNC-2.14 "GtkWidget* gtk_color_selection_dialog_get_color_selection GtkColorSelectionDialog* colorsel") (CFNC-2.14 "GtkWidget* gtk_container_get_focus_child GtkContainer* container") ;;; 3.12? (CFNC-2.14 "GtkWidget* gtk_dialog_get_action_area GtkDialog* dialog") (CFNC-2.14 "GtkWidget* gtk_dialog_get_content_area GtkDialog* dialog") (CFNC-2.14 "void gtk_entry_set_overwrite_mode GtkEntry* entry gboolean overwrite") (CFNC-2.14 "gboolean gtk_entry_get_overwrite_mode GtkEntry* entry") (CFNC-2.14 "guint16 gtk_entry_get_text_length GtkEntry* entry") ;;; out 2.13.7 (CFNC-2.14 "GtkWidget* gtk_font_selection_get_family_entry GtkFontSelection* fontsel") ;;; 3.1.12 (CFNC-2.14 "GtkWidget* gtk_font_selection_get_family_list GtkFontSelection* fontsel") ;;; out 2.13.7 (CFNC-2.14 "GtkWidget* gtk_font_selection_get_face_entry GtkFontSelection* fontsel") ;;; 3.1.12 (CFNC-2.14 "GtkWidget* gtk_font_selection_get_face_list GtkFontSelection* fontsel") ;;; 3.1.12 (CFNC-2.14 "GtkWidget* gtk_font_selection_get_size_entry GtkFontSelection* fontsel") ;;; 3.1.12 (CFNC-2.14 "GtkWidget* gtk_font_selection_get_size_list GtkFontSelection* fontsel") ;;; 3.1.12 (CFNC-2.14 "GtkWidget* gtk_font_selection_get_preview_entry GtkFontSelection* fontsel") ;;; 3.1.12 (CFNC-2.14 "PangoFontFamily* gtk_font_selection_get_family GtkFontSelection* fontsel") ;;; 3.1.12 (CFNC-2.14 "PangoFontFace* gtk_font_selection_get_face GtkFontSelection* fontsel") ;;; 3.1.12 (CFNC-2.14 "gint gtk_font_selection_get_size GtkFontSelection* fontsel") ;;; 3.1.12 (CFNC-2.14 "GtkWidget* gtk_font_selection_dialog_get_ok_button GtkFontSelectionDialog* fsd") ;;; out 2.15.0 (CFNC-2.14 "GtkWidget* gtk_font_selection_dialog_get_apply_button GtkFontSelectionDialog* fsd") ;;; 3.1.12 (CFNC-2.14 "GtkWidget* gtk_font_selection_dialog_get_cancel_button GtkFontSelectionDialog* fsd") ;;; 3.3.2 (CFNC-2.14 "gboolean gtk_handle_box_get_child_detached GtkHandleBox* handle_box") (CFNC-2.14 "GdkWindow* gtk_layout_get_bin_window GtkLayout* layout") (CFNC-2.14 "gchar* gtk_menu_get_accel_path GtkMenu* menu" 'const) (CFNC-2.14 "gint gtk_menu_get_monitor GtkMenu* menu") (CFNC-2.14 "gchar* gtk_menu_item_get_accel_path GtkMenuItem* menu_item" 'const) ;(CFNC-2.14 "GtkWidget* gtk_message_dialog_get_image GtkMessageDialog* dialog") ;;; 2.99.3 (CFNC-2.14 "gboolean gtk_plug_get_embedded GtkPlug* plug") ;;; 2.99.3 (CFNC-2.14 "GdkWindow* gtk_plug_get_socket_window GtkPlug* plug") ;;; out 2.15.1 (CFNC-2.14 "GtkOrientation gtk_scale_button_get_orientation GtkScaleButton* button") ;;; (CFNC-2.14 "void gtk_scale_button_set_orientation GtkScaleButton* button GtkOrientation orientation") (CFNC-2.14 "GtkWidget* gtk_scale_button_get_plus_button GtkScaleButton* button") (CFNC-2.14 "GtkWidget* gtk_scale_button_get_minus_button GtkScaleButton* button") (CFNC-2.14 "GtkWidget* gtk_scale_button_get_popup GtkScaleButton* button") (CFNC-2.14 "GdkAtom gtk_selection_data_get_target GtkSelectionData* selection_data") (CFNC-2.14 "GdkAtom gtk_selection_data_get_data_type GtkSelectionData* selection_data") (CFNC-2.14 "gint gtk_selection_data_get_format GtkSelectionData* selection_data") ;;; changed 2.14.1 (CFNC-2.14 "guchar* gtk_selection_data_get_data GtkSelectionData* selection_data guint* length" 'const) (CFNC-2.14 "GdkDisplay* gtk_selection_data_get_display GtkSelectionData* selection_data") ;;; 2.99.3 (CFNC-2.14 "GdkWindow* gtk_socket_get_plug_window GtkSocket* socket_") ;;out 2.14.1 ;(CFNC-2.14 "GtkAllocation gtk_widget_get_allocation GtkWidget* widget") (CFNC-2.14 "GdkWindow* gtk_widget_get_window GtkWidget* widget") ;;; (CFNC-2.14 "GtkWidget* gtk_window_get_default GtkWindow* window") (CFNC-2.14 "GdkModifierType gtk_accel_group_get_modifier_mask GtkAccelGroup* accel_group") ;;; 3.3.8 (STRUCT-make "GdkColor guint32 &pixel guint16 &red guint16 &green guint16 &blue") ;;; out 2.90.4 (STRUCT-make "GdkCursor GdkCursorType type guint ref_count") ;;; (STRUCT-make "GdkPoint gint x gint y") ;;; (STRUCT-make "GdkRectangle gint x gint y gint width gint height") ;;; (STRUCT-make "GtkRequisition gint width gint height") ;;; (STRUCT-make "GtkStockItem") ;(STRUCT-make "GtkTextIter") ;(STRUCT-make "GtkTreeIter") ;;; (STRUCT-make "PangoColor") ;(STRUCT-make "PangoRectangle") ;;; (STRUCT-make "PangoLogAttr") ;;; (STRUCT "GdkEventKey GdkEventType type GdkWindow* window guint32 time guint state guint keyval") ;;; gtk 1.13.6 (CINT-2.14 "GDK_CROSSING_GTK_GRAB" "GdkCrossingMode") (CINT-2.14 "GDK_CROSSING_GTK_UNGRAB" "GdkCrossingMode") (CINT-2.14 "GDK_CROSSING_STATE_CHANGED" "GdkCrossingMode") (CFNC-2.14 "guint gdk_threads_add_timeout_seconds_full gint priority guint interval GSourceFunc function lambda_data func_info GDestroyNotify notify") (CFNC-2.14 "guint gdk_threads_add_timeout_seconds guint interval GSourceFunc function lambda_data #func_info") (CFNC-2.14 "gdouble gtk_adjustment_get_lower GtkAdjustment* adjustment") (CFNC-2.14 "void gtk_adjustment_set_lower GtkAdjustment* adjustment gdouble lower") (CFNC-2.14 "gdouble gtk_adjustment_get_upper GtkAdjustment* adjustment") (CFNC-2.14 "void gtk_adjustment_set_upper GtkAdjustment* adjustment gdouble upper") (CFNC-2.14 "gdouble gtk_adjustment_get_step_increment GtkAdjustment* adjustment") (CFNC-2.14 "void gtk_adjustment_set_step_increment GtkAdjustment* adjustment gdouble step_increment") (CFNC-2.14 "gdouble gtk_adjustment_get_page_increment GtkAdjustment* adjustment") (CFNC-2.14 "void gtk_adjustment_set_page_increment GtkAdjustment* adjustment gdouble page_increment") (CFNC-2.14 "gdouble gtk_adjustment_get_page_size GtkAdjustment* adjustment") (CFNC-2.14 "void gtk_adjustment_set_page_size GtkAdjustment* adjustment gdouble page_size") (CFNC-2.14 "void gtk_adjustment_configure GtkAdjustment* adjustment gdouble value gdouble lower gdouble upper gdouble step_increment gdouble page_increment gdouble page_size") (CFNC-2.14 "void gtk_combo_box_set_button_sensitivity GtkComboBox* combo_box GtkSensitivityType sensitivity") (CFNC-2.14 "GtkSensitivityType gtk_combo_box_get_button_sensitivity GtkComboBox* combo_box") (CFNC-2.14 "GFile* gtk_file_chooser_get_file GtkFileChooser* chooser") (CFNC-2.14 "gboolean gtk_file_chooser_set_file GtkFileChooser* chooser GFile* file GError** [error]") (CFNC-2.14 "gboolean gtk_file_chooser_select_file GtkFileChooser* chooser GFile* file GError** [error]") (CFNC-2.14 "void gtk_file_chooser_unselect_file GtkFileChooser* chooser GFile* file") (CFNC-2.14 "GSList* gtk_file_chooser_get_files GtkFileChooser* chooser") (CFNC-2.14 "gboolean gtk_file_chooser_set_current_folder_file GtkFileChooser* chooser GFile* file GError** [error]") (CFNC-2.14 "GFile* gtk_file_chooser_get_current_folder_file GtkFileChooser* chooser") (CFNC-2.14 "GFile* gtk_file_chooser_get_preview_file GtkFileChooser* chooser") (CFNC-2.14 "GtkWidget* gtk_window_get_default_widget GtkWindow* window") ;;; gtkdestroynotify -> gdestroynotify (CINT-2.16 "GTK_ENTRY_ICON_PRIMARY" "GtkEntryIconPosition") (CINT-2.16 "GTK_ENTRY_ICON_SECONDARY" "GtkEntryIconPosition") ;;; 3.13.2 (CINT-2.16 "GTK_ARROWS_BOTH" "GtkArrowPlacement") ;;; 3.13.2 (CINT-2.16 "GTK_ARROWS_START" "GtkArrowPlacement") ;;; 3.13.2 (CINT-2.16 "GTK_ARROWS_END" "GtkArrowPlacement") (CFNC-2.16 "gboolean gtk_link_button_get_visited GtkLinkButton* link_button") (CFNC-2.16 "void gtk_link_button_set_visited GtkLinkButton* link_button bool visited") (CFNC-2.16 "gboolean gdk_keymap_get_caps_lock_state GdkKeymap* keymap") (CFNC-2.16 "GtkTreeModel* gtk_cell_view_get_model GtkCellView* cell_view") (CFNC-2.16 "void gtk_entry_unset_invisible_char GtkEntry* entry") (CFNC-2.16 "void gtk_entry_set_progress_fraction GtkEntry* entry gdouble fraction") (CFNC-2.16 "gdouble gtk_entry_get_progress_fraction GtkEntry* entry") (CFNC-2.16 "void gtk_entry_set_progress_pulse_step GtkEntry* entry gdouble fraction") (CFNC-2.16 "gdouble gtk_entry_get_progress_pulse_step GtkEntry* entry") (CFNC-2.16 "void gtk_entry_progress_pulse GtkEntry* entry") (CFNC-2.16 "void gtk_entry_set_icon_from_pixbuf GtkEntry* entry GtkEntryIconPosition icon_pos GdkPixbuf* pixbuf") ;;; 3.9.8 (CFNC-2.16 "void gtk_entry_set_icon_from_stock GtkEntry* entry GtkEntryIconPosition icon_pos gchar* stock_id") (CFNC-2.16 "void gtk_entry_set_icon_from_icon_name GtkEntry* entry GtkEntryIconPosition icon_pos gchar* icon_name") (CFNC-2.16 "void gtk_entry_set_icon_from_gicon GtkEntry* entry GtkEntryIconPosition icon_pos GIcon* icon") ;??? (CFNC-2.16 "GtkImageType gtk_entry_get_storage_type GtkEntry* entry GtkEntryIconPosition icon_pos") ;??? (CFNC-2.16 "GdkPixbuf* gtk_entry_get_pixbuf GtkEntry* entry GtkEntryIconPosition icon_pos") ;??? (CFNC-2.16 "gchar* gtk_entry_get_stock GtkEntry* entry GtkEntryIconPosition icon_pos" 'const) (CFNC-2.16 "gchar* gtk_entry_get_icon_name GtkEntry* entry GtkEntryIconPosition icon_pos" 'const) ;??? (CFNC-2.16 "GIcon* gtk_entry_get_gicon GtkEntry* entry GtkEntryIconPosition icon_pos") (CFNC-2.16 "void gtk_entry_set_icon_activatable GtkEntry* entry GtkEntryIconPosition icon_pos gboolean activatable") (CFNC-2.16 "gboolean gtk_entry_get_icon_activatable GtkEntry* entry GtkEntryIconPosition icon_pos") (CFNC-2.16 "void gtk_entry_set_icon_sensitive GtkEntry* entry GtkEntryIconPosition icon_pos gboolean sensitive") (CFNC-2.16 "gboolean gtk_entry_get_icon_sensitive GtkEntry* entry GtkEntryIconPosition icon_pos") (CFNC-2.16 "gint gtk_entry_get_icon_at_pos GtkEntry* entry gint x gint y") (CFNC-2.16 "void gtk_entry_set_icon_tooltip_text GtkEntry* entry GtkEntryIconPosition icon_pos gchar* tooltip") (CFNC-2.16 "void gtk_entry_set_icon_tooltip_markup GtkEntry* entry GtkEntryIconPosition icon_pos gchar* tooltip") (CFNC-2.16 "void gtk_entry_set_icon_drag_source GtkEntry* entry GtkEntryIconPosition icon_pos GtkTargetList* target_list GdkDragAction actions") (CFNC-2.16 "gint gtk_entry_get_current_icon_drag_source GtkEntry* entry") ;;; (CFNC-2.16 "void gtk_image_menu_item_set_use_stock GtkImageMenuItem* image_menu_item gboolean use_stock") ;;; (CFNC-2.16 "gboolean gtk_image_menu_item_get_use_stock GtkImageMenuItem* image_menu_item") ;;; (CFNC-2.16 "void gtk_image_menu_item_set_accel_group GtkImageMenuItem* image_menu_item GtkAccelGroup* accel_group") (CFNC-2.16 "void gtk_menu_item_set_label GtkMenuItem* menu_item gchar* label") (CFNC-2.16 "gchar* gtk_menu_item_get_label GtkMenuItem* menu_item" 'const) (CFNC-2.16 "void gtk_menu_item_set_use_underline GtkMenuItem* menu_item gboolean setting") (CFNC-2.16 "gboolean gtk_menu_item_get_use_underline GtkMenuItem* menu_item") (CFNC-2.16 "GdkAtom gtk_selection_data_get_selection GtkSelectionData* selection_data") ;;; 2.15.1 (CINT-2.16 "GDK_BLANK_CURSOR " "GdkCursorType") ;;; (CSTR-2.16 "GTK_STOCK_CAPS_LOCK_WARNING") ;;; 3.9.8 ;;; (CFNC-2.16 "void gtk_action_set_label GtkAction* action gchar* label") ;;; (CFNC-2.16 "gchar* gtk_action_get_label GtkAction* action") ;;; (CFNC-2.16 "void gtk_action_set_short_label GtkAction* action gchar* short_label") ;;; (CFNC-2.16 "gchar* gtk_action_get_short_label GtkAction* action") ;;; (CFNC-2.16 "void gtk_action_set_tooltip GtkAction* action gchar* tooltip") ;;; (CFNC-2.16 "gchar* gtk_action_get_tooltip GtkAction* action") ;;; (CFNC-2.16 "void gtk_action_set_stock_id GtkAction* action gchar* stock_id") ;;; (CFNC-2.16 "gchar* gtk_action_get_stock_id GtkAction* action") ;;; (CFNC-2.16 "void gtk_action_set_gicon GtkAction* action GIcon* icon") ;;; (CFNC-2.16 "GIcon* gtk_action_get_gicon GtkAction* action") ;;; (CFNC-2.16 "void gtk_action_set_icon_name GtkAction* action gchar* icon_name") ;;; (CFNC-2.16 "gchar* gtk_action_get_icon_name GtkAction* action") ;;; (CFNC-2.16 "void gtk_action_set_visible_horizontal GtkAction* action gboolean visible_horizontal") ;;; (CFNC-2.16 "gboolean gtk_action_get_visible_horizontal GtkAction* action") ;;; (CFNC-2.16 "void gtk_action_set_visible_vertical GtkAction* action gboolean visible_vertical") ;;; (CFNC-2.16 "gboolean gtk_action_get_visible_vertical GtkAction* action") ;;; (CFNC-2.16 "void gtk_action_set_is_important GtkAction* action gboolean is_important") ;;; (CFNC-2.16 "gboolean gtk_action_get_is_important GtkAction* action") (CFNC-2.16 "gchar* gtk_entry_get_icon_tooltip_text GtkEntry* entry GtkEntryIconPosition icon_pos") (CFNC-2.16 "gchar* gtk_entry_get_icon_tooltip_markup GtkEntry* entry GtkEntryIconPosition icon_pos") (CFNC-2.16 "void gtk_scale_add_mark GtkScale* scale gdouble value GtkPositionType position gchar* markup") (CFNC-2.16 "void gtk_scale_clear_marks GtkScale* scale") ;;; 2.15.2 (these on 2.17.2) ;;; (CFNC-2.18 "void gtk_image_menu_item_set_always_show_image GtkImageMenuItem* image_menu_item gboolean always_show") ;;; (CFNC-2.18 "gboolean gtk_image_menu_item_get_always_show_image GtkImageMenuItem* image_menu_item") (CINT-2.18 "PANGO_WEIGHT_THIN" "PangoWeight") (CINT-2.18 "PANGO_WEIGHT_BOOK" "PangoWeight") (CINT-2.18 "PANGO_WEIGHT_MEDIUM" "PangoWeight") ;;; 2.15.5 (CFNC-2.18 "gchar* gtk_window_get_default_icon_name void" 'const) ;;; 2.17.1 (CFNC-2.18 "gchar* gtk_label_get_current_uri GtkLabel* label" 'const) ;;; 2.17.2 (CCAST-2.18 "GTK_INFO_BAR(obj)" "GtkInfoBar*") (CCHK-2.18 "GTK_IS_INFO_BAR(obj)" "GtkInfoBar*") (CFNC-2.18 "GtkWidget* gtk_info_bar_new void") ;(CFNC-2.18 "GtkWidget* gtk_info_bar_new_with_buttons gchar* first_button_text ...") (CFNC-2.18 "GtkWidget* gtk_info_bar_get_action_area GtkInfoBar* info_bar") (CFNC-2.18 "GtkWidget* gtk_info_bar_get_content_area GtkInfoBar* info_bar") (CFNC-2.18 "void gtk_info_bar_add_action_widget GtkInfoBar* info_bar GtkWidget* child gint response_id") (CFNC-2.18 "GtkWidget* gtk_info_bar_add_button GtkInfoBar* info_bar gchar* button_text gint response_id") ;(CFNC-2.18 "void gtk_info_bar_add_buttons GtkInfoBar* info_bar gchar* first_button_text ...") (CFNC-2.18 "void gtk_info_bar_set_response_sensitive GtkInfoBar* info_bar gint response_id gboolean setting") ; const arg (CFNC-2.18 "void gtk_info_bar_set_default_response GtkInfoBar* info_bar gint response_id") (CFNC-2.18 "void gtk_info_bar_response GtkInfoBar* info_bar gint response_id") (CFNC-2.18 "void gtk_info_bar_set_message_type GtkInfoBar* info_bar GtkMessageType message_type") (CFNC-2.18 "GtkMessageType gtk_info_bar_get_message_type GtkInfoBar* info_bar") ;;; 2.17.3 (CINT-2.18 "GDK_WINDOW_OFFSCREEN" "GdkWindowType") ;;; (CFNC-2.18 "gboolean gdk_region_rect_equal GdkRegion* region GdkRectangle* rectangle" 'const) (CFNC-2.18 "gboolean gdk_window_ensure_native GdkWindow* window") (CFNC-2.18 "void gdk_window_get_root_coords GdkWindow* window gint x gint y gint* [root_x] gint* [root_y]") ;;; 2.91.0 (CFNC-2.18 "GdkPixmap* gdk_offscreen_window_get_pixmap GdkWindow* window") (CFNC-2.18 "void gdk_offscreen_window_set_embedder GdkWindow* window GdkWindow* embedder") (CFNC-2.18 "GdkWindow* gdk_offscreen_window_get_embedder GdkWindow* window") (CFNC-2.18 "void gdk_window_geometry_changed GdkWindow* window") (CFNC-2.18 "void gtk_menu_set_reserve_toggle_size GtkMenu* menu gboolean reserve_toggle_size") (CFNC-2.18 "gboolean gtk_menu_get_reserve_toggle_size GtkMenu* menu") ;;; 3.14.0 (CFNC-2.18 "void gtk_status_icon_set_title GtkStatusIcon* status_icon gchar* title") ;;; 3.14.0 (CFNC-2.18 "gchar* gtk_status_icon_get_title GtkStatusIcon* status_icon") ;;; 2.17.4 (CINT-2.18 "GTK_ENTRY_BUFFER_MAX_SIZE") ; maxushort in gtk_entry_buffer.h (gint) ;;; 2.91.6 (CLNG-2.18 "GTK_TYPE_ENTRY_BUFFER") (CCAST-2.18 "GTK_ENTRY_BUFFER(obj)" "GtkEntryBuffer*") (CCHK-2.18 "GTK_IS_ENTRY_BUFFER(obj)" "GtkEntryBuffer*") (CFNC-2.18 "GtkWidget* gtk_entry_new_with_buffer GtkEntryBuffer* buffer") (CFNC-2.18 "GtkEntryBuffer* gtk_entry_get_buffer GtkEntry* entry") (CFNC-2.18 "void gtk_entry_set_buffer GtkEntry* entry GtkEntryBuffer* buffer") (CFNC-2.18 "void gtk_label_set_track_visited_links GtkLabel* label gboolean track_links") (CFNC-2.18 "gboolean gtk_label_get_track_visited_links GtkLabel* label") (CFNC-2.18 "void gtk_print_operation_set_embed_page_setup GtkPrintOperation* op gboolean embed") (CFNC-2.18 "gboolean gtk_print_operation_get_embed_page_setup GtkPrintOperation* op") (CFNC-2.18 "GtkEntryBuffer* gtk_entry_buffer_new gchar* initial_chars gint n_initial_chars") (CFNC-2.18 "gsize gtk_entry_buffer_get_bytes GtkEntryBuffer* buffer") (CFNC-2.18 "guint gtk_entry_buffer_get_length GtkEntryBuffer* buffer") (CFNC-2.18 "gchar* gtk_entry_buffer_get_text GtkEntryBuffer* buffer" 'const) (CFNC-2.18 "void gtk_entry_buffer_set_text GtkEntryBuffer* buffer gchar* chars gint n_chars") (CFNC-2.18 "void gtk_entry_buffer_set_max_length GtkEntryBuffer* buffer guint max_length") (CFNC-2.18 "guint gtk_entry_buffer_get_max_length GtkEntryBuffer* buffer") (CFNC-2.18 "guint gtk_entry_buffer_insert_text GtkEntryBuffer* buffer guint position gchar* chars gint n_chars") (CFNC-2.18 "guint gtk_entry_buffer_delete_text GtkEntryBuffer* buffer guint position gint n_chars") (CFNC-2.18 "void gtk_entry_buffer_emit_inserted_text GtkEntryBuffer* buffer guint position gchar* chars guint n_chars") (CFNC-2.18 "void gtk_entry_buffer_emit_deleted_text GtkEntryBuffer* buffer guint position guint n_chars") ;;; 2.17.5 (CFNC-2.18 "void gtk_cell_renderer_set_alignment GtkCellRenderer* cell gfloat xalign gfloat yalign") (CFNC-2.18 "void gtk_cell_renderer_get_alignment GtkCellRenderer* cell gfloat* [xalign] gfloat* [yalign]") (CFNC-2.18 "void gtk_cell_renderer_set_padding GtkCellRenderer* cell gint xpad gint ypad") (CFNC-2.18 "void gtk_cell_renderer_get_padding GtkCellRenderer* cell gint* [xpad] gint* [ypad]") (CFNC-2.18 "void gtk_cell_renderer_set_visible GtkCellRenderer* cell gboolean visible") (CFNC-2.18 "gboolean gtk_cell_renderer_get_visible GtkCellRenderer* cell") (CFNC-2.18 "void gtk_cell_renderer_set_sensitive GtkCellRenderer* cell gboolean sensitive") (CFNC-2.18 "gboolean gtk_cell_renderer_get_sensitive GtkCellRenderer* cell") (CFNC-2.18 "gboolean gtk_cell_renderer_toggle_get_activatable GtkCellRendererToggle* toggle") (CFNC-2.18 "void gtk_cell_renderer_toggle_set_activatable GtkCellRendererToggle* toggle gboolean setting") (CFNC-2.18 "void gtk_widget_set_can_focus GtkWidget* widget gboolean can_focus") (CFNC-2.18 "gboolean gtk_widget_get_can_focus GtkWidget* widget") (CFNC-2.18 "gboolean gtk_widget_has_focus GtkWidget* widget") (CFNC-2.18 "void gtk_widget_set_can_default GtkWidget* widget gboolean can_default") (CFNC-2.18 "gboolean gtk_widget_get_can_default GtkWidget* widget") (CFNC-2.18 "gboolean gtk_widget_has_default GtkWidget* widget") ;;; (CFNC-2.18 "GtkStateType gtk_widget_get_state GtkWidget* widget") (CFNC-2.18 "gboolean gtk_widget_get_sensitive GtkWidget* widget") (CFNC-2.18 "gboolean gtk_widget_is_sensitive GtkWidget* widget") (CFNC-2.18 "void gtk_widget_set_has_window GtkWidget* widget gboolean has_window") (CFNC-2.18 "gboolean gtk_widget_get_has_window GtkWidget* widget") (CFNC-2.18 "gboolean gtk_widget_get_app_paintable GtkWidget* widget") ;;; 3.13.3 (CFNC-2.18 "gboolean gtk_widget_get_double_buffered GtkWidget* widget") ;;; 2.17.7 (CFNC-2.18 "GdkCursor* gdk_window_get_cursor GdkWindow* window") (CFNC-2.18 "void gtk_file_chooser_set_create_folders GtkFileChooser* chooser gboolean create_folders") (CFNC-2.18 "gboolean gtk_file_chooser_get_create_folders GtkFileChooser* chooser") (CFNC-2.18 "void gtk_icon_view_set_item_padding GtkIconView* icon_view gint item_padding") (CFNC-2.18 "gint gtk_icon_view_get_item_padding GtkIconView* icon_view") (CFNC-2.18 "gboolean gtk_widget_has_grab GtkWidget* widget") (CFNC-2.18 "void gtk_widget_set_visible GtkWidget* widget gboolean visible") (CFNC-2.18 "gboolean gtk_widget_get_visible GtkWidget* widget") ;(CFNC-2.18 "void gtk_widget_get_allocation GtkWidget* widget GtkAllocation* [allocation]") ; the struct arg is a problem for makexg.scm ;;; (CINT-2.18 "GTK_FILE_CHOOSER_PROP_CREATE_FOLDERS" "GtkFileChooserProp") ;;; 2.17.8 ;(CFNC-2.18 "void gtk_widget_set_allocation GtkWidget* widget GtkAllocation* allocation") ;;; 2.17.10 (CFNC-2.18 "void gtk_range_set_flippable GtkRange* range gboolean flippable") (CFNC-2.18 "gboolean gtk_range_get_flippable GtkRange* range") (CFNC-2.18 "gboolean gtk_widget_is_toplevel GtkWidget* widget") (CFNC-2.18 "gboolean gtk_widget_is_drawable GtkWidget* widget") (CFNC-2.18 "void gtk_widget_set_window GtkWidget* widget GdkWindow* window") ;;; 2.17.11 (CFNC-2.18 "gboolean gdk_window_is_destroyed GdkWindow* window") (CFNC-2.18 "void gdk_window_restack GdkWindow* window GdkWindow* sibling gboolean above") (CFNC-2.18 "void gtk_widget_set_receives_default GtkWidget* widget gboolean receives_default") (CFNC-2.18 "gboolean gtk_widget_get_receives_default GtkWidget* widget") ;;; 2.18.0 ;;; 3.13.3 (CFNC-2.18 "void gdk_window_flush GdkWindow* window") ;;; 2.19.0 (CFNC-2.20 "GtkWidget* gtk_dialog_get_widget_for_response GtkDialog* dialog gint response_id") ;;; (CFNC-2.20 "void gtk_tooltip_set_icon_from_gicon GtkTooltip* tooltip GIcon* gicon GtkIconSize size") (CFNC-2.20 "GdkWindow* gtk_viewport_get_bin_window GtkViewport* viewport") (CFNC-2.20 "GtkWidget* gtk_spinner_new void") (CFNC-2.20 "void gtk_spinner_start GtkSpinner* spinner") (CFNC-2.20 "void gtk_spinner_stop GtkSpinner* spinner") (CFNC-2.20 "GtkCellRenderer* gtk_cell_renderer_spinner_new void") ; surely they mean GtkCellRendererSpinner? (CCAST-2.20 "GTK_SPINNER(obj)" "GtkSpinner*") (CCHK-2.20 "GTK_IS_SPINNER(obj)" "GtkSpinner*") (CCAST-2.20 "GTK_CELL_RENDERER_SPINNER(obj)" "GtkCellRendererSpinner*") (CCHK-2.20 "GTK_IS_CELL_RENDERER_SPINNER(obj)" "GtkCellRendererSpinner*") ;;; 2.19.1 (CCAST-2.20 "GTK_TOOL_PALETTE(obj)" "GtkToolPalette*") (CCHK-2.20 "GTK_IS_TOOL_PALETTE(obj)" "GtkToolPalette*") (CCAST-2.20 "GTK_TOOL_ITEM_GROUP(obj)" "GtkToolItemGroup*") (CCHK-2.20 "GTK_IS_TOOL_ITEM_GROUP(obj)" "GtkToolItemGroup*") ;;; (CFNC-2.20 "void gtk_action_set_always_show_image GtkAction* action gboolean always_show") ;;; (CFNC-2.20 "gboolean gtk_action_get_always_show_image GtkAction* action") (CFNC-2.20 "GtkWidget* gtk_notebook_get_action_widget GtkNotebook* notebook GtkPackType pack_type") (CFNC-2.20 "void gtk_notebook_set_action_widget GtkNotebook* notebook GtkWidget* widget GtkPackType pack_type") (CFNC-2.20 "GtkWidget* gtk_statusbar_get_message_area GtkStatusbar* statusbar") (CFNC-2.20 "PangoEllipsizeMode gtk_tool_item_get_ellipsize_mode GtkToolItem* tool_item") (CFNC-2.20 "gfloat gtk_tool_item_get_text_alignment GtkToolItem* tool_item") (CFNC-2.20 "GtkOrientation gtk_tool_item_get_text_orientation GtkToolItem* tool_item") (CFNC-2.20 "GtkSizeGroup* gtk_tool_item_get_text_size_group GtkToolItem* tool_item") ;;; (CFNC-2.20 "GtkWindowType gtk_window_get_window_type GtkWindow* window") (CFNC-2.20 "GtkWidget* gtk_tool_palette_new void") (CFNC-2.20 "void gtk_tool_palette_set_group_position GtkToolPalette* palette GtkToolItemGroup* group gint position") ; these changed GtkWidget* to GtkToolItemGroup* (CFNC-2.20 "void gtk_tool_palette_set_exclusive GtkToolPalette* palette GtkToolItemGroup* group gboolean exclusive") (CFNC-2.20 "void gtk_tool_palette_set_expand GtkToolPalette* palette GtkToolItemGroup* group gboolean expand") (CFNC-2.20 "gint gtk_tool_palette_get_group_position GtkToolPalette* palette GtkToolItemGroup* group") (CFNC-2.20 "gboolean gtk_tool_palette_get_exclusive GtkToolPalette* palette GtkToolItemGroup* group") (CFNC-2.20 "gboolean gtk_tool_palette_get_expand GtkToolPalette* palette GtkToolItemGroup* group") ;;; (CFNC-2.20 "void gtk_tool_palette_set_icon_size GtkToolPalette* palette GtkIconSize icon_size") (CFNC-2.20 "void gtk_tool_palette_unset_icon_size GtkToolPalette* palette") (CFNC-2.20 "void gtk_tool_palette_set_style GtkToolPalette* palette GtkToolbarStyle style") (CFNC-2.20 "void gtk_tool_palette_unset_style GtkToolPalette* palette") ;;; (CFNC-2.20 "GtkIconSize gtk_tool_palette_get_icon_size GtkToolPalette* palette") (CFNC-2.20 "GtkToolbarStyle gtk_tool_palette_get_style GtkToolPalette* palette") (CFNC-2.20 "GtkToolItem* gtk_tool_palette_get_drop_item GtkToolPalette* palette gint x gint y") (CFNC-2.20 "GtkToolItemGroup* gtk_tool_palette_get_drop_group GtkToolPalette* palette gint x gint y") (CFNC-2.20 "GtkWidget* gtk_tool_palette_get_drag_item GtkToolPalette* palette GtkSelectionData* selection") (CFNC-2.20 "void gtk_tool_palette_set_drag_source GtkToolPalette* palette GtkToolPaletteDragTargets targets") (CFNC-2.20 "void gtk_tool_palette_add_drag_dest GtkToolPalette* palette GtkWidget* widget GtkDestDefaults flags GtkToolPaletteDragTargets targets GdkDragAction actions") ;;; 2.91.2 (CFNC-2.20 "GtkAdjustment* gtk_tool_palette_get_hadjustment GtkToolPalette* palette") ;;; 2.91.2 (CFNC-2.20 "GtkAdjustment* gtk_tool_palette_get_vadjustment GtkToolPalette* palette") (CFNC-2.20 "GtkTargetEntry* gtk_tool_palette_get_drag_target_item void" 'const-return) (CFNC-2.20 "GtkTargetEntry* gtk_tool_palette_get_drag_target_group void" 'const-return) (CFNC-2.20 "GtkWidget* gtk_tool_item_group_new gchar* label" 'const) (CFNC-2.20 "void gtk_tool_item_group_set_label GtkToolItemGroup* group gchar* label" 'const) (CFNC-2.20 "void gtk_tool_item_group_set_label_widget GtkToolItemGroup* group GtkWidget* label_widget") (CFNC-2.20 "void gtk_tool_item_group_set_collapsed GtkToolItemGroup* group gboolean collapsed") (CFNC-2.20 "void gtk_tool_item_group_set_ellipsize GtkToolItemGroup* group PangoEllipsizeMode ellipsize") (CFNC-2.20 "void gtk_tool_item_group_set_header_relief GtkToolItemGroup* group GtkReliefStyle style") (CFNC-2.20 "gchar* gtk_tool_item_group_get_label GtkToolItemGroup* group") (CFNC-2.20 "GtkWidget* gtk_tool_item_group_get_label_widget GtkToolItemGroup* group") (CFNC-2.20 "gboolean gtk_tool_item_group_get_collapsed GtkToolItemGroup* group") (CFNC-2.20 "PangoEllipsizeMode gtk_tool_item_group_get_ellipsize GtkToolItemGroup* group") (CFNC-2.20 "GtkReliefStyle gtk_tool_item_group_get_header_relief GtkToolItemGroup* group") (CFNC-2.20 "void gtk_tool_item_group_insert GtkToolItemGroup* group GtkToolItem* item gint position") (CFNC-2.20 "void gtk_tool_item_group_set_item_position GtkToolItemGroup* group GtkToolItem* item gint position") (CFNC-2.20 "gint gtk_tool_item_group_get_item_position GtkToolItemGroup* group GtkToolItem* item") (CFNC-2.20 "guint gtk_tool_item_group_get_n_items GtkToolItemGroup* group") (CFNC-2.20 "GtkToolItem* gtk_tool_item_group_get_nth_item GtkToolItemGroup* group guint index") (CFNC-2.20 "GtkToolItem* gtk_tool_item_group_get_drop_item GtkToolItemGroup* group gint x gint y") ;;; 2.19.2 ;; (CFNC-2.20 "gboolean gdk_keymap_map_virtual_modifiers GdkKeymap* keymap GdkModifierType *state") ;; there is no code for this! (CFNC-2.20 "gint gdk_screen_get_primary_monitor GdkScreen* screen") (CFNC-2.20 "void gtk_window_set_mnemonics_visible GtkWindow* window gboolean setting") (CFNC-2.20 "gboolean gtk_window_get_mnemonics_visible GtkWindow* window") ;;; 2.19.4 ;;; 2.91.2 (CFNC-2.20 "GdkWindow* gtk_entry_get_text_window GtkEntry* entry") ;;; 2.91.2 (CFNC-2.20 "GdkWindow* gtk_entry_get_icon_window GtkEntry* entry GtkEntryIconPosition icon_pos") (CFNC-2.20 "void gtk_range_set_slider_size_fixed GtkRange* range gboolean size_fixed") (CFNC-2.20 "gboolean gtk_range_get_slider_size_fixed GtkRange* range") (CFNC-2.20 "void gtk_range_set_min_slider_size GtkRange* range gboolean min_size") (CFNC-2.20 "gint gtk_range_get_min_slider_size GtkRange* range") (CFNC-2.20 "void gtk_range_get_range_rect GtkRange* range GdkRectangle* range_rect") (CFNC-2.20 "void gtk_range_get_slider_range GtkRange* range gint* [slider_start] gint* [slider_end]") ;;; 3.14.0 (CFNC-2.20 "void gtk_status_icon_set_name GtkStatusIcon* status_icon gchar* name") ; const gchar ;;; 2.91.6 (CFNC-2.20 "gboolean gtk_widget_has_rc_style GtkWidget* widget") ;;; 2.19.5 (CFNC-2.20 "GdkWindow* gtk_paned_get_handle_window GtkPaned* paned") ;;; 2.99.1 (CFNC-2.20 "void gtk_widget_style_attach GtkWidget* style") (CFNC-2.20 "void gtk_widget_set_realized GtkWidget* widget gboolean realized") (CFNC-2.20 "gboolean gtk_widget_get_realized GtkWidget* widget") (CFNC-2.20 "void gtk_widget_set_mapped GtkWidget* widget gboolean mapped") (CFNC-2.20 "gboolean gtk_widget_get_mapped GtkWidget* widget") ;;; 2.19.6 (CFNC-3.0 "void gdk_keymap_add_virtual_modifiers GdkKeymap* keymap GdkModifierType* state") ;(CFNC-3.0 "void gtk_widget_get_requisition GtkWidget* widget GtkRequisition* [requisition]") ;;; 2.21.0 (CFNC-3.0 "void gdk_window_coords_to_parent GdkWindow* window gdouble x gdouble y gdouble* [parent_x] gdouble* [parent_y]") (CFNC-3.0 "void gdk_window_coords_from_parent GdkWindow* window gdouble parent_x gdouble parent_y gdouble* [x] gdouble* [y]") (CFNC-3.0 "GdkWindow* gdk_window_get_effective_parent GdkWindow* window") (CFNC-3.0 "GdkWindow* gdk_window_get_effective_toplevel GdkWindow* window") (CFNC-3.0 "GtkWidget* gtk_accessible_get_widget GtkAccessible* accessible") ;;; 2.91.2 (CFNC-3.0 "GtkAdjustment* gtk_text_view_get_hadjustment GtkTextView* text_view") ;;; 2.91.2 (CFNC-3.0 "GtkAdjustment* gtk_text_view_get_vadjustment GtkTextView* text_view") (CFNC-3.0 "gboolean gtk_widget_send_focus_change GtkWidget* widget GdkEvent* event") ;;; 2.90.1 ;;; 2.99.0 (CFNC-3.0 "void gdk_display_get_device_state GdkDisplay* display GdkDevice* device GdkScreen** [screen] gint* [x] gint* [y] GdkModifierType* [mask]") ;;; 2.99.0 (CFNC-3.0 "GdkWindow* gdk_display_get_window_at_device_position GdkDisplay* display GdkDevice* device gint* [win_x] gint* [win_y]") ;;; 2.91.7 (CFNC-3.0 "void gdk_display_warp_device GdkDisplay* display GdkDevice* device GdkScreen* screen gint x gint y") (CFNC-3.0 "GdkDeviceManager* gdk_display_get_device_manager GdkDisplay* display") (CFNC-3.0 "void gdk_drag_context_set_device GdkDragContext* context GdkDevice* device") (CFNC-3.0 "GdkDevice* gdk_drag_context_get_device GdkDragContext* context") (CFNC-3.0 "GList* gdk_drag_context_list_targets GdkDragContext* context") (CFNC-3.0 "void gdk_event_set_device GdkEvent* event GdkDevice* device") (CFNC-3.0 "GdkDevice* gdk_event_get_device GdkEvent* event") (CFNC-3.0 "gboolean gdk_events_get_distance GdkEvent* event1 GdkEvent* event2 gdouble* [distance]") (CFNC-3.0 "gboolean gdk_events_get_angle GdkEvent* event1 GdkEvent* event2 gdouble* [angle]") (CFNC-3.0 "gboolean gdk_events_get_center GdkEvent* event1 GdkEvent* event2 gdouble* [x] gdouble* [y]") ;;; 2.90.6 (CFNC-3.0 "GdkVisual* gdk_image_get_visual GdkImage* image") ;;; 2.90.6 (CFNC-3.0 "GdkByteOrder gdk_image_get_byte_order GdkImage* image") ;;; 2.90.6 (CFNC-3.0 "gint gdk_image_get_width GdkImage* image") ;;; 2.90.6 (CFNC-3.0 "gint gdk_image_get_height GdkImage* image") ;;; 2.90.6 (CFNC-3.0 "guint16 gdk_image_get_depth GdkImage* image") ;;; 2.90.6 (CFNC-3.0 "guint16 gdk_image_get_bytes_per_pixel GdkImage* image") ;;; 2.90.6 (CFNC-3.0 "guint16 gdk_image_get_bytes_per_line GdkImage* image") ;;; 2.90.6 (CFNC-3.0 "guint16 gdk_image_get_bits_per_pixel GdkImage* image") (CFNC-3.0 "gboolean gdk_window_get_accept_focus GdkWindow* window") (CFNC-3.0 "gboolean gdk_window_get_focus_on_map GdkWindow* window") ;;; 3.15 (CFNC-3.0 "gboolean gdk_window_get_composited GdkWindow* window") (CFNC-3.0 "gboolean gdk_window_is_input_only GdkWindow* window") (CFNC-3.0 "gboolean gdk_window_is_shaped GdkWindow* window") (CFNC-3.0 "gboolean gdk_window_get_modal_hint GdkWindow* window") ;;; 2.90.6 (CFNC-3.0 "void gdk_window_get_background GdkWindow* window GdkColor* color") ;;; 2.90.6 (CFNC-3.0 "void gdk_window_get_back_pixmap GdkWindow* window GdkPixmap** [pixmap] gboolean* [parent_relative]") (CFNC-3.0 "void gdk_window_set_device_cursor GdkWindow* window GdkDevice* device GdkCursor* cursor") (CFNC-3.0 "GdkCursor* gdk_window_get_device_cursor GdkWindow* window GdkDevice* device") (CFNC-3.0 "GdkWindow* gdk_window_get_device_position GdkWindow* window GdkDevice* device gint* [x] gint* [y] GdkModifierType* [mask]") (CFNC-3.0 "void gdk_window_set_device_events GdkWindow* window GdkDevice* device GdkEventMask event_mask") (CFNC-3.0 "GdkEventMask gdk_window_get_device_events GdkWindow* window GdkDevice* device") (CFNC-3.0 "void gtk_combo_box_popup_for_device GtkComboBox* combo_box GdkDevice* device") (CFNC-3.0 "void gtk_device_grab_add GtkWidget* widget GdkDevice* device gboolean block_others") (CFNC-3.0 "void gtk_device_grab_remove GtkWidget* widget GdkDevice* device") (CFNC-3.0 "GdkDevice* gtk_get_current_event_device void") ;;; 2.90.1 (CFNC-3.0 "void gtk_menu_popup_for_device GtkMenu* menu GdkDevice* device GtkWidget* parent_menu_shell GtkWidget* parent_menu_item GtkMenuPositionFunc func lambda_data #func_info guint button guint32 activate_time") (CFNC-3.0 "GtkWidget* gtk_paned_new GtkOrientation orientation") ;;; (CFNC-3.0 "void gtk_radio_action_join_group GtkRadioAction* action GtkRadioAction* group_source") ;;; 2.91.5 (CFNC-3.0 "GtkWidget* gtk_ruler_new GtkOrientation orientation") (CFNC-3.0 "GtkWidget* gtk_scale_new GtkOrientation orientation GtkAdjustment* adjustment") (CFNC-3.0 "GtkWidget* gtk_scale_new_with_range GtkOrientation orientation gdouble min gdouble max gdouble step") (CFNC-3.0 "GtkWidget* gtk_scrollbar_new GtkOrientation orientation GtkAdjustment* adjustment") (CFNC-3.0 "GtkWidget* gtk_separator_new GtkOrientation orientation") (CFNC-3.0 "gboolean gtk_widget_device_is_shadowed GtkWidget* widget GdkDevice* device") (CFNC-3.0 "void gtk_widget_set_device_events GtkWidget* widget GdkDevice* device GdkEventMask events") (CFNC-3.0 "void gtk_widget_add_device_events GtkWidget* widget GdkDevice* device GdkEventMask events") (CFNC-3.0 "gboolean gtk_widget_get_support_multidevice GtkWidget* widget") (CFNC-3.0 "void gtk_widget_set_support_multidevice GtkWidget* widget gboolean support_multidevice") (CFNC-3.0 "GdkEventMask gtk_widget_get_device_events GtkWidget* widget GdkDevice* device") ;;; 2.91.0 (CINT-3.0 "GTK_MULTIDEVICE" "GtkWidgetFlags") ;;; 2.90.2 (CFNC-3.0 "gint gtk_icon_view_get_item_row GtkIconView* icon_view GtkTreePath* path") (CFNC-3.0 "gint gtk_icon_view_get_item_column GtkIconView* icon_view GtkTreePath* path") (CFNC-3.0 "void gtk_statusbar_remove_all GtkStatusbar* statusbar guint context_id") (CFNC-3.0 "gboolean gtk_window_has_group GtkWindow* window") ;;; 2.90.3 (CFNC-3.0 "void gtk_calendar_select_month GtkCalendar* calendar guint month guint year") (CFNC-3.0 "void gtk_calendar_mark_day GtkCalendar* calendar guint day") (CFNC-3.0 "void gtk_calendar_unmark_day GtkCalendar* calendar guint day") (CFNC-3.0 "GdkWindow* gdk_drag_context_get_source_window GdkDragContext* context") (CFNC-3.0 "GdkWindow* gtk_viewport_get_view_window GtkViewport* viewport") ;;; 2.90.4 ;;; 2.90.6 (CFNC-3.0 "gpointer gdk_image_get_pixels GdkImage* image") ;(CFNC-3.0 "GdkDevice* gdk_device_manager_get_client_pointer GdkDeviceManager* device_manager") (CFNC-3.0 "void gtk_accessible_set_widget GtkAccessible* accessible GtkWidget* widget") (CFNC-3.0 "GdkWindow* gtk_button_get_event_window GtkButton* button") ;;; 3.1.12 (CFNC-3.0 "GtkWidget* gtk_font_selection_dialog_get_font_selection GtkFontSelectionDialog* fsd") (CFNC-3.0 "GtkWidget* gtk_message_dialog_get_message_area GtkMessageDialog* message_dialog") ;;; 3.3.2 (CFNC-3.0 "void gtk_table_get_size GtkTable* table guint* [rows] guint* [columns]") (CINT-3.0 "GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH" "GtkSizeRequestMode") (CINT-3.0 "GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT" "GtkSizeRequestMode") (CFNC-3.0 "gint gtk_selection_data_get_length GtkSelectionData* selection_data") ;;; 2.90.5 removed all GdkRegion stuff ;;; (CFNC-3.0 "cairo_region_t* gdk_drawable_get_clip_region GdkDrawable* drawable") ;;; (CFNC-3.0 "cairo_region_t* gdk_drawable_get_visible_region GdkDrawable* drawable") ;;; 2.90.6 (CFNC-3.0 "void gdk_gc_set_clip_region GdkGC* gc cairo_region_t* region") (CFNC-3.0 "cairo_region_t* gdk_pango_layout_line_get_clip_region PangoLayoutLine* line gint x_origin gint y_origin gint* index_ranges gint n_ranges") (CFNC-3.0 "cairo_region_t* gdk_pango_layout_get_clip_region PangoLayout* layout gint x_origin gint y_origin gint* index_ranges gint n_ranges") (CFNC-3.0 "void gdk_window_shape_combine_region GdkWindow* window cairo_region_t* shape_region gint offset_x gint offset_y") (CFNC-3.0 "void gdk_window_invalidate_region GdkWindow* window cairo_region_t* region gboolean invalidate_children") ;(CFNC-3.0 "void gdk_window_invalidate_maybe_recurse GdkWindow* window cairo_region_t* region lambda2 func lambda_data #func_info") (CFNC-3.0 "cairo_region_t* gdk_window_get_update_area GdkWindow* window") (CFNC-3.0 "void gdk_window_begin_paint_region GdkWindow* window cairo_region_t* region") ;;; (CFNC-3.0 "cairo_region_t* gtk_widget_region_intersect GtkWidget* widget cairo_region_t* region") ; FREE (CFNC-3.0 "void gdk_window_move_region GdkWindow* window cairo_region_t* region gint dx gint dy") (CFNC-3.0 "gboolean gdk_keymap_get_num_lock_state GdkKeymap* keymap") (CFNC-3.0 "gboolean gdk_window_has_native GdkWindow* window") (CFNC-3.0 "GdkCursorType gdk_cursor_get_cursor_type GdkCursor* cursor") (CFNC-3.0 "gboolean gdk_display_is_closed GdkDisplay* display") (CFNC-3.0 "cairo_pattern_t* gdk_window_get_background_pattern GdkWindow* window") (CFNC-3.0 "cairo_surface_t* gdk_window_create_similar_surface GdkWindow* window cairo_content_t content int width int height") (CFNC-3.0 "void gtk_expander_set_label_fill GtkExpander* expander gboolean label_fill") (CFNC-3.0 "gboolean gtk_expander_get_label_fill GtkExpander* expander") ;;; (CFNC-3.0 "guint16 gtk_notebook_get_tab_hborder GtkNotebook* notebook") ;;; (CFNC-3.0 "guint16 gtk_notebook_get_tab_vborder GtkNotebook* notebook") ;;; 2.90.6: HAVE_GTK_EXPANDER_GET_LABEL_FILL ;;; 1.8.0: HAVE_CAIRO_GLYPH_ALLOCATE ;;; 1.9.12: HAVE_CAIRO_REGION_XOR (CAIRO-INT-810 "CAIRO_STATUS_FONT_TYPE_MISMATCH" "cairo_status_t") (CAIRO-INT-810 "CAIRO_STATUS_USER_FONT_IMMUTABLE" "cairo_status_t") (CAIRO-INT-810 "CAIRO_STATUS_USER_FONT_ERROR" "cairo_status_t") (CAIRO-INT-810 "CAIRO_STATUS_NEGATIVE_COUNT" "cairo_status_t") (CAIRO-INT-810 "CAIRO_STATUS_INVALID_CLUSTERS" "cairo_status_t") (CAIRO-INT-810 "CAIRO_STATUS_INVALID_SLANT" "cairo_status_t") (CAIRO-INT-810 "CAIRO_STATUS_INVALID_WEIGHT" "cairo_status_t") ;;; CAIRO_TEXT_CLUSTER_FLAG_BACKWARD = 0x00000001 (CAIRO-FUNC-810 "cairo_glyph_t* cairo_glyph_allocate int num_glyphs") (CAIRO-FUNC-810 "void cairo_glyph_free cairo_glyph_t* glyphs") (CAIRO-FUNC-810 "cairo_text_cluster_t* cairo_text_cluster_allocate int num_clusters") (CAIRO-FUNC-810 "void cairo_text_cluster_free cairo_text_cluster_t* clusters") (CAIRO-FUNC-810 "void cairo_show_text_glyphs cairo_t* cr char* utf8 int utf8_len cairo_glyph_t* glyphs int num_glyphs cairo_text_cluster_t* clusters int num_clusters cairo_text_cluster_flags_t cluster_flags" 'const) (CAIRO-FUNC-810 "cairo_status_t cairo_scaled_font_text_to_glyphs cairo_scaled_font_t* scaled_font double x double y char* utf8 int utf8_len cairo_glyph_t** glyphs int* num_glyphs cairo_text_cluster_t** clusters int* num_clusters cairo_text_cluster_flags_t* cluster_flags" 'const) (CAIRO-FUNC-810 "void cairo_scaled_font_get_scale_matrix cairo_scaled_font_t* scaled_font cairo_matrix_t* scale_matrix") (CAIRO-FUNC-810 "cairo_font_face_t* cairo_toy_font_face_create char* family cairo_font_slant_t slant cairo_font_weight_t weight" 'const) (CAIRO-FUNC-810 "char* cairo_toy_font_face_get_family cairo_font_face_t* font_face" 'const) ; return (CAIRO-FUNC-810 "cairo_font_slant_t cairo_toy_font_face_get_slant cairo_font_face_t* font_face") (CAIRO-FUNC-810 "cairo_font_weight_t cairo_toy_font_face_get_weight cairo_font_face_t* font_face") (CAIRO-FUNC-810 "cairo_font_face_t* cairo_user_font_face_create void") ;(CAIRO-FUNC-810 "void cairo_user_font_face_set_init_func cairo_font_face_t* font_face cairo_user_scaled_font_init_func_t init_func") ;(CAIRO-FUNC-810 "void cairo_user_font_face_set_render_glyph_func cairo_font_face_t* font_face cairo_user_scaled_font_render_glyph_func_t render_glyph_func") ;(CAIRO-FUNC-810 "void cairo_user_font_face_set_text_to_glyphs_func cairo_font_face_t* font_face cairo_user_scaled_font_text_to_glyphs_func_t text_to_glyphs_func") ;(CAIRO-FUNC-810 "void cairo_user_font_face_set_unicode_to_glyph_func cairo_font_face_t* font_face cairo_user_scaled_font_unicode_to_glyph_func_t unicode_to_glyph_func") ;(CAIRO-FUNC-810 "cairo_user_scaled_font_init_func_t cairo_user_font_face_get_init_func cairo_font_face_t* font_face") ;(CAIRO-FUNC-810 "cairo_user_scaled_font_render_glyph_func_t cairo_user_font_face_get_render_glyph_func cairo_font_face_t* font_face") ;(CAIRO-FUNC-810 "cairo_user_scaled_font_text_to_glyphs_func_t cairo_user_font_face_get_text_to_glyphs_func cairo_font_face_t* font_face") ;(CAIRO-FUNC-810 "cairo_user_scaled_font_unicode_to_glyph_func_t cairo_user_font_face_get_unicode_to_glyph_func cairo_font_face_t* font_face") (CAIRO-FUNC-810 "void cairo_surface_get_fallback_resolution cairo_surface_t* surface double* [x_pixels_per_inch] double* [y_pixels_per_inch]") (CAIRO-FUNC-810 "cairo_bool_t cairo_surface_has_show_text_glyphs cairo_surface_t* surface") ;;; 1.9 (CAIRO-INT-912 "CAIRO_STATUS_INVALID_SIZE" "cairo_status_t") (CAIRO-INT-912 "CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED" "cairo_status_t") (CAIRO-INT-912 "CAIRO_STATUS_DEVICE_TYPE_MISMATCH" "cairo_status_t") (CAIRO-INT-912 "CAIRO_STATUS_DEVICE_ERROR" "cairo_status_t") (CAIRO-INT-912 "CAIRO_OPERATOR_MULTIPLY" "cairo_operator_t") (CAIRO-INT-912 "CAIRO_OPERATOR_SCREEN" "cairo_operator_t") (CAIRO-INT-912 "CAIRO_OPERATOR_OVERLAY" "cairo_operator_t") (CAIRO-INT-912 "CAIRO_OPERATOR_DARKEN" "cairo_operator_t") (CAIRO-INT-912 "CAIRO_OPERATOR_LIGHTEN" "cairo_operator_t") (CAIRO-INT-912 "CAIRO_OPERATOR_COLOR_DODGE" "cairo_operator_t") (CAIRO-INT-912 "CAIRO_OPERATOR_COLOR_BURN" "cairo_operator_t") (CAIRO-INT-912 "CAIRO_OPERATOR_HARD_LIGHT" "cairo_operator_t") (CAIRO-INT-912 "CAIRO_OPERATOR_SOFT_LIGHT" "cairo_operator_t") (CAIRO-INT-912 "CAIRO_OPERATOR_DIFFERENCE" "cairo_operator_t") (CAIRO-INT-912 "CAIRO_OPERATOR_EXCLUSION" "cairo_operator_t") (CAIRO-INT-912 "CAIRO_OPERATOR_HSL_HUE" "cairo_operator_t") (CAIRO-INT-912 "CAIRO_OPERATOR_HSL_SATURATION" "cairo_operator_t") (CAIRO-INT-912 "CAIRO_OPERATOR_HSL_COLOR" "cairo_operator_t") (CAIRO-INT-912 "CAIRO_OPERATOR_HSL_LUMINOSITY" "cairo_operator_t") (CAIRO-INT-912 "CAIRO_SURFACE_TYPE_SCRIPT" "cairo_surface_t") (CAIRO-INT-912 "CAIRO_SURFACE_TYPE_QT" "cairo_surface_t") (CAIRO-INT-912 "CAIRO_SURFACE_TYPE_RECORDING" "cairo_surface_t") (CAIRO-INT-912 "CAIRO_SURFACE_TYPE_VG" "cairo_surface_t") (CAIRO-INT-912 "CAIRO_SURFACE_TYPE_GL" "cairo_surface_t") (CAIRO-INT-912 "CAIRO_SURFACE_TYPE_DRM" "cairo_surface_t") (CAIRO-INT-912 "CAIRO_SURFACE_TYPE_TEE" "cairo_surface_t") (CAIRO-INT-912 "CAIRO_SURFACE_TYPE_XML" "cairo_surface_t") (CAIRO-INT-912 "CAIRO_SURFACE_TYPE_SKIA" "cairo_surface_t") (CAIRO-STRING-912 "CAIRO_MIME_TYPE_JPEG") ; "image/jpeg") (CAIRO-STRING-912 "CAIRO_MIME_TYPE_PNG") ; "image/png") (CAIRO-STRING-912 "CAIRO_MIME_TYPE_JP2") ; "image/jp2") (CAIRO-STRING-912 "CAIRO_MIME_TYPE_URI") ; "text/x-uri") ;;; CAIRO_FORMAT_INVALID = -1 (CAIRO-FUNC-912 "cairo_bool_t cairo_in_clip cairo_t* cr double x double y") (CAIRO-FUNC-912 "cairo_device_t* cairo_device_reference cairo_device_t* device") (CAIRO-FUNC-912 "cairo_status_t cairo_device_status cairo_device_t* device") (CAIRO-FUNC-912 "cairo_status_t cairo_device_acquire cairo_device_t* device") (CAIRO-FUNC-912 "void cairo_device_release cairo_device_t* device") (CAIRO-FUNC-912 "void cairo_device_flush cairo_device_t* device") (CAIRO-FUNC-912 "void cairo_device_finish cairo_device_t* device") (CAIRO-FUNC-912 "void cairo_device_destroy cairo_device_t* device") (CAIRO-FUNC-912 "guint cairo_device_get_reference_count cairo_device_t* device") (CAIRO-FUNC-912 "void* cairo_device_get_user_data cairo_device_t* device cairo_user_data_key_t* key") (CAIRO-FUNC-912 "cairo_status_t cairo_device_set_user_data cairo_device_t* device cairo_user_data_key_t* key void* user_data cairo_destroy_func_t destroy") (CAIRO-FUNC-912 "cairo_surface_t* cairo_surface_create_for_rectangle cairo_surface_t* target double x double y double width double height") (CAIRO-FUNC-912 "cairo_device_t* cairo_surface_get_device cairo_surface_t* surface") ;;; stupid types (CAIRO-FUNC-912 "void cairo_surface_get_mime_data cairo_surface_t* surface char* mime_type guchar** [data] gulong* [length]" 'const) (CAIRO-FUNC-912 "cairo_status_t cairo_surface_set_mime_data cairo_surface_t* surface char* mime_type guchar* data gulong length cairo_destroy_func_t destroy void* closure" 'const) (CAIRO-FUNC-912 "cairo_surface_t* cairo_recording_surface_create cairo_content_t content cairo_rectangle_t* extents") (CAIRO-FUNC-912 "void cairo_recording_surface_ink_extents cairo_surface_t* surface double* x0 double* y0 double* width double* height") ;;; out in 1.10.0? ;;; (CAIRO-FUNC-912 "cairo_surface_t* cairo_tee_surface_create cairo_surface_t* master") ;;; (CAIRO-FUNC-912 "void cairo_tee_surface_add cairo_surface_t* surface cairo_surface_t* target") ;;; (CAIRO-FUNC-912 "void cairo_tee_surface_remove cairo_surface_t* surface cairo_surface_t* target") ;;; (CAIRO-FUNC-912 "cairo_surface_t* cairo_tee_surface_index cairo_surface_t* surface int index") (CAIRO-FUNC-912 "cairo_region_t* cairo_region_create void") (CAIRO-FUNC-912 "cairo_region_t* cairo_region_create_rectangle cairo_rectangle_int_t* rectangle") (CAIRO-FUNC-912 "cairo_region_t* cairo_region_create_rectangles cairo_rectangle_int_t* rects int count") (CAIRO-FUNC-912 "cairo_region_t* cairo_region_copy cairo_region_t* original") (CAIRO-FUNC-912 "cairo_region_t* cairo_region_reference cairo_region_t* region") (CAIRO-FUNC-912 "void cairo_region_destroy cairo_region_t* region") (CAIRO-FUNC-912 "cairo_bool_t cairo_region_equal cairo_region_t* a cairo_region_t* b") (CAIRO-FUNC-912 "cairo_status_t cairo_region_status cairo_region_t* region") (CAIRO-FUNC-912 "void cairo_region_get_extents cairo_region_t* region cairo_rectangle_int_t* extents") (CAIRO-FUNC-912 "int cairo_region_num_rectangles cairo_region_t* region") (CAIRO-FUNC-912 "void cairo_region_get_rectangle cairo_region_t* region int nth cairo_rectangle_int_t* rectangle") (CAIRO-FUNC-912 "cairo_bool_t cairo_region_is_empty cairo_region_t* region") (CAIRO-FUNC-912 "cairo_region_overlap_t cairo_region_contains_rectangle cairo_region_t* region cairo_rectangle_int_t* rectangle") (CAIRO-FUNC-912 "cairo_bool_t cairo_region_contains_point cairo_region_t* region int x int y") (CAIRO-FUNC-912 "void cairo_region_translate cairo_region_t* region int dx int dy") (CAIRO-FUNC-912 "cairo_status_t cairo_region_subtract cairo_region_t* dst cairo_region_t* other") (CAIRO-FUNC-912 "cairo_status_t cairo_region_subtract_rectangle cairo_region_t* dst cairo_rectangle_int_t* rectangle") (CAIRO-FUNC-912 "cairo_status_t cairo_region_intersect cairo_region_t* dst cairo_region_t* other") (CAIRO-FUNC-912 "cairo_status_t cairo_region_intersect_rectangle cairo_region_t* dst cairo_rectangle_int_t* rectangle") (CAIRO-FUNC-912 "cairo_status_t cairo_region_union cairo_region_t* dst cairo_region_t* other") (CAIRO-FUNC-912 "cairo_status_t cairo_region_union_rectangle cairo_region_t* dst cairo_rectangle_int_t* rectangle") (CAIRO-FUNC-912 "cairo_status_t cairo_region_xor cairo_region_t* dst cairo_region_t* other") (CAIRO-FUNC-912 "cairo_status_t cairo_region_xor_rectangle cairo_region_t* dst cairo_rectangle_int_t* rectangle") ;;; 2.91.1 (CINT-3.0 "GTK_WRAP_ALLOCATE_FREE" "GtkWrapAllocationMode") ;;; 2.91.1 (CINT-3.0 "GTK_WRAP_ALLOCATE_ALIGNED" "GtkWrapAllocationMode") ;;; 2.91.1 (CINT-3.0 "GTK_WRAP_ALLOCATE_HOMOGENEOUS" "GtkWrapAllocationMode") ;;; 2.91.1 (CINT-3.0 "GTK_WRAP_BOX_SPREAD_START" "GtkWrapBoxSpreading") ;;; 2.91.1 (CINT-3.0 "GTK_WRAP_BOX_SPREAD_END" "GtkWrapBoxSpreading") ;;; 2.91.1 (CINT-3.0 "GTK_WRAP_BOX_SPREAD_EVEN" "GtkWrapBoxSpreading") ;;; 2.91.1 (CINT-3.0 "GTK_WRAP_BOX_SPREAD_EXPAND" "GtkWrapBoxSpreading") ;;; 2.91.1 (CINT-3.0 "GTK_WRAP_BOX_H_EXPAND" "GtkWrapBoxPacking") ;;; 2.91.1 ;;; 2.91.0 (CINT-3.0 "GTK_WRAP_BOX_H_FILL" "GtkWrapBoxPacking") ;;; 2.91.1 (CINT-3.0 "GTK_WRAP_BOX_V_EXPAND" "GtkWrapBoxPacking") ;;; 2.91.1 ;;; 2.91.0 (CINT-3.0 "GTK_WRAP_BOX_V_FILL" "GtkWrapBoxPacking") (CFNC-3.0 "gboolean gtk_calendar_get_day_is_marked GtkCalendar* calendar guint day") ;;; 2.99.0 (CFNC-3.0 "void gtk_cell_view_get_desired_width_of_row GtkCellView* cell_view GtkTreePath* path gint* [minimum_size] gint* [natural_size]") ;;; 2.99.0 (CFNC-3.0 "void gtk_cell_view_get_desired_height_for_width_of_row GtkCellView* cell_view GtkTreePath* path gint avail_size gint* [minimum_size] gint* [natural_size]") (CFNC-3.0 "void gtk_progress_bar_set_inverted GtkProgressBar* pbar gboolean inverted") (CFNC-3.0 "gboolean gtk_progress_bar_get_inverted GtkProgressBar* pbar") (CFNC-3.0 "void gtk_radio_button_join_group GtkRadioButton* radio_button GtkRadioButton* group_source") ;;; 2.91.0 ;;; 2.91.1 (CCAST-3.0 "GTK_WRAP_BOX(obj)" "GtkWrapBox*") ;;; 2.91.1 (CCHK-3.0 "GTK_IS_WRAP_BOX(obj)" "GtkWrapBox*") (CFNC-3.0 "GtkAdjustment* gtk_adjustment_new gdouble value gdouble lower gdouble upper gdouble step_increment gdouble page_increment gdouble page_size") (CFNC-3.0 "gboolean gtk_binding_set_activate GtkBindingSet* binding_set guint keyval GdkModifierType modifiers GObject* object") (CFNC-3.0 "gboolean gtk_bindings_activate GObject* object guint keyval GdkModifierType modifiers") (CFNC-3.0 "cairo_surface_t* gtk_icon_view_create_drag_icon GtkIconView* icon_view GtkTreePath* path") ;;; 2.91.1 (CFNC-3.0 "void gtk_quit_add_destroy guint main_level GtkWidget* object") ;;; (CFNC-3.0 "cairo_surface_t* gdk_offscreen_window_get_pixmap GdkOffscreenWindow* window") ;;; 2.91.6 (CFNC-3.0 "void gtk_style_apply_default_background GtkStyle* style cairo_t* cr GdkWindow* window GtkStateType state_type gint x gint y gint width gint height") ;;; ;(CFNC-gtk2 "void gtk_paint_hline GtkStyle* style cairo_t* cr GtkStateType state_type GtkWidget* widget gchar* detail gint x1 gint x2 gint y") ;;; ;(CFNC-gtk2 "void gtk_paint_vline GtkStyle* style cairo_t* cr GtkStateType state_type GtkWidget* widget gchar* detail gint y1 gint y2 gint x") ;;; ;(CFNC-gtk2 "void gtk_paint_shadow GtkStyle* style cairo_t* cr GtkStateType state_type GtkShadowType shadow_type GtkWidget* widget gchar* detail gint x gint y gint width gint height") ;;; ;(CFNC-gtk2 "void gtk_paint_arrow GtkStyle* style cairo_t* cr GtkStateType state_type GtkShadowType shadow_type GtkWidget* widget gchar* detail GtkArrowType arrow_type gboolean fill gint x gint y gint width gint height") ;;; ;(CFNC-gtk2 "void gtk_paint_diamond GtkStyle* style cairo_t* cr GtkStateType state_type GtkShadowType shadow_type GtkWidget* widget gchar* detail gint x gint y gint width gint height") ;;; ;(CFNC-gtk2 "void gtk_paint_box GtkStyle* style cairo_t* cr GtkStateType state_type GtkShadowType shadow_type GtkWidget* widget gchar* detail gint x gint y gint width gint height") ;;; ;(CFNC-gtk2 "void gtk_paint_flat_box GtkStyle* style cairo_t* cr GtkStateType state_type GtkShadowType shadow_type GtkWidget* widget gchar* detail gint x gint y gint width gint height") ;;; ;(CFNC-gtk2 "void gtk_paint_check GtkStyle* style cairo_t* cr GtkStateType state_type GtkShadowType shadow_type GtkWidget* widget gchar* detail gint x gint y gint width gint height") ;;; ;(CFNC-gtk2 "void gtk_paint_option GtkStyle* style cairo_t* cr GtkStateType state_type GtkShadowType shadow_type GtkWidget* widget gchar* detail gint x gint y gint width gint height") ;;; ;(CFNC-gtk2 "void gtk_paint_tab GtkStyle* style cairo_t* cr GtkStateType state_type GtkShadowType shadow_type GtkWidget* widget gchar* detail gint x gint y gint width gint height") ;;; ;(CFNC-gtk2 "void gtk_paint_shadow_gap GtkStyle* style cairo_t* cr GtkStateType state_type GtkShadowType shadow_type GtkWidget* widget gchar* detail gint x gint y gint width gint height GtkPositionType gap_side gint gap_x gint gap_width") ;;; ;(CFNC-gtk2 "void gtk_paint_box_gap GtkStyle* style cairo_t* cr GtkStateType state_type GtkShadowType shadow_type GtkWidget* widget gchar* detail gint x gint y gint width gint height GtkPositionType gap_side gint gap_x gint gap_width") ;;; ;(CFNC-gtk2 "void gtk_paint_extension GtkStyle* style cairo_t* cr GtkStateType state_type GtkShadowType shadow_type GtkWidget* widget gchar* detail gint x gint y gint width gint height GtkPositionType gap_side") ;;; ;(CFNC-gtk2 "void gtk_paint_focus GtkStyle* style cairo_t* cr GtkStateType state_type GtkWidget* widget gchar* detail gint x gint y gint width gint height") ;;; ;(CFNC-gtk2 "void gtk_paint_slider GtkStyle* style cairo_t* cr GtkStateType state_type GtkShadowType shadow_type GtkWidget* widget gchar* detail gint x gint y gint width gint height GtkOrientation orientation") ;;; ;(CFNC-gtk2 "void gtk_paint_handle GtkStyle* style cairo_t* cr GtkStateType state_type GtkShadowType shadow_type GtkWidget* widget gchar* detail gint x gint y gint width gint height GtkOrientation orientation") ;;; ;(CFNC-gtk2 "void gtk_paint_expander GtkStyle* style cairo_t* cr GtkStateType state_type GtkWidget* widget gchar* detail gint x gint y GtkExpanderStyle expander_style") ;;; ;(CFNC-gtk2 "void gtk_paint_layout GtkStyle* style cairo_t* cr GtkStateType state_type gboolean use_text GtkWidget* widget gchar* detail gint x gint y PangoLayout* layout") ;;; ;(CFNC-gtk2 "void gtk_paint_resize_grip GtkStyle* style cairo_t* cr GtkStateType state_type GtkWidget* widget gchar* detail GdkWindowEdge edge gint x gint y gint width gint height") (CFNC-3.0 "cairo_surface_t* gtk_tree_view_create_row_drag_icon GtkTreeView* tree_view GtkTreePath* path") (CFNC-3.0 "gboolean gdk_cairo_get_clip_rectangle cairo_t* cr GdkRectangle* rect") (CFNC-3.0 "cairo_region_t* gdk_cairo_region_create_from_surface cairo_surface_t* surface") (CFNC-3.0 "GdkVisual* gdk_window_get_visual GdkWindow* window") (CFNC-3.0 "GdkScreen* gdk_window_get_screen GdkWindow* window") (CFNC-3.0 "GdkDisplay* gdk_window_get_display GdkWindow* window") (CFNC-3.0 "int gdk_window_get_width GdkWindow* window") (CFNC-3.0 "int gdk_window_get_height GdkWindow* window") (CFNC-3.0 "GtkSizeRequestMode gtk_cell_renderer_get_request_mode GtkCellRenderer* cell") (CFNC-3.0 "void gtk_cell_renderer_get_preferred_width GtkCellRenderer* cell GtkWidget* widget gint* [minimum_size] gint* [natural_size]") (CFNC-3.0 "void gtk_cell_renderer_get_preferred_height_for_width GtkCellRenderer* cell GtkWidget* widget gint width gint* [minimum_height] gint* [natural_height]") (CFNC-3.0 "void gtk_cell_renderer_get_preferred_height GtkCellRenderer* cell GtkWidget* widget gint* [minimum_size] gint* [natural_size]") (CFNC-3.0 "void gtk_cell_renderer_get_preferred_width_for_height GtkCellRenderer* cell GtkWidget* widget gint height gint* [minimum_width] gint* [natural_width]") ;(CFNC-3.0 "void gtk_cell_renderer_get_preferred_size GtkCellRenderer* cell GtkWidget* widget GtkRequisition* [minimum_size] GtkRequisition* [natural_size]") (CFNC-3.0 "void gtk_container_class_handle_border_width GtkContainerClass* klass") (CFNC-3.0 "void gtk_drag_set_icon_surface GdkDragContext* context cairo_surface_t* surface") (CFNC-3.0 "void gtk_notebook_set_group_name GtkNotebook* notebook gchar* group_name" 'const) (CFNC-3.0 "gchar* gtk_notebook_get_group_name GtkNotebook* notebook" 'const-return) (CFNC-3.0 "void gtk_widget_draw GtkWidget* widget cairo_t* cr") (CFNC-3.0 "GtkSizeRequestMode gtk_widget_get_request_mode GtkWidget* widget") (CFNC-3.0 "void gtk_widget_get_preferred_width GtkWidget* widget gint* [minimum_width] gint* [natural_width]") (CFNC-3.0 "void gtk_widget_get_preferred_height_for_width GtkWidget* widget gint width gint* [minimum_height] gint* [natural_height]") (CFNC-3.0 "void gtk_widget_get_preferred_height GtkWidget* widget gint* [minimum_height] gint* [natural_height]") (CFNC-3.0 "void gtk_widget_get_preferred_width_for_height GtkWidget* widget gint height gint* [minimum_width] gint* [natural_width]") ;(CFNC-3.0 "void gtk_widget_get_preferred_size GtkWidget* widget GtkRequisition* [minimum_size] GtkRequisition* [natural_size]") (CFNC-3.0 "int gtk_widget_get_allocated_width GtkWidget* widget") (CFNC-3.0 "int gtk_widget_get_allocated_height GtkWidget* widget") (CFNC-3.0 "void gtk_widget_set_visual GtkWidget* widget GdkVisual* visual") (CFNC-3.0 "GtkAlign gtk_widget_get_halign GtkWidget* widget") (CFNC-3.0 "void gtk_widget_set_halign GtkWidget* widget GtkAlign align") (CFNC-3.0 "GtkAlign gtk_widget_get_valign GtkWidget* widget") (CFNC-3.0 "void gtk_widget_set_valign GtkWidget* widget GtkAlign align") ;;; 3.12 (CFNC-3.0 "gint gtk_widget_get_margin_left GtkWidget* widget") ;;; 3.12 (CFNC-3.0 "void gtk_widget_set_margin_left GtkWidget* widget gint margin") ;;; 3.12 (CFNC-3.0 "gint gtk_widget_get_margin_right GtkWidget* widget") ;;; 3.12 (CFNC-3.0 "void gtk_widget_set_margin_right GtkWidget* widget gint margin") (CFNC-3.0 "gint gtk_widget_get_margin_top GtkWidget* widget") (CFNC-3.0 "void gtk_widget_set_margin_top GtkWidget* widget gint margin") (CFNC-3.0 "gint gtk_widget_get_margin_bottom GtkWidget* widget") (CFNC-3.0 "void gtk_widget_set_margin_bottom GtkWidget* widget gint margin") (CFNC-3.0 "void gtk_widget_shape_combine_region GtkWidget* widget cairo_region_t* region") (CFNC-3.0 "void gtk_widget_input_shape_combine_region GtkWidget* widget cairo_region_t* region") (CFNC-3.0 "gboolean gtk_cairo_should_draw_window cairo_t* cr GdkWindow* window") (CFNC-3.0 "void gtk_cairo_transform_to_window cairo_t* cr GtkWidget* widget GdkWindow* window") ;;; 2.91.1 (CFNC-3.0 "GtkWidget* gtk_wrap_box_new GtkWrapAllocationMode mode GtkWrapBoxSpreading horizontal_spreading GtkWrapBoxSpreading vertical_spreading guint horizontal_spacing guint vertical_spacing") ;;; 2.91.1 (CFNC-3.0 "void gtk_wrap_box_set_allocation_mode GtkWrapBox* box GtkWrapAllocationMode mode") ;;; 2.91.1 (CFNC-3.0 "GtkWrapAllocationMode gtk_wrap_box_get_allocation_mode GtkWrapBox* box") ;;; 2.91.1 (CFNC-3.0 "void gtk_wrap_box_set_horizontal_spreading GtkWrapBox* box GtkWrapBoxSpreading spreading") ;;; 2.91.1 (CFNC-3.0 "GtkWrapBoxSpreading gtk_wrap_box_get_horizontal_spreading GtkWrapBox* box") ;;; 2.91.1 (CFNC-3.0 "void gtk_wrap_box_set_vertical_spreading GtkWrapBox* box GtkWrapBoxSpreading spreading") ;;; 2.91.1 (CFNC-3.0 "GtkWrapBoxSpreading gtk_wrap_box_get_vertical_spreading GtkWrapBox* box") ;;; 2.91.1 (CFNC-3.0 "void gtk_wrap_box_set_vertical_spacing GtkWrapBox* box guint spacing") ;;; 2.91.1 (CFNC-3.0 "guint gtk_wrap_box_get_vertical_spacing GtkWrapBox* box") ;;; 2.91.1 (CFNC-3.0 "void gtk_wrap_box_set_horizontal_spacing GtkWrapBox* box guint spacing") ;;; 2.91.1 (CFNC-3.0 "guint gtk_wrap_box_get_horizontal_spacing GtkWrapBox* box") ;;; 2.91.1 (CFNC-3.0 "void gtk_wrap_box_set_minimum_line_children GtkWrapBox* box guint n_children") ;;; 2.91.1 (CFNC-3.0 "guint gtk_wrap_box_get_minimum_line_children GtkWrapBox* box") ;;; 2.91.1 (CFNC-3.0 "void gtk_wrap_box_set_natural_line_children GtkWrapBox* box guint n_children") ;;; 2.91.1 (CFNC-3.0 "guint gtk_wrap_box_get_natural_line_children GtkWrapBox* box") ;;; 2.91.1 (CFNC-3.0 "void gtk_wrap_box_insert_child GtkWrapBox* box GtkWidget* widget gint index GtkWrapBoxPacking packing") ;;; 2.91.1 (CFNC-3.0 "void gtk_wrap_box_reorder_child GtkWrapBox* box GtkWidget* widget guint index") (CFNC-3.0 "GtkWidget* gtk_combo_box_new_with_entry void") (CFNC-3.0 "gboolean gtk_combo_box_get_has_entry GtkComboBox* combo_box") (CFNC-3.0 "void gtk_combo_box_set_entry_text_column GtkComboBox* combo_box gint text_column") (CFNC-3.0 "gint gtk_combo_box_get_entry_text_column GtkComboBox* combo_box") (CFNC-3.0 "GtkTargetEntry* gtk_target_entry_new char* target guint flags guint info" 'const) (CFNC-3.0 "GtkTargetEntry* gtk_target_entry_copy GtkTargetEntry* data") (CFNC-3.0 "void gtk_target_entry_free GtkTargetEntry* data") (CFNC-3.0 "gboolean gtk_widget_get_hexpand GtkWidget* widget") (CFNC-3.0 "void gtk_widget_set_hexpand GtkWidget* widget gboolean expand") (CFNC-3.0 "gboolean gtk_widget_get_hexpand_set GtkWidget* widget") (CFNC-3.0 "void gtk_widget_set_hexpand_set GtkWidget* widget gboolean set") (CFNC-3.0 "gboolean gtk_widget_get_vexpand GtkWidget* widget") (CFNC-3.0 "void gtk_widget_set_vexpand GtkWidget* widget gboolean expand") (CFNC-3.0 "gboolean gtk_widget_get_vexpand_set GtkWidget* widget") (CFNC-3.0 "void gtk_widget_set_vexpand_set GtkWidget* widget gboolean set") (CFNC-3.0 "void gtk_widget_queue_compute_expand GtkWidget* widget") (CFNC-3.0 "gboolean gtk_widget_compute_expand GtkWidget* widget GtkOrientation orientation") (CFNC-3.0 "void gtk_window_set_default_geometry GtkWindow* window gint width gint height") (CFNC-3.0 "void gtk_window_resize_to_geometry GtkWindow* window gint width gint height") ;;; 3.13.4 (CFNC-3.0 "void gtk_window_set_has_resize_grip GtkWindow* window gboolean value") ;;; 3.13.4 (CFNC-3.0 "gboolean gtk_window_get_has_resize_grip GtkWindow* window") ;;; 3.13.4 (CFNC-3.0 "gboolean gtk_window_resize_grip_is_visible GtkWindow* window") ;;; 3.13.4 (CFNC-3.0 "gboolean gtk_window_get_resize_grip_area GtkWindow* window GdkRectangle* rect") (CCAST-3.0 "GTK_COMBO_BOX_TEXT(obj)" "GtkComboBoxText*") (CCHK-3.0 "GTK_IS_COMBO_BOX_TEXT(obj)" "GtkComboBoxText*") (CFNC-3.0 "GtkWidget* gtk_combo_box_text_new void") (CFNC-3.0 "GtkWidget* gtk_combo_box_text_new_with_entry void") (CFNC-3.0 "void gtk_combo_box_text_append_text GtkComboBoxText* combo_box gchar* text" 'const) (CFNC-3.0 "void gtk_combo_box_text_insert_text GtkComboBoxText* combo_box gint position gchar* text" 'const) (CFNC-3.0 "void gtk_combo_box_text_prepend_text GtkComboBoxText* combo_box gchar* text" 'const) (CFNC-3.0 "void gtk_combo_box_text_remove GtkComboBoxText* combo_box gint position") (CFNC-3.0 "gchar* gtk_combo_box_text_get_active_text GtkComboBoxText* combo_box") ;;; gtkapplication.h ;;; 2.91.2 (CCAST-3.0 "GTK_GRID(obj)" "GtkGrid*") (CCHK-3.0 "GTK_IS_GRID(obj)" "GtkGrid*") (CCAST-3.0 "GTK_SCROLLABLE(obj)" "GtkScrollable*") (CCHK-3.0 "GTK_IS_SCROLLABLE(obj)" "GtkScrollable*") (CCAST-3.0 "GDK_RGBA(object)" "GdkRGBA*") (CFNC-3.0 "void gdk_cairo_set_source_rgba cairo_t* cr GdkRGBA* rgba" 'const) (CFNC-3.0 "void gdk_window_set_background_rgba GdkWindow* window GdkRGBA* rgba") (CFNC-3.0 "void gtk_cell_view_set_background_rgba GtkCellView* cell_view GdkRGBA* rgba" 'const) ;;; 3.3.16 (CFNC-3.0 "GtkWidget* gtk_color_button_new_with_rgba GdkRGBA* rgba" 'const) ;;; 3.3.16 (CFNC-3.0 "void gtk_color_button_set_rgba GtkColorButton* color_button GdkRGBA* rgba" 'const) ;;; 3.3.16 ;(CFNC-3.0 "void gtk_color_button_get_rgba GtkColorButton* color_button GdkRGBA* [rgba]") ;;; 3.3.16 (CFNC-3.0 "void gtk_color_selection_set_current_rgba GtkColorSelection* colorsel GdkRGBA* rgba" 'const) ;;; 3.3.16 ;(CFNC-3.0 "void gtk_color_selection_get_current_rgba GtkColorSelection* colorsel GdkRGBA* [rgba]") ;;; 3.3.16 (CFNC-3.0 "void gtk_color_selection_set_previous_rgba GtkColorSelection* colorsel GdkRGBA* rgba" 'const) ;;; 3.3.16 ;(CFNC-3.0 "void gtk_color_selection_get_previous_rgba GtkColorSelection* colorsel GdkRGBA* [rgba]") (CFNC-3.0 "void gtk_combo_box_text_remove_all GtkComboBoxText* combo_box") (CFNC-3.0 "void gtk_combo_box_set_popup_fixed_width GtkComboBox* combo_box gboolean fixed") (CFNC-3.0 "gboolean gtk_combo_box_get_popup_fixed_width GtkComboBox* combo_box") ;(CFNC-3.0 "GAppInfo* gtk_recent_info_create_app_info GtkRecentInfo* info gchar* app_name GError** [error]" 'const) ;(CFNC-3.0 "GIcon* gtk_recent_info_get_gicon GtkRecentInfo* info") (CFNC-3.0 "gint gtk_scrolled_window_get_min_content_width GtkScrolledWindow* scrolled_window") (CFNC-3.0 "void gtk_scrolled_window_set_min_content_width GtkScrolledWindow* scrolled_window gint width") (CFNC-3.0 "gint gtk_scrolled_window_get_min_content_height GtkScrolledWindow* scrolled_window") (CFNC-3.0 "void gtk_scrolled_window_set_min_content_height GtkScrolledWindow* scrolled_window gint height") ;(CFNC-3.0 "void gtk_widget_queue_draw_region GtkWidget* widget cairo_region_t* [region]") (CFNC-3.0 "GtkWidget* gtk_grid_new void") (CFNC-3.0 "void gtk_grid_attach GtkGrid* grid GtkWidget* child gint left gint top gint width gint height") (CFNC-3.0 "void gtk_grid_attach_next_to GtkGrid* grid GtkWidget* child GtkWidget* sibling GtkPositionType side gint width gint height") (CFNC-3.0 "void gtk_grid_set_row_homogeneous GtkGrid* grid gboolean homogeneous") (CFNC-3.0 "gboolean gtk_grid_get_row_homogeneous GtkGrid* grid") (CFNC-3.0 "void gtk_grid_set_row_spacing GtkGrid* grid guint spacing") (CFNC-3.0 "guint gtk_grid_get_row_spacing GtkGrid* grid") (CFNC-3.0 "void gtk_grid_set_column_homogeneous GtkGrid* grid gboolean homogeneous") (CFNC-3.0 "gboolean gtk_grid_get_column_homogeneous GtkGrid* grid") (CFNC-3.0 "void gtk_grid_set_column_spacing GtkGrid* grid guint spacing") (CFNC-3.0 "guint gtk_grid_get_column_spacing GtkGrid* grid") (CFNC-3.0 "GtkAdjustment* gtk_scrollable_get_hadjustment GtkScrollable* scrollable") (CFNC-3.0 "void gtk_scrollable_set_hadjustment GtkScrollable* scrollable GtkAdjustment* hadjustment") (CFNC-3.0 "GtkAdjustment* gtk_scrollable_get_vadjustment GtkScrollable* scrollable") (CFNC-3.0 "void gtk_scrollable_set_vadjustment GtkScrollable* scrollable GtkAdjustment* vadjustment") ;;; (CAIRO-INT-110 "CAIRO_SURFACE_TYPE_SUBSURFACE" "cairo_surface_t") ;;; 2.91.3 (CINT-3.0 "GTK_ASSISTANT_PAGE_CUSTOM" "GtkAssistantPageType") (CINT-3.0 "GTK_TEXT_SEARCH_CASE_INSENSITIVE" "GtkTextSearchFlags") (CINT-3.0 "GTK_SCROLL_MINIMUM" "GtkScrollablePolicy") (CINT-3.0 "GTK_SCROLL_NATURAL" "GtkScrollablePolicy") (CFNC-3.0 "void gtk_assistant_next_page GtkAssistant* assistant") (CFNC-3.0 "void gtk_assistant_previous_page GtkAssistant* assistant") (CFNC-3.0 "GtkWidget* gtk_combo_box_new_with_model_and_entry GtkTreeModel* model") (CFNC-3.0 "GtkScrollablePolicy gtk_scrollable_get_hscroll_policy GtkScrollable* scrollable") (CFNC-3.0 "void gtk_scrollable_set_hscroll_policy GtkScrollable* scrollable GtkScrollablePolicy policy") (CFNC-3.0 "GtkScrollablePolicy gtk_scrollable_get_vscroll_policy GtkScrollable* scrollable") (CFNC-3.0 "void gtk_scrollable_set_vscroll_policy GtkScrollable* scrollable GtkScrollablePolicy policy") ;;; 2.91.5 (CCAST-3.0 "GTK_SWITCH(obj)" "GtkSwitch*") (CCHK-3.0 "GTK_IS_SWITCH(obj)" "GtkSwitch*") (CFNC-3.0 "GtkWidget* gtk_switch_new void") (CFNC-3.0 "void gtk_switch_set_active GtkSwitch* sw gboolean is_active") (CFNC-3.0 "gboolean gtk_switch_get_active GtkSwitch* sw") ;;; 2.91.6 ;;; a lot of this seems unnecessary -- also omitted the chooseapplication stuff and whatnot (CFNC-3.0 "cairo_region_t* gdk_window_get_clip_region GdkWindow* window") (CFNC-3.0 "cairo_region_t* gdk_window_get_visible_region GdkWindow* window") (CFNC-3.0 "GtkBorder* gtk_border_new void") (CFNC-3.0 "GtkBorder* gtk_border_copy GtkBorder* border_" 'const) (CFNC-3.0 "void gtk_border_free GtkBorder* border_") (CFNC-3.0 "gint gtk_combo_box_get_id_column GtkComboBox* combo_box") (CFNC-3.0 "void gtk_combo_box_set_id_column GtkComboBox* combo_box gint id_column") (CFNC-3.0 "gchar* gtk_combo_box_get_active_id GtkComboBox* combo_box" 'const) ;;; 3.1.4 changed type (CFNC-3.0 "void gtk_combo_box_set_active_id GtkComboBox* combo_box gchar* active_id" 'const) (CFNC-3.0 "void gtk_combo_box_text_insert GtkComboBoxText* combo_box gint position gchar* id gchar* text" 'const) (CFNC-3.0 "void gtk_combo_box_text_append GtkComboBoxText* combo_box gchar* id gchar* text" 'const) (CFNC-3.0 "void gtk_combo_box_text_prepend GtkComboBoxText* combo_box gchar* id gchar* text" 'const) ;; forgotten? (CFNC-3.0 "GtkWidget* gtk_button_box_new GtkOrientation orientation") (CFNC-3.0 "GtkWidget* gtk_box_new GtkOrientation orientation gint spacing") ; are these leftovers? ;(CCAST-3.0 "GTK_VOLUME_BUTTON" "GtkVolumeButton*") ;(CCHK-3.0 "GTK_IS_VOLUME_BUTTON" "GtkVolumeButton*") ;(CFNC-3.0 "GtkWidget* gtk_volume_button_new void") ;(CCAST-3.0 "GTK_SCALE_BUTTON" "GtkScaleButton*") ;(CCHK-3.0 "GTK_IS_SCALE_BUTTON" "GtkScaleButton*") ;;; ;(CFNC-3.0 "GtkWidget* gtk_scale_button_new GtkIconSize size gdouble min gdouble max gdouble step gchar** icons" 'const) ;(CFNC-3.0 "void gtk_scale_button_set_icons GtkScaleButton* button gchar** icons" 'const) ;(CFNC-3.0 "gdouble gtk_scale_button_get_value GtkScaleButton* button") ;(CFNC-3.0 "void gtk_scale_button_set_value GtkScaleButton* button gdouble value") ;(CFNC-3.0 "GtkAdjustment* gtk_scale_button_get_adjustment GtkScaleButton* button") ;(CFNC-3.0 "void gtk_scale_button_set_adjustment GtkScaleButton* button GtkAdjustment* adjustment") ;(CFNC-3.0 "GtkWidget* gtk_scale_button_get_plus_button GtkScaleButton* button") ;(CFNC-3.0 "GtkWidget* gtk_scale_button_get_minus_button GtkScaleButton* button") ;(CFNC-3.0 "GtkWidget* gtk_scale_button_get_popup GtkScaleButton* button") ;; message dialog depends completely on va lists ;;; (CCAST-3.0 "GTK_ACTIVATABLE" "GtkActivatable*") ;;; (CCHK-3.0 "GTK_IS_ACTIVATABLE" "GtkActivatable*") ;;; (CFNC-3.0 "void gtk_activatable_sync_action_properties GtkActivatable* activatable GtkAction* action") ;;; (CFNC-3.0 "void gtk_activatable_set_related_action GtkActivatable* activatable GtkAction* action") ;;; (CFNC-3.0 "GtkAction* gtk_activatable_get_related_action GtkActivatable* activatable") ;;; (CFNC-3.0 "void gtk_activatable_set_use_action_appearance GtkActivatable* activatable gboolean use_appearance") ;;; (CFNC-3.0 "gboolean gtk_activatable_get_use_action_appearance GtkActivatable* activatable") (CINT-3.0 "GTK_TARGET_SAME_APP" "GtkTargetFlags") (CINT-3.0 "GTK_TARGET_SAME_WIDGET" "GtkTargetFlags") (CINT-3.0 "GTK_TARGET_OTHER_APP" "GtkTargetFlags") (CINT-3.0 "GTK_TARGET_OTHER_WIDGET" "GtkTargetFlags") (CINT-3.0 "GTK_ALIGN_FILL" "GtkAlign") (CINT-3.0 "GTK_ALIGN_START" "GtkAlign") (CINT-3.0 "GTK_ALIGN_END" "GtkAlign") (CINT-3.0 "GTK_ALIGN_CENTER" "GtkAlign") ;;; 3.13.2 (CINT-3.0 "GTK_ARROW_NONE" "GtkArrowType") ;(CINT-3.0 "GTK_IM_PREEDIT_NOTHING" "GtkIMPreeditStyle") ;(CINT-3.0 "GTK_IM_PREEDIT_CALLBACK" "GtkIMPreeditStyle") ;(CINT-3.0 "GTK_IM_PREEDIT_NONE" "GtkIMPreeditStyle") ;(CINT-3.0 "GTK_IM_STATUS_NOTHING" "GtkIMStatusStyle") ;(CINT-3.0 "GTK_IM_STATUS_CALLBACK" "GtkIMStatusStyle") ;(CINT-3.0 "GTK_IM_STATUS_NONE" "GtkIMStatusStyle") ;; printer stuff ;(CINT-3.0 "GTK_PRINT_PAGES_ALL" "GtkPrintPages") ;(CINT-3.0 "GTK_PRINT_PAGES_CURRENT" "GtkPrintPages") ;(CINT-3.0 "GTK_PRINT_PAGES_RANGES" "GtkPrintPages") ;(CINT-3.0 "GTK_PRINT_PAGES_SELECTION" "GtkPrintPages") ;(CINT-3.0 "GTK_PAGE_SET_ALL" "GtkPageSet") ;(CINT-3.0 "GTK_PAGE_SET_EVEN" "GtkPageSet") ;(CINT-3.0 "GTK_PAGE_SET_ODD" "GtkPageSet") ;(CINT-3.0 "GTK_NUMBER_UP_LAYOUT_LEFT_TO_RIGHT_TOP_TO_BOTTOM" "GtkNumberUpLayout") ;(CINT-3.0 "GTK_NUMBER_UP_LAYOUT_LEFT_TO_RIGHT_BOTTOM_TO_TOP" "GtkNumberUpLayout") ;(CINT-3.0 "GTK_NUMBER_UP_LAYOUT_RIGHT_TO_LEFT_TOP_TO_BOTTOM" "GtkNumberUpLayout") ;(CINT-3.0 "GTK_NUMBER_UP_LAYOUT_RIGHT_TO_LEFT_BOTTOM_TO_TOP" "GtkNumberUpLayout") ;(CINT-3.0 "GTK_NUMBER_UP_LAYOUT_TOP_TO_BOTTOM_LEFT_TO_RIGHT" "GtkNumberUpLayout") ;(CINT-3.0 "GTK_NUMBER_UP_LAYOUT_TOP_TO_BOTTOM_RIGHT_TO_LEFT" "GtkNumberUpLayout") ;(CINT-3.0 "GTK_NUMBER_UP_LAYOUT_BOTTOM_TO_TOP_LEFT_TO_RIGHT" "GtkNumberUpLayout") ;(CINT-3.0 "GTK_NUMBER_UP_LAYOUT_BOTTOM_TO_TOP_RIGHT_TO_LEFT" "GtkNumberUpLayout") ;(CINT-3.0 "GTK_PAGE_ORIENTATION_PORTRAIT" "GtkPageOrientation") ;(CINT-3.0 "GTK_PAGE_ORIENTATION_LANDSCAPE" "GtkPageOrientation") ;(CINT-3.0 "GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT" "GtkPageOrientation") ;(CINT-3.0 "GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE" "GtkPageOrientation") ;(CINT-3.0 "GTK_PRINT_QUALITY_LOW" "GtkPrintQuality") ;(CINT-3.0 "GTK_PRINT_QUALITY_NORMAL" "GtkPrintQuality") ;(CINT-3.0 "GTK_PRINT_QUALITY_HIGH" "GtkPrintQuality") ;(CINT-3.0 "GTK_PRINT_QUALITY_DRAFT" "GtkPrintQuality") ;(CINT-3.0 "GTK_PRINT_DUPLEX_SIMPLEX" "GtkPrintDuplex") ;(CINT-3.0 "GTK_PRINT_DUPLEX_HORIZONTAL" "GtkPrintDuplex") ;(CINT-3.0 "GTK_PRINT_DUPLEX_VERTICAL" "GtkPrintDuplex") ;(CINT-3.0 "GTK_UNIT_PIXEL" "GtkUnit") ;(CINT-3.0 "GTK_UNIT_POINTS" "GtkUnit") ;(CINT-3.0 "GTK_UNIT_INCH" "GtkUnit") ;(CINT-3.0 "GTK_UNIT_MM" "GtkUnit") (CINT-3.0 "GTK_TOOL_PALETTE_DRAG_ITEMS" "GtkToolPaletteDragTargets") (CINT-3.0 "GTK_TOOL_PALETTE_DRAG_GROUPS" "GtkToolPaletteDragTargets") ;;; (CSTR-3.0 "GTK_STOCK_DIALOG_AUTHENTICATION") ;;; (CSTR-3.0 "GTK_STOCK_PAGE_SETUP") ;;; (CSTR-3.0 "GTK_STOCK_PRINT_ERROR") ;;; (CSTR-3.0 "GTK_STOCK_PRINT_PAUSED") ;;; (CSTR-3.0 "GTK_STOCK_PRINT_REPORT") ;;; (CSTR-3.0 "GTK_STOCK_PRINT_WARNING") (CFNC-3.0 "void gtk_tree_view_set_cursor_on_cell GtkTreeView* tree_view GtkTreePath* path GtkTreeViewColumn* focus_column GtkCellRenderer* focus_cell gboolean start_editing") (CFNC-3.0 "void gtk_tree_view_set_rubber_banding GtkTreeView* tree_view gboolean enable") (CFNC-3.0 "gboolean gtk_tree_view_get_rubber_banding GtkTreeView* tree_view") (CFNC-3.0 "void gtk_tooltip_set_markup GtkTooltip* tooltip gchar* markup" 'const) (CFNC-3.0 "void gtk_tooltip_set_icon GtkTooltip* tooltip GdkPixbuf* pixbuf") ;;; (CFNC-3.0 "void gtk_tooltip_set_icon_from_stock GtkTooltip* tooltip gchar* stock_id GtkIconSize size" 'const) (CFNC-3.0 "void gtk_tooltip_set_custom GtkTooltip* tooltip GtkWidget* custom_widget") (CFNC-3.0 "void gtk_tooltip_trigger_tooltip_query GdkDisplay* display") (CFNC-3.0 "void gtk_button_set_image_position GtkButton* button GtkPositionType position") (CFNC-3.0 "GtkPositionType gtk_button_get_image_position GtkButton* button") (CFNC-3.0 "gboolean gtk_show_uri GdkScreen* screen gchar* uri guint32 timestamp GError** [error]" 'const) (CFNC-3.0 "GtkTreeViewColumn* gtk_tree_view_column_new_with_area GtkCellArea* area") (CFNC-3.0 "GtkWidget* gtk_tree_view_column_get_button GtkTreeViewColumn* tree_column") (CFNC-3.0 "void gtk_tree_view_column_focus_cell GtkTreeViewColumn* tree_column GtkCellRenderer* cell") ;(CFNC-3.0 "AtkObject* gtk_combo_box_get_popup_accessible GtkComboBox* combo_box") ;(CFNC-3.0 "void gtk_clipboard_request_uris GtkClipboard* clipboard GtkClipboardURIReceivedFunc callback gpointer user_data") ;(CFNC-3.0 "gchar** gtk_clipboard_wait_for_uris GtkClipboard* clipboard") (CFNC-3.0 "gboolean gtk_clipboard_wait_is_uris_available GtkClipboard* clipboard") (CFNC-3.0 "void gtk_toolbar_set_drop_highlight_item GtkToolbar* toolbar GtkToolItem* tool_item gint index") (CFNC-3.0 "void gtk_tool_item_toolbar_reconfigured GtkToolItem* tool_item") (CCAST-3.0 "GTK_ORIENTABLE" "GtkOrientable*") (CCHK-3.0 "GTK_IS_ORIENTABLE" "GtkOrientable*") (CFNC-3.0 "void gtk_orientable_set_orientation GtkOrientable* orientable GtkOrientation orientation") (CFNC-3.0 "GtkOrientation gtk_orientable_get_orientation GtkOrientable* orientable") (CFNC-3.0 "void gtk_parse_args int* {argc} char*** |argv|") (CFNC-3.0 "guint gtk_get_major_version void" 'const-return) (CFNC-3.0 "guint gtk_get_minor_version void" 'const-return) (CFNC-3.0 "guint gtk_get_micro_version void" 'const-return) (CFNC-3.0 "guint gtk_get_binary_age void" 'const-return) (CFNC-3.0 "guint gtk_get_interface_age void" 'const-return) ;(CFNC-3.0 "GOptionGroup* gtk_get_option_group gboolean open_default_display") (CINT-3.0 "GTK_IMAGE_GICON" "GtkImageType") ;;; (CFNC-3.0 "GtkWidget* gtk_image_new_from_gicon GIcon* icon GtkIconSize size") ;;; (CFNC-3.0 "void gtk_image_set_from_gicon GtkImage* image GIcon* icon GtkIconSize size") ;;; (CFNC-3.0 "void gtk_image_get_gicon GtkImage* image GIcon** [gicon] GtkIconSize* [size]") (CFNC-3.0 "void gtk_progress_bar_set_show_text GtkProgressBar* pbar gboolean show_text") (CFNC-3.0 "gboolean gtk_progress_bar_get_show_text GtkProgressBar* pbar") (CFNC-3.0 "GtkWidget* gtk_invisible_new_for_screen GdkScreen* screen") (CFNC-3.0 "void gtk_invisible_set_screen GtkInvisible* invisible GdkScreen* screen") (CFNC-3.0 "GdkScreen* gtk_invisible_get_screen GtkInvisible* invisible") (CFNC-3.0 "GtkImageType gtk_entry_get_icon_storage_type GtkEntry* entry GtkEntryIconPosition icon_pos") (CFNC-3.0 "GdkPixbuf* gtk_entry_get_icon_pixbuf GtkEntry* entry GtkEntryIconPosition icon_pos") ;;; 3.9.8 (CFNC-3.0 "gchar* gtk_entry_get_icon_stock GtkEntry* entry GtkEntryIconPosition icon_pos" 'const-return) (CFNC-3.0 "GIcon* gtk_entry_get_icon_gicon GtkEntry* entry GtkEntryIconPosition icon_pos") ;(CFNC-3.0 "void gtk_entry_get_icon_area GtkEntry* entry GtkEntryIconPosition icon_pos GdkRectangle* [icon_area]") ;(CFNC-3.0 "void gtk_entry_get_text_area GtkEntry* entry GdkRectangle* [text_area]") ;(CFNC-3.0 "gboolean gtk_entry_im_context_filter_keypress GtkEntry* entry GdkEventKey* event") ;(CFNC-3.0 "void gtk_entry_reset_im_context GtkEntry* entry") (CFNC-3.0 "void gtk_container_propagate_draw GtkContainer* container GtkWidget* child cairo_t* cr") (CFNC-3.0 "void gtk_container_set_focus_chain GtkContainer* container GList* focusable_widgets") (CFNC-3.0 "gboolean gtk_container_get_focus_chain GtkContainer* container GList** [focusable_widgets]") (CFNC-3.0 "void gtk_container_unset_focus_chain GtkContainer* container") ;;; 3.13.2 (CFNC-3.0 "void gtk_container_set_reallocate_redraws GtkContainer* container gboolean needs_redraws") (CFNC-3.0 "void gtk_container_set_focus_child GtkContainer* container GtkWidget* child") (CFNC-3.0 "void gtk_container_set_focus_vadjustment GtkContainer* container GtkAdjustment* adjustment") (CFNC-3.0 "GtkAdjustment* gtk_container_get_focus_vadjustment GtkContainer* container") (CFNC-3.0 "void gtk_container_set_focus_hadjustment GtkContainer* container GtkAdjustment* adjustment") (CFNC-3.0 "GtkAdjustment* gtk_container_get_focus_hadjustment GtkContainer* container") ;;; 3.9.4 (CFNC-3.0 "void gtk_container_resize_children GtkContainer* container") (CFNC-3.0 "void gtk_assistant_commit GtkAssistant* assistant") ;;; (CFNC-3.0 "char* gtk_im_multicontext_get_context_id GtkIMMulticontext* context" 'const-return) ;;; (CFNC-3.0 "void gtk_im_multicontext_set_context_id GtkIMMulticontext* context char* context_id" 'const) (CINT-3.0 "GTK_FILE_CHOOSER_ERROR" "GtkFileChooserError") (CINT-3.0 "GTK_FILE_CHOOSER_ERROR_NONEXISTENT" "GtkFileChooserError") (CINT-3.0 "GTK_FILE_CHOOSER_ERROR_BAD_FILENAME" "GtkFileChooserError") (CINT-3.0 "GTK_FILE_CHOOSER_ERROR_ALREADY_EXISTS" "GtkFileChooserError") (CINT-3.0 "GTK_FILE_CHOOSER_ERROR_INCOMPLETE_HOSTNAME" "GtkFileChooserError") ;gtkfilechooser: gtk_file_chooser_error_quark ;(CFNC-3.0 "void gtk_about_dialog_set_license_type GtkAboutDialog* about GtkLicense license_type") ;(CFNC-3.0 "GtkLicense gtk_about_dialog_get_license_type GtkAboutDialog* about") ;;void gtk_show_about_dialog GtkWindow* parent gchar* first_property_name ...) ;(CINT-3.0 "GTK_LICENSE_UNKNOWN" "GtkLicense") ;(CINT-3.0 "GTK_LICENSE_CUSTOM" "GtkLicense") ;(CINT-3.0 "GTK_LICENSE_GPL_2_0" "GtkLicense") ;(CINT-3.0 "GTK_LICENSE_GPL_3_0" "GtkLicense") ;(CINT-3.0 "GTK_LICENSE_LGPL_2_1" "GtkLicense") ;(CINT-3.0 "GTK_LICENSE_LGPL_3_0" "GtkLicense") ;(CINT-3.0 "GTK_LICENSE_BSD" "GtkLicense") ;(CINT-3.0 "GTK_LICENSE_MIT_X11" "GtkLicense") ;(CINT-3.0 "GTK_LICENSE_ARTISTIC" "GtkLicense") (CFNC-3.0 "void gtk_window_set_skip_taskbar_hint GtkWindow* window gboolean setting") (CFNC-3.0 "gboolean gtk_window_get_skip_taskbar_hint GtkWindow* window") (CFNC-3.0 "void gtk_window_set_skip_pager_hint GtkWindow* window gboolean setting") (CFNC-3.0 "gboolean gtk_window_get_skip_pager_hint GtkWindow* window") (CFNC-3.0 "void gtk_window_set_screen GtkWindow* window GdkScreen* screen") (CFNC-3.0 "GdkScreen* gtk_window_get_screen GtkWindow* window") (CFNC-3.0 "gboolean gtk_window_set_icon_from_file GtkWindow* window gchar* filename GError** [err]" 'const) (CFNC-3.0 "gboolean gtk_window_set_default_icon_from_file gchar* filename GError** [err]" 'const) (CFNC-3.0 "void gtk_window_fullscreen GtkWindow* window") (CFNC-3.0 "void gtk_window_unfullscreen GtkWindow* window") (CFNC-3.0 "GtkWindowType gtk_window_get_window_type GtkWindow* window") ;GtkApplication *gtk_window_get_application GtkWindow* window) ;void gtk_window_set_application GtkWindow* window GtkApplication* application) (CCAST-3.0 "GTK_WINDOW_GROUP(object)" "GtkWindowGroup*") (CCHK-3.0 "GTK_IS_WINDOW_GROUP(object)" "GtkWindowGroup*") (CFNC-3.0 "void gtk_window_group_add_window GtkWindowGroup* window_group GtkWindow* window") (CFNC-3.0 "void gtk_window_group_remove_window GtkWindowGroup* window_group GtkWindow* window") (CFNC-3.0 "GtkWindowGroup* gtk_window_group_new void") (CFNC-3.0 "GtkWindowGroup* gtk_window_get_group GtkWindow* window") (CFNC-3.0 "GList* gtk_window_group_list_windows GtkWindowGroup* window_group") (CFNC-3.0 "GtkWidget* gtk_window_group_get_current_device_grab GtkWindowGroup* window_group GdkDevice* device") ;;;;(CFNC "GType gtk_window_group_get_type void") (CFNC-3.0 "GtkWidget* gtk_window_group_get_current_grab GtkWindowGroup* window_group") ;gtkrecentchooserdialog: gtk_recent_chooser_dialog_new -- these 2 use property lists ;gtkrecentchooserdialog: gtk_recent_chooser_dialog_new_for_manager (CFNC-3.0 "guchar* gtk_selection_data_get_data GtkSelectionData* selection_data" 'const) (CFNC-3.0 "gboolean gtk_selection_owner_set_for_display GdkDisplay* display GtkWidget* widget GdkAtom selection guint32 time") (CCAST-3.0 "GTK_TOOL_SHELL" "GtkToolShell*") (CCHK-3.0 "GTK_IS_TOOL_SHELL" "GtkToolShell*") (CFNC-3.0 "GtkOrientation gtk_tool_shell_get_text_orientation GtkToolShell* shell") (CFNC-3.0 "gfloat gtk_tool_shell_get_text_alignment GtkToolShell* shell") (CFNC-3.0 "PangoEllipsizeMode gtk_tool_shell_get_ellipsize_mode GtkToolShell* shell") (CFNC-3.0 "GtkSizeGroup* gtk_tool_shell_get_text_size_group GtkToolShell* shell") ;;; (CFNC-3.0 "GtkIconSize gtk_tool_shell_get_icon_size GtkToolShell* shell") (CFNC-3.0 "GtkOrientation gtk_tool_shell_get_orientation GtkToolShell* shell") (CFNC-3.0 "GtkToolbarStyle gtk_tool_shell_get_style GtkToolShell* shell") (CFNC-3.0 "GtkReliefStyle gtk_tool_shell_get_relief_style GtkToolShell* shell") (CFNC-3.0 "void gtk_tool_shell_rebuild_menu GtkToolShell* shell") ;;; 3.14.0 (CFNC-3.0 "GtkStatusIcon* gtk_status_icon_new_from_gicon GIcon* icon") ;;; 3.14.0 (CFNC-3.0 "void gtk_status_icon_set_from_gicon GtkStatusIcon* status_icon GIcon* icon") ;;; 3.14.0 (CFNC-3.0 "GIcon* gtk_status_icon_get_gicon GtkStatusIcon* status_icon") ;;; 3.14.0 (CFNC-3.0 "void gtk_status_icon_set_has_tooltip GtkStatusIcon* status_icon gboolean has_tooltip") ;;; 3.14.0 (CFNC-3.0 "void gtk_status_icon_set_tooltip_text GtkStatusIcon* status_icon gchar* text" 'const) ;;; 3.14.0 (CFNC-3.0 "void gtk_status_icon_set_tooltip_markup GtkStatusIcon* status_icon gchar* markup" 'const) ;;; 3.14.0 (CFNC-3.0 "gboolean gtk_status_icon_get_has_tooltip GtkStatusIcon* status_icon") ;;; 3.14.0 (CFNC-3.0 "gchar* gtk_status_icon_get_tooltip_text GtkStatusIcon* status_icon") ;;; 3.14.0 (CFNC-3.0 "gchar* gtk_status_icon_get_tooltip_markup GtkStatusIcon* status_icon") (CFNC-3.0 "void gtk_accel_map_lock_path gchar* accel_path" 'const) (CFNC-3.0 "void gtk_accel_map_unlock_path gchar* accel_path" 'const) ;;; ;(CFNC-3.0 "gboolean gtk_icon_size_lookup_for_settings GtkSettings* settings GtkIconSize size gint* [width] gint* [height]") ; most of the GtkSettings funcs have been removed above and docs say this func isn't needed (CINT-3.0 "GTK_ICON_LOOKUP_FORCE_SIZE" "GtkIconLookupFlags") (CINT-3.0 "GTK_ICON_THEME_NOT_FOUND" "GtkIconThemeError") (CINT-3.0 "GTK_ICON_THEME_FAILED" "GtkIconThemeError") ;gtkicontheme: gtk_icon_theme_choose_icon -- ref array? ;gtkicontheme: gtk_icon_info_load_symbolic ;gtkicontheme: gtk_icon_info_load_symbolic_for_context (CFNC-3.0 "GtkIconInfo* gtk_icon_theme_lookup_by_gicon GtkIconTheme* icon_theme GIcon* icon gint size GtkIconLookupFlags flags") (CFNC-3.0 "GtkIconInfo* gtk_icon_info_new_for_pixbuf GtkIconTheme* icon_theme GdkPixbuf* pixbuf") ;;; 2.99.3 ;gtkplug: gtk_plug_construct_for_display -- GdkNativeWindow ;;; 2.99.3 ;gtkplug: gtk_plug_new_for_display (CFNC-3.0 "void gtk_icon_view_set_item_orientation GtkIconView* icon_view GtkOrientation orientation") (CFNC-3.0 "GtkOrientation gtk_icon_view_get_item_orientation GtkIconView* icon_view") (CFNC-3.0 "gboolean gtk_text_view_im_context_filter_keypress GtkTextView* text_view GdkEventKey* event") (CFNC-3.0 "void gtk_text_view_reset_im_context GtkTextView* text_view") ;(CFNC-3.0 "void gtk_text_layout_draw GtkTextLayout* layout GtkWidget* widget cairo_t* cr GList** widgets") ;;; (CFNC-3.0 "gchar* gtk_action_get_accel_path GtkAction* action" 'const-return) ;;; (CFNC-3.0 "void gtk_action_block_activate GtkAction* action") ;;; (CFNC-3.0 "void gtk_action_unblock_activate GtkAction* action") ;;; (CFNC-3.0 "void gtk_action_set_accel_path GtkAction* action gchar* accel_path" 'const) ;;; (CFNC-3.0 "void gtk_action_set_accel_group GtkAction* action GtkAccelGroup* accel_group") ;;; 2.99.0 (CFNC-3.0 "void gdk_device_get_position GdkDevice* device GdkScreen** screen gint* [x] gint* [y]") (CFNC-3.0 "GdkWindow* gdk_device_get_window_at_position GdkDevice* device gint* [win_x] gint* [win_y]") (CFNC-3.0 "gboolean gtk_cell_view_get_draw_sensitive GtkCellView* cell_view") (CFNC-3.0 "void gtk_cell_view_set_draw_sensitive GtkCellView* cell_view gboolean draw_sensitive") (CFNC-3.0 "gboolean gtk_cell_view_get_fit_model GtkCellView* cell_view") (CFNC-3.0 "void gtk_cell_view_set_fit_model GtkCellView* cell_view gboolean fit_model") (CFNC-3.0 "GtkWidget* gtk_combo_box_new_with_area GtkCellArea* area") (CFNC-3.0 "GtkWidget* gtk_combo_box_new_with_area_and_entry GtkCellArea* area") (CFNC-3.0 "GtkWidget* gtk_icon_view_new_with_area GtkCellArea* area") (CFNC-3.0 "void gtk_menu_item_set_reserve_indicator GtkMenuItem* menu_item gboolean reserve") (CFNC-3.0 "gboolean gtk_menu_item_get_reserve_indicator GtkMenuItem* menu_item") (CFNC-3.0 "GtkWidget* gtk_menu_shell_get_selected_item GtkMenuShell* menu_shell") (CFNC-3.0 "GtkWidget* gtk_menu_shell_get_parent_shell GtkMenuShell* menu_shell") (CFNC-3.0 "guchar* gtk_selection_data_get_data_with_length GtkSelectionData* selection_data gint* [length]" 'const) (CFNC-3.0 "gboolean gtk_tree_model_iter_previous GtkTreeModel* tree_model GtkTreeIter* iter") (CSTR-3.0 "GTK_STYLE_CLASS_HIGHLIGHT") (CSTR-3.0 "GTK_STYLE_CLASS_FRAME") (CSTR-3.0 "GTK_STYLE_CLASS_DND") ;;; 2.99.1 (CSTR-3.0 "GTK_STYLE_CLASS_HORIZONTAL") (CSTR-3.0 "GTK_STYLE_CLASS_VERTICAL") (CFNC-3.0 "gboolean gtk_tree_view_is_blank_at_pos GtkTreeView* tree_view gint x gint y GtkTreePath** [path] GtkTreeViewColumn** [column] gint* [cell_x] gint* [cell_y]") (CFNC-3.0 "void gtk_widget_set_device_enabled GtkWidget* widget GdkDevice* device gboolean enabled") (CFNC-3.0 "gboolean gtk_widget_get_device_enabled GtkWidget* widget GdkDevice* device") (CFNC-3.0 "void gtk_window_set_has_user_ref_count GtkWindow* window gboolean setting") ;;; 2.99.2 -- no changes for xgdata I think ;;; 2.99.3 (CFNC-3.0 "void gdk_selection_send_notify GdkWindow* requestor GdkAtom selection GdkAtom target GdkAtom property guint32 time_") (CFNC-3.0 "void gdk_selection_send_notify_for_display GdkDisplay* display GdkWindow* requestor GdkAtom selection GdkAtom target GdkAtom property guint32 time_") ;(CFNC-3.0 "void gtk_text_view_get_cursor_locations GtkTextView* text_view GtkTextIter* iter GdkRectangle* [strong] GdkRectangle* [weak]") (CFNC-3.0 "GdkRGBA* gdk_rgba_copy GdkRGBA* rgba" 'const) (CFNC-3.0 "void gdk_rgba_free GdkRGBA* rgba") (CFNC-3.0 "gboolean gdk_rgba_parse GdkRGBA* rgba gchar* spec" 'const) (CFNC-3.0 "gchar* gdk_rgba_to_string GdkRGBA* rgba" 'const) ;(STRUCT-3.0-make "GdkRGBA") (CINT-3.0 "GTK_STATE_FLAG_NORMAL" "GtkStateFlags") (CINT-3.0 "GTK_STATE_FLAG_ACTIVE" "GtkStateFlags") (CINT-3.0 "GTK_STATE_FLAG_PRELIGHT" "GtkStateFlags") (CINT-3.0 "GTK_STATE_FLAG_SELECTED" "GtkStateFlags") (CINT-3.0 "GTK_STATE_FLAG_INSENSITIVE" "GtkStateFlags") (CINT-3.0 "GTK_STATE_FLAG_INCONSISTENT" "GtkStateFlags") (CINT-3.0 "GTK_STATE_FLAG_FOCUSED" "GtkStateFlags") (CFNC-3.0 "void gtk_widget_set_state_flags GtkWidget* widget GtkStateFlags flags gboolean clear") (CFNC-3.0 "void gtk_widget_unset_state_flags GtkWidget* widget GtkStateFlags flags") (CFNC-3.0 "GtkStateFlags gtk_widget_get_state_flags GtkWidget* widget") ;;; 3.15 (CFNC-3.0 "void gtk_widget_override_color GtkWidget* widget GtkStateFlags state GdkRGBA* color" 'const) ;;; 3.15 (CFNC-3.0 "void gtk_widget_override_background_color GtkWidget* widget GtkStateFlags state GdkRGBA* color" 'const) ;;; 3.15 (CFNC-3.0 "void gtk_widget_override_font GtkWidget* widget PangoFontDescription* font_desc" 'const) ;;; 3.7.4 (CFNC-3.0 "void gtk_widget_override_symbolic_color GtkWidget* widget gchar* name GdkRGBA* color" 'const) ;;; 3.15 (CFNC-3.0 "void gtk_widget_override_cursor GtkWidget* widget GdkRGBA* cursor GdkRGBA* secondary_cursor" 'const) ;;; 3.1.2 (CINT-3.2 "GTK_SIZE_REQUEST_CONSTANT_SIZE" "GtkSizeRequestMode") ;(CINT-3.2 "GDK_RENDERING_MODE_SIMILAR" "GdkRenderingMode") ;(CINT-3.2 "GDK_RENDERING_MODE_IMAGE" "GdkRenderingMode") ;(CINT-3.2 "GDK_RENDERING_MODE_RECORDING" "GdkRenderingMode") (CFNC-3.2 "gchar* gtk_entry_get_placeholder_text GtkEntry* entry" 'const) (CFNC-3.2 "void gtk_entry_set_placeholder_text GtkEntry* entry gchar* text" 'const) (CFNC-3.2 "void gtk_expander_set_resize_toplevel GtkExpander* expander gboolean resize_toplevel") (CFNC-3.2 "gboolean gtk_expander_get_resize_toplevel GtkExpander* expander") ;(CFNC-3.2 "void gtk_widget_queue_draw_region GtkWidget* widget cairo_region_t* [region]" 'const) (CFNC-3.2 "char* gtk_widget_path_to_string GtkWidgetPath* path" 'const) ;;; 3.1.4 (CFNC-3.2 "gboolean gtk_button_box_get_child_non_homogeneous GtkButtonBox* widget GtkWidget* child") (CFNC-3.2 "void gtk_button_box_set_child_non_homogeneous GtkButtonBox* widget GtkWidget* child gboolean non_homogeneous") (CFNC-3.2 "void gtk_container_child_notify GtkContainer* container GtkWidget* child gchar* property_name" 'const) (CFNC-3.2 "void gtk_drag_source_set_icon_gicon GtkWidget* widget GIcon* icon") (CFNC-3.2 "void gtk_drag_set_icon_gicon GdkDragContext* context GIcon* icon gint hot_x gint hot_y") (CFNC-3.2 "gboolean gtk_combo_box_set_active_id GtkComboBox* combo_box gchar* active_id" 'const) ;;; 3.1.6 ;(CFNC-3.2 "char* gtk_css_provider_to_string GtkCssProvider* provider") ;;; 3.7.4 (CFNC-3.2 "GtkGradient* gtk_gradient_new_linear gdouble x0 gdouble y0 gdouble x1 gdouble y1") ;;; 3.7.4 (CFNC-3.2 "GtkGradient* gtk_gradient_new_radial gdouble x0 gdouble y0 gdouble radius0 gdouble x1 gdouble y1 gdouble radius1") ;;; 3.7.4 (CFNC-3.2 "void gtk_gradient_add_color_stop GtkGradient* gradient gdouble offset GtkSymbolicColor* color") ;;; 3.7.4 (CFNC-3.2 "GtkGradient* gtk_gradient_ref GtkGradient* gradient") ;;; 3.7.4 (CFNC-3.2 "void gtk_gradient_unref GtkGradient* gradient") ;;; 3.7.4 (CFNC-3.2 "gboolean gtk_gradient_resolve GtkGradient* gradient GtkStyleProperties* props cairo_pattern_t** resolved_gradient") ;;; 3.7.4 (CFNC-3.2 "char* gtk_gradient_to_string GtkGradient* gradient") ;;; 3.7.4 (CFNC-3.2 "char* gtk_symbolic_color_to_string GtkSymbolicColor* color") (CFNC-3.2 "gint gtk_tree_view_column_get_x_offset GtkTreeViewColumn* tree_column") ;(CFNC-3.2 void gtk_render_icon GtkStyleContext* context cairo_t* cr GdkPixbuf* pixbuf gdouble x gdouble y") (CCAST-3.2 "GTK_OVERLAY" "GtkOverlay*") (CCHK-3.2 "GTK_IS_OVERLAY" "GtkOverlay*") (CFNC-3.2 "GtkWidget* gtk_overlay_new void") (CFNC-3.2 "void gtk_overlay_add_overlay GtkOverlay* overlay GtkWidget* widget") ;;; 3.1.8: no changes ;;; 3.1.10: (CFNC-3.2 "gdouble gtk_adjustment_get_minimum_increment GtkAdjustment* adjustment") ;(CFNC-3.2 "void gtk_asssistant_remove_page GtkAssistant* assistant gint page_num") ;;; 3.1.12: (CCAST-3.2 "GTK_FONT_CHOOSER" "GtkFontChooser*") (CCHK-3.2 "GTK_IS_FONT_CHOOSER" "GtkFontChooser*") (CCAST-3.2 "GTK_FONT_CHOOSER_DIALOG" "GtkFontChooserDialog*") (CCHK-3.2 "GTK_IS_FONT_CHOOSER_DIALOG" "GtkFontChooserDialog*") ;;; typedef gboolean (*GtkFontFilterFunc) (const PangoFontFamily *family, const PangoFontFace *face, gpointer data); ;;; void gtk_font_chooser_set_filter_func(GtkFontChooser *fontchooser, GtkFontFilterFunc filter, gpointer data, GDestroyNotify destroy); (CFNC-3.2 "void gtk_grid_insert_row GtkGrid* grid gint position") (CFNC-3.2 "void gtk_grid_insert_column GtkGrid* grid gint position") (CFNC-3.2 "void gtk_grid_insert_next_to GtkGrid* grid GtkWidget* sibling GtkPositionType side") (CFNC-3.2 "void gtk_text_iter_assign GtkTextIter* iter GtkTextIter* other") ; const (CFNC-3.2 "gboolean gtk_widget_has_visible_focus GtkWidget* widget") (CFNC-3.2 "void gtk_window_set_focus_visible GtkWindow* window gboolean setting") (CFNC-3.2 "gboolean gtk_window_get_focus_visible GtkWindow* window") ;;; out 3.1.90? ;;; (CFNC-3.2 "GtkWidget* gtk_font_chooser_new void") ;;; (CFNC-3.2 "PangoFontFamily* gtk_font_chooser_get_family GtkFontChooser* fontchooser") ;;; (CFNC-3.2 "PangoFontFace* gtk_font_chooser_get_face GtkFontChooser* fontchooser") ;;; (CFNC-3.2 "gint gtk_font_chooser_get_size GtkFontChooser* fontchooser") ;;; (CFNC-3.2 "gchar* gtk_font_chooser_get_font_name GtkFontChooser* fontchooser") ;;; (CFNC-3.2 "gboolean gtk_font_chooser_set_font_name GtkFontChooser* fontchooser gchar* fontname" 'const) ;;; (CFNC-3.2 "gchar* gtk_font_chooser_get_preview_text GtkFontChooser* fontchooser" 'const-return) ;;; (CFNC-3.2 "void gtk_font_chooser_set_preview_text GtkFontChooser* fontchooser gchar* text" 'const) ;;; (CFNC-3.2 "gboolean gtk_font_chooser_get_show_preview_entry GtkFontChooser* fontchooser") ;;; (CFNC-3.2 "void gtk_font_chooser_set_show_preview_entry GtkFontChooser* fontchooser gboolean show_preview_entry") ;;; (CFNC-3.2 "GtkWidget* gtk_font_chooser_dialog_get_font_chooser GtkFontChooserDialog* fcd") ;;; (CFNC-3.2 "gchar* gtk_font_chooser_dialog_get_font_name GtkFontChooserDialog* fcd") ;;; (CFNC-3.2 "gboolean gtk_font_chooser_dialog_set_font_name GtkFontChooserDialog* fcd gchar* fontname" 'const) ;;; (CFNC-3.2 "gchar* gtk_font_chooser_dialog_get_preview_text GtkFontChooserDialog* fcd" 'const-return) ;;; (CFNC-3.2 "void gtk_font_chooser_dialog_set_preview_text GtkFontChooserDialog* fcd gchar* text" 'const) (CFNC-3.2 "GtkWidget* gtk_font_chooser_dialog_new gchar* title GtkWindow* window" 'const) ;;; 3.1.16|18 ;;; new: gtkcsssection.h (CFNC-3.2 "gboolean gdk_event_get_button GdkEvent* event guint* button") (CFNC-3.2 "gboolean gdk_event_get_click_count GdkEvent* event guint* click_count") (CFNC-3.2 "gboolean gdk_event_get_keyval GdkEvent* event guint* keyval") (CFNC-3.2 "gboolean gdk_event_get_keycode GdkEvent* event guint16* keycode") (CFNC-3.2 "gboolean gdk_event_get_scroll_direction GdkEvent* event GdkScrollDirection* [direction]") (CFNC-3.2 "GtkWidget* gtk_grid_get_child_at GtkGrid* grid gint left gint top") ;;; 3.1.90 (CCAST-3.2 "GTK_FONT_CHOOSER_WIDGET" "GtkFontChooserWidget*") (CCHK-3.2 "GTK_IS_FONT_CHOOSER_WIDGET" "GtkFontChooserWidget*") (CFNC-3.2 "PangoFontFamily* gtk_font_chooser_get_font_family GtkFontChooser* fontchooser") (CFNC-3.2 "PangoFontFace* gtk_font_chooser_get_font_face GtkFontChooser* fontchooser") (CFNC-3.2 "gint gtk_font_chooser_get_font_size GtkFontChooser* fontchooser") (CFNC-3.2 "PangoFontDescription* gtk_font_chooser_get_font_desc GtkFontChooser* fontchooser") (CFNC-3.2 "void gtk_font_chooser_set_font_desc GtkFontChooser* fontchooser PangoFontDescription* font_desc" 'const) (CFNC-3.2 "gchar* gtk_font_chooser_get_font GtkFontChooser* fontchooser") (CFNC-3.2 "void gtk_font_chooser_set_font GtkFontChooser* fontchooser gchar* fontname" 'const) (CFNC-3.2 "gchar* gtk_font_chooser_get_preview_text GtkFontChooser* fontchooser") (CFNC-3.2 "void gtk_font_chooser_set_preview_text GtkFontChooser* fontchooser gchar* text" 'const) (CFNC-3.2 "gboolean gtk_font_chooser_get_show_preview_entry GtkFontChooser* fontchooser") (CFNC-3.2 "void gtk_font_chooser_set_show_preview_entry GtkFontChooser* fontchooser gboolean show_preview_entry") (CFNC-3.2 "GtkWidget* gtk_font_chooser_widget_new void") ;;; void gtk_font_chooser_set_filter_func GtkFontChooser* fontchooser GtkFontFilterFuncfilter gpointer user_data GDestroyNotify destroy) ;;; gtk 3.3.2 ;;; gtk 3.3.6 ;;; the scale troughs are changed -- in prefs they're all green or gray now? (CCAST-3.4 "GTK_APPLICATION_WINDOW" "GtkApplicationWindow*") (CCHK-3.4 "GTK_IS_APPLICATION_WINDOW" "GtkApplicationWindow*") (CINT-3.4 "GDK_MODIFIER_INTENT_PRIMARY_ACCELERATOR" "GdkModifierIntent") (CINT-3.4 "GDK_MODIFIER_INTENT_CONTEXT_MENU" "GdkModifierIntent") (CINT-3.4 "GDK_MODIFIER_INTENT_EXTEND_SELECTION" "GdkModifierIntent") (CINT-3.4 "GDK_MODIFIER_INTENT_MODIFY_SELECTION" "GdkModifierIntent") (CINT-3.4 "GDK_MODIFIER_INTENT_NO_TEXT_INPUT" "GdkModifierIntent") (CINT-3.4 "GDK_MODIFIER_INTENT_SHIFT_GROUP" "GdkModifierIntent") (CINT-3.4 "GTK_REGION_ONLY" "GtkRegionFlags") (CINT-3.4 "GDK_WINDOW_STATE_FOCUSED" "GdkWindowState") ;;; (CINT-3.4 "GTK_STATE_FLAG_WINDOW_UNFOCUSED" "GtkStateFlags") (CINT-3.4 "GTK_CELL_RENDERER_EXPANDABLE" "GtkCellRendererState") (CINT-3.4 "GTK_CELL_RENDERER_EXPANDED" "GtkCellRendererState") (CFNC-3.4 "GdkModifierType gdk_keymap_get_modifier_mask GdkKeymap* keymap GdkModifierIntent intent") (CFNC-3.4 "void gdk_window_begin_resize_drag_for_device GdkWindow* window GdkWindowEdge edge GdkDevice* device gint button gint root_x gint root_y guint32 timestamp") (CFNC-3.4 "void gdk_window_begin_move_drag_for_device GdkWindow* window GdkDevice* device gint button gint root_x gint root_y guint32 timestamp") (CFNC-3.4 "void gtk_accelerator_parse_with_keycode gchar* accelerator guint* accelerator_key guint** accelerator_codes GdkModifierType* accelerator_mods" 'const) (CFNC-3.4 "gchar* gtk_accelerator_name_with_keycode GdkDisplay* display guint accelerator_key guint keycode GdkModifierType accelerator_mods") (CFNC-3.4 "gchar* gtk_accelerator_get_label_with_keycode GdkDisplay* display guint accelerator_key guint keycode GdkModifierType accelerator_mods") (CFNC-3.4 "void gdk_screen_get_monitor_workarea GdkScreen* screen gint monitor_num GdkRectangle* dest") (CFNC-3.4 "GMenuModel* gtk_application_get_app_menu GtkApplication* application") (CFNC-3.4 "void gtk_application_set_app_menu GtkApplication* application GMenuModel* model") (CFNC-3.4 "GMenuModel* gtk_application_get_menubar GtkApplication* application") (CFNC-3.4 "void gtk_application_set_menubar GtkApplication* application GMenuModel* model") ;;; 3.14 (CFNC-3.4 "void gtk_application_add_accelerator GtkApplication* application gchar* accelerator gchar* action_name GVariant* parameter" 'const) ;;; 3.14 (CFNC-3.4 "void gtk_application_remove_accelerator GtkApplication* application gchar* action_name GVariant* parameter" 'const) (CFNC-3.4 "gchar* gtk_entry_completion_compute_prefix GtkEntryCompletion* completion char* key" 'const) (CFNC-3.4 "void gtk_scale_set_has_origin GtkScale* scale gboolean has_origin") (CFNC-3.4 "gboolean gtk_scale_get_has_origin GtkScale* scale") (CFNC-3.4 "void gtk_window_set_hide_titlebar_when_maximized GtkWindow* window gboolean setting") (CFNC-3.4 "gboolean gtk_window_get_hide_titlebar_when_maximized GtkWindow* window") (CFNC-3.4 "GtkWidget* gtk_application_window_new GtkApplication* application") (CFNC-3.4 "void gtk_application_window_set_show_menubar GtkApplicationWindow* window gboolean show_menubar") (CFNC-3.4 "gboolean gtk_application_window_get_show_menubar GtkApplicationWindow* window") ;;; 3.3.8 GdkColor deprecated, so all existing refs above need -gtk2 (CINT-3.4 "GTK_STATE_FLAG_BACKDROP" "GtkStateFlags") (CFNC-3.4 "GtkWidget* gtk_image_new_from_resource gchar* resource_path" 'const) (CFNC-3.4 "void gtk_image_set_from_resource GtkImage* image gchar* resource_path" 'const) (CFNC-3.4 "void gtk_window_set_attached_to GtkWindow* window GtkWidget* attach_widget") (CFNC-3.4 "GtkWidget* gtk_window_get_attached_to GtkWindow* window") ;;; 3.3.10 nothing new ;;; 3.3.12 (CFNC-3.4 "void gtk_about_dialog_add_credit_section GtkAboutDialog* about gchar* section_name gchar** people" 'const) ;;; 3.3.14 nothing new ;;; 3.3.16 color selection dialog deprecated -- many new headers for color chooser dialog ;;; colorsel.h and colorseldialog.h gone ;;; color_button stuff seems also to be deprecated? (CFNC-3.4 "guint gdk_keymap_get_modifier_state GdkKeymap* keymap") (CFNC-3.4 "void gtk_hsv_to_rgb gdouble h gdouble s gdouble v gdouble* [r] gdouble* [g] gdouble* [b]") (CFNC-3.4 "void gtk_rgb_to_hsv gdouble r gdouble g gdouble b gdouble* [h] gdouble* [s] gdouble* [v]") (CFNC-3.4 "void gtk_color_chooser_get_rgba GtkColorChooser* chooser GdkRGBA* color") (CFNC-3.4 "void gtk_color_chooser_set_rgba GtkColorChooser* chooser GdkRGBA* color" 'const) (CFNC-3.4 "gboolean gtk_color_chooser_get_use_alpha GtkColorChooser* chooser") (CFNC-3.4 "void gtk_color_chooser_set_use_alpha GtkColorChooser* chooser gboolean use_alpha") (CFNC-3.4 "GtkWidget* gtk_color_chooser_dialog_new gchar* title GtkWindow* parent" 'const) (CFNC-3.4 "GtkWidget* gtk_color_chooser_widget_new void") (CCAST-3.4 "GTK_COLOR_CHOOSER_DIALOG" "GtkColorChooserDialog*") (CCHK-3.4 "GTK_IS_COLOR_CHOOSER_DIALOG" "GtkColorChooserDialog*") (CCAST-3.4 "GTK_COLOR_CHOOSER_WIDGET" "GtkColorWidget*") (CCHK-3.4 "GTK_IS_COLOR_CHOOSER_WIDGET" "GtkColorWidget*") ;; also GDK_BUTTON_PRIMARY|MIDDLE|SECONDARY but they are just ints (from gdkevents.h) ;;; 3.3.18 ;(CINT-3.6 "GDK_EXTENSION_EVENTS_NONE" "GdkExtensionMode") ;(CINT-3.6 "GDK_EXTENSION_EVENTS_ALL" "GdkExtensionMode") ;(CINT-3.6 "GDK_EXTENSION_EVENTS_CURSOR" "GdkExtensionMode") (CINT-3.6 "GDK_TOUCH_BEGIN" "GdkEventType") (CINT-3.6 "GDK_TOUCH_UPDATE" "GdkEventType") (CINT-3.6 "GDK_TOUCH_END" "GdkEventType") (CINT-3.6 "GDK_TOUCH_CANCEL" "GdkEventType") (CINT-3.6 "GDK_SCROLL_SMOOTH" "GdkScrollDirection") (CINT-3.6 "GDK_CROSSING_TOUCH_BEGIN" "GdkCrossingMode") (CINT-3.6 "GDK_CROSSING_TOUCH_END" "GdkCrossingMode") (CINT-3.6 "GDK_CROSSING_DEVICE_SWITCH" "GdkCrossingMode") ;(CINT-3.6 "GDK_EVENT_POINTER_EMULATED" "GdkEventFlags") (CINT-3.6 "GDK_TOUCH_MASK" "GdkEventMask") (CINT-3.6 "GDK_SMOOTH_SCROLL_MASK" "GdkEventMask") (CFNC-3.6 "gboolean gdk_event_get_scroll_deltas GdkEvent* event gdouble* [delta_x] gdouble* [delta_y]") ;;; 3.3.20 -- nothing new but "XI2" requirement -- what is that?? -- apparently some sort of typo (CFNC-3.6 "void gtk_color_chooser_add_palette GtkColorChooser* chooser GtkOrientation horizontal gint colors_per_line gint n_colors GdkRGBA* colors") ; was gboolean horizontal ;;; 3.4.0|1 -- nothing new ;;; 3.5.2 -- a few deprecations (below) ;;; 3.5.4 (CFNC-3.6 "void gtk_button_set_always_show_image GtkButton* button gboolean always_show") (CFNC-3.6 "gboolean gtk_button_get_always_show_image GtkButton* button") (CFNC-3.6 "guint gtk_tree_view_get_n_columns GtkTreeView* tree_view") ;;; GTK_UNIT_NONE as a GtkUnit (like pixel) but this enum is commented out above ;;; 3.5.6 ;(CFNC-3.6 "gboolean gtk_icon_view_get_cell_rect GtkIconView* icon_view GtkTreePath* path GtkCellRenderer* cell GdkRectangle** [rect]") (CCAST-3.6 "GTK_MENU_BUTTON" "GtkMenuButton*") (CCHK-3.6 "GTK_IS_MENU_BUTTON" "GtkMenuButton*") (CFNC-3.6 "GtkWidget* gtk_menu_button_new void") ;;; 3.5.12 (CFNC-3.6 "void gtk_menu_button_set_menu GtkMenuButton* menu_button GtkWidget* menu") ;;; 3.5.12 (CFNC-3.6 "GtkMenu* gtk_menu_button_get_menu GtkMenuButton* menu_button") ;;; 3.13.2 (CFNC-3.6 "void gtk_menu_button_set_direction GtkMenuButton* menu_button GtkArrowType direction") ;;; 3.13.2 (CFNC-3.6 "GtkArrowType gtk_menu_button_get_direction GtkMenuButton* menu_button") (CFNC-3.6 "void gtk_menu_button_set_menu_model GtkMenuButton* menu_button GMenuModel* menu_model") (CFNC-3.6 "GMenuModel* gtk_menu_button_get_menu_model GtkMenuButton* menu_button") (CFNC-3.6 "void gtk_menu_button_set_align_widget GtkMenuButton* menu_button GtkWidget* align_widget") (CFNC-3.6 "GtkWidget* gtk_menu_button_get_align_widget GtkMenuButton* menu_button") (CCAST-3.6 "GTK_SEARCH_ENTRY" "GtkWidget*") (CCHK-3.6 "GTK_IS_SEARCH_ENTRY" "GtkWidget*") (CFNC-3.6 "GtkWidget* gtk_search_entry_new void") ;;; 3.5.8 (which requires atk-bridge which is not builable!) (CINT-3.6 "GTK_LEVEL_BAR_MODE_CONTINUOUS" "GtkLevelBarMode") (CINT-3.6 "GTK_LEVEL_BAR_MODE_DISCRETE" "GtkLevelBarMode") (CCAST-3.6 "GTK_LEVEL_BAR" "GtkLevelBar*") (CCHK-3.6 "GTK_IS_LEVEL_BAR" "GtkLevelBar*") (CFNC-3.6 "GtkWidget* gtk_level_bar_new void") (CFNC-3.6 "GtkWidget* gtk_level_bar_new_for_interval gdouble min_value gdouble max_value") (CFNC-3.6 "void gtk_level_bar_set_mode GtkLevelBar* self GtkLevelBarMode mode") (CFNC-3.6 "GtkLevelBarMode gtk_level_bar_get_mode GtkLevelBar* self") (CFNC-3.6 "void gtk_level_bar_set_value GtkLevelBar* self gdouble value") (CFNC-3.6 "gdouble gtk_level_bar_get_value GtkLevelBar* self") (CFNC-3.6 "void gtk_level_bar_set_min_value GtkLevelBar* self gdouble value") (CFNC-3.6 "gdouble gtk_level_bar_get_min_value GtkLevelBar* self") (CFNC-3.6 "void gtk_level_bar_set_max_value GtkLevelBar* self gdouble value") (CFNC-3.6 "gdouble gtk_level_bar_get_max_value GtkLevelBar* self") (CFNC-3.6 "void gtk_level_bar_add_offset_value GtkLevelBar* self gchar* name gdouble value" 'const) (CFNC-3.6 "void gtk_level_bar_remove_offset_value GtkLevelBar* self gchar* name" 'const) (CFNC-3.6 "gboolean gtk_level_bar_get_offset_value GtkLevelBar* self gchar* name gdouble* [value]" 'const) ;;; 3.5.12 (CFNC-3.6 "GtkWindow* gtk_application_get_active_window GtkApplication* application") (CFNC-3.6 "void gtk_entry_set_input_purpose GtkEntry* entry GtkInputPurpose purpose") (CFNC-3.6 "GtkInputPurpose gtk_entry_get_input_purpose GtkEntry* entry") (CFNC-3.6 "void gtk_entry_set_input_hints GtkEntry* entry GtkInputHints hints") (CFNC-3.6 "GtkInputHints gtk_entry_get_input_hints GtkEntry* entry") ;;; ?? (CFNC-3.6 "void gtk_menu_button_set_menu GtkMenuButton* menu_button GtkWidget* menu") (CFNC-3.6 "GtkMenu* gtk_menu_button_get_popup GtkMenuButton* menu_button") (CFNC-3.6 "void gtk_text_view_set_input_purpose GtkTextView* text_view GtkInputPurpose purpose") (CFNC-3.6 "GtkInputPurpose gtk_text_view_get_input_purpose GtkTextView* text_view") (CFNC-3.6 "void gtk_text_view_set_input_hints GtkTextView* text_view GtkInputHints hints") (CFNC-3.6 "GtkInputHints gtk_text_view_get_input_hints GtkTextView* text_view") ;(CFNC-3.6 "void gtk_widget_insert_action_group GtkWidget* widget gchar* name GActionGroup* group" 'const) (CINT-3.6 "GTK_INPUT_PURPOSE_FREE_FORM" "GtkInputPurpose") (CINT-3.6 "GTK_INPUT_PURPOSE_ALPHA" "GtkInputPurpose") (CINT-3.6 "GTK_INPUT_PURPOSE_DIGITS" "GtkInputPurpose") (CINT-3.6 "GTK_INPUT_PURPOSE_NUMBER" "GtkInputPurpose") (CINT-3.6 "GTK_INPUT_PURPOSE_PHONE" "GtkInputPurpose") (CINT-3.6 "GTK_INPUT_PURPOSE_URL" "GtkInputPurpose") (CINT-3.6 "GTK_INPUT_PURPOSE_EMAIL" "GtkInputPurpose") (CINT-3.6 "GTK_INPUT_PURPOSE_NAME" "GtkInputPurpose") (CINT-3.6 "GTK_INPUT_PURPOSE_PASSWORD" "GtkInputPurpose") (CINT-3.6 "GTK_INPUT_PURPOSE_PIN" "GtkInputPurpose") (CINT-3.6 "GTK_INPUT_HINT_NONE" "GtkInputHints") (CINT-3.6 "GTK_INPUT_HINT_SPELLCHECK" "GtkInputHints") (CINT-3.6 "GTK_INPUT_HINT_NO_SPELLCHECK" "GtkInputHints") (CINT-3.6 "GTK_INPUT_HINT_WORD_COMPLETION" "GtkInputHints") (CINT-3.6 "GTK_INPUT_HINT_LOWERCASE" "GtkInputHints") (CINT-3.6 "GTK_INPUT_HINT_UPPERCASE_CHARS" "GtkInputHints") (CINT-3.6 "GTK_INPUT_HINT_UPPERCASE_WORDS" "GtkInputHints") (CINT-3.6 "GTK_INPUT_HINT_UPPERCASE_SENTENCES" "GtkInputHints") ;;; 3.5.14 (CINT-3.6 "GTK_INPUT_HINT_INHIBIT_OSK" "GtkInputHints") (CFNC-3.6 "void gtk_entry_set_attributes GtkEntry* entry PangoAttrList* attrs") (CFNC-3.6 "PangoAttrList* gtk_entry_get_attributes GtkEntry* entry") ;;; nothing new in 3.5.16 ;;; 3.5.18 (CFNC-3.6 "void gtk_accel_label_set_accel GtkAccelLabel* accel_label guint accelerator_key GdkModifierType accelerator_mods") ;;; (CFNC-3.6 "GtkAccelGroup* gtk_action_group_get_accel_group GtkActionGroup* action_group") ;;; (CFNC-3.6 "void gtk_action_group_set_accel_group GtkActionGroup* action_group GtkAccelGroup* accel_group") (CFNC-3.6 "void gtk_menu_shell_bind_model GtkMenuShell* menu_shell GMenuModel* model gchar* action_namespace gboolean with_separators" 'const) ;;; nothing new in 3.6.0|1 ;;; 3.7.0 (CFNC-3.8 "void gtk_level_bar_set_inverted GtkLevelBar* self gboolean inverted") (CFNC-3.8 "gboolean gtk_level_bar_get_inverted GtkLevelBar* self") ;;; 3.7.2 (CFNC-3.8 "gboolean gtk_widget_is_visible GtkWidget* widget") ;;; 3.7.4 ;;; gtk-gradient is deprecated? and symboliccolor ;;; 3.7.6 (CINT-3.8 "GTK_STATE_FLAG_DIR_LTR" "GtkStateFlags") (CINT-3.8 "GTK_STATE_FLAG_DIR_RTL" "GtkStateFlags") ;;; 3.7.8 (CINT-3.8 "GDK_FULLSCREEN_ON_CURRENT_MONITOR" "GdkFullscreenMode") (CINT-3.8 "GDK_FULLSCREEN_ON_ALL_MONITORS" "GdkFullscreenMode") (CFNC-3.8 "void gdk_window_set_fullscreen_mode GdkWindow* window GdkFullscreenMode mode") (CFNC-3.8 "GdkFullscreenMode gdk_window_get_fullscreen_mode GdkWindow* window") (CFNC-3.8 "void gtk_icon_view_set_activate_on_single_click GtkIconView* icon_view gboolean single") (CFNC-3.8 "gboolean gtk_icon_view_get_activate_on_single_click GtkIconView* icon_view") (CFNC-3.8 "gboolean gtk_tree_view_get_activate_on_single_click GtkTreeView* tree_view") (CFNC-3.8 "void gtk_tree_view_set_activate_on_single_click GtkTreeView* tree_view gboolean single") ;;; 3.7.10 (CFNC-3.8 "void gtk_widget_register_window GtkWidget* widget GdkWindow* window") (CFNC-3.8 "void gtk_widget_unregister_window GtkWidget* widget GdkWindow* window") (CFNC-3.8 "void gtk_widget_set_opacity GtkWidget* widget double opacity") (CFNC-3.8 "double gtk_widget_get_opacity GtkWidget* widget") ;;; 3.7.12: (CFNC-3.8 "void pango_font_map_changed PangoFontMap* fontmap") ;;; 3.7.14: no changes ;;; 3.8.0: no changes ;;; 3.9.0: lots of changes! here we go... ;;; (CFNC-3.10 "GdkDisplayManager* gdk_display_manager_peek void") (CFNC-3.10 "void gdk_set_allowed_backends gchar* backends" 'const) (CFNC-3.10 "void gtk_box_set_baseline_position GtkBox* box GtkBaselinePosition position") (CFNC-3.10 "GtkBaselinePosition gtk_box_get_baseline_position GtkBox* box") (CFNC-3.10 "void gtk_grid_remove_row GtkGrid* grid gint position") (CFNC-3.10 "void gtk_grid_remove_column GtkGrid* grid gint position") (CFNC-3.10 "void gtk_grid_set_row_baseline_position GtkGrid* grid gint row GtkBaselinePosition pos") (CFNC-3.10 "GtkBaselinePosition gtk_grid_get_row_baseline_position GtkGrid* grid gint row") (CFNC-3.10 "void gtk_grid_set_baseline_row GtkGrid* grid gint row") (CFNC-3.10 "gint gtk_grid_get_baseline_row GtkGrid* grid") (CFNC-3.10 "void gtk_widget_size_allocate_with_baseline GtkWidget* widget GtkAllocation* allocation gint baseline") (CFNC-3.10 "void gtk_widget_get_preferred_height_and_baseline_for_width GtkWidget* widget gint width gint* [minimum_height] gint* [natural_height] gint* [minimum_baseline] gint* [natural_baseline]") ;;; (CFNC-3.10 "void gtk_widget_get_preferred_size_and_baseline GtkWidget* widget GtkRequisition* minimum_size GtkRequisition* natural_size gint* [minimum_baseline] gint* [natural_baseline]") (CFNC-3.10 "int gtk_widget_get_allocated_baseline GtkWidget* widget") (CFNC-3.10 "GtkAlign gtk_widget_get_valign_with_baseline GtkWidget* widget") (CFNC-3.10 "void gtk_widget_init_template GtkWidget* widget") ;;; (CFNC-3.10 "GObject* gtk_widget_get_automated_child GtkWidget* widget GType widget_type gchar* name" 'const) ;;; GObject* is apparently the problem here ;(CFNC-3.10 "void gtk_widget_class_set_template GtkWidgetClass* widget_class GBytes* template_bytes") ;(CFNC-3.10 "void gtk_widget_class_set_template_from_resource GtkWidgetClass* widget_class gchar* resource_name" 'const) ;;; (CFNC-3.10 "void gtk_widget_class_declare_callback GtkWidgetClass* widget_class gchar* callback_name GCallback callback_symbol" 'const) ;;; (CFNC-3.10 "void gtk_widget_class_automate_child GtkWidgetClass* widget_class gchar* name gboolean internal_child gssize struct_offset" 'const) (CFNC-3.10 "void gtk_window_set_titlebar GtkWindow* window GtkWidget* titlebar") (CFNC-3.10 "GtkWidget* gtk_places_sidebar_new void") (CFNC-3.10 "GtkPlacesOpenFlags gtk_places_sidebar_get_open_flags GtkPlacesSidebar* sidebar") (CFNC-3.10 "void gtk_places_sidebar_set_open_flags GtkPlacesSidebar* sidebar GtkPlacesOpenFlags flags") (CFNC-3.10 "GFile* gtk_places_sidebar_get_location GtkPlacesSidebar* sidebar") (CFNC-3.10 "void gtk_places_sidebar_set_location GtkPlacesSidebar* sidebar GFile* location") (CFNC-3.10 "gboolean gtk_places_sidebar_get_show_desktop GtkPlacesSidebar* sidebar") (CFNC-3.10 "void gtk_places_sidebar_set_show_desktop GtkPlacesSidebar* sidebar gboolean show_desktop") ;;; 3.18 (CFNC-3.10 "gboolean gtk_places_sidebar_get_show_connect_to_server GtkPlacesSidebar* sidebar") ;;; 3.18 (CFNC-3.10 "void gtk_places_sidebar_set_show_connect_to_server GtkPlacesSidebar* sidebar gboolean show_connect_to_server") (CFNC-3.10 "void gtk_places_sidebar_add_shortcut GtkPlacesSidebar* sidebar GFile* location") (CFNC-3.10 "void gtk_places_sidebar_remove_shortcut GtkPlacesSidebar* sidebar GFile* location") (CFNC-3.10 "GSList* gtk_places_sidebar_list_shortcuts GtkPlacesSidebar* sidebar") (CFNC-3.10 "GFile* gtk_places_sidebar_get_nth_bookmark GtkPlacesSidebar* sidebar gint n") (CFNC-3.10 "GtkWidget* gtk_stack_switcher_new void") (CFNC-3.10 "void gtk_stack_switcher_set_stack GtkStackSwitcher* switcher GtkStack* stack") (CFNC-3.10 "GtkStack* gtk_stack_switcher_get_stack GtkStackSwitcher* switcher") (CFNC-3.10 "GtkWidget* gtk_stack_new void") (CFNC-3.10 "void gtk_stack_add_named GtkStack* stack GtkWidget* child gchar* name" 'const) (CFNC-3.10 "void gtk_stack_add_titled GtkStack* stack GtkWidget* child gchar* name gchar* title" 'const) (CFNC-3.10 "void gtk_stack_set_visible_child GtkStack* stack GtkWidget* child") (CFNC-3.10 "GtkWidget* gtk_stack_get_visible_child GtkStack* stack") (CFNC-3.10 "void gtk_stack_set_visible_child_name GtkStack* stack gchar* name" 'const) (CFNC-3.10 "gchar* gtk_stack_get_visible_child_name GtkStack* stack") (CFNC-3.10 "void gtk_stack_set_visible_child_full GtkStack* stack gchar* name GtkStackTransitionType transition" 'const) (CFNC-3.10 "void gtk_stack_set_homogeneous GtkStack* stack gboolean homogeneous") (CFNC-3.10 "gboolean gtk_stack_get_homogeneous GtkStack* stack") (CFNC-3.10 "void gtk_stack_set_transition_duration GtkStack* stack guint duration") (CFNC-3.10 "guint gtk_stack_get_transition_duration GtkStack* stack") (CFNC-3.10 "void gtk_stack_set_transition_type GtkStack* stack GtkStackTransitionType transition") (CFNC-3.10 "GtkStackTransitionType gtk_stack_get_transition_type GtkStack* stack") (CFNC-3.10 "GtkWidget* gtk_revealer_new void") (CFNC-3.10 "gboolean gtk_revealer_get_reveal_child GtkRevealer* revealer") (CFNC-3.10 "void gtk_revealer_set_reveal_child GtkRevealer* revealer gboolean reveal_child") (CFNC-3.10 "gboolean gtk_revealer_get_child_revealed GtkRevealer* revealer") (CFNC-3.10 "guint gtk_revealer_get_transition_duration GtkRevealer* revealer") (CFNC-3.10 "void gtk_revealer_set_transition_duration GtkRevealer* revealer guint duration") (CFNC-3.10 "void gtk_revealer_set_transition_type GtkRevealer* revealer GtkRevealerTransitionType transition") (CFNC-3.10 "GtkRevealerTransitionType gtk_revealer_get_transition_type GtkRevealer* revealer") (CFNC-3.10 "GtkWidget* gtk_header_bar_new void") (CFNC-3.10 "void gtk_header_bar_set_title GtkHeaderBar* bar gchar* title" 'const) (CFNC-3.10 "gchar* gtk_header_bar_get_title GtkHeaderBar* bar" 'const) (CFNC-3.10 "void gtk_header_bar_set_subtitle GtkHeaderBar* bar gchar* subtitle" 'const) (CFNC-3.10 "gchar* gtk_header_bar_get_subtitle GtkHeaderBar* bar" 'const) (CFNC-3.10 "void gtk_header_bar_set_custom_title GtkHeaderBar* bar GtkWidget* title_widget") (CFNC-3.10 "GtkWidget* gtk_header_bar_get_custom_title GtkHeaderBar* bar") (CFNC-3.10 "void gtk_header_bar_pack_start GtkHeaderBar* bar GtkWidget* child") (CFNC-3.10 "void gtk_header_bar_pack_end GtkHeaderBar* bar GtkWidget* child") (CINT-3.10 "GTK_ALIGN_BASELINE" "GtkAlign") (CINT-3.10 "GTK_BASELINE_POSITION_TOP" "GtkBaselinePosition") (CINT-3.10 "GTK_BASELINE_POSITION_CENTER" "GtkBaselinePosition") (CINT-3.10 "GTK_BASELINE_POSITION_BOTTOM" "GtkBaselinePosition") (CINT-3.10 "GTK_PLACES_OPEN_NORMAL" "GtkPlacesOpenFlags") (CINT-3.10 "GTK_PLACES_OPEN_NEW_TAB" "GtkPlacesOpenFlags") (CINT-3.10 "GTK_PLACES_OPEN_NEW_WINDOW" "GtkPlacesOpenFlags") (CINT-3.10 "GTK_STACK_TRANSITION_TYPE_NONE" "GtkStackTransitionType") (CINT-3.10 "GTK_STACK_TRANSITION_TYPE_CROSSFADE" "GtkStackTransitionType") (CINT-3.10 "GTK_STACK_TRANSITION_TYPE_SLIDE_RIGHT" "GtkStackTransitionType") (CINT-3.10 "GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT" "GtkStackTransitionType") (CINT-3.10 "GTK_STACK_TRANSITION_TYPE_SLIDE_UP" "GtkStackTransitionType") (CINT-3.10 "GTK_STACK_TRANSITION_TYPE_SLIDE_DOWN" "GtkStackTransitionType") (CINT-3.10 "GTK_REVEALER_TRANSITION_TYPE_NONE" "GtkRevealerTransitionType") (CINT-3.10 "GTK_REVEALER_TRANSITION_TYPE_CROSSFADE" "GtkRevealerTransitionType") (CINT-3.10 "GTK_REVEALER_TRANSITION_TYPE_SLIDE_RIGHT" "GtkRevealerTransitionType") (CINT-3.10 "GTK_REVEALER_TRANSITION_TYPE_SLIDE_LEFT" "GtkRevealerTransitionType") (CINT-3.10 "GTK_REVEALER_TRANSITION_TYPE_SLIDE_UP" "GtkRevealerTransitionType") (CINT-3.10 "GTK_REVEALER_TRANSITION_TYPE_SLIDE_DOWN" "GtkRevealerTransitionType") (CCAST-3.10 "GTK_PLACES_SIDEBAR" "GtkPlacesSidebar*") (CCHK-3.10 "GTK_IS_PLACES_SIDEBAR" "GtkPlacesSidebar*") (CCAST-3.10 "GTK_STACK_SWITCHER" "GtkStackSwitcher*") (CCHK-3.10 "GTK_IS_STACK_SWITCHER" "GtkStackSwitcher*") (CCAST-3.10 "GTK_STACK" "GtkStack*") (CCHK-3.10 "GTK_IS_STACK" "GtkStack*") (CCAST-3.10 "GTK_REVEALER" "GtkRevealer*") (CCHK-3.10 "GTK_IS_REVEALER" "GtkRevealer*") (CCAST-3.10 "GTK_HEADER_BAR" "GtkHeaderBar*") (CCHK-3.10 "GTK_IS_HEADER_BAR" "GtkHeaderBar*") ;;; 3.9.2 (CINT-3.10 "GDK_WINDOW_STATE_TILED" "GdkWindowState") ;new files: [gtkactionmuxer|observable|observer] -- not apparently tying these in (see recent action), [gtkmenutrackeritem] ;;; 3.9.4: gtklistbox (slist replacement?) and gtksearchbar (CCAST-3.10 "GTK_LIST_BOX" "GtkListBox*") (CCHK-3.10 "GTK_IS_LIST_BOX" "GtkListBox*") (CCAST-3.10 "GTK_LIST_BOX_ROW" "GtkListBoxRow*") (CCHK-3.10 "GTK_IS_LIST_BOX_ROW" "GtkListBoxRow*") (CCAST-3.10 "GTK_SEARCH_BAR" "GtkSearchBar*") (CCHK-3.10 "GTK_IS_SEARCH_BAR" "GtkSearchBar*") ;typedef gboolean (*GtkListBoxFilterFunc) (GtkListBoxRow *row, gpointer user_data); ;typedef gint (*GtkListBoxSortFunc) (GtkListBoxRow *row1, GtkListBoxRow *row2, gpointer user_data); ;typedef void (*GtkListBoxUpdateHeaderFunc) (GtkListBoxRow *row, GtkListBoxRow *before, gpointer user_data); (CFNC-3.10 "GtkWidget* gtk_list_box_row_new void") (CFNC-3.10 "GtkWidget* gtk_list_box_row_get_header GtkListBoxRow* row") (CFNC-3.10 "void gtk_list_box_row_set_header GtkListBoxRow* row GtkWidget* header") (CFNC-3.10 "void gtk_list_box_row_changed GtkListBoxRow* row") (CFNC-3.10 "GtkListBoxRow* gtk_list_box_get_selected_row GtkListBox* list_box") (CFNC-3.10 "GtkListBoxRow* gtk_list_box_get_row_at_index GtkListBox* list_box gint index_") (CFNC-3.10 "GtkListBoxRow* gtk_list_box_get_row_at_y GtkListBox* list_box gint y") (CFNC-3.10 "void gtk_list_box_select_row GtkListBox* list_box GtkListBoxRow* row") (CFNC-3.10 "void gtk_list_box_set_placeholder GtkListBox* list_box GtkWidget* placeholder") (CFNC-3.10 "void gtk_list_box_set_adjustment GtkListBox* list_box GtkAdjustment* adjustment") (CFNC-3.10 "GtkAdjustment* gtk_list_box_get_adjustment GtkListBox* list_box") (CFNC-3.10 "void gtk_list_box_set_selection_mode GtkListBox* list_box GtkSelectionMode mode") (CFNC-3.10 "GtkSelectionMode gtk_list_box_get_selection_mode GtkListBox* list_box") ;(CFNC-3.10 "void gtk_list_box_set_filter_func GtkListBox* list_box GtkListBoxFilterFunc filter_func gpointer user_data GDestroyNotify destroy") ;(CFNC-3.10 "void gtk_list_box_set_header_func GtkListBox* list_box GtkListBoxUpdateHeaderFunc update_header gpointer user_data GDestroyNotify destroy") (CFNC-3.10 "void gtk_list_box_invalidate_filter GtkListBox* list_box") (CFNC-3.10 "void gtk_list_box_invalidate_sort GtkListBox* list_box") (CFNC-3.10 "void gtk_list_box_invalidate_headers GtkListBox* list_box") ;(CFNC-3.10 "void gtk_list_box_set_sort_func GtkListBox* list_box GtkListBoxSortFunc sort_func gpointer user_data GDestroyNotify destroy") (CFNC-3.10 "void gtk_list_box_set_activate_on_single_click GtkListBox* list_box gboolean single") (CFNC-3.10 "gboolean gtk_list_box_get_activate_on_single_click GtkListBox* list_box") (CFNC-3.10 "void gtk_list_box_drag_unhighlight_row GtkListBox* list_box") (CFNC-3.10 "void gtk_list_box_drag_highlight_row GtkListBox* list_box GtkListBoxRow* row") (CFNC-3.10 "GtkWidget* gtk_list_box_new void") (CFNC-3.10 "GtkWidget* gtk_search_bar_new void") (CFNC-3.10 "void gtk_search_bar_connect_entry GtkSearchBar* bar GtkEntry* entry") (CFNC-3.10 "gboolean gtk_search_bar_get_search_mode GtkSearchBar* bar") (CFNC-3.10 "void gtk_search_bar_set_search_mode GtkSearchBar* bar gboolean search_mode") (CFNC-3.10 "gboolean gtk_search_bar_get_show_close_button GtkSearchBar* bar") (CFNC-3.10 "void gtk_search_bar_set_show_close_button GtkSearchBar* bar gboolean visible") (CFNC-3.10 "gboolean gtk_search_bar_handle_event GtkSearchBar* bar GdkEvent* event") ;;; 3.9.6 (CFNC-3.10 "gchar* gtk_file_chooser_get_current_name GtkFileChooser* chooser") ; Wholly deprecated as part of this effort: ; GtkIconFactory, GtkIconSet, GtkIconSource, GtkImageMenuItem, ; GtkAction, GtkUIManager ; ; A number of settings have been deprecated and are ignored now: ; gtk-button-images, gtk-show-unicode-menu, gtk-show-input-method-menu, gtk-enable-mnemonics, gtk-auto-mnemonics, ; gtk-color-palette, gtk-can-change-accels, cursor blink settings, gtk-fallback-icon-theme, gtk-scrolled-window-placement, ; menu popup delay settings, gtk-menu-bar-accel, keynav tweaks, gtk-touchscreen-mode, gtk-icon-sizes, im style tweaks, ; gtk-file-chooser-backend, gtk-enable-tooltips, gtk-visible-focus, tooltip timeout tweaks, toolbar style tweaks ;;; 3.9.8: (CFNC-3.10 "cairo_surface_t* gdk_cairo_surface_create_from_pixbuf GdkPixbuf* pixbuf int scale GdkWindow* for_window") (CFNC-3.10 "void gdk_device_get_position_double GdkDevice* device GdkScreen** [screen] gdouble* [x] gdouble* [y]") (CFNC-3.10 "GdkWindow* gdk_device_get_window_at_position_double GdkDevice* device gdouble* [win_x] gdouble* [win_y]") (CFNC-3.10 "gint gdk_screen_get_monitor_scale_factor GdkScreen* screen gint monitor_num") (CFNC-3.10 "gint gdk_window_get_scale_factor GdkWindow* window") (CFNC-3.10 "GdkWindow* gdk_window_get_device_position_double GdkWindow* window GdkDevice* device gdouble* [x] gdouble* [y] GdkModifierType* [mask]") (CFNC-3.10 "cairo_surface_t* gdk_window_create_similar_image_surface GdkWindow* window cairo_format_t format int width int height int scale") (CFNC-3.10 "GtkIconInfo* gtk_icon_theme_lookup_icon_for_scale GtkIconTheme* icon_theme gchar* icon_name gint size gint scale GtkIconLookupFlags flags" 'const) ;(CFNC-3.10 "GtkIconInfo* gtk_icon_theme_choose_icon_for_scale GtkIconTheme* icon_theme gchar* icon_names[] gint size gint scale GtkIconLookupFlags flags" 'const) (CFNC-3.10 "GdkPixbuf* gtk_icon_theme_load_icon_for_scale GtkIconTheme* icon_theme gchar* icon_name gint size gint scale GtkIconLookupFlags flags GError** [error]" 'const) (CFNC-3.10 "cairo_surface_t* gtk_icon_theme_load_surface GtkIconTheme* icon_theme gchar* icon_name gint size gint scale GdkWindow* for_window GtkIconLookupFlags flags GError** [error]" 'const) (CFNC-3.10 "GtkIconInfo* gtk_icon_theme_lookup_by_gicon_for_scale GtkIconTheme* icon_theme GIcon* icon gint size gint scale GtkIconLookupFlags flags") (CFNC-3.10 "gint gtk_icon_info_get_base_scale GtkIconInfo* icon_info") (CFNC-3.10 "cairo_surface_t* gtk_icon_info_load_surface GtkIconInfo* icon_info GdkWindow* for_window GError** [error]") (CFNC-3.10 "GtkWidget* gtk_image_new_from_surface cairo_surface_t* surface") (CFNC-3.10 "void gtk_image_set_from_surface GtkImage* image cairo_surface_t* surface") (CFNC-3.10 "gint gtk_list_box_row_get_index GtkListBoxRow* row") (CFNC-3.10 "gint gtk_widget_get_scale_factor GtkWidget* widget") (CFNC-3.10 "void gtk_window_close GtkWindow* window") ;;; 3.9.10: (CFNC-3.10 "void gtk_info_bar_set_show_close_button GtkInfoBar* info_bar gboolean setting") (CFNC-3.10 "gboolean gtk_info_bar_get_show_close_button GtkInfoBar* info_bar") (CFNC-3.10 "void gtk_tree_model_rows_reordered_with_length GtkTreeModel* tree_model GtkTreePath* path GtkTreeIter* iter gint* new_order gint length") ;;; 3.9.12: (CFNC-3.10 "GdkCursor* gdk_cursor_new_from_surface GdkDisplay* display cairo_surface_t* surface gdouble x gdouble y") (CFNC-3.10 "cairo_surface_t* gdk_cursor_get_surface GdkCursor* cursor gdouble* [x_hot] gdouble* [y_hot]") (CFNC-3.10 "GdkEventType gdk_event_get_event_type GdkEvent* event" 'const) ;;; (CFNC-3.10 "GtkWidget* gtk_button_new_from_icon_name gchar* icon_name GtkIconSize size" 'const) (CFNC-3.10 "void gtk_entry_set_tabs GtkEntry* entry PangoTabArray* tabs") (CFNC-3.10 "PangoTabArray* gtk_entry_get_tabs GtkEntry* entry") (CFNC-3.10 "gboolean gtk_header_bar_get_show_close_button GtkHeaderBar* bar") (CFNC-3.10 "void gtk_header_bar_set_show_close_button GtkHeaderBar* bar gboolean setting") (CFNC-3.10 "void gtk_list_box_prepend GtkListBox* list_box GtkWidget* child") (CFNC-3.10 "void gtk_list_box_insert GtkListBox* list_box GtkWidget* child gint position") ;;; 3.9.14: (CFNC-3.10 "void gdk_window_set_opaque_region GdkWindow* window cairo_region_t* region") (CFNC-3.10 "void gtk_label_set_lines GtkLabel* label gint lines") (CFNC-3.10 "gint gtk_label_get_lines GtkLabel* label") ;;; 3.9.16: (CFNC-3.10 "GdkWindow* gdk_event_get_window GdkEvent* event" 'const) ;;; 3.10.0|1|2 -- nothing new ;;; 3.11.0 flowbox.h (CINT-3.12 "GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT_RIGHT" "GtkStackTransitionType") (CINT-3.12 "GTK_STACK_TRANSITION_TYPE_SLIDE_UP_DOWN" "GtkStackTransitionType") (CINT-3.12 "GTK_STACK_TRANSITION_TYPE_OVER_UP" "GtkStackTransitionType") (CINT-3.12 "GTK_STACK_TRANSITION_TYPE_OVER_DOWN" "GtkStackTransitionType") (CINT-3.12 "GTK_STACK_TRANSITION_TYPE_OVER_LEFT" "GtkStackTransitionType") (CINT-3.12 "GTK_STACK_TRANSITION_TYPE_OVER_RIGHT" "GtkStackTransitionType") (CINT-3.12 "GTK_STACK_TRANSITION_TYPE_UNDER_UP" "GtkStackTransitionType") (CINT-3.12 "GTK_STACK_TRANSITION_TYPE_UNDER_DOWN" "GtkStackTransitionType") (CINT-3.12 "GTK_STACK_TRANSITION_TYPE_UNDER_LEFT" "GtkStackTransitionType") (CINT-3.12 "GTK_STACK_TRANSITION_TYPE_UNDER_RIGHT" "GtkStackTransitionType") (CINT-3.12 "GTK_STACK_TRANSITION_TYPE_OVER_UP_DOWN" "GtkStackTransitionType") (CCAST-3.12 "GTK_FLOW_BOX" "GtkFlowBox*") (CCHK-3.12 "GTK_IS_FLOW_BOX" "GtkFlowBox*") (CCAST-3.12 "GTK_FLOW_BOX_CHILD" "GtkFlowBoxChild*") (CCHK-3.12 "GTK_IS_FLOW_BOX_CHILD" "GtkFlowBoxChild*") (CFNC-3.12 "GtkWidget* gtk_flow_box_child_new void") (CFNC-3.12 "gint gtk_flow_box_child_get_index GtkFlowBoxChild* child") (CFNC-3.12 "gboolean gtk_flow_box_child_is_selected GtkFlowBoxChild* child") (CFNC-3.12 "void gtk_flow_box_child_changed GtkFlowBoxChild* child") (CFNC-3.12 "GtkWidget* gtk_flow_box_new void") (CFNC-3.12 "void gtk_flow_box_set_homogeneous GtkFlowBox* box gboolean homogeneous") (CFNC-3.12 "gboolean gtk_flow_box_get_homogeneous GtkFlowBox* box") (CFNC-3.12 "void gtk_flow_box_set_row_spacing GtkFlowBox* box guint spacing") (CFNC-3.12 "guint gtk_flow_box_get_row_spacing GtkFlowBox* box") (CFNC-3.12 "void gtk_flow_box_set_column_spacing GtkFlowBox* box guint spacing") (CFNC-3.12 "guint gtk_flow_box_get_column_spacing GtkFlowBox* box") (CFNC-3.12 "void gtk_flow_box_set_min_children_per_line GtkFlowBox* box guint n_children") (CFNC-3.12 "guint gtk_flow_box_get_min_children_per_line GtkFlowBox* box") (CFNC-3.12 "void gtk_flow_box_set_max_children_per_line GtkFlowBox* box guint n_children") (CFNC-3.12 "guint gtk_flow_box_get_max_children_per_line GtkFlowBox* box") (CFNC-3.12 "void gtk_flow_box_set_activate_on_single_click GtkFlowBox* box gboolean single") (CFNC-3.12 "gboolean gtk_flow_box_get_activate_on_single_click GtkFlowBox* box") (CFNC-3.12 "void gtk_flow_box_insert GtkFlowBox* box GtkWidget* widget gint position") (CFNC-3.12 "GtkFlowBoxChild* gtk_flow_box_get_child_at_index GtkFlowBox* box gint idx") (CFNC-3.12 "GList* gtk_flow_box_get_selected_children GtkFlowBox* box") (CFNC-3.12 "void gtk_flow_box_select_child GtkFlowBox* box GtkFlowBoxChild* child") (CFNC-3.12 "void gtk_flow_box_unselect_child GtkFlowBox* box GtkFlowBoxChild* child") (CFNC-3.12 "void gtk_flow_box_select_all GtkFlowBox* box") (CFNC-3.12 "void gtk_flow_box_unselect_all GtkFlowBox* box") (CFNC-3.12 "void gtk_flow_box_set_selection_mode GtkFlowBox* box GtkSelectionMode mode") (CFNC-3.12 "GtkSelectionMode gtk_flow_box_get_selection_mode GtkFlowBox* box") (CFNC-3.12 "void gtk_flow_box_set_hadjustment GtkFlowBox* box GtkAdjustment* adjustment") (CFNC-3.12 "void gtk_flow_box_set_vadjustment GtkFlowBox* box GtkAdjustment* adjustment") (CFNC-3.12 "void gtk_flow_box_invalidate_filter GtkFlowBox* box") (CFNC-3.12 "void gtk_flow_box_invalidate_sort GtkFlowBox* box") ;void gtk_flow_box_selected_foreach GtkFlowBox* box GtkFlowBoxForeachFunc func gpointer data) ;void gtk_flow_box_set_sort_func GtkFlowBox* box GtkFlowBoxSortFunc sort_func gpointer user_data GDestroyNotify destroy) ;void gtk_flow_box_set_filter_func GtkFlowBox* box GtkFlowBoxFilterFunc filter_func gpointer user_data GDestroyNotify destroy) ;;; 3.11.2 -- these are internal to gdk ;;; (CINT-3.12 "GDK_EVENT_FLUSHED" "GdkEventFlags") ;;; (CINT-3.12 "GTK_STATE_FLAG_LINK" "GtkStateFlags") ;;; (CINT-3.12 "GTK_STATE_FLAG_VISITED" "GtkStateFlags") (CFNC-3.12 "void gdk_window_set_event_compression GdkWindow* window gboolean event_compression") (CFNC-3.12 "gboolean gdk_window_get_event_compression GdkWindow* window") ;;; (CFNC-3.12 "gboolean gtk_header_bar_get_show_fallback_app_menu GtkHeaderBar* bar") ;;; (CFNC-3.12 "void gtk_header_bar_set_show_fallback_app_menu GtkHeaderBar* bar gboolean setting") (CFNC-3.12 "void gtk_places_sidebar_set_local_only GtkPlacesSidebar* sidebar gboolean local_only") (CFNC-3.12 "gboolean gtk_places_sidebar_get_local_only GtkPlacesSidebar* sidebar") (CFNC-3.12 "gboolean gtk_stack_get_transition_running GtkStack* stack") (CFNC-3.12 "gint gtk_widget_get_margin_start GtkWidget* widget") (CFNC-3.12 "void gtk_widget_set_margin_start GtkWidget* widget gint margin") (CFNC-3.12 "gint gtk_widget_get_margin_end GtkWidget* widget") (CFNC-3.12 "void gtk_widget_set_margin_end GtkWidget* widget gint margin") ;;; 3.11.4 (CCAST-3.12 "GTK_ACTION_BAR" "GtkActionBar*") (CCHK-3.12 "GTK_IS_ACTION_BAR" "GtkActionBar*") (CFNC-3.12 "void gtk_accel_label_get_accel GtkAccelLabel* accel_label guint* [accelerator_key] GdkModifierType* [accelerator_mods]") (CFNC-3.12 "void gdk_window_set_shadow_width GdkWindow* window gint left gint right gint top gint bottom") (CFNC-3.12 "GtkWidget* gtk_action_bar_new void") (CFNC-3.12 "GtkWidget* gtk_action_bar_get_center_widget GtkActionBar* bar") (CFNC-3.12 "void gtk_action_bar_set_center_widget GtkActionBar* bar GtkWidget* center_widget") (CFNC-3.12 "void gtk_action_bar_pack_start GtkActionBar* bar GtkWidget* child") (CFNC-3.12 "void gtk_action_bar_pack_end GtkActionBar* bar GtkWidget* child") (CFNC-3.12 "void gtk_header_bar_set_has_subtitle GtkHeaderBar* bar gboolean setting") (CFNC-3.12 "gboolean gtk_header_bar_get_has_subtitle GtkHeaderBar* bar") (CFNC-3.12 "void gtk_header_bar_set_decoration_layout GtkHeaderBar* bar gchar* layout" 'const) (CFNC-3.12 "gchar* gtk_header_bar_get_decoration_layout GtkHeaderBar* bar" 'const) (CFNC-3.12 "gboolean gtk_icon_info_is_symbolic GtkIconInfo* icon_info") (CFNC-3.12 "GtkTextDirection gtk_get_locale_direction void") ;(CFNC-3.12 "GtkTreePath* gtk_tree_path_new_from_indicesv gint* indices gsize length") (CFNC-3.12 "gboolean gtk_window_is_maximized GtkWindow* window") ;;; 3.11.5 (CCAST-3.12 "GTK_POPOVER" "GtkPopover*") (CCHK-3.12 "GTK_IS_POPOVER" "GtkPopover*") ;;; ?? (CFNC-3.12 "GdkVisual* gdk_screen_get_preferred_visual GdkScreen* screen") (CFNC-3.12 "GtkWidget* gtk_dialog_get_header_bar GtkDialog* dialog") (CFNC-3.12 "GtkWidget* gtk_popover_new GtkWidget* relative_to") (CFNC-3.12 "void gtk_popover_set_relative_to GtkPopover* popover GtkWidget* relative_to") (CFNC-3.12 "GtkWidget* gtk_popover_get_relative_to GtkPopover* popover") ;(CFNC-3.12 "void gtk_popover_set_pointing_to GtkPopover* popover GdkRectangle *rect") ;(CFNC-3.12 "gboolean gtk_popover_get_pointing_to GtkPopover* popover GdkRectangle* [rect]") (CFNC-3.12 "void gtk_popover_set_position GtkPopover* popover GtkPositionType position") (CFNC-3.12 "GtkPositionType gtk_popover_get_position GtkPopover* popover") (CFNC-3.12 "void gtk_popover_set_modal GtkPopover* popover gboolean modal") (CFNC-3.12 "gboolean gtk_popover_get_modal GtkPopover* popover") ;;; 3.11.6 ;;; gtkmodelbutton.h (CFNC-3.12 "void gtk_box_set_center_widget GtkBox* box GtkWidget* widget") (CFNC-3.12 "GtkWidget* gtk_box_get_center_widget GtkBox* box") (CFNC-3.12 "void gtk_entry_set_max_width_chars GtkEntry* entry gint n_chars") (CFNC-3.12 "gint gtk_entry_get_max_width_chars GtkEntry* entry") ;;; 3.11.9 (CFNC-3.12 "GdkWindow* gdk_device_get_last_event_window GdkDevice* device") ;;; 3.12.0 -- no changes ;;; 3.12.1 -- no changes? ;;; 3.13.1 (CFNC-3.14 "gboolean gtk_list_box_row_is_selected GtkListBoxRow* row") ;(CFNC-3.14 "void gtk_list_box_selected_foreach (GtkListBox* box GtkListBoxForeachFunc func gpointer data") ;(CFNC-3.14 "GList *gtk_list_box_get_selected_rows GtkListBox* box") (CFNC-3.14 "void gtk_list_box_unselect_row GtkListBox* box GtkListBoxRow* row") (CFNC-3.14 "void gtk_list_box_select_all GtkListBox* box") (CFNC-3.14 "void gtk_list_box_unselect_all GtkListBox* box") (CFNC-3.14 "gboolean gtk_places_sidebar_get_show_enter_location GtkPlacesSidebar* sidebar") (CFNC-3.14 "void gtk_places_sidebar_set_show_enter_location GtkPlacesSidebar* sidebar gboolean show_enter_location") (CFNC-3.14 "void gtk_switch_set_state GtkSwitch* sw gboolean state") (CFNC-3.14 "gboolean gtk_switch_get_state GtkSwitch* sw") ;;; is this exported? ; GTK_MENU_SECTION_BOX(inst) ; GTK_IS_MENU_SECTION_BOX(inst) ; void gtk_menu_section_box_new_toplevel GtkStack* stack GMenuModel* model const gchar* action_namespace) ;;; 3.13.2: (CFNC-3.14 "gboolean gdk_window_show_window_menu GdkWindow* window GdkEvent* event") (CFNC-3.14 "void gtk_widget_set_clip GtkWidget* widget GtkAllocation* clip" 'const) (CFNC-3.14 "void gtk_widget_get_clip GtkWidget* widget GtkAllocation* clip") (CCAST-3.14 "GTK_GESTURE" "GtkGesture*") (CCHK-3.14 "GTK_IS_GESTURE" "GtkGesture*") (CCAST-3.14 "GTK_GESTURE_DRAG" "GtkGestureDrag*") (CCHK-3.14 "GTK_IS_GESTURE_DRAG" "GtkGestureDrag*") (CCAST-3.14 "GTK_GESTURE_LONG_PRESS" "GtkGestureLongPress*") (CCHK-3.14 "GTK_IS_GESTURE_LONG_PRESS" "GtkGestureLongPress*") (CCAST-3.14 "GTK_GESTURE_ZOOM" "GtkGestureZoom*") (CCHK-3.14 "GTK_IS_GESTURE_ZOOM" "GtkGestureZoom*") (CCAST-3.14 "GTK_GESTURE_SWIPE" "GtkGestureSwipe*") (CCHK-3.14 "GTK_IS_GESTURE_SWIPE" "GtkGestureSwipe*") (CCAST-3.14 "GTK_GESTURE_SINGLE" "GtkGestureSingle*") (CCHK-3.14 "GTK_IS_GESTURE_SINGLE" "GtkGestureSingle*") (CCAST-3.14 "GTK_GESTURE_PAN" "GtkGesturePan*") (CCHK-3.14 "GTK_IS_GESTURE_PAN" "GtkGesturePan*") (CCAST-3.14 "GTK_GESTURE_MULTI_PRESS" "GtkGestureMultiPress*") (CCHK-3.14 "GTK_IS_GESTURE_MULTI_PRESS" "GtkGestureMultiPress*") (CCAST-3.14 "GTK_GESTURE_ROTATE" "GtkGestureRotate*") (CCHK-3.14 "GTK_IS_GESTURE_ROTATE" "GtkGestureRotate*") (CFNC-3.14 "GdkDevice* gtk_gesture_get_device GtkGesture* gesture") (CFNC-3.14 "gboolean gtk_gesture_set_state GtkGesture* gesture GtkEventSequenceState state") (CFNC-3.14 "GtkEventSequenceState gtk_gesture_get_sequence_state GtkGesture* gesture GdkEventSequence* sequence") (CFNC-3.14 "gboolean gtk_gesture_set_sequence_state GtkGesture* gesture GdkEventSequence* sequence GtkEventSequenceState state") (CFNC-3.14 "GList* gtk_gesture_get_sequences GtkGesture* gesture") (CFNC-3.14 "GdkEventSequence* gtk_gesture_get_last_updated_sequence GtkGesture* gesture") (CFNC-3.14 "gboolean gtk_gesture_handles_sequence GtkGesture* gesture GdkEventSequence* sequence") (CFNC-3.14 "GdkEvent* gtk_gesture_get_last_event GtkGesture* gesture GdkEventSequence* sequence" 'const-return) (CFNC-3.14 "gboolean gtk_gesture_get_point GtkGesture* gesture GdkEventSequence* sequence gdouble* [x] gdouble* [y]") (CFNC-3.14 "gboolean gtk_gesture_get_bounding_box GtkGesture* gesture GdkRectangle* rect") (CFNC-3.14 "gboolean gtk_gesture_get_bounding_box_center GtkGesture* gesture gdouble* [x] gdouble* [y]") (CFNC-3.14 "gboolean gtk_gesture_is_active GtkGesture* gesture") (CFNC-3.14 "gboolean gtk_gesture_is_recognized GtkGesture* gesture") (CFNC-3.14 "GdkWindow* gtk_gesture_get_window GtkGesture* gesture") (CFNC-3.14 "void gtk_gesture_set_window GtkGesture* gesture GdkWindow* window") (CFNC-3.14 "void gtk_gesture_group GtkGesture* group_gesture GtkGesture* gesture") (CFNC-3.14 "void gtk_gesture_ungroup GtkGesture* gesture") (CFNC-3.14 "GList* gtk_gesture_get_group GtkGesture* gesture") (CFNC-3.14 "gboolean gtk_gesture_is_grouped_with GtkGesture* gesture GtkGesture* other") (CFNC-3.14 "GtkGesture* gtk_gesture_drag_new GtkWidget* widget") (CFNC-3.14 "gboolean gtk_gesture_drag_get_start_point GtkGestureDrag* gesture gdouble* [x] gdouble* [y]") (CFNC-3.14 "gboolean gtk_gesture_drag_get_offset GtkGestureDrag* gesture gdouble* [x] gdouble* [y]") (CFNC-3.14 "GtkGesture* gtk_gesture_long_press_new GtkWidget* widget") (CFNC-3.14 "GtkGesture* gtk_gesture_pan_new GtkWidget* widget GtkOrientation orientation") (CFNC-3.14 "GtkOrientation gtk_gesture_pan_get_orientation GtkGesturePan* gesture") (CFNC-3.14 "void gtk_gesture_pan_set_orientation GtkGesturePan* gesture GtkOrientation orientation") (CFNC-3.14 "GtkGesture* gtk_gesture_multi_press_new GtkWidget* widget") (CFNC-3.14 "void gtk_gesture_multi_press_set_area GtkGestureMultiPress* gesture GdkRectangle* rect") (CFNC-3.14 "gboolean gtk_gesture_multi_press_get_area GtkGestureMultiPress* gesture GdkRectangle* rect") (CFNC-3.14 "GtkGesture* gtk_gesture_rotate_new GtkWidget* widget") (CFNC-3.14 "gdouble gtk_gesture_rotate_get_angle_delta GtkGestureRotate* gesture") (CFNC-3.14 "gboolean gtk_gesture_single_get_touch_only GtkGestureSingle* gesture") (CFNC-3.14 "void gtk_gesture_single_set_touch_only GtkGestureSingle* gesture gboolean touch_only") (CFNC-3.14 "gboolean gtk_gesture_single_get_exclusive GtkGestureSingle* gesture") (CFNC-3.14 "void gtk_gesture_single_set_exclusive GtkGestureSingle* gesture gboolean exclusive") (CFNC-3.14 "guint gtk_gesture_single_get_button GtkGestureSingle* gesture") (CFNC-3.14 "void gtk_gesture_single_set_button GtkGestureSingle* gesture guint button") (CFNC-3.14 "guint gtk_gesture_single_get_current_button GtkGestureSingle* gesture") (CFNC-3.14 "GdkEventSequence* gtk_gesture_single_get_current_sequence GtkGestureSingle* gesture") (CFNC-3.14 "GtkGesture* gtk_gesture_swipe_new GtkWidget* widget") (CFNC-3.14 "gboolean gtk_gesture_swipe_get_velocity GtkGestureSwipe* gesture gdouble* [velocity_x] gdouble* [velocity_y]") (CFNC-3.14 "GtkGesture* gtk_gesture_zoom_new GtkWidget* widget") (CFNC-3.14 "gdouble gtk_gesture_zoom_get_scale_delta GtkGestureZoom* gesture") (CCAST-3.14 "GTK_EVENT_CONTROLLER" "GtkEventController*") (CCHK-3.14 "GTK_IS_EVENT_CONTROLLER" "GtkEventController*") (CFNC-3.14 "GtkWidget* gtk_event_controller_get_widget GtkEventController* controller") (CFNC-3.14 "gboolean gtk_event_controller_handle_event GtkEventController* controller GdkEvent* event") (CFNC-3.14 "void gtk_event_controller_reset GtkEventController* controller") (CFNC-3.14 "GtkPropagationPhase gtk_event_controller_get_propagation_phase GtkEventController* controller") (CFNC-3.14 "void gtk_event_controller_set_propagation_phase GtkEventController* controller GtkPropagationPhase phase") ;;; 3.13.3: nothing new ;;; 3.13.4: (CFNC-3.14 "void gtk_icon_theme_add_resource_path GtkIconTheme* icon_theme gchar* path" 'const) (CFNC-3.14 "void gtk_list_box_row_set_activatable GtkListBoxRow* row gboolean activatable") (CFNC-3.14 "gboolean gtk_list_box_row_get_activatable GtkListBoxRow* row") ;;; 3.13.5: (CFNC-3.14 "void gtk_list_box_row_set_selectable GtkListBoxRow* row gboolean selectable") (CFNC-3.14 "gboolean gtk_list_box_row_get_selectable GtkListBoxRow* row") (CFNC-3.14 "GtkStateFlags gtk_widget_path_iter_get_state GtkWidgetPath* path gint pos" 'const) (CFNC-3.14 "void gtk_widget_path_iter_set_state GtkWidgetPath* path gint pos GtkStateFlags state") ;;; 3.13.6: (CINT-3.14 "GTK_TEXT_VIEW_LAYER_BELOW" "GtkTextViewLayer") (CINT-3.14 "GTK_TEXT_VIEW_LAYER_ABOVE" "GtkTextViewLayer") ;;; 3.13.7: nothing new (GtkStatusIcon deprecated) ;;; 3.13.8: nothing new ;;; 3.13.9: nothing new, but GDK_KEY changes ;;; 3.14.0: nothing new ;;; 3.14.1: nothing new ;;; 3.14.2: nothing new ;;; 3.14.3: nothing new ;;; 3.14.4: nothing new ;;; 3.15.0: (CINT-3.16 "GTK_POLICY_EXTERNAL" "GtkPolicyType") ;(CINT-3.16 "GDK_GL_PROFILE_DEFAULT" "GdkGLProfile") ;(CINT-3.16 "GDK_GL_PROFILE_LEGACY" "GdkGLProfile") ;(CINT-3.16 "GDK_GL_PROFILE_3_2_CORE" "GdkGLProfile") ;(CINT-3.16 "GDK_GL_ERROR_NOT_AVAILABLE" "GdkGLError") ;(CINT-3.16 "GDK_GL_ERROR_UNSUPPORTED_FORMAT" "GdkGLError") ;(CINT-3.16 "GDK_GL_ERROR_UNSUPPORTED_PROFIL" "GdkGLError") (CCAST-3.16 "GTK_GL_AREA(object)" "GtkGLArea*") (CCAST-3.16 "GDK_GL_CONTEXT(object)" "GdkGLContext*") (CCHK-3.16 "GTK_IS_GL_AREA(object)" "GtkGLArea*") (CCHK-3.16 "GDK_IS_GL_CONTEXT(object)" "GdkGLContext*") (CFNC-3.16 "void gdk_cairo_draw_from_gl cairo_t* cr GdkWindow* window int source int source_type int buffer_scale int x int y int width int height") (CFNC-3.16 "void gdk_window_mark_paint_from_clip GdkWindow* window cairo_t* cr") ;(CFNC-3.16 "GdkGLContext* gdk_window_create_gl_context GdkWindow* window GdkGLProfile profile GError** error") ;(CFNC-3.16 "void gtk_css_provider_load_from_resource GtkCssProvider* css_provider gchar* resource_path" 'const) (CFNC-3.16 "void gtk_label_set_xalign GtkLabel* label gfloat xalign") (CFNC-3.16 "gfloat gtk_label_get_xalign GtkLabel* label") (CFNC-3.16 "void gtk_label_set_yalign GtkLabel* label gfloat xalign") (CFNC-3.16 "gfloat gtk_label_get_yalign GtkLabel* label") (CFNC-3.16 "void gtk_paned_set_wide_handle GtkPaned* paned gboolean wide") (CFNC-3.16 "gboolean gtk_paned_get_wide_handle GtkPaned* paned") (CFNC-3.16 "void gtk_scrolled_window_set_overlay_scrolling GtkScrolledWindow* scrolled_window gboolean overlay_scrolling") (CFNC-3.16 "gboolean gtk_scrolled_window_get_overlay_scrolling GtkScrolledWindow* scrolled_window") (CFNC-3.16 "void gtk_text_view_set_monospace GtkTextView* text_view gboolean monospace") (CFNC-3.16 "gboolean gtk_text_view_get_monospace GtkTextView* text_view") (CFNC-3.16 "GtkWidget* gtk_window_get_titlebar GtkWindow* window") (CFNC-3.16 "GtkWidget* gtk_gl_area_new void") (CFNC-3.16 "gboolean gtk_gl_area_get_has_alpha GtkGLArea* area") (CFNC-3.16 "void gtk_gl_area_set_has_alpha GtkGLArea* area gboolean has_alpha") (CFNC-3.16 "gboolean gtk_gl_area_get_has_depth_buffer GtkGLArea* area") (CFNC-3.16 "void gtk_gl_area_set_has_depth_buffer GtkGLArea* area gboolean has_depth_buffer") (CFNC-3.16 "GdkGLContext* gtk_gl_area_get_context GtkGLArea* area") (CFNC-3.16 "void gtk_gl_area_make_current GtkGLArea* area") (CFNC-3.16 "void gtk_render_check GtkStyleContext* context cairo_t* cr gdouble x gdouble y gdouble width gdouble height") (CFNC-3.16 "void gtk_render_option GtkStyleContext* context cairo_t* cr gdouble x gdouble y gdouble width gdouble height") (CFNC-3.16 "void gtk_render_arrow GtkStyleContext* context cairo_t* cr gdouble angle gdouble x gdouble y gdouble size") (CFNC-3.16 "void gtk_render_background GtkStyleContext* context cairo_t* cr gdouble x gdouble y gdouble width gdouble height") (CFNC-3.16 "void gtk_render_frame GtkStyleContext* context cairo_t* cr gdouble x gdouble y gdouble width gdouble height") (CFNC-3.16 "void gtk_render_expander GtkStyleContext* context cairo_t* cr gdouble x gdouble y gdouble width gdouble height") (CFNC-3.16 "void gtk_render_focus GtkStyleContext* context cairo_t* cr gdouble x gdouble y gdouble width gdouble height") (CFNC-3.16 "void gtk_render_layout GtkStyleContext* context cairo_t* cr gdouble x gdouble y PangoLayout* layout") (CFNC-3.16 "void gtk_render_line GtkStyleContext* context cairo_t* cr gdouble x0 gdouble y0 gdouble x1 gdouble y1") (CFNC-3.16 "void gtk_render_slider GtkStyleContext* context cairo_t* cr gdouble x gdouble y gdouble width gdouble height GtkOrientation orientation") (CFNC-3.16 "void gtk_render_frame_gap GtkStyleContext* context cairo_t* cr gdouble x gdouble y gdouble width gdouble height GtkPositionType gap_side gdouble xy0_gap gdouble xy1_gap") (CFNC-3.16 "void gtk_render_extension GtkStyleContext* context cairo_t* cr gdouble x gdouble y gdouble width gdouble height GtkPositionType gap_side") (CFNC-3.16 "void gtk_render_handle GtkStyleContext* context cairo_t* cr gdouble x gdouble y gdouble width gdouble height") (CFNC-3.16 "void gtk_render_activity GtkStyleContext* context cairo_t* cr gdouble x gdouble y gdouble width gdouble height") (CFNC-3.16 "void gtk_render_icon GtkStyleContext* context cairo_t* cr GdkPixbuf* pixbuf gdouble x gdouble y") (CFNC-3.16 "void gtk_render_icon_surface GtkStyleContext* context cairo_t* cr cairo_surface_t* surface gdouble x gdouble y") ;;; 3.15.2 (CFNC-3.16 "GdkVisual* gdk_gl_context_get_visual GdkGLContext* context") (CFNC-3.16 "GdkWindow* gdk_gl_context_get_window GdkGLContext* context") (CFNC-3.16 "void gdk_gl_context_make_current GdkGLContext* context") (CFNC-3.16 "GdkGLContext* gdk_gl_context_get_current void") (CFNC-3.16 "void gdk_gl_context_clear_current void") ;;; 3.15.1: (CFNC-3.16 "void gtk_stack_set_hhomogeneous GtkStack* stack gboolean hhomogeneous") (CFNC-3.16 "gboolean gtk_stack_get_hhomogeneous GtkStack* stack") (CFNC-3.16 "void gtk_stack_set_vhomogeneous GtkStack* stack gboolean vhomogeneous") (CFNC-3.16 "gboolean gtk_stack_get_vhomogeneous GtkStack* stack") ;;; pango 1.36.8 (CINT-3.16 "PANGO_WEIGHT_SEMILIGHT" "PangoWeight") #| ;;; cairo 1.14.0: (CFNC-3.16 "void cairo_surface_set_device_scale cairo_surface_t* surface double x_scale double y_scale") (CFNC-3.16 "void cairo_surface_get_device_scale cairo_surface_t* surface double* [x_scale] double* [y_scale]") |# ;;; 3.15.2: ;(CINT-3.16 "GDK_GL_DISABLE" "GdkGLFlags") ;(CINT-3.16 "GDK_GL_ALWAYS" "GdkGLFlags") ;(CINT-3.16 "GDK_GL_SOFTWARE_DRAW_GL" "GdkGLFlags") ;(CINT-3.16 "GDK_GL_SOFTWARE_DRAW_SURFACE" "GdkGLFlags") ;(CINT-3.16 "GDK_GL_TEXTURE_RECTANGLE" "GdkGLFlags") (CCAST-3.16 "GTK_POPOVER_MENU(object)" "GtkPopoverMenu*") (CCHK-3.16 "GTK_IS_POPOVER_MENU(object)" "GtkPopoverMenu*") (CFNC-3.16 "GdkDisplay* gdk_gl_context_get_display GdkGLContext* context") ;(CFNC-3.16 "GdkGLProfile gdk_gl_context_get_profile GdkGLContext* context") ;(CFNC-3.16 "GdkGLProfile gtk_gl_area_get_profile GtkGLArea* area") ;(CFNC-3.16 "void gtk_gl_area_set_profile GtkGLArea* area GdkGLProfile profile") (CFNC-3.16 "gboolean gtk_gl_area_get_has_stencil_buffer GtkGLArea* area") (CFNC-3.16 "void gtk_gl_area_set_has_stencil_buffer GtkGLArea* area gboolean has_stencil_buffer") (CFNC-3.16 "gboolean gtk_gl_area_get_auto_render GtkGLArea* area") (CFNC-3.16 "void gtk_gl_area_set_auto_render GtkGLArea* area gboolean auto_render") (CFNC-3.16 "void gtk_gl_area_queue_render GtkGLArea* area") (CFNC-3.16 "void gtk_gl_area_attach_buffers GtkGLArea* area") ;(CFNC-3.16 "void gtk_gl_area_set_error GtkGLArea* area GError *error" 'const) (CFNC-3.16 "GError* gtk_gl_area_get_error GtkGLArea* area") (CFNC-3.16 "GtkWidget* gtk_popover_menu_new void") (CFNC-3.16 "void gtk_popover_menu_open_submenu GtkPopoverMenu* popover gchar* name" 'const) ;;; 3.15.3: (CFNC-3.16 "void gtk_entry_grab_focus_without_selecting GtkEntry* entry") (CFNC-3.16 "gboolean gtk_scrollable_get_border GtkScrollable* scrollable GtkBorder* border") (CFNC-3.16 "void gtk_text_buffer_insert_markup GtkTextBuffer* buffer GtkTextIter* iter gchar* markup gint len" 'const) ;(CFNC-3.16 "GActionGroup* gtk_widget_get_action_group GtkWidget* widget gchar* prefix" 'const) ;(CNFC-3.16 "gchar** gtk_widget_list_action_prefixes GtkWidget* widget" 'const) ;;; 3.15.4: (CFNC-3.16 "gchar* gdk_device_get_vendor_id GdkDevice* device" 'const-return) (CFNC-3.16 "gchar* gdk_device_get_product_id GdkDevice* device" 'const-return) (CINT-3.16 "GTK_TEXT_EXTEND_SELECTION_WORD" "GtkTextExtendSelection") (CINT-3.16 "GTK_TEXT_EXTEND_SELECTION_LINE" "GtkTextExtendSelection") ;;; 3.15.5: (CFNC-3.16 "GdkGLContext* gdk_gl_context_get_shared_context GdkGLContext* context") (CFNC-3.16 "void gdk_gl_context_set_required_version GdkGLContext* context int major int minor") (CFNC-3.16 "void gdk_gl_context_get_required_version GdkGLContext* context int* [major] int* [minor]") (CFNC-3.16 "void gdk_gl_context_set_debug_enabled GdkGLContext* context gboolean enabled") (CFNC-3.16 "gboolean gdk_gl_context_get_debug_enabled GdkGLContext* context") (CFNC-3.16 "void gdk_gl_context_set_forward_compatible GdkGLContext* context gboolean compatible") (CFNC-3.16 "gboolean gdk_gl_context_get_forward_compatible GdkGLContext* context") (CFNC-3.16 "gboolean gdk_gl_context_realize GdkGLContext* context GError** [error]") (CFNC-3.16 "GtkClipboard* gtk_clipboard_get_default GdkDisplay* display") (CFNC-3.16 "void gtk_drag_cancel GdkDragContext* context") (CFNC-3.16 "gboolean gtk_search_entry_handle_event GtkSearchEntry* entry GdkEvent* event") ;;; 3.15.7: (CFNC-3.16 "void gdk_gl_context_get_version GdkGLContext* context int* [major] int* [minor]") (CFNC-3.16 "void gtk_gl_area_set_required_version GtkGLArea* area gint major gint minor") (CFNC-3.16 "void gtk_gl_area_get_required_version GtkGLArea* area gint* [major] gint* [minor]") ;(CFNC-3.16 "void gtk_list_box_bind_model GtkListBox* box GListModel* model GtkListBoxCreateWidgetFunc create_widget_func gpointer user_data GDestroyNotify user_data_free_func") (CFNC-3.16 "void gtk_notebook_detach_tab GtkNotebook* notebook GtkWidget* child") (CCAST-3.16 "GTK_STACK_SIDEBAR(object)" "GtkStackSidebar*") (CCHK-3.16 "GTK_IS_STACK_SIDEBAR(object)" "GtkStackSidebar*") (CFNC-3.16 "GtkWidget* gtk_stack_sidebar_new void") (CFNC-3.16 "void gtk_stack_sidebar_set_stack GtkStackSidebar* sidebar GtkStack* stack") (CFNC-3.16 "GtkStack* gtk_stack_sidebar_get_stack GtkStackSidebar* sidebar") ;;; 3.15.8: (CFNC-3.16 "void gtk_popover_set_transitions_enabled GtkPopover* popover gboolean transitions_enabled") (CFNC-3.16 "gboolean gtk_popover_get_transitions_enabled GtkPopover* popover") ;;; 3.16.0 ;;; 3.16.1 ;;; 3.16.2: ;;; 3.17.1 (CFNC-3.18 "gboolean gdk_keymap_get_scroll_lock_state GdkKeymap* keymap") (CFNC-3.18 "void gtk_radio_menu_item_join_group GtkRadioMenuItem* radio_menu_item GtkRadioMenuItem* group_source") ;;; 3.17.2: (CFNC-3.18 "void gtk_font_chooser_set_font_map GtkFontChooser* fontchooser PangoFontMap* fontmap") (CFNC-3.18 "PangoFontMap* gtk_font_chooser_get_font_map GtkFontChooser* fontchooser") (CFNC-3.18 "void gtk_popover_set_default_widget GtkPopover* popover GtkWidget* widget") (CFNC-3.18 "GtkWidget* gtk_popover_get_default_widget GtkPopover* popover") ;;; 3.17.4: (CFNC-3.18 "void gdk_window_set_pass_through GdkWindow* window gboolean pass_through") (CFNC-3.18 "gboolean gdk_window_get_pass_through GdkWindow* window") (CFNC-3.18 "void gtk_overlay_reorder_overlay GtkOverlay* overlay GtkWidget* child gint position") (CFNC-3.18 "gboolean gtk_overlay_get_overlay_pass_through GtkOverlay* overlay GtkWidget* widget") (CFNC-3.18 "void gtk_overlay_set_overlay_pass_through GtkOverlay* overlay GtkWidget* widget gboolean pass_through") (CFNC-3.18 "gboolean gtk_places_sidebar_get_show_recent GtkPlacesSidebar* sidebar") (CFNC-3.18 "void gtk_places_sidebar_set_show_recent GtkPlacesSidebar* sidebar gboolean show_recent") (CFNC-3.18 "void gtk_places_sidebar_set_drop_targets_visible GtkPlacesSidebar* sidebar gboolean visible GdkDragContext* context") ;;; 3.17.5: (CFNC-3.18 "gboolean gtk_places_sidebar_get_show_trash GtkPlacesSidebar* sidebar") (CFNC-3.18 "void gtk_places_sidebar_set_show_trash GtkPlacesSidebar* sidebar gboolean show_trash") (CFNC-3.18 "void gtk_places_sidebar_set_show_other_locations GtkPlacesSidebar* sidebar gboolean show_other_locations") (CFNC-3.18 "gboolean gtk_places_sidebar_get_show_other_locations GtkPlacesSidebar* sidebar") (CFNC-3.18 "void gtk_stack_set_interpolate_size GtkStack* stack gboolean interpolate_size") (CFNC-3.18 "gboolean gtk_stack_get_interpolate_size GtkStack* stack") (CFNC-3.18 "void gtk_widget_set_font_options GtkWidget* widget cairo_font_options_t* options" 'const) (CFNC-3.18 "cairo_font_options_t* gtk_widget_get_font_options GtkWidget* widget" 'const-return) (CFNC-3.18 "void gtk_widget_set_font_map GtkWidget* widget PangoFontMap* fontmap") (CFNC-3.18 "PangoFontMap* gtk_widget_get_font_map GtkWidget* widget") ;;; 3.17.6: (CFNC-3.18 "void gdk_window_fullscreen_on_monitor GdkWindow* window gint monitor") (CFNC-3.18 "void gtk_window_fullscreen_on_monitor GtkWindow* window GdkScreen* screen gint monitor") ;;; 3.17.7: (CINT-3.18 "GDK_TOUCHPAD_SWIPE" "GdkEventType") (CINT-3.18 "GDK_TOUCHPAD_PINCH" "GdkEventType") (CINT-3.18 "GDK_TOUCHPAD_GESTURE_PHASE_BEGIN" "GdkTouchpadGesturePhase") (CINT-3.18 "GDK_TOUCHPAD_GESTURE_PHASE_UPDATE" "GdkTouchpadGesturePhase") (CINT-3.18 "GDK_TOUCHPAD_GESTURE_PHASE_END" "GdkTouchpadGesturePhase") (CINT-3.18 "GDK_TOUCHPAD_GESTURE_PHASE_CANCEL" "GdkTouchpadGesturePhase") (CINT-3.18 "GDK_TOUCHPAD_GESTURE_MASK" "GdkEventMask") ;(CFNC-3.18 "void gtk_flow_box_bind_model GtkFlowBox* box GListModel* model GtkFlowBoxCreateWidgetFunc create_widget_func gpointer user_data GDestroyNotify user_data_free_func") (CFNC-3.18 "void gtk_text_view_set_top_margin GtkTextView* text_view gint top_margin") (CFNC-3.18 "gint gtk_text_view_get_top_margin GtkTextView* text_view") (CFNC-3.18 "void gtk_text_view_set_bottom_margin GtkTextView* text_view gint bottom_margin") (CFNC-3.18 "gint gtk_text_view_get_bottom_margin GtkTextView* text_view") ;;; 3.17.8|9: (CINT-3.18 "GDK_MODIFIER_INTENT_DEFAULT_MOD_MASK" "GdkModifierIntent") ;;; 3.18.0 ;;; 3.18.1 ;;; 3.19.1: (CFNC-3.20 "gboolean gdk_gl_context_is_legacy GdkGLContext* context") (CFNC-3.20 "gboolean gdk_rectangle_equal GdkRectangle* rect1 GdkRectangle*rect2" 'const) (CFNC-3.20 "void gtk_application_window_set_help_overlay GtkApplicationWindow* window GtkShortcutsWindow* help_overlay") ;;; (CFNC-3.20 "GtkShortcutsWindow* gtk_application_window_get_help_overlay GtkApplicationWindow* window") (CFNC-3.20 "void gtk_settings_reset_property GtkSettings* settings gchar* name" 'const) (CFNC-3.20 "void gtk_text_tag_changed GtkTextTag* tag gboolean size_changed") ;;; (CFNC-3.20 "void gtk_widget_class_set_css_name GtkWidgetClass* widget_class char* name" 'const) ;;; (CFNC-3.20 "char* gtk_widget_class_get_css_name GtkWidgetClass* widget_class" 'const-return) (CFNC-3.20 "char* gtk_widget_path_iter_get_object_name GtkWidgetPath* path gint pos" 'const-return) (CFNC-3.20 "void gtk_widget_path_iter_set_object_name GtkWidgetPath* path gint pos char* name" 'const) ;;; 3.19.2: (CFNC-3.20 "void gtk_widget_queue_allocate GtkWidget* widget") (CFNC-3.20 "void gtk_widget_set_focus_on_click GtkWidget* widget gboolean focus_on_click") (CFNC-3.20 "gboolean gtk_widget_get_focus_on_click GtkWidget* widget") (CFNC-3.20 "void gtk_widget_get_allocated_size GtkWidget* widget GtkAllocation* [allocation] int* [baseline]") ;;; 3.19.3: (CINT-3.20 "GTK_SHORTCUT_ACCELERATOR" "GtkShortcutType") (CINT-3.20 "GTK_SHORTCUT_GESTURE_PINCH" "GtkShortcutType") (CINT-3.20 "GTK_SHORTCUT_GESTURE_STRETCH" "GtkShortcutType") (CINT-3.20 "GTK_SHORTCUT_GESTURE_ROTATE_CLOCKWISE" "GtkShortcutType") (CINT-3.20 "GTK_SHORTCUT_GESTURE_ROTATE_COUNTERCLOCKWISE" "GtkShortcutType") (CINT-3.20 "GTK_SHORTCUT_GESTURE_TWO_FINGER_SWIPE_LEFT" "GtkShortcutType") (CINT-3.20 "GTK_SHORTCUT_GESTURE_TWO_FINGER_SWIPE_RIGHT" "GtkShortcutType") (CINT-3.20 "GTK_SHORTCUT_GESTURE" "GtkShortcutType") snd-16.1/tools/gtk-header-diffs0000755000076400007640000000560712625110635014536 0ustar bilbil#!/bin/csh -f set gtkolddir = /home/bil/test/gtk+-3.19.2 set gtknewdir = /home/bil/test/gtk+-3.19.3 set pangoolddir = /home/bil/test/pango-1.36.8 set pangonewdir = /home/bil/test/pango-1.36.8 set glibolddir = /home/bil/test/glib-2.39.3 set glibnewdir = /home/bil/test/glib-2.39.3 set cairoolddir = /home/bil/test/cairo-1.14.0 set caironewdir = /home/bil/test/cairo-1.14.0 set curdir = $cwd date > $curdir/hi echo ' ' >> $curdir/hi chdir $gtknewdir/gdk foreach file (*.h) echo '--------------------------------- ' $file ' --------------------------------' >> $curdir/hi if (-e $gtkolddir/gdk/$file) then diff -bcw $gtkolddir/gdk/$file $gtknewdir/gdk/$file >> $curdir/hi else echo '(new)' >> $curdir/hi endif end chdir $gtknewdir/gtk foreach file (*.h) echo '--------------------------------- ' $file ' --------------------------------' >> $curdir/hi if (-e $gtkolddir/gtk/$file) then diff -bcw $gtkolddir/gtk/$file $gtknewdir/gtk/$file >> $curdir/hi else echo '(new)' >> $curdir/hi endif end chdir $pangonewdir/pango foreach file (*.h) echo '--------------------------------- ' $file ' --------------------------------' >> $curdir/hi if (-e $pangoolddir/pango/$file) then diff -bcw $pangoolddir/pango/$file $pangonewdir/pango/$file >> $curdir/hi else echo '(new)' >> $curdir/hi endif end chdir $glibnewdir/glib foreach file (*.h) echo '--------------------------------- ' $file ' --------------------------------' >> $curdir/hi if (-e $glibolddir/glib/$file) then diff -bcw $glibolddir/glib/$file $glibnewdir/glib/$file >> $curdir/hi else echo '(new)' >> $curdir/hi endif end chdir $glibnewdir/gio foreach file (*.h) echo '--------------------------------- ' $file ' --------------------------------' >> $curdir/hi if (-e $glibolddir/gio/$file) then diff -bcw $glibolddir/gio/$file $glibnewdir/gio/$file >> $curdir/hi else echo '(new)' >> $curdir/hi endif end chdir $glibnewdir/gobject foreach file (*.h) echo '--------------------------------- ' $file ' --------------------------------' >> $curdir/hi if (-e $glibolddir/gobject/$file) then diff -bcw $glibolddir/gobject/$file $glibnewdir/gobject/$file >> $curdir/hi else echo '(new)' >> $curdir/hi endif end chdir $glibnewdir/gmodule foreach file (*.h) echo '--------------------------------- ' $file ' --------------------------------' >> $curdir/hi if (-e $glibolddir/gmodule/$file) then diff -bcw $glibolddir/gmodule/$file $glibnewdir/gmodule/$file >> $curdir/hi else echo '(new)' >> $curdir/hi endif end chdir $caironewdir/src foreach file (*.h) echo '--------------------------------- ' $file ' --------------------------------' >> $curdir/hi if (-e $cairoolddir/src/$file) then diff -bcw $cairoolddir/src/$file $caironewdir/src/$file >> $curdir/hi else echo '(new)' >> $curdir/hi endif end snd-16.1/tools/gcall.c0000644000076400007640000001647112512761112012730 0ustar bilbil/* example main program that calls glistener/s7 */ #include #include #include #include #include #include "s7.h" #include "glistener.h" static s7_scheme *s7; static s7_pointer wrap_glistener(glistener *g) { return(s7_make_c_pointer(s7, (void *)g)); } static glistener *unwrap_glistener(s7_pointer p) { return((glistener *)s7_c_pointer(p)); } static s7_pointer g_evaluate(s7_scheme *sc, s7_pointer args) { char *str; s7_pointer result; str = glistener_evaluate(unwrap_glistener(s7_car(args))); result = s7_make_string(s7, str); if (str) g_free(str); return(result); } static s7_pointer g_complete(s7_scheme *sc, s7_pointer args) { char *str; s7_pointer result; str = glistener_complete(unwrap_glistener(s7_car(args))); result = s7_make_string(s7, str); if (str) g_free(str); return(result); } static s7_pointer g_append_text(s7_scheme *sc, s7_pointer args) { glistener_append_text(unwrap_glistener(s7_car(args)), s7_string(s7_cadr(args))); return(s7_cadr(args)); } static s7_pointer g_insert_text(s7_scheme *sc, s7_pointer args) { glistener_insert_text(unwrap_glistener(s7_car(args)), s7_string(s7_cadr(args))); return(s7_cadr(args)); } static s7_pointer g_scroll_to_end(s7_scheme *sc, s7_pointer args) { glistener_scroll_to_end(unwrap_glistener(s7_car(args))); return(s7_car(args)); } static s7_pointer g_append_prompt(s7_scheme *sc, s7_pointer args) { glistener_append_prompt(unwrap_glistener(s7_car(args))); return(s7_car(args)); } static s7_pointer g_prompt_position(s7_scheme *sc, s7_pointer args) { return(s7_make_integer(s7, glistener_prompt_position(unwrap_glistener(s7_car(args))))); } static s7_pointer g_cursor_position(s7_scheme *sc, s7_pointer args) { return(s7_make_integer(s7, glistener_cursor_position(unwrap_glistener(s7_car(args))))); } static s7_pointer g_set_cursor_position(s7_scheme *sc, s7_pointer args) { glistener_set_cursor_position(unwrap_glistener(s7_car(args)), s7_integer(s7_cadr(args))); return(s7_cadr(args)); } static s7_pointer g_text(s7_scheme *sc, s7_pointer args) { char *str; s7_pointer result; str = glistener_text(unwrap_glistener(s7_car(args)), s7_integer(s7_cadr(args)), s7_integer(s7_caddr(args))); result = s7_make_string(s7, str); if (str) g_free(str); return(result); } static s7_pointer g_clear(s7_scheme *sc, s7_pointer args) { glistener_clear(unwrap_glistener(s7_car(args))); return(s7_car(args)); } static s7_pointer g_set_prompt(s7_scheme *sc, s7_pointer args) { glistener_set_prompt(unwrap_glistener(s7_car(args)), s7_string(s7_cadr(args))); return(s7_cadr(args)); } static void glistener_init(glistener *g1, glistener *g2) { s7_define_function(s7, "append-text", g_append_text, 2, 0, false, "(append-text g txt)"); s7_define_function(s7, "insert-text", g_insert_text, 2, 0, false, "(insert-text g txt)"); s7_define_function(s7, "cursor-position", g_cursor_position, 1, 0, false, "(cursor-position g)"); s7_define_function(s7, "set-cursor-position", g_set_cursor_position, 2, 0, false, "(set-cursor-position g pos)"); s7_define_function(s7, "text", g_text, 3, 0, false, "(text g start end)"); s7_define_function(s7, "append-prompt", g_append_prompt, 1, 0, false, "(append-prompt g)"); s7_define_function(s7, "prompt-position", g_prompt_position, 1, 0, false, "(prompt-position g)"); s7_define_function(s7, "set-prompt", g_set_prompt, 2, 0, false, "(set-prompt g str)"); s7_define_function(s7, "evaluate", g_evaluate, 1, 0, false, "(evaluate g)"); s7_define_function(s7, "complete", g_complete, 1, 0, false, "(complete g)"); s7_define_function(s7, "scroll", g_scroll_to_end, 1, 0, false, "(scroll g)"); s7_define_function(s7, "clear", g_clear, 1, 0, false, "(clear g)"); s7_define_variable(s7, "*g1*", wrap_glistener(g1)); s7_define_variable(s7, "*g2*", wrap_glistener(g2)); } static GdkCursor *arrow_cursor; static glistener *g1, *g2; static gint quit_repl(GtkWidget *w, GdkEvent *event, gpointer context) {exit(0);} static void evaluator(glistener *g, const char *text) { int gc_loc; s7_pointer old_port, result; const char *errmsg = NULL; char *msg = NULL; old_port = s7_set_current_error_port(s7, s7_open_output_string(s7)); gc_loc = s7_gc_protect(s7, old_port); result = s7_eval_c_string(s7, text); errmsg = s7_get_output_string(s7, s7_current_error_port(s7)); if ((errmsg) && (*errmsg)) { msg = (char *)calloc(strlen(errmsg) + 1, sizeof(char)); strcpy(msg, errmsg); glistener_set_cursor_shape(g1, arrow_cursor); /* make sure we undo the wait cursor if an error occurred */ glistener_set_cursor_shape(g2, arrow_cursor); } s7_close_output_port(s7, s7_current_error_port(s7)); s7_set_current_error_port(s7, old_port); s7_gc_unprotect_at(s7, gc_loc); glistener_append_text(g, "\n"); if (msg) glistener_append_text(g, msg); else { msg = s7_object_to_c_string(s7, result); glistener_append_text(g, msg); } if (msg) free(msg); glistener_append_prompt(g); } static void listener_init(glistener *g, GtkWidget *w) { unsigned char prompt[4] = {0xce, 0xbb, '>', '\0'}; /* lambda as prompt */ GtkTextBuffer *buffer; buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(w)); glistener_set_font(g, pango_font_description_from_string("Monospace 10")); glistener_set_prompt_tag(g, gtk_text_buffer_create_tag(buffer, "glistener_prompt_tag", "weight", PANGO_WEIGHT_BOLD, "foreground", "red", NULL)); glistener_set_prompt(g, prompt); } static const char *helper(glistener *g, const char *text) { s7_pointer sym; sym = s7_symbol_table_find_name(s7, text); if (sym) return(s7_help(s7, sym)); glistener_clear_status(g); return(NULL); } static void completer(glistener *g, bool (*symbol_func)(const char *symbol_name, void *data), void *data) { s7_for_each_symbol_name(s7, symbol_func, data); } int main(int argc, char **argv) { GtkWidget *shell, *frame1, *frame2, *vb; s7 = s7_init(); gtk_init(&argc, &argv); shell = gtk_window_new(GTK_WINDOW_TOPLEVEL); g_signal_connect(G_OBJECT(shell), "delete_event", G_CALLBACK(quit_repl), NULL); #if (!GTK_CHECK_VERSION(3, 0, 0)) vb = gtk_vbox_new(false, 0); #else vb = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); #endif gtk_container_add(GTK_CONTAINER(shell), vb); gtk_widget_show(vb); frame1 = gtk_frame_new(NULL); gtk_frame_set_shadow_type(GTK_FRAME(frame1), GTK_SHADOW_ETCHED_IN); gtk_widget_show(frame1); gtk_container_add(GTK_CONTAINER(vb), frame1); frame2 = gtk_frame_new(NULL); gtk_frame_set_shadow_type(GTK_FRAME(frame2), GTK_SHADOW_ETCHED_IN); gtk_widget_show(frame2); gtk_container_add(GTK_CONTAINER(vb), frame2); g1 = glistener_new(frame1, listener_init); glistener_set_evaluator(g1, evaluator); glistener_set_helper(g1, helper); glistener_set_completer(g1, completer); g2 = glistener_new(frame2, listener_init); glistener_set_evaluator(g2, evaluator); glistener_set_helper(g2, helper); glistener_set_completer(g2, completer); glistener_init(g1, g2); arrow_cursor = GDK_CURSOR_NEW(GDK_LEFT_PTR); gtk_widget_show(shell); gdk_window_resize(gtk_widget_get_window(shell), 500, 700); gtk_main(); } /* in gtk-2: gcc gcall.c -o gcall s7.o glistener.o `pkg-config --libs gtk+-2.0 --cflags` -lm -ldl in gtk-3: gcc gcall.c -o gcall s7.o glistener.o `pkg-config --libs gtk+-3.0 --cflags` -lm -ldl */ snd-16.1/tools/crossref.c0000644000076400007640000006047612622067377013516 0ustar bilbil/* gcc -o crossref crossref.c -O2 -Wall */ #include #include #include #include #include #include #include #include #include #if 1 /* this is almost four times faster */ static bool local_strcmp(const char *s1, const char *s2) { unsigned char c1, c2; while (true) { c1 = (unsigned char) *s1++; c2 = (unsigned char) *s2++; if (c1 != c2) return(false); if (c1 == '\0') break; } return(true); } #else #define local_strcmp(S1, S2) (strcmp(S1, S2) == 0) #endif char **names; char **hnames; char **nnames; char **files; char **headers; char **defs; int **counts; char ***lines; #define MAX_LINES 16 int *voids; int *results; int *procs; int names_size = 0, names_ctr = 0; int files_size = 0, files_ctr = 0; int headers_size = 0, headers_ctr = 0, nname_ctr = 0; int snd_xen_c = -1; int snd_noxen_c = -1; int snd_nogui_c = -1; char *mus_strdup(char *str) { char *newstr = NULL; if (str) { newstr = (char *)calloc(strlen(str) + 1, sizeof(char)); strcpy(newstr,str); } return(newstr); } void add_header(char *name) { headers[headers_ctr++] = mus_strdup(name); if (headers_ctr == headers_size) fprintf(stderr,"oops headers"); } int add_name(char *name, char *hdr) { int i; if (name == NULL) return(-1); if ((isdigit(name[0])) || (strlen(name) == 1)) return(-1); /* if (isupper(name[0])) return(-1); */ if (name[0] == '_') return(-1); if ((local_strcmp(hdr, "snd-nogui0.h")) || (local_strcmp(hdr, "snd-nogui1.h"))) nnames[nname_ctr++] = name; for (i = 0; i < names_ctr; i++) if (local_strcmp(names[i], name)) return(-1); hnames[names_ctr] = hdr; names[names_ctr++] = name; if (names_ctr == names_size) fprintf(stderr,"oops names"); return(names_ctr - 1); } int in_nogui_h(char *name) { int i; for (i = 0; i < nname_ctr; i++) if (local_strcmp(name, nnames[i])) return(1); return(0); } void add_file(char *name) { if (local_strcmp(name,"snd-xen.c")) snd_xen_c = files_ctr; if (local_strcmp(name,"snd-nogui.c")) snd_nogui_c = files_ctr; files[files_ctr++] = mus_strdup(name); if (files_ctr == files_size) fprintf(stderr,"oops files"); } static int add_count(char *name, int curfile) { int i; for (i = 0; i < names_ctr; i++) if (local_strcmp(names[i], name)) { if (counts[i] == NULL) counts[i] = (int *)calloc(files_size, sizeof(int)); counts[i][curfile] += 1; return(i); } return(-1); } static void add_def(char *name, int curfile) { int i; for (i = 0; i < names_ctr; i++) if (local_strcmp(names[i], name)) { if (!(defs[i])) defs[i] = strdup(files[curfile]); return; } } /* #define MAX_CHARS 1048576 */ #define MAX_CHARS 8388608 /* xg.c is 3.2 Mb */ static char *get_call(char *input, int input_loc, int curname_len, char *curname, int chars, char *filename) { int start = 0, end = 0, i; for (i = input_loc - curname_len; i >= 0; i--) if (input[i] == '\n') { start = i + 1; break; } if (start == 0) { if (input[0] == '_') return(NULL); /* fprintf(stderr, "%s: %s at %d found no begin cr\n", filename, curname, input_loc); */ } for (i = input_loc; i < chars; i++) { if (input[i] == ')') { end = i + 1; break; } if (input[i] == '\n') { end = i; break; } } if (end == 0) fprintf(stderr, "%s at %d found no end\n", curname, input_loc); if ((start != 0) && (end > start)) { char *value; int n, k, m; m = strlen(filename); value = (char *)calloc(end - start + 1 + m + 4, sizeof(char)); for (n = 0; n < m; n++) value[n] = filename[n]; value[n++] = ' '; value[n++] = ':'; value[n++] = ' '; k = n; for (n = start; n < end; n++, k++) value[k] = input[n]; return(value); } return(NULL); } static int get_result(char *input, int input_loc, int curname_len) { int i; for (i = input_loc - curname_len; i >= 0; i--) { if ((input[i] == '=') || (input[i] == '(') || (input[i] == ',')) return(1); if ((input[i] == '+') || (input[i] == '-') || (input[i] == '*') || (input[i] == '/')) return(1); if ((input[i] == '&') || (input[i] == '|') || (input[i] == '^') || (input[i] == '!') || (input[i] == '?')) return(1); if ((input[i] == ';') || (input[i] == '{')) return(0); if ((input[i] == ')') && (input[i - 1] != '*')) return(0); } return(1); } typedef struct { char *name, *hname, *def; int i, calls, v, results, proc; } qdata; static int greater_compare(const void *a, const void *b) { qdata *d1 = *(qdata **)a; qdata *d2 = *(qdata **)b; if (d1->calls > d2->calls) return(1); else { if (d1->calls == d2->calls) return(0); else return(-1); } } #define NAME_SIZE 8192 #define ID_SIZE 16384 int main(int argc, char **argv) { int i, j, fd, chars, k, in_comment = 0, in_cpp_comment = 0, in_white = 0, calls = 0, in_parens = 0, in_quotes = 0, in_define = 0, in_curly = 0, in_enum = 0; int maxc[NAME_SIZE], maxf[NAME_SIZE], maxg[NAME_SIZE], mcalls[NAME_SIZE]; qdata **qs; char input[MAX_CHARS]; char curname[ID_SIZE]; FILE *FD = NULL; names_size = NAME_SIZE; names = (char **)calloc(names_size, sizeof(char *)); hnames = (char **)calloc(names_size, sizeof(char *)); nnames = (char **)calloc(names_size, sizeof(char *)); defs = (char **)calloc(names_size, sizeof(char *)); voids = (int *)calloc(names_size, sizeof(int)); files_size = 256; files = (char **)calloc(files_size, sizeof(char *)); headers_size = 32; headers = (char **)calloc(headers_size, sizeof(char *)); counts = (int **)calloc(names_size, sizeof(int *)); lines = (char ***)calloc(names_size, sizeof(char **)); results = (int *)calloc(names_size, sizeof(int)); procs = (int *)calloc(names_size, sizeof(int)); add_header("sndlib.h"); add_header("clm.h"); add_header("vct.h"); add_header("sndlib2xen.h"); add_header("clm2xen.h"); add_header("snd.h"); add_header("glistener.h"); #if 1 add_header("snd-strings.h"); add_header("sndlib-strings.h"); add_header("clm-strings.h"); #endif add_header("snd-0.h"); add_header("snd-1.h"); add_header("snd-x0.h"); add_header("snd-x1.h"); add_header("snd-g0.h"); add_header("snd-g1.h"); add_header("snd-nogui0.h"); add_header("snd-nogui1.h"); add_header("libclm.def"); add_header("snd-menu.h"); add_header("snd-file.h"); add_header("s7.h"); add_file("s7.c"); /* add_file("xen.h"); */ /* add_file("snd.h"); */ /* these need to be last */ add_header("xen.h"); add_header("mus-config.h.in"); add_file("glistener.c"); add_file("headers.c"); add_file("audio.c"); add_file("io.c"); add_file("sound.c"); add_file("clm.c"); add_file("vct.c"); add_file("sndlib2xen.c"); add_file("clm2xen.c"); add_file("snd-io.c"); add_file("snd-utils.c"); add_file("snd-completion.c"); add_file("snd-menu.c"); add_file("snd-draw.c"); add_file("snd-axis.c"); add_file("snd-data.c"); add_file("snd-fft.c"); add_file("snd-marks.c"); add_file("snd-file.c"); add_file("snd-edits.c"); add_file("snd-chn.c"); add_file("snd-sig.c"); add_file("snd-kbd.c"); add_file("snd-dac.c"); add_file("snd-region.c"); add_file("snd-select.c"); add_file("snd-find.c"); add_file("snd-snd.c"); add_file("snd-help.c"); add_file("snd-main.c"); add_file("snd-print.c"); add_file("snd-trans.c"); add_file("snd-mix.c"); add_file("snd.c"); add_file("snd-env.c"); add_file("snd-xen.c"); add_file("snd-ladspa.c"); add_file("snd-motif.c"); add_file("snd-listener.c"); add_file("snd-xref.c"); add_file("snd-gxbitmaps.c"); add_file("snd-gxcolormaps.c"); add_file("snd-gutils.c"); add_file("snd-ghelp.c"); add_file("snd-gfind.c"); add_file("snd-gmenu.c"); add_file("snd-gdraw.c"); add_file("snd-glistener.c"); add_file("snd-gchn.c"); add_file("snd-gsnd.c"); add_file("snd-gregion.c"); add_file("snd-gmain.c"); add_file("snd-gmix.c"); add_file("snd-genv.c"); add_file("snd-gfft.c"); add_file("snd-gfile.c"); add_file("snd-gprefs.c"); add_file("snd-prefs.c"); add_file("snd-nogui.c"); add_file("xen.c"); add_file("xm.c"); add_file("gl.c"); add_file("xg.c"); add_file("cmus.c"); add_file("ffi.lisp"); add_file("sndlib2clm.lisp"); add_file("run.lisp"); add_file("clm1.lisp"); add_file("sndins/sndins.c"); add_file("ffitest.c"); add_file("tools/gcall.c"); add_file("/home/bil/test/s7webserver/s7webserver.cpp"); add_file("/home/bil/test/radium-3.4.2/embedded_scheme/scheme.cpp"); add_file("/home/bil/test/cm308/cm-3.8.0/src/CmSupport.cpp"); add_file("/home/bil/test/cm308/cm-3.8.0/src/Scheme.cpp"); add_file("/home/bil/test/cm308/cm-3.8.0/src/SndLib.cpp"); add_file("/home/bil/test/cm308/cm-3.8.0/src/SndLibBridge.cpp"); add_file("/home/bil/test/cm390/cm/src/CmSupport.cpp"); add_file("/home/bil/test/cm390/cm/src/Scheme.cpp"); add_file("/home/bil/test/cm390/cm/src/SndLib.cpp"); add_file("/home/bil/test/cm390/cm/src/SndLibBridge.cpp"); add_file("/home/bil/test/cm390/cm/src/s7.cpp"); add_file("/home/bil/test/cm390/cm/src/Osc.cpp"); add_file("/home/bil/test/cm390/cm/src/SchemeSources.cpp"); for (i = 0; i < headers_ctr; i++) { k = 0; in_quotes = 0; in_white = 0; in_parens = 0; in_comment = 0; in_cpp_comment = 0; fd = open(headers[i], O_RDONLY, 0); if (fd == -1) fprintf(stderr, "can't find %s\n", headers[i]); else { do { chars = read(fd, input, MAX_CHARS); for (j = 0; j < chars; j++) { if ((in_comment == 0) && (in_cpp_comment == 0) && (in_curly == 0)) { if ((isalpha(input[j])) || (isdigit(input[j])) || (input[j] == '_')) { in_white = 0; if (k < ID_SIZE) curname[k++] = input[j]; else fprintf(stderr, "0: curname overflow: %s[%d]: %s%c\n", headers[i], j, curname, input[j]); } else { in_white = 1; if (k < ID_SIZE) curname[k] = 0; else fprintf(stderr, "1: curname overflow: %s[%d]: %s\n", headers[i], j, curname); /* fprintf(stderr, "%s name: %s %d %d %d\n", headers[i], curname, k, in_parens, in_quotes); */ if ((k > 0) && (in_parens == 0) && (in_quotes == 0)) { int loc; loc = add_name(mus_strdup(curname), headers[i]); if (loc >= 0) { int start, n, maybe_proc = 1; for (n = 0; n < k; n++) if (isupper(curname[n])) { maybe_proc = 0; break; } if ((maybe_proc) && ((input[j] == '(') || ((input[j] == ' ') && (input[j + 1] == '(')))) procs[loc] = maybe_proc; else procs[loc] = 0; start = j - strlen(curname) - 6; if (start >= 0) { int m; for (m = 0; m < 3; m++) if (strncmp((char *)(input + start + m), "void", 4) == 0) { voids[loc] = 1; break; } } } } /* else if (k > 0) fprintf(stderr,"drop %s %d %d\n",curname, in_parens, in_quotes); */ k = 0; if ((input[j] == '/') && (input[j + 1] == '*')) in_comment = 1; else { if ((input[j] == '/') && (input[j + 1] == '/')) in_cpp_comment = 1; else { if (input[j] == '#') in_define = 1; else { if ((input[j] == '{') && ((j < 6) || (strncmp((input + (j - 5)), "enum", 4) != 0))) in_curly = 1; else { if (input[j] == '(') in_parens++; if (input[j] == ')') in_parens--; if (input[j] == '"') { if (in_quotes == 1) in_quotes = 0; else in_quotes = 1; } } } } } } } else /* in comment or curly */ { if ((input[j] == '*') && (input[j + 1] == '/')) in_comment = 0; else { if (input[j] == '}') in_curly = 2; else { if (input[j] == ';') in_curly = 0; else { if (input[j] == '\n') in_cpp_comment = 0; } } } } } } while (chars == MAX_CHARS); close(fd); } } FD = fopen("xref.data","w"); if (!FD) fprintf(stderr, "can't write xref.data?"); else { fprintf(stderr, "%d names ", names_ctr); k = 0; in_comment = 0; in_cpp_comment = 0; in_white = 0; in_define = 0; in_enum = 0; for (i = 0; i < files_ctr; i++) { char **all_names = NULL; int all_names_size = 0, all_names_top = 0; int *all_names_counts = NULL; k = 0; fd = open(files[i], O_RDONLY, 0); if (fd == -1) fprintf(stderr, "can't find %s\n", files[i]); else { int curly_ctr = 0, paren_ctr = 0, cancel_define = 0; bool got_macro = false; in_define = 0; if ((local_strcmp(files[i], "sndlib2clm.lisp")) || (local_strcmp(files[i], "ffi.lisp"))) curly_ctr = 1; do { chars = read(fd, input, MAX_CHARS); /* fprintf(stderr,"%s %d\n", files[i], chars); */ for (j = 0; j < chars; j++) { if ((in_comment == 0) && (in_cpp_comment == 0)) { if ((isalpha(input[j])) || (isdigit(input[j])) || (input[j] == '_')) { if (k < ID_SIZE) curname[k++] = input[j]; else fprintf(stderr, "2: curname overflow: %s[%d]: %s\n", files[i], j, curname); } else { if ((input[j] == '/') && (input[j + 1] == '*')) in_comment = 1; else { if ((input[j] == '/') && (input[j + 1] == '/')) in_cpp_comment = 1; else { if ((input[j] == '#') && (((input[j + 1] == 'd') && (input[j + 2] == 'e')) || ((input[j + 1] == 'u') && (input[j + 2] == 'n')))) { in_define = 1; got_macro = false; } else { if ((in_define == 1) && (input[j] == '\n') && (j > 0) && (input[j - 1] != '\\')) { cancel_define = 1; } } if ((in_define == 0) && (j < (chars - 1)) && ((input[j - 1] != '\'') || (input[j + 1] != '\''))) { if (input[j] == '{') { curly_ctr++; if ((j > 4) && (strncmp((input + (j - 5)), "enum", 4) == 0)) in_enum = true; } else { if (input[j] == '}') { curly_ctr--; if (in_enum) in_enum = false; } } } } } if ((input[j + 1] == ' ') && (input[j + 2] == '{') && (input[j + 3] == '}')) { k = 0; } if (k > 0) { if (k < ID_SIZE) curname[k] = 0; else fprintf(stderr, "3: curname overflow: %s[%d]: %s\n", files[i], j, curname); if (true) { bool happy = false; int m; if (all_names == NULL) { all_names_size = 1024; all_names_top = 0; all_names = (char **)calloc(all_names_size, sizeof(char *)); all_names_counts = (int *)calloc(all_names_size, sizeof(int)); } for (m = 0; m < all_names_top; m++) if (local_strcmp(curname, all_names[m])) { happy = true; all_names_counts[m]++; } if (((!got_macro) && (in_define == 1) && (!local_strcmp(curname, "define")) && (!local_strcmp(curname, "undef"))) || (in_enum)) { got_macro = true; if (!happy) { all_names[all_names_top++] = strdup(curname); got_macro = true; if (all_names_top == all_names_size) { all_names_size *= 2; all_names = (char **)realloc(all_names, all_names_size * sizeof(char *)); all_names_counts = (int *)realloc(all_names_counts, all_names_size * sizeof(int)); for (m = all_names_top; m < all_names_size; m++) { all_names[m] = NULL; all_names_counts[m] = 0; } } } } } if ((k < ID_SIZE) && (curly_ctr == 0) && (paren_ctr <= 0)) { add_def(curname, i); } if ((k < ID_SIZE) && ((curly_ctr > 0) || (in_define == 1) || (paren_ctr > 0))) { int loc; loc = add_count(curname, i); if (loc >= 0) { if (procs[loc]) results[loc] += get_result(input, j, k); if (lines[loc] == NULL) { lines[loc] = (char **)calloc(MAX_LINES, sizeof(char *)); lines[loc][0] = get_call(input, j, k, curname, chars, files[i]); } else { int m; for (m = 0; m < MAX_LINES; m++) if (lines[loc][m] == NULL) { lines[loc][m] = get_call(input, j, k, curname, chars, files[i]); break; } } } } k = 0; } if (cancel_define == 1) { cancel_define = 0; in_define = 0; } } if (input[j] == '(') paren_ctr++; else if (input[j] == ')') paren_ctr--; } else { if ((input[j] == '*') && (input[j + 1] == '/')) in_comment = 0; else { if (input[j] == '\n') in_cpp_comment = 0; } } } } while (chars == MAX_CHARS); close(fd); { int m; bool name_printed = false; for (m = 0; m < all_names_top; m++) if ((all_names_counts[m] == 0) && (all_names[m][0] != '_') && (((all_names[m][0] != 'Q') && (all_names[m][0] != 'H')) || (all_names[m][1] != '_'))) { if (!name_printed) { fprintf(FD, "\n%s: ", files[i]); name_printed = true; } fprintf(FD, "%s ", all_names[m]); } for (m = 0; m < all_names_top; m++) if (all_names[m]) free(all_names[m]); if (all_names) free(all_names); if (all_names_counts) free(all_names_counts); all_names = NULL; all_names_counts = NULL; all_names_size = 0; all_names_top = 0; } } } for (i = 0; i < names_ctr; i++) { maxc[i] = 0; maxf[i] = 0; maxg[i] = 0; for (j = 0; j < files_ctr; j++) if ((counts[i]) && (counts[i][j] > 0)) { maxc[i] += counts[i][j]; maxf[i]++; if ((j == snd_xen_c) || (j == snd_nogui_c)) maxg[i]++; } } for (i = 0; i < names_ctr; i++) { calls = 0; if (counts[i]) for (j = 0; j < files_ctr; j++) calls += counts[i][j]; mcalls[i] = calls; } qs = (qdata **)calloc(NAME_SIZE, sizeof(qdata *)); for (i = 0; i < names_ctr; i++) { qdata *q; q = calloc(1, sizeof(qdata)); qs[i] = q; q->i = i; q->v = voids[i]; q->name = names[i]; q->def = defs[i]; q->hname = hnames[i]; q->calls = mcalls[i]; q->results = results[i]; q->proc = procs[i]; } qsort((void *)qs, names_ctr, sizeof(qdata *), greater_compare); for (i = 0; i < names_ctr; i++) { bool menu_case, file_case, nonogui_case, static_case, x_case = true, ffitest_case; int menu_count = 0, file_count = 0, rec_count = 0, x_count = 0; int nfiles; nfiles = 0; /* try to get rid of a bunch of annoying false positives */ if ((local_strcmp(qs[i]->hname, "xen.h")) || (local_strcmp(qs[i]->hname, "mus-config.h.in")) || (qs[i]->name[0] == '_') || ((qs[i]->name[strlen(qs[i]->name) - 2] == '_') && ((qs[i]->name[strlen(qs[i]->name) - 1] == 't') || (qs[i]->name[strlen(qs[i]->name) - 1] == 'H')))) /* SND_0_H etc */ { } else { if (qs[i]->def) fprintf(FD, "\n\n%s: %d [%s, %s]", qs[i]->name, qs[i]->calls, qs[i]->hname, qs[i]->def); else fprintf(FD, "\n\n%s: %d [%s, ]", qs[i]->name, qs[i]->calls, qs[i]->hname); if (qs[i]->v) { fprintf(FD, " (void)"); } else { if ((qs[i]->results == 0) && (qs[i]->proc > 0) && (qs[i]->calls > 0) && (strncmp(qs[i]->name, "set_", 4) != 0) && (strncmp(qs[i]->name, "in_set_", 7) != 0)) fprintf(FD, " (not void but result not used?)"); } if (qs[i]->calls == 0) { char buf1[512], buf2[512]; snprintf(buf1, 512, "fgrep -q %s xen.h", qs[i]->name); snprintf(buf2, 512, "fgrep -q %s s7.html", qs[i]->name); if (system((const char *)buf1) == 0) { if (system((const char *)buf2) == 0) fprintf(FD, " (used in xen.h and s7.html)"); else fprintf(FD, " (used in xen.h)"); } else { if (system((const char *)buf2) == 0) fprintf(FD, " (used in s7.html)"); } } menu_case = (!local_strcmp(qs[i]->hname, "snd-menu.h")); file_case = (!local_strcmp(qs[i]->hname, "snd-file.h")); static_case = ((qs[i]->def != NULL) && (qs[i]->calls > 0)); ffitest_case = ((qs[i]->def != NULL) && (qs[i]->calls > 0)); menu_count = 0; file_count = 0; rec_count = 0; nonogui_case = in_nogui_h(qs[i]->name); if ((nonogui_case) && (counts[qs[i]->i])) { /* fprintf(stderr, "%s...", qs[i]->name); */ for (j = 0; j < files_ctr; j++) if ((counts[qs[i]->i][j] > 0) && ((local_strcmp(files[j], "snd-xen.c")) || ((!local_strcmp(files[j], "snd-nogui.c")) && (!local_strcmp(files[j], "snd-motif.c")) && (strncmp(files[j], "snd-g", 5) != 0)))) { /* fprintf(stderr,"in %s\n", files[j]); */ nonogui_case = false; break; } /* if (nonogui_case) fprintf(stderr, "!\n"); */ } for (j = 0; j < files_ctr; j++) { if ((counts[qs[i]->i]) && (counts[qs[i]->i][j] > 0)) { if ((ffitest_case) && (!local_strcmp(files[j], "ffitest.c"))) ffitest_case = false; if (menu_case) { if ((!local_strcmp(files[j], "snd-menu.c")) && (!local_strcmp(files[j], "snd-motif.c")) && (!local_strcmp(files[j], "snd-gmenu.c"))) { if (!local_strcmp(files[j], "snd-nogui.c")) menu_case = false; } else menu_count++; } if (x_case) { if (((!local_strcmp(files[j], "snd-motif.c")) && (strncmp(files[j], "snd-g", 5) != 0)) || (local_strcmp(files[j], "snd-xen.c"))) x_case = false; else x_count++; } if (file_case) { if ((!local_strcmp(files[j], "snd-file.c")) && (!local_strcmp(files[j], "snd-motif.c")) && (!local_strcmp(files[j], "snd-gfile.c"))) { if (!local_strcmp(files[j], "snd-nogui.c")) file_case = false; } else file_count++; } if ((static_case) && (!local_strcmp(files[j], qs[i]->def)) && (!local_strcmp(files[j], "snd-nogui.c"))) { if (((local_strcmp(files[j], "snd-motif.c")) || (strncmp(files[j], "snd-g", 5) == 0)) && ((local_strcmp(qs[i]->def, "snd-motif.c")) || (strncmp(qs[i]->def, "snd-g", 5) == 0)) && (local_strcmp((const char *)(files[j] + 5), (const char *)(qs[i]->def + 5)))) { } else static_case = false; } fprintf(FD,"\n %s: %d", files[j], counts[qs[i]->i][j]); nfiles++; } } if (ffitest_case) { char buf1[512], buf2[512]; snprintf(buf1, 512, "fgrep -q %s xen.h", qs[i]->name); snprintf(buf2, 512, "fgrep -q %s s7.html", qs[i]->name); if ((system((const char *)buf1) != 0) && (system((const char *)buf2) != 0)) fprintf(FD, "\njust ffitest!"); } if ((menu_case) && (menu_count > 0) && ((!(qs[i]->def)) || (local_strcmp(qs[i]->def, "snd-menu.c")) || (local_strcmp(qs[i]->def, "snd-motif.c")) || (local_strcmp(qs[i]->def, "snd-gmenu.c")))) fprintf(FD, "\n->SND-MENU.H\n"); if ((file_case) && (file_count > 0) && ((!(qs[i]->def)) || (local_strcmp(qs[i]->def, "snd-file.c")) || (local_strcmp(qs[i]->def, "snd-motif.c")) || (local_strcmp(qs[i]->def, "snd-gfile.c")))) fprintf(FD, "\n->SND-FILE.H\n"); if ((x_case) && (x_count > 0) && (qs[i]->def) && (local_strcmp(qs[i]->hname, "snd-1.h")) && (!local_strcmp(qs[i]->def, "snd-xen.c")) && ((local_strcmp(qs[i]->def, "snd-motif.c")) || (strncmp(qs[i]->def, "snd-g", 5) == 0))) fprintf(FD, "\n (all within gui)\n"); if (nonogui_case) fprintf(FD, "\nnot needed in snd-nogui?\n"); if (static_case) fprintf(FD, "\ncould be static?\n"); { int m; if ((nfiles > 0) && (lines[qs[i]->i])) { fprintf(FD, "\n"); for (m = 0; m < MAX_LINES; m++) { if (lines[qs[i]->i][m] == NULL) break; fprintf(FD, "\n %s", lines[qs[i]->i][m]); } } } fprintf(FD, "\n----------------"); } } fclose(FD); } return(0); } snd-16.1/tools/README0000644000076400007640000000201512447302354012355 0ustar bilbilThis directory contains various random scripts, scraps, snippets; a collection of tools used in Snd maintenance and development. The interested reader needs to keep in mind that these are quick hacks to do boring tasks; they are not intended for enshrinement in the Smithsonian. Contents: va.scm Check for common spelling mistakes, lack of trailing NULLs, etc. compsnd Run a bazillion configuration/compilation tests testsnd Run a bazillion tests gtk-headers-diffs Find changes in Gtk headers (for xgdata.scm) sarchive Update backup directory, report changes table.scm make snd-test contents list nor.scm change \r\n to \n crossref.c simple-minded cross referencer makexg.scm + xgdata.scm Build xg.c makegl.scm + gldata.scm Build gl.c make-index.scm Build index.html, snd-xref.c, elaborate html error checking snd.supp Valgrind suppressions make-snd-diffs exs7.c some s7 examples (extracted from s7.h) sam.c Samson box emulator snd-16.1/tools/make-index.scm0000644000076400007640000016444012620215654014235 0ustar bilbil;;; make-index.scm translated from index.cl ;;; run this -noinit so that loads in ~/.snd_s7 don't confuse matters (if (provided? 'pure-s7) (define (char-ci=? . chars) (apply char=? (map char-upcase chars)))) ;(set! (hook-functions *load-hook*) (list (lambda (hook) (format #t "loading ~S~%" (hook 'name))))) (set! (hook-functions *unbound-variable-hook*) ()) (define scheme-variable-names (let ((h (make-hash-table))) (for-each (lambda (name) (set! (h name) #t)) (list "after-graph-hook" "lisp-graph-hook" "before-transform-hook" "mix-release-hook" "stop-playing-channel-hook" "save-hook" "mus-error-hook" "mouse-enter-graph-hook" "mouse-leave-graph-hook" "open-raw-sound-hook" "select-channel-hook" "after-open-hook" "close-hook" "drop-hook" "update-hook" "just-sounds-hook" "mark-click-hook" "mark-drag-hook" "name-click-hook" "open-hook" "help-hook" "output-comment-hook" "play-hook" "snd-error-hook" "snd-warning-hook" "start-playing-hook" "stop-playing-hook" "stop-playing-region-hook" "mouse-enter-listener-hook" "mouse-leave-listener-hook" "window-property-changed-hook" "select-sound-hook" "print-hook" "exit-hook" "during-open-hook" "transform-hook" "mouse-enter-label-hook" "mouse-leave-label-hook" "initial-graph-hook" "graph-hook" "key-press-hook" "mouse-drag-hook" "mouse-press-hook" "enved-hook" "read-hook" "mouse-click-hook" "new-widget-hook" "mark-hook" "previous-files-select-hook" "dac-hook" "stop-dac-hook" "stop-playing-selection-hook" "after-apply-controls-hook" "draw-mark-hook" "bad-header-hook" "save-state-hook" "new-sound-hook" "color-hook" "orientation-hook" "listener-click-hook" "mix-click-hook" "after-save-state-hook" "mouse-enter-text-hook" "mouse-leave-text-hook" "mix-drag-hook" "start-playing-selection-hook" "selection-changed-hook" "*current-sound*" "before-save-state-hook" "after-save-as-hook" "after-transform-hook" "before-save-as-hook")) h)) (define scheme-constant-names (let ((h (make-hash-table))) (for-each (lambda (name) (set! (h name) #t)) (list "mus-out-format" "mus-unsupported" "mus-next" "mus-aifc" "mus-riff" "mus-rf64" "mus-nist" "mus-raw" "mus-ircam" "mus-aiff" "mus-bicsf" "mus-voc" "mus-svx" "mus-soundfont" "mus-unknown" "mus-bshort" "mus-lshort" "mus-mulaw" "mus-alaw" "mus-byte" "mus-ubyte" "mus-bfloat" "mus-lfloat" "mus-bint" "mus-lint" "mus-bintn" "mus-lintn" "mus-b24int" "mus-l24int" "mus-bdouble" "mus-ldouble" "mus-ubshort" "mus-ulshort" "mus-bdouble-unscaled" "mus-ldouble-unscaled" "mus-bfloat-unscaled" "mus-lfloat-unscaled" "mus-audio-default" "rectangular-window" "hann-window" "welch-window" "parzen-window" "bartlett-window" "hamming-window" "blackman2-window" "blackman3-window" "blackman4-window" "exponential-window" "riemann-window" "kaiser-window" "cauchy-window" "poisson-window" "gaussian-window" "tukey-window" "dolph-chebyshev-window" "samaraki-window" "ultraspherical-window" "blackman5-window" "blackman6-window" "blackman7-window" "blackman8-window" "blackman9-window" "blackman10-window" "rv2-window" "rv3-window" "rv4-window" "zoom-focus-left" "zoom-focus-right" "zoom-focus-active" "zoom-focus-middle" "graph-once" "graph-as-wavogram" "graph-as-sonogram" "graph-as-spectrogram" "cursor-cross" "cursor-line" "graph-lines" "graph-dots" "graph-filled" "graph-dots-and-lines" "graph-lollipops" "x-axis-in-seconds" "x-axis-in-samples" "x-axis-in-beats" "x-axis-in-measures" "x-axis-as-percentage" "show-all-axes" "show-all-axes-unlabelled" "show-no-axes" "show-x-axis" "show-x-axis-unlabelled" "cursor-in-view" "cursor-on-left" "cursor-on-right" "cursor-in-middle" "keyboard-no-action" "fourier-transform" "wavelet-transform" "haar-transform" "cepstrum" "hadamard-transform" "walsh-transform" "autocorrelation" "dont-normalize" "normalize-by-channel" "normalize-by-sound" "normalize-globally" "current-edit-position" "channels-separate" "channels-combined" "channels-superimposed" "speed-control-as-float" "speed-control-as-ratio" "speed-control-as-semitone" "enved-amplitude" "enved-spectrum" "enved-srate" "envelope-linear" "envelope-exponential" "enved-add-point" "enved-delete-point" "enved-move-point" "time-graph" "transform-graph" "lisp-graph" "copy-context" "cursor-context" "selection-context" "mark-context" "mus-interp-all-pass" "mus-interp-bezier" "mus-interp-hermite" "mus-interp-lagrange" "mus-interp-linear" "mus-interp-none" "mus-interp-sinusoidal" "sync-none" "sync-all" "sync-by-sound" )) h)) (define (without-dollar-sign str) (if (char=? (string-ref str 0) #\$) (substring str 1) str)) (define (creation-date) (strftime "%d-%b-%y %H:%M %Z" (localtime (current-time)))) (define (alphanumeric? c) (or (char-alphabetic? c) (char-numeric? c))) (define (find-if pred l) (cond ((null? l) #f) ((pred (car l)) (car l)) (else (find-if pred (cdr l))))) (define* (make-ind name sortby topic file general indexed char) (vector name sortby topic file general indexed char)) (define-expansion (ind-name obj) `(vector-ref ,obj 0)) (define-expansion (ind-sortby obj) `(vector-ref ,obj 1)) (define-expansion (ind-topic obj) `(vector-ref ,obj 2)) (define-expansion (ind-file obj) `(vector-ref ,obj 3)) (define-expansion (ind-general obj) `(vector-ref ,obj 4)) (define-expansion (ind-char obj) `(vector-ref ,obj 6)) (define ind-indexed (dilambda (lambda (obj) (vector-ref obj 5)) (lambda (obj val) (vector-set! obj 5 val)))) (define (html-length str) (if (char-position #\& str) (- (length str) 3) (length str))) (define (remove-all item sequence) (map (lambda (x) (if (eq? x item) (values) x)) sequence)) (define (remove-one item sequence) (let ((got-it #f)) (map (lambda (x) (if (and (not got-it) (eq? x item)) (begin (set! got-it #t) (values)) x)) sequence))) #| (define (count-table commands) (do ((count 0 (+ count 1)) (c (memq 'table commands) (memq 'table (cdr c)))) ((not c) count))) ;;; but sadly the for-each version below is faster. |# (define (count-table commands) (let ((count 0)) (for-each (lambda (c) (if (eq? c 'table) (set! count (+ count 1)))) commands) count)) (define (string" (substring str (+ colonpos 1)) ""))) (make-ind :name line :topic topic :file file :sortby (string-downcase (substring str (+ colonpos 1))))) (begin (let ((def-pos (string-position " class=def" str))) (when def-pos ;(format #t "str: ~S, def-pos: ~A~%" str def-pos) (set! str (string-append "" line))) (set! line (string-append (substring line 0 ipos) (substring line (+ ipos 14) ispos) (substring line (+ ispos 5)))) (if (not line) (format #t " but no for ~A~%" str)))) (let ((hpos (let ((start (string-position "" line start) (string-position "

" line start) (string-position "

" line start) (string-position "

" line start)))))) (when hpos (let ((hspos (let ((start (string-position "" line start) (string-position "

" line start) (string-position "

" line start) (string-position "" line start)))))) (set! line (string-append (substring line 0 hpos) (substring line (+ hpos 4) hspos) (substring line (+ hspos 5)))) (if (not line) (format #t " but no for ~A~%" str))))) (letrec ((search-caps ; caps is the list of names with upper case chars from the make-index-1 invocation ("AIFF" for example) (lambda (ln) (and caps (do ((cap caps (cdr cap))) ((or (null? cap) (string-position (car cap) ln)) (pair? cap))))))) (if (not (search-caps line)) ;; find the first character of the >name< business and downcase it (let ((bpos (char-position #\> line))) (set! (line (+ bpos 1)) (char-downcase (line (+ bpos 1))))))) (let ((bpos (char-position #\> line)) (epos (or (string-position "" line) (string-position "" line) (string-position "" line)))) (make-ind :name line :topic topic :file file :sortby (string-downcase (substring line (+ bpos 1) epos)))))))) (define (create-general str file) (let ((mid (char-position #\: str))) (make-ind :name (string-append "" (substring str (+ mid 1)) "") :topic #f :file file :general #t :sortby (string-downcase (substring str (+ mid 1)))))) (define (scheme->ruby scheme-name) (if (string=? scheme-name "frame*") "frame_multiply" (if (string=? scheme-name "frame+") "frame_add" (if (string=? scheme-name "float-vector*") "float-vector_multiply" (if (string=? scheme-name "float-vector+") "float-vector_add" (if (string=? scheme-name "mixer*") "mixer_multiply" (if (string=? scheme-name "mixer+") "mixer_add" (if (string=? scheme-name "redo") "redo_edit" (if (string=? scheme-name "in") "call_in" (let* ((len (length scheme-name)) (var-case (hash-table-ref scheme-variable-names scheme-name)) (strlen (if var-case (+ len 1) len)) (rb-name (make-string strlen #\space)) (i 0) (j 0)) (if var-case (begin (set! (rb-name 0) #\$) (set! j 1)) (if (hash-table-ref scheme-constant-names scheme-name) (begin (set! (rb-name 0) (char-upcase (scheme-name 0))) (set! i 1) (set! j 1)))) (do () ((>= i len)) (let ((c (scheme-name i))) (if (or (alphanumeric? c) (char=? c #\?) (char=? c #\!)) (begin (set! (rb-name j) c) (set! i (+ i 1)) (set! j (+ j 1))) (if (and (char=? c #\-) (char=? (scheme-name (+ i 1)) #\>)) (begin (set! (rb-name j) #\2) (set! j (+ j 1)) (set! i (+ i 2))) (begin (set! (rb-name j) #\_) (set! i (+ i 1)) (set! j (+ j 1))))))) (if (not (= j strlen)) (substring rb-name 0 j) rb-name))))))))))) (define (clean-up-xref xref file) (let* ((len (length xref)) (outstr (make-string (* len 2) #\space))) (let ((url-str "") (j 0) (need-start #f) (in-bracket #f) (in-href #f) (in-name #f)) (do ((loc 0)) ((>= loc len)) (let* ((leof (or (char-position #\newline xref loc) len)) (href-normal-start (or (string-position ") (begin (set! in-bracket #f) (if in-href (set! in-name #t)) (set! in-href #f))) (case c ((#\<) (if in-name (begin (set! (outstr j) #\}) (set! j (+ j 1)) (set! in-name #f))) (set! in-bracket #t) (if (or (and (< (+ i 7) len) (string=? ") (set! j (+ j 1)) (set! i (+ i 3))))) ; incf'd again below ((#\newline) (set! (outstr j) #\") (set! j (+ j 1)) (set! need-start #t)) (else (if need-start (begin (set! (outstr j) #\,) (set! (outstr (+ j 1)) #\newline) (set! (outstr (+ j 2)) #\space) (set! (outstr (+ j 3)) #\space) (set! (outstr (+ j 4)) #\") (set! j (+ j 5)) (set! need-start #f))) (set! (outstr j) c) (set! j (+ j 1)))) ))) (list (substring outstr 0 j) url-str)))) ;;; -------------------------------------------------------------------------------- ;;; get indexer.data (define-macro (provide sym) ; this picks up most of the (provide ...) statements for the autoloader `(define (,(cadr sym)) ,sym)) (load "ws.scm") ;(load "clm23.scm") ;(load "edit123.scm") ;(load "snd11.scm") (load "analog-filter.scm") ; (load "new-backgrounds.scm") (load "animals.scm") ; (load "new-effects.scm") (load "autosave.scm") (load "noise.scm") (load "binary-io.scm") ;(load "bess1.scm") (load "nrev.scm") ;(load "bess.scm") (load "numerics.scm") (load "big-gens.scm") (load "bird.scm") (load "clean.scm") (load "peak-phases.scm") (load "piano.scm") (load "clm-ins.scm") (load "play.scm") (load "dlocsig.scm") (load "poly.scm") (load "draw.scm") (load "dsp.scm") (load "prc95.scm") ; (load "edit-menu.scm") (load "primes.scm") ; (load "effects-utils.scm") (load "pvoc.scm") (load "enved.scm") (load "rgb.scm") (load "env.scm") (load "examp.scm") (load "rubber.scm") (load "expandn.scm") ;(load "s7-slib-init.scm") (load "extensions.scm") ;(load "s7test.scm") (load "fade.scm") (load "selection.scm") ; (load "fft-menu.scm") (load "singer.scm") ; (load "fmv.scm") (load "freeverb.scm") (load "fullmix.scm") (load "generators.scm") (load "grani.scm") ; (load "gtk-effects.scm") (load "snddiff.scm") ; (load "gtk-effects-utils.scm") ; (load "snd-gl.scm") ; (load "snd-gtk.scm") (load "hooks.scm") ;(load "sndlib-ws.scm") (load "index.scm") ; (load "snd-motif.scm") (load "jcrev.scm") ;(load "snd-test.scm") (load "jcvoi.scm") (load "sndwarp.scm") ; (load "special-menu.scm") (load "maraca.scm") (load "spectr.scm") ; (load "marks-menu.scm") (load "spokenword.scm") (load "marks.scm") (load "stochastic.scm") (load "maxf.scm") (load "strad.scm") ; (load "misc.scm") (load "v.scm") (load "mix.scm") (load "moog.scm") ; (load "xm-enved.scm") (load "musglyphs.scm") (load "zip.scm") (load "nb.scm") (load "write.scm") ;(load "lint.scm") (load "r7rs.scm") (load "cload.scm") (load "stuff.scm") (load "mockery.scm") ;(load "repl.scm") (let ((names (make-hash-table))) (define (where-is func) (let ((addr (with-let (funclet func) __func__))) ;; this misses scheme-side pws because their environment is (probably) the global env (and (pair? addr) (cadr addr)))) (define (apropos-1 e) (for-each (lambda (binding) (if (pair? binding) (let ((symbol (car binding)) (value (cdr binding))) (if (procedure? value) (let ((file (where-is value))) (if (and file (not (member file '("~/.snd_s7" "/home/bil/.snd_s7" "t.scm" "/home/bil/cl/t.scm" "make-index.scm" "/home/bil/cl/make-index.scm")))) (let ((pos (char-position #\/ file))) (if pos (do ((k (char-position #\/ file (+ pos 1)) (char-position #\/ file (+ pos 1)))) ((not k) (set! file (substring file (+ pos 1)))) (set! pos k))) (let ((cur-names (hash-table-ref names file))) (if cur-names (if (not (memq symbol cur-names)) (hash-table-set! names file (cons symbol cur-names))) (hash-table-set! names file (list symbol))))))))))) e)) ;; handle the main macros by hand (for-each (lambda (symbol-and-file) (let ((symbol (car symbol-and-file)) (file (cadr symbol-and-file))) (if (not (file-exists? file)) (format *stderr* ";~S says it is in ~S which does not exist~%" symbol file)) (let ((cur-names (hash-table-ref names file))) (if cur-names (hash-table-set! names file (cons symbol cur-names)) (hash-table-set! names file (list symbol)))))) (list (list '*libm* "libm.scm") (list '*libgdbm* "libgdbm.scm") (list '*libdl* "libdl.scm") (list '*libc* "libc.scm") (list '*libgsl* "libgsl.scm") (list '*repl* "repl.scm") (list 'with-sound "ws.scm") (list 'with-mixed-sound "ws.scm") (list 'with-full-sound "ws.scm") (list 'with-temp-sound "ws.scm") (list 'with-marked-sound "ws.scm") (list 'with-simple-sound "ws.scm") (list 'sound-let "ws.scm") (list 'definstrument "ws.scm") (list 'defgenerator "generators.scm") (list 'channel-sync "extensions.scm") (list 'xe-envelope "xm-enved.scm") (list '*clm-srate* "ws.scm") (list '*clm-file-name* "ws.scm") (list '*clm-channels* "ws.scm") (list '*clm-sample-type* "ws.scm") (list '*clm-header-type* "ws.scm") (list '*clm-verbose* "ws.scm") (list '*clm-play* "ws.scm") (list '*clm-statistics* "ws.scm") (list '*clm-reverb* "ws.scm") (list '*clm-reverb-channels* "ws.scm") (list '*clm-reverb-data* "ws.scm") (list '*clm-table-size* "ws.scm") (list '*clm-file-buffer-size* "ws.scm") (list '*clm-locsig-type* "ws.scm") (list '*clm-clipped* "ws.scm") (list '*clm-array-print-length* "ws.scm") (list '*clm-player* "ws.scm") (list '*clm-notehook* "ws.scm") (list '*clm-with-sound-depth* "ws.scm") (list '*clm-default-frequency* "ws.scm") (list '*clm-delete-reverb* "ws.scm") (list '*to-snd* "ws.scm") (list '*clm-search-list* "ws.scm") (list '*definstrument-hook* "ws.scm") ;; these are hidden in defgenerator (list 'make-abcos "generators.scm") (list 'make-absin "generators.scm") (list 'make-adjustable-oscil "generators.scm") (list 'make-adjustable-sawtooth-wave "generators.scm") (list 'make-adjustable-square-wave "generators.scm") (list 'make-adjustable-triangle-wave "generators.scm") (list 'make-asyfm "generators.scm") (list 'make-bess "generators.scm") (list 'make-blackman "generators.scm") (list 'make-brown-noise "generators.scm") (list 'make-dblsum "generators.scm") (list 'make-eoddcos "generators.scm") (list 'make-ercos "generators.scm") (list 'make-erssb "generators.scm") (list 'make-exponentially-weighted-moving-average "generators.scm") (list 'make-flocsig "generators.scm") (list 'make-fmssb "generators.scm") (list 'make-green-noise "generators.scm") (list 'make-green-noise-interp "generators.scm") (list 'make-izcos "generators.scm") (list 'make-j0evencos "generators.scm") (list 'make-j0j1cos "generators.scm") (list 'make-j2cos "generators.scm") (list 'make-jjcos "generators.scm") (list 'make-jncos "generators.scm") (list 'make-jpcos "generators.scm") (list 'make-jycos "generators.scm") (list 'make-k2cos "generators.scm") (list 'make-k2sin "generators.scm") (list 'make-k2ssb "generators.scm") (list 'make-k3sin "generators.scm") (list 'make-krksin "generators.scm") (list 'make-moving-autocorrelation "generators.scm") (list 'make-moving-fft "generators.scm") (list 'make-moving-length "generators.scm") (list 'make-moving-pitch "generators.scm") (list 'make-moving-rms "generators.scm") (list 'make-moving-scentroid "generators.scm") (list 'make-moving-spectrum "generators.scm") (list 'make-moving-sum "generators.scm") (list 'make-moving-variance "generators.scm") (list 'make-n1cos "generators.scm") (list 'make-nchoosekcos "generators.scm") (list 'make-ncos2 "generators.scm") (list 'make-ncos4 "generators.scm") (list 'make-nkssb "generators.scm") (list 'make-noddcos "generators.scm") (list 'make-noddsin "generators.scm") (list 'make-noddssb "generators.scm") (list 'make-noid "generators.scm") (list 'make-npcos "generators.scm") (list 'make-nrcos "generators.scm") (list 'make-nrsin "generators.scm") (list 'make-nrssb "generators.scm") (list 'make-nsincos "generators.scm") (list 'make-nssb "generators.scm") (list 'make-nxy1cos "generators.scm") (list 'make-nxy1sin "generators.scm") (list 'make-nxycos "generators.scm") (list 'make-nxysin "generators.scm") (list 'make-pink-noise "generators.scm") (list 'make-polyoid "generators.scm") (list 'make-r2k!cos "generators.scm") (list 'make-r2k2cos "generators.scm") (list 'make-rcos "generators.scm") (list 'make-rk!cos "generators.scm") (list 'make-rk!ssb "generators.scm") (list 'make-rkcos "generators.scm") (list 'make-rkoddssb "generators.scm") (list 'make-rksin "generators.scm") (list 'make-rkssb "generators.scm") (list 'make-round-interp "generators.scm") (list 'make-rssb "generators.scm") (list 'make-rxycos "generators.scm") (list 'make-rxysin "generators.scm") (list 'make-safe-rxycos "generators.scm") (list 'make-sinc-train "generators.scm") (list 'make-table-lookup-with-env "generators.scm") (list 'make-tanhsin "generators.scm") (list 'make-wave-train-with-env "generators.scm") (list 'make-waveshape "generators.scm") (list 'make-weighted-moving-average "generators.scm") (list 'nssb? "generators.scm") (list 'nxysin? "generators.scm") (list 'nxycos? "generators.scm") (list 'nxy1cos? "generators.scm") (list 'nxy1sin? "generators.scm") (list 'noddsin? "generators.scm") (list 'noddcos? "generators.scm") (list 'noddssb? "generators.scm") (list 'ncos2? "generators.scm") (list 'npcos? "generators.scm") (list 'nrsin? "generators.scm") (list 'nrcos? "generators.scm") (list 'nrssb? "generators.scm") (list 'nkssb? "generators.scm") (list 'nsincos? "generators.scm") (list 'n1cos? "generators.scm") (list 'rcos? "generators.scm") (list 'rssb? "generators.scm") (list 'rxysin? "generators.scm") (list 'rxycos? "generators.scm") (list 'safe-rxycos? "generators.scm") (list 'ercos? "generators.scm") (list 'erssb? "generators.scm") (list 'eoddcos? "generators.scm") (list 'rkcos? "generators.scm") (list 'rksin? "generators.scm") (list 'rkssb? "generators.scm") (list 'rk!cos? "generators.scm") (list 'rk!ssb? "generators.scm") (list 'r2k!cos? "generators.scm") (list 'k2sin? "generators.scm") (list 'k2cos? "generators.scm") (list 'k2ssb? "generators.scm") (list 'dblsum? "generators.scm") (list 'rkoddssb? "generators.scm") (list 'krksin? "generators.scm") (list 'abcos? "generators.scm") (list 'absin? "generators.scm") (list 'r2k2cos? "generators.scm") (list 'asyfm? "generators.scm") (list 'bess? "generators.scm") (list 'jjcos? "generators.scm") (list 'j0evencos? "generators.scm") (list 'j2cos? "generators.scm") (list 'jpcos? "generators.scm") (list 'jncos? "generators.scm") (list 'j0j1cos? "generators.scm") (list 'jycos? "generators.scm") (list 'blackman "generators.scm") (list 'blackman? "generators.scm") (list 'fmssb? "generators.scm") (list 'k3sin? "generators.scm") (list 'izcos? "generators.scm") (list 'adjustable-square-wave? "generators.scm") (list 'adjustable-triangle-wave? "generators.scm") (list 'adjustable-sawtooth-wave? "generators.scm") (list 'adjustable-oscil? "generators.scm") (list 'round-interp? "generators.scm") (list 'nchoosekcos? "generators.scm") (list 'sinc-train? "generators.scm") (list 'pink-noise? "generators.scm") (list 'brown-noise? "generators.scm") (list 'green-noise? "generators.scm") (list 'green-noise-interp? "generators.scm") (list 'moving-sum? "generators.scm") (list 'moving-variance? "generators.scm") (list 'moving-rms? "generators.scm") (list 'moving-length? "generators.scm") (list 'weighted-moving-average? "generators.scm") (list 'exponentially-weighted-moving-average? "generators.scm") (list 'polyoid "generators.scm") (list 'polyoid-tn "generators.scm") (list 'polyoid-un "generators.scm") (list 'noid "generators.scm") (list 'waveshape? "generators.scm") (list 'waveshape "generators.scm") (list 'tanhsin? "generators.scm") (list 'moving-fft? "generators.scm") (list 'moving-spectrum? "generators.scm") (list 'moving-scentroid? "generators.scm") (list 'moving-autocorrelation? "generators.scm") (list 'moving-pitch? "generators.scm") (list 'flocsig? "generators.scm") (list 'vector-for-each "r7rs.scm") (list 'string-for-each "r7rs.scm") (list 'list-copy "r7rs.scm") (list 'r7rs-string-fill! "r7rs.scm") (list 'char-foldcase "r7rs.scm") (list 'exact-integer? "r7rs.scm") (list 'inexact "r7rs.scm") (list 'exact "r7rs.scm") (list 'truncate-quotient "r7rs.scm") (list 'truncate-remainder "r7rs.scm") (list 'floor-remainder "r7rs.scm") (list 'open-binary-input-file "r7rs.scm") (list 'open-binary-output-file "r7rs.scm") (list 'bytevector-length "r7rs.scm") (list 'write-bytevector "r7rs.scm") (list 'open-input-bytevector "r7rs.scm") (list 'open-output-bytevector "r7rs.scm") (list 'read-u8 "r7rs.scm") (list 'write-u8 "r7rs.scm") (list 'u8-ready? "r7rs.scm") (list 'peek-u8 "r7rs.scm") (list 'write-simple "r7rs.scm") (list 'raise "r7rs.scm") (list 'raise-continuable "r7rs.scm") (list 'interaction-environment "r7rs.scm") (list 'jiffies-per-second "r7rs.scm") (list 'current-jiffy "r7rs.scm") (list 'current-second "r7rs.scm") (list 'get-environment-variable "r7rs.scm") (list 'get-environment-variables "r7rs.scm") (list 'r7rs-file-exists? "r7rs.scm") (list 'os-type "r7rs.scm") (list 'cpu-architecture "r7rs.scm") (list 'machine-name "r7rs.scm") (list 'os-version "r7rs.scm") (list 'implementation-name "r7rs.scm") (list 'implementation-version "r7rs.scm") (list 'box-type? "r7rs.scm") (list 'make-box-type "r7rs.scm") (list 'define-library "r7rs.scm") (list 'define-record-type "r7rs.scm") (list 'c?r "stuff.scm") (list 'do* "stuff.scm") (list 'typecase "stuff.scm") (list 'enum "stuff.scm") (list 'while "stuff.scm") (list 'define-class "stuff.scm") (list 'elambda "stuff.scm") (list 'reflective-let "stuff.scm") (list 'reflective-probe "stuff.scm") (list 'reactive-let "stuff.scm") (list 'reactive-let* "stuff.scm") (list 'reactive-lambda* "stuff.scm") (list 'pretty-print "write.scm") (list 'fully-macroexpand "stuff.scm") (list '*mock-vector* "mockery.scm") (list '*mock-port* "mockery.scm") (list '*mock-symbol* "mockery.scm") (list '*mock-pair* "mockery.scm") (list '*mock-number* "mockery.scm") (list '*mock-char* "mockery.scm") (list '*mock-string* "mockery.scm") (list '*mock-hash-table* "mockery.scm") (list 'lint "lint.scm") (list 'html-lint "lint.scm") (list 'moog? "moog.scm") (list 'make-moog "moog.scm") (list 'snd-clm23.scm "clm23.scm") (list 'snd-edit123.scm "edit123.scm") ; (list 'snd-snd11.scm "snd11.scm") (list 'snd-new-backgrounds.scm "new-backgrounds.scm") (list 'snd-new-effects.scm "new-effects.scm") (list 'snd-bess1.scm "bess1.scm") (list 'snd-bess.scm "bess.scm") (list 'snd-edit-menu.scm "edit-menu.scm") (list 'snd-effects-utils.scm "effects-utils.scm") (list 'snd-fft-menu.scm "fft-menu.scm") (list 'snd-fmv.scm "fmv.scm") (list 'snd-gtk-effects.scm "gtk-effects.scm") (list 'snd-gtk-effects-utils.scm "gtk-effects-utils.scm") (list 'snd-snd-gl.scm "snd-gl.scm") (list 'snd-snd-gtk.scm "snd-gtk.scm") (list 'snd-snd-motif.scm "snd-motif.scm") (list 'snd-special-menu.scm "special-menu.scm") (list 'snd-marks-menu.scm "marks-menu.scm") (list 'snd-misc.scm "misc.scm") (list 'snd-xm-enved.scm "xm-enved.scm") (list 'snd-ws.scm "ws.scm") (list 'sndlib-ws.scm "sndlib-ws.scm") )) ;; still missing (if not above): ;; copy-sample-reader free-sample-reader make-mix-sample-reader make-region-sample-reader make-sample-reader ;; mix-sample-reader? region-sample-reader? sample-reader-at-end? sample-reader-home sample-reader? sample-reader-position ;; spectro-cutoff spectro-end clear-selection cursor-follows-play ;; penv? make-penv ;; big-ring-modulate big-oscil? make-big-oscil big-ncos? make-big-ncos big-nsin? make-big-nsin big-table-lookup? ;; make-big-table-lookup big-one-zero? make-big-one-zero big-one-pole? make-big-one-pole ;; hilbert-transform highpass lowpass bandpass bandstop differentiator butter channel-lp-inf savitzky-golay-filter ;; stop-dac dlocsig array-ref sound-comment ;; alternate: (autoload sym (lambda (e) (let ((m (load file))) (varlet (rootlet) (cons sym (m sym)))))) (for-each (lambda (sym&file) (let ((e (car sym&file)) (file (cadr sym&file))) (let ((ce (if (not (defined? e)) (load file) (symbol->value e)))) (let ((flst (or (hash-table-ref names file) ()))) (for-each (lambda (slot) (let ((name (car slot))) (if (not (defined? name)) (set! flst (cons name flst))))) ce) (hash-table-set! names file flst))))) (list (list '*libm* "libm.scm") (list '*libgdbm* "libgdbm.scm") (list '*libdl* "libdl.scm") (list '*libc* "libc.scm") (list '*libgsl* "libgsl.scm") )) (apropos-1 (rootlet)) (let ((syms ()) (size 0)) (call-with-output-file "indexer.data" (lambda (p) (let ((hti (make-iterator names))) (do ((ns (iterate hti) (iterate hti))) ((eof-object? ns)) (let ((file (car ns)) (symbols (cdr ns))) (set! size (+ size (length symbols))) (for-each (lambda (symbol) (set! syms (cons (cons (symbol->string symbol) file) syms))) symbols))) (set! syms (sort! syms (lambda (a b) (string" dline)) (pos (and (not compos) (not indpos) (string-position "symbol name))) (if (not (hash-table-ref ids sym-name)) (hash-table-set! ids sym-name 0) (if (memq sym-name local-ids) (format #t "~S: id ~S is set twice~%" file sym-name))) (set! local-ids (cons sym-name local-ids))))) (if tpos (let ((epos (string-position " -->" dline))) (if (not epos) (format #t " for ~A~%" dline) (set! topic (substring dline (+ tpos 11) epos)))) (if compos (let ((epos (string-position " -->" dline))) (if (not epos) (format #t " for ~A~%" dline) (when (or (not no-bold) with-scm) (set! current-general g) (set! (generals g) (substring dline (+ compos 11) epos)) (set! (gfiles g) (car file)) (set! (xrefs g) "") (set! g (+ g 1))))) (if indpos (let ((epos (string-position " -->" dline))) (if (not epos) (format #t " for ~A~%" dline) (when (or (not no-bold) with-scm) (set! (names n) (substring dline (+ indpos 16) epos)) (set! (files n) (car file)) (set! n (+ n 1))))) (if xpos (set! xrefing #t) (do () ((not pos)) (set! dline (substring dline pos)) (let ((epos (or (string-position "" dline) (string-position "" dline) (string-position "" dline)))) (if (not epos) (format #t " but no for ~A~%" dline) (begin (set! (names n) (string-append (substring dline 0 epos) "")) (set! (files n) (car file)) (set! (topics n) topic) (set! n (+ n 1)) (set! dline (substring dline (+ epos 4))) (set! pos (string-position "" dline))) (when hpos (set! topic #f)))))))))) ;; end call-with-input-file loop (let ((tnames (make-vector (+ n g))) (ctr 0)) (do ((i 0 (+ i 1))) ((= i n)) (set! (tnames ctr) (clean-and-downcase-first-char (names i) capitalized (topics i) (files i))) (if (positive? (length (ind-sortby (tnames ctr)))) (set! ctr (+ ctr 1)))) (unless (= ctr n) (set! n ctr) (set! tnames (copy tnames (make-vector n)))) (when (positive? g) (if (< (length tnames) (+ g n)) (set! tnames (copy tnames (make-vector (+ g n) #f)))) (do ((i 0 (+ i 1))) ((= i g)) (set! (tnames (+ i n)) (create-general (generals i) (gfiles i)))) (set! n (+ n g))) (set! tnames (sort! tnames (lambda (a b) (string Snd Index
Index
~%" (creation-date)) (format ofil "~% ") (set! got-tr #t) (let ((row 0) (ctr 0) (offset (ceiling (/ n cols)))) (do ((i 0 (+ i 1))) ((>= row offset)) (let ((x (+ row (* ctr offset)))) (if (< x n) (let ((name (tnames x))) (format ofil "~A~A~A" (if (not (ind-name name)) "" (if (not (ind-sortby name)) " class=\"green\"" "")) (if (ind-char name) "
" "") (or (ind-char name) (ind-name name) " ") ; (if (and (not (ind-char name)) ; (string? (ind-file name)) ; (string=? (ind-file name) "s7.html")) ; " (s7)" ; "") ;; this looks kinda dumb (if (ind-char name) "
" "") ) (if (ind-indexed name) (format #t "~A indexed twice~%" (ind-name name))) (set! (ind-indexed name) #t)) (format ofil "~%"))) (set! ctr (+ ctr 1)) (when (< ctr cols) (format ofil "
")) (when (= ctr cols) (if got-tr (begin (format ofil "~%") (set! got-tr #f))) (set! row (+ row 1)) (if (< i n) (begin (format ofil " ") (set! got-tr #t))) (set! ctr 0)))) (format ofil "~%
~%~%"))) ;; end output (do ((i 0 (+ i 1))) ((= i n)) (if (not (ind-indexed (tnames i))) (format #t "unindexed: ~A (~A)~%" (ind-name (tnames i)) i))) (do ((i 0 (+ i 1))) ((= i (- n 1))) (let ((n1 (tnames i)) (n2 (tnames (+ i 1)))) (if (and (string? (ind-sortby n1)) (string? (ind-sortby n2)) (string=? (ind-sortby n1) (ind-sortby n2)) (string=? (ind-name n1) (ind-name n2))) (format #t "duplicated name: ~A (~A ~A)~%" (ind-sortby n1) (ind-name n1) (ind-name n2))))) (if with-scm (begin (call-with-output-file "test.c" (lambda (sfil) (let ((help-names ()) (help-urls ())) (format sfil "/* Snd help index (generated by make-index.scm) */~%") (do ((i 0 (+ i 1))) ((= i n)) (if (and (tnames i) (ind-sortby (tnames i))) (let* ((line (substring (ind-name (tnames i)) 8)) (dpos (char-position #\> line)) (url (substring line 1 (- dpos 1))) (epos (char-position #\< line)) (ind (substring line (+ dpos 1) epos)) (gpos (string-position ">" ind))) (if gpos (set! ind (string-append (substring ind 0 gpos) ">" (substring ind (+ gpos 4))))) (when (and ind (string? ind) (positive? (length ind))) (set! help-names (cons ind help-names)) (set! help-urls (cons url help-urls)))))) (set! help-names (reverse help-names)) (set! help-urls (reverse help-urls)) (let ((len (length help-names))) (format sfil "#define HELP_NAMES_SIZE ~D~%" len) (format sfil "#if HAVE_SCHEME || HAVE_FORTH~%") (format sfil "static const char *help_names[HELP_NAMES_SIZE] = {~% ") (format sfil "~S" (car help-names)) (do ((ctr 1 (+ ctr 1)) (lname (cdr help-names) (cdr lname))) ((null? lname)) (let ((name (car lname))) (if (= (modulo ctr 6) 0) (format sfil ",~% ~S" name) (format sfil ", ~S" name)))) (format sfil "};~%") (format sfil "#endif~%#if HAVE_RUBY~%") (format sfil "static const char *help_names[HELP_NAMES_SIZE] = {~% ") (format sfil "~S" (car help-names)) (do ((ctr 1 (+ ctr 1)) (lname (cdr help-names) (cdr lname))) ((null? lname)) (let ((name (car lname))) (if (= (modulo ctr 6) 0) (format sfil ",~% ~S" (without-dollar-sign (scheme->ruby name))) (format sfil ", ~S" (without-dollar-sign (scheme->ruby name)))))) (format sfil "};~%#endif~%") (format sfil "#if (!HAVE_EXTENSION_LANGUAGE)~%static const char **help_names = NULL;~%#endif~%") (format sfil "static const char *help_urls[HELP_NAMES_SIZE] = {~% ") (format sfil "~S" (car help-names)) (do ((ctr 1 (+ ctr 1)) (lname (cdr help-urls) (cdr lname))) ((null? lname)) (let ((url (car lname))) (if (= (modulo ctr 4) 0) (format sfil ",~% ~S" url) (format sfil ", ~S" url)))) (format sfil "};~%")) (do ((i 0 (+ i 1))) ((= i g)) (if (and (xrefs i) (> (length (xrefs i)) 1)) (let ((vals (clean-up-xref (xrefs i) (gfiles i)))) (format sfil "~%static const char *~A_xrefs[] = {~% ~A,~% NULL};~%" (let* ((str (generals i)) (mid (char-position #\: str))) (make-vector-name (substring str (+ mid 1)))) (car vals)) (format sfil "~%static const char *~A_urls[] = {~% ~ANULL};~%" (let* ((str (generals i)) (mid (char-position #\: str))) (make-vector-name (substring str (+ mid 1)))) (cadr vals)) )) ) (format sfil "~%~%#if HAVE_SCHEME~%") ))) (system "cat indexer.data >> test.c") (system "echo '#endif\n\n' >> test.c") ))))) ;;; -------------------------------------------------------------------------------- ;;; html-check (define array-size (* 4 8192)) ;;; (html-check '("sndlib.html" "snd.html" "sndclm.html" "extsnd.html" "grfsnd.html" "sndscm.html" "fm.html" "balance.html" "snd-contents.html" "s7.html")) (define (html-check files) (let ((name 0) (href 0) (names (make-hash-table 2048))) (for-each (lambda (file) (call-with-input-file file (lambda (f) (let ((linectr -1) (commands ()) (comments 0) (openctr 0) (warned #f) (p-parens 0) (p-quotes 0) (p-curlys 0) (in-comment #f) (scripting #f)) (do ((line (read-line f) (read-line f))) ((eof-object? line)) (set! linectr (+ linectr 1)) (let* ((len (length line)) (opos (and (positive? len) (char-position "<>\"(){}&" line))) (cpos (and (not opos) in-comment (string-position " -- " line)))) (when cpos (format #t "~A[~D]: possible -- in comment: ~A~%" file linectr line)) (when opos ;; open/close html entities (do ((i opos (or (char-position "<>\"(){}&" line (+ i 1)) len))) ((>= i len)) (case (string-ref line i) ((#\<) (unless scripting (if (and (not (zero? openctr)) (not (positive? p-quotes)) (not in-comment)) (format #t "~A[~D]: ~A has unclosed comments 1) (begin (format #t "~A[~D]: nested ?~%" file linectr) (set! comments 0)))) (if (and (not (zero? openctr)) (not (positive? p-quotes)) (not in-comment)) (format #t "~A[~D]: ~A has unmatched >?~%" file linectr line))) (set! openctr 0) (if (and (not in-comment) (>= i 2) (char=? (line (- i 1)) #\-) (not (char=? (line (- i 2)) #\-)) (< i (- len 1)) (alphanumeric? (line (+ i 1)))) (format #t "~A[~D]: untranslated '>': ~A~%" file linectr line)))) ;; else c != < or > ((#\() (set! p-parens (+ p-parens 1))) ((#\)) (set! p-parens (- p-parens 1))) ((#\") (if (or (= i 0) (not (char=? (line (- i 1)) #\\))) (set! p-quotes (+ p-quotes 1)))) ((#\&) (if (and (not in-comment) (case (string-ref line (+ i 1)) ((#\g) (not (string=? ">" (substring line i (min len (+ i 4)))))) ((#\l) (and (not (string=? "<" (substring line i (min len (+ i 4))))) (not (string=? "λ" (substring line i (min len (+ i 8))))))) ((#\a) (not (string=? "&" (substring line i (min len (+ i 5)))))) ((#\q) (not (string=? """ (substring line i (min len (+ i 6)))))) ((#\o) (not (string=? "ö" (substring line i (min len (+ i 6)))))) ((#\m) (and (not (string=? "—" (substring line i (min len (+ i 7))))) (not (string=? "µ" (substring line i (min len (+ i 7))))))) ((#\n) (not (string=? " " (substring line i (min len (+ i 6)))))) ((#\&) (not (string=? "&&" (substring line i (min len (+ i 2)))))) ((#\space) (not (string=? "& " (substring line i (min len (+ i 2)))))) ; following char -- should skip this (else #t))) (format #t "~A[~D]: unknown escape sequence: ~A~%" file linectr line))) ((#\{) (set! p-curlys (+ p-curlys 1))) ((#\}) (set! p-curlys (- p-curlys 1))))) ;; end line scan (if (not in-comment) (let ((start #f) (closing #f) (pos (char-position #\< line))) (if pos (do ((i pos (or (char-position "" line (+ i 1)) len))) ((>= i len)) (case (string-ref line i) ((#\space #\>) (if start (begin (if closing (let ((closer (string->symbol (substring line (+ start 2) i)))) (if (eq? closer 'TABLE) (set! closer 'table)) (if (memq closer '(center big font)) (format #t "~A[~D]: ~A is obsolete, ~A~%" file linectr closer line) (if (eq? closer 'script) (set! scripting #f) (if (not scripting) (if (not (memq closer commands)) (format #t "~A[~D]: ~A without start? ~A from [~D:~D] (commands: ~A)~%" file linectr closer line (+ start 2) i commands) (if (memq closer '(ul tr td table small sub blockquote p details summary a A i b title pre span h1 h2 h3 code body html em head h4 sup map smaller bigger th tbody div)) (begin (if (not (eq? (car commands) closer)) (format #t "~A[~D]: ~A -> ~A?~%" file linectr closer commands)) (if (memq closer '(p td pre)) (begin (if (odd? p-quotes) (format #t "~A[~D]: unmatched quote~%" file linectr)) (set! p-quotes 0) (if (= p-curlys 1) (format #t "~A[~D]: extra '{'~%" file linectr) (if (= p-curlys -1) (format #t "~A[~D]: extra '}'~%" file linectr) (if (not (= p-curlys 0)) (format #t "~A[~D]: curlys: ~D~%" file linectr p-curlys)))) (set! p-curlys 0) (if (= p-parens 1) (format #t "~A[~D]: extra '('~%" file linectr) (if (= p-parens -1) (format #t "~A[~D]: extra ')'~%" file linectr) (if (not (= p-parens 0)) (format #t "~A[~D]: parens: ~D~%" file linectr p-parens)))) (set! p-parens 0))) (set! commands (remove-one closer commands)) (if (not warned) (begin (if (and (eq? closer 'table) (not (memq 'table commands))) (begin (if (memq 'tr commands) (begin (set! warned #t) (set! commands (remove-all 'tr commands)) (format #t "~A[~D]: unclosed tr at table (~A)~%" file linectr commands))) (if (memq 'td commands) (begin (set! warned #t) (set! commands (remove-all 'td commands)) (format #t "~A[~D]: unclosed td at table (~A)~%" file linectr commands)))))))) (set! commands (remove-all closer commands))))))) (set! closing #f)) ;; not closing (if (not scripting) (let ((opener (string->symbol (substring line (+ start 1) i)))) (if (eq? opener 'TABLE) (set! opener 'table)) (if (memq opener '(center big font)) (format #t "~A[~D]: ~A is obsolete, ~A~%" file linectr opener line) (if (eq? opener 'script) (set! scripting #t) (if (eq? opener 'img) (let* ((rest-line (substring line (+ start 4))) (alt-pos (string-position "alt=" rest-line)) (src-pos (string-position "src=" rest-line))) (if (not alt-pos) (format #t "~A[~D]: img but no alt: ~A~%" file linectr line)) (if src-pos (let ((png-pos (string-position ".png" rest-line))) (if png-pos (let ((file (substring rest-line (+ src-pos 5) (+ png-pos 4)))) (if (not (file-exists? file)) (format #t "~A[~D]: src not found: ~S~%" file linectr file))))))) (if (and (not (memq opener '(br spacer li hr area ul tr td table small sub blockquote))) (memq opener commands) (= p-quotes 0)) (format #t "~A[~D]: nested ~A? ~A from: ~A~%" file linectr opener line commands) (begin (case opener ((td) (if (not (eq? 'tr (car commands))) (format #t "~A[~D]: td without tr?~%" file linectr)) (if (and (not warned) (memq 'td commands) (< (count-table commands) 2)) (begin (set! warned #t) (set! commands (remove-one 'td commands)) (format #t "~A[~D]: unclosed td at table~%" file linectr)))) ((tr) (if (and (not (eq? (car commands) 'table)) (not (eq? (cadr commands) 'table))) (format #t "~A[~D]: tr without table?~%" file linectr)) (if (and (not warned) (memq 'tr commands) (< (count-table commands) 2)) (begin (set! warned #t) (set! commands (remove-one 'tr commands)) (format #t "~A[~D]: unclosed tr at table~%" file linectr)))) ((p) (if (eq? (car commands) 'table) (format #t "~A[~D]: unclosed table?~%" file linectr))) ((pre br table hr img ul) (if (memq 'p commands) (format #t "~A[~D]: ~A within

?~%" file linectr opener))) ((li) (if (not (memq 'ul commands)) (format #t "~A[~D]: li without ul~%" file linectr))) ((small) (if (memq (car commands) '(pre code)) (format #t "~A[~D]: small shouldn't follow ~A~%" file linectr (car commands)))) ((--) (format #t "~A[~D]: <-- missing !?~%" file linectr))) (if (not (memq opener '(br meta spacer li hr area))) (set! commands (cons opener commands))))))))))) ;; end if closing (set! start #f)))) ((#\<) (if start (if (and (not scripting) (not (positive? p-quotes))) (format #t "~A[~D]: nested < ~A~%" file linectr line)) (set! start i))) ((#\/) (if (and start (= start (- i 1))) (set! closing #t))) ((#\!) (if (and start (= start (- i 1))) (set! start #f))))))) ) ; if not in-comment... ;; search for name (let* ((dline line) (pos (string-position "" dline) (string-position "" dline) (string-position "" dline)))) ;;actually should look for close double quote (if (not epos) (begin (format #t "~A[~D]: but no for ~A~%" file linectr dline) (abort)) (let ((min-epos (char-position #\space dline))) (set! epos (char-position #\> dline)) (if (and (number? min-epos) (< min-epos epos)) (set! epos min-epos)) (let ((new-name (string-append file "#" (substring dline 0 (- epos 1))))) (if (hash-table-ref names new-name) (format #t "~A[~D]: ambiguous name: ~A~%" file linectr new-name)) (hash-table-set! names new-name file)) (set! name (+ name 1)) (set! dline (substring dline epos)) (set! pos (string-position " dline))) (if (not epos) (format #t "~A[~D]: for ~A~%" file linectr dline) (let ((cur-href #f)) (set! epos (char-position #\" dline 1)) (if (char=? (dline 0) #\#) (set! cur-href (string-append file (substring dline 0 epos))) (begin (set! cur-href (substring dline 0 epos)) (let ((pos (char-position #\# cur-href))) (if (and (not pos) (> epos 5) (not (file-exists? cur-href)) (not (string=? (substring cur-href 0 4) "ftp:")) (not (string=? (substring cur-href 0 5) "http:"))) (format #t "~A[~D]: reference to missing file ~S~%" file linectr cur-href))))) ;; cur-href here is the full link: sndclm.html#make-filetosample for example ;; it can also be a bare file name (let* ((start (char-position #\# cur-href)) (name (and (number? start) (string->symbol (substring cur-href (+ start 1))))) (data (and (symbol? name) (hash-table-ref ids name)))) (if name (if (not data) (format #t ";can't find id ~A~%" name) (hash-table-set! ids name (+ data 1))))) (set! href (+ href 1)) (set! dline (substring dline epos)) (set! pos (string-position " href=" dline)) (set! pos-len 7)))))))) ) (if (pair? commands) (format #t "open directives at end of ~A: ~A~%" file commands)))))) files) ;; end file scan (format #t "found ~D names and ~D references~%" name href) (for-each (lambda (data) (if (zero? (cdr data)) (format #t ";~A unref'd~%" (car data)))) ids) )) (make-index-1 '("snd.html" "extsnd.html" "grfsnd.html" "sndscm.html" "sndlib.html" "sndclm.html" "fm.html" "s7.html") "test.html" 5 '("AIFF" "NeXT" "Sun" "RIFF" "IRCAM" "FIR" "IIR" "Hilbert" "AIFC") #t #t) (html-check '("sndlib.html" "snd.html" "extsnd.html" "grfsnd.html" "sndclm.html" "sndscm.html" "fm.html" "s7.html" "index.html")) (s7-version) (exit) snd-16.1/tools/make-config-pc.rb0000755000076400007640000000134212340220013014566 0ustar bilbil#! /usr/bin/env ruby # ruby make-config-pc.rb > ruby.pc require "rbconfig" if RUBY_VERSION < "1.9" include Config else include RbConfig end version = CONFIG["ruby_version"] arch = CONFIG["arch"] rubyhdrdir = CONFIG["rubyhdrdir"] if rubyhdrdir.nil? rubyhdrdir = CONFIG["rubylibdir"] else rubyhdrdir.chomp("/") end dldflags = CONFIG["DLDFLAGS"] librubyarg = CONFIG["LIBRUBYARG"] libs = CONFIG["LIBS"] rubylibdir = CONFIG["libdir"] print < 1)) #define Snd_assert_sound(Origin, Snd, Offset) \ if (!((Xen_is_integer(Snd)) || (xen_is_sound(Snd)) || (Xen_is_false(Snd)) || (!Xen_is_bound(Snd)))) \ Xen_wrong_type_arg_error(Origin, Offset, Snd, "a sound object, an integer (sound index), or " PROC_FALSE); #define Snd_assert_channel(Origin, Snd, Chn, Offset) \ if (!((Xen_is_integer(Snd)) || (xen_is_sound(Snd)) || (Xen_is_false(Snd)) || (!Xen_is_bound(Snd)))) \ Xen_wrong_type_arg_error(Origin, Offset, Snd, "a sound object, an integer (sound index), or " PROC_FALSE); \ else \ if (!((Xen_is_integer(Chn)) || (Xen_is_false(Chn)) || (!Xen_is_bound(Chn)))) \ Xen_wrong_type_arg_error(Origin, Offset + 1, Chn, "an integer (0-based channel number) or " PROC_FALSE); #if HAVE_SCHEME /* these macros fix up argument order for setter procs in Scheme: (set! (proc a b) c) */ #define with_two_setter_args(name_reversed, name) \ static s7_pointer name_reversed(s7_scheme *sc, s7_pointer args) \ { \ if (Xen_is_null(Xen_cdr(args))) \ return(name(Xen_car(args), Xen_undefined)); \ return(name(Xen_cadr(args), Xen_car(args))); \ } #define with_three_setter_args(name_reversed, name) \ static s7_pointer name_reversed(s7_scheme *sc, s7_pointer args) \ { \ if (Xen_is_null(Xen_cdr(args))) \ return(name(Xen_car(args), Xen_undefined, Xen_undefined)); \ else { \ if (Xen_is_null(Xen_cddr(args))) \ return(name(Xen_cadr(args), Xen_car(args), Xen_undefined)); \ else return(name(Xen_caddr(args), Xen_car(args), Xen_cadr(args))); \ }} #define with_four_setter_args(name_reversed, name) \ static s7_pointer name_reversed(s7_scheme *sc, s7_pointer args) \ { \ if (Xen_is_null(Xen_cdr(args))) \ return(name(Xen_car(args), Xen_undefined, Xen_undefined, Xen_undefined)); \ else { \ if (Xen_is_null(Xen_cddr(args))) \ return(name(Xen_cadr(args), Xen_car(args), Xen_undefined, Xen_undefined)); \ else { \ if (Xen_is_null(Xen_cdddr(args))) \ return(name(Xen_caddr(args), Xen_car(args), Xen_cadr(args), Xen_undefined)); \ else return(name(Xen_cadddr(args), Xen_car(args), Xen_cadr(args), Xen_caddr(args))); \ }}} #else #define with_two_setter_args(name_reversed, name) #define with_three_setter_args(name_reversed, name) #define with_four_setter_args(name_reversed, name) #endif #define Snd_assert_sample_type(Origin, Beg, Offset) \ Xen_check_type(Xen_is_integer(Beg) || Xen_is_false(Beg) || (!Xen_is_bound(Beg)), Beg, Offset, Origin, "an integer or " PROC_FALSE) typedef struct { char **values; int num_values, values_size; bool exact_match; } list_completer_info; typedef struct { int samps_per_bin, peak_env_size; mus_float_t fmax, fmin; mus_float_t *data_max, *data_min; bool completed; int bin, top_bin; } peak_env_info; typedef struct snd_io snd_io; typedef struct { char *name; /* full name */ mus_long_t samples; /* total samples = chans * framples */ mus_long_t data_location; /* bytes */ int srate; int chans; mus_sample_t sample_type; /* sample type (mus_bshort etc) */ mus_header_t type; /* header type (mus_aifc etc) */ char *comment; /* output case, not input */ int *loops; } file_info; typedef struct { snd_data_file_t type; mus_float_t *buffered_data; snd_io *io; char *filename; file_info *hdr; file_delete_t temporary; int edit_ctr; fd_open_t open; bool inuse; bool copy; int chan; mus_long_t data_bytes; /* used only for edit-history descriptions (snd-edits.c display_ed_list) */ bool free_me; } snd_data; typedef struct mark mark; typedef struct enved_fft enved_fft; typedef struct { int size, allocated_size; struct ed_fragment **fragments; mus_long_t beg, len; /* beg and len of changed portion */ char *origin; edit_t edit_type; int sound_location; mus_long_t selection_beg, selection_end; /* selection needs to follow edit list */ mus_float_t maxamp, selection_maxamp; mus_long_t maxamp_position, selection_maxamp_position; int edpos; bool backed_up; mus_long_t samples, cursor; int mark_size, mark_ctr; mark **marks; /* mark positions */ peak_env_info *peak_env; enved_fft *fft; /* overall fft data for envelope editor */ void *readers; /* current readers of this edit (g++ stupidity forces us to use void* here -- type is sf_info, snd-edits.c) */ void *mixes; Xen properties; int properties_gc_loc; } ed_list; typedef struct snd_fd { mus_float_t (*runf)(struct snd_fd *sf); mus_float_t (*rev_runf)(struct snd_fd *sf); ed_list *current_state; struct ed_fragment *cb; mus_long_t loc, first, last; int cbi; read_direction_t direction; bool at_eof, freed; mus_float_t *data; snd_data *current_sound; mus_long_t initial_samp; struct chan_info *cp; struct snd_info *local_sp; mus_float_t fscaler; mus_long_t frag_pos; int edit_ctr, region; reader_t type; void *ramps, *mixes; } snd_fd; typedef struct {mus_float_t freq; mus_float_t amp;} fft_peak; typedef struct { mus_float_t y0, y1; /* scroller-dependent axis bounds */ double x0, x1; double xmin, xmax; mus_float_t ymin, ymax; /* data-dependent absolute limits */ mus_float_t y_scale, y_base, y_ambit; double x_scale, x_base, x_ambit; char *xlabel, *ylabel, *default_xlabel; int y_axis_x0, x_axis_x0, y_axis_y0, x_axis_y0, x_axis_x1, y_axis_y1, x_label_x, x_label_y; bool graph_active; mus_long_t losamp, hisamp; /* displayed x-axis bounds in terms of sound sample numbers */ int graph_x0; /* x axis offset relative to window (for double graphs) */ struct tick_descriptor *x_ticks, *y_ticks; graphics_context *ax; int width, height; struct chan_info *cp; mus_float_t sy, zy; /* as set by user, 0.0 - 1.0 */ double sx, zx; int y_offset; int window_width; bool no_data, changed; #if HAVE_GL bool use_gl, used_gl; #endif } axis_info; typedef struct { mus_float_t *data; int pts, data_size; /* data_size is independent of actual number of points of data (can be much larger) */ mus_float_t base; } env; typedef struct { int mix_id; mus_long_t beg, len; mus_float_t scaler, speed; env *amp_env; int index; /* cp->sounds index (src writes a new temp file) */ } mix_state; typedef struct env_editor { int *current_xs; int *current_ys; int current_size; axis_info *axis; oclock_t down_time; bool env_dragged; int env_pos; bool click_to_delete, in_dB, with_dots, clipping; bool edited; } env_editor; typedef struct { mus_long_t size; mus_long_t current_size; mus_fft_window_t window; mus_float_t alpha, beta; mus_float_t scale; axis_info *axis; mus_float_t *data, *phases; char *xlabel; struct chan_info *chan; } fft_info; typedef struct { int total_slices; /* size of the data array (max for allocation checks) */ int total_bins; /* size other axis data array */ int active_slices; /* how many slices contain current data */ int target_bins; /* this many bins Y-side */ int target_slices; /* how many slices in full display (current) */ mus_float_t **data; /* data[total_slices][bins] -> each is a spectral magnitude */ mus_long_t *begs; /* associated begin times (for data reuse) */ struct chan_info *cp; mus_float_t scale; } sono_info; typedef struct { int chans, fields; double *axis_data; bool *fftp, *wavep; } axes_data; typedef struct chan_info { int chan; /* which chan are we */ bool graph_transform_on; /* f button state */ bool graph_time_on; /* w button state */ bool graph_lisp_on; /* is lisp graph active */ struct lisp_grf *lisp_info; /* defined in snd-chn.c */ bool cursor_on; /* channel's cursor */ bool cursor_visible, fft_cursor_visible; /* for XOR decisions */ int cursor_size; cursor_style_t cursor_style, tracking_cursor_style; int cx, cy, fft_cx; /* , old_cy; */ /* graph-relative cursor loc (for XOR in Motif, erase-via-overwrite in cairo) */ int edit_ctr; /* channel's edit history */ int edit_size; /* current edit list size */ ed_list **edits; /* the edit list */ int sound_size; /* edit_list associated temp sound buffers */ int sound_ctr; /* current location in sounds list */ snd_data **sounds; /* the associated temp buffer/file/struct list */ fft_info *fft; /* possibly null fft data */ struct snd_info *sound; /* containing sound */ axis_info *axis; /* time domain axis */ idle_t fft_in_progress; idle_t peak_env_in_progress; struct env_state *peak_env_state; graphics_context *ax; bool selected; mus_float_t progress_pct; #if USE_GTK GtkWidget **chan_widgets; GtkAdjustment **chan_adjs; GdkCursor *current_cursor; slist *edhist_list; color_info *combined_data_color; #if CAIRO_HAS_RECORDING_SURFACE && (0) cairo_surface_t *fft_pix; bool fft_pix_ready; #endif #endif #if USE_MOTIF Widget *chan_widgets; Pixmap fft_pix; unsigned int fft_pix_width, fft_pix_height; int fft_pix_x0, fft_pix_y0; bool fft_pix_ready; mus_float_t fft_pix_cutoff; Cursor current_cursor; Pixel combined_data_color; #endif #if USE_NO_GUI int current_cursor, combined_data_color; #endif sono_info *sonogram_data; struct sonogram_state *last_sonogram, *temp_sonogram; /* defined in snd-fft.c */ struct wavogram_state *last_wavogram; /* defined in snd-chn.c */ bool show_sonogram_cursor; struct fft_state *fft_data; /* parallels sonogram -- try to avoid repeating large ffts needlessly */ printing_t printing; fft_change_t fft_changed; mus_float_t gsy, gzy; int height; mus_long_t original_cursor, original_left_sample, original_window_size; /* for cursor reset after cursor-moving play */ with_hook_t hookable; mus_long_t selection_transform_size; bool squelch_update, previous_squelch_update, waiting_to_make_graph; int in_as_one_edit, as_one_edit_positions_size; int *as_one_edit_positions; /* moved from global to channel-local 4-Aug-00 */ mus_float_t spectro_x_scale, spectro_y_scale, spectro_z_scale, spectro_z_angle, spectro_x_angle, spectro_y_angle; mus_float_t spectrum_end, spectrum_start; mus_float_t lin_dB, min_dB, fft_window_alpha, fft_window_beta, beats_per_minute, grid_density; bool show_y_zero, show_marks, with_verbose_cursor; with_grid_t show_grid; int wavo_hop, wavo_trace, zero_pad, wavelet_type, max_transform_peaks, beats_per_measure; x_axis_style_t x_axis_style; show_axes_t show_axes; mus_long_t transform_size; mus_fft_window_t fft_window; graph_type_t transform_graph_type, time_graph_type; bool show_transform_peaks, fft_log_frequency, fft_log_magnitude, fft_with_phases; graph_style_t time_graph_style, lisp_graph_style, transform_graph_style; int dot_size; fft_normalize_t transform_normalization; int transform_type, spectro_hop, edhist_base; bool show_mix_waveforms, graphs_horizontal; Xen edit_hook; Xen undo_hook; Xen cursor_proc; Xen after_edit_hook; Xen properties; int cursor_proc_loc, edit_hook_loc, undo_hook_loc, after_edit_hook_loc, properties_loc; bool selection_visible; channel_state_t active; int old_x0, old_x1; mus_float_t *amp_control; /* local amp controls in snd-dac; should it be extended to other controls? */ bool just_zero, new_peaks, editable, updating; struct inset_graph_info_t *inset_graph; /* defined in snd-chn.c */ #if HAVE_GL int gl_fft_list, gl_wavo_list; #endif } chan_info; #define current_samples(Cp) (Cp)->edits[(Cp)->edit_ctr]->samples #define cursor_sample(Cp) (Cp)->edits[(Cp)->edit_ctr]->cursor typedef struct snd_info { sound_inuse_t inuse; int index; int playing; int sync, previous_sync; bool expand_control_on; bool contrast_control_on; bool reverb_control_on; bool filter_control_on, filter_control_in_dB, filter_control_in_hz; mus_float_t amp_control; mus_float_t speed_control; int speed_control_direction, speed_control_tones, speed_control_numerator, speed_control_denominator; speed_style_t speed_control_style; mus_float_t last_speed_control, last_amp_control, last_expand_control, last_contrast_control; mus_float_t last_reverb_control_length, last_reverb_control_scale; mus_float_t saved_speed_control, saved_amp_control, saved_expand_control, saved_contrast_control; mus_float_t saved_reverb_control_length, saved_reverb_control_scale; mus_float_t expand_control, expand_control_length, expand_control_ramp, expand_control_hop, expand_control_jitter; mus_float_t contrast_control, contrast_control_amp; mus_float_t reverb_control_length, reverb_control_scale, reverb_control_feedback, reverb_control_lowpass; mus_float_t reverb_control_decay, filter_control_xmax; mus_float_t contrast_control_min, contrast_control_max, expand_control_min, expand_control_max, speed_control_min, speed_control_max; mus_float_t amp_control_min, amp_control_max, reverb_control_scale_min, reverb_control_scale_max; mus_float_t reverb_control_length_min, reverb_control_length_max; int filter_control_order; bool filter_control_changed; env *filter_control_envelope; int selected_channel; char *filename; char *short_filename; int nchans; Xen properties; int properties_loc; bool remembering; read_only_t user_read_only, file_read_only; chan_info **chans; struct env_editor *flt; #if USE_MOTIF Widget *snd_widgets; Widget *progress_widgets; int num_progress_widgets; Widget tab; Widget dialog; int bomb_ctr; #endif #if USE_GTK GtkWidget **snd_widgets; GtkAdjustment **snd_adjs; GtkWidget *dialog; int page; graphics_context *name_pix_ax, *stop_pix_ax, *speed_arrow_ax, *filter_ax; graphics_context **clock_pix_ax; GtkWidget **clock_widgets; int num_clock_widgets; #endif #if USE_NO_GUI bool snd_widgets; #endif file_info *hdr; /* header of file that would be affected if we were to save current edits */ time_t write_date, update_warning_write_date; /* check for change behind back while editing */ bool need_update, file_unreadable; /* current in-core data does not match actual file (someone wrote it behind our back) */ channel_style_t channel_style; int allocated_chans, selectpos; struct region *edited_region; void *delete_me; chan_info *lacp; struct ctrl_state *saved_controls; bool apply_ok, applying; bool active; char *name_string; void *file_watcher; bool writing, bomb_in_progress; } snd_info; #define snd_srate(Sp) (((Sp)->hdr)->srate) #define has_widgets(Sp) ((Sp) && ((Sp)->snd_widgets)) typedef struct snd_state { int selected_sound; /* NO_SELECTION = none selected = which sound is currently receiving user's attention */ int active_sounds; int channel_min_height; snd_info **sounds; char *search_expr, *startup_title, *startup_errors; Xen search_proc; int file_sorters_size, file_filters_size; Xen file_sorters, file_filters; int search_proc_loc, local_errno, local_open_errno; int position_slider_width, zoom_slider_width, toggle_size, channel_sash_indent, sash_size, channel_sash_size, sash_indent; int max_sounds, sound_sync_max; char *translated_filename; print_choice_t print_choice; snd_apply_t apply_choice; bool gl_has_double_buffer; bool stopped_explicitly, checking_explicitly, selection_play_stop; int reloading_updated_file; int init_window_width, init_window_height; int init_window_x, init_window_y; bool graph_hook_active, lisp_graph_hook_active; bool Show_Transform_Peaks, Show_Y_Zero, Show_Marks; with_grid_t Show_Grid; bool Fft_Log_Frequency, Fft_Log_Magnitude, Fft_With_Phases; channel_style_t Channel_Style; sync_style_t Sync_Style; sound_style_t Sound_Style; show_axes_t Show_Axes; char *Eps_File, *Temp_Dir, *Save_Dir, *Ladspa_Dir, *Peak_Env_Dir; char *Listener_Font, *Axis_Label_Font, *Axis_Numbers_Font, *Tiny_Font, *Peaks_Font, *Bold_Peaks_Font; char *orig_listener_font, *orig_axis_label_font, *orig_axis_numbers_font, *orig_tiny_font, *orig_peaks_font, *orig_bold_peaks_font; bool With_Verbose_Cursor, With_Inset_Graph, With_Pointer_Focus, With_Smpte_Label, With_Interrupts; int Enved_Filter_Order; mus_float_t Eps_Left_Margin, Eps_Bottom_Margin, Eps_Size, Log_Freq_Start; mus_float_t Spectro_X_Scale, Spectro_Y_Scale, Spectro_Z_Scale, Spectro_Z_Angle, Spectro_X_Angle, Spectro_Y_Angle; mus_float_t Spectrum_End, Spectrum_Start; mus_header_t Default_Output_Header_Type; mus_sample_t Default_Output_Sample_Type; int Default_Output_Chans, Default_Output_Srate; int Spectro_Hop, Color_Map, Color_Map_Size, Wavelet_Type, Transform_Type; int Dot_Size; int Zero_Pad, Wavo_Hop, Wavo_Trace; mus_long_t Transform_Size; mus_fft_window_t Fft_Window; graph_type_t Transform_Graph_Type, Time_Graph_Type; bool Ask_Before_Overwrite, Ask_About_Unsaved_Edits, Show_Full_Duration, Show_Full_Range, Remember_Sound_State; bool Save_As_Dialog_Src, Save_As_Dialog_Auto_Comment, With_Toolbar, With_Tooltips, With_Menu_Icons; mus_float_t Fft_Window_Alpha, Fft_Window_Beta, Grid_Density, Initial_Beg, Initial_Dur; mus_float_t Color_Scale, Color_Cutoff, Beats_Per_Minute; bool Color_Inverted, Show_Mix_Waveforms; int Mix_Waveform_Height, Beats_Per_Measure; fft_normalize_t Transform_Normalization; int Sinc_Width; x_axis_style_t X_Axis_Style; zoom_focus_t Zoom_Focus_Style; graph_style_t Graph_Style, Region_Graph_Style; bool Auto_Resize, Auto_Update; int Max_Regions, Max_Transform_Peaks; bool With_GL, With_Relative_Panes; int Print_Length, Dac_Size, View_Files_Sort; bool Dac_Combines_Channels, Show_Selection_Transform, With_Mix_Tags, Selection_Creates_Region; char *Save_State_File, *Listener_Prompt; mus_float_t Enved_Base, Enved_Power, Auto_Update_Interval; bool Enved_With_Wave, Graphs_Horizontal, With_Background_Processes, With_File_Monitor; env_type_t Enved_Style; int Graph_Cursor, Mix_Tag_Width, Mix_Tag_Height, Mark_Tag_Height, Mark_Tag_Width; enved_target_t Enved_Target; bool Clipping, Show_Indices, Just_Sounds; int Cursor_Size; cursor_style_t Cursor_Style, Tracking_Cursor_Style; bool Filter_Control_In_Db, Filter_Control_In_Hz, Show_Sonogram_Cursor; int Speed_Control_Tones; speed_style_t Speed_Control_Style; mus_float_t Expand_Control_Length, Expand_Control_Ramp, Expand_Control_Hop, Expand_Control_Jitter; mus_float_t Contrast_Control_Amp; mus_float_t Reverb_Control_Feedback, Reverb_Control_Lowpass; mus_float_t Reverb_Control_Decay, Cursor_Update_Interval; mus_float_t Contrast_Control_Min, Contrast_Control_Max, Expand_Control_Min, Expand_Control_Max, Speed_Control_Min, Speed_Control_Max; mus_float_t Amp_Control_Min, Amp_Control_Max, Reverb_Control_Scale_Min, Reverb_Control_Scale_Max; mus_float_t Reverb_Control_Length_Min, Reverb_Control_Length_Max; int Filter_Control_Order, Cursor_Location_Offset, Play_Arrow_Size; mus_float_t Min_dB; bool Show_Controls; tracking_cursor_t With_Tracking_Cursor; char *HTML_Dir, *HTML_Program, *Open_File_Dialog_Directory; #if HAVE_SCHEME s7_pointer show_transform_peaks_symbol, show_y_zero_symbol, show_marks_symbol, show_grid_symbol, fft_log_frequency_symbol, fft_log_magnitude_symbol, fft_with_phases_symbol, channel_style_symbol, sync_style_symbol, show_axes_symbol, eps_file_symbol, temp_dir_symbol, save_dir_symbol, ladspa_dir_symbol, peak_env_dir_symbol, listener_font_symbol, axis_label_font_symbol, axis_numbers_font_symbol, tiny_font_symbol, peaks_font_symbol, bold_peaks_font_symbol, with_verbose_cursor_symbol, with_inset_graph_symbol, with_pointer_focus_symbol, with_smpte_label_symbol, with_interrupts_symbol, enved_filter_order_symbol, eps_left_margin_symbol, eps_bottom_margin_symbol, eps_size_symbol, log_freq_start_symbol, spectro_x_scale_symbol, spectro_y_scale_symbol, spectro_z_scale_symbol, spectro_z_angle_symbol, spectro_x_angle_symbol, spectro_y_angle_symbol, spectrum_end_symbol, spectrum_start_symbol, default_output_header_type_symbol, default_output_sample_type_symbol, default_output_chans_symbol, default_output_srate_symbol, spectro_hop_symbol, color_map_symbol, color_map_size_symbol, wavelet_type_symbol, transform_type_symbol, dot_size_symbol, zero_pad_symbol, wavo_hop_symbol, wavo_trace_symbol, transform_size_symbol, fft_window_symbol, transform_graph_type_symbol, time_graph_type_symbol, ask_before_overwrite_symbol, ask_about_unsaved_edits_symbol, show_full_duration_symbol, show_full_range_symbol, remember_sound_state_symbol, save_as_dialog_src_symbol, save_as_dialog_auto_comment_symbol, with_toolbar_symbol, with_tooltips_symbol, with_menu_icons_symbol, fft_window_alpha_symbol, fft_window_beta_symbol, grid_density_symbol, initial_beg_symbol, initial_dur_symbol, color_scale_symbol, color_cutoff_symbol, beats_per_minute_symbol, color_inverted_symbol, show_mix_waveforms_symbol, mix_waveform_height_symbol, beats_per_measure_symbol, transform_normalization_symbol, sinc_width_symbol, x_axis_style_symbol, zoom_focus_style_symbol, graph_style_symbol, region_graph_style_symbol, auto_resize_symbol, auto_update_symbol, max_regions_symbol, max_transform_peaks_symbol, with_gl_symbol, with_relative_panes_symbol, print_length_symbol, dac_size_symbol, view_files_sort_symbol, dac_combines_channels_symbol, show_selection_transform_symbol, with_mix_tags_symbol, selection_creates_region_symbol, save_state_file_symbol, listener_prompt_symbol, enved_base_symbol, enved_power_symbol, auto_update_interval_symbol, enved_with_wave_symbol, graphs_horizontal_symbol, with_background_processes_symbol, with_file_monitor_symbol, enved_style_symbol, graph_cursor_symbol, mix_tag_width_symbol, mix_tag_height_symbol, mark_tag_height_symbol, mark_tag_width_symbol, enved_target_symbol, clipping_symbol, show_indices_symbol, just_sounds_symbol, cursor_size_symbol, cursor_style_symbol, tracking_cursor_style_symbol, filter_control_in_db_symbol, filter_control_in_hz_symbol, show_sonogram_cursor_symbol, speed_control_tones_symbol, speed_control_style_symbol, expand_control_length_symbol, expand_control_ramp_symbol, expand_control_hop_symbol, expand_control_jitter_symbol, contrast_control_amp_symbol, reverb_control_feedback_symbol, reverb_control_lowpass_symbol, reverb_control_decay_symbol, cursor_update_interval_symbol, filter_control_order_symbol, cursor_location_offset_symbol, play_arrow_size_symbol, min_db_symbol, show_controls_symbol, with_tracking_cursor_symbol, #if USE_GTK listener_colorized_symbol, #endif html_dir_symbol, html_program_symbol, open_file_dialog_directory_symbol; #endif bool tracking; Xen cursor_proc; int cursor_proc_loc, listener_prompt_length; Xen zoom_focus_proc; int zoom_focus_proc_loc; mus_float_t lin_dB; char *io_error_info; int deferred_regions; open_requestor_t open_requestor; void *open_requestor_data; bool batch_mode; bool jump_ok, exiting; env_editor *enved; oclock_t click_time; bool file_monitor_ok, C_g_typed, squelch_mark_drag_info; void (*snd_error_handler)(const char *error_msg, void *data); void *snd_error_data; void (*snd_warning_handler)(const char *warning_msg, void *data); void *snd_warning_data; void (*xen_error_handler)(const char *error_msg, void *data); void *xen_error_data; void (*snd_print_handler)(const char *msg, void *data); void *snd_print_data; channel_style_t update_sound_channel_style; #if HAVE_GL && WITH_GL2PS bool gl_printing; #endif Xen mus_error_hook; Xen snd_error_hook; Xen snd_warning_hook; Xen snd_open_file_hook; Xen effects_hook; #if USE_MOTIF XtAppContext mainapp; Widget mainshell; Widget mainpane; Widget soundpane; Widget soundpanebox; Widget toolbar; Display *mdpy; xm_font_t peaks_fontlist; XFontStruct *peaks_fontstruct; xm_font_t bold_peaks_fontlist; XFontStruct *bold_peaks_fontstruct; xm_font_t listener_fontlist; XFontStruct *listener_fontstruct; XFontStruct *axis_label_fontstruct; XFontStruct *axis_numbers_fontstruct; xm_font_t tiny_fontlist; XFontStruct *tiny_fontstruct; Pixel white, black, red, yellow, green, blue, light_blue, lighter_blue; Pixel data_color, selected_data_color, mark_color, graph_color, selected_graph_color, listener_color, listener_text_color; Pixel basic_color, selection_color, zoom_color, position_color, highlight_color, enved_waveform_color, cursor_color; Pixel text_focus_color, filter_control_waveform_color, mix_color, sash_color; Pixel selected_grid_color, grid_color, axis_color; Pixel orig_data_color, orig_selected_data_color, orig_mark_color, orig_mix_color; Pixel orig_graph_color, orig_selected_graph_color, orig_listener_color, orig_listener_text_color, orig_cursor_color; Pixel orig_basic_color, orig_selection_color, orig_zoom_color, orig_position_color, orig_highlight_color; GC basic_gc, selected_basic_gc, combined_basic_gc; GC cursor_gc, selected_cursor_gc; GC selection_gc, selected_selection_gc; GC erase_gc, selected_erase_gc; GC mark_gc, selected_mark_gc; GC mix_gc; GC fltenv_basic_gc, fltenv_data_gc; Widget listener_pane; Widget *dialogs; int num_dialogs, dialogs_size; Cursor graph_cursor, wait_cursor, bounds_cursor, play_cursor, loop_play_cursor, yaxis_cursor; Widget requestor_dialog; #if HAVE_GL #if USE_MOTIF GLXContext cx; #endif #endif Widget *mw; bool axis_color_set; #endif #if USE_GTK cairo_t *cr; double line_width; GtkWidget *mainshell; GtkWidget *mainpane; GtkWidget *soundpane; GtkWidget *soundpanebox; GtkWidget *listener_pane; GdkWindow *mainwindow; PangoFontDescription *listener_fnt; PangoFontDescription *axis_label_fnt; PangoFontDescription *axis_numbers_fnt; PangoFontDescription *tiny_fnt; PangoFontDescription *peaks_fnt; PangoFontDescription *bold_peaks_fnt; color_info *white, *black, *red, *yellow, *green, *blue, *light_blue, *lighter_blue; color_info *data_color, *selected_data_color, *mark_color, *graph_color, *selected_graph_color, *listener_color, *listener_text_color, *cursor_color; color_info *basic_color, *selection_color, *zoom_color, *position_color, *highlight_color, *enved_waveform_color; color_info *text_focus_color, *filter_control_waveform_color, *mix_color, *sash_color; color_info *selected_grid_color, *grid_color, *axis_color; color_info *orig_data_color, *orig_selected_data_color, *orig_mark_color, *orig_mix_color; color_info *orig_graph_color, *orig_selected_graph_color, *orig_listener_color, *orig_listener_text_color, *orig_cursor_color; color_info *orig_basic_color, *orig_selection_color, *orig_zoom_color, *orig_position_color, *orig_highlight_color; gc_t *basic_gc, *selected_basic_gc, *combined_basic_gc; gc_t *cursor_gc, *selected_cursor_gc; gc_t *selection_gc, *selected_selection_gc; gc_t *erase_gc, *selected_erase_gc; gc_t *mark_gc, *selected_mark_gc; gc_t *mix_gc; gc_t *fltenv_basic_gc, *fltenv_data_gc; GtkWidget **dialogs; int num_dialogs, dialogs_size; bool graph_is_active; GtkWidget *requestor_dialog; mus_float_t bg_gradient; GdkCursor *arrow_cursor, *wait_cursor, *graph_cursor, *bounds_cursor, *play_cursor, *loop_play_cursor, *yaxis_cursor; GtkWidget **mw; bool axis_color_set; glistener *listener; #endif #if USE_NO_GUI int data_color, selected_data_color, mix_color, basic_color, grid_color, selected_grid_color, mark_color, axis_color; int white, black, red, yellow, green, blue, light_blue; int fltenv_basic_gc, fltenv_data_gc; int basic_gc, selected_basic_gc, combined_basic_gc; int cursor_gc, selected_cursor_gc; int selection_gc, selected_selection_gc; int erase_gc, selected_erase_gc; int mark_gc, selected_mark_gc; int mix_gc; void *ignore_me; int requestor_dialog; bool axis_color_set; int bounds_cursor, graph_cursor, play_cursor, loop_play_cursor, yaxis_cursor; #endif #if HAVE_SCHEME s7_pointer data_color_symbol, selected_data_color_symbol, mark_color_symbol, graph_color_symbol, selected_graph_color_symbol, listener_color_symbol, listener_text_color_symbol, basic_color_symbol, selection_color_symbol, zoom_color_symbol, position_color_symbol, highlight_color_symbol, enved_waveform_color_symbol, cursor_color_symbol, text_focus_color_symbol, filter_control_waveform_color_symbol, mix_color_symbol, sash_color_symbol, axis_color_symbol; #endif } snd_state; extern snd_state *ss; typedef struct { int chans; mus_long_t *begs; chan_info **cps; } sync_info; typedef struct { int len; char **name; } region_state; typedef struct { char *key; bool c, m, x; } key_info; /* -------- snd-io.c -------- */ int snd_creat(const char *filename, mode_t mode); FILE *snd_fopen(const char *filename, const char *modes); int snd_open(const char *filename, int flags, mode_t mode); void snd_remove(const char *name, cache_remove_t forget); void snd_close(int fd, const char *name); void snd_fclose(FILE *fd, const char *name); io_error_t copy_file(const char *oldname, const char *newname); io_error_t move_file(const char *oldfile, const char *newfile); int snd_open_read(const char *arg); int snd_reopen_write(const char *arg); io_error_t snd_write_header(const char *name, mus_header_t type, int srate, int chans, mus_long_t samples, mus_sample_t sample_type, const char *comment, int *loops); io_error_t sndlib_error_to_snd(int sndlib_err); int snd_file_open_descriptors(int tfd, const char *name, mus_sample_t sample_type, mus_long_t location, int chans, mus_header_t type); snd_io *make_file_state(int fd, file_info *hdr, int chan, mus_long_t beg, int suggested_bufsize); void file_buffers_forward(mus_long_t ind0, mus_long_t ind1, mus_long_t indx, snd_fd *sf, snd_data *cur_snd); void file_buffers_back(mus_long_t ind0, mus_long_t ind1, mus_long_t indx, snd_fd *sf, snd_data *cur_snd); void remember_temp(const char *filename, int chans); void forget_temp(const char *filename, int chan); void forget_temps(void); snd_data *make_snd_data_file(const char *name, snd_io *io, file_info *hdr, file_delete_t temp, int ctr, int temp_chan); snd_data *copy_snd_data(snd_data *sd, mus_long_t beg, int bufsize); snd_data *free_snd_data(snd_data *sf); snd_data *make_snd_data_buffer(mus_float_t *data, int len, int ctr); snd_data *make_snd_data_buffer_for_simple_channel(int len); int open_temp_file(const char *ofile, int chans, file_info *hdr, io_error_t *err); io_error_t close_temp_file(const char *filename, int ofd, mus_header_t type, mus_long_t bytes); void set_up_snd_io(chan_info *cp, int i, int fd, const char *filename, file_info *hdr, bool post_close); mus_long_t io_beg(snd_io *io); mus_long_t io_end(snd_io *io); /* -------- snd-help.c -------- */ void about_snd_help(void); void controls_help(void); void fft_help(void); void find_help(void); void undo_help(void); void sync_help(void); void debug_help(void); void env_help(void); void marks_help(void); void mix_help(void); void sound_files_help(void); void init_file_help(void); void region_help(void); void selection_help(void); void colors_help(void); char *version_info(void); void transform_dialog_help(void); void color_orientation_dialog_help(void); void envelope_editor_dialog_help(void); void region_dialog_help(void); void raw_data_dialog_help(const char *info); void new_file_dialog_help(void); void edit_header_dialog_help(void); void print_dialog_help(void); void view_files_dialog_help(void); void mix_dialog_help(void); void find_dialog_help(void); void open_file_dialog_help(void); void mix_file_dialog_help(void); void insert_file_dialog_help(void); void save_as_dialog_help(void); char* word_wrap(const char *text, int widget_len); void g_init_help(void); Xen g_snd_help_with_search(Xen text, int widget_wid, bool search); Xen g_snd_help(Xen text, int widget_wid); const char *snd_url(const char *name); void set_html_dir(char *new_dir); void key_help(void); void play_help(void); void save_help(void); void reverb_help(void); void resample_help(void); void filter_help(void); void insert_help(void); void delete_help(void); void name_to_html_viewer(const char *red_text); void url_to_html_viewer(const char *url); bool snd_topic_help(const char *topic); const char **help_name_to_xrefs(const char *name); /* -------- snd-menu.c -------- */ void reflect_file_revert_in_label(snd_info *sp); void set_menu_label(widget_t w, const char *label); void g_init_menu(void); /* -------- snd-main.c -------- */ const char *save_options_in_prefs(void); void open_save_sound_block(snd_info *sp, FILE *fd, bool with_nth); void close_save_sound_block(FILE *fd, bool need_f); void save_sound_state(snd_info *sp, void *ptr); bool snd_exit_cleanly(bool force_exit); void sound_not_current(snd_info *sp); void save_state(const char *save_state_name); void global_control_panel_state(void); void global_fft_state(void); int handle_next_startup_arg(int auto_open_ctr, char **auto_open_file_names, bool with_title, int args); void g_init_main(void); /* -------- snd-completion.c -------- */ char *expression_completer(widget_t w, const char *text, void *data); void preload_best_completions(void); void save_completion_choice(const char *selection); int find_best_completion(char **choices, int num_choices); int add_completer_func(char *(*func)(widget_t w, const char *text, void *context), void *data); int add_completer_func_with_multicompleter(char *(*func)(widget_t w, const char *text, void *context), void *data, void (*multi_func)(widget_t w, void *data)); int get_completion_matches(void); void set_completion_matches(int matches); void set_save_completions(bool save); void add_possible_completion(const char *text); int get_possible_completions_size(void); char **get_possible_completions(void); void clear_possible_completions(void); void handle_completions(widget_t w, int completer); char *complete_text(widget_t w, const char *text, int func); char *filename_completer(widget_t w, const char *text, void *data); char *sound_filename_completer(widget_t w, const char *text, void *data); char *srate_completer(widget_t w, const char *text, void *data); char *list_completer(widget_t w, const char *text, void *data); char *complete_listener_text(char *old_text, int end, bool *try_completion, char **to_file_text); void add_srate_to_completion_list(int srate); char *direct_completions(const char *str); #if HAVE_FORTH || HAVE_RUBY void call_read_hook_or_eval(const char *text); #endif /* -------- snd-print.c -------- */ void ps_set_grf_points(double x, int j, mus_float_t ymin, mus_float_t ymax); void ps_set_grf_point(double x, int j, mus_float_t y); void ps_allocate_grf_points(void); void ps_draw_grf_points(axis_info *ap, int j, mus_float_t y0, graph_style_t graph_style, int dot_size); void ps_draw_both_grf_points(axis_info *ap, int j, graph_style_t graph_style, int dot_size); void ps_draw_sono_rectangle(axis_info *ap, int color, mus_float_t x, mus_float_t y, mus_float_t width, mus_float_t height); void ps_reset_color(void); void ps_bg(axis_info *ap, graphics_context *ax); void ps_fg(chan_info *cp, graphics_context *ax); void ps_draw_line(axis_info *ap, int x0, int y0, int x1, int y1); void ps_draw_spectro_line(axis_info *ap, int color, mus_float_t x0, mus_float_t y0, mus_float_t x1, mus_float_t y1); void ps_fill_rectangle(axis_info *ap, int x0, int y0, int width, int height); void ps_draw_string(axis_info *ap, int x0, int y0, const char *str); void ps_set_number_font(void); void ps_set_label_font(void); void ps_set_bold_peak_numbers_font(void); void ps_set_peak_numbers_font(void); void ps_set_tiny_numbers_font(void); bool snd_print(const char *output); void print_enved(const char *output, int y0); void g_init_print(void); /* -------- snd-marks.c -------- */ int mark_sync_max(void); void set_mark_sync(mark *m, int val); int mark_to_int(mark *m); int mark_sync(mark *m); mus_long_t mark_sample(mark *m); void marks_off(chan_info *cp); mark *hit_mark(chan_info *cp, int x, int y); void set_mark_control(chan_info *cp, mark *mp, int key_state); mark *hit_mark_triangle(chan_info *cp, int x, int y); void move_mark(chan_info *cp, mark *mp, int x); void play_syncd_mark(chan_info *cp, mark *mp); void finish_moving_mark(chan_info *cp, mark *m); mark *add_mark(mus_long_t samp, const char *name, chan_info *cp); bool delete_mark_samp(mus_long_t samp, chan_info *cp); void free_mark_list(ed_list *ed); bool goto_mark(chan_info *cp, int count); mark *active_mark(chan_info *cp); mus_long_t mark_beg(chan_info *cp); void display_channel_marks(chan_info *cp); void ripple_marks(chan_info *cp, mus_long_t beg, mus_long_t change); bool mark_define_region(chan_info *cp, int count); void save_mark_list(FILE *fd, chan_info *cp, bool all_chans); void reverse_marks(chan_info *cp, mus_long_t beg, mus_long_t dur); void src_marks(chan_info *cp, mus_float_t ratio, mus_long_t old_samps, mus_long_t new_samps, mus_long_t beg, bool over_selection); void reset_marks(chan_info *cp, int cur_marks, mus_long_t *samps, mus_long_t end, mus_long_t extension, bool over_selection); void ripple_trailing_marks(chan_info *cp, mus_long_t beg, mus_long_t old_len, mus_long_t new_len); void swap_marks(chan_info *cp0, chan_info *cp1); void g_init_marks(void); void *sound_store_marks(snd_info *sp); void sound_restore_marks(snd_info *sp, void *marks); mus_long_t mark_id_to_sample(int id); Xen new_xen_mark(int n); bool xen_is_mark(Xen obj); int xen_mark_to_int(Xen n); #define Xen_mark_to_C_int(n) xen_mark_to_int(n) Xen g_mark_sync(Xen mark_n); Xen g_set_mark_sync(Xen mark_n, Xen sync_n); /* -------- snd-data.c -------- */ chan_info *make_chan_info(chan_info *cip, int chan, snd_info *sound); snd_info *make_snd_info(snd_info *sip, const char *filename, file_info *hdr, int snd_slot, read_only_t read_only); snd_info *make_basic_snd_info(int chans); void initialize_control_panel(snd_info *sp); void free_snd_info(snd_info *sp); snd_info *completely_free_snd_info(snd_info *sp); void for_each_chan_with_int(void (*func)(chan_info *ncp, int val), int value); void for_each_chan_with_mus_long_t(void (*func)(chan_info *ncp, mus_long_t val), mus_long_t value); void for_each_chan_with_bool(void (*func)(chan_info *ncp, bool val), bool value); void for_each_chan_with_float(void (*func)(chan_info *ncp, mus_float_t val), mus_float_t value); void for_each_chan(void (*func)(chan_info *ncp)); void for_each_normal_chan(void (*func)(chan_info *ncp)); void for_each_normal_chan_with_void(void (*func)(chan_info *ncp, void *ptr), void *userptr); void for_each_normal_chan_with_int(void (*func)(chan_info *ncp, int val), int value); void for_each_normal_chan_with_refint(void (*func)(chan_info *ncp, int *val), int *value); void for_each_sound_chan(snd_info *sp, void (*func)(chan_info *ncp)); void for_each_sound_chan_with_int(snd_info *sp, void (*func)(chan_info *ncp, int val1), int value); void for_each_sound(void (*func)(snd_info *usp)); void for_each_sound_with_void(void (*func)(snd_info *usp, void *ptr), void *userptr); void for_each_separate_chan(void (*func)(chan_info *ncp)); bool map_over_sound_chans(snd_info *sp, bool (*func)(chan_info *ncp)); bool snd_ok(snd_info *sp); int active_channels(virtual_channels_t count_virtual_channels); int syncd_channels(int sync); int find_free_sound_slot(int desired_chans); int find_free_sound_slot_for_channel_display(void); snd_info *selected_sound(void); chan_info *selected_channel(void); chan_info *color_selected_channel(snd_info *sp); snd_info *any_selected_sound(void); chan_info *any_selected_channel(snd_info *sp); void select_channel(snd_info *sp, int chan); chan_info *current_channel(void); sync_info *free_sync_info(sync_info *si); sync_info *snd_sync(int sync); sync_info *sync_to_chan(chan_info *cp); sync_info *make_simple_sync(chan_info *cp, mus_long_t beg); snd_info *find_sound(const char *name, int nth); void mix_display_during_drag(int mix_id, mus_long_t drag_beg, mus_long_t drag_end); void g_init_data(void); /* -------- snd-edits.c -------- */ mus_float_t channel_maxamp(chan_info *cp, int edpos); mus_long_t channel_maxamp_position(chan_info *cp, int edpos); mus_float_t channel_maxamp_and_position(chan_info *cp, int edpos, mus_long_t *maxpos); ed_list *initial_ed_list(mus_long_t beg, mus_long_t end); snd_info *sound_is_silence(snd_info *sp); mus_long_t edit_changes_begin_at(chan_info *cp, int edpos); mus_long_t edit_changes_end_at(chan_info *cp, int edpos); bool has_unsaved_edits(snd_info *sp); char *run_save_state_hook(const char *filename); void edit_history_to_file(FILE *fd, chan_info *cp, bool with_save_state_hook); char *edit_to_string(chan_info *cp, int edit); void free_edit_list(chan_info *cp); void backup_edit_list(chan_info *cp); void as_one_edit(chan_info *cp, int one_edit); void free_sound_list(chan_info *cp); void after_edit(chan_info *cp); bool extend_with_zeros(chan_info *cp, mus_long_t beg, mus_long_t num, int edpos, const char *origin); bool insert_samples(mus_long_t beg, mus_long_t num, mus_float_t *vals, chan_info *cp, const char *origin, int edpos); bool file_insert_samples(mus_long_t beg, mus_long_t num, const char *tempfile, chan_info *cp, int chan, file_delete_t auto_delete, const char *origin, int edpos); bool insert_complete_file_at_cursor(snd_info *sp, const char *filename); bool insert_complete_file(snd_info *sp, const char *str, mus_long_t chan_beg, file_delete_t auto_delete); bool delete_samples(mus_long_t beg, mus_long_t num, chan_info *cp, int edpos); bool change_samples(mus_long_t beg, mus_long_t num, mus_float_t *vals, chan_info *cp, const char *origin, int edpos, mus_float_t mx); bool file_change_samples(mus_long_t beg, mus_long_t num, const char *tempfile, chan_info *cp, int chan, file_delete_t auto_delete, const char *origin, int edpos); bool file_override_samples(mus_long_t num, const char *tempfile, chan_info *cp, int chan, file_delete_t auto_delete, const char *origin); mus_float_t chn_sample(mus_long_t samp, chan_info *cp, int pos); void check_saved_temp_file(const char *type, Xen filename, Xen date_and_length); bool is_editable(chan_info *cp); file_delete_t xen_to_file_delete_t(Xen auto_delete, const char *caller); snd_fd *free_snd_fd(snd_fd *sf); char *sampler_to_string(snd_fd *fd); bool is_sampler(Xen obj); snd_fd *xen_to_sampler(Xen obj); snd_fd *free_snd_fd_almost(snd_fd *sf); bool scale_channel(chan_info *cp, mus_float_t scaler, mus_long_t beg, mus_long_t num, int pos, bool in_as_one_edit); bool scale_channel_with_origin(chan_info *cp, mus_float_t scl, mus_long_t beg, mus_long_t num, int pos, bool in_as_one_edit, const char *origin); bool ramp_channel(chan_info *cp, double start, double incr, mus_long_t beg, mus_long_t num, int pos, bool in_as_one_edit); bool xramp_channel(chan_info *cp, double start, double incr, double scaler, double offset, mus_long_t beg, mus_long_t num, int pos, bool in_as_one_edit, mus_any *e, int xramp_seg_loc); snd_fd *init_sample_read(mus_long_t samp, chan_info *cp, read_direction_t direction); snd_fd *init_sample_read_any(mus_long_t samp, chan_info *cp, read_direction_t direction, int edit_position); snd_fd *init_sample_read_any_with_bufsize(mus_long_t samp, chan_info *cp, read_direction_t direction, int edit_position, int bufsize); void read_sample_change_direction(snd_fd *sf, read_direction_t dir); void sampler_set_safe(snd_fd *sf, mus_long_t dur); bool unrampable(chan_info *cp, mus_long_t beg, mus_long_t dur, int pos, bool is_xramp); bool sound_fragments_in_use(chan_info *cp, int pos); #define read_sample(Sf) (*((Sf)->runf))(Sf) mus_float_t channel_local_maxamp(chan_info *cp, mus_long_t beg, mus_long_t num, int edpos, mus_long_t *maxpos); bool undo_edit_with_sync(chan_info *cp, int count); bool redo_edit_with_sync(chan_info *cp, int count); bool undo_edit(chan_info *cp, int count); bool redo_edit(chan_info *cp, int count); io_error_t save_channel_edits(chan_info *cp, const char *ofile, int pos); io_error_t channel_to_file_with_settings(chan_info *cp, const char *new_name, int srate, mus_sample_t samp_type, mus_header_t hd_type, const char *comment, int pos); io_error_t save_edits(snd_info *sp); io_error_t save_edits_without_asking(snd_info *sp); io_error_t save_edits_and_update_display(snd_info *sp); io_error_t save_edits_without_display(snd_info *sp, const char *new_name, mus_header_t type, mus_sample_t sample_type, int srate, const char *comment, int pos); void revert_edits(chan_info *cp); mus_long_t current_location(snd_fd *sf); void g_init_edits(void); void set_ed_maxamp(chan_info *cp, int edpos, mus_float_t val); mus_float_t ed_maxamp(chan_info *cp, int edpos); void set_ed_maxamp_position(chan_info *cp, int edpos, mus_long_t val); mus_long_t ed_maxamp_position(chan_info *cp, int edpos); void set_ed_selection_maxamp(chan_info *cp, mus_float_t val); mus_float_t ed_selection_maxamp(chan_info *cp); void set_ed_selection_maxamp_position(chan_info *cp, mus_long_t val); mus_long_t ed_selection_maxamp_position(chan_info *cp); void copy_then_swap_channels(chan_info *cp0, chan_info *cp1, int pos0, int pos1); void reflect_file_change_in_label(chan_info *cp); void reflect_file_change_in_title(void); int mix_buffer_with_tag(chan_info *cp, mus_float_t *data, mus_long_t beg, mus_long_t num, const char *origin); int mix_file_with_tag(chan_info *cp, const char *filename, int chan, mus_long_t beg, file_delete_t auto_delete, const char *origin); void unmix(chan_info *cp, mix_state *ms); void remix(chan_info *cp, mix_state *ms); snd_fd *make_virtual_mix_reader(chan_info *cp, mus_long_t beg, mus_long_t len, int index, mus_float_t scl, read_direction_t direction); bool virtual_mix_ok(chan_info *cp, int edpos); bool begin_mix_op(chan_info *cp, mus_long_t old_beg, mus_long_t old_len, mus_long_t new_beg, mus_long_t new_len, int edpos, const char *caller); void end_mix_op(chan_info *cp, mus_long_t old_beg, mus_long_t old_len); void prepare_sound_list(chan_info *cp); Xen g_sampler_file_name(Xen obj); char *edit_list_to_function(chan_info *cp, int start_pos, int end_pos); vct *samples_to_vct(mus_long_t beg, mus_long_t len, chan_info *cp, int pos, mus_float_t *buf, snd_fd *reader); vct *samples_to_vct_with_reader(mus_long_t len, mus_float_t *buf, snd_fd *reader); /* -------- snd-fft.c -------- */ int find_and_sort_transform_peaks(mus_float_t *buf, fft_peak *found, int num_peaks, mus_long_t losamp, mus_long_t hisamp, mus_float_t samps_per_pixel, mus_float_t fft_scale); int find_and_sort_peaks(mus_float_t *buf, fft_peak *found, int num_peaks, mus_long_t losamp, mus_long_t hisamp); fft_info *free_fft_info(fft_info *fp); void free_sonogram_fft_state(void *ptr); bool fft_window_beta_in_use(mus_fft_window_t win); bool fft_window_alpha_in_use(mus_fft_window_t win); void free_sono_info(chan_info *cp); void sono_update(chan_info *cp); void c_convolve(const char *fname, mus_float_t amp, int filec, mus_long_t filehdr, int filterc, mus_long_t filterhdr, mus_long_t filtersize, mus_long_t fftsize, int filter_chans, int filter_chan, mus_long_t data_size, snd_info *gsp); void *make_sonogram_state(chan_info *cp, bool force_recalc); void single_fft(chan_info *cp, bool update_display, bool force_recalc); idle_func_t sonogram_in_slices(void *sono); void clear_transform_edit_ctrs(chan_info *cp); void g_init_fft(void); mus_float_t fft_beta_max(mus_fft_window_t win); void cp_free_fft_state(chan_info *cp); void set_fft_info_xlabel(chan_info *cp, const char *new_label); void fourier_spectrum(snd_fd *sf, mus_float_t *data, mus_long_t fft_size, mus_long_t data_len, mus_float_t *window, chan_info *cp); const char *wavelet_name(int i); const char **wavelet_names(void); void set_log_freq_start(mus_float_t base); const char *transform_name(int type); const char *transform_program_name(int type); int transform_position_to_type(int pos); int transform_type_to_position(int type); int max_transform_type(void); void set_transform_position(int i, int j); bool is_transform(int type); Xen new_xen_transform(int n); bool xen_is_transform(Xen obj); int xen_transform_to_int(Xen n); #define C_int_to_Xen_transform(Val) new_xen_transform(Val) #define Xen_transform_to_C_int(n) xen_transform_to_int(n) /* -------- snd-xen.c -------- */ const char *io_error_name(io_error_t err); #ifdef __GNUC__ void snd_error(const char *format, ...) __attribute__ ((format (printf, 1, 2))); void snd_warning(const char *format, ...) __attribute__ ((format (printf, 1, 2))); #else void snd_error(const char *format, ...); void snd_warning(const char *format, ...); #endif void snd_error_without_format(const char *msg); void snd_warning_without_format(const char *msg); void redirect_snd_error_to(void (*handler)(const char *error_msg, void *ufd), void *data); void redirect_snd_warning_to(void (*handler)(const char *warning_msg, void *ufd), void *data); char *stdin_check_for_full_expression(const char *newstr); void stdin_free_str(void); void redirect_xen_error_to(void (*handler)(const char *msg, void *ufd), void *data); void redirect_errors_to(void (*handler)(const char *msg, void *ufd), void *data); void redirect_everything_to(void (*handler)(const char *msg, void *ufd), void *data); Xen snd_catch_any(Xen_catch_t body, void *body_data, const char *caller); Xen snd_throw(Xen key, Xen args); Xen snd_no_such_file_error(const char *caller, Xen filename); Xen snd_no_such_channel_error(const char *caller, Xen snd, Xen chn); Xen snd_bad_arity_error(const char *caller, Xen errstr, Xen proc); Xen snd_no_active_selection_error(const char *caller); void g_xen_initialize(void); Xen eval_str_wrapper(void *data); Xen g_c_make_sampler(snd_fd *fd); char *procedure_ok(Xen proc, int args, const char *caller, const char *arg_name, int argn); bool procedure_arity_ok(Xen proc, int args); int snd_protect(Xen obj); void snd_unprotect_at(int loc); Xen run_or_hook(Xen hook, Xen args, const char *caller); Xen run_progn_hook(Xen hook, Xen args, const char *caller); Xen run_hook(Xen hook, Xen args, const char *caller); void check_features_list(const char *features); #if (!USE_NO_GUI) mus_float_t check_color_range(const char *caller, Xen val); #endif void set_basic_color(color_t color); void set_highlight_color(color_t color); void set_position_color(color_t color); void set_zoom_color(color_t color); void set_data_color(color_t color); void set_selected_data_color(color_t color); void set_graph_color(color_t color); void set_selected_graph_color(color_t color); mus_float_t string_to_mus_float_t(const char *str, mus_float_t lo, const char *file_name); int string_to_int(const char *str, int lo, const char *field_name); mus_long_t string_to_mus_long_t(const char *str, mus_long_t lo, const char *field_name); char *output_comment(file_info *hdr); void snd_load_init_file(bool nog, bool noi); void snd_load_file(const char *filename); void snd_display_result(const char *str, const char *endstr); void snd_report_result(Xen result, const char *buf); void snd_report_listener_result(Xen form); void snd_eval_stdin_str(const char *buf); void clear_stdin(void); #if HAVE_RUBY void snd_rb_raise(Xen type, Xen info); #endif bool is_source_file(const char *name); void save_added_source_file_extensions(FILE *fd); /* -------- snd-select.c -------- */ bool selection_is_active(void); bool selection_is_active_in_channel(chan_info *cp); bool selection_is_visible_in_channel(chan_info *cp); mus_long_t selection_beg(chan_info *cp); mus_long_t selection_end(chan_info *cp); mus_long_t selection_len(void); int selection_chans(void); int selection_srate(void); mus_float_t selection_maxamp(chan_info *cp); void deactivate_selection(void); void reactivate_selection(chan_info *cp, mus_long_t beg, mus_long_t end); void ripple_selection(ed_list *new_ed, mus_long_t beg, mus_long_t num); sync_info *selection_sync(void); void start_selection_creation(chan_info *cp, mus_long_t samp); void update_possible_selection_in_progress(mus_long_t samp); void restart_selection_creation(chan_info *cp, bool right); bool hit_selection_triangle(chan_info *cp, int x, int y); bool hit_selection_loop_triangle(chan_info *cp, int x, int y); void cp_delete_selection(chan_info *cp); int make_region_from_selection(void); void display_selection(chan_info *cp); bool delete_selection(cut_selection_regraph_t regraph); void move_selection(chan_info *cp, int x); void finish_selection_creation(void); int select_all(chan_info *cp); io_error_t save_selection(const char *ofile, int srate, mus_sample_t samp_type, mus_header_t head_type, const char *comment, int chan); bool selection_creation_in_progress(void); void add_selection_or_region(int reg, chan_info *cp); void insert_selection_from_menu(void); void cancel_selection_watch(void); void show_selection(void); bool xen_is_selection(Xen obj); Xen g_selection_chans(void); Xen g_selection_srate(void); Xen g_selection_maxamp(Xen snd, Xen chn); Xen g_selection_framples(Xen snd, Xen chn); void g_init_selection(void); /* -------- snd-region.c -------- */ void allocate_regions(int numreg); bool region_ok(int n); int region_chans(int n); int region_srate(int n); const char *region_file_name(int n); mus_long_t region_len(int n); mus_float_t region_maxamp(int n); int region_list_position_to_id(int n); int region_id_to_list_position(int id); file_info *fixup_region_data(chan_info *cp, int chan, int n); region_state *region_report(void); void free_region_state(region_state *r); int remove_region_from_list(int pos); io_error_t paste_region(int n, chan_info *cp); io_error_t add_region(int n, chan_info *cp); int define_region(sync_info *si, mus_long_t *ends); snd_fd *init_region_read(mus_long_t beg, int n, int chan, read_direction_t direction); void cleanup_region_temp_files(void); int snd_regions(void); void save_regions(FILE *fd); io_error_t save_region(int rg, const char *name, mus_sample_t samp_type, mus_header_t head_type, const char *comment); void region_edit(int reg); void clear_region_backpointer(snd_info *sp); void save_region_backpointer(snd_info *sp); void sequester_deferred_regions(chan_info *cp, int edit_top); void g_init_regions(void); void for_each_region_chan_with_refint(void (*func)(chan_info *ncp, int *val), int *value); mus_long_t region_current_location(snd_fd *fd); char *region_description(int rg); Xen new_xen_region(int n); bool xen_is_region(Xen obj); int xen_region_to_int(Xen n); #define C_int_to_Xen_region(Val) new_xen_region(Val) #define Xen_region_to_C_int(n) xen_region_to_int(n) Xen g_region_srate(Xen n); Xen g_region_chans(Xen n); Xen g_region_framples(Xen n, Xen chan); Xen g_region_maxamp(Xen n); Xen g_play_region(Xen n, play_process_t back, Xen stop_proc); Xen g_region_to_vct(Xen reg_n, Xen beg_n, Xen num, Xen chn_n, Xen v); /* -------- snd-env.c -------- */ env *copy_env(env *e); env *free_env(env *e); char *env_to_string(env *e); env *make_envelope_with_offset_and_scaler(mus_float_t *env_buffer, int len, mus_float_t offset, mus_float_t scaler); env *default_env(mus_float_t x1, mus_float_t y); bool is_default_env(env *e); bool envs_equal(env *e1, env *e2); env_editor *new_env_editor(void); void env_editor_button_motion_with_xy(env_editor *edp, int evx, int evy, oclock_t motion_time, env *e, mus_float_t *new_x, mus_float_t *new_y); void env_editor_button_motion(env_editor *edp, int evx, int evy, oclock_t motion_time, env *e); bool env_editor_button_press(env_editor *edp, int evx, int evy, oclock_t time, env *e); void env_editor_button_release(env_editor *edp, env *e); double env_editor_ungrf_y_dB(env_editor *edp, int y); void init_env_axes(axis_info *ap, const char *name, int x_offset, int ey0, int width, int height, mus_float_t xmin, mus_float_t xmax, mus_float_t ymin, mus_float_t ymax, printing_t printing); void env_editor_display_env(env_editor *edp, env *e, graphics_context *ax, const char *name, int x0, int y0, int width, int height, printing_t printing); void view_envs(int env_window_width, int env_window_height, printing_t printing); int hit_env(int xe, int ye, int env_window_width, int env_window_height); void prepare_enved_edit(env *new_env); void redo_env_edit(void); void undo_env_edit(void); void revert_env_edit(void); int enved_all_envs_top(void); char *enved_all_names(int n); void set_enved_env_list_top(int n); /* env *enved_all_envs(int pos); */ void alert_envelope_editor(const char *name, env *val); void enved_show_background_waveform(axis_info *ap, axis_info *gray_ap, bool apply_to_selection, bool show_fft, printing_t printing); void save_envelope_editor_state(FILE *fd); char *env_name_completer(widget_t w, const char *text, void *data); env *enved_next_env(void); env *string_to_env(const char *str); void add_or_edit_symbol(const char *name, env *val); env* name_to_env(const char *str); env *position_to_env(int pos); /* void delete_envelope(const char *name); */ enved_fft *free_enved_fft(enved_fft *ef); void reflect_enved_fft_change(chan_info *cp); Xen env_to_xen(env *e); env *xen_to_env(Xen res); env *get_env(Xen e, const char *origin); void g_init_env(void); /* -------- snd-dac.c -------- */ void cleanup_dac(void); void stop_playing_sound(snd_info *sp, play_stop_t reason); void stop_playing_sound_without_hook(snd_info *sp, play_stop_t reason); void stop_playing_sound_no_toggle(snd_info *sp, play_stop_t reason); void stop_playing_all_sounds(play_stop_t reason); void stop_playing_region(int n, play_stop_t reason); void play_region(int n, play_process_t background); void play_region_1(int region, play_process_t background, Xen stop_proc); void play_channel(chan_info *cp, mus_long_t start, mus_long_t end); void play_channel_with_sync(chan_info *cp, mus_long_t start, mus_long_t end); void play_sound(snd_info *sp, mus_long_t start, mus_long_t end); void play_channels(chan_info **cps, int chans, mus_long_t *starts, mus_long_t *ur_ends, play_process_t background, Xen edpos, bool selection, const char *caller, int arg_pos); void play_selection(play_process_t background); void loop_play_selection(void); bool add_mix_to_play_list(mix_state *ms, chan_info *cp, mus_long_t beg_within_mix, bool start_playing); void toggle_dac_pausing(void); /* snd-dac.c */ bool play_in_progress(void); void initialize_apply(snd_info *sp, int chans, mus_long_t beg, mus_long_t framples); void finalize_apply(snd_info *sp); int run_apply(int ofd); mus_float_t *sample_linear_env(env *e, int order); void g_init_dac(void); void clear_players(void); bool xen_is_player(Xen obj); #define is_player_sound(Sp) ((Sp) && ((Sp)->index < 0)) snd_info *get_player_sound(Xen player); Xen no_such_player_error(const char *caller, Xen player); void dac_set_expand(snd_info *sp, mus_float_t newval); void dac_set_expand_length(snd_info *sp, mus_float_t newval); void dac_set_expand_ramp(snd_info *sp, mus_float_t newval); void dac_set_expand_hop(snd_info *sp, mus_float_t newval); void dac_set_contrast_amp(snd_info *sp, mus_float_t newval); void dac_set_reverb_feedback(snd_info *sp, mus_float_t newval); void dac_set_reverb_lowpass(snd_info *sp, mus_float_t newval); /* -------- snd-chn.c -------- */ bool is_graph_style(int grf); chan_info *get_cp(Xen snd_n, Xen chn_n, const char *caller); snd_info *make_simple_channel_display(int srate, int initial_length, fw_button_t with_arrows, graph_style_t grf_style, widget_t container, bool with_events); axis_info *lisp_info_axis(chan_info *cp); void free_lisp_info(chan_info *cp); void zx_incremented(chan_info *cp, double amount); kbd_cursor_t cursor_decision(chan_info *cp); void reset_x_display(chan_info *cp, double sx, double zx); void set_x_axis_x0x1(chan_info *cp, double x0, double x1); void cursor_move(chan_info *cp, mus_long_t samps); void cursor_moveto_without_verbosity(chan_info *cp, mus_long_t samp); void cursor_moveto_with_window(chan_info *cp, mus_long_t samp, mus_long_t left_samp, mus_long_t window_size); void sync_cursors(chan_info *cp, mus_long_t samp); void set_wavo_trace(int uval); void set_dot_size(int val); chan_info *virtual_selected_channel(chan_info *cp); void handle_cursor(chan_info *cp, kbd_cursor_t redisplay); void handle_cursor_with_sync(chan_info *cp, kbd_cursor_t redisplay); void chans_field(fcp_t field, mus_float_t val); void in_set_transform_graph_type(graph_type_t val); void in_set_fft_window(mus_fft_window_t val); void set_max_transform_peaks(int val); void combine_sound(snd_info *sp); void separate_sound(snd_info *sp); void superimpose_sound(snd_info *sp); void set_sound_channel_style(snd_info *sp, channel_style_t val); void set_chan_fft_in_progress(chan_info *cp, idle_t fp); void stop_fft_in_progress(chan_info *cp); void goto_graph(chan_info *cp); void start_peak_env(chan_info *cp); void stop_peak_env(chan_info *cp); void write_transform_peaks(FILE *fd, chan_info *ucp); bool chan_fft_in_progress(chan_info *cp); void force_fft_clear(chan_info *cp); void chan_info_cleanup(chan_info *cp); void display_channel_data_for_print(chan_info *cp); void update_graph(chan_info *cp); void update_graph_or_warn(chan_info *cp); void make_partial_graph(chan_info *cp, mus_long_t beg, mus_long_t end); void add_channel_data(char *filename, chan_info *cp, channel_graph_t graphed); bool add_channel_data_1(chan_info *cp, int srate, mus_long_t framples, channel_graph_t graphed); void set_x_bounds(axis_info *ap); void set_show_axes(show_axes_t val); void display_channel_data(chan_info *cp); void display_channel_fft_data(chan_info *cp); void display_channel_time_data(chan_info *cp); void show_cursor_info(chan_info *cp); void apply_x_axis_change(chan_info *cp); void apply_y_axis_change(chan_info *cp); void sx_incremented(chan_info *cp, double amount); int move_axis(chan_info *cp, int x); void set_axes(chan_info *cp, double x0, double x1, mus_float_t y0, mus_float_t y1); void focus_x_axis_change(chan_info *cp, int focus_style); void key_press_callback(chan_info *ur_cp, int x, int y, int key_state, int keysym); void graph_button_press_callback(chan_info *cp, void *ev, int x, int y, int key_state, int button, oclock_t time); void graph_button_release_callback(chan_info *cp, int x, int y, int key_state, int button); void graph_button_motion_callback(chan_info *cp, int x, int y, oclock_t time); void channel_resize(chan_info *cp); void edit_history_select(chan_info *cp, int row); int make_background_graph(chan_info *cp, int srate, bool *two_sided); int make_dragged_marks_graph(chan_info *cp); void reset_spectro(void); void cursor_moveto(chan_info *cp, mus_long_t samp); chan_info *which_channel(snd_info *sp, int y); void set_show_grid(with_grid_t val); void set_grid_density(mus_float_t val); void set_cursor_size(int val); void set_cursor_style(cursor_style_t val); void set_show_mix_waveforms(bool val); void clear_inset_graph(chan_info *cp); void free_inset_graph(chan_info *cp); void draw_inset_line_cursor(chan_info *cp, graphics_context *ax); void make_sonogram(chan_info *cp); void g_init_chn(void); Xen make_graph_data(chan_info *cp, int edit_pos, mus_long_t losamp, mus_long_t hisamp); void draw_graph_data(chan_info *cp, mus_long_t losamp, mus_long_t hisamp, int data_size, mus_float_t *data, mus_float_t *data1, graphics_context *ax, graph_style_t style); void fftb(chan_info *cp, bool on); void waveb(chan_info *cp, bool on); void f_button_callback(chan_info *cp, bool on, bool with_control); void w_button_callback(chan_info *cp, bool on, bool with_control); graphics_context *set_context(chan_info *cp, chan_gc_t gc); graphics_context *copy_context(chan_info *cp); graphics_context *erase_context(chan_info *cp); graphics_context *selection_context(chan_info *cp); graphics_context *mark_tag_context(chan_info *cp); graphics_context *mix_waveform_context(chan_info *cp); graphics_context *cursor_context(chan_info *cp); void calculate_fft(chan_info *cp); void set_min_db(mus_float_t db); void set_x_axis_style(x_axis_style_t val); void set_with_verbose_cursor(bool val); void set_graph_style(graph_style_t val); void set_show_marks(bool val); void set_show_y_zero(bool val); Xen g_framples(Xen snd_n, Xen chn_n, Xen edpos); void check_cursor_shape(chan_info *cp, int x, int y); widget_t channel_to_widget(chan_info *cp); chan_info *channel_to_chan(chan_info *cp); /* -------- snd-axis.c -------- */ bool is_x_axis_style(int n); bool shows_axes(int n); axis_info *free_axis_info(axis_info *ap); char *x_axis_location_to_string(chan_info *cp, double loc); int grf_x(double val, axis_info *ap); int grf_y(mus_float_t val, axis_info *ap); void init_axis_scales(axis_info *ap); void make_axes_1(axis_info *ap, x_axis_style_t x_style, int srate, show_axes_t axes, printing_t printing, with_x_axis_t show_x_axis, with_grid_t grid, log_axis_t log_axes, mus_float_t grid_scale); #define ungrf_x(AP, X) (((X) - (AP)->x_base) / (AP)->x_scale) #define ungrf_y(AP, Y) (((Y) - (AP)->y_base) / (AP)->y_scale) axis_info *make_axis_info(chan_info *cp, double xmin, double xmax, mus_float_t ymin, mus_float_t ymax, const char *xlabel, double x0, double x1, mus_float_t y0, mus_float_t y1, axis_info *old_ap); void set_numbers_font(graphics_context *ax, printing_t printing, bool use_tiny_font); #if (!USE_NO_GUI) void g_init_axis(void); #endif #if HAVE_GL void reload_label_font(void); void reload_number_font(void); #endif /* -------- snd-snd.c -------- */ snd_info *get_sp(Xen snd_n); peak_env_info *free_peak_env(chan_info *cp, int pos); void free_peak_env_state(chan_info *cp); peak_env_info *free_peak_env_info(peak_env_info *ep); void start_peak_env_state(chan_info *cp); idle_func_t get_peak_env(any_pointer_t ptr); void finish_peak_env(chan_info *cp); bool peak_env_maxamp_ok(chan_info *cp, int edpos); mus_float_t peak_env_maxamp(chan_info *cp, int edpos); bool peak_env_usable(chan_info *cp, mus_float_t samples_per_pixel, mus_long_t hisamp, bool start_new, int edit_pos, bool finish_env); int peak_env_graph(chan_info *cp, mus_float_t samples_per_pixel, int srate); int peak_env_partial_graph(chan_info *cp, mus_long_t beg, mus_long_t end, mus_float_t samples_per_pixel, int srate); char *shortname(snd_info *sp); char *shortname_indexed(snd_info *sp); void add_sound_data(char *filename, snd_info *sp, channel_graph_t graphed); mus_float_t speed_changed(mus_float_t ival, char *srcbuf, speed_style_t style, int tones, int srcbuf_size); char *sp_name_click(snd_info *sp); void free_controls(snd_info *sp); void save_controls(snd_info *sp); void restore_controls(snd_info *sp); void reset_controls(snd_info *sp); void set_show_controls(bool val); void stop_applying(snd_info *sp); void expand_control_set_hop(mus_float_t hop); void expand_control_set_length(mus_float_t hop); void expand_control_set_ramp(mus_float_t hop); void expand_control_set_jitter(mus_float_t hop); void contrast_control_set_amp(mus_float_t hop); void reverb_control_set_lowpass(mus_float_t hop); void reverb_control_set_feedback(mus_float_t hop); void amp_env_env(chan_info *cp, mus_float_t *brkpts, int npts, int pos, mus_float_t base, mus_float_t scaler, mus_float_t offset); peak_env_info *copy_peak_env_info(peak_env_info *old_ep, bool reversed); void amp_env_env_selection_by(chan_info *cp, mus_any *e, mus_long_t beg, mus_long_t num, int pos); void peak_env_insert_zeros(chan_info *cp, mus_long_t beg, mus_long_t num, int pos); snd_info *snd_new_file(const char *newname, int chans, int srate, mus_sample_t sample_type, mus_header_t header_type, const char *new_comment, mus_long_t samples); #if XEN_HAVE_RATIOS void snd_rationalize(mus_float_t a, int *num, int *den); #endif #ifdef __GNUC__ void status_report(snd_info *sp, const char *format, ...) __attribute__ ((format (printf, 2, 3))); #else void status_report(snd_info *sp, const char *format, ...); #endif void errors_to_status_area(const char *msg, void *data); void printout_to_status_area(const char *msg, void *data); void clear_status_area(snd_info *sp);; void g_init_snd(void); Xen snd_no_such_sound_error(const char *caller, Xen n); void peak_env_scale_by(chan_info *cp, mus_float_t scl, int pos); void peak_env_scale_selection_by(chan_info *cp, mus_float_t scl, mus_long_t beg, mus_long_t num, int pos); peak_env_info *peak_env_copy(chan_info *cp, bool reversed, int edpos); peak_env_info *peak_env_section(chan_info *cp, mus_long_t beg, mus_long_t num, int edpos); void pick_one_bin(peak_env_info *ep, int bin, mus_long_t cursamp, chan_info *cp, int edpos); void set_channel_style(channel_style_t val); Xen new_xen_sound(int n); bool xen_is_sound(Xen obj); int xen_sound_to_int(Xen n); #define C_int_to_Xen_sound(Val) new_xen_sound(Val) #define Xen_sound_to_C_int(n) xen_sound_to_int(n) const char *read_peak_env_info_file(chan_info *cp); bool write_peak_env_info_file(chan_info *cp); void delete_peak_env_info_file(chan_info *cp); /* -------- snd-file -------- */ axes_data *free_axes_data(axes_data *sa); axes_data *make_axes_data(snd_info *sp); void restore_axes_data(snd_info *sp, axes_data *sa, mus_float_t new_duration, bool need_edit_history_update); mus_long_t disk_kspace(const char *filename); time_t file_write_date(const char *filename); bool is_link_file(const char *filename); int recent_files_size(void); char **recent_files(void); bool is_directory(const char *filename); file_info *make_file_info(const char *fullname, read_only_t read_only, bool selected); file_info *free_file_info(file_info *hdr); file_info *copy_header(const char *fullname, file_info *ohdr); file_info *make_temp_header(const char *fullname, int srate, int chans, mus_long_t samples, const char *caller); bool is_sound_file(const char *name); void init_sound_file_extensions(void); void save_added_sound_file_extensions(FILE *fd); const char **get_sound_file_extensions(void); int sound_file_extensions_length(void); snd_info *snd_open_file(const char *filename, read_only_t read_only); void snd_close_file(snd_info *sp); snd_info *make_sound_readable(const char *filename, bool post_close); snd_info *snd_update(snd_info *sp); snd_info *snd_update_within_xen(snd_info *sp, const char *caller); int snd_decode(mus_header_t type, const char *input_filename, const char *output_filename); void set_fallback_srate(int sr); void set_fallback_chans(int ch); void set_fallback_sample_type(mus_sample_t fr); void set_with_tooltips(bool val); void run_after_save_as_hook(snd_info *sp, const char *already_saved_as_name, bool from_save_as_dialog); bool run_before_save_as_hook(snd_info *sp, const char *save_as_filename, bool selection, int srate, mus_sample_t smp_type, mus_header_t hd_type, const char *comment); void during_open(int fd, const char *file, open_reason_t reason); void after_open(snd_info *sp); void set_with_toolbar_and_display(bool val); #if (!USE_NO_GUI) void display_info(snd_info *sp); #endif void g_init_file(void); void initialize_sample_type_lists(void); void set_with_menu_icons(bool val); Xen g_expand_vector(Xen vector, int new_size); /* -------- snd-utils -------- */ int snd_round(double x); mus_long_t snd_round_mus_long_t(double x); mus_long_t snd_abs_mus_long_t(mus_long_t val); int snd_int_pow2(int n); mus_long_t snd_mus_long_t_pow2(int n); int snd_to_int_pow2(int n); int snd_int_log2(int n); bool snd_feq(mus_float_t val1, mus_float_t val2); #if defined(__GNUC__) && (!(defined(__cplusplus))) #define in_dB(Min_Db, Lin_Db, Val) ({ mus_float_t _snd_1_h_1 = Val; (_snd_1_h_1 <= Lin_Db) ? Min_Db : (20.0 * log10(_snd_1_h_1)); }) #else mus_float_t in_dB(mus_float_t min_dB, mus_float_t lin_dB, mus_float_t val); #endif char *snd_local_time(void); char *snd_io_strerror(void); char *snd_open_strerror(void); char *string_to_colon(char *val); char *filename_without_directory(const char *name); char *just_filename(char *name); char *just_directory(const char *name); char *file_to_string(const char *filename); #ifdef __GNUC__ char *vstr(const char *format, va_list ap) __attribute__ ((format (printf, 1, 0))); char *snd_strftime(const char *format, time_t date) __attribute__ ((format (strftime, 1, 0))); #else char *vstr(const char *format, va_list ap); char *snd_strftime(const char *format, time_t date); #endif disk_space_t disk_has_space(mus_long_t bytes, const char *filename); char *prettyf(double num, int tens); char *shorter_tempnam(const char *dir, const char *prefix); char *snd_tempnam(void); void snd_exit(int val); void g_init_utils(void); /* -------- snd-listener -------- */ void g_init_listener(void); #if HAVE_SCHEME void listener_begin_hook(s7_scheme *sc, bool *val); #endif void set_listener_prompt(const char *new_prompt); bool listener_is_visible(void); Xen run_read_hook(char *str); bool have_read_hook(void); /* -------- snd-mix.c -------- */ void free_ed_mixes(void *ptr); bool mix_exists(int n); bool mix_is_active(int n); bool channel_has_mixes(chan_info *cp); bool channel_has_active_mixes(chan_info *cp); const char *mix_name(int id); const char *mix_file_name(int id); int mix_name_to_id(const char *name); void goto_mix(chan_info *cp, int count); mus_long_t zoom_focus_mix_in_channel_to_position(chan_info *cp); int any_mix_id(void); int next_mix_id(int id); int previous_mix_id(int id); int lowest_mix_id(void); int highest_mix_id(void); void reset_mix_ctr(void); void preload_mixes(mix_state **mixes, int low_id, ed_list *ed); void free_channel_mixes(chan_info *cp); void delete_any_remaining_mix_temp_files_at_exit(chan_info *cp); int mix_sync_from_id(int id); int mix_set_sync_from_id(int id, int new_sync); void set_mix_waveform_height(int new_val); Xen new_xen_mix(int n); Xen g_make_mix_sampler(Xen mix_id, Xen ubeg); bool xen_is_mix(Xen obj); snd_fd *xen_mix_to_snd_fd(Xen obj); int xen_mix_to_int(Xen n); #define Xen_mix_to_C_int(n) xen_mix_to_int(n) Xen g_mix_length(Xen n); Xen g_mix_sync(Xen n); Xen g_set_mix_sync(Xen n, Xen val); Xen g_mix_maxamp(Xen mix_id); Xen g_mix_to_vct(Xen mix_n, Xen beg_n, Xen num); mus_long_t mix_position_from_id(int id); mus_long_t mix_length_from_id(int id); mus_float_t mix_amp_from_id(int id); mus_float_t mix_speed_from_id(int id); env *mix_amp_env_from_id(int id); chan_info *mix_chan_info_from_id(int id); int copy_mix(int id); mix_state *prepare_mix_state_for_channel(chan_info *cp, int mix_loc, mus_long_t beg, mus_long_t len); void add_ed_mix(ed_list *ed, mix_state *ms); mix_state *copy_mix_state(mix_state *old_ms); void g_init_mix(void); bool mix_set_position_edit(int id, mus_long_t pos); bool mix_set_amp_env_edit(int id, env *e); bool mix_set_amp_edit(int id, mus_float_t amp); bool mix_set_speed_edit(int id, mus_float_t spd); void after_mix_edit(int id); void syncd_mix_set_color(int id, color_t col); void syncd_mix_unset_color(int id); void syncd_mix_set_amp(int id, mus_float_t amp); void syncd_mix_set_speed(int id, mus_float_t amp); void syncd_mix_set_amp_env(int id, env *e); void syncd_mix_play(int id); void mix_unset_color_from_id(int id); color_t mix_color_from_id(int mix_id); color_t mix_set_color_from_id(int id, color_t new_color); void start_dragging_syncd_mixes(int mix_id); void keep_dragging_syncd_mixes(int mix_id); void stop_dragging_syncd_mixes(int mix_id); void after_syncd_mix_edit(int id); void syncd_mix_change_position(int mix_id, mus_long_t change); int mix_complete_file(snd_info *sp, mus_long_t beg, const char *fullname, bool with_tag, file_delete_t auto_delete, mix_sync_t all_chans, int *out_chans); int mix_complete_file_at_cursor(snd_info *sp, const char *str); int mix_file(mus_long_t beg, mus_long_t num, int chans, chan_info **cps, const char *mixinfile, file_delete_t temp, const char *origin, bool with_tag, int start_chan); bool is_mix_sampler(Xen obj); Xen g_copy_mix_sampler(Xen obj); Xen g_mix_sampler_home(Xen obj); Xen g_mix_sampler_is_at_end(Xen obj); Xen g_mix_sampler_position(Xen obj); Xen g_free_mix_sampler(Xen obj); char *edit_list_mix_init(chan_info *cp); void channel_set_mix_tags_erased(chan_info *cp); void color_mixes(color_t color); void move_mix_tag(int mix_tag, int x, int y); void finish_moving_mix_tag(int mix_tag, int x); int hit_mix(chan_info *cp, int x, int y); int hit_mix_triangle(chan_info *cp, int x, int y); int prepare_mix_dialog_waveform(int mix_id, axis_info *ap, bool *two_sided); void display_channel_mixes(chan_info *cp); bool play_mix_from_id(int mix_id); Xen g_play_mix(Xen num, mus_long_t beg); void drag_and_drop_mix_at_x_y(int data, const char *filename, int x, int y); snd_fd *mf_to_snd_fd(void *p); /* -------- snd-find.c -------- */ #if HAVE_EXTENSION_LANGUAGE && (!USE_NO_GUI) void find_dialog_find(char *str, read_direction_t direction, chan_info *cp); #endif void g_init_find(void); /* -------- snd-trans.c -------- */ int snd_translate(const char *oldname, const char *newname, mus_header_t type); /* -------- snd.c -------- */ void snd_set_global_defaults(bool need_cleanup); void g_init_base(void); /* -------- snd-kbd.c -------- */ int in_keymap(int key, int state, bool cx_extended); void set_keymap_entry(int key, int state, int args, Xen func, bool cx_extended, const char *origin, const char *prefs_info); char *key_description(int key, int state, bool cx_extended); char *make_key_name(char *buf, int buf_size, int key, int state, bool extended); void map_over_keys(bool (*func)(int key, int state, bool cx, Xen xf)); key_info *find_prefs_key(const char *prefs_name); void save_edits_from_kbd(snd_info *sp); void keyboard_command(chan_info *cp, int keysym, int state); void control_g(snd_info *sp); void g_init_kbd(void); /* -------- snd-sig.c -------- */ void scale_by(chan_info *cp, mus_float_t *scalers, int len, bool selection); bool scale_to(snd_info *sp, chan_info *cp, mus_float_t *scalers, int len, bool selection); void src_env_or_num(chan_info *cp, env *e, mus_float_t ratio, bool just_num, const char *origin, bool over_selection, mus_any *gen, Xen edpos, int arg_pos); void apply_filter(chan_info *ncp, int order, env *e, const char *caller, const char *origin, bool over_selection, mus_float_t *ur_a, mus_any *gen, Xen edpos, int arg_pos, bool truncate); void apply_env(chan_info *cp, env *e, mus_long_t beg, mus_long_t dur, bool over_selection, const char *origin, mus_any *gen, Xen edpos, int arg_pos); void cos_smooth(chan_info *cp, mus_long_t beg, mus_long_t num, bool over_selection); void display_frequency_response(env *e, axis_info *ap, graphics_context *gax, int order, bool dBing); void cursor_delete(chan_info *cp, mus_long_t count); void cursor_zeros(chan_info *cp, mus_long_t count, bool over_selection); void cursor_insert(chan_info *cp, mus_long_t beg, mus_long_t count); void cut_and_smooth(chan_info *cp); void src_file(const char *file, double ratio); mus_long_t scan_channel(chan_info *cp, mus_long_t start, mus_long_t end, Xen proc); void g_init_sig(void); int to_c_edit_position(chan_info *cp, Xen edpos, const char *caller, int arg_pos); mus_long_t to_c_edit_samples(chan_info *cp, Xen edpos, const char *caller, int arg_pos); mus_long_t beg_to_sample(Xen beg, const char *caller); mus_long_t dur_to_samples(Xen dur, mus_long_t beg, chan_info *cp, int edpos, int argn, const char *caller); #if USE_MOTIF char *scale_and_src(char **files, int len, int max_chans, mus_float_t amp, mus_float_t speed, env *amp_env, bool *err); #endif Xen g_scale_selection_by(Xen scalers); void reverse_sound(chan_info *ncp, bool over_selection, Xen edpos, int arg_pos); /* -------- snd-draw.c -------- */ point_t *get_grf_points(void); point_t *get_grf_points1(void); void draw_cursor(chan_info *cp); void set_grf_points(int xi, int j, int ymin, int ymax); void set_grf_point(int xi, int j, int yi); void draw_grf_points(int dot_size, graphics_context *ax, int j, axis_info *ap, mus_float_t y0, graph_style_t graph_style); void draw_both_grf_points(int dot_size, graphics_context *ax, int j, graph_style_t graph_style); void g_init_draw(void); void set_dialog_widget(snd_dialog_t which, widget_t wid); void run_new_widget_hook(widget_t w); bool foreground_color_ok(Xen color, graphics_context *ax); #if HAVE_GL void sgl_save_currents(void); void sgl_set_currents(bool with_dialogs); #endif /* -------- snd-ladspa.c -------- */ #if HAVE_LADSPA void g_ladspa_to_snd(void); #endif #endif snd-16.1/jcvoi.scm0000644000076400007640000004022212624451314012153 0ustar bilbil;;; from VOIDAT.SAI[220,JDC] and GLSVOI.SAI[220,JDC], then (30 years later) jcvoi.ins (provide 'snd-jcvoi.scm) (require snd-env.scm) (define fnc #f) ;; fnc[sex,vowel,formant number,formant freq,amp or fm index] (define vibfreqfun #f) (define i3fun1 #f) (define i3fun2 #f) (define (flipxy data) ; SEG functions expected data in (y x) pairs. (let ((unseg ()) (len (length data))) (do ((i 0 (+ i 2))) ((>= i len) (reverse unseg)) (let ((x (data (+ 1 i))) (y (data i))) (set! unseg (cons y (cons x unseg))))))) (define (addenv env1 sc1 off1 env2 sc2 off2) (add-envelopes (scale-envelope env1 sc1 off1) (scale-envelope env2 sc2 off2))) (define (checkpt att dur) (if (or (zero? att) (negative? att)) (* 100 (/ .01 dur)) (if (< att dur) (* 100 (/ att dur)) 100))) (define (setf-aref vect a b c d val) (set! (vect (+ a (* 3 b) (* 3 6 c) (* 3 6 4 d))) val)) (define (aref vect a b c d) (vect (+ a (* 3 b) (* 3 6 c) (* 3 6 4 d)))) (define (fillfnc) (if (not fnc) (begin (set! fnc (make-vector (* 3 6 4 4) ())) (set! vibfreqfun (make-vector 3 ())) (set! i3fun1 (make-vector 3 ())) (set! i3fun2 (make-vector 3 ())) (setf-aref fnc 1 1 1 1 (flipxy '(350 130.8 524 261.6 392 392 523 523.2 784 784 1046 1064 1568 1568))) (setf-aref fnc 1 1 1 2 (flipxy '(.3 130.8 .8 261.6 .9 392 .9 523.2 .7 784 .86 1064 .86 1568))) (setf-aref fnc 1 1 1 3 (flipxy '(1.4 130.8 1.4 261.6 1.0 392 .8 523.2 .5 784 .3 1064 .2 1568))) (setf-aref fnc 1 1 2 1 (flipxy '(1100 130.8 1100 261.6 1100 392 1200 523.2 1500 784 1800 1064 2200 1568))) (setf-aref fnc 1 1 2 2 (flipxy '(.1 130.8 .2 261.6 .3 392 .3 523.2 .1 784 .05 1064 .05 1568))) (setf-aref fnc 1 1 2 3 (flipxy '(1.0 130.8 1.0 261.6 .4 392 .4 523.2 .2 784 .2 1064 .1 1568))) (setf-aref fnc 1 1 3 1 (flipxy '(3450 130.8 3400 261.6 3400 392 3600 523.2 4500 784 5000 1064 5800 1568))) (setf-aref fnc 1 1 3 2 (flipxy '(.04 130.8 .04 261.6 .04 392 .045 523.2 .03 784 .02 1064 .02 1568))) (setf-aref fnc 1 1 3 3 (flipxy '(3.5 130.8 2.0 261.6 1.5 392 1.2 523.2 .8 784 .8 1064 1.0 1568))) (setf-aref fnc 1 2 1 1 (flipxy '(175 130.8 262 261.6 392 392 523 523.2 784 784 1046 1064 1568 1568))) (setf-aref fnc 1 2 1 2 (flipxy '(.25 130.8 .6 261.6 .6 392 .6 523.2 .7 784 .86 1064 .86 1568))) (setf-aref fnc 1 2 1 3 (flipxy '(0.5 130.8 0.3 261.6 0.1 392 .05 523.2 .04 784 .03 1064 .02 1568))) (setf-aref fnc 1 2 2 1 (flipxy '(2900 130.8 2700 261.6 2600 392 2400 523.2 2300 784 2200 1064 2100 1568))) (setf-aref fnc 1 2 2 2 (flipxy '(.01 130.8 .05 261.6 .08 392 .1 523.2 .1 784 .1 1064 .05 1568))) (setf-aref fnc 1 2 2 3 (flipxy '(1.5 130.8 1.0 261.6 1.0 392 1.0 523.2 1.0 784 1.0 1064 .5 1568))) (setf-aref fnc 1 2 3 1 (flipxy '(4200 130.8 3900 261.6 3900 392 3900 523.2 3800 784 3700 1064 3600 1568))) (setf-aref fnc 1 2 3 2 (flipxy '(.01 130.8 .04 261.6 .03 392 .03 523.2 .03 784 .03 1064 .02 1568))) (setf-aref fnc 1 2 3 3 (flipxy '(1.2 130.8 .8 261.6 .8 392 .8 523.2 .8 784 .8 1064 .5 1568))) (setf-aref fnc 1 3 1 1 (flipxy '(175 130.8 262 261.6 392 392 523 523.2 784 784 1046 1064 1568 1568))) (setf-aref fnc 1 3 1 2 (flipxy '(.3 130.8 .7 261.6 .8 392 .6 523.2 .7 784 .86 1064 .86 1568))) (setf-aref fnc 1 3 1 3 (flipxy '(0.4 130.8 0.2 261.6 0.4 392 .4 523.2 .7 784 .5 1064 .2 1568))) (setf-aref fnc 1 3 2 1 (flipxy '(1000 130.8 1000 261.6 1100 392 1200 523.2 1400 784 1800 1064 2200 1568))) (setf-aref fnc 1 3 2 2 (flipxy '(.055 130.8 .1 261.6 .15 392 .13 523.2 .1 784 .1 1064 .05 1568))) (setf-aref fnc 1 3 2 3 (flipxy '(0.3 130.8 0.4 261.6 0.4 392 0.4 523.2 0.3 784 0.2 1064 0.1 1568))) (setf-aref fnc 1 3 3 1 (flipxy '(2600 130.8 2600 261.6 3000 392 3400 523.2 4500 784 5000 1064 5800 1568))) (setf-aref fnc 1 3 3 2 (flipxy '(.005 130.8 .03 261.6 .04 392 .04 523.2 .02 784 .02 1064 .02 1568))) (setf-aref fnc 1 3 3 3 (flipxy '(1.1 130.8 1.0 261.6 1.2 392 1.2 523.2 0.8 784 0.8 1064 1.0 1568))) (setf-aref fnc 1 4 1 1 (flipxy '(353 130.8 530 261.6 530 392 523 523.2 784 784 1046 1064 1568 1568))) (setf-aref fnc 1 4 1 2 (flipxy '(.5 130.8 .8 261.6 .8 392 .6 523.2 .7 784 .86 1064 .86 1568))) (setf-aref fnc 1 4 1 3 (flipxy '(0.6 130.8 0.7 261.6 1.0 392 0.8 523.2 .7 784 .5 1064 .2 1568))) (setf-aref fnc 1 4 2 1 (flipxy '(1040 130.8 1040 261.6 1040 392 1200 523.2 1400 784 1800 1064 2200 1568))) (setf-aref fnc 1 4 2 2 (flipxy '(.050 130.8 .05 261.6 .1 392 .2 523.2 .1 784 .1 1064 .05 1568))) (setf-aref fnc 1 4 2 3 (flipxy '(0.1 130.8 0.1 261.6 0.1 392 0.4 523.2 0.3 784 0.2 1064 0.1 1568))) (setf-aref fnc 1 4 3 1 (flipxy '(2695 130.8 2695 261.6 2695 392 3400 523.2 4500 784 5000 1064 5800 1568))) (setf-aref fnc 1 4 3 2 (flipxy '( .05 130.8 .05 261.6 .04 392 .04 523.2 .02 784 .02 1064 .02 1568))) (setf-aref fnc 1 4 3 3 (flipxy '(1.2 130.8 1.2 261.6 1.2 392 1.2 523.2 0.8 784 0.8 1064 1.0 1568))) (setf-aref fnc 1 5 1 1 (flipxy '(175 130.8 262 261.6 392 392 523 523.2 784 784 1046 1064 1568 1568))) (setf-aref fnc 1 5 1 2 (flipxy '(.4 130.8 .4 261.6 .8 392 .8 523.2 .8 784 .8 1064 .8 1568))) (setf-aref fnc 1 5 1 3 (flipxy '(0.1 130.8 0.1 261.6 0.1 392 0.1 523.2 .0 784 .0 1064 .0 1568))) (setf-aref fnc 1 5 2 1 (flipxy '( 350 130.8 524 261.6 784 392 950 523.2 1568 784 2092 1064 3136 1568))) (setf-aref fnc 1 5 2 2 (flipxy '(.8 130.8 .8 261.6 .4 392 .2 523.2 .1 784 .1 1064 .0 1568))) (setf-aref fnc 1 5 2 3 (flipxy '(0.5 130.8 0.1 261.6 0.1 392 0.1 523.2 0.0 784 0.0 1064 0.0 1568))) (setf-aref fnc 1 5 3 1 (flipxy '(2700 130.8 2700 261.6 2500 392 2450 523.2 2400 784 2350 1064 4500 1568))) (setf-aref fnc 1 5 3 2 (flipxy '( .1 130.8 .15 261.6 .15 392 .15 523.2 .15 784 .1 1064 .1 1568))) (setf-aref fnc 1 5 3 3 (flipxy '(2.0 130.8 1.6 261.6 1.6 392 1.6 523.2 1.6 784 1.6 1064 1.0 1568))) (setf-aref fnc 2 1 1 1 (flipxy '( 33 16.5 33 24.5 33 32.7 49 49.0 65 65.41 98 98 131 130.8))) (setf-aref fnc 2 1 1 2 (flipxy '( .3 16.5 .5 24.5 .6 32.7 .5 49.0 .47 65.41 .135 98 .2 130.8))) (setf-aref fnc 2 1 1 3 (flipxy '(2.4 16.5 2.0 24.5 1.8 32.7 1.6 49.0 1.5 65.41 1.2 98 .8 130.8))) (setf-aref fnc 2 1 2 1 (flipxy '(400 16.5 400 24.5 400 32.7 400 49.0 400 65.41 400 98 400 130.8))) (setf-aref fnc 2 1 2 2 (flipxy '( .2 16.5 .2 24.5 .35 32.7 .37 49.0 .4 65.41 .6 98 .8 130.8))) (setf-aref fnc 2 1 2 3 (flipxy '(6.0 16.5 5.0 24.5 4.0 32.7 3.0 49.0 2.7 65.41 2.2 98 1.8 130.8))) (setf-aref fnc 2 1 3 1 (flipxy '(2142 16.5 2142 24.5 2142 32.7 2142 49.0 2142 65.41 2142 98 2142 130.8))) (setf-aref fnc 2 1 3 2 (flipxy '(.02 16.5 .025 24.5 .05 32.7 .09 49.0 .13 65.41 .29 98 .4 130.8))) (setf-aref fnc 2 1 3 3 (flipxy '(9.0 16.5 8.0 24.5 7.2 32.7 5.5 49.0 3.9 65.41 3.0 98 1.8 130.8))) (setf-aref fnc 2 2 1 1 (flipxy '( 33 16.5 33 24.5 33 32.7 49 49.0 65 65.41 98 98 131 130.8))) (setf-aref fnc 2 2 1 2 (flipxy '( .75 16.5 .83 24.5 .91 32.7 .91 49.0 .91 65.41 .79 98 .67 130.8))) (setf-aref fnc 2 2 1 3 (flipxy '(2.5 16.5 2.5 24.5 2.5 32.7 2.1 49.0 1.8 65.41 1.4 98 1.0 130.8))) (setf-aref fnc 2 2 2 1 (flipxy '(1500 16.5 1500 24.5 1500 32.7 1500 49.0 1500 65.41 1500 98 1500 130.8))) (setf-aref fnc 2 2 2 2 (flipxy '( .01 16.5 .02 24.5 .02 32.7 .02 49.0 .02 65.41 .08 98 .08 130.8))) (setf-aref fnc 2 2 2 3 (flipxy '(1.5 16.5 1.37 24.5 1.25 32.7 1.07 49.0 0.9 65.41 0.7 98 0.5 130.8))) (setf-aref fnc 2 2 3 1 (flipxy '(2300 16.5 2300 24.5 2300 32.7 2325 49.0 2350 65.41 2375 98 2400 130.8))) (setf-aref fnc 2 2 3 2 (flipxy '(.05 16.5 .065 24.5 .70 32.7 .07 49.0 .07 65.41 .16 98 .2 130.8))) (setf-aref fnc 2 2 3 3 (flipxy '(11.0 16.5 10.0 24.5 10.0 32.7 7.7 49.0 5.4 65.41 3.7 98 2.0 130.8))) (setf-aref fnc 2 3 1 1 (flipxy '( 33 16.5 33 24.5 33 32.7 49 49.0 65 65.41 98 98 131 130.8))) (setf-aref fnc 2 3 1 2 (flipxy '( .75 16.5 .83 24.5 .87 32.7 .88 49.0 .90 65.41 .87 98 .85 130.8))) (setf-aref fnc 2 3 1 3 (flipxy '(1.4 16.5 1.4 24.5 1.4 32.7 1.4 49.0 1.4 65.41 1.4 98 1.4 130.8))) (setf-aref fnc 2 3 2 1 (flipxy '( 450 16.5 450 24.5 450 32.7 450 49.0 450 65.41 450 98 450 130.8))) (setf-aref fnc 2 3 2 2 (flipxy '( .01 16.5 .02 24.5 .08 32.7 .065 49.0 .05 65.41 .05 98 .05 130.8))) (setf-aref fnc 2 3 2 3 (flipxy '(3.0 16.5 2.6 24.5 2.1 32.7 1.75 49.0 1.4 65.41 1.05 98 0.7 130.8))) (setf-aref fnc 2 3 3 1 (flipxy '(2100 16.5 2100 24.5 2100 32.7 2125 49.0 2150 65.41 2175 98 2100 130.8))) (setf-aref fnc 2 3 3 2 (flipxy '(.05 16.5 .05 24.5 .05 32.7 .05 49.0 .05 65.41 .075 98 .1 130.8))) (setf-aref fnc 2 3 3 3 (flipxy '( 9.0 16.5 8.0 24.5 7.0 32.7 4.5 49.0 2.1 65.41 1.75 98 1.4 130.8))) (setf-aref fnc 2 4 1 1 (flipxy '( 33 16.5 33 24.5 33 32.7 49 49.0 65 65.41 98 98 131 130.8))) (setf-aref fnc 2 4 1 2 (flipxy '( .35 16.5 .40 24.5 .43 32.7 .47 49.0 .50 65.41 .57 98 .45 130.8))) (setf-aref fnc 2 4 1 3 (flipxy '(1.4 16.5 1.4 24.5 1.0 32.7 1.0 49.0 1.0 65.41 1.1 98 1.0 130.8))) (setf-aref fnc 2 4 2 1 (flipxy '( 300 16.5 300 24.5 300 32.7 300 49.0 300 65.41 300 98 300 130.8))) (setf-aref fnc 2 4 2 2 (flipxy '( .75 16.5 .80 24.5 .85 32.7 .90 49.0 .95 65.41 .99 98 .99 130.8))) (setf-aref fnc 2 4 2 3 (flipxy '(3.0 16.5 2.5 24.5 2.0 32.7 1.9 49.0 1.8 65.41 1.65 98 0.25 130.8))) (setf-aref fnc 2 4 3 1 (flipxy '(2200 16.5 2200 24.5 2200 32.7 2225 49.0 2250 65.41 2275 98 2300 130.8))) (setf-aref fnc 2 4 3 2 (flipxy '(.02 16.5 .02 24.5 .02 32.7 .035 49.0 .05 65.41 .07 98 .05 130.8))) (setf-aref fnc 2 4 3 3 (flipxy '( 5.0 16.5 4.0 24.5 3.0 32.7 2.8 49.0 2.6 65.41 1.9 98 1.2 130.8))) ;; (sef-(aref fnc 2 5 1 1 (flipxy '(175 16.5 262 24.5 392 32.7 523 49.0 784 65.41 1046 98 1568 130.8))) (setf-aref fnc 2 5 1 1 (flipxy '( 33 16.5 33 24.5 33 32.7 49 49.0 65 65.41 98 98 131 130.8))) (setf-aref fnc 2 5 1 2 (flipxy '( .40 16.5 .40 24.5 .80 32.7 .80 49.0 .80 65.41 .80 98 .80 130.8))) (setf-aref fnc 2 5 1 3 (flipxy '(0.1 16.5 0.1 24.5 0.1 32.7 0.1 49.0 0.0 65.41 0.0 98 0.0 130.8))) (setf-aref fnc 2 5 2 1 (flipxy '( 350 16.5 524 24.5 784 32.7 950 49.0 1568 65.41 2092 98 3136 130.8))) (setf-aref fnc 2 5 2 2 (flipxy '( .80 16.5 .80 24.5 .40 32.7 .20 49.0 .10 65.41 .10 98 .00 130.8))) (setf-aref fnc 2 5 2 3 (flipxy '(0.5 16.5 0.1 24.5 0.1 32.7 0.1 49.0 0.0 65.41 0.0 98 0.0 130.8))) (setf-aref fnc 2 5 3 1 (flipxy '(2700 16.5 2700 24.5 2500 32.7 2450 49.0 2400 65.41 2350 98 4500 130.8))) (setf-aref fnc 2 5 3 2 (flipxy '(.10 16.5 .15 24.5 .15 32.7 .15 49.0 .15 65.41 .10 98 .10 130.8))) (setf-aref fnc 2 5 3 3 (flipxy '( 2.0 16.5 1.6 24.5 1.6 32.7 1.6 49.0 1.6 65.41 1.5 98 1.0 130.8))) ;; these are vibrato frequencies functions (pitch dependent); (set! (vibfreqfun 1) (flipxy '(4.5 138.8 5 1568))) (set! (vibfreqfun 2) (flipxy '(4.5 16.5 5 130.8))) ;; these are index functions for cascade modulater (pitch dependent); (set! (i3fun1 1) (flipxy '(4 138.8 4 784 1 1568))) (set! (i3fun1 2) (flipxy '(4 16.5 4 65.41 1 130.8))) (set! (i3fun2 1) (flipxy '(.4 138.8 .1 1568))) (set! (i3fun2 2) (flipxy '(.4 16.5 .1 130.8))) ))) (define (fncval ptr pitch) (envelope-interp pitch ptr)) (definstrument (fm-voice beg dur pitch amp vowel-1 sex-1 ampfun1 ampfun2 ampfun3 indxfun skewfun vibfun ranfun dis pcrev deg vibscl pcran skewscl glissfun glissamt) (fillfnc) (let ((c 261.62) (vowel (floor vowel-1)) (sex (floor sex-1)) (ampref (expt amp .8)) (deg (- deg 45)) (ranfreq 20) (fm2 3) (mscale 1) (mconst 0) (indx1 1)) (let ((vibfreq (fncval (vibfreqfun sex) pitch)) (vibpc (* .01 (log pitch 2) (+ .15 (sqrt amp)) vibscl)) (ranpc (* .002 (log pitch 2) (- 2 (expt amp .25)) pcran)) (skewpc (if (= sex 1) (* (sqrt (+ .1 (* .05 ampref (- 1568 130.8)))) skewscl) (* (sqrt (+ .1 (* .05 ampref (- 130.8 16.5)))) skewscl))) (form1 (/ (fncval (aref fnc sex vowel 1 1) pitch) pitch)) (form2 (/ (fncval (aref fnc sex vowel 2 1) pitch) pitch)) (form3 (/ (fncval (aref fnc sex vowel 3 1) pitch) pitch))) (let ((fmntfreq1 (round form1)) (fmntfreq2 (round form2)) (fmntfreq3 (round form3)) (mfq (+ (* pitch mscale) mconst)) (freqratios1 fm2) (freqratios2 mscale) (freqratios3 mscale) (freqratios4 mscale)) (let ((freqratios5 fmntfreq1) (freqratios6 fmntfreq2) (freqratios7 fmntfreq3) (amp1 (sqrt amp)) (amp2 (expt amp 1.5)) (amp3 (* amp amp)) (formscl1 (abs (- form1 fmntfreq1))) (formscl2 (abs (- form2 fmntfreq2))) (formscl3 (abs (- form3 fmntfreq3))) (i3 (if (< pitch (/ c 2)) (fncval (i3fun1 sex) pitch) (fncval (i3fun2 sex) pitch))) (indx0 (if (or (= vowel 3) (= vowel 4)) 0 1.5))) (let ((caramp1sc (* (fncval (aref fnc sex vowel 1 2) pitch) (- 1 formscl1) amp1)) (caramp2sc (* (fncval (aref fnc sex vowel 2 2) pitch) (- 1 formscl2) amp2)) (caramp3sc (* (fncval (aref fnc sex vowel 3 2) pitch) (- 1 formscl3) amp3)) (scdev1 (fncval (aref fnc sex vowel 1 3) pitch)) (scdev2 (fncval (aref fnc sex vowel 2 3) pitch)) (scdev3 (fncval (aref fnc sex vowel 3 3) pitch)) (dev (hz->radians (* i3 mfq))) (dev0 (hz->radians (* indx0 mfq))) (dev1 (hz->radians (* (- indx1 indx0) mfq)))) (let ((gens1 (make-oscil 0)) (gens2 (make-oscil 0 (/ pi 2.0))) (gens2ampenv (make-env indxfun :duration dur :scaler (* scdev1 dev1) :offset (* scdev1 dev0))) (gens3 (make-oscil 0 (/ pi 2.0))) (gens3ampenv (make-env indxfun :duration dur :scaler (* scdev2 dev1) :offset (* scdev2 dev0))) (gens4 (make-oscil 0 (/ pi 2.0))) (gens4ampenv (make-env indxfun :duration dur :scaler (* scdev3 dev1) :offset (* scdev3 dev0))) (gens5 (make-oscil 0)) (gens5ampenv (make-env ampfun1 :duration dur :scaler (* amp caramp1sc .75))) (gens6 (make-oscil 0)) (gens6ampenv (make-env ampfun2 :duration dur :scaler (* amp caramp2sc .75))) (gens7 (make-oscil 0)) (gens7ampenv (make-env ampfun3 :duration dur :scaler (* amp caramp3sc .75))) (freqenv (make-env (addenv glissfun (* glissamt pitch) 0 skewfun (* skewpc pitch) pitch) :duration dur :scaler (hz->radians 1.0))) (pervenv (make-env vibfun :duration dur :scaler vibpc)) (ranvenv (make-env :envelope ranfun :duration dur :scaler ranpc)) (per-vib (make-triangle-wave :frequency vibfreq :amplitude (hz->radians pitch))) (ran-vib (make-rand-interp :frequency ranfreq :amplitude (hz->radians pitch))) (loc (make-locsig :degree deg :distance dis :reverb pcrev)) (start (floor (* *clm-srate* beg))) (end (floor (* *clm-srate* (+ beg dur))))) (do ((i start (+ i 1))) ((= i end)) (let* ((vib (+ (env freqenv) (* (env pervenv) (triangle-wave per-vib)) (* (env ranvenv) (rand-interp ran-vib)))) (cascadeout (* dev (oscil gens1 (* vib freqratios1))))) (locsig loc i (+ (* (env gens5ampenv) (oscil gens5 (+ (* vib freqratios5) (* (env gens2ampenv) (oscil gens2 (+ cascadeout (* vib freqratios2))))))) (* (env gens6ampenv) (oscil gens6 (+ (* vib freqratios6) (* (env gens3ampenv) (oscil gens3 (+ cascadeout (* vib freqratios3))))))) (* (env gens7ampenv) (oscil gens7 (+ (* vib freqratios7) (* (env gens4ampenv) (oscil gens4 (+ cascadeout (* vib freqratios4)))))))))))))) )))) #| (let ((ampf '(0 0 1 1 2 1 3 0))) (with-sound (:play #t) (fm-voice 0 1 300 .8 3 1 ampf ampf ampf ampf ampf ampf ampf 1 0 0 .25 .01 0 ampf .01))) (definstrument (fm-voice beg dur pitch amp vowel-1 sex-1 ampfun1 ampfun2 ampfun3 indxfun skewfun vibfun ranfun dis pcrev deg vibscl pcran skewscl glissfun glissamt) (define-macro (voi beg dur pitch amp vowel-1 sex-1 ampfun1 ampfun2 ampfun3 indxfun skewfun vibfun ranfun dis pcrev deg vibscl skewscl) `(fm-voice ,beg ,dur ,pitch ,amp ,vowel-1 ,sex-1 ,ampfun1 ,ampfun2 ,ampfun3 ,indxfun ,skewfun ,vibfun ,ranfun ,dis ,pcrev ,deg ,vibscl 0 ,skewscl '(0 0 100 0))) |# snd-16.1/snd-kbd.c0000644000076400007640000015156312571434531012041 0ustar bilbil#include "snd.h" /* -------- Keyboard Macros -------- */ #define MIN_KEY_CODE 0 #define MAX_KEY_CODE 65535 #define MIN_KEY_STATE 0 #define MAX_KEY_STATE 15 static bool defining_macro = false; static int macro_cmd_size = 0; static int macro_size = 0; typedef struct {int keysym; int state;} macro_cmd; static macro_cmd **macro_cmds = NULL; static void allocate_macro_cmds(void) { int old_size; old_size = macro_cmd_size; macro_cmd_size += 16; if (!macro_cmds) macro_cmds = (macro_cmd **)calloc(macro_cmd_size, sizeof(macro_cmd *)); else { int i; macro_cmds = (macro_cmd **)realloc(macro_cmds, macro_cmd_size * sizeof(macro_cmd *)); for (i = old_size; i < macro_cmd_size; i++) macro_cmds[i] = NULL; } } static void start_defining_macro(void) { macro_size = 0; defining_macro = true; if ((!macro_cmds) || (macro_size == macro_cmd_size)) allocate_macro_cmds(); } static void stop_defining_macro(void) { /* the last C-x ) went into the macro before we noticed it should not have */ macro_size -= 2; defining_macro = false; } static void execute_last_macro(chan_info *cp, int count) { int i, j; if ((macro_cmds) && (macro_size > 0)) for (j = 0; j < count; j++) for (i = 0; i < macro_size; i++) keyboard_command(cp, macro_cmds[i]->keysym, macro_cmds[i]->state); } static void continue_macro(int keysym, int state) { if (!(macro_cmds[macro_size])) macro_cmds[macro_size] = (macro_cmd *)calloc(1, sizeof(macro_cmd)); macro_cmds[macro_size]->keysym = keysym; macro_cmds[macro_size]->state = state; macro_size++; if (macro_size == macro_cmd_size) allocate_macro_cmds(); } /* ---------------- keys ---------------- */ typedef struct { int key; int state; int args; Xen func; bool cx_extended; /* Sun/Forte C defines "extended" somewhere */ const char *origin, *prefs_info; int gc_loc; } key_entry; static key_entry *keymap = NULL; static int keymap_size = 0; static int keymap_top = 0; int in_keymap(int key, int state, bool cx_extended) { int i; if (keymap_top == 0) return(-1); for (i = 0; i < keymap_top; i++) if ((keymap[i].key == key) && (keymap[i].state == state) && (keymap[i].cx_extended == cx_extended) && (Xen_is_bound(keymap[i].func))) return(i); return(-1); } #if HAVE_SCHEME || HAVE_FORTH #define kbd_false 0 #else #define kbd_false Xen_false #endif #define NUM_BUILT_IN_KEYS 81 static key_entry built_in_keys[NUM_BUILT_IN_KEYS] = { {snd_K_Down, 0, 0, kbd_false, false, "zoom out", NULL, -1}, {snd_K_Up, 0, 0, kbd_false, false, "zoom in", NULL, -1}, {snd_K_Left, 0, 0, kbd_false, false, "move window left", NULL, -1}, {snd_K_Right, 0, 0, kbd_false, false, "move window right", NULL, -1}, {snd_keypad_Down, 0, 0, kbd_false, false, "zoom fft out", NULL, -1}, {snd_keypad_Up, 0, 0, kbd_false, false, "zoom fft in", NULL, -1}, {snd_keypad_Left, 0, 0, kbd_false, false, "move fft left", NULL, -1}, {snd_keypad_Right, 0, 0, kbd_false, false, "move fft right", NULL, -1}, {snd_K_less, 0, 0, kbd_false, false, "move cursor to sample 0", NULL, -1}, {snd_K_greater, 0, 0, kbd_false, false, "move cursor to last sample", NULL, -1}, {snd_K_space, 0, 0, kbd_false, false, "play from cursor or stop playing", NULL, -1}, {snd_K_less, snd_ControlMask, 0, kbd_false, false, "move cursor to sample 0", NULL, -1}, {snd_K_greater, snd_ControlMask, 0, kbd_false, false, "move cursor to last sample", NULL, -1}, {snd_K_a, snd_ControlMask, 0, kbd_false, false, "move cursor to window start", NULL, -1}, {snd_K_b, snd_ControlMask, 0, kbd_false, false, "move cursor back one pixel", NULL, -1}, {snd_K_d, snd_ControlMask, 0, kbd_false, false, "delete sample at cursor", NULL, -1}, {snd_K_e, snd_ControlMask, 0, kbd_false, false, "move cursor to window end", NULL, -1}, {snd_K_f, snd_ControlMask, 0, kbd_false, false, "move cursor ahead one pixel", NULL, -1}, {snd_K_g, snd_ControlMask, 0, kbd_false, false, "abort current command", NULL, -1}, {snd_K_h, snd_ControlMask, 0, kbd_false, false, "delete previous sample", NULL, -1}, {snd_K_i, snd_ControlMask, 0, kbd_false, false, "display cursor info", NULL, -1}, {snd_K_j, snd_ControlMask, 0, kbd_false, false, "goto mark", NULL, -1}, {snd_K_k, snd_ControlMask, 0, kbd_false, false, "delete one line's worth of samples", NULL, -1}, {snd_K_l, snd_ControlMask, 0, kbd_false, false, "position window so cursor is in the middle", NULL, -1}, {snd_K_m, snd_ControlMask, 0, kbd_false, false, "place (or remove) mark at cursor location", NULL, -1}, {snd_K_n, snd_ControlMask, 0, kbd_false, false, "move cursor ahead one 'line'", NULL, -1}, {snd_K_o, snd_ControlMask, 0, kbd_false, false, "insert one zero sample at cursor", NULL, -1}, {snd_K_p, snd_ControlMask, 0, kbd_false, false, "move cursor back one 'line'", NULL, -1}, {snd_K_q, snd_ControlMask, 0, kbd_false, false, "play current channel starting at cursor", "play-channel-from-cursor", -1}, {snd_K_s, snd_ControlMask, 0, kbd_false, false, "search", NULL, -1}, {snd_K_t, snd_ControlMask, 0, kbd_false, false, "stop playing", NULL, -1}, {snd_K_u, snd_ControlMask, 0, kbd_false, false, "start arg count definition.", NULL, -1}, {snd_K_v, snd_ControlMask, 0, kbd_false, false, "move cursor to mid-window", NULL, -1}, {snd_K_w, snd_ControlMask, 0, kbd_false, false, "delete selection", "delete-selection", -1}, {snd_K_y, snd_ControlMask, 0, kbd_false, false, "insert selection.", "insert-selection", -1}, {snd_K_z, snd_ControlMask, 0, kbd_false, false, "set sample at cursor to 0.0", NULL, -1}, {snd_K_underscore, snd_ControlMask, 0, kbd_false, false, "undo", NULL, -1}, {snd_K_space, snd_ControlMask, 0, kbd_false, false, "start selection definition", NULL, -1}, {snd_K_g, snd_ControlMask | snd_MetaMask, 0, kbd_false, false, "clear listener", NULL, -1}, {snd_K_less, snd_MetaMask, 0, kbd_false, false, "move cursor to sample 0", NULL, -1}, {snd_K_greater, snd_MetaMask, 0, kbd_false, false, "move cursor to last sample", NULL, -1}, {snd_K_b, 0, 0, kbd_false, true, "position window so cursor is on left margin", NULL, -1}, {snd_K_c, 0, 0, kbd_false, true, "define selection from cursor to nth mark", NULL, -1}, {snd_K_e, 0, 0, kbd_false, true, "execute keyboard macro", NULL, -1}, {snd_K_f, 0, 0, kbd_false, true, "position window so cursor is on right margin", NULL, -1}, {snd_K_k, 0, 0, kbd_false, true, "close file", NULL, -1}, {snd_K_l, 0, 0, kbd_false, true, "position selection in mid-view", NULL, -1}, {snd_K_o, 0, 0, kbd_false, true, "move to next or previous graph", NULL, -1}, {snd_K_p, 0, 0, kbd_false, true, "play selection or region n", "play-selection", -1}, {snd_K_q, 0, 0, kbd_false, true, "mix in selection", "mix-selection", -1}, {snd_K_r, 0, 0, kbd_false, true, "redo", NULL, -1}, {snd_K_u, 0, 0, kbd_false, true, "undo", NULL, -1}, {snd_K_v, 0, 0, kbd_false, true, "position window over selection", NULL, -1}, {snd_K_z, 0, 0, kbd_false, true, "smooth selection", NULL, -1}, {snd_K_openparen, 0, 0, kbd_false, true, "begin keyboard macro definition", NULL, -1}, {snd_K_closeparen, 0, 0, kbd_false, true, "end keyboard macro definition", NULL, -1}, {snd_K_b, snd_ControlMask, 0, kbd_false, true, "set x window bounds (preceded by 1 arg)", NULL, -1}, {snd_K_c, snd_ControlMask, 0, kbd_false, true, "hide control panel", NULL, -1}, {snd_K_f, snd_ControlMask, 0, kbd_false, true, "open file", NULL, -1}, {snd_K_g, snd_ControlMask, 0, kbd_false, true, "abort command", NULL, -1}, {snd_K_o, snd_ControlMask, 0, kbd_false, true, "show control panel", NULL, -1}, {snd_K_p, snd_ControlMask, 0, kbd_false, true, "set window size (preceded by 1 arg)", NULL, -1}, {snd_K_q, snd_ControlMask, 0, kbd_false, true, "mix in file", NULL, -1}, {snd_K_r, snd_ControlMask, 0, kbd_false, true, "redo", "save-sound", -1}, {snd_K_s, snd_ControlMask, 0, kbd_false, true, "save file", NULL, -1}, {snd_K_u, snd_ControlMask, 0, kbd_false, true, "undo", NULL, -1}, {snd_K_v, snd_ControlMask, 0, kbd_false, true, "set window size as percentage of total", NULL, -1}, {snd_K_w, snd_ControlMask, 0, kbd_false, true, "save current channel in file", NULL, -1}, {snd_K_z, snd_ControlMask, 0, kbd_false, true, "smooth using cosine", NULL, -1}, }; void map_over_keys(bool (*func)(int key, int state, bool cx, Xen xf)) { int i; for (i = 0; i < keymap_top; i++) if ((Xen_is_bound(keymap[i].func)) && ((*func)(keymap[i].key, keymap[i].state, keymap[i].cx_extended, keymap[i].func))) return; } static key_info *make_key_info(key_entry k) { key_info *ki; ki = (key_info *)calloc(1, sizeof(key_info)); #if USE_MOTIF ki->key = XKeysymToString(k.key); /* no free! */ #else #if USE_GTK ki->key = gdk_keyval_name(k.key); #endif #endif ki->c = k.state & snd_ControlMask; ki->m = k.state & snd_MetaMask; ki->x = k.cx_extended; return(ki); } key_info *find_prefs_key(const char *prefs_name) { int i; key_info *ki; for (i = 0; i < keymap_top; i++) if ((Xen_is_bound(keymap[i].func)) && (mus_strcmp(keymap[i].prefs_info, prefs_name))) return(make_key_info(keymap[i])); for (i = 0; i < NUM_BUILT_IN_KEYS; i++) if (mus_strcmp(built_in_keys[i].prefs_info, prefs_name)) return(make_key_info(built_in_keys[i])); ki = (key_info *)calloc(1, sizeof(key_info)); ki->key = NULL; ki->c = false; ki->m = false; ki->x = false; return(ki); } char *key_description(int key, int state, bool cx_extended) { int pos; if ((key < MIN_KEY_CODE) || (key > MAX_KEY_CODE) || (state < MIN_KEY_STATE) || (state > MAX_KEY_STATE)) return(NULL); pos = in_keymap(key, state, cx_extended); if (pos < 0) pos = in_keymap(key, state, cx_extended); if (pos >= 0) { if (keymap[pos].origin) return(mus_strdup(keymap[pos].origin)); return(mus_strdup("something indescribable")); /* NULL would mean "no binding" */ } for (pos = 0; pos < NUM_BUILT_IN_KEYS; pos++) if ((built_in_keys[pos].key == key) && (built_in_keys[pos].state == state) && (built_in_keys[pos].cx_extended == cx_extended)) return(mus_strdup(built_in_keys[pos].origin)); return(NULL); } void set_keymap_entry(int key, int state, int args, Xen func, bool cx_extended, const char *origin, const char *prefs_info) { int i; i = in_keymap(key, state, cx_extended); if (i == -1) { if (keymap_size == keymap_top) { keymap_size += 16; if (keymap_top == 0) { keymap = (key_entry *)calloc(keymap_size, sizeof(key_entry)); for (i = 0; i < keymap_size; i++) keymap[i].func = Xen_undefined; } else { keymap = (key_entry *)realloc(keymap, keymap_size * sizeof(key_entry)); for (i = keymap_top; i < keymap_size; i++) { keymap[i].key = 0; keymap[i].state = 0; keymap[i].func = Xen_undefined; keymap[i].cx_extended = false; keymap[i].origin = NULL; keymap[i].prefs_info = NULL; keymap[i].gc_loc = NOT_A_GC_LOC; } } } keymap[keymap_top].key = key; keymap[keymap_top].state = state; keymap[keymap_top].cx_extended = cx_extended; check_menu_labels(key, state, cx_extended); i = keymap_top; keymap_top++; } else { if ((Xen_is_procedure(keymap[i].func)) && (keymap[i].gc_loc != NOT_A_GC_LOC)) { snd_unprotect_at(keymap[i].gc_loc); keymap[i].gc_loc = NOT_A_GC_LOC; } if (keymap[i].origin) { /* this is silly... */ char *tmp; tmp = (char *)keymap[i].origin; keymap[i].origin = NULL; free(tmp); } if (keymap[i].prefs_info) { char *tmp; tmp = (char *)keymap[i].prefs_info; keymap[i].prefs_info = NULL; free(tmp); } } keymap[i].origin = mus_strdup(origin); keymap[i].prefs_info = mus_strdup(prefs_info); keymap[i].args = args; keymap[i].func = func; if (Xen_is_procedure(func)) keymap[i].gc_loc = snd_protect(func); } static void call_keymap(int hashedsym, int count) { kbd_cursor_t res = KEYBOARD_NO_ACTION; if (Xen_is_bound(keymap[hashedsym].func)) { /* not _NO_CATCH here because the code is not protected at any higher level * if key-bind function returns some impossible cursor-action, return keyboard-no-action */ Xen result; if (keymap[hashedsym].args == 0) result = Xen_call_with_no_args(keymap[hashedsym].func, keymap[hashedsym].origin); else result = Xen_call_with_1_arg(keymap[hashedsym].func, C_int_to_Xen_integer(count), keymap[hashedsym].origin); if (Xen_is_integer(result)) { int r; r = (int)Xen_integer_to_C_int(result); if ((r <= KEYBOARD_NO_ACTION) && (r >= CURSOR_IN_VIEW)) res = (kbd_cursor_t)r; } } handle_cursor(selected_channel(), res); } /* ---------------- other kbd built-in commands ---------------- */ static void cursor_moveto_end(chan_info *cp) { cursor_moveto(cp, current_samples(cp) - 1); } static void set_window_bounds(chan_info *cp, int count) { /* count = sample number to start at */ axis_info *ap; ap = cp->axis; if (ap->x_ambit != 0.0) { double sx; sx = (((double)count / (double)snd_srate(cp->sound)) - ap->xmin) / ap->x_ambit; reset_x_display(cp, sx, ap->zx); } } static void set_window_size(chan_info *cp, int count) { /* set samples within window */ axis_info *ap; ap = cp->axis; if (ap->x_ambit != 0.0) { double zx; zx = ((double)count / (((double)snd_srate(cp->sound)) * ap->x_ambit)); reset_x_display(cp, ap->sx, zx); } } static void set_window_percentage(chan_info *cp, int count) { /* set percentage of file within window */ axis_info *ap; double zx; ap = cp->axis; zx = (double)count / (double)snd_srate(cp->sound); reset_x_display(cp, ap->sx, zx); } static void window_framples_selection(chan_info *cp) { double x0, x1; int i; x0 = (((double)(selection_beg(cp))) / ((double)snd_srate(cp->sound))); x1 = x0 + ((double)(selection_len())) / ((double)(snd_srate(cp->sound))); set_x_axis_x0x1(cp, x0, x1); for (i = 0; i < ss->max_sounds; i++) { snd_info *sp; sp = ss->sounds[i]; if ((sp) && (sp->inuse == SOUND_NORMAL) && (cp->sound != sp) && (selection_is_active_in_channel(sp->chans[0])) && (sp->sync != (cp->sound->sync))) set_x_axis_x0x1(sp->chans[0], x0, x1); } } static chan_info *goto_next_graph(chan_info *cp, int count); static chan_info *goto_previous_graph(chan_info *cp, int count) { snd_info *sp; chan_info *ncp, *vcp; int i, k, j, chan; if (count == 0) return(cp); sp = cp->sound; if (sp->inuse != SOUND_NORMAL) return(cp); vcp = virtual_selected_channel(cp); chan = vcp->chan; ncp = NULL; if (count < 0) k = -count; else return(goto_next_graph(cp, count)); if (chan > 0) { /* goto previous channel in current sound */ k -= chan; if (k <= 0) ncp = sp->chans[chan + count]; } while (k > 0) { /* look for previous sound, (wrap around) */ /* goto channel n */ for (i = (sp->index - 1); i >= 0; i--) if ((snd_ok(ss->sounds[i])) && (ss->sounds[i]->inuse == SOUND_NORMAL)) { sp = (snd_info *)(ss->sounds[i]); j = k; k -= sp->nchans; if (k <= 0) ncp = sp->chans[sp->nchans - j]; break; } if (k > 0) for (i = ss->max_sounds - 1; i >= sp->index; i--) if ((snd_ok(ss->sounds[i])) && (ss->sounds[i]->inuse == SOUND_NORMAL)) { sp = (snd_info *)(ss->sounds[i]); j = k; k -= sp->nchans; if (k <= 0) ncp = sp->chans[sp->nchans - j]; break; } } if (ncp == vcp) return(ncp); if (!ncp) snd_error_without_format("goto previous graph failed!"); select_channel(ncp->sound, ncp->chan); return(ncp); } static chan_info *goto_next_graph(chan_info *cp, int count) { snd_info *sp; chan_info *ncp, *vcp; int i, k, j, chan; if (count == 0) return(cp); sp = cp->sound; if (sp->inuse != SOUND_NORMAL) return(cp); vcp = virtual_selected_channel(cp); chan = vcp->chan; ncp = NULL; if (count < 0) return(goto_previous_graph(cp, count)); k = count; if (chan < (sp->nchans - 1)) { /* goto next channel in current sound */ k -= (sp->nchans-chan - 1); if (k <= 0) ncp = sp->chans[chan + count]; } while (k > 0) { /* look for next sound, (wrap around) */ /* goto channel 0 */ for (i = (sp->index + 1); i < ss->max_sounds; i++) if ((snd_ok(ss->sounds[i])) && (ss->sounds[i]->inuse == SOUND_NORMAL)) { sp = (snd_info *)(ss->sounds[i]); j = k; k -= sp->nchans; if (k <= 0) ncp = sp->chans[j - 1]; break; } if (k > 0) for (i = 0; i <= sp->index; i++) if ((snd_ok(ss->sounds[i])) && (ss->sounds[i]->inuse == SOUND_NORMAL)) { sp = (snd_info *)(ss->sounds[i]); j = k; k -= sp->nchans; if (k <= 0) ncp = sp->chans[j - 1]; break; } } if (ncp == vcp) return(ncp); if (!ncp) snd_error_without_format("goto next graph failed!"); select_channel(ncp->sound, ncp->chan); return(ncp); } void save_edits_from_kbd(snd_info *sp) { /* this used to prompt for confirmation, but we now use a dialog */ redirect_everything_to(printout_to_status_area, (void *)sp); #if (!USE_NO_GUI) { io_error_t err; err = save_edits(sp); if (err == IO_NEED_WRITE_CONFIRMATION) changed_file_dialog(sp); } #else save_edits_without_asking(sp); #endif redirect_everything_to(NULL, NULL); } /* ---------------- key response ---------------- */ static mus_long_t get_count_1(char *number_buffer, int number_ctr, bool dot_seen, chan_info *cp) { /* allow floats here = secs */ int i; if (number_ctr == 0) return(1); /* c-u followed by nothing = 1 */ number_buffer[number_ctr] = '\0'; if (number_ctr == 1) { /* handle special cases of just - or + */ if (number_buffer[0] == '-') return(-1); if (number_buffer[0] == '+') return(1); if (number_buffer[0] == '.') return(0); /* -. and +. -> 0 from sscanf */ } if (dot_seen) { float f; if (!(sscanf(number_buffer, "%12f", &f))) /* 12 is number_buffer size */ { /* this doesn't happen for most bogus cases -- the C spec says "it is not possible to determine * directly whether matches of literal character in the control string succeed or fail." * but really bad stuff like C-u ... C-f does get flagged. */ snd_error("invalid number: %s", number_buffer); return(0); } return((mus_long_t)(f * snd_srate(cp->sound))); } if (!(sscanf(number_buffer, "%12d", &i))) { snd_error("invalid number: %s", number_buffer); return(0); } return(i); } static mus_long_t get_count(char *number_buffer, int number_ctr, bool dot_seen, chan_info *cp, bool mark_wise) { mus_long_t val, old_cursor; val = get_count_1(number_buffer, number_ctr, dot_seen, cp); if (!mark_wise) return(val); old_cursor = cursor_sample(cp); if (!(goto_mark(cp, val))) set_status(cp->sound, "no such mark", false); val = cursor_sample(cp) - old_cursor; /* will be 0 if no relevant marks */ cursor_sample(cp) = old_cursor; return(val); } #define NUMBER_BUFFER_SIZE 12 static mus_float_t state_amount(int state) { mus_float_t amount; amount = 1.0; if (state & snd_ControlMask) amount *= 0.5; if (state & snd_MetaMask) amount *= 0.5; if (state & snd_ShiftMask) amount *= 0.5; return(amount); } static void zoom_fft(mus_float_t amount) { mus_float_t zx, mx; zx = spectrum_end(ss) - spectrum_start(ss); mx = (spectrum_end(ss) + spectrum_start(ss)) * 0.5; zx *= amount; mx -= (zx * 0.5); if (mx < 0.0) mx = 0.0; set_spectrum_start(mx); if ((mx + zx) <= 1.0) set_spectrum_end(mx + zx); else set_spectrum_end(1.0); } static void move_fft(mus_float_t amount) { mus_float_t mx, zx; zx = spectrum_end(ss) - spectrum_start(ss); mx = spectrum_start(ss) + zx * amount; if (mx < 0.0) mx = 0.0; if (mx >= 1.0) mx = 1.0 - zx; set_spectrum_start(mx); if ((mx + zx) <= 1.0) set_spectrum_end(mx + zx); else set_spectrum_end(1.0); } static bool stop_selecting(int keysym, int state) { return(((state & snd_ControlMask) == 0) || (keysym == snd_K_D) || (keysym == snd_K_d) || (keysym == snd_K_H) || (keysym == snd_K_h) || (keysym == snd_K_Y) || (keysym == snd_K_y)); } static const char *key_to_name(int keysym) { if (keysym) { const char *str; str = KEY_TO_NAME(keysym); if (str) return(str); } return("NUL"); } static int number_ctr = 0; static bool dot_seen = false; static bool counting = false; static bool extended_mode = false; void control_g(snd_info *sp) { ss->C_g_typed = true; number_ctr = 0; counting = false; dot_seen = false; extended_mode = false; /* if (selection_is_active()) deactivate_selection(); */ defining_macro = false; clear_stdin(); redirect_everything_to(NULL, NULL); if (sp) clear_status_area(sp); /* do this before stop_playing! */ if ((ss->checking_explicitly) || (play_in_progress())) ss->stopped_explicitly = true; /* this tries to break out of long filter/src computations (and perhaps others) */ /* but, as in other such cases, it leaves this flag set so all subsequent uses of it need to clear it first */ stop_playing_all_sounds(PLAY_C_G); /* several scm files assume hooks called upon C-g -- could be region play, etc */ if (sp) { if (sp->applying) stop_applying(sp); for_each_sound_chan(sp, stop_fft_in_progress); } if (selection_creation_in_progress()) deactivate_selection(); } #ifndef SND_KEYMASK #define SND_KEYMASK (snd_ControlMask | snd_MetaMask) #endif #if HAVE_EXTENSION_LANGUAGE && (!USE_NO_GUI) static chan_info *last_searcher = NULL; #endif void keyboard_command(chan_info *cp, int keysym, int unmasked_state) { /* we can't use the meta bit in some cases because this is trapped at a higher level for the Menu mnemonics */ /* state here is the kbd bucky-bit state -- it might have bogus junk like NumLock */ /* keysym has Shift taken into account already (see snd-xchn.c XKeycodeToKeysym, and same snd-xsnd.c) */ static bool u_count = false; static char number_buffer[NUMBER_BUFFER_SIZE]; static mus_long_t count = 1; static bool got_count = false; static bool m = false; int shift = 0; int hashloc, i, state; static mus_long_t ext_count = 1; static bool got_ext_count = false; snd_info *sp; axis_info *ap; /* fprintf(stderr, "%d (%s %d%s) ", keysym, KEY_TO_NAME(keysym), unmasked_state, (extended_mode) ? " (c-x)" : ""); */ if ((!cp) || (!(cp->sound)) || (cp->active < CHANNEL_HAS_EDIT_LIST)) return; sp = cp->sound; if ((!sp) || (sp->inuse != SOUND_NORMAL)) return; ap = cp->axis; if (keysym >= snd_K_Shift_L) return; /* this happens when the user presses Control or Shift etc prior to hitting the actual (modified) key */ shift = unmasked_state & snd_ShiftMask; state = unmasked_state & SND_KEYMASK; /* mask off stuff we don't care about */ if (defining_macro) continue_macro(keysym, state); if (!m) count = 1; else m = false; if ((selection_creation_in_progress()) && (!counting) && ((extended_mode) || (stop_selecting(keysym, state)))) finish_selection_creation(); if ((counting) && (((keysym < snd_K_0) || (keysym > snd_K_9)) && ((keysym < snd_keypad_0) || (keysym > snd_keypad_9)) && /* these are in order in both Motif (X11) and gdk */ (keysym != snd_K_minus) && (keysym != snd_K_period) && (keysym != snd_keypad_Decimal) && (keysym != snd_K_plus))) { m = ((u_count) && ((keysym == snd_K_M) || (keysym == snd_K_m))); count = get_count(number_buffer, number_ctr, dot_seen, cp, m); got_count = true; number_ctr = 0; counting = false; dot_seen = false; if (m) return; } u_count = false; if ((keysym != snd_K_X) && (keysym != snd_K_x) && (keysym != snd_K_B) && (keysym != snd_K_b) && (keysym != snd_K_F) && (keysym != snd_K_f)) { got_count = false; if (count == 0) return; } #if HAVE_EXTENSION_LANGUAGE hashloc = in_keymap(keysym, state, extended_mode); if (hashloc != -1) /* found user-defined key */ { extended_mode = false; call_keymap(hashloc, count); return; } #endif if (state & snd_ControlMask) { if (!extended_mode) { mus_long_t loc; /* -------------------------------- C-key -------------------------------- */ switch (keysym) { case snd_K_A: case snd_K_a: cp->cursor_on = true; loc = (mus_long_t)(ap->x0 * snd_srate(sp)); if ((loc + 1) == ap->losamp) loc = ap->losamp; /* handle dumb rounding problem */ cursor_moveto(cp, loc); break; case snd_K_B: case snd_K_b: /* this was by samples which is nuts if we're looking at a large window -- should be by pixel, I think */ { int samples_per_pixel = 1; if ((!got_count) && /* C-u 2.1 C-b moves back 2.1 seconds */ (cp->axis->x_axis_x1 > cp->axis->x_axis_x0)) /* avoid divide by zero if window tiny */ { samples_per_pixel = (cp->axis->hisamp - cp->axis->losamp) / (cp->axis->x_axis_x1 - cp->axis->x_axis_x0); if (samples_per_pixel < 1) samples_per_pixel = 1; } cp->cursor_on = true; cursor_move(cp, -count * samples_per_pixel); got_count = false; } break; case snd_K_D: case snd_K_d: cp->cursor_on = true; cursor_delete(cp, count); break; case snd_K_E: case snd_K_e: cp->cursor_on = true; loc = (mus_long_t)(ap->x1 * (double)snd_srate(sp)); if ((loc + 1) == ap->hisamp) loc = ap->hisamp; cursor_moveto(cp, loc); break; case snd_K_F: case snd_K_f: { int samples_per_pixel = 1; if ((!got_count) && (cp->axis->x_axis_x1 > cp->axis->x_axis_x0)) { samples_per_pixel = (cp->axis->hisamp - cp->axis->losamp) / (cp->axis->x_axis_x1 - cp->axis->x_axis_x0); if (samples_per_pixel < 1) samples_per_pixel = 1; } cp->cursor_on = true; cursor_move(cp, count * samples_per_pixel); got_count = false; } break; case snd_K_G: case snd_K_g: if (state & snd_MetaMask) clear_listener(); else control_g(sp); break; case snd_K_H: case snd_K_h: cp->cursor_on = true; cursor_delete(cp, -count); break; case snd_K_I: case snd_K_i: show_cursor_info(cp); break; case snd_K_J: case snd_K_j: cp->cursor_on = true; if (!(goto_mark(cp, count))) set_status(cp->sound, "no such mark", false); break; case snd_K_K: case snd_K_k: cp->cursor_on = true; cursor_delete(cp, count * 128); break; case snd_K_L: case snd_K_l: cp->cursor_on = true; handle_cursor_with_sync(cp, CURSOR_IN_MIDDLE); break; case snd_K_M: case snd_K_m: { mark *mk = NULL; if (count > 0) { cp->cursor_on = true; set_show_marks(true); mk = add_mark(cursor_sample(cp), NULL, cp); display_channel_marks(cp); } else { if (!(delete_mark_samp(cursor_sample(cp), cp))) status_report(cp->sound, "no mark at sample %lld", cursor_sample(cp)); } if ((keysym == snd_K_M) && (cp->sound->sync != 0)) { sync_info *si; int sync_num; sync_num = mark_sync_max() + 1; if (mk) set_mark_sync(mk, sync_num); si = snd_sync(cp->sound->sync); for (i = 0; i < si->chans; i++) if (cp != si->cps[i]) { if (count > 0) { mk = add_mark(cursor_sample(cp), NULL, si->cps[i]); if (mk) { set_mark_sync(mk, sync_num); display_channel_marks(si->cps[i]); } } else { if (!(delete_mark_samp(cursor_sample(cp), si->cps[i]))) status_report(cp->sound, "no mark at sample %lld", cursor_sample(cp)); } } si = free_sync_info(si); } } break; case snd_K_N: case snd_K_n: cp->cursor_on = true; cursor_move(cp, count * 128); break; case snd_K_O: case snd_K_o: cp->cursor_on = true; cursor_insert(cp, cursor_sample(cp), count); break; case snd_K_P: case snd_K_p: cp->cursor_on = true; cursor_move(cp, -count * 128); break; case snd_K_Q: case snd_K_q: play_channel(cp, cursor_sample(cp), NO_END_SPECIFIED); break; #if HAVE_EXTENSION_LANGUAGE && (!USE_NO_GUI) case snd_K_S: case snd_K_s: if ((cp == last_searcher) && (find_dialog_is_active())) find_dialog_find(NULL, READ_FORWARD, cp); last_searcher = cp; find_dialog(cp); break; case snd_K_R: case snd_K_r: if ((cp == last_searcher) && (find_dialog_is_active())) find_dialog_find(NULL, READ_BACKWARD, cp); last_searcher = cp; find_dialog(cp); break; #endif case snd_K_T: case snd_K_t: stop_playing_sound(sp, PLAY_C_T); set_play_button(sp, false); break; case snd_K_U: case snd_K_u: counting = true; u_count = true; number_ctr = 0; dot_seen = false; break; case snd_K_V: case snd_K_v: cp->cursor_on = true; /* in emacs this is move ahead one window, but for some reason in Snd it's center cursor?? */ cursor_moveto(cp, (mus_long_t)((ap->losamp + ap->hisamp) / 2)); break; case snd_K_W: case snd_K_w: delete_selection(UPDATE_DISPLAY); break; case snd_K_X: case snd_K_x: extended_mode = true; if (got_count) { ext_count = count; got_ext_count = got_count; got_count = false; } break; case snd_K_Y: case snd_K_y: paste_region(region_list_position_to_id(0), cp); break; case snd_K_Z: case snd_K_z: cp->cursor_on = true; cursor_zeros(cp, count, OVER_SOUND); break; case snd_K_Right: sx_incremented(cp, state_amount(state | shift)); break; case snd_K_Left: sx_incremented(cp, -state_amount(state | shift)); break; case snd_K_Up: zx_incremented(cp, 1.0 + state_amount(state | shift)); break; case snd_K_Down: zx_incremented(cp, 1.0 / (1.0 + state_amount(state | shift))); break; case snd_K_0: case snd_K_1: case snd_K_2: case snd_K_3: case snd_K_4: case snd_K_5: case snd_K_6: case snd_K_7: case snd_K_8: case snd_K_9: counting = true; number_buffer[number_ctr] = (char)('0' + keysym - snd_K_0); if (number_ctr < (NUMBER_BUFFER_SIZE - 2)) number_ctr++; /* there is also the bare-number case below */ break; case snd_keypad_0: case snd_keypad_1: case snd_keypad_2: case snd_keypad_3: case snd_keypad_4: case snd_keypad_5: case snd_keypad_6: case snd_keypad_7: case snd_keypad_8: case snd_keypad_9: counting = true; number_buffer[number_ctr] = (char)('0' + keysym - snd_keypad_0); if (number_ctr < (NUMBER_BUFFER_SIZE - 2)) number_ctr++; /* there is also the bare-number case below */ break; case snd_K_space: if (count > 0) { start_selection_creation(cp, cursor_sample(cp)); status_report(sp, "selection starts at %lld", cursor_sample(cp)); } break; case snd_K_period: case snd_keypad_Decimal: counting = true; number_buffer[number_ctr] = '.'; number_ctr++; dot_seen = true; break; case snd_K_greater: cp->cursor_on = true; cursor_moveto_end(cp); break; case snd_K_less: cp->cursor_on = true; cursor_moveto(cp ,0); break; case snd_K_minus: counting = true; number_ctr = 1; number_buffer[0] = '-'; break; case snd_K_underscore: undo_edit_with_sync(cp, count); break; default: status_report(sp, "C-%s undefined", key_to_name(keysym)); break; } } else /* extended mode with ctrl down */ { /* -------------------------------- C-x C-key -------------------------------- */ if (!got_ext_count) ext_count = 1; extended_mode = false; switch (keysym) { case snd_K_B: case snd_K_b: set_window_bounds(cp, ext_count); break; case snd_K_C: case snd_K_c: hide_controls(sp); break; case snd_K_F: case snd_K_f: make_open_file_dialog(FILE_READ_WRITE, true); break; case snd_K_G: case snd_K_g: control_g(sp); break; case snd_K_J: case snd_K_j: cp->cursor_on = true; goto_mix(cp, ext_count); break; case snd_K_O: case snd_K_o: /* this doesn't change the View:Controls menu label because (sigh...) it's specific to the currently selected sound */ show_controls(sp); break; case snd_K_P: case snd_K_p: set_window_size(cp, ext_count); break; case snd_K_Q: case snd_K_q: make_mix_file_dialog(true); break; case snd_K_R: case snd_K_r: redo_edit_with_sync(cp, ext_count); break; case snd_K_S: case snd_K_s: save_edits_from_kbd(sp); break; case snd_K_T: case snd_K_t: stop_playing_sound(sp, PLAY_C_T); break; case snd_K_U: case snd_K_u: undo_edit_with_sync(cp, ext_count); break; case snd_K_V: case snd_K_v: set_window_percentage(cp, ext_count); break; #if (!USE_NO_GUI) case snd_K_W: case snd_K_w: { chan_info *cp; cp = any_selected_channel(any_selected_sound()); make_channel_extract_dialog(cp->chan); } break; #endif case snd_K_Z: case snd_K_z: cp->cursor_on = true; cos_smooth(cp, cursor_sample(cp), ext_count, OVER_SOUND); break; case snd_K_Right: sx_incremented(cp, state_amount(state | shift)); break; case snd_K_Left: sx_incremented(cp, -state_amount(state | shift)); break; case snd_K_Up: zx_incremented(cp, 1.0 + state_amount(state | shift)); break; case snd_K_Down: zx_incremented(cp, 1.0 / (1.0 + state_amount(state | shift))); break; default: status_report(sp, "C-x C-%s undefined", key_to_name(keysym)); break; } } } else { if (!extended_mode) /* -------------------------------- key (or M-key) -------------------------------- */ { /* no control (but possibly meta), not extended mode -- bare alpha chars sent to listener if possible */ /* (we already checked for possible user key bindings above) */ switch (keysym) { case snd_K_0: case snd_K_1: case snd_K_2: case snd_K_3: case snd_K_4: case snd_K_5: case snd_K_6: case snd_K_7: case snd_K_8: case snd_K_9: counting = true; number_buffer[number_ctr] = (char)('0' + keysym-snd_K_0); if (number_ctr < (NUMBER_BUFFER_SIZE - 2)) number_ctr++; break; case snd_keypad_0: case snd_keypad_1: case snd_keypad_2: case snd_keypad_3: case snd_keypad_4: case snd_keypad_5: case snd_keypad_6: case snd_keypad_7: case snd_keypad_8: case snd_keypad_9: counting = true; number_buffer[number_ctr] = (char)('0' + keysym - snd_keypad_0); if (number_ctr < (NUMBER_BUFFER_SIZE - 2)) number_ctr++; break; case snd_K_period: case snd_keypad_Decimal: counting = true; number_buffer[number_ctr] = '.'; number_ctr++; dot_seen = true; break; case snd_K_greater: cp->cursor_on = true; cursor_moveto_end(cp); break; case snd_K_less: cp->cursor_on = true; cursor_moveto(cp, 0); break; case snd_K_minus: counting = true; number_buffer[0] = '-'; number_ctr = 1; break; case snd_K_Right: sx_incremented(cp, state_amount(state | shift)); break; case snd_K_Left: sx_incremented(cp, -state_amount(state | shift)); break; case snd_K_Up: zx_incremented(cp, 1.0 + state_amount(state | shift)); break; case snd_K_Down: zx_incremented(cp, 1.0 / (1.0 + state_amount(state | shift))); break; case snd_K_Home: redirect_everything_to(printout_to_status_area, (void *)sp); sp = snd_update(sp); redirect_everything_to(NULL, NULL); break; case snd_K_space: if (play_in_progress()) toggle_dac_pausing(); else play_sound(sp, cursor_sample(cp), NO_END_SPECIFIED); /* was deactivate_selection */ break; case snd_keypad_Add: if (time_graph_type(ss) == GRAPH_AS_WAVOGRAM) set_wavo_trace(wavo_trace(ss) + 1); else set_spectro_hop(spectro_hop(ss) + 1); reflect_spectro(); break; case snd_keypad_Subtract: if (time_graph_type(ss) == GRAPH_AS_WAVOGRAM) { if (wavo_trace(ss) > 1) set_wavo_trace(wavo_trace(ss) - 1); } else { if (spectro_hop(ss) > 1) set_spectro_hop(spectro_hop(ss) - 1); } reflect_spectro(); break; case snd_keypad_Multiply: set_transform_size(transform_size(ss) * 2); break; case snd_keypad_Divide: if (transform_size(ss) > 4) set_transform_size(transform_size(ss) / 2); break; case snd_keypad_Delete: set_dot_size(dot_size(ss) + 1); break; case snd_keypad_Insert: if (dot_size(ss) > 1) set_dot_size(dot_size(ss) - 1); break; case snd_keypad_Enter: reset_spectro(); reflect_spectro(); break; case snd_keypad_Up: zoom_fft(1.0 + state_amount(state | shift)); break; case snd_keypad_Down: zoom_fft(1.0 / (1.0 + state_amount(state | shift))); break; case snd_keypad_Left: move_fft(-state_amount(state | shift)); break; case snd_keypad_Right: move_fft(state_amount(state | shift)); break; default: /* try to send unbuckified random keyboard input to the lisp listener */ #if USE_MOTIF /* if meta key, assume for now that it's intended as a menu accelerator (don't send it to the listener) */ /* in gtk (and apparently some motif's?) we don't even see the accelerator, but in Linux we do */ if ((state & snd_MetaMask) && ((keysym == snd_K_f) || (keysym == snd_K_e) || (keysym == snd_K_v) || (keysym == snd_K_o) || (keysym == snd_K_h))) /* here the accelerators are f e v o h (not upper case for some reason -- it's given as 'F' in snd-xmenu.c) */ return; /* it might be better to remove the menu accelerators -- they are a dubious feature to begin with */ #endif #if HAVE_EXTENSION_LANGUAGE { char buf[2]; buf[0] = keysym; buf[1] = 0; if (listener_is_visible()) { goto_listener(); listener_append(buf); } } #else status_report(sp, "key %s%s undefined", (state & snd_MetaMask) ? "M-" : "", key_to_name(keysym)); #endif break; } } else /* extended mode with ctrl up -- where not an emacs analogy, related to the current selection */ /* the active selection now follows the edit list, so there may be no relation between * region 0 and the active selection -- in ambiguous cases, we need to look explicitly * for the selection first. */ { /* -------------------------------- C-x key -------------------------------- */ extended_mode = false; if (!(state & snd_MetaMask)) { switch (keysym) { case snd_K_B: case snd_K_b: cp->cursor_on = true; handle_cursor(cp, CURSOR_ON_LEFT); break; case snd_K_C: case snd_K_c: if (!(mark_define_region(cp, (!got_ext_count) ? 1 : ext_count))) set_status(cp->sound, "no such mark", false); break; case snd_K_E: case snd_K_e: if (defining_macro) { set_status(sp, "can't call macro while it's being defined", false); defining_macro = false; macro_size = 0; /* so subsequent M-x e doesn't get something silly */ } else { execute_last_macro(cp, (!got_ext_count) ? 1 : ext_count); if ((cp) && (cp->sound) && (cp->active >= CHANNEL_HAS_EDIT_LIST)) handle_cursor(cp, cursor_decision(cp)); else return; } break; case snd_K_F: case snd_K_f: cp->cursor_on = true; handle_cursor(cp, CURSOR_ON_RIGHT); break; case snd_K_K: case snd_K_k: snd_close_file(sp); break; case snd_K_L: case snd_K_l: cp->cursor_on = true; if (selection_is_active_in_channel(cp)) cursor_moveto(cp, (mus_long_t)(selection_beg(cp) + 0.5 * selection_len())); else set_status(sp, "no active selection", false); handle_cursor_with_sync(cp, CURSOR_IN_MIDDLE); break; case snd_K_O: case snd_K_o: if (ext_count > 0) goto_next_graph(cp, ext_count); else goto_previous_graph(cp, ext_count); break; case snd_K_P: case snd_K_p: if (!got_ext_count) play_selection(IN_BACKGROUND); else play_region(ext_count, IN_BACKGROUND); break; case snd_K_Q: case snd_K_q: add_selection_or_region((!got_ext_count) ? 0 : ext_count, cp); break; case snd_K_R: case snd_K_r: redo_edit_with_sync(cp, (!got_ext_count) ? 1 : ext_count); break; case snd_K_U: case snd_K_u: undo_edit_with_sync(cp, (!got_ext_count) ? 1 : ext_count); break; case snd_K_V: case snd_K_v: if (selection_is_active_in_channel(cp)) window_framples_selection(cp); else { bool complain = true; if (cp->sound->channel_style != CHANNELS_SEPARATE) { int i; for (i = 0; i < sp->nchans; i++) if ((i != cp->chan) && (selection_is_active_in_channel(sp->chans[i]))) { window_framples_selection(sp->chans[i]); complain = false; break; } } if (complain) set_status(sp, "no active selection", false); } break; case snd_K_Z: case snd_K_z: if (selection_is_active_in_channel(cp)) cos_smooth(cp, cursor_sample(cp), (!got_ext_count) ? 1 : ext_count, OVER_SELECTION); else set_status(sp, "no active selection", false); break; case snd_K_Right: sx_incremented(cp, state_amount(state | shift)); break; case snd_K_Left: sx_incremented(cp, -state_amount(state | shift)); break; case snd_K_Up: zx_incremented(cp, 1.0 + state_amount(state | shift)); break; case snd_K_Down: zx_incremented(cp, 1.0 / (1.0 + state_amount(state | shift))); break; case snd_K_less: cp->cursor_on = true; cursor_moveto(cp, 0); break; case snd_K_greater: cp->cursor_on = true; cursor_moveto_end(cp); break; case snd_K_openparen: if (defining_macro) set_status(sp, "macro definition already in progress", false); else { start_defining_macro(); set_status(sp, "defining macro...", false); } break; case snd_K_closeparen: if (defining_macro) { stop_defining_macro(); clear_status_area(sp); } break; default: status_report(sp, "C-x %s undefined", key_to_name(keysym)); break; } } else { status_report(sp, "C-x M-%s undefined", key_to_name(keysym)); } } } if (!extended_mode) {got_ext_count = false; ext_count = 1;} } char *make_key_name(char *buf, int buf_size, int key, int state, bool extended) { snprintf(buf, buf_size, "%s%s%s", (extended) ? "C-x " : "", (state & snd_ControlMask) ? ((state & snd_MetaMask) ? "CM-" : "C-") : ((state & snd_MetaMask) ? "M-" : ""), (key == snd_K_less) ? "<" : ((key == snd_K_greater) ? ">" : ((key == snd_K_openparen) ? "(" : ((key == snd_K_closeparen) ? ")" : ((key == snd_K_slash) ? "/" : KEY_TO_NAME(key)))))); return(buf); } static int key_name_to_key(Xen key, const char *caller) { /* Ruby thinks chars are strings */ if (Xen_is_integer(key)) return(Xen_integer_to_C_int(key)); /* includes 0xffc0 style keys, and in Ruby things like ?a */ #if (!HAVE_RUBY) if (Xen_is_char(key)) return((int)(Xen_char_to_C_char(key))); #endif #if USE_MOTIF return((int)XStringToKeysym(Xen_string_to_C_string(key))); /* these are the X names: not "+" but "plus" etc */ #endif #if USE_GTK return((int)gdk_keyval_from_name(Xen_string_to_C_string(key))); #endif return(0); } static Xen check_for_key_error(int k, int s, const char *caller) { if ((k < MIN_KEY_CODE) || (k > MAX_KEY_CODE) || (s < MIN_KEY_STATE) || (s > MAX_KEY_STATE)) Xen_error(Xen_make_error_type("no-such-key"), Xen_list_4(C_string_to_Xen_string("~A: no such key: ~A, state: ~A"), C_string_to_Xen_string(caller), C_int_to_Xen_integer(k), C_int_to_Xen_integer(s))); return(Xen_false); } static Xen g_key_binding(Xen key, Xen state, Xen cx_extended) { #define H_key_binding "(" S_key_binding " key :optional (state 0) extended): function bound to this key and associated \ modifiers. As in " S_bind_key ", state is the logical 'or' of ctrl=4, meta=8, and 'extended' is " PROC_TRUE " if the key is \ prefixed with C-x. 'key' can be a character, a key name such as 'Home', or an integer." int i, k, s; Xen_check_type(Xen_is_integer(key) || Xen_is_char(key) || Xen_is_string(key), key, 1, S_key_binding, "an integer, character, or string"); Xen_check_type(Xen_is_integer_or_unbound(state), state, 2, S_key_binding, "an integer"); Xen_check_type(Xen_is_boolean_or_unbound(cx_extended), cx_extended, 3, S_key_binding, "a boolean"); k = key_name_to_key(key, S_key_binding); s = ((Xen_is_integer(state)) ? Xen_integer_to_C_int(state) : 0) & 0xfffe; /* no shift bit */ check_for_key_error(k, s, S_key_binding); i = in_keymap(k, s, Xen_is_true(cx_extended)); if (i >= 0) return(keymap[i].func); return(Xen_undefined); } static Xen g_bind_key_1(Xen key, Xen state, Xen code, Xen cx_extended, Xen origin, Xen prefs_info, const char *caller) { int k, s; bool e; Xen_check_type(Xen_is_integer(key) || Xen_is_string(key) || Xen_is_char(key), key, 1, caller, "an integer, char, or string"); Xen_check_type(Xen_is_integer(state), state, 2, caller, "an integer"); Xen_check_type((Xen_is_false(code) || Xen_is_procedure(code)), code, 3, caller, PROC_FALSE " or a procedure"); Xen_check_type(Xen_is_boolean_or_unbound(cx_extended), cx_extended, 4, caller, "a boolean"); Xen_check_type(Xen_is_string_or_unbound(origin), origin, 5, caller, "a string"); Xen_check_type(Xen_is_string_or_unbound(prefs_info), prefs_info, 6, caller, "a string"); k = key_name_to_key(key, caller); s = Xen_integer_to_C_int(state) & 0xfffe; /* get rid of shift bit */ check_for_key_error(k, s, caller); e = (Xen_is_true(cx_extended)); if (Xen_is_false(code)) set_keymap_entry(k, s, 0, Xen_undefined, e, NULL, NULL); else { char buf[256]; int args; const char *comment = NULL, *prefs = NULL; args = Xen_required_args(code); if (args > 1) { Xen errmsg; char *errstr; errstr = mus_format(S_bind_key " function arg should take either zero or one args, not %d", args); errmsg = C_string_to_Xen_string(errstr); free(errstr); return(snd_bad_arity_error(caller, errmsg, code)); } if (Xen_is_string(origin)) comment = Xen_string_to_C_string(origin); else comment = make_key_name(buf, 256, k, s, e); if (Xen_is_string(prefs_info)) prefs = Xen_string_to_C_string(prefs_info); set_keymap_entry(k, s, args, code, e, comment, prefs); } return(code); } static Xen g_bind_key(Xen key, Xen state, Xen code, Xen cx_extended, Xen origin, Xen prefs_info) { #define H_bind_key "(" S_bind_key " key modifiers func :optional extended origin prefs-info): \ causes 'key' (an integer, character, or string) \ when typed with 'modifiers' (0:none, 4:control, 8:meta) (and C-x if extended) to invoke 'func', a function of \ zero or one arguments. If the function takes one argument, it is passed the preceding C-u number, if any. \ The function should return one of the cursor choices (e.g. " S_keyboard_no_action "). 'origin' is \ the name reported if an error occurs. The 'key' argument can be the X/Gtk name of the key (e.g. \"plus\" for \"+\" or \"Home\"), \ the character on the key (#\\a), or the integer corresponding to that character: (\"(char->integer #\\a)\" in Scheme, \ \"?a\" in Ruby, \ or \" a\" in Forth)." return(g_bind_key_1(key, state, code, cx_extended, origin, prefs_info, S_bind_key)); } static Xen g_unbind_key(Xen key, Xen state, Xen cx_extended) { #define H_unbind_key "(" S_unbind_key " key state :optional extended): undo the effect of a prior " S_bind_key " call." return(g_bind_key_1(key, state, Xen_false, cx_extended, Xen_undefined, Xen_undefined, S_unbind_key)); } static Xen g_key(Xen kbd, Xen buckybits, Xen snd, Xen chn) { #define H_key "(" S_key " key modifiers :optional snd chn): simulate typing 'key' with 'modifiers' in snd's channel chn" chan_info *cp; int k, s; Xen_check_type(Xen_is_integer(kbd) || Xen_is_char(kbd) || Xen_is_string(kbd), kbd, 1, S_key, "an integer, character, or string"); Xen_check_type(Xen_is_integer(buckybits), buckybits, 2, S_key, "an integer"); Snd_assert_channel(S_key, snd, chn, 3); cp = get_cp(snd, chn, S_key); if (!cp) return(Xen_false); k = key_name_to_key(kbd, S_key); s = Xen_integer_to_C_int(buckybits); check_for_key_error(k, s, S_key); keyboard_command(cp, k, s); return(kbd); } Xen_wrap_3_optional_args(g_key_binding_w, g_key_binding) Xen_wrap_6_optional_args(g_bind_key_w, g_bind_key) Xen_wrap_3_optional_args(g_unbind_key_w, g_unbind_key) Xen_wrap_4_optional_args(g_key_w, g_key) void g_init_kbd(void) { int i; #define H_cursor_in_view "The value for a " S_bind_key " function that moves the window so that the cursor is in the view" #define H_cursor_on_left "The value for a " S_bind_key " function that moves the window so that the cursor is at the left edge" #define H_cursor_on_right "The value for a " S_bind_key " function that moves the window so that the cursor is at the right edge" #define H_cursor_in_middle "The value for a " S_bind_key " function that moves the window so that the cursor is in the middle" #define H_keyboard_no_action "The value for a " S_bind_key " function that does nothing upon return" Xen_define_constant(S_cursor_in_view, CURSOR_IN_VIEW, H_cursor_in_view); Xen_define_constant(S_cursor_on_left, CURSOR_ON_LEFT, H_cursor_on_left); Xen_define_constant(S_cursor_on_right, CURSOR_ON_RIGHT, H_cursor_on_right); Xen_define_constant(S_cursor_in_middle, CURSOR_IN_MIDDLE, H_cursor_in_middle); Xen_define_constant(S_keyboard_no_action, KEYBOARD_NO_ACTION, H_keyboard_no_action); Xen_define_safe_procedure(S_key_binding, g_key_binding_w, 1, 2, 0, H_key_binding); Xen_define_safe_procedure(S_bind_key, g_bind_key_w, 3, 3, 0, H_bind_key); Xen_define_safe_procedure(S_unbind_key, g_unbind_key_w, 2, 1, 0, H_unbind_key); Xen_define_safe_procedure(S_key, g_key_w, 2, 2, 0, H_key); for (i = 0; i < NUM_BUILT_IN_KEYS; i++) built_in_keys[i].func = Xen_false; } snd-16.1/popup.rb0000644000076400007640000011557512453076052012045 0ustar bilbil# popup.rb -- Specialize Popup Menus converted from Scheme to Ruby. # Author: Michael Scholz # Created: 02/09/05 22:28:49 # Changed: 14/11/09 01:52:47 # Requires --with-motif # # Tested with Snd 15.x # Ruby 2.x.x # Motif 2.3.3 X11R6 # # $info_comment_hook: lambda do |file, info_string| ...; new_info_string; end # $edhist_save_hook: lambda do |prc| ... end # # make_snd_popup(name, *rest) do ... end # # class Snd_popup_menu < Menu # initialize(name, parent, args, target) do ... end # before_popup_hook, lambda do |snd, chn, xe| ...; flag; end # entry(name, *rest) do |snd, chn, w| ... end # label(name, args) # separator(single) # cascade(name, args) do ... end # each_value do |val| ... end # # class Cascade < Snd_popup_menu # initialize(name, parent, args) # values # # listener # children(set_cb, rest = false) do |snd| ... end # ==> set_cb.arity == -1 or 0 # # edhist # children(set_cb, rest = false) do |snd, chn, idx| ... end # ==> set_cb.arity == -1 or 0 # # transform # children(set_cb, rest = false) do |snd, chn, val| ... end # ==> set_cb.arity == 3 (snd, chn, val) # # Usage: # # menu = make_snd_popup("graph") do # entry("Play") do |snd, chn, w| play(snd, 0) end # cascade("Marks") do # entry("Add") do |snd, chn, w| add_mark(cursor(snd, chn), snd, chn) end # entry("Delete") do |snd, chn, w| delete_mark(marks(snd, chn)[0]) end # end # entry("Exit") do |snd, chn, w| exit(0) end # end # menu.change_menu_color("ivory3") # # CHILDREN # # Cascading can be simplified by using `children' which can take a # `set_cb' callback with 0 args (on listener) or 3 args (on channels). # If set_cb.arity == 0, the body.arity == 1 (current sound). If # set_cb.arity == 3, the body.arity == 3 (snd, chn, val). See # listener-popup menu below for the former and transform-popup for the # latter variant. # # children(set_cb, rest = false, &body) # case SET_CB.arity # when 0 # # listener popup example below # BODY.arity == 1 (snd) # REST means "no widget" # when 1 # # transform popup example below # BODY.arity == 3 (snd, chn, val) # REST means an array of arrays of [name, value] # end # # make_snd_popup("Listener", ...) do # ... # cascade("Close") do # children(lambda do | | Snd.sounds end) do |snd| # close_sound_extend(snd) # end # end # ... # end # # make_snd_popup("Transform") do # ... # cascade("Graph type") do # children(lambda do |snd, chn, val| # transform_graph_type(snd, chn) != val # end, [["once", Graph_once], # ["sonogram", Graph_as_sonogram], # ["spectrogram", Graph_as_spectrogram]]) do |snd, chn, val| # set_transform_graph_type(val, snd, choose_chan.call(snd, chn)) # end # end # ... # end # # Change the appearance of menu entries with `before_popup_hook', a # hook per instance. The example menus below may help. require "hooks" require "snd-xm" include Snd_XM unless provided?(:snd_motif) Snd.raise(:runtime_error, __FILE__, "--with-motif required") end $edhist_help_edits = false # for prefs $info_comment_hook = Hook.new("$info_comment_hook", 2, "\ lambda do |file, info_string| ...; new_info_string; end: provides a way to add more information to INFO_STRING and format the comment of FILE. The hook collects the return value of one hook to INFO_STRING on subsequent calls. This hook is called in popup.rb and nb.rb. If no hook procedure is defined, the normal sound comment is added. In snd-xm.rb exists format_sound_comment(comment). It is a very simple comment formatter. $info_comment_hook.add_hook!(\"snd-init-hook\") do |file, info| info += format_sound_comment(mus_sound_comment(file)) if s = mus_sound_loop_info(file) info += format(\" loop: %s\n\", s.inspect) end info end") # calls all hook-procs as long as they return true class Hook def run_hook_bool(*args) ret = true self.run_hook do |prc| if prc.call(*args) != true ret = false break end end ret end end add_help(:make_snd_popup, "make_snd_popup(name, *rest) do ... end NAME # menu name :parent, main_widgets[Main_pane] # e.g. listener popup takes # main_widgets[Listener_pane] :target, :channels # :channels, :edhist, :widget, :event :args, [RXmNbackground, highlight_color] # Motif arguments") def make_snd_popup(name, *rest, &body) parent, target = nil optkey(rest, binding, [:parent, main_widgets[Main_pane_shell]], [:target, :channels]) # targets :channels, :edhist, :widget, :event args = get_args(rest, :args, [RXmNbackground, highlight_color]) Snd_popup_menu.new(name, parent, args, target, &body) end class Snd_popup_menu < Menu def initialize(name, parent, args, target, &body) super(name, parent, args) @parent = parent @values = [] @popups = [] @widget_names = {} @target = target @before_popup_hook = Hook.new("@before_popup_hook", 3, "\ lambda do |snd, chn, xe| ... flag end: called before posting a popup menu. On channel popups (see popup.rb): SND, CHN, and XE are the selected sound, channel and x-position on the channel pane. If it returns non-nil or non-false, the menu will be posted. On the listener popup (see popup.rb): SND, CHN, and XE are meaningless as well as the return value. The menu will be posted in every case. On event-handler popups (see nb.rb): SND, CHN, and XE are meaningless. If it returns non-nil or non-false, the menu will be posted.") if symbol?(@target) # no `create' on Cascade.new create(&body) end end attr_reader :before_popup_hook def entry(name, *rest, &body) procedure = optkey(rest, :procedure) args = get_args(rest, :args, @args) child = RXtCreateManagedWidget(name, RxmPushButtonWidgetClass, @menu, args) if block_given? RXtAddCallback(child, RXmNactivateCallback, lambda do |w, c, i| chn = if snd = selected_sound() selected_channel() else false end body.call(snd, chn, w) end) end @widget_names[child] = name proc?(procedure) and procedure.call(child) child end def label(name, args = @args) label = super(name, args) @widget_names[label] = name label end def cascade(name, args = @args, &body) cas = Cascade.new(name, @menu, args, @target) cas.instance_eval(&body) if block_given? @values.push(cas.values) cas end def each_value(&body) @values.map(&body) end def widget_name(widget) @widget_names[widget] end private def create(&body) @menu = RXmCreatePopupMenu(@parent, @label, [RXmNpopupEnabled, RXmPOPUP_AUTOMATIC] + @args) unless @label.empty? label(@label) separator end instance_eval(&body) if block_given? case @target when :channels, :edhist Snd.sounds.each do |snd| set_channel_popup(snd) end hook_name = format("%s-popup", (@label or "channels").downcase.tr(" ", "-")) $after_open_hook.add_hook!(hook_name) do |snd| set_channel_popup(snd) end when :widget set_widget_popup when :event set_event_popup end end def set_channel_popup(snd) channels(snd).times do |chn| res = @popups.detect do |c| c == [snd, chn] end unless res @popups.push([snd, chn]) if @target == :edhist RXtAddCallback(channel_widgets(snd, chn)[Edhist], RXmNpopupHandlerCallback, lambda do |w, c, i| if Rtype(Revent(i)) == RButtonPress @before_popup_hook.call(snd, chn, w) Rset_menuToPost(i, @menu) end end) end if @target == :channels RXtAddCallback(channel_widgets(snd, chn)[Graph], RXmNpopupHandlerCallback, lambda do |w, c, i| if Rtype(e = Revent(i)) == RButtonPress if @target == :channels and @before_popup_hook.empty? Rset_menuToPost(i, @menu) else xe = Rx_root(e) - RXtTranslateCoords(w, 0, 0)[0] if channel_style(snd) == Channels_combined ye = Ry(e) if channel_style(snd) == Channels_combined ye = Ry(e) cn = (0...channels(snd)).detect do |cc| ye < axis_info(snd, cc)[14] end chn = cn ? cn : channels(snd) chn -= 1 end unless chn.between?(0, channels(snd) - 1) # in case of chans(new-snd) < chans(old-snd) # and new-snd has the same index like closed # old-snd chn = channels(snd) - 1 end end if @before_popup_hook.run_hook_bool(snd, chn, xe) Rset_menuToPost(i, @menu) end end end end) end end end end # e.g. on listener def set_widget_popup RXtAddCallback(@parent, RXmNpopupHandlerCallback, lambda do |w, c, i| if Rtype(Revent(i)) == RButtonPress @before_popup_hook.call(selected_sound(), selected_channel(), w) Rset_menuToPost(i, @menu) end end) end # see nb.rb for an example def set_event_popup RXtAddEventHandler(@parent, RButtonPressMask, false, lambda do |w, c, i, f| if Rbutton(i) == 3 if @before_popup_hook.run_hook_bool(w, c, i) RXmMenuPosition(@menu, i) RXtManageChild(@menu) end end end) end class Cascade < Snd_popup_menu def initialize(name, parent, args, target) super(name, parent, args, nil) @menu = RXmCreatePulldownMenu(@parent, @label, @args) @cascade = RXtCreateManagedWidget(@label, RxmCascadeButtonWidgetClass, @parent, [RXmNsubMenuId, @menu] + @args) @children = [] @target = target end attr_reader :values def children(set_cb, rest = false, &body) assert_type(proc?(set_cb), set_cb, 0, "a proc") assert_type(proc?(body), body, 2, "a proc") case set_cb.arity when -1, 0 add_with_arity_1(rest, set_cb, &body) when 3 add_with_arity_3(rest, set_cb, &body) end end private # listener: set_cb.arity == 0|-1, body.arity == 1 (snd) # edhist: set_cb.arity == 0|-1, body.arity == 3 (snd, chn, index) def add_with_arity_1(no_widget, set_cb, &body) if no_widget widget = false else widget = RXtCreateManagedWidget(@label, RxmPushButtonWidgetClass, @parent, @args) RXtAddCallback(widget, RXmNactivateCallback, lambda do |w, c, i| body.call(set_cb.call.first) end) end RXtAddCallback(@cascade, RXmNcascadingCallback, lambda do |w, c, i| @children.each do |child| RXtUnmanageChild(child) end snds = set_cb.call.reverse clen = @children.length slen = snds.length if clen < slen (clen...slen).each do |numb| child = RXtCreateManagedWidget(numb.to_s, RxmPushButtonWidgetClass, @menu, @args) RXtAddCallback(child, RXmNactivateCallback, lambda do |ww, cc, ii| if @target == :edhist body.call(selected_sound, selected_channel, RXtVaGetValues(ww,[RXmNuserData, 0]).cadr) else body.call(find_sound(current_label(ww))) end end) RXtVaSetValues(child, [RXmNuserData, @children.length]) @children.push(child) end end if slen.nonzero? if @target == :edhist @children.zip(snds) do |child, label| break unless label if string?(label) change_label(child, label) else change_label(child, format("%s[%d]", short_file_name(label.car), label.cadr)) end RXtManageChild(child) end else @children.zip(snds) do |child, snd| break unless snd change_label(child, short_file_name(snd)) RXtManageChild(child) end end end end) @values = [widget, @menu, @cascade, set_cb] end # transform: set_cb.arity and body.arity == 3 (snd, chn, val) def add_with_arity_3(list, set_cb, &body) list.each do |name, val| wid = RXtCreateManagedWidget(name.to_s, RxmPushButtonWidgetClass, @menu, @args) RXtAddCallback(wid, RXmNactivateCallback, lambda do |w, c, i| body.call(selected_sound, selected_channel, val) end) @values.push(val) @children.push(wid) end RXtAddCallback(@cascade, RXmNcascadingCallback, lambda do |w, c, i| @children.each_with_index do |child, idx| RXtSetSensitive(child, set_cb.call(selected_sound, selected_channel, @values[idx])) end end) end end end unless defined? $__private_popup_menu__ and $__private_popup_menu__ # # Selection Popup # make_snd_popup("Selection") do stopping = stopping1 = false stop_widget = stop_widget1 = nil selctr = 0 $stop_playing_selection_hook.add_hook!("popup-stop-selection-hook") do | | if stopping stopping = false change_label(stop_widget, "Play") if widget?(stop_widget) end end entry("Play") do |snd, chn, w| if stopping stopping = false change_label(w, "Play") if stopping1 stopping1 = false change_label(stop_widget1, "Loop play") $stop_playing_selection_hook.remove_hook!("popup-play-selection") end stop_playing else change_label(w, "Stop") stop_widget = w stopping = true play(selection()) end end entry("Loop play") do |snd, chn, w| if stopping1 stopping1 = false change_label(w, "Loop play") $stop_playing_selection_hook.remove_hook!("popup-play-selection") if stopping stopping = false change_label(stop_widget, "Play") end stop_playing else change_label(w, "Stop!") stop_widget1 = w stopping1 = true $stop_playing_selection_hook.add_hook!("popup-play-selection") do | | play(selection()) end play(selection()) end end entry("Delete") do |snd, chn, w| delete_selection end entry("Zero") do |snd, chn, w| scale_selection_by(0.0) end entry("Crop") do |snd, chn, w| sndlist = [] Snd.sounds.each do |s| channels(s).times do |i| sndlist.push([s, i]) if selection_member?(s, i) end end sndlist.each do |selection| snd, chn = selection beg = selection_position(snd, chn) len = selection_framples(snd, chn) as_one_edit(lambda do | | delete_samples(0, beg, snd, chn) if beg > 0 if len < framples(snd, chn) delete_samples(len + 1, framples(snd, chn) - len, snd, chn) end end) end end entry("Save as") do |snd, chn, w| save_selection_dialog end entry("Copy->New") do |snd, chn, w| new_file_name = format("newf-%d.snd", selctr) selctr += 1 save_selection(new_file_name) open_sound(new_file_name) end entry("Cut->New") do |snd, chn, w| new_file_name = format("newf-%d.snd", selctr) selctr += 1 save_selection(new_file_name) delete_selection open_sound(new_file_name) end entry("Snap marks") do |snd, chn, w| selection_members.each do |s, c| pos = selection_position(s, c) len = selection_framples(s, c) - 1 add_mark(pos, s, c) add_mark(pos + len, s, c) end end entry("Selection Info") do |snd, chn, w| beg = selection_position() len = selection_framples() sr = srate.to_f str = format(" start: %d, %.3f", beg, beg / sr) str += format(" end: %d, %.3f", beg + len, (beg + len) / sr) str += format(" duration: %d, %.3f", len, len / sr) str += format(" chans: %d", selection_chans) str += format(" maxamp: %.3f", selection_maxamp) end # 2 == selection entry("Apply controls") do |snd, chn, w| apply_controls(snd, 2) end entry("Reset controls") do |snd, chn, w| reset_controls() end entry("Unselect") do |snd, chn, w| set_selection_member?(false, true) end entry("Revert") do |snd, chn, w| reverse_selection() end entry("Mix") do |snd, chn, w| mix_selection(cursor()) end entry("Invert") do |snd, chn, w| scale_selection_by(-1) end before_popup_hook.add_hook!("selection popup") do |snd, chn, xe| fax = if transform_graph?(snd, chn) axis_info(snd, chn, Transform_graph) else false end lax = if lisp_graph?(snd, chn) axis_info(snd, chn, Lisp_graph) else false end if fax and xe >= fax[10] and xe <= fax[12] false else if lax and xe >= lax[10] and xe <= lax[12] false else if selection? sr = srate(snd).to_f pos = selection_position(snd, chn) beg = pos / sr fin = (pos + selection_framples(snd, chn)) / sr end if selection? and xe >= x2position(beg, snd, chn) and xe <= x2position(fin, snd, chn) true else false end end end end end # # Graph Popup # make_snd_popup("Snd") do stopping = false stop_widget = nil $stop_playing_hook.add_hook!("popup-change-label-hook") do |snd| if stopping stopping = false change_label(stop_widget, "Play") if widget?(stop_widget) end end entry("Play", :procedure, lambda do |w| stop_widget = w end) do |snd, chn, w| if stopping stopping = false change_label(w, "Play") stop_playing else change_label(w, "Stop") stopping = true play(snd, 0) end end entry("Play channel") do |snd, chn, w| stopping = true change_label(stop_widget, "Stop") play(snd, :channel, chn) end entry("Play from cursor") do |snd, chn, w| stopping = true change_label(stop_widget, "Stop") play(snd, :start, cursor(snd, chn)) end entry("Play previous") do |snd, chn, w| stopping = true change_label(stop_widget, "Stop") play(snd, :channel, chn, :edit_position, edit_position - 1) end entry("Play original") do |snd, chn, w| stopping = true change_label(stop_widget, "Stop") play(snd, :channel, chn, :edit_position, 0) end entry("Undo") do |snd, chn, w| undo_edit(1, snd, chn) end if defined? undo_edit entry("Redo") do |snd, chn, w| redo_edit(1, snd, chn) end if defined? redo_edit entry("Revert") do |snd, chn, w| revert_sound(snd) end entry("Open") do |snd, chn, w| open_file_dialog end entry("Save") do |snd, chn, w| save_sound(snd) end entry("Save as") do |snd, chn, w| select_sound(snd) save_sound_dialog end entry("Update") do |snd, chn, w| update_sound(snd) end entry("Close") do |snd, chn, w| close_sound_extend(snd) end entry("Mix selection") do |snd, chn, w| mix_selection(cursor(snd, chn), snd, chn) end entry("Insert selection") do |snd, chn, w| insert_selection(cursor(snd, chn), snd, chn) end entry("Replace with selection") do |snd, chn, w| beg = cursor(snd, chn) len = selection_framples() sbeg = selection_position() if (not selection_member?(snd, chn)) or ((beg + len) < sbeg) or (beg > (sbeg + len)) delete_samples(beg, len, snd, chn) insert_selection(beg, snd, chn) elsif beg < sbeg delete_samples(beg, sbeg - beg, snd, chn) end end entry("Select all") do |snd, chn, w| select_all(snd, chn) end entry("Unselect") do |snd, chn, w| set_selection_member?(false, true) end entry("Apply controls") do |snd, chn, w| apply_controls() end entry("Reset controls") do |snd, chn, w| reset_controls() end entry("Info") do |snd, chn, w| file = file_name(snd) fdate = Time.at(mus_sound_write_date(file)) date = fdate.localtime.strftime("%a %d-%b-%y %H:%M %z") info_string = format("\ chans: %d, srate: %d length: %1.3f (%d frms) format: %s [%s] maxamp: %s written: %s\n", channels(snd), srate(snd), framples(snd) / srate(snd).to_f, framples(snd), mus_sample_type_name(sample_type(snd)), mus_header_type_name(header_type(snd)), maxamp(snd, true).to_string, date) if $info_comment_hook.empty? if s = comment(snd) info_string += format("comment: %s\n", s) end else $info_comment_hook.run_hook do |prc| info_string = prc.call(file, info_string) end end if defined? XM_NB and defined? Kernel.xm_nb and Kernel.xm_nb.kind_of?(XM_NB) Kernel.xm_nb.popup_nb_hook.run_hook do |prc| info_string = prc.call(snd, info_string) end end info_dialog(file + " info", info_string) end entry("Add mark") do |snd, chn, w| add_mark(cursor(snd, chn), snd, chn) end entry("Delete mark") do |snd, chn, w| if (ms = marks(snd, chn)).nil? or ms.empty? false elsif ms.length == 1 delete_mark(ms[0]) else loc = cursor() id = ms.first cur_min = (loc - mark_sample(ms.first)).abs ms.each do |m| if (this_min = (loc - mark_sample(m)).abs) < cur_min cur_min = this_min id = m end end delete_mark(id) end end entry("Delete all marks") do |snd, chn, w| delete_marks(snd, chn) end entry("To next mark") do |snd, chn, w| key(?j, 4, snd, chn) end entry("To last mark") do |snd, chn, w| key(?\-, 4, snd, chn) key(?j, 4, snd, chn) end separator(:double) entry("Exit") do |snd, chn, w| exit(0) end before_popup_hook.add_hook!("graph popup") do |snd, chn, xe| fax = if transform_graph?(snd, chn) axis_info(snd, chn, Transform_graph) else false end lax = if lisp_graph?(snd, chn) axis_info(snd, chn, Lisp_graph) else false end flag = if fax and xe >= fax[10] and xe <= fax[12] false else if lax and xe >= lax[10] and xe <= lax[12] # lisp graph true else if selection? sr = srate(snd).to_f pos = selection_position(snd, chn) beg = pos / sr fin = (pos + selection_framples(snd, chn)) / sr end if selection? and xe >= x2position(beg, snd, chn) and xe <= x2position(fin, snd, chn) false else true end end end if flag select_sound(snd) select_channel(chn) each_entry do |w| eds = edits(snd, chn) case widget_name(w) when "Snd" if channels(snd) > 1 change_label(w, format("%s[%d]", short_file_name(snd), chn)) else change_label(w, short_file_name(snd)) end when "Save", "Undo", "Revert", "Play previous" eds[0] > 0 ? show_widget(w) : hide_widget(w) when "Play channel" channels(snd) > 1 ? show_widget(w) : hide_widget(w) when "Redo" eds[1] > 0 ? show_widget(w) : hide_widget(w) when "Mix selection", "Insert selection", "Unselect", "Replace with selection" selection? ? show_widget(w) : hide_widget(w) when "Play from cursor" cursor(snd, chn) > 0 ? show_widget(w) : hide_widget(w) when "Play original" eds[0] > 1 ? show_widget(w) : hide_widget(w) when "Delete mark", "To next mark", "To last mark" marks(snd, chn) ? show_widget(w) : hide_widget(w) when "Delete all marks" Snd.marks(snd, chn).length > 1 ? show_widget(w) : hide_widget(w) end end end flag end end # # Transform Popup # make_snd_popup("Transform") do choose_chan = lambda do |snd, chn| if channel_style(snd) == Channels_separate chn else true end end entry("Peaks") do |snd, chn, w| set_show_transform_peaks(!show_transform_peaks(snd, chn), snd, choose_chan.call(snd, chn)) end entry("dB") do |snd, chn, w| set_fft_log_magnitude(!fft_log_magnitude(snd, chn), snd, choose_chan.call(snd, chn)) end entry("Log freq") do |snd, chn, w| set_fft_log_frequency(!fft_log_frequency(snd, chn), snd, choose_chan.call(snd, chn)) end entry("Normalize") do |snd, chn, w| if transform_normalization(snd, chn) == Dont_normalize set_transform_normalization(Normalize_by_channel, snd, choose_chan.call(snd, chn)) else set_transform_normalization(Dont_normalize, snd, choose_chan.call(snd, chn)) end end cascade("Graph type") do children(lambda do |snd, chn, val| transform_graph_type(snd, chn) != val end, [["once", Graph_once], ["sonogram", Graph_as_sonogram], ["spectrogram", Graph_as_spectrogram]]) do |snd, chn, val| set_transform_graph_type(val, snd, choose_chan.call(snd, chn)) end end cascade("Size") do children(lambda do |snd, chn, val| transform_size(snd, chn) != val end, [16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 65536, 262144, 1048576].map do |s| [s.to_s, s] end) do |snd, chn, val| set_transform_size(val, snd, choose_chan.call(snd, chn)) end end cascade("Window") do children(lambda do |snd, chn, val| fft_window(snd, chn) != val end, [["Rectangular", Rectangular_window], ["Hann", Hann_window], ["Welch", Welch_window], ["Parzen", Parzen_window], ["Bartlett", Bartlett_window], ["Hamming", Hamming_window], ["Blackman2", Blackman2_window], ["Blackman3", Blackman3_window], ["Blackman4", Blackman4_window], ["Exponential", Exponential_window], ["Riemann", Riemann_window], ["Kaiser", Kaiser_window], ["Cauchy", Cauchy_window], ["Poisson", Poisson_window], ["Gaussian", Gaussian_window], ["Tukey", Tukey_window], ["Dolph-Chebyshev", Dolph_chebyshev_window], ["Hann-Poisson", Hann_poisson_window], ["Connes", Connes_window], ["Samaraki", Samaraki_window], ["Ultraspherical", Ultraspherical_window]]) do |snd, chn, val| set_fft_window(val, snd, choose_chan.call(snd, chn)) end end cascade("Transform type") do children(lambda do |snd, chn, val| transform_type(snd, chn) != val end, [["Fourier", $fourier_transform], ["Autocorrelate", $autocorrelation], ["Cepstrum", $cepstrum], ["Walsh", $walsh_transform], ["Haar", $haar_transform], ["Wavelet", $wavelet_transform]]) do |snd, chn, val| set_transform_type(val, snd, choose_chan.call(snd, chn)) end end cascade("Wavelet type") do children(lambda do |snd, chn, val| wavelet_type(snd, chn) != val end, ["daub4", "daub6", "daub8", "daub10", "daub12", "daub14", "daub16", "daub18", "daub20", "battle-lemarie", "burt-adelson", "beylkin", "coif2", "coif4", "coif6", "sym2", "sym3", "sym4", "sym5", "sym6"].map_with_index do |v, idx| [v, idx] end) do |snd, chn, val| set_wavelet_type(val, snd, choose_chan.call(snd, chn)) end end entry("Color/Orientation") do |snd, chn, w| color_orientation_dialog() end before_popup_hook.add_hook!("transform popup") do |snd, chn, xe| fax = if transform_graph?(snd, chn) axis_info(snd, chn, Transform_graph) else false end if fax and xe >= fax[10] and xe <= fax[12] each_entry do |w| case widget_name(w) when "Peaks" change_label(w, show_transform_peaks(snd, chn) ? "No peaks" : "Peaks") when "dB" change_label(w, fft_log_magnitude(snd, chn) ? "Linear" : "dB") when "Log freq" change_label(w, fft_log_frequency(snd, chn) ? "Linear freq" : "Log freq") when "Normalize" change_label(w, transform_normalization(snd, chn) == Dont_normalize ? "Normalize" : "Original") end end true else false end end end # # Edit History Popup # make_snd_popup("Edits", :target, :edhist) do funcs = [] make_hook("$edhist_save_hook", 1, "lambda do |prc| ... end: for debugging; \ Called in menu entry Save with new delivered PROC \ from edit_list2function as only argument, e.g. $edhist_save_hook.add_hook!(\"edhist save\") do |prc| Snd.display(prc.source) end") $close_hook.add_hook!("edhist-close") do |snd| name = short_file_name(snd) channels(snd).times do |chn| if old_val = funcs.assoc([snd, chn]) old_val.car = format("%s[%d]", name, chn) end end end entry("Save") do |snd, chn, w| cur_edits = edits(snd, chn) new_func = edit_list2function(snd, chn, cur_edits.car + 1, cur_edits.apply(:+)) $edhist_save_hook.call(new_func) if old_val = funcs.assoc([snd, chn]) old_val.cadr = new_func else funcs.push([[snd, chn], new_func]) end end entry("Reapply") do |snd, chn, w| val = funcs.assoc([snd, chn]) if val prc = val.cadr if proc?(prc) prc.call(snd, chn) end end end cascade("Apply") do children(lambda do | | funcs.map do |vals| vals.car end end, true) do |snd, chn, index| index.between?(0, funcs.length - 1) and funcs[index].cadr.call(snd, chn) end end entry("Clear") do |snd, chn, w| funcs = [] end separator entry("Help") do |snd, chn, w| help_dialog("Edit History Functions", "This popup menu gives access to the \ edit-list function handlers in Snd. \ At any time you can backup in the edit list, \ 'save' the current trailing edits, make some \ new set of edits, then 'reapply' the saved edits. \ The 'apply' choice gives access to all \ currently saved edit lists---any such list can be applied to any channel. \ 'Clear' deletes all saved edit lists.", ["{edit lists}" "{edit-list->function}"], ["extsnd.html#editlists" "extsnd.html#editlist_to_function"]) end before_popup_hook.add_hook!("edhist popup") do |snd, chn, wid| each_value do |val| funcs.empty? ? hide_widget(val.caddr) : show_widget(val.caddr) end each_entry do |w| set_sensitive(w, case widget_name(w) when "Save" (edits(snd, (main_widgets[Notebook_outer_pane] ? false : chn)).apply(:+) > 0) when "Reapply" (not funcs.assoc([snd, chn]).nil?) when "Clear" (not funcs.empty?) else true end) end true end end # # Listener Popup (only with Motif) # if $with_motif make_snd_popup("Listener", :target, :widget, :parent, if widget?(ww = main_widgets[Listener_pane]) ww else set_show_listener(true) set_show_listener(false) main_widgets[Listener_pane] end) do identity = lambda do | | Snd.sounds end edited = lambda do | | Snd.sounds.delete_if do |snd| (0...channels(snd)).detect do |chn| edits(snd, chn).first.zero? end end end focused = lambda do | | snds = Snd.sounds snds.length > 1 ? snds : [] end cascade("Play") do children(identity) do |snd| play(snd, 0) end end entry("Open") do |snd, chn, w| open_file_dialog end entry("Clear listener") do |snd, chn, w| clear_listener end cascade("Close") do children(identity) do |snd| close_sound_extend(snd) end end cascade("Save") do children(edited) do |snd| save_sound(snd) end end cascade("Revert") do children(edited) do |snd| revert_sound(snd) end end cascade("Focus") do children(focused, true) do |snd| if widget?(main_widgets[Notebook_outer_pane]) set_selected_sound(snd) else pane = sound_widgets(snd)[Main_pane] RXtVaSetValues(main_widgets[Top_level_shell], [RXmNallowShellResize, false]) Snd.sounds.each do |them| hide_widget(sound_widgets(them)[Main_pane]) end show_widget(pane) RXtVaSetValues(main_widgets[Top_level_shell], [RXmNallowShellResize, auto_resize]) end end end entry("Help") do |snd, chn, w| selected = listener_selection() if selected help = snd_help(selected) if help help_dialog(selected, help) else snd_warning(format("%p: no help found", selected)) end end end separator(:double) entry("Exit") do |snd, chn, w| exit(0) end before_popup_hook.add_hook!("listener popup") do |d1, d2, d3| each_value do |val| w = val[0] cas = val[1..2] prc = val[3] len = prc.call.length if widget?(w) if len == 1 show_widget(w) else hide_widget(w) end end if len > 1 cas.each do |wid| show_widget(wid) end else cas.each do |wid| hide_widget(wid) end end end each_entry do |w1| if widget?(w1) if widget_name(w1) == "Help" subject = listener_selection() if subject change_label(w1, format("Help on %p", subject)) show_widget(w1) else hide_widget(w1) end end end end end end end $edhist_help_edits = true end # popup.rb ends here snd-16.1/snd-gregion.c0000644000076400007640000010066312512761107012723 0ustar bilbil#include "snd.h" static void sg_left_justify_button(GtkWidget *button) { #if GTK_CHECK_VERSION(3, 0, 0) gtk_widget_set_halign(GTK_WIDGET(button), GTK_ALIGN_START); #else gfloat x, y; gtk_misc_get_alignment(GTK_MISC(GTK_LABEL(BIN_CHILD(button))), &x, &y); gtk_misc_set_alignment(GTK_MISC(GTK_LABEL(BIN_CHILD(button))), 0.05, y); #endif } #if (!GTK_CHECK_VERSION(3, 0, 0)) static void sg_left_justify_label(GtkWidget *label) { /* the label justify function in Gtk refers to the text of the lines after the first! */ gfloat x, y; gtk_misc_get_alignment(GTK_MISC(GTK_LABEL(label)), &x, &y); gtk_misc_set_alignment(GTK_MISC(GTK_LABEL(label)), 0.05, y); } #endif /* -------- region browser -------- */ typedef struct { GtkWidget *rw, *nm, *pl; int pos; } regrow; static GtkWidget *region_dialog = NULL, *region_list, *region_grf; static regrow **region_rows = NULL; static int region_rows_size = 0; static snd_info *rsp = NULL; static int current_region = -1; static GtkWidget *srate_text, *length_text, *chans_text, *maxamp_text; static GtkWidget *save_as_button = NULL, *insert_button = NULL, *mix_button = NULL; static regrow *region_row(int n); static void set_current_region(int rg) { bool reg_ok = false; current_region = rg; reflect_region_in_save_as_dialog(); if (rg >= 0) reg_ok = region_ok(region_list_position_to_id(rg)); if (save_as_button) gtk_widget_set_sensitive(save_as_button, reg_ok); if (mix_button) gtk_widget_set_sensitive(mix_button, reg_ok); if (insert_button) gtk_widget_set_sensitive(insert_button, reg_ok); } void reflect_regions_in_region_browser(void) { if (rsp) { int i; rsp->active = true; if (rsp->chans) for (i = 0; i < rsp->nchans; i++) rsp->chans[i]->active = CHANNEL_HAS_AXES; } } void reflect_no_regions_in_region_browser(void) { if (rsp) { int i; rsp->active = false; if (rsp->chans) for (i = 0; i < rsp->nchans; i++) rsp->chans[i]->active = CHANNEL_INACTIVE; } } static void region_update_graph(chan_info *cp) { if (current_region == -1) return; rsp->nchans = region_chans(region_list_position_to_id(current_region)); if (rsp->nchans == 0) return; update_graph(cp); rsp->nchans = 1; } void reflect_region_graph_style(void) { if (current_region == -1) return; if ((rsp) && (rsp->chans) && (rsp->chans[0]) && (region_dialog_is_active())) { rsp->chans[0]->time_graph_style = region_graph_style(ss); rsp->chans[0]->dot_size = dot_size(ss); /* update_graph(rsp->chans[0]); */ update_region_browser(true); } } static void unhighlight_region(void) { if (current_region != -1) { regrow *oldr; oldr = region_row(current_region); widget_modify_bg(oldr->nm, GTK_STATE_NORMAL, ss->white); widget_modify_base(oldr->nm, GTK_STATE_NORMAL, ss->white); widget_modify_bg(oldr->rw, GTK_STATE_NORMAL, ss->white); widget_modify_base(oldr->rw, GTK_STATE_NORMAL, ss->white); } } static void highlight_region(void) { if (current_region != -1) { regrow *oldr; oldr = region_row(current_region); widget_modify_bg(oldr->nm, GTK_STATE_NORMAL, ss->light_blue); widget_modify_base(oldr->nm, GTK_STATE_NORMAL, ss->light_blue); widget_modify_bg(oldr->rw, GTK_STATE_NORMAL, ss->light_blue); widget_modify_base(oldr->rw, GTK_STATE_NORMAL, ss->light_blue); } } static void make_region_labels(file_info *hdr) { char *str; if (hdr == NULL) return; str = (char *)calloc(PRINT_BUFFER_SIZE, sizeof(char)); snprintf(str, PRINT_BUFFER_SIZE, "srate: %d", hdr->srate); #if (!GTK_CHECK_VERSION(3, 0, 0)) set_label(srate_text, str); #else set_button_label(srate_text, str); #endif snprintf(str, PRINT_BUFFER_SIZE, "chans: %d", hdr->chans); #if (!GTK_CHECK_VERSION(3, 0, 0)) set_label(chans_text, str); #else set_button_label(chans_text, str); #endif snprintf(str, PRINT_BUFFER_SIZE, "length: %.3f", (float)((double)(hdr->samples) / (float)(hdr->chans * hdr->srate))); #if (!GTK_CHECK_VERSION(3, 0, 0)) set_label(length_text, str); #else set_button_label(length_text, str); #endif snprintf(str, PRINT_BUFFER_SIZE, "maxamp: %.3f", region_maxamp(region_list_position_to_id(current_region))); #if (!GTK_CHECK_VERSION(3, 0, 0)) set_label(maxamp_text, str); #else set_button_label(maxamp_text, str); #endif free(str); } int update_region_browser(bool grf_too) { int i, len; region_state *rs; rs = region_report(); len = rs->len; for (i = 0; i < len; i++) { regrow *r; r = region_row(i); set_button_label(r->nm, rs->name[i]); #if WITH_AUDIO set_toggle_button(r->pl, false, false, (void *)r); #endif gtk_widget_show(r->rw); } for (i = len; i < max_regions(ss); i++) if (region_rows[i]) gtk_widget_hide(region_rows[i]->rw); free_region_state(rs); if (len == 0) return(0); gtk_widget_show(region_list); if (grf_too) { chan_info *cp; unhighlight_region(); set_current_region(0); highlight_region(); goto_window(region_rows[0]->nm); cp = rsp->chans[0]; if (cp) { cp->sound = rsp; cp->chan = 0; set_sensitive(channel_f(cp), false); set_sensitive(channel_w(cp), (region_chans(region_list_position_to_id(0)) > 1)); rsp->hdr = fixup_region_data(cp, 0, 0); make_region_labels(rsp->hdr); region_update_graph(cp); } } return(len); } static gint region_browser_delete_callback(GtkWidget *w, GdkEvent *event, gpointer context) { gtk_widget_hide(region_dialog); return(true); } static void region_ok_callback(GtkWidget *w, gpointer context) { gtk_widget_hide(region_dialog); } bool region_browser_is_active(void) { return((region_dialog) && (widget_is_active(region_dialog))); } static gboolean region_resize_callback(GtkWidget *w, GdkEventConfigure *ev, gpointer data) { region_update_graph((chan_info *)data); return(false); } static gboolean region_expose_callback(GtkWidget *w, GdkEventExpose *ev, gpointer data) { region_update_graph((chan_info *)data); return(false); } void delete_region_and_update_browser(int pos) { int act; unhighlight_region(); act = remove_region_from_list(pos); if (act == INVALID_REGION) return; if (region_dialog) { if (act != NO_REGIONS) { set_current_region(0); highlight_region(); goto_window(region_rows[0]->nm); } else set_current_region(-1); update_region_browser(true); } } static void region_insert_callback(GtkWidget *w, gpointer context) { if ((current_region != -1) && (selected_channel())) paste_region(region_list_position_to_id(current_region), selected_channel()); } static void region_mix_callback(GtkWidget *w, gpointer context) { if ((current_region != -1) && (selected_channel())) add_region(region_list_position_to_id(current_region), selected_channel()); } static void region_save_callback(GtkWidget *w, gpointer context) { if (current_region != -1) make_region_save_as_dialog(true); } static void region_help_callback(GtkWidget *w, gpointer context) { region_dialog_help(); } static gboolean region_up_arrow_callback(GtkWidget *w, GdkEventButton *ev, gpointer data) { chan_info *cp; cp = rsp->chans[0]; cp->sound = rsp; if (cp->chan > 0) { cp->chan--; set_sensitive(channel_f(cp), (cp->chan > 0)); set_sensitive(channel_w(cp), true); fixup_region_data(cp, cp->chan, current_region); region_update_graph(cp); } return(false); } static gboolean region_down_arrow_callback(GtkWidget *w, GdkEventButton *ev, gpointer data) { chan_info *cp; cp = rsp->chans[0]; cp->sound = rsp; if ((cp->chan + 1) < region_chans(region_list_position_to_id(current_region))) { cp->chan++; set_sensitive(channel_f(cp), true); set_sensitive(channel_w(cp), (region_chans(region_list_position_to_id(current_region)) > (cp->chan + 1))); fixup_region_data(cp, cp->chan, current_region); region_update_graph(cp); } return(false); } static oclock_t mouse_down_time = 0, ev_mouse_down_time = 0; static gboolean select_event_callback(GtkWidget *w, GdkEventButton *ev, gpointer data) { ev_mouse_down_time = EVENT_TIME(ev); return(false); } static void region_focus_callback(GtkWidget *w, gpointer context) /* button clicked callback */ { chan_info *cp; regrow *r = (regrow *)context; if (mouse_down_time != 0) { if ((ev_mouse_down_time - mouse_down_time) < 200) { mouse_down_time = ev_mouse_down_time; if (current_region != -1) region_edit(current_region); return; } } mouse_down_time = ev_mouse_down_time; unhighlight_region(); if (region_list_position_to_id(r->pos) == INVALID_REGION) return; /* needed by auto-tester */ set_current_region(r->pos); cp = rsp->chans[0]; cp->sound = rsp; cp->chan = 0; highlight_region(); set_sensitive(channel_f(cp), false); set_sensitive(channel_w(cp), (region_chans(region_list_position_to_id(current_region)) > 1)); rsp->hdr = fixup_region_data(cp, 0, current_region); make_region_labels(rsp->hdr); region_update_graph(cp); } void reflect_play_region_stop(int n) { #if WITH_AUDIO if (region_rows) { regrow *rg; rg = region_row(region_id_to_list_position(n)); if (rg) set_toggle_button(rg->pl, false, false, (void *)rg); } #endif } static void region_play_callback(GtkWidget *w, gpointer context) { #if WITH_AUDIO regrow *r = (regrow *)context; if (TOGGLE_BUTTON_ACTIVE(r->pl)) play_region(region_list_position_to_id(r->pos), IN_BACKGROUND); else stop_playing_region(region_list_position_to_id(r->pos), PLAY_BUTTON_UNSET); #endif } static Xen reflect_file_in_region_browser(Xen hook_or_reason) { if (region_dialog) { bool file_on; file_on = (bool)(any_selected_sound()); set_sensitive(mix_button, file_on); set_sensitive(insert_button, file_on); } return(Xen_false); } Xen_wrap_1_arg(reflect_file_in_region_browser_w, reflect_file_in_region_browser) char *regrow_get_label(void *ur) { regrow *r = (regrow *)ur; return((char *)gtk_label_get_text(GTK_LABEL(BIN_CHILD(r->nm)))); } int regrow_get_pos(void *ur) { regrow *r = (regrow *)ur; return(r->pos); } static Xen mouse_enter_label_hook; static Xen mouse_leave_label_hook; static void mouse_enter_or_leave_label(void *r, int type, Xen hook, const char *caller) { if ((r) && (Xen_hook_has_list(hook))) { char *label = NULL; label = regrow_get_label(r); if (label) run_hook(hook, Xen_list_3(C_int_to_Xen_integer(type), C_int_to_Xen_integer(regrow_get_pos(r)), C_string_to_Xen_string(label)), caller); } } static void mouse_leave_label(void *r, int type) { mouse_enter_or_leave_label(r, type, mouse_leave_label_hook, S_mouse_leave_label_hook); } static void mouse_enter_label(void *r, int type) { mouse_enter_or_leave_label(r, type, mouse_enter_label_hook, S_mouse_enter_label_hook); } static gboolean regrow_mouse_enter_label(GtkWidget *w, GdkEventCrossing *ev, gpointer gp) { mouse_enter_label((void *)gp, REGION_VIEWER); return(false); } static gboolean regrow_mouse_leave_label(GtkWidget *w, GdkEventCrossing *ev, gpointer gp) { mouse_leave_label((void *)gp, REGION_VIEWER); return(false); } static regrow *make_regrow(GtkWidget *ww, GCallback play_callback, GCallback name_callback) { regrow *r; r = (regrow *)calloc(1, sizeof(regrow)); /* assume "ww" is a vbox widget in this case */ r->rw = gtk_hbox_new(false, 0); gtk_box_pack_start(GTK_BOX(ww), r->rw, false, false, 0); widget_modify_bg(r->rw, GTK_STATE_NORMAL, ss->white); widget_modify_base(r->rw, GTK_STATE_NORMAL, ss->white); gtk_widget_show(r->rw); #if WITH_AUDIO r->pl = gtk_check_button_new(); gtk_box_pack_start(GTK_BOX(r->rw), r->pl, false, false, 2); SG_SIGNAL_CONNECT(r->pl, "toggled", play_callback, r); gtk_widget_show(r->pl); #endif r->nm = gtk_button_new_with_label(""); widget_modify_bg(r->nm, GTK_STATE_NORMAL, ss->white); widget_modify_base(r->nm, GTK_STATE_NORMAL, ss->white); gtk_button_set_relief(GTK_BUTTON(r->nm), GTK_RELIEF_HALF); sg_left_justify_button(r->nm); gtk_box_pack_start(GTK_BOX(r->rw), r->nm, true, true, 2); add_white_button_style(r->nm); SG_SIGNAL_CONNECT(r->nm, "clicked", name_callback, r); SG_SIGNAL_CONNECT(r->nm, "enter_notify_event", regrow_mouse_enter_label, r); SG_SIGNAL_CONNECT(r->nm, "leave_notify_event", regrow_mouse_leave_label, r); SG_SIGNAL_CONNECT(r->nm, "button_press_event", select_event_callback, NULL); set_user_data(G_OBJECT(r->nm), (gpointer)r); gtk_widget_show(r->nm); return(r); } static bool query_callback(GtkTooltip *tooltip, const char *which) { snd_info *sp; sp = any_selected_sound(); if (sp) { chan_info *cp; cp = any_selected_channel(sp); if (cp) { char *tip; tip = mus_format("%s the selected region at the cursor (at time %.3f) in %s", which, ((double)cursor_sample(cp)) / ((double)(snd_srate(sp))), sp->short_filename); gtk_tooltip_set_text(tooltip, tip); free(tip); return(true); } } if (strcmp(which, "insert") == 0) gtk_tooltip_set_text(tooltip, "if there is an active sound, this inserts the selected region into it at the cursor"); else gtk_tooltip_set_text(tooltip, "if there is an active sound, this mixes the selected region with it starting at the cursor"); return(true); } static gboolean insert_region_tooltip(GtkWidget *w, gint x, gint y, gboolean keyboard_tip, GtkTooltip *tooltip, gpointer data) { return(query_callback(tooltip, "insert")); } static gboolean mix_region_tooltip(GtkWidget *w, gint x, gint y, gboolean keyboard_tip, GtkTooltip *tooltip, gpointer data) { return(query_callback(tooltip, "mix")); } static void make_region_dialog(void) { int i, id, rows; regrow *r; chan_info *cp; GtkWidget *infobox, *labels, *labbox, *dismiss_button, *help_button; GtkWidget *sep1, *cww, *toppane, *tophbox, *formw; #if WITH_AUDIO GtkWidget *plw; #endif region_dialog = snd_gtk_dialog_new(); #if GTK_CHECK_VERSION(3, 14, 0) gtk_window_set_transient_for(GTK_WINDOW(region_dialog), GTK_WINDOW(MAIN_SHELL(ss))); #endif SG_SIGNAL_CONNECT(region_dialog, "delete_event", region_browser_delete_callback, NULL); gtk_window_set_title(GTK_WINDOW(region_dialog), "Regions"); sg_make_resizable(region_dialog); gtk_container_set_border_width(GTK_CONTAINER(region_dialog), 10); gtk_window_resize(GTK_WINDOW(region_dialog), 400, 500); gtk_widget_realize(region_dialog); insert_button = gtk_dialog_add_button(GTK_DIALOG(region_dialog), "Insert", GTK_RESPONSE_NONE); mix_button = gtk_dialog_add_button(GTK_DIALOG(region_dialog), "Mix", GTK_RESPONSE_NONE); save_as_button = gtk_dialog_add_button(GTK_DIALOG(region_dialog), "Save as", GTK_RESPONSE_NONE); dismiss_button = gtk_dialog_add_button(GTK_DIALOG(region_dialog), "Go away", GTK_RESPONSE_NONE); help_button = gtk_dialog_add_button(GTK_DIALOG(region_dialog), "Help", GTK_RESPONSE_NONE); gtk_widget_set_name(help_button, "dialog_button"); gtk_widget_set_name(dismiss_button, "dialog_button"); gtk_widget_set_name(insert_button, "dialog_button"); gtk_widget_set_name(mix_button, "dialog_button"); gtk_widget_set_name(save_as_button, "dialog_button"); #if GTK_CHECK_VERSION(3, 0, 0) add_highlight_button_style(help_button); add_highlight_button_style(dismiss_button); add_highlight_button_style(insert_button); add_highlight_button_style(save_as_button); add_highlight_button_style(mix_button); #endif SG_SIGNAL_CONNECT(insert_button, "clicked", region_insert_callback, NULL); SG_SIGNAL_CONNECT(mix_button, "clicked", region_mix_callback, NULL); SG_SIGNAL_CONNECT(help_button, "clicked", region_help_callback, NULL); SG_SIGNAL_CONNECT(dismiss_button, "clicked", region_ok_callback, NULL); SG_SIGNAL_CONNECT(save_as_button, "clicked", region_save_callback, NULL); add_tooltip(insert_button, "insert the selected region"); add_tooltip(mix_button, "mix the selected region"); add_tooltip(save_as_button, "save the selected region to a file"); g_signal_connect(insert_button, "query-tooltip", G_CALLBACK(insert_region_tooltip), NULL); g_signal_connect(mix_button, "query-tooltip", G_CALLBACK(mix_region_tooltip), NULL); gtk_widget_show(insert_button); gtk_widget_show(mix_button); gtk_widget_show(help_button); gtk_widget_show(dismiss_button); gtk_widget_show(save_as_button); region_grf = gtk_vpaned_new(); add_paned_style(region_grf); gtk_box_pack_start(GTK_BOX(DIALOG_CONTENT_AREA(region_dialog)), region_grf, true, true, 0); gtk_widget_show(region_grf); toppane = gtk_hbox_new(false, 0); gtk_paned_add1(GTK_PANED(region_grf), toppane); gtk_widget_show(toppane); formw = gtk_vbox_new(false, 0); gtk_box_pack_start(GTK_BOX(toppane), formw, true, true, 4); gtk_widget_show(formw); sep1 = gtk_vseparator_new(); /* not hsep -- damned thing insists on drawing a line */ gtk_box_pack_start(GTK_BOX(formw), sep1, false, false, 2); gtk_widget_show(sep1); tophbox = gtk_hbox_new(false, 0); gtk_box_pack_start(GTK_BOX(formw), tophbox, false, false, 4); gtk_widget_show(tophbox); #if WITH_AUDIO #if (!GTK_CHECK_VERSION(3, 0, 0)) plw = gtk_label_new("play"); #else plw = gtk_button_new_with_label("play"); add_highlight_button_style(plw); #endif gtk_box_pack_start(GTK_BOX(tophbox), plw, false, false, 2); gtk_widget_show(plw); #endif sep1 = gtk_vseparator_new(); gtk_box_pack_start(GTK_BOX(formw), sep1, false, false, 2); gtk_widget_show(sep1); region_list = gtk_vbox_new(false, 0); cww = gtk_scrolled_window_new(NULL, NULL); gtk_box_pack_start(GTK_BOX(formw), cww, true, true, 0); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(cww), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); #if HAVE_GTK_HEADER_BAR_NEW gtk_container_add(GTK_CONTAINER(cww), region_list); #else gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(cww), region_list); #endif gtk_widget_show(region_list); gtk_widget_show(cww); sep1 = gtk_hseparator_new(); gtk_box_pack_end(GTK_BOX(formw), sep1, false, false, 2); gtk_widget_show(sep1); infobox = gtk_vbox_new(false, 0); gtk_box_pack_start(GTK_BOX(toppane), infobox, false, false, 2); gtk_widget_show(infobox); region_rows = (regrow **)calloc(max_regions(ss), sizeof(regrow *)); region_rows_size = max_regions(ss); for (i = 0; i < max_regions(ss); i++) { r = make_regrow(region_list, (void (*)())region_play_callback, (void (*)())region_focus_callback); region_rows[i] = r; r->pos = i; } rows = update_region_browser(false); if (rows > 10) rows = 10; /* in Gtk, apparently, labels are just the text, not the background (i.e. they're transparent) */ /* we need a button simply to get the background color, then a vbox to put four labels on the button */ /* but we get a button which flashes whenever the mouse comes near it and has "relief" */ /* if we turn off the relief, the colors go away */ /* all I want is an opaque label with a background color */ labels = gtk_event_box_new(); gtk_box_pack_start(GTK_BOX(infobox), labels, true, true, 2); gtk_widget_show(labels); widget_modify_bg(labels, GTK_STATE_NORMAL, ss->highlight_color); /* SG_SIGNAL_CONNECT(labels, "enter_notify_event", region_labels_mouse_enter, NULL); */ labbox = gtk_vbox_new(true, 0); gtk_container_add(GTK_CONTAINER(labels), labbox); gtk_widget_show(labbox); widget_modify_bg(labbox, GTK_STATE_NORMAL, ss->highlight_color); #if (!GTK_CHECK_VERSION(3, 0, 0)) srate_text = gtk_label_new("srate:"); sg_left_justify_label(srate_text); #else srate_text = gtk_button_new_with_label("srate:"); add_highlight_button_style(srate_text); sg_left_justify_button(srate_text); #endif gtk_box_pack_start(GTK_BOX(labbox), srate_text, false, false, 2); gtk_widget_show(srate_text); #if (!GTK_CHECK_VERSION(3, 0, 0)) chans_text = gtk_label_new("chans:"); sg_left_justify_label(chans_text); #else chans_text = gtk_button_new_with_label("chans:"); add_highlight_button_style(chans_text); sg_left_justify_button(chans_text); #endif gtk_box_pack_start(GTK_BOX(labbox), chans_text, false, false, 2); gtk_widget_show(chans_text); #if (!GTK_CHECK_VERSION(3, 0, 0)) length_text = gtk_label_new("length:"); sg_left_justify_label(length_text); #else length_text = gtk_button_new_with_label("length:"); add_highlight_button_style(length_text); sg_left_justify_button(length_text); #endif gtk_box_pack_start(GTK_BOX(labbox), length_text, false, false, 2); gtk_widget_show(length_text); #if (!GTK_CHECK_VERSION(3, 0, 0)) maxamp_text = gtk_label_new("maxamp:"); sg_left_justify_label(maxamp_text); #else maxamp_text = gtk_button_new_with_label("maxamp:"); add_highlight_button_style(maxamp_text); sg_left_justify_button(maxamp_text); #endif gtk_box_pack_start(GTK_BOX(labbox), maxamp_text, false, false, 2); gtk_widget_show(maxamp_text); gtk_widget_show(region_dialog); id = region_list_position_to_id(0); rsp = make_simple_channel_display(region_srate(id), region_len(id), WITH_ARROWS, region_graph_style(ss), region_grf, WITHOUT_EVENTS); rsp->inuse = SOUND_REGION; set_current_region(0); cp = rsp->chans[0]; gtk_paned_set_position(GTK_PANED(region_grf), (gint)floor(100 + rows * 14)); SG_SIGNAL_CONNECT(channel_graph(cp), DRAW_SIGNAL, region_resize_callback, cp); SG_SIGNAL_CONNECT(channel_graph(cp), "configure_event", region_expose_callback, cp); SG_SIGNAL_CONNECT(channel_up_arrow(cp), "button_press_event", region_up_arrow_callback, NULL); SG_SIGNAL_CONNECT(channel_down_arrow(cp), "button_press_event", region_down_arrow_callback, NULL); set_sensitive(channel_f(cp), false); set_sensitive(channel_w(cp), (region_chans(region_list_position_to_id(0)) > 1)); add_tooltip(channel_f(cp), "move the graph to the previous channel"); add_tooltip(channel_w(cp), "move the graph to the next channel"); cp->chan = 0; rsp->hdr = fixup_region_data(cp, 0, 0); make_region_labels(rsp->hdr); highlight_region(); region_update_graph(cp); Xen_add_to_hook_list(ss->snd_open_file_hook, reflect_file_in_region_browser_w, "region-dialog-open-file-watcher", "region dialog open-file-hook handler"); set_dialog_widget(REGION_DIALOG, region_dialog); } void view_region_callback(GtkWidget *w, gpointer context) { /* put up scrollable dialog describing/playing/editing the region list */ if (region_dialog == NULL) make_region_dialog(); else { update_region_browser(true); raise_dialog(region_dialog); set_current_region(0); } } bool region_dialog_is_active(void) { return((region_dialog != NULL) && (widget_is_active(region_dialog))); } void allocate_region_rows(int n) { if ((region_dialog) && (n > region_rows_size)) { int i; region_rows = (regrow **)realloc(region_rows, n * sizeof(regrow *)); for (i = region_rows_size; i < n; i++) region_rows[i] = NULL; region_rows_size = n; } } static regrow *region_row(int n) { if (n < region_rows_size) { if (region_rows[n] == NULL) { regrow *r; r = make_regrow(region_list, (void (*)())region_play_callback, (void (*)())region_focus_callback); region_rows[n] = r; r->pos = n; } return(region_rows[n]); } return(NULL); } int region_dialog_region(void) { return(region_list_position_to_id(current_region)); } static Xen g_view_regions_dialog(void) { #define H_view_regions_dialog "(" S_view_regions_dialog "): start the region dialog" if (snd_regions() > 0) view_region_callback(MAIN_PANE(ss), NULL); return(Xen_wrap_widget(region_dialog)); } Xen_wrap_no_args(g_view_regions_dialog_w, g_view_regions_dialog) void g_init_gxregion(void) { Xen_define_procedure(S_view_regions_dialog, g_view_regions_dialog_w, 0, 0, 0, H_view_regions_dialog); #if HAVE_SCHEME #define H_mouse_enter_label_hook S_mouse_enter_label_hook " (type position label): called when the mouse enters a file viewer or region label. \ The 'type' is 1 for view-files, and 2 for regions. The 'position' \ is the scrolled list position of the label. The label itself is 'label'. We could use the 'finfo' procedure in examp.scm \ to popup file info as follows: \n\ (hook-push " S_mouse_enter_label_hook "\n\ (lambda (type position name)\n\ (if (not (= type 2))\n\ (" S_info_dialog " name (finfo name)))))\n\ See also nb.scm." #endif #if HAVE_RUBY #define H_mouse_enter_label_hook S_mouse_enter_label_hook " (type position label): called when the mouse enters a file viewer or region label. \ The 'type' is 1 for view-files, and 2 for regions. The 'position' \ is the scrolled list position of the label. The label itself is 'label'. We could use the 'finfo' procedure in examp.rb \ to popup file info as follows: \n\ $mouse_enter_label_hook.add_hook!(\"finfo\") do |type, position, name|\n\ if type != 2\n\ " S_info_dialog "(name, finfo(name))\n\ end\n\ end\n\ See also nb.rb." #endif #if HAVE_FORTH #define H_mouse_enter_label_hook S_mouse_enter_label_hook " (type position label): called when the mouse enters a file viewer or region label. \ The 'type' is 1 for view-files, and 2 for regions. The 'position' \ is the scrolled list position of the label. The label itself is 'label'. We could use the 'finfo' procedure in examp.fs \ to popup file info as follows: \n\ " S_mouse_enter_label_hook " lambda: <{ type position name }>\n\ type 2 <> if\n\ name name finfo info-dialog\n\ else\n\ #f\n\ then\n\ ; add-hook!" #endif #define H_mouse_leave_label_hook S_mouse_leave_label_hook " (type position label): called when the mouse leaves a file viewer or region label" mouse_enter_label_hook = Xen_define_hook(S_mouse_enter_label_hook, "(make-hook 'type 'position 'label)", 3, H_mouse_enter_label_hook); mouse_leave_label_hook = Xen_define_hook(S_mouse_leave_label_hook, "(make-hook 'type 'position 'label)", 3, H_mouse_leave_label_hook); } /* simple view-files replacement */ #include "snd-file.h" GtkWidget *view_files_dialog = NULL; static gint vf_delete_callback(GtkWidget *w, GdkEvent *event, gpointer context) { gtk_widget_hide(view_files_dialog); return(true); } static void vf_ok_callback(GtkWidget *w, gpointer context) { gtk_widget_hide(view_files_dialog); } static void vf_help_callback(GtkWidget *w, gpointer context) { view_files_dialog_help(); } static char **vf_names, **vf_full_names; static int vf_names_size = 0; static regrow **vf_rows = NULL; static snd_info *vf_play_sp = NULL; static bool view_files_play(int pos, bool play) { if (play) { if (vf_play_sp) { if (vf_play_sp->playing) return(true); /* can't play two of these at once */ if (strcmp(vf_play_sp->short_filename, vf_names[pos]) != 0) { completely_free_snd_info(vf_play_sp); vf_play_sp = NULL; } } if ((!vf_play_sp) && (vf_full_names[pos])) vf_play_sp = make_sound_readable(vf_full_names[pos], false); if (vf_play_sp) { vf_play_sp->short_filename = vf_names[pos]; vf_play_sp->filename = NULL; play_sound(vf_play_sp, 0, NO_END_SPECIFIED); } else return(true); /* can't find or setup file */ } else { /* play toggled off */ if ((vf_play_sp) && (vf_play_sp->playing)) { stop_playing_sound(vf_play_sp, PLAY_BUTTON_UNSET); } } return(false); } void view_files_unplay(void) { int i; for (i = 0; i < vf_names_size; i++) if (TOGGLE_BUTTON_ACTIVE(vf_rows[i]->pl)) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(vf_rows[i]->pl), false); } static void vf_focus_callback(GtkWidget *w, gpointer context) {} static void vf_play_callback(GtkWidget *w, gpointer context) { regrow *r = (regrow *)context; view_files_play(r->pos, TOGGLE_BUTTON_ACTIVE(r->pl)); } static int sort_a_to_z(const void *a, const void *b) { sort_info *d1 = *(sort_info **)a; sort_info *d2 = *(sort_info **)b; return(strcmp(d1->filename, d2->filename)); } static void vf_sort(void) { sort_info **data; int i; data = (sort_info **)calloc(vf_names_size, sizeof(sort_info *)); for (i = 0; i < vf_names_size; i++) { data[i] = (sort_info *)calloc(1, sizeof(sort_info)); data[i]->filename = vf_names[i]; data[i]->full_filename = vf_full_names[i]; } qsort((void *)data, vf_names_size, sizeof(sort_info *), sort_a_to_z); for (i = 0; i < vf_names_size; i++) { vf_names[i] = data[i]->filename; vf_full_names[i] = data[i]->full_filename; free(data[i]); } free(data); } void view_files_add_directory(widget_t dialog, const char *dirname) { dir_info *sound_files = NULL; if ((dirname) && (dirname[strlen(dirname) - 1] != '/')) { char *add_slash; add_slash = mus_format("%s/", dirname); sound_files = find_sound_files_in_dir(add_slash); free(add_slash); } else sound_files = find_sound_files_in_dir(dirname); if ((sound_files) && (sound_files->len > 0)) { int i; vf_names_size = sound_files->len; vf_names = (char **)calloc(vf_names_size, sizeof(char *)); vf_full_names = (char **)calloc(vf_names_size, sizeof(char *)); vf_rows = (regrow **)calloc(vf_names_size, sizeof(regrow *)); for (i = 0; i < sound_files->len; i++) { vf_names[i] = mus_strdup(sound_files->files[i]->filename); vf_full_names[i] = mus_strdup(sound_files->files[i]->full_filename); } sound_files = free_dir_info(sound_files); vf_sort(); } } bool view_files_has_files(void) { return(vf_names_size > 0); } void view_files_callback(GtkWidget *w, gpointer info) { if (!view_files_dialog) { int i; regrow *r; GtkWidget *dismiss_button, *help_button, *vf_list; GtkWidget *sep1, *cww, *tophbox, *formw; #if WITH_AUDIO GtkWidget *plw; #endif view_files_dialog = snd_gtk_dialog_new(); #if GTK_CHECK_VERSION(3, 14, 0) gtk_window_set_transient_for(GTK_WINDOW(view_files_dialog), GTK_WINDOW(MAIN_SHELL(ss))); #endif SG_SIGNAL_CONNECT(view_files_dialog, "delete_event", vf_delete_callback, NULL); gtk_window_set_title(GTK_WINDOW(view_files_dialog), "Files"); sg_make_resizable(view_files_dialog); gtk_container_set_border_width(GTK_CONTAINER(view_files_dialog), 10); gtk_window_resize(GTK_WINDOW(view_files_dialog), 300, 500); gtk_widget_realize(view_files_dialog); dismiss_button = gtk_dialog_add_button(GTK_DIALOG(view_files_dialog), "Go away", GTK_RESPONSE_NONE); help_button = gtk_dialog_add_button(GTK_DIALOG(view_files_dialog), "Help", GTK_RESPONSE_NONE); gtk_widget_set_name(help_button, "dialog_button"); gtk_widget_set_name(dismiss_button, "dialog_button"); #if GTK_CHECK_VERSION(3, 0, 0) add_highlight_button_style(help_button); add_highlight_button_style(dismiss_button); #endif SG_SIGNAL_CONNECT(help_button, "clicked", vf_help_callback, NULL); SG_SIGNAL_CONNECT(dismiss_button, "clicked", vf_ok_callback, NULL); gtk_widget_show(help_button); gtk_widget_show(dismiss_button); formw = gtk_vbox_new(false, 0); gtk_box_pack_start(GTK_BOX(DIALOG_CONTENT_AREA(view_files_dialog)), formw, true, true, 0); gtk_widget_show(formw); sep1 = gtk_vseparator_new(); /* not hsep -- damned thing insists on drawing a line */ gtk_box_pack_start(GTK_BOX(formw), sep1, false, false, 2); gtk_widget_show(sep1); tophbox = gtk_hbox_new(false, 0); gtk_box_pack_start(GTK_BOX(formw), tophbox, false, false, 4); gtk_widget_show(tophbox); #if WITH_AUDIO #if (!GTK_CHECK_VERSION(3, 0, 0)) plw = gtk_label_new("play"); #else plw = gtk_button_new_with_label("play"); add_highlight_button_style(plw); #endif gtk_box_pack_start(GTK_BOX(tophbox), plw, false, false, 2); gtk_widget_show(plw); #endif sep1 = gtk_vseparator_new(); gtk_box_pack_start(GTK_BOX(formw), sep1, false, false, 2); gtk_widget_show(sep1); vf_list = gtk_vbox_new(false, 0); cww = gtk_scrolled_window_new(NULL, NULL); gtk_box_pack_start(GTK_BOX(formw), cww, true, true, 0); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(cww), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); #if HAVE_GTK_HEADER_BAR_NEW gtk_container_add(GTK_CONTAINER(cww), vf_list); #else gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(cww), vf_list); #endif gtk_widget_show(vf_list); gtk_widget_show(cww); for (i = 0; i < vf_names_size; i++) { r = make_regrow(vf_list, (void (*)())vf_play_callback, (void (*)())vf_focus_callback); vf_rows[i] = r; r->pos = i; set_button_label(r->nm, vf_names[i]); } gtk_widget_show(view_files_dialog); set_dialog_widget(VIEW_FILES_DIALOG, view_files_dialog); } else { raise_dialog(view_files_dialog); } } snd-16.1/libm.scm0000644000076400007640000001272212565750454012003 0ustar bilbil;;; libm.scm ;;; ;;; tie the math library into the *libm* environment (require cload.scm) (provide 'libm.scm) ;; if loading from a different directory, pass that info to C (let ((current-file (port-filename (current-input-port)))) (let ((directory (and (or (char=? (current-file 0) #\/) (char=? (current-file 0) #\~)) (substring current-file 0 (- (length current-file) 9))))) (when (and directory (not (member directory *load-path*))) (set! *load-path* (cons directory *load-path*))) (with-let (rootlet) (require cload.scm)) (when (and directory (not (string-position directory *cload-cflags*))) (set! *cload-cflags* (string-append "-I" directory " " *cload-cflags*))))) (if (not (defined? '*libm*)) (define *libm* (with-let (unlet) (set! *libraries* (cons (cons "libm.scm" (curlet)) *libraries*)) (c-define '((double j0 (double) "Bessel j0") (double j1 (double)) (double erf (double)) (double erfc (double)) (double lgamma (double)) (double fabs (double)) (double ceil (double)) (reader-cond ((not (provided? 'netbsd)) (double nearbyint (double)) (double scalbln (double int)) (double fma (double double double)))) (double rint (double)) (int llrint (double)) (int llround (double)) (double trunc (double)) (double fmod (double double)) (double ldexp (double int)) (double scalbn (double int)) (double exp2 (double)) (double expm1 (double)) (double log10 (double)) (double log1p (double)) (double log2 (double)) (int ilogb (double)) (double cbrt (double)) (double hypot (double double)) (double pow (double double)) (double fdim (double double)) (double tgamma (double)) (double copysign (double double)) (double nan (char*)) (double nextafter (double double)) (double nexttoward (double double)) (reader-cond ((not (provided? 'solaris)) (int fpclassify (double)) (int isfinite (double)) (int isinf (double)) (int isnan (double)) (int isnormal (double)) (int signbit (double)))) ;; exporting these will overwrite the built-in versions (double floor (double)) (double round (double)) (double remainder (double double)) (double exp (double)) (double log (double)) (double sqrt (double)) (double cos (double)) (double sin (double)) (double tan (double)) (double cosh (double)) (double sinh (double)) (double tanh (double)) (double acos (double)) (double asin (double)) (double atan (double)) (double atan2 (double double)) (double acosh (double)) (double asinh (double)) (double atanh (double)) (int (FP_NAN FP_INFINITE FP_ZERO FP_SUBNORMAL FP_NORMAL)) (double (M_E M_LOG2E M_LOG10E M_LN2 M_LN10 M_PI M_PI_2 M_PI_4 M_1_PI M_2_PI M_2_SQRTPI M_SQRT2 M_SQRT1_2)) (C-macro (char* __VERSION__)) (C-macro (int (__SIZEOF_LONG_LONG__ __SIZEOF_INT__ __SIZEOF_POINTER__ __SIZEOF_LONG__ __SIZEOF_LONG_DOUBLE__ __SIZEOF_SIZE_T__ __SIZEOF_FLOAT__ __SIZEOF_SHORT__ __SIZEOF_DOUBLE__ __CHAR_BIT__ __DBL_MIN_EXP__ __DBL_MIN_10_EXP__ __LDBL_MAX_EXP__ __DBL_DIG__ __DECIMAL_DIG__ __BIGGEST_ALIGNMENT__ __DBL_MAX_EXP__ __LONG_LONG_MAX__ __FLT_MIN_EXP__ __FLT_MANT_DIG__ __FLT_RADIX__ __FLT_MAX_10_EXP__ __LONG_MAX__ __LDBL_MANT_DIG__ __FLT_DIG__ __INT_MAX__ __FLT_MAX_EXP__ __DBL_MANT_DIG__ __LDBL_MIN_EXP__ __LDBL_MAX_10_EXP__ __INTMAX_MAX__ __FLT_MIN_10_EXP__ __DBL_MAX_10_EXP__ __LDBL_MIN_10_EXP__ __LDBL_DIG__))) (C-macro (double (__FLT_MIN__ __DBL_DENORM_MIN__ __LDBL_MAX__ __FLT_EPSILON__ __LDBL_MIN__ __DBL_MAX__ __DBL_MIN__ __LDBL_EPSILON__ __DBL_EPSILON__ __FLT_DENORM_MIN__ __FLT_MAX__ __LDBL_DENORM_MIN__))) ;; these have arg by reference, return list in s7 (in-C " static s7_pointer g_remquo(s7_scheme *sc, s7_pointer args) { if (s7_is_real(s7_car(args))) { if (s7_is_real(s7_cadr(args))) { int quo = 0; double rem; rem = remquo(s7_number_to_real(sc, s7_car(args)), s7_number_to_real(sc, s7_cadr(args)), &quo); return(s7_list(sc, 2, s7_make_real(sc, rem), s7_make_integer(sc, quo))); } return(s7_wrong_type_arg_error(sc, \"remquo\", 2, s7_cadr(args), \"a real\")); } return(s7_wrong_type_arg_error(sc, \"remquo\", 1, s7_car(args), \"a real\")); } static s7_pointer g_frexp(s7_scheme *sc, s7_pointer args) { if (s7_is_real(s7_car(args))) { int ex = 0; double frac; frac = frexp(s7_number_to_real(sc, s7_car(args)), &ex); return(s7_list(sc, 2, s7_make_real(sc, frac), s7_make_integer(sc, ex))); } return(s7_wrong_type_arg_error(sc, \"frexp\", 1, s7_car(args), \"a real\")); } static s7_pointer g_modf(s7_scheme *sc, s7_pointer args) { if (s7_is_real(s7_car(args))) { double frac, ip = 0.0; frac = modf(s7_number_to_real(sc, s7_car(args)), &ip); return(s7_list(sc, 2, s7_make_real(sc, frac), s7_make_real(sc, ip))); } return(s7_wrong_type_arg_error(sc, \"modf\", 1, s7_car(args), \"a real\")); } ") (C-function ("remquo" g_remquo "(remquo x y) returns a list: (remainder messed-up-quotient)" 2)) (C-function ("frexp" g_frexp "(frexp x) returns a list: (fraction exponent)" 1)) (C-function ("modf" g_modf "(modf x) returns a list: (int-part frac-part) -- this is not the same as fmod!" 1)) ) "" "math.h" "" "" "libm_s7") (curlet)))) *libm* ;; the loader will return *libm* snd-16.1/snd-xref.c0000644000076400007640000124104212620215651012231 0ustar bilbil/* Snd help index (generated by make-index.scm) */ #define HELP_NAMES_SIZE 1602 #if HAVE_SCHEME || HAVE_FORTH static const char *help_names[HELP_NAMES_SIZE] = { "*#readers*", "->byte-vector", "abcos", "abcos?", "abort", "absin", "absin?", "add-amp-controls", "add-colormap", "add-delete-option", "add-directory-to-view-files-list", "add-file-filter", "add-file-sorter", "add-file-to-view-files-list", "add-mark", "add-mark-pane", "add-player", "add-sound-file-extension", "add-source-file-extension", "add-to-main-menu", "add-to-menu", "add-tooltip", "add-transform", "additive synthesis", "adjustable-sawtooth-wave", "adjustable-sawtooth-wave?", "adjustable-square-wave", "adjustable-square-wave?", "adjustable-triangle-wave", "adjustable-triangle-wave?", "after-apply-controls-hook", "after-edit-hook", "after-graph-hook", "after-lisp-graph-hook", "after-open-hook", "after-save-as-hook", "after-save-state-hook", "after-transform-hook", "all-chans", "all-pass", "all-pass-bank", "all-pass-bank?", "all-pass?", "amp-control", "amp-control-bounds", "amplitude-modulate", "analyse-ladspa", "anoi", "any-env-channel", "any-random", "apply-controls", "apply-ladspa", "aritable?", "arity", "array->file", "array-interp", "as-one-edit", "ask-about-unsaved-edits", "ask-before-overwrite", "asyfm-I", "asyfm-J", "asyfm?", "asymmetric-fm", "asymmetric-fm?", "auto-resize", "auto-save", "auto-update", "auto-update-interval", "autocorrelate", "axis-color", "axis-info", "axis-label-font", "axis-numbers-font", "background-gradient", "bad-header-hook", "bagpipe", "basic-color", "beats-per-measure", "beats-per-minute", "before-close-hook", "before-exit-hook", "before-save-as-hook", "before-save-state-hook", "before-transform-hook", "bes-j0", "bess", "bess?", "bessel filters", "bigbird", "bignum", "bignum?", "binary files", "bind-key", "bird", "blackman", "blackman4-env-channel", "blackman?", "bold-peaks-font", "break", "brown-noise", "brown-noise?", "butterworth filters", "byte-vector", "byte-vector?", "c-define", "c-g?", "c-object?", "c-pointer", "c-pointer?", "call-with-exit", "canter", "cascade->canonical", "catch", "cellon", "chain-dsps", "channel->vct", "channel-amp-envs", "channel-data", "channel-envelope", "channel-polynomial", "channel-properties", "channel-property", "channel-rms", "channel-style", "channel-sync", "channel-widgets", "channels", "channels-equal?", "channels=?", "chans", "char-position", "cheby-hka", "chebyshev filters", "check-mix-tags", "chordalize", "chorus", "clean-channel", "clean-sound", "clear-listener", "clip-hook", "clipping", "clm-channel", "clm-expsrc", "close-hook", "close-sound", "color->list", "color-cutoff", "color-hook", "color-inverted", "color-mixes", "color-orientation-dialog", "color-scale", "color?", "colormap", "colormap->integer", "colormap-name", "colormap-ref", "colormap-size", "colormap?", "comb", "comb-bank", "comb-bank?", "comb?", "combined-data-color", "comment", "complexify", "compute-uniform-circular-string", "concatenate-envelopes", "constant?", "continuation?", "continue-frample->file", "continue-sample->file", "contrast-channel", "contrast-control", "contrast-control-amp", "contrast-control-bounds", "contrast-control?", "contrast-enhancement", "contrast-sound", "controls->channel", "convolution", "convolution reverb", "convolve", "convolve-files", "convolve-selection-with", "convolve-with", "convolve?", "copy", "copy-context", "copy-sampler", "correlate", "coverlet", "cross-fade (amplitude)", "cross-fade (frequency domain)", "cross-synthesis", "curlet", "current-font", "cursor", "cursor-color", "cursor-context", "cursor-location-offset", "cursor-position", "cursor-size", "cursor-style", "cursor-update-interval", "cutlet", "cyclic-sequences", "dac-combines-channels", "dac-size", "data-color", "data-location", "data-size", "db->linear", "default-output-chans", "default-output-header-type", "default-output-sample-type", "default-output-srate", "defgenerator", "define*", "define-constant", "define-envelope", "define-expansion", "define-macro", "define-macro*", "define-selection-via-marks", "defined?", "degrees->radians", "delay", "delay-channel-mixes", "delay-tick", "delay?", "delete-colormap", "delete-file-filter", "delete-file-sorter", "delete-mark", "delete-marks", "delete-sample", "delete-samples", "delete-samples-and-smooth", "delete-selection", "delete-selection-and-smooth", "delete-transform", "describe-hook", "describe-mark", "dht", "dialog-widgets", "dilambda", "disable-control-panel", "display-bark-fft", "display-correlation", "display-db", "display-edits", "display-energy", "dissolve-fade", "dither-channel", "dither-sound", "dolph", "dot-product", "dot-size", "down-oct", "draw-axes", "draw-dot", "draw-dots", "draw-line", "draw-lines", "draw-mark-hook", "draw-mix-hook", "draw-string", "drone", "drop sites", "drop-hook", "during-open-hook", "edit-fragment", "edit-header-dialog", "edit-hook", "edit-list->function", "edit-position", "edit-properties", "edit-property", "edit-tree", "edits", "edot-product", "effects-hook", "elliptic filters", "env", "env-any", "env-channel", "env-channel-with-base", "env-expt-channel", "env-interp", "env-mixes", "env-selection", "env-sound", "env-sound-interp", "env-squared-channel", "env?", "enved-base", "enved-clip?", "enved-dialog", "enved-envelope", "enved-filter", "enved-filter-order", "enved-hook", "enved-in-dB", "enved-power", "enved-style", "enved-target", "enved-wave?", "enved-waveform-color", "envelope-interp", "enveloped-mix", "eoddcos", "eoddcos?", "eps-bottom-margin", "eps-file", "eps-left-margin", "eps-size", "ercos", "ercos?", "*error-hook*", "erssb", "erssb?", "even-multiple", "even-weight", "every-sample?", "exit", "exit-hook", "expand-control", "expand-control-bounds", "expand-control-hop", "expand-control-jitter", "expand-control-length", "expand-control-ramp", "expand-control?", "explode-sf2", "exponentially-weighted-moving-average", "expsnd", "expsrc", "*features*", "feedback fm", "fft", "fft-cancel", "fft-edit", "fft-env-edit", "fft-env-interp", "fft-log-frequency", "fft-log-magnitude", "fft-smoother", "fft-squelch", "fft-window", "fft-window-alpha", "fft-window-beta", "fft-with-phases", "file database", "file->array", "file->frample", "file->frample?", "file->sample", "file->sample?", "file-name", "fill!", "fill-polygon", "fill-rectangle", "filter", "filter-channel", "filter-control-coeffs", "filter-control-envelope", "filter-control-in-dB", "filter-control-in-hz", "filter-control-order", "filter-control-waveform-color", "filter-control?", "filter-fft", "filter-selection", "filter-selection-and-smooth", "filter-sound", "filter?", "filtered-comb", "filtered-comb-bank", "filtered-comb-bank?", "filtered-comb?", "find-dialog", "find-mark", "find-mix", "find-sound", "finfo", "finish-progress-report", "fir-filter", "fir-filter?", "firmant", "firmant?", "fit-selection-between-marks", "flatten-partials", "float-vector", "float-vector*", "float-vector+", "float-vector->channel", "float-vector->list", "float-vector->string", "float-vector-abs!", "float-vector-add!", "float-vector-copy", "float-vector-equal?", "float-vector-fill!", "float-vector-length", "float-vector-max", "float-vector-min", "float-vector-move!", "float-vector-multiply!", "float-vector-offset!", "float-vector-peak", "float-vector-polynomial", "float-vector-ref", "float-vector-reverse!", "float-vector-scale!", "float-vector-set!", "float-vector-subseq", "float-vector-subtract!", "float-vector?", "flocsig", "flocsig?", "flute model", "fm-bell", "fm-drum", "fm-noise", "fm-parallel-component", "fm-talker", "fm-trumpet", "fm-violin", "fm-voice", "fmssb", "fmssb?", "focus-widget", "FOF synthesis", "fofins", "for-each-child", "for-each-sound-file", "Forbidden Planet", "foreground-color", "forget-region", "formant", "formant-bank", "formant-bank?", "formant?", "format", "fp", "fractional-fourier-transform", "frample->file", "frample->file?", "frample->frample", "framples", "free-player", "free-sampler", "freeverb", "fullmix", "funclet", "gaussian-distribution", "gc-off", "gc-on", "gensym", "gensym?", "gl-graph->ps", "glSpectrogram", "goertzel", "goto-listener-end", "grani", "granulate", "granulate?", "granulated-sound-interp", "graph", "graph->ps", "graph-color", "graph-cursor", "graph-data", "graph-hook", "graph-style", "graphic equalizer", "graphs-horizontal", "green-noise", "green-noise-interp", "green-noise-interp?", "green-noise?", "grid-density", "harmonicizer", "Hartley transform", "hash-table", "hash-table*", "hash-table-entries", "hash-table-ref", "hash-table-set!", "hash-table?", "header-type", "hello-dentist", "help-dialog", "help-hook", "hide-widget", "highlight-color", "hilbert-transform", "hook-functions", "hook-member", "html", "html-dir", "html-program", "hz->radians", "iir-filter", "iir-filter?", "in", "in-any", "ina", "inb", "info-dialog", "init-ladspa", "initial-beg", "initial-dur", "initial-graph-hook", "inlet", "insert-channel", "insert-file-dialog", "insert-region", "insert-sample", "insert-samples", "insert-selection", "insert-silence", "insert-sound", "int-vector", "int-vector-ref", "int-vector-set!", "int-vector?", "integer->colormap", "integer->mark", "integer->mix", "integer->region", "integer->sound", "integer->transform", "integrate-envelope", "invert-filter", "iterate", "iterator-at-end?", "iterator-sequence", "iterator?", "izcos", "izcos?", "j0evencos", "j0evencos?", "j0j1cos", "j0j1cos?", "j2cos", "j2cos?", "jc-reverb", "jjcos", "jjcos?", "jncos", "jncos?", "jpcos", "jpcos?", "just-sounds", "jycos", "jycos?", "k2cos", "k2cos?", "k2sin", "k2sin?", "k2ssb", "k2ssb?", "k3sin", "k3sin?", "kalman-filter-channel", "key", "key-binding", "key-press-hook", "krksin", "krksin?", "ladspa-descriptor", "ladspa-dir", "lambda*", "lbj-piano", "left-sample", "let->list", "let-ref", "let-set!", "let?", "linear->db", "linear-src-channel", "lint for scheme", "lisp-graph-hook", "lisp-graph-style", "lisp-graph?", "list->float-vector", "list->vct", "list-ladspa", "listener-click-hook", "listener-color", "listener-colorized", "listener-font", "listener-prompt", "listener-selection", "listener-text-color", "little-endian?", "*load-hook*", "*load-path*", "locate-zero", "locsig", "locsig-ref", "locsig-reverb-ref", "locsig-reverb-set!", "locsig-set!", "locsig-type", "locsig?", "log-freq-start", "lpc-coeffs", "lpc-predict", "macro?", "macroexpand", "main-menu", "main-widgets", "make-abcos", "make-absin", "make-adjustable-sawtooth-wave", "make-adjustable-square-wave", "make-adjustable-triangle-wave", "make-all-pass", "make-all-pass-bank", "make-asyfm", "make-asymmetric-fm", "make-bandpass", "make-bandstop", "make-bess", "make-biquad", "make-birds", "make-blackman", "make-brown-noise", "make-byte-vector", "make-channel-drop-site", "make-color", "make-comb", "make-comb-bank", "make-convolve", "make-delay", "make-differentiator", "make-env", "make-eoddcos", "make-ercos", "make-erssb", "make-fft-window", "make-file->frample", "make-file->sample", "make-filter", "make-filtered-comb", "make-filtered-comb-bank", "make-fir-coeffs", "make-fir-filter", "make-firmant", "make-float-vector", "make-flocsig", "make-fmssb", "make-formant", "make-formant-bank", "make-frample->file", "make-granulate", "make-graph-data", "make-green-noise", "make-green-noise-interp", "make-hash-table", "make-highpass", "make-hilbert-transform", "make-hook", "make-iir-filter", "make-int-vector", "make-iterator", "make-izcos", "make-j0evencos", "make-j0j1cos", "make-j2cos", "make-jjcos", "make-jncos", "make-jpcos", "make-jycos", "make-k2cos", "make-k2sin", "make-k2ssb", "make-k3sin", "make-krksin", "make-locsig", "make-lowpass", "make-mix-sampler", "make-move-sound", "make-moving-autocorrelation", "make-moving-average", "make-moving-fft", "make-moving-max", "make-moving-norm", "make-moving-pitch", "make-moving-scentroid", "make-moving-spectrum", "make-n1cos", "make-nchoosekcos", "make-ncos", "make-nkssb", "make-noddcos", "make-noddsin", "make-noddssb", "make-noid", "make-notch", "make-nrcos", "make-nrsin", "make-nrssb", "make-nrxycos", "make-nrxysin", "make-nsin", "make-nsincos", "make-nssb", "make-nxy1cos", "make-nxy1sin", "make-nxycos", "make-nxysin", "make-one-pole", "make-one-pole-all-pass", "make-one-zero", "make-oscil", "make-oscil-bank", "make-phase-vocoder", "make-pink-noise", "make-pixmap", "make-player", "make-polyoid", "make-polyshape", "make-polywave", "make-pulse-train", "make-pulsed-env", "make-r2k!cos", "make-r2k2cos", "make-ramp", "make-rand", "make-rand-interp", "make-rcos", "make-readin", "make-region", "make-region-sampler", "make-rk!cos", "make-rk!ssb", "make-rkcos", "make-rkoddssb", "make-rksin", "make-rkssb", "make-round-interp", "make-rssb", "make-rxycos", "make-rxyk!cos", "make-rxyk!sin", "make-rxysin", "make-sample->file", "make-sampler", "make-sawtooth-wave", "make-selection", "make-sinc-train", "make-snd->sample", "make-sound-box", "make-spencer-filter", "make-square-wave", "make-src", "make-ssb-am", "make-table-lookup", "make-table-lookup-with-env", "make-tanhsin", "make-triangle-wave", "make-two-pole", "make-two-zero", "make-variable-display", "make-variable-graph", "make-vct", "make-wave-train", "make-wave-train-with-env", "map-channel", "map-sound-files", "maracas", "mark->integer", "mark-click-hook", "mark-click-info", "mark-color", "mark-context", "mark-drag-hook", "mark-explode", "mark-home", "mark-hook", "mark-loops", "mark-name", "mark-name->id", "mark-properties", "mark-property", "mark-sample", "mark-sync", "mark-sync-color", "mark-sync-max", "mark-tag-height", "mark-tag-width", "mark?", "marks", "match-sound-files", "max-envelope", "max-regions", "max-transform-peaks", "maxamp", "maxamp-position", "menu-widgets", "menus, optional", "min-dB", "mix", "mix->float-vector", "mix->integer", "mix-amp", "mix-amp-env", "mix-channel", "mix-click-hook", "mix-click-info", "mix-click-sets-amp", "mix-color", "mix-dialog-mix", "mix-drag-hook", "mix-file-dialog", "mix-home", "mix-length", "mix-maxamp", "mix-name", "mix-name->id", "mix-position", "mix-properties", "mix-property", "mix-region", "mix-release-hook", "mix-sampler?", "mix-selection", "mix-sound", "mix-speed", "mix-sync", "mix-sync-max", "mix-tag-height", "mix-tag-width", "mix-tag-y", "mix-vct", "mix-waveform-height", "mix?", "mixes", "mono->stereo", "moog-filter", "morally-equal?", "mouse-click-hook", "mouse-drag-hook", "mouse-enter-graph-hook", "mouse-enter-label-hook", "mouse-enter-listener-hook", "mouse-enter-text-hook", "mouse-leave-graph-hook", "mouse-leave-label-hook", "mouse-leave-listener-hook", "mouse-leave-text-hook", "mouse-press-hook", "move-locsig", "move-mixes", "move-sound", "move-sound?", "move-syncd-marks", "moving-autocorrelation", "moving-autocorrelation?", "moving-average", "moving-average?", "moving-fft", "moving-fft?", "moving-length", "moving-max", "moving-max?", "moving-norm", "moving-norm?", "moving-pitch", "moving-pitch?", "moving-rms", "moving-scentroid", "moving-scentroid?", "moving-spectrum", "moving-spectrum?", "moving-sum", "mpg", "mus-alsa-buffer-size", "mus-alsa-buffers", "mus-alsa-capture-device", "mus-alsa-device", "mus-alsa-playback-device", "mus-alsa-squelch-warning", "mus-array-print-length", "mus-bytes-per-sample", "mus-channel", "mus-channels", "mus-chebyshev-tu-sum", "mus-clipping", "mus-close", "mus-copy", "mus-data", "mus-describe", "mus-error-hook", "mus-error-type->string", "mus-expand-filename", "mus-feedback", "mus-feedforward", "mus-fft", "mus-file-buffer-size", "mus-file-clipping", "mus-file-mix", "mus-file-name", "mus-float-equal-fudge-factor", "mus-frequency", "mus-generator?", "mus-header-raw-defaults", "mus-header-type->string", "mus-header-type-name", "mus-hop", "mus-increment", "mus-input?", "mus-interp-type", "mus-interpolate", "mus-length", "mus-location", "mus-max-malloc", "mus-max-table-size", "mus-name", "mus-offset", "mus-order", "mus-oss-set-buffers", "mus-output?", "mus-phase", "mus-ramp", "mus-rand-seed", "mus-random", "mus-reset", "mus-run", "mus-sample-type->string", "mus-sample-type-name", "mus-scaler", "mus-sound-chans", "mus-sound-close-input", "mus-sound-close-output", "mus-sound-comment", "mus-sound-data-location", "mus-sound-datum-size", "mus-sound-duration", "mus-sound-forget", "mus-sound-framples", "mus-sound-header-type", "mus-sound-length", "mus-sound-loop-info", "mus-sound-mark-info", "mus-sound-maxamp", "mus-sound-maxamp-exists?", "mus-sound-open-input", "mus-sound-open-output", "mus-sound-path", "mus-sound-preload", "mus-sound-prune", "mus-sound-read", "mus-sound-reopen-output", "mus-sound-report-cache", "mus-sound-sample-type", "mus-sound-samples", "mus-sound-seek-frample", "mus-sound-srate", "mus-sound-type-specifier", "mus-sound-write", "mus-sound-write-date", "mus-srate", "mus-width", "mus-xcoeff", "mus-xcoeffs", "mus-ycoeff", "mus-ycoeffs", "n1cos", "n1cos?", "name-click-hook", "nchoosekcos", "nchoosekcos?", "ncos", "ncos2?", "ncos4?", "ncos?", "new-sound", "new-sound-dialog", "new-sound-hook", "new-widget-hook", "next-sample", "nkssb", "nkssb-interp", "nkssb?", "noddcos", "noddcos?", "noddsin", "noddsin?", "noddssb", "noddssb?", "noid", "normalize-channel", "normalize-envelope", "normalize-partials", "normalize-sound", "normalized-mix", "notch", "notch-channel", "notch-selection", "notch-sound", "notch?", "npcos?", "nrcos", "nrcos?", "nrev", "nrsin", "nrsin?", "nrssb", "nrssb-interp", "nrssb?", "nrxycos", "nrxycos?", "nrxysin", "nrxysin?", "nsin", "nsin?", "nsincos", "nsincos?", "nssb", "nssb?", "nxy1cos", "nxy1cos?", "nxy1sin", "nxy1sin?", "nxycos", "nxycos?", "nxysin", "nxysin?", "object->string", "odd-multiple", "odd-weight", "offset-channel", "offset-sound", "one-pole", "one-pole-all-pass", "one-pole-all-pass?", "one-pole?", "one-zero", "one-zero?", "open-file-dialog", "open-file-dialog-directory", "open-hook", "open-next-file-in-directory", "open-raw-sound", "open-raw-sound-hook", "open-sound", "openlet", "openlet?", "orientation-hook", "oscil", "oscil-bank", "oscil-bank?", "oscil?", "out-any", "out-bank", "outa", "outlet", "*output*", "output-comment-hook", "overlay-rms-env", "owlet", "pad-channel", "pad-marks", "pad-sound", "pan-mix", "pan-mix-float-vector", "partials->polynomial", "partials->wave", "pausing", "peak-env-dir", "peaks", "peaks-font", "phase-partials->wave", "phase-vocoder", "phase-vocoder?", "piano model", "pink-noise", "pink-noise?", "pins", "place-sound", "play", "play-arrow-size", "play-between-marks", "play-hook", "play-mixes", "play-often", "play-region-forever", "play-sine", "play-sines", "play-syncd-marks", "play-until-c-g", "play-with-envs", "player-home", "player?", "players", "playing", "pluck", "polar->rectangular", "polynomial", "polynomial operations", "polyoid", "polyoid-env", "polyoid?", "polyshape", "polyshape?", "polywave", "polywave?", "position->x", "position->y", "position-color", "power-env", "pqw", "pqw-vox", "preferences-dialog", "previous-sample", "print-dialog", "print-length", "procedure-documentation", "procedure-setter", "procedure-signature", "procedure-source", "profile", "progress-report", "pulse-train", "pulse-train?", "pulsed-env", "pulsed-env?", "r2k!cos", "r2k!cos?", "r2k2cos", "r2k2cos?", "radians->degrees", "radians->hz", "ramp-channel", "rand", "rand-interp", "rand-interp?", "rand?", "random", "random-state", "random-state?", "rcos", "rcos?", "read-hook", "read-mix-sample", "read-only", "read-region-sample", "read-sample", "read-sample-with-direction", "reader-cond", "readin", "readin?", "rectangular->magnitudes", "rectangular->polar", "redo", "region->integer", "region->vct", "region-chans", "region-framples", "region-graph-style", "region-home", "region-maxamp", "region-maxamp-position", "region-play-list", "region-position", "region-rms", "region-sample", "region-sampler?", "region-srate", "region?", "regions", "remember-sound-state", "remove-clicks", "remove-from-menu", "replace-with-selection", "report-mark-names", "require", "reset-all-hooks", "reset-controls", "reset-listener-cursor", "reson", "restore-controls", "*reverb*", "reverb-control-decay", "reverb-control-feedback", "reverb-control-length", "reverb-control-length-bounds", "reverb-control-lowpass", "reverb-control-scale", "reverb-control-scale-bounds", "reverb-control?", "reverse!", "reverse-by-blocks", "reverse-channel", "reverse-envelope", "reverse-selection", "reverse-sound", "revert-sound", "right-sample", "ring-modulate", "rk!cos", "rk!cos?", "rk!ssb", "rk!ssb?", "rkcos", "rkcos?", "rkoddssb", "rkoddssb?", "rksin", "rksin?", "rkssb", "rkssb?", "rms", "rms, gain, balance gens", "rms-envelope", "rootlet", "round-interp", "round-interp?", "rssb", "rssb-interp", "rssb?", "rubber-sound", "rxycos", "rxycos?", "rxyk!cos", "rxyk!cos?", "rxyk!sin", "rxyk!sin?", "rxysin", "rxysin?", "sample", "sample->file", "sample->file?", "sample-type", "sampler-at-end?", "sampler-home", "sampler-position", "sampler?", "samples", "samples->seconds", "sash-color", "save-as-dialog-auto-comment", "save-as-dialog-src", "save-controls", "save-dir", "save-edit-history", "save-envelopes", "save-hook", "save-listener", "save-mark-properties", "save-marks", "save-mix", "save-region", "save-region-dialog", "save-selection", "save-selection-dialog", "save-sound", "save-sound-as", "save-sound-dialog", "save-state", "save-state-file", "save-state-hook", "savitzky-golay-filter", "sawtooth-wave", "sawtooth-wave?", "scale-by", "scale-channel", "scale-envelope", "scale-mixes", "scale-selection-by", "scale-selection-to", "scale-sound", "scale-tempo", "scale-to", "scan-channel", "scanned synthesis", "scentroid", "scratch", "script-arg", "script-args", "search-for-click", "search-procedure", "seconds->samples", "select-all", "select-channel", "select-channel-hook", "select-sound", "select-sound-hook", "selected-channel", "selected-data-color", "selected-graph-color", "selected-sound", "selection", "selection->mix", "selection-chans", "selection-color", "selection-context", "selection-creates-region", "selection-framples", "selection-maxamp", "selection-maxamp-position", "selection-member?", "selection-members", "selection-position", "selection-rms", "selection-srate", "selection?", "set-samples", "short-file-name", "show-axes", "show-controls", "show-disk-space", "show-full-duration", "show-full-range", "show-grid", "show-indices", "show-listener", "show-marks", "show-mix-waveforms", "show-selection", "show-selection-transform", "show-sonogram-cursor", "show-transform-peaks", "show-widget", "show-y-zero", "silence-all-mixes", "silence-mixes", "sinc-train", "sinc-train?", "sinc-width", "sine-env-channel", "sine-ramp", "singer", "smooth-channel", "smooth-selection", "smooth-sound", "SMS synthesis", "snap-mark-to-beat", "snap-marks", "snap-mix-to-beat", "snd->sample", "snd->sample?", "snd-color", "snd-error", "snd-error-hook", "snd-font", "snd-gcs", "snd-help", "snd-hooks", "*snd-opened-sound*", "snd-print", "snd-spectrum", "snd-tempnam", "snd-url", "snd-urls", "snd-version", "snd-warning", "snd-warning-hook", "sndwarp", "sort!", "sound->amp-env", "sound->integer", "sound-file-extensions", "sound-file?", "sound-files-in-directory", "sound-interp", "sound-loop-info", "sound-properties", "sound-property", "sound-widgets", "sound?", "soundfont-info", "sounds", "sounds->segment-data", "spectra", "spectral interpolation", "spectral-polynomial", "spectro-hop", "spectro-x-angle", "spectro-x-scale", "spectro-y-angle", "spectro-y-scale", "spectro-z-angle", "spectro-z-scale", "spectrum", "spectrum->coeffs", "spectrum-end", "spectrum-start", "speed-control", "speed-control-bounds", "speed-control-style", "speed-control-tones", "spot-freq", "square-wave", "square-wave?", "squelch-update", "squelch-vowels", "srate", "src", "src-channel", "src-duration", "src-fit-envelope", "src-mixes", "src-selection", "src-sound", "src?", "ssb-am", "ssb-am?", "ssb-bank", "ssb-bank-env", "ssb-fm", "start-dac", "start-playing", "start-playing-hook", "start-playing-selection-hook", "start-progress-report", "status-report", "stereo->mono", "stereo-flute", "stop-player", "stop-playing", "stop-playing-hook", "stop-playing-selection-hook", "stretch-envelope", "stretch-sound-via-dft", "string-position", "sublet", "superimpose-ffts", "swap-channels", "swap-selection-channels", "symbol->dynamic-value", "symbol->value", "symbol-access", "symbol-table", "sync", "sync-everything", "sync-max", "sync-style", "syncd-marks", "syncd-mixes", "syncup", "table-lookup", "table-lookup?", "tanhsin", "tanhsin?", "tap", "tap?", "telephone", "temp-dir", "text-focus-color", "time-graph-style", "time-graph-type", "time-graph?", "times->samples", "tiny-font", "touch-tone", "trace", "tracking-cursor-style", "transform->integer", "transform->vct", "transform-dialog", "transform-framples", "transform-graph-style", "transform-graph-type", "transform-graph?", "transform-normalization", "transform-sample", "transform-size", "transform-type", "transform?", "transpose-mixes", "triangle-wave", "triangle-wave?", "tubebell", "tubular bell", "two-pole", "two-pole?", "two-tab", "two-zero", "two-zero?", "unbind-key", "*unbound-variable-hook*", "unclip-channel", "undo", "undo-hook", "unlet", "unselect-all", "update-graphs", "update-hook", "update-lisp-graph", "update-sound", "update-time-graph", "update-transform-graph", "upon-save-yourself", "user interface extensions", "variable-display", "variable-graph?", "varlet", "vct", "vct*", "vct+", "vct->channel", "vct->list", "vct->string", "vct->vector", "vct-abs!", "vct-add!", "vct-copy", "vct-equal?", "vct-fill!", "vct-length", "vct-max", "vct-min", "vct-move!", "vct-multiply!", "vct-offset!", "vct-peak", "vct-ref", "vct-reverse!", "vct-scale!", "vct-set!", "vct-subseq", "vct-subtract!", "vct?", "vector->vct", "view-files-amp", "view-files-amp-env", "view-files-dialog", "view-files-files", "view-files-select-hook", "view-files-selected-files", "view-files-sort", "view-files-speed", "view-files-speed-style", "view-mixes-dialog", "view-regions-dialog", "view-sound", "voice physical model", "voiced->unvoiced", "volterra-filter", "vox", "wave-train", "wave-train?", "wavelet-type", "waveshaping voice", "wavo-hop", "wavo-trace", "weighted-moving-average", "widget-position", "widget-size", "widget-text", "window-height", "window-samples", "window-width", "window-x", "window-y", "with-background-processes", "with-baffle", "with-file-monitor", "with-gl", "with-inset-graph", "with-interrupts", "with-let", "with-local-hook", "with-menu-icons", "with-mix-tags", "with-pointer-focus", "with-relative-panes", "with-smpte-label", "with-sound", "with-temporary-selection", "with-toolbar", "with-tooltips", "with-tracking-cursor", "with-verbose-cursor", "x->position", "x-axis-label", "x-axis-style", "x-bounds", "x-position-slider", "x-zoom-slider", "xb-open", "xramp-channel", "y->position", "y-axis-label", "y-bounds", "y-position-slider", "y-zoom-slider", "z-transform", "zecho", "zero+", "zero-pad", "zero-phase", "zip-sound", "zipper", "zoom-color", "zoom-focus-style"}; #endif #if HAVE_RUBY static const char *help_names[HELP_NAMES_SIZE] = { "*#readers*", "2byte_vector", "abcos", "abcos?", "abort", "absin", "absin?", "add_amp_controls", "add_colormap", "add_delete_option", "add_directory_to_view_files_list", "add_file_filter", "add_file_sorter", "add_file_to_view_files_list", "add_mark", "add_mark_pane", "add_player", "add_sound_file_extension", "add_source_file_extension", "add_to_main_menu", "add_to_menu", "add_tooltip", "add_transform", "additive_synthesis", "adjustable_sawtooth_wave", "adjustable_sawtooth_wave?", "adjustable_square_wave", "adjustable_square_wave?", "adjustable_triangle_wave", "adjustable_triangle_wave?", "after_apply_controls_hook", "after_edit_hook", "after_graph_hook", "after_lisp_graph_hook", "after_open_hook", "after_save_as_hook", "after_save_state_hook", "after_transform_hook", "all_chans", "all_pass", "all_pass_bank", "all_pass_bank?", "all_pass?", "amp_control", "amp_control_bounds", "amplitude_modulate", "analyse_ladspa", "anoi", "any_env_channel", "any_random", "apply_controls", "apply_ladspa", "aritable?", "arity", "array2file", "array_interp", "as_one_edit", "ask_about_unsaved_edits", "ask_before_overwrite", "asyfm_I", "asyfm_J", "asyfm?", "asymmetric_fm", "asymmetric_fm?", "auto_resize", "auto_save", "auto_update", "auto_update_interval", "autocorrelate", "axis_color", "axis_info", "axis_label_font", "axis_numbers_font", "background_gradient", "bad_header_hook", "bagpipe", "basic_color", "beats_per_measure", "beats_per_minute", "before_close_hook", "before_exit_hook", "before_save_as_hook", "before_save_state_hook", "before_transform_hook", "bes_j0", "bess", "bess?", "bessel_filters", "bigbird", "bignum", "bignum?", "binary_files", "bind_key", "bird", "blackman", "blackman4_env_channel", "blackman?", "bold_peaks_font", "break", "brown_noise", "brown_noise?", "butterworth_filters", "byte_vector", "byte_vector?", "c_define", "c_g?", "c_object?", "c_pointer", "c_pointer?", "call_with_exit", "canter", "cascade2canonical", "catch", "cellon", "chain_dsps", "channel2vct", "channel_amp_envs", "channel_data", "channel_envelope", "channel_polynomial", "channel_properties", "channel_property", "channel_rms", "channel_style", "channel_sync", "channel_widgets", "channels", "channels_equal?", "channels_?", "chans", "char_position", "cheby_hka", "chebyshev_filters", "check_mix_tags", "chordalize", "chorus", "clean_channel", "clean_sound", "clear_listener", "clip_hook", "clipping", "clm_channel", "clm_expsrc", "close_hook", "close_sound", "color2list", "color_cutoff", "color_hook", "color_inverted", "color_mixes", "color_orientation_dialog", "color_scale", "color?", "colormap", "colormap2integer", "colormap_name", "colormap_ref", "colormap_size", "colormap?", "comb", "comb_bank", "comb_bank?", "comb?", "combined_data_color", "comment", "complexify", "compute_uniform_circular_string", "concatenate_envelopes", "constant?", "continuation?", "continue_frample2file", "continue_sample2file", "contrast_channel", "contrast_control", "contrast_control_amp", "contrast_control_bounds", "contrast_control?", "contrast_enhancement", "contrast_sound", "controls2channel", "convolution", "convolution_reverb", "convolve", "convolve_files", "convolve_selection_with", "convolve_with", "convolve?", "copy", "Copy_context", "copy_sampler", "correlate", "coverlet", "cross_fade__amplitude_", "cross_fade__frequency_domain_", "cross_synthesis", "curlet", "current_font", "cursor", "cursor_color", "Cursor_context", "cursor_location_offset", "cursor_position", "cursor_size", "cursor_style", "cursor_update_interval", "cutlet", "cyclic_sequences", "dac_combines_channels", "dac_size", "data_color", "data_location", "data_size", "db2linear", "default_output_chans", "default_output_header_type", "default_output_sample_type", "default_output_srate", "defgenerator", "define_", "define_constant", "define_envelope", "define_expansion", "define_macro", "define_macro_", "define_selection_via_marks", "defined?", "degrees2radians", "delay", "delay_channel_mixes", "delay_tick", "delay?", "delete_colormap", "delete_file_filter", "delete_file_sorter", "delete_mark", "delete_marks", "delete_sample", "delete_samples", "delete_samples_and_smooth", "delete_selection", "delete_selection_and_smooth", "delete_transform", "describe_hook", "describe_mark", "dht", "dialog_widgets", "dilambda", "disable_control_panel", "display_bark_fft", "display_correlation", "display_db", "display_edits", "display_energy", "dissolve_fade", "dither_channel", "dither_sound", "dolph", "dot_product", "dot_size", "down_oct", "draw_axes", "draw_dot", "draw_dots", "draw_line", "draw_lines", "draw_mark_hook", "draw_mix_hook", "draw_string", "drone", "drop_sites", "drop_hook", "during_open_hook", "edit_fragment", "edit_header_dialog", "edit_hook", "edit_list2function", "edit_position", "edit_properties", "edit_property", "edit_tree", "edits", "edot_product", "effects_hook", "elliptic_filters", "env", "env_any", "env_channel", "env_channel_with_base", "env_expt_channel", "env_interp", "env_mixes", "env_selection", "env_sound", "env_sound_interp", "env_squared_channel", "env?", "enved_base", "enved_clip?", "enved_dialog", "enved_envelope", "enved_filter", "enved_filter_order", "enved_hook", "enved_in_dB", "enved_power", "enved_style", "enved_target", "enved_wave?", "enved_waveform_color", "envelope_interp", "enveloped_mix", "eoddcos", "eoddcos?", "eps_bottom_margin", "eps_file", "eps_left_margin", "eps_size", "ercos", "ercos?", "_error_hook_", "erssb", "erssb?", "even_multiple", "even_weight", "every_sample?", "exit", "exit_hook", "expand_control", "expand_control_bounds", "expand_control_hop", "expand_control_jitter", "expand_control_length", "expand_control_ramp", "expand_control?", "explode_sf2", "exponentially_weighted_moving_average", "expsnd", "expsrc", "_features_", "feedback_fm", "fft", "fft_cancel", "fft_edit", "fft_env_edit", "fft_env_interp", "fft_log_frequency", "fft_log_magnitude", "fft_smoother", "fft_squelch", "fft_window", "fft_window_alpha", "fft_window_beta", "fft_with_phases", "file_database", "file2array", "file2frample", "file2frample?", "file2sample", "file2sample?", "file_name", "fill!", "fill_polygon", "fill_rectangle", "filter", "filter_channel", "filter_control_coeffs", "filter_control_envelope", "filter_control_in_dB", "filter_control_in_hz", "filter_control_order", "filter_control_waveform_color", "filter_control?", "filter_fft", "filter_selection", "filter_selection_and_smooth", "filter_sound", "filter?", "filtered_comb", "filtered_comb_bank", "filtered_comb_bank?", "filtered_comb?", "find_dialog", "find_mark", "find_mix", "find_sound", "finfo", "finish_progress_report", "fir_filter", "fir_filter?", "firmant", "firmant?", "fit_selection_between_marks", "flatten_partials", "float_vector", "float-vector_multiply", "float-vector_add", "float_vector2channel", "float_vector2list", "float_vector2string", "float_vector_abs!", "float_vector_add!", "float_vector_copy", "float_vector_equal?", "float_vector_fill!", "float_vector_length", "float_vector_max", "float_vector_min", "float_vector_move!", "float_vector_multiply!", "float_vector_offset!", "float_vector_peak", "float_vector_polynomial", "float_vector_ref", "float_vector_reverse!", "float_vector_scale!", "float_vector_set!", "float_vector_subseq", "float_vector_subtract!", "float_vector?", "flocsig", "flocsig?", "flute_model", "fm_bell", "fm_drum", "fm_noise", "fm_parallel_component", "fm_talker", "fm_trumpet", "fm_violin", "fm_voice", "fmssb", "fmssb?", "focus_widget", "FOF_synthesis", "fofins", "for_each_child", "for_each_sound_file", "Forbidden_Planet", "foreground_color", "forget_region", "formant", "formant_bank", "formant_bank?", "formant?", "format", "fp", "fractional_fourier_transform", "frample2file", "frample2file?", "frample2frample", "framples", "free_player", "free_sampler", "freeverb", "fullmix", "funclet", "gaussian_distribution", "gc_off", "gc_on", "gensym", "gensym?", "gl_graph2ps", "glSpectrogram", "goertzel", "goto_listener_end", "grani", "granulate", "granulate?", "granulated_sound_interp", "graph", "graph2ps", "graph_color", "graph_cursor", "graph_data", "graph_hook", "graph_style", "graphic_equalizer", "graphs_horizontal", "green_noise", "green_noise_interp", "green_noise_interp?", "green_noise?", "grid_density", "harmonicizer", "Hartley_transform", "hash_table", "hash_table_", "hash_table_entries", "hash_table_ref", "hash_table_set!", "hash_table?", "header_type", "hello_dentist", "help_dialog", "help_hook", "hide_widget", "highlight_color", "hilbert_transform", "hook_functions", "hook_member", "html", "html_dir", "html_program", "hz2radians", "iir_filter", "iir_filter?", "call_in", "in_any", "ina", "inb", "info_dialog", "init_ladspa", "initial_beg", "initial_dur", "initial_graph_hook", "inlet", "insert_channel", "insert_file_dialog", "insert_region", "insert_sample", "insert_samples", "insert_selection", "insert_silence", "insert_sound", "int_vector", "int_vector_ref", "int_vector_set!", "int_vector?", "integer2colormap", "integer2mark", "integer2mix", "integer2region", "integer2sound", "integer2transform", "integrate_envelope", "invert_filter", "iterate", "iterator_at_end?", "iterator_sequence", "iterator?", "izcos", "izcos?", "j0evencos", "j0evencos?", "j0j1cos", "j0j1cos?", "j2cos", "j2cos?", "jc_reverb", "jjcos", "jjcos?", "jncos", "jncos?", "jpcos", "jpcos?", "just_sounds", "jycos", "jycos?", "k2cos", "k2cos?", "k2sin", "k2sin?", "k2ssb", "k2ssb?", "k3sin", "k3sin?", "kalman_filter_channel", "key", "key_binding", "key_press_hook", "krksin", "krksin?", "ladspa_descriptor", "ladspa_dir", "lambda_", "lbj_piano", "left_sample", "let2list", "let_ref", "let_set!", "let?", "linear2db", "linear_src_channel", "lint_for_scheme", "lisp_graph_hook", "lisp_graph_style", "lisp_graph?", "list2float_vector", "list2vct", "list_ladspa", "listener_click_hook", "listener_color", "listener_colorized", "listener_font", "listener_prompt", "listener_selection", "listener_text_color", "little_endian?", "_load_hook_", "_load_path_", "locate_zero", "locsig", "locsig_ref", "locsig_reverb_ref", "locsig_reverb_set!", "locsig_set!", "locsig_type", "locsig?", "log_freq_start", "lpc_coeffs", "lpc_predict", "macro?", "macroexpand", "main_menu", "main_widgets", "make_abcos", "make_absin", "make_adjustable_sawtooth_wave", "make_adjustable_square_wave", "make_adjustable_triangle_wave", "make_all_pass", "make_all_pass_bank", "make_asyfm", "make_asymmetric_fm", "make_bandpass", "make_bandstop", "make_bess", "make_biquad", "make_birds", "make_blackman", "make_brown_noise", "make_byte_vector", "make_channel_drop_site", "make_color", "make_comb", "make_comb_bank", "make_convolve", "make_delay", "make_differentiator", "make_env", "make_eoddcos", "make_ercos", "make_erssb", "make_fft_window", "make_file2frample", "make_file2sample", "make_filter", "make_filtered_comb", "make_filtered_comb_bank", "make_fir_coeffs", "make_fir_filter", "make_firmant", "make_float_vector", "make_flocsig", "make_fmssb", "make_formant", "make_formant_bank", "make_frample2file", "make_granulate", "make_graph_data", "make_green_noise", "make_green_noise_interp", "make_hash_table", "make_highpass", "make_hilbert_transform", "make_hook", "make_iir_filter", "make_int_vector", "make_iterator", "make_izcos", "make_j0evencos", "make_j0j1cos", "make_j2cos", "make_jjcos", "make_jncos", "make_jpcos", "make_jycos", "make_k2cos", "make_k2sin", "make_k2ssb", "make_k3sin", "make_krksin", "make_locsig", "make_lowpass", "make_mix_sampler", "make_move_sound", "make_moving_autocorrelation", "make_moving_average", "make_moving_fft", "make_moving_max", "make_moving_norm", "make_moving_pitch", "make_moving_scentroid", "make_moving_spectrum", "make_n1cos", "make_nchoosekcos", "make_ncos", "make_nkssb", "make_noddcos", "make_noddsin", "make_noddssb", "make_noid", "make_notch", "make_nrcos", "make_nrsin", "make_nrssb", "make_nrxycos", "make_nrxysin", "make_nsin", "make_nsincos", "make_nssb", "make_nxy1cos", "make_nxy1sin", "make_nxycos", "make_nxysin", "make_one_pole", "make_one_pole_all_pass", "make_one_zero", "make_oscil", "make_oscil_bank", "make_phase_vocoder", "make_pink_noise", "make_pixmap", "make_player", "make_polyoid", "make_polyshape", "make_polywave", "make_pulse_train", "make_pulsed_env", "make_r2k!cos", "make_r2k2cos", "make_ramp", "make_rand", "make_rand_interp", "make_rcos", "make_readin", "make_region", "make_region_sampler", "make_rk!cos", "make_rk!ssb", "make_rkcos", "make_rkoddssb", "make_rksin", "make_rkssb", "make_round_interp", "make_rssb", "make_rxycos", "make_rxyk!cos", "make_rxyk!sin", "make_rxysin", "make_sample2file", "make_sampler", "make_sawtooth_wave", "make_selection", "make_sinc_train", "make_snd2sample", "make_sound_box", "make_spencer_filter", "make_square_wave", "make_src", "make_ssb_am", "make_table_lookup", "make_table_lookup_with_env", "make_tanhsin", "make_triangle_wave", "make_two_pole", "make_two_zero", "make_variable_display", "make_variable_graph", "make_vct", "make_wave_train", "make_wave_train_with_env", "map_channel", "map_sound_files", "maracas", "mark2integer", "mark_click_hook", "mark_click_info", "mark_color", "Mark_context", "mark_drag_hook", "mark_explode", "mark_home", "mark_hook", "mark_loops", "mark_name", "mark_name2id", "mark_properties", "mark_property", "mark_sample", "mark_sync", "mark_sync_color", "mark_sync_max", "mark_tag_height", "mark_tag_width", "mark?", "marks", "match_sound_files", "max_envelope", "max_regions", "max_transform_peaks", "maxamp", "maxamp_position", "menu_widgets", "menus__optional", "min_dB", "mix", "mix2float_vector", "mix2integer", "mix_amp", "mix_amp_env", "mix_channel", "mix_click_hook", "mix_click_info", "mix_click_sets_amp", "mix_color", "mix_dialog_mix", "mix_drag_hook", "mix_file_dialog", "mix_home", "mix_length", "mix_maxamp", "mix_name", "mix_name2id", "mix_position", "mix_properties", "mix_property", "mix_region", "mix_release_hook", "mix_sampler?", "mix_selection", "mix_sound", "mix_speed", "mix_sync", "mix_sync_max", "mix_tag_height", "mix_tag_width", "mix_tag_y", "mix_vct", "mix_waveform_height", "mix?", "mixes", "mono2stereo", "moog_filter", "morally_equal?", "mouse_click_hook", "mouse_drag_hook", "mouse_enter_graph_hook", "mouse_enter_label_hook", "mouse_enter_listener_hook", "mouse_enter_text_hook", "mouse_leave_graph_hook", "mouse_leave_label_hook", "mouse_leave_listener_hook", "mouse_leave_text_hook", "mouse_press_hook", "move_locsig", "move_mixes", "move_sound", "move_sound?", "move_syncd_marks", "moving_autocorrelation", "moving_autocorrelation?", "moving_average", "moving_average?", "moving_fft", "moving_fft?", "moving_length", "moving_max", "moving_max?", "moving_norm", "moving_norm?", "moving_pitch", "moving_pitch?", "moving_rms", "moving_scentroid", "moving_scentroid?", "moving_spectrum", "moving_spectrum?", "moving_sum", "mpg", "mus_alsa_buffer_size", "mus_alsa_buffers", "mus_alsa_capture_device", "mus_alsa_device", "mus_alsa_playback_device", "mus_alsa_squelch_warning", "mus_array_print_length", "mus_bytes_per_sample", "mus_channel", "mus_channels", "mus_chebyshev_tu_sum", "mus_clipping", "mus_close", "mus_copy", "mus_data", "mus_describe", "mus_error_hook", "mus_error_type2string", "mus_expand_filename", "mus_feedback", "mus_feedforward", "mus_fft", "mus_file_buffer_size", "mus_file_clipping", "mus_file_mix", "mus_file_name", "mus_float_equal_fudge_factor", "mus_frequency", "mus_generator?", "mus_header_raw_defaults", "mus_header_type2string", "mus_header_type_name", "mus_hop", "mus_increment", "mus_input?", "mus_interp_type", "mus_interpolate", "mus_length", "mus_location", "mus_max_malloc", "mus_max_table_size", "mus_name", "mus_offset", "mus_order", "mus_oss_set_buffers", "mus_output?", "mus_phase", "mus_ramp", "mus_rand_seed", "mus_random", "mus_reset", "mus_run", "mus_sample_type2string", "mus_sample_type_name", "mus_scaler", "mus_sound_chans", "mus_sound_close_input", "mus_sound_close_output", "mus_sound_comment", "mus_sound_data_location", "mus_sound_datum_size", "mus_sound_duration", "mus_sound_forget", "mus_sound_framples", "mus_sound_header_type", "mus_sound_length", "mus_sound_loop_info", "mus_sound_mark_info", "mus_sound_maxamp", "mus_sound_maxamp_exists?", "mus_sound_open_input", "mus_sound_open_output", "mus_sound_path", "mus_sound_preload", "mus_sound_prune", "mus_sound_read", "mus_sound_reopen_output", "mus_sound_report_cache", "mus_sound_sample_type", "mus_sound_samples", "mus_sound_seek_frample", "mus_sound_srate", "mus_sound_type_specifier", "mus_sound_write", "mus_sound_write_date", "mus_srate", "mus_width", "mus_xcoeff", "mus_xcoeffs", "mus_ycoeff", "mus_ycoeffs", "n1cos", "n1cos?", "name_click_hook", "nchoosekcos", "nchoosekcos?", "ncos", "ncos2?", "ncos4?", "ncos?", "new_sound", "new_sound_dialog", "new_sound_hook", "new_widget_hook", "next_sample", "nkssb", "nkssb_interp", "nkssb?", "noddcos", "noddcos?", "noddsin", "noddsin?", "noddssb", "noddssb?", "noid", "normalize_channel", "normalize_envelope", "normalize_partials", "normalize_sound", "normalized_mix", "notch", "notch_channel", "notch_selection", "notch_sound", "notch?", "npcos?", "nrcos", "nrcos?", "nrev", "nrsin", "nrsin?", "nrssb", "nrssb_interp", "nrssb?", "nrxycos", "nrxycos?", "nrxysin", "nrxysin?", "nsin", "nsin?", "nsincos", "nsincos?", "nssb", "nssb?", "nxy1cos", "nxy1cos?", "nxy1sin", "nxy1sin?", "nxycos", "nxycos?", "nxysin", "nxysin?", "object2string", "odd_multiple", "odd_weight", "offset_channel", "offset_sound", "one_pole", "one_pole_all_pass", "one_pole_all_pass?", "one_pole?", "one_zero", "one_zero?", "open_file_dialog", "open_file_dialog_directory", "open_hook", "open_next_file_in_directory", "open_raw_sound", "open_raw_sound_hook", "open_sound", "openlet", "openlet?", "orientation_hook", "oscil", "oscil_bank", "oscil_bank?", "oscil?", "out_any", "out_bank", "outa", "outlet", "_output_", "output_comment_hook", "overlay_rms_env", "owlet", "pad_channel", "pad_marks", "pad_sound", "pan_mix", "pan_mix_float_vector", "partials2polynomial", "partials2wave", "pausing", "peak_env_dir", "peaks", "peaks_font", "phase_partials2wave", "phase_vocoder", "phase_vocoder?", "piano_model", "pink_noise", "pink_noise?", "pins", "place_sound", "play", "play_arrow_size", "play_between_marks", "play_hook", "play_mixes", "play_often", "play_region_forever", "play_sine", "play_sines", "play_syncd_marks", "play_until_c_g", "play_with_envs", "player_home", "player?", "players", "playing", "pluck", "polar2rectangular", "polynomial", "polynomial_operations", "polyoid", "polyoid_env", "polyoid?", "polyshape", "polyshape?", "polywave", "polywave?", "position2x", "position2y", "position_color", "power_env", "pqw", "pqw_vox", "preferences_dialog", "previous_sample", "print_dialog", "print_length", "procedure_documentation", "procedure_setter", "procedure_signature", "procedure_source", "profile", "progress_report", "pulse_train", "pulse_train?", "pulsed_env", "pulsed_env?", "r2k!cos", "r2k!cos?", "r2k2cos", "r2k2cos?", "radians2degrees", "radians2hz", "ramp_channel", "rand", "rand_interp", "rand_interp?", "rand?", "random", "random_state", "random_state?", "rcos", "rcos?", "read_hook", "read_mix_sample", "read_only", "read_region_sample", "read_sample", "read_sample_with_direction", "reader_cond", "readin", "readin?", "rectangular2magnitudes", "rectangular2polar", "redo_edit", "region2integer", "region2vct", "region_chans", "region_framples", "region_graph_style", "region_home", "region_maxamp", "region_maxamp_position", "region_play_list", "region_position", "region_rms", "region_sample", "region_sampler?", "region_srate", "region?", "regions", "remember_sound_state", "remove_clicks", "remove_from_menu", "replace_with_selection", "report_mark_names", "require", "reset_all_hooks", "reset_controls", "reset_listener_cursor", "reson", "restore_controls", "_reverb_", "reverb_control_decay", "reverb_control_feedback", "reverb_control_length", "reverb_control_length_bounds", "reverb_control_lowpass", "reverb_control_scale", "reverb_control_scale_bounds", "reverb_control?", "reverse!", "reverse_by_blocks", "reverse_channel", "reverse_envelope", "reverse_selection", "reverse_sound", "revert_sound", "right_sample", "ring_modulate", "rk!cos", "rk!cos?", "rk!ssb", "rk!ssb?", "rkcos", "rkcos?", "rkoddssb", "rkoddssb?", "rksin", "rksin?", "rkssb", "rkssb?", "rms", "rms__gain__balance_gens", "rms_envelope", "rootlet", "round_interp", "round_interp?", "rssb", "rssb_interp", "rssb?", "rubber_sound", "rxycos", "rxycos?", "rxyk!cos", "rxyk!cos?", "rxyk!sin", "rxyk!sin?", "rxysin", "rxysin?", "sample", "sample2file", "sample2file?", "sample_type", "sampler_at_end?", "sampler_home", "sampler_position", "sampler?", "samples", "samples2seconds", "sash_color", "save_as_dialog_auto_comment", "save_as_dialog_src", "save_controls", "save_dir", "save_edit_history", "save_envelopes", "save_hook", "save_listener", "save_mark_properties", "save_marks", "save_mix", "save_region", "save_region_dialog", "save_selection", "save_selection_dialog", "save_sound", "save_sound_as", "save_sound_dialog", "save_state", "save_state_file", "save_state_hook", "savitzky_golay_filter", "sawtooth_wave", "sawtooth_wave?", "scale_by", "scale_channel", "scale_envelope", "scale_mixes", "scale_selection_by", "scale_selection_to", "scale_sound", "scale_tempo", "scale_to", "scan_channel", "scanned_synthesis", "scentroid", "scratch", "script_arg", "script_args", "search_for_click", "search_procedure", "seconds2samples", "select_all", "select_channel", "select_channel_hook", "select_sound", "select_sound_hook", "selected_channel", "selected_data_color", "selected_graph_color", "selected_sound", "selection", "selection2mix", "selection_chans", "selection_color", "Selection_context", "selection_creates_region", "selection_framples", "selection_maxamp", "selection_maxamp_position", "selection_member?", "selection_members", "selection_position", "selection_rms", "selection_srate", "selection?", "set_samples", "short_file_name", "show_axes", "show_controls", "show_disk_space", "show_full_duration", "show_full_range", "show_grid", "show_indices", "show_listener", "show_marks", "show_mix_waveforms", "show_selection", "show_selection_transform", "show_sonogram_cursor", "show_transform_peaks", "show_widget", "show_y_zero", "silence_all_mixes", "silence_mixes", "sinc_train", "sinc_train?", "sinc_width", "sine_env_channel", "sine_ramp", "singer", "smooth_channel", "smooth_selection", "smooth_sound", "SMS_synthesis", "snap_mark_to_beat", "snap_marks", "snap_mix_to_beat", "snd2sample", "snd2sample?", "snd_color", "snd_error", "snd_error_hook", "snd_font", "snd_gcs", "snd_help", "snd_hooks", "_snd_opened_sound_", "snd_print", "snd_spectrum", "snd_tempnam", "snd_url", "snd_urls", "snd_version", "snd_warning", "snd_warning_hook", "sndwarp", "sort!", "sound2amp_env", "sound2integer", "sound_file_extensions", "sound_file?", "sound_files_in_directory", "sound_interp", "sound_loop_info", "sound_properties", "sound_property", "sound_widgets", "sound?", "soundfont_info", "sounds", "sounds2segment_data", "spectra", "spectral_interpolation", "spectral_polynomial", "spectro_hop", "spectro_x_angle", "spectro_x_scale", "spectro_y_angle", "spectro_y_scale", "spectro_z_angle", "spectro_z_scale", "spectrum", "spectrum2coeffs", "spectrum_end", "spectrum_start", "speed_control", "speed_control_bounds", "speed_control_style", "speed_control_tones", "spot_freq", "square_wave", "square_wave?", "squelch_update", "squelch_vowels", "srate", "src", "src_channel", "src_duration", "src_fit_envelope", "src_mixes", "src_selection", "src_sound", "src?", "ssb_am", "ssb_am?", "ssb_bank", "ssb_bank_env", "ssb_fm", "start_dac", "start_playing", "start_playing_hook", "start_playing_selection_hook", "start_progress_report", "status_report", "stereo2mono", "stereo_flute", "stop_player", "stop_playing", "stop_playing_hook", "stop_playing_selection_hook", "stretch_envelope", "stretch_sound_via_dft", "string_position", "sublet", "superimpose_ffts", "swap_channels", "swap_selection_channels", "symbol2dynamic_value", "symbol2value", "symbol_access", "symbol_table", "sync", "sync_everything", "sync_max", "sync_style", "syncd_marks", "syncd_mixes", "syncup", "table_lookup", "table_lookup?", "tanhsin", "tanhsin?", "tap", "tap?", "telephone", "temp_dir", "text_focus_color", "time_graph_style", "time_graph_type", "time_graph?", "times2samples", "tiny_font", "touch_tone", "trace", "tracking_cursor_style", "transform2integer", "transform2vct", "transform_dialog", "transform_framples", "transform_graph_style", "transform_graph_type", "transform_graph?", "transform_normalization", "transform_sample", "transform_size", "transform_type", "transform?", "transpose_mixes", "triangle_wave", "triangle_wave?", "tubebell", "tubular_bell", "two_pole", "two_pole?", "two_tab", "two_zero", "two_zero?", "unbind_key", "_unbound_variable_hook_", "unclip_channel", "undo", "undo_hook", "unlet", "unselect_all", "update_graphs", "update_hook", "update_lisp_graph", "update_sound", "update_time_graph", "update_transform_graph", "upon_save_yourself", "user_interface_extensions", "variable_display", "variable_graph?", "varlet", "vct", "vct_", "vct_", "vct2channel", "vct2list", "vct2string", "vct2vector", "vct_abs!", "vct_add!", "vct_copy", "vct_equal?", "vct_fill!", "vct_length", "vct_max", "vct_min", "vct_move!", "vct_multiply!", "vct_offset!", "vct_peak", "vct_ref", "vct_reverse!", "vct_scale!", "vct_set!", "vct_subseq", "vct_subtract!", "vct?", "vector2vct", "view_files_amp", "view_files_amp_env", "view_files_dialog", "view_files_files", "view_files_select_hook", "view_files_selected_files", "view_files_sort", "view_files_speed", "view_files_speed_style", "view_mixes_dialog", "view_regions_dialog", "view_sound", "voice_physical_model", "voiced2unvoiced", "volterra_filter", "vox", "wave_train", "wave_train?", "wavelet_type", "waveshaping_voice", "wavo_hop", "wavo_trace", "weighted_moving_average", "widget_position", "widget_size", "widget_text", "window_height", "window_samples", "window_width", "window_x", "window_y", "with_background_processes", "with_baffle", "with_file_monitor", "with_gl", "with_inset_graph", "with_interrupts", "with_let", "with_local_hook", "with_menu_icons", "with_mix_tags", "with_pointer_focus", "with_relative_panes", "with_smpte_label", "with_sound", "with_temporary_selection", "with_toolbar", "with_tooltips", "with_tracking_cursor", "with_verbose_cursor", "x2position", "x_axis_label", "x_axis_style", "x_bounds", "x_position_slider", "x_zoom_slider", "xb_open", "xramp_channel", "y2position", "y_axis_label", "y_bounds", "y_position_slider", "y_zoom_slider", "z_transform", "zecho", "zero_", "zero_pad", "zero_phase", "zip_sound", "zipper", "zoom_color", "zoom_focus_style"}; #endif #if (!HAVE_EXTENSION_LANGUAGE) static const char **help_names = NULL; #endif static const char *help_urls[HELP_NAMES_SIZE] = { "*#readers*", "s7.html#tobytevector", "sndclm.html#abcos", "sndclm.html#abcos?", "extsnd.html#abort", "sndclm.html#absin", "sndclm.html#absin?", "sndscm.html#addampcontrols", "extsnd.html#addcolormap", "sndscm.html#adddeleteoption", "extsnd.html#adddirectorytoviewfileslist", "extsnd.html#addfilefilter", "extsnd.html#addfilesorter", "extsnd.html#addfiletoviewfileslist", "extsnd.html#addmark", "sndscm.html#addmarkpane", "extsnd.html#addplayer", "extsnd.html#addsoundfileextension", "extsnd.html#addsourcefileextension", "extsnd.html#addtomainmenu", "extsnd.html#addtomenu", "sndscm.html#addtooltip", "extsnd.html#addtransform", "sndscm.html#spectra", "sndclm.html#adjustable-sawtooth-wave", "sndclm.html#adjustable-sawtooth-wave?", "sndclm.html#adjustable-square-wave", "sndclm.html#adjustable-square-wave?", "sndclm.html#adjustable-triangle-wave", "sndclm.html#adjustable-triangle-wave?", "extsnd.html#afterapplycontrolshook", "extsnd.html#afteredithook", "extsnd.html#aftergraphhook", "extsnd.html#afterlispgraphhook", "extsnd.html#afteropenhook", "extsnd.html#aftersaveashook", "extsnd.html#aftersavestatehook", "extsnd.html#aftertransformhook", "sndscm.html#allchans", "sndclm.html#all-pass", "sndclm.html#allpassbank", "sndclm.html#allpassbankp", "sndclm.html#all-pass?", "extsnd.html#ampcontrol", "extsnd.html#ampcontrolbounds", "sndclm.html#amplitude-modulate", "grfsnd.html#analyseladspa", "sndscm.html#anoi", "sndscm.html#anyenvchannel", "sndscm.html#anyrandom", "extsnd.html#applycontrols", "grfsnd.html#applyladspa", "s7.html#aritablep", "s7.html#arity", "sndclm.html#arraytofile", "sndclm.html#array-interp", "extsnd.html#asoneedit", "extsnd.html#askaboutunsavededits", "extsnd.html#askbeforeoverwrite", "sndclm.html#asyfmI", "sndclm.html#asyfmJ", "sndclm.html#asyfm?", "sndclm.html#asymmetric-fm", "sndclm.html#asymmetric-fm?", "extsnd.html#autoresize", "sndscm.html#autosavedoc", "extsnd.html#autoupdate", "extsnd.html#autoupdateinterval", "sndclm.html#autocorrelate", "extsnd.html#axiscolor", "extsnd.html#axisinfo", "extsnd.html#axislabelfont", "extsnd.html#axisnumbersfont", "extsnd.html#backgroundgradient", "extsnd.html#badheaderhook", "sndscm.html#bagpipe", "extsnd.html#basiccolor", "extsnd.html#beatspermeasure", "extsnd.html#beatsperminute", "extsnd.html#beforeclosehook", "extsnd.html#beforeexithook", "extsnd.html#beforesaveashook", "extsnd.html#beforesavestatehook", "extsnd.html#beforetransformhook", "extsnd.html#besj0", "sndclm.html#bess", "sndclm.html#bess?", "sndscm.html#analogfilterdoc", "sndscm.html#bigbird", "s7.html#bignum", "s7.html#bignump", "sndscm.html#binaryiodoc", "extsnd.html#bindkey", "sndscm.html#bird", "sndclm.html#blackman", "sndscm.html#blackman4envchannel", "sndclm.html#blackman?", "extsnd.html#boldpeaksfont", "extsnd.html#break", "sndclm.html#brown-noise", "sndclm.html#brown-noise?", "sndscm.html#analogfilterdoc", "s7.html#bytevector", "s7.html#bytevectorp", "s7.html#definecfunction", "extsnd.html#cgp", "s7.html#cobject", "s7.html#cpoint", "s7.html#cpointer", "s7.html#callwithexit", "sndscm.html#bagpipe", "sndscm.html#cascadetocanonical", "s7.html#catch", "sndscm.html#cellon", "sndscm.html#chaindsps", "extsnd.html#channeltovct", "extsnd.html#channelampenvs", "extsnd.html#channeldata", "sndscm.html#channelenvelope", "sndscm.html#channelpolynomial", "extsnd.html#channelproperties", "extsnd.html#channelproperty", "sndscm.html#channelrms", "extsnd.html#channelstyle", "sndscm.html#channelsync", "extsnd.html#channelwidgets", "extsnd.html#channels", "sndscm.html#channelsequal", "sndscm.html#channelseq", "extsnd.html#chans", "s7.html#charposition", "sndscm.html#chebyhka", "sndscm.html#analogfilterdoc", "sndscm.html#checkmixtags", "sndscm.html#chordalize", "sndscm.html#chorus", "sndscm.html#cleanchannel", "sndscm.html#cleansound", "extsnd.html#clearlistener", "extsnd.html#cliphook", "extsnd.html#clipping", "extsnd.html#clmchannel", "sndscm.html#clmexpsrc", "extsnd.html#closehook", "extsnd.html#closesound", "extsnd.html#colortolist", "extsnd.html#colorcutoff", "extsnd.html#colorhook", "extsnd.html#colorinverted", "sndscm.html#colormixes", "extsnd.html#colororientationdialog", "extsnd.html#colorscale", "extsnd.html#colorp", "extsnd.html#colormap", "extsnd.html#colormaptointeger", "extsnd.html#colormapname", "extsnd.html#colormapref", "extsnd.html#colormapsize", "extsnd.html#colormapp", "sndclm.html#comb", "sndclm.html#combbank", "sndclm.html#combbankp", "sndclm.html#comb?", "extsnd.html#combineddatacolor", "extsnd.html#comment", "sndscm.html#complexify", "sndscm.html#computeuniformcircularstring", "sndscm.html#concatenateenvelopes", "s7.html#constantp", "s7.html#continuationp", "sndclm.html#continue-frampletofile", "sndclm.html#continue-sampletofile", "sndscm.html#contrastchannel", "extsnd.html#contrastcontrol", "extsnd.html#contrastcontrolamp", "extsnd.html#contrastcontrolbounds", "extsnd.html#contrastcontrolp", "sndclm.html#contrast-enhancement", "sndscm.html#contrastsound", "extsnd.html#controlstochannel", "sndclm.html#convolution", "extsnd.html#convolvewith", "sndclm.html#convolve", "sndclm.html#convolvefiles", "extsnd.html#convolveselectionwith", "extsnd.html#convolvewith", "sndclm.html#convolve?", "s7.html#s7copy", "extsnd.html#copycontext", "extsnd.html#copysampler", "sndclm.html#correlate", "s7.html#coverlet", "sndscm.html#mixdoc", "sndscm.html#fadedoc", "sndscm.html#crosssynthesis", "s7.html#curlet", "extsnd.html#currentfont", "extsnd.html#cursor", "extsnd.html#cursorcolor", "extsnd.html#cursorcontext", "extsnd.html#cursorlocationoffset", "extsnd.html#cursorposition", "extsnd.html#cursorsize", "extsnd.html#cursorstyle", "extsnd.html#cursorupdateinterval", "s7.html#cutlet", "s7.html#cyclicsequences", "extsnd.html#dacfolding", "extsnd.html#dacsize", "extsnd.html#datacolor", "extsnd.html#datalocation", "extsnd.html#datasize", "sndclm.html#dbtolinear", "extsnd.html#defaultoutputchans", "extsnd.html#defaultoutputheadertype", "extsnd.html#defaultoutputsampletype", "extsnd.html#defaultoutputsrate", "sndclm.html#defgenerator", "s7.html#definestar", "s7.html#defineconstant", "extsnd.html#defineenvelope", "s7.html#expansion", "s7.html#definemacro", "s7.html#definemacrostar", "sndscm.html#defineselectionviamarks", "s7.html#definedp", "sndclm.html#degreestoradians", "sndclm.html#delay", "sndscm.html#delaychannelmixes", "sndclm.html#delaytick", "sndclm.html#delay?", "extsnd.html#deletecolormap", "extsnd.html#deletefilefilter", "extsnd.html#deletefilesorter", "extsnd.html#deletemark", "extsnd.html#deletemarks", "extsnd.html#deletesample", "extsnd.html#deletesamples", "extsnd.html#deletesamplesandsmooth", "extsnd.html#deleteselection", "extsnd.html#deleteselectionandsmooth", "extsnd.html#deletetransform", "sndscm.html#describehook", "sndscm.html#describemark", "sndscm.html#dht", "extsnd.html#dialogwidgets", "s7.html#dilambda", "sndscm.html#disablecontrolpanel", "sndscm.html#displaybarkfft", "sndscm.html#displaycorrelation", "sndscm.html#displaydb", "extsnd.html#displayedits", "sndscm.html#displayenergy", "sndscm.html#dissolvefade", "sndscm.html#ditherchannel", "sndscm.html#dithersound", "sndscm.html#dolph", "sndclm.html#dot-product", "extsnd.html#dotsize", "sndscm.html#downoct", "extsnd.html#drawaxes", "extsnd.html#drawdot", "extsnd.html#drawdots", "extsnd.html#drawline", "extsnd.html#drawlines", "extsnd.html#drawmarkhook", "extsnd.html#drawmixhook", "extsnd.html#drawstring", "sndscm.html#drone", "sndscm.html#makedropsite", "extsnd.html#drophook", "extsnd.html#duringopenhook", "extsnd.html#editfragment", "extsnd.html#editheaderdialog", "extsnd.html#edithook", "extsnd.html#editlisttofunction", "extsnd.html#editposition", "extsnd.html#editproperties", "extsnd.html#editproperty", "extsnd.html#edittree", "extsnd.html#edits", "sndclm.html#edot-product", "extsnd.html#effectshook", "sndscm.html#analogfilterdoc", "sndclm.html#env", "sndclm.html#env-any", "extsnd.html#envchannel", "extsnd.html#envchannelwithbase", "sndscm.html#envexptchannel", "sndclm.html#env-interp", "sndscm.html#envmixes", "extsnd.html#envselection", "extsnd.html#envsound", "sndscm.html#envsoundinterp", "sndscm.html#envsquaredchannel", "sndclm.html#env?", "extsnd.html#envedbase", "extsnd.html#envedclipping", "extsnd.html#enveddialog", "extsnd.html#envedenvelope", "extsnd.html#filterenv", "extsnd.html#filterenvorder", "extsnd.html#envedhook", "extsnd.html#envedin-dB", "extsnd.html#envedpower", "extsnd.html#envedstyle", "extsnd.html#envedtarget", "extsnd.html#envedwaving", "extsnd.html#envedwaveformcolor", "sndclm.html#envelopeinterp", "sndscm.html#envelopedmix", "sndclm.html#eoddcos", "sndclm.html#eoddcos?", "extsnd.html#epsbottommargin", "extsnd.html#epsfile", "extsnd.html#epsleftmargin", "extsnd.html#epssize", "sndclm.html#ercos", "sndclm.html#ercos?", "s7.html#errorhook", "sndclm.html#erssb", "sndclm.html#erssb?", "sndclm.html#evenmultiple", "sndclm.html#evenweight", "sndscm.html#everysample", "extsnd.html#exit", "extsnd.html#exithook", "extsnd.html#expandcontrol", "extsnd.html#expandcontrolbounds", "extsnd.html#expandcontrolhop", "extsnd.html#expandcontroljitter", "extsnd.html#expandcontrollength", "extsnd.html#expandcontrolramp", "extsnd.html#expandcontrolp", "sndscm.html#explodesf2", "sndclm.html#exponentially-weighted-moving-average", "sndscm.html#expsnd", "sndscm.html#expsrc", "s7.html#featureslist", "sndscm.html#cellon", "extsnd.html#fft", "sndscm.html#fftcancel", "sndscm.html#fftedit", "sndscm.html#fftenvedit", "sndscm.html#fftenvinterp", "extsnd.html#fftlogfrequency", "extsnd.html#fftlogmagnitude", "sndscm.html#fftsmoother", "sndscm.html#fftsquelch", "extsnd.html#fftwindow", "extsnd.html#fftalpha", "extsnd.html#fftbeta", "extsnd.html#fftwithphases", "sndscm.html#nbdoc", "sndclm.html#filetoarray", "sndclm.html#filetoframple", "sndclm.html#filetoframple?", "sndclm.html#filetosample", "sndclm.html#filetosample?", "extsnd.html#filename", "s7.html#fillb", "extsnd.html#fillpolygon", "extsnd.html#fillrectangle", "sndclm.html#filter", "extsnd.html#filterchannel", "extsnd.html#filtercontrolcoeffs", "extsnd.html#filtercontrolenvelope", "extsnd.html#filtercontrolindB", "extsnd.html#filtercontrolinhz", "extsnd.html#filtercontrolorder", "extsnd.html#filterwaveformcolor", "extsnd.html#filtercontrolp", "sndscm.html#filterfft", "extsnd.html#filterselection", "sndscm.html#filterselectionandsmooth", "extsnd.html#filtersound", "sndclm.html#filter?", "sndclm.html#filtered-comb", "sndclm.html#filteredcombbank", "sndclm.html#filteredcombbankp", "sndclm.html#filtered-comb?", "extsnd.html#finddialog", "extsnd.html#findmark", "sndscm.html#findmix", "extsnd.html#findsound", "sndscm.html#finfo", "extsnd.html#finishprogressreport", "sndclm.html#fir-filter", "sndclm.html#fir-filter?", "sndclm.html#firmant", "sndclm.html#firmant?", "sndscm.html#fitselectionbetweenmarks", "sndscm.html#flattenpartials", "extsnd.html#fv", "extsnd.html#fvtimes", "extsnd.html#fvplus", "extsnd.html#fvtochannel", "extsnd.html#fvtolist", "extsnd.html#fvtostring", "extsnd.html#fvabs", "extsnd.html#fvadd", "extsnd.html#fvcopy", "extsnd.html#fvequal", "extsnd.html#fvfill", "extsnd.html#fvlength", "extsnd.html#fvmax", "extsnd.html#fvmin", "extsnd.html#fvmove", "extsnd.html#fvmultiply", "extsnd.html#fvoffset", "extsnd.html#fvpeak", "sndscm.html#vctpolynomial", "extsnd.html#fvref", "extsnd.html#fvreverse", "extsnd.html#fvscale", "extsnd.html#fvset", "extsnd.html#fvsubseq", "extsnd.html#fvsubtract", "extsnd.html#fvp", "sndclm.html#flocsig", "sndclm.html#flocsig?", "sndscm.html#stereoflute", "sndscm.html#fmbell", "sndscm.html#fmdrum", "sndscm.html#fmnoise", "sndscm.html#fmparallelcomponent", "sndscm.html#fmvox", "sndscm.html#fmtrumpet", "sndscm.html#vdoc", "sndscm.html#fmvoice", "sndclm.html#fmssb", "sndclm.html#fmssb?", "extsnd.html#focuswidget", "sndscm.html#fofins", "sndscm.html#fofins", "sndscm.html#foreachchild", "sndscm.html#foreachsoundfile", "sndscm.html#fp", "extsnd.html#foregroundcolor", "extsnd.html#forgetregion", "sndclm.html#formant", "sndclm.html#formantbank", "sndclm.html#formantbankp", "sndclm.html#formant?", "s7.html#format", "sndscm.html#fp", "sndscm.html#fractionalfouriertransform", "sndclm.html#frampletofile", "sndclm.html#frampletofile?", "sndclm.html#frampletoframple", "extsnd.html#framples", "extsnd.html#freeplayer", "extsnd.html#freesampler", "sndscm.html#freeverb", "sndscm.html#fullmix", "s7.html#funclet", "sndscm.html#gaussiandistribution", "extsnd.html#gcoff", "extsnd.html#gcon", "s7.html#gensym", "s7.html#gensym?", "extsnd.html#glgraphtops", "extsnd.html#glspectrogram", "sndscm.html#goertzel", "extsnd.html#gotolistenerend", "sndscm.html#grani", "sndclm.html#granulate", "sndclm.html#granulate?", "sndscm.html#granulatedsoundinterp", "extsnd.html#graph", "extsnd.html#graphtops", "extsnd.html#graphcolor", "extsnd.html#graphcursor", "extsnd.html#graphdata", "extsnd.html#graphhook", "extsnd.html#graphstyle", "sndscm.html#grapheq", "extsnd.html#graphshorizontal", "sndclm.html#green-noise", "sndclm.html#green-noise-interp", "sndclm.html#green-noise-interp?", "sndclm.html#green-noise?", "extsnd.html#griddensity", "sndscm.html#harmonicizer", "sndscm.html#dht", "s7.html#hashtable", "s7.html#hashtablestar", "s7.html#hashtableentries", "s7.html#hashtableref", "s7.html#hashtableset", "s7.html#hashtablep", "extsnd.html#headertype", "sndscm.html#hellodentist", "extsnd.html#helpdialog", "extsnd.html#helphook", "extsnd.html#hidewidget", "extsnd.html#highlightcolor", "sndscm.html#hilberttransform", "s7.html#hookfunctions", "sndscm.html#hookmember", "sndscm.html#html", "extsnd.html#htmldir", "extsnd.html#htmlprogram", "sndclm.html#hztoradians", "sndclm.html#iir-filter", "sndclm.html#iir-filter?", "extsnd.html#gin", "sndclm.html#in-any", "sndclm.html#ina", "sndclm.html#inb", "extsnd.html#infodialog", "grfsnd.html#initladspa", "extsnd.html#initialbeg", "extsnd.html#initialdur", "extsnd.html#initialgraphhook", "s7.html#inlet", "sndscm.html#insertchannel", "extsnd.html#insertfiledialog", "extsnd.html#insertregion", "extsnd.html#insertsample", "extsnd.html#insertsamples", "extsnd.html#insertselection", "extsnd.html#insertsilence", "extsnd.html#insertsound", "s7.html#intvector", "s7.html#intvectorref", "s7.html#intvectorset", "s7.html#intvectorp", "extsnd.html#integertocolormap", "extsnd.html#integertomark", "extsnd.html#integertomix", "extsnd.html#integertoregion", "extsnd.html#integertosound", "extsnd.html#integertotransform", "sndscm.html#integrateenvelope", "sndscm.html#invertfilter", "s7.html#iterate", "s7.html#iteratoratend", "s7.html#iteratorsequence", "s7.html#iteratorp", "sndclm.html#izcos", "sndclm.html#izcos?", "sndclm.html#j0evencos", "sndclm.html#j0evencos?", "sndclm.html#j0j1cos", "sndclm.html#j0j1cos?", "sndclm.html#j2cos", "sndclm.html#j2cos?", "sndscm.html#jcreverb", "sndclm.html#jjcos", "sndclm.html#jjcos?", "sndclm.html#jncos", "sndclm.html#jncos?", "sndclm.html#jpcos", "sndclm.html#jpcos?", "extsnd.html#justsounds", "sndclm.html#jycos", "sndclm.html#jycos?", "sndclm.html#k2cos", "sndclm.html#k2cos?", "sndclm.html#k2sin", "sndclm.html#k2sin?", "sndclm.html#k2ssb", "sndclm.html#k2ssb?", "sndclm.html#k3sin", "sndclm.html#k3sin?", "sndscm.html#kalmanfilterchannel", "extsnd.html#key", "extsnd.html#keybinding", "extsnd.html#keypresshook", "sndclm.html#krksin", "sndclm.html#krksin?", "grfsnd.html#ladspadescriptor", "extsnd.html#ladspadir", "s7.html#lambdastar", "sndscm.html#lbjpiano", "extsnd.html#leftsample", "s7.html#lettolist", "s7.html#letref", "s7.html#letset", "s7.html#letp", "sndclm.html#lineartodb", "sndscm.html#linearsrcchannel", "sndscm.html#lintdoc", "extsnd.html#lispgraphhook", "extsnd.html#lispgraphstyle", "extsnd.html#lispgraphp", "extsnd.html#listtofv", "extsnd.html#listtovct", "grfsnd.html#listladspa", "extsnd.html#listenerclickhook", "extsnd.html#listenercolor", "extsnd.html#listenercolorized", "extsnd.html#listenerfont", "extsnd.html#listenerprompt", "extsnd.html#listenerselection", "extsnd.html#listenertextcolor", "extsnd.html#littleendianp", "s7.html#loadhook", "s7.html#loadpath", "sndscm.html#locatezero", "sndclm.html#locsig", "sndclm.html#locsig-ref", "sndclm.html#locsig-reverb-ref", "sndclm.html#locsig-reverb-set!", "sndclm.html#locsig-set!", "sndclm.html#locsig-type", "sndclm.html#locsig?", "extsnd.html#logfreqstart", "sndscm.html#lpccoeffs", "sndscm.html#lpcpredict", "s7.html#macrop", "s7.html#macroexpand", "extsnd.html#mainmenu", "extsnd.html#mainwidgets", "sndclm.html#make-abcos", "sndclm.html#make-absin", "sndclm.html#make-adjustable-sawtooth-wave", "sndclm.html#make-adjustable-square-wave", "sndclm.html#make-adjustable-triangle-wave", "sndclm.html#make-all-pass", "sndclm.html#makeallpassbank", "sndclm.html#make-asyfm", "sndclm.html#make-asymmetric-fm", "sndscm.html#makebandpass", "sndscm.html#makebandstop", "sndclm.html#make-bess", "sndscm.html#makebiquad", "sndscm.html#makebirds", "sndclm.html#make-blackman", "sndclm.html#make-brown-noise", "s7.html#makebytevector", "sndscm.html#makedropsite", "extsnd.html#makecolor", "sndclm.html#make-comb", "sndclm.html#makecombbank", "sndclm.html#make-convolve", "sndclm.html#make-delay", "sndscm.html#makedifferentiator", "sndclm.html#make-env", "sndclm.html#make-eoddcos", "sndclm.html#make-ercos", "sndclm.html#make-erssb", "sndclm.html#make-fft-window", "sndclm.html#make-filetoframple", "sndclm.html#make-filetosample", "sndclm.html#make-filter", "sndclm.html#make-filtered-comb", "sndclm.html#makefilteredcombbank", "sndclm.html#make-fir-coeffs", "sndclm.html#make-fir-filter", "sndclm.html#make-firmant", "extsnd.html#makefv", "sndclm.html#make-flocsig", "sndclm.html#make-fmssb", "sndclm.html#make-formant", "sndclm.html#makeformantbank", "sndclm.html#make-frampletofile", "sndclm.html#make-granulate", "extsnd.html#makegraphdata", "sndclm.html#make-green-noise", "sndclm.html#make-green-noise-interp", "s7.html#makehashtable", "sndscm.html#makehighpass", "sndscm.html#makehilberttransform", "s7.html#makehook", "sndclm.html#make-iir-filter", "s7.html#makeintvector", "s7.html#makeiterator", "sndclm.html#make-izcos", "sndclm.html#make-j0evencos", "sndclm.html#make-j0j1cos", "sndclm.html#make-j2cos", "sndclm.html#make-jjcos", "sndclm.html#make-jncos", "sndclm.html#make-jpcos", "sndclm.html#make-jycos", "sndclm.html#make-k2cos", "sndclm.html#make-k2sin", "sndclm.html#make-k2ssb", "sndclm.html#make-k3sin", "sndclm.html#make-krksin", "sndclm.html#make-locsig", "sndscm.html#makelowpass", "extsnd.html#makemixsampler", "sndclm.html#make-move-sound", "sndclm.html#make-moving-autocorrelation", "sndclm.html#make-moving-average", "sndclm.html#make-moving-fft", "sndclm.html#make-moving-max", "sndclm.html#make-moving-norm", "sndclm.html#make-moving-pitch", "sndclm.html#make-moving-scentroid", "sndclm.html#make-moving-spectrum", "sndclm.html#make-n1cos", "sndclm.html#make-nchoosekcos", "sndclm.html#make-ncos", "sndclm.html#make-nkssb", "sndclm.html#make-noddcos", "sndclm.html#make-noddsin", "sndclm.html#make-noddssb", "sndclm.html#make-noid", "sndclm.html#make-notch", "sndclm.html#make-nrcos", "sndclm.html#make-nrsin", "sndclm.html#make-nrssb", "sndclm.html#make-nrxycos", "sndclm.html#make-nrxysin", "sndclm.html#make-nsin", "sndclm.html#make-nsincos", "sndclm.html#make-nssb", "sndclm.html#make-nxy1cos", "sndclm.html#make-nxy1sin", "sndclm.html#make-nxycos", "sndclm.html#make-nxysin", "sndclm.html#make-one-pole", "sndclm.html#make-one-pole-all-pass", "sndclm.html#make-one-zero", "sndclm.html#make-oscil", "sndclm.html#make-oscil-bank", "sndclm.html#make-phase-vocoder", "sndclm.html#make-pink-noise", "sndscm.html#makepixmap", "extsnd.html#makeplayer", "sndclm.html#make-polyoid", "sndclm.html#make-polyshape", "sndclm.html#make-polywave", "sndclm.html#make-pulse-train", "sndclm.html#make-pulsed-env", "sndclm.html#make-r2k!cos", "sndclm.html#make-r2k2cos", "sndscm.html#makeramp", "sndclm.html#make-rand", "sndclm.html#make-rand-interp", "sndclm.html#make-rcos", "sndclm.html#make-readin", "extsnd.html#makeregion", "extsnd.html#makeregionsampler", "sndclm.html#make-rk!cos", "sndclm.html#make-rk!ssb", "sndclm.html#make-rkcos", "sndclm.html#make-rkoddssb", "sndclm.html#make-rksin", "sndclm.html#make-rkssb", "sndclm.html#make-round-interp", "sndclm.html#make-rssb", "sndclm.html#make-rxycos", "sndclm.html#make-rxyk!cos", "sndclm.html#make-rxyk!sin", "sndclm.html#make-rxysin", "sndclm.html#make-sampletofile", "extsnd.html#makesampler", "sndclm.html#make-sawtooth-wave", "sndscm.html#makeselection", "sndclm.html#make-sinc-train", "extsnd.html#makesndtosample", "sndscm.html#makesoundbox", "sndscm.html#makespencerfilter", "sndclm.html#make-square-wave", "sndclm.html#make-src", "sndclm.html#make-ssb-am", "sndclm.html#make-table-lookup", "sndclm.html#make-table-lookup-with-env", "sndclm.html#make-tanhsin", "sndclm.html#make-triangle-wave", "sndclm.html#make-two-pole", "sndclm.html#make-two-zero", "sndscm.html#makevariabledisplay", "extsnd.html#makevariablegraph", "extsnd.html#makevct", "sndclm.html#make-wave-train", "sndclm.html#make-wave-train-with-env", "extsnd.html#mapchannel", "sndscm.html#mapsoundfiles", "sndscm.html#maracadoc", "extsnd.html#marktointeger", "extsnd.html#markclickhook", "sndscm.html#markclickinfo", "extsnd.html#markcolor", "extsnd.html#markcontext", "extsnd.html#markdraghook", "sndscm.html#markexplode", "extsnd.html#markhome", "extsnd.html#markhook", "sndscm.html#markloops", "extsnd.html#markname", "sndscm.html#marknametoid", "extsnd.html#markproperties", "extsnd.html#markproperty", "extsnd.html#marksample", "extsnd.html#marksync", "sndscm.html#marksynccolor", "extsnd.html#marksyncmax", "extsnd.html#marktagheight", "extsnd.html#marktagwidth", "extsnd.html#markp", "extsnd.html#emarks", "sndscm.html#matchsoundfiles", "sndscm.html#maxenvelope", "extsnd.html#maxregions", "extsnd.html#maxfftpeaks", "extsnd.html#maxamp", "extsnd.html#maxampposition", "extsnd.html#menuwidgets", "sndscm.html#menusdoc", "extsnd.html#mindb", "extsnd.html#mix", "sndscm.html#mixtovct", "extsnd.html#mixtointeger", "extsnd.html#mixamp", "extsnd.html#mixampenv", "sndscm.html#mixchannel", "extsnd.html#mixclickhook", "sndscm.html#mixclickinfo", "sndscm.html#mixclicksetsamp", "extsnd.html#mixcolor", "extsnd.html#mixdialogmix", "extsnd.html#mixdraghook", "extsnd.html#mixfiledialog", "extsnd.html#mixhome", "extsnd.html#mixlength", "sndscm.html#mixmaxamp", "extsnd.html#mixname", "sndscm.html#mixnametoid", "extsnd.html#mixposition", "extsnd.html#mixproperties", "extsnd.html#mixproperty", "extsnd.html#mixregion", "extsnd.html#mixreleasehook", "extsnd.html#mixsamplerQ", "extsnd.html#mixselection", "sndscm.html#mixsound", "extsnd.html#mixspeed", "extsnd.html#mixsync", "extsnd.html#mixsyncmax", "extsnd.html#mixtagheight", "extsnd.html#mixtagwidth", "extsnd.html#mixtagy", "extsnd.html#mixvct", "extsnd.html#mixwaveformheight", "extsnd.html#mixp", "extsnd.html#mixes", "sndscm.html#monotostereo", "sndscm.html#moogfilter", "s7.html#morallyequalp", "extsnd.html#mouseclickhook", "extsnd.html#mousedraghook", "extsnd.html#mouseentergraphhook", "extsnd.html#mouseenterlabelhook", "extsnd.html#mouseenterlistenerhook", "extsnd.html#mouseentertexthook", "extsnd.html#mouseleavegraphhook", "extsnd.html#mouseleavelabelhook", "extsnd.html#mousleavelistenerhook", "extsnd.html#mousleavetexthook", "extsnd.html#mousepresshook", "sndclm.html#move-locsig", "sndscm.html#movemixes", "sndclm.html#move-sound", "sndclm.html#move-sound?", "sndscm.html#movesyncdmarks", "sndclm.html#moving-autocorrelation", "sndclm.html#moving-autocorrelation?", "sndclm.html#moving-average", "sndclm.html#moving-average?", "sndclm.html#moving-fft", "sndclm.html#moving-fft?", "sndclm.html#moving-length", "sndclm.html#moving-max", "sndclm.html#moving-max?", "sndclm.html#moving-norm", "sndclm.html#moving-norm?", "sndclm.html#moving-pitch", "sndclm.html#moving-pitch?", "sndclm.html#moving-rms", "sndclm.html#moving-scentroid", "sndclm.html#moving-scentroid?", "sndclm.html#moving-spectrum", "sndclm.html#moving-spectrum?", "sndclm.html#moving-sum", "sndscm.html#mpg", "extsnd.html#musalsabuffersize", "extsnd.html#musalsabuffers", "extsnd.html#musalsacapturedevice", "extsnd.html#musalsadevice", "extsnd.html#musalsaplaybackdevice", "extsnd.html#musalsasquelchwarning", "sndclm.html#musarrayprintlength", "extsnd.html#musbytespersample", "sndclm.html#mus-channel", "sndclm.html#mus-channels", "sndclm.html#mus-chebyshev-tu-sum", "extsnd.html#musclipping", "sndclm.html#mus-close", "sndclm.html#mus-copy", "sndclm.html#mus-data", "sndclm.html#mus-describe", "extsnd.html#muserrorhook", "extsnd.html#muserrortypetostring", "extsnd.html#musexpandfilename", "sndclm.html#mus-feedback", "sndclm.html#mus-feedforward", "sndclm.html#fft", "sndclm.html#musfilebuffersize", "extsnd.html#musfileclipping", "sndscm.html#musfilemix", "sndclm.html#mus-file-name", "sndclm.html#musfloatequalfudgefactor", "sndclm.html#mus-frequency", "sndclm.html#musgeneratorp", "extsnd.html#musheaderrawdefaults", "extsnd.html#musheadertypetostring", "extsnd.html#musheadertypename", "sndclm.html#mus-hop", "sndclm.html#mus-increment", "sndclm.html#mus-input?", "sndclm.html#mus-interp-type", "sndclm.html#mus-interpolate", "sndclm.html#mus-length", "sndclm.html#mus-location", "extsnd.html#musmaxmalloc", "extsnd.html#musmaxtablesize", "sndclm.html#mus-name", "sndclm.html#mus-offset", "sndclm.html#mus-order", "extsnd.html#musosssetbuffers", "sndclm.html#mus-output?", "sndclm.html#mus-phase", "sndclm.html#mus-ramp", "sndclm.html#mus-rand-seed", "sndclm.html#mus-random", "sndclm.html#mus-reset", "sndclm.html#mus-run", "extsnd.html#mussampletypetostring", "extsnd.html#mussampletypename", "sndclm.html#mus-scaler", "extsnd.html#mussoundchans", "extsnd.html#mussoundcloseinput", "extsnd.html#mussoundcloseoutput", "extsnd.html#mussoundcomment", "extsnd.html#mussounddatalocation", "extsnd.html#mussounddatumsize", "extsnd.html#mussoundduration", "extsnd.html#mussoundforget", "extsnd.html#mussoundframples", "extsnd.html#mussoundheadertype", "extsnd.html#mussoundlength", "extsnd.html#mussoundloopinfo", "extsnd.html#mussoundmarkinfo", "extsnd.html#mussoundmaxamp", "extsnd.html#mussoundmaxampexists", "extsnd.html#mussoundopeninput", "extsnd.html#mussoundopenoutput", "extsnd.html#mussoundpath", "extsnd.html#mussoundpreload", "extsnd.html#mussoundprune", "extsnd.html#mussoundread", "extsnd.html#mussoundreopenoutput", "extsnd.html#mussoundreportcache", "extsnd.html#mussoundsampletype", "extsnd.html#mussoundsamples", "extsnd.html#mussoundseekframple", "extsnd.html#mussoundsrate", "extsnd.html#mussoundtypespecifier", "extsnd.html#mussoundwrite", "extsnd.html#mussoundwritedate", "sndclm.html#mussrate", "sndclm.html#mus-width", "sndclm.html#mus-xcoeff", "sndclm.html#mus-xcoeffs", "sndclm.html#mus-ycoeff", "sndclm.html#mus-ycoeffs", "sndclm.html#n1cos", "sndclm.html#n1cos?", "extsnd.html#nameclickhook", "sndclm.html#nchoosekcos", "sndclm.html#nchoosekcos?", "sndclm.html#ncos", "sndclm.html#ncos2?", "sndclm.html#ncos4?", "sndclm.html#ncos?", "extsnd.html#newsound", "extsnd.html#newsounddialog", "extsnd.html#newsoundhook", "extsnd.html#newwidgethook", "extsnd.html#nextsample", "sndclm.html#nkssb", "sndclm.html#nkssbinterp", "sndclm.html#nkssb?", "sndclm.html#noddcos", "sndclm.html#noddcos?", "sndclm.html#noddsin", "sndclm.html#noddsin?", "sndclm.html#noddssb", "sndclm.html#noddssb?", "sndclm.html#noid", "extsnd.html#normalizechannel", "sndscm.html#normalizeenvelope", "sndclm.html#normalizepartials", "sndscm.html#normalizesound", "sndscm.html#normalizedmix", "sndclm.html#notch", "sndscm.html#notchchannel", "sndscm.html#notchselection", "sndscm.html#notchsound", "sndclm.html#notch?", "sndclm.html#npcos?", "sndclm.html#nrcos", "sndclm.html#nrcos?", "sndscm.html#nrev", "sndclm.html#nrsin", "sndclm.html#nrsin?", "sndclm.html#nrssb", "sndclm.html#nrssbinterp", "sndclm.html#nrssb?", "sndclm.html#nrxycos", "sndclm.html#nrxycos?", "sndclm.html#nrxysin", "sndclm.html#nrxysin?", "sndclm.html#nsin", "sndclm.html#nsin?", "sndclm.html#nsincos", "sndclm.html#nsincos?", "sndclm.html#nssb", "sndclm.html#nssb?", "sndclm.html#nxy1cos", "sndclm.html#nxy1cos?", "sndclm.html#nxy1sin", "sndclm.html#nxy1sin?", "sndclm.html#nxycos", "sndclm.html#nxycos?", "sndclm.html#nxysin", "sndclm.html#nxysin?", "s7.html#objecttostring", "sndclm.html#oddmultiple", "sndclm.html#oddweight", "sndscm.html#offsetchannel", "sndscm.html#offsetsound", "sndclm.html#one-pole", "sndclm.html#one-pole-all-pass", "sndclm.html#one-pole-all-pass?", "sndclm.html#one-pole?", "sndclm.html#one-zero", "sndclm.html#one-zero?", "extsnd.html#openfiledialog", "extsnd.html#openfiledialogdirectory", "extsnd.html#openhook", "sndscm.html#opennextfileindirectory", "extsnd.html#openrawsound", "extsnd.html#openrawsoundhook", "extsnd.html#opensound", "s7.html#openlet", "s7.html#openletp", "extsnd.html#orientationhook", "sndclm.html#oscil", "sndclm.html#oscil-bank", "sndclm.html#oscil-bank?", "sndclm.html#oscil?", "sndclm.html#out-any", "sndclm.html#outbank", "sndclm.html#outa", "s7.html#outlet", "sndclm.html#*output*", "extsnd.html#outputcommenthook", "sndscm.html#overlayrmsenv", "s7.html#owlet", "extsnd.html#padchannel", "sndscm.html#padmarks", "sndscm.html#padsound", "sndscm.html#panmix", "sndscm.html#panmixvct", "sndclm.html#partialstopolynomial", "sndclm.html#partialstowave", "extsnd.html#pausing", "extsnd.html#peakenvdir", "extsnd.html#peaks", "extsnd.html#peaksfont", "sndclm.html#phase-partialstowave", "sndclm.html#phase-vocoder", "sndclm.html#phase-vocoder?", "sndscm.html#pianodoc", "sndclm.html#pink-noise", "sndclm.html#pink-noise?", "sndscm.html#pins", "sndscm.html#placesound", "extsnd.html#play", "extsnd.html#playarrowsize", "sndscm.html#playbetweenmarks", "extsnd.html#playhook", "sndscm.html#playmixes", "sndscm.html#playoften", "sndscm.html#playregionforever", "sndscm.html#playsine", "sndscm.html#playsines", "sndscm.html#playsyncdmarks", "sndscm.html#playuntilcg", "sndscm.html#playwithenvs", "extsnd.html#playerhome", "extsnd.html#playerQ", "extsnd.html#players", "extsnd.html#playing", "sndscm.html#pluck", "sndclm.html#polartorectangular", "sndclm.html#polynomial", "sndscm.html#polydoc", "sndclm.html#polyoid", "sndclm.html#polyoidenv", "sndclm.html#polyoid?", "sndclm.html#polyshape", "sndclm.html#polyshape?", "sndclm.html#polywave", "sndclm.html#polywave?", "extsnd.html#positiontox", "extsnd.html#positiontoy", "extsnd.html#positioncolor", "sndscm.html#powerenv", "sndscm.html#pqw", "sndscm.html#pqwvox", "extsnd.html#preferencesdialog", "extsnd.html#previoussample", "extsnd.html#printdialog", "extsnd.html#printlength", "s7.html#proceduredocumentation", "s7.html#proceduresetter", "s7.html#proceduresignature", "s7.html#proceduresource", "s7.html#profile", "extsnd.html#progressreport", "sndclm.html#pulse-train", "sndclm.html#pulse-train?", "sndclm.html#pulsedenv", "sndclm.html#pulsedenv?", "sndclm.html#r2k!cos", "sndclm.html#r2k!cos?", "sndclm.html#r2k2cos", "sndclm.html#r2k2cos?", "sndclm.html#radianstodegrees", "sndclm.html#radianstohz", "extsnd.html#rampchannel", "sndclm.html#rand", "sndclm.html#rand-interp", "sndclm.html#rand-interp?", "sndclm.html#rand?", "s7.html#random", "s7.html#randomstate", "s7.html#randomstatep", "sndclm.html#rcos", "sndclm.html#rcos?", "extsnd.html#readhook", "extsnd.html#readmixsample", "extsnd.html#readonly", "extsnd.html#readregionsample", "extsnd.html#readsample", "extsnd.html#readsamplewithdirection", "s7.html#readercond", "sndclm.html#readin", "sndclm.html#readin?", "sndclm.html#rectangulartomagnitudes", "sndclm.html#rectangulartopolar", "extsnd.html#redo", "extsnd.html#regiontointeger", "extsnd.html#regiontovct", "extsnd.html#regionchans", "extsnd.html#regionframples", "extsnd.html#regiongraphstyle", "extsnd.html#regionhome", "extsnd.html#regionmaxamp", "extsnd.html#regionmaxampposition", "sndscm.html#regionplaylist", "extsnd.html#regionposition", "sndscm.html#regionrms", "extsnd.html#regionsample", "extsnd.html#regionsamplerQ", "extsnd.html#regionsrate", "extsnd.html#regionok", "extsnd.html#eregions", "extsnd.html#remembersoundstate", "sndscm.html#removeclicks", "extsnd.html#removefrommenu", "sndscm.html#replacewithselection", "sndscm.html#reportmarknames", "s7.html#requires7", "sndscm.html#resetallhooks", "extsnd.html#resetcontrols", "extsnd.html#resetlistenercursor", "sndscm.html#reson", "extsnd.html#restorecontrols", "sndclm.html#*reverb*", "extsnd.html#reverbdecay", "extsnd.html#reverbcontrolfeedback", "extsnd.html#reverbcontrollength", "extsnd.html#reverbcontrollengthbounds", "extsnd.html#reverbcontrollowpass", "extsnd.html#reverbcontrolscale", "extsnd.html#reverbcontrolscalebounds", "extsnd.html#reverbcontrolp", "s7.html#reverseb", "sndscm.html#reversebyblocks", "extsnd.html#reversechannel", "sndscm.html#reverseenvelope", "extsnd.html#reverseselection", "extsnd.html#reversesound", "extsnd.html#revertsound", "extsnd.html#rightsample", "sndclm.html#ring-modulate", "sndclm.html#rk!cos", "sndclm.html#rk!cos?", "sndclm.html#rk!ssb", "sndclm.html#rk!ssb?", "sndclm.html#rkcos", "sndclm.html#rkcos?", "sndclm.html#rkoddssb", "sndclm.html#rkoddssb?", "sndclm.html#rksin", "sndclm.html#rksin?", "sndclm.html#rkssb", "sndclm.html#rkssb?", "sndscm.html#rmsgain", "sndscm.html#rmsgain", "sndscm.html#rmsenvelope", "s7.html#rootlet", "sndclm.html#round-interp", "sndclm.html#round-interp?", "sndclm.html#rssb", "sndclm.html#rssbinterp", "sndclm.html#rssb?", "sndscm.html#rubbersound", "sndclm.html#rxycos", "sndclm.html#rxycos?", "sndclm.html#rxyk!cos", "sndclm.html#rxyk!cos?", "sndclm.html#rxyk!sin", "sndclm.html#rxyk!sin?", "sndclm.html#rxysin", "sndclm.html#rxysin?", "extsnd.html#sample", "sndclm.html#sampletofile", "sndclm.html#sampletofile?", "extsnd.html#sampletype", "extsnd.html#sampleratendQ", "extsnd.html#samplerhome", "extsnd.html#samplerposition", "extsnd.html#samplerQ", "extsnd.html#samples", "sndclm.html#samplestoseconds", "extsnd.html#sashcolor", "extsnd.html#saveasdialogautocomment", "extsnd.html#saveasdialogsrc", "extsnd.html#savecontrols", "extsnd.html#savedir", "extsnd.html#saveedithistory", "extsnd.html#saveenvelopes", "extsnd.html#savehook", "extsnd.html#savelistener", "sndscm.html#savemarkproperties", "extsnd.html#savemarks", "extsnd.html#savemix", "extsnd.html#saveregion", "extsnd.html#saveregiondialog", "extsnd.html#saveselection", "extsnd.html#saveselectiondialog", "extsnd.html#savesound", "extsnd.html#savesoundas", "extsnd.html#savesounddialog", "extsnd.html#savestate", "extsnd.html#savestatefile", "extsnd.html#savestatehook", "sndscm.html#sgfilter", "sndclm.html#sawtooth-wave", "sndclm.html#sawtooth-wave?", "extsnd.html#scaleby", "extsnd.html#scalechannel", "sndscm.html#scaleenvelope", "sndscm.html#scalemixes", "extsnd.html#scaleselectionby", "extsnd.html#scaleselectionto", "sndscm.html#scalesound", "sndscm.html#scaletempo", "extsnd.html#scaleto", "extsnd.html#scanchannel", "sndscm.html#dspdocscanned", "sndscm.html#scentroid", "sndscm.html#scratch", "extsnd.html#scriptarg", "extsnd.html#scriptargs", "sndscm.html#searchforclick", "extsnd.html#searchprocedure", "sndclm.html#secondstosamples", "extsnd.html#selectall", "extsnd.html#selectchannel", "extsnd.html#selectchannelhook", "extsnd.html#selectsound", "extsnd.html#selectsoundhook", "extsnd.html#selectedchannel", "extsnd.html#selecteddatacolor", "extsnd.html#selectedgraphcolor", "extsnd.html#selectedsound", "extsnd.html#selection", "extsnd.html#selectiontomix", "extsnd.html#selectionchans", "extsnd.html#selectioncolor", "extsnd.html#selectioncontext", "extsnd.html#selectioncreatesregion", "extsnd.html#selectionframples", "extsnd.html#selectionmaxamp", "extsnd.html#selectionmaxampposition", "extsnd.html#selectionmember", "sndscm.html#selectionmembers", "extsnd.html#selectionposition", "sndscm.html#selectionrms", "extsnd.html#selectionsrate", "extsnd.html#selectionok", "extsnd.html#setsamples", "extsnd.html#shortfilename", "extsnd.html#showaxes", "extsnd.html#showcontrols", "sndscm.html#showdiskspace", "extsnd.html#showfullduration", "extsnd.html#showfullrange", "extsnd.html#showgrid", "extsnd.html#showindices", "extsnd.html#showlistener", "extsnd.html#showmarks", "extsnd.html#showmixwaveforms", "extsnd.html#showselection", "extsnd.html#showselectiontransform", "extsnd.html#showsonogramcursor", "extsnd.html#showtransformpeaks", "extsnd.html#showwidget", "extsnd.html#showyzero", "sndscm.html#silenceallmixes", "sndscm.html#silencemixes", "sndclm.html#sinc-train", "sndclm.html#sinc-train?", "extsnd.html#sincwidth", "sndscm.html#sineenvchannel", "sndscm.html#sineramp", "sndscm.html#singerdoc", "extsnd.html#smoothchannel", "extsnd.html#smoothselection", "extsnd.html#smoothsound", "sndscm.html#pins", "sndscm.html#snapmarktobeat", "sndscm.html#snapmarks", "sndscm.html#snapmixtobeat", "extsnd.html#sndtosample", "extsnd.html#sndtosamplep", "extsnd.html#sndcolor", "extsnd.html#snderror", "extsnd.html#snderrorhook", "extsnd.html#sndfont", "extsnd.html#sndgcs", "extsnd.html#sndhelp", "sndscm.html#sndscmhooks", "extsnd.html#sndopenedsound", "extsnd.html#sndprint", "extsnd.html#sndspectrum", "extsnd.html#sndtempnam", "extsnd.html#sndurl", "extsnd.html#sndurls", "extsnd.html#sndversion", "extsnd.html#sndwarning", "extsnd.html#sndwarninghook", "sndscm.html#sndwarp", "s7.html#sortb", "sndscm.html#soundtoamp_env", "extsnd.html#soundtointeger", "extsnd.html#soundfileextensions", "extsnd.html#soundfilep", "extsnd.html#soundfilesindirectory", "sndscm.html#soundinterp", "extsnd.html#soundloopinfo", "extsnd.html#soundproperties", "extsnd.html#soundproperty", "extsnd.html#soundwidgets", "extsnd.html#soundp", "extsnd.html#soundfontinfo", "extsnd.html#sounds", "sndscm.html#soundstosegmentdata", "sndscm.html#spectra", "sndscm.html#twotab", "sndscm.html#spectralpolynomial", "extsnd.html#spectrohop", "extsnd.html#spectroxangle", "extsnd.html#spectroxscale", "extsnd.html#spectroyangle", "extsnd.html#spectroyscale", "extsnd.html#spectrozangle", "extsnd.html#spectrozscale", "sndclm.html#spectrum", "sndscm.html#spectrumtocoeffs", "extsnd.html#spectrumend", "extsnd.html#spectrumstart", "extsnd.html#speedcontrol", "extsnd.html#speedcontrolbounds", "extsnd.html#speedstyle", "extsnd.html#speedtones", "sndscm.html#spotfreq", "sndclm.html#square-wave", "sndclm.html#square-wave?", "extsnd.html#squelchupdate", "sndscm.html#squelchvowels", "extsnd.html#srate", "sndclm.html#src", "extsnd.html#srcchannel", "sndscm.html#srcduration", "sndscm.html#srcfitenvelope", "sndscm.html#srcmixes", "extsnd.html#srcsoundselection", "extsnd.html#srcsound", "sndclm.html#src?", "sndclm.html#ssb-am", "sndclm.html#ssb-am?", "sndscm.html#ssbbank", "sndscm.html#ssbbankenv", "sndscm.html#ssbfm", "sndscm.html#startdac", "extsnd.html#startplaying", "extsnd.html#startplayinghook", "extsnd.html#startplayingselectionhook", "extsnd.html#startprogressreport", "extsnd.html#statusreport", "sndscm.html#stereotomono", "sndscm.html#stereoflute", "extsnd.html#stopplayer", "extsnd.html#stopplaying", "extsnd.html#stopplayinghook", "extsnd.html#stopplayingselectionhook", "sndscm.html#stretchenvelope", "sndscm.html#stretchsoundviadft", "s7.html#stringposition", "s7.html#sublet", "sndscm.html#superimposeffts", "extsnd.html#swapchannels", "sndscm.html#swapselectionchannels", "s7.html#symboltodynamicvalue", "s7.html#symboltovalue", "s7.html#symbolaccess", "s7.html#symboltable", "extsnd.html#sync", "sndscm.html#sync-everything", "extsnd.html#syncmax", "extsnd.html#syncstyle", "extsnd.html#syncdmarks", "sndscm.html#syncdmixes", "sndscm.html#syncup", "sndclm.html#table-lookup", "sndclm.html#table-lookup?", "sndclm.html#tanhsin", "sndclm.html#tanhsin?", "sndclm.html#tap", "sndclm.html#tap?", "sndscm.html#telephone", "extsnd.html#tempdir", "extsnd.html#textfocuscolor", "extsnd.html#timegraphstyle", "extsnd.html#timegraphtype", "extsnd.html#timegraphp", "sndclm.html#timestosamples", "extsnd.html#tinyfont", "sndscm.html#telephone", "s7.html#trace", "extsnd.html#trackingcursorstyle", "extsnd.html#transformtointeger", "extsnd.html#transformtovct", "extsnd.html#transformdialog", "extsnd.html#transformframples", "extsnd.html#transformgraphstyle", "extsnd.html#transformgraphtype", "extsnd.html#transformgraphp", "extsnd.html#normalizefft", "extsnd.html#transformsample", "extsnd.html#transformsize", "extsnd.html#transformtype", "extsnd.html#transformp", "sndscm.html#transposemixes", "sndclm.html#triangle-wave", "sndclm.html#triangle-wave?", "sndscm.html#tubebell", "sndscm.html#tubebell", "sndclm.html#two-pole", "sndclm.html#two-pole?", "sndscm.html#twotab", "sndclm.html#two-zero", "sndclm.html#two-zero?", "extsnd.html#unbindkey", "s7.html#unboundvariablehook", "sndscm.html#unclipchannel", "extsnd.html#undo", "extsnd.html#undohook", "s7.html#unlet", "extsnd.html#unselectall", "sndscm.html#updategraphs", "extsnd.html#updatehook", "extsnd.html#updatelispgraph", "extsnd.html#updatesound", "extsnd.html#updatetimegraph", "extsnd.html#updatetransformgraph", "sndscm.html#uponsaveyourself", "sndscm.html#sndmotifdoc", "sndscm.html#variabledisplay", "extsnd.html#variablegraphp", "s7.html#varlet", "extsnd.html#vct", "extsnd.html#vcttimes", "extsnd.html#vctplus", "extsnd.html#vcttochannel", "extsnd.html#vcttolist", "extsnd.html#vcttostring", "extsnd.html#vcttovector", "extsnd.html#vctabs", "extsnd.html#vctadd", "extsnd.html#vctcopy", "extsnd.html#vctequal", "extsnd.html#vctfill", "extsnd.html#vctlength", "extsnd.html#vctmax", "extsnd.html#vctmin", "extsnd.html#vctmove", "extsnd.html#vctmultiply", "extsnd.html#vctoffset", "extsnd.html#vctpeak", "extsnd.html#vctref", "extsnd.html#vctreverse", "extsnd.html#vctscale", "extsnd.html#vctset", "extsnd.html#vctsubseq", "extsnd.html#vctsubtract", "extsnd.html#vctp", "extsnd.html#vectortovct", "extsnd.html#viewfilesamp", "extsnd.html#viewfilesampenv", "extsnd.html#viewfilesdialog", "extsnd.html#viewfilesfiles", "extsnd.html#viewfilesselecthook", "extsnd.html#viewfilesselectedfiles", "extsnd.html#viewfilessort", "extsnd.html#viewfilesspeed", "extsnd.html#viewfilesspeedstyle", "extsnd.html#viewmixesdialog", "extsnd.html#viewregionsdialog", "extsnd.html#viewsound", "sndscm.html#singerdoc", "sndscm.html#voicedtounvoiced", "sndscm.html#volterrafilter", "sndscm.html#fmvox", "sndclm.html#wave-train", "sndclm.html#wave-train?", "extsnd.html#wavelettype", "sndscm.html#pqwvox", "extsnd.html#wavohop", "extsnd.html#wavotrace", "sndclm.html#weighted-moving-average", "extsnd.html#widgetposition", "extsnd.html#widgetsize", "extsnd.html#widgettext", "extsnd.html#windowheight", "sndscm.html#windowsamples", "extsnd.html#windowwidth", "extsnd.html#windowx", "extsnd.html#windowy", "extsnd.html#withbackgroundprocesses", "s7.html#withbaffle", "extsnd.html#withfilemonitor", "extsnd.html#withgl", "extsnd.html#withinsetgraph", "extsnd.html#withinterrupts", "s7.html#with-let", "sndscm.html#withlocalhook", "extsnd.html#withmenuicons", "extsnd.html#withmixtags", "extsnd.html#withpointerfocus", "extsnd.html#withrelativepanes", "extsnd.html#withsmptelabel", "sndscm.html#withsound", "sndscm.html#withtemporaryselection", "extsnd.html#withtoolbar", "extsnd.html#withtooltips", "extsnd.html#withtrackingcursor", "extsnd.html#withverbosecursor", "extsnd.html#xtoposition", "extsnd.html#xaxislabel", "extsnd.html#xaxisstyle", "extsnd.html#xbounds", "extsnd.html#xpositionslider", "extsnd.html#xzoomslider", "sndscm.html#xbopen", "extsnd.html#xrampchannel", "extsnd.html#ytoposition", "extsnd.html#yaxislabel", "extsnd.html#ybounds", "extsnd.html#ypositionslider", "extsnd.html#yzoomslider", "sndscm.html#ztransform", "sndscm.html#zecho", "sndscm.html#zeroplus", "extsnd.html#zeropad", "sndscm.html#zerophase", "sndscm.html#zipsound", "sndscm.html#zipper", "extsnd.html#zoomcolor", "extsnd.html#zoomfocusstyle"}; static const char *Tracking_cursors_xrefs[] = { "play from the current cursor position with a tracking cursor: {pfc}", "display tracking cursor as a full height vertical line: {tracking-cursor-style}", "track play once: control-click 'play'. (You can add a mark at the current tracking cursor location during the play with C-m)", "leave the cursor at the final position after tracking play: (set! *with-tracking-cursor* :track-and-stay)", "tracking cursor accuracy: {cursor-location-offset}", "tracking cursor updating: {cursor-update-interval}", NULL}; static const char *Tracking_cursors_urls[] = { "extsnd.html#pfc", "extsnd.html#trackingcursorstyle", NULL, NULL, "extsnd.html#cursorlocationoffset", "extsnd.html#cursorupdateinterval", NULL}; static const char *Copying_xrefs[] = { "copy file: in Scheme: copy-file, in Ruby: File.copy or File.syscopy", "copy string: in Forth: string-copy", "copy list: in Forth: list-copy or copy-tree", "copy mix: {mix->float-vector}", "copy sampler: {copy-sampler}", "copy (clone) current sound edit state: {clone-sound-as}", "copy channel data: {channel->float-vector}, or {save-sound-as}", "copy selection data: {selection->float-vector} or {save-selection}", "copy region data: {region->float-vector}, {save-region}", "copy transform data: {transform->float-vector}", NULL}; static const char *Copying_urls[] = { NULL, NULL, NULL, "sndscm.html#mixtovct", "extsnd.html#copysampler", "extsnd.html#clonesoundas", "extsnd.html#channeltovct", "extsnd.html#selection2vct", "extsnd.html#regiontovct", "extsnd.html#transformtovct", NULL}; static const char *Marking_xrefs[] = { "{Marks}", "find mark in any sound: {mark-name->id}", "mark history: {describe-mark}", "synchronize marks by inserting silences: {syncup}", "squeeze selection between marks: {fit-selection-between-marks}", "insert silence before marks: {pad-marks}", "move syncd marks: {move-syncd-marks}", "play starting from syncd marks: {play-syncd-marks}", "place marks at selection start and end: {snap-marks}", "define selection via marks: {define-selection-via-marks}", "force dragged mark to land on a beat: {snap-mark-to-beat}", "split sound into separate files based on mark placement: {mark-explode}", "mark property lists: {mark-property}", "save mark properties in saved state file: {save-mark-properties}", "show mark properties upon click: {mark-click-info}", NULL}; static const char *Marking_urls[] = { NULL, "sndscm.html#marknametoid", "sndscm.html#describemark", "sndscm.html#syncup", "sndscm.html#fitselectionbetweenmarks", "sndscm.html#padmarks", "sndscm.html#movesyncdmarks", "sndscm.html#playsyncdmarks", "sndscm.html#snapmarks", "sndscm.html#defineselectionviamarks", "sndscm.html#snapmarktobeat", "sndscm.html#markexplode", "extsnd.html#markproperty", "sndscm.html#savemarkproperties", "sndscm.html#markclickinfo", NULL}; static const char *Mixing_xrefs[] = { "{Mixing}", "mix sound file: {mix} or drag-and-drop it where you want it mixed", "mix channel: see {mix-channel} in extensions.scm", "mix region: {mix-region}", "mix selection: {mix-selection}", "mix vct: {mix-vct}", "enveloped mix: see {enveloped-mix} in extensions.scm", "read mix samples: {make-mix-sampler}", "mix data maxamp: {mix-maxamp}", "mix data to vct: {mix->vct}", "save mix data in file: {save-mix}", "mix property list: {mix-property} in mix.scm", "pan mono sound into stereo: see {place-sound} in examp.scm", "move a mixed sound via dlocsig: {mix-move-sound}", "the mix dialog: {Mix Dialog}", "cross-fade in frequency: cross-fade and dissolve-fade in {fade.scm}", "zipper cross-fade: {zipper.scm}", "snap mix to beat after drag: {snap-mix-to-beat}", "delete all mixes: {silence-all-mixes}", "with-sound (a notelist) expanded into mixes: {with-mixed-sound}", NULL}; static const char *Mixing_urls[] = { NULL, "extsnd.html#mix", "sndscm.html#mixchannel", "extsnd.html#mixregion", "extsnd.html#mixselection", "extsnd.html#mixvct", "sndscm.html#envelopedmix", "extsnd.html#makemixsampler", "sndscm.html#mixmaxamp", "sndscm.html#mixtovct", "extsnd.html#savemix", "extsnd.html#mixproperty", "sndscm.html#placesound", "extsnd.html#mixmovesound", "snd.html#mixdialog", "sndscm.html#fadedoc", "sndscm.html#zipdoc", "sndscm.html#snapmixtobeat", "sndscm.html#silenceallmixes", "sndscm.html#withmixedsound", NULL}; static const char *Regions_xrefs[] = { "{Regions}", "Max length of region list: {max-regions}", "Whether selection creates a region: {selection-creates-region}", "To play region repeatedly: {play-region-forever}", "Start region browser from Scheme: {view-regions-dialog}", "All about regions: {regions}", "The region dialog: {region browser}", "Region rms amp: {region-rms}", "region-play-list and region-play-sequence in examp.scm", NULL}; static const char *Regions_urls[] = { NULL, "extsnd.html#maxregions", "extsnd.html#selectioncreatesregion", "sndscm.html#playregionforever", "extsnd.html#viewregionsdialog", "snd.html#regions", "snd.html#regionbrowser", "sndscm.html#regionrms", NULL, NULL}; static const char *Selections_xrefs[] = { "{Selections}", "show the current selection: {show-selection}", "color of selected portion: {selection-color}", "set whether creating a selection creates a region: {selection-creates-region}", "fft graph refers to the selection: {show-selection-transform}", "hook called when selection stops playing: {stop-playing-selection-hook}", "swap chans in selected portion: {swap-selection-channels}", "replace portion with selection: {replace-with-selection}", "select portion via function: {make-selection}", "selection members as list of lists of sound indices and channels: {selection-members}", "rms of selection data: {selection-rms}", "delete selection and smooth the splice: {delete-selection-and-smooth}", "select portion between two marks: {define-selection-via-marks}", "place marks at selection start and end: {snap-marks}", "squeeze selection between marks: {fit-selection-between-marks}", "delete selection and write it to a file: {cut-selection->new}", "append selection: {append-selection}", "write selection to a file: {selection->new}", "notch filter selection: {notch-selection}", "undo select-all.: {deselect-all}", "filter the selection: {filter-selection}, {filter-selection-and-smooth}", "turn the selection into a mix: {selection->mix}", "unselect everything: {unselect-all}", NULL}; static const char *Selections_urls[] = { NULL, "extsnd.html#showselection", "extsnd.html#selectioncolor", "extsnd.html#selectioncreatesregion", "extsnd.html#showselectiontransform", "extsnd.html#stopplayingselectionhook", "sndscm.html#swapselectionchannels", "sndscm.html#replacewithselection", "sndscm.html#makeselection", "sndscm.html#selectionmembers", "sndscm.html#selectionrms", "extsnd.html#deleteselectionandsmooth", "sndscm.html#defineselectionviamarks", "sndscm.html#snapmarks", "sndscm.html#fitselectionbetweenmarks", "sndscm.html#menusdoc", "sndscm.html#menusdoc", "sndscm.html#menusdoc", "sndscm.html#notchselection", "sndscm.html#menusdoc", "extsnd.html#filterselection", "extsnd.html#selectiontomix", "extsnd.html#unselectall", NULL}; static const char *Cursors_xrefs[] = { "Tracking cursor: {with-tracking-cursor}", "Change cursor shape or size: {cursor-style}, {cursor-size}", "Cursor moving keys: {Moving the Cursor}", "Display data about sample under cursor: {with-verbose-cursor}", "play from the current cursor position with a tracking cursor: {pfc}", "display tracking cursor as a full height vertical line: {tracking-cursor-style}", "track play once: control-click 'play'. (You can add a mark at the current tracking cursor location during the play with C-m)", "leave the cursor at the final position after tracking play: (set! *with-tracking-cursor* :track-and-stay)", "tracking cursor accuracy: {cursor-location-offset}", "tracking cursor updating: {cursor-update-interval}", NULL}; static const char *Cursors_urls[] = { "extsnd.html#withtrackingcursor", "extsnd.html#cursorstyle", "snd.html#movecursor", "extsnd.html#withverbosecursor", "extsnd.html#pfc", "extsnd.html#trackingcursorstyle", NULL, NULL, "extsnd.html#cursorlocationoffset", "extsnd.html#cursorupdateinterval", NULL}; static const char *Deletions_xrefs[] = { "delete a file: in scheme delete-file or Ruby's File.delete", "delete a region: {forget-region}", "delete the currently selected samples: {delete-selection}", "delete the selection and smooth the splice: {delete-selection-and-smooth}", "delete a mark or all marks: {delete-mark}", "delete a colormap: {delete-colormap}", "delete samples: {delete-samples}", "delete samples and smooth over the splice: {delete-samples-and-smooth}", "remove a file from the sound cache: {mus-sound-forget}", "remove a menu item: {remove-from-menu} or remove-main-menu in snd-motif.scm", "delete a mix or all mixes: {silence-mixes}", "add a 'delete' option to the file selection dialog: {add-delete-option}", "Scheme delete funcs: remove-if assoc-remove! hash-remove! delete-if! delete! string-delete", NULL}; static const char *Deletions_urls[] = { NULL, "extsnd.html#forgetregion", "extsnd.html#deleteselection", "extsnd.html#deleteselectionandsmooth", "extsnd.html#deletemark", "extsnd.html#deletecolormap", "extsnd.html#deletesamples", "extsnd.html#deletesamplesandsmooth", "extsnd.html#mussoundforget", "extsnd.html#removefrommenu", "sndscm.html#silenceallmixes", "sndscm.html#adddeleteoption", NULL, NULL}; static const char *Envelopes_xrefs[] = { "envelope sound: {env-channel}, {env-sound}", "Other enveloping functions: {ramp-channel}, {xramp-channel}, {smooth-channel}", "The CLM env generator: {env}, many examples in examp.scm, new-effects.scm, etc", "Various operations on envelopes: {env.scm}", "The envelope editor: {Edit or View and Envelope}", "Panning: place-sound in examp.scm", "Envelope over mix: {enveloped-mix}", "Local envelope editor: {enved.scm}, xm-enved.scm", "Read sound indexed through envelope: {env-sound-interp}", "Cosine as envelope: {cosine-channel}, {bell-curve}", "envelope with sinusoidal connections between points: {sine-env-channel}", "envelope with separate base for each segment: {powenv-channel}", "envelope with x^2 connections: {env-squared-channel}", "envelope with x^n connections: {env-expt-channel}", "envelope with {ncos} connections: {blackman4-env-channel}", "Customizing the envelope editor: {enved-hook}", "peak amp follower: {moving-max}", NULL}; static const char *Envelopes_urls[] = { "extsnd.html#envchannel", "extsnd.html#rampchannel", "sndclm.html#make-env", "sndscm.html#envdoc", "snd.html#editenvelope", NULL, "sndscm.html#envelopedmix", "sndscm.html#enveddoc", "sndscm.html#envsoundinterp", "extsnd.html#cosinechannel", "sndscm.html#sineenvchannel", "sndscm.html#powenvchannel", "sndscm.html#envsquaredchannel", "sndscm.html#envexptchannel", "sndclm.html#ncos", "extsnd.html#envedhook", "sndclm.html#moving-max", NULL}; static const char *Filters_xrefs[] = { "filter a sound: {filter-sound}, {filter-channel}, and {clm-channel}", "filter the selection: {filter-selection}, {filter-selection-and-smooth}", "CLM filter generators: {filter, one-pole, formant, comb, notch, all-pass, etc}", "lowpass filter: {make-lowpass} in dsp.scm", "highpass filter: {make-highpass} in dsp.scm", "bandpass filter: {make-bandpass} in dsp.scm", "bandstop filter: {make-bandstop} in dsp.scm", "the usual analog filters (Butterworth, Chebyshev, Bessel, Elliptic): {analog-filter.scm}", "Butterworth filters: {make-butter-high-pass}, make-butter-low etc in dsp.scm, used in new-effects.scm", "IIR filters of various orders/kinds: {dsp.scm}", "Hilbert transform: {make-hilbert-transform} in dsp.scm", "differentiator: {make-differentiator} in dsp.scm", "block DC: see example above, dc-block in prc95.scm, or stereo-flute in clm-ins.scm", "hum elimination: see {eliminate-hum} and {notch-channel} in dsp.scm", "hiss elimination: {notch-out-rumble-and-hiss}", "smoothing filters: {moving-average}, {weighted-moving-average}, exponentially-weighted-moving-average", "notch-filters: {notch-channel} and {notch-selection}", "arbitrary spectrum via FIR filter: {spectrum->coeffs} in dsp.scm", "invert an FIR filter: {invert-filter} in dsp.scm", "filtered echo sound effect: {flecho} in examp.scm", "time varying filter: fltit in examp.scm", "draw frequency response: use {envelope editor} or {filter control} in control panel", "Moog filter: {moog.scm}", "Savitzky-Golay filter: {savitzky-golay-filter}", "Click reduction: {remove-clicks}, {clean-channel}", "Max Mathews resonator: {firmant}, {maxf.scm, maxf.rb}", "Spectral edit dialog: {Envelope Editor}", "graphical equalizer filter bank: {graphEq}", "nonlinear (Volterra) filter: {volterra-filter}", "Kalman filter: {kalman-filter-channel}", "see also convolution, physical modeling, reverb, and {fft-based filtering}", NULL}; static const char *Filters_urls[] = { "extsnd.html#filtersound", "extsnd.html#filterselection", "sndclm.html#filterdoc", "sndscm.html#makelowpass", "sndscm.html#makehighpass", "sndscm.html#makebandpass", "sndscm.html#makebandstop", "sndscm.html#analogfilterdoc", "sndscm.html#makebutter", "sndscm.html#IIRfilters", "sndscm.html#makehilberttransform", "sndscm.html#makedifferentiator", NULL, "sndscm.html#IIRfilters", "sndscm.html#notchoutrumbleandhiss", "sndclm.html#moving-average", "sndscm.html#notchchannel", "sndscm.html#spectrumtocoeffs", "sndscm.html#invertfilter", "sndscm.html#zecho", NULL, "snd.html#editenvelope", "sndscm.html#moogdoc", "sndscm.html#sgfilter", "sndscm.html#removeclicks", "sndclm.html#firmant", "snd.html#editenvelope", "sndscm.html#clminsdoc", "sndscm.html#volterrafilter", "sndscm.html#kalmanfilterchannel", "sndscm.html#ssffts", NULL}; static const char *Searching_xrefs[] = { "find a mark: {find-mark}", "find a mix: {find-mix}", "find a sound: {find-sound}", "Example find procedures: {search-for-click, zero+, next-peak, find-pitch}", "Default search procedure: {search-procedure}", "The Find dialog: {Find} or {find-dialog}", "find silence: {map-silence}, scramble-channel in examp.scm", "find any difference between two chans: {channels-equal}", "find a widget: find-child in snd-motif.scm", "add C-s and C-r to the listener key bindings: add-find-to-listener in snd-motif.scm", "Scheme find: find-if", NULL}; static const char *Searching_urls[] = { "extsnd.html#findmark", "sndscm.html#findmix", "extsnd.html#findsound", "sndscm.html#searchforclick", "extsnd.html#searchprocedure", "snd.html#editoperations", "extsnd.html#mapsilence", "sndscm.html#channelsequal", NULL, NULL, NULL, NULL}; static const char *Insertions_xrefs[] = { "insert some portion of a channel: {insert-channel}", "insert a silence: {pad-channel}, {insert-silence}, {pad-sound}", "insert a region: {insert-region}", "insert the selection: {insert-selection}", "insert a vct of samples: {insert-samples}", "insert a sound: {insert-sound}", "append a sound and silence: {append-sound}", NULL}; static const char *Insertions_urls[] = { "sndscm.html#insertchannel", "extsnd.html#padchannel", "extsnd.html#insertregion", "extsnd.html#insertselection", "extsnd.html#insertsamples", "extsnd.html#insertsound", "extsnd.html#appendsound", NULL}; static const char *Window_size_and_position_xrefs[] = { "Built-in keyboard commands: {Moving the Window}", "Specialized keyboard commands: {bind-key}", "Window size: {x-zoom-slider}, {zoom-one-pixel}, ", "Window position: {x-position-slider}, {move-one-pixel}", "Window left edge: {left-sample}", "Window right edge: {right-sample}", "fft window:", "window size: drag x axis, {spectrum-end}", "window start: {spectrum-start}", "relation to time domain: {before-transform-hook}", "selection fft: {show-selection-transform}", "general info:", "Axis description: {axis-info}", NULL}; static const char *Window_size_and_position_urls[] = { "snd.html#movewindow", "extsnd.html#bindkey", "extsnd.html#xzoomslider", "extsnd.html#xpositionslider", "extsnd.html#leftsample", "extsnd.html#rightsample", NULL, "extsnd.html#spectrumend", "extsnd.html#spectrumstart", "extsnd.html#beforetransformhook", "extsnd.html#showselectiontransform", NULL, "extsnd.html#axisinfo", NULL}; static const char *Maxamps_xrefs[] = { "Sound file maxamp: {mus-sound-maxamp}", "Region maxamp: {region-maxamp}", "Selection maxamp: {selection-maxamp}", "To set the y axis bounds to reflect the channel's maxamp: {y-bounds}", "Mix maxamp: {mix-maxamp}", "maxamp locations: {maxamp-position}, {region-maxamp-position}, {selection-maxamp-position}", NULL}; static const char *Maxamps_urls[] = { "extsnd.html#mussoundmaxamp", "extsnd.html#regionmaxamp", "extsnd.html#selectionmaxamp", "extsnd.html#ybounds", "sndscm.html#mixmaxamp", "extsnd.html#maxampposition", NULL}; static const char *Playing_xrefs[] = { "play from cursor: C-q and example above", "play from cursor with tracking cursor: {pfc} above", "play the selection: (play (selection)), {C-x p}", "play a region: (play region-object), {C-x p}, play button in Region dialog", "play a mix: (play mix-object), play button in Mix dialog", "play a sequence of mixes: {play-mixes}", "play from mark: click or drag triangle (control-click for all chans)", "stop playing: C-g, C-t, {stop-playing}, set {playing} to #f", "pause or resume playback: space, set {pausing}", "play repeatedly: {play-often}", "play repeatedly until C-g: {play-until-c-g}", "play region repeatedly: {play-region-forever}", "play a file upon a keystroke: {bind-key}", "play using an external program: (system \"sndplay wood16.wav\")", "play a sine-wave or spectrum: {play-sine} and {play-sines}", "play arbitrary mixtures of things: {make-player} and related functions, {play-syncd-marks}", "play with applied amplitude envelope: {play-with-envs}", "play an external file: (play \"file\")", NULL}; static const char *Playing_urls[] = { NULL, "extsnd.html#pfc", "snd.html#cxp", "snd.html#cxp", NULL, "sndscm.html#playmixes", NULL, "extsnd.html#stopplaying", "extsnd.html#pausing", "sndscm.html#playoften", "sndscm.html#playuntilcg", "sndscm.html#playregionforever", "extsnd.html#extendedpiano", NULL, "sndscm.html#playsine", "extsnd.html#makeplayer", "sndscm.html#playwithenvs", NULL, NULL}; static const char *Reversing_xrefs[] = { "reverse channel: {reverse-channel}, {reverse-sound}", "reverse selected portion: {reverse-selection}", "read samples in reverse: use {make-sampler} with direction -1", "reverse at new sampling rate: use {src-channel} with a negative ratio", "Reverse in control panel: {control panel} and {speed-control} variable", "reverse an envelope: {reverse-envelope}", "reverse block-wise: {reverse-by-blocks and reverse-within-blocks}", "reverse via FFT: {silly-reverse}", "reverse order of channels: {reverse-channels}", "reverse a list: reverse and reverse!", "reverse a string: in Ruby: reverse", "reverse vct: {vct-reverse!}", NULL}; static const char *Reversing_urls[] = { "extsnd.html#reversechannel", "extsnd.html#reverseselection", "extsnd.html#makesampler", "extsnd.html#srcchannel", "snd.html#speed", "sndscm.html#reverseenvelope", "sndscm.html#reversebyblocks", "extsnd.html#sillyreverse", "extsnd.html#reversechannels", NULL, NULL, "extsnd.html#vctreverse", NULL}; static const char *Saving_xrefs[] = { "save sound: {save-sound}", "save all sounds: (for-each save-sound (sounds))", "save a sound under a different name: {save-sound-as}", "extract one channel from a sound: {extract-channel}", "extract a set of channels from a sound: {extract-channels}", "save a sound in a different sample type or header: {save-sound-as}", "backup edits automatically: {autosave}", "check first for unsaved edits: {ask-about-unsaved-edits}", "save Snd's complete state (unsaved edits and all): {save-state}, {save-dir}, {save-state-hook}, {save-state-file}", "save the selection: {save-selection}", "save a region: {save-region}", "save a mix: {save-mix}", "save the control panel state: {save-controls}", "save currently defined envelopes (envelope editor): {save-envelopes}", "start the file save dialog: {save-sound-dialog}", "start the selection save dialog: {save-selection-dialog}", "start the region save dialog: {save-region-dialog}", "save the current listener text: {save-listener}", "save marks: {save-marks}", "save just the edit history: {save-edit-history}", "take some action upon a window manager save-yourself signal: {upon-save-yourself}", "save the current sound setup for a later reopen: {remember-sound-state}", "save the current fft peak info: {peaks}", NULL}; static const char *Saving_urls[] = { "extsnd.html#savesound", NULL, "extsnd.html#savesoundas", "extsnd.html#extractchannel", "extsnd.html#extractchannels", "extsnd.html#savesoundas", "sndscm.html#autosavedoc", "extsnd.html#askaboutunsavededits", "extsnd.html#savestate", "extsnd.html#saveselection", "extsnd.html#saveregion", "extsnd.html#savemix", "extsnd.html#savecontrols", "extsnd.html#saveenvelopes", "extsnd.html#savesounddialog", "extsnd.html#saveselectiondialog", "extsnd.html#saveregiondialog", "extsnd.html#savelistener", "extsnd.html#savemarks", "extsnd.html#saveedithistory", "sndscm.html#uponsaveyourself", "extsnd.html#remembersoundstate", "extsnd.html#peaks", NULL}; static const char *Smoothing_xrefs[] = { "smooth channel: {smooth-channel}", "smooth all channels: {smooth-sound}", "smooth selection: {smooth-selection}", "delete the selection and smooth the splice: {delete-selection-and-smooth}", "smoothing via fft: {fft-smoother}", "smooth via low-pass {filter}", "smooth over click: {remove-clicks} in examp.scm", NULL}; static const char *Smoothing_urls[] = { "extsnd.html#smoothchannel", "extsnd.html#smoothsound", "extsnd.html#smoothselection", "extsnd.html#deleteselectionandsmooth", "sndscm.html#fftsmoother", "extsnd.html#filtersinsnd", "sndscm.html#removeclicks", NULL}; static const char *Resampling_xrefs[] = { "resample channel: {src-channel}", "resample all chans: {src-sound}", "resample selection: {src-selection}", "resample mix: speed control in {Mix dialog} (also {apply-controls})", "resample via drawn envelope: srate in {Envelope editor}", "resample via CLM gen: {src}", "resample with independent time control (ssb-am): {ssb-bank} in dsp.scm", "resample with independent time control (granulate): expand in {control panel}, {expsrc} and {expsnd}", "resample with independent time control (vocoder): {phase-vocoder} (this never works)", "another time stretcher (autocorrelation):{rubber-sound} (this takes forever and rarely works)", "resampling-based sound effects: {hello-dentist}, {fp}, flange and chorus in dsp.scm and new-effects.scm", "the digital zipper: {zipper}", "resample via FFT: {down-oct}", "resample through env: {sound-interp} and {env-sound-interp}", "resample through list: {scratch}", "resample step-size through a function: {step-src}", "predict duration of resampled sound: {src-duration}", "linear src: linear-src-channel in dsp.scm", NULL}; static const char *Resampling_urls[] = { "extsnd.html#srcchannel", "extsnd.html#srcsound", "extsnd.html#srcsoundselection", "snd.html#mixdialog", "snd.html#editenvelope", "sndclm.html#src", "sndscm.html#ssbbank", "extsnd.html#customcontrols", "sndclm.html#phase-vocoder", "sndscm.html#rubbersound", "sndscm.html#hellodentist", "sndscm.html#zipdoc", "sndscm.html#downoct", "sndscm.html#soundinterp", "sndscm.html#scratch", "extsnd.html#setsamples", "sndscm.html#srcduration", NULL, NULL}; static const char *Undo_and_Redo_xrefs[] = { "undo edit: {undo} and {undo-channel}", "undo all edits: {revert-sound}", "specialize undo: {undo-hook}", "protect against undo: {edit-hook}", "redo edit: {redo} and {redo-channel}", "move around in edit list: {edit-position} and {current-edit-position}", "About edit lists: {Edit lists}", NULL}; static const char *Undo_and_Redo_urls[] = { "extsnd.html#undo", "extsnd.html#revertsound", "extsnd.html#undohook", "extsnd.html#edithook", "extsnd.html#redo", "extsnd.html#editposition", "extsnd.html#editlists", NULL}; static const char *FFTs_xrefs[] = { "CLM fft function: {mus-fft}", "CLM spectrum: {spectrum}", "Snd spectrum: {snd-spectrum}", "autocorrelation: {autocorrelate}", "cross correlation: {correlate}, {display-correlation}", "FFT window: {make-fft-window}", "Dolph-Chebyshev window in Scheme: {dolph}", "Hartley transform in Scheme: {dht}", "Spectral edit dialog: {Envelope Editor}", "fft-based filter: {fft-edit}, {fft-env-edit}, {fft-env-interp}, {fft-squelch}, {fft-cancel}", "phase-vocoder: {phase-vocoder}. {pvoc}", "transposition via fft: {down-oct}", "phase rotation via fft: {zero-phase, rotate-phase}", "duration change via autocorrelation: {rubber-sound}", "smoothing via fft: {fft-smoother}", "cross-synthesis: {cross-synthesis}", "voiced->unvoiced effect: {voiced->unvoiced}", "noise reduction: {clean-channel}, {anoi}", "power spectral density: green.scm", "spectral modeling: {pins}", "polynomial approach to spectral multiplies (convolution): {spectral-polynomial}", "Superimpose ffts: {superimpose-ffts}", "More transforms: {fractional-fourier-transform}, {z-transform} in dsp.scm", "3D (single) fft display: {complexify}", "bark, mel, erb scale display: {display-bark-fft}", "apply function to spectrum, inverse fft: {filter-fft}", NULL}; static const char *FFTs_urls[] = { "sndclm.html#fft", "sndclm.html#spectrum", "extsnd.html#sndspectrum", "sndclm.html#autocorrelate", "sndclm.html#correlate", "sndclm.html#make-fft-window", "sndscm.html#dolph", "sndscm.html#dht", "snd.html#editenvelope", "sndscm.html#fftedit", "sndclm.html#phase-vocoder", "sndscm.html#downoct", "sndscm.html#zerophase", "sndscm.html#rubberdoc", "sndscm.html#fftsmoother", "sndscm.html#crosssynthesis", "sndscm.html#voicedtounvoiced", "sndscm.html#cleanchannel", NULL, "sndscm.html#clminsdoc", "sndscm.html#spectralpolynomial", "sndscm.html#superimposeffts", "sndscm.html#fractionalfouriertransform", "sndscm.html#complexify", "sndscm.html#displaybarkfft", "sndscm.html#filterfft", NULL}; static const char *Colors_xrefs[] = { "{Colors}", "Other color-related stuff:", "Color names: {rgb.scm, rgb.rb}", "colors in the file dialogs: install-searcher-with-colors in snd-motif.scm", "color-orientation-dialog: {color-orientation-dialog}", "colored samples: {display-colored-samples} and others in draw.scm", "colored edits: {display-previous-edits} in draw.scm", "colored marks: mark-sync-color in snd-motif.scm", "colors in rxvt: red-text et al in examp.scm", "flashing colors: flash-selected-data in examp.scm", "openGL: snd-gl.scm, {Snd and OpenGL}", "color hook: {color-hook}", "Snd graphics contexts: {snd-gcs}", NULL}; static const char *Colors_urls[] = { NULL, NULL, "sndscm.html#rgbdoc", NULL, "extsnd.html#colororientationdialog", "sndscm.html#drawdoc", "sndscm.html#drawdoc", NULL, NULL, NULL, "grfsnd.html#sndandgl", "extsnd.html#colorhook", "extsnd.html#sndgcs", NULL}; static const char *Random_Numbers_xrefs[] = { "generators, arbitrary distributions, fractals, 1/f: {rand and rand-interp}", "dithering: {dither-channel}, {dither-sound}", "noise-making instrument: {noise.scm, noise.rb}", "physical modeling of noisy instruments: {maraca.scm, maraca.rb}", "arbitrary distribution via rejection method: {any-random}", "s7: random, random-state: random number between 0 and arg", "Ruby: kernel_rand (alias for Ruby's rand), srand: random integer between 0 and arg, or float between 0 and 1", "{mus-random, mus_random}: random float between -arg and arg", "mus-rand-seed (settable)", "bounded brownian noise: {green-noise}", "brown and pink noise: {brown-noise}", NULL}; static const char *Random_Numbers_urls[] = { "sndclm.html#randdoc", "sndscm.html#ditherchannel", "sndscm.html#noisedoc", "sndscm.html#maracadoc", "sndscm.html#anyrandom", NULL, NULL, "sndclm.html#mus-random", NULL, "sndclm.html#green-noise", "sndclm.html#brown-noise", NULL}; static const char *Reverb_xrefs[] = { "freeverb: {freeverb.scm, freeverb.rb}", "jc-reverb: {jcrev.scm}", "jl-reverb: {clm-ins.scm}", "nrev: {clm-ins.scm}", "control panel reverb: {Reverb}, {control variables}", "convolution reverb: {conrev}", "*reverb*: {with-sound}", NULL}; static const char *Reverb_urls[] = { "sndscm.html#freeverbdoc", "sndscm.html#jcrevdoc", "sndscm.html#clminsdoc", "sndscm.html#clminsdoc", "snd.html#reverb", "extsnd.html#convolvewith", "sndscm.html#wsdoc", NULL}; #if HAVE_SCHEME static const char *snd_names[11580] = { "*clm-array-print-length*", "ws.scm", "*clm-channels*", "ws.scm", "*clm-clipped*", "ws.scm", "*clm-default-frequency*", "ws.scm", "*clm-delete-reverb*", "ws.scm", "*clm-file-buffer-size*", "ws.scm", "*clm-file-name*", "ws.scm", "*clm-header-type*", "ws.scm", "*clm-locsig-type*", "ws.scm", "*clm-notehook*", "ws.scm", "*clm-play*", "ws.scm", "*clm-player*", "ws.scm", "*clm-reverb*", "ws.scm", "*clm-reverb-channels*", "ws.scm", "*clm-reverb-data*", "ws.scm", "*clm-sample-type*", "ws.scm", "*clm-search-list*", "ws.scm", "*clm-srate*", "ws.scm", "*clm-statistics*", "ws.scm", "*clm-table-size*", "ws.scm", "*clm-verbose*", "ws.scm", "*clm-with-sound-depth*", "ws.scm", "*default-player*", "ws.scm", "*definstrument-hook*", "ws.scm", "*libc*", "libc.scm", "*libdl*", "libdl.scm", "*libgdbm*", "libgdbm.scm", "*libgsl*", "libgsl.scm", "*libm*", "libm.scm", "*mock-char*", "mockery.scm", "*mock-hash-table*", "mockery.scm", "*mock-number*", "mockery.scm", "*mock-pair*", "mockery.scm", "*mock-port*", "mockery.scm", "*mock-string*", "mockery.scm", "*mock-symbol*", "mockery.scm", "*mock-vector*", "mockery.scm", "*repl*", "repl.scm", "*s7*->list", "stuff.scm", "*to-snd*", "ws.scm", "->frequency", "ws.scm", "->predicate", "stuff.scm", "->sample", "ws.scm", "->x", "musglyphs.scm", "->y", "musglyphs.scm", "1+", "stuff.scm", "1-", "stuff.scm", "2^n-1?", "stuff.scm", "2^n?", "stuff.scm", "AF_APPLETALK", "libc.scm", "AF_ASH", "libc.scm", "AF_ATMPVC", "libc.scm", "AF_ATMSVC", "libc.scm", "AF_AX25", "libc.scm", "AF_BLUETOOTH", "libc.scm", "AF_BRIDGE", "libc.scm", "AF_CAN", "libc.scm", "AF_DECnet", "libc.scm", "AF_ECONET", "libc.scm", "AF_FILE", "libc.scm", "AF_IEEE802154", "libc.scm", "AF_INET", "libc.scm", "AF_INET6", "libc.scm", "AF_IPX", "libc.scm", "AF_IRDA", "libc.scm", "AF_ISDN", "libc.scm", "AF_IUCV", "libc.scm", "AF_KEY", "libc.scm", "AF_LLC", "libc.scm", "AF_LOCAL", "libc.scm", "AF_MAX", "libc.scm", "AF_NETBEUI", "libc.scm", "AF_NETLINK", "libc.scm", "AF_NETROM", "libc.scm", "AF_PACKET", "libc.scm", "AF_PHONET", "libc.scm", "AF_PPPOX", "libc.scm", "AF_RDS", "libc.scm", "AF_ROSE", "libc.scm", "AF_ROUTE", "libc.scm", "AF_RXRPC", "libc.scm", "AF_SECURITY", "libc.scm", "AF_SNA", "libc.scm", "AF_TIPC", "libc.scm", "AF_UNIX", "libc.scm", "AF_UNSPEC", "libc.scm", "AF_WANPIPE", "libc.scm", "AF_X25", "libc.scm", "AI_ADDRCONFIG", "libc.scm", "AI_ALL", "libc.scm", "AI_CANONNAME", "libc.scm", "AI_NUMERICHOST", "libc.scm", "AI_NUMERICSERV", "libc.scm", "AI_PASSIVE", "libc.scm", "AI_V4MAPPED", "libc.scm", "BC_BASE_MAX", "libc.scm", "BC_DIM_MAX", "libc.scm", "BC_SCALE_MAX", "libc.scm", "BC_STRING_MAX", "libc.scm", "BRKINT", "libc.scm", "BUFSIZ", "libc.scm", "CHARCLASS_NAME_MAX", "libc.scm", "CHAR_BIT", "libc.scm", "CHAR_MAX", "libc.scm", "CHAR_MIN", "libc.scm", "CLOCKS_PER_SEC", "libc.scm", "CLOCK_MONOTONIC", "libc.scm", "CLOCK_MONOTONIC_COARSE", "libc.scm", "CLOCK_MONOTONIC_RAW", "libc.scm", "CLOCK_PROCESS_CPUTIME_ID", "libc.scm", "CLOCK_REALTIME", "libc.scm", "CLOCK_REALTIME_COARSE", "libc.scm", "CLOCK_THREAD_CPUTIME_ID", "libc.scm", "COLL_WEIGHTS_MAX", "libc.scm", "CblasColMajor", "libgsl.scm", "CblasConjTrans", "libgsl.scm", "CblasLeft", "libgsl.scm", "CblasLower", "libgsl.scm", "CblasNoTrans", "libgsl.scm", "CblasNonUnit", "libgsl.scm", "CblasRight", "libgsl.scm", "CblasRowMajor", "libgsl.scm", "CblasTrans", "libgsl.scm", "CblasUnit", "libgsl.scm", "CblasUpper", "libgsl.scm", "Ci", "numerics.scm", "DBL_DIG", "libc.scm", "DBL_EPSILON", "libc.scm", "DBL_MANT_DIG", "libc.scm", "DBL_MAX", "libc.scm", "DBL_MAX_10_EXP", "libc.scm", "DBL_MAX_EXP", "libc.scm", "DBL_MIN", "libc.scm", "DBL_MIN_10_EXP", "libc.scm", "DBL_MIN_EXP", "libc.scm", "E2BIG", "libc.scm", "EACCES", "libc.scm", "EAGAIN", "libc.scm", "EAI_AGAIN", "libc.scm", "EAI_BADFLAGS", "libc.scm", "EAI_FAIL", "libc.scm", "EAI_FAMILY", "libc.scm", "EAI_MEMORY", "libc.scm", "EAI_NONAME", "libc.scm", "EAI_OVERFLOW", "libc.scm", "EAI_SERVICE", "libc.scm", "EAI_SOCKTYPE", "libc.scm", "EAI_SYSTEM", "libc.scm", "EBADF", "libc.scm", "EBUSY", "libc.scm", "ECANCELED", "libc.scm", "ECHILD", "libc.scm", "ECHO", "libc.scm", "ECHOE", "libc.scm", "ECHOK", "libc.scm", "ECHONL", "libc.scm", "EDOM", "libc.scm", "EEXIST", "libc.scm", "EFAULT", "libc.scm", "EFBIG", "libc.scm", "EILSEQ", "libc.scm", "EINTR", "libc.scm", "EINVAL", "libc.scm", "EIO", "libc.scm", "EISDIR", "libc.scm", "EMFILE", "libc.scm", "EMLINK", "libc.scm", "ENFILE", "libc.scm", "ENODEV", "libc.scm", "ENOENT", "libc.scm", "ENOEXEC", "libc.scm", "ENOMEM", "libc.scm", "ENOSPC", "libc.scm", "ENOTBLK", "libc.scm", "ENOTDIR", "libc.scm", "ENOTRECOVERABLE", "libc.scm", "ENOTTY", "libc.scm", "ENXIO", "libc.scm", "EOF", "libc.scm", "EOWNERDEAD", "libc.scm", "EPERM", "libc.scm", "EPIPE", "libc.scm", "ERANGE", "libc.scm", "ERFKILL", "libc.scm", "EROFS", "libc.scm", "ESPIPE", "libc.scm", "ESRCH", "libc.scm", "ETXTBSY", "libc.scm", "EXDEV", "libc.scm", "EXIT_FAILURE", "libc.scm", "EXIT_SUCCESS", "libc.scm", "EXPR_NEST_MAX", "libc.scm", "FD_CLOEXEC", "libc.scm", "FE_ALL_EXCEPT", "libc.scm", "FE_DIVBYZERO", "libc.scm", "FE_DOWNWARD", "libc.scm", "FE_INEXACT", "libc.scm", "FE_INVALID", "libc.scm", "FE_OVERFLOW", "libc.scm", "FE_TONEAREST", "libc.scm", "FE_TOWARDZERO", "libc.scm", "FE_UNDERFLOW", "libc.scm", "FE_UPWARD", "libc.scm", "FILENAME_MAX", "libc.scm", "FLT_DIG", "libc.scm", "FLT_EPSILON", "libc.scm", "FLT_MANT_DIG", "libc.scm", "FLT_MAX", "libc.scm", "FLT_MAX_10_EXP", "libc.scm", "FLT_MAX_EXP", "libc.scm", "FLT_MIN", "libc.scm", "FLT_MIN_10_EXP", "libc.scm", "FLT_MIN_EXP", "libc.scm", "FLT_RADIX", "libc.scm", "FLT_ROUNDS", "libc.scm", "FNM_NOESCAPE", "libc.scm", "FNM_NOMATCH", "libc.scm", "FNM_PATHNAME", "libc.scm", "FNM_PERIOD", "libc.scm", "FOPEN_MAX", "libc.scm", "FP_INFINITE", "libm.scm", "FP_NAN", "libm.scm", "FP_NORMAL", "libm.scm", "FP_SUBNORMAL", "libm.scm", "FP_ZERO", "libm.scm", "FTW_D", "libc.scm", "FTW_DNR", "libc.scm", "FTW_F", "libc.scm", "FTW_NS", "libc.scm", "F_DUPFD", "libc.scm", "F_GETFD", "libc.scm", "F_GETFL", "libc.scm", "F_GETLK", "libc.scm", "F_GETLK64", "libc.scm", "F_LOCK", "libc.scm", "F_OK", "libc.scm", "F_RDLCK", "libc.scm", "F_SETFD", "libc.scm", "F_SETFL", "libc.scm", "F_SETLK", "libc.scm", "F_SETLK64", "libc.scm", "F_SETLKW", "libc.scm", "F_SETLKW64", "libc.scm", "F_TEST", "libc.scm", "F_TLOCK", "libc.scm", "F_ULOCK", "libc.scm", "F_UNLCK", "libc.scm", "F_WRLCK", "libc.scm", "GDBM_BAD_FILE_OFFSET", "libgdbm.scm", "GDBM_BAD_MAGIC_NUMBER", "libgdbm.scm", "GDBM_BAD_OPEN_FLAGS", "libgdbm.scm", "GDBM_BLOCK_SIZE_ERROR", "libgdbm.scm", "GDBM_BYTE_SWAPPED", "libgdbm.scm", "GDBM_CACHESIZE", "libgdbm.scm", "GDBM_CANNOT_REPLACE", "libgdbm.scm", "GDBM_CANT_BE_READER", "libgdbm.scm", "GDBM_CANT_BE_WRITER", "libgdbm.scm", "GDBM_CENTFREE", "libgdbm.scm", "GDBM_CLOEXEC", "libgdbm.scm", "GDBM_COALESCEBLKS", "libgdbm.scm", "GDBM_EMPTY_DATABASE", "libgdbm.scm", "GDBM_FAST", "libgdbm.scm", "GDBM_FASTMODE", "libgdbm.scm", "GDBM_FILE_EOF", "libgdbm.scm", "GDBM_FILE_OPEN_ERROR", "libgdbm.scm", "GDBM_FILE_READ_ERROR", "libgdbm.scm", "GDBM_FILE_SEEK_ERROR", "libgdbm.scm", "GDBM_FILE_STAT_ERROR", "libgdbm.scm", "GDBM_FILE_WRITE_ERROR", "libgdbm.scm", "GDBM_GETCACHESIZE", "libgdbm.scm", "GDBM_GETCENTFREE", "libgdbm.scm", "GDBM_GETCOALESCEBLKS", "libgdbm.scm", "GDBM_GETDBNAME", "libgdbm.scm", "GDBM_GETFLAGS", "libgdbm.scm", "GDBM_GETMAXMAPSIZE", "libgdbm.scm", "GDBM_GETMMAP", "libgdbm.scm", "GDBM_GETSYNCMODE", "libgdbm.scm", "GDBM_ILLEGAL_DATA", "libgdbm.scm", "GDBM_INSERT", "libgdbm.scm", "GDBM_ITEM_NOT_FOUND", "libgdbm.scm", "GDBM_MALLOC_ERROR", "libgdbm.scm", "GDBM_NEWDB", "libgdbm.scm", "GDBM_NOLOCK", "libgdbm.scm", "GDBM_NOMMAP", "libgdbm.scm", "GDBM_NO_ERROR", "libgdbm.scm", "GDBM_OPENMASK", "libgdbm.scm", "GDBM_OPT_ALREADY_SET", "libgdbm.scm", "GDBM_OPT_ILLEGAL", "libgdbm.scm", "GDBM_READER", "libgdbm.scm", "GDBM_READER_CANT_DELETE", "libgdbm.scm", "GDBM_READER_CANT_REORGANIZE", "libgdbm.scm", "GDBM_READER_CANT_STORE", "libgdbm.scm", "GDBM_REORGANIZE_FAILED", "libgdbm.scm", "GDBM_REPLACE", "libgdbm.scm", "GDBM_SETCACHESIZE", "libgdbm.scm", "GDBM_SETCENTFREE", "libgdbm.scm", "GDBM_SETCOALESCEBLKS", "libgdbm.scm", "GDBM_SETMAXMAPSIZE", "libgdbm.scm", "GDBM_SETMMAP", "libgdbm.scm", "GDBM_SETSYNCMODE", "libgdbm.scm", "GDBM_SYNC", "libgdbm.scm", "GDBM_SYNCMODE", "libgdbm.scm", "GDBM_UNKNOWN_UPDATE", "libgdbm.scm", "GDBM_VERSION_MAJOR", "libgdbm.scm", "GDBM_VERSION_MINOR", "libgdbm.scm", "GDBM_VERSION_PATCH", "libgdbm.scm", "GDBM_WRCREAT", "libgdbm.scm", "GDBM_WRITER", "libgdbm.scm", "GLOB_ABORTED", "libc.scm", "GLOB_ALTDIRFUNC", "libc.scm", "GLOB_APPEND", "libc.scm", "GLOB_BRACE", "libc.scm", "GLOB_DOOFFS", "libc.scm", "GLOB_ERR", "libc.scm", "GLOB_MAGCHAR", "libc.scm", "GLOB_MARK", "libc.scm", "GLOB_NOCHECK", "libc.scm", "GLOB_NOESCAPE", "libc.scm", "GLOB_NOMAGIC", "libc.scm", "GLOB_NOMATCH", "libc.scm", "GLOB_NOSORT", "libc.scm", "GLOB_NOSPACE", "libc.scm", "GLOB_NOSYS", "libc.scm", "GLOB_ONLYDIR", "libc.scm", "GLOB_PERIOD", "libc.scm", "GLOB_TILDE", "libc.scm", "GLOB_TILDE_CHECK", "libc.scm", "GSL_COMPLEX_EQ", "libgsl.scm", "GSL_COMPLEX_NEGONE", "libgsl.scm", "GSL_COMPLEX_ONE", "libgsl.scm", "GSL_COMPLEX_ZERO", "libgsl.scm", "GSL_CONST_CGSM_ACRE", "libgsl.scm", "GSL_CONST_CGSM_ANGSTROM", "libgsl.scm", "GSL_CONST_CGSM_ASTRONOMICAL_UNIT", "libgsl.scm", "GSL_CONST_CGSM_BAR", "libgsl.scm", "GSL_CONST_CGSM_BARN", "libgsl.scm", "GSL_CONST_CGSM_BOHR_MAGNETON", "libgsl.scm", "GSL_CONST_CGSM_BOHR_RADIUS", "libgsl.scm", "GSL_CONST_CGSM_BOLTZMANN", "libgsl.scm", "GSL_CONST_CGSM_BTU", "libgsl.scm", "GSL_CONST_CGSM_CALORIE", "libgsl.scm", "GSL_CONST_CGSM_CANADIAN_GALLON", "libgsl.scm", "GSL_CONST_CGSM_CARAT", "libgsl.scm", "GSL_CONST_CGSM_CUP", "libgsl.scm", "GSL_CONST_CGSM_CURIE", "libgsl.scm", "GSL_CONST_CGSM_DAY", "libgsl.scm", "GSL_CONST_CGSM_DYNE", "libgsl.scm", "GSL_CONST_CGSM_ELECTRON_CHARGE", "libgsl.scm", "GSL_CONST_CGSM_ELECTRON_MAGNETIC_MOMENT", "libgsl.scm", "GSL_CONST_CGSM_ELECTRON_VOLT", "libgsl.scm", "GSL_CONST_CGSM_ERG", "libgsl.scm", "GSL_CONST_CGSM_FARADAY", "libgsl.scm", "GSL_CONST_CGSM_FATHOM", "libgsl.scm", "GSL_CONST_CGSM_FLUID_OUNCE", "libgsl.scm", "GSL_CONST_CGSM_FOOT", "libgsl.scm", "GSL_CONST_CGSM_FOOTCANDLE", "libgsl.scm", "GSL_CONST_CGSM_FOOTLAMBERT", "libgsl.scm", "GSL_CONST_CGSM_GRAM_FORCE", "libgsl.scm", "GSL_CONST_CGSM_GRAVITATIONAL_CONSTANT", "libgsl.scm", "GSL_CONST_CGSM_GRAV_ACCEL", "libgsl.scm", "GSL_CONST_CGSM_HECTARE", "libgsl.scm", "GSL_CONST_CGSM_HORSEPOWER", "libgsl.scm", "GSL_CONST_CGSM_HOUR", "libgsl.scm", "GSL_CONST_CGSM_INCH", "libgsl.scm", "GSL_CONST_CGSM_INCH_OF_MERCURY", "libgsl.scm", "GSL_CONST_CGSM_INCH_OF_WATER", "libgsl.scm", "GSL_CONST_CGSM_JOULE", "libgsl.scm", "GSL_CONST_CGSM_KILOMETERS_PER_HOUR", "libgsl.scm", "GSL_CONST_CGSM_KILOPOUND_FORCE", "libgsl.scm", "GSL_CONST_CGSM_KNOT", "libgsl.scm", "GSL_CONST_CGSM_LAMBERT", "libgsl.scm", "GSL_CONST_CGSM_LIGHT_YEAR", "libgsl.scm", "GSL_CONST_CGSM_LITER", "libgsl.scm", "GSL_CONST_CGSM_LUMEN", "libgsl.scm", "GSL_CONST_CGSM_LUX", "libgsl.scm", "GSL_CONST_CGSM_MASS_ELECTRON", "libgsl.scm", "GSL_CONST_CGSM_MASS_MUON", "libgsl.scm", "GSL_CONST_CGSM_MASS_NEUTRON", "libgsl.scm", "GSL_CONST_CGSM_MASS_PROTON", "libgsl.scm", "GSL_CONST_CGSM_METER_OF_MERCURY", "libgsl.scm", "GSL_CONST_CGSM_METRIC_TON", "libgsl.scm", "GSL_CONST_CGSM_MICRON", "libgsl.scm", "GSL_CONST_CGSM_MIL", "libgsl.scm", "GSL_CONST_CGSM_MILE", "libgsl.scm", "GSL_CONST_CGSM_MILES_PER_HOUR", "libgsl.scm", "GSL_CONST_CGSM_MINUTE", "libgsl.scm", "GSL_CONST_CGSM_MOLAR_GAS", "libgsl.scm", "GSL_CONST_CGSM_NAUTICAL_MILE", "libgsl.scm", "GSL_CONST_CGSM_NEWTON", "libgsl.scm", "GSL_CONST_CGSM_NUCLEAR_MAGNETON", "libgsl.scm", "GSL_CONST_CGSM_OUNCE_MASS", "libgsl.scm", "GSL_CONST_CGSM_PARSEC", "libgsl.scm", "GSL_CONST_CGSM_PHOT", "libgsl.scm", "GSL_CONST_CGSM_PINT", "libgsl.scm", "GSL_CONST_CGSM_PLANCKS_CONSTANT_H", "libgsl.scm", "GSL_CONST_CGSM_PLANCKS_CONSTANT_HBAR", "libgsl.scm", "GSL_CONST_CGSM_POINT", "libgsl.scm", "GSL_CONST_CGSM_POISE", "libgsl.scm", "GSL_CONST_CGSM_POUNDAL", "libgsl.scm", "GSL_CONST_CGSM_POUND_FORCE", "libgsl.scm", "GSL_CONST_CGSM_POUND_MASS", "libgsl.scm", "GSL_CONST_CGSM_PROTON_MAGNETIC_MOMENT", "libgsl.scm", "GSL_CONST_CGSM_PSI", "libgsl.scm", "GSL_CONST_CGSM_QUART", "libgsl.scm", "GSL_CONST_CGSM_RAD", "libgsl.scm", "GSL_CONST_CGSM_ROENTGEN", "libgsl.scm", "GSL_CONST_CGSM_RYDBERG", "libgsl.scm", "GSL_CONST_CGSM_SOLAR_MASS", "libgsl.scm", "GSL_CONST_CGSM_SPEED_OF_LIGHT", "libgsl.scm", "GSL_CONST_CGSM_STANDARD_GAS_VOLUME", "libgsl.scm", "GSL_CONST_CGSM_STD_ATMOSPHERE", "libgsl.scm", "GSL_CONST_CGSM_STEFAN_BOLTZMANN_CONSTANT", "libgsl.scm", "GSL_CONST_CGSM_STILB", "libgsl.scm", "GSL_CONST_CGSM_STOKES", "libgsl.scm", "GSL_CONST_CGSM_TABLESPOON", "libgsl.scm", "GSL_CONST_CGSM_TEASPOON", "libgsl.scm", "GSL_CONST_CGSM_TEXPOINT", "libgsl.scm", "GSL_CONST_CGSM_THERM", "libgsl.scm", "GSL_CONST_CGSM_THOMSON_CROSS_SECTION", "libgsl.scm", "GSL_CONST_CGSM_TON", "libgsl.scm", "GSL_CONST_CGSM_TORR", "libgsl.scm", "GSL_CONST_CGSM_TROY_OUNCE", "libgsl.scm", "GSL_CONST_CGSM_UK_GALLON", "libgsl.scm", "GSL_CONST_CGSM_UK_TON", "libgsl.scm", "GSL_CONST_CGSM_UNIFIED_ATOMIC_MASS", "libgsl.scm", "GSL_CONST_CGSM_US_GALLON", "libgsl.scm", "GSL_CONST_CGSM_WEEK", "libgsl.scm", "GSL_CONST_CGSM_YARD", "libgsl.scm", "GSL_CONST_CGS_ACRE", "libgsl.scm", "GSL_CONST_CGS_ANGSTROM", "libgsl.scm", "GSL_CONST_CGS_ASTRONOMICAL_UNIT", "libgsl.scm", "GSL_CONST_CGS_BAR", "libgsl.scm", "GSL_CONST_CGS_BARN", "libgsl.scm", "GSL_CONST_CGS_BOHR_RADIUS", "libgsl.scm", "GSL_CONST_CGS_BOLTZMANN", "libgsl.scm", "GSL_CONST_CGS_BTU", "libgsl.scm", "GSL_CONST_CGS_CALORIE", "libgsl.scm", "GSL_CONST_CGS_CANADIAN_GALLON", "libgsl.scm", "GSL_CONST_CGS_CARAT", "libgsl.scm", "GSL_CONST_CGS_CUP", "libgsl.scm", "GSL_CONST_CGS_CURIE", "libgsl.scm", "GSL_CONST_CGS_DAY", "libgsl.scm", "GSL_CONST_CGS_DYNE", "libgsl.scm", "GSL_CONST_CGS_ELECTRON_VOLT", "libgsl.scm", "GSL_CONST_CGS_ERG", "libgsl.scm", "GSL_CONST_CGS_FATHOM", "libgsl.scm", "GSL_CONST_CGS_FLUID_OUNCE", "libgsl.scm", "GSL_CONST_CGS_FOOT", "libgsl.scm", "GSL_CONST_CGS_FOOTCANDLE", "libgsl.scm", "GSL_CONST_CGS_FOOTLAMBERT", "libgsl.scm", "GSL_CONST_CGS_GRAM_FORCE", "libgsl.scm", "GSL_CONST_CGS_GRAVITATIONAL_CONSTANT", "libgsl.scm", "GSL_CONST_CGS_GRAV_ACCEL", "libgsl.scm", "GSL_CONST_CGS_HECTARE", "libgsl.scm", "GSL_CONST_CGS_HORSEPOWER", "libgsl.scm", "GSL_CONST_CGS_HOUR", "libgsl.scm", "GSL_CONST_CGS_INCH", "libgsl.scm", "GSL_CONST_CGS_INCH_OF_MERCURY", "libgsl.scm", "GSL_CONST_CGS_INCH_OF_WATER", "libgsl.scm", "GSL_CONST_CGS_JOULE", "libgsl.scm", "GSL_CONST_CGS_KILOMETERS_PER_HOUR", "libgsl.scm", "GSL_CONST_CGS_KILOPOUND_FORCE", "libgsl.scm", "GSL_CONST_CGS_KNOT", "libgsl.scm", "GSL_CONST_CGS_LAMBERT", "libgsl.scm", "GSL_CONST_CGS_LIGHT_YEAR", "libgsl.scm", "GSL_CONST_CGS_LITER", "libgsl.scm", "GSL_CONST_CGS_LUMEN", "libgsl.scm", "GSL_CONST_CGS_LUX", "libgsl.scm", "GSL_CONST_CGS_MASS_ELECTRON", "libgsl.scm", "GSL_CONST_CGS_MASS_MUON", "libgsl.scm", "GSL_CONST_CGS_MASS_NEUTRON", "libgsl.scm", "GSL_CONST_CGS_MASS_PROTON", "libgsl.scm", "GSL_CONST_CGS_METER_OF_MERCURY", "libgsl.scm", "GSL_CONST_CGS_METRIC_TON", "libgsl.scm", "GSL_CONST_CGS_MICRON", "libgsl.scm", "GSL_CONST_CGS_MIL", "libgsl.scm", "GSL_CONST_CGS_MILE", "libgsl.scm", "GSL_CONST_CGS_MILES_PER_HOUR", "libgsl.scm", "GSL_CONST_CGS_MINUTE", "libgsl.scm", "GSL_CONST_CGS_MOLAR_GAS", "libgsl.scm", "GSL_CONST_CGS_NAUTICAL_MILE", "libgsl.scm", "GSL_CONST_CGS_NEWTON", "libgsl.scm", "GSL_CONST_CGS_OUNCE_MASS", "libgsl.scm", "GSL_CONST_CGS_PARSEC", "libgsl.scm", "GSL_CONST_CGS_PHOT", "libgsl.scm", "GSL_CONST_CGS_PINT", "libgsl.scm", "GSL_CONST_CGS_PLANCKS_CONSTANT_H", "libgsl.scm", "GSL_CONST_CGS_PLANCKS_CONSTANT_HBAR", "libgsl.scm", "GSL_CONST_CGS_POINT", "libgsl.scm", "GSL_CONST_CGS_POISE", "libgsl.scm", "GSL_CONST_CGS_POUNDAL", "libgsl.scm", "GSL_CONST_CGS_POUND_FORCE", "libgsl.scm", "GSL_CONST_CGS_POUND_MASS", "libgsl.scm", "GSL_CONST_CGS_PSI", "libgsl.scm", "GSL_CONST_CGS_QUART", "libgsl.scm", "GSL_CONST_CGS_RAD", "libgsl.scm", "GSL_CONST_CGS_ROENTGEN", "libgsl.scm", "GSL_CONST_CGS_RYDBERG", "libgsl.scm", "GSL_CONST_CGS_SOLAR_MASS", "libgsl.scm", "GSL_CONST_CGS_SPEED_OF_LIGHT", "libgsl.scm", "GSL_CONST_CGS_STANDARD_GAS_VOLUME", "libgsl.scm", "GSL_CONST_CGS_STD_ATMOSPHERE", "libgsl.scm", "GSL_CONST_CGS_STEFAN_BOLTZMANN_CONSTANT", "libgsl.scm", "GSL_CONST_CGS_STILB", "libgsl.scm", "GSL_CONST_CGS_STOKES", "libgsl.scm", "GSL_CONST_CGS_TABLESPOON", "libgsl.scm", "GSL_CONST_CGS_TEASPOON", "libgsl.scm", "GSL_CONST_CGS_TEXPOINT", "libgsl.scm", "GSL_CONST_CGS_THERM", "libgsl.scm", "GSL_CONST_CGS_THOMSON_CROSS_SECTION", "libgsl.scm", "GSL_CONST_CGS_TON", "libgsl.scm", "GSL_CONST_CGS_TORR", "libgsl.scm", "GSL_CONST_CGS_TROY_OUNCE", "libgsl.scm", "GSL_CONST_CGS_UK_GALLON", "libgsl.scm", "GSL_CONST_CGS_UK_TON", "libgsl.scm", "GSL_CONST_CGS_UNIFIED_ATOMIC_MASS", "libgsl.scm", "GSL_CONST_CGS_US_GALLON", "libgsl.scm", "GSL_CONST_CGS_WEEK", "libgsl.scm", "GSL_CONST_CGS_YARD", "libgsl.scm", "GSL_CONST_MKSA_ACRE", "libgsl.scm", "GSL_CONST_MKSA_ANGSTROM", "libgsl.scm", "GSL_CONST_MKSA_ASTRONOMICAL_UNIT", "libgsl.scm", "GSL_CONST_MKSA_BAR", "libgsl.scm", "GSL_CONST_MKSA_BARN", "libgsl.scm", "GSL_CONST_MKSA_BOHR_MAGNETON", "libgsl.scm", "GSL_CONST_MKSA_BOHR_RADIUS", "libgsl.scm", "GSL_CONST_MKSA_BOLTZMANN", "libgsl.scm", "GSL_CONST_MKSA_BTU", "libgsl.scm", "GSL_CONST_MKSA_CALORIE", "libgsl.scm", "GSL_CONST_MKSA_CANADIAN_GALLON", "libgsl.scm", "GSL_CONST_MKSA_CARAT", "libgsl.scm", "GSL_CONST_MKSA_CUP", "libgsl.scm", "GSL_CONST_MKSA_CURIE", "libgsl.scm", "GSL_CONST_MKSA_DAY", "libgsl.scm", "GSL_CONST_MKSA_DEBYE", "libgsl.scm", "GSL_CONST_MKSA_DYNE", "libgsl.scm", "GSL_CONST_MKSA_ELECTRON_CHARGE", "libgsl.scm", "GSL_CONST_MKSA_ELECTRON_MAGNETIC_MOMENT", "libgsl.scm", "GSL_CONST_MKSA_ELECTRON_VOLT", "libgsl.scm", "GSL_CONST_MKSA_ERG", "libgsl.scm", "GSL_CONST_MKSA_FARADAY", "libgsl.scm", "GSL_CONST_MKSA_FATHOM", "libgsl.scm", "GSL_CONST_MKSA_FLUID_OUNCE", "libgsl.scm", "GSL_CONST_MKSA_FOOT", "libgsl.scm", "GSL_CONST_MKSA_FOOTCANDLE", "libgsl.scm", "GSL_CONST_MKSA_FOOTLAMBERT", "libgsl.scm", "GSL_CONST_MKSA_GAUSS", "libgsl.scm", "GSL_CONST_MKSA_GRAM_FORCE", "libgsl.scm", "GSL_CONST_MKSA_GRAVITATIONAL_CONSTANT", "libgsl.scm", "GSL_CONST_MKSA_GRAV_ACCEL", "libgsl.scm", "GSL_CONST_MKSA_HECTARE", "libgsl.scm", "GSL_CONST_MKSA_HORSEPOWER", "libgsl.scm", "GSL_CONST_MKSA_HOUR", "libgsl.scm", "GSL_CONST_MKSA_INCH", "libgsl.scm", "GSL_CONST_MKSA_INCH_OF_MERCURY", "libgsl.scm", "GSL_CONST_MKSA_INCH_OF_WATER", "libgsl.scm", "GSL_CONST_MKSA_JOULE", "libgsl.scm", "GSL_CONST_MKSA_KILOMETERS_PER_HOUR", "libgsl.scm", "GSL_CONST_MKSA_KILOPOUND_FORCE", "libgsl.scm", "GSL_CONST_MKSA_KNOT", "libgsl.scm", "GSL_CONST_MKSA_LAMBERT", "libgsl.scm", "GSL_CONST_MKSA_LIGHT_YEAR", "libgsl.scm", "GSL_CONST_MKSA_LITER", "libgsl.scm", "GSL_CONST_MKSA_LUMEN", "libgsl.scm", "GSL_CONST_MKSA_LUX", "libgsl.scm", "GSL_CONST_MKSA_MASS_ELECTRON", "libgsl.scm", "GSL_CONST_MKSA_MASS_MUON", "libgsl.scm", "GSL_CONST_MKSA_MASS_NEUTRON", "libgsl.scm", "GSL_CONST_MKSA_MASS_PROTON", "libgsl.scm", "GSL_CONST_MKSA_METER_OF_MERCURY", "libgsl.scm", "GSL_CONST_MKSA_METRIC_TON", "libgsl.scm", "GSL_CONST_MKSA_MICRON", "libgsl.scm", "GSL_CONST_MKSA_MIL", "libgsl.scm", "GSL_CONST_MKSA_MILE", "libgsl.scm", "GSL_CONST_MKSA_MILES_PER_HOUR", "libgsl.scm", "GSL_CONST_MKSA_MINUTE", "libgsl.scm", "GSL_CONST_MKSA_MOLAR_GAS", "libgsl.scm", "GSL_CONST_MKSA_NAUTICAL_MILE", "libgsl.scm", "GSL_CONST_MKSA_NEWTON", "libgsl.scm", "GSL_CONST_MKSA_NUCLEAR_MAGNETON", "libgsl.scm", "GSL_CONST_MKSA_OUNCE_MASS", "libgsl.scm", "GSL_CONST_MKSA_PARSEC", "libgsl.scm", "GSL_CONST_MKSA_PHOT", "libgsl.scm", "GSL_CONST_MKSA_PINT", "libgsl.scm", "GSL_CONST_MKSA_PLANCKS_CONSTANT_H", "libgsl.scm", "GSL_CONST_MKSA_PLANCKS_CONSTANT_HBAR", "libgsl.scm", "GSL_CONST_MKSA_POINT", "libgsl.scm", "GSL_CONST_MKSA_POISE", "libgsl.scm", "GSL_CONST_MKSA_POUNDAL", "libgsl.scm", "GSL_CONST_MKSA_POUND_FORCE", "libgsl.scm", "GSL_CONST_MKSA_POUND_MASS", "libgsl.scm", "GSL_CONST_MKSA_PROTON_MAGNETIC_MOMENT", "libgsl.scm", "GSL_CONST_MKSA_PSI", "libgsl.scm", "GSL_CONST_MKSA_QUART", "libgsl.scm", "GSL_CONST_MKSA_RAD", "libgsl.scm", "GSL_CONST_MKSA_ROENTGEN", "libgsl.scm", "GSL_CONST_MKSA_RYDBERG", "libgsl.scm", "GSL_CONST_MKSA_SOLAR_MASS", "libgsl.scm", "GSL_CONST_MKSA_SPEED_OF_LIGHT", "libgsl.scm", "GSL_CONST_MKSA_STANDARD_GAS_VOLUME", "libgsl.scm", "GSL_CONST_MKSA_STD_ATMOSPHERE", "libgsl.scm", "GSL_CONST_MKSA_STEFAN_BOLTZMANN_CONSTANT", "libgsl.scm", "GSL_CONST_MKSA_STILB", "libgsl.scm", "GSL_CONST_MKSA_STOKES", "libgsl.scm", "GSL_CONST_MKSA_TABLESPOON", "libgsl.scm", "GSL_CONST_MKSA_TEASPOON", "libgsl.scm", "GSL_CONST_MKSA_TEXPOINT", "libgsl.scm", "GSL_CONST_MKSA_THERM", "libgsl.scm", "GSL_CONST_MKSA_THOMSON_CROSS_SECTION", "libgsl.scm", "GSL_CONST_MKSA_TON", "libgsl.scm", "GSL_CONST_MKSA_TORR", "libgsl.scm", "GSL_CONST_MKSA_TROY_OUNCE", "libgsl.scm", "GSL_CONST_MKSA_UK_GALLON", "libgsl.scm", "GSL_CONST_MKSA_UK_TON", "libgsl.scm", "GSL_CONST_MKSA_UNIFIED_ATOMIC_MASS", "libgsl.scm", "GSL_CONST_MKSA_US_GALLON", "libgsl.scm", "GSL_CONST_MKSA_VACUUM_PERMEABILITY", "libgsl.scm", "GSL_CONST_MKSA_VACUUM_PERMITTIVITY", "libgsl.scm", "GSL_CONST_MKSA_WEEK", "libgsl.scm", "GSL_CONST_MKSA_YARD", "libgsl.scm", "GSL_CONST_MKS_ACRE", "libgsl.scm", "GSL_CONST_MKS_ANGSTROM", "libgsl.scm", "GSL_CONST_MKS_ASTRONOMICAL_UNIT", "libgsl.scm", "GSL_CONST_MKS_BAR", "libgsl.scm", "GSL_CONST_MKS_BARN", "libgsl.scm", "GSL_CONST_MKS_BOHR_MAGNETON", "libgsl.scm", "GSL_CONST_MKS_BOHR_RADIUS", "libgsl.scm", "GSL_CONST_MKS_BOLTZMANN", "libgsl.scm", "GSL_CONST_MKS_BTU", "libgsl.scm", "GSL_CONST_MKS_CALORIE", "libgsl.scm", "GSL_CONST_MKS_CANADIAN_GALLON", "libgsl.scm", "GSL_CONST_MKS_CARAT", "libgsl.scm", "GSL_CONST_MKS_CUP", "libgsl.scm", "GSL_CONST_MKS_CURIE", "libgsl.scm", "GSL_CONST_MKS_DAY", "libgsl.scm", "GSL_CONST_MKS_DEBYE", "libgsl.scm", "GSL_CONST_MKS_DYNE", "libgsl.scm", "GSL_CONST_MKS_ELECTRON_CHARGE", "libgsl.scm", "GSL_CONST_MKS_ELECTRON_MAGNETIC_MOMENT", "libgsl.scm", "GSL_CONST_MKS_ELECTRON_VOLT", "libgsl.scm", "GSL_CONST_MKS_ERG", "libgsl.scm", "GSL_CONST_MKS_FARADAY", "libgsl.scm", "GSL_CONST_MKS_FATHOM", "libgsl.scm", "GSL_CONST_MKS_FLUID_OUNCE", "libgsl.scm", "GSL_CONST_MKS_FOOT", "libgsl.scm", "GSL_CONST_MKS_FOOTCANDLE", "libgsl.scm", "GSL_CONST_MKS_FOOTLAMBERT", "libgsl.scm", "GSL_CONST_MKS_GAUSS", "libgsl.scm", "GSL_CONST_MKS_GRAM_FORCE", "libgsl.scm", "GSL_CONST_MKS_GRAVITATIONAL_CONSTANT", "libgsl.scm", "GSL_CONST_MKS_GRAV_ACCEL", "libgsl.scm", "GSL_CONST_MKS_HECTARE", "libgsl.scm", "GSL_CONST_MKS_HORSEPOWER", "libgsl.scm", "GSL_CONST_MKS_HOUR", "libgsl.scm", "GSL_CONST_MKS_INCH", "libgsl.scm", "GSL_CONST_MKS_INCH_OF_MERCURY", "libgsl.scm", "GSL_CONST_MKS_INCH_OF_WATER", "libgsl.scm", "GSL_CONST_MKS_JOULE", "libgsl.scm", "GSL_CONST_MKS_KILOMETERS_PER_HOUR", "libgsl.scm", "GSL_CONST_MKS_KILOPOUND_FORCE", "libgsl.scm", "GSL_CONST_MKS_KNOT", "libgsl.scm", "GSL_CONST_MKS_LAMBERT", "libgsl.scm", "GSL_CONST_MKS_LIGHT_YEAR", "libgsl.scm", "GSL_CONST_MKS_LITER", "libgsl.scm", "GSL_CONST_MKS_LUMEN", "libgsl.scm", "GSL_CONST_MKS_LUX", "libgsl.scm", "GSL_CONST_MKS_MASS_ELECTRON", "libgsl.scm", "GSL_CONST_MKS_MASS_MUON", "libgsl.scm", "GSL_CONST_MKS_MASS_NEUTRON", "libgsl.scm", "GSL_CONST_MKS_MASS_PROTON", "libgsl.scm", "GSL_CONST_MKS_METER_OF_MERCURY", "libgsl.scm", "GSL_CONST_MKS_METRIC_TON", "libgsl.scm", "GSL_CONST_MKS_MICRON", "libgsl.scm", "GSL_CONST_MKS_MIL", "libgsl.scm", "GSL_CONST_MKS_MILE", "libgsl.scm", "GSL_CONST_MKS_MILES_PER_HOUR", "libgsl.scm", "GSL_CONST_MKS_MINUTE", "libgsl.scm", "GSL_CONST_MKS_MOLAR_GAS", "libgsl.scm", "GSL_CONST_MKS_NAUTICAL_MILE", "libgsl.scm", "GSL_CONST_MKS_NEWTON", "libgsl.scm", "GSL_CONST_MKS_NUCLEAR_MAGNETON", "libgsl.scm", "GSL_CONST_MKS_OUNCE_MASS", "libgsl.scm", "GSL_CONST_MKS_PARSEC", "libgsl.scm", "GSL_CONST_MKS_PHOT", "libgsl.scm", "GSL_CONST_MKS_PINT", "libgsl.scm", "GSL_CONST_MKS_PLANCKS_CONSTANT_H", "libgsl.scm", "GSL_CONST_MKS_PLANCKS_CONSTANT_HBAR", "libgsl.scm", "GSL_CONST_MKS_POINT", "libgsl.scm", "GSL_CONST_MKS_POISE", "libgsl.scm", "GSL_CONST_MKS_POUNDAL", "libgsl.scm", "GSL_CONST_MKS_POUND_FORCE", "libgsl.scm", "GSL_CONST_MKS_POUND_MASS", "libgsl.scm", "GSL_CONST_MKS_PROTON_MAGNETIC_MOMENT", "libgsl.scm", "GSL_CONST_MKS_PSI", "libgsl.scm", "GSL_CONST_MKS_QUART", "libgsl.scm", "GSL_CONST_MKS_RAD", "libgsl.scm", "GSL_CONST_MKS_ROENTGEN", "libgsl.scm", "GSL_CONST_MKS_RYDBERG", "libgsl.scm", "GSL_CONST_MKS_SOLAR_MASS", "libgsl.scm", "GSL_CONST_MKS_SPEED_OF_LIGHT", "libgsl.scm", "GSL_CONST_MKS_STANDARD_GAS_VOLUME", "libgsl.scm", "GSL_CONST_MKS_STD_ATMOSPHERE", "libgsl.scm", "GSL_CONST_MKS_STEFAN_BOLTZMANN_CONSTANT", "libgsl.scm", "GSL_CONST_MKS_STILB", "libgsl.scm", "GSL_CONST_MKS_STOKES", "libgsl.scm", "GSL_CONST_MKS_TABLESPOON", "libgsl.scm", "GSL_CONST_MKS_TEASPOON", "libgsl.scm", "GSL_CONST_MKS_TEXPOINT", "libgsl.scm", "GSL_CONST_MKS_THERM", "libgsl.scm", "GSL_CONST_MKS_THOMSON_CROSS_SECTION", "libgsl.scm", "GSL_CONST_MKS_TON", "libgsl.scm", "GSL_CONST_MKS_TORR", "libgsl.scm", "GSL_CONST_MKS_TROY_OUNCE", "libgsl.scm", "GSL_CONST_MKS_UK_GALLON", "libgsl.scm", "GSL_CONST_MKS_UK_TON", "libgsl.scm", "GSL_CONST_MKS_UNIFIED_ATOMIC_MASS", "libgsl.scm", "GSL_CONST_MKS_US_GALLON", "libgsl.scm", "GSL_CONST_MKS_VACUUM_PERMEABILITY", "libgsl.scm", "GSL_CONST_MKS_VACUUM_PERMITTIVITY", "libgsl.scm", "GSL_CONST_MKS_WEEK", "libgsl.scm", "GSL_CONST_MKS_YARD", "libgsl.scm", "GSL_CONST_NUM_ATTO", "libgsl.scm", "GSL_CONST_NUM_AVOGADRO", "libgsl.scm", "GSL_CONST_NUM_EXA", "libgsl.scm", "GSL_CONST_NUM_FEMTO", "libgsl.scm", "GSL_CONST_NUM_FINE_STRUCTURE", "libgsl.scm", "GSL_CONST_NUM_GIGA", "libgsl.scm", "GSL_CONST_NUM_KILO", "libgsl.scm", "GSL_CONST_NUM_MEGA", "libgsl.scm", "GSL_CONST_NUM_MICRO", "libgsl.scm", "GSL_CONST_NUM_MILLI", "libgsl.scm", "GSL_CONST_NUM_NANO", "libgsl.scm", "GSL_CONST_NUM_PETA", "libgsl.scm", "GSL_CONST_NUM_PICO", "libgsl.scm", "GSL_CONST_NUM_TERA", "libgsl.scm", "GSL_CONST_NUM_YOCTO", "libgsl.scm", "GSL_CONST_NUM_YOTTA", "libgsl.scm", "GSL_CONST_NUM_ZEPTO", "libgsl.scm", "GSL_CONST_NUM_ZETTA", "libgsl.scm", "GSL_CONTINUE", "libgsl.scm", "GSL_DBL_EPSILON", "libgsl.scm", "GSL_DBL_MAX", "libgsl.scm", "GSL_DBL_MIN", "libgsl.scm", "GSL_EBADFUNC", "libgsl.scm", "GSL_EBADLEN", "libgsl.scm", "GSL_EBADTOL", "libgsl.scm", "GSL_ECACHE", "libgsl.scm", "GSL_EDIVERGE", "libgsl.scm", "GSL_EDOM", "libgsl.scm", "GSL_EFACTOR", "libgsl.scm", "GSL_EFAILED", "libgsl.scm", "GSL_EFAULT", "libgsl.scm", "GSL_EIGEN_SORT_ABS_ASC", "libgsl.scm", "GSL_EIGEN_SORT_ABS_DESC", "libgsl.scm", "GSL_EIGEN_SORT_VAL_ASC", "libgsl.scm", "GSL_EIGEN_SORT_VAL_DESC", "libgsl.scm", "GSL_EINVAL", "libgsl.scm", "GSL_ELOSS", "libgsl.scm", "GSL_EMAXITER", "libgsl.scm", "GSL_ENOMEM", "libgsl.scm", "GSL_ENOPROG", "libgsl.scm", "GSL_ENOPROGJ", "libgsl.scm", "GSL_ENOTSQR", "libgsl.scm", "GSL_EOF", "libgsl.scm", "GSL_EOVRFLW", "libgsl.scm", "GSL_ERANGE", "libgsl.scm", "GSL_EROUND", "libgsl.scm", "GSL_ERUNAWAY", "libgsl.scm", "GSL_ESANITY", "libgsl.scm", "GSL_ESING", "libgsl.scm", "GSL_ETABLE", "libgsl.scm", "GSL_ETOL", "libgsl.scm", "GSL_ETOLF", "libgsl.scm", "GSL_ETOLG", "libgsl.scm", "GSL_ETOLX", "libgsl.scm", "GSL_EUNDRFLW", "libgsl.scm", "GSL_EUNIMPL", "libgsl.scm", "GSL_EUNSUP", "libgsl.scm", "GSL_EZERODIV", "libgsl.scm", "GSL_FAILURE", "libgsl.scm", "GSL_FLT_EPSILON", "libgsl.scm", "GSL_FLT_MAX", "libgsl.scm", "GSL_FLT_MIN", "libgsl.scm", "GSL_IEEE_DOUBLE_PRECISION", "libgsl.scm", "GSL_IEEE_EXTENDED_PRECISION", "libgsl.scm", "GSL_IEEE_MASK_ALL", "libgsl.scm", "GSL_IEEE_MASK_DENORMALIZED", "libgsl.scm", "GSL_IEEE_MASK_DIVISION_BY_ZERO", "libgsl.scm", "GSL_IEEE_MASK_INVALID", "libgsl.scm", "GSL_IEEE_MASK_OVERFLOW", "libgsl.scm", "GSL_IEEE_MASK_UNDERFLOW", "libgsl.scm", "GSL_IEEE_ROUND_DOWN", "libgsl.scm", "GSL_IEEE_ROUND_TO_NEAREST", "libgsl.scm", "GSL_IEEE_ROUND_TO_ZERO", "libgsl.scm", "GSL_IEEE_ROUND_UP", "libgsl.scm", "GSL_IEEE_SINGLE_PRECISION", "libgsl.scm", "GSL_IEEE_TRAP_INEXACT", "libgsl.scm", "GSL_IEEE_TYPE_DENORMAL", "libgsl.scm", "GSL_IEEE_TYPE_INF", "libgsl.scm", "GSL_IEEE_TYPE_NAN", "libgsl.scm", "GSL_IEEE_TYPE_NORMAL", "libgsl.scm", "GSL_IEEE_TYPE_ZERO", "libgsl.scm", "GSL_IMAG", "libgsl.scm", "GSL_INTEG_GAUSS15", "libgsl.scm", "GSL_INTEG_GAUSS21", "libgsl.scm", "GSL_INTEG_GAUSS31", "libgsl.scm", "GSL_INTEG_GAUSS41", "libgsl.scm", "GSL_INTEG_GAUSS51", "libgsl.scm", "GSL_INTEG_GAUSS61", "libgsl.scm", "GSL_IS_EVEN", "libgsl.scm", "GSL_IS_ODD", "libgsl.scm", "GSL_IS_REAL", "libgsl.scm", "GSL_LINALG_MOD_CONJUGATE", "libgsl.scm", "GSL_LINALG_MOD_NONE", "libgsl.scm", "GSL_LINALG_MOD_TRANSPOSE", "libgsl.scm", "GSL_LOG_DBL_EPSILON", "libgsl.scm", "GSL_LOG_DBL_MAX", "libgsl.scm", "GSL_LOG_DBL_MIN", "libgsl.scm", "GSL_LOG_FLT_EPSILON", "libgsl.scm", "GSL_LOG_FLT_MAX", "libgsl.scm", "GSL_LOG_FLT_MIN", "libgsl.scm", "GSL_LOG_MACH_EPS", "libgsl.scm", "GSL_LOG_SFLT_EPSILON", "libgsl.scm", "GSL_MACH_EPS", "libgsl.scm", "GSL_MAJOR_VERSION", "libgsl.scm", "GSL_MAX", "libgsl.scm", "GSL_MAX_DBL", "libgsl.scm", "GSL_MAX_INT", "libgsl.scm", "GSL_MESSAGE_MASK_A", "libgsl.scm", "GSL_MESSAGE_MASK_B", "libgsl.scm", "GSL_MESSAGE_MASK_C", "libgsl.scm", "GSL_MESSAGE_MASK_D", "libgsl.scm", "GSL_MESSAGE_MASK_E", "libgsl.scm", "GSL_MESSAGE_MASK_F", "libgsl.scm", "GSL_MESSAGE_MASK_G", "libgsl.scm", "GSL_MESSAGE_MASK_H", "libgsl.scm", "GSL_MIN", "libgsl.scm", "GSL_MINOR_VERSION", "libgsl.scm", "GSL_MIN_DBL", "libgsl.scm", "GSL_MIN_INT", "libgsl.scm", "GSL_MODE_DEFAULT", "libgsl.scm", "GSL_NAN", "libgsl.scm", "GSL_NEGINF", "libgsl.scm", "GSL_NEGZERO", "libgsl.scm", "GSL_POSINF", "libgsl.scm", "GSL_POSZERO", "libgsl.scm", "GSL_PREC_APPROX", "libgsl.scm", "GSL_PREC_DOUBLE", "libgsl.scm", "GSL_PREC_SINGLE", "libgsl.scm", "GSL_REAL", "libgsl.scm", "GSL_ROOT3_DBL_EPSILON", "libgsl.scm", "GSL_ROOT3_DBL_MAX", "libgsl.scm", "GSL_ROOT3_DBL_MIN", "libgsl.scm", "GSL_ROOT3_FLT_EPSILON", "libgsl.scm", "GSL_ROOT3_FLT_MAX", "libgsl.scm", "GSL_ROOT3_FLT_MIN", "libgsl.scm", "GSL_ROOT3_MACH_EPS", "libgsl.scm", "GSL_ROOT3_SFLT_EPSILON", "libgsl.scm", "GSL_ROOT4_DBL_EPSILON", "libgsl.scm", "GSL_ROOT4_DBL_MAX", "libgsl.scm", "GSL_ROOT4_DBL_MIN", "libgsl.scm", "GSL_ROOT4_FLT_EPSILON", "libgsl.scm", "GSL_ROOT4_FLT_MAX", "libgsl.scm", "GSL_ROOT4_FLT_MIN", "libgsl.scm", "GSL_ROOT4_MACH_EPS", "libgsl.scm", "GSL_ROOT4_SFLT_EPSILON", "libgsl.scm", "GSL_ROOT5_DBL_EPSILON", "libgsl.scm", "GSL_ROOT5_DBL_MAX", "libgsl.scm", "GSL_ROOT5_DBL_MIN", "libgsl.scm", "GSL_ROOT5_FLT_EPSILON", "libgsl.scm", "GSL_ROOT5_FLT_MAX", "libgsl.scm", "GSL_ROOT5_FLT_MIN", "libgsl.scm", "GSL_ROOT5_MACH_EPS", "libgsl.scm", "GSL_ROOT5_SFLT_EPSILON", "libgsl.scm", "GSL_ROOT6_DBL_EPSILON", "libgsl.scm", "GSL_ROOT6_DBL_MAX", "libgsl.scm", "GSL_ROOT6_DBL_MIN", "libgsl.scm", "GSL_ROOT6_FLT_EPSILON", "libgsl.scm", "GSL_ROOT6_FLT_MAX", "libgsl.scm", "GSL_ROOT6_FLT_MIN", "libgsl.scm", "GSL_ROOT6_MACH_EPS", "libgsl.scm", "GSL_ROOT6_SFLT_EPSILON", "libgsl.scm", "GSL_SFLT_EPSILON", "libgsl.scm", "GSL_SF_DOUBLEFACT_NMAX", "libgsl.scm", "GSL_SF_FACT_NMAX", "libgsl.scm", "GSL_SF_GAMMA_XMAX", "libgsl.scm", "GSL_SF_MATHIEU_COEFF", "libgsl.scm", "GSL_SIGN", "libgsl.scm", "GSL_SPMATRIX_CCS", "libgsl.scm", "GSL_SPMATRIX_TRIPLET", "libgsl.scm", "GSL_SQRT_DBL_EPSILON", "libgsl.scm", "GSL_SQRT_DBL_MAX", "libgsl.scm", "GSL_SQRT_DBL_MIN", "libgsl.scm", "GSL_SQRT_FLT_EPSILON", "libgsl.scm", "GSL_SQRT_FLT_MAX", "libgsl.scm", "GSL_SQRT_FLT_MIN", "libgsl.scm", "GSL_SQRT_MACH_EPS", "libgsl.scm", "GSL_SQRT_SFLT_EPSILON", "libgsl.scm", "GSL_SUCCESS", "libgsl.scm", "GSL_VERSION", "libgsl.scm", "ICANON", "libc.scm", "ICRNL", "libc.scm", "IEXTEN", "libc.scm", "IGNBRK", "libc.scm", "IGNCR", "libc.scm", "IGNPAR", "libc.scm", "IMAXBEL", "libc.scm", "INLCR", "libc.scm", "INPCK", "libc.scm", "INT16_MAX", "libc.scm", "INT16_MIN", "libc.scm", "INT32_MAX", "libc.scm", "INT32_MIN", "libc.scm", "INT64_MAX", "libc.scm", "INT64_MIN", "libc.scm", "INT8_MAX", "libc.scm", "INT8_MIN", "libc.scm", "INTMAX_MAX", "libc.scm", "INTMAX_MIN", "libc.scm", "INTPTR_MAX", "libc.scm", "INTPTR_MIN", "libc.scm", "INT_FAST16_MAX", "libc.scm", "INT_FAST16_MIN", "libc.scm", "INT_FAST32_MAX", "libc.scm", "INT_FAST32_MIN", "libc.scm", "INT_FAST64_MAX", "libc.scm", "INT_FAST64_MIN", "libc.scm", "INT_FAST8_MAX", "libc.scm", "INT_FAST8_MIN", "libc.scm", "INT_LEAST16_MAX", "libc.scm", "INT_LEAST16_MIN", "libc.scm", "INT_LEAST32_MAX", "libc.scm", "INT_LEAST32_MIN", "libc.scm", "INT_LEAST64_MAX", "libc.scm", "INT_LEAST64_MIN", "libc.scm", "INT_LEAST8_MAX", "libc.scm", "INT_LEAST8_MIN", "libc.scm", "INT_MAX", "libc.scm", "INT_MIN", "libc.scm", "IPPORT_BIFFUDP", "libc.scm", "IPPORT_CMDSERVER", "libc.scm", "IPPORT_DAYTIME", "libc.scm", "IPPORT_DISCARD", "libc.scm", "IPPORT_ECHO", "libc.scm", "IPPORT_EFSSERVER", "libc.scm", "IPPORT_EXECSERVER", "libc.scm", "IPPORT_FINGER", "libc.scm", "IPPORT_FTP", "libc.scm", "IPPORT_LOGINSERVER", "libc.scm", "IPPORT_MTP", "libc.scm", "IPPORT_NAMESERVER", "libc.scm", "IPPORT_NETSTAT", "libc.scm", "IPPORT_RESERVED", "libc.scm", "IPPORT_RJE", "libc.scm", "IPPORT_ROUTESERVER", "libc.scm", "IPPORT_SMTP", "libc.scm", "IPPORT_SUPDUP", "libc.scm", "IPPORT_SYSTAT", "libc.scm", "IPPORT_TELNET", "libc.scm", "IPPORT_TFTP", "libc.scm", "IPPORT_TIMESERVER", "libc.scm", "IPPORT_TTYLINK", "libc.scm", "IPPORT_USERRESERVED", "libc.scm", "IPPORT_WHOIS", "libc.scm", "IPPORT_WHOSERVER", "libc.scm", "IPPROTO_AH", "libc.scm", "IPPROTO_COMP", "libc.scm", "IPPROTO_DCCP", "libc.scm", "IPPROTO_DSTOPTS", "libc.scm", "IPPROTO_EGP", "libc.scm", "IPPROTO_ENCAP", "libc.scm", "IPPROTO_ESP", "libc.scm", "IPPROTO_FRAGMENT", "libc.scm", "IPPROTO_GRE", "libc.scm", "IPPROTO_HOPOPTS", "libc.scm", "IPPROTO_ICMP", "libc.scm", "IPPROTO_ICMPV6", "libc.scm", "IPPROTO_IDP", "libc.scm", "IPPROTO_IGMP", "libc.scm", "IPPROTO_IP", "libc.scm", "IPPROTO_IPIP", "libc.scm", "IPPROTO_IPV6", "libc.scm", "IPPROTO_MTP", "libc.scm", "IPPROTO_NONE", "libc.scm", "IPPROTO_PIM", "libc.scm", "IPPROTO_PUP", "libc.scm", "IPPROTO_RAW", "libc.scm", "IPPROTO_ROUTING", "libc.scm", "IPPROTO_RSVP", "libc.scm", "IPPROTO_SCTP", "libc.scm", "IPPROTO_TCP", "libc.scm", "IPPROTO_TP", "libc.scm", "IPPROTO_UDP", "libc.scm", "IPPROTO_UDPLITE", "libc.scm", "ISIG", "libc.scm", "ISTRIP", "libc.scm", "IUCLC", "libc.scm", "IUTF8", "libc.scm", "IXANY", "libc.scm", "IXOFF", "libc.scm", "IXON", "libc.scm", "LC_ADDRESS", "libc.scm", "LC_ALL", "libc.scm", "LC_COLLATE", "libc.scm", "LC_CTYPE", "libc.scm", "LC_IDENTIFICATION", "libc.scm", "LC_MEASUREMENT", "libc.scm", "LC_MESSAGES", "libc.scm", "LC_MONETARY", "libc.scm", "LC_NAME", "libc.scm", "LC_NUMERIC", "libc.scm", "LC_PAPER", "libc.scm", "LC_TELEPHONE", "libc.scm", "LC_TIME", "libc.scm", "LDBL_DIG", "libc.scm", "LDBL_EPSILON", "libc.scm", "LDBL_MANT_DIG", "libc.scm", "LDBL_MAX", "libc.scm", "LDBL_MAX_10_EXP", "libc.scm", "LDBL_MAX_EXP", "libc.scm", "LDBL_MIN", "libc.scm", "LDBL_MIN_10_EXP", "libc.scm", "LDBL_MIN_EXP", "libc.scm", "LINE_MAX", "libc.scm", "LLONG_MAX", "libc.scm", "LLONG_MIN", "libc.scm", "LONG_MAX", "libc.scm", "LONG_MIN", "libc.scm", "L_ctermid", "libc.scm", "L_tmpnam", "libc.scm", "MB_CUR_MAX", "libc.scm", "MSG_CMSG_CLOEXEC", "libc.scm", "MSG_CONFIRM", "libc.scm", "MSG_CTRUNC", "libc.scm", "MSG_DONTROUTE", "libc.scm", "MSG_DONTWAIT", "libc.scm", "MSG_EOR", "libc.scm", "MSG_ERRQUEUE", "libc.scm", "MSG_FIN", "libc.scm", "MSG_MORE", "libc.scm", "MSG_NOSIGNAL", "libc.scm", "MSG_OOB", "libc.scm", "MSG_PEEK", "libc.scm", "MSG_PROXY", "libc.scm", "MSG_RST", "libc.scm", "MSG_SYN", "libc.scm", "MSG_TRUNC", "libc.scm", "MSG_WAITALL", "libc.scm", "MSG_WAITFORONE", "libc.scm", "M_1_PI", "libm.scm", "M_2_PI", "libm.scm", "M_2_SQRTPI", "libm.scm", "M_E", "libm.scm", "M_LN10", "libm.scm", "M_LN2", "libm.scm", "M_LOG10E", "libm.scm", "M_LOG2E", "libm.scm", "M_PI", "libm.scm", "M_PI_2", "libm.scm", "M_PI_4", "libm.scm", "M_SQRT1_2", "libm.scm", "M_SQRT2", "libm.scm", "NGROUPS_MAX", "libc.scm", "NI_DGRAM", "libc.scm", "NI_NAMEREQD", "libc.scm", "NI_NOFQDN", "libc.scm", "NI_NUMERICHOST", "libc.scm", "NI_NUMERICSERV", "libc.scm", "NOFLSH", "libc.scm", "NSS_BUFLEN_PASSWD", "libc.scm", "NULL", "libc.scm", "OCRNL", "libc.scm", "OFDEL", "libc.scm", "OFILL", "libc.scm", "OLCUC", "libc.scm", "ONLCR", "libc.scm", "ONLRET", "libc.scm", "ONOCR", "libc.scm", "OPOST", "libc.scm", "O_ACCMODE", "libc.scm", "O_APPEND", "libc.scm", "O_ASYNC", "libc.scm", "O_CREAT", "libc.scm", "O_DSYNC", "libc.scm", "O_EXCL", "libc.scm", "O_FSYNC", "libc.scm", "O_NDELAY", "libc.scm", "O_NOCTTY", "libc.scm", "O_NONBLOCK", "libc.scm", "O_RDONLY", "libc.scm", "O_RDWR", "libc.scm", "O_RSYNC", "libc.scm", "O_SYNC", "libc.scm", "O_TRUNC", "libc.scm", "O_WRONLY", "libc.scm", "PARMRK", "libc.scm", "PF_APPLETALK", "libc.scm", "PF_ASH", "libc.scm", "PF_ATMPVC", "libc.scm", "PF_ATMSVC", "libc.scm", "PF_AX25", "libc.scm", "PF_BLUETOOTH", "libc.scm", "PF_BRIDGE", "libc.scm", "PF_CAN", "libc.scm", "PF_DECnet", "libc.scm", "PF_ECONET", "libc.scm", "PF_FILE", "libc.scm", "PF_IEEE802154", "libc.scm", "PF_INET", "libc.scm", "PF_INET6", "libc.scm", "PF_IPX", "libc.scm", "PF_IRDA", "libc.scm", "PF_ISDN", "libc.scm", "PF_IUCV", "libc.scm", "PF_KEY", "libc.scm", "PF_LLC", "libc.scm", "PF_LOCAL", "libc.scm", "PF_MAX", "libc.scm", "PF_NETBEUI", "libc.scm", "PF_NETLINK", "libc.scm", "PF_NETROM", "libc.scm", "PF_PACKET", "libc.scm", "PF_PHONET", "libc.scm", "PF_PPPOX", "libc.scm", "PF_RDS", "libc.scm", "PF_ROSE", "libc.scm", "PF_ROUTE", "libc.scm", "PF_RXRPC", "libc.scm", "PF_SECURITY", "libc.scm", "PF_SNA", "libc.scm", "PF_TIPC", "libc.scm", "PF_UNIX", "libc.scm", "PF_UNSPEC", "libc.scm", "PF_WANPIPE", "libc.scm", "PF_X25", "libc.scm", "POSIX_FADV_DONTNEED", "libc.scm", "POSIX_FADV_NOREUSE", "libc.scm", "POSIX_FADV_NORMAL", "libc.scm", "POSIX_FADV_RANDOM", "libc.scm", "POSIX_FADV_SEQUENTIAL", "libc.scm", "POSIX_FADV_WILLNEED", "libc.scm", "PRIO_MAX", "libc.scm", "PRIO_MIN", "libc.scm", "PRIO_PGRP", "libc.scm", "PRIO_PROCESS", "libc.scm", "PRIO_USER", "libc.scm", "PTRDIFF_MAX", "libc.scm", "PTRDIFF_MIN", "libc.scm", "P_tmpdir", "libc.scm", "RAND_MAX", "libc.scm", "RE_DUP_MAX", "libc.scm", "RLIMIT_AS", "libc.scm", "RLIMIT_CORE", "libc.scm", "RLIMIT_CPU", "libc.scm", "RLIMIT_DATA", "libc.scm", "RLIMIT_FSIZE", "libc.scm", "RLIMIT_LOCKS", "libc.scm", "RLIMIT_MEMLOCK", "libc.scm", "RLIMIT_MSGQUEUE", "libc.scm", "RLIMIT_NICE", "libc.scm", "RLIMIT_NLIMITS", "libc.scm", "RLIMIT_NOFILE", "libc.scm", "RLIMIT_NPROC", "libc.scm", "RLIMIT_OFILE", "libc.scm", "RLIMIT_RSS", "libc.scm", "RLIMIT_RTPRIO", "libc.scm", "RLIMIT_SIGPENDING", "libc.scm", "RLIMIT_STACK", "libc.scm", "RLIM_INFINITY", "libc.scm", "RLIM_NLIMITS", "libc.scm", "RLIM_SAVED_CUR", "libc.scm", "RLIM_SAVED_MAX", "libc.scm", "RTLD_BINDING_MASK", "libdl.scm", "RTLD_DEEPBIND", "libdl.scm", "RTLD_LOCAL", "libdl.scm", "RTLD_NODELETE", "libdl.scm", "RTLD_NOLOAD", "libdl.scm", "RUSAGE_CHILDREN", "libc.scm", "RUSAGE_SELF", "libc.scm", "R_OK", "libc.scm", "SA_NOCLDSTOP", "libc.scm", "SA_NOCLDWAIT", "libc.scm", "SA_NODEFER", "libc.scm", "SA_NOMASK", "libc.scm", "SA_ONESHOT", "libc.scm", "SA_ONSTACK", "libc.scm", "SA_RESETHAND", "libc.scm", "SA_RESTART", "libc.scm", "SA_SIGINFO", "libc.scm", "SA_STACK", "libc.scm", "SCHAR_MAX", "libc.scm", "SCHAR_MIN", "libc.scm", "SEEK_CUR", "libc.scm", "SEEK_END", "libc.scm", "SEEK_SET", "libc.scm", "SHRT_MAX", "libc.scm", "SHRT_MIN", "libc.scm", "SHUT_RD", "libc.scm", "SHUT_RDWR", "libc.scm", "SHUT_WR", "libc.scm", "SIGABRT", "libc.scm", "SIGALRM", "libc.scm", "SIGBUS", "libc.scm", "SIGCHLD", "libc.scm", "SIGCLD", "libc.scm", "SIGCONT", "libc.scm", "SIGFPE", "libc.scm", "SIGHUP", "libc.scm", "SIGILL", "libc.scm", "SIGINT", "libc.scm", "SIGIO", "libc.scm", "SIGIOT", "libc.scm", "SIGKILL", "libc.scm", "SIGPIPE", "libc.scm", "SIGPOLL", "libc.scm", "SIGPROF", "libc.scm", "SIGPWR", "libc.scm", "SIGQUIT", "libc.scm", "SIGSEGV", "libc.scm", "SIGSTKFLT", "libc.scm", "SIGSTOP", "libc.scm", "SIGSYS", "libc.scm", "SIGTERM", "libc.scm", "SIGTRAP", "libc.scm", "SIGTSTP", "libc.scm", "SIGTTIN", "libc.scm", "SIGTTOU", "libc.scm", "SIGUNUSED", "libc.scm", "SIGURG", "libc.scm", "SIGUSR1", "libc.scm", "SIGUSR2", "libc.scm", "SIGVTALRM", "libc.scm", "SIGWINCH", "libc.scm", "SIGXCPU", "libc.scm", "SIGXFSZ", "libc.scm", "SIG_ATOMIC_MAX", "libc.scm", "SIG_ATOMIC_MIN", "libc.scm", "SIG_BLOCK", "libc.scm", "SIG_DFL", "libc.scm", "SIG_ERR", "libc.scm", "SIG_IGN", "libc.scm", "SIG_SETMASK", "libc.scm", "SIG_UNBLOCK", "libc.scm", "SIZE_MAX", "libc.scm", "SOCK_CLOEXEC", "libc.scm", "SOCK_DCCP", "libc.scm", "SOCK_DGRAM", "libc.scm", "SOCK_NONBLOCK", "libc.scm", "SOCK_PACKET", "libc.scm", "SOCK_RAW", "libc.scm", "SOCK_RDM", "libc.scm", "SOCK_SEQPACKET", "libc.scm", "SOCK_STREAM", "libc.scm", "SOL_AAL", "libc.scm", "SOL_ATM", "libc.scm", "SOL_DECNET", "libc.scm", "SOL_IRDA", "libc.scm", "SOL_PACKET", "libc.scm", "SOL_RAW", "libc.scm", "SOL_X25", "libc.scm", "SSIZE_MAX", "libc.scm", "STDERR_FILENO", "libc.scm", "STDIN_FILENO", "libc.scm", "STDOUT_FILENO", "libc.scm", "S_IFBLK", "libc.scm", "S_IFCHR", "libc.scm", "S_IFDIR", "libc.scm", "S_IFIFO", "libc.scm", "S_IFLNK", "libc.scm", "S_IFMT", "libc.scm", "S_IFREG", "libc.scm", "S_IFSOCK", "libc.scm", "S_IRGRP", "libc.scm", "S_IROTH", "libc.scm", "S_IRUSR", "libc.scm", "S_IRWXG", "libc.scm", "S_IRWXO", "libc.scm", "S_IRWXU", "libc.scm", "S_ISBLK", "libc.scm", "S_ISCHR", "libc.scm", "S_ISDIR", "libc.scm", "S_ISFIFO", "libc.scm", "S_ISGID", "libc.scm", "S_ISLNK", "libc.scm", "S_ISREG", "libc.scm", "S_ISSOCK", "libc.scm", "S_ISUID", "libc.scm", "S_IWGRP", "libc.scm", "S_IWOTH", "libc.scm", "S_IWUSR", "libc.scm", "S_IXGRP", "libc.scm", "S_IXOTH", "libc.scm", "S_IXUSR", "libc.scm", "Si", "numerics.scm", "TCIFLUSH", "libc.scm", "TCIOFF", "libc.scm", "TCIOFLUSH", "libc.scm", "TCION", "libc.scm", "TCOFLUSH", "libc.scm", "TCOOFF", "libc.scm", "TCOON", "libc.scm", "TCSADRAIN", "libc.scm", "TCSAFLUSH", "libc.scm", "TCSANOW", "libc.scm", "TMP_MAX", "libc.scm", "TOSTOP", "libc.scm", "UCHAR_MAX", "libc.scm", "UINT16_MAX", "libc.scm", "UINT32_MAX", "libc.scm", "UINT64_MAX", "libc.scm", "UINT8_MAX", "libc.scm", "UINTMAX_MAX", "libc.scm", "UINTPTR_MAX", "libc.scm", "UINT_FAST16_MAX", "libc.scm", "UINT_FAST32_MAX", "libc.scm", "UINT_FAST64_MAX", "libc.scm", "UINT_FAST8_MAX", "libc.scm", "UINT_LEAST16_MAX", "libc.scm", "UINT_LEAST32_MAX", "libc.scm", "UINT_LEAST64_MAX", "libc.scm", "UINT_LEAST8_MAX", "libc.scm", "UINT_MAX", "libc.scm", "ULLONG_MAX", "libc.scm", "ULONG_MAX", "libc.scm", "USHRT_MAX", "libc.scm", "VDISCARD", "libc.scm", "VEOF", "libc.scm", "VEOL", "libc.scm", "VEOL2", "libc.scm", "VERASE", "libc.scm", "VINTR", "libc.scm", "VKILL", "libc.scm", "VLNEXT", "libc.scm", "VMIN", "libc.scm", "VQUIT", "libc.scm", "VREPRINT", "libc.scm", "VSTART", "libc.scm", "VSTOP", "libc.scm", "VSUSP", "libc.scm", "VSWTC", "libc.scm", "VTIME", "libc.scm", "VWERASE", "libc.scm", "WCHAR_MAX", "libc.scm", "WCHAR_MIN", "libc.scm", "WCONTINUED", "libc.scm", "WEXITED", "libc.scm", "WEXITSTATUS", "libc.scm", "WIFEXITED", "libc.scm", "WIFSIGNALED", "libc.scm", "WIFSTOPPED", "libc.scm", "WINT_MAX", "libc.scm", "WINT_MIN", "libc.scm", "WNOHANG", "libc.scm", "WNOWAIT", "libc.scm", "WRDE_APPEND", "libc.scm", "WRDE_BADCHAR", "libc.scm", "WRDE_BADVAL", "libc.scm", "WRDE_CMDSUB", "libc.scm", "WRDE_DOOFFS", "libc.scm", "WRDE_NOCMD", "libc.scm", "WRDE_NOSPACE", "libc.scm", "WRDE_REUSE", "libc.scm", "WRDE_SHOWERR", "libc.scm", "WRDE_SYNTAX", "libc.scm", "WRDE_UNDEF", "libc.scm", "WSTOPPED", "libc.scm", "WSTOPSIG", "libc.scm", "WTERMSIG", "libc.scm", "WUNTRACED", "libc.scm", "W_OK", "libc.scm", "X_OK", "libc.scm", "_CS_GNU_LIBC_VERSION", "libc.scm", "_CS_GNU_LIBPTHREAD_VERSION", "libc.scm", "_CS_PATH", "libc.scm", "_IOFBF", "libc.scm", "_IOLBF", "libc.scm", "_IONBF", "libc.scm", "_PATH_NETWORKS", "libc.scm", "_PATH_NSSWITCH_CONF", "libc.scm", "_PATH_PROTOCOLS", "libc.scm", "_PATH_SERVICES", "libc.scm", "_PC_2_SYMLINKS", "libc.scm", "_PC_ALLOC_SIZE_MIN", "libc.scm", "_PC_ASYNC_IO", "libc.scm", "_PC_CHOWN_RESTRICTED", "libc.scm", "_PC_FILESIZEBITS", "libc.scm", "_PC_LINK_MAX", "libc.scm", "_PC_MAX_CANON", "libc.scm", "_PC_MAX_INPUT", "libc.scm", "_PC_NAME_MAX", "libc.scm", "_PC_NO_TRUNC", "libc.scm", "_PC_PATH_MAX", "libc.scm", "_PC_PIPE_BUF", "libc.scm", "_PC_PRIO_IO", "libc.scm", "_PC_REC_INCR_XFER_SIZE", "libc.scm", "_PC_REC_MAX_XFER_SIZE", "libc.scm", "_PC_REC_MIN_XFER_SIZE", "libc.scm", "_PC_REC_XFER_ALIGN", "libc.scm", "_PC_SOCK_MAXBUF", "libc.scm", "_PC_SYMLINK_MAX", "libc.scm", "_PC_SYNC_IO", "libc.scm", "_PC_VDISABLE", "libc.scm", "_POSIX2_BC_BASE_MAX", "libc.scm", "_POSIX2_BC_DIM_MAX", "libc.scm", "_POSIX2_BC_SCALE_MAX", "libc.scm", "_POSIX2_BC_STRING_MAX", "libc.scm", "_POSIX2_CHARCLASS_NAME_MAX", "libc.scm", "_POSIX2_CHAR_TERM", "libc.scm", "_POSIX2_COLL_WEIGHTS_MAX", "libc.scm", "_POSIX2_EXPR_NEST_MAX", "libc.scm", "_POSIX2_LINE_MAX", "libc.scm", "_POSIX2_RE_DUP_MAX", "libc.scm", "_POSIX2_VERSION", "libc.scm", "_POSIX_ADVISORY_INFO", "libc.scm", "_POSIX_AIO_LISTIO_MAX", "libc.scm", "_POSIX_AIO_MAX", "libc.scm", "_POSIX_ARG_MAX", "libc.scm", "_POSIX_ASYNCHRONOUS_IO", "libc.scm", "_POSIX_ASYNC_IO", "libc.scm", "_POSIX_BARRIERS", "libc.scm", "_POSIX_CHILD_MAX", "libc.scm", "_POSIX_CHOWN_RESTRICTED", "libc.scm", "_POSIX_CLOCKRES_MIN", "libc.scm", "_POSIX_CLOCK_SELECTION", "libc.scm", "_POSIX_CPUTIME", "libc.scm", "_POSIX_DELAYTIMER_MAX", "libc.scm", "_POSIX_FSYNC", "libc.scm", "_POSIX_HOST_NAME_MAX", "libc.scm", "_POSIX_IPV6", "libc.scm", "_POSIX_JOB_CONTROL", "libc.scm", "_POSIX_LINK_MAX", "libc.scm", "_POSIX_LOGIN_NAME_MAX", "libc.scm", "_POSIX_MAPPED_FILES", "libc.scm", "_POSIX_MAX_CANON", "libc.scm", "_POSIX_MAX_INPUT", "libc.scm", "_POSIX_MEMLOCK", "libc.scm", "_POSIX_MEMLOCK_RANGE", "libc.scm", "_POSIX_MEMORY_PROTECTION", "libc.scm", "_POSIX_MESSAGE_PASSING", "libc.scm", "_POSIX_MONOTONIC_CLOCK", "libc.scm", "_POSIX_MQ_OPEN_MAX", "libc.scm", "_POSIX_MQ_PRIO_MAX", "libc.scm", "_POSIX_NAME_MAX", "libc.scm", "_POSIX_NGROUPS_MAX", "libc.scm", "_POSIX_NO_TRUNC", "libc.scm", "_POSIX_OPEN_MAX", "libc.scm", "_POSIX_PATH_MAX", "libc.scm", "_POSIX_PIPE_BUF", "libc.scm", "_POSIX_PRIORITIZED_IO", "libc.scm", "_POSIX_PRIORITY_SCHEDULING", "libc.scm", "_POSIX_RAW_SOCKETS", "libc.scm", "_POSIX_READER_WRITER_LOCKS", "libc.scm", "_POSIX_REALTIME_SIGNALS", "libc.scm", "_POSIX_REENTRANT_FUNCTIONS", "libc.scm", "_POSIX_REGEXP", "libc.scm", "_POSIX_RE_DUP_MAX", "libc.scm", "_POSIX_RTSIG_MAX", "libc.scm", "_POSIX_SAVED_IDS", "libc.scm", "_POSIX_SEMAPHORES", "libc.scm", "_POSIX_SEM_NSEMS_MAX", "libc.scm", "_POSIX_SEM_VALUE_MAX", "libc.scm", "_POSIX_SHARED_MEMORY_OBJECTS", "libc.scm", "_POSIX_SHELL", "libc.scm", "_POSIX_SIGQUEUE_MAX", "libc.scm", "_POSIX_SPAWN", "libc.scm", "_POSIX_SPIN_LOCKS", "libc.scm", "_POSIX_SPORADIC_SERVER", "libc.scm", "_POSIX_SSIZE_MAX", "libc.scm", "_POSIX_STREAM_MAX", "libc.scm", "_POSIX_SYMLINK_MAX", "libc.scm", "_POSIX_SYMLOOP_MAX", "libc.scm", "_POSIX_SYNCHRONIZED_IO", "libc.scm", "_POSIX_THREADS", "libc.scm", "_POSIX_THREAD_ATTR_STACKADDR", "libc.scm", "_POSIX_THREAD_ATTR_STACKSIZE", "libc.scm", "_POSIX_THREAD_CPUTIME", "libc.scm", "_POSIX_THREAD_PRIORITY_SCHEDULING", "libc.scm", "_POSIX_THREAD_PRIO_INHERIT", "libc.scm", "_POSIX_THREAD_PRIO_PROTECT", "libc.scm", "_POSIX_THREAD_PROCESS_SHARED", "libc.scm", "_POSIX_THREAD_SAFE_FUNCTIONS", "libc.scm", "_POSIX_THREAD_SPORADIC_SERVER", "libc.scm", "_POSIX_TIMEOUTS", "libc.scm", "_POSIX_TIMERS", "libc.scm", "_POSIX_TIMER_MAX", "libc.scm", "_POSIX_TRACE", "libc.scm", "_POSIX_TRACE_EVENT_FILTER", "libc.scm", "_POSIX_TRACE_INHERIT", "libc.scm", "_POSIX_TRACE_LOG", "libc.scm", "_POSIX_TTY_NAME_MAX", "libc.scm", "_POSIX_TYPED_MEMORY_OBJECTS", "libc.scm", "_POSIX_TZNAME_MAX", "libc.scm", "_POSIX_VDISABLE", "libc.scm", "_POSIX_VERSION", "libc.scm", "_SC_2_CHAR_TERM", "libc.scm", "_SC_2_C_BIND", "libc.scm", "_SC_2_C_DEV", "libc.scm", "_SC_2_C_VERSION", "libc.scm", "_SC_2_FORT_DEV", "libc.scm", "_SC_2_FORT_RUN", "libc.scm", "_SC_2_LOCALEDEF", "libc.scm", "_SC_2_PBS", "libc.scm", "_SC_2_PBS_ACCOUNTING", "libc.scm", "_SC_2_PBS_CHECKPOINT", "libc.scm", "_SC_2_PBS_LOCATE", "libc.scm", "_SC_2_PBS_MESSAGE", "libc.scm", "_SC_2_PBS_TRACK", "libc.scm", "_SC_2_SW_DEV", "libc.scm", "_SC_2_UPE", "libc.scm", "_SC_2_VERSION", "libc.scm", "_SC_ADVISORY_INFO", "libc.scm", "_SC_AIO_LISTIO_MAX", "libc.scm", "_SC_AIO_MAX", "libc.scm", "_SC_AIO_PRIO_DELTA_MAX", "libc.scm", "_SC_ARG_MAX", "libc.scm", "_SC_ASYNCHRONOUS_IO", "libc.scm", "_SC_ATEXIT_MAX", "libc.scm", "_SC_AVPHYS_PAGES", "libc.scm", "_SC_BARRIERS", "libc.scm", "_SC_BASE", "libc.scm", "_SC_BC_BASE_MAX", "libc.scm", "_SC_BC_DIM_MAX", "libc.scm", "_SC_BC_SCALE_MAX", "libc.scm", "_SC_BC_STRING_MAX", "libc.scm", "_SC_CHARCLASS_NAME_MAX", "libc.scm", "_SC_CHAR_BIT", "libc.scm", "_SC_CHAR_MAX", "libc.scm", "_SC_CHAR_MIN", "libc.scm", "_SC_CHILD_MAX", "libc.scm", "_SC_CLK_TCK", "libc.scm", "_SC_CLOCK_SELECTION", "libc.scm", "_SC_COLL_WEIGHTS_MAX", "libc.scm", "_SC_CPUTIME", "libc.scm", "_SC_C_LANG_SUPPORT", "libc.scm", "_SC_C_LANG_SUPPORT_R", "libc.scm", "_SC_DELAYTIMER_MAX", "libc.scm", "_SC_DEVICE_IO", "libc.scm", "_SC_DEVICE_SPECIFIC", "libc.scm", "_SC_DEVICE_SPECIFIC_R", "libc.scm", "_SC_EQUIV_CLASS_MAX", "libc.scm", "_SC_EXPR_NEST_MAX", "libc.scm", "_SC_FD_MGMT", "libc.scm", "_SC_FIFO", "libc.scm", "_SC_FILE_ATTRIBUTES", "libc.scm", "_SC_FILE_LOCKING", "libc.scm", "_SC_FILE_SYSTEM", "libc.scm", "_SC_FSYNC", "libc.scm", "_SC_GETGR_R_SIZE_MAX", "libc.scm", "_SC_GETPW_R_SIZE_MAX", "libc.scm", "_SC_HOST_NAME_MAX", "libc.scm", "_SC_INT_MAX", "libc.scm", "_SC_INT_MIN", "libc.scm", "_SC_IOV_MAX", "libc.scm", "_SC_IPV6", "libc.scm", "_SC_JOB_CONTROL", "libc.scm", "_SC_LEVEL1_DCACHE_ASSOC", "libc.scm", "_SC_LEVEL1_DCACHE_LINESIZE", "libc.scm", "_SC_LEVEL1_DCACHE_SIZE", "libc.scm", "_SC_LEVEL1_ICACHE_ASSOC", "libc.scm", "_SC_LEVEL1_ICACHE_LINESIZE", "libc.scm", "_SC_LEVEL1_ICACHE_SIZE", "libc.scm", "_SC_LEVEL2_CACHE_ASSOC", "libc.scm", "_SC_LEVEL2_CACHE_LINESIZE", "libc.scm", "_SC_LEVEL2_CACHE_SIZE", "libc.scm", "_SC_LEVEL3_CACHE_ASSOC", "libc.scm", "_SC_LEVEL3_CACHE_LINESIZE", "libc.scm", "_SC_LEVEL3_CACHE_SIZE", "libc.scm", "_SC_LEVEL4_CACHE_ASSOC", "libc.scm", "_SC_LEVEL4_CACHE_LINESIZE", "libc.scm", "_SC_LEVEL4_CACHE_SIZE", "libc.scm", "_SC_LINE_MAX", "libc.scm", "_SC_LOGIN_NAME_MAX", "libc.scm", "_SC_LONG_BIT", "libc.scm", "_SC_MAPPED_FILES", "libc.scm", "_SC_MB_LEN_MAX", "libc.scm", "_SC_MEMLOCK", "libc.scm", "_SC_MEMLOCK_RANGE", "libc.scm", "_SC_MEMORY_PROTECTION", "libc.scm", "_SC_MESSAGE_PASSING", "libc.scm", "_SC_MONOTONIC_CLOCK", "libc.scm", "_SC_MQ_OPEN_MAX", "libc.scm", "_SC_MQ_PRIO_MAX", "libc.scm", "_SC_MULTI_PROCESS", "libc.scm", "_SC_NETWORKING", "libc.scm", "_SC_NGROUPS_MAX", "libc.scm", "_SC_NL_ARGMAX", "libc.scm", "_SC_NL_LANGMAX", "libc.scm", "_SC_NL_MSGMAX", "libc.scm", "_SC_NL_NMAX", "libc.scm", "_SC_NL_SETMAX", "libc.scm", "_SC_NL_TEXTMAX", "libc.scm", "_SC_NPROCESSORS_CONF", "libc.scm", "_SC_NPROCESSORS_ONLN", "libc.scm", "_SC_NZERO", "libc.scm", "_SC_OPEN_MAX", "libc.scm", "_SC_PAGESIZE", "libc.scm", "_SC_PAGE_SIZE", "libc.scm", "_SC_PASS_MAX", "libc.scm", "_SC_PHYS_PAGES", "libc.scm", "_SC_PII", "libc.scm", "_SC_PII_INTERNET", "libc.scm", "_SC_PII_INTERNET_DGRAM", "libc.scm", "_SC_PII_INTERNET_STREAM", "libc.scm", "_SC_PII_OSI", "libc.scm", "_SC_PII_OSI_CLTS", "libc.scm", "_SC_PII_OSI_COTS", "libc.scm", "_SC_PII_OSI_M", "libc.scm", "_SC_PII_SOCKET", "libc.scm", "_SC_PII_XTI", "libc.scm", "_SC_PIPE", "libc.scm", "_SC_POLL", "libc.scm", "_SC_PRIORITIZED_IO", "libc.scm", "_SC_PRIORITY_SCHEDULING", "libc.scm", "_SC_RAW_SOCKETS", "libc.scm", "_SC_READER_WRITER_LOCKS", "libc.scm", "_SC_REALTIME_SIGNALS", "libc.scm", "_SC_REGEXP", "libc.scm", "_SC_REGEX_VERSION", "libc.scm", "_SC_RE_DUP_MAX", "libc.scm", "_SC_RTSIG_MAX", "libc.scm", "_SC_SAVED_IDS", "libc.scm", "_SC_SCHAR_MAX", "libc.scm", "_SC_SCHAR_MIN", "libc.scm", "_SC_SELECT", "libc.scm", "_SC_SEMAPHORES", "libc.scm", "_SC_SEM_NSEMS_MAX", "libc.scm", "_SC_SEM_VALUE_MAX", "libc.scm", "_SC_SHARED_MEMORY_OBJECTS", "libc.scm", "_SC_SHELL", "libc.scm", "_SC_SHRT_MAX", "libc.scm", "_SC_SHRT_MIN", "libc.scm", "_SC_SIGNALS", "libc.scm", "_SC_SIGQUEUE_MAX", "libc.scm", "_SC_SINGLE_PROCESS", "libc.scm", "_SC_SPAWN", "libc.scm", "_SC_SPIN_LOCKS", "libc.scm", "_SC_SPORADIC_SERVER", "libc.scm", "_SC_SSIZE_MAX", "libc.scm", "_SC_SS_REPL_MAX", "libc.scm", "_SC_STREAMS", "libc.scm", "_SC_STREAM_MAX", "libc.scm", "_SC_SYMLOOP_MAX", "libc.scm", "_SC_SYNCHRONIZED_IO", "libc.scm", "_SC_SYSTEM_DATABASE", "libc.scm", "_SC_SYSTEM_DATABASE_R", "libc.scm", "_SC_THREADS", "libc.scm", "_SC_THREAD_ATTR_STACKADDR", "libc.scm", "_SC_THREAD_ATTR_STACKSIZE", "libc.scm", "_SC_THREAD_CPUTIME", "libc.scm", "_SC_THREAD_DESTRUCTOR_ITERATIONS", "libc.scm", "_SC_THREAD_KEYS_MAX", "libc.scm", "_SC_THREAD_PRIORITY_SCHEDULING", "libc.scm", "_SC_THREAD_PRIO_INHERIT", "libc.scm", "_SC_THREAD_PRIO_PROTECT", "libc.scm", "_SC_THREAD_PROCESS_SHARED", "libc.scm", "_SC_THREAD_ROBUST_PRIO_INHERIT", "libc.scm", "_SC_THREAD_ROBUST_PRIO_PROTECT", "libc.scm", "_SC_THREAD_SAFE_FUNCTIONS", "libc.scm", "_SC_THREAD_SPORADIC_SERVER", "libc.scm", "_SC_THREAD_STACK_MIN", "libc.scm", "_SC_THREAD_THREADS_MAX", "libc.scm", "_SC_TIMEOUTS", "libc.scm", "_SC_TIMERS", "libc.scm", "_SC_TIMER_MAX", "libc.scm", "_SC_TRACE", "libc.scm", "_SC_TRACE_EVENT_FILTER", "libc.scm", "_SC_TRACE_EVENT_NAME_MAX", "libc.scm", "_SC_TRACE_INHERIT", "libc.scm", "_SC_TRACE_LOG", "libc.scm", "_SC_TRACE_NAME_MAX", "libc.scm", "_SC_TRACE_SYS_MAX", "libc.scm", "_SC_TRACE_USER_EVENT_MAX", "libc.scm", "_SC_TTY_NAME_MAX", "libc.scm", "_SC_TYPED_MEMORY_OBJECTS", "libc.scm", "_SC_TZNAME_MAX", "libc.scm", "_SC_T_IOV_MAX", "libc.scm", "_SC_UCHAR_MAX", "libc.scm", "_SC_UINT_MAX", "libc.scm", "_SC_UIO_MAXIOV", "libc.scm", "_SC_ULONG_MAX", "libc.scm", "_SC_USER_GROUPS", "libc.scm", "_SC_USER_GROUPS_R", "libc.scm", "_SC_USHRT_MAX", "libc.scm", "_SC_VERSION", "libc.scm", "_SC_WORD_BIT", "libc.scm", "__BIGGEST_ALIGNMENT__", "libm.scm", "__BIG_ENDIAN", "libc.scm", "__BYTE_ORDER", "libc.scm", "__CHAR_BIT__", "libm.scm", "__DBL_DENORM_MIN__", "libm.scm", "__DBL_DIG__", "libm.scm", "__DBL_EPSILON__", "libm.scm", "__DBL_MANT_DIG__", "libm.scm", "__DBL_MAX_10_EXP__", "libm.scm", "__DBL_MAX_EXP__", "libm.scm", "__DBL_MAX__", "libm.scm", "__DBL_MIN_10_EXP__", "libm.scm", "__DBL_MIN_EXP__", "libm.scm", "__DBL_MIN__", "libm.scm", "__DECIMAL_DIG__", "libm.scm", "__FLT_DENORM_MIN__", "libm.scm", "__FLT_DIG__", "libm.scm", "__FLT_EPSILON__", "libm.scm", "__FLT_MANT_DIG__", "libm.scm", "__FLT_MAX_10_EXP__", "libm.scm", "__FLT_MAX_EXP__", "libm.scm", "__FLT_MAX__", "libm.scm", "__FLT_MIN_10_EXP__", "libm.scm", "__FLT_MIN_EXP__", "libm.scm", "__FLT_MIN__", "libm.scm", "__FLT_RADIX__", "libm.scm", "__GLIBC_MINOR__", "libc.scm", "__GLIBC__", "libc.scm", "__INTMAX_MAX__", "libm.scm", "__INT_MAX__", "libm.scm", "__LDBL_DENORM_MIN__", "libm.scm", "__LDBL_DIG__", "libm.scm", "__LDBL_EPSILON__", "libm.scm", "__LDBL_MANT_DIG__", "libm.scm", "__LDBL_MAX_10_EXP__", "libm.scm", "__LDBL_MAX_EXP__", "libm.scm", "__LDBL_MAX__", "libm.scm", "__LDBL_MIN_10_EXP__", "libm.scm", "__LDBL_MIN_EXP__", "libm.scm", "__LDBL_MIN__", "libm.scm", "__LITTLE_ENDIAN", "libc.scm", "__LONG_LONG_MAX__", "libm.scm", "__LONG_MAX__", "libm.scm", "__SIZEOF_DOUBLE__", "libm.scm", "__SIZEOF_FLOAT__", "libm.scm", "__SIZEOF_INT__", "libm.scm", "__SIZEOF_LONG_DOUBLE__", "libm.scm", "__SIZEOF_LONG_LONG__", "libm.scm", "__SIZEOF_LONG__", "libm.scm", "__SIZEOF_POINTER__", "libm.scm", "__SIZEOF_SHORT__", "libm.scm", "__SIZEOF_SIZE_T__", "libm.scm", "__S_IFLNK", "libc.scm", "__VERSION__", "libm.scm", "__WORDSIZE", "libc.scm", "_exit", "libc.scm", "a-cricket", "animals.scm", "a-frog", "animals.scm", "abcos", "generators.scm", "abcos?", "generators.scm", "absin", "generators.scm", "absin?", "generators.scm", "acadian-flycatcher", "animals.scm", "accept", "libc.scm", "access", "libc.scm", "acorn-woodpecker", "animals.scm", "add-envelopes", "env.scm", "add-notes", "examp.scm", "add-predicate", "stuff.scm", "addenv", "jcvoi.scm", "addrinfo.ai_canonname", "libc.scm", "addrinfo.ai_family", "libc.scm", "addrinfo.ai_flags", "libc.scm", "addrinfo.ai_next", "libc.scm", "addrinfo.ai_protocol", "libc.scm", "addrinfo.ai_socktype", "libc.scm", "addrinfo.make", "libc.scm", "addrinfo.set_ai_family", "libc.scm", "addrinfo.set_ai_flags", "libc.scm", "addrinfo.set_ai_protocol", "libc.scm", "addrinfo.set_ai_socktype", "libc.scm", "adjoin", "stuff.scm", "adjustable-oscil", "generators.scm", "adjustable-oscil?", "generators.scm", "adjustable-sawtooth-wave", "generators.scm", "adjustable-sawtooth-wave?", "generators.scm", "adjustable-square-wave", "generators.scm", "adjustable-square-wave?", "generators.scm", "adjustable-triangle-wave", "generators.scm", "adjustable-triangle-wave?", "generators.scm", "adsat", "dsp.scm", "alarm", "libc.scm", "all-chans", "examp.scm", "all-methods", "stuff.scm", "am", "examp.scm", "amargosa-toad", "animals.scm", "ambisonics-channels", "dlocsig.scm", "american-crow", "animals.scm", "american-crow-no-formants", "animals.scm", "american-robin", "animals.scm", "american-toad", "animals.scm", "analog->digital", "analog-filter.scm", "angles-in-degree", "dlocsig.scm", "angles-in-radians", "dlocsig.scm", "angles-in-turns", "dlocsig.scm", "anoi", "clm-ins.scm", "any-env-channel", "extensions.scm", "any-random", "dsp.scm", "any?", "stuff.scm", "aref", "jcvoi.scm", "arrange-speakers", "dlocsig.scm", "array-set!", "maxf.scm", "asctime", "libc.scm", "ash-throated-flycatcher", "animals.scm", "asyfm-I", "generators.scm", "asyfm-J", "generators.scm", "asyfm?", "generators.scm", "asymmetric-difference", "stuff.scm", "atan2", "libm.scm", "atof", "libc.scm", "atoi", "libc.scm", "atol", "libc.scm", "atoll", "libc.scm", "attack-point", "noise.scm", "attract", "clm-ins.scm", "auto-dot", "examp.scm", "auto-save", "autosave.scm", "aux-f", "numerics.scm", "aux-g", "numerics.scm", "b-american-widgeon", "bird.scm", "b-audubons-warbler", "bird.scm", "b-bachmans-sparrow", "bird.scm", "b-bairds-sparrow", "bird.scm", "b-black-chinned-sparrow", "bird.scm", "b-black-necked-stilt", "bird.scm", "b-black-throated-gray-warbler", "bird.scm", "b-black-throated-sparrow", "bird.scm", "b-blue-gray-gnatcatcher", "bird.scm", "b-bobwhite", "bird.scm", "b-cassins-kingbird", "bird.scm", "b-cedar-waxwing", "bird.scm", "b-cerulean-warbler", "bird.scm", "b-chestnut-sided-warbler", "bird.scm", "b-chipping-sparrow", "bird.scm", "b-chuck-wills-widow", "bird.scm", "b-eastern-bluebird", "bird.scm", "b-eastern-phoebe", "bird.scm", "b-golden-crowned-sparrow", "bird.scm", "b-grasshopper-sparrow", "bird.scm", "b-great-horned-owl", "bird.scm", "b-hooded-warbler", "bird.scm", "b-indigo-bunting", "bird.scm", "b-kentucky-warbler", "bird.scm", "b-lark-bunting", "bird.scm", "b-louisiana-waterthrush", "bird.scm", "b-nashville-warbler", "bird.scm", "b-orchard-oriole", "bird.scm", "b-painted-bunting", "bird.scm", "b-pigeon-hawk", "bird.scm", "b-prothonotary-warbler", "bird.scm", "b-robin", "bird.scm", "b-rufous-sided-towhee", "bird.scm", "b-scissor-tailed-flycatcher", "bird.scm", "b-solitary-vireo", "bird.scm", "b-swamp-sparrow", "bird.scm", "b-western-flycatcher", "bird.scm", "b-western-meadowlark", "bird.scm", "b-yellow-warbler", "bird.scm", "bachmans-sparrow", "animals.scm", "balance", "clm-ins.scm", "balance-avg", "clm-ins.scm", "bald-eagle", "animals.scm", "barking-tree-frog", "animals.scm", "barn-owl", "animals.scm", "barred-owl-1", "animals.scm", "bernoulli-poly", "numerics.scm", "bernoulli3", "numerics.scm", "bes-fm", "clm-ins.scm", "bess", "generators.scm", "bess?", "generators.scm", "bessel-prototype", "analog-filter.scm", "bezier-3d", "dlocsig.scm", "bezier-bx", "dlocsig.scm", "bezier-by", "dlocsig.scm", "bezier-bz", "dlocsig.scm", "bezier-curvature", "dlocsig.scm", "bezier-error", "dlocsig.scm", "bezier-path", "dlocsig.scm", "bezier-polar", "dlocsig.scm", "bezier-render", "dlocsig.scm", "bezier-v", "dlocsig.scm", "bezier-x", "dlocsig.scm", "bezier-y", "dlocsig.scm", "bezier-z", "dlocsig.scm", "big-amplitude-modulate", "big-gens.scm", "big-array-clear", "big-gens.scm", "big-array-interp", "big-gens.scm", "big-array-normalize", "big-gens.scm", "big-contrast-enhancement", "big-gens.scm", "big-db->linear", "big-gens.scm", "big-degrees->radians", "big-gens.scm", "big-dot-product", "big-gens.scm", "big-hz->radians", "big-gens.scm", "big-linear->db", "big-gens.scm", "big-maraca", "maraca.scm", "big-ncos", "big-gens.scm", "big-nsin", "big-gens.scm", "big-one-pole", "big-gens.scm", "big-one-zero", "big-gens.scm", "big-oscil", "big-gens.scm", "big-polar->rectangular", "big-gens.scm", "big-polynomial", "big-gens.scm", "big-radians->degrees", "big-gens.scm", "big-radians->hz", "big-gens.scm", "big-rectangular->polar", "big-gens.scm", "big-samples->seconds", "big-gens.scm", "big-seconds->samples", "big-gens.scm", "big-table-lookup", "big-gens.scm", "bigbird", "bird.scm", "binary-port?", "r7rs.scm", "bind", "libc.scm", "binomial", "dsp.scm", "binomial-direct", "numerics.scm", "bird", "bird.scm", "black-billed-cuckoo", "animals.scm", "black-chinned-sparrow", "animals.scm", "black-crowned-night-heron", "animals.scm", "black-horned-tree-cricket", "animals.scm", "black-necked-stilt", "animals.scm", "black-phoebe", "animals.scm", "black-rail", "animals.scm", "black-throated-blue-warbler", "animals.scm", "black-throated-sparrow", "animals.scm", "blackman", "generators.scm", "blackman4-env", "generators.scm", "blackman4-env-channel", "extensions.scm", "blackman4-ramp", "extensions.scm", "blackman?", "generators.scm", "blue-grosbeak", "animals.scm", "bobwhite", "animals.scm", "boolean=?", "r7rs.scm", "bouncy", "generators.scm", "bow", "strad.scm", "bowstr", "prc95.scm", "bowtable", "prc95.scm", "box", "r7rs.scm", "box-type?", "r7rs.scm", "box?", "r7rs.scm", "brass", "prc95.scm", "brassy", "generators.scm", "brighten-slightly", "dsp.scm", "brighten-slightly-1", "dsp.scm", "broad-winged-tree-cricket", "animals.scm", "brown-crested-flycatcher-1", "animals.scm", "brown-crested-flycatcher-2", "animals.scm", "brown-jay", "animals.scm", "brown-noise", "generators.scm", "brown-noise?", "generators.scm", "bullfrog", "animals.scm", "bump", "generators.scm", "burrowing-owl", "animals.scm", "bushtit", "animals.scm", "butterworth-prototype", "analog-filter.scm", "byte", "stuff.scm", "bytevector->list", "r7rs.scm", "bytevector-append", "r7rs.scm", "bytevector-copy", "r7rs.scm", "bytevector-copy!", "r7rs.scm", "bytevector-length", "r7rs.scm", "bytevector-u8-ref", "r7rs.scm", "bytevector-u8-set!", "r7rs.scm", "c-define-1", "cload.scm", "c-null?", "libc.scm", "c-pointer->string", "libc.scm", "c?r", "stuff.scm", "calculate-fit", "dlocsig.scm", "california-quail", "animals.scm", "california-towhee", "animals.scm", "call-with-input-vector", "stuff.scm", "call-with-output-vector", "stuff.scm", "call-with-port", "r7rs.scm", "calling-all-animals", "animals.scm", "calling-all-birds", "animals.scm", "calling-all-frogs", "animals.scm", "calling-all-generators", "generators.scm", "calling-all-insects", "animals.scm", "calling-all-mammals", "animals.scm", "calloc", "libc.scm", "canada-goose", "animals.scm", "canada-goose-1", "animals.scm", "canada-goose-2", "animals.scm", "canada-goose-3", "animals.scm", "cancel-auto-save", "autosave.scm", "canonicalize", "peak-phases.scm", "canonicalize-one", "peak-phases.scm", "canter", "clm-ins.scm", "cape-may-warbler", "animals.scm", "cardinal", "animals.scm", "carolina-grasshopper", "animals.scm", "carolina-wren", "animals.scm", "cascade->canonical", "dsp.scm", "cassins-sparrow", "animals.scm", "cassins-vireo", "animals.scm", "cblas_dasum", "libgsl.scm", "cblas_daxpy", "libgsl.scm", "cblas_dcopy", "libgsl.scm", "cblas_ddot", "libgsl.scm", "cblas_dgbmv", "libgsl.scm", "cblas_dgemm", "libgsl.scm", "cblas_dgemv", "libgsl.scm", "cblas_dger", "libgsl.scm", "cblas_dnrm2", "libgsl.scm", "cblas_drot", "libgsl.scm", "cblas_drotg", "libgsl.scm", "cblas_drotm", "libgsl.scm", "cblas_drotmg", "libgsl.scm", "cblas_dsbmv", "libgsl.scm", "cblas_dscal", "libgsl.scm", "cblas_dspmv", "libgsl.scm", "cblas_dspr", "libgsl.scm", "cblas_dspr2", "libgsl.scm", "cblas_dswap", "libgsl.scm", "cblas_dsymm", "libgsl.scm", "cblas_dsymv", "libgsl.scm", "cblas_dsyr", "libgsl.scm", "cblas_dsyr2", "libgsl.scm", "cblas_dsyr2k", "libgsl.scm", "cblas_dsyrk", "libgsl.scm", "cblas_dtbmv", "libgsl.scm", "cblas_dtbsv", "libgsl.scm", "cblas_dtpmv", "libgsl.scm", "cblas_dtpsv", "libgsl.scm", "cblas_dtrmm", "libgsl.scm", "cblas_dtrmv", "libgsl.scm", "cblas_dtrsm", "libgsl.scm", "cblas_dtrsv", "libgsl.scm", "cblas_dzasum", "libgsl.scm", "cblas_dznrm2", "libgsl.scm", "cblas_icamax", "libgsl.scm", "cblas_idamax", "libgsl.scm", "cblas_izamax", "libgsl.scm", "cblas_zaxpy", "libgsl.scm", "cblas_zcopy", "libgsl.scm", "cblas_zdotc_sub", "libgsl.scm", "cblas_zdotu_sub", "libgsl.scm", "cblas_zdscal", "libgsl.scm", "cblas_zgbmv", "libgsl.scm", "cblas_zgemm", "libgsl.scm", "cblas_zgemv", "libgsl.scm", "cblas_zgerc", "libgsl.scm", "cblas_zgeru", "libgsl.scm", "cblas_zhbmv", "libgsl.scm", "cblas_zhemm", "libgsl.scm", "cblas_zhemv", "libgsl.scm", "cblas_zher", "libgsl.scm", "cblas_zher2", "libgsl.scm", "cblas_zher2k", "libgsl.scm", "cblas_zherk", "libgsl.scm", "cblas_zhpmv", "libgsl.scm", "cblas_zhpr", "libgsl.scm", "cblas_zhpr2", "libgsl.scm", "cblas_zscal", "libgsl.scm", "cblas_zswap", "libgsl.scm", "cblas_zsymm", "libgsl.scm", "cblas_zsyr2k", "libgsl.scm", "cblas_zsyrk", "libgsl.scm", "cblas_ztbmv", "libgsl.scm", "cblas_ztbsv", "libgsl.scm", "cblas_ztpmv", "libgsl.scm", "cblas_ztpsv", "libgsl.scm", "cblas_ztrmm", "libgsl.scm", "cblas_ztrmv", "libgsl.scm", "cblas_ztrsm", "libgsl.scm", "cblas_ztrsv", "libgsl.scm", "cbrt", "libm.scm", "cdr*", "stuff.scm", "cdr-assoc", "stuff.scm", "cedar-waxwing", "animals.scm", "ceil", "libm.scm", "cellon", "clm-ins.scm", "cfgetispeed", "libc.scm", "cfgetospeed", "libc.scm", "cfsetispeed", "libc.scm", "cfsetospeed", "libc.scm", "chain-dsps", "examp.scm", "channel-average-power", "dsp.scm", "channel-clipped?", "examp.scm", "channel-distance", "dsp.scm", "channel-envelope", "enved.scm", "channel-lp", "dsp.scm", "channel-mean", "dsp.scm", "channel-norm", "dsp.scm", "channel-polynomial", "dsp.scm", "channel-rms", "dsp.scm", "channel-sync", "extensions.scm", "channel-total-energy", "dsp.scm", "channel-variance", "dsp.scm", "channel2-angle", "dsp.scm", "channel2-coefficient-of-projection", "dsp.scm", "channel2-inner-product", "dsp.scm", "channel2-orthogonal?", "dsp.scm", "channels-equal?", "extensions.scm", "channels=?", "extensions.scm", "char-foldcase", "r7rs.scm", "chdir", "libc.scm", "cheby-hka", "dsp.scm", "chebyshev", "numerics.scm", "chebyshev-polynomial", "numerics.scm", "chebyshev-prototype", "analog-filter.scm", "check-freq", "clean.scm", "check-mix-tags", "mix.scm", "checkpt", "jcvoi.scm", "chestnut-sided-warbler", "animals.scm", "chipping-sparrow", "animals.scm", "chmod", "libc.scm", "chordalize", "dsp.scm", "chorus", "dsp.scm", "chown", "libc.scm", "chuck-wills-widow", "animals.scm", "circle", "musglyphs.scm", "circular-list", "stuff.scm", "circular-list?", "stuff.scm", "cis", "dlocsig.scm", "cl-set-difference", "stuff.scm", "clamp", "stuff.scm", "clamp-rxycos-r", "generators.scm", "clarinet", "prc95.scm", "clean-channel", "clean.scm", "clean-sound", "clean.scm", "clearerr", "libc.scm", "click-middle-button-to-open-next-file-in-directory", "examp.scm", "click-to-sync", "marks.scm", "clm-display-globals", "ws.scm", "clm-expsrc", "clm-ins.scm", "clm-find-file", "ws.scm", "clm-load", "ws.scm", "cload.scm", "cload.scm", "clock", "libc.scm", "clock_getcpuclockid", "libc.scm", "clock_getres", "libc.scm", "clock_gettime", "libc.scm", "clock_nanosleep", "libc.scm", "clock_settime", "libc.scm", "close", "libc.scm", "close-port", "r7rs.scm", "closedir", "libc.scm", "cnvrev", "clm-ins.scm", "cnvtest", "examp.scm", "collect-if", "stuff.scm", "color-mixes", "mix.scm", "color-samples", "draw.scm", "comb-chord", "examp.scm", "comb-filter", "examp.scm", "command-line", "r7rs.scm", "common-gull", "animals.scm", "common-loon-1", "animals.scm", "common-loon-2", "animals.scm", "common-pauraque", "animals.scm", "common-yellowthroat", "animals.scm", "compand", "examp.scm", "compute-string", "dsp.scm", "compute-uniform-circular-string", "dsp.scm", "concatenate", "stuff.scm", "concatenate-envelopes", "env.scm", "confstr", "libc.scm", "confused-ground-cricket", "animals.scm", "connect", "libc.scm", "constant-velocity", "dlocsig.scm", "continuable-error", "stuff.scm", "continue-from-error", "stuff.scm", "contrast-channel", "extensions.scm", "contrast-sound", "extensions.scm", "copy-tree", "stuff.scm", "copysign", "libm.scm", "count-if", "stuff.scm", "cpu-architecture", "r7rs.scm", "crawfish-frog", "animals.scm", "creat", "libc.scm", "create-initial-envelopes", "enved.scm", "crested-caracara", "animals.scm", "cross-correlate", "snddiff.scm", "cross-fade", "fade.scm", "cross-synthesis", "examp.scm", "ctermid", "libc.scm", "ctime", "libc.scm", "current-jiffy", "r7rs.scm", "current-second", "r7rs.scm", "curveto", "musglyphs.scm", "cyclic?", "stuff.scm", "dark-eyed-junco", "animals.scm", "davis-tree-cricket", "animals.scm", "db-envelope", "grani.scm", "dblsum", "generators.scm", "dblsum?", "generators.scm", "dc-block", "prc95.scm", "defgenerator", "generators.scm", "define-class", "stuff.scm", "define-library", "r7rs.scm", "define-record-type", "r7rs.scm", "define-selection-via-marks", "marks.scm", "definstrument", "ws.scm", "delay-channel-mixes", "mix.scm", "delayl", "prc95.scm", "delete-from-out-to-in", "spokenword.scm", "delete-mix", "mix.scm", "describe", "dlocsig.scm", "describe-hook", "hooks.scm", "describe-mark", "marks.scm", "determinant", "poly.scm", "dht", "dsp.scm", "differ", "peak-phases.scm", "difftime", "libc.scm", "digit-value", "r7rs.scm", "display-bark-fft", "dsp.scm", "display-colored-samples", "draw.scm", "display-correlation", "examp.scm", "display-db", "examp.scm", "display-energy", "examp.scm", "display-previous-edits", "draw.scm", "display-samples-in-color", "draw.scm", "dissolve-fade", "fade.scm", "distance", "dlocsig.scm", "distances-in-feet", "dlocsig.scm", "distances-in-meters", "dlocsig.scm", "dither-channel", "extensions.scm", "dither-sound", "extensions.scm", "div", "libc.scm", "do*", "stuff.scm", "do-all-chans", "examp.scm", "do-chans", "examp.scm", "do-sound-chans", "examp.scm", "dog-day-cicada", "animals.scm", "dolph", "dsp.scm", "dolph-1", "dsp.scm", "double*", "libgsl.scm", "down-oct", "dsp.scm", "dpb", "stuff.scm", "draw", "musglyphs.scm", "draw-128th-rest", "cmn-glyphs.lisp", "draw-16th-rest", "cmn-glyphs.lisp", "draw-32nd-rest", "cmn-glyphs.lisp", "draw-64th-rest", "cmn-glyphs.lisp", "draw-8th-flag-down", "cmn-glyphs.lisp", "draw-8th-flag-up", "cmn-glyphs.lisp", "draw-8th-rest", "cmn-glyphs.lisp", "draw-a-note", "musglyphs.scm", "draw-accent", "cmn-glyphs.lisp", "draw-arpeggio", "cmn-glyphs.lisp", "draw-arpeggios", "cmn-glyphs.lisp", "draw-bass-clef", "cmn-glyphs.lisp", "draw-breath-mark", "cmn-glyphs.lisp", "draw-c-clef", "cmn-glyphs.lisp", "draw-caesura", "cmn-glyphs.lisp", "draw-circled-x", "cmn-glyphs.lisp", "draw-coda", "cmn-glyphs.lisp", "draw-common-time", "cmn-glyphs.lisp", "draw-cut-time", "cmn-glyphs.lisp", "draw-diamond", "cmn-glyphs.lisp", "draw-diamond-1", "cmn-glyphs.lisp", "draw-double-flat", "cmn-glyphs.lisp", "draw-double-mordent", "cmn-glyphs.lisp", "draw-double-sharp", "cmn-glyphs.lisp", "draw-double-whole-note", "cmn-glyphs.lisp", "draw-double-whole-rest", "cmn-glyphs.lisp", "draw-down-bow", "cmn-glyphs.lisp", "draw-eight", "cmn-glyphs.lisp", "draw-extend-flag-down", "cmn-glyphs.lisp", "draw-extend-flag-up", "cmn-glyphs.lisp", "draw-f", "cmn-glyphs.lisp", "draw-fermata", "cmn-glyphs.lisp", "draw-filled-diamond-1", "cmn-glyphs.lisp", "draw-five", "cmn-glyphs.lisp", "draw-flat", "cmn-glyphs.lisp", "draw-four", "cmn-glyphs.lisp", "draw-half-note", "cmn-glyphs.lisp", "draw-half-rest", "cmn-glyphs.lisp", "draw-left-paren", "cmn-glyphs.lisp", "draw-lig-p", "cmn-glyphs.lisp", "draw-lower-bracket", "cmn-glyphs.lisp", "draw-m", "cmn-glyphs.lisp", "draw-measure-rest", "cmn-glyphs.lisp", "draw-mordent", "cmn-glyphs.lisp", "draw-mslash", "cmn-glyphs.lisp", "draw-n", "cmn-glyphs.lisp", "draw-natural", "cmn-glyphs.lisp", "draw-niente", "cmn-glyphs.lisp", "draw-nine", "cmn-glyphs.lisp", "draw-one", "cmn-glyphs.lisp", "draw-p", "cmn-glyphs.lisp", "draw-ped", "cmn-glyphs.lisp", "draw-pedal-off", "cmn-glyphs.lisp", "draw-percussion-clef", "cmn-glyphs.lisp", "draw-plus", "cmn-glyphs.lisp", "draw-quarter-note", "cmn-glyphs.lisp", "draw-quarter-rest", "cmn-glyphs.lisp", "draw-r", "cmn-glyphs.lisp", "draw-repeat-sign", "cmn-glyphs.lisp", "draw-rhythmX", "cmn-glyphs.lisp", "draw-right-paren", "cmn-glyphs.lisp", "draw-s", "cmn-glyphs.lisp", "draw-segno", "cmn-glyphs.lisp", "draw-seven", "cmn-glyphs.lisp", "draw-sharp", "cmn-glyphs.lisp", "draw-six", "cmn-glyphs.lisp", "draw-slash", "cmn-glyphs.lisp", "draw-square", "cmn-glyphs.lisp", "draw-staff", "musglyphs.scm", "draw-subito", "cmn-glyphs.lisp", "draw-three", "cmn-glyphs.lisp", "draw-tnecca", "cmn-glyphs.lisp", "draw-tr", "cmn-glyphs.lisp", "draw-treble-clef", "cmn-glyphs.lisp", "draw-triangle", "cmn-glyphs.lisp", "draw-trill-section", "cmn-glyphs.lisp", "draw-trill-sections", "cmn-glyphs.lisp", "draw-turn", "cmn-glyphs.lisp", "draw-two", "cmn-glyphs.lisp", "draw-up-bow", "cmn-glyphs.lisp", "draw-upper-bracket", "cmn-glyphs.lisp", "draw-upside-down-fermata", "cmn-glyphs.lisp", "draw-wedge", "cmn-glyphs.lisp", "draw-whole-note", "cmn-glyphs.lisp", "draw-whole-rest", "cmn-glyphs.lisp", "draw-z", "cmn-glyphs.lisp", "draw-zero", "cmn-glyphs.lisp", "drone", "clm-ins.scm", "dup", "libc.scm", "dup2", "libc.scm", "dusky-flycatcher", "animals.scm", "eared-grebe", "animals.scm", "eastern-bluebird", "animals.scm", "eastern-meadowlark", "animals.scm", "eastern-wood-pewee-1", "animals.scm", "eastern-wood-pewee-2", "animals.scm", "echo", "examp.scm", "eighth", "stuff.scm", "elambda", "stuff.scm", "elliptic-prototype", "analog-filter.scm", "empty?", "stuff.scm", "endhostent", "libc.scm", "endnetent", "libc.scm", "endprotoent", "libc.scm", "endpwent", "libc.scm", "endservent", "libc.scm", "enum", "stuff.scm", "env-expt-channel", "extensions.scm", "env-mixes", "mix.scm", "env-sound-interp", "examp.scm", "env-squared-channel", "extensions.scm", "envelope-exp", "env.scm", "envelope-last-x", "env.scm", "envelope-or-number", "grani.scm", "enveloped-mix", "extensions.scm", "enveloping-key-press", "enved.scm", "eoddcos", "generators.scm", "eoddcos?", "generators.scm", "eof-object", "r7rs.scm", "ercos", "generators.scm", "ercos?", "generators.scm", "ercoser", "generators.scm", "errno", "libc.scm", "error-message", "r7rs.scm", "erssb", "generators.scm", "erssb?", "generators.scm", "evening-grosbeak", "animals.scm", "every-sample?", "examp.scm", "every?", "stuff.scm", "exact", "r7rs.scm", "exact-integer-sqrt", "r7rs.scm", "exact-integer?", "r7rs.scm", "exp-envelope", "grani.scm", "exp-snd", "clm-ins.scm", "exp2", "libm.scm", "expandn", "expandn.scm", "expfil", "clm-ins.scm", "explode-sf2", "examp.scm", "expm1", "libm.scm", "exponentially-weighted-moving-average?", "generators.scm", "expsnd", "examp.scm", "expsrc", "examp.scm", "exptmod", "numerics.scm", "fabs", "libm.scm", "factorial", "numerics.scm", "factorize", "primes.scm", "false", "libc.scm", "fast-calling-tree-cricket", "animals.scm", "fclose", "libc.scm", "fcntl", "libc.scm", "fdim", "libm.scm", "fdopen", "libc.scm", "features", "r7rs.scm", "feclearexcept", "libc.scm", "fegetenv", "libc.scm", "fegetexceptflag", "libc.scm", "fegetround", "libc.scm", "feholdexcept", "libc.scm", "feof", "libc.scm", "feraiseexcept", "libc.scm", "ferror", "libc.scm", "fesetenv", "libc.scm", "fesetexceptflag", "libc.scm", "fesetround", "libc.scm", "fetestexcept", "libc.scm", "feupdateenv", "libc.scm", "fflush", "libc.scm", "fft-cancel", "examp.scm", "fft-edit", "examp.scm", "fft-env-data", "examp.scm", "fft-env-edit", "examp.scm", "fft-env-interp", "examp.scm", "fft-peak", "examp.scm", "fft-smoother", "examp.scm", "fft-squelch", "examp.scm", "fgetc", "libc.scm", "fgetpos", "libc.scm", "fgets", "libc.scm", "field-sparrow", "animals.scm", "fifth", "stuff.scm", "file->floats", "examp.scm", "file-error?", "r7rs.scm", "fileno", "libc.scm", "files-popdown-info", "nb.scm", "files-popup-info", "nb.scm", "fill-in", "musglyphs.scm", "fillfnc", "jcvoi.scm", "filter-fft", "examp.scm", "filter-selection-and-smooth", "selection.scm", "filtered-env", "examp.scm", "final-direction", "dlocsig.scm", "find-click", "examp.scm", "find-if", "stuff.scm", "find-mix", "mix.scm", "find-noddsin-max", "generators.scm", "find-nxysin-max", "generators.scm", "find-other-mins", "peak-phases.scm", "find-pitch", "examp.scm", "find-sine", "dsp.scm", "finfo", "examp.scm", "finish-with-sound", "ws.scm", "finite?", "r7rs.scm", "first", "stuff.scm", "first-mark-in-window-at-left", "examp.scm", "fit-path", "dlocsig.scm", "fit-selection-between-marks", "marks.scm", "flammulated-owl", "animals.scm", "flash-selected-data", "examp.scm", "flatten-let", "stuff.scm", "flatten-partials", "dsp.scm", "flecho", "examp.scm", "flipxy", "jcvoi.scm", "float-vector->gsl_matrix", "libgsl.scm", "float-vector->gsl_vector", "libgsl.scm", "float-vector->vector", "poly.scm", "float-vector-polynomial", "dsp.scm", "float-vector-size", "snddiff.scm", "float64_to_int32", "binary-io.scm", "float64_to_int64", "binary-io.scm", "flockfile", "libc.scm", "flocsig", "generators.scm", "flocsig?", "generators.scm", "floor-quotient", "r7rs.scm", "floor-remainder", "r7rs.scm", "fltit-1", "dsp.scm", "flute", "prc95.scm", "fm-bell", "clm-ins.scm", "fm-cancellation", "generators.scm", "fm-cascade-component", "dsp.scm", "fm-complex-component", "dsp.scm", "fm-drum", "clm-ins.scm", "fm-insect", "clm-ins.scm", "fm-noise", "noise.scm", "fm-parallel-component", "dsp.scm", "fm-trumpet", "clm-ins.scm", "fm-violin", "v.scm", "fm-voice", "jcvoi.scm", "fm2", "clm-ins.scm", "fma", "libm.scm", "fmssb", "generators.scm", "fmssb?", "generators.scm", "fncval", "jcvoi.scm", "fnmatch", "libc.scm", "fofins", "clm-ins.scm", "fopen", "libc.scm", "for-each-permutation", "stuff.scm", "for-each-sound-file", "extensions.scm", "for-each-subset", "stuff.scm", "force", "r7rs.scm", "fork", "libc.scm", "formant-filter", "examp.scm", "formants", "examp.scm", "four-spotted-tree-cricket", "animals.scm", "fourth", "stuff.scm", "fox-sparrow", "animals.scm", "fp", "examp.scm", "fpathconf", "libc.scm", "fpclassify", "libm.scm", "fpmc", "generators.scm", "fputc", "libc.scm", "fputs", "libc.scm", "fractional-fourier-transform", "dsp.scm", "fread", "libc.scm", "free", "libc.scm", "freeaddrinfo", "libc.scm", "freeverb", "freeverb.scm", "freopen", "libc.scm", "freqdiv", "dsp.scm", "frequency->note-octave-and-accidental", "musglyphs.scm", "frexp", "libm.scm", "fseek", "libc.scm", "fsetpos", "libc.scm", "fstat", "libc.scm", "ftruncate", "libc.scm", "ftrylockfile", "libc.scm", "ftw", "libc.scm", "full-count-if", "stuff.scm", "full-find-if", "stuff.scm", "full-index-if", "stuff.scm", "fullmix", "fullmix.scm", "fully-macroexpand", "stuff.scm", "funlockfile", "libc.scm", "fwrite", "libc.scm", "g-mustext", "musglyphs.scm", "gai_strerror", "libc.scm", "gain", "clm-ins.scm", "gain-avg", "clm-ins.scm", "gambels-quail", "animals.scm", "gather-symbols", "stuff.scm", "gaussian-distribution", "dsp.scm", "gaussian-envelope", "dsp.scm", "gdbm_close", "libgdbm.scm", "gdbm_delete", "libgdbm.scm", "gdbm_errno", "libgdbm.scm", "gdbm_exists", "libgdbm.scm", "gdbm_fdesc", "libgdbm.scm", "gdbm_fetch", "libgdbm.scm", "gdbm_firstkey", "libgdbm.scm", "gdbm_nextkey", "libgdbm.scm", "gdbm_open", "libgdbm.scm", "gdbm_reorganize", "libgdbm.scm", "gdbm_store", "libgdbm.scm", "gdbm_strerror", "libgdbm.scm", "gdbm_sync", "libgdbm.scm", "gdbm_version", "libgdbm.scm", "gegenbauer", "numerics.scm", "generator-clamp-r", "generators.scm", "get-best", "peak-phases.scm", "get-environment-variable", "r7rs.scm", "get-environment-variables", "r7rs.scm", "get-output-bytevector", "r7rs.scm", "get-speaker-configuration", "dlocsig.scm", "getaddrinfo", "libc.scm", "getc", "libc.scm", "getchar", "libc.scm", "getegid", "libc.scm", "getenvs", "libc.scm", "geteuid", "libc.scm", "getgid", "libc.scm", "getgrgid", "libc.scm", "getgrnam", "libc.scm", "getgroups", "libc.scm", "gethostbyaddr", "libc.scm", "gethostbyname", "libc.scm", "gethostent", "libc.scm", "getlogin", "libc.scm", "getnameinfo", "libc.scm", "getnetbyaddr", "libc.scm", "getnetbyname", "libc.scm", "getnetent", "libc.scm", "getpeername", "libc.scm", "getpgid", "libc.scm", "getppid", "libc.scm", "getpriority", "libc.scm", "getprotobyname", "libc.scm", "getprotobynumber", "libc.scm", "getprotoent", "libc.scm", "getpwent", "libc.scm", "getpwnam", "libc.scm", "getpwuid", "libc.scm", "getrlimit", "libc.scm", "getrusage", "libc.scm", "getservbyname", "libc.scm", "getservbyport", "libc.scm", "getservent", "libc.scm", "getsid", "libc.scm", "getsockname", "libc.scm", "getsockopt", "libc.scm", "gettimeofday", "libc.scm", "getuid", "libc.scm", "glassy", "generators.scm", "glob", "libc.scm", "glob.gl_pathc", "libc.scm", "glob.gl_pathv", "libc.scm", "glob.make", "libc.scm", "globfree", "libc.scm", "gmtime", "libc.scm", "goertzel", "dsp.scm", "goertzel-channel", "clean.scm", "golden-crowned-sparrow", "animals.scm", "gong", "clm-ins.scm", "gran-synth", "clm-ins.scm", "grani", "grani.scm", "granulated-sound-interp", "examp.scm", "graphEq", "clm-ins.scm", "grasshopper-sparrow", "animals.scm", "gray-crowned-rosy-finch", "animals.scm", "gray-vireo", "animals.scm", "gray-vireo-1", "animals.scm", "gray-vireo-2", "animals.scm", "gray-vireo-3", "animals.scm", "gray-vireo-4", "animals.scm", "gray-vireo-5", "animals.scm", "great-crested-flycatcher", "animals.scm", "great-horned-owl", "animals.scm", "great-kiskadee", "animals.scm", "great-plains-narrow-mouthed-toad", "animals.scm", "greater-pewee", "animals.scm", "greater-roadrunner", "animals.scm", "green-noise", "generators.scm", "green-noise-interp", "generators.scm", "green-noise-interp?", "generators.scm", "green-noise?", "generators.scm", "green-tailed-towhee", "animals.scm", "green-toad", "animals.scm", "green-tree-frog", "animals.scm", "groove-billed-ani", "animals.scm", "group-id", "dlocsig.scm", "group-matrix", "dlocsig.scm", "group-size", "dlocsig.scm", "group-speakers", "dlocsig.scm", "group-vertices", "dlocsig.scm", "group.gr_gid", "libc.scm", "group.gr_mem", "libc.scm", "group.gr_name", "libc.scm", "group.gr_passwd", "libc.scm", "gsl_acosh", "libgsl.scm", "gsl_asinh", "libgsl.scm", "gsl_atanh", "libgsl.scm", "gsl_blas_dasum", "libgsl.scm", "gsl_blas_daxpy", "libgsl.scm", "gsl_blas_dcopy", "libgsl.scm", "gsl_blas_dgemm", "libgsl.scm", "gsl_blas_dgemv", "libgsl.scm", "gsl_blas_dger", "libgsl.scm", "gsl_blas_dnrm2", "libgsl.scm", "gsl_blas_drot", "libgsl.scm", "gsl_blas_drotg", "libgsl.scm", "gsl_blas_drotm", "libgsl.scm", "gsl_blas_drotmg", "libgsl.scm", "gsl_blas_dscal", "libgsl.scm", "gsl_blas_dswap", "libgsl.scm", "gsl_blas_dsymm", "libgsl.scm", "gsl_blas_dsymv", "libgsl.scm", "gsl_blas_dsyr", "libgsl.scm", "gsl_blas_dsyr2", "libgsl.scm", "gsl_blas_dsyr2k", "libgsl.scm", "gsl_blas_dsyrk", "libgsl.scm", "gsl_blas_dtrmm", "libgsl.scm", "gsl_blas_dtrmv", "libgsl.scm", "gsl_blas_dtrsm", "libgsl.scm", "gsl_blas_dtrsv", "libgsl.scm", "gsl_blas_dzasum", "libgsl.scm", "gsl_blas_dznrm2", "libgsl.scm", "gsl_blas_idamax", "libgsl.scm", "gsl_blas_izamax", "libgsl.scm", "gsl_blas_zcopy", "libgsl.scm", "gsl_blas_zdotc", "libgsl.scm", "gsl_blas_zdotu", "libgsl.scm", "gsl_blas_zdscal", "libgsl.scm", "gsl_blas_zher", "libgsl.scm", "gsl_blas_zherk", "libgsl.scm", "gsl_blas_zswap", "libgsl.scm", "gsl_blas_ztrmv", "libgsl.scm", "gsl_blas_ztrsv", "libgsl.scm", "gsl_bspline_alloc", "libgsl.scm", "gsl_bspline_breakpoint", "libgsl.scm", "gsl_bspline_deriv_eval", "libgsl.scm", "gsl_bspline_deriv_eval_nonzero", "libgsl.scm", "gsl_bspline_eval", "libgsl.scm", "gsl_bspline_eval_nonzero", "libgsl.scm", "gsl_bspline_free", "libgsl.scm", "gsl_bspline_greville_abscissa", "libgsl.scm", "gsl_bspline_knots", "libgsl.scm", "gsl_bspline_knots_greville", "libgsl.scm", "gsl_bspline_knots_uniform", "libgsl.scm", "gsl_bspline_nbreak", "libgsl.scm", "gsl_bspline_ncoeffs", "libgsl.scm", "gsl_bspline_order", "libgsl.scm", "gsl_cdf_beta_P", "libgsl.scm", "gsl_cdf_beta_Pinv", "libgsl.scm", "gsl_cdf_beta_Q", "libgsl.scm", "gsl_cdf_beta_Qinv", "libgsl.scm", "gsl_cdf_binomial_P", "libgsl.scm", "gsl_cdf_binomial_Q", "libgsl.scm", "gsl_cdf_cauchy_P", "libgsl.scm", "gsl_cdf_cauchy_Pinv", "libgsl.scm", "gsl_cdf_cauchy_Q", "libgsl.scm", "gsl_cdf_cauchy_Qinv", "libgsl.scm", "gsl_cdf_chisq_P", "libgsl.scm", "gsl_cdf_chisq_Pinv", "libgsl.scm", "gsl_cdf_chisq_Q", "libgsl.scm", "gsl_cdf_chisq_Qinv", "libgsl.scm", "gsl_cdf_exponential_P", "libgsl.scm", "gsl_cdf_exponential_Pinv", "libgsl.scm", "gsl_cdf_exponential_Q", "libgsl.scm", "gsl_cdf_exponential_Qinv", "libgsl.scm", "gsl_cdf_exppow_P", "libgsl.scm", "gsl_cdf_exppow_Q", "libgsl.scm", "gsl_cdf_fdist_P", "libgsl.scm", "gsl_cdf_fdist_Pinv", "libgsl.scm", "gsl_cdf_fdist_Q", "libgsl.scm", "gsl_cdf_fdist_Qinv", "libgsl.scm", "gsl_cdf_flat_P", "libgsl.scm", "gsl_cdf_flat_Pinv", "libgsl.scm", "gsl_cdf_flat_Q", "libgsl.scm", "gsl_cdf_flat_Qinv", "libgsl.scm", "gsl_cdf_gamma_P", "libgsl.scm", "gsl_cdf_gamma_Pinv", "libgsl.scm", "gsl_cdf_gamma_Q", "libgsl.scm", "gsl_cdf_gamma_Qinv", "libgsl.scm", "gsl_cdf_gaussian_P", "libgsl.scm", "gsl_cdf_gaussian_Pinv", "libgsl.scm", "gsl_cdf_gaussian_Q", "libgsl.scm", "gsl_cdf_gaussian_Qinv", "libgsl.scm", "gsl_cdf_geometric_P", "libgsl.scm", "gsl_cdf_geometric_Q", "libgsl.scm", "gsl_cdf_gumbel1_P", "libgsl.scm", "gsl_cdf_gumbel1_Pinv", "libgsl.scm", "gsl_cdf_gumbel1_Q", "libgsl.scm", "gsl_cdf_gumbel1_Qinv", "libgsl.scm", "gsl_cdf_gumbel2_P", "libgsl.scm", "gsl_cdf_gumbel2_Pinv", "libgsl.scm", "gsl_cdf_gumbel2_Q", "libgsl.scm", "gsl_cdf_gumbel2_Qinv", "libgsl.scm", "gsl_cdf_hypergeometric_P", "libgsl.scm", "gsl_cdf_hypergeometric_Q", "libgsl.scm", "gsl_cdf_laplace_P", "libgsl.scm", "gsl_cdf_laplace_Pinv", "libgsl.scm", "gsl_cdf_laplace_Q", "libgsl.scm", "gsl_cdf_laplace_Qinv", "libgsl.scm", "gsl_cdf_logistic_P", "libgsl.scm", "gsl_cdf_logistic_Pinv", "libgsl.scm", "gsl_cdf_logistic_Q", "libgsl.scm", "gsl_cdf_logistic_Qinv", "libgsl.scm", "gsl_cdf_lognormal_P", "libgsl.scm", "gsl_cdf_lognormal_Pinv", "libgsl.scm", "gsl_cdf_lognormal_Q", "libgsl.scm", "gsl_cdf_lognormal_Qinv", "libgsl.scm", "gsl_cdf_negative_binomial_P", "libgsl.scm", "gsl_cdf_negative_binomial_Q", "libgsl.scm", "gsl_cdf_pareto_P", "libgsl.scm", "gsl_cdf_pareto_Pinv", "libgsl.scm", "gsl_cdf_pareto_Q", "libgsl.scm", "gsl_cdf_pareto_Qinv", "libgsl.scm", "gsl_cdf_pascal_P", "libgsl.scm", "gsl_cdf_pascal_Q", "libgsl.scm", "gsl_cdf_poisson_P", "libgsl.scm", "gsl_cdf_poisson_Q", "libgsl.scm", "gsl_cdf_rayleigh_P", "libgsl.scm", "gsl_cdf_rayleigh_Pinv", "libgsl.scm", "gsl_cdf_rayleigh_Q", "libgsl.scm", "gsl_cdf_rayleigh_Qinv", "libgsl.scm", "gsl_cdf_tdist_P", "libgsl.scm", "gsl_cdf_tdist_Pinv", "libgsl.scm", "gsl_cdf_tdist_Q", "libgsl.scm", "gsl_cdf_tdist_Qinv", "libgsl.scm", "gsl_cdf_ugaussian_P", "libgsl.scm", "gsl_cdf_ugaussian_Pinv", "libgsl.scm", "gsl_cdf_ugaussian_Q", "libgsl.scm", "gsl_cdf_ugaussian_Qinv", "libgsl.scm", "gsl_cdf_weibull_P", "libgsl.scm", "gsl_cdf_weibull_Pinv", "libgsl.scm", "gsl_cdf_weibull_Q", "libgsl.scm", "gsl_cdf_weibull_Qinv", "libgsl.scm", "gsl_cheb_alloc", "libgsl.scm", "gsl_cheb_calc_deriv", "libgsl.scm", "gsl_cheb_calc_integ", "libgsl.scm", "gsl_cheb_coeffs", "libgsl.scm", "gsl_cheb_eval", "libgsl.scm", "gsl_cheb_eval_err", "libgsl.scm", "gsl_cheb_eval_mode", "libgsl.scm", "gsl_cheb_eval_mode_e", "libgsl.scm", "gsl_cheb_eval_n", "libgsl.scm", "gsl_cheb_eval_n_err", "libgsl.scm", "gsl_cheb_free", "libgsl.scm", "gsl_cheb_init", "libgsl.scm", "gsl_cheb_order", "libgsl.scm", "gsl_cheb_size", "libgsl.scm", "gsl_check_range", "libgsl.scm", "gsl_coerce_double", "libgsl.scm", "gsl_combination->int-vector", "libgsl.scm", "gsl_combination_alloc", "libgsl.scm", "gsl_combination_calloc", "libgsl.scm", "gsl_combination_fprintf", "libgsl.scm", "gsl_combination_fread", "libgsl.scm", "gsl_combination_free", "libgsl.scm", "gsl_combination_fscanf", "libgsl.scm", "gsl_combination_fwrite", "libgsl.scm", "gsl_combination_get", "libgsl.scm", "gsl_combination_init_first", "libgsl.scm", "gsl_combination_init_last", "libgsl.scm", "gsl_combination_k", "libgsl.scm", "gsl_combination_memcpy", "libgsl.scm", "gsl_combination_n", "libgsl.scm", "gsl_combination_next", "libgsl.scm", "gsl_combination_prev", "libgsl.scm", "gsl_combination_valid", "libgsl.scm", "gsl_complex_abs", "libgsl.scm", "gsl_complex_abs2", "libgsl.scm", "gsl_complex_add", "libgsl.scm", "gsl_complex_add_imag", "libgsl.scm", "gsl_complex_add_real", "libgsl.scm", "gsl_complex_arccos", "libgsl.scm", "gsl_complex_arccos_real", "libgsl.scm", "gsl_complex_arccosh", "libgsl.scm", "gsl_complex_arccosh_real", "libgsl.scm", "gsl_complex_arccot", "libgsl.scm", "gsl_complex_arccoth", "libgsl.scm", "gsl_complex_arccsc", "libgsl.scm", "gsl_complex_arccsc_real", "libgsl.scm", "gsl_complex_arccsch", "libgsl.scm", "gsl_complex_arcsec", "libgsl.scm", "gsl_complex_arcsec_real", "libgsl.scm", "gsl_complex_arcsech", "libgsl.scm", "gsl_complex_arcsin", "libgsl.scm", "gsl_complex_arcsin_real", "libgsl.scm", "gsl_complex_arcsinh", "libgsl.scm", "gsl_complex_arctan", "libgsl.scm", "gsl_complex_arctanh", "libgsl.scm", "gsl_complex_arctanh_real", "libgsl.scm", "gsl_complex_arg", "libgsl.scm", "gsl_complex_conjugate", "libgsl.scm", "gsl_complex_cos", "libgsl.scm", "gsl_complex_cosh", "libgsl.scm", "gsl_complex_cot", "libgsl.scm", "gsl_complex_coth", "libgsl.scm", "gsl_complex_csc", "libgsl.scm", "gsl_complex_csch", "libgsl.scm", "gsl_complex_div", "libgsl.scm", "gsl_complex_div_imag", "libgsl.scm", "gsl_complex_div_real", "libgsl.scm", "gsl_complex_exp", "libgsl.scm", "gsl_complex_inverse", "libgsl.scm", "gsl_complex_log", "libgsl.scm", "gsl_complex_log10", "libgsl.scm", "gsl_complex_log_b", "libgsl.scm", "gsl_complex_logabs", "libgsl.scm", "gsl_complex_mul", "libgsl.scm", "gsl_complex_mul_imag", "libgsl.scm", "gsl_complex_mul_real", "libgsl.scm", "gsl_complex_negative", "libgsl.scm", "gsl_complex_polar", "libgsl.scm", "gsl_complex_poly_complex_eval", "libgsl.scm", "gsl_complex_pow", "libgsl.scm", "gsl_complex_pow_real", "libgsl.scm", "gsl_complex_rect", "libgsl.scm", "gsl_complex_sec", "libgsl.scm", "gsl_complex_sech", "libgsl.scm", "gsl_complex_sin", "libgsl.scm", "gsl_complex_sinh", "libgsl.scm", "gsl_complex_sqrt", "libgsl.scm", "gsl_complex_sqrt_real", "libgsl.scm", "gsl_complex_sub", "libgsl.scm", "gsl_complex_sub_imag", "libgsl.scm", "gsl_complex_sub_real", "libgsl.scm", "gsl_complex_tan", "libgsl.scm", "gsl_complex_tanh", "libgsl.scm", "gsl_deriv_backward", "libgsl.scm", "gsl_deriv_central", "libgsl.scm", "gsl_deriv_forward", "libgsl.scm", "gsl_dft_complex_backward", "libgsl.scm", "gsl_dft_complex_forward", "libgsl.scm", "gsl_dft_complex_inverse", "libgsl.scm", "gsl_dft_complex_transform", "libgsl.scm", "gsl_dht_alloc", "libgsl.scm", "gsl_dht_apply", "libgsl.scm", "gsl_dht_free", "libgsl.scm", "gsl_dht_init", "libgsl.scm", "gsl_dht_k_sample", "libgsl.scm", "gsl_dht_new", "libgsl.scm", "gsl_dht_x_sample", "libgsl.scm", "gsl_eigen_francis", "libgsl.scm", "gsl_eigen_francis_T", "libgsl.scm", "gsl_eigen_francis_Z", "libgsl.scm", "gsl_eigen_francis_alloc", "libgsl.scm", "gsl_eigen_francis_free", "libgsl.scm", "gsl_eigen_gen", "libgsl.scm", "gsl_eigen_gen_QZ", "libgsl.scm", "gsl_eigen_gen_alloc", "libgsl.scm", "gsl_eigen_gen_free", "libgsl.scm", "gsl_eigen_gen_params", "libgsl.scm", "gsl_eigen_genherm", "libgsl.scm", "gsl_eigen_genherm_alloc", "libgsl.scm", "gsl_eigen_genherm_free", "libgsl.scm", "gsl_eigen_genherm_standardize", "libgsl.scm", "gsl_eigen_genhermv", "libgsl.scm", "gsl_eigen_genhermv_alloc", "libgsl.scm", "gsl_eigen_genhermv_free", "libgsl.scm", "gsl_eigen_genhermv_sort", "libgsl.scm", "gsl_eigen_gensymm", "libgsl.scm", "gsl_eigen_gensymm_alloc", "libgsl.scm", "gsl_eigen_gensymm_free", "libgsl.scm", "gsl_eigen_gensymm_standardize", "libgsl.scm", "gsl_eigen_gensymmv", "libgsl.scm", "gsl_eigen_gensymmv_alloc", "libgsl.scm", "gsl_eigen_gensymmv_free", "libgsl.scm", "gsl_eigen_gensymmv_sort", "libgsl.scm", "gsl_eigen_genv", "libgsl.scm", "gsl_eigen_genv_QZ", "libgsl.scm", "gsl_eigen_genv_alloc", "libgsl.scm", "gsl_eigen_genv_free", "libgsl.scm", "gsl_eigen_genv_sort", "libgsl.scm", "gsl_eigen_herm", "libgsl.scm", "gsl_eigen_herm_alloc", "libgsl.scm", "gsl_eigen_herm_free", "libgsl.scm", "gsl_eigen_hermv", "libgsl.scm", "gsl_eigen_hermv_alloc", "libgsl.scm", "gsl_eigen_hermv_free", "libgsl.scm", "gsl_eigen_hermv_sort", "libgsl.scm", "gsl_eigen_invert_jacobi", "libgsl.scm", "gsl_eigen_jacobi", "libgsl.scm", "gsl_eigen_nonsymm", "libgsl.scm", "gsl_eigen_nonsymm_Z", "libgsl.scm", "gsl_eigen_nonsymm_alloc", "libgsl.scm", "gsl_eigen_nonsymm_free", "libgsl.scm", "gsl_eigen_nonsymm_params", "libgsl.scm", "gsl_eigen_nonsymmv", "libgsl.scm", "gsl_eigen_nonsymmv_Z", "libgsl.scm", "gsl_eigen_nonsymmv_alloc", "libgsl.scm", "gsl_eigen_nonsymmv_free", "libgsl.scm", "gsl_eigen_nonsymmv_params", "libgsl.scm", "gsl_eigen_nonsymmv_sort", "libgsl.scm", "gsl_eigen_symm", "libgsl.scm", "gsl_eigen_symm_alloc", "libgsl.scm", "gsl_eigen_symm_free", "libgsl.scm", "gsl_eigen_symmv", "libgsl.scm", "gsl_eigen_symmv_alloc", "libgsl.scm", "gsl_eigen_symmv_free", "libgsl.scm", "gsl_eigen_symmv_sort", "libgsl.scm", "gsl_error", "libgsl.scm", "gsl_expm1", "libgsl.scm", "gsl_fcmp", "libgsl.scm", "gsl_fdiv", "libgsl.scm", "gsl_fft_backward", "libgsl.scm", "gsl_fft_complex_backward", "libgsl.scm", "gsl_fft_complex_forward", "libgsl.scm", "gsl_fft_complex_inverse", "libgsl.scm", "gsl_fft_complex_memcpy", "libgsl.scm", "gsl_fft_complex_radix2_backward", "libgsl.scm", "gsl_fft_complex_radix2_dif_backward", "libgsl.scm", "gsl_fft_complex_radix2_dif_forward", "libgsl.scm", "gsl_fft_complex_radix2_dif_inverse", "libgsl.scm", "gsl_fft_complex_radix2_dif_transform", "libgsl.scm", "gsl_fft_complex_radix2_forward", "libgsl.scm", "gsl_fft_complex_radix2_inverse", "libgsl.scm", "gsl_fft_complex_radix2_transform", "libgsl.scm", "gsl_fft_complex_transform", "libgsl.scm", "gsl_fft_complex_wavetable_alloc", "libgsl.scm", "gsl_fft_complex_wavetable_free", "libgsl.scm", "gsl_fft_complex_workspace_alloc", "libgsl.scm", "gsl_fft_complex_workspace_free", "libgsl.scm", "gsl_fft_forward", "libgsl.scm", "gsl_fft_real_radix2_transform", "libgsl.scm", "gsl_fft_real_transform", "libgsl.scm", "gsl_fft_real_unpack", "libgsl.scm", "gsl_fft_real_wavetable_alloc", "libgsl.scm", "gsl_fft_real_wavetable_free", "libgsl.scm", "gsl_fft_real_workspace_alloc", "libgsl.scm", "gsl_fft_real_workspace_free", "libgsl.scm", "gsl_finite", "libgsl.scm", "gsl_fit_linear", "libgsl.scm", "gsl_fit_linear_est", "libgsl.scm", "gsl_fit_mul", "libgsl.scm", "gsl_fit_mul_est", "libgsl.scm", "gsl_fit_wlinear", "libgsl.scm", "gsl_fit_wmul", "libgsl.scm", "gsl_frexp", "libgsl.scm", "gsl_histogram2d_accumulate", "libgsl.scm", "gsl_histogram2d_add", "libgsl.scm", "gsl_histogram2d_alloc", "libgsl.scm", "gsl_histogram2d_calloc", "libgsl.scm", "gsl_histogram2d_calloc_range", "libgsl.scm", "gsl_histogram2d_calloc_uniform", "libgsl.scm", "gsl_histogram2d_clone", "libgsl.scm", "gsl_histogram2d_cov", "libgsl.scm", "gsl_histogram2d_div", "libgsl.scm", "gsl_histogram2d_equal_bins_p", "libgsl.scm", "gsl_histogram2d_find", "libgsl.scm", "gsl_histogram2d_fprintf", "libgsl.scm", "gsl_histogram2d_fread", "libgsl.scm", "gsl_histogram2d_free", "libgsl.scm", "gsl_histogram2d_fscanf", "libgsl.scm", "gsl_histogram2d_fwrite", "libgsl.scm", "gsl_histogram2d_get", "libgsl.scm", "gsl_histogram2d_get_xrange", "libgsl.scm", "gsl_histogram2d_get_yrange", "libgsl.scm", "gsl_histogram2d_increment", "libgsl.scm", "gsl_histogram2d_max_bin", "libgsl.scm", "gsl_histogram2d_max_val", "libgsl.scm", "gsl_histogram2d_memcpy", "libgsl.scm", "gsl_histogram2d_min_bin", "libgsl.scm", "gsl_histogram2d_min_val", "libgsl.scm", "gsl_histogram2d_mul", "libgsl.scm", "gsl_histogram2d_nx", "libgsl.scm", "gsl_histogram2d_ny", "libgsl.scm", "gsl_histogram2d_pdf_alloc", "libgsl.scm", "gsl_histogram2d_pdf_free", "libgsl.scm", "gsl_histogram2d_pdf_init", "libgsl.scm", "gsl_histogram2d_pdf_sample", "libgsl.scm", "gsl_histogram2d_reset", "libgsl.scm", "gsl_histogram2d_scale", "libgsl.scm", "gsl_histogram2d_set_ranges_uniform", "libgsl.scm", "gsl_histogram2d_shift", "libgsl.scm", "gsl_histogram2d_sub", "libgsl.scm", "gsl_histogram2d_sum", "libgsl.scm", "gsl_histogram2d_xmax", "libgsl.scm", "gsl_histogram2d_xmean", "libgsl.scm", "gsl_histogram2d_xmin", "libgsl.scm", "gsl_histogram2d_xsigma", "libgsl.scm", "gsl_histogram2d_ymax", "libgsl.scm", "gsl_histogram2d_ymean", "libgsl.scm", "gsl_histogram2d_ymin", "libgsl.scm", "gsl_histogram2d_ysigma", "libgsl.scm", "gsl_histogram_accumulate", "libgsl.scm", "gsl_histogram_add", "libgsl.scm", "gsl_histogram_alloc", "libgsl.scm", "gsl_histogram_bins", "libgsl.scm", "gsl_histogram_calloc", "libgsl.scm", "gsl_histogram_calloc_range", "libgsl.scm", "gsl_histogram_calloc_uniform", "libgsl.scm", "gsl_histogram_clone", "libgsl.scm", "gsl_histogram_div", "libgsl.scm", "gsl_histogram_equal_bins_p", "libgsl.scm", "gsl_histogram_find", "libgsl.scm", "gsl_histogram_fprintf", "libgsl.scm", "gsl_histogram_fread", "libgsl.scm", "gsl_histogram_free", "libgsl.scm", "gsl_histogram_fscanf", "libgsl.scm", "gsl_histogram_fwrite", "libgsl.scm", "gsl_histogram_get", "libgsl.scm", "gsl_histogram_get_range", "libgsl.scm", "gsl_histogram_increment", "libgsl.scm", "gsl_histogram_max", "libgsl.scm", "gsl_histogram_max_bin", "libgsl.scm", "gsl_histogram_max_val", "libgsl.scm", "gsl_histogram_mean", "libgsl.scm", "gsl_histogram_memcpy", "libgsl.scm", "gsl_histogram_min", "libgsl.scm", "gsl_histogram_min_bin", "libgsl.scm", "gsl_histogram_min_val", "libgsl.scm", "gsl_histogram_mul", "libgsl.scm", "gsl_histogram_pdf_alloc", "libgsl.scm", "gsl_histogram_pdf_free", "libgsl.scm", "gsl_histogram_pdf_init", "libgsl.scm", "gsl_histogram_pdf_sample", "libgsl.scm", "gsl_histogram_reset", "libgsl.scm", "gsl_histogram_scale", "libgsl.scm", "gsl_histogram_set_ranges", "libgsl.scm", "gsl_histogram_set_ranges_uniform", "libgsl.scm", "gsl_histogram_shift", "libgsl.scm", "gsl_histogram_sigma", "libgsl.scm", "gsl_histogram_sub", "libgsl.scm", "gsl_histogram_sum", "libgsl.scm", "gsl_hypot", "libgsl.scm", "gsl_hypot3", "libgsl.scm", "gsl_ieee_env_setup", "libgsl.scm", "gsl_ieee_set_mode", "libgsl.scm", "gsl_integration_cquad_workspace_alloc", "libgsl.scm", "gsl_integration_cquad_workspace_free", "libgsl.scm", "gsl_integration_glfixed", "libgsl.scm", "gsl_integration_glfixed_point", "libgsl.scm", "gsl_integration_glfixed_table_alloc", "libgsl.scm", "gsl_integration_glfixed_table_free", "libgsl.scm", "gsl_integration_qag", "libgsl.scm", "gsl_integration_qagi", "libgsl.scm", "gsl_integration_qagil", "libgsl.scm", "gsl_integration_qagiu", "libgsl.scm", "gsl_integration_qagp", "libgsl.scm", "gsl_integration_qags", "libgsl.scm", "gsl_integration_qawc", "libgsl.scm", "gsl_integration_qawf", "libgsl.scm", "gsl_integration_qawo", "libgsl.scm", "gsl_integration_qawo_table_alloc", "libgsl.scm", "gsl_integration_qawo_table_free", "libgsl.scm", "gsl_integration_qawo_table_set", "libgsl.scm", "gsl_integration_qawo_table_set_length", "libgsl.scm", "gsl_integration_qaws", "libgsl.scm", "gsl_integration_qaws_table_alloc", "libgsl.scm", "gsl_integration_qaws_table_free", "libgsl.scm", "gsl_integration_qaws_table_set", "libgsl.scm", "gsl_integration_qcheb", "libgsl.scm", "gsl_integration_qk", "libgsl.scm", "gsl_integration_qk15", "libgsl.scm", "gsl_integration_qk21", "libgsl.scm", "gsl_integration_qk31", "libgsl.scm", "gsl_integration_qk41", "libgsl.scm", "gsl_integration_qk51", "libgsl.scm", "gsl_integration_qk61", "libgsl.scm", "gsl_integration_qng", "libgsl.scm", "gsl_integration_workspace_alloc", "libgsl.scm", "gsl_integration_workspace_free", "libgsl.scm", "gsl_interp2d_alloc", "libgsl.scm", "gsl_interp2d_bicubic", "libgsl.scm", "gsl_interp2d_bilinear", "libgsl.scm", "gsl_interp2d_eval", "libgsl.scm", "gsl_interp2d_eval_deriv_x", "libgsl.scm", "gsl_interp2d_eval_deriv_x_e", "libgsl.scm", "gsl_interp2d_eval_deriv_xx", "libgsl.scm", "gsl_interp2d_eval_deriv_xx_e", "libgsl.scm", "gsl_interp2d_eval_deriv_xy", "libgsl.scm", "gsl_interp2d_eval_deriv_xy_e", "libgsl.scm", "gsl_interp2d_eval_deriv_y", "libgsl.scm", "gsl_interp2d_eval_deriv_y_e", "libgsl.scm", "gsl_interp2d_eval_deriv_yy", "libgsl.scm", "gsl_interp2d_eval_deriv_yy_e", "libgsl.scm", "gsl_interp2d_eval_e", "libgsl.scm", "gsl_interp2d_eval_e_extrap", "libgsl.scm", "gsl_interp2d_eval_extrap", "libgsl.scm", "gsl_interp2d_free", "libgsl.scm", "gsl_interp2d_get", "libgsl.scm", "gsl_interp2d_idx", "libgsl.scm", "gsl_interp2d_init", "libgsl.scm", "gsl_interp2d_min_size", "libgsl.scm", "gsl_interp2d_name", "libgsl.scm", "gsl_interp2d_set", "libgsl.scm", "gsl_interp2d_type_min_size", "libgsl.scm", "gsl_interp_accel_alloc", "libgsl.scm", "gsl_interp_accel_find", "libgsl.scm", "gsl_interp_accel_free", "libgsl.scm", "gsl_interp_accel_reset", "libgsl.scm", "gsl_interp_akima", "libgsl.scm", "gsl_interp_akima_periodic", "libgsl.scm", "gsl_interp_alloc", "libgsl.scm", "gsl_interp_bsearch", "libgsl.scm", "gsl_interp_cspline", "libgsl.scm", "gsl_interp_cspline_periodic", "libgsl.scm", "gsl_interp_eval", "libgsl.scm", "gsl_interp_eval_deriv", "libgsl.scm", "gsl_interp_eval_deriv2", "libgsl.scm", "gsl_interp_eval_deriv2_e", "libgsl.scm", "gsl_interp_eval_deriv_e", "libgsl.scm", "gsl_interp_eval_e", "libgsl.scm", "gsl_interp_eval_integ", "libgsl.scm", "gsl_interp_eval_integ_e", "libgsl.scm", "gsl_interp_free", "libgsl.scm", "gsl_interp_init", "libgsl.scm", "gsl_interp_linear", "libgsl.scm", "gsl_interp_min_size", "libgsl.scm", "gsl_interp_name", "libgsl.scm", "gsl_interp_polynomial", "libgsl.scm", "gsl_interp_steffen", "libgsl.scm", "gsl_interp_type_min_size", "libgsl.scm", "gsl_isinf", "libgsl.scm", "gsl_isnan", "libgsl.scm", "gsl_ldexp", "libgsl.scm", "gsl_linalg_HH_solve", "libgsl.scm", "gsl_linalg_HH_svx", "libgsl.scm", "gsl_linalg_LQ_LQsolve", "libgsl.scm", "gsl_linalg_LQ_Lsolve_T", "libgsl.scm", "gsl_linalg_LQ_Lsvx_T", "libgsl.scm", "gsl_linalg_LQ_decomp", "libgsl.scm", "gsl_linalg_LQ_lssolve_T", "libgsl.scm", "gsl_linalg_LQ_solve_T", "libgsl.scm", "gsl_linalg_LQ_svx_T", "libgsl.scm", "gsl_linalg_LQ_unpack", "libgsl.scm", "gsl_linalg_LQ_update", "libgsl.scm", "gsl_linalg_LQ_vecQ", "libgsl.scm", "gsl_linalg_LQ_vecQT", "libgsl.scm", "gsl_linalg_LU_decomp", "libgsl.scm", "gsl_linalg_LU_det", "libgsl.scm", "gsl_linalg_LU_invert", "libgsl.scm", "gsl_linalg_LU_lndet", "libgsl.scm", "gsl_linalg_LU_refine", "libgsl.scm", "gsl_linalg_LU_sgndet", "libgsl.scm", "gsl_linalg_LU_solve", "libgsl.scm", "gsl_linalg_LU_svx", "libgsl.scm", "gsl_linalg_L_solve_T", "libgsl.scm", "gsl_linalg_PTLQ_LQsolve_T", "libgsl.scm", "gsl_linalg_PTLQ_Lsolve_T", "libgsl.scm", "gsl_linalg_PTLQ_Lsvx_T", "libgsl.scm", "gsl_linalg_PTLQ_decomp", "libgsl.scm", "gsl_linalg_PTLQ_decomp2", "libgsl.scm", "gsl_linalg_PTLQ_solve_T", "libgsl.scm", "gsl_linalg_PTLQ_svx_T", "libgsl.scm", "gsl_linalg_PTLQ_update", "libgsl.scm", "gsl_linalg_QRPT_QRsolve", "libgsl.scm", "gsl_linalg_QRPT_Rsolve", "libgsl.scm", "gsl_linalg_QRPT_Rsvx", "libgsl.scm", "gsl_linalg_QRPT_decomp", "libgsl.scm", "gsl_linalg_QRPT_decomp2", "libgsl.scm", "gsl_linalg_QRPT_solve", "libgsl.scm", "gsl_linalg_QRPT_svx", "libgsl.scm", "gsl_linalg_QRPT_update", "libgsl.scm", "gsl_linalg_QR_QRsolve", "libgsl.scm", "gsl_linalg_QR_QTmat", "libgsl.scm", "gsl_linalg_QR_QTvec", "libgsl.scm", "gsl_linalg_QR_Qvec", "libgsl.scm", "gsl_linalg_QR_Rsolve", "libgsl.scm", "gsl_linalg_QR_Rsvx", "libgsl.scm", "gsl_linalg_QR_decomp", "libgsl.scm", "gsl_linalg_QR_lssolve", "libgsl.scm", "gsl_linalg_QR_matQ", "libgsl.scm", "gsl_linalg_QR_solve", "libgsl.scm", "gsl_linalg_QR_svx", "libgsl.scm", "gsl_linalg_QR_unpack", "libgsl.scm", "gsl_linalg_QR_update", "libgsl.scm", "gsl_linalg_R_solve", "libgsl.scm", "gsl_linalg_R_svx", "libgsl.scm", "gsl_linalg_SV_decomp", "libgsl.scm", "gsl_linalg_SV_decomp_jacobi", "libgsl.scm", "gsl_linalg_SV_decomp_mod", "libgsl.scm", "gsl_linalg_SV_leverage", "libgsl.scm", "gsl_linalg_SV_solve", "libgsl.scm", "gsl_linalg_balance_accum", "libgsl.scm", "gsl_linalg_balance_columns", "libgsl.scm", "gsl_linalg_balance_matrix", "libgsl.scm", "gsl_linalg_bidiag_decomp", "libgsl.scm", "gsl_linalg_bidiag_unpack", "libgsl.scm", "gsl_linalg_bidiag_unpack2", "libgsl.scm", "gsl_linalg_bidiag_unpack_B", "libgsl.scm", "gsl_linalg_cholesky_decomp", "libgsl.scm", "gsl_linalg_cholesky_decomp_unit", "libgsl.scm", "gsl_linalg_cholesky_invert", "libgsl.scm", "gsl_linalg_cholesky_solve", "libgsl.scm", "gsl_linalg_cholesky_svx", "libgsl.scm", "gsl_linalg_complex_LU_decomp", "libgsl.scm", "gsl_linalg_complex_LU_det", "libgsl.scm", "gsl_linalg_complex_LU_invert", "libgsl.scm", "gsl_linalg_complex_LU_lndet", "libgsl.scm", "gsl_linalg_complex_LU_refine", "libgsl.scm", "gsl_linalg_complex_LU_sgndet", "libgsl.scm", "gsl_linalg_complex_LU_solve", "libgsl.scm", "gsl_linalg_complex_LU_svx", "libgsl.scm", "gsl_linalg_complex_cholesky_decomp", "libgsl.scm", "gsl_linalg_complex_cholesky_invert", "libgsl.scm", "gsl_linalg_complex_cholesky_solve", "libgsl.scm", "gsl_linalg_complex_cholesky_svx", "libgsl.scm", "gsl_linalg_complex_householder_hm", "libgsl.scm", "gsl_linalg_complex_householder_hv", "libgsl.scm", "gsl_linalg_complex_householder_mh", "libgsl.scm", "gsl_linalg_complex_householder_transform", "libgsl.scm", "gsl_linalg_exponential_ss", "libgsl.scm", "gsl_linalg_givens", "libgsl.scm", "gsl_linalg_givens_gv", "libgsl.scm", "gsl_linalg_hermtd_decomp", "libgsl.scm", "gsl_linalg_hermtd_unpack", "libgsl.scm", "gsl_linalg_hermtd_unpack_T", "libgsl.scm", "gsl_linalg_hessenberg", "libgsl.scm", "gsl_linalg_hessenberg_decomp", "libgsl.scm", "gsl_linalg_hessenberg_set_zero", "libgsl.scm", "gsl_linalg_hessenberg_submatrix", "libgsl.scm", "gsl_linalg_hessenberg_unpack", "libgsl.scm", "gsl_linalg_hessenberg_unpack_accum", "libgsl.scm", "gsl_linalg_hesstri_decomp", "libgsl.scm", "gsl_linalg_householder_hm", "libgsl.scm", "gsl_linalg_householder_hm1", "libgsl.scm", "gsl_linalg_householder_hv", "libgsl.scm", "gsl_linalg_householder_mh", "libgsl.scm", "gsl_linalg_householder_transform", "libgsl.scm", "gsl_linalg_matmult", "libgsl.scm", "gsl_linalg_matmult_mod", "libgsl.scm", "gsl_linalg_solve_cyc_tridiag", "libgsl.scm", "gsl_linalg_solve_symm_cyc_tridiag", "libgsl.scm", "gsl_linalg_solve_symm_tridiag", "libgsl.scm", "gsl_linalg_solve_tridiag", "libgsl.scm", "gsl_linalg_symmtd_decomp", "libgsl.scm", "gsl_linalg_symmtd_unpack", "libgsl.scm", "gsl_linalg_symmtd_unpack_T", "libgsl.scm", "gsl_log1p", "libgsl.scm", "gsl_matrix->float-vector", "libgsl.scm", "gsl_matrix_add", "libgsl.scm", "gsl_matrix_add_constant", "libgsl.scm", "gsl_matrix_add_diagonal", "libgsl.scm", "gsl_matrix_alloc", "libgsl.scm", "gsl_matrix_alloc_from_matrix", "libgsl.scm", "gsl_matrix_calloc", "libgsl.scm", "gsl_matrix_complex_add", "libgsl.scm", "gsl_matrix_complex_add_constant", "libgsl.scm", "gsl_matrix_complex_add_diagonal", "libgsl.scm", "gsl_matrix_complex_alloc", "libgsl.scm", "gsl_matrix_complex_alloc_from_matrix", "libgsl.scm", "gsl_matrix_complex_calloc", "libgsl.scm", "gsl_matrix_complex_const_ptr", "libgsl.scm", "gsl_matrix_complex_div_elements", "libgsl.scm", "gsl_matrix_complex_equal", "libgsl.scm", "gsl_matrix_complex_fprintf", "libgsl.scm", "gsl_matrix_complex_fread", "libgsl.scm", "gsl_matrix_complex_free", "libgsl.scm", "gsl_matrix_complex_fscanf", "libgsl.scm", "gsl_matrix_complex_fwrite", "libgsl.scm", "gsl_matrix_complex_get", "libgsl.scm", "gsl_matrix_complex_get_col", "libgsl.scm", "gsl_matrix_complex_get_row", "libgsl.scm", "gsl_matrix_complex_isneg", "libgsl.scm", "gsl_matrix_complex_isnonneg", "libgsl.scm", "gsl_matrix_complex_isnull", "libgsl.scm", "gsl_matrix_complex_ispos", "libgsl.scm", "gsl_matrix_complex_memcpy", "libgsl.scm", "gsl_matrix_complex_mul_elements", "libgsl.scm", "gsl_matrix_complex_ptr", "libgsl.scm", "gsl_matrix_complex_scale", "libgsl.scm", "gsl_matrix_complex_set", "libgsl.scm", "gsl_matrix_complex_set_all", "libgsl.scm", "gsl_matrix_complex_set_col", "libgsl.scm", "gsl_matrix_complex_set_identity", "libgsl.scm", "gsl_matrix_complex_set_row", "libgsl.scm", "gsl_matrix_complex_set_zero", "libgsl.scm", "gsl_matrix_complex_sub", "libgsl.scm", "gsl_matrix_complex_swap", "libgsl.scm", "gsl_matrix_complex_swap_columns", "libgsl.scm", "gsl_matrix_complex_swap_rowcol", "libgsl.scm", "gsl_matrix_complex_swap_rows", "libgsl.scm", "gsl_matrix_complex_transpose", "libgsl.scm", "gsl_matrix_complex_transpose_memcpy", "libgsl.scm", "gsl_matrix_const_ptr", "libgsl.scm", "gsl_matrix_div_elements", "libgsl.scm", "gsl_matrix_equal", "libgsl.scm", "gsl_matrix_fprintf", "libgsl.scm", "gsl_matrix_fread", "libgsl.scm", "gsl_matrix_free", "libgsl.scm", "gsl_matrix_fscanf", "libgsl.scm", "gsl_matrix_fwrite", "libgsl.scm", "gsl_matrix_get", "libgsl.scm", "gsl_matrix_get_col", "libgsl.scm", "gsl_matrix_get_row", "libgsl.scm", "gsl_matrix_isneg", "libgsl.scm", "gsl_matrix_isnonneg", "libgsl.scm", "gsl_matrix_isnull", "libgsl.scm", "gsl_matrix_ispos", "libgsl.scm", "gsl_matrix_max", "libgsl.scm", "gsl_matrix_max_index", "libgsl.scm", "gsl_matrix_memcpy", "libgsl.scm", "gsl_matrix_min", "libgsl.scm", "gsl_matrix_min_index", "libgsl.scm", "gsl_matrix_minmax", "libgsl.scm", "gsl_matrix_minmax_index", "libgsl.scm", "gsl_matrix_mul_elements", "libgsl.scm", "gsl_matrix_ptr", "libgsl.scm", "gsl_matrix_scale", "libgsl.scm", "gsl_matrix_set", "libgsl.scm", "gsl_matrix_set_all", "libgsl.scm", "gsl_matrix_set_col", "libgsl.scm", "gsl_matrix_set_identity", "libgsl.scm", "gsl_matrix_set_row", "libgsl.scm", "gsl_matrix_set_zero", "libgsl.scm", "gsl_matrix_size", "libgsl.scm", "gsl_matrix_sub", "libgsl.scm", "gsl_matrix_swap", "libgsl.scm", "gsl_matrix_swap_columns", "libgsl.scm", "gsl_matrix_swap_rowcol", "libgsl.scm", "gsl_matrix_swap_rows", "libgsl.scm", "gsl_matrix_transpose", "libgsl.scm", "gsl_matrix_transpose_memcpy", "libgsl.scm", "gsl_max", "libgsl.scm", "gsl_message", "libgsl.scm", "gsl_message_mask", "libgsl.scm", "gsl_min", "libgsl.scm", "gsl_min_find_bracket", "libgsl.scm", "gsl_min_fminimizer_alloc", "libgsl.scm", "gsl_min_fminimizer_brent", "libgsl.scm", "gsl_min_fminimizer_f_lower", "libgsl.scm", "gsl_min_fminimizer_f_minimum", "libgsl.scm", "gsl_min_fminimizer_f_upper", "libgsl.scm", "gsl_min_fminimizer_free", "libgsl.scm", "gsl_min_fminimizer_goldensection", "libgsl.scm", "gsl_min_fminimizer_iterate", "libgsl.scm", "gsl_min_fminimizer_minimum", "libgsl.scm", "gsl_min_fminimizer_name", "libgsl.scm", "gsl_min_fminimizer_quad_golden", "libgsl.scm", "gsl_min_fminimizer_set", "libgsl.scm", "gsl_min_fminimizer_set_with_values", "libgsl.scm", "gsl_min_fminimizer_x_lower", "libgsl.scm", "gsl_min_fminimizer_x_minimum", "libgsl.scm", "gsl_min_fminimizer_x_upper", "libgsl.scm", "gsl_min_test_interval", "libgsl.scm", "gsl_multifit_covar", "libgsl.scm", "gsl_multifit_covar_QRPT", "libgsl.scm", "gsl_multifit_fsolver_alloc", "libgsl.scm", "gsl_multifit_fsolver_driver", "libgsl.scm", "gsl_multifit_fsolver_free", "libgsl.scm", "gsl_multifit_fsolver_iterate", "libgsl.scm", "gsl_multifit_fsolver_name", "libgsl.scm", "gsl_multifit_fsolver_position", "libgsl.scm", "gsl_multifit_fsolver_set", "libgsl.scm", "gsl_multifit_gradient", "libgsl.scm", "gsl_multifit_linear", "libgsl.scm", "gsl_multifit_linear_Lk", "libgsl.scm", "gsl_multifit_linear_Lsobolev", "libgsl.scm", "gsl_multifit_linear_alloc", "libgsl.scm", "gsl_multifit_linear_applyW", "libgsl.scm", "gsl_multifit_linear_bsvd", "libgsl.scm", "gsl_multifit_linear_est", "libgsl.scm", "gsl_multifit_linear_free", "libgsl.scm", "gsl_multifit_linear_genform1", "libgsl.scm", "gsl_multifit_linear_genform2", "libgsl.scm", "gsl_multifit_linear_lcorner", "libgsl.scm", "gsl_multifit_linear_lcorner2", "libgsl.scm", "gsl_multifit_linear_lcurve", "libgsl.scm", "gsl_multifit_linear_lreg", "libgsl.scm", "gsl_multifit_linear_residuals", "libgsl.scm", "gsl_multifit_linear_solve", "libgsl.scm", "gsl_multifit_linear_stdform1", "libgsl.scm", "gsl_multifit_linear_stdform2", "libgsl.scm", "gsl_multifit_linear_svd", "libgsl.scm", "gsl_multifit_linear_wgenform2", "libgsl.scm", "gsl_multifit_linear_wstdform1", "libgsl.scm", "gsl_multifit_linear_wstdform2", "libgsl.scm", "gsl_multifit_robust", "libgsl.scm", "gsl_multifit_robust_alloc", "libgsl.scm", "gsl_multifit_robust_bisquare", "libgsl.scm", "gsl_multifit_robust_cauchy", "libgsl.scm", "gsl_multifit_robust_default", "libgsl.scm", "gsl_multifit_robust_est", "libgsl.scm", "gsl_multifit_robust_fair", "libgsl.scm", "gsl_multifit_robust_free", "libgsl.scm", "gsl_multifit_robust_huber", "libgsl.scm", "gsl_multifit_robust_maxiter", "libgsl.scm", "gsl_multifit_robust_name", "libgsl.scm", "gsl_multifit_robust_ols", "libgsl.scm", "gsl_multifit_robust_residuals", "libgsl.scm", "gsl_multifit_robust_statistics", "libgsl.scm", "gsl_multifit_robust_tune", "libgsl.scm", "gsl_multifit_robust_weights", "libgsl.scm", "gsl_multifit_robust_welsch", "libgsl.scm", "gsl_multifit_test_delta", "libgsl.scm", "gsl_multifit_test_gradient", "libgsl.scm", "gsl_multifit_wlinear", "libgsl.scm", "gsl_multifit_wlinear_svd", "libgsl.scm", "gsl_multifit_wlinear_usvd", "libgsl.scm", "gsl_multimin_diff", "libgsl.scm", "gsl_multimin_fminimizer_alloc", "libgsl.scm", "gsl_multimin_fminimizer_free", "libgsl.scm", "gsl_multimin_fminimizer_fval", "libgsl.scm", "gsl_multimin_fminimizer_iterate", "libgsl.scm", "gsl_multimin_fminimizer_minimum", "libgsl.scm", "gsl_multimin_fminimizer_name", "libgsl.scm", "gsl_multimin_fminimizer_nmsimplex", "libgsl.scm", "gsl_multimin_fminimizer_nmsimplex2", "libgsl.scm", "gsl_multimin_fminimizer_nmsimplex2rand", "libgsl.scm", "gsl_multimin_fminimizer_set", "libgsl.scm", "gsl_multimin_fminimizer_size", "libgsl.scm", "gsl_multimin_fminimizer_x", "libgsl.scm", "gsl_multimin_test_gradient", "libgsl.scm", "gsl_multimin_test_size", "libgsl.scm", "gsl_multiroot_fdjacobian", "libgsl.scm", "gsl_multiroot_fsolver_alloc", "libgsl.scm", "gsl_multiroot_fsolver_broyden", "libgsl.scm", "gsl_multiroot_fsolver_dnewton", "libgsl.scm", "gsl_multiroot_fsolver_dx", "libgsl.scm", "gsl_multiroot_fsolver_f", "libgsl.scm", "gsl_multiroot_fsolver_free", "libgsl.scm", "gsl_multiroot_fsolver_hybrid", "libgsl.scm", "gsl_multiroot_fsolver_hybrids", "libgsl.scm", "gsl_multiroot_fsolver_iterate", "libgsl.scm", "gsl_multiroot_fsolver_name", "libgsl.scm", "gsl_multiroot_fsolver_root", "libgsl.scm", "gsl_multiroot_fsolver_set", "libgsl.scm", "gsl_multiroot_test_delta", "libgsl.scm", "gsl_multiroot_test_residual", "libgsl.scm", "gsl_multiset_alloc", "libgsl.scm", "gsl_multiset_calloc", "libgsl.scm", "gsl_multiset_data", "libgsl.scm", "gsl_multiset_fprintf", "libgsl.scm", "gsl_multiset_fread", "libgsl.scm", "gsl_multiset_free", "libgsl.scm", "gsl_multiset_fscanf", "libgsl.scm", "gsl_multiset_fwrite", "libgsl.scm", "gsl_multiset_get", "libgsl.scm", "gsl_multiset_init_first", "libgsl.scm", "gsl_multiset_init_last", "libgsl.scm", "gsl_multiset_k", "libgsl.scm", "gsl_multiset_memcpy", "libgsl.scm", "gsl_multiset_n", "libgsl.scm", "gsl_multiset_next", "libgsl.scm", "gsl_multiset_prev", "libgsl.scm", "gsl_multiset_valid", "libgsl.scm", "gsl_nan", "libgsl.scm", "gsl_neginf", "libgsl.scm", "gsl_permutation_alloc", "libgsl.scm", "gsl_permutation_calloc", "libgsl.scm", "gsl_permutation_canonical_cycles", "libgsl.scm", "gsl_permutation_canonical_to_linear", "libgsl.scm", "gsl_permutation_data", "libgsl.scm", "gsl_permutation_fprintf", "libgsl.scm", "gsl_permutation_fread", "libgsl.scm", "gsl_permutation_free", "libgsl.scm", "gsl_permutation_fscanf", "libgsl.scm", "gsl_permutation_fwrite", "libgsl.scm", "gsl_permutation_get", "libgsl.scm", "gsl_permutation_init", "libgsl.scm", "gsl_permutation_inverse", "libgsl.scm", "gsl_permutation_inversions", "libgsl.scm", "gsl_permutation_linear_cycles", "libgsl.scm", "gsl_permutation_linear_to_canonical", "libgsl.scm", "gsl_permutation_memcpy", "libgsl.scm", "gsl_permutation_mul", "libgsl.scm", "gsl_permutation_next", "libgsl.scm", "gsl_permutation_prev", "libgsl.scm", "gsl_permutation_reverse", "libgsl.scm", "gsl_permutation_size", "libgsl.scm", "gsl_permutation_swap", "libgsl.scm", "gsl_permutation_valid", "libgsl.scm", "gsl_permute", "libgsl.scm", "gsl_permute_complex", "libgsl.scm", "gsl_permute_complex_inverse", "libgsl.scm", "gsl_permute_inverse", "libgsl.scm", "gsl_permute_vector", "libgsl.scm", "gsl_permute_vector_complex", "libgsl.scm", "gsl_permute_vector_complex_inverse", "libgsl.scm", "gsl_permute_vector_inverse", "libgsl.scm", "gsl_poly_complex_eval", "libgsl.scm", "gsl_poly_complex_solve", "libgsl.scm", "gsl_poly_complex_solve_cubic", "libgsl.scm", "gsl_poly_complex_solve_quadratic", "libgsl.scm", "gsl_poly_complex_workspace_alloc", "libgsl.scm", "gsl_poly_complex_workspace_free", "libgsl.scm", "gsl_poly_dd_eval", "libgsl.scm", "gsl_poly_dd_hermite_init", "libgsl.scm", "gsl_poly_dd_init", "libgsl.scm", "gsl_poly_dd_taylor", "libgsl.scm", "gsl_poly_eval", "libgsl.scm", "gsl_poly_eval_derivs", "libgsl.scm", "gsl_poly_solve_cubic", "libgsl.scm", "gsl_poly_solve_quadratic", "libgsl.scm", "gsl_posinf", "libgsl.scm", "gsl_pow_2", "libgsl.scm", "gsl_pow_3", "libgsl.scm", "gsl_pow_4", "libgsl.scm", "gsl_pow_5", "libgsl.scm", "gsl_pow_6", "libgsl.scm", "gsl_pow_7", "libgsl.scm", "gsl_pow_8", "libgsl.scm", "gsl_pow_9", "libgsl.scm", "gsl_pow_int", "libgsl.scm", "gsl_prec_eps", "libgsl.scm", "gsl_prec_root3_eps", "libgsl.scm", "gsl_prec_root4_eps", "libgsl.scm", "gsl_prec_root5_eps", "libgsl.scm", "gsl_prec_root6_eps", "libgsl.scm", "gsl_prec_sqrt_eps", "libgsl.scm", "gsl_qrng_alloc", "libgsl.scm", "gsl_qrng_clone", "libgsl.scm", "gsl_qrng_free", "libgsl.scm", "gsl_qrng_get", "libgsl.scm", "gsl_qrng_halton", "libgsl.scm", "gsl_qrng_init", "libgsl.scm", "gsl_qrng_memcpy", "libgsl.scm", "gsl_qrng_name", "libgsl.scm", "gsl_qrng_niederreiter_2", "libgsl.scm", "gsl_qrng_reversehalton", "libgsl.scm", "gsl_qrng_size", "libgsl.scm", "gsl_qrng_sobol", "libgsl.scm", "gsl_qrng_state", "libgsl.scm", "gsl_ran_bernoulli", "libgsl.scm", "gsl_ran_bernoulli_pdf", "libgsl.scm", "gsl_ran_beta", "libgsl.scm", "gsl_ran_beta_pdf", "libgsl.scm", "gsl_ran_binomial", "libgsl.scm", "gsl_ran_binomial_knuth", "libgsl.scm", "gsl_ran_binomial_pdf", "libgsl.scm", "gsl_ran_binomial_tpe", "libgsl.scm", "gsl_ran_bivariate_gaussian", "libgsl.scm", "gsl_ran_bivariate_gaussian_pdf", "libgsl.scm", "gsl_ran_cauchy", "libgsl.scm", "gsl_ran_cauchy_pdf", "libgsl.scm", "gsl_ran_chisq", "libgsl.scm", "gsl_ran_chisq_pdf", "libgsl.scm", "gsl_ran_choose", "libgsl.scm", "gsl_ran_dir_2d", "libgsl.scm", "gsl_ran_dir_2d_trig_method", "libgsl.scm", "gsl_ran_dir_3d", "libgsl.scm", "gsl_ran_dir_nd", "libgsl.scm", "gsl_ran_dirichlet", "libgsl.scm", "gsl_ran_dirichlet_lnpdf", "libgsl.scm", "gsl_ran_dirichlet_pdf", "libgsl.scm", "gsl_ran_discrete", "libgsl.scm", "gsl_ran_discrete_free", "libgsl.scm", "gsl_ran_discrete_pdf", "libgsl.scm", "gsl_ran_discrete_preproc", "libgsl.scm", "gsl_ran_erlang", "libgsl.scm", "gsl_ran_erlang_pdf", "libgsl.scm", "gsl_ran_exponential", "libgsl.scm", "gsl_ran_exponential_pdf", "libgsl.scm", "gsl_ran_exppow", "libgsl.scm", "gsl_ran_exppow_pdf", "libgsl.scm", "gsl_ran_fdist", "libgsl.scm", "gsl_ran_fdist_pdf", "libgsl.scm", "gsl_ran_flat", "libgsl.scm", "gsl_ran_flat_pdf", "libgsl.scm", "gsl_ran_gamma", "libgsl.scm", "gsl_ran_gamma_int", "libgsl.scm", "gsl_ran_gamma_knuth", "libgsl.scm", "gsl_ran_gamma_mt", "libgsl.scm", "gsl_ran_gamma_pdf", "libgsl.scm", "gsl_ran_gaussian", "libgsl.scm", "gsl_ran_gaussian_pdf", "libgsl.scm", "gsl_ran_gaussian_ratio_method", "libgsl.scm", "gsl_ran_gaussian_tail", "libgsl.scm", "gsl_ran_gaussian_tail_pdf", "libgsl.scm", "gsl_ran_gaussian_ziggurat", "libgsl.scm", "gsl_ran_geometric", "libgsl.scm", "gsl_ran_geometric_pdf", "libgsl.scm", "gsl_ran_gumbel1", "libgsl.scm", "gsl_ran_gumbel1_pdf", "libgsl.scm", "gsl_ran_gumbel2", "libgsl.scm", "gsl_ran_gumbel2_pdf", "libgsl.scm", "gsl_ran_hypergeometric", "libgsl.scm", "gsl_ran_hypergeometric_pdf", "libgsl.scm", "gsl_ran_landau", "libgsl.scm", "gsl_ran_landau_pdf", "libgsl.scm", "gsl_ran_laplace", "libgsl.scm", "gsl_ran_laplace_pdf", "libgsl.scm", "gsl_ran_levy", "libgsl.scm", "gsl_ran_levy_skew", "libgsl.scm", "gsl_ran_logarithmic", "libgsl.scm", "gsl_ran_logarithmic_pdf", "libgsl.scm", "gsl_ran_logistic", "libgsl.scm", "gsl_ran_logistic_pdf", "libgsl.scm", "gsl_ran_lognormal", "libgsl.scm", "gsl_ran_lognormal_pdf", "libgsl.scm", "gsl_ran_negative_binomial", "libgsl.scm", "gsl_ran_negative_binomial_pdf", "libgsl.scm", "gsl_ran_pareto", "libgsl.scm", "gsl_ran_pareto_pdf", "libgsl.scm", "gsl_ran_pascal", "libgsl.scm", "gsl_ran_pascal_pdf", "libgsl.scm", "gsl_ran_poisson", "libgsl.scm", "gsl_ran_poisson_pdf", "libgsl.scm", "gsl_ran_rayleigh", "libgsl.scm", "gsl_ran_rayleigh_pdf", "libgsl.scm", "gsl_ran_rayleigh_tail", "libgsl.scm", "gsl_ran_rayleigh_tail_pdf", "libgsl.scm", "gsl_ran_sample", "libgsl.scm", "gsl_ran_shuffle", "libgsl.scm", "gsl_ran_tdist", "libgsl.scm", "gsl_ran_tdist_pdf", "libgsl.scm", "gsl_ran_ugaussian", "libgsl.scm", "gsl_ran_ugaussian_pdf", "libgsl.scm", "gsl_ran_ugaussian_ratio_method", "libgsl.scm", "gsl_ran_ugaussian_tail", "libgsl.scm", "gsl_ran_ugaussian_tail_pdf", "libgsl.scm", "gsl_ran_weibull", "libgsl.scm", "gsl_ran_weibull_pdf", "libgsl.scm", "gsl_rng_alloc", "libgsl.scm", "gsl_rng_borosh13", "libgsl.scm", "gsl_rng_clone", "libgsl.scm", "gsl_rng_cmrg", "libgsl.scm", "gsl_rng_coveyou", "libgsl.scm", "gsl_rng_default", "libgsl.scm", "gsl_rng_default_seed", "libgsl.scm", "gsl_rng_env_setup", "libgsl.scm", "gsl_rng_fishman18", "libgsl.scm", "gsl_rng_fishman20", "libgsl.scm", "gsl_rng_fishman2x", "libgsl.scm", "gsl_rng_fread", "libgsl.scm", "gsl_rng_free", "libgsl.scm", "gsl_rng_fwrite", "libgsl.scm", "gsl_rng_get", "libgsl.scm", "gsl_rng_gfsr4", "libgsl.scm", "gsl_rng_knuthran", "libgsl.scm", "gsl_rng_knuthran2", "libgsl.scm", "gsl_rng_knuthran2002", "libgsl.scm", "gsl_rng_lecuyer21", "libgsl.scm", "gsl_rng_max", "libgsl.scm", "gsl_rng_memcpy", "libgsl.scm", "gsl_rng_min", "libgsl.scm", "gsl_rng_minstd", "libgsl.scm", "gsl_rng_mrg", "libgsl.scm", "gsl_rng_mt19937", "libgsl.scm", "gsl_rng_mt19937_1998", "libgsl.scm", "gsl_rng_mt19937_1999", "libgsl.scm", "gsl_rng_name", "libgsl.scm", "gsl_rng_print_state", "libgsl.scm", "gsl_rng_r250", "libgsl.scm", "gsl_rng_ran0", "libgsl.scm", "gsl_rng_ran1", "libgsl.scm", "gsl_rng_ran2", "libgsl.scm", "gsl_rng_ran3", "libgsl.scm", "gsl_rng_rand", "libgsl.scm", "gsl_rng_rand48", "libgsl.scm", "gsl_rng_random128_bsd", "libgsl.scm", "gsl_rng_random128_glibc2", "libgsl.scm", "gsl_rng_random128_libc5", "libgsl.scm", "gsl_rng_random256_bsd", "libgsl.scm", "gsl_rng_random256_glibc2", "libgsl.scm", "gsl_rng_random256_libc5", "libgsl.scm", "gsl_rng_random32_bsd", "libgsl.scm", "gsl_rng_random32_glibc2", "libgsl.scm", "gsl_rng_random32_libc5", "libgsl.scm", "gsl_rng_random64_bsd", "libgsl.scm", "gsl_rng_random64_glibc2", "libgsl.scm", "gsl_rng_random64_libc5", "libgsl.scm", "gsl_rng_random8_bsd", "libgsl.scm", "gsl_rng_random8_glibc2", "libgsl.scm", "gsl_rng_random8_libc5", "libgsl.scm", "gsl_rng_random_bsd", "libgsl.scm", "gsl_rng_random_glibc2", "libgsl.scm", "gsl_rng_random_libc5", "libgsl.scm", "gsl_rng_randu", "libgsl.scm", "gsl_rng_ranf", "libgsl.scm", "gsl_rng_ranlux", "libgsl.scm", "gsl_rng_ranlux389", "libgsl.scm", "gsl_rng_ranlxd1", "libgsl.scm", "gsl_rng_ranlxd2", "libgsl.scm", "gsl_rng_ranlxs0", "libgsl.scm", "gsl_rng_ranlxs1", "libgsl.scm", "gsl_rng_ranlxs2", "libgsl.scm", "gsl_rng_ranmar", "libgsl.scm", "gsl_rng_set", "libgsl.scm", "gsl_rng_size", "libgsl.scm", "gsl_rng_slatec", "libgsl.scm", "gsl_rng_state", "libgsl.scm", "gsl_rng_taus", "libgsl.scm", "gsl_rng_taus113", "libgsl.scm", "gsl_rng_taus2", "libgsl.scm", "gsl_rng_transputer", "libgsl.scm", "gsl_rng_tt800", "libgsl.scm", "gsl_rng_types_setup", "libgsl.scm", "gsl_rng_uni", "libgsl.scm", "gsl_rng_uni32", "libgsl.scm", "gsl_rng_uniform", "libgsl.scm", "gsl_rng_uniform_int", "libgsl.scm", "gsl_rng_uniform_pos", "libgsl.scm", "gsl_rng_vax", "libgsl.scm", "gsl_rng_waterman14", "libgsl.scm", "gsl_rng_zuf", "libgsl.scm", "gsl_root_fsolver_alloc", "libgsl.scm", "gsl_root_fsolver_bisection", "libgsl.scm", "gsl_root_fsolver_brent", "libgsl.scm", "gsl_root_fsolver_falsepos", "libgsl.scm", "gsl_root_fsolver_free", "libgsl.scm", "gsl_root_fsolver_iterate", "libgsl.scm", "gsl_root_fsolver_name", "libgsl.scm", "gsl_root_fsolver_root", "libgsl.scm", "gsl_root_fsolver_set", "libgsl.scm", "gsl_root_fsolver_x_lower", "libgsl.scm", "gsl_root_fsolver_x_upper", "libgsl.scm", "gsl_root_test_delta", "libgsl.scm", "gsl_root_test_interval", "libgsl.scm", "gsl_root_test_residual", "libgsl.scm", "gsl_rstat_add", "libgsl.scm", "gsl_rstat_alloc", "libgsl.scm", "gsl_rstat_free", "libgsl.scm", "gsl_rstat_kurtosis", "libgsl.scm", "gsl_rstat_max", "libgsl.scm", "gsl_rstat_mean", "libgsl.scm", "gsl_rstat_median", "libgsl.scm", "gsl_rstat_min", "libgsl.scm", "gsl_rstat_n", "libgsl.scm", "gsl_rstat_quantile_add", "libgsl.scm", "gsl_rstat_quantile_alloc", "libgsl.scm", "gsl_rstat_quantile_free", "libgsl.scm", "gsl_rstat_quantile_get", "libgsl.scm", "gsl_rstat_reset", "libgsl.scm", "gsl_rstat_sd", "libgsl.scm", "gsl_rstat_sd_mean", "libgsl.scm", "gsl_rstat_skew", "libgsl.scm", "gsl_rstat_variance", "libgsl.scm", "gsl_schur_gen_eigvals", "libgsl.scm", "gsl_schur_solve_equation", "libgsl.scm", "gsl_schur_solve_equation_z", "libgsl.scm", "gsl_set_error_handler", "libgsl.scm", "gsl_set_error_handler_off", "libgsl.scm", "gsl_set_stream", "libgsl.scm", "gsl_set_stream_handler", "libgsl.scm", "gsl_sf_Chi", "libgsl.scm", "gsl_sf_Chi_e", "libgsl.scm", "gsl_sf_Ci", "libgsl.scm", "gsl_sf_Ci_e", "libgsl.scm", "gsl_sf_Shi", "libgsl.scm", "gsl_sf_Shi_e", "libgsl.scm", "gsl_sf_Si", "libgsl.scm", "gsl_sf_Si_e", "libgsl.scm", "gsl_sf_airy_Ai", "libgsl.scm", "gsl_sf_airy_Ai_deriv", "libgsl.scm", "gsl_sf_airy_Ai_deriv_e", "libgsl.scm", "gsl_sf_airy_Ai_deriv_scaled", "libgsl.scm", "gsl_sf_airy_Ai_deriv_scaled_e", "libgsl.scm", "gsl_sf_airy_Ai_e", "libgsl.scm", "gsl_sf_airy_Ai_scaled", "libgsl.scm", "gsl_sf_airy_Ai_scaled_e", "libgsl.scm", "gsl_sf_airy_Bi", "libgsl.scm", "gsl_sf_airy_Bi_deriv", "libgsl.scm", "gsl_sf_airy_Bi_deriv_e", "libgsl.scm", "gsl_sf_airy_Bi_deriv_scaled", "libgsl.scm", "gsl_sf_airy_Bi_deriv_scaled_e", "libgsl.scm", "gsl_sf_airy_Bi_e", "libgsl.scm", "gsl_sf_airy_Bi_scaled", "libgsl.scm", "gsl_sf_airy_Bi_scaled_e", "libgsl.scm", "gsl_sf_airy_zero_Ai", "libgsl.scm", "gsl_sf_airy_zero_Ai_deriv", "libgsl.scm", "gsl_sf_airy_zero_Ai_deriv_e", "libgsl.scm", "gsl_sf_airy_zero_Ai_e", "libgsl.scm", "gsl_sf_airy_zero_Bi", "libgsl.scm", "gsl_sf_airy_zero_Bi_deriv", "libgsl.scm", "gsl_sf_airy_zero_Bi_deriv_e", "libgsl.scm", "gsl_sf_airy_zero_Bi_e", "libgsl.scm", "gsl_sf_angle_restrict_pos", "libgsl.scm", "gsl_sf_angle_restrict_pos_e", "libgsl.scm", "gsl_sf_angle_restrict_pos_err_e", "libgsl.scm", "gsl_sf_angle_restrict_symm", "libgsl.scm", "gsl_sf_angle_restrict_symm_e", "libgsl.scm", "gsl_sf_angle_restrict_symm_err_e", "libgsl.scm", "gsl_sf_atanint", "libgsl.scm", "gsl_sf_atanint_e", "libgsl.scm", "gsl_sf_bessel_I0", "libgsl.scm", "gsl_sf_bessel_I0_e", "libgsl.scm", "gsl_sf_bessel_I0_scaled", "libgsl.scm", "gsl_sf_bessel_I0_scaled_e", "libgsl.scm", "gsl_sf_bessel_I1", "libgsl.scm", "gsl_sf_bessel_I1_e", "libgsl.scm", "gsl_sf_bessel_I1_scaled", "libgsl.scm", "gsl_sf_bessel_I1_scaled_e", "libgsl.scm", "gsl_sf_bessel_In", "libgsl.scm", "gsl_sf_bessel_In_array", "libgsl.scm", "gsl_sf_bessel_In_e", "libgsl.scm", "gsl_sf_bessel_In_scaled", "libgsl.scm", "gsl_sf_bessel_In_scaled_array", "libgsl.scm", "gsl_sf_bessel_In_scaled_e", "libgsl.scm", "gsl_sf_bessel_Inu", "libgsl.scm", "gsl_sf_bessel_Inu_e", "libgsl.scm", "gsl_sf_bessel_Inu_scaled", "libgsl.scm", "gsl_sf_bessel_Inu_scaled_e", "libgsl.scm", "gsl_sf_bessel_J0", "libgsl.scm", "gsl_sf_bessel_J0_e", "libgsl.scm", "gsl_sf_bessel_J1", "libgsl.scm", "gsl_sf_bessel_J1_e", "libgsl.scm", "gsl_sf_bessel_Jn", "libgsl.scm", "gsl_sf_bessel_Jn_array", "libgsl.scm", "gsl_sf_bessel_Jn_e", "libgsl.scm", "gsl_sf_bessel_Jnu", "libgsl.scm", "gsl_sf_bessel_Jnu_e", "libgsl.scm", "gsl_sf_bessel_K0", "libgsl.scm", "gsl_sf_bessel_K0_e", "libgsl.scm", "gsl_sf_bessel_K0_scaled", "libgsl.scm", "gsl_sf_bessel_K0_scaled_e", "libgsl.scm", "gsl_sf_bessel_K1", "libgsl.scm", "gsl_sf_bessel_K1_e", "libgsl.scm", "gsl_sf_bessel_K1_scaled", "libgsl.scm", "gsl_sf_bessel_K1_scaled_e", "libgsl.scm", "gsl_sf_bessel_Kn", "libgsl.scm", "gsl_sf_bessel_Kn_array", "libgsl.scm", "gsl_sf_bessel_Kn_e", "libgsl.scm", "gsl_sf_bessel_Kn_scaled", "libgsl.scm", "gsl_sf_bessel_Kn_scaled_array", "libgsl.scm", "gsl_sf_bessel_Kn_scaled_e", "libgsl.scm", "gsl_sf_bessel_Knu", "libgsl.scm", "gsl_sf_bessel_Knu_e", "libgsl.scm", "gsl_sf_bessel_Knu_scaled", "libgsl.scm", "gsl_sf_bessel_Knu_scaled_e", "libgsl.scm", "gsl_sf_bessel_Knu_scaled_e10_e", "libgsl.scm", "gsl_sf_bessel_Y0", "libgsl.scm", "gsl_sf_bessel_Y0_e", "libgsl.scm", "gsl_sf_bessel_Y1", "libgsl.scm", "gsl_sf_bessel_Y1_e", "libgsl.scm", "gsl_sf_bessel_Yn", "libgsl.scm", "gsl_sf_bessel_Yn_array", "libgsl.scm", "gsl_sf_bessel_Yn_e", "libgsl.scm", "gsl_sf_bessel_Ynu", "libgsl.scm", "gsl_sf_bessel_Ynu_e", "libgsl.scm", "gsl_sf_bessel_i0_scaled", "libgsl.scm", "gsl_sf_bessel_i0_scaled_e", "libgsl.scm", "gsl_sf_bessel_i1_scaled", "libgsl.scm", "gsl_sf_bessel_i1_scaled_e", "libgsl.scm", "gsl_sf_bessel_i2_scaled", "libgsl.scm", "gsl_sf_bessel_i2_scaled_e", "libgsl.scm", "gsl_sf_bessel_il_scaled", "libgsl.scm", "gsl_sf_bessel_il_scaled_array", "libgsl.scm", "gsl_sf_bessel_il_scaled_e", "libgsl.scm", "gsl_sf_bessel_j0", "libgsl.scm", "gsl_sf_bessel_j0_e", "libgsl.scm", "gsl_sf_bessel_j1", "libgsl.scm", "gsl_sf_bessel_j1_e", "libgsl.scm", "gsl_sf_bessel_j2", "libgsl.scm", "gsl_sf_bessel_j2_e", "libgsl.scm", "gsl_sf_bessel_jl", "libgsl.scm", "gsl_sf_bessel_jl_array", "libgsl.scm", "gsl_sf_bessel_jl_e", "libgsl.scm", "gsl_sf_bessel_jl_steed_array", "libgsl.scm", "gsl_sf_bessel_k0_scaled", "libgsl.scm", "gsl_sf_bessel_k0_scaled_e", "libgsl.scm", "gsl_sf_bessel_k1_scaled", "libgsl.scm", "gsl_sf_bessel_k1_scaled_e", "libgsl.scm", "gsl_sf_bessel_k2_scaled", "libgsl.scm", "gsl_sf_bessel_k2_scaled_e", "libgsl.scm", "gsl_sf_bessel_kl_scaled", "libgsl.scm", "gsl_sf_bessel_kl_scaled_array", "libgsl.scm", "gsl_sf_bessel_kl_scaled_e", "libgsl.scm", "gsl_sf_bessel_lnKnu", "libgsl.scm", "gsl_sf_bessel_lnKnu_e", "libgsl.scm", "gsl_sf_bessel_sequence_Jnu_e", "libgsl.scm", "gsl_sf_bessel_y0", "libgsl.scm", "gsl_sf_bessel_y0_e", "libgsl.scm", "gsl_sf_bessel_y1", "libgsl.scm", "gsl_sf_bessel_y1_e", "libgsl.scm", "gsl_sf_bessel_y2", "libgsl.scm", "gsl_sf_bessel_y2_e", "libgsl.scm", "gsl_sf_bessel_yl", "libgsl.scm", "gsl_sf_bessel_yl_array", "libgsl.scm", "gsl_sf_bessel_yl_e", "libgsl.scm", "gsl_sf_bessel_zero_J0", "libgsl.scm", "gsl_sf_bessel_zero_J0_e", "libgsl.scm", "gsl_sf_bessel_zero_J1", "libgsl.scm", "gsl_sf_bessel_zero_J1_e", "libgsl.scm", "gsl_sf_bessel_zero_Jnu", "libgsl.scm", "gsl_sf_bessel_zero_Jnu_e", "libgsl.scm", "gsl_sf_beta", "libgsl.scm", "gsl_sf_beta_e", "libgsl.scm", "gsl_sf_beta_inc", "libgsl.scm", "gsl_sf_beta_inc_e", "libgsl.scm", "gsl_sf_choose", "libgsl.scm", "gsl_sf_choose_e", "libgsl.scm", "gsl_sf_clausen", "libgsl.scm", "gsl_sf_clausen_e", "libgsl.scm", "gsl_sf_complex_cos_e", "libgsl.scm", "gsl_sf_complex_dilog_e", "libgsl.scm", "gsl_sf_complex_dilog_xy_e", "libgsl.scm", "gsl_sf_complex_log_e", "libgsl.scm", "gsl_sf_complex_logsin_e", "libgsl.scm", "gsl_sf_complex_psi_e", "libgsl.scm", "gsl_sf_complex_sin_e", "libgsl.scm", "gsl_sf_complex_spence_xy_e", "libgsl.scm", "gsl_sf_conicalP_0", "libgsl.scm", "gsl_sf_conicalP_0_e", "libgsl.scm", "gsl_sf_conicalP_1", "libgsl.scm", "gsl_sf_conicalP_1_e", "libgsl.scm", "gsl_sf_conicalP_cyl_reg", "libgsl.scm", "gsl_sf_conicalP_cyl_reg_e", "libgsl.scm", "gsl_sf_conicalP_half", "libgsl.scm", "gsl_sf_conicalP_half_e", "libgsl.scm", "gsl_sf_conicalP_mhalf", "libgsl.scm", "gsl_sf_conicalP_mhalf_e", "libgsl.scm", "gsl_sf_conicalP_sph_reg", "libgsl.scm", "gsl_sf_conicalP_sph_reg_e", "libgsl.scm", "gsl_sf_cos", "libgsl.scm", "gsl_sf_cos_e", "libgsl.scm", "gsl_sf_cos_err_e", "libgsl.scm", "gsl_sf_coulomb_CL_array", "libgsl.scm", "gsl_sf_coulomb_CL_e", "libgsl.scm", "gsl_sf_coulomb_wave_FG_array", "libgsl.scm", "gsl_sf_coulomb_wave_FG_e", "libgsl.scm", "gsl_sf_coulomb_wave_FGp_array", "libgsl.scm", "gsl_sf_coulomb_wave_F_array", "libgsl.scm", "gsl_sf_coulomb_wave_sphF_array", "libgsl.scm", "gsl_sf_coupling_3j", "libgsl.scm", "gsl_sf_coupling_3j_e", "libgsl.scm", "gsl_sf_coupling_6j", "libgsl.scm", "gsl_sf_coupling_6j_e", "libgsl.scm", "gsl_sf_coupling_9j", "libgsl.scm", "gsl_sf_coupling_9j_e", "libgsl.scm", "gsl_sf_coupling_RacahW", "libgsl.scm", "gsl_sf_coupling_RacahW_e", "libgsl.scm", "gsl_sf_dawson", "libgsl.scm", "gsl_sf_dawson_e", "libgsl.scm", "gsl_sf_debye_1", "libgsl.scm", "gsl_sf_debye_1_e", "libgsl.scm", "gsl_sf_debye_2", "libgsl.scm", "gsl_sf_debye_2_e", "libgsl.scm", "gsl_sf_debye_3", "libgsl.scm", "gsl_sf_debye_3_e", "libgsl.scm", "gsl_sf_debye_4", "libgsl.scm", "gsl_sf_debye_4_e", "libgsl.scm", "gsl_sf_debye_5", "libgsl.scm", "gsl_sf_debye_5_e", "libgsl.scm", "gsl_sf_debye_6", "libgsl.scm", "gsl_sf_debye_6_e", "libgsl.scm", "gsl_sf_dilog", "libgsl.scm", "gsl_sf_dilog_e", "libgsl.scm", "gsl_sf_doublefact", "libgsl.scm", "gsl_sf_doublefact_e", "libgsl.scm", "gsl_sf_ellint_D", "libgsl.scm", "gsl_sf_ellint_D_e", "libgsl.scm", "gsl_sf_ellint_Dcomp", "libgsl.scm", "gsl_sf_ellint_Dcomp_e", "libgsl.scm", "gsl_sf_ellint_E", "libgsl.scm", "gsl_sf_ellint_E_e", "libgsl.scm", "gsl_sf_ellint_Ecomp", "libgsl.scm", "gsl_sf_ellint_Ecomp_e", "libgsl.scm", "gsl_sf_ellint_F", "libgsl.scm", "gsl_sf_ellint_F_e", "libgsl.scm", "gsl_sf_ellint_Kcomp", "libgsl.scm", "gsl_sf_ellint_Kcomp_e", "libgsl.scm", "gsl_sf_ellint_P", "libgsl.scm", "gsl_sf_ellint_P_e", "libgsl.scm", "gsl_sf_ellint_Pcomp", "libgsl.scm", "gsl_sf_ellint_Pcomp_e", "libgsl.scm", "gsl_sf_ellint_RC", "libgsl.scm", "gsl_sf_ellint_RC_e", "libgsl.scm", "gsl_sf_ellint_RD", "libgsl.scm", "gsl_sf_ellint_RD_e", "libgsl.scm", "gsl_sf_ellint_RF", "libgsl.scm", "gsl_sf_ellint_RF_e", "libgsl.scm", "gsl_sf_ellint_RJ", "libgsl.scm", "gsl_sf_ellint_RJ_e", "libgsl.scm", "gsl_sf_elljac_e", "libgsl.scm", "gsl_sf_erf", "libgsl.scm", "gsl_sf_erf_Q", "libgsl.scm", "gsl_sf_erf_Q_e", "libgsl.scm", "gsl_sf_erf_Z", "libgsl.scm", "gsl_sf_erf_Z_e", "libgsl.scm", "gsl_sf_erf_e", "libgsl.scm", "gsl_sf_erfc", "libgsl.scm", "gsl_sf_erfc_e", "libgsl.scm", "gsl_sf_eta", "libgsl.scm", "gsl_sf_eta_e", "libgsl.scm", "gsl_sf_eta_int", "libgsl.scm", "gsl_sf_eta_int_e", "libgsl.scm", "gsl_sf_exp", "libgsl.scm", "gsl_sf_exp_e", "libgsl.scm", "gsl_sf_exp_e10_e", "libgsl.scm", "gsl_sf_exp_err_e", "libgsl.scm", "gsl_sf_exp_err_e10_e", "libgsl.scm", "gsl_sf_exp_mult", "libgsl.scm", "gsl_sf_exp_mult_e", "libgsl.scm", "gsl_sf_exp_mult_e10_e", "libgsl.scm", "gsl_sf_exp_mult_err_e", "libgsl.scm", "gsl_sf_exp_mult_err_e10_e", "libgsl.scm", "gsl_sf_expint_3", "libgsl.scm", "gsl_sf_expint_3_e", "libgsl.scm", "gsl_sf_expint_E1", "libgsl.scm", "gsl_sf_expint_E1_e", "libgsl.scm", "gsl_sf_expint_E1_scaled", "libgsl.scm", "gsl_sf_expint_E1_scaled_e", "libgsl.scm", "gsl_sf_expint_E2", "libgsl.scm", "gsl_sf_expint_E2_e", "libgsl.scm", "gsl_sf_expint_E2_scaled", "libgsl.scm", "gsl_sf_expint_E2_scaled_e", "libgsl.scm", "gsl_sf_expint_Ei", "libgsl.scm", "gsl_sf_expint_Ei_e", "libgsl.scm", "gsl_sf_expint_Ei_scaled", "libgsl.scm", "gsl_sf_expint_Ei_scaled_e", "libgsl.scm", "gsl_sf_expint_En", "libgsl.scm", "gsl_sf_expint_En_e", "libgsl.scm", "gsl_sf_expint_En_scaled", "libgsl.scm", "gsl_sf_expint_En_scaled_e", "libgsl.scm", "gsl_sf_expm1", "libgsl.scm", "gsl_sf_expm1_e", "libgsl.scm", "gsl_sf_exprel", "libgsl.scm", "gsl_sf_exprel_2", "libgsl.scm", "gsl_sf_exprel_2_e", "libgsl.scm", "gsl_sf_exprel_e", "libgsl.scm", "gsl_sf_exprel_n", "libgsl.scm", "gsl_sf_exprel_n_CF_e", "libgsl.scm", "gsl_sf_exprel_n_e", "libgsl.scm", "gsl_sf_fact", "libgsl.scm", "gsl_sf_fact_e", "libgsl.scm", "gsl_sf_fermi_dirac_0", "libgsl.scm", "gsl_sf_fermi_dirac_0_e", "libgsl.scm", "gsl_sf_fermi_dirac_1", "libgsl.scm", "gsl_sf_fermi_dirac_1_e", "libgsl.scm", "gsl_sf_fermi_dirac_2", "libgsl.scm", "gsl_sf_fermi_dirac_2_e", "libgsl.scm", "gsl_sf_fermi_dirac_3half", "libgsl.scm", "gsl_sf_fermi_dirac_3half_e", "libgsl.scm", "gsl_sf_fermi_dirac_half", "libgsl.scm", "gsl_sf_fermi_dirac_half_e", "libgsl.scm", "gsl_sf_fermi_dirac_inc_0", "libgsl.scm", "gsl_sf_fermi_dirac_inc_0_e", "libgsl.scm", "gsl_sf_fermi_dirac_int", "libgsl.scm", "gsl_sf_fermi_dirac_int_e", "libgsl.scm", "gsl_sf_fermi_dirac_m1", "libgsl.scm", "gsl_sf_fermi_dirac_m1_e", "libgsl.scm", "gsl_sf_fermi_dirac_mhalf", "libgsl.scm", "gsl_sf_fermi_dirac_mhalf_e", "libgsl.scm", "gsl_sf_gamma", "libgsl.scm", "gsl_sf_gamma_e", "libgsl.scm", "gsl_sf_gamma_inc", "libgsl.scm", "gsl_sf_gamma_inc_P", "libgsl.scm", "gsl_sf_gamma_inc_P_e", "libgsl.scm", "gsl_sf_gamma_inc_Q", "libgsl.scm", "gsl_sf_gamma_inc_Q_e", "libgsl.scm", "gsl_sf_gamma_inc_e", "libgsl.scm", "gsl_sf_gammainv", "libgsl.scm", "gsl_sf_gammainv_e", "libgsl.scm", "gsl_sf_gammastar", "libgsl.scm", "gsl_sf_gammastar_e", "libgsl.scm", "gsl_sf_gegenpoly_1", "libgsl.scm", "gsl_sf_gegenpoly_1_e", "libgsl.scm", "gsl_sf_gegenpoly_2", "libgsl.scm", "gsl_sf_gegenpoly_2_e", "libgsl.scm", "gsl_sf_gegenpoly_3", "libgsl.scm", "gsl_sf_gegenpoly_3_e", "libgsl.scm", "gsl_sf_gegenpoly_array", "libgsl.scm", "gsl_sf_gegenpoly_n", "libgsl.scm", "gsl_sf_gegenpoly_n_e", "libgsl.scm", "gsl_sf_hazard", "libgsl.scm", "gsl_sf_hazard_e", "libgsl.scm", "gsl_sf_hydrogenicR", "libgsl.scm", "gsl_sf_hydrogenicR_1", "libgsl.scm", "gsl_sf_hydrogenicR_1_e", "libgsl.scm", "gsl_sf_hydrogenicR_e", "libgsl.scm", "gsl_sf_hyperg_0F1", "libgsl.scm", "gsl_sf_hyperg_0F1_e", "libgsl.scm", "gsl_sf_hyperg_1F1", "libgsl.scm", "gsl_sf_hyperg_1F1_e", "libgsl.scm", "gsl_sf_hyperg_1F1_int", "libgsl.scm", "gsl_sf_hyperg_1F1_int_e", "libgsl.scm", "gsl_sf_hyperg_2F0", "libgsl.scm", "gsl_sf_hyperg_2F0_e", "libgsl.scm", "gsl_sf_hyperg_2F1", "libgsl.scm", "gsl_sf_hyperg_2F1_conj", "libgsl.scm", "gsl_sf_hyperg_2F1_conj_e", "libgsl.scm", "gsl_sf_hyperg_2F1_conj_renorm", "libgsl.scm", "gsl_sf_hyperg_2F1_conj_renorm_e", "libgsl.scm", "gsl_sf_hyperg_2F1_e", "libgsl.scm", "gsl_sf_hyperg_2F1_renorm", "libgsl.scm", "gsl_sf_hyperg_2F1_renorm_e", "libgsl.scm", "gsl_sf_hyperg_U", "libgsl.scm", "gsl_sf_hyperg_U_e", "libgsl.scm", "gsl_sf_hyperg_U_e10_e", "libgsl.scm", "gsl_sf_hyperg_U_int", "libgsl.scm", "gsl_sf_hyperg_U_int_e", "libgsl.scm", "gsl_sf_hyperg_U_int_e10_e", "libgsl.scm", "gsl_sf_hypot", "libgsl.scm", "gsl_sf_hypot_e", "libgsl.scm", "gsl_sf_hzeta", "libgsl.scm", "gsl_sf_hzeta_e", "libgsl.scm", "gsl_sf_laguerre_1", "libgsl.scm", "gsl_sf_laguerre_1_e", "libgsl.scm", "gsl_sf_laguerre_2", "libgsl.scm", "gsl_sf_laguerre_2_e", "libgsl.scm", "gsl_sf_laguerre_3", "libgsl.scm", "gsl_sf_laguerre_3_e", "libgsl.scm", "gsl_sf_laguerre_n", "libgsl.scm", "gsl_sf_laguerre_n_e", "libgsl.scm", "gsl_sf_lambert_W0", "libgsl.scm", "gsl_sf_lambert_W0_e", "libgsl.scm", "gsl_sf_lambert_Wm1", "libgsl.scm", "gsl_sf_lambert_Wm1_e", "libgsl.scm", "gsl_sf_legendre_H3d", "libgsl.scm", "gsl_sf_legendre_H3d_0", "libgsl.scm", "gsl_sf_legendre_H3d_0_e", "libgsl.scm", "gsl_sf_legendre_H3d_1", "libgsl.scm", "gsl_sf_legendre_H3d_1_e", "libgsl.scm", "gsl_sf_legendre_H3d_array", "libgsl.scm", "gsl_sf_legendre_H3d_e", "libgsl.scm", "gsl_sf_legendre_P1", "libgsl.scm", "gsl_sf_legendre_P1_e", "libgsl.scm", "gsl_sf_legendre_P2", "libgsl.scm", "gsl_sf_legendre_P2_e", "libgsl.scm", "gsl_sf_legendre_P3", "libgsl.scm", "gsl_sf_legendre_P3_e", "libgsl.scm", "gsl_sf_legendre_Pl", "libgsl.scm", "gsl_sf_legendre_Pl_array", "libgsl.scm", "gsl_sf_legendre_Pl_deriv_array", "libgsl.scm", "gsl_sf_legendre_Pl_e", "libgsl.scm", "gsl_sf_legendre_Plm", "libgsl.scm", "gsl_sf_legendre_Plm_e", "libgsl.scm", "gsl_sf_legendre_Q0", "libgsl.scm", "gsl_sf_legendre_Q0_e", "libgsl.scm", "gsl_sf_legendre_Q1", "libgsl.scm", "gsl_sf_legendre_Q1_e", "libgsl.scm", "gsl_sf_legendre_Ql", "libgsl.scm", "gsl_sf_legendre_Ql_e", "libgsl.scm", "gsl_sf_legendre_array", "libgsl.scm", "gsl_sf_legendre_array_e", "libgsl.scm", "gsl_sf_legendre_array_index", "libgsl.scm", "gsl_sf_legendre_array_n", "libgsl.scm", "gsl_sf_legendre_deriv2_alt_array", "libgsl.scm", "gsl_sf_legendre_deriv2_alt_array_e", "libgsl.scm", "gsl_sf_legendre_deriv2_array", "libgsl.scm", "gsl_sf_legendre_deriv2_array_e", "libgsl.scm", "gsl_sf_legendre_deriv_alt_array", "libgsl.scm", "gsl_sf_legendre_deriv_alt_array_e", "libgsl.scm", "gsl_sf_legendre_deriv_array", "libgsl.scm", "gsl_sf_legendre_deriv_array_e", "libgsl.scm", "gsl_sf_legendre_nlm", "libgsl.scm", "gsl_sf_legendre_sphPlm", "libgsl.scm", "gsl_sf_legendre_sphPlm_e", "libgsl.scm", "gsl_sf_lnbeta", "libgsl.scm", "gsl_sf_lnbeta_e", "libgsl.scm", "gsl_sf_lnbeta_sgn_e", "libgsl.scm", "gsl_sf_lnchoose", "libgsl.scm", "gsl_sf_lnchoose_e", "libgsl.scm", "gsl_sf_lncosh", "libgsl.scm", "gsl_sf_lncosh_e", "libgsl.scm", "gsl_sf_lndoublefact", "libgsl.scm", "gsl_sf_lndoublefact_e", "libgsl.scm", "gsl_sf_lnfact", "libgsl.scm", "gsl_sf_lnfact_e", "libgsl.scm", "gsl_sf_lngamma", "libgsl.scm", "gsl_sf_lngamma_complex_e", "libgsl.scm", "gsl_sf_lngamma_e", "libgsl.scm", "gsl_sf_lngamma_sgn_e", "libgsl.scm", "gsl_sf_lnpoch", "libgsl.scm", "gsl_sf_lnpoch_e", "libgsl.scm", "gsl_sf_lnpoch_sgn_e", "libgsl.scm", "gsl_sf_lnsinh", "libgsl.scm", "gsl_sf_lnsinh_e", "libgsl.scm", "gsl_sf_log", "libgsl.scm", "gsl_sf_log_1plusx", "libgsl.scm", "gsl_sf_log_1plusx_e", "libgsl.scm", "gsl_sf_log_1plusx_mx", "libgsl.scm", "gsl_sf_log_1plusx_mx_e", "libgsl.scm", "gsl_sf_log_abs", "libgsl.scm", "gsl_sf_log_abs_e", "libgsl.scm", "gsl_sf_log_e", "libgsl.scm", "gsl_sf_log_erfc", "libgsl.scm", "gsl_sf_log_erfc_e", "libgsl.scm", "gsl_sf_mathieu_Mc", "libgsl.scm", "gsl_sf_mathieu_Mc_array", "libgsl.scm", "gsl_sf_mathieu_Mc_e", "libgsl.scm", "gsl_sf_mathieu_Ms", "libgsl.scm", "gsl_sf_mathieu_Ms_array", "libgsl.scm", "gsl_sf_mathieu_Ms_e", "libgsl.scm", "gsl_sf_mathieu_a", "libgsl.scm", "gsl_sf_mathieu_a_array", "libgsl.scm", "gsl_sf_mathieu_a_coeff", "libgsl.scm", "gsl_sf_mathieu_a_e", "libgsl.scm", "gsl_sf_mathieu_alloc", "libgsl.scm", "gsl_sf_mathieu_b", "libgsl.scm", "gsl_sf_mathieu_b_array", "libgsl.scm", "gsl_sf_mathieu_b_coeff", "libgsl.scm", "gsl_sf_mathieu_b_e", "libgsl.scm", "gsl_sf_mathieu_ce", "libgsl.scm", "gsl_sf_mathieu_ce_array", "libgsl.scm", "gsl_sf_mathieu_ce_e", "libgsl.scm", "gsl_sf_mathieu_free", "libgsl.scm", "gsl_sf_mathieu_se", "libgsl.scm", "gsl_sf_mathieu_se_array", "libgsl.scm", "gsl_sf_mathieu_se_e", "libgsl.scm", "gsl_sf_multiply", "libgsl.scm", "gsl_sf_multiply_e", "libgsl.scm", "gsl_sf_multiply_err_e", "libgsl.scm", "gsl_sf_poch", "libgsl.scm", "gsl_sf_poch_e", "libgsl.scm", "gsl_sf_pochrel", "libgsl.scm", "gsl_sf_pochrel_e", "libgsl.scm", "gsl_sf_polar_to_rect", "libgsl.scm", "gsl_sf_pow_int", "libgsl.scm", "gsl_sf_pow_int_e", "libgsl.scm", "gsl_sf_psi", "libgsl.scm", "gsl_sf_psi_1", "libgsl.scm", "gsl_sf_psi_1_e", "libgsl.scm", "gsl_sf_psi_1_int", "libgsl.scm", "gsl_sf_psi_1_int_e", "libgsl.scm", "gsl_sf_psi_1piy", "libgsl.scm", "gsl_sf_psi_1piy_e", "libgsl.scm", "gsl_sf_psi_e", "libgsl.scm", "gsl_sf_psi_int", "libgsl.scm", "gsl_sf_psi_int_e", "libgsl.scm", "gsl_sf_psi_n", "libgsl.scm", "gsl_sf_psi_n_e", "libgsl.scm", "gsl_sf_rect_to_polar", "libgsl.scm", "gsl_sf_result.err", "libgsl.scm", "gsl_sf_result.make", "libgsl.scm", "gsl_sf_result.val", "libgsl.scm", "gsl_sf_result_e10.make", "libgsl.scm", "gsl_sf_result_smash_e", "libgsl.scm", "gsl_sf_sin", "libgsl.scm", "gsl_sf_sin_e", "libgsl.scm", "gsl_sf_sin_err_e", "libgsl.scm", "gsl_sf_sinc", "libgsl.scm", "gsl_sf_sinc_e", "libgsl.scm", "gsl_sf_synchrotron_1", "libgsl.scm", "gsl_sf_synchrotron_1_e", "libgsl.scm", "gsl_sf_synchrotron_2", "libgsl.scm", "gsl_sf_synchrotron_2_e", "libgsl.scm", "gsl_sf_taylorcoeff", "libgsl.scm", "gsl_sf_taylorcoeff_e", "libgsl.scm", "gsl_sf_transport_2", "libgsl.scm", "gsl_sf_transport_2_e", "libgsl.scm", "gsl_sf_transport_3", "libgsl.scm", "gsl_sf_transport_3_e", "libgsl.scm", "gsl_sf_transport_4", "libgsl.scm", "gsl_sf_transport_4_e", "libgsl.scm", "gsl_sf_transport_5", "libgsl.scm", "gsl_sf_transport_5_e", "libgsl.scm", "gsl_sf_zeta", "libgsl.scm", "gsl_sf_zeta_e", "libgsl.scm", "gsl_sf_zeta_int", "libgsl.scm", "gsl_sf_zeta_int_e", "libgsl.scm", "gsl_sf_zetam1", "libgsl.scm", "gsl_sf_zetam1_e", "libgsl.scm", "gsl_sf_zetam1_int", "libgsl.scm", "gsl_sf_zetam1_int_e", "libgsl.scm", "gsl_sort", "libgsl.scm", "gsl_sort2", "libgsl.scm", "gsl_sort_index", "libgsl.scm", "gsl_sort_largest", "libgsl.scm", "gsl_sort_largest_index", "libgsl.scm", "gsl_sort_smallest", "libgsl.scm", "gsl_sort_smallest_index", "libgsl.scm", "gsl_sort_vector", "libgsl.scm", "gsl_sort_vector2", "libgsl.scm", "gsl_sort_vector_index", "libgsl.scm", "gsl_sort_vector_largest", "libgsl.scm", "gsl_sort_vector_largest_index", "libgsl.scm", "gsl_sort_vector_smallest", "libgsl.scm", "gsl_sort_vector_smallest_index", "libgsl.scm", "gsl_spblas_dgemm", "libgsl.scm", "gsl_spblas_dgemv", "libgsl.scm", "gsl_spblas_scatter", "libgsl.scm", "gsl_splinalg_itersolve_alloc", "libgsl.scm", "gsl_splinalg_itersolve_free", "libgsl.scm", "gsl_splinalg_itersolve_gmres", "libgsl.scm", "gsl_splinalg_itersolve_iterate", "libgsl.scm", "gsl_splinalg_itersolve_name", "libgsl.scm", "gsl_splinalg_itersolve_normr", "libgsl.scm", "gsl_spline2d_alloc", "libgsl.scm", "gsl_spline2d_eval", "libgsl.scm", "gsl_spline2d_eval_deriv_x", "libgsl.scm", "gsl_spline2d_eval_deriv_x_e", "libgsl.scm", "gsl_spline2d_eval_deriv_xx", "libgsl.scm", "gsl_spline2d_eval_deriv_xx_e", "libgsl.scm", "gsl_spline2d_eval_deriv_xy", "libgsl.scm", "gsl_spline2d_eval_deriv_xy_e", "libgsl.scm", "gsl_spline2d_eval_deriv_y", "libgsl.scm", "gsl_spline2d_eval_deriv_y_e", "libgsl.scm", "gsl_spline2d_eval_deriv_yy", "libgsl.scm", "gsl_spline2d_eval_deriv_yy_e", "libgsl.scm", "gsl_spline2d_eval_e", "libgsl.scm", "gsl_spline2d_free", "libgsl.scm", "gsl_spline2d_get", "libgsl.scm", "gsl_spline2d_init", "libgsl.scm", "gsl_spline2d_min_size", "libgsl.scm", "gsl_spline2d_name", "libgsl.scm", "gsl_spline2d_set", "libgsl.scm", "gsl_spline_alloc", "libgsl.scm", "gsl_spline_eval", "libgsl.scm", "gsl_spline_eval_deriv", "libgsl.scm", "gsl_spline_eval_deriv2", "libgsl.scm", "gsl_spline_eval_deriv2_e", "libgsl.scm", "gsl_spline_eval_deriv_e", "libgsl.scm", "gsl_spline_eval_e", "libgsl.scm", "gsl_spline_eval_integ", "libgsl.scm", "gsl_spline_eval_integ_e", "libgsl.scm", "gsl_spline_free", "libgsl.scm", "gsl_spline_init", "libgsl.scm", "gsl_spline_min_size", "libgsl.scm", "gsl_spline_name", "libgsl.scm", "gsl_spmatrix_add", "libgsl.scm", "gsl_spmatrix_alloc", "libgsl.scm", "gsl_spmatrix_alloc_nzmax", "libgsl.scm", "gsl_spmatrix_compare_idx", "libgsl.scm", "gsl_spmatrix_compcol", "libgsl.scm", "gsl_spmatrix_cumsum", "libgsl.scm", "gsl_spmatrix_d2sp", "libgsl.scm", "gsl_spmatrix_equal", "libgsl.scm", "gsl_spmatrix_free", "libgsl.scm", "gsl_spmatrix_get", "libgsl.scm", "gsl_spmatrix_memcpy", "libgsl.scm", "gsl_spmatrix_minmax", "libgsl.scm", "gsl_spmatrix_nnz", "libgsl.scm", "gsl_spmatrix_realloc", "libgsl.scm", "gsl_spmatrix_scale", "libgsl.scm", "gsl_spmatrix_set", "libgsl.scm", "gsl_spmatrix_set_zero", "libgsl.scm", "gsl_spmatrix_sp2d", "libgsl.scm", "gsl_spmatrix_transpose_memcpy", "libgsl.scm", "gsl_stats_absdev", "libgsl.scm", "gsl_stats_absdev_m", "libgsl.scm", "gsl_stats_correlation", "libgsl.scm", "gsl_stats_covariance", "libgsl.scm", "gsl_stats_covariance_m", "libgsl.scm", "gsl_stats_kurtosis", "libgsl.scm", "gsl_stats_kurtosis_m_sd", "libgsl.scm", "gsl_stats_lag1_autocorrelation", "libgsl.scm", "gsl_stats_lag1_autocorrelation_m", "libgsl.scm", "gsl_stats_max", "libgsl.scm", "gsl_stats_max_index", "libgsl.scm", "gsl_stats_mean", "libgsl.scm", "gsl_stats_median_from_sorted_data", "libgsl.scm", "gsl_stats_min", "libgsl.scm", "gsl_stats_min_index", "libgsl.scm", "gsl_stats_minmax", "libgsl.scm", "gsl_stats_minmax_index", "libgsl.scm", "gsl_stats_pvariance", "libgsl.scm", "gsl_stats_quantile_from_sorted_data", "libgsl.scm", "gsl_stats_sd", "libgsl.scm", "gsl_stats_sd_m", "libgsl.scm", "gsl_stats_sd_with_fixed_mean", "libgsl.scm", "gsl_stats_skew", "libgsl.scm", "gsl_stats_skew_m_sd", "libgsl.scm", "gsl_stats_spearman", "libgsl.scm", "gsl_stats_tss", "libgsl.scm", "gsl_stats_tss_m", "libgsl.scm", "gsl_stats_ttest", "libgsl.scm", "gsl_stats_variance", "libgsl.scm", "gsl_stats_variance_m", "libgsl.scm", "gsl_stats_variance_with_fixed_mean", "libgsl.scm", "gsl_stats_wabsdev", "libgsl.scm", "gsl_stats_wabsdev_m", "libgsl.scm", "gsl_stats_wkurtosis", "libgsl.scm", "gsl_stats_wkurtosis_m_sd", "libgsl.scm", "gsl_stats_wmean", "libgsl.scm", "gsl_stats_wsd", "libgsl.scm", "gsl_stats_wsd_m", "libgsl.scm", "gsl_stats_wsd_with_fixed_mean", "libgsl.scm", "gsl_stats_wskew", "libgsl.scm", "gsl_stats_wskew_m_sd", "libgsl.scm", "gsl_stats_wtss", "libgsl.scm", "gsl_stats_wtss_m", "libgsl.scm", "gsl_stats_wvariance", "libgsl.scm", "gsl_stats_wvariance_m", "libgsl.scm", "gsl_stats_wvariance_with_fixed_mean", "libgsl.scm", "gsl_stream_printf", "libgsl.scm", "gsl_strerror", "libgsl.scm", "gsl_sum_levin_u_accel", "libgsl.scm", "gsl_sum_levin_u_alloc", "libgsl.scm", "gsl_sum_levin_u_free", "libgsl.scm", "gsl_sum_levin_u_minmax", "libgsl.scm", "gsl_sum_levin_u_step", "libgsl.scm", "gsl_sum_levin_utrunc_accel", "libgsl.scm", "gsl_sum_levin_utrunc_alloc", "libgsl.scm", "gsl_sum_levin_utrunc_free", "libgsl.scm", "gsl_sum_levin_utrunc_minmax", "libgsl.scm", "gsl_sum_levin_utrunc_step", "libgsl.scm", "gsl_vector->float-vector", "libgsl.scm", "gsl_vector_add", "libgsl.scm", "gsl_vector_add_constant", "libgsl.scm", "gsl_vector_alloc", "libgsl.scm", "gsl_vector_alloc_col_from_matrix", "libgsl.scm", "gsl_vector_alloc_from_vector", "libgsl.scm", "gsl_vector_alloc_row_from_matrix", "libgsl.scm", "gsl_vector_calloc", "libgsl.scm", "gsl_vector_complex_alloc", "libgsl.scm", "gsl_vector_complex_alloc_col_from_matrix", "libgsl.scm", "gsl_vector_complex_alloc_row_from_matrix", "libgsl.scm", "gsl_vector_complex_free", "libgsl.scm", "gsl_vector_complex_get", "libgsl.scm", "gsl_vector_const_ptr", "libgsl.scm", "gsl_vector_div", "libgsl.scm", "gsl_vector_equal", "libgsl.scm", "gsl_vector_fprintf", "libgsl.scm", "gsl_vector_fread", "libgsl.scm", "gsl_vector_free", "libgsl.scm", "gsl_vector_fscanf", "libgsl.scm", "gsl_vector_fwrite", "libgsl.scm", "gsl_vector_get", "libgsl.scm", "gsl_vector_isneg", "libgsl.scm", "gsl_vector_isnonneg", "libgsl.scm", "gsl_vector_isnull", "libgsl.scm", "gsl_vector_ispos", "libgsl.scm", "gsl_vector_max", "libgsl.scm", "gsl_vector_max_index", "libgsl.scm", "gsl_vector_memcpy", "libgsl.scm", "gsl_vector_min", "libgsl.scm", "gsl_vector_min_index", "libgsl.scm", "gsl_vector_minmax", "libgsl.scm", "gsl_vector_minmax_index", "libgsl.scm", "gsl_vector_mul", "libgsl.scm", "gsl_vector_ptr", "libgsl.scm", "gsl_vector_reverse", "libgsl.scm", "gsl_vector_scale", "libgsl.scm", "gsl_vector_set", "libgsl.scm", "gsl_vector_set_all", "libgsl.scm", "gsl_vector_set_basis", "libgsl.scm", "gsl_vector_set_zero", "libgsl.scm", "gsl_vector_sub", "libgsl.scm", "gsl_vector_swap", "libgsl.scm", "gsl_vector_swap_elements", "libgsl.scm", "gsl_version", "libgsl.scm", "gsl_wavelet2d_nstransform", "libgsl.scm", "gsl_wavelet2d_nstransform_forward", "libgsl.scm", "gsl_wavelet2d_nstransform_inverse", "libgsl.scm", "gsl_wavelet2d_nstransform_matrix", "libgsl.scm", "gsl_wavelet2d_nstransform_matrix_forward", "libgsl.scm", "gsl_wavelet2d_nstransform_matrix_inverse", "libgsl.scm", "gsl_wavelet2d_transform", "libgsl.scm", "gsl_wavelet2d_transform_forward", "libgsl.scm", "gsl_wavelet2d_transform_inverse", "libgsl.scm", "gsl_wavelet2d_transform_matrix", "libgsl.scm", "gsl_wavelet2d_transform_matrix_forward", "libgsl.scm", "gsl_wavelet2d_transform_matrix_inverse", "libgsl.scm", "gsl_wavelet_alloc", "libgsl.scm", "gsl_wavelet_backward", "libgsl.scm", "gsl_wavelet_bspline", "libgsl.scm", "gsl_wavelet_bspline_centered", "libgsl.scm", "gsl_wavelet_daubechies", "libgsl.scm", "gsl_wavelet_daubechies_centered", "libgsl.scm", "gsl_wavelet_forward", "libgsl.scm", "gsl_wavelet_free", "libgsl.scm", "gsl_wavelet_haar", "libgsl.scm", "gsl_wavelet_haar_centered", "libgsl.scm", "gsl_wavelet_name", "libgsl.scm", "gsl_wavelet_transform", "libgsl.scm", "gsl_wavelet_transform_forward", "libgsl.scm", "gsl_wavelet_transform_inverse", "libgsl.scm", "gsl_wavelet_workspace_alloc", "libgsl.scm", "gsl_wavelet_workspace_free", "libgsl.scm", "hairy-woodpecker", "animals.scm", "hammondoid", "clm-ins.scm", "hammonds-flycatcher", "animals.scm", "handsome-trig", "animals.scm", "hard-clipped", "dsp.scm", "harmonicizer", "dsp.scm", "hash-table->alist", "stuff.scm", "hello-dentist", "examp.scm", "henslows-sparrow", "animals.scm", "hermit-thrush", "animals.scm", "hermite", "numerics.scm", "hermite-polynomial", "numerics.scm", "hook-member", "hooks.scm", "hostent.h_addrtype", "libc.scm", "hostent.h_aliases", "libc.scm", "hostent.h_length", "libc.scm", "hostent.h_name", "libc.scm", "house-finch", "animals.scm", "house-sparrow-1", "animals.scm", "html", "index.scm", "html-lint", "lint.scm", "htonl", "libc.scm", "htons", "libc.scm", "huttons-vireo", "animals.scm", "hypot", "libm.scm", "hz->2pi", "dsp.scm", "ilogb", "libm.scm", "implementation-name", "r7rs.scm", "implementation-version", "r7rs.scm", "inca-dove-1", "animals.scm", "inca-dove-2", "animals.scm", "index-if", "stuff.scm", "indexable?", "stuff.scm", "indri", "animals.scm", "inexact", "r7rs.scm", "init-with-sound", "ws.scm", "initial-direction", "dlocsig.scm", "initstate", "libc.scm", "input-port-open?", "r7rs.scm", "insert-channel", "extensions.scm", "int_to_float32", "binary-io.scm", "int_to_float64", "binary-io.scm", "integrate-envelope", "env.scm", "interaction-environment", "r7rs.scm", "intersection", "stuff.scm", "inverse-chebyshev-prototype", "analog-filter.scm", "inverse-integrate", "dsp.scm", "invert-filter", "dsp.scm", "invert-matrix", "dsp.scm", "io-read-string", "binary-io.scm", "io-write-string", "binary-io.scm", "iota", "stuff.scm", "isalnum", "libc.scm", "isalpha", "libc.scm", "isatty", "libc.scm", "iscntrl", "libc.scm", "isdigit", "libc.scm", "isfinite", "libm.scm", "isgraph", "libc.scm", "isinf", "libm.scm", "islower", "libc.scm", "isnan", "libm.scm", "isnormal", "libm.scm", "isprint", "libc.scm", "ispunct", "libc.scm", "isspace", "libc.scm", "isupper", "libc.scm", "isxdigit", "libc.scm", "izcos", "generators.scm", "izcos?", "generators.scm", "j0", "libm.scm", "j0evencos", "generators.scm", "j0evencos?", "generators.scm", "j0j1cos", "generators.scm", "j0j1cos?", "generators.scm", "j1", "libm.scm", "j2cos", "generators.scm", "j2cos?", "generators.scm", "jc-reverb", "jcrev.scm", "jettable", "prc95.scm", "jiffies-per-second", "r7rs.scm", "jjcos", "generators.scm", "jjcos?", "generators.scm", "jl-reverb", "clm-ins.scm", "jncos", "generators.scm", "jncos?", "generators.scm", "jpcos", "generators.scm", "jpcos?", "generators.scm", "jycos", "generators.scm", "jycos?", "generators.scm", "k2cos", "generators.scm", "k2cos?", "generators.scm", "k2sin", "generators.scm", "k2sin?", "generators.scm", "k2ssb", "generators.scm", "k2ssb?", "generators.scm", "k3sin", "generators.scm", "k3sin?", "generators.scm", "kalman-filter-channel", "dsp.scm", "kill", "libc.scm", "killdeer", "animals.scm", "kirtlands-warbler", "animals.scm", "knudsens-frog", "animals.scm", "krksin", "generators.scm", "krksin?", "generators.scm", "labs", "libc.scm", "lag?", "snddiff.scm", "laguerre", "numerics.scm", "laguerre-polynomial", "numerics.scm", "last", "dlocsig.scm", "lbj-piano", "clm-ins.scm", "ldb", "stuff.scm", "ldexp", "libm.scm", "ldiv", "libc.scm", "least-bittern", "animals.scm", "least-flycatcher", "animals.scm", "legendre", "numerics.scm", "legendre-polynomial", "numerics.scm", "lesser-nighthawk", "animals.scm", "libc.scm", "libc.scm", "libdl.scm", "libdl.scm", "libgdbm.scm", "libgdbm.scm", "libm.scm", "libm.scm", "linear-src-channel", "dsp.scm", "linearize", "stuff.scm", "lineto", "musglyphs.scm", "link", "libc.scm", "linnaeus-cicada", "animals.scm", "lint", "lint.scm", "lip", "prc95.scm", "lip-set-freq", "prc95.scm", "list-copy", "r7rs.scm", "list??", "dlocsig.scm", "listen", "libc.scm", "literal-3d", "dlocsig.scm", "literal-points", "dlocsig.scm", "literal-polar", "dlocsig.scm", "literal-render", "dlocsig.scm", "little-grass-frog", "animals.scm", "llabs", "libc.scm", "llrint", "libm.scm", "llround", "libm.scm", "local-data", "spokenword.scm", "local-peak", "spokenword.scm", "local-rms", "spokenword.scm", "local-smooth", "spokenword.scm", "localeconv", "libc.scm", "locate-zero", "examp.scm", "lockf", "libc.scm", "log-all-of", "stuff.scm", "log-any-of", "stuff.scm", "log-n-of", "stuff.scm", "log-none-of", "stuff.scm", "log10", "dsp.scm", "log1p", "libm.scm", "log2", "libm.scm", "logeqv", "stuff.scm", "loggerhead-shrike-1", "animals.scm", "loggerhead-shrike-2", "animals.scm", "lognand", "stuff.scm", "lognor", "stuff.scm", "long-eared-owl", "animals.scm", "long-spurred-meadow-katydid", "animals.scm", "lpc-coeffs", "dsp.scm", "lpc-predict", "dsp.scm", "lseek", "libc.scm", "lstat", "libc.scm", "lucys-warbler", "animals.scm", "lutish", "generators.scm", "lyric-cicada", "animals.scm", "macgillivrays-warbler", "animals.scm", "machine-name", "r7rs.scm", "machine1", "generators.scm", "magnolia-warbler", "animals.scm", "make-a-even", "dlocsig.scm", "make-a-odd", "dlocsig.scm", "make-abcos", "generators.scm", "make-absin", "generators.scm", "make-adjustable-oscil", "generators.scm", "make-adjustable-sawtooth-wave", "generators.scm", "make-adjustable-square-wave", "generators.scm", "make-adjustable-triangle-wave", "generators.scm", "make-array", "maxf.scm", "make-asyfm", "generators.scm", "make-bandpass", "dsp.scm", "make-bandstop", "dsp.scm", "make-bess", "generators.scm", "make-bessel-bandpass", "analog-filter.scm", "make-bessel-bandstop", "analog-filter.scm", "make-bessel-highpass", "analog-filter.scm", "make-bessel-lowpass", "analog-filter.scm", "make-bezier-1", "musglyphs.scm", "make-bezier-path", "dlocsig.scm", "make-biquad", "strad.scm", "make-birds", "bird.scm", "make-blackman", "generators.scm", "make-bowtable", "prc95.scm", "make-box-type", "r7rs.scm", "make-brown-noise", "generators.scm", "make-butter-band-pass", "dsp.scm", "make-butter-band-reject", "dsp.scm", "make-butter-bp", "dsp.scm", "make-butter-bs", "dsp.scm", "make-butter-high-pass", "dsp.scm", "make-butter-hp", "dsp.scm", "make-butter-low-pass", "dsp.scm", "make-butter-lp", "dsp.scm", "make-butterworth-bandpass", "analog-filter.scm", "make-butterworth-bandstop", "analog-filter.scm", "make-butterworth-highpass", "analog-filter.scm", "make-butterworth-lowpass", "analog-filter.scm", "make-chebyshev-bandpass", "analog-filter.scm", "make-chebyshev-bandstop", "analog-filter.scm", "make-chebyshev-highpass", "analog-filter.scm", "make-chebyshev-lowpass", "analog-filter.scm", "make-circular-list", "stuff.scm", "make-closed-path", "dlocsig.scm", "make-complete-iterator", "stuff.scm", "make-db-env", "grani.scm", "make-dblsum", "generators.scm", "make-dc-block", "prc95.scm", "make-delayl", "prc95.scm", "make-differentiator", "dsp.scm", "make-directory-iterator", "stuff.scm", "make-dlocsig", "dlocsig.scm", "make-elliptic-bandpass", "analog-filter.scm", "make-elliptic-bandstop", "analog-filter.scm", "make-elliptic-highpass", "analog-filter.scm", "make-elliptic-lowpass", "analog-filter.scm", "make-eoddcos", "generators.scm", "make-ercos", "generators.scm", "make-erssb", "generators.scm", "make-exponentially-weighted-moving-average", "generators.scm", "make-flocsig", "generators.scm", "make-fm-noise", "noise.scm", "make-fm2", "clm-ins.scm", "make-fmssb", "generators.scm", "make-gr-env", "grani.scm", "make-green-noise", "generators.scm", "make-green-noise-interp", "generators.scm", "make-group", "dlocsig.scm", "make-highpass", "dsp.scm", "make-hilbert-transform", "dsp.scm", "make-iir-band-pass-2", "dsp.scm", "make-iir-band-stop-2", "dsp.scm", "make-iir-high-pass-2", "dsp.scm", "make-iir-low-pass-2", "dsp.scm", "make-inverse-chebyshev-bandpass", "analog-filter.scm", "make-inverse-chebyshev-bandstop", "analog-filter.scm", "make-inverse-chebyshev-highpass", "analog-filter.scm", "make-inverse-chebyshev-lowpass", "analog-filter.scm", "make-izcos", "generators.scm", "make-j0evencos", "generators.scm", "make-j0j1cos", "generators.scm", "make-j2cos", "generators.scm", "make-jjcos", "generators.scm", "make-jncos", "generators.scm", "make-jpcos", "generators.scm", "make-jycos", "generators.scm", "make-k2cos", "generators.scm", "make-k2sin", "generators.scm", "make-k2ssb", "generators.scm", "make-k3sin", "generators.scm", "make-krksin", "generators.scm", "make-list-1", "dlocsig.scm", "make-literal-path", "dlocsig.scm", "make-literal-polar-path", "dlocsig.scm", "make-lowpass", "dsp.scm", "make-method", "mockery.scm", "make-moog", "moog.scm", "make-moog-filter", "moog.scm", "make-moving-autocorrelation", "generators.scm", "make-moving-fft", "generators.scm", "make-moving-length", "generators.scm", "make-moving-pitch", "generators.scm", "make-moving-rms", "generators.scm", "make-moving-scentroid", "generators.scm", "make-moving-spectrum", "generators.scm", "make-moving-sum", "generators.scm", "make-moving-variance", "generators.scm", "make-n1cos", "generators.scm", "make-nchoosekcos", "generators.scm", "make-ncos2", "generators.scm", "make-ncos4", "generators.scm", "make-nkssb", "generators.scm", "make-noddcos", "generators.scm", "make-noddsin", "generators.scm", "make-noddssb", "generators.scm", "make-noid", "generators.scm", "make-notch-frequency-response", "dsp.scm", "make-npcos", "generators.scm", "make-nrcos", "generators.scm", "make-nrsin", "generators.scm", "make-nrssb", "generators.scm", "make-nsincos", "generators.scm", "make-nssb", "generators.scm", "make-nxy1cos", "generators.scm", "make-nxy1sin", "generators.scm", "make-nxycos", "generators.scm", "make-nxysin", "generators.scm", "make-object", "mockery.scm", "make-octaves-env", "grani.scm", "make-onep", "prc95.scm", "make-onezero", "prc95.scm", "make-open-bezier-path", "dlocsig.scm", "make-parameter", "r7rs.scm", "make-path", "dlocsig.scm", "make-peaking-2", "dsp.scm", "make-pink-noise", "generators.scm", "make-polar-path", "dlocsig.scm", "make-polygon", "musglyphs.scm", "make-polyoid", "generators.scm", "make-power-env", "env.scm", "make-promise", "r7rs.scm", "make-pvocoder", "pvoc.scm", "make-r2k!cos", "generators.scm", "make-r2k2cos", "generators.scm", "make-ramp", "examp.scm", "make-rcos", "generators.scm", "make-reed", "prc95.scm", "make-rk!cos", "generators.scm", "make-rk!ssb", "generators.scm", "make-rkcos", "generators.scm", "make-rkoddssb", "generators.scm", "make-rksin", "generators.scm", "make-rkssb", "generators.scm", "make-rmsgain", "clm-ins.scm", "make-round-interp", "generators.scm", "make-rssb", "generators.scm", "make-rxycos", "generators.scm", "make-rxysin", "generators.scm", "make-safe-rxycos", "generators.scm", "make-savitzky-golay-filter", "dsp.scm", "make-selection", "selection.scm", "make-semitones-env", "grani.scm", "make-sinc-train", "generators.scm", "make-sound-interp", "examp.scm", "make-speaker-config", "dlocsig.scm", "make-spencer-filter", "dsp.scm", "make-spiral-path", "dlocsig.scm", "make-ssb-fm", "clm-ins.scm", "make-table-lookup-with-env", "generators.scm", "make-tanhsin", "generators.scm", "make-unmoving-sum", "generators.scm", "make-volterra-filter", "dsp.scm", "make-wave-train-with-env", "generators.scm", "make-waveshape", "generators.scm", "make-weighted-moving-average", "generators.scm", "make-zipper", "zip.scm", "malloc", "libc.scm", "map-envelopes", "env.scm", "map-sound-files", "extensions.scm", "maraca", "maraca.scm", "mark-click-info", "marks.scm", "mark-explode", "marks.scm", "mark-in", "spokenword.scm", "mark-loops", "examp.scm", "mark-name->id", "marks.scm", "mark-out", "spokenword.scm", "marsh-meadow-grasshopper", "animals.scm", "match-sound-files", "extensions.scm", "matrix-solve", "dsp.scm", "max-envelope", "env.scm", "maxfilter", "maxf.scm", "member?", "stuff.scm", "memchr", "libc.scm", "memcmp", "libc.scm", "memcpy", "libc.scm", "memmove", "libc.scm", "memset", "libc.scm", "merge-hash-tables", "stuff.scm", "metal", "clm-ins.scm", "min-envelope", "env.scm", "mirror-path", "dlocsig.scm", "mix->float-vector", "mix.scm", "mix-channel", "extensions.scm", "mix-click-info", "mix.scm", "mix-click-sets-amp", "mix.scm", "mix-maxamp", "mix.scm", "mix-name->id", "mix.scm", "mix-notelists", "ws.scm", "mix-sound", "mix.scm", "mixes-length", "mix.scm", "mixes-maxamp", "mix.scm", "mkdir", "libc.scm", "mkfifo", "libc.scm", "mknod", "libc.scm", "mkstemp", "libc.scm", "mktemp", "libc.scm", "mktime", "libc.scm", "mock->string", "mockery.scm", "mockery.scm", "mockery.scm", "modf", "libm.scm", "mono->stereo", "extensions.scm", "mono-files->stereo", "extensions.scm", "montezuma-quail", "animals.scm", "moog-filter", "moog.scm", "moog-filter-saturated", "moog.scm", "moog-frequency", "moog.scm", "moog?", "moog.scm", "mosquito", "animals.scm", "mountain-quail", "animals.scm", "mourning-dove", "animals.scm", "mouse-drag-envelope", "enved.scm", "mouse-press-envelope", "enved.scm", "mouse-release-envelope", "enved.scm", "move-mixes", "mix.scm", "move-syncd-marks", "marks.scm", "moveto", "musglyphs.scm", "moving-autocorrelation", "generators.scm", "moving-autocorrelation?", "generators.scm", "moving-fft", "generators.scm", "moving-fft?", "generators.scm", "moving-formant", "examp.scm", "moving-length", "generators.scm", "moving-length?", "generators.scm", "moving-pitch", "generators.scm", "moving-pitch?", "generators.scm", "moving-rms", "generators.scm", "moving-rms?", "generators.scm", "moving-scentroid", "generators.scm", "moving-scentroid?", "generators.scm", "moving-spectrum", "generators.scm", "moving-spectrum?", "generators.scm", "moving-sum", "generators.scm", "moving-sum?", "generators.scm", "moving-variance", "generators.scm", "moving-variance?", "generators.scm", "mpg", "examp.scm", "multi-expt-env", "generators.scm", "multiply-envelopes", "env.scm", "music-font", "musglyphs.scm", "mvmfilt", "maxf.scm", "n-choose-k", "stuff.scm", "n1cos", "generators.scm", "n1cos?", "generators.scm", "nan", "libm.scm", "nanosleep", "libc.scm", "narrow-winged-tree-cricket", "animals.scm", "nashville-warbler", "animals.scm", "nb", "nb.scm", "nchoosekcos", "generators.scm", "nchoosekcos?", "generators.scm", "ncos2", "generators.scm", "ncos2?", "generators.scm", "ncos4", "generators.scm", "nearbyint", "libm.scm", "nearest-point", "dlocsig.scm", "netent.n_addrtype", "libc.scm", "netent.n_aliases", "libc.scm", "netent.n_name", "libc.scm", "netent.n_net", "libc.scm", "next-peak", "examp.scm", "next-phrase", "spokenword.scm", "nextafter", "libm.scm", "nexttoward", "libm.scm", "ninth", "stuff.scm", "nkssb", "generators.scm", "nkssb-interp", "generators.scm", "nkssb?", "generators.scm", "nkssber", "generators.scm", "noddcos", "generators.scm", "noddcos?", "generators.scm", "noddsin", "generators.scm", "noddsin?", "generators.scm", "noddssb", "generators.scm", "noddssb?", "generators.scm", "noid", "generators.scm", "noid?", "generators.scm", "nonce", "stuff.scm", "normalize-envelope", "env.scm", "normalize-sound", "extensions.scm", "normalized-mix", "extensions.scm", "northern-beardless-tyrannulet", "animals.scm", "northern-goshawk", "animals.scm", "northern-leopard-frog-1", "animals.scm", "northern-leopard-frog-2", "animals.scm", "not-fitted", "dlocsig.scm", "not-parsed", "dlocsig.scm", "not-rendered", "dlocsig.scm", "not-transformed", "dlocsig.scm", "notch-channel", "dsp.scm", "notch-filter", "examp.scm", "notch-selection", "dsp.scm", "notch-sound", "dsp.scm", "note-data->pitch", "musglyphs.scm", "npcos", "generators.scm", "npcos?", "generators.scm", "nrcos", "generators.scm", "nrcos->polywave", "animals.scm", "nrcos-set-scaler", "generators.scm", "nrcos?", "generators.scm", "nrev", "clm-ins.scm", "nrsin?", "generators.scm", "nrssb", "generators.scm", "nrssb-interp", "generators.scm", "nrssb?", "generators.scm", "nsincos", "generators.scm", "nsincos?", "generators.scm", "nssb", "generators.scm", "nssb?", "generators.scm", "ntohl", "libc.scm", "ntohs", "libc.scm", "nxy1cos", "generators.scm", "nxy1cos?", "generators.scm", "nxy1sin", "generators.scm", "nxy1sin?", "generators.scm", "nxycos", "generators.scm", "nxycos?", "generators.scm", "nxysin", "generators.scm", "nxysin?", "generators.scm", "oak-titmouse", "animals.scm", "oak-toad", "animals.scm", "oboish", "generators.scm", "octaves-envelope", "grani.scm", "offset-channel", "extensions.scm", "offset-sound", "extensions.scm", "olive-sided-flycatcher", "animals.scm", "one-turn-is", "dlocsig.scm", "open", "libc.scm", "open-binary-input-file", "r7rs.scm", "open-binary-output-file", "r7rs.scm", "open-input-bytevector", "r7rs.scm", "open-next-file-in-directory", "examp.scm", "open-output-bytevector", "r7rs.scm", "opendir", "libc.scm", "orange-crowned-warbler", "animals.scm", "organish", "generators.scm", "ornate-chorus-frog", "animals.scm", "os-type", "r7rs.scm", "os-version", "r7rs.scm", "osc-formants", "examp.scm", "outlet-member", "mockery.scm", "output-port-open?", "r7rs.scm", "output-type", "musglyphs.scm", "overlay-rms-env", "draw.scm", "overlay-sounds", "draw.scm", "ow!", "stuff.scm", "owlets", "stuff.scm", "p", "piano.scm", "pacific-chorus-frog", "animals.scm", "pacific-slope-flycatcher", "animals.scm", "pad-marks", "marks.scm", "pad-sound", "extensions.scm", "pan-mix", "mix.scm", "pan-mix-float-vector", "mix.scm", "pan-mix-region", "mix.scm", "pan-mix-selection", "mix.scm", "pareto-distribution", "dsp.scm", "parse-cartesian-coordinates", "dlocsig.scm", "parse-polar-coordinates", "dlocsig.scm", "partials->waveshape", "generators.scm", "passwd.pw_dir", "libc.scm", "passwd.pw_gecos", "libc.scm", "passwd.pw_gid", "libc.scm", "passwd.pw_name", "libc.scm", "passwd.pw_passwd", "libc.scm", "passwd.pw_shell", "libc.scm", "passwd.pw_uid", "libc.scm", "path-rt", "dlocsig.scm", "path-rv", "dlocsig.scm", "path-rx", "dlocsig.scm", "path-ry", "dlocsig.scm", "path-rz", "dlocsig.scm", "path-time", "dlocsig.scm", "path-tt", "dlocsig.scm", "path-tx", "dlocsig.scm", "path-ty", "dlocsig.scm", "path-tz", "dlocsig.scm", "path-x", "dlocsig.scm", "path-y", "dlocsig.scm", "path-z", "dlocsig.scm", "pathconf", "libc.scm", "pause", "libc.scm", "pclose", "libc.scm", "peek-u8", "r7rs.scm", "periodogram", "dsp.scm", "perror", "libc.scm", "phainopepla", "animals.scm", "philadelphia-vireo", "animals.scm", "phrase-start?", "spokenword.scm", "phrase?", "spokenword.scm", "pianoy", "generators.scm", "pianoy1", "generators.scm", "pianoy2", "generators.scm", "pileated-woodpecker", "animals.scm", "pine-tree-cricket", "animals.scm", "pine-warbler", "animals.scm", "pinewoods-tree-frog", "animals.scm", "pink-noise?", "generators.scm", "pins", "clm-ins.scm", "pinyon-jay", "animals.scm", "pipe", "libc.scm", "place-sound", "examp.scm", "plain-chacalaca", "animals.scm", "plains-spadefoot", "animals.scm", "play-ac3", "examp.scm", "play-between-marks", "marks.scm", "play-mixes", "mix.scm", "play-often", "play.scm", "play-preview", "spokenword.scm", "play-region-forever", "play.scm", "play-sine", "play.scm", "play-sines", "play.scm", "play-syncd-marks", "marks.scm", "play-until-c-g", "play.scm", "play-with-amps", "play.scm", "play-with-envs", "enved.scm", "plgndr", "numerics.scm", "pluck", "clm-ins.scm", "plucky", "prc95.scm", "plumbeous-vireo-1", "animals.scm", "plumbeous-vireo-2", "animals.scm", "poly*", "poly.scm", "poly+", "poly.scm", "poly-as-vector*", "poly.scm", "poly-as-vector+", "poly.scm", "poly-as-vector-derivative", "poly.scm", "poly-as-vector-discriminant", "poly.scm", "poly-as-vector-eval", "poly.scm", "poly-as-vector-gcd", "poly.scm", "poly-as-vector-reduce", "poly.scm", "poly-as-vector-resultant", "poly.scm", "poly-as-vector-roots", "poly.scm", "poly-as-vector/", "poly.scm", "poly-derivative", "poly.scm", "poly-discriminant", "poly.scm", "poly-gcd", "poly.scm", "poly-reduce", "poly.scm", "poly-resultant", "poly.scm", "poly-roots", "poly.scm", "poly/", "poly.scm", "polyoid", "generators.scm", "polyoid-env", "generators.scm", "polyoid-tn", "generators.scm", "polyoid-un", "generators.scm", "polyoid?", "generators.scm", "popen", "libc.scm", "port?", "r7rs.scm", "posix_fadvise", "libc.scm", "posix_fallocate", "libc.scm", "pow", "libm.scm", "powenv-channel", "env.scm", "power-env", "env.scm", "power-env-channel", "env.scm", "power-set", "stuff.scm", "pp", "write.scm", "pqw", "clm-ins.scm", "pqw-vox", "clm-ins.scm", "pread", "libc.scm", "pretty-print", "write.scm", "previous-phrase", "spokenword.scm", "protoent.p_aliases", "libc.scm", "protoent.p_name", "libc.scm", "protoent.p_proto", "libc.scm", "prototype->highpass", "analog-filter.scm", "prune-db", "nb.scm", "pulse-voice", "examp.scm", "purple-finch", "animals.scm", "putc", "libc.scm", "putchar", "libc.scm", "putenv", "libc.scm", "puts", "libc.scm", "pvoc", "pvoc.scm", "pvocoder", "pvoc.scm", "pwrite", "libc.scm", "pygmy-nuthatch", "animals.scm", "r2k!cos", "generators.scm", "r2k!cos?", "generators.scm", "r2k2cos", "generators.scm", "r2k2cos-norm", "generators.scm", "r2k2cos?", "generators.scm", "r7rs-file-exists?", "r7rs.scm", "r7rs-make-hash-table", "r7rs.scm", "r7rs-string-copy", "r7rs.scm", "r7rs-string-fill!", "r7rs.scm", "r7rs.scm", "r7rs.scm", "raise", "r7rs.scm", "raise-continuable", "r7rs.scm", "raised-cosine", "grani.scm", "ramp", "examp.scm", "ramp-expt", "extensions.scm", "ramp-squared", "extensions.scm", "rcos", "generators.scm", "rcos?", "generators.scm", "reactive-lambda*", "stuff.scm", "reactive-let", "stuff.scm", "reactive-let*", "stuff.scm", "read-aif-header", "binary-io.scm", "read-ascii", "examp.scm", "read-au-header", "binary-io.scm", "read-bfloat32", "binary-io.scm", "read-bfloat64", "binary-io.scm", "read-bfloat80->int", "binary-io.scm", "read-bint16", "binary-io.scm", "read-bint32", "binary-io.scm", "read-bint64", "binary-io.scm", "read-bytevector", "r7rs.scm", "read-bytevector!", "r7rs.scm", "read-chars", "binary-io.scm", "read-error?", "r7rs.scm", "read-flac", "examp.scm", "read-lfloat32", "binary-io.scm", "read-lfloat64", "binary-io.scm", "read-lint16", "binary-io.scm", "read-lint32", "binary-io.scm", "read-lint64", "binary-io.scm", "read-ogg", "examp.scm", "read-speex", "examp.scm", "read-u8", "r7rs.scm", "read_dir", "libc.scm", "realloc", "libc.scm", "realpath", "libc.scm", "recv", "libc.scm", "recvfrom", "libc.scm", "recvmsg", "libc.scm", "red-breasted-nuthatch", "animals.scm", "red-eyed-vireo", "animals.scm", "red-shouldered-hawk", "animals.scm", "red-spotted-toad", "animals.scm", "redo-channel", "extensions.scm", "reedtable", "prc95.scm", "reflective-let", "stuff.scm", "reflective-probe", "stuff.scm", "region-play-list", "examp.scm", "region-play-sequence", "examp.scm", "region-rms", "examp.scm", "remove", "libc.scm", "remove-clicks", "examp.scm", "remove-if", "stuff.scm", "remove-pops", "clean.scm", "remove-single-sample-clicks", "clean.scm", "remquo", "libm.scm", "rename", "libc.scm", "render-path", "dlocsig.scm", "repeat-envelope", "env.scm", "replace-with-selection", "selection.scm", "report-mark-names", "marks.scm", "reset-all-hooks", "hooks.scm", "reset-fit", "dlocsig.scm", "reset-rendering", "dlocsig.scm", "reset-transformation", "dlocsig.scm", "resflt", "clm-ins.scm", "reson", "clm-ins.scm", "reverse-by-blocks", "examp.scm", "reverse-envelope", "env.scm", "reverse-within-blocks", "examp.scm", "rewind", "libc.scm", "rewinddir", "libc.scm", "rhodey", "clm-ins.scm", "ring-mod", "examp.scm", "rint", "libm.scm", "river-frog", "animals.scm", "rk!cos", "generators.scm", "rk!cos?", "generators.scm", "rk!ssb", "generators.scm", "rk!ssb?", "generators.scm", "rkcos", "generators.scm", "rkcos?", "generators.scm", "rkoddssb", "generators.scm", "rkoddssb?", "generators.scm", "rksin", "generators.scm", "rksin?", "generators.scm", "rkssb", "generators.scm", "rkssb?", "generators.scm", "rlimit.make", "libc.scm", "rlimit.rlim_cur", "libc.scm", "rlimit.rlim_max", "libc.scm", "rlineto", "musglyphs.scm", "rmdir", "libc.scm", "rmoveto", "musglyphs.scm", "rms", "clm-ins.scm", "rms-envelope", "env.scm", "rotate-path", "dlocsig.scm", "rotate-phase", "dsp.scm", "round-interp", "generators.scm", "round-interp?", "generators.scm", "rssb", "generators.scm", "rssb-interp", "generators.scm", "rssb?", "generators.scm", "rubber-sound", "rubber.scm", "ruby-crowned-kinglet", "animals.scm", "ruffed-grouse", "animals.scm", "run-with-fm-and-pm", "generators.scm", "rusage.make", "libc.scm", "rusage.ru_inblock", "libc.scm", "rusage.ru_majflt", "libc.scm", "rusage.ru_maxrss", "libc.scm", "rusage.ru_minflt", "libc.scm", "rusage.ru_nivcsw", "libc.scm", "rusage.ru_nvcsw", "libc.scm", "rusage.ru_oublock", "libc.scm", "rusage.ru_stime", "libc.scm", "rusage.ru_utime", "libc.scm", "rxycos", "generators.scm", "rxycos?", "generators.scm", "rxysin", "generators.scm", "rxysin?", "generators.scm", "safe-count-if", "stuff.scm", "safe-find-if", "stuff.scm", "safe-rxycos", "generators.scm", "safe-rxycos?", "generators.scm", "safe-srate", "zip.scm", "sage-sparrow", "animals.scm", "samples-via-colormap", "draw.scm", "sandhill-crane", "animals.scm", "savannah-sparrow", "animals.scm", "save-mark-properties", "marks.scm", "says-phoebe", "animals.scm", "scalbln", "libm.scm", "scalbn", "libm.scm", "scale-envelope", "env.scm", "scale-mixes", "mix.scm", "scale-path", "dlocsig.scm", "scale-sound", "extensions.scm", "scale-tempo", "mix.scm", "scaled-quail", "animals.scm", "scentroid", "dsp.scm", "scotts-oriole", "animals.scm", "scramble-channel", "examp.scm", "scramble-channels", "examp.scm", "scratch", "clm-ins.scm", "scrub-euphonia", "animals.scm", "search-for-click", "examp.scm", "second", "stuff.scm", "secs->samples", "spokenword.scm", "selection-members", "selection.scm", "selection-rms", "examp.scm", "semitones-envelope", "grani.scm", "send", "libc.scm", "sendmsg", "libc.scm", "sendto", "libc.scm", "sequence->string", "stuff.scm", "sequences->list", "stuff.scm", "servent.s_aliases", "libc.scm", "servent.s_name", "libc.scm", "servent.s_port", "libc.scm", "servent.s_proto", "libc.scm", "set-box!", "r7rs.scm", "set-coeffs", "maxf.scm", "set-gain", "prc95.scm", "set-mixes-tag-y", "mix.scm", "set-pole", "prc95.scm", "set-speaker-configuration", "dlocsig.scm", "set_errno", "libc.scm", "setbuf", "libc.scm", "setenv", "libc.scm", "setf-aref", "jcvoi.scm", "setgid", "libc.scm", "sethostent", "libc.scm", "setlinebuf", "libc.scm", "setlocale", "libc.scm", "setnetent", "libc.scm", "setpgid", "libc.scm", "setpriority", "libc.scm", "setprotoent", "libc.scm", "setpwent", "libc.scm", "setrlimit", "libc.scm", "setservent", "libc.scm", "setsid", "libc.scm", "setsockopt", "libc.scm", "setstate", "libc.scm", "setuid", "libc.scm", "setvbuf", "libc.scm", "seventh", "stuff.scm", "shift-channel-pitch", "dsp.scm", "show-digits-of-pi-starting-at-digit", "numerics.scm", "show-mins", "peak-phases.scm", "showall", "peak-phases.scm", "showdiff", "peak-phases.scm", "showodd", "peak-phases.scm", "showphases", "peak-phases.scm", "shutdown", "libc.scm", "sigaction", "libc.scm", "sigaction.make", "libc.scm", "sigaction.sa_flags", "libc.scm", "sigaction.sa_handler", "libc.scm", "sigaction.sa_mask", "libc.scm", "sigaction.set_sa_flags", "libc.scm", "sigaction.set_sa_handler", "libc.scm", "sigaddset", "libc.scm", "sigdelset", "libc.scm", "sigemptyset", "libc.scm", "sigfillset", "libc.scm", "siginfo.make", "libc.scm", "siginfo.si_addr", "libc.scm", "siginfo.si_band", "libc.scm", "siginfo.si_code", "libc.scm", "siginfo.si_errno", "libc.scm", "siginfo.si_fd", "libc.scm", "siginfo.si_int", "libc.scm", "siginfo.si_overrun", "libc.scm", "siginfo.si_pid", "libc.scm", "siginfo.si_ptr", "libc.scm", "siginfo.si_signo", "libc.scm", "siginfo.si_status", "libc.scm", "siginfo.si_stime", "libc.scm", "siginfo.si_timerid", "libc.scm", "siginfo.si_uid", "libc.scm", "siginfo.si_utime", "libc.scm", "siginfo.si_value", "libc.scm", "sigismember", "libc.scm", "signal", "libc.scm", "signbit", "libm.scm", "signum", "dsp.scm", "sigpending", "libc.scm", "sigprocmask", "libc.scm", "sigqueue", "libc.scm", "sigset.make", "libc.scm", "sigsuspend", "libc.scm", "sigtimedwait", "libc.scm", "sigwait", "libc.scm", "sigwaitinfo", "libc.scm", "silence-all-mixes", "mix.scm", "silence-mixes", "mix.scm", "silence?", "spokenword.scm", "simplify-complex", "poly.scm", "simplify-envelope", "env.scm", "sin-m*pi/n", "numerics.scm", "sin-nx-peak", "numerics.scm", "sinc-train", "generators.scm", "sinc-train?", "generators.scm", "sine-bank", "pvoc.scm", "sine-env", "generators.scm", "sine-env-channel", "extensions.scm", "sine-ramp", "extensions.scm", "singer", "singer.scm", "sixth", "stuff.scm", "sleep", "libc.scm", "slightly-musical-conehead", "animals.scm", "smooth-float-vector", "clean.scm", "snap-mark-to-beat", "marks.scm", "snap-marks", "marks.scm", "snap-mix-1", "mix.scm", "snap-mix-to-beat", "mix.scm", "snap-syncd-mixes-1", "mix.scm", "snap-syncd-mixes-to-beat", "mix.scm", "snd-analog-filter.scm", "analog-filter.scm", "snd-animals.scm", "animals.scm", "snd-autosave.scm", "autosave.scm", "snd-bess.scm", "bess.scm", "snd-bess1.scm", "bess1.scm", "snd-big-gens.scm", "big-gens.scm", "snd-binary-io.scm", "binary-io.scm", "snd-bird.scm", "bird.scm", "snd-clean.scm", "clean.scm", "snd-clm-ins.scm", "clm-ins.scm", "snd-clm23.scm", "clm23.scm", "snd-dlocsig.scm", "dlocsig.scm", "snd-draw.scm", "draw.scm", "snd-dsp.scm", "dsp.scm", "snd-edit-menu.scm", "edit-menu.scm", "snd-edit123.scm", "edit123.scm", "snd-effects-utils.scm", "effects-utils.scm", "snd-env.scm", "env.scm", "snd-enved.scm", "enved.scm", "snd-examp.scm", "examp.scm", "snd-expandn.scm", "expandn.scm", "snd-extensions.scm", "extensions.scm", "snd-fade.scm", "fade.scm", "snd-fft-menu.scm", "fft-menu.scm", "snd-fmv.scm", "fmv.scm", "snd-freeverb.scm", "freeverb.scm", "snd-fullmix.scm", "fullmix.scm", "snd-generators.scm", "generators.scm", "snd-grani.scm", "grani.scm", "snd-gtk-effects-utils.scm", "gtk-effects-utils.scm", "snd-gtk-effects.scm", "gtk-effects.scm", "snd-hooks", "hooks.scm", "snd-hooks.scm", "hooks.scm", "snd-index.scm", "index.scm", "snd-jcrev.scm", "jcrev.scm", "snd-jcvoi.scm", "jcvoi.scm", "snd-maraca.scm", "maraca.scm", "snd-marks-menu.scm", "marks-menu.scm", "snd-marks.scm", "marks.scm", "snd-maxf.scm", "maxf.scm", "snd-misc.scm", "misc.scm", "snd-mix.scm", "mix.scm", "snd-moog.scm", "moog.scm", "snd-msg", "maxf.scm", "snd-musglyphs.scm", "musglyphs.scm", "snd-nb.scm", "nb.scm", "snd-new-backgrounds.scm", "new-backgrounds.scm", "snd-new-effects.scm", "new-effects.scm", "snd-noise.scm", "noise.scm", "snd-nrev.scm", "nrev.scm", "snd-numerics.scm", "numerics.scm", "snd-peak-phases.scm", "peak-phases.scm", "snd-piano.scm", "piano.scm", "snd-play.scm", "play.scm", "snd-poly.scm", "poly.scm", "snd-prc95.scm", "prc95.scm", "snd-pvoc.scm", "pvoc.scm", "snd-rgb.scm", "rgb.scm", "snd-rubber.scm", "rubber.scm", "snd-selection.scm", "selection.scm", "snd-singer.scm", "singer.scm", "snd-snd-gl.scm", "snd-gl.scm", "snd-snd-gtk.scm", "snd-gtk.scm", "snd-snd-motif.scm", "snd-motif.scm", "snd-snddiff.scm", "snddiff.scm", "snd-sndwarp.scm", "sndwarp.scm", "snd-special-menu.scm", "special-menu.scm", "snd-spectr.scm", "spectr.scm", "snd-strad.scm", "strad.scm", "snd-v.scm", "v.scm", "snd-ws.scm", "ws.scm", "snd-xm-enved.scm", "xm-enved.scm", "snd-zip.scm", "zip.scm", "snddiff", "snddiff.scm", "snddiff-1", "snddiff.scm", "snddiff-2", "snddiff.scm", "sndlib-ws.scm", "sndlib-ws.scm", "sndwarp", "sndwarp.scm", "snowy-tree-cricket", "animals.scm", "socket", "libc.scm", "socketpair", "libc.scm", "soft-clipped", "dsp.scm", "song-sparrow", "animals.scm", "sonoran-desert-toad", "animals.scm", "sora", "animals.scm", "sort-samples", "examp.scm", "sound-interp", "examp.scm", "sound-let", "ws.scm", "southeastern-field-cricket", "animals.scm", "southern-cricket-frog", "animals.scm", "southern-mole-cricket", "animals.scm", "southwestern-toad", "animals.scm", "speaker-config-coords", "dlocsig.scm", "speaker-config-delays", "dlocsig.scm", "speaker-config-dimension", "dlocsig.scm", "speaker-config-groups", "dlocsig.scm", "speaker-config-map", "dlocsig.scm", "speaker-config-number", "dlocsig.scm", "spectra", "clm-ins.scm", "spectral-polynomial", "dsp.scm", "spectrum->coeffs", "dsp.scm", "sphagnum-ground-cricket", "animals.scm", "spike", "dsp.scm", "spiral-distance", "dlocsig.scm", "spiral-height", "dlocsig.scm", "spiral-render", "dlocsig.scm", "spiral-start-angle", "dlocsig.scm", "spiral-step-angle", "dlocsig.scm", "spiral-total-angle", "dlocsig.scm", "spiral-turns", "dlocsig.scm", "spiral-velocity", "dlocsig.scm", "spot-freq", "dsp.scm", "spring-peeper", "animals.scm", "square", "r7rs.scm", "square-env", "generators.scm", "squelch-vowels", "examp.scm", "squirrel-tree-frog", "animals.scm", "srand", "libc.scm", "srandom", "libc.scm", "src-duration", "dsp.scm", "src-fit-envelope", "dsp.scm", "src-mixes", "mix.scm", "ssb-bank", "dsp.scm", "ssb-bank-env", "dsp.scm", "ssb-fm", "clm-ins.scm", "start-dac", "play.scm", "start-enveloping", "enved.scm", "start-sync", "marks.scm", "stat", "libc.scm", "stat.make", "libc.scm", "stat.st_atime", "libc.scm", "stat.st_blksize", "libc.scm", "stat.st_blocks", "libc.scm", "stat.st_ctime", "libc.scm", "stat.st_dev", "libc.scm", "stat.st_gid", "libc.scm", "stat.st_ino", "libc.scm", "stat.st_mode", "libc.scm", "stat.st_mtime", "libc.scm", "stat.st_nlink", "libc.scm", "stat.st_rdev", "libc.scm", "stat.st_size", "libc.scm", "stat.st_uid", "libc.scm", "stderr", "libc.scm", "stdin", "libc.scm", "stdout", "libc.scm", "stellers-jay", "animals.scm", "stereo->mono", "extensions.scm", "stereo-flute", "clm-ins.scm", "stochastic", "stochastic.scm", "stop-enveloping", "enved.scm", "stop-sync", "marks.scm", "strcasecmp", "libc.scm", "strcat", "libc.scm", "strchr", "libc.scm", "strcmp", "libc.scm", "strcoll", "libc.scm", "strcpy", "libc.scm", "strcspn", "libc.scm", "strerror", "libc.scm", "stretch-envelope", "env.scm", "stretch-sound-via-dft", "dsp.scm", "string->c-pointer", "libc.scm", "string->utf8", "r7rs.scm", "string->vector", "r7rs.scm", "string-copy!", "r7rs.scm", "string-for-each", "r7rs.scm", "string-map", "r7rs.scm", "stringy", "generators.scm", "striped-ground-cricket", "animals.scm", "strlen", "libc.scm", "strncasecmp", "libc.scm", "strncat", "libc.scm", "strncmp", "libc.scm", "strncpy", "libc.scm", "strnlen", "libc.scm", "strpbrk", "libc.scm", "strrchr", "libc.scm", "strspn", "libc.scm", "strstr", "libc.scm", "strtod", "libc.scm", "strtof", "libc.scm", "strtok", "libc.scm", "strtol", "libc.scm", "strtoll", "libc.scm", "strxfrm", "libc.scm", "stuff.scm", "stuff.scm", "submatrix", "poly.scm", "subsequence", "stuff.scm", "summer-tanager", "animals.scm", "superimpose-ffts", "examp.scm", "swainsons-thrush", "animals.scm", "swap-selection-channels", "selection.scm", "symbol=?", "r7rs.scm", "symmetric-difference", "stuff.scm", "sync-all-mixes", "mix.scm", "sync-everything", "examp.scm", "syncd-mixes", "mix.scm", "syncup", "marks.scm", "sysconf", "libc.scm", "tanhsin", "generators.scm", "tanhsin?", "generators.scm", "tcdrain", "libc.scm", "tcflow", "libc.scm", "tcflush", "libc.scm", "tcgetattr", "libc.scm", "tcgetpgrp", "libc.scm", "tcsendbreak", "libc.scm", "tcsetattr", "libc.scm", "tcsetpgrp", "libc.scm", "tempnam", "libc.scm", "tenth", "stuff.scm", "termios.c_lflag", "libc.scm", "termios.make", "libc.scm", "termios.set_c_cc", "libc.scm", "termios.set_c_lflag", "libc.scm", "test-grani", "grani.scm", "test-notch-hum", "clean.scm", "test-remove-DC", "clean.scm", "test-remove-pops", "clean.scm", "test-remove-single-clicks", "clean.scm", "test-sv", "generators.scm", "texas-toad", "animals.scm", "textual-port?", "r7rs.scm", "tgamma", "libm.scm", "third", "stuff.scm", "time", "libc.scm", "time.make", "libc.scm", "times->samples", "ws.scm", "timespec.make", "libc.scm", "timespec.tv_nsec", "libc.scm", "timespec.tv_sec", "libc.scm", "tinkling-ground-cricket", "animals.scm", "tmpfile", "libc.scm", "tolower", "libc.scm", "touch-tone", "clm-ins.scm", "toupper", "libc.scm", "townsends-solitaire", "animals.scm", "transform-path", "dlocsig.scm", "translate-path", "dlocsig.scm", "transpose-mixes", "mix.scm", "tree-for-each", "mix.scm", "tree-for-each-reversed", "mix.scm", "tree-member", "stuff.scm", "true", "libc.scm", "trumpeter-swan-1", "animals.scm", "trunc", "libm.scm", "truncate-quotient", "r7rs.scm", "truncate-remainder", "r7rs.scm", "tstall", "peak-phases.scm", "tstallderiv", "peak-phases.scm", "tstallf", "peak-phases.scm", "tsteven", "peak-phases.scm", "tstodd", "peak-phases.scm", "tstoddderiv", "peak-phases.scm", "tstprime", "peak-phases.scm", "ttyname", "libc.scm", "tubebell", "clm-ins.scm", "tufted-titmouse", "animals.scm", "tvf-channel", "clean.scm", "two-tab", "clm-ins.scm", "typecase", "stuff.scm", "typeq?", "stuff.scm", "u8-ready?", "r7rs.scm", "uname", "libc.scm", "unb", "nb.scm", "unbox", "r7rs.scm", "unclip-channel", "dsp.scm", "unclip-sound", "dsp.scm", "uncolor-samples", "draw.scm", "unconvolve", "snddiff.scm", "unconvolve-1", "snddiff.scm", "undisplay-bark-fft", "dsp.scm", "undo-channel", "extensions.scm", "ungetc", "libc.scm", "union", "stuff.scm", "unique-reactive-let-name", "stuff.scm", "unlink", "libc.scm", "unsetenv", "libc.scm", "update-graphs", "examp.scm", "utf8->string", "r7rs.scm", "utime", "libc.scm", "varied-thrush", "animals.scm", "various-gull-cries-from-end-of-colony-5", "bird.scm", "vector->float-vector", "poly.scm", "vector->string", "r7rs.scm", "vector-add!", "poly.scm", "vector-copy", "r7rs.scm", "vector-copy!", "r7rs.scm", "vector-for-each", "r7rs.scm", "vector-map", "r7rs.scm", "vector-scale!", "poly.scm", "verdin", "animals.scm", "vermillion-flycatcher", "animals.scm", "vibro", "examp.scm", "virginia-rail", "animals.scm", "voiced->unvoiced", "examp.scm", "volterra-filter", "dsp.scm", "vox", "clm-ins.scm", "wait", "libc.scm", "waitid", "libc.scm", "waitpid", "libc.scm", "warbling-vireo", "animals.scm", "waveshape", "generators.scm", "waveshape?", "generators.scm", "weighted-moving-average", "generators.scm", "weighted-moving-average?", "generators.scm", "western-meadowlark", "animals.scm", "western-tanager", "animals.scm", "western-toad", "animals.scm", "western-wood-pewee-1", "animals.scm", "western-wood-pewee-2", "animals.scm", "while", "stuff.scm", "whip-poor-will", "animals.scm", "white-breasted-nuthatch", "animals.scm", "white-eyed-vireo", "animals.scm", "white-headed-woodpecker", "animals.scm", "white-throated-sparrow", "animals.scm", "white-tipped-dove", "animals.scm", "whooping-crane", "animals.scm", "willet", "animals.scm", "willow-flycatcher", "animals.scm", "wilsons-warbler", "animals.scm", "window-envelope", "env.scm", "window-rms", "examp.scm", "window-samples", "examp.scm", "with-exception-handler", "r7rs.scm", "with-full-sound", "ws.scm", "with-local-hook", "hooks.scm", "with-marked-sound", "ws.scm", "with-mixed-sound", "ws.scm", "with-mixed-sound->notelist", "ws.scm", "with-mixed-sound-mix-info", "ws.scm", "with-simple-sound", "ws.scm", "with-simple-sound-helper", "ws.scm", "with-sound", "ws.scm", "with-sound-helper", "ws.scm", "with-temp-sound", "ws.scm", "with-temporary-selection", "selection.scm", "wood-duck", "animals.scm", "wordexp", "libc.scm", "wordexp.make", "libc.scm", "wordexp.we_wordc", "libc.scm", "wordexp.we_wordv", "libc.scm", "wordfree", "libc.scm", "wrentit", "animals.scm", "write-au-header", "binary-io.scm", "write-bfloat32", "binary-io.scm", "write-bfloat64", "binary-io.scm", "write-bint16", "binary-io.scm", "write-bint32", "binary-io.scm", "write-bint64", "binary-io.scm", "write-bytevector", "r7rs.scm", "write-chars", "binary-io.scm", "write-flac", "examp.scm", "write-int->bfloat80", "binary-io.scm", "write-lfloat32", "binary-io.scm", "write-lfloat64", "binary-io.scm", "write-lint16", "binary-io.scm", "write-lint32", "binary-io.scm", "write-lint64", "binary-io.scm", "write-ogg", "examp.scm", "write-simple", "r7rs.scm", "write-speex", "examp.scm", "write-u8", "r7rs.scm", "write.scm", "write.scm", "ws-save-state", "ws.scm", "wsdat-play", "ws.scm", "wurley", "clm-ins.scm", "x-norm", "dlocsig.scm", "xe-envelope", "xm-enved.scm", "xparse-path", "dlocsig.scm", "yellow-bellied-flycatcher", "animals.scm", "yellow-green-vireo", "animals.scm", "yellow-rumped-warbler", "animals.scm", "yellow-warbler", "animals.scm", "z-transform", "dsp.scm", "za", "clm-ins.scm", "zc", "clm-ins.scm", "zcomb", "examp.scm", "zecho", "examp.scm", "zero+", "examp.scm", "zero-phase", "dsp.scm", "zip-sound", "zip.scm", "zipper", "zip.scm", "zn", "clm-ins.scm", "zone-tailed-hawk", "animals.scm", "zoom-spectrum", "examp.scm", }; static void autoload_info(s7_scheme *sc) { s7_autoload_set_names(sc, snd_names, 5790); } #endif snd-16.1/bess1.rb0000644000076400007640000004746112371762361011721 0ustar bilbil#!/usr/bin/env ruby # bess1.rb -- some examples from clm/rt.lisp and clm/bess5.cl # Copyright (C) 2002--2009 Michael Scholz # Author: Michael Scholz # Created: Sun Sep 15 19:11:12 CEST 2002 # Changed: Tue Sep 29 02:05:49 CEST 2009 # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # Commentary: # Requires sndlib.so and libxm.so! # # This file provides simple mono real time output to DAC. Tempo, # frequency, amplitude, and FM index can be controlled via sliders. # The music algorithms are taken from clm/rt.lisp and clm/bess5.cl. # # Bess.new.start -- starts a Motif widget with two DAC tests. # # Bess.new.start(:srate, $clm_srate # 22050 # :bufsize, $clm_rt_bufsize # 128 # :sample_type, $clm_sample_type # Mus_lshort # :which, :agn # :agn or :vct_test # :play, false) # Code: def warn(*args) str = format(*args) << ($! ? ": #{$!}" : "") << "\n" str << (($@ and $DEBUG) ? "\n[#{$@.join("\n")}]" : "") $stdout.print str $! = nil end def die(*args) warn(*args) exit 1 end def rbm_require(lib) puts "loading #{lib.inspect}" if $VERBOSE require lib.to_s rescue ScriptError die "\aScriptError" end rbm_require "sndlib" $output = nil # holds fd from mus_audio_open_output() $clm_srate = 22050 $clm_sample_type = Mus_lshort $clm_rt_bufsize = 128 module Bess_utils def rbm_random(n) mus_random(n).abs end def get_args(args, key, val) if(key == :help and (args == key or args.member?(key) or args.assoc(key))) val = true elsif(args.member?(key)) x = args[args.index(key) + 1] val = ((x == nil) ? val : x) elsif(args.assoc(key)) val = (args.assoc(key)[1] rescue val) end val end def seconds2samples(sec) sr = (mus_srate() rescue $clm_srate) (sec * sr).round end def envelope_interp(*args) x = args[0] env = args[1] base = args[2] if (not env) or env.empty? 0.0 elsif x <= env[0] or env[2..-1].empty? env[1] elsif env[2] > x if env[1] == env[3] or (base and base == 0.0) env[1] elsif (not base) or base == 1.0 env[1] + (x - env[0]) * ((env[3] - env[1]) / (env[2] - env[0])) else env[1] + ((env[3] - env[1]) / (base - 1.0)) * ((base ** ((x - env[0]) / (env[2] - env[0]))) - 1.0) end else envelope_interp(x, env[2..-1]) end end include Math # simple violin, see snd/fm.html def make_rt_violin(dur = 1.0, freq = 440.0, amp = 0.3, *args) fm_index = get_args(args, :fm_index, 1.0) amp_env = get_args(args, :amp_env, [0, 0, 25, 1, 75, 1, 100, 0]) frq_scl = hz2radians(freq) maxdev = frq_scl * fm_index index1 = maxdev * (5.0 / log(freq)) index2 = maxdev * 3.0 * ((8.5 - log(freq)) / (3.0 + freq / 1000.0)) index3 = maxdev * (4.0 / sqrt(freq)) carrier = make_oscil(:frequency, freq) fmosc1 = make_oscil(:frequency, freq) fmosc2 = make_oscil(:frequency, freq * 3.0) fmosc3 = make_oscil(:frequency, freq * 4.0) ampf = make_env(:envelope, amp_env, :scaler, amp, :duration, dur) indf1 = make_env(:envelope, [0, 1, 25, 0.4, 75, 0.6, 100, 0], :scaler, index1, :duration, dur) indf2 = make_env(:envelope, [0, 1, 25, 0.4, 75, 0.6, 100, 0], :scaler, index2, :duration, dur) indf3 = make_env(:envelope, [0, 1, 25, 0.4, 75, 0.6, 100, 0], :scaler, index3, :duration, dur) pervib = make_triangle_wave(:frequency, 0.5, :amplitude, 0.0025 * frq_scl) ranvib = make_rand_interp(:frequency, 16.0, :amplitude, 0.005 * frq_scl) lambda do | | vib = triangle_wave(pervib) + rand_interp(ranvib) env(ampf) * oscil(carrier, vib + env(indf1) * oscil(fmosc1, vib) + env(indf2) * oscil(fmosc2, 3.0 * vib) + env(indf3) * oscil(fmosc3, 4.0 * vib)) end end end # class Agn is a simplified translation of clm/bess5.cl and # clm/clm-example.lisp. class Agn include Bess_utils def initialize @tempo = 0.25 @amp = 1.0 @freq = 1.0 @index = 1.0 @play = false @lim = 256 @time = 60 @octs = Array.new(@lim + 1) do |i| (4 + 2 * rbell(rbm_random(1.0))).floor end @rhys = Array.new(@lim + 1) do |i| (4 + 6 * rbm_random(1.0)).floor end @amps = Array.new(@lim + 1) do |i| (1 + 8 * rbell(rbm_random(1.0))).floor end @pits = Array.new(@lim + 1) do |i| [0, 0, 2, 4, 11, 11, 5, 6, 7, 9, 2, 0, 0].at((12 * rbm_random(1.0)).floor) end @begs = Array.new(@lim + 1) do |i| if rbm_random(1.0) < 0.9 (4 + 2 * rbm_random(1.0)).floor else (6 * rbm_random(4.0)).floor end end end # called by XtAppAddWorkProc def rt_send2dac(func) if @play mus_audio_write($output, vct2sound_data(vct_map!(make_vct($clm_rt_bufsize), func.call), make_sound_data(1, $clm_rt_bufsize), 0), $clm_rt_bufsize) false else mus_audio_close($output) $output = nil true end end # see clm/rt.lisp def make_vct_test(*args) srate = get_args(args, :srate, $clm_srate) bufsize = get_args(args, :bufsize, $clm_rt_bufsize) sample_type = get_args(args, :sample_type, $clm_sample_type) $clm_srate = set_mus_srate(srate).to_i $clm_rt_bufsize = bufsize $output = mus_audio_open_output(Mus_audio_default, srate, 1, sample_type, bufsize * 2) mode = [0, 12, 2, 4, 14, 4, 5, 5, 0, 7, 7, 11, 11] pits = Array.new(@lim + 1) do rbm_random(12.0).floor end begs = Array.new(@lim + 1) do 1 + rbm_random(3.0).floor end cellbeg, cellsiz, cellctr = 0, 6, 0 func = nil len = dur = 0 lambda do | | if len > 1 len -= 1 else dur = @tempo * begs[cellctr + 1] cellctr += 1 if cellctr > (cellsiz + cellbeg) cellbeg += 1 if rbm_random(1.0) > 0.5 cellsiz += 1 if rbm_random(1.0) > 0.5 cellctr = cellbeg end func = make_rt_violin(dur, @freq * 16.351 * 16 * 2 ** (mode[pits[cellctr]] / 12.0), @amp * 0.3, :fm_index, @index) len = (seconds2samples(dur) / bufsize).ceil end func end end def tune(x) [1.0, 256.0 / 243, 9.0 / 8, 32.0 / 27, 81.0 / 64, 4.0 / 3, 1024.0 / 729, 3.0 / 2, 128.0 / 81, 27.0 / 16, 16.0 / 9, 243.0 / 128, 2.0].at(x % 12) * 2 ** x.divmod(12).first end def rbell(x) envelope_interp(x * 100, [0, 0, 10, 0.25, 90, 1.0, 100, 1.0]) end # see clm/bess5.cl def make_agn(*args) srate = get_args(args, :srate, $clm_srate) bufsize = get_args(args, :bufsize, $clm_rt_bufsize) sample_type = get_args(args, :sample_type, $clm_sample_type) $clm_srate = set_mus_srate(srate).to_i $clm_rt_bufsize = bufsize $output = mus_audio_open_output(Mus_audio_default, srate, 1, sample_type, bufsize * 2) die("can't open DAC (%s)", $output.inspect) if $output < 0 wins = [[0, 0, 40, 0.1, 60, 0.2, 75, 0.4, 82, 1, 90, 1, 100, 0], [0, 0, 60, 0.1, 80, 0.2, 90, 0.4, 95, 1, 100, 0], [0, 0, 10, 1, 16, 0, 32, 0.1, 50, 1, 56, 0, 60, 0, 90, 0.3, 100, 0], [0, 0, 30, 1, 56, 0, 60, 0, 90, 0.3, 100, 0], [0, 0, 50, 1, 80, 0.3, 100, 0], [0, 0, 40, 0.1, 60, 0.2, 75, 0.4, 82, 1, 90, 1, 100, 0], [0, 0, 40, 0.1, 60, 0.2, 75, 0.4, 82, 1, 90, 1, 100, 0], [0, 0, 10, 1, 32, 0.1, 50, 1, 90, 0.3, 100, 0], [0, 0, 60, 0.1, 80, 0.3, 95, 1, 100, 0], [0, 0, 80, 0.1, 90, 1, 100, 0]] cellbeg, cellsiz, cellctr, whichway = 0, 4, 0, 1 nextbeg = beg = 0.0 func = nil len = dur = 0 lambda do | | if len > 1 len -= 1 else beg += nextbeg nextbeg += [0.025, @tempo * (0.95 + rbm_random(0.1)) * @begs[cellctr]].max dur = [0.025, @tempo * (0.85 + rbm_random(0.1)) * @rhys[cellctr]].max freq = @freq * 16.351 * tune(@pits[cellctr]) * 2 ** @octs[cellctr] dur += dur if freq < 100 ampl = @amp * 10 * [0.003, @amps[cellctr] * 0.01].max ind = @index * rbm_random(1.0) * 3.0 cellctr += 1 if cellctr > (cellsiz + cellbeg) cellbeg += 1 if rbm_random(1.0) > 0.5 cellsiz += whichway end if cellsiz > 10 and rbm_random(1.0) > 0.99 whichway = -2 if cellsiz > 6 and rbm_random(1.0) > 0.999 whichway = -1 if cellsiz < 4 whichway = 1 end end end nextbeg += rbm_random(1.0) cellctr = cellbeg end func = make_rt_violin(dur, freq, ampl, :fm_index, ind, :amp_env, wins[(10 * (beg - beg.floor)).floor]) len = (seconds2samples(dur) / bufsize).ceil end func end end end class Bess < Agn rbm_require "libxm" def initialize super @sliderback = "lightsteelblue" @background = "lightsteelblue1" @which = @proc = nil @shell_app = @form = nil @tl = @ts = @fl = @fs = @al = @as = @il = @is = nil 1.upto(15) do |i| trap(i) do |sig| puts "\nSignal #{sig} received. Process #{$$} canceled." RXtRemoveWorkProc(@proc) if @proc exit 0 end end end def get_color(color) col = RXColor() dpy = RXtDisplay(@shell_app[0]) cmap = RDefaultColormap(dpy, RDefaultScreen(dpy)) warn("Can't allocate #{color.inspect}!") if RXAllocNamedColor(dpy, cmap, color, col, col).zero? Rpixel(col) end def set_label(wid, *args) RXtVaSetValues(wid, [RXmNlabelString, RXmStringCreate(format(*args), RXmFONTLIST_DEFAULT_TAG)]) end def make_label(wid, name) RXtCreateManagedWidget(name, RxmLabelWidgetClass, @form, [RXmNleftAttachment, RXmATTACH_FORM, RXmNbottomAttachment, RXmATTACH_NONE, RXmNtopAttachment, RXmATTACH_WIDGET, RXmNtopWidget, wid, RXmNrightAttachment, RXmATTACH_NONE, RXmNalignment, RXmALIGNMENT_END, RXmNrecomputeSize, false, RXmNbackground, get_color(@background)]) end def make_scale_label(wid) RXtCreateManagedWidget("label", RxmLabelWidgetClass, @form, [RXmNleftAttachment, RXmATTACH_WIDGET, RXmNleftWidget, wid, RXmNbottomAttachment, RXmATTACH_NONE, RXmNtopAttachment, RXmATTACH_OPPOSITE_WIDGET, RXmNtopWidget, wid, RXmNrightAttachment, RXmATTACH_NONE, RXmNbackground, get_color(@background)]) end def make_scale(wid) RXtCreateManagedWidget("scale", RxmScaleWidgetClass, @form, [RXmNleftAttachment, RXmATTACH_WIDGET, RXmNleftWidget, wid, RXmNbottomAttachment, RXmATTACH_NONE, RXmNtopAttachment, RXmATTACH_OPPOSITE_WIDGET, RXmNtopWidget, wid, RXmNrightAttachment, RXmATTACH_FORM, RXmNshowValue, false, RXmNorientation, RXmHORIZONTAL, RXmNheight, 20, RXmNbackground, get_color(@sliderback)]) end # return label and scale widget def make_scales(wid, name, val, callback) label = make_scale_label(make_label(wid, name)) scale = make_scale(label) set_label(label, val.kind_of?(Integer) ? "%4d" : "%4.3f", val) RXtAddCallback(scale, RXmNdragCallback, callback, label) RXtAddCallback(scale, RXmNvalueChangedCallback, callback ,label) [label, scale] end def do_play(*args) if @play case @which when :agn func = make_agn(*args) when :vct_test func = make_vct_test(*args) else func = make_agn(*args) end @proc = RXtAppAddWorkProc(@shell_app[1], lambda do |c| rt_send2dac(func) end) else RXtRemoveWorkProc(@proc) if @proc end end def set_defaults(parent) @tempo = 0.25 @amp = 1.0 @freq = 1.0 @index = 1.0 low_tempo = 0.05 high_tempo = 0.5 low_freq = 0.1 high_freq = 4.0 high_index = 2.0 set_label(@tl, "%4.3f", @tempo) RXmScaleSetValue(@ts, (100 * (@tempo - low_tempo) / (high_tempo - low_tempo)).round) set_label(@fl, "%4.3f", @freq) RXmScaleSetValue(@fs, (100 * (@freq - low_freq) / (high_freq - low_freq)).round) set_label(@al, "%4.3f", @amp) RXmScaleSetValue(@as, (100 * @amp).round) set_label(@il, "%4.3f", @index) RXmScaleSetValue(@is, (100 * (@index / high_index)).round) end def start(*args) @play = get_args(args, :play, false) @which = get_args(args, :which, :agn) # rest args are going to make_vct_test() or make_agn() cargs = [$0] + $* @shell_app = RXtVaOpenApplication("FM", cargs.length, cargs, RapplicationShellWidgetClass, [RXmNallowShellResize, true, RXmNtitle, "FM forever!"]) RXtAddEventHandler(@shell_app[0], 0, true, lambda do |w, c, i, f| R_XEditResCheckMessages(w, c, i, f) end) @form = RXtCreateManagedWidget("form", RxmFormWidgetClass, @shell_app[0], [RXmNresizePolicy, RXmRESIZE_GROW, RXmNbackground, get_color(@background)]) play = RXtCreateManagedWidget("play", RxmToggleButtonWidgetClass, @form, [RXmNtopAttachment, RXmATTACH_FORM, RXmNleftAttachment, RXmATTACH_FORM, RXmNrightAttachment, RXmATTACH_NONE, RXmNbottomAttachment, RXmATTACH_NONE, RXmNbackground, get_color(@background)]) radio = RXmCreateRadioBox(@form, "radio", [RXmNorientation, RXmHORIZONTAL, RXmNtopAttachment, RXmATTACH_FORM, RXmNleftAttachment, RXmATTACH_WIDGET, RXmNleftWidget, play, RXmNrightAttachment, RXmATTACH_NONE, RXmNbottomAttachment, RXmATTACH_NONE, RXmNbackground, get_color(@background)]) p_agn = RXtCreateManagedWidget("agn", RxmToggleButtonWidgetClass, radio, [RXmNtopAttachment, RXmATTACH_FORM, RXmNleftAttachment, RXmATTACH_FORM, RXmNrightAttachment, RXmATTACH_NONE, RXmNbottomAttachment, RXmATTACH_NONE, RXmNbackground, get_color(@background)]) p_test = RXtCreateManagedWidget("test", RxmToggleButtonWidgetClass, radio, [RXmNtopAttachment, RXmATTACH_FORM, RXmNleftAttachment, RXmATTACH_WIDGET, RXmNleftWidget, p_agn, RXmNrightAttachment, RXmATTACH_NONE, RXmNbottomAttachment, RXmATTACH_NONE, RXmNbackground, get_color(@background)]) quit = RXtCreateManagedWidget(" quit ", RxmPushButtonWidgetClass, @form, [RXmNtopAttachment, RXmATTACH_FORM, RXmNleftAttachment, RXmATTACH_WIDGET, RXmNleftWidget, radio, RXmNrightAttachment, RXmATTACH_FORM, RXmNbottomAttachment, RXmATTACH_NONE, RXmNbackground, get_color(@background)]) sep = RXtCreateManagedWidget("sep", RxmSeparatorWidgetClass, @form, [RXmNleftAttachment, RXmATTACH_FORM, RXmNbottomAttachment, RXmATTACH_NONE, RXmNtopAttachment, RXmATTACH_WIDGET, RXmNtopWidget, radio, RXmNrightAttachment, RXmATTACH_FORM, RXmNheight, 4, RXmNorientation, RXmHORIZONTAL]) RXmToggleButtonSetState(play, @play, true) RXtAddCallback(play, RXmNvalueChangedCallback, lambda do |w, c, i| @play = Rset(i) set_defaults(sep) if @play do_play(*args) end) RXmToggleButtonSetState(p_agn, @which == :agn, true) RXtAddCallback(p_agn, RXmNvalueChangedCallback, lambda do |w, c, i| @which = c if Rset(i) @play = false RXmToggleButtonSetState(play, @play, true) end, :agn) RXmToggleButtonSetState(p_test, @which == :vct_test, true) RXtAddCallback(p_test, RXmNvalueChangedCallback, lambda do |w, c, i| @which = c if Rset(i) @play = false RXmToggleButtonSetState(play, @play, true) end, :vct_test) RXtAddCallback(quit, RXmNactivateCallback, lambda do |w, c, i| RXtRemoveWorkProc(@proc) if @proc exit 0 end) low_tempo = 0.05 high_tempo = 0.5 low_freq = 0.1 high_freq = 4.0 high_index = 2.0 @tl, @ts = make_scales(sep, " tempo:", @tempo, lambda do |w, c, i| @tempo = low_tempo + Rvalue(i) * (high_tempo - low_tempo) * 0.01 set_label(c, "%4.3f", @tempo) end) RXmScaleSetValue(@ts, (100 * (@tempo - low_tempo) / (high_tempo - low_tempo)).round) @fl, @fs = make_scales(@ts, " freq:", @freq, lambda do |w, c, i| @freq = low_freq + Rvalue(i) * ((high_freq - low_freq) * 0.01) set_label(c, "%4.3f", @freq) end) RXmScaleSetValue(@fs, (100 * (@freq - low_freq) / (high_freq - low_freq)).round) @al, @as = make_scales(@fs, " amp:", @amp, lambda do |w, c, i| @amp = Rvalue(i) * 0.01 set_label(c, "%4.3f", @amp) end) RXmScaleSetValue(@as, (100 * @amp).round) @il, @is = make_scales(@as, " index:", @index, lambda do |w, c, i| @index = Rvalue(i) * high_index * 0.01 set_label(c, "%4.3f", @index) end) RXmScaleSetValue(@is, (100 * (@index / high_index)).round) do_play(*args) RXtManageChild(radio) RXtRealizeWidget(@shell_app[0]) RXtAppMainLoop(@shell_app[1]) end end begin # Bess.new.start(:srate, $clm_srate, # :bufsize, $clm_rt_bufsize, # :sample_type, $clm_sample_type, # :which, :agn, # :play, false) Bess.new.start end # bess1.rb ends here snd-16.1/vct.c0000644000076400007640000015742512601500374011307 0ustar bilbil/* vct support * * a vct is an object containing a mus_float_t array and its size * * C side: * void mus_vct_init(void) called to declare the various functions and the vct type * bool mus_is_vct(Xen obj) is obj a vct * Xen xen_make_vct(int len, mus_float_t *data) make a new vct * Xen xen_make_vct_wrapper(int len, mus_float_t *data) make a new vct that doesn't free data when garbage collector strikes * vct *xen_to_vct(Xen arg) given Xen arg, return vct * void mus_vct_set_print_length(int val) set vct print length (default 10) (also mus_vct_print_length) * * (make-vct len (filler 0.0)) make new vct * (vct? obj) is obj a vct * (vct-ref v index) return v[index] * (vct-set! v index val) v[index] = val * (vct-copy v) return a copy of v * (vct-length v) return length of v * (vct-add! v1 v2 (offset 0)) v1[i+offset] = v1[i+offset] + v2[i] -> v1 * (vct-subtract! v1 v2) v1[i] = v1[i] - v2[i] -> v1 * (vct-offset! v1 scl) v1[i] += scl -> v1 * (vct-multiply! v1 v2) v1[i] *= v2[i] -> v1 * (vct-scale! v1 scl) v1[i] *= scl -> v1 * (vct-abs! v) v[i] = abs(v[i]) * (vct-fill! v1 val) v1[i] = val -> v1 * (vct-map! v1 proc) set each element of v1 to value of function proc() * (vct-peak v1) max val (abs) in v * (vct-equal? v1 v2 diff) is element-wise relative-difference of v1 and v2 ever greater than diff? * (list->vct lst) return vct with elements of list lst * (vct->list v1) return list with elements of vct v1 * (vector->vct vect) return vct with elements of vector vect * (vct->vector v) return vector of vct contents * (vct-move! v new old) v[new++] = v[old++] -> v * (vct-subseq v start end vnew) vnew = v[start..end] * (vct-reverse! v (len #f)) reverse contents (using len as end point if given) * (vct->string v) scheme-readable description of vct * * (vct* obj1 obj2) combines vct-multiply and vct-scale * (vct+ obj1 obj2) combines vct-add and vct-offset * * The intended use is a sort of latter-day array-processing system that handles huge * one-dimensional vectors -- fft's, etc. Some of these functions can be found in * the Snd package; others can be found in the CLM package (clm2xen.c). */ #include "mus-config.h" #if USE_SND #include "snd.h" #endif #include #include #include #include #include #if _MSC_VER #pragma warning(disable: 4244) #endif #include "_sndlib.h" #include "xen.h" #include "clm.h" #include "sndlib2xen.h" #include "clm2xen.h" #include "vct.h" #if (!HAVE_SCHEME) struct vct { mus_long_t length; mus_float_t *data; bool dont_free; }; mus_long_t mus_vct_length(vct *v) {return(v->length);} mus_float_t *mus_vct_data(vct *v) {return(v->data);} #endif #if HAVE_SCHEME #define S_make_vct "make-float-vector" #define S_vct_add "float-vector-add!" #define S_vct_subtract "float-vector-subtract!" #define S_vct_copy "float-vector-copy" #define S_vct_length "float-vector-length" #define S_vct_multiply "float-vector-multiply!" #define S_vct_offset "float-vector-offset!" #define S_vct_ref "float-vector-ref" #define S_vct_scale "float-vector-scale!" #define S_vct_abs "float-vector-abs!" #define S_vct_fill "float-vector-fill!" #define S_vct_set "float-vector-set!" #define S_vct_peak "float-vector-peak" #define S_vct_equal "float-vector-equal?" #define S_is_vct "float-vector?" #define S_list_to_vct "list->float-vector" #define S_vct_to_list "float-vector->list" #define S_vector_to_vct "vector->float-vector" #define S_vct_to_vector "float-vector->vector" #define S_vct_move "float-vector-move!" #define S_vct_subseq "float-vector-subseq" #define S_vct_reverse "float-vector-reverse!" #define S_vct_to_string "float-vector->string" #define S_vct_times "float-vector*" #define S_vct_plus "float-vector+" #define A_VCT "a float-vector" #else #define S_make_vct "make-vct" #define S_vct_add "vct-add!" #define S_vct_subtract "vct-subtract!" #define S_vct_copy "vct-copy" #define S_vct_length "vct-length" #define S_vct_multiply "vct-multiply!" #define S_vct_offset "vct-offset!" #define S_vct_ref "vct-ref" #define S_vct_scale "vct-scale!" #define S_vct_abs "vct-abs!" #define S_vct_fill "vct-fill!" #define S_vct_set "vct-set!" #define S_vct_peak "vct-peak" #define S_vct_equal "vct-equal?" #define S_is_vct "vct?" #define S_list_to_vct "list->vct" #define S_vct_to_list "vct->list" #define S_vector_to_vct "vector->vct" #define S_vct_to_vector "vct->vector" #define S_vct_move "vct-move!" #define S_vct_subseq "vct-subseq" #define S_vct_reverse "vct-reverse!" #define S_vct_to_string "vct->string" #if HAVE_RUBY #define S_vct_times "vct_multiply" #define S_vct_plus "vct_add" #else #define S_vct_times "vct*" #define S_vct_plus "vct+" #endif #define A_VCT "a vct" #endif #ifndef PROC_FALSE #if HAVE_RUBY #define PROC_FALSE "false" #define PROC_TRUE "true" #else #define PROC_FALSE "#f" #define PROC_TRUE "#t" #endif #endif #if USE_SND #define VCT_PRINT_LENGTH DEFAULT_PRINT_LENGTH #else #define VCT_PRINT_LENGTH 10 #endif static int vct_print_length = VCT_PRINT_LENGTH; void mus_vct_set_print_length(int len) { vct_print_length = len; } int mus_vct_print_length(void) { return(vct_print_length); } vct *xen_to_vct(Xen arg) { if (mus_is_vct(arg)) return((vct *)Xen_to_vct(arg)); return(NULL); } #define VCT_PRINT_BUFFER_SIZE 64 #if (!HAVE_SCHEME) static Xen_object_type_t vct_tag; bool mus_is_vct(Xen obj) { return(Xen_c_object_is_type(obj, vct_tag)); } static void vct_free(vct *v) { if (v) { if ((!(v->dont_free)) && (v->data)) free(v->data); v->data = NULL; free(v); } } Xen_wrap_free(vct, free_vct, vct_free) static char *mus_vct_to_string(vct *v) { int len, size; char *buf; char flt[VCT_PRINT_BUFFER_SIZE]; mus_float_t *d; if (v == NULL) return(NULL); len = vct_print_length; if (len > mus_vct_length(v)) len = mus_vct_length(v); d = mus_vct_data(v); size = (len + 1) * VCT_PRINT_BUFFER_SIZE; buf = (char *)calloc(size, sizeof(char)); snprintf(buf, size, "# 0) && (d != NULL)) { int i; strcat(buf, ":"); for (i = 0; i < len; i++) { snprintf(flt, VCT_PRINT_BUFFER_SIZE, " %.3f", d[i]); strcat(buf, flt); } if (mus_vct_length(v) > vct_print_length) strcat(buf, " ..."); } strcat(buf, ">"); return(buf); } #endif char *mus_vct_to_readable_string(vct *v) { int i, len, size; char *buf; char flt[VCT_PRINT_BUFFER_SIZE]; mus_float_t *d; if (v == NULL) return(NULL); len = (int)(mus_vct_length(v)); size = (len + 1) * VCT_PRINT_BUFFER_SIZE; buf = (char *)calloc(size, sizeof(char)); d = mus_vct_data(v); #if HAVE_SCHEME snprintf(buf, size, "(float-vector"); #endif #if HAVE_RUBY || HAVE_FORTH snprintf(buf, size, "vct("); #endif for (i = 0; i < len; i++) { #if HAVE_SCHEME || HAVE_FORTH snprintf(flt, VCT_PRINT_BUFFER_SIZE, " %.3f", d[i]); #endif #if HAVE_RUBY snprintf(flt, VCT_PRINT_BUFFER_SIZE, "%.3f%s", d[i], i + 1 < len ? ", " : ""); #endif strcat(buf, flt); } #if HAVE_FORTH strcat(buf, " "); #endif strcat(buf, ")"); return(buf); } static Xen g_vct_to_readable_string(Xen obj) { char *vstr; Xen result; #define H_vct_to_string "(" S_vct_to_string " v): readable description of v" Xen_check_type(mus_is_vct(obj), obj, 1, S_vct_to_string, A_VCT); vstr = mus_vct_to_readable_string(Xen_to_vct(obj)); result = C_string_to_Xen_string(vstr); free(vstr); return(result); } bool mus_vct_is_equal(vct *v1, vct *v2) { if (v1 == v2) return(true); return((mus_vct_length(v1) == mus_vct_length(v2)) && (mus_arrays_are_equal(mus_vct_data(v1), mus_vct_data(v2), mus_float_equal_fudge_factor(), mus_vct_length(v1)))); } #if (!HAVE_SCHEME) static Xen g_is_vct(Xen obj) { #define H_is_vct "(" S_is_vct " obj): is obj a " S_vct return(C_bool_to_Xen_boolean(mus_is_vct(obj))); } Xen_wrap_print(vct, print_vct, mus_vct_to_string) static Xen equalp_vct(Xen obj1, Xen obj2) { if ((!(mus_is_vct(obj1))) || (!(mus_is_vct(obj2)))) return(Xen_false); return(C_bool_to_Xen_boolean(mus_vct_is_equal(Xen_to_vct(obj1), Xen_to_vct(obj2)))); } vct *mus_vct_make(mus_long_t len) { vct *new_vct; new_vct = (vct *)malloc(sizeof(vct)); new_vct->length = len; if (len > 0) new_vct->data = (mus_float_t *)calloc(len, sizeof(mus_float_t)); else new_vct->data = NULL; new_vct->dont_free = false; return(new_vct); } vct *mus_vct_wrap(mus_long_t len, mus_float_t *data) { vct *new_vct; new_vct = (vct *)malloc(sizeof(vct)); new_vct->length = len; new_vct->data = data; new_vct->dont_free = true; return(new_vct); } vct *mus_vct_free(vct *v) { vct_free(v); return(NULL); } Xen xen_make_vct(mus_long_t len, mus_float_t *data) { vct *new_vct; if (len < 0) return(Xen_false); if ((len > 0) && (data == NULL)) Xen_error(Xen_make_error_type("out-of-memory"), Xen_list_2(C_string_to_Xen_string(S_make_vct ": can't allocate size ~A"), C_int_to_Xen_integer(len))); new_vct = (vct *)malloc(sizeof(vct)); new_vct->length = len; new_vct->data = data; new_vct->dont_free = false; return(Xen_make_object(vct_tag, new_vct, 0, free_vct)); } Xen xen_make_vct_wrapper(mus_long_t len, mus_float_t *data) { vct *new_vct; new_vct = (vct *)malloc(sizeof(vct)); new_vct->length = len; new_vct->data = data; new_vct->dont_free = true; return(Xen_make_object(vct_tag, new_vct, 0, free_vct)); } Xen vct_to_xen(vct *v) { return(Xen_make_object(vct_tag, v, 0, free_vct)); } static Xen g_vct_fill(Xen obj, Xen val); static Xen g_make_vct(Xen len, Xen filler) { #if HAVE_RUBY #define vct_make_example "v = make_vct(32, 1.0)" #endif #if HAVE_FORTH #define vct_make_example "32 1.0 make-vct value v" #endif #if HAVE_SCHEME #define vct_make_example "(make-float-vector 32 1.0)" #endif #define H_make_vct "(" S_make_vct " len :optional (initial-element 0)): returns a new " S_vct " of length len filled with \ initial-element: \n " vct_make_example mus_long_t size; Xen_check_type(Xen_is_llong(len), len, 1, S_make_vct, "an integer"); Xen_check_type(Xen_is_number(filler) || !Xen_is_bound(filler), filler, 2, S_make_vct, "a number"); size = Xen_llong_to_C_llong(len); if (size < 0) Xen_out_of_range_error(S_make_vct, 1, len, "new vct size < 0?"); if ((size > mus_max_malloc()) || (((mus_long_t)(size * sizeof(mus_float_t))) > mus_max_malloc())) Xen_out_of_range_error(S_make_vct, 1, len, "new vct size is too large (see mus-max-malloc)"); if (Xen_is_number(filler)) return(g_vct_fill(xen_make_vct(size, (mus_float_t *)calloc(size, sizeof(mus_float_t))), filler)); return(xen_make_vct(size, (mus_float_t *)calloc(size, sizeof(mus_float_t)))); } static Xen g_vct_length(Xen obj) { #define H_vct_length "(" S_vct_length " v): length of " S_vct " v" vct *v; Xen_check_type(mus_is_vct(obj), obj, 1, S_vct_length, A_VCT); v = Xen_to_vct(obj); return(C_llong_to_Xen_llong(mus_vct_length(v))); } static Xen g_vct_copy(Xen obj) { #define H_vct_copy "(" S_vct_copy " v): returns a copy of " S_vct " v" vct *v; mus_float_t *copied_data = NULL; mus_long_t len; Xen_check_type(mus_is_vct(obj), obj, 1, S_vct_copy, A_VCT); v = Xen_to_vct(obj); len = mus_vct_length(v); if (len > 0) { copied_data = (mus_float_t *)malloc(len * sizeof(mus_float_t)); memcpy((void *)copied_data, (void *)(mus_vct_data(v)), (len * sizeof(mus_float_t))); } return(xen_make_vct(len, copied_data)); } #else /* HAVE_SCHEME */ vct *mus_vct_make(mus_long_t len) { s7_int di[1]; di[0] = len; return(s7_make_float_vector(s7, len, 1, di)); } Xen xen_make_vct(mus_long_t len, mus_float_t *data) { return(s7_make_float_vector_wrapper(s7, len, (s7_double *)data, 1, NULL, true)); /* freed by s7 */ } Xen xen_make_vct_wrapper(mus_long_t len, mus_float_t *data) { s7_int di[1]; di[0] = len; return(s7_make_float_vector_wrapper(s7, len, (s7_double *)data, 1, di, false)); /* not freed by s7 */ } vct *mus_vct_wrap(mus_long_t len, mus_float_t *data) { return(xen_make_vct_wrapper(len, data)); } static Xen g_vct_copy(Xen obj) { #define H_vct_copy "(" S_vct_copy " v): returns a copy of " S_vct " v" Xen_check_type(mus_is_vct(obj), obj, 1, S_vct_copy, A_VCT); return(s7_vector_copy(s7, obj)); } #endif static Xen g_vct_move(Xen obj, Xen newi, Xen oldi, Xen backwards) { #define H_vct_moveB "(" S_vct_move " obj new old :optional backwards): moves " S_vct " obj data from old to new: v[new++] = v[old++], or \ v[new--] = v[old--] if backwards is " PROC_FALSE "." vct *v; mus_long_t i, j, ni, nj; mus_float_t *d; Xen_check_type(mus_is_vct(obj), obj, 1, S_vct_move, A_VCT); Xen_check_type(Xen_is_llong(newi), newi, 2, S_vct_move, "an integer"); Xen_check_type(Xen_is_llong(oldi), oldi, 3, S_vct_move, "an integer"); Xen_check_type(Xen_is_boolean_or_unbound(backwards), backwards, 4, S_vct_move, "a boolean"); v = Xen_to_vct(obj); d = mus_vct_data(v); ni = Xen_llong_to_C_llong(newi); nj = Xen_llong_to_C_llong(oldi); if ((Xen_is_boolean(backwards)) && (!Xen_is_false(backwards))) { if (ni >= mus_vct_length(v)) Xen_out_of_range_error(S_vct_move, 2, newi, "new-index too high"); if (nj >= mus_vct_length(v)) Xen_out_of_range_error(S_vct_move, 3, oldi, "old-index too high"); for (i = ni, j = nj; (j >= 0) && (i >= 0); i--, j--) d[i] = d[j]; } else { mus_long_t len; if (ni < 0) Xen_out_of_range_error(S_vct_move, 2, newi, "new-index < 0?"); if (nj < 0) Xen_out_of_range_error(S_vct_move, 3, oldi, "old-index < 0?"); len = mus_vct_length(v); for (i = ni, j = nj; (j < len) && (i < len); i++, j++) d[i] = d[j]; } return(obj); } #if (!HAVE_SCHEME) static Xen g_vct_ref(Xen obj, Xen pos) { #define H_vct_ref "(" S_vct_ref " v n): element n of " S_vct " v, v[n]" vct *v; mus_long_t loc; Xen_check_type(mus_is_vct(obj), obj, 1, S_vct_ref, A_VCT); Xen_check_type(Xen_is_llong(pos), pos, 2, S_vct_ref, "an integer"); v = Xen_to_vct(obj); loc = Xen_llong_to_C_llong(pos); if (loc < 0) Xen_out_of_range_error(S_vct_ref, 2, pos, "index < 0?"); if (loc >= mus_vct_length(v)) Xen_out_of_range_error(S_vct_ref, 2, pos, "index too high?"); return(C_double_to_Xen_real(mus_vct_data(v)[loc])); } static Xen g_vct_set(Xen obj, Xen pos, Xen val) { #define H_vct_setB "(" S_vct_set " v n val): sets element of " S_vct " v to val, v[n] = val" vct *v; mus_long_t loc; double x; mus_float_t *d; Xen_check_type(mus_is_vct(obj), obj, 1, S_vct_set, A_VCT); Xen_check_type(Xen_is_llong(pos), pos, 2, S_vct_set, "an integer"); Xen_check_type(Xen_is_number(val), val, 3, S_vct_set, "a real number"); x = Xen_real_to_C_double(val); v = Xen_to_vct(obj); loc = Xen_llong_to_C_llong(pos); if (loc < 0) Xen_out_of_range_error(S_vct_set, 2, pos, "index < 0?"); if (loc >= mus_vct_length(v)) Xen_out_of_range_error(S_vct_set, 2, pos, "index >= vct-length?"); d = mus_vct_data(v); d[loc] = x; return(val); } #endif static Xen g_vct_multiply(Xen obj1, Xen obj2) { #define H_vct_multiplyB "(" S_vct_multiply " v1 v2): element-wise multiply of " S_vct "s v1 and v2: v1[i] *= v2[i], returns v1" mus_long_t i, lim, lim1; vct *v1, *v2; mus_float_t *d1, *d2; Xen_check_type(mus_is_vct(obj1), obj1, 1, S_vct_multiply, A_VCT); Xen_check_type(mus_is_vct(obj2), obj2, 2, S_vct_multiply, A_VCT); v1 = Xen_to_vct(obj1); v2 = Xen_to_vct(obj2); d1 = mus_vct_data(v1); d2 = mus_vct_data(v2); lim = mus_vct_length(v1); lim1 = mus_vct_length(v2); if (lim > lim1) lim = lim1; for (i = 0; i < lim; i++) d1[i] *= d2[i]; return(obj1); } static void vct_add(mus_float_t *d1, mus_float_t *d2, mus_long_t lim) { mus_long_t i, lim8; lim8 = lim - 16; i = 0; while (i <= lim8) { d1[i] += d2[i]; i++; d1[i] += d2[i]; i++; d1[i] += d2[i]; i++; d1[i] += d2[i]; i++; d1[i] += d2[i]; i++; d1[i] += d2[i]; i++; d1[i] += d2[i]; i++; d1[i] += d2[i]; i++; d1[i] += d2[i]; i++; d1[i] += d2[i]; i++; d1[i] += d2[i]; i++; d1[i] += d2[i]; i++; d1[i] += d2[i]; i++; d1[i] += d2[i]; i++; d1[i] += d2[i]; i++; d1[i] += d2[i]; i++; } for (; i < lim; i++) d1[i] += d2[i]; } static Xen g_vct_add(Xen obj1, Xen obj2, Xen offs) { #define H_vct_addB "(" S_vct_add " v1 v2 :optional (offset 0)): element-wise add of " S_vct "s v1 and v2: v1[i + offset] += v2[i], returns v1" mus_long_t lim, len1; vct *v1, *v2; mus_float_t *d1, *d2; Xen_check_type(mus_is_vct(obj1), obj1, 1, S_vct_add, A_VCT); Xen_check_type(mus_is_vct(obj2), obj2, 2, S_vct_add, A_VCT); Xen_check_type(Xen_is_llong_or_unbound(offs), offs, 3, S_vct_add, "an integer"); v1 = Xen_to_vct(obj1); v2 = Xen_to_vct(obj2); d1 = mus_vct_data(v1); d2 = mus_vct_data(v2); len1 = mus_vct_length(v1); lim = mus_vct_length(v2); if (lim > len1) lim = len1; if (lim == 0) return(obj1); if (Xen_is_llong(offs)) { mus_long_t j; j = Xen_llong_to_C_llong(offs); if (j < 0) Xen_out_of_range_error(S_vct_add, 3, offs, "offset < 0?"); if (j > len1) Xen_out_of_range_error(S_vct_add, 3, offs, "offset > length of vct?"); if ((j + lim) > len1) lim = (len1 - j); vct_add((mus_float_t *)(d1 + j), d2, lim); } else vct_add(d1, d2, lim); return(obj1); } static Xen g_vct_subtract(Xen obj1, Xen obj2) { #define H_vct_subtractB "(" S_vct_subtract " v1 v2): element-wise subtract of " S_vct "s v1 and v2: v1[i] -= v2[i], returns v1" mus_long_t i, lim, lim1, lim4; vct *v1, *v2; mus_float_t *d1, *d2; Xen_check_type(mus_is_vct(obj1), obj1, 1, S_vct_subtract, A_VCT); Xen_check_type(mus_is_vct(obj2), obj2, 2, S_vct_subtract, A_VCT); v1 = Xen_to_vct(obj1); v2 = Xen_to_vct(obj2); d1 = mus_vct_data(v1); d2 = mus_vct_data(v2); lim = mus_vct_length(v1); lim1 = mus_vct_length(v2); if (lim > lim1) lim = lim1; lim4 = lim - 4; i = 0; while (i <= lim4) { d1[i] -= d2[i]; i++; d1[i] -= d2[i]; i++; d1[i] -= d2[i]; i++; d1[i] -= d2[i]; i++; } for (; i < lim; i++) d1[i] -= d2[i]; return(obj1); } static Xen g_vct_abs(Xen obj) { #define H_vct_absB "(" S_vct_abs " v): v[i] = abs(v[i]), return v." mus_long_t i, lim; vct *v; mus_float_t *d; Xen_check_type(mus_is_vct(obj), obj, 0, S_vct_abs, A_VCT); v = Xen_to_vct(obj); d = mus_vct_data(v); lim = mus_vct_length(v); for (i = 0; i < lim; i++) d[i] = fabs(d[i]); return(obj); } static Xen g_vct_equal(Xen uv1, Xen uv2, Xen udiff) { #define H_vct_equal "(" S_vct_equal " v1 v2 diff): is element-wise relative-difference of v1 and v2 ever greater than diff?" mus_long_t i, lim; vct *v1, *v2; mus_float_t *d1, *d2; mus_float_t diff, max_diff = 0.0; Xen_check_type(mus_is_vct(uv1), uv1, 1, S_vct_equal, A_VCT); Xen_check_type(mus_is_vct(uv2), uv2, 2, S_vct_equal, A_VCT); Xen_check_type(Xen_is_number(udiff), udiff, 3, S_vct_equal, "a number"); v1 = Xen_to_vct(uv1); d1 = mus_vct_data(v1); v2 = Xen_to_vct(uv2); d2 = mus_vct_data(v2); diff = Xen_real_to_C_double(udiff); lim = mus_vct_length(v1); if (mus_vct_length(v2) < lim) lim = mus_vct_length(v2); for (i = 0; i < lim; i++) { mus_float_t x1, x2, z; x1 = fabs(d1[i]); x2 = fabs(d2[i]); z = fabs(d1[i] - d2[i]); if (x1 > x2) z /= x1; else { if (x2 > 0.0) z /= x2; } if (z > diff) return(Xen_false); if (z > max_diff) max_diff = z; } return(C_double_to_Xen_real(max_diff)); } static void vct_scale(mus_float_t *d, mus_float_t scl, mus_long_t len) { if (scl == 0.0) memset((void *)d, 0, len * sizeof(mus_float_t)); else { if (scl != 1.0) { mus_long_t i, lim4; lim4 = len - 4; i = 0; while (i <= lim4) { d[i++] *= scl; d[i++] *= scl; d[i++] *= scl; d[i++] *= scl; } for (; i < len; i++) d[i] *= scl; } } } static Xen g_vct_scale(Xen obj1, Xen obj2) { #define H_vct_scaleB "(" S_vct_scale " v val): scale each element of v by val: v[i] *= val, returns v" /* Xen_check_type(s7_is_float_vector(obj1), obj1, 1, "float-vector-scale!", "a float-vector"); * return(s7_float_vector_scale(s7, obj1, obj2)); */ vct *v1; Xen_check_type(mus_is_vct(obj1), obj1, 1, S_vct_scale, A_VCT); Xen_check_type(Xen_is_number(obj2), obj2, 2, S_vct_scale, "a number"); v1 = Xen_to_vct(obj1); if (mus_vct_length(v1) == 0) return(obj1); vct_scale(mus_vct_data(v1), Xen_real_to_C_double(obj2), mus_vct_length(v1)); return(obj1); } static Xen g_vct_offset(Xen obj1, Xen obj2) { #define H_vct_offsetB "(" S_vct_offset " v val): add val to each element of v: v[i] += val, returns v" vct *v1; mus_float_t scl; mus_float_t *d; Xen_check_type(mus_is_vct(obj1), obj1, 1, S_vct_offset, A_VCT); Xen_check_type(Xen_is_number(obj2), obj2, 2, S_vct_offset, "a number"); v1 = Xen_to_vct(obj1); if (mus_vct_length(v1) == 0) return(obj1); d = mus_vct_data(v1); scl = Xen_real_to_C_double(obj2); if (scl != 0.0) { mus_long_t i; for (i = 0; i < mus_vct_length(v1); i++) d[i] += scl; } return(obj1); } #if HAVE_SCHEME #define S_vct_spatter "float-vector-spatter" static Xen g_vct_spatter(Xen fv, XEN iv, XEN end, XEN val) { #define H_vct_spatter "(" S_vct_spatter " fv iv end val) places val in fv at locations determined by iv" s7_double *fv_vals; s7_int *iv_vals; s7_double x; int i, len; if (!s7_is_float_vector(fv)) s7_wrong_type_arg_error(s7, S_vct_spatter, 1, fv, "a float-vector"); if (!s7_is_int_vector(iv)) s7_wrong_type_arg_error(s7, S_vct_spatter, 2, iv, "an int-vector"); if (!s7_is_integer(end)) s7_wrong_type_arg_error(s7, S_vct_spatter, 3, end, "an integer"); if (!s7_is_real(val)) s7_wrong_type_arg_error(s7, S_vct_spatter, 4, val, "a real"); fv_vals = s7_float_vector_elements(fv); iv_vals = s7_int_vector_elements(iv); len = s7_integer(end); x = s7_real(val); for (i = 0; i < len; i++) fv_vals[iv_vals[i]] = x; return(val); } #define S_vct_interpolate "float-vector-interpolate" static Xen g_vct_interpolate(Xen fv, Xen start_index, Xen end_index, Xen start_x, XEN incr, XEN val1, XEN val2) { #define H_vct_interpolate "(" S_vct_interpolate " fv index0 index1 x0 dx x1 x2) sets the values of fv between\ index0 and index1 interpolating between x2 and x1 by incrementing x0 by dx" s7_double x0, dx, x1, x2; int i, beg, lim; s7_double *fv_vals; fv_vals = s7_float_vector_elements(fv); if (!s7_is_float_vector(fv)) s7_wrong_type_arg_error(s7, S_vct_interpolate, 1, fv, "a float-vector"); if (!s7_is_integer(start_index)) s7_wrong_type_arg_error(s7, S_vct_spatter, 2, start_index, "an integer"); if (!s7_is_integer(end_index)) s7_wrong_type_arg_error(s7, S_vct_spatter, 3, end_index, "an integer"); if (!s7_is_real(start_x)) s7_wrong_type_arg_error(s7, S_vct_spatter, 4, start_x, "a real"); if (!s7_is_real(incr)) s7_wrong_type_arg_error(s7, S_vct_spatter, 5, incr, "a real"); if (!s7_is_real(val1)) s7_wrong_type_arg_error(s7, S_vct_spatter, 6, val1, "a real"); if (!s7_is_real(val2)) s7_wrong_type_arg_error(s7, S_vct_spatter, 7, val2, "a real"); beg = s7_integer(start_index); lim = s7_integer(end_index); x0 = s7_real(start_x); dx = s7_real(incr); x1 = s7_real(val1); x2 = s7_real(val2); for (i = beg; i < lim; i++, x0 += dx) fv_vals[i] = (x0 * x1) + ((1.0 - x0) * x2); return(val1); } #endif #if (!HAVE_SCHEME) static Xen g_vct_fill(Xen obj1, Xen obj2) { #define H_vct_fillB "(" S_vct_fill " v val): set each element of v to val: v[i] = val, returns v" mus_long_t i; /* unsigned int is much slower */ vct *v1; mus_float_t scl; mus_float_t *d; Xen_check_type(mus_is_vct(obj1), obj1, 1, S_vct_fill, A_VCT); Xen_check_type(Xen_is_number(obj2), obj2, 2, S_vct_fill, "a number"); v1 = Xen_to_vct(obj1); if (mus_vct_length(v1) == 0) return(obj1); d = mus_vct_data(v1); scl = Xen_real_to_C_double(obj2); if (scl == 0.0) memset((void *)d, 0, mus_vct_length(v1) * sizeof(mus_float_t)); else { mus_long_t lim8; lim8 = mus_vct_length(v1) - 8; i = 0; while (i <= lim8) { d[i++] = scl; d[i++] = scl; d[i++] = scl; d[i++] = scl; d[i++] = scl; d[i++] = scl; d[i++] = scl; d[i++] = scl; } for (; i < mus_vct_length(v1); i++) d[i] = scl; } return(obj1); } #endif double mus_vct_peak(vct *v) { mus_float_t val = 0.0, absv; mus_float_t *d; mus_long_t i, lim4, len; len = mus_vct_length(v); if (len == 0) return(0.0); lim4 = len - 4; i = 1; d = mus_vct_data(v); val = fabs(d[0]); while (i <= lim4) { absv = fabs(d[i++]); if (absv > val) val = absv; absv = fabs(d[i++]); if (absv > val) val = absv; absv = fabs(d[i++]); if (absv > val) val = absv; absv = fabs(d[i++]); if (absv > val) val = absv; } for (; i < len; i++) { absv = fabs(d[i]); if (absv > val) val = absv; } return(val); } Xen g_vct_peak(Xen obj) { #define H_vct_peak "(" S_vct_peak " v): max of abs of elements of v" Xen_check_type(mus_is_vct(obj), obj, 1, S_vct_peak, A_VCT); return(C_double_to_Xen_real(mus_vct_peak(Xen_to_vct(obj)))); } #if HAVE_SCHEME #define S_vct_peak_and_location "float-vector-peak-and-location" #else #define S_vct_peak_and_location "vct-peak-and-location" #endif static Xen g_vct_peak_and_location(Xen obj) { #define H_vct_peak_and_location "(" S_vct_peak_and_location " v): max of abs of elements of v and its position in v" mus_float_t val = 0.0; mus_long_t i, loc = 0; vct *v; mus_float_t *d; Xen_check_type(mus_is_vct(obj), obj, 1, S_vct_peak_and_location, "a " S_vct); v = Xen_to_vct(obj); d = mus_vct_data(v); for (i = 0; i < mus_vct_length(v); i++) { mus_float_t absv; absv = fabs(d[i]); if (absv > val) { val = absv; loc = i; } } return(Xen_list_2(C_double_to_Xen_real(val), C_int_to_Xen_integer(loc))); } static Xen g_vct_subseq(Xen vobj, Xen start, Xen end, Xen newv) { #define H_vct_subseq "(" S_vct_subseq " v start :optional end vnew): v[start..end], placed in vnew if given or new " S_vct vct *vold, *vnew; mus_float_t *dnew, *dold; Xen res; mus_long_t i, old_len, new_len, j, istart; Xen_check_type(mus_is_vct(vobj), vobj, 1, S_vct_subseq, A_VCT); Xen_check_type(Xen_is_llong(start), start, 2, S_vct_subseq, "an integer"); Xen_check_type(Xen_is_llong_or_unbound(end), end, 3, S_vct_subseq, "an integer"); istart = Xen_llong_to_C_llong(start); if (istart < 0) Xen_out_of_range_error(S_vct_subseq, 2, start, "start < 0?"); vold = Xen_to_vct(vobj); old_len = mus_vct_length(vold); if (Xen_is_llong(end)) { mus_long_t iend; iend = Xen_llong_to_C_llong(end); if (iend < istart) Xen_out_of_range_error(S_vct_subseq, 3, end, "end < start?"); if (iend > old_len) Xen_out_of_range_error(S_vct_subseq, 3, end, "end > vct length?"); new_len = iend - istart + 1; } else new_len = old_len - istart; if (new_len <= 0) return(Xen_false); if (mus_is_vct(newv)) res = newv; else res = xen_make_vct(new_len, (mus_float_t *)calloc(new_len, sizeof(mus_float_t))); vnew = Xen_to_vct(res); if (new_len > mus_vct_length(vnew)) new_len = mus_vct_length(vnew); dnew = mus_vct_data(vnew); dold = mus_vct_data(vold); for (i = istart, j = 0; (j < new_len) && (i < old_len); i++, j++) dnew[j] = dold[i]; return(res); } Xen xen_list_to_vct(Xen lst) { #define H_list_to_vct "(" S_list_to_vct " lst): returns a new " S_vct " filled with elements of list lst" mus_long_t len = 0, i; vct *v; mus_float_t *d; Xen scv, lst1; Xen_check_type(Xen_is_list(lst), lst, 1, S_list_to_vct, "a list"); len = Xen_list_length(lst); if (len > 0) scv = xen_make_vct(len, (mus_float_t *)calloc(len, sizeof(mus_float_t))); else scv = xen_make_vct(0, NULL); v = Xen_to_vct(scv); d = mus_vct_data(v); for (i = 0, lst1 = Xen_copy_arg(lst); i < len; i++, lst1 = Xen_cdr(lst1)) { if (Xen_is_number(Xen_car(lst1))) d[i] = (mus_float_t)Xen_real_to_C_double(Xen_car(lst1)); else Xen_wrong_type_arg_error(S_list_to_vct, i, Xen_car(lst1), "a number"); } return(scv); } Xen mus_array_to_list(mus_float_t *arr, mus_long_t i, mus_long_t len) { if (i < (len - 1)) return(Xen_cons(C_double_to_Xen_real(arr[i]), mus_array_to_list(arr, i + 1, len))); else return(Xen_cons(C_double_to_Xen_real(arr[i]), Xen_empty_list)); } #if (!HAVE_SCHEME) static Xen g_vct(Xen args) { #define H_vct "(" S_vct " args...): returns a new " S_vct " with args as contents; same as " S_list_to_vct ": (" S_vct " 1 2 3)" return(xen_list_to_vct(args)); } static Xen g_vct_to_list(Xen vobj) { #define H_vct_to_list "(" S_vct_to_list " v): returns a new list with elements of " S_vct " v" vct *v; Xen_check_type(mus_is_vct(vobj), vobj, 1, S_vct_to_list, A_VCT); v = Xen_to_vct(vobj); if (mus_vct_length(v) == 0) return(Xen_empty_list); return(mus_array_to_list(mus_vct_data(v), 0, mus_vct_length(v))); } static Xen g_vector_to_vct(Xen vect) { #define H_vector_to_vct "(" S_vector_to_vct " vect): returns a new " S_vct " with the elements of vector vect" mus_long_t len, i; vct *v; mus_float_t *d; Xen scv; Xen_check_type(Xen_is_vector(vect), vect, 1, S_vector_to_vct, "a vector"); len = (mus_long_t)Xen_vector_length(vect); if (len > 0) scv = xen_make_vct(len, (mus_float_t *)calloc(len, sizeof(mus_float_t))); else scv = xen_make_vct(0, NULL); v = Xen_to_vct(scv); d = mus_vct_data(v); for (i = 0; i < len; i++) d[i] = (mus_float_t)Xen_real_to_C_double(Xen_vector_ref(vect, i)); return(scv); } static Xen g_vct_to_vector(Xen vobj) { #define H_vct_to_vector "(" S_vct_to_vector " v): returns a new vector with the elements of " S_vct vct *v; mus_float_t *d; mus_long_t i, len; Xen new_vect; Xen_check_type(mus_is_vct(vobj), vobj, 1, S_vct_to_vector, A_VCT); v = Xen_to_vct(vobj); len = mus_vct_length(v); new_vect = Xen_make_vector(len, C_double_to_Xen_real(0.0)); #if HAVE_RUBY && HAVE_RB_GC_DISABLE rb_gc_disable(); /* uh oh -- gc is triggered by C_double_to_Xen_real causing segfault, even if we * protect (via Xen_protect_from_gc) new_vect -- I guess the double currently * being created is causing the trouble? */ #endif d = mus_vct_data(v); for (i = 0; i < len; i++) Xen_vector_set(new_vect, i, C_double_to_Xen_real(d[i])); #if HAVE_RUBY && HAVE_RB_GC_DISABLE rb_gc_enable(); #endif return(new_vect); } static Xen g_vct_reverse(Xen vobj, Xen size) { #define H_vct_reverse "(" S_vct_reverse " v len): in-place reversal of " S_vct " contents" vct *v; mus_float_t *d; mus_long_t i, j, len = -1; Xen_check_type(mus_is_vct(vobj), vobj, 1, S_vct_reverse, A_VCT); Xen_check_type(Xen_is_llong_or_unbound(size), size, 2, S_vct_reverse, "an integer"); v = Xen_to_vct(vobj); if (Xen_is_llong(size)) len = Xen_llong_to_C_llong(size); if ((len <= 0) || (len > mus_vct_length(v))) len = mus_vct_length(v); if (len == 1) return(vobj); d = mus_vct_data(v); for (i = 0, j = len - 1; i < j; i++, j--) { mus_float_t temp; temp = d[i]; d[i] = d[j]; d[j] = temp; } return(vobj); } #endif #if HAVE_SCHEME #define S_vct_max "float-vector-max" #define S_vct_min "float-vector-min" #else #define S_vct_max "vct-max" #define S_vct_min "vct-min" #endif static mus_float_t vct_max(mus_float_t *d, mus_long_t len) { mus_long_t i; mus_float_t mx; mx = d[0]; for (i = 1; i < len; i++) if (d[i] > mx) mx = d[i]; return(mx); } static Xen g_vct_max(Xen vobj) { #define H_vct_max "(" S_vct_max " v): returns the maximum element of " S_vct vct *v; mus_long_t len; Xen_check_type(mus_is_vct(vobj), vobj, 1, S_vct_max, A_VCT); v = Xen_to_vct(vobj); len = mus_vct_length(v); if (len > 0) return(C_double_to_Xen_real(vct_max(mus_vct_data(v), len))); return(C_double_to_Xen_real(0.0)); } static mus_float_t vct_min(mus_float_t *d, mus_long_t len) { mus_long_t i; mus_float_t mx; mx = d[0]; for (i = 1; i < len; i++) if (d[i] < mx) mx = d[i]; return(mx); } static Xen g_vct_min(Xen vobj) { #define H_vct_min "(" S_vct_min " v): returns the minimum element of " S_vct vct *v; mus_long_t len; Xen_check_type(mus_is_vct(vobj), vobj, 1, S_vct_min, A_VCT); v = Xen_to_vct(vobj); len = mus_vct_length(v); if (len > 0) return(C_double_to_Xen_real(vct_min(mus_vct_data(v), len))); return(C_double_to_Xen_real(0.0)); } static Xen g_vct_times(Xen obj1, Xen obj2) { #define H_vct_times "(" S_vct_times " obj1 obj2): either " S_vct_multiply " or " S_vct_scale ", depending on the types of its arguments" if (mus_is_vct(obj1)) { if (mus_is_vct(obj2)) return(g_vct_multiply(obj1, obj2)); return(g_vct_scale(obj1, obj2)); } return(g_vct_scale(obj2, obj1)); } static Xen g_vct_plus(Xen obj1, Xen obj2) { #define H_vct_plus "(" S_vct_plus " obj1 obj2): either " S_vct_add " or " S_vct_offset ", depending on the types of its arguments" if (mus_is_vct(obj1)) { if (mus_is_vct(obj2)) return(g_vct_add(obj1, obj2, Xen_undefined)); return(g_vct_offset(obj1, obj2)); } return(g_vct_offset(obj2, obj1)); } #if HAVE_RUBY static Xen g_vct_each(Xen obj) { mus_long_t i; vct *v; mus_float_t *d; v = Xen_to_vct(obj); d = mus_vct_data(v); for (i = 0; i < mus_vct_length(v); i++) rb_yield(C_double_to_Xen_real(d[i])); return(obj); } static Xen g_vct_compare(Xen vr1, Xen vr2) { if ((mus_is_vct(vr1)) && (mus_is_vct(vr2))) { mus_long_t i, len; vct *v1, *v2; mus_float_t *d1, *d2; v1 = Xen_to_vct(vr1); v2 = Xen_to_vct(vr2); d1 = mus_vct_data(v1); d2 = mus_vct_data(v2); len = mus_vct_length(v1); if (len > mus_vct_length(v2)) len = mus_vct_length(v2); for (i = 0; i < len; i++) if (d1[i] < d2[i]) return(C_int_to_Xen_integer(-1)); else if (d1[i] > d2[i]) return(C_int_to_Xen_integer(1)); len = mus_vct_length(v1) - mus_vct_length(v2); if (len == 0) return(C_int_to_Xen_integer(0)); if (len > 0) return(C_int_to_Xen_integer(1)); } return(C_int_to_Xen_integer(-1)); } static Xen g_rb_make_vct(int argc, Xen *argv, Xen self) { mus_long_t size; Xen len, filler; rb_scan_args(argc, argv, "11", &len, &filler); Xen_check_type(Xen_is_llong(len), len, 1, "Vct.new", "an integer"); size = Xen_llong_to_C_llong(len); if (size <= 0) Xen_out_of_range_error("Vct.new", 1, len, "len <= 0?"); if (Xen_is_number(filler)) return(g_vct_fill(xen_make_vct(size, (mus_float_t *)calloc(size, sizeof(mus_float_t))), filler)); if (rb_block_given_p()) { mus_long_t i; mus_float_t *buffer = (mus_float_t *)calloc(size, sizeof(mus_float_t)); for (i = 0; i < size; i++) { buffer[i] = Xen_real_to_C_double(rb_yield(C_int_to_Xen_integer(i))); } return xen_make_vct(size, buffer); } return(xen_make_vct(size, (mus_float_t *)calloc(size, sizeof(mus_float_t)))); } static Xen g_vct_map(Xen obj) { if (rb_block_given_p()) { mus_long_t i; vct *v; mus_float_t *d; v = Xen_to_vct(obj); d = mus_vct_data(v); mus_float_t *buffer = (mus_float_t *)calloc(mus_vct_length(v), sizeof(mus_float_t)); for (i = 0; i < mus_vct_length(v); i++) buffer[i] = Xen_real_to_C_double(rb_yield(C_double_to_Xen_real(d[i]))); return xen_make_vct(mus_vct_length(v), buffer); } return obj; } static Xen g_vct_map_store(Xen obj) { if (rb_block_given_p()) { mus_long_t i; vct *v; mus_float_t *d; v = Xen_to_vct(obj); d = mus_vct_data(v); for (i = 0; i < mus_vct_length(v); i++) d[i] = Xen_real_to_C_double(rb_yield(C_double_to_Xen_real(d[i]))); } return obj; } /* v1.add!(v2[,offset=0]) destructive */ static Xen rb_vct_add(int argc, Xen *argv, Xen obj1) { Xen obj2, offs; rb_scan_args(argc, argv, "11", &obj2, &offs); return g_vct_add(obj1, obj2, (argc == 2) ? offs : Xen_undefined); } /* v1.add(v2[,offset=0]) returns new vct */ static Xen rb_vct_add_cp(int argc, Xen *argv, Xen obj1) { Xen obj2, offs; rb_scan_args(argc, argv, "11", &obj2, &offs); return g_vct_add(g_vct_copy(obj1), obj2, (argc == 2) ? offs : Xen_undefined); } /* v1.subtract(v2) returns new vct */ static Xen rb_vct_subtract_cp(Xen obj1, Xen obj2) { return g_vct_subtract(g_vct_copy(obj1), obj2); } static Xen rb_vct_offset_cp(Xen obj, Xen scl) { return g_vct_offset(g_vct_copy(obj), scl); } static Xen rb_vct_multiply_cp(Xen obj1, Xen obj2) { return g_vct_multiply(g_vct_copy(obj1), obj2); } static Xen rb_vct_scale_cp(Xen obj, Xen scl) { return g_vct_scale(g_vct_copy(obj), scl); } /* destructive */ static Xen rb_vct_move(int argc, Xen *argv, Xen obj) { Xen vnew, old, backward; rb_scan_args(argc, argv, "21", &vnew, &old, &backward); return g_vct_move(obj, vnew, old, (argc == 3) ? backward : Xen_undefined); } /* returns new vct */ static Xen rb_vct_move_cp(int argc, Xen *argv, Xen obj) { Xen vnew, old, backward; rb_scan_args(argc, argv, "21", &vnew, &old, &backward); return g_vct_move(g_vct_copy(obj), vnew, old, (argc == 3) ? backward : Xen_undefined); } static Xen rb_vct_subseq(int argc, Xen *argv, Xen obj) { Xen start, end, vnew; rb_scan_args(argc, argv, "12", &start, &end, &vnew); return g_vct_subseq(obj, start, (argc > 1) ? end :Xen_undefined, (argc > 2) ? vnew : Xen_undefined); } /* destructive */ static Xen rb_vct_reverse(int argc, Xen *argv, Xen obj) { Xen len; rb_scan_args(argc, argv, "01", &len); return g_vct_reverse(obj, (argc > 0) ? len : Xen_undefined); } /* returns new vct */ static Xen rb_vct_reverse_cp(int argc, Xen *argv, Xen obj) { Xen len; rb_scan_args(argc, argv, "01", &len); return g_vct_reverse(g_vct_copy(obj), (argc > 0) ? len : Xen_undefined); } static Xen rb_vct_first(Xen obj) { return g_vct_ref(obj, C_int_to_Xen_integer(0)); } static Xen rb_set_vct_first(Xen obj, Xen val) { return g_vct_set(obj, C_int_to_Xen_integer(0), val); } static Xen rb_vct_last(Xen obj) { return g_vct_ref(obj, C_int_to_Xen_integer(mus_vct_length(Xen_to_vct(obj)) - 1)); } static Xen rb_set_vct_last(Xen obj, Xen val) { return g_vct_set(obj, C_int_to_Xen_integer(mus_vct_length(Xen_to_vct(obj)) - 1), val); } #endif #if HAVE_FORTH static void ficl_values_to_vct(ficlVm *vm) { #define h_values_to_vct "( len-floats len -- vct ) \ Returns a new vct of length LEN with len items found on stack.\n\ 0.5 0.3 0.1 3 >vct .g => #" long size; FICL_STACK_CHECK(vm->dataStack, 1, 0); size = ficlStackPopInteger(vm->dataStack); if (size > 0) { mus_float_t *data = (mus_float_t *)calloc(size, sizeof(mus_float_t)); if (data) { long i; FICL_STACK_CHECK(vm->dataStack, size, 1); for (i = size - 1; i >= 0; i--) data[i] = ficlStackPop2Float(vm->dataStack); ficlStackPushUnsigned(vm->dataStack, xen_make_vct(size, data)); } else fth_throw(FTH_SYSTEM_ERROR, "cannot create Vct"); } else ficlStackPushUnsigned(vm->dataStack, fth_false()); } static void ficl_begin_vct(ficlVm *vm) { #define h_begin_vct "( -- ) \ Creates a vct with contents between `vct(' and closing paren `)'.\n\ vct( 0.5 0.3 0.1 ) .g => #" fth_begin_values_to_obj(vm, (char *)">vct", FTH_FALSE); } #endif #if HAVE_SCHEME #define PF_TO_RF(CName, Cfnc) \ static s7_double CName ## _rf_a(s7_scheme *sc, s7_pointer **p) \ { \ s7_pf_t f; \ s7_pointer x; \ f = (s7_pf_t)(**p); (*p)++; \ x = f(sc, p); \ return(Cfnc); \ } \ static s7_rf_t CName ## _rf(s7_scheme *sc, s7_pointer expr) \ { \ if ((s7_is_pair(s7_cdr(expr))) && (s7_is_null(sc, s7_cddr(expr))) && \ (s7_arg_to_pf(sc, s7_cadr(expr)))) \ return(CName ## _rf_a); \ return(NULL); \ } static s7_double c_vct_max(s7_scheme *sc, s7_pointer x) { s7_int len; if (!s7_is_float_vector(x)) s7_wrong_type_arg_error(sc, S_vct_max, 1, x, "a float-vector"); len = s7_vector_length(x); if (len == 0) return(0.0); return(vct_max(s7_float_vector_elements(x), len)); } PF_TO_RF(float_vector_max, c_vct_max(sc, x)) static s7_double c_vct_min(s7_scheme *sc, s7_pointer x) { s7_int len; if (!s7_is_float_vector(x)) s7_wrong_type_arg_error(sc, S_vct_min, 1, x, "a float-vector"); len = s7_vector_length(x); if (len == 0) return(0.0); return(vct_min(s7_float_vector_elements(x), len)); } PF_TO_RF(float_vector_min, c_vct_min(sc, x)) PF_TO_RF(float_vector_peak, mus_vct_peak(x)) #define PF2_TO_PF(CName, Cfnc) \ static s7_pointer CName ## _pf_a(s7_scheme *sc, s7_pointer **p) \ { \ s7_pf_t f; \ s7_pointer x, y; \ f = (s7_pf_t)(**p); (*p)++; \ x = f(sc, p); \ f = (s7_pf_t)(**p); (*p)++; \ y = f(sc, p); \ return(Cfnc); \ } \ static s7_pf_t CName ## _pf(s7_scheme *sc, s7_pointer expr) \ { \ if ((s7_is_pair(s7_cdr(expr))) && (s7_is_pair(s7_cddr(expr))) && (s7_is_null(sc, s7_cdddr(expr))) && \ (s7_arg_to_pf(sc, s7_cadr(expr))) && \ (s7_arg_to_pf(sc, s7_caddr(expr)))) \ return(CName ## _pf_a); \ return(NULL); \ } static s7_pointer c_vct_add(s7_scheme *sc, s7_pointer x, s7_pointer y) { s7_int len1, lim; if (!s7_is_float_vector(x)) s7_wrong_type_arg_error(sc, S_vct_add, 1, x, "a float-vector"); if (!s7_is_float_vector(y)) s7_wrong_type_arg_error(sc, S_vct_add, 2, y, "a float-vector"); len1 = s7_vector_length(x); lim = s7_vector_length(y); if (lim > len1) lim = len1; if (lim == 0) return(x); vct_add(s7_float_vector_elements(x), s7_float_vector_elements(y), lim); return(x); } PF2_TO_PF(float_vector_add, c_vct_add(sc, x, y)) static s7_pointer c_vct_subtract(s7_scheme *sc, s7_pointer x, s7_pointer y) { s7_int i, len1, lim; s7_double *fx, *fy; if (!s7_is_float_vector(x)) s7_wrong_type_arg_error(sc, S_vct_subtract, 1, x, "a float-vector"); if (!s7_is_float_vector(y)) s7_wrong_type_arg_error(sc, S_vct_subtract, 2, y, "a float-vector"); len1 = s7_vector_length(x); lim = s7_vector_length(y); if (lim > len1) lim = len1; if (lim == 0) return(x); fx = s7_float_vector_elements(x); fy = s7_float_vector_elements(y); for (i = 0; i < lim; i++) fx[i] -= fy[i]; return(x); } PF2_TO_PF(float_vector_subtract, c_vct_subtract(sc, x, y)) static s7_pointer c_vct_multiply(s7_scheme *sc, s7_pointer x, s7_pointer y) { s7_int i, len1, lim; s7_double *fx, *fy; if (!s7_is_float_vector(x)) s7_wrong_type_arg_error(sc, S_vct_multiply, 1, x, "a float-vector"); if (!s7_is_float_vector(y)) s7_wrong_type_arg_error(sc, S_vct_multiply, 2, y, "a float-vector"); len1 = s7_vector_length(x); lim = s7_vector_length(y); if (lim > len1) lim = len1; if (lim == 0) return(x); fx = s7_float_vector_elements(x); fy = s7_float_vector_elements(y); for (i = 0; i < lim; i++) fx[i] *= fy[i]; return(x); } PF2_TO_PF(float_vector_multiply, c_vct_multiply(sc, x, y)) #define PRF_TO_PF(CName, Cfnc) \ static s7_pointer CName ## _pf_a(s7_scheme *sc, s7_pointer **p) \ { \ s7_pf_t f; \ s7_rf_t r; \ s7_pointer x; \ s7_double y; \ f = (s7_pf_t)(**p); (*p)++; \ x = f(sc, p); \ r = (s7_rf_t)(**p); (*p)++; \ y = r(sc, p); \ return(Cfnc); \ } \ static s7_pf_t CName ## _pf(s7_scheme *sc, s7_pointer expr) \ { \ if ((s7_is_pair(s7_cdr(expr))) && (s7_is_pair(s7_cddr(expr))) && (s7_is_null(sc, s7_cdddr(expr))) && \ (s7_arg_to_pf(sc, s7_cadr(expr))) && \ (s7_arg_to_rf(sc, s7_caddr(expr)))) \ return(CName ## _pf_a); \ return(NULL); \ } static s7_pointer c_vct_scale(s7_scheme *sc, s7_pointer x, s7_double y) { s7_int len; if (!s7_is_float_vector(x)) s7_wrong_type_arg_error(sc, S_vct_scale, 1, x, "a float-vector"); len = s7_vector_length(x); if (len == 0) return(x); vct_scale(s7_float_vector_elements(x), y, len); return(x); } PRF_TO_PF(float_vector_scale, c_vct_scale(sc, x, y)) static s7_pointer c_vct_offset(s7_scheme *sc, s7_pointer x, s7_double y) { s7_int i, len; s7_double *fx; if (!s7_is_float_vector(x)) s7_wrong_type_arg_error(sc, S_vct_offset, 1, x, "a float-vector"); len = s7_vector_length(x); if (len == 0) return(x); fx = s7_float_vector_elements(x); for (i = 0; i < len; i++) fx[i] += y; return(x); } PRF_TO_PF(float_vector_offset, c_vct_offset(sc, x, y)) static s7_pointer vct_abs_pf_a(s7_scheme *sc, s7_pointer **p) { s7_pf_t f; s7_pointer x; s7_int i, len; s7_double *fx; f = (s7_pf_t)(**p); (*p)++; x = f(sc, p); if (!s7_is_float_vector(x)) s7_wrong_type_arg_error(sc, S_vct_abs, 1, x, "a float-vector"); len = s7_vector_length(x); if (len == 0) return(x); fx = s7_float_vector_elements(x); for (i = 0; i < len; i++) fx[i] = fabs(fx[i]); return(x); } static s7_pf_t float_vector_abs_pf(s7_scheme *sc, s7_pointer expr) { if ((s7_is_pair(s7_cdr(expr))) && (s7_is_null(sc, s7_cddr(expr))) && (s7_arg_to_pf(sc, s7_cadr(expr)))) return(vct_abs_pf_a); \ return(NULL); } #endif #if (!HAVE_SCHEME) Xen_wrap_2_optional_args(g_make_vct_w, g_make_vct) Xen_wrap_2_args(g_vct_fill_w, g_vct_fill) Xen_wrap_any_args(g_vct_w, g_vct) Xen_wrap_1_arg(g_vct_length_w, g_vct_length) Xen_wrap_2_optional_args(g_vct_reverse_w, g_vct_reverse) Xen_wrap_1_arg(g_vct_to_list_w, g_vct_to_list) Xen_wrap_1_arg(g_list_to_vct_w, xen_list_to_vct) Xen_wrap_1_arg(g_vector_to_vct_w, g_vector_to_vct) Xen_wrap_1_arg(g_vct_to_vector_w, g_vct_to_vector) Xen_wrap_1_arg(g_is_vct_w, g_is_vct) Xen_wrap_2_args(g_vct_ref_w, g_vct_ref) Xen_wrap_3_args(g_vct_set_w, g_vct_set) #endif Xen_wrap_1_arg(g_vct_copy_w, g_vct_copy) Xen_wrap_2_args(g_vct_multiply_w, g_vct_multiply) Xen_wrap_2_args(g_vct_scale_w, g_vct_scale) Xen_wrap_1_arg(g_vct_abs_w, g_vct_abs) Xen_wrap_3_optional_args(g_vct_add_w, g_vct_add) Xen_wrap_2_args(g_vct_subtract_w, g_vct_subtract) Xen_wrap_2_args(g_vct_offset_w, g_vct_offset) Xen_wrap_1_arg(g_vct_peak_w, g_vct_peak) Xen_wrap_3_args(g_vct_equal_w, g_vct_equal) Xen_wrap_1_arg(g_vct_peak_and_location_w, g_vct_peak_and_location) Xen_wrap_4_optional_args(g_vct_move_w, g_vct_move) Xen_wrap_4_optional_args(g_vct_subseq_w, g_vct_subseq) Xen_wrap_1_arg(g_vct_to_readable_string_w, g_vct_to_readable_string) Xen_wrap_2_args(g_vct_times_w, g_vct_times) Xen_wrap_2_args(g_vct_plus_w, g_vct_plus) Xen_wrap_1_arg(g_vct_max_w, g_vct_max) Xen_wrap_1_arg(g_vct_min_w, g_vct_min) #if HAVE_SCHEME Xen_wrap_4_args(g_vct_spatter_w, g_vct_spatter) Xen_wrap_7_args(g_vct_interpolate_w, g_vct_interpolate) #endif void mus_vct_init(void) { #if HAVE_SCHEME s7_pointer pl_ff, pl_rf, pl_fff, pl_fffi, pl_ffr, pl_pf, pl_bffr, pl_ftt, pl_ffii, pl_ffiif, pl_sf; #else vct_tag = Xen_make_object_type("Vct", sizeof(vct)); /* for ruby and forth, I think we can define Frame, SoundData, and Mixer to be Vct's with * some handlers for the channel arg. Then nothing in the *.rb|fs file has to change * except all the deprecated names like "region-frames" -> framples. * * Not sure how to do this -- is it "alias" in Ruby? */ #endif #if HAVE_FORTH fth_set_object_inspect(vct_tag, print_vct); fth_set_object_dump(vct_tag, g_vct_to_readable_string); fth_set_object_to_array(vct_tag, g_vct_to_vector); fth_set_object_copy(vct_tag, g_vct_copy); fth_set_object_value_ref(vct_tag, g_vct_ref); fth_set_object_value_set(vct_tag, g_vct_set); fth_set_object_equal(vct_tag, equalp_vct); fth_set_object_length(vct_tag, g_vct_length); fth_set_object_free(vct_tag, free_vct); fth_set_object_apply(vct_tag, Xen_procedure_cast g_vct_ref, 1, 0, 0); FTH_PRIM(FTH_FICL_DICT(), (char *)">vct", ficl_values_to_vct, h_values_to_vct); FTH_PRIM(FTH_FICL_DICT(), (char *)"vct(", ficl_begin_vct, h_begin_vct); Xen_eval_C_string("start-prefixes : vct( vct( ; end-prefixes"); #endif #if HAVE_RUBY rb_include_module(vct_tag, rb_mComparable); rb_include_module(vct_tag, rb_mEnumerable); rb_define_method(vct_tag, "to_s", Xen_procedure_cast print_vct, 0); rb_define_method(vct_tag, "eql?", Xen_procedure_cast equalp_vct, 1); rb_define_method(vct_tag, "[]", Xen_procedure_cast g_vct_ref, 1); rb_define_method(vct_tag, "[]=", Xen_procedure_cast g_vct_set, 2); rb_define_method(vct_tag, "length", Xen_procedure_cast g_vct_length, 0); rb_define_method(vct_tag, "each", Xen_procedure_cast g_vct_each, 0); rb_define_method(vct_tag, "<=>", Xen_procedure_cast g_vct_compare, 1); rb_define_singleton_method(vct_tag, "new", Xen_procedure_cast g_rb_make_vct, -1); rb_define_method(vct_tag, "map", Xen_procedure_cast g_vct_map, 0); rb_define_method(vct_tag, "map!", Xen_procedure_cast g_vct_map_store, 0); rb_define_method(vct_tag, "to_a", Xen_procedure_cast g_vct_to_vector, 0); rb_define_method(rb_cArray, "to_vct", Xen_procedure_cast g_vector_to_vct, 0); rb_define_method(vct_tag, "to_str", Xen_procedure_cast g_vct_to_readable_string, 0); rb_define_method(vct_tag, "dup", Xen_procedure_cast g_vct_copy, 0); rb_define_method(vct_tag, "peak", Xen_procedure_cast g_vct_peak, 0); rb_define_method(vct_tag, "add", Xen_procedure_cast rb_vct_add_cp, -1); rb_define_method(vct_tag, "add!", Xen_procedure_cast rb_vct_add, -1); rb_define_method(vct_tag, "subtract", Xen_procedure_cast rb_vct_subtract_cp, 1); rb_define_method(vct_tag, "subtract!", Xen_procedure_cast g_vct_subtract, 1); rb_define_method(vct_tag, "offset", Xen_procedure_cast rb_vct_offset_cp, 1); rb_define_method(vct_tag, "offset!", Xen_procedure_cast g_vct_offset, 1); rb_define_method(vct_tag, "multiply", Xen_procedure_cast rb_vct_multiply_cp, 1); rb_define_method(vct_tag, "multiply!", Xen_procedure_cast g_vct_multiply, 1); rb_define_method(vct_tag, "scale", Xen_procedure_cast rb_vct_scale_cp, 1); rb_define_method(vct_tag, "scale!", Xen_procedure_cast g_vct_scale, 1); rb_define_method(vct_tag, "fill", Xen_procedure_cast g_vct_fill, 1); rb_define_method(vct_tag, "move", Xen_procedure_cast rb_vct_move_cp, -1); rb_define_method(vct_tag, "move!", Xen_procedure_cast rb_vct_move, -1); rb_define_method(vct_tag, "subseq", Xen_procedure_cast rb_vct_subseq, -1); rb_define_method(vct_tag, "reverse", Xen_procedure_cast rb_vct_reverse_cp, -1); rb_define_method(vct_tag, "reverse!", Xen_procedure_cast rb_vct_reverse, -1); rb_define_method(vct_tag, "first", Xen_procedure_cast rb_vct_first, 0); rb_define_method(vct_tag, "first=", Xen_procedure_cast rb_set_vct_first, 1); rb_define_method(vct_tag, "last", Xen_procedure_cast rb_vct_last, 0); rb_define_method(vct_tag, "last=", Xen_procedure_cast rb_set_vct_last, 1); #endif #if HAVE_SCHEME { s7_pointer s, i, p, b, r, f, t; s = s7_make_symbol(s7, "string?"); i = s7_make_symbol(s7, "integer?"); p = s7_make_symbol(s7, "pair?"); r = s7_make_symbol(s7, "real?"); b = s7_make_symbol(s7, "boolean?"); f = s7_make_symbol(s7, "float-vector?"); t = s7_t(s7); pl_rf = s7_make_signature(s7, 2, r, f); pl_ff = s7_make_signature(s7, 2, f, f); pl_sf = s7_make_signature(s7, 2, s, f); pl_pf = s7_make_signature(s7, 2, p, f); pl_ftt = s7_make_signature(s7, 3, f, t, t); pl_fff = s7_make_signature(s7, 3, f, f, f); pl_ffr = s7_make_signature(s7, 3, f, f, r); pl_bffr = s7_make_signature(s7, 4, b, f, f, r); pl_fffi = s7_make_signature(s7, 4, f, f, f, i); pl_ffii = s7_make_signature(s7, 4, f, f, i, i); pl_ffiif = s7_make_signature(s7, 5, f, f, i, i, f); } #endif Xen_define_typed_procedure(S_vct_multiply, g_vct_multiply_w, 2, 0, 0, H_vct_multiplyB, pl_fff); Xen_define_typed_procedure(S_vct_add, g_vct_add_w, 2, 1, 0, H_vct_addB, pl_fffi); Xen_define_typed_procedure(S_vct_subtract, g_vct_subtract_w, 2, 0, 0, H_vct_subtractB, pl_fff); Xen_define_typed_procedure(S_vct_offset, g_vct_offset_w, 2, 0, 0, H_vct_offsetB, pl_ffr); Xen_define_typed_procedure(S_vct_peak, g_vct_peak_w, 1, 0, 0, H_vct_peak, pl_rf); Xen_define_typed_procedure(S_vct_peak_and_location, g_vct_peak_and_location_w, 1, 0, 0, H_vct_peak_and_location, pl_pf); Xen_define_typed_procedure(S_vct_move, g_vct_move_w, 3, 1, 0, H_vct_moveB, pl_ffii); Xen_define_typed_procedure(S_vct_subseq, g_vct_subseq_w, 2, 2, 0, H_vct_subseq, pl_ffiif); Xen_define_typed_procedure(S_vct_copy, g_vct_copy_w, 1, 0, 0, H_vct_copy, pl_ff); #if HAVE_FORTH Xen_define_dilambda(S_vct_ref, g_vct_ref_w, H_vct_ref, "set-" S_vct_ref, g_vct_set_w, 2, 0, 3, 0); #else #if (!HAVE_SCHEME) Xen_define_procedure(S_vct_ref, g_vct_ref_w, 2, 0, 0, H_vct_ref); #endif #endif Xen_define_typed_procedure(S_vct_to_string, g_vct_to_readable_string_w, 1, 0, 0, H_vct_to_string, pl_sf); Xen_define_typed_procedure(S_vct_times, g_vct_times_w, 2, 0, 0, H_vct_times, pl_ftt); Xen_define_typed_procedure(S_vct_plus, g_vct_plus_w, 2, 0, 0, H_vct_plus, pl_ftt); Xen_define_typed_procedure(S_vct_max, g_vct_max_w, 1, 0, 0, H_vct_max, pl_rf); Xen_define_typed_procedure(S_vct_min, g_vct_min_w, 1, 0, 0, H_vct_min, pl_rf); Xen_define_typed_procedure(S_vct_scale, g_vct_scale_w, 2, 0, 0, H_vct_scaleB, pl_ftt); Xen_define_typed_procedure(S_vct_abs, g_vct_abs_w, 1, 0, 0, H_vct_absB, pl_ff); Xen_define_typed_procedure(S_vct_equal, g_vct_equal_w, 3, 0, 0, H_vct_equal, pl_bffr); #if (!HAVE_SCHEME) Xen_define_procedure(S_vct_set, g_vct_set_w, 3, 0, 0, H_vct_setB); Xen_define_procedure(S_is_vct, g_is_vct_w, 1, 0, 0, H_is_vct); Xen_define_procedure(S_vct_fill, g_vct_fill_w, 2, 0, 0, H_vct_fillB); Xen_define_procedure(S_vct, g_vct_w, 0, 0, 1, H_vct); Xen_define_procedure(S_vct_length, g_vct_length_w, 1, 0, 0, H_vct_length); Xen_define_procedure(S_vct_reverse, g_vct_reverse_w, 1, 1, 0, H_vct_reverse); Xen_define_procedure(S_vct_to_list, g_vct_to_list_w, 1, 0, 0, H_vct_to_list); Xen_define_procedure(S_list_to_vct, g_list_to_vct_w, 1, 0, 0, H_list_to_vct); Xen_define_procedure(S_vector_to_vct, g_vector_to_vct_w, 1, 0, 0, H_vector_to_vct); Xen_define_procedure(S_vct_to_vector, g_vct_to_vector_w, 1, 0, 0, H_vct_to_vector); Xen_define_procedure(S_make_vct, g_make_vct_w, 1, 1, 0, H_make_vct); #else Xen_define_procedure(S_vct_spatter, g_vct_spatter_w, 4, 0, 0, H_vct_spatter); Xen_define_procedure(S_vct_interpolate, g_vct_interpolate_w, 7, 0, 0, H_vct_interpolate); s7_pf_set_function(s7_name_to_value(s7, S_vct_add), float_vector_add_pf); s7_pf_set_function(s7_name_to_value(s7, S_vct_subtract), float_vector_subtract_pf); s7_pf_set_function(s7_name_to_value(s7, S_vct_multiply), float_vector_multiply_pf); s7_pf_set_function(s7_name_to_value(s7, S_vct_scale), float_vector_scale_pf); s7_pf_set_function(s7_name_to_value(s7, S_vct_offset), float_vector_offset_pf); s7_pf_set_function(s7_name_to_value(s7, S_vct_abs), float_vector_abs_pf); s7_rf_set_function(s7_name_to_value(s7, S_vct_min), float_vector_min_rf); s7_rf_set_function(s7_name_to_value(s7, S_vct_max), float_vector_max_rf); s7_rf_set_function(s7_name_to_value(s7, S_vct_peak), float_vector_peak_rf); #endif } snd-16.1/snd-gmain.c0000644000076400007640000005740012623170516012365 0ustar bilbil#include "snd.h" #define FALLBACK_FONT "Sans 14" #define HIGHLIGHT_COLOR rgb_to_color(1.00, 1.00, 0.94) /* "ivory1" */ #define BASIC_COLOR rgb_to_color(0.96, 0.96, 0.90) /* "ivory2" lightened */ #define POSITION_COLOR rgb_to_color(0.80, 0.80, 0.75) /* "ivory3" */ #define ZOOM_COLOR rgb_to_color(0.54, 0.54, 0.51) /* "ivory4" */ #define CURSOR_COLOR rgb_to_color(1.0, 0.0, 0.0) /* "red" */ #define SELECTION_COLOR rgb_to_color(0.79, 0.88, 1.00) /* "lightsteelblue1" */ #define MIX_COLOR rgb_to_color(0.66, 0.66, 0.66) /* "darkgray" */ #define ENVED_WAVEFORM_COLOR rgb_to_color(0.0, 0.0, 1.0) /* "blue" */ #define GRAPH_COLOR rgb_to_color(1.0, 1.0, 1.0) /* "white" */ #define SELECTED_GRAPH_COLOR rgb_to_color(1.0, 1.0, 1.0) /* "white" */ #define DATA_COLOR rgb_to_color(0.0, 0.0, 0.0) /* "black" */ #define SELECTED_DATA_COLOR rgb_to_color(0.0, 0.0, 0.0) /* "black" */ #define MARK_COLOR rgb_to_color(1.0, 0.0, 0.0) /* "red" */ #define LISTENER_COLOR rgb_to_color(1.0, 1.0, 1.0) /* "white" */ /* rgb_to_color(0.94, 0.97, 1.00) */ /* "AliceBlue" */ #define LISTENER_TEXT_COLOR rgb_to_color(0.0, 0.0, 0.0) /* "black" */ #define LIGHT_BLUE_COLOR rgb_to_color(0.79, 0.88, 1.00) /* "lightsteelblue1" */ #define LIGHTER_BLUE_COLOR rgb_to_color(0.94, 0.97, 1.00) /* "AliceBlue" */ #define WHITE_COLOR rgb_to_color(1.0, 1.0, 1.0) /* "white" */ #define BLACK_COLOR rgb_to_color(0.0, 0.0, 0.0) /* "black" */ #define GREEN_COLOR rgb_to_color(0.00, 0.93, 0.00) /* "green2" */ #define RED_COLOR rgb_to_color(1.0, 0.0, 0.0) /* "red" */ #define YELLOW_COLOR rgb_to_color(1.00, 1.00, 0.00) /* "yellow" */ #define TEXT_FOCUS_COLOR rgb_to_color(1.0, 1.0, 1.0) /* "white" */ #define FILTER_CONTROL_WAVEFORM_COLOR rgb_to_color(0.0, 0.0, 1.0) /* "blue" */ #define SASH_COLOR rgb_to_color(0.56, 0.93, 0.56) /* "lightgreen" */ #define BLUE_COLOR rgb_to_color(0.0, 0.0, 1.0); #define CHANNEL_SASH_INDENT -10 #define CHANNEL_SASH_SIZE 10 #define POSITION_SLIDER_WIDTH 13 #define ZOOM_SLIDER_WIDTH 10 #define TOGGLE_SIZE 15 #define CHANNEL_MIN_HEIGHT 150 #define SASH_SIZE 14 #define SASH_INDENT -6 #define AUTO_RESIZE_DEFAULT true #define INITIAL_WINDOW_WIDTH 700 #define INITIAL_WINDOW_HEIGHT 300 static gint window_close(GtkWidget *w, GdkEvent *event, gpointer context) { if (snd_exit_cleanly(EXIT_FORCED)) snd_exit(0); return(false); } static GtkWidget **iconify_active_dialogs = NULL; static gint window_iconify(GtkWidget *w, GdkEventWindowState *event, gpointer context) { int i; if ((!ss) || (!(ss->dialogs))) return(false); if (event->new_window_state & GDK_WINDOW_STATE_ICONIFIED) { /* presumably we are now iconified */ if (iconify_active_dialogs) free(iconify_active_dialogs); iconify_active_dialogs = (GtkWidget **)calloc(ss->num_dialogs, sizeof(GtkWidget *)); for (i = 0; i < ss->num_dialogs; i++) if (ss->dialogs[i]) { if (widget_is_active(ss->dialogs[i])) iconify_active_dialogs[i] = ss->dialogs[i]; gtk_widget_hide(ss->dialogs[i]); } } else { if (!(event->new_window_state & GDK_WINDOW_STATE_ICONIFIED)) { /* this is confusing -- can I assume I've been deiconified or not? if not, how to tell? */ if (iconify_active_dialogs) { for (i = 0; i < ss->num_dialogs; i++) if (iconify_active_dialogs[i]) gtk_widget_show(iconify_active_dialogs[i]); free(iconify_active_dialogs); iconify_active_dialogs = NULL; } } } return(false); } static guint auto_update_proc = 0; static gint auto_update_check(gpointer context) { if (auto_update_proc != 0) { g_source_remove(auto_update_proc); auto_update_proc = 0; } if (auto_update_interval(ss) > 0.0) { if (!(play_in_progress())) for_each_sound(sound_not_current); auto_update_proc = g_timeout_add_full(0, (guint32)(auto_update_interval(ss) * 1000), auto_update_check, context, NULL); } return(0); } void auto_update_restart(void) { if (auto_update_proc == 0) auto_update_proc = g_timeout_add_full(0, (guint32)(auto_update_interval(ss) * 1000), auto_update_check, NULL, NULL); } #ifndef _MSC_VER #include static jmp_buf top_level_jump; void top_level_catch(int ignore); void top_level_catch(int ignore) { longjmp(top_level_jump, 1); } #endif static char **auto_open_file_names = NULL; static int auto_open_files = 0; static bool noglob = false, noinit = false, batch = false, nostdin = false; #if HAVE_EXTENSION_LANGUAGE static gint stdin_id = 0; static void get_stdin_string(gpointer context, gint fd, int condition) { int bytes, size; char *buf; buf = (char *)calloc(1024, sizeof(char)); size = 1024; bytes = read(fd, buf, 1024); if (bytes <= 0) { /* redirected to /dev/null?? */ g_source_remove(stdin_id); stdin_id = 0; } else { while (bytes == 1024) { size += 1024; buf = (char *)realloc(buf, size); bytes = read(fd, (char *)(buf + size - 1024), 1024); } snd_eval_stdin_str(buf); } free(buf); } #endif static void setup_gcs(void) { ss->basic_gc = gc_new(); gc_set_background(ss->basic_gc, ss->graph_color); gc_set_foreground(ss->basic_gc, ss->data_color); ss->combined_basic_gc = gc_new(); gc_set_background(ss->combined_basic_gc, ss->graph_color); gc_set_foreground(ss->combined_basic_gc, ss->data_color); ss->mix_gc = gc_new(); gc_set_background(ss->mix_gc, ss->graph_color); gc_set_foreground(ss->mix_gc, ss->mix_color); ss->cursor_gc = gc_new(); gc_set_background(ss->cursor_gc, ss->graph_color); gc_set_colors(ss->cursor_gc, ss->cursor_color, ss->graph_color); ss->selection_gc = gc_new(); gc_set_background(ss->selection_gc, ss->graph_color); gc_set_colors(ss->selection_gc, ss->selection_color, ss->graph_color); ss->mark_gc = gc_new(); gc_set_background(ss->mark_gc, ss->graph_color); gc_set_colors(ss->mark_gc, ss->mark_color, ss->graph_color); ss->erase_gc = gc_new(); gc_set_background(ss->erase_gc, ss->data_color); gc_set_foreground(ss->erase_gc, ss->graph_color); ss->selected_basic_gc = gc_new(); gc_set_background(ss->selected_basic_gc, ss->selected_graph_color); gc_set_foreground(ss->selected_basic_gc, ss->selected_data_color); ss->selected_cursor_gc = gc_new(); gc_set_background(ss->selected_cursor_gc, ss->graph_color); gc_set_colors(ss->selected_cursor_gc, ss->cursor_color, ss->graph_color); ss->selected_selection_gc = gc_new(); gc_set_background(ss->selected_selection_gc, ss->graph_color); gc_set_colors(ss->selected_selection_gc, ss->selection_color, ss->graph_color); ss->selected_mark_gc = gc_new(); gc_set_background(ss->selected_mark_gc, ss->selected_graph_color); gc_set_colors(ss->selected_mark_gc, ss->mark_color, ss->selected_graph_color); ss->selected_erase_gc = gc_new(); gc_set_background(ss->selected_erase_gc, ss->selected_data_color); gc_set_foreground(ss->selected_erase_gc, ss->selected_graph_color); ss->fltenv_basic_gc = gc_new(); gc_set_background(ss->fltenv_basic_gc, ss->basic_color); gc_set_foreground(ss->fltenv_basic_gc, ss->black); ss->fltenv_data_gc = gc_new(); gc_set_background(ss->fltenv_data_gc, ss->basic_color); gc_set_foreground(ss->fltenv_data_gc, ss->filter_control_waveform_color); initialize_colormap(); } static void save_a_color(FILE *Fp, color_info *default_color, color_info *current_color, const char *ext_name) { #if HAVE_EXTENSION_LANGUAGE if ((current_color->red != default_color->red) || (current_color->green != default_color->green) || (current_color->blue != default_color->blue)) #if HAVE_FORTH fprintf(Fp, "%.3f %.3f %.3f %s set-%s drop\n", rgb_to_float(current_color->red), rgb_to_float(current_color->green), rgb_to_float(current_color->blue), S_make_color, ext_name); #endif #if HAVE_SCHEME fprintf(Fp, "(set! (%s) (%s %.3f %.3f %.3f))\n", to_proc_name(ext_name), to_proc_name(S_make_color), rgb_to_float(current_color->red), rgb_to_float(current_color->green), rgb_to_float(current_color->blue)); #endif #if HAVE_RUBY fprintf(Fp, "set_%s(%s(%.3f, %.3f, %.3f))\n", to_proc_name(ext_name), to_proc_name(S_make_color), rgb_to_float(current_color->red), rgb_to_float(current_color->green), rgb_to_float(current_color->blue)); #endif #endif /* ext lang */ free(default_color); /* macro has rgb_to_color which allocates */ } void save_colors(FILE *Fp) { save_a_color(Fp, BASIC_COLOR, ss->basic_color, S_basic_color); save_a_color(Fp, CURSOR_COLOR, ss->cursor_color, S_cursor_color); save_a_color(Fp, DATA_COLOR, ss->data_color, S_data_color); save_a_color(Fp, SELECTED_DATA_COLOR, ss->selected_data_color, S_selected_data_color); save_a_color(Fp, HIGHLIGHT_COLOR, ss->highlight_color, S_highlight_color); save_a_color(Fp, POSITION_COLOR, ss->position_color, S_position_color); save_a_color(Fp, ZOOM_COLOR, ss->zoom_color, S_zoom_color); save_a_color(Fp, SELECTION_COLOR, ss->selection_color, S_selection_color); save_a_color(Fp, MIX_COLOR, ss->mix_color, S_mix_color); save_a_color(Fp, ENVED_WAVEFORM_COLOR, ss->enved_waveform_color, S_enved_waveform_color); save_a_color(Fp, FILTER_CONTROL_WAVEFORM_COLOR, ss->filter_control_waveform_color, S_filter_control_waveform_color); save_a_color(Fp, LISTENER_COLOR, ss->listener_color, S_listener_color); save_a_color(Fp, LISTENER_TEXT_COLOR, ss->listener_text_color, S_listener_text_color); save_a_color(Fp, GRAPH_COLOR, ss->graph_color, S_graph_color); save_a_color(Fp, SELECTED_GRAPH_COLOR, ss->selected_graph_color, S_selected_graph_color); save_a_color(Fp, MARK_COLOR, ss->mark_color, S_mark_color); save_a_color(Fp, SASH_COLOR, ss->sash_color, S_sash_color); save_a_color(Fp, TEXT_FOCUS_COLOR, ss->text_focus_color, S_text_focus_color); } #if HAVE_EXTENSION_LANGUAGE static gboolean io_invoke(GIOChannel *source, GIOCondition condition, gpointer data) { get_stdin_string(NULL, g_io_channel_unix_get_fd(source), 0); return(true); } #endif static void startup_funcs(void) { static int auto_open_ctr = 0; ss->file_monitor_ok = true; /* trap outer-level Close for cleanup check */ SG_SIGNAL_CONNECT(MAIN_SHELL(ss), "delete_event", window_close, NULL); /* when iconified, we need to hide any dialogs as well */ SG_SIGNAL_CONNECT(MAIN_SHELL(ss), "window_state_event", window_iconify, NULL); ss->graph_cursor = GDK_CURSOR_NEW((GdkCursorType)in_graph_cursor(ss)); ss->wait_cursor = GDK_CURSOR_NEW(GDK_WATCH); ss->bounds_cursor = GDK_CURSOR_NEW(GDK_SB_H_DOUBLE_ARROW); ss->yaxis_cursor = GDK_CURSOR_NEW(GDK_SB_V_DOUBLE_ARROW); ss->play_cursor = GDK_CURSOR_NEW(GDK_SB_RIGHT_ARROW); ss->loop_play_cursor = GDK_CURSOR_NEW(GDK_SB_LEFT_ARROW); ss->arrow_cursor = GDK_CURSOR_NEW(GDK_LEFT_PTR); #if HAVE_EXTENSION_LANGUAGE snd_load_init_file(noglob, noinit); #endif #if (!_MSC_VER) && HAVE_EXTENSION_LANGUAGE && !__MINGW32__ if (!nostdin) { GIOChannel *channel; signal(SIGTTIN, SIG_IGN); signal(SIGTTOU, SIG_IGN); /* these signals are sent by a shell if we start Snd as a background process, * but try to read stdin (needed to support the emacs subjob connection). If * we don't do this, the background job is suspended when the shell sends SIGTTIN. */ channel = g_io_channel_unix_new(STDIN_FILENO); stdin_id = g_io_add_watch_full(channel, G_PRIORITY_DEFAULT, (GIOCondition)(G_IO_IN | G_IO_HUP | G_IO_ERR), io_invoke, NULL, NULL); g_io_channel_unref(channel); } #endif while (auto_open_ctr < auto_open_files) auto_open_ctr = handle_next_startup_arg(auto_open_ctr, auto_open_file_names, true, auto_open_files); if ((ss->init_window_width > 0) && (ss->init_window_height > 0)) set_widget_size(GTK_WIDGET(MAIN_SHELL(ss)), ss->init_window_width, ss->init_window_height); if ((ss->init_window_x != DEFAULT_INIT_WINDOW_X) && (ss->init_window_y != DEFAULT_INIT_WINDOW_Y)) set_widget_position(GTK_WIDGET(MAIN_SHELL(ss)), ss->init_window_x, ss->init_window_y); if (!(ss->file_monitor_ok)) { if (auto_update_interval(ss) > 0.0) g_timeout_add_full(0, (guint32)(auto_update_interval(ss) * 1000), auto_update_check, NULL, NULL); } if ((ss->sounds) && (ss->selected_sound == NO_SELECTION)) { snd_info *sp; sp = ss->sounds[0]; if ((sp) && (sp->inuse == SOUND_NORMAL) && (sp->selected_channel == NO_SELECTION)) /* don't clobber possible select-channel in loaded startup files */ select_channel(sp, 0); } } static void set_up_icon(void) { gtk_window_set_icon(GTK_WINDOW(MAIN_SHELL(ss)), gdk_pixbuf_new_from_xpm_data(snd_icon_bits())); } color_t get_in_between_color(color_t fg, color_t bg) { color_info *new_color; new_color = (color_info *)calloc(1, sizeof(color_info)); /* memleak here */ new_color->red = (rgb_t)((fg->red + (2 * bg->red)) / 3); new_color->green = (rgb_t)((fg->green + (2 * bg->green)) / 3); new_color->blue = (rgb_t)((fg->blue + (2 * bg->blue)) / 3); new_color->alpha = 1.0; return(new_color); } static void notebook_switch_page(GtkNotebook *w, GtkWidget *page_widget, gint page_num) { GtkWidget *pw; pw = gtk_notebook_get_nth_page(w, page_num); if (pw) { int index = 0; index = get_user_int_data(G_OBJECT(pw)); if ((index < ss->max_sounds) && (snd_ok(ss->sounds[index]))) { snd_info *sp; sp = ss->sounds[index]; if (sp->selected_channel == NO_SELECTION) select_channel(ss->sounds[index], 0); else select_channel(ss->sounds[index], sp->selected_channel); } } } void snd_doit(int argc, char **argv) { GtkWidget *shell; int i; gtk_init(&argc, &argv); #if (!GTK_CHECK_VERSION(3, 0, 0)) && (!__APPLE__) gdk_set_locale(); #endif ss->channel_min_height = CHANNEL_MIN_HEIGHT; ss->Graph_Cursor = DEFAULT_GRAPH_CURSOR; shell = gtk_window_new(GTK_WINDOW_TOPLEVEL); sg_make_resizable(shell); #ifndef _MSC_VER setlocale(LC_NUMERIC, "C"); #endif auto_open_files = argc-1; if (argc > 1) auto_open_file_names = (char **)(argv + 1); ss->startup_title = mus_strdup("snd"); set_sound_style(SOUNDS_VERTICAL); for (i = 1; i < argc; i++) if ((mus_strcmp(argv[i], "-h")) || (mus_strcmp(argv[i], "-horizontal")) || (mus_strcmp(argv[i], "--horizontal"))) set_sound_style(SOUNDS_HORIZONTAL); else if ((mus_strcmp(argv[i], "-v")) || (mus_strcmp(argv[i], "-vertical")) || (mus_strcmp(argv[i], "--vertical"))) set_sound_style(SOUNDS_VERTICAL); else if ((mus_strcmp(argv[i], "-notebook")) || (mus_strcmp(argv[i], "--notebook"))) set_sound_style(SOUNDS_IN_NOTEBOOK); else if ((mus_strcmp(argv[i], "-separate")) || (mus_strcmp(argv[i], "--separate"))) set_sound_style(SOUNDS_IN_SEPARATE_WINDOWS); else if (mus_strcmp(argv[i], "-noglob")) noglob = true; else if (mus_strcmp(argv[i], "-noinit")) noinit = true; else if (mus_strcmp(argv[i], "-nostdin")) nostdin = true; else if ((mus_strcmp(argv[i], "-b")) || (mus_strcmp(argv[i], "-batch")) || (mus_strcmp(argv[i], "--batch"))) batch = true; else if (mus_strcmp(argv[i], "--features")) /* testing (compsnd) */ check_features_list(argv[i + 1]); ss->batch_mode = batch; set_auto_resize(AUTO_RESIZE_DEFAULT); ss->zoom_slider_width = ZOOM_SLIDER_WIDTH; ss->position_slider_width = POSITION_SLIDER_WIDTH; ss->channel_sash_indent = CHANNEL_SASH_INDENT; /* not currently used */ ss->channel_sash_size = CHANNEL_SASH_SIZE; ss->sash_size = SASH_SIZE; ss->sash_indent = SASH_INDENT; ss->toggle_size = TOGGLE_SIZE; ss->graph_is_active = false; ss->bg_gradient = 0.05; ss->white = WHITE_COLOR; ss->black = BLACK_COLOR; ss->light_blue = LIGHT_BLUE_COLOR; ss->lighter_blue = LIGHTER_BLUE_COLOR; ss->red = RED_COLOR; ss->green = GREEN_COLOR; ss->blue = BLUE_COLOR; ss->yellow = YELLOW_COLOR; ss->highlight_color = HIGHLIGHT_COLOR; ss->basic_color = BASIC_COLOR; ss->position_color = POSITION_COLOR; ss->zoom_color = ZOOM_COLOR; ss->cursor_color = CURSOR_COLOR; ss->selection_color = SELECTION_COLOR; ss->mix_color = MIX_COLOR; ss->enved_waveform_color = ENVED_WAVEFORM_COLOR; ss->filter_control_waveform_color = FILTER_CONTROL_WAVEFORM_COLOR; ss->listener_color = LISTENER_COLOR; ss->listener_text_color = LISTENER_TEXT_COLOR; ss->graph_color = GRAPH_COLOR; ss->selected_graph_color = SELECTED_GRAPH_COLOR; ss->data_color = DATA_COLOR; ss->selected_data_color = SELECTED_DATA_COLOR; ss->mark_color = MARK_COLOR; ss->sash_color = SASH_COLOR; ss->text_focus_color = TEXT_FOCUS_COLOR; #if HAVE_SCHEME s7_symbol_set_value(s7, ss->highlight_color_symbol, Xen_wrap_pixel(ss->highlight_color)); s7_symbol_set_value(s7, ss->basic_color_symbol, Xen_wrap_pixel(ss->basic_color)); s7_symbol_set_value(s7, ss->position_color_symbol, Xen_wrap_pixel(ss->position_color)); s7_symbol_set_value(s7, ss->zoom_color_symbol, Xen_wrap_pixel(ss->zoom_color)); s7_symbol_set_value(s7, ss->cursor_color_symbol, Xen_wrap_pixel(ss->cursor_color)); s7_symbol_set_value(s7, ss->selection_color_symbol, Xen_wrap_pixel(ss->selection_color)); s7_symbol_set_value(s7, ss->mix_color_symbol, Xen_wrap_pixel(ss->mix_color)); s7_symbol_set_value(s7, ss->enved_waveform_color_symbol, Xen_wrap_pixel(ss->enved_waveform_color)); s7_symbol_set_value(s7, ss->filter_control_waveform_color_symbol, Xen_wrap_pixel(ss->filter_control_waveform_color)); s7_symbol_set_value(s7, ss->listener_color_symbol, Xen_wrap_pixel(ss->listener_color)); s7_symbol_set_value(s7, ss->listener_text_color_symbol, Xen_wrap_pixel(ss->listener_text_color)); s7_symbol_set_value(s7, ss->graph_color_symbol, Xen_wrap_pixel(ss->graph_color)); s7_symbol_set_value(s7, ss->selected_graph_color_symbol, Xen_wrap_pixel(ss->selected_graph_color)); s7_symbol_set_value(s7, ss->data_color_symbol, Xen_wrap_pixel(ss->data_color)); s7_symbol_set_value(s7, ss->selected_data_color_symbol, Xen_wrap_pixel(ss->selected_data_color)); s7_symbol_set_value(s7, ss->mark_color_symbol, Xen_wrap_pixel(ss->mark_color)); s7_symbol_set_value(s7, ss->sash_color_symbol, Xen_wrap_pixel(ss->sash_color)); s7_symbol_set_value(s7, ss->text_focus_color_symbol, Xen_wrap_pixel(ss->text_focus_color)); #endif ss->grid_color = get_in_between_color(ss->data_color, ss->graph_color); ss->selected_grid_color = get_in_between_color(ss->selected_data_color, ss->selected_graph_color); ss->axis_color_set = false; ss->orig_data_color = ss->data_color; ss->orig_selected_data_color = ss->selected_data_color; ss->orig_mark_color = ss->mark_color; ss->orig_mix_color = ss->mix_color; ss->orig_graph_color = ss->graph_color; ss->orig_selected_graph_color = ss->selected_graph_color; ss->orig_listener_color = ss->listener_color; ss->orig_listener_text_color = ss->listener_text_color; ss->orig_cursor_color = ss->cursor_color; ss->orig_basic_color = ss->basic_color; ss->orig_selection_color = ss->selection_color; ss->orig_zoom_color = ss->zoom_color; ss->orig_position_color = ss->position_color; ss->orig_highlight_color = ss->highlight_color; if ((!(set_tiny_font(DEFAULT_TINY_FONT))) && (!(set_tiny_font(FALLBACK_FONT)))) fprintf(stderr, "can't find tiny font: %s", DEFAULT_TINY_FONT); if ((!(set_axis_label_font(DEFAULT_AXIS_LABEL_FONT))) && (!(set_axis_label_font(FALLBACK_FONT)))) fprintf(stderr, "can't find axis label font: %s", DEFAULT_AXIS_LABEL_FONT); if ((!(set_axis_numbers_font(DEFAULT_AXIS_NUMBERS_FONT))) && (!(set_axis_numbers_font(FALLBACK_FONT)))) fprintf(stderr, "can't find axis numbers font: %s", DEFAULT_AXIS_NUMBERS_FONT); if ((!(set_peaks_font(DEFAULT_PEAKS_FONT))) && (!(set_peaks_font(FALLBACK_FONT)))) fprintf(stderr, "can't find peaks font: %s", DEFAULT_PEAKS_FONT); if ((!(set_bold_peaks_font(DEFAULT_BOLD_PEAKS_FONT))) && (!(set_bold_peaks_font(FALLBACK_FONT)))) fprintf(stderr, "can't find bold peaks font: %s", DEFAULT_BOLD_PEAKS_FONT); if ((!(set_listener_font(DEFAULT_LISTENER_FONT))) && (!(set_listener_font(FALLBACK_FONT)))) fprintf(stderr, "can't find listener font: %s", DEFAULT_LISTENER_FONT); ss->orig_axis_label_font = mus_strdup(axis_label_font(ss)); ss->orig_axis_numbers_font = mus_strdup(axis_numbers_font(ss)); ss->orig_peaks_font = mus_strdup(peaks_font(ss)); ss->orig_bold_peaks_font = mus_strdup(bold_peaks_font(ss)); ss->orig_listener_font = mus_strdup(listener_font(ss)); ss->orig_tiny_font = mus_strdup(tiny_font(ss)); #if (!(GTK_CHECK_VERSION(3, 0, 0))) init_gtk(); #endif MAIN_PANE(ss) = gtk_vbox_new(false, 0); /* not homogenous, spacing 0 */ #if (GTK_CHECK_VERSION(3, 0, 0)) init_gtk(); #endif MAIN_SHELL(ss) = shell; gtk_container_add(GTK_CONTAINER(MAIN_SHELL(ss)), MAIN_PANE(ss)); add_menu(); /* adds menubar to MAIN_PANE (via box_pack_start) */ if (with_toolbar(ss)) show_toolbar(); if (sound_style(ss) != SOUNDS_IN_SEPARATE_WINDOWS) { /* hseparator here looks bad */ SOUND_PANE(ss) = gtk_vpaned_new(); add_paned_style(SOUND_PANE(ss)); gtk_container_set_border_width(GTK_CONTAINER(SOUND_PANE(ss)), 0); gtk_container_add(GTK_CONTAINER(MAIN_PANE(ss)), SOUND_PANE(ss)); if (sound_style(ss) == SOUNDS_IN_NOTEBOOK) { SOUND_PANE_BOX(ss) = gtk_notebook_new(); gtk_notebook_set_tab_pos(GTK_NOTEBOOK(SOUND_PANE_BOX(ss)), GTK_POS_TOP); SG_SIGNAL_CONNECT(SOUND_PANE_BOX(ss), "switch_page", notebook_switch_page, NULL); } else { if (sound_style(ss) == SOUNDS_HORIZONTAL) SOUND_PANE_BOX(ss) = gtk_hbox_new(false, 0); else SOUND_PANE_BOX(ss) = gtk_vbox_new(false, 0); #if GTK_CHECK_VERSION(3, 0, 0) gtk_widget_set_hexpand(GTK_WIDGET(SOUND_PANE_BOX(ss)), true); gtk_widget_set_vexpand(GTK_WIDGET(SOUND_PANE_BOX(ss)), true); #endif } gtk_paned_add1(GTK_PANED(SOUND_PANE(ss)), SOUND_PANE_BOX(ss)); gtk_widget_show(SOUND_PANE_BOX(ss)); gtk_widget_show(SOUND_PANE(ss)); } gtk_widget_show(MAIN_PANE(ss)); gtk_widget_show(MAIN_SHELL(ss)); #if HAVE_GTK_ADJUSTMENT_GET_UPPER MAIN_WINDOW(ss) = gtk_widget_get_window(MAIN_SHELL(ss)); #else MAIN_WINDOW(ss) = MAIN_SHELL(ss)->window; #endif setup_gcs(); if (batch) gtk_widget_hide(MAIN_SHELL(ss)); else gdk_window_resize(WIDGET_TO_WINDOW(MAIN_SHELL(ss)), INITIAL_WINDOW_WIDTH, INITIAL_WINDOW_HEIGHT); #ifndef _MSC_VER if (setjmp(top_level_jump)) { if (!(ss->jump_ok)) snd_error_without_format("Caught top level error (will try to continue):\n"); else ss->jump_ok = false; } else #endif startup_funcs(); /* snd /tmp -> segfault if this happens before the setjmp(top_level_jump) */ if (ss->startup_errors) { post_it("Error in initialization", ss->startup_errors); free(ss->startup_errors); ss->startup_errors = NULL; } #if GTK_CHECK_VERSION(3, 0, 0) set_basic_color(ss->basic_color); color_listener(ss->listener_color); color_chan_components(ss->zoom_color, COLOR_ZOOM); color_chan_components(ss->position_color, COLOR_POSITION); #endif if ((!listener_exists()) && (!(ss->sounds[0]))) handle_listener(true); set_up_icon(); gtk_main(); } snd-16.1/spectr.rb0000644000076400007640000077145412306421672012205 0ustar bilbil# spectra courtesy j.a. moorer # # i removed phase information, since the psychoacousticians tell us that these # normally don't matter. also, i omitted any partials with amplitude below # 0.0001, although this may have thrown away good data, because the original # data was not normalized in any way. # bass clarinet? Bc_c2 = [1.00, 0.0370, 1.98, 0.0037, 2.99, 0.0862, 3.98, 0.0011, 4.97, 0.0270, 5.98, 0.0030, 6.97, 0.0586, 7.95, 0.0031, 8.96, 0.0363, 9.95, 0.0076, 10.93, 0.0310, 11.95, 0.0097, 12.93, 0.0206, 13.92, 0.0045, 14.93, 0.0044, 15.91, 0.0021, 16.90, 0.0220, 17.91, 0.0082, 18.90, 0.0227, 19.88, 0.0049, 20.90, 0.0090, 21.87, 0.0004, 22.87, 0.0051, 23.88, 0.0010, 24.86, 0.0072, 25.85, 0.0026, 26.86, 0.0044, 27.84, 0.0035, 28.85, 0.0031, 29.84, 0.0025, 30.83, 0.0042, 31.84, 0.0024, 32.83, 0.0022, 33.81, 0.0021, 34.82, 0.0011, 35.81, 0.0008, 36.79, 0.0013, 37.80, 0.0024, 38.78, 0.0028, 39.78, 0.0016, 40.79, 0.0024, 41.77, 0.0005, 42.76, 0.0005, 43.77, 0.0003, 44.76, 0.0002, 45.74, 0.0005, 46.75, 0.0003, 47.74, 0.0006, 48.73, 0.0003, 49.74, 0.0009, 50.72, 0.0002, 51.71, 0.0007, 52.72, 0.0004, 53.70, 0.0005, 54.70, 0.0004, 55.71, 0.0005, 56.69, 0.0002, 57.68, 0.0003, 58.69, 0.0002, 59.68, 0.0002, 60.68, 0.0003, 61.68, 0.0002, 62.66, 0.0002, 63.66, 0.0002, 65.65, 0.0001, 67.64, 0.0002, 69.63, 0.0002, 70.63, 0.0002, 71.60, 0.0002, 72.62, 0.0002, 73.60, 0.0002, 75.59, 0.0002, 76.59, 0.0002, 77.58, 0.0001, 78.59, 0.0001, 79.57, 0.0002, 80.57, 0.0002, 81.57, 0.0002, 82.54, 0.0001, 83.56, 0.0002, 84.54, 0.0001, 85.53, 0.0001, 87.53, 0.0002, 89.53, 0.0002] Bc_cs2 = [1.02, 0.0306, 2.00, 0.0016, 2.99, 0.0926, 4.00, 0.0027, 5.01, 0.0305, 5.99, 0.0006, 6.99, 0.0158, 8.00, 0.0025, 9.01, 0.0072, 10.01, 0.0057, 10.99, 0.0203, 12.00, 0.0078, 13.01, 0.0147, 14.02, 0.0036, 15.00, 0.0103, 16.07, 0.0007, 17.01, 0.0070, 18.01, 0.0053, 19.00, 0.0049, 20.02, 0.0027, 21.01, 0.0024, 22.01, 0.0014, 23.00, 0.0011, 24.02, 0.0023, 25.00, 0.0031, 26.01, 0.0021, 27.00, 0.0029, 28.02, 0.0010, 29.02, 0.0026, 30.04, 0.0011, 31.00, 0.0019, 32.01, 0.0010, 33.03, 0.0004, 34.02, 0.0002, 36.02, 0.0004, 37.05, 0.0002, 38.04, 0.0004, 39.00, 0.0003, 40.02, 0.0002, 41.01, 0.0002, 42.01, 0.0002, 43.00, 0.0001, 44.02, 0.0001, 45.01, 0.0002, 47.01, 0.0002, 48.03, 0.0001, 49.00, 0.0002, 50.03, 0.0001, 51.02, 0.0001, 55.00, 0.0001, 56.99, 0.0002, 73.98, 0.0001, 75.02, 0.0001, 75.98, 0.0001] Bc_d2 = [1.01, 0.1419, 1.97, 0.0009, 3.00, 0.0865, 4.01, 0.0008, 5.00, 0.0059, 6.00, 0.0009, 7.00, 0.0110, 8.00, 0.0014, 9.00, 0.0050, 10.00, 0.0057, 11.01, 0.0267, 12.01, 0.0091, 13.00, 0.0238, 14.02, 0.0023, 15.01, 0.0069, 16.01, 0.0033, 17.00, 0.0064, 18.01, 0.0036, 18.99, 0.0067, 20.01, 0.0026, 21.01, 0.0047, 22.01, 0.0037, 22.99, 0.0040, 24.00, 0.0038, 25.01, 0.0036, 26.01, 0.0032, 27.00, 0.0036, 27.99, 0.0019, 29.00, 0.0034, 30.00, 0.0014, 31.00, 0.0007, 31.98, 0.0003, 33.04, 0.0002, 34.05, 0.0003, 35.04, 0.0003, 35.95, 0.0002, 37.05, 0.0003, 37.98, 0.0002, 39.07, 0.0002, 40.02, 0.0002, 40.95, 0.0001, 42.01, 0.0003, 42.98, 0.0002, 44.02, 0.0004, 44.99, 0.0002, 46.03, 0.0002, 46.98, 0.0002, 48.04, 0.0001, 49.01, 0.0001, 51.02, 0.0002, 52.03, 0.0002, 53.01, 0.0002, 54.01, 0.0001, 55.01, 0.0002, 56.02, 0.0001, 65.00, 0.0002, 66.99, 0.0001, 69.01, 0.0001, 71.00, 0.0002, 73.00, 0.0001, 74.99, 0.0001] Bc_ds2 = [1.01, 0.2718, 2.01, 0.0016, 3.01, 0.0476, 4.01, 0.0022, 5.01, 0.0228, 6.00, 0.0005, 7.01, 0.0466, 8.01, 0.0014, 9.00, 0.0179, 10.01, 0.0059, 11.00, 0.0254, 12.01, 0.0099, 13.00, 0.0176, 14.01, 0.0031, 15.02, 0.0109, 16.00, 0.0007, 17.02, 0.0090, 18.03, 0.0038, 19.02, 0.0036, 20.02, 0.0029, 21.02, 0.0045, 22.02, 0.0026, 23.02, 0.0060, 24.02, 0.0031, 25.02, 0.0023, 26.02, 0.0033, 27.02, 0.0041, 28.02, 0.0033, 29.02, 0.0034, 30.03, 0.0007, 31.04, 0.0005, 32.03, 0.0005, 33.05, 0.0005, 34.03, 0.0006, 35.05, 0.0002, 36.04, 0.0004, 37.03, 0.0002, 38.03, 0.0003, 39.03, 0.0004, 40.03, 0.0002, 41.03, 0.0004, 42.03, 0.0003, 43.03, 0.0006, 44.04, 0.0002, 45.05, 0.0005, 46.04, 0.0001, 47.05, 0.0003, 48.04, 0.0002, 49.05, 0.0003, 50.04, 0.0001, 51.04, 0.0003, 52.04, 0.0002, 53.04, 0.0001, 55.04, 0.0002, 57.05, 0.0002, 59.06, 0.0002, 61.07, 0.0002, 62.06, 0.0001, 63.06, 0.0002, 64.05, 0.0001, 65.06, 0.0001, 66.06, 0.0002, 67.06, 0.0002, 68.06, 0.0002, 70.06, 0.0002, 72.06, 0.0001, 74.08, 0.0001] Bc_e2 = [1.01, 0.1365, 2.01, 0.0009, 3.03, 0.0219, 3.99, 0.0004, 5.04, 0.0239, 6.03, 0.0013, 7.02, 0.0284, 8.04, 0.0029, 9.03, 0.0167, 10.06, 0.0042, 11.05, 0.0059, 12.03, 0.0012, 13.07, 0.0095, 14.07, 0.0013, 15.08, 0.0109, 16.06, 0.0038, 17.06, 0.0042, 18.09, 0.0006, 19.07, 0.0034, 20.10, 0.0036, 21.09, 0.0018, 22.08, 0.0025, 23.11, 0.0054, 24.08, 0.0008, 25.12, 0.0035, 26.09, 0.0013, 27.13, 0.0022, 28.13, 0.0009, 29.12, 0.0006, 30.14, 0.0004, 31.13, 0.0005, 32.15, 0.0003, 33.15, 0.0003, 35.15, 0.0002, 36.13, 0.0001, 37.17, 0.0003, 38.19, 0.0002, 39.16, 0.0006, 40.21, 0.0001, 41.17, 0.0005, 42.18, 0.0002, 43.19, 0.0003, 44.18, 0.0001, 45.21, 0.0002, 46.19, 0.0002, 47.22, 0.0004, 48.22, 0.0002, 49.20, 0.0002, 50.23, 0.0001, 55.24, 0.0001, 56.23, 0.0001, 57.26, 0.0002, 59.26, 0.0001, 61.25, 0.0002, 62.29, 0.0002, 64.27, 0.0001] Bc_f2 = [0.99, 0.1014, 2.00, 0.0021, 3.02, 0.0301, 4.02, 0.0012, 5.00, 0.0893, 6.02, 0.0028, 7.03, 0.0333, 8.04, 0.0046, 9.05, 0.0109, 10.03, 0.0033, 11.03, 0.0174, 12.05, 0.0075, 13.06, 0.0085, 14.06, 0.0037, 15.04, 0.0133, 16.08, 0.0021, 17.07, 0.0017, 18.07, 0.0009, 19.05, 0.0015, 20.07, 0.0002, 21.08, 0.0068, 22.09, 0.0033, 23.10, 0.0060, 24.07, 0.0031, 25.08, 0.0036, 26.10, 0.0009, 27.11, 0.0001, 28.11, 0.0010, 29.10, 0.0007, 30.10, 0.0004, 31.12, 0.0005, 32.13, 0.0002, 33.11, 0.0005, 34.11, 0.0003, 35.12, 0.0004, 36.13, 0.0002, 37.14, 0.0005, 38.12, 0.0001, 39.14, 0.0005, 40.14, 0.0002, 41.16, 0.0002, 43.14, 0.0003, 45.17, 0.0004, 46.18, 0.0002, 47.16, 0.0002, 49.18, 0.0002, 51.18, 0.0001, 53.19, 0.0002, 55.22, 0.0001, 56.19, 0.0002, 57.21, 0.0001, 58.22, 0.0002, 60.23, 0.0002, 62.22, 0.0001] Bc_fs2 = [1.01, 0.0724, 2.02, 0.0045, 3.01, 0.0626, 4.01, 0.0014, 5.00, 0.1104, 6.00, 0.0041, 7.00, 0.0216, 8.03, 0.0017, 9.03, 0.0255, 10.02, 0.0011, 11.02, 0.0152, 12.02, 0.0019, 13.01, 0.0061, 14.02, 0.0018, 15.04, 0.0077, 16.05, 0.0009, 17.04, 0.0031, 18.04, 0.0014, 19.02, 0.0058, 20.04, 0.0005, 21.03, 0.0030, 22.03, 0.0030, 23.05, 0.0048, 24.06, 0.0013, 25.04, 0.0009, 26.04, 0.0002, 27.03, 0.0008, 28.05, 0.0005, 29.05, 0.0003, 30.06, 0.0002, 31.06, 0.0004, 32.05, 0.0005, 33.05, 0.0003, 34.04, 0.0002, 35.05, 0.0004, 37.08, 0.0006, 38.06, 0.0002, 39.07, 0.0003, 41.06, 0.0003, 42.07, 0.0001, 43.07, 0.0003, 44.09, 0.0002, 45.10, 0.0001, 47.07, 0.0001, 51.10, 0.0002, 53.10, 0.0002, 54.10, 0.0001, 56.09, 0.0002, 57.09, 0.0001, 58.12, 0.0001, 62.11, 0.0001, 64.11, 0.0001] Bc_g2 = [1.00, 0.0567, 1.99, 0.0037, 3.00, 0.1114, 3.98, 0.0030, 4.99, 0.1112, 5.98, 0.0041, 6.99, 0.0195, 7.99, 0.0061, 8.98, 0.0081, 9.97, 0.0084, 10.98, 0.0139, 11.98, 0.0038, 12.98, 0.0092, 13.97, 0.0038, 14.97, 0.0042, 15.97, 0.0003, 16.97, 0.0012, 17.96, 0.0019, 18.97, 0.0040, 19.95, 0.0032, 20.97, 0.0088, 21.95, 0.0022, 22.96, 0.0025, 23.94, 0.0004, 24.94, 0.0003, 25.92, 0.0005, 26.95, 0.0005, 27.91, 0.0003, 28.95, 0.0003, 29.90, 0.0002, 30.94, 0.0006, 31.89, 0.0001, 32.93, 0.0007, 34.92, 0.0005, 35.89, 0.0002, 36.92, 0.0003, 37.89, 0.0001, 38.91, 0.0002, 39.88, 0.0002, 40.90, 0.0004, 41.88, 0.0002, 43.88, 0.0002, 50.90, 0.0001, 51.89, 0.0002, 52.93, 0.0001, 53.89, 0.0003, 55.87, 0.0002] Bc_gs2 = [0.99, 0.0794, 2.00, 0.0021, 3.00, 0.1294, 3.98, 0.0015, 4.98, 0.0849, 5.98, 0.0058, 6.99, 0.0389, 7.97, 0.0113, 8.97, 0.0154, 9.98, 0.0026, 10.98, 0.0172, 11.95, 0.0048, 12.95, 0.0099, 13.98, 0.0011, 14.97, 0.0029, 15.95, 0.0013, 16.95, 0.0055, 17.97, 0.0014, 18.96, 0.0052, 19.94, 0.0040, 20.94, 0.0038, 21.96, 0.0006, 22.94, 0.0003, 23.92, 0.0005, 24.93, 0.0005, 25.93, 0.0002, 26.94, 0.0006, 27.92, 0.0003, 28.91, 0.0007, 29.91, 0.0004, 30.93, 0.0006, 31.90, 0.0003, 32.90, 0.0006, 33.90, 0.0003, 34.91, 0.0004, 35.89, 0.0001, 36.89, 0.0003, 37.90, 0.0003, 38.90, 0.0003, 40.88, 0.0002, 42.89, 0.0001, 45.89, 0.0002, 47.87, 0.0001, 49.87, 0.0003, 50.86, 0.0002, 51.85, 0.0002, 53.86, 0.0001] Bc_a2 = [0.99, 0.1177, 1.99, 0.0047, 2.99, 0.2346, 3.99, 0.0023, 4.98, 0.0538, 5.99, 0.0060, 6.98, 0.0493, 7.99, 0.0062, 8.99, 0.0103, 9.99, 0.0030, 10.99, 0.0146, 11.99, 0.0126, 12.99, 0.0042, 13.99, 0.0016, 14.99, 0.0060, 15.98, 0.0034, 16.96, 0.0039, 17.96, 0.0036, 18.96, 0.0076, 19.96, 0.0018, 20.96, 0.0025, 22.95, 0.0018, 23.95, 0.0005, 24.94, 0.0003, 25.95, 0.0005, 26.95, 0.0006, 27.95, 0.0008, 28.96, 0.0005, 29.96, 0.0005, 30.96, 0.0007, 31.95, 0.0005, 32.95, 0.0005, 33.95, 0.0001, 34.95, 0.0003, 35.93, 0.0002, 36.94, 0.0003, 38.92, 0.0002, 42.93, 0.0001, 44.93, 0.0001, 46.93, 0.0002, 47.92, 0.0001] Bc_as2 = [1.00, 0.1279, 1.99, 0.0028, 2.99, 0.1611, 3.98, 0.0034, 4.97, 0.0322, 5.97, 0.0085, 6.98, 0.0274, 7.97, 0.0068, 8.96, 0.0245, 9.97, 0.0022, 10.94, 0.0254, 11.93, 0.0010, 12.93, 0.0078, 13.95, 0.0022, 14.94, 0.0035, 15.92, 0.0022, 16.92, 0.0033, 17.91, 0.0039, 18.90, 0.0037, 19.92, 0.0012, 20.92, 0.0003, 21.91, 0.0008, 22.89, 0.0005, 23.88, 0.0007, 24.87, 0.0007, 25.87, 0.0005, 26.88, 0.0007, 27.86, 0.0001, 28.86, 0.0014, 29.84, 0.0004, 30.85, 0.0005, 31.85, 0.0001, 32.85, 0.0004, 33.84, 0.0004, 34.84, 0.0003, 36.82, 0.0003, 40.81, 0.0003, 42.80, 0.0001, 43.79, 0.0002, 44.79, 0.0002, 45.79, 0.0003, 46.79, 0.0001, 47.79, 0.0002, 49.77, 0.0001] Bc_b2 = [1.00, 0.1161, 1.98, 0.0036, 2.97, 0.1813, 3.98, 0.0038, 4.96, 0.0298, 5.95, 0.0073, 6.95, 0.0125, 7.95, 0.0064, 8.92, 0.0175, 9.94, 0.0087, 10.91, 0.0117, 11.91, 0.0025, 12.91, 0.0055, 13.92, 0.0027, 14.88, 0.0069, 15.88, 0.0034, 16.88, 0.0052, 17.85, 0.0038, 18.88, 0.0003, 19.83, 0.0005, 20.83, 0.0005, 21.78, 0.0002, 22.82, 0.0004, 23.74, 0.0002, 24.81, 0.0008, 25.76, 0.0003, 26.78, 0.0005, 27.78, 0.0006, 28.78, 0.0005, 29.74, 0.0002, 30.75, 0.0001, 31.75, 0.0004, 32.72, 0.0002, 33.73, 0.0002, 34.73, 0.0002, 41.69, 0.0002, 42.68, 0.0002, 43.67, 0.0002, 44.68, 0.0002, 45.67, 0.0001] Bc_c3 = [1.00, 0.1579, 1.99, 0.0068, 2.99, 0.1885, 3.99, 0.0022, 4.97, 0.0384, 5.96, 0.0054, 6.97, 0.0247, 7.97, 0.0023, 8.96, 0.0114, 9.95, 0.0096, 10.93, 0.0054, 11.95, 0.0030, 12.94, 0.0036, 13.92, 0.0075, 14.93, 0.0033, 15.92, 0.0052, 16.91, 0.0010, 17.91, 0.0011, 18.90, 0.0004, 19.89, 0.0006, 20.90, 0.0005, 21.89, 0.0003, 22.87, 0.0004, 23.88, 0.0004, 24.87, 0.0005, 25.86, 0.0008, 26.87, 0.0005, 27.85, 0.0002, 28.84, 0.0002, 29.85, 0.0003, 30.83, 0.0002, 31.84, 0.0002, 32.83, 0.0002, 35.83, 0.0001, 36.80, 0.0002, 38.81, 0.0002, 39.78, 0.0002, 40.78, 0.0003, 41.79, 0.0001] Bc_cs3 = [1.00, 0.2106, 1.98, 0.0073, 2.99, 0.1027, 3.98, 0.0038, 4.97, 0.0191, 5.98, 0.0036, 6.97, 0.0256, 7.95, 0.0035, 8.97, 0.0347, 9.95, 0.0039, 10.94, 0.0048, 11.95, 0.0026, 12.94, 0.0089, 13.93, 0.0011, 14.93, 0.0052, 15.93, 0.0033, 16.96, 0.0002, 17.93, 0.0003, 18.94, 0.0001, 19.92, 0.0002, 20.91, 0.0007, 21.91, 0.0006, 22.89, 0.0005, 23.90, 0.0005, 24.90, 0.0005, 25.87, 0.0005, 26.89, 0.0003, 27.88, 0.0005, 28.87, 0.0003, 29.87, 0.0003, 31.85, 0.0002, 33.84, 0.0001, 34.84, 0.0001, 36.82, 0.0003, 37.83, 0.0001, 38.83, 0.0003] Bc_d3 = [1.01, 0.2039, 2.00, 0.0041, 3.00, 0.0640, 3.99, 0.0062, 5.00, 0.0192, 6.00, 0.0013, 7.01, 0.0225, 8.00, 0.0034, 9.01, 0.0245, 10.00, 0.0038, 11.02, 0.0028, 12.01, 0.0030, 13.02, 0.0042, 14.00, 0.0021, 15.01, 0.0049, 16.02, 0.0006, 17.02, 0.0003, 18.02, 0.0007, 19.00, 0.0001, 20.03, 0.0005, 21.02, 0.0010, 22.05, 0.0002, 23.04, 0.0012, 24.05, 0.0003, 25.02, 0.0002, 26.03, 0.0003, 27.02, 0.0004, 28.03, 0.0001, 29.05, 0.0002, 30.05, 0.0001, 33.03, 0.0001, 34.04, 0.0001, 35.04, 0.0001, 36.04, 0.0003, 38.05, 0.0001, 40.04, 0.0001] Bc_ds3 = [1.01, 0.1501, 2.00, 0.0036, 3.00, 0.0682, 4.00, 0.0069, 4.99, 0.0142, 5.98, 0.0017, 6.99, 0.0322, 7.99, 0.0063, 8.98, 0.0019, 10.00, 0.0010, 11.00, 0.0046, 11.99, 0.0023, 12.99, 0.0035, 13.98, 0.0041, 14.98, 0.0020, 15.97, 0.0001, 16.98, 0.0003, 17.98, 0.0008, 18.98, 0.0009, 20.03, 0.0002, 21.00, 0.0007, 21.99, 0.0006, 22.99, 0.0006, 23.99, 0.0003, 24.98, 0.0004, 25.98, 0.0003, 26.97, 0.0001, 27.98, 0.0001, 29.97, 0.0001, 30.98, 0.0002, 32.96, 0.0003, 33.97, 0.0003, 34.95, 0.0002, 35.96, 0.0002, 36.97, 0.0001] Bc_e3 = [0.99, 0.1413, 1.99, 0.0047, 3.00, 0.0710, 4.01, 0.0016, 5.01, 0.0154, 6.01, 0.0063, 7.01, 0.0122, 8.02, 0.0179, 9.00, 0.0044, 10.00, 0.0082, 11.01, 0.0058, 12.01, 0.0031, 13.02, 0.0045, 14.02, 0.0027, 15.02, 0.0004, 16.03, 0.0010, 17.01, 0.0008, 18.04, 0.0002, 19.04, 0.0004, 20.03, 0.0006, 21.04, 0.0004, 22.03, 0.0003, 23.04, 0.0004, 24.04, 0.0002, 25.04, 0.0003, 26.06, 0.0001, 27.04, 0.0003, 28.03, 0.0002, 29.02, 0.0003, 30.99, 0.0002, 32.04, 0.0006, 33.03, 0.0002, 34.04, 0.0003, 36.04, 0.0001] Bc_f3 = [0.99, 0.2534, 1.99, 0.0057, 3.00, 0.0476, 3.98, 0.0101, 4.98, 0.0334, 5.97, 0.0066, 6.98, 0.0489, 7.96, 0.0038, 8.96, 0.0096, 9.95, 0.0008, 10.96, 0.0056, 11.95, 0.0049, 12.95, 0.0029, 13.95, 0.0002, 14.95, 0.0006, 15.96, 0.0002, 16.96, 0.0008, 17.94, 0.0004, 18.93, 0.0002, 19.94, 0.0009, 20.94, 0.0002, 21.93, 0.0004, 22.94, 0.0004, 23.93, 0.0004, 25.90, 0.0004, 26.90, 0.0003, 27.89, 0.0001, 28.91, 0.0004, 29.87, 0.0001, 30.89, 0.0005, 32.89, 0.0002, 33.87, 0.0001] Bc_fs3 = [1.00, 0.3131, 1.99, 0.0095, 3.00, 0.0885, 3.99, 0.0194, 4.98, 0.0653, 5.99, 0.0049, 6.98, 0.0528, 7.99, 0.0038, 8.98, 0.0129, 9.97, 0.0042, 10.98, 0.0063, 11.97, 0.0023, 12.97, 0.0016, 13.98, 0.0002, 14.97, 0.0004, 15.97, 0.0005, 16.97, 0.0006, 17.96, 0.0001, 18.96, 0.0008, 20.95, 0.0007, 21.96, 0.0001, 22.95, 0.0001, 23.94, 0.0003, 25.94, 0.0004, 26.95, 0.0004, 27.94, 0.0005, 28.93, 0.0003, 29.94, 0.0003, 31.93, 0.0002, 33.92, 0.0002] Bc_g3 = [1.00, 0.2177, 2.01, 0.0024, 3.01, 0.0126, 4.02, 0.0067, 5.02, 0.0577, 6.02, 0.0083, 7.02, 0.0215, 8.03, 0.0034, 9.03, 0.0047, 10.04, 0.0046, 11.05, 0.0143, 12.04, 0.0037, 13.04, 0.0010, 14.05, 0.0005, 15.06, 0.0005, 16.06, 0.0003, 17.06, 0.0002, 18.06, 0.0004, 19.09, 0.0001, 20.08, 0.0003, 21.08, 0.0002, 23.08, 0.0003, 24.08, 0.0003, 25.08, 0.0001, 26.10, 0.0010, 27.11, 0.0002, 28.10, 0.0004, 30.12, 0.0003, 32.13, 0.0003] Bc_gs3 = [1.01, 0.1420, 2.01, 0.0026, 3.01, 0.0289, 4.03, 0.0162, 5.03, 0.0373, 6.02, 0.0015, 7.03, 0.0112, 8.05, 0.0068, 9.05, 0.0063, 10.04, 0.0027, 11.06, 0.0022, 12.07, 0.0004, 13.06, 0.0008, 14.07, 0.0011, 15.08, 0.0003, 16.08, 0.0002, 17.09, 0.0005, 19.11, 0.0003, 23.12, 0.0004, 24.12, 0.0003, 25.14, 0.0002, 26.14, 0.0003, 27.14, 0.0002, 28.14, 0.0002, 29.16, 0.0002, 30.16, 0.0001, 34.18, 0.0002] Bc_a3 = [1.01, 0.2365, 2.02, 0.0034, 3.03, 0.0242, 4.04, 0.0251, 5.04, 0.0203, 6.06, 0.0078, 7.06, 0.0213, 8.08, 0.0162, 9.09, 0.0121, 10.10, 0.0053, 11.11, 0.0024, 12.12, 0.0028, 13.14, 0.0010, 14.13, 0.0006, 15.15, 0.0009, 16.16, 0.0008, 17.17, 0.0009, 18.18, 0.0006, 19.19, 0.0003, 20.20, 0.0003, 21.20, 0.0003, 22.22, 0.0004, 23.22, 0.0002, 24.24, 0.0007, 26.26, 0.0003, 27.26, 0.0001, 29.29, 0.0003] Bc_as3 = [1.00, 0.1078, 2.01, 0.0072, 3.02, 0.0487, 4.04, 0.0332, 5.05, 0.0329, 6.06, 0.0069, 7.07, 0.0153, 8.08, 0.0061, 9.08, 0.0082, 10.09, 0.0023, 11.10, 0.0003, 12.11, 0.0009, 13.12, 0.0008, 14.13, 0.0007, 15.15, 0.0003, 16.16, 0.0006, 17.16, 0.0007, 18.16, 0.0003, 19.17, 0.0003, 20.18, 0.0005, 21.19, 0.0005, 22.20, 0.0005, 23.22, 0.0004, 24.23, 0.0001, 26.25, 0.0001, 27.25, 0.0001, 28.26, 0.0001] Bc_b3 = [1.01, 0.0572, 2.02, 0.0086, 3.03, 0.0724, 4.04, 0.0057, 5.04, 0.0365, 6.05, 0.0058, 7.06, 0.0083, 8.07, 0.0113, 9.08, 0.0102, 10.09, 0.0022, 11.10, 0.0012, 12.11, 0.0005, 13.11, 0.0014, 14.12, 0.0003, 15.13, 0.0008, 16.14, 0.0009, 17.15, 0.0003, 18.16, 0.0002, 19.17, 0.0006, 20.18, 0.0009, 21.19, 0.0002, 22.19, 0.0006, 23.20, 0.0004, 24.21, 0.0004, 25.22, 0.0001] Bc_c4 = [1.01, 0.0509, 2.02, 0.0146, 3.02, 0.0344, 4.03, 0.0126, 5.04, 0.0254, 6.05, 0.0004, 7.05, 0.0134, 8.06, 0.0069, 9.08, 0.0007, 10.09, 0.0005, 11.09, 0.0006, 12.09, 0.0004, 13.11, 0.0010, 14.12, 0.0001, 15.12, 0.0008, 16.13, 0.0001, 17.14, 0.0003, 18.15, 0.0002, 19.17, 0.0001, 20.16, 0.0004, 21.17, 0.0002] Bc_cs4 = [1.00, 0.1853, 2.00, 0.0169, 3.01, 0.0922, 4.01, 0.0035, 5.01, 0.0204, 6.01, 0.0046, 7.02, 0.0077, 8.02, 0.0085, 9.02, 0.0028, 10.05, 0.0002, 11.02, 0.0003, 12.03, 0.0006, 13.05, 0.0002, 14.03, 0.0006, 15.04, 0.0006, 16.04, 0.0004, 17.02, 0.0003, 18.04, 0.0006, 19.04, 0.0004, 20.04, 0.0003, 21.06, 0.0001, 22.04, 0.0001, 23.06, 0.0002] Bc_d4 = [1.00, 0.3391, 2.00, 0.0134, 2.99, 0.0186, 3.99, 0.0424, 4.98, 0.0122, 5.98, 0.0055, 6.97, 0.0197, 7.98, 0.0034, 8.97, 0.0017, 9.98, 0.0004, 10.96, 0.0008, 11.96, 0.0009, 12.96, 0.0003, 13.96, 0.0007, 14.95, 0.0004, 15.94, 0.0002, 16.95, 0.0003, 17.94, 0.0008, 18.93, 0.0002, 19.93, 0.0001] Bc_ds4 = [0.99, 0.3684, 1.98, 0.0187, 2.98, 0.0647, 3.97, 0.0186, 4.97, 0.0070, 5.96, 0.0127, 6.95, 0.0173, 7.94, 0.0011, 8.94, 0.0011, 9.93, 0.0014, 10.92, 0.0013, 11.90, 0.0001, 12.90, 0.0006, 13.91, 0.0003, 14.89, 0.0003, 15.89, 0.0001, 16.88, 0.0010, 17.88, 0.0004, 18.86, 0.0001, 19.86, 0.0002, 20.85, 0.0001] Bc_e4 = [1.00, 0.5390, 3.01, 0.0188, 4.00, 0.0247, 5.00, 0.0129, 6.01, 0.0050, 7.01, 0.0014, 8.01, 0.0012, 9.01, 0.0012, 10.01, 0.0010, 11.02, 0.0005, 12.02, 0.0002, 13.03, 0.0004] Bc_f4 = [1.01, 0.5398, 2.01, 0.0309, 3.01, 0.0727, 4.01, 0.0062, 5.01, 0.0041, 6.02, 0.0280, 7.02, 0.0005, 8.02, 0.0014, 9.02, 0.0013, 10.02, 0.0030, 11.03, 0.0006, 12.03, 0.0004, 14.03, 0.0003, 15.04, 0.0003, 16.04, 0.0007] Bc_fs4 = [1.00, 0.6398, 2.01, 0.0314, 3.01, 0.0423, 4.01, 0.0292, 5.01, 0.0093, 6.02, 0.0088, 7.02, 0.0010, 8.03, 0.0043, 9.02, 0.0004, 10.03, 0.0013, 11.03, 0.0003, 12.04, 0.0003, 13.02, 0.0002, 14.04, 0.0010, 15.04, 0.0006, 16.05, 0.0001, 17.04, 0.0003] Bc_g4 = [1.00, 0.5985, 1.99, 0.0192, 2.99, 0.0346, 3.99, 0.0257, 4.98, 0.0082, 5.98, 0.0037, 6.98, 0.0008, 7.99, 0.0013, 8.97, 0.0014, 9.98, 0.0016, 10.98, 0.0010, 11.98, 0.0005, 12.97, 0.0005, 13.97, 0.0008, 14.95, 0.0002, 15.96, 0.0003] Bc_gs4 = [1.00, 0.2635, 1.99, 0.0230, 2.99, 0.0936, 3.99, 0.0214, 4.99, 0.0320, 5.99, 0.0013, 6.99, 0.0020, 7.99, 0.0004, 8.99, 0.0014, 9.99, 0.0003, 10.99, 0.0003, 11.98, 0.0005, 12.98, 0.0015, 13.98, 0.0005, 14.98, 0.0003, 15.98, 0.0003, 18.98, 0.0001] Bc_a4 = [1.00, 0.1539, 2.00, 0.0355, 3.00, 0.0834, 4.01, 0.0210, 5.01, 0.0103, 6.00, 0.0035, 7.02, 0.0004, 8.01, 0.0008, 9.00, 0.0002, 10.01, 0.0001, 11.01, 0.0005, 12.01, 0.0007, 13.02, 0.0011, 14.01, 0.0003, 15.02, 0.0003, 18.02, 0.0002] Bc_as4 = [1.00, 0.1843, 2.01, 0.0229, 3.00, 0.0348, 4.01, 0.0157, 5.01, 0.0170, 6.01, 0.0037, 7.02, 0.0012, 8.02, 0.0027, 9.02, 0.0003, 10.02, 0.0011, 11.03, 0.0010, 12.03, 0.0007, 13.03, 0.0004, 14.03, 0.0002, 15.03, 0.0002, 17.04, 0.0002] Bc_b4 = [1.00, 0.5063, 2.01, 0.0563, 3.01, 0.0376, 4.01, 0.0383, 5.01, 0.0135, 6.02, 0.0081, 7.02, 0.0011, 8.02, 0.0049, 9.03, 0.0007, 10.03, 0.0006, 11.04, 0.0013, 12.04, 0.0007, 13.04, 0.0004, 14.05, 0.0002, 15.05, 0.0002, 17.05, 0.0002, 19.06, 0.0001] Bc_c5 = [1.00, 0.5459, 2.00, 0.0278, 3.01, 0.0456, 4.01, 0.0648, 5.02, 0.0035, 6.02, 0.0050, 7.02, 0.0025, 8.02, 0.0021, 9.02, 0.0005, 10.03, 0.0007, 11.03, 0.0016, 12.03, 0.0007, 13.04, 0.0001, 14.03, 0.0002, 15.04, 0.0002, 18.05, 0.0002, 19.05, 0.0001, 20.05, 0.0002] Bc_cs5 = [1.00, 0.2584, 2.01, 0.0583, 3.02, 0.1090, 4.02, 0.0290, 5.02, 0.0020, 6.03, 0.0018, 7.03, 0.0016, 8.03, 0.0001, 9.04, 0.0005, 10.05, 0.0017, 11.05, 0.0010, 12.05, 0.0002, 13.06, 0.0001, 14.06, 0.0001, 17.08, 0.0002, 18.08, 0.0001, 19.08, 0.0001] Bc_d5 = [1.00, 0.1626, 2.00, 0.0485, 3.01, 0.0856, 4.00, 0.0023, 5.01, 0.0096, 6.01, 0.0042, 7.01, 0.0015, 8.01, 0.0004, 9.02, 0.0019, 10.02, 0.0016, 11.02, 0.0003, 12.02, 0.0002, 13.02, 0.0002, 16.03, 0.0001, 17.03, 0.0001, 18.03, 0.0002, 19.03, 0.0001] Bc_ds5 = [1.00, 0.1756, 1.99, 0.1645, 2.99, 0.0381, 3.98, 0.0028, 4.98, 0.0042, 5.98, 0.0004, 6.97, 0.0025, 7.97, 0.0006, 8.96, 0.0022, 9.96, 0.0011, 10.96, 0.0002, 13.94, 0.0002, 14.94, 0.0002, 15.94, 0.0001, 16.93, 0.0001, 17.93, 0.0001] Bc_e5 = [0.99, 0.2661, 1.99, 0.1398, 2.99, 0.0589, 3.99, 0.0048, 4.98, 0.0022, 5.98, 0.0015, 6.97, 0.0021, 7.97, 0.0008, 8.96, 0.0011, 9.96, 0.0009, 10.95, 0.0004, 11.94, 0.0001, 13.94, 0.0001, 14.94, 0.0001, 15.94, 0.0001] Bc_f5 = [1.00, 0.1378, 2.00, 0.0654, 3.00, 0.1301, 4.00, 0.0049, 5.00, 0.0030, 6.01, 0.0018, 7.01, 0.0030, 8.01, 0.0015, 9.01, 0.0008, 10.01, 0.0001, 11.01, 0.0003, 12.01, 0.0002, 13.01, 0.0001, 14.01, 0.0002, 15.01, 0.0002, 16.02, 0.0001] Bc_fs5 = [1.00, 0.3952, 2.01, 0.1124, 3.01, 0.0326, 4.02, 0.0104, 5.03, 0.0013, 6.03, 0.0010, 7.03, 0.0009, 8.04, 0.0009, 9.05, 0.0002, 10.05, 0.0003, 11.05, 0.0001, 13.06, 0.0002, 14.07, 0.0003, 15.08, 0.0002] Bc_g5 = [1.01, 0.3434, 2.01, 0.0390, 3.02, 0.0051, 4.03, 0.0057, 5.04, 0.0042, 6.05, 0.0017, 7.06, 0.0022, 8.06, 0.0012, 9.07, 0.0002, 10.07, 0.0001, 11.08, 0.0002, 12.09, 0.0002, 13.10, 0.0002, 14.11, 0.0002, 15.12, 0.0001] Bc_gs5 = [1.00, 0.1109, 1.99, 0.0911, 2.98, 0.0061, 3.98, 0.0062, 4.98, 0.0020, 5.97, 0.0006, 6.96, 0.0008, 7.96, 0.0013, 8.95, 0.0002, 10.94, 0.0002, 11.94, 0.0002, 12.93, 0.0002, 13.93, 0.0001] Bc_a5 = [1.00, 0.1585, 2.00, 0.0562, 3.00, 0.0039, 4.00, 0.0064, 5.00, 0.0016, 6.00, 0.0022, 7.00, 0.0009, 8.00, 0.0004, 9.00, 0.0002, 11.00, 0.0003, 12.00, 0.0003, 13.00, 0.0002, 14.00, 0.0002] Bc_as5 = [0.99, 0.1211, 1.98, 0.0394, 2.97, 0.0093, 3.96, 0.0024, 4.95, 0.0030, 5.94, 0.0027, 6.93, 0.0006, 8.92, 0.0002, 10.90, 0.0001, 12.88, 0.0001] # # # # # bassoon? Bsn_as1 = [1.00, 0.0038, 2.02, 0.0235, 3.04, 0.0511, 4.06, 0.0348, 5.07, 0.0491, 6.09, 0.0518, 7.11, 0.0184, 8.12, 0.0381, 9.11, 0.1027, 10.13, 0.0412, 11.15, 0.0112, 12.17, 0.0144, 13.18, 0.0097, 14.20, 0.0074, 15.21, 0.0081, 16.23, 0.0067, 17.22, 0.0108, 18.24, 0.0113, 19.25, 0.0114, 20.28, 0.0066, 21.30, 0.0065, 22.32, 0.0035, 23.33, 0.0041, 24.33, 0.0036, 25.34, 0.0025, 26.35, 0.0010, 27.37, 0.0021, 28.39, 0.0007, 29.42, 0.0006, 30.42, 0.0009, 31.43, 0.0005, 32.43, 0.0003, 33.46, 0.0005, 34.46, 0.0002, 35.48, 0.0002, 36.48, 0.0004, 37.52, 0.0003, 38.53, 0.0003, 39.55, 0.0002, 40.56, 0.0002, 51.69, 0.0001, 54.72, 0.0002] Bsn_b1 = [1.01, 0.0039, 2.02, 0.0230, 3.02, 0.0517, 4.03, 0.0473, 5.03, 0.0443, 6.03, 0.0691, 7.03, 0.0664, 8.04, 0.0408, 9.04, 0.1283, 10.06, 0.0429, 11.07, 0.0339, 12.08, 0.0223, 13.08, 0.0207, 14.08, 0.0256, 15.08, 0.0171, 16.09, 0.0106, 17.09, 0.0136, 18.09, 0.0082, 19.12, 0.0052, 20.12, 0.0041, 21.13, 0.0015, 22.13, 0.0023, 23.12, 0.0021, 24.12, 0.0009, 25.13, 0.0029, 26.14, 0.0014, 27.15, 0.0003, 28.15, 0.0010, 29.17, 0.0013, 30.18, 0.0003, 31.19, 0.0005, 32.19, 0.0007, 33.19, 0.0004, 34.20, 0.0005, 35.19, 0.0005, 36.19, 0.0003, 37.21, 0.0003, 38.23, 0.0002, 39.23, 0.0001, 40.23, 0.0001, 43.23, 0.0001, 46.26, 0.0002, 49.27, 0.0002, 51.27, 0.0003, 52.27, 0.0002, 53.28, 0.0002] Bsn_c2 = [1.01, 0.0047, 2.03, 0.0390, 3.04, 0.0460, 4.04, 0.0217, 5.05, 0.0464, 6.05, 0.0631, 7.06, 0.0874, 8.07, 0.1167, 9.08, 0.0339, 10.09, 0.0209, 11.11, 0.0133, 12.12, 0.0088, 13.11, 0.0092, 14.14, 0.0032, 15.15, 0.0026, 16.16, 0.0061, 17.17, 0.0019, 18.17, 0.0051, 19.18, 0.0161, 20.18, 0.0048, 21.20, 0.0044, 22.21, 0.0035, 23.23, 0.0010, 24.24, 0.0028, 25.25, 0.0006, 26.26, 0.0013, 27.27, 0.0016, 28.26, 0.0002, 29.28, 0.0006, 30.28, 0.0006, 31.30, 0.0004, 32.32, 0.0012, 33.33, 0.0003, 34.34, 0.0003, 35.35, 0.0002, 36.34, 0.0001, 43.41, 0.0001, 46.43, 0.0001, 48.44, 0.0001, 51.48, 0.0001] Bsn_cs2 = [1.01, 0.0090, 2.02, 0.0531, 3.01, 0.0318, 4.01, 0.0199, 5.02, 0.0211, 6.04, 0.0629, 7.04, 0.1340, 8.05, 0.0925, 9.04, 0.0206, 10.04, 0.0584, 11.05, 0.0140, 12.07, 0.0066, 13.08, 0.0068, 14.08, 0.0011, 15.07, 0.0028, 16.07, 0.0015, 17.08, 0.0041, 18.10, 0.0106, 19.10, 0.0034, 20.10, 0.0033, 21.10, 0.0020, 22.10, 0.0021, 23.11, 0.0040, 24.13, 0.0001, 25.12, 0.0004, 26.13, 0.0003, 28.13, 0.0004, 29.14, 0.0002, 30.16, 0.0001, 31.17, 0.0001, 43.20, 0.0001, 46.22, 0.0002] Bsn_d2 = [1.01, 0.0616, 2.00, 0.0436, 3.00, 0.0430, 3.99, 0.0491, 5.01, 0.0358, 6.01, 0.1695, 7.00, 0.1562, 7.99, 0.0174, 8.99, 0.0062, 10.01, 0.0054, 11.00, 0.0104, 12.00, 0.0055, 12.99, 0.0052, 13.99, 0.0018, 15.00, 0.0021, 16.00, 0.0019, 16.99, 0.0087, 17.98, 0.0025, 18.99, 0.0027, 20.00, 0.0015, 21.00, 0.0024, 21.98, 0.0015, 22.99, 0.0002, 24.00, 0.0006, 25.99, 0.0001, 26.95, 0.0001, 28.00, 0.0001, 28.94, 0.0001, 30.01, 0.0002] Bsn_ds2 = [1.01, 0.0769, 2.01, 0.0341, 3.00, 0.0240, 4.00, 0.0633, 5.00, 0.0124, 5.99, 0.0850, 6.99, 0.1044, 7.99, 0.0115, 8.99, 0.0046, 10.00, 0.0048, 11.00, 0.0054, 12.00, 0.0082, 13.00, 0.0033, 14.00, 0.0080, 15.00, 0.0022, 15.99, 0.0081, 16.99, 0.0028, 17.98, 0.0038, 18.98, 0.0028, 19.99, 0.0032, 20.99, 0.0007, 22.00, 0.0003, 22.98, 0.0004, 23.99, 0.0001, 24.98, 0.0005, 25.98, 0.0002, 26.97, 0.0003, 28.98, 0.0001, 38.97, 0.0001, 40.97, 0.0001] Bsn_e2 = [1.00, 0.0369, 1.98, 0.0190, 3.00, 0.0291, 3.98, 0.0844, 5.00, 0.0730, 5.98, 0.0856, 7.00, 0.0563, 7.98, 0.0792, 9.00, 0.0139, 9.97, 0.0127, 10.99, 0.0046, 11.96, 0.0052, 12.99, 0.0043, 13.97, 0.0030, 14.99, 0.0102, 15.98, 0.0020, 16.97, 0.0029, 17.98, 0.0010, 18.96, 0.0040, 19.98, 0.0008, 20.97, 0.0004, 21.99, 0.0001, 23.98, 0.0004, 25.96, 0.0002, 26.93, 0.0001, 36.94, 0.0001] Bsn_f2 = [0.99, 0.0208, 2.00, 0.0164, 3.01, 0.0576, 4.02, 0.0547, 5.02, 0.0965, 5.99, 0.1701, 7.00, 0.0206, 8.01, 0.0040, 9.02, 0.0075, 10.02, 0.0033, 11.00, 0.0067, 12.00, 0.0021, 13.01, 0.0010, 14.02, 0.0072, 15.03, 0.0014, 16.01, 0.0028, 17.01, 0.0034, 18.02, 0.0026, 19.03, 0.0007, 20.05, 0.0004, 20.43, 0.0001, 22.02, 0.0001, 24.01, 0.0003, 26.03, 0.0001] Bsn_fs2 = [1.00, 0.0112, 1.99, 0.0211, 2.98, 0.0379, 3.97, 0.0630, 4.98, 0.0727, 5.97, 0.1555, 6.95, 0.0348, 7.94, 0.0362, 8.96, 0.0083, 9.94, 0.0145, 10.92, 0.0070, 11.91, 0.0031, 12.93, 0.0059, 13.92, 0.0054, 14.91, 0.0024, 15.89, 0.0024, 16.88, 0.0045, 17.90, 0.0013, 18.91, 0.0007, 19.87, 0.0005, 20.87, 0.0004, 21.88, 0.0002, 22.85, 0.0007, 23.84, 0.0003, 24.83, 0.0002, 26.84, 0.0001, 28.80, 0.0002, 29.80, 0.0001, 30.81, 0.0003, 31.81, 0.0001, 32.78, 0.0003, 33.77, 0.0001, 34.79, 0.0002] Bsn_g2 = [0.98, 0.0330, 1.99, 0.0314, 2.95, 0.0487, 3.95, 0.0272, 4.95, 0.2864, 5.91, 0.0849, 6.92, 0.0047, 7.89, 0.0049, 8.88, 0.0015, 9.88, 0.0060, 10.85, 0.0051, 11.85, 0.0013, 12.83, 0.0083, 13.82, 0.0018, 14.82, 0.0010, 15.78, 0.0032, 16.79, 0.0007, 17.77, 0.0004, 18.76, 0.0005, 19.76, 0.0008, 20.72, 0.0004, 21.72, 0.0009, 22.72, 0.0003, 23.69, 0.0002] Bsn_gs2 = [0.98, 0.0321, 1.98, 0.0281, 2.99, 0.0196, 3.99, 0.0683, 4.96, 0.2698, 5.95, 0.0125, 6.95, 0.0153, 7.96, 0.0034, 8.96, 0.0050, 9.93, 0.0056, 10.92, 0.0049, 11.92, 0.0160, 12.92, 0.0072, 13.91, 0.0013, 14.89, 0.0028, 15.91, 0.0005, 16.86, 0.0004, 17.89, 0.0006, 18.89, 0.0009, 19.87, 0.0005, 20.85, 0.0001, 21.87, 0.0003, 27.83, 0.0001, 28.82, 0.0002] Bsn_a2 = [0.99, 0.0170, 2.00, 0.0296, 3.00, 0.0324, 4.01, 0.1542, 5.02, 0.1393, 6.02, 0.0249, 7.03, 0.0041, 8.03, 0.0022, 9.01, 0.0043, 10.02, 0.0077, 11.03, 0.0092, 12.04, 0.0021, 13.04, 0.0027, 14.05, 0.0026, 15.06, 0.0007, 16.05, 0.0001, 17.05, 0.0003, 18.04, 0.0006, 19.04, 0.0004, 20.05, 0.0002, 26.06, 0.0003, 27.06, 0.0002, 29.07, 0.0001] Bsn_as2 = [1.01, 0.0153, 2.00, 0.0261, 3.00, 0.0305, 3.99, 0.1573, 4.97, 0.0908, 5.98, 0.0053, 6.97, 0.0054, 7.98, 0.0159, 8.99, 0.0031, 9.99, 0.0015, 10.96, 0.0124, 11.96, 0.0020, 12.95, 0.0026, 13.94, 0.0034, 14.94, 0.0005, 16.95, 0.0007, 17.93, 0.0002, 18.94, 0.0003, 24.92, 0.0002, 25.91, 0.0002, 27.89, 0.0002, 28.89, 0.0001] Bsn_b2 = [1.01, 0.0061, 2.00, 0.0199, 2.99, 0.0393, 3.98, 0.2060, 5.00, 0.0178, 5.99, 0.0340, 6.98, 0.0029, 7.98, 0.0065, 8.99, 0.0102, 9.99, 0.0271, 10.98, 0.0068, 11.97, 0.0032, 12.97, 0.0060, 13.99, 0.0002, 14.98, 0.0005, 15.96, 0.0008, 16.96, 0.0008, 17.98, 0.0006, 18.98, 0.0001, 21.96, 0.0001, 22.96, 0.0002, 23.95, 0.0002, 24.94, 0.0002, 25.94, 0.0001, 26.95, 0.0001, 28.95, 0.0001] Bsn_c3 = [1.00, 0.0082, 1.98, 0.0489, 2.99, 0.1248, 3.98, 0.1892, 4.97, 0.0149, 5.98, 0.0017, 6.96, 0.0172, 7.95, 0.0072, 8.96, 0.0028, 9.95, 0.0114, 10.93, 0.0055, 11.94, 0.0029, 12.96, 0.0005, 13.92, 0.0017, 14.93, 0.0008, 15.91, 0.0012, 16.90, 0.0005, 17.91, 0.0001, 20.90, 0.0001, 21.88, 0.0003, 22.87, 0.0001, 24.85, 0.0002, 28.85, 0.0001] Bsn_cs3 = [1.01, 0.0191, 2.00, 0.0451, 2.99, 0.2847, 4.00, 0.0925, 5.00, 0.0143, 5.99, 0.0024, 7.00, 0.0055, 8.00, 0.0131, 8.99, 0.0286, 9.98, 0.0021, 10.99, 0.0020, 11.99, 0.0010, 12.96, 0.0003, 13.97, 0.0005, 14.98, 0.0009, 15.97, 0.0005, 20.97, 0.0003, 21.97, 0.0003] Bsn_d3 = [1.01, 0.0218, 2.01, 0.0560, 3.01, 0.1696, 4.01, 0.0504, 5.00, 0.0268, 6.02, 0.0018, 7.03, 0.0081, 8.03, 0.0035, 9.04, 0.0026, 10.04, 0.0023, 11.02, 0.0045, 12.04, 0.0002, 13.04, 0.0004, 14.04, 0.0007, 15.05, 0.0004, 16.06, 0.0001, 21.06, 0.0001, 22.07, 0.0003] Bsn_ds3 = [1.00, 0.0185, 1.99, 0.0627, 2.98, 0.2037, 3.97, 0.0211, 4.98, 0.0204, 5.97, 0.0434, 6.95, 0.0056, 7.94, 0.0171, 8.95, 0.0014, 9.94, 0.0062, 10.93, 0.0007, 11.91, 0.0006, 12.91, 0.0004, 13.90, 0.0004, 14.90, 0.0003, 16.88, 0.0001, 17.89, 0.0002, 18.88, 0.0002, 20.86, 0.0004, 21.84, 0.0002, 22.85, 0.0001] Bsn_e3 = [1.00, 0.0167, 2.00, 0.0801, 3.01, 0.2223, 4.02, 0.0252, 5.02, 0.0098, 6.01, 0.0058, 7.02, 0.0073, 8.03, 0.0032, 9.03, 0.0066, 10.04, 0.0011, 10.66, 0.0001, 12.04, 0.0013, 13.04, 0.0013, 14.05, 0.0010, 15.05, 0.0004, 18.07, 0.0002, 20.06, 0.0003, 23.07, 0.0001] Bsn_f3 = [1.00, 0.0152, 2.01, 0.0471, 3.00, 0.1985, 4.00, 0.0345, 5.01, 0.0136, 6.00, 0.0064, 7.01, 0.0153, 8.00, 0.0011, 9.00, 0.0093, 10.02, 0.0006, 11.01, 0.0006, 12.00, 0.0001, 13.01, 0.0008, 14.01, 0.0006, 16.02, 0.0001, 17.01, 0.0003, 19.01, 0.0002, 22.01, 0.0001, 23.02, 0.0002] Bsn_fs3 = [1.01, 0.0363, 2.01, 0.1019, 3.01, 0.3226, 4.01, 0.1274, 5.03, 0.0397, 6.03, 0.0061, 7.02, 0.0117, 8.03, 0.0099, 9.04, 0.0006, 10.04, 0.0026, 11.04, 0.0020, 12.04, 0.0008, 13.05, 0.0001, 14.06, 0.0002, 15.05, 0.0002, 19.07, 0.0002] Bsn_g3 = [0.99, 0.0358, 1.99, 0.0535, 2.99, 0.1072, 3.99, 0.0270, 4.99, 0.0106, 5.98, 0.0010, 6.97, 0.0007, 7.97, 0.0041, 8.95, 0.0002, 9.94, 0.0002, 10.97, 0.0002, 12.96, 0.0001] Bsn_gs3 = [1.00, 0.0382, 1.99, 0.0923, 2.99, 0.0199, 3.99, 0.0156, 4.96, 0.0044, 5.98, 0.0130, 6.97, 0.0020, 7.97, 0.0033, 8.97, 0.0007, 9.95, 0.0002, 10.95, 0.0001, 12.95, 0.0001] Bsn_a3 = [1.00, 0.0469, 2.00, 0.2187, 3.00, 0.0287, 4.01, 0.0121, 5.01, 0.0114, 6.01, 0.0022, 7.01, 0.0044, 8.02, 0.0008, 9.02, 0.0004, 10.01, 0.0003, 13.02, 0.0001] Bsn_as3 = [1.01, 0.0298, 2.01, 0.2016, 3.02, 0.0058, 4.00, 0.0258, 5.00, 0.0008, 6.00, 0.0029, 7.00, 0.0031, 8.01, 0.0010, 9.01, 0.0004, 10.00, 0.0001, 13.01, 0.0001] Bsn_b3 = [1.01, 0.0341, 2.01, 0.2100, 3.01, 0.0390, 4.02, 0.0044, 5.02, 0.0213, 6.02, 0.0044, 7.02, 0.0006, 8.03, 0.0012, 9.04, 0.0002, 12.05, 0.0002, 13.05, 0.0002] Bsn_c4 = [1.00, 0.0684, 2.00, 0.2934, 3.00, 0.0096, 4.00, 0.0084, 5.00, 0.0039, 6.00, 0.0059, 7.00, 0.0010, 8.00, 0.0006] Bsn_cs4 = [1.01, 0.0848, 2.01, 0.3334, 3.02, 0.0152, 4.03, 0.0032, 5.03, 0.0059, 6.03, 0.0032, 7.05, 0.0013, 8.05, 0.0007, 9.05, 0.0001, 10.06, 0.0001, 11.06, 0.0002] Bsn_d4 = [1.00, 0.1020, 2.00, 0.1065, 3.00, 0.0086, 3.99, 0.0013, 5.00, 0.0038, 6.00, 0.0011, 7.00, 0.0003, 8.00, 0.0002, 11.01, 0.0003] Bsn_ds4 = [1.00, 0.0469, 1.99, 0.0248, 2.96, 0.0045, 3.99, 0.0163, 4.99, 0.0042, 6.00, 0.0004, 6.98, 0.0003] Bsn_e4 = [1.00, 0.0389, 2.01, 0.0439, 3.01, 0.0110, 4.01, 0.0072, 5.02, 0.0041, 6.02, 0.0005, 7.02, 0.0006, 9.03, 0.0003] Bsn_f4 = [1.00, 0.0229, 2.00, 0.0331, 2.99, 0.0138, 4.00, 0.0008, 4.99, 0.0010, 5.99, 0.0004] Bsn_fs4 = [1.00, 0.1522, 1.99, 0.0563, 3.00, 0.0126, 3.99, 0.0035, 4.28, 0.0002, 4.35, 0.0002, 4.43, 0.0001, 4.98, 0.0001, 5.99, 0.0001, 6.98, 0.0002] Bsn_g4 = [1.00, 0.0415, 2.00, 0.0486, 3.00, 0.0068, 4.00, 0.0148, 5.00, 0.0016, 6.00, 0.0001] Bsn_gs4 = [1.01, 0.0811, 2.01, 0.0402, 3.03, 0.0114, 4.04, 0.0044, 5.03, 0.0004] Bsn_a4 = [1.00, 0.0399, 2.01, 0.0195, 3.00, 0.0069, 4.01, 0.0005, 5.01, 0.0009, 6.01, 0.0002, 7.01, 0.0003] Bsn_as4 = [1.01, 0.1259, 2.01, 0.0811, 3.01, 0.0051, 4.01, 0.0027, 5.01, 0.0008, 6.02, 0.0002, 7.02, 0.0003] Bsn_b4 = [1.01, 0.1159, 2.02, 0.0380, 3.03, 0.0089, 4.04, 0.0038, 5.05, 0.0006, 6.05, 0.0002] Bsn_c5 = [1.02, 0.0871, 2.03, 0.0356, 3.04, 0.0192, 4.06, 0.0063, 6.09, 0.0003, 7.11, 0.0002] Bsn_cs5 = [1.01, 0.2418, 2.02, 0.0674, 3.02, 0.0067, 4.03, 0.0021, 5.03, 0.0004, 6.05, 0.0003, 7.05, 0.0005, 8.06, 0.0001] Bsn_d5 = [1.01, 0.1931, 2.01, 0.0462, 3.02, 0.0118, 4.02, 0.0014, 5.03, 0.0006, 6.03, 0.0008, 8.04, 0.0001] # # # # # cello C_c2 = [1.00, 0.0047, 1.99, 0.0251, 2.99, 0.0546, 4.01, 0.1041, 4.99, 0.0279, 5.97, 0.0219, 6.93, 0.0137, 7.94, 0.0349, 8.91, 0.0151, 10.04, 0.0565, 11.00, 0.0458, 12.00, 0.0216, 12.97, 0.0151, 14.52, 0.0025, 14.95, 0.0088, 16.03, 0.0103, 17.02, 0.0027, 17.98, 0.0089, 19.00, 0.0052, 20.03, 0.0048, 20.93, 0.0051, 22.04, 0.0023, 23.01, 0.0072, 24.01, 0.0022, 24.99, 0.0027, 26.03, 0.0036, 27.47, 0.0011, 27.99, 0.0011, 29.02, 0.0012, 29.86, 0.0005, 30.97, 0.0020, 31.88, 0.0006, 33.02, 0.0021, 33.98, 0.0011, 35.02, 0.0010, 36.01, 0.0028, 37.00, 0.0022, 37.99, 0.0014, 39.00, 0.0014, 40.01, 0.0022, 41.04, 0.0021, 42.02, 0.0008, 43.01, 0.0024, 44.02, 0.0007, 45.01, 0.0003, 46.00, 0.0002, 48.03, 0.0002, 48.85, 0.0002, 51.01, 0.0001, 51.98, 0.0001, 54.89, 0.0002, 55.39, 0.0002, 56.38, 0.0001, 58.02, 0.0002, 58.98, 0.0002, 62.00, 0.0001, 64.09, 0.0001, 65.02, 0.0002] C_cs2 = [1.01, 0.0160, 2.02, 0.0737, 3.02, 0.0287, 4.02, 0.0183, 5.02, 0.0669, 6.04, 0.0520, 7.05, 0.0043, 8.06, 0.0066, 9.06, 0.0194, 10.05, 0.0193, 11.05, 0.0254, 12.06, 0.0153, 13.08, 0.0041, 14.11, 0.0037, 15.09, 0.0098, 16.09, 0.0022, 17.09, 0.0053, 18.10, 0.0135, 19.12, 0.0118, 20.13, 0.0057, 21.15, 0.0039, 22.14, 0.0023, 23.14, 0.0027, 24.15, 0.0026, 25.16, 0.0012, 26.16, 0.0011, 27.17, 0.0020, 28.17, 0.0015, 29.14, 0.0020, 30.19, 0.0013, 31.19, 0.0019, 32.20, 0.0007, 33.21, 0.0005, 34.22, 0.0004, 35.19, 0.0012, 36.20, 0.0005, 37.25, 0.0015, 38.25, 0.0018, 39.26, 0.0014, 40.40, 0.0007, 41.25, 0.0010, 42.24, 0.0009, 43.28, 0.0003, 44.31, 0.0002, 45.28, 0.0002, 46.30, 0.0001, 48.29, 0.0002, 49.31, 0.0004, 50.34, 0.0001, 51.35, 0.0002, 52.32, 0.0003, 53.50, 0.0001, 54.28, 0.0001, 57.34, 0.0001, 58.35, 0.0002] C_d2 = [1.00, 0.0368, 2.02, 0.1070, 3.03, 0.0107, 4.04, 0.0445, 5.04, 0.0477, 6.04, 0.0281, 7.07, 0.0191, 8.06, 0.0205, 9.06, 0.0456, 10.07, 0.0283, 11.07, 0.0320, 12.08, 0.0094, 13.35, 0.0009, 14.11, 0.0042, 15.11, 0.0066, 16.12, 0.0075, 17.13, 0.0117, 18.14, 0.0043, 19.16, 0.0067, 20.14, 0.0020, 21.16, 0.0046, 22.16, 0.0011, 23.17, 0.0029, 24.17, 0.0010, 25.18, 0.0011, 26.19, 0.0013, 27.18, 0.0029, 28.20, 0.0039, 29.21, 0.0048, 30.23, 0.0020, 31.23, 0.0006, 32.25, 0.0018, 33.23, 0.0009, 34.24, 0.0012, 35.28, 0.0016, 36.27, 0.0018, 37.28, 0.0019, 38.28, 0.0031, 39.28, 0.0008, 40.25, 0.0001, 41.30, 0.0002, 42.31, 0.0002, 43.32, 0.0001, 44.32, 0.0002, 45.33, 0.0002, 46.34, 0.0004, 48.37, 0.0002, 49.37, 0.0006, 50.37, 0.0004, 51.35, 0.0001, 52.35, 0.0001, 53.40, 0.0001, 54.39, 0.0002, 55.41, 0.0003, 56.43, 0.0002, 57.41, 0.0001, 64.49, 0.0001, 65.50, 0.0001] C_ds2 = [1.01, 0.0485, 2.01, 0.1800, 3.01, 0.0143, 4.02, 0.1265, 5.03, 0.1372, 6.03, 0.0102, 7.02, 0.0261, 8.03, 0.0216, 9.02, 0.0145, 10.04, 0.0292, 11.05, 0.0133, 12.06, 0.0038, 13.06, 0.0026, 14.04, 0.0041, 15.06, 0.0053, 16.06, 0.0014, 17.08, 0.0051, 18.06, 0.0048, 19.07, 0.0026, 20.07, 0.0025, 21.09, 0.0039, 22.08, 0.0018, 23.08, 0.0031, 24.11, 0.0023, 25.10, 0.0035, 26.10, 0.0037, 27.10, 0.0019, 28.10, 0.0030, 29.11, 0.0020, 30.10, 0.0036, 31.13, 0.0020, 32.10, 0.0011, 33.13, 0.0013, 34.12, 0.0027, 35.11, 0.0022, 36.13, 0.0018, 37.15, 0.0005, 38.13, 0.0002, 39.17, 0.0002, 40.16, 0.0006, 41.13, 0.0002, 43.16, 0.0002, 44.16, 0.0002, 45.15, 0.0002, 46.18, 0.0003, 47.17, 0.0001, 48.18, 0.0001, 49.16, 0.0002, 50.19, 0.0001, 58.35, 0.0001] C_e2 = [1.02, 0.0293, 2.00, 0.1425, 3.04, 0.0549, 4.03, 0.0364, 5.03, 0.1171, 6.07, 0.0100, 7.04, 0.0253, 8.06, 0.0448, 9.08, 0.0115, 10.06, 0.0116, 11.08, 0.0048, 12.09, 0.0174, 13.09, 0.0037, 14.11, 0.0029, 15.11, 0.0104, 16.12, 0.0036, 17.14, 0.0046, 18.13, 0.0016, 19.16, 0.0027, 20.13, 0.0036, 21.14, 0.0012, 22.18, 0.0027, 23.17, 0.0011, 24.18, 0.0033, 25.20, 0.0019, 26.20, 0.0016, 26.99, 0.0005, 28.22, 0.0009, 29.19, 0.0052, 30.23, 0.0021, 31.21, 0.0015, 32.24, 0.0014, 33.23, 0.0019, 34.22, 0.0033, 35.27, 0.0009, 36.27, 0.0002, 38.30, 0.0004, 39.27, 0.0005, 40.26, 0.0004, 41.25, 0.0003, 42.31, 0.0002, 43.34, 0.0007, 44.32, 0.0006, 45.32, 0.0003, 46.36, 0.0002, 47.36, 0.0001, 48.34, 0.0002, 49.37, 0.0002, 54.40, 0.0002, 55.40, 0.0001] C_f2 = [0.99, 0.0765, 2.00, 0.0311, 3.02, 0.0635, 4.02, 0.0223, 5.15, 0.0022, 6.01, 0.0457, 7.03, 0.0278, 8.04, 0.0188, 9.04, 0.0344, 10.02, 0.0093, 11.00, 0.0034, 12.05, 0.0172, 13.06, 0.0106, 14.07, 0.0020, 15.02, 0.0011, 16.06, 0.0022, 17.08, 0.0027, 18.08, 0.0007, 19.05, 0.0016, 20.07, 0.0015, 21.07, 0.0057, 22.10, 0.0010, 23.07, 0.0030, 24.07, 0.0013, 25.07, 0.0019, 26.09, 0.0018, 27.10, 0.0042, 28.10, 0.0020, 29.09, 0.0015, 30.12, 0.0027, 31.11, 0.0021, 32.13, 0.0035, 33.08, 0.0003, 34.12, 0.0005, 35.12, 0.0004, 36.15, 0.0008, 37.15, 0.0003, 39.14, 0.0005, 40.17, 0.0003, 41.15, 0.0003, 42.14, 0.0002, 43.14, 0.0001, 44.17, 0.0002, 51.84, 0.0001, 53.18, 0.0001, 54.22, 0.0001] C_fs2 = [1.02, 0.0680, 2.02, 0.0790, 3.03, 0.0722, 4.03, 0.0851, 5.03, 0.0169, 6.03, 0.0073, 7.02, 0.0859, 8.02, 0.0250, 9.04, 0.0073, 10.07, 0.0037, 11.04, 0.0035, 12.01, 0.0009, 13.09, 0.0056, 14.05, 0.0059, 15.05, 0.0031, 16.07, 0.0050, 17.07, 0.0034, 18.07, 0.0010, 19.47, 0.0004, 20.10, 0.0045, 21.10, 0.0028, 22.09, 0.0039, 23.10, 0.0032, 24.11, 0.0007, 25.09, 0.0017, 26.10, 0.0041, 27.16, 0.0006, 28.12, 0.0021, 29.13, 0.0021, 30.39, 0.0004, 31.11, 0.0013, 32.17, 0.0004, 33.13, 0.0005, 34.14, 0.0014, 35.07, 0.0002, 36.06, 0.0001, 37.16, 0.0002, 39.18, 0.0007, 40.18, 0.0002, 41.22, 0.0001, 42.21, 0.0002, 43.24, 0.0003, 49.15, 0.0001, 51.22, 0.0001, 52.23, 0.0002] C_g2 = [1.00, 0.0434, 2.00, 0.0983, 2.99, 0.0548, 3.98, 0.0364, 4.98, 0.0228, 5.97, 0.0390, 6.97, 0.0091, 7.96, 0.0154, 9.03, 0.0078, 9.96, 0.0174, 10.98, 0.0110, 11.96, 0.0125, 12.97, 0.0039, 13.94, 0.0028, 14.95, 0.0057, 15.94, 0.0020, 16.95, 0.0046, 17.94, 0.0011, 18.97, 0.0017, 19.94, 0.0010, 20.98, 0.0025, 21.94, 0.0040, 22.94, 0.0030, 23.91, 0.0064, 24.95, 0.0013, 25.96, 0.0009, 26.94, 0.0015, 27.92, 0.0014, 28.93, 0.0017, 29.91, 0.0015, 30.92, 0.0010, 31.49, 0.0002, 32.83, 0.0002, 33.89, 0.0003, 34.92, 0.0002, 36.91, 0.0003, 37.91, 0.0002, 40.84, 0.0002, 41.87, 0.0002, 42.89, 0.0002] C_gs2 = [0.98, 0.0579, 1.97, 0.0445, 2.97, 0.1178, 3.97, 0.0806, 4.96, 0.1095, 5.94, 0.0245, 6.92, 0.0203, 7.91, 0.0153, 8.92, 0.0186, 9.93, 0.0129, 10.92, 0.0154, 11.89, 0.0040, 12.87, 0.0036, 13.88, 0.0033, 14.74, 0.0006, 15.85, 0.0011, 16.86, 0.0020, 17.85, 0.0026, 18.84, 0.0040, 19.84, 0.0022, 20.83, 0.0022, 21.82, 0.0020, 22.80, 0.0060, 23.79, 0.0073, 24.81, 0.0023, 25.80, 0.0030, 26.79, 0.0008, 27.77, 0.0005, 28.75, 0.0012, 29.73, 0.0017, 30.75, 0.0003, 31.74, 0.0005, 32.74, 0.0003, 33.71, 0.0003, 34.70, 0.0005, 35.72, 0.0002, 36.67, 0.0003, 38.69, 0.0002, 39.71, 0.0002, 40.65, 0.0001] C_a2 = [0.99, 0.0612, 1.98, 0.0094, 2.98, 0.0435, 3.98, 0.0098, 4.97, 0.0550, 5.97, 0.0775, 6.96, 0.0337, 7.96, 0.0330, 8.97, 0.0137, 9.95, 0.0122, 10.95, 0.0080, 11.94, 0.0082, 13.00, 0.0009, 13.95, 0.0034, 14.96, 0.0029, 15.94, 0.0011, 16.94, 0.0041, 17.95, 0.0060, 18.92, 0.0008, 19.97, 0.0026, 20.94, 0.0009, 21.94, 0.0041, 22.92, 0.0050, 23.92, 0.0056, 24.93, 0.0030, 25.92, 0.0015, 26.22, 0.0002, 27.90, 0.0011, 28.90, 0.0004, 29.89, 0.0007, 30.89, 0.0009, 31.90, 0.0004, 32.91, 0.0002, 33.88, 0.0005, 34.86, 0.0001, 35.89, 0.0003, 36.87, 0.0006, 37.89, 0.0003, 38.93, 0.0002, 46.84, 0.0001, 54.82, 0.0001] C_as2 = [1.00, 0.0401, 1.99, 0.0101, 2.98, 0.0769, 3.96, 0.0345, 4.96, 0.0696, 5.97, 0.0342, 6.95, 0.0413, 7.95, 0.0130, 8.92, 0.0147, 9.93, 0.0034, 10.94, 0.0135, 11.94, 0.0007, 12.92, 0.0013, 13.91, 0.0017, 14.89, 0.0026, 15.88, 0.0019, 16.89, 0.0039, 17.88, 0.0034, 18.86, 0.0037, 19.84, 0.0009, 20.85, 0.0021, 21.86, 0.0021, 22.85, 0.0049, 23.82, 0.0042, 24.82, 0.0007, 25.80, 0.0007, 26.82, 0.0003, 27.81, 0.0004, 28.79, 0.0009, 29.79, 0.0007, 30.77, 0.0005, 31.18, 0.0001, 31.66, 0.0001, 32.76, 0.0002, 33.78, 0.0002, 34.76, 0.0004, 35.75, 0.0002, 36.74, 0.0002] C_b2 = [1.00, 0.0486, 1.99, 0.0621, 2.98, 0.0627, 3.98, 0.0145, 4.98, 0.0494, 5.97, 0.0353, 6.96, 0.0287, 7.96, 0.0169, 8.95, 0.0167, 9.95, 0.0039, 10.94, 0.0075, 11.94, 0.0043, 12.95, 0.0018, 13.92, 0.0040, 14.94, 0.0054, 15.93, 0.0046, 16.93, 0.0035, 17.92, 0.0037, 18.93, 0.0036, 19.91, 0.0055, 20.89, 0.0055, 21.89, 0.0058, 22.89, 0.0039, 23.88, 0.0005, 24.87, 0.0009, 25.87, 0.0003, 26.87, 0.0007, 27.78, 0.0002, 28.86, 0.0004, 29.86, 0.0004, 30.85, 0.0004, 31.86, 0.0001, 32.83, 0.0009, 33.83, 0.0003, 34.82, 0.0001, 37.81, 0.0002, 43.79, 0.0001, 48.71, 0.0001] C_c3 = [0.99, 0.0486, 1.98, 0.1268, 2.99, 0.0920, 3.98, 0.0752, 4.96, 0.1515, 5.95, 0.0086, 6.97, 0.0102, 7.95, 0.0108, 8.95, 0.0120, 9.94, 0.0034, 10.95, 0.0029, 11.94, 0.0007, 12.91, 0.0029, 13.92, 0.0077, 14.90, 0.0028, 15.89, 0.0027, 16.90, 0.0038, 17.92, 0.0034, 18.87, 0.0115, 19.89, 0.0039, 20.89, 0.0023, 21.86, 0.0023, 22.88, 0.0008, 23.88, 0.0006, 24.86, 0.0004, 26.05, 0.0002, 26.84, 0.0003, 27.84, 0.0005, 28.84, 0.0003, 29.80, 0.0004, 30.82, 0.0007, 31.58, 0.0001, 31.79, 0.0001, 32.52, 0.0001, 33.80, 0.0001, 34.80, 0.0001, 39.78, 0.0002] C_cs3 = [1.01, 0.0839, 1.99, 0.0414, 2.99, 0.1265, 4.00, 0.0196, 5.00, 0.0377, 6.00, 0.0117, 6.99, 0.0111, 8.00, 0.0151, 9.00, 0.0207, 9.98, 0.0033, 10.99, 0.0090, 11.99, 0.0039, 13.00, 0.0039, 14.01, 0.0031, 14.99, 0.0038, 16.02, 0.0023, 17.00, 0.0026, 17.98, 0.0069, 19.00, 0.0020, 20.01, 0.0017, 21.02, 0.0007, 22.02, 0.0006, 22.22, 0.0002, 22.93, 0.0001, 24.05, 0.0003, 25.04, 0.0002, 25.99, 0.0003, 27.00, 0.0003, 29.03, 0.0003] C_d3 = [1.01, 0.1033, 2.00, 0.0588, 3.00, 0.0184, 4.00, 0.0725, 5.00, 0.0720, 6.01, 0.0251, 7.01, 0.0292, 8.02, 0.0069, 9.00, 0.0094, 10.00, 0.0159, 11.02, 0.0134, 12.00, 0.0008, 13.01, 0.0053, 14.01, 0.0204, 15.01, 0.0122, 16.02, 0.0024, 17.03, 0.0044, 18.02, 0.0069, 19.03, 0.0043, 20.01, 0.0024, 21.02, 0.0020, 22.03, 0.0006, 23.03, 0.0005, 24.02, 0.0006, 25.01, 0.0011, 26.01, 0.0006, 27.03, 0.0007, 28.04, 0.0005, 29.04, 0.0003, 30.02, 0.0001, 31.03, 0.0002, 32.04, 0.0003, 36.02, 0.0002, 38.03, 0.0001, 39.06, 0.0002, 40.01, 0.0002, 42.09, 0.0001, 43.08, 0.0001, 44.05, 0.0002] C_ds3 = [1.01, 0.1622, 2.01, 0.1721, 3.02, 0.0068, 4.02, 0.0256, 5.03, 0.0568, 6.02, 0.0438, 7.03, 0.0061, 8.04, 0.0086, 9.04, 0.0050, 10.06, 0.0045, 11.07, 0.0012, 12.10, 0.0025, 13.08, 0.0028, 14.11, 0.0014, 15.07, 0.0060, 16.07, 0.0014, 17.13, 0.0026, 18.08, 0.0015, 19.13, 0.0007, 20.13, 0.0003, 21.15, 0.0003, 22.06, 0.0004, 23.10, 0.0002, 24.15, 0.0001, 25.12, 0.0001, 26.16, 0.0002, 27.20, 0.0001] C_e3 = [1.00, 0.1620, 2.01, 0.0201, 3.01, 0.0224, 4.02, 0.0903, 5.03, 0.0425, 6.01, 0.0323, 7.02, 0.0089, 8.11, 0.0023, 9.02, 0.0050, 10.03, 0.0055, 11.05, 0.0038, 12.04, 0.0099, 13.04, 0.0062, 14.03, 0.0027, 15.06, 0.0040, 16.07, 0.0035, 17.07, 0.0089, 18.06, 0.0013, 19.05, 0.0012, 20.08, 0.0004, 21.06, 0.0008, 22.09, 0.0002, 23.08, 0.0008, 24.09, 0.0005, 25.08, 0.0006, 26.65, 0.0001, 27.13, 0.0001, 29.10, 0.0002, 30.10, 0.0001, 31.10, 0.0002, 32.11, 0.0001, 35.12, 0.0003, 36.10, 0.0002, 37.15, 0.0003, 38.17, 0.0001] C_f3 = [0.99, 0.0412, 1.99, 0.0398, 2.99, 0.1009, 3.99, 0.0605, 4.97, 0.0481, 5.96, 0.0358, 6.96, 0.0065, 7.83, 0.0052, 7.97, 0.0050, 8.95, 0.0042, 9.94, 0.0038, 10.95, 0.0044, 11.94, 0.0120, 12.93, 0.0044, 13.92, 0.0074, 14.92, 0.0037, 15.92, 0.0030, 16.92, 0.0017, 17.90, 0.0021, 18.90, 0.0016, 19.89, 0.0016, 20.89, 0.0002, 22.86, 0.0013, 23.87, 0.0014, 24.87, 0.0006, 25.86, 0.0003, 26.88, 0.0001, 29.84, 0.0004, 30.83, 0.0002, 31.82, 0.0001, 32.83, 0.0001, 33.81, 0.0001, 34.81, 0.0002, 35.82, 0.0003, 37.80, 0.0002] C_fs3 = [1.00, 0.0386, 2.00, 0.0915, 3.00, 0.0406, 4.01, 0.0601, 5.00, 0.0460, 5.99, 0.0213, 7.01, 0.0148, 8.00, 0.0085, 9.00, 0.0073, 10.00, 0.0017, 11.01, 0.0191, 12.00, 0.0069, 13.00, 0.0057, 14.02, 0.0023, 15.01, 0.0059, 16.00, 0.0010, 17.02, 0.0006, 18.01, 0.0019, 19.00, 0.0012, 20.02, 0.0002, 20.99, 0.0004, 22.01, 0.0013, 23.02, 0.0007, 24.02, 0.0002, 24.94, 0.0001, 27.03, 0.0001, 28.02, 0.0002, 29.00, 0.0001, 31.01, 0.0001, 32.01, 0.0001, 33.02, 0.0003, 34.03, 0.0002] C_g3 = [1.01, 0.0124, 1.99, 0.0359, 2.98, 0.0602, 3.98, 0.0390, 4.98, 0.0496, 5.98, 0.0070, 6.98, 0.0121, 7.97, 0.0089, 8.97, 0.0044, 9.97, 0.0068, 10.97, 0.0085, 11.96, 0.0110, 12.95, 0.0034, 13.95, 0.0099, 14.95, 0.0059, 15.95, 0.0003, 16.94, 0.0014, 17.94, 0.0005, 18.94, 0.0008, 19.95, 0.0004, 20.94, 0.0007, 21.39, 0.0001, 22.95, 0.0002, 24.93, 0.0001, 25.92, 0.0002, 27.91, 0.0001, 29.91, 0.0005, 30.94, 0.0001, 31.93, 0.0002, 33.90, 0.0001] C_gs3 = [1.00, 0.0509, 1.99, 0.1477, 3.00, 0.0407, 4.00, 0.0514, 5.00, 0.0367, 6.00, 0.0032, 7.02, 0.0097, 8.00, 0.0090, 9.07, 0.0009, 10.03, 0.0069, 10.99, 0.0020, 12.03, 0.0010, 13.02, 0.0019, 14.06, 0.0010, 15.02, 0.0010, 16.03, 0.0008, 17.03, 0.0003, 18.05, 0.0002, 18.98, 0.0004, 20.09, 0.0002, 21.03, 0.0001, 28.01, 0.0001] C_a3 = [1.00, 0.0110, 2.01, 0.0315, 3.02, 0.1476, 4.03, 0.0358, 5.01, 0.0391, 6.02, 0.0638, 7.03, 0.0692, 8.02, 0.0039, 9.04, 0.0218, 10.04, 0.0342, 11.05, 0.0335, 12.04, 0.0187, 13.05, 0.0167, 14.06, 0.0168, 15.06, 0.0035, 16.07, 0.0019, 17.07, 0.0014, 18.08, 0.0040, 19.07, 0.0070, 20.08, 0.0014, 21.09, 0.0015, 22.08, 0.0003, 23.10, 0.0003, 24.08, 0.0011, 25.10, 0.0003, 26.12, 0.0013, 27.13, 0.0009, 28.13, 0.0006, 29.12, 0.0003, 30.11, 0.0002, 31.13, 0.0002, 33.15, 0.0002, 34.13, 0.0001, 36.15, 0.0001, 41.16, 0.0002, 44.18, 0.0001, 47.17, 0.0001] C_as3 = [1.00, 0.0140, 2.00, 0.0411, 3.00, 0.0723, 4.00, 0.1057, 5.00, 0.0044, 6.00, 0.0248, 6.98, 0.0048, 8.00, 0.0014, 9.00, 0.0304, 9.99, 0.0184, 10.99, 0.0130, 12.00, 0.0159, 13.00, 0.0107, 13.99, 0.0021, 15.00, 0.0015, 15.99, 0.0020, 17.00, 0.0028, 18.00, 0.0067, 19.00, 0.0005, 20.04, 0.0003, 21.00, 0.0003, 22.02, 0.0001, 23.98, 0.0003, 25.01, 0.0007, 26.01, 0.0009, 27.00, 0.0003, 28.02, 0.0002, 28.98, 0.0002, 30.00, 0.0002, 31.01, 0.0002, 32.01, 0.0002, 32.99, 0.0003, 33.99, 0.0001, 35.02, 0.0002, 37.00, 0.0002, 38.98, 0.0003, 43.98, 0.0001, 44.99, 0.0001] C_b3 = [1.00, 0.0648, 2.00, 0.0397, 3.00, 0.0872, 4.01, 0.0429, 5.00, 0.0213, 6.01, 0.0524, 7.00, 0.0064, 8.03, 0.0162, 9.02, 0.0212, 10.01, 0.0175, 11.02, 0.0256, 12.03, 0.0038, 13.03, 0.0039, 14.04, 0.0056, 15.03, 0.0008, 16.08, 0.0005, 17.03, 0.0032, 18.04, 0.0010, 19.04, 0.0011, 20.04, 0.0002, 21.06, 0.0010, 22.05, 0.0002, 23.08, 0.0011, 24.09, 0.0005, 25.12, 0.0003, 26.07, 0.0002, 27.03, 0.0001, 39.10, 0.0002] C_c4 = [1.00, 0.0472, 2.00, 0.1961, 3.00, 0.1030, 4.00, 0.0974, 5.00, 0.0183, 6.00, 0.0397, 7.00, 0.0158, 8.00, 0.0170, 8.99, 0.0253, 10.00, 0.0129, 10.99, 0.0121, 11.99, 0.0103, 12.98, 0.0055, 14.03, 0.0004, 14.99, 0.0012, 15.99, 0.0051, 16.99, 0.0009, 17.99, 0.0012, 19.00, 0.0004, 19.98, 0.0015, 21.02, 0.0002, 22.00, 0.0009, 22.99, 0.0007, 24.01, 0.0004, 25.00, 0.0002, 26.00, 0.0003, 28.00, 0.0002, 28.97, 0.0002, 31.00, 0.0002, 32.98, 0.0003, 33.98, 0.0001, 34.97, 0.0001, 35.98, 0.0002, 37.97, 0.0002, 38.97, 0.0001] C_cs4 = [1.00, 0.1199, 2.00, 0.0345, 3.01, 0.0978, 4.00, 0.0466, 5.02, 0.0070, 6.01, 0.0258, 7.02, 0.0241, 8.01, 0.0070, 9.02, 0.0161, 10.02, 0.0124, 11.02, 0.0145, 12.02, 0.0101, 13.02, 0.0026, 14.03, 0.0011, 15.02, 0.0028, 16.03, 0.0011, 17.04, 0.0005, 18.02, 0.0003, 19.05, 0.0012, 20.07, 0.0004, 21.06, 0.0011, 22.06, 0.0007, 23.04, 0.0007, 24.05, 0.0005, 26.07, 0.0003, 27.04, 0.0002, 28.05, 0.0002, 29.06, 0.0001, 32.05, 0.0001, 33.06, 0.0002, 35.07, 0.0002, 36.07, 0.0001, 37.07, 0.0002] C_d4 = [1.00, 0.0657, 2.00, 0.0681, 3.00, 0.1031, 3.99, 0.0157, 4.99, 0.0570, 5.98, 0.0160, 6.99, 0.0236, 7.98, 0.0259, 8.99, 0.0144, 9.98, 0.0154, 10.98, 0.0046, 11.97, 0.0104, 12.98, 0.0024, 13.97, 0.0020, 14.97, 0.0012, 15.97, 0.0010, 16.97, 0.0004, 17.95, 0.0008, 18.97, 0.0005, 19.98, 0.0007, 20.98, 0.0009, 21.93, 0.0004, 22.00, 0.0003, 22.94, 0.0002, 23.95, 0.0002, 24.98, 0.0001, 25.97, 0.0002, 26.96, 0.0001, 28.94, 0.0002, 29.94, 0.0002, 30.94, 0.0002, 32.97, 0.0001, 33.97, 0.0001, 34.95, 0.0001, 36.93, 0.0001] C_ds4 = [1.00, 0.3562, 1.99, 0.0664, 2.99, 0.1446, 3.98, 0.0393, 4.97, 0.0363, 5.97, 0.0237, 6.96, 0.0366, 7.95, 0.0079, 8.96, 0.0127, 9.95, 0.0148, 10.95, 0.0143, 11.94, 0.0031, 12.96, 0.0022, 13.94, 0.0032, 14.92, 0.0004, 15.92, 0.0007, 16.90, 0.0007, 17.92, 0.0007, 18.92, 0.0012, 19.94, 0.0005, 20.89, 0.0003, 21.88, 0.0001, 22.89, 0.0005, 23.87, 0.0004, 24.87, 0.0001, 25.89, 0.0007, 26.87, 0.0001, 29.85, 0.0001, 30.83, 0.0001, 31.82, 0.0001, 32.82, 0.0002, 33.82, 0.0001] C_e4 = [1.00, 0.0390, 2.01, 0.1863, 3.02, 0.0265, 4.02, 0.0184, 5.02, 0.0319, 6.03, 0.0456, 7.04, 0.0122, 8.04, 0.0149, 9.05, 0.0159, 10.05, 0.0067, 11.06, 0.0044, 12.06, 0.0053, 13.08, 0.0012, 14.08, 0.0008, 15.08, 0.0007, 16.09, 0.0021, 17.09, 0.0005, 18.09, 0.0021, 19.13, 0.0016, 20.12, 0.0004, 21.12, 0.0003, 22.14, 0.0003, 23.12, 0.0003, 24.13, 0.0003, 25.14, 0.0005, 26.14, 0.0002, 27.15, 0.0002, 28.16, 0.0002, 29.18, 0.0002, 30.17, 0.0002, 31.16, 0.0002, 36.21, 0.0001] C_f4 = [1.00, 0.1183, 1.99, 0.1142, 2.99, 0.1085, 3.98, 0.0306, 4.99, 0.0252, 5.97, 0.0272, 6.97, 0.0290, 7.97, 0.0142, 8.97, 0.0112, 9.96, 0.0079, 10.96, 0.0038, 11.97, 0.0026, 12.96, 0.0014, 13.95, 0.0007, 14.94, 0.0011, 15.95, 0.0008, 16.94, 0.0011, 17.03, 0.0001, 17.94, 0.0001, 18.95, 0.0004, 19.94, 0.0003, 20.94, 0.0007, 21.92, 0.0002, 23.92, 0.0002, 24.92, 0.0002, 25.90, 0.0002, 26.90, 0.0002, 27.89, 0.0001, 28.89, 0.0002, 30.89, 0.0001] C_fs4 = [1.00, 0.1140, 2.00, 0.0935, 3.00, 0.0504, 3.99, 0.0715, 4.99, 0.0063, 6.00, 0.0808, 6.99, 0.0099, 8.00, 0.0093, 9.00, 0.0093, 9.99, 0.0019, 10.99, 0.0050, 11.99, 0.0017, 12.99, 0.0021, 14.00, 0.0003, 14.99, 0.0010, 16.00, 0.0015, 17.00, 0.0019, 17.95, 0.0002, 18.00, 0.0002, 18.99, 0.0002, 19.99, 0.0003, 21.00, 0.0002, 21.99, 0.0003, 23.99, 0.0001, 24.98, 0.0001, 26.02, 0.0001, 27.01, 0.0001, 28.00, 0.0002] C_g4 = [1.00, 0.0809, 1.99, 0.1377, 2.99, 0.0348, 3.99, 0.0337, 4.98, 0.0177, 5.98, 0.0295, 6.98, 0.0266, 7.98, 0.0063, 8.98, 0.0105, 9.97, 0.0016, 10.97, 0.0022, 11.98, 0.0029, 12.97, 0.0018, 13.96, 0.0008, 14.99, 0.0023, 15.97, 0.0012, 16.96, 0.0009, 17.97, 0.0002, 18.95, 0.0006, 20.94, 0.0002, 20.99, 0.0002, 22.95, 0.0002, 23.94, 0.0002, 24.94, 0.0003, 25.97, 0.0003, 26.95, 0.0002] C_gs4 = [1.00, 0.2601, 1.99, 0.1726, 2.99, 0.0722, 3.99, 0.0276, 4.99, 0.0535, 5.99, 0.0103, 6.99, 0.0244, 7.99, 0.0046, 8.98, 0.0035, 9.99, 0.0088, 10.98, 0.0038, 11.98, 0.0008, 12.96, 0.0006, 13.98, 0.0020, 14.98, 0.0016, 15.98, 0.0008, 16.97, 0.0003, 17.97, 0.0005, 18.98, 0.0006, 19.96, 0.0005, 20.96, 0.0001, 21.96, 0.0003, 23.96, 0.0002, 24.96, 0.0003, 25.96, 0.0002] C_a4 = [0.99, 0.0363, 1.98, 0.2481, 2.98, 0.0514, 3.97, 0.0365, 4.97, 0.0468, 5.95, 0.0182, 6.95, 0.0333, 7.94, 0.0106, 8.93, 0.0048, 9.92, 0.0048, 10.92, 0.0016, 11.90, 0.0010, 12.89, 0.0011, 13.92, 0.0023, 14.90, 0.0014, 15.88, 0.0007, 16.87, 0.0002, 17.89, 0.0001, 18.85, 0.0004, 19.84, 0.0002, 20.84, 0.0003, 21.84, 0.0004, 22.83, 0.0003, 23.86, 0.0002, 24.84, 0.0002, 26.82, 0.0001] C_as4 = [0.99, 0.0564, 1.99, 0.1983, 2.98, 0.0520, 3.97, 0.0442, 4.97, 0.0260, 5.96, 0.0139, 6.96, 0.0099, 7.94, 0.0046, 8.94, 0.0178, 9.94, 0.0032, 10.93, 0.0021, 11.00, 0.0002, 11.93, 0.0001, 12.92, 0.0038, 13.91, 0.0011, 14.90, 0.0006, 15.92, 0.0004, 16.89, 0.0004, 17.89, 0.0002, 18.87, 0.0005, 19.87, 0.0003, 20.86, 0.0003, 21.85, 0.0003, 22.85, 0.0001, 23.85, 0.0001, 24.85, 0.0001, 25.85, 0.0002, 26.84, 0.0002] C_b4 = [0.99, 0.0774, 1.98, 0.1289, 2.96, 0.1071, 3.95, 0.0216, 4.94, 0.0346, 5.93, 0.0108, 6.91, 0.0239, 7.90, 0.0056, 8.88, 0.0045, 9.88, 0.0014, 10.87, 0.0057, 11.85, 0.0018, 12.85, 0.0035, 13.83, 0.0007, 14.84, 0.0003, 15.80, 0.0003, 16.79, 0.0008, 17.78, 0.0003, 18.78, 0.0002, 19.76, 0.0004, 20.75, 0.0005, 21.73, 0.0002, 23.71, 0.0001, 24.68, 0.0001] C_c5 = [0.99, 0.4933, 1.97, 0.1293, 2.95, 0.0971, 4.92, 0.0189, 5.91, 0.0031, 6.88, 0.0093, 7.87, 0.0143, 8.85, 0.0063, 9.84, 0.0010, 10.82, 0.0023, 11.81, 0.0015, 12.79, 0.0006, 13.78, 0.0009, 14.76, 0.0007, 15.75, 0.0004, 16.72, 0.0007, 17.71, 0.0002, 18.68, 0.0008, 19.67, 0.0004, 20.66, 0.0003] C_cs5 = [0.99, 0.1576, 1.99, 0.0760, 2.98, 0.0560, 3.97, 0.1172, 4.96, 0.0433, 5.96, 0.0029, 6.95, 0.0079, 7.95, 0.0058, 8.93, 0.0025, 9.93, 0.0014, 10.93, 0.0054, 11.92, 0.0005, 12.92, 0.0004, 13.90, 0.0009, 14.90, 0.0015, 15.89, 0.0003, 16.87, 0.0002, 17.87, 0.0004, 18.87, 0.0002, 19.86, 0.0002, 20.86, 0.0002, 21.86, 0.0003, 22.85, 0.0002] C_d5 = [1.01, 0.1243, 2.02, 0.0648, 3.03, 0.0586, 4.04, 0.0543, 5.05, 0.0183, 6.07, 0.0046, 7.08, 0.0080, 8.09, 0.0027, 9.10, 0.0053, 10.12, 0.0036, 11.14, 0.0014, 12.14, 0.0004, 13.16, 0.0004, 14.15, 0.0007, 15.17, 0.0005, 17.20, 0.0006, 18.22, 0.0002, 19.22, 0.0002, 21.24, 0.0001] C_ds5 = [1.01, 0.1367, 2.02, 0.0170, 3.02, 0.0192, 4.03, 0.0425, 5.04, 0.0143, 6.05, 0.0064, 7.06, 0.0057, 8.06, 0.0028, 9.08, 0.0027, 10.09, 0.0051, 11.09, 0.0009, 12.09, 0.0001, 13.10, 0.0014, 14.11, 0.0005, 15.13, 0.0003, 16.13, 0.0003, 17.14, 0.0002, 19.15, 0.0003, 20.17, 0.0004, 21.17, 0.0001] C_e5 = [1.02, 0.2402, 2.03, 0.0419, 3.05, 0.1068, 5.08, 0.0164, 6.10, 0.0019, 7.11, 0.0044, 8.13, 0.0018, 9.15, 0.0044, 10.17, 0.0021, 11.18, 0.0003, 12.20, 0.0007, 13.21, 0.0011, 14.24, 0.0003, 15.24, 0.0008, 16.27, 0.0001, 17.28, 0.0001, 18.31, 0.0001] C_f5 = [1.01, 0.1166, 2.03, 0.0750, 3.04, 0.0532, 4.05, 0.0620, 5.06, 0.0054, 6.07, 0.0141, 7.08, 0.0027, 8.10, 0.0015, 9.09, 0.0021, 10.13, 0.0006, 11.13, 0.0009, 12.14, 0.0004, 13.15, 0.0008, 14.17, 0.0003, 15.18, 0.0002, 17.19, 0.0003, 18.20, 0.0002] C_fs5 = [1.00, 0.1595, 2.00, 0.0985, 3.01, 0.1045, 4.01, 0.0147, 5.01, 0.0078, 6.01, 0.0016, 7.01, 0.0020, 8.02, 0.0007, 9.02, 0.0015, 10.03, 0.0008, 11.03, 0.0006, 12.02, 0.0004, 13.02, 0.0009, 14.03, 0.0006, 15.02, 0.0005, 16.03, 0.0002, 17.04, 0.0001] C_g5 = [1.00, 0.1740, 1.99, 0.0431, 2.99, 0.1899, 3.99, 0.0201, 4.98, 0.0009, 5.98, 0.0031, 6.98, 0.0055, 7.97, 0.0051, 8.97, 0.0007, 9.96, 0.0007, 10.95, 0.0006, 11.95, 0.0009, 12.95, 0.0008, 13.96, 0.0002, 14.94, 0.0001, 15.95, 0.0002] C_gs5 = [1.00, 0.1902, 1.99, 0.0327, 2.98, 0.0551, 3.98, 0.0157, 4.97, 0.0078, 5.97, 0.0030, 6.96, 0.0035, 7.96, 0.0020, 8.95, 0.0017, 9.94, 0.0011, 10.94, 0.0005, 11.93, 0.0007, 12.93, 0.0004, 13.92, 0.0002, 14.93, 0.0003] C_a5 = [0.99, 0.4175, 1.99, 0.0209, 2.98, 0.0274, 3.97, 0.0220, 4.96, 0.0061, 5.96, 0.0020, 6.96, 0.0038, 7.95, 0.0009, 8.95, 0.0014, 9.93, 0.0005, 10.93, 0.0005, 11.91, 0.0007, 12.91, 0.0002, 13.91, 0.0001, 14.91, 0.0001] C_as5 = [1.00, 0.4648, 2.00, 0.0475, 3.01, 0.1268, 4.01, 0.0164, 5.02, 0.0035, 6.02, 0.0018, 7.02, 0.0033, 8.03, 0.0028, 9.03, 0.0008, 10.03, 0.0006, 11.03, 0.0005, 12.04, 0.0006, 13.05, 0.0003, 14.04, 0.0001] C_b5 = [1.01, 0.2812, 2.02, 0.1380, 3.02, 0.0722, 4.03, 0.0215, 5.04, 0.0036, 6.06, 0.0018, 7.05, 0.0005, 8.07, 0.0015, 9.08, 0.0013, 10.08, 0.0003, 11.10, 0.0002, 12.11, 0.0003, 13.11, 0.0002] C_c6 = [1.01, 0.2553, 2.01, 0.1160, 3.02, 0.0171, 4.02, 0.0272, 5.02, 0.0020, 6.03, 0.0062, 7.03, 0.0012, 8.04, 0.0011, 9.05, 0.0007, 10.05, 0.0007, 11.06, 0.0002, 12.06, 0.0001, 12.08, 0.0001] C_cs6 = [1.01, 0.1045, 2.02, 0.1220, 3.04, 0.0220, 4.05, 0.0094, 5.06, 0.0021, 6.07, 0.0031, 7.09, 0.0018, 8.10, 0.0020, 9.11, 0.0014, 10.12, 0.0003, 11.13, 0.0006] C_d6 = [1.00, 0.0653, 1.99, 0.2499, 2.99, 0.0334, 3.98, 0.0098, 4.98, 0.0091, 5.98, 0.0007, 6.97, 0.0011, 7.97, 0.0008, 8.96, 0.0042, 9.96, 0.0003, 10.95, 0.0004] C_ds6 = [0.99, 0.0485, 1.99, 0.1325, 2.98, 0.0152, 3.98, 0.0064, 4.97, 0.0043, 5.97, 0.0007, 6.96, 0.0007, 7.97, 0.0006, 8.96, 0.0003, 9.95, 0.0004] C_e6 = [1.01, 0.1797, 2.01, 0.0750, 4.03, 0.0065, 5.04, 0.0018, 6.04, 0.0012, 7.04, 0.0004, 8.06, 0.0003, 9.06, 0.0003] # # # # # clarinet? Cl_d3 = [1.01, 0.1722, 2.00, 0.0056, 2.99, 0.1609, 3.99, 0.0333, 5.00, 0.1157, 5.99, 0.1149, 6.98, 0.0079, 7.98, 0.0620, 8.99, 0.0601, 9.99, 0.0104, 10.98, 0.0134, 11.97, 0.0122, 12.99, 0.0058, 13.98, 0.0110, 14.98, 0.0029, 15.97, 0.0045, 16.98, 0.0023, 17.98, 0.0010, 18.97, 0.0016, 19.96, 0.0021, 20.96, 0.0008, 21.97, 0.0021, 22.96, 0.0001, 23.96, 0.0012, 24.95, 0.0003, 25.97, 0.0002, 26.96, 0.0003, 27.95, 0.0002, 30.96, 0.0002, 32.94, 0.0002, 34.96, 0.0001, 35.95, 0.0002, 37.93, 0.0001] Cl_ds3 = [0.99, 0.1038, 1.98, 0.0043, 2.96, 0.0953, 3.97, 0.0013, 4.94, 0.1057, 5.93, 0.0145, 6.93, 0.0787, 7.91, 0.0328, 8.89, 0.0086, 9.90, 0.0088, 10.88, 0.0128, 11.86, 0.0005, 12.86, 0.0085, 13.84, 0.0026, 14.83, 0.0051, 15.81, 0.0030, 16.82, 0.0008, 17.79, 0.0026, 18.78, 0.0013, 19.78, 0.0015, 20.76, 0.0011, 22.74, 0.0012, 23.72, 0.0002, 24.71, 0.0006, 25.70, 0.0003, 26.70, 0.0002, 28.67, 0.0002, 30.64, 0.0002, 31.64, 0.0001, 32.63, 0.0001, 33.61, 0.0003, 35.59, 0.0002] Cl_e3 = [1.00, 0.0825, 1.99, 0.0024, 2.97, 0.0406, 3.96, 0.0042, 4.94, 0.0683, 6.40, 0.0010, 6.92, 0.0709, 7.92, 0.0099, 8.91, 0.0059, 9.89, 0.0055, 10.88, 0.0111, 11.90, 0.0009, 12.86, 0.0126, 13.87, 0.0021, 14.84, 0.0110, 15.83, 0.0010, 16.83, 0.0057, 17.81, 0.0007, 18.80, 0.0037, 19.78, 0.0008, 20.78, 0.0016, 21.75, 0.0006, 22.75, 0.0008, 23.73, 0.0005, 24.74, 0.0007, 26.72, 0.0004, 27.68, 0.0002, 29.67, 0.0003, 31.66, 0.0003, 33.64, 0.0002] Cl_f3 = [0.99, 0.0685, 1.98, 0.0012, 2.98, 0.0854, 3.98, 0.0029, 4.96, 0.0507, 5.97, 0.0017, 6.96, 0.0507, 7.94, 0.0027, 8.94, 0.0092, 9.94, 0.0084, 10.92, 0.0116, 11.91, 0.0018, 12.92, 0.0039, 13.92, 0.0003, 14.89, 0.0013, 15.88, 0.0019, 16.87, 0.0012, 17.86, 0.0010, 18.87, 0.0011, 19.86, 0.0008, 20.85, 0.0008, 21.83, 0.0002, 23.81, 0.0004, 24.83, 0.0002, 25.80, 0.0003, 27.78, 0.0002, 29.78, 0.0001] Cl_fs3 = [1.00, 0.1546, 1.99, 0.0015, 2.99, 0.0594, 4.00, 0.0014, 5.00, 0.0268, 6.00, 0.0019, 7.00, 0.0170, 7.97, 0.0005, 9.00, 0.0110, 9.99, 0.0006, 10.99, 0.0077, 11.99, 0.0013, 12.99, 0.0025, 14.01, 0.0004, 14.99, 0.0018, 15.98, 0.0001, 16.98, 0.0013, 17.97, 0.0003, 18.98, 0.0013, 20.97, 0.0001, 21.97, 0.0004, 22.96, 0.0002, 23.98, 0.0002, 25.99, 0.0001] Cl_g3 = [0.99, 0.1660, 2.00, 0.0016, 2.99, 0.0889, 3.99, 0.0017, 4.99, 0.0430, 6.00, 0.0009, 6.98, 0.0128, 8.00, 0.0040, 8.98, 0.0077, 9.99, 0.0017, 10.98, 0.0052, 11.98, 0.0011, 12.98, 0.0012, 13.97, 0.0008, 14.98, 0.0010, 15.97, 0.0005, 16.98, 0.0005, 17.96, 0.0007, 18.97, 0.0002, 19.96, 0.0004, 20.96, 0.0003, 22.94, 0.0003, 23.95, 0.0002, 24.96, 0.0002, 25.93, 0.0001, 26.94, 0.0002, 27.95, 0.0001] Cl_gs3 = [1.00, 0.1107, 2.00, 0.0016, 2.99, 0.0872, 3.99, 0.0028, 4.98, 0.0293, 5.97, 0.0020, 6.96, 0.0202, 7.99, 0.0019, 8.95, 0.0118, 9.94, 0.0028, 10.95, 0.0040, 11.92, 0.0006, 12.95, 0.0030, 13.92, 0.0002, 14.92, 0.0010, 15.91, 0.0005, 16.91, 0.0015, 18.90, 0.0004, 19.89, 0.0004, 20.89, 0.0002, 21.88, 0.0004, 22.87, 0.0002, 23.88, 0.0001, 24.87, 0.0001] Cl_a3 = [1.00, 0.0842, 2.01, 0.0017, 3.00, 0.0420, 4.01, 0.0029, 5.00, 0.0251, 6.02, 0.0041, 6.99, 0.0115, 7.96, 0.0006, 8.99, 0.0032, 9.98, 0.0003, 11.00, 0.0018, 11.96, 0.0003, 12.96, 0.0006, 14.00, 0.0001, 14.97, 0.0001, 15.97, 0.0005, 17.95, 0.0002, 18.96, 0.0001, 19.07, 0.0001, 22.06, 0.0001] Cl_as3 = [1.00, 0.1118, 1.99, 0.0006, 2.98, 0.0383, 3.98, 0.0019, 4.98, 0.0335, 5.98, 0.0034, 6.97, 0.0131, 7.94, 0.0005, 8.95, 0.0024, 9.96, 0.0028, 10.96, 0.0019, 11.94, 0.0012, 12.94, 0.0012, 13.93, 0.0003, 14.94, 0.0007, 16.92, 0.0004, 17.90, 0.0003, 18.93, 0.0002, 20.89, 0.0002, 21.90, 0.0001] Cl_b3 = [1.00, 0.1324, 1.99, 0.0011, 3.00, 0.0693, 4.01, 0.0012, 4.99, 0.0279, 5.98, 0.0044, 6.98, 0.0149, 7.97, 0.0009, 8.97, 0.0028, 9.97, 0.0009, 10.98, 0.0026, 11.96, 0.0003, 12.96, 0.0006, 13.95, 0.0003, 15.95, 0.0001, 16.94, 0.0001] Cl_c4 = [1.00, 0.2335, 1.99, 0.0017, 2.99, 0.1253, 4.01, 0.0023, 4.99, 0.0343, 6.01, 0.0028, 6.98, 0.0023, 7.98, 0.0014, 8.98, 0.0041, 10.01, 0.0003, 10.96, 0.0004, 11.94, 0.0008, 12.94, 0.0002, 14.94, 0.0003, 15.94, 0.0004, 16.93, 0.0002, 17.91, 0.0002, 18.91, 0.0002, 19.91, 0.0001, 20.90, 0.0001] Cl_cs4 = [0.99, 0.2609, 2.00, 0.0016, 2.99, 0.1469, 3.99, 0.0040, 4.99, 0.0143, 5.97, 0.0091, 6.97, 0.0055, 7.97, 0.0024, 8.96, 0.0041, 9.96, 0.0015, 10.96, 0.0021, 11.95, 0.0005, 12.94, 0.0011, 13.93, 0.0004, 14.94, 0.0006, 15.94, 0.0004, 16.92, 0.0004, 17.93, 0.0002, 18.93, 0.0001, 19.91, 0.0001, 20.91, 0.0001, 21.90, 0.0002, 22.91, 0.0001] Cl_d4 = [1.00, 0.2056, 1.99, 0.0006, 2.99, 0.1715, 3.99, 0.0010, 4.98, 0.0194, 5.99, 0.0028, 6.98, 0.0106, 7.98, 0.0007, 8.97, 0.0022, 9.97, 0.0005, 10.96, 0.0011, 11.97, 0.0006, 12.96, 0.0006, 13.96, 0.0003, 14.95, 0.0005, 15.95, 0.0003, 17.95, 0.0002, 18.94, 0.0002, 20.94, 0.0001] Cl_ds4 = [1.00, 0.2590, 1.98, 0.0019, 2.99, 0.1336, 3.97, 0.0034, 4.97, 0.0442, 5.97, 0.0017, 6.96, 0.0108, 7.96, 0.0006, 8.95, 0.0031, 9.94, 0.0003, 11.93, 0.0003, 12.93, 0.0004, 13.93, 0.0005, 14.92, 0.0001, 15.91, 0.0003, 16.90, 0.0004, 17.90, 0.0002, 18.89, 0.0001] Cl_e4 = [1.00, 0.2560, 2.00, 0.0013, 3.00, 0.0878, 4.00, 0.0053, 5.00, 0.0304, 6.00, 0.0009, 7.00, 0.0060, 7.99, 0.0007, 9.00, 0.0011, 9.99, 0.0006, 10.99, 0.0006, 11.98, 0.0001, 13.99, 0.0001] Cl_f4 = [0.99, 0.1966, 1.99, 0.0021, 2.98, 0.0812, 3.96, 0.0018, 4.97, 0.0248, 5.96, 0.0032, 6.96, 0.0060, 7.95, 0.0024, 8.95, 0.0019, 9.94, 0.0008, 10.94, 0.0007, 11.92, 0.0005, 12.91, 0.0002, 13.94, 0.0001, 14.90, 0.0002, 15.91, 0.0002] Cl_fs4 = [1.00, 0.1555, 2.01, 0.0022, 3.01, 0.1755, 4.01, 0.0005, 5.01, 0.0127, 6.02, 0.0004, 7.02, 0.0031, 8.02, 0.0007, 9.02, 0.0005, 10.02, 0.0002, 11.03, 0.0003, 12.02, 0.0002, 14.02, 0.0001, 15.03, 0.0001, 16.04, 0.0001] Cl_g4 = [1.00, 0.0470, 2.00, 0.0016, 3.00, 0.0787, 4.00, 0.0041, 5.00, 0.0046, 6.00, 0.0010, 7.00, 0.0036, 8.00, 0.0011, 9.00, 0.0012, 10.00, 0.0002, 11.00, 0.0003, 13.00, 0.0001] Cl_gs4 = [1.00, 0.1205, 1.99, 0.0014, 2.99, 0.0145, 3.99, 0.0015, 4.99, 0.0030, 5.99, 0.0005, 6.98, 0.0006, 9.00, 0.0001, 9.98, 0.0001] Cl_a4 = [1.00, 0.2677, 2.00, 0.0592, 3.01, 0.0961, 4.01, 0.0083, 5.02, 0.0075, 6.02, 0.0027, 7.03, 0.0048, 8.03, 0.0031, 9.02, 0.0007, 10.03, 0.0003, 11.03, 0.0001] Cl_as4 = [1.00, 0.1363, 2.01, 0.0056, 3.00, 0.0168, 4.01, 0.0026, 5.01, 0.0112, 6.00, 0.0011, 7.01, 0.0011, 8.01, 0.0003, 10.00, 0.0002, 12.02, 0.0001] Cl_b4 = [1.01, 0.0312, 2.01, 0.0042, 3.02, 0.0061, 4.02, 0.0127, 5.03, 0.0090, 6.04, 0.0002, 7.04, 0.0021, 8.05, 0.0008, 11.06, 0.0001] Cl_c5 = [1.00, 0.2597, 2.00, 0.0052, 3.00, 0.0337, 4.00, 0.0012, 5.00, 0.0025, 6.00, 0.0014, 7.00, 0.0007, 7.99, 0.0004, 8.99, 0.0003, 10.00, 0.0004] Cl_cs5 = [1.00, 0.1894, 2.00, 0.0060, 3.00, 0.0250, 4.01, 0.0022, 5.01, 0.0048, 6.00, 0.0004, 8.01, 0.0001, 10.01, 0.0001] Cl_d5 = [1.00, 0.1727, 2.01, 0.0013, 3.00, 0.0066, 4.01, 0.0011, 5.00, 0.0013, 5.99, 0.0008, 8.02, 0.0001] Cl_ds5 = [1.00, 0.3538, 2.00, 0.0053, 3.01, 0.0757, 4.01, 0.0009, 5.01, 0.0045, 6.02, 0.0008, 7.02, 0.0011, 8.01, 0.0003, 9.02, 0.0005, 10.01, 0.0002, 11.02, 0.0001, 12.02, 0.0002] Cl_e5 = [1.00, 0.1647, 2.00, 0.0048, 3.00, 0.0524, 3.99, 0.0055, 4.99, 0.0030, 5.98, 0.0011, 6.99, 0.0004, 7.99, 0.0003] Cl_f5 = [0.99, 0.1880, 1.99, 0.0126, 2.99, 0.0222, 3.98, 0.0070, 4.98, 0.0135, 5.97, 0.0020, 6.97, 0.0012, 7.96, 0.0001, 8.96, 0.0007, 9.95, 0.0003] Cl_fs5 = [1.00, 0.3103, 2.00, 0.0104, 3.00, 0.0335, 4.00, 0.0078, 5.00, 0.0026, 6.01, 0.0005, 7.01, 0.0006, 8.00, 0.0003] Cl_g5 = [1.01, 0.4163, 2.01, 0.0446, 3.02, 0.0290, 4.03, 0.0031, 5.02, 0.0004, 6.03, 0.0002, 7.05, 0.0001, 8.05, 0.0001] Cl_gs5 = [1.01, 0.2150, 2.00, 0.0334, 3.00, 0.0012, 4.02, 0.0003, 5.02, 0.0002] Cl_a5 = [1.01, 0.5463, 2.01, 0.0429, 3.02, 0.0317, 4.02, 0.0159, 5.03, 0.0012, 6.04, 0.0005, 7.04, 0.0005, 8.05, 0.0002] Cl_as5 = [1.00, 0.3802, 2.00, 0.0397, 3.01, 0.0186, 4.01, 0.0102, 5.01, 0.0020, 6.01, 0.0001, 7.01, 0.0002, 8.02, 0.0003, 9.02, 0.0002, 10.02, 0.0001, 11.02, 0.0001, 12.02, 0.0002] Cl_b5 = [1.00, 0.0896, 2.00, 0.0851, 3.00, 0.0081, 4.00, 0.0024, 5.00, 0.0010, 6.00, 0.0001, 7.00, 0.0002] Cl_c6 = [1.00, 0.1740, 2.00, 0.0081, 3.01, 0.0111, 4.01, 0.0087, 5.01, 0.0005, 6.01, 0.0007, 7.01, 0.0001, 9.01, 0.0002, 10.02, 0.0002] Cl_cs6 = [1.00, 0.1295, 1.99, 0.0270, 2.99, 0.0012, 3.99, 0.0004] Cl_d6 = [1.00, 0.1700, 2.01, 0.0603, 3.01, 0.0169, 4.01, 0.0031, 5.01, 0.0007, 6.01, 0.0002] Cl_ds6 = [1.01, 0.2624, 2.02, 0.0042, 3.03, 0.0049, 4.03, 0.0015, 5.04, 0.0001] Cl_e6 = [1.02, 0.0632, 2.03, 0.0115, 3.04, 0.0011, 4.06, 0.0006] Cl_f6 = [1.02, 0.0748, 2.03, 0.0535, 3.05, 0.0044, 4.07, 0.0009, 5.08, 0.0001, 7.12, 0.0001, 8.13, 0.0001] Cl_fs6 = [1.02, 0.0305, 2.03, 0.0175, 3.04, 0.0005, 4.05, 0.0002] Cl_g6 = [1.03, 0.0026, 2.04, 0.0008] Cl_gs6 = [1.03, 0.0015, 2.00, 0.0002] Cl_a6 = [1.03, 0.0043, 2.05, 0.0010] Cl_as6 = [1.05, 0.0008, 2.00, 0.0001] # # # # # french horn? Fh_as1 = [1.01, 0.0041, 2.00, 0.0015, 3.01, 0.0121, 4.02, 0.0111, 5.02, 0.0343, 6.03, 0.0165, 7.04, 0.0066, 8.03, 0.0064, 9.05, 0.0049, 10.06, 0.0012, 11.05, 0.0093, 12.07, 0.0029, 13.07, 0.0042, 14.08, 0.0040, 15.08, 0.0019, 16.09, 0.0013, 17.10, 0.0009, 18.04, 0.0002, 19.03, 0.0002, 20.12, 0.0003, 21.13, 0.0003, 22.13, 0.0002, 23.13, 0.0002] Fh_b1 = [1.01, 0.0035, 2.03, 0.0064, 3.04, 0.0087, 4.08, 0.0087, 5.12, 0.0049, 6.08, 0.0189, 7.10, 0.0304, 8.12, 0.0205, 9.16, 0.0026, 10.18, 0.0039, 11.20, 0.0006, 12.11, 0.0029, 13.15, 0.0037, 14.24, 0.0014, 15.26, 0.0010, 16.29, 0.0005, 17.19, 0.0003, 18.21, 0.0007, 19.23, 0.0005, 20.25, 0.0004, 21.33, 0.0003, 22.36, 0.0001, 23.32, 0.0002, 24.33, 0.0002, 25.33, 0.0001, 26.39, 0.0002, 27.42, 0.0002] Fh_c2 = [1.02, 0.0034, 2.02, 0.0059, 3.01, 0.0083, 4.02, 0.0274, 5.03, 0.0206, 6.03, 0.0155, 7.04, 0.0131, 8.03, 0.0073, 9.05, 0.0014, 10.03, 0.0064, 11.05, 0.0055, 12.06, 0.0109, 13.08, 0.0037, 14.10, 0.0012, 15.10, 0.0010, 16.01, 0.0004, 17.05, 0.0009, 18.06, 0.0008, 19.06, 0.0006, 20.09, 0.0004, 21.11, 0.0002, 22.14, 0.0002, 23.09, 0.0002, 24.08, 0.0001, 25.08, 0.0002, 26.07, 0.0002, 27.12, 0.0002, 28.16, 0.0001, 32.11, 0.0001] Fh_cs2 = [1.01, 0.0038, 1.99, 0.0124, 2.98, 0.0065, 4.00, 0.0260, 5.00, 0.0138, 5.99, 0.0093, 6.97, 0.0077, 7.95, 0.0055, 8.97, 0.0061, 9.97, 0.0016, 10.95, 0.0034, 11.96, 0.0036, 12.14, 0.0010, 12.94, 0.0009, 13.97, 0.0008, 14.86, 0.0004, 15.89, 0.0006, 16.91, 0.0007, 17.93, 0.0004, 18.94, 0.0002, 19.95, 0.0001, 20.77, 0.0001, 21.78, 0.0002, 22.86, 0.0001, 23.89, 0.0002] Fh_d2 = [1.01, 0.0153, 2.01, 0.0192, 3.01, 0.0216, 4.01, 0.0371, 5.01, 0.0259, 6.02, 0.0188, 7.02, 0.0076, 8.04, 0.0009, 9.03, 0.0038, 10.03, 0.0065, 11.03, 0.0075, 12.03, 0.0026, 13.03, 0.0005, 14.04, 0.0009, 15.06, 0.0008, 16.04, 0.0006, 17.03, 0.0004, 18.03, 0.0003, 19.04, 0.0002, 23.03, 0.0002] Fh_ds2 = [1.00, 0.0234, 1.98, 0.0227, 2.96, 0.0129, 3.97, 0.0333, 4.96, 0.0315, 5.95, 0.0252, 6.93, 0.0076, 7.94, 0.0061, 8.91, 0.0028, 9.89, 0.0096, 10.90, 0.0089, 11.89, 0.0024, 12.88, 0.0022, 13.88, 0.0019, 14.87, 0.0010, 15.79, 0.0006, 16.79, 0.0003, 17.79, 0.0002, 18.69, 0.0002, 19.68, 0.0003, 20.70, 0.0002, 21.70, 0.0002] Fh_e2 = [1.00, 0.0150, 1.99, 0.0230, 3.01, 0.0204, 4.00, 0.0298, 5.02, 0.0112, 6.03, 0.0135, 7.02, 0.0019, 8.03, 0.0061, 9.01, 0.0099, 10.04, 0.0053, 11.03, 0.0006, 12.04, 0.0028, 13.04, 0.0016, 14.04, 0.0015, 15.03, 0.0009, 16.02, 0.0005, 17.05, 0.0002, 20.02, 0.0002, 21.02, 0.0001, 24.00, 0.0002, 25.03, 0.0001] Fh_f2 = [0.97, 0.0088, 1.96, 0.0127, 2.97, 0.0179, 3.96, 0.0163, 4.94, 0.0421, 5.91, 0.0165, 6.96, 0.0019, 7.93, 0.0020, 8.91, 0.0112, 9.85, 0.0035, 10.91, 0.0017, 12.02, 0.0004, 12.83, 0.0014, 13.79, 0.0010, 14.79, 0.0007, 15.75, 0.0002, 16.73, 0.0003, 17.74, 0.0007, 18.74, 0.0005, 19.73, 0.0001, 20.68, 0.0002, 21.66, 0.0002, 22.65, 0.0002, 23.63, 0.0001, 24.65, 0.0001] Fh_fs2 = [1.00, 0.0035, 1.99, 0.0136, 2.97, 0.0394, 3.96, 0.0379, 4.98, 0.0330, 5.97, 0.0111, 6.94, 0.0156, 7.94, 0.0108, 8.96, 0.0076, 9.95, 0.0025, 10.95, 0.0021, 11.93, 0.0026, 12.93, 0.0014, 13.89, 0.0008, 14.87, 0.0006, 15.78, 0.0001, 16.94, 0.0001, 17.93, 0.0001, 18.93, 0.0001, 19.89, 0.0001] Fh_g2 = [1.01, 0.0150, 2.01, 0.0182, 3.04, 0.1047, 4.04, 0.0662, 5.03, 0.0448, 6.06, 0.0018, 7.06, 0.0034, 8.06, 0.0202, 9.09, 0.0051, 10.09, 0.0070, 11.08, 0.0060, 12.11, 0.0022, 13.12, 0.0011, 14.13, 0.0005, 15.20, 0.0001, 16.09, 0.0002, 17.14, 0.0002, 18.14, 0.0002, 19.14, 0.0002, 20.16, 0.0002, 21.15, 0.0001, 22.15, 0.0001] Fh_gs2 = [0.99, 0.0092, 2.00, 0.0177, 3.00, 0.0664, 3.98, 0.0447, 4.99, 0.0223, 5.99, 0.0144, 7.00, 0.0124, 7.97, 0.0096, 8.97, 0.0046, 9.96, 0.0011, 10.99, 0.0021, 12.00, 0.0010, 12.99, 0.0007, 13.93, 0.0007, 14.92, 0.0007, 15.94, 0.0005, 16.94, 0.0003, 17.90, 0.0002, 18.88, 0.0001, 19.87, 0.0002, 20.86, 0.0002, 21.86, 0.0001] Fh_a2 = [1.00, 0.0063, 2.01, 0.0609, 3.03, 0.0699, 4.05, 0.1365, 5.04, 0.0249, 6.05, 0.0103, 7.07, 0.0200, 8.08, 0.0059, 9.10, 0.0063, 10.09, 0.0046, 11.10, 0.0015, 12.13, 0.0008, 13.14, 0.0006, 14.07, 0.0004, 15.05, 0.0004, 16.08, 0.0004, 17.10, 0.0002, 18.12, 0.0002, 19.10, 0.0001] Fh_as2 = [1.00, 0.0026, 2.02, 0.0329, 3.03, 0.0926, 4.04, 0.0530, 5.07, 0.0041, 6.07, 0.0072, 7.09, 0.0076, 8.10, 0.0053, 9.11, 0.0057, 10.13, 0.0017, 11.16, 0.0005, 12.21, 0.0001, 13.09, 0.0003, 14.11, 0.0003, 15.18, 0.0003, 16.17, 0.0001] Fh_b2 = [1.01, 0.0154, 2.02, 0.0506, 3.05, 0.1042, 4.05, 0.0643, 5.06, 0.0151, 6.08, 0.0102, 7.09, 0.0045, 8.11, 0.0040, 9.12, 0.0033, 10.12, 0.0015, 11.13, 0.0006, 12.16, 0.0004, 13.18, 0.0003, 14.95, 0.0001, 15.98, 0.0001, 16.99, 0.0001, 18.02, 0.0001] Fh_c3 = [1.01, 0.0147, 2.02, 0.0897, 3.01, 0.1180, 4.01, 0.0323, 5.02, 0.0133, 6.04, 0.0226, 7.04, 0.0033, 8.06, 0.0023, 9.02, 0.0019, 10.03, 0.0010, 11.04, 0.0009, 12.06, 0.0003, 13.04, 0.0002, 14.05, 0.0002, 15.05, 0.0002, 16.01, 0.0002, 16.94, 0.0001] Fh_cs3 = [1.01, 0.0345, 2.00, 0.1083, 2.99, 0.0911, 4.01, 0.0280, 5.01, 0.0071, 6.00, 0.0123, 7.00, 0.0043, 8.01, 0.0034, 9.01, 0.0014, 10.02, 0.0004, 10.94, 0.0003, 11.96, 0.0003, 12.96, 0.0002, 14.89, 0.0001, 15.92, 0.0001] Fh_d3 = [1.01, 0.0488, 2.02, 0.1313, 3.03, 0.1606, 4.03, 0.0029, 5.04, 0.0187, 6.05, 0.0059, 7.05, 0.0018, 8.05, 0.0023, 9.05, 0.0007, 10.06, 0.0003, 11.07, 0.0001, 12.08, 0.0002] Fh_ds3 = [1.00, 0.0619, 2.00, 0.1230, 3.01, 0.0981, 4.02, 0.0299, 5.02, 0.0210, 6.03, 0.0054, 7.03, 0.0023, 8.04, 0.0010, 9.04, 0.0005, 10.06, 0.0002] Fh_e3 = [1.00, 0.0500, 2.01, 0.1076, 3.03, 0.1077, 4.04, 0.0167, 5.03, 0.0138, 6.06, 0.0058, 7.07, 0.0036, 8.06, 0.0007, 9.09, 0.0004, 10.07, 0.0002, 11.03, 0.0001, 12.05, 0.0002] Fh_f3 = [1.01, 0.0368, 2.02, 0.1311, 3.02, 0.0405, 4.03, 0.0139, 5.03, 0.0080, 6.04, 0.0052, 7.05, 0.0015, 8.04, 0.0004, 9.06, 0.0002, 10.06, 0.0002, 12.08, 0.0001] Fh_fs3 = [1.01, 0.0430, 2.02, 0.1877, 3.05, 0.0299, 4.05, 0.0218, 5.07, 0.0067, 6.08, 0.0054, 7.10, 0.0012, 8.11, 0.0010, 9.12, 0.0004, 10.13, 0.0002, 11.15, 0.0001] Fh_g3 = [1.01, 0.0339, 2.04, 0.1965, 4.07, 0.0541, 5.08, 0.0113, 6.10, 0.0049, 7.10, 0.0022, 8.13, 0.0014, 9.14, 0.0008, 10.16, 0.0005] Fh_gs3 = [1.02, 0.0596, 2.02, 0.1865, 3.03, 0.0629, 4.04, 0.0304, 5.05, 0.0087, 6.05, 0.0035, 7.07, 0.0008, 8.09, 0.0004, 9.09, 0.0005, 10.10, 0.0005, 11.11, 0.0002, 12.12, 0.0001] Fh_a3 = [1.00, 0.1160, 2.02, 0.2642, 3.02, 0.0259, 4.02, 0.0127, 5.04, 0.0095, 6.04, 0.0022, 7.04, 0.0013, 8.06, 0.0008, 9.04, 0.0003, 10.01, 0.0001] Fh_as3 = [1.01, 0.0585, 2.01, 0.1648, 3.02, 0.0229, 4.02, 0.0150, 5.03, 0.0084, 6.03, 0.0016, 7.06, 0.0003, 9.01, 0.0002] Fh_b3 = [1.01, 0.0741, 2.00, 0.1581, 3.00, 0.0490, 4.01, 0.0133, 5.01, 0.0045, 6.02, 0.0013, 7.03, 0.0002, 8.00, 0.0001] Fh_c4 = [0.99, 0.1378, 2.00, 0.0872, 2.99, 0.0736, 3.99, 0.0065, 4.99, 0.0025, 5.97, 0.0009, 6.98, 0.0002, 7.98, 0.0005, 8.98, 0.0002] Fh_cs4 = [1.01, 0.2826, 2.02, 0.0676, 3.02, 0.0523, 4.03, 0.0208, 5.04, 0.0069, 6.04, 0.0009, 7.05, 0.0009, 8.06, 0.0011, 9.07, 0.0004, 10.07, 0.0001, 11.08, 0.0002, 12.09, 0.0001] Fh_d4 = [1.01, 0.2849, 2.02, 0.0068, 3.03, 0.0144, 4.04, 0.0066, 5.05, 0.0032, 6.07, 0.0007, 7.07, 0.0003, 8.09, 0.0003] Fh_ds4 = [1.00, 0.2321, 2.01, 0.0612, 3.02, 0.0150, 4.03, 0.0042, 5.03, 0.0007, 6.04, 0.0005, 7.05, 0.0002, 8.06, 0.0001] Fh_e4 = [1.01, 0.1701, 2.01, 0.0303, 3.02, 0.0156, 4.03, 0.0021, 5.04, 0.0009, 6.04, 0.0003, 7.04, 0.0001] Fh_f4 = [1.01, 0.1957, 2.01, 0.0196, 3.01, 0.0087, 4.01, 0.0022, 5.01, 0.0006, 6.02, 0.0002] Fh_fs4 = [1.01, 0.3622, 2.02, 0.0601, 3.03, 0.0187, 4.04, 0.0043, 5.05, 0.0011, 6.06, 0.0005] Fh_g4 = [1.00, 0.2782, 2.01, 0.0918, 3.01, 0.0080, 4.03, 0.0013, 5.03, 0.0010, 6.03, 0.0003] Fh_gs4 = [1.01, 0.2703, 2.02, 0.0548, 3.02, 0.0083, 4.03, 0.0011, 5.03, 0.0009, 6.04, 0.0003] Fh_a4 = [1.01, 0.4575, 2.02, 0.0245, 3.03, 0.0049, 4.04, 0.0019, 5.05, 0.0008, 6.06, 0.0002] Fh_as4 = [1.00, 0.2524, 2.01, 0.0291, 3.02, 0.0022, 4.03, 0.0011, 5.03, 0.0003] Fh_b4 = [1.00, 0.3254, 2.00, 0.0428, 3.00, 0.0026, 4.00, 0.0006] Fh_c5 = [1.00, 0.1672, 2.00, 0.0223, 3.00, 0.0010, 4.00, 0.0005] Fh_cs5 = [1.00, 0.1209, 2.00, 0.0340, 3.00, 0.0014, 4.01, 0.0004] Fh_d5 = [1.01, 0.0150, 2.01, 0.0313, 3.02, 0.0023, 4.03, 0.0007] Fh_ds5 = [1.00, 0.1633, 2.00, 0.0260, 3.00, 0.0012, 4.00, 0.0002] Fh_e5 = [1.00, 0.1001, 2.00, 0.0146, 3.00, 0.0019, 4.00, 0.0001] Fh_f5 = [1.01, 0.0944, 2.01, 0.0114, 3.02, 0.0016, 4.02, 0.0002] Fh_fs5 = [1.01, 0.1904, 2.02, 0.0076, 3.02, 0.0025, 4.03, 0.0003] Fh_g5 = [1.00, 0.2511, 2.00, 0.0017, 3.01, 0.0010, 4.01, 0.0004] Fh_gs5 = [1.00, 0.1029, 1.99, 0.0050, 2.99, 0.0007, 3.99, 0.0002] # # # # # Fhf_as1 = [1.01, 0.0025, 1.99, 0.0008, 3.01, 0.0057, 4.02, 0.0063, 5.03, 0.0268, 6.04, 0.0198, 7.04, 0.0157, 8.03, 0.0160, 9.05, 0.0056, 10.05, 0.0016, 11.06, 0.0059, 12.09, 0.0009, 13.10, 0.0023, 14.08, 0.0022, 15.09, 0.0011, 16.10, 0.0011, 17.11, 0.0012, 18.16, 0.0009, 19.16, 0.0008, 20.15, 0.0005, 21.16, 0.0002, 22.15, 0.0001, 23.15, 0.0001] Fhf_b1 = [1.03, 0.0025, 2.07, 0.0054, 5.15, 0.0276, 6.18, 0.0379, 7.21, 0.0389, 8.23, 0.0176, 9.26, 0.0020, 10.29, 0.0039, 11.24, 0.0002, 12.26, 0.0010, 13.28, 0.0015, 14.34, 0.0010, 15.37, 0.0009, 16.42, 0.0010, 17.47, 0.0027, 18.49, 0.0015, 19.52, 0.0010, 20.56, 0.0005, 21.57, 0.0004, 22.59, 0.0004, 23.60, 0.0003, 24.61, 0.0003, 25.65, 0.0002, 26.67, 0.0002, 27.66, 0.0001, 28.71, 0.0002, 29.75, 0.0001] Fhf_c2 = [1.02, 0.0023, 2.03, 0.0041, 3.03, 0.0059, 4.05, 0.0291, 5.05, 0.0280, 6.06, 0.0396, 7.06, 0.0428, 8.07, 0.0111, 9.08, 0.0018, 10.10, 0.0049, 11.12, 0.0052, 12.12, 0.0075, 13.12, 0.0021, 14.15, 0.0009, 15.18, 0.0008, 16.21, 0.0009, 17.22, 0.0012, 18.23, 0.0008, 19.23, 0.0003, 20.24, 0.0003, 21.23, 0.0002, 22.22, 0.0002, 23.22, 0.0002, 24.25, 0.0001, 25.27, 0.0002, 26.27, 0.0001, 28.25, 0.0001, 30.29, 0.0001, 32.31, 0.0001] Fhf_cs2 = [1.03, 0.0031, 2.02, 0.0111, 3.02, 0.0074, 4.01, 0.0370, 5.01, 0.0307, 6.03, 0.0330, 7.03, 0.0281, 8.02, 0.0089, 9.02, 0.0097, 9.21, 0.0016, 10.03, 0.0014, 11.04, 0.0044, 12.03, 0.0039, 12.96, 0.0004, 14.09, 0.0011, 15.10, 0.0006, 16.10, 0.0014, 17.09, 0.0011, 18.09, 0.0006, 19.10, 0.0005, 20.10, 0.0004, 21.08, 0.0002, 22.10, 0.0003, 22.28, 0.0002, 23.07, 0.0001, 24.04, 0.0002, 25.09, 0.0001, 26.10, 0.0001, 27.10, 0.0001, 32.10, 0.0001] Fhf_d2 = [1.00, 0.0154, 2.01, 0.0193, 3.01, 0.0257, 4.00, 0.0566, 5.00, 0.0570, 6.01, 0.0680, 7.01, 0.0222, 8.03, 0.0023, 9.02, 0.0036, 10.05, 0.0043, 11.07, 0.0037, 12.07, 0.0010, 12.97, 0.0005, 13.99, 0.0014, 14.99, 0.0022, 15.98, 0.0023, 16.97, 0.0011, 17.96, 0.0007, 18.95, 0.0004, 19.12, 0.0003, 19.89, 0.0002, 20.92, 0.0003, 21.11, 0.0002, 21.92, 0.0002, 22.91, 0.0002, 23.88, 0.0002, 24.92, 0.0002, 25.89, 0.0003, 26.88, 0.0003, 27.84, 0.0001] Fhf_ds2 = [1.00, 0.0204, 2.02, 0.0234, 3.03, 0.0132, 4.04, 0.0416, 5.05, 0.0425, 6.04, 0.0258, 7.06, 0.0086, 8.07, 0.0067, 9.14, 0.0009, 10.17, 0.0030, 11.20, 0.0008, 12.09, 0.0016, 13.11, 0.0015, 14.12, 0.0029, 15.11, 0.0028, 16.11, 0.0011, 17.11, 0.0006, 18.09, 0.0003, 19.13, 0.0004, 19.29, 0.0002, 20.10, 0.0002, 21.13, 0.0002, 21.29, 0.0002, 22.26, 0.0001, 23.11, 0.0003, 24.11, 0.0003, 25.08, 0.0002, 26.10, 0.0002, 27.08, 0.0002, 28.10, 0.0001, 28.28, 0.0001] Fhf_e2 = [1.00, 0.0097, 1.99, 0.0146, 3.00, 0.0159, 4.00, 0.0246, 5.02, 0.0137, 6.06, 0.0177, 7.02, 0.0017, 8.05, 0.0029, 9.04, 0.0058, 10.06, 0.0041, 10.96, 0.0009, 12.03, 0.0029, 13.08, 0.0021, 14.12, 0.0008, 15.14, 0.0002, 16.11, 0.0002, 26.90, 0.0001] Fhf_f2 = [1.00, 0.0039, 2.02, 0.0070, 3.04, 0.0156, 4.06, 0.0113, 5.08, 0.0222, 6.07, 0.0065, 7.07, 0.0046, 8.12, 0.0018, 9.13, 0.0081, 10.13, 0.0014, 11.17, 0.0012, 12.17, 0.0014, 13.21, 0.0007, 13.98, 0.0005, 14.24, 0.0003, 14.98, 0.0003, 15.96, 0.0002, 17.21, 0.0001, 18.97, 0.0002, 20.02, 0.0001, 21.05, 0.0001] Fhf_fs2 = [1.02, 0.0030, 2.03, 0.0096, 3.04, 0.0372, 4.06, 0.0225, 5.09, 0.0048, 6.17, 0.0019, 7.19, 0.0014, 8.20, 0.0014, 9.19, 0.0023, 10.22, 0.0008, 11.09, 0.0003, 12.23, 0.0006, 13.25, 0.0004, 14.25, 0.0002, 15.14, 0.0001, 16.19, 0.0002, 17.20, 0.0002, 18.24, 0.0002, 19.23, 0.0001, 20.27, 0.0001, 21.29, 0.0001, 23.26, 0.0001] Fhf_g2 = [1.03, 0.0067, 2.02, 0.0055, 3.06, 0.0282, 5.01, 0.0043, 5.20, 0.0033, 6.05, 0.0006, 7.09, 0.0009, 8.13, 0.0070, 9.17, 0.0006, 10.20, 0.0010, 11.23, 0.0007, 12.28, 0.0002, 13.16, 0.0001, 14.23, 0.0001] Fhf_gs2 = [0.99, 0.0029, 2.02, 0.0054, 3.01, 0.0149, 4.03, 0.0101, 5.03, 0.0047, 6.02, 0.0035, 7.02, 0.0028, 8.04, 0.0026, 9.03, 0.0010, 10.03, 0.0003, 11.07, 0.0004, 11.89, 0.0001, 12.98, 0.0001, 13.99, 0.0002] Fhf_a2 = [0.99, 0.0020, 2.00, 0.0131, 3.00, 0.0085, 4.01, 0.0199, 4.99, 0.0044, 5.98, 0.0020, 7.00, 0.0029, 8.01, 0.0009, 9.02, 0.0010, 9.99, 0.0007, 10.94, 0.0003] Fhf_as2 = [1.00, 0.0013, 2.01, 0.0042, 3.01, 0.0101, 3.99, 0.0132, 4.98, 0.0011, 5.97, 0.0007, 6.96, 0.0031, 7.99, 0.0009, 9.10, 0.0003, 9.99, 0.0003, 10.92, 0.0002, 11.88, 0.0002, 12.85, 0.0001] Fhf_b2 = [1.01, 0.0038, 2.00, 0.0081, 2.98, 0.0138, 3.96, 0.0105, 4.96, 0.0021, 5.95, 0.0034, 6.89, 0.0013, 7.91, 0.0006, 8.86, 0.0005, 9.87, 0.0001] Fhf_c3 = [1.00, 0.0033, 2.01, 0.0162, 3.00, 0.0168, 4.00, 0.0069, 5.00, 0.0033, 6.01, 0.0061, 7.01, 0.0006, 8.01, 0.0003, 8.98, 0.0003, 9.97, 0.0002, 10.98, 0.0001] Fhf_cs3 = [1.01, 0.0161, 2.01, 0.0404, 3.01, 0.0208, 4.02, 0.0039, 5.02, 0.0013, 6.02, 0.0041, 7.02, 0.0019, 8.01, 0.0011, 9.01, 0.0003] Fhf_d3 = [1.01, 0.0238, 2.01, 0.0582, 3.02, 0.0679, 4.02, 0.0022, 5.03, 0.0081, 6.03, 0.0024, 7.03, 0.0012, 8.05, 0.0010, 9.05, 0.0001, 10.08, 0.0001] Fhf_ds3 = [1.00, 0.0295, 2.01, 0.0519, 3.02, 0.0343, 4.04, 0.0119, 5.05, 0.0067, 6.07, 0.0011, 7.08, 0.0013, 8.09, 0.0004] Fhf_e3 = [1.01, 0.0251, 2.04, 0.0479, 3.03, 0.0741, 4.04, 0.0054, 5.05, 0.0049, 6.04, 0.0029, 7.06, 0.0021, 8.10, 0.0006, 9.11, 0.0004, 10.10, 0.0002, 11.13, 0.0002] Fhf_f3 = [1.02, 0.0143, 2.02, 0.0453, 3.04, 0.0115, 4.05, 0.0021, 5.08, 0.0007, 6.10, 0.0007, 7.07, 0.0006, 8.04, 0.0001] Fhf_fs3 = [1.01, 0.0220, 2.03, 0.0843, 3.04, 0.0119, 4.06, 0.0062, 5.09, 0.0022, 6.12, 0.0016, 7.14, 0.0003, 9.13, 0.0001] Fhf_g3 = [1.02, 0.0145, 2.03, 0.0700, 3.03, 0.0010, 5.13, 0.0013, 6.14, 0.0007, 7.14, 0.0002] Fhf_gs3 = [1.02, 0.0273, 2.03, 0.0703, 3.04, 0.0176, 4.07, 0.0073, 5.08, 0.0021, 6.09, 0.0004, 7.09, 0.0002, 8.09, 0.0001] Fhf_a3 = [1.00, 0.0529, 2.02, 0.0982, 3.02, 0.0066, 4.04, 0.0034, 5.05, 0.0029, 6.04, 0.0003, 7.03, 0.0002] Fhf_as3 = [1.01, 0.0274, 2.01, 0.0613, 3.02, 0.0056, 4.03, 0.0056, 5.03, 0.0024, 6.03, 0.0003] Fhf_b3 = [1.01, 0.0468, 2.01, 0.0884, 3.01, 0.0246, 4.02, 0.0058, 5.03, 0.0016, 6.03, 0.0005, 7.02, 0.0002, 8.01, 0.0001] Fhf_c4 = [1.01, 0.0972, 2.01, 0.0455, 3.02, 0.0442, 4.03, 0.0073, 5.03, 0.0017, 6.03, 0.0005, 7.04, 0.0008, 8.05, 0.0003, 9.05, 0.0001] Fhf_cs4 = [1.01, 0.1452, 2.01, 0.0382, 3.02, 0.0285, 4.02, 0.0080, 5.02, 0.0019, 6.01, 0.0002, 7.03, 0.0003, 8.04, 0.0002] Fhf_d4 = [1.01, 0.1930, 2.02, 0.0066, 3.03, 0.0070, 4.05, 0.0041, 5.05, 0.0016, 6.07, 0.0003] Fhf_ds4 = [1.00, 0.1433, 2.01, 0.0414, 3.02, 0.0101, 4.03, 0.0020, 5.02, 0.0002, 6.03, 0.0003, 7.06, 0.0001] Fhf_e4 = [1.00, 0.1373, 2.01, 0.0256, 3.01, 0.0164, 4.02, 0.0026, 5.02, 0.0014, 6.02, 0.0004, 7.03, 0.0002] Fhf_f4 = [1.01, 0.1930, 2.01, 0.0192, 3.02, 0.0124, 4.02, 0.0030, 5.03, 0.0013, 6.03, 0.0006, 7.03, 0.0002] Fhf_fs4 = [1.01, 0.2352, 2.01, 0.0485, 3.02, 0.0135, 4.03, 0.0035, 5.03, 0.0010, 6.04, 0.0004] Fhf_g4 = [1.01, 0.1991, 2.03, 0.0655, 3.04, 0.0065, 4.04, 0.0015, 5.06, 0.0006, 6.07, 0.0002] Fhf_gs4 = [1.01, 0.2177, 2.02, 0.0422, 3.03, 0.0038, 4.05, 0.0014, 5.06, 0.0006] Fhf_a4 = [1.01, 0.3779, 2.02, 0.0161, 3.03, 0.0026, 4.04, 0.0009, 5.05, 0.0005] Fhf_as4 = [1.00, 0.1879, 2.01, 0.0205, 3.02, 0.0006, 4.03, 0.0006] Fhf_b4 = [0.99, 0.2910, 1.99, 0.0363, 2.99, 0.0019, 3.99, 0.0001, 4.98, 0.0001] Fhf_c5 = [1.00, 0.0690, 2.01, 0.0086, 3.01, 0.0002, 4.00, 0.0002] Fhf_cs5 = [1.01, 0.0872, 2.02, 0.0247, 3.03, 0.0008, 4.05, 0.0002] Fhf_d5 = [1.01, 0.0213, 2.02, 0.0275, 3.03, 0.0031, 4.04, 0.0008, 5.05, 0.0002, 6.07, 0.0001] Fhf_ds5 = [1.01, 0.1852, 2.01, 0.0224, 3.01, 0.0043, 4.02, 0.0006, 5.03, 0.0001] Fhf_e5 = [1.01, 0.1063, 2.02, 0.0144, 3.03, 0.0018, 4.04, 0.0006, 5.05, 0.0001] Fhf_f5 = [1.02, 0.1058, 2.04, 0.0062, 3.06, 0.0023, 4.08, 0.0005] Fhf_fs5 = [1.01, 0.1683, 2.03, 0.0099, 3.04, 0.0026, 4.05, 0.0004, 5.07, 0.0003] Fhf_g5 = [1.01, 0.3271, 2.02, 0.0090, 3.03, 0.0022, 4.04, 0.0007] # # # # # flute? Fl_c4 = [1.01, 0.0602, 2.02, 0.0954, 3.03, 0.0270, 4.03, 0.0199, 5.05, 0.0177, 6.06, 0.0104, 7.07, 0.0040, 8.08, 0.0040, 9.08, 0.0035, 10.10, 0.0017, 11.10, 0.0009, 12.12, 0.0004, 13.11, 0.0002, 14.13, 0.0006, 15.14, 0.0003, 17.15, 0.0002, 18.16, 0.0001] Fl_cs4 = [1.01, 0.0672, 2.01, 0.0689, 3.02, 0.0604, 4.02, 0.0410, 5.02, 0.0130, 6.03, 0.0040, 7.03, 0.0210, 8.03, 0.0078, 9.04, 0.0010, 10.07, 0.0002, 11.05, 0.0005, 12.05, 0.0008, 13.05, 0.0004, 14.06, 0.0002, 15.07, 0.0001, 19.08, 0.0001] Fl_d4 = [1.01, 0.0747, 2.01, 0.2106, 3.01, 0.0522, 4.02, 0.0208, 5.01, 0.0138, 6.02, 0.0024, 7.03, 0.0071, 8.03, 0.0038, 8.17, 0.0002, 8.74, 0.0001, 10.03, 0.0004, 11.04, 0.0014, 12.03, 0.0001, 13.06, 0.0002, 14.05, 0.0003, 15.06, 0.0001, 16.07, 0.0001, 17.06, 0.0002, 18.06, 0.0002] Fl_ds4 = [1.00, 0.0256, 2.00, 0.1167, 3.00, 0.0241, 4.01, 0.0159, 5.01, 0.0200, 6.00, 0.0167, 7.01, 0.0069, 8.04, 0.0004, 9.00, 0.0009, 10.01, 0.0010, 11.00, 0.0004, 12.00, 0.0003, 13.00, 0.0002, 14.01, 0.0002, 16.00, 0.0002, 17.01, 0.0002] Fl_e4 = [1.00, 0.0572, 2.01, 0.1769, 3.01, 0.0622, 4.00, 0.0323, 5.01, 0.0210, 6.01, 0.0163, 7.02, 0.0068, 8.01, 0.0007, 8.13, 0.0002, 8.39, 0.0001, 10.02, 0.0011, 11.02, 0.0004, 12.02, 0.0003, 15.03, 0.0002, 16.03, 0.0001, 17.04, 0.0001, 18.04, 0.0001] Fl_f4 = [1.01, 0.0438, 2.01, 0.0964, 3.01, 0.0569, 4.01, 0.0096, 5.01, 0.0164, 6.01, 0.0194, 7.02, 0.0024, 8.01, 0.0005, 9.03, 0.0007, 10.04, 0.0005, 12.05, 0.0002, 13.04, 0.0001, 14.05, 0.0002] Fl_fs4 = [1.00, 0.0952, 2.00, 0.1432, 3.01, 0.0299, 4.01, 0.0371, 5.02, 0.0189, 6.02, 0.0092, 7.03, 0.0060, 8.03, 0.0003, 9.04, 0.0025, 10.04, 0.0006, 11.04, 0.0003, 13.05, 0.0002, 14.06, 0.0002] Fl_g4 = [1.00, 0.2831, 2.01, 0.1781, 3.01, 0.0370, 4.02, 0.0191, 5.02, 0.0313, 6.02, 0.0048, 7.04, 0.0007, 8.03, 0.0022, 9.04, 0.0015, 9.13, 0.0001, 10.04, 0.0001, 11.05, 0.0002, 12.05, 0.0002, 14.07, 0.0001, 15.06, 0.0001] Fl_gs4 = [1.00, 0.2598, 2.00, 0.2241, 3.01, 0.0407, 4.01, 0.0354, 5.01, 0.0398, 6.01, 0.0111, 7.03, 0.0007, 8.01, 0.0030, 9.01, 0.0018, 10.02, 0.0002, 12.02, 0.0004, 13.02, 0.0001, 14.03, 0.0002, 15.03, 0.0001] Fl_a4 = [1.00, 0.2580, 2.01, 0.1605, 3.00, 0.0236, 4.01, 0.0281, 5.02, 0.0047, 6.02, 0.0024, 7.02, 0.0010, 8.02, 0.0027, 9.02, 0.0004, 10.03, 0.0002, 11.03, 0.0003, 12.04, 0.0001, 13.04, 0.0002, 14.04, 0.0002] Fl_as4 = [1.01, 0.1855, 2.01, 0.1041, 3.01, 0.0480, 4.02, 0.0416, 5.02, 0.0059, 6.02, 0.0016, 7.03, 0.0004, 8.03, 0.0016, 9.03, 0.0003, 10.04, 0.0004, 11.05, 0.0003, 16.07, 0.0002] Fl_b4 = [1.01, 0.0564, 2.01, 0.1996, 3.02, 0.0219, 4.02, 0.0108, 5.03, 0.0183, 6.04, 0.0005, 7.04, 0.0009, 8.05, 0.0014, 10.06, 0.0006, 11.07, 0.0003] Fl_c5 = [1.01, 0.0245, 2.02, 0.1674, 3.04, 0.0228, 4.05, 0.0229, 5.06, 0.0087, 6.09, 0.0004, 7.09, 0.0004, 8.10, 0.0003, 9.11, 0.0002, 10.14, 0.0002, 11.15, 0.0001] Fl_cs5 = [1.00, 0.0885, 2.01, 0.0661, 3.01, 0.0281, 4.02, 0.0068, 5.02, 0.0038, 6.02, 0.0010, 7.02, 0.0008, 8.03, 0.0007, 9.03, 0.0005, 10.04, 0.0002, 11.04, 0.0003] Fl_d5 = [1.01, 0.3830, 2.01, 0.1043, 3.01, 0.0372, 4.02, 0.0175, 5.03, 0.0035, 6.03, 0.0011, 7.04, 0.0010, 8.04, 0.0004, 9.04, 0.0002, 10.05, 0.0001] Fl_ds5 = [1.00, 0.2294, 2.01, 0.0606, 3.01, 0.0238, 4.01, 0.0050, 5.01, 0.0041, 6.02, 0.0007, 7.02, 0.0007, 8.02, 0.0006, 10.03, 0.0002, 12.03, 0.0001] Fl_e5 = [1.01, 0.3759, 2.03, 0.0529, 3.03, 0.0595, 4.05, 0.0010, 5.06, 0.0077, 6.07, 0.0008, 7.09, 0.0007, 8.09, 0.0005, 9.11, 0.0001, 10.12, 0.0002, 12.14, 0.0001] Fl_f5 = [1.01, 0.1982, 2.02, 0.0204, 3.02, 0.0554, 4.03, 0.0064, 5.04, 0.0040, 6.05, 0.0016, 7.06, 0.0007, 8.07, 0.0006, 9.07, 0.0001, 10.08, 0.0001, 12.10, 0.0001] Fl_fs5 = [1.01, 0.3241, 2.02, 0.0548, 3.03, 0.0082, 4.04, 0.0022, 5.05, 0.0038, 6.06, 0.0004, 7.07, 0.0009, 8.09, 0.0001, 9.09, 0.0003, 10.10, 0.0001] Fl_g5 = [1.01, 0.4049, 2.01, 0.0301, 3.02, 0.0229, 4.03, 0.0047, 5.04, 0.0029, 6.05, 0.0014, 7.05, 0.0009, 8.06, 0.0003, 9.07, 0.0002, 10.07, 0.0002, 11.09, 0.0001, 12.09, 0.0001] Fl_gs5 = [1.00, 0.5433, 2.01, 0.0536, 3.01, 0.0411, 4.02, 0.0074, 5.02, 0.0014, 6.02, 0.0011, 7.03, 0.0004, 8.03, 0.0003, 9.04, 0.0001] Fl_a5 = [1.01, 0.3063, 2.01, 0.0346, 3.02, 0.0102, 4.03, 0.0031, 5.03, 0.0007, 6.04, 0.0010, 7.03, 0.0003, 8.06, 0.0001, 9.05, 0.0002, 11.06, 0.0002] Fl_as5 = [1.01, 0.1962, 2.03, 0.0355, 3.04, 0.0128, 4.06, 0.0020, 5.07, 0.0021, 6.08, 0.0003, 7.10, 0.0003, 8.11, 0.0002] Fl_b5 = [1.01, 0.3829, 2.02, 0.0120, 3.03, 0.0037, 4.04, 0.0030, 5.05, 0.0016, 6.06, 0.0006, 7.07, 0.0002, 8.08, 0.0004, 9.09, 0.0001] Fl_c6 = [1.01, 0.3072, 2.02, 0.0248, 3.04, 0.0012, 4.05, 0.0006, 5.06, 0.0011, 6.07, 0.0009, 7.08, 0.0003, 8.10, 0.0001, 10.12, 0.0001] Fl_cs6 = [1.01, 0.1262, 2.02, 0.0030, 3.03, 0.0012, 4.04, 0.0005, 5.06, 0.0010, 6.07, 0.0002, 7.08, 0.0004, 8.09, 0.0002] Fl_d6 = [1.01, 0.3050, 2.03, 0.0071, 3.04, 0.0107, 4.06, 0.0005, 5.07, 0.0015, 6.08, 0.0002, 7.10, 0.0003, 8.11, 0.0002, 9.13, 0.0001] Fl_ds6 = [1.02, 0.0954, 2.05, 0.0025, 3.06, 0.0047, 4.09, 0.0007, 5.11, 0.0017, 6.13, 0.0001, 7.15, 0.0002] Fl_e6 = [1.02, 0.2864, 2.05, 0.0057, 3.08, 0.0023, 5.13, 0.0007, 6.16, 0.0001, 8.21, 0.0001] Fl_f6 = [1.03, 0.0675, 2.05, 0.0049, 3.08, 0.0024, 5.13, 0.0008, 6.16, 0.0002, 7.18, 0.0002, 8.21, 0.0001] Fl_fs6 = [1.02, 0.2553, 2.05, 0.0044, 3.07, 0.0032, 5.12, 0.0007, 6.14, 0.0002, 8.19, 0.0001] Fl_g6 = [1.02, 0.1190, 2.05, 0.0069, 3.07, 0.0046, 5.12, 0.0010, 6.14, 0.0001, 7.17, 0.0007, 7.26, 0.0001] Fl_gs6 = [1.02, 0.3872, 2.05, 0.0093, 3.07, 0.0051, 5.12, 0.0008, 6.15, 0.0001, 7.17, 0.0002, 7.18, 0.0001] Fl_a6 = [1.02, 0.2920, 2.04, 0.0122, 3.06, 0.0052, 4.08, 0.0007, 5.10, 0.0003, 6.31, 0.0002, 7.15, 0.0003] Fl_as6 = [1.02, 0.5687, 2.04, 0.0090, 3.06, 0.0075, 4.08, 0.0007, 5.10, 0.0010, 6.15, 0.0002, 6.21, 0.0002, 6.40, 0.0001, 6.47, 0.0001] Fl_b6 = [1.03, 0.2752, 2.06, 0.0061, 3.09, 0.0039, 5.14, 0.0002, 5.86, 0.0002, 6.18, 0.0001, 6.24, 0.0001, 6.45, 0.0001] Fl_c7 = [1.04, 0.2720, 2.07, 0.0046, 5.18, 0.0003, 5.40, 0.0002, 6.02, 0.0002] Fl_cs7 = [1.03, 0.3752, 2.06, 0.0156, 5.16, 0.0007, 5.20, 0.0003, 5.40, 0.0001, 5.41, 0.0001, 5.57, 0.0001] Fl_d7 = [1.04, 0.2861, 2.07, 0.0147, 5.18, 0.0012, 5.27, 0.0002, 5.30, 0.0001] # # # # # oboe? Ob_as3 = [1.00, 0.0504, 2.00, 0.0724, 2.99, 0.1036, 3.99, 0.1215, 4.99, 0.1360, 5.99, 0.0852, 6.98, 0.0593, 7.97, 0.0230, 8.98, 0.0077, 9.97, 0.0063, 10.97, 0.0016, 11.96, 0.0008, 12.97, 0.0017, 13.97, 0.0017, 14.96, 0.0020, 15.96, 0.0007, 16.96, 0.0006, 17.96, 0.0002, 21.95, 0.0001, 22.95, 0.0001, 23.94, 0.0002, 24.94, 0.0002, 25.94, 0.0001] Ob_b3 = [0.99, 0.0587, 1.99, 0.0820, 2.98, 0.0673, 3.98, 0.1069, 4.97, 0.1336, 5.97, 0.0948, 6.96, 0.0455, 7.96, 0.0070, 8.95, 0.0017, 9.95, 0.0023, 10.95, 0.0063, 11.93, 0.0031, 12.93, 0.0021, 13.92, 0.0009, 14.92, 0.0005, 15.92, 0.0003, 16.89, 0.0001, 21.88, 0.0001, 23.88, 0.0001] Ob_c4 = [1.00, 0.0784, 2.00, 0.0494, 2.99, 0.0668, 3.99, 0.0785, 4.99, 0.1406, 5.99, 0.0747, 6.99, 0.0460, 7.98, 0.0147, 8.98, 0.0115, 9.97, 0.0083, 10.98, 0.0058, 11.98, 0.0059, 12.97, 0.0027, 13.98, 0.0010, 14.96, 0.0006, 15.97, 0.0002, 16.96, 0.0001, 17.96, 0.0002, 19.95, 0.0001, 20.96, 0.0002, 21.95, 0.0001] Ob_cs4 = [1.00, 0.0801, 2.00, 0.0526, 2.99, 0.0568, 3.99, 0.0713, 4.99, 0.1811, 5.99, 0.0721, 6.99, 0.0491, 7.98, 0.0201, 8.98, 0.0128, 9.98, 0.0132, 10.98, 0.0104, 11.98, 0.0081, 12.97, 0.0055, 13.97, 0.0026, 14.97, 0.0010, 15.97, 0.0003, 16.97, 0.0004, 17.96, 0.0003, 18.97, 0.0004, 19.95, 0.0006, 20.96, 0.0003, 21.96, 0.0002] Ob_d4 = [1.00, 0.0775, 2.00, 0.0853, 3.01, 0.0538, 4.01, 0.0600, 5.00, 0.1853, 6.01, 0.0714, 7.01, 0.0247, 8.01, 0.0265, 9.01, 0.0028, 10.01, 0.0116, 11.02, 0.0078, 12.02, 0.0060, 13.01, 0.0036, 14.02, 0.0010, 15.03, 0.0005, 16.01, 0.0002, 17.02, 0.0002, 18.01, 0.0004, 19.02, 0.0004, 20.02, 0.0002, 21.02, 0.0001] Ob_ds4 = [1.00, 0.0922, 1.99, 0.0922, 2.99, 0.0912, 3.99, 0.0337, 4.98, 0.1696, 5.97, 0.0481, 6.98, 0.0184, 7.97, 0.0104, 8.96, 0.0185, 9.96, 0.0147, 10.96, 0.0057, 11.95, 0.0039, 12.95, 0.0012, 13.94, 0.0006, 14.94, 0.0009, 15.94, 0.0005, 16.93, 0.0005, 17.93, 0.0003, 18.93, 0.0001, 19.92, 0.0001] Ob_e4 = [1.00, 0.0970, 2.01, 0.0554, 3.01, 0.0624, 4.02, 0.1806, 5.02, 0.1392, 6.02, 0.0367, 7.03, 0.0165, 8.04, 0.0102, 9.04, 0.0159, 10.04, 0.0077, 11.04, 0.0092, 12.05, 0.0027, 13.06, 0.0004, 14.06, 0.0007, 15.06, 0.0003, 16.07, 0.0006, 17.07, 0.0003, 18.08, 0.0003, 19.08, 0.0001, 20.09, 0.0002] Ob_f4 = [1.00, 0.0988, 2.01, 0.0364, 3.00, 0.0573, 4.01, 0.2291, 5.01, 0.0802, 6.02, 0.0188, 7.02, 0.0160, 8.02, 0.0143, 9.02, 0.0152, 10.02, 0.0140, 11.03, 0.0054, 12.01, 0.0003, 13.03, 0.0012, 14.03, 0.0008, 15.04, 0.0008, 16.04, 0.0006, 17.04, 0.0006, 18.04, 0.0003, 19.05, 0.0001] Ob_fs4 = [1.01, 0.0340, 2.01, 0.0618, 3.02, 0.0923, 4.03, 0.1479, 5.03, 0.1058, 6.04, 0.0281, 7.05, 0.0071, 8.05, 0.0157, 9.06, 0.0018, 10.07, 0.0014, 11.07, 0.0005, 12.08, 0.0013, 13.09, 0.0012, 14.10, 0.0005, 15.10, 0.0003, 16.11, 0.0005, 17.12, 0.0002] Ob_g4 = [1.01, 0.0606, 2.01, 0.0774, 3.02, 0.0552, 4.03, 0.0700, 5.04, 0.0194, 6.04, 0.0066, 7.05, 0.0147, 8.06, 0.0134, 9.07, 0.0055, 10.08, 0.0035, 11.08, 0.0004, 12.10, 0.0004, 13.10, 0.0008, 14.11, 0.0011, 15.10, 0.0004] Ob_gs4 = [1.01, 0.0573, 2.01, 0.0346, 3.03, 0.0608, 4.03, 0.0675, 5.04, 0.0643, 6.05, 0.0193, 7.06, 0.0125, 8.07, 0.0109, 9.07, 0.0010, 10.09, 0.0003, 11.09, 0.0016, 12.10, 0.0015, 13.11, 0.0006, 14.11, 0.0003, 15.13, 0.0002, 16.13, 0.0002] Ob_a4 = [1.00, 0.0923, 2.00, 0.0358, 3.00, 0.0726, 4.00, 0.2111, 5.00, 0.0316, 5.99, 0.0016, 7.00, 0.0080, 8.00, 0.0075, 9.00, 0.0031, 10.01, 0.0007, 11.01, 0.0008, 12.00, 0.0005, 13.00, 0.0003, 14.01, 0.0005, 15.01, 0.0001] Ob_as4 = [1.00, 0.0753, 2.00, 0.0693, 3.00, 0.3731, 4.01, 0.0810, 5.01, 0.0245, 6.00, 0.0142, 7.00, 0.0061, 8.01, 0.0025, 9.01, 0.0004, 10.01, 0.0005, 11.01, 0.0005, 12.02, 0.0005, 13.02, 0.0003] Ob_b4 = [1.00, 0.0618, 2.01, 0.0377, 3.02, 0.0642, 4.02, 0.0401, 5.02, 0.0165, 6.03, 0.0176, 7.03, 0.0079, 8.04, 0.0016, 9.04, 0.0003, 10.06, 0.0003, 11.05, 0.0006, 12.06, 0.0003, 13.06, 0.0001] Ob_c5 = [1.01, 0.0484, 2.02, 0.0490, 3.02, 0.0364, 4.03, 0.0166, 5.03, 0.0172, 6.04, 0.0261, 7.05, 0.0120, 8.06, 0.0021, 9.06, 0.0035, 10.07, 0.0021, 11.08, 0.0008, 12.08, 0.0003] Ob_cs5 = [1.01, 0.1071, 2.02, 0.0487, 3.03, 0.1175, 4.04, 0.0329, 5.05, 0.0231, 6.06, 0.0136, 7.07, 0.0047, 8.07, 0.0009, 9.09, 0.0011, 10.10, 0.0016, 11.10, 0.0010, 12.12, 0.0002] Ob_d5 = [1.01, 0.1893, 2.01, 0.0986, 3.02, 0.1665, 4.02, 0.0326, 5.03, 0.0275, 6.04, 0.0155, 7.04, 0.0029, 8.05, 0.0013, 9.06, 0.0016, 10.07, 0.0010, 11.07, 0.0004, 12.08, 0.0001] Ob_ds5 = [1.00, 0.2003, 2.00, 0.0265, 3.00, 0.1047, 4.00, 0.0138, 5.00, 0.0391, 6.00, 0.0094, 6.99, 0.0023, 8.00, 0.0018, 8.99, 0.0011, 9.99, 0.0006, 10.99, 0.0002, 11.99, 0.0001] Ob_e5 = [1.00, 0.0906, 2.00, 0.4215, 3.00, 0.1046, 3.99, 0.0081, 4.99, 0.0118, 5.99, 0.0054, 6.99, 0.0005, 7.99, 0.0014, 8.99, 0.0005, 9.99, 0.0002] Ob_f5 = [1.00, 0.0657, 2.00, 0.4134, 2.99, 0.0463, 3.99, 0.0144, 4.99, 0.0277, 5.99, 0.0047, 6.98, 0.0005, 7.98, 0.0004, 8.98, 0.0003] Ob_fs5 = [1.01, 0.0957, 2.03, 0.2943, 3.04, 0.0855, 4.06, 0.0568, 5.07, 0.0247, 6.08, 0.0013, 7.10, 0.0024, 8.12, 0.0011, 9.13, 0.0006, 10.15, 0.0002, 11.16, 0.0001, 12.17, 0.0001] Ob_g5 = [1.01, 0.0975, 2.02, 0.1012, 3.04, 0.0543, 4.05, 0.0298, 5.06, 0.0083, 6.07, 0.0026, 7.08, 0.0017, 8.09, 0.0003, 9.11, 0.0001] Ob_gs5 = [1.01, 0.0400, 2.01, 0.0481, 3.02, 0.0403, 4.02, 0.0169, 5.03, 0.0002, 6.04, 0.0030, 7.04, 0.0008] Ob_a5 = [1.01, 0.0725, 2.02, 0.1474, 3.03, 0.0327, 4.04, 0.0281, 5.05, 0.0013, 6.06, 0.0028, 7.07, 0.0004] Ob_as5 = [1.00, 0.0837, 2.00, 0.1039, 3.00, 0.0366, 4.01, 0.0118, 5.01, 0.0021, 6.01, 0.0012] Ob_b5 = [1.02, 0.0812, 2.04, 0.0709, 3.06, 0.0658, 4.08, 0.0099, 5.10, 0.0069, 6.12, 0.0007, 7.14, 0.0001, 8.16, 0.0001] Ob_c6 = [1.01, 0.0799, 2.02, 0.0161, 3.02, 0.0476, 4.03, 0.0084, 5.04, 0.0029, 6.05, 0.0002] Ob_cs6 = [1.01, 0.2331, 2.02, 0.1151, 3.03, 0.0163, 4.04, 0.0013, 5.05, 0.0004, 6.07, 0.0003] Ob_d6 = [1.02, 0.2469, 2.03, 0.0288, 3.05, 0.0144, 4.06, 0.0012, 5.08, 0.0008] Ob_ds6 = [1.00, 0.2770, 2.00, 0.0028, 3.00, 0.0095, 4.00, 0.0042, 5.00, 0.0006, 5.99, 0.0002] Ob_e6 = [1.00, 0.3019, 2.01, 0.0125, 3.01, 0.0049, 4.02, 0.0008, 5.02, 0.0001, 6.02, 0.0001] Ob_f6 = [1.01, 0.0898, 2.01, 0.0089, 3.02, 0.0067, 4.02, 0.0010, 5.03, 0.0002, 6.03, 0.0001] Ob_fs6 = [1.01, 0.1330, 2.03, 0.0090, 3.05, 0.0031, 4.06, 0.0001] Ob_g6 = [1.00, 0.1046, 1.99, 0.0228, 2.99, 0.0004, 3.98, 0.0001] # # # # # piano P_c1 = [1.97, 0.0326, 2.99, 0.0086, 3.95, 0.0163, 4.97, 0.0178, 5.98, 0.0177, 6.95, 0.0315, 8.02, 0.0001, 8.94, 0.0076, 9.96, 0.0134, 10.99, 0.0284, 11.98, 0.0229, 13.02, 0.0229, 13.89, 0.0010, 15.06, 0.0090, 16.00, 0.0003, 17.08, 0.0078, 18.16, 0.0064, 19.18, 0.0129, 20.21, 0.0085, 21.27, 0.0225, 22.32, 0.0061, 23.41, 0.0102, 24.48, 0.0005, 25.56, 0.0016, 26.64, 0.0018, 27.70, 0.0113, 28.80, 0.0111, 29.91, 0.0158, 31.06, 0.0093, 32.17, 0.0017, 33.32, 0.0002, 34.42, 0.0018, 35.59, 0.0027, 36.74, 0.0055, 37.90, 0.0037, 39.06, 0.0064, 40.25, 0.0033, 41.47, 0.0014, 42.53, 0.0004, 43.89, 0.0010, 45.12, 0.0039, 46.33, 0.0039, 47.64, 0.0009, 48.88, 0.0016, 50.13, 0.0006, 51.37, 0.0010, 52.70, 0.0002, 54.00, 0.0004, 55.30, 0.0008, 56.60, 0.0025, 57.96, 0.0010, 59.30, 0.0012, 60.67, 0.0011, 61.99, 0.0003, 62.86, 0.0001, 64.36, 0.0005, 64.86, 0.0001, 66.26, 0.0004, 67.70, 0.0006, 68.94, 0.0002, 70.10, 0.0001, 70.58, 0.0002, 72.01, 0.0007, 73.53, 0.0006, 75.00, 0.0002, 77.03, 0.0005, 78.00, 0.0002, 79.57, 0.0006, 81.16, 0.0005, 82.70, 0.0005, 84.22, 0.0003, 85.41, 0.0002, 87.46, 0.0001, 90.30, 0.0001, 94.02, 0.0001, 95.26, 0.0002, 109.39, 0.0003] P_cs1 = [1.98, 0.0194, 2.99, 0.0210, 3.97, 0.0276, 4.96, 0.0297, 5.96, 0.0158, 6.99, 0.0207, 8.01, 0.0009, 9.00, 0.0101, 10.00, 0.0297, 11.01, 0.0289, 12.02, 0.0211, 13.04, 0.0127, 14.07, 0.0061, 15.08, 0.0174, 16.13, 0.0009, 17.12, 0.0093, 18.16, 0.0117, 19.21, 0.0122, 20.29, 0.0108, 21.30, 0.0077, 22.38, 0.0132, 23.46, 0.0073, 24.14, 0.0002, 25.58, 0.0026, 26.69, 0.0035, 27.77, 0.0053, 28.88, 0.0024, 30.08, 0.0027, 31.13, 0.0075, 32.24, 0.0027, 33.36, 0.0004, 34.42, 0.0004, 35.64, 0.0019, 36.78, 0.0037, 38.10, 0.0009, 39.11, 0.0027, 40.32, 0.0010, 41.51, 0.0013, 42.66, 0.0019, 43.87, 0.0007, 45.13, 0.0017, 46.35, 0.0019, 47.65, 0.0021, 48.89, 0.0014, 50.18, 0.0023, 51.42, 0.0015, 52.73, 0.0002, 54.00, 0.0005, 55.34, 0.0006, 56.60, 0.0010, 57.96, 0.0016, 58.86, 0.0005, 59.30, 0.0004, 60.75, 0.0005, 62.22, 0.0003, 63.55, 0.0005, 64.82, 0.0003, 66.24, 0.0003, 67.63, 0.0011, 69.09, 0.0007, 70.52, 0.0004, 72.00, 0.0005, 73.50, 0.0008, 74.95, 0.0003, 77.13, 0.0013, 78.02, 0.0002, 79.48, 0.0004, 82.59, 0.0004, 84.10, 0.0003] P_d1 = [2.00, 0.0313, 2.99, 0.0109, 4.00, 0.0215, 5.00, 0.0242, 5.98, 0.0355, 7.01, 0.0132, 8.01, 0.0009, 9.01, 0.0071, 10.00, 0.0258, 11.03, 0.0221, 12.02, 0.0056, 13.06, 0.0196, 14.05, 0.0160, 15.11, 0.0107, 16.11, 0.0003, 17.14, 0.0111, 18.21, 0.0085, 19.23, 0.0010, 20.28, 0.0048, 21.31, 0.0128, 22.36, 0.0051, 23.41, 0.0041, 24.05, 0.0006, 25.54, 0.0019, 26.62, 0.0028, 27.72, 0.0034, 28.82, 0.0062, 29.89, 0.0039, 30.98, 0.0058, 32.08, 0.0011, 33.21, 0.0002, 34.37, 0.0008, 35.46, 0.0018, 36.62, 0.0036, 37.77, 0.0018, 38.92, 0.0042, 40.07, 0.0037, 41.23, 0.0011, 42.67, 0.0003, 43.65, 0.0018, 44.68, 0.0025, 45.99, 0.0044, 47.21, 0.0051, 48.40, 0.0044, 49.67, 0.0005, 50.88, 0.0019, 52.15, 0.0003, 53.42, 0.0008, 54.69, 0.0010, 55.98, 0.0005, 57.26, 0.0013, 58.53, 0.0027, 59.83, 0.0011, 61.21, 0.0027, 62.54, 0.0003, 63.78, 0.0003, 65.20, 0.0001, 66.60, 0.0006, 67.98, 0.0008, 69.37, 0.0019, 70.73, 0.0007, 72.14, 0.0004, 73.62, 0.0002, 74.40, 0.0003, 76.52, 0.0006, 77.97, 0.0002, 79.49, 0.0004, 80.77, 0.0003, 81.00, 0.0001, 82.47, 0.0005, 83.97, 0.0001, 87.27, 0.0002] P_ds1 = [2.00, 0.0257, 2.99, 0.0142, 3.97, 0.0202, 4.95, 0.0148, 5.95, 0.0420, 6.95, 0.0037, 7.94, 0.0004, 8.94, 0.0172, 9.95, 0.0191, 10.96, 0.0115, 11.97, 0.0059, 12.98, 0.0140, 14.00, 0.0178, 15.03, 0.0121, 16.09, 0.0002, 17.07, 0.0066, 18.08, 0.0033, 19.15, 0.0022, 20.18, 0.0057, 21.22, 0.0077, 22.29, 0.0037, 23.33, 0.0066, 24.97, 0.0002, 25.49, 0.0019, 26.55, 0.0042, 27.61, 0.0043, 28.73, 0.0038, 29.81, 0.0084, 30.91, 0.0040, 32.03, 0.0025, 33.14, 0.0005, 34.26, 0.0003, 35.38, 0.0019, 36.56, 0.0037, 37.68, 0.0049, 38.86, 0.0036, 40.11, 0.0011, 41.28, 0.0008, 42.50, 0.0004, 43.60, 0.0002, 44.74, 0.0022, 45.99, 0.0050, 47.20, 0.0009, 48.40, 0.0036, 49.68, 0.0004, 50.92, 0.0009, 52.17, 0.0005, 53.46, 0.0007, 54.76, 0.0006, 56.06, 0.0005, 57.34, 0.0011, 58.67, 0.0005, 59.95, 0.0015, 61.37, 0.0008, 62.72, 0.0004, 65.42, 0.0009, 66.96, 0.0003, 68.18, 0.0003, 69.78, 0.0003, 71.21, 0.0004, 72.45, 0.0002, 74.22, 0.0003, 75.44, 0.0001, 76.53, 0.0003, 78.31, 0.0004, 79.83, 0.0003, 80.16, 0.0001, 81.33, 0.0003, 82.44, 0.0001, 83.17, 0.0002, 84.81, 0.0003, 85.97, 0.0003, 89.08, 0.0001, 90.70, 0.0002, 92.30, 0.0002, 95.59, 0.0002, 97.22, 0.0003, 98.86, 0.0001, 108.37, 0.0001, 125.54, 0.0001] P_e1 = [1.99, 0.0650, 3.03, 0.0040, 4.03, 0.0059, 5.02, 0.0090, 5.97, 0.0227, 6.98, 0.0050, 8.04, 0.0020, 9.00, 0.0082, 9.96, 0.0078, 11.01, 0.0056, 12.01, 0.0095, 13.02, 0.0050, 14.04, 0.0093, 15.08, 0.0064, 16.14, 0.0017, 17.06, 0.0020, 18.10, 0.0025, 19.14, 0.0023, 20.18, 0.0015, 21.24, 0.0032, 22.29, 0.0029, 23.32, 0.0014, 24.37, 0.0005, 25.43, 0.0030, 26.50, 0.0022, 27.60, 0.0027, 28.64, 0.0024, 29.76, 0.0035, 30.81, 0.0136, 31.96, 0.0025, 33.02, 0.0003, 34.13, 0.0005, 35.25, 0.0007, 36.40, 0.0014, 37.51, 0.0020, 38.64, 0.0012, 39.80, 0.0019, 40.97, 0.0004, 42.09, 0.0003, 43.24, 0.0003, 44.48, 0.0002, 45.65, 0.0024, 46.86, 0.0005, 48.07, 0.0013, 49.27, 0.0008, 50.49, 0.0006, 52.95, 0.0001, 54.23, 0.0005, 55.45, 0.0004, 56.73, 0.0001, 58.03, 0.0003, 59.29, 0.0002, 60.59, 0.0003, 62.04, 0.0002, 65.89, 0.0002, 67.23, 0.0002, 68.61, 0.0002, 69.97, 0.0004, 71.36, 0.0005, 85.42, 0.0001] P_f1 = [1.98, 0.0256, 2.96, 0.0158, 3.95, 0.0310, 4.94, 0.0411, 5.95, 0.0238, 6.94, 0.0152, 7.93, 0.0011, 8.95, 0.0185, 9.92, 0.0166, 10.93, 0.0306, 11.94, 0.0258, 12.96, 0.0202, 13.97, 0.0403, 14.95, 0.0228, 15.93, 0.0005, 17.01, 0.0072, 18.02, 0.0034, 19.06, 0.0028, 20.08, 0.0124, 21.13, 0.0137, 22.16, 0.0102, 23.19, 0.0058, 23.90, 0.0013, 25.30, 0.0039, 26.36, 0.0039, 27.41, 0.0025, 28.47, 0.0071, 29.64, 0.0031, 30.60, 0.0027, 31.71, 0.0021, 32.84, 0.0003, 33.82, 0.0002, 35.07, 0.0019, 36.09, 0.0054, 37.20, 0.0038, 38.33, 0.0024, 39.47, 0.0055, 40.55, 0.0016, 41.77, 0.0006, 42.95, 0.0002, 43.27, 0.0018, 44.03, 0.0006, 45.25, 0.0019, 46.36, 0.0033, 47.50, 0.0024, 48.87, 0.0012, 50.03, 0.0016, 51.09, 0.0004, 53.52, 0.0017, 54.74, 0.0012, 56.17, 0.0003, 57.40, 0.0011, 58.42, 0.0020, 59.70, 0.0007, 61.29, 0.0008, 62.56, 0.0003, 63.48, 0.0002, 64.83, 0.0002, 66.12, 0.0012, 67.46, 0.0017, 68.81, 0.0003, 69.13, 0.0003, 70.53, 0.0002, 71.84, 0.0001, 73.28, 0.0002, 75.52, 0.0010, 76.96, 0.0005, 77.93, 0.0003, 78.32, 0.0003, 79.73, 0.0003, 81.69, 0.0002, 82.52, 0.0001, 84.01, 0.0001, 84.61, 0.0002, 86.88, 0.0001, 88.36, 0.0002, 89.85, 0.0002, 91.35, 0.0003, 92.86, 0.0002, 93.40, 0.0001, 105.28, 0.0002, 106.22, 0.0002, 107.45, 0.0001, 108.70, 0.0003, 122.08, 0.0002] P_fs1 = [1.97, 0.0264, 2.97, 0.0211, 3.98, 0.0234, 4.98, 0.0307, 5.96, 0.0085, 6.94, 0.0140, 7.93, 0.0005, 8.96, 0.0112, 9.96, 0.0209, 10.98, 0.0194, 11.98, 0.0154, 12.99, 0.0274, 13.99, 0.0127, 15.01, 0.0101, 15.99, 0.0002, 17.04, 0.0011, 18.08, 0.0032, 19.14, 0.0028, 20.12, 0.0054, 21.20, 0.0053, 22.13, 0.0028, 23.22, 0.0030, 24.32, 0.0006, 25.24, 0.0004, 26.43, 0.0028, 27.53, 0.0048, 28.52, 0.0039, 29.54, 0.0047, 30.73, 0.0044, 31.82, 0.0007, 32.94, 0.0008, 34.04, 0.0012, 35.13, 0.0018, 36.29, 0.0007, 37.35, 0.0075, 38.51, 0.0045, 39.66, 0.0014, 40.90, 0.0004, 41.90, 0.0002, 43.08, 0.0002, 44.24, 0.0017, 45.36, 0.0013, 46.68, 0.0020, 47.79, 0.0015, 48.98, 0.0010, 50.21, 0.0012, 51.34, 0.0001, 53.82, 0.0003, 55.09, 0.0004, 56.23, 0.0005, 57.53, 0.0004, 58.79, 0.0005, 59.30, 0.0002, 60.03, 0.0002, 61.40, 0.0003, 62.84, 0.0001, 66.64, 0.0001, 67.97, 0.0001, 69.33, 0.0001, 70.68, 0.0001, 73.57, 0.0002, 75.76, 0.0002, 76.45, 0.0001, 79.27, 0.0001, 80.44, 0.0002, 81.87, 0.0002] P_g1 = [2.00, 0.0311, 2.99, 0.0086, 3.99, 0.0266, 4.97, 0.0123, 5.98, 0.0235, 6.97, 0.0161, 7.97, 0.0008, 8.96, 0.0088, 9.96, 0.0621, 10.99, 0.0080, 11.99, 0.0034, 12.99, 0.0300, 14.03, 0.0228, 15.04, 0.0105, 16.03, 0.0004, 17.06, 0.0036, 18.09, 0.0094, 18.95, 0.0009, 20.17, 0.0071, 21.21, 0.0161, 22.25, 0.0106, 23.28, 0.0104, 24.33, 0.0008, 25.38, 0.0030, 26.46, 0.0035, 27.50, 0.0026, 28.59, 0.0028, 29.66, 0.0128, 30.75, 0.0139, 31.81, 0.0038, 32.93, 0.0006, 34.04, 0.0004, 35.16, 0.0005, 36.25, 0.0023, 37.35, 0.0012, 38.46, 0.0021, 39.59, 0.0035, 40.71, 0.0006, 41.86, 0.0007, 42.42, 0.0001, 43.46, 0.0003, 44.17, 0.0032, 45.29, 0.0013, 46.57, 0.0004, 47.72, 0.0011, 48.79, 0.0005, 50.11, 0.0005, 51.29, 0.0003, 52.47, 0.0002, 53.68, 0.0004, 55.02, 0.0005, 56.18, 0.0003, 57.41, 0.0003, 58.75, 0.0007, 59.33, 0.0009, 60.00, 0.0004, 61.34, 0.0001, 64.97, 0.0003, 65.20, 0.0002, 66.48, 0.0002, 67.83, 0.0002, 68.90, 0.0003, 70.25, 0.0003, 71.59, 0.0002, 73.68, 0.0001, 75.92, 0.0001, 77.08, 0.0002, 78.45, 0.0002, 81.56, 0.0002, 82.99, 0.0001, 88.39, 0.0001] P_gs1 = [0.97, 0.0059, 1.98, 0.0212, 2.99, 0.0153, 3.99, 0.0227, 4.96, 0.0215, 5.97, 0.0153, 6.98, 0.0085, 7.98, 0.0007, 8.97, 0.0179, 9.98, 0.0512, 10.98, 0.0322, 12.00, 0.0098, 13.02, 0.0186, 14.00, 0.0099, 15.05, 0.0109, 15.88, 0.0011, 17.07, 0.0076, 18.11, 0.0071, 19.12, 0.0045, 20.16, 0.0038, 21.23, 0.0213, 22.27, 0.0332, 23.34, 0.0082, 24.34, 0.0014, 25.42, 0.0024, 26.47, 0.0012, 27.54, 0.0014, 28.60, 0.0024, 29.72, 0.0026, 30.10, 0.0008, 31.91, 0.0021, 32.13, 0.0011, 33.02, 0.0007, 34.09, 0.0014, 35.17, 0.0007, 36.27, 0.0024, 37.39, 0.0029, 38.58, 0.0014, 39.65, 0.0017, 40.95, 0.0012, 41.97, 0.0004, 42.43, 0.0002, 43.49, 0.0001, 44.31, 0.0012, 45.42, 0.0031, 46.62, 0.0017, 47.82, 0.0013, 49.14, 0.0013, 50.18, 0.0010, 51.54, 0.0003, 53.90, 0.0006, 55.06, 0.0010, 56.31, 0.0003, 57.63, 0.0001, 59.02, 0.0003, 60.09, 0.0004, 60.35, 0.0004, 61.62, 0.0009, 63.97, 0.0001, 65.19, 0.0001, 65.54, 0.0002, 66.92, 0.0002, 67.94, 0.0002, 69.17, 0.0003, 69.60, 0.0004, 70.88, 0.0002, 72.24, 0.0002, 76.12, 0.0001, 78.94, 0.0001, 81.75, 0.0001, 82.06, 0.0001, 83.53, 0.0001, 90.29, 0.0002, 91.75, 0.0001, 92.09, 0.0002, 93.28, 0.0001, 97.07, 0.0001] P_a1 = [1.98, 0.0159, 2.98, 0.1008, 3.98, 0.0365, 4.98, 0.0133, 5.97, 0.0101, 6.97, 0.0115, 7.97, 0.0007, 8.99, 0.0349, 10.01, 0.0342, 11.01, 0.0236, 12.00, 0.0041, 13.02, 0.0114, 14.05, 0.0137, 15.06, 0.0100, 16.05, 0.0007, 17.04, 0.0009, 18.12, 0.0077, 19.15, 0.0023, 20.12, 0.0017, 21.24, 0.0113, 22.26, 0.0126, 23.30, 0.0093, 24.36, 0.0007, 25.43, 0.0007, 26.47, 0.0009, 27.55, 0.0013, 28.59, 0.0025, 29.61, 0.0010, 30.77, 0.0021, 31.86, 0.0023, 32.96, 0.0003, 34.03, 0.0007, 35.06, 0.0005, 36.20, 0.0006, 37.34, 0.0006, 38.36, 0.0009, 39.60, 0.0016, 40.69, 0.0005, 41.77, 0.0002, 42.92, 0.0002, 44.02, 0.0003, 45.24, 0.0006, 46.33, 0.0004, 47.50, 0.0007, 48.71, 0.0007, 49.87, 0.0002, 51.27, 0.0002, 53.42, 0.0003, 55.88, 0.0003, 57.10, 0.0004, 58.34, 0.0002, 59.86, 0.0003, 61.13, 0.0003, 67.18, 0.0001, 68.50, 0.0001, 71.17, 0.0001, 83.91, 0.0001, 90.55, 0.0001] P_as1 = [0.98, 0.0099, 2.00, 0.0181, 2.99, 0.0353, 3.98, 0.0285, 4.97, 0.0514, 5.96, 0.0402, 6.96, 0.0015, 7.98, 0.0012, 8.98, 0.0175, 9.98, 0.0264, 10.98, 0.0392, 11.98, 0.0236, 13.00, 0.0153, 14.04, 0.0049, 15.00, 0.0089, 16.01, 0.0001, 17.03, 0.0106, 18.03, 0.0028, 19.05, 0.0024, 20.08, 0.0040, 21.11, 0.0103, 22.12, 0.0104, 23.20, 0.0017, 24.19, 0.0008, 25.20, 0.0007, 26.24, 0.0011, 27.36, 0.0009, 27.97, 0.0030, 29.40, 0.0044, 30.37, 0.0019, 31.59, 0.0017, 32.65, 0.0008, 33.59, 0.0005, 34.79, 0.0009, 35.75, 0.0027, 36.88, 0.0035, 37.93, 0.0039, 39.00, 0.0031, 40.08, 0.0025, 41.16, 0.0010, 43.25, 0.0004, 44.52, 0.0012, 45.62, 0.0023, 45.85, 0.0012, 47.00, 0.0006, 47.87, 0.0008, 48.99, 0.0003, 50.48, 0.0003, 51.62, 0.0001, 52.43, 0.0001, 53.56, 0.0002, 54.76, 0.0002, 56.04, 0.0002, 56.68, 0.0006, 57.10, 0.0003, 58.28, 0.0005, 59.47, 0.0003, 59.96, 0.0002, 60.67, 0.0001, 63.08, 0.0002, 64.29, 0.0002, 66.72, 0.0001, 67.97, 0.0001, 68.65, 0.0001, 70.43, 0.0001, 79.38, 0.0001, 80.39, 0.0001, 82.39, 0.0001] P_b1 = [1.00, 0.0765, 1.99, 0.0151, 2.99, 0.0500, 3.99, 0.0197, 5.00, 0.0260, 6.00, 0.0145, 6.98, 0.0128, 7.97, 0.0004, 8.98, 0.0158, 9.99, 0.0265, 11.02, 0.0290, 12.02, 0.0053, 13.03, 0.0242, 14.03, 0.0103, 15.06, 0.0054, 16.04, 0.0006, 17.08, 0.0008, 18.10, 0.0058, 19.16, 0.0011, 20.16, 0.0055, 21.18, 0.0040, 22.20, 0.0019, 23.22, 0.0014, 24.05, 0.0005, 25.31, 0.0019, 26.38, 0.0018, 27.44, 0.0022, 28.45, 0.0024, 29.57, 0.0073, 30.58, 0.0032, 31.66, 0.0071, 32.73, 0.0015, 33.85, 0.0005, 34.96, 0.0003, 36.00, 0.0020, 37.11, 0.0018, 38.18, 0.0055, 39.23, 0.0006, 40.33, 0.0004, 41.52, 0.0003, 43.41, 0.0028, 45.05, 0.0003, 45.99, 0.0002, 47.07, 0.0003, 48.52, 0.0002, 49.48, 0.0003, 50.63, 0.0003, 51.81, 0.0002, 54.05, 0.0002, 55.24, 0.0001, 56.62, 0.0001, 57.81, 0.0004, 59.16, 0.0013, 60.23, 0.0003, 66.44, 0.0001, 68.99, 0.0004, 75.49, 0.0001, 87.56, 0.0004] P_c2 = [0.98, 0.0629, 1.99, 0.0232, 2.98, 0.0217, 4.00, 0.0396, 4.98, 0.0171, 5.97, 0.0098, 6.99, 0.0167, 7.99, 0.0003, 8.98, 0.0192, 9.98, 0.0266, 10.99, 0.0256, 12.01, 0.0061, 13.02, 0.0135, 14.02, 0.0062, 15.05, 0.0158, 16.06, 0.0018, 17.08, 0.0101, 18.09, 0.0053, 19.11, 0.0074, 20.13, 0.0020, 21.17, 0.0052, 22.22, 0.0077, 23.24, 0.0035, 24.00, 0.0009, 25.32, 0.0016, 26.40, 0.0022, 27.43, 0.0005, 28.55, 0.0026, 29.60, 0.0026, 30.65, 0.0010, 31.67, 0.0019, 32.77, 0.0008, 33.81, 0.0003, 34.91, 0.0003, 36.01, 0.0005, 37.11, 0.0010, 38.20, 0.0014, 39.29, 0.0039, 40.43, 0.0012, 41.50, 0.0006, 43.38, 0.0017, 43.75, 0.0002, 44.94, 0.0005, 46.13, 0.0002, 47.11, 0.0003, 48.28, 0.0005, 48.42, 0.0005, 49.44, 0.0003, 50.76, 0.0004, 51.93, 0.0002, 54.15, 0.0003, 55.31, 0.0005, 55.50, 0.0003, 56.98, 0.0003, 57.90, 0.0004, 60.33, 0.0002, 61.39, 0.0001, 61.59, 0.0001, 65.09, 0.0002, 66.34, 0.0001, 68.85, 0.0001, 70.42, 0.0002, 71.72, 0.0001, 73.05, 0.0003, 79.65, 0.0001, 85.28, 0.0002, 93.52, 0.0001] P_cs2 = [1.02, 0.0185, 1.99, 0.0525, 2.98, 0.0613, 3.99, 0.0415, 4.98, 0.0109, 5.97, 0.0248, 6.99, 0.0102, 7.98, 0.0005, 8.98, 0.0124, 9.99, 0.0103, 10.99, 0.0124, 12.00, 0.0016, 13.01, 0.0029, 14.03, 0.0211, 15.04, 0.0128, 16.07, 0.0021, 17.09, 0.0009, 18.09, 0.0043, 19.14, 0.0022, 20.13, 0.0016, 21.20, 0.0045, 22.21, 0.0088, 23.26, 0.0046, 24.29, 0.0013, 25.35, 0.0009, 26.39, 0.0028, 27.49, 0.0009, 28.51, 0.0006, 29.58, 0.0012, 30.70, 0.0010, 31.74, 0.0019, 32.75, 0.0002, 33.85, 0.0001, 34.95, 0.0005, 36.02, 0.0003, 37.16, 0.0009, 38.25, 0.0018, 39.35, 0.0008, 40.54, 0.0004, 41.61, 0.0002, 43.40, 0.0004, 43.74, 0.0003, 45.05, 0.0001, 46.11, 0.0003, 47.40, 0.0002, 48.36, 0.0004, 49.55, 0.0004, 50.72, 0.0002, 52.00, 0.0001, 55.58, 0.0002, 57.02, 0.0001, 57.98, 0.0002, 59.13, 0.0003, 61.56, 0.0001, 66.56, 0.0001, 87.65, 0.0002] P_d2 = [1.00, 0.0473, 1.99, 0.0506, 2.99, 0.0982, 3.99, 0.0654, 5.00, 0.0196, 5.99, 0.0094, 6.99, 0.0118, 7.93, 0.0001, 8.99, 0.0057, 10.01, 0.0285, 11.01, 0.0142, 12.03, 0.0032, 13.03, 0.0056, 14.06, 0.0064, 15.06, 0.0059, 16.11, 0.0005, 17.09, 0.0033, 18.14, 0.0027, 19.15, 0.0014, 20.17, 0.0010, 21.21, 0.0059, 22.26, 0.0043, 23.31, 0.0031, 24.31, 0.0018, 25.33, 0.0009, 26.41, 0.0005, 27.47, 0.0015, 28.53, 0.0015, 29.58, 0.0041, 30.65, 0.0025, 31.73, 0.0011, 32.83, 0.0010, 34.98, 0.0003, 36.07, 0.0009, 37.23, 0.0001, 38.26, 0.0020, 39.41, 0.0014, 40.53, 0.0005, 41.40, 0.0003, 42.80, 0.0002, 43.48, 0.0028, 43.93, 0.0001, 45.03, 0.0003, 46.18, 0.0007, 47.41, 0.0001, 48.57, 0.0002, 49.67, 0.0001, 50.83, 0.0002, 54.39, 0.0001, 55.58, 0.0002, 57.97, 0.0005, 58.11, 0.0002, 59.21, 0.0001, 60.42, 0.0002, 61.66, 0.0001] P_ds2 = [1.00, 0.0503, 2.00, 0.0963, 2.99, 0.1304, 3.99, 0.0218, 4.98, 0.0041, 5.98, 0.0292, 6.98, 0.0482, 7.99, 0.0005, 8.99, 0.0280, 10.00, 0.0237, 11.00, 0.0152, 12.02, 0.0036, 12.95, 0.0022, 14.06, 0.0111, 15.07, 0.0196, 16.08, 0.0016, 17.11, 0.0044, 18.13, 0.0073, 19.17, 0.0055, 20.19, 0.0028, 21.20, 0.0012, 22.27, 0.0068, 23.30, 0.0036, 24.35, 0.0012, 25.35, 0.0002, 26.46, 0.0005, 27.47, 0.0005, 28.59, 0.0009, 29.65, 0.0021, 30.70, 0.0020, 31.78, 0.0012, 32.89, 0.0010, 35.06, 0.0005, 36.16, 0.0008, 37.27, 0.0010, 38.36, 0.0010, 39.47, 0.0014, 40.58, 0.0004, 41.43, 0.0007, 41.82, 0.0003, 43.48, 0.0008, 44.53, 0.0001, 45.25, 0.0003, 46.43, 0.0002, 47.46, 0.0002, 48.76, 0.0005, 49.95, 0.0004, 50.96, 0.0002, 51.12, 0.0002, 52.33, 0.0001, 54.75, 0.0001, 55.75, 0.0002, 56.90, 0.0002, 58.17, 0.0002, 59.40, 0.0004, 60.62, 0.0002, 65.65, 0.0001, 66.91, 0.0002, 69.91, 0.0001, 71.25, 0.0002] P_e2 = [1.00, 0.1243, 1.98, 0.1611, 3.00, 0.0698, 3.98, 0.0390, 5.00, 0.0138, 5.99, 0.0154, 7.01, 0.0287, 8.01, 0.0014, 9.01, 0.0049, 10.00, 0.0144, 11.01, 0.0055, 12.05, 0.0052, 13.01, 0.0011, 14.05, 0.0118, 15.07, 0.0154, 16.12, 0.0028, 17.14, 0.0061, 18.25, 0.0007, 19.22, 0.0020, 20.24, 0.0011, 21.27, 0.0029, 22.30, 0.0046, 23.34, 0.0049, 24.35, 0.0004, 25.45, 0.0003, 26.47, 0.0007, 27.59, 0.0008, 28.16, 0.0009, 29.12, 0.0002, 29.81, 0.0006, 30.81, 0.0009, 31.95, 0.0004, 33.00, 0.0011, 34.12, 0.0005, 35.18, 0.0003, 36.30, 0.0008, 37.38, 0.0003, 38.55, 0.0003, 39.64, 0.0006, 40.77, 0.0007, 41.52, 0.0006, 41.89, 0.0006, 43.04, 0.0011, 43.60, 0.0009, 44.31, 0.0002, 45.68, 0.0002, 46.56, 0.0003, 47.60, 0.0001, 48.83, 0.0006, 50.01, 0.0003, 51.27, 0.0003, 56.04, 0.0005, 57.21, 0.0003, 58.56, 0.0004, 59.83, 0.0003, 61.05, 0.0001, 62.20, 0.0001, 67.37, 0.0002, 76.53, 0.0001] P_f2 = [0.99, 0.0222, 1.99, 0.0678, 2.99, 0.0683, 4.00, 0.0191, 5.00, 0.0119, 6.01, 0.0232, 6.98, 0.0336, 7.99, 0.0082, 9.01, 0.0201, 10.01, 0.0189, 11.01, 0.0041, 12.01, 0.0053, 13.05, 0.0154, 14.04, 0.0159, 15.06, 0.0092, 16.11, 0.0038, 17.12, 0.0014, 18.15, 0.0091, 19.16, 0.0006, 20.30, 0.0012, 21.25, 0.0061, 22.28, 0.0099, 23.34, 0.0028, 24.38, 0.0012, 25.43, 0.0016, 26.49, 0.0048, 27.55, 0.0025, 28.62, 0.0015, 29.71, 0.0032, 30.78, 0.0077, 31.88, 0.0011, 32.97, 0.0007, 34.08, 0.0006, 35.16, 0.0008, 36.28, 0.0004, 37.41, 0.0006, 38.54, 0.0005, 39.62, 0.0002, 40.80, 0.0003, 41.93, 0.0001, 43.06, 0.0002, 44.21, 0.0003, 45.38, 0.0002, 46.54, 0.0007, 47.78, 0.0003, 48.95, 0.0004, 50.10, 0.0003, 51.37, 0.0002, 53.79, 0.0003, 56.20, 0.0001, 58.71, 0.0002, 66.47, 0.0003] P_fs2 = [1.01, 0.0241, 1.99, 0.1011, 2.98, 0.0938, 3.98, 0.0081, 4.99, 0.0062, 5.99, 0.0291, 6.99, 0.0676, 7.59, 0.0004, 8.98, 0.0127, 9.99, 0.0112, 10.99, 0.0142, 12.00, 0.0029, 13.02, 0.0071, 14.02, 0.0184, 15.03, 0.0064, 16.07, 0.0010, 17.09, 0.0011, 18.11, 0.0010, 19.15, 0.0060, 20.19, 0.0019, 21.24, 0.0025, 22.29, 0.0013, 23.31, 0.0050, 25.41, 0.0030, 26.50, 0.0018, 27.53, 0.0006, 28.63, 0.0012, 29.66, 0.0013, 30.77, 0.0020, 31.84, 0.0006, 34.04, 0.0001, 35.14, 0.0001, 36.32, 0.0004, 37.41, 0.0007, 38.53, 0.0007, 39.67, 0.0009, 40.85, 0.0003, 45.49, 0.0002, 46.65, 0.0001, 47.81, 0.0004, 49.01, 0.0002, 53.91, 0.0002, 55.14, 0.0002, 57.69, 0.0002] P_g2 = [1.00, 0.0326, 2.00, 0.1066, 2.99, 0.1015, 4.00, 0.0210, 4.97, 0.0170, 5.99, 0.0813, 6.98, 0.0820, 7.96, 0.0011, 8.99, 0.0248, 10.03, 0.0107, 11.01, 0.0126, 12.01, 0.0027, 13.01, 0.0233, 14.04, 0.0151, 15.05, 0.0071, 16.04, 0.0002, 17.10, 0.0061, 18.12, 0.0059, 19.15, 0.0087, 20.23, 0.0005, 21.25, 0.0040, 22.30, 0.0032, 23.35, 0.0004, 24.40, 0.0001, 25.45, 0.0030, 26.54, 0.0022, 27.60, 0.0003, 28.70, 0.0009, 29.80, 0.0029, 30.85, 0.0006, 31.97, 0.0006, 34.19, 0.0004, 35.30, 0.0003, 36.43, 0.0007, 37.56, 0.0005, 38.68, 0.0019, 39.88, 0.0013, 41.00, 0.0003, 43.35, 0.0003, 44.51, 0.0002, 45.68, 0.0006, 46.93, 0.0010, 48.11, 0.0006, 49.29, 0.0003, 55.58, 0.0002] P_gs2 = [0.98, 0.0113, 1.99, 0.0967, 3.00, 0.0719, 3.98, 0.0345, 4.98, 0.0121, 6.00, 0.0621, 7.00, 0.0137, 7.98, 0.0006, 9.01, 0.0314, 10.01, 0.0171, 11.02, 0.0060, 12.03, 0.0024, 13.05, 0.0077, 14.07, 0.0040, 15.12, 0.0032, 16.13, 0.0004, 17.15, 0.0011, 18.20, 0.0028, 19.18, 0.0003, 20.26, 0.0003, 21.31, 0.0025, 22.35, 0.0021, 23.39, 0.0005, 25.55, 0.0002, 26.62, 0.0014, 27.70, 0.0003, 28.78, 0.0005, 29.90, 0.0030, 31.01, 0.0011, 32.12, 0.0005, 34.31, 0.0001, 35.50, 0.0002, 36.62, 0.0002, 37.76, 0.0005, 38.85, 0.0002, 40.09, 0.0004, 43.60, 0.0001, 44.73, 0.0002, 46.02, 0.0002, 47.25, 0.0004, 48.44, 0.0004] P_a2 = [0.99, 0.0156, 1.98, 0.0846, 2.98, 0.0178, 3.98, 0.0367, 4.98, 0.0448, 5.98, 0.0113, 6.99, 0.0189, 8.00, 0.0011, 9.01, 0.0247, 10.02, 0.0089, 11.01, 0.0184, 12.03, 0.0105, 13.00, 0.0039, 14.07, 0.0116, 15.09, 0.0078, 16.13, 0.0008, 17.14, 0.0064, 18.19, 0.0029, 19.22, 0.0028, 20.25, 0.0017, 21.32, 0.0043, 22.37, 0.0055, 23.42, 0.0034, 24.48, 0.0004, 25.54, 0.0002, 26.61, 0.0017, 27.70, 0.0011, 28.80, 0.0002, 29.89, 0.0019, 30.97, 0.0028, 32.09, 0.0007, 34.30, 0.0002, 35.44, 0.0003, 36.55, 0.0001, 37.69, 0.0004, 38.93, 0.0002, 40.05, 0.0005, 41.20, 0.0005, 42.37, 0.0002, 43.54, 0.0003, 44.73, 0.0001, 45.95, 0.0002, 47.16, 0.0001, 48.43, 0.0005, 49.65, 0.0004, 55.90, 0.0002, 59.81, 0.0004] P_as2 = [1.01, 0.0280, 2.00, 0.0708, 2.99, 0.0182, 3.99, 0.0248, 4.98, 0.0245, 5.98, 0.0279, 6.98, 0.0437, 7.99, 0.0065, 8.99, 0.0299, 10.00, 0.0073, 10.99, 0.0011, 12.03, 0.0122, 13.03, 0.0028, 14.08, 0.0044, 15.11, 0.0097, 16.15, 0.0010, 17.17, 0.0025, 18.19, 0.0017, 19.24, 0.0008, 20.28, 0.0040, 21.32, 0.0024, 22.38, 0.0008, 23.46, 0.0032, 24.52, 0.0010, 25.59, 0.0008, 26.68, 0.0009, 27.76, 0.0012, 28.88, 0.0003, 29.95, 0.0005, 31.05, 0.0017, 32.14, 0.0002, 33.29, 0.0003, 37.88, 0.0002, 39.03, 0.0002, 40.19, 0.0004, 41.37, 0.0003, 43.74, 0.0002, 46.20, 0.0001, 48.68, 0.0001, 49.93, 0.0001, 51.19, 0.0002] P_b2 = [1.00, 0.0225, 1.99, 0.0921, 2.98, 0.0933, 3.99, 0.0365, 4.99, 0.0100, 5.98, 0.0213, 6.98, 0.0049, 7.98, 0.0041, 8.98, 0.0090, 9.99, 0.0068, 11.01, 0.0040, 12.03, 0.0086, 13.02, 0.0015, 14.04, 0.0071, 15.09, 0.0082, 16.14, 0.0011, 17.15, 0.0014, 18.18, 0.0010, 19.26, 0.0013, 20.26, 0.0005, 21.33, 0.0006, 22.36, 0.0011, 23.46, 0.0016, 24.52, 0.0004, 25.59, 0.0002, 26.70, 0.0006, 27.78, 0.0007, 28.87, 0.0002, 30.03, 0.0008, 31.14, 0.0010, 32.24, 0.0006, 33.37, 0.0002, 35.67, 0.0003, 37.99, 0.0004, 39.17, 0.0004, 40.35, 0.0005, 41.53, 0.0001, 46.42, 0.0001] P_c3 = [1.00, 0.0465, 1.99, 0.0976, 2.98, 0.0678, 4.00, 0.0727, 4.99, 0.0305, 5.98, 0.0210, 6.98, 0.0227, 8.00, 0.0085, 9.01, 0.0183, 10.02, 0.0258, 11.05, 0.0003, 12.06, 0.0061, 13.05, 0.0021, 14.10, 0.0089, 15.12, 0.0077, 16.16, 0.0016, 17.21, 0.0061, 18.23, 0.0011, 19.29, 0.0031, 20.36, 0.0031, 21.41, 0.0007, 22.48, 0.0013, 23.55, 0.0020, 24.64, 0.0004, 25.74, 0.0005, 26.81, 0.0006, 27.95, 0.0006, 29.03, 0.0001, 30.22, 0.0010, 31.30, 0.0004, 32.48, 0.0001, 33.60, 0.0002, 38.30, 0.0003] P_cs3 = [1.00, 0.0674, 1.99, 0.0841, 2.98, 0.0920, 3.99, 0.0328, 4.99, 0.0368, 5.98, 0.0206, 6.99, 0.0246, 8.01, 0.0048, 9.01, 0.0218, 10.03, 0.0155, 11.05, 0.0048, 12.06, 0.0077, 13.00, 0.0020, 14.10, 0.0083, 15.15, 0.0084, 16.18, 0.0015, 17.22, 0.0039, 18.27, 0.0032, 19.34, 0.0026, 20.40, 0.0012, 21.47, 0.0009, 22.54, 0.0008, 23.62, 0.0016, 24.71, 0.0005, 25.82, 0.0004, 26.91, 0.0002, 28.03, 0.0008, 29.17, 0.0002, 30.32, 0.0028, 31.45, 0.0004, 32.61, 0.0005, 33.77, 0.0001, 36.14, 0.0003, 37.32, 0.0002, 38.54, 0.0005, 39.75, 0.0002, 42.23, 0.0002, 48.65, 0.0001] P_d3 = [1.01, 0.0423, 1.99, 0.0240, 2.98, 0.0517, 4.00, 0.0493, 5.00, 0.0324, 6.00, 0.0094, 6.99, 0.0449, 7.99, 0.0050, 9.00, 0.0197, 10.03, 0.0132, 11.03, 0.0009, 12.07, 0.0017, 13.08, 0.0023, 14.12, 0.0094, 15.16, 0.0071, 16.21, 0.0020, 17.25, 0.0005, 18.30, 0.0027, 19.04, 0.0004, 20.43, 0.0022, 21.51, 0.0002, 22.59, 0.0006, 23.72, 0.0018, 24.80, 0.0002, 25.88, 0.0002, 27.03, 0.0002, 28.09, 0.0006, 29.31, 0.0002, 30.46, 0.0004, 31.61, 0.0007, 32.78, 0.0005, 33.95, 0.0001, 36.34, 0.0002, 37.56, 0.0001, 38.80, 0.0001, 40.02, 0.0001, 44.14, 0.0001] P_ds3 = [1.00, 0.0669, 1.99, 0.0909, 2.99, 0.0410, 3.98, 0.0292, 4.98, 0.0259, 5.98, 0.0148, 6.98, 0.0319, 7.99, 0.0076, 9.01, 0.0056, 10.02, 0.0206, 11.04, 0.0032, 12.05, 0.0085, 13.08, 0.0040, 14.12, 0.0037, 15.16, 0.0030, 16.20, 0.0013, 17.24, 0.0021, 18.30, 0.0010, 19.36, 0.0015, 20.44, 0.0013, 21.50, 0.0009, 22.60, 0.0015, 23.69, 0.0014, 24.80, 0.0006, 25.87, 0.0002, 27.02, 0.0006, 28.12, 0.0002, 29.28, 0.0003, 30.43, 0.0002, 31.59, 0.0007, 32.79, 0.0001, 35.14, 0.0001, 37.57, 0.0001, 40.03, 0.0002, 41.28, 0.0004, 44.10, 0.0001] P_e3 = [0.99, 0.0421, 1.99, 0.1541, 2.98, 0.0596, 3.98, 0.0309, 4.98, 0.0301, 5.99, 0.0103, 7.00, 0.0240, 8.01, 0.0073, 9.01, 0.0222, 10.04, 0.0140, 11.05, 0.0033, 12.08, 0.0045, 13.13, 0.0009, 14.13, 0.0015, 15.21, 0.0026, 16.24, 0.0003, 17.30, 0.0004, 18.35, 0.0010, 19.39, 0.0003, 20.50, 0.0015, 21.57, 0.0003, 22.68, 0.0011, 23.80, 0.0005, 24.90, 0.0008, 26.02, 0.0002, 27.16, 0.0001, 28.30, 0.0006, 29.48, 0.0002, 31.81, 0.0005, 33.00, 0.0003, 34.21, 0.0001, 37.89, 0.0001] P_f3 = [0.99, 0.0389, 2.00, 0.2095, 3.00, 0.0835, 3.99, 0.0289, 5.00, 0.0578, 5.99, 0.0363, 7.01, 0.0387, 8.01, 0.0056, 9.04, 0.0173, 10.05, 0.0175, 11.08, 0.0053, 12.10, 0.0056, 13.15, 0.0064, 14.19, 0.0036, 15.22, 0.0019, 16.29, 0.0010, 17.36, 0.0017, 18.43, 0.0018, 19.51, 0.0004, 20.60, 0.0011, 21.70, 0.0003, 22.82, 0.0003, 23.95, 0.0001, 25.05, 0.0004, 26.17, 0.0001, 28.50, 0.0003, 29.68, 0.0001, 32.07, 0.0003, 33.28, 0.0004, 34.52, 0.0001] P_fs3 = [1.00, 0.1238, 1.99, 0.2270, 3.00, 0.0102, 3.99, 0.0181, 4.98, 0.0415, 6.00, 0.0165, 7.01, 0.0314, 8.02, 0.0148, 9.04, 0.0203, 10.05, 0.0088, 11.07, 0.0062, 12.11, 0.0070, 13.14, 0.0054, 14.19, 0.0028, 15.24, 0.0044, 16.30, 0.0029, 17.38, 0.0009, 18.45, 0.0026, 19.56, 0.0003, 20.65, 0.0025, 21.74, 0.0014, 22.87, 0.0013, 23.99, 0.0007, 25.15, 0.0002, 27.46, 0.0004, 28.39, 0.0006, 28.65, 0.0004, 29.85, 0.0001, 31.05, 0.0002, 32.27, 0.0003, 33.52, 0.0002, 34.76, 0.0003] P_g3 = [1.00, 0.1054, 2.00, 0.2598, 2.99, 0.0369, 3.98, 0.0523, 4.99, 0.0020, 5.99, 0.0051, 7.00, 0.0268, 8.01, 0.0027, 9.04, 0.0029, 10.05, 0.0081, 11.08, 0.0047, 12.12, 0.0051, 13.16, 0.0091, 14.19, 0.0015, 15.27, 0.0030, 16.34, 0.0017, 17.42, 0.0006, 18.51, 0.0003, 19.61, 0.0007, 20.72, 0.0003, 21.84, 0.0001, 22.99, 0.0010, 24.13, 0.0001, 28.44, 0.0001, 30.09, 0.0001] P_gs3 = [0.99, 0.0919, 2.00, 0.0418, 2.99, 0.0498, 3.99, 0.0135, 4.99, 0.0026, 6.00, 0.0155, 7.01, 0.0340, 8.02, 0.0033, 9.04, 0.0218, 10.08, 0.0084, 11.11, 0.0057, 12.15, 0.0051, 13.21, 0.0043, 14.25, 0.0015, 15.31, 0.0023, 16.40, 0.0008, 17.48, 0.0004, 18.59, 0.0016, 19.71, 0.0010, 20.84, 0.0018, 21.98, 0.0002, 23.11, 0.0013, 24.26, 0.0003, 26.67, 0.0002, 29.12, 0.0002, 30.37, 0.0002, 31.62, 0.0003, 32.92, 0.0001] P_a3 = [0.99, 0.1174, 1.99, 0.1126, 2.99, 0.0370, 3.99, 0.0159, 5.01, 0.0472, 6.01, 0.0091, 7.03, 0.0211, 8.05, 0.0015, 9.07, 0.0098, 10.11, 0.0038, 11.15, 0.0042, 12.20, 0.0018, 13.24, 0.0041, 14.32, 0.0033, 15.41, 0.0052, 16.49, 0.0001, 17.61, 0.0004, 18.71, 0.0004, 19.84, 0.0004, 20.99, 0.0002, 22.14, 0.0006, 23.31, 0.0006, 24.50, 0.0004, 25.70, 0.0002, 28.09, 0.0002, 28.66, 0.0002, 32.00, 0.0001] P_as3 = [1.00, 0.1085, 2.00, 0.1400, 2.99, 0.0173, 3.99, 0.0229, 5.00, 0.0272, 6.02, 0.0077, 7.03, 0.0069, 8.04, 0.0017, 9.08, 0.0045, 10.10, 0.0030, 11.15, 0.0040, 12.20, 0.0007, 13.25, 0.0019, 14.32, 0.0008, 15.42, 0.0024, 16.50, 0.0002, 17.59, 0.0005, 18.71, 0.0003, 19.83, 0.0002, 20.98, 0.0005, 23.29, 0.0008] P_b3 = [1.00, 0.0985, 2.00, 0.1440, 2.99, 0.0364, 3.99, 0.0425, 5.00, 0.0190, 6.01, 0.0089, 7.03, 0.0278, 8.04, 0.0006, 9.07, 0.0083, 10.10, 0.0021, 11.14, 0.0050, 12.18, 0.0005, 13.26, 0.0036, 14.33, 0.0005, 15.41, 0.0026, 17.62, 0.0004, 18.75, 0.0004, 19.89, 0.0003, 21.04, 0.0012, 22.21, 0.0002, 23.38, 0.0004, 27.04, 0.0001] P_c4 = [0.99, 0.1273, 2.00, 0.1311, 2.99, 0.0120, 4.00, 0.0099, 5.00, 0.0235, 6.02, 0.0068, 7.03, 0.0162, 8.06, 0.0009, 9.08, 0.0083, 10.12, 0.0014, 11.17, 0.0050, 12.24, 0.0010, 13.29, 0.0013, 14.39, 0.0022, 15.48, 0.0011, 16.59, 0.0002, 17.70, 0.0003, 18.84, 0.0010, 20.00, 0.0003, 21.17, 0.0003, 23.56, 0.0004, 28.79, 0.0003] P_cs4 = [1.00, 0.1018, 2.00, 0.1486, 3.00, 0.0165, 4.00, 0.0186, 5.01, 0.0194, 6.02, 0.0045, 7.04, 0.0083, 8.06, 0.0012, 9.10, 0.0066, 10.15, 0.0009, 11.19, 0.0008, 12.26, 0.0011, 13.34, 0.0028, 14.45, 0.0006, 15.53, 0.0009, 16.66, 0.0002, 17.79, 0.0006, 18.94, 0.0005, 20.11, 0.0003, 21.29, 0.0005, 22.49, 0.0003, 23.73, 0.0005, 26.22, 0.0001, 27.52, 0.0001, 28.88, 0.0002] P_d4 = [1.00, 0.1889, 1.99, 0.1822, 3.00, 0.0363, 4.00, 0.0047, 5.01, 0.0202, 6.03, 0.0053, 7.05, 0.0114, 8.01, 0.0002, 9.13, 0.0048, 10.17, 0.0010, 11.23, 0.0033, 12.30, 0.0010, 13.38, 0.0006, 14.50, 0.0002, 15.62, 0.0010, 20.27, 0.0001, 21.47, 0.0001] P_ds4 = [1.00, 0.0522, 1.99, 0.0763, 2.99, 0.0404, 4.00, 0.0139, 5.01, 0.0185, 6.01, 0.0021, 7.06, 0.0045, 8.09, 0.0002, 9.11, 0.0003, 10.17, 0.0006, 11.25, 0.0004, 12.32, 0.0005, 13.40, 0.0003, 14.53, 0.0003, 15.65, 0.0007, 16.80, 0.0001, 17.95, 0.0002, 19.14, 0.0006, 20.34, 0.0002, 21.56, 0.0003] P_e4 = [0.99, 0.1821, 1.99, 0.0773, 3.00, 0.0125, 4.01, 0.0065, 5.01, 0.0202, 6.03, 0.0071, 7.05, 0.0090, 8.08, 0.0006, 9.13, 0.0008, 10.18, 0.0013, 11.25, 0.0010, 12.33, 0.0012, 13.42, 0.0006, 14.54, 0.0005, 15.65, 0.0004, 17.97, 0.0002, 19.15, 0.0001] P_f4 = [1.00, 0.1868, 2.00, 0.0951, 3.00, 0.0147, 4.01, 0.0134, 5.02, 0.0184, 6.04, 0.0132, 7.06, 0.0011, 8.11, 0.0008, 9.15, 0.0010, 10.22, 0.0012, 11.30, 0.0011, 12.40, 0.0003, 13.11, 0.0004, 13.49, 0.0002, 14.62, 0.0003, 15.77, 0.0001] P_fs4 = [1.00, 0.1933, 2.00, 0.0714, 3.00, 0.0373, 4.00, 0.0108, 5.02, 0.0094, 6.02, 0.0010, 7.07, 0.0022, 8.11, 0.0002, 9.16, 0.0065, 10.23, 0.0015, 11.31, 0.0023, 12.40, 0.0003, 13.53, 0.0014, 14.66, 0.0002, 15.81, 0.0011, 18.20, 0.0002, 19.41, 0.0001] P_g4 = [0.99, 0.2113, 1.99, 0.0877, 3.00, 0.0492, 4.01, 0.0094, 5.02, 0.0144, 6.04, 0.0103, 7.07, 0.0117, 8.12, 0.0006, 9.19, 0.0019, 10.25, 0.0007, 11.35, 0.0017, 12.45, 0.0010, 13.58, 0.0003, 14.74, 0.0003, 15.91, 0.0003, 19.57, 0.0002] P_gs4 = [0.99, 0.2455, 1.99, 0.0161, 3.00, 0.0215, 4.01, 0.0036, 5.03, 0.0049, 6.04, 0.0012, 7.09, 0.0036, 8.14, 0.0011, 9.21, 0.0009, 10.30, 0.0001, 11.40, 0.0012, 12.50, 0.0001, 13.66, 0.0005, 14.84, 0.0001] P_a4 = [1.00, 0.1132, 2.00, 0.0252, 3.00, 0.0292, 4.01, 0.0136, 5.03, 0.0045, 6.06, 0.0022, 7.11, 0.0101, 8.17, 0.0004, 9.23, 0.0010, 10.33, 0.0012, 11.44, 0.0013, 12.58, 0.0011, 13.75, 0.0002, 14.93, 0.0005, 16.14, 0.0002] P_as4 = [1.00, 0.1655, 2.00, 0.0445, 3.00, 0.0120, 4.00, 0.0038, 5.02, 0.0015, 6.07, 0.0038, 7.11, 0.0003, 8.19, 0.0002, 9.25, 0.0010, 10.36, 0.0011, 11.48, 0.0005, 12.63, 0.0002, 13.79, 0.0003, 16.24, 0.0002] P_b4 = [0.99, 0.3637, 1.99, 0.0259, 3.01, 0.0038, 4.01, 0.0057, 5.03, 0.0040, 6.07, 0.0067, 7.12, 0.0014, 8.19, 0.0004, 9.27, 0.0003, 10.38, 0.0002, 12.67, 0.0001] P_c5 = [1.00, 0.1193, 2.00, 0.0230, 3.00, 0.0104, 4.01, 0.0084, 5.04, 0.0047, 6.08, 0.0035, 7.13, 0.0041, 8.20, 0.0002, 9.29, 0.0005, 10.40, 0.0005, 11.53, 0.0003, 12.70, 0.0002, 13.91, 0.0002] P_cs5 = [1.00, 0.0752, 2.00, 0.0497, 3.00, 0.0074, 4.02, 0.0076, 5.05, 0.0053, 6.09, 0.0043, 7.15, 0.0024, 8.22, 0.0001, 9.32, 0.0006, 10.45, 0.0002, 11.58, 0.0001, 12.78, 0.0001, 15.22, 0.0001] P_d5 = [1.00, 0.2388, 2.00, 0.0629, 3.01, 0.0159, 4.04, 0.0063, 5.07, 0.0051, 6.12, 0.0045, 7.19, 0.0026, 8.29, 0.0015, 9.43, 0.0001, 11.75, 0.0002] P_ds5 = [1.00, 0.1919, 2.01, 0.0116, 3.01, 0.0031, 4.03, 0.0090, 5.07, 0.0061, 6.13, 0.0036, 7.19, 0.0013, 8.30, 0.0016, 9.13, 0.0001, 10.59, 0.0002, 11.78, 0.0002] P_e5 = [1.00, 0.1296, 2.00, 0.0135, 3.01, 0.0041, 4.04, 0.0045, 5.09, 0.0028, 6.14, 0.0046, 7.23, 0.0007, 8.32, 0.0007, 9.50, 0.0001] P_f5 = [1.00, 0.0692, 2.00, 0.0209, 3.02, 0.0025, 4.05, 0.0030, 5.09, 0.0047, 6.17, 0.0022, 7.25, 0.0015, 8.36, 0.0015, 9.53, 0.0010, 10.69, 0.0001, 13.40, 0.0001] P_fs5 = [1.00, 0.1715, 2.00, 0.0142, 3.01, 0.0024, 4.03, 0.0015, 5.07, 0.0017, 6.13, 0.0018, 7.22, 0.0009, 8.33, 0.0014, 9.51, 0.0007, 10.69, 0.0002] P_g5 = [1.00, 0.1555, 2.01, 0.0148, 3.02, 0.0007, 4.06, 0.0006, 5.10, 0.0005, 6.16, 0.0008, 7.26, 0.0009, 8.39, 0.0008, 9.58, 0.0002] P_gs5 = [1.00, 0.1357, 2.00, 0.0116, 3.02, 0.0026, 4.04, 0.0009, 5.09, 0.0004, 6.17, 0.0005, 7.27, 0.0002, 8.40, 0.0001] P_a5 = [1.00, 0.2185, 2.01, 0.0087, 3.03, 0.0018, 4.06, 0.0025, 5.11, 0.0020, 6.20, 0.0012, 7.32, 0.0005, 8.46, 0.0001, 9.66, 0.0003] P_as5 = [1.00, 0.2735, 2.00, 0.0038, 3.02, 0.0008, 4.06, 0.0012, 5.12, 0.0008, 6.22, 0.0011, 7.35, 0.0003, 8.50, 0.0002] P_b5 = [1.00, 0.1441, 1.99, 0.0062, 3.01, 0.0023, 4.05, 0.0011, 5.11, 0.0012, 6.20, 0.0003, 7.33, 0.0004, 8.50, 0.0001] P_c6 = [1.00, 0.0726, 2.01, 0.0293, 3.03, 0.0022, 5.14, 0.0005, 6.26, 0.0011, 7.41, 0.0002, 8.63, 0.0002] P_cs6 = [1.00, 0.0516, 2.00, 0.0104, 3.02, 0.0029, 5.15, 0.0002, 6.27, 0.0001] P_d6 = [1.00, 0.0329, 2.00, 0.0033, 3.03, 0.0013, 4.10, 0.0005, 5.19, 0.0004, 6.32, 0.0002] P_ds6 = [1.00, 0.0179, 1.99, 0.0012, 3.04, 0.0005, 4.10, 0.0017, 5.20, 0.0005, 6.35, 0.0001] P_e6 = [1.00, 0.0334, 2.01, 0.0033, 3.04, 0.0011, 4.13, 0.0003, 5.22, 0.0003] P_f6 = [0.99, 0.0161, 2.01, 0.0100, 3.04, 0.0020, 4.13, 0.0003] P_fs6 = [1.00, 0.0475, 1.99, 0.0045, 3.03, 0.0035, 4.12, 0.0011] P_g6 = [1.00, 0.0593, 2.00, 0.0014, 4.17, 0.0002] P_gs6 = [1.00, 0.0249, 2.01, 0.0016] P_a6 = [1.00, 0.0242, 2.00, 0.0038, 4.19, 0.0002] P_as6 = [1.00, 0.0170, 2.02, 0.0030] P_b6 = [1.00, 0.0381, 2.00, 0.0017, 3.09, 0.0002] P_c7 = [1.00, 0.0141, 2.03, 0.0005, 3.11, 0.0003, 4.26, 0.0001] P_cs7 = [1.00, 0.0122, 2.03, 0.0024] P_d7 = [1.00, 0.0107, 2.07, 0.0007, 3.12, 0.0004] P_ds7 = [1.00, 0.0250, 2.02, 0.0026, 3.15, 0.0002] P_e7 = [1.01, 0.0092] P_f7 = [1.01, 0.0102, 2.09, 0.0005] P_fs7 = [1.00, 0.0080, 2.00, 0.0005, 3.19, 0.0001] P_g7 = [1.01, 0.0298, 2.01, 0.0005] # # # # # sax Sax_cs3 = [1.01, 0.0565, 2.01, 0.0374, 3.00, 0.0377, 4.00, 0.0498, 5.02, 0.0907, 6.02, 0.0361, 7.02, 0.0250, 8.01, 0.0036, 9.02, 0.0181, 10.03, 0.0319, 11.03, 0.0075, 12.03, 0.0068, 13.03, 0.0037, 14.03, 0.0015, 15.05, 0.0021, 16.04, 0.0034, 17.04, 0.0076, 18.04, 0.0101, 19.06, 0.0056, 20.06, 0.0051, 21.05, 0.0046, 22.05, 0.0029, 23.05, 0.0015, 24.07, 0.0026, 25.07, 0.0023, 26.06, 0.0025, 27.06, 0.0010, 28.08, 0.0011, 29.08, 0.0005, 30.07, 0.0017, 31.07, 0.0025, 32.07, 0.0032, 33.09, 0.0026, 34.09, 0.0023, 35.09, 0.0038, 36.09, 0.0023, 37.09, 0.0018, 38.11, 0.0023, 39.11, 0.0017, 40.10, 0.0015, 41.10, 0.0010, 42.10, 0.0008, 43.13, 0.0004, 45.13, 0.0001, 46.11, 0.0005, 47.12, 0.0004, 48.12, 0.0006, 49.11, 0.0004, 50.12, 0.0008, 51.13, 0.0006, 52.14, 0.0009, 53.13, 0.0006, 54.13, 0.0008, 55.13, 0.0007, 56.15, 0.0005, 57.16, 0.0002, 58.13, 0.0001, 59.17, 0.0001, 61.15, 0.0001, 62.15, 0.0002, 63.16, 0.0002, 65.17, 0.0004, 66.18, 0.0005, 67.18, 0.0003, 68.17, 0.0002, 69.17, 0.0005, 70.18, 0.0003, 71.18, 0.0002, 72.18, 0.0005, 73.18, 0.0003, 74.18, 0.0003, 75.20, 0.0003, 76.19, 0.0003, 77.19, 0.0002, 78.19, 0.0004, 80.20, 0.0002, 81.19, 0.0001, 82.21, 0.0001, 89.23, 0.0002, 90.23, 0.0002, 91.23, 0.0003, 92.22, 0.0001] Sax_d3 = [1.00, 0.0423, 1.99, 0.0487, 2.98, 0.0259, 3.99, 0.0630, 4.99, 0.1026, 5.97, 0.0532, 6.97, 0.0259, 7.98, 0.0110, 8.97, 0.0076, 9.96, 0.0123, 10.97, 0.0162, 11.96, 0.0128, 12.95, 0.0178, 13.94, 0.0114, 14.96, 0.0134, 15.95, 0.0186, 16.94, 0.0180, 17.93, 0.0087, 18.94, 0.0084, 19.93, 0.0064, 20.92, 0.0033, 21.93, 0.0025, 22.93, 0.0041, 23.91, 0.0041, 24.90, 0.0034, 25.91, 0.0012, 26.90, 0.0013, 27.90, 0.0020, 28.89, 0.0036, 29.90, 0.0054, 30.89, 0.0054, 31.88, 0.0038, 32.89, 0.0059, 33.89, 0.0037, 34.88, 0.0024, 35.86, 0.0024, 36.87, 0.0023, 37.87, 0.0017, 38.86, 0.0020, 39.85, 0.0019, 40.86, 0.0021, 41.86, 0.0007, 42.84, 0.0012, 43.84, 0.0007, 44.84, 0.0010, 45.85, 0.0005, 46.82, 0.0006, 47.84, 0.0009, 48.82, 0.0009, 49.82, 0.0006, 50.81, 0.0008, 51.82, 0.0012, 52.80, 0.0012, 54.81, 0.0005, 55.78, 0.0003, 56.79, 0.0003, 57.78, 0.0003, 58.79, 0.0003, 59.80, 0.0004, 60.77, 0.0003, 61.78, 0.0004, 62.77, 0.0005, 63.77, 0.0001, 64.75, 0.0004, 65.76, 0.0003, 66.77, 0.0003, 67.76, 0.0006, 68.75, 0.0006, 69.75, 0.0007, 70.74, 0.0004, 71.74, 0.0010, 72.73, 0.0008, 73.74, 0.0007, 75.74, 0.0002, 76.72, 0.0004, 77.72, 0.0002, 78.71, 0.0004, 79.70, 0.0001, 80.71, 0.0001, 81.70, 0.0002, 82.70, 0.0001, 83.70, 0.0004, 84.69, 0.0003, 85.68, 0.0008, 86.68, 0.0003, 87.69, 0.0001, 88.69, 0.0002, 90.66, 0.0001] Sax_ds3 = [1.00, 0.0338, 1.99, 0.0765, 2.97, 0.0602, 3.96, 0.0870, 4.97, 0.1666, 5.96, 0.0394, 6.95, 0.0067, 7.94, 0.0199, 8.94, 0.0418, 9.93, 0.0110, 10.92, 0.0101, 11.91, 0.0077, 12.90, 0.0052, 13.91, 0.0148, 14.90, 0.0172, 15.88, 0.0218, 16.87, 0.0110, 17.88, 0.0086, 18.87, 0.0045, 19.86, 0.0009, 20.85, 0.0014, 21.85, 0.0045, 22.84, 0.0037, 23.83, 0.0010, 24.82, 0.0028, 25.81, 0.0013, 26.82, 0.0032, 27.81, 0.0040, 28.79, 0.0067, 29.78, 0.0035, 30.79, 0.0041, 31.78, 0.0028, 32.76, 0.0017, 33.75, 0.0011, 34.76, 0.0015, 35.75, 0.0018, 36.73, 0.0021, 37.72, 0.0017, 38.71, 0.0019, 39.72, 0.0014, 40.71, 0.0015, 41.70, 0.0016, 42.69, 0.0006, 43.69, 0.0021, 44.69, 0.0024, 45.67, 0.0003, 46.66, 0.0014, 47.66, 0.0002, 48.66, 0.0011, 49.65, 0.0010, 50.63, 0.0002, 51.62, 0.0008, 52.63, 0.0007, 53.62, 0.0008, 54.60, 0.0004, 56.59, 0.0005, 57.59, 0.0003, 58.58, 0.0007, 60.56, 0.0004, 61.56, 0.0002, 62.55, 0.0004, 63.54, 0.0004, 64.53, 0.0008, 65.54, 0.0011, 66.53, 0.0003, 67.52, 0.0009, 68.51, 0.0008, 69.51, 0.0013, 70.50, 0.0002, 71.49, 0.0004, 72.47, 0.0004, 73.47, 0.0002, 74.48, 0.0002, 75.46, 0.0002, 76.45, 0.0005, 77.45, 0.0003, 78.45, 0.0008, 79.44, 0.0003, 80.42, 0.0008, 81.41, 0.0005, 82.41, 0.0001, 83.42, 0.0001] Sax_e3 = [1.00, 0.0225, 1.99, 0.0627, 2.99, 0.0834, 3.98, 0.0804, 4.98, 0.0984, 5.97, 0.0393, 6.96, 0.0345, 7.96, 0.0102, 8.95, 0.0084, 9.94, 0.0129, 10.93, 0.0214, 11.93, 0.0154, 12.92, 0.0184, 13.91, 0.0167, 14.91, 0.0213, 15.90, 0.0116, 16.89, 0.0090, 17.88, 0.0045, 18.88, 0.0008, 19.87, 0.0024, 20.86, 0.0045, 21.86, 0.0058, 22.85, 0.0012, 23.84, 0.0012, 24.84, 0.0030, 25.83, 0.0035, 26.82, 0.0067, 27.83, 0.0048, 28.82, 0.0016, 29.82, 0.0012, 30.81, 0.0015, 31.81, 0.0032, 32.80, 0.0033, 33.80, 0.0038, 34.79, 0.0032, 35.78, 0.0025, 36.78, 0.0008, 37.77, 0.0007, 38.76, 0.0020, 39.75, 0.0009, 40.75, 0.0007, 41.74, 0.0018, 42.73, 0.0024, 43.72, 0.0012, 44.72, 0.0016, 45.71, 0.0015, 46.70, 0.0019, 47.69, 0.0005, 48.69, 0.0007, 49.68, 0.0006, 50.67, 0.0003, 51.68, 0.0006, 52.67, 0.0002, 53.66, 0.0004, 54.65, 0.0004, 55.65, 0.0005, 56.64, 0.0004, 57.64, 0.0006, 58.64, 0.0004, 59.64, 0.0004, 60.63, 0.0011, 61.62, 0.0004, 62.62, 0.0003, 63.61, 0.0005, 64.60, 0.0011, 65.60, 0.0010, 65.74, 0.0001, 66.59, 0.0001, 67.58, 0.0006, 68.57, 0.0007, 69.56, 0.0003, 70.56, 0.0002, 71.56, 0.0002, 72.55, 0.0007, 73.54, 0.0009, 74.53, 0.0008, 75.52, 0.0007, 76.52, 0.0006, 77.51, 0.0002, 79.50, 0.0002] Sax_f3 = [0.98, 0.0394, 1.98, 0.0562, 2.97, 0.0897, 3.96, 0.0683, 4.96, 0.0231, 5.95, 0.0309, 6.94, 0.0308, 7.91, 0.0176, 8.91, 0.0089, 9.90, 0.0084, 10.89, 0.0141, 11.89, 0.0045, 12.88, 0.0070, 13.87, 0.0083, 14.85, 0.0142, 15.84, 0.0089, 16.83, 0.0048, 17.82, 0.0015, 18.82, 0.0028, 19.82, 0.0027, 20.81, 0.0015, 21.79, 0.0012, 22.77, 0.0015, 23.76, 0.0050, 24.76, 0.0041, 25.75, 0.0048, 26.75, 0.0015, 27.74, 0.0007, 28.73, 0.0011, 29.71, 0.0016, 30.70, 0.0020, 31.69, 0.0019, 32.68, 0.0032, 33.68, 0.0026, 34.67, 0.0014, 35.66, 0.0013, 36.64, 0.0009, 37.63, 0.0014, 38.62, 0.0009, 39.61, 0.0018, 40.61, 0.0008, 41.60, 0.0013, 42.59, 0.0007, 43.57, 0.0010, 44.56, 0.0006, 45.57, 0.0002, 46.54, 0.0009, 47.53, 0.0005, 48.51, 0.0002, 49.53, 0.0001, 50.52, 0.0005, 51.49, 0.0002, 52.49, 0.0006, 53.47, 0.0001, 54.48, 0.0002, 55.46, 0.0003, 56.47, 0.0002, 57.45, 0.0006, 58.43, 0.0004, 59.42, 0.0003, 60.41, 0.0006, 61.41, 0.0005, 62.40, 0.0005, 63.40, 0.0002, 64.38, 0.0003, 65.37, 0.0001, 66.35, 0.0002, 68.34, 0.0005, 69.33, 0.0003, 70.33, 0.0005, 71.32, 0.0001, 72.30, 0.0002, 75.27, 0.0001] Sax_fs3 = [0.99, 0.0784, 1.99, 0.0550, 2.97, 0.0439, 3.97, 0.0998, 4.95, 0.0679, 5.95, 0.0244, 6.93, 0.0178, 7.94, 0.0130, 8.92, 0.0186, 9.92, 0.0204, 10.90, 0.0091, 11.90, 0.0102, 12.88, 0.0166, 13.88, 0.0130, 14.86, 0.0079, 15.86, 0.0039, 16.86, 0.0023, 17.84, 0.0052, 18.84, 0.0049, 19.82, 0.0042, 20.82, 0.0027, 21.81, 0.0027, 22.80, 0.0057, 23.78, 0.0042, 24.79, 0.0042, 25.77, 0.0015, 26.77, 0.0008, 27.75, 0.0020, 28.75, 0.0021, 29.73, 0.0032, 30.73, 0.0036, 31.71, 0.0022, 32.71, 0.0011, 33.71, 0.0015, 34.69, 0.0011, 35.69, 0.0012, 36.67, 0.0013, 37.67, 0.0014, 38.65, 0.0006, 39.65, 0.0013, 40.64, 0.0004, 41.63, 0.0010, 42.62, 0.0002, 43.62, 0.0010, 44.60, 0.0003, 45.59, 0.0003, 46.58, 0.0004, 47.59, 0.0005, 48.57, 0.0002, 49.55, 0.0005, 50.55, 0.0002, 51.54, 0.0002, 52.53, 0.0005, 53.53, 0.0006, 54.52, 0.0006, 55.51, 0.0002, 56.50, 0.0008, 57.47, 0.0003, 58.48, 0.0007, 59.47, 0.0003, 60.46, 0.0002, 61.44, 0.0002, 62.45, 0.0002, 63.43, 0.0001, 64.43, 0.0004, 65.42, 0.0005, 66.41, 0.0007, 67.40, 0.0002, 68.39, 0.0002, 69.39, 0.0002, 70.37, 0.0001] Sax_g3 = [1.00, 0.1076, 1.99, 0.0463, 2.98, 0.1092, 3.97, 0.0816, 4.95, 0.0831, 5.94, 0.0118, 6.93, 0.0095, 7.94, 0.0104, 8.93, 0.0148, 9.92, 0.0144, 10.91, 0.0117, 11.90, 0.0196, 12.89, 0.0153, 13.88, 0.0107, 14.87, 0.0052, 15.86, 0.0033, 16.86, 0.0058, 17.85, 0.0042, 18.83, 0.0013, 19.83, 0.0029, 20.82, 0.0067, 21.81, 0.0040, 22.80, 0.0057, 23.79, 0.0022, 24.79, 0.0019, 25.78, 0.0009, 26.78, 0.0017, 27.76, 0.0025, 28.76, 0.0024, 29.74, 0.0020, 30.73, 0.0011, 31.72, 0.0010, 32.73, 0.0007, 33.72, 0.0013, 34.70, 0.0019, 35.69, 0.0017, 36.69, 0.0011, 37.67, 0.0006, 38.67, 0.0008, 39.67, 0.0005, 40.66, 0.0005, 41.65, 0.0011, 42.64, 0.0003, 43.63, 0.0004, 44.62, 0.0007, 45.60, 0.0007, 46.60, 0.0006, 47.59, 0.0006, 48.59, 0.0003, 49.59, 0.0007, 50.57, 0.0006, 51.57, 0.0007, 52.55, 0.0003, 53.54, 0.0008, 54.53, 0.0005, 55.53, 0.0005, 56.51, 0.0003, 57.52, 0.0005, 59.50, 0.0001, 60.48, 0.0002, 61.47, 0.0006, 62.46, 0.0005, 63.46, 0.0003, 64.46, 0.0002, 65.45, 0.0002] Sax_gs3 = [0.98, 0.0781, 1.97, 0.0393, 2.96, 0.0842, 3.94, 0.0434, 4.93, 0.0378, 5.91, 0.0141, 6.89, 0.0201, 7.87, 0.0294, 8.86, 0.0169, 9.85, 0.0124, 10.84, 0.0137, 11.81, 0.0238, 12.80, 0.0172, 13.78, 0.0094, 14.77, 0.0040, 15.76, 0.0036, 16.74, 0.0061, 17.72, 0.0032, 18.70, 0.0035, 19.69, 0.0086, 20.68, 0.0065, 21.66, 0.0097, 22.65, 0.0036, 23.63, 0.0010, 24.62, 0.0006, 25.61, 0.0018, 26.59, 0.0026, 27.58, 0.0023, 28.56, 0.0017, 29.54, 0.0010, 30.52, 0.0012, 31.50, 0.0018, 32.50, 0.0021, 33.48, 0.0025, 34.46, 0.0010, 35.45, 0.0028, 36.42, 0.0018, 37.41, 0.0009, 38.41, 0.0007, 39.38, 0.0006, 40.37, 0.0004, 41.36, 0.0005, 42.34, 0.0007, 43.31, 0.0001, 44.29, 0.0002, 45.29, 0.0006, 46.28, 0.0005, 47.26, 0.0005, 48.25, 0.0006, 49.22, 0.0006, 50.21, 0.0003, 51.20, 0.0007, 52.18, 0.0004, 53.16, 0.0003, 54.15, 0.0004, 55.14, 0.0001, 56.10, 0.0001, 57.11, 0.0005, 58.09, 0.0007, 59.07, 0.0005, 59.22, 0.0001, 61.04, 0.0004, 63.02, 0.0002] Sax_a3 = [0.99, 0.0950, 1.97, 0.0374, 2.95, 0.0738, 3.94, 0.0772, 4.93, 0.0103, 5.92, 0.0135, 6.90, 0.0099, 7.88, 0.0088, 8.88, 0.0151, 9.86, 0.0150, 10.84, 0.0177, 11.83, 0.0121, 12.82, 0.0071, 13.81, 0.0049, 14.79, 0.0025, 15.77, 0.0046, 16.77, 0.0023, 17.75, 0.0020, 18.73, 0.0079, 19.71, 0.0057, 20.70, 0.0068, 21.69, 0.0036, 22.67, 0.0007, 23.65, 0.0003, 24.65, 0.0006, 25.64, 0.0016, 26.62, 0.0013, 27.60, 0.0006, 28.59, 0.0005, 29.59, 0.0005, 30.56, 0.0013, 31.55, 0.0015, 32.53, 0.0013, 33.52, 0.0009, 34.51, 0.0016, 35.48, 0.0002, 36.47, 0.0007, 37.46, 0.0002, 38.46, 0.0003, 39.43, 0.0002, 40.42, 0.0003, 41.40, 0.0006, 42.40, 0.0006, 43.39, 0.0002, 44.36, 0.0009, 45.35, 0.0008, 46.34, 0.0010, 47.32, 0.0003, 48.30, 0.0009, 49.29, 0.0006, 50.28, 0.0002, 51.27, 0.0004, 52.25, 0.0002, 54.23, 0.0003, 55.21, 0.0001, 56.19, 0.0002, 58.17, 0.0002] Sax_as3 = [0.99, 0.0856, 1.98, 0.0365, 2.97, 0.0409, 3.96, 0.0666, 4.94, 0.0192, 5.94, 0.0263, 6.92, 0.0311, 7.91, 0.0175, 8.90, 0.0203, 9.89, 0.0358, 10.87, 0.0214, 11.87, 0.0177, 12.85, 0.0068, 13.84, 0.0071, 14.83, 0.0068, 15.82, 0.0040, 16.80, 0.0040, 17.80, 0.0126, 18.78, 0.0101, 19.77, 0.0086, 20.75, 0.0053, 21.75, 0.0012, 22.73, 0.0026, 23.73, 0.0019, 24.71, 0.0018, 25.71, 0.0026, 26.68, 0.0023, 27.68, 0.0022, 28.66, 0.0015, 29.66, 0.0031, 30.64, 0.0008, 31.63, 0.0023, 32.61, 0.0029, 33.61, 0.0007, 34.59, 0.0016, 35.59, 0.0009, 36.57, 0.0006, 37.56, 0.0012, 38.54, 0.0004, 39.53, 0.0005, 40.52, 0.0007, 41.52, 0.0006, 42.50, 0.0009, 43.50, 0.0015, 44.48, 0.0005, 45.47, 0.0012, 46.46, 0.0007, 47.45, 0.0003, 48.44, 0.0007, 49.41, 0.0003, 50.41, 0.0003, 51.40, 0.0011, 52.39, 0.0007, 53.37, 0.0005, 54.36, 0.0005, 55.34, 0.0002, 56.34, 0.0002] Sax_b3 = [0.99, 0.1015, 1.99, 0.0817, 2.98, 0.0315, 3.98, 0.0386, 4.97, 0.0424, 5.96, 0.0104, 6.96, 0.0144, 7.94, 0.0361, 8.94, 0.0182, 9.93, 0.0238, 10.93, 0.0139, 11.93, 0.0063, 12.91, 0.0058, 13.91, 0.0071, 14.91, 0.0051, 15.89, 0.0035, 16.90, 0.0114, 17.88, 0.0097, 18.88, 0.0081, 19.87, 0.0043, 20.86, 0.0014, 21.86, 0.0009, 22.85, 0.0012, 23.86, 0.0006, 24.84, 0.0013, 25.83, 0.0006, 26.83, 0.0010, 27.82, 0.0015, 28.80, 0.0008, 29.80, 0.0012, 30.80, 0.0017, 31.77, 0.0002, 32.78, 0.0016, 33.78, 0.0006, 34.77, 0.0003, 35.77, 0.0009, 36.76, 0.0006, 37.75, 0.0011, 38.75, 0.0006, 39.74, 0.0011, 40.74, 0.0011, 41.73, 0.0006, 42.72, 0.0015, 43.72, 0.0008, 44.70, 0.0002, 45.71, 0.0005, 46.70, 0.0004, 47.69, 0.0003, 48.69, 0.0005, 49.67, 0.0005, 50.64, 0.0001, 51.66, 0.0003] Sax_c4 = [0.99, 0.1462, 1.98, 0.0760, 2.98, 0.0464, 3.97, 0.0292, 4.95, 0.0393, 5.95, 0.0117, 6.94, 0.0150, 7.93, 0.0251, 8.93, 0.0238, 9.92, 0.0182, 10.90, 0.0142, 11.89, 0.0100, 12.89, 0.0108, 13.88, 0.0029, 14.87, 0.0060, 15.86, 0.0116, 16.85, 0.0066, 17.84, 0.0072, 18.84, 0.0034, 19.83, 0.0010, 20.82, 0.0013, 21.81, 0.0015, 22.80, 0.0012, 23.80, 0.0011, 24.79, 0.0004, 25.77, 0.0027, 26.76, 0.0021, 27.75, 0.0018, 28.75, 0.0013, 29.74, 0.0015, 30.73, 0.0008, 31.72, 0.0004, 32.71, 0.0007, 33.71, 0.0011, 34.70, 0.0002, 35.68, 0.0010, 36.67, 0.0002, 37.66, 0.0003, 38.67, 0.0010, 39.66, 0.0008, 40.64, 0.0019, 41.64, 0.0005, 42.62, 0.0010, 43.62, 0.0003, 45.60, 0.0005, 46.59, 0.0002, 47.59, 0.0002, 48.58, 0.0002, 49.57, 0.0002, 50.55, 0.0001] Sax_cs4 = [0.99, 0.0832, 1.97, 0.0162, 2.96, 0.0337, 3.95, 0.0272, 4.94, 0.0264, 5.93, 0.0256, 6.93, 0.0180, 7.92, 0.0206, 8.90, 0.0167, 9.89, 0.0172, 10.88, 0.0075, 11.86, 0.0087, 12.85, 0.0048, 13.85, 0.0051, 14.83, 0.0134, 15.83, 0.0091, 16.82, 0.0065, 17.80, 0.0008, 18.80, 0.0018, 19.78, 0.0023, 20.77, 0.0025, 21.76, 0.0021, 22.74, 0.0013, 23.74, 0.0011, 24.72, 0.0032, 25.72, 0.0006, 26.72, 0.0005, 27.69, 0.0026, 28.69, 0.0009, 29.68, 0.0006, 30.66, 0.0003, 31.65, 0.0007, 32.64, 0.0003, 33.62, 0.0014, 34.61, 0.0007, 35.60, 0.0007, 36.59, 0.0005, 37.60, 0.0004, 38.56, 0.0006, 39.54, 0.0004, 40.55, 0.0004, 41.55, 0.0003, 42.50, 0.0002, 43.51, 0.0005, 44.50, 0.0003, 45.50, 0.0002, 46.48, 0.0002, 47.48, 0.0002] Sax_d4 = [0.98, 0.0860, 1.97, 0.0143, 2.95, 0.0061, 3.94, 0.0407, 4.93, 0.0204, 5.91, 0.0066, 6.90, 0.0372, 7.89, 0.0217, 8.87, 0.0220, 9.86, 0.0147, 10.85, 0.0042, 11.83, 0.0072, 12.82, 0.0023, 13.81, 0.0074, 14.79, 0.0104, 15.78, 0.0050, 16.76, 0.0005, 17.74, 0.0036, 18.73, 0.0056, 19.71, 0.0022, 20.70, 0.0040, 21.69, 0.0021, 22.68, 0.0018, 23.66, 0.0026, 24.65, 0.0035, 25.64, 0.0021, 26.62, 0.0011, 27.61, 0.0013, 28.59, 0.0006, 29.58, 0.0002, 30.57, 0.0010, 31.69, 0.0001, 32.54, 0.0004, 33.52, 0.0009, 34.50, 0.0005, 35.49, 0.0004, 36.47, 0.0013, 37.46, 0.0015, 38.45, 0.0009, 39.43, 0.0003, 40.42, 0.0004, 41.41, 0.0008, 42.40, 0.0005, 43.38, 0.0004, 44.37, 0.0006] Sax_ds4 = [0.98, 0.0870, 1.97, 0.0204, 2.96, 0.0184, 3.94, 0.0494, 4.92, 0.0500, 5.91, 0.0163, 6.90, 0.0267, 7.88, 0.0158, 8.86, 0.0159, 9.85, 0.0095, 10.84, 0.0095, 11.82, 0.0039, 12.81, 0.0053, 13.79, 0.0074, 14.78, 0.0054, 15.77, 0.0004, 16.75, 0.0027, 17.73, 0.0034, 18.71, 0.0035, 19.70, 0.0019, 20.69, 0.0028, 21.67, 0.0032, 22.65, 0.0016, 23.64, 0.0018, 24.63, 0.0033, 25.61, 0.0006, 26.59, 0.0015, 27.58, 0.0005, 28.57, 0.0010, 29.56, 0.0006, 30.54, 0.0010, 31.52, 0.0009, 32.51, 0.0004, 33.50, 0.0012, 34.47, 0.0006, 35.46, 0.0009, 36.45, 0.0007, 37.44, 0.0002, 38.42, 0.0006, 39.41, 0.0003, 40.38, 0.0003, 41.38, 0.0005, 42.36, 0.0003] Sax_e4 = [0.99, 0.0111, 1.97, 0.0520, 2.96, 0.0287, 3.94, 0.0704, 4.93, 0.0240, 5.91, 0.0286, 6.89, 0.0516, 7.89, 0.0184, 8.87, 0.0076, 9.86, 0.0113, 10.84, 0.0049, 11.83, 0.0044, 12.81, 0.0111, 13.79, 0.0080, 14.78, 0.0008, 15.76, 0.0031, 16.76, 0.0042, 17.74, 0.0016, 18.73, 0.0021, 19.71, 0.0010, 20.69, 0.0048, 21.68, 0.0014, 22.66, 0.0020, 23.66, 0.0016, 24.64, 0.0011, 25.62, 0.0011, 26.61, 0.0001, 27.59, 0.0011, 28.58, 0.0013, 29.56, 0.0011, 30.55, 0.0004, 31.54, 0.0015, 32.52, 0.0023, 33.51, 0.0015, 34.49, 0.0004, 35.48, 0.0003, 36.46, 0.0007, 37.45, 0.0003, 38.43, 0.0003, 39.42, 0.0009] Sax_f4 = [1.00, 0.0896, 2.00, 0.1802, 3.00, 0.0636, 4.00, 0.0344, 5.01, 0.0214, 6.01, 0.0196, 7.01, 0.0241, 8.01, 0.0118, 9.01, 0.0057, 10.01, 0.0060, 11.01, 0.0059, 12.01, 0.0032, 13.02, 0.0055, 14.02, 0.0023, 15.01, 0.0020, 16.02, 0.0027, 17.02, 0.0022, 18.02, 0.0017, 19.02, 0.0015, 20.02, 0.0020, 21.03, 0.0014, 22.03, 0.0010, 23.02, 0.0006, 24.03, 0.0007, 25.03, 0.0005, 27.03, 0.0006, 28.03, 0.0005, 29.04, 0.0003, 30.04, 0.0009, 31.03, 0.0006, 32.04, 0.0003, 33.04, 0.0002, 34.04, 0.0003, 35.04, 0.0001, 36.04, 0.0002, 37.05, 0.0003] Sax_fs4 = [0.99, 0.0786, 1.99, 0.1613, 2.99, 0.0550, 3.98, 0.0380, 4.98, 0.0201, 5.98, 0.0245, 6.97, 0.0212, 7.96, 0.0069, 8.96, 0.0130, 9.96, 0.0029, 10.95, 0.0084, 11.95, 0.0093, 12.94, 0.0026, 13.94, 0.0015, 14.93, 0.0022, 15.93, 0.0025, 16.93, 0.0022, 17.92, 0.0015, 18.91, 0.0011, 19.91, 0.0011, 20.91, 0.0006, 21.90, 0.0010, 22.89, 0.0003, 23.89, 0.0003, 24.89, 0.0004, 25.89, 0.0003, 26.88, 0.0011, 26.95, 0.0003, 27.87, 0.0003, 28.87, 0.0012, 29.87, 0.0002, 30.86, 0.0004, 31.85, 0.0003, 32.85, 0.0005, 33.84, 0.0006, 34.84, 0.0002, 34.90, 0.0001] Sax_g4 = [1.00, 0.0747, 2.00, 0.1351, 3.00, 0.0384, 4.00, 0.0519, 5.00, 0.0376, 6.00, 0.0323, 7.00, 0.0212, 8.00, 0.0091, 9.00, 0.0086, 10.00, 0.0060, 11.00, 0.0132, 12.00, 0.0038, 13.00, 0.0016, 14.00, 0.0044, 15.00, 0.0023, 16.00, 0.0029, 17.00, 0.0031, 18.00, 0.0011, 19.00, 0.0008, 20.00, 0.0006, 21.01, 0.0005, 22.00, 0.0006, 23.00, 0.0007, 24.00, 0.0008, 25.01, 0.0003, 26.01, 0.0017, 27.00, 0.0012, 28.00, 0.0005, 29.03, 0.0001, 30.00, 0.0004, 31.00, 0.0005, 32.00, 0.0001, 33.00, 0.0003, 34.00, 0.0001] Sax_gs4 = [1.00, 0.0671, 1.99, 0.0676, 2.98, 0.0664, 3.97, 0.0207, 4.97, 0.0170, 5.96, 0.0406, 6.96, 0.0157, 7.95, 0.0093, 8.94, 0.0032, 9.93, 0.0117, 10.93, 0.0059, 11.93, 0.0034, 12.92, 0.0052, 13.91, 0.0036, 14.90, 0.0010, 15.89, 0.0023, 16.89, 0.0019, 17.89, 0.0011, 18.88, 0.0013, 19.87, 0.0009, 20.86, 0.0005, 21.86, 0.0006, 22.86, 0.0011, 23.85, 0.0006, 24.85, 0.0008, 25.83, 0.0010, 26.83, 0.0010, 27.82, 0.0007, 28.80, 0.0002, 29.82, 0.0006, 31.80, 0.0001] Sax_a4 = [0.99, 0.0707, 1.99, 0.1376, 2.99, 0.0767, 3.98, 0.0191, 4.98, 0.0316, 5.97, 0.0241, 6.97, 0.0070, 7.97, 0.0095, 8.96, 0.0085, 9.96, 0.0109, 10.96, 0.0012, 11.95, 0.0047, 12.94, 0.0051, 13.94, 0.0022, 14.93, 0.0020, 15.93, 0.0007, 16.93, 0.0016, 17.92, 0.0014, 18.92, 0.0008, 19.92, 0.0005, 20.91, 0.0008, 21.91, 0.0005, 22.91, 0.0002, 23.90, 0.0008, 24.89, 0.0015, 25.89, 0.0004, 26.89, 0.0003, 27.88, 0.0002, 28.88, 0.0002, 29.88, 0.0002] Sax_as4 = [0.99, 0.0652, 1.98, 0.0768, 2.97, 0.0399, 3.96, 0.0314, 4.95, 0.0539, 5.94, 0.0282, 6.93, 0.0048, 7.93, 0.0059, 8.91, 0.0163, 9.90, 0.0039, 10.89, 0.0052, 11.88, 0.0086, 12.87, 0.0025, 13.86, 0.0011, 14.85, 0.0069, 15.84, 0.0006, 16.84, 0.0018, 17.82, 0.0008, 18.80, 0.0004, 19.81, 0.0004, 20.78, 0.0002, 21.79, 0.0010, 22.78, 0.0038, 23.76, 0.0018, 24.75, 0.0010, 25.74, 0.0002, 26.73, 0.0005, 27.72, 0.0006, 28.71, 0.0003] Sax_b4 = [1.00, 0.1365, 1.99, 0.0773, 2.98, 0.0370, 3.97, 0.0399, 4.97, 0.0441, 5.96, 0.0193, 6.95, 0.0055, 7.95, 0.0036, 8.94, 0.0106, 9.93, 0.0050, 10.93, 0.0075, 11.92, 0.0047, 12.91, 0.0013, 13.90, 0.0034, 14.90, 0.0024, 15.89, 0.0018, 16.89, 0.0005, 17.87, 0.0006, 18.87, 0.0014, 19.87, 0.0011, 20.86, 0.0017, 21.84, 0.0018, 22.84, 0.0007, 23.83, 0.0003, 24.82, 0.0006, 25.83, 0.0002, 26.81, 0.0002] Sax_c5 = [0.99, 0.1197, 1.98, 0.0661, 2.97, 0.0448, 3.96, 0.0398, 4.96, 0.0311, 5.95, 0.0167, 6.93, 0.0068, 7.93, 0.0249, 8.92, 0.0065, 9.91, 0.0104, 10.90, 0.0081, 11.89, 0.0032, 12.88, 0.0060, 13.87, 0.0037, 14.86, 0.0020, 15.86, 0.0008, 16.84, 0.0005, 17.84, 0.0025, 18.83, 0.0010, 19.81, 0.0020, 20.81, 0.0017, 21.80, 0.0013, 22.79, 0.0016, 23.78, 0.0009, 24.77, 0.0006, 25.76, 0.0002] Sax_cs5 = [0.98, 0.0251, 1.97, 0.0316, 2.95, 0.0599, 3.93, 0.0403, 4.92, 0.0418, 5.90, 0.0065, 6.89, 0.0047, 7.86, 0.0085, 8.85, 0.0061, 9.84, 0.0097, 10.82, 0.0033, 10.87, 0.0006, 12.26, 0.0004, 12.78, 0.0040, 13.77, 0.0023, 14.75, 0.0020, 15.73, 0.0003, 16.72, 0.0011, 17.71, 0.0012, 18.69, 0.0013, 19.67, 0.0008, 20.66, 0.0013, 21.64, 0.0005, 22.62, 0.0004, 23.60, 0.0005] Sax_d5 = [0.99, 0.0055, 1.97, 0.0823, 2.95, 0.0106, 3.94, 0.0646, 4.93, 0.0345, 5.91, 0.0069, 6.90, 0.0201, 7.89, 0.0165, 8.87, 0.0171, 9.86, 0.0114, 10.85, 0.0050, 11.82, 0.0053, 12.82, 0.0107, 13.81, 0.0033, 14.78, 0.0026, 15.78, 0.0016, 16.76, 0.0019, 17.74, 0.0011, 18.72, 0.0030, 19.73, 0.0009, 20.70, 0.0021, 21.67, 0.0003, 22.67, 0.0003, 23.65, 0.0001] Sax_ds5 = [0.98, 0.0699, 1.97, 0.0761, 2.95, 0.0777, 3.93, 0.0573, 4.92, 0.0236, 5.90, 0.0082, 6.88, 0.0195, 7.87, 0.0108, 8.85, 0.0205, 9.83, 0.0042, 10.82, 0.0112, 11.80, 0.0039, 12.78, 0.0018, 13.77, 0.0027, 14.75, 0.0017, 15.73, 0.0015, 16.72, 0.0019, 17.70, 0.0047, 18.68, 0.0011, 19.67, 0.0020, 20.65, 0.0027, 21.63, 0.0002] Sax_e5 = [0.99, 0.1082, 1.99, 0.1222, 2.99, 0.0874, 3.98, 0.0436, 4.98, 0.0208, 5.98, 0.0141, 6.97, 0.0193, 7.97, 0.0172, 8.97, 0.0118, 9.96, 0.0082, 10.96, 0.0133, 11.96, 0.0062, 12.95, 0.0058, 13.95, 0.0013, 14.94, 0.0017, 15.94, 0.0029, 16.94, 0.0032, 17.93, 0.0006, 18.93, 0.0028, 19.92, 0.0004] Sax_f5 = [1.00, 0.1462, 2.00, 0.0665, 3.01, 0.0741, 4.01, 0.0382, 5.01, 0.0262, 6.02, 0.0172, 7.02, 0.0168, 8.02, 0.0172, 9.02, 0.0087, 10.02, 0.0145, 11.03, 0.0046, 12.03, 0.0033, 13.03, 0.0032, 14.03, 0.0030, 15.03, 0.0040, 16.04, 0.0059, 17.04, 0.0026, 18.04, 0.0005, 19.05, 0.0009] Sax_fs5 = [1.00, 0.0652, 2.00, 0.0563, 3.00, 0.0939, 3.99, 0.0334, 5.00, 0.0109, 5.99, 0.0258, 6.99, 0.0213, 7.99, 0.0135, 8.99, 0.0018, 9.99, 0.0205, 10.99, 0.0043, 11.99, 0.0004, 12.99, 0.0037, 13.98, 0.0017, 14.98, 0.0071, 15.98, 0.0035, 16.98, 0.0029, 17.98, 0.0005] Sax_g5 = [1.00, 0.0918, 1.99, 0.0493, 2.99, 0.0565, 3.98, 0.0225, 4.98, 0.0118, 5.98, 0.0184, 6.97, 0.0138, 7.99, 0.0042, 8.98, 0.0077, 9.95, 0.0104, 10.96, 0.0018, 11.94, 0.0022, 12.98, 0.0061, 13.96, 0.0032, 14.96, 0.0023, 15.96, 0.0016, 16.90, 0.0008] Sax_gs5 = [0.99, 0.1447, 1.98, 0.0908, 2.97, 0.0522, 3.96, 0.0607, 4.96, 0.0316, 5.95, 0.0115, 6.94, 0.0147, 7.93, 0.0148, 8.92, 0.0221, 9.91, 0.0097, 10.90, 0.0087, 11.90, 0.0078, 12.89, 0.0127, 13.88, 0.0042, 14.87, 0.0007, 15.86, 0.0012] Sax_a5 = [0.97, 0.1089, 1.94, 0.0491, 4.85, 0.0162, 5.82, 0.0156, 6.78, 0.0130, 7.75, 0.0174, 8.72, 0.0104, 8.75, 0.0087, 8.77, 0.0024, 8.80, 0.0019, 8.82, 0.0014, 9.72, 0.0010, 10.66, 0.0033, 11.63, 0.0092, 11.66, 0.0045, 12.59, 0.0028, 12.65, 0.0015, 12.67, 0.0011, 13.64, 0.0007, 14.56, 0.0017, 14.59, 0.0017, 14.61, 0.0010, 14.62, 0.0008, 14.64, 0.0005, 15.50, 0.0003, 15.53, 0.0002, 15.56, 0.0002, 15.58, 0.0001] # # # # # soprano sax? Ssax_gs3 = [1.01, 0.0846, 2.02, 0.0851, 3.03, 0.0782, 4.03, 0.0250, 5.04, 0.0513, 6.05, 0.0121, 7.07, 0.0065, 8.08, 0.0409, 9.09, 0.0134, 10.09, 0.0032, 11.10, 0.0168, 12.12, 0.0076, 13.13, 0.0054, 14.13, 0.0091, 15.14, 0.0078, 16.15, 0.0029, 17.16, 0.0103, 18.18, 0.0103, 19.18, 0.0071, 20.19, 0.0105, 21.20, 0.0063, 22.20, 0.0054, 23.21, 0.0011, 24.22, 0.0008, 25.24, 0.0003, 26.23, 0.0001, 27.26, 0.0002, 28.25, 0.0006, 29.27, 0.0004, 30.29, 0.0008, 31.29, 0.0004, 32.31, 0.0002, 33.32, 0.0003, 34.32, 0.0003, 35.33, 0.0001, 36.34, 0.0002, 37.35, 0.0005, 38.36, 0.0003, 39.37, 0.0003, 40.37, 0.0002, 41.39, 0.0002, 42.40, 0.0002, 43.41, 0.0002, 44.43, 0.0001, 45.43, 0.0007, 46.43, 0.0004, 47.44, 0.0002, 48.46, 0.0001, 49.48, 0.0001, 50.48, 0.0002, 51.49, 0.0002, 52.49, 0.0002, 53.50, 0.0002, 54.51, 0.0002, 55.53, 0.0003, 56.54, 0.0003, 57.54, 0.0002, 58.55, 0.0002, 59.55, 0.0001] Ssax_a3 = [0.99, 0.1143, 1.99, 0.0599, 2.99, 0.0780, 3.99, 0.0629, 4.99, 0.0063, 5.99, 0.0066, 6.99, 0.0283, 7.99, 0.0134, 8.98, 0.0083, 9.97, 0.0114, 10.97, 0.0087, 11.97, 0.0171, 12.97, 0.0109, 13.97, 0.0149, 14.97, 0.0075, 15.97, 0.0164, 16.97, 0.0174, 17.94, 0.0021, 18.97, 0.0139, 19.96, 0.0073, 20.95, 0.0122, 21.95, 0.0018, 22.95, 0.0022, 23.94, 0.0002, 24.95, 0.0014, 25.94, 0.0006, 26.95, 0.0007, 27.94, 0.0012, 28.94, 0.0013, 29.93, 0.0009, 30.94, 0.0014, 31.92, 0.0012, 32.93, 0.0008, 33.93, 0.0015, 34.93, 0.0021, 35.92, 0.0009, 36.93, 0.0011, 37.93, 0.0011, 38.94, 0.0005, 39.92, 0.0008, 41.93, 0.0004, 42.91, 0.0012, 43.87, 0.0002, 44.93, 0.0006, 45.92, 0.0006, 46.91, 0.0002, 47.92, 0.0002, 48.91, 0.0004, 49.89, 0.0004, 50.89, 0.0003, 51.89, 0.0003, 52.90, 0.0003, 53.90, 0.0003, 54.91, 0.0003, 55.90, 0.0003, 56.89, 0.0002] Ssax_as3 = [1.00, 0.0772, 1.99, 0.0797, 2.98, 0.0350, 3.99, 0.1086, 4.98, 0.0418, 5.97, 0.0170, 6.98, 0.0247, 7.97, 0.0288, 8.96, 0.0041, 9.95, 0.0047, 10.95, 0.0120, 11.95, 0.0176, 12.93, 0.0128, 13.95, 0.0151, 14.94, 0.0162, 15.92, 0.0152, 16.93, 0.0077, 17.93, 0.0111, 18.92, 0.0092, 19.91, 0.0079, 20.91, 0.0053, 21.89, 0.0009, 22.90, 0.0008, 24.88, 0.0004, 25.88, 0.0009, 26.88, 0.0009, 27.87, 0.0014, 28.87, 0.0008, 29.87, 0.0023, 30.87, 0.0013, 31.85, 0.0012, 32.87, 0.0015, 33.85, 0.0011, 34.85, 0.0024, 35.84, 0.0021, 36.86, 0.0024, 37.87, 0.0008, 38.82, 0.0007, 39.85, 0.0009, 40.79, 0.0007, 41.83, 0.0009, 42.84, 0.0007, 43.84, 0.0006, 44.82, 0.0001, 46.83, 0.0004, 47.83, 0.0003, 48.81, 0.0003, 49.82, 0.0002, 50.82, 0.0001, 51.82, 0.0002, 52.81, 0.0002, 54.81, 0.0004, 55.80, 0.0002] Ssax_b3 = [0.99, 0.0413, 1.98, 0.0949, 2.98, 0.0746, 3.96, 0.0636, 4.96, 0.0383, 5.95, 0.0300, 6.93, 0.0190, 7.93, 0.0159, 8.92, 0.0172, 9.90, 0.0159, 10.90, 0.0047, 11.89, 0.0087, 12.88, 0.0153, 13.87, 0.0129, 14.87, 0.0112, 15.85, 0.0054, 16.84, 0.0076, 17.84, 0.0060, 18.82, 0.0064, 19.81, 0.0050, 20.81, 0.0009, 21.80, 0.0013, 22.78, 0.0003, 23.79, 0.0005, 24.78, 0.0005, 25.76, 0.0020, 26.75, 0.0020, 27.75, 0.0016, 28.73, 0.0012, 29.72, 0.0009, 30.72, 0.0017, 31.70, 0.0018, 32.69, 0.0012, 33.69, 0.0022, 34.67, 0.0014, 35.67, 0.0015, 36.66, 0.0009, 37.65, 0.0013, 38.64, 0.0019, 39.63, 0.0010, 40.62, 0.0012, 41.61, 0.0003, 42.61, 0.0003, 43.60, 0.0003, 44.58, 0.0004, 45.58, 0.0003, 47.55, 0.0004, 48.54, 0.0002, 49.54, 0.0003, 50.53, 0.0002, 51.52, 0.0002] Ssax_c4 = [0.99, 0.1251, 1.98, 0.0932, 2.97, 0.1614, 3.97, 0.0801, 4.96, 0.0100, 5.94, 0.0183, 6.94, 0.0221, 7.93, 0.0060, 8.92, 0.0055, 9.91, 0.0162, 10.90, 0.0171, 11.89, 0.0181, 12.88, 0.0135, 13.88, 0.0102, 14.87, 0.0071, 15.86, 0.0066, 16.84, 0.0071, 17.83, 0.0057, 18.83, 0.0027, 19.82, 0.0006, 20.82, 0.0008, 21.80, 0.0003, 22.78, 0.0007, 23.78, 0.0011, 24.77, 0.0019, 25.77, 0.0010, 26.76, 0.0016, 27.74, 0.0008, 28.74, 0.0013, 29.73, 0.0025, 30.72, 0.0019, 31.71, 0.0029, 32.70, 0.0022, 33.69, 0.0011, 34.68, 0.0014, 35.68, 0.0010, 36.67, 0.0014, 37.65, 0.0007, 38.64, 0.0005, 39.62, 0.0001, 40.63, 0.0004, 41.62, 0.0006, 42.61, 0.0005, 43.60, 0.0003, 44.58, 0.0003, 45.58, 0.0003, 46.58, 0.0006, 47.57, 0.0003, 48.56, 0.0002] Ssax_cs4 = [0.98, 0.0809, 1.97, 0.0745, 2.96, 0.1141, 3.95, 0.0537, 4.95, 0.0028, 5.92, 0.0112, 6.93, 0.0029, 7.90, 0.0117, 8.89, 0.0101, 9.89, 0.0091, 10.87, 0.0113, 11.86, 0.0048, 12.85, 0.0076, 13.84, 0.0054, 14.82, 0.0089, 15.81, 0.0068, 16.80, 0.0065, 17.79, 0.0031, 18.77, 0.0009, 19.76, 0.0007, 20.75, 0.0005, 21.73, 0.0010, 22.72, 0.0016, 23.71, 0.0009, 24.70, 0.0016, 25.68, 0.0010, 26.68, 0.0018, 27.66, 0.0018, 28.65, 0.0009, 29.64, 0.0012, 30.63, 0.0017, 31.61, 0.0016, 32.60, 0.0008, 33.59, 0.0012, 34.58, 0.0014, 35.57, 0.0005, 36.56, 0.0006, 37.54, 0.0008, 38.53, 0.0005, 39.52, 0.0004, 40.50, 0.0004, 41.49, 0.0001, 42.47, 0.0004, 43.46, 0.0002] Ssax_d4 = [0.99, 0.0919, 1.98, 0.0711, 2.98, 0.0924, 3.97, 0.0396, 4.95, 0.0407, 5.94, 0.0357, 6.93, 0.0035, 7.93, 0.0079, 8.91, 0.0110, 9.90, 0.0191, 10.89, 0.0103, 11.89, 0.0134, 12.88, 0.0025, 13.86, 0.0014, 14.86, 0.0082, 15.85, 0.0084, 16.84, 0.0024, 17.82, 0.0011, 18.82, 0.0011, 19.81, 0.0010, 20.80, 0.0002, 21.79, 0.0015, 22.78, 0.0011, 23.76, 0.0025, 24.77, 0.0018, 25.75, 0.0027, 26.74, 0.0036, 27.73, 0.0023, 28.73, 0.0034, 29.72, 0.0032, 30.70, 0.0011, 31.70, 0.0017, 32.69, 0.0014, 33.68, 0.0013, 34.66, 0.0004, 35.65, 0.0003, 36.64, 0.0002, 37.63, 0.0002, 38.62, 0.0004, 39.62, 0.0008, 40.61, 0.0004, 41.60, 0.0005, 42.59, 0.0005, 43.59, 0.0003, 44.56, 0.0002] Ssax_ds4 = [0.99, 0.0684, 1.98, 0.0744, 2.97, 0.1315, 3.96, 0.0137, 4.94, 0.0352, 5.94, 0.0195, 6.93, 0.0148, 7.91, 0.0275, 8.91, 0.0191, 9.90, 0.0268, 10.88, 0.0194, 11.86, 0.0044, 12.86, 0.0046, 13.85, 0.0090, 14.84, 0.0072, 15.83, 0.0049, 16.82, 0.0015, 17.80, 0.0017, 18.80, 0.0006, 19.79, 0.0008, 20.77, 0.0020, 21.76, 0.0010, 22.75, 0.0025, 23.74, 0.0033, 24.73, 0.0023, 25.72, 0.0041, 26.71, 0.0051, 27.70, 0.0043, 28.69, 0.0033, 29.68, 0.0010, 30.66, 0.0013, 31.65, 0.0013, 32.64, 0.0013, 33.63, 0.0008, 34.64, 0.0001, 35.61, 0.0002, 36.60, 0.0003, 37.62, 0.0002, 38.58, 0.0006, 39.57, 0.0005, 40.58, 0.0001, 41.55, 0.0002] Ssax_e4 = [1.00, 0.0363, 1.98, 0.1101, 2.98, 0.1009, 3.96, 0.0168, 4.95, 0.0610, 5.95, 0.0099, 6.94, 0.0066, 7.93, 0.0157, 8.92, 0.0162, 9.91, 0.0154, 10.90, 0.0131, 11.89, 0.0061, 12.88, 0.0029, 13.87, 0.0058, 14.86, 0.0040, 15.85, 0.0015, 16.84, 0.0012, 17.84, 0.0005, 18.82, 0.0005, 19.81, 0.0008, 20.85, 0.0007, 21.80, 0.0005, 22.78, 0.0016, 23.77, 0.0017, 24.76, 0.0022, 25.76, 0.0010, 26.80, 0.0006, 27.74, 0.0012, 28.72, 0.0007, 29.71, 0.0004, 30.70, 0.0004, 31.69, 0.0001, 32.68, 0.0001, 33.67, 0.0003, 34.65, 0.0004, 35.65, 0.0003, 36.64, 0.0003, 37.63, 0.0002, 38.61, 0.0002] Ssax_f4 = [1.00, 0.0607, 1.99, 0.1291, 3.00, 0.0576, 3.99, 0.0530, 4.99, 0.0330, 5.98, 0.0364, 6.98, 0.0116, 7.98, 0.0252, 8.97, 0.0175, 9.97, 0.0166, 10.97, 0.0147, 11.97, 0.0096, 12.96, 0.0060, 13.96, 0.0022, 14.95, 0.0018, 15.95, 0.0018, 16.96, 0.0003, 17.94, 0.0012, 18.94, 0.0021, 19.94, 0.0051, 20.94, 0.0018, 21.93, 0.0034, 22.93, 0.0038, 23.93, 0.0035, 24.92, 0.0041, 25.92, 0.0015, 26.91, 0.0024, 27.92, 0.0019, 28.92, 0.0008, 29.91, 0.0005, 30.92, 0.0003, 31.91, 0.0005, 32.91, 0.0006, 33.90, 0.0003, 34.89, 0.0002, 35.89, 0.0005, 36.89, 0.0002] Ssax_fs4 = [0.99, 0.0502, 1.98, 0.0678, 2.96, 0.0319, 3.95, 0.0589, 4.93, 0.0093, 5.93, 0.0072, 6.91, 0.0063, 7.89, 0.0224, 8.88, 0.0185, 9.87, 0.0096, 10.86, 0.0046, 11.84, 0.0060, 12.83, 0.0052, 13.82, 0.0008, 14.80, 0.0022, 15.79, 0.0009, 16.79, 0.0008, 17.76, 0.0011, 18.75, 0.0024, 19.74, 0.0013, 20.71, 0.0009, 21.71, 0.0038, 22.70, 0.0037, 23.68, 0.0023, 24.66, 0.0010, 25.66, 0.0007, 26.64, 0.0009, 27.64, 0.0007, 28.61, 0.0002, 29.61, 0.0006, 30.60, 0.0004, 31.58, 0.0008, 32.56, 0.0004, 33.55, 0.0005, 35.53, 0.0002] Ssax_g4 = [1.00, 0.0253, 1.99, 0.0803, 2.98, 0.0107, 3.97, 0.0688, 4.96, 0.0361, 5.96, 0.0208, 6.96, 0.0172, 7.95, 0.0172, 8.94, 0.0189, 9.93, 0.0080, 10.92, 0.0114, 11.92, 0.0059, 12.91, 0.0058, 13.90, 0.0007, 14.89, 0.0011, 15.89, 0.0011, 16.88, 0.0023, 17.87, 0.0046, 18.87, 0.0024, 19.85, 0.0043, 20.86, 0.0087, 21.83, 0.0023, 22.84, 0.0043, 23.84, 0.0039, 24.83, 0.0020, 25.81, 0.0017, 26.81, 0.0009, 27.82, 0.0006, 28.80, 0.0004, 29.79, 0.0007, 30.80, 0.0005, 31.78, 0.0011, 32.78, 0.0004, 33.76, 0.0001] Ssax_gs4 = [1.00, 0.0453, 2.00, 0.1198, 2.99, 0.0370, 3.99, 0.1319, 4.98, 0.0327, 5.97, 0.0018, 6.98, 0.0199, 7.97, 0.0362, 8.97, 0.0196, 9.96, 0.0065, 10.96, 0.0061, 11.96, 0.0025, 12.95, 0.0026, 13.95, 0.0010, 14.94, 0.0005, 15.94, 0.0027, 16.94, 0.0031, 17.93, 0.0037, 18.92, 0.0019, 19.92, 0.0034, 20.92, 0.0087, 21.92, 0.0034, 22.91, 0.0029, 23.91, 0.0024, 24.90, 0.0006, 25.90, 0.0002, 26.90, 0.0009, 27.90, 0.0003, 28.90, 0.0015, 29.89, 0.0011, 30.89, 0.0004, 31.88, 0.0001] Ssax_a4 = [1.00, 0.0568, 1.99, 0.1275, 2.98, 0.0496, 3.98, 0.0504, 4.97, 0.0277, 5.96, 0.0064, 6.95, 0.0205, 7.95, 0.0244, 8.94, 0.0067, 9.93, 0.0133, 10.92, 0.0045, 11.92, 0.0035, 12.91, 0.0028, 13.90, 0.0010, 14.90, 0.0011, 15.89, 0.0035, 16.89, 0.0034, 17.88, 0.0037, 18.87, 0.0052, 19.86, 0.0027, 20.86, 0.0028, 21.86, 0.0003, 22.84, 0.0011, 23.84, 0.0005, 24.83, 0.0010, 25.82, 0.0005, 26.81, 0.0003, 27.81, 0.0007, 28.80, 0.0005, 29.79, 0.0004] Ssax_as4 = [0.99, 0.0497, 1.98, 0.0814, 2.97, 0.0351, 3.96, 0.0207, 4.95, 0.0068, 5.93, 0.0241, 6.92, 0.0219, 7.91, 0.0187, 8.90, 0.0053, 9.88, 0.0026, 10.88, 0.0026, 11.87, 0.0027, 12.85, 0.0011, 13.85, 0.0018, 14.84, 0.0029, 15.84, 0.0013, 16.83, 0.0014, 17.81, 0.0036, 18.80, 0.0042, 19.79, 0.0015, 20.78, 0.0021, 21.77, 0.0018, 22.76, 0.0011, 23.75, 0.0004, 24.66, 0.0003, 25.73, 0.0006, 26.72, 0.0005, 27.71, 0.0002] Ssax_b4 = [0.99, 0.0161, 1.98, 0.0825, 2.96, 0.0846, 3.95, 0.0304, 4.94, 0.0112, 5.93, 0.0158, 6.91, 0.0362, 7.90, 0.0085, 8.89, 0.0147, 9.87, 0.0047, 10.85, 0.0016, 11.85, 0.0044, 12.84, 0.0024, 13.83, 0.0044, 14.82, 0.0015, 15.80, 0.0066, 16.79, 0.0061, 17.78, 0.0135, 18.77, 0.0107, 19.75, 0.0020, 20.75, 0.0008, 21.73, 0.0010, 22.71, 0.0014, 23.70, 0.0007, 24.69, 0.0009, 25.68, 0.0008, 26.67, 0.0002] Ssax_c5 = [1.00, 0.1378, 1.99, 0.1932, 2.99, 0.0181, 3.98, 0.0213, 4.97, 0.0472, 5.97, 0.0302, 6.97, 0.0099, 7.96, 0.0039, 8.96, 0.0052, 9.95, 0.0031, 10.95, 0.0007, 11.94, 0.0010, 12.93, 0.0015, 13.93, 0.0009, 14.93, 0.0013, 15.92, 0.0018, 16.92, 0.0015, 17.91, 0.0030, 18.91, 0.0013, 19.90, 0.0008, 20.90, 0.0008, 21.89, 0.0006, 22.89, 0.0006, 23.89, 0.0003] Ssax_cs5 = [0.99, 0.1332, 1.97, 0.2232, 2.96, 0.1240, 3.95, 0.0080, 4.94, 0.0398, 5.93, 0.0194, 6.92, 0.0059, 7.90, 0.0022, 8.91, 0.0008, 9.88, 0.0017, 10.87, 0.0005, 11.85, 0.0004, 12.84, 0.0008, 13.83, 0.0009, 14.82, 0.0032, 15.81, 0.0009, 16.81, 0.0017, 17.78, 0.0009, 18.77, 0.0003, 19.76, 0.0002, 20.75, 0.0006, 21.74, 0.0004, 22.73, 0.0002] Ssax_d5 = [0.99, 0.1242, 1.98, 0.0414, 2.97, 0.0487, 3.96, 0.0182, 4.95, 0.0225, 5.94, 0.0112, 6.93, 0.0012, 7.92, 0.0035, 8.87, 0.0004, 9.90, 0.0011, 10.89, 0.0006, 11.88, 0.0004, 12.81, 0.0008, 13.87, 0.0011, 14.86, 0.0015, 15.84, 0.0005, 16.83, 0.0002, 17.82, 0.0005, 18.46, 0.0002, 19.82, 0.0002, 20.81, 0.0002, 21.66, 0.0001] Ssax_ds5 = [0.99, 0.1419, 1.98, 0.0180, 2.98, 0.0683, 3.96, 0.0172, 4.95, 0.0329, 5.94, 0.0093, 6.93, 0.0017, 7.91, 0.0014, 8.91, 0.0022, 9.90, 0.0018, 10.88, 0.0004, 11.89, 0.0011, 12.88, 0.0009, 13.87, 0.0010, 14.83, 0.0007, 15.85, 0.0004, 16.85, 0.0002, 17.85, 0.0003, 18.85, 0.0003, 20.81, 0.0001] Ssax_e5 = [1.00, 0.2435, 1.99, 0.0422, 2.99, 0.0422, 3.98, 0.0137, 4.97, 0.0155, 5.97, 0.0127, 6.96, 0.0024, 7.96, 0.0014, 8.95, 0.0017, 9.95, 0.0011, 10.94, 0.0006, 11.94, 0.0009, 12.93, 0.0022, 13.92, 0.0048, 14.92, 0.0004, 15.91, 0.0006, 16.91, 0.0003, 17.90, 0.0002, 18.89, 0.0002, 19.89, 0.0002] Ssax_f5 = [1.00, 0.2095, 2.00, 0.0502, 3.01, 0.0783, 4.01, 0.0216, 5.01, 0.0293, 6.01, 0.0080, 7.01, 0.0043, 8.02, 0.0036, 9.02, 0.0019, 10.02, 0.0002, 11.02, 0.0013, 12.02, 0.0010, 13.02, 0.0007, 14.03, 0.0010, 15.03, 0.0003, 16.03, 0.0013, 17.04, 0.0009, 18.04, 0.0005] Ssax_fs5 = [0.99, 0.1379, 1.98, 0.0339, 2.98, 0.0480, 3.97, 0.0340, 4.96, 0.0264, 5.95, 0.0126, 6.94, 0.0046, 7.93, 0.0030, 8.92, 0.0013, 9.91, 0.0010, 10.90, 0.0009, 11.89, 0.0007, 12.88, 0.0007, 13.88, 0.0018, 14.87, 0.0012, 15.86, 0.0006, 16.85, 0.0004, 17.84, 0.0007] Ssax_g5 = [0.99, 0.0699, 1.98, 0.0273, 2.96, 0.0227, 3.95, 0.0133, 4.94, 0.0151, 5.92, 0.0023, 6.92, 0.0024, 7.91, 0.0011, 8.90, 0.0009, 9.89, 0.0018, 10.87, 0.0009, 11.88, 0.0016, 12.86, 0.0007, 13.84, 0.0008, 14.83, 0.0007, 15.82, 0.0005, 16.81, 0.0003] Ssax_gs5 = [1.00, 0.1830, 1.99, 0.0897, 2.99, 0.0456, 3.99, 0.0296, 4.99, 0.0125, 5.98, 0.0059, 6.98, 0.0105, 7.98, 0.0027, 8.97, 0.0044, 9.97, 0.0096, 10.97, 0.0011, 11.97, 0.0027, 12.97, 0.0006, 13.97, 0.0024, 14.96, 0.0014, 15.95, 0.0002] Ssax_a5 = [0.99, 0.2010, 1.98, 0.0677, 2.97, 0.0195, 3.97, 0.0363, 4.96, 0.0191, 5.95, 0.0092, 6.94, 0.0047, 7.93, 0.0021, 7.96, 0.0004, 8.91, 0.0004, 9.92, 0.0039, 10.90, 0.0023, 11.91, 0.0005, 12.88, 0.0008, 12.91, 0.0002, 13.86, 0.0002, 14.87, 0.0007] Ssax_as5 = [1.00, 0.1011, 1.99, 0.0696, 2.99, 0.0359, 3.98, 0.0008, 4.99, 0.0111, 5.98, 0.0027, 6.98, 0.0005, 7.98, 0.0038, 8.98, 0.0032, 9.98, 0.0037, 10.97, 0.0024, 11.97, 0.0012, 12.97, 0.0009, 13.97, 0.0004] Ssax_b5 = [0.98, 0.0933, 1.95, 0.0632, 2.93, 0.0226, 4.89, 0.0036, 5.86, 0.0133, 6.84, 0.0018, 7.82, 0.0036, 8.79, 0.0037, 9.77, 0.0111, 10.75, 0.0011, 11.72, 0.0009, 12.70, 0.0013] Ssax_c6 = [1.01, 0.0218, 1.98, 0.0033, 3.00, 0.0037, 3.99, 0.0010, 4.03, 0.0009, 4.77, 0.0002, 4.95, 0.0002, 6.01, 0.0001, 7.00, 0.0002, 8.02, 0.0004, 9.03, 0.0004, 10.03, 0.0003, 12.03, 0.0001] Ssax_cs6 = [0.99, 0.1143, 1.99, 0.0478, 2.99, 0.0259, 3.97, 0.0101, 4.97, 0.0058, 5.96, 0.0010, 6.95, 0.0012, 7.98, 0.0017, 8.95, 0.0024, 8.98, 0.0016, 9.96, 0.0007, 10.93, 0.0019, 10.96, 0.0010, 11.90, 0.0003, 11.95, 0.0002] Ssax_d6 = [1.01, 0.0247, 2.02, 0.0062, 3.02, 0.0036, 4.03, 0.0052, 5.05, 0.0006, 6.07, 0.0004, 7.06, 0.0013, 8.07, 0.0027, 11.11, 0.0001] # # # # # Tbf_e2 = [1.01, 0.0028, 2.00, 0.0192, 3.04, 0.0188, 4.02, 0.0134, 5.02, 0.0319, 6.05, 0.0335, 7.04, 0.0136, 8.06, 0.0074, 9.07, 0.0527, 10.06, 0.0217, 11.05, 0.0025, 12.09, 0.0068, 13.08, 0.0278, 14.10, 0.0125, 15.09, 0.0152, 16.13, 0.0101, 17.13, 0.0088, 18.11, 0.0094, 19.14, 0.0084, 20.20, 0.0008, 21.13, 0.0031, 22.16, 0.0097, 23.14, 0.0053, 24.17, 0.0030, 25.20, 0.0013, 26.17, 0.0055, 27.20, 0.0049, 28.19, 0.0040, 29.21, 0.0010, 30.21, 0.0030, 31.20, 0.0032, 32.24, 0.0031, 33.21, 0.0006, 34.23, 0.0015, 35.25, 0.0020, 36.23, 0.0012, 37.25, 0.0010, 38.29, 0.0007, 39.26, 0.0017, 40.29, 0.0014, 41.27, 0.0015, 42.29, 0.0005, 43.32, 0.0012, 44.30, 0.0014, 45.32, 0.0010, 46.32, 0.0005, 47.31, 0.0003, 48.34, 0.0009, 49.32, 0.0005, 50.34, 0.0005, 51.35, 0.0001, 52.35, 0.0005, 53.37, 0.0006, 54.37, 0.0006, 55.38, 0.0001, 56.38, 0.0002, 57.39, 0.0006, 58.41, 0.0005, 59.42, 0.0004, 60.42, 0.0001, 61.43, 0.0004, 62.41, 0.0004, 63.42, 0.0003, 64.45, 0.0002, 65.46, 0.0001, 66.45, 0.0003, 67.48, 0.0003, 68.46, 0.0001, 69.50, 0.0001, 70.49, 0.0004, 71.48, 0.0002, 72.47, 0.0001, 74.52, 0.0002, 75.51, 0.0002, 76.51, 0.0002, 79.55, 0.0002, 80.56, 0.0002, 81.55, 0.0001, 83.58, 0.0002, 84.57, 0.0001, 85.59, 0.0002, 87.60, 0.0002, 88.59, 0.0001, 89.61, 0.0002, 92.62, 0.0001, 93.64, 0.0001, 96.67, 0.0001, 98.69, 0.0001] Tbf_f2 = [0.99, 0.0062, 2.00, 0.0189, 3.01, 0.0059, 4.03, 0.0167, 5.01, 0.0454, 6.01, 0.0190, 7.03, 0.0261, 8.04, 0.0495, 9.04, 0.0195, 10.01, 0.0059, 11.02, 0.0030, 12.05, 0.0247, 13.04, 0.0097, 14.05, 0.0122, 15.04, 0.0076, 16.03, 0.0044, 17.05, 0.0063, 18.06, 0.0045, 19.06, 0.0011, 20.05, 0.0028, 21.07, 0.0056, 22.07, 0.0019, 22.55, 0.0004, 23.17, 0.0001, 24.07, 0.0026, 25.08, 0.0016, 26.10, 0.0017, 27.11, 0.0006, 28.09, 0.0011, 29.10, 0.0014, 30.10, 0.0011, 31.13, 0.0007, 32.12, 0.0006, 33.11, 0.0009, 34.10, 0.0004, 35.15, 0.0002, 36.15, 0.0004, 37.13, 0.0006, 38.11, 0.0004, 39.11, 0.0002, 40.15, 0.0003, 41.13, 0.0004, 42.13, 0.0003, 43.17, 0.0002, 44.20, 0.0002, 45.16, 0.0002, 46.18, 0.0003, 48.16, 0.0001, 49.20, 0.0002, 50.20, 0.0002, 51.21, 0.0001, 54.20, 0.0001] Tbf_fs2 = [1.02, 0.0056, 2.01, 0.0355, 3.01, 0.0221, 3.99, 0.0130, 4.99, 0.0606, 6.00, 0.0189, 7.01, 0.0127, 8.02, 0.0612, 9.01, 0.0211, 10.01, 0.0079, 10.99, 0.0134, 11.99, 0.0205, 13.00, 0.0282, 14.03, 0.0114, 15.02, 0.0079, 16.01, 0.0116, 17.00, 0.0082, 18.02, 0.0015, 19.00, 0.0052, 20.03, 0.0082, 21.03, 0.0057, 22.05, 0.0011, 23.02, 0.0048, 24.01, 0.0035, 25.01, 0.0032, 26.02, 0.0012, 27.04, 0.0033, 28.01, 0.0015, 29.03, 0.0013, 30.05, 0.0008, 31.03, 0.0024, 32.02, 0.0010, 33.02, 0.0007, 34.05, 0.0007, 35.05, 0.0013, 36.04, 0.0008, 37.03, 0.0004, 38.02, 0.0004, 39.03, 0.0008, 40.03, 0.0005, 42.07, 0.0005, 43.05, 0.0006, 44.05, 0.0003, 45.10, 0.0002, 46.05, 0.0003, 47.05, 0.0003, 48.05, 0.0002, 50.08, 0.0003, 51.07, 0.0003, 52.06, 0.0002, 53.09, 0.0001, 54.00, 0.0001, 55.06, 0.0002, 56.09, 0.0002, 57.10, 0.0001, 58.08, 0.0001, 59.05, 0.0001, 60.09, 0.0001, 62.09, 0.0001, 63.06, 0.0001, 66.13, 0.0001] Tbf_g2 = [0.99, 0.0059, 1.98, 0.0515, 2.98, 0.0305, 3.98, 0.0081, 4.97, 0.0448, 5.98, 0.0160, 6.97, 0.0397, 7.97, 0.0418, 8.93, 0.0079, 9.96, 0.0086, 10.95, 0.0358, 11.96, 0.0207, 12.94, 0.0116, 13.94, 0.0070, 14.93, 0.0156, 15.94, 0.0120, 16.98, 0.0013, 17.94, 0.0060, 18.91, 0.0074, 19.94, 0.0070, 20.94, 0.0013, 21.92, 0.0060, 22.91, 0.0043, 23.89, 0.0014, 24.95, 0.0017, 25.91, 0.0031, 26.90, 0.0022, 27.90, 0.0009, 28.91, 0.0017, 29.89, 0.0016, 30.88, 0.0012, 31.86, 0.0004, 32.88, 0.0013, 33.89, 0.0008, 34.85, 0.0005, 35.83, 0.0005, 36.85, 0.0008, 37.87, 0.0006, 38.87, 0.0001, 39.86, 0.0004, 40.90, 0.0008, 41.86, 0.0005, 42.88, 0.0003, 43.86, 0.0005, 44.84, 0.0005, 45.89, 0.0003, 46.92, 0.0002, 47.86, 0.0003, 48.77, 0.0002, 49.85, 0.0002, 50.86, 0.0002, 51.81, 0.0003, 52.88, 0.0001, 53.87, 0.0001, 54.80, 0.0002, 55.77, 0.0001, 56.88, 0.0002, 58.76, 0.0001, 59.82, 0.0001, 62.83, 0.0001, 63.88, 0.0001, 73.81, 0.0001] Tbf_gs2 = [0.99, 0.0058, 1.98, 0.0327, 2.99, 0.0282, 3.99, 0.0353, 4.98, 0.0348, 5.96, 0.0451, 6.97, 0.0549, 7.97, 0.0183, 8.96, 0.0096, 9.94, 0.0221, 10.94, 0.0110, 11.93, 0.0102, 12.92, 0.0074, 13.92, 0.0109, 14.91, 0.0080, 15.15, 0.0013, 15.91, 0.0003, 16.90, 0.0034, 17.88, 0.0030, 18.88, 0.0036, 19.14, 0.0004, 20.05, 0.0003, 20.86, 0.0029, 21.87, 0.0014, 22.84, 0.0008, 23.85, 0.0021, 24.83, 0.0011, 25.81, 0.0007, 26.80, 0.0003, 27.81, 0.0010, 28.82, 0.0003, 29.84, 0.0003, 30.77, 0.0006, 31.75, 0.0002, 32.78, 0.0005, 33.79, 0.0003, 34.77, 0.0003, 35.78, 0.0003, 37.75, 0.0002, 38.72, 0.0002, 41.75, 0.0001, 42.73, 0.0001, 45.69, 0.0001] Tbf_a2 = [1.00, 0.0085, 1.99, 0.0291, 2.99, 0.0151, 4.00, 0.0554, 5.00, 0.0164, 6.02, 0.0087, 7.00, 0.0365, 8.06, 0.0023, 9.02, 0.0098, 9.98, 0.0165, 10.97, 0.0176, 11.97, 0.0107, 12.98, 0.0081, 13.97, 0.0077, 14.97, 0.0012, 15.99, 0.0038, 16.98, 0.0028, 17.97, 0.0017, 18.97, 0.0024, 19.98, 0.0014, 20.95, 0.0017, 21.92, 0.0009, 23.01, 0.0009, 23.98, 0.0006, 24.94, 0.0004, 25.95, 0.0013, 26.95, 0.0003, 27.99, 0.0002, 28.97, 0.0006, 29.96, 0.0002, 30.90, 0.0003, 31.89, 0.0003, 32.83, 0.0002, 33.02, 0.0001, 33.78, 0.0001, 34.94, 0.0001, 35.94, 0.0002, 38.91, 0.0002, 39.88, 0.0001] Tbf_as2 = [1.00, 0.0251, 2.05, 0.0009, 3.02, 0.0385, 4.03, 0.0997, 5.03, 0.0337, 6.04, 0.1061, 7.04, 0.0539, 8.05, 0.0357, 9.06, 0.0635, 10.06, 0.0233, 11.05, 0.0153, 12.07, 0.0218, 13.07, 0.0235, 14.08, 0.0092, 15.08, 0.0135, 16.09, 0.0104, 17.09, 0.0055, 18.10, 0.0130, 19.11, 0.0059, 20.12, 0.0030, 21.12, 0.0060, 22.12, 0.0029, 23.12, 0.0032, 24.13, 0.0022, 25.14, 0.0016, 26.14, 0.0007, 27.15, 0.0032, 28.15, 0.0014, 29.16, 0.0012, 30.15, 0.0015, 31.18, 0.0011, 32.19, 0.0008, 33.18, 0.0014, 34.19, 0.0007, 35.19, 0.0003, 36.18, 0.0009, 37.16, 0.0004, 39.21, 0.0007, 40.22, 0.0006, 41.23, 0.0001, 42.20, 0.0004, 43.24, 0.0007, 45.25, 0.0007, 46.26, 0.0004, 47.32, 0.0001, 48.26, 0.0004, 49.26, 0.0003, 51.29, 0.0003, 52.28, 0.0002, 54.30, 0.0003, 55.32, 0.0002, 57.31, 0.0002, 58.32, 0.0001, 60.31, 0.0002, 61.30, 0.0001, 63.35, 0.0001, 64.34, 0.0001, 66.37, 0.0001] Tbf_b2 = [1.02, 0.0294, 2.03, 0.0276, 3.03, 0.0170, 4.05, 0.0409, 5.06, 0.0434, 6.06, 0.0552, 7.06, 0.0128, 8.08, 0.0076, 9.07, 0.0216, 10.08, 0.0169, 11.07, 0.0035, 12.09, 0.0094, 13.10, 0.0046, 14.12, 0.0021, 15.12, 0.0059, 16.13, 0.0023, 17.15, 0.0039, 18.16, 0.0035, 19.17, 0.0015, 20.18, 0.0020, 21.19, 0.0023, 22.19, 0.0005, 23.22, 0.0022, 24.24, 0.0010, 25.27, 0.0006, 26.26, 0.0008, 27.27, 0.0010, 28.28, 0.0003, 29.28, 0.0006, 30.27, 0.0005, 31.32, 0.0003, 32.30, 0.0004, 33.29, 0.0004, 35.37, 0.0004, 36.34, 0.0002, 37.38, 0.0002, 38.38, 0.0003, 39.48, 0.0002, 41.43, 0.0003, 42.40, 0.0001, 44.50, 0.0001, 45.47, 0.0001, 47.46, 0.0001] Tbf_c3 = [1.01, 0.0167, 2.00, 0.0116, 3.00, 0.0033, 3.99, 0.0432, 5.01, 0.0116, 6.00, 0.0573, 7.00, 0.0128, 8.00, 0.0582, 9.02, 0.0354, 10.01, 0.0203, 11.00, 0.0226, 12.00, 0.0167, 13.03, 0.0055, 14.02, 0.0174, 15.01, 0.0088, 16.01, 0.0083, 17.03, 0.0066, 18.03, 0.0022, 19.01, 0.0058, 20.01, 0.0049, 21.03, 0.0016, 22.03, 0.0053, 23.03, 0.0028, 24.01, 0.0013, 25.03, 0.0028, 26.03, 0.0015, 27.00, 0.0003, 28.02, 0.0026, 28.39, 0.0002, 29.70, 0.0002, 30.03, 0.0014, 31.03, 0.0010, 32.04, 0.0007, 33.03, 0.0010, 34.03, 0.0007, 35.04, 0.0004, 36.03, 0.0009, 37.03, 0.0004, 38.05, 0.0006, 39.04, 0.0008, 40.03, 0.0003, 41.04, 0.0004, 42.04, 0.0005, 43.06, 0.0003, 44.02, 0.0004, 45.03, 0.0002, 46.08, 0.0001, 47.05, 0.0004, 48.03, 0.0002, 49.06, 0.0001, 50.05, 0.0003, 51.06, 0.0002, 52.07, 0.0002, 53.04, 0.0002, 54.05, 0.0001, 55.05, 0.0002, 56.05, 0.0001, 58.05, 0.0002, 59.06, 0.0001, 61.05, 0.0002] Tbf_cs3 = [1.00, 0.0192, 1.98, 0.0300, 2.99, 0.0565, 3.98, 0.0329, 4.97, 0.0791, 5.98, 0.0457, 6.96, 0.0053, 7.95, 0.0405, 8.96, 0.0260, 9.95, 0.0146, 10.93, 0.0283, 11.95, 0.0038, 12.93, 0.0205, 13.92, 0.0086, 14.93, 0.0028, 15.91, 0.0069, 16.91, 0.0030, 17.91, 0.0095, 18.89, 0.0058, 19.90, 0.0023, 20.89, 0.0048, 21.87, 0.0015, 22.89, 0.0033, 23.88, 0.0021, 24.87, 0.0003, 25.87, 0.0030, 26.86, 0.0014, 27.85, 0.0016, 28.86, 0.0021, 29.85, 0.0005, 30.83, 0.0019, 31.84, 0.0014, 32.83, 0.0005, 33.82, 0.0012, 34.82, 0.0006, 35.81, 0.0008, 36.82, 0.0011, 37.81, 0.0004, 38.78, 0.0004, 39.80, 0.0005, 40.79, 0.0004, 41.77, 0.0007, 42.77, 0.0002, 43.78, 0.0004, 44.76, 0.0005, 45.77, 0.0003, 46.76, 0.0003, 47.75, 0.0002, 48.75, 0.0002, 49.75, 0.0005, 50.74, 0.0002, 51.73, 0.0002, 52.73, 0.0002, 53.72, 0.0002, 54.73, 0.0003, 55.70, 0.0001, 56.70, 0.0001, 57.71, 0.0003, 58.71, 0.0001, 59.70, 0.0002, 60.70, 0.0001, 61.69, 0.0002, 62.69, 0.0003, 64.67, 0.0001, 65.67, 0.0001, 67.64, 0.0001, 69.65, 0.0001, 70.63, 0.0001, 75.62, 0.0001] Tbf_d3 = [1.01, 0.0462, 2.01, 0.0592, 3.00, 0.1127, 3.99, 0.0398, 5.00, 0.1221, 6.02, 0.0099, 7.01, 0.0396, 8.01, 0.0429, 9.00, 0.0249, 10.00, 0.0223, 10.27, 0.0015, 11.03, 0.0010, 12.01, 0.0146, 13.01, 0.0097, 14.00, 0.0008, 15.00, 0.0064, 16.01, 0.0020, 17.02, 0.0066, 18.02, 0.0043, 19.02, 0.0021, 20.01, 0.0035, 21.02, 0.0009, 22.02, 0.0022, 23.03, 0.0022, 24.00, 0.0007, 25.02, 0.0025, 26.02, 0.0002, 27.03, 0.0017, 27.30, 0.0003, 28.73, 0.0002, 29.03, 0.0016, 30.02, 0.0012, 31.02, 0.0006, 32.04, 0.0013, 33.04, 0.0005, 34.02, 0.0006, 35.01, 0.0004, 36.03, 0.0007, 37.03, 0.0009, 38.05, 0.0003, 39.05, 0.0006, 40.04, 0.0003, 41.04, 0.0003, 42.04, 0.0005, 43.05, 0.0002, 44.06, 0.0003, 45.05, 0.0001, 46.05, 0.0002, 47.04, 0.0003, 48.06, 0.0002, 49.06, 0.0003, 50.06, 0.0001, 51.06, 0.0001, 52.04, 0.0001, 53.06, 0.0001, 54.06, 0.0002, 57.06, 0.0001, 58.07, 0.0001, 59.06, 0.0002, 66.09, 0.0001] Tbf_ds3 = [1.00, 0.0462, 2.01, 0.0546, 3.03, 0.1220, 4.04, 0.0672, 5.06, 0.0575, 6.07, 0.0310, 7.08, 0.0402, 8.09, 0.0228, 9.09, 0.0345, 10.10, 0.0204, 11.11, 0.0134, 12.12, 0.0171, 13.13, 0.0056, 14.15, 0.0087, 15.16, 0.0035, 16.17, 0.0068, 17.18, 0.0027, 18.18, 0.0061, 19.20, 0.0018, 20.20, 0.0037, 21.22, 0.0030, 22.24, 0.0013, 23.24, 0.0028, 23.58, 0.0004, 24.91, 0.0002, 25.26, 0.0031, 26.26, 0.0008, 27.27, 0.0022, 28.28, 0.0021, 29.29, 0.0013, 30.31, 0.0017, 31.31, 0.0006, 32.34, 0.0015, 33.34, 0.0008, 34.35, 0.0012, 35.36, 0.0012, 36.36, 0.0008, 37.37, 0.0012, 38.38, 0.0006, 39.40, 0.0008, 40.39, 0.0002, 41.43, 0.0004, 42.44, 0.0003, 43.45, 0.0004, 44.45, 0.0004, 45.45, 0.0004, 46.46, 0.0006, 47.46, 0.0002, 48.48, 0.0004, 49.47, 0.0002, 50.52, 0.0003, 51.52, 0.0002, 52.53, 0.0003, 53.53, 0.0003, 54.54, 0.0002, 55.55, 0.0003, 57.58, 0.0002, 58.58, 0.0001, 59.60, 0.0002, 60.60, 0.0002, 61.62, 0.0002, 62.63, 0.0002, 63.62, 0.0001, 64.64, 0.0002, 66.67, 0.0001, 68.68, 0.0001, 69.70, 0.0001, 71.70, 0.0001] Tbf_e3 = [1.00, 0.0427, 2.02, 0.0329, 3.03, 0.0739, 4.03, 0.0442, 5.05, 0.0547, 6.06, 0.0547, 7.06, 0.0357, 8.07, 0.0307, 9.09, 0.0344, 10.10, 0.0088, 11.10, 0.0255, 12.12, 0.0049, 13.13, 0.0161, 14.13, 0.0032, 15.14, 0.0087, 16.16, 0.0028, 17.15, 0.0054, 18.17, 0.0018, 19.18, 0.0048, 20.20, 0.0025, 21.19, 0.0033, 22.21, 0.0032, 23.22, 0.0009, 24.22, 0.0017, 25.25, 0.0004, 26.24, 0.0011, 26.54, 0.0002, 27.27, 0.0002, 28.26, 0.0012, 28.54, 0.0002, 29.26, 0.0001, 30.29, 0.0009, 31.29, 0.0003, 32.30, 0.0007, 33.32, 0.0005, 34.32, 0.0007, 35.32, 0.0005, 36.35, 0.0004, 37.36, 0.0004, 38.38, 0.0002, 39.37, 0.0004, 41.39, 0.0004, 42.42, 0.0001, 43.40, 0.0002, 45.43, 0.0002, 47.45, 0.0002, 48.45, 0.0001, 49.46, 0.0001, 50.48, 0.0002, 51.49, 0.0001, 52.49, 0.0001, 54.52, 0.0001, 56.54, 0.0001] Tbf_f3 = [1.01, 0.0430, 2.02, 0.0658, 3.02, 0.0533, 4.02, 0.1351, 5.04, 0.0653, 6.03, 0.0900, 7.05, 0.0410, 8.05, 0.0344, 9.07, 0.0169, 10.07, 0.0220, 11.08, 0.0159, 12.08, 0.0180, 13.08, 0.0045, 14.09, 0.0098, 15.08, 0.0023, 16.10, 0.0022, 17.12, 0.0040, 18.12, 0.0030, 19.13, 0.0031, 20.14, 0.0014, 21.14, 0.0019, 22.15, 0.0012, 23.16, 0.0015, 24.16, 0.0007, 25.16, 0.0010, 26.17, 0.0009, 27.19, 0.0009, 28.19, 0.0004, 29.20, 0.0009, 30.19, 0.0002, 31.21, 0.0007, 32.23, 0.0003, 33.23, 0.0005, 35.24, 0.0004, 36.33, 0.0001, 37.25, 0.0003, 38.26, 0.0002, 39.27, 0.0003, 41.29, 0.0002, 42.29, 0.0001, 43.30, 0.0002, 45.31, 0.0001, 46.33, 0.0001] Tbf_fs3 = [1.00, 0.0676, 1.99, 0.0337, 3.00, 0.0651, 4.00, 0.0928, 4.99, 0.0773, 6.00, 0.0359, 6.99, 0.0266, 7.99, 0.0183, 9.00, 0.0246, 9.99, 0.0092, 10.98, 0.0144, 11.99, 0.0027, 12.98, 0.0112, 13.98, 0.0019, 14.99, 0.0058, 15.97, 0.0010, 16.97, 0.0024, 17.98, 0.0033, 18.97, 0.0025, 19.97, 0.0024, 20.98, 0.0018, 21.97, 0.0030, 22.98, 0.0013, 23.97, 0.0026, 24.19, 0.0004, 24.97, 0.0003, 25.97, 0.0026, 26.96, 0.0003, 27.96, 0.0018, 28.97, 0.0006, 29.96, 0.0012, 30.96, 0.0012, 31.97, 0.0011, 32.96, 0.0012, 33.95, 0.0006, 34.96, 0.0008, 35.95, 0.0003, 36.95, 0.0009, 37.95, 0.0002, 38.95, 0.0005, 39.95, 0.0002, 40.95, 0.0005, 41.95, 0.0003, 42.95, 0.0005, 43.95, 0.0002, 44.94, 0.0003, 45.95, 0.0003, 46.94, 0.0001, 47.94, 0.0002, 49.94, 0.0003, 50.94, 0.0001, 51.94, 0.0003, 53.93, 0.0002, 55.93, 0.0002, 56.93, 0.0001, 57.93, 0.0002, 58.93, 0.0001, 59.93, 0.0001, 60.93, 0.0001, 62.93, 0.0001, 64.91, 0.0001] Tbf_g3 = [1.01, 0.1108, 2.02, 0.0159, 3.03, 0.0749, 4.03, 0.0774, 5.05, 0.0554, 6.06, 0.0287, 7.06, 0.0529, 8.08, 0.0167, 9.09, 0.0172, 10.09, 0.0181, 11.10, 0.0072, 12.12, 0.0148, 13.11, 0.0028, 14.13, 0.0060, 15.14, 0.0012, 16.14, 0.0047, 17.15, 0.0034, 18.17, 0.0009, 19.17, 0.0041, 20.18, 0.0007, 21.20, 0.0016, 22.20, 0.0011, 23.21, 0.0022, 24.23, 0.0010, 25.24, 0.0008, 26.24, 0.0015, 27.25, 0.0003, 28.26, 0.0011, 29.26, 0.0009, 30.28, 0.0009, 31.29, 0.0007, 32.29, 0.0002, 33.31, 0.0005, 34.32, 0.0001, 35.32, 0.0006, 36.33, 0.0002, 37.35, 0.0003, 38.34, 0.0004, 40.37, 0.0003, 42.39, 0.0002, 43.40, 0.0002, 44.40, 0.0001, 45.41, 0.0002, 47.44, 0.0002, 50.47, 0.0001, 52.48, 0.0001, 54.49, 0.0001] Tbf_gs3 = [1.01, 0.0962, 2.01, 0.0925, 3.01, 0.0770, 4.03, 0.0479, 5.03, 0.1190, 6.03, 0.0237, 7.03, 0.0168, 8.05, 0.0283, 9.05, 0.0100, 10.05, 0.0292, 11.06, 0.0097, 12.07, 0.0103, 13.07, 0.0121, 14.07, 0.0042, 15.08, 0.0012, 16.09, 0.0051, 17.09, 0.0023, 18.09, 0.0058, 19.11, 0.0009, 20.11, 0.0029, 21.11, 0.0028, 22.12, 0.0011, 23.13, 0.0028, 24.12, 0.0013, 25.13, 0.0016, 26.14, 0.0014, 27.14, 0.0009, 28.15, 0.0016, 29.16, 0.0007, 30.16, 0.0007, 31.16, 0.0010, 32.17, 0.0004, 33.18, 0.0006, 34.18, 0.0005, 35.18, 0.0003, 36.19, 0.0006, 37.20, 0.0003, 38.20, 0.0003, 39.21, 0.0004, 40.22, 0.0002, 41.22, 0.0004, 42.23, 0.0001, 43.23, 0.0002, 44.24, 0.0002, 46.25, 0.0003, 47.25, 0.0001, 48.26, 0.0002, 49.26, 0.0001, 51.28, 0.0001, 54.29, 0.0001] Tbf_a3 = [0.99, 0.0880, 1.99, 0.1784, 2.99, 0.0966, 3.99, 0.0789, 4.99, 0.0440, 5.99, 0.0574, 6.99, 0.0067, 7.99, 0.0384, 8.98, 0.0270, 9.98, 0.0089, 10.97, 0.0152, 11.97, 0.0039, 12.97, 0.0092, 13.97, 0.0081, 14.97, 0.0020, 15.97, 0.0030, 16.96, 0.0051, 17.96, 0.0014, 18.96, 0.0031, 19.96, 0.0026, 20.95, 0.0004, 21.95, 0.0028, 22.95, 0.0006, 23.94, 0.0012, 24.94, 0.0021, 25.94, 0.0009, 26.94, 0.0010, 27.94, 0.0010, 28.94, 0.0006, 29.94, 0.0008, 30.93, 0.0009, 31.93, 0.0001, 32.92, 0.0007, 33.92, 0.0005, 34.91, 0.0002, 35.92, 0.0005, 36.91, 0.0003, 37.92, 0.0002, 38.92, 0.0004, 40.91, 0.0002, 41.90, 0.0002, 43.89, 0.0002, 44.89, 0.0002, 46.89, 0.0001, 49.89, 0.0001, 52.88, 0.0001] Tbf_as3 = [1.00, 0.0084, 2.02, 0.2204, 3.02, 0.1914, 4.03, 0.0999, 5.03, 0.0302, 6.04, 0.0574, 7.04, 0.0432, 8.05, 0.0168, 9.05, 0.0414, 10.06, 0.0213, 11.06, 0.0024, 12.07, 0.0063, 13.08, 0.0058, 14.08, 0.0014, 15.09, 0.0031, 16.09, 0.0067, 17.10, 0.0026, 18.10, 0.0026, 19.11, 0.0039, 20.11, 0.0016, 21.12, 0.0015, 22.12, 0.0032, 23.13, 0.0017, 24.13, 0.0010, 25.14, 0.0020, 26.14, 0.0016, 27.15, 0.0002, 28.16, 0.0013, 29.16, 0.0009, 31.17, 0.0009, 32.18, 0.0008, 33.18, 0.0004, 34.19, 0.0005, 35.19, 0.0008, 36.20, 0.0002, 37.20, 0.0004, 38.21, 0.0005, 39.21, 0.0002, 40.22, 0.0002, 41.22, 0.0003, 42.23, 0.0002, 43.23, 0.0001, 44.24, 0.0002, 45.25, 0.0001, 47.26, 0.0002, 48.26, 0.0001, 50.28, 0.0001, 51.28, 0.0001] Tbf_b3 = [1.00, 0.0475, 2.00, 0.1146, 3.01, 0.1513, 4.01, 0.0759, 5.00, 0.0441, 6.01, 0.0348, 7.01, 0.0462, 8.01, 0.0291, 9.02, 0.0056, 10.02, 0.0281, 11.01, 0.0178, 12.02, 0.0016, 13.02, 0.0054, 14.02, 0.0082, 15.03, 0.0051, 16.02, 0.0014, 17.02, 0.0053, 18.03, 0.0050, 19.03, 0.0017, 20.03, 0.0024, 21.04, 0.0037, 22.03, 0.0025, 23.03, 0.0008, 24.04, 0.0028, 25.04, 0.0023, 26.04, 0.0007, 27.04, 0.0007, 28.04, 0.0018, 29.04, 0.0017, 30.05, 0.0003, 31.04, 0.0011, 32.04, 0.0013, 33.05, 0.0004, 34.05, 0.0005, 35.05, 0.0009, 36.06, 0.0007, 37.05, 0.0002, 38.06, 0.0004, 39.06, 0.0006, 40.06, 0.0004, 41.07, 0.0003, 42.06, 0.0005, 43.06, 0.0004, 44.07, 0.0001, 45.07, 0.0003, 46.07, 0.0003, 47.08, 0.0001, 48.07, 0.0001, 49.07, 0.0003, 50.08, 0.0002, 52.08, 0.0001, 53.08, 0.0001] Tbf_c4 = [1.01, 0.0092, 2.01, 0.0918, 3.01, 0.1218, 4.03, 0.1524, 5.03, 0.0561, 6.03, 0.0196, 7.05, 0.0312, 8.05, 0.0481, 9.05, 0.0292, 10.07, 0.0048, 11.07, 0.0035, 12.07, 0.0096, 13.08, 0.0079, 14.09, 0.0040, 15.09, 0.0017, 16.09, 0.0054, 17.11, 0.0080, 18.11, 0.0039, 19.11, 0.0010, 20.13, 0.0034, 21.13, 0.0028, 22.13, 0.0027, 23.14, 0.0004, 24.15, 0.0015, 25.15, 0.0024, 26.16, 0.0021, 27.17, 0.0006, 28.17, 0.0008, 29.17, 0.0013, 30.19, 0.0015, 31.19, 0.0005, 32.19, 0.0002, 33.21, 0.0009, 34.21, 0.0010, 35.21, 0.0006, 36.23, 0.0003, 37.23, 0.0005, 38.23, 0.0009, 39.24, 0.0007, 40.25, 0.0002, 41.25, 0.0004, 42.26, 0.0006, 43.27, 0.0004, 44.27, 0.0002, 45.27, 0.0003, 46.29, 0.0004, 47.29, 0.0003, 48.29, 0.0001] Tbf_cs4 = [1.00, 0.0881, 2.00, 0.1170, 3.00, 0.0852, 4.00, 0.0643, 5.00, 0.0778, 6.00, 0.0489, 6.99, 0.0269, 8.00, 0.0107, 8.99, 0.0292, 10.00, 0.0159, 10.99, 0.0082, 12.00, 0.0066, 12.99, 0.0009, 14.00, 0.0050, 14.99, 0.0064, 15.99, 0.0059, 17.00, 0.0044, 17.99, 0.0024, 19.00, 0.0042, 19.99, 0.0040, 21.00, 0.0027, 21.99, 0.0023, 22.99, 0.0018, 23.99, 0.0024, 24.99, 0.0025, 25.99, 0.0019, 26.99, 0.0007, 27.99, 0.0004, 28.99, 0.0012, 29.99, 0.0014, 30.99, 0.0012, 31.99, 0.0004, 32.99, 0.0002, 33.99, 0.0007, 34.98, 0.0009, 35.99, 0.0008, 36.98, 0.0005, 37.99, 0.0002, 38.98, 0.0005, 39.99, 0.0007, 40.98, 0.0007, 41.98, 0.0004, 42.98, 0.0001, 43.98, 0.0003, 44.99, 0.0004, 45.98, 0.0003] Tbf_d4 = [1.01, 0.1228, 2.02, 0.1247, 3.02, 0.1142, 4.03, 0.0474, 5.04, 0.0335, 6.04, 0.0332, 7.05, 0.0302, 8.06, 0.0222, 9.07, 0.0090, 10.08, 0.0030, 11.09, 0.0027, 12.09, 0.0054, 13.10, 0.0059, 14.10, 0.0040, 15.11, 0.0038, 16.12, 0.0029, 17.13, 0.0011, 18.14, 0.0020, 19.15, 0.0021, 20.15, 0.0023, 21.16, 0.0016, 22.17, 0.0012, 23.17, 0.0008, 24.18, 0.0003, 25.19, 0.0006, 26.20, 0.0008, 27.21, 0.0008, 28.22, 0.0008, 29.22, 0.0004, 30.23, 0.0002, 31.23, 0.0002, 32.24, 0.0003, 33.26, 0.0004, 34.26, 0.0004, 35.27, 0.0004, 36.28, 0.0002, 39.29, 0.0002, 40.30, 0.0002, 41.32, 0.0001] Tbf_ds4 = [1.01, 0.1133, 2.01, 0.1562, 3.02, 0.1429, 4.02, 0.0366, 5.02, 0.0219, 6.03, 0.0212, 7.03, 0.0142, 8.04, 0.0216, 9.04, 0.0101, 10.04, 0.0063, 11.05, 0.0076, 12.05, 0.0081, 13.06, 0.0050, 14.06, 0.0030, 15.07, 0.0010, 16.07, 0.0011, 17.07, 0.0019, 18.08, 0.0022, 19.08, 0.0029, 20.09, 0.0028, 21.09, 0.0021, 22.09, 0.0016, 23.10, 0.0016, 24.10, 0.0010, 25.11, 0.0005, 26.11, 0.0003, 27.11, 0.0002, 28.12, 0.0006, 29.12, 0.0004, 30.13, 0.0005, 31.13, 0.0004, 32.13, 0.0006, 33.14, 0.0003, 34.14, 0.0003, 35.15, 0.0002, 37.15, 0.0002, 38.15, 0.0001, 39.16, 0.0002, 40.16, 0.0002, 41.17, 0.0002] Tbf_e4 = [0.99, 0.0906, 1.99, 0.1338, 2.99, 0.1235, 3.98, 0.0833, 4.98, 0.0601, 5.98, 0.0264, 6.98, 0.0126, 7.97, 0.0051, 8.97, 0.0026, 9.97, 0.0014, 10.96, 0.0018, 11.96, 0.0025, 12.96, 0.0031, 13.96, 0.0021, 14.95, 0.0034, 15.95, 0.0035, 16.95, 0.0037, 17.94, 0.0031, 18.94, 0.0021, 19.93, 0.0021, 20.93, 0.0016, 21.92, 0.0010, 22.92, 0.0012, 23.92, 0.0011, 24.91, 0.0007, 25.91, 0.0004, 26.91, 0.0002, 28.91, 0.0001, 30.89, 0.0001, 31.90, 0.0002, 32.90, 0.0002, 33.89, 0.0002, 34.89, 0.0002, 35.88, 0.0002, 36.88, 0.0002, 37.88, 0.0002, 38.87, 0.0001] Tbf_f4 = [1.01, 0.1228, 2.01, 0.3008, 3.01, 0.1922, 4.01, 0.0927, 5.01, 0.0581, 6.02, 0.0447, 7.02, 0.0207, 8.03, 0.0106, 9.02, 0.0057, 10.02, 0.0018, 11.03, 0.0040, 12.03, 0.0041, 13.04, 0.0040, 14.04, 0.0039, 15.04, 0.0042, 16.04, 0.0034, 17.05, 0.0035, 18.05, 0.0038, 19.06, 0.0033, 20.06, 0.0029, 21.06, 0.0024, 22.06, 0.0020, 23.07, 0.0018, 24.07, 0.0015, 25.07, 0.0012, 26.07, 0.0009, 27.07, 0.0006, 28.08, 0.0005, 29.08, 0.0003, 30.09, 0.0003, 31.10, 0.0003, 32.10, 0.0004, 33.11, 0.0004, 34.11, 0.0004, 35.10, 0.0004, 36.10, 0.0004, 37.11, 0.0003, 38.11, 0.0002] Tbf_fs4 = [1.01, 0.0765, 2.01, 0.2561, 3.02, 0.0803, 4.03, 0.0653, 5.03, 0.0230, 6.04, 0.0093, 7.05, 0.0035, 8.05, 0.0042, 9.06, 0.0040, 10.07, 0.0052, 11.07, 0.0056, 12.08, 0.0049, 13.09, 0.0039, 14.09, 0.0035, 15.10, 0.0031, 16.10, 0.0021, 17.11, 0.0012, 18.12, 0.0010, 19.12, 0.0005, 20.13, 0.0003, 21.14, 0.0001, 22.14, 0.0001, 23.15, 0.0003, 24.16, 0.0002, 25.16, 0.0003, 26.17, 0.0003, 27.18, 0.0003, 28.18, 0.0003, 29.19, 0.0003, 30.20, 0.0002, 31.20, 0.0001] Tbf_g4 = [1.01, 0.0092, 2.02, 0.2167, 3.02, 0.0668, 4.02, 0.0254, 5.03, 0.0210, 6.04, 0.0282, 7.04, 0.0151, 8.05, 0.0130, 9.05, 0.0054, 10.06, 0.0031, 11.07, 0.0014, 12.08, 0.0020, 13.08, 0.0020, 14.09, 0.0020, 15.09, 0.0021, 16.10, 0.0015, 17.10, 0.0007, 18.11, 0.0003, 19.13, 0.0002, 20.13, 0.0004, 21.13, 0.0005, 22.14, 0.0004, 23.14, 0.0003, 24.15, 0.0003, 25.15, 0.0001, 29.18, 0.0001, 30.19, 0.0001] Tbf_gs4 = [1.00, 0.1758, 2.01, 0.1249, 3.01, 0.0253, 4.02, 0.0471, 5.02, 0.0478, 6.03, 0.0217, 7.03, 0.0025, 8.04, 0.0044, 9.05, 0.0066, 10.05, 0.0060, 11.05, 0.0030, 12.06, 0.0021, 13.09, 0.0005, 14.07, 0.0008, 15.07, 0.0014, 16.08, 0.0010, 17.08, 0.0005, 18.10, 0.0002, 19.09, 0.0003, 20.10, 0.0003, 21.10, 0.0003, 22.10, 0.0001, 24.13, 0.0001, 25.13, 0.0001, 26.13, 0.0001] Tbf_a4 = [1.00, 0.3944, 2.01, 0.1441, 3.00, 0.0979, 4.01, 0.0595, 5.01, 0.0218, 6.01, 0.0057, 7.01, 0.0131, 8.01, 0.0053, 9.01, 0.0018, 10.02, 0.0029, 11.01, 0.0042, 12.02, 0.0032, 13.01, 0.0001, 14.02, 0.0014, 15.02, 0.0017, 16.02, 0.0006, 17.03, 0.0003, 18.02, 0.0006, 19.03, 0.0009, 20.03, 0.0003, 21.04, 0.0002, 22.03, 0.0004, 23.03, 0.0004, 25.04, 0.0002, 26.04, 0.0003, 27.04, 0.0001] Tbf_as4 = [1.01, 0.3895, 2.03, 0.1550, 3.03, 0.0985, 4.05, 0.0153, 5.06, 0.0280, 6.07, 0.0103, 7.08, 0.0028, 8.10, 0.0069, 9.10, 0.0023, 10.12, 0.0025, 11.13, 0.0029, 12.14, 0.0011, 13.15, 0.0011, 14.16, 0.0009, 15.17, 0.0002, 16.19, 0.0007, 17.20, 0.0004, 18.22, 0.0002, 19.22, 0.0003, 20.23, 0.0001, 22.26, 0.0001] Tbf_b4 = [1.00, 0.2165, 2.01, 0.1597, 3.00, 0.0717, 4.01, 0.0353, 5.01, 0.0332, 6.01, 0.0024, 7.01, 0.0088, 8.02, 0.0009, 9.02, 0.0039, 10.02, 0.0016, 11.02, 0.0015, 12.02, 0.0014, 13.03, 0.0003, 14.03, 0.0007, 16.03, 0.0004, 17.04, 0.0002, 18.03, 0.0002, 19.04, 0.0001] Tbf_c5 = [1.01, 0.1699, 2.01, 0.2670, 3.03, 0.0349, 4.03, 0.0454, 5.05, 0.0024, 6.05, 0.0069, 7.06, 0.0021, 8.07, 0.0015, 9.08, 0.0011, 10.09, 0.0007, 11.09, 0.0007, 12.10, 0.0001, 13.11, 0.0004, 15.13, 0.0002] Tbf_cs5 = [1.00, 0.2017, 2.00, 0.0920, 3.00, 0.0598, 3.99, 0.0086, 4.99, 0.0120, 5.99, 0.0063, 6.99, 0.0034, 7.99, 0.0029, 8.99, 0.0008, 9.99, 0.0014, 10.98, 0.0008, 11.97, 0.0007, 12.98, 0.0006, 13.96, 0.0001, 14.97, 0.0003, 15.97, 0.0001] # # # # # Tbp_e2 = [1.00, 0.0179, 2.00, 0.0770, 2.99, 0.0532, 3.99, 0.0183, 4.97, 0.0494, 5.98, 0.0137, 6.95, 0.0121, 7.97, 0.0153, 8.94, 0.0012, 9.96, 0.0040, 10.97, 0.0030, 11.93, 0.0021, 12.93, 0.0034, 13.94, 0.0007, 14.91, 0.0004, 16.01, 0.0002, 16.93, 0.0003, 17.92, 0.0008, 18.94, 0.0004, 19.96, 0.0002, 21.00, 0.0001, 22.95, 0.0001, 25.89, 0.0001] Tbp_f2 = [0.99, 0.0137, 2.01, 0.0473, 3.03, 0.0362, 4.01, 0.0117, 5.02, 0.0565, 6.04, 0.0247, 7.06, 0.0348, 8.04, 0.0251, 9.05, 0.0143, 10.07, 0.0146, 11.09, 0.0020, 12.07, 0.0048, 13.09, 0.0013, 14.12, 0.0012, 15.12, 0.0009, 16.12, 0.0004, 17.10, 0.0010, 18.11, 0.0003, 19.13, 0.0004, 20.13, 0.0001, 22.14, 0.0001, 24.17, 0.0001] Tbp_fs2 = [1.02, 0.0110, 2.02, 0.0470, 3.02, 0.0038, 4.02, 0.0343, 5.01, 0.0442, 6.02, 0.0198, 7.01, 0.0600, 8.02, 0.0144, 9.05, 0.0468, 10.05, 0.0112, 11.05, 0.0137, 12.05, 0.0078, 13.05, 0.0041, 14.05, 0.0040, 15.05, 0.0012, 16.05, 0.0018, 17.05, 0.0007, 18.08, 0.0011, 19.08, 0.0003, 20.09, 0.0005, 21.08, 0.0004, 22.08, 0.0002, 23.07, 0.0003, 25.07, 0.0001] Tbp_g2 = [1.01, 0.0148, 2.00, 0.0544, 3.02, 0.0144, 4.01, 0.0848, 5.03, 0.0334, 6.02, 0.0703, 7.01, 0.0546, 8.03, 0.0242, 9.02, 0.0235, 10.04, 0.0054, 11.02, 0.0079, 12.04, 0.0009, 13.03, 0.0032, 14.02, 0.0011, 15.04, 0.0013, 16.02, 0.0005, 17.06, 0.0005, 18.01, 0.0001, 19.01, 0.0002, 20.07, 0.0002, 21.08, 0.0001] Tbp_gs2 = [0.99, 0.0357, 2.00, 0.0505, 3.00, 0.0158, 3.99, 0.0999, 4.99, 0.0473, 6.00, 0.0633, 7.00, 0.0187, 7.98, 0.0536, 8.99, 0.0153, 9.99, 0.0238, 10.98, 0.0049, 11.98, 0.0045, 12.99, 0.0018, 13.98, 0.0031, 14.97, 0.0011, 15.97, 0.0009, 16.98, 0.0005, 17.97, 0.0007, 18.97, 0.0006, 19.95, 0.0003, 20.96, 0.0001] Tbp_a2 = [1.00, 0.0295, 1.99, 0.1044, 2.98, 0.0380, 3.96, 0.1223, 4.95, 0.0652, 5.93, 0.0906, 6.93, 0.0212, 7.91, 0.0492, 8.91, 0.0034, 9.88, 0.0180, 10.87, 0.0036, 11.86, 0.0050, 12.85, 0.0005, 13.85, 0.0016, 14.84, 0.0009, 15.81, 0.0014, 16.80, 0.0002, 17.77, 0.0003, 20.73, 0.0001, 21.73, 0.0002, 22.73, 0.0002, 24.70, 0.0001] Tbp_as2 = [1.00, 0.0228, 2.01, 0.0987, 3.02, 0.0160, 4.03, 0.0517, 5.03, 0.0818, 6.04, 0.0522, 7.06, 0.0447, 8.06, 0.0171, 9.07, 0.0228, 10.06, 0.0032, 11.08, 0.0065, 12.06, 0.0008, 13.09, 0.0023, 14.11, 0.0008, 15.09, 0.0004, 16.11, 0.0004, 17.10, 0.0003, 18.13, 0.0002, 20.07, 0.0001] Tbp_b2 = [1.01, 0.0076, 1.99, 0.0810, 2.98, 0.0345, 3.98, 0.0341, 4.99, 0.0653, 5.99, 0.0085, 6.96, 0.0538, 7.97, 0.0030, 8.97, 0.0204, 9.96, 0.0059, 10.95, 0.0026, 11.96, 0.0028, 12.96, 0.0006, 13.94, 0.0014, 14.92, 0.0002, 15.94, 0.0007, 16.95, 0.0002] Tbp_c3 = [1.02, 0.0300, 2.02, 0.0703, 3.03, 0.1222, 4.04, 0.0495, 5.04, 0.0810, 6.04, 0.0372, 7.05, 0.0371, 8.06, 0.0353, 9.08, 0.0026, 10.09, 0.0078, 11.10, 0.0065, 12.11, 0.0027, 13.11, 0.0030, 14.12, 0.0006, 15.12, 0.0013, 16.13, 0.0006, 17.14, 0.0002, 18.16, 0.0002, 19.18, 0.0001, 20.19, 0.0001, 21.19, 0.0001] Tbp_cs3 = [0.99, 0.0466, 1.97, 0.0094, 2.97, 0.0953, 3.95, 0.0427, 4.96, 0.0520, 5.94, 0.0187, 6.94, 0.0127, 7.92, 0.0075, 8.90, 0.0015, 9.90, 0.0017, 10.88, 0.0009, 11.89, 0.0002, 12.85, 0.0002] Tbp_d3 = [1.01, 0.0634, 2.02, 0.0187, 3.02, 0.0987, 4.02, 0.0742, 5.02, 0.0182, 6.03, 0.0331, 7.03, 0.0132, 8.03, 0.0025, 9.04, 0.0026, 10.06, 0.0016, 11.07, 0.0002, 12.08, 0.0001] Tbp_ds3 = [1.01, 0.1106, 2.01, 0.0100, 3.00, 0.0866, 4.00, 0.0859, 5.00, 0.0217, 6.00, 0.0251, 6.99, 0.0134, 7.99, 0.0022, 8.99, 0.0026, 9.99, 0.0021, 11.00, 0.0005, 14.99, 0.0001, 16.99, 0.0001] Tbp_e3 = [1.00, 0.1452, 1.99, 0.0464, 2.98, 0.0553, 3.97, 0.1114, 4.96, 0.0181, 5.95, 0.0077, 6.94, 0.0033, 7.93, 0.0043, 8.92, 0.0023, 9.92, 0.0003, 10.90, 0.0006, 11.89, 0.0003, 14.88, 0.0001, 15.87, 0.0002, 19.83, 0.0001] Tbp_f3 = [0.99, 0.0923, 2.00, 0.0191, 3.00, 0.0745, 3.99, 0.1014, 5.00, 0.0547, 6.00, 0.0129, 6.99, 0.0032, 8.00, 0.0023, 9.00, 0.0018, 9.98, 0.0007, 10.38, 0.0001, 12.98, 0.0001] Tbp_fs3 = [1.01, 0.0781, 2.00, 0.0346, 2.99, 0.0441, 4.01, 0.0196, 5.00, 0.0310, 5.99, 0.0213, 7.00, 0.0062, 7.99, 0.0021, 9.00, 0.0003, 9.99, 0.0002] Tbp_g3 = [1.01, 0.0733, 2.03, 0.0883, 3.03, 0.0772, 4.05, 0.0148, 5.06, 0.0055, 6.06, 0.0033, 7.09, 0.0026, 8.09, 0.0015, 9.11, 0.0003, 10.12, 0.0002] Tbp_gs3 = [1.02, 0.0885, 2.03, 0.1115, 3.05, 0.0480, 4.06, 0.0466, 5.07, 0.0106, 6.09, 0.0018, 7.10, 0.0009] Tbp_a3 = [1.01, 0.1416, 2.02, 0.1418, 3.02, 0.0683, 4.03, 0.0464, 5.04, 0.0178, 6.04, 0.0037, 7.06, 0.0018, 8.07, 0.0006, 9.05, 0.0004] Tbp_as3 = [1.01, 0.1361, 2.01, 0.0839, 3.00, 0.0761, 4.00, 0.0211, 5.00, 0.0045, 6.00, 0.0018, 7.00, 0.0004] Tbp_b3 = [1.01, 0.0960, 2.01, 0.0594, 3.01, 0.0315, 4.01, 0.0078, 5.01, 0.0021, 6.01, 0.0009, 7.02, 0.0005, 8.03, 0.0003] Tbp_c4 = [1.00, 0.0855, 2.00, 0.1172, 3.00, 0.0276, 4.00, 0.0135, 5.00, 0.0053, 6.00, 0.0021, 6.99, 0.0003] Tbp_cs4 = [1.01, 0.0033, 2.00, 0.0982, 2.99, 0.0491, 3.99, 0.0185, 4.99, 0.0043, 5.98, 0.0004, 6.99, 0.0001] Tbp_d4 = [1.01, 0.0485, 2.01, 0.1552, 3.01, 0.0547, 4.01, 0.0136, 5.03, 0.0026, 6.04, 0.0010, 7.05, 0.0001] Tbp_ds4 = [1.01, 0.0030, 2.01, 0.1892, 3.01, 0.0563, 4.01, 0.0025, 5.02, 0.0034, 5.97, 0.0001, 7.03, 0.0003] Tbp_e4 = [1.01, 0.0508, 2.02, 0.0934, 3.02, 0.0147, 4.03, 0.0111, 5.05, 0.0014, 6.06, 0.0014, 8.08, 0.0001] Tbp_f4 = [1.00, 0.0260, 2.02, 0.2047, 3.02, 0.0550, 4.03, 0.0165, 5.04, 0.0051, 6.04, 0.0005, 7.05, 0.0002] Tbp_fs4 = [1.02, 0.0971, 2.03, 0.0635, 3.04, 0.0254, 4.05, 0.0023, 5.07, 0.0002, 6.08, 0.0003, 7.09, 0.0001] Tbp_g4 = [1.02, 0.3176, 2.03, 0.0734, 3.04, 0.0332, 4.05, 0.0152, 5.06, 0.0048, 6.08, 0.0007] Tbp_gs4 = [1.01, 0.3321, 2.01, 0.1320, 3.01, 0.0072, 4.02, 0.0028, 5.03, 0.0009, 6.04, 0.0002, 7.04, 0.0002] Tbp_a4 = [1.00, 0.5149, 2.00, 0.2025, 3.00, 0.0392, 3.99, 0.0117, 4.99, 0.0035, 5.99, 0.0008, 6.99, 0.0002, 7.98, 0.0001] Tbp_as4 = [1.01, 0.3188, 2.01, 0.2130, 3.02, 0.0427, 4.03, 0.0024, 5.05, 0.0004, 6.05, 0.0007, 7.06, 0.0002, 8.06, 0.0002] Tbp_b4 = [1.00, 0.1685, 1.99, 0.0732, 2.99, 0.0056, 3.99, 0.0042, 4.99, 0.0009, 5.99, 0.0005] Tbp_c5 = [1.01, 0.3386, 2.02, 0.0634, 3.02, 0.0212, 4.03, 0.0019, 5.04, 0.0004] Tbp_cs5 = [1.00, 0.2958, 2.00, 0.0843, 3.01, 0.0058, 4.01, 0.0027, 5.01, 0.0003] Tbp_d5 = [1.00, 0.4237, 2.01, 0.0453, 3.01, 0.0045, 4.02, 0.0007, 5.02, 0.0004] # # # # # trumpet Trp_fs3 = [1.01, 0.0533, 2.03, 0.0559, 3.05, 0.0505, 4.06, 0.0542, 5.08, 0.0382, 6.10, 0.0570, 7.12, 0.0321, 8.14, 0.0393, 9.15, 0.0277, 10.17, 0.0157, 11.19, 0.0165, 12.20, 0.0152, 13.22, 0.0081, 14.23, 0.0089, 15.24, 0.0035, 16.26, 0.0045, 17.28, 0.0052, 18.29, 0.0020, 19.31, 0.0021, 20.33, 0.0017, 21.35, 0.0014, 22.37, 0.0010, 23.38, 0.0009, 24.40, 0.0004, 25.42, 0.0005, 26.44, 0.0004, 27.45, 0.0004, 28.46, 0.0004, 29.48, 0.0002, 30.49, 0.0002, 31.51, 0.0002, 32.53, 0.0001, 33.55, 0.0001] Trp_g3 = [0.99, 0.0459, 1.99, 0.0931, 3.00, 0.0517, 4.00, 0.0496, 5.00, 0.0576, 6.00, 0.0452, 7.00, 0.0263, 8.00, 0.0125, 9.01, 0.0131, 10.01, 0.0136, 11.00, 0.0066, 12.00, 0.0081, 13.00, 0.0032, 14.00, 0.0039, 14.99, 0.0026, 16.00, 0.0017, 16.99, 0.0017, 17.99, 0.0009, 19.01, 0.0013, 20.01, 0.0008, 21.01, 0.0006, 22.00, 0.0006, 23.00, 0.0003, 24.01, 0.0004, 25.01, 0.0003, 26.01, 0.0002, 27.02, 0.0002, 28.02, 0.0001, 29.02, 0.0001, 31.04, 0.0001] Trp_gs3 = [0.99, 0.0455, 1.99, 0.0969, 2.97, 0.0487, 3.97, 0.0296, 4.97, 0.0186, 5.95, 0.0219, 6.95, 0.0075, 7.94, 0.0176, 8.93, 0.0202, 9.93, 0.0175, 10.91, 0.0156, 11.91, 0.0097, 12.91, 0.0066, 13.89, 0.0065, 14.89, 0.0051, 15.88, 0.0037, 16.86, 0.0015, 17.87, 0.0016, 18.85, 0.0010, 19.85, 0.0006, 20.84, 0.0006, 21.84, 0.0006, 22.84, 0.0005, 23.82, 0.0003, 24.82, 0.0003, 25.80, 0.0002, 26.79, 0.0002, 27.79, 0.0001, 28.79, 0.0001] Trp_a3 = [0.99, 0.0420, 1.99, 0.0954, 2.99, 0.0579, 3.99, 0.0722, 4.98, 0.0813, 5.98, 0.0399, 6.98, 0.0379, 7.98, 0.0181, 8.98, 0.0188, 9.98, 0.0147, 10.97, 0.0100, 11.97, 0.0091, 12.96, 0.0048, 13.96, 0.0091, 14.96, 0.0048, 15.96, 0.0016, 16.96, 0.0027, 17.97, 0.0020, 18.96, 0.0014, 19.96, 0.0007, 20.95, 0.0007, 21.95, 0.0006, 22.94, 0.0003, 23.95, 0.0005, 24.95, 0.0002, 25.95, 0.0002, 26.95, 0.0002, 27.96, 0.0002, 28.95, 0.0002, 29.94, 0.0001] Trp_as3 = [1.01, 0.0487, 2.01, 0.0236, 3.01, 0.0599, 4.01, 0.0397, 5.01, 0.0525, 6.01, 0.0426, 7.00, 0.0144, 8.01, 0.0134, 9.01, 0.0274, 10.01, 0.0087, 11.01, 0.0041, 12.00, 0.0052, 13.01, 0.0080, 14.01, 0.0028, 15.02, 0.0022, 16.01, 0.0014, 17.04, 0.0005, 18.04, 0.0003, 19.03, 0.0005, 20.02, 0.0003, 21.02, 0.0003, 22.02, 0.0003, 23.03, 0.0002, 24.03, 0.0002, 25.02, 0.0001] Trp_b3 = [1.00, 0.0534, 2.00, 0.0362, 3.00, 0.0698, 4.00, 0.0793, 4.99, 0.0301, 6.00, 0.0216, 7.00, 0.0130, 8.00, 0.0151, 9.00, 0.0172, 10.00, 0.0062, 11.00, 0.0041, 11.99, 0.0022, 13.00, 0.0017, 14.00, 0.0012, 14.99, 0.0013, 15.95, 0.0002, 16.99, 0.0001, 18.00, 0.0003, 19.00, 0.0003, 20.00, 0.0003, 21.01, 0.0001] Trp_c4 = [1.01, 0.0410, 2.03, 0.0543, 3.03, 0.0487, 4.04, 0.0354, 5.05, 0.0408, 6.06, 0.0221, 7.08, 0.0099, 8.09, 0.0248, 9.09, 0.0107, 10.11, 0.0037, 11.11, 0.0087, 12.13, 0.0035, 13.14, 0.0012, 14.16, 0.0013, 15.17, 0.0002, 16.18, 0.0002, 17.19, 0.0003, 18.20, 0.0002, 19.21, 0.0002, 20.22, 0.0002, 21.23, 0.0001, 22.24, 0.0001] Trp_cs4 = [1.01, 0.0199, 2.03, 0.0437, 3.03, 0.0142, 4.04, 0.0534, 5.04, 0.0310, 6.06, 0.0194, 7.06, 0.0124, 8.06, 0.0071, 9.07, 0.0061, 10.06, 0.0037, 11.09, 0.0022, 12.12, 0.0007, 13.11, 0.0005, 14.12, 0.0003, 15.10, 0.0002, 16.12, 0.0002, 17.13, 0.0001, 18.13, 0.0001] Trp_d4 = [1.01, 0.0320, 2.02, 0.0510, 3.04, 0.0747, 4.05, 0.0619, 5.06, 0.0404, 6.07, 0.0195, 7.08, 0.0221, 8.09, 0.0112, 9.11, 0.0073, 10.13, 0.0031, 11.13, 0.0026, 12.15, 0.0017, 13.16, 0.0013, 14.17, 0.0009, 15.18, 0.0007, 16.18, 0.0004, 17.19, 0.0003, 18.22, 0.0002, 19.23, 0.0002, 20.23, 0.0002, 21.25, 0.0001] Trp_ds4 = [1.00, 0.0471, 2.01, 0.0466, 3.02, 0.0304, 4.02, 0.0166, 5.02, 0.0187, 6.02, 0.0086, 7.03, 0.0064, 8.03, 0.0067, 9.03, 0.0033, 10.02, 0.0016, 11.05, 0.0013, 12.06, 0.0008, 13.06, 0.0005, 14.05, 0.0002, 15.04, 0.0002, 16.05, 0.0002, 17.05, 0.0001] Trp_e4 = [1.01, 0.0365, 2.01, 0.0352, 3.02, 0.0462, 4.02, 0.0230, 5.02, 0.0092, 6.02, 0.0078, 7.02, 0.0059, 8.04, 0.0034, 9.04, 0.0011, 10.05, 0.0010, 11.07, 0.0003, 12.07, 0.0003, 13.06, 0.0002, 14.06, 0.0001, 15.07, 0.0001] Trp_f4 = [1.00, 0.0412, 2.00, 0.0621, 3.00, 0.0180, 3.99, 0.0631, 4.99, 0.0245, 5.99, 0.0369, 6.99, 0.0093, 7.99, 0.0126, 8.99, 0.0027, 9.99, 0.0035, 10.99, 0.0021, 11.99, 0.0016, 12.99, 0.0010, 13.98, 0.0009, 14.98, 0.0006, 15.98, 0.0004, 16.98, 0.0002] Trp_fs4 = [0.99, 0.0581, 1.98, 0.0494, 2.98, 0.0614, 3.97, 0.0316, 4.96, 0.0151, 5.96, 0.0095, 6.95, 0.0022, 7.93, 0.0022, 8.93, 0.0013, 9.94, 0.0008, 10.93, 0.0003, 11.92, 0.0002, 12.92, 0.0001, 13.93, 0.0001] Trp_g4 = [1.00, 0.0979, 1.99, 0.0344, 2.99, 0.0374, 3.99, 0.0179, 4.98, 0.0148, 5.98, 0.0059, 6.98, 0.0029, 7.95, 0.0005, 8.97, 0.0004, 9.97, 0.0002, 10.96, 0.0002] Trp_gs4 = [1.00, 0.0670, 2.00, 0.0138, 3.00, 0.0100, 4.01, 0.0076, 4.99, 0.0070, 5.99, 0.0037, 6.97, 0.0023, 7.97, 0.0007, 8.97, 0.0002, 9.98, 0.0001, 10.97, 0.0002] Trp_a4 = [1.00, 0.0403, 2.01, 0.0211, 3.00, 0.0107, 4.00, 0.0052, 4.99, 0.0022, 6.00, 0.0013, 7.00, 0.0006, 8.01, 0.0002, 9.02, 0.0001, 10.03, 0.0001] Trp_as4 = [1.00, 0.0128, 2.01, 0.0154, 3.00, 0.0269, 3.99, 0.0098, 4.99, 0.0021, 5.98, 0.0016, 6.99, 0.0004, 8.00, 0.0003, 9.02, 0.0002] Trp_b4 = [1.01, 0.0287, 2.01, 0.0583, 3.01, 0.0386, 4.00, 0.0098, 5.01, 0.0068, 6.02, 0.0012, 7.02, 0.0012, 8.03, 0.0003, 9.02, 0.0003, 10.01, 0.0001] Trp_c5 = [1.01, 0.0190, 2.01, 0.0057, 3.01, 0.0039, 4.01, 0.0051, 5.03, 0.0005, 6.02, 0.0002, 7.03, 0.0001] Trp_cs5 = [1.01, 0.0087, 2.01, 0.0050, 3.01, 0.0011, 4.01, 0.0002] Trp_d5 = [1.01, 0.0145, 2.01, 0.0098, 3.01, 0.0013, 4.01, 0.0003] Trp_ds5 = [1.00, 0.0231, 2.00, 0.0053, 2.98, 0.0077, 3.97, 0.0021, 4.96, 0.0003, 6.98, 0.0001] Trp_e5 = [1.01, 0.0520, 2.02, 0.0187, 3.00, 0.0009, 4.04, 0.0011, 5.02, 0.0001] Trp_f5 = [1.02, 0.0332, 2.02, 0.0074, 3.03, 0.0031] Trp_fs5 = [1.01, 0.1718, 2.02, 0.1098, 3.02, 0.0288, 4.02, 0.0047, 5.04, 0.0026, 6.04, 0.0008, 7.06, 0.0004, 8.06, 0.0002] Trp_g5 = [1.02, 0.0825, 2.03, 0.0364, 3.04, 0.0160, 4.06, 0.0045, 5.07, 0.0011, 6.09, 0.0005, 7.10, 0.0002] Trp_gs5 = [1.02, 0.0114, 2.02, 0.0346, 3.02, 0.0045, 4.04, 0.0013, 5.06, 0.0002] Trp_a5 = [1.02, 0.0821, 2.03, 0.0089, 3.04, 0.0023, 4.06, 0.0003, 5.05, 0.0001] Trp_as5 = [1.01, 0.1554, 2.01, 0.0287, 3.02, 0.0084, 4.02, 0.0035, 5.03, 0.0007, 6.04, 0.0002, 7.04, 0.0001] Trp_b5 = [1.01, 0.0559, 2.01, 0.0017, 3.01, 0.0013, 4.02, 0.0001] Trp_c6 = [1.01, 0.0291, 2.00, 0.0150, 3.01, 0.0032, 4.02, 0.0004, 5.02, 0.0002] # # # # # Trpf_fs3 = [1.00, 0.0292, 1.99, 0.0424, 3.00, 0.0242, 4.00, 0.0413, 4.99, 0.0315, 6.00, 0.0454, 7.00, 0.0143, 7.98, 0.0108, 8.99, 0.0077, 9.99, 0.0084, 10.99, 0.0071, 11.98, 0.0078, 12.97, 0.0085, 13.98, 0.0032, 14.97, 0.0035, 15.97, 0.0052, 16.96, 0.0021, 17.96, 0.0033, 18.96, 0.0024, 19.97, 0.0016, 20.95, 0.0015, 21.95, 0.0011, 22.95, 0.0006, 23.95, 0.0007, 24.94, 0.0006, 25.94, 0.0004, 26.94, 0.0003, 27.93, 0.0004, 28.93, 0.0003, 29.93, 0.0002, 30.92, 0.0003, 31.92, 0.0001, 32.93, 0.0001, 33.91, 0.0002] Trpf_g3 = [0.99, 0.0286, 1.97, 0.0669, 2.95, 0.0456, 3.95, 0.0345, 4.94, 0.0617, 5.91, 0.0341, 6.90, 0.0225, 7.89, 0.0264, 8.88, 0.0155, 9.86, 0.0160, 10.84, 0.0150, 11.83, 0.0085, 12.82, 0.0112, 13.80, 0.0054, 14.78, 0.0042, 15.77, 0.0056, 16.76, 0.0023, 17.73, 0.0027, 18.71, 0.0010, 19.73, 0.0014, 20.69, 0.0014, 21.68, 0.0007, 22.67, 0.0007, 23.64, 0.0007, 24.63, 0.0004, 25.62, 0.0005, 26.59, 0.0003, 27.62, 0.0002, 28.56, 0.0003, 29.55, 0.0001, 30.53, 0.0002, 31.51, 0.0002, 32.50, 0.0001, 33.48, 0.0002, 35.47, 0.0001] Trpf_gs3 = [0.99, 0.0306, 1.99, 0.0608, 2.97, 0.0495, 3.97, 0.0557, 4.97, 0.0228, 5.95, 0.0337, 6.95, 0.0177, 7.94, 0.0112, 8.92, 0.0146, 9.93, 0.0022, 10.91, 0.0069, 11.89, 0.0053, 12.89, 0.0047, 13.88, 0.0031, 14.87, 0.0063, 15.87, 0.0042, 16.86, 0.0033, 17.84, 0.0031, 18.84, 0.0028, 19.83, 0.0018, 20.83, 0.0015, 21.82, 0.0010, 22.80, 0.0010, 23.80, 0.0005, 24.79, 0.0007, 25.77, 0.0004, 26.77, 0.0005, 27.76, 0.0003, 28.75, 0.0003, 29.74, 0.0002, 30.74, 0.0002, 32.73, 0.0001] Trpf_a3 = [0.99, 0.0331, 2.00, 0.0607, 3.00, 0.0463, 4.00, 0.0350, 5.00, 0.0480, 6.00, 0.0294, 7.00, 0.0318, 7.99, 0.0150, 8.98, 0.0166, 9.98, 0.0148, 10.98, 0.0109, 11.99, 0.0052, 13.02, 0.0012, 13.99, 0.0070, 14.98, 0.0054, 15.98, 0.0035, 16.97, 0.0035, 17.96, 0.0021, 18.96, 0.0019, 19.96, 0.0008, 20.96, 0.0010, 21.97, 0.0006, 22.96, 0.0005, 23.96, 0.0007, 24.96, 0.0004, 25.95, 0.0006, 26.95, 0.0004, 27.94, 0.0003, 28.94, 0.0002, 29.94, 0.0001, 30.94, 0.0002, 31.93, 0.0002, 32.93, 0.0001] Trpf_as3 = [1.00, 0.0250, 2.00, 0.0182, 2.99, 0.0170, 3.97, 0.0199, 4.97, 0.0223, 5.97, 0.0224, 6.95, 0.0094, 7.95, 0.0070, 8.94, 0.0069, 9.92, 0.0064, 10.91, 0.0030, 11.92, 0.0028, 12.90, 0.0024, 13.01, 0.0007, 14.00, 0.0003, 14.89, 0.0008, 15.89, 0.0007, 16.91, 0.0002, 17.88, 0.0002, 18.86, 0.0001, 20.83, 0.0001] Trpf_b3 = [1.00, 0.0379, 1.99, 0.0221, 2.99, 0.0480, 3.99, 0.0721, 4.97, 0.0322, 5.98, 0.0203, 6.97, 0.0220, 7.97, 0.0170, 8.96, 0.0150, 9.96, 0.0042, 10.95, 0.0040, 11.93, 0.0049, 12.94, 0.0038, 14.00, 0.0011, 14.95, 0.0021, 15.95, 0.0008, 16.93, 0.0004, 16.98, 0.0004, 17.90, 0.0004, 18.00, 0.0003, 18.99, 0.0003, 19.89, 0.0003, 20.88, 0.0003, 21.89, 0.0002, 22.97, 0.0002, 23.97, 0.0002] Trpf_c4 = [1.01, 0.0330, 2.02, 0.0365, 3.02, 0.0430, 4.03, 0.0164, 5.05, 0.0234, 6.04, 0.0138, 7.05, 0.0110, 8.06, 0.0202, 9.07, 0.0098, 10.08, 0.0030, 11.09, 0.0065, 12.11, 0.0027, 13.11, 0.0009, 14.13, 0.0014, 15.15, 0.0003, 16.12, 0.0002, 17.13, 0.0002, 18.12, 0.0002, 19.14, 0.0002, 20.13, 0.0002, 21.14, 0.0001] Trpf_cs4 = [1.01, 0.0082, 2.02, 0.0191, 3.02, 0.0152, 4.01, 0.0324, 5.02, 0.0129, 6.03, 0.0050, 7.01, 0.0093, 8.01, 0.0031, 9.01, 0.0036, 10.00, 0.0017, 11.01, 0.0010, 12.00, 0.0004, 13.02, 0.0004, 14.03, 0.0003, 15.02, 0.0002, 16.03, 0.0001] Trpf_d4 = [1.01, 0.0190, 2.03, 0.0431, 3.04, 0.0481, 4.05, 0.0399, 5.07, 0.0179, 6.08, 0.0198, 7.09, 0.0136, 8.10, 0.0081, 9.12, 0.0041, 10.10, 0.0011, 11.15, 0.0016, 12.16, 0.0014, 13.17, 0.0007, 14.18, 0.0005, 15.20, 0.0003, 16.20, 0.0002, 17.22, 0.0002, 19.24, 0.0001] Trpf_ds4 = [1.00, 0.0239, 2.01, 0.0207, 3.02, 0.0113, 4.00, 0.0083, 5.00, 0.0145, 5.97, 0.0054, 6.99, 0.0031, 7.98, 0.0026, 8.97, 0.0027, 9.98, 0.0010, 11.01, 0.0004, 11.99, 0.0004, 13.00, 0.0003, 13.97, 0.0002, 14.98, 0.0002, 15.97, 0.0002] Trpf_e4 = [1.02, 0.0134, 2.03, 0.0124, 3.04, 0.0117, 4.05, 0.0041, 5.08, 0.0007, 6.06, 0.0009, 7.08, 0.0006, 8.06, 0.0002, 9.11, 0.0002] Trpf_f4 = [1.03, 0.0045, 2.03, 0.0019, 3.03, 0.0006, 4.04, 0.0012, 5.02, 0.0004, 6.08, 0.0001] Trpf_fs4 = [1.00, 0.0501, 2.00, 0.0385, 3.00, 0.0509, 3.99, 0.0156, 4.98, 0.0099, 5.98, 0.0063, 6.99, 0.0017, 7.97, 0.0020, 8.97, 0.0017, 9.96, 0.0012, 10.96, 0.0004, 11.95, 0.0004, 12.97, 0.0001, 13.94, 0.0002] Trpf_g4 = [1.00, 0.0998, 2.00, 0.0632, 3.01, 0.0506, 4.01, 0.0395, 5.00, 0.0265, 6.01, 0.0137, 7.01, 0.0058, 8.01, 0.0017, 9.02, 0.0010, 10.02, 0.0007, 11.02, 0.0007, 12.03, 0.0004, 13.03, 0.0004, 14.03, 0.0002, 15.05, 0.0001] Trpf_gs4 = [1.00, 0.0589, 2.00, 0.0237, 2.99, 0.0208, 3.98, 0.0103, 4.98, 0.0087, 5.98, 0.0053, 6.97, 0.0039, 7.98, 0.0017, 8.98, 0.0006, 10.00, 0.0003, 10.97, 0.0002, 12.00, 0.0001] Trpf_a4 = [1.01, 0.0482, 2.01, 0.0264, 3.02, 0.0127, 4.01, 0.0108, 5.01, 0.0039, 6.01, 0.0012, 7.00, 0.0012, 8.01, 0.0004, 9.02, 0.0002, 10.02, 0.0002, 11.00, 0.0001] Trpf_as4 = [1.00, 0.0176, 2.01, 0.0156, 3.00, 0.0312, 3.99, 0.0057, 5.00, 0.0055, 5.99, 0.0036, 6.99, 0.0007, 7.99, 0.0005, 8.99, 0.0003, 9.99, 0.0001, 10.99, 0.0001] Trpf_b4 = [1.01, 0.0051, 1.99, 0.0340, 2.98, 0.0087, 3.97, 0.0121, 4.97, 0.0018, 5.94, 0.0018, 6.95, 0.0005, 7.93, 0.0002, 8.94, 0.0004] Trpf_c5 = [1.01, 0.0110, 1.99, 0.0059, 3.00, 0.0200, 3.99, 0.0059, 5.00, 0.0016, 5.99, 0.0005, 6.98, 0.0002, 7.96, 0.0002, 8.99, 0.0002] Trpf_cs5 = [1.01, 0.0257, 2.01, 0.0215, 3.02, 0.0022, 4.00, 0.0027, 5.01, 0.0007, 6.00, 0.0007, 7.02, 0.0002] Trpf_d5 = [1.01, 0.0616, 2.01, 0.0423, 3.01, 0.0140, 4.01, 0.0061, 4.99, 0.0034, 5.99, 0.0008, 6.98, 0.0006, 8.00, 0.0003, 8.97, 0.0002] Trpf_ds5 = [0.99, 0.0763, 1.99, 0.0800, 2.98, 0.0329, 3.97, 0.0255, 4.96, 0.0110, 5.95, 0.0041, 6.95, 0.0018, 7.94, 0.0006, 8.93, 0.0005, 9.90, 0.0002, 9.93, 0.0002, 10.91, 0.0002] Trpf_e5 = [1.01, 0.0196, 2.00, 0.0085, 2.98, 0.0039, 3.97, 0.0007, 4.98, 0.0003] Trpf_f5 = [1.02, 0.0735, 2.03, 0.0526, 3.04, 0.0168, 4.05, 0.0064, 5.07, 0.0009, 6.07, 0.0008, 7.09, 0.0002, 8.09, 0.0001, 9.12, 0.0001] Trpf_fs5 = [1.01, 0.1101, 2.02, 0.0477, 3.03, 0.0090, 4.04, 0.0024, 5.05, 0.0012, 6.06, 0.0015, 7.07, 0.0004, 8.08, 0.0002] Trpf_g5 = [1.02, 0.1148, 2.03, 0.0215, 3.04, 0.0185, 4.06, 0.0077, 5.07, 0.0023, 6.08, 0.0007, 7.09, 0.0004, 8.12, 0.0002] Trpf_gs5 = [1.01, 0.0538, 2.02, 0.0584, 3.03, 0.0156, 4.04, 0.0028, 5.06, 0.0009, 6.07, 0.0006, 7.07, 0.0002] Trpf_a5 = [1.01, 0.1885, 2.02, 0.0789, 3.04, 0.0214, 4.05, 0.0086, 5.06, 0.0049, 6.07, 0.0010, 7.08, 0.0007, 8.10, 0.0003, 9.11, 0.0003, 10.12, 0.0001, 11.13, 0.0001] Trpf_as5 = [1.01, 0.0233, 2.02, 0.0033, 3.01, 0.0008, 4.03, 0.0002] Trpf_b5 = [1.00, 0.1077, 2.01, 0.0158, 3.01, 0.0039, 4.01, 0.0011, 5.01, 0.0003, 6.02, 0.0002, 7.02, 0.0001] Trpf_c6 = [1.01, 0.0873, 2.02, 0.0519, 3.03, 0.0156, 4.04, 0.0042, 5.04, 0.0019, 6.05, 0.0006, 7.06, 0.0004, 8.07, 0.0002] Trpf_cs6 = [1.01, 0.0852, 2.02, 0.0049, 3.03, 0.0007, 4.05, 0.0001] # # # # # violin? Vl_g3 = [0.99, 0.0159, 1.99, 0.1898, 3.00, 0.0499, 3.99, 0.0352, 5.00, 0.0192, 6.00, 0.0100, 7.00, 0.0173, 8.00, 0.0142, 8.99, 0.0045, 10.01, 0.0178, 11.00, 0.0108, 12.00, 0.0081, 12.99, 0.0254, 13.99, 0.0074, 14.99, 0.0062, 16.00, 0.0122, 17.00, 0.0049, 17.99, 0.0022, 19.01, 0.0041, 20.01, 0.0048, 21.01, 0.0037, 22.01, 0.0016, 23.01, 0.0001, 24.00, 0.0002, 25.00, 0.0006, 26.00, 0.0010, 27.00, 0.0015, 28.03, 0.0004, 29.02, 0.0007, 30.01, 0.0006, 32.00, 0.0002, 33.01, 0.0001, 34.00, 0.0001, 35.01, 0.0004, 36.02, 0.0003, 37.02, 0.0001, 40.02, 0.0001, 40.99, 0.0002, 42.01, 0.0003, 48.01, 0.0001, 51.01, 0.0001] Vl_gs3 = [0.99, 0.0185, 1.99, 0.1881, 2.97, 0.0463, 3.97, 0.0528, 4.97, 0.0309, 5.95, 0.0316, 6.95, 0.0104, 7.93, 0.0422, 8.94, 0.0114, 9.90, 0.0018, 10.92, 0.0088, 11.89, 0.0021, 12.90, 0.0077, 13.91, 0.0044, 14.86, 0.0029, 14.93, 0.0028, 15.91, 0.0011, 16.88, 0.0082, 17.89, 0.0022, 18.88, 0.0043, 19.86, 0.0024, 20.84, 0.0012, 21.84, 0.0007, 22.87, 0.0008, 23.85, 0.0006, 24.84, 0.0004, 25.82, 0.0010, 26.81, 0.0006, 27.81, 0.0012, 28.79, 0.0002, 29.78, 0.0002, 30.77, 0.0001, 31.78, 0.0003, 33.75, 0.0001, 34.76, 0.0002, 35.75, 0.0002, 36.75, 0.0002, 37.77, 0.0001, 40.74, 0.0001] Vl_a3 = [0.99, 0.0215, 2.00, 0.1550, 2.99, 0.0293, 4.00, 0.0298, 5.00, 0.0211, 6.00, 0.0389, 7.00, 0.0057, 7.99, 0.0235, 8.99, 0.0172, 9.99, 0.0040, 11.00, 0.0026, 12.00, 0.0074, 12.99, 0.0065, 13.99, 0.0192, 14.99, 0.0026, 15.98, 0.0063, 16.99, 0.0045, 18.01, 0.0036, 18.99, 0.0050, 20.00, 0.0012, 20.98, 0.0011, 21.99, 0.0007, 22.99, 0.0014, 23.99, 0.0003, 25.00, 0.0011, 26.00, 0.0008, 26.99, 0.0007, 27.98, 0.0002, 28.99, 0.0001, 29.97, 0.0004, 31.00, 0.0002, 31.99, 0.0002, 32.99, 0.0002, 33.98, 0.0001, 35.03, 0.0001, 36.00, 0.0002, 36.98, 0.0003, 37.99, 0.0002, 38.99, 0.0001, 39.99, 0.0002, 41.01, 0.0001, 41.99, 0.0001, 43.04, 0.0001, 43.99, 0.0001] Vl_as3 = [1.00, 0.0210, 2.00, 0.1015, 3.00, 0.0450, 3.99, 0.0210, 4.99, 0.0266, 6.00, 0.0143, 7.00, 0.0661, 7.99, 0.0367, 8.99, 0.0149, 9.99, 0.0037, 10.99, 0.0344, 11.99, 0.0069, 12.99, 0.0110, 13.98, 0.0088, 14.98, 0.0052, 15.98, 0.0066, 16.99, 0.0038, 17.98, 0.0027, 18.98, 0.0007, 19.98, 0.0018, 20.98, 0.0009, 21.99, 0.0011, 22.99, 0.0013, 23.99, 0.0006, 24.97, 0.0004, 25.98, 0.0001, 26.98, 0.0003, 27.97, 0.0002, 28.99, 0.0002, 29.97, 0.0002, 31.00, 0.0002, 31.97, 0.0004, 32.97, 0.0001, 33.99, 0.0003, 34.97, 0.0002, 35.97, 0.0003, 36.94, 0.0001, 37.99, 0.0001, 38.96, 0.0001, 41.97, 0.0001] Vl_b3 = [1.00, 0.0532, 1.99, 0.0205, 3.00, 0.0342, 3.99, 0.0312, 5.00, 0.0493, 5.99, 0.0062, 6.99, 0.0103, 7.99, 0.0240, 8.99, 0.0134, 9.99, 0.0046, 10.98, 0.0154, 11.99, 0.0077, 12.98, 0.0084, 13.99, 0.0028, 14.99, 0.0026, 15.98, 0.0054, 16.98, 0.0031, 17.99, 0.0004, 18.98, 0.0009, 19.99, 0.0005, 20.52, 0.0001, 21.98, 0.0011, 22.97, 0.0010, 23.99, 0.0004, 24.96, 0.0003, 26.00, 0.0001, 27.99, 0.0006, 28.99, 0.0001, 30.97, 0.0003, 32.00, 0.0002, 32.99, 0.0001, 33.97, 0.0002, 36.99, 0.0001] Vl_c4 = [0.99, 0.1156, 2.00, 0.0827, 3.00, 0.0458, 4.00, 0.0163, 5.00, 0.0256, 6.01, 0.0103, 7.02, 0.0032, 8.00, 0.0025, 8.98, 0.0056, 10.00, 0.0072, 10.98, 0.0016, 11.98, 0.0036, 13.02, 0.0013, 14.00, 0.0021, 15.00, 0.0024, 15.99, 0.0013, 16.99, 0.0003, 18.01, 0.0001, 19.01, 0.0003, 19.99, 0.0001, 21.02, 0.0001, 22.03, 0.0002, 29.00, 0.0001] Vl_cs4 = [1.00, 0.3269, 2.00, 0.0869, 2.99, 0.0386, 4.00, 0.0117, 4.99, 0.0062, 6.00, 0.0264, 7.00, 0.0099, 8.00, 0.0038, 9.01, 0.0040, 10.00, 0.0057, 11.03, 0.0040, 12.02, 0.0017, 13.00, 0.0009, 14.02, 0.0026, 15.02, 0.0009, 15.95, 0.0002, 16.99, 0.0002, 18.01, 0.0001, 19.01, 0.0005, 20.00, 0.0001, 21.03, 0.0002, 22.03, 0.0001] Vl_d4 = [1.00, 0.2473, 2.00, 0.0621, 2.98, 0.0073, 3.99, 0.0178, 5.00, 0.0070, 5.98, 0.0041, 7.02, 0.0054, 8.01, 0.0114, 9.05, 0.0034, 10.05, 0.0024, 10.93, 0.0003, 11.99, 0.0011, 13.00, 0.0011, 14.03, 0.0010, 15.01, 0.0002, 15.96, 0.0001, 17.02, 0.0001, 18.01, 0.0005, 21.00, 0.0001, 22.00, 0.0002] Vl_ds4 = [1.00, 0.0394, 2.00, 0.0358, 2.99, 0.0119, 3.99, 0.0208, 4.99, 0.0064, 5.98, 0.0126, 6.96, 0.0028, 7.03, 0.0017, 8.01, 0.0006, 8.92, 0.0005, 9.97, 0.0048, 10.97, 0.0004, 11.99, 0.0005, 12.97, 0.0005, 13.96, 0.0002, 14.92, 0.0001, 15.92, 0.0001, 19.93, 0.0001, 22.92, 0.0001, 23.96, 0.0001] Vl_e4 = [1.00, 0.0649, 2.00, 0.0412, 3.01, 0.0315, 4.00, 0.0446, 5.01, 0.0414, 6.01, 0.0209, 7.02, 0.0189, 8.01, 0.0101, 9.03, 0.0012, 10.03, 0.0029, 11.02, 0.0041, 12.00, 0.0012, 13.04, 0.0004, 14.05, 0.0005, 15.03, 0.0009, 16.06, 0.0005, 17.09, 0.0004, 18.07, 0.0006, 19.08, 0.0004, 20.10, 0.0001, 21.09, 0.0001, 22.09, 0.0004, 23.11, 0.0002, 24.06, 0.0002, 25.07, 0.0002, 26.07, 0.0002, 27.08, 0.0002, 30.10, 0.0001] Vl_f4 = [1.00, 0.0700, 2.00, 0.0235, 3.00, 0.0294, 4.00, 0.0101, 4.99, 0.0173, 5.99, 0.0081, 6.99, 0.0023, 7.99, 0.0006, 8.97, 0.0101, 9.98, 0.0060, 11.00, 0.0063, 11.99, 0.0038, 13.00, 0.0011, 13.98, 0.0003, 15.01, 0.0009, 16.02, 0.0005, 17.01, 0.0004, 18.06, 0.0002, 19.01, 0.0004, 20.01, 0.0004, 21.03, 0.0005, 22.04, 0.0002, 23.00, 0.0003, 24.00, 0.0001, 25.99, 0.0001, 29.04, 0.0001, 31.04, 0.0001] Vl_fs4 = [1.01, 0.1897, 2.02, 0.0152, 3.02, 0.0312, 4.03, 0.0224, 5.03, 0.0483, 6.04, 0.0217, 7.05, 0.0184, 8.07, 0.0051, 9.06, 0.0031, 10.08, 0.0047, 11.09, 0.0040, 12.10, 0.0021, 13.10, 0.0006, 14.11, 0.0010, 15.14, 0.0012, 16.14, 0.0009, 17.15, 0.0004, 18.16, 0.0010, 19.18, 0.0003, 20.19, 0.0005, 21.14, 0.0002, 22.17, 0.0002, 23.18, 0.0002, 24.18, 0.0002, 26.22, 0.0001, 29.25, 0.0002, 30.26, 0.0002] Vl_g4 = [1.01, 0.0788, 2.01, 0.0144, 2.99, 0.0064, 3.99, 0.0078, 5.02, 0.0053, 6.00, 0.0045, 7.01, 0.0011, 7.98, 0.0025, 9.03, 0.0010, 10.02, 0.0014, 11.02, 0.0002, 12.02, 0.0001, 13.02, 0.0003, 14.05, 0.0002, 15.07, 0.0002, 17.05, 0.0001, 18.02, 0.0002, 19.07, 0.0001] Vl_gs4 = [1.00, 0.2902, 2.01, 0.0644, 3.01, 0.0378, 4.02, 0.0473, 5.02, 0.0027, 6.03, 0.0278, 7.04, 0.0077, 8.04, 0.0105, 9.04, 0.0026, 10.04, 0.0106, 11.05, 0.0011, 12.05, 0.0014, 13.06, 0.0045, 14.09, 0.0015, 15.09, 0.0010, 16.09, 0.0008, 17.09, 0.0011, 18.10, 0.0010, 19.09, 0.0011, 20.09, 0.0004, 21.10, 0.0010, 22.10, 0.0006, 23.11, 0.0003, 24.10, 0.0002, 24.14, 0.0002, 25.15, 0.0002, 26.14, 0.0005, 27.14, 0.0003, 30.13, 0.0002, 31.14, 0.0001] Vl_a4 = [1.00, 0.3420, 2.02, 0.0045, 3.00, 0.0160, 4.00, 0.0105, 5.01, 0.0370, 6.02, 0.0193, 7.01, 0.0342, 8.02, 0.0178, 9.02, 0.0146, 10.04, 0.0025, 11.03, 0.0011, 12.02, 0.0010, 13.03, 0.0009, 14.03, 0.0003, 15.05, 0.0031, 16.04, 0.0009, 17.04, 0.0004, 18.04, 0.0004, 19.03, 0.0004, 20.06, 0.0005, 21.05, 0.0001, 22.04, 0.0001, 24.06, 0.0001, 25.07, 0.0002, 26.08, 0.0001] Vl_as4 = [1.00, 0.1478, 2.00, 0.0159, 3.00, 0.0033, 3.99, 0.0600, 5.00, 0.0291, 5.99, 0.0028, 7.01, 0.0118, 8.00, 0.0115, 8.99, 0.0039, 9.99, 0.0020, 10.99, 0.0024, 11.99, 0.0012, 12.99, 0.0009, 14.01, 0.0011, 15.00, 0.0015, 16.01, 0.0004, 17.02, 0.0001, 18.01, 0.0001, 19.01, 0.0002, 20.00, 0.0002, 20.98, 0.0001, 22.00, 0.0001, 24.02, 0.0002, 25.00, 0.0002] Vl_b4 = [1.00, 0.0247, 2.01, 0.0570, 3.01, 0.0115, 4.02, 0.0167, 5.02, 0.0162, 6.02, 0.0154, 7.02, 0.0056, 8.04, 0.0021, 9.04, 0.0003, 10.04, 0.0023, 11.04, 0.0003, 12.07, 0.0005, 13.09, 0.0005, 14.06, 0.0003, 15.06, 0.0004, 16.09, 0.0003, 17.07, 0.0002, 18.10, 0.0003, 19.10, 0.0002] Vl_c5 = [1.00, 0.0690, 1.99, 0.0372, 2.99, 0.0326, 3.99, 0.0222, 4.99, 0.0107, 5.97, 0.0033, 6.99, 0.0029, 7.98, 0.0013, 8.97, 0.0005, 9.98, 0.0008, 10.97, 0.0004, 11.97, 0.0006, 12.99, 0.0003, 13.99, 0.0002, 14.97, 0.0001, 16.95, 0.0001, 16.98, 0.0001, 17.97, 0.0001, 19.96, 0.0001] Vl_cs5 = [1.00, 0.1446, 2.01, 0.0499, 3.01, 0.0768, 4.02, 0.0436, 5.02, 0.0287, 6.03, 0.0204, 7.03, 0.0301, 7.11, 0.0011, 8.04, 0.0010, 9.04, 0.0036, 10.05, 0.0030, 11.05, 0.0023, 12.06, 0.0008, 13.06, 0.0005, 14.07, 0.0009, 15.08, 0.0005, 16.09, 0.0009, 17.08, 0.0003, 18.10, 0.0006, 19.09, 0.0008, 20.13, 0.0002, 21.11, 0.0001, 22.14, 0.0001, 23.11, 0.0002] Vl_d5 = [1.00, 0.0614, 1.99, 0.0194, 2.99, 0.0196, 3.99, 0.0159, 5.00, 0.0057, 6.00, 0.0031, 7.01, 0.0024, 8.00, 0.0004, 9.00, 0.0003, 9.98, 0.0003, 11.01, 0.0005, 11.99, 0.0003, 12.99, 0.0002, 16.99, 0.0001, 17.98, 0.0001] Vl_ds5 = [0.99, 0.1393, 1.99, 0.0875, 2.99, 0.1163, 3.98, 0.0152, 4.98, 0.0551, 5.97, 0.0214, 6.97, 0.0072, 7.96, 0.0017, 8.95, 0.0028, 9.96, 0.0034, 10.95, 0.0015, 11.94, 0.0010, 12.95, 0.0009, 13.91, 0.0008, 14.94, 0.0011, 15.93, 0.0005, 16.93, 0.0007, 17.92, 0.0004, 17.97, 0.0002, 18.94, 0.0002, 19.93, 0.0003, 20.92, 0.0004, 21.90, 0.0001] Vl_e5 = [1.00, 0.1926, 2.00, 0.0731, 3.00, 0.0543, 4.00, 0.0258, 5.02, 0.0238, 6.02, 0.0177, 7.03, 0.0206, 8.03, 0.0081, 9.03, 0.0030, 10.05, 0.0043, 11.03, 0.0011, 12.06, 0.0007, 13.08, 0.0013, 14.10, 0.0007, 15.11, 0.0004, 16.14, 0.0002] Vl_f5 = [1.00, 0.0684, 2.00, 0.0409, 3.00, 0.0344, 4.00, 0.0439, 5.00, 0.0686, 6.00, 0.0504, 7.00, 0.0045, 8.00, 0.0056, 9.00, 0.0094, 10.00, 0.0028, 11.00, 0.0015, 11.99, 0.0010, 13.00, 0.0032, 14.00, 0.0017, 15.00, 0.0010, 16.01, 0.0011, 16.99, 0.0003, 18.01, 0.0006, 19.00, 0.0003] Vl_fs5 = [1.00, 0.0291, 2.01, 0.0323, 3.01, 0.0110, 4.02, 0.0071, 5.04, 0.0028, 6.04, 0.0010, 7.08, 0.0007, 8.08, 0.0003, 9.09, 0.0004, 10.12, 0.0002, 11.06, 0.0003] Vl_g5 = [1.00, 0.0980, 1.99, 0.0303, 3.00, 0.0044, 4.01, 0.0107, 5.03, 0.0027, 6.03, 0.0011, 7.00, 0.0010, 8.02, 0.0011, 8.06, 0.0004, 9.04, 0.0003, 10.04, 0.0001] Vl_gs5 = [1.01, 0.1116, 2.01, 0.0200, 3.03, 0.0147, 4.03, 0.0034, 5.08, 0.0061, 6.10, 0.0012, 7.06, 0.0005, 8.14, 0.0005, 9.14, 0.0004] Vl_a5 = [1.00, 0.0211, 2.01, 0.0180, 3.01, 0.0158, 4.02, 0.0057, 5.03, 0.0013, 6.03, 0.0006, 7.02, 0.0001] Vl_as5 = [1.00, 0.0442, 2.01, 0.0922, 3.01, 0.0102, 4.00, 0.0031, 5.03, 0.0053, 6.01, 0.0004, 7.04, 0.0018, 7.08, 0.0009, 8.06, 0.0004, 9.06, 0.0006, 10.06, 0.0003, 11.06, 0.0003, 12.09, 0.0002, 13.09, 0.0002] Vl_b5 = [1.01, 0.0061, 2.01, 0.0016, 3.01, 0.0014, 4.03, 0.0005, 5.04, 0.0005, 5.06, 0.0001] Vl_c6 = [1.01, 0.0039, 2.00, 0.0005, 3.02, 0.0006, 4.03, 0.0001] Vl_cs6 = [1.00, 0.0754, 2.00, 0.1620, 3.00, 0.1551, 4.00, 0.0277, 5.00, 0.0466, 6.00, 0.0408, 7.00, 0.0025, 8.00, 0.0055, 9.00, 0.0048, 9.99, 0.0034, 10.99, 0.0039, 11.99, 0.0005] Vl_d6 = [1.00, 0.0905, 2.00, 0.0808, 3.00, 0.0909, 4.00, 0.0616, 5.00, 0.0172, 5.99, 0.0043, 7.01, 0.0044, 8.00, 0.0036, 9.00, 0.0043, 10.01, 0.0015, 11.03, 0.0014] Vl_ds6 = [1.00, 0.1772, 2.00, 0.1029, 3.00, 0.0398, 4.01, 0.0602, 5.00, 0.0222, 6.01, 0.0073, 7.01, 0.0037, 8.01, 0.0044, 9.01, 0.0019, 10.01, 0.0028, 11.01, 0.0006, 11.03, 0.0001] Vl_e6 = [1.00, 0.1865, 2.00, 0.2083, 2.99, 0.0822, 3.99, 0.0298, 4.99, 0.0227, 6.00, 0.0023, 6.98, 0.0049, 7.99, 0.0021, 8.98, 0.0022, 9.98, 0.0003, 9.99, 0.0003] Vl_f6 = [1.01, 0.0841, 2.01, 0.0654, 3.02, 0.1346, 4.03, 0.0041, 5.04, 0.0077, 6.05, 0.0088, 7.05, 0.0016, 8.06, 0.0017, 9.06, 0.0012, 9.08, 0.0003, 9.10, 0.0002, 9.11, 0.0001] Vl_fs6 = [1.00, 0.1693, 2.02, 0.0779, 3.03, 0.0411, 4.03, 0.0147, 5.04, 0.0085, 6.05, 0.0080, 7.06, 0.0088, 8.06, 0.0032, 9.06, 0.0010, 9.08, 0.0007, 9.10, 0.0004] Vl_g6 = [1.01, 0.2123, 2.02, 0.2854, 3.03, 0.0552, 4.04, 0.0246, 5.05, 0.0058, 6.06, 0.0022, 7.07, 0.0017, 8.09, 0.0029, 9.10, 0.0001] Vl_gs6 = [1.02, 0.1270, 2.03, 0.0961, 3.05, 0.0347, 4.06, 0.0032, 5.08, 0.0083, 6.09, 0.0050, 7.11, 0.0020, 8.12, 0.0013, 8.14, 0.0002] Vl_a6 = [1.02, 0.3359, 2.03, 0.1252, 3.05, 0.0238, 4.07, 0.0155, 5.09, 0.0053, 6.10, 0.0051, 7.12, 0.0025, 7.18, 0.0001] Vl_as6 = [1.01, 0.2037, 2.03, 0.0456, 3.05, 0.0029, 4.06, 0.0053, 5.07, 0.0041, 6.09, 0.0043, 7.11, 0.0026, 7.13, 0.0006, 7.14, 0.0001] Vl_b6 = [1.02, 0.4213, 2.04, 0.1379, 3.06, 0.0067, 4.06, 0.0041, 4.08, 0.0039, 5.09, 0.0026, 6.11, 0.0027, 7.13, 0.0002] Vl_c7 = [1.01, 0.1299, 2.02, 0.1571, 3.03, 0.0461, 4.04, 0.0033, 5.05, 0.0057, 6.06, 0.0015] Vl_cs7 = [1.01, 0.1471, 2.03, 0.0526, 3.05, 0.0161, 4.06, 0.0037, 5.08, 0.0017, 6.09, 0.0005] Vl_d7 = [1.01, 0.0321, 2.02, 0.0529, 3.03, 0.0046, 4.03, 0.0054, 4.04, 0.0021, 5.04, 0.0010] Vl_ds7 = [1.00, 0.1220, 2.00, 0.0667, 2.99, 0.0319, 4.00, 0.0020, 4.99, 0.0052, 5.03, 0.0002] Vl_e7 = [1.01, 0.1110, 2.02, 0.0588, 3.03, 0.0143, 4.04, 0.0068, 5.05, 0.0011] Vl_f7 = [1.01, 0.0798, 2.02, 0.0111, 3.03, 0.0125, 4.03, 0.0036, 4.50, 0.0002, 5.04, 0.0001] Vl_fs7 = [1.02, 0.1071, 2.04, 0.0117, 3.06, 0.0148, 4.08, 0.0092, 4.11, 0.0007, 4.13, 0.0005, 4.16, 0.0003, 4.23, 0.0002, 4.24, 0.0002, 4.28, 0.0002, 4.34, 0.0001, 4.39, 0.0001] Vl_g7 = [1.02, 0.2741, 2.05, 0.0256, 3.07, 0.0122, 4.11, 0.0002, 4.14, 0.0001] Vl_gs7 = [1.02, 0.1027, 2.05, 0.0192, 3.07, 0.0091] Vl_a7 = [1.02, 0.0796, 2.04, 0.0112, 3.06, 0.0030] Vl_as7 = [1.06, 0.1256] Vl_b7 = [1.08, 0.1494, 3.24, 0.0003] Vl_c8 = [1.07, 0.0582, 3.25, 0.0004] Vl_cs8 = [1.08, 0.0889] Vl_d8 = [1.07, 0.0573] # # # # # Almf_c3 = [1.01, 0.0037, 2.01, 0.0482, 3.01, 0.0275, 4.01, 0.0182, 5.03, 0.0047, 6.03, 0.0032, 7.03, 0.0005, 8.03, 0.0050, 9.05, 0.0044, 10.02, 0.0016, 11.06, 0.0011, 12.06, 0.0004, 13.06, 0.0006, 14.16, 0.0001, 15.12, 0.0001, 16.12, 0.0004, 17.12, 0.0004, 19.08, 0.0003, 20.11, 0.0004, 23.11, 0.0002, 24.14, 0.0003, 25.14, 0.0003, 27.12, 0.0002, 28.13, 0.0001, 30.17, 0.0001] Almf_cs3 = [1.01, 0.0043, 2.01, 0.0357, 3.02, 0.0452, 4.01, 0.0156, 5.02, 0.0152, 6.04, 0.0022, 7.04, 0.0039, 8.06, 0.0078, 9.06, 0.0049, 10.09, 0.0046, 11.24, 0.0004, 12.08, 0.0016, 13.09, 0.0015, 14.10, 0.0021, 15.12, 0.0006, 16.12, 0.0012, 17.12, 0.0002, 18.16, 0.0004, 19.16, 0.0006, 20.15, 0.0006, 21.15, 0.0007, 22.16, 0.0005, 23.17, 0.0005, 24.13, 0.0004, 25.48, 0.0003, 26.19, 0.0002, 27.18, 0.0002, 28.20, 0.0002, 30.26, 0.0001, 31.25, 0.0002, 34.23, 0.0001] Almf_d3 = [1.01, 0.0052, 2.03, 0.0062, 3.01, 0.0292, 4.05, 0.0043, 5.02, 0.0149, 5.97, 0.0018, 7.02, 0.0016, 8.05, 0.0029, 9.04, 0.0005, 10.06, 0.0012, 11.04, 0.0006, 12.12, 0.0002, 13.05, 0.0005, 14.10, 0.0004, 15.08, 0.0004, 15.99, 0.0001, 17.18, 0.0001, 18.07, 0.0004, 19.06, 0.0001, 20.08, 0.0003, 22.11, 0.0003, 24.13, 0.0002, 25.15, 0.0001, 26.12, 0.0001] Almf_ds3 = [1.01, 0.0043, 2.01, 0.0532, 3.01, 0.0389, 4.00, 0.0094, 5.01, 0.0031, 6.00, 0.0038, 7.00, 0.0219, 8.00, 0.0122, 8.99, 0.0129, 10.00, 0.0014, 11.00, 0.0021, 12.01, 0.0037, 13.01, 0.0021, 14.01, 0.0017, 15.02, 0.0015, 16.01, 0.0023, 17.03, 0.0024, 18.00, 0.0008, 19.03, 0.0011, 20.04, 0.0003, 21.04, 0.0009, 22.04, 0.0003, 23.00, 0.0012, 24.00, 0.0011, 25.01, 0.0007, 27.02, 0.0002, 28.02, 0.0004, 29.03, 0.0003, 30.04, 0.0002, 31.04, 0.0001, 46.55, 0.0001, 48.01, 0.0001] Almf_e3 = [1.00, 0.0123, 2.00, 0.0733, 2.99, 0.0330, 4.00, 0.0098, 5.00, 0.0171, 6.00, 0.0013, 7.01, 0.0117, 7.99, 0.0020, 9.00, 0.0044, 10.01, 0.0012, 11.01, 0.0014, 12.00, 0.0021, 13.02, 0.0002, 14.02, 0.0016, 15.03, 0.0012, 16.03, 0.0028, 17.02, 0.0007, 18.02, 0.0019, 19.03, 0.0008, 20.04, 0.0013, 21.03, 0.0005, 22.03, 0.0005, 23.03, 0.0003, 24.04, 0.0003, 26.03, 0.0005, 27.04, 0.0001, 28.06, 0.0001, 29.04, 0.0002] Almf_f3 = [1.00, 0.0185, 2.00, 0.0813, 3.00, 0.0142, 3.99, 0.0132, 5.00, 0.0066, 5.99, 0.0027, 6.93, 0.0009, 8.01, 0.0042, 8.99, 0.0018, 9.97, 0.0002, 10.97, 0.0010, 12.00, 0.0008, 13.00, 0.0012, 13.98, 0.0003, 14.96, 0.0006, 16.00, 0.0004, 17.01, 0.0005, 18.00, 0.0003, 18.98, 0.0005, 19.99, 0.0002, 20.99, 0.0002, 22.00, 0.0002] Almf_fs3 = [1.01, 0.0480, 2.01, 0.0778, 3.01, 0.0124, 4.01, 0.0204, 5.05, 0.0008, 6.03, 0.0068, 7.05, 0.0052, 8.06, 0.0017, 9.07, 0.0017, 10.05, 0.0008, 11.07, 0.0010, 12.08, 0.0008, 13.11, 0.0002, 14.08, 0.0006, 15.10, 0.0002, 16.09, 0.0013, 17.12, 0.0003, 18.10, 0.0003, 19.11, 0.0004, 20.14, 0.0001, 23.17, 0.0001] Almf_g3 = [1.00, 0.0526, 2.00, 0.0242, 2.99, 0.0351, 3.99, 0.0076, 4.98, 0.0062, 5.99, 0.0085, 6.99, 0.0061, 8.04, 0.0006, 8.98, 0.0005, 10.01, 0.0006, 10.97, 0.0003, 11.96, 0.0004, 13.07, 0.0004, 13.95, 0.0003, 14.99, 0.0003, 15.20, 0.0002, 17.93, 0.0002, 18.02, 0.0002, 24.96, 0.0001] Almf_gs3 = [0.99, 0.0523, 1.99, 0.0560, 2.98, 0.0166, 3.98, 0.0183, 4.96, 0.0005, 5.98, 0.0066, 6.99, 0.0026, 7.96, 0.0011, 8.95, 0.0013, 9.95, 0.0026, 10.95, 0.0019, 11.96, 0.0017, 12.94, 0.0005, 13.92, 0.0002, 14.94, 0.0006, 15.95, 0.0007, 16.94, 0.0007, 17.96, 0.0002, 18.92, 0.0002, 19.93, 0.0002, 20.92, 0.0002, 21.94, 0.0001] Almf_a3 = [1.00, 0.1590, 2.00, 0.0394, 3.02, 0.0076, 3.99, 0.0222, 5.00, 0.0063, 5.93, 0.0008, 6.97, 0.0016, 7.95, 0.0002, 8.94, 0.0002, 9.94, 0.0003, 10.05, 0.0002, 10.15, 0.0001, 12.00, 0.0005, 12.12, 0.0002, 12.95, 0.0001, 15.98, 0.0002] Almf_as3 = [1.00, 0.2533, 2.00, 0.0498, 3.00, 0.0178, 3.99, 0.0108, 5.00, 0.0245, 6.00, 0.0112, 6.99, 0.0066, 8.00, 0.0010, 8.98, 0.0074, 9.99, 0.0042, 10.99, 0.0025, 12.00, 0.0015, 13.01, 0.0006, 14.00, 0.0012, 15.00, 0.0004, 16.02, 0.0004, 17.00, 0.0010, 18.00, 0.0005, 18.99, 0.0002, 19.98, 0.0002] Almf_b3 = [1.00, 0.1639, 2.00, 0.0436, 3.01, 0.0584, 4.01, 0.0080, 5.01, 0.0117, 6.01, 0.0208, 7.02, 0.0062, 8.02, 0.0035, 9.03, 0.0037, 10.03, 0.0022, 11.04, 0.0023, 12.04, 0.0048, 13.04, 0.0022, 14.04, 0.0005, 15.04, 0.0007, 16.05, 0.0012, 17.05, 0.0010, 18.06, 0.0005, 19.05, 0.0001, 20.06, 0.0005, 21.07, 0.0002, 24.07, 0.0002, 25.08, 0.0002, 27.08, 0.0002, 28.10, 0.0001, 33.12, 0.0001] Almf_c4 = [1.00, 0.0931, 2.00, 0.0251, 3.00, 0.0077, 4.00, 0.0129, 5.00, 0.0115, 6.00, 0.0055, 7.00, 0.0041, 8.01, 0.0046, 9.00, 0.0013, 10.00, 0.0067, 11.02, 0.0011, 12.02, 0.0021, 12.99, 0.0002, 14.01, 0.0007, 15.02, 0.0008, 16.03, 0.0007, 17.02, 0.0004, 19.02, 0.0003, 20.05, 0.0001, 24.04, 0.0001] Almf_cs4 = [1.01, 0.0587, 2.01, 0.0263, 3.02, 0.0299, 4.03, 0.0306, 5.04, 0.0172, 6.04, 0.0097, 7.05, 0.0024, 8.06, 0.0034, 9.06, 0.0053, 10.07, 0.0065, 11.08, 0.0025, 12.09, 0.0005, 13.10, 0.0016, 14.11, 0.0011, 15.11, 0.0009, 16.12, 0.0004, 17.13, 0.0002, 18.13, 0.0003, 21.15, 0.0002, 23.17, 0.0001, 24.18, 0.0001, 25.19, 0.0002, 30.23, 0.0001, 32.25, 0.0001] Almf_d4 = [1.00, 0.0619, 2.00, 0.0432, 3.01, 0.0479, 4.01, 0.0136, 5.00, 0.0220, 6.01, 0.0064, 7.02, 0.0138, 8.02, 0.0033, 9.02, 0.0066, 10.06, 0.0006, 11.02, 0.0019, 12.01, 0.0013, 13.02, 0.0008, 14.01, 0.0004, 15.03, 0.0007, 16.04, 0.0003, 17.03, 0.0001, 18.02, 0.0001, 21.04, 0.0003] Almf_ds4 = [1.00, 0.0762, 1.99, 0.0071, 2.99, 0.0085, 3.99, 0.0120, 4.98, 0.0064, 5.98, 0.0018, 6.98, 0.0039, 7.99, 0.0027, 8.96, 0.0017, 9.95, 0.0007, 10.98, 0.0006, 11.95, 0.0003, 12.98, 0.0006, 13.98, 0.0007, 15.97, 0.0002, 19.96, 0.0001] Almf_e4 = [0.99, 0.0726, 1.99, 0.0195, 2.99, 0.0147, 3.98, 0.0106, 4.99, 0.0069, 6.00, 0.0026, 6.99, 0.0046, 7.99, 0.0105, 8.97, 0.0017, 10.01, 0.0007, 10.97, 0.0022, 11.99, 0.0009, 12.99, 0.0011, 13.98, 0.0001, 14.96, 0.0002, 15.96, 0.0001, 16.99, 0.0001, 17.95, 0.0002, 18.98, 0.0002, 20.98, 0.0001, 21.97, 0.0001] Almf_f4 = [1.00, 0.0772, 2.00, 0.0150, 3.00, 0.0166, 4.01, 0.0118, 4.99, 0.0024, 6.01, 0.0067, 7.03, 0.0017, 8.00, 0.0012, 9.02, 0.0017, 10.02, 0.0011, 11.03, 0.0008, 12.04, 0.0004, 13.04, 0.0007, 14.03, 0.0002, 15.04, 0.0002, 16.04, 0.0001] Almf_fs4 = [0.99, 0.1309, 1.99, 0.0550, 2.98, 0.0321, 3.98, 0.0270, 4.97, 0.0070, 5.97, 0.0099, 6.96, 0.0041, 7.96, 0.0033, 8.95, 0.0023, 9.94, 0.0017, 10.94, 0.0023, 11.93, 0.0015, 12.93, 0.0006, 13.95, 0.0002, 14.93, 0.0002, 15.91, 0.0002, 16.91, 0.0003, 17.92, 0.0001, 18.90, 0.0003, 19.93, 0.0001, 22.87, 0.0001, 23.88, 0.0001] Almf_g4 = [0.99, 0.0515, 2.00, 0.0153, 3.00, 0.0281, 4.00, 0.0071, 5.01, 0.0020, 6.00, 0.0045, 7.02, 0.0006, 8.00, 0.0054, 8.99, 0.0020, 10.00, 0.0031, 11.01, 0.0023, 12.02, 0.0003, 13.00, 0.0004, 14.01, 0.0002, 15.02, 0.0003, 15.98, 0.0002, 16.02, 0.0002, 18.03, 0.0002, 19.01, 0.0001] Almf_gs4 = [1.00, 0.0592, 2.00, 0.0287, 3.00, 0.0196, 3.99, 0.0175, 4.99, 0.0168, 6.00, 0.0071, 6.07, 0.0008, 7.00, 0.0003, 7.99, 0.0019, 8.98, 0.0007, 9.98, 0.0012, 10.99, 0.0012, 11.98, 0.0004, 12.98, 0.0003, 13.99, 0.0002, 14.96, 0.0001, 15.98, 0.0001, 16.97, 0.0002, 17.96, 0.0002] Almf_a4 = [1.01, 0.0784, 2.01, 0.0480, 3.02, 0.0131, 4.02, 0.0074, 5.03, 0.0141, 6.03, 0.0173, 7.04, 0.0070, 8.04, 0.0033, 9.06, 0.0154, 9.12, 0.0016, 10.07, 0.0011, 11.07, 0.0013, 12.07, 0.0009, 13.09, 0.0008, 14.07, 0.0006, 15.09, 0.0002, 16.10, 0.0005, 17.10, 0.0003, 19.12, 0.0001, 23.14, 0.0001] Almf_as4 = [1.00, 0.0507, 2.00, 0.0304, 3.00, 0.0303, 4.00, 0.0084, 5.00, 0.0072, 6.00, 0.0098, 6.99, 0.0058, 8.01, 0.0036, 9.01, 0.0023, 10.00, 0.0010, 11.00, 0.0008, 12.00, 0.0007, 12.97, 0.0005, 13.02, 0.0004, 14.00, 0.0003, 14.99, 0.0003, 16.01, 0.0001, 17.01, 0.0002, 18.00, 0.0001, 20.01, 0.0001] Almf_b4 = [1.00, 0.0340, 2.00, 0.0113, 3.01, 0.0098, 4.02, 0.0033, 5.03, 0.0013, 6.05, 0.0008, 7.02, 0.0007, 8.07, 0.0006, 9.01, 0.0001] Almf_c5 = [1.00, 0.0384, 2.00, 0.0426, 3.01, 0.0092, 4.02, 0.0239, 5.02, 0.0184, 6.02, 0.0031, 7.03, 0.0029, 8.04, 0.0016, 8.10, 0.0006, 9.04, 0.0005, 10.04, 0.0003, 11.05, 0.0006, 12.05, 0.0007, 13.06, 0.0002, 15.07, 0.0002] Almf_cs5 = [1.00, 0.0159, 2.00, 0.0592, 3.00, 0.0390, 4.00, 0.0272, 5.00, 0.0121, 6.00, 0.0032, 7.01, 0.0124, 8.01, 0.0055, 9.00, 0.0009, 10.01, 0.0016, 11.01, 0.0007, 12.01, 0.0006, 13.02, 0.0020, 14.02, 0.0010, 15.02, 0.0007, 16.03, 0.0004, 17.03, 0.0002, 18.02, 0.0001, 19.03, 0.0001, 20.03, 0.0003, 21.03, 0.0002, 22.03, 0.0003, 23.03, 0.0002] Almf_d5 = [1.01, 0.0376, 2.01, 0.0409, 3.02, 0.0136, 4.03, 0.0016, 5.05, 0.0080, 6.05, 0.0044, 7.06, 0.0036, 8.07, 0.0018, 9.07, 0.0007, 10.08, 0.0011, 11.09, 0.0002, 12.09, 0.0004, 13.12, 0.0003, 14.11, 0.0001, 16.15, 0.0002, 17.16, 0.0001, 20.18, 0.0001] Almf_ds5 = [1.00, 0.0391, 2.01, 0.0445, 3.01, 0.0188, 4.02, 0.0329, 5.02, 0.0185, 6.02, 0.0311, 7.03, 0.0107, 8.03, 0.0032, 9.03, 0.0010, 10.03, 0.0009, 11.04, 0.0019, 12.04, 0.0019, 13.05, 0.0005, 14.06, 0.0004, 15.05, 0.0007, 16.06, 0.0002, 17.07, 0.0002, 18.08, 0.0002, 19.07, 0.0005, 20.07, 0.0003, 21.08, 0.0001] Almf_e5 = [1.00, 0.0869, 2.00, 0.0181, 3.01, 0.0252, 4.01, 0.0520, 5.01, 0.0040, 6.02, 0.0336, 7.02, 0.0108, 8.03, 0.0070, 9.03, 0.0023, 10.03, 0.0009, 11.03, 0.0017, 12.02, 0.0004, 13.04, 0.0012, 14.04, 0.0006, 15.05, 0.0016, 16.06, 0.0007, 17.06, 0.0003, 18.06, 0.0012, 19.07, 0.0001, 20.06, 0.0001] Almf_f5 = [1.01, 0.0905, 2.02, 0.0649, 3.02, 0.0406, 4.03, 0.0295, 5.04, 0.0038, 6.05, 0.0088, 7.06, 0.0009, 8.07, 0.0021, 9.07, 0.0037, 10.09, 0.0022, 11.09, 0.0014, 12.09, 0.0018, 13.11, 0.0006, 14.12, 0.0009, 15.13, 0.0004, 16.12, 0.0003, 17.14, 0.0006, 18.15, 0.0002] Almf_fs5 = [0.99, 0.0868, 1.98, 0.0447, 2.98, 0.0303, 3.97, 0.0092, 4.96, 0.0183, 5.95, 0.0121, 6.94, 0.0033, 7.95, 0.0010, 8.92, 0.0022, 9.92, 0.0007, 10.91, 0.0007, 11.90, 0.0007, 12.89, 0.0014, 13.87, 0.0004, 14.88, 0.0006, 14.91, 0.0003, 15.87, 0.0002, 16.85, 0.0003] Almf_g5 = [1.00, 0.0467, 2.00, 0.0739, 3.00, 0.0255, 4.00, 0.0277, 5.00, 0.0349, 6.00, 0.0119, 7.00, 0.0024, 8.00, 0.0085, 9.00, 0.0016, 9.99, 0.0012, 11.00, 0.0004, 11.99, 0.0014, 12.99, 0.0024, 13.99, 0.0017, 14.99, 0.0007, 15.99, 0.0004, 16.98, 0.0001] Almf_gs5 = [0.99, 0.0605, 1.99, 0.0384, 2.98, 0.0154, 3.98, 0.0036, 4.97, 0.0164, 5.96, 0.0039, 6.96, 0.0036, 7.95, 0.0040, 8.94, 0.0012, 9.94, 0.0006, 10.93, 0.0015, 11.93, 0.0012, 12.93, 0.0008, 13.91, 0.0010, 14.90, 0.0005, 15.91, 0.0001] Almf_a5 = [1.00, 0.1051, 2.01, 0.0322, 3.02, 0.0393, 4.03, 0.0112, 5.03, 0.0099, 6.04, 0.0074, 7.05, 0.0054, 8.05, 0.0030, 9.06, 0.0019, 10.07, 0.0006, 11.07, 0.0023, 12.08, 0.0004, 13.08, 0.0005, 14.09, 0.0006, 14.11, 0.0001, 15.11, 0.0001] Almf_as5 = [1.00, 0.0284, 2.01, 0.0161, 3.02, 0.0248, 4.03, 0.0414, 5.03, 0.0135, 6.04, 0.0028, 7.05, 0.0021, 8.06, 0.0006, 9.07, 0.0009, 10.07, 0.0010, 11.08, 0.0012, 12.10, 0.0003, 13.09, 0.0010, 14.10, 0.0003] Almf_b5 = [0.99, 0.0354, 1.98, 0.0173, 2.97, 0.0086, 3.96, 0.0204, 3.99, 0.0077, 4.03, 0.0067, 4.06, 0.0037, 4.95, 0.0034, 5.93, 0.0030, 5.96, 0.0015, 5.98, 0.0009, 6.92, 0.0007, 7.92, 0.0008, 8.91, 0.0017, 9.90, 0.0008, 9.93, 0.0006, 10.88, 0.0003, 11.91, 0.0003, 12.86, 0.0004, 12.90, 0.0002] Almf_c6 = [1.01, 0.0675, 2.01, 0.0578, 3.02, 0.0346, 4.03, 0.0170, 5.03, 0.0082, 6.04, 0.0050, 7.06, 0.0032, 8.03, 0.0009, 9.06, 0.0009, 10.07, 0.0008, 11.09, 0.0010, 12.03, 0.0002] Almf_cs6 = [1.00, 0.0896, 1.99, 0.0634, 3.01, 0.0037, 3.98, 0.0105, 4.98, 0.0030, 5.98, 0.0019, 6.97, 0.0020, 7.97, 0.0014, 8.00, 0.0007, 8.99, 0.0005, 9.96, 0.0005, 10.95, 0.0008, 10.98, 0.0005, 11.00, 0.0003, 11.02, 0.0003, 11.03, 0.0002, 11.06, 0.0002, 11.95, 0.0001, 11.98, 0.0001] Almf_d6 = [1.00, 0.0593, 2.00, 0.0364, 3.01, 0.0142, 4.01, 0.0065, 5.02, 0.0063, 6.01, 0.0024, 7.02, 0.0010, 8.02, 0.0019, 9.02, 0.0015, 10.03, 0.0007, 11.02, 0.0002] Almf_ds6 = [1.00, 0.0410, 1.99, 0.0353, 2.99, 0.0291, 3.99, 0.0089, 4.99, 0.0066, 5.98, 0.0023, 6.99, 0.0012, 7.96, 0.0011, 7.99, 0.0006, 8.94, 0.0004, 8.98, 0.0003, 9.95, 0.0001] Almf_e6 = [1.01, 0.0254, 2.01, 0.0252, 3.02, 0.0365, 4.03, 0.0034, 5.02, 0.0013, 6.02, 0.0010, 7.08, 0.0006, 8.02, 0.0010, 9.03, 0.0007, 9.12, 0.0004] Almf_f6 = [1.00, 0.1896, 2.00, 0.0411, 3.00, 0.0216, 4.00, 0.0019, 5.00, 0.0032, 6.01, 0.0012, 7.02, 0.0007, 7.99, 0.0026, 9.00, 0.0003, 9.03, 0.0002] Almf_fs6 = [1.01, 0.0285, 2.01, 0.0189, 3.02, 0.0213, 4.02, 0.0033, 5.03, 0.0024, 6.03, 0.0010, 7.04, 0.0016, 8.05, 0.0015, 9.05, 0.0003, 9.06, 0.0002] Almf_g6 = [1.00, 0.1939, 2.00, 0.0339, 3.00, 0.0219, 4.01, 0.0079, 5.01, 0.0025, 6.01, 0.0017, 7.01, 0.0014, 7.95, 0.0009, 8.00, 0.0006, 8.02, 0.0003] Almf_gs6 = [1.00, 0.1069, 2.00, 0.0146, 3.00, 0.0220, 4.00, 0.0046, 5.00, 0.0020, 6.00, 0.0027, 6.99, 0.0011, 8.00, 0.0003] Almf_a6 = [1.00, 0.0952, 1.99, 0.0201, 3.00, 0.0015, 3.99, 0.0064, 4.98, 0.0021, 5.97, 0.0009, 6.98, 0.0010] Almf_as6 = [1.00, 0.0132, 1.99, 0.0635, 2.99, 0.0057, 3.98, 0.0054, 3.99, 0.0034, 4.99, 0.0011, 5.96, 0.0012, 5.98, 0.0008, 5.99, 0.0007, 6.96, 0.0004, 6.98, 0.0004] Almf_b6 = [1.00, 0.0241, 2.01, 0.0417, 3.02, 0.0098, 3.99, 0.0016, 4.02, 0.0016, 5.03, 0.0016, 6.04, 0.0012] # # # # # snd-16.1/snd-nogui.c0000644000076400007640000010636712536120064012416 0ustar bilbil#include "snd.h" #include "snd-menu.h" #include "snd-file.h" void cleanup_file_monitor(void) {} void *unmonitor_file(void *watcher) {return(NULL);} void monitor_sound(snd_info *sp) {} bool find_dialog_is_active(void) {return(false);} void snd_help_back_to_top(void) {} color_t get_in_between_color(color_t fg, color_t bg) {return(0);} void save_find_dialog_state(FILE *fd) {} void check_menu_labels(int key, int state, bool extended) {} int add_channel_window(snd_info *sound, int channel, int chan_y, int insertion, widget_t main, fw_button_t arrows, bool with_events) {return(0);} int snd_help(const char *subject, const char *help, with_word_wrap_t with_wrap) {fprintf(stdout, "%s", help); return(0);} int snd_help_with_xrefs(const char *subject, const char *helpstr, with_word_wrap_t with_wrap, const char **xrefs, const char **urls) {return(0);} void snd_help_append(const char *text) {fprintf(stdout, "%s", text);} int help_text_width(const char *txt, int start, int end) {return(0);} widget_t post_it(const char *subject, const char *str) {fprintf(stdout, "%s", str); return(0);} void save_post_it_dialog_state(FILE *fd) {} void reflect_just_sounds(void) {} void reflect_save_as_src(bool val) {} void reflect_save_as_auto_comment(bool val) {} void reflect_save_as_sound_selection(const char *sound_name) {} void save_file_dialog_state(FILE *fd) {} void draw_line(graphics_context *ax, int x0, int y0, int x1, int y1) {} void fill_rectangle(graphics_context *ax, int x0, int y0, int width, int height) {} void fill_polygon(graphics_context *ax, int points, ...) {} void fill_polygons(graphics_context *ax, point_t *points, int num, int y0) {} void fill_two_sided_polygons(graphics_context *ax, point_t *points, point_t *points1, int num) {} void draw_string(graphics_context *ax, int x0, int y0, const char *str, int len) {} void draw_dot(graphics_context *ax, int x, int y, int size) {} void save_colors(FILE *Fp) {} void erase_rectangle(chan_info *cp, graphics_context *ax, int x0, int y0, int width, int height) {} void setup_graphics_context(chan_info *cp, graphics_context *ax) {} void draw_spectro_line(graphics_context *ax, int color, int x0, int y0, int x1, int y1) {} void allocate_color_map(int colormap) {} void allocate_sono_rects(int size) {} void set_with_gl(bool val, bool dpys) {} void set_sono_rectangle(int j, int color, int x, int y, int width, int height) {} void draw_sono_rectangles(graphics_context *ax, int color, int jmax) {} void draw_colored_lines(chan_info *cp, graphics_context *ax, point_t *points, int num, int *colors, int axis_y0, color_t default_color) {} widget_t make_color_orientation_dialog(bool managed) {return(0);} void set_color_scale(mus_float_t val) {} void set_color_inverted(bool val) {} void set_color_cutoff(mus_float_t val) {} void set_spectro_hop(int val) {} void set_spectro_x_angle(mus_float_t val) {} void set_spectro_y_angle(mus_float_t val) {} void set_spectro_z_angle(mus_float_t val) {} void set_spectro_x_scale(mus_float_t val) {} void set_spectro_y_scale(mus_float_t val) {} void set_spectro_z_scale(mus_float_t val) {} void set_spectrum_end(mus_float_t val) {} void set_spectrum_start(mus_float_t val) {} bool color_orientation_dialog_is_active(void) {return(false);} void reflect_spectro(void) {} void reflect_peaks_in_transform_dialog(void) {} void reflect_log_freq_start_in_transform_dialog(void) {} void reflect_min_db_in_transform_dialog(void) {} void listener_append_and_prompt(const char *msg) {fprintf(stderr, "%s", msg);} void goto_listener(void) {} int save_listener_text(FILE *fp) {return(0);} void append_listener_text(int end, const char *msg) {} void listener_append(const char *msg) {fprintf(stderr, "%s", msg);} void handle_listener(bool new_state) {} bool listener_exists(void) {return(false);} int listener_height(void) {return(0);} int listener_width(void) {return(0);} void set_button_label(int label, const char *str) {} int g_add_to_main_menu(const char *label, int slot) {return(0);} widget_t g_add_to_menu(int which_menu, const char *label, int callb, int position) {return(0);} int g_remove_from_menu(int which_menu, const char *label) {return(0);} void reflect_play_selection_stop(void) {} int make_transform_dialog(bool managed) {return(0);} bool transform_dialog_is_active(void) {return(false);} void set_show_transform_peaks(bool val) {} void set_fft_log_magnitude(bool val) {} void set_fft_with_phases(bool val) {} void set_fft_log_frequency(bool val) {} void set_transform_normalization(fft_normalize_t val) {} void set_show_selection_transform(bool show) {} void reflect_regions_in_region_browser(void) {} void reflect_selection_in_save_as_dialog(bool on) {} void reflect_no_regions_in_region_browser(void) {} int update_region_browser(bool grf_too) {return(0);} bool region_browser_is_active(void) {return(false);} void delete_region_and_update_browser(int n) {} void reflect_play_region_stop(int n) {} bool region_dialog_is_active(void) {return(false);} void allocate_region_rows(int n) {} void reflect_region_graph_style(void) {} bool set_tiny_font(const char *font) {if (ss->Tiny_Font) free(ss->Tiny_Font); ss->Tiny_Font = mus_strdup(font); return(false);} bool set_listener_font(const char *font) {if (ss->Listener_Font) free(ss->Listener_Font); ss->Listener_Font = mus_strdup(font); return(false);} bool set_peaks_font(const char *font) {if (ss->Peaks_Font) free(ss->Peaks_Font); ss->Peaks_Font = mus_strdup(font); return(false);} bool set_bold_peaks_font(const char *font) {if (ss->Bold_Peaks_Font) free(ss->Bold_Peaks_Font); ss->Bold_Peaks_Font = mus_strdup(font); return(false);} bool set_axis_label_font(const char *font) {if (ss->Axis_Label_Font) free(ss->Axis_Label_Font); ss->Axis_Label_Font = mus_strdup(font); return(false);} bool set_axis_numbers_font(const char *font) {if (ss->Axis_Numbers_Font) free(ss->Axis_Numbers_Font); ss->Axis_Numbers_Font = mus_strdup(font); return(false);} int label_width(const char *txt, bool use_tiny_font) {return(0);} int number_width(const char *num, bool use_tiny_font) {return(0);} int number_height(int fnt) {return(0);} int label_height(bool use_tiny_font) {return(0);} int mark_name_width(const char *txt) {return(0);} void clear_window(graphics_context *ax) {} void set_title(const char *title) {} void goto_window(int text) {} void check_for_event(void) {} void recolor_graph(chan_info *cp, bool selected) {} void set_sensitive(int wid, bool val) {} void set_toggle_button(int wid, bool val, bool passed, void *data) {} int widget_height(int w) {return(0);} int widget_width(int w) {return(0);} void set_widget_size(int w, int width, int height) {} int widget_x(int w) {return(0);} int widget_y(int w) {return(0);} void set_widget_x(int w, int x) {} void set_widget_y(int w, int y) {} void set_open_file_play_button(bool val) {} int channel_w(chan_info *cp) {return(0);} int channel_f(chan_info *cp) {return(0);} int channel_graph(chan_info *cp) {return(0);} bool channel_graph_is_visible(chan_info *cp) {return(false);} /* maybe this should be true? */ void change_gzy(mus_float_t val, chan_info *cp) {} mus_float_t gsy_value(chan_info *cp) {return(0.0);} mus_float_t gsy_size(chan_info *cp) {return(0.0);} void initialize_scrollbars(chan_info *cp) {} void set_z_scrollbars(chan_info *cp, axis_info *ap) {} void resize_sx(chan_info *cp) {} void resize_sy(chan_info *cp) {} void resize_sy_and_zy(chan_info *cp) {} void resize_sx_and_zx(chan_info *cp) {} void channel_open_pane(chan_info *cp) {} void reflect_edit_history_change(chan_info *cp) {} void reflect_edit_counter_change(chan_info *cp) {} void set_peak_numbers_font(chan_info *cp, graphics_context *ax) {} void set_bold_peak_numbers_font(chan_info *cp, graphics_context *ax) {} void set_tiny_numbers_font(chan_info *cp, graphics_context *ax) {} color_t get_foreground_color(graphics_context *ax) {return(0);} void set_foreground_color(graphics_context *ax, int color) {} void change_channel_style(snd_info *sp, channel_style_t new_style) {} void cleanup_cw(chan_info *cp) {} void set_status(snd_info *sp, const char *str, bool update) {if ((str) && (*str)) fprintf(stderr, "%s", str);} void snd_info_cleanup(snd_info *sp) {} void toggle_expand_button(snd_info *sp, bool state) {} void toggle_contrast_button(snd_info *sp, bool state) {} void toggle_reverb_button(snd_info *sp, bool state) {} void toggle_filter_button(snd_info *sp, bool state) {} void toggle_direction_arrow(snd_info *sp, bool state) {} void filter_env_changed(snd_info *sp, env *e) {} void set_play_button(snd_info *sp, bool val) {} void play_button_pause(bool pausing) {} void syncb(snd_info *sp, int on) {sp->sync = on; if (on > ss->sound_sync_max) ss->sound_sync_max = on;} void show_lock(snd_info *sp) {} void hide_lock(snd_info *sp) {} void start_bomb(snd_info *sp) {} void stop_bomb(snd_info *sp) {} void set_sound_pane_file_label(snd_info *sp, const char *str) {} void reflect_sound_selection(snd_info *sp) {} void show_controls(snd_info *sp) {} void hide_controls(snd_info *sp) {} bool showing_controls(snd_info *sp) {return(false);} void start_progress_report(chan_info *cp) {} void finish_progress_report(chan_info *cp) {} void progress_report(chan_info *cp, mus_float_t pct) {} char *get_file_dialog_sound_attributes(file_data *fdat, int *srate, int *chans, mus_header_t *header_type, mus_sample_t *sample_type, mus_long_t *location, mus_long_t *samples, int min_chan) {return(NULL);} widget_t make_new_file_dialog(bool managed) {return(0);} int edit_header(snd_info *sp) {return(0);} void save_edit_header_dialog_state(FILE *fd) {} widget_t make_selection_save_as_dialog(bool managed) {return(0);} widget_t make_region_save_as_dialog(bool managed) {return(0);} widget_t make_sound_save_as_dialog(bool managed) {return(0);} widget_t make_file_print_dialog(bool managed, bool direct_to_printer) {return(0);} axis_info *enved_make_axis(const char *name, graphics_context *ax, int ex0, int ey0, int width, int height, mus_float_t xmin, mus_float_t xmax, mus_float_t ymin, mus_float_t ymax, printing_t printing) {return(NULL);} void display_enved_env_with_selection(env *e, const char *name, int x0, int y0, int width, int height, bool dots, printing_t printing) {} void set_enved_redo_sensitive(bool val) {} void set_enved_revert_sensitive(bool val) {} void set_enved_undo_sensitive(bool val) {} void set_enved_save_sensitive(bool val) {} void set_enved_show_sensitive(bool val) {} void enved_reflect_selection(bool on) {} void make_scrolled_env_list(void) {} void enved_reflect_peak_env_completion(snd_info *sp) {} void new_active_channel_alert(void) {} void env_redisplay(void) {} void env_redisplay_with_print(void) {} void update_enved_background_waveform(chan_info *cp) {} int create_envelope_editor(void) {return(0);} void set_enved_clipping(bool val) {} void reflect_enved_style(void) {} void set_enved_base(mus_float_t val) {} void set_enved_target(enved_target_t val) {} void set_enved_with_wave(bool val) {} void set_enved_in_dB(bool val) {} bool enved_dialog_is_active(void) {return(false);} void set_enved_filter_order(int order) {} widget_t make_open_file_dialog(read_only_t read_only, bool managed) {return(0);} widget_t make_mix_file_dialog(bool managed) {return(0);} widget_t make_insert_file_dialog(bool managed) {return(0);} void clear_listener(void) {} int menu_widget(int which_menu) {return(0);} void get_current_color(int colormap, int j, rgb_t *r, rgb_t *g, rgb_t *b) {} void set_filter_text(snd_info *sp, const char *str) {} void display_filter_env(snd_info *sp) {} void reflect_mix_change(int mix_id) {} int make_mix_dialog(void) {return(0);} void reflect_mix_play_stop(void) {} void set_mix_color(int color) {} int mix_dialog_mix(void) {return(0);} void mix_dialog_set_mix(int id) {} void set_fft_window_alpha(mus_float_t val) {in_set_fft_window_alpha(val);} void set_fft_window_beta(mus_float_t val) {in_set_fft_window_beta(val);} void set_transform_size(mus_long_t val) {in_set_transform_size(val);} void set_fft_window(mus_fft_window_t val) {in_set_fft_window(val);} void set_transform_type(int val) {in_set_transform_type(val);} void set_wavelet_type(int val) {in_set_wavelet_type(val);} void make_transform_type_list(void) {} void set_transform_graph_type(graph_type_t val) {in_set_transform_graph_type(val);} void set_amp(snd_info *sp, mus_float_t val) {sp->amp_control = val;} void set_expand(snd_info *sp, mus_float_t val) {sp->expand_control = val;} void set_contrast(snd_info *sp, mus_float_t val) {sp->contrast_control = val;} void set_speed(snd_info *sp, mus_float_t val) {sp->speed_control = val;} void set_revlen(snd_info *sp, mus_float_t val) {sp->reverb_control_length = val;} void set_revscl(snd_info *sp, mus_float_t val) {sp->reverb_control_scale = val;} void set_filter_order(snd_info *sp, int val) {sp->filter_control_order = val;} void set_filter_in_dB(snd_info *sp, bool val) {sp->filter_control_in_dB = val;} void set_filter_in_hz(snd_info *sp, bool val) {sp->filter_control_in_hz = val;} void post_basic_popup_menu(void *ev) {} void post_lisp_popup_menu(void *ev) {} void post_fft_popup_menu(void *ev) {} void post_selection_popup_menu(void *ev) {} void ensure_scrolled_window_row_visible(widget_t list, int pos, int num_rows) {} widget_t make_preferences_dialog(void) {return(NULL_WIDGET);} void update_sound_label(snd_info *sp) {} void auto_update_restart(void) {} snd_info *add_sound_window(char *filename, read_only_t read_only, file_info *hdr) { snd_info *sp; int snd_slot, nchans, i; bool free_filename = false; if (ss->translated_filename) { filename = ss->translated_filename; free_filename = true; ss->translated_filename = NULL; } nchans = hdr->chans; if (nchans <= 0) nchans = 1; if (nchans > 256) { /* either a screwed up header, or Snd was built with wrong endianess */ /* this kind of error is trapped by raw_data_explanation in make_file_info in the motif/gtk cases */ fprintf(stderr, "%s has %d channels? ", filename, nchans); if (mus_char_to_bint((unsigned char *)&nchans) < 8) fprintf(stderr, "byte swap problem: chans should be %d", mus_char_to_bint((unsigned char *)&nchans)); if (mus_char_to_lint((unsigned char *)&nchans) < 8) fprintf(stderr, "byte swap problem: chans should be %d", mus_char_to_lint((unsigned char *)&nchans)); nchans = 1; /* ?? */ } snd_slot = find_free_sound_slot(nchans); /* expands sound list if needed */ ss->sounds[snd_slot] = make_snd_info(ss->sounds[snd_slot], filename, hdr, snd_slot, read_only); sp = ss->sounds[snd_slot]; sp->write_date = file_write_date(filename); /* needed early in this process by the peak-env handlers */ for (i = 0; i < nchans; i++) sp->chans[i] = make_chan_info(sp->chans[i], i, sp); add_sound_data(filename, sp, WITHOUT_GRAPH); after_open(sp); if (free_filename) free(filename); return(sp); } static char **auto_open_file_names = NULL; static int auto_open_files = 0; static bool noglob = false, noinit = false, nostdin = false; #ifndef _MSC_VER #include static jmp_buf top_level_jump; void top_level_catch(int ignore); void top_level_catch(int ignore) { longjmp(top_level_jump, 1); } #endif #define FALLBACK_FONT "9x15" static Xen colormap_temp[16]; /* static for Ruby's sake */ void snd_doit(int argc, char **argv) { static int auto_open_ctr = 0; int i; ss->axis_color_set = false; #if HAVE_SCHEME xen_s7_set_repl_prompt("snd> "); #endif Xen_define_variable("black-and-white-colormap", colormap_temp[0], C_int_to_Xen_integer(0)); Xen_define_variable("gray-colormap", colormap_temp[1], C_int_to_Xen_integer(1)); Xen_define_variable("hot-colormap", colormap_temp[2], C_int_to_Xen_integer(2)); Xen_define_variable("cool-colormap", colormap_temp[3], C_int_to_Xen_integer(3)); Xen_define_variable("bone-colormap", colormap_temp[4], C_int_to_Xen_integer(4)); Xen_define_variable("copper-colormap", colormap_temp[5], C_int_to_Xen_integer(5)); Xen_define_variable("pink-colormap", colormap_temp[6], C_int_to_Xen_integer(6)); Xen_define_variable("jet-colormap", colormap_temp[7], C_int_to_Xen_integer(7)); Xen_define_variable("prism-colormap", colormap_temp[8], C_int_to_Xen_integer(8)); Xen_define_variable("autumn-colormap", colormap_temp[9], C_int_to_Xen_integer(9)); Xen_define_variable("winter-colormap", colormap_temp[10], C_int_to_Xen_integer(10)); Xen_define_variable("spring-colormap", colormap_temp[11], C_int_to_Xen_integer(11)); Xen_define_variable("summer-colormap", colormap_temp[12], C_int_to_Xen_integer(12)); Xen_define_variable("rainbow-colormap", colormap_temp[13], C_int_to_Xen_integer(13)); Xen_define_variable("flag-colormap", colormap_temp[14], C_int_to_Xen_integer(14)); Xen_define_variable("phases-colormap", colormap_temp[15], C_int_to_Xen_integer(15)); #if HAVE_SCHEME Xen_eval_C_string("(define " S_color_hook " (make-hook))"); Xen_eval_C_string("(define " S_drop_hook " (make-hook 'name))"); Xen_eval_C_string("(define " S_listener_click_hook " (make-hook 'position)) "); Xen_eval_C_string("(define " S_mouse_enter_graph_hook " (make-hook 'snd 'chn))"); Xen_eval_C_string("(define " S_mouse_enter_label_hook " (make-hook 'type 'position 'label))"); Xen_eval_C_string("(define " S_mouse_enter_listener_hook " (make-hook 'widget))"); Xen_eval_C_string("(define " S_mouse_enter_text_hook " (make-hook 'widget))"); Xen_eval_C_string("(define " S_mouse_leave_graph_hook " (make-hook 'snd 'chn))"); Xen_eval_C_string("(define " S_mouse_leave_label_hook " (make-hook 'type 'position 'label))"); Xen_eval_C_string("(define " S_mouse_leave_listener_hook " (make-hook 'widget))"); Xen_eval_C_string("(define " S_mouse_leave_text_hook " (make-hook 'widget))"); Xen_eval_C_string("(define " S_new_widget_hook " (make-hook 'widget))"); Xen_eval_C_string("(define " S_orientation_hook " (make-hook))"); Xen_eval_C_string("(define " S_copy_context " 0)"); Xen_eval_C_string("(define " S_cursor_context " 3)"); Xen_eval_C_string("(define " S_lisp_graph " 2)"); Xen_eval_C_string("(define " S_mark_context " 4)"); Xen_eval_C_string("(define " S_selection_context " 2)"); Xen_eval_C_string("(define " S_time_graph " 0)"); Xen_eval_C_string("(define " S_transform_graph " 1)"); Xen_eval_C_string("(define " S_basic_color " (dilambda (lambda () #f) (lambda (val) val)))"); Xen_eval_C_string("(define " S_colormap " (dilambda (lambda () #f) (lambda (val) val)))"); Xen_eval_C_string("(define " S_colormap_size " (dilambda (lambda () #f) (lambda (val) val)))"); Xen_eval_C_string("(define " S_cursor_color " (dilambda (lambda () #f) (lambda (val) val)))"); Xen_eval_C_string("(define " S_data_color " (dilambda (lambda () #f) (lambda (val) val)))"); Xen_eval_C_string("(define " S_enved_envelope " (dilambda (lambda () #f) (lambda (val) val)))"); Xen_eval_C_string("(define " S_enved_filter " (dilambda (lambda () #f) (lambda (val) val)))"); Xen_eval_C_string("(define " S_enved_waveform_color " (dilambda (lambda () #f) (lambda (val) val)))"); Xen_eval_C_string("(define " S_filter_control_waveform_color " (dilambda (lambda () #f) (lambda (val) val)))"); Xen_eval_C_string("(define " S_graph_color " (dilambda (lambda () #f) (lambda (val) val)))"); Xen_eval_C_string("(define " S_graph_cursor " (dilambda (lambda () #f) (lambda (val) val)))"); Xen_eval_C_string("(define " S_listener_color " (dilambda (lambda () #f) (lambda (val) val)))"); Xen_eval_C_string("(define " S_listener_text_color " (dilambda (lambda () #f) (lambda (val) val)))"); Xen_eval_C_string("(define " S_axis_color " (dilambda (lambda () #f) (lambda (val) val)))"); Xen_eval_C_string("(define " S_mark_color " (dilambda (lambda args #f) (lambda args #f)))"); Xen_eval_C_string("(define " S_mix_color " (dilambda (lambda args #f) (lambda args #f)))"); Xen_eval_C_string("(define " S_combined_data_color " (dilambda (lambda args #f) (lambda args #f)))"); Xen_eval_C_string("(define " S_position_color " (dilambda (lambda () #f) (lambda (val) val)))"); Xen_eval_C_string("(define " S_foreground_color " (dilambda (lambda args #f) (lambda args (car args))))"); Xen_eval_C_string("(define " S_sash_color " (dilambda (lambda () #f) (lambda (val) val)))"); Xen_eval_C_string("(define " S_selected_data_color " (dilambda (lambda () #f) (lambda (val) val)))"); Xen_eval_C_string("(define " S_selected_graph_color " (dilambda (lambda () #f) (lambda (val) val)))"); Xen_eval_C_string("(define " S_text_focus_color " (dilambda (lambda () #f) (lambda (val) val)))"); Xen_eval_C_string("(define " S_x_axis_label " (dilambda (lambda args \"\") (lambda args \"\")))"); Xen_eval_C_string("(define " S_y_axis_label " (dilambda (lambda args \"\") (lambda args \"\")))"); Xen_eval_C_string("(define " S_zoom_color " (dilambda (lambda () #f) (lambda (val) val)))"); Xen_eval_C_string("(define " S_widget_size " (dilambda (lambda (w) #f) (lambda (w val) val)))"); Xen_eval_C_string("(define " S_widget_position " (dilambda (lambda (w) #f) (lambda (w val) val)))"); Xen_eval_C_string("(define (" S_make_cairo " . args) #f)"); Xen_eval_C_string("(define (" S_free_cairo " . args) #f)"); Xen_eval_C_string("(define (" S_axis_info " . args) #f)"); Xen_eval_C_string("(define (" S_channel_widgets " . args) #f)"); Xen_eval_C_string("(define (" S_is_color " obj) #f)"); Xen_eval_C_string("(define (" S_color_to_list " obj) #f)"); Xen_eval_C_string("(define (" S_is_colormap " obj) #f)"); Xen_eval_C_string("(define (" S_current_font " . args) #f)"); Xen_eval_C_string("(define (" S_dialog_widgets ") #f)"); Xen_eval_C_string("(define (" S_graph_data " . args) #f)"); Xen_eval_C_string("(define (" S_in " . args) #f)"); Xen_eval_C_string("(define (" S_main_widgets ") #f)"); Xen_eval_C_string("(define (" S_make_color " . args) #f)"); Xen_eval_C_string("(define (" S_make_graph_data " . args) #f)"); Xen_eval_C_string("(define (" S_menu_widgets " . args) #f)"); Xen_eval_C_string("(define (" S_reset_listener_cursor ") #f)"); Xen_eval_C_string("(define (" S_sound_widgets " . args) #f)"); Xen_eval_C_string("(define (" S_view_regions_dialog " . args) #f)"); Xen_eval_C_string("(define (" S_find_dialog " . args) #f)"); Xen_eval_C_string("(define (" S_widget_text " . args) \"\")"); Xen_eval_C_string("(define (" S_goto_listener_end ") #f)"); Xen_eval_C_string("(define (" S_y_to_position " . args) #f)"); Xen_eval_C_string("(define (" S_x_to_position " . args) #f)"); Xen_eval_C_string("(define (" S_snd_gcs " . args) #f)"); Xen_eval_C_string("(define (" S_show_widget " . args) #f)"); Xen_eval_C_string("(define (" S_position_to_y " . args) #f)"); Xen_eval_C_string("(define (" S_position_to_x " . args) #f)"); Xen_eval_C_string("(define (" S_listener_selection " . args) #f)"); Xen_eval_C_string("(define (" S_hide_widget " arg) #f)"); Xen_eval_C_string("(define (" S_focus_widget " arg) #f)"); Xen_eval_C_string("(define (" S_fill_rectangle " . args) #f)"); Xen_eval_C_string("(define (" S_fill_polygon " . args) #f)"); Xen_eval_C_string("(define (" S_draw_string " . args) #f)"); Xen_eval_C_string("(define (" S_draw_lines " . args) #f)"); Xen_eval_C_string("(define (" S_draw_line " . args) #f)"); Xen_eval_C_string("(define (" S_draw_dots " . args) #f)"); Xen_eval_C_string("(define (" S_draw_dot " . args) #f)"); Xen_eval_C_string("(define (" S_draw_axes " . args) #f)"); Xen_eval_C_string("(define (" S_delete_colormap " . args) #f)"); Xen_eval_C_string("(define (" S_colormap_ref " . args) #f)"); Xen_eval_C_string("(define (" S_colormap_name " arg) #f)"); Xen_eval_C_string("(define (" S_add_colormap " . args) #f)"); Xen_eval_C_string("(define " S_x_bounds " (dilambda (lambda args #f) (lambda args #f)))"); Xen_eval_C_string("(define " S_y_bounds " (dilambda (lambda args #f) (lambda args #f)))"); #endif #if HAVE_RUBY Xen_eval_C_string("def make_cairo (a) false end"); Xen_eval_C_string("def free_cairo (a) false end"); Xen_eval_C_string("def axis_info (s, c, a) false end"); Xen_eval_C_string("def channel_widgets (s, c) false end"); Xen_eval_C_string("def color? (a) false end"); Xen_eval_C_string("def color_to_list (a) false end"); Xen_eval_C_string("def current_font () false end"); Xen_eval_C_string("def dialog_widgets () false end"); Xen_eval_C_string("def enved_filter () false end"); Xen_eval_C_string("def main_widgets (s) false end"); Xen_eval_C_string("def make_color (r, g, b) false end"); Xen_eval_C_string("def menu_widgets (s) false end"); Xen_eval_C_string("def reset_listener_cursor () false end"); Xen_eval_C_string("def sound_widgets (s) false end"); Xen_eval_C_string("def view_regions_dialog () false end"); Xen_eval_C_string("def find_dialog () false end"); Xen_eval_C_string("def x_axis_label () false end"); Xen_eval_C_string("def y_axis_label () false end"); Xen_eval_C_string("def basic_color () false end"); Xen_eval_C_string("def set_basic_color (a) false end"); Xen_eval_C_string("def colormap () false end"); Xen_eval_C_string("def set_colormap (a) false end"); Xen_eval_C_string("def colormap_size () false end"); Xen_eval_C_string("def set_colormap_size (a) false end"); Xen_eval_C_string("def cursor_color () false end"); Xen_eval_C_string("def set_cursor_color (a) false end"); Xen_eval_C_string("def data_color () false end"); Xen_eval_C_string("def set_data_color (a) false end"); Xen_eval_C_string("def enved_envelope () false end"); Xen_eval_C_string("def set_enved_envelope (a) false end"); Xen_eval_C_string("def enved_waveform_color () false end"); Xen_eval_C_string("def set_enved_waveform_color (a) false end"); Xen_eval_C_string("def filter_control_waveform_color () false end"); Xen_eval_C_string("def set_filter_control_waveform_color (a) false end"); Xen_eval_C_string("def graph_color () false end"); Xen_eval_C_string("def set_graph_color (a) false end"); Xen_eval_C_string("def graph_cursor () false end"); Xen_eval_C_string("def set_graph_cursor (a) false end"); Xen_eval_C_string("def listener_color () false end"); Xen_eval_C_string("def set_listener_color (a) false end"); Xen_eval_C_string("def listener_text_color () false end"); Xen_eval_C_string("def set_listener_text_color (a) false end"); Xen_eval_C_string("def mark_color () false end"); Xen_eval_C_string("def set_mark_color (m) false end"); Xen_eval_C_string("def mix_color () false end"); Xen_eval_C_string("def set_mix_color (m) false end"); Xen_eval_C_string("def combined_data_color (a b) false end"); Xen_eval_C_string("def set_combined_data_color (a b c) false end"); Xen_eval_C_string("def position_color () false end"); Xen_eval_C_string("def set_position_color (a) false end"); Xen_eval_C_string("def foreground_color () false end"); Xen_eval_C_string("def set_foreground_color (a) false end"); Xen_eval_C_string("def sash_color () false end"); Xen_eval_C_string("def set_sash_color (a) false end"); Xen_eval_C_string("def selected_data_color () false end"); Xen_eval_C_string("def set_selected_data_color (a) false end"); Xen_eval_C_string("def selected_graph_color () false end"); Xen_eval_C_string("def set_selected_graph_color (a) false end"); Xen_eval_C_string("def text_focus_color () false end"); Xen_eval_C_string("def set_text_focus_color (a) false end"); Xen_eval_C_string("def zoom_color () false end"); Xen_eval_C_string("def set_zoom_color (a) false end"); Xen_eval_C_string("def widget_size () false end"); Xen_eval_C_string("def set_widget_size (a) false end"); Xen_eval_C_string("def widget_position () false end"); Xen_eval_C_string("def set_widget_position (a) false end"); Xen_eval_C_string("def colormap? (a) false end"); Xen_eval_C_string("def in (a, b) false end"); Xen_eval_C_string("def widget_text (a) false end"); Xen_eval_C_string("def y2position (a) false end"); Xen_eval_C_string("def x2position (a) false end"); Xen_eval_C_string("def position2y (a) false end"); Xen_eval_C_string("def position2x (a) false end"); Xen_eval_C_string("def snd_gcs (a) false end"); Xen_eval_C_string("def show_widget (a) false end"); Xen_eval_C_string("def listener_selection (a) false end"); Xen_eval_C_string("def hide_widget (a) false end"); Xen_eval_C_string("def focus_widget (a) false end"); Xen_eval_C_string("def fill_rectangle (a) false end"); Xen_eval_C_string("def fill_polygon (a) false end"); Xen_eval_C_string("def draw_string (a) false end"); Xen_eval_C_string("def draw_lines (a) false end"); Xen_eval_C_string("def draw_line (a) false end"); Xen_eval_C_string("def draw_dots (a) false end"); Xen_eval_C_string("def draw_dot (a) false end"); Xen_eval_C_string("def draw_axes (a) false end"); Xen_eval_C_string("def delete_colormap (a) false end"); Xen_eval_C_string("def colormap_ref (a) false end"); Xen_eval_C_string("def colormap_name (a) false end"); Xen_eval_C_string("def add_colormap (a) false end"); Xen_eval_C_string("def make_graph_data (a, b, c) false end"); Xen_eval_C_string("def graph_data (a, b, c) false end"); Xen_eval_C_string("$drop_hook = false"); Xen_eval_C_string("$listener_click_hook = false"); Xen_eval_C_string("$mouse_enter_graph_hook = false"); Xen_eval_C_string("$mouse_enter_label_hook = false"); Xen_eval_C_string("$mouse_enter_listener_hook = false"); Xen_eval_C_string("$mouse_enter_text_hook = false"); Xen_eval_C_string("$mouse_leave_graph_hook = false"); Xen_eval_C_string("$mouse_leave_label_hook = false"); Xen_eval_C_string("$mouse_leave_listener_hook = false"); Xen_eval_C_string("$mouse_leave_text_hook = false"); Xen_eval_C_string("$new_widget_hook = false"); Xen_eval_C_string("$orientation_hook = false"); Xen_eval_C_string("Copy_context = 0"); Xen_eval_C_string("Cursor_context = 3"); Xen_eval_C_string("Lisp_graph = 2"); Xen_eval_C_string("Mark_context = 4"); Xen_eval_C_string("Selection_context = 2"); Xen_eval_C_string("Time_graph = 0"); Xen_eval_C_string("Transform_graph = 1"); Xen_eval_C_string("def x_bounds (s, c, a) false end"); Xen_eval_C_string("def set_x_bounds (s, c, ax, a) false end"); Xen_eval_C_string("def y_bounds (s, c, a) false end"); Xen_eval_C_string("def set_y_bounds (s, c, ax, a) false end"); #endif #if HAVE_FORTH Xen_eval_C_string("\ 0 #f create-hook " S_color_hook "\n\ 1 #f create-hook " S_drop_hook "\n\ 1 #f create-hook " S_listener_click_hook "\n\ 2 #f create-hook " S_mouse_enter_graph_hook "\n\ 3 #f create-hook " S_mouse_enter_label_hook "\n\ 1 #f create-hook " S_mouse_enter_listener_hook "\n\ 1 #f create-hook " S_mouse_enter_text_hook "\n\ 2 #f create-hook " S_mouse_leave_graph_hook "\n\ 3 #f create-hook " S_mouse_leave_label_hook "\n\ 1 #f create-hook " S_mouse_leave_listener_hook "\n\ 1 #f create-hook " S_mouse_leave_text_hook "\n\ 1 #f create-hook " S_new_widget_hook "\n\ 0 #f create-hook " S_orientation_hook "\n"); Xen_eval_C_string("\ 0 constant " S_copy_context "\n\ 3 constant " S_cursor_context "\n\ 2 constant " S_lisp_graph "\n\ 4 constant " S_mark_context "\n\ 2 constant " S_selection_context "\n\ 0 constant " S_time_graph "\n\ 1 constant " S_transform_graph "\n"); Xen_eval_C_string("\ : " S_basic_color " #f ;\n\ : set-" S_basic_color " { a } #f ;\n\ : " S_colormap " #f ;\n\ : set-" S_colormap " { a } #f ;\n\ : " S_colormap_size " #f ;\n\ : set-" S_colormap_size " { a } #f ;\n\ : " S_cursor_color " #f ;\n\ : set-" S_cursor_color " { a } #f ;\n\ : " S_data_color " #f ;\n\ : set-" S_data_color " { a } #f ;\n\ : " S_enved_envelope " #f ;\n\ : set-" S_enved_envelope " { a } #f ;\n\ : " S_enved_filter " #f ;\n\ : set-" S_enved_filter " { a } #f ;\n\ : " S_enved_waveform_color " #f ;\n\ : set-" S_enved_waveform_color " { a } #f ;\n\ : " S_filter_control_waveform_color " #f ;\n\ : set-" S_filter_control_waveform_color " { a } #f ;\n\ : " S_graph_color " #f ;\n\ : set-" S_graph_color " { a } #f ;\n\ : " S_graph_cursor " #f ;\n\ : set-" S_graph_cursor " { a } #f ;\n\ : " S_listener_color " #f ;\n\ : set-" S_listener_color " { a } #f ;\n\ : " S_listener_text_color " #f ;\n\ : set-" S_listener_text_color " { a } #f ;\n\ : " S_mark_color " #f ;\n\ : set-" S_mark_color " { a } #f ;\n\ : " S_mix_color " #f ;\n\ : set-" S_mix_color " { a } #f ;\n\ : " S_combined_data_color " #f ;\n\ : set-" S_combined_data_color " { a } #f ;\n\ : " S_position_color " #f ;\n\ : set-" S_position_color " { a } #f ;\n\ : " S_sash_color " #f ;\n\ : set-" S_sash_color " { a } #f ;\n\ : " S_selected_data_color " #f ;\n\ : set-" S_selected_data_color " { a } #f ;\n\ : " S_selected_graph_color " #f ;\n\ : set-" S_selected_graph_color " { a } #f ;\n\ : " S_text_focus_color " #f ;\n\ : set-" S_text_focus_color " { a } #f ;\n\ : " S_x_axis_label " #f ;\n\ : set-" S_x_axis_label " { a } #f ;\n\ : " S_y_axis_label " #f ;\n\ : set-" S_y_axis_label " { a } #f ;\n\ : " S_zoom_color " #f ;\n\ : set-" S_zoom_color " { a } #f ;\n\ : " S_make_cairo " { a } #f ;\n\ : " S_free_cairo " { a } #f ;\n\ : " S_axis_info " { s c a } #f ;\n\ : " S_x_bounds " { s c a } #f ;\n\ : set-" S_x_bounds " { a } #f ;\n\ : " S_y_bounds " { s c a } #f ;\n\ : set-" S_y_bounds " { a } #f ;\n\ : " S_channel_widgets " { s c } #f ;\n\ : " S_is_color " { a } #f ;\n\ : " S_color_to_list " { a } #f ;\n\ : " S_is_colormap " { a } #f ;\n\ : " S_current_font " #f ;\n\ : " S_dialog_widgets " #f ;\n\ : " S_focus_widget " #f ;\n\ : " S_graph_data " { a b c } #f ;\n\ : " S_in " { a b } #f ;\n\ : " S_main_widgets " { s } #f ;\n\ : " S_make_color " { r g b } #f ;\n\ : " S_make_graph_data " { a b c } #f ;\n\ : " S_menu_widgets " { s } #f ;\n\ : " S_reset_listener_cursor " #f ;\n\ : " S_sound_widgets " { s } #f ;\n\ : " S_view_regions_dialog " #f ;\n\ : " S_widget_text " { a } #f ;\n\ : " S_goto_listener_end " #f ;\n"); #endif set_peaks_font(FALLBACK_FONT); set_tiny_font(FALLBACK_FONT); set_bold_peaks_font(FALLBACK_FONT); set_axis_label_font(FALLBACK_FONT); set_axis_numbers_font(FALLBACK_FONT); set_listener_font(FALLBACK_FONT); ss->startup_title = mus_strdup("snd"); for (i = 1; i < argc; i++) { if (mus_strcmp(argv[i], "-noglob")) noglob = true; else if (mus_strcmp(argv[i], "-noinit")) noinit = true; else if (mus_strcmp(argv[i], "-nostdin")) nostdin = true; else if ((mus_strcmp(argv[i], "-b")) || (mus_strcmp(argv[i], "-batch"))) ss->batch_mode = true; else if (mus_strcmp(argv[i], "--features")) /* testing (compsnd) */ check_features_list(argv[i + 1]); } snd_load_init_file(noglob, noinit); #if (!_MSC_VER) && !__MINGW32__ signal(SIGTTIN, SIG_IGN); signal(SIGTTOU, SIG_IGN); #endif #ifndef _MSC_VER if (setjmp(top_level_jump)) { if (!(ss->jump_ok)) snd_error_without_format("Caught top level error (will try to continue):\n"); else ss->jump_ok = false; } else { #endif auto_open_files = argc - 1; if (argc > 1) auto_open_file_names = (char **)(argv + 1); while (auto_open_ctr < auto_open_files) auto_open_ctr = handle_next_startup_arg(auto_open_ctr, auto_open_file_names, false, auto_open_files); #ifndef _MSC_VER } #endif if ((ss->sounds) && (ss->sounds[0]) && ((ss->sounds[0])->inuse == SOUND_NORMAL)) select_channel(ss->sounds[0], 0); #if HAVE_SCHEME if (!nostdin) { s7_load(s7, "repl.scm"); if ((listener_prompt(ss)) && (strcmp(listener_prompt(ss), DEFAULT_LISTENER_PROMPT) != 0)) s7_eval_c_string(s7, "(set! (*repl* 'prompt) \ (lambda (num) \ (with-let (sublet (*repl* 'repl-let) :num num) \ (set! prompt-string (format #f \"(~D)~A\" num *listener-prompt*)) \ (set! prompt-length (length prompt-string)))))"); s7_eval_c_string(s7, "((*repl* 'run))"); } #else if (!nostdin) xen_repl(1, argv); #endif } snd-16.1/audio.c0000644000076400007640000050717312571434530011621 0ustar bilbil/* Audio hardware handlers (OSS, ALSA, Sun, Windows, Mac OSX, Jack, HPUX, NetBSD, OpenBSD, pulseaudio, portaudio) * * In many cases, only callback driven transfers are supported, so ideally we'd have: * int mus_audio_playback(caller_data, start_func, fill_func, end_func) * returns error indication or MUS_NO_ERROR * calls start_func at startup: void start(caller_data, ...)? * each times it needs a bufferfull, calls fill_func: bool fill(caller_data, void *buf, buf_size_in_samples, buf_data_type) * perhaps returns false to signal normal quit? * at end (either via fill or some interrupt), calls end(caller_data, ...)? */ /* * layout of this file: * error handlers * OSS * ALSA * Sun * Windows 95/98 * OSX * JACK * HPUX * NetBSD/OpenBSD * PulseAudio (in progress?) * PortAudio */ /* * int mus_audio_open_output(int dev, int srate, int chans, mus_sample_t samp_type, int size) * int mus_audio_open_input(int dev, int srate, int chans, mus_sample_t samp_type, int size) * int mus_audio_write(int line, char *buf, int bytes) * int mus_audio_close(int line) * int mus_audio_read(int line, char *buf, int bytes) * int mus_audio_initialize(void) does whatever is needed to get set up * char *mus_audio_moniker(void) returns some brief description of the overall audio setup (don't free return string). */ #include "mus-config.h" #if USE_SND && __APPLE__ && USE_MOTIF #undef USE_MOTIF #define USE_NO_GUI 1 /* Xt's Boolean (/usr/include/X11/Intrinsic.h = char) collides with MacTypes.h Boolean, (actually, * unsigned char in /Developer/SDKs/MacOSX10.4u.sdk/System/Library/Frameworks/CoreFoundation.framework/Versions/A/Headers/CFBase.h) * but we want snd.h for other stuff, so, if Motif is in use, don't load its headers at this time * perhaps we could use the -funsigned-char switch in gcc */ #endif #if USE_SND && __APPLE__ && HAVE_RUBY /* if using Ruby, OpenTransport.h T_* definitions collide with Ruby's -- it isn't needed here, so... */ #define REDEFINE_HAVE_RUBY 1 #undef HAVE_RUBY #endif #if USE_SND #include "snd.h" #else #define PRINT_BUFFER_SIZE 512 #define LABEL_BUFFER_SIZE 64 #endif #if USE_SND && __APPLE__ #define USE_MOTIF 1 #undef USE_NO_GUI #if REDEFINE_HAVE_RUBY #define HAVE_RUBY 1 #endif #endif #include #include #include #include #include #ifndef _MSC_VER #include #endif #include #ifdef __APPLE__ #include #include /* these pull in stdbool.h apparently, so they have to precede sndlib.h */ #endif #define HAVE_JACK_IN_LINUX (MUS_JACK && __linux__) #include "_sndlib.h" #include "sndlib-strings.h" #if WITH_AUDIO enum {MUS_AUDIO_IGNORED, MUS_AUDIO_DUPLEX_DEFAULT, MUS_AUDIO_LINE_OUT, MUS_AUDIO_LINE_IN, MUS_AUDIO_MICROPHONE, MUS_AUDIO_SPEAKERS, MUS_AUDIO_DIGITAL_OUT, MUS_AUDIO_DAC_OUT, MUS_AUDIO_MIXER, MUS_AUDIO_AUX_OUTPUT }; #define mus_standard_error(Error_Type, Error_Message) \ mus_print("%s\n [%s[%d] %s]", Error_Message, __FILE__, __LINE__, __func__) #define mus_standard_io_error(Error_Type, IO_Func, IO_Name) \ mus_print("%s %s: %s\n [%s[%d] %s]", IO_Func, IO_Name, strerror(errno), __FILE__, __LINE__, __func__) static char *version_name = NULL; static bool audio_initialized = false; /* ------------------------------- OSS ----------------------------------------- */ /* Thanks to Yair K. for OSS v4 changes. 22-Jan-08 */ #if (HAVE_OSS || HAVE_ALSA || HAVE_JACK_IN_LINUX) /* actually it's not impossible that someday we'll have ALSA but not OSS... */ #define AUDIO_OK 1 #include #include #if ((SOUND_VERSION > 360) && (defined(OSS_SYSINFO))) #define NEW_OSS 1 #endif #define MUS_OSS_WRITE_RATE SNDCTL_DSP_SPEED #define MUS_OSS_WRITE_CHANNELS SNDCTL_DSP_CHANNELS #define MUS_OSS_SET_FORMAT SNDCTL_DSP_SETFMT #define MUS_OSS_GET_FORMATS SNDCTL_DSP_GETFMTS #define DAC_NAME "/dev/dsp" #define MIXER_NAME "/dev/mixer" /* some programs use /dev/audio */ /* there can be more than one sound card installed, and a card can be handled through * more than one /dev/dsp device, so we can't use a global dac device here. * The caller has to keep track of the various cards (via AUDIO_SYSTEM) -- * I toyed with embedding all that in mus_audio_open_output and mus_audio_write, but * decided it's better to keep them explicit -- the caller may want entirely * different (non-synchronous) streams going to the various cards. This same * code (AUDIO_SYSTEM(n)->devn) should work in Windoze (see below), and * might work on the Mac -- something for a rainy day... */ #define return_error_exit(Message_Type, Audio_Line, Ur_Message) \ do { \ char *Message; Message = Ur_Message; \ if (Audio_Line != -1) \ linux_audio_close(Audio_Line); \ if ((Message) && (strlen(Message) > 0)) \ { \ mus_print("%s\n [%s[%d] %s]", \ Message, \ __FILE__, __LINE__, __func__); \ free(Message); \ } \ else mus_print("%s\n [%s[%d] %s]", \ mus_error_type_to_string(Message_Type), \ __FILE__, __LINE__, __func__); \ return(MUS_ERROR); \ } while (false) static int FRAGMENTS = 4; static int FRAGMENT_SIZE = 12; static bool fragments_locked = false; /* defaults here are FRAGMENTS 16 and FRAGMENT_SIZE 12; these values however * cause about a .5 second delay, which is not acceptable in "real-time" situations. * * this changed 22-May-01: these are causing more trouble than they're worth */ static void oss_mus_oss_set_buffers(int num, int size) {FRAGMENTS = num; FRAGMENT_SIZE = size; fragments_locked = true;} #define MAX_SOUNDCARDS 8 #define MAX_DSPS 8 #define MAX_MIXERS 8 /* there can be (apparently) any number of mixers and dsps per soundcard, but 8 is enough! */ static int *audio_fd = NULL; static int *audio_open_ctr = NULL; static int *audio_dsp = NULL; static int *audio_mixer = NULL; static int *audio_mode = NULL; static int sound_cards = 0; #ifdef NEW_OSS static int new_oss_running = 0; #endif static char *dev_name = NULL; static char *oss_mus_audio_moniker(void) { if (version_name == NULL) version_name = (char *)calloc(LABEL_BUFFER_SIZE, sizeof(char)); if (SOUND_VERSION < 361) { char version[LABEL_BUFFER_SIZE]; snprintf(version, LABEL_BUFFER_SIZE, "%d", SOUND_VERSION); snprintf(version_name, LABEL_BUFFER_SIZE, "OSS %c.%c.%c", version[0], version[1], version[2]); } else snprintf(version_name, LABEL_BUFFER_SIZE, "OSS %x.%x.%x", (SOUND_VERSION >> 16) & 0xff, (SOUND_VERSION >> 8) & 0xff, SOUND_VERSION & 0xff); return(version_name); } static char *dac_name(int sys, int offset) { if ((sys < sound_cards) && (audio_mixer[sys] >= -1)) { snprintf(dev_name, LABEL_BUFFER_SIZE, "%s%d", DAC_NAME, audio_dsp[sys] + offset); return(dev_name); } return((char *)DAC_NAME); } #define MIXER_SIZE SOUND_MIXER_NRDEVICES static int **mixer_state = NULL; static int *init_srate = NULL, *init_chans = NULL, *init_format = NULL; static int oss_mus_audio_initialize(void) { /* here we need to set up the map of /dev/dsp and /dev/mixer to a given system */ /* since this info is not passed to us by OSS, we have to work at it... */ /* for the time being, I'll ignore auxiliary dsp and mixer ports (each is a special case) */ int amp, old_mixer_amp, old_dsp_amp, new_mixer_amp; int devmask; #ifdef NEW_OSS int status, ignored; oss_sysinfo sysinfo; static mixer_info mixinfo; int sysinfo_ok = 0; #endif if (!audio_initialized) { int i, num_mixers, num_dsps, nmix, ndsp, err = 0, fd = -1, responsive_field; audio_initialized = true; audio_fd = (int *)calloc(MAX_SOUNDCARDS, sizeof(int)); audio_open_ctr = (int *)calloc(MAX_SOUNDCARDS, sizeof(int)); audio_dsp = (int *)calloc(MAX_SOUNDCARDS, sizeof(int)); audio_mixer = (int *)calloc(MAX_SOUNDCARDS, sizeof(int)); audio_mode = (int *)calloc(MAX_SOUNDCARDS, sizeof(int)); dev_name = (char *)calloc(LABEL_BUFFER_SIZE, sizeof(char)); init_srate = (int *)calloc(MAX_SOUNDCARDS, sizeof(int)); init_chans = (int *)calloc(MAX_SOUNDCARDS, sizeof(int)); init_format = (int *)calloc(MAX_SOUNDCARDS, sizeof(int)); mixer_state = (int **)calloc(MAX_SOUNDCARDS, sizeof(int *)); for (i = 0; i < MAX_SOUNDCARDS; i++) mixer_state[i] = (int *)calloc(MIXER_SIZE, sizeof(int)); for (i = 0; i < MAX_SOUNDCARDS; i++) { audio_fd[i] = -1; audio_open_ctr[i] = 0; audio_dsp[i] = -1; audio_mixer[i] = -1; } num_mixers = MAX_MIXERS; num_dsps = MAX_DSPS; #ifdef NEW_OSS fd = open(DAC_NAME, O_WRONLY | O_NONBLOCK, 0); if (fd == -1) fd = open(MIXER_NAME, O_RDONLY | O_NONBLOCK, 0); if (fd != -1) { status = ioctl(fd, OSS_GETVERSION, &ignored); new_oss_running = (status == 0); if (new_oss_running) { status = ioctl(fd, OSS_SYSINFO, &sysinfo); sysinfo_ok = (status == 0); } if ((new_oss_running) && (sysinfo_ok)) { num_mixers = sysinfo.nummixers; num_dsps = sysinfo.numaudios; } close(fd); } #endif /* need to get which /dev/dsp lines match which /dev/mixer lines, * find out how many separate systems (soundcards) are available, * fill the audio_dsp and audio_mixer arrays with the system-related numbers, * since we have no way to tell from OSS info which mixers/dsps are the * main ones, we'll do some messing aound to try to deduce this info. * for example, SB uses two dsp ports and two mixers per card, whereas * Ensoniq uses 2 dsps and 1 mixer. * * the data we are gathering here: * int audio_dsp[MAX_SOUNDCARDS] -> main_dsp_port[n] (-1 => no such system dsp) * int audio_mixer[MAX_SOUNDCARDS] -> main_mixer_port[n] * int sound_cards = 0 -> usable systems * all auxiliary ports are currently ignored (SB equalizer, etc) */ sound_cards = 0; ndsp = 0; nmix = 0; while ((nmix < num_mixers) && (ndsp < num_dsps)) { char dname[LABEL_BUFFER_SIZE]; int md; /* for each mixer, find associated main dsp (assumed to be first in /dev/dsp ordering) */ /* if mixer's dsp overlaps or we run out of dsps first, ignore it (aux mixer) */ /* our by-guess-or-by-gosh method here is to try to open the mixer. * if that fails, quit (if very first, try at least to get the dsp setup) * find volume field, if none, go on, else read current volume * open next unchecked dsp, try to set volume, read current, if different we found a match -- set and go on. * if no change, move to next dsp and try again, if no more dsps, quit (checking for null case as before) */ snprintf(dname, LABEL_BUFFER_SIZE, "%s%d", MIXER_NAME, nmix); md = open(dname, O_RDWR, 0); if (md == -1) { if (errno == EBUSY) { mus_print("%s is busy: can't access it [%s[%d] %s]", dname, __FILE__, __LINE__, __func__); nmix++; continue; } else break; } snprintf(dname, LABEL_BUFFER_SIZE, "%s%d", DAC_NAME, ndsp); fd = open(dname, O_RDWR | O_NONBLOCK, 0); if (fd == -1) fd = open(dname, O_RDONLY | O_NONBLOCK, 0); if (fd == -1) fd = open(dname, O_WRONLY | O_NONBLOCK, 0); /* some output devices need this */ if (fd == -1) { close(md); if (errno == EBUSY) /* in linux /usr/include/asm-generic/errno-base.h */ { fprintf(stderr, "%s is busy: can't access it\n", dname); ndsp++; continue; } else { if ((errno != ENXIO) && (errno != ENODEV) && (errno != ENOENT)) fprintf(stderr, "%s: %s! ", dname, strerror(errno)); break; } } #ifdef NEW_OSS status = ioctl(md, SOUND_MIXER_INFO, &mixinfo); #endif err = ioctl(md, SOUND_MIXER_READ_DEVMASK, &devmask); responsive_field = SOUND_MIXER_VOLUME; for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) if ((1 << i) & devmask) { responsive_field = i; break; } if (!err) { err = ioctl(md, MIXER_READ(responsive_field), &old_mixer_amp); if (!err) { err = ioctl(fd, MIXER_READ(responsive_field), &old_dsp_amp); if ((!err) && (old_dsp_amp == old_mixer_amp)) { if (old_mixer_amp == 0) amp = 50; else amp = 0; /* 0..100 */ err = ioctl(fd, MIXER_WRITE(responsive_field), &); if (!err) { err = ioctl(md, MIXER_READ(responsive_field), &new_mixer_amp); if (!err) { if (new_mixer_amp == amp) { /* found one! */ audio_dsp[sound_cards] = ndsp; ndsp++; audio_mixer[sound_cards] = nmix; nmix++; sound_cards++; } else ndsp++; err = ioctl(fd, MIXER_WRITE(responsive_field), &old_dsp_amp); } else nmix++; } else ndsp++; } else ndsp++; } else nmix++; } else nmix++; close(fd); close(md); } if (sound_cards == 0) { fd = open(DAC_NAME, O_WRONLY | O_NONBLOCK, 0); if (fd != -1) { sound_cards = 1; audio_dsp[0] = 0; audio_mixer[0] = -2; /* hmmm -- need a way to see /dev/dsp as lonely outpost */ close(fd); fd = open(MIXER_NAME, O_RDONLY | O_NONBLOCK, 0); if (fd == -1) audio_mixer[0] = -3; else close(fd); } } } return(MUS_NO_ERROR); } static int linux_audio_open(const char *pathname, int flags, mode_t mode, int system) { /* sometimes this is simply searching for a device (so failure is not a mus_error) */ if (audio_fd[system] == -1) { audio_fd[system] = open(pathname, flags, mode); audio_open_ctr[system] = 0; } else audio_open_ctr[system]++; return(audio_fd[system]); } static int linux_audio_open_with_error(const char *pathname, int flags, mode_t mode, int system) { int fd; static bool already_warned = false; if ((system < 0) || (system >= MAX_SOUNDCARDS)) return(-1); fd = linux_audio_open(pathname, flags, mode, system); if ((fd == -1) && (!already_warned)) { already_warned = true; mus_standard_io_error(MUS_AUDIO_CANT_OPEN, ((mode == O_RDONLY) ? "open read" : (mode == O_WRONLY) ? "open write" : "open read/write"), pathname); } return(fd); } static int find_system(int line) { int i; for (i = 0; i < sound_cards; i++) if (line == audio_fd[i]) return(i); return(MUS_ERROR); } static int linux_audio_close(int fd) { if (fd != -1) { int err = 0, sys; sys = find_system(fd); if (sys != -1) { if (audio_open_ctr[sys] > 0) audio_open_ctr[sys]--; else { err = close(fd); audio_open_ctr[sys] = 0; audio_fd[sys] = -1; } } else err = close(fd); if (err) return_error_exit(MUS_AUDIO_CANT_CLOSE, -1, mus_format("close %d failed: %s", fd, strerror(errno))); } /* is this an error? */ return(MUS_NO_ERROR); } static int to_oss_sample_type(mus_sample_t snd_format) { switch (snd_format) { case MUS_BYTE: return(AFMT_S8); break; case MUS_BSHORT: return(AFMT_S16_BE); break; case MUS_UBYTE: return(AFMT_U8); break; case MUS_MULAW: return(AFMT_MU_LAW); break; case MUS_ALAW: return(AFMT_A_LAW); break; case MUS_LSHORT: return(AFMT_S16_LE); break; case MUS_UBSHORT: return(AFMT_U16_BE); break; case MUS_ULSHORT: return(AFMT_U16_LE); break; #ifdef NEW_OSS case MUS_LINT: return(AFMT_S32_LE); break; case MUS_BINT: return(AFMT_S32_BE); break; #endif default: break; } return(MUS_ERROR); } static bool fragment_set_failed = false; static int oss_mus_audio_open_output(int ur_dev, int srate, int chans, mus_sample_t samp_type, int size) { int oss_sample_type, buffer_info, audio_out = -1, sys, dev; char *dev_name; #ifndef NEW_OSS int stereo; #endif sys = MUS_AUDIO_SYSTEM(ur_dev); dev = MUS_AUDIO_DEVICE(ur_dev); oss_sample_type = to_oss_sample_type(samp_type); if (oss_sample_type == MUS_ERROR) return_error_exit(MUS_AUDIO_SAMPLE_TYPE_NOT_AVAILABLE, -1, mus_format("sample type %d (%s) not available", samp_type, mus_sample_type_name(samp_type))); if (dev == MUS_AUDIO_DEFAULT) audio_out = linux_audio_open_with_error(dev_name = dac_name(sys, 0), O_WRONLY, 0, sys); else audio_out = linux_audio_open_with_error(dev_name = dac_name(sys, (dev == MUS_AUDIO_AUX_OUTPUT) ? 1 : 0), O_RDWR, 0, sys); if (audio_out == -1) return(MUS_ERROR); /* ioctl(audio_out, SNDCTL_DSP_RESET, 0); */ /* causes clicks */ if ((fragments_locked) && (!(fragment_set_failed)) && ((dev == MUS_AUDIO_DUPLEX_DEFAULT) || (size != 0))) /* only set if user has previously called set_oss_buffers */ { buffer_info = (FRAGMENTS << 16) | (FRAGMENT_SIZE); if (ioctl(audio_out, SNDCTL_DSP_SETFRAGMENT, &buffer_info) == -1) { /* older Linuces (or OSS's?) refuse to handle the fragment reset if O_RDWR used -- * someone at OSS forgot to update the version number when this was fixed, so * I have no way to get around this except to try and retry... */ linux_audio_close(audio_out); audio_out = linux_audio_open_with_error(dev_name = dac_name(sys, (dev == MUS_AUDIO_AUX_OUTPUT) ? 1 : 0), O_WRONLY, 0, sys); if (audio_out == -1) return(MUS_ERROR); buffer_info = (FRAGMENTS << 16) | (FRAGMENT_SIZE); if (ioctl(audio_out, SNDCTL_DSP_SETFRAGMENT, &buffer_info) == -1) { char *tmp; tmp = mus_format("can't set %s fragments to: %d x %d", dev_name, FRAGMENTS, FRAGMENT_SIZE); /* not an error if ALSA OSS-emulation */ fprintf(stderr, "%s\n", tmp); fragment_set_failed = true; free(tmp); } } } if ((ioctl(audio_out, MUS_OSS_SET_FORMAT, &oss_sample_type) == -1) || (oss_sample_type != to_oss_sample_type(samp_type))) return_error_exit(MUS_AUDIO_SAMPLE_TYPE_NOT_AVAILABLE, audio_out, mus_format("sample type %d (%s) not available on %s", samp_type, mus_sample_type_name(samp_type), dev_name)); #ifdef NEW_OSS if (ioctl(audio_out, MUS_OSS_WRITE_CHANNELS, &chans) == -1) return_error_exit(MUS_AUDIO_CHANNELS_NOT_AVAILABLE, audio_out, mus_format("can't get %d channels on %s", chans, dev_name)); #else if (chans == 2) stereo = 1; else stereo = 0; if ((ioctl(audio_out, SNDCTL_DSP_STEREO, &stereo) == -1) || ((chans == 2) && (stereo == 0))) return_error_exit(MUS_AUDIO_CHANNELS_NOT_AVAILABLE, audio_out, mus_format("can't get %d channels on %s", chans, dev_name)); #endif if (ioctl(audio_out, MUS_OSS_WRITE_RATE, &srate) == -1) return_error_exit(MUS_AUDIO_SRATE_NOT_AVAILABLE, audio_out, mus_format("can't set srate of %s to %d", dev_name, srate)); /* http://www.4front-tech.com/pguide/audio.html says this order has to be followed */ return(audio_out); } static int oss_mus_audio_write(int line, char *buf, int bytes) { int err; if (line < 0) return(-1); errno = 0; err = write(line, buf, bytes); if (err != bytes) { if (errno != 0) return_error_exit(MUS_AUDIO_WRITE_ERROR, -1, mus_format("write error: %s", strerror(errno))); else return_error_exit(MUS_AUDIO_WRITE_ERROR, -1, mus_format("wrote %d bytes of requested %d", err, bytes)); } return(MUS_NO_ERROR); } static int oss_mus_audio_close(int line) { return(linux_audio_close(line)); } static int oss_mus_audio_read(int line, char *buf, int bytes) { int err; if (line < 0) return(-1); errno = 0; err = read(line, buf, bytes); if (err != bytes) { if (errno != 0) return_error_exit(MUS_AUDIO_READ_ERROR, -1, mus_format("read error: %s", strerror(errno))); else return_error_exit(MUS_AUDIO_READ_ERROR, -1, mus_format("read %d bytes of requested %d", err, bytes)); } return(MUS_NO_ERROR); } static char *oss_unsrc(int srcbit) { if (srcbit == 0) return(mus_strdup("none")); else { bool need_and = false; char *buf; buf = (char *)calloc(PRINT_BUFFER_SIZE, sizeof(char)); if (srcbit & SOUND_MASK_MIC) {need_and = true; strcat(buf, "mic");} if (srcbit & SOUND_MASK_LINE) {if (need_and) strcat(buf, " and "); need_and = true; strcat(buf, "line in");} if (srcbit & SOUND_MASK_CD) {if (need_and) strcat(buf, " and "); strcat(buf, "cd");} return(buf); } } static int oss_mus_audio_open_input(int ur_dev, int srate, int chans, mus_sample_t samp_type, int requested_size) { /* dev can be MUS_AUDIO_DEFAULT or MUS_AUDIO_DUPLEX_DEFAULT as well as the obvious others */ int audio_fd = -1, oss_sample_type, buffer_info, sys, dev, srcbit, cursrc, err; char *dev_name; #ifndef NEW_OSS int stereo; #endif sys = MUS_AUDIO_SYSTEM(ur_dev); dev = MUS_AUDIO_DEVICE(ur_dev); oss_sample_type = to_oss_sample_type(samp_type); if (oss_sample_type == MUS_ERROR) return_error_exit(MUS_AUDIO_SAMPLE_TYPE_NOT_AVAILABLE, -1, mus_format("sample type %d (%s) not available", samp_type, mus_sample_type_name(samp_type))); if (((dev == MUS_AUDIO_DEFAULT) || (dev == MUS_AUDIO_DUPLEX_DEFAULT)) && (sys == 0)) audio_fd = linux_audio_open(dev_name = dac_name(sys, 0), O_RDWR, 0, sys); else audio_fd = linux_audio_open(dev_name = dac_name(sys, 0), O_RDONLY, 0, sys); if (audio_fd == -1) { if (dev == MUS_AUDIO_DUPLEX_DEFAULT) return_error_exit(MUS_AUDIO_CONFIGURATION_NOT_AVAILABLE, -1, mus_format("can't open %s: %s", dev_name, strerror(errno))); if ((audio_fd = linux_audio_open(dev_name = dac_name(sys, 0), O_RDONLY, 0, sys)) == -1) { if ((errno == EACCES) || (errno == ENOENT)) return_error_exit(MUS_AUDIO_NO_READ_PERMISSION, -1, mus_format("can't open %s: %s\n to get input in Linux, we need read permission on /dev/dsp", dev_name, strerror(errno))); else return_error_exit(MUS_AUDIO_NO_INPUT_AVAILABLE, -1, mus_format("can't open %s: %s", dev_name, strerror(errno))); } } #ifdef SNDCTL_DSP_SETDUPLEX else ioctl(audio_fd, SNDCTL_DSP_SETDUPLEX, &err); /* not always a no-op! */ #endif /* need to make sure the desired recording source is active -- does this actually have any effect? */ switch (dev) { case MUS_AUDIO_MICROPHONE: srcbit = SOUND_MASK_MIC; break; case MUS_AUDIO_LINE_IN: srcbit = SOUND_MASK_LINE; break; case MUS_AUDIO_DUPLEX_DEFAULT: case MUS_AUDIO_DEFAULT: srcbit = SOUND_MASK_LINE | SOUND_MASK_MIC; break; default: srcbit = 0; break; } ioctl(audio_fd, MIXER_READ(SOUND_MIXER_RECSRC), &cursrc); srcbit = (srcbit | cursrc); ioctl(audio_fd, MIXER_WRITE(SOUND_MIXER_RECSRC), &srcbit); ioctl(audio_fd, MIXER_READ(SOUND_MIXER_RECSRC), &cursrc); if (cursrc != srcbit) { char *str1, *str2; str1 = oss_unsrc(srcbit); str2 = oss_unsrc(cursrc); mus_print("weird: tried to set recorder source to %s, but got %s?", str1, str2); free(str1); free(str2); } if ((fragments_locked) && (requested_size != 0)) { buffer_info = (FRAGMENTS << 16) | (FRAGMENT_SIZE); ioctl(audio_fd, SNDCTL_DSP_SETFRAGMENT, &buffer_info); } if ((ioctl(audio_fd, MUS_OSS_SET_FORMAT, &oss_sample_type) == -1) || (oss_sample_type != to_oss_sample_type(samp_type))) return_error_exit(MUS_AUDIO_SAMPLE_TYPE_NOT_AVAILABLE, audio_fd, mus_format("can't set %s sample type to %d (%s)", dev_name, samp_type, mus_sample_type_name(samp_type))); #ifdef NEW_OSS if (ioctl(audio_fd, MUS_OSS_WRITE_CHANNELS, &chans) == -1) return_error_exit(MUS_AUDIO_CHANNELS_NOT_AVAILABLE, audio_fd, mus_format("can't get %d channels on %s", chans, dev_name)); #else if (chans == 2) stereo = 1; else stereo = 0; if ((ioctl(audio_fd, SNDCTL_DSP_STEREO, &stereo) == -1) || ((chans == 2) && (stereo == 0))) return_error_exit(MUS_AUDIO_CHANNELS_NOT_AVAILABLE, audio_fd, mus_format("can't get %d channels on %s", chans, dev_name)); #endif if (ioctl(audio_fd, MUS_OSS_WRITE_RATE, &srate) == -1) return_error_exit(MUS_AUDIO_SRATE_NOT_AVAILABLE, audio_fd, mus_format("can't set srate to %d on %s", srate, dev_name)); return(audio_fd); } #if (!HAVE_ALSA) static int oss_sample_types(int ur_dev, mus_sample_t *val) { int fd, samp_types = 0, sys, ind; sys = MUS_AUDIO_SYSTEM(ur_dev); /* dev = MUS_AUDIO_DEVICE(ur_dev); */ fd = open(dac_name(sys, 0), O_WRONLY, 0); if (fd == -1) fd = open(DAC_NAME, O_WRONLY, 0); if (fd == -1) { return_error_exit(MUS_AUDIO_CANT_OPEN, -1, mus_format("can't open %s: %s", DAC_NAME, strerror(errno))); return(MUS_ERROR); } ioctl(fd, MUS_OSS_GET_FORMATS, &samp_types); ind = 1; if (samp_types & (to_oss_sample_type(MUS_BSHORT))) val[ind++] = MUS_BSHORT; if (samp_types & (to_oss_sample_type(MUS_LSHORT))) val[ind++] = MUS_LSHORT; if (samp_types & (to_oss_sample_type(MUS_MULAW))) val[ind++] = MUS_MULAW; if (samp_types & (to_oss_sample_type(MUS_ALAW))) val[ind++] = MUS_ALAW; if (samp_types & (to_oss_sample_type(MUS_BYTE))) val[ind++] = MUS_BYTE; if (samp_types & (to_oss_sample_type(MUS_UBYTE))) val[ind++] = MUS_UBYTE; if (samp_types & (to_oss_sample_type(MUS_UBSHORT))) val[ind++] = MUS_UBSHORT; if (samp_types & (to_oss_sample_type(MUS_ULSHORT))) val[ind++] = MUS_ULSHORT; val[0] = (mus_sample_t)(ind - 1); return(MUS_NO_ERROR); } #endif /* ------------------------------- ALSA, OSS, Jack-in-Linux ----------------------------------- */ static int api = MUS_ALSA_API; int mus_audio_api(void) {return(api);} /* hopefully first call to sndlib will be this... */ static int probe_api(void); static int (*vect_mus_audio_initialize)(void); /* FIXME: add a suitable default for all other vectors so that a call happening before mus_audio_initialize can be detected */ /* I don't think this is necessary -- documentation discusses this * (mus_sound_initialize calls mus_audio_initialize) */ /* vectors for the rest of the sndlib api */ static void (*vect_mus_oss_set_buffers)(int num, int size); static char* (*vect_mus_audio_moniker)(void); static int (*vect_mus_audio_open_output)(int ur_dev, int srate, int chans, mus_sample_t samp_type, int size); static int (*vect_mus_audio_open_input)(int ur_dev, int srate, int chans, mus_sample_t samp_type, int requested_size); static int (*vect_mus_audio_write)(int id, char *buf, int bytes); static int (*vect_mus_audio_read)(int id, char *buf, int bytes); static int (*vect_mus_audio_close)(int id); /* vectors for the rest of the sndlib api */ int mus_audio_initialize(void) { return(probe_api()); } void mus_oss_set_buffers(int num, int size) { vect_mus_oss_set_buffers(num, size); } #if HAVE_ALSA static char* alsa_mus_audio_moniker(void); #endif char* mus_audio_moniker(void) { #if (HAVE_OSS && HAVE_ALSA) char *both_names; both_names = (char *)calloc(PRINT_BUFFER_SIZE, sizeof(char)); /* need to be careful here since these use the same constant buffer */ strcpy(both_names, oss_mus_audio_moniker()); strcat(both_names, ", "); strcat(both_names, alsa_mus_audio_moniker()); return(both_names); /* tiny memory leak ... */ #else return(vect_mus_audio_moniker()); #endif } int mus_audio_open_output(int ur_dev, int srate, int chans, mus_sample_t samp_type, int size) { return(vect_mus_audio_open_output(ur_dev, srate, chans, samp_type, size)); } int mus_audio_open_input(int ur_dev, int srate, int chans, mus_sample_t samp_type, int requested_size) { return(vect_mus_audio_open_input(ur_dev, srate, chans, samp_type, requested_size)); } int mus_audio_write(int id, char *buf, int bytes) { return(vect_mus_audio_write(id, buf, bytes)); } int mus_audio_read(int id, char *buf, int bytes) { return(vect_mus_audio_read(id, buf, bytes)); } int mus_audio_close(int id) { return(vect_mus_audio_close(id)); } #if HAVE_JACK_IN_LINUX static int jack_mus_audio_initialize(void); #endif #if (!HAVE_ALSA) static int probe_api(void) { #if HAVE_JACK_IN_LINUX { int jackprobe = jack_mus_audio_initialize(); if (jackprobe == MUS_ERROR) { #endif /* go for the oss api */ api = MUS_OSS_API; vect_mus_audio_initialize = oss_mus_audio_initialize; vect_mus_oss_set_buffers = oss_mus_oss_set_buffers; vect_mus_audio_moniker = oss_mus_audio_moniker; vect_mus_audio_open_output = oss_mus_audio_open_output; vect_mus_audio_open_input = oss_mus_audio_open_input; vect_mus_audio_write = oss_mus_audio_write; vect_mus_audio_read = oss_mus_audio_read; vect_mus_audio_close = oss_mus_audio_close; return(vect_mus_audio_initialize()); #if HAVE_JACK_IN_LINUX } return(jackprobe); } #endif } #endif #endif /* ------------------------------- ALSA ----------------------------------------- */ /* * Changed the names of the environment variables to use MUS, not SNDLIB. * reformatted and reorganized to be like the rest of the code * changed default device to "default" * -- Bill 3-Feb-06 * * error handling (mus_error) changed by Bill 14-Nov-02 * 0.5 support removed by Bill 24-Mar-02 * * changed for 0.9.x api by Fernando Lopez-Lezcano * * sndlib "exports" only one soundcard with two directions (if they are available), * and only deals with the alsa library pcm's. It does not scan for available * cards and devices at the hardware level. Which device it uses can be defined by: * * - setting variables in the environment (searched for in the following order): * MUS_ALSA_PLAYBACK_DEVICE * defines the name of the playback device * MUS_ALSA_CAPTURE_DEVICE * defines the name of the capture device * MUS_ALSA_DEVICE * defines the name of the playback and capture device * use the first two if the playback and capture devices are different or the * third if they are the same. * - if no variables are found in the environment sndlib tries to probe for a * default device named "sndlib" (in alsa 0.9 devices are configured in * /usr/share/alsa/alsa.conf or in ~/.asoundrc) * - if "sndlib" is not a valid device "hw:0,0" was used [but now it looks for "default"] (which by default should * point to the first device of the first card * * Some default settings are controllable through the environment as well: * MUS_ALSA_BUFFER_SIZE = size of each buffer in frames * MUS_ALSA_BUFFERS = number of buffers * * changed 18-Sep-00 by Bill: new error handling: old mus_audio_error folded into * mus_error; mus_error itself should be used only for "real" errors -- things * that can cause a throw (a kind of global jump elsewhere); use mus_print for informational * stuff -- in Snd, mus_print will also save everything printed in the error dialog. * In a few cases, I tried to fix the code to unwind before mus_error, and in others * I've changed mus_error to mus_print, but some of these may be mistaken. * Look for ?? below for areas where I'm not sure I rewrote code correctly. * * changed for 0.6.x api by Paul Barton-Davis, pbd@op.net * * changed for 0.5.x api by Fernando Lopez-Lezcano, nando@ccrma.stanford.edu * 04-10-2000: * based on original 0.4.x code by Paul Barton-Davis (not much left of it :-) * also Bill's code and Jaroslav Kysela (aplay.c and friends) * * Changes: * 04/25/2000: finished major rework, snd-dac now automatically decides which * device or devices it uses for playback. Multiple device use is * for now restricted to only two at most (more changes in Bill's * needed to be able to support more). Four channel playback in * Ensoniq AudioPCI and relatives possible (with proper settings * of the mixer) as well as using two separate cards. * 04/11/2000: added reporting of alsa sound formats */ #if HAVE_ALSA #if (!HAVE_OSS) #define AUDIO_OK 1 #endif #include #if HAVE_ALSA #include #else #include #endif #if SND_LIB_VERSION < ((0<<16)|(6<<8)|(0)) #error ALSA version is too old -- audio.c needs 0.9 or later #endif /* prototypes for the alsa sndlib functions */ static int alsa_mus_audio_initialize(void); static void alsa_mus_oss_set_buffers(int num, int size); static int alsa_mus_audio_open_output(int ur_dev, int srate, int chans, mus_sample_t samp_type, int size); static int alsa_mus_audio_open_input(int ur_dev, int srate, int chans, mus_sample_t samp_type, int requested_size); static int alsa_mus_audio_write(int id, char *buf, int bytes); static int alsa_mus_audio_read(int id, char *buf, int bytes); static int alsa_mus_audio_close(int id); /* decide which api to activate */ static int probe_api(void) { #if HAVE_JACK_IN_LINUX int jackprobe; jackprobe = jack_mus_audio_initialize(); if (jackprobe == MUS_ERROR) { #endif int card = -1; if ((snd_card_next(&card) >= 0) && (card >= 0)) { /* the alsa library has detected one or more cards */ api = MUS_ALSA_API; vect_mus_audio_initialize = alsa_mus_audio_initialize; vect_mus_oss_set_buffers = alsa_mus_oss_set_buffers; vect_mus_audio_moniker = alsa_mus_audio_moniker; vect_mus_audio_open_output = alsa_mus_audio_open_output; vect_mus_audio_open_input = alsa_mus_audio_open_input; vect_mus_audio_write = alsa_mus_audio_write; vect_mus_audio_read = alsa_mus_audio_read; vect_mus_audio_close = alsa_mus_audio_close; } else { /* go for the oss api */ api = MUS_OSS_API; vect_mus_audio_initialize = oss_mus_audio_initialize; vect_mus_oss_set_buffers = oss_mus_oss_set_buffers; vect_mus_audio_moniker = oss_mus_audio_moniker; vect_mus_audio_open_output = oss_mus_audio_open_output; vect_mus_audio_open_input = oss_mus_audio_open_input; vect_mus_audio_write = oss_mus_audio_write; vect_mus_audio_read = oss_mus_audio_read; vect_mus_audio_close = oss_mus_audio_close; } /* will the _real_ mus_audio_initialize please stand up? */ return(vect_mus_audio_initialize()); #if HAVE_JACK_IN_LINUX } return(jackprobe); #endif } /* convert a sndlib sample type to an alsa sample type */ static snd_pcm_format_t to_alsa_format(mus_sample_t snd_format) { switch (snd_format) { case MUS_BYTE: return(SND_PCM_FORMAT_S8); case MUS_UBYTE: return(SND_PCM_FORMAT_U8); case MUS_MULAW: return(SND_PCM_FORMAT_MU_LAW); case MUS_ALAW: return(SND_PCM_FORMAT_A_LAW); case MUS_BSHORT: return(SND_PCM_FORMAT_S16_BE); case MUS_LSHORT: return(SND_PCM_FORMAT_S16_LE); case MUS_UBSHORT: return(SND_PCM_FORMAT_U16_BE); case MUS_ULSHORT: return(SND_PCM_FORMAT_U16_LE); case MUS_B24INT: return(SND_PCM_FORMAT_S24_BE); case MUS_L24INT: return(SND_PCM_FORMAT_S24_LE); case MUS_BINT: return(SND_PCM_FORMAT_S32_BE); case MUS_LINT: return(SND_PCM_FORMAT_S32_LE); case MUS_BINTN: return(SND_PCM_FORMAT_S32_BE); case MUS_LINTN: return(SND_PCM_FORMAT_S32_LE); case MUS_BFLOAT: return(SND_PCM_FORMAT_FLOAT_BE); case MUS_LFLOAT: return(SND_PCM_FORMAT_FLOAT_LE); case MUS_BDOUBLE: return(SND_PCM_FORMAT_FLOAT64_BE); case MUS_LDOUBLE: return(SND_PCM_FORMAT_FLOAT64_LE); default: break; } return((snd_pcm_format_t)MUS_ERROR); } /* FIXME: this is not taking yet into account the * number of bits that a given alsa format is actually * using... */ static mus_sample_t to_mus_sample_type(int alsa_format) { /* alsa format definitions from asoundlib.h (0.9 cvs 6/27/2001) */ switch (alsa_format) { case SND_PCM_FORMAT_S8: return(MUS_BYTE); case SND_PCM_FORMAT_U8: return(MUS_UBYTE); case SND_PCM_FORMAT_S16_LE: return(MUS_LSHORT); case SND_PCM_FORMAT_S16_BE: return(MUS_BSHORT); case SND_PCM_FORMAT_U16_LE: return(MUS_ULSHORT); case SND_PCM_FORMAT_U16_BE: return(MUS_UBSHORT); case SND_PCM_FORMAT_S24_LE: return(MUS_L24INT); case SND_PCM_FORMAT_S24_BE: return(MUS_B24INT); case SND_PCM_FORMAT_S32_LE: return(MUS_LINTN); /* 32bit normalized plays 24bit and 16bit files with same amplitude bound (for 24 bit cards) */ case SND_PCM_FORMAT_S32_BE: return(MUS_BINTN); case SND_PCM_FORMAT_FLOAT_LE: return(MUS_LFLOAT); case SND_PCM_FORMAT_FLOAT_BE: return(MUS_BFLOAT); case SND_PCM_FORMAT_FLOAT64_LE: return(MUS_LDOUBLE); case SND_PCM_FORMAT_FLOAT64_BE: return(MUS_BDOUBLE); case SND_PCM_FORMAT_MU_LAW: return(MUS_MULAW); case SND_PCM_FORMAT_A_LAW: return(MUS_ALAW); /* formats with no translation in snd */ case SND_PCM_FORMAT_U24_LE: case SND_PCM_FORMAT_U24_BE: case SND_PCM_FORMAT_U32_LE: case SND_PCM_FORMAT_U32_BE: case SND_PCM_FORMAT_IEC958_SUBFRAME_LE: case SND_PCM_FORMAT_IEC958_SUBFRAME_BE: case SND_PCM_FORMAT_IMA_ADPCM: case SND_PCM_FORMAT_MPEG: case SND_PCM_FORMAT_GSM: case SND_PCM_FORMAT_SPECIAL: default: return(MUS_UNKNOWN_SAMPLE); } } /* convert a sndlib device into an alsa device number and channel * [has to be coordinated with following function!] */ /* very simplistic approach, device mapping should also depend * on which card we're dealing with, digital i/o devices should * be identified as such and so on */ /* NOTE: in the Delta1010 digital i/o is just a pair of channels * in the 10 channel playback frame or 12 channel capture frame, * how do we specify that??? */ static int to_alsa_device(int dev, int *adev, snd_pcm_stream_t *achan) { switch (dev) { /* default values are a problem because the concept does * not imply a direction (playback or capture). This works * fine as long as both directions of a device are symetric, * the Midiman 1010, for example, has 10 channel frames for * playback and 12 channel frames for capture and breaks * the recorder (probes the default, defaults to output, * uses the values for input). */ case MUS_AUDIO_DEFAULT: case MUS_AUDIO_DUPLEX_DEFAULT: case MUS_AUDIO_LINE_OUT: /* analog output */ (*adev) = 0; (*achan) = SND_PCM_STREAM_PLAYBACK; break; case MUS_AUDIO_AUX_OUTPUT: /* extra analog output */ (*adev) = 1; (*achan) = SND_PCM_STREAM_PLAYBACK; break; case MUS_AUDIO_DAC_OUT: /* analog outputs */ (*adev) = 2; (*achan) = SND_PCM_STREAM_PLAYBACK; break; case MUS_AUDIO_MICROPHONE: case MUS_AUDIO_LINE_IN: /* analog input */ (*adev) = 0; (*achan) = SND_PCM_STREAM_CAPTURE; break; default: return(MUS_ERROR); break; } return(0); } /* convert an alsa device into a sndlib device * [has to be coordinated with previous function!] * * naming here is pretty much arbitrary. We have to have * a bidirectional mapping between sndlib devices and * alsa devices and that's just not possible (I think). * This stopgap mapping ignores digital input and output * devices - how to differentiate them in alsa? */ static int to_sndlib_device(int dev, int channel) { switch (channel) { case SND_PCM_STREAM_PLAYBACK: switch (dev) { /* works only for the first three outputs */ case 0: return(MUS_AUDIO_LINE_OUT); case 1: return(MUS_AUDIO_AUX_OUTPUT); case 2: return(MUS_AUDIO_DAC_OUT); default: return(MUS_ERROR); } case SND_PCM_STREAM_CAPTURE: switch (dev) { case 0: return(MUS_AUDIO_LINE_IN); default: return(MUS_ERROR); } break; } return(MUS_ERROR); } static int alsa_mus_error(int type, char *message) { if (message) { mus_print("%s", message); free(message); } return(MUS_ERROR); } /* dump current hardware and software configuration */ static void alsa_dump_configuration(char *name, snd_pcm_hw_params_t *hw_params, snd_pcm_sw_params_t *sw_params) { int err; char *str; snd_output_t *buf; #if (SND_LIB_MAJOR == 0) || ((SND_LIB_MAJOR == 1) && (SND_LIB_MINOR == 0) && (SND_LIB_SUBMINOR < 8)) return; /* avoid Alsa bug */ #endif err = snd_output_buffer_open(&buf); if (err < 0) mus_print("could not open dump buffer: %s", snd_strerror(err)); else { size_t len; if (hw_params) { snd_output_puts(buf, "hw_params status of "); snd_output_puts(buf, name); snd_output_puts(buf, "\n"); err = snd_pcm_hw_params_dump(hw_params, buf); if (err < 0) mus_print("snd_pcm_hw_params_dump: %s", snd_strerror(err)); } if (sw_params) { snd_output_puts(buf, "sw_params status of "); snd_output_puts(buf, name); snd_output_puts(buf, "\n"); err = snd_pcm_sw_params_dump(sw_params, buf); if (err < 0) mus_print("snd_pcm_hw_params_dump: %s", snd_strerror(err)); } snd_output_putc(buf, '\0'); len = snd_output_buffer_string(buf, &str); if (len > 1) mus_print("status of %s\n%s", name, str); snd_output_close(buf); } } /* get hardware params for a pcm */ static snd_pcm_hw_params_t *alsa_get_hardware_params(const char *name, snd_pcm_stream_t stream, int mode) { int err; snd_pcm_t *handle; if ((err = snd_pcm_open(&handle, name, stream, mode | SND_PCM_NONBLOCK)) != 0) { alsa_mus_error(MUS_AUDIO_CANT_OPEN, mus_format("open pcm %s for stream %d: %s", name, stream, snd_strerror(err))); return(NULL); } else { snd_pcm_hw_params_t *params; params = (snd_pcm_hw_params_t *)calloc(1, snd_pcm_hw_params_sizeof()); if (params == NULL) { snd_pcm_close(handle); alsa_mus_error(MUS_AUDIO_CONFIGURATION_NOT_AVAILABLE, mus_format("could not allocate memory for hardware params")); } else { err = snd_pcm_hw_params_any(handle, params); if (err < 0) { snd_pcm_close(handle); alsa_mus_error(MUS_AUDIO_CONFIGURATION_NOT_AVAILABLE, mus_format("snd_pcm_hw_params_any: pcm %s, stream %d, error: %s", name, stream, snd_strerror(err))); } else { snd_pcm_close(handle); return(params); } } } return(NULL); } /* allocate software params structure */ static snd_pcm_sw_params_t *alsa_get_software_params(void) { snd_pcm_sw_params_t *params = NULL; params = (snd_pcm_sw_params_t *)calloc(1, snd_pcm_sw_params_sizeof()); if (params == NULL) { alsa_mus_error(MUS_AUDIO_CONFIGURATION_NOT_AVAILABLE, mus_format("could not allocate memory for software params")); } return(params); } /* probe a device name against the list of available pcm devices */ static bool alsa_probe_device_name(const char *name) { snd_config_t *conf; snd_config_iterator_t pos, next; int err; err = snd_config_update(); if (err < 0) { mus_print("snd_config_update: %s", snd_strerror(err)); return(false); } err = snd_config_search(snd_config, "pcm", &conf); if (err < 0) { mus_print("snd_config_search: %s", snd_strerror(err)); return(false); } snd_config_for_each(pos, next, conf) { snd_config_t *c = snd_config_iterator_entry(pos); const char *id; int err = snd_config_get_id(c, &id); if (err == 0) { int result = strncmp(name, id, strlen(id)); if (result == 0 && (name[strlen(id)] == '\0' || name[strlen(id)] == ':')) { return(true); } } } return(false); } /* check a device name against the list of available pcm devices */ static int alsa_check_device_name(const char *name) { if (!alsa_probe_device_name(name)) { return(alsa_mus_error(MUS_AUDIO_CANT_READ, mus_format("alsa could not find device \"%s\" in configuration", name))); } return(MUS_NO_ERROR); } /* set scheduling priority to SCHED_FIFO * this will only work if the program that uses sndlib is run as root or is suid root */ /* whether we want to trace calls * * set to "1" to print function trace information in the * snd error window */ static int alsa_trace = 0; /* this should go away as it is oss specific */ static int fragment_size = 512; static int fragments = 4; static void alsa_mus_oss_set_buffers(int num, int size) { fragments = num; fragment_size = size; } /* total number of soundcards in our setup, set by initialize_audio */ /* static int sound_cards = 0; */ /* return the number of cards that are available */ /* return the type of driver we're dealing with */ static char *alsa_mus_audio_moniker(void) { if (version_name == NULL) version_name = (char *)calloc(LABEL_BUFFER_SIZE, sizeof(char)); snprintf(version_name, LABEL_BUFFER_SIZE, "ALSA %s", SND_LIB_VERSION_STR); return(version_name); } /* handles for both directions of the virtual device */ static snd_pcm_t *handles[2] = {NULL, NULL}; /* hardware and software parameter sctructure pointers */ static snd_pcm_hw_params_t *alsa_hw_params[2] = {NULL, NULL}; /* avoid bogus free */ static snd_pcm_sw_params_t *alsa_sw_params[2] = {NULL, NULL}; /* some defaults */ static int alsa_open_mode = SND_PCM_ASYNC; static int alsa_buffers = 3; /* size of buffer in number of samples per channel, * at 44100 approximately 5.9mSecs */ static int alsa_samples_per_channel = 1024; static snd_pcm_access_t alsa_interleave = SND_PCM_ACCESS_RW_INTERLEAVED; static int alsa_max_capture_channels = 32; /* first default name for pcm configuration */ static char *alsa_sndlib_device_name = (char *)"sndlib"; /* second default for playback and capture: hardware pcm, first card, first device */ /* pcms used by sndlib, playback and capture */ static char *alsa_playback_device_name = NULL; static char *alsa_capture_device_name = NULL; /* -------- tie these names into scheme/ruby -------- */ static int alsa_get_max_buffers(void) { unsigned int max_periods = 0, max_rec_periods = 0; int dir = 0; if (alsa_hw_params[SND_PCM_STREAM_PLAYBACK]) snd_pcm_hw_params_get_periods_max(alsa_hw_params[SND_PCM_STREAM_PLAYBACK], &max_periods, &dir); if (alsa_hw_params[SND_PCM_STREAM_CAPTURE]) { snd_pcm_hw_params_get_periods_max(alsa_hw_params[SND_PCM_STREAM_CAPTURE], &max_rec_periods, &dir); if (max_periods > max_rec_periods) max_periods = max_rec_periods; } return(max_periods); } static int alsa_get_min_buffers(void) { unsigned int min_periods = 0, min_rec_periods = 0; int dir = 0; if (alsa_hw_params[SND_PCM_STREAM_PLAYBACK]) snd_pcm_hw_params_get_periods_min(alsa_hw_params[SND_PCM_STREAM_PLAYBACK], &min_periods, &dir); if (alsa_hw_params[SND_PCM_STREAM_CAPTURE]) { snd_pcm_hw_params_get_periods_min(alsa_hw_params[SND_PCM_STREAM_CAPTURE], &min_rec_periods, &dir); if (min_periods < min_rec_periods) min_periods = min_rec_periods; } return(min_periods); } static int alsa_clamp_buffers(int bufs) { int minb, maxb; minb = alsa_get_min_buffers(); maxb = alsa_get_max_buffers(); if (bufs > maxb) bufs = maxb; if (bufs < minb) bufs = minb; return(bufs); } static snd_pcm_uframes_t alsa_get_min_buffer_size(void) { snd_pcm_uframes_t min_buffer_size = 0, min_rec_buffer_size = 0; if (alsa_hw_params[SND_PCM_STREAM_PLAYBACK]) snd_pcm_hw_params_get_buffer_size_min(alsa_hw_params[SND_PCM_STREAM_PLAYBACK], &min_buffer_size); if (alsa_hw_params[SND_PCM_STREAM_CAPTURE]) { snd_pcm_hw_params_get_buffer_size_min(alsa_hw_params[SND_PCM_STREAM_CAPTURE], &min_rec_buffer_size); if (min_buffer_size < min_rec_buffer_size) min_buffer_size = min_rec_buffer_size; } return(min_buffer_size); } static snd_pcm_uframes_t alsa_get_max_buffer_size(void) { snd_pcm_uframes_t max_buffer_size = 0, max_rec_buffer_size = 0; if (alsa_hw_params[SND_PCM_STREAM_PLAYBACK]) snd_pcm_hw_params_get_buffer_size_max(alsa_hw_params[SND_PCM_STREAM_PLAYBACK], &max_buffer_size); if (alsa_hw_params[SND_PCM_STREAM_CAPTURE]) { snd_pcm_hw_params_get_buffer_size_max(alsa_hw_params[SND_PCM_STREAM_CAPTURE], &max_rec_buffer_size); if (max_buffer_size > max_rec_buffer_size) max_buffer_size = max_rec_buffer_size; } return(max_buffer_size); } static snd_pcm_uframes_t alsa_clamp_buffer_size(snd_pcm_uframes_t buf_size) { snd_pcm_uframes_t minb, maxb; minb = alsa_get_min_buffer_size(); maxb = alsa_get_max_buffer_size(); if (buf_size > maxb) buf_size = maxb; if (buf_size < minb) buf_size = minb; return(buf_size); } static bool alsa_set_playback_parameters(void) { /* playback stream parameters */ if (alsa_hw_params[SND_PCM_STREAM_PLAYBACK]) free(alsa_hw_params[SND_PCM_STREAM_PLAYBACK]); alsa_hw_params[SND_PCM_STREAM_PLAYBACK] = alsa_get_hardware_params(alsa_playback_device_name, SND_PCM_STREAM_PLAYBACK, alsa_open_mode); if (alsa_hw_params[SND_PCM_STREAM_PLAYBACK]) { snd_pcm_uframes_t size; int old_buffers; old_buffers = alsa_buffers; if (alsa_sw_params[SND_PCM_STREAM_PLAYBACK]) free(alsa_sw_params[SND_PCM_STREAM_PLAYBACK]); alsa_sw_params[SND_PCM_STREAM_PLAYBACK] = alsa_get_software_params(); sound_cards = 1; alsa_buffers = alsa_clamp_buffers(alsa_buffers); if (alsa_buffers <= 0) { alsa_buffers = old_buffers; return(false); } size = alsa_clamp_buffer_size((snd_pcm_uframes_t)(alsa_samples_per_channel * alsa_buffers)); if (size <= 0) return(false); alsa_samples_per_channel = size / alsa_buffers; } return(alsa_hw_params[SND_PCM_STREAM_PLAYBACK] && alsa_sw_params[SND_PCM_STREAM_PLAYBACK]); } static bool alsa_set_capture_parameters(void) { /* capture stream parameters */ if (alsa_hw_params[SND_PCM_STREAM_CAPTURE]) free(alsa_hw_params[SND_PCM_STREAM_CAPTURE]); alsa_hw_params[SND_PCM_STREAM_CAPTURE] = alsa_get_hardware_params(alsa_capture_device_name, SND_PCM_STREAM_CAPTURE, alsa_open_mode); if (alsa_hw_params[SND_PCM_STREAM_CAPTURE]) { snd_pcm_uframes_t size; int old_buffers; old_buffers = alsa_buffers; if (alsa_sw_params[SND_PCM_STREAM_CAPTURE]) free(alsa_sw_params[SND_PCM_STREAM_CAPTURE]); alsa_sw_params[SND_PCM_STREAM_CAPTURE] = alsa_get_software_params(); sound_cards = 1; alsa_buffers = alsa_clamp_buffers(alsa_buffers); if (alsa_buffers <= 0) { alsa_buffers = old_buffers; return(false); } size = alsa_clamp_buffer_size((snd_pcm_uframes_t)(alsa_samples_per_channel * alsa_buffers)); if (size <= 0) return(false); alsa_samples_per_channel = size / alsa_buffers; } return(alsa_hw_params[SND_PCM_STREAM_CAPTURE] && alsa_sw_params[SND_PCM_STREAM_CAPTURE]); } char *mus_alsa_playback_device(void) {return(alsa_playback_device_name);} char *mus_alsa_set_playback_device(const char *name) { if (alsa_check_device_name(name) == MUS_NO_ERROR) { char *old_name = alsa_playback_device_name; alsa_playback_device_name = mus_strdup(name); if (!alsa_set_playback_parameters()) { alsa_playback_device_name = old_name; /* try to back out of the mistake */ alsa_set_playback_parameters(); } } return(alsa_playback_device_name); } char *mus_alsa_capture_device(void) {return(alsa_capture_device_name);} char *mus_alsa_set_capture_device(const char *name) { if (alsa_check_device_name(name) == MUS_NO_ERROR) { char *old_name = alsa_capture_device_name; alsa_capture_device_name = mus_strdup(name); if (!alsa_set_capture_parameters()) { alsa_capture_device_name = old_name; alsa_set_capture_parameters(); } } return(alsa_capture_device_name); } char *mus_alsa_device(void) {return(alsa_sndlib_device_name);} char *mus_alsa_set_device(const char *name) { if (alsa_check_device_name(name) == MUS_NO_ERROR) { alsa_sndlib_device_name = mus_strdup(name); mus_alsa_set_playback_device(name); mus_alsa_set_capture_device(name); } return(alsa_sndlib_device_name); } int mus_alsa_buffer_size(void) {return(alsa_samples_per_channel);} int mus_alsa_set_buffer_size(int size) { snd_pcm_uframes_t bsize; if (alsa_buffers == 0) alsa_buffers = 1; if (size > 0) { bsize = alsa_clamp_buffer_size((snd_pcm_uframes_t)(size * alsa_buffers)); alsa_samples_per_channel = bsize / alsa_buffers; } return(alsa_samples_per_channel); } int mus_alsa_buffers(void) {return(alsa_buffers);} int mus_alsa_set_buffers(int num) { snd_pcm_uframes_t size; if (num > 0) { alsa_buffers = alsa_clamp_buffers(num); if (alsa_buffers > 0) { size = alsa_clamp_buffer_size((snd_pcm_uframes_t)(alsa_samples_per_channel * alsa_buffers)); alsa_samples_per_channel = size / alsa_buffers; } } return(alsa_buffers); } static bool alsa_squelch_warning = false; bool mus_alsa_squelch_warning(void) {return(alsa_squelch_warning);} bool mus_alsa_set_squelch_warning(bool val) { alsa_squelch_warning = val; return(val); } /* get a device name from the environment */ static char *alsa_get_device_from_env(const char *name) { char *string = getenv(name); if (string) if (alsa_check_device_name(string) == MUS_NO_ERROR) return(string); return(NULL); } /* get an integer from the environment */ static int alsa_get_int_from_env(const char *name, int *value, int min, int max) { char *string = getenv(name); if (string) { char *end; long int result = strtol(string, &end, 10); if (((min != -1) && (max != -1)) && (result < min || result > max)) { return(alsa_mus_error(MUS_AUDIO_CANT_READ, mus_format("%s ignored: out of range, value=%d, min=%d, max=%d", name, (int)result, min, max))); } else { if (errno == ERANGE) { return(alsa_mus_error(MUS_AUDIO_CANT_READ, mus_format("%s ignored: strlol conversion out of range", name))); } else { if ((*string != '\0') && (*end == '\0')) { *value = (int)result; return(MUS_NO_ERROR); } else { return(alsa_mus_error(MUS_AUDIO_CANT_READ, mus_format("%s ignored: value is \"%s\", not an integer", name, string))); } } } } return(MUS_ERROR); } /* initialize the audio subsystem */ /* define environment variable names */ #define MUS_ALSA_PLAYBACK_DEVICE_ENV_NAME "MUS_ALSA_PLAYBACK_DEVICE" #define MUS_ALSA_CAPTURE_DEVICE_ENV_NAME "MUS_ALSA_CAPTURE_DEVICE" #define MUS_ALSA_DEVICE_ENV_NAME "MUS_ALSA_DEVICE" #define MUS_ALSA_BUFFERS_ENV_NAME "MUS_ALSA_BUFFERS" #define MUS_ALSA_BUFFER_SIZE_ENV_NAME "MUS_ALSA_BUFFER_SIZE" #define MUS_ALSA_TRACE_ENV_NAME "MUS_ALSA_TRACE" static int alsa_mus_audio_initialize(void) { char *name = NULL; char *pname; char *cname; int value = 0, alsa_buffer_size = 0; if (audio_initialized) return(0); sound_cards = 0; /* get trace flag from environment */ if (alsa_get_int_from_env(MUS_ALSA_TRACE_ENV_NAME, &value, 0, 1) == MUS_NO_ERROR) alsa_trace = value; /* try to get device names from environment */ pname = alsa_get_device_from_env(MUS_ALSA_PLAYBACK_DEVICE_ENV_NAME); if ((pname) && (alsa_probe_device_name(pname))) alsa_playback_device_name = pname; cname = alsa_get_device_from_env(MUS_ALSA_CAPTURE_DEVICE_ENV_NAME); if ((cname) && (alsa_probe_device_name(cname))) alsa_capture_device_name = cname; name = alsa_get_device_from_env(MUS_ALSA_DEVICE_ENV_NAME); if ((name) && (alsa_probe_device_name(name))) { if (!alsa_playback_device_name) alsa_playback_device_name = name; if (!alsa_capture_device_name) alsa_capture_device_name = name; alsa_sndlib_device_name = name; } /* now check that we have a plausible name */ if (!alsa_probe_device_name(alsa_sndlib_device_name)) { alsa_sndlib_device_name = (char *)"default"; if (!alsa_probe_device_name(alsa_sndlib_device_name)) { alsa_sndlib_device_name = (char *)"plughw:0"; if (!alsa_probe_device_name(alsa_sndlib_device_name)) alsa_sndlib_device_name = (char *)"hw:0"; } } /* if no device name set yet, try for special sndlib name first */ if (!alsa_playback_device_name) { if (alsa_probe_device_name(alsa_sndlib_device_name)) alsa_playback_device_name = alsa_sndlib_device_name; else alsa_playback_device_name = (char *)"hw:0"; } if (!alsa_capture_device_name) { if (alsa_probe_device_name(alsa_sndlib_device_name)) alsa_capture_device_name = alsa_sndlib_device_name; else alsa_capture_device_name = (char *)"hw:0"; } alsa_get_int_from_env(MUS_ALSA_BUFFERS_ENV_NAME, &alsa_buffers, -1, -1); alsa_get_int_from_env(MUS_ALSA_BUFFER_SIZE_ENV_NAME, &alsa_buffer_size, -1, -1); if ((alsa_buffer_size > 0) && (alsa_buffers > 0)) alsa_samples_per_channel = alsa_buffer_size / alsa_buffers; if (!alsa_set_playback_parameters()) { /* somehow we got a device that passed muster with alsa_probe_device_name, but doesn't return hw params! */ alsa_playback_device_name = (char *)"plughw:0"; if (!alsa_set_playback_parameters()) { alsa_playback_device_name = (char *)"hw:0"; if (!alsa_set_playback_parameters()) return(MUS_ERROR); } } if (!alsa_set_capture_parameters()) { alsa_capture_device_name = (char *)"plughw:0"; if (!alsa_set_capture_parameters()) { alsa_capture_device_name = (char *)"hw:0"; if (!alsa_set_capture_parameters()) return(MUS_ERROR); } } if ((!alsa_hw_params[SND_PCM_STREAM_CAPTURE]) || (!alsa_hw_params[SND_PCM_STREAM_PLAYBACK])) return(MUS_ERROR); audio_initialized = true; return(0); } /* open an input or output stream */ static int alsa_audio_open(int ur_dev, int srate, int chans, mus_sample_t samp_type, int size) { int device, alsa_device; snd_pcm_format_t alsa_format; snd_pcm_stream_t alsa_stream; char *alsa_name; int frames, periods; int err; snd_pcm_t *handle; snd_pcm_hw_params_t *hw_params = NULL; snd_pcm_sw_params_t *sw_params = NULL; if ((!audio_initialized) && (mus_audio_initialize() != MUS_NO_ERROR)) return(MUS_ERROR); if (chans <= 0) return(MUS_ERROR); if (alsa_trace) mus_print("%s: %x rate=%d, chans=%d, format=%d:%s, size=%d", __func__, ur_dev, srate, chans, samp_type, mus_sample_type_to_string(samp_type), size); /* card = MUS_AUDIO_SYSTEM(ur_dev); */ device = MUS_AUDIO_DEVICE(ur_dev); if ((err = to_alsa_device(device, &alsa_device, &alsa_stream)) < 0) { return(alsa_mus_error(MUS_AUDIO_DEVICE_NOT_AVAILABLE, mus_format("%s: cannot translate device %d to alsa", snd_strerror(err), device))); } if ((alsa_format = to_alsa_format(samp_type)) == (snd_pcm_format_t)MUS_ERROR) { return(alsa_mus_error(MUS_AUDIO_SAMPLE_TYPE_NOT_AVAILABLE, mus_format("could not change %s<%d> to alsa format", mus_sample_type_to_string(samp_type), samp_type))); } alsa_name = (alsa_stream == SND_PCM_STREAM_PLAYBACK) ? alsa_playback_device_name : alsa_capture_device_name; if ((err = snd_pcm_open(&handle, alsa_name, alsa_stream, alsa_open_mode)) != 0) { /* snd_pcm_close(handle); */ /* this segfaults in some versions of ALSA */ return(alsa_mus_error(MUS_AUDIO_CANT_OPEN, mus_format("open pcm %s stream %s: %s", alsa_name, snd_pcm_stream_name(alsa_stream), snd_strerror(err)))); } handles[alsa_stream] = handle; hw_params = alsa_hw_params[alsa_stream]; sw_params = alsa_sw_params[alsa_stream]; if ((err = snd_pcm_hw_params_any(handle, hw_params)) < 0) { snd_pcm_close(handle); handles[alsa_stream] = NULL; alsa_dump_configuration(alsa_name, hw_params, sw_params); return(alsa_mus_error(MUS_AUDIO_CONFIGURATION_NOT_AVAILABLE, mus_format("%s: no parameter configurations available for %s", snd_strerror(err), alsa_name))); } err = snd_pcm_hw_params_set_access(handle, hw_params, alsa_interleave); if (err < 0) { snd_pcm_close(handle); handles[alsa_stream] = NULL; alsa_dump_configuration(alsa_name, hw_params, sw_params); return(alsa_mus_error(MUS_AUDIO_CONFIGURATION_NOT_AVAILABLE, mus_format("%s: %s: access type %s not available", snd_strerror(err), alsa_name, snd_pcm_access_name(alsa_interleave)))); } periods = alsa_buffers; err = snd_pcm_hw_params_set_periods(handle, hw_params, periods, 0); if (err < 0) { unsigned int minp, maxp; int dir; snd_pcm_hw_params_get_periods_min(hw_params, &minp, &dir); snd_pcm_hw_params_get_periods_max(hw_params, &maxp, &dir); snd_pcm_close(handle); handles[alsa_stream] = NULL; alsa_dump_configuration(alsa_name, hw_params, sw_params); return(alsa_mus_error(MUS_AUDIO_CONFIGURATION_NOT_AVAILABLE, mus_format("%s: %s: cannot set number of periods to %d, min is %d, max is %d", snd_strerror(err), alsa_name, periods, (int)minp, (int)maxp))); } frames = size / chans / mus_bytes_per_sample(samp_type); err = snd_pcm_hw_params_set_buffer_size(handle, hw_params, frames * periods); if (err < 0) { snd_pcm_uframes_t minp, maxp; snd_pcm_hw_params_get_buffer_size_min(hw_params, &minp); snd_pcm_hw_params_get_buffer_size_max(hw_params, &maxp); snd_pcm_close(handle); handles[alsa_stream] = NULL; alsa_dump_configuration(alsa_name, hw_params, sw_params); return(alsa_mus_error(MUS_AUDIO_CONFIGURATION_NOT_AVAILABLE, mus_format("%s: %s: cannot set buffer size to %d periods of %d frames; \ total requested buffer size is %d frames, minimum allowed is %d, maximum is %d", snd_strerror(err), alsa_name, periods, frames, periods * frames, (int)minp, (int)maxp))); } err = snd_pcm_hw_params_set_format(handle, hw_params, alsa_format); if (err < 0) { snd_pcm_close(handle); handles[alsa_stream] = NULL; alsa_dump_configuration(alsa_name, hw_params, sw_params); return(alsa_mus_error(MUS_AUDIO_CONFIGURATION_NOT_AVAILABLE, mus_format("%s: %s: cannot set format to %s", snd_strerror(err), alsa_name, snd_pcm_format_name(alsa_format)))); } err = snd_pcm_hw_params_set_channels(handle, hw_params, chans); if (err < 0) { snd_pcm_close(handle); handles[alsa_stream] = NULL; alsa_dump_configuration(alsa_name, hw_params, sw_params); return(alsa_mus_error(MUS_AUDIO_CONFIGURATION_NOT_AVAILABLE, mus_format("%s: %s: cannot set channels to %d", snd_strerror(err), alsa_name, chans))); } { unsigned int new_rate; new_rate = srate; /* r is unsigned int so it can't be negative */ err = snd_pcm_hw_params_set_rate_near(handle, hw_params, &new_rate, 0); if ((new_rate != (unsigned int)srate) && (!alsa_squelch_warning)) { mus_print("%s: could not set rate to exactly %d, set to %d instead", alsa_name, srate, new_rate); } } err = snd_pcm_hw_params(handle, hw_params); if (err < 0) { snd_pcm_close(handle); handles[alsa_stream] = NULL; alsa_dump_configuration(alsa_name, hw_params, sw_params); return(alsa_mus_error(MUS_AUDIO_CONFIGURATION_NOT_AVAILABLE, mus_format("%s: cannot set hardware parameters for %s", snd_strerror(err), alsa_name))); } snd_pcm_sw_params_current(handle, sw_params); err = snd_pcm_sw_params(handle, sw_params); if (err < 0) { snd_pcm_close(handle); handles[alsa_stream] = NULL; alsa_dump_configuration(alsa_name, hw_params, sw_params); return(alsa_mus_error(MUS_AUDIO_CONFIGURATION_NOT_AVAILABLE, mus_format("%s: cannot set software parameters for %s", snd_strerror(err), alsa_name))); } /* for now the id for the stream is the direction identifier, that is not a problem because we only advertise one card with two devices */ return(alsa_stream); } /* sndlib support for opening output devices */ static int alsa_mus_audio_open_output(int ur_dev, int srate, int chans, mus_sample_t samp_type, int size) { return(alsa_audio_open(ur_dev, srate, chans, samp_type, size)); } /* sndlib support for opening input devices */ static int alsa_mus_audio_open_input(int ur_dev, int srate, int chans, mus_sample_t samp_type, int size) { return(alsa_audio_open(ur_dev, srate, chans, samp_type, size)); } /* sndlib support for closing a device */ /* to force it to stop, snd_pcm_drop */ static bool xrun_warned = false; static int alsa_mus_audio_close(int id) { xrun_warned = false; if (id == MUS_ERROR) return(MUS_ERROR); if (alsa_trace) mus_print( "%s: %d", __func__, id); if (handles[id]) { int err; err = snd_pcm_drain(handles[id]); if (err != 0) mus_print("snd_pcm_drain: %s", snd_strerror(err)); err = snd_pcm_close(handles[id]); if (err != 0) return(alsa_mus_error(MUS_AUDIO_CANT_CLOSE, mus_format("snd_pcm_close: %s", snd_strerror(err)))); handles[id] = NULL; } return(MUS_NO_ERROR); } /* recover from underruns or overruns */ static int recover_from_xrun(int id) { int err; snd_pcm_status_t *status; snd_pcm_state_t state; snd_pcm_status_alloca(&status); err = snd_pcm_status(handles[id], status); if (err < 0) { mus_print("%s: snd_pcm_status: %s", __func__, snd_strerror(err)); return(MUS_ERROR); } state = snd_pcm_status_get_state(status); if (state == SND_PCM_STATE_XRUN) { if (!xrun_warned) { xrun_warned = true; mus_print("[under|over]run detected"); } err = snd_pcm_prepare(handles[id]); if (err < 0) mus_print("snd_pcm_prepare: %s", snd_strerror(err)); else return(MUS_NO_ERROR); } else mus_print("%s: error, current state is %s", __func__, snd_pcm_state_name(state)); return(MUS_ERROR); } /* sndlib support for writing a buffer to an output device */ static int alsa_mus_audio_write(int id, char *buf, int bytes) { snd_pcm_sframes_t status; ssize_t frames; if (id == MUS_ERROR) return(MUS_ERROR); frames = snd_pcm_bytes_to_frames(handles[id], bytes); status = snd_pcm_writei(handles[id], buf, frames); if ((status == -EAGAIN) || ((status >= 0) && (status < frames))) snd_pcm_wait(handles[id], 1000); else { if (status == -EPIPE) return(recover_from_xrun(id)); else { if (status < 0) { mus_print("snd_pcm_writei: %s", snd_strerror(status)); return(MUS_ERROR); } } } return(MUS_NO_ERROR); } /* sndlib support for reading a buffer from an input device */ static int alsa_mus_audio_read(int id, char *buf, int bytes) { snd_pcm_sframes_t status; ssize_t frames; if (id == MUS_ERROR) return(MUS_ERROR); frames = snd_pcm_bytes_to_frames(handles[id], bytes); status = snd_pcm_readi(handles[id], buf, frames); if ((status == -EAGAIN) || ((status >= 0) && (status < frames))) snd_pcm_wait(handles[id], 1000); else { if (status == -EPIPE) return(recover_from_xrun(id)); else { if (status < 0) { mus_print("snd_pcm_readi: %s", snd_strerror(status)); return(MUS_ERROR); } } } return(MUS_NO_ERROR); } /* read state of the audio hardware */ static int alsa_chans(int ur_dev, int *info) { int card; int device; int alsa_device = 0; snd_pcm_stream_t alsa_stream = SND_PCM_STREAM_PLAYBACK; if ((!audio_initialized) && (mus_audio_initialize() != MUS_NO_ERROR)) return(MUS_ERROR); card = MUS_AUDIO_SYSTEM(ur_dev); device = MUS_AUDIO_DEVICE(ur_dev); to_alsa_device(device, &alsa_device, &alsa_stream); if (card > 0 || alsa_device > 0) return(alsa_mus_error(MUS_AUDIO_CANT_READ, NULL)); if ((alsa_stream == SND_PCM_STREAM_CAPTURE) && (alsa_capture_device_name) && (strcmp(alsa_capture_device_name, "default") == 0)) { if (info) info[0] = 2; else return(2); } { unsigned int max_channels = 0; snd_pcm_hw_params_get_channels_max(alsa_hw_params[alsa_stream], &max_channels); if ((alsa_stream == SND_PCM_STREAM_CAPTURE) && (max_channels > (unsigned int)alsa_max_capture_channels)) { /* limit number of capture channels to a reasonable maximum, if the user specifies a plug pcm as the capture pcm then the returned number of channels would be MAXINT (or whatever the name is for a really big number). At this point there is no support in the alsa api to distinguish between default parameters or those that have been set by a user on purpose, of for querying the hardware pcm device that is hidden by the plug device to see what is the real number of channels for the device we are dealing with. We could also try to flag this as an error to the user and exit the program */ max_channels = alsa_max_capture_channels; } if (info) { unsigned int tmp = 0; info[0] = max_channels; snd_pcm_hw_params_get_channels_min(alsa_hw_params[alsa_stream], &tmp); info[1] = tmp; info[2] = max_channels; } return(max_channels); } } static int alsa_sample_types(int ur_dev, int chan, mus_sample_t *val) { int card; int device; int alsa_device = 0; snd_pcm_stream_t alsa_stream = SND_PCM_STREAM_PLAYBACK; if ((!audio_initialized) && (mus_audio_initialize() != MUS_NO_ERROR)) return(MUS_ERROR); card = MUS_AUDIO_SYSTEM(ur_dev); device = MUS_AUDIO_DEVICE(ur_dev); to_alsa_device(device, &alsa_device, &alsa_stream); if (card > 0 || alsa_device > 0) return(alsa_mus_error(MUS_AUDIO_CANT_READ, NULL)); { int f, format; snd_pcm_format_mask_t *mask; snd_pcm_format_mask_alloca(&mask); snd_pcm_hw_params_get_format_mask(alsa_hw_params[alsa_stream], mask); for (format = 0, f = 1; format < SND_PCM_FORMAT_LAST; format++) { int err; err = snd_pcm_format_mask_test(mask, (snd_pcm_format_t)format); if (err > 0) { if ((f < chan) && (to_mus_sample_type(format) != MUS_UNKNOWN_SAMPLE)) val[f++] = to_mus_sample_type(format); } } val[0] = (mus_sample_t)(f - 1); } return(MUS_NO_ERROR); } #endif /* HAVE_ALSA */ /* -------------------------------- SUN -------------------------------- */ /* * Thanks to Seppo Ingalsuo for several bugfixes. * record case improved after perusal of Snack 1.6/src/jkAudio_sun.c */ /* apparently input other than 8000 is 16-bit, 8000 is (?) mulaw */ #if (defined(__sun) || defined(__SVR4)) && (!(defined(AUDIO_OK))) #define AUDIO_OK 1 #include #ifdef SUNOS #include #endif #include #ifdef SUNOS #include #else #include #endif #include int mus_audio_initialize(void) {return(MUS_NO_ERROR);} #define DAC_NAME "/dev/audio" #define AUDIODEV_ENV "AUDIODEV" #define return_error_exit(Error_Type, Audio_Line, Ur_Error_Message) \ do { char *Error_Message; Error_Message = Ur_Error_Message; \ if (Audio_Line != -1) close(Audio_Line); \ if (Error_Message) \ {mus_standard_error(Error_Type, Error_Message); free(Error_Message);} \ else mus_standard_error(Error_Type, mus_error_type_to_string(Error_Type)); \ return(MUS_ERROR); \ } while (false) char *mus_audio_moniker(void) { #ifndef AUDIO_DEV_AMD struct audio_device ad; #else int ad; #endif int audio_fd, err; char *dev_name; if (getenv(AUDIODEV_ENV) != NULL) dev_name = getenv(AUDIODEV_ENV); else dev_name = (char *)DAC_NAME; audio_fd = open(dev_name, O_RDONLY | O_NONBLOCK, 0); if (audio_fd == -1) { audio_fd = open("/dev/audioctl", O_RDONLY | O_NONBLOCK, 0); if (audio_fd == -1) return("sun probably"); } err = ioctl(audio_fd, AUDIO_GETDEV, &ad); if (err == -1) { close(audio_fd); return("sun?"); } mus_audio_close(audio_fd); if (version_name == NULL) version_name = (char *)calloc(PRINT_BUFFER_SIZE, sizeof(char)); #ifndef AUDIO_DEV_AMD snprintf(version_name, LABEL_BUFFER_SIZE, "audio: %s (%s)", ad.name, ad.version); #else switch (ad) { case AUDIO_DEV_AMD: snprintf(version_name, LABEL_BUFFER_SIZE, "audio: amd"); break; #ifdef AUDIO_DEV_CS4231 case AUDIO_DEV_CS4231: snprintf(version_name, LABEL_BUFFER_SIZE, "audio: cs4231"); break; #endif case AUDIO_DEV_SPEAKERBOX: snprintf(version_name, LABEL_BUFFER_SIZE, "audio: speakerbox"); break; case AUDIO_DEV_CODEC: snprintf(version_name, LABEL_BUFFER_SIZE, "audio: codec"); break; default: snprintf(version_name, LABEL_BUFFER_SIZE, "audio: unknown"); break; } #endif return(version_name); } static int to_sun_sample_type(mus_sample_t samp_type) { switch (samp_type) { #if MUS_LITTLE_ENDIAN case MUS_LSHORT: /* Solaris on Intel? */ #else case MUS_BSHORT: #endif return(AUDIO_ENCODING_LINEAR); break; case MUS_BYTE: #if defined(AUDIO_ENCODING_LINEAR8) return(AUDIO_ENCODING_LINEAR8); break; #else return(AUDIO_ENCODING_LINEAR); break; #endif case MUS_MULAW: return(AUDIO_ENCODING_ULAW); break; case MUS_ALAW: return(AUDIO_ENCODING_ALAW); break; /* there's also AUDIO_ENCODING_DVI */ default: break; } return(MUS_ERROR); } int mus_audio_open_output(int ur_dev, int srate, int chans, mus_sample_t samp_type, int size) { struct audio_info info; char *dev_name; int encode, bits, dev; int audio_fd, err; dev = MUS_AUDIO_DEVICE(ur_dev); encode = to_sun_sample_type(samp_type); if (encode == MUS_ERROR) return_error_exit(MUS_AUDIO_SAMPLE_TYPE_NOT_AVAILABLE, -1, mus_format("sample type %d (%s) not available", samp_type, mus_sample_type_name(samp_type))); if (getenv(AUDIODEV_ENV) != NULL) dev_name = getenv(AUDIODEV_ENV); else dev_name = (char *)DAC_NAME; if (dev != MUS_AUDIO_DUPLEX_DEFAULT) audio_fd = open(dev_name, O_WRONLY, 0); else audio_fd = open(dev_name, O_RDWR, 0); if (audio_fd == -1) return_error_exit(MUS_AUDIO_CANT_OPEN, -1, mus_format("can't open output %s: %s", dev_name, strerror(errno))); AUDIO_INITINFO(&info); if (dev == MUS_AUDIO_LINE_OUT) info.play.port = AUDIO_LINE_OUT; else { if (dev == MUS_AUDIO_SPEAKERS) /* OR may not be available */ info.play.port = AUDIO_SPEAKER | AUDIO_HEADPHONE; else info.play.port = AUDIO_SPEAKER; } info.play.sample_rate = srate; info.play.channels = chans; bits = 8 * mus_bytes_per_sample(samp_type); info.play.precision = bits; info.play.encoding = encode; err = ioctl(audio_fd, AUDIO_SETINFO, &info); if (err == -1) { ioctl(audio_fd, AUDIO_GETINFO, &info); if ((int)info.play.channels != chans) return_error_exit(MUS_AUDIO_CHANNELS_NOT_AVAILABLE, audio_fd, mus_format("can't set output %s channels to %d", dev_name, chans)); if (((int)info.play.precision != bits) || ((int)info.play.encoding != encode)) return_error_exit(MUS_AUDIO_SAMPLE_TYPE_NOT_AVAILABLE, audio_fd, mus_format("can't set output %s sample type to %d bits, %d encode (%s)", dev_name, bits, encode, mus_sample_type_name(samp_type))); if ((int)info.play.sample_rate != srate) return_error_exit(MUS_AUDIO_CHANNELS_NOT_AVAILABLE, audio_fd, mus_format("can't set output %s srate to %d", dev_name, srate)); } /* man audio sez the play.buffer_size field is not currently supported */ /* but since the default buffer size is 8180! we need ioctl(audio_fd, I_SETSIG, ...) */ #ifdef SUNOS ioctl(audio_fd, I_FLUSH, FLUSHR); #endif return(audio_fd); } int mus_audio_write(int line, char *buf, int bytes) { if (write(line, buf, bytes) != bytes) return_error_exit(MUS_AUDIO_WRITE_ERROR, -1, mus_format("write error: %s", strerror(errno))); return(MUS_NO_ERROR); } int mus_audio_close(int line) { write(line, (char *)NULL, 0); close(line); return(MUS_NO_ERROR); } int mus_audio_read(int line, char *buf, int bytes) { int total = 0; char *curbuf; /* ioctl(line, AUDIO_DRAIN, NULL) */ /* this seems to return 8-12 bytes fewer than requested -- perverse! */ /* should I buffer data internally? */ /* apparently we need to loop here ... */ curbuf = buf; while (total < bytes) { int bytes_available; ioctl(line, FIONREAD, &bytes_available); if (bytes_available > 0) { int bytes_read; if ((total + bytes_available) > bytes) bytes_available = bytes - total; bytes_read = read(line, curbuf, bytes_available); if (bytes_read > 0) { total += bytes_read; curbuf = (char *)(buf + total); } /* else return anyway?? */ } } return(MUS_NO_ERROR); } int mus_audio_open_input(int ur_dev, int srate, int chans, mus_sample_t samp_type, int size) { struct audio_info info; int indev, encode, bits, dev, audio_fd, err; char *dev_name; dev = MUS_AUDIO_DEVICE(ur_dev); encode = to_sun_sample_type(samp_type); bits = 8 * mus_bytes_per_sample(samp_type); if (encode == -1) return_error_exit(MUS_AUDIO_SAMPLE_TYPE_NOT_AVAILABLE, -1, mus_format("sample type %d bits, %d encode (%s) not available", bits, encode, mus_sample_type_name(samp_type))); if (getenv(AUDIODEV_ENV) != NULL) dev_name = getenv(AUDIODEV_ENV); else dev_name = (char *)DAC_NAME; if (dev != MUS_AUDIO_DUPLEX_DEFAULT) audio_fd = open(dev_name, O_RDONLY, 0); else audio_fd = open(dev_name, O_RDWR, 0); if (audio_fd == -1) return_error_exit(MUS_AUDIO_CANT_OPEN, -1, mus_format("can't open input %s: %s", dev_name, strerror(errno))); AUDIO_INITINFO(&info); /* ioctl(audio_fd, AUDIO_GETINFO, &info); */ info.record.sample_rate = srate; info.record.channels = chans; err = ioctl(audio_fd, AUDIO_SETINFO, &info); if (err == -1) return_error_exit(MUS_AUDIO_CANT_OPEN, audio_fd, mus_format("can't set srate %d and chans %d for input %s", srate, chans, dev_name)); ioctl(audio_fd, AUDIO_GETINFO, &info); if (info.record.sample_rate != (unsigned int)srate) mus_print("%s[%d]: sampling rate: %d != %d\n", __FILE__, __LINE__, info.record.sample_rate, srate); if (info.record.channels != (unsigned int)chans) mus_print("%s[%d]: channels: %d != %d\n", __FILE__, __LINE__, info.record.channels, chans); info.record.precision = bits; /* was play, changed 10-Jul-03 thanks to Jürgen Keil */ info.record.encoding = encode; err = ioctl(audio_fd, AUDIO_SETINFO, &info); if (err == -1) return_error_exit(MUS_AUDIO_CANT_OPEN, audio_fd, mus_format("can't set bits %d, encode %d (sample type %s) for input %s", bits, encode, mus_sample_type_name(samp_type), dev_name)); ioctl(audio_fd, AUDIO_GETINFO, &info); /* these cannot be OR'd */ if (dev == MUS_AUDIO_LINE_IN) indev = AUDIO_LINE_IN; else indev = AUDIO_MICROPHONE; info.record.port = indev; err = ioctl(audio_fd, AUDIO_SETINFO, &info); if (err == -1) return_error_exit(MUS_AUDIO_CANT_WRITE, audio_fd, mus_format("can't set record.port to %d for %s", indev, dev_name)); err = ioctl(audio_fd, AUDIO_GETINFO, &info); if (err == -1) return_error_exit(MUS_AUDIO_CANT_READ, audio_fd, mus_format("can't getinfo on input %s (line: %d)", dev_name, audio_fd)); else { if ((int)info.record.port != indev) return_error_exit(MUS_AUDIO_DEVICE_NOT_AVAILABLE, audio_fd, mus_format("confusion in record.port: %d != %d (%s)", (int)info.record.port, indev, dev_name)); if ((int)info.record.channels != chans) return_error_exit(MUS_AUDIO_CHANNELS_NOT_AVAILABLE, audio_fd, mus_format("confusion in record.channels: %d != %d (%s)", (int)info.record.channels, chans, dev_name)); if (((int)info.record.precision != bits) || ((int)info.record.encoding != encode)) return_error_exit(MUS_AUDIO_SAMPLE_TYPE_NOT_AVAILABLE, audio_fd, mus_format("confusion in record.precision|encoding: %d != %d or %d != %d (%s)", (int)info.record.precision, bits, (int)info.record.encoding, encode, dev_name)); } /* this may be a bad idea */ info.record.buffer_size = size; err = ioctl(audio_fd, AUDIO_SETINFO, &info); if (err == -1) return_error_exit(MUS_AUDIO_CANT_WRITE, audio_fd, mus_format("can't set buffer size to %d on input %s", size, dev_name)); return(audio_fd); } #if 0 /* pause can be implemented with play.pause and record.pause */ static const char *sun_sample_type_name(mus_sample_t samp_type) { switch (samp_type) { #ifdef AUDIO_ENCODING_ALAW case AUDIO_ENCODING_ALAW: return("alaw"); break; #endif #ifdef AUDIO_ENCODING_ULAW case AUDIO_ENCODING_ULAW: return("ulaw"); break; #endif #ifdef AUDIO_ENCODING_DVI case AUDIO_ENCODING_DVI: return("dvi adpcm"); break; #endif #ifdef AUDIO_ENCODING_LINEAR8 case AUDIO_ENCODING_LINEAR8: return("linear"); break; #else #ifdef AUDIO_ENCODING_PCM8 case AUDIO_ENCODING_PCM8: return("linear"); break; #endif #endif #ifdef AUDIO_ENCODING_LINEAR case AUDIO_ENCODING_LINEAR: return("linear"); break; #else #ifdef AUDIO_ENCODING_PCM16 case AUDIO_ENCODING_PCM16: return("linear"); break; #endif #endif #ifdef AUDIO_ENCODING_NONE case AUDIO_ENCODING_NONE: return("not audio"); break; /* dbri interface configured for something else */ #endif } return("unknown"); } static const char *sun_in_device_name(int dev) { if (dev == AUDIO_MICROPHONE) return("microphone"); if (dev == AUDIO_LINE_IN) return("line in"); if (dev == AUDIO_INTERNAL_CD_IN) return("cd"); if (dev == (AUDIO_MICROPHONE | AUDIO_LINE_IN)) return("microphone + line in"); if (dev == (AUDIO_MICROPHONE | AUDIO_LINE_IN | AUDIO_INTERNAL_CD_IN)) return("microphone + line in + cd"); if (dev == (AUDIO_MICROPHONE | AUDIO_INTERNAL_CD_IN)) return("microphone + cd"); if (dev == (AUDIO_LINE_IN | AUDIO_INTERNAL_CD_IN)) return("line in + cd"); return("unknown"); } static const char *sun_out_device_name(int dev) { if (dev == AUDIO_SPEAKER) return("speakers"); if (dev == AUDIO_LINE_OUT) return("line out"); if (dev == AUDIO_HEADPHONE) return("headphones"); if (dev == (AUDIO_SPEAKER | AUDIO_LINE_OUT)) return("speakers + line out"); if (dev == (AUDIO_SPEAKER | AUDIO_LINE_OUT | AUDIO_HEADPHONE)) return("speakers + line out + headphones"); if (dev == (AUDIO_SPEAKER | AUDIO_HEADPHONE)) return("speakers + headphones"); if (dev == (AUDIO_LINE_OUT | AUDIO_HEADPHONE)) return("line out + headphones"); return("unknown"); } static char *sun_vol_name = NULL; static char *sun_volume_name(float vol, int balance, int chans) { if (sun_vol_name == NULL) sun_vol_name = (char *)calloc(LABEL_BUFFER_SIZE, sizeof(char)); if (chans != 2) snprintf(sun_vol_name, LABEL_BUFFER_SIZE, "%.3f", vol); else { snprintf(sun_vol_name, LABEL_BUFFER_SIZE, "%.3f %.3f", vol * (float)(AUDIO_RIGHT_BALANCE - balance) / (float)AUDIO_RIGHT_BALANCE, vol * (float)balance / (float)AUDIO_RIGHT_BALANCE); } return(sun_vol_name); } #endif #endif /* ------------------------------- WINDOZE ----------------------------------------- */ #if defined(_MSC_VER) && (!(defined(__CYGWIN__))) #define AUDIO_OK 1 #include #include #define BUFFER_FILLED 1 #define BUFFER_EMPTY 2 #define OUTPUT_LINE 1 #define INPUT_LINE 2 #define SOUND_UNREADY 0 #define SOUND_INITIALIZED 1 #define SOUND_RUNNING 2 static int buffer_size = 1024; static int db_state[2]; static int sound_state = 0; static int current_chans = 1; static int current_datum_size = 2; static int current_buf = 0; WAVEHDR wh[2]; HWAVEOUT fd; HWAVEIN record_fd; WAVEHDR rec_wh; static int rec_state = SOUND_UNREADY; static MMRESULT win_in_err = 0, win_out_err = 0; static char errstr[128], getstr[128]; static char *win_err_buf = NULL; static mus_print_handler_t *old_handler; static void win_mus_print(char *msg) { if ((win_in_err == 0) && (win_out_err == 0)) (*old_handler)(msg); else { if (win_in_err) waveInGetErrorText(win_in_err, getstr, PRINT_BUFFER_SIZE); else waveOutGetErrorText(win_out_err, getstr, PRINT_BUFFER_SIZE); snprintf(errstr, PRINT_BUFFER_SIZE, "%s [%s]", msg, getstr); (*old_handler)(errstr); } } static void start_win_print(void) { if (old_handler != win_mus_print) old_handler = mus_print_set_handler(win_mus_print); } static void end_win_print(void) { if (old_handler == win_mus_print) mus_print_set_handler(NULL); else mus_print_set_handler(old_handler); } #define return_error_exit(Error_Type, Ur_Error_Message) \ do { char *Error_Message; Error_Message = Ur_Error_Message; \ if (Error_Message) \ {mus_standard_error(Error_Type, Error_Message); free(Error_Message);} \ else mus_standard_error(Error_Type, mus_error_type_to_string(Error_Type)); \ end_win_print(); \ return(MUS_ERROR); \ } while (false) DWORD CALLBACK next_buffer(HWAVEOUT w, UINT msg, DWORD user_data, DWORD p1, DWORD p2) { if (msg == WOM_DONE) { db_state[current_buf] = BUFFER_EMPTY; } return(0); } int mus_audio_open_output(int ur_dev, int srate, int chans, mus_sample_t samp_type, int size) { WAVEFORMATEX wf; int dev; start_win_print(); dev = MUS_AUDIO_DEVICE(ur_dev); wf.nChannels = chans; current_chans = chans; wf.wFormatTag = WAVE_FORMAT_PCM; wf.cbSize = 0; if (samp_type == MUS_UBYTE) { wf.wBitsPerSample = 8; current_datum_size = 1; } else { wf.wBitsPerSample = 16; current_datum_size = 2; } wf.nSamplesPerSec = srate; wf.nBlockAlign = chans * current_datum_size; wf.nAvgBytesPerSec = wf.nBlockAlign * wf.nSamplesPerSec; #if _MSC_VER win_out_err = waveOutOpen(&fd, WAVE_MAPPER, &wf, (DWORD (*)(HWAVEOUT,UINT,DWORD,DWORD,DWORD))next_buffer, 0, CALLBACK_FUNCTION); #else win_out_err = waveOutOpen(&fd, WAVE_MAPPER, &wf, (DWORD)next_buffer, 0, CALLBACK_FUNCTION); #endif /* 0 here = user_data above, other case = WAVE_FORMAT_QUERY */ if (win_out_err) return_error_exit(MUS_AUDIO_DEVICE_NOT_AVAILABLE, mus_format("can't open %d", dev)); waveOutPause(fd); if (size <= 0) buffer_size = 1024; else buffer_size = size; wh[0].dwBufferLength = buffer_size * current_datum_size; wh[0].dwFlags = 0; wh[0].dwLoops = 0; wh[0].lpData = (char *)calloc(wh[0].dwBufferLength, sizeof(char)); if ((wh[0].lpData) == 0) { waveOutClose(fd); return_error_exit(MUS_AUDIO_SIZE_NOT_AVAILABLE, mus_format("can't allocate buffer size %d for output %d", buffer_size, dev)); } win_out_err = waveOutPrepareHeader(fd, &(wh[0]), sizeof(WAVEHDR)); if (win_out_err) { free(wh[0].lpData); waveOutClose(fd); return_error_exit(MUS_AUDIO_CONFIGURATION_NOT_AVAILABLE, mus_format("can't setup output 'header' for %d", dev)); } db_state[0] = BUFFER_EMPTY; wh[1].dwBufferLength = buffer_size * current_datum_size; wh[1].dwFlags = 0; wh[1].dwLoops = 0; wh[1].lpData = (char *)calloc(wh[0].dwBufferLength, sizeof(char)); if ((wh[1].lpData) == 0) { free(wh[0].lpData); waveOutClose(fd); return_error_exit(MUS_AUDIO_SIZE_NOT_AVAILABLE, mus_format("can't allocate buffer size %d for output %d", buffer_size, dev)); } win_out_err = waveOutPrepareHeader(fd, &(wh[1]), sizeof(WAVEHDR)); if (win_out_err) { waveOutUnprepareHeader(fd, &(wh[0]), sizeof(WAVEHDR)); free(wh[0].lpData); free(wh[1].lpData); waveOutClose(fd); return_error_exit(MUS_AUDIO_CONFIGURATION_NOT_AVAILABLE, mus_format("can't setup output 'header' for %d", dev)); } db_state[1] = BUFFER_EMPTY; sound_state = SOUND_INITIALIZED; current_buf = 0; end_win_print(); return(OUTPUT_LINE); } static MMRESULT fill_buffer(int dbi, char *inbuf, int instart, int bytes) { int i, j; win_out_err = 0; if (sound_state == SOUND_UNREADY) return(0); for (i = instart, j = 0; j < bytes; j++, i++) wh[dbi].lpData[j] = inbuf[i]; wh[dbi].dwBufferLength = bytes; db_state[dbi] = BUFFER_FILLED; if ((sound_state == SOUND_INITIALIZED) && (dbi == 1)) { sound_state = SOUND_RUNNING; win_out_err = waveOutRestart(fd); } return(win_out_err); } static void wait_for_empty_buffer(int buf) { while (db_state[buf] != BUFFER_EMPTY) { Sleep(1); /* in millisecs, so even this may be too much if buf = 256 bytes */ } } int mus_audio_write(int line, char *buf, int bytes) { int leftover, start; start_win_print(); if (line != OUTPUT_LINE) return_error_exit(MUS_AUDIO_CANT_WRITE, mus_format("write error: line %d != %d?", line, OUTPUT_LINE)); win_out_err = 0; leftover = bytes; start = 0; if (sound_state == SOUND_UNREADY) { end_win_print(); return(MUS_NO_ERROR); } while (leftover > 0) { int lim; lim = leftover; if (lim > buffer_size) lim = buffer_size; leftover -= lim; wait_for_empty_buffer(current_buf); win_out_err = fill_buffer(current_buf, buf, start, lim); if (win_out_err) return_error_exit(MUS_AUDIO_CANT_WRITE, mus_format("write error on %d", line)); win_out_err = waveOutWrite(fd, &wh[current_buf], sizeof(WAVEHDR)); if (win_out_err) return_error_exit(MUS_AUDIO_CANT_WRITE, mus_format("write error on %d", line)); start += lim; current_buf++; if (current_buf > 1) current_buf = 0; } return(MUS_NO_ERROR); } static float unlog(unsigned short val) { /* 1.0 linear is 0xffff, rest is said to be "logarithmic", whatever that really means here */ if (val == 0) return(0.0); return((float)val / 65536.0); /* return(pow(2.0, amp) - 1.0); */ /* doc seems to be bogus */ } static char *mixer_status_name(int status) { switch (status) { case MIXERLINE_LINEF_ACTIVE: return(", (active)"); break; case MIXERLINE_LINEF_DISCONNECTED: return(", (disconnected)"); break; case MIXERLINE_LINEF_SOURCE: return(", (source)"); break; default: return(""); break; } } static char *mixer_target_name(int type) { switch (type) { case MIXERLINE_TARGETTYPE_UNDEFINED: return("undefined"); break; case MIXERLINE_TARGETTYPE_WAVEOUT: return("output"); break; case MIXERLINE_TARGETTYPE_WAVEIN: return("input"); break; case MIXERLINE_TARGETTYPE_MIDIOUT: return("midi output"); break; case MIXERLINE_TARGETTYPE_MIDIIN: return("midi input"); break; case MIXERLINE_TARGETTYPE_AUX: return("aux"); break; default: return(""); break; } } static char *mixer_component_name(int type) { switch (type) { case MIXERLINE_COMPONENTTYPE_DST_UNDEFINED: return("undefined"); break; case MIXERLINE_COMPONENTTYPE_DST_DIGITAL: return("digital"); break; case MIXERLINE_COMPONENTTYPE_DST_LINE: return("line"); break; case MIXERLINE_COMPONENTTYPE_DST_MONITOR: return("monitor"); break; case MIXERLINE_COMPONENTTYPE_DST_SPEAKERS: return("speakers"); break; case MIXERLINE_COMPONENTTYPE_DST_HEADPHONES: return("headphones"); break; case MIXERLINE_COMPONENTTYPE_DST_TELEPHONE: return("telephone"); break; case MIXERLINE_COMPONENTTYPE_DST_WAVEIN: return("wave in"); break; case MIXERLINE_COMPONENTTYPE_DST_VOICEIN: return("voice in"); break; case MIXERLINE_COMPONENTTYPE_SRC_UNDEFINED: return("undefined"); break; case MIXERLINE_COMPONENTTYPE_SRC_DIGITAL: return("digital"); break; case MIXERLINE_COMPONENTTYPE_SRC_LINE: return("line"); break; case MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE: return("mic"); break; case MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER: return("synth"); break; case MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC: return("CD"); break; case MIXERLINE_COMPONENTTYPE_SRC_TELEPHONE: return("telephone"); break; case MIXERLINE_COMPONENTTYPE_SRC_PCSPEAKER: return("speaker"); break; case MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT: return("wave out"); break; case MIXERLINE_COMPONENTTYPE_SRC_AUXILIARY: return("aux"); break; case MIXERLINE_COMPONENTTYPE_SRC_ANALOG: return("analog"); break; default: return(""); break; } } char *mus_audio_moniker(void) {return("MS audio");} /* version number of some sort? */ int mus_audio_initialize(void) { return(MUS_NO_ERROR); } int mus_audio_close(int line) { win_out_err = 0; win_in_err = 0; if (line == OUTPUT_LINE) { /* fill with a few zeros, wait for empty flag */ if (sound_state != SOUND_UNREADY) { int i; wait_for_empty_buffer(current_buf); for (i = 0; i < 128; i++) wh[current_buf].lpData[i] = 0; wait_for_empty_buffer(current_buf); win_out_err = waveOutClose(fd); i = 0; while (win_out_err == WAVERR_STILLPLAYING) { Sleep(1); win_out_err = waveOutClose(fd); i++; if (i > 1024) break; } db_state[0] = BUFFER_EMPTY; db_state[1] = BUFFER_EMPTY; sound_state = SOUND_UNREADY; waveOutUnprepareHeader(fd, &(wh[0]), sizeof(WAVEHDR)); waveOutUnprepareHeader(fd, &(wh[1]), sizeof(WAVEHDR)); free(wh[0].lpData); free(wh[1].lpData); if (win_out_err) return_error_exit(MUS_AUDIO_CANT_CLOSE, mus_format("close failed on %d", line)); } } else { if (line == INPUT_LINE) { if (rec_state != SOUND_UNREADY) { waveInReset(record_fd); waveInClose(record_fd); waveInUnprepareHeader(record_fd, &rec_wh, sizeof(WAVEHDR)); if (rec_wh.lpData) { free(rec_wh.lpData); rec_wh.lpData = NULL; } rec_state = SOUND_UNREADY; } } else return_error_exit(MUS_AUDIO_CANT_CLOSE, mus_format("can't close unrecognized line %d", line)); } return(MUS_NO_ERROR); } /* * waveInAddBuffer sends buffer to get data * MM_WIM_DATA lParam->WAVEHDR dwBytesRecorded =>how much data actually in buffer */ static int current_record_chans = 0, current_record_datum_size = 0; DWORD CALLBACK next_input_buffer(HWAVEIN w, UINT msg, DWORD user_data, DWORD p1, DWORD p2) { if (msg == WIM_DATA) { /* grab data */ /* p1->dwBytesRecorded */ } return(0); } int mus_audio_open_input(int ur_dev, int srate, int chans, mus_sample_t samp_type, int size) { WAVEFORMATEX wf; int dev; win_in_err = 0; dev = MUS_AUDIO_DEVICE(ur_dev); wf.nChannels = chans; current_record_chans = chans; wf.wFormatTag = WAVE_FORMAT_PCM; wf.cbSize = 0; if (samp_type == MUS_UBYTE) { wf.wBitsPerSample = 8; current_record_datum_size = 1; } else { wf.wBitsPerSample = 16; current_record_datum_size = 2; } wf.nSamplesPerSec = srate; wf.nBlockAlign = chans * current_datum_size; wf.nAvgBytesPerSec = wf.nBlockAlign * wf.nSamplesPerSec; rec_wh.dwBufferLength = size * current_record_datum_size; rec_wh.dwFlags = 0; rec_wh.dwLoops = 0; rec_wh.lpData = (char *)calloc(rec_wh.dwBufferLength, sizeof(char)); if ((rec_wh.lpData) == 0) return_error_exit(MUS_AUDIO_SIZE_NOT_AVAILABLE, mus_format("can't allocated %d bytes for input buffer of %d", size, dev)); #if _MSC_VER win_in_err = waveInOpen(&record_fd, WAVE_MAPPER, &wf, (DWORD (*)(HWAVEIN,UINT,DWORD,DWORD,DWORD))next_input_buffer, 0, CALLBACK_FUNCTION); /* why isn't the simple cast (DWORD) correct here as below? -- the docs say the 4th arg's type is DWORD */ #else win_in_err = waveInOpen(&record_fd, WAVE_MAPPER, &wf, (DWORD)next_input_buffer, 0, CALLBACK_FUNCTION); #endif if (win_in_err) { free(rec_wh.lpData); return_error_exit(MUS_AUDIO_DEVICE_NOT_AVAILABLE, mus_format("can't open input device %d", dev)); } win_in_err = waveInPrepareHeader(record_fd, &(rec_wh), sizeof(WAVEHDR)); if (win_in_err) { free(rec_wh.lpData); waveInClose(record_fd); return_error_exit(MUS_AUDIO_CONFIGURATION_NOT_AVAILABLE, mus_format("can't prepare input 'header' for %d", dev)); } return(MUS_NO_ERROR); } int mus_audio_read(int line, char *buf, int bytes) { win_in_err = 0; return(MUS_ERROR); } #endif /* ------------------------------- Mac OSX ----------------------------------------- */ /* this code based primarily on the CoreAudio headers and portaudio pa_mac_core.c, * and to a much lesser extent, coreaudio.pdf and the HAL/Daisy examples. */ #ifdef __APPLE__ #define AUDIO_OK 1 #include #define HAVE_AUDIODEVICEDESTROYIOPROCID (defined(MAC_OS_X_VERSION_10_5)) /* #include #include */ /* ./System/Library/Frameworks/CoreAudio.framework/Headers/CoreAudio.h */ static const char* osx_error(OSStatus err) { if (err == noErr) return("no error"); switch (err) { case kAudioHardwareNoError: return("no error"); break; case kAudioHardwareUnspecifiedError: return("unspecified audio hardware error"); break; case kAudioHardwareNotRunningError: return("audio hardware not running"); break; case kAudioHardwareUnknownPropertyError: return("unknown property"); break; case kAudioHardwareBadPropertySizeError: return("bad property"); break; case kAudioHardwareBadDeviceError: return("bad device"); break; case kAudioHardwareBadStreamError: return("bad stream"); break; case kAudioHardwareIllegalOperationError: return("illegal operation"); break; case kAudioDeviceUnsupportedFormatError: return("unsupported sample type"); break; case kAudioDevicePermissionsError: return("device permissions error"); break; } return("unknown error"); } #define MAX_BUFS 4 static char **bufs = NULL; static unsigned int in_buf = 0, out_buf = 0; static OSStatus writer(AudioDeviceID inDevice, const AudioTimeStamp *inNow, const AudioBufferList *InputData, const AudioTimeStamp *InputTime, AudioBufferList *OutputData, const AudioTimeStamp *OutputTime, void *appGlobals) { AudioBuffer abuf; char *aplbuf, *sndbuf; abuf = OutputData->mBuffers[0]; aplbuf = (char *)(abuf.mData); sndbuf = bufs[out_buf]; memmove((void *)aplbuf, (void *)sndbuf, abuf.mDataByteSize); out_buf++; if (out_buf >= MAX_BUFS) out_buf = 0; return(noErr); } static OSStatus reader(AudioDeviceID inDevice, const AudioTimeStamp *inNow, const AudioBufferList *InputData, const AudioTimeStamp *InputTime, AudioBufferList *OutputData, const AudioTimeStamp *OutputTime, void *appGlobals) { AudioBuffer abuf; char *aplbuf, *sndbuf; abuf = InputData->mBuffers[0]; aplbuf = (char *)(abuf.mData); sndbuf = bufs[out_buf]; memmove((void *)sndbuf, (void *)aplbuf, abuf.mDataByteSize); out_buf++; if (out_buf >= MAX_BUFS) out_buf = 0; return(noErr); } static AudioDeviceID device = kAudioDeviceUnknown; static bool writing = false, open_for_input = false; #if HAVE_AUDIODEVICEDESTROYIOPROCID static AudioDeviceIOProcID read_procId, write_procId; #endif int mus_audio_close(int line) { OSStatus err = noErr; UInt32 sizeof_running; UInt32 running; if (open_for_input) { in_buf = 0; err = AudioDeviceStop(device, (AudioDeviceIOProc)reader); if (err == noErr) #if HAVE_AUDIODEVICEDESTROYIOPROCID err = AudioDeviceDestroyIOProcID(device, read_procId); #else err = AudioDeviceRemoveIOProc(device, (AudioDeviceIOProc)reader); #endif } else { if ((in_buf > 0) && (!writing)) { /* short enough sound that we never got started? */ #if HAVE_AUDIODEVICEDESTROYIOPROCID err = AudioDeviceCreateIOProcID(device, (AudioDeviceIOProc)writer, NULL, &write_procId); #else err = AudioDeviceAddIOProc(device, (AudioDeviceIOProc)writer, NULL); #endif if (err == noErr) err = AudioDeviceStart(device, (AudioDeviceIOProc)writer); /* writer will be called right away */ if (err == noErr) writing = true; } if (writing) { /* send out waiting buffers */ sizeof_running = sizeof(UInt32); while (in_buf == out_buf) { /* err = AudioDeviceGetProperty(device, 0, false, kAudioDevicePropertyDeviceIsRunning, &sizeof_running, &running); */ { AudioObjectPropertyAddress device_address = { kAudioDevicePropertyDeviceIsRunning, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster }; err = AudioObjectGetPropertyData(device, &device_address, 0, NULL, &sizeof_running, &running); } } while (in_buf != out_buf) { /* err = AudioDeviceGetProperty(device, 0, false, kAudioDevicePropertyDeviceIsRunning, &sizeof_running, &running); */ { AudioObjectPropertyAddress device_address = { kAudioDevicePropertyDeviceIsRunning, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster }; err = AudioObjectGetPropertyData(device, &device_address, 0, NULL, &sizeof_running, &running); } } in_buf = 0; err = AudioDeviceStop(device, (AudioDeviceIOProc)writer); if (err == noErr) #if HAVE_AUDIODEVICEDESTROYIOPROCID err = AudioDeviceDestroyIOProcID(device, write_procId); #else err = AudioDeviceRemoveIOProc(device, (AudioDeviceIOProc)writer); #endif writing = false; } } device = kAudioDeviceUnknown; if (err == noErr) return(MUS_NO_ERROR); return(MUS_ERROR); } typedef enum {CONVERT_NOT, CONVERT_COPY, CONVERT_SKIP, CONVERT_COPY_AND_SKIP, CONVERT_SKIP_N, CONVERT_COPY_AND_SKIP_N} audio_convert_t; static audio_convert_t conversion_choice = CONVERT_NOT; static float conversion_multiplier = 1.0; static int dac_out_chans, dac_out_srate; static int incoming_out_chans = 1, incoming_out_srate = 44100; static unsigned int fill_point = 0; static unsigned int bufsize = 0, current_bufsize = 0; static bool match_dac_to_sound = true; bool mus_audio_output_properties_mutable(bool mut) { match_dac_to_sound = mut; return(mut); } /* I'm getting bogus buffer sizes from the audio conversion stuff from Apple, * and I think AudioConvert doesn't handle cases like 4->6 chans correctly * so, I'll just do the conversions myself -- there is little need here * for non-integer srate conversion anyway, and the rest is trivial. */ int mus_audio_open_output(int dev, int srate, int chans, mus_sample_t samp_type, int size) { OSStatus err = noErr; UInt32 sizeof_device, sizeof_format, sizeof_bufsize; AudioStreamBasicDescription device_desc; device = 0; sizeof_device = sizeof(AudioDeviceID); sizeof_bufsize = sizeof(unsigned int); /* err = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &sizeof_device, (void *)(&device)); */ { AudioObjectPropertyAddress device_address = { kAudioHardwarePropertyDefaultOutputDevice, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; err = AudioObjectGetPropertyData(kAudioObjectSystemObject, &device_address, 0, NULL, &sizeof_device, &device); } bufsize = 4096; if (err == noErr) { /* err = AudioDeviceGetProperty(device, 0, false, kAudioDevicePropertyBufferSize, &sizeof_bufsize, &bufsize); */ { AudioObjectPropertyAddress device_address = { kAudioDevicePropertyBufferSize, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster }; err = AudioObjectGetPropertyData(device, &device_address, 0, NULL, &sizeof_bufsize, &bufsize); } } if (err != noErr) { fprintf(stderr, "open audio output err: %d %s\n", (int)err, osx_error(err)); return(MUS_ERROR); } sizeof_format = sizeof(AudioStreamBasicDescription); /* err = AudioDeviceGetProperty(device, 0, false, kAudioDevicePropertyStreamFormat, &sizeof_format, &device_desc); */ { AudioObjectPropertyAddress device_address = { kAudioDevicePropertyStreamFormat, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster }; err = AudioObjectGetPropertyData(device, &device_address, 0, NULL, &sizeof_format, &device_desc); } if (err != noErr) { fprintf(stderr, "open audio output (get device format) err: %d %s\n", (int)err, osx_error(err)); return(MUS_ERROR); } if (match_dac_to_sound) { /* now check for srate/chan mismatches and so on */ /* current DAC state: device_desc.mChannelsPerFrame, (int)(device_desc.mSampleRate) */ /* apparently get stream format can return noErr but chans == 0?? */ if (((int)device_desc.mChannelsPerFrame != chans) || ((int)(device_desc.mSampleRate) != srate)) { /* try to match DAC settings to current sound */ device_desc.mChannelsPerFrame = chans; device_desc.mSampleRate = srate; device_desc.mBytesPerPacket = chans * 4; /* assume 1 frame/packet and float32 data */ device_desc.mBytesPerFrame = chans * 4; sizeof_format = sizeof(AudioStreamBasicDescription); /* err = AudioDeviceSetProperty(device, 0, 0, false, kAudioDevicePropertyStreamFormat, sizeof_format, &device_desc); */ { AudioObjectPropertyAddress device_address = { kAudioDevicePropertyStreamFormat, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster }; err = AudioObjectSetPropertyData(device, &device_address, 0, NULL, sizeof_format, &device_desc); } /* this error is bogus in some cases -- other audio systems just ignore it, * but in my case (a standard MacIntel with no special audio hardware), if I leave * this block out, the sound is played back at the wrong rate, and the volume * of outa is set to 0.0?? */ if (err != noErr) { /* it must have failed for some reason -- look for closest match available */ /* if srate = 22050 try 44100, if chans = 1 try 2 */ /* the "get closest match" business appears to be completely bogus... */ device_desc.mChannelsPerFrame = (chans == 1) ? 2 : chans; device_desc.mSampleRate = (srate == 22050) ? 44100 : srate; device_desc.mBytesPerPacket = device_desc.mChannelsPerFrame * 4; /* assume 1 frame/packet and float32 data */ device_desc.mBytesPerFrame = device_desc.mChannelsPerFrame * 4; sizeof_format = sizeof(AudioStreamBasicDescription); /* err = AudioDeviceSetProperty(device, 0, 0, false, kAudioDevicePropertyStreamFormat, sizeof_format, &device_desc); */ { AudioObjectPropertyAddress device_address = { kAudioDevicePropertyStreamFormat, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster }; err = AudioObjectSetPropertyData(device, &device_address, 0, NULL, sizeof_format, &device_desc); } if (err != noErr) { sizeof_format = sizeof(AudioStreamBasicDescription); /* err = AudioDeviceGetProperty(device, 0, false, kAudioDevicePropertyStreamFormatMatch, &sizeof_format, &device_desc); */ { AudioObjectPropertyAddress device_address = { kAudioDevicePropertyStreamFormatMatch, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster }; err = AudioObjectGetPropertyData(device, &device_address, 0, NULL, &sizeof_format, &device_desc); } if (err == noErr) { /* match suggests: device_desc.mChannelsPerFrame, (int)(device_desc.mSampleRate) */ /* try to set DAC to reflect that match */ /* a bug here in emagic 2|6 -- we can get 6 channel match, but then can't set it?? */ sizeof_format = sizeof(AudioStreamBasicDescription); /* err = AudioDeviceSetProperty(device, 0, 0, false, kAudioDevicePropertyStreamFormat, sizeof_format, &device_desc); */ { AudioObjectPropertyAddress device_address = { kAudioDevicePropertyStreamFormat, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster }; err = AudioObjectSetPropertyData(device, &device_address, 0, NULL, sizeof_format, &device_desc); } if (err != noErr) { /* no luck -- get current DAC settings at least */ sizeof_format = sizeof(AudioStreamBasicDescription); /* AudioDeviceGetProperty(device, 0, false, kAudioDevicePropertyStreamFormat, &sizeof_format, &device_desc); */ { AudioObjectPropertyAddress device_address = { kAudioDevicePropertyStreamFormat, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster }; err = AudioObjectGetPropertyData(device, &device_address, 0, NULL, &sizeof_format, &device_desc); } } } } else { /* nothing matches? -- get current DAC settings */ sizeof_format = sizeof(AudioStreamBasicDescription); /* AudioDeviceGetProperty(device, 0, false, kAudioDevicePropertyStreamFormat, &sizeof_format, &device_desc); */ { AudioObjectPropertyAddress device_address = { kAudioDevicePropertyStreamFormat, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster }; err = AudioObjectGetPropertyData(device, &device_address, 0, NULL, &sizeof_format, &device_desc); } } } } } /* end mismatch check */ /* now DAC claims it is ready for device_desc.mChannelsPerFrame, (int)(device_desc.mSampleRate) */ dac_out_chans = device_desc.mChannelsPerFrame; /* use better variable names */ dac_out_srate = (int)(device_desc.mSampleRate); open_for_input = false; if ((bufs == NULL) || (bufsize > current_bufsize)) { int i; if (bufs) { for (i = 0; i < MAX_BUFS; i++) free(bufs[i]); free(bufs); } bufs = (char **)calloc(MAX_BUFS, sizeof(char *)); for (i = 0; i < MAX_BUFS; i++) bufs[i] = (char *)calloc(bufsize, sizeof(char)); current_bufsize = bufsize; } in_buf = 0; out_buf = 0; fill_point = 0; if (!match_dac_to_sound) { incoming_out_srate = dac_out_srate; incoming_out_chans = dac_out_chans; conversion_choice = CONVERT_NOT; conversion_multiplier = 1.0; return(MUS_NO_ERROR); } incoming_out_srate = srate; incoming_out_chans = chans; if (incoming_out_chans == dac_out_chans) { if (incoming_out_srate == dac_out_srate) { conversion_choice = CONVERT_NOT; conversion_multiplier = 1.0; } else { /* here we don't get very fancy -- assume dac/2=in */ conversion_choice = CONVERT_COPY; conversion_multiplier = 2.0; } } else { if (incoming_out_srate == dac_out_srate) { if ((dac_out_chans == 2) && (incoming_out_chans == 1)) /* the usual case */ { conversion_choice = CONVERT_SKIP; conversion_multiplier = 2.0; } else { conversion_choice = CONVERT_SKIP_N; conversion_multiplier = ((float)dac_out_chans / (float)incoming_out_chans); } } else { if ((dac_out_chans == 2) && (incoming_out_chans == 1)) /* the usual case */ { conversion_choice = CONVERT_COPY_AND_SKIP; conversion_multiplier = 4.0; } else { conversion_choice = CONVERT_COPY_AND_SKIP_N; conversion_multiplier = ((float)dac_out_chans / (float)incoming_out_chans) * 2; } } } return(MUS_NO_ERROR); } static void convert_incoming(char *to_buf, int fill_point, int lim, char *buf) { int i, j, k, jc, kc, ic; switch (conversion_choice) { case CONVERT_NOT: /* no conversion needed */ for (i = 0; i < lim; i++) to_buf[i + fill_point] = buf[i]; break; case CONVERT_COPY: /* copy sample to mimic lower srate */ for (i = 0, j = fill_point; i < lim; i += 8, j += 16) for (k = 0; k < 8; k++) { to_buf[j + k] = buf[i + k]; to_buf[j + k + 8] = buf[i + k]; } break; case CONVERT_SKIP: /* skip sample for empty chan */ for (i = 0, j = fill_point; i < lim; i += 4, j += 8) for (k = 0; k < 4; k++) { to_buf[j + k] = buf[i + k]; to_buf[j + k + 4] = 0; } break; case CONVERT_SKIP_N: /* copy incoming_out_chans then skip up to dac_out_chans */ jc = dac_out_chans * 4; ic = incoming_out_chans * 4; for (i = 0, j = fill_point; i < lim; i += ic, j += jc) { for (k = 0; k < ic; k++) to_buf[j + k] = buf[i + k]; for (k = ic; k < jc; k++) to_buf[j + k] = 0; } break; case CONVERT_COPY_AND_SKIP: for (i = 0, j = fill_point; i < lim; i += 4, j += 16) for (k = 0; k < 4; k++) { to_buf[j + k] = buf[i + k]; to_buf[j + k + 4] = 0; to_buf[j + k + 8] = buf[i + k]; to_buf[j + k + 12] = 0; } break; case CONVERT_COPY_AND_SKIP_N: /* copy for each active chan, skip rest */ jc = dac_out_chans * 8; ic = incoming_out_chans * 4; kc = dac_out_chans * 4; for (i = 0, j = fill_point; i < lim; i += ic, j += jc) { for (k = 0; k < ic; k++) { to_buf[j + k] = buf[i + k]; to_buf[j + k + kc] = buf[i + k]; } for (k = ic; k < kc; k++) { to_buf[j + k] = 0; to_buf[j + k + kc] = 0; } } break; } } int mus_audio_write(int line, char *buf, int bytes) { OSStatus err = noErr; unsigned int lim, out_bytes; UInt32 sizeof_running; UInt32 running; char *to_buf; to_buf = bufs[in_buf]; out_bytes = (unsigned int)(bytes * conversion_multiplier); if ((fill_point + out_bytes) > bufsize) out_bytes = bufsize - fill_point; lim = (unsigned int)(out_bytes / conversion_multiplier); if (!writing) { convert_incoming(to_buf, fill_point, lim, buf); fill_point += out_bytes; if (fill_point >= bufsize) { in_buf++; fill_point = 0; if (in_buf == MAX_BUFS) { in_buf = 0; #if HAVE_AUDIODEVICEDESTROYIOPROCID err = AudioDeviceCreateIOProcID(device, (AudioDeviceIOProc)writer, NULL, &write_procId); #else err = AudioDeviceAddIOProc(device, (AudioDeviceIOProc)writer, NULL); #endif if (err == noErr) err = AudioDeviceStart(device, (AudioDeviceIOProc)writer); /* writer will be called right away */ if (err == noErr) { writing = true; return(MUS_NO_ERROR); } else return(MUS_ERROR); } } return(MUS_NO_ERROR); } if ((fill_point == 0) && (in_buf == out_buf)) { unsigned int bp; bp = out_buf; sizeof_running = sizeof(UInt32); while (bp == out_buf) { /* i.e. just kill time without hanging */ /* err = AudioDeviceGetProperty(device, 0, false, kAudioDevicePropertyDeviceIsRunning, &sizeof_running, &running); */ { AudioObjectPropertyAddress device_address = { kAudioDevicePropertyDeviceIsRunning, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster }; err = AudioObjectGetPropertyData(device, &device_address, 0, NULL, &sizeof_running, &running); } /* usleep(10); */ } } to_buf = bufs[in_buf]; if (fill_point == 0) memset((void *)to_buf, 0, bufsize); convert_incoming(to_buf, fill_point, lim, buf); fill_point += out_bytes; if (fill_point >= bufsize) { in_buf++; fill_point = 0; if (in_buf >= MAX_BUFS) in_buf = 0; } return(MUS_NO_ERROR); } int mus_audio_open_input(int dev, int srate, int chans, mus_sample_t samp_type, int size) { OSStatus err = noErr; UInt32 sizeof_device; UInt32 sizeof_bufsize; sizeof_device = sizeof(AudioDeviceID); sizeof_bufsize = sizeof(unsigned int); device = 0; /* err = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, &sizeof_device, (void *)(&device)); */ { AudioObjectPropertyAddress device_address = { kAudioHardwarePropertyDefaultInputDevice, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; err = AudioObjectGetPropertyData(kAudioObjectSystemObject, &device_address, 0, NULL, &sizeof_device, &device); } bufsize = 4096; if (err == noErr) { /* err = AudioDeviceGetProperty(device, 0, true, kAudioDevicePropertyBufferSize, &sizeof_bufsize, &bufsize); */ { AudioObjectPropertyAddress device_address = { kAudioDevicePropertyBufferSize, kAudioDevicePropertyScopeInput, kAudioObjectPropertyElementMaster }; err = AudioObjectGetPropertyData(device, &device_address, 0, NULL, &sizeof_bufsize, &bufsize); } } if (err != noErr) { fprintf(stderr, "open audio input err: %d %s\n", (int)err, osx_error(err)); return(MUS_ERROR); } open_for_input = true; /* assume for now that recorder (higher level) will enforce match */ if ((bufs == NULL) || (bufsize > current_bufsize)) { int i; if (bufs) { for (i = 0; i < MAX_BUFS; i++) free(bufs[i]); free(bufs); } bufs = (char **)calloc(MAX_BUFS, sizeof(char *)); for (i = 0; i < MAX_BUFS; i++) bufs[i] = (char *)calloc(bufsize, sizeof(char)); current_bufsize = bufsize; } in_buf = 0; out_buf = 0; fill_point = 0; incoming_out_srate = srate; incoming_out_chans = chans; #if HAVE_AUDIODEVICEDESTROYIOPROCID err = AudioDeviceCreateIOProcID(device, (AudioDeviceIOProc)reader, NULL, &read_procId); #else err = AudioDeviceAddIOProc(device, (AudioDeviceIOProc)reader, NULL); #endif if (err == noErr) err = AudioDeviceStart(device, (AudioDeviceIOProc)reader); if (err != noErr) { fprintf(stderr, "add open audio input err: %d %s\n", (int)err, osx_error(err)); return(MUS_ERROR); } return(MUS_NO_ERROR); } int mus_audio_read(int line, char *buf, int bytes) { OSStatus err = noErr; UInt32 sizeof_running; UInt32 running; char *to_buf; if (in_buf == out_buf) { unsigned int bp; bp = out_buf; sizeof_running = sizeof(UInt32); while (bp == out_buf) { /* err = AudioDeviceGetProperty(device, 0, true, kAudioDevicePropertyDeviceIsRunning, &sizeof_running, &running); */ { AudioObjectPropertyAddress device_address = { kAudioDevicePropertyDeviceIsRunning, kAudioDevicePropertyScopeInput, kAudioObjectPropertyElementMaster }; err = AudioObjectGetPropertyData(device, &device_address, 0, NULL, &sizeof_running, &running); } if (err != noErr) fprintf(stderr, "wait err: %s ", osx_error(err)); } } to_buf = bufs[in_buf]; if (bytes <= (int)bufsize) memmove((void *)buf, (void *)to_buf, bytes); else memmove((void *)buf, (void *)to_buf, bufsize); in_buf++; if (in_buf >= MAX_BUFS) in_buf = 0; return(MUS_ERROR); } int mus_audio_initialize(void) {return(MUS_NO_ERROR);} char *mus_audio_moniker(void) {return((char *)"Mac OSX audio");} #endif /* ------------------------------- JACK ----------------------------------------- */ /* Kjetil S. Matheussen. k.s.matheussen@notam02.no */ /* Based on code from ceres. */ #if MUS_JACK #define AUDIO_OK 1 #include #include #include #include #include #if MUS_LITTLE_ENDIAN # define MUS_COMP_SHORT MUS_LSHORT # define MUS_COMP_FLOAT MUS_LFLOAT #else # define MUS_COMP_SHORT MUS_BSHORT # define MUS_COMP_FLOAT MUS_BFLOAT #endif #define SRC_QUALITY SRC_SINC_BEST_QUALITY #if defined(__i386__) || defined(__x86_64) static inline void __attribute__ ((__unused__)) atomic_add(volatile int* __mem, int __val) { __asm__ __volatile__ ("lock; addl %1,%0" : "=m" (*__mem) : "ir" (__val), "m" (*__mem)); } #elif defined(__powerpc__) || defined(__ppc__) #ifdef __PPC405__ #define _STWCX "sync \n\tstwcx. " #else #define _STWCX "stwcx. " #endif static inline void __attribute__ ((__unused__)) atomic_add(volatile int* __mem, int __val) { int __tmp; __asm__ __volatile__ ( "/* Inline atomic add */\n" "0:\t" "lwarx %0,0,%2 \n\t" "add%I3 %0,%0,%3 \n\t" _STWCX " %0,0,%2 \n\t" "bne- 0b \n\t" "/* End atomic add */" : "=&b"(__tmp), "=m" (*__mem) : "r" (__mem), "Ir"(__val), "m" (*__mem) : "cr0"); } #else #error "Seems like an unsupported hardware for jack. Please contact k.s.matheussen@notam02.no" #endif /*************/ /* Jack Part */ /*************/ #define SNDJACK_BUFFERSIZE 32768 typedef jack_default_audio_sample_t sample_t; typedef jack_nframes_t nframes_t; struct SndjackChannel{ jack_port_t *port; sample_t *buffer; }; static jack_client_t *sndjack_client = NULL; /*************************/ /* Variables for reading */ /*************************/ static int sndjack_num_read_channels_allocated=0; static int sndjack_num_read_channels_inuse=0; static struct SndjackChannel *sndjack_read_channels=NULL; static pthread_cond_t sndjack_read_cond= PTHREAD_COND_INITIALIZER; static pthread_mutex_t sndjack_read_mutex= PTHREAD_MUTEX_INITIALIZER; static int sj_r_buffersize=0; static int sj_r_writeplace=0; static int sj_r_readplace=0; static int sj_r_unread=0; static int sj_r_xrun=0; static int sj_r_totalxrun=0; /*************************/ /* Variables for writing */ /*************************/ static pthread_cond_t sndjack_cond= PTHREAD_COND_INITIALIZER; static pthread_mutex_t sndjack_mutex= PTHREAD_MUTEX_INITIALIZER; enum{SJ_STOPPED,SJ_RUNNING,SJ_ABOUTTOSTOP}; // Variables for the ringbuffer: static int sj_writeplace=0; static int sj_readplace=0; static int sj_unread=0; static int sj_buffersize; static int sj_jackbuffersize; // number of frames sent to sndjack_process. static int sj_totalxrun=0; static int sj_xrun=0; static int sj_status=SJ_STOPPED; static int sndjack_num_channels_allocated=0; static int sndjack_num_channels_inuse=0; static struct SndjackChannel *sndjack_channels=NULL; static int sndjack_read_format; static SRC_STATE **sndjack_srcstates; static double sndjack_srcratio=1.0; static int jack_mus_watchdog_counter=0; #define SJ_MAX(a,b) (((a)>(b))?(a):(b)) static void sndjack_read_process(jack_nframes_t nframes){ int i,ch; sample_t *out[sndjack_num_channels_allocated]; if (sndjack_num_read_channels_inuse==0) return; for (ch=0;ch=2){ for (ch=2;ch=2){ for (ch=0;ch<2;ch++){ out[ch][i]=sndjack_channels[0].buffer[sj_readplace]; } }else{ for (ch=0;ch0){ sj_r_totalxrun+=sj_r_xrun; sj_r_xrun=0; return -1; } for (ch=0;ch0){ if (sj_status==SJ_RUNNING){ printf("Warning. %d frames delayed.\n",sj_xrun); sj_totalxrun+=sj_xrun; } sj_xrun=0; } for (i=0;i= SJ_MAX(sj_jackbuffersize*2, latencyframes)) ) { jack_mus_watchdog_counter++; pthread_cond_wait(&sndjack_cond,&sndjack_mutex); } for (ch=0;ch=sj_jackbuffersize) sj_status=SJ_RUNNING; } static int sndjack_buffersizecallback(jack_nframes_t nframes, void *arg){ sj_jackbuffersize=nframes; return 0; } static int sndjack_getnumoutchannels(void){ char *a=getenv("SNDLIB_NUM_JACK_CHANNELS"); if (a!=NULL){ int num_ch=atoi(a); return (num_ch<=0 || num_ch > 100000) ? 2 : num_ch; }else{ int lokke=0; const char **ports=jack_get_ports(sndjack_client,NULL,NULL,JackPortIsPhysical|JackPortIsInput); while(ports!=NULL && ports[lokke]!=NULL){ lokke++; } if (lokke<2) return 2; return lokke; } } static int sndjack_getnuminchannels(void){ char *a=getenv("SNDLIB_NUM_JACK_CHANNELS"); if (a!=NULL){ int num_ch=atoi(a); return (num_ch<=0 || num_ch > 100000) ? 2 : num_ch; }else{ int lokke=0; const char **ports=jack_get_ports(sndjack_client,NULL,NULL,JackPortIsPhysical|JackPortIsOutput); while(ports!=NULL && ports[lokke]!=NULL){ lokke++; } if (lokke<2) return 2; return lokke; } } static int sndjack_init(void){ int ch; int numch; int num=0; { jack_status_t status; sndjack_client=jack_client_open("sndlib",JackNoStartServer,&status,NULL); if (sndjack_client == NULL) { #if 0 fprintf (stderr, "jack_client_open() failed, " "status = 0x%2.0x\n", status); if (status & JackServerFailed) { fprintf (stderr, "Unable to connect to JACK server\n"); } #endif return -1; } } pthread_mutex_init(&sndjack_mutex,NULL); pthread_cond_init(&sndjack_cond,NULL); pthread_mutex_init(&sndjack_read_mutex,NULL); pthread_cond_init(&sndjack_read_cond,NULL); jack_set_process_callback(sndjack_client,sndjack_process,NULL); sndjack_num_channels_allocated = numch = sndjack_getnumoutchannels(); sndjack_num_read_channels_allocated = sndjack_getnuminchannels(); sndjack_channels=(struct SndjackChannel *)calloc(sizeof(struct SndjackChannel),numch); sndjack_read_channels=(struct SndjackChannel *)calloc(sizeof(struct SndjackChannel),sndjack_num_read_channels_allocated); for (ch=0;chSNDJACK_BUFFERSIZE) return -1; for (i=0;iSNDJACK_BUFFERSIZE) return -1; for (i=0;iSNDJACK_BUFFERSIZE) return -1; for (i=0;i0 && src_data.output_frames_gen!=outlen){ printf("Error, src_process did not output the same number of frames as previous resampled channel (%ld/%d).\n" "Please report this problem to k.s.matheussen@notam02.no. Thanks!\n",(long int)(src_data.output_frames_gen),outlen); return MUS_ERROR; } outlen=src_data.output_frames_gen; }else{ outlen=len; } } sndjack_write(sndjack_buffer,outlen,outlen*2,sndjack_num_channels_inuse); return MUS_NO_ERROR; } int jack_mus_audio_close(int line) { jack_mus_audio_set_non_realtime(); if (line==sndjack_dev){ sj_status=SJ_ABOUTTOSTOP; sndjack_num_channels_inuse=0; } return MUS_NO_ERROR; } int jack_mus_audio_open_input(int dev, int srate, int chans, mus_sample_t samp_type, int size){ if (sndjack_client==NULL){ if (jack_mus_audio_initialize()==MUS_ERROR) return MUS_ERROR; } if (sndjack_num_read_channels_allocated #define return_error_exit(Error_Type, Audio_Line, Ur_Error_Message) \ do { char *Error_Message; Error_Message = Ur_Error_Message; \ if (Audio_Line != -1) close(Audio_Line); \ if (Error_Message) \ {mus_standard_error(Error_Type, Error_Message); free(Error_Message);} \ else mus_standard_error(Error_Type, mus_error_type_to_string(Error_Type)); \ return(MUS_ERROR); \ } while (false) char *mus_audio_moniker(void) { return("HPUX audio"); } int mus_audio_open_output(int ur_dev, int srate, int chans, mus_sample_t samp_type, int size) { int fd, i, dev; struct audio_describe desc; dev = MUS_AUDIO_DEVICE(ur_dev); fd = open("/dev/audio", O_RDWR); if (fd == -1) return_error_exit(MUS_AUDIO_CANT_OPEN, -1, mus_format("can't open /dev/audio for output: %s", strerror(errno))); ioctl(fd, AUDIO_SET_CHANNELS, chans); if (dev == MUS_AUDIO_SPEAKERS) ioctl(fd, AUDIO_SET_OUTPUT, AUDIO_OUT_SPEAKER); else if (dev == MUS_AUDIO_LINE_OUT) ioctl(fd, AUDIO_SET_OUTPUT, AUDIO_OUT_LINE); else ioctl(fd, AUDIO_SET_OUTPUT, AUDIO_OUT_HEADPHONE); if (samp_type == MUS_BSHORT) ioctl(fd, AUDIO_SET_SAMPLE_TYPE, AUDIO_FORMAT_LINEAR16BIT); else { if (samp_type == MUS_MULAW) ioctl(fd, AUDIO_SET_SAMPLE_TYPE, AUDIO_FORMAT_ULAW); else { if (samp_type == MUS_ALAW) ioctl(fd, AUDIO_SET_SAMPLE_TYPE, AUDIO_FORMAT_ALAW); else return_error_exit(MUS_AUDIO_SAMPLE_TYPE_NOT_AVAILABLE, fd, mus_format("can't set output sample type to %d (%s) for %d", samp_type, mus_sample_type_to_string(samp_type), dev)); } } ioctl(fd, AUDIO_DESCRIBE, &desc); for (i = 0; i < desc.nrates; i++) if (srate == desc.sample_rate[i]) break; if (i == desc.nrates) return_error_exit(SRATE_NOT_AVAILABLE, fd, mus_format("can't set srate to %d on %d", srate, dev)); ioctl(fd, AUDIO_SET_SAMPLE_RATE, srate); return(fd); } int mus_audio_write(int line, char *buf, int bytes) { write(line, buf, bytes); return(MUS_NO_ERROR); } int mus_audio_close(int line) { close(line); return(MUS_NO_ERROR); } int mus_audio_initialize(void) { return(MUS_NO_ERROR); } /* struct audio_status status_b; * ioctl(devAudio, AUDIO_GET_STATUS, &status_b) * not_busy = (status_b.transmit_status == AUDIO_DONE); */ int mus_audio_open_input(int ur_dev, int srate, int chans, mus_sample_t samp_type, int size) { int fd, i, dev; struct audio_describe desc; dev = MUS_AUDIO_DEVICE(ur_dev); fd = open("/dev/audio", O_RDWR); if (fd == -1) return_error_exit(MUS_AUDIO_CANT_OPEN, NULL, mus_format("can't open /dev/audio for input: %s", strerror(errno))); ioctl(fd, AUDIO_SET_CHANNELS, chans); if (dev == MUS_AUDIO_MICROPHONE) ioctl(fd, AUDIO_SET_INPUT, AUDIO_IN_MIKE); else ioctl(fd, AUDIO_SET_INPUT, AUDIO_IN_LINE); if (samp_type == MUS_BSHORT) ioctl(fd, AUDIO_SET_SAMPLE_TYPE, AUDIO_FORMAT_LINEAR16BIT); else { if (samp_type == MUS_MULAW) ioctl(fd, AUDIO_SET_SAMPLE_TYPE, AUDIO_FORMAT_ULAW); else { if (samp_type == MUS_ALAW) ioctl(fd, AUDIO_SET_SAMPLE_TYPE, AUDIO_FORMAT_ALAW); else return_error_exit(MUS_AUDIO_SAMPLE_TYPE_NOT_AVAILABLE, fd, mus_format("can't set input sample type to %d (%s) on %d", samp_type, mus_sample_type_to_string(samp_type), dev)); } } ioctl(fd, AUDIO_DESCRIBE, &desc); for (i = 0; i < desc.nrates; i++) if (srate == desc.sample_rate[i]) break; if (i == desc.nrates) return_error_exit(MUS_AUDIO_SRATE_NOT_AVAILABLE, fd, mus_format("can't set srate to %d on %d", srate, dev)); ioctl(fd, AUDIO_SET_SAMPLE_RATE, srate); return(fd); } int mus_audio_read(int line, char *buf, int bytes) { read(line, buf, bytes); return(MUS_NO_ERROR); } #endif /* ------------------------------- NETBSD/OpenBSD ----------------------------------------- */ #if (__NetBSD__ || __OpenBSD__) && (!(defined(AUDIO_OK))) #define AUDIO_OK 1 /* started from Xanim a long time ago..., bugfixes from Thomas Klausner 30-Jul-05, worked into better shape Aug-05 */ #include #include #include #define return_error_exit(Error_Type, Audio_Line, Ur_Error_Message) \ do { char *Error_Message; Error_Message = Ur_Error_Message; \ if (Audio_Line != -1) close(Audio_Line); \ if (Error_Message) \ {mus_standard_error(Error_Type, Error_Message); free(Error_Message);} \ else mus_standard_error(Error_Type, mus_error_type_to_string(Error_Type)); \ return(MUS_ERROR); \ } while (false) static mus_sample_t bsd_format_to_sndlib(int encoding) { switch (encoding) { case AUDIO_ENCODING_ULAW: return(MUS_MULAW); break; case AUDIO_ENCODING_ALAW: return(MUS_ALAW); break; case AUDIO_ENCODING_LINEAR: return(MUS_BSHORT); break; /* "sun compatible" so probably big-endian? */ case AUDIO_ENCODING_SLINEAR: case AUDIO_ENCODING_LINEAR8: return(MUS_BYTE); break; case AUDIO_ENCODING_SLINEAR_LE: return(MUS_LSHORT); break; case AUDIO_ENCODING_SLINEAR_BE: return(MUS_BSHORT); break; case AUDIO_ENCODING_ULINEAR_LE: return(MUS_ULSHORT); break; case AUDIO_ENCODING_ULINEAR_BE: return(MUS_UBSHORT); break; case AUDIO_ENCODING_ULINEAR: return(MUS_UBYTE); break; case AUDIO_ENCODING_NONE: case AUDIO_ENCODING_ADPCM: default: return(MUS_UNKNOWN_SAMPLE); break; } return(MUS_UNKNOWN_SAMPLE); } static int sndlib_format_to_bsd(mus_sample_t encoding) { switch (encoding) { case MUS_MULAW: return(AUDIO_ENCODING_ULAW); break; case MUS_ALAW: return(AUDIO_ENCODING_ALAW); break; case MUS_BYTE: return(AUDIO_ENCODING_SLINEAR); break; case MUS_LSHORT: return(AUDIO_ENCODING_SLINEAR_LE); break; case MUS_BSHORT: return(AUDIO_ENCODING_SLINEAR_BE); break; case MUS_ULSHORT: return(AUDIO_ENCODING_ULINEAR_LE); break; case MUS_UBSHORT: return(AUDIO_ENCODING_ULINEAR_BE); break; case MUS_UBYTE: return(AUDIO_ENCODING_ULINEAR); break; default: break; } return(AUDIO_ENCODING_NONE); } int mus_audio_initialize(void) { return(MUS_NO_ERROR); } char *mus_audio_moniker(void) { #if __NetBSD__ return((char *)"NetBSD audio"); #else return((char *)"OpenBSD audio"); #endif } static int cur_chans = 1, cur_srate = 22050; int mus_audio_write(int line, char *buf, int bytes) { /* trouble... AUDIO_WSEEK always returns 0, no way to tell that I'm about to * hit "hiwat", but when I do, it hangs. Can't use AUDIO_DRAIN -- * it introduces interruptions. Not sure what to do... */ int b = 0; b = write(line, buf, bytes); usleep(10000); if ((b != bytes) && (b > 0)) /* b <= 0 presumably some sort of error, and we want to avoid infinite recursion below */ { /* hangs at close if we don't handle this somehow */ if ((cur_chans == 1) || (cur_srate == 22050)) sleep(1); else usleep(10000); mus_audio_write(line, (char *)(buf + b), bytes - b); } return(MUS_NO_ERROR); } int mus_audio_close(int line) { usleep(100000); ioctl(line, AUDIO_FLUSH, 0); close(line); return(MUS_NO_ERROR); } static int netbsd_default_outputs = (AUDIO_HEADPHONE | AUDIO_LINE_OUT | AUDIO_SPEAKER); int mus_audio_open_output(int dev, int srate, int chans, mus_sample_t samp_type, int size) { int line, encode; audio_info_t a_info; line = open("/dev/sound", O_WRONLY); /* /dev/audio assumes mono 8-bit mulaw */ if (line == -1) { if (errno == EBUSY) return(mus_error(MUS_AUDIO_CANT_OPEN, NULL)); else return(mus_error(MUS_AUDIO_DEVICE_NOT_AVAILABLE, NULL)); } AUDIO_INITINFO(&a_info); /* a_info.blocksize = size; */ encode = sndlib_format_to_bsd(samp_type); if (encode == AUDIO_ENCODING_NONE) return_error_exit(MUS_AUDIO_SAMPLE_TYPE_NOT_AVAILABLE, -1, mus_format("sample type %d (%s) not available", samp_type, mus_sample_type_name(samp_type))); a_info.play.encoding = encode; a_info.mode = AUMODE_PLAY | AUMODE_PLAY_ALL; a_info.play.precision = mus_bytes_per_sample(samp_type) * 8; a_info.play.sample_rate = srate; if (dev == MUS_AUDIO_LINE_OUT) a_info.play.port = AUDIO_LINE_OUT; else { if (dev == MUS_AUDIO_SPEAKERS) a_info.play.port = AUDIO_SPEAKER | (netbsd_default_outputs & AUDIO_HEADPHONE); else a_info.play.port = netbsd_default_outputs; } a_info.play.channels = chans; ioctl(line, AUDIO_SETINFO, &a_info); /* actually doesn't set the "ports" field -- always 0 */ ioctl(line, AUDIO_GETINFO, &a_info); if ((int)(a_info.play.sample_rate) != srate) mus_print("srate: %d -> %d\n", srate, a_info.play.sample_rate); if ((int)(a_info.play.encoding) != sndlib_format_to_bsd(samp_type)) mus_print("encoding: %d -> %d\n", sndlib_format_to_bsd(samp_type), a_info.play.encoding); if ((int)(a_info.play.channels) != chans) mus_print("chans: %d -> %d\n", chans, a_info.play.channels); cur_chans = chans; cur_srate = srate; return(line); } int mus_audio_read(int line, char *buf, int bytes) { read(line, buf, bytes); return(MUS_NO_ERROR); } static int netbsd_sample_types(int ur_dev, mus_sample_t *val) { int i, audio_fd, err, dev; audio_info_t info; audio_encoding_t e_info; dev = MUS_AUDIO_DEVICE(ur_dev); AUDIO_INITINFO(&info); audio_fd = open("/dev/sound", O_RDONLY | O_NONBLOCK, 0); if (audio_fd == -1) return_error_exit(MUS_AUDIO_CANT_READ, -1, mus_format("can't open /dev/sound: %s", strerror(errno))); err = ioctl(audio_fd, AUDIO_GETINFO, &info); if (err == -1) { close(audio_fd); return_error_exit(MUS_AUDIO_CANT_READ, audio_fd, mus_format("can't get dac info")); } for (i = 0; ; i++) { e_info.index = i; err = ioctl(audio_fd, AUDIO_GETENC, &e_info); if (err != 0) break; val[i + 1] = bsd_format_to_sndlib(e_info.encoding); } val[0] = (mus_sample_t)i; close(audio_fd); return(MUS_NO_ERROR); } int mus_audio_open_input(int ur_dev, int srate, int chans, mus_sample_t samp_type, int size) { audio_info_t info; int encode, bits, dev, audio_fd, err; dev = MUS_AUDIO_DEVICE(ur_dev); encode = sndlib_format_to_bsd(samp_type); bits = 8 * mus_bytes_per_sample(samp_type); if (encode == AUDIO_ENCODING_NONE) return_error_exit(MUS_AUDIO_SAMPLE_TYPE_NOT_AVAILABLE, -1, mus_format("sample type %s not available for recording", mus_sample_type_name(samp_type))); if (dev != MUS_AUDIO_DUPLEX_DEFAULT) audio_fd = open("/dev/sound", O_RDONLY, 0); else audio_fd = open("/dev/sound", O_RDWR, 0); if (audio_fd == -1) return_error_exit(MUS_AUDIO_CANT_OPEN, -1, mus_format("can't open /dev/sound: %s", strerror(errno))); AUDIO_INITINFO(&info); info.record.sample_rate = srate; info.record.channels = chans; info.record.precision = bits; info.record.encoding = encode; info.record.port = AUDIO_MICROPHONE; err = ioctl(audio_fd, AUDIO_SETINFO, &info); if (err == -1) return_error_exit(MUS_AUDIO_CANT_WRITE, audio_fd, mus_format("can't set up for recording")); return(audio_fd); } #endif /* -------------------------------- PULSEAUDIO -------------------------------- */ #if defined(MUS_PULSEAUDIO) && (!(defined(AUDIO_OK))) #define AUDIO_OK 1 /* this code compiles/loads, but I don't know if it works -- paplay itself * doesn't work on my machine due to either a libtool/dlopen mismatch * or some problem with "pulse-rt". */ #include #include #include static int sndlib_to_pa_format(mus_sample_t samp_type) { switch (samp_type) { case MUS_BYTE: return(PA_SAMPLE_U8); case MUS_LSHORT: return(PA_SAMPLE_S16LE); case MUS_BSHORT: return(PA_SAMPLE_S16BE); case MUS_LINT: return(PA_SAMPLE_S32LE); case MUS_BINT: return(PA_SAMPLE_S32BE); case MUS_LFLOAT: return(PA_SAMPLE_FLOAT32LE); case MUS_BFLOAT: return(PA_SAMPLE_FLOAT32BE); case MUS_ALAW: return(PA_SAMPLE_ALAW); case MUS_MULAW: return(PA_SAMPLE_ULAW); default: fprintf(stderr, "unsupported sample type: %d\n", samp_type); return(0); break; } } static pa_simple *pa_out = NULL, *pa_in = NULL; int mus_audio_open_output(int dev, int srate, int chans, mus_sample_t samp_type, int size) { pa_sample_spec *spec; int error; spec = (pa_sample_spec *)malloc(sizeof(pa_sample_spec)); spec->format = sndlib_to_pa_format(samp_type); spec->rate = srate; spec->channels = chans; pa_out = pa_simple_new(NULL, "snd", PA_STREAM_PLAYBACK, NULL, "playback", spec, NULL, NULL, &error); free(spec); if (!pa_out) { fprintf(stderr, "can't play: %s\n", pa_strerror(error)); return(MUS_ERROR); } return(0); } int mus_audio_open_input(int dev, int srate, int chans, mus_sample_t samp_type, int size) { return(MUS_ERROR); } int mus_audio_write(int line, char *buf, int bytes) { int error; pa_simple_write(pa_out, (unsigned char *)buf, (size_t)bytes, &error); } int mus_audio_close(int line) { int error; pa_simple_drain(pa_out, &error); pa_simple_free(pa_out); pa_out = NULL; } int mus_audio_read(int line, char *buf, int bytes) { return(MUS_ERROR); } int mus_audio_initialize(void) { return(MUS_ERROR); } char *mus_audio_moniker(void) { return(mus_format("pulseaudio %s", pa_get_library_version())); } #endif /* -------------------------------- PORTAUDIO -------------------------------- */ #if defined(MUS_PORTAUDIO) && (!(defined(AUDIO_OK))) #define AUDIO_OK 1 #include #define PA_OUT_STREAM 0 #define PA_IN_STREAM 1 static unsigned long sndlib_to_portaudio_format(mus_sample_t samp_type) { switch (samp_type) { case MUS_BYTE: return(paInt8); case MUS_LSHORT: return(paInt16); case MUS_BSHORT: return(paInt16); case MUS_LINT: return(paInt32); case MUS_BINT: return(paInt32); case MUS_LFLOAT: return(paFloat32); case MUS_BFLOAT: return(paFloat32); default: break; } return(paInt16); } static PaStream *out_stream = NULL; int mus_audio_open_output(int dev, int srate, int chans, mus_sample_t samp_type, int size) { PaStreamParameters output_pars; PaError err; output_pars.device = Pa_GetDefaultOutputDevice(); output_pars.channelCount = chans; output_pars.sampleFormat = sndlib_to_portaudio_format(samp_type); output_pars.suggestedLatency = Pa_GetDeviceInfo(output_pars.device)->defaultHighOutputLatency; output_pars.hostApiSpecificStreamInfo = NULL; err = Pa_OpenStream(&out_stream, NULL, &output_pars, srate, 1024, paClipOff, NULL, NULL); /* 1024 = frames [dac_size] but can we use "size"? */ if (err == paNoError) err = Pa_StartStream(out_stream); if (err != paNoError) { fprintf(stderr, "portaudio open output: %s\n", Pa_GetErrorText(err)); return(MUS_ERROR); } return(PA_OUT_STREAM); } static PaStream *in_stream = NULL; int mus_audio_open_input(int dev, int srate, int chans, mus_sample_t samp_type, int size) { PaStreamParameters input_pars; PaError err; input_pars.device = Pa_GetDefaultInputDevice(); input_pars.channelCount = chans; input_pars.sampleFormat = sndlib_to_portaudio_format(samp_type); input_pars.suggestedLatency = Pa_GetDeviceInfo(input_pars.device)->defaultHighInputLatency; input_pars.hostApiSpecificStreamInfo = NULL; err = Pa_OpenStream(&in_stream, &input_pars, NULL, srate, 1024, paClipOff, NULL, NULL); if (err == paNoError) err = Pa_StartStream(in_stream); if (err != paNoError) { fprintf(stderr, "portaudio open input: %s\n", Pa_GetErrorText(err)); return(MUS_ERROR); } return(MUS_NO_ERROR); } int mus_audio_write(int line, char *buf, int bytes) { PaError err; err = Pa_WriteStream(out_stream, buf, 1024); if (err != paNoError) { fprintf(stderr, "portaudio write: %s\n", Pa_GetErrorText(err)); return(MUS_ERROR); } return(MUS_NO_ERROR); } int mus_audio_close(int line) { PaError err; if (line == PA_IN_STREAM) err = Pa_CloseStream(in_stream); else err = Pa_CloseStream(out_stream); if (err != paNoError) { fprintf(stderr, "portaudio close: %s\n", Pa_GetErrorText(err)); return(MUS_ERROR); } return(MUS_NO_ERROR); } int mus_audio_read(int line, char *buf, int bytes) { PaError err; err = Pa_ReadStream(in_stream, buf, 1024); if (err != paNoError) { fprintf(stderr, "portaudio read: %s\n", Pa_GetErrorText(err)); return(MUS_ERROR); } return(MUS_NO_ERROR); } static bool portaudio_initialized = false; int mus_audio_initialize(void) { PaError err; if (portaudio_initialized) return(MUS_NO_ERROR); portaudio_initialized = true; err = Pa_Initialize(); if (err == paNoError) return(MUS_NO_ERROR); fprintf(stderr, "portaudio initialize: %s\n", Pa_GetErrorText(err)); return(MUS_ERROR); } char *mus_audio_moniker(void) { return((char *)Pa_GetVersionText()); } #endif /* ------------------------------- STUBS ----------------------------------------- */ #ifndef AUDIO_OK int mus_audio_open_output(int dev, int srate, int chans, mus_sample_t samp_type, int size) {return(MUS_ERROR);} int mus_audio_open_input(int dev, int srate, int chans, mus_sample_t samp_type, int size) {return(MUS_ERROR);} int mus_audio_write(int line, char *buf, int bytes) {return(MUS_ERROR);} int mus_audio_close(int line) {return(MUS_ERROR);} int mus_audio_read(int line, char *buf, int bytes) {return(MUS_ERROR);} int mus_audio_initialize(void) {return(MUS_ERROR);} char *mus_audio_moniker(void) {return((char *)"no audio support");} #endif /* for CLM */ void mus_reset_audio_c(void) { audio_initialized = false; version_name = NULL; } #if HAVE_ALSA || HAVE_OSS void mus_audio_alsa_channel_info(int dev, int *info); void mus_audio_alsa_channel_info(int dev, int *info) { #if MUS_JACK if (api == MUS_JACK_API) { info[0] = sndjack_num_channels_allocated; return; } #endif #if HAVE_ALSA if (api == MUS_ALSA_API) { alsa_chans(dev, info); return; } #endif #if HAVE_OSS info[0] = 2; #endif } int mus_audio_alsa_samples_per_channel(int dev); int mus_audio_alsa_samples_per_channel(int dev) { #if HAVE_ALSA return(alsa_samples_per_channel); #else return(1024); #endif } void mus_audio_alsa_device_list(int ur_dev, int chan, int *val); void mus_audio_alsa_device_list(int ur_dev, int chan, int *val) { #if HAVE_ALSA int i = 1; if (!audio_initialized) mus_audio_initialize(); if (alsa_hw_params[SND_PCM_STREAM_PLAYBACK]) val[i++] = to_sndlib_device(0, SND_PCM_STREAM_PLAYBACK); if (alsa_hw_params[SND_PCM_STREAM_CAPTURE]) val[i++] = to_sndlib_device(0, SND_PCM_STREAM_CAPTURE); val[0] = (i - 1); #endif } #define MUS_AUDIO_DIRECTION_PLAYBACK 0 #define MUS_AUDIO_DIRECTION_RECORD 1 int mus_audio_alsa_device_direction(int dev); int mus_audio_alsa_device_direction(int dev) { #if HAVE_OSS switch (MUS_AUDIO_DEVICE(dev)) { case MUS_AUDIO_DIGITAL_OUT: case MUS_AUDIO_LINE_OUT: case MUS_AUDIO_DEFAULT: case MUS_AUDIO_SPEAKERS: case MUS_AUDIO_MIXER: case MUS_AUDIO_AUX_OUTPUT: case MUS_AUDIO_DAC_OUT: return(MUS_AUDIO_DIRECTION_PLAYBACK); default: return(MUS_AUDIO_DIRECTION_RECORD); } #else { int card, device, alsa_device = 0; snd_pcm_stream_t alsa_stream = SND_PCM_STREAM_PLAYBACK; if ((!audio_initialized) && (mus_audio_initialize() != MUS_NO_ERROR)) return(MUS_ERROR); card = MUS_AUDIO_SYSTEM(dev); device = MUS_AUDIO_DEVICE(dev); to_alsa_device(device, &alsa_device, &alsa_stream); if (card > 0 || alsa_device > 0) return(alsa_mus_error(MUS_AUDIO_CANT_READ, NULL)); return(alsa_stream); } #endif } #endif int mus_audio_device_channels(int dev) { #if MUS_JACK if (api == MUS_JACK_API) { return(sndjack_num_channels_allocated); } #endif #if HAVE_ALSA if (api == MUS_ALSA_API) { return(alsa_chans(dev, NULL)); } #endif return(2); /* netbsd hpux sun mac and oss with quibbles */ } mus_sample_t mus_audio_compatible_sample_type(int dev) /* snd-dac and sndplay */ { #if HAVE_ALSA if (api == MUS_ALSA_API) { int err; mus_sample_t ival[32]; err = alsa_sample_types(dev, 32, ival); if (err != MUS_ERROR) { int i; for (i = 1; i <= (int)(ival[0]); i++) if (ival[i] == MUS_AUDIO_COMPATIBLE_SAMPLE_TYPE) return(MUS_AUDIO_COMPATIBLE_SAMPLE_TYPE); for (i = 1; i <= (int)(ival[0]); i++) if ((ival[i] == MUS_BINT) || (ival[i] == MUS_LINT) || (ival[i] == MUS_BFLOAT) || (ival[i] == MUS_LFLOAT) || (ival[i] == MUS_BSHORT) || (ival[i] == MUS_LSHORT)) return(ival[i]); for (i = 1; i <= (int)(ival[0]); i++) if ((ival[i] == MUS_MULAW) || (ival[i] == MUS_ALAW) || (ival[i] == MUS_UBYTE) || (ival[i] == MUS_BYTE)) return(ival[i]); return(ival[1]); } } #endif #if MUS_JACK if (api == MUS_JACK_API) return(MUS_COMP_FLOAT); #endif return(MUS_AUDIO_COMPATIBLE_SAMPLE_TYPE); } static mus_sample_t look_for_sample_type (mus_sample_t *mixer_vals, mus_sample_t samp_type) { int i, lim; lim = mixer_vals[0]; for (i = 1; i <= lim; i++) if (mixer_vals[i] == samp_type) return(samp_type); return(MUS_UNKNOWN_SAMPLE); } mus_sample_t mus_audio_device_sample_type(int dev) /* snd-dac */ { mus_sample_t mixer_vals[16]; mus_sample_t samp_type; /* we return the new sample type, so mixer_vals is just a local collector of possible sample types */ mixer_vals[0] = MUS_UNKNOWN_SAMPLE; #if (!WITH_AUDIO) return(MUS_AUDIO_COMPATIBLE_SAMPLE_TYPE); #endif #if HAVE_OSS if (api == MUS_OSS_API) oss_sample_types(dev, mixer_vals); #endif #if HAVE_ALSA if (api == MUS_ALSA_API) alsa_sample_types(dev, 16, mixer_vals); #endif #if MUS_JACK if (api == MUS_JACK_API) { mixer_vals[0] = (mus_sample_t)1; mixer_vals[1] = MUS_COMP_FLOAT; } #endif #if HAVE_SUN mixer_vals[0] = (mus_sample_t)2; mixer_vals[1] = MUS_LSHORT; mixer_vals[2] = MUS_MULAW; #endif #if __APPLE__ mixer_vals[0] = (mus_sample_t)1; #if MUS_LITTLE_ENDIAN mixer_vals[1] = MUS_LFLOAT; #else mixer_vals[1] = MUS_BFLOAT; #endif #endif #if __NetBSD__ || __OpenBSD__ netbsd_sample_types(dev, mixer_vals); #endif samp_type = look_for_sample_type(mixer_vals, MUS_AUDIO_COMPATIBLE_SAMPLE_TYPE); if (samp_type != MUS_UNKNOWN_SAMPLE) return(samp_type); #if MUS_LITTLE_ENDIAN samp_type = look_for_sample_type(mixer_vals, MUS_LFLOAT); if (samp_type == MUS_UNKNOWN_SAMPLE) { samp_type = look_for_sample_type(mixer_vals, MUS_LSHORT); if (samp_type == MUS_UNKNOWN_SAMPLE) samp_type = mixer_vals[1]; } #else samp_type = look_for_sample_type(mixer_vals, MUS_BFLOAT); if (samp_type == MUS_UNKNOWN_SAMPLE) { samp_type = look_for_sample_type(mixer_vals, MUS_BSHORT); if (samp_type == MUS_UNKNOWN_SAMPLE) samp_type = mixer_vals[1]; } #endif return(samp_type); } #else /* not WITH_AUDIO */ int mus_audio_open_output(int dev, int srate, int chans, mus_sample_t samp_type, int size) {return(-1);} int mus_audio_open_input(int dev, int srate, int chans, mus_sample_t samp_type, int size) {return(-1);} int mus_audio_write(int line, char *buf, int bytes) {return(-1);} int mus_audio_close(int line) {return(-1);} int mus_audio_read(int line, char *buf, int bytes) {return(-1);} int mus_audio_initialize(void) {return(-1);} char *mus_audio_moniker(void) {return((char *)"no audio support");} void mus_reset_audio_c(void) {} int mus_audio_device_channels(int dev) {return(0);} mus_sample_t mus_audio_compatible_sample_type(int dev) {return(MUS_UNKNOWN_SAMPLE);} mus_sample_t mus_audio_device_sample_type(int dev) {return(MUS_UNKNOWN_SAMPLE);} #if __APPLE__ bool mus_audio_output_properties_mutable(bool mut) {return(false);} #endif #endif snd-16.1/cload.scm0000644000076400007640000006171012615773031012133 0ustar bilbil(provide 'cload.scm) ;;; -------------------------------------------------------------------------------- ;;; automatically link a C function into s7 (there are a bunch of examples below) ;;; (c-define '(double j0 (double)) "m" "math.h") ;;; means link the name m:j0 to the math library function j0 passing a double arg and getting a double result (reals in s7) ;;; ;;; (c-define c-info prefix headers cflags ldflags) ;;; prefix is some arbitrary prefix (it can be "") that you want prepended to various names. ;;; headers is a list of headers (as strings) that the c-info relies on, (("math.h") for example). ;;; cflags are any special C compiler flags that are needed ("-I." in particular). ;;; ldflags is the similar case for the loader. ;;; c-info is a list that describes the C entities that you want to tie into s7. ;;; it can be either one list describing one entity, or a list of such lists. ;;; Each description has the form: (return-type entity-name-in-C (argument-type...)) ;;; where each entry is a symbol, and C names are used throughout. So, in the j0 ;;; example above, (double j0 (double)) says we want access to j0, it returns ;;; a C double, and takes one argument, also a C double. s7 tries to figure out ;;; what the corresponding s7 type is, but in tricky cases, you should tell it ;;; by replacing the bare type name with a list: (C-type underlying-C-type). For example, ;;; the Snd function set_graph_style takes an (enum) argument of type graph_style_t. ;;; This is actually an int, so we use (graph_style_t int) as the type: ;;; (void set_graph_style ((graph_style_t int))) ;;; If the C entity is a constant, then the descriptor list has just two entries, ;;; the C-type and the entity name: (int F_OK) for example. The entity name can also be a list ;;; (an enum listing for example). ;;; If the C type has a space ("struct tm*" for example), use (symbol "struct tm*") ;;; to construct the corresponding symbol. ;;; The entity is placed in the current s7 environment under the name (string-append prefix ":" name) ;;; where the ":" is omitted if the prefix is null. So in the j0 example, we get in s7 the function m:j0. ;;; ;;; some examples: ;;; ;;; (c-define '((double j0 (double)) ;;; (double j1 (double)) ;;; (double erf (double)) ;;; (double erfc (double)) ;;; (double lgamma (double))) ;;; "m" "math.h") ;;; ;;; ;;; (c-define '(char* getenv (char*))) ;;; (c-define '(int setenv (char* char* int))) ;;; (define get-environment-variable (let () (c-define '(char* getenv (char*))) getenv)) ;;; ;;; (define file-exists? (let () (c-define '((int F_OK) (int access (char* int))) "" "unistd.h") (lambda (arg) (= (access arg F_OK) 0)))) ;;; (define delete-file (let () (c-define '(int unlink (char*)) "" "unistd.h") (lambda (file) (= (unlink file) 0)))) ; 0=success, -1=failure ;;; ;;; ;;; these pick up Snd stuff: ;;; (c-define '(char* version_info ()) "" "snd.h" "-I.") ;;; (c-define '(mus_float_t mus_degrees_to_radians (mus_float_t)) "" "snd.h" "-I.") ;;; ;;; (c-define '(snd_info* any_selected_sound ()) "" "snd.h" "-I.") ;;; (c-define '(void select_channel (snd_info* int)) "" "snd.h" "-I.") ;;; (c-define '(((graph_style_t int) (GRAPH_LINES GRAPH_DOTS GRAPH_FILLED GRAPH_DOTS_AND_LINES GRAPH_LOLLIPOPS)) ;;; (void set_graph_style ((graph_style_t int)))) ;;; "" "snd.h" "-I.") ;;; ;;; ;;; (c-define '(char* getcwd (char* size_t)) "" "unistd.h") ;;; :(let ((str (make-string 32))) (getcwd str 32) str) ;;; "/home/bil/cl\x00 " ;;; so it works in a sense -- there is a memory leak here ;;; ;;; ;;; (c-define (list '(void* calloc (size_t size_t)) ;;; '(void* malloc (size_t)) ;;; '(void free (void*)) ;;; '(void* realloc(void* size_t)) ;;; '(void time (time_t*)) ; ignore returned value ;;; (list (symbol "struct tm*") 'localtime '(time_t*)) ;;; (list 'size_t 'strftime (list 'char* 'size_t 'char* (symbol "struct tm*")))) ;;; "" "time.h") ;;; > (let ((p (calloc 1 8)) (str (make-string 32))) (time p) (strftime str 32 "%a %d-%b-%Y %H:%M %Z" (localtime p)) (free p) str) ;;; "Sat 11-Aug-2012 08:55 PDT\x00 " ;;; ;;; ;;; (c-define '((int closedir (DIR*)) ;;; (DIR* opendir (char*)) ;;; (in-C "static char *read_dir(DIR *p) \ ;;; { \ ;;; struct dirent *dirp; \ ;;; dirp = readdir(p); \ ;;; if (!dirp) return(NULL); \ ;;; else return(dirp->d_name); \ ;;; }") ;;; (char* read_dir (DIR*))) ;;; "" '("sys/types.h" "dirent.h")) ;;; ;;; (let ((dir (opendir "/home/bil/gtk-snd"))) ;;; (do ((p (read_dir dir) (read_dir dir))) ;;; ((= (length p) 0)) ;;; (format *stderr* "~A " p)) ;;; (closedir dir)) ;;; ;;; (define (memory-usage) ;;; (with-let *libc* ;;; (let ((v (rusage.make))) ;;; (getrusage RUSAGE_SELF v) ;;; (let ((mem (rusage.ru_maxrss v))) ;;; (free v) ;;; (* 1024 mem))))) ;;; -------------------------------------------------------------------------------- (define *cload-cflags* "") (define *cload-ldflags* "") (define-macro (defvar name value) `(if (not (defined? ',name)) (define ,name ,value))) (defvar c-define-output-file-counter 0) ; ugly, but I can't find a way around this (dlopen/dlsym stupidity) ;;; to place the new function in the caller's current environment, we need to pass the environment in explicitly: (define-macro (c-define . args) `(c-define-1 (curlet) ,@args)) (define* (c-define-1 cur-env function-info (prefix "") (headers ()) (cflags "") (ldflags "") output-name) ;; write a C shared library module that links in the functions in function-info ;; function info is either a list: (return-type c-name arg-type) or a list thereof ;; the new functions are placed in cur-env (define collides? (let ((all-names ())) (lambda (name) (if (member name all-names eq?) (format *stderr* "~A twice?~%" name) (set! all-names (cons name all-names))) name))) (define handlers (list '(integer s7_is_integer s7_integer s7_make_integer s7_int) '(boolean s7_is_boolean s7_boolean s7_make_boolean bool) '(real s7_is_real s7_number_to_real s7_make_real s7_double) ;; '(complex s7_is_complex #f s7_make_complex s7_Complex) ;; the typedef is around line 6116 in s7.c, but we also need s7_complex which requires the s7_Complex type ;; xen.h uses (s7_real_part(a) + s7_imag_part(a) * _Complex_I) instead since c++ won't let use define s7_Complex in s7.h '(string s7_is_string s7_string s7_make_string char*) (list 'character 's7_is_character 's7_character 's7_make_character (symbol "unsigned char")) '(c_pointer s7_is_c_pointer s7_c_pointer s7_make_c_pointer void*) '(s7_pointer #f #f #f s7_pointer) )) (define (find-handler handle choice) (let ((found (assoc handle handlers eq?))) (if (pair? found) (choice found) #t))) (define (C-type->s7-type type) (if (pair? type) ; in case the type name does not make its C type obvious: (graph_style_t int) (symbol->string (cadr type)) (let ((type-name (symbol->string type))) (cond ((string-position "**" type-name) ; any complicated C pointer is uninterpreted 'c_pointer) ((string=? "s7_pointer" type-name) 's7_pointer) ((string-position "char*" type-name) ; but not char** (caught above) 'string) ((or (string-position "*" type-name) ; float* etc (string-position "pointer" type-name)) 'c_pointer) ((string-position "char" type-name) 'character) ((string-position "bool" type-name) 'boolean) ;; ((string-position "complex" type-name) ;; 'complex) ; double complex or complex double (mus_edot_product in clm.c uses the latter) ((or (string-position "float" type-name) (string-position "double" type-name)) 'real) ((or (string-position "int" type-name) (string-position "long" type-name) ; assuming not "long double" here so we need to look for it first (above) (string-position "short" type-name) (string-position "size" type-name) (string-position "byte" type-name)) 'integer) (#t #t))))) (define (C->s7-cast type) (find-handler (C-type->s7-type type) (lambda (p) (car (cddddr p))))) (define (C->s7 type) (find-handler (C-type->s7-type type) cadddr)) (define (s7->C type) (find-handler (C-type->s7-type type) caddr)) (define (checker type) (find-handler (C-type->s7-type type) cadr)) (define* (cload->signature type (rtn #f)) (case (C-type->s7-type type) ((real) (if rtn 'float? 'real?)) ((integer) 'integer?) ((string) 'string?) ((boolean) 'boolean?) ((character) 'char?) ((c_pointer) 'c-pointer?) (else #t))) (define (signature->pl type) (case type ((integer?) #\i) ((boolean?) #\b) ((real?) #\r) ((float?) #\d) ((char?) #\c) ((string?) #\s) ((c-pointer?) #\x) (else #\t))) (set! c-define-output-file-counter (+ c-define-output-file-counter 1)) (let* ((file-name (or output-name (format "temp-s7-output-~D" c-define-output-file-counter))) (c-file-name (string-append file-name ".c")) (o-file-name (string-append file-name ".o")) (so-file-name (string-append file-name ".so")) (init-name (if output-name (string-append output-name "_init") (string-append "init_" (number->string c-define-output-file-counter)))) (functions ()) (constants ()) (macros ()) ; these are protected by #ifdef ... #endif (inits ()) ; C code (a string in s7) inserted in the library initialization function (p #f) (if-funcs ()) ; if-functions (guaranteed to return int, so we can optimize away make-integer etc) (rf-funcs ()) ; rf-functions (sig-symbols (list (cons 'integer? 0) (cons 'boolean? 0) (cons 'real? 0) (cons 'float? 0) (cons 'char? 0) (cons 'string? 0) (cons 'c-pointer? 0) (cons 't 0))) (signatures (make-hash-table))) (define (make-signature rtn args) (define (compress sig) (if (and (pair? sig) (pair? (cdr sig)) (eq? (car sig) (cadr sig))) (compress (cdr sig)) sig)) (let ((sig (list (cload->signature rtn #t))) (cyclic #f)) (for-each (lambda (arg) (set! sig (cons (cload->signature arg) sig))) args) (let ((len (length sig))) (set! sig (compress sig)) (set! cyclic (not (= len (length sig))))) (set! sig (reverse sig)) (when (not (signatures sig)) ; it's not in our collection yet (let ((pl (make-string (+ (if cyclic 4 3) (length sig)))) (loc (if cyclic 4 3))) (set! (pl 0) #\p) (if cyclic (begin (set! (pl 1) #\c) (set! (pl 2) #\l) (set! (pl 3) #\_)) (begin (set! (pl 1) #\l) (set! (pl 2) #\_))) (for-each (lambda (typer) (set! (pl loc) (signature->pl typer)) (let ((count (or (assoc typer sig-symbols eq?) (assoc 't sig-symbols eq?)))) (set-cdr! count (+ (cdr count) 1))) (set! loc (+ loc 1))) sig) (set! (signatures sig) pl))) sig)) (define (initialize-c-file) ;; C header stuff (set! p (open-output-file c-file-name)) (format p "#include ~%") (format p "#include ~%") (format p "#include ~%") (if (string? headers) (format p "#include <~A>~%" headers) (for-each (lambda (header) (format p "#include <~A>~%" header)) headers)) (format p "#include \"s7.h\"~%~%")) (define* (add-one-function return-type name arg-types doc) ;; (format *stderr* "~A ~A ~A~%" return-type name arg-types): double j0 (double) for example ;; C function -> scheme (let* ((func-name (symbol->string (collides? name))) (num-args (length arg-types)) (base-name (string-append (if (> (length prefix) 0) prefix "s7_dl") "_" func-name)) ; not "g" -- collides with glib (scheme-name (string-append prefix (if (> (length prefix) 0) ":" "") func-name))) (if (and (= num-args 1) (eq? (car arg-types) 'void)) (set! num-args 0)) (format p "~%/* -------- ~A -------- */~%" func-name) (format p "static s7_pointer ~A(s7_scheme *sc, s7_pointer args)~%" base-name) (format p "{~%") ;; get the Scheme args, check their types, assign to local C variables (if (positive? num-args) (begin (format p " s7_pointer arg;~%") (do ((i 0 (+ i 1)) (type arg-types (cdr type))) ((= i num-args)) (format p " ~A ~A_~D;~%" (if (pair? (car type)) (caar type) (car type)) base-name i)) (format p " arg = args;~%") (do ((i 0 (+ i 1)) (type arg-types (cdr type))) ((= i num-args)) (let* ((nominal-type (if (pair? (car type)) (caar type) (car type))) ; double in the example (true-type (if (pair? (car type)) (cadar type) (car type))) (s7-type (C-type->s7-type true-type))) ; real (if (eq? true-type 's7_pointer) (format p " ~A_~D = s7_car(arg);~%" base-name i) (begin (format p " if (~A(s7_car(arg)))~%" (checker true-type)) (format p " ~A_~D = (~A)~A(~As7_car(arg));~%" base-name i nominal-type (s7->C true-type) ; s7_number_to_real which requires (if (member s7-type '(boolean real) eq?) ; the extra sc arg "sc, " "")) (format p " else return(s7_wrong_type_arg_error(sc, ~S, ~D, s7_car(arg), ~S));~%" func-name (if (= num-args 1) 0 (+ i 1)) (if (symbol? s7-type) (symbol->string s7-type) (error 'bad-arg (format #f "in ~S, ~S is not a symbol~%" name s7-type)))))) (if (< i (- num-args 1)) (format p " arg = s7_cdr(arg);~%")))))) ;; return C value to Scheme (if (pair? return-type) (set! return-type (cadr return-type))) (let ((return-translator (C->s7 return-type))) (format p " ") (if (not (eq? return-translator #t)) (format p "return(")) (if (symbol? return-translator) (format p "~A(sc, (~A)" return-translator (C->s7-cast return-type))) (format p "~A(" func-name) (do ((i 0 (+ i 1))) ((>= i (- num-args 1))) (format p "~A_~D, " base-name i)) (if (positive? num-args) (format p "~A_~D" base-name (- num-args 1))) (format p ")") (if (symbol? return-translator) (format p ")")) (if (not (eq? return-translator #t)) (format p ");~%") (format p ";~% return(s7_unspecified(sc));~%")) (format p "}~%")) ;; add optimizer connection (when (and (eq? return-type 'double) ; double (f double) -- s7_rf_t: double f(s7, s7_pointer **p) (eq? (car arg-types) 'double) (or (= num-args 1) (and (= num-args 2) ; double (f double double) (eq? (cadr arg-types) 'double)))) (set! rf-funcs (cons (cons func-name scheme-name) rf-funcs)) (if (= num-args 1) (format p "static s7_double ~A_rf_r(s7_scheme *sc, s7_pointer **p)~ {s7_rf_t f; s7_double x; f = (s7_rf_t)(**p); (*p)++; x = f(sc, p); return(~A(x));}~%" func-name func-name) (format p "static s7_double ~A_rf_r(s7_scheme *sc, s7_pointer **p)~% ~ {s7_rf_t f; s7_double x, y; f = (s7_rf_t)(**p); (*p)++; x = f(sc, p); f = (s7_rf_t)(**p); (*p)++; y = f(sc, p); return(~A(x, y));}~%" func-name func-name)) (format p "static s7_rf_t ~A_rf(s7_scheme *sc, s7_pointer expr) ~ {if (s7_arg_to_rf(sc, s7_cadr(expr))) return(~A_rf_r); return(NULL);}~%" func-name func-name)) (when (and (eq? return-type 'int) ; int (f int|double|void) (member (car arg-types) '(int double void) eq?) (<= num-args 1)) (set! if-funcs (cons (cons func-name scheme-name) if-funcs)) (case (car arg-types) ((double) (format p "static s7_int ~A_if_r(s7_scheme *sc, s7_pointer **p)~ {s7_rf_t f; s7_double x; f = (s7_rf_t)(**p); (*p)++; x = f(sc, p); return(~A(x));}~%" func-name func-name) (format p "static s7_if_t ~A_if(s7_scheme *sc, s7_pointer expr) ~ {if (s7_arg_to_if(sc, s7_cadr(expr))) return(~A_if_r); return(NULL);}~%" func-name func-name)) ((int) (format p "static s7_int ~A_if_i(s7_scheme *sc, s7_pointer **p)~ {s7_if_t f; s7_int x; f = (s7_if_t)(**p); (*p)++; x = f(sc, p); return(~A(x));}~%" func-name func-name) (format p "static s7_if_t ~A_if(s7_scheme *sc, s7_pointer expr) ~ {if (s7_arg_to_if(sc, s7_cadr(expr))) return(~A_if_i); return(NULL);}~%" func-name func-name)) ((void) (format p "static s7_int ~A_if_i(s7_scheme *sc, s7_pointer **p) {return(~A());}~%" func-name func-name) (format p "static s7_if_t ~A_if(s7_scheme *sc, s7_pointer expr) {return(~A_if_i);}~%" func-name func-name)))) (format p "~%") (set! functions (cons (list scheme-name base-name (if (and (string? doc) (> (length doc) 0)) doc (format #f "~A ~A~A" return-type func-name arg-types)) num-args 0 (make-signature return-type arg-types)) functions)))) (define (add-one-constant type name) ;; C constant -> scheme (let ((c-type (if (pair? type) (cadr type) type))) (if (symbol? name) (set! constants (cons (list c-type (symbol->string (collides? name))) constants)) (for-each (lambda (c) (set! constants (cons (list c-type (symbol->string (collides? c))) constants))) name)))) (define (add-one-macro type name) ;; C macro (with definition check) -> scheme (let ((c-type (if (pair? type) (cadr type) type))) (if (symbol? name) (set! macros (cons (list c-type (symbol->string (collides? name))) macros)) (for-each (lambda (c) (set! macros (cons (list c-type (symbol->string (collides? c))) macros))) name)))) (define (end-c-file) ;; now the init function ;; the new scheme variables and functions are placed in the current environment (format p "void ~A(s7_scheme *sc);~%" init-name) (format p "void ~A(s7_scheme *sc)~%" init-name) (format p "{~%") (format p " s7_pointer cur_env;~%") (format p " s7_pointer ") (let ((pls (hash-table-entries signatures)) (loc 1)) (for-each (lambda (s) (format p "~A~A~A" (cdr s) (if (< loc pls) "," ";") (if (< loc pls) " " #\newline)) (set! loc (+ loc 1))) signatures)) (let ((syms ()) (names ())) (for-each (lambda (q) (when (positive? (cdr q)) (set! syms (cons (car q) syms)) (set! names (cons (signature->pl (car q)) names)))) sig-symbols) (when (pair? syms) (format p " {~% s7_pointer ~{~C~^, ~};~%" names) (for-each (lambda (name sym) (if (eq? sym 't) (format p " t = s7_t(sc);~%") (format p " ~C = s7_make_symbol(sc, ~S);~%" name (symbol->string sym)))) names syms)) (format p "~%") (for-each (lambda (sig) (let ((cyclic (char=? ((cdr sig) 1) #\c))) (if cyclic (format p " ~A = s7_make_circular_signature(sc, ~D, ~D" (cdr sig) (- (length (car sig)) 1) (length (car sig))) (format p " ~A = s7_make_signature(sc, ~D" (cdr sig) (length (car sig)))) (format p "~{~^, ~C~}" (substring (cdr sig) (if cyclic 4 3))) (format p ");~%"))) signatures) (format p " }~%~%")) (format p " cur_env = s7_outlet(sc, s7_curlet(sc));~%") ; this must exist because we pass load the env ourselves ;; send out any special initialization code (for-each (lambda (init-str) (format p " ~A~%" init-str)) (reverse inits)) ;; "constants" -- actually variables in s7 because we want them to be local to the current environment (if (pair? constants) (begin (format p "~%") (for-each (lambda (c) (let* ((type (c 0)) (c-name (c 1)) (scheme-name (string-append prefix (if (> (length prefix) 0) ":" "") c-name))) (format p " s7_define(sc, cur_env, s7_make_symbol(sc, ~S), ~A(sc, (~A)~A));~%" scheme-name (C->s7 type) (C->s7-cast type) c-name))) constants))) ;; C macros -- need #ifdef name #endif wrapper (if (pair? macros) (begin (format p "~%") (for-each (lambda (c) (let* ((type (c 0)) (c-name (c 1)) (scheme-name (string-append prefix (if (> (length prefix) 0) ":" "") c-name))) (format p "#ifdef ~A~%" c-name) (format p " s7_define(sc, cur_env, s7_make_symbol(sc, ~S), ~A(sc, (~A)~A));~%" scheme-name (C->s7 type) (C->s7-cast type) c-name) (format p "#endif~%"))) macros))) ;; functions (for-each (lambda (f) (let ((scheme-name (f 0)) (base-name (f 1)) (help (f 2)) (num-args (f 3)) (opt-args (if (> (length f) 4) (f 4) 0)) (sig (and (> (length f) 5) (f 5)))) (format p "~% s7_define(sc, cur_env,~% s7_make_symbol(sc, ~S),~%" scheme-name) (format p " s7_make_typed_function(sc, ~S, ~A, ~D, ~D, false, ~S, ~A));~%" scheme-name base-name num-args opt-args help (if (pair? sig) (signatures sig) 'NULL)))) functions) ;; optimizer connection (when (pair? rf-funcs) (format p "~% /* rf optimizer connections */~%") (for-each (lambda (f) (format p " s7_rf_set_function(s7_name_to_value(sc, ~S), ~A_rf);~%" (cdr f) (car f))) rf-funcs)) (when (pair? if-funcs) (format p "~% /* if optimizer connections */~%") (for-each (lambda (f) (format p " s7_if_set_function(s7_name_to_value(sc, ~S), ~A_if);~%" (cdr f) (car f))) if-funcs)) (format p "}~%") (close-output-port p) ;; now we have the module .c file -- make it into a shared object, load it, delete the temp files (if (provided? 'osx) (begin ;; I assume the caller is also compiled with these flags? (system (format #f "gcc -c ~A ~A" c-file-name (string-append *cload-cflags* " " cflags))) (system (format #f "gcc ~A -o ~A -dynamic -bundle -undefined suppress -flat_namespace ~A" o-file-name so-file-name (string-append *cload-ldflags* " " ldflags)))) (if (provided? 'freebsd) (begin (system (format #f "cc -fPIC -c ~A ~A" c-file-name (string-append *cload-cflags* " " cflags))) (system (format #f "cc ~A -shared -o ~A ~A" o-file-name so-file-name (string-append *cload-ldflags* " " ldflags)))) (if (provided? 'openbsd) (begin (system (format #f "cc -fPIC -ftrampolines -c ~A ~A" c-file-name (string-append *cload-cflags* " " cflags))) (system (format #f "cc ~A -shared -o ~A ~A" o-file-name so-file-name (string-append *cload-ldflags* " " ldflags)))) (begin (system (format #f "gcc -fPIC -c ~A ~A" c-file-name (string-append *cload-cflags* " " cflags))) (system (format #f "gcc ~A -shared -o ~A ~A" o-file-name so-file-name (string-append *cload-ldflags* " " ldflags)))))))) (define (check-doc func-data) (let ((doc (caddr func-data))) (if (and (string? doc) (> (length doc) 0)) func-data (append (list (car func-data) (cadr func-data) (car func-data)) (cdddr func-data))))) (define (handle-declaration func) ;; functions (if (>= (length func) 3) (apply add-one-function func) (case (car func) ((in-C) (format p "~A~%" (cadr func))) ((C-init) (set! inits (cons (cadr func) inits))) ((C-macro) (apply add-one-macro (cadr func))) ((C-function) (collides? (caadr func)) (set! functions (cons (check-doc (cadr func)) functions))) (else (apply add-one-constant func))))) ;; this is the body of c-define (if (or (not output-name) (not (file-exists? c-file-name)) (not (file-exists? so-file-name)) (not (provided? 'system-extras)) (< (file-mtime so-file-name) (file-mtime c-file-name)) ; they are equal on my linux system (and (file-exists? (port-filename (current-input-port))) ; we're actually loading a file (< (file-mtime so-file-name) (file-mtime (port-filename (current-input-port)))))) (begin (format *stderr* "writing ~A~%" c-file-name) ;; write a new C file and compile it (initialize-c-file) (if (and (pair? (cdr function-info)) (symbol? (cadr function-info))) (handle-declaration function-info) (for-each handle-declaration function-info)) (end-c-file) (delete-file o-file-name))) ;; load the object file, clean up (let ((new-env (sublet cur-env 'init_func (string->symbol init-name)))) (format *stderr* "loading ~A~%" so-file-name) (load so-file-name new-env)))) ;;; backwards compatibility (define define-c-function c-define) #| (let ((cd (symbol "complex double")) (cd* (symbol "complex double *"))) (c-define (list cd 'mus_edot_product (list cd cd* 'int)))) ;complex double mus_edot_product(complex double freq, complex double *data, mus_long_t size) |# snd-16.1/clm23.scm0000644000076400007640000026170112617635310011772 0ustar bilbil;;; these are CLM test instruments (provide 'snd-clm23.scm) (if (provided? 'snd) (require snd-ws.scm) (require sndlib-ws.scm)) (require snd-dsp.scm snd-jcrev.scm) ;;; definstrument -> define* (+ change open paren placement) ;;; *srate* -> *clm-srate* ;;; run loop ... -> (do...) ;;; aref -> [float-vector-ref or vector-ref use implicit indexing] ;;; setf -> set! ;;; remove declare ;;; double not needed ;;; array of gen -> vector (and setf aref to vector-set! in this case) ;;; nil -> #f, t -> #t ;;; incf, decf to explicit sets ;;; length sometimes length, vector-length etc ;;; make-filter in scm requires coeffs arrays ;;; &optional, &key -> define* ;;; two-pi -> (* 2 pi) ;;; open-input and close-input -> make-readin or use name directly (in make-readin) ;;; make-locsig channel arg is in a different place ;;; progn -> begin, dotimes -> do ;;; string= -> string=? (also string-equal) ;;; integerp -> integer? and others like it (null -> null? is the tricky one) ;;; sound-duration -> mus-sound-duration and similarly for others ;;; various array info procs like array-dimension ;;; #'(lambda ...) to just (lambda...), and if possible move the lambda out of the args ;;; nth -> list-ref ;;; loop -> do (define (clm23-sine-bank amps phases len) (let ((sum 0.0)) (do ((i 0 (+ 1 i))) ((= i len)) (set! sum (+ sum (* (amps i) (sin (phases i)))))) sum)) (define open-input make-file->sample) (define two-pi (* 2 pi)) (define (simple-out beg dur freq amp) (let ((os (make-oscil freq)) (start (seconds->samples beg)) (end (seconds->samples (+ beg dur)))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (oscil os)))))) (definstrument (simple-fm beg dur freq amp mc-ratio index amp-env index-env) (let ((fm-index (hz->radians (* index mc-ratio freq)))) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (cr (make-oscil freq)) ; our carrier (md (make-oscil (* freq mc-ratio))) ; our modulator (ampf (make-env (or amp-env '(0 0 .5 1 1 0)) :scaler amp :duration dur)) (indf (make-env (or index-env '(0 0 .5 1 1 0)) :scaler fm-index :duration dur))) (do ((i start (+ i 1))) ((= i end)) (outa i (* (env ampf) (oscil cr (* (env indf) (oscil md))))))))) (define (simple-outn beg dur freq ampa ampb ampc ampd reva revb) (let ((os (make-oscil freq)) (start (seconds->samples beg)) (end (seconds->samples (+ beg dur)))) (do ((i start (+ i 1))) ((= i end)) (let ((val (oscil os))) (if (> ampa 0.0) (outa i (* ampa val))) (if (> ampb 0.0) (outb i (* ampb val))) (if (> ampc 0.0) (outc i (* ampc val))) (if (> ampd 0.0) (outd i (* ampd val))) (if (> reva 0.0) (outa i (* reva val) *reverb*)) (if (> revb 0.0) (outb i (* revb val) *reverb*)))))) (define (simple-ssb beg dur freq amp) (let ((os (make-ssb-am freq)) (start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (arr (make-vector 3))) (set! (arr 0) os) (set! (arr 1) #f) (set! (arr 2) (make-ssb-am 660 40)) (do ((k 0 (+ k 1))) ((= k (length arr))) (let ((g (arr k))) (if (ssb-am? g) (do ((i start (+ i 1))) ((= i end)) (outa i (ssb-am g amp)))))))) (define (simple-multiarr beg dur freq amp) ;; this won't work in CL because that version of CLM assumes all aref gens are the same type (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (arr (make-vector 3))) (set! (arr 0) (make-oscil freq)) (set! (arr 1) (make-env '(0 0 1 1) :scaler amp :duration dur)) (set! (arr 2) (make-oscil (* freq 2))) (do ((i start (+ i 1))) ((= i end)) (outa i (* (env (vector-ref arr 1)) (oscil (arr 0) (* .1 (oscil (arr 2))))))))) (define (simple-nsin beg dur amp) (let ((os (make-nsin 440 10)) (start (seconds->samples beg)) (end (seconds->samples (+ beg dur)))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (nsin os)))))) (define (simple-ncos beg dur freq amp) (let ((os (make-ncos freq 10)) (start (seconds->samples beg)) (end (seconds->samples (+ beg dur)))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (ncos os)))))) (define (simple-nrxysin beg dur amp) (let ((os (make-nrxysin 440 1.0 10)) (start (seconds->samples beg)) (end (seconds->samples (+ beg dur)))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (nrxysin os)))))) (define (simple-nrxycos beg dur freq amp) (let ((os (make-nrxycos freq 1.0 10)) (start (seconds->samples beg)) (end (seconds->samples (+ beg dur)))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (nrxycos os)))))) (define (simple-osc beg dur freq amp) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (freqs (make-float-vector 20))) (let ((obank (make-oscil-bank freqs (let ((fv (make-float-vector 20 0.0))) (do ((i 0 (+ i 1))) ((= i 20) fv) (set! (freqs i) (hz->radians (* (+ i 1) 100))))) (make-float-vector 20 1.0) #t))) (set! amp (* 0.05 amp)) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (oscil-bank obank))))))) (define (simple-asy beg dur amp) (let ((os (make-asymmetric-fm 440.0)) (start (seconds->samples beg)) (end (seconds->samples (+ beg dur)))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (asymmetric-fm os 1.0)))))) (define (simple-saw beg dur amp) (let ((os (make-sawtooth-wave 440.0 amp)) (start (seconds->samples beg)) (end (seconds->samples (+ beg dur)))) (do ((i start (+ i 1))) ((= i end)) (outa i (sawtooth-wave os))))) (define (simple-sqr beg dur amp) (let ((os (make-square-wave 440.0 amp)) (start (seconds->samples beg)) (end (seconds->samples (+ beg dur)))) (do ((i start (+ i 1))) ((= i end)) (outa i (square-wave os))))) (define (simple-tri beg dur amp) (let ((os (make-triangle-wave 440.0 amp)) (start (seconds->samples beg)) (end (seconds->samples (+ beg dur)))) (do ((i start (+ i 1))) ((= i end)) (outa i (triangle-wave os))))) (define (simple-pul beg dur amp) (let ((os (make-pulse-train 440.0 amp)) (start (seconds->samples beg)) (end (seconds->samples (+ beg dur)))) (do ((i start (+ i 1))) ((= i end)) (outa i (pulse-train os))))) (define (simple-oz beg dur freq amp) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (os (make-oscil freq)) (oz (make-one-zero (* amp 0.4) (* amp 0.6)))) (do ((i start (+ i 1))) ((= i end)) (outa i (one-zero oz (oscil os)))))) (define (simple-op beg dur freq amp) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (os (make-oscil freq)) (oz (make-one-pole (* amp 0.4) -0.6))) (do ((i start (+ i 1))) ((= i end)) (outa i (one-pole oz (oscil os)))))) (define (simple-tz beg dur freq amp) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (os (make-oscil freq)) (oz (make-two-zero (* amp 0.4) (* amp 0.3) (* amp 0.3)))) (do ((i start (+ i 1))) ((= i end)) (outa i (two-zero oz (oscil os)))))) (define (simple-tp beg dur freq amp) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (os (make-oscil freq)) (oz (make-two-pole (* amp 0.3) -0.6 0.1))) (do ((i start (+ i 1))) ((= i end)) (outa i (two-pole oz (oscil os)))))) (define (simple-frm beg dur freq amp) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (os (make-oscil freq)) (oz (make-formant 1200.0 0.95))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (formant oz (oscil os))))))) (define (simple-firm beg dur freq amp) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (os (make-oscil freq)) (oz (make-firmant 1200.0 0.95))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (firmant oz (oscil os))))))) (define (simple-firm2 beg dur freq amp) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (os (make-oscil freq)) (frqf (make-env '(0 1200 1 2400) :scaler (hz->radians 1.0) :duration dur)) (oz (make-firmant 1200.0 0.95))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (firmant oz (oscil os) (env frqf))))))) ;(define w1 (make-polyshape :frequency 100.0 ; :partials (let ((frqs ())) ; (do ((i 1 (+ i 1))) ; ((= i 10) (begin (format #t frqs) (reverse frqs))) ; (set! frqs (cons (/ 1.0 (* i i)) (cons i frqs))))))) (define (simple-poly beg dur freq amp) (let ((w1 (make-polyshape freq :partials '(1 1 2 1 3 1))) (start (seconds->samples beg)) (end (seconds->samples (+ beg dur)))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (polyshape w1 1.0)))))) (define (simple-polyw beg dur freq amp) (let ((w1 (make-polywave freq :partials (list 1 amp 2 amp 3 amp))) (start (seconds->samples beg)) (end (seconds->samples (+ beg dur)))) (do ((i start (+ i 1))) ((= i end)) (outa i (polywave w1))))) (define (simple-dly beg dur freq amp) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (os (make-oscil freq)) (buf (make-delay 100))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (delay buf (oscil os))))))) (define (simple-cmb beg dur freq amp) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (os (make-oscil freq)) (buf (make-comb .1 100))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (comb buf (oscil os))))))) (define (simple-filtered-cmb beg dur freq amp) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (os (make-oscil freq)) (buf (make-filtered-comb .1 100 :filter (make-one-zero .5 .5)))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (filtered-comb buf (oscil os))))))) (define (simple-not beg dur freq amp) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (os (make-oscil freq)) (buf (make-notch .1 100))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (notch buf (oscil os))))))) (define (simple-alp beg dur freq amp) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (os (make-oscil freq)) (buf (make-all-pass .2 .8 100))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (all-pass buf (oscil os))))))) (define (simple-ave beg dur freq amp) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (os (make-oscil freq)) (buf (make-moving-average 10))) (set! (mus-increment buf) (* amp (mus-increment buf))) (do ((i start (+ i 1))) ((= i end)) (outa i (moving-average buf (oscil os)))))) (define (simple-tab beg dur freq amp) (let ((table-size 256)) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (buf (make-table-lookup freq 0.0 :size table-size))) (let ((table (mus-data buf))) (do ((i 0 (+ i 1))) ((= i table-size)) (set! (table i) (/ i table-size)))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (table-lookup buf))))))) (define (simple-flt beg dur freq amp) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (flt (make-filter 8 :xcoeffs (make-float-vector 8) :ycoeffs (make-float-vector 8))) (os (make-oscil freq))) (do ((i 0 (+ i 1))) ((= i 8)) (set! ((mus-xcoeffs flt) i) (/ i 16.0)) (set! ((mus-ycoeffs flt) i) (- 0.5 (/ i 16.0)))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (filter flt (oscil os))))))) (define (simple-fir beg dur freq amp) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (flt (make-fir-filter 8 :xcoeffs (make-float-vector 8))) (os (make-oscil freq))) (do ((i 0 (+ i 1))) ((= i 8)) (set! ((mus-xcoeffs flt) i) (/ i 16.0))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (fir-filter flt (oscil os))))))) (define (simple-iir beg dur freq amp) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (flt (make-iir-filter 8 :ycoeffs (make-float-vector 8))) (os (make-oscil freq))) (do ((i 0 (+ i 1))) ((= i 8)) (set! ((mus-ycoeffs flt) i) (/ i 16.0))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (iir-filter flt (oscil os))))))) (define (simple-ran beg dur freq amp) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (os (make-rand freq amp))) (do ((i start (+ i 1))) ((= i end)) (outa i (rand os))))) (define (simple-ri beg dur freq amp) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (os (make-rand-interp freq amp))) (do ((i start (+ i 1))) ((= i end)) (outa i (rand-interp os))))) (define (simple-rndist beg dur freq amp) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (os (make-rand freq amp :distribution (inverse-integrate '(0 0 1 1))))) (do ((i start (+ i 1))) ((= i end)) (outa i (rand os))))) (define (simple-ridist beg dur freq amp) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (os (make-rand-interp freq amp :distribution (inverse-integrate '(0 1 1 0))))) (do ((i start (+ i 1))) ((= i end)) (outa i (rand-interp os))))) (define (simple-env beg dur freq amp) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (os (make-oscil freq)) (e (make-env '(0 0 1 1 2 1 3 0) :scaler amp :offset .1 :duration dur))) (do ((i start (+ i 1))) ((= i end)) (outa i (* (env e) (oscil os)))))) (define* (simple-fof beg dur frq amp vib f0 a0 f1 a1 f2 a2 ve ae) (let ((foflen (if (= *clm-srate* 22050) 100 200))) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (ampf (make-env :envelope (or ae (list 0 0 25 1 75 1 100 0)) :scaler amp :duration dur)) (frq0 (hz->radians f0)) (frq1 (hz->radians f1)) (frq2 (hz->radians f2)) (vibr (make-oscil 6)) (vibenv (make-env :envelope (or ve (list 0 1 100 1)) :scaler vib :duration dur)) (win-freq (/ two-pi foflen)) (wt0 (make-wave-train :size foflen :frequency frq))) (let ((foftab (mus-data wt0))) (do ((i 0 (+ i 1))) ((= i foflen)) (set! (foftab i) ;; this is not the pulse shape used by B&R (* (+ (* a0 (sin (* i frq0))) (* a1 (sin (* i frq1))) (* a2 (sin (* i frq2)))) .5 (- 1.0 (cos (* i win-freq))))))) (do ((i start (+ i 1))) ((= i end)) (outa i (* (env ampf) (wave-train wt0 (* (env vibenv) (oscil vibr))))))))) (define (simple-amb beg dur freq amp) (let ((os (if (> freq 1) (make-oscil freq) (make-rand freq))) (start (seconds->samples beg)) (end (seconds->samples (+ beg dur)))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (os)))))) (define (simple-rd beg dur amp file) (let ((rd (make-readin file)) (start (seconds->samples beg)) (end (seconds->samples (+ beg dur)))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (readin rd)))))) (define (simple-rd-start beg dur amp file channel start) (let ((rd (make-readin file :channel channel :start start)) (start (seconds->samples beg)) (end (seconds->samples (+ beg dur)))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (readin rd)))))) (define (simple-cnv beg dur amp file) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (filt (make-float-vector 8))) (set! (filt 4) 1.0) (let ((ff (make-convolve :input (make-readin file) :filter filt))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (convolve ff))))))) (define (simple-cnf beg dur amp file) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (filt (make-float-vector 8))) (set! (filt 4) 1.0) (let ((ff (make-convolve (make-readin file) :filter filt))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (convolve ff))))))) (define (simple-lrg beg dur amp file) (let ((rd (make-readin file))) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (read-func (lambda (dir) (readin rd))) (filt (make-float-vector 8))) (set! (filt 4) 1.0) (let ((ff (make-convolve :filter filt :input read-func))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (convolve ff)))))))) (define (simple-cn2 beg dur amp file) (let ((rd (make-readin file))) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (read-func (lambda (dir) (readin rd))) (filt (make-float-vector 8))) (set! (filt 4) 1.0) (let ((ff (make-convolve :filter filt :input read-func)) (ff1 (make-convolve :filter filt :input (make-readin file)))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (+ (convolve ff) (convolve ff1))))))))) (define (simple-src beg dur amp speed file) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (sr (make-src :input (make-readin file) :srate speed))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (src sr)))))) (define (simple-src-f beg dur amp speed file) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (sr (make-src :input (make-readin file) :srate speed))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (src sr 0.0)))))) (define (simple-sr2 beg dur amp speed file) (let ((rd (make-readin file))) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (sr (make-src :srate speed :input (lambda (dir) (readin rd))))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (src sr))))))) (define (simple-sr2a beg dur amp speed file) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (sr (make-src :input (make-readin file) :srate speed))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (src sr)))))) (define (simple-sro beg dur amp speed freq) (let ((os (make-oscil freq))) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (sr (make-src :srate speed :input (lambda (dir) (oscil os))))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (src sr))))))) (define (simple-grn beg dur amp speed freq) (let ((os (make-oscil freq))) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (sr (make-granulate :expansion speed :input (lambda (dir) (oscil os))))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (granulate sr))))))) (define (simple-pvoc beg dur amp size file) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (sr (make-phase-vocoder :input (make-readin file) :fft-size size))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (phase-vocoder sr)))))) ;;; (with-sound (:statistics #t) (simple-pvoc 0 2.0 .4 256 "oboe.snd")) (define (simple-ina beg dur amp file) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (fil (open-input file))) (do ((i start (+ i 1)) (ctr 0 (+ ctr 1))) ((= i end)) (outa i (* amp (in-any ctr 0 fil)))))) (define (simple-in-rev beg dur ampa ampb) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (chns (mus-channels *reverb*))) (if (or (> ampa 0.0) (> ampb 0.0)) (if (or (zero? ampb) (= chns 1)) (do ((i start (+ i 1))) ((= i end)) (outa i (* ampa (ina i *reverb*)))) (do ((i start (+ i 1))) ((= i end)) (outa i (* ampa (ina i *reverb*))) (outb i (* ampb (inb i *reverb*)))))))) (define (simple-f2s beg dur amp file) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (fil (make-file->sample file))) (do ((i start (+ i 1)) (ctr 0 (+ ctr 1))) ((= i end)) (outa i (* amp (file->sample fil ctr)))))) (define (simple-rdf beg dur amp file) (let ((rd (make-readin file)) (start (seconds->samples beg)) (end (seconds->samples (+ beg dur)))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (readin rd)))))) (define (simple-loc beg dur freq amp) (let ((os (make-oscil freq)) (loc (make-locsig :degree 0.0)) (start (seconds->samples beg)) (end (seconds->samples (+ beg dur)))) (do ((i start (+ i 1))) ((= i end)) (locsig loc i (* amp (oscil os)))))) (define (simple-dloc beg dur freq amp) (let ((os (make-oscil freq)) (start (seconds->samples beg)) (end (seconds->samples (+ beg dur)))) (let ((loc (make-move-sound (list start end 1 0 (make-delay 32) (make-env '(0 0 1 1) :length 1000) (make-env '(0 0 1 1) :length 1000) (vector (make-delay 32)) (vector (make-env '(0 0 1 1) :length 1000)) (vector (make-delay 32)) (vector 0 1))))) (do ((i start (+ i 1))) ((= i end)) (move-sound loc i (* amp (oscil os))))))) (define (simple-dloc-4 beg dur freq amp) (let ((os (make-oscil freq)) (start (seconds->samples beg)) (end (seconds->samples (+ beg dur)))) (let ((loc (make-move-sound (list start end 4 0 (make-delay 12) (make-env '(0 0 10 1) :duration dur) #f (make-vector 4 #f) (vector (make-env '(0 0 1 1 2 0 3 0 4 0) :duration dur) (make-env '(0 0 1 0 2 1 3 0 4 0) :duration dur) (make-env '(0 0 1 0 2 0 3 1 4 0) :duration dur) (make-env '(0 0 1 0 2 0 3 0 4 1) :duration dur)) #f (vector 0 1 2 3))))) (do ((i start (+ i 1))) ((= i end)) (move-sound loc i (* amp (oscil os))))))) ;(with-sound (:channels 4 :output "temp.snd") (simple-dloc-4 0 2 440 .5)) (define (simple-dup beg dur freq amp) (let ((os (make-oscil freq)) (j 2) (start (seconds->samples beg)) (end (seconds->samples (+ beg dur)))) (do ((i start (+ i 1))) ((= i end)) (let ((amp .3) (j 4)) (if (not (= j 4)) (format #t "local j is ~D\n" j)) (if (> (abs (- amp .3)) .001) (format #t "local amp is ~F\n" amp))) (if (= j 2) (outa i (* amp (oscil os))))))) (define (simple-du1 beg dur freq amp) (let ((os (make-oscil freq)) (j (+ (expt 2 41) 1234)) ; 2199023256786 (mj -3) (jj (- (+ (expt 2 40) 4321))) ; -1099511632097 (start (seconds->samples beg)) (end (seconds->samples (+ beg dur)))) (do ((i start (+ i 1))) ((= i end)) (if (not (= j 2199023256786)) (format #t "local j is ~A" j)) (if (not (= jj -1099511632097)) (format #t "local jj is ~A" jj)) (if (= mj -3) (outa i (* amp (oscil os))) (format #t "minus 3: ~D" mj))))) (define (sample-desc beg dur freq amp) (let ((os (make-oscil freq)) (start (seconds->samples beg)) (printed #f) (end (seconds->samples (+ beg dur)))) (do ((i start (+ i 1))) ((= i end)) (if (not printed) (begin (if (not (string=? (mus-describe os) "oscil freq: 440.000Hz, phase: 0.000")) (format #t "describe oscil: ~A~%" (mus-describe os))) (if (> (abs (- (mus-frequency os) freq)) .001) (format #t "osc freq: ~A (~A)~%" (mus-frequency os) freq)) (set! printed #t))) (outa i (* amp (oscil os)))))) (define (sample-mdat beg dur freq amp) (let ((table-size 256)) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (buf (make-table-lookup freq 0.0 :size table-size))) (let ((table (mus-data buf))) (do ((i 0 (+ i 1))) ((= i table-size)) (set! (table i) (/ i table-size)))) (do ((i start (+ i 1)) (j 0 (modulo (+ j 1) table-size))) ((= i end)) (outa i (* amp ((mus-data buf) j) (table-lookup buf))))))) (define (sample-xtab beg dur freq amp) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (flt (make-filter 8 :xcoeffs (make-float-vector 8) :ycoeffs (make-float-vector 8))) (os (make-oscil freq))) (do ((i 0 (+ i 1))) ((= i 8)) (set! ((mus-xcoeffs flt) i) (/ i 16.0)) (set! ((mus-ycoeffs flt) i) (- 0.5 (/ i 16.0)))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (+ ((mus-xcoeffs flt) 4) ((mus-ycoeffs flt) 4)) (filter flt (oscil os))))))) (define (sample-xts beg dur freq amp) (let ((vx (make-float-vector 8)) (vy (make-float-vector 8))) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (flt (make-filter 8 :xcoeffs vx :ycoeffs vy)) (os (make-oscil freq))) (do ((i 0 (+ i 1))) ((= i 8)) (set! ((mus-xcoeffs flt) i) (/ i 16.0)) (set! ((mus-ycoeffs flt) i) (- 0.5 (/ i 16.0)))) (do ((i start (+ i 1))) ((= i end)) (float-vector-set! vx 0 .5) (float-vector-set! vy 0 .5) (outa i (* amp (+ (vx 0) (mus-ycoeff flt 0)) (filter flt (oscil os)))))))) (define (sample-srl2 beg dur amp speed freq) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (os1 (make-oscil freq)) (os2 (make-oscil (* freq 2)))) (let ((sr1 (make-src :srate speed :input (lambda (dir) (oscil os1)))) (sr2 (make-src :srate speed :input (lambda (dir) (oscil os2))))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (+ (src sr1) (src sr2)))))))) (define (sample-srll beg dur amp speed freq) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (os (make-oscil freq))) (let ((sr2 (make-src :srate speed :input (lambda (dir) (oscil os))))) (let ((sr1 (make-src :srate speed :input (lambda (dir) (src sr2))))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (src sr1)))))))) (define (sample-srl3 beg dur amp speed freq) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (os1 (make-oscil freq)) (os2 (make-oscil freq))) (let ((sr3 (make-src :srate speed :input (lambda (dir) (oscil os2)))) (sr2 (make-src :srate speed :input (lambda (dir) (oscil os1))))) (let ((sr1 (make-src :srate speed :input (lambda (dir) (src sr2))))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (+ (src sr1) (src sr3))))))))) (define (sample-grn2 beg dur amp speed freq) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (os (make-oscil freq))) (let ((sr (make-granulate :expansion speed :input (lambda (dir) (oscil os)) :edit (lambda (g) 0)))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (granulate sr))))))) (define (sample-grn3 beg dur amp speed file) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (sr (make-src (make-readin file) :srate speed))) (let ((gr (make-granulate :expansion speed :input (lambda (dir) (src sr))))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (granulate gr))))))) (define (sample-cnv beg dur amp speed file) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (sr (make-src (make-readin file) :srate speed)) (filt (make-float-vector 8))) (set! (filt 4) 1.0) (let ((ff (make-convolve :filter filt :input (lambda (dir) (src sr))))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (convolve ff))))))) (define (sample-cnv1 beg dur amp speed file) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (sr (make-src :srate speed :input (make-readin file))) (filt (make-float-vector 8))) (set! (filt 4) 1.0) (let ((ff (make-convolve :filter filt :input (lambda (dir) (src sr))))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (convolve ff))))))) (define (sample-pvoc1 beg dur amp size file) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (sr (make-phase-vocoder (make-readin file) :fft-size size))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (phase-vocoder sr)))))) (define (sample-pvoc2 beg dur amp size file) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (sr (make-phase-vocoder (make-readin file) :fft-size size :edit (lambda (pv) (if (not (= (mus-location pv) 0)) (format #t "outctr: ~A" (mus-location pv))) #t)))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (phase-vocoder sr)))))) (define (sample-pvoc3 beg dur amp size file) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (N2 (/ size 2)) (amps #f) (paincrs #f) (ppincrs #f) (phases #f) (freqs #f)) (let ((sr (make-phase-vocoder (make-readin file) :fft-size size :synthesize (lambda (pv) (float-vector-add! amps paincrs) (float-vector-add! ppincrs freqs) (float-vector-add! phases ppincrs) (clm23-sine-bank amps phases N2))))) (set! amps (phase-vocoder-amps sr)) (set! paincrs (phase-vocoder-amp-increments sr)) (set! ppincrs (phase-vocoder-phase-increments sr)) (set! phases (phase-vocoder-phases sr)) (set! freqs (phase-vocoder-freqs sr)) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (phase-vocoder sr))))))) (define (sample-osc beg dur freq amp) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (arr (make-vector 20)) (arrfrq (make-float-vector 20))) (set! amp (* amp 0.05)) (do ((i 0 (+ i 1))) ((= i 20)) (set! (arrfrq i) (* (+ i 1) 100.0)) (set! (arr i) (make-oscil (* (+ i 1) 100)))) (do ((i 0 (+ i 1))) ((= i 20)) (let ((g (arr i)) (frq (arrfrq i))) (if (oscil? g) (begin (set! (mus-frequency g) frq) (if (> (abs (- (mus-frequency g) frq)) .001) (format #t "oops ~A ~A" (mus-frequency g) frq)) (do ((k start (+ k 1))) ((= k end)) (outa k (* amp (oscil g)))))))))) (define (sample-ardcl beg dur freq amp) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (amps (make-float-vector 3)) (phases (make-float-vector 3)) (freqs (make-float-vector 3)) (ints (make-vector 3 32))) (do ((i 0 (+ i 1))) ((= i 3)) (set! (freqs i) (hz->radians (* freq (+ i 1)))) (set! (amps i) (/ amp (+ i 2)))) (do ((i start (+ i 1))) ((= i end)) (do ((i 0 (+ i 1))) ((= i (length phases))) (set! (phases i) (+ (phases i) (freqs i)))) (if (not (= (ints 0) 32)) (format #t "int array trouble")) (set! (ints 1) 3) (if (not (= (ints 1) 3)) (format #t "set int array trouble")) (if (not (= (length amps) 3)) (format #t "amps len: ~A" (length amps))) (outa i (clm23-sine-bank amps phases 3))))) (define (sample-flt beg dur freq amp) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (fltdat (make-float-vector 3 3.14)) (intdat (make-vector 3 3)) (flt (make-filter 8 :xcoeffs (make-float-vector 8) :ycoeffs (make-float-vector 8))) (os (make-oscil freq))) (do ((i 0 (+ i 1))) ((= i 8)) (set! ((mus-xcoeffs flt) i) (/ i 16.0)) (set! ((mus-ycoeffs flt) i) (- 0.5 (/ i 16.0)))) (do ((i start (+ i 1))) ((= i end)) (let ((xs (mus-xcoeffs flt))) (if (or (> (abs (- (xs 1) (mus-xcoeff flt 1))) .001) (> (abs (- (xs 1) 0.0625)) .001)) (format #t "~A ~A~%" (xs 1) (mus-xcoeff flt 1)))) (let ((data (mus-data flt))) (if (> (data 0) 1.0) (format #t "data overflow? ~A~%" (data 0)))) (let ((is intdat) (fs fltdat)) (if (not (= (is 1) 3)) (format #t "intdat let: ~A~%" (is 1))) (if (> (abs (- (fs 1) 3.14)) .001) (format #t "fltdat let: ~A~%" (fs 1)))) (outa i (* amp (filter flt (oscil os))))))) (define (sample-arrintp beg dur freq amp) (let ((len (seconds->samples dur))) (let ((os (make-oscil freq)) (arr (make-float-vector 101)) (start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (loc-incr (/ 100.0 len))) (do ((i 0 (+ i 1)) (x 0.0 (+ x .01))) ((= i 100)) (set! (arr i) x)) (do ((i start (+ i 1)) (loc 0.0 (+ loc loc-incr))) ((= i end)) (outa i (* amp (array-interp arr loc) (oscil os))))))) (define (sample-if beg dur freq amp) (let ((os (make-oscil freq)) (start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (k -123) (j 0) (bool #t)) (do ((i start (+ i 1))) ((= i end)) (if (and (= i start) (not (= k -123))) (format #t "init k: ~A~%" k)) (if (not bool) (format #t "bool: ~A~%" bool)) (set! j (if bool 1 2)) (if (not (= j 1)) (format #t "if expr: ~A~%" j)) (if bool (set! j 3) (set! j 4)) (if (not (= j 3)) (format #t "if statement: ~A~%" j)) (if (integer? k) (set! j 5)) (if (not (= j 5)) (format #t "int k? ~A ~A~%" (integer? k) j)) (if (= j k) (set! j 6)) (if (= j 6) (format #t "j if false: ~A~%" j)) (set! j (if (= j k) (+ k 7) (+ k 8))) (if (not (= j (+ k 8))) (format #t "if false expr: ~A ~A~%" j k)) (set! j (if (> j -1234) (if (> k -1234) 9 10) 11)) (if (not (= j 9)) (format #t "if 2 expr: ~A~%" j)) (set! j (if (> j -1234) (begin (set! k 0) 12) 13)) (if (not (= j 12)) (format #t "if begin expr: ~A~%" j)) (if (> j -1234) (begin (set! j 1234) (set! j 14)) (set! j 15)) (if (not (= j 14)) (format #t "if begin: ~A~%" j)) ; (if (> j -1234) (set! j (prog1 16 (set! k 0)))) ; (if (not (= j 16)) (format #t "if prog1: ~A~%" j)) ; (if (> j -1234) (set! j (prog2 (set! k 0) 17 (set! k 0)))) ; (if (not (= j 17)) (format #t "if prog2: ~A~%" j)) ; (set! k (loop for j from 1 to 4 sum j)) ; (if (not (= k 10)) (format #t "loop sum: ~A~%" k)) ; (if (> j -1234) (set! j (prog2 (set! k 0) (if (> j -1234) (begin (set! k 123) 18) 19) (set! k 0)))) ; (if (not (= j 18)) (format #t "if nested prog2: ~A~%" j)) (set! j 123) (cond ((= j 0) (set! k -1)) ((= j 12) (set! k -2)) ((= j 123) (set! k -3)) (#t (set! k -4))) (if (not (= k -3)) (format #t "cond: ~A ~A~%" j k)) (set! k (cond ((= j 0) -4) ((= j 12) -5) (#t -6))) (if (not (= k -6)) (format #t "cond expr: ~A ~A~%" j k)) (set! k (let ((a 123)) (if (> a 0) 20 32))) (if (not (= k 20)) (format #t "let expr: ~A ~A~%" j k)) (let ((a 123)) (set! k a)) (if (not (= k 123)) (format #t "let: ~A ~A~%" j k)) (set! k 123) (set! bool (= k 123)) (if (not bool) (format #t "bool expr: ~A~%" bool)) (set! bool (if (= k 123) (> k 0) (< k 0))) (if (not bool) (format #t "if bool expr: ~A~%" bool)) (set! j 0) (set! k (do ((m 0 (+ 1 m))) ((= m 3) j) (set! j (+ j 1)))) (if (not (= k 3)) (format #t "do expr: ~A~%" k)) ; (dotimes (m 2) ; (set! k (- k 1))) ; (if (not (= k 1)) (format #t "dotimes: ~A~%" k)) (outa i (* amp (oscil os)))))) (define (sample-arrfile beg dur freq amp) (let ((os (make-oscil freq)) (start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (arr (make-float-vector 100)) (ctr 0) (dir 1)) (do ((i 0 (+ i 1))) ((= i 100)) (set! (arr i) (* amp (+ -.5 (* i .01))))) (array->file "testx.data" arr 100 22050 1) (fill! arr 0.0) (file->array "testx.data" 0 0 100 arr) (do ((i start (+ i 1))) ((= i end)) (outa i (* (arr ctr) (oscil os))) (set! ctr (+ ctr dir)) (if (>= ctr 99) (set! dir -1) (if (<= ctr 0) (set! dir 1)))))) (define (simple-grn-f1 beg dur amp speed freq) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (os (make-oscil freq))) (let ((sr (make-granulate :expansion speed :input (lambda (dir) (oscil os))))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (granulate sr))))))) ;(with-sound () (simple-grn-f1 0 1 .1 2 440)) (define (simple-grn-f2 beg dur amp speed file) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (sr (make-granulate :input (make-readin file) :expansion speed))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (granulate sr)))))) ;(with-sound () (simple-grn-f2 0 1 1 2 "oboe.snd")) (define (simple-grn-f3 beg dur amp speed file) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (sr (make-granulate :input (make-readin file) :expansion speed))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (granulate sr)))))) ;(with-sound () (simple-grn-f3 0 1 1 2 "oboe.snd")) (define (simple-grn-f4 beg dur amp speed file) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (sr (make-granulate :input (make-readin file) :expansion speed))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (granulate sr)))))) ;(with-sound () (simple-grn-f4 0 1 1 2 "oboe.snd")) (define (simple-grn-f5 beg dur amp speed file) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (sr (make-granulate :input (make-readin file) :expansion speed :edit (lambda (g) (float-vector-scale! (mus-data g) 2.0) 0)))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (granulate sr)))))) ;(with-sound (:statistics #t) (simple-grn-f5 0 1 1 2 "oboe.snd")) (define (sample-pvoc5 beg dur amp size file freq) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (os (make-oscil freq))) (let ((sr (make-phase-vocoder (make-readin file) :fft-size size :synthesize (lambda (pv) (oscil os))))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (phase-vocoder sr))))))) ;; (with-sound () (sample-pvoc5 0 1 .1 256 "oboe.snd" 440.0)) #| (with-sound (:statistics #t) (simple-ssb 0 .2 440 .1) (simple-nsin .6 .2 .1) (simple-ncos 0.7 .2 440 .1) (simple-nrxysin .6 .2 .1) (simple-nrxycos 0.7 .2 440 .1) (simple-osc 0.75 .2 440 .1) (simple-asy 1.25 .2 .1) (simple-saw 1.5 .2 .1) (simple-tri 1.75 .2 .1) (simple-pul 2.0 .2 .1) (simple-sqr 2.25 .2 .1) (simple-oz 2.75 .2 440.0 .1) (simple-op 3.0 .2 440.0 .1) (simple-tz 3.25 .2 440.0 .1) (simple-tp 3.5 .2 440.0 .1) (simple-frm 3.75 .2 440.0 .1) (simple-buf 4.5 .2 440.0 .1) (simple-dly 4.75 .2 440.0 .1) (simple-cmb 5.0 .2 440.0 .1) (simple-not 5.25 .2 440.0 .1) (simple-alp 5.5 .2 440.0 .1) (simple-ave 5.75 .2 440.0 .1) (simple-tab 6.0 .2 440.0 .1) (simple-flt 6.25 .2 440.0 .1) (simple-fir 6.5 .2 440.0 .1) (simple-iir 6.5 .2 440.0 .3) (simple-ran 7.0 .2 440.0 .1) (simple-ri 7.25 .2 440.0 .1) (simple-env 7.5 .2 440.0 .1) (simple-amb 7.75 .2 440.0 .1) (simple-fof 8 1 270 .1 .001 730 .6 1090 .3 2440 .1) ;"Ahh" (simple-fof 9 4 270 .1 0.005 730 .6 1090 .3 2440 .1 '(0 0 40 0 75 .2 100 1) '(0 0 .5 1 3 .5 10 .2 20 .1 50 .1 60 .2 85 1 100 0)) (simple-fof 9 4 (* 6/5 540) .1 0.005 730 .6 1090 .3 2440 .1 '(0 0 40 0 75 .2 100 1) '(0 0 .5 .5 3 .25 6 .1 10 .1 50 .1 60 .2 85 1 100 0)) (simple-fof 9 4 135 .1 0.005 730 .6 1090 .3 2440 .1 '(0 0 40 0 75 .2 100 1) '(0 0 1 3 3 1 6 .2 10 .1 50 .1 60 .2 85 1 100 0)) (simple-rd 13.5 .45 .75 "oboe.snd") (simple-cnv 14.0 .45 .75 "oboe.snd") (simple-cnf 14.5 .45 .75 "oboe.snd") (simple-lrg 15.0 .45 .75 "oboe.snd") (simple-cn2 15.5 .45 .4 "oboe.snd") (simple-src 16 .45 1.0 2.0 "oboe.snd") (simple-sr2 16.5 .45 1.0 2.0 "oboe.snd") (simple-sr2a 16.75 .45 1.0 2.0 "oboe.snd") (simple-rndist 17.0 .2 440.0 .1) (simple-ridist 17.25 .2 440.0 .1) (simple-sro 17.5 .45 .1 .5 440) (simple-grn 18 .2 .1 1.0 440) (simple-pvoc 18.25 .2 .4 256 "oboe.snd") (simple-ina 18.5 .45 1 "oboe.snd") (simple-rdf 19 .45 1 "oboe.snd") (simple-f2s 19.5 .45 1 "oboe.snd") (simple-loc 20 .2 440 .1) (simple-out 20.25 .2 440 .1) (simple-dup 20.5 .2 440 .1) (simple-du1 20.75 .2 440 .1))) (with-sound (:statistics #t) (sample-desc 0 .2 440 .1) (sample-mdat .25 .2 440 .1) (sample-xtab .5 .2 440 .1) (sample-xts .75 .2 440 .1) (sample-srl2 1 .2 .2 .5 (* 440 2)) (sample-srll 1.25 .2 .1 .5 (* 440 4)) (sample-srl3 1.5 .2 .1 .5 880) (sample-grn2 1.75 .2 .1 .5 880) (sample-grn3 2 .45 1 1 "oboe.snd") (sample-cnv 2.5 .45 1 1 "oboe.snd") (sample-cnv1 3.0 .45 1 1 "oboe.snd") (sample-pvoc1 3.5 .45 1 512 "oboe.snd") (sample-pvoc2 4.0 .45 1 512 "oboe.snd") (sample-pvoc3 4.5 .001 1 512 "oboe.snd") (sample-osc 5.25 .2 440 .1) (sample-ardcl 5.5 .2 440 .1) (sample-flt 6 .2 440 .1) (sample-arrintp 6.25 .2 440 .1) (sample-if 6.5 .2 440 .1) (sample-arrfile 6.75 .2 440 .15) (sample-pvoc5 7 .2 .1 256 "oboe.snd" 440.0) ) |# (define (pvoc-a beg dur amp size file) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (sr (make-phase-vocoder :input (make-readin file) :fft-size size :interp (/ size 4) :overlap 4))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (phase-vocoder sr)))))) (define (pvoc-e beg dur amp size file) (let ((N2 (floor (/ size 2))) (rd (make-readin file))) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (lastphases (make-float-vector N2)) (in-data (make-float-vector size)) (filptr 0) (window (make-fft-window hamming-window size 0.0)) (D (floor (/ size 4))) ; overlap = 4 (amps #f) (paincrs #f) (ppincrs #f) (phases #f) (freqs #f)) (let ((sr (make-phase-vocoder rd :fft-size size :interp (/ size 4) :overlap 4 :analyze (lambda (pv input) (let ((buf (modulo filptr size))) (fill! freqs 0.0) (if (= filptr 0) (do ((k 0 (+ k 1))) ((= k size)) (set! (in-data k) (readin rd))) (begin (do ((k 0 (+ k 1)) (j D (+ j 1))) ((= j size)) (set! (in-data k) (in-data j))) (do ((k (- size D) (+ k 1))) ((= k size)) (set! (in-data k) (readin rd))))) (do ((k 0 (+ k 1))) ((= k size)) (float-vector-set! paincrs buf (* (in-data k) (window k))) (set! buf (+ buf 1)) (if (>= buf size) (set! buf 0))) (set! filptr (+ filptr D)) (mus-fft paincrs freqs size 1) (rectangular->polar paincrs freqs) #f)) :edit (lambda (pv) (let ((pscl (/ 1.0 D)) (kscl (/ two-pi size))) (do ((k 0 (+ k 1)) (ks 0.0 (+ ks kscl))) ((= k N2)) (let* ((freq (freqs k)) (diff (- freq (lastphases k)))) (set! (lastphases k) freq) (if (> diff pi) (set! diff (- diff two-pi))) (if (< diff (- pi)) (set! diff (+ diff two-pi))) (float-vector-set! freqs k (+ (* diff pscl) ks)))) #f)) :synthesize (lambda (pv) (float-vector-add! amps paincrs) (float-vector-add! ppincrs freqs) (float-vector-add! phases ppincrs) (clm23-sine-bank amps phases N2))))) (set! amps (phase-vocoder-amps sr)) (set! paincrs (phase-vocoder-amp-increments sr)) (set! ppincrs (phase-vocoder-phase-increments sr)) (set! phases (phase-vocoder-phases sr)) (set! freqs (phase-vocoder-freqs sr)) (float-vector-scale! window (/ 2.0 (* 0.54 size))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (phase-vocoder sr)))))))) (define (or1) (let ((e1 (make-env '(0 0 1 1) :length 10)) (e2 (make-env '(0 1 1 0) :length 10)) (e3 #f) (ok1 0.0)) (do ((i 0 (+ i 1))) ((= i 1)) (set! ok1 0.0) (if (or e1 e2) (set! ok1 (+ ok1 (env e1))) (format #t ";or1 a~%")) (if (not (or e1 e2)) (format #t ";or1 1~%")) (if (and e1 e2) (set! ok1 (+ ok1 (env e2))) (format #t ";or1 b~%")) (if (not (and e1 e2)) (format #t ";or1 2~%")) (if (or e3 e1 e2) (mus-reset e2) ; resets e2 -> 1.0 (format #t ";or1 c~%")) (if (and e1 e3 e2) (format #t ";or1 3~%")) (if (not e1) (format #t ";or1 4~%")) (if (< (abs ok1) .001) (format #t ";or1 ok1: ~A~%" ok1))))) (define (or2) (let ((e1 (make-env '(0 0 1 1) :length 10)) (e2 (make-env '(0 1 1 0) :length 10)) (e3 #f) (ok1 0.0) (oki 0) (okb #f)) (do ((i 0 (+ i 1))) ((= i 1)) (set! ok1 0.0) (set! oki (+ oki 1)) (set! okb #t) (if (or e1 e2) (set! ok1 (+ ok1 (env e1))) (format #t ";or2 a~%")) (if (not (or e1 e2 okb)) (format #t ";or2 1~%")) (if (and e1 e2) (set! ok1 (+ ok1 (env e2))) (format #t ";or2 b~%")) (if (not (and e1 e2)) (format #t ";or2 2~%")) (if (or e3 e1 e2) (mus-reset e2) ; resets e2 -> 1.0 (format #t ";or2 c~%")) (if (and e1 e3 e2) (format #t ";or2 3~%")) (if (not e1) (format #t ";or2 4~%")) (if (< (abs ok1) .001) (format #t ";or1 ok1: ~A~%" ok1))))) (define (or3) (let ((e1 (make-env '(0 0 1 1) :length 10)) (i1 (make-vector 3 32)) (f1 (make-float-vector 3 3.14)) (i2 (make-vector 3 3)) (f2 (make-vector 3 1.5)) (ok1 0.0) (oki 0)) (do ((i 0 (+ i 1))) ((= i 1)) (cond (e1 (set! ok1 (+ ok1 (env e1)))) (#t (format #t ";or3 1~%"))) (if (or f1 f2) (set! ok1 (+ ok1 (f2 0))) (format #t ";or3 a~%")) (if (not (or f2 f1)) (format #t ";or3 2~%")) (if (and f2 f1) (set! ok1 (+ ok1 (f1 1))) (format #t ";or3 b~%")) (if (or i1 i2) (set! oki (+ oki (i2 0))) (format #t ";or3 d~%")) (if (not (or i2 i1)) (format #t ";or3 3~%")) (if (and i2 i1) (set! oki (+ oki (i1 1))) (format #t ";or3 e~%"))))) (define (or4) (let ((e1 (make-env '(0 0 1 1) :length 10)) (e2 (make-env '(0 1 1 0) :length 10)) (i1 (make-vector 3 32)) (f1 (make-float-vector 3 3.14)) (i2 (make-vector 3 3)) (f2 (make-vector 3 1.5)) (oki 0)) (do ((i 0 (+ i 1))) ((= i 1)) (if (or (and e1 e2) (and f1 f2) (and i1 i2)) (set! oki (+ oki 1)) (format #t ";or4 a~%")) (if (and (or f1 f2) (not (or i1 i2)) (or e1 e2)) (format #t ";or4 1~%")) (if f1 (if e1 (if (not e2) (format #t ";or4 2~%") (set! oki (+ oki 1))) (format #t ";or4 3~%")) (format #t ";or4 4~%"))))) ;;; -------------------------------------------------------------------------------- ;;; ;;; instruments and note lists from the documentation ;;; ins in docs + note lists ;;; fm.html (define (fmdoc-pm beg end freq amp mc-ratio index) (let ((carrier-phase 0.0) ; set to pi/2 if someone tells you PM can't produce energy at 0Hz (carrier-phase-incr (hz->radians freq)) (modulator-phase 0.0) (modulator-phase-incr (hz->radians (* mc-ratio freq)))) (do ((i beg (+ i 1))) ((= i end)) (let* ((modulation (* index (sin modulator-phase))) (pm-val (* amp (sin (+ carrier-phase modulation))))) ;; no integration in phase modulation (it's a phase change) (set! carrier-phase (+ carrier-phase carrier-phase-incr)) (set! modulator-phase (+ modulator-phase modulator-phase-incr)) (outa i pm-val))))) (define (fmdoc-fm beg end freq amp mc-ratio index) (let ((carrier-phase 0.0) (carrier-phase-incr (hz->radians freq)) (modulator-phase-incr (hz->radians (* mc-ratio freq)))) (let ((modulator-phase (* 0.5 (+ pi modulator-phase-incr))) ;; (pi+incr)/2 to get (centered) sin after integration, to match pm case above ;; I believe this is what causes most of the confusion (fm-index (hz->radians (* mc-ratio freq index)))) ;; fix up fm index (it's a frequency change) (do ((i beg (+ i 1))) ((= i end)) (let ((modulation (* fm-index (sin modulator-phase))) (fm-val (* amp (sin carrier-phase)))) (set! carrier-phase (+ carrier-phase modulation carrier-phase-incr)) (set! modulator-phase (+ modulator-phase modulator-phase-incr)) (outa i fm-val)))))) (define* (fmdoc-fm-1 beg dur freq amp mc-ratio index (index-env '(0 1 100 1))) (let ((fm-index (hz->radians (* index mc-ratio freq)))) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (cr (make-oscil freq)) (md (make-oscil (* freq mc-ratio))) (ampf (make-env index-env :scaler amp :duration dur)) (indf (make-env index-env :scaler fm-index :duration dur))) (do ((i start (+ i 1))) ((= i end)) (outa i (* (env ampf) ; amplitude env (oscil cr (* (env indf) ; carrier + modulation env (oscil md)))) ; modulation ))))) (define (fmdoc-fm-2 beg dur freq amp mc-ratio index carrier-phase mod-phase) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (cr (make-oscil freq carrier-phase)) (md (make-oscil (* freq mc-ratio) mod-phase)) (fm-index (hz->radians (* index mc-ratio freq)))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (oscil cr (* fm-index (oscil md)))))))) (define (fmdoc-fm-3 beg dur freq amp mc-ratio index car-phase mod-phase skew-func skew) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (cr (make-oscil freq car-phase)) (md (make-oscil (* freq mc-ratio) mod-phase)) (skewf (make-env skew-func :scaler (hz->radians (* skew mc-ratio freq)) :duration dur)) (fm-index (hz->radians (* index mc-ratio freq)))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (oscil cr (* fm-index (oscil md (env skewf))))))))) (define (fmdoc-fm-4 beg dur freq amp mc-ratio index cr0p cr1p md0p md1p) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (cr0 (make-oscil 0 cr0p)) (cr1 (make-oscil 0 cr1p)) (md0 (make-oscil (* freq mc-ratio) md0p)) (md1 (make-oscil (* freq mc-ratio) md1p)) (am0 (make-oscil freq 0)) (am1 (make-oscil freq (* .5 pi))) (fm-index (hz->radians (* index mc-ratio freq)))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (+ (* (oscil am0) (oscil cr0 (* fm-index (oscil md0)))) (* (oscil am1) (oscil cr1 (* fm-index (oscil md1)))))))))) (define (fmdoc-fm-5 beg dur freq amp mc-ratios indexes carrier-phase mod-phases) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (cr (make-oscil freq carrier-phase)) (n (length mc-ratios))) (define (interleave a b) (let ((lst ())) (for-each (lambda (x y) (set! lst (cons (hz->radians (* freq x y)) (cons x lst)))) a b) (reverse lst))) (if (and (apply and (map integer? mc-ratios)) (apply and (map zero? mod-phases))) ; use polyoid if any not 0.0 (let ((fm (make-polywave freq (interleave mc-ratios indexes) mus-chebyshev-second-kind))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (oscil cr (polywave fm)))))) (let ((modulators (make-float-vector n)) (fm-indices (make-float-vector n))) (do ((i 0 (+ i 1))) ((= i n)) (set! (modulators i) (hz->radians (* freq (mc-ratios i) (mod-phases i)))) (set! (fm-indices i) (hz->radians (* freq (indexes i) (mc-ratios i))))) (let ((ob (make-oscil-bank modulators (make-float-vector n 0.0) fm-indices #t))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (oscil cr (oscil-bank ob)))))))))) (define (fmdoc-violin beg dur frequency amplitude fm-index) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (frq-scl (hz->radians frequency))) (let ((maxdev (* frq-scl fm-index))) (let ((index1 (* maxdev (/ 5.0 (log frequency)))) (index2 (* maxdev 3.0 (/ (- 8.5 (log frequency)) (+ 3.0 (/ frequency 1000))))) (index3 (* maxdev (/ 4.0 (sqrt frequency)))) (carrier (make-oscil frequency)) (fmosc1 (make-oscil frequency)) (fmosc2 (make-oscil (* 3 frequency))) (fmosc3 (make-oscil (* 4 frequency))) (ampf (make-env '(0 0 25 1 75 1 100 0) :scaler amplitude :duration dur))) (let ((indf1 (make-env '(0 1 25 .4 75 .6 100 0) :scaler index1 :duration dur)) (indf2 (make-env '(0 1 25 .4 75 .6 100 0) :scaler index2 :duration dur)) (indf3 (make-env '(0 1 25 .4 75 .6 100 0) :scaler index3 :duration dur)) (pervib (make-triangle-wave 5 :amplitude (* .0025 frq-scl))) (ranvib (make-rand-interp 16 :amplitude (* .005 frq-scl)))) (do ((i start (+ i 1))) ((= i end)) (let ((vib (+ (triangle-wave pervib) (rand-interp ranvib)))) (outa i (* (env ampf) (oscil carrier (+ vib (+ (* (env indf1) (oscil fmosc1 vib)) (* (env indf2) (oscil fmosc2 (* 3.0 vib))) (* (env indf3) (oscil fmosc3 (* 4.0 vib))))))))))))))) (define (fmdoc-cascade beg dur freq amp modrat modind casrat casind caspha) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (cr (make-oscil freq)) (md (make-oscil (* freq modrat))) (ca (make-oscil (* freq casrat) caspha)) (fm-ind0 (hz->radians (* modind modrat freq))) (fm-ind1 (hz->radians (* casind (/ casrat modrat) freq)))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (oscil cr (* fm-ind0 (oscil md (* fm-ind1 (oscil ca)))))))))) (define (fmdoc-feedbk beg dur freq amp index) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (y 0.0) (x-incr (hz->radians freq))) (do ((i start (+ i 1)) (x 0.0 (+ x x-incr))) ((= i end)) (set! y (+ x (* index (sin y)))) (outa i (* amp (sin y)))))) (define* (fmdoc-vox beg dur freq amp (indices '(.005 .01 .02)) (formant-amps '(.86 .13 .01))) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (car (make-oscil 0)) (per-vib (make-triangle-wave 6 :amplitude (* freq .03))) (ran-vib (make-rand-interp 20 :amplitude (* freq .5 .02)))) (let ((a0 (make-env '(0 0 25 1 75 1 100 0) :scaler (* amp (formant-amps 0)) :duration dur)) (a1 (make-env '(0 0 25 1 75 1 100 0) :scaler (* amp (formant-amps 1)) :duration dur)) (a2 (make-env '(0 0 25 1 75 1 100 0) :scaler (* amp (formant-amps 2)) :duration dur)) (o0 (make-oscil 0.0)) (o1 (make-oscil 0.0)) (o2 (make-oscil 0.0)) (e0 (make-oscil 0.0)) (e1 (make-oscil 0.0)) (e2 (make-oscil 0.0)) (ind0 (indices 0)) (ind1 (indices 1)) (ind2 (indices 2)) (f0 (make-env '(0 520 100 490) :duration dur)) (f1 (make-env '(0 1190 100 1350) :duration dur)) (f2 (make-env '(0 2390 100 1690) :duration dur))) (do ((i start (+ i 1))) ((= i end)) (let* ((frq (+ freq (triangle-wave per-vib) (rand-interp ran-vib))) (frq1 (hz->radians frq)) (carg (oscil car frq1)) (frm0 (/ (env f0) frq)) (frm1 (/ (env f1) frq)) (frm2 (/ (env f2) frq))) (outa i (+ (* (env a0) (+ (* (even-weight frm0) (oscil e0 (+ (* ind0 carg) (even-multiple frm0 frq1)))) (* (odd-weight frm0) (oscil o0 (+ (* ind0 carg) (odd-multiple frm0 frq1)))))) (* (env a1) (+ (* (even-weight frm1) (oscil e1 (+ (* ind1 carg) (even-multiple frm1 frq1)))) (* (odd-weight frm1) (oscil o1 (+ (* ind1 carg) (odd-multiple frm1 frq1)))))) (* (env a2) (+ (* (even-weight frm2) (oscil e2 (+ (* ind2 carg) (even-multiple frm2 frq1)))) (* (odd-weight frm2) (oscil o2 (+ (* ind2 carg) (odd-multiple frm2 frq1))))))))))))) #| (define* (fmdoc-vox beg dur freq amp (indexes '(.005 .01 .02)) (formant-amps '(.86 .13 .01))) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (car-os (make-oscil 0)) (evens (make-vector 3)) (odds (make-vector 3)) (ampfs (make-vector 3)) (frmfs (make-vector 3)) (indices (apply float-vector indexes)) (per-vib (make-triangle-wave 6 :amplitude (* freq .03))) (ran-vib (make-rand-interp 20 :amplitude (* freq .5 .02))) (frq1 0.0) (frq 0.0) (carg 0.0) (frm0 0.0) (frm-int 0) (frac 0.0) (fracf 0.0)) (do ((i 0 (+ i 1))) ((= i 3)) (set! (evens i) (make-oscil 0)) (set! (odds i) (make-oscil 0)) (set! (ampfs i) (make-env '(0 0 25 1 75 1 100 0) :scaler (* amp (formant-amps i)) :duration dur))) (set! (frmfs 0) (make-env '(0 520 100 490) :duration dur)) (set! (frmfs 1) (make-env '(0 1190 100 1350) :duration dur)) (set! (frmfs 2) (make-env '(0 2390 100 1690) :duration dur)) (do ((i start (+ i 1))) ((= i end)) (set! frq (+ freq (triangle-wave per-vib) (rand-interp ran-vib))) (set! frq1 (hz->radians frq)) (set! carg (oscil car-os frq1)) (do ((k 0 (+ k 1))) ((= k 3)) (set! frm0 (/ (env (vector-ref frmfs k)) frq)) (set! frm-int (floor frm0)) (set! frac (- frm0 frm-int)) (set! fracf (+ (* (float-vector-ref indices k) carg) (* frm-int frq1))) (if (even? frm-int) (outa i (* (env (vector-ref ampfs k)) (+ (* (- 1.0 frac) (oscil (vector-ref evens k) fracf)) (* frac (oscil (vector-ref odds k) (+ fracf frq1)))))) (outa i (* (env (vector-ref ampfs k)) (+ (* frac (oscil (vector-ref evens k) (+ fracf frq1))) (* (- 1.0 frac) (oscil (vector-ref odds k) fracf)))))))))) |# ;;; -------------------------------------------------------------------------------- ;;; sndclm.html (define (sndclmdoc-simp start end freq amp) (let ((os (make-oscil freq))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (oscil os)))))) (define (sndclmdoc-simp-1 beg dur freq amp) (let ((os (make-oscil freq)) (start (seconds->samples beg)) (end (seconds->samples (+ beg dur)))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (oscil os)))))) (define (sndclmdoc-simp-2 beg dur freq amp) (let ((os (make-oscil freq)) (start (seconds->samples beg)) (end (seconds->samples (+ beg dur)))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (oscil os)))))) (definstrument (sndclmdoc-simp-3 beg dur freq amp) (let ((os (make-oscil freq)) (start (seconds->samples beg)) (end (seconds->samples (+ beg dur)))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (oscil os)))))) (define (sndclmdoc-telephone start telephone-number) (let ((touch-tab-1 '(0 697 697 697 770 770 770 852 852 852 941 941 941)) (touch-tab-2 '(0 1209 1336 1477 1209 1336 1477 1209 1336 1477 1209 1336 1477))) (do ((i 0 (+ i 1))) ((= i (length telephone-number))) (let* ((num (telephone-number i)) (frq1 (touch-tab-1 num)) (frq2 (touch-tab-2 num))) (sndclmdoc-simp-3 (+ start (* i .4)) .3 frq1 .1) (sndclmdoc-simp-3 (+ start (* i .4)) .3 frq2 .1))))) (definstrument (sndclmdoc-simp-4 beg dur freq amp envelope) (let ((os (make-oscil freq)) (amp-env (make-env envelope :duration dur :scaler amp)) (start (seconds->samples beg)) (end (seconds->samples (+ beg dur)))) (do ((i start (+ i 1))) ((= i end)) (outa i (* (env amp-env) (oscil os)))))) (define (make-my-oscil frequency) ; we want our own oscil! (float-vector 0.0 (hz->radians frequency))) ; current phase and frequency-based phase increment (define (my-oscil gen fm) ; the corresponding generator (let ((result (sin (gen 0)))) ; return sin(current-phase) (set! (gen 0) (+ (gen 0) ; increment current phase (gen 1) ; by frequency fm)) ; and FM result)) ; return sine wave (define (sndclmdoc-simp-5 start end freq amp frq-env) (let ((os (make-oscil freq)) (frqe (make-env frq-env :length (- end start) :scaler (hz->radians freq)))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (oscil os (env frqe))))))) (definstrument (sndclmdoc-simple-fm beg dur freq amp mc-ratio index amp-env index-env) (let ((fm-index (hz->radians (* index mc-ratio freq)))) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (cr (make-oscil freq)) ; carrier (md (make-oscil (* freq mc-ratio))) ; modulator (ampf (make-env (or amp-env '(0 0 .5 1 1 0)) :scaler amp :duration dur)) (indf (make-env (or index-env '(0 0 .5 1 1 0)) :scaler fm-index :duration dur))) (do ((i start (+ i 1))) ((= i end)) (outa i (* (env ampf) (oscil cr (* (env indf) (oscil md))))))))) (define (sndclmdoc-simple-add beg dur freq amp) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (harms (do ((i 1 (+ i 1)) (lst ())) ((> i 20) (reverse lst)) (set! lst (cons (* amp .05) (cons i lst)))))) ;; we'll create a tone with 20 equal amplitude harmonics (let ((gen (make-polywave freq harms))) (do ((i start (+ i 1))) ((= i end)) (outa i (polywave gen)))))) (definstrument (sndclmdoc-mapenv beg dur frq amp en) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (osc (make-oscil frq)) (zv (make-env en 1.0 dur)) (pi2 (* 0.5 pi))) (do ((i start (+ i 1))) ((= i end)) (let ((zval (env zv))) (outa i (* amp (sin (* pi2 zval (* zval zval))) (oscil osc))))))) (definstrument (sndclmdoc-simple-table dur) (let ((tab (make-table-lookup :wave (partials->wave '(1 .5 2 .5))))) (do ((i 0 (+ i 1))) ((= i dur)) (outa i (* .3 (table-lookup tab)))))) (define (sndclmdoc-looper start dur sound freq amp) (let ((beg (seconds->samples start)) (end (seconds->samples (+ start dur))) (loop-data (mus-sound-loop-info sound))) (if (or (null? loop-data) (<= (cadr loop-data) (car loop-data))) (error 'no-loop-positions) (let* ((loop-start (car loop-data)) (loop-end (cadr loop-data)) (loop-length (+ 1 (- loop-end loop-start))) (sound-section (float-vector-scale! (file->array sound 0 loop-start loop-length (make-float-vector loop-length)) amp)) (original-loop-duration (/ loop-length (srate sound))) (tbl (make-table-lookup :frequency (/ freq original-loop-duration) :wave sound-section))) ;; "freq" here is how fast we read (transpose) the sound -- 1.0 returns the original (do ((i beg (+ i 1))) ((= i end)) (outa i (table-lookup tbl))))))) (definstrument (sndclmdoc-fm-table file start dur amp read-speed modulator-freq index-in-samples) (let ((table-length (framples file))) (let ((beg (seconds->samples start)) (end (seconds->samples (+ start dur))) (tab (make-table-lookup :frequency (/ read-speed (mus-sound-duration file)) :wave (float-vector-scale! (file->array file 0 0 table-length (make-float-vector table-length)) amp))) (osc (make-oscil modulator-freq)) (index (/ (* (hz->radians modulator-freq) 2 pi index-in-samples) table-length))) (do ((i beg (+ i 1))) ((= i end)) (outa i (table-lookup tab (* index (oscil osc)))))))) (definstrument (sndclmdoc-bigbird start duration frequency freqskew amplitude freq-env amp-env partials) (let ((beg (seconds->samples start)) (end (seconds->samples (+ start duration))) (gls-env (make-env freq-env (hz->radians freqskew) duration)) (polyos (make-polywave frequency :partials partials)) (fil (make-one-pole .1 .9)) (amp-env (make-env amp-env amplitude duration))) (do ((i beg (+ i 1))) ((= i end)) (outa i (one-pole fil ; for distance effects (* (env amp-env) (polywave polyos (env gls-env)))))))) (definstrument (sndclmdoc-pqw start dur spacing carrier partials) (let ((spacing-cos (make-oscil spacing (/ pi 2.0))) (spacing-sin (make-oscil spacing)) (carrier-cos (make-oscil carrier (/ pi 2.0))) (carrier-sin (make-oscil carrier)) (sin-coeffs (partials->polynomial partials mus-chebyshev-second-kind)) (cos-coeffs (partials->polynomial partials mus-chebyshev-first-kind)) (beg (seconds->samples start)) (end (seconds->samples (+ start dur)))) (do ((i beg (+ i 1))) ((= i end)) (let ((ax (oscil spacing-cos))) (outa i (- (* (oscil carrier-sin) (oscil spacing-sin) (polynomial sin-coeffs ax)) (* (oscil carrier-cos) (polynomial cos-coeffs ax)))))))) (definstrument (sndclmdoc-bl-saw start dur frequency order) (let ((norm (if (= order 1) 1.0 ; these peak amps were determined empirically (if (= order 2) 1.3 ; actual limit is supposed to be pi/2 (G&R 1.441) (if (< order 9) 1.7 ; but Gibbs phenomenon pushes it to 1.851 1.9)))) ; if order>25, numerical troubles -- use table-lookup (freqs ())) (do ((i 1 (+ i 1))) ((> i order)) (set! freqs (cons (/ 1.0 (* norm i)) (cons i freqs)))) (let ((ccos (make-oscil frequency (/ pi 2.0))) (csin (make-oscil frequency)) (coeffs (partials->polynomial (reverse freqs) mus-chebyshev-second-kind)) (beg (seconds->samples start)) (end (seconds->samples (+ start dur)))) (do ((i beg (+ i 1))) ((= i end)) (outa i (* (oscil csin) (polynomial coeffs (oscil ccos)))))))) (define (sndclmdoc-tritri start dur freq amp index mcr) (let ((beg (seconds->samples start)) (end (seconds->samples (+ start dur))) (carrier (make-triangle-wave freq amp)) (modulator (make-triangle-wave (* mcr freq) index))) (do ((i beg (+ i 1))) ((= i end)) (outa i (triangle-wave carrier (triangle-wave modulator)))))) (define* (sndclmdoc-make-sinc-train (frequency 440.0) width) (let ((range (or width (* pi (- (* 2 (floor (/ *clm-srate* (* 2.2 frequency)))) 1))))) ;; 2.2 leaves a bit of space before srate/2, (* 3 pi) is the minimum width, normally (list (- (* range 0.5)) range (/ (* range frequency) *clm-srate*)))) (define* (sndclmdoc-sinc-train gen (fm 0.0)) (let ((ang (car gen)) (range (cadr gen)) (frq (caddr gen))) (let ((top (* 0.5 range)) (val (if (= ang 0.0) 1.0 (/ (sin ang) ang))) (new-ang (+ ang frq fm))) (if (> new-ang top) (set! (gen 0) (- new-ang range)) (set! (gen 0) new-ang)) val))) (define (sndclmdoc-make-sum-of-odd-sines frequency n) (float-vector 0.0 (hz->radians frequency) (* 1.0 n))) (define (sndclmdoc-sum-of-odd-sines gen fm) (let* ((angle (gen 0)) (a2 (* angle 0.5)) (n (gen 2)) (den (* n (sin a2))) (result (if (< (abs den) 1.0e-9) 0.0 (/ (* (sin (* n a2)) (sin (* (+ 1 n) a2))) den)))) (set! (gen 0) (+ (gen 0) (gen 1) fm)) result)) (definstrument (sndclmdoc-shift-pitch beg dur file freq (order 40)) (let ((st (seconds->samples beg)) (nd (seconds->samples (+ beg dur))) (gen (make-ssb-am freq order)) (rd (make-readin file))) (do ((i st (+ i 1))) ((= i nd)) (outa i (ssb-am gen (readin rd)))))) (definstrument (sndclmdoc-repitch beg dur sound old-freq new-freq (amp 1.0) (pairs 10) (order 40) (bw 50.0)) (let ((start (seconds->samples beg)) (len (seconds->samples dur)) (end (seconds->samples (+ beg dur))) (ssbs (make-vector pairs)) (bands (make-vector pairs)) (factor (/ (- new-freq old-freq) old-freq)) (rd (make-readin sound))) (let ((in-data (make-float-vector len))) (do ((i 0 (+ i 1))) ((= i len)) (float-vector-set! in-data i (readin rd))) (float-vector-scale! in-data amp) (do ((i 1 (+ i 1))) ((> i pairs)) (let ((aff (* i old-freq)) (bwf (* bw (+ 1.0 (/ i (* 2 pairs)))))) (set! (ssbs (- i 1)) (make-ssb-am (* i factor old-freq))) (set! (bands (- i 1)) (make-bandpass (hz->radians (- aff bwf)) (hz->radians (+ aff bwf)) order)))) (do ((band 0 (+ 1 band))) ((= band pairs)) (let ((ssb (ssbs band)) (flt (bands band))) (do ((i start (+ i 1)) (j 0 (+ j 1))) ((= i end)) (outa i (ssb-am ssb (bandpass flt (float-vector-ref in-data j)))))))))) #| (let* ((sound "oboe.snd") ; 1.8 (mx (maxamp sound)) (dur (mus-sound-duration sound))) (with-sound (:scaled-to mx :srate 22050 :statistics #t) (sndclmdoc-repitch 0 dur sound 554 1000))) |# (definstrument (sndclmdoc-fofins beg dur frq amp vib f0 a0 f1 a1 f2 a2 ve ae) (let ((foflen (if (= *clm-srate* 22050) 100 200))) (let ((foftab (make-float-vector foflen))) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (ampf (make-env :envelope (or ae (list 0 0 25 1 75 1 100 0)) :scaler amp :duration dur)) (frq0 (hz->radians f0)) (frq1 (hz->radians f1)) (frq2 (hz->radians f2)) (vibr (make-oscil 6)) (vibenv (make-env :envelope (or ve (list 0 1 100 1)) :scaler vib :duration dur)) (win-freq (/ (* 2 pi) foflen)) (wt0 (make-wave-train :wave foftab :frequency frq))) (do ((i 0 (+ i 1))) ((= i foflen)) (set! (foftab i) ;; this is not the pulse shape used by B&R (* (+ (* a0 (sin (* i frq0))) (* a1 (sin (* i frq1))) (* a2 (sin (* i frq2)))) .5 (- 1.0 (cos (* i win-freq)))))) (do ((i start (+ i 1))) ((= i end)) (outa i (* (env ampf) (wave-train wt0 (* (env vibenv) (oscil vibr)))))))))) (definstrument (sndclmdoc-echo beg dur scaler secs file) (let ((del (make-delay (seconds->samples secs))) (rd (make-sampler 0 file)) (stop (+ beg dur))) (do ((i beg (+ i 1))) ((= i stop)) (let ((inval (read-sample rd))) (outa i (+ inval (delay del (* scaler (+ (tap del) inval))))))))) ; (with-sound () (sndclmdoc-echo 0 60000 .5 1.0 "pistol.snd")) (define* (sndclmdoc-make-moving-max (size 128)) (let ((gen (make-delay size))) (set! (mus-scaler gen) 0.0) gen)) (define (sndclmdoc-moving-max gen y) (let* ((absy (abs y)) (mx (delay gen absy))) (if (>= absy (mus-scaler gen)) (set! (mus-scaler gen) absy) (if (>= mx (mus-scaler gen)) (set! (mus-scaler gen) (float-vector-peak (mus-data gen))))) (mus-scaler gen))) (definstrument (sndclmdoc-zc time dur freq amp length1 length2 feedback) (let ((beg (seconds->samples time)) (end (seconds->samples (+ time dur))) (s (make-pulse-train freq)) ; some raspy input so we can hear the effect easily (d0 (make-comb :size length1 :max-size (max length1 length2) :scaler feedback)) (aenv (make-env '(0 0 .1 1 .9 1 1 0) :scaler amp :duration dur)) (zenv (make-env '(0 0 1 1) :scaler (- length2 length1) :base 12.0 :duration dur))) (do ((i beg (+ i 1))) ((= i end)) (outa i (* (env aenv) (comb d0 (pulse-train s) (env zenv))))))) (define (sndclmdoc-fir+comb beg dur freq amp size) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (dly (make-comb :scaler .9 :size size))) (let ((flt (make-fir-filter :order size :xcoeffs (mus-data dly))) ; comb delay line as FIR coeffs (r (make-rand freq))) ; feed comb with white noise (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (fir-filter flt (comb dly (rand r))))))))) (definstrument (sndclmdoc-simple-src start-time duration amp srt srt-env filename) (let ((senv (make-env :envelope srt-env :duration duration)) (beg (seconds->samples start-time)) (end (seconds->samples (+ start-time duration))) (src-gen (make-src :input (make-readin filename) :srate srt))) (do ((i beg (+ i 1))) ((= i end)) (outa i (* amp (src src-gen (env senv))))))) (definstrument (sndclmdoc-srcer start-time duration amp srt fmamp fmfreq filename) (let ((os (make-oscil fmfreq)) (beg (seconds->samples start-time)) (end (seconds->samples (+ start-time duration))) (src-gen (make-src :input (make-readin filename) :srate srt))) (do ((i beg (+ i 1))) ((= i end)) (outa i (* amp (src src-gen (* fmamp (oscil os)))))))) ;;; (with-sound () (sndclmdoc-srcer 0 2 1.0 0.5 1.0 300 "oboe.snd")) (definstrument (sndclmdoc-convins beg dur filt file (size 128)) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (ff (make-convolve :input (make-readin file) :fft-size size :filter filt))) (do ((i start (+ i 1))) ((= i end)) (outa i (convolve ff))))) (definstrument (sndclmdoc-granulate-sound file beg dur (orig-beg 0.0) (exp-amt 1.0)) (let* ((f-srate (srate file)) (f-start (round (* f-srate orig-beg))) (f (make-readin file :start f-start)) (st (seconds->samples beg)) (new-dur (or dur (- (mus-sound-duration file) orig-beg)))) (let ((exA (make-granulate :input f :expansion exp-amt)) (nd (+ st (seconds->samples new-dur)))) (do ((i st (+ i 1))) ((= i nd)) (outa i (granulate exA)))))) (definstrument (sndclmdoc-grev beg dur exp-amt file file-beg) (let ((exA (make-granulate :expansion exp-amt :input (make-readin file 0 file-beg -1))) (stop (+ beg dur))) (do ((i beg (+ i 1))) ((= i stop)) (outa i (granulate exA))))) (definstrument (sndclmdoc-simple-pvoc beg dur amp size file) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (sr (make-phase-vocoder (make-readin file) :fft-size size))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (phase-vocoder sr)))))) (definstrument (sndclmdoc-asy beg dur freq amp index (r 1.0) (ratio 1.0)) (let ((st (seconds->samples beg)) (nd (seconds->samples (+ beg dur))) (asyf (make-asymmetric-fm :r r :ratio ratio :frequency freq))) (do ((i st (+ i 1))) ((= i nd)) (outa i (* amp (asymmetric-fm asyf index)))))) (define (sndclmdoc-simple-f2s beg dur amp file) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (fil (make-file->sample file))) (do ((i start (+ i 1)) (ctr 0 (+ ctr 1))) ((= i end)) (outa i (* amp (file->sample fil ctr)))))) (definstrument (sndclmdoc-simple-ina beg dur amp file) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (fil (make-file->sample file))) (do ((i start (+ i 1)) (ctr 0 (+ ctr 1))) ((= i end)) (outa i (* amp (ina ctr fil)))))) (definstrument (sndclmdoc-env-sound file beg (amp 1.0) (amp-env '(0 1 100 1))) (let ((st (seconds->samples beg)) (dur (mus-sound-framples file)) (rev-amount .01) (rdA (make-readin file))) (let ((ampf (make-env amp-env amp :length dur)) (nd (+ st dur))) (if *reverb* (do ((i st (+ i 1))) ((= i nd)) (let ((outval (* (env ampf) (readin rdA)))) (outa i outval) (outa i (* outval rev-amount) *reverb*))) (do ((i st (+ i 1))) ((= i nd)) (outa i (* (env ampf) (readin rdA)))))))) (definstrument (sndclmdoc-space file onset duration (distance-env '(0 1 100 10)) (amplitude-env '(0 1 100 1)) (degree-env '(0 45 50 0 100 90)) (reverb-amount .05)) (let ((beg (seconds->samples onset)) (end (seconds->samples (+ onset duration))) (loc (make-locsig :degree 0 :distance 1 :reverb reverb-amount)) (rdA (make-readin :file file)) (dist-env (make-env distance-env :duration duration)) (amp-env (make-env amplitude-env :duration duration)) (deg-env (make-env degree-env :scaler (/ 1.0 90.0) :duration duration)) (dist-scaler 0.0) (degval 0.0) (stereo (> (channels *output*) 1))) (if (and stereo *reverb*) (do ((i beg (+ i 1))) ((= i end)) (set! degval (env deg-env)) (set! dist-scaler (/ 1.0 (env dist-env))) (locsig-set! loc 0 (* (- 1.0 degval) dist-scaler)) (locsig-set! loc 1 (* degval dist-scaler)) (locsig-reverb-set! loc 0 (* reverb-amount (sqrt dist-scaler))) (locsig loc i (* (env amp-env) (readin rdA)))) (do ((i beg (+ i 1))) ((= i end)) (set! degval (env deg-env)) (set! dist-scaler (/ 1.0 (env dist-env))) (locsig-set! loc 0 (* (- 1.0 degval) dist-scaler)) (if stereo (locsig-set! loc 1 (* degval dist-scaler))) (if *reverb* (locsig-reverb-set! loc 0 (* reverb-amount (sqrt dist-scaler)))) (locsig loc i (* (env amp-env) (readin rdA))))))) (define (sndclmdoc-simple-dloc beg dur freq amp) (let ((os (make-oscil freq)) (start (seconds->samples beg)) (end (seconds->samples (+ beg dur)))) (let ((loc (make-move-sound (list start end 4 0 (make-delay 12) (make-env '(0 0 10 1) :duration dur) #f (make-vector 4 #f) (vector (make-env '(0 0 1 1 2 0 3 0 4 0) :duration dur) (make-env '(0 0 1 0 2 1 3 0 4 0) :duration dur) (make-env '(0 0 1 0 2 0 3 1 4 0) :duration dur) (make-env '(0 0 1 0 2 0 3 0 4 1) :duration dur)) #f (vector 0 1 2 3))))) (do ((i start (+ i 1))) ((= i end)) (move-sound loc i (* amp (oscil os))))))) (definstrument (when? start-time duration start-freq end-freq grain-file) (let ((beg (seconds->samples start-time)) (len (seconds->samples duration)) (end (seconds->samples (+ start-time duration))) (frqf (make-env '(0 0 1 1) :scaler (hz->radians (- end-freq start-freq)) :duration duration)) (click-track (make-pulse-train start-freq)) (grain-size (mus-sound-framples grain-file))) (let ((grains (make-wave-train :size grain-size :frequency start-freq)) (ampf (make-env '(0 1 1 0) :scaler .7 :offset .3 :duration duration :base 3.0)) (grain #f)) (set! grain (mus-data grains)) (file->array grain-file 0 0 grain-size grain) (let ((original-grain (copy grain))) (do ((i beg (+ i 1))) ((= i end)) (let ((gliss (env frqf))) (outa i (* (env ampf) (wave-train grains gliss))) (if (> (pulse-train click-track gliss) 0.0) (let ((scaler (max 0.1 (* 1.0 (/ (- i beg) len)))) (comb-len 32) (cs (make-vector 3))) (vector-set! cs 0 (make-comb scaler comb-len)) (vector-set! cs 1 (make-comb scaler (floor (* comb-len .75)))) (vector-set! cs 2 (make-comb scaler (floor (* comb-len 1.25)))) (set! cs (make-comb-bank cs)) (do ((k 0 (+ k 1))) ((= k grain-size)) (float-vector-set! grain k (comb-bank cs (float-vector-ref original-grain k)))))))))))) (definstrument (move-formants start file amp radius move-env num-formants) (let ((frms (make-vector num-formants)) (beg (seconds->samples start)) (dur (framples file))) (let ((end (+ beg dur)) (rd (make-readin file)) (menv (make-env move-env :length dur)) (amps (make-float-vector num-formants amp))) (let ((start-frq (env menv))) (do ((i 0 (+ i 1))) ((= i num-formants)) (set! (frms i) (make-formant (* (+ i 1) start-frq) radius)))) (let ((frms1 (make-formant-bank frms amps))) (do ((k beg (+ k 1))) ((= k end)) (let ((frq (env menv))) (outa k (formant-bank frms1 (readin rd))) (do ((i 0 (+ i 1)) (gfrq frq (+ gfrq frq))) ((= i num-formants)) (mus-set-formant-frequency (vector-ref frms i) gfrq)))))))) (define (test-filter flt) (let ((osc (make-oscil 0.0)) (samps (seconds->samples 0.5))) (let ((rmp (make-env '(0 0 1 1) :scaler (hz->radians samps) :length samps))) (with-sound () (do ((i 0 (+ i 1))) ((= i samps)) (outa i (flt (oscil osc (env rmp))))))))) (definstrument (flux start-time file frequency combs0 combs1 (scaler 0.99) (comb-len 32)) (let ((beg (seconds->samples start-time)) (len (framples file))) (let ((end (+ beg len)) (num-combs0 (length combs0)) (num-combs1 (length combs1))) (let ((cmbs0 (make-vector num-combs0)) (cmbs1 (make-vector num-combs1)) (osc (make-oscil frequency)) (rd (make-readin file))) (do ((k 0 (+ k 1))) ((= k num-combs0)) (set! (cmbs0 k) (make-comb scaler (floor (* comb-len (combs0 k)))))) (do ((k 0 (+ k 1))) ((= k num-combs1)) (set! (cmbs1 k) (make-comb scaler (floor (* comb-len (combs1 k)))))) (set! cmbs0 (make-comb-bank cmbs0)) (set! cmbs1 (make-comb-bank cmbs1)) (do ((i beg (+ i 1))) ((= i end)) (let ((interp (oscil osc)) (x (readin rd))) (outa i (+ (* interp (comb-bank cmbs0 x)) (* (- 1.0 interp) (comb-bank cmbs1 x)))))))))) ;;; ---------------- sndscm-osc ---------------- (defgenerator sndscm-osc freq phase fm res) (define (sndscm-osc gen fm) (let-set! gen 'fm fm) (with-let gen (set! res (sin phase)) (set! phase (+ phase freq fm)) res)) (definstrument (sndscm-osc-fm beg dur freq amp mc-ratio fm-index) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (carrier (make-sndscm-osc (hz->radians freq))) (modulator (make-sndscm-osc (hz->radians (* mc-ratio freq)))) (index (hz->radians (* freq mc-ratio fm-index)))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (sndscm-osc carrier (* index (sndscm-osc modulator 0.0)))))))) ;;; ---------------- sndscm-osc1 ---------------- (defgenerator (sndscm-osc1 :make-wrapper (lambda (gen) (set! (gen 'freq) (hz->radians (gen 'freq))) gen)) freq phase fm res) (define* (sndscm-osc1 gen fm) (let-set! gen 'fm fm) (with-let gen (set! res (sin phase)) (set! phase (+ phase freq fm)) res)) (definstrument (sndscm-osc1-fm beg dur freq amp mc-ratio (fm-index 1.0)) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (carrier (make-sndscm-osc1 freq)) (modulator (make-sndscm-osc1 (* mc-ratio freq))) (index (hz->radians (* freq mc-ratio fm-index)))) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (sndscm-osc1 carrier (* index (sndscm-osc1 modulator 0.0)))))))) ;;; ---------------- sndscm-osc2 ---------------- (defgenerator (sndscm-osc2 :make-wrapper (lambda (gen) (set! (gen 'freq) (hz->radians (gen 'freq))) gen) :methods (list (cons 'mus-frequency (dilambda (lambda (g) (radians->hz (g 'freq))) (lambda (g val) (set! (g 'freq) (hz->radians val))))) (cons 'mus-phase (dilambda (lambda (g) (g 'phase)) (lambda (g val) (set! (g 'phase) val)))) (cons 'mus-describe (lambda (g) (format #f "sndscm-osc2 freq: ~A, phase: ~A" (mus-frequency g) (mus-phase g)))))) freq phase fm res) (define* (sndscm-osc2 gen fm) (let-set! gen 'fm fm) (with-let gen (set! res (sin phase)) (set! phase (+ phase freq fm)) res)) (definstrument (sndscm-osc2-fm beg dur freq amp mc-ratio (fm-index 1.0)) (let ((start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (carrier (make-sndscm-osc2 freq)) (modulator (make-sndscm-osc2 (* mc-ratio freq))) (index (hz->radians (* freq mc-ratio fm-index)))) (if (fneq (mus-frequency carrier) freq) (format #t ";sndscm-osc2 (sclm23.scm) mus-frequency ~A: ~A ~A" (mus-describe carrier) (mus-frequency carrier) freq)) (do ((i start (+ i 1))) ((= i end)) (outa i (* amp (sndscm-osc2 carrier (* index (sndscm-osc2 modulator 0.0)))))))) ;;; -------- asymmetric FM (bes-i0 case) (defgenerator (dsp-asyfm :make-wrapper (lambda (gen) (set! (gen 'freq) (hz->radians (gen 'freq))) (set! (gen 'r1) (* 0.5 (gen 'index) (+ (gen 'r) (/ (gen 'r))))) (set! (gen 'r2) (* 0.5 (gen 'index) (- (gen 'r) (/ (gen 'r))))) (set! (gen 'r3) (* 0.5 (log (bes-i0 (* 2.0 (gen 'r1)))))) gen)) freq phase (ratio 1.0) (r 1.0) (index 1.0) input r1 r2 r3) (define dsp-asyfm-J (let ((documentation "(dsp-asyfm-J gen input) is the same as the CLM asymmetric-fm generator, set r != 1.0 to get the asymmetric spectra")) (lambda (gen input) (let-set! gen 'input input) (with-let gen (let* ((modphase (* ratio phase)) (result (* (exp (* r2 (cos modphase))) (sin (+ phase (* r1 (sin modphase))))))) (set! phase (+ phase input freq)) result))))) (define dsp-asyfm-I (let ((documentation "(dsp-asyfm-I gen input) is the I0 case of the asymmetric-fm generator (dsp.scm)")) (lambda (gen input) (let-set! gen 'input input) (with-let gen (let* ((modphase (* ratio phase)) (result (* (exp (- (* r1 (cos modphase)) r3)) (sin (+ phase (* r2 (sin modphase))))))) (set! phase (+ phase input freq)) result))))) (defgenerator (sndclm-expcs :make-wrapper (lambda (g) (if (<= (g 'et) 0.0) (set! (g 'et) 0.00001)) (set! (g 'frequency) (hz->radians (g 'frequency))) (set! (g 'sinht) (* 0.5 (sinh (g 'et)))) (set! (g 'cosht) (cosh (g 'et))) g)) frequency phase et sinht cosht fm) (define (sndclm-expcs gen fm) (let-set! gen 'fm fm) (with-let gen (let ((result (- (/ sinht (- cosht (cos phase))) 0.5))) (set! phase (+ phase frequency fm)) result))) ;;; -------------------------------------------------------------------------------- (define (simp-named-let beg dur freq amp) (let ((o (make-oscil freq)) (start (seconds->samples beg)) (end (seconds->samples (+ beg dur)))) (let loop ((i start)) (outa i (* amp (oscil o))) (if (< i end) (loop (+ i 1)))))) (define (simp-tail-recursion beg dur freq amp) (let ((o (make-oscil freq)) (start (seconds->samples beg)) (end (seconds->samples (+ beg dur)))) (define (simper i) (outa i (* amp (oscil o))) (if (< i end) (simper (+ i 1)))) (simper start))) ;;; -------------------------------------------------------------------------------- (define (test-documentation-instruments) (with-sound (:channels 2) (fmdoc-pm 0 10000 1000 .25 0.5 4) (fmdoc-fm 0 10000 1000 .25 0.5 4)) (with-sound () (fmdoc-fm-1 0 1.0 100 .5 1.0 4.0) (fmdoc-fm-1 1 1.0 400 .5 0.25 4.0) (fmdoc-fm-1 2 1.0 400 .5 1.1414 4.0) (fmdoc-fm-1 3 0.5 400 .5 1.0 5.0 '(0 0 20 1 40 .6 90 .5 100 0)) (fmdoc-fm-1 4 1.0 900 .5 1/3 2.0 '(0 0 6 .5 10 1 90 1 100 0)) (fmdoc-fm-1 5 1.0 500 .5 .2 1.5 '(0 0 6 .5 10 1 90 1 100 0)) (fmdoc-fm-1 6 1.0 900 .5 2/3 2 '(0 0 25 1 75 1 100 0)) (fmdoc-fm-2 7 1.0 100 .25 1.0 4 0 (* .5 pi)) (fmdoc-fm-2 8 1.0 100 .25 1.0 4.0 (* .5 pi) (* .5 pi)) (fmdoc-fm-3 9 2.0 100 .25 1.0 4.0 0 0 '(0 0 50 1 100 0) .02) (fmdoc-fm-4 10 1.0 1000 .25 .1 1.0 0 (* .5 pi) (* .5 pi) 0) (fmdoc-fm-5 11 2.0 440 .3 '(1 3 4) '(1.0 0.5 0.1) 0.0 '(0.0 0.0 0.0)) (fmdoc-violin 12 1.0 440 .1 2.5)) (with-sound () (fmdoc-cascade 0 1.0 400 .25 1.0 1.0 1.0 1.0 0) (fmdoc-cascade 1.5 1.0 400 .25 1.0 1.0 1.0 1.0 (* .5 pi)) (fmdoc-feedbk 2 1 100.0 1.0 1.0)) (with-sound () ; 1.2 (fmdoc-vox 0 1.0 220.0 0.5) (fmdoc-vox 1.5 1.0 110 .5 '(0.02 0.01 0.02) '(.9 .09 .01))) (with-sound (:srate 44100) (sndclmdoc-simp 0 22050 330 .1) (sndclmdoc-simp-1 0 1.0 440.0 0.1) (sndclmdoc-telephone 1.0 '(7 2 3 4 9 7 1)) (sndclmdoc-simp-4 2 2 440 .1 '(0 0 0.1 1.0 1.0 0.0))) (with-sound () (let ((sqr (make-square-wave 100))) ; test a square-wave generator (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (square-wave sqr)))) (let ((osc (make-my-oscil 440.0))) (do ((i 10000 (+ i 1))) ((= i 22050)) (outa i (my-oscil osc 0.0))))) (with-sound () (sndclmdoc-simp-5 0 10000 440 .1 '(0 0 1 1)) ; sweep up an octave (sndclmdoc-simple-fm 1 1 440 .1 2 1.0) (sndclmdoc-simple-add 2 1 220 .3) (sndclmdoc-mapenv 3 1 440 .4 '(0 0 50 1 75 0 86 .5 100 0))) (if (file-exists? "/home/bil/sf1/forest.aiff") (with-sound (:srate 44100) (sndclmdoc-looper 0 10 "/home/bil/sf1/forest.aiff" 1.0 0.5))) (with-sound () (sndclmdoc-bigbird 0 .05 1800 1800 .2 '(.00 .00 .40 1.00 .60 1.00 1.00 .0) ; freq env '(.00 .00 .25 1.00 .60 .70 .75 1.00 1.00 .0) ; amp env '(1 .5 2 1 3 .5 4 .1 5 .01))) ; bird song spectrum (with-sound (:srate 44100) (sndclmdoc-pqw 0 1 200.0 1000.0 '(2 .2 3 .3 6 .5)) (sndclmdoc-tritri 0 1 1000.0 0.5 0.1 0.01) ; sci-fi laser gun (sndclmdoc-tritri 1 1 4000.0 0.7 0.1 0.01)) ; a sparrow? (with-sound (:srate 22050) (sndclmdoc-shift-pitch 0 3 "oboe.snd" 1108.0)) ; 1.7 (let* ((sound "oboe.snd") ; 1.8 (mx (maxamp sound)) (dur (mus-sound-duration sound))) (with-sound (:scaled-to mx :srate 22050) (sndclmdoc-repitch 0 dur sound 554 1000))) (with-sound () (sndclmdoc-fofins 0 1 270 .2 .001 730 .6 1090 .3 2440 .1)) ; "Ahh" (with-sound () ; one of JC's favorite demos (sndclmdoc-fofins 0 4 270 .2 0.005 730 .6 1090 .3 2440 .1 '(0 0 40 0 75 .2 100 1) '(0 0 .5 1 3 .5 10 .2 20 .1 50 .1 60 .2 85 1 100 0)) (sndclmdoc-fofins 0 4 (* 6/5 540) .2 0.005 730 .6 1090 .3 2440 .1 '(0 0 40 0 75 .2 100 1) '(0 0 .5 .5 3 .25 6 .1 10 .1 50 .1 60 .2 85 1 100 0)) (sndclmdoc-fofins 0 4 135 .2 0.005 730 .6 1090 .3 2440 .1 '(0 0 40 0 75 .2 100 1) '(0 0 1 3 3 1 6 .2 10 .1 50 .1 60 .2 85 1 100 0))) (with-sound () (sndclmdoc-echo 0 60000 .5 1.0 "pistol.snd")) (with-sound () (sndclmdoc-zc 0 3 100 .1 20 100 .5) (sndclmdoc-zc 3.5 3 100 .1 90 100 .95)) (with-sound (:srate 22050) ; .93 (sndclmdoc-fir+comb 0 2 10000 .001 200) (sndclmdoc-fir+comb 2 2 1000 .0005 400) (sndclmdoc-fir+comb 4 2 3000 .001 300) (sndclmdoc-fir+comb 6 2 3000 .0005 1000)) (with-sound (:srate 22050) ; 1.3 (sndclmdoc-simple-src 0 4 1.0 0.5 '(0 1 1 2) "oboe.snd") (sndclmdoc-srcer 1 2 1.0 1 .3 20 "fyow.snd") (sndclmdoc-srcer 2 25 10.0 .01 1 10 "fyow.snd") (sndclmdoc-srcer 3 2 1.0 .9 .05 60 "oboe.snd") (sndclmdoc-srcer 4 2 1.0 1.0 .5 124 "oboe.snd") (sndclmdoc-srcer 5 10 10.0 .01 .2 8 "oboe.snd") (sndclmdoc-srcer 6 2 1.0 1 3 20 "oboe.snd")) (with-sound () (sndclmdoc-convins 0 2 (float-vector 1.0 0.5 0.25 0.125) "oboe.snd") ; same as fir-filter with those coeffs (sndclmdoc-granulate-sound "now.snd" 1 3.0 0 2.0) (sndclmdoc-grev 2 100000 2.0 "pistol.snd" 40000) (sndclmdoc-simple-pvoc 3 2.0 1.0 512 "oboe.snd") (sndclmdoc-simple-ina 4 1 .5 "oboe.snd") (sndclmdoc-env-sound "oboe.snd" 5 1.0 '(0 0 1 1 2 1 3 0))) (with-sound (:reverb jc-reverb :channels 2) (sndclmdoc-space "pistol.snd" 0 1 :distance-env '(0 1 1 2) :degree-env '(0 0 1 90))) (with-sound () (let ((gen (sndclmdoc-make-sum-of-odd-sines 440.0 10))) (sndclmdoc-sum-of-odd-sines gen 0.0)) (let ((gen (sndclmdoc-make-sinc-train 440.0))) (sndclmdoc-sinc-train gen)) (let ((gen (sndclmdoc-make-moving-max))) (sndclmdoc-moving-max gen 0.1)) (sndclmdoc-asy 0 .1 440 .1 1.0) (sndclmdoc-simple-table 1000) (sndclmdoc-simple-f2s .1 .1 .1 "oboe.snd") (sndclmdoc-simp-2 .2 .1 440 .1) (sndclmdoc-fm-table "oboe.snd" .3 .1 .1 1.0 10.0 10) (sndclmdoc-bl-saw .5 .1 440 10)) (with-sound (:channels 4) (let ((loc (make-locsig)) (osc (make-oscil 440.0))) (do ((i 0 (+ i 1))) ((= i 360)) (let ((start (* i 1000)) (stop (* (+ i 1) 1000))) (do ((j start (+ j 1))) ((= j stop)) (locsig loc j (* .5 (oscil osc))))) (move-locsig loc (* 1.0 i) 1.0)))) (with-sound (:channels 4) (sndclmdoc-simple-dloc 0 2 440 .5)) (with-sound () (when? 0 4 2.0 8.0 "1a.snd")) (with-sound () (move-formants 0 "oboe.snd" 2.0 0.99 '(0 1200 1.6 2400 2 1400) 4)) (test-filter (make-one-zero 0.5 0.5)) (test-filter (make-one-pole 0.1 -0.9)) (test-filter (make-two-pole 0.1 0.1 0.9)) (test-filter (make-two-zero 0.5 0.2 0.3)) (with-sound (:scaled-to .5) ; .875 (flux 0 "oboe.snd" 10.0 '(1.0 1.25 1.5) '(1.0 1.333 1.6)) (flux 2 "now.snd" 4.0 '(1.0 1.25 1.5) '(1.0 1.333 1.6 2.0 3.0)) (flux 4 "now.snd" 1.0 '(1.0 1.25 1.5) '(1.0 1.333 1.6 2.0 3.0) 0.995 20) (flux 6 "now.snd" 10.0 '(1.0 1.25 1.5) '(1.0 1.333 1.6 2.0 3.0) 0.99 10) (flux 8 "now.snd" 10.0 '(2.0) '(1.0 1.333 1.6 2.0 3.0) 0.99 120) (flux 10 "fyow.snd" .50 '(1.0 2.0 1.5) '(1.0 1.333 1.6 2.0 3.0) 0.99 120)) (with-sound () (sndscm-osc-fm 0 1 440 .1 1 1) (sndscm-osc1-fm 0 1 440 .1 1) (sndscm-osc2-fm 0 1 440.0 .1 1) (simp-named-let 0 .01 440 .1) (simp-tail-recursion 0 .01 440 .1)) (with-sound () (let ((gen (make-dsp-asyfm :freq 2000 :ratio .1))) (do ((i 0 (+ i 1))) ((= i 1000)) (outa i (dsp-asyfm-J gen 0.0)))) (let ((gen (make-dsp-asyfm :freq 2000 :ratio .1))) (do ((i 1000 (+ i 1))) ((= i 2000)) (outa i (* 0.5 (dsp-asyfm-I gen 0.0))))) (let ((gen (make-sndclm-expcs :frequency 100 :et 1.0))) (do ((i 2000 (+ i 1))) ((= i 12000)) (outa i (sndclm-expcs gen 0.0)))) (let ((gen (make-sndclm-expcs :frequency 100 :et 0.1)) (t-env (make-env '(0 .1 1 2) :length 10000))) (do ((i 12000 (+ i 1))) ((= i 22000)) (let ((et (env t-env))) (set! (gen 'sinht) (* 0.5 (sinh et))) (set! (gen 'cosht) (cosh et)) (outa i (sndclm-expcs gen 0.0)))))) (for-each close-sound (sounds))) snd-16.1/snd-gprefs.c0000644000076400007640000026330412512761107012561 0ustar bilbil#include "snd.h" #include "sndlib-strings.h" static GtkWidget *preferences_dialog = NULL, *load_path_text_widget = NULL; static bool prefs_unsaved = false; static char *prefs_saved_filename = NULL; static char *include_load_path = NULL; #define POWER_WAIT_TIME ((guint32)100) #define POWER_INITIAL_WAIT_TIME ((guint32)500) #define ERROR_WAIT_TIME ((guint32)5000) #if (!HAVE_GTK_WIDGET_GET_VISIBLE) #define Widget_Is_Sensitive(Wid) GTK_WIDGET_SENSITIVE(Wid) #else #define Widget_Is_Sensitive(Wid) gtk_widget_is_sensitive(Wid) #endif #define STARTUP_WIDTH 750 #define STARTUP_HEIGHT 800 typedef struct prefs_info { GtkWidget *label, *text, *arrow_up, *arrow_down, *arrow_right, *error, *toggle, *scale, *toggle2, *toggle3; GtkWidget *color, *rscl, *gscl, *bscl, *rtxt, *gtxt, *btxt, *list_menu, *radio_button; GtkAdjustment *adj, *radj, *gadj, *badj; GtkWidget **radio_buttons; bool got_error; timeout_result_t help_id, power_id, erase_id; const char *var_name, *saved_label; const char **values; int num_values, num_buttons; mus_float_t scale_max; GtkSizeGroup *color_texts, *color_scales; void (*toggle_func)(struct prefs_info *prf); void (*toggle2_func)(struct prefs_info *prf); void (*toggle3_func)(struct prefs_info *prf); void (*scale_func)(struct prefs_info *prf); void (*arrow_up_func)(struct prefs_info *prf); void (*arrow_down_func)(struct prefs_info *prf); void (*text_func)(struct prefs_info *prf); void (*color_func)(struct prefs_info *prf, float r, float g, float b); void (*reflect_func)(struct prefs_info *prf); void (*save_func)(struct prefs_info *prf, FILE *fd); const char *(*help_func)(struct prefs_info *prf); void (*clear_func)(struct prefs_info *prf); void (*revert_func)(struct prefs_info *prf); } prefs_info; static void prefs_set_dialog_title(const char *filename); static void reflect_key(prefs_info *prf, const char *key_name); static void save_key(prefs_info *prf, FILE *fd, char *(*binder)(char *key, bool c, bool m, bool x)); static void key_bind(prefs_info *prf, char *(*binder)(char *key, bool c, bool m, bool x)); static void clear_prefs_dialog_error(void); static void scale_set_color(prefs_info *prf, color_t pixel); static char *get_text(GtkWidget *w); static void set_text(GtkWidget *w, const char *value); static void post_prefs_error(const char *msg, prefs_info *data); #ifdef __GNUC__ static void va_post_prefs_error(const char *msg, prefs_info *data, ...) __attribute__ ((format (printf, 1, 0))); #else static void va_post_prefs_error(const char *msg, prefs_info *data, ...); #endif /* used in snd-prefs.c */ #define GET_TOGGLE(Toggle) gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(Toggle)) #define SET_TOGGLE(Toggle, Value) set_toggle_button(Toggle, Value, false, (void *)prf) #define GET_TEXT(Text) get_text(Text) #define SET_TEXT(Text, Val) set_text(Text, Val) #define free_TEXT(Val) #define TIMEOUT(Func) g_timeout_add_full(0, ERROR_WAIT_TIME, Func, (gpointer)prf, NULL) #define SET_SCALE(Value) ADJUSTMENT_SET_VALUE(prf->adj, Value) #define GET_SCALE() (ADJUSTMENT_VALUE(prf->adj) * prf->scale_max) #define SET_SENSITIVE(Wid, Val) gtk_widget_set_sensitive(Wid, Val) #define black_text(Prf) #define red_text(Prf) /* gdk_gc_set_foreground(Prf->label->style->black_gc, ss->red) no effect? */ static GtkWidget *make_basic_row(GtkWidget *box) { #if GTK_CHECK_VERSION(3, 0, 0) GtkWidget *row, *r; r = gtk_event_box_new(); /* not button! */ gtk_widget_set_hexpand(GTK_WIDGET(r), true); gtk_box_pack_start(GTK_BOX(box), r, false, false, 0); add_highlight_button_style(r); gtk_widget_show(r); row = gtk_hbox_new(false, 0); gtk_container_add(GTK_CONTAINER(r), row); gtk_widget_set_hexpand(GTK_WIDGET(row), true); gtk_widget_show(row); #else GtkWidget *row; row = gtk_hbox_new(false, 0); gtk_box_pack_start(GTK_BOX(box), row, false, false, 0); gtk_widget_show(row); #endif return(row); } static void set_radio_button(prefs_info *prf, int which) { if ((which >= 0) && (which < prf->num_buttons)) set_toggle_button(prf->radio_buttons[which], true, false, (void *)prf); } #define which_radio_button(Prf) get_user_int_data(G_OBJECT(Prf->radio_button)) #include "snd-prefs.c" static void sg_entry_set_text(GtkEntry* entry, const char *text) { if (text) gtk_entry_set_text(entry, (gchar *)text); else gtk_entry_set_text(entry, " "); } static void set_text(GtkWidget *w, const char *value) { if (GTK_IS_ENTRY(w)) sg_entry_set_text(GTK_ENTRY(w), value); else { if (GTK_IS_ENTRY(BIN_CHILD(w))) sg_entry_set_text(GTK_ENTRY(BIN_CHILD(w)), value); } } static char *get_text(GtkWidget *w) { if (GTK_IS_ENTRY(w)) return((char *)gtk_entry_get_text(GTK_ENTRY(w))); if (GTK_IS_ENTRY(BIN_CHILD(w))) return((char *)gtk_entry_get_text(GTK_ENTRY(BIN_CHILD(w)))); return(NULL); } /* ---------------- help strings ---------------- */ static bool prefs_dialog_error_is_posted = false; static void post_prefs_dialog_error(const char *message, void *data) { gtk_window_set_title(GTK_WINDOW(preferences_dialog), (char *)message); prefs_dialog_error_is_posted = (message != NULL); } static void clear_prefs_dialog_error(void) { if (prefs_dialog_error_is_posted) { prefs_dialog_error_is_posted = false; post_prefs_dialog_error(NULL, NULL); } } static void prefs_change_callback(GtkWidget *w, gpointer context) { prefs_unsaved = true; prefs_set_dialog_title(NULL); clear_prefs_dialog_error(); } static GtkSizeGroup *label_group; static GtkSizeGroup *widgets_group; static color_info *rscl_color, *gscl_color, *bscl_color; #define PACK_1 true #define PACK_2 false /* ---------------- row (main) label widget ---------------- */ static GtkWidget *make_row_label(prefs_info *prf, const char *label, GtkWidget *box) { GtkWidget *w; w = gtk_label_new(label); #if (!GTK_CHECK_VERSION(3, 0, 0)) gtk_misc_set_alignment(GTK_MISC(w), 1.0, 0.0); #else #if GTK_CHECK_VERSION(3, 14, 0) gtk_widget_set_halign(GTK_WIDGET(w), GTK_ALIGN_END); #else gtk_misc_set_alignment(GTK_MISC(w), 1.0, 0.5); #endif #endif gtk_size_group_add_widget(label_group, w); gtk_box_pack_start(GTK_BOX(box), w, PACK_1, PACK_2, 0); gtk_widget_show(w); prf->saved_label = label; return(w); } /* ---------------- row inner label widget ---------------- */ static void make_row_inner_label(prefs_info *prf, const char *label, GtkWidget *box) { GtkWidget *w; w = gtk_label_new(label); gtk_box_pack_start(GTK_BOX(box), w, false, false, 4); gtk_widget_show(w); } /* ---------------- row middle separator widget ---------------- */ static void make_row_middle_separator(GtkWidget *box) { GtkWidget *w; w = gtk_vseparator_new(); gtk_box_pack_start(GTK_BOX(box), w, false, false, 10); gtk_widget_show(w); } /* ---------------- row inner separator widget ---------------- */ static void make_row_inner_separator(int width, GtkWidget *box) { GtkWidget *w; w = gtk_hseparator_new(); gtk_box_pack_start(GTK_BOX(box), w, false, false, width); gtk_widget_show(w); } /* ---------------- row toggle widget ---------------- */ static GtkWidget *make_row_toggle_with_label(prefs_info *prf, bool current_value, GtkWidget *box, const char *label) { GtkWidget *w; if (label) w = gtk_check_button_new_with_label(label); else w = gtk_check_button_new(); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), current_value); gtk_box_pack_start(GTK_BOX(box), w, false, false, 0); /* was 10 */ gtk_widget_show(w); SG_SIGNAL_CONNECT(w, "toggled", prefs_change_callback, NULL); return(w); } static GtkWidget *make_row_toggle(prefs_info *prf, bool current_value, GtkWidget *box) { return(make_row_toggle_with_label(prf, current_value, box, NULL)); } /* ---------------- error widget ---------------- */ static GtkWidget *make_row_error(prefs_info *prf, GtkWidget *box) { GtkWidget *w; w = gtk_label_new(""); gtk_box_pack_end(GTK_BOX(box), w, true, false, 0); gtk_widget_show(w); return(w); } /* ---------------- row arrows ---------------- */ static gboolean remove_arrow_func(GtkWidget *w, GdkEventButton *ev, gpointer context) { prefs_info *prf = (prefs_info *)context; if (prf->power_id != 0) { g_source_remove(prf->power_id); prf->power_id = 0; } return(false); } static gint arrow_func_up(gpointer context) { prefs_info *prf = (prefs_info *)context; if (Widget_Is_Sensitive(prf->arrow_up)) { if (prf->arrow_up_func) { (*(prf->arrow_up_func))(prf); prf->power_id = g_timeout_add_full(0, POWER_WAIT_TIME, arrow_func_up, (gpointer)prf, NULL); } else prf->power_id = 0; } return(0); } static gint arrow_func_down(gpointer context) { prefs_info *prf = (prefs_info *)context; if (Widget_Is_Sensitive(prf->arrow_down)) { if (prf->arrow_down_func) { (*(prf->arrow_down_func))(prf); prf->power_id = g_timeout_add_full(0, POWER_WAIT_TIME, arrow_func_down, (gpointer)prf, NULL); } else prf->power_id = 0; } return(0); } static gboolean call_arrow_down_press(GtkWidget *w, GdkEventButton *ev, gpointer context) { prefs_info *prf = (prefs_info *)context; if ((prf) && (prf->arrow_down_func)) { (*(prf->arrow_down_func))(prf); if (Widget_Is_Sensitive(w)) prf->power_id = g_timeout_add_full(0, POWER_INITIAL_WAIT_TIME, arrow_func_down, (gpointer)prf, NULL); else prf->power_id = 0; } return(false); } static gboolean call_arrow_up_press(GtkWidget *w, GdkEventButton *ev, gpointer context) { prefs_info *prf = (prefs_info *)context; if ((prf) && (prf->arrow_up_func)) { (*(prf->arrow_up_func))(prf); if (Widget_Is_Sensitive(w)) prf->power_id = g_timeout_add_full(0, POWER_INITIAL_WAIT_TIME, arrow_func_up, (gpointer)prf, NULL); else prf->power_id = 0; } return(false); } static GtkWidget *make_row_arrows(prefs_info *prf, GtkWidget *box) { GtkWidget *ev_up, *ev_down, *up, *down; #if GTK_CHECK_VERSION(3, 14, 0) GtkIconTheme *icon_theme; icon_theme = gtk_icon_theme_get_default(); #endif ev_down = gtk_event_box_new(); gtk_box_pack_start(GTK_BOX(box), ev_down, false, false, 0); gtk_widget_show(ev_down); #if GTK_CHECK_VERSION(3, 14, 0) down = gtk_image_new_from_pixbuf(gtk_icon_theme_load_icon(icon_theme, "pan-down-symbolic", 16, (GtkIconLookupFlags)0, NULL)); #else down = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_ETCHED_OUT); #endif gtk_container_add(GTK_CONTAINER(ev_down), down); gtk_widget_show(down); ev_up = gtk_event_box_new(); gtk_box_pack_start(GTK_BOX(box), ev_up, false, false, 0); gtk_widget_show(ev_up); #if GTK_CHECK_VERSION(3, 14, 0) up = gtk_image_new_from_pixbuf(gtk_icon_theme_load_icon(icon_theme, "pan-up-symbolic", 16, (GtkIconLookupFlags)0, NULL)); #else up = gtk_arrow_new(GTK_ARROW_UP, GTK_SHADOW_ETCHED_OUT); #endif gtk_container_add(GTK_CONTAINER(ev_up), up); gtk_widget_show(up); prf->arrow_up = up; prf->arrow_down = down; SG_SIGNAL_CONNECT(ev_down, "button_press_event", call_arrow_down_press, (gpointer)prf); SG_SIGNAL_CONNECT(ev_down, "button_release_event", remove_arrow_func, (gpointer)prf); SG_SIGNAL_CONNECT(ev_up, "button_press_event", call_arrow_up_press, (gpointer)prf); SG_SIGNAL_CONNECT(ev_up, "button_release_event", remove_arrow_func, (gpointer)prf); SG_SIGNAL_CONNECT(ev_down, "button_press_event", prefs_change_callback, NULL); SG_SIGNAL_CONNECT(ev_up, "button_press_event", prefs_change_callback, NULL); return(up); } /* ---------------- bool row ---------------- */ static void call_toggle_func(GtkWidget *w, gpointer context) { prefs_info *prf = (prefs_info *)context; if ((prf) && (prf->toggle_func)) (*(prf->toggle_func))(prf); } static prefs_info *prefs_row_with_toggle(const char *label, const char *varname, bool current_value, GtkWidget *box, void (*toggle_func)(prefs_info *prf)) { prefs_info *prf = NULL; GtkWidget *hb, *row; prf = (prefs_info *)calloc(1, sizeof(prefs_info)); prf->var_name = varname; prf->toggle_func = toggle_func; row = make_basic_row(box); prf->label = make_row_label(prf, label, row); hb = gtk_hbox_new(false, 0); gtk_size_group_add_widget(widgets_group, hb); gtk_box_pack_start(GTK_BOX(row), hb, false, false, 0); gtk_widget_show(hb); make_row_middle_separator(hb); prf->toggle = make_row_toggle(prf, current_value, hb); SG_SIGNAL_CONNECT(prf->toggle, "toggled", call_toggle_func, (gpointer)prf); return(prf); } /* ---------------- two toggles ---------------- */ static void call_toggle2_func(GtkWidget *w, gpointer context) { prefs_info *prf = (prefs_info *)context; if ((prf) && (prf->toggle2_func)) (*(prf->toggle2_func))(prf); } static prefs_info *prefs_row_with_two_toggles(const char *label, const char *varname, const char *label1, bool value1, const char *label2, bool value2, GtkWidget *box, void (*toggle_func)(prefs_info *prf), void (*toggle2_func)(prefs_info *prf)) { prefs_info *prf = NULL; GtkWidget *row, *hb; prf = (prefs_info *)calloc(1, sizeof(prefs_info)); prf->var_name = varname; prf->toggle_func = toggle_func; prf->toggle2_func = toggle2_func; row = make_basic_row(box); prf->label = make_row_label(prf, label, row); hb = gtk_hbox_new(false, 0); gtk_size_group_add_widget(widgets_group, hb); gtk_box_pack_start(GTK_BOX(row), hb, false, false, 0); gtk_widget_show(hb); make_row_middle_separator(hb); prf->toggle = make_row_toggle_with_label(prf, value1, hb, label1); make_row_inner_separator(20, hb); prf->toggle2 = make_row_toggle_with_label(prf, value2, hb, label2); SG_SIGNAL_CONNECT(prf->toggle, "toggled", call_toggle_func, (gpointer)prf); SG_SIGNAL_CONNECT(prf->toggle2, "toggled", call_toggle2_func, (gpointer)prf); return(prf); } /* ---------------- toggle with text ---------------- */ /* see commentary in snd-xprefs.c */ typedef struct { bool text_focussed, text_changed; prefs_info *prf; } text_info; static void text_change_callback(GtkWidget *w, gpointer context) { text_info *data = (text_info *)context; if (data->text_focussed) /* try to omit non-user actions that change the value */ data->text_changed = true; } static void text_activate_callback(GtkWidget *w, gpointer context) { text_info *data = (text_info *)context; data->text_changed = false; } static void text_grab_focus_callback(GtkWidget *w, GdkEventCrossing *ev, gpointer context) { text_info *data = (text_info *)context; if (with_pointer_focus(ss)) goto_window(w); data->text_focussed = true; } static void text_lose_focus_callback(GtkWidget *w, GdkEventCrossing *ev, gpointer context) { text_info *data = (text_info *)context; if ((data->text_focussed) && (data->text_changed) && (data->prf) && (data->prf->text_func)) { (*(data->prf->text_func))(data->prf); data->text_changed = false; } } static void call_text_func(GtkWidget *w, gpointer context) { prefs_info *prf = (prefs_info *)context; if ((prf) && (prf->text_func)) (*(prf->text_func))(prf); } static GtkWidget *make_row_text(prefs_info *prf, const char *text_value, int cols, GtkWidget *box) { int len; GtkWidget *w; GtkSettings *settings; text_info *info; len = mus_strlen(text_value); w = gtk_entry_new(); gtk_entry_set_has_frame(GTK_ENTRY(w), true); if (text_value) sg_entry_set_text(GTK_ENTRY(w), text_value); gtk_entry_set_has_frame(GTK_ENTRY(w), false); if (cols > 0) gtk_entry_set_width_chars(GTK_ENTRY(w), cols); else { if (len > 24) /* sigh... */ gtk_entry_set_width_chars(GTK_ENTRY(w), len); } gtk_editable_set_editable(GTK_EDITABLE(w), true); settings = gtk_widget_get_settings(w); g_object_set(settings, "gtk-entry-select-on-focus", false, NULL); gtk_box_pack_start(GTK_BOX(box), w, false, false, 0); gtk_widget_show(w); info = (text_info *)calloc(1, sizeof(text_info)); info->prf = prf; SG_SIGNAL_CONNECT(w, "enter_notify_event", text_grab_focus_callback, (gpointer)info); SG_SIGNAL_CONNECT(w, "leave_notify_event", text_lose_focus_callback, (gpointer)info); SG_SIGNAL_CONNECT(w, "changed", text_change_callback, (gpointer)info); SG_SIGNAL_CONNECT(w, "activate", text_activate_callback, (gpointer)info); return(w); } static prefs_info *prefs_row_with_toggle_with_text(const char *label, const char *varname, bool current_value, const char *text_label, const char *text_value, int cols, GtkWidget *box, void (*toggle_func)(prefs_info *prf), void (*text_func)(prefs_info *prf)) { prefs_info *prf = NULL; GtkWidget *hb, *row; prf = (prefs_info *)calloc(1, sizeof(prefs_info)); prf->var_name = varname; prf->toggle_func = toggle_func; prf->text_func = text_func; row = make_basic_row(box); prf->label = make_row_label(prf, label, row); hb = gtk_hbox_new(false, 0); gtk_size_group_add_widget(widgets_group, hb); gtk_box_pack_start(GTK_BOX(row), hb, false, false, 0); gtk_widget_show(hb); make_row_middle_separator(hb); prf->toggle = make_row_toggle(prf, current_value, hb); make_row_inner_separator(16, hb); make_row_inner_label(prf, text_label, hb); prf->text= make_row_text(prf, text_value, cols, hb); SG_SIGNAL_CONNECT(prf->toggle, "toggled", call_toggle_func, (gpointer)prf); SG_SIGNAL_CONNECT(prf->text, "activate", call_text_func, (gpointer)prf); return(prf); } static prefs_info *prefs_row_with_toggle_with_two_texts(const char *label, const char *varname, bool current_value, const char *label1, const char *text1, const char *label2, const char *text2, int cols, GtkWidget *box, void (*toggle_func)(prefs_info *prf), void (*text_func)(prefs_info *prf)) { prefs_info *prf = NULL; GtkWidget *hb, *row; prf = (prefs_info *)calloc(1, sizeof(prefs_info)); prf->var_name = varname; prf->toggle_func = toggle_func; prf->text_func = text_func; row = make_basic_row(box); prf->label = make_row_label(prf, label, row); hb = gtk_hbox_new(false, 0); gtk_size_group_add_widget(widgets_group, hb); gtk_box_pack_start(GTK_BOX(row), hb, false, false, 0); gtk_widget_show(hb); make_row_middle_separator(hb); prf->toggle = make_row_toggle(prf, current_value, hb); make_row_inner_separator(16, hb); make_row_inner_label(prf, label1, hb); prf->text= make_row_text(prf, text1, cols, hb); make_row_inner_label(prf, label2, hb); prf->rtxt= make_row_text(prf, text2, cols, hb); SG_SIGNAL_CONNECT(prf->toggle, "toggled", call_toggle_func, (gpointer)prf); SG_SIGNAL_CONNECT(prf->text, "activate", call_text_func, (gpointer)prf); SG_SIGNAL_CONNECT(prf->rtxt, "activate", call_text_func, (gpointer)prf); return(prf); } /* ---------------- text with toggle ---------------- */ static prefs_info *prefs_row_with_text_with_toggle(const char *label, const char *varname, bool current_value, const char *toggle_label, const char *text_value, int cols, GtkWidget *box, void (*toggle_func)(prefs_info *prf), void (*text_func)(prefs_info *prf)) { prefs_info *prf = NULL; GtkWidget *hb, *row; prf = (prefs_info *)calloc(1, sizeof(prefs_info)); prf->var_name = varname; prf->toggle_func = toggle_func; prf->text_func = text_func; row = make_basic_row(box); prf->label = make_row_label(prf, label, row); hb = gtk_hbox_new(false, 0); gtk_size_group_add_widget(widgets_group, hb); gtk_box_pack_start(GTK_BOX(row), hb, false, false, 0); gtk_widget_show(hb); make_row_middle_separator(hb); prf->text = make_row_text(prf, text_value, cols, hb); make_row_inner_separator(8, hb); make_row_inner_label(prf, toggle_label, hb); prf->toggle = make_row_toggle(prf, current_value, hb); SG_SIGNAL_CONNECT(prf->toggle, "toggled", call_toggle_func, (gpointer)prf); SG_SIGNAL_CONNECT(prf->text, "activate", call_text_func, (gpointer)prf); return(prf); } /* ---------------- text with three toggle ---------------- */ static prefs_info *prefs_row_with_text_and_three_toggles(const char *label, const char *varname, const char *text_label, int cols, const char *toggle1_label, const char *toggle2_label, const char *toggle3_label, const char *text_value, bool toggle1_value, bool toggle2_value, bool toggle3_value, GtkWidget *box, void (*text_func)(prefs_info *prf)) { prefs_info *prf = NULL; GtkWidget *hb, *row; prf = (prefs_info *)calloc(1, sizeof(prefs_info)); prf->var_name = varname; prf->text_func = text_func; row = make_basic_row(box); prf->label = make_row_label(prf, label, row); hb = gtk_hbox_new(false, 0); gtk_size_group_add_widget(widgets_group, hb); gtk_box_pack_start(GTK_BOX(row), hb, false, false, 0); gtk_widget_show(hb); make_row_middle_separator(hb); make_row_inner_label(prf, text_label, hb); prf->text = make_row_text(prf, text_value, cols, hb); make_row_inner_separator(12, hb); make_row_inner_label(prf, toggle1_label, hb); prf->toggle = make_row_toggle(prf, toggle1_value, hb); make_row_inner_separator(4, hb); make_row_inner_label(prf, toggle2_label, hb); prf->toggle2 = make_row_toggle(prf, toggle2_value, hb); make_row_inner_separator(4, hb); make_row_inner_label(prf, toggle3_label, hb); prf->toggle3 = make_row_toggle(prf, toggle3_value, hb); SG_SIGNAL_CONNECT(prf->text, "activate", call_text_func, (gpointer)prf); return(prf); } /* ---------------- radio row ---------------- */ static void call_radio_func(GtkWidget *w, gpointer context) { prefs_info *prf = (prefs_info *)context; if ((prf) && (prf->toggle_func)) { prf->radio_button = w; (*(prf->toggle_func))(prf); } } static GtkWidget *make_row_radio_box(prefs_info *prf, const char **labels, int num_labels, int current_value, GtkWidget *box) { GtkWidget *w, *current_button; int i; w = gtk_hbox_new(false, 0); gtk_box_pack_start(GTK_BOX(box), w, false, false, 0); gtk_widget_show(w); prf->radio_buttons = (GtkWidget **)calloc(num_labels, sizeof(GtkWidget *)); prf->num_buttons = num_labels; for (i = 0; i < num_labels; i++) { if (i == 0) current_button = gtk_radio_button_new_with_label(NULL, labels[i]); else current_button = gtk_radio_button_new_with_label(gtk_radio_button_get_group(GTK_RADIO_BUTTON(prf->radio_buttons[0])), labels[i]); prf->radio_buttons[i] = current_button; gtk_box_pack_start(GTK_BOX(w), current_button, false, false, 0); set_user_int_data(G_OBJECT(current_button), i); gtk_widget_show(current_button); SG_SIGNAL_CONNECT(current_button, "clicked", call_radio_func, (gpointer)prf); SG_SIGNAL_CONNECT(current_button, "clicked", prefs_change_callback, NULL); } if (current_value != -1) set_toggle_button(prf->radio_buttons[current_value], true, false, (void *)prf); return(w); } static prefs_info *prefs_row_with_radio_box(const char *label, const char *varname, const char **labels, int num_labels, int current_value, GtkWidget *box, void (*toggle_func)(prefs_info *prf)) { prefs_info *prf = NULL; GtkWidget *hb, *row; prf = (prefs_info *)calloc(1, sizeof(prefs_info)); prf->var_name = varname; prf->toggle_func = toggle_func; row = make_basic_row(box); prf->label = make_row_label(prf, label, row); hb = gtk_hbox_new(false, 0); gtk_size_group_add_widget(widgets_group, hb); gtk_box_pack_start(GTK_BOX(row), hb, false, false, 0); gtk_widget_show(hb); make_row_middle_separator(hb); prf->toggle = make_row_radio_box(prf, labels, num_labels, current_value, hb); return(prf); } static prefs_info *prefs_row_with_radio_box_and_number(const char *label, const char *varname, const char **labels, int num_labels, int current_value, const char *text_value, int text_cols, GtkWidget *box, void (*toggle_func)(prefs_info *prf), void (*arrow_up_func)(prefs_info *prf), void (*arrow_down_func)(prefs_info *prf), void (*text_func)(prefs_info *prf)) { prefs_info *prf = NULL; GtkWidget *row, *hb; prf = (prefs_info *)calloc(1, sizeof(prefs_info)); prf->var_name = varname; prf->toggle_func = toggle_func; prf->text_func = text_func; prf->arrow_up_func = arrow_up_func; prf->arrow_down_func = arrow_down_func; row = make_basic_row(box); prf->label = make_row_label(prf, label, row); hb = gtk_hbox_new(false, 0); gtk_size_group_add_widget(widgets_group, hb); gtk_box_pack_start(GTK_BOX(row), hb, false, false, 0); gtk_widget_show(hb); make_row_middle_separator(hb); prf->toggle = make_row_radio_box(prf, labels, num_labels, current_value, hb); prf->text = make_row_text(prf, text_value, text_cols, hb); prf->arrow_up = make_row_arrows(prf, hb); SG_SIGNAL_CONNECT(prf->text, "activate", call_text_func, (gpointer)prf); return(prf); } /* ---------------- scale row ---------------- */ static void call_scale_func(GtkAdjustment *w, gpointer context) { prefs_info *prf = (prefs_info *)context; if ((prf) && (prf->scale_func)) (*(prf->scale_func))(prf); } static void call_scale_text_func(GtkWidget *w, gpointer context) { prefs_info *prf = (prefs_info *)context; if ((prf) && (prf->text_func)) (*(prf->text_func))(prf); } static void prefs_scale_callback(GtkWidget *w, gpointer context) { prefs_info *prf = (prefs_info *)context; float_to_textfield(prf->text, ADJUSTMENT_VALUE(prf->adj) * prf->scale_max); } static prefs_info *prefs_row_with_scale(const char *label, const char *varname, mus_float_t max_val, mus_float_t current_value, GtkWidget *box, void (*scale_func)(prefs_info *prf), void (*text_func)(prefs_info *prf)) { prefs_info *prf = NULL; GtkWidget *hb, *row; char *str; prf = (prefs_info *)calloc(1, sizeof(prefs_info)); prf->var_name = varname; prf->scale_max = max_val; row = make_basic_row(box); prf->label = make_row_label(prf, label, row); hb = gtk_hbox_new(false, 0); gtk_size_group_add_widget(widgets_group, hb); gtk_box_pack_start(GTK_BOX(row), hb, false, false, 0); gtk_widget_show(hb); make_row_middle_separator(hb); str = (char *)calloc(12, sizeof(char)); snprintf(str, 12, "%.3f", current_value); prf->text = make_row_text(prf, str, 6, hb); free(str); prf->adj = (GtkAdjustment *)gtk_adjustment_new(current_value /max_val, 0.0, 1.01, 0.001, 0.01, .01); prf->scale = gtk_hscale_new(GTK_ADJUSTMENT(prf->adj)); gtk_box_pack_start(GTK_BOX(hb), prf->scale, true, true, 4); gtk_widget_show(prf->scale); gtk_range_set_update_policy(GTK_RANGE(GTK_SCALE(prf->scale)), GTK_UPDATE_CONTINUOUS); gtk_scale_set_draw_value(GTK_SCALE(prf->scale), false); prf->scale_func = scale_func; prf->text_func = text_func; SG_SIGNAL_CONNECT(prf->scale, "value_changed", call_scale_func, (gpointer)prf); SG_SIGNAL_CONNECT(prf->scale, "value_changed", prefs_change_callback, NULL); SG_SIGNAL_CONNECT(prf->scale, "value_changed", prefs_scale_callback, (gpointer)prf); SG_SIGNAL_CONNECT(prf->text, "activate", call_scale_text_func, (gpointer)prf); return(prf); } /* ---------------- text row ---------------- */ static prefs_info *prefs_row_with_text(const char *label, const char *varname, const char *value, GtkWidget *box, void (*text_func)(prefs_info *prf)) { prefs_info *prf = NULL; GtkWidget *hb, *row; prf = (prefs_info *)calloc(1, sizeof(prefs_info)); prf->var_name = varname; row = make_basic_row(box); prf->label = make_row_label(prf, label, row); hb = gtk_hbox_new(false, 0); gtk_size_group_add_widget(widgets_group, hb); gtk_box_pack_start(GTK_BOX(row), hb, false, false, 0); gtk_widget_show(hb); make_row_middle_separator(hb); prf->text = make_row_text(prf, value, 0, hb); prf->text_func = text_func; SG_SIGNAL_CONNECT(prf->text, "activate", call_text_func, (gpointer)prf); return(prf); } /* ---------------- two texts in a row ---------------- */ static prefs_info *prefs_row_with_two_texts(const char *label, const char *varname, const char *label1, const char *text1, const char *label2, const char *text2, int cols, GtkWidget *box, void (*text_func)(prefs_info *prf)) { prefs_info *prf = NULL; GtkWidget *hb, *row; prf = (prefs_info *)calloc(1, sizeof(prefs_info)); prf->var_name = varname; row = make_basic_row(box); prf->label = make_row_label(prf, label, row); hb = gtk_hbox_new(false, 0); gtk_size_group_add_widget(widgets_group, hb); gtk_box_pack_start(GTK_BOX(row), hb, false, false, 0); gtk_widget_show(hb); make_row_middle_separator(hb); make_row_inner_label(prf, label1, hb); prf->text = make_row_text(prf, text1, cols, hb); make_row_inner_label(prf, label2, hb); prf->rtxt = make_row_text(prf, text2, cols, hb); prf->text_func = text_func; SG_SIGNAL_CONNECT(prf->text, "activate", call_text_func, (gpointer)prf); SG_SIGNAL_CONNECT(prf->rtxt, "activate", call_text_func, (gpointer)prf); return(prf); } /* ---------------- number row ---------------- */ static prefs_info *prefs_row_with_number(const char *label, const char *varname, const char *value, int cols, GtkWidget *box, void (*arrow_up_func)(prefs_info *prf), void (*arrow_down_func)(prefs_info *prf), void (*text_func)(prefs_info *prf)) { prefs_info *prf = NULL; GtkWidget *hb, *row; prf = (prefs_info *)calloc(1, sizeof(prefs_info)); prf->var_name = varname; row = make_basic_row(box); prf->label = make_row_label(prf, label, row); hb = gtk_hbox_new(false, 0); gtk_size_group_add_widget(widgets_group, hb); gtk_box_pack_start(GTK_BOX(row), hb, false, false, 0); gtk_widget_show(hb); make_row_middle_separator(hb); prf->text = make_row_text(prf, value, cols, hb); prf->arrow_up = make_row_arrows(prf, hb); prf->error = make_row_error(prf, hb); prf->text_func = text_func; prf->arrow_up_func = arrow_up_func; prf->arrow_down_func = arrow_down_func; SG_SIGNAL_CONNECT(prf->text, "activate", call_text_func, (gpointer)prf); return(prf); } /* ---------------- list row ---------------- */ static prefs_info *prefs_row_with_list(const char *label, const char *varname, const char *value, const char **values, int num_values, GtkWidget *box, void (*text_func)(prefs_info *prf), char *(*completion_func)(widget_t w, const char *text, void *context), void *completion_context) { int i; prefs_info *prf = NULL; GtkWidget *hb, *row; prf = (prefs_info *)calloc(1, sizeof(prefs_info)); prf->var_name = varname; row = make_basic_row(box); prf->label = make_row_label(prf, label, row); hb = gtk_hbox_new(false, 0); gtk_size_group_add_widget(widgets_group, hb); gtk_box_pack_start(GTK_BOX(row), hb, false, false, 0); gtk_widget_show(hb); make_row_middle_separator(hb); #if GTK_CHECK_VERSION(3, 0, 0) prf->text = gtk_combo_box_text_new_with_entry(); for (i = 0; i < num_values; i++) gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(prf->text), (values[i]) ? values[i] : " "); #else prf->text = gtk_combo_box_entry_new_text(); for (i = 0; i < num_values; i++) gtk_combo_box_append_text(GTK_COMBO_BOX(prf->text), (values[i]) ? values[i] : " "); #endif sg_entry_set_text(GTK_ENTRY(BIN_CHILD(prf->text)), value); gtk_box_pack_start(GTK_BOX(hb), prf->text, false, false, 4); gtk_widget_show(prf->text); prf->error = make_row_error(prf, hb); prf->text_func = text_func; SG_SIGNAL_CONNECT(prf->text, "changed", call_text_func, (gpointer)prf); SG_SIGNAL_CONNECT(prf->text, "changed", prefs_change_callback, NULL); return(prf); } /* ---------------- color selector row(s) ---------------- */ static void pixel_to_rgb(color_t pix, float *r, float *g, float *b) { (*r) = rgb_to_float(pix->red); (*g) = rgb_to_float(pix->green); (*b) = rgb_to_float(pix->blue); } #if GTK_CHECK_VERSION(3, 0, 0) static void display_color(GtkWidget *w, color_t pixel) { cairo_t *cr; cr = gdk_cairo_create(WIDGET_TO_WINDOW(w)); cairo_set_source_rgba(cr, pixel->red, pixel->green, pixel->blue, pixel->alpha); cairo_rectangle(cr, 0, 0, widget_width(w), widget_height(w)); cairo_fill(cr); cairo_destroy(cr); } #endif static void scale_set_color(prefs_info *prf, color_t pixel) { float r = 0.0, g = 0.0, b = 0.0; pixel_to_rgb(pixel, &r, &g, &b); float_to_textfield(prf->rtxt, r); ADJUSTMENT_SET_VALUE(prf->radj, r); float_to_textfield(prf->gtxt, g); ADJUSTMENT_SET_VALUE(prf->gadj, g); float_to_textfield(prf->btxt, b); ADJUSTMENT_SET_VALUE(prf->badj, b); #if GTK_CHECK_VERSION(3, 0, 0) display_color(prf->color, pixel); #else widget_modify_bg(prf->color, GTK_STATE_NORMAL, pixel); #endif } static void reflect_color(prefs_info *prf) { mus_float_t r, g, b; color_info *current_color; r = ADJUSTMENT_VALUE(prf->radj); g = ADJUSTMENT_VALUE(prf->gadj); b = ADJUSTMENT_VALUE(prf->badj); current_color = rgb_to_color(r, g, b); #if GTK_CHECK_VERSION(3, 0, 0) display_color(prf->color, current_color); #else widget_modify_bg(prf->color, GTK_STATE_NORMAL, current_color); #endif float_to_textfield(prf->rtxt, r); float_to_textfield(prf->gtxt, g); float_to_textfield(prf->btxt, b); } static void prefs_color_callback(GtkWidget *w, gpointer context) { reflect_color((prefs_info *)context); } static gint unpost_color_error(gpointer data) { prefs_info *prf = (prefs_info *)data; prf->got_error = false; gtk_label_set_text(GTK_LABEL(prf->label), prf->saved_label); reflect_color(prf); return(0); } static void errors_to_color_text(const char *msg, void *data) { prefs_info *prf = (prefs_info *)data; prf->got_error = true; gtk_label_set_text(GTK_LABEL(prf->label), msg); TIMEOUT(unpost_color_error); } static void prefs_r_callback(GtkWidget *w, gpointer context) { prefs_info *prf = (prefs_info *)context; char *str; float r; str = (char *)gtk_entry_get_text(GTK_ENTRY(w)); redirect_errors_to(errors_to_color_text, context); r = (float)string_to_mus_float_t(str, 0.0, "red amount"); redirect_errors_to(NULL, NULL); if (!(prf->got_error)) { ADJUSTMENT_SET_VALUE(prf->radj, (float)mus_fclamp(0.0, r, 1.0)); reflect_color(prf); } } static void prefs_g_callback(GtkWidget *w, gpointer context) { prefs_info *prf = (prefs_info *)context; char *str; float r; str = (char *)gtk_entry_get_text(GTK_ENTRY(w)); redirect_errors_to(errors_to_color_text, context); r = (float)string_to_mus_float_t(str, 0.0, "green amount"); redirect_errors_to(NULL, NULL); if (!(prf->got_error)) { ADJUSTMENT_SET_VALUE(prf->gadj, (float)mus_fclamp(0.0, r, 1.0)); reflect_color(prf); } } static void prefs_b_callback(GtkWidget *w, gpointer context) { prefs_info *prf = (prefs_info *)context; char *str; float r; str = (char *)gtk_entry_get_text(GTK_ENTRY(w)); redirect_errors_to(errors_to_color_text, context); r = (float)string_to_mus_float_t(str, 0.0, "blue amount"); redirect_errors_to(NULL, NULL); if (!(prf->got_error)) { ADJUSTMENT_SET_VALUE(prf->badj, (float)mus_fclamp(0.0, r, 1.0)); reflect_color(prf); } } static void prefs_call_color_func_callback(GtkWidget *w, gpointer context) { prefs_info *prf = (prefs_info *)context; if ((prf) && (prf->color_func)) { float r, g, b; r = ADJUSTMENT_VALUE(prf->radj); g = ADJUSTMENT_VALUE(prf->gadj); b = ADJUSTMENT_VALUE(prf->badj); (*(prf->color_func))(prf, r, g, b); } } #if GTK_CHECK_VERSION(3, 0, 0) static gboolean drawer_expose(GtkWidget *w, GdkEventExpose *ev, gpointer data) { prefs_info *prf = (prefs_info *)data; mus_float_t r, g, b; color_info *current_color; r = ADJUSTMENT_VALUE(prf->radj); g = ADJUSTMENT_VALUE(prf->gadj); b = ADJUSTMENT_VALUE(prf->badj); current_color = rgb_to_color(r, g, b); display_color(prf->color, current_color); return(false); } #endif static prefs_info *prefs_color_selector_row(const char *label, const char *varname, color_t current_pixel, GtkWidget *box, void (*color_func)(prefs_info *prf, float r, float g, float b)) { prefs_info *prf = NULL; GtkWidget *hb, *row, *row2, *sep3; float r = 0.0, g = 0.0, b = 0.0; prf = (prefs_info *)calloc(1, sizeof(prefs_info)); prf->var_name = varname; pixel_to_rgb(current_pixel, &r, &g, &b); /* first row */ row = make_basic_row(box); prf->label = make_row_label(prf, label, row); hb = gtk_hbox_new(false, 0); gtk_size_group_add_widget(widgets_group, hb); gtk_box_pack_start(GTK_BOX(row), hb, false, false, 0); gtk_widget_show(hb); make_row_middle_separator(hb); { GtkWidget *frame; frame = gtk_frame_new(NULL); gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN); prf->color_texts = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); gtk_box_pack_start(GTK_BOX(hb), frame, false, false, 4); gtk_size_group_add_widget(prf->color_texts, frame); prf->color = gtk_drawing_area_new(); gtk_container_add(GTK_CONTAINER(frame), prf->color); #if GTK_CHECK_VERSION(3, 0, 0) SG_SIGNAL_CONNECT(prf->color, DRAW_SIGNAL, drawer_expose, prf); gtk_widget_set_hexpand(GTK_WIDGET(prf->color), true); gtk_widget_set_vexpand(GTK_WIDGET(prf->color), true); #else widget_modify_bg(prf->color, GTK_STATE_NORMAL, current_pixel); #endif gtk_widget_show(prf->color); gtk_widget_show(frame); } make_row_inner_separator(8, hb); prf->rtxt = make_row_text(prf, NULL, 6, hb); gtk_size_group_add_widget(prf->color_texts, prf->rtxt); float_to_textfield(prf->rtxt, r); prf->gtxt = make_row_text(prf, NULL, 6, hb); gtk_size_group_add_widget(prf->color_texts, prf->gtxt); float_to_textfield(prf->gtxt, g); prf->btxt = make_row_text(prf, NULL, 6, hb); gtk_size_group_add_widget(prf->color_texts, prf->btxt); float_to_textfield(prf->btxt, b); /* second row */ row2 = gtk_hbox_new(false, 0); gtk_box_pack_start(GTK_BOX(box), row2, false, false, 0); gtk_widget_show(row2); make_row_inner_separator(20, row2); prf->radj = (GtkAdjustment *)gtk_adjustment_new(r, 0.0, 1.01, 0.001, 0.01, .01); prf->rscl = gtk_hscale_new(GTK_ADJUSTMENT(prf->radj)); gtk_widget_set_name(prf->rscl, "prefs_color_scale"); gtk_box_pack_start(GTK_BOX(row2), prf->rscl, true, true, 4); #if (!GTK_CHECK_VERSION(3, 0, 0)) widget_modify_bg(prf->rscl, GTK_STATE_NORMAL, rscl_color); /* this is the slider except when clicked */ widget_modify_bg(prf->rscl, GTK_STATE_PRELIGHT, rscl_color); /* this is the slider when clicked */ #else add_red_scale_style(prf->rscl); #endif gtk_widget_show(prf->rscl); gtk_range_set_update_policy(GTK_RANGE(GTK_SCALE(prf->rscl)), GTK_UPDATE_CONTINUOUS); gtk_scale_set_draw_value(GTK_SCALE(prf->rscl), false); prf->gadj = (GtkAdjustment *)gtk_adjustment_new(g, 0.0, 1.01, 0.001, 0.01, .01); prf->gscl = gtk_hscale_new(GTK_ADJUSTMENT(prf->gadj)); gtk_widget_set_name(prf->gscl, "prefs_color_scale"); gtk_box_pack_start(GTK_BOX(row2), prf->gscl, true, true, 4); #if (!GTK_CHECK_VERSION(3, 0, 0)) widget_modify_bg(prf->gscl, GTK_STATE_NORMAL, gscl_color); widget_modify_bg(prf->gscl, GTK_STATE_PRELIGHT, gscl_color); #else add_green_scale_style(prf->gscl); #endif gtk_widget_show(prf->gscl); gtk_range_set_update_policy(GTK_RANGE(GTK_SCALE(prf->gscl)), GTK_UPDATE_CONTINUOUS); gtk_scale_set_draw_value(GTK_SCALE(prf->gscl), false); prf->badj = (GtkAdjustment *)gtk_adjustment_new(b, 0.0, 1.01, 0.001, 0.01, .01); prf->bscl = gtk_hscale_new(GTK_ADJUSTMENT(prf->badj)); gtk_widget_set_name(prf->bscl, "prefs_color_scale"); gtk_box_pack_start(GTK_BOX(row2), prf->bscl, true, true, 4); #if (!GTK_CHECK_VERSION(3, 0, 0)) widget_modify_bg(prf->bscl, GTK_STATE_NORMAL, bscl_color); widget_modify_bg(prf->bscl, GTK_STATE_PRELIGHT, bscl_color); #else add_blue_scale_style(prf->bscl); #endif gtk_widget_show(prf->bscl); gtk_range_set_update_policy(GTK_RANGE(GTK_SCALE(prf->bscl)), GTK_UPDATE_CONTINUOUS); gtk_scale_set_draw_value(GTK_SCALE(prf->bscl), false); sep3 = gtk_hseparator_new(); gtk_box_pack_end(GTK_BOX(row2), sep3, false, false, 20); gtk_widget_show(sep3); SG_SIGNAL_CONNECT(prf->rtxt, "activate", prefs_r_callback, (gpointer)prf); SG_SIGNAL_CONNECT(prf->gtxt, "activate", prefs_g_callback, (gpointer)prf); SG_SIGNAL_CONNECT(prf->btxt, "activate", prefs_b_callback, (gpointer)prf); SG_SIGNAL_CONNECT(prf->radj, "value_changed", prefs_call_color_func_callback, (gpointer)prf); SG_SIGNAL_CONNECT(prf->gadj, "value_changed", prefs_call_color_func_callback, (gpointer)prf); SG_SIGNAL_CONNECT(prf->badj, "value_changed", prefs_call_color_func_callback, (gpointer)prf); SG_SIGNAL_CONNECT(prf->radj, "value_changed", prefs_change_callback, NULL); SG_SIGNAL_CONNECT(prf->gadj, "value_changed", prefs_change_callback, NULL); SG_SIGNAL_CONNECT(prf->badj, "value_changed", prefs_change_callback, NULL); SG_SIGNAL_CONNECT(prf->radj, "value_changed", prefs_color_callback, (gpointer)prf); SG_SIGNAL_CONNECT(prf->gadj, "value_changed", prefs_color_callback, (gpointer)prf); SG_SIGNAL_CONNECT(prf->badj, "value_changed", prefs_color_callback, (gpointer)prf); prf->color_func = color_func; return(prf); } /* ---------------- topic separator ---------------- */ static void make_inter_topic_separator(GtkWidget *topics) { GtkWidget *w; w = gtk_hseparator_new(); gtk_box_pack_start(GTK_BOX(topics), w, false, false, 0); gtk_widget_show(w); /* height = INTER_TOPIC_SPACE no line */ } /* ---------------- variable separator ---------------- */ static void make_inter_variable_separator(GtkWidget *topics) { GtkWidget *w; w = gtk_hseparator_new(); gtk_box_pack_start(GTK_BOX(topics), w, false, false, 0); gtk_widget_show(w); /* height = INTER_VARIABLE_SPACE no line */ } /* ---------------- top-level contents label ---------------- */ static void make_top_level_label(const char *label, GtkWidget *parent) { GtkWidget *w1, *w2, *w3; char *str; w1 = gtk_vseparator_new(); gtk_box_pack_start(GTK_BOX(parent), w1, false, false, 6); gtk_widget_show(w1); str = mus_format("%s", label); #if (!GTK_CHECK_VERSION(3, 0, 0)) w2 = gtk_label_new(label); gtk_label_set_markup(GTK_LABEL(w2), str); gtk_label_set_use_markup(GTK_LABEL(w2), true); gtk_misc_set_alignment(GTK_MISC(w2), 0.01, 0.5); #else w2 = gtk_button_new_with_label(label); add_highlight_button_style(w2); gtk_label_set_markup(GTK_LABEL(BIN_CHILD(w2)), str); gtk_label_set_use_markup(GTK_LABEL(BIN_CHILD(w2)), true); #if GTK_CHECK_VERSION(3, 14, 0) gtk_widget_set_halign(GTK_WIDGET(w2), GTK_ALIGN_START); #else gtk_misc_set_alignment(GTK_MISC(BIN_CHILD(w2)), 0.01, 0.5); #endif #endif free(str); gtk_box_pack_start(GTK_BOX(parent), w2, false, false, 0); gtk_widget_show(w2); w3 = gtk_vseparator_new(); gtk_box_pack_start(GTK_BOX(parent), w3, false, false, 6); gtk_widget_show(w3); make_inter_variable_separator(parent); } static GtkWidget *make_top_level_box(GtkWidget *topics) { GtkWidget *w, *frame; frame = gtk_frame_new(NULL); gtk_box_pack_start(GTK_BOX(topics), frame, true, true, 0); gtk_widget_show(frame); w = gtk_vbox_new(false, 2); gtk_container_add(GTK_CONTAINER(frame), w); gtk_widget_show(w); return(w); } static void make_inner_label(const char *label, GtkWidget *parent) { GtkWidget *w, *w1, *w2; char *str; w1 = gtk_vseparator_new(); gtk_box_pack_start(GTK_BOX(parent), w1, false, false, 4); gtk_widget_show(w1); str = mus_format("%s", label); #if (!GTK_CHECK_VERSION(3, 0, 0)) w = gtk_label_new(label); gtk_label_set_markup(GTK_LABEL(w), str); gtk_label_set_use_markup(GTK_LABEL(w), true); gtk_misc_set_alignment(GTK_MISC(w), 0.0, 0.5); #else w = gtk_button_new_with_label(label); add_highlight_button_style(w); gtk_label_set_markup(GTK_LABEL(BIN_CHILD(w)), str); gtk_label_set_use_markup(GTK_LABEL(BIN_CHILD(w)), true); #if GTK_CHECK_VERSION(3, 14, 0) gtk_widget_set_halign(GTK_WIDGET(w), GTK_ALIGN_START); #else gtk_misc_set_alignment(GTK_MISC(BIN_CHILD(w)), 0.0, 0.5); #endif #endif free(str); gtk_box_pack_start(GTK_BOX(parent), w, false, false, 0); gtk_widget_show(w); w2 = gtk_vseparator_new(); gtk_box_pack_start(GTK_BOX(parent), w2, false, false, 4); gtk_widget_show(w2); make_inter_variable_separator(parent); } /* ---------------- base buttons ---------------- */ static gint preferences_delete_callback(GtkWidget *w, GdkEvent *event, gpointer context) { clear_prefs_dialog_error(); gtk_widget_hide(preferences_dialog); return(true); } static void preferences_dismiss_callback(GtkWidget *w, gpointer context) { clear_prefs_dialog_error(); gtk_widget_hide(preferences_dialog); } static void preferences_help_callback(GtkWidget *w, gpointer context) { snd_help("preferences", "This dialog sets various global variables. 'Save' then writes the new values \ to ~/.snd_prefs_ruby|forth|s7 so that they take effect the next time you start Snd. 'Revert' resets each variable either to \ its value when the Preferences dialog was started, or to the last saved value. 'Clear' resets each variable to its default value (its \ value when Snd starts, before loading initialization files). 'Help' starts this dialog, and as long as it's active, it will post helpful \ information if the mouse lingers over some variable -- sort of a tooltip that stays out of your way. \ You can also request help on a given topic by clicking the variable name on the far right.", WITH_WORD_WRAP); } static void prefs_set_dialog_title(const char *filename) { char *str; if (filename) { if (prefs_saved_filename) free(prefs_saved_filename); prefs_saved_filename = mus_strdup(filename); } if (prefs_saved_filename) str = mus_format("Preferences%s (saved in %s)\n", (prefs_unsaved) ? "*" : "", prefs_saved_filename); else str = mus_format("Preferences%s", (prefs_unsaved) ? "*" : ""); gtk_window_set_title(GTK_WINDOW(preferences_dialog), str); free(str); } static void preferences_revert_callback(GtkWidget *w, gpointer context) { preferences_revert_or_clear(true); } static void preferences_clear_callback(GtkWidget *w, gpointer context) { preferences_revert_or_clear(false); } #if HAVE_EXTENSION_LANGUAGE static void preferences_save_callback(GtkWidget *w, gpointer context) { clear_prefs_dialog_error(); redirect_snd_error_to(post_prefs_dialog_error, NULL); redirect_snd_warning_to(post_prefs_dialog_error, NULL); save_prefs(); redirect_snd_error_to(NULL, NULL); redirect_snd_warning_to(NULL, NULL); } #endif /* ---------------- errors ---------------- */ static void clear_prefs_error(GtkWidget *w, gpointer context) { prefs_info *prf = (prefs_info *)context; g_signal_handler_disconnect(prf->text, prf->erase_id); prf->erase_id = 0; set_label(prf->error, ""); } static void post_prefs_error(const char *msg, prefs_info *prf) { prf->got_error = true; set_label(prf->error, msg); if (prf->erase_id != 0) g_signal_handler_disconnect(prf->text, prf->erase_id); prf->erase_id = SG_SIGNAL_CONNECT(prf->text, "changed", clear_prefs_error, (gpointer)prf); } static void va_post_prefs_error(const char *msg, prefs_info *data, ...) { char *buf; va_list ap; va_start(ap, data); buf = vstr(msg, ap); va_end(ap); post_prefs_error(buf, data); free(buf); } /* ---------------- preferences dialog ---------------- */ widget_t make_preferences_dialog(void) { GtkWidget *save_button, *revert_button, *clear_button, *help_button, *dismiss_button, *topics, *scroller; prefs_info *prf; char *str; if (preferences_dialog) { gtk_widget_show(preferences_dialog); return(preferences_dialog); } preferences_dialog = snd_gtk_dialog_new(); #if GTK_CHECK_VERSION(3, 14, 0) gtk_window_set_transient_for(GTK_WINDOW(preferences_dialog), GTK_WINDOW(MAIN_SHELL(ss))); #endif gtk_window_set_title(GTK_WINDOW(preferences_dialog), "Preferences"); sg_make_resizable(preferences_dialog); /* gtk_container_set_border_width (GTK_CONTAINER(preferences_dialog), 10); */ gtk_widget_realize(preferences_dialog); if ((STARTUP_WIDTH < gdk_screen_width()) && (STARTUP_HEIGHT < gdk_screen_height())) gtk_window_resize(GTK_WINDOW(preferences_dialog), STARTUP_WIDTH, STARTUP_HEIGHT); help_button = gtk_dialog_add_button(GTK_DIALOG(preferences_dialog), "Help", GTK_RESPONSE_NONE); revert_button = gtk_dialog_add_button(GTK_DIALOG(preferences_dialog), "Revert", GTK_RESPONSE_NONE); clear_button = gtk_dialog_add_button(GTK_DIALOG(preferences_dialog), "Clear", GTK_RESPONSE_NONE); dismiss_button = gtk_dialog_add_button(GTK_DIALOG(preferences_dialog), "Go away", GTK_RESPONSE_NONE); #if HAVE_EXTENSION_LANGUAGE save_button = gtk_dialog_add_button(GTK_DIALOG(preferences_dialog), "Save", GTK_RESPONSE_NONE); gtk_widget_set_name(save_button, "dialog_button"); #endif gtk_widget_set_name(help_button, "dialog_button"); gtk_widget_set_name(revert_button, "dialog_button"); gtk_widget_set_name(clear_button, "dialog_button"); gtk_widget_set_name(dismiss_button, "dialog_button"); #if GTK_CHECK_VERSION(3, 0, 0) add_highlight_button_style(dismiss_button); add_highlight_button_style(revert_button); add_highlight_button_style(clear_button); #if HAVE_EXTENSION_LANGUAGE add_highlight_button_style(save_button); #endif add_highlight_button_style(help_button); #endif SG_SIGNAL_CONNECT(preferences_dialog, "delete_event", preferences_delete_callback, NULL); SG_SIGNAL_CONNECT(dismiss_button, "clicked", preferences_dismiss_callback, NULL); SG_SIGNAL_CONNECT(revert_button, "clicked", preferences_revert_callback, NULL); SG_SIGNAL_CONNECT(clear_button, "clicked", preferences_clear_callback, NULL); #if HAVE_EXTENSION_LANGUAGE SG_SIGNAL_CONNECT(save_button, "clicked", preferences_save_callback, NULL); #endif SG_SIGNAL_CONNECT(help_button, "clicked", preferences_help_callback, NULL); gtk_widget_show(dismiss_button); #if HAVE_EXTENSION_LANGUAGE gtk_widget_show(save_button); #endif gtk_widget_show(revert_button); gtk_widget_show(clear_button); gtk_widget_show(help_button); topics = gtk_vbox_new(false, 0); scroller = gtk_scrolled_window_new(NULL, NULL); gtk_box_pack_start(GTK_BOX(DIALOG_CONTENT_AREA(preferences_dialog)), scroller, true, true, 0); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroller), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); #if HAVE_GTK_HEADER_BAR_NEW gtk_container_add(GTK_CONTAINER(scroller), topics); #else gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scroller), topics); #endif gtk_widget_show(topics); gtk_widget_show(scroller); label_group = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); widgets_group = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); #if 0 /* these are really garish */ rscl_color = rgb_to_color(1.0, 0.0, 0.0); gscl_color = rgb_to_color(0.0, 1.0, 0.0); bscl_color = rgb_to_color(0.0, 0.0, 1.0); #else rscl_color = rgb_to_color(1.0, 0.4, 0.4); gscl_color = rgb_to_color(0.56, 1.0, 0.56); bscl_color = rgb_to_color(0.68, 0.84, 1.0); #endif /* ---------------- overall behavior ---------------- */ { GtkWidget *dpy_box; char *str1, *str2; /* ---------------- overall behavior ----------------*/ dpy_box = make_top_level_box(topics); make_top_level_label("overall behavior choices", dpy_box); str1 = mus_format("%d", ss->init_window_width); str2 = mus_format("%d", ss->init_window_height); rts_init_window_width = ss->init_window_width; rts_init_window_height = ss->init_window_height; prf = prefs_row_with_two_texts("start up size", S_window_width, "width:", str1, "height:", str2, 6, dpy_box, startup_size_text); remember_pref(prf, reflect_init_window_size, save_init_window_size, help_init_window_size, clear_init_window_size, revert_init_window_size); free(str2); free(str1); make_inter_variable_separator(dpy_box); prf = prefs_row_with_toggle("ask before overwriting anything", S_ask_before_overwrite, rts_ask_before_overwrite = ask_before_overwrite(ss), dpy_box, overwrite_toggle); remember_pref(prf, reflect_ask_before_overwrite, save_ask_before_overwrite, help_ask_before_overwrite, NULL, revert_ask_before_overwrite); make_inter_variable_separator(dpy_box); prf = prefs_row_with_toggle("ask about unsaved edits before exiting", S_ask_about_unsaved_edits, rts_unsaved_edits = ask_about_unsaved_edits(ss), dpy_box, unsaved_edits_toggle); remember_pref(prf, reflect_unsaved_edits, save_unsaved_edits, help_unsaved_edits, clear_unsaved_edits, revert_unsaved_edits); make_inter_variable_separator(dpy_box); prf = prefs_row_with_toggle("include thumbnail graph in upper right corner", S_with_inset_graph, rts_with_inset_graph = with_inset_graph(ss), dpy_box, with_inset_graph_toggle); remember_pref(prf, reflect_with_inset_graph, save_with_inset_graph, help_inset_graph, clear_with_inset_graph, revert_with_inset_graph); make_inter_variable_separator(dpy_box); prf = prefs_row_with_toggle("resize main window as sounds open and close", S_auto_resize, rts_auto_resize = auto_resize(ss), dpy_box, resize_toggle); remember_pref(prf, reflect_auto_resize, save_auto_resize, help_auto_resize, NULL, revert_auto_resize); make_inter_variable_separator(dpy_box); prf = prefs_row_with_toggle("pointer focus", S_with_pointer_focus, rts_with_pointer_focus = with_pointer_focus(ss), dpy_box, with_pointer_focus_toggle); remember_pref(prf, reflect_with_pointer_focus, save_with_pointer_focus, help_pointer_focus, clear_with_pointer_focus, revert_with_pointer_focus); make_inter_variable_separator(dpy_box); rts_sync_style = sync_style(ss); prf = prefs_row_with_two_toggles("operate on all channels together", S_sync, "within each sound", rts_sync_style == SYNC_BY_SOUND, "across all sounds", rts_sync_style == SYNC_ALL, dpy_box, sync1_choice, sync2_choice); remember_pref(prf, reflect_sync_style, save_sync_style, help_sync_style, clear_sync_style, revert_sync_style); make_inter_variable_separator(dpy_box); rts_remember_sound_state = remember_sound_state(ss); prf = prefs_row_with_toggle("restore a sound's state if reopened later", S_remember_sound_state, rts_remember_sound_state, dpy_box, toggle_remember_sound_state); remember_pref(prf, reflect_remember_sound_state, save_remember_sound_state, help_remember_sound_state, clear_remember_sound_state, revert_remember_sound_state); make_inter_variable_separator(dpy_box); prf = prefs_row_with_toggle("show the control panel upon opening a sound", S_show_controls, rts_show_controls = in_show_controls(ss), dpy_box, controls_toggle); remember_pref(prf, reflect_show_controls, save_show_controls, help_show_controls, NULL, revert_show_controls); make_inter_variable_separator(dpy_box); include_peak_env_directory = mus_strdup(peak_env_dir(ss)); rts_peak_env_directory = mus_strdup(include_peak_env_directory); include_peak_envs = find_peak_envs(); rts_peak_envs = include_peak_envs; prf = prefs_row_with_toggle_with_text("save peak envs to speed up initial display", S_peak_env_dir, include_peak_envs, "directory:", include_peak_env_directory, 25, dpy_box, peak_envs_toggle, peak_envs_text); remember_pref(prf, reflect_peak_envs, save_peak_envs, help_peak_envs, clear_peak_envs, revert_peak_envs); make_inter_variable_separator(dpy_box); str = mus_format("%d", rts_max_regions = max_regions(ss)); prf = prefs_row_with_toggle_with_text("selection creates an associated region", S_selection_creates_region, rts_selection_creates_region = selection_creates_region(ss), "max regions:", str, 5, dpy_box, selection_creates_region_toggle, max_regions_text); remember_pref(prf, reflect_selection_creates_region, save_selection_creates_region, help_selection_creates_region, NULL, revert_selection_creates_region); free(str); make_inter_variable_separator(dpy_box); rts_with_toolbar = with_toolbar(ss); prf = prefs_row_with_toggle("include a toolbar", S_with_toolbar, rts_with_toolbar, dpy_box, toggle_with_toolbar); remember_pref(prf, reflect_with_toolbar, save_with_toolbar, help_with_toolbar, clear_with_toolbar, revert_with_toolbar); make_inter_variable_separator(dpy_box); rts_with_tooltips = with_tooltips(ss); prf = prefs_row_with_toggle("enable tooltips", S_with_tooltips, rts_with_tooltips, dpy_box, toggle_with_tooltips); remember_pref(prf, reflect_with_tooltips, save_with_tooltips, help_with_tooltips, clear_with_tooltips, revert_with_tooltips); make_inter_variable_separator(dpy_box); rts_with_menu_icons = with_menu_icons(ss); prf = prefs_row_with_toggle("enable menu icons (gtk only)", S_with_menu_icons, rts_with_menu_icons, dpy_box, toggle_with_menu_icons); remember_pref(prf, reflect_with_menu_icons, save_with_menu_icons, help_with_menu_icons, clear_with_menu_icons, revert_with_menu_icons); /* ---------------- file options ---------------- */ make_inter_variable_separator(dpy_box); make_inner_label(" file options", dpy_box); rts_load_path = find_sources(); prf = prefs_row_with_text("directory containing Snd's " Xen_language " files", "load path", rts_load_path, dpy_box, load_path_text); remember_pref(prf, reflect_load_path, NULL, help_load_path, clear_load_path, revert_load_path); load_path_text_widget = prf->text; make_inter_variable_separator(dpy_box); prf = prefs_row_with_toggle("display only sound files in various file lists", S_just_sounds, rts_just_sounds = just_sounds(ss), dpy_box, just_sounds_toggle); remember_pref(prf, prefs_reflect_just_sounds, save_just_sounds, help_just_sounds, NULL, revert_just_sounds); make_inter_variable_separator(dpy_box); rts_temp_dir = mus_strdup(temp_dir(ss)); prf = prefs_row_with_text("directory for temporary files", S_temp_dir, temp_dir(ss), dpy_box, temp_dir_text); remember_pref(prf, reflect_temp_dir, save_temp_dir, help_temp_dir, NULL, revert_temp_dir); make_inter_variable_separator(dpy_box); rts_save_dir = mus_strdup(save_dir(ss)); prf = prefs_row_with_text("directory for save-state files", S_save_dir, save_dir(ss), dpy_box, save_dir_text); remember_pref(prf, reflect_save_dir, save_save_dir, help_save_dir, NULL, revert_save_dir); make_inter_variable_separator(dpy_box); rts_save_state_file = mus_strdup(save_state_file(ss)); prf = prefs_row_with_text("default save-state filename", S_save_state_file, save_state_file(ss), dpy_box, save_state_file_text); remember_pref(prf, reflect_save_state_file, save_save_state_file, help_save_state_file, NULL, revert_save_state_file); #if HAVE_LADSPA make_inter_variable_separator(dpy_box); rts_ladspa_dir = mus_strdup(ladspa_dir(ss)); prf = prefs_row_with_text("directory for ladspa plugins", S_ladspa_dir, ladspa_dir(ss), dpy_box, ladspa_dir_text); remember_pref(prf, reflect_ladspa_dir, save_ladspa_dir, help_ladspa_dir, NULL, revert_ladspa_dir); #endif make_inter_variable_separator(dpy_box); rts_html_program = mus_strdup(html_program(ss)); prf = prefs_row_with_text("external program to read HTML files via snd-help", S_html_program, html_program(ss), dpy_box, html_program_text); remember_pref(prf, reflect_html_program, save_html_program, help_html_program, NULL, revert_html_program); make_inter_variable_separator(dpy_box); rts_default_output_chans = default_output_chans(ss); prf = prefs_row_with_radio_box("default new sound attributes: chans", S_default_output_chans, output_chan_choices, NUM_OUTPUT_CHAN_CHOICES, -1, dpy_box, default_output_chans_choice); remember_pref(prf, reflect_default_output_chans, save_default_output_chans, help_default_output_chans, NULL, revert_default_output_chans); reflect_default_output_chans(prf); rts_default_output_srate = default_output_srate(ss); prf = prefs_row_with_radio_box("srate", S_default_output_srate, output_srate_choices, NUM_OUTPUT_SRATE_CHOICES, -1, dpy_box, default_output_srate_choice); remember_pref(prf, reflect_default_output_srate, save_default_output_srate, help_default_output_srate, NULL, revert_default_output_srate); reflect_default_output_srate(prf); rts_default_output_header_type = default_output_header_type(ss); prf = prefs_row_with_radio_box("header type", S_default_output_header_type, output_header_type_choices, NUM_OUTPUT_HEADER_TYPE_CHOICES, -1, dpy_box, default_output_header_type_choice); output_header_type_prf = prf; remember_pref(prf, reflect_default_output_header_type, save_default_output_header_type, help_default_output_header_type, NULL, revert_default_output_header_type); rts_default_output_sample_type = default_output_sample_type(ss); prf = prefs_row_with_radio_box("sample type", S_default_output_sample_type, output_sample_type_choices, NUM_OUTPUT_SAMPLE_TYPE_CHOICES, -1, dpy_box, default_output_sample_type_choice); output_sample_type_prf = prf; remember_pref(prf, reflect_default_output_sample_type, save_default_output_sample_type, help_default_output_sample_type, NULL, revert_default_output_sample_type); reflect_default_output_header_type(output_header_type_prf); reflect_default_output_sample_type(output_sample_type_prf); make_inter_variable_separator(dpy_box); { int i, srate = 0, chans = 0; mus_sample_t samp_type = MUS_UNKNOWN_SAMPLE; mus_header_raw_defaults(&srate, &chans, &samp_type); str = mus_format("%d", chans); str1 = mus_format("%d", srate); rts_raw_chans = chans; rts_raw_srate = srate; rts_raw_sample_type = samp_type; raw_sample_type_choices = (char **)calloc(MUS_NUM_SAMPLES - 1, sizeof(char *)); for (i = 1; i < MUS_NUM_SAMPLES; i++) raw_sample_type_choices[i - 1] = raw_sample_type_to_string((mus_sample_t)i); /* skip MUS_UNKNOWN_SAMPLE = 0 */ prf = prefs_row_with_text("default raw sound attributes: chans", S_mus_header_raw_defaults, str, dpy_box, raw_chans_choice); remember_pref(prf, reflect_raw_chans, save_raw_chans, help_raw_chans, NULL, revert_raw_chans); prf = prefs_row_with_text("srate", S_mus_header_raw_defaults, str1, dpy_box, raw_srate_choice); remember_pref(prf, reflect_raw_srate, save_raw_srate, help_raw_srate, NULL, revert_raw_srate); free(str); free(str1); prf = prefs_row_with_list("sample type", S_mus_header_raw_defaults, raw_sample_type_choices[samp_type - 1], (const char **)raw_sample_type_choices, MUS_NUM_SAMPLES - 1, dpy_box, raw_sample_type_from_text, NULL, NULL); remember_pref(prf, reflect_raw_sample_type, save_raw_sample_type, help_raw_sample_type, NULL, revert_raw_sample_type); } make_inter_variable_separator(dpy_box); /* ---------------- additional keys ---------------- */ { key_info *ki; make_inner_label(" additional keys", dpy_box); ki = find_prefs_key("play-from-cursor"); prf = prefs_row_with_text_and_three_toggles("play all chans from cursor", S_play, "key:", 8, "ctrl:", "meta:", "C-x:", ki->key, ki->c, ki->m, ki->x, dpy_box, bind_play_from_cursor); remember_pref(prf, reflect_play_from_cursor, save_pfc, help_play_from_cursor, clear_play_from_cursor, NULL); free(ki); make_inter_variable_separator(dpy_box); ki = find_prefs_key("show-all"); prf = prefs_row_with_text_and_three_toggles("show entire sound", S_x_bounds, "key:", 8, "ctrl:", "meta:", "C-x:", ki->key, ki->c, ki->m, ki->x, dpy_box, bind_show_all); remember_pref(prf, reflect_show_all, save_show_all, help_show_all, clear_show_all, NULL); free(ki); make_inter_variable_separator(dpy_box); ki = find_prefs_key("select-all"); prf = prefs_row_with_text_and_three_toggles("select entire sound", S_select_all, "key:", 8, "ctrl:", "meta:", "C-x:", ki->key, ki->c, ki->m, ki->x, dpy_box, bind_select_all); remember_pref(prf, reflect_select_all, save_select_all, help_select_all, clear_select_all, NULL); free(ki); make_inter_variable_separator(dpy_box); ki = find_prefs_key("show-selection"); prf = prefs_row_with_text_and_three_toggles("show current selection", "show-selection", "key:", 8, "ctrl:", "meta:", "C-x:", ki->key, ki->c, ki->m, ki->x, dpy_box, bind_show_selection); remember_pref(prf, reflect_show_selection, save_show_selection, help_show_selection, clear_show_selection, NULL); free(ki); make_inter_variable_separator(dpy_box); ki = find_prefs_key("revert-sound"); prf = prefs_row_with_text_and_three_toggles("undo all edits (revert)", S_revert_sound, "key:", 8, "ctrl:", "meta:", "C-x:", ki->key, ki->c, ki->m, ki->x, dpy_box, bind_revert); remember_pref(prf, reflect_revert, save_revert, help_revert, clear_revert_sound, NULL); free(ki); make_inter_variable_separator(dpy_box); ki = find_prefs_key("exit"); prf = prefs_row_with_text_and_three_toggles("exit from Snd", S_exit, "key:", 8, "ctrl:", "meta:", "C-x:", ki->key, ki->c, ki->m, ki->x, dpy_box, bind_exit); remember_pref(prf, reflect_exit, save_exit, help_exit, clear_exit, NULL); free(ki); make_inter_variable_separator(dpy_box); ki = find_prefs_key("goto-maxamp"); prf = prefs_row_with_text_and_three_toggles("move cursor to channel's maximum sample", S_maxamp_position, "key:", 8, "ctrl:", "meta:", "C-x:", ki->key, ki->c, ki->m, ki->x, dpy_box, bind_goto_maxamp); remember_pref(prf, reflect_goto_maxamp, save_goto_maxamp, help_goto_maxamp, clear_goto_maxamp, NULL); free(ki); } /* ---------------- cursor options ---------------- */ make_inter_variable_separator(dpy_box); make_inner_label(" cursor options", dpy_box); prf = prefs_row_with_toggle("report cursor location as it moves", S_with_verbose_cursor, rts_with_verbose_cursor = with_verbose_cursor(ss), dpy_box, with_verbose_cursor_toggle); remember_pref(prf, reflect_with_verbose_cursor, save_with_verbose_cursor, help_with_verbose_cursor, NULL, revert_with_verbose_cursor); make_inter_variable_separator(dpy_box); { char *str1; str = mus_format("%.2f", rts_cursor_update_interval = cursor_update_interval(ss)); str1 = mus_format("%d", rts_cursor_location_offset = cursor_location_offset(ss)); prf = prefs_row_with_toggle_with_two_texts("track current location while playing", S_with_tracking_cursor, (rts_with_tracking_cursor = with_tracking_cursor(ss)), "update:", str, "offset:", str1, 8, dpy_box, with_tracking_cursor_toggle, cursor_location_text); remember_pref(prf, reflect_with_tracking_cursor, save_with_tracking_cursor, help_with_tracking_cursor, NULL, revert_with_tracking_cursor); free(str); free(str1); } make_inter_variable_separator(dpy_box); str = mus_format("%d", rts_cursor_size = cursor_size(ss)); prf = prefs_row_with_number("size", S_cursor_size, str, 4, dpy_box, cursor_size_up, cursor_size_down, cursor_size_from_text); remember_pref(prf, reflect_cursor_size, save_cursor_size, help_cursor_size, NULL, revert_cursor_size); free(str); if (cursor_size(ss) <= 0) gtk_widget_set_sensitive(prf->arrow_down, false); make_inter_variable_separator(dpy_box); prf = prefs_row_with_radio_box("shape", S_cursor_style, cursor_styles, NUM_CURSOR_STYLES, rts_cursor_style = cursor_style(ss), dpy_box, cursor_style_choice); remember_pref(prf, reflect_cursor_style, save_cursor_style, help_cursor_style, NULL, revert_cursor_style); make_inter_variable_separator(dpy_box); prf = prefs_row_with_radio_box("tracking cursor shape", S_tracking_cursor_style, cursor_styles, NUM_CURSOR_STYLES, rts_tracking_cursor_style = tracking_cursor_style(ss), dpy_box, tracking_cursor_style_choice); remember_pref(prf, reflect_tracking_cursor_style, save_tracking_cursor_style, help_tracking_cursor_style, NULL, revert_tracking_cursor_style); make_inter_variable_separator(dpy_box); saved_cursor_color = ss->cursor_color; prf = prefs_color_selector_row("color", S_cursor_color, ss->cursor_color, dpy_box, cursor_color_func); remember_pref(prf, NULL, save_cursor_color, help_cursor_color, clear_cursor_color, revert_cursor_color); /* ---------------- (overall) colors ---------------- */ make_inter_variable_separator(dpy_box); make_inner_label(" colors", dpy_box); saved_basic_color = ss->basic_color; prf = prefs_color_selector_row("main background color", S_basic_color, ss->basic_color, dpy_box, basic_color_func); remember_pref(prf, NULL, save_basic_color, help_basic_color, clear_basic_color, revert_basic_color); make_inter_variable_separator(dpy_box); saved_highlight_color = ss->highlight_color; prf = prefs_color_selector_row("main highlight color", S_highlight_color, ss->highlight_color, dpy_box, highlight_color_func); remember_pref(prf, NULL, save_highlight_color, help_highlight_color, clear_highlight_color, revert_highlight_color); make_inter_variable_separator(dpy_box); saved_position_color = ss->position_color; prf = prefs_color_selector_row("second highlight color", S_position_color, ss->position_color, dpy_box, position_color_func); remember_pref(prf, NULL, save_position_color, help_position_color, clear_position_color, revert_position_color); make_inter_variable_separator(dpy_box); saved_zoom_color = ss->zoom_color; prf = prefs_color_selector_row("third highlight color", S_zoom_color, ss->zoom_color, dpy_box, zoom_color_func); remember_pref(prf, NULL, save_zoom_color, help_zoom_color, clear_zoom_color, revert_zoom_color); } make_inter_topic_separator(topics); /* -------- graphs -------- */ { GtkWidget *grf_box; /* ---------------- graph options ---------------- */ grf_box = make_top_level_box(topics); make_top_level_label("graph options", grf_box); prf = prefs_row_with_radio_box("how to connect the dots", S_graph_style, graph_styles, NUM_GRAPH_STYLES, rts_graph_style = graph_style(ss), grf_box, graph_style_choice); remember_pref(prf, reflect_graph_style, save_graph_style, help_graph_style, NULL, revert_graph_style); make_inter_variable_separator(grf_box); str = mus_format("%d", rts_dot_size = dot_size(ss)); prf = prefs_row_with_number("dot size", S_dot_size, str, 4, grf_box, dot_size_up, dot_size_down, dot_size_from_text); remember_pref(prf, reflect_dot_size, save_dot_size, help_dot_size, NULL, revert_dot_size); free(str); if (dot_size(ss) <= 0) gtk_widget_set_sensitive(prf->arrow_down, false); make_inter_variable_separator(grf_box); rts_initial_beg = initial_beg(ss); rts_initial_dur = initial_dur(ss); str = mus_format("%.2f : %.2f", rts_initial_beg, rts_initial_dur); prf = prefs_row_with_text_with_toggle("initial graph x bounds", S_initial_graph_hook, (rts_full_duration = show_full_duration(ss)), "show full duration", str, 16, grf_box, initial_bounds_toggle, initial_bounds_text); free(str); remember_pref(prf, reflect_initial_bounds, save_initial_bounds, help_initial_bounds, clear_initial_bounds, revert_initial_bounds); make_inter_variable_separator(grf_box); prf = prefs_row_with_radio_box("how to layout multichannel graphs", S_channel_style, channel_styles, NUM_CHANNEL_STYLES, rts_channel_style = channel_style(ss), grf_box, channel_style_choice); remember_pref(prf, reflect_channel_style, save_channel_style, help_channel_style, NULL, revert_channel_style); make_inter_variable_separator(grf_box); prf = prefs_row_with_toggle("layout wave and fft graphs horizontally", S_graphs_horizontal, rts_graphs_horizontal = graphs_horizontal(ss), grf_box, graphs_horizontal_toggle); remember_pref(prf, reflect_graphs_horizontal, save_graphs_horizontal, help_graphs_horizontal, NULL, revert_graphs_horizontal); make_inter_variable_separator(grf_box); prf = prefs_row_with_toggle("include y=0 line in sound graphs", S_show_y_zero, rts_show_y_zero = show_y_zero(ss), grf_box, y_zero_toggle); remember_pref(prf, reflect_show_y_zero, save_show_y_zero, help_show_y_zero, NULL, revert_show_y_zero); make_inter_variable_separator(grf_box); rts_show_grid = show_grid(ss); prf = prefs_row_with_toggle("include a grid in sound graphs", S_show_grid, rts_show_grid == WITH_GRID, grf_box, grid_toggle); remember_pref(prf, reflect_show_grid, save_show_grid, help_show_grid, NULL, revert_show_grid); make_inter_variable_separator(grf_box); prf = prefs_row_with_scale("grid density", S_grid_density, 2.0, rts_grid_density = grid_density(ss), grf_box, grid_density_scale_callback, grid_density_text_callback); remember_pref(prf, reflect_grid_density, save_grid_density, help_grid_density, NULL, revert_grid_density); make_inter_variable_separator(grf_box); rts_show_axes = show_axes(ss); prf = prefs_row_with_list("what axes to display", S_show_axes, show_axes_choices[(int)rts_show_axes], show_axes_choices, NUM_SHOW_AXES, grf_box, show_axes_from_text, NULL, NULL); remember_pref(prf, reflect_show_axes, save_show_axes, help_show_axes, clear_show_axes, revert_show_axes); make_inter_variable_separator(grf_box); rts_x_axis_style = x_axis_style(ss); prf = prefs_row_with_list("time division", S_x_axis_style, x_axis_styles[(int)rts_x_axis_style], x_axis_styles, NUM_X_AXIS_STYLES, grf_box, x_axis_style_from_text, NULL, NULL); remember_pref(prf, reflect_x_axis_style, save_x_axis_style, help_x_axis_style, clear_x_axis_style, revert_x_axis_style); make_inter_variable_separator(grf_box); prf = prefs_row_with_toggle("include smpte info", "show-smpte-label", rts_with_smpte_label = with_smpte_label(ss), grf_box, smpte_toggle); remember_pref(prf, reflect_smpte, save_smpte, help_smpte, clear_smpte, revert_smpte); /* ---------------- (graph) colors ---------------- */ make_inter_variable_separator(grf_box); make_inner_label(" colors", grf_box); saved_data_color = ss->data_color; prf = prefs_color_selector_row("unselected data (waveform) color", S_data_color, ss->data_color, grf_box, data_color_func); remember_pref(prf, NULL, save_data_color, help_data_color, clear_data_color, revert_data_color); make_inter_variable_separator(grf_box); saved_graph_color = ss->graph_color; prf = prefs_color_selector_row("unselected graph (background) color", S_graph_color, ss->graph_color, grf_box, graph_color_func); remember_pref(prf, NULL, save_graph_color, help_graph_color, clear_graph_color, revert_graph_color); make_inter_variable_separator(grf_box); saved_selected_data_color = ss->selected_data_color; prf = prefs_color_selector_row("selected channel data (waveform) color", S_selected_data_color, ss->selected_data_color, grf_box, selected_data_color_func); remember_pref(prf, NULL, save_selected_data_color, help_selected_data_color, clear_selected_data_color, revert_selected_data_color); make_inter_variable_separator(grf_box); saved_selected_graph_color = ss->selected_graph_color; prf = prefs_color_selector_row("selected channel graph (background) color", S_selected_graph_color, ss->selected_graph_color, grf_box, selected_graph_color_func); remember_pref(prf, NULL, save_selected_graph_color, help_selected_graph_color, clear_selected_graph_color, revert_selected_graph_color); make_inter_variable_separator(grf_box); saved_selection_color = ss->selection_color; prf = prefs_color_selector_row("selection color", S_selection_color, ss->selection_color, grf_box, selection_color_func); remember_pref(prf, NULL, save_selection_color, help_selection_color, clear_selection_color, revert_selection_color); /* ---------------- (graph) fonts ---------------- */ make_inter_variable_separator(grf_box); make_inner_label(" fonts", grf_box); rts_axis_label_font = mus_strdup(axis_label_font(ss)); prf = prefs_row_with_text("axis label font", S_axis_label_font, axis_label_font(ss), grf_box, axis_label_font_text); remember_pref(prf, reflect_axis_label_font, save_axis_label_font, help_axis_label_font, clear_axis_label_font, revert_axis_label_font); make_inter_variable_separator(grf_box); rts_axis_numbers_font = mus_strdup(axis_numbers_font(ss)); prf = prefs_row_with_text("axis number font", S_axis_numbers_font, axis_numbers_font(ss), grf_box, axis_numbers_font_text); remember_pref(prf, reflect_axis_numbers_font, save_axis_numbers_font, help_axis_numbers_font, clear_axis_numbers_font, revert_axis_numbers_font); make_inter_variable_separator(grf_box); rts_peaks_font = mus_strdup(peaks_font(ss)); prf = prefs_row_with_text("fft peaks font", S_peaks_font, peaks_font(ss), grf_box, peaks_font_text); remember_pref(prf, reflect_peaks_font, save_peaks_font, help_peaks_font, clear_peaks_font, revert_peaks_font); make_inter_variable_separator(grf_box); rts_bold_peaks_font = mus_strdup(bold_peaks_font(ss)); prf = prefs_row_with_text("fft peaks bold font (for main peaks)", S_bold_peaks_font, bold_peaks_font(ss), grf_box, bold_peaks_font_text); remember_pref(prf, reflect_bold_peaks_font, save_bold_peaks_font, help_bold_peaks_font, clear_bold_peaks_font, revert_bold_peaks_font); make_inter_variable_separator(grf_box); rts_tiny_font = mus_strdup(tiny_font(ss)); prf = prefs_row_with_text("tiny font (for various annotations)", S_peaks_font, tiny_font(ss), grf_box, tiny_font_text); remember_pref(prf, reflect_tiny_font, save_tiny_font, help_tiny_font, clear_tiny_font, revert_tiny_font); } make_inter_topic_separator(topics); /* -------- transform -------- */ { GtkWidget *fft_box; /* ---------------- transform options ---------------- */ fft_box = make_top_level_box(topics); make_top_level_label("transform options", fft_box); rts_fft_size = transform_size(ss); str = mus_format("%lld", rts_fft_size); prf = prefs_row_with_number("size", S_transform_size, str, 12, fft_box, fft_size_up, fft_size_down, fft_size_from_text); remember_pref(prf, reflect_fft_size, save_fft_size, help_fft_size, NULL, revert_fft_size); free(str); if (transform_size(ss) <= 2) gtk_widget_set_sensitive(prf->arrow_down, false); make_inter_variable_separator(fft_box); prf = prefs_row_with_radio_box("transform graph choice", S_transform_graph_type, transform_graph_types, NUM_TRANSFORM_GRAPH_TYPES, rts_transform_graph_type = transform_graph_type(ss), fft_box, transform_graph_type_choice); remember_pref(prf, reflect_transform_graph_type, save_transform_graph_type, help_transform_graph_type, NULL, revert_transform_graph_type); make_inter_variable_separator(fft_box); rts_transform_type = transform_type(ss); prf = prefs_row_with_list("transform", S_transform_type, transform_types[rts_transform_type], transform_types, NUM_BUILTIN_TRANSFORM_TYPES, fft_box, transform_type_from_text, transform_type_completer, NULL); remember_pref(prf, reflect_transform_type, save_transform_type, help_transform_type, clear_transform_type, revert_transform_type); make_inter_variable_separator(fft_box); rts_fft_window = fft_window(ss); prf = prefs_row_with_list("data window", S_fft_window, mus_fft_window_name(rts_fft_window), mus_fft_window_names(), MUS_NUM_FFT_WINDOWS, fft_box, fft_window_from_text, fft_window_completer, NULL); remember_pref(prf, reflect_fft_window, save_fft_window, help_fft_window, clear_fft_window, revert_fft_window); make_inter_variable_separator(fft_box); prf = prefs_row_with_scale("data window family parameter", S_fft_window_beta, 1.0, rts_fft_window_beta = fft_window_beta(ss), fft_box, fft_window_beta_scale_callback, fft_window_beta_text_callback); remember_pref(prf, reflect_fft_window_beta, save_fft_window_beta, help_fft_window_beta, NULL, revert_fft_window_beta); make_inter_variable_separator(fft_box); str = mus_format("%d", rts_max_transform_peaks = max_transform_peaks(ss)); prf = prefs_row_with_toggle_with_text("show fft peak data", S_show_transform_peaks, rts_show_transform_peaks = show_transform_peaks(ss), "max peaks:", str, 5, fft_box, transform_peaks_toggle, max_peaks_text); remember_pref(prf, reflect_transform_peaks, save_transform_peaks, help_transform_peaks, NULL, revert_transform_peaks); free(str); make_inter_variable_separator(fft_box); { const char **cmaps; int i, len; len = num_colormaps(); cmaps = (const char **)calloc(len, sizeof(const char *)); for (i = 0; i < len; i++) cmaps[i] = (const char *)colormap_name(i); rts_colormap = color_map(ss); prf = prefs_row_with_list("sonogram colormap", S_colormap, cmaps[rts_colormap], cmaps, len, fft_box, colormap_from_text, colormap_completer, NULL); remember_pref(prf, reflect_colormap, save_colormap, help_colormap, clear_colormap, revert_colormap); free(cmaps); } make_inter_variable_separator(fft_box); prf = prefs_row_with_toggle("y axis as log magnitude (dB)", S_fft_log_magnitude, rts_fft_log_magnitude = fft_log_magnitude(ss), fft_box, log_magnitude_toggle); remember_pref(prf, reflect_fft_log_magnitude, save_fft_log_magnitude, help_fft_log_magnitude, NULL, revert_fft_log_magnitude); make_inter_variable_separator(fft_box); str = mus_format("%.1f", rts_min_dB = min_dB(ss)); prf = prefs_row_with_text("minimum y-axis dB value", S_min_dB, str, fft_box, min_dB_text); remember_pref(prf, reflect_min_dB, save_min_dB, help_min_dB, NULL, revert_min_dB); free(str); make_inter_variable_separator(fft_box); prf = prefs_row_with_toggle("x axis as log freq", S_fft_log_frequency, rts_fft_log_frequency = fft_log_frequency(ss), fft_box, log_frequency_toggle); remember_pref(prf, reflect_fft_log_frequency, save_fft_log_frequency, help_fft_log_frequency, NULL, revert_fft_log_frequency); make_inter_variable_separator(fft_box); prf = prefs_row_with_radio_box("normalization", S_transform_normalization, transform_normalizations, NUM_TRANSFORM_NORMALIZATIONS, rts_transform_normalization = transform_normalization(ss), fft_box, transform_normalization_choice); remember_pref(prf, reflect_transform_normalization, save_transform_normalization, help_transform_normalization, NULL, revert_transform_normalization); } make_inter_topic_separator(topics); /* -------- marks, mixes, and regions -------- */ { GtkWidget *mmr_box; char *str1, *str2; /* ---------------- marks and mixes ---------------- */ mmr_box = make_top_level_box(topics); make_top_level_label("marks and mixes", mmr_box); saved_mark_color = ss->mark_color; prf = prefs_color_selector_row("mark and mix tag color", S_mark_color, ss->mark_color, mmr_box, mark_color_func); remember_pref(prf, NULL, save_mark_color, help_mark_color, clear_mark_color, revert_mark_color); make_inter_variable_separator(mmr_box); str1 = mus_format("%d", rts_mark_tag_width = mark_tag_width(ss)); str2 = mus_format("%d", rts_mark_tag_height = mark_tag_height(ss)); prf = prefs_row_with_two_texts("mark tag size", S_mark_tag_width, "width:", str1, "height:", str2, 4, mmr_box, mark_tag_size_text); remember_pref(prf, reflect_mark_tag_size, save_mark_tag_size, help_mark_tag_size, NULL, revert_mark_tag_size); free(str2); free(str1); make_inter_variable_separator(mmr_box); str1 = mus_format("%d", rts_mix_tag_width = mix_tag_width(ss)); str2 = mus_format("%d", rts_mix_tag_height = mix_tag_height(ss)); prf = prefs_row_with_two_texts("mix tag size", S_mix_tag_width, "width:", str1, "height:", str2, 4, mmr_box, mix_tag_size_text); remember_pref(prf, reflect_mix_tag_size, save_mix_tag_size, help_mix_tag_size, NULL, revert_mix_tag_size); free(str2); free(str1); make_inter_variable_separator(mmr_box); saved_mix_color = ss->mix_color; prf = prefs_color_selector_row("mix waveform color", S_mix_color, ss->mix_color, mmr_box, mix_color_func); remember_pref(prf, NULL, save_mix_color, help_mix_color, clear_mix_color, revert_mix_color); make_inter_variable_separator(mmr_box); str = mus_format("%d", rts_mix_waveform_height = mix_waveform_height(ss)); prf = prefs_row_with_toggle_with_text("show mix waveforms (attached to the mix tag)", S_show_mix_waveforms, rts_show_mix_waveforms = show_mix_waveforms(ss), "max waveform height:", str, 5, mmr_box, show_mix_waveforms_toggle, mix_waveform_height_text); remember_pref(prf, reflect_mix_waveforms, save_mix_waveforms, help_mix_waveforms, NULL, revert_mix_waveforms); free(str); } make_inter_topic_separator(topics); /* -------- clm -------- */ { GtkWidget *clm_box; /* ---------------- clm options ---------------- */ clm_box = make_top_level_box(topics); make_top_level_label("clm", clm_box); str = mus_format("%d", rts_speed_control_tones = speed_control_tones(ss)); rts_speed_control_style = speed_control_style(ss); prf = prefs_row_with_radio_box_and_number("speed control choice", S_speed_control_style, speed_control_styles, NUM_SPEED_CONTROL_STYLES, (int)speed_control_style(ss), str, 6, clm_box, speed_control_choice, speed_control_up, speed_control_down, speed_control_text); remember_pref(prf, reflect_speed_control, save_speed_control, help_speed_control, NULL, revert_speed_control); free(str); make_inter_variable_separator(clm_box); str = mus_format("%d", rts_sinc_width = sinc_width(ss)); prf = prefs_row_with_text("sinc interpolation width in srate converter", S_sinc_width, str, clm_box, sinc_width_text); remember_pref(prf, reflect_sinc_width, save_sinc_width, help_sinc_width, NULL, revert_sinc_width); free(str); } make_inter_topic_separator(topics); /* -------- programming -------- */ { GtkWidget *prg_box; /* ---------------- listener options ---------------- */ prg_box = make_top_level_box(topics); make_top_level_label("listener options", prg_box); prf = prefs_row_with_toggle("show listener at start up", S_show_listener, rts_show_listener = listener_is_visible(), prg_box, show_listener_toggle); remember_pref(prf, reflect_show_listener, save_show_listener, help_show_listener, clear_show_listener, revert_show_listener); make_inter_variable_separator(prg_box); rts_listener_prompt = mus_strdup(listener_prompt(ss)); prf = prefs_row_with_text("prompt", S_listener_prompt, listener_prompt(ss), prg_box, listener_prompt_text); remember_pref(prf, reflect_listener_prompt, save_listener_prompt, help_listener_prompt, NULL, revert_listener_prompt); make_inter_variable_separator(prg_box); str = mus_format("%d", rts_print_length = print_length(ss)); prf = prefs_row_with_text("number of vector elements to display", S_print_length, str, prg_box, print_length_text); remember_pref(prf, reflect_print_length, save_print_length, help_print_length, NULL, revert_print_length); free(str); make_inter_variable_separator(prg_box); rts_listener_font = mus_strdup(listener_font(ss)); prf = prefs_row_with_text("font", S_listener_font, listener_font(ss), prg_box, listener_font_text); remember_pref(prf, reflect_listener_font, save_listener_font, help_listener_font, clear_listener_font, revert_listener_font); make_inter_variable_separator(prg_box); saved_listener_color = ss->listener_color; prf = prefs_color_selector_row("background color", S_listener_color, ss->listener_color, prg_box, listener_color_func); remember_pref(prf, NULL, save_listener_color, help_listener_color, clear_listener_color, revert_listener_color); make_inter_variable_separator(prg_box); saved_listener_text_color = ss->listener_text_color; prf = prefs_color_selector_row("text color", S_listener_text_color, ss->listener_text_color, prg_box, listener_text_color_func); remember_pref(prf, NULL, save_listener_text_color, help_listener_text_color, clear_listener_text_color, revert_listener_text_color); } /* -------- audio -------- */ { GtkWidget *aud_box; /* ---------------- audio options ---------------- */ aud_box = make_top_level_box(topics); make_top_level_label("audio options", aud_box); str = mus_format("%d", rts_dac_size = dac_size(ss)); prf = prefs_row_with_text("dac buffer size", S_dac_size, str, aud_box, dac_size_text); remember_pref(prf, reflect_dac_size, save_dac_size, help_dac_size, NULL, revert_dac_size); free(str); make_inter_variable_separator(aud_box); prf = prefs_row_with_toggle("fold in otherwise unplayable channels", S_dac_combines_channels, rts_dac_combines_channels = dac_combines_channels(ss), aud_box, dac_combines_channels_toggle); remember_pref(prf, reflect_dac_combines_channels, save_dac_combines_channels, help_dac_combines_channels, NULL, revert_dac_combines_channels); } set_dialog_widget(PREFERENCES_DIALOG, preferences_dialog); gtk_widget_show(preferences_dialog); prefs_unsaved = false; prefs_set_dialog_title(NULL); return(preferences_dialog); } snd-16.1/draw.fs0000644000076400007640000002024712327441227011633 0ustar bilbil\ draw.fs -- draw.scm -> draw.fs \ Author: Michael Scholz \ Created: 05/12/18 23:36:09 \ Changed: 14/04/28 03:52:17 \ \ @(#)draw.fs 1.19 4/28/14 \ make-current-window-display ( -- ) \ close-current-window-display ( -- ) require extensions \ --- inset overall waveform; if click, move to that location --- #f value current-window-display-is-running \ for prefs hide 0.20 constant inset-width 0.25 constant inset-height : update-current-window-location <{ snd -- #f }> current-window-display-is-running if snd channels 0 ?do 'inset-envelope snd i channel-property { vals } \ set edit-position to impossible value vals array? if vals 'edit-position -2 array-assoc-set! to vals then loop then #f ; : display-current-window-location <{ snd chn -- }> current-window-display-is-running snd chn time-graph? && if snd chn undef axis-info { axinf } axinf 12 array-ref { grf-width } inset-width grf-width f* fround->s { width } grf-width width - { x-offset } axinf 11 array-ref axinf 13 array-ref - { grf-height } inset-height grf-height f* fround->s { height } axinf 13 array-ref 10 - { chan-offset } chan-offset height 2/ + { y-offset } snd channel-style channels-separate = if chn else 0 then { grf-chn } axinf 19 array-ref { new-peaks } snd chn #f framples { frms } #f { data0 } #f { data1 } width 10 > height 10 > && frms 0> && chn 0= snd channel-style channels-superimposed <> || && if x-offset chan-offset height + width 2 snd grf-chn undef #f fill-rectangle drop x-offset chan-offset 2 height snd grf-chn undef #f fill-rectangle drop snd chn right-sample frms f/ width f* fround->s { rx } snd chn left-sample frms f/ width f* fround->s { lx } x-offset lx + chan-offset rx lx - 1 max height snd grf-chn selection-context #f fill-rectangle drop 'inset-envelope snd chn channel-property { old-env } old-env array? if new-peaks not old-env 'width array-assoc-ref width = && old-env 'height array-assoc-ref height = && old-env 'y-offset array-assoc-ref y-offset = && old-env 'edit-position array-assoc-ref snd chn edit-position = && if old-env 'data0 array-assoc-ref to data0 old-env 'data1 array-assoc-ref to data1 #t else #f then else #f then unless \ else (old-env == #f) snd chn current-edit-position 0 frms make-graph-data { data } \ data may be a vct or a list of two vcts data vct? if data vct-peak else data 0 array-ref vct-peak data 1 array-ref vct-peak fmax then { data-max } data-max f0> if height data-max f2* f/ else 0.0 then { data-scaler } width 2* { new-len } data vct? if data else data 0 array-ref then length { data-len } data-len width f/ fround->s { step } data-len width > if new-len make-array to data0 data array? if new-len make-array to data1 then 0 { idxi } 0 { idxj } data-max fnegate { max-y } data-max { min-y } 0 { stepper } begin idxi data-len < idxj new-len < && while data1 if max-y data 1 array-ref idxi vct-ref fmax to max-y min-y data 0 array-ref idxi vct-ref fmin to min-y else max-y data idxi vct-ref fmax to max-y then stepper 1+ to stepper stepper step >= if data0 idxj x-offset array-set! data0 idxj 1+ y-offset max-y data-scaler f* f- fround->s array-set! data-max fnegate to max-y data1 if data1 idxj x-offset array-set! data1 idxj 1+ y-offset min-y data-scaler f* f- fround->s array-set! data-max to min-y then x-offset 1+ to x-offset stepper step - to stepper idxj 2 + to idxj then idxi 1+ to idxi repeat begin idxj new-len < while data0 idxj data0 idxj 2 - array-ref array-set! data0 idxj 1+ data0 idxj 1 - array-ref array-set! data1 if data1 idxj data1 idxj 2 - array-ref array-set! data1 idxj 1+ data1 idxj 1 - array-ref array-set! then idxj 2 + to idxj repeat else width data-len f/ fround->s { xstep } data-len 2* make-array to data0 data array? if new-len 2* make-array to data1 then 0 { idxj } x-offset { xj } data-len 0 ?do data0 idxj xj array-set! data1 if data0 idxj 1+ y-offset data 1 array-ref i vct-ref data-scaler f* f- fround->s array-set! data1 idxj xj array-set! data1 idxj 1+ y-offset data 0 array-ref i vct-ref data-scaler f* f- fround->s array-set! else data0 idxj 1+ y-offset data i vct-ref data-scaler f* f- fround->s array-set! then idxj 2 + to idxj xj xstep + to xj loop then #() 'width width array-assoc-set! ( vals ) 'height height array-assoc-set! ( vals ) 'edit-position snd chn edit-position array-assoc-set! ( vals ) 'data0 data0 array-assoc-set! ( vals ) 'data1 data1 array-assoc-set! ( vals ) 'y-offset y-offset array-assoc-set! { vals } 'inset-envelope vals snd chn set-channel-property drop then data1 length 2 mod if data1 array-pop drop then data0 snd grf-chn time-graph draw-lines drop data1 if data1 snd grf-chn time-graph draw-lines drop then then then ; : click-current-window-location <{ snd chn button state x y axis -- f }> current-window-display-is-running axis time-graph = && if snd chn undef axis-info { axinf } axinf 12 array-ref { grf-width } inset-width grf-width f* fround->s { width } grf-width width - { x-offset } axinf 11 array-ref axinf 13 array-ref - inset-height f* fround->s { height } axinf 13 array-ref 10 - { chan-offset } width 0> x x-offset >= && x grf-width <= && y chan-offset >= && y chan-offset height + <= && if snd chn #f framples x x-offset f- width f/ f* fround->s { samp } snd chn left-sample { ls } snd chn right-sample { rs } samp snd chn #f set-cursor drop samp ls < samp rs > || if samp ls rs - 2/ - 0 max snd chn #f framples 1- min snd chn set-right-sample drop then snd chn update-time-graph drop #t else #f then else #f then ; : undo-cb { snd chn -- proc; self -- } 0 proc-create snd , chn , does> { self -- } 'inset-envelope #f self @ ( snd ) self cell+ @ ( chn ) set-channel-property drop ; : install-current-window-location <{ snd -- }> snd channels 0 ?do 'inset-envelope snd i set-channel-property-save-state-ignore drop snd i undo-hook snd i undo-cb add-hook! loop ; set-current : make-current-window-display ( -- ) doc" Display in upper right corner the overall current sound \ and where the current window fits in it." current-window-display-is-running unless #t to current-window-display-is-running after-open-hook <'> install-current-window-location add-hook! after-graph-hook <'> display-current-window-location add-hook! mouse-click-hook <'> click-current-window-location add-hook! update-hook <'> update-current-window-location add-hook! then ; : close-current-window-display ( -- ) current-window-display-is-running if #f to current-window-display-is-running after-open-hook <'> install-current-window-location remove-hook! drop after-graph-hook <'> display-current-window-location remove-hook! drop mouse-click-hook <'> click-current-window-location remove-hook! drop update-hook <'> update-current-window-location remove-hook! drop sounds each { snd } snd channels 0 ?do snd i undo-hook <'> undo-cb remove-hook! drop loop end-each then ; previous \ draw.fs ends here snd-16.1/clm.rb0000644000076400007640000017725012440052536011450 0ustar bilbil# clm.rb -- Ruby extension # Author: Michael Scholz # Created: 09/10/14 23:02:57 # Changed: 14/11/30 18:00:42 # Ruby extensions: # # array?(obj) alias list?(obj) # hash?(obj) # string?(obj) # regexp?(obj) # symbol?(obj) # number?(obj) # integer?(obj) # float?(obj) # rational?(obj) # complex?(obj) # boolean?(obj) # proc?(obj) # thunk?(obj) # method?(obj) # func?(obj) # mus?(obj) # get_func_name(n) # assert_type(condition, obj, pos, msg) # identity(arg) # ignore(*rest) # with_silence(exception) do |old_verbose, old_debug| ... end # # provided?(feature) # provide(feature) # features(all) # # Backward compatibility aliases and constants (from sndXX.scm) # # enum(*names) # # class Object # null? # function?(obj) # snd_func(name, *rest, &body) # set_snd_func(name, val, *rest, &body) # snd_apropos(str_or_sym) # # NilClass(arg) # Fixnum(arg) # # class NilClass # each # apply(func, *rest, &body) # empty? # zero? # nonzero? # to_vct # to_vector # to_poly # +(other) # -(other) # *(other) # # backward compatibility methods: # String#to_sym, Symbol#to_sym # make_array(len, init, &body) # Array#insert # Float#step # Numeric#to_c # Range#step # Enumerable#each_index # Enumerable#zip # # class Array # to_pairs # each_pair do |x, y| ... end # to_string(len) # first=(val) # last=(val) # pick # rand # rand! # add(other) # add!(other) # subtract(other) # subtract!(other) # multiply(other) # multiply!(other) # offset(scl) # offset!(scl) # scale(scl) # scale!(scl) # to_vector # car # car= # cadr # cadr= # caddr # caddr= # cadddr # cadddr= # caddddr # caddddr= # cdr # step(n) # apply(func, *rest, &body) # # class Vec < Array # Vec[] # initialize(len, init, &body) # inspect # to_s # to_vector # +(other) # -(other) # *(other) # # Vec(obj) # make_vector(len, init, &body) # vector?(obj) # vector(*args) # # class String # to_vector # to_vct # # Vct(obj) # make_vct!(len, init) do |i| ... end # # class Vct # Vct[] # name # to_vct # to_vector # apply(func, *rest, &body) # +(other) handles self.offset (Numeric) and self.add (Array, Vec, Vct) # -(other) handles self.offset (Numeric) and self.subtract (Array, Vec, Vct) # *(other) handles self.scale (Numeric) and self.multiply (Array, Vec, Vct) # step(n) # [](idx, size) # # class Fixnum # +(other) handles other.offset on Vct, Array, and Vec # *(other) handles other.scale on Vct, Array, and Vec # # class Float # +(other) handles other.offset on Vct, Array, and Vec # *(other) handles other.scale on Vct, Array, and Vec # # mus_a0(gen) # set_mus_a0(gen, val) # mus_a1(gen) # set_mus_a1(gen, val) # mus_a2(gen) # set_mus_a2(gen, val) # mus_b1(gen) # set_mus_b1(gen, val) # mus_b2(gen) # set_mus_b2(gen, val) # # class Mus # run(arg1, arg2) # apply(*rest) # inspect # close # xcoeff=(index, val) # ycoeff=(index, val) # a0 a0=(val) # a1 a1=(val) # a2 a2=(val) # b1 b1=(val) # b2 b2=(val) # # class Musgen base class for generators written in Ruby # initialize # inspect # to_s # run(val1, val2) # apply(*rest) # eql?(other) # reset # # class Numeric # positive? # negative? # # class Integer # even? # odd? # prime? # # module Enumerable # map_with_index do |x, i| ... end # map_with_index! do |x, i| ... end # clm_cycle # clm_cycle=(val) # # as_one_edit_rb(*origin, &body) # map_channel_rb(beg, dur, snd, chn, edpos, edname, &body) # map_chan_rb(beg, dur, edpos, snd, chn, &body) # # module Info # description=(text) # description # # class Proc # to_method(name, klass) # to_str # to_body # source # source= # # make_proc2method(name, prc) # make_proc_with_setter(name, getter, setter) # make_proc_with_source(string, bind) # proc_source(prc) set_proc_source(prc, val) # # Multi-line input to the Snd listener and Emacs/inf-snd.el # # $emacs_eval_hook.call(line) # run_emacs_eval_hook(line) # # class Snd_eval # Snd_eval.count_level(line) # # class Snd_prompt # initialize(level) # inspect # update(level) # reset # # start_emacs_eval(file) # start_listener_eval(file) # stop_emacs_eval # stop_listener_eval # # Debugging resp. inspecting local variables # # debug_properties(name) set_debug_properties(name, val) # debug_property(key, name) set_debug_property(key, val, name) # debug_binding(name) set_debug_binding(bind, name) # display_all_variables(name) # each_variables(bind, &body) # # let(*rest) do |*rest| ... end # # Utilities: # # close_sound_extend(snd) # times2samples(start, dur) # random(n) # logn(r, b) # car(v), cadr(v), caddr(v), cdr(v) # warning(*args), die(*args), error(*args) # clm_message(*args), message(*args), debug(*args), debug_trace(*args) # # class Snd # Snd.add_sound_path(path) # Snd.open_from_path(fname) # Snd.find_from_path(fname) # Snd.fullname(fname) # Snd.load_path # Snd.message(*args) # Snd.display(*args) # Snd.warning(*args) # Snd.die(*args) # Snd.error(*args) # Snd.debug(*args) # Snd.debug_trace(*args) # Snd.sounds # Snd.regions # Snd.marks(snd, chn) # Snd.snd(snd) # Snd.chn(chn) # Snd.catch(tag, retval) # Snd.throw(tag, *rest) # Snd.raise(tag, *rest) # # snd_catch(tag, retval) # snd_throw(tag, *rest) # snd_raise(tag, *rest) # # gloop(*args) do |args| ... end # get_args(args, key, default) # get_shift_args(args, key, default) # get_class_or_key(args, klass, key, default) # optkey(args, *rest) # load_init_file(file) # # edit_list_proc_counter # set_edit_list_proc_counter def make_polar(r, theta) Complex(cos(theta) * r, sin(theta) * r) end def make_rectangular(re, im = 1.0) Complex(re, im) end def array?(obj) obj.kind_of?(Array) end alias list? array? def hash?(obj) obj.kind_of?(Hash) end def string?(obj) obj.kind_of?(String) end def regexp?(obj) obj.kind_of?(Regexp) end def symbol?(obj) obj.kind_of?(Symbol) end def number?(obj) obj.kind_of?(Numeric) end def integer?(obj) obj.kind_of?(Fixnum) end def float?(obj) obj.kind_of?(Float) end def rational?(obj) obj.kind_of?(Rational) end def complex?(obj) obj.kind_of?(Complex) end def boolean?(obj) obj.kind_of?(TrueClass) or obj.kind_of?(FalseClass) end def proc?(obj) obj.kind_of?(Proc) end def thunk?(obj) obj.kind_of?(Proc) and obj.arity.zero? end def method?(obj) obj.kind_of?(Method) end def func?(obj) obj.kind_of?(String) or obj.kind_of?(Symbol) end def mus?(obj) obj.kind_of?(Mus) end def binding?(obj) obj.kind_of?(Binding) end def get_func_name(n = 1) if ca = caller(n)[0].scan(/^.*:in `(.*)'/).first ca.first else "top_level" end end def assert_type(condition, obj, pos, msg) condition or Kernel.raise(TypeError, format("%s: wrong type arg %d, %p, wanted %s", get_func_name(2), pos, obj, msg)) end def identity(arg) arg end def ignore(*rest) nil end unless defined? $LOADED_FEATURES alias $LOADED_FEATURES $" end def provided?(feature) $LOADED_FEATURES.map do |f| File.basename(f) end.member?(feature.to_s.tr("_", "-")) end def provide(feature) $LOADED_FEATURES.push(feature.to_s) end def features(all = nil) if all $LOADED_FEATURES.map do |f| File.basename(f) end else $LOADED_FEATURES.map do |f| next if f.include?("/") or f.include?(".") f end.compact end end # with_silence(exception) do |old_verbose, old_debug| ... end # # subpress debug messages (mostly on older Ruby versions) # # with_silence do $global_var ||= value end # with_silence(LoadError) do require("nonexistent.file") end def with_silence(exception = StandardError) old_verbose = $VERBOSE old_debug = $DEBUG $VERBOSE = false $DEBUG = false ret = if block_given? begin yield(old_verbose, old_debug) rescue exception false end else false end $VERBOSE = old_verbose $DEBUG = old_debug ret end # ruby19 moved complex.rb and rational.rb to C # (See ruby/Changelog Sun Mar 16 08:51:41 2008.) if defined? Complex require "cmath" include CMath else with_silence do # lib/complex.rb is deprecated require "complex" end include Math end unless defined? Rational with_silence do # lib/rational.rb is deprecated require "rational" end end unless provided?(:sndlib) with_silence do # warning: method redefined; discarding old rand require "sndlib" end end TWO_PI = PI * 2.0 unless defined? TWO_PI HALF_PI = PI * 0.5 unless defined? HALF_PI # # Backward compatibility aliases and constants (from sndXX.scm) # # alias new old if provided? :snd alias save_options save_state alias delete_samples_with_origin delete_samples alias default_output_type default_output_header_type alias default_output_format default_output_sample_type alias mus_audio_set_oss_buffers mus_oss_set_buffers unless defined? mus_file_data_clipped alias mus_file_data_clipped mus_clipping alias set_mus_file_data_clipped set_mus_clipping end alias mus_data_clipped mus_clipping alias set_mus_data_clipped set_mus_clipping alias dac_is_running playing # backwards compatibility for snd 8 alias make_ppolar make_two_pole alias make_zpolar make_two_zero alias make_average make_moving_average alias average moving_average alias average? moving_average? # snd10.scm def make_sum_of_sines(*args) sines, frequency, initial_phase = nil optkey(args, binding, [:sines, 1], [:frequency, 0.0], [:initial_phase, 0.0]) gen = make_nsin(:frequency, frequency, :n, sines) gen.phase = initial_phase gen end alias sum_of_sines nsin alias sum_of_sines? nsin? def make_sum_of_cosines(*args) cosines, frequency, initial_phase = nil optkey(args, binding, [:cosines, 1], [:frequency, 0.0], [:initial_phase, 0.0]) gen = make_ncos(:frequency, frequency, :n, cosines) gen.phase = initial_phase gen end alias sum_of_cosines ncos alias sum_of_cosines? ncos? def make_sine_summation(*args) frequency, initial_phase, n, a, ratio = nil optkey(args, binding, [:frequency, 0.0], [:initial_phase, 0.0], [:n, 1], [:a, 0.5], [:ratio, 1.0]) gen = make_nrxysin(:frequency, frequency, :ratio, ratio, :n, n, :r, a) gen.phase = initial_phase gen end alias sine_summation nrxysin alias sine_summation? nrxysin? # snd13.scm def clm_print(fmt, *args) snd_print(format(fmt, *args)) end unless defined? clm_print end # enum("foo", :bar, "FOO_BAR") # produces three constants # Foo == 0 # Bar == 1 # FOO_BAR == 2 if ?a.kind_of?(String) def enum(*names) names.map_with_index do |name, i| const_name = name.to_s const_name[0] = const_name[0].capitalize Object.const_set(const_name, i) const_name end end else def enum(*names) cap_alpha = ?A.kind_of?(String) ? ?A.sum : ?A lit_alpha = ?a.kind_of?(String) ? ?a.sum : ?a letter_diff = cap_alpha - lit_alpha names.map_with_index do |name, i| const_name = name.to_s if const_name[0].between?(?a, ?z) const_name[0] += letter_diff end Object.const_set(const_name, i) const_name end end end class Object def null? self.nil? or (self.respond_to?(:zero?) and self.zero?) or (self.respond_to?(:empty?) and self.empty?) or (self.respond_to?(:length) and self.length.zero?) end def function?(obj) func?(obj) and Snd.catch(:all, false) do self.method(obj) end.first rescue false end # Float(nil) ==> 0.0 like Integer(nil) ==> 0 alias old_Float Float def new_Float(numb) if numb.kind_of?(NilClass) 0.0 else old_Float(numb) end end alias Float new_Float def snd_func(name, *rest, &body) send(name.to_s, *rest, &body) end def set_snd_func(name, val, *rest, &body) send(format("set_%s", name.to_s), val, *rest, &body) end # snd_apropos(str_or_sym) # if `str_or_sym' is a symbol, returns snd_help result, # if `str_or_sym' is a string or regexp it looks in # self.public_methods, # self.protected_methods, # self.private_methods, # Object.constants, and # Kernel.global_variables and returns an array of strings or nil. # # [].snd_apropos(/^apply/) ==> ["apply", "apply_controls"] # vct(0).snd_apropos("subseq") ==> ["subseq", "vct_subseq"] # snd_apropos(/^mus_sound/) ==> ["mus_sound_...", ...] def snd_apropos(str_or_sym) case str_or_sym when Symbol snd_help(str_or_sym) when String, Regexp res = [] [self.public_methods, self.protected_methods, self.private_methods, Object.constants, Kernel.global_variables].each do |m| res += m.grep(/#{str_or_sym}/) end res else nil end end end def NilClass(arg) nil end alias Fixnum Integer class NilClass def each nil end def apply(func, *rest, &body) nil end def empty? true end # Integer(nil) ==> 0 def zero? true end def nonzero? false end def to_vct vector2vct([]) end def to_vector vector() end def to_poly poly() end def +(other) other end def -(other) other end def *(other) snd_func(other.class.name, nil) end end # If $DEBUG = true, on older Ruby versions warnings occur about # missing NilClass#to_str and Symbol#to_str if $DEBUG and RUBY_VERSION < "1.8.0" class Object def method_missing(id, *args) if id == :to_str self.class.class_eval do define_method(id, lambda do | | self.to_s end) end id.id2name else Kernel.raise(NameError, format("[version %s] undefined method `%s'", RUBY_VERSION, id.id2name)) end end end end class String def to_sym self.intern end unless defined? "a".to_sym end class Symbol def to_sym self end unless defined? :a.to_sym end alias object_id __id__ unless defined? object_id # Provides descriptions of instances of classes, see nb.rb, # xm-enved.rb, etc. # # m = lambda do |*args| puts args end # m.info = "my description" # puts m.info module Info def description=(val) @description = val.to_s end alias info= description= def description if defined?(@description) and string?(@description) and (not @description.empty?) @description else "no description available" end end alias info description end unless defined? snd_help alias snd_help get_help end $array_print_length = 10 def print_length $array_print_length end unless defined? print_length def set_print_length(val) $array_print_length = val end unless defined? set_print_length module Enumerable def map_with_index i = -1 self.map do |x| yield(x, i += 1) end end def map_with_index! i = -1 self.map! do |x| yield(x, i += 1) end end def clm_cycle unless defined? @clm_cycle_index then @clm_cycle_index = 0 end val = self[@clm_cycle_index % self.length] @clm_cycle_index += 1 if @clm_cycle_index == self.length then @clm_cycle_index = 0 end val end def clm_cycle=(val) unless defined? @clm_cycle_index then @clm_cycle_index = 0 end self[@clm_cycle_index % self.length] = val @clm_cycle_index += 1 if @clm_cycle_index == self.length then @clm_cycle_index = 0 end val end attr_accessor :clm_cycle_index # backward compatibility methods def each_index self.each_with_index do |val, i| yield(i) end end unless vct(0).respond_to?(:each_index) # Enumerable#zip, new in ruby core since 19-Nov-2002. # a = [4, 5, 6] # b = [7, 8, 9] # [1, 2, 3].zip(a, b) ==> [[1, 4, 7], [2, 5, 8], [3, 6, 9]] # [1, 2].zip(a, b) ==> [[1, 4, 7], [2, 5, 8]] # a.zip([1, 2],[8]) ==> [[4, 1, 8], [5, 2, nil], [6, nil, nil]] def clm_zip(*objs) args = objs.map do |obj| obj.to_a end res = self.to_a res.each_with_index do |val, i| ary = [val] args.each do |obj| ary.push(obj[i]) end if block_given? yield(*ary) else res[i] = ary end end res end alias zip clm_zip unless [].respond_to?(:zip) end # Older Ruby versions lack Array.new(10) do |i| ... end # make_array # make_array(10) # make_array(10, 1.0) # make_array(10) do |i| ... end def make_array(len = 0, init = nil) if len >= 0 if block_given? Array.new(len, init).map_with_index do |x, i| yield(i) end else Array.new(len, init) end else Kernel.raise(TypeError, format("array length < 0 (%p)?", len)) end end class Array def insert(pos, *args) unless args.empty? if pos < 0 pos = self.length - (pos.abs - 1) end tmp = self.dup self[pos, args.length] = args self[pos + args.length..-1] = tmp[pos..-1] end self end unless defined? [].insert # [0.0, 0.0, 0.5, 0.2, 1.0, 1.0].to_pairs # ==> [[0.0, 0.0], [0.5, 0.2], [1.0, 1.0]] def to_pairs ary = [] self.step(2) do |a, b| ary.push([a, b]) end ary end # [0.0, 0.0, 0.5, 0.2, 1.0, 1.0].each_pair do |x, y| # print x, " ", y, "\n" # end ==> 0.0 0.0 # 0.5 0.2 # 1.0 1.0 def each_pair ary = [] self.step(2) do |a, b| ary.push(yield(a, b)) end ary end # prints flat float array more prettily def to_string(len = print_length) ary = self.flatten str = "[" ary.each_with_index do |val, i| if i < len str = str + "%1.3f, " % val.to_f else break end end if ary.length > len str += "..." else str.chop!.chop! end str += "]" end alias old_to_s to_s alias to_s inspect def first=(val) self[0] = val end def last=(val) self[-1] = val end # ary.pick ==> random value # ary.pick(3) ==> [x, y, z] # ary.pick(true) ==> whole ary randomized def array_pick(n = 1) n = self.length if n == true if n == 1 self[kernel_rand(self.length)] else (0...n).map do |i| self[kernel_rand(self.length)] end end end alias pick array_pick def array_rand tmp = self.dup tmp.each_index do |i| r = kernel_rand(tmp.length) tmp[r], tmp[i] = tmp[i], tmp[r] end tmp end alias rand array_rand def array_rand! self.each_index do |i| r = kernel_rand(self.length) self[r], self[i] = self[i], self[r] end self end alias rand! array_rand! def add(other) new_ary = self.dup [self.length, other.length].min.times do |i| new_ary[i] += other[i] end new_ary end def add!(other) [self.length, other.length].min.times do |i| self[i] += other[i] end self end def subtract(other) new_ary = self.dup [self.length, other.length].min.times do |i| new_ary[i] -= other[i] end new_ary end def subtract!(other) [self.length, other.length].min.times do |i| self[i] -= other[i] end self end def multiply(other) new_ary = self.dup [self.length, other.length].min.times do |i| new_ary[i] *= other[i] end new_ary end def multiply!(other) [self.length, other.length].min.times do |i| self[i] *= other[i] end self end def offset(scl) scl = Float(scl) self.class.new(self.length) do |i| self[i] + scl end end def offset!(scl) scl = Float(scl) self.map! do |val| val += scl end end def scale(scl) scl = Float(scl) self.class.new(self.length) do |i| self[i] * scl end end def scale!(scl) scl = Float(scl) self.map! do |val| val *= scl end end def to_vector Vec.new(self.length) do |i| Float(self[i]) end end def car self[0] end def car=(val) self[0] = val end def cadr self[1] end def cadr=(val) self[1] = val end def caddr self[2] end def caddr=(val) self[2] = val end def cadddr self[3] end def cadddr=(val) self[3] = val end def caddddr self[4] end def caddddr=(val) self[4] = val end def cdr self[1..-1] end def step(n = 1) 0.step(self.length - n, n) do |i| yield(*self[i, n]) end self end add_help(:apply, "Array#apply([:func,] *rest, &body) \ Applies function or procedure with possible rest args \ to each element of Array or subclasses of Array. [0, 1, 2].apply(\"a: %d\\n\") do |fmt, a| printf(fmt, a) end [0, 1, 2].apply(:printf, \"a: %d\\n\") both produce a: 0 a: 1 a: 2 [1, 2, 3, 4].apply(:+) # ==> 10 %w(snd sndplay with_sound).apply(:length) # ==> [3, 7, 10] [[1, 2, 3, 4], [1, 2, 3], [1, 2]].apply(:max) # ==> [4, 3, 2] [vct(0.1, 0.2, 0.3), vct(-0.1, -0.2, -0.3)].apply(:peak) # ==> [0.3, 0.3] sounds.apply(:map) do |s| puts s end sounds.apply(:close_sound)") def apply(func, *rest, &body) if block_given? and (not symbol?(func)) rest.unshift(func) self.map do |item| body.call(*rest + [item]) end else case func when Proc, Method self.map do |item| func.call(*rest + [item]) end when Symbol, String meths = self.methods if body and (meths.member?(func.to_s) or meths.member?(func.to_sym)) # map, each, ... self.send(func, *rest, &body) else receiver = self.compact.first meths = receiver.methods if receiver and (meths.member?(func.to_s) or meths.member?(func.to_sym)) # methods case func.to_sym when :+, :-, :* res = receiver self[1..-1].compact.map do |item| res = res.send(func, *rest + [item]) end res else len = rest.length + ((array?(receiver) and receiver.length) or 1) if receiver.method(func).arity.abs == len # remove_file (String(WS) in ws.rb) self.map do |item| send(func, *rest + [item]) end else # length, max, min, ... self.map do |item| item.send(func, *rest) end end end else # functions self.map do |item| send(func, *rest + [item]) end end end end end end # original operands +, -, and * can now handle nil and numberic # (offset, multiply) # # [].+(ary) concatenate arrays # [].+(number) [].add(number) unless defined? [].ary_plus alias old_ary_plus + def ary_plus(other) case other when Numeric self.offset(other) when NilClass self else self.old_ary_plus(other) end end alias + ary_plus end # [].-(ary) intersection # [1, 2, 3, 4] - [2, 3] ==> [1, 4] # [] - number [].offset unless defined? [].ary_minus alias old_ary_minus - def ary_minus(other) case other when Numeric self.offset(-other) when NilClass self else self.old_ary_minus(other) end end alias - ary_minus end # [].*(n) repetition or [].join(n) # [5] * 3 ==> [5, 5, 5] # ["foo", "bar"] * "-" ==> "foo-bar" unless defined? [].ary_times alias old_ary_times * def ary_times(other) case other when NilClass nil.to_a else self.old_ary_times(other) end end alias * ary_times end end # name Vector is in use (lib/ruby/1.9/matrix.rb) class Vec < Array def self.[](*ary) self.new(ary.length) do |i| ary[i] end end def initialize(len, init = 0.0, &body) @name = "vector" if len >= 0 if block_given? super(len, &body) else super(len, init) end else Kernel.raise(TypeError, format("array length < 0 (%p)?", len)) end if test = self.detect do |x| (not number?(x)) end Kernel.raise(TypeError, format("only numeric elements (%p)?", test)) end end def inspect str = "%s(" % @name self.each do |val| str = str + "%s, " % val end if self.length > 0 then str.chop!.chop! end str += ")" str end def to_s if self.length > 0 vals = ":" self.map do |val| vals = vals + " %s" % val end else vals = "" end format("#<%s[%d]%s>", self.class, self.length, vals) end def +(other) case other when Numeric self.offset(other).to_vector when Array, Vec, Vct self.add(other.to_vector) when NilClass self end end def -(other) case other when Numeric self.offset(-other).to_vector when Array, Vec, Vct self.subtract(other.to_vector) when NilClass self end end def *(other) case other when Numeric self.scale(other).to_vector when Array, Vec, Vct self.multiply(other.to_vector) when NilClass nil.to_vector end end end def Vec(obj) if obj.nil? then obj = [] end assert_type(obj.respond_to?(:to_vector), obj, 0, "an object containing method \ 'to_vector' (Vct, String, Array and subclasses)") obj.to_vector end def make_vector(len, init = 0.0, &body) Vec.new(len, init, &body) end def vector?(obj) obj.kind_of?(Vec) end def vector(*args) args.to_vector end class String def to_vector if self.scan(/^vector\([-+,.)\d\s]+/).null? nil else eval(self) end end def to_vct if self.scan(/^vct\([-+,.)\d\s]+/).null? nil else eval(self) end end end def Vct(obj) if obj.nil? then obj = [] end assert_type(obj.respond_to?(:to_vct), obj, 0, "an object containing method \ 'to_vct' (Vct, String, Array and subclasses)") obj.to_vct end def make_vct!(len, init = 0.0, &body) if block_given? Vct.new(len, &body) else Vct.new(len, init) end end class Vct def self.[](*ary) self.new(ary.length) do |i| ary[i] end end def name self.class.to_s.downcase end def to_vct self end def to_vector Vec.new(self.length) do |i| self[i] end end def apply(*rest, &body) self.to_a.apply(*rest, &body) end def +(other) case other when Numeric self.offset(other) when Array, Vec, Vct self.add(other.to_vct) when NilClass self end end def -(other) case other when Numeric self.offset(-other) when Array, Vec, Vct self.subtract(other.to_vct) when NilClass self end end def *(other) case other when Numeric self.scale(other) when Array, Vec, Vct self.multiply(other.to_vct) when NilClass nil.to_vct end end def step(n = 1, &body) self.to_a.step(n, &body) end # v = vct(0, 1, 2, 3, 4) # v[2..4] ==> vct(2.000, 3.000, 4.000) # v[2...4] ==> vct(2.000, 3.000) # v[3, 4] ==> vct(3.000, 4.000) # v[-1] ==> 4.0 def vct_ref_extend(idx, size = nil) case idx when Fixnum if idx < 0 then idx += self.length end if idx < 0 then Snd.raise(:out_of_range, "index < 0", idx) end if integer?(size) size += idx - 1 if size >= self.length then size = self.length - 1 end if size.between?(0, self.length - 1) and size >= idx self.subseq(idx, size) else nil.to_vct # i.e. false end else vct_ref(self, idx) end when Range beg = idx.first len = idx.last if beg < 0 then beg += self.length end if len < 0 then len += self.length end if len >= self.length then len = self.length - 1 end # exclude_end?: (1..2) ==> false # (1...2) ==> true if idx.exclude_end? then len -= 1 end if beg.between?(0, self.length - 1) and len >= beg self.subseq(beg, len) else nil.to_vct # i.e. false end end end # alias [] vct_ref_extend # This is required since Ruby 1.9. alias zip clm_zip if [].respond_to?(:zip) end class Fixnum # no reloading (load "clm.rb") unless defined? 0.new_int_plus alias int_plus + def new_int_plus(other) case other when Vct, Array, Vec other.offset(Float(self)) when NilClass self else self.int_plus(other) end end alias + new_int_plus end unless defined? 0.new_int_times alias int_times * def new_int_times(other) case other when Vct, Array, Vec other.scale(self) when NilClass 0 else self.int_times(other) end end alias * new_int_times end end class Float # no reloading (load "clm.rb") unless defined? 0.0.new_float_plus alias float_plus + def new_float_plus(other) case other when Vct, Array, Vec other.offset(self) when NilClass self else self.float_plus(other) end end alias + new_float_plus end unless defined? 0.0.new_float_times alias float_times * def new_float_times(other) case other when Vct, Array, Vec other.scale(self) when NilClass 0.0 else self.float_times(other) end end alias * new_float_times end unless defined? 0.0.imag def imag 0.0 end alias image imag end end def mus_a0(gen) mus_xcoeff(gen, 0) end def set_mus_a0(gen, val) set_mus_xcoeff(gen, 0, val) end def mus_a1(gen) mus_xcoeff(gen, 1) end def set_mus_a1(gen, val) set_mus_xcoeff(gen, 1, val) end def mus_a2(gen) mus_xcoeff(gen, 2) end def set_mus_a2(gen, val) set_mus_xcoeff(gen, 2, val) end def mus_b1(gen) mus_ycoeff(gen, 1) end def set_mus_b1(gen, val) set_mus_ycoeff(gen, 1, val) end def mus_b2(gen) mus_ycoeff(gen, 2) end def set_mus_b2(gen, val) set_mus_ycoeff(gen, 2, val) end class Mus # clm_gen.call(a1, a2) requires 2 arguments but clm_gen.run([a1, [a2]]) # 0, 1 or 2. # # clm_gen.run([arg1, [arg2]]) def run(arg1 = 0.0, arg2 = 0.0) mus_run(self, arg1, arg2) end def apply(*rest) mus_apply(self, *rest) end alias mus_inspect inspect def inspect "#<" + mus_describe(self) + ">" end def close mus_close(self) end # gen.xcoeff = 0, 0.4 # set_mus_xcoeff(gen, index, val) def xcoeff=(args) set_mus_xcoeff(self, *args.flatten[0, 2]) end # gen.ycoeff = 0, 0.4 # set_mus_ycoeff(gen, index, val) def ycoeff=(args) set_mus_ycoeff(self, *args.flatten[0, 2]) end def a0 mus_xcoeff(self, 0) end def a0=(val) set_mus_xcoeff(self, 0, val) end def a1 mus_xcoeff(self, 1) end def a1=(val) set_mus_xcoeff(self, 1, val) end def a2 mus_xcoeff(self, 2) end def a2=(val) set_mus_xcoeff(self, 2, val) end def b1 mus_ycoeff(self, 1) end def b1=(val) set_mus_ycoeff(self, 1, val) end def b2 mus_ycoeff(self, 2) end def b2=(val) set_mus_ycoeff(self, 2, val) end end # base class for generators written in Ruby class Musgen def initialize @frequency = $clm_default_frequency @phase = 0.0 @scaler = 1.0 @length = 0 @data = nil @increment = 0 @interp_type = -1 @file_name = "" end attr_accessor :frequency attr_accessor :phase attr_accessor :scaler attr_accessor :increment attr_reader :length attr_reader :data attr_reader :interp_type attr_reader :file_name def inspect format("%s.new()", self.class) end def to_s format("#<%s>", self.class) end def run(val1 = 0.0, val2 = 0.0) self.run_func(val1, val2) end alias call run def apply(*rest) self.run_func(*rest) end def eql?(other) self == other end def reset @frequency = $clm_default_frequency @phase = 0.0 @scaler = 1.0 @increment = 0 self end end class Numeric def positive? self > 0 end def negative? self < 0 end # According to Ruby's ChangeLog-2.0.0: # Wed Nov 21 21:53:29 2012 Tadayoshi Funaba # * complex.c (nucomp_to_c): added. def to_c Complex(self) end unless defined? 1.to_c end class Integer def even? self.modulo(2) == 0 end unless defined? 1.even? def odd? self.modulo(2) != 0 end unless defined? 1.odd? def prime? (self == 2) or (self.odd? and 3.step(sqrt(self), 2) do |i| return false if self.modulo(i) == 0 end) end end class Float # step accepts floats as arguments (implemented in newer versions) def step(upto, step) counter = self while counter < upto yield(counter) counter += step end counter end unless 1.1.respond_to?(:step) end class Range def step(n = 1, &body) self.to_a.step(n, &body) end unless defined? Range.new(0, 1).step end def as_one_edit_rb(*origin, &body) # ruby compatibility: # ruby pre 1.9: lambda do end.arity != lambda do | | end.arity # ruby 1.9: they are even (0) as_one_edit(lambda do | | body.call end, origin.empty? ? "" : format(*origin)) end def map_channel_rb(beg = 0, dur = false, snd = false, chn = false, edpos = false, edname = false, &func) map_channel(func, beg, dur, snd, chn, edpos, edname) end add_help(:map_chan_rb, "map_chan(func, start=0, end=false, edname=false, \ snd=false, chn=false, edpos=false) \ Applies FUNC to samples in the specified channel. \ It is the old (\"irregular\") version of map_channel.") def map_chan_rb(beg = 0, dur = false, ednam = false, snd = false, chn = false, edpos = false, &func) map_chan(func, beg, dur, ednam, snd, chn, edpos) end class Proc include Info alias run call add_help(:to_method, "Proc#to_method(name, klass=Object) \ Converts a Proc to a Method 'name' in the given class, default Object. \ NAME can be a string or a symbol. m = lambda do |*args| p args end m.to_method(:func) func(1, 2, 3) ==> [1, 2, 3] lambda do |x| p x end.to_method(:foo); foo(\"text1\") ==> \"text1\" lambda do |x| p x end.to_method(\"bar\"); bar(\"text2\") ==> \"text2\"") def to_method(name, klass = Object) name = case name when String name.intern when Symbol name end body = self klass.class_eval do define_method(name, body) end end # Important: # The following works only with newer ruby versions (I assume >= # 1.8.x). Proc#inspect must return # to # locate the source file of the procedure, not only #! # Functions to_str and to_body try to search the procedure source # code in a file determined by to_s. It is only a simple scanner # which doesn't look for the whole Ruby syntax. ;-) # # It doesn't work if no source file exists, i.e, if the code is # eval'ed by the Snd listener (or in Emacs). You must load the file # instead. # # with_sound(:notehook, # lambda do |name| snd_print(name) if name =~ /viol/ end) do # fm_violin(0, 1, 440, 0.3) # end # # $clm_notehook = lambda do |name| clm_print(name) if name =~ /viol/ end # # with_sound do # fm_violin(0, 1, 440, 0.3) # end # # with_sound(:save_body, true) do # ... # end # returns something like 'lambda do ... end' def to_str if body = self.source return body end file, line = self.to_s.sub(/>/, "").split(/@/).last.split(/:/) if file[0] == ?( and file[-1] == ?) if $VERBOSE warning("%s#%s: no file found for procedure %p", self.class, get_func_name, self) end body = "" elsif (not File.exist?(file)) if $VERBOSE warning("%s#%s: \ Sorry, you need a higher ruby version to use Proc#to_str. It works only with newer ruby versions (I assume >= 1.8.x). Proc#inspect must return # not only %p!", self.class, get_func_name, self) end body = "" else lineno = line.to_i body = "" blck = i = 0 first_line = true File.foreach(file) do |ln| i += 1 next if i < lineno body << ln if first_line if (ln.scan(/\s*do\b|\{/).length - ln.scan(/\s*end\b|\}/).length).zero? and (ln.scan(/\(/).length - ln.scan(/\)/).length).zero? break else first_line = false blck = 1 next end end next if /\s*\S+\s*(if|unless|while|until)+/ =~ ln break if (blck += Snd_eval.count_level(ln)).zero? break if blck.negative? end end unless self.source then self.source = body end body end # returns the inner body without 'lambda do end' def to_body if (body = self.to_str).null? "" elsif body.split(/\n/).length == 1 body.chomp.sub(/^(?:\s*\w+(?:\(.*\))??\s*(?:do\s+|\{\s*))(.*)\s*(?:end|\})$/, '\1').strip else body.split(/\n/)[1..-2].join("\n") end end # property set in g_edit_list_to_function (snd-edits.c) def source property(self.object_id, :proc_source) end def source=(val) set_property(self.object_id, :proc_source, val) end end def make_proc2method(name, prc) prc.to_method(name) end # produces two new functions: NAME and SET_NAME # val = 10 # make_proc_with_setter(:foo, lambda { puts val }, lambda { |a| val = a }) # foo ==> 10 # set_foo(12) # foo ==> 12 def make_proc_with_setter(name, getter, setter) make_proc2method(name, getter) make_proc2method(format("set_%s", name).intern, setter) end # prc = make_proc_with_source(%(lambda do |a, b, c| puts a, b, c end)) # prc.call(1, 2, 3) # prc.source ==> "lambda do |a, b, c| puts a, b, c end" # # With the second argument BIND one can use local variables known in # the current (or other) environment in the proc body: # # os = make_oscil(:frequency, 330) # prc = make_proc_with_source(%(lambda do | | # 10.times do |i| p os.run end # end), binding) # puts prc.source ==> lambda do | | 10.times do |i| p os.run end end # prc.call ==> ..., 0.748837699712728 # puts # prc.call ==> ..., 0.97679449812022 def make_proc_with_source(string, bind = binding) if proc?(prc = (res = Snd.catch(:all) do eval(string, bind) end).first) prc.source = string prc else Snd.raise(:runtime_error, res, prc, string) end end make_proc_with_setter(:proc_source, lambda do |prc| prc.source end, lambda do |prc, val| prc.source = val end) # Multi-line input to the Snd listener and Emacs/inf-snd.el. # A simple parser collects multi-line input, e.g. # # with_sound do # fm_violin(0.0, 0.1, 330, 0.1) # fm_violin(0.1, 0.1, 660, 0.1) # end # # and evals it. # # ~/.snd # set_listener_prompt("snd> ") # optional # start_listener_eval # installs read-hook for snd-listener input # start_emacs_eval # installs emacs-eval-hook make_hook("$emacs_eval_hook", 1, "\ emacs_eval_hook(line): \ called each time inf-snd.el sends a line to the Snd process. \ The hook functions may do their best to deal with multi-line input; \ they can collect multi-line input and eval it by itself. \ One example is install_eval_hooks(file, retval, input, hook, &reset_cursor) \ in clm.rb.") # inf-snd.el calls this function each time a line was sent to the # emacs buffer. def run_emacs_eval_hook(line) if $emacs_eval_hook.empty? # without emacs-eval-hook only single line eval file = "(emacs-eval-hook)" set_snd_input(:emacs) begin Snd.display(eval(line, TOPLEVEL_BINDING, file, 1).inspect) rescue Interrupt, ScriptError, NameError, StandardError Snd.display(verbose_message_string(true, "# ", file)) end set_snd_input(:snd) nil else $emacs_eval_hook.call(line) end end class Snd_eval class << Snd_eval Open_token = %w(class module def do { while until if unless case begin for) Close_token = %w(end }) def count_level(line) eval_level = 0 # skip strings and symbols which may contain reserved words line.gsub(/(:\w+|".+")/, "").split(/\b/).each do |s| case s when *Open_token eval_level += 1 when *Close_token eval_level -= 1 end end eval_level end end end class Snd_prompt # level number inserted into original prompt # ">" ==> "(0)>" # "snd> " ==> "snd(0)> " def initialize(level) @listener_prompt = listener_prompt @base_prompt = listener_prompt.split(/(\(\d+\))?(>)?\s*$/).car.to_s @rest_prompt = listener_prompt.scan(/>\s*$/).car.to_s update(level) end def inspect format("#<%s %s(0)%s>", self.class, @base_prompt, @rest_prompt) end def update(level) set_listener_prompt(format("%s(%d)%s", @base_prompt, level, @rest_prompt)) end def reset set_listener_prompt(@listener_prompt) end end def install_eval_hooks(file, retval, input, hook, &reset_cursor) eval_level = 0 eval_line = "" prompt = Snd_prompt.new(eval_level) reset_cursor.nil? or reset_cursor.call $exit_hook.add_hook!(file) do | | prompt.reset end hook.add_hook!(file) do |line| eval_line = eval_line + line + "\n" eval_level += Snd_eval.count_level(line) if eval_level.negative? eval_level = 0 eval_line = "" end if eval_level.zero? set_snd_input(input) begin Snd.display(eval(eval_line, TOPLEVEL_BINDING, file, 1).inspect) rescue Interrupt, ScriptError, NameError, StandardError Snd.display(verbose_message_string(true, "# ", file)) ensure eval_line = "" end end prompt.update(eval_level) reset_cursor.nil? or reset_cursor.call retval end end # installs the emacs-eval-hook def start_emacs_eval(name = "(emacs)") install_eval_hooks(name, nil, :emacs, $emacs_eval_hook) do $stdout.print(listener_prompt) $stdout.flush end end # installs the read-hook def start_listener_eval(name = "(snd)") set_show_listener(true) install_eval_hooks(name, true, :snd, $read_hook) end def stop_emacs_eval(name = "(emacs)") $emacs_eval_hook.remove_hook!(name) $exit_hook.run_hook_by_name(name) $exit_hook.remove_hook!(name) end def stop_listener_eval(name = "(snd)") $read_hook.remove_hook!(name) $exit_hook.run_hook_by_name(name) $exit_hook.remove_hook!(name) reset_listener_cursor clm_print("\n%s", listener_prompt) end # Debugging resp. inspecting local variables make_proc_with_setter(:debug_properties, lambda do |name| property(name, :debug_property) end, lambda do |name, val| set_property(name, :debug_property, val) end) make_proc_with_setter(:debug_property, lambda do |key, name| hash?(h = debug_properties(name)) and h[key] end, lambda do |key, val, name| h = debug_properties(name) unless hash?(h) and h.store(key, [val] + h[key]) a = property(:debug, :names) unless array?(a) and a.push(name) set_property(:debug, :names, [name]) end set_debug_properties(name, {key => [val]}) end end) make_proc_with_setter(:debug_binding, lambda do |name| debug_property(:binding, name) end, lambda do |bind, *name| set_debug_property(:binding, bind, (name[0] or get_func_name(3))) end) # Shows all local variables of last call of functions prepared with # set_debug_binding(binding) # # def function1 # [...] # set_debug_binding(binding) # end # def function2 # [...] # set_debug_binding(binding) # end # [...] # function1 # function2 # [...] # # display_all_variables def display_all_variables(name = nil) if name [name] else (property(:debug, :names) or []) end.each do |nm| debug_binding(nm).each do |bind| Snd.message("=== %s ===", nm) Snd.message() each_variables(bind) do |var, val| Snd.message("%s = %s", var, val.inspect) end Snd.message() end end end # each_variables provides all local variable names and their values in # the given proc context # # def function # [...] # each_variables do |k, v| # Snd.display("%s = %s", k, v) # end # end def each_variables(bind = binding, &prc) eval("local_variables", bind).each do |name| name = name.to_s prc.call(name, eval(name, bind)) end end # let(8, :foo, "bar") do |a, b, c| # printf("a: %d, b: %s, c: %s\n", a, b, c) # end # # Simulates a save local variable environment and restores old # variables to their original values. def let(*args, &prc) locals = Hash.new bind = prc.binding each_variables(bind) do |var, val| locals[var] = val end prc.call(*args) rescue Interrupt, ScriptError, NameError, StandardError Kernel.raise ensure @locals = locals locals.each_key do |name| eval("#{name} = @locals[#{name.inspect}]", bind) end remove_instance_variable("@locals") end # for irb (rgb.rb) def make_color(r, g, b) [:Pixel, 0] end unless defined? make_color def doc(*rest) # dummy for old Kernel.doc end ## ## Utilities ## if provided? :snd_nogui alias close_sound_extend close_sound else def close_sound_extend(snd) # 5 == Notebook if main_widgets[5] idx = Snd.sounds.index(snd) if idx.nil? then idx = 0 end close_sound(snd) snds = sounds() and set_selected_sound(snds[idx < snds.length ? idx : -1]) else close_sound(snd) end end end add_help(:times2samples, "times2samples(start, dur) \ START and DUR are in seconds; returns array [beg, end] in samples.") def times2samples(start, dur) beg = seconds2samples(start) [beg, beg + seconds2samples(dur)] end def random(val) if val.zero? val else case val when Fixnum kernel_rand(val) when Float val.negative? ? -mus_random(val).abs : mus_random(val).abs end end end def logn(r, b = 10) if r <= 0 Snd.raise(:ruby_error, r, "r must be > 0") end if b <= 0 or b == 1 Snd.raise(:ruby_error, b, "b must be > 0 and != 1") end log(r) / log(b) end def car(v) v[0] end def cadr(v) v[1] end def caddr(v) v[2] end def cdr(v) v[1..-1] end def verbose_message_string(stack_p, remark, *args) fmt_remark = format("\n%s", remark) str = if args.null? "" elsif args.length == 1 String(args.car) else format(*args) end str = if str.split(/\n/).length > 1 str.split(/\n/).join(fmt_remark) else format("%s%s", remark, str) end if $! str += format("[%p] %s (%s)", rb_error_to_mus_tag, snd_error_to_message, $!.class) if stack_p str += format("\n%s%s", remark, $!.backtrace.join(fmt_remark)) end else if stack_p and caller(2) str += format("\n%s%s", remark, caller(2).join(fmt_remark)) end end str end def warning(*args) str = "Warning: " << verbose_message_string($VERBOSE, nil, *args) if provided? :snd snd_warning(str) else clm_message(str) end nil end def die(*args) message(verbose_message_string(true, nil, *args)) exit(1) unless provided? :snd end def error(*args) Snd.raise(:runtime_error, verbose_message_string(true, nil, *args)) end make_proc_with_setter(:snd_input, lambda do property(:snd_input, :snd_listener) end, lambda do |val| set_property(:snd_input, :snd_listener, val) end) # like clm_print(fmt, *args) def clm_message(*args) msg = if args.null? "" elsif args.length == 1 String(args.car) else format(*args) end if provided? :snd if provided? :snd_nogui clm_print("%s\n", msg) else clm_print("\n%s", msg) end nil else $stdout.print(msg, "\n") end nil end # like clm_print(*args), in emacs it prepends msg with a comment sign def message(*args) clm_message(verbose_message_string(false, "# ", *args)) end # debug(var1, var2) ==> # def debug(*args) fmt = "" args.each do |arg| fmt += format("%s: %p", arg.class, arg) fmt += ", " end message("#", fmt.chomp(", ")) end def debug_trace(*args) debug(*args) clm_message(verbose_message_string(true, "# ")) end if provided?(:snd) then set_snd_input(:snd) end class Snd class << Snd Snd_path = Array.new if provided? :snd_motif def add_sound_path(path) Snd_path.push(path) add_directory_to_view_files_list(path) end else def add_sound_path(path) Snd_path.push(path) end end def fullname(fname) if File.exist?(fname) fname else f = File.basename(fname) Snd_path.each do |path| if File.exist?(path + "/" + f) return path + "/" + f end end Snd.raise(:no_such_file, fname) end end def open_from_path(fname) snd_file = Snd.fullname(fname) find_sound(snd_file) or open_sound(snd_file) end def find_from_path(fname) find_sound(Snd.fullname(fname)) end def load_path Snd_path end def message(*args) clm_message(verbose_message_string(false, "# ", *args)) end def display(*args) msg = if args.null? "" elsif args.length == 1 String(args.car) else format(*args) end if snd_input == :snd if provided? :snd_nogui clm_print("%s\n", msg) else clm_print("\n%s", msg) end else $stdout.print(msg, "\n") end nil end def warning(*args) if provided? :snd snd_warning(verbose_message_string($VERBOSE, nil, *args)) else args[0] = "Warning: " + String(args[0]) Snd.display(verbose_message_string($VERBOSE, "# ", *args)) end nil end def die(*args) Snd.display(verbose_message_string(true, nil, *args)) exit(1) unless provided? :snd end def error(*args) Snd.raise(:runtime_error, verbose_message_string(true, nil, *args)) end def debug(*args) if args.null? Snd.message("#") elsif args.length == 1 Snd.message("#", String(args.car)) else Snd.message("#", format(*args)) end end def debug_trace(*args) Snd.debug(*args) Snd.display(verbose_message_string(true, "# ")) end def sounds (Kernel.sounds or []).reverse end def regions (Kernel.regions or []).reverse end def marks(snd = false, chn = false) (Kernel.marks(snd, chn) or []) end def snd(sn = false) sn or selected_sound or Snd.sounds.car end def chn(ch = false) ch or selected_channel or 0 end def catch(tag = :all, retval = :undefined) old_debug = $DEBUG $DEBUG = false val = Kernel.catch(tag) do yield end # catch/throw part # [:snd_throw, tag, get_func_name(2), *rest] if array?(val) and val.car == :snd_throw if retval != :undefined if proc?(retval) retval.call(val.cdr) else [retval] end else val.cdr end else [val] end # ruby1.9/ChangeLog # Thu Feb 2 16:01:24 2006 Yukihiro Matsumoto # * error.c (Init_Exception): change NameError to direct subclass of # Exception so that default rescue do not handle it silently. rescue Interrupt, ScriptError, NameError, StandardError mus_tag = rb_error_to_mus_tag # raise part if (tag == mus_tag) or (tag == :all) if retval != :undefined if proc?(retval) retval.call(mus_tag, snd_error_to_message) else [retval] end else [mus_tag, snd_error_to_message] end else Kernel.raise end ensure $DEBUG = old_debug end def throw(tag, *rest) Kernel.throw(tag, [:snd_throw, tag, get_func_name(2), *rest]) end def raise(tag, *rest) msg = format("%s in %s:", tag, get_func_name(2)) rest.each do |s| msg += format(" %s,", s) end msg.chomp!(",") exception = case tag when :out_of_range RangeError when :wrong_type_arg TypeError when *Snd_error_tags StandardError else Ruby_exceptions[tag] or RuntimeError end Kernel.raise(exception, msg, caller(1)) end end end # almost all StandardError Snd_error_tags = [# clm2xen.c :mus_error, :no_such_method, :wrong_type_arg, # TypeError # snd-0.h :no_such_envelope, :no_such_sample, :no_such_edit, :cannot_save, :cant_update_file, # snd-chn.c :cant_open_file, # snd-dac.c :bad_format, :no_such_player, :arg_error, # snd-draw.c :no_such_widget, :no_such_graphics_context, :no_such_axis, :bad_length, # snd-edits.c :no_such_direction, :no_such_region, :no_such_auto_delete_choice, # snd-env.c :env_error, # snd-error.c :snd_error, # snd-gxcolormaps.c :no_such_colormap, :colormap_error, # snd-key.c :no_such_key, # snd-ladspa.c :no_such_plugin, :plugin_error, # snd-marks.c :no_such_mark, # snd-menu.c :no_such_menu, # snd-mix.c :no_such_mix, # snd-print.c :cannot_print, # snd-region.c :io_error, # run.c :wrong_number_of_args, :cannot_parse, # snd-snd.c :no_such_sound, :not_a_sound_file, :cannot_apply_controls, :bad_size, :snd_internal_error, # snd-xen.c :no_active_selection, :bad_arity, # snd-xmain.c :xt_error, # snd-xchn.c :no_such_color, # snd.c :snd_top_level, :gsl_error, # sndlib2xen.h :out_of_range, :no_such_channel, :no_such_file, :bad_type, :no_data, :bad_header, # xm.c :no_such_resource] def rb_error_to_mus_tag # to_s and string error-names intentional here # otherwise e.g. NameError goes to case StandardError! case $!.class.to_s when "StandardError" $!.message.split(/[: ]/).first.downcase.intern when "RangeError" :out_of_range when "TypeError" :wrong_type_arg when "ArgumentError" :wrong_number_of_args else # converts ruby exceptions to symbols: NoMethodError ==> :no_method_error $!.class.to_s.gsub(/([A-Z])/) do |c| "_" + c.tr("A-Z", "a-z") end[1..-1].intern end end def snd_error_to_message $!.message.split(/\n/).first.sub(/^.*: /, "") end add_help(:snd_catch, "snd_catch(tag=:all, retval=:undefined]) \ Catchs snd_throw and exceptions and \ returns body's last value wrapped in an array if all goes well. \ If a snd_throw tag meets snd_catch's, returns an array with the tag name, \ the function name from where was thrown \ and optional arguments given to snd_throw. \ If an exception was risen and the exception name meets tag name, \ returns an array with tag name and the exception message, \ otherwise reraises exception. \ If retval is given and tag matches exception or snd_throw tag, \ returns retval. \ If retval is a procedure, calls retval with tag name and message. res = snd_catch do 10 + 2 end puts res ==> [12] res = Snd.catch(:no_such_file) do open_sound(\"unknown-file.snd\") end puts res ==> [:no_such_file, \ \"open_sound: no_such_file: Unknown_file.snd No such file or directory\"] res = Snd.catch(:finish) do 10.times do |i| if i == 8 then snd_throw(:finish, i) end end end puts res ==> [:finish, \"top_level\", 8] res = Snd.catch(:all, lambda do |tag, msg| Snd.display([tag, msg]) end) do set_listener_prompt(17) end ==> [:wrong_type_arg, \ \"set_listener-prompt: wrong type arg 0, 17, wanted a string\"] puts res ==> nil The lambda function handles the error in the last case.") def snd_catch(tag = :all, retval = :undefined, &body) Snd.catch(tag, retval, &body) end add_help(:snd_throw, "snd_throw(tag, *rest) \ Jumps to the corresponding snd_catch(TAG) and returns an array \ with TAG, function name and possible *REST strings or values.") def snd_throw(tag, *rest) Snd.throw(tag, *rest) end class Break < StandardError end Ruby_exceptions = { :script_error => ScriptError, :load_error => LoadError, :name_error => NameError, :not_implemented_error => NotImplementedError, :syntax_error => SyntaxError, :interrupt => Interrupt, :system_exit => SystemExit, :standard_error => StandardError, :arg_error => ArgumentError, :float_domain_error => FloatDomainError, :index_error => IndexError, :io_error => IOError, :eof_error => EOFError, :local_jump_error => LocalJumpError, :no_memory_error => NoMemoryError, :range_error => RangeError, :regexp_error => RegexpError, :runtime_error => RuntimeError, :security_error => SecurityError, :system_call_error => SystemCallError, :system_stack_error => SystemStackError, :thread_error => ThreadError, :type_error => TypeError, :zero_division_error => ZeroDivisionError, :break => Break} add_help(:snd_raise, "snd_raise(tag, *rest) \ Raises an exception TAG with an error message \ containing function name, TAG and possible *REST strings or values. \ TAG is a symbol, \ a Ruby exception looks like :local_jump_error instead of LocalJumpError, \ a Snd error tag looks like :no_such_sound.") def snd_raise(tag, *rest) Snd.raise(tag, *rest) end def srate mus_srate end unless defined? srate # general purpose loop add_help(:gloop, "gloop(*args) { |args| ... } :step = 1 :before = nil (thunk) :after = nil (thunk) args[0]: Range (each) Hash(s) (each) Array(s) (each_with_index) [args.last == Fixnum ==> step] Fixnum (times) Fixnum [args[1] == :step ==> step] A general purpose loop, handling Range, Hash, Array, Vec, Vct, Fixnum, with optional step. Returns the result of body as array like map. Examples: Range gloop(0..3) do |i| puts i end Hash (loops over all Hashs consecutively) gloop({1 => :a, 2 => :b}, {11 => :aa => 22 => :bb}) do |k, v| print('key: ', k, ' value: ', v) puts end Array, Vec, Vct gloop([0, 1]) do |x, i| print(i, ': ', x) puts end Arrays with step (mixes all Arrays) gloop([0, 1, 2, 3], [:a, :b, :c, :d], [55, 66, 77, 88, 99], 2) do |x, i| print(i, ': ', x.inspect) puts end Numeric (like Integer#times) gloop(3) do |i| puts i end Numeric with step (like Integer#step) gloop(6, 2) do |i| puts i end a simple body call gloop do puts 'empty' end") def gloop(*args, &body) step = get_shift_args(args, :step, 1) before = get_shift_args(args, :before) after = get_shift_args(args, :after) do_extra = lambda do |thunk| thunk?(thunk) ? thunk.call : snd_func(thunk) end result = [] case args[0] when Range args[0].step(step) do |i| do_extra.call(before) if before result << body.call(i) do_extra.call(after) if after end when Array, Vec, Vct lmax = args.map do |x| x.length end.max 0.step(lmax - 1, step.round) do |i| do_extra.call(before) if before result << body.call(*args.map do |x| x[i] end << i) do_extra.call(after) if after end when Hash args.each do |x| x.each do |k, v| do_extra.call(before) if before result << body.call(k, v) do_extra.call(after) if after end end when Numeric 0.step(args[0], number?(args[1]) ? args[1] : step) do |i| do_extra.call(before) if before result << body.call(i) do_extra.call(after) if after end else do_extra.call(before) if before result << body.call do_extra.call(after) if after end result end # get_args(args, key, default = nil) # # returns value, whether DEFAULT or value of KEY found in ARGS def get_args(args, key, default = nil) if args.member?(key) arg = args[args.index(key) + 1] default = arg.nil? ? default : arg end default end def get_shift_args(args, key, default = nil) default = get_args(args, key, default) if args.member?(key) i = args.index(key) 2.times do args.delete_at(i) end end default end # var = get_class_or_key(args, Klass, :key, default = nil) def get_class_or_key(args, klass, key, default = nil) if (not symbol?(args.first)) and args.first.kind_of?(klass) args.shift else get_shift_args(args, key, default) end end # var1, var2, var3, var4 = optkey(args, [:key, default], # [:number, 1], # [Array, :list, [0, 1, 2, 3]], # :var_w/o_default_value) # # Key-default pairs must be included in brackets while keys alone can # be included in brackets or not, see last key # ":var_w/o_default_value" above. If no default value is specified, # nil is used. def optkey(args, *rest) args_1 = args.dup bind = binding?(rest.car) ? rest.shift : nil @locals = nil vals = rest.map do |keys| val = if array?(keys) case keys.length when 1 name = keys.car.to_s get_class_or_key(args_1, Object, keys.car, nil) when 2 name = keys.car.to_s get_class_or_key(args_1, keys.cadr.class, *keys) when 3 name = keys.cadr.to_s get_class_or_key(args_1, *keys) else assert_type(keys.length.between?(1, 3), keys, 1, "an array of one to three \ elements [class, :key, default]") end else name = keys.to_s get_class_or_key(args_1, Object, keys, nil) end @locals = val eval("#{name} = @locals", bind) val end remove_instance_variable("@locals") if vals.length == 1 vals.first else vals end end add_help(:load_init_file, "load_init_file(file) \ Returns false if FILE doesn't exist, otherwise loads it. \ FILE may reside in current working dir or in $HOME dir.") def load_init_file(file) if File.exist?(file) Snd.catch do load(file) end elsif File.exist?(f = ENV["HOME"] + "/" + file) Snd.catch do load(f) end else false end end let(-1) do |count| # see rotate_phase(func, snd, chn) in dsp.rb # it's necessary to produce a uniq method name make_proc_with_setter(:edit_list_proc_counter, lambda do count end, lambda do count += 1 end) end # clm.rb ends here snd-16.1/snd-snd.c0000644000076400007640000063410712603035272012060 0ustar bilbil#include "snd.h" #include "sndlib-strings.h" #include "clm2xen.h" static snd_info *get_sp_1(int index) { if ((index >= 0) && (index < ss->max_sounds) && (snd_ok(ss->sounds[index]))) return(ss->sounds[index]); return(NULL); } snd_info *get_sp(Xen snd) { if (xen_is_sound(snd)) return(get_sp_1(xen_sound_to_int(snd))); #if (!HAVE_SCHEME) if (Xen_is_integer(snd)) return(get_sp_1(Xen_integer_to_C_int(snd))); #else if (Xen_is_integer(snd)) { s7_int p; p = s7_integer(snd); if ((p < 0) || (p > ss->max_sounds)) return(NULL); return(get_sp_1((int)p)); } #endif if ((Xen_is_boolean(snd)) || (!Xen_is_bound(snd))) /* use default sound, if any */ return(any_selected_sound()); return(NULL); } snd_info *snd_new_file(const char *newname, int chans, int srate, mus_sample_t sample_type, mus_header_t header_type, const char *new_comment, mus_long_t samples) { /* caller checks newname != null, and runs overwrite hook */ if (mus_header_writable(header_type, sample_type)) { io_error_t err; err = snd_write_header(newname, header_type, srate, chans, samples * chans, sample_type, new_comment, NULL); if (err != IO_NO_ERROR) snd_error("%s %s: %s", io_error_name(err), newname, snd_io_strerror()); else { int chan; mus_long_t size; /* send out the initial samples */ chan = snd_reopen_write(newname); lseek(chan, mus_header_data_location(), SEEK_SET); size = chans * mus_samples_to_bytes(sample_type, samples); if (size > 0) { ssize_t bytes; unsigned char *buf = NULL; buf = (unsigned char *)calloc(size, sizeof(unsigned char)); bytes = write(chan, buf, size); if (bytes == 0) fprintf(stderr, "%s: write error", newname); free(buf); } snd_close(chan, newname); ss->open_requestor = FROM_NEW_FILE_DIALOG; return(sound_is_silence(snd_open_file(newname, FILE_READ_WRITE))); } } else snd_error("%s: can't write %s header with %s sample type", newname, mus_header_type_name(header_type), mus_sample_type_name(sample_type)); return(NULL); } /* ---------------- peak amp envs ---------------- */ typedef struct env_state { int slice, edpos; mus_long_t samples, m; peak_env_info *ep; snd_fd *sf; unsigned char *direct_data; mus_sample_t format; int chans, bytes, fd; bool file_open; } env_state; static env_state *free_env_state(env_state *es) { if (es) { if (es->sf) es->sf = free_snd_fd(es->sf); if (es->file_open) { close(es->fd); es->file_open = false; } if (es->direct_data) { free(es->direct_data); es->direct_data = NULL; } free(es); } return(NULL); } peak_env_info *free_peak_env_info(peak_env_info *ep) { if (ep) { if (ep->data_max) {free(ep->data_max); ep->data_max = NULL;} if (ep->data_min) {free(ep->data_min); ep->data_min = NULL;} free(ep); } return(NULL); } peak_env_info *free_peak_env(chan_info *cp, int pos) { /* can be either during channel close, or premature work proc removal */ if ((cp) && (cp->edits) && (pos < cp->edit_size) && (cp->edits[pos]->peak_env)) { free_peak_env_info(cp->edits[pos]->peak_env); cp->edits[pos]->peak_env = NULL; } return(NULL); } /* during processing, cp->peak_env_state -> env_state for that channel * cp->peak_env_in_progress is the associated X work proc */ void free_peak_env_state(chan_info *cp) { /* env info is tied into cp edit list peak envs immediately upon env start, released via normal cp cleanups */ /* this function just cleans up the current work proc stuff (amp_env in this case can be incomplete) */ if (cp) { cp->peak_env_state = free_env_state(cp->peak_env_state); cp->peak_env_in_progress = 0; } } #define MIN_INIT 1000000.0 #define MAX_INIT -1000000.0 #define MAX_ENV_SIZE (1 << 30) static env_state *make_env_state(chan_info *cp, mus_long_t samples) { int pos, orig_pos; peak_env_info *ep; env_state *es; if (samples <= 0) return(NULL); if (samples > MAX_ENV_SIZE) return(NULL); stop_peak_env(cp); pos = cp->edit_ctr; orig_pos = cp->edits[pos]->edpos; /* don't assume we're editing the preceding state! */ es = (env_state *)calloc(1, sizeof(env_state)); /* only creation point */ es->file_open = false; es->samples = samples; es->slice = 0; es->edpos = pos; es->m = 0; es->direct_data = NULL; if (cp->edits[pos]->peak_env) { es->ep = cp->edits[pos]->peak_env; ep = es->ep; } else { bool happy = false; es->ep = (peak_env_info *)calloc(1, sizeof(peak_env_info)); ep = es->ep; if (pos > 0) { peak_env_info *old_ep; old_ep = cp->edits[orig_pos]->peak_env; if ((old_ep) && (old_ep->completed)) { mus_long_t old_samples; /* here in many cases, the underlying edit's amp env has most of the data we need. * cp->edits[cp->edit_ctr] describes the current edit, with beg and end, so in the * simplest case, we can just copy to the bin representing beg, and from the bin * representing end (setting ep->top_bin and ep->bin); if the file's length has * changed dramatically, we need to do it all. fmin/fmax need to be set as we copy. * as-one-edit can mess this up... */ old_samples = cp->edits[orig_pos]->samples; if (snd_abs_mus_long_t(samples - old_samples) < (samples / 2)) { mus_long_t start, end; start = edit_changes_begin_at(cp, cp->edit_ctr); end = edit_changes_end_at(cp, cp->edit_ctr); if (snd_abs_mus_long_t(end - start) < (samples / 2)) { int i, start_bin; /* here we'll try to take advantage of an existing envelope */ old_ep = cp->edits[orig_pos]->peak_env; ep->samps_per_bin = old_ep->samps_per_bin; ep->peak_env_size = (int)(ceil((double)(es->samples) / (double)(ep->samps_per_bin))); ep->data_max = (mus_float_t *)calloc(ep->peak_env_size, sizeof(mus_float_t)); ep->data_min = (mus_float_t *)calloc(ep->peak_env_size, sizeof(mus_float_t)); start_bin = (int)(start / ep->samps_per_bin); ep->fmin = old_ep->data_min[0]; ep->fmax = old_ep->data_max[0]; for (i = 0; i < start_bin; i++) { ep->data_min[i] = old_ep->data_min[i]; ep->data_max[i] = old_ep->data_max[i]; if (ep->data_min[i] < ep->fmin) ep->fmin = ep->data_min[i]; if (ep->data_max[i] > ep->fmax) ep->fmax = ep->data_max[i]; } ep->bin = start_bin; if (end != 0) { int j, end_bin, old_end_bin; old_end_bin = (int)(end / old_ep->samps_per_bin); end += (samples - old_samples); end_bin = (int)(end / ep->samps_per_bin); if (end_bin <= 0) { old_end_bin += (1 - end_bin); end_bin = 1; } for (i = end_bin, j = old_end_bin; (i < ep->peak_env_size) && (j < old_ep->peak_env_size); i++, j++) { ep->data_min[i] = old_ep->data_min[j]; ep->data_max[i] = old_ep->data_max[j]; if (ep->data_min[i] < ep->fmin) ep->fmin = ep->data_min[i]; if (ep->data_max[i] > ep->fmax) ep->fmax = ep->data_max[i]; } ep->top_bin = end_bin; } else ep->top_bin = 0; happy = true; } } } } if (!happy) { int val; /* we want samps_per_bin to be useful over a wide range of file sizes */ /* 160e6 = about a hour at 44KHz */ val = (int)(log((double)(es->samples))); if (val > 20) val = 20; ep->peak_env_size = snd_int_pow2(val); ep->samps_per_bin = (int)(ceil((double)(es->samples) / (double)(ep->peak_env_size))); ep->data_max = (mus_float_t *)calloc(ep->peak_env_size, sizeof(mus_float_t)); ep->data_min = (mus_float_t *)calloc(ep->peak_env_size, sizeof(mus_float_t)); ep->bin = 0; ep->top_bin = 0; ep->fmin = 10000000.0; ep->fmax = -10000000.0; /* preset as much as possible of the envelope */ } cp->edits[pos]->peak_env = ep; ep->completed = false; } es->sf = NULL; return(es); } void start_peak_env_state(chan_info *cp) { cp->peak_env_state = make_env_state(cp, current_samples(cp)); } static bool tick_peak_env(chan_info *cp, env_state *es) { peak_env_info *ep; ep = es->ep; if (es->slice == 0) { int n, sb, lm; mus_long_t samps_to_read; if (ep->top_bin != 0) lm = (ep->top_bin - ep->bin + 1); else lm = (ep->peak_env_size - ep->bin); if (lm <= 0) lm = 1; samps_to_read = (mus_long_t)lm * (mus_long_t)(ep->samps_per_bin); if (samps_to_read > 1000000) { lm = 1000000 / ep->samps_per_bin; samps_to_read = (mus_long_t)lm * (mus_long_t)(ep->samps_per_bin); } sb = ep->bin; if (sb >= ep->peak_env_size) { /* oops... */ es->slice++; if (es->sf) es->sf = free_snd_fd(es->sf); if (es->direct_data) { free(es->direct_data); es->direct_data = NULL; } ep->completed = true; return(true); } if ((es->sf == NULL) && (es->direct_data == NULL)) { if ((cp->edit_ctr == 0) && (cp->sound) && (cp->sound->inuse == SOUND_NORMAL) && (cp->sound->hdr) && (cp->sounds) && (cp->sounds[0] != NULL) && (cp->sounds[0]->io)) { es->fd = mus_file_open_read(cp->sound->filename); if (es->fd == -1) { snd_warning("%s no longer exists!", cp->sound->filename); return(true); } es->file_open = true; lseek(es->fd, cp->sound->hdr->data_location, SEEK_SET); es->format = cp->sound->hdr->sample_type; es->chans = cp->sound->nchans; es->bytes = ep->samps_per_bin * mus_bytes_per_sample(es->format) * es->chans; es->direct_data = (unsigned char *)malloc(es->bytes * lm); } else es->sf = init_sample_read_any(ep->bin * ep->samps_per_bin, cp, READ_FORWARD, es->edpos); } if (es->direct_data == NULL) { snd_fd *sfd; sfd = es->sf; if (sfd == NULL) return(false); for (n = 0; (n < lm) && (sb < ep->peak_env_size); n++, sb++) { mus_float_t ymin, ymax, val; int i, lim; val = read_sample(sfd); ymin = val; ymax = val; i = 1; lim = ep->samps_per_bin - 4; while (i <= lim) { val = read_sample(sfd); if (ymin > val) ymin = val; else if (ymax < val) ymax = val; val = read_sample(sfd); if (ymin > val) ymin = val; else if (ymax < val) ymax = val; val = read_sample(sfd); if (ymin > val) ymin = val; else if (ymax < val) ymax = val; val = read_sample(sfd); if (ymin > val) ymin = val; else if (ymax < val) ymax = val; i += 4; } for (; i < ep->samps_per_bin; i++) { val = read_sample(sfd); if (ymin > val) ymin = val; else if (ymax < val) ymax = val; } ep->data_max[sb] = ymax; ep->data_min[sb] = ymin; if (ymin < ep->fmin) ep->fmin = ymin; if (ymax > ep->fmax) ep->fmax = ymax; } } else { ssize_t bytes_read; bytes_read = read(es->fd, (char *)(es->direct_data), lm * es->bytes); if (bytes_read < lm * es->bytes) { int zero_byte; zero_byte = mus_sample_type_zero(es->format); if ((zero_byte == 0) || ((es->format != MUS_UBSHORT) && (es->format != MUS_ULSHORT))) memset((void *)(es->direct_data + bytes_read), zero_byte, lm * es->bytes - bytes_read); else /* MUS_UB|LSHORT 32768 or 128(as a short)=>0 */ { mus_long_t i, start, len; unsigned short *buf; /* (with-sound (:sample-type mus-ubshort) (fm-violin 0 2 440 .1)) */ buf = (unsigned short *)(es->direct_data); start = bytes_read / 2; len = lm * es->bytes / 2; for (i = start; i < len; i++) buf[i] = (unsigned short)zero_byte; } } for (n = 0; (n < lm) && (sb < ep->peak_env_size); n++, sb++) { mus_float_t cur_min = 0.0, cur_max = 0.0; mus_samples_bounds((unsigned char *)(es->direct_data + es->bytes * n), es->bytes, cp->chan, es->chans, es->format, &cur_min, &cur_max); ep->data_max[sb] = cur_max; ep->data_min[sb] = cur_min; if (cur_min < ep->fmin) ep->fmin = cur_min; if (cur_max > ep->fmax) ep->fmax = cur_max; } } es->m += samps_to_read; ep->bin += lm; if ((es->m >= es->samples) || ((ep->top_bin > 0) && (ep->bin >= ep->top_bin))) /* this applies to partial amp envs */ { es->slice++; if (es->sf) es->sf = free_snd_fd(es->sf); if (es->direct_data) { free(es->direct_data); es->direct_data = NULL; } ep->completed = true; return(true); } return(false); } else { ep->completed = true; return(true); } } void finish_peak_env(chan_info *cp) { if ((cp->peak_env_in_progress) && (cp->peak_env_state)) { while (!(tick_peak_env(cp, cp->peak_env_state))) ; /* finish peak-env scan */ enved_reflect_peak_env_completion(cp->sound); free_peak_env_state(cp); } } idle_func_t get_peak_env(any_pointer_t ptr) { /* calculate the amp env of channel */ chan_info *cp = (chan_info *)ptr; env_state *es; int pos; if (!cp) return(BACKGROUND_QUIT); pos = cp->edit_ctr; if ((pos == -1) || (cp->active < CHANNEL_HAS_EDIT_LIST)) { free_peak_env_state(cp); return(BACKGROUND_QUIT); } if (!(cp->peak_env_state)) cp->peak_env_state = make_env_state(cp, current_samples(cp)); es = cp->peak_env_state; if (es) { if (tick_peak_env(cp, es)) { free_peak_env_state(cp); enved_reflect_peak_env_completion(cp->sound); if (cp->waiting_to_make_graph) { cp->waiting_to_make_graph = false; cp->new_peaks = true; update_graph(cp); cp->new_peaks = false; } return(BACKGROUND_QUIT); } else return(BACKGROUND_CONTINUE); } return(BACKGROUND_QUIT); } bool peak_env_maxamp_ok(chan_info *cp, int edpos) { if (cp) { peak_env_info *ep; ep = cp->edits[edpos]->peak_env; return((ep) && (ep->completed)); } return(false); } mus_float_t peak_env_maxamp(chan_info *cp, int edpos) { peak_env_info *ep; mus_float_t ymax; ep = cp->edits[edpos]->peak_env; ymax = -ep->fmin; if (ymax < ep->fmax) return(ep->fmax); return(ymax); } bool peak_env_usable(chan_info *cp, mus_float_t samples_per_pixel, mus_long_t hisamp, bool start_new, int edit_pos, bool finish_env) { peak_env_info *ep; #if USE_NO_GUI return(false); #endif if (!(cp->edits)) return(false); ep = cp->edits[edit_pos]->peak_env; if (ep) { int bin; bin = (int)(hisamp / ep->samps_per_bin); if ((ep->completed) || (bin < ep->bin) || ((ep->top_bin != 0) && (bin > ep->top_bin))) return(samples_per_pixel >= (mus_float_t)(ep->samps_per_bin)); } if ((finish_env) && (cp->peak_env_in_progress) && (cp->peak_env_state)) { /* caller wants data, but a read is in progress -- finish it as quickly as possible */ finish_peak_env(cp); if (cp->waiting_to_make_graph) { cp->waiting_to_make_graph = false; update_graph(cp); } return(peak_env_usable(cp, samples_per_pixel, hisamp, start_new, edit_pos, false)); } if ((start_new) && (!(cp->peak_env_in_progress)) && (current_samples(cp) > PEAK_ENV_CUTOFF) && (cp->sound->short_filename != NULL)) /* region browser jumped in too soon during autotest */ start_peak_env(cp); return(false); } static short local_grf_y(mus_float_t val, axis_info *ap) { if (val >= ap->y1) return(ap->y_axis_y1); if (val <= ap->y0) return(ap->y_axis_y0); return((short)(ap->y_base + val * ap->y_scale)); } int peak_env_graph(chan_info *cp, mus_float_t samples_per_pixel, int srate) { mus_float_t step, x, pinc = 0.0; double xf, xk; mus_float_t ymin, ymax; int xi; int j = 0; mus_long_t i; peak_env_info *ep; axis_info *ap; ap = cp->axis; ep = cp->edits[cp->edit_ctr]->peak_env; step = samples_per_pixel / (mus_float_t)(ep->samps_per_bin); xf = (double)(ap->losamp) / (double)(ep->samps_per_bin); x = ap->x0; xi = grf_x(x, ap); i = ap->losamp; xk = (double)i; if (cp->printing) pinc = (mus_float_t)samples_per_pixel / (mus_float_t)srate; ymin = ep->fmax; ymax = ep->fmin; while (i <= ap->hisamp) { int k, kk; k = (int)xf; xf += step; kk = (int)xf; if (kk >= ep->peak_env_size) kk = ep->peak_env_size - 1; for (; k <= kk; k++) { if (ep->data_min[k] < ymin) ymin = ep->data_min[k]; if (ep->data_max[k] > ymax) ymax = ep->data_max[k]; } xk += samples_per_pixel; i = (mus_long_t)xk; set_grf_points(xi, j, local_grf_y(ymin, ap), local_grf_y(ymax, ap)); if (cp->printing) { x += pinc; ps_set_grf_points(x, j, ymin, ymax); } xi++; j++; if (j >= POINT_BUFFER_SIZE) break; ymin = ep->fmax; ymax = ep->fmin; } return(j); } int peak_env_partial_graph(chan_info *cp, mus_long_t beg, mus_long_t end, mus_float_t samples_per_pixel, int srate) { mus_float_t step, x; double xf, xk; mus_float_t ymin, ymax; int xi; int j = 0; mus_long_t i; peak_env_info *ep; axis_info *ap; ap = cp->axis; ep = cp->edits[cp->edit_ctr]->peak_env; step = samples_per_pixel / (mus_float_t)(ep->samps_per_bin); xf = (double)(beg) / (double)(ep->samps_per_bin); x = beg / srate; xi = grf_x(x, ap); i = beg; xk = (double)i; ymin = ep->fmax; ymax = ep->fmin; while (i <= end) { int k, kk; k = (int)xf; xf += step; kk = (int)xf; if (kk >= ep->peak_env_size) kk = ep->peak_env_size - 1; for (; k <= kk; k++) { if (ep->data_min[k] < ymin) ymin = ep->data_min[k]; if (ep->data_max[k] > ymax) ymax = ep->data_max[k]; } xk += samples_per_pixel; i = (mus_long_t)xk; set_grf_points(xi, j, local_grf_y(ymin, ap), local_grf_y(ymax, ap)); xi++; j++; if (j >= POINT_BUFFER_SIZE) break; ymin = ep->fmax; ymax = ep->fmin; } return(j); } void peak_env_scale_by(chan_info *cp, mus_float_t scl, int pos) { peak_env_info *old_ep; old_ep = cp->edits[pos]->peak_env; if ((old_ep) && (old_ep->completed)) { int i; peak_env_info *new_ep; new_ep = cp->edits[cp->edit_ctr]->peak_env; if ((new_ep) && (new_ep->peak_env_size != old_ep->peak_env_size)) new_ep = free_peak_env(cp, cp->edit_ctr); if (new_ep == NULL) { new_ep = (peak_env_info *)calloc(1, sizeof(peak_env_info)); new_ep->data_max = (mus_float_t *)malloc(old_ep->peak_env_size * sizeof(mus_float_t)); new_ep->data_min = (mus_float_t *)malloc(old_ep->peak_env_size * sizeof(mus_float_t)); } new_ep->peak_env_size = old_ep->peak_env_size; new_ep->samps_per_bin = old_ep->samps_per_bin; if (scl >= 0.0) { new_ep->fmin = old_ep->fmin * scl; new_ep->fmax = old_ep->fmax * scl; for (i = 0; i < new_ep->peak_env_size; i++) { new_ep->data_min[i] = old_ep->data_min[i] * scl; new_ep->data_max[i] = old_ep->data_max[i] * scl; } } else { new_ep->fmax = old_ep->fmin * scl; new_ep->fmin = old_ep->fmax * scl; for (i = 0; i < new_ep->peak_env_size; i++) { new_ep->data_max[i] = old_ep->data_min[i] * scl; new_ep->data_min[i] = old_ep->data_max[i] * scl; } } new_ep->completed = true; new_ep->bin = old_ep->bin; new_ep->top_bin = old_ep->top_bin; cp->edits[cp->edit_ctr]->peak_env = new_ep; } } void pick_one_bin(peak_env_info *ep, int bin, mus_long_t cursamp, chan_info *cp, int edpos) { snd_fd *sf; int n; mus_float_t val, ymin, ymax; /* here we have to read the current bin using the current fragments */ sf = init_sample_read_any(cursamp, cp, READ_FORWARD, edpos); if (sf == NULL) return; val = read_sample(sf); ymin = val; ymax = val; for (n = 1; n < ep->samps_per_bin; n++) { val = read_sample(sf); if (ymin > val) ymin = val; if (ymax < val) ymax = val; } ep->data_max[bin] = ymax; ep->data_min[bin] = ymin; free_snd_fd(sf); } void peak_env_scale_selection_by(chan_info *cp, mus_float_t scl, mus_long_t beg, mus_long_t num, int pos) { peak_env_info *old_ep; old_ep = cp->edits[pos]->peak_env; if ((old_ep) && (old_ep->completed)) { mus_float_t fmax = MAX_INIT, fmin = MIN_INIT; mus_long_t cursamp, start, end; int i; peak_env_info *new_ep; new_ep = cp->edits[cp->edit_ctr]->peak_env; if ((new_ep) && (new_ep->peak_env_size != old_ep->peak_env_size)) new_ep = free_peak_env(cp, cp->edit_ctr); if (new_ep == NULL) { new_ep = (peak_env_info *)calloc(1, sizeof(peak_env_info)); new_ep->data_max = (mus_float_t *)malloc(old_ep->peak_env_size * sizeof(mus_float_t)); new_ep->data_min = (mus_float_t *)malloc(old_ep->peak_env_size * sizeof(mus_float_t)); } new_ep->peak_env_size = old_ep->peak_env_size; new_ep->samps_per_bin = old_ep->samps_per_bin; end = beg + num - 1; start = beg - new_ep->samps_per_bin; for (i = 0, cursamp = 0; i < new_ep->peak_env_size; i++, cursamp += new_ep->samps_per_bin) { if ((cursamp >= end) || (cursamp <= start)) { new_ep->data_min[i] = old_ep->data_min[i]; new_ep->data_max[i] = old_ep->data_max[i]; } else { /* if segment is entirely in scaled section, just scale it */ if ((cursamp >= beg) && ((cursamp + new_ep->samps_per_bin) <= end)) { if (scl >= 0.0) { new_ep->data_max[i] = old_ep->data_max[i] * scl; new_ep->data_min[i] = old_ep->data_min[i] * scl; } else { new_ep->data_max[i] = old_ep->data_min[i] * scl; new_ep->data_min[i] = old_ep->data_max[i] * scl; } } else pick_one_bin(new_ep, i, cursamp, cp, cp->edit_ctr); } if (fmin > new_ep->data_min[i]) fmin = new_ep->data_min[i]; if (fmax < new_ep->data_max[i]) fmax = new_ep->data_max[i]; } new_ep->fmin = fmin; new_ep->fmax = fmax; new_ep->completed = true; new_ep->bin = old_ep->bin; new_ep->top_bin = old_ep->top_bin; cp->edits[cp->edit_ctr]->peak_env = new_ep; } } peak_env_info *peak_env_section(chan_info *cp, mus_long_t beg, mus_long_t num, int edpos) { /* used in snd-region.c to create the region peak amp env */ peak_env_info *old_ep, *new_ep = NULL; mus_float_t fmax = MAX_INIT, fmin = MIN_INIT; int i, j; mus_long_t cursamp, start, end; old_ep = cp->edits[edpos]->peak_env; if (old_ep == NULL) return(NULL); new_ep = (peak_env_info *)calloc(1, sizeof(peak_env_info)); new_ep->data_max = (mus_float_t *)malloc(old_ep->peak_env_size * sizeof(mus_float_t)); new_ep->data_min = (mus_float_t *)malloc(old_ep->peak_env_size * sizeof(mus_float_t)); new_ep->peak_env_size = old_ep->peak_env_size; new_ep->samps_per_bin = old_ep->samps_per_bin; end = beg + num - 1; start = beg - new_ep->samps_per_bin; for (i = 0, j = 0, cursamp = 0; (i < new_ep->peak_env_size) && (cursamp < end); i++, cursamp += new_ep->samps_per_bin) { if (cursamp > start) { /* if segment is entirely in region, just copy it */ if ((cursamp >= beg) && ((cursamp + new_ep->samps_per_bin) <= end)) { new_ep->data_max[j] = old_ep->data_max[i]; new_ep->data_min[j] = old_ep->data_min[i]; } else pick_one_bin(new_ep, j, cursamp, cp, edpos); if (fmin > new_ep->data_min[j]) fmin = new_ep->data_min[j]; if (fmax < new_ep->data_max[j]) fmax = new_ep->data_max[j]; j++; } new_ep->fmin = fmin; new_ep->fmax = fmax; new_ep->completed = true; new_ep->bin = old_ep->bin; new_ep->top_bin = old_ep->top_bin; } return(new_ep); } peak_env_info *copy_peak_env_info(peak_env_info *old_ep, bool reversed) { peak_env_info *new_ep = NULL; if ((old_ep) && (old_ep->completed)) { new_ep = (peak_env_info *)calloc(1, sizeof(peak_env_info)); new_ep->data_max = (mus_float_t *)malloc(old_ep->peak_env_size * sizeof(mus_float_t)); new_ep->data_min = (mus_float_t *)malloc(old_ep->peak_env_size * sizeof(mus_float_t)); new_ep->peak_env_size = old_ep->peak_env_size; new_ep->samps_per_bin = old_ep->samps_per_bin; new_ep->fmin = old_ep->fmin; new_ep->fmax = old_ep->fmax; if (reversed) { int i, j; for (i = 0, j = new_ep->peak_env_size - 1; i < new_ep->peak_env_size; i++, j--) { new_ep->data_min[j] = old_ep->data_min[i]; new_ep->data_max[j] = old_ep->data_max[i]; } } else { memcpy((void *)new_ep->data_min, (void *)old_ep->data_min, sizeof(mus_float_t) * new_ep->peak_env_size); memcpy((void *)new_ep->data_max, (void *)old_ep->data_max, sizeof(mus_float_t) * new_ep->peak_env_size); } new_ep->completed = true; new_ep->bin = old_ep->bin; new_ep->top_bin = old_ep->top_bin; } return(new_ep); } peak_env_info *peak_env_copy(chan_info *cp, bool reversed, int edpos) { return(copy_peak_env_info(cp->edits[edpos]->peak_env, reversed)); } void amp_env_env(chan_info *cp, mus_float_t *brkpts, int npts, int pos, mus_float_t base, mus_float_t scaler, mus_float_t offset) { peak_env_info *old_ep; old_ep = cp->edits[pos]->peak_env; if ((old_ep) && (old_ep->completed)) { int i; mus_any *e; mus_float_t fmin, fmax; peak_env_info *new_ep; new_ep = cp->edits[cp->edit_ctr]->peak_env; if ((new_ep) && (new_ep->peak_env_size != old_ep->peak_env_size)) new_ep = free_peak_env(cp, cp->edit_ctr); if (new_ep == NULL) { new_ep = (peak_env_info *)calloc(1, sizeof(peak_env_info)); new_ep->data_max = (mus_float_t *)malloc(old_ep->peak_env_size * sizeof(mus_float_t)); new_ep->data_min = (mus_float_t *)malloc(old_ep->peak_env_size * sizeof(mus_float_t)); } new_ep->peak_env_size = old_ep->peak_env_size; new_ep->samps_per_bin = old_ep->samps_per_bin; if (base == 1.0) e = mus_make_env(brkpts, npts, scaler, offset, base, 0.0, new_ep->peak_env_size - 1, brkpts); else e = mus_make_env(brkpts, npts, 1.0, 0.0, base, 0.0, new_ep->peak_env_size - 1, brkpts); fmin = MIN_INIT; fmax = MAX_INIT; for (i = 0; i < new_ep->peak_env_size; i++) { mus_float_t val; val = mus_env(e); if (val >= 0.0) { new_ep->data_min[i] = old_ep->data_min[i] * val; new_ep->data_max[i] = old_ep->data_max[i] * val; } else { new_ep->data_min[i] = old_ep->data_max[i] * val; new_ep->data_max[i] = old_ep->data_min[i] * val; } if (new_ep->data_min[i] < fmin) fmin = new_ep->data_min[i]; if (new_ep->data_max[i] > fmax) fmax = new_ep->data_max[i]; } new_ep->fmin = fmin; new_ep->fmax = fmax; new_ep->completed = true; new_ep->bin = old_ep->bin; new_ep->top_bin = old_ep->top_bin; cp->edits[cp->edit_ctr]->peak_env = new_ep; mus_free(e); } } void amp_env_env_selection_by(chan_info *cp, mus_any *e, mus_long_t beg, mus_long_t num, int pos) { peak_env_info *old_ep; old_ep = cp->edits[pos]->peak_env; if ((old_ep) && (old_ep->completed)) { mus_float_t xmax = 1.0; mus_float_t *data; mus_float_t fmax = MAX_INIT, fmin = MIN_INIT; int i; mus_long_t cursamp, start, end; peak_env_info *new_ep; new_ep = cp->edits[cp->edit_ctr]->peak_env; if ((new_ep) && (new_ep->peak_env_size != old_ep->peak_env_size)) new_ep = free_peak_env(cp, cp->edit_ctr); if (new_ep == NULL) { new_ep = (peak_env_info *)calloc(1, sizeof(peak_env_info)); new_ep->data_max = (mus_float_t *)malloc(old_ep->peak_env_size * sizeof(mus_float_t)); new_ep->data_min = (mus_float_t *)malloc(old_ep->peak_env_size * sizeof(mus_float_t)); } new_ep->peak_env_size = old_ep->peak_env_size; new_ep->samps_per_bin = old_ep->samps_per_bin; end = beg + num - 1; start = beg - new_ep->samps_per_bin; data = mus_data(e); xmax = data[mus_env_breakpoints(e) * 2 - 2]; for (i = 0, cursamp = 0; i < new_ep->peak_env_size; i++, cursamp += new_ep->samps_per_bin) { if ((cursamp >= end) || (cursamp <= start)) { new_ep->data_min[i] = old_ep->data_min[i]; new_ep->data_max[i] = old_ep->data_max[i]; } else { /* if segment is entirely in scaled section, just scale it */ if ((cursamp >= beg) && ((cursamp + new_ep->samps_per_bin) <= end)) { mus_float_t val; val = mus_env_interp((double)(cursamp - beg) * xmax / (double)num, e); if (val >= 0.0) { new_ep->data_max[i] = old_ep->data_max[i] * val; new_ep->data_min[i] = old_ep->data_min[i] * val; } else { new_ep->data_max[i] = old_ep->data_min[i] * val; new_ep->data_min[i] = old_ep->data_max[i] * val; } } else pick_one_bin(new_ep, i, cursamp, cp, cp->edit_ctr); } if (fmin > new_ep->data_min[i]) fmin = new_ep->data_min[i]; if (fmax < new_ep->data_max[i]) fmax = new_ep->data_max[i]; } new_ep->fmin = fmin; new_ep->fmax = fmax; new_ep->completed = true; new_ep->bin = old_ep->bin; new_ep->top_bin = old_ep->top_bin; cp->edits[cp->edit_ctr]->peak_env = new_ep; } } void peak_env_insert_zeros(chan_info *cp, mus_long_t beg, mus_long_t num, int pos) { peak_env_info *old_ep; old_ep = cp->edits[pos]->peak_env; if ((old_ep) && (old_ep->completed)) { mus_long_t end, old_samps, cur_samps; int i, j, subsamp, val, bins; peak_env_info *new_ep; new_ep = cp->edits[cp->edit_ctr]->peak_env; if (new_ep) new_ep = free_peak_env(cp, cp->edit_ctr); old_samps = cp->edits[pos]->samples; cur_samps = current_samples(cp); val = (int)(log((double)(cur_samps))); if (val > 20) val = 20; val = snd_int_pow2(val); subsamp = val / old_ep->peak_env_size; if (subsamp != 1) return; new_ep = (peak_env_info *)calloc(1, sizeof(peak_env_info)); new_ep->samps_per_bin = old_ep->samps_per_bin; new_ep->peak_env_size = (int)(ceil(cur_samps / new_ep->samps_per_bin)); new_ep->completed = true; cp->edits[cp->edit_ctr]->peak_env = new_ep; new_ep->bin = new_ep->peak_env_size; new_ep->top_bin = new_ep->peak_env_size; new_ep->data_max = (mus_float_t *)calloc(new_ep->peak_env_size, sizeof(mus_float_t)); new_ep->data_min = (mus_float_t *)calloc(new_ep->peak_env_size, sizeof(mus_float_t)); new_ep->fmin = old_ep->fmin; if (new_ep->fmin > 0.0) new_ep->fmin = 0.0; new_ep->fmax = old_ep->fmax; if (new_ep->fmax < 0.0) new_ep->fmax = 0.0; end = beg + num - 1; if (beg == 0) { /* insert at start, so copy to end */ i = (int)ceil(end / new_ep->samps_per_bin); bins = new_ep->peak_env_size - i; if (old_ep->peak_env_size < bins) bins = old_ep->peak_env_size; memcpy((void *)(&(new_ep->data_min[i])), (void *)old_ep->data_min, sizeof(mus_float_t) * bins); memcpy((void *)(&(new_ep->data_max[i])), (void *)old_ep->data_max, sizeof(mus_float_t) * bins); } else { if (beg >= old_samps) { /* copy start */ bins = (int)floor(beg / old_ep->samps_per_bin); if (bins > old_ep->peak_env_size) bins = old_ep->peak_env_size; memcpy((void *)new_ep->data_min, (void *)old_ep->data_min, sizeof(mus_float_t) * bins); memcpy((void *)new_ep->data_max, (void *)old_ep->data_max, sizeof(mus_float_t) * bins); } else { i = (int)floor(beg / old_ep->samps_per_bin); if (i > 0) { memcpy((void *)new_ep->data_min, (void *)old_ep->data_min, sizeof(mus_float_t) * i); memcpy((void *)new_ep->data_max, (void *)old_ep->data_max, sizeof(mus_float_t) * i); } if (i < new_ep->peak_env_size) { pick_one_bin(new_ep, i, i * old_ep->samps_per_bin, cp, cp->edit_ctr); i++; } j = (int)floor(end / new_ep->samps_per_bin); if (j < new_ep->peak_env_size) { pick_one_bin(new_ep, j, j * new_ep->samps_per_bin, cp, cp->edit_ctr); j++; } if (i < old_ep->peak_env_size) { bins = new_ep->peak_env_size - j; if ((i + bins) >= old_ep->peak_env_size) bins = old_ep->peak_env_size - i; memcpy((void *)(&(new_ep->data_min[j])), (void *)(&(old_ep->data_min[i])), sizeof(mus_float_t) * bins); memcpy((void *)(&(new_ep->data_max[j])), (void *)(&(old_ep->data_max[i])), sizeof(mus_float_t) * bins); } } } } } #if XEN_HAVE_RATIOS void snd_rationalize(mus_float_t a, int *num, int *den) { Xen ratio; int gloc; ratio = Xen_rationalize(C_double_to_Xen_real(a), C_double_to_Xen_real(a * .04)); /* was .02 until 13-Dec-07 but that gives too many useless choices */ gloc = snd_protect(ratio); (*num) = (int)Xen_numerator(ratio); (*den) = (int)Xen_denominator(ratio); snd_unprotect_at(gloc); } #endif /* -------- control panel speed -------- */ #if (!XEN_HAVE_RATIOS) #define TOTAL_RATS 123 static const char *rat_names[TOTAL_RATS] = { "1/20", "5/96", "7/128", "15/256", "31/512", "1/16", "1/15", "5/72", "9/128", "3/40", "5/64", "1/12", "11/128", "3/32", "1/10", "5/48", "7/64", "15/128", "31/256", "1/8", "2/15", "5/36", "9/64", "3/20", "5/32", "1/6", "11/64", "3/16", "1/5", "5/24", "7/32", "15/64", "31/128", "1/4", "4/15", "5/18", "9/32", "3/10", "5/16", "1/3", "11/32", "3/8", "2/5", "5/12", "7/16", "15/32", "31/64", "1/2", "8/15", "5/9", "9/16", "3/5", "5/8", "2/3", "11/16", "3/4", "4/5", "5/6", "7/8", "15/16", "31/32", "1/1", "16/15", "10/9", "9/8", "6/5", "5/4", "4/3", "11/8", "3/2", "8/5", "5/3", "7/4", "15/8", "31/16", "2/1", "32/15", "20/9", "9/4", "12/5", "5/2", "8/3", "11/4", "3/1", "16/5", "10/3", "7/2", "15/4", "31/8", "4/1", "64/15", "40/9", "9/2", "24/5", "5/1", "16/3", "11/2", "6/1", "32/5", "20/3", "7/1", "15/2", "31/4", "8/1", "128/15", "80/9", "9/1", "48/5", "10/1", "32/3", "11/1", "12/1", "64/5", "40/3", "14/1", "15/1", "31/2", "16/1", "256/15", "160/9", "18/1", "96/5", "20/1"}; static mus_float_t rat_values[TOTAL_RATS] = { 0.050, 0.052, 0.055, 0.059, 0.061, 0.063, 0.067, 0.069, 0.070, 0.075, 0.078, 0.083, 0.086, 0.094, 0.100, 0.104, 0.109, 0.117, 0.121, 0.125, 0.133, 0.139, 0.141, 0.150, 0.156, 0.167, 0.172, 0.188, 0.200, 0.208, 0.219, 0.234, 0.242, 0.250, 0.267, 0.278, 0.281, 0.300, 0.313, 0.333, 0.344, 0.375, 0.400, 0.417, 0.438, 0.469, 0.484, 0.500, 0.533, 0.556, 0.563, 0.600, 0.625, 0.667, 0.688, 0.750, 0.800, 0.833, 0.875, 0.938, 0.969, 1.000, 1.067, 1.111, 1.125, 1.200, 1.250, 1.333, 1.375, 1.500, 1.600, 1.667, 1.750, 1.875, 1.938, 2.000, 2.133, 2.222, 2.250, 2.400, 2.500, 2.667, 2.750, 3.000, 3.200, 3.333, 3.500, 3.750, 3.875, 4.000, 4.267, 4.444, 4.500, 4.800, 5.000, 5.333, 5.500, 6.000, 6.400, 6.667, 7.000, 7.500, 7.750, 8.000, 8.533, 8.889, 9.000, 9.600, 10.000, 10.667, 11.000, 12.000, 12.800, 13.333, 14.000, 15.000, 15.500, 16.000, 17.067, 17.778, 18.000, 19.200, 20.000}; #endif mus_float_t speed_changed(mus_float_t val, char *srcbuf, speed_style_t style, int tones, int srcbuf_size) { char numbuf[16]; int semi, i, j; switch (style) { case SPEED_CONTROL_AS_RATIO: #if XEN_HAVE_RATIOS { int num, den; snd_rationalize(val, &num, &den); snprintf(srcbuf, srcbuf_size, "%d/%d", num, den); return((mus_float_t)num / (mus_float_t)den); } #else for (i = 1; i < TOTAL_RATS; i++) if (rat_values[i] > val) break; if ((rat_values[i] - val) < (val - rat_values[i - 1])) { snprintf(srcbuf, srcbuf_size, "%s", rat_names[i]); return(rat_values[i]); } else { snprintf(srcbuf, srcbuf_size, "%s", rat_names[i - 1]); return(rat_values[i - 1]); } #endif break; case SPEED_CONTROL_AS_SEMITONE: /* find closest semitone to val */ semi = snd_round(log(val) * ((mus_float_t)tones / log(2.0))); /* space until (-) num (-52 to 52 is its range if 12-tone) */ for (i = 0; i < srcbuf_size; i++) srcbuf[i] = ' '; snprintf(numbuf, 16, "%d", semi); j = strlen(numbuf) - 1; for (i = 3; (i >= 0) && (j >= 0); i--, j--) srcbuf[i] = numbuf[j]; srcbuf[srcbuf_size - 1] = 0; return(pow(2.0, ((mus_float_t)semi / (mus_float_t)tones))); break; default: snprintf(srcbuf, srcbuf_size, "%.3f", val); return(val); break; } } /* -------- name click etc */ static char sname[PRINT_BUFFER_SIZE]; char *shortname(snd_info *sp) { if (is_link_file(sp->filename)) { snprintf(sname, PRINT_BUFFER_SIZE, "(%s)", sp->short_filename); return(sname); } return(sp->short_filename); } char *shortname_indexed(snd_info *sp) { if (show_indices(ss)) { if (is_link_file(sp->filename)) snprintf(sname, PRINT_BUFFER_SIZE, "%d: (%s)", sp->index, sp->short_filename); /* don't try to share sname */ else snprintf(sname, PRINT_BUFFER_SIZE, "%d: %s", sp->index, sp->short_filename); return(sname); } return(shortname(sp)); } void add_sound_data(char *filename, snd_info *sp, channel_graph_t graphed) { int i; for (i = 0; i < sp->nchans; i++) add_channel_data(filename, sp->chans[i], graphed); } #ifndef _MSC_VER static char *linked_file(const char *link_name) { char *link_file; ssize_t bytes; #define READLINK_FILE_SIZE 256 link_file = (char *)calloc(READLINK_FILE_SIZE, sizeof(char)); bytes = readlink(link_name, link_file, READLINK_FILE_SIZE); link_file[bytes] = 0; return(link_file); } #endif static Xen name_click_hook; char *sp_name_click(snd_info *sp) /* caller should free returned string */ { if (sp) { file_info *hdr; /* call name-click-hook (if any) return #t = don't print info in the status area */ if ((Xen_hook_has_list(name_click_hook)) && (Xen_is_true(run_or_hook(name_click_hook, Xen_list_1(C_int_to_Xen_sound(sp->index)), S_name_click_hook)))) return(NULL); hdr = sp->hdr; if (hdr) { mus_float_t dur; char *result, *str = NULL; bool linked; linked = is_link_file(sp->filename); dur = (mus_float_t)((double)(hdr->samples) / (double)(hdr->chans * hdr->srate)); result = mus_format("%d, %d chan%s, %.3f sec%s, %s: %s, %s%s%s%s", hdr->srate, hdr->chans, ((hdr->chans > 1) ? "s" : ""), dur, ((dur == 1.0) ? "" : "s"), mus_header_type_to_string(hdr->type), mus_sample_type_to_string(hdr->sample_type), snd_strftime("%d-%b-%Y %H:%M", sp->write_date), (linked) ? ", (link to " : "", #ifndef _MSC_VER (linked) ? str = linked_file(sp->filename) : "", #else (linked) ? "?" : "", #endif (linked) ? ")" : ""); if (str) free(str); return(result); } } return(NULL); } /* ---------------- save and restore control panel buttons ----------------*/ typedef struct ctrl_state { mus_float_t amp, speed, contrast, expand, revscl, revlen; env *filter_env; bool expand_on, contrast_on, reverb_on, filter_on, reversed; int filter_order; mus_float_t contrast_amp, expand_ramp, expand_length, expand_hop, expand_jitter, reverb_feedback, reverb_decay, reverb_lowpass; } ctrl_state; static ctrl_state *free_control_settings(ctrl_state *cs) { if (cs) { if (cs->filter_env) free_env(cs->filter_env); free(cs); } return(NULL); } void free_controls(snd_info *sp) { sp->saved_controls = free_control_settings(sp->saved_controls); } static ctrl_state *current_control_settings(snd_info *sp, ctrl_state *cs) { if (!cs) cs = (ctrl_state *)calloc(1, sizeof(ctrl_state)); cs->amp = sp->amp_control; cs->speed = sp->speed_control; cs->expand = sp->expand_control; cs->revscl = sp->reverb_control_scale; cs->revlen = sp->reverb_control_length; cs->contrast = sp->contrast_control; cs->expand_on = sp->expand_control_on; cs->reverb_on = sp->reverb_control_on; cs->contrast_on = sp->contrast_control_on; cs->filter_on = sp->filter_control_on; cs->filter_order = sp->filter_control_order; if (sp->filter_control_envelope) { if (cs->filter_env) cs->filter_env = free_env(cs->filter_env); cs->filter_env = copy_env(sp->filter_control_envelope); } if (sp->speed_control_direction == 1) cs->reversed = false; else cs->reversed = true; cs->contrast_amp = sp->contrast_control_amp; cs->expand_ramp = sp->expand_control_ramp; cs->expand_hop = sp->expand_control_hop; cs->expand_jitter = sp->expand_control_jitter; cs->expand_length = sp->expand_control_length; cs->reverb_feedback = sp->reverb_control_feedback; cs->reverb_decay = sp->reverb_control_decay; cs->reverb_lowpass = sp->reverb_control_lowpass; return(cs); } void save_controls(snd_info *sp) { sp->saved_controls = current_control_settings(sp, sp->saved_controls); } static ctrl_state *restore_control_settings(snd_info *sp, ctrl_state *cs) { /* for use in controls->channel when the actual control panel is not in use */ if (cs) { sp->amp_control = cs->amp; sp->speed_control = cs->speed; sp->expand_control = cs->expand; sp->reverb_control_scale = cs->revscl; sp->reverb_control_length = cs->revlen; sp->contrast_control = cs->contrast; sp->expand_control_on = cs->expand_on; sp->reverb_control_on = cs->reverb_on; sp->contrast_control_on = cs->contrast_on; sp->filter_control_on = cs->filter_on; sp->filter_control_order = cs->filter_order; if (cs->filter_env) { sp->filter_control_envelope = free_env(sp->filter_control_envelope); sp->filter_control_envelope = copy_env(cs->filter_env); } if (cs->reversed) sp->speed_control_direction = -1; else sp->speed_control_direction = 1; sp->contrast_control_amp = cs->contrast_amp; sp->expand_control_ramp = cs->expand_ramp; sp->expand_control_hop = cs->expand_hop; sp->expand_control_jitter = cs->expand_jitter; sp->expand_control_length = cs->expand_length; sp->reverb_control_feedback = cs->reverb_feedback; sp->reverb_control_decay = cs->reverb_decay; sp->reverb_control_lowpass = cs->reverb_lowpass; } return(cs); } void restore_controls(snd_info *sp) { ctrl_state *cs; char *tmpstr; cs = sp->saved_controls; if (!cs) { sp->saved_controls = (ctrl_state *)calloc(1, sizeof(ctrl_state)); cs = sp->saved_controls; cs->amp = DEFAULT_AMP_CONTROL; cs->speed = DEFAULT_SPEED_CONTROL; cs->reversed = false; /* (this is the button's view) */ cs->expand = DEFAULT_EXPAND_CONTROL; cs->expand_on = DEFAULT_EXPAND_CONTROL_ON; cs->revscl = DEFAULT_REVERB_CONTROL_SCALE; cs->revlen = DEFAULT_REVERB_CONTROL_LENGTH; cs->reverb_on = DEFAULT_REVERB_CONTROL_ON; cs->contrast = DEFAULT_CONTRAST_CONTROL; cs->contrast_on = DEFAULT_CONTRAST_CONTROL_ON; cs->filter_on = DEFAULT_FILTER_CONTROL_ON; cs->filter_order = filter_control_order(ss); cs->filter_env = NULL; } toggle_expand_button(sp, cs->expand_on); toggle_contrast_button(sp, cs->contrast_on); toggle_reverb_button(sp, cs->reverb_on); toggle_filter_button(sp, cs->filter_on); toggle_direction_arrow(sp, cs->reversed); set_amp(sp, cs->amp); set_speed(sp, cs->speed); set_contrast(sp, cs->contrast); set_expand(sp, cs->expand); set_revscl(sp, cs->revscl); set_revlen(sp, cs->revlen); if (sp->filter_control_envelope) sp->filter_control_envelope = free_env(sp->filter_control_envelope); if (cs->filter_env) sp->filter_control_envelope = copy_env(cs->filter_env); else sp->filter_control_envelope = default_env(sp->filter_control_xmax, 1.0); set_filter_order(sp, cs->filter_order); /* causes redisplay */ tmpstr = env_to_string(sp->filter_control_envelope); set_filter_text(sp, tmpstr); if (tmpstr) free(tmpstr); } void reset_controls(snd_info *sp) { char *tmpstr; toggle_expand_button(sp, DEFAULT_EXPAND_CONTROL_ON); toggle_contrast_button(sp, DEFAULT_CONTRAST_CONTROL_ON); toggle_reverb_button(sp, DEFAULT_REVERB_CONTROL_ON); toggle_filter_button(sp, DEFAULT_FILTER_CONTROL_ON); toggle_direction_arrow(sp, false); set_amp(sp, DEFAULT_AMP_CONTROL); set_speed(sp, DEFAULT_SPEED_CONTROL); set_contrast(sp, DEFAULT_CONTRAST_CONTROL); set_expand(sp, DEFAULT_EXPAND_CONTROL); set_revscl(sp, DEFAULT_REVERB_CONTROL_SCALE); set_revlen(sp, DEFAULT_REVERB_CONTROL_LENGTH); set_filter_order(sp, filter_control_order(ss)); if (sp->filter_control_envelope) sp->filter_control_envelope = free_env(sp->filter_control_envelope); sp->filter_control_envelope = default_env(sp->filter_control_xmax, 1.0); tmpstr = env_to_string(sp->filter_control_envelope); set_filter_text(sp, tmpstr); display_filter_env(sp); if (tmpstr) free(tmpstr); } static void apply_unset_controls(snd_info *sp) { /* after apply_controls there's no need to clear everything! */ toggle_expand_button(sp, DEFAULT_EXPAND_CONTROL_ON); toggle_contrast_button(sp, DEFAULT_CONTRAST_CONTROL_ON); toggle_reverb_button(sp, DEFAULT_REVERB_CONTROL_ON); toggle_filter_button(sp, DEFAULT_FILTER_CONTROL_ON); toggle_direction_arrow(sp, false); set_amp(sp, DEFAULT_AMP_CONTROL); set_speed(sp, DEFAULT_SPEED_CONTROL); } void set_show_controls(bool val) { in_set_show_controls(ss, val); #if (!USE_NO_GUI) if (in_show_controls(ss)) show_all_controls(); else hide_all_controls(); #endif } /* ---------------- control panel apply ---------------- */ void stop_applying(snd_info *sp) { /* called if C-g during the apply process */ sp->apply_ok = false; } typedef struct { int slice; snd_info *sp; mus_long_t i; int ofd; char *ofile; ctrl_state *cs; file_info *hdr; char *origin; } apply_state; static Xen after_apply_controls_hook; static void *make_apply_state(snd_info *sp) { /* set up initial state for apply_controls */ apply_state *ap = NULL; ap = (apply_state *)calloc(1, sizeof(apply_state)); ap->slice = 0; ap->hdr = NULL; ap->sp = sp; return((void *)ap); } static apply_state *free_apply_state(apply_state *ap) { if (ap) { if (ap->ofile) {free(ap->ofile); ap->ofile = NULL;} if (ap->origin) {free(ap->origin); ap->origin = NULL;} ap->hdr = free_file_info(ap->hdr); free(ap); } return(NULL); } static mus_long_t apply_dur = 0, orig_dur, apply_beg = 0; static bool apply_controls(apply_state *ap) { snd_info *sp; chan_info *cp = NULL; sync_info *si; mus_float_t mult_dur; int i, added_dur = 0; if (ap == NULL) return(false); sp = ap->sp; if ((!(sp->active)) || (sp->inuse != SOUND_NORMAL)) return(false); if (sp->filter_control_on) added_dur = sp->filter_control_order; mult_dur = 1.0 / fabs(sp->speed_control); if (sp->expand_control_on) mult_dur *= sp->expand_control; if (sp->reverb_control_on) added_dur += (int)((snd_srate(sp) * sp->reverb_control_decay)); if ((ss->apply_choice != APPLY_TO_SELECTION) && (snd_feq(sp->speed_control, 1.0)) && (apply_beg == 0) && (sp->speed_control_direction == 1) && (!(sp->filter_control_on)) && (!(sp->expand_control_on)) && (!(sp->reverb_control_on)) && (!(sp->contrast_control_on))) { int old_sync; bool need_scaling = false; mus_float_t *scalers = NULL; old_sync = sp->sync; /* get unused sync val */ if (ss->apply_choice == APPLY_TO_SOUND) { sp->sync = ss->sound_sync_max + 1; ss->sound_sync_max++; } else sp->sync = 0; /* check for local amp_control vals */ if (sp->selected_channel == NO_SELECTION) cp = sp->chans[0]; else cp = sp->chans[sp->selected_channel]; si = sync_to_chan(cp); if (si == NULL) { sp->sync = old_sync; return(false); } scalers = (mus_float_t *)calloc(si->chans, sizeof(mus_float_t)); for (i = 0; i < si->chans; i++) { chan_info *ncp; ncp = si->cps[i]; if (ncp->amp_control) scalers[i] = ncp->amp_control[0]; else scalers[i] = sp->amp_control; if (!(snd_feq(scalers[i], 1.0))) need_scaling = true; /* could possibly check all edit_ctrs, but this seems easier */ } if (need_scaling) scale_by(cp, scalers, si->chans, false); else snd_warning_without_format("apply controls: no changes to apply!"); sp->sync = old_sync; free(scalers); si = free_sync_info(si); } else { mus_long_t orig_apply_dur; io_error_t io_err = IO_NO_ERROR; int curchan = 0; orig_apply_dur = apply_dur; switch (ap->slice) { case 0: /* apply_beg = 0; */ ap->ofile = NULL; ap->ofile = snd_tempnam(); ap->hdr = make_temp_header(ap->ofile, snd_srate(sp), sp->nchans, 0, (char *)__func__); switch (ss->apply_choice) { case APPLY_TO_CHANNEL: ap->hdr->chans = 1; if (sp->selected_channel != NO_SELECTION) curchan = sp->selected_channel; if (apply_dur == 0) apply_dur = current_samples(sp->chans[curchan]) - apply_beg; break; case APPLY_TO_SOUND: ap->hdr->chans = sp->nchans; if (apply_dur == 0) apply_dur = current_samples(sp->chans[0]) - apply_beg; break; case APPLY_TO_SELECTION: ap->hdr->chans = selection_chans(); if (ap->hdr->chans <= 0) return(false); if (apply_dur == 0) apply_dur = selection_len(); break; } if (ap->origin == NULL) { /* from apply-controls */ /* to reproduce this on a channel-independent basis, we need to use controls->channel * and conjure up a list of settings that match the current ones. */ char *ampstr, *speedstr, *contraststr, *expandstr, *filterstr, *reverbstr; if (sp->amp_control != DEFAULT_AMP_CONTROL) ampstr = mus_format("%.4f", sp->amp_control); else ampstr = mus_strdup(PROC_FALSE); if ((!(snd_feq(sp->speed_control, DEFAULT_SPEED_CONTROL))) || (sp->speed_control_direction == -1)) speedstr = mus_format("%.4f", sp->speed_control * sp->speed_control_direction); else speedstr = mus_strdup(PROC_FALSE); if (sp->contrast_control_on) contraststr = mus_format(LIST_OPEN "%.4f" PROC_SEP "%.4f" LIST_CLOSE, sp->contrast_control, sp->contrast_control_amp); else contraststr = mus_strdup(PROC_FALSE); if (sp->expand_control_on) expandstr = mus_format(LIST_OPEN "%.4f" PROC_SEP "%.4f" PROC_SEP "%.4f" PROC_SEP "%.4f" PROC_SEP "%.4f" LIST_CLOSE, sp->expand_control, sp->expand_control_length, sp->expand_control_ramp, sp->expand_control_hop, sp->expand_control_jitter); else expandstr = mus_strdup(PROC_FALSE); if (sp->reverb_control_on) reverbstr = mus_format(LIST_OPEN "%.4f" PROC_SEP "%.4f" PROC_SEP "%.4f" PROC_SEP "%.4f" PROC_SEP "%.4f" LIST_CLOSE, sp->reverb_control_scale, sp->reverb_control_length, sp->reverb_control_feedback, sp->reverb_control_lowpass, sp->reverb_control_decay); else reverbstr = mus_strdup(PROC_FALSE); if (sp->filter_control_on) { char *envstr; envstr = env_to_string(sp->filter_control_envelope); filterstr = mus_format(LIST_OPEN "%d" PROC_SEP "%s" LIST_CLOSE, sp->filter_control_order, envstr); free(envstr); } else filterstr = mus_strdup(PROC_FALSE); #if HAVE_FORTH if (orig_apply_dur == 0) ap->origin = mus_format(" '( %s %s %s %s %s %s ) %lld" PROC_SEP PROC_FALSE " %s", ampstr, speedstr, contraststr, expandstr, reverbstr, filterstr, apply_beg, S_controls_to_channel); else ap->origin = mus_format(" '( %s %s %s %s %s %s ) %lld" PROC_SEP "%lld %s", ampstr, speedstr, contraststr, expandstr, reverbstr, filterstr, apply_beg, apply_dur, S_controls_to_channel); #else if (orig_apply_dur == 0) ap->origin = mus_format("%s" PROC_OPEN LIST_OPEN "%s" PROC_SEP "%s" PROC_SEP "%s" PROC_SEP "%s" PROC_SEP "%s" PROC_SEP "%s" LIST_CLOSE PROC_SEP "%lld" PROC_SEP PROC_FALSE, to_proc_name(S_controls_to_channel), ampstr, speedstr, contraststr, expandstr, reverbstr, filterstr, apply_beg); else ap->origin = mus_format("%s" PROC_OPEN LIST_OPEN "%s" PROC_SEP "%s" PROC_SEP "%s" PROC_SEP "%s" PROC_SEP "%s" PROC_SEP "%s" LIST_CLOSE PROC_SEP "%lld" PROC_SEP "%lld", to_proc_name(S_controls_to_channel), ampstr, speedstr, contraststr, expandstr, reverbstr, filterstr, apply_beg, apply_dur); #endif free(ampstr); free(speedstr); free(contraststr); free(expandstr); free(reverbstr); free(filterstr); } orig_dur = apply_dur; apply_dur = (mus_long_t)(mult_dur * (apply_dur + added_dur)); ap->ofd = open_temp_file(ap->ofile, ap->hdr->chans, ap->hdr, &io_err); if (ap->ofd == -1) { snd_error("%s apply temp file %s: %s\n", (io_err != IO_NO_ERROR) ? io_error_name(io_err) : "can't open", ap->ofile, snd_open_strerror()); sp->applying = false; ap = free_apply_state(ap); return(false); } sp->apply_ok = true; initialize_apply(sp, ap->hdr->chans, apply_beg, orig_dur + added_dur); /* dur here is input dur */ ap->i = 0; ap->slice++; return(true); break; case 1: if (!(sp->apply_ok)) ap->slice++; else { int len; len = run_apply(ap->ofd); /* returns framples written (an int) */ if (len <= 0) { ap->slice++; return(true); } ap->i += len; if (ap->i >= apply_dur) ap->slice++; /* check_for_event(); */ /* if C-G, stop_applying called which cancels and backs out */ if ((ss->stopped_explicitly) || (!(sp->active))) ap->slice++; } return(true); break; case 2: finalize_apply(sp); close_temp_file(ap->ofile, ap->ofd, ap->hdr->type, apply_dur * (ap->hdr->chans) * mus_bytes_per_sample((ap->hdr)->sample_type)); if ((sp->apply_ok) && (apply_dur > 0)) { switch (ss->apply_choice) { case APPLY_TO_SOUND: if (sp->nchans > 1) remember_temp(ap->ofile, sp->nchans); if (apply_beg > 0) { for (i = 0; i < sp->nchans; i++) { if (file_change_samples(apply_beg, apply_dur, ap->ofile, sp->chans[i], i, (sp->nchans > 1) ? MULTICHANNEL_DELETION : DELETE_ME, ap->origin, sp->chans[i]->edit_ctr)) update_graph(sp->chans[i]); } } else { for (i = 0; i < sp->nchans; i++) { if (file_override_samples(apply_dur, ap->ofile, sp->chans[i], i, (sp->nchans > 1) ? MULTICHANNEL_DELETION : DELETE_ME, ap->origin)) update_graph(sp->chans[i]); } } break; case APPLY_TO_CHANNEL: if (sp->selected_channel != NO_SELECTION) curchan = sp->selected_channel; if (apply_beg > 0) file_change_samples(apply_beg, apply_dur, ap->ofile, sp->chans[curchan], 0, DELETE_ME, ap->origin, sp->chans[curchan]->edit_ctr); else file_override_samples(apply_dur, ap->ofile, sp->chans[curchan], 0, DELETE_ME, ap->origin); update_graph(sp->chans[curchan]); break; case APPLY_TO_SELECTION: if (selection_chans() > 1) remember_temp(ap->ofile, selection_chans()); si = selection_sync(); if (apply_dur == selection_len()) { for (i = 0; i < si->chans; i++) { if (file_change_samples(si->begs[i], apply_dur, ap->ofile, si->cps[i], i, (si->chans > 1) ? MULTICHANNEL_DELETION : DELETE_ME, ap->origin, si->cps[i]->edit_ctr)) update_graph(si->cps[i]); } } else { bool ok; ok = delete_selection(DONT_UPDATE_DISPLAY); if (apply_dur > 0) { for (i = 0; i < si->chans; i++) { file_insert_samples(si->begs[i], apply_dur, ap->ofile, si->cps[i], 0, (si->chans > 1) ? MULTICHANNEL_DELETION : DELETE_ME, ap->origin, si->cps[i]->edit_ctr); reactivate_selection(si->cps[i], si->begs[i], si->begs[i] + apply_dur); if (ok) backup_edit_list(si->cps[i]); } } } si = free_sync_info(si); break; } clear_status_area(sp); sp->apply_ok = false; if ((sp->expand_control_on) || (sp->speed_control_direction != 1) || (!(snd_feq(sp->speed_control, 1.0)))) { for (i = 0; i < sp->nchans; i++) { cp = sp->chans[i]; if (cp->edits[cp->edit_ctr]->marks) { mus_float_t ratio; if (!(sp->expand_control_on)) ratio = sp->speed_control; else ratio = sp->speed_control / sp->expand_control; if (ratio != 1.0) { bool over_selection; over_selection = (ss->apply_choice == APPLY_TO_SELECTION); src_marks(cp, ratio, orig_dur, apply_dur, (over_selection) ? selection_beg(cp) : 0, over_selection); update_graph(cp); } } } } } else { snd_remove(ap->ofile, REMOVE_FROM_CACHE); } break; } } apply_unset_controls(sp); if (Xen_hook_has_list(after_apply_controls_hook)) run_hook(after_apply_controls_hook, Xen_list_1(C_int_to_Xen_sound(sp->index)), S_after_apply_controls_hook); sp->applying = false; free_apply_state(ap); ss->stopped_explicitly = false; return(false); } void expand_control_set_hop(mus_float_t hop) { int i; in_set_expand_control_hop(ss, hop); for (i = 0; i < ss->max_sounds; i++) { snd_info *sp; sp = ss->sounds[i]; if ((sp) && (sp->inuse == SOUND_NORMAL)) { sp->expand_control_hop = expand_control_hop(ss); if (sp->playing) dac_set_expand_hop(sp, expand_control_hop(ss)); } } } void expand_control_set_length(mus_float_t hop) { int i; in_set_expand_control_length(ss, hop); for (i = 0; i < ss->max_sounds; i++) { snd_info *sp; sp = ss->sounds[i]; if ((sp) && (sp->inuse == SOUND_NORMAL)) { sp->expand_control_length = expand_control_length(ss); if (sp->playing) dac_set_expand_length(sp, expand_control_length(ss)); } } } void expand_control_set_ramp(mus_float_t hop) { int i; in_set_expand_control_ramp(ss, hop); for (i = 0; i < ss->max_sounds; i++) { snd_info *sp; sp = ss->sounds[i]; if ((sp) && (sp->inuse == SOUND_NORMAL)) { sp->expand_control_ramp = expand_control_ramp(ss); if (sp->playing) dac_set_expand_ramp(sp, expand_control_ramp(ss)); } } } void expand_control_set_jitter(mus_float_t hop) { int i; in_set_expand_control_jitter(ss, hop); for (i = 0; i < ss->max_sounds; i++) { snd_info *sp; sp = ss->sounds[i]; if ((sp) && (sp->inuse == SOUND_NORMAL)) { sp->expand_control_jitter = expand_control_jitter(ss); } } } void contrast_control_set_amp(mus_float_t hop) { int i; in_set_contrast_control_amp(ss, hop); for (i = 0; i < ss->max_sounds; i++) { snd_info *sp; sp = ss->sounds[i]; if ((sp) && (sp->inuse == SOUND_NORMAL)) { sp->contrast_control_amp = contrast_control_amp(ss); if (sp->playing) dac_set_contrast_amp(sp, contrast_control_amp(ss)); } } } void reverb_control_set_lowpass(mus_float_t hop) { int i; in_set_reverb_control_lowpass(ss, hop); for (i = 0; i < ss->max_sounds; i++) { snd_info *sp; sp = ss->sounds[i]; if ((sp) && (sp->inuse == SOUND_NORMAL)) { sp->reverb_control_lowpass = reverb_control_lowpass(ss); if (sp->playing) dac_set_reverb_lowpass(sp, reverb_control_lowpass(ss)); } } } void reverb_control_set_feedback(mus_float_t hop) { int i; in_set_reverb_control_feedback(ss, hop); for (i = 0; i < ss->max_sounds; i++) { snd_info *sp; sp = ss->sounds[i]; if ((sp) && (sp->inuse == SOUND_NORMAL)) { sp->reverb_control_feedback = reverb_control_feedback(ss); if (sp->playing) dac_set_reverb_feedback(sp, reverb_control_feedback(ss)); } } } /* ---------------- status area ---------------- */ void status_report(snd_info *sp, const char *format, ...) { #if (!USE_NO_GUI) char *buf; va_list ap; if ((!sp) || (!(sp->active)) || (sp->inuse != SOUND_NORMAL)) return; va_start(ap, format); buf = vstr(format, ap); va_end(ap); set_status(sp, buf, false); free(buf); #endif } void clear_status_area(snd_info *sp) { set_status(sp, NULL, true); } void errors_to_status_area(const char *msg, void *data) { snd_info *sp; sp = (snd_info *)data; if (!(snd_ok(sp))) { sp = any_selected_sound(); if (!snd_ok(sp)) return; } status_report((snd_info *)data, "%s", msg); } void printout_to_status_area(const char *msg, void *data) { set_status((snd_info *)data, msg, false); } /* ---------------------------------------- sound objects ---------------------------------------- */ typedef struct { int n; } xen_sound; #define Xen_to_xen_sound(arg) ((xen_sound *)Xen_object_ref(arg)) int xen_sound_to_int(Xen n) { xen_sound *mx; mx = Xen_to_xen_sound(n); return(mx->n); } static Xen_object_type_t xen_sound_tag; bool xen_is_sound(Xen obj) { return(Xen_c_object_is_type(obj, xen_sound_tag)); } static void xen_sound_free(xen_sound *v) {if (v) free(v);} Xen_wrap_free(xen_sound, free_xen_sound, xen_sound_free) static char *xen_sound_to_string(xen_sound *v) { #define SOUND_PRINT_BUFFER_SIZE 64 char *buf; if (v == NULL) return(NULL); buf = (char *)calloc(SOUND_PRINT_BUFFER_SIZE, sizeof(char)); snprintf(buf, SOUND_PRINT_BUFFER_SIZE, "#", v->n); return(buf); } Xen_wrap_print(xen_sound, print_xen_sound, xen_sound_to_string) #if HAVE_FORTH || HAVE_RUBY static Xen g_xen_sound_to_string(Xen obj) { char *vstr; Xen result; #define S_xen_sound_to_string "sound->string" Xen_check_type(xen_is_sound(obj), obj, 1, S_xen_sound_to_string, "a sound"); vstr = xen_sound_to_string(Xen_to_xen_sound(obj)); result = C_string_to_Xen_string(vstr); free(vstr); return(result); } #endif #if (!HAVE_SCHEME) static bool xen_sound_equalp(xen_sound *v1, xen_sound *v2) { return((v1 == v2) || (v1->n == v2->n)); } static Xen equalp_xen_sound(Xen obj1, Xen obj2) { if ((!(xen_is_sound(obj1))) || (!(xen_is_sound(obj2)))) return(Xen_false); return(C_bool_to_Xen_boolean(xen_sound_equalp(Xen_to_xen_sound(obj1), Xen_to_xen_sound(obj2)))); } #endif static xen_sound *xen_sound_make(int n) { xen_sound *new_v; new_v = (xen_sound *)malloc(sizeof(xen_sound)); new_v->n = n; return(new_v); } Xen new_xen_sound(int n) { xen_sound *mx; if (n < 0) return(Xen_false); mx = xen_sound_make(n); return(Xen_make_object(xen_sound_tag, mx, 0, free_xen_sound)); } #if HAVE_SCHEME static bool s7_xen_sound_equalp(void *obj1, void *obj2) { return((obj1 == obj2) || (((xen_sound *)obj1)->n == ((xen_sound *)obj2)->n)); } static Xen s7_xen_sound_length(s7_scheme *sc, Xen obj) { return(g_framples(obj, Xen_integer_zero, C_int_to_Xen_integer(AT_CURRENT_EDIT_POSITION))); } static Xen s7_xen_sound_copy(s7_scheme *sc, Xen args) { snd_info *sp; s7_pointer obj; obj = s7_car(args); sp = get_sp(obj); if (sp) { io_error_t err; char *name; name = snd_tempnam(); if (mus_header_writable(sp->hdr->type, sp->hdr->sample_type)) err = save_edits_without_display(sp, name, sp->hdr->type, sp->hdr->sample_type, sp->hdr->srate, NULL, AT_CURRENT_EDIT_POSITION); else err = save_edits_without_display(sp, name, MUS_NEXT, MUS_OUT_SAMPLE_TYPE, sp->hdr->srate, NULL, AT_CURRENT_EDIT_POSITION); sp = snd_open_file(name, FILE_READ_WRITE); free(name); if (sp) return(new_xen_sound(sp->index)); if (is_serious_io_error(err)) Xen_error(Xen_make_error_type("IO-error"), Xen_list_2(C_string_to_Xen_string("copy sound: can't save edits, ~A"), C_string_to_Xen_string(io_error_name(err)))); } return(Xen_false); } static Xen s7_xen_sound_fill(s7_scheme *sc, Xen args) { snd_info *sp; s7_pointer obj; obj = s7_car(args); sp = get_sp(obj); if (sp) { mus_float_t valf; chan_info *cp; int i; s7_pointer val; val = s7_cadr(args); valf = Xen_real_to_C_double(val); if (valf == 0.0) { for (i = 0; i < sp->nchans; i++) { cp = sp->chans[i]; scale_channel(cp, 0.0, 0, current_samples(cp), cp->edit_ctr, false); update_graph(cp); } } else { /* this was #if (!HAVE_SCHEME) which makes no sense -- I think it meant (!HAVE_RUN) * but that means (fill! ) fails if optimization is off. */ mus_long_t len = -1, j; mus_float_t *data = NULL; for (i = 0; i < sp->nchans; i++) { cp = sp->chans[i]; if ((!data) || (current_samples(cp) != len)) { len = current_samples(cp); if (data) free(data); data = (mus_float_t *)malloc(len * sizeof(mus_float_t)); for (j = 0; j < len; j++) data[j] = valf; } if (change_samples(0, len, data, cp, "fill! sound", cp->edit_ctr, fabs(valf))) update_graph(cp); } free(data); } } return(Xen_false); } #endif static void init_xen_sound(void) { #if HAVE_SCHEME xen_sound_tag = s7_new_type_x(s7, "", print_xen_sound, free_xen_sound, s7_xen_sound_equalp, NULL, NULL, NULL, s7_xen_sound_length, s7_xen_sound_copy, NULL, s7_xen_sound_fill); #else #if HAVE_RUBY xen_sound_tag = Xen_make_object_type("XenSound", sizeof(xen_sound)); #else xen_sound_tag = Xen_make_object_type("Sound", sizeof(xen_sound)); #endif #endif #if HAVE_FORTH fth_set_object_inspect(xen_sound_tag, print_xen_sound); fth_set_object_dump(xen_sound_tag, g_xen_sound_to_string); fth_set_object_equal(xen_sound_tag, equalp_xen_sound); fth_set_object_free(xen_sound_tag, free_xen_sound); #endif #if HAVE_RUBY rb_define_method(xen_sound_tag, "to_s", Xen_procedure_cast print_xen_sound, 0); rb_define_method(xen_sound_tag, "eql?", Xen_procedure_cast equalp_xen_sound, 1); rb_define_method(xen_sound_tag, "==", Xen_procedure_cast equalp_xen_sound, 1); rb_define_method(xen_sound_tag, "to_str", Xen_procedure_cast g_xen_sound_to_string, 0); #endif } /* -------------------------------------------------------------------------------- */ static Xen g_integer_to_sound(Xen n) { #define H_integer_to_sound "(" S_integer_to_sound " n) returns a sound object corresponding to the given integer" Xen_check_type(Xen_is_integer(n), n, 1, S_integer_to_sound, "an integer"); return(new_xen_sound(Xen_integer_to_C_int(n))); } static Xen g_sound_to_integer(Xen n) { #define H_sound_to_integer "(" S_sound_to_integer " id) returns the integer corresponding to the given sound" Xen_check_type(xen_is_sound(n), n, 1, S_sound_to_integer, "a sound"); return(C_int_to_Xen_integer(xen_sound_to_int(n))); } Xen snd_no_such_sound_error(const char *caller, Xen n) { Xen_error(Xen_make_error_type("no-such-sound"), Xen_list_3(C_string_to_Xen_string("~A: no such sound: ~A"), C_string_to_Xen_string(caller), n)); return(Xen_false); } static Xen g_is_sound(Xen snd) { #define H_is_sound "(" S_is_sound " snd): " PROC_TRUE " if 'snd' (a sound object or an integer) is an active (accessible) sound" if (Xen_is_integer(snd) || xen_is_sound(snd)) { snd_info *sp; sp = get_sp(snd); return(C_bool_to_Xen_boolean((sp) && (snd_ok(sp)) && (sp->inuse == SOUND_NORMAL))); } return(Xen_false); } static Xen g_select_sound(Xen snd) { #define H_select_sound "(" S_select_sound " snd): make sound 'snd' (a sound object or an index) the default sound for \ any editing operations." snd_info *sp; Xen_check_type(Xen_is_integer(snd) || xen_is_sound(snd), snd, 1, S_select_sound, "a sound object or index"); sp = get_sp(snd); if (sp) { select_channel(sp, 0); return(snd); } return(snd_no_such_sound_error(S_select_sound, snd)); } static Xen g_select_channel(Xen chn_n) { #define H_select_channel "(" S_select_channel " :optional (chn 0)): make channel 'chn' of the currently selected sound the default \ channel for editing." snd_info *sp; int chan = 0; Snd_assert_sound(S_select_channel, chn_n, 1); if (Xen_is_integer(chn_n)) chan = Xen_integer_to_C_int(chn_n); sp = any_selected_sound(); if ((sp) && (chan >= 0) && (chan < sp->nchans)) { select_channel(sp, chan); return(chn_n); } return(snd_no_such_channel_error(S_select_channel, C_string_to_Xen_string(S_selected_sound), chn_n)); } static Xen g_find_sound(Xen filename, Xen which) { #define H_find_sound "(" S_find_sound " name :optional (nth 0)): return the sound associated with file 'name'. \ If more than one such sound exists, 'nth' chooses which one to return." snd_info *sp; Xen_check_type(Xen_is_string(filename), filename, 1, S_find_sound, "a string"); Xen_check_type(Xen_is_integer_or_unbound(which), which, 2, S_find_sound, "an integer"); sp = find_sound(Xen_string_to_C_string(filename), (Xen_is_integer(which)) ? Xen_integer_to_C_int(which) : 0); if (sp) return(C_int_to_Xen_sound(sp->index)); return(Xen_false); } typedef enum {SP_SYNC, SP_READ_ONLY, SP_NCHANS, SP_CONTRASTING, SP_EXPANDING, SP_REVERBING, SP_FILTERING, SP_FILTER_ORDER, SP_SRATE, SP_SAMPLE_TYPE, SP_DATA_LOCATION, SP_HEADER_TYPE, SP_SAVE_CONTROLS, SP_RESTORE_CONTROLS, SP_SELECTED_CHANNEL, SP_COMMENT, SP_FILE_NAME, SP_SHORT_FILE_NAME, SP_CLOSE, SP_UPDATE, SP_SHOW_CONTROLS, SP_FILTER_DBING, SP_SPEED_TONES, SP_SPEED_STYLE, SP_RESET_CONTROLS, SP_AMP, SP_CONTRAST, SP_CONTRAST_AMP, SP_EXPAND, SP_EXPAND_LENGTH, SP_EXPAND_RAMP, SP_EXPAND_HOP, SP_SPEED, SP_REVERB_LENGTH, SP_REVERB_FEEDBACK, SP_REVERB_SCALE, SP_REVERB_LOW_PASS, SP_REVERB_DECAY, SP_PROPERTIES, SP_FILTER_COEFFS, SP_DATA_SIZE, SP_FILTER_HZING, SP_EXPAND_JITTER, SP_CONTRAST_BOUNDS, SP_AMP_BOUNDS, SP_SPEED_BOUNDS, SP_EXPAND_BOUNDS, SP_REVERB_LENGTH_BOUNDS, SP_REVERB_SCALE_BOUNDS, SP_FILTER_ENVELOPE } sp_field_t; static Xen sound_get(Xen snd, sp_field_t fld, const char *caller) { snd_info *sp; Xen res = Xen_empty_list; if (Xen_is_true(snd)) { int i; for (i = ss->max_sounds - 1; i >= 0; i--) { sp = ss->sounds[i]; if ((sp) && (sp->inuse == SOUND_NORMAL)) res = Xen_cons(sound_get(C_int_to_Xen_integer(i), fld, caller), res); } return(res); } if (xen_is_player(snd)) { sp = get_player_sound(snd); if (!sp) return(no_such_player_error(caller, snd)); } else { Snd_assert_sound(caller, snd, 1); sp = get_sp(snd); if (!sp) return(snd_no_such_sound_error(caller, snd)); } if ((sp == NULL) || (sp->inuse == SOUND_WRAPPER)) return(snd_no_such_sound_error(caller, snd)); switch (fld) { case SP_SYNC: return(C_int_to_Xen_integer(sp->sync)); break; case SP_READ_ONLY: return(C_bool_to_Xen_boolean(sp->user_read_only == FILE_READ_ONLY)); break; case SP_NCHANS: return(C_int_to_Xen_integer(sp->nchans)); break; case SP_EXPANDING: return(C_bool_to_Xen_boolean(sp->expand_control_on)); break; case SP_CONTRASTING: return(C_bool_to_Xen_boolean(sp->contrast_control_on)); break; case SP_REVERBING: return(C_bool_to_Xen_boolean(sp->reverb_control_on)); break; case SP_FILTERING: return(C_bool_to_Xen_boolean(sp->filter_control_on)); break; case SP_FILTER_DBING: return(C_bool_to_Xen_boolean(sp->filter_control_in_dB)); break; case SP_FILTER_HZING: return(C_bool_to_Xen_boolean(sp->filter_control_in_hz)); break; case SP_FILTER_ORDER: return(C_int_to_Xen_integer(sp->filter_control_order)); break; case SP_SRATE: return(C_int_to_Xen_integer(sp->hdr->srate)); break; case SP_SAMPLE_TYPE: return(C_int_to_Xen_integer(sp->hdr->sample_type)); break; case SP_HEADER_TYPE: return(C_int_to_Xen_integer(sp->hdr->type)); break; case SP_DATA_LOCATION: return(C_llong_to_Xen_llong(sp->hdr->data_location)); break; case SP_DATA_SIZE: return(C_llong_to_Xen_llong(mus_samples_to_bytes(sp->hdr->sample_type, sp->hdr->samples))); break; case SP_SAVE_CONTROLS: if (has_widgets(sp)) save_controls(sp); break; case SP_RESTORE_CONTROLS: if (has_widgets(sp)) restore_controls(sp); break; case SP_RESET_CONTROLS: if (has_widgets(sp)) reset_controls(sp); break; case SP_FILE_NAME: return(C_string_to_Xen_string(sp->filename)); break; case SP_SHORT_FILE_NAME: return(C_string_to_Xen_string(sp->short_filename)); break; case SP_CLOSE: if (!(is_player_sound(sp))) snd_close_file(sp); break; case SP_SHOW_CONTROLS: if (has_widgets(sp)) return(C_bool_to_Xen_boolean(showing_controls(sp))); break; case SP_SPEED_TONES: return(C_int_to_Xen_integer(sp->speed_control_tones)); break; case SP_SPEED_STYLE: return(C_int_to_Xen_integer((int)(sp->speed_control_style))); break; case SP_COMMENT: return(C_string_to_Xen_string(sp->hdr->comment)); break; case SP_AMP: return(C_double_to_Xen_real(sp->amp_control)); break; case SP_CONTRAST: return(C_double_to_Xen_real(sp->contrast_control)); break; case SP_CONTRAST_AMP: return(C_double_to_Xen_real(sp->contrast_control_amp)); break; case SP_EXPAND: return(C_double_to_Xen_real(sp->expand_control)); break; case SP_EXPAND_LENGTH: return(C_double_to_Xen_real(sp->expand_control_length)); break; case SP_EXPAND_RAMP: return(C_double_to_Xen_real(sp->expand_control_ramp)); break; case SP_EXPAND_HOP: return(C_double_to_Xen_real(sp->expand_control_hop)); break; case SP_EXPAND_JITTER: return(C_double_to_Xen_real(sp->expand_control_jitter)); break; case SP_REVERB_LENGTH: return(C_double_to_Xen_real(sp->reverb_control_length)); break; case SP_REVERB_FEEDBACK: return(C_double_to_Xen_real(sp->reverb_control_feedback)); break; case SP_REVERB_SCALE: return(C_double_to_Xen_real(sp->reverb_control_scale)); break; case SP_REVERB_LOW_PASS: return(C_double_to_Xen_real(sp->reverb_control_lowpass)); break; case SP_REVERB_DECAY: return(C_double_to_Xen_real(sp->reverb_control_decay)); break; case SP_AMP_BOUNDS: return(Xen_list_2(C_double_to_Xen_real(sp->amp_control_min), C_double_to_Xen_real(sp->amp_control_max))); break; case SP_CONTRAST_BOUNDS: return(Xen_list_2(C_double_to_Xen_real(sp->contrast_control_min), C_double_to_Xen_real(sp->contrast_control_max))); break; case SP_EXPAND_BOUNDS: return(Xen_list_2(C_double_to_Xen_real(sp->expand_control_min), C_double_to_Xen_real(sp->expand_control_max))); break; case SP_SPEED_BOUNDS: return(Xen_list_2(C_double_to_Xen_real(sp->speed_control_min), C_double_to_Xen_real(sp->speed_control_max))); break; case SP_REVERB_LENGTH_BOUNDS: return(Xen_list_2(C_double_to_Xen_real(sp->reverb_control_length_min), C_double_to_Xen_real(sp->reverb_control_length_max))); break; case SP_REVERB_SCALE_BOUNDS: return(Xen_list_2(C_double_to_Xen_real(sp->reverb_control_scale_min), C_double_to_Xen_real(sp->reverb_control_scale_max))); break; case SP_SELECTED_CHANNEL: if (sp->selected_channel != NO_SELECTION) return(C_int_to_Xen_integer(sp->selected_channel)); return(Xen_false); break; case SP_UPDATE: if (!(is_player_sound(sp))) { mus_sound_forget(sp->filename); /* old record must be out-of-date, so flush it (write date can be troublesome) */ sp = snd_update_within_xen(sp, caller); if (sp) return(C_int_to_Xen_sound(sp->index)); } break; case SP_PROPERTIES: if (!(is_player_sound(sp))) { if (!(Xen_is_vector(sp->properties))) { sp->properties = Xen_make_vector(1, Xen_empty_list); sp->properties_loc = snd_protect(sp->properties); } return(Xen_vector_ref(sp->properties, 0)); } break; case SP_SPEED: #if XEN_HAVE_RATIOS if (sp->speed_control_style == SPEED_CONTROL_AS_RATIO) { if (sp->speed_control_direction == -1) return(Xen_make_ratio(C_int_to_Xen_integer(-sp->speed_control_numerator), C_int_to_Xen_integer(sp->speed_control_denominator))); else return(Xen_make_ratio(C_int_to_Xen_integer(sp->speed_control_numerator), C_int_to_Xen_integer(sp->speed_control_denominator))); } #endif if (sp->speed_control_direction == -1) return(C_double_to_Xen_real((-(sp->speed_control)))); else return(C_double_to_Xen_real(sp->speed_control)); break; case SP_FILTER_COEFFS: if (sp->filter_control_envelope) { int len; mus_float_t *coeffs, *data; len = sp->filter_control_order; coeffs = (mus_float_t *)calloc(len, len * sizeof(mus_float_t)); data = sample_linear_env(sp->filter_control_envelope, len); mus_make_fir_coeffs(len, data, coeffs); free(data); return(xen_make_vct(len, coeffs)); } break; case SP_FILTER_ENVELOPE: if (sp->filter_control_envelope) return(env_to_xen(sp->filter_control_envelope)); break; } return(Xen_false); } static Xen sound_get_global(Xen snd, sp_field_t fld, const char *caller) { if (!Xen_is_bound(snd)) switch (fld) { case SP_FILTER_DBING: return(C_bool_to_Xen_boolean(filter_control_in_dB(ss))); break; case SP_FILTER_HZING: return(C_bool_to_Xen_boolean(filter_control_in_hz(ss))); break; case SP_FILTER_ORDER: return(C_int_to_Xen_integer(filter_control_order(ss))); break; case SP_SHOW_CONTROLS: return(C_bool_to_Xen_boolean(in_show_controls(ss))); break; case SP_SPEED_TONES: return(C_int_to_Xen_integer(speed_control_tones(ss))); break; case SP_SPEED_STYLE: return(C_int_to_Xen_integer((int)(speed_control_style(ss)))); break; case SP_CONTRAST_AMP: return(C_double_to_Xen_real(contrast_control_amp(ss))); break; case SP_EXPAND_LENGTH: return(C_double_to_Xen_real(expand_control_length(ss))); break; case SP_EXPAND_RAMP: return(C_double_to_Xen_real(expand_control_ramp(ss))); break; case SP_EXPAND_HOP: return(C_double_to_Xen_real(expand_control_hop(ss))); break; case SP_EXPAND_JITTER: return(C_double_to_Xen_real(expand_control_jitter(ss))); break; case SP_REVERB_FEEDBACK: return(C_double_to_Xen_real(reverb_control_feedback(ss))); break; case SP_REVERB_LOW_PASS: return(C_double_to_Xen_real(reverb_control_lowpass(ss))); break; case SP_REVERB_DECAY: return(C_double_to_Xen_real(reverb_control_decay(ss))); break; case SP_AMP_BOUNDS: return(Xen_list_2(C_double_to_Xen_real(amp_control_min(ss)), C_double_to_Xen_real(amp_control_max(ss)))); break; case SP_CONTRAST_BOUNDS: return(Xen_list_2(C_double_to_Xen_real(contrast_control_min(ss)), C_double_to_Xen_real(contrast_control_max(ss)))); break; case SP_EXPAND_BOUNDS: return(Xen_list_2(C_double_to_Xen_real(expand_control_min(ss)), C_double_to_Xen_real(expand_control_max(ss)))); break; case SP_SPEED_BOUNDS: return(Xen_list_2(C_double_to_Xen_real(speed_control_min(ss)), C_double_to_Xen_real(speed_control_max(ss)))); break; case SP_REVERB_LENGTH_BOUNDS: return(Xen_list_2(C_double_to_Xen_real(reverb_control_length_min(ss)), C_double_to_Xen_real(reverb_control_length_max(ss)))); break; case SP_REVERB_SCALE_BOUNDS: return(Xen_list_2(C_double_to_Xen_real(reverb_control_scale_min(ss)), C_double_to_Xen_real(reverb_control_scale_max(ss)))); break; default: break; } return(sound_get(snd, fld, caller)); } static Xen sound_set(Xen snd, Xen val, sp_field_t fld, const char *caller) { snd_info *sp; int i, ival; mus_float_t fval; if (Xen_is_true(snd)) { for (i = 0; i < ss->max_sounds; i++) { sp = ss->sounds[i]; if ((sp) && (sp->inuse == SOUND_NORMAL)) sound_set(C_int_to_Xen_integer(i), val, fld, caller); } return(val); } if (xen_is_player(snd)) { sp = get_player_sound(snd); if (!sp) return(no_such_player_error(caller, snd)); } else { Snd_assert_sound(caller, snd, 1); sp = get_sp(snd); if (!sp) return(snd_no_such_sound_error(caller, snd)); } if ((sp == NULL) || (sp->inuse == SOUND_WRAPPER)) return(snd_no_such_sound_error(caller, snd)); switch (fld) { case SP_SYNC: if (Xen_is_integer(val)) syncb(sp, Xen_integer_to_C_int(val)); else syncb(sp, (int)Xen_boolean_to_C_bool(val)); break; case SP_READ_ONLY: if (has_widgets(sp)) { sp->user_read_only = (Xen_boolean_to_C_bool(val) ? FILE_READ_ONLY : FILE_READ_WRITE); if ((sp->user_read_only == FILE_READ_ONLY) || (sp->file_read_only == FILE_READ_ONLY)) show_lock(sp); else hide_lock(sp); } break; case SP_EXPANDING: toggle_expand_button(sp, Xen_boolean_to_C_bool(val)); break; case SP_CONTRASTING: toggle_contrast_button(sp, Xen_boolean_to_C_bool(val)); break; case SP_REVERBING: toggle_reverb_button(sp, Xen_boolean_to_C_bool(val)); break; case SP_FILTERING: toggle_filter_button(sp, Xen_boolean_to_C_bool(val)); break; case SP_FILTER_DBING: set_filter_in_dB(sp, Xen_boolean_to_C_bool(val)); break; case SP_FILTER_HZING: set_filter_in_hz(sp, Xen_boolean_to_C_bool(val)); break; case SP_FILTER_ORDER: set_filter_order(sp, Xen_integer_to_C_int(val)); break; case SP_SHOW_CONTROLS: if (has_widgets(sp)) { if (Xen_boolean_to_C_bool(val)) show_controls(sp); else hide_controls(sp); } break; case SP_SPEED_TONES: sp->speed_control_tones = Xen_integer_to_C_int(val); if (sp->speed_control_tones <= 0) sp->speed_control_tones = DEFAULT_SPEED_CONTROL_TONES; set_speed(sp, sp->speed_control); /* update label etc */ break; case SP_SPEED_STYLE: sp->speed_control_style = (speed_style_t)Xen_integer_to_C_int(val); /* range checked already */ #if XEN_HAVE_RATIOS if (sp->speed_control_style == SPEED_CONTROL_AS_RATIO) snd_rationalize(sp->speed_control, &(sp->speed_control_numerator), &(sp->speed_control_denominator)); #endif set_speed(sp, sp->speed_control); /* update label etc */ break; case SP_SRATE: if (!(is_player_sound(sp))) { if (Xen_is_integer(val)) ival = Xen_integer_to_C_int(val); else { if (Xen_is_double(val)) ival = snd_round(Xen_real_to_C_double(val)); else ival = 44100; } if ((ival <= 0) || (ival > 100000000)) Xen_out_of_range_error(S_set S_srate, 1, val, "impossible srate"); mus_sound_set_srate(sp->filename, ival); sp->hdr->srate = ival; /* if there are pending edits, we certainly don't want to flush them in this case! */ if (!(has_unsaved_edits(sp))) snd_update_within_xen(sp, caller); else { /* reset x axis bounds */ int i; for (i = 0; i < sp->nchans; i++) set_x_axis_x0x1(sp->chans[i], 0.0, (double)(current_samples(sp->chans[i])) / (double)ival); } } break; case SP_NCHANS: if (!(is_player_sound(sp))) { ival = Xen_integer_to_C_int(val); if ((ival <= 0) || (ival > 256)) Xen_out_of_range_error(S_set S_channels, 1, val, "highly unlikely number of channels"); mus_sound_set_chans(sp->filename, ival); sp->hdr->chans = ival; snd_update_within_xen(sp, caller); } break; case SP_SAMPLE_TYPE: if (!(is_player_sound(sp))) { mus_sample_t ival; ival = (mus_sample_t)Xen_integer_to_C_int(val); if (mus_is_sample_type(ival)) { mus_sample_t old_format; old_format = sp->hdr->sample_type; mus_sound_set_sample_type(sp->filename, ival); sp->hdr->sample_type = ival; if (mus_bytes_per_sample(old_format) != mus_bytes_per_sample(ival)) { sp->hdr->samples = (sp->hdr->samples * mus_bytes_per_sample(old_format)) / mus_bytes_per_sample(ival); mus_sound_set_samples(sp->filename, sp->hdr->samples); } /* clear peak amp envs, if any -- is this right? (snd-update below...) */ for (i = 0; i < sp->nchans; i++) { chan_info *cp; cp = sp->chans[i]; if ((cp) && (cp->edits[cp->edit_ctr]->peak_env)) cp->edits[cp->edit_ctr]->peak_env = free_peak_env(cp, cp->edit_ctr); } snd_update_within_xen(sp, caller); } else Xen_out_of_range_error(S_set S_sample_type, 1, val, "unknown sample type"); } break; case SP_HEADER_TYPE: if (!(is_player_sound(sp))) { mus_header_t typ; typ = (mus_header_t)Xen_integer_to_C_int(val); if (mus_is_header_type(typ)) { mus_sound_set_header_type(sp->filename, typ); snd_update_within_xen(sp, caller); } else Xen_out_of_range_error(S_set S_header_type, 1, val, "unknown header type"); } break; case SP_DATA_LOCATION: if (!(is_player_sound(sp))) { mus_long_t loc; loc = Xen_llong_to_C_llong(val); if (loc >= 0) { mus_sound_set_data_location(sp->filename, loc); snd_update_within_xen(sp, caller); } else Xen_out_of_range_error(S_set S_data_location, 1, val, "data location < 0?"); } break; case SP_DATA_SIZE: if (!(is_player_sound(sp))) { mus_long_t size; size = Xen_llong_to_C_llong(val); if (size >= 0) { mus_sound_set_samples(sp->filename, mus_bytes_to_samples(sp->hdr->sample_type, size)); snd_update_within_xen(sp, caller); } else Xen_out_of_range_error(S_set S_data_size, 1, val, "data size < 0?"); } break; case SP_COMMENT: if (!(is_player_sound(sp))) { if (sp->hdr->comment) free(sp->hdr->comment); if (Xen_is_false(val)) sp->hdr->comment = NULL; else sp->hdr->comment = mus_strdup(Xen_string_to_C_string(val)); } break; case SP_PROPERTIES: if (!(is_player_sound(sp))) { if (!(Xen_is_vector(sp->properties))) { sp->properties = Xen_make_vector(1, Xen_empty_list); sp->properties_loc = snd_protect(sp->properties); } Xen_vector_set(sp->properties, 0, val); return(Xen_vector_ref(sp->properties, 0)); } break; case SP_AMP: fval = Xen_real_to_C_double(val); if (fval >= 0.0) set_amp(sp, fval); return(C_double_to_Xen_real(sp->amp_control)); break; case SP_AMP_BOUNDS: sp->amp_control_min = Xen_real_to_C_double(Xen_car(val)); sp->amp_control_max = Xen_real_to_C_double(Xen_cadr(val)); set_amp(sp, mus_fclamp(sp->amp_control_min, sp->amp_control, sp->amp_control_max)); return(val); break; case SP_CONTRAST: set_contrast(sp, Xen_real_to_C_double(val)); return(C_double_to_Xen_real(sp->contrast_control)); break; case SP_CONTRAST_BOUNDS: sp->contrast_control_min = Xen_real_to_C_double(Xen_car(val)); sp->contrast_control_max = Xen_real_to_C_double(Xen_cadr(val)); set_contrast(sp, mus_fclamp(sp->contrast_control_min, sp->contrast_control, sp->contrast_control_max)); return(val); break; case SP_CONTRAST_AMP: sp->contrast_control_amp = Xen_real_to_C_double(val); if (sp->playing) dac_set_contrast_amp(sp, sp->contrast_control_amp); break; case SP_EXPAND: fval = Xen_real_to_C_double(val); if (fval > 0.0) set_expand(sp, fval); return(C_double_to_Xen_real(sp->expand_control)); break; case SP_EXPAND_BOUNDS: sp->expand_control_min = Xen_real_to_C_double(Xen_car(val)); sp->expand_control_max = Xen_real_to_C_double(Xen_cadr(val)); set_expand(sp, mus_fclamp(sp->expand_control_min, sp->expand_control, sp->expand_control_max)); return(val); break; case SP_EXPAND_LENGTH: fval = Xen_real_to_C_double(val); if (fval > 0.0) { sp->expand_control_length = fval; if (sp->playing) dac_set_expand_length(sp, sp->expand_control_length); } else Xen_out_of_range_error(S_set S_expand_control_length, 1, val, "length <= 0.0?"); return(C_double_to_Xen_real(sp->expand_control_length)); break; case SP_EXPAND_RAMP: fval = Xen_real_to_C_double(val); if ((fval >= 0.0) && (fval < 0.5)) { sp->expand_control_ramp = fval; if (sp->playing) dac_set_expand_ramp(sp, fval); } return(C_double_to_Xen_real(sp->expand_control_ramp)); break; case SP_EXPAND_HOP: fval = Xen_real_to_C_double(val); if (fval > 0.0) { sp->expand_control_hop = fval; if (sp->playing) dac_set_expand_hop(sp, fval); } else Xen_out_of_range_error(S_set S_expand_control_hop, 1, val, "hop <= 0.0?"); return(C_double_to_Xen_real(sp->expand_control_hop)); break; case SP_EXPAND_JITTER: fval = mus_fclamp(0.0, Xen_real_to_C_double(val), 100.0); sp->expand_control_jitter = fval; return(C_double_to_Xen_real(sp->expand_control_jitter)); break; case SP_SPEED: #if XEN_HAVE_RATIOS if ((sp->speed_control_style == SPEED_CONTROL_AS_RATIO) && (Xen_is_ratio(val))) { sp->speed_control_numerator = (int)Xen_numerator(val); sp->speed_control_denominator = (int)Xen_denominator(val); fval = (mus_float_t)(sp->speed_control_numerator) / (mus_float_t)(sp->speed_control_denominator); if (sp->speed_control_numerator < 0) { sp->speed_control_direction = -1; sp->speed_control_numerator = -sp->speed_control_numerator; } else sp->speed_control_direction = 1; set_speed(sp, fabs(fval)); sp->speed_control = fabs(fval); /* not redundant */ toggle_direction_arrow(sp, (sp->speed_control_direction == -1)); return(val); } #endif fval = Xen_real_to_C_double(val); if (fval != 0.0) { int direction; if (fval > 0.0) direction = 1; else direction = -1; set_speed(sp, fabs(fval)); #if XEN_HAVE_RATIOS if (sp->speed_control_style == SPEED_CONTROL_AS_RATIO) snd_rationalize(sp->speed_control, &(sp->speed_control_numerator), &(sp->speed_control_denominator)); #endif toggle_direction_arrow(sp, (direction == -1)); if (sp->speed_control_direction == -1) return(C_double_to_Xen_real((-(sp->speed_control)))); else return(C_double_to_Xen_real(sp->speed_control)); } break; case SP_SPEED_BOUNDS: sp->speed_control_min = Xen_real_to_C_double(Xen_car(val)); sp->speed_control_max = Xen_real_to_C_double(Xen_cadr(val)); set_speed(sp, mus_fclamp(sp->speed_control_min, sp->speed_control, sp->speed_control_max)); return(val); break; case SP_REVERB_LENGTH: fval = Xen_real_to_C_double(val); if (fval >= 0.0) set_revlen(sp, fval); return(C_double_to_Xen_real(sp->reverb_control_length)); break; case SP_REVERB_LENGTH_BOUNDS: sp->reverb_control_length_min = Xen_real_to_C_double(Xen_car(val)); sp->reverb_control_length_max = Xen_real_to_C_double(Xen_cadr(val)); set_revlen(sp, mus_fclamp(sp->reverb_control_length_min, sp->reverb_control_length, sp->reverb_control_length_max)); return(val); break; case SP_REVERB_FEEDBACK: sp->reverb_control_feedback = mus_fclamp(0.0, Xen_real_to_C_double(val), 100.0); if (sp->playing) dac_set_reverb_feedback(sp, sp->reverb_control_feedback); break; case SP_REVERB_SCALE: set_revscl(sp, Xen_real_to_C_double(val)); return(C_double_to_Xen_real(sp->reverb_control_scale)); break; case SP_REVERB_SCALE_BOUNDS: sp->reverb_control_scale_min = Xen_real_to_C_double(Xen_car(val)); sp->reverb_control_scale_max = Xen_real_to_C_double(Xen_cadr(val)); set_revscl(sp, mus_fclamp(sp->reverb_control_scale_min, sp->reverb_control_scale, sp->reverb_control_scale_max)); return(val); break; case SP_REVERB_LOW_PASS: sp->reverb_control_lowpass = mus_fclamp(0.0, Xen_real_to_C_double(val), 1.0); if (sp->playing) dac_set_reverb_lowpass(sp, sp->reverb_control_lowpass); break; case SP_REVERB_DECAY: sp->reverb_control_decay = Xen_real_to_C_double(val); break; case SP_FILTER_ENVELOPE: { env *e = NULL; if (sp->filter_control_envelope) sp->filter_control_envelope = free_env(sp->filter_control_envelope); /* set to null in case get_env throws error */ if (!(Xen_is_false(val))) e = get_env(val, caller); /* has some error checks -- val must be list, but we can be #f -- see "get" case above: null env (nogui) -> #f */ if (e) { for (i = 0; i < e->pts; i++) if ((e->data[i * 2 + 1] > 1.0) || (e->data[i * 2 + 1] < 0.0)) { free_env(e); Xen_out_of_range_error(caller, 1, val, "y values < 0.0 or > 1.0"); } sp->filter_control_envelope = e; filter_env_changed(sp, sp->filter_control_envelope); } } break; default: break; } return(val); } static Xen sound_set_global(Xen snd, Xen val, sp_field_t fld, const char *caller) { mus_float_t fval; if (!Xen_is_bound(snd)) switch (fld) { case SP_FILTER_DBING: in_set_filter_control_in_dB(ss, Xen_boolean_to_C_bool(val)); return(sound_set(Xen_true, val, fld, caller)); break; case SP_FILTER_HZING: in_set_filter_control_in_hz(ss, Xen_boolean_to_C_bool(val)); return(sound_set(Xen_true, val, fld, caller)); break; case SP_FILTER_ORDER: Xen_check_type(Xen_is_integer(val), val, 0, caller, "an integer"); if (Xen_integer_to_C_int(val) > 0) in_set_filter_control_order(ss, Xen_integer_to_C_int(val)); return(sound_set(Xen_true, val, fld, caller)); break; case SP_SHOW_CONTROLS: in_set_show_controls(ss, Xen_boolean_to_C_bool(val)); return(sound_set(Xen_true, val, fld, caller)); break; case SP_SPEED_TONES: Xen_check_type(Xen_is_integer(val), val, 0, caller, "an integer"); in_set_speed_control_tones(ss, Xen_integer_to_C_int(val)); return(sound_set(Xen_true, val, fld, caller)); break; case SP_SPEED_STYLE: Xen_check_type(Xen_is_integer(val), val, 0, caller, "an integer"); in_set_speed_control_style(ss, (speed_style_t)Xen_integer_to_C_int(val)); /* range checked already */ return(sound_set(Xen_true, val, fld, caller)); break; case SP_AMP_BOUNDS: in_set_amp_control_min(ss, Xen_real_to_C_double(Xen_car(val))); in_set_amp_control_max(ss, Xen_real_to_C_double(Xen_cadr(val))); reflect_mix_change(ANY_MIX_ID); return(sound_set(Xen_true, val, fld, caller)); break; case SP_CONTRAST_BOUNDS: in_set_contrast_control_min(ss, Xen_real_to_C_double(Xen_car(val))); in_set_contrast_control_max(ss, Xen_real_to_C_double(Xen_cadr(val))); return(sound_set(Xen_true, val, fld, caller)); break; case SP_CONTRAST_AMP: in_set_contrast_control_amp(ss, Xen_real_to_C_double(val)); return(sound_set(Xen_true, val, fld, caller)); break; case SP_EXPAND_BOUNDS: in_set_expand_control_min(ss, Xen_real_to_C_double(Xen_car(val))); in_set_expand_control_max(ss, Xen_real_to_C_double(Xen_cadr(val))); return(sound_set(Xen_true, val, fld, caller)); break; case SP_EXPAND_LENGTH: fval = Xen_real_to_C_double(val); if (fval > 0.0) in_set_expand_control_length(ss, fval); return(sound_set(Xen_true, val, fld, caller)); break; case SP_EXPAND_RAMP: fval = Xen_real_to_C_double(val); if ((fval >= 0.0) && (fval < 0.5)) in_set_expand_control_ramp(ss, fval); return(sound_set(Xen_true, val, fld, caller)); break; case SP_EXPAND_HOP: fval = Xen_real_to_C_double(val); if (fval > 0.0) in_set_expand_control_hop(ss, fval); return(sound_set(Xen_true, val, fld, caller)); break; case SP_EXPAND_JITTER: in_set_expand_control_jitter(ss, Xen_real_to_C_double(val)); return(sound_set(Xen_true, val, fld, caller)); break; case SP_SPEED_BOUNDS: in_set_speed_control_min(ss, Xen_real_to_C_double(Xen_car(val))); in_set_speed_control_max(ss, Xen_real_to_C_double(Xen_cadr(val))); reflect_mix_change(ANY_MIX_ID); return(sound_set(Xen_true, val, fld, caller)); break; case SP_REVERB_LENGTH_BOUNDS: in_set_reverb_control_length_min(ss, Xen_real_to_C_double(Xen_car(val))); in_set_reverb_control_length_max(ss, Xen_real_to_C_double(Xen_cadr(val))); return(sound_set(Xen_true, val, fld, caller)); break; case SP_REVERB_FEEDBACK: in_set_reverb_control_feedback(ss, Xen_real_to_C_double(val)); return(sound_set(Xen_true, val, fld, caller)); break; case SP_REVERB_SCALE_BOUNDS: in_set_reverb_control_scale_min(ss, Xen_real_to_C_double(Xen_car(val))); in_set_reverb_control_scale_max(ss, Xen_real_to_C_double(Xen_cadr(val))); return(sound_set(Xen_true, val, fld, caller)); break; case SP_REVERB_LOW_PASS: in_set_reverb_control_lowpass(ss, Xen_real_to_C_double(val)); return(sound_set(Xen_true, val, fld, caller)); break; case SP_REVERB_DECAY: in_set_reverb_control_decay(ss, Xen_real_to_C_double(val)); return(sound_set(Xen_true, val, fld, caller)); break; default: break; } return(sound_set(snd, val, fld, caller)); } static Xen g_channels(Xen snd) { #define H_channels "(" S_channels " :optional obj): how many channels the object obj has" if (Xen_is_string(snd)) return(g_mus_sound_chans(snd)); /* mus-sound-chans */ if ((mus_is_xen(snd)) || (mus_is_vct(snd)) || (Xen_is_list(snd))) return(g_mus_channels(snd)); /* mus-channels */ if (xen_is_mix(snd)) /* mixes are always 1 chan */ return(C_int_to_Xen_integer(1)); if (xen_is_region(snd)) /* region-chans */ return(g_region_chans(snd)); if (xen_is_selection(snd)) /* selection-chans */ return(g_selection_chans()); if (Xen_is_vector(snd)) /* vector as output in clm */ return(C_int_to_Xen_integer(Xen_vector_rank(snd))); return(sound_get(snd, SP_NCHANS, S_channels)); } static Xen check_number(Xen val, const char *caller) { Xen_check_type(Xen_is_number(val), val, 1, caller, "a number"); return(val); } static Xen check_non_negative_integer(Xen val, const char *caller) { Xen_check_type(Xen_is_integer(val) && (Xen_integer_to_C_int(val) >= 0), val, 1, caller, "a non-negative integer"); return(val); } static Xen g_set_channels(Xen snd, Xen val) { if (!Xen_is_bound(val)) return(sound_set(Xen_undefined, check_non_negative_integer(snd, S_set S_channels), SP_NCHANS, S_set S_channels)); else return(sound_set(snd, check_non_negative_integer(val, S_set S_channels), SP_NCHANS, S_set S_channels)); } static Xen g_srate(Xen snd) { #define H_srate "(" S_srate " :optional obj): obj's srate; obj can be a region, a string (sound file name), a sound, or an integer (sound index)" if (Xen_is_string(snd)) return(g_mus_sound_srate(snd)); if (xen_is_region(snd)) return(g_region_srate(snd)); if (xen_is_selection(snd)) return(g_selection_srate()); return(sound_get(snd, SP_SRATE, S_srate)); } static Xen g_set_srate(Xen snd, Xen val) { if (!Xen_is_bound(val)) return(sound_set(Xen_undefined, check_number(snd, S_set S_srate), SP_SRATE, S_set S_srate)); else return(sound_set(snd, check_number(val, S_set S_srate), SP_SRATE, S_set S_srate)); } static Xen g_data_location(Xen snd) { #define H_data_location "(" S_data_location " :optional snd): snd's data location (bytes)" return(sound_get(snd, SP_DATA_LOCATION, S_data_location)); } static Xen g_set_data_location(Xen snd, Xen val) { if (!Xen_is_bound(val)) return(sound_set(Xen_undefined, check_non_negative_integer(snd, S_set S_data_location), SP_DATA_LOCATION, S_set S_data_location)); else return(sound_set(snd, check_non_negative_integer(val, S_set S_data_location), SP_DATA_LOCATION, S_set S_data_location)); } static Xen g_data_size(Xen snd) { #define H_data_size "(" S_data_size " :optional snd): snd's data size (bytes)" return(sound_get(snd, SP_DATA_SIZE, S_data_size)); } static Xen g_set_data_size(Xen snd, Xen val) { if (!Xen_is_bound(val)) return(sound_set(Xen_undefined, check_non_negative_integer(snd, S_set S_data_size), SP_DATA_SIZE, S_set S_data_size)); else return(sound_set(snd, check_non_negative_integer(val, S_set S_data_size), SP_DATA_SIZE, S_set S_data_size)); } static Xen g_sample_type(Xen snd) { #define H_sample_type "(" S_sample_type " :optional snd): snd's sample type (e.g. " S_mus_bshort ")" return(sound_get(snd, SP_SAMPLE_TYPE, S_sample_type)); } static Xen g_set_sample_type(Xen snd, Xen val) { if (!Xen_is_bound(val)) return(sound_set(Xen_undefined, check_non_negative_integer(snd, S_set S_sample_type), SP_SAMPLE_TYPE, S_set S_sample_type)); else return(sound_set(snd, check_non_negative_integer(val, S_set S_sample_type), SP_SAMPLE_TYPE, S_set S_sample_type)); } static Xen g_header_type(Xen snd) { #define H_header_type "(" S_header_type " :optional snd): snd's header type (e.g. " S_mus_aiff ")" return(sound_get(snd, SP_HEADER_TYPE, S_header_type)); } static Xen g_set_header_type(Xen snd, Xen val) { if (!Xen_is_bound(val)) return(sound_set(Xen_undefined, check_non_negative_integer(snd, S_set S_header_type), SP_HEADER_TYPE, S_set S_header_type)); else return(sound_set(snd, check_non_negative_integer(val, S_set S_header_type), SP_HEADER_TYPE, S_set S_header_type)); } static Xen g_comment(Xen snd) { #define H_comment "(" S_comment " :optional snd): snd's comment (in its header)" return(sound_get(snd, SP_COMMENT, S_comment)); } static Xen g_set_comment(Xen snd, Xen val) { if (!Xen_is_bound(val)) { Xen_check_type(Xen_is_string(snd) || Xen_is_false(snd), snd, 1, S_set S_comment, "a string"); return(sound_set(Xen_undefined, snd, SP_COMMENT, S_set S_comment)); } Xen_check_type(Xen_is_string(val) || Xen_is_false(val), val, 2, S_set S_comment, "a string"); return(sound_set(snd, val, SP_COMMENT, S_set S_comment)); } static Xen g_sync(Xen snd) { #define H_sync "(" S_sync " :optional snd): snd's sync value (0 = no sync). Some editing operations \ are applied to all sounds sharing the sync value of the selected sound. 'snd' can also be a mix or mark object." if (xen_is_mix(snd)) /* mix-sync */ return(g_mix_sync(snd)); if (xen_is_mark(snd)) /* mark-sync */ return(g_mark_sync(snd)); return(sound_get(snd, SP_SYNC, S_sync)); /* sync */ } static Xen g_set_sync(Xen on, Xen snd) { Xen_check_type(Xen_is_integer_or_boolean(on), on, 1, S_set S_sync, "an integer"); if (xen_is_mix(snd)) return(g_set_mix_sync(snd, on)); if (xen_is_mark(snd)) return(g_set_mark_sync(snd, on)); return(sound_set(snd, on, SP_SYNC, S_set S_sync)); } with_two_setter_args(g_set_sync_reversed, g_set_sync) static Xen g_sync_max(void) { #define H_sync_max "(" S_sync_max "): max sound sync value seen so far" return(C_int_to_Xen_integer(ss->sound_sync_max)); } static Xen g_sound_properties(Xen snd) { #define H_sound_properties "(" S_sound_properties " :optional snd): snd's property list" return(sound_get(snd, SP_PROPERTIES, S_sound_properties)); } static Xen g_set_sound_properties(Xen on, Xen snd) { return(sound_set(snd, on, SP_PROPERTIES, S_set S_sound_properties)); } with_two_setter_args(g_set_sound_properties_reversed, g_set_sound_properties) static Xen g_sound_property(Xen key, Xen snd) { #define H_sound_property "(" S_sound_property " key snd) returns the value associated with 'key' in the given sound's\ property list, or " PROC_FALSE "." return(Xen_assoc_ref(key, g_sound_properties(snd))); } #if HAVE_SCHEME static Xen g_set_sound_property(Xen val, Xen key, Xen snd) #else static Xen g_set_sound_property(Xen key, Xen val, Xen snd) #endif { g_set_sound_properties(Xen_assoc_set(key, val, g_sound_properties(snd)), snd); return(val); } with_three_setter_args(g_set_sound_property_reversed, g_set_sound_property) static Xen g_channel_style(Xen snd) { snd_info *sp; if (!Xen_is_bound(snd)) return(C_int_to_Xen_integer(channel_style(ss))); Snd_assert_sound(S_channel_style, snd, 1); sp = get_sp(snd); if (sp == NULL) return(snd_no_such_sound_error(S_channel_style, snd)); return(C_int_to_Xen_integer((int)(sp->channel_style))); } static void update_sound(snd_info *sp) { if (sp) { switch (channel_style(ss)) { case CHANNELS_SEPARATE: separate_sound(sp); break; case CHANNELS_COMBINED: combine_sound(sp); break; case CHANNELS_SUPERIMPOSED: superimpose_sound(sp); break; default: break; } } } void set_channel_style(channel_style_t val) { in_set_channel_style(val); for_each_sound(update_sound); for_each_chan(update_graph); } static Xen g_set_channel_style(Xen style, Xen snd) { snd_info *sp; int in_style; channel_style_t new_style = CHANNELS_SEPARATE; #define H_channel_style "(" S_channel_style " :optional snd): how multichannel sounds lay out the channels. \ The default is " S_channels_combined "; other values are " S_channels_separate " and " S_channels_superimposed ". \ As a global (if the 'snd' arg is omitted), it is the default setting for each sound's 'unite' button." Xen_check_type(Xen_is_integer(style), style, 1, S_set S_channel_style, "an integer"); in_style = Xen_integer_to_C_int(style); if ((in_style < 0) || (in_style >= NUM_CHANNEL_STYLES)) Xen_out_of_range_error(S_set S_channel_style, 1, style, S_channel_style " should be " S_channels_separate ", " S_channels_combined ", or " S_channels_superimposed); new_style = (channel_style_t)in_style; if (!Xen_is_bound(snd)) { set_channel_style(new_style); return(C_int_to_Xen_integer(channel_style(ss))); } Snd_assert_sound(S_set S_channel_style, snd, 2); sp = get_sp(snd); if (sp == NULL) return(snd_no_such_sound_error(S_set S_channel_style, snd)); set_sound_channel_style(sp, new_style); return(C_int_to_Xen_integer((int)(sp->channel_style))); } with_two_setter_args(g_set_channel_style_reversed, g_set_channel_style) static Xen g_read_only(Xen snd) { #define H_read_only "(" S_read_only " :optional snd): whether snd is write-protected" return(sound_get(snd, SP_READ_ONLY, S_read_only)); } static Xen g_set_read_only(Xen on, Xen snd) { Xen_check_type(Xen_is_boolean(on), on, 1, S_set S_read_only, "a boolean"); return(sound_set(snd, on, SP_READ_ONLY, S_set S_read_only)); } with_two_setter_args(g_set_read_only_reversed, g_set_read_only) static Xen g_contrast_control_on(Xen snd) { #define H_contrast_control_on "(" S_contrast_control_on " :optional snd): snd's control panel constrast button state" return(sound_get(snd, SP_CONTRASTING, S_contrast_control_on)); } static Xen g_set_contrast_control_on(Xen on, Xen snd) { Xen_check_type(Xen_is_boolean(on), on, 1, S_set S_contrast_control_on, "a boolean"); return(sound_set(snd, on, SP_CONTRASTING, S_set S_contrast_control_on)); } with_two_setter_args(g_set_contrast_control_on_reversed, g_set_contrast_control_on) static Xen g_expand_control_on(Xen snd) { #define H_expand_control_on "(" S_expand_control_on " :optional snd): snd's control panel expand button state" return(sound_get(snd, SP_EXPANDING, S_expand_control_on)); } static Xen g_set_expand_control_on(Xen on, Xen snd) { Xen_check_type(Xen_is_boolean(on), on, 1, S_set S_expand_control_on, "a boolean"); return(sound_set(snd, on, SP_EXPANDING, S_set S_expand_control_on)); } with_two_setter_args(g_set_expand_control_on_reversed, g_set_expand_control_on) static Xen g_reverb_control_on(Xen snd) { #define H_reverb_control_on "(" S_reverb_control_on " :optional snd): snd's control panel reverb button state" return(sound_get(snd, SP_REVERBING, S_reverb_control_on)); } static Xen g_set_reverb_control_on(Xen on, Xen snd) { Xen_check_type(Xen_is_boolean(on), on, 1, S_set S_reverb_control_on, "a boolean"); return(sound_set(snd, on, SP_REVERBING, S_set S_reverb_control_on)); } with_two_setter_args(g_set_reverb_control_on_reversed, g_set_reverb_control_on) static Xen g_filter_control_on(Xen snd) { #define H_filter_control_on "(" S_filter_control_on " :optional snd): snd's control panel filter button state" return(sound_get(snd, SP_FILTERING, S_filter_control_on)); } static Xen g_set_filter_control_on(Xen on, Xen snd) { Xen_check_type(Xen_is_boolean(on), on, 1, S_set S_filter_control_on, "a boolean"); return(sound_set(snd, on, SP_FILTERING, S_set S_filter_control_on)); } with_two_setter_args(g_set_filter_control_on_reversed, g_set_filter_control_on) static Xen g_filter_control_in_dB(Xen snd) { #define H_filter_control_in_dB "(" S_filter_control_in_dB " :optional snd): " PROC_TRUE " if snd's filter envelope is displayed in dB in control panel" return(sound_get_global(snd, SP_FILTER_DBING, S_filter_control_in_dB)); } static Xen g_set_filter_control_in_dB(Xen on, Xen snd) { Xen_check_type(Xen_is_boolean(on), on, 1, S_set S_filter_control_in_dB, "a boolean"); return(sound_set_global(snd, on, SP_FILTER_DBING, S_set S_filter_control_in_dB)); } with_two_setter_args(g_set_filter_control_in_dB_reversed, g_set_filter_control_in_dB) static Xen g_filter_control_in_hz(Xen snd) { #define H_filter_control_in_hz "(" S_filter_control_in_hz " :optional snd): " PROC_TRUE " if snd's filter envelope x axis should be in hz (control panel filter)" return(sound_get_global(snd, SP_FILTER_HZING, S_filter_control_in_hz)); } static Xen g_set_filter_control_in_hz(Xen on, Xen snd) { Xen_check_type(Xen_is_boolean(on), on, 1, S_set S_filter_control_in_hz, "a boolean"); return(sound_set_global(snd, on, SP_FILTER_HZING, S_set S_filter_control_in_hz)); } with_two_setter_args(g_set_filter_control_in_hz_reversed, g_set_filter_control_in_hz) static Xen g_filter_control_coeffs(Xen snd) { #define H_filter_control_coeffs "(" S_filter_control_coeffs " :optional snd): control panel filter coeffs" return(sound_get(snd, SP_FILTER_COEFFS, S_filter_control_coeffs)); } static Xen g_filter_control_order(Xen snd) { #define H_filter_control_order "(" S_filter_control_order " :optional snd): filter order (in control panel)" return(sound_get_global(snd, SP_FILTER_ORDER, S_filter_control_order)); } static Xen g_set_filter_control_order(Xen on, Xen snd) { Xen_check_type(Xen_is_integer(on), on, 1, S_set S_filter_control_order, "an integer"); return(sound_set_global(snd, on, SP_FILTER_ORDER, S_set S_filter_control_order)); } with_two_setter_args(g_set_filter_control_order_reversed, g_set_filter_control_order) static Xen g_show_controls(Xen snd) { #define H_show_controls "(" S_show_controls " :optional snd): " PROC_TRUE " if snd's control panel is known to be open" return(sound_get_global(snd, SP_SHOW_CONTROLS, S_show_controls)); } static Xen g_set_show_controls(Xen on, Xen snd) { Xen_check_type(Xen_is_boolean(on), on, 1, S_set S_show_controls, "a boolean"); return(sound_set_global(snd, on, SP_SHOW_CONTROLS, S_set S_show_controls)); } with_two_setter_args(g_set_show_controls_reversed, g_set_show_controls) static Xen g_save_controls(Xen snd) { #define H_save_controls "(" S_save_controls " :optional snd): save the control panel settings for subsequent " S_restore_controls return(sound_get(snd, SP_SAVE_CONTROLS, S_save_controls)); } static Xen g_restore_controls(Xen snd) { #define H_restore_controls "(" S_restore_controls " :optional snd): restore the previously saved control panel settings" return(sound_get(snd, SP_RESTORE_CONTROLS, S_restore_controls)); } static Xen g_reset_controls(Xen snd) { #define H_reset_controls "(" S_reset_controls " :optional snd): reset (clear) the control panel settings" return(sound_get(snd, SP_RESET_CONTROLS, S_reset_controls)); } static Xen g_selected_channel(Xen snd) { #define H_selected_channel "(" S_selected_channel " :optional snd): currently selected channel in snd (or " PROC_FALSE " if none)" return(sound_get(snd, SP_SELECTED_CHANNEL, S_selected_channel)); } static Xen g_set_selected_channel(Xen snd, Xen chn_n) { snd_info *sp; if (!Xen_is_bound(chn_n)) return(g_select_channel(snd)); Snd_assert_sound(S_set S_selected_channel, snd, 1); sp = get_sp(snd); if (sp == NULL) return(snd_no_such_sound_error(S_set S_selected_channel, snd)); if (Xen_is_false(chn_n)) sp->selected_channel = NO_SELECTION; else { mus_long_t chan = 0; if (Xen_is_integer(chn_n)) chan = Xen_integer_to_C_int(chn_n); if ((chan >= 0) && (chan < sp->nchans)) { select_channel(sp, (int)chan); return(chn_n); } return(snd_no_such_channel_error(S_set S_selected_channel, snd, chn_n)); } return(Xen_false); } static Xen g_file_name(Xen snd) { #define H_file_name "(" S_file_name " :optional snd): snd's full filename; snd can be a sound, mix, region, string, or generator." if (xen_is_sound(snd)) return(sound_get(snd, SP_FILE_NAME, S_file_name)); if (mus_is_xen(snd)) return(g_mus_file_name(snd)); if (xen_is_mix(snd)) return(C_string_to_Xen_string(mix_file_name(Xen_mix_to_C_int(snd)))); if (xen_is_region(snd)) return(C_string_to_Xen_string(region_file_name(Xen_region_to_C_int(snd)))); #if HAVE_SCHEME if ((s7_is_input_port(s7, snd)) || (s7_is_output_port(s7, snd))) return(C_string_to_Xen_string(s7_port_filename(snd))); #endif if (Xen_is_string(snd)) return(g_mus_expand_filename(snd)); if ((is_sampler(snd)) || (is_mix_sampler(snd))) return(g_sampler_file_name(snd)); return(sound_get(snd, SP_FILE_NAME, S_file_name)); } static Xen g_short_file_name(Xen snd) { #define H_short_file_name "(" S_short_file_name " :optional snd): short form of snd's file name (no directory)" return(sound_get(snd, SP_SHORT_FILE_NAME, S_short_file_name)); } static Xen g_close_sound_1(int snd) { if ((snd >= 0) && (snd < ss->max_sounds)) { snd_info *sp; sp = ss->sounds[snd]; if (snd_ok(sp)) { if (sp->inuse == SOUND_WRAPPER) /* from make_simple_channel_display (variable-graph and the region graphs) */ { /* not sure what to do in this case, but at least we can get it out of the various #t chan loops */ sp->inuse = SOUND_IDLE; ss->sounds[sp->index] = NULL; /* a huge memory leak... */ } else snd_close_file(sp); } } return(Xen_false); } static Xen g_close_sound(Xen snd) { #define H_close_sound "(" S_close_sound " :optional snd): close snd" if (Xen_is_integer(snd)) return(g_close_sound_1(Xen_integer_to_C_int(snd))); if (xen_is_sound(snd)) return(g_close_sound_1(Xen_sound_to_C_int(snd))); return(sound_get(snd, SP_CLOSE, S_close_sound)); } static Xen g_update_sound(Xen snd) { #define H_update_sound "(" S_update_sound " :optional snd): update snd (re-read it from the disk after flushing pending edits)" return(sound_get(snd, SP_UPDATE, S_update_sound)); } static void save_sound_error_handler(const char *msg, void *data) { redirect_snd_error_to(NULL, NULL); redirect_snd_warning_to(NULL, NULL); Xen_error(CANNOT_SAVE, Xen_list_3(C_string_to_Xen_string("~A: ~A"), C_string_to_Xen_string((char *)data), C_string_to_Xen_string(msg))); } static Xen g_save_sound(Xen index) { snd_info *sp; io_error_t err = IO_NO_ERROR; #define H_save_sound "(" S_save_sound " :optional snd): save snd (update the on-disk data to match Snd's current version)" Snd_assert_sound(S_save_sound, index, 1); sp = get_sp(index); if (sp == NULL) return(snd_no_such_sound_error(S_save_sound, index)); if ((sp->user_read_only == FILE_READ_ONLY) || (sp->file_read_only == FILE_READ_ONLY)) { char *msg; Xen str; msg = mus_format("%s (index %d) is write-protected", sp->short_filename, sp->index); str = C_string_to_Xen_string(msg); free(msg); Xen_error(CANNOT_SAVE, Xen_list_2(C_string_to_Xen_string(S_save_sound ": can't save sound, ~A"), str)); return(Xen_false); } redirect_snd_error_to(save_sound_error_handler, (void *)S_save_sound); redirect_snd_warning_to(save_sound_error_handler, (void *)S_save_sound); err = save_edits_without_asking(sp); redirect_snd_error_to(NULL, NULL); redirect_snd_warning_to(NULL, NULL); /* if err and we got here, report it */ if (is_serious_io_error(err)) Xen_error(CANNOT_SAVE, Xen_list_2(C_string_to_Xen_string(S_save_sound ": IO error ~A"), C_string_to_Xen_string(io_error_name(err)))); return(C_int_to_Xen_sound(sp->index)); } static Xen g_revert_sound(Xen index) { #define H_revert_sound "(" S_revert_sound " :optional snd): revert snd to its unedited state (undo all)" snd_info *sp; int i; Snd_assert_sound(S_revert_sound, index, 1); sp = get_sp(index); if (sp == NULL) return(snd_no_such_sound_error(S_revert_sound, index)); for (i = 0; i < sp->nchans; i++) { revert_edits(sp->chans[i]); update_graph(sp->chans[i]); } reflect_file_revert_in_label(sp); return(index); /* was #t */ } static Xen g_selected_sound(void) { #define H_selected_sound "(" S_selected_sound "): currently selected sound (or " PROC_FALSE " if none)" if ((ss->selected_sound != NO_SELECTION) && (snd_ok(ss->sounds[ss->selected_sound]))) return(C_int_to_Xen_sound(ss->selected_sound)); return(Xen_false); } static void open_sound_error_handler(const char *msg, void *data) { redirect_snd_error_to(NULL, NULL); redirect_snd_warning_to(NULL, NULL); Xen_error(Xen_make_error_type("not-a-sound-file"), Xen_list_3(C_string_to_Xen_string("~A: ~A"), C_string_to_Xen_string((char *)data), C_string_to_Xen_string(msg))); } static Xen g_open_sound(Xen filename) { /* return new sound if successful */ #define H_open_sound "(" S_open_sound " filename): \ open filename (as if opened from File:Open menu option), and return the new sound" const char *fname = NULL; snd_info *sp; bool file_exists; Xen_check_type(Xen_is_string(filename), filename, 1, S_open_sound, "a string"); fname = Xen_string_to_C_string(filename); { char *fullname; /* before probing, need to undo all the Unix-isms */ fullname = mus_expand_filename(fname); file_exists = mus_file_probe(fullname); free(fullname); } if (!file_exists) return(snd_no_such_file_error(S_open_sound, filename)); ss->open_requestor = FROM_OPEN_SOUND; redirect_snd_error_to(open_sound_error_handler, (void *)S_open_sound); sp = snd_open_file(fname, FILE_READ_WRITE); /* this will call mus_expand_filename */ redirect_snd_error_to(NULL, NULL); if (sp) return(C_int_to_Xen_sound(sp->index)); /* sp NULL is not an error (open-hook func returned #t) */ return(Xen_false); } static Xen kw_header_type, kw_file, kw_srate, kw_channel, kw_sound, kw_edit_position, kw_channels, kw_size, kw_comment, kw_sample_type; static void init_sound_keywords(void) { kw_header_type = Xen_make_keyword("header-type"); kw_sample_type = Xen_make_keyword("sample-type"); kw_file = Xen_make_keyword("file"); kw_srate = Xen_make_keyword("srate"); kw_channel = Xen_make_keyword("channel"); kw_sound = Xen_make_keyword("sound"); kw_edit_position = Xen_make_keyword("edit-position"); kw_channels = Xen_make_keyword("channels"); kw_size = Xen_make_keyword("size"); kw_comment = Xen_make_keyword("comment"); } static Xen g_open_raw_sound(Xen arglist) { #define H_open_raw_sound "(" S_open_raw_sound " file channels srate sample-type): \ open file assuming the data matches the attributes indicated unless the file actually has a header" const char *file = NULL; char *fullname; snd_info *sp; bool file_exists; int os = 1, oc = 1; mus_sample_t ofr = MUS_BSHORT; Xen args[8]; Xen keys[4]; int orig_arg[4] = {0, 0, 0, 0}; int vals, i, arglist_len; keys[0] = kw_file; keys[1] = kw_channels; keys[2] = kw_srate; keys[3] = kw_sample_type; mus_header_raw_defaults(&os, &oc, &ofr); for (i = 0; i < 8; i++) args[i] = Xen_undefined; arglist_len = Xen_list_length(arglist); if (arglist_len > 8) Xen_out_of_range_error(S_open_raw_sound, 0, arglist, "too many arguments"); for (i = 0; i < arglist_len; i++) args[i] = Xen_list_ref(arglist, i); vals = mus_optkey_unscramble(S_open_raw_sound, 4, keys, args, orig_arg); if (vals > 0) { file = mus_optkey_to_string(keys[0], S_open_raw_sound, orig_arg[0], NULL); oc = mus_optkey_to_int(keys[1], S_open_raw_sound, orig_arg[1], oc); if ((oc < 0) || (oc > 256)) Xen_out_of_range_error(S_open_raw_sound, 2, args[orig_arg[1]], "too many channels requested"); if (!(Xen_is_keyword(keys[1]))) set_fallback_chans(oc); os = mus_optkey_to_int(keys[2], S_open_raw_sound, orig_arg[2], os); if (!(Xen_is_keyword(keys[2]))) set_fallback_srate(os); ofr = (mus_sample_t)mus_optkey_to_int(keys[3], S_open_raw_sound, orig_arg[3], (int)ofr); if (!(Xen_is_keyword(keys[3]))) set_fallback_sample_type(ofr); } if (file == NULL) Xen_error(NO_SUCH_FILE, Xen_list_1(C_string_to_Xen_string(S_open_raw_sound ": no output file?"))); fullname = mus_expand_filename(file); file_exists = mus_file_probe(fullname); free(fullname); if (!file_exists) return(snd_no_such_file_error(S_open_raw_sound, keys[0])); mus_header_set_raw_defaults(os, oc, ofr); ss->reloading_updated_file = -1; ss->open_requestor = FROM_OPEN_RAW_SOUND; sp = snd_open_file(file, FILE_READ_WRITE); set_fallback_chans(0); set_fallback_srate(0); set_fallback_sample_type(MUS_UNKNOWN_SAMPLE); ss->reloading_updated_file = 0; /* snd_open_file -> snd_open_file_1 -> add_sound_window -> make_file_info -> raw_data_dialog_to_file_info */ /* so here if hooked, we'd need to save the current hook, make it return the current args, open, then restore */ if (sp) return(C_int_to_Xen_sound(sp->index)); return(Xen_false); } #if HAVE_SCHEME #define read_only_example "You can make it writable via: (set! (" S_read_only ") #f)" #endif #if HAVE_RUBY #define read_only_example "You can make it writable via: set_read_only(false)" #endif #if HAVE_FORTH #define read_only_example "You can make it writable via: #f set-read-only" #endif static Xen g_view_sound(Xen filename) { #define H_view_sound "(" S_view_sound " filename): open a file in read-only mode. " read_only_example " at any time." const char *fname = NULL; char *fullname; snd_info *sp = NULL; bool file_exists; Xen_check_type(Xen_is_string(filename), filename, 1, S_view_sound, "a string"); fname = Xen_string_to_C_string(filename); fullname = mus_expand_filename(fname); file_exists = mus_file_probe(fullname); free(fullname); if (!file_exists) return(snd_no_such_file_error(S_view_sound, filename)); ss->open_requestor = FROM_VIEW_SOUND; sp = snd_open_file(fname, FILE_READ_ONLY); if (sp) return(C_int_to_Xen_sound(sp->index)); return(Xen_false); } static Xen g_save_sound_as(Xen arglist) { #if HAVE_SCHEME #define save_as_example "(" S_save_sound_as " \"test.snd\" index 44100 " S_mus_bshort " " S_mus_next ")" #endif #if HAVE_RUBY #define save_as_example "save_sound_as(\"test.snd\", index, 44100, Mus_bshort, Mus_next)" #endif #if HAVE_FORTH #define save_as_example "\"test.snd\" index 44100 mus-bshort mus-next save-sound-as" #endif #define H_save_sound_as "(" S_save_sound_as " file sound srate sample-type header-type channel edit-position comment): \ save sound in file using the indicated attributes. If channel is specified, only that channel is saved (extracted). \ Omitted arguments take their value from the sound being saved.\n " save_as_example snd_info *sp; file_info *hdr; mus_header_t ht = MUS_UNKNOWN_HEADER; mus_sample_t df = MUS_UNKNOWN_SAMPLE; int sr = -1, chan = -1, edit_position = AT_CURRENT_EDIT_POSITION; io_error_t io_err = IO_NO_ERROR; char *fname = NULL; const char *file = NULL, *outcom = NULL; Xen args[16]; Xen keys[8]; int orig_arg[8] = {0, 0, 0, 0, 0, 0, 0, 0}; int vals, i, arglist_len; Xen edpos = Xen_undefined, index = Xen_undefined; bool got_edpos = false, free_outcom = false; keys[0] = kw_file; keys[1] = kw_sound; keys[2] = kw_srate; keys[3] = kw_sample_type; keys[4] = kw_header_type; keys[5] = kw_channel; keys[6] = kw_edit_position; keys[7] = kw_comment; for (i = 0; i < 16; i++) args[i] = Xen_undefined; arglist_len = Xen_list_length(arglist); if (arglist_len > 16) Xen_out_of_range_error(S_save_sound_as, 0, arglist, "too many arguments"); for (i = 0; i < arglist_len; i++) args[i] = Xen_list_ref(arglist, i); vals = mus_optkey_unscramble(S_save_sound_as, 8, keys, args, orig_arg); if (vals > 0) { file = mus_optkey_to_string(keys[0], S_save_sound_as, orig_arg[0], NULL); if (!(Xen_is_keyword(keys[1]))) index = keys[1]; ht = (mus_header_t)mus_optkey_to_int(keys[4], S_save_sound_as, orig_arg[4], (int)ht); df = (mus_sample_t)mus_optkey_to_int(keys[3], S_save_sound_as, orig_arg[3], (int)df); sr = mus_optkey_to_int(keys[2], S_save_sound_as, orig_arg[2], sr); if ((sr <= 0) && (!Xen_is_keyword(keys[2]))) Xen_error(CANNOT_SAVE, Xen_list_2(C_string_to_Xen_string(S_save_sound_as ": srate (~A) can't be <= 0"), C_int_to_Xen_integer(sr))); chan = mus_optkey_to_int(keys[5], S_save_sound_as, orig_arg[5], chan); if (!(Xen_is_keyword(keys[6]))) { edpos = keys[6]; if ((Xen_is_integer(edpos)) || (Xen_is_procedure(edpos))) got_edpos = true; } outcom = mus_optkey_to_string(keys[7], S_save_sound_as, orig_arg[7], NULL); } if ((file == NULL) || (is_directory(file))) Xen_error(NO_SUCH_FILE, Xen_list_1(C_string_to_Xen_string(S_save_sound_as ": no output file?"))); Snd_assert_sound(S_save_sound_as, index, 2); sp = get_sp(index); if (sp == NULL) return(snd_no_such_sound_error(S_save_sound_as, index)); hdr = sp->hdr; if (ht == MUS_UNKNOWN_HEADER) ht = hdr->type; if (!(mus_header_writable(ht, MUS_IGNORE_SAMPLE))) Xen_error(CANNOT_SAVE, Xen_list_2(C_string_to_Xen_string(S_save_sound_as ": can't write ~A headers"), C_string_to_Xen_string(mus_header_type_name(ht)))); if (sr == -1) sr = hdr->srate; if (df == MUS_UNKNOWN_SAMPLE) { /* try to find some writable sample_type */ df = hdr->sample_type; if (!mus_header_writable(ht, df)) df = MUS_OUT_SAMPLE_TYPE; if (!mus_header_writable(ht, df)) { switch (df) { case MUS_BFLOAT: df = MUS_LFLOAT; break; case MUS_BDOUBLE: df = MUS_LDOUBLE; break; case MUS_BINT: df = MUS_LINT; break; case MUS_LFLOAT: df = MUS_BFLOAT; break; case MUS_LDOUBLE: df = MUS_BDOUBLE; break; case MUS_LINT: df = MUS_BINT; break; default: break; } if (!mus_header_writable(ht, df)) { int i; for (i = 1; i < MUS_NUM_SAMPLES; i++) /* MUS_UNKNOWN_SAMPLE is 0 */ { df = (mus_sample_t)i; if (mus_header_writable(ht, df)) break; } } } } if (!mus_header_writable(ht, df)) Xen_error(CANNOT_SAVE, Xen_list_3(C_string_to_Xen_string(S_save_sound_as ": can't write ~A data to ~A headers"), C_string_to_Xen_string(mus_sample_type_name(df)), C_string_to_Xen_string(mus_header_type_name(ht)))); if (chan >= sp->nchans) return(snd_no_such_channel_error(S_save_sound_as, index, keys[5])); if (got_edpos) { edit_position = to_c_edit_position(sp->chans[(chan >= 0) ? chan : 0], edpos, S_save_sound_as, 7); for (i = 0; i < sp->nchans; i++) if (edit_position > sp->chans[i]->edit_ctr) Xen_error(NO_SUCH_EDIT, Xen_list_5(C_string_to_Xen_string(S_save_sound_as ": no such edit position: ~A (~S chan ~A has ~A edits)"), C_int_to_Xen_integer(edit_position), C_string_to_Xen_string(sp->short_filename), C_int_to_Xen_integer(i), C_int_to_Xen_integer(sp->chans[i]->edit_ctr))); } fname = mus_expand_filename(file); if (outcom == NULL) { outcom = output_comment(hdr); if (outcom) free_outcom = true; } if (!(run_before_save_as_hook(sp, fname, false, sr, df, ht, outcom))) { if (chan >= 0) io_err = channel_to_file_with_settings(sp->chans[chan], fname, sr, df, ht, outcom, edit_position); else io_err = save_edits_without_display(sp, fname, ht, df, sr, outcom, edit_position); } if (free_outcom) { free((char *)outcom); outcom = NULL; } if (io_err == IO_NO_ERROR) run_after_save_as_hook(sp, fname, false); /* true => from dialog */ else { if (io_err != IO_SAVE_HOOK_CANCELLATION) { Xen errstr; errstr = C_string_to_Xen_string(fname); if (fname) {free(fname); fname = NULL;} Xen_error(CANNOT_SAVE, Xen_list_3(C_string_to_Xen_string(S_save_sound_as ": ~A (~A)"), errstr, C_string_to_Xen_string(snd_open_strerror()))); } } if (fname) free(fname); return(args[orig_arg[0] - 1]); } static Xen g_new_sound(Xen arglist) { #if HAVE_SCHEME #define new_sound_example "(" S_new_sound " \"test.snd\" 1 22050 " S_mus_bshort " " S_mus_next " \"no comment\" 1000)" #endif #if HAVE_RUBY #define new_sound_example "new_sound(\"test.snd\", 1, 22050, Mus_bshort, Mus_next, \"no comment\", 1000)" #endif #if HAVE_FORTH #define new_sound_example "\"test.snd\" 1 22050 mus-bshort mus-next \"no comment\" 1000 new-sound" #endif #define H_new_sound "(" S_new_sound " file channels srate sample-type header-type comment size): \ creates a new sound file with the indicated attributes; if any are omitted, the corresponding default-output variable is used. \ The 'size' argument sets the number of samples (zeros) in the newly created sound. \n " new_sound_example snd_info *sp = NULL; mus_header_t ht; mus_sample_t df; int sr, ch, chan; mus_long_t size, len = 1; char *str = NULL; const char *com = NULL, *file = NULL; Xen args[14]; Xen keys[7]; int orig_arg[7] = {0, 0, 0, 0, 0, 0, 0}; int vals, i, arglist_len; io_error_t io_err; keys[0] = kw_file; keys[1] = kw_channels; keys[2] = kw_srate; keys[3] = kw_sample_type; keys[4] = kw_header_type; keys[5] = kw_comment; keys[6] = kw_size; for (i = 0; i < 14; i++) args[i] = Xen_undefined; arglist_len = Xen_list_length(arglist); if (arglist_len > 14) Xen_out_of_range_error(S_open_raw_sound, 0, arglist, "too many arguments"); for (i = 0; i < arglist_len; i++) args[i] = Xen_list_ref(arglist, i); vals = mus_optkey_unscramble(S_new_sound, 7, keys, args, orig_arg); ht = default_output_header_type(ss); df = default_output_sample_type(ss); sr = default_output_srate(ss); ch = default_output_chans(ss); if (vals > 0) { file = mus_optkey_to_string(keys[0], S_new_sound, orig_arg[0], NULL); /* this can be null if :file is not passed as an arg (use temp name below) */ ht = (mus_header_t)mus_optkey_to_int(keys[4], S_new_sound, orig_arg[4], (int)ht); df = (mus_sample_t)mus_optkey_to_int(keys[3], S_new_sound, orig_arg[3], (int)df); sr = mus_optkey_to_int(keys[2], S_new_sound, orig_arg[2], sr); ch = mus_optkey_to_int(keys[1], S_new_sound, orig_arg[1], ch); com = mus_optkey_to_string(keys[5], S_new_sound, orig_arg[5], NULL); len = mus_optkey_to_mus_long_t(keys[6], S_new_sound, orig_arg[6], len); } if (!(mus_is_header_type(ht))) Xen_out_of_range_error(S_new_sound, orig_arg[4], keys[4], "invalid header type"); if (!(mus_is_sample_type(df))) Xen_out_of_range_error(S_new_sound, orig_arg[3], keys[3], "invalid sample type"); if (!(mus_header_writable(ht, df))) Xen_error(BAD_HEADER, Xen_list_3(C_string_to_Xen_string(S_new_sound ": can't write ~A data to a ~A header"), C_string_to_Xen_string(mus_sample_type_short_name(df)), C_string_to_Xen_string(mus_header_type_name(ht)))); if (sr <= 0) Xen_out_of_range_error(S_new_sound, orig_arg[2], keys[2], "srate <= 0?"); if (ch <= 0) Xen_out_of_range_error(S_new_sound, orig_arg[1], keys[1], "channels <= 0?"); if (len < 0) Xen_out_of_range_error(S_new_sound, orig_arg[6], keys[6], "size < 0?"); if (file) { str = mus_expand_filename(file); if (!str) Xen_out_of_range_error(S_new_sound, orig_arg[0], keys[0], "bad file name?"); } else str = snd_tempnam(); mus_sound_forget(str); io_err = snd_write_header(str, ht, sr, ch, len * ch, df, com, NULL); /* last arg is loop info */ if (io_err != IO_NO_ERROR) { if (str) {free(str); str = NULL;} Xen_error(Xen_make_error_type("IO-error"), Xen_list_3(C_string_to_Xen_string(S_new_sound ": ~S, ~A"), keys[0], C_string_to_Xen_string(snd_io_strerror()))); } chan = snd_reopen_write(str); lseek(chan, mus_header_data_location(), SEEK_SET); size = ch * mus_samples_to_bytes(df, len); if (size > 0) { unsigned char *buf; buf = (unsigned char *)calloc(size, sizeof(unsigned char)); if (write(chan, buf, size) != size) fprintf(stderr, "new-sound %s write error", str); free(buf); } snd_close(chan, str); ss->open_requestor = FROM_NEW_SOUND; sp = sound_is_silence(snd_open_file(str, FILE_READ_WRITE)); if (str) free(str); if (sp) return(C_int_to_Xen_sound(sp->index)); return(Xen_false); } static Xen g_speed_control_style(Xen snd) { #define H_speed_control_style "(" S_speed_control_style " :optional snd): speed control panel interpretation \ choice: " S_speed_control_as_float ", " S_speed_control_as_ratio ", or " S_speed_control_as_semitone "." return(sound_get_global(snd, SP_SPEED_STYLE, S_speed_control_style)); } static Xen g_set_speed_control_style(Xen speed, Xen snd) { int in_spd; speed_style_t spd; Xen_check_type(Xen_is_integer(speed), speed, 1, S_set S_speed_control_style, "an integer"); in_spd = Xen_integer_to_C_int(speed); if (in_spd < 0) Xen_out_of_range_error(S_set S_speed_control_style, 1, speed, "invalid " S_speed_control_style); spd = (speed_style_t)in_spd; if (spd >= NUM_SPEED_CONTROL_STYLES) Xen_out_of_range_error(S_set S_speed_control_style, 1, speed, S_speed_control_style " should be " S_speed_control_as_float ", " S_speed_control_as_ratio ", or " S_speed_control_as_semitone); return(sound_set_global(snd, speed, SP_SPEED_STYLE, S_set S_speed_control_style)); } with_two_setter_args(g_set_speed_control_style_reversed, g_set_speed_control_style) static Xen g_speed_control_tones(Xen snd) { #define H_speed_control_tones "(" S_speed_control_tones " :optional snd): if " S_speed_control_style " is " S_speed_control_as_semitone ", this chooses the octave divisions (12)" return(sound_get_global(snd, SP_SPEED_TONES, S_speed_control_tones)); } static Xen g_set_speed_control_tones(Xen val, Xen snd) { Xen_check_type(Xen_is_number(val), val, 1, S_set S_speed_control_tones, "a number"); return(sound_set_global(snd, val, SP_SPEED_TONES, S_set S_speed_control_tones)); } with_two_setter_args(g_set_speed_control_tones_reversed, g_set_speed_control_tones) static Xen g_amp_control(Xen snd, Xen chn_n) { #define H_amp_control "(" S_amp_control " :optional snd chn): current amp slider setting" if (Xen_is_bound(chn_n)) { chan_info *cp; Snd_assert_channel(S_amp_control, snd, chn_n, 1); cp = get_cp(snd, chn_n, S_amp_control); if (!cp) return(Xen_false); if (cp->amp_control) return(C_double_to_Xen_real(cp->amp_control[0])); } return(sound_get(snd, SP_AMP, S_amp_control)); } static Xen g_set_amp_control(Xen on, Xen snd, Xen chn_n) { Xen_check_type(Xen_is_number(on), on, 1, S_set S_amp_control, "a number"); if (Xen_is_bound(chn_n)) { chan_info *cp; Snd_assert_channel(S_amp_control, snd, chn_n, 2); cp = get_cp(snd, chn_n, S_amp_control); if (!cp) return(Xen_false); if (cp->amp_control == NULL) cp->amp_control = (mus_float_t *)calloc(1, sizeof(mus_float_t)); cp->amp_control[0] = (mus_float_t)Xen_real_to_C_double(on); return(on); } return(sound_set(snd, on, SP_AMP, S_set S_amp_control)); } with_three_setter_args(g_set_amp_control_reversed, g_set_amp_control) static Xen g_amp_control_bounds(Xen snd) { #define H_amp_control_bounds "(" S_amp_control_bounds " :optional snd): current amp slider bounds (default: '(0.0 8.0))" return(sound_get_global(snd, SP_AMP_BOUNDS, S_amp_control_bounds)); } static Xen g_set_amp_control_bounds(Xen on, Xen snd) { Xen_check_type(Xen_is_list(on), on, 1, S_set S_amp_control_bounds, "a list of the new min and max values"); if ((Xen_list_length(on) != 2) || (!(Xen_is_number(Xen_car(on)))) || (!(Xen_is_number(Xen_cadr(on))))) Xen_wrong_type_arg_error(S_set S_amp_control_bounds, 1, on, "a list of 2 numbers"); if (Xen_real_to_C_double(Xen_car(on)) >= Xen_real_to_C_double(Xen_cadr(on))) Xen_out_of_range_error(S_set S_amp_control_bounds, 1, on, "min >= max"); return(sound_set_global(snd, on, SP_AMP_BOUNDS, S_set S_amp_control_bounds)); } with_two_setter_args(g_set_amp_control_bounds_reversed, g_set_amp_control_bounds) static Xen g_contrast_control(Xen snd) { #define H_contrast_control "(" S_contrast_control " :optional snd): current contrast slider setting" return(sound_get(snd, SP_CONTRAST, S_contrast_control)); } static Xen g_set_contrast_control(Xen on, Xen snd) { Xen_check_type(Xen_is_number(on), on, 1, S_set S_contrast_control, "a number"); return(sound_set(snd, on, SP_CONTRAST, S_set S_contrast_control)); } with_two_setter_args(g_set_contrast_control_reversed, g_set_contrast_control) static Xen g_contrast_control_bounds(Xen snd) { #define H_contrast_control_bounds "(" S_contrast_control_bounds " :optional snd): current contrast slider bounds (default: '(0.0 10.0))" return(sound_get_global(snd, SP_CONTRAST_BOUNDS, S_contrast_control_bounds)); } static Xen g_set_contrast_control_bounds(Xen on, Xen snd) { Xen_check_type(Xen_is_list(on), on, 1, S_set S_contrast_control_bounds, "a list of the new min and max values"); if ((Xen_list_length(on) != 2) || (!(Xen_is_number(Xen_car(on)))) || (!(Xen_is_number(Xen_cadr(on))))) Xen_wrong_type_arg_error(S_set S_contrast_control_bounds, 1, on, "a list of 2 numbers"); if (Xen_real_to_C_double(Xen_car(on)) >= Xen_real_to_C_double(Xen_cadr(on))) Xen_out_of_range_error(S_set S_contrast_control_bounds, 1, on, "min >= max"); return(sound_set_global(snd, on, SP_CONTRAST_BOUNDS, S_set S_contrast_control_bounds)); } with_two_setter_args(g_set_contrast_control_bounds_reversed, g_set_contrast_control_bounds) static Xen g_contrast_control_amp(Xen snd) { #define H_contrast_control_amp "(" S_contrast_control_amp " :optional snd): snd's contrast amp\n\ (scaler on data before contrast operation in control panel, 1.0)" return(sound_get_global(snd, SP_CONTRAST_AMP, S_contrast_control_amp)); } static Xen g_set_contrast_control_amp(Xen on, Xen snd) { Xen_check_type(Xen_is_number(on), on, 1, S_set S_contrast_control_amp, "a number"); return(sound_set_global(snd, on, SP_CONTRAST_AMP, S_set S_contrast_control_amp)); } with_two_setter_args(g_set_contrast_control_amp_reversed, g_set_contrast_control_amp) static Xen g_expand_control(Xen snd) { #define H_expand_control "(" S_expand_control " :optional snd): current expand slider setting" return(sound_get(snd, SP_EXPAND, S_expand_control)); } static Xen g_set_expand_control(Xen on, Xen snd) { Xen_check_type(Xen_is_number(on), on, 1, S_set S_expand_control, "a number"); return(sound_set(snd, on, SP_EXPAND, S_set S_expand_control)); } with_two_setter_args(g_set_expand_control_reversed, g_set_expand_control) static Xen g_expand_control_bounds(Xen snd) { #define H_expand_control_bounds "(" S_expand_control_bounds " :optional snd): current expand slider bounds (default: '(0.001 20.0))" return(sound_get_global(snd, SP_EXPAND_BOUNDS, S_expand_control_bounds)); } static Xen g_set_expand_control_bounds(Xen on, Xen snd) { Xen_check_type(Xen_is_list(on), on, 1, S_set S_expand_control_bounds, "a list of the new min and max values"); if ((Xen_list_length(on) != 2) || (!(Xen_is_number(Xen_car(on)))) || (!(Xen_is_number(Xen_cadr(on))))) Xen_wrong_type_arg_error(S_set S_expand_control_bounds, 1, on, "a list of 2 numbers"); if (Xen_real_to_C_double(Xen_car(on)) >= Xen_real_to_C_double(Xen_cadr(on))) Xen_out_of_range_error(S_set S_expand_control_bounds, 1, on, "min >= max"); if (Xen_real_to_C_double(Xen_car(on)) <= 0.0) Xen_out_of_range_error(S_set S_expand_control_bounds, 1, on, "min <= 0.0"); return(sound_set_global(snd, on, SP_EXPAND_BOUNDS, S_set S_expand_control_bounds)); } with_two_setter_args(g_set_expand_control_bounds_reversed, g_set_expand_control_bounds) static Xen g_expand_control_length(Xen snd) { #define H_expand_control_length "(" S_expand_control_length " :optional snd): current expansion segment length in seconds (.15)" return(sound_get_global(snd, SP_EXPAND_LENGTH, S_expand_control_length)); } static Xen g_set_expand_control_length(Xen on, Xen snd) { Xen_check_type(Xen_is_number(on), on, 1, S_set S_expand_control_length, "a number"); return(sound_set_global(snd, on, SP_EXPAND_LENGTH, S_set S_expand_control_length)); } with_two_setter_args(g_set_expand_control_length_reversed, g_set_expand_control_length) static Xen g_expand_control_ramp(Xen snd) { #define H_expand_control_ramp "(" S_expand_control_ramp " :optional snd): current expansion ramp time (.4)" return(sound_get_global(snd, SP_EXPAND_RAMP, S_expand_control_ramp)); } static Xen g_set_expand_control_ramp(Xen on, Xen snd) { Xen_check_type(Xen_is_number(on), on, 1, S_set S_expand_control_ramp, "a number"); return(sound_set_global(snd, on, SP_EXPAND_RAMP, S_set S_expand_control_ramp)); } with_two_setter_args(g_set_expand_control_ramp_reversed, g_set_expand_control_ramp) static Xen g_expand_control_hop(Xen snd) { #define H_expand_control_hop "(" S_expand_control_hop " :optional snd): current expansion output grain spacing in seconds (0.05)" return(sound_get_global(snd, SP_EXPAND_HOP, S_expand_control_hop)); } static Xen g_set_expand_control_hop(Xen on, Xen snd) { Xen_check_type(Xen_is_number(on), on, 1, S_set S_expand_control_hop, "a number"); return(sound_set_global(snd, on, SP_EXPAND_HOP, S_set S_expand_control_hop)); } with_two_setter_args(g_set_expand_control_hop_reversed, g_set_expand_control_hop) static Xen g_expand_control_jitter(Xen snd) { #define H_expand_control_jitter "(" S_expand_control_jitter " :optional snd): current expansion output grain spacing jitter (0.1)" return(sound_get_global(snd, SP_EXPAND_JITTER, S_expand_control_jitter)); } static Xen g_set_expand_control_jitter(Xen on, Xen snd) { Xen_check_type(Xen_is_number(on), on, 1, S_set S_expand_control_jitter, "a number"); return(sound_set_global(snd, on, SP_EXPAND_JITTER, S_set S_expand_control_jitter)); } with_two_setter_args(g_set_expand_control_jitter_reversed, g_set_expand_control_jitter) static Xen g_speed_control(Xen snd) { #define H_speed_control "(" S_speed_control " :optional snd): current speed (srate) slider setting" return(sound_get(snd, SP_SPEED, S_speed_control)); } static Xen g_set_speed_control(Xen on, Xen snd) { Xen_check_type(Xen_is_number(on), on, 1, S_set S_speed_control, "a number"); return(sound_set(snd, on, SP_SPEED, S_set S_speed_control)); } with_two_setter_args(g_set_speed_control_reversed, g_set_speed_control) static Xen g_speed_control_bounds(Xen snd) { #define H_speed_control_bounds "(" S_speed_control_bounds " :optional snd): current speed slider bounds (default: '(0.05 20.0))" return(sound_get_global(snd, SP_SPEED_BOUNDS, S_speed_control_bounds)); } static Xen g_set_speed_control_bounds(Xen on, Xen snd) { Xen_check_type(Xen_is_list(on), on, 1, S_set S_speed_control_bounds, "a list of the new min and max values"); if ((Xen_list_length(on) != 2) || (!(Xen_is_number(Xen_car(on)))) || (!(Xen_is_number(Xen_cadr(on))))) Xen_wrong_type_arg_error(S_set S_speed_control_bounds, 1, on, "a list of 2 numbers"); if (Xen_real_to_C_double(Xen_car(on)) >= Xen_real_to_C_double(Xen_cadr(on))) Xen_out_of_range_error(S_set S_speed_control_bounds, 1, on, "min >= max"); if (Xen_real_to_C_double(Xen_car(on)) <= 0.0) Xen_out_of_range_error(S_set S_speed_control_bounds, 1, on, "min <= 0.0"); return(sound_set_global(snd, on, SP_SPEED_BOUNDS, S_set S_speed_control_bounds)); } with_two_setter_args(g_set_speed_control_bounds_reversed, g_set_speed_control_bounds) static Xen g_reverb_control_length(Xen snd) { #define H_reverb_control_length "(" S_reverb_control_length " :optional snd): reverb decay length scaler" return(sound_get(snd, SP_REVERB_LENGTH, S_reverb_control_length)); } static Xen g_set_reverb_control_length(Xen on, Xen snd) { Xen_check_type(Xen_is_number(on), on, 1, S_set S_reverb_control_length, "a number"); return(sound_set(snd, on, SP_REVERB_LENGTH, S_set S_reverb_control_length)); } with_two_setter_args(g_set_reverb_control_length_reversed, g_set_reverb_control_length) static Xen g_reverb_control_length_bounds(Xen snd) { #define H_reverb_control_length_bounds "(" S_reverb_control_length_bounds " :optional snd): current reverb length slider bounds (default: '(0.0 5.0))" return(sound_get_global(snd, SP_REVERB_LENGTH_BOUNDS, S_reverb_control_length_bounds)); } static Xen g_set_reverb_control_length_bounds(Xen on, Xen snd) { Xen_check_type(Xen_is_list(on), on, 1, S_set S_reverb_control_length_bounds, "a list of the new min and max values"); if ((Xen_list_length(on) != 2) || (!(Xen_is_number(Xen_car(on)))) || (!(Xen_is_number(Xen_cadr(on))))) Xen_wrong_type_arg_error(S_set S_reverb_control_length_bounds, 1, on, "a list of 2 numbers"); if (Xen_real_to_C_double(Xen_car(on)) >= Xen_real_to_C_double(Xen_cadr(on))) Xen_out_of_range_error(S_set S_reverb_control_length_bounds, 1, on, "min >= max"); return(sound_set_global(snd, on, SP_REVERB_LENGTH_BOUNDS, S_set S_reverb_control_length_bounds)); } with_two_setter_args(g_set_reverb_control_length_bounds_reversed, g_set_reverb_control_length_bounds) static Xen g_reverb_control_feedback(Xen snd) { #define H_reverb_control_feedback "(" S_reverb_control_feedback " :optional snd): reverb feedback scaler" return(sound_get_global(snd, SP_REVERB_FEEDBACK, S_reverb_control_feedback)); } static Xen g_set_reverb_control_feedback(Xen on, Xen snd) { Xen_check_type(Xen_is_number(on), on, 1, S_set S_reverb_control_feedback, "a number"); return(sound_set_global(snd, on, SP_REVERB_FEEDBACK, S_set S_reverb_control_feedback)); } with_two_setter_args(g_set_reverb_control_feedback_reversed, g_set_reverb_control_feedback) static Xen g_reverb_control_scale(Xen snd) { #define H_reverb_control_scale "(" S_reverb_control_scale " :optional snd): reverb scaler (the amount of reverb)" return(sound_get(snd, SP_REVERB_SCALE, S_reverb_control_scale)); } static Xen g_set_reverb_control_scale(Xen on, Xen snd) { Xen_check_type(Xen_is_number(on), on, 1, S_set S_reverb_control_scale, "a number"); return(sound_set(snd, on, SP_REVERB_SCALE, S_set S_reverb_control_scale)); } with_two_setter_args(g_set_reverb_control_scale_reversed, g_set_reverb_control_scale) static Xen g_reverb_control_scale_bounds(Xen snd) { #define H_reverb_control_scale_bounds "(" S_reverb_control_scale_bounds " :optional snd): current reverb scale slider bounds (default: '(0.0 4.0))" return(sound_get_global(snd, SP_REVERB_SCALE_BOUNDS, S_reverb_control_scale_bounds)); } static Xen g_set_reverb_control_scale_bounds(Xen on, Xen snd) { Xen_check_type(Xen_is_list(on), on, 1, S_set S_reverb_control_scale_bounds, "a list of the new min and max values"); if ((Xen_list_length(on) != 2) || (!(Xen_is_number(Xen_car(on)))) || (!(Xen_is_number(Xen_cadr(on))))) Xen_wrong_type_arg_error(S_set S_reverb_control_scale_bounds, 1, on, "a list of 2 numbers"); if (Xen_real_to_C_double(Xen_car(on)) >= Xen_real_to_C_double(Xen_cadr(on))) Xen_out_of_range_error(S_set S_reverb_control_scale_bounds, 1, on, "min >= max"); return(sound_set_global(snd, on, SP_REVERB_SCALE_BOUNDS, S_set S_reverb_control_scale_bounds)); } with_two_setter_args(g_set_reverb_control_scale_bounds_reversed, g_set_reverb_control_scale_bounds) static Xen g_reverb_control_lowpass(Xen snd) { #define H_reverb_control_lowpass "(" S_reverb_control_lowpass " :optional snd): reverb lowpass filter coefficient" return(sound_get_global(snd, SP_REVERB_LOW_PASS, S_reverb_control_lowpass)); } static Xen g_set_reverb_control_lowpass(Xen on, Xen snd) { Xen_check_type(Xen_is_number(on), on, 1, S_set S_reverb_control_lowpass, "a number"); return(sound_set_global(snd, on, SP_REVERB_LOW_PASS, S_set S_reverb_control_lowpass)); } with_two_setter_args(g_set_reverb_control_lowpass_reversed, g_set_reverb_control_lowpass) static Xen g_reverb_control_decay(Xen snd) { #define H_reverb_control_decay "(" S_reverb_control_decay " :optional snd): " S_apply_controls " reverb decay time (1.0 seconds)" return(sound_get_global(snd, SP_REVERB_DECAY, S_reverb_control_decay)); } static Xen g_set_reverb_control_decay(Xen val, Xen snd) { Xen_check_type(Xen_is_number(val), val, 1, S_set S_reverb_control_decay, "a number"); return(sound_set_global(snd, val, SP_REVERB_DECAY, S_set S_reverb_control_decay)); } with_two_setter_args(g_set_reverb_control_decay_reversed, g_set_reverb_control_decay) static Xen g_filter_control_envelope(Xen snd) { #define H_filter_control_envelope "(" S_filter_control_envelope " :optional snd): snd's filter envelope (in the control panel)" return(sound_get(snd, SP_FILTER_ENVELOPE, S_filter_control_envelope)); } static Xen g_set_filter_control_envelope(Xen val, Xen snd) { return(sound_set(snd, val, SP_FILTER_ENVELOPE, S_set S_filter_control_envelope)); } with_two_setter_args(g_set_filter_control_envelope_reversed, g_set_filter_control_envelope) static void squelch_printout(const char *msg, void *ignore) { } static void apply_controls_error(const char *msg, void *data) { redirect_snd_warning_to(NULL, NULL); redirect_snd_error_to(NULL, NULL); Xen_error(Xen_make_error_type("cannot-apply-controls"), Xen_list_3(C_string_to_Xen_string("~A: ~A"), C_string_to_Xen_string((char *)data), C_string_to_Xen_string(msg))); } static Xen g_controls_to_channel(Xen settings, Xen beg, Xen dur, Xen snd, Xen chn, Xen origin) { #define H_controls_to_channel "(" S_controls_to_channel " settings :optional beg dur snd chn origin) sets up \ snd's controls to reflect 'settings' (unspecified settings are not changed), then applies the controls as \ an edit of channel 'chn'. The 'settings' argument is a list:\n\ \n\ (list amp speed\n\ (list contrast contrast_amp)\n\ (list expand expand_length expand_ramp expand_hop expand_jitter)\n\ (list reverb_scale reverb_length reverb_feedback reverb_low_pass reverb_decay)\n\ (list filter_order filter_env))\n\ \n\ where each inner list entry can also be " PROC_FALSE "." snd_info *sp; chan_info *cp; Xen_check_type(Xen_is_list(settings), settings, 1, S_controls_to_channel, "a list"); Snd_assert_channel(S_controls_to_channel, snd, chn, 4); Xen_check_type(Xen_is_llong(beg) || Xen_is_false(beg) || !Xen_is_bound(beg), beg, 2, S_controls_to_channel, "an integer"); Xen_check_type(Xen_is_llong(dur) || Xen_is_false(dur) || !Xen_is_bound(dur), dur, 3, S_controls_to_channel, "an integer"); Xen_check_type(Xen_is_string_or_unbound(origin), origin, 7, S_controls_to_channel, "a string"); sp = get_sp(snd); /* control changes make sense, but not 'apply' -- expecting just 'play' if a player */ if (sp) { apply_state *ap; int old_selected_channel; ctrl_state *saved_settings; if (sp->applying) { Xen_error(Xen_make_error_type("cannot-apply-controls"), Xen_list_1(C_string_to_Xen_string(S_controls_to_channel ": already applying controls"))); } if (Xen_is_llong(beg)) apply_beg = Xen_llong_to_C_llong(beg); else apply_beg = 0; if (Xen_is_llong(dur)) apply_dur = Xen_llong_to_C_llong(dur); else apply_dur = 0; cp = get_cp(snd, chn, S_controls_to_channel); old_selected_channel = sp->selected_channel; sp->selected_channel = cp->chan; saved_settings = current_control_settings(sp, NULL); /* now read the 'settings' list for any new settings */ if ((Xen_is_list(settings)) && (!Xen_is_null(settings))) { int i, len, elen; Xen lst; /* settings: (list amp speed (list contrast contrast_amp) (list expand expand_length expand_ramp expand_hop expand_jitter) (list reverb_scale reverb_length reverb_feedback reverb_low_pass reverb_decay) (list filter_order filter_env)) where any (outer) items can be #f */ len = Xen_list_length(settings); for (i = 0, lst = Xen_copy_arg(settings); i < len; i++, lst = Xen_cdr(lst)) { Xen element; element = Xen_car(lst); switch (i) { case 0: if (Xen_is_number(element)) sp->amp_control = Xen_real_to_C_double(element); break; case 1: if (Xen_is_number(element)) sp->speed_control = Xen_real_to_C_double(element); break; case 2: if (Xen_is_list(element)) { elen = Xen_list_length(element); if (elen > 0) sp->contrast_control_on = true; if (elen > 0) sp->contrast_control = Xen_real_to_C_double(Xen_car(element)); if (elen > 1) sp->contrast_control_amp = Xen_real_to_C_double(Xen_cadr(element)); } break; case 3: if (Xen_is_list(element)) { elen = Xen_list_length(element); if (elen > 0) sp->expand_control_on = true; if (elen > 0) sp->expand_control = Xen_real_to_C_double(Xen_car(element)); if (elen > 1) sp->expand_control_length = Xen_real_to_C_double(Xen_cadr(element)); if (elen > 2) sp->expand_control_ramp = Xen_real_to_C_double(Xen_caddr(element)); if (elen > 3) sp->expand_control_hop = Xen_real_to_C_double(Xen_list_ref(element, 3)); if (elen > 4) sp->expand_control_jitter = Xen_real_to_C_double(Xen_list_ref(element, 4)); } break; case 4: if (Xen_is_list(element)) { elen = Xen_list_length(element); if (elen > 0) sp->reverb_control_on = true; if (elen > 0) sp->reverb_control_scale = Xen_real_to_C_double(Xen_car(element)); if (elen > 1) sp->reverb_control_length = Xen_real_to_C_double(Xen_cadr(element)); if (elen > 2) sp->reverb_control_feedback = Xen_real_to_C_double(Xen_caddr(element)); if (elen > 3) sp->reverb_control_lowpass = Xen_real_to_C_double(Xen_list_ref(element, 3)); if (elen > 4) sp->reverb_control_decay = Xen_real_to_C_double(Xen_list_ref(element, 4)); } break; case 5: if (Xen_is_list(element)) { elen = Xen_list_length(element); if (elen > 0) sp->filter_control_on = true; if (elen > 0) sp->filter_control_order = Xen_integer_to_C_int(Xen_car(element)); if (elen > 1) sp->filter_control_envelope = get_env(Xen_cadr(element), S_controls_to_channel); } } } } ss->apply_choice = APPLY_TO_CHANNEL; sp->applying = true; ap = (apply_state *)make_apply_state(sp); #if HAVE_EXTENSION_LANGUAGE #if HAVE_FORTH if (!(Xen_is_number(dur))) ap->origin = mus_format("%s %lld" PROC_SEP PROC_FALSE " %s", Xen_object_to_C_string(settings), apply_beg, S_controls_to_channel); else ap->origin = mus_format("%s " PROC_SEP "%lld" PROC_SEP "%lld %s", Xen_object_to_C_string(settings), apply_beg, apply_dur, S_controls_to_channel); #else { char *temp = NULL; if (!(Xen_is_number(dur))) ap->origin = mus_format("%s" PROC_OPEN "%s%s" PROC_SEP "%lld" PROC_SEP PROC_FALSE, to_proc_name(S_controls_to_channel), PROC_QUOTE, temp = Xen_object_to_C_string(settings), apply_beg); else ap->origin = mus_format("%s" PROC_OPEN "%s%s" PROC_SEP "%lld" PROC_SEP "%lld", to_proc_name(S_controls_to_channel), PROC_QUOTE, temp = Xen_object_to_C_string(settings), apply_beg, apply_dur); #if HAVE_SCHEME if (temp) free(temp); #endif } #endif #endif if (ap) { redirect_snd_error_to(apply_controls_error, (void *)S_controls_to_channel); redirect_snd_warning_to(squelch_printout, NULL); while (apply_controls(ap)) {}; redirect_snd_warning_to(NULL, NULL); /* no-op message pointless within xen */ redirect_snd_error_to(NULL, NULL); } sp->selected_channel = old_selected_channel; restore_control_settings(sp, saved_settings); free_control_settings(saved_settings); } return(settings); } static Xen g_apply_controls(Xen snd, Xen choice, Xen beg, Xen dur) { #define H_apply_controls "(" S_apply_controls " :optional snd (choice 0) (beg 0) (dur len)): \ applies the current control panel state as an edit. \ The 'choices' are 0 (apply to sound), 1 (apply to channel), and 2 (apply to selection). If 'beg' is given, the apply starts there." snd_info *sp; Snd_assert_sound(S_apply_controls, snd, 1); Xen_check_type(Xen_is_integer_or_unbound(choice), choice, 2, S_apply_controls, "an integer"); Xen_check_type(Xen_is_integer_or_unbound(beg), beg, 3, S_apply_controls, "an integer"); Xen_check_type(Xen_is_integer_or_unbound(dur), dur, 4, S_apply_controls, "an integer"); sp = get_sp(snd); /* control changes make sense, but not 'apply' -- expecting just 'play' if a player */ if (sp) { apply_state *ap; snd_apply_t cur_choice = APPLY_TO_SOUND; if (sp->applying) { Xen_error(Xen_make_error_type("cannot-apply-controls"), Xen_list_1(C_string_to_Xen_string(S_apply_controls ": already applying controls"))); } if (Xen_is_llong(beg)) apply_beg = Xen_llong_to_C_llong(beg); else apply_beg = 0; if (Xen_is_llong(dur)) apply_dur = Xen_llong_to_C_llong(dur); else apply_dur = 0; if (Xen_is_integer(choice)) cur_choice = (snd_apply_t)Xen_integer_to_C_int(choice); if (cur_choice > APPLY_TO_SELECTION) Xen_out_of_range_error(S_apply_controls, 2, choice, "choice must be 0=sound, 1=channel, or 2=selection"); ss->apply_choice = cur_choice; sp->applying = true; ap = (apply_state *)make_apply_state(sp); if (ap) { redirect_snd_error_to(apply_controls_error, (void *)S_apply_controls); redirect_snd_warning_to(squelch_printout, NULL); while (apply_controls(ap)) {}; redirect_snd_warning_to(NULL, NULL); /* no-op message pointless within xen */ redirect_snd_error_to(NULL, NULL); } return(snd); } return(snd_no_such_sound_error(S_apply_controls, snd)); } /* ---------------------------------------- peak env files ---------------------------------------- */ static int pack_env_info_type(void) { /* put data description in peak-env info file (in case user opens it from incompatible machine) */ int val = 0; #if MUS_LITTLE_ENDIAN val |= (1 << 8); #endif val |= (1 << 9); /* always float now */ val |= (sizeof(mus_float_t) << 10); return(val); } static char *peak_clean(const char *name) { int len, i; char *peak_name; len = mus_strlen(name); peak_name = (char *)calloc(len + 1, sizeof(char)); for (i = 0; i < len; i++) { if ((name[i] == '\\') || (name[i] == '/')) peak_name[i] = '_'; else peak_name[i] = name[i]; } return(peak_name); } static char *expanded_peak_name(const char *name, int chan) { char *fullname, *peak_file_name, *clean_name; clean_name = peak_clean(name); peak_file_name = mus_format("%s/%s-peaks-%d", peak_env_dir(ss), clean_name, chan); fullname = mus_expand_filename(peak_file_name); if (clean_name) free(clean_name); if (peak_file_name) free(peak_file_name); return(fullname); } void delete_peak_env_info_file(chan_info *cp) { char *fullname; fullname = expanded_peak_name(cp->sound->filename, cp->chan); if (mus_file_probe(fullname)) remove(fullname); if (fullname) free(fullname); } #define PEAK_ENV_VERSION 0 #define PEAK_ENV_INTS 5 #define PEAK_ENV_SAMPS 2 bool write_peak_env_info_file(chan_info *cp) { char *fullname; peak_env_info *ep; int fd; int ibuf[PEAK_ENV_INTS]; mus_float_t mbuf[PEAK_ENV_SAMPS]; ssize_t bytes; if (!(cp->edits)) return(true); ep = cp->edits[0]->peak_env; if (ep == NULL) return(false); fullname = expanded_peak_name(cp->sound->filename, cp->chan); fd = mus_file_create(fullname); if (fd == -1) { if (fullname) free(fullname); return(false); } ibuf[0] = ((ep->completed) ? 1 : 0) | PEAK_ENV_VERSION | (pack_env_info_type() << 16); ibuf[1] = ep->peak_env_size; ibuf[2] = ep->samps_per_bin; ibuf[3] = ep->bin; ibuf[4] = ep->top_bin; mbuf[0] = ep->fmin; mbuf[1] = ep->fmax; bytes = write(fd, (char *)ibuf, (PEAK_ENV_INTS * sizeof(int))); if (bytes != 0) bytes = write(fd, (char *)mbuf, (PEAK_ENV_SAMPS * sizeof(mus_float_t))); if (bytes != 0) bytes = write(fd, (char *)(ep->data_min), (ep->peak_env_size * sizeof(mus_float_t))); if (bytes != 0) bytes = write(fd, (char *)(ep->data_max), (ep->peak_env_size * sizeof(mus_float_t))); if (bytes == 0) fprintf(stderr, "write error while writing peak env file"); snd_close(fd, fullname); if (fullname) free(fullname); return(true); } typedef enum {PEAK_ENV_NO_ERROR, PEAK_ENV_BAD_HEADER, PEAK_ENV_BAD_FORMAT, PEAK_ENV_BAD_SIZE, PEAK_ENV_NO_FILE, PEAK_ENV_NO_DATA} peak_env_error_t; static const char *peak_env_error[6] = { "no error", "peak-env file has a bad header!", "peak-env file is in the wrong sample type; will re-make it.", "peak-env file size is messed up!", "peak-env file has vanished!", "peak-env file is empty!"}; static bool peak_env_info_type_ok(int val) { return((val == 0) || /* for backwards compatibility */ (val == pack_env_info_type())); } static peak_env_info *get_peak_env_info(const char *fullname, peak_env_error_t *error) { peak_env_info *ep; int fd, hdr = 0; ssize_t bytes; int ibuf[PEAK_ENV_INTS]; mus_float_t mbuf[PEAK_ENV_SAMPS]; fd = mus_file_open_read(fullname); if (fd == -1) { (*error) = PEAK_ENV_NO_FILE; return(NULL); } bytes = read(fd, (char *)ibuf, (PEAK_ENV_INTS * sizeof(int))); if (bytes != (PEAK_ENV_INTS * sizeof(int))) { snd_close(fd, fullname); (*error) = PEAK_ENV_NO_DATA; return(NULL); } hdr = ibuf[0]; (*error) = PEAK_ENV_NO_ERROR; if (((hdr & 0xf) != 0) && ((hdr & 0xf) != 1)) (*error) = PEAK_ENV_BAD_HEADER; else { if (!(peak_env_info_type_ok(hdr >> 16))) (*error) = PEAK_ENV_BAD_FORMAT; else { if ((ibuf[1] <= 0) || (!(is_power_of_2(ibuf[1])))) (*error) = PEAK_ENV_BAD_SIZE; else { if ((ibuf[2] <= 0) || (ibuf[4] > ibuf[1])) (*error) = PEAK_ENV_BAD_HEADER; } } } if ((*error) != PEAK_ENV_NO_ERROR) { snd_close(fd, fullname); return(NULL); } ep = (peak_env_info *)calloc(1, sizeof(peak_env_info)); ep->completed = (bool)(hdr & 0xf); /* version number in higher bits */ ep->peak_env_size = ibuf[1]; ep->samps_per_bin = ibuf[2]; ep->bin = ibuf[3]; ep->top_bin = ibuf[4]; if (read(fd, (char *)mbuf, (PEAK_ENV_SAMPS * sizeof(mus_float_t))) == 0) fprintf(stderr, "%s: read error", fullname); ep->fmin = mbuf[0]; ep->fmax = mbuf[1]; ep->data_min = (mus_float_t *)malloc(ep->peak_env_size * sizeof(mus_float_t)); ep->data_max = (mus_float_t *)malloc(ep->peak_env_size * sizeof(mus_float_t)); if (read(fd, (char *)(ep->data_min), (ep->peak_env_size * sizeof(mus_float_t))) == 0) fprintf(stderr, "%s: read error", fullname); if (read(fd, (char *)(ep->data_max), (ep->peak_env_size * sizeof(mus_float_t))) == 0) fprintf(stderr, "%s: read error", fullname); snd_close(fd, fullname); return(ep); } const char *read_peak_env_info_file(chan_info *cp) { peak_env_error_t err = PEAK_ENV_NO_ERROR; char *fullname; if (!(cp->edits)) return(NULL); fullname = expanded_peak_name(cp->sound->filename, cp->chan); if (mus_file_probe(fullname)) { if (file_write_date(fullname) > cp->sound->write_date) cp->edits[0]->peak_env = get_peak_env_info(fullname, &err); else remove(fullname); } if (fullname) free(fullname); if ((cp->edits[0]->peak_env == NULL) && (err != PEAK_ENV_NO_ERROR)) return(peak_env_error[(int)err]); return(NULL); } static Xen g_peak_env_info_to_vcts(peak_env_info *ep, int len) { /* changed 5-Jan-03 to return vcts */ /* in snd-test this causes unfreed memory because the sound-icon-box saves all the data for each icon (vcts unfreed) */ Xen res; int i, lim; vct *vmax, *vmin; mus_float_t *maxdata, *mindata; int loc; if ((len == 0) || (len > ep->peak_env_size)) lim = ep->peak_env_size; else lim = len; if (lim <= 0) return(Xen_empty_list); res = Xen_list_2(xen_make_vct(lim, (mus_float_t *)calloc(lim, sizeof(mus_float_t))), xen_make_vct(lim, (mus_float_t *)calloc(lim, sizeof(mus_float_t)))); loc = snd_protect(res); vmin = xen_to_vct(Xen_car(res)); vmax = xen_to_vct(Xen_cadr(res)); mindata = mus_vct_data(vmin); maxdata = mus_vct_data(vmax); if (ep->peak_env_size == lim) { for (i = 0; i < lim; i++) { mindata[i] = ep->data_min[i]; maxdata[i] = ep->data_max[i]; } } else { mus_float_t cmax, cmin, incr, x; int j; incr = (mus_float_t)(ep->peak_env_size - 1) / (mus_float_t)lim; /* make extra room on left */ cmax = ep->fmin; cmin = ep->fmax; mindata[0] = ep->data_min[0]; maxdata[0] = ep->data_max[0]; for (i = 1, j = 1, x = 0.0; i < ep->peak_env_size; i++) { if (ep->data_max[i] > cmax) cmax = ep->data_max[i]; if (ep->data_min[i] < cmin) cmin = ep->data_min[i]; x += 1.0; if (x >= incr) { mindata[j] = cmin; maxdata[j++] = cmax; x -= incr; cmax = ep->fmin; cmin = ep->fmax; if (j == lim) break; } } } snd_unprotect_at(loc); return(res); } #if (!USE_NO_GUI) typedef struct { chan_info *cp; env_state *es; int len; Xen filename; Xen func; int func_gc_loc; } env_tick; static idle_func_t tick_it(any_pointer_t pet) { bool val; env_state *es; chan_info *cp; env_tick *et = (env_tick *)pet; es = et->es; cp = et->cp; val = tick_peak_env(cp, es); if (val) { es = free_env_state(es); if (Xen_is_procedure(et->func)) { int loc; Xen peak; peak = g_peak_env_info_to_vcts(cp->edits[0]->peak_env, et->len); loc = snd_protect(peak); Xen_call_with_3_args(et->func, et->filename, C_int_to_Xen_integer(cp->chan), peak, "amp env tick"); snd_unprotect_at(et->func_gc_loc); snd_unprotect_at(loc); } completely_free_snd_info(cp->sound); free(et); return(BACKGROUND_QUIT); } return(BACKGROUND_CONTINUE); } #endif static Xen g_channel_amp_envs(Xen filename, Xen chan, Xen pts, Xen peak_func, Xen done_func) { /* return two vectors of size pts containing y vals (min and max) of amp env * if peak_func, use it to get peak_env_info file if needed * if done_func set workproc that calls it when done */ #define H_channel_amp_envs "(" S_channel_amp_envs " :optional file (chan 0) size peak-file-func work-proc-func): \ return two " S_vct "s of length 'size' containing y vals (min and max) of file's channel chan's amp envs. \ 'peak-file-func' is used to get the name of the associated peak_env_info file if the file is very large. \ 'work-proc-func' is called when the amp envs are ready if the amp envs are gathered in the background. \ If 'filename' is a sound index or a sound object, 'size' is interpreted as an edit-position, and the current amp envs are returned." char *fullname = NULL; int len = 0, chn = 0; snd_info *sp = NULL; chan_info *cp = NULL; peak_env_error_t err = PEAK_ENV_NO_ERROR; Xen_check_type(Xen_is_string(filename) || Xen_is_integer(filename) || !Xen_is_bound(filename) || xen_is_sound(filename), filename, 1, S_channel_amp_envs, "a string or sound index"); Xen_check_type(Xen_is_integer_or_unbound(chan), chan, 2, S_channel_amp_envs, "an integer"); Xen_check_type(Xen_is_integer_or_unbound(pts), pts, 3, S_channel_amp_envs, "an integer"); Xen_check_type(((Xen_is_procedure(peak_func)) && (procedure_arity_ok(peak_func, 2))) || (Xen_is_false(peak_func)) || (!Xen_is_bound(peak_func)), peak_func, 4, S_channel_amp_envs, "a procedure of 2 args"); Xen_check_type(((Xen_is_procedure(done_func)) && (procedure_arity_ok(done_func, 3))) || (Xen_is_false(done_func)) || (!Xen_is_bound(done_func)), done_func, 5, S_channel_amp_envs, "a procedure of 3 args"); if (!(Xen_is_string(filename))) { cp = get_cp(filename, chan, S_channel_amp_envs); if (cp) { env_state *es; peak_env_info *ep; int pos; pos = to_c_edit_position(cp, pts, S_channel_amp_envs, 3); /* here "pts" is edpos, not vector size */ if (cp->edits == NULL) return(Xen_empty_list); ep = cp->edits[pos]->peak_env; /* this can be null -- we run the peak envs if necessary */ if ((ep) && (ep->completed)) return(g_peak_env_info_to_vcts(ep, ep->peak_env_size)); /* force amp env to completion */ stop_peak_env(cp); es = make_env_state(cp, cp->edits[pos]->samples); if (es) { while (!(tick_peak_env(cp, es))) {}; es = free_env_state(es); ep = cp->edits[pos]->peak_env; if (ep) return(g_peak_env_info_to_vcts(ep, ep->peak_env_size)); } return(Xen_empty_list); } /* else get_cp threw an error */ } /* filename is a string from here down */ fullname = mus_expand_filename(Xen_string_to_C_string(filename)); if (Xen_is_integer(chan)) chn = Xen_integer_to_C_int(chan); if (chn < 0) Xen_out_of_range_error(S_channel_amp_envs, 2, chan, "must be >= 0"); if (Xen_is_integer(pts)) len = Xen_integer_to_C_int(pts); /* look for sp->filename = fullname then peak then read direct (via make_sound_readable) */ sp = find_sound(fullname, 0); if (sp) { if (chn < sp->nchans) { cp = sp->chans[chn]; if (cp->edits[0]->peak_env) { if (fullname) free(fullname); /* here len can be 0 */ return(g_peak_env_info_to_vcts(cp->edits[0]->peak_env, len)); } } else { if (fullname) free(fullname); Xen_error(NO_SUCH_CHANNEL, Xen_list_3(C_string_to_Xen_string(S_channel_amp_envs ": no such channel (~A in ~S)"), chan, filename)); return(Xen_false); } } if (!(mus_file_probe(fullname))) { if (fullname) free(fullname); Xen_error(NO_SUCH_FILE, Xen_list_2(C_string_to_Xen_string(S_channel_amp_envs ": no such file: ~S"), filename)); return(Xen_false); } if (mus_sound_chans(fullname) < chn) { if (fullname) free(fullname); Xen_error(NO_SUCH_CHANNEL, Xen_list_3(C_string_to_Xen_string(S_channel_amp_envs ": no such channel (~A in ~S)"), chan, filename)); return(Xen_false); } if (Xen_is_procedure(peak_func)) { Xen peak_filename; peak_filename = Xen_call_with_2_args(peak_func, filename, chan, "peak env filename procedure"); if (Xen_is_string(peak_filename)) { char *peakname; peakname = mus_expand_filename(Xen_string_to_C_string(peak_filename)); if (mus_file_probe(peakname)) { peak_env_info *ep; ep = get_peak_env_info(peakname, &err); if (ep) { Xen vcts; vcts = g_peak_env_info_to_vcts(ep, len); ep = free_peak_env_info(ep); if (peakname) free(peakname); if (fullname) free(fullname); return(vcts); } } /* the else side (no such file) could be considered a request to make the peak env file (i.e. not necessarily an error) */ if (peakname) {free(peakname); peakname = NULL;} } } /* now set up to read direct... */ sp = make_sound_readable(fullname, false); if (fullname) free(fullname); fullname = NULL; if ((sp) && (chn < sp->nchans)) { cp = sp->chans[chn]; if (cp) { Xen peak = Xen_false; env_state *es; es = make_env_state(cp, cp->edits[0]->samples); if (es) { #if (!USE_NO_GUI) if (Xen_is_procedure(done_func)) { int id; env_tick *et; if (len <= 0) Xen_out_of_range_error(S_channel_amp_envs, 3, pts, "must be > 0"); et = (env_tick *)calloc(1, sizeof(env_tick)); et->cp = cp; et->es = es; et->func = done_func; et->func_gc_loc = snd_protect(done_func); et->len = len; et->filename = filename; id = (int)BACKGROUND_ADD(tick_it, (any_pointer_t)et); return(C_int_to_Xen_integer(id)); } #endif while (!(tick_peak_env(cp, es))) {}; es = free_env_state(es); peak = g_peak_env_info_to_vcts(cp->edits[0]->peak_env, len); } cp->active = CHANNEL_INACTIVE; completely_free_snd_info(sp); return(peak); } } return(Xen_false); } /* -------------------------------------------------------------------------------- */ static Xen g_start_progress_report(Xen snd, Xen chn) { #define H_start_progress_report "(" S_start_progress_report " :optional snd chn): post the hour-glass icon" chan_info *cp; Snd_assert_channel(S_start_progress_report, snd, chn, 1); cp = get_cp(snd, chn, S_start_progress_report); if (!cp) return(snd_no_such_channel_error(S_start_progress_report, snd, chn)); start_progress_report(cp); return(Xen_true); } static Xen g_finish_progress_report(Xen snd, Xen chn) { #define H_finish_progress_report "(" S_finish_progress_report " :optional snd chn): remove the hour-glass icon" chan_info *cp; Snd_assert_channel(S_finish_progress_report, snd, chn, 1); cp = get_cp(snd, chn, S_finish_progress_report); if (!cp) return(snd_no_such_channel_error(S_finish_progress_report, snd, chn)); finish_progress_report(cp); return(Xen_false); } static Xen g_progress_report(Xen pct, Xen snd, Xen chn) { #define H_progress_report "(" S_progress_report " pct :optional snd chn): \ update an on-going 'progress report' (an animated hour-glass icon) in snd's channel chn using pct to indicate how far along we are" chan_info *cp; Snd_assert_channel(S_progress_report, snd, chn, 2); cp = get_cp(snd, chn, S_progress_report); if (!cp) return(snd_no_such_channel_error(S_progress_report, snd, chn)); Xen_check_type(Xen_is_number(pct), pct, 1, S_progress_report, "a number"); progress_report(cp, Xen_real_to_C_double(pct)); return(pct); } static Xen g_sounds(void) { #define H_sounds "(" S_sounds "): list of active sounds" int i; Xen result; result = Xen_empty_list; for (i = 0; i < ss->max_sounds; i++) { snd_info *sp; sp = ss->sounds[i]; if ((sp) && (sp->inuse == SOUND_NORMAL)) result = Xen_cons(C_int_to_Xen_sound(i), result); } return(result); } static Xen g_status_report(Xen msg, Xen snd) { #define H_status_report "(" S_status_report " message :optional snd) posts message in snd's status area.\ If 'snd' is not a currently open sound, the message is sent to the listener, if it is open. \ If there is no sound or listener, it is sent to stderr." snd_info *sp; const char *message; Xen_check_type(Xen_is_string(msg), msg, 1, S_status_report, "a string"); Snd_assert_sound(S_status_report, snd, 2); message = Xen_string_to_C_string(msg); sp = get_sp(snd); if ((sp == NULL) || (sp->inuse != SOUND_NORMAL)) { if ((message) && (*message)) { if (listener_exists()) append_listener_text(-1, message); else fprintf(stderr, "%s", message); } } else { if ((message) && (*message)) set_status(sp, message, false); else clear_status_area(sp); } return(msg); } Xen_wrap_1_arg(g_is_sound_w, g_is_sound) Xen_wrap_2_optional_args(g_find_sound_w, g_find_sound) Xen_wrap_1_optional_arg(g_channels_w, g_channels) Xen_wrap_2_optional_args(g_set_channels_w, g_set_channels) Xen_wrap_1_optional_arg(g_srate_w, g_srate) Xen_wrap_2_optional_args(g_set_srate_w, g_set_srate) Xen_wrap_1_optional_arg(g_data_location_w, g_data_location) Xen_wrap_2_optional_args(g_set_data_location_w, g_set_data_location) Xen_wrap_1_optional_arg(g_data_size_w, g_data_size) Xen_wrap_2_optional_args(g_set_data_size_w, g_set_data_size) Xen_wrap_1_optional_arg(g_sample_type_w, g_sample_type) Xen_wrap_2_optional_args(g_set_sample_type_w, g_set_sample_type) Xen_wrap_1_optional_arg(g_header_type_w, g_header_type) Xen_wrap_2_optional_args(g_set_header_type_w, g_set_header_type) Xen_wrap_1_optional_arg(g_comment_w, g_comment) Xen_wrap_2_optional_args(g_set_comment_w, g_set_comment) Xen_wrap_1_optional_arg(g_file_name_w, g_file_name) Xen_wrap_1_optional_arg(g_short_file_name_w, g_short_file_name) Xen_wrap_1_optional_arg(g_save_controls_w, g_save_controls) Xen_wrap_1_optional_arg(g_restore_controls_w, g_restore_controls) Xen_wrap_1_optional_arg(g_reset_controls_w, g_reset_controls) Xen_wrap_no_args(g_selected_sound_w, g_selected_sound) Xen_wrap_1_optional_arg(g_selected_channel_w, g_selected_channel) Xen_wrap_2_optional_args(g_set_selected_channel_w, g_set_selected_channel) Xen_wrap_1_arg(g_select_sound_w, g_select_sound) Xen_wrap_1_optional_arg(g_select_channel_w, g_select_channel) Xen_wrap_1_optional_arg(g_close_sound_w, g_close_sound) Xen_wrap_1_optional_arg(g_update_sound_w, g_update_sound) Xen_wrap_1_optional_arg(g_save_sound_w, g_save_sound) Xen_wrap_1_arg(g_open_sound_w, g_open_sound) Xen_wrap_any_args(g_open_raw_sound_w, g_open_raw_sound) Xen_wrap_1_arg(g_view_sound_w, g_view_sound) Xen_wrap_any_args(g_new_sound_w, g_new_sound) Xen_wrap_1_optional_arg(g_revert_sound_w, g_revert_sound) Xen_wrap_any_args(g_save_sound_as_w, g_save_sound_as) Xen_wrap_4_optional_args(g_apply_controls_w, g_apply_controls) Xen_wrap_6_optional_args(g_controls_to_channel_w, g_controls_to_channel) Xen_wrap_1_optional_arg(g_filter_control_envelope_w, g_filter_control_envelope) Xen_wrap_1_optional_arg(g_show_controls_w, g_show_controls) Xen_wrap_1_optional_arg(g_sync_w, g_sync) Xen_wrap_no_args(g_sync_max_w, g_sync_max) Xen_wrap_1_optional_arg(g_sound_properties_w, g_sound_properties) Xen_wrap_2_optional_args(g_sound_property_w, g_sound_property) Xen_wrap_1_optional_arg(g_channel_style_w, g_channel_style) Xen_wrap_1_optional_arg(g_read_only_w, g_read_only) Xen_wrap_1_optional_arg(g_expand_control_on_w, g_expand_control_on) Xen_wrap_1_optional_arg(g_contrast_control_on_w, g_contrast_control_on) Xen_wrap_1_optional_arg(g_reverb_control_on_w, g_reverb_control_on) Xen_wrap_1_optional_arg(g_filter_control_on_w, g_filter_control_on) Xen_wrap_1_optional_arg(g_filter_control_in_dB_w, g_filter_control_in_dB) Xen_wrap_1_optional_arg(g_filter_control_in_hz_w, g_filter_control_in_hz) Xen_wrap_1_optional_arg(g_filter_control_coeffs_w, g_filter_control_coeffs) Xen_wrap_1_optional_arg(g_filter_control_order_w, g_filter_control_order) Xen_wrap_1_optional_arg(g_contrast_control_w, g_contrast_control) Xen_wrap_1_optional_arg(g_contrast_control_bounds_w, g_contrast_control_bounds) Xen_wrap_1_optional_arg(g_contrast_control_amp_w, g_contrast_control_amp) Xen_wrap_1_optional_arg(g_expand_control_w, g_expand_control) Xen_wrap_1_optional_arg(g_expand_control_bounds_w, g_expand_control_bounds) Xen_wrap_1_optional_arg(g_expand_control_length_w, g_expand_control_length) Xen_wrap_1_optional_arg(g_expand_control_ramp_w, g_expand_control_ramp) Xen_wrap_1_optional_arg(g_expand_control_hop_w, g_expand_control_hop) Xen_wrap_1_optional_arg(g_expand_control_jitter_w, g_expand_control_jitter) Xen_wrap_1_optional_arg(g_speed_control_w, g_speed_control) Xen_wrap_1_optional_arg(g_speed_control_bounds_w, g_speed_control_bounds) Xen_wrap_1_optional_arg(g_reverb_control_length_w, g_reverb_control_length) Xen_wrap_1_optional_arg(g_reverb_control_length_bounds_w, g_reverb_control_length_bounds) Xen_wrap_1_optional_arg(g_reverb_control_scale_w, g_reverb_control_scale) Xen_wrap_1_optional_arg(g_reverb_control_scale_bounds_w, g_reverb_control_scale_bounds) Xen_wrap_1_optional_arg(g_reverb_control_feedback_w, g_reverb_control_feedback) Xen_wrap_1_optional_arg(g_reverb_control_lowpass_w, g_reverb_control_lowpass) Xen_wrap_2_optional_args(g_amp_control_w, g_amp_control) Xen_wrap_1_optional_arg(g_amp_control_bounds_w, g_amp_control_bounds) Xen_wrap_1_optional_arg(g_reverb_control_decay_w, g_reverb_control_decay) Xen_wrap_1_optional_arg(g_speed_control_style_w, g_speed_control_style) Xen_wrap_1_optional_arg(g_speed_control_tones_w, g_speed_control_tones) Xen_wrap_5_optional_args(g_channel_amp_envs_w, g_channel_amp_envs); Xen_wrap_2_optional_args(g_start_progress_report_w, g_start_progress_report) Xen_wrap_2_optional_args(g_finish_progress_report_w, g_finish_progress_report) Xen_wrap_3_optional_args(g_progress_report_w, g_progress_report) Xen_wrap_no_args(g_sounds_w, g_sounds) Xen_wrap_1_arg(g_integer_to_sound_w, g_integer_to_sound) Xen_wrap_1_arg(g_sound_to_integer_w, g_sound_to_integer) Xen_wrap_2_optional_args(g_status_report_w, g_status_report) #if HAVE_SCHEME #define g_set_filter_control_envelope_w g_set_filter_control_envelope_reversed #define g_set_read_only_w g_set_read_only_reversed #define g_set_sound_properties_w g_set_sound_properties_reversed #define g_set_sound_property_w g_set_sound_property_reversed #define g_set_sync_w g_set_sync_reversed #define g_set_channel_style_w g_set_channel_style_reversed #define g_set_show_controls_w g_set_show_controls_reversed #define g_set_expand_control_on_w g_set_expand_control_on_reversed #define g_set_contrast_control_on_w g_set_contrast_control_on_reversed #define g_set_reverb_control_on_w g_set_reverb_control_on_reversed #define g_set_filter_control_on_w g_set_filter_control_on_reversed #define g_set_filter_control_in_dB_w g_set_filter_control_in_dB_reversed #define g_set_filter_control_in_hz_w g_set_filter_control_in_hz_reversed #define g_set_filter_control_order_w g_set_filter_control_order_reversed #define g_set_contrast_control_w g_set_contrast_control_reversed #define g_set_contrast_control_bounds_w g_set_contrast_control_bounds_reversed #define g_set_contrast_control_amp_w g_set_contrast_control_amp_reversed #define g_set_expand_control_w g_set_expand_control_reversed #define g_set_expand_control_bounds_w g_set_expand_control_bounds_reversed #define g_set_expand_control_length_w g_set_expand_control_length_reversed #define g_set_expand_control_ramp_w g_set_expand_control_ramp_reversed #define g_set_expand_control_hop_w g_set_expand_control_hop_reversed #define g_set_expand_control_jitter_w g_set_expand_control_jitter_reversed #define g_set_speed_control_w g_set_speed_control_reversed #define g_set_speed_control_bounds_w g_set_speed_control_bounds_reversed #define g_set_reverb_control_length_w g_set_reverb_control_length_reversed #define g_set_reverb_control_length_bounds_w g_set_reverb_control_length_bounds_reversed #define g_set_reverb_control_scale_w g_set_reverb_control_scale_reversed #define g_set_reverb_control_scale_bounds_w g_set_reverb_control_scale_bounds_reversed #define g_set_reverb_control_feedback_w g_set_reverb_control_feedback_reversed #define g_set_reverb_control_lowpass_w g_set_reverb_control_lowpass_reversed #define g_set_amp_control_w g_set_amp_control_reversed #define g_set_amp_control_bounds_w g_set_amp_control_bounds_reversed #define g_set_reverb_control_decay_w g_set_reverb_control_decay_reversed #define g_set_speed_control_style_w g_set_speed_control_style_reversed #define g_set_speed_control_tones_w g_set_speed_control_tones_reversed #else Xen_wrap_2_optional_args(g_set_filter_control_envelope_w, g_set_filter_control_envelope) Xen_wrap_2_optional_args(g_set_read_only_w, g_set_read_only) Xen_wrap_2_optional_args(g_set_sound_properties_w, g_set_sound_properties) Xen_wrap_3_optional_args(g_set_sound_property_w, g_set_sound_property) Xen_wrap_2_optional_args(g_set_sync_w, g_set_sync) Xen_wrap_2_optional_args(g_set_channel_style_w, g_set_channel_style) Xen_wrap_2_optional_args(g_set_show_controls_w, g_set_show_controls) Xen_wrap_2_optional_args(g_set_expand_control_on_w, g_set_expand_control_on) Xen_wrap_2_optional_args(g_set_contrast_control_on_w, g_set_contrast_control_on) Xen_wrap_2_optional_args(g_set_reverb_control_on_w, g_set_reverb_control_on) Xen_wrap_2_optional_args(g_set_filter_control_on_w, g_set_filter_control_on) Xen_wrap_2_optional_args(g_set_filter_control_in_dB_w, g_set_filter_control_in_dB) Xen_wrap_2_optional_args(g_set_filter_control_in_hz_w, g_set_filter_control_in_hz) Xen_wrap_2_optional_args(g_set_filter_control_order_w, g_set_filter_control_order) Xen_wrap_2_optional_args(g_set_contrast_control_w, g_set_contrast_control) Xen_wrap_2_optional_args(g_set_contrast_control_bounds_w, g_set_contrast_control_bounds) Xen_wrap_2_optional_args(g_set_contrast_control_amp_w, g_set_contrast_control_amp) Xen_wrap_2_optional_args(g_set_expand_control_w, g_set_expand_control) Xen_wrap_2_optional_args(g_set_expand_control_bounds_w, g_set_expand_control_bounds) Xen_wrap_2_optional_args(g_set_expand_control_length_w, g_set_expand_control_length) Xen_wrap_2_optional_args(g_set_expand_control_ramp_w, g_set_expand_control_ramp) Xen_wrap_2_optional_args(g_set_expand_control_hop_w, g_set_expand_control_hop) Xen_wrap_2_optional_args(g_set_expand_control_jitter_w, g_set_expand_control_jitter) Xen_wrap_2_optional_args(g_set_speed_control_w, g_set_speed_control) Xen_wrap_2_optional_args(g_set_speed_control_bounds_w, g_set_speed_control_bounds) Xen_wrap_2_optional_args(g_set_reverb_control_length_w, g_set_reverb_control_length) Xen_wrap_2_optional_args(g_set_reverb_control_length_bounds_w, g_set_reverb_control_length_bounds) Xen_wrap_2_optional_args(g_set_reverb_control_scale_w, g_set_reverb_control_scale) Xen_wrap_2_optional_args(g_set_reverb_control_scale_bounds_w, g_set_reverb_control_scale_bounds) Xen_wrap_2_optional_args(g_set_reverb_control_feedback_w, g_set_reverb_control_feedback) Xen_wrap_2_optional_args(g_set_reverb_control_lowpass_w, g_set_reverb_control_lowpass) Xen_wrap_3_optional_args(g_set_amp_control_w, g_set_amp_control) Xen_wrap_2_optional_args(g_set_amp_control_bounds_w, g_set_amp_control_bounds) Xen_wrap_2_optional_args(g_set_reverb_control_decay_w, g_set_reverb_control_decay) Xen_wrap_2_optional_args(g_set_speed_control_style_w, g_set_speed_control_style) Xen_wrap_2_optional_args(g_set_speed_control_tones_w, g_set_speed_control_tones) #endif #if HAVE_SCHEME static s7_pointer acc_channel_style(s7_scheme *sc, s7_pointer args) {return(g_set_channel_style(s7_cadr(args), s7_undefined(sc)));} static s7_pointer acc_filter_control_in_dB(s7_scheme *sc, s7_pointer args) {return(g_set_filter_control_in_dB(s7_cadr(args), s7_undefined(sc)));} static s7_pointer acc_filter_control_in_hz(s7_scheme *sc, s7_pointer args) {return(g_set_filter_control_in_hz(s7_cadr(args), s7_undefined(sc)));} static s7_pointer acc_speed_control_tones(s7_scheme *sc, s7_pointer args) {return(g_set_speed_control_tones(s7_cadr(args), s7_undefined(sc)));} static s7_pointer acc_speed_control_style(s7_scheme *sc, s7_pointer args) {return(g_set_speed_control_style(s7_cadr(args), s7_undefined(sc)));} static s7_pointer acc_expand_control_length(s7_scheme *sc, s7_pointer args) {return(g_set_expand_control_length(s7_cadr(args), s7_undefined(sc)));} static s7_pointer acc_expand_control_ramp(s7_scheme *sc, s7_pointer args) {return(g_set_expand_control_ramp(s7_cadr(args), s7_undefined(sc)));} static s7_pointer acc_expand_control_hop(s7_scheme *sc, s7_pointer args) {return(g_set_expand_control_hop(s7_cadr(args), s7_undefined(sc)));} static s7_pointer acc_expand_control_jitter(s7_scheme *sc, s7_pointer args) {return(g_set_expand_control_jitter(s7_cadr(args), s7_undefined(sc)));} static s7_pointer acc_contrast_control_amp(s7_scheme *sc, s7_pointer args) {return(g_set_contrast_control_amp(s7_cadr(args), s7_undefined(sc)));} static s7_pointer acc_reverb_control_feedback(s7_scheme *sc, s7_pointer args) {return(g_set_reverb_control_feedback(s7_cadr(args), s7_undefined(sc)));} static s7_pointer acc_reverb_control_lowpass(s7_scheme *sc, s7_pointer args) {return(g_set_reverb_control_lowpass(s7_cadr(args), s7_undefined(sc)));} static s7_pointer acc_reverb_control_decay(s7_scheme *sc, s7_pointer args) {return(g_set_reverb_control_decay(s7_cadr(args), s7_undefined(sc)));} static s7_pointer acc_filter_control_order(s7_scheme *sc, s7_pointer args) {return(g_set_filter_control_order(s7_cadr(args), s7_undefined(sc)));} static s7_pointer acc_show_controls(s7_scheme *sc, s7_pointer args) {return(g_set_show_controls(s7_cadr(args), s7_undefined(sc)));} #endif void g_init_snd(void) { #if HAVE_SCHEME s7_pointer pl_iq, pl_iqi, pl_sq, pl_sts, pl_i, pl_osi, pl_bt, pl_bo, pl_bob, pl_io, pl_ioi, pl_po, pl_pop, pl_ro, pl_ror, pl_oi, pl_ioz; { s7_pointer i, t, s, b, o, q, p, r, z; i = s7_make_symbol(s7, "integer?"); s = s7_make_symbol(s7, "string?"); b = s7_make_symbol(s7, "boolean?"); p = s7_make_symbol(s7, "pair?"); r = s7_make_symbol(s7, "real?"); t = s7_t(s7); q = t; /* sigh -- #t is legal here which is idiotic */ o = t; z = s7_make_signature(s7, 2, i, b); pl_i = s7_make_signature(s7, 1, i); pl_iq = s7_make_signature(s7, 2, i, q); pl_iqi = s7_make_signature(s7, 3, i, q, i); pl_sts = s7_make_signature(s7, 3, s, t, s); pl_sq = s7_make_signature(s7, 2, s, q); pl_osi = s7_make_signature(s7, 3, o, s, i); pl_bt = s7_make_signature(s7, 2, b, t); pl_bo = s7_make_signature(s7, 2, b, o); pl_bob = s7_make_signature(s7, 3, b, o, b); pl_io = s7_make_signature(s7, 2, i, o); pl_oi = s7_make_signature(s7, 2, o, i); pl_ioi = s7_make_signature(s7, 3, i, o, i); pl_ioz = s7_make_signature(s7, 3, i, o, z); pl_po = s7_make_signature(s7, 2, p, o); pl_pop = s7_make_signature(s7, 3, p, o, p); pl_ro = s7_make_signature(s7, 2, r, o); pl_ror = s7_make_signature(s7, 3, r, o, r); } #endif init_xen_sound(); init_sound_keywords(); #define H_name_click_hook S_name_click_hook " (snd): called when sound name clicked. \ If it returns " PROC_TRUE ", the usual informative status babbling is squelched." #define H_after_apply_controls_hook S_after_apply_controls_hook " (snd): called when " S_apply_controls " finishes." name_click_hook = Xen_define_hook(S_name_click_hook, "(make-hook 'snd)", 1, H_name_click_hook); after_apply_controls_hook = Xen_define_hook(S_after_apply_controls_hook, "(make-hook 'snd)", 1, H_after_apply_controls_hook); #define H_channels_separate "The value for " S_channel_style " that causes channel graphs to occupy separate panes" #define H_channels_combined "The value for " S_channel_style " that causes channel graphs to occupy one pane (set by the 'unite' button)" #define H_channels_superimposed "The value for " S_channel_style " that causes channel graphs to occupy one pane and one axis" Xen_define_constant(S_channels_separate, CHANNELS_SEPARATE, H_channels_separate); Xen_define_constant(S_channels_combined, CHANNELS_COMBINED, H_channels_combined); Xen_define_constant(S_channels_superimposed, CHANNELS_SUPERIMPOSED, H_channels_superimposed); Xen_define_typed_procedure(S_status_report, g_status_report_w, 1, 1, 0, H_status_report, pl_sts); Xen_define_typed_dilambda(S_channels, g_channels_w, H_channels, S_set S_channels, g_set_channels_w, 0, 1, 1, 1, pl_iq, pl_iqi); Xen_define_typed_dilambda(S_chans, g_channels_w, H_channels, S_set S_chans, g_set_channels_w, 0, 1, 1, 1, pl_iq, pl_iqi); Xen_define_typed_dilambda(S_srate, g_srate_w, H_srate, S_set S_srate, g_set_srate_w, 0, 1, 1, 1, pl_iq, pl_iqi); Xen_define_typed_dilambda(S_data_location, g_data_location_w, H_data_location, S_set S_data_location, g_set_data_location_w, 0, 1, 1, 1, pl_iq, pl_iqi); Xen_define_typed_dilambda(S_data_size, g_data_size_w, H_data_size, S_set S_data_size, g_set_data_size_w, 0, 1, 1, 1, pl_iq, pl_iqi); Xen_define_typed_dilambda(S_sample_type, g_sample_type_w, H_sample_type, S_set S_sample_type, g_set_sample_type_w, 0, 1, 1, 1, pl_iq, pl_iqi); Xen_define_typed_dilambda(S_header_type, g_header_type_w, H_header_type, S_set S_header_type, g_set_header_type_w, 0, 1, 1, 1, pl_iq, pl_iqi); Xen_define_typed_dilambda(S_comment, g_comment_w, H_comment, S_set S_comment, g_set_comment_w, 0, 1, 1, 1, NULL, NULL); Xen_define_typed_procedure(S_is_sound, g_is_sound_w, 1, 0, 0, H_is_sound, pl_bt); Xen_define_typed_procedure(S_find_sound, g_find_sound_w, 1, 1, 0, H_find_sound, pl_osi); Xen_define_typed_procedure(S_file_name, g_file_name_w, 0, 1, 0, H_file_name, pl_sq); Xen_define_typed_procedure(S_short_file_name, g_short_file_name_w, 0, 1, 0, H_short_file_name, pl_sq); Xen_define_typed_procedure(S_save_controls, g_save_controls_w, 0, 1, 0, H_save_controls, pl_bt); Xen_define_typed_procedure(S_restore_controls, g_restore_controls_w, 0, 1, 0, H_restore_controls, pl_bt); Xen_define_typed_procedure(S_reset_controls, g_reset_controls_w, 0, 1, 0, H_reset_controls, pl_bt); Xen_define_safe_procedure(S_select_sound, g_select_sound_w, 1, 0, 0, H_select_sound); Xen_define_safe_procedure(S_select_channel, g_select_channel_w, 0, 1, 0, H_select_channel); Xen_define_dilambda(S_selected_sound, g_selected_sound_w, H_selected_sound, S_set S_selected_sound, g_select_sound_w, 0, 0, 1, 0); Xen_define_dilambda(S_selected_channel, g_selected_channel_w, H_selected_channel, S_set S_selected_channel, g_set_selected_channel_w, 0, 1, 0, 2); Xen_define_safe_procedure(S_start_progress_report, g_start_progress_report_w, 0, 2, 0, H_start_progress_report); Xen_define_safe_procedure(S_finish_progress_report, g_finish_progress_report_w, 0, 2, 0, H_finish_progress_report); Xen_define_safe_procedure(S_progress_report, g_progress_report_w, 1, 2, 0, H_progress_report); Xen_define_procedure(S_close_sound, g_close_sound_w, 0, 1, 0, H_close_sound); Xen_define_procedure(S_update_sound, g_update_sound_w, 0, 1, 0, H_update_sound); Xen_define_procedure(S_save_sound, g_save_sound_w, 0, 1, 0, H_save_sound); Xen_define_procedure(S_open_sound, g_open_sound_w, 1, 0, 0, H_open_sound); /* not "safe" procedure! */ Xen_define_procedure(S_open_raw_sound, g_open_raw_sound_w, 0, 0, 1, H_open_raw_sound); Xen_define_procedure(S_view_sound, g_view_sound_w, 1, 0, 0, H_view_sound); Xen_define_procedure(S_new_sound, g_new_sound_w, 0, 0, 1, H_new_sound); Xen_define_procedure(S_revert_sound, g_revert_sound_w, 0, 1, 0, H_revert_sound); Xen_define_procedure(S_save_sound_as, g_save_sound_as_w, 0, 0, 1, H_save_sound_as); Xen_define_procedure(S_apply_controls, g_apply_controls_w, 0, 4, 0, H_apply_controls); Xen_define_procedure(S_controls_to_channel, g_controls_to_channel_w, 0, 6, 0, H_controls_to_channel); Xen_define_typed_procedure(S_sync_max, g_sync_max_w, 0, 0, 0, H_sync_max, pl_i); Xen_define_safe_procedure(S_filter_control_coeffs, g_filter_control_coeffs_w, 0, 1, 0, H_filter_control_coeffs); Xen_define_dilambda(S_filter_control_envelope, g_filter_control_envelope_w, H_filter_control_envelope, S_set S_filter_control_envelope, g_set_filter_control_envelope_w, 0, 1, 1, 1); Xen_define_dilambda(S_sound_properties, g_sound_properties_w, H_sound_properties, S_set S_sound_properties, g_set_sound_properties_w, 0, 1, 1, 1); Xen_define_dilambda(S_sound_property, g_sound_property_w, H_sound_property, S_set S_sound_property, g_set_sound_property_w, 1, 1, 2, 1); Xen_define_typed_dilambda(S_show_controls, g_show_controls_w, H_show_controls, S_set S_show_controls, g_set_show_controls_w, 0, 1, 1, 1, pl_bo, pl_bob); Xen_define_typed_dilambda(S_sync, g_sync_w, H_sync, S_set S_sync, g_set_sync_w, 0, 1, 1, 1, pl_io, pl_ioz); Xen_define_typed_dilambda(S_channel_style, g_channel_style_w, H_channel_style, S_set S_channel_style, g_set_channel_style_w, 0, 1, 1, 1, pl_io, pl_ioi); Xen_define_typed_dilambda(S_read_only, g_read_only_w, H_read_only, S_set S_read_only, g_set_read_only_w, 0, 1, 1, 1, pl_bo, pl_bob); Xen_define_typed_dilambda(S_expand_control_on, g_expand_control_on_w, H_expand_control_on, S_set S_expand_control_on, g_set_expand_control_on_w, 0, 1, 1, 1, pl_bo, pl_bob); Xen_define_typed_dilambda(S_contrast_control_on, g_contrast_control_on_w, H_contrast_control_on, S_set S_contrast_control_on, g_set_contrast_control_on_w, 0, 1, 1, 1, pl_bo, pl_bob); Xen_define_typed_dilambda(S_reverb_control_on, g_reverb_control_on_w, H_reverb_control_on, S_set S_reverb_control_on, g_set_reverb_control_on_w, 0, 1, 1, 1, pl_bo, pl_bob); Xen_define_typed_dilambda(S_filter_control_on, g_filter_control_on_w, H_filter_control_on, S_set S_filter_control_on, g_set_filter_control_on_w, 0, 1, 1, 1, pl_bo, pl_bob); Xen_define_typed_dilambda(S_filter_control_in_dB, g_filter_control_in_dB_w, H_filter_control_in_dB, S_set S_filter_control_in_dB, g_set_filter_control_in_dB_w, 0, 1, 1, 1, pl_bo, pl_bob); Xen_define_typed_dilambda(S_filter_control_in_hz, g_filter_control_in_hz_w, H_filter_control_in_hz, S_set S_filter_control_in_hz, g_set_filter_control_in_hz_w, 0, 1, 1, 1, pl_bo, pl_bob); Xen_define_typed_dilambda(S_filter_control_order, g_filter_control_order_w, H_filter_control_order, S_set S_filter_control_order, g_set_filter_control_order_w, 0, 1, 1, 1, pl_io, pl_ioi); Xen_define_typed_dilambda(S_contrast_control, g_contrast_control_w, H_contrast_control, S_set S_contrast_control, g_set_contrast_control_w, 0, 1, 1, 1, pl_ro, pl_ror); Xen_define_typed_dilambda(S_contrast_control_bounds, g_contrast_control_bounds_w, H_contrast_control_bounds, S_set S_contrast_control_bounds, g_set_contrast_control_bounds_w, 0, 1, 1, 1, pl_po, pl_pop); Xen_define_typed_dilambda(S_contrast_control_amp, g_contrast_control_amp_w, H_contrast_control_amp, S_set S_contrast_control_amp, g_set_contrast_control_amp_w, 0, 1, 1, 1, pl_ro, pl_ror); Xen_define_typed_dilambda(S_expand_control, g_expand_control_w, H_expand_control, S_set S_expand_control, g_set_expand_control_w, 0, 1, 1, 1, pl_ro, pl_ror); Xen_define_typed_dilambda(S_expand_control_bounds, g_expand_control_bounds_w, H_expand_control_bounds, S_set S_expand_control_bounds, g_set_expand_control_bounds_w, 0, 1, 1, 1, pl_po, pl_pop); Xen_define_typed_dilambda(S_expand_control_length, g_expand_control_length_w, H_expand_control_length, S_set S_expand_control_length, g_set_expand_control_length_w, 0, 1, 1, 1, pl_ro, pl_ror); Xen_define_typed_dilambda(S_expand_control_ramp, g_expand_control_ramp_w, H_expand_control_ramp, S_set S_expand_control_ramp, g_set_expand_control_ramp_w, 0, 1, 1, 1, pl_ro, pl_ror); Xen_define_typed_dilambda(S_expand_control_hop, g_expand_control_hop_w, H_expand_control_hop, S_set S_expand_control_hop, g_set_expand_control_hop_w, 0, 1, 1, 1, pl_ro, pl_ror); Xen_define_typed_dilambda(S_expand_control_jitter, g_expand_control_jitter_w, H_expand_control_jitter, S_set S_expand_control_jitter, g_set_expand_control_jitter_w, 0, 1, 1, 1, pl_ro, pl_ror); Xen_define_typed_dilambda(S_speed_control, g_speed_control_w, H_speed_control, S_set S_speed_control, g_set_speed_control_w, 0, 1, 1, 1, pl_ro, pl_ror); Xen_define_typed_dilambda(S_speed_control_bounds, g_speed_control_bounds_w, H_speed_control_bounds, S_set S_speed_control_bounds, g_set_speed_control_bounds_w, 0, 1, 1, 1, pl_po, pl_pop); Xen_define_typed_dilambda(S_reverb_control_length, g_reverb_control_length_w, H_reverb_control_length, S_set S_reverb_control_length, g_set_reverb_control_length_w, 0, 1, 1, 1, pl_ro, pl_ror); Xen_define_typed_dilambda(S_reverb_control_length_bounds, g_reverb_control_length_bounds_w, H_reverb_control_length_bounds, S_set S_reverb_control_length_bounds, g_set_reverb_control_length_bounds_w, 0, 1, 1, 1, pl_po, pl_pop); Xen_define_typed_dilambda(S_reverb_control_scale, g_reverb_control_scale_w, H_reverb_control_scale, S_set S_reverb_control_scale, g_set_reverb_control_scale_w, 0, 1, 1, 1, pl_ro, pl_ror); Xen_define_typed_dilambda(S_reverb_control_scale_bounds, g_reverb_control_scale_bounds_w, H_reverb_control_scale_bounds, S_set S_reverb_control_scale_bounds, g_set_reverb_control_scale_bounds_w, 0, 1, 1, 1, pl_po, pl_pop); Xen_define_typed_dilambda(S_reverb_control_feedback, g_reverb_control_feedback_w, H_reverb_control_feedback, S_set S_reverb_control_feedback, g_set_reverb_control_feedback_w, 0, 1, 1, 1, pl_ro, pl_ror); Xen_define_typed_dilambda(S_reverb_control_lowpass, g_reverb_control_lowpass_w, H_reverb_control_lowpass, S_set S_reverb_control_lowpass, g_set_reverb_control_lowpass_w, 0, 1, 1, 1, pl_ro, pl_ror); Xen_define_typed_dilambda(S_amp_control, g_amp_control_w, H_amp_control, S_set S_amp_control, g_set_amp_control_w, 0, 2, 1, 2, pl_ro, pl_ror); Xen_define_typed_dilambda(S_amp_control_bounds, g_amp_control_bounds_w, H_amp_control_bounds, S_set S_amp_control_bounds, g_set_amp_control_bounds_w, 0, 1, 1, 1, pl_po, pl_pop); Xen_define_typed_dilambda(S_reverb_control_decay, g_reverb_control_decay_w, H_reverb_control_decay, S_set S_reverb_control_decay, g_set_reverb_control_decay_w, 0, 1, 1, 1, pl_ro, pl_ror); #define H_speed_control_as_float "The value for " S_speed_control_style " that interprets the speed slider as a float" #define H_speed_control_as_ratio "The value for " S_speed_control_style " that interprets the speed slider as a just-intonation ratio" #define H_speed_control_as_semitone "The value for " S_speed_control_style " that interprets the speed slider as a microtone (via " S_speed_control_tones ")" Xen_define_constant(S_speed_control_as_float, SPEED_CONTROL_AS_FLOAT, H_speed_control_as_float); Xen_define_constant(S_speed_control_as_ratio, SPEED_CONTROL_AS_RATIO, H_speed_control_as_ratio); Xen_define_constant(S_speed_control_as_semitone, SPEED_CONTROL_AS_SEMITONE, H_speed_control_as_semitone); Xen_define_typed_dilambda(S_speed_control_style, g_speed_control_style_w, H_speed_control_style, S_set S_speed_control_style, g_set_speed_control_style_w, 0, 1, 1, 1, pl_io, pl_ioi); Xen_define_typed_dilambda(S_speed_control_tones, g_speed_control_tones_w, H_speed_control_tones, S_set S_speed_control_tones, g_set_speed_control_tones_w, 0, 1, 1, 1, pl_io, pl_ioi); Xen_define_procedure(S_channel_amp_envs, g_channel_amp_envs_w, 0, 5, 0, H_channel_amp_envs); Xen_define_safe_procedure(S_sounds, g_sounds_w, 0, 0, 0, H_sounds); Xen_define_typed_procedure(S_integer_to_sound, g_integer_to_sound_w, 1, 0, 0, H_integer_to_sound, pl_oi); Xen_define_typed_procedure(S_sound_to_integer, g_sound_to_integer_w, 1, 0, 0, H_sound_to_integer, pl_io); #if HAVE_SCHEME s7_symbol_set_documentation(s7, ss->channel_style_symbol, "*channel-style*: how multichannel sounds lay out the channels: channels-combined, channels-separate or channels-superimposed."); s7_symbol_set_documentation(s7, ss->filter_control_in_db_symbol, "*filter-control-in-dB*: #t if snd's filter envelope is displayed in dB in control panel"); s7_symbol_set_documentation(s7, ss->filter_control_in_hz_symbol, "*filter-control-in-hz*: #t if snd's filter envelope x axis should be in hz (control panel filter)"); s7_symbol_set_documentation(s7, ss->speed_control_tones_symbol, "*speed-control-tones*: the speed-control octave divisions (12)"); s7_symbol_set_documentation(s7, ss->speed_control_style_symbol, "*speed-control-style*: speed control choice (speed-control-as-float etc)"); s7_symbol_set_documentation(s7, ss->expand_control_length_symbol, "*expand-control-length*: current expansion segment length in seconds (.15)"); s7_symbol_set_documentation(s7, ss->expand_control_ramp_symbol, "*expand-control-ramp*: current expansion ramp time (.4)"); s7_symbol_set_documentation(s7, ss->expand_control_hop_symbol, "*expand-control-hop*: current expansion output grain spacing in seconds (0.05)"); s7_symbol_set_documentation(s7, ss->expand_control_jitter_symbol, "*expand-control-jitter*: current expansion output grain spacing jitter (0.1)"); s7_symbol_set_documentation(s7, ss->contrast_control_amp_symbol, "*contrast-control-amp*: contrast amp"); s7_symbol_set_documentation(s7, ss->reverb_control_feedback_symbol, "*reverb-control-feedback*: control-panel reverb feedback scaler"); s7_symbol_set_documentation(s7, ss->reverb_control_lowpass_symbol, "*reverb-control-lowpass*: control-panel reverb lowpass filter coefficient"); s7_symbol_set_documentation(s7, ss->reverb_control_decay_symbol, "*reverb-control-decay*: control-panel reverb decay time (1.0 seconds)"); s7_symbol_set_documentation(s7, ss->filter_control_order_symbol, "*filter-control-order*: control-panel filter order"); s7_symbol_set_documentation(s7, ss->show_controls_symbol, "*show-controls*: #t if snd's control panel is known to be open"); s7_symbol_set_access(s7, ss->channel_style_symbol, s7_make_function(s7, "[acc-" S_channel_style "]", acc_channel_style, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->filter_control_in_db_symbol, s7_make_function(s7, "[acc-" S_filter_control_in_dB "]", acc_filter_control_in_dB, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->filter_control_in_hz_symbol, s7_make_function(s7, "[acc-" S_filter_control_in_hz "]", acc_filter_control_in_hz, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->speed_control_tones_symbol, s7_make_function(s7, "[acc-" S_speed_control_tones "]", acc_speed_control_tones, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->speed_control_style_symbol, s7_make_function(s7, "[acc-" S_speed_control_style "]", acc_speed_control_style, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->expand_control_length_symbol, s7_make_function(s7, "[acc-" S_expand_control_length "]", acc_expand_control_length, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->expand_control_ramp_symbol, s7_make_function(s7, "[acc-" S_expand_control_ramp "]", acc_expand_control_ramp, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->expand_control_hop_symbol, s7_make_function(s7, "[acc-" S_expand_control_hop "]", acc_expand_control_hop, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->expand_control_jitter_symbol, s7_make_function(s7, "[acc-" S_expand_control_jitter "]", acc_expand_control_jitter, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->contrast_control_amp_symbol, s7_make_function(s7, "[acc-" S_contrast_control_amp "]", acc_contrast_control_amp, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->reverb_control_feedback_symbol, s7_make_function(s7, "[acc-" S_reverb_control_feedback "]", acc_reverb_control_feedback, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->reverb_control_lowpass_symbol, s7_make_function(s7, "[acc-" S_reverb_control_lowpass "]", acc_reverb_control_lowpass, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->reverb_control_decay_symbol, s7_make_function(s7, "[acc-" S_reverb_control_decay "]", acc_reverb_control_decay, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->filter_control_order_symbol, s7_make_function(s7, "[acc-" S_filter_control_order "]", acc_filter_control_order, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->show_controls_symbol, s7_make_function(s7, "[acc-" S_show_controls "]", acc_show_controls, 2, 0, false, "accessor")); #endif } snd-16.1/snd-utils.c0000644000076400007640000001754512452076311012436 0ustar bilbil#if (defined(__GNUC__)) && (!(defined(__cplusplus))) #define _GNU_SOURCE /* this is needed to get the vasprintf declaration */ #endif #include "snd.h" int snd_round(double x) /* needs to be double here (not mus_float_t) for x axis calcs */ { int i; i = (int)x; if ((x - i) > 0.5) return(i + 1); return(i); } mus_long_t snd_round_mus_long_t(double x) { mus_long_t i; i = (mus_long_t)x; if ((x - i) > 0.5) return(i + 1); return(i); } mus_long_t snd_abs_mus_long_t(mus_long_t val) { /* div is also limited to int */ return((val < 0) ? -val : val); } #define POW2_SIZE 31 static int ipow2s[POW2_SIZE] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, 67108864, 134217728, 268435456, 536870912, 1073741824}; int snd_int_pow2(int n) { return(ipow2s[n]); } mus_long_t snd_mus_long_t_pow2(int n) { if ((n < 0) || (n > 46)) return(0); if (n < POW2_SIZE) return((mus_long_t)ipow2s[n]); return((mus_long_t)ipow2s[16] * (mus_long_t)ipow2s[n - 16]); /* can't store an array as above -- compiler complaints */ } int snd_to_int_pow2(int n) { /* round up to next power of 2 */ int i; for (i = 0; i < POW2_SIZE; i++) if (ipow2s[i] >= n) return(ipow2s[i]); return(0); } int snd_int_log2(int n) { /* round down */ int i; for (i = 1; i < POW2_SIZE; i++) if (ipow2s[i] > n) return(i - 1); return(0); } #define MAX_FLOAT_DIFF_FOR_EQUAL 0.0000001 bool snd_feq(mus_float_t val1, mus_float_t val2) { /* if some float can be affected by a widget, we can easily get float inaccuracies that confuse "==" (in gtk in particular) */ if (val1 == val2) return(true); if (fabs(val1 - val2) < MAX_FLOAT_DIFF_FOR_EQUAL) return(true); return(false); } #if !(defined(__GNUC__) && (!(defined(__cplusplus)))) mus_float_t in_dB(mus_float_t min_dB, mus_float_t lin_dB, mus_float_t val) { return((val <= lin_dB) ? min_dB : (20.0 * log10(val))); } #endif #define TIME_STR_SIZE 64 static char time_buf[TIME_STR_SIZE]; char *snd_local_time(void) { time_t ts; time(&ts); strftime(time_buf, TIME_STR_SIZE, STRFTIME_FORMAT, localtime(&ts)); return(time_buf); } char *snd_strftime(const char *format, time_t date) { strftime(time_buf, TIME_STR_SIZE, format, localtime(&date)); return(time_buf); } char *snd_io_strerror(void) /* "snd_strerror" is exported by ALSA! */ { if (ss->local_errno != 0) return(strerror(ss->local_errno)); if (errno != 0) return(strerror(errno)); return(NULL); } char *snd_open_strerror(void) { if (ss->local_open_errno != 0) return(strerror(ss->local_open_errno)); return(snd_io_strerror()); } char *string_to_colon(char *val) { char *up_to_colon; int i, len; up_to_colon = (char *)calloc(strlen(val) + 1, sizeof(char)); len = strlen(val); for (i = 0; i < len; i++) { if ((val[i] == ':') || (val[i] == ' ')) { up_to_colon[i] = 0; return(up_to_colon); } up_to_colon[i] = val[i]; } return(up_to_colon); } char *filename_without_directory(const char *name) { /* since I don't want to mess with freeing these guys, I'll just return a pointer into the name */ int i, len, last_slash; last_slash = 0; len = strlen(name); for (i = 0; i < len - 1; i++) if (name[i] == '/') last_slash = i + 1; return((char *)(name + last_slash)); } char *just_filename(char *name) { char *nodir; int i, len; nodir = mus_strdup(filename_without_directory(name)); len = strlen(nodir); for (i = 0; i < len; i++) if (nodir[i] == '.') { nodir[i] = '\0'; break; } return(nodir); } char *just_directory(const char *name) { int i, len, last_slash = 0; char *dirname = NULL; len = strlen(name); dirname = (char *)calloc(len + 1, sizeof(char)); for (i = 0; i < len - 1; i++) if (name[i] == '/') last_slash = i + 1; if (last_slash > 0) strncpy(dirname, name, last_slash); return(dirname); } char *file_to_string(const char *filename) { FILE *file; long size; char *content = NULL; file = fopen(filename, "r"); if (!file) return(NULL); fseek(file, 0, SEEK_END); size = ftell(file); if (size > 0) { size_t bytes; rewind(file); content = (char *)calloc(size + 1, sizeof(char)); bytes = fread(content, sizeof(char), size, file); if (bytes == 0) fprintf(stderr, "file->string read error"); } fclose(file); return(content); } char *vstr(const char *format, va_list ap) { char *buf; #ifndef _MSC_VER if (vasprintf(&buf, format, ap) == -1) return(NULL); #else int len; len = mus_strlen(format) + PRINT_BUFFER_SIZE; buf = (char *)calloc(len, sizeof(char)); vsnprintf(buf, len, format, ap); #endif return(buf); } disk_space_t disk_has_space(mus_long_t bytes, const char *filename) { mus_long_t kfree, kneeded; kfree = disk_kspace(filename); if (kfree < 0) { snd_error("can't access %s: %s", filename, snd_io_strerror()); return(NO_DISK_SPACE); } kneeded = bytes >> 10; if (kfree < kneeded) { snd_error("not enough space left on disk: only %lld kbytes available", kfree); return(NOT_ENOUGH_DISK_SPACE); } return(DISK_SPACE_OK); } char *prettyf(double num, int tens) { /* try to prettify float display -- if tens <= 0, return int */ static char prtbuf[256]; if (tens <= 0) snprintf(prtbuf, 256, "%d", (int)snd_round(num)); else { int i, len; snprintf(prtbuf, 256, "%.*f", tens, num); /* %f assumes double arg */ /* look for trailing 0's beyond the ddd.0 case */ len = strlen(prtbuf); for (i = len - 1; (i > 0) && (prtbuf[i] == '0') && (prtbuf[i - 1] != '.'); i--) prtbuf[i] = '\0'; } return(mus_strdup(prtbuf)); } static char *get_tmpdir(void) { char *tmpdir = NULL; int len; tmpdir = mus_strdup(getenv("TMPDIR")); if ((tmpdir == NULL) && (MUS_DEFAULT_TEMP_DIR)) tmpdir = mus_strdup(MUS_DEFAULT_TEMP_DIR); #ifdef P_tmpdir if (tmpdir == NULL) tmpdir = mus_strdup(P_tmpdir); /* /usr/include/stdio.h */ #else if (tmpdir == NULL) return(mus_strdup("/tmp")); #endif if (tmpdir == NULL) return(mus_strdup(".")); len = strlen(tmpdir); if (tmpdir[len - 1] == '/') tmpdir[len - 1] = 0; /* this is what forces us to copy the string above (Sun segfaults otherwise) */ return(tmpdir); } static int sect_ctr = 0; char *shorter_tempnam(const char *udir, const char *prefix) { /* tempnam turns out names that are inconveniently long (in this case the filename is user-visible) */ char *str, *tmpdir = NULL; str = (char *)calloc(PRINT_BUFFER_SIZE, sizeof(char)); if ((udir == NULL) || (mus_strlen(udir) == 0)) tmpdir = get_tmpdir(); /* incoming dir could be "" */ else tmpdir = mus_strdup(udir); snprintf(str, PRINT_BUFFER_SIZE, "%s/%s%d_%d.snd", tmpdir, (prefix) ? prefix : "snd_", (int)getpid(), sect_ctr++); if (tmpdir) free(tmpdir); tmpdir = mus_strdup(str); free(str); return(tmpdir); } char *snd_tempnam(void) { char *udir; udir = temp_dir(ss); if ((udir) && (*udir)) return(shorter_tempnam(udir, "snd_")); return(shorter_tempnam(NULL, "snd_")); } #if MUS_PORTAUDIO #include #endif void snd_exit(int val) { #if MUS_PORTAUDIO Pa_Terminate(); #endif exit(val); } /* currently this is only used by the test suite (snd-test.scm) */ #if HAVE_SCHEME #define S_file_to_string "file->string" static Xen g_file_to_string(Xen name) { char *contents; Xen val = Xen_false; Xen_check_type(Xen_is_string(name), name, 1, S_file_to_string, "a string"); contents = file_to_string(Xen_string_to_C_string(name)); val = C_string_to_Xen_string(contents); free(contents); return(val); } #endif #if HAVE_SCHEME Xen_wrap_1_arg(g_file_to_string_w, g_file_to_string) #endif void g_init_utils(void) { #if HAVE_SCHEME Xen_define_safe_procedure(S_file_to_string, g_file_to_string_w, 1, 0, 0, "file contents as string"); #endif } snd-16.1/noise.scm0000644000076400007640000001705012462277004012163 0ustar bilbil;;; noise.scm -- CLM -> Snd/Scheme translation of noise.ins ;; Translator/Author: Michael Scholz ;; Last: Wed Apr 02 02:47:21 CEST 2003 ;; Version: $Revision: 1.9 $ ;;; Comments not otherwise noted are taken from noise.ins! ;; Included functions: ;; (attack-point duration attack decay (total-x 100.0)) ;; (fm-noise ...) ;; (make-fm-noise len freq ...) ;;; The "noise" instrument (useful for Oceanic Music): (provide 'snd-noise.scm) (require snd-ws.scm snd-env.scm) (define *locsig-type* mus-interp-sinusoidal) (define* (attack-point duration attack decay (total-x 100.0)) (* total-x (/ (if (= 0.0 attack) (if (= 0.0 decay) (/ duration 4) (/ (- duration decay) 4)) attack) duration))) (definstrument (fm-noise startime dur freq0 amp ampfun ampat ampdc freq1 glissfun freqat freqdc rfreq0 rfreq1 rfreqfun rfreqat rfreqdc dev0 dev1 devfun devat devdc (degree 0.0) (distance 1.0) (reverb-amount 0.005)) ;; ampat = amp envelope attack time, and so on -- this instrument ;; assumes your envelopes go from 0 to 100 on the x-axis, and that ;; the "attack" portion ends at 25, the "decay" portion starts at ;; 75. "rfreq" is the frequency of the random number generator -- ;; if below about 25 hz you get automatic composition, above that ;; you start to get noise. well, you get a different kind of noise. ;; "dev" is the bandwidth of the noise -- very narrow gives a ;; whistle, very broad more of a whoosh. this is basically "simple ;; fm", but the modulating signal is white noise. (let (;; fix-up troubles in attack and decay times (there are ;; lots of ways to handle this -- the basic problem is that ;; these durned instruments end up having way too many ;; parameters. rick taube's common music replacement for pla ;; should help, but just for old time's sake, we'll do it the ;; way the ancients did it. (we could also package up this ;; stuff in our own function, somewhat like the allvln ;; function in vln.clm, leaving the instrument code to apply ;; envelopes and other data to some patch). (amp-attack (attack-point dur ampat ampdc)) (amp-decay (- 100.0 (attack-point dur ampdc ampat))) (freq-attack (attack-point dur freqat freqdc)) (freq-decay (- 100.0 (attack-point dur freqdc freqat))) (dev-attack (attack-point dur devat devdc)) (dev-decay (- 100.0 (attack-point dur devdc devat))) (rfreq-attack (attack-point dur rfreqat rfreqdc)) (rfreq-decay (- 100.0 (attack-point dur rfreqdc rfreqat)))) (let ((beg (seconds->samples startime)) (end (seconds->samples (+ startime dur))) (carrier (make-oscil freq0)) (modulator (make-rand :frequency rfreq0 :amplitude 1.0)) (loc (make-locsig :degree degree :distance distance :reverb reverb-amount :type *locsig-type*)) ;; now make the actual envelopes -- these all assume we are ;; thinking in terms of the "value when the envelope is 1" ;; (i.e. dev1 and friends), and the "value when the envelope ;; is 0" (i.e. dev0 and friends) -- over the years this ;; seemed to make beginners happier than various other ways ;; of describing the y-axis behaviour of the envelope. all ;; this boiler-plate for envelopes might seem overly ;; elaborate when our basic instrument is really simple, but ;; in most cases, and this one in particular, nearly all the ;; musical interest comes from the envelopes, not the ;; somewhat dull spectrum generated by the basic patch. (dev-f (make-env (stretch-envelope devfun 25 dev-attack 75 dev-decay) :duration dur :offset (hz->radians dev0) :scaler (hz->radians (- dev1 dev0)))) (amp-f (make-env (stretch-envelope ampfun 25 amp-attack 75 amp-decay) :duration dur :scaler amp)) (freq-f (make-env (stretch-envelope glissfun 25 freq-attack 75 freq-decay) :duration dur :scaler (hz->radians (- freq1 freq0)))) (rfreq-f (make-env (stretch-envelope rfreqfun 25 rfreq-attack 75 rfreq-decay) :duration dur :scaler (hz->radians (- rfreq1 rfreq0))))) (do ((i beg (+ i 1))) ((= i end)) (locsig loc i (* (env amp-f) (oscil carrier (+ (env freq-f) (* (env dev-f) (rand modulator (env rfreq-f))))))))))) ;;; (with-sound () (fm-noise 0 0.5 500 0.25 '(0 0 25 1 75 1 100 0) 0.1 0.1 1000 '(0 0 100 1) 0.1 0.1 10 1000 '(0 0 100 1) 0 0 100 500 '(0 0 100 1) 0 0)) ;; (let* ((ofile "test.snd") ;; (snd (find-sound ofile))) ;; (if snd ;; (close-sound snd)) ;; (with-sound (:output ofile :play 1 :statistics #t) ;; (fm-noise 0 2.0 500 0.25 '(0 0 25 1 75 1 100 0) 0.1 0.1 ;; 1000 '(0 0 100 1) 0.1 0.1 ;; 10 1000 '(0 0 100 1) 0 0 ;; 100 500 '(0 0 100 1) 0 0))) ;;; And here is a generator-like instrument, see make-fm-violin in ;;; fmv.scm. [MS] (define* (make-fm-noise len freq (amp 0.25) (ampfun '(0 0 25 1 75 1 100 0)) (ampat 0.1) (ampdc 0.1) (freq1 1000) (glissfun '(0 0 100 1)) (freqat 0.1) (freqdc 0.1) (rfreq0 10) (rfreq1 1000) (rfreqfun '(0 0 100 1)) (rfreqat 0) (rfreqdc 0) (dev0 100) (dev1 500) (devfun '(0 0 100 1)) (devat 0) (devdc 0) ; (degree (random 90.0)) ; (distance 1.0) ; (reverb-amount 0.005) ) (let* ((dur (/ len (floor (srate)))) (amp-attack (attack-point dur ampat ampdc)) (amp-decay (- 100.0 (attack-point dur ampdc ampat))) (freq-attack (attack-point dur freqat freqdc)) (freq-decay (- 100.0 (attack-point dur freqdc freqat))) (dev-attack (attack-point dur devat devdc)) (dev-decay (- 100.0 (attack-point dur devdc devat))) (rfreq-attack (attack-point dur rfreqat rfreqdc)) (rfreq-decay (- 100.0 (attack-point dur rfreqdc rfreqat))) (dev-ff (make-env (stretch-envelope devfun 25 dev-attack 75 dev-decay) :duration dur :scaler (hz->radians (- dev1 dev0)))) (amp-ff (make-env (stretch-envelope ampfun 25 amp-attack 75 amp-decay) :duration dur :scaler amp)) (freq-ff (make-env (stretch-envelope glissfun 25 freq-attack 75 freq-decay) :duration dur :scaler (hz->radians (- freq1 freq)))) (rfreq-ff (make-env (stretch-envelope rfreqfun 25 rfreq-attack 75 rfreq-decay) :duration dur :scaler (hz->radians (- rfreq1 rfreq0)))) (carrier (make-oscil freq)) (modulator (make-rand :frequency rfreq0 :amplitude 1.0)) (dev-0 (hz->radians dev0)) (dev-f (lambda () (env dev-ff))) (amp-f (lambda () (env amp-ff))) (freq-f (lambda () (env freq-ff))) (rfreq-f (lambda () (env rfreq-ff)))) (lambda () (* (amp-f) (oscil carrier (+ (freq-f) (* (+ dev-0 (dev-f)) (rand modulator (rfreq-f))))))))) ;; (let* ((beg 0) ;; (dur 9.8) ;; (len (+ beg (floor (* dur (srate))))) ;; (chns 4) ;; (outfile "test.snd") ;; (snd (find-sound outfile)) ;; (loc (make-locsig :degree (random 3535.0) :channels chns)) ;; (data (make-float-vector len))) ;; (do ((i 0 (+ i 1))) ;; ((= i len)) ;; (set! (data i) (make-fm-noise len 500))) ;; (if snd ;; (close-sound snd)) ;; (set! snd (new-sound outfile chns *clm-srate* mus-bshort mus-next)) ;; (do ((i 0 (+ i 1))) ;; ((= i chns)) ;; (mix-float-vector (float-vector-scale! (copy data) (locsig-ref loc i)) beg snd i #f)) ;; (let* ((beg (floor (* 10 (srate)))) ;; (len (+ beg (floor (* dur (srate))))) ;; (loc (make-locsig :degree (random 3535.0) :channels chns)) ;; (data (make-float-vector len))) ;; (do ((i 0 (+ i 1))) ;; ((= i len)) ;; (set! (data i) (make-fm-noise len 200))) ;; (do ((i 0 (+ i 1))) ;; ((= i chns)) ;; (mix-float-vector (float-vector-scale! (copy data) (locsig-ref loc i)) beg snd i #f)) ;; (play snd 0))) ;; noise.scm ends here snd-16.1/expandn.scm0000644000076400007640000003073312616475120012506 0ustar bilbil;;; multi-channel sound file expansion with srate and reverb. ;;; michael klingbeil (michael@klingbeil.com) ;;; ;;; $Name: $ ;;; $Revision: 1.1 $ ;;; $Date: 2005/10/16 22:15:44 $ ;;; ;;; clm-4 and scheme May-08 bil ;;; split out cases to optimize May-09 bil (provide 'snd-expandn.scm) (if (provided? 'snd) (require snd-ws.scm) (require sndlib-ws.scm)) (require snd-env.scm) (definstrument (expandn time duration filename amplitude (expand 1.0) matrix (ramp 0.4) (seglen 0.15) (srate 1.0) (hop .05) (amp-env '(0 0 50 1 100 0)) (input-start 0.0) (grain-amp 0.8) reverb) (let ((fnam (file-name filename))) (if (not (file-exists? fnam)) (error 'no-such-file (list 'expandn filename)) (let* ((beg (seconds->samples time)) (end (+ beg (seconds->samples duration))) (min-exp-amt (if (pair? expand) (min-envelope expand) expand)) (max-out-hop (if (pair? hop) (max-envelope hop) hop))) (let ((in-chans (channels fnam)) (out-chans (channels *output*)) (rev-chans (if *reverb* (channels *reverb*) 0))) (let ((update-rate 100) (ochans (max in-chans out-chans)) (max-seg-len (if (pair? seglen) (max-envelope seglen) seglen)) (rampdata (if (pair? ramp) ramp (list 0 ramp 1 ramp))) (start (floor (* input-start (mus-sound-srate fnam)))) (max-in-hop (/ max-out-hop min-exp-amt)) (rev-mx (and *reverb* reverb (> reverb 0.0) (let* ((rchans (max out-chans rev-chans)) (rmx (make-float-vector (list rchans rchans) 0.0))) (do ((i 0 (+ i 1))) ((= i rchans)) (set! (rmx i i) reverb)) rmx)))) (let ((mx (let ((v (make-float-vector (list ochans ochans) 0.0))) (if (pair? matrix) (let ((mat-in (min ochans (length matrix))) (mat-out (min ochans (length (car matrix))))) (do ((inp 0 (+ inp 1))) ((= inp mat-in)) (do ((outp 0 (+ outp 1))) ((= outp mat-out)) (set! (v inp outp) (matrix inp outp))))) (do ((i 0 (+ i 1))) ((= i ochans)) (set! (v i i) 1.0))) v)) (revvals (and rev-mx (make-float-vector (max out-chans rev-chans) 0.0))) (update-envs (or (pair? expand) (pair? seglen) (pair? ramp) (pair? hop))) (update-ctr 0) (expenv (make-env (if (pair? expand) expand (list 0 expand 1 expand)) :duration (/ duration update-rate))) (lenenv (make-env (if (pair? seglen) seglen (list 0 seglen 1 seglen)) :duration (/ duration update-rate))) (segment-scaler (if (> max-seg-len .15) (/ (* grain-amp .15) max-seg-len) grain-amp)) (srenv (if (pair? srate) (make-env srate :duration duration) (make-env (list 0 srate) :duration duration))) (rampenv (make-env rampdata :duration (/ duration update-rate))) (minramp-bug (<= (min-envelope rampdata) 0.0)) (maxramp-bug (>= (max-envelope rampdata) 0.5)) (hopenv (make-env (if (pair? hop) hop (list 0 hop 1 hop)) :duration (/ duration update-rate))) (ampenv (make-env amp-env :duration duration :scaler amplitude)) (ex-array (make-vector in-chans #f)) (ex-samp -1.0) (next-samp 0.0) (max-len (ceiling (* *clm-srate* (+ (max max-out-hop max-in-hop) max-seg-len)))) (invals (make-float-vector ochans 0.0)) (outvals (make-float-vector ochans 0.0))) (if (or minramp-bug maxramp-bug) (error 'out-of-range (list expand "ramp argument to expandn must always be " (if (and minramp-bug maxramp-bug) "between 0.0 and 0.5" (if minramp-bug "greater than 0.0" "less than 0.5"))))) ;; setup granulate generators (do ((i 0 (+ i 1))) ((= i in-chans)) (vector-set! ex-array i (make-granulate :input (make-readin fnam :start start :channel i) :expansion (if (pair? expand) (cadr expand) expand) :max-size max-len :ramp (if (pair? ramp) (cadr ramp) ramp) :hop (if (pair? hop) (cadr hop) hop) :length (if (pair? seglen) (cadr seglen) seglen) :scaler segment-scaler))) ;; split out 1 and 2 chan input (if (= in-chans 1) (let ((ingen (vector-ref ex-array 0)) (sample-0 0.0) (sample-1 0.0)) ;; these vars used for resampling (if (and (not (pair? srate)) (not update-envs) (= out-chans 1) (not matrix) (not rev-mx)) (let ((file-end (+ beg (seconds->samples (+ (* 2 seglen) (* (mus-sound-duration fnam) (/ (mus-sound-srate fnam) *clm-srate*) (/ expand srate))))))) (if (> end file-end) (set! end file-end)) (do ((i beg (+ i 1))) ((= i end)) (let ((vol (env ampenv))) (if (negative? ex-samp) (begin (set! sample-0 (* vol (granulate ingen))) (set! sample-1 (* vol (granulate ingen))) (set! ex-samp (+ ex-samp 1)) (set! next-samp ex-samp) (outa i sample-0)) (begin (set! next-samp (+ next-samp srate)) (if (> next-samp (+ ex-samp 1)) (let ((samps (floor (- next-samp ex-samp)))) (if (= samps 2) (begin (set! sample-0 (* vol (granulate ingen))) (set! sample-1 (* vol (granulate ingen)))) (do ((k 0 (+ k 1))) ((= k samps)) (set! sample-0 sample-1) (set! sample-1 (* vol (granulate ingen))))) (set! ex-samp (+ ex-samp samps)))) (if (= next-samp ex-samp) (outa i sample-0) (outa i (+ sample-0 (* (- next-samp ex-samp) (- sample-1 sample-0)))))))))) (do ((i beg (+ i 1))) ((= i end)) (let ((vol (env ampenv)) (resa (env srenv))) (if update-envs (begin (set! update-ctr (+ update-ctr 1)) (if (>= update-ctr update-rate) (let ((sl (floor (* (env lenenv) *clm-srate*)))) (set! update-ctr 0) (set! (mus-length ingen) sl) (set! (mus-ramp ingen) (floor (* sl (env rampenv)))) (set! (mus-frequency ingen) (env hopenv)) (set! (mus-increment ingen) (env expenv)))))) (if (negative? ex-samp) (begin (set! sample-0 (* vol (granulate ingen))) (set! sample-1 (* vol (granulate ingen))) (set! ex-samp (+ ex-samp 1)) (set! next-samp ex-samp)) (begin (set! next-samp (+ next-samp resa)) (if (> next-samp (+ ex-samp 1)) (let ((samps (floor (- next-samp ex-samp)))) (if (= samps 2) (begin (set! sample-0 (* vol (granulate ingen))) (set! sample-1 (* vol (granulate ingen)))) (do ((k 0 (+ k 1))) ((= k samps)) (set! sample-0 sample-1) (set! sample-1 (* vol (granulate ingen))))) (set! ex-samp (+ ex-samp samps)))))) (if (= next-samp ex-samp) ;; output actual samples (set! (invals 0) sample-0) ;; output interpolated samples (set! (invals 0) (+ sample-0 (* (- next-samp ex-samp) (- sample-1 sample-0))))) ;; output mixed result (frample->file *output* i (frample->frample mx invals ochans outvals ochans)) ;; if reverb is turned on, output to the reverb streams (if rev-mx (frample->file *reverb* i (frample->frample rev-mx outvals ochans revvals rev-chans))))))) (if (= in-chans 2) (let ((sample-0-0 0.0) (sample-1-0 0.0) (sample-0-1 0.0) (sample-1-1 0.0) (ingen0 (vector-ref ex-array 0)) (ingen1 (vector-ref ex-array 1))) (do ((i beg (+ i 1))) ((= i end)) (let ((vol (env ampenv)) (resa (env srenv))) (if update-envs (begin (set! update-ctr (+ update-ctr 1)) (if (>= update-ctr update-rate) (let ((expa (env expenv)) ;current expansion amount (segl (env lenenv)) ;current segment length (rmpl (env rampenv)) ;current ramp length (0 to .5) (hp (env hopenv))) ;current hop size (let* ((sl (floor (* segl *clm-srate*))) (rl (floor (* rmpl sl)))) (set! update-ctr 0) (set! (mus-length ingen0) sl) (set! (mus-ramp ingen0) rl) (set! (mus-frequency ingen0) hp) (set! (mus-increment ingen0) expa) (set! (mus-length ingen1) sl) (set! (mus-ramp ingen1) rl) (set! (mus-frequency ingen1) hp) (set! (mus-increment ingen1) expa)))))) (if (negative? ex-samp) (begin (set! sample-0-0 (* vol (granulate ingen0))) (set! sample-1-0 (* vol (granulate ingen0))) (set! sample-0-1 (* vol (granulate ingen1))) (set! sample-1-1 (* vol (granulate ingen1))) (set! ex-samp (+ ex-samp 1)) (set! next-samp ex-samp)) (begin (set! next-samp (+ next-samp resa)) (if (> next-samp (+ ex-samp 1)) (let ((samps (floor (- next-samp ex-samp)))) (do ((k 0 (+ k 1))) ((= k samps)) (set! sample-0-0 sample-1-0) (set! sample-1-0 (* vol (granulate ingen0))) (set! sample-0-1 sample-1-1) (set! sample-1-1 (* vol (granulate ingen1)))) (set! ex-samp (+ ex-samp samps)))))) (if (= next-samp ex-samp) ;; output actual samples (begin (set! (invals 0) sample-0-0) (set! (invals 1) sample-0-1)) (begin ;; output interpolated samples (set! (invals 0) (+ sample-0-0 (* (- next-samp ex-samp) (- sample-1-0 sample-0-0)))) (set! (invals 1) (+ sample-0-1 (* (- next-samp ex-samp) (- sample-1-1 sample-0-1)))))) ;; output mixed result (frample->file *output* i (frample->frample mx invals ochans outvals ochans)) ;; if reverb is turned on, output to the reverb streams (if rev-mx (frample->file *reverb* i (frample->frample rev-mx outvals ochans revvals rev-chans)))))) (let ((samples-0 (make-float-vector in-chans 0.0)) (samples-1 (make-float-vector in-chans 0.0))) ;; more than 2 chans in input file (do ((i beg (+ i 1))) ((= i end)) (let ((vol (env ampenv)) (resa (env srenv))) (if update-envs (begin (set! update-ctr (+ update-ctr 1)) (if (>= update-ctr update-rate) (let ((expa (env expenv)) ;current expansion amount (segl (env lenenv)) ;current segment length (rmpl (env rampenv)) ;current ramp length (0 to .5) (hp (env hopenv))) ;current hop size (let* ((sl (floor (* segl *clm-srate*))) (rl (floor (* rmpl sl)))) (set! update-ctr 0) (do ((ix 0 (+ ix 1))) ((= ix in-chans)) (let ((gen (vector-ref ex-array ix))) (set! (mus-length gen) sl) (set! (mus-ramp gen) rl) (set! (mus-frequency gen) hp) (set! (mus-increment gen) expa)))))))) (if (negative? ex-samp) (begin (do ((ix 0 (+ ix 1))) ((= ix in-chans)) (let ((gen (vector-ref ex-array ix))) (float-vector-set! samples-0 ix (* vol (granulate gen))) (float-vector-set! samples-1 ix (* vol (granulate gen))))) (set! ex-samp (+ ex-samp 1)) (set! next-samp ex-samp)) (begin (set! next-samp (+ next-samp resa)) (if (> next-samp (+ ex-samp 1)) (let ((samps (floor (- next-samp ex-samp)))) (do ((k 0 (+ k 1))) ((= k samps)) (do ((ix 0 (+ ix 1))) ((= ix in-chans)) (let ((gen (vector-ref ex-array ix))) (float-vector-set! samples-0 ix (float-vector-ref samples-1 ix)) (float-vector-set! samples-1 ix (* vol (granulate gen)))))) (set! ex-samp (+ ex-samp samps)))))) (if (= next-samp ex-samp) ;; output actual samples (copy samples-0 invals 0 in-chans) ;; output interpolated samples (do ((ix 0 (+ ix 1))) ((= ix in-chans)) (let ((v0 (float-vector-ref samples-0 ix)) (v1 (float-vector-ref samples-1 ix))) (float-vector-set! invals ix (+ v0 (* (- next-samp ex-samp) (- v1 v0))))))) ;; output mixed result (frample->file *output* i (frample->frample mx invals ochans outvals ochans)) ;; if reverb is turned on, output to the reverb streams (if rev-mx (frample->file *reverb* i (frample->frample rev-mx outvals ochans revvals rev-chans))))))))))))))) ;;; (with-sound () (expandn 0 1 "oboe.snd" 1 :expand 4)) snd-16.1/fullmix.scm0000644000076400007640000001514512616475120012531 0ustar bilbil(provide 'snd-fullmix.scm) (if (provided? 'snd) (require snd-ws.scm) (require sndlib-ws.scm)) (definstrument (fullmix in-file beg outdur inbeg matrix srate reverb-amount) ;; "matrix" can be a simple amplitude or a list of lists ;; each inner list represents one input channel's amps into one output channel ;; each element of the list can be a number, a list (turned into an env) or an env ;; ;; "srate" can be a negative number (read in reverse), or an envelope. (let ((st (seconds->samples (or beg 0.0))) (dur (or outdur (/ (- (mus-sound-duration in-file) (or inbeg 0.0)) (or (and srate (number? srate) (abs srate)) 1.0)))) (in-chans (channels in-file)) (out-chans (channels *output*)) (reversed (or (and (number? srate) (negative? srate)) (and (pair? srate) (negative? (cadr srate))))) (inloc (floor (* (or inbeg 0.0) (mus-sound-srate in-file))))) (let ((samps (seconds->samples dur)) (mx (let ((ochans (max in-chans out-chans))) (if matrix (make-float-vector (list ochans ochans) 0.0) (let ((v (make-float-vector (list ochans ochans) 0.0))) (do ((i 0 (+ i 1))) ((= i ochans)) (set! (v i i) 1.0)) v)))) (rev-mx (and *reverb* reverb-amount (> reverb-amount 0.0) (let ((rmx (make-float-vector (list in-chans in-chans) 0.0))) (do ((i 0 (+ i 1))) ((= i in-chans)) (set! (rmx i 0) reverb-amount)) ; 0->assume 1 chan reverb stream, I think rmx))) (file (if (or (not srate) (and (number? srate) (= srate 1.0))) (make-file->frample in-file) (let ((vect (make-vector in-chans #f))) (do ((i 0 (+ i 1))) ((= i in-chans)) (vector-set! vect i (make-readin in-file i inloc :direction (if reversed -1 1)))) vect))) (envs #f) (srcenv (and (pair? srate) (make-env srate :duration dur :scaler (if reversed -1.0 1.0))))) (if matrix (if (pair? matrix) ; matrix is list of scalers, envelopes (lists), or env gens (do ((inp 0 (+ inp 1)) (off 0 (+ off out-chans))) ((= inp in-chans)) (let ((inlist (list-ref matrix inp))) (do ((outp 0 (+ outp 1))) ((= outp out-chans)) (let ((outn (list-ref inlist outp))) (if outn (if (number? outn) (set! (mx inp outp) outn) (if (or (env? outn) (pair? outn)) (begin (if (not envs) (set! envs (make-vector (* in-chans out-chans) #f))) (if (env? outn) (vector-set! envs (+ off outp) outn) (vector-set! envs (+ off outp) (make-env outn :duration dur)))) (format #t "unknown element in matrix: ~A" outn)))))))) (do ((inp 0 (+ inp 1))) ; matrix is a number in this case (a global scaler) ((= inp in-chans)) (if (< inp out-chans) (set! (mx inp inp) matrix))))) (if (or (not srate) (and (number? srate) (= srate 1.0))) (let ((mxe (and envs (let ((v (make-vector in-chans))) (do ((i 0 (+ i 1)) (off 0 (+ off out-chans))) ((= i in-chans)) (let ((vo (make-vector out-chans #f))) (vector-set! v i vo) (do ((j 0 (+ j 1))) ((= j out-chans)) (vector-set! vo j (vector-ref envs (+ off j)))))) v)))) ;; -------- no src (mus-file-mix *output* file st samps inloc mx mxe) (if rev-mx (mus-file-mix *reverb* file st samps inloc rev-mx))) (let ((srcs (make-vector in-chans #f))) (do ((inp 0 (+ inp 1))) ((= inp in-chans)) (vector-set! srcs inp (make-src :input (vector-ref file inp) :srate (if (number? srate) (abs srate) 0.0)))) (mus-file-mix-with-envs file st samps mx rev-mx envs srcs srcenv *output* *reverb*) ))))) #| (with-sound (:channels 2 :statistics #t) (fullmix "pistol.snd") (fullmix "2.snd" .5 1) (fullmix "2.snd" 1.5 1 0 #f 2.0) (fullmix "oboe.snd" 1 2 0 (list (list .1 (make-env '(0 0 1 1) :duration 2 :scaler .5)))) (fullmix "pistol.snd" 2 1 0 #f .5) (fullmix "2.snd" 0 2 0 (list (list .1 .2) (list .3 .4)) 2.0) (fullmix "oboe.snd" 3 2 0 (list (list .1 (make-env '(0 0 1 1) :duration 2 :scaler .5))) .25) (let ((e0->0 (make-env '(0 0 1 1) :duration 2)) (e0->1 (make-env '(0 1 1 0) :duration 2)) (e1->0 (make-env '(0 1 1 0) :duration 2)) (e1->1 (make-env '(0 0 1 1) :duration 2))) (fullmix "2.snd" 4 2 0 (list (list e0->0 e0->1) (list e1->0 e1->1)))) (let ((e0->0 (make-env '(0 0 1 1) :duration 2)) (e0->1 (make-env '(0 1 1 0) :duration 2)) (e1->0 (make-env '(0 1 1 0) :duration 2)) (e1->1 (make-env '(0 0 1 1) :duration 2))) (fullmix "2.snd" 6 2 0 (list (list e0->0 e0->1) (list e1->0 e1->1)) 2.0))) (with-sound (:channels 2 :statistics #t) (fullmix "2.snd" 0 2 0 (list (list .1 .2) (list .3 .4)) 2.0)) (with-sound () (fullmix "pistol.snd" 0 2 2 #f -1.0)) (with-sound (:channels 2) (let ((e0->0 (make-env '(0 0 1 1) :duration 2)) (e0->1 (make-env '(0 1 1 0) :duration 2)) (e1->0 (make-env '(0 1 1 0) :duration 2)) (e1->1 (make-env '(0 0 1 1) :duration 2))) (fullmix "2.snd" 6 2 0 (list (list e0->0 e0->1) (list e1->0 e1->1))) 2.0)) (with-sound () (fullmix "pistol.snd")) (with-sound () (fullmix "pistol.snd" 1)) (with-sound () (fullmix "pistol.snd" 1 1)) (with-sound () (fullmix "pistol.snd" 0 1 1)) (with-sound (:statistics #t) (fullmix "pistol.snd" 0 1 0 2.0)) (with-sound (:statistics #t :channels 2) (fullmix "pistol.snd" 0 1 0 2.0)) (with-sound (:statistics #t :channels 2) (fullmix "pistol.snd" 0 1 0 (list (list 0.1 0.7)))) (with-sound (:statistics #t :channels 2) (fullmix "pistol.snd" 0 1 0 (list (list 0.1 (list 0 0 1 1))))) (with-sound (:channels 2 :output "one-2.snd") (do ((i 0 (+ i 1))) ((= i 10000)) (outa i 0.5) (outb i -0.5))) (with-sound (:channels 4 :output "one-4.snd") (do ((i 0 (+ i 1))) ((= i 10000)) (outa i 0.5) (outb i -0.5) (outc i 0.1) (outd i -0.1))) (with-sound (:statistics #t :channels 2) (fullmix "one-2.snd" 0 .2 0 '((1.0 0.5) (0.5 1.0)))) (with-sound (:statistics #t :channels 2) (fullmix "one-2.snd" 0 .2 0 (list (list 0.1 (list 0 0 1 1)) (list (list 0 1 1 0) .5)))) (with-sound (:statistics #t :channels 2) (let ((e0->0 (make-env '(0 0 1 1) :end 10000)) (e0->1 (make-env '(0 1 1 0) :end 10000)) (e1->0 (make-env '(0 1 1 0) :end 10000)) (e1->1 (make-env '(0 0 1 1) :end 10000))) (fullmix "one-2.snd" 0 .2 0 (list (list e0->0 e0->1) (list e1->0 e1->1))))) (with-sound (:statistics #t :channels 2 :reverb jc-reverb) (let ((e0->0 (make-env '(0 0 1 1) :end 10000)) (e0->1 (make-env '(0 1 1 0) :end 10000)) (e1->0 (make-env '(0 1 1 0) :end 10000)) (e1->1 (make-env '(0 0 1 1) :end 10000))) (fullmix "one-2.snd" 0 .2 0 (list (list e0->0 e0->1) (list e1->0 e1->1)) #f .1))) (with-sound () (fullmix "oboe.snd" 0 2 0 #f '(0 0.5 1 1 2 .1))) |# snd-16.1/sndclm.html0000644000076400007640000147250412623732553012526 0ustar bilbil CLM

CLM (originally an acronym for Common Lisp Music) is a sound synthesis package in the Music V family. This file describes CLM as implemented in Snd, aiming primarily at the Scheme version. CLM is based on a set of functions known as "generators". These can be packaged into "instruments", and instrument calls can be packaged into "note lists". (These names are just convenient historical artifacts). The main emphasis here is on the generators; note lists and instruments are described in sndscm.html.

Bill Schottstaedt (bil@ccrma.stanford.edu)
Contents
all-passall-pass filter nrxysinn scaled sines
asymmetric-fmasymmetric fm nsinn equal amplitude sines
combcomb filter one-poleone pole filter
convolveconvolution one-zeroone zero filter
delaydelay line oscilsine wave and FM
envline segment envelope out-anysound output
file->sampleinput sample from file phase-vocodervocoder analysis and resynthesis
file->frampleinput frample from file polyshape and polywavewaveshaping
filterdirect form FIR/IIR filter pulse-trainpulse train
filtered-combcomb filter with filter on feedback rand, rand-interprandom numbers, noise
fir-filterFIR filter readinsound input
formant and firmantresonance sample->fileoutput sample to file
frample->fileoutput frample to file sawtooth-wavesawtooth
granulategranular synthesis square-wavesquare wave
iir-filterIIR filter srcsampling rate conversion
in-anysound file input ssb-amsingle sideband amplitude modulation
locsigstatic sound placement table-lookupinterpolated table lookup
move-soundsound motion tapdelay line tap
moving-averagemoving window average triangle-wavetriangle wave
ncosn equal amplitude cosines two-poletwo pole filter
notchnotch filter two-zerotwo zero filter
nrxycosn scaled cosines wave-trainwave train
autocorrelateautocorrelation dot-productdot (scalar) product
amplitude-modulatesig1 * (car + sig2) fftFourier transform
array-interparray interpolation make-fft-windowvarious standard windows
contrast-enhancementmodulate signal polynomialHorner's rule
convolutionconvolve signals ring-modulatesig * sig
correlatecross correlation spectrumpower spectrum of signal
Introduction

Start Snd, open the listener (choose "Show listener" in the View menu), and:

> (load "v.scm")
fm-violin
> (with-sound () (fm-violin 0 1 440 .1))
"test.snd"

If all went well, you should see a graph of the fm-violin's output. Click the "play" button to hear it; click "f" to see its spectrum.

In Ruby, we'd do it this way:

>load "v.rb"
true
>with_sound() do fm_violin_rb(0, 1.0, 440.0, 0.1) end
#<With_CLM: output: "test.snd", channels: 1, srate: 22050>

and in Forth:

snd> "clm-ins.fs" file-eval
0
snd> 0.0 1.0 440.0 0.1 ' fm-violin with-sound
\ filename: test.snd

In most of this document, I'll stick with Scheme as implemented by s7. extsnd.html and sndscm.html have numerous Ruby and Forth examples, and I'll toss some in here as I go along. You can save yourself a lot of typing by using two features of the listener. First, <TAB> (that is, the key marked TAB) tries to complete the current name, so if you type "fm-<TAB>" the listener completes the name as "fm-violin". And second, you can back up to a previous expression, edit it, move the cursor to the closing parenthesis, and type <RETURN>, and that expression will be evaluated as if you had typed all of it in from the start. Needless to say, you can paste code from this file into the Snd listener.

with-sound opens an output sound file, evaluates its body, closes the file, and then opens it in Snd. If the sound is already open, with-sound replaces it with the new version. The body of with-sound can be any size, and can include anything that you could put in a function body. For example, to get an arpeggio:

(with-sound ()
  (do ((i 0 (+ i 1)))
      ((= i 8))
    (fm-violin (* i .25) .5 (* 100 (+ i 1)) .1)))

with-sound, instruments, CLM itself are all optional, of course. We could do everything by hand:

(let ((sound (new-sound "test.snd" :size 22050))
      (increment (/ (* 440.0 2.0 pi) 22050.0))
      (current-phase 0.0))
  (map-channel (lambda (y)
 	         (let ((val (* .1 (sin current-phase))))
                   (set! current-phase (+ current-phase increment))
                   val))))

This opens a sound file (via new-sound) and fills it with a .1 amplitude sine wave at 440 Hz. The "increment" calculation turns 440 Hz into a phase increment in radians (we could also use the function hz->radians). The "oscil" generator keeps track of the phase increment for us, so essentially the same thing using with-sound and oscil is:

(with-sound ()
  (let ((osc (make-oscil 440.0)))
    (do ((i 0 (+ i 1)))
        ((= i 44100))
      (outa i (* .1 (oscil osc)) *output*))))

*output* is the file opened by with-sound, and outa is a function that adds its second argument (the sinusoid) into the current output at the sample given by its first argument ("i" in this case). oscil is our sinusoid generator, created by make-oscil. You don't need to worry about freeing the oscil; we can depend on the Scheme garbage collector to deal with that. All the generators are like oscil in that each is a function that on each call returns the next sample in an infinite stream of samples. An oscillator, for example, returns an endless sine wave, one sample at a time. Each generator consists of a set of functions: make-<gen> sets up the data structure associated with the generator; <gen> produces a new sample; <gen>? checks whether a variable is that kind of generator. Current generator state is accessible via various generic functions such as mus-frequency:

(set! oscillator (make-oscil :frequency 330))

prepares "oscillator" to produce a sine wave when set in motion via

(oscil oscillator)

The make-<gen> function takes a number of optional arguments, setting whatever state the given generator needs to operate on. The run-time function's first argument is always its associated structure. Its second argument is nearly always something like an FM input or whatever run-time modulation might be desired. Frequency sweeps of all kinds (vibrato, glissando, breath noise, FM proper) are all forms of frequency modulation. So, in normal usage, our oscillator looks something like:

(oscil oscillator (+ vibrato glissando frequency-modulation))

One special aspect of each make-<gen> function is the way it reads its arguments. I use parenthesized parameters in the function definitions to indicate that the argument names are keywords, but the keywords themselves are optional. Take the make-oscil call, defined as:

make-oscil (frequency *clm-default-frequency*) (initial-phase 0.0)

This says that make-oscil has two optional arguments, frequency (in Hz), and initial-phase (in radians). The keywords associated with these values are :frequency and :initial-phase. When make-oscil is called, it scans its arguments; if a keyword is seen, that argument and all following arguments are passed unchanged, but if a value is seen, the corresponding keyword is prepended in the argument list:

(make-oscil :frequency 440.0)
(make-oscil :frequency 440.0 :initial-phase 0.0)
(make-oscil 440.0)
(make-oscil 440.0 :initial-phase 0.0)
(make-oscil 440.0 0.0)

are all equivalent, but

(make-oscil :frequency 440.0 0.0)
(make-oscil :initial-phase 0.0 440.0)

are in error, because once we see any keyword, all the rest of the arguments have to use keywords too (we can't reliably make any assumptions after that point about argument ordering). This style of argument passing is the same as that of s7's define*, and is very similar to the "Optional Positional and Named Parameters" extension of scheme: SRFI-89.

Since we often want to use a given sound-producing algorithm many times (in a note list, for example), it is convenient to package up that code into a function. Our sinewave could be rewritten:

(define (simp start end freq amp)
  (let ((os (make-oscil freq)))
    (do ((i start (+ i 1))) 
        ((= i end))
      (outa i (* amp (oscil os)))))) ; outa output defaults to *output* so we can omit it

Now to hear our sine wave:

(with-sound (:play #t) (simp 0 44100 330 .1))

This version of "simp" forces you to think in terms of sample numbers ("start" and "end") which are dependent on the sampling rate. Our first enhancement is to use seconds:

(define (simp beg dur freq amp)
  (let ((os (make-oscil freq))
        (start (seconds->samples beg))
        (end (seconds->samples (+ beg dur))))
    (do ((i start (+ i 1))) 
        ((= i end))
      (outa i (* amp (oscil os))))))

Now we can use any sampling rate, and call "simp" using seconds:

(with-sound (:srate 44100) (simp 0 1.0 440.0 0.1))

Next we turn the "simp" function into an "instrument". An instrument is a function that has a variety of built-in actions within with-sound. The only change is the word "definstrument":

(definstrument (simp beg dur freq amp)
  (let ((os (make-oscil freq))
        (start (seconds->samples beg))
        (end (seconds->samples (+ beg dur))))
    (do ((i start (+ i 1))) 
        ((= i end))
      (outa i (* amp (oscil os))))))

Now we can simulate a telephone:

(define (telephone start telephone-number)
  (let ((touch-tab-1 '(0 697 697 697 770 770 770 852 852 852 941 941 941))
	(touch-tab-2 '(0 1209 1336 1477 1209 1336 1477 1209 1336 1477 1209 1336 1477)))
    (do ((i 0 (+ i 1)))
	((= i (length telephone-number)))
      (let* ((num (telephone-number i))
	     (frq1 (touch-tab-1 num))
	     (frq2 (touch-tab-2 num)))
        (simp (+ start (* i .4)) .3 frq1 .1)
        (simp (+ start (* i .4)) .3 frq2 .1)))))

(with-sound () (telephone 0.0 '(7 2 3 4 9 7 1)))

As a last change, let's add an amplitude envelope:

(definstrument (simp beg dur freq amp envelope)
  (let ((os (make-oscil freq))
        (amp-env (make-env envelope :duration dur :scaler amp))
	(start (seconds->samples beg))
        (end (seconds->samples (+ beg dur))))
    (do ((i start (+ i 1))) 
        ((= i end))
      (outa i (* (env amp-env) (oscil os))))))

A CLM envelope is a list of (x y) break-point pairs. The x-axis bounds are arbitrary, but it is conventional (here at ccrma) to go from 0 to 1.0. The y-axis values are normally between -1.0 and 1.0, to make it easier to figure out how to apply the envelope in various different situations.

(with-sound () (simp 0 2 440 .1 '(0 0  0.1 1.0  1.0 0.0)))

Add a few more oscils and envs, and you've got the fm-violin. You can try out a generator or a patch of generators quickly by plugging it into the following with-sound call:

(with-sound () 
  (let ((sqr (make-square-wave 100))) ; test a square-wave generator
    (do ((i 0 (+ i 1))) 
        ((= i 10000)) 
      (outa i (square-wave sqr)))))

Many people find the syntax of "do" confusing. It's possible to hide that away in a macro:

(define-macro (output beg dur . body)
  `(do ((i (seconds->samples ,beg) (+ i 1)))
       ((= i (seconds->samples (+ ,beg ,dur))))
     (outa i (begin ,@body))))

(define (simp beg dur freq amp)
  (let ((o (make-oscil freq)))
    (output beg dur (* amp (oscil o)))))

(with-sound ()
  (simp 0 1 440 .1)
  (simp .5 .5 660 .1))

It's also possible to use recursion, rather than iteration:

(define (simp1)
  (let ((freq (hz->radians 440.0)))
    (let simp-loop ((i 0) (x 0.0))
      (outa i (sin x)) 
      (if (< i 44100)
	  (simp-loop (+ i 1) (+ x freq))))))

(define simp2
  (let ((freq (hz->radians 440.0)))
    (lambda* ((i 0) (x 0.0))
      (outa i (sin x))
      (if (< i 44100)
	  (simp2 (+ i 1) (+ x freq))))))

but the do-loop is faster.

Generators
oscil
make-oscil (frequency *clm-default-frequency*) (initial-phase 0.0)
oscil os (fm-input 0.0) (pm-input 0.0)
oscil? os

make-oscil-bank freqs phases amps stable
oscil-bank os fms
oscil-bank? os
oscil methods
mus-frequency frequency in Hz
mus-phase phase in radians
mus-length 1 (no set!)
mus-increment frequency in radians per sample

oscil produces a sine wave (using sin) with optional frequency change (FM). It might be defined:

(let ((result (sin (+ phase pm-input))))
  (set! phase (+ phase (hz->radians frequency) fm-input))
  result)

oscil's first argument is an oscil created by make-oscil. Oscil's second argument is the frequency change (frequency modulation), and the third argument is the phase change (phase modulation). The initial-phase argument to make-oscil is in radians. You can use degrees->radians to convert from degrees to radians. To get a cosine (as opposed to sine), set the initial-phase to (/ pi 2). Here are examples in Scheme, Ruby, and Forth:

(with-sound (:play #t)
  (let ((gen (make-oscil 440.0)))
    (do ((i 0 (+ i 1)))
        ((= i 44100))
      (outa i (* 0.5 (oscil gen))))))
with_sound(:play, true) do
  gen = make_oscil(440.0);
  44100.times do |i| 
    outa(i, 0.5 * oscil(gen), $output) 
    end
  end.output
lambda: ( -- )
  440.0 make-oscil { gen }
  44100 0 do
    i  gen 0 0 oscil  f2/ *output* outa drop
  loop
; :play #t with-sound drop

One slightly confusing aspect of oscil is that glissando has to be turned into a phase-increment envelope. This means that the frequency envelope y values should be passed through hz->radians:

(define (simp start end freq amp frq-env)
  (let ((os (make-oscil freq)) 
        (frqe (make-env frq-env :length (+ 1 (- end start)) :scaler (hz->radians freq))))
    (do ((i start (+ i 1))) 
        ((= i end))
      (outa i (* amp (oscil os (env frqe)))))))

(with-sound () (simp 0 10000 440 .1 '(0 0 1 1))) ; sweep up an octave

Here is an example of FM (here the hz->radians business is folded into the FM index):

(definstrument (simple-fm beg dur freq amp mc-ratio index amp-env index-env)
  (let* ((start (seconds->samples beg))
	 (end (+ start (seconds->samples dur)))
	 (cr (make-oscil freq))                     ; carrier
         (md (make-oscil (* freq mc-ratio)))        ; modulator
         (fm-index (hz->radians (* index mc-ratio freq)))
         (ampf (make-env (or amp-env '(0 0  .5 1  1 0)) :scaler amp :duration dur))
         (indf (make-env (or index-env '(0 0  .5 1  1 0)) :scaler fm-index :duration dur)))
    (do ((i start (+ i 1)))
        ((= i end))
      (outa i (* (env ampf) 
                 (oscil cr (* (env indf) 
                              (oscil md))))))))

;;; (with-sound () (simple-fm 0 1 440 .1 2 1.0))

fm.html has an introduction to FM. FM and PM behave slightly differently during a glissando; FM is the more "natural" in that, left to its own devices, it produces a spectrum that varies inversely with the pitch. Compare these two cases. Both involve a slow glissando up an octave, FM in channel 0, and PM in channel 1. In the first note, I fix up the FM index during the sweep to keep the spectra steady, and in the second, I fix up the PM index.

(with-sound (:channels 2)
  (let* ((dur 2.0)
	 (samps (seconds->samples dur))
	 (pitch 1000)
	 (modpitch 100)
	 (pm-index 4.0)
	 (fm-index (hz->radians (* 4.0 modpitch))))
    (let ((car1 (make-oscil pitch))
	  (mod1 (make-oscil modpitch))
	  (car2 (make-oscil pitch))
	  (mod2 (make-oscil modpitch))
	  (frqf (make-env '(0 0 1 1) :duration dur))
	  (ampf (make-env '(0 0 1 1 20 1 21 0) :duration dur :scaler .5)))
      (do ((i 0 (+ i 1)))
	  ((= i samps))
	(let* ((frq (env frqf))
	       (rfrq (hz->radians frq))
	       (amp (env ampf)))
	  (outa i (* amp (oscil car1 (+ (* rfrq pitch)
					(* fm-index (+ 1 frq) ; keep spectrum the same
					   (oscil mod1 (* rfrq modpitch)))))))
	  (outb i (* amp (oscil car2 (* rfrq pitch)
				(* pm-index (oscil mod2 (* rfrq modpitch)))))))))
    (let ((car1 (make-oscil pitch))
	  (mod1 (make-oscil modpitch))
	  (car2 (make-oscil pitch))
	  (mod2 (make-oscil modpitch))
	  (frqf (make-env '(0 0 1 1) :duration dur))
	  (ampf (make-env '(0 0 1 1 20 1 21 0) :duration dur :scaler .5)))
      (do ((i 0 (+ i 1)))
	  ((= i samps))
	(let* ((frq (env frqf))
	       (rfrq (hz->radians frq))
	       (amp (env ampf)))
	  (outa (+ i samps) (* amp (oscil car1 (+ (* rfrq pitch)
						  (* fm-index   ; let spectrum decay
						     (oscil mod1 (* rfrq modpitch)))))))
	  (outb (+ i samps) (* amp (oscil car2 (* rfrq pitch)
				          (* (/ pm-index (+ 1 frq)) (oscil mod2 (* rfrq modpitch)))))))))))

And if you read somewhere that PM can't produce a frequency shift:

(with-sound ()
  (let ((o (make-oscil 200.0))
        (e (make-env '(0 0 1 1) :scaler 300.0 :duration 1.0)))
    (do ((i 0 (+ i 1)))
        ((= i 44100))
      (outa i (oscil o 0.0 (env e))))))

To show CLM in its various embodiments, here are the Scheme, Common Lisp, Ruby, Forth, and C versions of the bird instrument; it produces a sinusoid with (usually very elaborate) amplitude and frequency envelopes.

(define (scheme-bird start dur frequency freqskew amplitude freq-envelope amp-envelope)
  (let* ((gls-env (make-env freq-envelope (hz->radians freqskew) dur))
         (os (make-oscil frequency))
         (amp-env (make-env amp-envelope amplitude dur))
	 (beg (seconds->samples start))
	 (end (+ beg (seconds->samples dur))))
   (do ((i beg (+ i 1)))
       ((= i end))
     (outa i (* (env amp-env) 
                (oscil os (env gls-env)))))))
(definstrument common-lisp-bird (startime dur frequency freq-skew amplitude freq-envelope amp-envelope)
  (multiple-value-bind (beg end) (times->samples startime dur)
    (let* ((amp-env (make-env amp-envelope amplitude dur))
	   (gls-env (make-env freq-envelope (hz->radians freq-skew) dur))
	   (os (make-oscil frequency)))
      (run
       (loop for i from beg to end do
	 (outa i (* (env amp-env) 
                    (oscil os (env gls-env)))))))))
def ruby_bird(start, dur, freq, freqskew, amp, freq_envelope, amp_envelope)
  gls_env = make_env(:envelope, freq_envelope, :scaler, hz2radians(freqskew), :duration, dur)
  os = make_oscil(:frequency, freq)
  amp_env = make_env(:envelope, amp_envelope, :scaler, amp, :duration, dur)
  run_instrument(start, dur) do
    env(amp_env) * oscil(os, env(gls_env))
  end
end
instrument: forth-bird { f: start f: dur f: freq f: freq-skew f: amp freqenv ampenv -- }
    :frequency freq make-oscil { os }
    :envelope ampenv :scaler amp :duration dur make-env { ampf }
    :envelope freqenv :scaler freq-skew hz>radians :duration dur make-env { gls-env }
    90e random :locsig-degree
    start dur run-instrument  ampf env  gls-env env os oscil-1  f*  end-run
    os gen-free
    ampf gen-free
    gls-env gen-free
;instrument
void c_bird(double start, double dur, double frequency, double freqskew, double amplitude, 
	    mus_float_t *freqdata, int freqpts, mus_float_t *ampdata, int amppts, mus_any *output)
{
  mus_long_t beg, end, i;
  mus_any *amp_env, *freq_env, *osc;
  beg = start * mus_srate();
  end = start + dur * mus_srate();
  osc = mus_make_oscil(frequency, 0.0);
  amp_env = mus_make_env(ampdata, amppts, amplitude, 0.0, 1.0, dur, 0, NULL);
  freq_env = mus_make_env(freqdata, freqpts, mus_hz_to_radians(freqskew), 0.0, 1.0, dur, 0, NULL);
  for (i = beg; i < end; i++)
    mus_sample_to_file(output, i, 0, 
		       mus_env(amp_env) * 
		         mus_oscil(osc, mus_env(freq_env), 0.0));
  mus_free(osc);
  mus_free(amp_env);
  mus_free(freq_env);
}

Many of the CLM synthesis functions try to make it faster or more convenient to produce a lot of sinusoids, but there are times when nothing but a ton of oscils will do:

(with-sound () 
 (let* ((peaks (list  23  0.0051914    32  0.0090310    63  0.0623477    123  0.1210755    185  0.1971876
		      209  0.0033631  247  0.5797809   309  1.0000000    370  0.1713255    432  0.9351965
		      481  0.0369873  495  0.1335089   518  0.0148626    558  0.1178001    617  0.6353443
		      629  0.1462804  661  0.0208941   680  0.1739281    701  0.0260423    742  0.1203807
		      760  0.0070301  803  0.0272111   865  0.0418878    926  0.0090197    992  0.0098687
		      1174  0.00444  1298  0.0039722  2223  0.0033486   2409  0.0083675   2472  0.0100995
		      2508  0.004262 2533  0.0216248  2580  0.0047732   2596  0.0088663   2612  0.0040592
		      2657  0.005971 2679  0.0032541  2712  0.0048836   2761  0.0050938   2780  0.0098877
		      2824  0.003421 2842  0.0134356  2857  0.0050194   2904  0.0147466   2966  0.0338878
		      3015  0.004832 3027  0.0095497  3040  0.0041434   3092  0.0044802   3151  0.0038269
		      3460  0.003633 3585  0.0050849  4880  0.0042301   5121  0.0037906   5136  0.0048349
		      5158  0.004336 5192  0.0037841  5200  0.0038025   5229  0.0035555   5356  0.0045781
		      5430  0.003687 5450  0.0055170  5462  0.0057821   5660  0.0041789   5673  0.0044932
		      5695  0.007370 5748  0.0031716  5776  0.0037921   5800  0.0062308   5838  0.0034629
		      5865  0.005942 5917  0.0032254  6237  0.0046164   6360  0.0034708   6420  0.0044593
		      6552  0.005939 6569  0.0034665  6752  0.0041965   7211  0.0039695   7446  0.0031611
		      7468  0.003330 7482  0.0046322  8013  0.0034398   8102  0.0031590   8121  0.0031972
		      8169  0.003345 8186  0.0037020  8476  0.0035857   8796  0.0036703   8927  0.0042374
		      9388  0.003173 9443  0.0035844  9469  0.0053484   9527  0.0049137   9739  0.0032365
		      9853  0.004297 10481  0.0036424  10490  0.0033786  10606  0.0031366))
	(len (/ (length peaks) 2))
	(dur 10)
	(oscs (make-vector len))
	(amps (make-vector len))
	(ramps (make-vector len))
	(freqs (make-vector len))
	(vib (make-rand-interp 50 (hz->radians .01)))
	(ampf (make-env '(0 0 1 1 10 1 11 0) :duration dur :scaler .1))
	(samps (seconds->samples dur)))

   (do ((i 0 (+ i 1)))
       ((= i len))
     (set! (freqs i) (peaks (* i 2)))
     (set! (oscs i) (make-oscil (freqs i) (random pi)))
     (set! (amps i) (peaks (+ 1 (* 2 i))))
     (set! (ramps i) (make-rand-interp (+ 1.0 (* i (/ 20.0 len))) 
				       (* (+ .1 (* i (/ 3.0 len))) (amps i)))))
  (do ((i 0 (+ i 1)))
      ((= i samps))
    (let ((sum 0.0)
          (fm (rand-interp vib)))
      (do ((k 0 (+ k 1)))
          ((= k len))
        (set! sum (+ sum (* (+ (amps k)
		               (rand-interp (ramps k)))
		            (oscil (oscs k) (* (freqs k) fm))))))
  (outa i (* (env ampf) sum))))))

oscil-bank here would be faster, or mus-chebyshev-t-sum:

...
(amps (make-float-vector 10607))
(angle 0.0)
(freq (hz->radians 1.0))
...
(do ((i 0 (+ i 1))
     (k 0 (+ k 2)))
    ((= i len))
  (set! (amps (peaks k)) (peaks (+ k 1))))
...
 (outa i (* (env ampf) (mus-chebyshev-t-sum angle amps)))
 (set! angle (+ angle freq (rand-interp vib)))
...

Here's a better example: we want to start with a sum of equal amplitude harmonically related cosines (a sequence of spikes), and move slowly to a waveform with the same magnitude spectrum, but with the phases chosen to minimize the peak amplitude.

(let ((98-phases #(0.000000 -0.183194 0.674802 1.163820 -0.147489 1.666302 0.367236 0.494059 0.191339 
                   0.714980 1.719816 0.382307 1.017937 0.548019 0.342322 1.541035 0.966484 0.936993 
                   -0.115147 1.638513 1.644277 0.036575 1.852586 1.211701 1.300475 1.231282 0.026079 
 		   0.393108 1.208123 1.645585 -0.152499 0.274978 1.281084 1.674451 1.147440 0.906901 
		   1.137155 1.467770 0.851985 0.437992 0.762219 -0.417594 1.884062 1.725160 -0.230688 
		   0.764342 0.565472 0.612443 0.222826 -0.016453 1.527577 -0.045196 0.585089 0.031829 
		   0.486579 0.557276 -0.040985 1.257633 1.345950 0.061737 0.281650 -0.231535 0.620583 
		   0.504202 0.817304 -0.010580 0.584809 1.234045 0.840674 1.222939 0.685333 1.651765 
		   0.299738 1.890117 0.740013 0.044764 1.547307 0.169892 1.452239 0.352220 0.122254 
		   1.524772 1.183705 0.507801 1.419950 0.851259 0.008092 1.483245 0.608598 0.212267	
		   0.545906 0.255277 1.784889 0.270552 1.164997 -0.083981 0.200818 1.204088)))
  (let ((freq 10.0)
	(dur 5.0)
	(n 98))
    (with-sound ()
      (let ((samps (floor (* dur 44100)))
	    (1/n (/ 1.0 n))
	    (freqs (make-float-vector n))
	    (phases (make-float-vector n (* pi 0.5))))
	(do ((i 0 (+ i 1)))
	    ((= i n))
	  (let ((off (/ (* pi (- 0.5 (98-phases i))) (* dur 44100)))
		(h (hz->radians (* freq (+ i 1)))))
	    (set! (freqs i) (+ h off))))
	(let ((ob (make-oscil-bank freqs phases)))
	  (do ((i 0 (+ i 1))) ; get rid of the distracting initial click
	      ((= i 1000))
	    (oscil-bank ob))
	  (do ((k 0 (+ k 1)))
	      ((= k samps))
	    (outa k (* 1/n (oscil-bank ob)))))))))

The last argument to make-oscil-bank, "stable", defaults to false. If it is true, oscil-bank can assume that the frequency, phase, and amplitude values passed to make-oscil-bank will not change over the life of the generator.

Related generators are ncos, nsin, asymmetric-fm, and nrxysin. Some instruments that use oscil are bird and bigbird, fm-violin (v), lbj-piano (clm-ins.scm), vox (clm-ins.scm), and fm-bell (clm-ins.scm). Interesting extensions of oscil include the various summation formulas in generators.scm. To goof around with FM from a graphical interface, see bess.scm and bess1.scm.

When oscil's frequency is high relative to the sampling rate, the waveform it produces may not look very sinusoidal. Here, for example, is oscil at 440 Hz when the srate is 1000, 4000, and 16000:

effect of different srates
env
make-env 
      envelope      ; list or float-vector of x,y break-point pairs
      (scaler 1.0)  ; scaler on every y value (before offset is added)
      duration      ; duration in seconds
      (offset 0.0)  ; value added to every y value
      base          ; type of connecting line between break-points
      end           ; end sample number (obsolete, use length)
      length        ; duration in samples

env e
env? e

env-interp x env (base 1.0) ;value of env at x
env-any e connecting-function
envelope-interp x env (base 1.0)

make-pulsed-env envelope duration frequency
pulsed-env gen (fm 0.0)
pulsed-env? gen
env methods
mus-location number of calls so far on this env
mus-incrementbase
mus-data original breakpoint list
mus-scaler scaler
mus-offset offset
mus-length duration in samples
mus-channels current position in the break-point list

An envelope is a list or float-vector of break point pairs: '(0 0 100 1) is a ramp from 0 to 1 over an x-axis excursion from 0 to 100, as is (float-vector 0 0 100 1). This data is passed to make-env along with the scaler (multiplier) applied to the y axis, the offset added to every y value, and the time in samples or seconds that the x axis represents. make-env returns an env generator. env then returns the next sample of the envelope each time it is called. Say we want a ramp moving from .3 to .5 during 1 second.

    (make-env '(0 0  100 1) :scaler .2 :offset .3 :duration 1.0)
    (make-env '(0 .3  1 .5) :duration 1.0)

I find the second version easier to read. The first is handy if you have a bunch of stored envelopes. To specify the breakpoints, you can also use the form '((0 0) (100 1)).

an envelope
(with-sound (:play #t)
  (let ((gen (make-oscil 440.0))
        (ampf (make-env '(0 0  .01 1  .25 .1 1 0)
	        :scaler 0.5
                :length 44100)))
    (do ((i 0 (+ i 1)))
        ((= i 44100))
      (outa i (* (env ampf) (oscil gen))))))
with_sound(:play, true) do
  gen = make_oscil(440.0);
  ampf = make_env(
          [0, 0, 0.01, 1.0, 0.25, 0.1, 1, 0],
          :scaler, 0.5,
          :length, 44100);
  44100.times do |i| 
    outa(i, env(ampf) * oscil(gen), $output) 
    end
  end.output
lambda: ( -- )
  440.0 make-oscil { gen }
  '( 0 0 0.01 1 0.25 0.1 1 0 )
  :scaler 0.5 :length 44100 make-env { ampf }
  44100 0 do
    i  gen 0 0 oscil  ampf env  f* *output*  outa drop
  loop
; :play #t with-sound drop

The base argument determines how the break-points are connected. If it is 1.0 (the default), you get straight line segments. If base is 0.0, you get a step function (the envelope changes its value suddenly to the new one without any interpolation). Any other positive value affects the exponent of the exponential curve connecting the points. A base less than 1.0 gives convex curves (i.e. bowed out), and a base greater than 1.0 gives concave curves (i.e. sagging). If you'd rather think in terms of e^-kt, set the base to (exp k).

base .03 choice base 32 choice

You can get a lot from a couple of envelopes:

> (load "animals.scm")
#<unspecified>
> (with-sound (:play #t) (pacific-chorus-frog 0 .5))
"test.snd"
> (with-sound (:play #t) (house-finch 0 .5))
"test.snd"

There are several ways to get arbitrary connecting curves between the break points. The simplest method is to treat the output of env as the input to the connecting function. Here's an instrument that maps the line segments into sin x^3:

(definstrument (mapenv beg dur frq amp en)
  (let* ((start (seconds->samples beg))
	 (end (+ start (seconds->samples dur)))
	 (osc (make-oscil frq))
	 (zv (make-env en 1.0 dur)))
   (do ((i start (+ i 1)))
       ((= i end))
     (let ((zval (env zv))) 
       (outa i 
         (* amp 
            (sin (* 0.5 pi zval zval zval)) 
            (oscil osc)))))))

(with-sound () 
  (mapenv 0 1 440 .5 '(0 0  50 1  75 0  86 .5  100 0)))
sin cubed envelope

Another method is to write a function that traces out the curve you want. J.C.Risset's bell curve is:

(define (bell-curve x)
  ;; x from 0.0 to 1.0 creates bell curve between .64e-4 and nearly 1.0
  ;; if x goes on from there, you get more bell curves; x can be
  ;; an envelope (a ramp from 0 to 1 if you want just a bell curve)
  (+ .64e-4 (* .1565 (- (exp (- 1.0 (cos (* 2 pi x)))) 1.0))))

But the most flexible method is to use env-any. env-any takes the env generator that produces the underlying envelope, and a function to "connect the dots", and returns the new envelope applying that connecting function between the break points. For example, say we want to square each envelope value:

(with-sound ()
  (let ((e (make-env '(0 0 1 1 2 .25 3 1 4 0) 
                     :duration 0.5)))
    (do ((i 0 (+ i 1)))
	((= i 44100))
      (outa i (env-any e (lambda (y) (* y y)))))))

;; or connect the dots with a sinusoid:

(define (sine-env e)
  (env-any e (lambda (y)
	       (* 0.5 (+ 1.0 (sin (+ (* -0.5 pi) 
				     (* pi y))))))))

(with-sound ()
  (let ((e (make-env '(0 0 1 1 2 .25 3 1 4 0)
                     :duration 0.5)))
   (do ((i 0 (+ i 1)))
       ((= i 44100))
     (outa i (sine-env e)))))
env-any pix

The env-any connecting function takes one argument, the current envelope value treated as going between 0.0 and 1.0 between each two points. It returns a value that is then fitted back into the original (scaled, offset) envelope. There are a couple more of these functions in generators.scm, one to apply a blackman4 window between the points, and the other to cycle through a set of exponents.

mus-reset of an env causes it to start all over again from the beginning. mus-reset is called internally if you use mus-scaler to set an env's scaler (and similarly for offset and length). To jump to any position in an env, use mus-location. Here's a function that uses these methods to apply an envelope over and over:

(define (strum e)
  (map-channel (lambda (y)
		 (if (> (mus-location e) (mus-length e)) ; mus-length = dur
		     (mus-reset e))     ; start env again (default is to stick at the last value)
		 (* y (env e)))))

;;; (strum (make-env (list 0 0 1 1 10 .6 25 .3 100 0) :length 2000))

To copy an env while changing one aspect (say duration), it's simplest to use make-env:

(define (change-env-dur e dur)
  (make-env (mus-data e) :scaler (mus-scaler e) :offset (mus-offset e) :base (mus-increment e)
	    :duration dur))

make-env signals an error if the envelope breakpoints are either out of order, or an x axis value occurs twice. The default error handler in with-sound may not give you the information you need to track down the offending note, even given the original envelope. Here's one way to trap the error and get more info (in this case, the begin time and duration of the enclosing note):

(define* (make-env-with-catch beg dur :rest args)
  (catch 'mus-error
	 (lambda ()
	   (apply make-env args))
	 (lambda args
	   (format #t ";~A ~A: ~A~%" beg dur args))))

(envelope-interp x env base) returns value of 'env' at 'x'. If 'base' is 0, 'env' is treated as a step function; if 'base' is 1.0 (the default), the breakpoints of 'env' are connected by a straight line, and any other 'base' connects the breakpoints with a kind of exponential curve:

> (envelope-interp .1 '(0 0 1 1))
0.1
> (envelope-interp .1 '(0 0 1 1) 32.0)
0.0133617278184869
> (envelope-interp .1 '(0 0 1 1) .012)
0.361774730775292

The corresponding function for a CLM env generator is env-interp. If you'd rather think in terms of e^-kt, set the 'base' to (exp k).

pulsed-env produces a repeating envelope. env sticks at its last value, but pulsed-env repeats it over and over. "duration" is the envelope duration, and "frequency" is the repeitition rate, changeable via the "fm" argument to the pulsed-env generator.

An envelope applied to the amplitude of a signal is a form of amplitude modulation, and glissando is frequency modulation. Both cause a broadening of the spectral components:

amp env spectrum frq env spectrum
truncated pyramid amplitude envelope
multiplied by sinusoid at 50Hz
truncated pyramid frquency envelope
sinusoid from 100Hz to 300Hz

The amplitude case reflects the spectrum of the amplitude envelope all by itself, translated (by multiplication) up to the sinusoid's pitch. The sidebands are about 1 Hz apart (the envelope takes 1 second to go linearly from 0 to 1). Despite appearances, we hear this (are you sitting down?) as a changing amplitude, not a timbral mess. Spectra can be tricky to interpret, and I've tried to choose parameters for this display that emphasize the broadening.


Envelopes

Various operations on envelopes:

env.scm:
add-envelopes            add two envelopes
concatenate-envelopes    concatenate a bunch of envelopes
envelope-exp             interpolate points to approximate exponential curves
envelope-interp          return the value of an envelope given the x position
envelope-last-x          return the last x value in an envelope
intergrate-envelope      return the area under an envelope
make-power-env           exponential curves with multiple exponents (see also multi-expt-env in generators.scm)
map-envelopes            apply a function to the breakpoints in two envelopes, returning a new envelope
max-envelope             return the maximum y value in an envelope (also min-envelope)
multiply-envelopes       multiply two envelopes
normalize-envelope       scale the y values of an envelope to peak at 1.0
repeat-envelope          concatenate copies of an envelope
reverse-envelope         reverse the breakpoints in an envelope
scale-envelope           scale and offset the y values of an envelope
stretch-envelope         apply attack and decay times to an envelope ("adsr", or "divenv")
window-envelope          return the portion of an envelope within given x axis bounds
envelope sound: env-channel, env-sound
other enveloping functions: ramp-channel, xramp-channel, smooth-channel
envelope editor: Edit or View and Envelope
panning: place-sound in examp.scm
read sound indexed through envelope: env-sound-interp
repeating envelope: pulsed-env
step envelope in pitch: brassy in generators.scm
table-lookup
make-table-lookup 
        (frequency *clm-default-frequency*) ; table repetition rate in Hz
        (initial-phase 0.0)                 ; starting point in radians (pi = mid-table)
        wave                                ; a float-vector containing the signal
        (size *clm-table-size*)             ; table size if wave not specified
        (type mus-interp-linear)            ; interpolation type

table-lookup tl (fm-input 0.0)
table-lookup? tl

make-table-lookup-with-env frequency env size
table-lookup methods
mus-frequencyfrequency in Hz
mus-phasephase in radians
mus-datawave float-vector
mus-lengthwave size (no set!)
mus-interp-typeinterpolation choice (no set!)
mus-incrementtable increment per sample

table-lookup performs interpolating table lookup with a lookup index that moves through the table at a speed set by make-table-lookup's "frequency" argument and table-lookup's "fm-input" argument. That is, the waveform in the table is produced repeatedly, the repetition rate set by the frequency arguments. Table-lookup scales its fm-input argument to make its table size appear to be two pi. The intention here is that table-lookup with a sinusoid in the table and a given FM signal produces the same output as oscil with that FM signal. The "type" argument sets the type of interpolation used: mus-interp-none, mus-interp-linear, mus-interp-lagrange, or mus-interp-hermite. make-table-lookup-with-env (defined in generators.scm) returns a new table-lookup generator with the envelope 'env' loaded into its table. table-lookup might be defined:

(let ((result (array-interp wave phase)))
  (set! phase (+ phase 
                 (hz->radians frequency)
                 (* fm-input
                    (/ (length wave) 
                       (* 2 pi)))))
  result)
(with-sound (:play #t)
  (let ((gen (make-table-lookup 440.0 :wave (partials->wave '(1 .5  2 .5)))))
    (do ((i 0 (+ i 1)))
        ((= i 44100))
      (outa i (* 0.5 (table-lookup gen))))))
with_sound(:play, true) do
  gen = make_table_lookup(440.0, :wave, partials2wave([1.0, 0.5, 2.0, 0.5]));
  44100.times do |i| 
    outa(i, 0.5 * table_lookup(gen), $output) 
    end
  end.output
lambda: ( -- )
  440.0 :wave '( 1 0.5  2 0.5 ) #f #f partials->wave make-table-lookup { gen }
  44100 0 do
    i  gen 0 table-lookup  f2/ *output* outa drop
  loop
; :play #t with-sound drop

In the past, table-lookup was often used for additive synthesis, so there are two functions that make it easier to load up various such waveforms:

partials->wave synth-data wave (norm #t)
phase-partials->wave synth-data wave (norm #t)

The "synth-data" argument is a list or float-vector of (partial amp) pairs: '(1 .5 2 .25) gives a combination of a sine wave at the carrier (partial = 1) at amplitude .5, and another at the first harmonic (partial = 2) at amplitude .25. The partial amplitudes are normalized to sum to a total amplitude of 1.0 unless the argument "norm" is #f. If the initial phases matter (they almost never do), you can use phase-partials->wave; in this case the synth-data is a list or float-vector of (partial amp phase) triples with phases in radians. If "wave" is not passed, these functions return a new float-vector.

(definstrument (simple-table dur)
  (let ((tab (make-table-lookup :wave (partials->wave '(1 .5  2 .5)))))
    (do ((i 0 (+ i 1))) ((= i dur))
      (outa i (* .3 (table-lookup tab))))))

table-lookup can also be used as a sort of "freeze" function, looping through a sound repeatedly, based on some previously chosen loop positions:

(define (looper start dur sound freq amp)
  (let* ((beg (seconds->samples start))
         (end (+ beg (seconds->samples dur)))
         (loop-data (mus-sound-loop-info sound)))
    (if (or (null? loop-data)
            (<= (cadr loop-data) (car loop-data)))
        (error 'no-loop-positions)
        (let* ((loop-start (car loop-data))
               (loop-end (cadr loop-data))
               (loop-length (+ 1 (- loop-end loop-start)))
               (sound-section (file->array sound 0 loop-start loop-length (make-float-vector loop-length 0.0)))
               (original-loop-duration (/ loop-length (srate sound)))
               (tbl (make-table-lookup :frequency (/ freq original-loop-duration) :wave sound-section)))
               ;; "freq" here is how fast we read (transpose) the sound — 1.0 returns the original
         (do ((i beg (+ i 1)))
             ((= i end))
           (outa i (* amp (table-lookup tbl))))))))

(with-sound (:srate 44100) (looper 0 10 "/home/bil/sf1/forest.aiff" 1.0 0.5))

And for total confusion, here's a table-lookup that modulates a sound where we specify the modulation deviation in samples:

(definstrument (fm-table file start dur amp read-speed modulator-freq index-in-samples)
  (let* ((beg (seconds->samples start))
         (end (+ beg (seconds->samples dur)))
         (table-length (mus-sound-framples file))
         (tab (make-table-lookup :frequency (/ read-speed (mus-sound-duration file)) 
                                 :wave (file->array file 0 0 table-length (make-float-vector table-length 0.0))))
         (osc (make-oscil modulator-freq))
         (index (/ (* (hz->radians modulator-freq) 2 pi index-in-samples) table-length)))
   (do ((i beg (+ i 1)))
       ((= i end))
     (outa i (* amp (table-lookup tab (* index (oscil osc))))))))

Lessee.. there's a factor of table-length/(2*pi) in table-lookup, so that a table with a sinusoid behaves the same as an oscil even with FM; hz->radians adds a factor of (2*pi)/srate; so we've cancelled the internal 2*pi and table-length, and we have an actual deviation of mfreq*2*pi*index/srate, which looks like FM; hmmm. See srcer below for an src-based way to do the same thing.

There is one annoying problem with table-lookup: noise. Say we have a sine wave in a table with L elements, and we want to read it at a frequency of f Hz at a sampling rate of Fs. This requires that we read the table at locations that are multiples of L * f / Fs. This is ordinarily not an integer (that is, we've fallen between the table elements). We have no data between the elements, but we can make (plenty of) assumptions about what ought to be there. In the no-interpolation case (type = mus-interp-none), we take the floor of the table-relative phase, returning a squared-off sine-wave:

squared-off sine spectra

In addition to the sine at 100 Hz, we're getting lots of pairs of components, each pair centered around n * L * f, (10000 = 100 * 100 is the first), and separated from it by f, (9900 and 10100), and the amplitude of each pair is 1/(nL): -40 dB is 1/100 for the n=1 case. This spectrum says "amplitude modulation" (the fast square wave times the slow sinusoid). After scribbling a bit on the back of an envelope, we announce with a confident air that the sawtooth error signal gives us the 1/n (it is a sum of sin nx/n), and its amplitude gives us the 1/L. Now we try linear interpolation (mus-interp-linear), and get the same components as before, but the amplitude is going (essentially) as 1.0 / (n * n * L * L). So the interpolation reduces the original problem by a factor of n * L:

squared-off sine spectra

We can view this also as amplitude modulation: the sinusoid at frequency f times the little blip during each table sample at frequency L * f. Each component is at n * L * f, as before, and split in half by the modulation. Since L * f is normally a very high frequency, and sampling rates are not in the megahertz range (as in our examples), these components alias to such an extent that they look like noise, but they are noise only in the sense that we wish they weren't there.

The table length (L above) is the "effective" length. If we store an nth harmonic in the table, each period gets L/n elements (we want to avoid clicks caused by discontinuities between the first and last table elements), so the amplitude of the nth harmonic's noise components is higher (by n^2) than the fundamental's. We either have to use enormous tables or stick to low numbered partials. To keep the noise components out of sight in 16-bit output (down 90 dB), we need 180 elements per period. So a table with a 50th harmonic has to be at least length 8192. It's odd that the cutoff here is so similar to the waveshaping case; a 50-th harmonic is trouble in either case. (This leaves an opening for ncos and friends even when dynamic spectra aren't the issue).

We can try fancier interpolations. mus-interp-lagrange and mus-interp-hermite reduce the components (which are at the same frequencies as before) by about another factor of L. But these interpolations are expensive and ugly. If you're trying to produce a sum of sinusoids, use polywave — it makes a monkey out of table lookup in every case.

table-lookup of a sine (or some facsimile thereof) probably predates Ptolemy. One neat method of generating the table is that of Bhaskara I, AD 600, India, mentioned in van Brummelen, "The Mathematics of the Heavens and the Earth": use the rational approximation 4x(180-x)/(40500-x(180-x)), x in degrees, or more readably: 4x(pi-x)/(12.337-x(pi-x)), x in radians. The maximum error is 0.00163 at x=11.54 (degrees)!

spectr.scm has a steady state spectra of several standard orchestral instruments, courtesy of James A. Moorer. The drone instrument in clm-ins.scm uses table-lookup for the bagpipe drone. two-tab in the same file interpolates between two tables. See also grani.

polywave, polyshape
make-polywave 
         (frequency *clm-default-frequency*) 
         (partials '(1 1))                   ; a list of harmonic numbers and their associated amplitudes
         (type mus-chebyshev-first-kind)     ; Chebyshev polynomial choice
         xcoeffs ycoeffs                     ; tn/un for tu-sum case

polywave w (fm 0.0)
polywave? w

make-polyshape 
        (frequency *clm-default-frequency*) 
        (initial-phase 0.0) 
        coeffs 
        (partials '(1 1)) 
        (kind mus-chebyshev-first-kind)

polyshape w (index 1.0) (fm 0.0)
polyshape? w

partials->polynomial partials (kind mus-chebyshev-first-kind)
normalize-partials partials

mus-chebyshev-tu-sum x t-coeffs u-coeffs
mus-chebyshev-t-sum x t-coeffs
mus-chebyshev-u-sum x u-coeffs
polywave methods
mus-frequencyfrequency in Hz
mus-scalerindex
mus-phasephase in radians
mus-datapolynomial coeffs
mus-lengthnumber of partials
mus-incrementfrequency in radians per sample

These two generators drive a sum of scaled Chebyshev polynomials with a cosine, creating a sort of cross between additive synthesis and FM; see "Digital Waveshaping Synthesis" by Marc Le Brun in JAES 1979 April, vol 27, no 4, p250. The basic idea is:

Cheby eqs

We can add scaled Tns (polynomials) to get the spectrum we want, producing in the simplest case an inexpensive additive synthesis. We can vary the peak amplitude of the input (cos theta) to get effects similar to those of FM. polyshape uses a prebuilt sum of Chebyshev polynomials, whereas polywave uses the underlying Chebyshev recursion. polywave is stable and noise-free even with high partial numbers (I've tried it with 16384 harmonics). The "partials" argument to the make function can be either a list or a float-vector ("vct" in Ruby and Forth). The "type" or "kind" argument determines which kind of Chebyshev polynomial is used internally: mus-chebyshev-first-kind (Tn) which produces a sum of cosines, or mus-chebyshev-second-kind (Un), which produces a sum of sines.

(with-sound (:play #t)
  (let ((gen (make-polywave 440.0 :partials '(1 .5  2 .5))))
    (do ((i 0 (+ i 1)))
        ((= i 44100))
      (outa i (* 0.5 (polywave gen))))))
with_sound(:play, true) do
  gen = make_polywave(440.0, :partials, [1.0, 0.5, 2.0, 0.5]);
  44100.times do |i| 
    outa(i, 0.5 * polywave(gen), $output) 
    end
  end.output
lambda: ( -- )
  440.0 :partials '( 1 0.5 2 0.5 ) make-polywave { gen }
  44100 0 do
    i  gen 0 polywave  f2/ *output* outa drop
  loop
; :play #t with-sound drop

normalize-partials takes the list or float-vector of partial number and amplitudes, and returns a float-vector with the amplitudes normalized so that their magnitudes add to 1.0.

> (normalize-partials '(1 1 3 2 6 1))
#(1.0 0.25 3.0 0.5 6.0 0.25);
> (normalize-partials (float-vector 1 .1 2 .1 3 -.2))
#(1.0 0.25 2.0 0.25 3.0 -0.5)

partials->polynomial takes a list or float-vector of partial numbers and amplitudes and returns the Chebyshev polynomial coefficients that produce that spectrum. These coefficients can be passed to polyshape (the coeffs argument), or used directly by polynomial (there are examples of both below).

> (partials->polynomial '(1 1 3 2 6 1))
#(-1.0 -5.0 18.0 8.0 -48.0 0.0 32.0)
> (partials->polynomial '(1 1 3 2 6 1) mus-chebyshev-second-kind)
#(-1.0 6.0 8.0 -32.0 0.0 32.0 0.0)
> (partials->polynomial (float-vector 1 .1 2 .1 3 -.2))
#(-0.1 0.7 0.2 -0.8)

mus-chebyshev-tu-sum and friends perform the same function as partials->polynomial, but use the much more stable and accurate underlying recursion (see below for a long-winded explanation). They are the innards of the polywave and polyoid generators. The arguments are "x" (normally a phase), and one or two float-vectors of component amplitudes. These functions makes it easy to do additive synthesis with any number of harmonics (I've tried 16384), each with arbitrary initial-phase and amplitude, and each harmonic independently changeable in phase and amplitude at run-time by setting a float-vector value.

(let ((result (polynomial wave (cos phase))))
  (set! phase (+ phase (hz->radians frequency) fm))
  result)

In its simplest use, waveshaping is additive synthesis:

(with-sound ()
  (let ((wav (make-polyshape 
               :frequency 500.0
               :partials '(1 .5  2 .3  3 .2))))
    (do ((i 0 (+ i 1))) ((= i 40000))
      (outa i (polyshape wav)))))
waveshaping

Say we want every third harmonic at amplitude 1/sqrt(harmonic-number) for 5 harmonics total:

(with-sound (:clipped #f :statistics #t :play #t :scaled-to .5)
  (let ((gen (make-polywave 200 (let ((harms (make-float-vector (* 5 2) 0.0))) ; 5 harmonics, 2 numbers for each
				   (do ((k 1 (+ k 3))
					(i 0 (+ i 2)))
				       ((= i (* 5 2)))
				     (set! (harms i) k) ; harmonic number (k*freq)
				     (set! (harms (+ i 1)) (/ 1.0 (sqrt k)))) ; harmonic amplitude
				   harms)))
	(ampf (make-env '(0 0 1 1 10 1 11 0) :duration 1.0 :scaler .5)))
    (do ((i 0 (+ i 1)))
	((= i 44100))
      (outa i (* (env ampf) (polywave gen))))))

See animals.scm for many more examples along these lines. normalize-partials makes sure that the component amplitudes (magnitudes) add to 1.0. Its argument can be either a list or float-vector, but it always returns a float-vector. The fm-violin uses polyshape for the multiple FM section in some cases. The pqw and pqwvox instruments use both kinds of Chebyshev polynomials to produce single side-band spectra. Here is a somewhat low-level example:

(definstrument (pqw start dur spacing carrier partials)
  (let* ((spacing-cos (make-oscil spacing (/ pi 2.0)))
	 (spacing-sin (make-oscil spacing))
	 (carrier-cos (make-oscil carrier (/ pi 2.0)))
	 (carrier-sin (make-oscil carrier))
	 (sin-coeffs (partials->polynomial
                       partials mus-chebyshev-second-kind))
	 (cos-coeffs (partials->polynomial
                       partials mus-chebyshev-first-kind))
	 (beg (seconds->samples start))
	 (end (+ beg (seconds->samples dur))))
    (do ((i beg (+ i 1))) 
        ((= i end))
      (let ((ax (oscil spacing-cos)))
        (outa i (- (* (oscil carrier-sin) 
                      (oscil spacing-sin) 
	              (polynomial sin-coeffs ax))
	           (* (oscil carrier-cos) 
	              (polynomial cos-coeffs ax))))))))
pqw example
(with-sound () (pqw 0 1 200.0 1000.0 '(2 .2 3 .3 6 .5)))

We can use waveshaping to make a band-limited triangle-wave:

(define* (make-band-limited-triangle-wave (frequency *clm-default-frequency*) (order 1))
  (let ((freqs ()))
    (do ((i 1 (+ i 1))
	 (j 1 (+ j 2)))
	((> i order))
      (set! freqs (cons (/ 1.0 (* j j)) (cons j freqs))))
    (make-polywave frequency :partials (reverse freqs))))

(define* (band-limited-triangle-wave gen (fm 0.0))
  (polywave gen fm))

Band-limited square or sawtooth waves:

(definstrument (bl-saw start dur frequency order)
  (let ((norm (if (= order 1) 1.0     ; these peak amps were determined empirically
                 (if (= order 2) 1.3   ;   actual limit is supposed to be pi/2 (G&R 1.441)
                   (if (< order 9) 1.7 ;   but Gibbs phenomenon pushes it to 1.851
                     1.852))))
        (freqs ()))
    (do ((i 1 (+ i 1)))
	((> i order))
      (set! freqs (cons (/ 1.0 (* norm i)) (cons i freqs))))
    (let* ((gen (make-polywave frequency :partials (reverse freqs) :type mus-chebyshev-second-kind))
	   (beg (seconds->samples start))
	   (end (+ beg (seconds->samples dur))))
     (do ((i beg (+ i 1))) 
         ((= i end))
       (outa i (polywave gen))))))

The "fm" argument to these generators is intended mainly for vibrato and frequency envelopes. If you use it for frequency modulation, you'll notice that the result is not the necessarily same as applying that modulation to the equivalent bank of oscillators, but it is the same as (for example) applying it to an ncos generator, or most of the other generators (table-lookup, nsin, etc). The polynomial in cos(x) produces a sum of cos(nx) for various "n", but if "x" is itself a sinusoid, its effective index includes the factor of "n" (the partial number). This is what you want if all the components should move together (as in vibrato). If you need better control of the FM spectrum, use a bank of oscils where you can set each index independently. Here we used '(1 1 2 1 3 1) and polyshape with sinusoidal FM with an index of 1.

polyshape fm

The same thing happens if you use polyshape or ncos (or whatever) as the (complex) modulating signal to an oscil (the reverse of the situation above). The effective index of each partial is divided by the partial number (and in ncos, for example, the output is scaled to be -1..1, so that adds another layer of confusion). There's a longer discussion of this under ncos.

To get the FM effect of a spectrum centered around a carrier, multiply the waveshaping output by the carrier (the 0Hz term gives us the carrier):

(with-sound ()
  (let ((modulator (make-polyshape 100.0 :partials (list 0 .4  1 .4  2 .1  3 .05  4 .05)))
	(carrier (make-oscil 1000.0)))
    (do ((i 0 (+ i 1))) ((= i 20000))
      (outa i (* .5 (oscil carrier) (polyshape modulator))))))

The simplest way to get changing spectra is to interpolate between two or more sets of coefficients.

(+ (* interp (polywave p1 ...))  ; see animals.scm for many examples
   (* (- 1.0 interp) (polywave p2 ...)))

Or use mus-chebyshev-*-sum and set the component amplitudes directly:

(with-sound ()
  (let* ((dur 1.0)
	 (samps (seconds->samples dur))
	 (coeffs (float-vector 0.0 0.5 0.25 0.125 0.125))
	 (x 0.0)
	 (incr (hz->radians 100.0))
	 (ampf (make-env '(0 0 1 1 10 1 11 0) :duration dur :scaler .5))
	 (harmf (make-env '(0 .125 1 .25) :duration dur)))
    (do ((i 0 (+ i 1)))
	((= i samps))
      (let ((harm (env harmf)))
	(set! (coeffs 3) harm)
	(set! (coeffs 4) (- .25 harm))
	(outa i (* (env ampf)
		   (mus-chebyshev-t-sum x coeffs)))
	(set! x (+ x incr))))))

But we can also vary the index (the amplitude of the cosine driving the sum of polynomials), much as in FM. The kth partial's amplitude at a given index, given a set h[k] of coefficients, is:

cheby hka calc

(This formula is implemented by cheby-hka in dsp.scm). The function traced out by the harmonic (analogous to the role the Bessel function Jn plays in FM) is a polynomial in the index whose order depends on the number of coefficients. When the index is less than 1.0, energy appears in lower harmonics even if they are not included in the index=1.0 list:

> (cheby-hka 3 0.25 (float-vector 0 0 0 0 1.0 1.0))
-0.0732421875
> (cheby-hka 2 0.25 (float-vector 0 0 0 0 1.0 1.0))
-0.234375
> (cheby-hka 1 0.25 (float-vector 0 0 0 0 1.0 1.0))
1.025390625
> (cheby-hka 0 0.25 (float-vector 0 0 0 0 1.0 1.0))
1.5234375

Below we sweep the index from 0.0 to 1.0 (sticking at 1.0 for a moment at the end), with a partials list of '(11 1.0 20 1.0). These numbers were chosen to show that the even and odd harmonics are independent:

  (with-sound ()
    (let ((gen (make-polyshape 100.0 :partials (list 11 1 20 1)))
	  (ampf (make-env '(0 0 1 1 20 1 21 0) :scaler .4 :length 88200))
	  (indf (make-env '(0 0 1 1 1.1 1) :length 88200)))
      (do ((i 0 (+ i 1)))
	  ((= i 88200))
        (outa i (* (env ampf) (polyshape gen (env indf)))))))
picture of waveshaping sweep time domain

You can see there's another annoying "gotcha": the DC component can be arbitrarily large. If we don't counteract it in some way, we lose dynamic range, and we get a big click when the generator stops. In addition (as the right graph shows, although in this case the effect is minor), the peak amplitude is dependent on the index. We can reduce this problem somewhat by changing the signs of the harmonics to follow the pattern + + - -:

(list 1 .5  2 .25  3 -.125  4 -.125) ; squeeze the amplitude change toward index=0

but now the peak amplitude is hard to predict (it's .6242 in this example). Perhaps flatten-partials would be a better choice here. To follow an amplitude envelope despite a changing index, we can use a moving-max generator:

(with-sound ()
  (let ((gen (make-polyshape 1000.0 :partials (list 1 .25 2 .25 3 .125 4 .125 5 .25)))
	(indf (make-env '(0 0 1 1 2 0) :duration 2.0))     ; index env
	(ampf (make-env '(0 0 1 1 2 1 3 0) :duration 2.0)) ; desired amp env
	(mx (make-moving-max 256))                         ; track actual current amp
	(samps (seconds->samples 2.0)))
    (do ((i 0 (+ i 1)))
	((= i samps))
      (let ((val (polyshape gen (env indf))))              ; polyshape with index env
	(outa i (/ (* (env ampf) val)
		   (max 0.001 (moving-max mx val))))))))

The harmonic amplitude formula for the Chebyshev polynomials of the second kind is:

more cheby hka calcs

On a related topic, if we drive the sum of Chebyshev polynomials with more than one sinusoid, we get sum and difference tones, much as in complex FM:

T5 driven with sinusoids at 100Hz and 2000Hz

(with-sound ()
  (let ((pcoeffs (partials->polynomial (float-vector 5 1)))
	(gen1 (make-oscil 100.0))
	(gen2 (make-oscil 2000.0)))
    (do ((i 0 (+ i 1)))
	((= i 44100))
      (outa i (polynomial pcoeffs 
                (+ (* 0.5 (oscil gen1))
		   (* 0.5 (oscil gen2))))))))

t5
cross

This kind of output is typical; I get the impression that the cross products are much more noticeable here than in FM. Of course, we can take advantage of that:

(with-sound (:channels 2)
  (let* ((dur 2.0)
	 (samps (seconds->samples dur))
	 (p1 (make-polywave 800 (list 1 .1  2 .3  3 .4 5 .2)))
	 (p2 (make-polywave 400 (list 1 .1  2 .3  3 .4 5 .2)))
	 (interpf (make-env '(0 0 1 1) :duration dur))
	 (p3 (partials->polynomial (list 1 .1  2 .3  3 .4  5 .2)))
	 (g1 (make-oscil 800))
	 (g2 (make-oscil 400))
	 (ampf (make-env '(0 0 1 1 10 1 11 0) :duration dur)))
    (do ((i 0 (+ i 1)))
	((= i samps))
      (let ((interp (env interpf))
	    (amp (env ampf)))
	;; chan A: interpolate from one spectrum to the next directly
	(outa i (* amp (+ (* interp (polywave p1))
			  (* (- 1.0 interp) (polywave p2)))))
        ;; chan B: interpolate inside the sum of Tns!
	(outb i (* amp (polynomial p3 (+ (* interp (oscil g1))
					 (* (- 1.0 interp) (oscil g2))))))))))

If we use an arbitrary sound as the argument to the polynomial, the output is a brightened or distorted version of the original:

  (define (brighten-slightly coeffs)
    (let ((pcoeffs (partials->polynomial coeffs))
	  (mx (maxamp)))
      (map-channel
       (lambda (y)
         (* mx (polynomial pcoeffs (/ y mx)))))))

but watch out for clicks from the DC component if any of the "n" in the Tn are even. When I use this idea, I either use only odd numbered partials in the partials->polynomial list, or add an amplitude envelope to make sure the result ends at 0. I suppose you could also subtract out the DC term (coeffs[0]), but I haven't tried this.

If you push the polyshape generator into high harmonics (above say 30), you'll run into numerical trouble (the polywave generator is immune to this bug). Where does the trouble lie? The polynomials are related to each other via the recursion: Cheby recurse, so the first few polynomials are:

some Chebys more Chebys

The first coefficient is 2^n or 2^(n-1). This is bad news if "n" is large because we are expecting a bunch of huge numbers to add up to something in the vicinity of 0.0 or 1.0. If we're using 32-bit floats, the first sign of trouble comes when the order is around 26. If you look at some of the coefficients, you'll see numbers like -129026688.000 (in the 32 bit case), which should be -129026680.721 — we have run out of bits in the mantissa! With doubles we can only push the order up to around 46. polywave, on the other hand, builds up the sum of sines from the underlying recursion, which is only slightly slower than using the polynomial, and it is not bothered by these numerical problems. I have run polywave with 16384 harmonics, and the maximum error compared to the equivalent sum of sinusoids was around 5.0e-12.

Since it is primarily used for additive synthesis, and we can always do that with oscils or table-lookup, we might ask why we'd want polywave at all. Leaving aside speed (the Chebyshev computation is 10 to 20 times faster than the equivalent sum of oscils) and memory (the defunct table-lookup based waveshape generator and table-lookup itself use a table that has to be loaded), the main reason to use polywave is accuracy. polywave produces output that is as clean as the equivalent sum of oscils, whereas table-lookup and poor old waveshape, both of which interpolate into a sampled version of the desired function, are noisy. To make the difference almost appalling, here are spectra comparing a sum of oscils, polyshape, (table-lookup based) waveshape, and table-lookup.

compare ffts

The table size is 512, but that almost doesn't matter; you'd have to use a table size of at least 8192 to approach the oscil and polyshape cases. The FFT size is 1048576, with no data window ("rectangular"), and the y-axis is in dB, going down to -120 dB. The choice of fft window can make a big difference; using no window, but a huge fft seems like the least confusing way to present this result.

Notice the lower peaks in the table-lookup case. partials->wave puts n periods of the nth harmonic in the table, so the nth harmonic has an effective table length of table-length/n. n * 1/n = 1, so all our components have their first interpolation noise peak centered (in this case) around 7100 Hz ((512 * 100) mod 22050). Since the 1600 Hz component has an effective table size of only 32 samples, it creates big sidebands at 5500 Hz and 8700 Hz. The 800 Hz component makes smaller peaks (by a factor of 4, since this is proportional to n^2) at 6300 Hz and 7900 Hz, and the 100 Hz cases are at 7000 Hz and 7200 Hz (down in amplitude by 16^2). The highest peaks are down only 60 dB. See table-lookup for more discussion of interpolation noise (it's actually amplitude modulation of the stored signal and the linear interpolating signal with severe aliasing).

The waveshaping noise is much worse because the polynomial is so sensitive numerically. Here is a portion of the error signal at the point where the driving sinusoid is at its maximum:

cheby error

See also polyoid and noid in generators.scm.

sawtooth-wave, triangle-wave, pulse-train, square-wave
make-triangle-wave (frequency *clm-default-frequency*) (amplitude 1.0) (initial-phase pi)
triangle-wave s (fm 0.0)
triangle-wave? s

make-square-wave (frequency *clm-default-frequency*) (amplitude 1.0) (initial-phase 0)
square-wave s (fm  0.0)
square-wave? s

make-sawtooth-wave (frequency *clm-default-frequency*) (amplitude 1.0) (initial-phase pi)
sawtooth-wave s (fm 0.0)
sawtooth-wave? s

make-pulse-train (frequency *clm-default-frequency*) (amplitude 1.0) (initial-phase (* 2 pi))
pulse-train s (fm 0.0)
pulse-train? s
saw-tooth and friends' methods
mus-frequencyfrequency in Hz
mus-phasephase in radians
mus-scaleramplitude arg used in make-<gen>
mus-widthwidth of square-wave pulse (0.0 to 1.0)
mus-incrementfrequency in radians per sample

These generators produce some standard old-timey wave forms that are still occasionally useful (well, triangle-wave is useful; the others are silly). One popular kind of vibrato is:

  (+ (triangle-wave pervib) 
     (rand-interp ranvib))

sawtooth-wave ramps from -1 to 1, then goes immediately back to -1. Use a negative frequency to turn the "teeth" the other way. To get a sawtooth from 0 to 1, you can use modulo:

(with-sound () (do ((i 0 (+ i 1)) (x 0.0 (+ x .01))) ((= i 22050)) (outa i (modulo x 1.0))))

triangle-wave ramps from -1 to 1, then ramps from 1 to -1. pulse-train produces a single sample of 1.0, then zeros. square-wave produces 1 for half a period, then 0. All have a period of two pi, so the "fm" argument should have an effect comparable to the same FM applied to the same waveform in table-lookup.

(with-sound (:play #t)
  (let ((gen (make-triangle-wave 440.0)))
    (do ((i 0 (+ i 1)))
        ((= i 44100))
      (outa i (* 0.5 (triangle-wave gen))))))
with_sound(:play, true) do
  gen = make_triangle_wave(440.0);
  44100.times do |i| 
    outa(i, 0.5 * triangle_wave(gen), $output) 
    end
  end.output
lambda: ( -- )
  440.0 make-triangle-wave { gen }
  44100 0 do
    i  gen 0 triangle-wave  f2/ *output* outa drop
  loop
; :play #t with-sound drop

To get a square-wave with control over the "duty-factor":

(with-sound ()
  (let* ((duty-factor .25) ; ratio of pulse duration to pulse period
	 (p-on (make-pulse-train 100 0.5))
	 (p-off (make-pulse-train 100 -0.5 (* 2 pi (- 1.0 duty-factor))))
	 (sum 0.0))
    (do ((i 0 (+ i 1)))
	((= i 44100))
      (set! sum (+ sum (pulse-train p-on) (pulse-train p-off)))
      (outa i sum))))

This is the adjustable-square-wave generator in generators.scm. That file also defines adjustable-triangle-wave and adjustable-sawtooth-wave. All of these generators produce non-band-limited output; if the frequency is too high, you can get foldover. A more reasonable square-wave can be generated via (tanh (* B (sin theta))), where "B" (a float) sets how squared-off it is:

B: 1.0 B: 3.0 B: 100.0
tanh 1 tanh 1 tanh 1

The spectrum of tanh(sin) can be obtained by expanding tanh as a power series:

tanh power series

plugging in "sin" for "x", expanding the sine powers, and collecting terms (very tedious — use maxima!):

tanh sin power series

which is promising since a square wave is made up of odd harmonics with amplitude 1/n. As the "B" in tanh(B sin(x)) increases above pi/2, this series doesn't apply.

more tanh

but I haven't found a completion of this expansion that isn't ugly when B > pi/2. In any case, we can check the formula for tanh, and see that the e^-x term will vanish (in the positive x case), giving 1.0. So we do get a square wave, but it's not band limited. If a complex signal replaces the sin(x), we get "intermodulation products" (sum and difference tones); this use of tanh as a soft clipper goes way back — I don't know who invented it.

If you try to make a square wave by adding harmonics at amplitude 1/n, you run into "Gibb's phenomenon": although the sum converges on a square wave, it does so "pointwise" — each point converges to the square wave, but the sum always has an overshoot. To get something that looks square, we need to round-off the corners. Bill Gosper shows one mathematical way to do this (gibbs.html). We could also use with-mixed-sound and the Mixes dialog:

(definstrument (sine-wave start dur freq amp)
  (let* ((beg (seconds->samples start))
	 (end (+ beg (seconds->samples dur)))
	 (osc (make-oscil freq)))
   (do ((i beg (+ i 1))) 
       ((= i end))
     (outa i (* amp (oscil osc))))))

(with-mixed-sound ()
  (sine-wave 0 1 10.0 1.0)
  (sine-wave 0 1 30.0 .333)
  (sine-wave 0 1 50.0 .2)
  (sine-wave 0 1 70.0 .143))

Now we can play with the individual sinewave amplitudes in the Mixes dialog, seeing "in realtime" what effect an amplitude has on the waveform. In the graph below, we've taken the original set of four sines and chosen amplitudes 1.16, .87, .46, .14 (these are multipliers on the original 1/n amps). The first graph is the original waveform, the last is the result of the amplitude changes, and the middle one shows 100 sines (it is the usual demo that the Gibbs overshoot is not reduced by adding lots more components). The peak amplitude should be pi/4, but the Gibbs phenomenon adds .14.

reduce Gibbs

But goofing with individual amplitudes quickly becomes tiresome. This "realtime" business depends on luck; if we have some idea of what we're doing, we don't have to get lucky. Since tanh(B sin(x)) produces a nice square wave, we can truncate its spectrum at the desired number of harmonics:

(define square-wave->coeffs
  (let ((previous-results (make-vector 128 #f)))
    (lambda* (n B)
      (or (and (< n 128)
	       (not B)
	       (previous-results n))
	  (let* ((coeffs (make-float-vector (* 2 n) 0.0))
		 (size (expt 2 12))
		 (rl (make-float-vector size 0.0))
		 (im (make-float-vector size 0.0))
		 (incr (/ (* 2 pi) size))
		 (index (or B (max 1 (floor (/ n 2))))))
	    (do ((i 0 (+ i 1))
		 (x 0.0 (+ x incr)))
		((= i size))
	      (set! (rl i) (tanh (* index (sin x))))) ; make our desired square wave
	    (spectrum rl im #f 2)                       ; get its spectrum
	    (do ((i 0 (+ i 1))
		 (j 0 (+ j 2)))
		((= i n))
	      (set! (coeffs j) (+ j 1))
	      (set! (coeffs (+ j 1)) (/ (* 2 (rl (+ j 1))) size)))
	    (if (and (< n 128)                          ; save this set so we don't have to compute it again
		     (not B))
		(set! (previous-results n) coeffs))
	    coeffs)))))

(with-sound ()
  (let* ((samps (seconds->samples 1.0))
	 (wave (make-polywave 100.0 
			      :partials (square-wave->coeffs 16)
			      :type mus-chebyshev-second-kind)))
   (do ((i 0 (+ i 1)))
       ((= i samps))
     (outa i (* 0.5 (polywave wave))))))
tanh

See also tanhsin in generators.scm. Another square-wave choice is eoddcos in generators.scm, based on atan; as its "r" parameter approaches 0.0, you get closer to a square wave. Even more amusing is this algorithm (related to tanh(sin)):

square
(define (cossq c theta)   ; as c -> 1.0+, more of a square wave (try 1.00001)
  (let* ((cs (cos theta)) ; (+ theta pi) if matching sin case (or (- ...))
	 (cp1 (+ c 1.0))
	 (cm1 (- c 1.0))
	 (cm1c (expt cm1 cs))
	 (cp1c (expt cp1 cs)))
    (/ (- cp1c cm1c)
       (+ cp1c cm1c))))  ; from "From Squares to Circles..." Lasters and Sharpe, Math Spectrum 38:2

(define (sinsq c theta) (cossq c (- theta (* 0.5 pi))))
(define (sqsq c theta) (sinsq c (- (sinsq c theta)))) ; a sharper square wave

(with-sound ()
  (let ((angle 0.0))
    (do ((i 0 (+ i 1))
	 (angle 0.0 (+ angle 0.02)))
	((= i 44100))
      (outa i (* 0.5 (+ 1.0 (sqsq 1.001 angle)))))))

And in the slightly batty category is this method which uses only nested sines:

(with-sound ()
  (let ((angle 0.0) (z 1.18)
        (incr (hz->radians 100.0)))
    (do ((i 0 (+ i 1)))
        ((= i 20000))
      (let ((result (* z (sin angle))))
        (do ((k 0 (+ k 1)))
            ((= k 100))  ; the limit here sets how square it is, and also the overall amplitude
          (set! result (* z (sin result))))
        (set! angle (+ angle incr))
        (outa i result)))))

The continuously variable square-wave, tanh(B sin), can be differentiated to get a variable pulse-train, or integrated to get a variable triangle-wave. The derivative is B * cos(x) / (cosh^2(B * sin(x))):

(with-sound ()
  (let ((Benv (make-env '(0 .1 .1 1 .7 2 2 5) :end 10000))
        (osc (make-oscil 100)))	 
    (do ((i 0 (+ i 1)))
	((= i 10000))
      (let* ((B (env Benv))
	     (num (cos (mus-phase osc)))
	     (den (cosh (* B (oscil osc)))))
	(outa i (/ num (* den den)))))))
tanh(sin) as pulse train

Similar, but simpler is B*cos(x)/(e^(B*cos(x)) - 1):

(with-sound ()
  (let ((gen (make-oscil 40.0))
        (Benv (make-env '(0 .75 1 1.5 2 20) :end 10000)))
   (do ((i 0 (+ i 1)))
       ((= i 10000))
     (let* ((B (env Benv))
            (arg (* B pi (+ 1.0 (oscil gen)))))
       (outa i (/ arg (- (exp arg) 1)))))))
another pulse train

When we integrate tanh(B sin), the peak amp depends on both the frequency and the "B" factor (which sets how close we get to a triangle wave):

(with-sound ()
  (let ((gen (make-oscil 30.0))
	(Benv (make-env '(0 .1 .25 1 2 3 3 10) 
                :end 20000))
	(scl (hz->radians 30.0))
	(sum 0.0))
    (do ((i 0 (+ i 1)))
	((= i 20000))
      (let* ((B (env Benv))
	     (val (/ (* scl (max 1.0 (log B)) 
	                (tanh (* B (oscil gen)))) 
                     B)))
	(outa i (- sum 1.0))
	(set! sum (+ sum val))))))
tanh(sin) as triangle-wave

The amplitude scaling is obviously not right (if "B" > 3, it works to use (* (/ scl 1.6) (tanh (* B (oscil gen)))) and (outa i (- sum .83)), but if "B" is following an envelope, the integration makes it hard to keep everything centered and normalized). For sawtooth output, see also rksin. In these generators, the "fm" argument is useful mainly for various sci-fi sound effects:

(define (tritri start dur freq amp index mcr)
  (let* ((beg (seconds->samples start))
         (end (+ beg (seconds->samples dur)))
	 (carrier (make-triangle-wave freq))
	 (modulator (make-triangle-wave (* mcr freq))))
   (do ((i beg (+ i 1)))
       ((= i end))
     (outa i (* amp (triangle-wave carrier 
                    (* index (triangle-wave modulator))))))))

(with-sound (:srate 44100) (tritri 0 1 1000.0 0.5 0.1 0.01)) ; sci-fi laser gun
(with-sound (:srate 44100) (tritri 0 1 4000.0 0.7 0.1 0.01)) ; a sparrow?

On the other hand, animals.scm uses pulse-train's fm argument to track a frequency envelope, triggering a new peep each time the pulse goes by. I think just about every combination of oscil/triangle-wave/sawtooth-wave/square-wave has been used. Even triangle-wave(square-wave) can make funny noises. See ncos for more dicussion about using these generators as FM modulators.

ncos and nsin
make-ncos (frequency *clm-default-frequency*) (n 1)
ncos nc (fm 0.0)
ncos? nc

make-nsin (frequency *clm-default-frequency*) (n 1)
nsin ns (fm 0.0)
nsin? ns
ncos methods
mus-frequencyfrequency in Hz
mus-phasephase in radians
mus-scaler(/ 1.0 cosines)
mus-lengthn or cosines arg used in make-<gen>
mus-incrementfrequency in radians per sample

ncos produces a band-limited pulse train containing "n" cosines. I think this was originally viewed as a way to get a speech-oriented pulse train that would then be passed through formant filters (see pulse-voice in examp.scm). Set "n" to srate/2 to get a pulse-train (a single non-zero sample). These generators are based on the Dirichlet kernel:

sum of cosines


(with-sound (:play #t)
  (let ((gen (make-ncos 440.0 10)))
    (do ((i 0 (+ i 1)))
        ((= i 44100))
      (outa i (* 0.5 (ncos gen))))))
with_sound(:play, true) do
  gen = make_ncos(440.0, 10);
  44100.times do |i| 
    outa(i, 0.5 * ncos(gen), $output) 
    end
  end.output
lambda: ( -- )
  440.0 10 make-ncos { gen }
  44100 0 do
    i  gen 0 ncos  f2/ *output* outa drop
  loop
; :play #t with-sound drop

There are many similar formulas: see ncos2 and friends in generators.scm. "Trigonometric Delights" by Eli Maor has a derivation of the nsin formula and a neat geometric explanation. For a derivation of the ncos formula, see "Fourier Analysis" by Stein and Shakarchi, or (in the formula given below) multiply the left side (the cosines) by sin(x/2), use the trig formula 2sin(a)cos(b) = sin(b+a)-sin(b-a), and notice that all the terms in the series cancel except the last.

(define (simple-soc beg dur freq amp)
  (let* ((os (make-ncos freq 10))
         (start (seconds->samples beg))
         (end (+ start (seconds->samples dur))))
   (do ((i start (+ i 1))) ((= i end))
     (outa i (* amp (ncos os))))))

(with-sound () (simple-soc 0 1 100 1.0))
sum of cosines example

The sinc-train generator (in generators.scm) is very similar to ncos. If you use ncos as the FM modulating signal, you may be surprised and disappointed. As the modulating signal approaches a spike (as n increases), the bulk of the energy collapses back onto the carrier:

(with-sound ()
  (for-each
    (lambda (arg)
      (let ((car1 (make-oscil 1000))
            (mod1 (make-ncos 100 (cadr arg)))
            (start (seconds->samples (car arg)))
            (samps (seconds->samples 1.0))
            (ampf (make-env '(0 0 1 1 20 1 21 0) 
                    :duration 1.0 :scaler .8))
            (index (hz->radians (* 100 3.0))))
        (do ((i start (+ i 1)))
            ((= i (+ start samps)))
            (outa i (* (env ampf)
                       (oscil car1 (* index
                         (ncos mod1))))))))
    (list
     (list 0.0 1)   (list 2.0 2)
     (list 4.0 4)   (list 6.0 8)   
     (list 8.0 16)  (list 10.0 32)
     (list 12.0 64) (list 14.0 128))))
ncos as FM

If you go all the way and use a pulse-train as the FM source, you get a large component for the carrier, and all the others are very small.

pulse-train as FM j0 and j1
(define (ncfm freq-we-want wc modfreq baseindex n)
  ;; get amplitude of "freq-we-want" given ncos as FM, 
  ;;   "wc" as carrier, "modfreq" as ncos freq,
  ;;   "baseindex" as FM-index of first harmonic, 
  ;;   "n" as number of harmonics
  (let ((harms ())
	(amps ()))
    (do ((i 1 (+ i 1)))
	((> i n))
      (set! harms (cons (* i modfreq) harms))
      (set! amps (cons (/ baseindex (* i n)) amps)))
    (fm-parallel-component freq-we-want wc 
      (reverse harms) (reverse amps) () () #f)))
4 components: (ncfm x 1000 100 3.0 4)
x=1000 0.81 0.81 from J0(3/(4*k)) '(0 0 0 0)
x=900-0.44-0.32 from J1(3/4)*J0s '(-1 0 0 0)
x=800-0.14-0.16 from J1(3/8)*J0s '(0 -1 0 0)
x=700-0.06-0.10 from J1(3/12)*J0s '(0 0 -1 0)


24 components: (ncfm x 1000 100 3.0 24)
x=10000.99 0.99 from J0(3/(24*k)) '(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)
x=900-0.06-0.06 from J1(3/24)*J0s '(-1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)
x=800-0.03-0.03 from J1(3/48)*J0s '(0 -1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)
x=700-0.02-0.02 from J1(3/96)*J0s '(0 0 -1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)

You can multiply the index by n to counteract the effect of the n modulators (in the n=128 case mentioned above, the index becomes 384!). I find it surprising how smooth the spectral evolution is in this context. Here we sweep the index from 0 to 48 using n=16:

ncos
ncos (n=16) as FM, index from 0 to 48

But if our second analysis is correct, there's nothing special about the spike waveform that ncos produces. We only need a lot of components of decreasing effective FM index. If we randomize the initial phases of the n harmonically related equal amplitude sinusoids, we can minimize the peak amplitude (to reduce the spike), getting waveforms and results like these:

ncos case but random phases
FM of sum of n sinusoids
ncos case but random phases
sum of n sinusoids minimizing resemblance to pulse-train

Compare the sound of the n=64 and n=128 cases using ncos and random phases: they sound very different despite having the same spectrum. We confront the burning question: given n equal amplitude harmonically related sinusoids, what is the minimum peak amplitude? For my current best results, see peak-phases.

If you use ncos (or nsin) as both the carrier and modulator, you get a very similar effect. As n increases, the ncos(wc + ncos(wm)) output gradually approaches the unmodulated ncos output — the crunch happens on each carrier component, but most strongly on the earlier ones (the "effective index" is less on those components, as mentioned under polywave). And (for some reason this makes me smile), polywave modulated by ncos behaves the same way:

(with-sound ()
  (let ((modulator (make-ncos 100 :n 128))
        (carrier (make-polywave 1000 (list 1 .5 3 .25 6 .25))))
    (do ((i 0 (+ i 1))) 
        ((= i 20000))
      (outa i (* .5 (polywave carrier 
                      (* (hz->radians (* 3 100)) 
                         (ncos modulator 0.0))))))))

So, a pulse-train modulated by a pulse-train is a pulse-train. Are there any other cases where gen(wc + gen(wm)) = gen(wc)? My first thought was rand, but that has a hidden surprise: the modulation obscures the underlying square-wave!

rand(rand) spectrum

What FM input (to oscil, for a given index) would give the most dispersed output? My first guess was square-wave, but looking at graphs, I'd say rand gives it a good contest. If you sweep ncos upwards in frequency, you'll eventually get foldover; the generator produces its preset number of cosines no matter what. It is possible to vary the spectrum smoothly:

(with-sound ()
  (let ((os (make-ncos 100.0 4))
        (pow (make-env '(0 1.0 1 30.0) :length 10000))) ; our "index" envelope in FM jargon
    (do ((i 0 (+ i 1)))
	((= i 10000))
      (let ((val (ncos os)))
	(outa i (* (signum val) ; signum is in dsp.scm
		   (expt (abs val) (env pow))))))))

This is not a very polite sound. The same trick works on all the pulse-train functions in generators.scm (or an oscil for that matter!), but perhaps a filter is a simpler approach. There are a lot more of these "kernels" in generators.scm.

ncos2 (Fejer, n=10) npcos (Poussin, n=5) ncos4 (Jackson, n=10)
fejer sum poussin sum jackson sum

nsin produces a sum of equal amplitude sines. It is very similar (good and bad) to ncos. For n greater than 10 or so, its peak amplitude occurs at approximately 3pi/4n, and is about .7245*n (that is, 8n*(sin^2(3pi/8))/3pi). The nsin generator scales its output to be between -1 and 1 for any n. We can use nxysin to try any initial-phase in a sum of equal sinusoids. The peak amp in this case varys sinusoidally from a sum of sines n * 0.7245 to a sum of cosines n * 1.0; the peak amp is nsin-max(n) + abs(sin(initial-phase))*(1 - nsin-max(n)). nsin is based on the conjugate Dirichlet kernel:

sum of sines

sum of sines graphs


nsin methods
mus-frequencyfrequency in Hz
mus-phasephase in radians
mus-scalerdependent on number of sines
mus-lengthn or sines arg used in make-<gen>
mus-incrementfrequency in radians per sample

As with all the paired cos/sin generators (waveshaping, generators.scm, etc), we can vary the initial phase by taking advantage of the trig identity:

sin split

that is,

 (+ (* (ncos nc) (sin initial-phase))
    (* (nsin ns) (cos initial-phase)))

Or vary it via an envelope at run-time:

(with-sound ()
  (let ((nc (make-ncos 500.0 6))
	(ns (make-nsin 500.0 6))
	(phase (make-env '(0 0 1 1) 
                  :length 1000 :scaler (/ pi 2))))
    (do ((i 0 (+ i 1)))
	((= i 1000)) 
      (let ((angle (env phase)))
	(outa i (+ (* (ncos nc) (sin angle))
		   (* (nsin ns) (cos angle))))))))
ncos+nsin example

Compared to ncos or nsin, polywave is probably always faster and more accurate, but less convenient to set up. Both ncos and nsin could be implemented as polynomials in cos x, just as in polyshape; in fact, ncos is almost the same as the Chebyshev polynomial of the fourth kind. See also the nrxycos generator, and generators.scm.

various sums
many sums nxysin nxycos nxy1cos nxy1sin noddsin noddcos nkssb nkssb nchoosekcos many more sums nrsin nrcos rssb rcos rksin rkcos rkoddssb rkoddssb erssb ercos j0evencos
Gradshteyn and Ryzhik, "Table of Integrals, Series, and Products", 1.341.., 1.352.., 1.447.., 1.461, 1.518, 8.516, 8.531
more sums rxycos rxysin k2sin eoddcos more sums rxyk!cos rxyk!sin
Jolley, "Summation of Series", 521 587 623 635 638 685 686 691 692 728
Abramowitz and Stegun, "Handbook of Mathematical Functions", 9.6.34, 27.8.6
more sums
Zygmund, "Trigonometric Series" p34, 352
more sums
Sansone, "Orthogonal Functions"
more sums j0j1cos j0j1cos more sums jycos
Gray and Mathews, "A Treatise on Bessel Functions and Their Applications to Physics" p 28, 29, 92, 240
Watson, "A Treatise on the Theory of Bessel Functions": 4.82, 11.41, 17.31
Askey, "Ramanujan and Hypergeometric Series" Ramanujan, "On certain Arithmetical Functions"

There are many formulas that produce exponentially decaying or bell-curve shaped spectra; I think these all sound about the same, so I have included only a representative sample of them. A couple of the formulas are special cases of the "Bessel function summation theorem", G&R 8.530: summation formula, where Z stands for any of the various Bessel functions (J, Y, etc), and R stands for the Poisson-like business (or is it Legendre?) in the square root. Most of the formulas above are implemented as generators in generators.scm, along with the single side-band cases, where possible. Don't shy away from the sums to infinity just because you've heard shouting about "band-limited waveforms" — FM is an infinite sum:

cos cos cases cos cos cases
(Is cos(sin(x)) always greater than sin(cos(x))?)
nrxysin and nrxycos
make-nrxysin 
      (frequency *clm-default-frequency*) 
      (ratio 1.0)               ; ratio between frequency and the spacing between successive sidebands
      (n 1)                     ; number of sidebands
      (r .5)                    ; amplitude ratio between successive sidebands (-1.0 < r < 1.0)
nrxysin s (fm 0.0)
nrxysin? s

make-nrxycos (frequency *clm-default-frequency*) (ratio 1.0) (n 1) (r .5)
nrxycos s (fm 0.0)
nrxycos? s

nrxysin methods
mus-frequencyfrequency in Hz
mus-phasephase in radians
mus-scaler"r" parameter; sideband scaler
mus-length"n" parameter
mus-incrementfrequency in radians per sample
mus-offset"ratio" parameter

These three generators produce a kind of additive synthesis. "n" is the number of sidebands (0 gives a sine wave), "r" is the amplitude ratio between successive sidebands (don't set it to 1.0), and "ratio" is the ratio between the carrier frequency and the spacing between successive sidebands. A "ratio" of 2 gives odd-numbered harmonics for a (vaguely) clarinet-like sound. A negative ratio puts the side-bands below the carrier. A negative r is the same as shifting the initial phase by pi (instead of lining up for the spike at multiples of 2*pi, the (-1)^n causes them to line up at (2k-1)*pi, but the waveform is the same otherwise). The basic idea is very similar to that used in the ncos generator, but you have control of the fall-off of the spectrum and the spacing of the partials. Here are the underlying formulas:

nxry formulas
nxry formula
nrxysin, n=5, r=0.5
(with-sound (:play #t)
  (let ((gen (make-nrxycos 440.0 :n 10)))
    (do ((i 0 (+ i 1)))
        ((= i 44100))
      (outa i (* 0.5 (nrxycos gen))))))
with_sound(:play, true) do
  gen = make_nrxycos(440.0, 1.0, 10, 0.5);
  44100.times do |i| 
    outa(i, 0.5 * nrxycos(gen), $output) 
    end
  end.output
lambda: ( -- )
  440.0 :n 10 make-nrxycos { gen }
  44100 0 ?do
    i  gen 0 nrxycos  f2/ *output* outa drop
  loop
; :play #t with-sound drop

The peak amplitude of nrxysin is hard to predict. I think nrxysin is close to the -1.0..1.0 ideal, and won't go over 1.0. nrxycos is normalized correctly. Besides the usual FM input, you can also vary the "r" parameter (via mus-scaler) to get changing spectra. In the next example, we add a glissando envelope, and use the same envelope to vary "r" so that as the frequency goes up, "r" goes down (to avoid foldover, or whatever).

(definstrument (ss beg dur freq amp (n 1) (r .5) (ratio 1.0) frqf)
  (let* ((st (seconds->samples beg))
         (nd (+ st (seconds->samples dur)))
         (sgen (make-nrxysin freq ratio n r))
         (frq-env (and frqf (make-env frqf :scaler (hz->radians freq) :duration dur)))
         (spectr-env (and frqf (make-env frqf :duration dur)))
         (amp-env (make-env '(0 0 1 1 2 1 3 0) :scaler amp :duration dur)))
    (do ((i st (+ i 1))) 
        ((= i nd))
      (if spectr-env
          (set! (mus-scaler sgen) (* r (exp (- (env spectr-env))))))
      (outa i (* (env amp-env)
                 (nrxysin sgen (if frq-env (env frq-env) 0.0)))))))

(with-sound () (ss 0 1 400.0 1.0 5 0.5 1.0 '(0 0 1 2)))

"r" can also be used in the same way as an FM index, but with much simpler spectral evolution (x^n, x between -1.0 and 1.0, rather than Jn(x)). In the graph, r is 0 at the midpoint, r goes from -1.0 to 1.0 along the horizontal axis — I forgot to label the axes.

nrxycos changing r
(with-sound ()
  (let ((gen1 (make-nrxycos 400 1 15 0.95))
        (indr (make-env '(0 -1 1 1) 
                :length 80000 :scaler 0.9999)))
    (do ((i 0 (+ i 1)))
        ((= i 80000))
      (set! (mus-scaler gen1) (env indr)) ; this sets r
      (outa i (* .5 (nrxycos gen1 0.0))))))
ssb-am
make-ssb-am (frequency *clm-default-frequency*) (order 40)
ssb-am gen (insig 0.0) (fm 0.0)
ssb-am? gen
ssb-am methods
mus-frequencyfrequency in Hz
mus-phasephase (of embedded sin osc) in radians
mus-orderembedded delay line size
mus-lengthsame as mus-order
mus-interp-typemus-interp-none
mus-xcoeffFIR filter coeff
mus-xcoeffsembedded Hilbert transform FIR filter coeffs
mus-dataembedded filter state
mus-incrementfrequency in radians per sample

ssb-am provides single sideband suppressed carrier amplitude modulation, normally used for frequency shifting. The basic notion is to shift a spectrum up or down while cancelling either the upper or lower half of the spectrum. See dsp.scm for a number of curious possibilities (time stretch without pitch shift for example). When this works, which it does more often than I expected, it is much better than the equivalent phase-vocoder or granular synthesis kludges.

(with-sound (:play #t :srate 44100)
  (let ((shifter (make-ssb-am 440.0 20))
	(osc (make-oscil 440.0)))
    (do ((i 0 (+ i 1)))
	((= i 44100))
      (outa i (* 0.5 (ssb-am shifter (oscil osc)))))))
with_sound(:play, true, :srate, 44100) do
  shifter = make_ssb_am(440.0, 20);
  osc = make_oscil(440.0);
  44100.times do |i|
    outa(i, 0.5 * ssb_am(shifter, oscil(osc)), $output);
    end
  end.output
lambda: ( -- )
  440.0 20 make-ssb-am { shifter }
  440.0 make-oscil { osc }
  44100 0 ?do
    i  shifter  osc 0 0 oscil  0 ssb-am f2/ *output* outa drop
  loop
; :play #t :srate 44100 with-sound drop
(define* (ssb-am freq (order 40)) 
  ;; higher order = better cancellation
  (let* ((car-freq (abs freq))
	 (cos-car (make-oscil car-freq (* .5 pi)))
	 (sin-car (make-oscil car-freq))
	 (dly (make-delay order))
	 (hlb (make-hilbert-transform order)))
    (map-channel 
      (lambda (y)
        (let ((ccos (oscil cos-car))
	      (csin (oscil sin-car))
	      (yh (hilbert-transform hlb y))
  	      (yd (delay dly y)))
          (if (> freq 0.0)
	      (- (* ccos yd) ; shift up
	         (* csin yh))
	      (+ (* ccos yd) ; shift down
	         (* csin yh))))))))

(definstrument (shift-pitch beg dur file freq (order 40))
  (let* ((st (seconds->samples beg))
         (nd (+ st (seconds->samples dur)))
	 (gen (make-ssb-am freq order))
	 (rd (make-readin file)))
    (do ((i st (+ i 1))) 
        ((= i nd))
      (outa i (ssb-am gen (readin rd))))))

(with-sound () (shift-pitch 0 3 "oboe.snd" 1108.0))

Normal amplitude modulation, cos(x) * (amp + Y(t)), where Y is some signal, produces the carrier (cos(x)), and symmetric sidebands at x+/-frq where frq is each spectral component of Y. This is just an elaboration of

cos(x) * (amp + cos(y)) = amp * cos(x) + 1/2(cos(x - y) + cos(x + y))

So, the Y spectrum (the first picture below) is shifted up by cos(x) and mirrored on either side of it (the second picture below; the spectral components on the left side are folding under 0). In single side-band AM, we create both the Y spectrum, and, via the hilbert transform, a version of Y in which the phases are shifted too. Then we can add these two copies, using the phase differences to cancel one side of the symmetric spectrum (this is the third picture below; the new spectral components are not harmonically related however). Once we can shift a pitch without creating its symmetric twin, we can split a spectrum into many bands, shift each band separately, and thereby retain its original harmonic spacing (the fourth picture). We have the original, but at a higher pitch. If we then use src to convert it back to its pre-shift pitch, we have the original, but with a different length. We have decoupled the pitch from the duration, much as in a phase vocoder (which uses an FFT rather than a filter bank, and an inverse FFT of the moved spectrum, rather than ssb-am).

unaltered oboe am oboe ssbam oboe ssbambank oboe
original amplitude modulation ssb-am ssb-am bank

The second picture was created from oboe.snd (the original) via:

(let ((osc (make-oscil 1000.0))) 
  (map-channel 
    (lambda (y) 
      (* .5 (amplitude-modulate .01 (oscil osc) y)))))

The third picture was created by:

(let ((am (make-ssb-am 1000 40))) 
  (map-channel 
    (lambda (y) 
      (ssb-am am y))))

And the fourth used the ssb-am-bank function in dsp.scm rewritten here for with-sound:

(definstrument (repitch beg dur sound old-freq new-freq 
                 (amp 1.0) (pairs 10) (order 40) (bw 50.0))
  (let* ((start (seconds->samples beg))
         (end (+ start (seconds->samples dur)))
         (ssbs (make-vector pairs))
         (bands (make-vector pairs))
         (factor (/ (- new-freq old-freq) old-freq))
         (rd (make-readin sound)))
    (do ((i 1 (+ i 1)))
        ((> i pairs))
      (let ((aff (* i old-freq))
            (bwf (* bw (+ 1.0 (/ i (* 2 pairs))))))
        (set! (ssbs (- i 1)) (make-ssb-am (* i factor old-freq)))
        (set! (bands (- i 1)) (make-bandpass (hz->radians (- aff bwf)) ; bandpass is in dsp.scm
                                             (hz->radians (+ aff bwf)) 
                                             order))))
    (do ((i start (+ i 1))) 
        ((= i end))
      (let ((sum 0.0)
            (y (readin rd)))
        (do ((band 0 (+ 1 band)))
            ((= band pairs))
          (set! sum (+ sum (ssb-am (ssbs band) 
                                   (bandpass (bands band) y)))))
        (outa i (* amp sum))))))

 (let* ((sound "oboe.snd")
        (mx (maxamp sound))
        (dur (mus-sound-duration sound)))
    (with-sound (:scaled-to mx  :srate (srate sound))
      (repitch 0 dur sound 554 1000)))

If you'd like to move formants independently of the fundamental, add or subtract integer multiples of the new fundamental from the make-ssb-am frequency argument. In the repitch instrument above, say we wanted to add a "stretch" argument to spread out or squeeze down the spectrum. We would replace the current make-ssb-am line with:

(set! (ssbs (- i 1)) (make-ssb-am (+ (* i factor old-freq)
                                   (* new-freq (round (* i stretch))))))
wave-train
make-wave-train 
        (frequency *clm-default-frequency*) 
        (initial-phase 0.0) 
        wave 
        (size *clm-table-size*) 
        (type mus-interp-linear)

wave-train w (fm 0.0)
wave-train? w

make-wave-train-with-env frequency env size
wave-train methods
mus-frequencyfrequency in Hz
mus-phasephase in radians
mus-datawave array (no set!)
mus-lengthlength of wave array (no set!)
mus-interp-typeinterpolation choice (no set!)

wave-train adds a copy of its wave (a "grain" in more modern parlance) into its output at frequency times per second. These copies can overlap or have long intervals of silence in between, so wave train can be viewed either as an extension of pulse-train and table-lookup, or as a primitive form of granular synthesis. make-wave-train-with-env (defined in generators.scm) returns a new wave-train generator with the envelope 'env' loaded into its table.

(with-sound (:play #t)
  (let ((gen (make-wave-train 440.0
               :wave (let ((v (make-float-vector 64 0.0)) 
                           (g (make-ncos 400 10)))
                       (set! (mus-phase g) (* -0.5 pi))
                       (do ((i 0 (+ i 1))) 
                           ((= i 64)) 
                         (set! (v i) (ncos g))) 
                       v))))
    (do ((i 0 (+ i 1)))
        ((= i 44100))
      (outa i (* 0.5 (wave-train gen))))))
with_sound(:play, true) do
  v = make_vct(64);
  g = make_ncos(400, 10);
  g.phase =  -0.5 * 3.14159;
  64.times do |i|
    v[i] = ncos(g);
    end
  gen = make_wave_train(440.0, :wave, v);
  44100.times do |i| 
    outa(i, 0.5 * wave_train(gen), $output) 
    end
  end.output
lambda: ( -- )
  400 10 make-ncos { g }
  g -0.5 pi f* set-mus-phase drop
  64 make-vct map! g 0 ncos end-map { v }
  440.0 :wave v make-wave-train { gen }
  44100 0 do
    i  gen 0 wave-train  f2/ *output* outa drop
  loop
; :play #t with-sound drop
wave-train example

With some simple envelopes or filters, you can use this for VOSIM and other related techniques. Here is a FOF instrument based loosely on fof.c of Perry Cook and the article "Synthesis of the Singing Voice" by Bennett and Rodet in "Current Directions in Computer Music Research".

(definstrument (fofins beg dur frq amp vib f0 a0 f1 a1 f2 a2 ve ae)
  (let* ((start (seconds->samples beg))
         (end (+ start (seconds->samples dur)))
         (ampf (make-env (or ae (list 0 0 25 1 75 1 100 0)) :scaler amp :duration dur))
         (frq0 (hz->radians f0))
         (frq1 (hz->radians f1))
         (frq2 (hz->radians f2))
         (foflen (if (= *clm-srate* 22050) 100 200))
         (vibr (make-oscil 6))
         (vibenv (make-env (or ve (list 0 1 100 1)) :scaler vib :duration dur))
         (win-freq (/ (* 2 pi) foflen))
         (foftab (make-float-vector foflen 0.0))
         (wt0 (make-wave-train :wave foftab :frequency frq)))
    (do ((i 0 (+ i 1)))
        ((= i foflen))
      (set! (foftab i) ;; this is not the pulse shape used by B&R
            (* (+ (* a0 (sin (* i frq0))) 
                  (* a1 (sin (* i frq1))) 
                  (* a2 (sin (* i frq2)))) 
               .5 (- 1.0 (cos (* i win-freq))))))
    (do ((i start (+ i 1)))
        ((= i end))
      (outa i (* (env ampf) (wave-train wt0 (* (env vibenv) (oscil vibr))))))))

(with-sound () (fofins 0 1 270 .2 .001 730 .6 1090 .3 2440 .1)) ; "Ahh"

(with-sound () ; one of JC's favorite demos
  (fofins 0 4 270 .2 0.005 730 .6 1090 .3 2440 .1 '(0 0 40 0 75 .2 100 1) 
          '(0 0 .5 1 3 .5 10 .2 20 .1 50 .1 60 .2 85 1 100 0))
  (fofins 0 4 (* 6/5 540) .2 0.005 730 .6 1090 .3 2440 .1 '(0 0 40 0 75 .2 100 1) 
          '(0 0 .5 .5 3 .25 6 .1 10 .1 50 .1 60 .2 85 1 100 0))
  (fofins 0 4 135 .2 0.005 730 .6 1090 .3 2440 .1 '(0 0 40 0 75 .2 100 1) 
          '(0 0 1 3 3 1 6 .2 10 .1 50 .1 60 .2 85 1 100 0)))

The wave-trains's wave is a float-vector accessible via mus-data. The "fm" argument affects the frequency of repetition. Here is a wave-train instrument that increasingly filters its grain (the word "now", for example) while increasing the repetition rate. We're also using a pulse train as a sort of internal click track, using the same frequency envelope as the wave-train, so we have some idea when to refilter the grain.

(definstrument (when? start-time duration start-freq end-freq grain-file)
  (let* ((beg (seconds->samples start-time))
         (len (seconds->samples duration))
         (end (+ beg len))
         (grain-dur (mus-sound-duration grain-file))
         (frqf (make-env '(0 0 1 1) :scaler (hz->radians (- end-freq start-freq)) :duration duration))
         (click-track (make-pulse-train start-freq))
         (grain-size (seconds->samples grain-dur))
         (grains (make-wave-train :size grain-size :frequency start-freq))
         (ampf (make-env '(0 1 1 0) :scaler .7 :offset .3 :duration duration :base 3.0))
         (grain (mus-data grains)))
    (file->array grain-file 0 0 grain-size grain)
    (let ((original-grain (copy grain)))
      (do ((i beg (+ i 1)))
          ((= i end))
        (let ((gliss (env frqf)))
          (outa i (* (env ampf) (wave-train grains gliss)))
          (let ((click (pulse-train click-track gliss)))
            (if (> click 0.0)
                (let* ((scaler (max 0.1 (* 1.0 (/ (- i beg) len))))
                       (comb-len 32)
                       (c1 (make-comb scaler comb-len))
                       (c2 (make-comb scaler (floor (* comb-len .75))))
                       (c3 (make-comb scaler (floor (* comb-len 1.25)))))
                  (do ((k 0 (+ k 1)))
                      ((= k grain-size))
                    (let ((x (original-grain k)))
                     (set! (grain k) (+ (comb c1 x) (comb c2 x) (comb c3 x)))))))))))))

(with-sound () (when? 0 4 2.0 8.0 "right-now.snd"))

wave-train is built on table-lookup and shares all of its questionable aspects. See also the pulsed-enve generator in generators.scm, used in animals.scm. It is often simpler to use pulse-train as the repetition trigger, and mus-reset to restart an envelope.

rand, rand-interp
make-rand 
        (frequency *clm-default-frequency*) ; frequency at which new random numbers occur
        (amplitude 1.0)                     ; numbers are between -amplitude and amplitude
        (envelope '(-1 1 1 1))              ; distribution envelope (uniform distribution is the default)
        distribution                        ; pre-computed distribution

rand r (sweep 0.0)
rand? r

make-rand-interp 
        (frequency *clm-default-frequency*) 
        (amplitude 1.0)
        (envelope '(-1 1 1 1)
        distribution)

rand-interp r (sweep 0.0)
rand-interp? r

mus-random amp
mus-rand-seed
rand and rand-interp methods
mus-frequencyfrequency in Hz
mus-phasephase in radians
mus-scaleramplitude arg used in make-<gen>
mus-lengthdistribution table (float-vector) length
mus-datadistribution table (float-vector), if any
mus-incrementfrequency in radians per sample

rand produces a sequence of random numbers between -amplitude and amplitude (a sort of step function). rand-interp interpolates between successive random numbers. rand-interp could be defined as (moving-average agen (rand rgen)) where the averager has the same period (length) as the rand. In both cases, the "envelope" argument or the "distribution" argument determines the random number distribution. mus-random returns a random number between -amplitude and amplitude.

(with-sound (:channels 2 :play #t)
  (let ((ran1 (make-rand 5.0 (hz->radians 220.0)))
        (ran2 (make-rand-interp 5.0 (hz->radians 220.0)))
	(osc1 (make-oscil 440.0))
	(osc2 (make-oscil 1320.0)))
    (do ((i 0 (+ i 1)))
	((= i 88200))
      (outa i (* 0.5 (oscil osc1 (rand ran1))))
      (outb i (* 0.5 (oscil osc2 (rand-interp ran2)))))))
with_sound(:play, true, :channels, 2) do
  ran1 = make_rand(5.0, hz2radians(220.0));
  ran2 = make_rand_interp(5.0, hz2radians(220.0));
  osc1 = make_oscil(440.0);  
  osc2 = make_oscil(1320.0);
  88200.times do |i|
    outa(i, 0.5 * oscil(osc1, rand(ran1)), $output);
    outb(i, 0.5 * oscil(osc2, rand_interp(ran2)), $output);
    end
  end.output
lambda: ( -- )
  5.0 220.0 hz->radians make-rand { ran1 }
  5.0 330.0 hz->radians make-rand-interp { ran2 }
   440.0 make-oscil { osc1 }
  1320.0 make-oscil { osc2 }
  88200 0 do
    i  osc1  ran1 0 rand         0 oscil  f2/ *output* outa drop
    i  osc2  ran2 0 rand-interp  0 oscil  f2/ *output* outb drop
  loop
; :channels 2 :play #t with-sound drop

The "frequency" is the rate at which new values are produced, so it makes sense to request a frequency above srate/2. If rand's frequency is the current srate, it produces a new random value on every sample. Since rand is (normally) producing a sequence of square-waves, and rand-interp a sequence of triangle-waves, both reflect that in their spectra (spectrum y axis is in dB):

sqwave spectrumtriwave spectrum
square-wave (freq=1000)triangle-wave (freq=1000)
rand spectrumrand-interp spectrum
rand (freq=2000)rand-interp (freq=2000)

There are a variety of ways to get a non-uniform random number distribution: (random (random 1.0)) or (sin (mus-random pi)) are examples. Exponential distribution could be:

(log (max .01 (random 1.0)) .01)

where the ".01"'s affect how tightly the resultant values cluster toward 0.0 — set them to .0001, for example, to get most of the random values close to 0.0. The central-limit theorem says that you can get closer and closer to gaussian noise by adding rand's together. Orfanidis in "Introduction to Signal Processing" says 12 calls on rand will do perfectly well:

(define (gaussian-noise)
  (let ((val 0.0))
    (do ((i 0 (+ i 1))) 
        ((= i 12) (/ val 12.0) )
      (set! val (+ val (random 1.0))))))

You can watch this (or any other distribution) in action via:

(define (add-rands n)
  (let ((bins (make-vector 201 0))
	(rands (make-vector n #f)))
    (do ((i 0 (+ i 1)))
	((= i n))
      (set! (rands i) (make-rand :frequency *clm-srate* :amplitude (/ 100 n)))
      (rand (rands i)))
    (do ((i 0 (+ i 1)))
	((= i 100000))
      (let ((sum 0.0))
	(do ((k 0 (+ k 1)))
	    ((= k n))
	  (set! sum (+ sum (rand (rands k)))))
	(let ((bin (floor (+ 100 (round sum)))))
	  (set! (bins bin) (+ (bins bin) 1)))))
    bins))

(let ((ind (new-sound "test.snd")))
  (do ((n 1 (+ n 1)))
      ((= n 12))
    (let* ((bins (vector->float-vector (add-rands n)))
	   (pk (maxamp bins)))
      (float-vector->channel (float-vector-scale! bins (/ 1.0 pk)))
      (set! (x-axis-label) (format #f "n: ~D" n))
      (update-time-graph))))

Another way to get different distributions is the "rejection method" in which we generate random number pairs until we get a pair that falls within the desired distribution; see any-random in dsp.scm. The rand and rand-interp generators, however, use the "transformation method". The make-rand and make-rand-interp "envelope" arguments specify the desired distribution function; the generator takes the inverse of the integral of this envelope, loads that into an array, and uses (array-interp (random array-size)). This gives random numbers of any arbitrary distribution at a computational cost equivalent to the old waveshape generator. The x axis of the envelope sets the output range (before scaling by the "amplitude" argument), and the y axis sets the relative weight of the corresponding x axis value. So, the default is '(-1 1 1 1) which says "output numbers between -1 and 1, each number having the same chance of being chosen". An envelope of '(0 1 1 0) outputs values between 0 and 1, denser toward 0. If you already have the distribution table (a float-vector, the result of (inverse-integrate envelope) for example), you can pass it through the "distribution" argument. Here is gaussian noise using the "envelope" argument:

(define (gaussian-envelope s)
  (let ((e ())
	(den (* 2.0 s s)))
    (do ((i 0 (+ i 1))
	 (x -1.0 (+ x .1))
	 (y -4.0 (+ y .4)))
	((= i 21)
         (reverse e))
      (set! e (cons (exp (- (/ (* y y) den))) (cons x e))))))

(make-rand :envelope (gaussian-envelope 1.0))

If you want a particular set of values, it's simplest to fill a float-vector with those values, then use random as the index into the array. Say we want 0.0, 0.5, and 1.0 at random, but 0.5 should happen three times as often as either of the others:

(let ((vals (float-vector 0.0 0.5 0.5 0.5 1.0)))
  (do ((i 0 (+ i 1)))
      ((= i 10))
    (format #t ";~A " (vals (floor (random 5.0))))))

These "distributions" refer to the values returned by the random number generator, but all of them produce white noise (all frequencies are equally likely). You can, of course, filter the output of rand to get a different frequency distribution. See, for example, round-interp in generators.scm. It uses a moving-average generator to low-pass filter the output of a rand-interp generator; the result is a rand-interp signal with rounded corners. Orfanidis also mentions a clever way to get reasonably good 1/f noise: sum together n rand's, where each rand is running an octave slower than the preceding:

(define (make-1f-noise n)
  ;; returns an array of rand's ready for the 1f-noise generator
  (let ((rans (make-vector n)))
    (do ((i 0 (+ i 1))) 
        ((= i n) rans)
      (set! (rans i) (make-rand :frequency (/ *clm-srate* (expt 2 i)))))))

(define (1f-noise rans)
  (let ((val 0.0) 
        (len (length rans)))
    (do ((i 0 (+ i 1)))
        ((= i len) (/ val len))
      (set! val (+ val (rand (rans i)))))))

This is the pink-noise generator in generators.scm. See also green-noise — bounded brownian noise that can mimic 1/f noise in some cases. (The brownian graph below has a different dB range, and the rand graph would be flat if we used a frequency of 44100).

random rand rand-interp
random spectrum rand spectrum rand-interp spectrum
1/f brownian green
1/f spectrum brownian spectrum green spectrum

And we can't talk about noise without mentioning fractals:

(definstrument (fractal start duration m x amp)
  ;; use formula of M J Feigenbaum
  (let* ((beg (seconds->samples start))
	 (end (+ beg (seconds->samples duration))))
    (do ((i beg (+ i 1)))
        ((= i end))
      (outa i (* amp x))
      (set! x (- 1.0 (* m x x))))))

;;; this quickly reaches a stable point for any m in[0,.75], so:
(with-sound () (fractal 0 1 .5 0 .5)) 
;;; is just a short "ftt"
(with-sound () (fractal 0 1 1.5 .20 .2))

With this instrument you can hear the change over from the stable equilibria, to the period doublings, and finally into the combination of noise and periodicity that has made these curves famous. See appendix 2 to Ekeland's "Mathematics and the Unexpected" for more details. Another instrument based on similar ideas is:

(definstrument (attract beg dur amp c) ; c from 1 to 10 or so
  ;; by James McCartney, from CMJ vol 21 no 3 p 6
  (let* ((st (seconds->samples beg))
	 (nd (+ st (seconds->samples dur)))
	 (a .2) (b .2) (dt .04)
	 (scale (/ (* .5 amp) c))
	 (x1 0.0) (x -1.0) (y 0.0) (z 0.0))
    (do ((i st (+ i 1)))
        ((= i nd))
     (set! x1 (- x (* dt (+ y z))))
     (set! y (+ y (* dt (+ x (* a y)))))
     (set! z (+ z (* dt (- (+ b (* x z)) (* c z)))))
     (set! x x1)
     (outa i (* scale x)))))

which gives brass-like sounds! We can also get all the period doublings and so on from sin:

(with-sound (:clipped #f :scaled-to 0.5)
  (let ((x 0.5)) 
    (do ((i 0 (+ i 1)))
	((= i 44100))
      (outa i x)
      (set! x (* 4 (sin (* pi x)))))))

For an extended discussion of this case, complete with pictures of the period doublings, see Strogatz, "Nonlinear Dynamics and Chaos".

mus-rand-seed provides access to the seed for mus-random's random number generator:

> (set! (mus-rand-seed) 1234)
1234
> (mus-random 1.0)
-0.7828369138846
> (mus-random 1.0)
-0.880371093652
> (set! (mus-rand-seed) 1234) ; now start again with the same sequence of numbers
1234
> (mus-random 1.0)
-0.7828369138846
> (mus-random 1.0)
-0.880371093652

The clm random functions discussed here are different from s7's random function. The latter has a random-state record to guide the sequence (and uses a different algorithm), whereas the clm functions just use an integer, mus-rand-seed.

See also dither-channel (dithering), maraca.scm (physical modelling), noise.scm, noise.rb (a truly ancient noise-maker), any-random (arbitrary distribution via the rejection method), and green-noise (bounded Brownian noise).

one-pole, one-zero, two-pole, two-zero
 make-one-pole a0 b1    ; b1 < 0.0 gives lowpass, b1 > 0.0 gives highpass
 one-pole f input 
 one-pole? f

 make-one-zero a0 a1    ; a1 > 0.0 gives weak lowpass, a1 < 0.0 highpass
 one-zero f input 
 one-zero? f

 make-two-pole frequency [or a0] radius [or b1] b2
 two-pole f input 
 two-pole? f

 make-two-zero frequency [or a0] radius [or a1] a2
 two-zero f input 
 two-zero? f
simple filter methods
mus-xcoeffa0, a1, a2 in equations
mus-ycoeffb1, b2 in equations
mus-order1 or 2 (no set!)
mus-scalertwo-pole and two-zero radius
mus-frequencytwo-pole and two-zero center frequency

These are the simplest of filters. If you're curious about filters, Julius Smith's on-line Introduction to Digital Filters is excellent.

one-zero  y(n) = a0 x(n) + a1 x(n-1)
one-pole  y(n) = a0 x(n) - b1 y(n-1)
two-pole  y(n) = a0 x(n) - b1 y(n-1) - b2 y(n-2)
two-zero  y(n) = a0 x(n) + a1 x(n-1) + a2 x(n-2)

The "a0, b1" nomenclature is taken from Julius Smith's "An Introduction to Digital Filter Theory" in Strawn "Digital Audio Signal Processing", and is different from that used in the more general filters such as fir-filter. In make-two-pole and make-two-zero you can specify either the actual desired coefficients ("a0" and friends), or the center frequency and radius of the filter ("frequency" and "radius"). The word "radius" refers to the unit circle, so it should be between 0.0 and (less than) 1.0. "frequency" should be between 0 and srate/2.

(with-sound (:play #t)
  (let ((flt (make-two-pole 1000.0 0.999))
	(ran1 (make-rand 10000.0 .002)))
    (do ((i 0 (+ i 1)))
	((= i 44100))
      (outa i (* 0.5 (two-pole flt (rand ran1)))))))
with_sound(:play, true) do
  flt = make_two_pole(1000.0, 0.999);
  ran1 = make_rand(10000.0, 0.002); 
  44100.times do |i|
    outa(i, 0.5 * two_pole(flt, rand(ran1)), $output);
    end
  end.output
lambda: ( -- )
  1000.0 0.999 make-two-pole { flt }
  10000.0 0.002 make-rand { ran1 }
  44100 0 do
    i  flt  ran1 0 rand  two-pole  f2/ *output* outa drop
  loop
; :play #t with-sound drop

We can use a one-pole filter as an "exponentially weighted moving average":

(make-one-pole (/ 1.0 order) (/ (- order) (+ 1.0 order)))

where "order" is more or less how long an input affects the output. The mus-xcoeff and mus-ycoeff functions give access to the filter coefficients. prc95.scm uses them to make "run time" alterations to the filters:

(set! (mus-ycoeff p 1) (- val))     ; "p" is a one-pole filter, this is setting "b1"
(set! (mus-xcoeff p 0) (- 1.0 val)) ; this is setting "a0"

We can also use mus-frequency and mus-scaler (the pole "radius") as a more intuitive handle on these coefficients:

> (define p (make-two-pole :radius .9 :frequency 1000.0))
#<unspecified>
>p
#<two-pole: a0: 1.000, b1: -1.727, b2: 0.810, y1: 0.000, y2: 0.000>
> (mus-frequency p)
1000.00025329731
> (mus-scaler p)
0.899999968210856
> (set! (mus-frequency p) 2000.0)
2000.0
>p
#<two-pole: a0: 1.000, b1: -1.516, b2: 0.810, y1: 0.000, y2: 0.000>

A quick way to see the frequency response of a filter is to drive it with a sine wave sweeping from 0 Hz to half the sampling rate; if the sound length is 0.5 seconds, you can read off the time axis as the response at that frequency (in terms of a sampling rate of 1.0):

(define (test-filter flt)
  (let* ((osc (make-oscil))
	 (samps (seconds->samples 0.5))
	 (ramp (make-env '(0 0 1 1) 
                     :scaler (hz->radians samps) 
                     :length samps)))
    (with-sound ()
      (do ((i 0 (+ i 1)))
	  ((= i samps))
        (outa i (flt (oscil osc (env ramp))))))))
		
(test-filter (make-one-zero 0.5 0.5))
(test-filter (make-one-pole 0.1 -0.9))
(test-filter (make-two-pole 0.1 0.1 0.9))
(test-filter (make-two-zero 0.5 0.2 0.3))
simple filters
formant
make-formant 
      frequency   ; resonance center frequency in Hz
      radius      ; resonance width, indirectly
formant f input center-frequency-in-radians
formant? f

formant-bank filters input
formant-bank? f
make-formant-bank filters amps

make-firmant frequency radius
firmant f input center-frequency-in-radians
firmant? f

;; the next two are optimizations that I may remove
mus-set-formant-frequency f frequency
mus-set-formant-radius-and-frequency f radius frequency
formant methods
mus-phaseformant radius
mus-frequencyformant center frequency
mus-order2 (no set!)

formant and firmant are resonators (two-pole, two-zero bandpass filters) centered at "frequency", with the bandwidth set by "radius".

formant:
    y(n) = x(n) - 
           r * x(n-2) + 
           2 * r * cos(frq) * y(n-1) - 
           r * r * y(n-2)

firmant:
    x(n+1) = r * (x(n) - 2 * sin(frq/2) * y(n)) + input
    y(n+1) = r * (2 * sin(frq/2) * x(n+1) + y(n))
(with-sound (:play #t)
  (let ((flt (make-firmant 1000.0 0.999))
	(ran1 (make-rand 10000.0 5.0)))
    (do ((i 0 (+ i 1)))
	((= i 44100))
      (outa i (* 0.5 (firmant flt (rand ran1)))))))
with_sound(:play, true) do
  flt = make_firmant(1000.0, 0.999);
  ran1 = make_rand(10000.0, 5.0); 
  44100.times do |i|
    outa(i, 0.5 * firmant(flt, rand(ran1)), $output);
    end
  end.output
lambda: ( -- )
  1000.0 0.999 make-firmant { flt }
  10000.0 5.0 make-rand { ran1 }
  44100 0 do
    i  flt  ran1 0 rand  #f firmant  f2/ *output* outa drop
  loop
; :play #t with-sound drop

The formant generator is described in "A Constant-gain Digital Resonator Tuned By a Single Coefficient" by Julius O. Smith and James B. Angell in Computer Music Journal Vol. 6 No. 4 (winter 1982) and "A note on Constant-Gain Digital Resonators" by Ken Steiglitz, CMJ vol 18 No. 4 pp.8-10 (winter 1994). The formant bandwidth is a function of the "radius", and its center frequency is set by "frequency". As the radius approaches 1.0 (the unit circle), the resonance gets narrower. Use mus-frequency to change the center frequency, and mus-scaler to change the radius. The radius can be set in terms of desired bandwidth in Hz via:

(exp (* -0.5 (hz->radians bandwidth)))

If you change the radius, the peak amplitude of the output changes. The firmant generator is the "modified coupled form" of the formant generator, developed by Max Mathews and Julius Smith in "Methods for Synthesizing Very High Q Parametrically Well Behaved Two Pole Filters". Here are some graphs showing the formant and firmant filtering white noise as we sweep either the frequency or the radius:

various formant cases

formant and firmant are often used to sculpt away unwanted spectral components, or emphasize formant regions. In animals.scm, the crow, for example,

(load "animals.scm")
(with-sound (:play #t) (american-crow 0 .5))

has three formant filters. Without them, it would sound like this:

(with-sound (:play #t) (american-crow-no-formants 0 .5))

formant generators are also commonly used in a bank of filters to provide a sort of sample-by-sample spectrum. An example is fade.scm which has various functions for frequency domain mixing. See also grapheq (a non-graphic equalizer), and cross-synthesis. Here's an example that moves a set of harmonically related formants through a sound. If "radius" is .99, you get a glass-harmonica effect; if it's less, you get more of an FM index envelope effect.

(definstrument (move-formants start file amp radius move-env num-formants)
  (let* ((frms (make-vector num-formants))
	 (beg (seconds->samples start))
	 (dur (mus-sound-framples file))
	 (end (+ beg dur))
	 (rd (make-readin file))
	 (menv (make-env move-env :length dur)))
    (let ((start-frq (env menv)))
      (do ((i 0 (+ i 1)))
	  ((= i num-formants))
	(set! (frms i) (make-formant (* (+ i 1) start-frq) radius))))
    (let ((fb (make-formant-bank frms)))
      (do ((k beg (+ k 1)))
          ((= k end))
        (let ((frq (env menv)))
          (outa k (formant-bank fb (* amp (readin rd))))
	  (do ((i 0 (+ i 1))
	       (curfrq frq (+ curfrq frq)))
	      ((= i num-formants))
	    (if (< (* 2 curfrq) *clm-srate*)
	        (set! (mus-frequency (frms i)) curfrq))))))))

(with-sound () 
  (move-formants 0 "oboe.snd" 2.0 0.99 '(0 1200 1.6 2400 2 1400) 4))

make-formant-bank creates a formant-bank generator, an array of formant generators that is summed in parallel. The explicit do loop:

(let ((sum 0.0)) ; say we have n formant generators in the formants vector, and we're passing each a signal x
  (do ((i 0 (+ i 1)))
      ((= i n) sum)
    (set! sum (+ sum (formant (formants i) x)))))

can be replaced with:

(let ((fb (make-formant-bank formants)))
  ...
  (formant-bank fb x))

make-formant-bank takes a vector of formant generators as its first argument. Its optional second argument is a float-vector of gains (amplitudes) to scale each formant's contribution to the sum. Similarly, formant-bank's second argument is either a real number or a float-vector. If a float-vector, each element is treated as the input to the corresponding formant in the bank.


The clm-3 formant gain calculation was incorrect. To translate from the old formant to the new one, multiply the old gain by (* 2 (sin (hz->radians frequency))).

If you change the radius or frequency rapidly, the formant generator will either produce clicks or overflow, but firmant gives good output. Here's an example that puts formant on the edge of disaster (the glitch is about to explode), but firmant plugs away happily:

(with-sound (:channels 2)
  (let* ((dur 3)
	 (samps (seconds->samples dur))
	 (flta (make-formant 100 .999))
	 (fltc (make-firmant 100 .999))
	 (vibosc (make-oscil 10))
	 (index (hz->radians 100))
	 (click (make-ncos 40 500)))
    (do ((i 0 (+ i 1)))
        ((= i samps))
      (let ((vib (* index (+ 1 (oscil vibosc))))
            (pulse (ncos click)))
        (outa i (* 10 (formant flta pulse vib)))
        (outb i (* 10 (firmant fltc pulse vib)))))))
firmant is happy
filter, iir-filter, fir-filter
 make-filter order xcoeffs ycoeffs
 filter fl inp 
 filter? fl

 make-fir-filter order xcoeffs
 fir-filter fl inp 
 fir-filter? fl

 make-iir-filter order ycoeffs
 iir-filter fl inp 
 iir-filter? fl

 make-fir-coeffs order v
general filter methods
mus-orderfilter order
mus-xcoeffx (input) coeff
mus-xcoeffsx (input) coeffs
mus-ycoeffy (output) coeff
mus-ycoeffsy (output) coeffs
mus-datacurrent state (input values)
mus-lengthsame as mus-order

These are general FIR/IIR filters of arbitrary order. The "order" argument is one greater than the nominal filter order (it is the size of the coefficient array). The filter generator might be defined:

  (let ((xout 0.0))
    (set! (state 0) input)
    (do ((j (- order 1) (- j 1)))
        ((= j 0))
      (set! xout (+ xout (* (xcoeffs j) (state j))))
      (set! (state 0) (- (state 0) (* (ycoeffs j) (state j))))
      (set! (state j) (state (- j 1))))
    (+ xout (* (state 0) (xcoeffs 0))))
(with-sound (:play #t)
  (let ((flt (make-iir-filter 3 (float-vector 0.0 -1.978 0.998)))
	(ran1 (make-rand 10000.0 0.002)))
    (do ((i 0 (+ i 1)))
	((= i 44100))
      (outa i (* 0.5 (iir-filter flt (rand ran1)))))))
with_sound(:play, true) do
  flt = make_iir_filter(3, vct(0.0, -1.978, 0.998));
  ran1 = make_rand(10000.0, 0.002); 
  44100.times do |i|
    outa(i, 0.5 * iir_filter(flt, rand(ran1)), $output);
    end
  end.output
lambda: ( -- )
  3 vct( 0.0 -1.978 0.998 ) make-iir-filter { flt }
  10000.0 0.002 make-rand { ran1 }
  44100 0 do
    i  flt  ran1 0 rand  iir-filter  f2/ *output* outa drop
  loop
; :play #t with-sound drop

dsp.scm has a number of filter design functions, and various specializations of the filter generators, including such perennial favorites as biquad, butterworth, hilbert transform, and notch filters. Similarly, analog-filter.scm has the usual IIR suspects: Butterworth, Chebyshev, Bessel, and Elliptic filters. A biquad section can be implemented as:

(define (make-biquad a0 a1 a2 b1 b2) 
  (make-filter 3 (float-vector 0.0 b1 b2)))

The Hilbert transform can be implemented with an fir-filter:

(define* (make-hilbert-transform (len 30))
  (let* ((arrlen (+ 1 (* 2 len)))
         (arr (make-float-vector arrlen 0.0))
         (lim (if (even? len) len (+ 1 len))))
    (do ((i (- len) (+ i 1)))
        ((= i lim))
      (let ((k (+ i len))
            (denom (* pi i))
            (num (- 1.0 (cos (* pi i)))))
        (if (or (= num 0.0) (= i 0))
            (set! (arr k) 0.0)
            (set! (arr k) (* (/ num denom) 
                             (+ .54 (* .46 (cos (/ (* i pi) len)))))))))
    (make-fir-filter arrlen arr)))

(define hilbert-transform fir-filter)

make-fir-coeffs translates a frequency response envelope (actually, evenly spaced points in a float-vector) into the corresponding FIR filter coefficients. The order of the filter determines how close you get to the envelope.

Filters
lowpass filter: make-lowpass in dsp.scm
highpass filter: make-highpass in dsp.scm
bandpass filter: make-bandpass in dsp.scm
bandstop filter: make-bandstop in dsp.scm
Butterworth, Chebyshev, Bessel, Elliptic filters: analog-filter.scm
Hilbert transform: make-hilbert-transform in dsp.scm
differentiator: make-differentiator in dsp.scm
block DC: dc-block in prc95.scm or (make-filter 2 (float-vector 1 -1) (float-vector 0 -0.99))
hum elimination: make-eliminate-hum and notch-channel in dsp.scm
hiss elimination: notch-out-rumble-and-hiss
smoothing filters: moving-average, weighted-moving-average, exponentially-weighted-moving-average
notch-filters: notch-channel and notch-selection
arbitrary spectrum via FIR filter: spectrum->coeffs in dsp.scm
invert an FIR filter: invert-filter in dsp.scm
filtered echo sound effect: flecho in examp.scm
time varying filter: fltit in examp.scm
draw frequency response: use the envelope editor or filter control in control panel
Moog filter: moog.scm
Savitzky-Golay filter: savitzky-golay-filter
click reduction: remove-clicks, clean-channel
graphical equalizer filter bank: graphEq
nonlinear (Volterra) filter: volterra-filter
Kalman filter: kalman-filter-channel
filter a sound: filter-sound, filter-channel
see also convolution, physical modeling, reverb, and fft-based filtering
delay, tap
make-delay 
      size                  ; delay length
      initial-contents      ; delay line's initial values (a float-vector or a list)
      (initial-element 0.0) ; delay line's initial element
      max-size              ; maximum delay size in case the delay changes 
      type                  ; interpolation type
delay d input (pm 0.0)
delay? d

tap d (offset 0)
tap? d
delay-tick d input
delay methods
mus-lengthlength of delay
mus-ordersame as mus-length
mus-datadelay line itself (no set!)
mus-interp-typeinterpolation choice (no set!)
mus-scaleravailable for delay specializations
mus-locationcurrent delay line write position

The delay generator is a delay line. The make-delay "size" argument sets the delay line length (in samples). Input fed into a delay line reappears at the output size samples later. If "max-size" is specified in make-delay, and it is larger than "size", the delay line can provide varying-length delays (including fractional amounts). The delay generator's "pm" argument determines how far from the original "size" we are; that is, it is difference between the length set by make-delay and the current actual delay length, size + pm. So, a positive "pm" corresponds to a longer delay line. See zecho in examp.scm for an example. The make-delay "type" argument sets the interpolation type in the case of fractional delays: mus-interp-none, mus-interp-linear, mus-interp-all-pass, mus-interp-lagrange, mus-interp-bezier, or mus-interp-hermite. Delay could be defined:

(let ((result (array-interp line (- loc pm))))
  (set! (line loc) input)
  (set! loc (+ 1 loc))
  (if (<= size loc) (set! loc 0))
  result)
(with-sound (:play #t)
  (let ((dly (make-delay (seconds->samples 0.5)))
        (osc1 (make-oscil 440.0))
        (osc2 (make-oscil 660.0)))
    (do ((i 0 (+ i 1)))
        ((= i 44100))
      (outa i (* 0.5 
                 (+ (oscil osc1)
                    (delay dly (oscil osc2))))))))
with_sound(:play, true) do
  dly = make_delay(seconds2samples(0.5));
  osc1 = make_oscil(440.0);
  osc2 = make_oscil(660.0);
  44100.times do |i|
    outa(i, 
         0.5 * (oscil(osc1) + 
                delay(dly, oscil(osc2))), 
         $output);
    end
  end.output
lambda: ( -- )
  0.5 seconds->samples make-delay { dly }
  440.0 make-oscil { osc1 }
  660.0 make-oscil { osc2 }
  44100 0 do
    i
    osc1 0 0 oscil
    dly  osc2 0 0 oscil  0 delay f+
    f2/ *output* outa drop
  loop
; :play #t with-sound drop

The tap function taps a delay line at a given offset from the output point. delay-tick is a function that just puts a sample in the delay line, 'ticks' the delay forward, and returns its "input" argument. See prc95.scm for examples of both of these functions.

(definstrument (echo beg dur scaler secs file)
  (let ((del (make-delay (seconds->samples secs)))
        (rd (make-sampler 0 file)))
    (do ((i beg (+ i 1)))
        ((= i (+ beg dur)))
      (let ((inval (rd)))
        (outa i (+ inval (delay del (* scaler (+ (tap del) inval)))))))))

(with-sound () (echo 0 60000 .5 1.0 "pistol.snd"))

The mus-scaler field is available for simple extensions of the delay. For example, the moving-max generator uses mus-scaler to track the current maximum sample value in the delay line; the result is an envelope that tracks the peak amplitude in the last "size" samples. The mus-location field returns the current delay line write position. To access the delay line contents as a sliding window on the input data, use:

(define (delay-ref dly loc)
  (float-vector-ref (mus-data dly) (modulo (+ loc (mus-location dly)) (mus-length dly))))

The delay generator is used in some reverbs (nrev), many physical models (stereo-flute), dlocsig, chorus effects (chorus in dsp.scm), and flanging (new-effects), and is the basis for about a dozen extensions (comb and friends below).

comb, notch
make-comb (scaler 1.0) size initial-contents (initial-element 0.0) max-size
comb cflt input (pm 0.0)
comb? cflt

comb-bank combs input
comb-bank? object
make-comb-bank combs

make-filtered-comb (scaler 1.0) size initial-contents (initial-element 0.0) max-size filter
filtered-comb cflt input (pm 0.0)
filtered-comb? cflt

filtered-comb-bank fcombs input
filtered-comb-bank? object
make-filtered-comb-bank fcombs

make-notch (scaler 1.0) size initial-contents (initial-element 0.0) max-size
notch cflt input (pm 0.0)
notch? cflt
comb, filtered-comb, and notch methods
mus-lengthlength of delay
mus-ordersame as mus-length
mus-datadelay line itself (no set!)
mus-feedbackscaler (comb only)
mus-feedforwardscaler (notch only)
mus-interp-typeinterpolation choice (no set!)

The comb generator is a delay line with a scaler on the feedback. notch is a delay line with a scaler on the current input. filtered-comb is a comb filter with a filter on the feedback. Although normally this is a one-zero filter, it can be any CLM generator. The make-<gen> "size" argument sets the length in samples of the delay line, and the other arguments are also handled as in delay.

comb:           y(n) = x(n - size) + scaler * y(n - size)
notch:          y(n) = x(n) * scaler  + x(n - size)
filtered-comb:  y(n) = x(n - size) + scaler * filter(y(n - size))
sonogram of comb
(with-sound (:play #t)
  (let ((cmb (make-comb 0.4 (seconds->samples 0.4)))
        (osc (make-oscil 440.0))
        (ampf (make-env '(0 0 1 1 2 1 3 0) :length 4410)))
    (do ((i 0 (+ i 1)))
	((= i 88200))
      (outa i (* 0.5 (comb cmb (* (env ampf) (oscil osc))))))))
with_sound(:play, true) do
  cmb = make_comb(0.4, seconds2samples(0.4));
  osc = make_oscil(440.0);
  ampf = make_env([0.0, 0.0, 1.0, 1.0, 2.0, 1.0, 3.0, 0.0], :length, 4410);
  88200.times do |i|
    outa(i, 0.5 * (comb(cmb, env(ampf) * oscil(osc))), $output);
    end
  end.output
lambda: ( -- )
  0.4 0.4 seconds->samples make-comb { cmb }
  440.0 make-oscil { osc }
  '( 0 0 1 1 2 1 3 0 ) :length 4410 make-env { ampf }
  88200 0 do
    i
    cmb ( gen )
    ampf env  osc 0 0 oscil  f* ( val )
    0 ( pm )
    comb f2/ *output* outa drop
  loop
; :play #t with-sound drop

As a rule of thumb, the decay time of the feedback is 7.0 * size / (1.0 - scaler) samples, so to get a decay of feedback-dur seconds,

    (make-comb :size size :scaler (- 1.0 (/ (* 7.0 size) (* feedback-dur *clm-srate*))))

The peak gain is 1.0 / (1.0 - (abs scaler)). The peaks (or valleys in notch's case) are evenly spaced at *clm-srate* / size. The height (or depth) thereof is determined by scaler — the closer to 1.0 it is, the more pronounced the dips or peaks. See Julius Smith's "An Introduction to Digital Filter Theory" in Strawn "Digital Audio Signal Processing", or Smith's "Music Applications of Digital Waveguides". The following instrument sweeps the comb filter using the pm argument:

(definstrument (zc time dur freq amp length1 length2 feedback)
  (let* ((beg (seconds->samples time))
         (end (+ beg (seconds->samples dur)))
         (s (make-pulse-train :frequency freq))  ; some raspy input so we can hear the effect easily
         (d0 (make-comb :size length1 :max-size (max length1 length2) :scaler feedback))
         (aenv (make-env '(0 0 .1 1 .9 1 1 0) :scaler amp :duration dur))
         (zenv (make-env '(0 0 1 1) :scaler (- length2 length1) :base 12.0 :duration dur)))
     (do ((i beg (+ i 1))) ((= i end))
       (outa i (* (env aenv) (comb d0 (pulse-train s) (env zenv)))))))

(with-sound () 
  (zc 0 3 100 .1 20 100 .5) 
  (zc 3.5 3 100 .1 90 100 .95))

Nearly every actual use of comb filters involves a bank of them, a vector of combs summed in parallel. The comb-bank generator is intended for this kind of application. make-comb-bank takes a vector of combs and returns the comb-bank generator which can be called via comb-bank.

(let ((sum 0.0)) 
  (do ((i 0 (+ i 1)))
      ((= i n) sum)
    (set! sum (+ sum (comb (combs i) x)))))

can be replaced with:

(let ((cb (make-comb-bank combs)))
  ...
  (comb-bank cb x))

The comb filter can produce some nice effects; here's one that treats the comb filter's delay line as the coefficients for an FIR filter:

(define (fir+comb beg dur freq amp size)
  (let* ((start (seconds->samples beg))
         (end (+ start (seconds->samples dur)))
         (dly (make-comb :scaler .9 :size size)) 
         (flt (make-fir-filter :order size :xcoeffs (mus-data dly))) ; comb delay line as FIR coeffs
         (r (make-rand freq)))                                       ; feed comb with white noise
    (do ((i start (+ i 1))) 
        ((= i end)) 
      (outa i (* amp (fir-filter flt (comb dly (rand r))))))))

(with-sound () 
  (fir+comb 0 2 10000 .001 200)
  (fir+comb 2 2 1000 .0005 400)
  (fir+comb 4 2 3000 .001 300)
  (fir+comb 6 2 3000 .0005 1000))

Here's another that fluctuates between two sets of combs; it usually works best with voice sounds. We use comb-bank generators:

(definstrument (flux start-time file frequency combs0 combs1 (scaler 0.99) (comb-len 32))
  (let* ((beg (seconds->samples start-time))
         (len (mus-sound-framples file))
         (end (+ beg len))
         (num-combs0 (length combs0))
         (num-combs1 (length combs1))
         (cmbs0 (make-vector num-combs0))
         (cmbs1 (make-vector num-combs1))
         (osc (make-oscil frequency))
         (rd (make-readin file)))
    (do ((k 0 (+ k 1)))
        ((= k num-combs0))
      (set! (cmbs0 k)
            (make-comb scaler 
              (floor (* comb-len (combs0 k))))))
    (do ((k 0 (+ k 1)))
        ((= k num-combs1))
      (set! (cmbs1 k)
            (make-comb scaler 
              (floor (* comb-len (combs1 k))))))
    (let ((nc0 (make-comb-bank cmbs0))
          (nc1 (make-comb-bank cmbs1)))
      (do ((i beg (+ i 1)))
          ((= i end))
        (let ((interp (oscil osc))
              (x (readin rd)))
          (outa i (+ (* interp (comb-bank nc0 x)) 
                     (* (- 1.0 interp) (comb-bank nc1 x)))))))))

(with-sound (:scaled-to .5) 
  (flux 0 "oboe.snd" 10.0 '(1.0 1.25 1.5) '(1.0 1.333 1.6)) ; bowed oboe?
  (flux 2 "now.snd" 4.0 '(1.0 1.25 1.5) '(1.0 1.333 1.6 2.0 3.0))
  (flux 4 "now.snd" 1.0 '(1.0 1.25 1.5) '(1.0 1.333 1.6 2.0 3.0) 0.995 20)
  (flux 6 "now.snd" 10.0 '(1.0 1.25 1.5) '(1.0 1.333 1.6 2.0 3.0) 0.99 10)
  (flux 8 "now.snd" 10.0 '(2.0) '(1.0 1.333 1.6 2.0 3.0) 0.99 120)
  (flux 10 "fyow.snd" .50 '(1.0 2.0 1.5) '(1.0 1.333 1.6 2.0 3.0) 0.99 120))

For more comb filter examples, see examp.scm, chordalize in dsp.scm, or any of the standard reverbs such as nrev.


filtered-comb is used in freeverb where a one-zero filter is placed in the feedback loop:

(make-filtered-comb :size len :scaler room-decay-val :filter (make-one-zero :a0 (- 1.0 dmp) :a1 dmp))

As with the normal comb filter, the filtered-comb-bank generator sums a vector of filtered-comb generators in parallel.

all-pass
make-all-pass 
        (feedback 0.0) 
        (feedforward 0.0)
        size 
        initial-contents 
        (initial-element 0.0) 
        max-size

all-pass f input (pm 0.0)
all-pass? f

all-pass-bank all-passes input
all-pass-bank? object
make-all-pass-bank all-passes

make-one-pole-all-pass size coeff
one-pole-all-pass f input 
one-pole-all-pass? f
all-pass methods
mus-lengthlength of delay
mus-ordersame as mus-length
mus-datadelay line itself (no set!)
mus-feedbackfeedback scaler
mus-feedforwardfeedforward scaler
mus-interp-typeinterpolation choice (no set!)

The all-pass or moving average comb generator is just like comb but with an added scaler on the input ("feedforward" is Julius Smith's suggested name for it). If feedforward is 0.0, we get a comb filter. If both scale terms are 0.0, we get a pure delay line.

y(n) = feedforward * x(n) + x(n - size) + feedback * y(n - size)
(with-sound (:play #t)
  (let ((alp (make-all-pass -0.4 0.4 (seconds->samples 0.4)))
        (osc (make-oscil 440.0))
        (ampf (make-env '(0 0 1 1 2 1 3 0) :length 4410)))
    (do ((i 0 (+ i 1)))
        ((= i 88200))
      (outa i (* 0.5 (all-pass alp (* (env ampf) (oscil osc))))))))
with_sound(:play, true) do
  alp = make_all_pass(-0.4, 0.4, seconds2samples(0.4));
  osc = make_oscil(440.0);
  ampf = make_env([0.0, 0.0, 1.0, 1.0, 2.0, 1.0, 3.0, 0.0], :length, 4410);
  88200.times do |i|
    outa(i, 0.5 * (all_pass(alp, env(ampf) * oscil(osc))), $output);
    end
  end.output
lambda: ( -- )
  -0.4 0.4 0.4 seconds->samples make-all-pass { alp }
  440.0 make-oscil { osc }
  '( 0 0 1 1 2 1 3 0 ) :length 4410 make-env { ampf }
  88200 0 do
    i
    alp ( gen )
    ampf env  osc 0 0 oscil  f* ( val )
    0 ( pm )
    all-pass f2/ *output* outa drop
  loop
; :play #t with-sound drop

all-pass filters are used extensively in reverberation; see jcrev or nrev. To get the "all-pass" behavior, set feedback equal to -feedforward. Here's an example (based on John Chowning's ancient reverb) that was inspired by the bleed-through you get on old analog tapes — the reverb slightly precedes the direct signal:

(define (later file dly rev)
  (let* ((allpass1 (make-all-pass -0.700 0.700 1051))
         (allpass2 (make-all-pass -0.700 0.700  337))
         (allpass3 (make-all-pass -0.700 0.700  113))
         (comb1 (make-comb 0.742 4799))
         (comb2 (make-comb 0.733 4999))
         (comb3 (make-comb 0.715 5399))
         (comb4 (make-comb 0.697 5801))
         (file-dur (mus-sound-framples file))
         (decay-dur *clm-srate*)
         (len (floor (+ decay-dur file-dur)))
         (rd (make-readin file)) ; the direct signal (via sound-let below)
         (d (make-delay dly))    ; this delays the direct signal
         (backup (min 4799 dly)))
    (do ((i 0 (+ i 1)))
        ((= i len))
      (let* ((inval (readin rd))
             (allpass-sum (all-pass allpass3 
                            (all-pass allpass2 
                              (all-pass allpass1 
                                (* rev inval)))))
             (comb-sum 
              (+ (comb comb1 allpass-sum)
                 (comb comb2 allpass-sum)
                 (comb comb3 allpass-sum)
                 (comb comb4 allpass-sum)))
             (orig (delay d inval)))  
        (if (>= i backup)
            (outa (- i backup) (+ comb-sum orig)))))))

(with-sound () 
  (sound-let ((tmp () (fm-violin 0 .1 440 .1))) 
    (later tmp 10000 .1)))

In all such applications, the all-pass filters are connected in series (each one's output is the input to the next in the set). To package this up in one generator, use an all-pass-bank. An all-pass-bank is slightly different from the other "bank" generators in that it connects the vector of all-passes in series, rather than summing them in parallel. Code of the form:

(all-pass a1 (all-pass a2 input))

can be replaced with:

(let ((ab (make-all-pass-bank (vector a1 a2))))
  (all-pass-bank ab input))

one-pole-all-pass is used by piano.scm:

y(n) = x(n) + coeff * (y(n-1) - y(n))
x(n) = y(n-1)

This is repeated "size" times, with the generator input as the first y(n-1) value.

moving-average, moving-max, moving-norm
make-moving-average size initial-contents (initial-element 0.0)
moving-average f input
moving-average? f

make-moving-max size initial-contents (initial-element 0.0)
moving-max f input
moving-max? f

make-moving-norm size (scaler 1.0)
moving-norm f input
moving-norm? f
moving-average methods
mus-lengthlength of table
mus-ordersame as mus-length
mus-datatable of last 'size' values

The moving-average or moving window average generator returns the average of the last "size" values input to it.

result = sum-of-last-n-inputs / n
(with-sound (:play #t)
  (let ((avg (make-moving-average 4410))
	(osc (make-oscil 440.0))
	(stop (- 44100 4410)))
    (do ((i 0 (+ i 1)))
	((= i stop))
      (let ((val (oscil osc)))
	(outa i (* val (moving-average avg (abs val))))))
    (do ((i stop (+ i 1)))
	((= i 44100))
      (outa i (* (oscil osc) (moving-average avg 0.0))))))
with_sound(:play, true) do
  avg = make_moving_average(4410);
  osc = make_oscil(440.0);
  stop = 44100 - 4410;
  stop.times do |i|
    val = oscil(osc);
    outa(i, val * moving_average(avg, val.abs), $output);
    end
  4410.times do |i|
    outa(stop + i, oscil(osc) * moving_average(avg, 0.0), $output);
    end
  end.output
lambda: ( -- )
  4410 make-moving-average { avg }
  440.0 make-oscil { osc }
  44100 4410 - { stop }
  0.0 { val }
  stop 0 do
    osc 0 0 oscil to val
    i  avg val fabs moving-average  val f* *output* outa drop
  loop
  44100 stop do
    i  avg 0.0 moving-average  osc 0 0 oscil f*  *output* outa drop
  loop
; :play #t with-sound drop

moving-average is used both to track rms values and to generate ramps between 0 and 1 in a "gate" effect in new-effects.scm and in rms-envelope in env.scm. It can also be viewed as a low-pass filter. And in sounds->segment-data in examp.scm, it is used to segment a sound library. Here is an example (from new-effects.scm) that implements a "squelch" effect, throwing away any samples below a threshhold, and ramping between portions that are squelched and those that are unchanged (to avoid clicks):

(define (squelch-channel amount snd chn gate-size)  ; gate-size = ramp length and rms window length
  (let ((gate (make-moving-average gate-size))
        (ramp (make-moving-average gate-size :initial-element 1.0)))
    (map-channel (lambda (y) 
                   (* y (moving-average ramp                           ; ramp between 0 and 1
                          (if (< (moving-average gate (* y y)) amount) ; local (r)ms value
                              0.0                               ; below "amount" so squelch
                            1.0))))
                 0 #f snd chn)))

moving-max is a specialization of the delay generator; it produces an envelope that tracks the peak amplitude of the last 'n' samples. (make-moving-max 256) returns the generator (this one's window size is 256), and (moving-max gen y) then returns the envelope traced out by the signal 'y'. The harmonicizer uses this generator to normalize an in-coming signal to 1.0 so that the Chebyshev polynomials it is driving will produce a full spectrum at all times. Here is a similar, but simpler, example; we use the moving-max generator to track the current peak amplitude over a small window, use that value to drive a contrast-enhancement generator (so that its output is always fully modulated), and rescale by the same value upon output (to track the original sound's amplitude envelope):

(define (intensify index)
  (let ((mx (make-moving-max))
        (flt (make-lowpass (* pi .1) 8))) ; smooth the maxamp signal
    (map-channel (lambda (y)
                   (let ((amp (max .1 (fir-filter flt (moving-max mx y)))))
                     (* amp (contrast-enhancement (/ y amp) index)))))))

moving-norm specializes moving-max to provide automatic gain control. It is essentially a one-pole (low-pass) filter on the output of moving-max, inverted and multiplied by a scaler. (* input-signal (moving-norm g input-signal)) is the normal usage.

See generators.scm for several related functions: moving-rms, moving-sum, moving-length, weighted-moving-average, and exponentially-weighted-moving-average (the latter being just a one-pole filter).

src
make-src input (srate 1.0) (width 5)
src s (sr-change 0.0)
src? s
src methods
mus-incrementsrate arg to make-src

The src generator performs sampling rate conversion by convolving its input with a sinc function. make-src's "srate" argument is the ratio between the old sampling rate and the new; an srate of 2 causes the sound to be half as long, transposed up an octave.

(with-sound (:play #t :srate 22050)
  (let* ((rd (make-readin "oboe.snd"))
         (len (* 2 (mus-sound-framples "oboe.snd")))
         (sr (make-src rd 0.5)))
    (do ((i 0 (+ i 1)))
        ((= i len))
      (outa i (src sr)))))
with_sound(:play, true, :srate, 22050) do
  rd = make_readin("oboe.snd");
  len = 2 * mus_sound_framples("oboe.snd");
  sr = make_src(lambda do |dir| 
                 readin(rd) end, 0.5);
  len.times do |i|
    outa(i, src(sr), $output);
    end
  end.output
lambda: ( -- )
  "oboe.snd" make-readin { rd }
  rd 0.5 make-src { sr }
  "oboe.snd" mus-sound-framples 2* ( len ) 0 do
    i  sr 0 #f src  *output* outa drop
  loop
; :play #t :srate 22050 with-sound drop

The "width" argument sets how many neighboring samples to convolve with the sinc function. If you hear high-frequency artifacts in the conversion, try increasing this number; Perry Cook's default value is 40, and I've seen cases where it needs to be 100. It can also be set as low as 2 in some cases. The greater the width, the slower the src generator runs.

The src generator's "sr-change" argument is the amount to add to the current srate on a sample by sample basis (if it's 0.0 and the original make-src srate argument was also 0.0, you get a constant output because the generator is not moving at all). Here's an instrument that provides time-varying sampling rate conversion:

(definstrument (simple-src start-time duration amp srt srt-env filename)
  (let* ((senv (make-env srt-env :duration duration))
         (beg (seconds->samples start-time))
         (end (+ beg (seconds->samples duration)))
         (src-gen (make-src :input (make-readin filename) :srate srt)))
     (do ((i beg (+ i 1)))
         ((= i end))
       (outa i (* amp (src src-gen (env senv)))))))

(with-sound () (simple-src 0 4 1.0 0.5 '(0 1 1 2) "oboe.snd"))

src can provide an all-purpose "Forbidden Planet" sound effect:

(definstrument (srcer start-time duration amp srt fmamp fmfreq filename)
  (let* ((os (make-oscil fmfreq))
         (beg (seconds->samples start-time))
         (end (+ beg (seconds->samples duration)))
         (src-gen (make-src :input (make-readin filename) :srate srt)))
     (do ((i beg (+ i 1)))
         ((= i end))
       (outa i (* amp (src src-gen (* fmamp (oscil os))))))))

(with-sound () (srcer 0 2 1.0   1 .3 20 "fyow.snd"))   
(with-sound () (srcer 0 25 10.0   .01 1 10 "fyow.snd"))
(with-sound () (srcer 0 2 1.0   .9 .05 60 "oboe.snd")) 
(with-sound () (srcer 0 2 1.0   1.0 .5 124 "oboe.snd"))
(with-sound () (srcer 0 2 10.0   .01 .2 8 "oboe.snd"))
(with-sound () (srcer 0 2 1.0   1 3 20 "oboe.snd"))    

The "input" argument to make-src and the "input-function" argument to src provide the generator with input as it is needed. The input function is a function of one argument (the desired read direction, if the reader can support it), that is called each time src needs another sample of input. Here's an example instrument that reads a file with an envelope on the src:

(definstrument (src-change filename start-time duration file-start srcenv)
  (let* ((beg (seconds->samples start-time))
         (end (+ beg (seconds->samples duration)))
	 (loc (seconds->samples file-start))
         (src-gen (make-src :srate 0.0))
	 (e (make-env srcenv :duration duration))
	 (inp (make-file->sample filename)))
    (do ((i beg (+ i 1)))
        ((= i end))
      (outa i (src src-gen (env e) 
	        (lambda (dir)  ; our input function
		  (set! loc (+ loc dir))
		  (ina loc inp)))))))

;;; (with-sound () (src-change "pistol.snd" 0 2 0 '(0 0.5 1 -1.5)))

If you jump around in the input (via mus-location for example), use mus-reset to clear out any lingering state before starting to read at the new position. (src, like many other generators, has an internal buffer of recently read samples, so a sudden jump to a new location will otherwise cause a click).

There are several other ways to resample a sound. Some of the more interesting ones are in dsp.scm (down-oct, sound-interp, linear-src, etc). To calculate a sound's new duration after a time-varying src is applied, use src-duration. To scale an src envelope so that the result has a given duration, use scr-fit-envelope.

convolve
make-convolve input filter fft-size filter-size
convolve gen
convolve? gen

convolve-files file1 file2 (maxamp 1.0) (output-file "tmp.snd")
convolve methods
mus-lengthfft size used in the convolution

The convolve generator convolves its input with the impulse response "filter" (a float-vector). "input" is a function of one argument that is called whenever convolve needs input.

(with-sound (:play #t :statistics #t)
  (let ((cnv (make-convolve 
              (make-readin "pistol.snd")
              (file->float-vector "oboe.snd" 0 (make-float-vector (framples "pistol.snd"))))))
    (do ((i 0 (+ i 1)))
	((= i 88200))
      (outa i (* 0.25 (convolve cnv))))))
with_sound(:play, true, :statistics, true) do
  rd = make_readin("oboe.snd");
  flt = file2vct("pistol.snd"); # examp.rb
  cnv = make_convolve(lambda { |dir| readin(rd)}, flt);
  88200.times do |i|
    outa(i, 0.25 * convolve(cnv), $output);
    end
  end.output
lambda: ( -- )
  "pistol.snd" make-readin ( rd )
  "oboe.snd" file->vct ( v ) make-convolve { cnv }
  88200 0 do
    i  cnv #f convolve  0.25 f* *output* outa drop
  loop
; :play #t :statistics #t with-sound drop
(with-sound (:play #t)
  (let* ((tempfile (convolve-files "oboe.snd" 
  		   		   "pistol.snd" 0.5 
				   "convolved.snd"))
	 (len (mus-sound-framples tempfile))
	 (reader (make-readin tempfile)))
    (do ((i 0 (+ i 1)))
	((= i len))
      (outa i (readin reader)))
    (delete-file tempfile)))
with_sound(:play, true) do
  tempfile = convolve_files("oboe.snd", 
  	                    "pistol.snd", 0.5, 
			    "convolved.snd");
  len = mus_sound_framples(tempfile);
  reader = make_readin(tempfile);
  len.times do |i|
    outa(i, readin(reader), $output);
    end
  File.unlink(tempfile)
  end.output
lambda: ( -- )
  "oboe.snd" "pistol.snd" 0.5 "convolved.snd" convolve-files { tempfile }
  tempfile make-readin { reader }
  tempfile mus-sound-framples ( len ) 0 do
    i  reader readin  *output* outa drop
  loop
  tempfile file-delete
; :play #t with-sound drop
(definstrument (convins beg dur filter file (size 128))
  (let* ((start (seconds->samples beg))
         (end (+ start (seconds->samples dur)))
         (ff (make-convolve :input (make-readin file) :fft-size size :filter filter)))
     (do ((i start (+ i 1)))
         ((= i end))
       (outa i (convolve ff)))))

(with-sound () 
  (convins 0 2 (float-vector 1.0 0.5 0.25 0.125) "oboe.snd")) ; same as fir-filter with those coeffs

convolve-files handles a very common special case: convolve two files, then normalize the result to some maxamp. The convolve generator does not know in advance what its maxamp will be, and when the two files are more or less the same size, there's no real computational savings from using overlap-add (i.e. the generator), so a one-time giant FFT saved as a temporary sound file is much handier. If you're particular about the format of the convolved data:

(define* (convolve-files->aifc file1 file2 (maxamp 1.0) (output-file "test.snd"))
  (let ((outname (string-append "temp-" output-file)))
    (convolve-files file1 file2 maxamp outname)
    (with-sound (:header-type mus-aifc :sample-type mus-bfloat)
      (let ((len (seconds->samples (mus-sound-duration outname)))
	    (reader (make-readin outname)))
        (do ((i 0 (+ i 1)))
            ((= i len))
          (outa i (readin reader)))))
    (delete-file outname)
    output-file))

The convolve generator is the modern way to add reverb. There are impulse responses of various concert halls floating around the web. convolve and fir-filter actually perform the same mathematical operation, but convolve uses an FFT internally, rather than a laborious dot-product.

granulate
make-granulate   
        input
        (expansion 1.0)   ; how much to lengthen or compress the file
        (length .15)      ; length of file slices that are overlapped
        (scaler .6)       ; amplitude scaler on slices (to avoid overflows)
        (hop .05)         ; speed at which slices are repeated in output
        (ramp .4)         ; amount of slice-time spent ramping up/down
        (jitter 1.0)      ; affects spacing of successive grains
        max-size          ; internal buffer size
        edit              ; grain editing function

granulate e
granulate? e
granulate methods
mus-frequencytime (seconds) between output grains (hop)
mus-ramplength (samples) of grain envelope ramp segment
mus-hoptime (samples) between output grains (hop)
mus-scalergrain amp (scaler)
mus-incrementexpansion
mus-lengthgrain length (samples)
mus-datagrain samples (a float-vector)
mus-locationgranulate's local random number seed

The granulate generator "granulates" its input (normally a sound file). It is the poor man's way to change the speed at which things happen in a recorded sound without changing the pitches. It works by slicing the input file into short pieces, then overlapping these slices to lengthen (or shorten) the result; this process is sometimes known as granular synthesis, and is similar to the freeze function.

result = overlap add many tiny slices from input
(with-sound (:play #t)
  (let ((grn (make-granulate (make-readin "oboe.snd") 2.0)))
    (do ((i 0 (+ i 1)))
	((= i 44100))
      (outa i (granulate grn)))))
with_sound(:play, true) do
  rd = make_readin("oboe.snd");
  grn = make_granulate(lambda do |dir| readin(rd) end, 2.0);
  88200.times do |i|
    outa(i, granulate(grn), $output);
    end
  end.output
lambda: ( -- )
  "oboe.snd" make-readin 2.0 make-granulate { grn }
  44100 0 do
    i  grn #f #f granulate  *output* outa drop
  loop
; :play #t with-sound drop
(with-sound (:play #t)
  (let* ((osc (make-oscil 440.0))
	 (sweep (make-env '(0 0 1 1) 
			  :scaler (hz->radians 440.0) 
			  :length 44100))
	 (grn (make-granulate (lambda (dir)
				(* 0.2 (oscil osc (env sweep))))
			      :expansion 2.0
			      :length .5)))
    (do ((i 0 (+ i 1)))
	((= i 88200))
      (outa i (granulate grn)))))
with_sound(:play, true) do
  osc = make_oscil(440.0);
  sweep = make_env([0.0, 0.0, 1.0, 1.0],
                   :scaler, hz2radians(440.0),
		   :length, 44100);
  grn = make_granulate(lambda { |dir| 0.2 * oscil(osc, env(sweep))},
	               :expansion, 2.0,
	               :length, 0.5);
  88200.times do |i|
    outa(i, granulate(grn), $output);
    end
  end.output
: make-granulate-proc { osc sweep -- prc; dir self -- val }
  1 proc-create osc , sweep , ( prc )
 does> { dir self -- val }
  self @ ( osc )  self cell+ @ ( sweep ) env  0 oscil  0.2 f*
;

lambda: ( -- )
  440.0 make-oscil { osc }
  '( 0 0 1 1 ) :scaler 440.0 hz->radians :length 44100 make-env { sweep }
  osc sweep make-granulate-proc :expansion 2.0 :length 0.5 make-granulate { grn }
  88200 0 do
    i  grn #f #f granulate  *output* outa drop
  loop
; :play #t with-sound drop

The duration of each slice is "length" — the longer the slice, the more the effect resembles reverb. The portion of the length (on a scale from 0 to 1.0) spent on each ramp (up or down) is set by the "ramp" argument. It can control the smoothness of the result of the overlaps.

The "jitter" argument sets the accuracy with which granulate hops. If you set it to 0 (no randomness), you can get very strong comb filter effects, or tremolo. The more-or-less average time between successive segments is "hop". If jitter is 0.0, and hop is very small (say .01), you're asking for trouble (a big comb filter). If you're granulating more than one channel at a time, and want the channels to remain in-sync, make each granulator use the same initial random number seed (via mus-location).

The overall amplitude scaler on each segment is set by the "scaler" argument; this is used to try to avoid overflows as we add all these zillions of segments together. "expansion" determines the input hop in relation to the output hop; an expansion-amount of 2.0 should more or less double the length of the original, whereas an expansion-amount of 1.0 should return something close to the original tempo. "input" and "input-function" are the same as in src and convolve (functions of one argument that return a new input sample whenever they are called by granulate).

(definstrument (granulate-sound file beg dur (orig-beg 0.0) (exp-amt 1.0))
  (let* ((f-srate (srate file))
	 (f-start (round (* f-srate orig-beg)))
         (f (make-readin file :start f-start))
	 (st (seconds->samples beg))
	 (new-dur (or dur (- (mus-sound-duration file) orig-beg)))
	 (exA (make-granulate :input f :expansion exp-amt))
	 (nd (+ st (seconds->samples new-dur))))
    (do ((i st (+ i 1)))
        ((= i nd))
      (outa i (granulate exA)))))

(with-sound () (granulate-sound "now.snd" 0 3.0 0 2.0))

See clm-expsrc in clm-ins.scm. Here's an instrument that uses the input-function argument to granulate. It cause the granulation to run backwards through the file:

(definstrument (grev beg dur exp-amt file file-beg)
  (let ((exA (make-granulate :expansion exp-amt))
	(fil (make-file->sample file))
	(ctr file-beg))
    (do ((i beg (+ i 1)))
        ((= i (+ beg dur)))
      (outa i (granulate exA
                (lambda (dir)
	          (let ((inval (file->sample fil ctr 0)))
	            (if (> ctr 0) (set! ctr (- ctr 1)))
	            inval)))))))

(with-sound () (grev 0 100000 2.0 "pistol.snd" 40000))

But it's unnecessary to write clever input functions. It is just as fast, and much more perspicuous, to use sound-let in cases like this. Here's an example that takes any set of notes and calls granulate on the result:

(define-macro (gran-any beg dur expansion . body)
  `(sound-let ((tmp () ,@body))
     (let* ((start (floor (* *clm-srate* ,beg)))
	    (end (+ start (* *clm-srate* ,dur)))
	    (rd (make-readin tmp))
	    (gran (make-granulate :input rd :expansion ,expansion)))
       (do ((i start (+ i 1)))
	   ((= i end))
	 (outa i (granulate gran))))))

(with-sound () 
  (gran-any 0 2.5 4 
    (fm-violin 0 .1 440 .1) 
    (fm-violin .2 .1 660 .1) 
    (fm-violin .4 .1 880 .1)))

Any of the input-oriented generators (src, etc) can use this trick.

The "edit" argument can be a function of one argument, the current granulate generator. It is called just before a grain is added into the output buffer. The current grain is accessible via mus-data. The edit function, if any, should return the length in samples of the grain, or 0. In the following example, we use the edit function to reverse every other grain:

(let ((forward #t))
  (let ((grn (make-granulate :expansion 2.0
                             :edit (lambda (g)
                                     (let ((grain (mus-data g))  ; current grain
                                           (len (mus-length g))) ; current grain length
                                       (if forward ; no change to data
                                           (set! forward #f)
                                           (begin
                                             (set! forward #t)
                                             (reverse! grain)))
                                       len))))
        (rd (make-sampler 0)))
    (map-channel (lambda (y) (granulate grn (lambda (dir) (rd)))))))
phase-vocoder
make-phase-vocoder input (fft-size 512) (overlap 4) (interp 128) (pitch 1.0) analyze edit synthesize
phase-vocoder pv
phase-vocoder? pv
phase-vocoder methods
mus-frequencypitch shift
mus-lengthfft-size
mus-incrementinterp
mus-hopfft-size / overlap
mus-locationoutctr (counter to next fft)

The phase-vocoder generator performs phase-vocoder analysis and resynthesis. The process is split into three pieces, the analysis stage, editing of the amplitudes and phases, then the resynthesis. Each stage has a default that is invoked if the "analyze", "edit", or "synthesize" arguments are omitted from make-phase-vocoder or the phase-vocoder generator. The edit and synthesize arguments are functions of one argument, the phase-vocoder generator. The analyze argument is a function of two arguments, the generator and the input function. The default is to read the current input, take an fft, get the new amplitudes and phases (as the edit function default), then resynthesize using sines; so, the default case returns a resynthesis of the original input. The "interp" argument sets the time between ffts (for time stretching, etc).

(with-sound (:play #t) ; new pitch = 2 * old
  (let ((pv (make-phase-vocoder 
             (make-readin "oboe.snd") :pitch 2.0)))
    (do ((i 0 (+ i 1)))
	((= i 44100))
      (outa i (phase-vocoder pv)))))
with_sound(:play, true) do
  rd = make_readin("oboe.snd");
  pv = make_phase_vocoder(
         lambda do |dir| 
           readin(rd) end, :pitch, 2.0);
  88200.times do |i|
    outa(i, phase_vocoder(pv), $output);
    end
  end.output
lambda: ( -- )
  "oboe.snd" make-readin :pitch 2.0 make-phase-vocoder { pv }
  44100 0 do
    i  pv #f #f #f #f phase-vocoder  *output* outa drop
  loop
; :play #t with-sound drop
(with-sound (:play #t :srate 22050) ; new dur = 2 * old
  (let ((pv (make-phase-vocoder 
	     (make-readin "oboe.snd")
	     :interp 256)) ; 2 * 512 / 4
        ;; 512: fft size, 4: overlap, new dur: 2 * old dur
	(samps (* 2 (mus-sound-framples "oboe.snd"))))
    (do ((i 0 (+ i 1)))
	((= i samps))
      (outa i (phase-vocoder pv)))))
with_sound(:play, true, :srate, 22050) do
  rd = make_readin("oboe.snd");
  pv = make_phase_vocoder(
	lambda do |dir| readin(rd) end,
        :interp, 2 * 512 / 4);
  samps = 2 * mus_sound_framples("oboe.snd");
  samps.times do |i|
    outa(i, phase_vocoder(pv), $output);
    end
  end.output
lambda: ( -- )
  "oboe.snd" make-readin :interp 256 make-phase-vocoder { pv }
  "oboe.snd" mus-sound-framples 2* ( samps ) 0 do
    i  pv #f #f #f #f phase-vocoder  *output* outa drop
  loop
; :play #t :srate 22050 with-sound drop

There are several functions giving access to the phase-vocoder data:

phase-vocoder-amps gen
phase-vocoder-freqs gen
phase-vocoder-phases gen
phase-vocoder-amp-increments gen
phase-vocoder-phase-increments gen

These are arrays (float-vectors) containing the spectral data the phase-vocoder uses to reconstruct the sound. See clm23.scm for examples, in particular pvoc-e that specifies all of the functions with their default values (that is, it explicitly passes in functions that do what the phase-vocoder would have done without any function arguments). pvoc.scm implements the phase-vocoder directly in Scheme (rather than going through the CLM generator). In the next example we use all these special functions to resynthesize down an octave:

(with-sound (:srate 22050 :statistics #t)
  (let ((pv (make-phase-vocoder
	     (make-readin "oboe.snd")
	     512 4 128 1.0
	     #f ; no change to analysis method
	     #f ; no change to spectrum
	     (lambda (gen) ; resynthesis function
	       (float-vector-add! (phase-vocoder-amps gen) (phase-vocoder-amp-increments gen))
	       (float-vector-add! (phase-vocoder-phase-increments gen) (phase-vocoder-freqs gen))
	       (float-vector-add! (phase-vocoder-phases gen) (phase-vocoder-phase-increments gen))
	       (let ((sum 0.0)
		     (n (length (phase-vocoder-amps gen))))
		 (do ((k 0 (+ k 1)))
		     ((= k n))
		   (set! sum (+ sum (* (float-vector-ref (phase-vocoder-amps gen) k)
				       (sin (* 0.5 (float-vector-ref (phase-vocoder-phases gen) k)))))))
		 sum)))))
    (do ((i 0 (+ i 1)))
        ((= i 44100))
      (outa i (phase-vocoder pv)))))

but, sadly, this code crawls. It won't actually be useful until I optimize handling of the caller's resynthesis function, but I am dragging my feet because I've never felt that this phase-vocoder (as a generator) was the "right thing". The first step toward something less stupid is moving-spectrum in generators.scm.

asymmetric-fm
make-asymmetric-fm 
      (frequency *clm-default-frequency*) 
      (initial-phase 0.0) 
      (r 1.0)             ; amplitude ratio between successive sidebands
      (ratio 1.0)         ; ratio between carrier and sideband spacing
asymmetric-fm af index (fm 0.0)
asymmetric-fm? af
asymmetric-fm methods
mus-frequencyfrequency in Hz
mus-phasephase in radians
mus-scaler"r" parameter; sideband scaler
mus-offset"ratio" parameter
mus-incrementfrequency in radians per sample

The asymmetric-fm generator provides a way around the symmetric spectra normally produced by FM. See Palamin and Palamin, "A Method of Generating and Controlling Asymmetrical Spectra" JAES vol 36, no 9, Sept 88, p671-685. P&P use sin(sin), but I'm using cos(sin) so that we get a sum of cosines, and can therefore easily normalize the peak amplitude to -1.0..1.0. asymmetric-fm is based on:

e sin
I form
(with-sound (:play #t)
  (let ((fm (make-asymmetric-fm 440.0 0.0 0.9 0.5)))
    (do ((i 0 (+ i 1)))
	((= i 44100))
      (outa i (* 0.5 (asymmetric-fm fm 1.0))))))
with_sound(:play, true) do
  fm = make_asymmetric_fm(440.0, 0.0, 0.9, 0.5);
  44100.times do |i|
    outa(i, 0.5 * asymmetric_fm(fm, 1.0), $output);
    end
  end.output
lambda: ( -- )
  440.0 0.0 0.9 0.5 make-asymmetric-fm { fm }
  44100 0 do
    i  fm 1.0 0 asymmetric-fm  f2/ *output* outa drop
  loop
; :play #t with-sound drop

"r" is the ratio between successive sideband amplitudes, r < 0.0 or r > 1.0 pushes energy above the carrier, whereas r between 0.0 and 1.0 pushes it below. (r = 1.0 gives normal FM). The mirror image of r (around a given carrier) is produced by -1/r. "ratio" is the ratio between the carrier and modulator (i.e. sideband spacing). It's somewhat inconsistent that asymmetric-fm takes "index" (the fm-index) as its second argument, but otherwise it would be tricky to get time-varying indices. In this instrument we sweep "r" with an envelope:

(definstrument (asy beg dur freq amp index (ratio 1.0))
  (let* ((st (seconds->samples beg))
         (nd (+ st (seconds->samples dur)))
         (r-env (make-env '(0 -1 1 -20) :duration dur))
         (asyf (make-asymmetric-fm :ratio ratio :frequency freq)))
    (do ((i st (+ i 1))) 
        ((= i nd))
      (set! (mus-scaler asyf) (env r-env)) ; this sets "r"
      (outa i (* amp (asymmetric-fm asyf index))))))

For the other kind of asymmetric-fm see generators.scm, and for asymmetric spectra via "single sideband FM" see generators.scm.

frample->frample mf inf outfpass frample through a matrix multiply, return outf
sound IO

Sound file IO is based on a set of file readers and writers that deal either in samples or float-vectors. The six functions are file->sample, sample->file, file->frample, frample->file, array->file, and file->array. The name "array" is used here, rather than "float-vector" for historical reasons (the CL version of CLM predates Snd by many years). These functions are then packaged up in more convenient forms as in-any, out-any, locsig, readin, etc. Within with-sound, the variable *output* is bound to the with-sound output file via a sample->file object.

make-file->sample name (buffer-size 8192)
make-sample->file name (chans 1) (format mus-lfloat) (type mus-next) comment
file->sample? obj
sample->file? obj
file->sample obj samp chan
sample->file obj samp chan val
continue-sample->file file

make-file->frample name (buffer-size 8192)
make-frample->file name (chans 1) (format mus-lfloat) (type mus-next) comment
frample->file? obj
file->frample? obj
file->frample obj samp outf
frample->file obj samp val
continue-frample->file file

file->array file channel beg dur array
array->file file data len srate channels

mus-input? obj
mus-output? obj
mus-close obj
*output*
*reverb*
mus-file-buffer-size (also known as *clm-file-buffer-size*)
(with-sound (:channels 2)
  ;; swap channels of stereo file
  (let ((input (make-file->frample "stereo.snd"))
	(len (mus-sound-framples "stereo.snd"))
	(frample (make-float-vector 2 0.0)))
    (do ((i 0 (+ i 1)))
	((= i len))
      (file->frample input i frample)
      (let ((val (frample 0)))
	(set! (frample 0) (frample 1))
	(set! (frample 1) val))
      (frample->file *output* i frample))))
with_sound(:channels, 2) do
  input = make_file2frample("stereo.snd");
  len = mus_sound_framples("stereo.snd");
  frample = make_frample(2);
  len.times do |i|
    file2frample(input, i, frample);
    val = frample_ref(frample, 0);
    frample_set!(frample, 0, frample_ref(frample, 1));
    frample_set!(frample, 1, val);
    frample2file($output, i, frample);
    end
  end.output
lambda: ( -- )
  "stereo.snd" make-file->frample { input }
  2 make-frample { frm }
  "stereo.snd" mus-sound-framples ( len ) 0 do
    input i frm file->frample ( frm ) 1 frample-ref ( val1 )
    frm 0 frample-ref ( val0 ) frm 1 rot frample-set! drop
    ( val1 ) frm 0 rot frample-set! drop
    *output* i frm frample->file drop
  loop
; :channels 2 :play #t with-sound drop

file->sample writes a sample to a file, frample->file writes a frample, file->sample reads a sample from a file, and file->frample reads a frample. continue-frample->file and continue-sample->file reopen an existing file to continue adding sound data to it. mus-output? returns #t is its argument is some sort of file writing generator, and mus-input? returns #t if its argument is a file reader. In make-file->sample and make-file->frample, the buffer-size defaults to *clm-file-buffer-size*. There are many examples of these functions in snd-test.scm, clm-ins.scm, and clm23.scm. Here is one that uses file->sample to mix in a sound file (there are a zillion other ways to do this):

(define (simple-f2s beg dur amp file)
  (let* ((start (seconds->samples beg))
         (end (+ start (seconds->samples dur)))
         (fil (make-file->sample file))
         (ctr 0))
    (do ((i start (+ i 1))) ((= i end))
      (out-any i (* amp (file->sample fil ctr 0)) 0)
      (set! ctr (+ 1 ctr)))))

mus-close flushes any pending output and closes the output stream 'obj'. This is normally done for you by with-sound, but if you have your own output streams, and you forget to call mus-close, the GC will eventually do it for you.

readin
 make-readin file (channel 0) (start 0) (direction 1) size
 readin rd
 readin? rd
readin methods
mus-channelchannel arg to make-readin (no set!)
mus-locationcurrent location in file
mus-incrementsample increment (direction arg to make-readin)
mus-file-namename of file associated with gen
mus-lengthnumber of framples in file associated with gen

readin returns successive samples from a file; it is an elaboration of file->sample that keeps track of the current read location and channel number for you. Its "file" argument is the input file's name. "start" is the frample at which to start reading the input file. "channel" is which channel to read (0-based). "size" is the read buffer size in samples. It defaults to *clm-file-buffer-size*.

(with-sound (:play #t)
  (let ((reader (make-readin "oboe.snd")))
    (do ((i 0 (+ i 1)))
        ((= i 44100))
      (outa i (* 2.0 (readin reader))))))
with_sound(:play, true) do
  reader = make_readin("oboe.snd");
  44100.times do |i|
   outa(i, 2.0 * readin(reader), 
        $output);
   end
  end.output
lambda: ( -- )
  "oboe.snd" make-readin { reader }
  44100 0 do
    i  reader readin  f2/ *output* outa drop
  loop
; :play #t with-sound drop

Here is an instrument that applies an envelope to a sound file using readin and env:

(definstrument (env-sound file beg (amp 1.0) (amp-env '(0 1 100 1)))
  (let* ((st (seconds->samples beg))
         (dur (mus-sound-duration file))
         (rev-amount .01)
         (rdA (make-readin file))
         (ampf (make-env amp-env amp dur))
         (nd (+ st (seconds->samples dur))))
     (do ((i st (+ i 1)))
         ((= i nd))
       (let ((outval (* (env ampf) (readin rdA))))
           (outa i outval)
         (if *reverb* 
           (outa i (* outval rev-amount) *reverb*))))))

(with-sound () (env-sound "oboe.snd" 0 1.0 '(0 0 1 1 2 1 3 0)))
in-any, out-any
out-any loc data channel (output *output*)
outa loc data (output *output*)
outb loc data (output *output*)
outc loc data (output *output*)
outd loc data (output *output*)
out-bank gens loc input

in-any loc channel input
ina loc input
inb loc input

These are the "generic" input and output functions. out-any adds its "data" argument (a sound sample) into the "output" object at sample position "loc". The "output" argument can be a vector as well as the more usual frample->file object. or any output-capable CLM generator. In with-sound, the current output is *output* and the reverb output is *reverb*. outa is the same as out-any with a channel of 0. It is not an error to try to write to a channel that doesn't exist; the function just returns.

in-any returns the sample at position "loc" in "input". ina is the same as in-any with a channel of 0. As in out-any and friends, the "input" argument can be a file->frample object, or a vector.

(with-sound (:play #t)
  (let ((infile (make-file->sample "oboe.snd")))
    (do ((i 0 (+ i 1)))
        ((= i 44100))
      (out-any i (in-any i 0 infile) 0))))
with_sound(:play, true) do
  infile = make_file2sample("oboe.snd");
  44100.times do |i|
    out_any(i, in_any(i, 0, infile), 0, $output);
    end
  end.output
lambda: ( -- )
  "oboe.snd" make-file->sample { infile }
  44100 0 do
    i  i 0 infile in-any  0 *output* out-any drop
  loop
; :play #t with-sound drop
(definstrument (simple-ina beg dur amp file)
  (let* ((start (seconds->samples beg))
         (end (+ start (seconds->samples dur)))
         (fil (make-file->sample file)))
     (do ((i start (+ i 1)))
         ((= i end))
       (outa i 
         (* amp (in-any i 0 fil)))))) ; same as (ina i fil)

(with-sound () (simple-ina 0 1 .5 "oboe.snd"))

To write from with-sound to a vector, rather than a file, use its :output argument:

(with-sound (:output (make-float-vector 44100 0.0)) ; this sets *output*, the default output location
   (fm-violin 0 1 440 .1))

If *output* is a function, it should take 3 arguments, the sample number, current output value, and channel.

(let ((avg 0.0)
      (samps 0))
  (with-sound (:output (lambda (frample val chan) ; get the average of all the samples
                         (set! avg (+ avg val))
                         (set! samps (+ 1 samps))
                	 val))
    (do ((i 0 (+ i 1)))
	((> i 10))
      (outa i (* i .1))))
  (/ avg samps))

;; returns 0.5

Similarly, if in-any's "input" argument is a function, it takes the input location (sample number), and channel (0-based).

(let ((input (make-readin "oboe.snd" :start 1000)))
  (with-sound ((make-float-vector 10 0.0))
    (do ((i 0 (+ i 1)))
	((= i 10))
      (outa i (ina i (lambda (loc chn)
		       (readin input)))))))
(let ((outv (make-float-vector 10 0.0)))
  (with-sound ()
     (do ((i 0 (+ i 1)))
         ((= i 10))
      (outa i (* i .1) (lambda (loc val chan)
	 	         (set! (outv loc) val)))))
  outv) ; this is equivalent to using :output (make-float-vector 10 0.0) as a with-sound argument
locsig
 make-locsig 
        (degree 0.0)
        (distance 1.0) 
	(reverb 0.0)       ; reverb amount
        (output *output*)  ; output generator or location
	(revout *reverb*)  ; reverb output generator or location
        (channels (channels output))
	(type mus-interp-linear)
 locsig loc i in-sig
 locsig? loc

 locsig-ref loc chan
 locsig-set! loc chan val
 locsig-reverb-ref loc chan
 locsig-reverb-set! loc chan val

 move-locsig loc degree distance
 locsig-type ()
locsig methods
mus-dataoutput scalers (a float-vector)
mus-xcoeffreverb scaler
mus-xcoeffsreverb scalers (a float-vector)
mus-channelsoutput channels
mus-lengthoutput channels

locsig places a sound in an N-channel circle of speakers by scaling the respective channel amplitudes ("that old trick never works"). It normally replaces out-any. "reverb" determines how much of the direct signal gets sent to the reverberator. "distance" tries to imitate a distance cue by fooling with the relative amounts of direct and reverberated signal (independent of the "reverb" argument). The distance should be greater than or equal to 1.0. "type" (returned by the function locsig-type) can be mus-interp-linear (the default) or mus-interp-sinusoidal. The mus-interp-sinusoidal case uses sin and cos to set the respective channel amplitudes (this is reported to help with the "hole-in-the-middle" problem). The "output" argument can be a vector as well as a frample->file generator.

(with-sound (:play #t :channels 2)
  (let ((loc (make-locsig 60.0))
	(osc (make-oscil 440.0)))
    (do ((i 0 (+ i 1)))
	((= i 44100))
      (locsig loc i 
              (* 0.5 (oscil osc))))))
with_sound(:play, true, :channels, 2) do
  loc = make_locsig(60.0, :output, $output);
  osc = make_oscil(440.0);
  44100.times do |i|
    locsig(loc, i, 0.5 * oscil(osc));
    end
  end.output
lambda: ( -- )
  60.0 make-locsig { loc }
  440.0 make-oscil { osc }
  44100 0 do
    loc i  osc 0 0 oscil f2/  locsig drop
  loop
; :play #t :channels 2 with-sound drop

Locsig can send output to any number of channels. If channels > 2, the speakers are assumed to be evenly spaced in a circle. You can use locsig-set! to override the placement decisions. To have full output to both channels,

(locsig-set! loc 0 1.0) 
(locsig-set! loc 1 1.0)

Here is an instrument that has envelopes on the distance and degrees, and optionally reverberates a file:

(definstrument (space file onset duration (distance-env '(0 1 100 10)) (amplitude-env '(0 1 100 1))
		     (degree-env '(0 45 50 0 100 90)) (reverb-amount .05))
  (let* ((beg (seconds->samples onset))
	 (end (+ beg (seconds->samples duration)))
         (loc (make-locsig :degree 0 :distance 1 :reverb reverb-amount))
         (rdA (make-readin :file file))
         (dist-env (make-env distance-env :duration duration))
         (amp-env (make-env amplitude-env :duration duration))
         (deg-env (make-env degree-env :scaler (/ 1.0 90.0) :duration duration))
         (dist-scaler 0.0))
    (do ((i beg (+ i 1)))
        ((= i end))
      (let ((rdval (* (readin rdA) (env amp-env)))
            (degval (env deg-env))
            (distval (env dist-env)))
        (set! dist-scaler (/ 1.0 distval))
        (locsig-set! loc 0 (* (- 1.0 degval) dist-scaler))
        (if (> (channels *output*) 1)
            (locsig-set! loc 1 (* degval dist-scaler)))
        (if *reverb* 
            (locsig-reverb-set! loc 0 (* reverb-amount (sqrt dist-scaler))))
        (locsig loc i rdval)))))

(with-sound (:reverb jc-reverb :channels 2) 
  (space "pistol.snd" 0 3 :distance-env '(0 1 1 2) :degree-env '(0 0 1 90)))

For a moving sound source, see either move-locsig, Fernando Lopez Lezcano's dlocsig, or flocsig (flanged locsig) in generators.scm. Here is an example of move-locsig:

(with-sound (:channels 4)
  (let ((loc (make-locsig))
	(osc (make-oscil 440.0))
	(j 0))
    (do ((i 0 (+ i 1)))
        ((= i 360))
      (do ((k 0 (+ k 1)))
          ((= k 1000))
        (let ((sig (* .5 (oscil osc))))
          (locsig loc j sig)
          (set! j (+ j 1))))
      (move-locsig loc (* 1.0 i) 1.0))))
move-locsig example move-locsig example
linear interp sinusoidal interp

The interaction of outa, locsig, and *reverb* seems to be causing confusion, so here are some simple examples:

(load "nrev.scm")

(define (simp start end freq amp)
  (let ((os (make-oscil freq)))
    (do ((i start (+ i 1))) 
        ((= i end))
      (let ((output (* amp (oscil os))))
	(outa i output)
	(if *reverb* (outa i (* output .1) *reverb*))))))

; (with-sound () (simp 0 44100 440 .1))            ; no reverb
; (with-sound (:reverb nrev) (simp 0 44100 440 .1)); reverb


(define (locsimp start end freq amp)
  (let ((os (make-oscil freq))
	(loc (make-locsig :reverb .1)))
    (do ((i start (+ i 1))) 
        ((= i end))
      (locsig loc i (* amp (oscil os))))))

; (with-sound () (locsimp 0 44100 440 .1))            ; no reverb
; (with-sound (:reverb nrev) (locsimp 0 44100 440 .1)); reverb
move-sound
make-move-sound dlocs-list (output *output*) (revout *reverb*)
move-sound dloc i in-sig
move-sound? dloc

move-sound is intended as the run-time portion of dlocsig. make-dlocsig creates a move-sound structure, passing it to the move-sound generator inside the dlocsig macro. All the necessary data is packaged up in a list:

(list
  (start 0)               ; absolute sample number at which samples first reach the listener
  (end 0)                 ; absolute sample number of end of input samples
  (out-channels 0)        ; number of output channels in soundfile
  (rev-channels 0)        ; number of reverb channels in soundfile
  path                    ; interpolated delay line for doppler
  delay                   ; tap doppler env
  rev                     ; reverberation amount
  out-delays              ; delay lines for output channels that have additional delays
  gains                   ; gain envelopes, one for each output channel
  rev-gains               ; reverb gain envelopes, one for each reverb channel
  out-map)                ; mapping of speakers to output channels

Here's an instrument that uses this generator to pan a sound through four channels:

(define (simple-dloc beg dur freq amp)
  (let* ((os (make-oscil freq))
         (start (seconds->samples beg))
         (end (+ start (seconds->samples dur)))
         (loc (make-move-sound (list start end 4 0
                                              (make-delay 12) 
                                     (make-env '(0 0 10 1) :length dur)
                                     #f
                                     (make-vector 4 #f)
                                     (vector (make-env '(0 0 1 1 2 0 3 0 4 0) :duration dur)
                                             (make-env '(0 0 1 0 2 1 3 0 4 0) :duration dur)
                                             (make-env '(0 0 1 0 2 0 3 1 4 0) :duration dur)
                                             (make-env '(0 0 1 0 2 0 3 0 4 1) :duration dur))
                                     #f
                                     (vector 0 1 2 3)))))
    (do ((i start (+ i 1)))
        ((= i end))
      (move-sound loc i (* amp (oscil os))))))

(with-sound (:channels 4) (simple-dloc 0 2 440 .5))
Generic functions

Besides the 30 or so built-in generators, there are around 100 others defined in generators.scm. If we required separate functions for each generator for access to the generator internal state (current phase, for example), we'd end up with hundreds, or even thousands of accessors. Instead, all the generators respond to a set of "generic" functions. mus-frequency, for example, tries to return (or set) a generator's frequency, for any generator that has some sort of frequency field. The generic functions are:

mus-channelchannel being read/written
mus-channelschannels open
mus-copycopy a generator
mus-datafloat-vector of data
mus-describedescription of current state
mus-feedbackfeedback coefficient
mus-feedforwardfeedforward coefficient
mus-file-namefile being read/written
mus-frequencyfrequency (Hz)
mus-hophop size for block processing
mus-incrementvarious increments
mus-interp-typeinterpolation type (mus-interp-linear, etc)
mus-lengthdata length
mus-locationsample location for reads/writes
mus-namegenerator name ("oscil")
mus-offsetenvelope offset
mus-orderfilter order
mus-phasephase (radians)
mus-rampgranulate grain envelope ramp setting
mus-resetset gen to default starting state
mus-runrun any generator
mus-scalerscaler, normally on an amplitude
mus-widthwidth of interpolation tables, etc
mus-xcoeffx (input) coefficient
mus-xcoeffsfloat-vector of x (input) coefficients
mus-ycoeffy (output, feedback) coefficient
mus-ycoeffsfloat-vector of y (feedback) coefficients

Many of these are settable: (set! (mus-frequency osc1) 440.0) sets osc1's phase increment to (hz->radians 440.0). When I have a cold, I sometimes use the following function to see how high I can hear; count the audible tones and multiply by 1000:

(define (quick-check)
  (with-sound () 
    (let ((gen (make-oscil 1000))) 
      (do ((i 0 (+ i 1))) 
          ((= i 400000))
        (if (= (modulo i 20000) 0) 
            (set! (mus-frequency gen) (+ 1000 (/ i 20))))
        (outa i (* .5 (oscil gen)))))))

Another example is run-with-fm-and-pm in generators.scm which applies phase modulation (as well as the default frequency modulation) to any generator:

(define (run-with-fm-and-pm gen fm pm)
  (set! (mus-phase gen) (+ (mus-phase gen) pm))
  (let ((result (mus-run gen fm 0.0)))
    (set! (mus-phase gen) (- (mus-phase gen) pm))
    result))

mus-generator? returns #t if its argument is a generator. A generator defined via defgenerator can also take part in these methods.

Other generators

(this section is work in progress...)

There are dozens of generators scattered around the *.scm files that come with Snd. Some that come to mind:

analog-filter.scm:
    filter: butterworth-lowpass|highpass|bandpass|bandstop, 
            chebyshev-lowpass|highpass|bandpass|bandstop, 
            inverse-chebyshev-lowpass|highpass|bandpass|bandstop, 
            elliptic-lowpass|highpass|bandpass|bandstop,
            bessel-lowpass|highpass|bandpass|bandstop

clm-ins.scm:
    rms gain balance

dsp.scm:
    fir-filter: hilbert-transform, 
                highpass, lowpass, bandpass, bandstop, 
                differentiator,
                make-spencer-filter, 
                savitzky-golay-filter
   
    filter: butter-high-pass, butter-low-pass, butter-band-pass, butter-band-reject, 
            biquad,
            iir-low-pass, iir-high-pass, iir-band-pass, iir-band-stop, peaking,
            butter-lp, butter-hp, butter-bp, butter-bs
   
    volterra-filter

env.scm:
    power-env (and many env makers/modifiers)

extensions.scm:
    env-expt-channel (and many related env modifiers)

examp.scm:
    ramp, 
    sound-interp

moog.scm:
    moog-filter

prc95.scm:
    reed, bowtable, jettable, onep, lip, dc-block, delaya, delayl

zip.scm:
    zipper

In this section, we concentrate on the generators defined in generators.scm. Nearly all of them respond to the generic functions mus-name, mus-reset, mus-describe, mus-frequency, mus-scaler, mus-offset, mus-phase, and mus-order. The parameters are generally "frequency", "n" (the number of sidebands), "r" (the ratio between successive sideband amplitudes), and "ratio" (the ratio between the frequency and the spacing between successive sidebands).

make-polyoid 
         (frequency *clm-default-frequency*) 
         (partial-amps-and-phases '(1 1 0.0))   ; a list of harmonic numbers, their associated amplitudes, and their initial-phases

polyoid w (fm 0.0)
polyoid? w

polyoid-env w fm amps phases

make-noid (frequency 0.0) (n 1) phases
noid w (fm 0.0)

polyoid combines the first and second Chebyshev polynomials to provide a sum of sinusoids each with arbitrary amplitude and initial-phase. noid is a wrapper for polyoid that sets up n equal amplitude components, a generalization of ncos and nsin. noid's phase argument can be a float-vector, 'min-peak, 'max-peak, or omitted (#f). If omitted, the phases are set to random numbers between 0 and 2 pi; if a float-vector, the float-vector's values are used as the phases; if 'max-peak, all phases are set to pi/2 (ncos essentially — use (make-float-vector n 0.0) to get nsin); and if 'min-peak, the minimum peak amplitude phases in peak-phases.scm are used. In the 'min-peak and 'max-peak cases, noid's output is normalized to fall between -1.0 and 1.0. polyoid-env is an extension of polyoid that takes envelopes to control the amplitude and phase of each harmonic.

noid choices

We can use the peak-phases.scm phases to reduce the "spikiness" of the waveform with any set of components and component amplitudes. We could, for example, change noid to use

(set! (amps (+ j 1)) (/ (expt r (- i 1)) norm))

where "r" is the ratio between successive component amplitude: "nroid"? This is not as pointless as it might at first appear. Many of these waveforms actually sound different, despite having the same (magnitude) spectrum; the minimum peak version usually sounds raspier, and in the limit it can sound like white noise!

Check out the n=1024 case:

(with-sound () 
  (let ((samps 44100)
	(gen (make-noid 10.0 1024 'min-peak)))
    (do ((i 0 (+ i 1)))
	((= i samps))
      (outa i (* 0.5 (noid gen 0.0))))))
make-asyfm (frequency 0.0) (ratio 1.0) (r 1.0) (index 1.0)
asyfm-J gen (fm 0.0)
asyfm-I gen (fm 0.0)
asyfm? gen

These two generators produce the two flavors of asymmetric-fm. asyfm-J is the same as the built-in asymmetric generator; asyfm-I is the modified Bessel function version (the second formula in the asymmetric-fm section).

make-fmssb (frequency 0.0) (ratio 1.0) (index 1.0)
fmssb gen (fm 0.0)
fmssb? gen

This generator produces the "gapped" spectra mentioned in fm.html. It is used extensively in the various "imaginary machines". Also included in this section of generators.scm is fpmc, an instrument that performs FM with a complex index (complex in the sense of complex numbers).

make-blackman frequency n ; 1 <= n <= 10
blackman gen (fm 0.0)
blackman? gen

This produces a Blackman-Harris sum of cosines of order 'n'. It could be viewed as a special case of pulsed-env, or as yet another "kernel" along the lines of ncos.

make-sinc-train frequency (n 1)
sinc-train gen (fm 0.0)
sinc-train? gen

This produces a sinc-train ((sin x)/x) with n components. It is very similar to ncos.

make-pink-noise (n 1)
pink-noise gen
pink-noise? gen

This produces a reasonable approximation to 1/f noise, also known as pink-noise. 'n' sets the number of octaves used (starting at the high end); 12 is the recommended choice. (If n=1, you get white noise).

make-brown-noise frequency (amplitude 1.0)
brown-noise gen
brown-noise? gen

This produces (unbounded) brownian noise. 'amplitude' sets the maximum size of individual jumps.

make-green-noise (frequency 0.0) (amplitude 1.0) (low -1.0) (high 1.0)
green-noise gen (fm 0.0)
green-noise? gen

make-green-noise-interp (frequency 0.0) (amplitude 1.0) (low -1.0) (high 1.0)
green-noise-interp gen (fm 0.0)
green-noise-interp? gen

These two generators produce bounded brownian noise; "green-noise" was Michael McNabb's name for it. Unlike CLM's rand or rand-interp which produce white noise centered around 0.0, green-noise wanders around, bouncing off its bounds every now and then. This produces a noise that can be similar to pink noise (see some graphs under rand). My informal explanation is that each time we bounce off an edge, we're transferring energy from a low frequency into some higher frequency. It is still brownian noise however. The 'amplitude' argument controls how large individual steps can be; 'low' and 'high' set the overall output bounds; 'frequency' controls how often a new random number is chosen. Here's an instrument that fuzzes up its amplitude envelope a bit using green noise:

(definstrument (green3 start dur freq amp amp-env noise-freq noise-width noise-max-step)
  (let* ((grn (make-green-noise-interp :frequency noise-freq 
                                       :amplitude noise-max-step 
                                       :high (* 0.5 noise-width) :low (* -0.5 noise-width)))
	 (osc (make-oscil freq))
	 (e (make-env amp-env :scaler amp :duration dur))
	 (beg (seconds->samples start))
	 (end (+ beg (seconds->samples dur))))
    (do ((i beg (+ i 1)))
        ((= i end))
      (outa i (* (env e) 
	         (+ 1.0 (green-noise-interp grn))
		 (oscil osc))))))

(with-sound () 
  (green3 0 2.0 440 .5 '(0 0 1 1 2 1 3 0) 100 .2 .02))
make-adjustable-square-wave frequency (duty-factor 0.5) (amplitude 1.0)
adjustable-square-wave gen (fm 0.0)
adjustable-square-wave? gen

make-adjustable-triangle-wave frequency (duty-factor 0.5) (amplitude 1.0)
adjustable-triangle-wave gen (fm 0.0)
adjustable-triangle-wave? gen

make-adjustable-sawtooth-wave frequency (duty-factor 0.5) (amplitude 1.0)
adjustable-sawtooth-wave gen (fm 0.0)
adjustable-sawtooth-wave? gen

adjustable-square-wave produces a square-wave with optional "duty-factor" (ratio of pulse duration to pulse period). The other two are similar, producing triangle and sawtooth waves. There is also an adjustable-oscil. Use mus-scaler to set the duty-factor at run-time.

mus-scaler adjusts

A similar trick can make, for example, a squared-off triangle-wave:

(gen (make-triangle-wave 200.0 :amplitude 4)) ; amp sets slope
...
(outa i (max -1.0 (min 1.0 (triangle-wave gen))))
make-round-interp frequency n amplitude
round-interp gen (fm 0.0)
round-interp? gen

This is a rand-interp generator feeding a moving-average generator. "n" is the length of the moving-average; the higher "n", the more low-passed the output.

round-interp
make-moving-sum (n 128)
moving-sum gen y
moving-sum? gen

make-moving-rms (n 128)
moving-rms gen y
moving-rms? gen

make-moving-length (n 128)
moving-length gen y
moving-length? gen

make-weighted-moving-average n
weighted-moving-average gen y
weighted-moving-average? gen

make-exponentially-weighted-moving-average n
exponentially-weighted-moving-average gen y
exponentially-weighted-moving-average? gen

The "moving" generators are specializations of the moving-average generator. moving-sum keeps the ongoing sum of absolute values, moving-length the square root of the sum of squares, and moving-rms the square root of the sum of squares divided by the size. moving-rms is used in overlay-rms-env in draw.scm. weighted-moving-average weights the table entries by 1/n. Similarly exponentially-weighted-moving-average applies exponential weights (it is actually just a one-pole filter — this generator wins the "longest-name-for-simplest-effect" award). Also defined, but not tested, is moving-variance; in the same mold, but not defined, are things like moving-inner-product and moving-distance.

Bessel functions
make-bess (frequency 0.0) (n 0)
bess gen (fm 0.0)
bess? gen

bess produces the nth Bessel function. The generator output is scaled to have a maximum of 1.0, so bess's output is not the same as the raw bessel function value returned by bes-jn. The "frequency" argument actually makes sense here because the Bessel functions are close to damped sinusoids after their initial hesitation:

Jn

where the variables other than x remain bounded as x increases. This explains, in a sketchy way, why Jn(cos) and Jn(Jn) behave like FM. To see how close these are to FM, compare the expansion of J0(sin) with FM's cos(sin):

J(sin) and cos(sin)

Except for jpcos, the rest of the generators in this section suffer a similar fate. From a waveshaping perspective, we're using a sinusoid, or a modulated sinusoid, to index into the near-zero portion of a Bessel function, and the result is sadly reminiscent of standard FM. But they're such pretty formulas; I must be missing something.

make-j0evencos (frequency 0.0) (index 1.0)
j0evencos gen (fm 0.0)
j0evencos? gen

j0evencos produces the J0(index * sin(x)) case mentioned above (with the DC component subtracted out). If you sweep the index, the bandwidth is the same as in normal FM (J2k(B) is about 3log(k)*Jk(B/2)^2), but the B/2 factor causes the individual component amplitudes to follow the Bessel functions half as fast. So j0evencos produces a spectral sweep that is like FM's but smoother.

compare FM and j0evencos compare FM and j0evencos
(with-sound (:channels 2)
  (let* ((dur 1.0)
         (end (seconds->samples dur))
         (jmd (make-j0evencos 200.0))
	 (fmd (make-oscil 200.0))
         (ampf (make-env '(0 0  1 1  20 1  21 0) :scaler 0.5 :duration dur))
         (indf (make-env '(0 0  1 20) :duration dur)))
    (do ((i 0 (+ i 1)))
	((= i end))
      (let ((ind (env indf))
	    (vol (env ampf)))
	(set! (jmd 'index) ind)
	(outa i (* vol (- (cos (* ind (oscil fmd))) 
                          (bes-j0 ind)))) ; subtract out DC (see cos(B sin x) above)
	(outb i (* vol (j0evencos jmd)))))))
make-j0j1cos (frequency 0.0) (index 0.0)
j0j1cos gen fm
j0j1cos? gen
j0j1 formulsa

This uses J0(index * cos(x)) + J1(index * cos(x)) to produce a full set of cosines. It is not yet normalized correctly, and is very similar to normal FM.

make-izcos (frequency 0.0) (r 1.0)
izcos gen (fm 0.0)
izcos? gen
I(k) sum

This produces a sum of cosines scaled by In(r), again very similar to normal FM.

make-jjcos (frequency 0.0) (r 0.5) (a 1.0) (k 1.0)
jjcos gen (fm 0.0)
jjcos? gen

make-j2cos (frequency 0.0) (r 0.5) (n 1)
j2cos gen (fm 0.0)
j2cos? gen

make-jpcos (frequency 0.0) (r 0.5) (a 0.0) (k 1.0)
jpcos gen (fm 0.0)
jpcos? gen

make-jncos (frequency 0.0) (r 0.5) (a 1.0) (n 0)
jncos gen (fm 0.0)
jncos? gen

These produce a sum of cosines scaled by a product of Bessel functions; in a sense, there are two, or maybe three "indices". Normalization is handled correctly at least for jpcos. Of the four, jpcos seems the most interesting. "a" should not equal "r"; in general as a and r approach 1.0, the spectrum approaches "k" components, sometimes in a highly convoluted manner.

jjcos:more sums
j2cos:more sums
jpcos:more sums
jncos:more sums
make-jycos (frequency 0.0) (r 1.0) (a 1.0)
jycos gen (fm 0.0)
jycos? gen

This uses bes-y0 to produce components scaled by Yn(r)*Jn(a). bes-y0(0) is -inf, so a^2 + r^2 should be greater than 2ar, and r should be greater than 0.0. Tricky to use. (If you get an inf or a NaN from division by zero or whatever in Scheme, both the time and frequency graphs will be unhappy).

finite sums

These generators produce a set of n sinusoids. With a bit of bother, they could be done with polywave. I don't think there would be any difference, even taking FM into account.

make-nssb (frequency 0.0) (ratio 1.0) (n 1)
nssb gen (fm 0.0)
nssb? gen

nssb is the single side-band version of ncos and nsin. It is very similar to nxysin and nxycos.

make-ncos2 (frequency 0.0) (n 1)
ncos2 gen (fm 0.0)
ncos2? gen

This is the Fejer kernel. The i-th harmonic amplitude is (n-i)/(n+1).

sum of cosines
make-ncos4 (frequency 0.0) (n 1)
ncos4 gen (fm 0.0)
ncos4? gen

This is the Jackson kernel, the square of ncos2.

make-npcos (frequency 0.0) (n 1)
npcos gen (fm 0.0)
npcos? gen

This is the Poussin kernel, a combination of two ncos2 generators, one at "n" subtracted from twice another at 2n+1.

make-n1cos (frequency 0.0) (n 1)
n1cos gen (fm 0.0)
n1cos? gen

Another spikey waveform, very similar to ncos2 above.

linear cosines
make-nxycos (frequency 0.0) (ratio 1.0) (n 1)
nxycos gen (fm 0.0)
nxycos? gen

make-nxysin (frequency 0.0) (ratio 1.0) (n 1)
nxysin gen (fm 0.0)
nxysin? gen

make-nxy1cos (frequency 0.0) (ratio 1.0) (n 1)
nxy1cos gen (fm 0.0)
nxy1cos? gen

make-nxy1sin (frequency 0.0) (ratio 1.0) (n 1)
nxy1sin gen (fm 0.0)
nxy1sin? gen

These produce a sum of "n" sinsoids starting at "frequency", spaced by "ratio". Since "frequency" can be treated as the carrier, there's no point in an ssb version. nxy1cos is the same as nxycos, but every other component is multiplied by -1, and "n" produces 2n components. Normalization in the "sin" cases is tricky. If ratio is 1, we can use nsin's normalization, and if ratio = 2, noddsin's, but otherwise nxysin currently uses 1/n. This ensures that the generator output is always between -1 and 1, but in some cases (mainly involving low "n" and simple "ratio"), the output might not be full amplitude. nxy1sin is even trickier, so it divides by "n".

make-noddcos (frequency 0.0) (n 1)
noddcos gen (fm 0.0)
noddcos? gen

make-noddsin (frequency 0.0) (n 1)
noddsin gen (fm 0.0)
noddsin? gen

make-noddssb (frequency 0.0) (ratio 1.0) (n 1)
noddssb gen (fm 0.0)
noddssb? gen

These produce the sum of "n" equal amplitude odd-numbered sinusoids:

sum of cosines sum of sines

The corresponding "even" case is the same as ncos with twice the frequency. noddsin produces a somewhat clarinet-like tone:

(with-sound (:play #t)
  (let ((gen (make-noddsin 300 :n 3))
	(ampf (make-env '(0 0 1 1 2 1 3 0) :length 40000 :scaler .5)))
     (do ((i 0 (+ i 1)))
         ((= i 40000))
       (outa i (* (env ampf) (noddsin gen))))))

noddsin normalization is the same as nsin. The peak happens half as far from the 0 crossing as in nsin (3pi/(4n) for nsin, and 3pi/(8n) for noddsin (assuming large n)), and its amplitude is 8n*sin^2(3pi/8)/(3pi), just as in nsin. The noddsin generator scales its output by the inverse of this, so it is always between -1 and 1.

make-nrcos (frequency 0.0) (n 1) (r 0.5)             ; -1.0 < r < 1.0
nrcos gen (fm 0.0)
nrcos? gen

make-nrsin (frequency 0.0) (n 1) (r 0.5)             ; -1.0 < r < 1.0
nrsin gen (fm 0.0)
nrsin? gen

make-nrssb (frequency 0.0) (ratio 1.0) (n 1) (r 0.5) ; 0.0 <= r < 1.0
nrssb gen (fm 0.0)
nrssb-interp gen fm interp
nrssb? gen

These produce the sum of "n" sinusoids, with successive sinusoids scaled by "r"; the nth component has amplitude r^n. nrsin is just a wrapper for nrxysin, and the other two are obviously variants of nrxycos. In the nrssb-interp generator, the "interp" argument interpolates between the upper (interp=1.0) and lower (interp=-1.0) side bands.

The instrument lutish uses nrcos: lutish beg dur freq amp:

    (with-sound (:play #t)
      (do ((i 0 (+ i 1)))
          ((= i 10))
        (lutish (* i .1) 2 (* 100 (+ i 1)) .05)))

The instrument oboish uses nrssb: oboish beg dur freq amp amp-env:

    (with-sound (:play #t)
      (do ((i 0 (+ i 1)))
          ((= i 10))
        (oboish (* i .3) .4 (+ 100 (* 50 i)) .05 '(0 0 1 1 2 1 3 0))))

organish also uses nrssb: organish beg dur freq amp fm-index amp-env:

    (with-sound (:play #t)
      (do ((i 0 (+ i 1)))
          ((= i 10))
        (organish (* i .3) .4 (+ 100 (* 50 i)) .5 1.0 #f)))
make-nkssb (frequency 0.0) (ratio 1.0) (n 1)
nkssb gen (fm 0.0)
nkssb-interp gen fm interp
nkssb? gen

This generator produces the single side-band version of the sum of "n" sinusoids, where the nth component has amplitude n. In the nkssb-interp generator, the "interp" argument interpolates between the upper and lower side bands. The instrument nkssber uses nkssb-interp:

(with-sound (:play #t)
  (nkssber 0 1 1000 100 5 5 0.5)
  (nkssber 1 2 600 100 4 1 0.5)
  (nkssber 3 2 1000 540 3 3 0.5)
  (nkssber 5 4 300 120 2 0.25 0.5)
  (nkssber 9 1 30 4 40 0.5 0.5)
  (nkssber 10 1 20 6 80 0.5 0.5))
make-nsincos (frequency 0.0) (n 1)
nsincos gen (fm 0.0)
nsincos? gen

This generator produces a sum of n cosines scaled by sin(k*pi/(n+1))/sin(pi/(n+1)).

make-nchoosekcos (frequency 0.0) (ratio 1.0) (n 1)
nchoosekcos gen (fm 0.0)
nchoosekcos? gen

This generator produces a sum of n cosines scaled by the binomial coefficients. If n is even, the last term is halved. All these "finite sum" generators are a bit inflexible, and sound more or less the same. One (desperate) countermeasure is amplitude modulation:

(with-sound ()
  (let ((modulator (make-nchoosekcos 100.0 1.0 4))
	(carrier (make-nrcos 2000.0 :n 3 :r .5)))
    (do ((i 0 (+ i 1))) ((= i 20000))
      (outa i (* .5 (nrcos carrier) 
                    (nchoosekcos modulator))))))
am nchoosekcos
infinite sums
make-rcos (frequency 0.0) (r 0.5) ; -1.0 < r < 1.0
rcos gen (fm 0.0)
rcos? gen

make-rssb (frequency 0.0) (ratio 1.0) (r 0.5) ; -1.0 < r < 1.0
rssb gen (fm 0.0)
rssb-interp gen fm interp
rssb? gen

make-rxycos (frequency 0.0) (ratio 1.0) (r 0.5) ; -1.0 < r < 1.0
rxycos gen (fm 0.0)
rxycos? gen

make-rxysin (frequency 0.0) (ratio 1.0) (r 0.5) ; -1.0 < r < 1.0
rxysin gen (fm 0.0)
rxysin? gen

These generators produce an infinite sum of sinusoids, each successive component scaled by "r" (so the nth component has amplitude r^n). The bump instrument uses rssb-interp: bump beg dur freq amp f0 f1 f2:

(with-sound (:play #t)
  (do ((k 0 (+ k 1))) 
      ((= k 10))
    (bump (* 0.4 k) 1 (* 16.3 (expt 2.0 (+ 3 (/ k 12)))) .5 520 1190 2390))
  (do ((k 0 (+ k 1))) 
      ((= k 10))
    (let* ((freq (* 16.3 (expt 2.0 (+ 3 (/ k 12)))))
	   (scl (sqrt (/ freq 120))))
      (bump (+ 4 (* 0.4 k)) 1 freq  .5 (* scl 520) (* scl 1190) (* scl 2390)))))

As with all the "infinite sums" generators, aliasing is a major concern. We can use the following relatively conservative function to find the highest safe "r" given the current fundamental and sampling rate:

(define (safe-r-max freq srate) ; the safe-rxycos generator in generators.scm has this built-in
  (expt .001 (/ 1.0 (floor (/ srate (* 3 freq))))))

If you go over that value, be prepared for some very unintuitive behavior! For example, at an srate of 44100:

(with-sound (:channels 2)
  (let ((gen1 (make-rcos 1050 0.99))
        ;; r=.6 or so is the safe max
	(gen2 (make-rcos 1048 0.99)))
    (do ((i 0 (+ i 1)))
	((= i 88200))
      (outa i (rcos gen1))
      (outb i (rcos gen2)))))

In the first case, all the aliased harmonics line up perfectly with the unaliased ones because 21*1050 is 22050, but in the second case, we get (for example) the strong 84 Hz component because the 42nd harmonic which falls at 44100 - 42*1048 = 84 still has an amplitude of 0.99^42 = .66!

rcos aliased

Another artifact of aliasing is that at some frequencies, for example at 100 Hz, and a sampling rate of 44100, if r is -0.99 and the initial phase is 0.5*pi, or if r is 0.99 and the initial phase is 1.5*pi, the peak amp is only 0.6639. Finally(?), there's a sharp discontinuity (a click) as you sweep r through 0.0. As in nrxycos, the waveforms produced by r and -r are the same, but there's an overall phase difference of pi.

Other notes: the output of rssb is not normalized, nor is rxysin.

make-ercos (frequency 0.0) (r 0.5) ; r > 0.0
ercos gen (fm 0.0)
ercos? gen

make-erssb (frequency 0.0) (ratio 1.0) (r 0.5)
erssb gen (fm 0.0)
erssb? gen

These produce a sum of sinusoids, each scaled by e^(-kr), a special case of rcos. Our safe (minimum) "r" here becomes (/ (log 0.001) (floor (/ srate (* -3 freq)))). The ercoser instrument uses ercos: ercoser beg dur freq amp r:

    (with-sound (:play #t)
      (ercoser 0 1 100 .5 0.1))
make-eoddcos (frequency 0.0) (r 0.5)
eoddcos gen (fm 0.0)
eoddcos? gen

This produces a sum of odd harmonics, each scaled by e^r(2k-1)/(2k-1). As "r" approches 0.0, this approaches a square wave.

    (with-sound (:play #t)
      (let ((gen1 (make-eoddcos 400.0 :r 0.0))
	    (gen2 (make-oscil 400.0))
	    (a-env (make-env '(0 0 1 1) :length 10000)))
        (do ((i 0 (+ i 1)))
	    ((= i 10000))
	  (set! (gen1 'r) (env a-env))
 	  (outa i (* .5 (eoddcos gen1 (* .1 (oscil gen2))))))))
make-rkcos (frequency 0.0) (r 0.5) ; -1.0 < r < 1.0
rkcos gen (fm 0.0)
rkcos? gen

make-rksin (frequency 0.0) (r 0.5) ; -1.0 < r < 1.0
rksin gen (fm 0.0)
rksin? gen

make-rkssb (frequency 0.0) (ratio 1.0) (r 0.5) ; -1.0 < r < 1.0
rkssb gen (fm 0.0)
rkssb? gen

These produce a sum of sinusoids scaled by (r^k)/k. As r approaches 1.0 or -1.0, rksin approaches a sawtooth.

sawtooths

As with rcos, we can calculate the safe maximum r, given the current srate and frequency (this function is perhaps too cautious...):

    (define (safe-rk-max freq srate)
      (let ((topk (floor (/ srate (* 3 freq)))))
        (min 0.999999 (expt (* .001 topk) (/ 1.0 topk)))))

Similar to rkcos is (expt (asin (sqrt (oscil x))) 2). rksin and rkcos provide a nice demonstration of how insensitive the ear is to phase. These two waveforms look different, but have the same timbre. The sawtooth sounds louder to me, despite having the same peak amplitude.

(with-sound (:channels 2)
  (let ((gen1 (make-rkcos 200.0 :r 0.9))
        (gen2 (make-rksin 200.0 :r 0.9)))
    (do ((i 0 (+ i 1)))
	((= i 100000))
      (outa i (* .95 (rkcos gen1)))
      (outb i (* .95 (rksin gen2))))))

> (channel-rms 0 0) ; from dsp.scm
0.305301097090353
> (channel-rms 0 1)
0.627769794744852
sin vs cos

We might conclude that the RMS value gives the perceived amplitude, but in the next case, the RMS values are the same, and the peak amplitudes differ by a factor of 3. I think the one with the higher peak amplitude sounds louder.

(with-sound (:channels 2)
  (let ((gen1 (make-adjustable-square-wave 400 
	        :duty-factor .75 :amplitude .25))
	(gen2 (make-adjustable-square-wave 400 
                :duty-factor .11 :amplitude .75))
	(flt1 (make-moving-average 10))
	(flt2 (make-moving-average 10)))
    (do ((i 0 (+ i 1)))
	((= i 50000))
      (outa i (moving-average flt1 
                (adjustable-square-wave gen1)))
      (outb i (moving-average flt2 
                (adjustable-square-wave gen2))))))
rms vs peak

Since clipping is a disaster, we focus on peak amplitudes in the generators.

make-rk!cos (frequency 0.0) (r 0.5)  ; rk!cos is a special case of rxyk!cos
rk!cos gen (fm 0.0)
rk!cos? gen

make-rk!ssb (frequency 0.0) (ratio 1.0) (r 0.5)
rk!ssb gen (fm 0.0)
rk!ssb? gen

make-rxyk!cos (frequency 0.0) (ratio 1.0) (r 0.5)
rxyk!cos gen (fm 0.0)
rxyk!cos? gen

make-rxyk!sin (frequency 0.0) (ratio 1.0) (r 0.5)
rxyk!sin gen (fm 0.0)
rxyk!sin? gen

These produce a sum of sinusoids scaled by (r^k)/k!. The k! denominator dominates eventually, so r * ratio * frequency is approximately the spectral center (the ratio between successive harmonic amplitudes is (r^(k+1)/(k+1)!)/(r^k/k!) = r/(k+1), which becomes less than 1.0 at k=r). For example, in the graph on the right, the frequency is 100 and r is 30, so the center of the spectrum is around 3kHz. Negative "r" gives the same spectrum as positive, but the waveform's initial-phase is shifted by pi. The (very) safe maximum "r" is:

  (define (safe-rk!-max freq srate)
    (let ((topk (floor (/ srate (* 3 freq)))))
      (expt (* .001 (factorial topk)) (/ 1.0 topk))))
                  ;; factorial is in numerics.scm
rk!cos spectrum

As in other such cases, varying "r" gives changing spectra. You can sweep r through 0 smoothly except in rk!cos where you'll get a click. Coupled with the fm argument, these generators provide an extension of multi-carrier FM, similar in effect to the "leap-frog" FM voice. Here is a use of rk!cos to make a bird twitter:

(with-sound (:play #t :scaled-to .5)
  (do ((k 0 (+ k 1)))
      ((= k 6))
    (let ((gen (make-rk!cos 3000.0 :r 0.6)) 
          (ampf (make-env '(0 0 1 1 2 1 3 0) :length 3000))
	  (frqf (make-env '(0 0 1 1) :base .1 :scaler (hz->radians 2000) :length 3000)))
     (do ((i 0 (+ i 1)))
         ((= i 3000)) 
       (outa (+ i (* k 4000)) 
             (* (env ampf) 
	        (rk!cos gen (env frqf))))))))

The instrument bouncy uses rk!ssb: bouncy beg dur freq amp (bounce-freq 5) (bounce-amp 20)

    (with-sound (:play #t)
      (bouncy 0 2 200 .5 3 2))

brassy (also in generators.scm) uses rxyk!cos, but it is more of an experiment with envelopes than spectra. It takes a gliss envelope and turns it into a series of quick jumps between harmonics, handling both the pitch and the index ("r") of the rxyk!cos generator. The effect is vaguely brass-like.

make-r2k!cos (frequency 0.0) (r 0.5) (k 0.0)
r2k!cos gen (fm 0.0)
r2k!cos? gen

This generator produces a sum of cosines with a complicated-looking formula for the component amplitudes. It's actually pretty simple, as this graph shows. The "F" notation stands for a hypergeometric series, a generalization of sinusoids and Bessel functions.

sum of sines
r2k!cos spectra

Negative "r" gives the same output as the corresponding positive "r", and there is sometimes a lot of DC. Despite appearances, as r increases beyond 1.0, the spectrum collapses back towards the fundamental. (I think that r and 1/r produce the same spectrum). Aliasing can be a problem, especially when r is close to 1. The instruments pianoy and pianoy1 use r2k!cos: pianoy beg dur freq amp, and pianoy1 beg dur freq amp (bounce-freq 5) (bounce-amp 20):

    (with-sound (:play #t)
      (pianoy 0 3 100 .5))

    (with-sound (:play #t)
      (pianoy1 0 4 200 .5 1 .1))

pianoy2 combines r2k!cos with fmssb to try to get closer to the hammer sound:

    (with-sound (:play #t) 
      (pianoy2 0 1 100 .5))
make-rkoddssb (frequency 0.0) (ratio 1.0) (r 0.5) ; -1.0 < r < 1.0
rkoddssb gen (fm 0.0)
rkoddssb? gen

This produces a sum of odd-numbered harmonics scaled by (r^(2k-1))/(2k-1). This kind of spectrum is usually called "clarinet-like". Negative r gives the same output as positive. The (not very) safe maximum r is:

  (define (safe-rkodd-max-r freq srate)
    (let* ((topk (floor (/ srate (* 3 freq))))
           (k2-1 (- (* 2 topk) 1)))
      (expt (* .001 k2-1) (/ 1.0 k2-1))))

The instrument stringy uses rkoddssb and rcos: stringy beg dur freq amp:

(with-sound (:play #t)
  (do ((i 0 (+ i 1)))
      ((= i 10))
    (stringy (* i .3) .3 (+ 200 (* 100 i)) .5)))

glassy also uses rkoddssb: glassy beg dur freq amp:

(with-sound (:play #t)
  (do ((i 0 (+ i 1)))
      ((= i 10))
    (glassy (* i .3) .1 (+ 400 (* 100 i)) .5)))
make-k2sin (frequency 0.0)
k2sin gen (fm 0.0)
k2sin? gen

make-k2cos (frequency 0.0)
k2cos gen (fm 0.0)
k2cos? gen

make-k2ssb (frequency 0.0) (ratio 1.0)
k2ssb gen (fm 0.0)
k2ssb? gen

These produce a sum of sinusoids scaled by 1/(2^k).

make-k3sin (frequency 0.0)
k3sin gen fm
k3sin? gen

This produces a sum of sines scaled by 1.0/(k^3).

make-krksin (frequency 0.0) (r 0.5)
krksin gen (fm 0.0)
krksin? gen
sum of sines

This produces a sum of sinusoids scaled by kr^k. Its output is not normalized. I think the formula given assumes that r is less than 1.0, and in that case, the safe maximum r is given by:

  (define (safe-krk-max-r freq srate)
    (let ((topk (floor (/ srate (* 3 freq)))))
      (expt (/ .001 topk) (/ 1.0 topk))))

However, r can be greater than 1.0 without causing any trouble, and behaves in that case much like r2k!cos — as it increases, the spectrum collapses; I think r in that case is equivalent to 1/r. The only value to avoid is 1.0.

make-abcos (frequency 0.0) (a 0.5) (b 0.25)
abcos gen (fm 0.0)
abcos? gen

make-absin (frequency 0.0) (a 0.5) (b 0.25)
absin gen (fm 0.0)
absin? gen

These produce a sum of sinusoids scaled as follows:

sum of sines
make-r2k2cos (frequency 0.0) (r 0.5)
r2k2cos gen (fm 0.0)
r2k2cos? gen

This produces a sum of cosines, each scaled by 1/(r^2+k^2). r shouldn't be 0, but otherwise it almost doesn't matter what it is — this is not a very flexible generator!

There are a dozen or so other generators defined in generators.scm, but most are close variants of those given above.

make-tanhsin (frequency *clm-default-frequency*) (r 1.0) (initial-phase 0.0)
tanhsin gen (fm 0.0)
tanhsin? gen

This produces tanh(r * sin(x)) which approaches a square wave as "r" increases.

make-moving-fft (input #f) (n 512) (hop 128)
moving-fft gen
moving-fft? gen

moving-fft provides a sample-by-sample FFT (magnitudes and phases) of its input (currently assumed to be a readin generator). mus-xcoeffs returns the magnitudes, mus-ycoeffs returns the phases, and mus-data returns the current input block. We could mimic the fft display window in the "lisp graph" via:

(let* ((rd (make-readin "oboe.snd"))
       (ft (make-moving-fft rd))
       (data (make-float-vector 256 0.0)))
  (set! (lisp-graph?) #t)
  (do ((i 0 (+ i 1)))
      ((= i 10000))
    (moving-fft ft)
    (float-vector-subseq (mus-xcoeffs ft) 0 255 data)
    (graph data "fft" 0.0 11025.0 0.0 0.1 0 0 #t)))
make-moving-spectrum (input #f) (n 512) (hop 128)
moving-spectrum gen
moving-spectrum? gen

moving-spectrum provides a sample-by-sample spectrum (amplitudes, frequencies, and current phases) of its input (currently assumed to be a readin generator). It is identical to the first (analysis) portion of the phase-vocoder generator (see test-sv in generators.scm for details). To access the current amps and so on, use moving-spectrum-amps, moving-spectrum-phases, and moving-spectrum-freqs.

make-moving-autocorrelation (input #f) (n 512) (hop 128)
moving-autocorrelation gen
moving-autocorrelation? gen

moving-autocorrelation provides the autocorrelation of the last 'n' samples every 'hop' samples. The samples come from 'input' (currently assumed to be a readin generator). The output is accessible via mus-data.

make-moving-pitch (input #f) (n 512) (hop 128)
moving-pitch gen
moving-pitch? gen

moving-pitch provides the current pitch of its input, recalculated (via moving-autocorrelation) every 'hop' samples.

(let ((rd (make-readin "oboe.snd"))
      (cur-srate (srate "oboe.snd"))
      (old-srate *clm-srate*))
  (set! *clm-srate* cur-srate)
  (let ((scn (make-moving-pitch rd))
	(last-pitch 0.0)
	(pitch 0.0))
    (do ((i 0 (+ i 1)))
	((= i 22050))
      (set! last-pitch pitch)
      (set! pitch (moving-pitch scn))
      (if (not (= last-pitch pitch))
	  (format #t "~A: ~A~%" (* 1.0 (/ i cur-srate)) pitch))))
  (set! *clm-srate* old-srate))
make-moving-scentroid (dbfloor -40.0) (rfreq 100.0) (size 4096)
moving-scentroid gen
moving-scentroid? gen

moving-scentroid provides a generator that mimics Bret Battey's scentroid instrument (in dsp.scm or scentroid.ins).

make-flocsig (reverb-amount 0.0) (frequency 1.0) (amplitude 2.0) offset
flocsig gen i val
flocsig? gen

flocsig is a version of locsig that adds changing delays between the channels (flanging). The delay amount is set by a rand-interp centered around 'offset', moving as many as 'amplitude' samples (this also affects signal placement), and moving at a speed set by 'frequency'. Currently flocsig assumes stereo output and stereo reverb output. This generator is trying to open up the space in the same manner that flanging does, but hopefully unobtrusively. Here is an example, including a stereo reverb:

(definstrument (jcrev2)
  (let* ((allpass11 (make-all-pass -0.700 0.700 1051))
	 (allpass21 (make-all-pass -0.700 0.700  337))
	 (allpass31 (make-all-pass -0.700 0.700  113))
	 (comb11 (make-comb 0.742 4799))
	 (comb21 (make-comb 0.733 4999))
	 (comb31 (make-comb 0.715 5399))
	 (comb41 (make-comb 0.697 5801))
	 (outdel11 (make-delay (seconds->samples .01)))
				
	 (allpass12 (make-all-pass -0.700 0.700 1051))
	 (allpass22 (make-all-pass -0.700 0.700  337))
	 (allpass32 (make-all-pass -0.700 0.700  113))
	 (comb12 (make-comb 0.742 4799))
	 (comb22 (make-comb 0.733 4999))
	 (comb32 (make-comb 0.715 5399))
	 (comb42 (make-comb 0.697 5801))
	 (outdel12 (make-delay (seconds->samples .01)))
						       
	 (file-dur (framples *reverb*))
	 (decay-dur *clm-srate*)
	 (len (floor (+ decay-dur file-dur))))
    
    (do ((i 0 (+ i 1)))
	((= i len))
      (let* ((allpass-sum (all-pass allpass31 
				    (all-pass allpass21 
					      (all-pass allpass11 
							(ina i *reverb*)))))
	     (comb-sum (+ (comb comb11 allpass-sum)
			  (comb comb21 allpass-sum)
			  (comb comb31 allpass-sum)
			  (comb comb41 allpass-sum))))
	(outa i (delay outdel11 comb-sum)))
      
      (let* ((allpass-sum (all-pass allpass32 
				    (all-pass allpass22 
					      (all-pass allpass12 
							(inb i *reverb*)))))
	     (comb-sum (+ (comb comb12 allpass-sum)
			  (comb comb22 allpass-sum)
			  (comb comb32 allpass-sum)
			  (comb comb42 allpass-sum))))
	(outb i (delay outdel12 comb-sum))))))

(definstrument (simp beg dur (amp 0.5) (freq 440.0) (ramp 2.0) (rfreq 1.0) offset)
  (let* ((os (make-pulse-train freq))
	 (floc (make-flocsig :reverb-amount 0.1
			     :frequency rfreq
			     :amplitude ramp
			     :offset offset))
	 (start (seconds->samples beg))
	 (end (+ start (seconds->samples dur))))
    (do ((i start (+ i 1))) 
        ((= i end))
      (flocsig floc i (* amp (pulse-train os))))))

(with-sound (:channels 2 :reverb-channels 2 :reverb jcrev2) 
  (simp 0 1))
defgenerator
defgenerator name fields

defgenerator defines a generator. Its syntax is modelled after Common Lisp's defstruct. It sets up a structure, an environment with slots that you can get and set. It also defines a "make" function to create an instance of the environment, and a predicate for it. Here is a way to define oscil using defgenerator:

(defgenerator osc freq phase)

;;; make-osc creates an osc, and osc? returns #t if passed an osc.
;;; Once we have an osc (an environment with "freq" and "phase" locals)
;;;   we can either use with-let, or refer to the local variables
;;;   directly via (gen 'freq) and (gen 'phase).

(define (osc gen fm)                ; our new generator
  (let ((result (sin (gen 'phase))))
    (set! (gen 'phase) (+ (gen 'phase) (gen 'freq) fm))
    result))

;;; now we can use the osc generator in an instrument:

(definstrument (osc-fm beg dur freq amp mc-ratio fm-index)
  (let* ((start (seconds->samples beg))
	 (end (+ start (seconds->samples dur)))
	 (carrier (make-osc (hz->radians freq)))
	 (modulator (make-osc (hz->radians (* mc-ratio freq))))
	 (index (hz->radians (* freq mc-ratio fm-index))))
    (do ((i start (+ i 1)))
        ((= i end))
      (outa i (* amp (osc carrier (* index (osc modulator 0.0))))))))

(with-sound () (osc-fm 0 1 440 .1 1 1))

The first argument to defgenerator is the new object's name, and the rest are the fields of that object. Each field has a name and an optional initial value which defaults to 0.0. The "make" function (make-osc in our example) uses define* with the field names and initial values as the optional keys. So make-osc above is declared (by the defgenerator macro) as:

(define* (make-osc (freq 0.0) (phase 0.0)) ...)

which we can invoke in various ways, e.g.:

(make-osc 440)
(make-osc :phase (/ pi 2) :freq 440)
(make-osc 440 :phase 0.0)

The defgenerator "name" parameter can also be a list; in this case the first element is the actual generator name. The next elements are :make-wrapper followed by a function of one argument (the default object normally returned by defgenerator), and :methods, followed by a list of the methods the generator responds to. The make wrapper function can make any changes it pleases, then return the fixed-up generator. For example, in our "osc" generator, we had to remember to change frequency in Hz to radians; we can use the wrapper to handle that:

(defgenerator 
  (osc :make-wrapper (lambda (gen)
                       (set! (gen 'freq) (hz->radians (gen 'freq)))
                       gen))
        (freq 0.0) (phase 0.0))

and now the make process in the instrument can be simplified to:

...
(carrier (make-osc freq))
(modulator (make-osc (* mc-ratio freq)))
...

If you want the struct to take part in the generic function facility in CLM, add the desired methods as an association list with the keyword :methods:

(defgenerator (osc :make-wrapper
		     (lambda (gen)
		       (set! (gen 'freq) (hz->radians (gen 'freq)))
		       gen)
		   :methods
		     (list
		      (cons 'mus-frequency 
                            (dilambda
			      (lambda (g) (radians->hz (g 'freq)))
			      (lambda (g val) (set! (g 'freq) (hz->radians val)))))
		      (cons 'mus-phase 
                            (dilambda		          
			      (lambda (g) (g 'phase))
			      (lambda (g val) (set! (g 'phase) val))))
		      
		      (cons 'mus-describe 
			    (lambda (g) (format #f "osc freq: ~A, phase: ~A" 
					  (mus-frequency g) 
					  (mus-phase g))))))
  freq phase)

The make-wrapper might more accurately be called an after-method; it is evaluated at the end of the automatically-created make function. All the fields have been set at that point either by arguments to the make function, or from the default values given in the defgenerator declaration. The make function returns whatever the make-wrapper function returns, so you almost always want to return the "gen" argument. There are many examples in generators.scm.

Other functions

There are several functions closely tied to the generators and instruments.

hz->radians freqconvert freq to radians per sample (using *clm-srate*): (freq * 2 * pi) / srate
radians->hz radsconvert rads to Hz (using *clm-srate*): (rads * srate) / (2 * pi)
db->linear dBconvert dB to linear value: 10^(dB/20)
linear->db valconvert val to dB: 20 * log(x) / log(10)
times->samples start durationconvert start and duration from seconds to samples (beg+dur in latter case)
samples->seconds sampsconvert samples to seconds (using *clm-srate*): samps / srate
seconds->samples secsconvert seconds to samples (using *clm-srate*): secs * srate
degrees->radians degsconvert degrees to radians: (degs * 2 * pi) / 360
radians->degrees radsconvert radians to degrees: (rads * 360) / (2 * pi)
mus-sratesampling rate in with-sound (better known as *clm-srate*)
odd-weight xreturn a number between 0.0 (x is even) and 1.0 (x is odd)
even-weight xreturn a number between 0.0 (x is odd) and 1.0 (x is even)
odd-multiple x yreturn y times the nearest odd integer to x
even-multiple x yreturn y times the nearest even integer to x

hz->radians converts its argument to radians/sample (for any situation where a frequency is used as an amplitude — glissando or FM).

freq-in-hz * 2 * pi gives us the number of radians traversed per second; we then divide by the number of samples per second to get the radians per sample; in dimensional terms: (radians/sec) / (sample/sec) = radians/sample. We need this conversion whenever a frequency-related value is being accessed on every sample, as an increment of a phase variable.

> *clm-srate*
44100.0

> (hz->radians 440.0)
0.0626893772144902
> (/ (* 440.0 2 pi) 44100.0)
0.0626893772144902

> (linear->db .1)
-20.0

> (times->samples 1.0 2.0)
(44100 132300)
> (seconds->samples 2.0)
88200
> (samples->seconds 44100)
1.0

> (degrees->radians 45)
0.785398163397448
> (radians->degrees (/ pi 4))
45.0
mus-float-equal-fudge-factor (also known as *mus-float-equal-fudge-factor*)

This function sets how far apart generator float-vector elements can be and still be considered equal in equal?

> *mus-float-equal-fudge-factor*
1.0e-7
> (define v1 (float-vector .1 .1 .101))
#<unspecified>
> (define v2 (float-vector .1 .1 .1))
#<unspecified>
> (equal? v1 v2)
#f
> (set! *mus-float-equal-fudge-factor* .01)
1.0e-7 ; set! returns the previous value
> (equal? v1 v2)
#t
mus-array-print-length (also known as *mus-array-print-length*)

This function determines how many float-vector elements are printed by mus-describe.

polynomial
polynomial coeffs x

The polynomial function evaluates a polynomial, defined by giving its coefficients, at the point "x". "coeffs" is a vector of coefficients where coeffs[0] is the constant term, and so on.

> (polynomial (float-vector 0.0 1.0) 2.0) ; x
2.0
> (polynomial (float-vector 1.0 2.0 3.0) 2.0) ; 3x*x + 2x + 1
17.0

poly.scm has a variety of polynomial-related functions. Abramowitz and Stegun, "A Handbook of Mathematical Functions" is a treasure-trove of interesting polynomials.

array-interp, dot-product
array-interp fn x size
dot-product in1 in2
edot-product freq data
mus-interpolate type x v size y1

array-interp interpolates in the array "fn" at the point "x". It underlies the table-lookup generator, among others. Here's array-interp as a "compander":

(define compand-table (float-vector -1.0 -0.96 -0.90 -0.82 -0.72 -0.60 -0.45 -0.25 
                            0.0 0.25 0.45 0.60 0.72 0.82 0.90 0.96 1.0))

(map-channel
  (lambda (inval)
    (let ((index (+ 8.0 (* 8.0 inval))))
      (array-interp compand-table index 17))))

sound-interp in examp.scm fills an array with an entire sound, then uses array-interp to read it.

dot-product is the usual "inner product" or "scalar product" (a name that should be banned from polite society). We could define our own FIR filter using dot-product:

(define (make-fr-filter coeffs)
  (list coeffs (make-float-vector (length coeffs) 0.0)))

(define (fr-filter flt x)
  (let* ((coeffs (car flt))
	 (xs (cadr flt))
	 (xlen (length xs)))
    (float-vector-move! xs (- xlen 1) (- xlen 2) #t)
    (set! (xs 0) x)
    (dot-product coeffs xs xlen)))

edot-product returns the complex dot-product of the "data" argument (a vector) with (exp (* freq i)). Here, "i" goes from 0 to data's size - 1. "freq" and the elements of "data" can be complex, as can the return value. See stretch-sound-via-dft for an example.

mus-interpolate is the function used whenever table lookup interpolation is requested, as in delay or wave-train. The "type" argument is one of the interpolation types (mus-interp-linear, for example).

contrast-enhancement
contrast-enhancement in-samp (fm-index 1.0)

contrast-enhancement passes its input to sin as a kind of phase modulation.

(sin (+ (* input pi 0.5)
        (* index (sin (* input pi 2)))))

This brightens the input, helping it cut through a huge mix. A similar (slightly simpler) effect is:

(let ((mx (maxamp))) 
  (map-channel 
    (lambda (y) 
      (* mx (sin (/ (* pi y) mx))))))

This modulates the sound but keeps the output maxamp the same as the input. See moving-max for a similar function that does this kind of scaling throughout the sound, resulting in a steady modulation, rather than an intensification of just the peaks. And a sort of converse is sound-interp.

ring-modulate, amplitude-modulate
ring-modulate in1 in2                  ; returns (* in1 in2)
amplitude-modulate am-carrier in1 in2  ; returns (* in1 (+ am-carrier in2))
(with-sound (:play #t)
  (let ((osc1 (make-oscil 440.0))
	(osc2 (make-oscil 220.0)))
    (do ((i 0 (+ i 1)))
	((= i 44100))
      (outa i (* 0.5 (amplitude-modulate 0.3 (oscil osc1) (oscil osc2)))))))
with_sound(:play, true) do
  osc1 = make_oscil(440.0);
  osc2 = make_oscil(220.0);
  44100.times do |i|
    outa(i, 0.5 * amplitude_modulate(0.3, oscil(osc1), oscil(osc2)), $output);
    end
  end.output
lambda: ( -- )
  440.0 make-oscil { osc1 }
  220.0 make-oscil { osc2 }
  44100 0 do
    i
    0.3            ( car )
    osc1 0 0 oscil ( in1 )
    osc2 0 0 oscil ( in2 ) amplitude-modulate  f2/ *output* outa drop
  loop
; :play #t with-sound drop

ring-modulation is sometimes called "double-sideband-suppressed-carrier" modulation — that is, amplitude modulation with the carrier omitted (set to 0.0 above). The nomenclature here is a bit confusing — I can't remember now why I used these names; think of "carrier" as "carrier amplitude" and "in1" as "carrier". Normal amplitude modulation using this function is:

(define carrier (make-oscil carrier-freq (* .5 pi)))
...
(amplitude-modulate 1.0 (oscil carrier) signal)

Both of these functions take advantage of the "Modulation Theorem"; since multiplying a signal by e^(iwt) translates its spectrum by w / two pi Hz, multiplying by a sinusoid splits its spectrum into two equal parts translated up and down by w/(two pi) Hz:

coscos and sinsin

Waveshaping (via the Chebyshev polynomials) is an elaboration of AM. For example, cos^2x is amplitude modulation of cos x with itself, splitting into cos2x and cos0x. T2 (that is, 2cos^2x - 1) then subtracts the cos0x term to return cos2x.

The upper sidebands may foldover (alias); if it's a problem, low-pass filter the inputs (surely no CLM user needs that silly reminder!).

FFT (fourier transform)
mus-fft rdat idat fftsize sign
make-fft-window type size (beta 0.0) (alpha 0.0)
rectangular->polar rdat idat
rectangular->magnitudes rdat idat
polar->rectangular rdat idat
spectrum rdat idat window norm-type
convolution rdat idat size
autocorrelate data
correlate data1 data2

mus-fft, spectrum, and convolution are the standard functions used everywhere. fft is the Fourier transform, convolution convolves its arguments, and spectrum returns '(magnitude (rectangular->polar (fft))). The results are in dB (if "norm-type" is 0), or linear and normalized to 1.0 ("norm-type" = 1), or linear unnormalized. The name "mus-fft" is used to distuinguish clm's fft routine from Snd's; the only difference is that mus-fft includes the fft length as an argument, whereas fft does not. Here we use mus-fft to low-pass filter a sound:

(let* ((len (mus-sound-framples "oboe.snd"))
       (fsize (expt 2 (ceiling (log len 2))))
       (rdata (make-float-vector fsize 0.0))
       (idata (make-float-vector fsize 0.0))
       (cutoff (round (/ fsize 10)))
       (fsize2 (/ fsize 2)))
  (file->array "oboe.snd" 0 0 len rdata)
  
  (mus-fft rdata idata fsize 1)
  (do ((i cutoff (+ i 1))
       (j (- fsize 1) (- j 1)))
      ((= i fsize2))
    (set! (rdata i) 0.0)
    (set! (idata i) 0.0)
    (set! (rdata j) 0.0)
    (set! (idata j) 0.0))
  (mus-fft rdata idata fsize -1)
  
  (array->file "test.snd" 
	       (float-vector-scale! rdata (/ 1.0 fsize)) 
	       len 
	       (srate "oboe.snd") 
	       1)
  (let ((previous-case (find-sound "test.snd")))
    (if (sound? previous-case)
	(close-sound previous-case)))
  (open-sound "test.snd"))

make-fft-window can return many of the standard windows including:

bartlett-hann-window     bartlett-window        blackman2-window       blackman3-window
blackman4-window         bohman-window          cauchy-window          connes-window       
dolph-chebyshev-window   exponential-window     flat-top-window        gaussian-window     
hamming-window           hann-poisson-window    hann-window            kaiser-window
parzen-window            poisson-window         rectangular-window     riemann-window      
samaraki-window          tukey-window           ultraspherical-window  welch-window        
blackman5-window         blackman6-window       blackman7-window       blackman8-window       
blackman9-window         blackman10-window      rv2-window             rv3-window
rv4-window               mlt-sine-window        papoulis-window        dpss-window
sinc-window

rectangular->polar and polar->rectangular change how we view the FFT data: in polar or rectangular coordinates. rectangular->magnitudes is the same as rectangular->polar, but only calculates the magnitudes. autocorrelate performs an (in place) autocorrelation of 'data' (a float-vector). See moving-pitch in generators.scm, or rubber.scm. correlate performs an in-place cross-correlation of data1 and data2 (see, for example, snddiff).

FFTs
Hartley transform in Scheme: dht
Spectral edit dialog: Envelope Editor
fft-based filter: fft-edit, fft-env-edit, fft-env-interp, fft-squelch, fft-cancel
phase-vocoder: phase-vocoder. pvoc
transposition via fft: down-oct
phase rotation via fft: zero-phase, rotate-phase
duration change via autocorrelation: rubber-sound
smoothing via fft: fft-smoother
cross-synthesis: cross-synthesis
voiced->unvoiced effect: voiced->unvoiced
noise reduction: clean-channel, anoi
spectral modeling: pins
polynomial approach to spectral multiplies (convolution): spectral-polynomial
More transforms: fractional-fourier-transform, z-transform in dsp.scm
bark, mel, erb scale display: display-bark-fft
apply function to spectrum, inverse fft: filter-fft
Instruments

It's hard to decide what's an "instrument" in this context, but I think I'll treat it as something that can be called as a note in a notelist (in with-sound) and generate its own sound. There are hundreds of instruments scattered around the documentation, and most of the map-channel functions can be recast as instruments. There are also several that represent "classic" computer music instruments; they are listed here, documented in sndscm.html, and tested (via sample runs) in test 23 in snd-test.

instrument function CL Scheme Ruby Forth
complete-add additive synthesis add.ins
addflts filters addflt.ins dsp.scm dsp.rb
add-sound mix in a sound file addsnd.ins
bullfrog et al many animals (frogs, insects, birds) animals.scm
anoi noise reduction anoi.ins clm-ins.scm clm-ins.rb clm-ins.fs
autoc pitch estimation (Bret Battey) autoc.ins
badd fancier additive synthesis (Doug Fulton) badd.ins
bandedwg Juan Reyes banded waveguide instrument bandedwg.ins bandedwg.cms
fm-bell fm bell sounds (Michael McNabb) bell.ins clm-ins.scm clm-ins.rb clm-ins.fs
bigbird waveshaping bigbird.ins bird.scm bird.rb clm-ins.fs, bird.fs
singbowl Juan Reyes Tibetan bowl instrument bowl.ins bowl.cms
canter fm bagpipes (Peter Commons) canter.ins clm-ins.scm clm-ins.rb clm-ins.fs
cellon feedback fm (Stanislaw Krupowicz) cellon.ins clm-ins.scm clm-ins.rb clm-ins.fs
cnvrev convolution (aimed at reverb) cnv.ins clm-ins.scm
moving sounds sound movement (Fernando Lopez-Lezcano) dlocsig.lisp dlocsig.scm dlocsig.rb
drone additive synthesis (bag.clm) (Peter Commons) drone.ins clm-ins.scm clm-ins.rb clm-ins.fs
expandn granular synthesis (Michael Klingbeil) expandn.ins clm-ins.scm
granulate-sound examples granular synthesis expsrc.ins clm-ins.scm clm-ins.rb clm-ins.fs
cross-fade cross-fades in the frequency domain fade.ins fade.scm
filter-sound filter a sound file fltsnd.ins dsp.scm
stereo-flute physical model of a flute (Nicky Hind) flute.ins clm-ins.scm clm-ins.rb clm-ins.fs
fm examples fm bell, gong, drum (Paul Weineke, Jan Mattox) fmex.ins clm-ins.scm clm-ins.rb clm-ins.fs
Jezar's reverb fancy reverb (Jezar Wakefield) freeverb.ins freeverb.scm freeverb.rb clm-ins.fs
fofins FOF synthesis sndclm.html clm-ins.scm clm-ins.rb clm-ins.fs
fullmix a mixer fullmix.ins clm-ins.scm clm-ins.rb clm-ins.fs
grani granular synthesis (Fernando Lopez-Lezcano) grani.ins grani.scm
grapheq graphic equalizer (Marco Trevisani) grapheq.ins clm-ins.scm clm-ins.rb clm-ins.fs
fm-insect fm insect.ins clm-ins.scm clm-ins.rb
jc-reverb a reverberator (see also jlrev) jcrev.ins jcrev.scm clm-ins.rb clm-ins.fs
fm-voice fm voice (John Chowning) jcvoi.ins jcvoi.scm
kiprev a fancier reverberator (Kip Sheeline) kiprev.ins
lbj-piano additive synthesis piano (Doug Fulton) lbjPiano.ins clm-ins.scm clm-ins.rb clm-ins.fs
rotates Juan Reyes Leslie instrument leslie.ins leslie.cms
maraca Perry Cook's maraca physical models maraca.ins maraca.scm maraca.rb
maxfilter Juan Reyes modular synthesis maxf.ins maxf.scm maxf.rb
mlb-voice fm voice (Marc LeBrun) mlbvoi.ins clm-ins.scm clm-ins.rb clm-ins.fs
moog filters Moog filters (Fernando Lopez-Lezcano) moog.lisp moog.scm
fm-noise noise maker noise.ins noise.scm noise.rb clm-ins.fs
nrev a popular reverberator (Michael McNabb) nrev.ins clm-ins.scm clm-ins.rb clm-ins.fs
one-cut "cut and paste" (Fernando Lopez-Lezcano) one-cut.ins
p Scott van Duyne's piano physical model piano.ins piano.scm piano.rb
pluck Karplus-Strong synthesis (David Jaffe) pluck.ins clm-ins.scm clm-ins.rb clm-ins.fs
pqw waveshaping pqw.ins clm-ins.scm clm-ins.rb clm-ins.fs
pqw-vox waveshaping voice pqwvox.ins clm-ins.scm clm-ins.rb clm-ins.fs
physical models physical modelling (Perry Cook) prc-toolkit95.lisp prc95.scm prc95.rb clm-ins.fs
various ins from Perry Cook's Synthesis Toolkit prc96.ins clm-ins.scm clm-ins.rb clm-ins.fs
pvoc phase vocoder (Michael Klingbeil) pvoc.ins pvoc.scm pvoc.rb
resflt filters (Xavier Serra, Richard Karpen) resflt.ins clm-ins.scm clm-ins.rb clm-ins.fs
reson fm formants (John Chowning) reson.ins clm-ins.scm clm-ins.rb clm-ins.fs
ring-modulate ring-modulation of sounds (Craig Sapp) ring-modulate.ins examp.scm examp.rb
rmsenv rms envelope of sound (Bret Battey) rmsenv.ins
pins spectral modelling san.ins clm-ins.scm clm-ins.rb clm-ins.fs
scanned Juan Reyes scanned synthesis instrument scanned.ins dsp.scm
scentroid spectral scentroid envelope (Bret Battey) scentroid.ins dsp.scm
shepard Shepard tones (Juan Reyes) shepard.ins sndscm.html
singer Perry Cook's vocal tract physical model singer.ins singer.scm singer.rb
sndwarp Csound-like sndwarp generator (Bret Battey) sndwarp.ins sndwarp.scm
stochastic Bill Sack's stochastic synthesis implementation stochastic.insstochastic.scm
bow Juan Reyes bowed string physical model strad.ins strad.scm strad.rb
track-rms rms envelope of sound file (Michael Edwards) track-rms.ins
fm-trumpet fm trumpet (Dexter Morrill) trp.ins clm-ins.scm clm-ins.rb clm-ins.fs
various ins granular synthesis, formants, etc ugex.ins clm-ins.scm clm-ins.rb
test ins CLM regression tests — see clm-test.lisp ug(1,2,3,4).ins clm23.scm
fm-violin fm violin (fmviolin.clm, popi.clm) v.ins v.scm v.rb clm-ins.fs
vowel vowels (Michelle Daniels) vowel.ins
vox fm voice (cream.clm) vox.ins clm-ins.scm clm-ins.rb clm-ins.fs
zc, zn interpolating delays zd.ins clm-ins.scm clm-ins.rb clm-ins.fs
zipper The 'digital zipper' effect. zipper.ins zip.scm zip.rb

If you develop an interesting instrument that you're willing to share, please send it to me (bil@ccrma.stanford.edu). definstrument, the individual instruments, and with-sound are documented in sndscm.html.

snd-16.1/noise.rb0000644000076400007640000001107612306421672012005 0ustar bilbil# noise.rb -- CLM -> Snd/Ruby translation of noise.ins # Translator/Author: Michael Scholz # Created: Wed Mar 19 05:16:56 CET 2003 # Changed: Thu Oct 15 00:17:48 CEST 2009 # Comments beginning with ;; are taken from noise.ins! # attack_point(dur, attack, decay, total_x = 100.0) # fm_noise(...) # ;;; The "noise" instrument (useful for Oceanic Music): require "ws" require "env" include Env def attack_point(dur, attack, decay, total_x = 100.0) x = if 0.0 == attack if 0.0 == decay dur / 4.0 else (dur - decay) / 4.0 end else attack.to_f end total_x * (x / dur) end def fm_noise(start, dur, freq0, amp, ampfun, ampat, ampdc, freq1, glissfun, freqat, freqdc, rfreq0, rfreq1, rfreqfun, rfreqat, rfreqdc, dev0, dev1, devfun, devat, devdc, *args) degree, distance, reverb = nil optkey(args, binding, [:degree, kernel_rand(90.0)], [:distance, 1.0], [:reverb, 0.005]) # ;; ampat = amp envelope attack time, and so on -- this instrument # ;; assumes your envelopes go from 0 to 100 on the x-axis, and that # ;; the "attack" portion ends at 25, the "decay" portion starts at # ;; 75. "rfreq" is the frequency of the random number generator -- # ;; if below about 25 hz you get automatic composition, above that # ;; you start to get noise. well, you get a different kind of # ;; noise. "dev" is the bandwidth of the noise -- very narrow # ;; gives a whistle, very broad more of a whoosh. this is # ;; basically "simple fm", but the modulating signal is white # ;; noise. car = make_oscil(:frequency, freq0) mod = make_rand(:frequency, rfreq0, :amplitude, 1.0) dev_0 = hz2radians(dev0) # ;; next fix-up troubles in attack and decay times (there are lots # ;; of ways to handle this -- the basic problem is that these # ;; durned instruments end up having way too many parameters. rick # ;; taube's common music replacement for pla should help, but just # ;; for old time's sake, we'll do it the way the ancients did it. # ;; (we could also package up this stuff in our own function, # ;; somewhat like the allvln function in vln.clm, leaving the # ;; instrument code to apply envelopes and other data to some # ;; patch). amp_attack = attack_point(dur, ampat, ampdc) amp_decay = 100.0 - attack_point(dur, ampdc, ampat) freq_attack = attack_point(dur, freqat, freqdc) freq_decay = 100.0 - attack_point(dur, freqdc, freqat) dev_attack = attack_point(dur, devat, devdc) dev_decay = 100.0 - attack_point(dur, devdc, devat) rfreq_attack = attack_point(dur, rfreqat, rfreqdc) rfreq_decay = 100.0 - attack_point(dur, rfreqdc, rfreqat) # ;; now make the actual envelopes -- these all assume we are # ;; thinking in terms of the "value when the envelope is 1" # ;; (i.e. dev1 and friends), and the "value when the envelope is 0" # ;; (i.e. dev0 and friends) -- over the years this seemed to make # ;; beginners happier than various other ways of describing the # ;; y-axis behaviour of the envelope. all this boiler-plate for # ;; envelopes might seem overly elaborate when our basic instrument # ;; is really simple, but in most cases, and this one in # ;; particular, nearly all the musical interest comes from the # ;; envelopes, not the somewhat dull spectrum generated by the # ;; basic patch. dev_f = make_env(stretch_envelope(devfun, 25, dev_attack, 75, dev_decay), hz2radians(dev1 - dev0), dur) amp_f = make_env(stretch_envelope(ampfun, 25, amp_attack, 75, amp_decay), amp, dur) freq_f = make_env(stretch_envelope(glissfun, 25, freq_attack, 75, freq_decay), hz2radians(freq1 - freq0), dur) rfreq_f = make_env(stretch_envelope(rfreqfun, 25, rfreq_attack, 75, rfreq_decay), hz2radians(rfreq1 - rfreq0), dur) run_instrument(start, dur, :degree, degree, :distance, distance, :reverb_amount, reverb) do env(amp_f) * oscil(car, env(freq_f) + (dev_0 + env(dev_f)) * rand(mod, env(rfreq_f))) end end =begin with_sound(:statistics, true, :play, 1) do fm_noise(0, 1.8, 500, 0.25, [0, 0, 25, 1, 75, 1, 100, 0], 0.1, 0.1, 1000, [0, 0, 100, 1], 0.1, 0.1, 10, 1000, [0, 0, 100, 1], 0, 0, 100, 500, [0, 0, 100, 1], 0, 0) fm_noise(2, 1.8, 200, 0.25, [0, 0, 25, 1, 75, 1, 100, 0], 0.1, 0.1, 1000, [0, 0, 100, 1], 0.1, 0.1, 10, 1000, [0, 0, 100, 1], 0, 0, 100, 500, [0, 0, 100, 1], 0, 0) end =end # noise.rb ends here snd-16.1/sndscm.html0000644000076400007640000151620712623170516012527 0ustar bilbil Scheme, Ruby, and Forth Functions included with Snd
Scheme, Ruby, and Forth Functions included with Snd

This file describes the Scheme, Ruby, and Forth code included with Snd. To use this code, load the relevant file:

Scheme: (load "dsp.scm") or (load-from-path "dsp.scm")
Ruby:   load "dsp.rb"
Forth:  "dsp.fs" file-eval

To start Snd with the file already loaded, snd -l v.scm, or put the load statement in your initialization file. For help with Forth and Snd/CLM, see the Forth documentation section "Snd, CLM, and Fth".

Contents
analog-filter standard IIR filters (Butterworth, Chebyshev, Bessel, Elliptic)
animals a bunch of animals
autosave auto-save (edit backup) support
bess FM demo
binary-io binary files
bird North-American birds
clean noise reduction
clm-ins, clm23, jcvoi various CLM instruments
dlocsig moving sounds (Michael Scholz)
draw graphics additions
dsp various DSP-related procedures
env envelope functions
enved envelope editor
examp many examples
extensions various generally useful Snd extensions
fade frequency-domain cross-fades
freeverb a reverb
generators.scm a bunch of generators
grani CLM's grani (Fernando Lopez-Lezcano) translated by Mike Scholz
heart use Snd with non-sound (arbitrary range) data
hooks functions related to hooks
index snd-help extension
inf-snd.el, DotEmacs Emacs subjob support (Michael Scholz, Fernando Lopez-Lezcano)
jcrev John Chowning's ancient reverb
lint A lint program for scheme code
maraca Perry Cook's maraca physical model
marks functions related to marks
maxf Max Mathews resonator
menus additional menus
mix functions related to mixes
moog Moog filter
musglyphs Music notation symbols (from CMN)
nb Popup File info etc
noise noise maker
numerics various numerical functions
peak-phases phases for the unpulse-train
piano piano physical model
play play-related functions
poly polynomial-related stuff
prc95 Perry Cook's physical model examples
pvoc phase-vocoder
rgb color names
rubber rubber-sound
s7test s7 regression tests
selection functions acting on the current selection
singer Perry Cook's vocal-tract physical model
snd13|14|15.scm Backwards compatibility
snddiff sound difference detection
snd-gl OpenGL examples (gl.c)
snd-motif, snd-gtk, snd-xm Motif/Gtk module (xm.c, xg.c)
snd-test Snd regression tests
sndwarp Bret Battey's sndwarp instrument
spectr instrument steady state spectra
stochastic Bill Sack's dynamic stochastic synthesis
strad string physical model (from CLM)
v fm-violin
ws with-sound
zip the zipper (the anti-cross-fader)
analog-filter
make-butterworth-lowpass order fcut
make-butterworth-highpass order fcut
make-butterworth-bandpass order flo fhi
make-butterworth-bandstop order flo fhi

make-chebyshev-lowpass order fcut (ripple-dB 1.0)
make-chebyshev-highpass order fcut (ripple-dB 1.0)
make-chebyshev-bandpass order flo fhi (ripple-dB 1.0)
make-chebyshev-bandstop order flo fhi (ripple-dB 1.0)

make-inverse-chebyshev-lowpass order fcut (loss-dB 60.0)
make-inverse-chebyshev-highpass order fcut (loss-dB 60.0)
make-inverse-chebyshev-bandpass order flo fhi (loss-dB 60.0)
make-inverse-chebyshev-bandstop order flo fhi (loss-dB 60.0)

make-bessel-lowpass order fcut
make-bessel-highpass order fcut
make-bessel-bandpass order flo fh
make-bessel-bandstop order flo fh

make-elliptic-lowpass order fcut (ripple-dB 1.0) (loss-dB 60.0)
make-elliptic-highpass order fcut (ripple-dB 1.0) (loss-dB 60.0)
make-elliptic-bandpass order flo fhi (ripple-dB 1.0) (loss-dB 60.0)
make-elliptic-bandstop order flo fhi (ripple-dB 1.0) (loss-dB 60.0)

;; fcut = cutoff frequency in terms of srate = 1.0, 
;; flo = low freq of band, fhi = high freq of band

analog-filter.scm has the usual IIR filters: Butterworth, Chebyshev, inverse Chebyshev, Bessel, and Elliptic filters in lowpass, highpass, bandpass, and bandstop versions. Each of the lowpass and highpass "make" functions returns a filter generator, whereas the bandstop and bandpass make functions return a function of one argument, the current input (the filter generators are built-in in these cases). The filter order should be an even number; very high orders can cause numerical disaster! The elliptic filters depend on GSL, so you'll also need GSL (Snd's configure script includes it by default, if possible).

(let ((flt (make-elliptic-lowpass 8 .1))) ; 8th order elliptic with cutoff at .1 * srate
  (map-channel flt))                       ; flt is a clm filter generator

One quick way to see the frequency response of your filter is to create a sound that sweeps a sinewave upward in frequency, run it through the filter, then view the entire sound, treating the x axis as frequency in terms of srate = 1.0 (for convenience):

(define (filter-sweep flt chan)
  (let ((phase 0.0)
	(freq 0.0)
	(incr (/ (* 2 pi) 44100.0))
        (samps (seconds->samples 0.5)))
    (do ((i 0 (+ i 1)))
	((= i samps))
      (let ((sval (* .8 (sin phase))))
	(set! phase (+ phase freq)) 
	(set! freq (+ freq incr))
	(out-any i (flt sval) chan)))))

(with-sound (:channels 5 :output "test.snd")
  (filter-sweep (make-butterworth-lowpass 8 .1) 0)
  (filter-sweep (make-bessel-lowpass 8 .1) 1)
  (filter-sweep (make-chebyshev-lowpass 8 .1) 2)
  (filter-sweep (make-inverse-chebyshev-lowpass 8 .1) 3)
  (filter-sweep (make-elliptic-lowpass 8 .1) 4))
IIR filters, order=8, low cutoff at .1 (4410Hz), high cutoff at .3 (13230Hz)
iir filters
see also:   dsp   examp   moog   maxf   prc95   graphEq   clm
animals

People paint birds; why not bird songs? Check out a Hermit Thrush song down 2 or 3 octaves and slowed down as well (via granular synthesis, for example) — incredibly beautiful 2-part microtonal counterpoint. animals.scm contains several synthesized animal sounds: frogs, birds, insects, and one mammal. To hear them all, (calling-all-animals).

How to Paint a Bird Song

Back in 1980, I wanted some bird songs for "Colony", but my stabs at a fake bird song were completely unconvincing. So I went to my battered bird book (Robbins, Bruun, Zim, Singer "Birds of North America" Golden Press, NY 1966) which had sonograms of lots of bird songs. Unfortunately, the graphs were so tiny that I could barely read them:

Lincoln's Sparrow, approximately original size Lincoln's Sparrow approximately original size, but blurrier due to incredibly bad scanner software.

Graphs like this became bird.scm. It surprised me that the synthetic song could sound good even with just a sinewave and a couple sketchy envelopes. But squawks and screeches were harder. 27 years later, I tackled animal sounds again, but now using Snd and some extremely high quality recordings, mainly from Cornell. It's not that hard to match some animal sounds; perhaps someone would like to see the steps I took to match a Hairy Woodpecker call (hairy-woodpecker in animals.scm).

Open the Hairy Woodpecker. Find a squawk that seems within reach, and select it.

selecting a squawk

Zoom onto the first channel (the vertical slider on the right — we don't care about stereo here), and center the squawk in the time domain window (C-x v). Get the selection duration in seconds. Start the envelope editor dialog (under the Edit menu). Choose "selection" and "wave" in that dialog.

zoom in

Since the goal is a CLM instrument that synthesizes this sound, get a "blank bird", and fill in the duration.

(definstrument (hairy-woodpecker beg amp)
  (let* ((start (seconds->samples beg))
	 (dur 0.08)                                      ; filled in from the selection duration
	 (stop (+ start (seconds->samples dur)))
	 (ampf (make-env '                               ; left blank for the moment
			 :duration dur :scaler amp))
	 (gen1 (make-oscil))
	 (frqf (make-env '                               ; ditto
			 :duration dur :scaler (hz->radians 1.0))))
   (do ((i start (+ i 1)))
       ((= i stop))
     (outa i (* (env ampf)                           ; just a first guess at the synthesis algorithm
	        (oscil gen1 (env frqf)))))))

Now to get an amplitude envelope, set the y axis limits to be from 0.0 to the selection maxamp:

(set! (y-bounds (selected-sound) (selected-channel)) (list 0 (selection-maxamp)))

I have this action bound to the "m" key in my ~/.snd initialization file. The change is reflected in the envelope editor. We can define the amplitude envelope by approximating the shape. Call it "hairy-amp".

get amp env

Now go to the listener and get the value of hairy-amp as a list of breakpoints. I usually use this function to get the breakpoints:

> (define (clean-string e)
    (format #f "(~{~,3F~^ ~})" e))

> (clean-string hairy-amp)
"(0.000 0.000 0.099 0.188 0.152 0.148 0.211 0.558 0.242 0.267 0.278 0.519 0.434 0.472 0.527 0.543 0.612 0.479 
  0.792 0.941 0.831 0.523 0.854 1.000 0.913 0.422 0.927 0.200 0.946 0.430 0.971 0.304 1.000 0.000 )"

Plug this list into the bird instrument (ampf). Now switch to the FFT view (click "f" and "w"), open the FFT dialog (Options:Transform), choose Blackman10 window, sonogram, 512. In the color dialog, choose the "jet" colormap. In the envelope editor, switch from "amp" to "flt", and resize the dialog window so that its graph fits the displayed spectrum. For fast moving sounds, it's important to align the amp and freq envelopes exactly, but the FFT delays or blurs stuff, so mess with the graph placement until the amplitude envelope and the spectrum match (bright spots at loud spots and so on). I bind the arrow keys to precision movements for this reason (in my ~/.snd file, see move-one-pixel).

preapring to get freq env

Reset the envelope editor (to erase the amp envelope), and press "flt" and "wave" again. Now zoom in to the main spectral component (drag the FFT y axis up), and trace out the frequency curve in the envelope editor. Call it hairy-freq, and get the list of breakpoints as before in the listener. Plug that into the bird instrument. The "scaler" for the frequency envelope is the top of the FFT graph in Hz; it is 10KHz in this case.

get freq env
(definstrument (hairy-woodpecker beg amp)
  (let* ((start (seconds->samples beg))
	 (dur 0.08)
	 (stop (+ start (seconds->samples dur)))
	 (ampf (make-env '(0.000 0.000 0.099 0.188 0.152 0.148 0.211 0.558 0.242 0.267 0.278 0.519 0.434 0.472 
			   0.527 0.543 0.612 0.479 0.792 0.941 0.831 0.523 0.854 1.000 0.913 0.422 0.927 0.200 
			   0.946 0.430 0.971 0.304 1.000 0.000 )
			 :duration dur :scaler amp))
	 (frqf (make-env '(0.000 0.180 0.056 0.213 0.135 0.241 0.167 0.305 0.191 0.396 0.212 0.402 0.242 0.485 
			   0.288 0.506 0.390 0.524 0.509 0.530 0.637 0.537 0.732 0.530 0.770 0.503 0.808 0.503 
			   0.826 0.427 0.848 0.366 0.889 0.345 0.913 0.232 1.000 0.198)
			 :duration dur :scaler (hz->radians 10000.0)))
	 (gen1 (make-oscil)))
   (do ((i start (+ i 1)))
       ((= i stop))
     (outa i (* (env ampf)
	        (oscil gen1 (env frqf)))))))

This squawk has more than one component (it is not just a sine wave), and the components follow more or less the same amplitude envelope (so we can use polywave). Go to the "single transform" view (in the Transform dialog), make the FFT size bigger, move the time domain window into about the middle of the call, and get some estimate of the number of components and their relative amplitudes (concentrating for now on the steady state). Change the "make-oscil" to "make-polywave" and give some first stab at the steady-state spectrum:

...
(gen1 (make-polywave :partials (list 1 .9  2 .1  3 .01)))
  ...
(polywave gen1 (env frqf))
...

Load ws.scm, load the current woodpecker code, and listen to the squawk: (with-sound (:play #t) (hairy-woodpecker 0.0 0.5)). Not terrible. If it's cut off during playback, add a dummy silent call to the end: (with-sound (:play #t) (hairy-woodpecker 0.0 0.5) (hairy-woodpecker 0.5 0.0)). We're happy at this stage if it's in the right ballpark.

first take

The attack and decay sections need work. Returning to either FFT view, it's clear there's a set of components moving together at half the steady state frequency, so add another polywave with its own amplitude envelope:

(definstrument (hairy-woodpecker beg amp)
  (let* ((start (seconds->samples beg))
	 (dur 0.08)
	 (stop (+ start (seconds->samples dur)))
	 (ampf (make-env '(0.000 0.000 0.099 0.188 0.152 0.148 0.211 0.558 0.242 0.267 0.278 0.519 0.434 0.472 
			   0.527 0.543 0.612 0.479 0.792 0.941 0.831 0.523 0.854 1.000 0.913 0.422 0.927 0.200 
			   0.946 0.430 0.971 0.304 1.000 0.000 )
			 :duration dur :scaler amp))
	 (frqf (make-env '(0.000 0.180 0.056 0.213 0.135 0.241 0.167 0.305 0.191 0.396 0.212 0.402 0.242 0.485 
			   0.288 0.506 0.390 0.524 0.509 0.530 0.637 0.537 0.732 0.530 0.770 0.503 0.808 0.503 
			   0.826 0.427 0.848 0.366 0.889 0.345 0.913 0.232 1.000 0.198)
			 :duration dur :scaler (hz->radians 10000.0)))
	 (gen1 (make-polywave :partials (list 1 .9  2 .09  3 .01)))
	 (gen2 (make-polywave :partials (list 1 .2  2 .1  3 .1  4 .1  5 .1  6 .05  7 .01))) ; attack and decay
	 (ampf2 (make-env '(0 1  .3 1  .4 0 .75 0 .8 1  1 1) :duration dur :scaler 1.0)))      ; its amplitude
    (do ((i start (+ i 1)))
        ((= i stop))
      (let ((frq (env frqf)))
        (outa i (* (env ampf)
		   (+ (polywave gen1 frq)
		      (* (env ampf2)
			 (polywave gen2 (* 0.5 frq))))))))))

Now patience is the key. Use the speed control to slow playback down by an octave or two. (Perhaps the frequency envelope should end at a higher point?) Keep tweaking the envelopes and spectral amplitudes until it sounds right! Total elapsed time? Two or three hours probably.

the end

animals.scm has all the functions, key bindings, and dialog variable settings mentioned here. They can save you a ton of time.

see also:   birds
autosave
auto-save 
cancel-auto-save 

The auto-save code sets up a background process that checks periodically for unsaved edits, and if any are found it saves them in a temporary file (the name is the base file name enclosed in "#...#" and placed in the temp-dir directory). The time between checks is set by the variable auto-save-interval which defaults to 60.0 seconds. To start auto-saving, (load "autosave.scm"). Thereafter (cancel-auto-save) stops autosaving, and (auto-save) restarts it.

bess

bess.scm creates a dialog (named "FM Forever!"), opens the DAC, puts up a bunch of scale widgets, and starts two CLM oscils doing frequency modulation in semi-real-time (how "real-time" it is depends on your audio setup). Michael Scholz has contributed a Ruby translation of this with many improvements: bess.rb.

fm dialog
;; bess opens the DAC and continuously sends the following:
(* amp 
   (oscil carosc 
     (+ (hz->radians frequency)
        (* index (oscil modosc 
                   (hz->radians (* ratio frequency)))))))

bess1.scm and bess1.rb give you real-time GUI-based control over the fm-violin while it cycles around in a simple compositional algorithm. Both were written by Michael Scholz, based on CLM's bess5.cl and rt.lisp.

see also:   fm
binary-io
read|write-l|bint16|32|64
read|write-l|bfloat32|64
read|write-chars|string
read|write-au-header

This file has functions to read and write numbers and strings to and from binary files. The function names are similar to those used for sample-type names, so for example, read-bint32 reads the next 4 bytes from the current input port, interpreting them as a big-endian 32-bit integer.

bird
bird start dur frequency freqskew amplitude freq-envelope amp-envelope
bigbird start dur frequency freqskew amplitude freq-envelope amp-envelope partials
one-bird beg maxdur func birdname
make-birds (output-file "test.snd")

bird.scm is a translation of the Sambox/CLM bird songs. The two instruments set up a sine wave (bird) and waveshaping synthesis (bigbird). Use a low-pass filter for distance effects (a bird song sounds really silly reverberated). All the real information is in the amplitude and frequency envelopes. These were transcribed from sonograms found in some bird guides and articles from the Cornell Ornithology Lab. Many of these birds were used in "Colony". To hear all the birds, (make-birds). This writes the sequence out as "test.snd" using with-sound. Waveshaping is described in Le Brun, "Digital Waveshaping Synthesis", JAES 1979 April, vol 27, no 4, p250. The lines

...
(coeffs (partials->polynomial (normalize-partials partials)))
...
   (polynomial coeffs
     (oscil os (env gls-env))))))
 

setup and run the waveshaping synthesis (in this case it's just a fast additive synthesis). partials->polynomial calculates the Chebyshev polynomial coefficients given the desired spectrum; the spectrum then results from driving that polynomial with an oscillator. Besides the bird guides, there are now numerous recordings of birds that can be turned into sonograms and transcribed as envelopes. sndclm.html has the code for the bird instrument in several languages.

see also:   animals
clean

This file provides a set of noise reduction functions packaged up in:

clean-channel snd chn
clean-sound snd

clean-channel tries to fix up clicks, pops, hum, DC offset, clipped portions, and hiss using a variety of functions from dsp.scm. The final low-pass filter is relatively conservative (that is, it's not a very intense filter), so you may want to run another filter over the data after calling clean-channel.

A Noisy Story

There is no built-in noise reduction function in Snd. I believe the most common such function is some variant of Perry Cook's Scrubber program (see anoi in clm-ins.scm or fft-squelch in examp.scm). Secondary tricks involve smoothing functions similar to smooth-channel, and enveloping to silence stuff between tracks, and so on. clean-channel came about when I blithely offered to clean up some recorded telephone conversations. The first step was to find the clipped locations (where the conversation was accidentally over-recorded). I did this first because there were places in the recordings where the DC offset was huge, causing clipping in a signal that would otherwise have been safe. I hoped to reconstruct the signal at the clipped points, but these would be hard to find once the DC was removed. A quick check:

(count-matches (lambda (y) (or (> y .9999) (< y -.9999))))

returned 5437 (in 18 minutes of sound). That seemed high, and I thought "maybe those are just one sample clicks that can easily be smoothed over", so

(define* (count-clips snd chn)
  (let ((y0 0.0))
    (count-matches
     (lambda (y) (let ((val (and (or (> y0 .9999) (< y0 -.9999))
				 (or (> y .9999) (< y -.9999)))))
		   (set! y0 y)
		   val))
     0 snd chn)))

But this returned 4768! I made a list of clipped portions (this function has at least one bug, but I plowed past it — no time for perfection...):

(define* (list-clips snd chn)
  (let* ((max-clips (count-clips snd chn))
	 (clip-data (make-vector (* 2 max-clips) 0))
	 (clip-ctr 0)
	 (clip-beg 0)
	 (clip-end 0)
	 (clip-max-len 0)
	 (in-clip #f)
	 (samp 0))
    (scan-channel
     (lambda (y)
       (if (or (> y .9999) (< y -.9999))
	   (if in-clip
	       (set! clip-end samp)
	       (begin
		 (set! in-clip #t)
		 (set! clip-beg samp)
		 (set! clip-end samp)))
	   (if in-clip
	       (begin
		 (set! in-clip #f)
		 (set! (clip-data clip-ctr) clip-beg)
		 (set! (clip-data (+ 1 clip-ctr)) clip-end)
		 (set! clip-max-len (max clip-max-len (+ 1 (- clip-end clip-beg))))
		 (set! clip-ctr (+ clip-ctr 2)))))
       (set! samp (+ 1 samp))
       #f)) ; make sure scan doesn't quit prematurely
    (list clip-ctr clip-max-len clip-data)))

which returned a vector of 669 clipped portions, the worst being 42 samples long! I saved that data in a separate file, just in case of disaster:

(with-output-to-file "clips" (lambda () (display (list-clips))))

I decided to try to reconstruct the clipped portions before filtering them. This produced sample values outside -1.0 to 1.0, so I reset the graph y bounds:

(set! (y-bounds) (list -1.5 1.5))

Now to conjure up a plausible sine wave between the clip begin and end points. (This is also "just-good-enough" software).

(if (not (defined? 'pi)) (define pi 3.141592653589793))

(define (fix-clip clip-beg-1 clip-end-1)
  (if (> clip-end-1 clip-beg-1)
      (let* ((dur (+ 1 (- clip-end-1 clip-beg-1)))
	     (samps (channel->float-vector (- clip-beg-1 4) (+ dur 9)))
	     (clip-beg 3)
	     (clip-end (+ dur 4)))
	(let ((samp0 (samps clip-beg))
	      (samp1 (samps clip-end)))
	  (if (or (> samp0 .99) (< samp0 -.99))
	      (begin
	        ;; weird!  some of the clipped passages have "knees"
		;;   this looks nuts, but no time to scratch my head
		(set! clip-beg (- clip-beg 1))
		(set! samp0 (samps clip-beg))
		(if (or (> samp0 .99) (< samp0 -.99))
		    (begin
		      (set! clip-beg (- clip-beg 1))
		      (set! samp0 (samps clip-beg))))))
	  (if (or (> samp1 .99) (< samp1 -.99))
	      (begin
		(set! clip-end (+ 1 clip-end))
		(set! samp1 (samps clip-end))
		(if (or (> samp1 .99) (< samp1 -.99))
		    (begin
		      (set! clip-end (+ 1 clip-end))
		      (set! samp1 (samps clip-end))))))
          ;; now we have semi-plausible bounds
          ;; make sine dependent on rate of change of current 
	  (let* ((samp00 (samps (- clip-beg 1)))
		 (samp11 (samps (+ 1 clip-end)))
		 (dist (- clip-end clip-beg))
		 (incr (/ pi dist))
		 (amp (* .125 (+ (abs (- samp0 samp00)) (abs (- samp1 samp11))) dist)))
	    (if (> samp0 0.0)
                ;; clipped at 1.0
		(do ((i (+ 1 clip-beg) (+ i 1))
		     (angle incr (+ angle incr)))
		    ((= i clip-end))
		  (set! (samps i) (+ 1.0 (* amp (sin angle)))))
                ;; clipped at -1.0
		(do ((i (+ 1 clip-beg) (+ i 1))
		     (angle incr (+ angle incr)))
		    ((= i clip-end))
		  (set! (samps i) (- -1.0 (* amp (sin angle))))))
	    (float-vector->channel samps (- clip-beg-1 4))))
	#t) ; return values so I can tell when I hit a 1-sample section during testing
      #f))

(define (fix-it n)
  ;; turn off graphics and fix all the clipped sections
  (set! (squelch-update) #t)
  (do ((i 0 (+ i 1)))
      ((= i n))
      ;; "clips" here is a list form of the earlier vector of clip locations
    (fix-clip (clips (* i 2)) 
	      (clips (+ 1 (* i 2)))))
  (set! (squelch-update) #f))

(fix-it 669)

This produced 418 edits, with a maxamp of 2.26. So scale it back down: (scale-to .9). Next I ran some large ffts to see what sort of overall spectrum I had: (set! (transform-size) (expt 2 23)). This showed a massive DC component, and numerous harmonics of 60 Hz. I decided to get rid of the portions that were clearly noise. Since I was dealing with telephone recordings, I assumed anything under 40 Hz or above 4000 Hz was extraneous:

(define* (notch-out-rumble-and-hiss snd chn)
  (let ((cur-srate (exact->inexact (srate snd))))
    (filter-sound
     (list 0.0 0.0                    ; get rid of DC
	   (/ 80.0 cur-srate) 0.0     ; get rid of anything under 40 Hz (1.0=srate/2 here)
	   (/ 90.0 cur-srate) 1.0     ; now the passband
	   (/ 7000.0 cur-srate) 1.0 
	   (/ 8000.0 cur-srate) 0.0   ; end passband (40..4000)
	   1.0 0.0)                   ; get rid of some of the hiss
     ;; since I'm assuming the minimum band is 10 Hz here, 
     ;;   cur-srate/10 rounded up to next power of 2 seems a safe filter size
     ;;   filter-sound will actually use overlap-add convolution in this case
     (floor (expt 2 (ceiling (log (/ cur-srate 10.0) 2))))
     snd chn)))

(notch-out-rumble-and-hiss)

By now it was obvious I needed a simple way to play portions of the sound before and after an edit, sometimes with a tracking cursor. So I bound a few keys:

(define (play-from-cursor current)
  (play (cursor) #f #f #f #f (and (not current) (- (edit-position) 1))))

(define (play-from-cursor-with-tracking current)
  ;; patterned after pfc in extsnd.html
  (let ((old-tracking (with-tracking-cursor)))
    (set! (with-tracking-cursor) #t)
    (hook-push stop-playing-hook 
	       (lambda (hook)
		 (set! (with-tracking-cursor) old-tracking)))
    (play (cursor) #f #f #f #f (and (not current) (- (edit-position) 1)))))

(bind-key #\p 0 (lambda () 
                  "play from cursor" 
	  	  (play-from-cursor #t) keyboard-no-action))
(bind-key #\P 0 (lambda () 
                  "play previous from cursor" 
		  (play-from-cursor #f) keyboard-no-action))
(bind-key #\p 4 (lambda () 
                  "play from cursor with tracking" 
		  (play-from-cursor-with-tracking #t) keyboard-no-action))

In words, if the mouse is in the channel graph, 'p' plays from the cursor, 'P' plays the previous version from the cursor, and 'C-p' plays from the cursor with a "tracking cursor". In several of the sections (the overall sound consisted of a couple dozen separate conversations), there was a loud mid-range tone. To figure out what its component frequencies were, I FFT'd a portion containing only that noise and got this spectrum (plus a zillion other peaks that didn't look interesting):

((425 .05) (450 .01) (546 .02) (667 .01) (789 .034) (910 .032) (470 .01))

To hear that, I passed this list to play-sines:

(play-sines '((425 .05) (450 .01) (546 .02) (667 .01) (789 .034) (910 .032) (470 .01)))

And to my surprise, the result was close to the main portion of the hum. So now to notch out those frequencies, and see what is left: (notch-sound (list 425 450 470 546 667 789 910) #f 1 10). This erased most of the hum, but it also changed the timbre of the voices which wasn't acceptable. I goofed around with the notch-width and filter-size parameters, looking for something that would still do the trick without removing the personal side of the voices, but in only a few cases was the result usable. What was being said was not very important, but the individual characteristics of each voice were.

The next step was to take out noisy sections between snippets, mostly using (env-selection '(0 1 1 0 10 0 11 1)) and equalizing each snippet, more or less, with scale-selection-by. There were a few "you-are-being-recorded" beeps which I deleted (via the Edit menu delete selection option). In some of the conversations, between sections of speech the background hum would gradually increase, then the voice would abruptly start with a large peak amplitude. These were fixed mostly with small-section scale-by's and envelopes. In the female voice sections, it seemed to help to: (filter-selection '(0 0 .01 0 .02 1 1 1) 1024) which got rid of some of the rumble without noticeably affecting the vocal timbre.

clm-ins

These are instruments from CLM translated for use in Snd. All expect to be called within with-sound or some equivalent environment. This set of instruments is a bit of a grab-bag; some are just examples of synthesis techniques; a few others are historical, rather than useful. If I were using, for example, the fm trumpet, I'd remove all the attack and decay parameters, moving that up a level to Common Music or whoever calls the trumpet, and combine several other parameters to reflect the desired output, rather than the details of the algorithm; 30 parameters could be reduced to less than 10, and the resulting instrument would be much easier to use. But, it is an historical artifact, so I'm reluctant to change it.

To try out any of these instruments, start Snd, load ws.scm and clm-ins.scm, then paste the with-sound call into the listener. It will automatically write the new sound file and open it in Snd.

anoi file start dur (fftsize 128) (amp-scaler 1.0) (r 6.28)

anoi is a stab at noise reduction based on Perry Cook's Scrubber.m. It tracks an on-going average spectrum, then tries to squelch that, obviously aimed at reducing background noise in an intermittent signal.

(with-sound () (anoi "now.snd" 0 2))
attract beg dur amp c

attract is a translation to CLM of an instrument developed by James McCartney (CMJ vol 21 no 3 p 6), based on a "chaotic" equation. 'c' should be between 1 and 10 or thereabouts.

(with-sound () (attract 0 1 .1 1) (attract 1 1 .1 5))
bes-fm beg dur freq amp ratio index

bes-fm is J1(J1): (bes-j1 (* index (bes-j1 phase))); it uses the Bessel functions where FM uses sinusoids. J0 is also good in this context, and the few other Jn options that I've tried were ok.

Scheme:  (with-sound () (bes-fm 0 1 440 10.0 1.0 4.0))
Ruby:    with_sound() do bes_fm(0, 0.5, 440, 5, 1, 8) end

So why does this work? My "back-of-the-envelope" guess is that the Bessel functions are basically a bump at the start followed by a decaying sinusoid, so the bump gives us a percussive attack, and the damped sinusoid gives us a dynamic spectrum, mimicking FM more or less. The Bessel functions I0, Jn, and Yn are built-in; Kn and In are implemented in Scheme in snd-test.scm. See bess and friends for many more examples.

canter beg dur freq amp ...

canter is half of a bagpipe instrument developed by Peter Commons (the other portion is drone below). The (required) trailing parameters are:

deg dis pcrev ampfun ranfun skewfun skewpc ranpc ranfreq indexfun atdr dcdr
ampfun1 indfun1 fmtfun1 ampfun2 indfun2 fmtfun2 ampfun3 indfun3 fmtfun3 ampfun4 indfun4 fmtfun4

Here is a portion of a bagpipe tune:

(let ((fmt1 '(0 1200 100 1000))
      (fmt2 '(0 2250 100 1800))
      (fmt3 '(0 4500 100 4500))
      (fmt4 '(0 6750 100 8100))
      (amp1 '(0 .67 100 .7))
      (amp2 '(0 .95 100 .95))
      (amp3 '(0 .28 100 .33))
      (amp4 '(0 .14 100 .15))
      (ind1 '(0 .75 100 .65))
      (ind2 '(0 .75 100 .75))
      (ind3 '(0 1 100 1))
      (ind4 '(0 1 100 1))
      (skwf '(0 0 100 0))
      (ampf '(0 0 25 1 75 1 100 0))
      (ranf '(0 .5 100 .5))
      (index '(0 1 100 1))
      (solid '(0 0 5 1 95 1 100 0))
      (bassdr2 '(.5 .06 1 .62 1.5 .07 2.0 .6 2.5 .08 3.0 .56 4.0 .24 5 .98 6 .53 7 
                 .16 8 .33 9 .62 10 .12 12 .14 14 .86 16 .12 23 .14 24 .17))
      (tenordr '(.3 .04 1 .81 2 .27 3 .2 4 .21 5 .18 6 .35 7 .03 8 .07 9 .02 10 .025 11 .035)))
  (with-sound (:reverb nrev)
    (drone .000 4.000 115.000 (* .25 .500) solid bassdr2 .100 .500 .030 45.000 1 .010 10)
    (drone .000 4.000 229.000 (* .25 .500) solid tenordr .100 .500 .030 45.000 1 .010 11)
    (drone .000 4.000 229.500 (* .25 .500) solid tenordr .100 .500 .030 45.000 1 .010 9)
    (canter .000 2.100 918 (* .25 .700) 45.000 1 .050 ampf ranf skwf 
             .050 .010 10 index .005 .005 amp1 ind1 fmt1 amp2 ind2 fmt2 amp3 ind3 fmt3 amp4 ind4 fmt4)
    (canter  2.100  .300 688.5  (* .25 .700)  45.000 1  .050 ampf ranf skwf
	     .050  .010 10 index  .005  .005 amp1 ind1 fmt1 amp2 ind2 fmt2 amp3 ind3 fmt3 amp4 ind4 fmt4)
    (canter  2.400  .040 826.2  (* .25 .700)  45.000 1  .050 ampf ranf skwf
	     .050  .010 10 index  .005  .005 amp1 ind1 fmt1 amp2 ind2 fmt2 amp3 ind3 fmt3 amp4 ind4 fmt4)
    (canter  2.440  .560 459  (* .25 .700)  45.000 1  .050 ampf ranf skwf
	     .050  .010 10 index  .005  .005 amp1 ind1 fmt1 amp2 ind2 fmt2 amp3 ind3 fmt3 amp4 ind4 fmt4)
    (canter  3.000  .040 408  (* .25 .700)  45.000 1  .050 ampf ranf skwf
	     .050  .010 10 index  .005  .005 amp1 ind1 fmt1 amp2 ind2 fmt2 amp3 ind3 fmt3 amp4 ind4 fmt4)
    (canter  3.040  .040 619.65  (* .25 .700)  45.000 1  .050 ampf ranf skwf
	     .050  .010 10 index  .005  .005 amp1 ind1 fmt1 amp2 ind2 fmt2 amp3 ind3 fmt3 amp4 ind4 fmt4)
    (canter  3.080  .040 408  (* .25 .700)  45.000 1  .050 ampf ranf skwf
	     .050  .010 10 index  .005  .005 amp1 ind1 fmt1 amp2 ind2 fmt2 amp3 ind3 fmt3 amp4 ind4 fmt4)
    (canter  3.120  .040 688.5  (* .25 .700)  45.000 1  .050 ampf ranf skwf
	     .050  .010 10 index  .005  .005 amp1 ind1 fmt1 amp2 ind2 fmt2 amp3 ind3 fmt3 amp4 ind4 fmt4)
    (canter  3.160  .290 459  (* .25 .700)  45.000 1  .050 ampf ranf skwf
	     .050  .010 10 index  .005  .005 amp1 ind1 fmt1 amp2 ind2 fmt2 amp3 ind3 fmt3 amp4 ind4 fmt4)
    (canter  3.450  .150 516.375  (* .25 .700)  45.000 1  .050 ampf ranf skwf
	     .050  .010 10 index  .005  .005 amp1 ind1 fmt1 amp2 ind2 fmt2 amp3 ind3 fmt3 amp4 ind4 fmt4)
    (canter  3.600  .040 826.2  (* .25 .700)  45.000 1  .050 ampf ranf skwf
	     .050  .010 10 index  .005  .005 amp1 ind1 fmt1 amp2 ind2 fmt2 amp3 ind3 fmt3 amp4 ind4 fmt4)
    (canter  3.640  .040 573.75  (* .25 .700)  45.000 1  .050 ampf ranf skwf
	     .050  .010 10 index  .005  .005 amp1 ind1 fmt1 amp2 ind2 fmt2 amp3 ind3 fmt3 amp4 ind4 fmt4)
    (canter  3.680  .040 619.65  (* .25 .700)  45.000 1  .050 ampf ranf skwf
	     .050  .010 10 index  .005  .005 amp1 ind1 fmt1 amp2 ind2 fmt2 amp3 ind3 fmt3 amp4 ind4 fmt4)
    (canter  3.720  .180 573.75  (* .25 .700)  45.000 1  .050 ampf ranf skwf
	     .050  .010 10 index  .005  .005 amp1 ind1 fmt1 amp2 ind2 fmt2 amp3 ind3 fmt3 amp4 ind4 fmt4)
    (canter  3.900  .040 688.5  (* .25 .700)  45.000 1  .050 ampf ranf skwf
	     .050  .010 10 index  .005  .005 amp1 ind1 fmt1 amp2 ind2 fmt2 amp3 ind3 fmt3 amp4 ind4 fmt4)
    (canter  3.940  .260 459  (* .25 .700)  45.000 1  .050 ampf ranf skwf
	     .050  .010 10 index  .005  .005 amp1 ind1 fmt1 amp2 ind2 fmt2 amp3 ind3 fmt3 amp4 ind4 fmt4)))

It is not easy to keep track of all these arguments in a long note-list; hence the development of programs such as Score (Leland Smith), Pla (yers truly), and Common Music (Rick Taube). The full note list is bag.clm in the CLM tarball.

cellon beg dur freq amp ...

cellon, developed by Stanislaw Krupowiecz, uses feedback FM as in some old synthesizers. There's a brief discussion of it in fm.html. The trailing parameters are:

ampfun betafun beta0 beta1 betaat betadc ampat ampdc dis pcrev deg pitch1 glissfun glissat 
glissdc pvibfreq pvibpc pvibfun pvibat pvibdc rvibfreq rvibpc rvibfun

and I actually don't know what they all do. I think they're dealing with attack and decay portions of envelopes; in the old days we felt we had to store one envelope, then kludge around with attack and decay timings to bash that envelope into the correct shape; this made instruments needlessly messy. Here's a call:

(with-sound () 
  (cellon 0 2 220 .1 '(0 0 25 1 75 1 100 0) '(0 0 25 1 75 1 100 0) .75 1.0 0 0 0 0 1 0 0 220 
          '(0 0 25 1 75 1 100 0) 0 0 0 0 '(0 0 100 0) 0 0 0 0 '(0 0 100 0)))

The use of x axis values between 0 and 100, rather than 0.0 and 1.0 is a dead give-away that this is really ancient stuff.

clm-expsrc beg dur input-file exp-ratio src-ratio amp rev start-in-file

clm-expsrc can stretch or compress a sound (using granular synthesis) while optionally changing its sampling rate. 'exp-ratio' sets the expansion amount (greater than 1.0 makes the sound longer), and 'src-ratio' sets the sampling rate change (greater than 1.0 makes it higher in pitch). So to make a sound twice as long, but keep the pitch the same:

(with-sound () (clm-expsrc 0 4 "oboe.snd" 2.0 1.0 1.0))

'start-in-file' sets where we start reading the input file (in seconds); it defaults to 0.0.

drone beg dur freq amp ampfun synth ampat ampdc amtrev deg dis rvibamt rvibfreq

This is the other half of Peter Common's bagpipe — see canter above. 'synth' is a list of partials loaded into a table and read via table-lookup.

expandn time duration file amp ...

Here is the documentation from Rick Taube's granular synthesis page, edited slightly for the Scheme CLM.

The expandn instrument by Michael Klingbeil performs granular syntheisis by time-stretching (expanding/compressing) an input file. This effect is achieved by chopping up the input sound into very small segments (grains) that are then overlayed in the ouput stream. The larger the segments, the more the output sound is smeared, an effect approaching reverberation. The expandn instrument parameters are:

   time duration filename amplitude
	(expand 1.0)
	(matrix #f)
	(ramp 0.4)
	(seglen 0.15)
	(srate 1.0)
	(hop .05)
	(amp-env '(0 0 50 1 100 0))
	(input-start 0.0)
	(grain-amp 0.8)
	(reverb #f)

'time' is the start time of the sound in the output file. 'duration' is the duration of expanded sound. To expand an entire sound, set this to the expansion factor times the input sound's duration. 'filename' is the input file to expand. 'amplitude' is a scaler on the amplitude of the input file. Since the output is created by overlaying many copies of the intput this value is generally less than 1. 'hop' can be a number or an envelope. It is the average length in time between segments (grains) in the output. 'expand' can be a number or an envelope. It sets the amount of expansion to produce in the output file. 'seglen'can be a number or an envelope. It is the length in time of the sound segments (grains). 'srate' can be a number or an envelope. It sets the sampling rate change to apply to the output file. 'amp-env' is the amplitude envelope for the output sound. 'input-start' sets where to start reading in the input file. 'grain-amp' is a scaler on each grain's amplitude. 'matrix' is a list, a mixing matrix. 'reverb' is the reverb amount.

expfil start duration hopsecs rampsecs steadysecs file1 file2

expfile interleaves two granular synthesis processes (two readers pasting in tiny sections of their file, one after the other).

(with-sound () 
  (expfil 0 2 .2 .01 .1 "oboe.snd" "fyow.snd")
  (expfil 2 2 .01 .01 .02 "oboe.snd" "fyow.snd"))
exp-snd file beg dur amp (exp-amt 1.0) (ramp .4) (seglen .15) (sr 1.0) (hop .05) ampenv

exp-snd is a granular synthesis instrument with envelopes on the expansion amount ('exp-amt' as a list), segment ramp steepness ('ramp' as a list), segment length ('seglen' as a list), hop length ('hop' as a list), amplitude ('ampenv'), and resampling rate ('sr' as a list). In the next example, the expansion amount in both calls goes from 1 to 3 over the course of the note, the ramp time and segment lengths stay the same, the sampling rate changes from 2 to 0.5, and the hop stays the same (.05 in the first, and .2 in the second).

(with-sound ()
  (exp-snd "fyow.snd" 0 3 1 '(0 1 1 3) 0.4 .15 '(0 2 1 .5) 0.05)
  (exp-snd "oboe.snd" 1 3 1 '(0 1 1 3) 0.4 .15 '(0 2 1 .5) 0.2))
fm-bell beg dur frequency amplitude amp-env index-env index
fm-bell is an FM instrument developed by Michael McNabb in Mus10 in the late '70s. It is intended for low bell sounds (say middle C or so). The lines
  (mod1 (make-oscil (* frequency 2)))
  (mod2 (make-oscil (* frequency 1.41)))
  (mod3 (make-oscil (* frequency 2.82)))
  (mod4 (make-oscil (* frequency 2.4)))
  (car1 (make-oscil frequency))
  (car2 (make-oscil frequency))
  (car3 (make-oscil (* frequency 2.4)))
set up three FM pairs, car1 and mod1 handling the basic harmonic spectra, car2 and mod2 creating inharmonic spectra (using the square root of 2 more or less at random), and car3 and mod3 putting a sort of formant at the minor third (2.4 = a ratio of 12/5 = octave+6/5 = minor tenth).
(with-sound ()
  (let ((fbell '(0 1 2 1.1000 25 .7500 75 .5000 100 .5000))
        (abell '(0 0 .1000 1 10 .6000 25 .3000 50 .1500 90 .1000 100 0)))
    (fm-bell 0.0 2.0 220.0 .5 abell fbell 0.5)))
fm-drum beg dur freq amp ind (high #f) (deg 0.0) (dist 1.0) (rev-amount 0.01)

The fm-drum uses "cascade FM" (see fm.html); it was developed by Jan Mattox.

(with-sound () (fm-drum 0 1.5 55 .3 5 #f) (fm-drum 1.5 1.5 66 .3 4 #t))
fm-insect beg dur freq amp ampenv modfreq modskew modenv index indexenv fmindex ratio deg dist rev

The fm-insect started as an attempt to get cicada sounds from FM (for the 5th movement of "Colony"), but ended with:

(with-sound (:srate 22050) 
  (let ((locust '(0 0 40 1 95 1 100 .5))
	(bug_hi '(0 1 25 .7 75 .78 100 1))
	(amp    '(0 0 25 1 75 .7 100 0)))
    (fm-insect 0      1.699  4142.627  .015 amp 60 -16.707 locust 500.866 bug_hi  .346  .500)
    (fm-insect 0.195   .233  4126.284  .030 amp 60 -12.142 locust 649.490 bug_hi  .407  .500)
    (fm-insect 0.217  2.057  3930.258  .045 amp 60 -3.011  locust 562.087 bug_hi  .591  .500)
    (fm-insect 2.100  1.500   900.627  .06  amp 40 -16.707 locust 300.866 bug_hi  .346  .500)
    (fm-insect 3.000  1.500   900.627  .06  amp 40 -16.707 locust 300.866 bug_hi  .046  .500)
    (fm-insect 3.450  1.500   900.627  .09  amp 40 -16.707 locust 300.866 bug_hi  .006  .500)
    (fm-insect 3.950  1.500   900.627  .12  amp 40 -10.707 locust 300.866 bug_hi  .346  .500)
    (fm-insect 4.300  1.500   900.627  .09  amp 40 -20.707 locust 300.866 bug_hi  .246  .500)))

See animals.scm for much more convincing insect calls.

fm-trumpet beg dur ...

This is Dexter Morrill's FM-trumpet; see CMJ feb 77 p51.

(with-sound () (fm-trumpet 0 .25))

As with many instruments from that era, it has a million parameters:

    beg dur (frq1 250.0) (frq2 1500.0) (amp1 0.5) (amp2 0.1)
    (ampatt1 0.03) (ampdec1 0.35) (ampatt2 0.03) (ampdec2 0.3)
    (modfrq1 250.0) (modind11 0.0) (modind12 2.66) 
    (modfrq2 250.0) (modind21 0.0) (modind22 1.8) 
    (rvibamp 0.007) (rvibfrq 125.0) (vibamp 0.007) (vibfrq 7.0) (vibatt 0.6) (vibdec 0.2)
    (frqskw 0.03) (frqatt 0.06) 
    (ampenv1 '(0 0  25 1  75 .9  100 0)) (ampenv2 '(0 0  25 1  75 .9  100 0)) 
    (indenv1 '(0 0  25 1  75 .9  100 0)) (indenv2 '(0 0  25 1  75 .9  100 0))
    (degree 0.0) (distance 1.0) (reverb-amount 0.005)

The pitch depends on the 'modfrq1' and 'modfrq2' parameters, as well as 'frq1' and 'frq2':

(with-sound () (fm-trumpet 0 1 :frq1 400 :frq2 1600 :modfrq1 400 :modfrq2 400))
fm-voice beg dur ...

This is John Chowning's FM voice instrument, used in "Phone" I think. It is in jcvoi.scm, not clm-ins.scm. Its parameters are:

beg dur pitch amp vowel-1 sex-1 ampfun1 ampfun2 ampfun3 
indxfun skewfun vibfun ranfun
dis pcrev deg vibscl pcran skewscl ranpower glissfun glissamt

Here's an example:

(let ((ampf '(0 0 1 1 2 1 3 0))) 
  (with-sound (:play #t) 
    (fm-voice 0 1 300 .8 3 1 ampf ampf ampf ampf ampf ampf ampf 1 0 0 .25 .01 0 ampf .01)))
fofins beg dur frq amp uvib f0 a0 f1 a1 f2 a2 (amp-env '(0 0 1 1 2 1 3 0))

fofins is an implementation of FOF synthesis, taken originally from fof.c of Perry Cook and the article "Synthesis of the Singing Voice" by Bennett and Rodet in "Current Directions in Computer Music Research" (MIT Press). FOF synthesis sets up a wave with the desired spectrum (to mimic vocal formats, for example), then calls wave-train to turn that into a tone. fofins just adds an amplitude envelope and vibrato. In the Scheme version, there is also an optional trailing vibrato envelope argument (this is slightly different from the CL version):

(with-sound ()  ; slowly ramp up the vibrato
  (fofins 0 4 270 .1 0.005 730 .6 1090 .3 2440 .1 
          '(0 0 .5 1 3 .5 10 .2 20 .1 50 .1 60 .2 85 1 100 0)
	  '(0 0 40 0 75 .2 100 1) )
  (fofins 0 4 (* 6/5 540) .1 0.005 730 .6 1090 .3 2440 .1 
          '(0 0 .5 .5 3 .25 6 .1 10 .1 50 .1 60 .2 85 1 100 0)
	  '(0 0 40 0 75 .2 100 1) )
  (fofins 0 4 135 .1 0.005 730 .6 1090 .3 2440 .1 
          '(0 0 1 3 3 1 6 .2 10 .1 50 .1 60 .2 85 1 100 0)
	  '(0 0 40 0 75 .2 100 1)))
fullmix infile beg outdur inbeg matrix srate reverb-amount

fullmix is a complicated way to mix stuff. It's built into the CL version of CLM, so there was clamor for some sort of replacement in other versions of CLM. fullmix provides a sound file mixer that can handle any number of channels of data in and out with scalers and envelopes on any path, sampling rate conversion, reverb — you name it! 'infile' is the file to be mixed:

(with-sound () (fullmix "pistol.snd")) ; this places pistol.snd at time 0

'beg' is the start time of the mix in the output sound; 'outdur' is the duration of the mixed-in portion in the output; 'inbeg' is where to start the mix in the input file:

(with-sound () (fullmix "pistol.snd" 1.0 2.0 0.25)) 
;; start at 0.25 in pistol.snd, include next 2 secs, put at time 1.0 in output

'srate' is the amount of sampling rate conversion to apply, and 'reverb' is the amount of the signal to send to the reverberator:

(with-sound (:reverb nrev) (fullmix "pistol.snd" 1.0 2.0 0.25 #f 2.0 0.1)) ; up an octave, lots of reverb!

The 'matrix' parameter is much harder to describe. It is either a number or a list of lists. In the first case, that number is the amplitude scaler on the output:

(with-sound (:reverb nrev) (fullmix "pistol.snd" 1.0 2.0 0.25 0.2 2.0 0.1)) ; same but much softer (0.2 amp)

If 'matrix' is a list of lists, each element of the inner lists can be either a number or list a breakpoints (an envelope). If a number, it is treated as an amplitude scaler for that input and output channel combination. Each inner list represents an input channel, so if we have a stereo input file going to a stereo output file and we want the channels to be mixed straight, but channel 0 at .5 amp and channel 1 at .75:

(with-sound (:channels 2) (fullmix "2a.snd" #f #f #f '((0.5 0.0) (0.0 0.75))))
;;                                                       ^   ^     ^   ^
;;                                                       |   |     |   |
;;                                                    0->0   |  1->0   |
;;                                                        0->1      1->1

So, 2a.snd's first channel gets mixed into the output's first channel, scaled by 0.5, and its second channel goes to the output second channel scaled by 0.75. If we have four channels in and are writing a mono file, and want to mix in only the second channel of the input:

(with-sound (:channels 1) (fullmix "4.aiff" #f #f #f '((0.0) (1.0) (0.0) (0.0))))

The next complication is that each entry in the inner lists can also be a list of envelope breakpoints. In that case, an envelope is applied to that portion of the mix, rather than just a scaler:

(with-sound (:channels 2) (fullmix "oboe.snd" #f #f #f (list (list (list 0 0 1 1 2 0) 0.5))))
;; mono input so one list, envelope output chan 0, scale output chan 1 (two copies of input) 

And finally(!) each inner list element can also be a CLM env generator:

(with-sound (:channels 2)
  (fullmix "oboe.snd" 1 2 0 (list (list .1 (make-env '(0 0 1 1) :duration 2 :scaler .5)))))

Here's a Ruby example:

with_sound(:channels, 2, :statistics, true) do
  fullmix("pistol.snd")
  fullmix("oboe.snd", 1, 2, 0, [[0.1, make_env([0, 0, 1, 1], :duration, 2, :scaler, 0.5)]])
end

"srate" can be negative (meaning read in reverse) or a list or breakpoints (an src envelope). Now we need filters!

gong beg dur freq amp (degree 0.0) (distance 1.0) (reverb-amount 0.005)

gong is an FM instrument developed by Paul Weineke.

Scheme:  (with-sound () (gong 0 3 261.61 .3))
Ruby:    with_sound() do gong(0, 3, 261.61, 0.6) end
gran-synth beg dur freq grain-dur grain-hop amp

gran-synth sets up a wave-train playing an enveloped sinusoid (the "grain" in this case). 'grain-dur' sets the grain's length (in seconds), 'grain-hop' sets the frequency of the wave-train generator (how quickly the grain is repeated), and 'freq' sets the grain sinusoid's frequency.

(with-sound () (gran-synth 0 1 300 .0189 .03 .4)) ; grain freq 300Hz, repetition rate 33Hz
graphEq file beg dur or-beg amp (amp-env '(0 1.0 0.8 1.0 1.0 0.0)) (amp-base 1.0) ...

graphEq is a sort of non-graphical graphical equalizer, developed by Marco Trevisani. It sets up a bank of formant generators with an optional envelope on each formant, then filters and envelopes the input file. Its trailing parameters are:

(offset-gain 0)  
(gain-freq-list '((0 1 1 0) 440 (0 0 1 1) 660))      
(filt-gain-scale 1)                   
(filt-gain-base 1)                    
(a1 .99)
(stats #t)

'a1' is the formant radius. 'gain-freq-list' is a list of gains and frequencies to filter The gains can be either numbers or envelopes (one or the other, not a mixture). 'offset-gain' is an offset (addition) to all the gains. 'filt-gain-scale' and 'filt-gain-base' are similar, but apply to the envelopes, if any. 'stats' prints encouraging numbers if #t.

(with-sound () (graphEq "oboe.snd")) ; accept all the defaults (Scheme is case sensitive)

If we want just steady bands:

(with-sound () (graphEq "oboe.snd" 0 0 0 1.0 '(0 1 1 0) 1.0 0 '(.1 440 .3 1500 .2 330)))
hammondoid beg dur freq amp

hammondoid is Perry Cook's additive-synthesis Hammond organ.

(with-sound () (hammondoid 0 1 440 .1))
jl-reverb (decay 3.0)

jl-reverb is a cavernous version of John Chowning's ancient reverberator. You can never get enough reverb!

(with-sound (:reverb jl-reverb) (fm-violin 0 .1 440 .1 :reverb-amount .1))

'decay' is the reverb decay time tacked onto the end of the output sound. To pass parameters to a reverberator, use the with-sound parameter :reverb-data. So, if we want 5 seconds of decay:

(with-sound (:reverb jl-reverb :reverb-data '(5.0)) (fm-violin 0 .1 440 .1 :reverb-amount .1))
;;                                            ^ this is passed as (jl-reverb 5.0)
lbj-piano beg dur freq amp (pfreq frequency) (degree 45) (reverb-amount 0) (distance 1)

lbj-piano, developed by Doug Fulton, uses James A Moorer's piano spectra and additive synthesis to mimic a piano.

(with-sound () (lbj-piano 0 2 110.0 .2))

Doug says, "The high notes sound pretty rotten" and thinks perhaps one major problem is the lack of mechanical noise. 'pfreq' sets which spectrum to use; it defaults to whatever matches 'freq'.

(with-sound () (lbj-piano 0 2 110.0 .2 :pfreq 550))
metal beg dur freq amp

metal is another Perry Cook creation (HeavyMtl); it's an FM instrument:

(with-sound () (metal 0 1 440 .2))
nrev (reverb-factor 1.09) (lp-coeff 0.7) (volume-1 1.0)

nrev, developed by Michael McNabb, is one of the more popular old-style reverbs. It is much cleaner than jc-reverb.

(with-sound (:reverb nrev) (fm-violin 0 .1 440 .1 :reverb-amount .1))

'reverb-factor' controls the length of the decay — it should not exceed 1.21 or so. 'lp-coeff' controls the strength of the low pass filter inserted in the feedback loop. 'volume-1' can be used to boost the reverb output.

(with-sound (:reverb nrev :reverb-data '(:lp-coeff 0.9 :volume-1 2.0)) 
  (fm-violin 0 .1 440 .1 :reverb-amount .1))
pins beg dur file amp ...

pins is a simple implementation of the spectral modeling synthesis of Xavier Serra and Julius Smith (sometimes known as "Sansy" or "SMS"). See Serra, X., J. O. Smith. 1990. "Spectral Modeling Synthesis:A Sound Analysis/Synthesis Based on a Deterministic plus Stochastic Decomposition". Computer Music Journal, vol. 14(4), 1990. The idea behind SMS is similar to the phase vocoder, but tracks spectral peaks so that its resynthesis options are much more sophisticated. The trailing parameters are:

(transposition 1.0) (time-scaler 1.0) (fft-size 256) 
     (highest-bin 128) (max-peaks 16) printit attack

'transposition' can be used to transpose a sound; 'time-scaler' changes the sound's duration; 'fft-size' may need to be larger if your sampling rate is 44100, or the input sound's fundamental is below 300 Hz; 'highest-bin' sets how many fft bins we search for spectral peaks; 'max-peaks' sets how many peaks we track (at a maximum) through the sound; 'printit', if set to #t, causes the peak envelopes to be printied; 'attack' is an optional float-vector containing the attack portion of the new sound.

Scheme:  (with-sound () (pins 0.0 1.0 "now.snd" 1.0 :time-scaler 2.0))
Ruby:    with_sound() do pins(0, 1, "now.snd", 1, :time_scaler, 2) end

Xavier has a website devoted to this system, but it seems to move; search for CLAM or SMS.

pluck beg dur freq amp (weighting .5) (lossfact .9)

pluck is based on the Karplus-Strong algorithm as extended by David Jaffe and Julius Smith — see Jaffe and Smith, "Extensions of the Karplus-Strong Plucked-String Algorithm" CMJ vol 7 no 2 Summer 1983, reprinted in "The Music Machine". The basic idea is to fill an array with noise, then filter the array values as it is played repeatedly, giving a sharp attack and a ringing decay, much like plucking a guitar. The CMJ article gives many variations, changing pick position and so on. Jaffe's "Silicon Valley Breakdown" makes great use of this instrument. 'weighting' is the ratio of the once-delayed to the twice-delayed samples. It defaults to .5 which gives a short decay; anything other than .5 produces a longer decay. It should be between 0.0 and 1.0. 'lossfact' can be used to shorten decays. The most useful values are between .8 and 1.0.

(with-sound () 
  (pluck 0 1 330 .3 .95 .95) 
  (pluck .3 2 330 .3 .9 .9999) 
  (pluck .7 2 330 .3 .8 .99))

In Ruby:

with_sound() do pluck(0.05, 0.1, 330, 0.1, 0.95, 0.95) end
pqw-vox beg dur freq spacing-freq amp ampfun freqfun freqscl phonemes formant-amps formant-shapes

pqw-vox is an extension of Marc LeBrun's instrument vox (described below) to use phase-quadrature (single-sideband) waveshaping. It uses both Chebyshev polynomial kinds to set up spectra-producing pairs of waveshapers that will add in such a way as to cancel either the upper or lower set of sidebands. These are then ganged together as in the vox instrument to mimic moving formants.

(with-sound () 
  (pqw-vox 0 1 300 300 .1 '(0 0 50 1 100 0) '(0 0 100 1) .3 '(0 L 100 L) '(.5 .25 .1) 
          '((1 1 2 .5) (1 .5 2 .5 3 1) (1 1 4 .5))))

(with-sound ()
  (pqw-vox 0 2 200 200 .1 '(0 0 50 1 100 0) '(0 0 100 1) .1 '(0 UH 100 ER) '(.8 .15 .05) 
           '((1 1 2 .5) (1 1 2 .5 3 .2 4 .1) (1 1 3 .1 4 .5)))
  (pqw-vox 2 2 200 314 .1 '(0 0 50 1 100 0) '(0 0 100 1) .01 '(0 UH 100 ER) '(.8 .15 .05) 
           '((1 1 2 .5) (1 1 4 .1) (1 1 2 .1 4 .05)))
  (pqw-vox 4 2 100 414 .2 '(0 0 50 1 100 0) '(0 0 100 1) .01 '(0 OW 50 E 100 ER) '(.8 .15 .05) 
           '((1 1 2 .5 3 .1 4 .01) (1 1 4 .1) (1 1 2 .1 4 .05))))
pqw beg dur freq spacing-freq carrier-freq amplitude ampfun indexfun partials ...

pqw is a phase-quadrature waveshaping instrument which produces asymmetric spectra. The trailing parameters just set the usual degree, distance, and reverb values.

(with-sound () (pqw 0 .5 200 1000 .2 '(0 0 25 1 100 0) '(0 1 100 0) '(2 .1 3 .3 6 .5)))

To see the asymmetric spectrum most clearly, set the index function above to '(0 1 100 1).

resflt beg dur driver ...

resflt, developed by Richard Karpen and Xavier Serra, sets up three resonators (two-pole filters), then drives them with either white noise or an ncos pulse train. Both can be used for vocal effects:

(with-sound () 
  (resflt 0 1.0 0 0 0 #f .1 200 230 10 '(0 0 50 1 100 0) '(0 0 100 1) 
          500 .995 .1 1000 .995 .1 2000 .995 .1)
  (resflt 1 1.0 1 10000 .01 '(0 0 50 1 100 0) 0 0 0 0 #f #f 
          500 .995 .1 1000 .995 .1 2000 .995 .1))

The trailing parameters are:

ranfreq noiamp noifun cosamp cosfreq1 cosfreq0 cosnum ampcosfun freqcosfun 
frq1 r1 g1 frq2 r2 g2 frq3 r3 g3
(degree 0.0) (distance 1.0)(reverb-amount 0.005)

Set 'driver' to 0 to get the pulse train, or to 1 to get white noise. In the latter case, 'ranfreq' is the random number generator frequency, 'noiamp' is its amplitude, and 'noifun' is an amplitude envelope on its output (filter input) In the pulse case, 'cosamp' is the pulse train amplitude, 'ampcosfun' the amplitude envelope, 'cosfreq0' and 'cosfreq1' set the frequency limits of 'freqcosfun', and 'cosnum' sets the number of cosines in the pulse. The three resonators are centered at 'frq1', 'frq2', 'frq3', with pole-radius 'r1', 'r2', and 'r3' respectively, and with gains of 'g1', 'g2', and 'g3'.

reson beg dur freq amp ...

reson is a vocal simulator developed by John Chowning. Its trailing parameters are:

numformants indxfun skewfun pcskew skewat skewdc vibfreq vibpc ranvibfreq ranvibpc 
degree distance reverb-amount data

'data' is a list of lists of form 
  '(ampf resonfrq resonamp ampat ampdc dev0 dev1 indxat indxdc)

Needless to say, no one has ever written out these parameters by hand, so here's an all-time first:

(with-sound ()
  (reson 0.0 1.0 440 .1 2 '(0 0 100 1) '(0 0 100 1) .1 .1 .1 5 .01 5 .01 0 1.0 0.01
     '(((0 0 100 1) 1200 .5 .1 .1 0 1.0 .1 .1) ((0 1 100 0) 2400 .5 .1 .1 0 1.0 .1 .1))))

But JC got very nice vocal sounds from this — I must have mistyped somewhere... Here's another stab at it:

(with-sound ()
      (reson 0.0 1.0 440 .1 2 '(0 1 100 0) '(0 0 100 1) .01 .1 .1 5 .01 5 .01 0 1.0 0.01
   	     '(((0 1 100 1) 1000 .65 .1 .1 0 1.0 .1 .1) ((0 0 100 1) 2400 .15 .1 .1 0 1.0 .1 .1))))

If you find a good example, please send me it!

rhodey beg dur freq amp (base .5)

rhodey is another of Perry Cook's instruments (an electric piano), based on a pair of FM generators.

(with-sound () (rhodey 0 1 440 .2))

One of the oscillators is set to a frequency 15 times the requested 'freq', so for higher notes, you'll need to set the srate higher:

(with-sound (:srate 44100) (rhodey 0 1 880 .2))
rms gen sig
balance gen sig comparison
gain gen sig rsmval
make-rmsgain (hp 10.0)

rms, balance, and gain are an implementation of the balance generators of CLM (based on CSound originals, Scheme versions originally provided by Fabio Furlanete). This section is a paraphrase of balance.html in the CLM tarball which was written by Sam Hiesz. balance, rms, and gain are used to track the RMS value of a signal and use that information to scale some other signal. rms returns the RMS value; gain takes a signal and an RMS value and modifies the signal to track the RMS value; balance packages gain and rms into one function call. make-rmsgain returns the generator used by rms, gain, and balance. The 'hp' parameter sets the speed with which the balance process tracks the RMS signal. An example is worth a zillion words:

  (with-sound (:channels 3)
    (let ((rg (make-rmsgain))
          (rg1 (make-rmsgain 40))
          (rg2 (make-rmsgain 2))
          (e (make-env '(0 0 1 1 2 0) :length 10000))
          (e1 (make-env '(0 0 1 1) :length 10000))
          (e2 (make-env '(0 0 1 1 2 0 10 0) :length 10000))
          (o (make-oscil 440.0)))
      (do ((i 0 (+ i 1)))
          ((= i 10000))
        (let ((sig (env e)))
          (outa i (balance rg sig (env e2)))
          (outb i (balance rg1 sig (env e1)))
          (outc i (balance rg2 (* .1 (oscil o)) (env e2)))))))
scratch beg file src-ratio turnlist

scratch moves back and forth in a sound file according to a list of turn times much like env-sound-interp. With voice input, we can create a "Remembrance of Bugs Bunny":

Scheme: (with-sound () (scratch 0.0 "now.snd" 1.5 '(0.0 .5 .25 1.0)))
Ruby:   with_sound() do scratch(0, "now.snd", 1.5, [0.0, 0.5, 0.25, 1.0]) end

I translate this as: "go forward from 0.0 to 0.5 secs, backwards to 0.25 secs, then forward to 1.0 secs".

spectra beg dur freq amp ...

spectra is an additive-synthesis instrument with vibrato and an amplitude envelope. It was intended originally to be used with the spectra in spectra.scm (information laboriously gathered at the dawn of the computer era by James A Moorer). One such spectrum is labelled "p-a4", so we can hear it via:

(load "spectr.scm")
(with-sound () 
  (spectra 0 1 440.0 .1 p-a4 '(0.0 0.0 1.0 1.0 5.0 0.9 12.0 0.5 25.0 0.25 100.0 0.0)))

The trailing parameters are:

 (partials '(1 1 2 0.5))
           (amp-envelope '(0 0 50 1 100 0))
           (vibrato-amplitude 0.005)
           (vibrato-speed 5.0)
           (degree 0.0)
           (distance 1.0)
           (reverb-amount 0.005)

We can pass our own partials:

(with-sound ()
  (spectra 0 1 440.0 .1 '(1.0 .4 2.0 .2 3.0 .2 4.0 .1 6.0 .1) 
           '(0.0 0.0 1.0 1.0 5.0 0.9 12.0 0.5 25.0 0.25 100.0 0.0)))
ssb-fm gen modsig
make-ssb-fm freq

These two functions implement a sort of asymmetric FM using ideas similar to those used in ssb-am.

stereo-flute beg dur freq flow ...

This is a physical model of a flute developed by Nicky Hind.

Scheme:
(with-sound (:channels 2) 
   (stereo-flute 0 1 440 0.55 :flow-envelope '(0 0 1 1 2 1 3 0))
   (stereo-flute 1 3 220 0.55 :flow-envelope '(0 0 1 1 2 1 3 0)))

Ruby:
with_sound() do stereo_flute(0, 2, 440, 0.55, :flow_envelope, [0, 0, 1, 1, 2, 1, 3, 0]) end

The trailing parameters are:

(flow-envelope '(0 1 100 1))
     (decay 0.01) 		; additional time for instrument to decay
     (noise 0.0356) 
     (embouchure-size 0.5)
     (fbk-scl1 0.5)		; these two are crucial for good results
     (fbk-scl2 0.55)
     (offset-pos 0.764264)      ; from 0.0 to 1.0 along the bore
     (out-scl 1.0)
     (a0 0.7) (b1 -0.3)	        ; filter coefficients
     (vib-rate 5) 
     (vib-amount 0.03)
     (ran-rate 5) 
     (ran-amount 0.03)

As with physical models in general, you may need to experiment a bit to find parameters that work.

touch-tone beg number

This instrument produces telephone tones:

Scheme:  (with-sound () (touch-tone 0.0 '(7 2 3 4 9 7 1)))
Ruby:    with_sound() do touch_tone(0, [7, 2, 3, 4, 9, 7, 1]) end

It is just two sine waves whose frequencies are chosen based on the number pressed.

  1     2     3   697 Hz
  4     5     6   770 Hz
  7     8     9   852 Hz
        0         941 Hz
 1209  1336  1477 Hz

For more than you really want to know about other such sounds, see Telephone Tone Frequencies.

tubebell beg dur freq amp (base 32.0)

Perry Cook's tubular bell:

(with-sound () 
  (tubebell 0 2 440 .1 32.0) 
  (tubebell 2 2 220 .1 64.0) 
  (tubebell 4 2 660 .1 .032))

'base' is the envelope base:

(with-sound () 
  (tubebell 0 2 440 .1 32.0) 
  (tubebell 2 2 220 .1 2048.0) 
  (tubebell 4 3 660 .1 .032))
two-tab beg dur freq amp ...

two-tab interpolates between two spectra.

(with-sound () (two-tab 0 2 440 .1 '(1.0 1.0) '(3.0 1.0)))
;; go from harmonic 1 to harmonic 3

The trailing parameters are:

(partial-1 '(1.0 1.0 2.0 0.5))
          (partial-2 '(1.0 0.0 3.0 1.0))
          (amp-envelope '(0 0 50 1 100 0))
          (interp-func '(0 1 100 0))
          (vibrato-amplitude 0.005)
          (vibrato-speed 5.0)
          (degree 0.0)
          (distance 1.0)
          (reverb-amount 0.005)

'interp-func' determines how we interpolate between the two spectra. When it is at 1.0, we get only the first, at 0.0 only the second.

(with-sound () (two-tab 0 2 440 .1 '(1.0 1.0) '(3.0 1.0) '(0 0 1 1 2 0) '(0 0 1 1)))

is the reverse of the earlier sound. To go out and back:

(with-sound () (two-tab 0 2 440 .1 '(1.0 1.0) '(3.0 1.0) '(0 0 1 1 2 0) '(0 0 1 1 2 0)))
vox beg dur freq amp ampfun freqfun freqscl voxfun index vibscl

vox is a translation of Marc LeBrun's MUS10 waveshaping voice instrument using FM in this case. The basic idea is that each of the three vocal formants is created by two sets of waveshapers (or oscils producing FM), one centered on the even multiple of the base frequency closest to the desired formant frequency, and the other on the nearest odd multiple. As the base frequency moves (due to vibrato or glissando), these center frequencies are recalculated on each sample, and the respective amplitudes set to reflect the distance of the current center frequency from the desired formant frequency. If a center frequency moves enough that the previous upper member of the pair has to become the lower member, the upper waveshaper (which has meanwhile ramped to zero amplitude), jumps down to its new center. The male-speaker formant table was provided by Robert Poor (see the code for the complete table of formants). For details on waveshaping, see Le Brun, "Digital Waveshaping Synthesis", JAES 1979 April, vol 27, no 4, p250. I used vox in the 5th movement of "Colony" and in "The New Music Liberation Army".

(with-sound ()
  (let ((amp-env '(0 0 25 1 75 1 100 0))
        (frq-env '(0 0 5 .5 10 0 100 1)))
  (vox 0 2 170 .4 amp-env frq-env .1 
    '(0 E 25 AE 35 ER 65 ER 75 I 100 UH) '(.8 .15 .05) '(.005 .0125 .025) .05 .1)
  (vox 2 2 110 .4 amp-env frq-env .5 
    '(0 UH 25 UH 35 ER 65 ER 75 UH 100 UH) '(.8 .15 .05) '(.005 .0125 .025))
  (vox 4 2 300 .4 amp-env frq-env .1 
    '(0 I 5 OW 10 I 50 AE 100 OO) '(.8 .15 .05) '(.05 .0125 .025) .02 .1)))

Or in Ruby:

with_sound() do
  amp_env = [0, 0, 25, 1, 75, 1, 100, 0]
  frq_env = [0, 0, 5, 0.5, 10, 0, 100, 1]
  vox(0, 2, 170, 0.4, amp_env, frq_env, 0.1, 
       [0, :E, 25, :AE, 35, :ER, 65, :ER, 75, :I, 100, :UH], 0.05, 0.1)
  vox(2, 2, 300, 0.4, amp_env, frq_env, 0.1, 
       [0, :I, 5, :OW, 10, :I, 50, :AE, 100, :OO], 0.02, 0.1)
  vox(4, 5, 600, 0.4, amp_env, frq_env, 0.1, 
       [0, :I, 5, :OW, 10, :I, 50, :AE, 100, :OO], 0.01, 0.1)
end

vox can also be use for less vocal effects:

(with-sound (:play #t :scaled-to .5)
  (vox 0 .25 500 .4 '(0 0 .1 1 1 1 2 .5 3 .25 10 0) '(0 0 5 .5 10 0 100 1) .1 
       '(0 E 25 OW 35 ER 105 ER) '(.13 .15 .15) '(.005 .005 .015) .05 .1))
wurley beg dur freq amp

Perry Cook's Wurlitzer (I assume).

(with-sound () (wurley 0 1 440 .1))
za time dur freq amp length1 length2 feedback feedforward
zc time dur freq amp length1 length2 feedback
zn time dur freq amp length1 length2 feedforward

The "z" instruments demonstrate "zdelay" effects — interpolating comb, notch, and all-pass filters.

(with-sound () (zn 0 1   100 .1 20 100 .995) 
  (zn 1.5 1 100 .1 100 20 .995)
  (zc 3 1   100 .1 20 100 .95) 
  (zc 4.5 1 100 .1 100 20 .95)
  (za 6 1   100 .1 20 100 .95 .95) 
  (za 7.5 1 100 .1 100 20 .95 .95))

snd-test.scm has examples of calling all these instruments. For more examples of instruments, there are a variety of separate files such as v.scm, and clm23.scm has a translation of the CLM test instruments. It also has some comments about the differences between the CL and Scheme instruments.

see also:   bird   clm   dlocsig   examp   fade   fm   fmv   freeverb   graphEq   grani   jcrev   maraca   maxf   noise   piano   prc95   pvoc   singer   sndwarp   stochastic   strad   ws
dlocsig

dlocsig is a CLM generator developed by Fernando Lopez-Lezcano that can move sounds in two or three dimensions. Fernando's CLM/lisp-oriented documentation can be found in dlocsig.html. dlocsig.rb is Michael Scholz's translation of dlocsig to Ruby. It has lots of documentation and examples. If you load dlocsig.rb, a new menu is added named "Dlocsig". If you choose a path from this menu, you get a graphical user-interface to play with the various envelopes that drive dlocsig. Click the "With_Snd" button to apply the current path choices to the currently selected sound. Click "Gnuplot" to get a pretty picture of the path (in 3D!). An instrument that uses dlocsig is:

(define* (sinewave start-time duration freq amp (amp-env '(0 1 1 1))
		   (path (make-path :path '(-10 10 0 5 10 10))))
  (let* ((vals (make-dlocsig :start-time start-time :duration duration :path path))
	 (dloc (car vals))
	 (beg (cadr vals))
	 (end (caddr vals)))
    (let ((osc (make-oscil freq))
	  (aenv (make-env amp-env :scaler amp :duration duration)))
      (do ((i beg (+ i 1)))
          ((= i end))
	(dlocsig dloc i (* (env aenv) (oscil osc)))))))

(with-sound (:channels 2) (sinewave 0 1.0 440 .5 :path (make-path '((-10 10) (0.5 0.5) (10 10)) :3d #f)))
draw

draw.scm has examples of graphics-oriented extensions.

color-samples color beg dur snd chn
uncolor-samples snd chn

color-samples displays the samples from sample 'beg' for 'dur' samples in 'color' whenever they're in the current time domain view. uncolor-samples cancels this action. To activate this, add it to after-graph-hook.

display-previous-edits snd chn

display-previous-edits displays all the edits of the current sound, with older edits gradually fading away. To activate this, add it to after-graph-hook:

(hook-push after-graph-hook display-previous-edits)
overlay-rms-env snd chn

overlay-rms-env displays the running rms value of the currently displayed data in red, overlayed upon the normal graph. To activate it, add it to the after-graph-hook:

(hook-push after-graph-hook overlay-rms-env)
overlay-sounds :rest sounds

overlay-sounds overlays onto its first argument (a sound) all subsequent arguments: (overlay-sounds 1 0 3).

samples-via-colormap snd chn

samples-via-colormap displays the time domain graph using the current colormap (it is really just an example of colormap-ref). To activate this, add it to after-graph-hook:

(hook-push after-graph-hook samples-via-colormap)
samples-via-colormap
dsp

dsp.scm is a DSP grabbag, mostly filters. There are more than 100 functions to describe here, so an alphabetical list is just a jumble of names. Instead, I've tried to divide them into several vague categories: FFTs, FIR filters, IIR filters, synthesis, sound effects, sampling rate conversion, linear algebra and stats, and scanned synthesis.

If you're new to DSP, I recommend Lyons' "Understanding Digital Signal Processing" and Steiglitz, "A Digital Signal Processing Primer"; there are many good books on advanced calculus — I especially liked Hildebrand, "Advanced Calculus for Applications", but it may be out of print (this was about 25 years ago, I think); a great book on complex analysis is Needham, "Visual Complex Analysis"; Poole's "Linear Algebra" is a very straightforward introduction; also Halmos, "Linear Algebra Problem Book"; the most enjoyable Fourier Analysis book is by Körner, but you don't want to start with it. For the ambitious, there is the encyclopedic set of books by Julius Smith. His "Mathematics of the DFT" and "Introduction to Digital Filters" are very clear.

FFTs
dht data

dht is the slow form of the Hartley transform, taken from Perry Cook's SignalProcessor.m. The Hartley transform is a kind of Fourier transform.

display-bark-fft off color1 color2 color3
undisplay-bark-fft 

display-bark-fft shows the current spectrum in the "lisp" graph in three different frequency scales: bark, mel, and erb, each in a different color. The default ticks follow the bark scale; click anywhere in the lisp graph to switch to a different tick scale choice. undisplay-bark-fft turns this graph off. Here we've used rgb.scm for some color names:

(display-bark-fft #f sea-green orange alice-blue)
(set! (selected-graph-color) gray30)
(set! (selected-data-color) light-green)
bark display
dolph n gamma

dolph is the Dolph-Chebyshev fft data window, taken from Richard Lyons, "Understanding DSP". The C version used by Snd/CLM is in clm.c. Another version of the same function, taken (with a few minor changes) from Julius Smith's "Spectral Audio", is named dolph-1.

down-oct n snd chn
stretch-sound-via-dft factor snd chn

down-oct tries to move a sound down by a factor of n (assumed to be a power of 2, 1 = no change) by goofing with the fft data, then inverse ffting. I think this is "stretch" in DSP jargon; to interpolate in the time domain we're squeezing the frequency domain. The power-of-2 limitation is based on the underlying fft function's insistence on power-of-2 data sizes. A more general version of this is stretch-sound-via-dft, but it's extremely slow.

goertzel freq beg dur snd
find-sine freq beg dur snd

goertzel and find-sine find the amplitude of a single component of a spectrum ('freq').

> (find-sine 550.0 0.0 (framples))
(0.00116420908413177 0.834196665512423)   ; car is amplitude, cadr is phase in radians
> (* (goertzel 550.0 0.0 (framples)) (/ 2.0 (framples)))
0.00116630805062827
periodogram N

periodogram (the "Bartlett" version, I think) runs over an entire file, piling up 'N' sized chunks of data, then displays the results in the "lisp graph" area; this needs a lot of work to be useful!

scentroid file (beg 0.0) dur (db-floor -40.0) (rfreq 100.0) (fftsize 4096)

scentroid is Brett Battey's CLM scentroid instrument, translated to Snd/Scheme. To paraphrase Brett: scentroid returns (in a float-vector) the continuous spectral centroid envelope of a sound. The spectral centroid is the "center of gravity" of the spectrum, and it has a rough correlation to our sense of "brightness" of a sound. 'db-floor' sets a lower limit on which framples are included in the analysis. 'rfreq' sets the number of measurements per second. 'fftsize' sets the fft window size (a power of 2). See also the moving-scentroid generator in generators.scm.

spot-freq samp snd chn

spot-freq is a first-pass at using autocorrelation for pitch tracking; it's easily fooled, but could probably be made relatively robust.

> (spot-freq 10000)  ; this is oboe.snd, in about .5 secs
555.262096862931    ; 555Hz is correct(!)

In the next example, we add spot-freq to the mouse-click-hook (in Ruby), so that each time we click somewhere in the graph, the pitch at that point is reported:

$mouse_click_hook.add_hook!("examp-cursor-hook") do |snd, chn, button, state, x, y, axis|
  if axis == Time_graph
    status_report(format("(freq: %.3f)", spot_freq(cursor(snd, chn))))
  end
end
rotate-phase func snd chn
zero-phase snd chn

These are fft phase manipulators taken from the phazor package of Scott McNab. zero-phase takes ffts, sets all phases to 0.0, then unffts. rotate-phase is similar, but applies 'func' to the phases.

(rotate-phase (lambda (x) 0.0))             ; same as (zero-phase)
(rotate-phase (lambda (x) (random 3.1415))) ; randomizes phases
(rotate-phase (lambda (x) x))               ; returns original
(rotate-phase (lambda (x) (- x)))           ; reverses original

or in Ruby:

rotate_phase(lambda {|x| random(PI) })      # randomizes phases

and Forth:

lambda: <{ x }> pi random ; #f #f rotate-phase \ randomizes phases
z-transform rl size z
fractional-fourier-transform rl im size angle

z-transform performs a z-transform returning a vector (to accommodate complex results):

> (define d0 (make-float-vector 8 0.0))
d0
;; and similarly for d1 and d2 ...
> (set! (d0 2) 1.0)
1.0
> (set! (d1 2) 1.0)
1.0
> (z-transform d0 8 (exp (make-rectangular 0.0 (* .25 pi))))
;; Ruby: z_transform(d0, 8, exp(Complex(0.0, (2.0 / 8) * PI)))
#(1.0  0.0+1.0i  -1.0  0.0-1.0i  1.0  0.0+1.0i  -1.0  0.0-1.0i)
> (mus-fft d1 d2 8)
#(1.0 0.0 -1.0 -0.0 1.0 0.0 -1.0 -0.0)
> d2
#(0.0 1.0 0.0 -1.0 0.0 1.0 0.0 -1.0)

which is a complicated way of showing that if 'z' is e^2*pi*i/n, you get a fourier transform. fractional-fourier-transform is the slow (DFT) version of the fractional Fourier Transform. If 'angle' is 1.0, you get a fourier transform.

FIR filters
make-highpass fc length, highpass f in
make-lowpass fc length, lowpass f in
make-bandpass flo fhi length, bandpass f in
make-bandstop flo fhi length, bandstop f in
make-differentiator length, differentiator f in

make-lowpass and lowpass provide FIR low pass filtering, and similarly for the other four choices. The order chosen is twice the 'length'; 'fc', 'flo', and 'fhi' are the edge frequencies in terms of srate = 2 * pi.

(let ((hp (make-bandpass (* .1 pi) (* .2 pi))))
  (map-channel (lambda (y)
    (bandpass hp y))))
make-hilbert-transform length
hilbert-transform f in
hilbert-transform-via-fft snd chn
sound->amp-env snd chn

These functions perform the hilbert transform using either an FIR filter (the first two) or an FFT. One example of its use is sound->amp-env (from R Lyons). Another is the ssb-am generator in CLM.

invert-filter coeffs

invert-filter inverts an FIR filter. Say we previously filtered a sound via

(filter-channel (float-vector .5 .25 .125))

and our mouse is broken so we can't use the Undo menu, and we've forgotten that we could type (undo). Nothing daunted, we use:

(filter-channel (invert-filter (float-vector .5 .25 .125)))

There are a million gotchas here. The primary one is that the inverse filter can "explode" — the coefficients can grow without bound. For example, any filter returned by spectrum->coeffs will be problematic.

make-spencer-filter

This returns a CLM fir-filter generator with the standard "Spencer Filter" coefficients.

notch-sound freqs order s c width
notch-channel freqs order beg dur s c e trunc width
notch-selection freqs order width

notch-channel, notch-selection, and notch-sound are aimed at noise reduction. Each takes a list of frequencies (in Hz), and an optional filter order, and notches out each frequency. The sharpness of the notch is settable explicitly via the 'width' argument, and implicitly via the filter 'order'. A common application cancels 60 Hz hum:

(notch-channel (let ((freqs ())) 
                 (do ((i 60 (+ i 60))) 
                     ((= i 3000)) 
                   (set! freqs (cons i freqs))) (reverse freqs)))

Here we've built a list of multiples of 60 and passed it to notch-channel. Its default notch width is 2 Hz, and its default order tries to maintain that width given the channel's sampling rate, so the default filter order can be very high (65536). The filtering is normally done via convolution (by CLM's convolve generator), so a high filter order is not a big deal. In ideal cases, this can reduce the hum and its harmonics by about 90%. But, if the hum is not absolutely stable, you'll probably want wider notches:

(notch-channel (let ((freqs ())) 
                 (do ((i 60 (+ i 60))) 
                     ((= i 3000)) 
                   (set! freqs (cons i freqs))) (reverse freqs)) 1024)

The order of 1024 means we get 20 Hz width minima (44100 Hz srate), so this notches out much bigger chunks of the spectrum. You get 98% cancellation, but also lose more of the original signal.

make-savitzky-golay-filter size (order 2)
savitzky-golay-filter f in

This the Savitzky-Golay filter, assuming symmetrical positioning. It is an FIR smoothing filter; perhaps it could be useful in noise reduction.

(define (unnoise order)
  (let ((flt (make-savitzky-golay-filter order 2)))
    (map-channel (lambda (y) (savitzky-golay-filter flt y)))))

For more info on this filter, See "Numerical Recipes in C".

spectrum->coeffs order spectrum
fltit-1 order spectr

spectrum->coeffs is a version of Snd's very simple spectrum->coefficients procedure ("frequency sampling"). It returns the FIR filter coefficients given the filter 'order' and desired 'spectrum' (a float-vector). An example of its use is fltit-1.

(map-channel (fltit-1 10 (float-vector 0 1.0 0 0 0 0 0 0 1.0 0)))
make-volterra-filter acoeffs bcoeffs
volterra-filter flt x

volterra-filter and make-volterra-filter implement one form of a common non-linear FIR filter. This version is taken from Monson Hayes "Statistical DSP and Modeling"; it is a slight specialization of the form mentioned by J O Smith and others. The 'acoeffs' apply to the linear terms, and the 'bcoeffs' to the quadratic.

(let ((flt (make-volterra-filter (float-vector .5 .1) (float-vector .3 .2 .1))))
  (map-channel (lambda (x) (volterra-filter flt x))))
IIR filters
make-biquad a0 a1 a2 b1 b2

make-biquad is a wrapper for make-filter to return a biquad filter section.

cascade->canonical coeffs

cascade->canonical converts cascade coefficients to canonical form (the form used by CLM's filter generator). 'coeffs' is a list of filter coefficients; the function returns a float-vector, ready for make-filter.

kalman-filter-channel (Q 1.0e-5)

This is an experimental function aimed at noise reduction using a Kalman filter.

make-butter-high-pass fq, make-butter-hp M fc
make-butter-low-pass fq, make-butter-lp M fc
make-butter-band-pass fq bw, make-butter-bp M f1 f2
make-butter-band-reject fq bw, make-butter-bs M f1 f2

These functions produce Butterworth filters, returning a CLM filter generator. The first named ones (make-butter-high-pass et al) are taken from Sam Heisz's CLM version of Paris Smaragdis's Csound version of Charles Dodge's code from "Computer Music: synthesis, composition, and performance". The second set (make-butter-lp et al) provide arbitrary order Butterworths. 'M' * 2 is the filter order, 'f1' and 'f2' are the band edges in Hz.

(clm-channel (make-butter-bp 3 1000 2000))
(filter-sound (make-butter-low-pass 500.0))

See also the notch filter in new-effects.scm, and of course analog-filter.scm: the latter renders this section obsolete.

make-iir-high-pass-2 fc din
make-iir-low-pass-2 fc din
make-iir-band-pass-2 f1 f2
make-iir-band-stop-2 f1 f2
make-eliminate-hum  (hum-freq 60.0) (hum-harmonics 5) (bandwidth 10)
make-peaking-2 f1 f2 m

More IIR filters.

(map-channel (make-eliminate-hum))

make-peaking (a bandpass filter) returns a function suitable for map-channel (it takes one argument, the current sample, and returns a sample):

(let ((peaker (make-peaking-2 500 1000 1.0)))
  (map-channel peaker))

In this case 'm' is the gain in the pass band. Use the functions in analog-filter.scm, rather than this group.

synthesis
cheby-hka k a coeffs

This returns the amplitude of the kth harmonic (0=DC) in the waveshaping output given the index 'a', and harmonic coefficients 'coeffs' (the 0th element is DC amplitude).

(with-sound ()
  (let ((gen (make-polyshape 1000.0 :partials (list 1 .5  2 .25  3 .125  4 .125))))
    (do ((i 0 (+ i 1)))
        ((= i 88200))
      (outa i (* .5 (polyshape gen 0.25))))))
(cheby-hka 1 0.25 (float-vector 0 .5 .25 .125 .125)) ; returns first partial (fundamental) amplitude
flatten-partials partials (tries 32)

flatten-partials takes a list or float-vector of partial numbers and amplitudes, as passed to make-polywave, and tries to find an equivalent set of amplitudes that produces a less spikey waveform. The difference is primarily one of loudness until you have a lot of partials.

fm-parallel-component freq-we-want wc wms inds ns bs using-sine
fm-cascade-component freq-we-want wc wm1 a wm2 b
fm-complex-component freq-we-want wc wm a b interp sine ; "sine" arg currently ignored

This returns the amplitude of "freq-we-want" in parallel (complex) FM, where "wc" is the carrier, "wms" is a list of modulator frequencies, "inds" is a list of the corresponding indices, "ns" and "bs" are null (used internally), and using-sine is #t if the modulators are set up to produce a spectrum of sines, as opposed to cosines (we need to know whether to add or subtract the components that foldunder 0.0).

(fm-parallel-component 200 2000.0 (list 2000.0 200.0) (list 0.5 1.0) () () #t)

To get the same information for FM with a complex index, use fm-compex-component: (fm-compex-component 1200 1000 100 1.0 3.0 0.0 #f). For cascade FM (two levels only), use fm-cascade-component.

ssb-bank old-freq new-freq pairs-1 (order 40) (bw 50.0) (beg 0) dur snd chn edpos
ssb-bank-env old-freq new-freq freq-env pairs-1 (order 40) (bw 50.0) (beg 0) dur snd chn edpos
shift-channel-pitch freq (order 40) (beg 0) dur snd chn edpos

The ssb-bank functions provide single-sideband amplitude modulation, and pitch/time changes based on the ssb-am generator. If you run ssb-am on some input signal, the signal is shifted in pitch by the 'freq' amount. The higher the 'order', the better the sideband cancellation (amplitude modulation creates symmetrical sidebands, one of which is cancelled by the ssb-am generator). ssb-bank uses a bank of ssb-am generators, each with its own bandpass filter to shift a sound's pitch without changing its duration; the ssb-am generators do the pitch shift, and the filters pick out successive harmonics, so each harmonic gets shifted individually (i.e. harmonic relations are maintained despite the pitch shift). For an oboe at 557 Hz, good values are: (ssb-bank 557 new-freq 6 40 50). For a person talking at ca. 150 Hz: (ssb-bank 150 300 30 100 30) or (ssb-bank 150 100 40 100 20). To get a duration change without a pitch change, use this function followed by sampling rate conversion back to the original pitch:

(define (stretch-oboe factor)
  (ssb-bank 557 (* factor 557) 7 40 40)
  (src-sound (/ 1.0 factor)))

ssb-bank-env is the same as ssb-bank, but includes a frequency envelope: (ssb-bank-env 557 880 '(0 0 1 100.0) 7). shift-channel-pitch applies an ssb-am generator to a sound's channel (this is a variant of amplitude modulation). 'freq' and 'order' are the corresponding arguments to make-ssb-am. There is a dialog that runs ssb-bank in snd-motif.scm: create-ssb-dialog.

any-random e
gaussian-distribution s
pareto-distribution a
gaussian-envelope s

any-random provides the same output as rand if the latter's envelope (distribution function) argument is used, but using a slightly different method to generate the numbers. gaussian-envelope makes a gaussian distribution envelope suitable for rand. Also included is inverse-integrate, a version of CLM's distribution-to-weighting function.

(map-channel (lambda (y) (any-random 1.0 '(0 1 1 1))))          ; uniform distribution
(map-channel (lambda (y) (any-random 1.0 '(0 0 0.95 0.1 1 1)))) ; mostly toward 1.0
(let ((g (gaussian-distribution 1.0))) (map-channel (lambda (y) (any-random 1.0 g))))
(let ((g (pareto-distribution 1.0))) (map-channel (lambda (y) (any-random 1.0 g))))

In Ruby:

map_channel(lambda do |y| any_random(1.0, [0, 1, 1, 1]))            # uniform distribution
map_channel(lambda do |y| any_random(1.0, [0, 0, 0.95, 0.1, 1, 1])) # mostly toward 1.0
let(gaussian-distribution(1.0)) do |g|  map_channel(lambda do |y| any_random(1.0, g)) end
let(pareto-distribution(1.0))   do |g| map_channel(lambda do |y| any_random(1.0, g)) end
Random Numbers in Snd/CLM
generators, arbitrary distributions, fractals, 1/f: rand and rand-interp
dithering: dither-channel, dither-sound
noise-making instrument: noise.scm, noise.rb
physical modeling of noisy instruments: maraca.scm, maraca.rb
arbitrary distribution via rejection method: any-random
s7: random, random-state: random number between 0 and arg
Ruby: kernel_rand (alias for Ruby's rand), srand: random integer between 0 and arg, or float between 0 and 1
mus-random, mus_random: random float between -arg and arg
mus-rand-seed (settable)
bounded brownian noise: green-noise
brown and pink noise: brown-noise
effects
adsat size beg dur snd chn
freqdiv n snd chn

These two functions come from a package of effects developed by sed_sed@my-dejanews.com. adsat is "adaptive saturation", and freqdiv is "frequency division". (freqdiv n) repeats each nth sample 'n' times, clobbering the intermediate samples: (freqdiv 8). It turns your sound into a bunch of square waves.

brighten-slightly amount snd chn

brighten-slightly is a slight simplification of contrast-enhancement.

chordalize 

chordalize uses harmonically-related comb-filters to bring out a chord in a sound. The comb filters are controled by chordalize-amount (the default is .95), chordalize-base (the default is 100 Hz), and chordalize-chord (the default is (list 1 3/4 5/4)). chordalize returns a function suitable for map-channel:

 (map-channel (chordalize))

chordalize seems to work best with vocal sounds.

chorus

chorus tries to produce the chorus sound effect, but it needs work. It is controlled by the following variables:

chorus-size (5)        ; number of flangers
chorus-time (.05)      ; scales delay line length (flanger)
chorus-amount (20.0)   ; amp of rand-interp (flanger)
chorus-speed (10.0)    ; freq of rand-interp (flanger)
harmonicizer freq coeffs pairs (order 40) (bw 50.0) (beg 0) dur snd chn edpos

harmonicizer splits a sound into separate sinusoids, then splits each resultant harmonic into a set of harmonics, then reassembles the sound. The basic idea is very similar to ssb-bank, but harmonicizer splits harmonics, rather than pitch-shifting them. The result can be a brighter or richer sound.

(harmonicizer 550.0 (list 1 .5 2 .3 3 .2) 10)

'coeffs' is a list of harmonic-number and amplitude pairs, describing the spectrum produced by each harmonic. 'pairs' controls how many bands are used to split the original sound. 'order' is the bandpass filter's order in each such pair, and 'bw' controls its bandwidth.

lpc-coeffs data n m

lpc-coeffs returns 'm' LPC coeffients (in a vector) given 'n' data points in the float-vector 'data'.

lpc-predict data n coeffs m nf clipped

lpc-predict takes the output of lpc-coeffs ('coeffs') and the length thereof ('m'), 'n' data points 'data', and produces 'nf' new data points (in a float-vector) as its prediction. If 'clipped' is #t, the new data is assumed to be outside -1.0 to 1.0.

> (lpc-predict (float-vector 0 1 2 3 4 5 6 7) 8 (lpc-coeffs (float-vector 0 1 2 3 4 5 6 7) 8 4) 4 2)
#(7.906 8.557)
spike snd chn

spike returns a product (rather than the more usual sum) of succesive samples, with the current sample's sign; this normally produces a more spikey output. The more successive samples we include in the product, the more we limit the output to pulses placed at (just after) wave peaks. In spike's case, just three samples are multiplied. See also the volterra filter.

unclip-channel snd chn

unclip-channel tries to reconstruct clipped portions of a sound by using LPC to predict (backwards and forwards) the lost samples.

unclip-sound snd

unclip-sound calls unclip-channel on each channel in the sound 'snd'.

sampling rate conversion
linear-src-channel srinc snd chn

linear-src-channel performs sampling rate conversion using linear interpolation; this can sometimes be a nice effect.

src-duration env

src-duration takes an envelope representing the input (src change) to src, and returns the resultant sound length.

(src-duration '(0 1 1 2)) ; -> 0.693147180559945

which means that if the original sound was 2 seconds long, and we apply the envelope '(0 1 1 2) (via src-channel, for example) to that sound, the result will be .693 * 2 seconds long. To scale an src envelope to return a given duration, see src-fit-envelope below.

src-fit-envelope env target-dur

src-fit-envelope returns a version of "env" scaled so that its duration as an src envelope is "target-dur".

> (src-duration (src-fit-envelope '(0 1 1 2) 2.0))
2.0
stats, linear algebra, etc
channel-mean snd chn                            ; <f, 1> / n
channel-total-energy snd chn                    ; <f, f>
channel-average-power snd chn                   ; <f, f> / n
channel-norm snd chn                            ; sqrt(<f, f>)
channel-rms snd chn                             ; sqrt(<f, f> / n)
channel-variance snd chn                        ; <f, f> - ((<f, 1> / n) ^ 2) with quibbles
channel-lp u-p snd chn              
channel-lp-inf snd chn                          ; max abs f
channel2-inner-product s1 c1 s2 c2              ; <f, g>
channel2-orthogonal? s1 c1 s2 c2                ; <f, g> == 0
channel2-angle s1 c1 s2 c2                      ; acos(<f, g> / (sqrt(<f, f>) * sqrt(<g, g>)))
channel2-coefficient-of-projection s1 c1 s2 c2  ; <f, g> / <f, f>
channel-distance (s1 0) (c1 0) (s2 1) (c2 0)    ; sqrt(<f - g, f - g>)

These functions are taken from (or at least inspired by) Julius Smith's "Mathematics of the DFT". Many are standard ways of describing a signal in statistics; others treat a signal as a vector (channel-distance, for example, returns the Euclidean distance between two sounds). The 's1' and 's2' parameters refer to sound objects, and the 'c1' and 'c2' parameters refer to channel numbers.

channel-polynomial coeffs snd chn
spectral-polynomial coeffs snd chn
float-vector-polynomial v coeffs

float-vector-polynomial returns the evaluation of the polynomial (given its coefficients) over an entire float-vector, each element being treated as "x". channel-polynomial performs the same operation over a sound channel. spectral-polynomial is similar, but operates in the frequency domain (each multiply being a convolution).

> (float-vector-polynomial (float-vector 0.0 2.0) (float-vector 1.0 2.0)) ; x*2 + 1
#(1.0 5.0)
> (channel-polynomial (float-vector 0.0 1.0 1.0 1.0)) ; x*x*x + x*x + x

The "constant" (0-th coefficient) term in spectral polynomial is treated as a dither amount (that is, it has the given magnitude, but its phase is randomized, rather than being simple DC). See also poly.scm. In channel-poynomial, if you have an nth-order polynomial, the resultant spectrum is n times as wide as the original, so aliasing is a possibility, and even powers create energy at 0Hz.

scanned synthesis
compute-uniform-circular-string size x0 x1 x2 mass xspring damp
compute-string size x0 x1 x2 masses xsprings esprings damps haptics

These functions implement scanned synthesis of Bill Verplank and Max Mathews. To watch the wave, open some sound (so Snd has some place to put the graph), turn off the time domain display (to give our graph all the window) then

(let* ((size 128)
       (x0 (make-float-vector size 0.0))	   
       (x1 (make-float-vector size 0.0))	   
       (x2 (make-float-vector size 0.0)))
  (do ((i 0 (+ i 1)))
      ((= i 12))
    (let ((val (sin (/ (* 2 pi i) 12.0))))
      (set! (x1 (+ i (- (/ size 4) 6))) val)))
  (do ((i 0 (+ i 1)))
      ((= i 1024))
    (compute-uniform-circular-string size x0 x1 x2 1.0 0.1 0.0)
    (graph x0 "string" 0 1.0 -10.0 10.0)))
env

env.scm provides a variety envelope functions. An envelope in Snd/CLM is a list of breakpoint pairs. In the function names, I try to remember to use "envelope" to be a list of breakpoints, and "env" to be the result of make-env, a CLM env structure passed to the env generator. In an envelope, the x axis extent is arbitrary, though it's simplest to use 0.0 to 1.0. (In this file, envelopes are assumed to be flat lists, not float-vectors or lists of lists).

add-envelopes env1 env2

add-envelopes adds two envelopes together:

> (add-envelopes '(0 0 1 1) '(0 0 1 1 2 0))
(0 0 1/2 3/2 1 1)  ; i.e. (0 0 1 1.5 2 1) in the second env's terms
concatenate-envelopes :rest envs

concatenate-envelopes concatenates its arguments:

> (concatenate-envelopes '(0 1 1 0) '(0 0 1 1))
(0.0 1 1.0 0 2.0 1)
envelope-exp e (power 1.0) (xgrid 100)

envelope-exp interpolates segments into envelope to approximate exponential curves.

> (format #f "~{~,3F ~}" (envelope-exp '(0 0 1 1) 3.0 6))
"0.000 0.000 0.167 0.005 0.333 0.037 0.500 0.125 0.667 0.296 0.833 0.579 1.000 1.000 "
envelope-last-x env

envelope-last-x returns the maximum x value:

> (envelope-last-x '(0 1 1 0 2 0))
2
integrate-envelope env

integrate-envelope returns the area under the envelope.

> (integrate-envelope '(0 0 1 1))
0.5
> (integrate-envelope '(0 1 1 1))
1.0
> (integrate-envelope '(0 0 1 1 2 .5))
1.25
make-power-env e (scaler 1.0) (offset 0.0) duration
power-env e
power-env-channel pe (beg 0) snd chn edpos (edname "power-env-channel")
powenv-channel envelope (beg 0) dur snd chn edpos

make-power-env and power-env implement an extension of exponential envelopes; each segment has its own base. power-env-channel uses the same mechanism as an extension of env-channel.

(let ((pe (make-power-env '(0 0 32.0  1 1 0.0312  2 0 1) :duration 1.0)))
  (map-channel (lambda (y) (* y (power-env pe)))))

(let ((pe1 (make-power-env '(0 0 32.0  1 1 0.0312  2 0 1.0  3 .5 3.0  4 0 0) :duration 1.0)))
  (power-env-channel pe1))

powenv-channel is a simplification of power-env-channel; it takes a breakpoint list rather than a power-env structure:

(powenv-channel '(0 0 .325  1 1 32.0 2 0 32.0))
map-envelopes func env1 env2

map-envelopes applies 'func' to the breakpoints in the two envelope arguments, returning a new envelope.

> (map-envelopes + '(0 0 1 1 2 0) '(0 1 2 0))
(0 1 1/2 3/2 1 0)  ; i.e. '(0 1 1 1.5 2 0) in the original x-axis bounds
min-envelope env
max-envelope env

max-envelope returns the maximum y value in 'env', and min-envelope returns the minimum y value:

> (max-envelope '(0 0 1 1 2 3 4 0))
3.0
multiply-envelopes env1 env2

multiply-envelopes uses map-envelopes to multiply two envelopes:

Scheme:
> (multiply-envelopes '(0 0 1 1) '(0 0 1 1 2 0))
(0 0 0.5 0.5 1 0)

Ruby:
> multiply_envelopes([0, 0, 1, 1], [0, 0, 1, 1, 2, 0])
[0.0, 0.0, 0.5, 0.5, 1.0, 0.0]
 
Forth:
snd> '( 0e 0e 1.0 1.0 ) '( 0e 0e 1.0 1.0 2.0 0.0 ) multiply-envelopes
'( 0.0 0.0 0.5 0.5 1.0 0.0 )

The new envelope goes from 0.0 to 1.0 along the X axis; the multiplied envelopes are stretched or contracted to fit 0.0 to 1.0, and wherever one has a breakpoint, the corresponding point in the other envelope is interpolated, if necessary.

normalize-envelope env (new-max 1.0)

normalize-envelope returns a version of 'env' scaled so that its maximum y value is 'new-max'.

> (normalize-envelope '(0 0 1 1 2 3 4 0) .5)
(0 0.0 1 0.167 2 0.5 4 0.0)
repeat-envelope env repeats reflected normalized

repeat-envelope repeats an envelope (concatenates copies of itself). It's usually easier to use mus-reset to restart an envelope over and over (see pulsed-env).

> (repeat-envelope '(0 0 .1 .9 1 1 1.3 .2 2 0) 2)
(0 0 0.1 0.9 1.0 1 1.3 0.2 2.0 0 2.1 0.9 3.0 1 3.3 0.2 4.0 0)
repeated envelope

If the final y value is different from the first y value (as above), a quick ramp is inserted between repeats. 'normalized' causes the new envelope's x axis to have the same extent as the original's. 'reflected' causes every other repetition to be in reverse.

reverse-envelope env

reverse-envelope reverses an envelope.

> (reverse-envelope '(0 0 1 1 2 1))
(0 1 1 1 2 0)
rms-envelope file (beg 0.0) dur (rfreq 30.0) db

rms-envelope returns an rms envelope of a file; it is based on rmsenv.ins in the CLM package.

> (format #f "~{~,3F ~}" (rms-envelope "1a.snd"))
"0.000 0.049 0.033 0.069 0.067 0.049 0.100 0.000 0.133 0.000 0.167 0.000 0.200 0.000 "
scale-envelope env scl (offset 0.0)

scale-envelope scales the y values of an envelope by 'scl', and optionally adds 'offset'.

stretch-envelope env old-attack new-attack (old-decay #f) (new-decay #f)

stretch-envelope applies attack and optionally decay times to an envelope, much like divseg in clm-1.

> (stretch-envelope '(0 0 1 1) .1 .2)
(0 0 0.2 0.1 1.0 1)
> (stretch-envelope '(0 0 1 1 2 0) .1 .2 1.5 1.6)
(0 0 0.2 0.1 1.1 1 1.6 0.5 2.0 0)
window-envelope beg end env

window-envelope returns (as an envelope) the portion of its envelope argument that lies between the x axis values 'beg' and 'end'. This is useful when you're treating an envelope as a phrase-level control, applying successive portions of it to many underlying notes.

> (window-envelope 1.0 3.0 '(0.0 0.0 5.0 1.0))
(1.0 0.2 3.0 0.6)
see also:   make-env   env-channel   Enved   env-expt-channel
enved, xm-enved

enved.scm implements an independent envelope editor in each channel.

start-enveloping 
stop-enveloping 
channel-envelope snd chn
play-with-envs snd

(start-enveloping) opens an envelope editor for each subsequently opened sound. (stop-enveloping) turns this off. Each envelope can be read or written via (channel-envelope snd chn). An example use is play-with-envs which sets the channel's amplitude from its envelope during playback

channel enveds

Closely related to this is xm-enved.scm which implements a separate envelope editor widget.

xe-create-enved name parent args axis
xe-envelope xe-editor

xe-create-enved returns a new envelope editor whose x axis label is 'name', the x and y axis bounds are in the list 'axis', the editor's parent widget is 'parent', and the Xt-style resource argument list is 'args'. The editor's current envelope is accessible as 'xe-envelope'.

examp

examp.scm has become a bit of a mess; rather than get organized, I just appended new stuff as it came to mind. In this documentation, I'll divide the functions into the following non-orthogonal categories: ffts, filters, sound effects, marks, selections, graphics, and miscellaneous stuff

FFTs
display-correlation snd chn y0 y1

display-correlation graphs the correlation of the 2 channels of the sound 'snd'. To make this happen automatically as you move the time domain position slider: (hook-push graph-hook display-correlation). The last three parameters are unused; they are just for compatibility with graph-hook.

fft-cancel lo-freq hi-freq snd chn

fft-cancel ffts an entire channel, zeroes the bins between 'lo-freq' and 'hi-freq' (in Hz), then inverse ffts, giving a good notch filter.

(fft-cancel 500 1000)  ; squelch frequencies between 500 and 1000 Hz
fft-edit low-freq high-freq snd chn

fft-edit takes an fft of the entire sound, removes all energy below 'low-freq' and above 'high-freq' (in Hz), then inverse fft's. This is the complement of fft-cancel.

fft-env-edit env snd chn

fft-env-edit is similar to fft-edit, but applies an envelope to the spectral magnitudes.

(fft-env-edit '(0 0 .1 1 .2 1 .3 0 .5 1 1.0 0)) ; 1.0 = srate / 2 here
fft-env-interp env1 env2 interp snd chn

fft-env-interp performs fft-env-edit twice (using 'env1' and 'env2'), then mixes the two results following the interpolation envelope 'interp'.

fft-peak snd chn scale

fft-peak is an after-transform-hook function that reports the peak spectral magnitude in the status area.

Scheme: (hook-push after-transform-hook fft-peak)

Ruby:   $after_transform_hook.add_hook!(\"fft-peak\") do |snd, chn, scale|
          fft_peak(snd, chn, scale)
        end

This can be helpful if you're scanning a sound with the fft graph displayed; since it normalizes to 1.0 (to keep the graph from jumping around simply because the amplitude is changing), it's nice to know what the current peak actually represents. You can, of course, turn off the normalization:

(set! (transform-normalization) dont-normalize)
fft-smoother cutoff start samps snd chn

fft-smoother uses fft filtering to smooth a portion of a sound, returning a float-vector with the smoothed data. 'cutoff' sets where we starting zeroing out high frequencies.

Scheme: (float-vector->channel (fft-smoother .1 (cursor) 400 0 0) (cursor) 400)
Ruby:   vct2channel(fft_smoother(0.1, cursor, 400, 0, 0), cursor, 400)
fft-squelch squelch snd chn

fft-squelch is similar to fft-edit; any fft bin whose (normalized) magnitude is below 'squelch' is set to 0.0. This is sometimes useful for noise-reduction.

filter-fft func (normalize #t) snd chn

This a sort of generalization of the preceding functions. It gets the spectrum of all the data in the given channel, applies the function 'func' to each element of the spectrum, then inverse ffts. 'func' should take one argument, the current spectrum value.

(define brfft
  (let ((documentation "(brfft lofrq hifrq) removes all frequencies between lofrq and hifrq: (brfft 1000.0 2000.0)"))
    (lambda (lofrq hifrq)
      (let* ((len (framples))
	     (fsize (expt 2 (ceiling (log len 2))))
	     (ctr -1)
	     (lo (round (/ (* fsize lofrq) (srate))))
	     (hi (round (/ (* fsize hifrq) (srate)))))
        (filter-fft (lambda (y)
		      (set! ctr (+ 1 ctr))
		      (if (>= hi ctr lo)
		          0.0
		          y)))))))

Here are some sillier examples...

(let ((op (make-one-zero .5 .5))) (filter-fft op))
(let ((op (make-one-pole .05 .95))) (filter-fft op))
(filter-fft (lambda (y) (if (< y .1) 0.0 y))) ; like fft-squelch
(let ((rd (make-sampler 0 0 0 1 0))) 
  (scale-by 0) 
  (filter-fft (lambda (y) (rd))))             ; treat sound as spectrum
(filter-fft contrast-enhancement)
(filter-fft (lambda (y) (* y y y)))           ; extreme low pass
squelch-vowels snd chn

squelch-vowels uses fft data to try to distinguish a steady state portion (a vowel in speech) from noise (a consonant, sometimes), then tries to remove (set to 0.0) the vowel-like portions.

superimpose-ffts snd chn y0 y1

superimpose-ffts is a graph-hook function that superimposes the ffts of multiple (sync'd) sounds. (hook-push graph-hook superimpose-ffts) This function needs some work...

zoom-spectrum snd chn y0 y1

zoom-spectrum sets the transform size to correspond to the time-domain window size. (hook-push graph-hook zoom-spectrum).

filters
comb-filter scaler size
zcomb scaler size pm

comb-filter is an example of using the CLM comb generator.

Scheme:  (map-channel (comb-filter .8 32))
Ruby:    map_channel(comb_filter(0.8, 32))
Forth:   0.8 32 comb-filter-1 map-channel

it would be faster to use the comb filter directly:

(clm-channel (make-comb .8 32))

zcomb is a time-varying comb filter using the envelope 'pm' (the envelope is applied to the comb filter delay length).

(map-channel (zcomb .8 32 '(0 0 1 10)))
comb-chord scaler size amp

comb-chord uses comb filters at harmonically related sizes to create a chord (see also chordalize in dsp.scm). 'amp' is an overall amplitude scaler.

(map-channel (comb-chord .95 100 .3))
(map-channel (comb-chord .95 60 .3))
filtered-env e snd chn

filtered-env takes an amplitude envelope 'e' and creates a one-pole filter, and moves them in parallel over a sound; as the sound gets softer, the low-pass filter's cutoff frequency gets lower, a sort of poor-man's distance effect. When 'e' is at 1.0, no filtering takes place.

(filtered-env '(0 1 1 0)) ; fade out
formant-filter radius frequency

formant-filter applies a formant to its input.

(map-channel (formant-filter .99 2400))

It's probably faster to use the CLM filter directly:

(filter-sound (make-formant 2400 .99))
formants r1 f1 r2 f2 r3 f3

formants applies three formants in parallel.

(map-channel (formants .99 900 .98 1800 .99 2700))
moving-formant radius move-envelope

moving-formant moves a formant according to an envelope (the envelope y value is in Hz).

(map-channel (moving-formant .99 '(0 1200 1 2400)))
notch-filter scaler size

This is an example of calling the CLM notch filter.

(map-channel (notch-filter .8 32))
osc-formants radius bases amounts freqs

osc-formants sets up any number of independently oscillating formants, then calls map-channel.

Scheme: (osc-formants .99 (float-vector 400.0 800.0 1200.0) (float-vector 80.0 80.0 120.0) (float-vector 4.0 2.0 3.0))
Ruby:   osc_formants(0.99, vct(400, 800, 1200), vct(80, 80, 120), vct(4, 2, 3))

'bases' are the formant center frequencies; 'freqs' are the oscillator frequencies; 'amounts' are "deviations" — they scale the oscillator outputs which set the runtime formant frequencies (thereby setting the width of the warbling).

sound effects
add-notes notes snd chn

add-notes adds (mixes) 'notes' starting at the cursor in the currently selected channel. 'notes' is a list of lists of the form: (list file offset amp).

Scheme: (add-notes '(("oboe.snd") 
                     ("pistol.snd" 1.0 2.0)))

Ruby:   add_notes([["oboe.snd"], 
                   ["pistol.snd", 1.0, 2.0]])

This mixes "oboe.snd" at time 0.0, then "pistol.snd" at 1.0 (second) scaled by 2.0.

am freq
ring-mod freq gliss-env
ring-modulate-channel freq beg dur snd chn edpos
vibro speed depth

These functions perform amplitude modulation and ring-modulation. 'freq' is the modulation frequency.

(map-channel (am 440))
(map-channel (ring-mod 10 (list 0 0 1 (hz->radians 100))))
(ring-modulate-channel 100.0)
(map-channel (vibro 440 0.5))

am uses the CLM amplitude-modulate generator; the others are little more than oscil and a multiply. 'gliss-env' in ring-mod controls the frequency of the modulation. See also ssb-am.

chain-dsps beg dur :rest dsps

chain-dsps creates a patch of chained generators from its arguments. Someone wanted to set up generator patches in a note list:

(with-sound ()
  (chain-dsps 0 1.0 '(0 0 1 .25 2 0) (make-oscil 440))
  (chain-dsps 1.0 1.0 '(0 0 1 1 2 0) (make-one-zero .5) (make-readin "oboe.snd"))
  (chain-dsps 2.0 1.0 '(0 0 1 .125 2 0) (let ((osc1 (make-oscil 220)) 
	                                      (osc2 (make-oscil 440))) 
                                          (lambda (val) (+ (osc1 val) 
		                                           (osc2 (* 2 val)))))))

The 'dsps' is a sequence of breakpoint lists and generators; the breakpoint lists are treated as envelopes, and the generators are connected (previous) output to (current) input in the reverse of the order received. readin is an exception; since its input comes from a file, it is added to the current output. So, the first call is an oscil multiplied by an envelope. The second filters and envelopes readin input. The third sets up an additive synthesis patch. In Ruby, this example is:

with_sound() do
  chain_dsps(0, 1.0, [0, 0, 1, 1, 2, 0], make_oscil(:frequency, 440))
  chain_dsps(0, 1.0, [0, 0, 1, 1, 2, 0], make_one_pole(0.5), make_readin("oboe.snd"))
  chain_dsps(0, 1.0, [0, 0, 1, 1, 2, 0], 
   let(make_oscil(:frequency, 220),
       make_oscil(:frequency, 440)) 
     do |osc1, osc2|
       lambda do |val| 
         osc1.run(val) + osc2.run(2.0 * val) 
     end
   end)
end
compand 

These functions lookup a table value based on the current sample amplitude; the table is set up so that soft portions are slightly amplified. The companding curve is taken from Steiglitz "A DSP Primer".

cnvtest snd0 snd1 amp

This is an example of using convolution. It convolves 'snd0' and 'snd1' (using the CLM convolve generator), then scales by 'amp'. It returns the new maximum amplitude.

(cnvtest 0 1 .1)
cross-synthesis cross-snd amp fftsize radius

cross-synthesis performs cross-synthesis between 'cross-snd' (a sound) and the currently selected sound. 'cross-snd' is the sound that controls the spectra.

(map-channel (cross-synthesis 1 .5 128 6.0))
echo scaler secs
flecho scaler secs
zecho scaler secs frq amp

These are delay-based sound effects. echo returns an echo maker ('secs' is the delay in seconds between echos, 'scaler' is the amplitude ratio between successive echoes). zecho is similar, but also modulates the echoes. flecho is a low-pass filtered echo maker. See Snd with CLM for a discussion.

Scheme:
(map-channel (echo .5 .5) 0 44100)
(map-channel (zecho .5 .75 6 10.0) 0 65000)
(map-channel (flecho .5 .9) 0 75000)

Ruby:
map_channel(echo(0.5, 0.5), 0 44100)
map_channel(zecho(0.5, 0.75, 6, 10.0), 0, 65000)
map_channel(flecho(0.5, 0.9), 0, 75000)
expsrc rate snd chn

expsrc uses sampling rate conversion (the src generator) and granular synthesis (the granulate generator) to change the pitch of a sound without changing its duration.

(map-channel (expsrc 2.0)) ; up an octave

There are lots of other related examples: see for example clm-expsrc, expsnd below, ssb-bank, or the phase-vocoder.

expsnd rate-envelope snd chn

expsnd uses the same technique as expsrc, but uses it to change the tempo according to an envelope while maintaining the original pitch. expsnd needs dsp.scm (but doesn't check that it is loaded).

(expsnd '(0 1 2 .4))   ; speed up
(expsnd '(0 .5 2 2.0)) ; start fast, end slow
fp sr osamp osfrq snd chn

fp drives an src generator with an oscillator, modulating a sound. 'sr' is the base sampling rate; 'osamp' is the modulation depth; 'osfrq' is the modulation frequency. hello-dentist below is a randomized version of this. The name "fp" refers to "Forbidden Planet" which used this kind of sound effect a lot.

(fp 1.0 .3 20)
hello-dentist frq amp snd chn

hello-dentist drives n src generator with a rand-interp generator, producing a random quavering effect, hence the name.

(hello-dentist 40.0 .1)

'frq' is the random number frequency; 'amp' sets the depth of the modulation.

place-sound mono-snd stereo-snd panning-envelope-or-degree

place-sound mixes a mono sound ('mono-snd', an index) into a stereo sound ('stereo-snd') with panning determined by 'panning-envelope-or-degree'. If 'panning-envelope-or-degree' is a number (in degrees), the place-sound function has the same effect as using CLM's locsig generator; it mixes a mono sound into a stereo sound, splitting it into two copies whose amplitudes depend on the desired location. 0 degrees: all in channel 0, 90: all in channel 1.

(place-sound 0 1 45.0) 
;; 0=sound 0 (mono), 1=sound 1 (stereo), 45 deg, so outa * 0.5 and outb * 0.5

If 'panning-envelope-or-degree' is an envelope, the split depends on the panning envelope (0 = all in chan 0, etc).

(place-sound 0 1 '(0 0 1 1)) ; mix goes from all in outa to all in outb

This function could use at least a start time parameter.

Panning or Sound Placement
Place sound: place-sound above.
Place mix: mus-file-mix
CLM placement generator: locsig
CLM moving sound generator: dlocsig
Move sound via flanging: see flanging effect in new-effects.scm
Cross fade in frequency domain: fade.scm
pulse-voice cosines (freq 440.0) (amp 1.0) (fftsize 256) (r 2.0) snd chn

This function is a form of cross-synthesis which drives the resynthesis with a ncos pulse train. 'freq' is the ncos frequency; 'amp' is an overall amplitude scaler; 'cosines' is the number of cosines in the pulse (the more the spikier); 'fftsize' and 'r' (radius) control the formant bank used to get the current spectrum.

(pulse-voice 80 20.0 1.0 1024 0.01)
(pulse-voice 80 120.0 1.0 1024 0.2)
(pulse-voice 30 240.0 1.0 1024 0.1)
(pulse-voice 6 1000.0 1.0 512)

See also voice->unvoiced below.

make-ramp (size 128)
ramp gen up

ramp is a generator that produces a ramp of a given length, then sticks at 0.0 or 1.0 until the 'up' argument changes. The idea here is that we want to ramp in or out a portion of a sound based on some factor of the sound data; the ramp generator produces a ramp up when 'up' is #t, sticking at 1.0, and a ramp down when 'up' is #f, sticking at 0.0. 'size' sets the steepness of the ramp. A similar, less bumpy effect uses the moving-average generator. The following produces a very jittery, wandering amplitude envelope (brownian motion):

(let ((ramper (make-ramp 1000)))  ; ramp via increments of .001
  (map-channel (lambda (y) 
                 (* y (ramp ramper (< (random 1.0) .5))))))
reverse-by-blocks block-len snd chn
reverse-within-blocks block-len snd chn

reverse-by-blocks and reverse-within-blocks work best with speech. reverse-by-blocks divides a sound into blocks, then recombines those blocks in reverse order. reverse-within-blocks divides a sound into blocks, then recombines them in order, but with each block internally reversed. 'block-len' is the block length in seconds.

(reverse-by-blocks .1)
(reverse-within-blocks .1) ; .5 is also good
scramble-channels :rest new-order
scramble-channel silence

scramble-channels uses swap-channels to arbitrarily reorder the current sound's channels. The new channel order is 'new-order' so

(scramble-channels 3 2 0 1)

replaces chan0 with chan3, chan1 with chan2 and so on. scramble-channel searches for silences, sets up a list of segments based on those silences, and randomly re-orders the segments. 'silence' determines the background level that is treated as silence.

(scramble-channel .01)

This function needs cleaner splices between the sections.

sound-interp reader loc
make-sound-interp start snd chn
env-sound-interp envelope (time-scale 1.0) snd chn
granulated-sound-interp envelope (time-scale 1.0) (grain-length 0.10)
              (grain-envelope '(0 0 1 1 2 1 3 0)) (output-hop 0.05) snd chn

make-sound-interp returns an interpolating reader for the given channel. The interpolating reader reads a channel at an arbitary location, interpolating between samples if necessary. The corresponding generator is sound-interp. Here we use a sine wave to lookup the current sound:

 (let ((osc (make-oscil :frequency 0.5 :initial-phase (+ pi (/ pi 2))))
       (reader (make-sound-interp 0 0 0)) 
       (len (- (framples 0 0) 1)))
   (map-channel (lambda (val) 
     (sound-interp reader (* len (+ 0.5 (* 0.5 (oscil osc))))))))

This is effectively phase-modulation with an index of length-of-file-in-samples * 0.5 * hz->radians(oscil-frequency), or equivalently duration-in-seconds * frequency-in-Hz * pi. env-sound-interp reads the given channel (via a sound-interp generator) according to 'envelope' and 'time-scale', returning a new version of the data in the specified channel that follows that envelope; that is, when the envelope is 0.0 we get sample 0, when the envelope is 1.0 we get the last sample, when it is 0.5 we get the middle sample of the sound and so on.

Scheme: (env-sound-interp '(0 0 1 1))
Ruby:   env_sound_interp([0, 0, 1, 1])

returns an unchanged copy of the current sound. To get the entire sound in reverse:

Scheme: (env-sound-interp '(0 1 1 0))
Ruby:   env_sound_interp([0, 1, 1, 0])

And to go forward then backward, taking twice the original duration:

Scheme: (env-sound-interp '(0 0 1 1 2 0) 2.0)
Ruby:   env_sound_interp([0, 0, 1, 1, 2, 0], 2.0)

src-sound with an envelope could be used for this effect, but it is much more direct to apply the envelope to sound sample positions. A similar function is scratch in clm-ins.scm.

granulated-sound-interp is similar to env-sound-interp, but uses granular synthesis rather than sampling rate conversion to recreate the sound, so the effect is one of changing tempo rather than changing speed (pitch). Here we dawdle for awhile, then race at the end to get the whole sound in:

(granulated-sound-interp '(0 0 1 .1 2 1) 1.0 0.2 '(0 0 1 1 2 0))
voiced->unvoiced amp fftsize r tempo snd chn

This function is a form of cross-synthesis which drives the resynthesis with white noise (see also pulse-voice above).

 (voiced->unvoiced 1.0 256 2.0 2.0) ; whispered, twice as fast as original

'tempo' is the speed of the resynthesis.

marks
first-mark-in-window-at-left 

first-mark-in-window-at-left moves the (time domain) graph so that the leftmost visible mark is at the left edge. In large sounds it can be pain to get the left edge of the window aligned with a specific spot in the sound. In the following example, we assume the desired left edge has a mark, and the 'l' key (without control) will move the window left edge to that mark.

(bind-key #\l 0 first-mark-in-window-at-left)
mark-loops 

mark-loops places marks at any loop points found in the current sound's header. Only a few headers support loop points which are apparently used in synthesizers to mark portions of a waveform that can be looped without causing clicks, thereby lengthening a sound as a key is held down.

selections
region-play-list data
region-play-sequence data

region-play-list plays a list of regions. 'data' is list of lists: (list (list reg time)...); region 'reg' is played at time 'time' (in seconds).

(region-play-list (list (list reg0 0.0) (list reg1 0.5) (list reg2 1.0) (list reg0 1.0)))

which plays region reg0 at time 0.0 and 1.0, region reg1 at 0.5, and region reg2 at 1.0. Similarly, region-play-sequence plays a sequence of regions, one after the other:

(region-play-sequence (list reg0 reg1 reg2 reg0)) ; play in same order as before, but one after the other
region-rms reg

region-rms returns the rms value of the region's data (in chan 0).

selection-rms 

selection-rms returns the rms value of the selection's data (in chan 0).

graphics
auto-dot snd chn y0 y1

auto-dot sets the dot size (when you're using dots in the time domain) based on the current graph size.

(hook-push graph-hook auto-dot)
display-db snd chn

display-db is a lisp-graph-hook function to display the time domain data in dB.

(hook-push lisp-graph-hook display-db)

I just noticed that its y axis is labelled upside down.

display-energy snd chn

display-energy is a lisp-graph-hook function to display the time domain data squared. Here is a picture of it in action.

flash-selected-data time-interval

flash-selected-data causes the selected channel's graph to flash red and green. 'time-interval' is in milliseconds:

(flash-selected-data 100)

Not sure why anyone would want such a thing... examp.scm also has (commented out) functions to display colored text in rxvt:

(format #t "~Athis is red!~Abut this is not" red-text normal-text)
(format #t "~A~Ahiho~Ahiho" yellow-bg red-fg normal-text)

It's possible to use the same escape sequences in a normal shell script, of course:

echo '\e[41m This is red! \e[0m'
miscellaneous stuff
all-chans 

all-chans returns two parallel lists, the first a list of sound objects, the second of channel numbers. If we have two sounds open (indices 0 and 1 for example), and the second has two channels, (all-chans) returns '((#<sound 0> #<sound 1> #<sound 1>) (0 0 1)). The interpretation is: '((sound-with-index0 sound-with-index1 sound-with-index1) (chan0 chan0 chan1)), so if we're mapping some function with the usual snd chn parameters over all the current channels, we can get the sound and channel values from these lists.

channel-clipped? snd chn

channel-clipped? returns #t and a sample number if it finds clipping in the given channel. examp.scm also has commented out code that places a mark at the start of each clipped section in a sound, and adds a menu item ("Show Clipping") under the View menu.

do-chans func origin
do-all-chans func origin
do-sound-chans func origin

do-chans applies 'func' to all the sync'd channels using 'origin' as the edit history indication. do-all-chans is the same but applies 'func' to all channels of all sounds. do-sound-chans applies 'func' to all channels in the currently selected sound.

(do-all-chans (lambda (val) (* 2.0 val))) ; double all samples
every-sample? func

every-sample? applies 'func' to each sample in the current channel and returns #t if 'func' is not #f for all samples; otherwise it moves the cursor to the first offending sample.

> (every-sample? (lambda (y) (< (abs y) .1)))
#f
> (cursor)
4423
> (sample (cursor))
0.101104736328125
explode-sf2 

explode-sf2 turns a soundfont file (assuming it is the currently selected sound) into a bunch of files of the form sample-name.aif. It is based on soundfont-info; that documentation includes a function, mark-sf2, that places a named mark at start of each new member of the font and unnamed marks at the various loop points.

find-click loc

find-click finds the next click, starting its search at 'loc'. It returns #f if it can't find a click.

finfo filename

finfo returns a description of the file 'filename'.

> (finfo "oboe.snd")
"oboe.snd: chans: 1, srate: 22050, Sun/Next, big endian short (16 bits), len: 2.305"
find-pitch pitch
locate-zero limit
next-peak 
search-for-click 
zero+ 

locate-zero looks for the next sample where adjacent samples together are less than 'limit' and moves the cursor to that sample. The others are examples of searching procedures (to be used with C-s and friends): zero+ finds the next positive-going zero crossing (if searching forwards). next-peak finds the next maximum or minimum in the waveform. search-for-click looks for a click. find-pitch finds the next place where 'pitch' (in Hz) is predominate. For example, type C-s (in the graph), then in the status area: (find-pitch 600), and if the function finds some place in the sound where 600 Hz seems to be the basic pitch, it moves the cursor there and reports the time in the status area text window.

mpg mpgfile rawfile

mpg uses the "system" function to call mpg123 to translate an MPEG format sound file to a headerless ("raw") file containing 16-bit samples.

(mpg "mpeg.mpg" "mpeg.raw")

This is now built-in if the Snd configuration process can find mpg123.

open-next-file-in-directory 
click-middle-button-to-open-next-file-in-directory 

click-middle-button-to-open-next-file-in-directory sets up the mouse-click-hook and open-hook so that clicking the middle mouse button closes the current file and opens the next (alphabetical by filename) in the current directory. These are used in edit123.scm.

play-ac3 name

play-ac3 tries to play an AC3 encoded sound file by calling a52dec.

read-ascii file (out-filename "test.snd") (out-type mus-next) (out-format mus-bshort) (out-srate 44100)

read-ascii tries to turn a text file into a sound file. Octave or perhaps WaveLab produce these files; each line has one integer (as text), apparently a signed short. The read-ascii parameters describe the output file.

read-flac file
write-flac snd

read-flac and write-flac deal with FLAC files. This is now built into Snd if the flac program can be found at configuration time.

read-ogg file
write-ogg snd

read-ogg and write-ogg deal with OGG files. This is now built into Snd if the oggdec and offenc programs can be found at configuration time.

read-speex file
write-speex snd

read-speex and write-speex deal with SPEEX files. This is now built into Snd if speexdec and speexenc can be found at configuration time.

remove-clicks 

remove-clicks looks for obvious clicks and uses smooth-sound to remove them. See also remove-single-sample-clicks and remove-pops in clean.scm.

sounds->segment-data main-dir (output-file "sounds.data")

This function takes a directory name, and runs through all the sounds in the embedded directories, returning a text file with segment start and end times, and segment maxamps.

(sounds->segment-data "/home/bil/test/iowa/sounds/" "iowa.data")

It was written to find the note boundaries in the Iowa musical instrument sound library.

sort-samples bins

sort-samples provides a histogram of the samples (by amplitude) in 'bins' bins.

> (sort-samples 20)  ; bins go by 0.05
#(129017 90569 915 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)
;; so 915 samples were > 0.1 in absolute value
sync-everything 

sync-everything sets the sync fields of all currently open sounds to the same unique value.

update-graphs 

update-graphs updates (redraws) all graphs.

window-rms 

window-rms returns the rms of the data in currently selected graph window.

window-samples snd chn

window-samples returns (in a float-vector) the samples displayed in the current window for the given channel. This is just a trivial wrapper for channel->float-vector.

xb-open snd
xb-close snd
switch-to-buf

These provide Emacs-like C-x b support where only one sound is visible at a time. To activate it:

(bind-key #\b 0 switch-to-buf #t)
(hook-push close-hook xb-close)
(hook-push after-open-hook xb-open)	    
extensions

These were originally scattered around examp.scm; I thought it would be more convenient if they were in one file.

channels-equal? snd1 chn1 snd2 chn2 (allowable-difference 0.0)
channels=? snd1 chn1 snd2 chn2 (allowable-difference 0.0)

channels=? returns #t if the two specified channels are the same within the given 'allowable-difference'. The 'allowable-difference' is checked on each sample, so any sample-wise difference larger than that causes the comparison to return #f. channels-equal? returns #t if channels=? and the channels are the same length. In channels=? one the other hand, the trailing (extra) samples in one channel are compared with 0.0 (that is, the shorter channel is padded out with zeros).

channel-sync snd chn

channel-sync uses the channel-properties list to implement a channel-local sync field. (This property is currently not used anywhere).

contrast-channel index beg dur snd chn edpos

contrast-channel applies the CLM contrast-enhancement function to a channel; this is largely equivalent to the control panel Contrast slider.

contrast-sound index (beg 0) dur snd

contrast-sound applies contrast-enhancement to every channel of the sound 'snd'. It is the multichannel version of contrast-channel.

dither-channel (amount .00006) beg dur snd chn edpos	

dither-channel adds "dithering" (noise) to a channel; some experts insist this makes everything copacetic. The noise consists of two white noise generators adding together.

dither-sound (amount .00006) (beg 0) dur snd

dither-sound adds dithering to every channel of the sound 'snd'. It is the multichannel version of dither-channel.

enveloped-mix filename beg env

enveloped-mix is like mix-sound, but includes an amplitude envelope over the mixed-in data.

(enveloped-mix "pistol.snd" 0 '(0 0 1 1 2 0))
env-expt-channel env exponent (symmetric #t) beg dur snd chn edpos
any-env-channel env func beg dur snd chn edpos
ramp-expt a0 a1 exponent (symmetric #t) beg dur snd chn edpos
sine-env-channel env beg dur snd chn edpos
sine-ramp a0 a1 beg dur snd chn edpos
blackman4-env-channel env beg dur snd chn edpos
blackman4-ramp a0 a1 beg dur snd chn edpos
env-squared-channel env (symmetric #t) beg dur snd chn edpos
ramp-squared a0 a1 (symmetric #t) beg dur snd chn edpos

These functions goof around with envelopes in various amusing ways. any-env-channel takes an envelope and a function to produce the connection between successive breakpoints, and applies the two to the current channel as an envelope. This packages up most of the "boilerplate" associated with applying an envelope to a sound. It is used by the other enveloping functions: sine-env-channel, blackman4-env-channel, and env-squared-channel. sine-ramp and sine-env-channel are the sinusoidal versions of ramp-channel and env-channel.

(sine-env-channel '(0 0 1 1 2 -.5 3 1))

applies the given envelope to the current channel, connecting the points with a sinusoidal curve. Similarly, blackman4-env-channel connects the dots with a sum of cosines, and env-squared-channel connects the dots with an x^2 curve. To get any other positive exponent, use env-expt-channel. The 'symmetric' argument determines whether the up and down moving ramps look symmetrical around a break point.

exponential envelopes
(env-channel '(0 0 1 1 2 -.75 3 0)) 
(env-sound '(0 0 1 1 2 -.75 3 0) 0 100 32.0)  
(env-sound '(0 0 1 1 2 -.75 3 0) 0 100 .032) 
(env-sound '(0 0 1 1 2 -.75 3 0) 0 100 0.0)
(sine-env-channel '(0 0 1 1 2 -.75 3 0))
(env-squared-channel '(0 0 1 1 2 -.75 3 0))
(blackman4-env-channel '(0 0 1 1 2 -.75 3 0))
(env-squared-channel '(0 0 1 1 2 -.75 3 0) #f)
(env-expt-channel '(0 0 1 1 2 -.75 3 0) 3.0)
(env-expt-channel '(0 0 1 1 2 -.75 3 0) 3.0 #f)
(env-expt-channel '(0 0 1 1 2 -.75 3 0) .3)
(env-expt-channel '(0 0 1 1 2 -.75 3 0) .3)
for-each-sound-file func dir
map-sound-files func dir
match-sound-files func dir

for-each-sound-file and map-sound-files apply 'func' to each sound file in 'dir'. The 'func' is passed one argument, the sound file name. map-sound-files returns a list of the results, if any, returned from 'func'. match-sound-files applies 'func' to each sound file in 'dir' and returns a list of files for which func does not return #f.

(for-each-sound-file
  (lambda (n) 
    (if (> (mus-sound-duration n) 10.0) 
      (snd-print n)))
  (sound-files-in-directory "."))
insert-channel filedat beg dur snd chn edpos

insert-channel inserts the specified data ('filedat') in the given channel at the given location. See mix-channel for a description of 'filedat'.

mix-channel filedat beg dur snd chn edpos

mix-channel is a "regularized" version of the file mixing functions (mix and mix-sound). Its first argument can be either a filename (a string), a sound, or a list containing the filename (or index), the start point in the file, and (optionally) the channel of the file to mix:

(mix-channel "pistol.snd")             ; mixing starts at sample 0, entire sound is mixed
(mix-channel "pistol.snd" 10000)       ; mixing starts at sample 10000 in current sound
(mix-channel (list "pistol.snd" 1000)) ; mixed data starts at sample 1000 in pistol.snd
(mix-channel (list "2.snd" 0 1))       ; mixed data reads channel 1 in 2.snd
mono->stereo new-name snd1 chn1 snd2 chn2
stereo->mono orig-snd chan1-name chan2-name
mono-files->stereo new-name chan1-file chan2-file

mono->stereo combines two mono sounds (currently open in Snd) into one (new) stereo file. mono-files->stereo is the same, but the source sounds are files, not necessarily already open in Snd. stereo->mono takes a stereo sound and produces two new mono sounds. (The corresponding stereo->mono-files can be based on the existing extract-channel function).

normalized-mix filename beg in-chan snd chn

normalized-mix is like mix but the mixed result has same peak amplitude as the original data.

normalize-sound amp (beg 0) dur snd

normalize-sound scales the sound 'snd' to peak amplitude 'amp'. It is the multichannel version of normalize-channel.

offset-channel amount beg dur snd chn edpos	

offset-channel adds a constant (DC offset) to a channel.

offset-sound off (beg 0) dur snd

offset-sound adds 'off' to every sample in the sound 'snd'. It is the multichannel version of offset-channel.

pad-sound beg dur snd

pad-sound places a block of 'dur' zeros in every channel of the sound 'snd' starting at 'beg'. It is the multichannel version of pad-channel.

redo-channel (edits 1) snd chn

redo-channel is a "regularized" version of redo.

scale-sound scl (beg 0) dur snd

scale-sound multiplies every sample in the sound 'snd' by 'scl'. It is the multichannel version of scale-channel.

undo-channel (edits 1) snd chn

undo-channel is a "regularized" version of undo.

fade

The two functions in fade.scm perform frequency-domain cross-fades, that is, the cross-fade is handled by a bank of bandpass filters (formant generators). The effect is sometimes only slightly different from a normal (time-domain) cross-fade, but there are some interesting possibilities ("sound evaporation", etc).

cross-fade beg dur amp file1 file2 ramp-beg ramp-dur ramp-type bank-dur fs fwidth

cross-fade stitches 'file1' to 'file2' using filtering to provide the join (rather than amplitude ramps). 'ramp-type' can be 0: sweep up, 1: sweep down, 2: sweep split from the middle; "sweep up" means that the low frequencies are filtered out first, etc. 'fs' is how many formants to set up; 'fwidth' is the formant resonance width control; 'ramp-beg' and 'ramp-dur' set the start point and length of the sweep; 'bank-dur' controls how much time is spent in the formant bank before starting or after ending the ramp.

(with-sound () (cross-fade 0 2 1.0 "oboe.snd" "trumpet.snd" 0.5 1.0 0 .1 256 2))
(float-vector->channel (cross-fade 0 1.5 1.0 0 1 0.5 .5 0 1.0 256 2))

These fades seem more successful to me when done relatively quickly (the opposite of the dissolve-fade below which is best if done as slowly as possible). With any luck the "sweep up" case can produce a sort of "evaporation" effect. A similar idea is behind dissolve-fade:

dissolve-fade beg dur amp file1 file2 fsize r lo hi

It ramps in and out frequency bands chosen at random. The original hope was to get something like a graphical dissolve, but it turns out to be better to let the random changes float along with no overall direction. If the current band amplitude is 1.0, we send it toward 0.0 and vice versa. Given patience and a suitably noisy original, strange pitches emerge and submerge. 'fsize' is the formant bank size; 'r' is the same as 'fwidth' in cross-fade (resonance width) modulo a factor of 2 (sigh...). 'lo' and 'hi' set the portion of the formant bank that is active during the dissolve.

(with-sound () (dissolve-fade 0 1 1.0 "oboe.snd" "trumpet.snd" 256 2 0 128))
(float-vector->channel (dissolve-fade 0 2 1 0 1 1024 2 2 #f))
freeverb

freeverb is Jezar Wakefield's reverberator, translated by Michael Scholz from CLM's freeverb.ins (written by Fernando Lopez-Lezcano), and documented in freeverb.html in the CLM tarball.

freeverb
    (room-decay 0.5)
    (damping 0.5)
    (global 0.3)
    (predelay 0.03)
    (output-gain 1.0)
    (output-mixer #f)
    (scale-room-decay 0.28)
    (offset-room-decay 0.7)
    (combtuning '(1116 1188 1277 1356 1422 1491 1557 1617))
    (allpasstuning '(556 441 341 225))
    (scale-damping 0.4)
    (stereo-spread 23)
    (verbose #f)

Here is a paraphrase of some of Fernando's documentation. 'room-decay' determines the decay time of the reverberation. 'damping' set the high frequency damping; this parameter can be a number, or an array or a list (with same number of elements as output channels). It is possible to control the damping for each output channel. 'global' controls how the outputs of all reverbs (one per channel) are mixed into the output stream. Specifying "0" will connect each reverberator directly to each output channel, "1" will mix all reverberated channels equally into all output channels. Intermediate values will allow for an arbitrary balance between local and global reverberation. The overall gain of the mixing matrix is kept constant. 'output-mixer' overrides this parameter. 'predelay' sets the predelay that is applied to the input streams. An array or list lets you specify the individual predelays for all chanenels. 'output-gain' is the overall gain multiplier for the output streams. 'output-mixer' sets the output mixing matrix directly (rather than through 'global').

(with-sound (:reverb freeverb :reverb-data '(:output-gain 3.0)) 
  (fm-violin 0 .1 440 .1 :reverb-amount .1))
see also:   jcrev   nrev convolution
grani

This is Fernando Lopez-Lezcano's CLM grani granular synthesis instrument translated to Scheme by Mike Scholz. The Ruby version is in clm-ins.rb.

grani start-time duration amplitude file
  (input-channel 0)                       ; input file channel from which samples are read
  (grains 0)                              ; if not 0, total number of grains to be generated
  (amp-envelope '(0 0 0.3 1 0.7 1 1 0))   ; overall amplitude envelope for note
  (grain-envelope '(0 0 0.3 1 0.7 1 1 0)) ; env for each individual grain
  (grain-envelope-end #f)                 ; if not #f, a second grain env
  (grain-envelope-transition '(0 0 1 1))  ; interp 0: use grain-envelope, 1: use grain-envelope-end
  (grain-envelope-array-size 512)         ; make-table-lookup table size
  (grain-duration 0.1)                    ; number or envelope setting grain duration (in seconds)
  (grain-duration-spread 0.0)             ; random spread around 'grain-duration'
  (grain-duration-limit 0.002)            ; minimum grain duration (in seconds)
  (srate 0.0)                             ; number or envelope setting sampling rate conversion
  (srate-spread 0.0)                      ; random spread of src around 'srate'
  (srate-linear #f)                       ; if #f, srate (envelope) is exponential
  (srate-base (expt 2 (/ 12)))            ; srate env base if exponential
  (srate-error 0.01)                      ; error bound for exponential conversion
  (grain-start '(0 0 1 1))                ; env that sets input file read point of current grain
  (grain-start-spread 0.0)                ; random spread around 'grain-start'
  (grain-start-in-seconds #f)             ; if #f, treat 'grain-start' as a percentage
  (grain-density 10.0)                    ; env on number of grains / second in output
  (grain-density-spread 0.0)              ; random spread around 'grain-density'
  (reverb-amount 0.01)
  (reverse #f)                            ; if #t, input is read backwards
  (where-to 0)                            ; locsig stuff — see the full documentation
  (where-bins ())
  (grain-distance 1.0)                    ; distance of sound source (locsig)
  (grain-distance-spread 0.0)             ; random spread around 'grain-distance'
  (grain-degree 45.0)
  (grain-degree-spread 0.0)
  (verbose #t)

(with-sound (:channels 2 :reverb jc-reverb :reverb-channels 1)
  (grani 0 1 .5 "oboe.snd" :grain-envelope '(0 0 0.2 0.2 0.5 1 0.8 0.2 1 0)))
see also:   granulate   expsrc   expand
heart

Snd can be used with non-sound data, and with-sound makes it easy to write such data to a sound file. An example is heart.scm. In this code, we search a file for blood pressure readings (they are scattered around with a bunch of other stuff), then write those numbers to a stereo sound file (the sphygmometer readings are between 70 and 150), then open that file in Snd with all the sound-related clipping features turned off. We also tell Snd to skip the data file in its start-up load process (since it is an uninterpretable text file) by incrementing script-arg.

heart picture
hooks

hooks.scm and hooks.rb have various hook-related functions.

describe-hook hook

describe-hook tries to decipher the functions on the hook list; this is almost identical to hook-functions.

hook-member func hook

hook-member returns #t if 'func' is already on the hook list, equivalent to (member value (hook-functions hook))

reset-all-hooks 

reset-all-hooks resets all of Snd's built-in hooks.

snd-hooks 

snd-hooks returns a list of all Snd built-in non-channel hooks.

with-local-hook hook local-hook-procs thunk

with-local-hook is a kind of "let" for hooks; it evaluates 'thunk' with 'hook' set to 'local-hook-procs' (a list which can be nil), then restores 'hook' to its previous state upon exit. The result returned by 'thunk' is returned by with-local-hook.

index
html obj

index.scm provides a connection between firefox and the Snd documentation. The index itself is built by make-index.scm, then accessed through the function html. (html arg), where 'arg' can be a string, a symbol, or a procedure sends the html reader to the corresponding url in the Snd documents.

see also:   html-program   snd-help   snd-urls
inf-snd.el, DotEmacs

These two files provide support for Snd as an Emacs subjob. inf-snd.el is by Michael Scholz, and DotEmacs is by Fernando Lopez-Lezcano. Both can be loaded in your ~/.emacs file (or ~/.xemacs/init.el if you're using xemacs).

DotEmacs sets up "dialects" for various versions of Common Lisp and for Snd, then binds C-x C-l to run ACL. This is intended for CCRMA'S 220 class, but it might be of interest to others. Much fancier is inf-snd.el. What follows is taken almost verbatim from Mike Scholz's comments in that file:

inf-snd.el defines a snd-in-a-buffer package for Emacs. It includes a Snd-Ruby mode (snd-ruby-mode), a Snd-Scheme mode (snd-scheme-mode), and a Snd-Forth mode (snd-forth-mode) for editing source files. The commands inf-snd-help and snd-help access the description which Snd provides for many functions. Using the prefix key C-u you get the HTML version of Snd's help. With tab-completion in the status area you can scan all functions at a glance. A menu "Snd/Ruby" is placed in the Emacs menu bar. Entries in this menu are disabled if no inferior Snd process exists. These variables may need to be customized to fit your system:

inf-snd-ruby-program-name   "snd-ruby"    Snd-Ruby program name
inf-snd-scheme-program-name "snd-s7"      Snd-Scheme program name using s7
inf-snd-forth-program-name  "snd-forth"   Snd-Forth program name
inf-snd-working-directory   "~/"          where Ruby or Scheme scripts reside
inf-snd-index-path          "~/"          path to snd-xref.c
inf-snd-prompt-char         ">"           listener prompt
snd-ruby-mode-hook          nil           to customize snd-ruby-mode
snd-scheme-mode-hook         nil           to customize snd-scheme-mode
snd-forth-mode-hook         nil           to customize inf-snd-forth-mode

You can start inf-snd-ruby-mode either with the prefix-key (C-u M-x run-snd-ruby) — you will be asked for program name and optional arguments — or directly via (M-x run-snd-ruby). In the latter case, the variable inf-snd-ruby-program-name needs to be set correctly. inf-snd-scheme-mode and inf-snd-forth-mode are handled in the same way. Here's an example for your ~/.emacs file:

(autoload 'run-snd-ruby     "inf-snd" "Start inferior Snd-Ruby process" t)
(autoload 'run-snd-scheme    "inf-snd" "Start inferior Snd-Scheme process" t)
(autoload 'run-snd-forth    "inf-snd" "Start inferior Snd-Forth process" t)
(autoload 'snd-ruby-mode    "inf-snd" "Load snd-ruby-mode." t)
(autoload 'snd-scheme-mode   "inf-snd" "Load snd-scheme-mode." t)
(autoload 'snd-forth-mode   "inf-snd" "Load snd-forth-mode." t)

(setq inf-snd-ruby-program-name "snd-ruby -notebook")
(setq inf-snd-scheme-program-name "snd-scheme -separate")
(setq inf-snd-forth-program-name "snd-forth")
(setq inf-snd-working-directory "~/Snd/")
(setq inf-snd-index-path "~/Snd/snd/")

See inf-snd.el for more info and examples of specializing these modes. You can change the mode while editing a Snd-Ruby, Snd-Scheme, or Snd-Forth source file with M-x snd-ruby-mode, M-x snd-scheme-mode, or M-x snd-forth-mode. To have Emacs determine automatically which mode to set, you can use special file-extensions. I use file-extension ".rbs" for Snd-Ruby source files, ".cms" for Snd-Scheme, and ".fth" for Snd-Forth.

(set-default 'auto-mode-alist
	     (append '(("\\.rbs$" . snd-ruby-mode)
                    ("\\.cms$" . snd-scheme-mode))
		     auto-mode-alist))

Or you can use the local mode variable in source files, e.g. by "-*- snd-ruby -*-" or "-*- snd-scheme -*-" in first line.

Key bindings for inf-* and snd-*-modes

\e\TAB        snd-completion    symbol completion at point
C-h m         describe-mode     describe current major mode

Key bindings of inf-snd-ruby|scheme|forth-mode:

C-c C-s   	 inf-snd-run-snd   (Snd-Ruby|Scheme|Forth from a dead Snd process buffer)
M-C-l		 inf-snd-load      load script in current working directory
C-c C-f   	 inf-snd-file      open view-files-dialog of Snd
M-C-p		 inf-snd-play      play current sound file
C-c C-t 	 inf-snd-stop      stop playing all sound files
C-c C-i   	 inf-snd-help      help on Snd-function (snd-help)
C-u C-c C-i	 inf-snd-help-html help on Snd-function (html)
C-c C-q   	 inf-snd-quit      send exit to Snd process
C-c C-k   	 inf-snd-kill      kill Snd process and buffer

Key bindings of snd-ruby|scheme|forth-mode editing source files:

C-c C-s   	 snd-run-snd
M-C-x     	 snd-send-definition
C-x C-e   	 snd-send-last-sexp
C-c M-e   	 snd-send-definition
C-c C-e   	 snd-send-definition-and-go
C-c M-r   	 snd-send-region
C-c C-r   	 snd-send-region-and-go
C-c M-o   	 snd-send-buffer
C-c C-o   	 snd-send-buffer-and-go
C-c M-b   	 snd-send-block          (Ruby only)
C-c C-b   	 snd-send-block-and-go   (Ruby only)
C-c C-z   	 snd-switch-to-snd
C-c C-l   	 snd-load-file
C-u C-c C-l 	 snd-load-file-protected (Ruby only)
C-c C-f   	 snd-file    	   open view-files-dialog of Snd
C-c C-p   	 snd-play    	   play current sound file
C-c C-t   	 snd-stop    	   stop playing all sound files
C-c C-i   	 snd-help    	   help on Snd-function (snd-help)
C-u C-c C-i	 snd-help-html	   help on Snd-function (html)
C-c C-q   	 snd-quit    	   send exit to Snd process
C-c C-k   	 snd-kill    	   kill Snd process and buffer

If xemacs complains that comint-snapshot-last-prompt is not defined, get the latest comint.el; I had to go to the xemacs CVS site since Fedora Core 5's xemacs (21.4) had an obsolete copy. Then scrounge around until you find xemacs-packages/xemacs-base/comint.el. Don't use the comint.el in the emacs package. It's not a tragedy if this variable isn't defined — you just don't get a prompt in the Snd Emacs window, but things still work. If either emacs or xemacs complains that it can't find gforth.el, you can find that file in the gforth package or site (or perhaps you can comment out the line (require 'forth-mode "gforth") in inf-snd.el). Finally, if temporary-file-directory is undefined, you can set it alongside the rest of the variables. So, for example, I (Bill S) have the following in my ~/.xemacs/init.el:

(setq load-path
      (append (list nil 
		    "/home/bil/cl"
		    "/home/bil/test/gforth-0.6.2" ; gforth.el
		    )
	      load-path))

(autoload 'run-snd-ruby     "inf-snd" "Start inferior Snd-Ruby process" t)
(autoload 'run-snd-scheme   "inf-snd" "Start inferior Snd-Scheme process" t)
(autoload 'run-snd-forth    "inf-snd" "Start inferior Snd-Forth process" t)
(autoload 'snd-ruby-mode    "inf-snd" "Load snd-ruby-mode." t)
(autoload 'snd-scheme-mode  "inf-snd" "Load snd-scheme-mode." t)
(autoload 'snd-forth-mode   "inf-snd" "Load snd-forth-mode." t)

(setq inf-snd-ruby-program-name "~/ruby-snd/snd") ; these are my local Snd's
(setq inf-snd-scheme-program-name "~/cl/snd")
(setq inf-snd-forth-program-name "~/forth-snd/snd")
(setq inf-snd-working-directory "~/cl/")
(setq inf-snd-index-path "~/cl/")
(setq inf-snd-working-directory   "~/cl/")
(setq inf-snd-index-path          "~/cl/")
(setq temporary-file-directory    "~/zap/")

If emacs complains about ruby-mode or something similar, you probably need to get ruby-mode.el and inf-ruby.el from ftp://ftp.ruby-lang.org/pub/ruby/ruby-*.tar.gz, or gforth.el from ftp://ftp.gnu.org/pub/gnu/gforth/gforth-0.[67].*.tar.gz.

jcrev

jc-reverb is a reverberator developed by John Chowning a long time ago (I can't actually remember when — before 1976 probably), based on ideas of Manfred Schroeder. It "colors" the sound much more than nrev, and has noticeable echoes, but I liked the effect a lot. new-effects.scm has a version of jc-reverb that runs as a normal snd editing function (via map-channel), whereas the jcrev.scm version assumes it is being called within with-sound:

Scheme:
    (with-sound (:reverb jc-reverb) (fm-violin 0 .1 440 .1 :reverb-amount .1))

Ruby:
    with_sound(:reverb, :jc_reverb) do fm_violin_rb(0, 0.1, 440, 0.1) end

Forth:
    0 1 440 0.2 ' fm-violin :reverb ' jc-reverb with-sound

jc-reverb has three parameters:

jc-reverb low-pass (volume 1.0) amp-env

if 'low-pass' if #t, a low pass filter is inserted before the output; 'volume' can be used to boost the output; 'amp-env' is an amplitude envelope that can be used to squelch the reverb ringing at the end of a piece.

(with-sound (:reverb jc-reverb :reverb-data '(#t 1.5 (0 0 1 1 2 1 3 0))) (fm-violin 0 .1 440 .1))
Reverbs in Snd
freeverb: freeverb.scm, freeverb.rb
jc-reverb: jcrev.scm
jl-reverb: clm-ins.scm
nrev: clm-ins.scm
control panel reverb: Reverb, control variables
convolution reverb: conrev
*reverb*: with-sound
lint

lint.scm is a lint program for Scheme. It tries to find errors or infelicities in your code. To try it:

(lint "some-code.scm")

lint tries to reduce false positives, so its default is somewhat laconic. There are several variables at the start of lint.scm to control additional output:

*report-unused-parameters*           ; if #t, report unused function/macro parameters
*report-unused-top-level-functions*  ; if #t, report unused functions
*report-undefined-variables*         ; if #t, report undefined identifiers
*report-shadowed-variables*          ; if #t, report function parameters that are shadowed
*report-minor-stuff*                 ; if #t, report all sorts of other stuff

lint is not real smart about functions defined outside the current file, so *report-undefined-variables* sometimes is confused. *report-minor-stuff* adds output about overly complicated boolean and numerical expressions, dangerous floating point operations, bad docstrings (this check is easily confused), and whatever else it finds that it thinks is odd.

maraca

The maracas are physical models developed by Perry Cook (CMJ, vol 21 no 3 Fall 97, p 44).

maraca beg dur 
       (amp .1) 
       (sound-decay 0.95) 
       (system-decay 0.999) 
       (probability .0625)
       (shell-freq 3200.0)
       (shell-reso 0.96)

maraca: (with-sound () (maraca 0 5 .5))
cabasa: (with-sound () (maraca 0 5 .5 0.95 0.997 0.5 3000.0 0.7))

big-maraca beg dur 
           (amp .1) 
           (sound-decay 0.95) 
           (system-decay 0.999) 
           (probability .0625)
           (shell-freqs '(3200.0))
           (shell-resos '(0.96))
           (randiff .01)
           (with-filters #t)

tambourine: 
    (with-sound () 
      (big-maraca 0 1 .25 0.95 0.9985 .03125 '(2300 5600 8100) '(0.96 0.995 0.995) .01))

sleighbells: 
    (with-sound () 
      (big-maraca 0 2 .15 0.97 0.9994 0.03125 '(2500 5300 6500 8300 9800) 
        '(0.999 0.999 0.999 0.999 0.999)))

sekere: 
    (with-sound ()
      (big-maraca 0 2 .5 0.96 0.999 .0625 '(5500) '(0.6)))

windchimes: 
    (with-sound () 
      (big-maraca 0 4 .5 0.99995 0.95 .001 '(2200 2800 3400) '(0.995 0.995 0.995) .01 #f))

big-maraca is like maraca, but takes a list of resonances and includes low-pass filter (or no filter).

see also:   noise   rand
marks

marks.scm/rb is a collection of mark-related functions.

define-selection-via-marks m1 m2

define-selection-via-marks selects the portion between the given marks, then returns the selection length. The marks defining the selection bounds must be in the same channel.

describe-mark mark

describe-mark returns a description of the movements of the mark over the channel's edit history:

> (define m (add-mark 1234))
m
> (describe-mark m)
((#<mark 1> sound: 0 "oboe.snd" channel: 0) 1234 478)

Here I placed a mark in oboe.snd at sample 1234, then deleted a few samples before it, causing it to move to sample 478.

fit-selection-between-marks m1 m2

fit-selection-between-marks tries to squeeze the current selection between two marks, using the granulate generator to fix up the selection duration (it currently does a less than perfect job).

mark-click-info mark

mark-click-info is a mark-click-hook function that describes a mark and its properties. It is used by with-marked-sound in ws.scm.

mark-explode (htype mus-next) (dformat mus-bfloat)

mark-explode splits a sound into a bunch of separate files based on mark placements. Each mark becomes the first sample of a separate sound.

mark-name->id name

mark-name->id is like find-mark, but searches all currently accessible channels. If a such a mark doesn't exist, it returns 'no-such-mark.

move-syncd-marks sync samples-to-move

move-syncd-marks moves any marks sharing the mark-sync value 'sync' by 'samples-to-move' samples.

pad-marks marks secs

pad-marks inserts 'secs' seconds of silence before each in a list of marks.

play-between-marks snd m1 m2

play-between-marks plays the portion in the sound 'snd' between the given marks.

play-syncd-marks sync

play-syncd-marks starts playing from all the marks sharing its 'sync' argument (see mark-sync).

report-mark-names 

report-mark-names causes a named mark to display its name in the status area when its sample happens to be played.

save-mark-properties 

save-mark-properties sets up an after-save-state-hook function to save any mark-properties.

snap-mark-to-beat 

snap-mark-to-beat forces a dragged mark to end up on a beat.

snap-marks 

snap-marks places marks at the start and end of the current selection in all its portions (i.e. in every channel that has selected data). It returns a list of all the marks it has added.

> (selection-position)
360
> (selection-framples)
259
> (snap-marks)
(#<mark 0> #<mark 1>)
> (mark-sample (integer->mark 0))
360
> (mark-sample (integer->mark 1))
619
syncup marks

syncup synchronizes a list of marks (positions them all at the same sample number) by inserting silences as needed.

marks.scm also has code that tries to make it simpler to sync marks together — you just click the marks that should share a mark-sync field, rather than laboriously setting each one in the listener; see start-sync and stop-sync. There is also some code (look for "eval-header" toward the end of the file) that saves mark info in a sound file header, and reads it when the file is subsequently reopened.

see also:   add-mark-pane   Marks   mark-loops   marks-menu
maxf

These files are translations (thanks to Michael Scholz!) of CLM's maxf.ins (thanks to Juan Reyes!). They implement a variant of the CLM formant generator developed by Max Mathews and Julius Smith (see their online paper). For a version of the filter closer to the paper, see the firmant generator. maxf.scm and maxf.rb provide a kind of demo instrument showing various ways to use the filter (banks tuned to different sets of frequencies, etc).

maxfilter file beg (att 1.0) (numf 1) (freqfactor 1.0) (amplitude 1.0)
		    (amp-env '(0 1 100 1)) (degree (random 90.0)) (distance 1.0) (reverb-amount 0.2)
(with-sound () (maxfilter "dog.snd" 0))
(with-sound (:srate 44100) (maxfilter "dog.snd" 0 :numf 12))
(with-sound (:srate 44100) (maxfilter "dog.snd" 0 :numf 13 :att 0.75))
(with-sound (:srate 44100) (maxfilter "dog.snd" 0 :numf 2 :att 0.25 :freqfactor 0.5))

The files described in this section either add new top-level menus to Snd, or modify existing ones. Most were written by Dave Phillips.

edit-menu.scm

edit-menu.scm adds some useful options to the Edit menu:

Selection->new      ; save selection in a new file, open that file
Cut selection->new  ; save selection in a new file, delete selection, open the file
Append selection    ; append selection to end of selected sound
Make stereofile     ; make a new 2-chan file, copy currently selected sound to it
Trim front          ; find first mark in each sync'd channel and remove all samples before it
Trim back           ; find last mark in each sync'd channel and remove all samples after it
Crop                ; find first and last mark in each sync'd channel and remove all samples outside them
fft-menu.scm

fft-menu.scm adds an "FFT Edits" top-level menu. It has entries for:

FFT notch filter   ; use FFT to notch out a portion of the spectrum
FFT squelch        ; use FFT to squelch low-level noise
Squelch vowels     ; use FFT to squelch vowel-like portions of speech
marks-menu.scm

marks-menu.scm adds a "Marks" top-level menu with entries:

Play between marks         ; play samples between marks
Loop play between marks    ; continuous play looping between marks
Trim before mark           ; remove samples before mark
Trim behind mark           ; remove samples after mark
Crop around marks          ; remove samples outside marks
Fit selection to marks     ; squeeze selection to fit between marks
Define selection by marks  ; define selection based on marks
Mark sync                  ; if on, click mark to sync with other marks
Mark sample loop points    ; place marks at header loop points, if any
Show loop editor           ; edit loop points; this dialog is not really functional yet
Delete all marks           ; delete all marks
Explode marks to files     ; writes a separate file for each set of marks
new-effects.scm, effects-utils.scm, gtk-effects.scm, gtk-effects-utils.scm, effects.rb, effects.fs

new-effects.scm (effects.rb, effects.fs) implements an Effects menu. Use gtk-effects.scm with Gtk. There are a ton of choices, most of them presented in separate dialogs. The gain dialog is illustrated below. Some of the outer menu items are:

Amplitude effects (gain, normalize)
Delay effects (various echos)
Filter effects (various filters)
Frequency effects (src, expsrc)
Modulation effects (AM)
Reverbs (nrev, jcrev, convolution)
Various (flange, locsig, etc)
Octave down
Remove clicks
Remove DC
Compand
Reverse
gain effect dialog

Most of these are either simple calls on Snd functions ("invert" is (scale-by -1)), or use functions in the other scm files. The actual operations follow the sync chain of the currently active channel.

special-menu.scm

special-menu.scm adds a "Special" menu with entries:

Append file
MIDI to WAV (using Timidity)
Record input channel 
Envelope new file (see start-enveloping)
Play panned 
Save as MP3 (using bladeenc)
Save as Ogg (using oggenc)
Explode SF2 (using the code explode-sf2 in examp.scm) 

Associated with these menus is a group of files that change Snd's overall appearance, add a box of handy icons, and so on: misc.scm, and new-backgrounds.scm. new-backgrounds.scm defines some background pictures that can be applied to all the Snd widgets: wood, granite, rough, blueish, and smoke. I think "rough" is the default used by misc.scm.

misc.scm loads these menus and interface improvements, adds several sound file extensions, makes sure all the widget backgrounds reflect the current background choice (metal, granite, wood, etc), adds some hook functions for mpeg files etc, and includes a number of options such as show-disk-space. It then adds these menu items:

File:Delete                 ; delete the selected file
File:Rename                 ; rename the selected file
Edit:Append selection       ; append selection to end of current sound
Edit:Replace with selection ; put copy of selection at cursor

I think Dave expects you to customize this to suit yourself, perhaps even moving the stuff you want to your initialization file.

see also:   add-to-main-menu.
mix

mix.scm provides various mix utilities.

check-mix-tags snd chn
check-mix-tags looks at the current mix tags in the given channel, and if any are found that appear to be overlapping, it moves one of them down a ways.
color-mixes mix-list new-color
color-mixes sets the color of each mix in 'mix-list' to 'new-color'.
delay-channel-mixes beg dur snd chn
delay-channel-mixes adds dur (which can be negative) to the begin time of each mix that starts after beg in the given channel.
env-mixes mix-list envelope
env-mixes applies 'envelope' as an overall amplitude envelope to the mixes in 'mix-list'.
find-mix sample snd chn
find-mix returns the identifier of the mix at sample 'sample' (or anywhere in the given channel if 'sample' is not specified), or #f if no mix is found.
mix-click-info mix
mix-click-info is a mix-click-hook function that posts a description of the clicked mix in the help dialog.
mix-click-sets-amp 
mix-click-sets-amp adds a mix-click-hook function so that if you click a mix, it is removed (its amplitude is set to 0.0); a subsequent click resets it to its previous value. This is intended to make it easy to compare renditions with and without a given mix.
mix-maxamp mix
mix-maxamp returns the maxamp in the given mix.
mix-name->id name
mix-name->id returns the mix with the given name, or 'no-such-mix if none can be found.
mix-sound file start
mix-sound mixes 'file' (all chans) into the currently selected sound at 'start'.
mix->float-vector mix
mix->float-vector returns a mix's samples in a float-vector.
mixes-length mix-list
mixes-length returns the number of samples between the start of the first mix in 'mix-list' and the last end point.
mixes-maxamp mix-list
mixes-maxamp returns the maxamp of the mixes in 'mix-list'.
move-mixes mix-list samps
move-mixes moves each mix in 'mix-list' by 'samps' samples. To move all sync'd mixes together whenever one of them is dragged:
(hook-push mix-release-hook
	   (lambda (hook)
	     (let* ((id (hook 'id))
	            (samps-moved (hook 'samples))
                    (result (= (mix-sync id) 0)))
	       (if (not result)
		   (move-mixes (syncd-mixes (mix-sync id)) samps-moved))
	       (set! (hook 'result) result))))

See also snap-syncd-mixes-to-beat.

pan-mix file beg env snd auto-delete

pan-mix mixes 'file' into the current sound starting at 'beg' using the envelope 'env' to pan the mixed samples (0: all chan 1, 1: all chan 0). So,

(pan-mix "oboe.snd" 1000 '(0 0 1 1))

goes from all chan 0 to all chan 1. 'auto-delete' determines whether the in-coming file should be treated as a temporary file and deleted when the mix is no longer accessible.

pan-mix-region region beg env snd
pan-mix-region is similar to pan-mix above, but mixes a region, rather than a file.
pan-mix-selection beg env snd
pan-mix-selection is similar to pan-mix above, but mixes the current selection, rather than a file.
pan-mix-float-vector data beg env snd
pan-mix-float-vector is similar to pan-mix above, but mixes a float-vector, rather than a file. The argument 'data' represents one channel of sound. To sync all the panned mixes together:
(let ((new-sync (+ 1 (mix-sync-max))))
  (for-each
    (lambda (id)
     (set! (mix-sync id) new-sync))
   (pan-mix-float-vector (make-float-vector 10 0.5) 100 '(0 0 1 1))))
play-mixes mix-list
play-mixes plays the mixes in 'mix-list'.
scale-mixes mix-list scl
scale-mixes scales the amplitude of each mix in 'mix-list' by 'scl'.
scale-tempo mix-list scl
scale-tempo changes the positions of the mixes in 'mix-list' to reflect a tempo change of 'scl'. (scale-tempo (mixes 0 0) 2.0) makes the mixes in snd 0, chan 0 happen twice as slowly. To reverse the order of the mixes: (scale-tempo (mixes 0 0) -1).
set-mixes-tag-y mix-list new-y
set-mixes-tag-y sets the tag y location of each mix in 'mix-list' to 'new-y'.
silence-all-mixes 
This sets all mix amplitudes to 0.0.
silence-mixes mix-list
silence-mixes sets the amplitude of each mix in 'mix-list' to 0.0.
snap-mix-to-beat 
snap-mix-to-beat forces a dragged mix to end up on a beat (see x-axis-in-beats). To turn this off, (hook-remove mix-release-hook snap-mix-1). To snap the dragged mix, and every other mix syncd to it, use snap-syncd-mixes-to-beat.
src-mixes mix-list scl
src-mixes scales the speed (resampling ratio) of each mix in 'mix-list' by 'scl'.
sync-all-mixes (new-sync 1)
sync-all-mixes sets the mix-sync field of every active mix to 'new-sync'.
syncd-mixes sync
syncd-mixes returns a list (possibly null) of all mixes whose mix-sync field is set to 'sync'. Most of the functions in mix.scm take a 'mix-list'; to form that list based on a given mix-sync value, use syncd-mixes:
	
(scale-mixes (syncd-mixes 2) 2.0)
which scales the amplitude by 2.0 of any mix whose mix-sync field is 2.
transpose-mixes mix-list semitones
transpose-mixes sets the speed of mix in 'mix-list' to cause a transposition by the given number of semitones.
moog
make-moog-filter frequency Q
moog-filter gen input

moog is a translation of CLM's moog.lisp (written by Fernando Lopez-Lezcano — http://ccrma.stanford.edu/~nando/clm/moog), itself a translation of Tim Stilson's original C code. The functions provide a kind of CLM generator view of the filter. Fernando describes it as a "Moog style four pole lowpass (24db/Oct) filter clm unit generator, variable resonance, warm, analog sound ;-)". In make-moog-filter, 'frequency' is the cutoff frequency in Hz (more or less) and 'Q' controls the resonance: 0.0 = no resonance, whereas 1.0 causes the filter to oscillate at 'frequency'.

(define (moog freq Q)
  (let ((gen (make-moog-filter freq Q)))
    (lambda (inval)
      (moog-filter gen inval))))

(map-channel (moog 1200.0 .7))

The Ruby version of this is in examp.rb, and the Forth version is in examp.fs.

musglyphs

musglyphs.scm provides Scheme/Snd wrappers to load CMN's cmn-glyphs.lisp (directly!), thereby defining most of the standard music notation symbols. Each of the original functions (e.g. draw-bass-clef) becomes a Snd/Scheme procedure of the form (name x y size style snd chn context). (draw-bass-clef 100 100 50) draws a bass clef in the current graph at position (100 100) of size 50; since the 'style' argument defaults to #f, the clef is displayed as a filled polygon; use #t to get an outline of the clef instead.

Snd with music symbols

This was created with:

(with-sound () (fm-violin 0 1 440 .1))

(define (draw-staff x0 y0 width line-sep)
  (let ((cr (make-cairo (car (channel-widgets 0 0)))))
    (do ((line 0 (+ 1 line))
         (x x0) 
         (y y0 (+ y line-sep)))
        ((= line 5))
      (draw-line x y (+ x width) y 0 0 time-graph cr))
    (free-cairo cr)))

(define (draw-a-440 x0 y0 size)
  (let ((width (* size 100))
        (line-sep (* size 20))
        (qsize (* size 80)))
    (draw-staff (+ x0 (* size 5)) y0 width line-sep)	
    (draw-treble-clef x0 (+ y0 (* size 61)) qsize)
    (draw-quarter-note (+ x0 (* 70 size)) (+ y0 (* size 52)) qsize)
    (let ((cr (make-cairo (car (channel-widgets 0 0)))))
      (fill-rectangle (+ x0 (* 90 size)) (- y0 (* size 10)) (* size 3) (* size 60) 0 0 time-graph #f cr)
      (free-cairo cr))))

(draw-a-440 50 80 1.0)

A fancier example is included in musglyphs.scm. It takes a list of notes, each mixed as a virtual mix, and displays the note pitches as music notation on two staves at the top of the graph. The two main drawing functions are draw-staff and draw-a-note. The staves are drawn via an after-graph-hook function, and the notes are displayed via draw-mix-hook. mix-waveform-height sets the overall size of the music notation. The note list data is passed into these functions by setting various mix-properties: 'frequency and 'instrument (the first to give the pitch, the second the staff).

There's also an even fancier version of the same thing that treats the note heads as the mix tags, and changes the mix pitch if you drag the note up or down.

nb

nb.scm provides popup help for files in the View:Files dialog. As you move the mouse through the file list, the help dialog posts information about the file underneath the mouse. This uses a slightly fancier file information procedure than finfo in examp.scm.

nb file note
unb file
prune-db 

nb adds 'note' to the info associated with a file: (nb "test.snd" "test's info"). unb erases any info pertaining to a file: (unb "test.snd"). prune-db removes any info associated with defunct files. The Ruby version of nb (written by Mike Scholz) has several other features — see nb.rb for details.

noise

The noise files are translations (thanks to Michael Scholz) of CLM's noise.ins. noise.ins has a very long pedigree; I think it dates back to about 1978. It can produce those all-important whooshing sounds.

fm-noise startime dur freq0 amp ampfun ampat ampdc
   freq1 glissfun freqat freqdc rfreq0 rfreq1 rfreqfun rfreqat rfreqdc
   dev0 dev1 devfun devat devdc
   (degree 0.0) (distance 1.0) (reverb-amount 0.005)

This is an old instrument, so one must make allowances. 'ampat' and 'ampdc' are the amplitude envelope ('ampfun') attack and decay times, and similarly for the frequency envelope 'glissfun', the random number frequency envelope 'rfreqfun' and the index envelope 'devfun' (dev = "deviation", and old radio-style name for the FM index). Each envelope must go on the x axis from 0 to 100; the attack portion ends at 25, the decay portion starts at 75 (once upon a time there was a generator named LINEN; his full name was Line-Segment Envelope, but everyone just called him LINEN; they had to shout because he was a bit deaf). 'rfreq' is the frequency of the random number generator; if it is below about 25 Hz, you get automatic composition; above that you start to get noise. Well, you get a different kind of noise. 'dev' is the bandwidth of the noise; very narrow 'dev' gives a whistle, very broad more of a whoosh. This is simple FM where the modulating signal is white noise.

(with-sound ()
  (fm-noise 0 2.0 500 0.25 '(0 0 25 1 75 1 100 0) 0.1 0.1 1000 '(0 0 100 1) 0.1 0.1
            10 1000 '(0 0 100 1) 0 0 100 500 '(0 0 100 1) 0 0))

There is also a generator-like version of the instrument:

make-fm-noise len freq (amp 0.25) (ampfun '(0 0 25 1 75 1 100 0)) (ampat 0.1)
              (ampdc 0.1) (freq1 1000) (glissfun '(0 0 100 1)) (freqat 0.1) (freqdc 0.1)
              (rfreq0 10) (rfreq1 1000) (rfreqfun '(0 0 100 1)) (rfreqat 0) (rfreqdc 0)
              (dev0 100) (dev1 500) (devfun '(0 0 100 1)) (devat 0) (devdc 0) 
              (degree (random 90.0)) (distance 1.0) (reverb-amount 0.005)
see also:   maraca   rand
numerics

This file has a variety of functions oriented toward some experiments that so far haven't panned out.

factorial n
binomial n k
n-choose-k n k
plgndr l m x
legendre-polynomial a x
legendre n x
gegenbauer n x (alpha 0.0)
chebyshev-polynomial a x (kind 1)
chebyshev n x (kind 1)
hermite-polynomial a x
hermite n x
laguerre-polynomial a x (alpha 0.0)
laguerre n x (alpha 0.0)
Si x
Ci x
sin-m*pi/n m n
show-digits-of-pi-starting-at-digit start

In this case, "the code is the documentation" — these functions are informal, experimental, etc. One amusing function is sin-m*pi/n. It returns an expression giving the exact value of sin(m*pi/n), m and n integer, if we can handle n. Currently n can be anything of the form 2^a 3^b 5^c 7^d 11^e 13^f 17^g 257^h, so (sin-m*pi/n 1 60) returns an exact expression for sin(pi/60). The expression is not reduced much.

> (sin-m*pi/n 1 9)
(/ (- (expt (+ (sqrt 1/4) (* 0+1i (sqrt 3/4))) 1/3) (expt (- (sqrt 1/4) (* 0+1i (sqrt 3/4))) 1/3)) 0+2i)
> (eval (sin-m*pi/n 1 9))
0.34202014332567
> (sin (/ pi 9))
0.34202014332567
> (sin (/ pi (* 257 17)))
0.00071906440440859
> (eval (sin-m*pi/n 1 (* 17 257)))
0.00071906440440875

Another amusing function is show-digits-of-pi-starting-at-digit, translated from a C program written by David Bailey. It shows 10 (hex) digits of the expansion of pi starting from any point in that expansion.

peak-phases

peak-phases.scm contains the phases that produce a minimum peak amplitude ("low peak-factor") sum of sinusoids, the unpulse-train, so to speak. I started with the questions: given a sum of n equal amplitude harmonically related sinusoids, what set of initial phases minimizes the peak amplitude? What is that peak as a function of n? Can we find any pattern to the initial phases so that a tiresome search is unnecessary? For the second question, there are several simple cases. If all harmonics are cosines, the peak amplitude is n (they all are 1 at the start). If we have 2 harmonics, and vary the initial phase of the second from 0.0 to 2*pi, graphing the resulting peak amplitude, we get:

n=2 case n=2 case

The graph on the left is the second harmonic's initial phase vs the peak amplitude. Since 0.0 appears to be a minimum (we can show that it is via simultaneous non-linear equations; see peak-phases.scm), we can solve for the peak at that point using calculus: differentiate sin(x) + sin(2x) to get cos(x) + 2cos(2x) = 4cos^2(x) + cos(x) -2, a quadratic equation in cos(x). Let y=cos(x), solve for y: (sqrt(33)-1)/8. Plug that back into the original equation (x=acos(y) = 0.93592945566133), and get 1.7601725930461. Looking back at the peak-amplitude graph, it appears that the peak varies as approximately 1.76+0.24*abs(sin(initial-phase)). If we graph the peak location, we see that it is moving (nearly) linearly with the initial-phase from the 0.9359 business given above to the corresponding peak location when the initial-phase is pi (acos((1-sqrt(33))/8) = 2.20566), then the two peaks cross, and the other one predominates from pi to 2*pi. So the peak amplitude as a function of the initial-phase ("phi" below) is (very nearly):

  (let* ((a (acos (/ (- (sqrt 33) 1) 8)))
	 (b (acos (/ (- 1 (sqrt 33)) 8)))
	 (ap (- (* 2 pi) a))                          ; start location of peak 1 (the peak when phi is 0..pi)
	 (bp (- (* 2 pi) b))                          ; end location of peak 1 
	 (ax (+ b (* (- phi pi) (/ (- a b) pi))))     ; same for peak 2 (the peak when phi is pi..2pi)
	 (bx (+ ap (* phi (/ (- bp ap) pi)))))        ; the 2 peaks move in opposite directions
    (max (abs (+ (sin ax) (sin (+ (* 2 ax) phi))))    ; plug in the 2 locations and
	 (abs (+ (sin bx) (sin (+ (* 2 bx) phi))))))  ;   return the max 

We can reduce the peak difference below .00000002 by using:

  (let* ((waver (+ (* .002565 (sin (* 2 phi)))
                   (* .0003645 (sin (* 4 phi)))
                   (* .0001 (sin (* 6 phi)))
                   (* .00004 (sin (* 8 phi)))
                   (* .00002 (sin (* 10 phi)))
                   (* .00001 (sin (* 12 phi)))
                   (* .0000035 (sin (* 14 phi)))))
         (ax (- (+ b (* (- phi pi) (/ (- a b) pi))) waver))
         (bx (- (+ ap (* phi (/ (- bp ap) pi))) waver)))
    ...)

Similarly sin(x)+sin(3x) differentiated is cos(x)+3cos(3x) = 12cos^3(x)-8cos(x). cos(x)=0 is a minimum of the original, but the other case is acos(sqrt(2/3)) = 0.61547970867039, and plugging that into the original gives 1.539600717839. If we vary the sin(3x) term's initial phase, we get approximately 1.5396 + 0.4604 * sin(initial-phase). As before, the location of the peak varies nearly linearly with the initial-phase, the end point now being acos(-(sqrt(2/3))):

  (let* ((a (acos (sqrt 2/3)))
	 (b (acos (- (sqrt 2/3))))
	 (ap (- (* 2 pi) a))                              ; start loc peak 1
	 (bp (- (* 2 pi) b))                              ; end loc
	 (ax (+ ap (* phi (/ (- bp ap) (* 2 pi)))))       ; peak 1 
	 (bx (- ax pi)))                                  ; peak 2 (the two interleave)
    (max (abs (+ (sin ax) (sin (+ (* 3 ax) phi))))        ; plug in our 2 peak locations
	 (abs (+ (sin bx) (sin (+ (* 3 bx) phi))))))      ;   and return the max

sin(x)+sin(5x+a) becomes a quadratic in cos^2(x), so we can find the peak location as a function of the initial-phase:

  (let* ((a0 (* pi 1/2))
	 (a1 (acos (sqrt (/ (- 25 (sqrt 145)) 40))))
	 (ax (+ a0 (/ (* (- a1 a0) phi) pi)))
	 (bx (+ pi ax))
	 (cx (- a0 (/ (* (- a1 a0) (- (* 2 pi) phi)) pi)))
	 (dx (+ cx pi)))
   (max (abs (+ (sin ax) (sin (+ (* 5 ax) phi))))
	(abs (+ (sin bx) (sin (+ (* 5 bx) phi))))
	(abs (+ (sin cx) (sin (+ (* 5 cx) phi))))
	(abs (+ (sin dx) (sin (+ (* 5 dx) phi))))))

but now we have four peaks to track. The minimum peak is at initial-phase of pi, and is 1.81571610422. sin(x)+sin(4x+a) is much messier to handle in this manner when a=0 because it ends up in a quartic equation in cos(x). A glance at the derivative, cos(x)+4*cos(4x+a), shows there is a 0 at (x=0, a=acos(-1/4)), (x=pi, a=acos(1/4)), (x=pi/2, a=pi/2) and so on, but these points do not seem to be at maxima of the original. A brute force search finds that the minimum peak (which is at initial-phase of 0) is at 1.940859829001 and is 1.9282082241513. We could also use poly-roots in poly.scm:

  > (map (lambda (y) 
          (+ (sin y) (sin (* 4 y)))) 
        (map acos (poly-roots (float-vector 4 1 -32 0 32)))) ; 4 + cos(x) - 32cos^2(x) + 32cos^4(x)
  (... 1.928208224151313892413267491649096952858E0 ...)

I think in the sin(x)+sin(nx+a) case there's a minimum at a=pi, except when n=4k+3, and the peak itself (at either pi/2 or 3pi/2) approaches 2 as n increases. sin-nx-peak in numerics.scm searches for this peak, and for reasonable "n" it can be compared to the equivalent search using poly-roots in poly.scm:

  > (sin-nx-peak 6)
  (1.966832009581999989057660894590273760791E0 ...)
  (map (lambda (y) 
         (+ (sin y) (sin (* 6 y)))) 
       (map acos (poly-roots (float-vector -6 1 108 0 -288 0 192)))) ; n*Tn + cos(x)
  (1.966832009581999989057661205729776550611E0 ...)

Another case that is not too hard involves a sum of n sines all at 0 initial phase. This can be expressed as:

sum of sines

which is the nsin generator in clm. Since the waveform is a two-sided pulse with the first local maximum at the peak, we can easily search for that peak as n increases. We find that it is approaching (3*pi)/(4*n), and if we plug that into the original equation, we get that the peak amplitude approaches 8*n*(sin^2(3*pi/8))/(3*pi), about 0.7245 * n (using the right hand expression above, set x to (3*pi)/(4*n), let n be large, so (n+1)/n approaches 1 and sin(y) is close to y if it is very small). A sum of n odd harmonics behaves similarly (the peak comes half as far from the zero crossing, but has the same max). A sum of n sines of alternating sign also has the same peak amp, but now the peak is at pi-(3*pi)/(4*n). Those are the easy cases. The next case involves 3 harmonics, where we vary the second and third harmonic's initial phase, looking for the minimum peak amplitude. One view of this terrain has the second harmonic's initial phase on the Y axis, the third's on the X axis, and the color for the height of the corresponding peak:

3 harmonics in 3D
3 harmonics
4 harmonics in 3D
4 harmonics

I tilted the graph slightly to try to show how the colors match the peaks. If we set the second component's phase to (a+pi)/2 where "a" is the third one's initial phase, we travel along the minimum going diagonally through the middle of the graph (I think the graph got truncated slightly: the top should match the bottom). The graph on the right is an attempt to show the 4-dimensional 4-harmonic case by stacking 3-D slices. I forgot to "invert" the colors, so red in the n=4 case matches a minimum (blue in the n=3 case); I should redo these graphs! A different way to view these graphs that can be applied to any number of dimensions (until we run out of disk space and patience), is to move through the possibilities in much the way you'd count to 100; before each 10's digit increments, you'd count diligently through all the 1's. Similarly, in the next set of graphs, we go from 0 to 2pi completely on one component before incrementing the next lower component. So, we get the second component moving slowly from 0 to 2pi, and, in the n=3 case, at each step it takes, it waits until the third component has gone from 0 to 2pi. This way we get all possible initial phases graphed in a normal 2D picture. Here is the n=3 case. The top level looks a bit like the n=2 case, but zooming in shows more complexity (each graph on the right is the selected portion of the one on its left). (The complexity in this case is mostly due to the slice-at-a-time approach).

n=3 case

We're trying to pinpoint the minima (there appear to be 4 black areas in the 3D graph, corresponding (I hope!) to the four minima in the second graph). A multiprecision search finds these values:

 1.9798054823226 #(0.0 0.58972511242747172044431636095396243035  0.3166675693251937984129540382127743214) 
 1.9798054823226 #(0.0 1.58972511242745917492413809668505564332  0.3166675693251493894919690319511573761)
 1.9798054823222 #(0.0 0.41027488757208596670267297668033279478  1.68333243067326587816268101960304193198)  
 1.9798054823222 #(0.0 1.41027488757208596670267297668033279478  1.68333243067326587816268101960304193198)

which shows that the minima are essentially at (23/39 19/60), (16/39 101/60), (1 + 23/39, 19/60), and (1 + 16/39, 101/60), all numbers multiplied by pi of course. (Our labor was mostly wasted; once we find one such point, the symmetries of the sinusoids hand us the other three for free. See find-other-mins in peak-phases.scm).

Here is n=4 graphed in the same way:

n=4 case

One of those minima might be the one we found near 2.04. n=5:

n=5 case

Here is the corresponding 3-D graph of the 5 harmonic case. It is trying to show 8 4-D slices through the 5-D landscape, each 4-D case being 8 3-D slices as before (I forgot to invert the colors here also, so despite appearances, blue is a maximum, and we're looking for the reddest point, the global minimum):

all

n=6 is even more beautiful and complex, but the graph is too large to include here.

;;; use mix and with-temp-sound to create a draggable mix object for each component.

(load "peak-phases.scm")
(set! *with-mix-tags* #t)     ; drag the tag to change the harmonic's initial phase
(set! *show-mix-waveforms* #f)
(set! *with-inset-graph* #f)

(define (show choice n)                           ; (show :all 14) for example
  (definstrument (sine-wave start dur freq phase) ; make one harmonic
    (let* ((beg (seconds->samples start))
	   (end (+ beg (seconds->samples dur)))
	   (osc (make-oscil freq phase)))
     (do ((i beg (+ i 1))) 
	 ((= i end))
       (outa i (oscil osc)))))

  (if (null? (sounds))
      (new-sound))
  (let ((phases (cadr (get-best choice n))))
    (do ((i 0 (+ i 1)))
	((= i n))
      (let* ((freq (case choice
		     ((:all) (+ i 1))
		     ((:even) (max (* 2 i) 1))
		     ((:odd) (+ (* 2 i) 1))
		     ((:prime) (primes i))))
	     (snd (with-temp-sound (:ignore-output #t :clipped #f)
		   (sine-wave 0 2 (* 10 freq) (* pi (phases i))))))
	(let ((mx (car (mix snd 400)))) ; give some space after the axis
	  (set! (mix-tag-y mx) (+ 10 (* 40 i)))))))
  (let ((mx (+ 2.0 (maxamp))))
    (set! (y-bounds) (list (- mx) mx)))
  (set! (x-bounds) (list 0.0 0.2)))

(hook-push mix-drag-hook ; report the current maxamp as we drag a component
  (lambda (hook)
    (let ((beg 0)
	  (end (framples))
	  (mx 0.0))
      (for-each
       (lambda (sine)
	 (set! beg (max beg (mix-position sine)))
	 (set! end (min end (+ (mix-position sine) (mix-length sine)))))
       (caar (mixes)))
      (let ((rd (make-sampler beg)))
	(do ((i beg (+ i 1)))
	    ((> i end))
	  (set! mx (max mx (abs (rd))))))
      (status-report (format #f "maxamp: ~A" mx)))))

It's curious that the "min-peak-amplitude versus n" graphs look continuous; what happens to the minima as we slowly add the next higher harmonic? In the n=2 case, each minimum splits in two, then smoothly moves to its next minimum location (where the third harmonic has amplitude 1.0). Here's a graph of the moving minima, showing also the resultant peak amplitude:

moving minima moving minima

In the first graph, each dot is at the phase location of the minimum peak amplitude as the third harmonic is increased in amplitude by 0.025. The turning points are just before the third harmonic reaches an amplitude of 0.5. The n=2 minima are at (0, 0), (red and green, with the green x=2 rather than 0), and (0, 1), (black and blue). Each splits and wanders eventually to the n=3 global minima at (0.41 1.68), (1.41, 1.68), (1.59, 0.32), and (0.59, 0.32). Each of the n=2 global minima ends up at 2 of the 4 n=3 global minima! How lucky can we be? If this worked in general, we could use it to speed up our search by following a minimum of n harmonics as it meanders to a minimum of n+1 harmonics:

;; this starts at the current min and marches to an n+1 min
(let ((n 3))
  (let ((phases (vector 0.0 0.0 1.0)))
    (do ((x 0.1 (+ x .1)))
	((>= x 1.0))
      (let ((p (fpsap x 0 n 1000 0.1 50 #f #t phases))) ; args may change without warning.
	(format #t ";~A: ~A~%" x p)
	(do ((k 0 (+ k 1)))
	    ((= k n))
	  (set! (phases k) (modulo (p k) 2.0)))))))

Since we can restrict our search to 0.1 (maybe less) in each direction (rather than 2.0), we get a reduction of 20^n in the size of the space we are searching. But, as usual, there's a problem. The search works for n=2 -> 3 -> 4 -> 5, but going from 5 to 6, I seem to fall into a non-optimal path.

The other short-cut that immediately comes to mind is to look for the zeros of the derivative, then plug those into the original to get the maxima. But it is just as hard to find those zeros as to find the peaks of the original. Or we could minimize the length of the curve. In the 57 harmonics case, for example, the cosine version (peak=57.0) has a length of 485.45, whereas the minimized peak version (peak=7.547) has a length of 909.52. But this also doesn't save us any time over the original search.

So we're resigned to a laborious search. The first thing we need is a fast way to produce a sum of sinusoids. Up to n=25 or 30, the Chebyshev polynomials are just as fast as an inverse FFT, but why stop at 30! Since we'll be doing an inverse FFT for every test case, we need to make the FFT size as small as possible while still giving a reasonably accurate peak (say within 0.001 of the true peak). According to N Higham in "Accuracy and Stability of Numerical Algorithms", the FFT is stable and very accurate. He has a graph showing accumulated numerical errors down in the 10^-15 range! But that is not where the inverse FFT loses. We get n points back from an n-point FFT, so effectively we're sampling the resultant waveform at those n points. This subsampling can easily miss the peak. Here are the errors for inverse FFT's of various sizes for the 8 and 128 all harmonics case (all initial phases = 0.0, multiply "mult" by the number of harmonics to get the FFT size):

              8 harmonics                     128 harmonics    
                 
mult    reported peak    error           reported peak     error

2        5.02733      1.11686e0           81.48324      11.62779
4        5.57658      5.67621e-1          81.98630      11.12473
8        6.10774      3.64636e-2          93.08931      0.021721
16       6.10774      3.64636e-2          93.08931      0.021721
32       6.14247      1.72736e-3          93.08931      0.021721
64       6.14247      1.72736e-3          93.08931      0.021721
128      6.14391      2.87163e-4          93.10728      0.003753
256      6.14405      1.50636e-4          93.10980      0.001232
512      6.14420      5.36694e-6          93.11143      0.000391
1024     6.14420      5.36694e-6          93.11143      0.000391
2048     6.14420      1.59697e-6          93.11156      0.000525
4096     6.14420      1.44227e-7          93.11156      0.000525
8192     6.14420      3.60112e-8          93.11156      0.000526

128 seems pretty good. Those are spikey cases. If we try the best minimum-peak case, the errors are much smaller. Here are graphs of both the 0.0 phase and minimum phase cases for 8 harmonics:

8 case 8 case

Ok, we have a fast way to make test cases. Off we go... When I started this search more than two years ago, I had no idea what a long and winding path I was headed down! My initial guess was that I could find minimum peaks close to the square root of n. This was based on nothing more than the breezy idea that the initial phases give you enough freedom that you're approaching the behavior of a sum of n random signals. I thought these minima could not be very hard to find; simply use a brute force grid. The first such grid used initial phases of 0 and pi, and I actually ran every possible such case, up to n=45 or so. Since each harmonic can be positive or negative, this is 2^44 cases to check, which is starting to be a pain. The results were discouraging; I did not get close to the square root of n. I also tried smaller grids (down to pi/32) for small n (say n < 8), without any success.

Next great idea: try random initial phases. This actually works better than it has any right to, but again the results are disappointing. You can run random phases until hell freezes over and only get to n^.6 or slightly less. And the long term trend of this process can dampen one's optimism. Here's a graph where we've taken 100 stabs at each case of N harmonics, N from 3 to 2000, using randomly chosen initial phases, and tracked the minimum, maximum, and average peaks. The graph is logarithmic (that is we show (log minimum N) and so on):

average peaks from n=3 to 2000

The trend continues upwards as N goes to 100000; it probably approaches 1 in the limit. But we can always do better than n^.6 by using phases 0.0938*i*i - 0.35*i where "i" is the harmonic number counting from 0. This little formula gives results as low as n^.541 (at n=2076), and it is always below n^.6 if n is large enough. Lots of such formulas get us down to n^.53 or, as n gets larger, .52: in the all harmonic case, if n=65536, 4.5547029e-05*i*i + 0.640075398*i gives a peak of 309.9, and -4.697190e-05*i*i + 1.357080536*i peaks at 303.6 (n^.515). If n=131072, 2.09440276*i*i + 1.4462367*i peaks at 438.7 (n^.516).

A good quadratic for each n, in the all harmonics case, is (pi/n)*i*i - i*pi/2. Except for the pi/n term, the rest just marches through the quadrants in order, so this is the same as (pi*(((mod(i,4)/2)+(i*i/n)))). This is similar to the formula suggested by M. Schroeder, but the addition of the "mod(i,4)/2" term improves its performance. If N=100, for example, Schroeder's peak is 13.49, whereas the mod peak is 11.90. There are better choices of quadrant than mod(i,4); if N=14, the mod(i,4) formula gives a peak of 4.89 (Schroeder's formula's peak is 5.1), but an exhaustive search of all quadrant choices finds #(0 0 0 1 3 3 0 1 2 3 1 3 2 3) with a peak of 4.28. Since the search involves approximately 4^n FFTs, there's not much hope of going above N=20 or thereabouts. I can't see any pattern in the lists of ideal quadrants.

The corresponding even harmonics version is (-pi/n)*(i+1)*(i+1) - (i+1)*pi/2. These sorts of formulas do better as n increases, but I don't think they reach n^.5. If n=4000000, the peak is at 2408.9 (n^.512). A linear equation in "i" here is simply phase offset in the sum of sines formula mentioned earlier, so given an initial phase of x*i, as x goes from 0 to pi/2, the peak goes from .7245*n to n. Another good variant is (pi*i*i)/n using cos rather than sin.

I haven't found any functions that get all the way to the square root. In the next graph, the y axis is the peak value with n=100, the x axis is the number of tests, and we've sorted the tests by peak. Each test is centered around a known excellent minimum peak, and the separate curves are showing the peaks when the initial phases can vary around that best value by pi/4, then pi/8 etc. It's hard to read at first, but take the black top curve. This is what you'd get if you randomly sampled a hypercube whose side length is pi/2 centered on that minimum. Nearly all the values are between 18 (100^.63) and 23 (100^.68). Each successive curve divides the space we sample by 2 in all 100 dimensions, so by the time we get to the bottom curve, we've reduced our search space by a factor of 2^800 (we're down to .006 on a side), and we still don't see the actual minimum even once in 50000 tries! Imagine trying to set up a grid to catch this point.

histogram of 100 reduced 8 times

What to do? There are a bunch of papers on this subject, but the best I found was: Horner and Beauchamp, "a genetic algorithm-based method for synthesis of low peak amplitude signals", J. Acoustic. Soc. Am Vol 99 No 1 Jan 96, online at ems.music.uiuc.edu/beaucham/papers/JASA.01.96.pdf, They report good results using the genetic algorithm, so it tried it. I started with 2000 randomly chosen initial points and a search radius of 1.0 (= pi). These are pretty good choices, but after a few months of searching, I reached a point of almost no returns. I tried variants of the basic algorithm and other search methods, but the results were not very good until I noticed that in the graphs of the peaks, the good values are more or less clustered together. So I tried centering the genetic search on the best phases I had found to that point, then repeating the search each time from the new best point, slowly reducing the search radius ("simulated annealing" is the jargon for this).

(define (iterated-peak choice n)
  (let ((phases (make-vector n 0.0))
	(cur-best n)
	(cur-incr 1.0))
    (do ((i 1 (+ i 1)))
	((= i n))
      (set! (phases i) (random 1.0)))
    (do ()
	((< cur-incr .001))
      (let ((vals (fpsap (if (eq? choice :all) 0 
                           (if (eq? choice :odd) 1 
                             (if (eq? choice :even) 2 3))) 
                         n phases 5000 cur-incr)))
	(let ((pk (car vals))
	      (new-phases (cadr vals)))
	  (let ((down (- cur-best pk)))
	    (if (< down (/ cur-best 10))
		(set! cur-incr (* 0.5 cur-incr))))
	  (if (< pk cur-best)
	      (begin
		(set! cur-best pk)
		(set! phases (float-vector->vector new-phases)))))))
    (list cur-best phases)))

The "fpsap" function is the genetic algorithm mentioned earlier, written in C. Here is the GA code used to find the initial-phase polynomials mentioned above:

(define (piterate choice n)   ; (piterate :all 4096)
  (let* ((size 1000)
	 (pop (make-vector size))
	 (phases (make-vector n 0.0)))
    ;; initialize our set of choices		   
    (do ((i 0 (+ i 1)))
	((= i size))
      (let ((f1 (random 1.0)) ; or (- 1.0 (random 2.0)) and also below
	    (f2 (random 1.0)))
	(do ((k 0 (+ k 1)))
	    ((= k n))
	  (set! (phases k) (modulo (/ (+ (* f2 k k) (* f1 k)) pi) 2.0)))
	(set! (pop i) (list (get-peak choice n phases) f1 f2))))
    ;; now do the GA search with annealing
    (do ((try 0 (+ try 1))
	 (increment .3 (* increment .98)))
	((= try 1000))
      (sort! pop (lambda (a b) (< (car a) (car b))))
      (format #t "~A ~D ~A ~A~%" choice n (pop 0) (log (car (pop 0)) n))
      (do ((i 0 (+ i 1))
	   (j (/ size 2) (+ j 1)))
	  ((= i (/ size 2)))
      (let ((f1 (+ (list-ref (pop i) 1) (random increment)))
	    (f2 (+ (list-ref (pop i) 2) (random increment))))
	(do ((k 0 (+ k 1)))
	    ((= k n))
	  (set! (phases k) (modulo (/ (+ (* f2 k k) (* f1 k)) pi) 2.0)))
	(set! (pop j) (list (get-peak choice n phases) f1 f2)))))))

Here are the results I have so far. In each set, the first number is the number of harmonics, then the minimum peak amplitude, then (log peak n).

=============================================================================================
        all                      odd                      even                    prime
=============================================================================================

20    4.288    0.4860  | 11    3.177   0.4820   | 115  11.164  0.5085   | 24    5.643   0.5445
14    3.612    0.4867  | 9     2.886   0.4824   | 113  11.086  0.5089   | 18    4.855   0.5467
23    4.604    0.4870  | 17    3.926   0.4827   | 126  11.729  0.5091   | 25    5.811   0.5467
11    3.218    0.4874  | 10    3.053   0.4848   | 114  11.157  0.5093   | 19    5.001   0.5467
17    3.980    0.4876  | 19    4.172   0.4851   | 127  11.792  0.5094   | 28    6.191   0.5471
16    3.874    0.4884  | 14    3.598   0.4852   | 117  11.317  0.5095   | 93    11.942  0.5472
24    4.728    0.4888  | 13    3.475   0.4856   | 124  11.657  0.5095   | 23    5.562   0.5473
19    4.218    0.4889  | 18    4.070   0.4856   | 99   10.395  0.5095   | 22    5.434   0.5476
22    4.540    0.4894  | 16    3.857   0.4869   | 120  11.467  0.5096   | 17    4.719   0.5476
21    4.443    0.4898  | 15    3.738   0.4869   | 121  11.520  0.5096   | 95    12.115  0.5478
15    3.768    0.4899  | 12    3.362   0.4879   | 128  11.857  0.5097   | 40    7.543   0.5478
25    4.853    0.4907  | 28    5.089   0.4883   | 256  16.896  0.5098   | 77    10.803  0.5479
13    3.524    0.4911  | 21    4.448   0.4902   | 96   10.249  0.5099   | 30    6.452   0.5481
12    3.389    0.4911  | 23    4.662   0.4909   | 125  11.726  0.5099   | 39    7.452   0.5482
18    4.140    0.4915  | 20    4.358   0.4914   | 102  10.574  0.5099   | 102   12.631  0.5484
10    3.102    0.4917  | 31    5.419   0.4921   | 104  10.682  0.5100   | 86    11.518  0.5487
29    5.241    0.4920  | 22    4.581   0.4924   | 123  11.636  0.5100   | 47    8.268   0.5487
27    5.064    0.4922  | 24    4.786   0.4927   | 111  11.044  0.5100   | 63    9.713   0.5487
28    5.157    0.4923  | 33    5.603   0.4929   | 100  10.472  0.5100   | 51    8.653   0.5488
37    5.918    0.4924  | 25    4.887   0.4929   | 88   9.812   0.5100   | 94    12.115  0.5490
35    5.762    0.4926  | 29    5.263   0.4932   | 116  11.309  0.5103   | 87    11.613  0.5491
26    4.982    0.4929  | 30    5.353   0.4933   | 122  11.609  0.5104   | 109   13.144  0.5491
33    5.608    0.4931  | 8     2.791   0.4935   | 109  10.962  0.5104   | 20    5.183   0.5492
32    5.526    0.4932  | 27    5.089   0.4937   | 94   10.168  0.5105   | 21    5.324   0.5492
30    5.361    0.4937  | 26    5.006   0.4944   | 103  10.655  0.5105   | 74    10.650  0.5496
31    5.453    0.4939  | 7     2.618   0.4946   | 105  10.762  0.5105   | 89    11.788  0.5496
36    5.872    0.4940  | 32    5.563   0.4952   | 83   9.549   0.5106   | 29    6.365   0.5496
9     2.962    0.4941  | 52    7.080   0.4954   | 93   10.121  0.5107   | 96    12.293  0.5497
8     2.795    0.4942  | 50    6.947   0.4955   | 119  11.483  0.5107   | 101   12.654  0.5499
34    5.715    0.4943  | 34    5.741   0.4956   | 112  11.133  0.5107   | 114   13.530  0.5500
70    8.177    0.4946  | 82    8.895   0.4960   | 108  10.929  0.5108   | 38    7.396   0.5501
39    6.124    0.4946  | 35    5.833   0.4960   | 1024 34.487  0.5108   | 57    9.246   0.5501
93    9.413    0.4947  | 48    6.828   0.4962   | 106  10.831  0.5109   | 59    9.424   0.5502
41    6.278    0.4947  | 41    6.322   0.4966   | 97   10.354  0.5109   | 33    6.846   0.5502
60    7.589    0.4950  | 43    6.474   0.4966   | 101  10.578  0.5111   | 37    7.292   0.5502
38    6.056    0.4951  | 72    8.366   0.4967   | 85   9.691   0.5112   | 31    6.616   0.5502
69    8.144    0.4953  | 45    6.625   0.4967   | 84   9.634   0.5113   | 97    12.398  0.5503
48    6.804    0.4953  | 42    6.403   0.4968   | 95   10.275  0.5116   | 27    6.134   0.5503
58    7.475    0.4954  | 74    8.488   0.4969   | 82   9.531   0.5116   | 41    7.720   0.5504
56    7.349    0.4955  | 78    8.715   0.4970   | 118  11.484  0.5117   | 36    7.188   0.5504
42    6.374    0.4956  | 37    6.019   0.4971   | 110  11.084  0.5117   | 16    4.600   0.5504
64    7.856    0.4956  | 46    6.709   0.4972   | 91   10.063  0.5118   | 108   13.162  0.5505
40    6.224    0.4956  | 39    6.182   0.4972   | 86   9.779   0.5119   | 122   14.078  0.5505
83    8.939    0.4957  | 105   10.116  0.4972   | 107  10.937  0.5119   | 43    7.936   0.5507
63    7.800    0.4958  | 47    6.785   0.4973   | 92   10.124  0.5119   | 54    8.998   0.5508
59    7.557    0.4960  | 38    6.108   0.4975   | 90   10.013  0.5120   | 52    8.817   0.5509
92    9.420    0.4960  | 89    9.332   0.4976   | 71   8.877   0.5122   | 66    10.066  0.5512
50    6.967    0.4962  | 111   10.417  0.4976   | 79   9.381   0.5123   | 70    10.403  0.5513
47    6.757    0.4962  | 40    6.272   0.4978   | 75   9.137   0.5124   | 106   13.080  0.5513
45    6.613    0.4962  | 56    7.419   0.4979   | 98   10.481  0.5124   | 45    8.157   0.5514
100   9.828    0.4962  | 106   10.198  0.4980   | 78   9.336   0.5127   | 62    9.734   0.5514
44    6.544    0.4964  | 59    7.618   0.4980   | 87   9.875   0.5128   | 12    3.936   0.5514
46    6.691    0.4965  | 57    7.489   0.4980   | 512  24.510  0.5128   | 34    6.991   0.5515
57    7.443    0.4965  | 91    9.457   0.4981   | 77   9.278   0.5128   | 85    11.589  0.5515
84    9.023    0.4965  | 51    7.088   0.4981   | 89   9.998   0.5129   | 125   14.336  0.5515
94    9.544    0.4965  | 80    8.870   0.4981   | 81   9.529   0.5130   | 88    11.815  0.5515
95    9.595    0.4966  | 81    8.926   0.4981   | 70   8.849   0.5132   | 64    9.912   0.5515
49    6.908    0.4966  | 101   9.965   0.4982   | 61   8.247   0.5132   | 46    8.261   0.5515
43    6.475    0.4966  | 119   10.815  0.4982   | 72   8.986   0.5134   | 72    10.580  0.5516
67    8.073    0.4967  | 77    8.707   0.4982   | 80   9.493   0.5136   | 92    12.112  0.5516
54    7.254    0.4968  | 76    8.651   0.4982   | 73   9.061   0.5137   | 60    9.568   0.5516
68    8.135    0.4968  | 62    7.817   0.4982   | 74   9.134   0.5139   | 124   14.280  0.5516
71    8.312    0.4968  | 55    7.364   0.4982   | 63   8.414   0.5141   | 103   12.892  0.5516
114   10.518   0.4968  | 67    8.128   0.4983   | 68   8.755   0.5142   | 123   14.218  0.5516
85    9.093    0.4969  | 110   10.408  0.4984   | 57   7.998   0.5143   | 56    9.213   0.5517
91    9.407    0.4969  | 90    9.422   0.4985   | 76   9.274   0.5143   | 98    12.555  0.5518
87    9.201    0.4969  | 60    7.700   0.4985   | 64   8.501   0.5146   | 48    8.469   0.5519
73    8.433    0.4969  | 86    9.213   0.4985   | 67   8.715   0.5149   | 128   14.551  0.5519
88    9.256    0.4970  | 108   10.325  0.4986   | 58   8.103   0.5153   | 120   14.042  0.5519
55    7.328    0.4970  | 44    6.599   0.4986   | 2048 50.887  0.5154   | 116   13.783  0.5519
98    9.767    0.4971  | 88    9.324   0.4986   | 62   8.391   0.5154   | 110   13.386  0.5519
86    9.154    0.4971  | 64    7.957   0.4987   | 69   8.870   0.5155   | 32    6.772   0.5519
80    8.832    0.4971  | 83    9.061   0.4988   | 65   8.610   0.5157   | 84    11.537  0.5519
78    8.722    0.4971  | 68    8.204   0.4988   | 66   8.679   0.5158   | 42    7.870   0.5520
74    8.497    0.4971  | 102   10.046  0.4988   | 53   7.750   0.5158   | 76    10.919  0.5520
82    8.942    0.4971  | 85    9.173   0.4989   | 59   8.195   0.5159   | 104   12.987  0.5521
53    7.198    0.4971  | 114   10.621  0.4989   | 51   7.602   0.5159   | 61    9.674   0.5521
51    7.062    0.4972  | 61    7.775   0.4989   | 55   7.908   0.5160   | 105   13.058  0.5521
90    9.369    0.4972  | 125   11.122  0.4989   | 44   7.048   0.5160   | 53    8.953   0.5521
75    8.558    0.4973  | 70    8.328   0.4989   | 47   7.293   0.5160   | 75    10.845  0.5521
52    7.133    0.4973  | 36    5.978   0.4990   | 38   6.537   0.5161   | 115   13.732  0.5521
99    9.827    0.4973  | 98    9.853   0.4990   | 54   7.845   0.5164   | 71    10.523  0.5521
61    7.725    0.4973  | 63    7.904   0.4990   | 60   8.297   0.5168   | 81    11.319  0.5522
65    7.973    0.4973  | 107   10.296  0.4990   | 50   7.554   0.5169   | 100   12.717  0.5522
97    9.734    0.4974  | 103   10.102  0.4990   | 56   8.011   0.5169   | 73    10.689  0.5522
79    8.789    0.4974  | 118   10.812  0.4990   | 52   7.716   0.5171   | 107   13.202  0.5522
76    8.623    0.4975  | 115   10.674  0.4990   | 48   7.407   0.5173   | 50    8.676   0.5523
62    7.793    0.4975  | 58    7.586   0.4990   | 45   7.165   0.5173   | 80    11.248  0.5523
112   10.460   0.4975  | 128   11.261  0.4990   | 40   6.748   0.5176   | 113   13.613  0.5523
101   9.935    0.4975  | 53    7.253   0.4990   | 46   7.276   0.5184   | 55    9.146   0.5523
109   10.322   0.4976  | 94    9.654   0.4991   | 42   6.941   0.5184   | 49    8.583   0.5524
72    8.398    0.4976  | 69    8.275   0.4991   | 34   6.223   0.5184   | 111   13.484  0.5524
81    8.909    0.4977  | 92    9.553   0.4991   | 39   6.683   0.5185   | 91    12.084  0.5524
96    9.699    0.4978  | 120   10.909  0.4991   | 49   7.532   0.5188   | 121   14.145  0.5524
77    8.694    0.4979  | 113   10.586  0.4991   | 41   6.881   0.5194   | 79    11.178  0.5525
116   10.667   0.4980  | 96    9.759   0.4991   | 36   6.432   0.5194   | 69    10.373  0.5525
115   10.622   0.4980  | 66    8.095   0.4992   | 43   7.055   0.5195   | 119   14.019  0.5525
66    8.057    0.4980  | 73    8.515   0.4992   | 37   6.533   0.5198   | 117   13.889  0.5525
102   10.008   0.4980  | 84    9.133   0.4992   | 32   6.061   0.5199   | 118   13.956  0.5525
89    9.351    0.4980  | 116   10.733  0.4993   | 33   6.163   0.5201   | 112   13.561  0.5525
113   10.533   0.4981  | 100   9.968   0.4993   | 29   5.766   0.5203   | 127   14.536  0.5525
128   11.210   0.4981  | 54    7.328   0.4993   | 35   6.362   0.5205   | 78    11.104  0.5526
111   10.443   0.4981  | 95    9.717   0.4993   | 26   5.452   0.5206   | 68    10.294  0.5526
122   10.950   0.4982  | 121   10.965  0.4993   | 31   5.988   0.5212   | 58    9.429   0.5526
127   11.176   0.4983  | 122   11.011  0.4993   | 24   5.253   0.5220   | 15    4.466   0.5526
108   10.313   0.4984  | 117   10.783  0.4994   | 30   5.907   0.5222   | 65    10.042  0.5526
105   10.170   0.4984  | 104   10.169  0.4994   | 23   5.148   0.5226   | 99    12.671  0.5526
103   10.073   0.4984  | 79    8.865   0.4994   | 21   4.920   0.5233   | 83    11.495  0.5526
104   10.124   0.4984  | 65    8.042   0.4994   | 27   5.620   0.5238   | 126   14.478  0.5526
117   10.740   0.4985  | 71    8.407   0.4995   | 28   5.732   0.5240   | 90    12.023  0.5526
126   11.145   0.4985  | 109   10.414  0.4995   | 25   5.403   0.5241   | 44    8.096   0.5527
120   10.878   0.4985  | 99    9.928   0.4995   | 22   5.055   0.5242   | 26    6.060   0.5530
107   10.274   0.4985  | 49    6.989   0.4996   | 18   4.569   0.5257   | 82    11.463  0.5535
110   10.417   0.4985  | 97    9.832   0.4996   | 20   4.839   0.5264   | 35    7.164   0.5538
121   10.925   0.4986  | 93    9.629   0.4997   | 17   4.463   0.5280   | 67    10.270  0.5540
118   10.790   0.4986  | 75    8.650   0.4997   | 16   4.325   0.5282   | 11    3.778   0.5544
124   11.060   0.4986  | 124   11.120  0.4997   | 19   4.741   0.5286   | 9     3.382   0.5546
119   10.836   0.4986  | 87    9.317   0.4998   | 15   4.192   0.5292   | 14    4.324   0.5548
123   11.016   0.4986  | 126   11.217  0.4999   | 14   4.097   0.5344   | 13    4.154   0.5553
125   11.105   0.4986  | 123   11.088  0.4999   | 12   3.787   0.5359   | 10    3.602   0.5565
106   10.234   0.4987  | 127   11.268  0.5000   | 13   3.973   0.5378   | 5     2.477   0.5635
7     2.639    0.4988  | 112   10.582  0.5000   | 11   3.656   0.5406   | 4     2.192   0.5662
256   16.061   0.5007  | 3     1.739   0.5035   | 10   3.559   0.5513   | 8     3.263   0.5687
1024  33.411   0.5062  | 512   23.717  0.5075   | 8    3.198   0.5590   | 256   23.955  0.5728
512   23.664   0.5072  | 256   16.933  0.5102   | 9    3.454   0.5641   | 7     3.062   0.5750
2048  50.205   0.5136  | 1024  34.393  0.5104   | 7    3.047   0.5726   | 6     2.805   0.5757
4     2.039    0.5139  | 2048  49.287  0.5112   | 6    2.837   0.5820   | 512   38.603  0.5856
6     2.549    0.5223  | 4     2.045   0.5161   | 5    2.605   0.5948   | 2048  95.904  0.5985
5     2.343    0.5292  | 6     2.523   0.5164   | 3    2.021   0.6406   | 1024  65.349  0.6030
3     1.980    0.6217  | 5     2.307   0.5195   | 4    2.431   0.6406   | 3     1.980   0.6217
2     1.760    0.8156  | 2     1.539   0.6220   | 2    1.760   0.8157   | 2     1.760   0.8156

Here is a graph of the peaks (as of February, 2015), followed by a graph of the exponent vs n (n^y = peak amp).

sqrt n n^y

The "even" cases are not independent of the "all" cases; each even-harmonics case can be at worst 1.0 above the corresponding (n-1) all-harmonics case (shift the current "all" choices right to multiply each by 2, then set the new fundamental phase to 0.0). If you then search around this set of phases, you'll find very good values. Using Snd's fpsap (a version of the genetic algorithm):

(let ((all (cadr (get-best :all (- n 1)))))   ; get the best all-harmonic phases for n - 1
  (let ((new-phases (make-vector n 0.0)))     ; place in new phase vector shifted up
    (do ((k 0 (+ k 1)))
        ((= k (- n 1)))
      (set! (new-phases (+ k 1)) (all k)))
    (set! (new-phases 0) 0.0)
    (fpsap 2 n new-phases)))                  ; search that vicinity for a good set (2 = even harmonics)

Here is the time domain view of one of the n=5 cases when the minimum peak phases are chosen; the sum of the 5 components is in black.

n=5 case

The next graph compares the 100 harmonic minimum peak case in blue with the case where all the initial phases are 0.0 in black:

100 harmonics

And a few others:

57 harmonics 57 odd harmonics
99 harmonics

As N increases, the minimum peak amplitude waveform can approach white noise (in sound as well as appearance); here is a small portion of one period when n=65536 (the prescaling peak was 704):

65536 harmonics

but the waveforms generated from the initial-phase polynomials look more regular (this is with n=64):

64 harmonics using pi/n formula
piano

This instrument is a translation of CLM's piano.ins, a piano physical model by Scott van Duyne; see Julius O. Smith and Scott A. Van Duyne, "Commuted piano synthesis," in Proc. Int. Computer Music Conf., Banff, Canada, September 1995, pp. 335 - 342. To paraphrase, the model includes multiple coupled strings, a nonlinear hammer, and an arbitrarily large soundboard and enclosure. The actual instrument name is 'p':

(with-sound ()
  (do ((i 0 (+ i 1))) ((= i 7))
    (p (* i .5) :duration .5                    ; generate a sequence of 1/2 second tones
                :keyNum (+ 24 (* 12 i))         ; jump by octaves
                :strike-velocity .5             ; 0 to 1, 0 is softest played note, 1 is loud note
                :amp .4		                ; overall volume level
                :DryPedalResonanceFactor .25))) ; 0 no open string resonance
				                ; 1.0 is about full resonance of dampers raised
				                ; can be greater than 1.0

"p" has lots of parameters, and I really don't know what they do. The interested reader should goof around with them.

p (start 
   (duration 1.0)
   (keyNum 60.0)              ; middleC=60: can use fractional part to detune
   (strike-velocity 0.5)      ; corresponding normalized velocities (range: 0.0--1.0)
   (pedal-down #f)	      ; set to t for sustain pedal down...pedal-down-times not yet impl.
   (release-time-margin 0.75) ; extra compute time allowed beyond duration
   (amp .5)                   ; amp scale of noise inputs...
   (detuningFactor 1.0)
   (detuningFactor-table ())
   (stiffnessFactor 1.0)
   (stiffnessFactor-table ())
   (pedalPresenceFactor .3)
   (longitudinalMode 10.5)
   (StrikePositionInvFac -0.9)
   (singleStringDecayRateFactor 1.0)
   
   ;; parameter tables indexed by keyNum
   ;; you can override the loudPole-table by directly setting :loudPole to a value

   loudPole (loudPole-table default-loudPole-table)
   softPole (softPole-table default-softPole-table)
   loudGain (loudGain-table default-loudGain-table)
   softGain (softGain-table default-softGain-table)
   strikePosition (strikePosition-table default-strikePosition-table)
   detuning2 (detuning2-table default-detuning2-table)
   detuning3 (detuning3-table default-detuning3-table)
   stiffnessCoefficient (stiffnessCoefficient-table default-stiffnessCoefficient-table)
   singleStringDecayRate (singleStringDecayRate-table default-singleStringDecayRate-table)
   singleStringZero (singleStringZero-table default-singleStringZero-table)
   singleStringPole (singleStringPole-table default-singleStringPole-table)
   releaseLoopGain (releaseLoopGain-table default-releaseLoopGain-table)
   DryTapFiltCoeft60 (DryTapFiltCoeft60-table default-DryTapFiltCoeft60-table)
   DryTapFiltCoefTarget (DryTapFiltCoefTarget-table default-DryTapFiltCoefTarget-table)
   DryTapFiltCoefCurrent (DryTapFiltCoefCurrent-table default-DryTapFiltCoefCurrent-table)
   DryTapAmpt60 (DryTapAmpt60-table default-DryTapAmpt60-table)
   sustainPedalLevel (sustainPedalLevel-table default-sustainPedalLevel-table)
   pedalResonancePole (pedalResonancePole-table default-pedalResonancePole-table)
   pedalEnvelopet60 (pedalEnvelopet60-table default-pedalEnvelopet60-table)
   soundboardCutofft60 (soundboardCutofft60-table default-soundboardCutofft60-table)
   DryPedalResonanceFactor (DryPedalResonanceFactor-table default-DryPedalResonanceFactor-table)
   unaCordaGain (unaCordaGain-table default-unaCordaGain-table))

Here is another example; there are a couple other examples at the end of piano.scm:

(with-sound ()
  (do ((i 0 (+ i 1))) ((= i 8))
    (p (* i .5) :duration .5 :keyNum (+ 24 (* 12 i)) :strike-velocity .5 :amp .4 :DryPedalResonanceFactor .25
     :detuningFactor-table '(24 5 36 7.0 48 7.5 60 12.0 72 20 84 30 96 100 108 300)
		    ; scales the above detuning values so 1.0 is nominal detuning, 
                    ;  0.0 is exactly in tune,  > 1.0 is out of tune
     :stiffnessFactor-table '(21 1.5 24 1.5 36 1.5 48 1.5 60 1.4 72 1.3 84 1.2 96 1.0 108 1.0))))
		    ; 0.0 to 1.0 is less stiff, 1.0 to 2.0 is more stiff

In Ruby:

include Piano
with_sound(:clm, false, :channels, 1) do
  7.times do |i|
    p(i * 0.5,
      :duration, 0.5,
      :keyNum, 24 + 12.0 * i,
      :strike_velocity, 0.5,
      :amp, 0.4,
      :dryPedalResonanceFactor, 0.25)
  end
end
see also:   flute   maraca   pluck   prc95   singer   strad
play

This file has a variety of "real-time" audio output examples. It is almost entirely obsolete.

play-with-amps snd :rest amps

play-with-amps plays the sound 'snd' with each channel scaled by the corresponding amp: (play-with-amps 0 1.0 0.5) plays sound 0's channel 1 at full amplitude, and channel 2 at half amplitude.

play-often n
play-until-c-g 
play-region-forever reg

play-often plays the selected sound 'n' times. play-until-c-g plays the selected sound until you interrupt it via C-g. Similarly, play-region-forever plays region 'reg' until you interrupt it with C-g.

(bind-key #\p 0 
  (lambda (n) 
    "play often" 
    (play-often (max 1 n))))

(bind-key #\r 0 
  (lambda (n) 
    "play region forever" 
    (play-region-forever n)))

Now C-u 31 p plays the current sound 31 times; C-u 3 r plays region 3 until we type C-g.

play-sine freq amp
play-sines freqs-and-amps

play-sine plays a one-second sine wave at the given frequency and amplitude: (play-sine 440 .1). play-sines produces a spectrum given a list of lists of frequency and amplitude:

(play-sines '((425 .05) (450 .01) (470 .01) (546 .02) (667 .01) (789 .034) (910 .032)))
start-dac 
stop-dac 

start-dac opens the DAC ready for sound output, and stop-dac closes it.

poly

This file contains various functions related to the CLM polynomial function. A polynomial here is a vector (for complex coefficients) holding the polynomial coefficients from lowest to highest (i.e. the constant is (v 0), x+2 is (float-vector 2 1), etc).

poly+ p1 p2              ; new poly = p1 + p2
poly* p1 p2              ; new poly = p1 * p2
poly/ p1 p2              ; (list quotient-poly remainder-poly) = p1 / p2
poly-derivative p1       ; new poly = Dp1
poly-reduce p1           ; new poly = p1 without high zeros
poly-gcd p1 p2           ; new poly = gcd(p1, p2)
poly-roots p1            ; list of roots of p1
poly-resultant p1 p2     ; resultant of p1 and p2
poly-discriminant p1     ; discriminant of p1

poly+ adds two polynomials, and poly* multiplies two polynomials. poly/ divides two polynomials, with a few restrictions, and returns a list containing the quotient and remainder polynomials. poly-derivative returns the derivative of a polynomial. In all these cases, the resultant polynomials may have extra high-degree entries whose coefficients are zero. To remove these pointless coefficients, use poly-reduce. The last functions are just for fun.

You can treat a sound as a set of polynomial coefficients; then, for example, convolution the infinitely slow way is poly*:

(float-vector->channel (poly* (channel->float-vector 0 (framples)) (float-vector 2.0))) ; no, this is not serious
see also:   polynomial  
prc95

prc95.scm is a translation to Snd of Perry Cook's (1995) physical modelling toolkit; prc-toolkit95.lisp in CLM. One starting point for physical modelling is Smith, "Music Applications of Digital Waveguides", CCRMA, Stan-M-39, 1987, or Julius's home page, or any of several classic papers also by Julius Smith. Perry's own version of this code can be found in STK. The example instruments are:

plucky beg dur freq amplitude maxa  ; plucked string
bow beg dur frq amplitude maxa      ; bowed string
brass beg dur freq amplitude maxa   
clarinet beg dur freq amplitude maxa 
flute beg dur freq amplitude maxa

(with-sound ()
  (plucky 0 .3 440 .2 1.0)
  (bow .5 .3 220 .2 1.0)
  (brass 1 .3 440 .2 1.0)
  (clarinet 1.5 .3 440 .2 1.0)
  (flute 2 .3 440 .2 1.0))
see also:   maraca: maraca.scm, maraca.rb   piano: piano.scm, piano.rb   singer: singer.scm, singer.rb   bowed string: strad.scm, strad.rb   flute: clm-ins.scm   string: compute-string   plucked string: pluck in clm-ins.scm
pvoc

This is the same as the CLM phase-vocoder generator, but implemented in Scheme. If you're interested in how the thing works, I think the Scheme version is easiest to understand; the Common Lisp version is in mus.lisp, and the C version is in clm.c.

make-pvocoder fftsize overlap interp analyze edit synthesize
pvocoder gen input
pvoc (fftsize 512) (overlap 4) (time 1.0) (pitch 1.0) (gate 0.0) (hoffset 0.0) (snd 0) (chn 0)

The 'analyze', 'edit', and 'synthesize' arguments to make-pvocoder are functions that are applied as needed during pvocoder processing; similarly, the 'input' argument to pvocoder can be a function.

(let ((ind (open-sound "oboe.snd"))
      (pv (make-pvocoder 256 4 64))
      (rd (make-sampler 0)))
  (map-channel (lambda (y) (pvocoder pv rd))))

pvoc.scm also contains a few examples of using the CLM phase-vocoder generator:

(define test-pv-4
  (lambda (gate)
    (let* ((reader (make-sampler 0))
           (pv (make-phase-vocoder
                                  (lambda (dir) (reader))
				  512 4 128 1.0
				  #f ;no change to analysis
				  (lambda (v)
				    (let ((N (length v)))
				      (do ((i 0 (+ i 1)))
					  ((= i N))
					(if (< ((phase-vocoder-amp-increments v) i) gate)
					    (set! ((phase-vocoder-amp-increments v) i) 0.0)))
				      #t))
				  #f))) ;no change to synthesis
	  
      (map-channel (lambda (val)
		  (phase-vocoder pv))))))

This sets up a phase-vocoder generator whose edit function is squelching soft partials. In this case, the input function is reading the currently selected channel.

pvoc is yet another (unoptimized) phase-vocoder; it applies the phase-vocoder to the current sound; 'pitch' specifies the pitch transposition ratio, 'time' specifies the time dilation ratio, 'gate' specifies a resynthesis gate in dB (partials with amplitudes lower than the gate value will not be synthesized), 'hoffset' is a pitch offset in Hz.

(pvoc :time 2.0)
see also:   phase-vocoder   pins
rgb

rgb.scm (rgb.rb) is a translation of the standard X11 color names into Snd color objects.

(define snow (make-color 1.00 0.98 0.98))

is taken from the line

255 250 250             snow

/usr/lib/X11/rgb.txt. The choice of a float between 0.0 and 1.0 (rather than an integer between 0 and 255) mimics PostScript; as video hardware has improved over the years, there's less and less need for these elaborate color names, and less reason (except perhaps psychophysical) to limit these numbers to bytes. There is one gotcha in this file — X11 defines a color named "tan" which is already used by Scheme, so (at the suggestion of Dave Phillips) this color is named "tawny" in rgb.scm.

rubber
rubber-sound stretch-factor snd chn

rubber-sound tries to stretch or contract a sound (in time); it scans the sound looking for stable (periodic) sections, then either deletes periods or interpolates new ones to shorten or lengthen the sound. It still needs a lot of robustification. The algorithm is 1) remove all frequencies below 16 Hz, 2) resample the file to be ten times longer (interpolating samples), 3) make a list of upward zero crossings, 4) using autocorrelation decide where the next fundamental zero crossing probably is and see how much difference there is between the current period and the next, 5) check intermediate crossing weights and if the autocorrelation weight is not the smallest, throw away this crossing, 6) sort the remaining crossings by least weight, 7) interpolate or delete periods until the sound has been sufficiently lengthened or shortened. rubber-sound is incredibly slow, and almost never works. The idea seems good however...

see also:   clm-expsrc   expsrc   pvoc   ssb-bank
s7test

s7test.scm is a regression test for s7. Any additional tests are most welcome!

selection
filter-selection-and-smooth ramp-dur flt order

filter-selection-and-smooth filters the current selection with flt, then mixes it back into the original using ramp-dur to set how long the cross-fade ramps are.

(filter-selection-and-smooth .01 (float-vector .25 .5 .5 .5 .25))
make-selection beg end snd chn

make-selection makes a selection, like make-region but without creating a region. make-selection follows snd's sync field, and applies to all snd's channels if chn is not specified. end defaults to end of channel, beg defaults to 0, and snd defaults to the currently selected sound.

(make-selection 1000 2000)
replace-with-selection 

replace-with-selection replaces any data at the cursor with the current selection.

selection-members 

selection-members returns a list of lists of '(snd chn) indicating the channels participating in the current selection. It is the selection-oriented version of all-chans.

swap-selection-channels

swap-selection-channels swaps the current selection's channels.

with-temporary-selection thunk beg dur snd chn

with-temporary selection saves the current selection placement, makes a new selection of the data from sample 'beg' to beg + dur in the given channel, calls 'thunk', then restores the previous selection (if any). It returns whatever 'thunk' returned.

singer

singer.scm is an implementation of Perry Cook's physical model of the vocal tract as described in:

  Cook, Perry R. "Synthesis of the Singing Voice Using a Physically Parameterized Model of the Human Vocal Tract"
     Published in the Proceedings of the International Computer Music Conference, Ohio 1989 
     and as Stanford University Department of Music Technical Report Stan-M-57, August 1989.
 
 ---- "Identification of Control Parameters in an Articulatory Vocal Tract Model, with Applications 
    to the Synthesis of Singing," Ph.D. Thesis, Stanford University Department of Music Technical Report 
    Stan-M-68, December 1990.

 ----  "SPASM, a Real-time Vocal Tract Physical Model Controller; and Singer, the Companion Software 
    Synthesis System", Computer Music Journal, vol 17 no 1 Spring 1993.

singer.scm is a translation of Perry's singer.c. I think that Perry's code assumes a sampling rate of 22050; you'll need to fix up lots of lengths in the code to run at 44100. The singer instrument looks deceptively simple:

singer beg amp data

but all the complexity is hidden in the 'data' parameter. 'data' is a list of lists; each imbedded list has the form: '(dur shape glot pitch glotamp noiseamps vibramt). The 'shape' and 'glot' entries are themselves lists; I think the 'glot' list describes the glottal pulse. I wish I could fully explain all these lists, but I translated this code a very long time ago, and can't remember any details. You'll have to read the code, or perhaps find something in Perry's publications. In any case, here's an example:

(with-sound () 
  (singer 0 .1 (list (list .4 ehh.shp test.glt 523.0 .8 0.0 .01) 
                     (list .6 oo.shp test.glt 523.0 .7 .1 .01))))

The *.shp and *.glt data is defined at the end of singer.scm. For example:

(define test.glt (list 10 .65 .65))
(define ee.shp (list 8 1.02 1.637 1.67 1.558 0.952 0.501 0.681 0.675 0.9 -0.4 1.0 0.0 0.0 0.0 0.0 0.0 0.0))

A more complex example is singer's attempt to say "requiem":

(with-sound ()
  (singer 0 .1 (list (list .05 ehh.shp test.glt 523.0 0.8 0.0 .01) 
       (list .15 ehh.shp test.glt 523.0 0.8 0.0 .01) 
       (list .05 kkk.shp test.glt 523.0 0.0 0.0 .01) 
       (list .05 kkk.shp test.glt 523.0 0.0 0.0 .01) 
       (list .02 kk+.shp test.glt 523.0 0.0 1.0 .01) 
       (list .08 kk+.shp test.glt 523.0 0.0 0.2 .01) 
       (list .05 ooo.shp test.glt 523.0 0.8 0.0 .01) 
       (list .15 ooo.shp test.glt 523.0 0.8 0.0 .01) 
       (list .05 eee.shp test.glt 523.0 0.8 0.0 .01) 
       (list .15 eee.shp test.glt 523.0 0.8 0.0 .01) 
       (list .05 ehh.shp test.glt 523.0 0.8 0.0 .01) 
       (list .15 ehh.shp test.glt 523.0 0.8 0.0 .01) 
       (list .05 mmm.shp test.glt 523.0 0.8 0.0 .01) 
       (list .15 mmm.shp test.glt 523.0 0.8 0.0 .01) 			      
       (list .10 mmm.shp test.glt 523.0 0.0 0.0 .01))))
see also:   fofins   reson   pqw-vox   vox
snd13|14|15

These files contain several procedures that were removed from or renamed in earlier versions of Snd (in Ruby, look in extensions.rb). snd13.scm, for example, has the old sine-summation, make-sum-of-cosines, and make-sum-of-sines generators.

snddiff

The snddiff function tries to detect how one sound differs from another.

snddiff snd0 chn0 snd1 chn1

This could use about a lifetime's work, but it does find some differences:

                 ;; start with two identical sounds:
> (map short-file-name (sounds))
("oboe.snd" "oboe.snd")
> (snddiff 0 0 1 0)
no-difference
                 ;; snddiff can find individual sample differences:
> (set! (sample 1000 0 0) 0.5)
0.5
> (snddiff 0 0 1 0)
(differences ((1000 0.5 0.0328369140625)))
                 ;; and scaling changes (we reverted the previous change):
> (scale-channel 2.0)
2.0
> (snddiff 0 0 1 0)
(scale 2.0)
                 ;; and some initial delays:
> (pad-channel 0 200 0 0)
0
> (snddiff 0 0 1 0)
(lag 200 no-difference 0.0 #f #f #f)
snd-gl

snd-gl.scm has examples of using OpenGL. To try out these functions, build Snd with GL: configure --with-gl. You can tell if your current Snd has OpenGL loaded by checking the *features* list for 'gl: (provided? 'gl).

complexify 

complexify displays FFT data in the complex plane; each bin is rotated so that they all stack along the x axis, with a line drawn from the x axis to the current real/imaginary point (as (z, y)), so as you move (slowly) through a file, you'll see the phase info as well as the magnitude — the vectors whirl around in each slice of the complex plane. Use the View:Orientation dialog to change the viewing angle. To move one sample at a time through a sound, you could bind the arrow keys:

(bind-key "Left" 0 (lambda () 
                     (set! (left-sample) (max 0 (- (left-sample) 1))) 
                     keyboard-no-action))
(bind-key "Right" 0 (lambda () 
                     (set! (left-sample) (min (framples) (+ 1 (left-sample)))) 
                     keyboard-no-action))
gl-dump-state

gl-dump-state displays much of the current GL graphics state.

gl-info 

gl-info prints out information about the current GL system setup.

see also:   glSpectrogram   OpenGL
snd-motif, snd-xm

snd-motif.scm has a variety of user-interface extensions that rely on the Motif module (xm.c). Some of these have been translated to Gtk and xg.c — snd-gtk.scm. In Ruby, see snd-xm.rb.

add-amp-controls

add-amp-controls adds amplitude sliders to the control panel for multichannel sounds so that each channel gets its own amplitude control slider. To make this the default, add (add-amp-controls) to your initialization file. Here is a 4-channel control panel after adding the channel-specific amp controls.

added amp controls
add-delete-option 

add-delete-option adds a "Delete" (file) option to the File menu.

add-find-to-listener 

add-find-to-listener causes C-s and C-r in the listener to start a separate "Find" dialog.

add-mark-pane 

add-mark-pane adds a pane to each channel giving the current mark locations (sample values). These can be edited to move the mark, or deleted to delete the mark. (If you add-mark-pane to a channel having marks, you need to make some change to them to force it to be displayed). Here's a picture (it also shows with-smpte-label, with-inset-graph, and show-disk-space).

mark pane SMPTE label SMPTE label SMPTE label SMPTE label SMPTE label SMPTE label SMPTE label
add-rename-option 

add-rename-option adds a "Rename" (file) option to the File menu.

add-text-to-status-area

add-text-to-status-area puts a text widget in the notebook's status area (the lower left portion of the main Snd window when using the -notebook invocation switch). It returns the widget; you can write to it via XmTextFieldSetString.

add-tooltip widget tip

add-tooltip adds a tooltip (also known as bubble-help) to a widget. Once added, set the variable with-tooltips to #f to turn it off.

(add-tooltip (cadr (channel-widgets)) "show the time domain waveform")
disable-control-panel snd

disable-control-panel does away with the control panel.

display-widget-tree widget

display-widget-tree displays the hierarchy of widgets beneath 'widget'.

equalize-panes snd

This equalizes multichannel sound panes (tries to make them the same size), It is specific to Motif since Gtk paned window widgets are too simple-minded to get into this predicament. If the 'snd' argument is given, only that sound's panes are affected.

for-each-child w func
find-child w name

for-each-child applies 'func' to the widget 'w' and to each widget in the hierarchy of widgets below it. 'func' takes one argument, the child widget. for-each-child is used by find-child which searches for a widget named 'name' belonging to 'w'.

(for-each-child 
  ((sound-widgets) 2) ; control panel
  (lambda (w) 
    (snd-print (format #f "~%~A" (XtName w)))))
install-searcher-with-colors proc

install-searcher-with-colors places our own search procedure into the filter mechanism in the File:Open dialog. This has been superseded by the file-filter mechanism now built into Snd.

(install-searcher-with-colors (lambda (file) #t))
keep-file-dialog-open-upon-ok

keep-file-dialog-open-upon-ok changes File:Open so that clicking "ok" does not unmanage (dismiss) the dialog.

load-font font-name

load-font loads a font and returns a handle for it.

  (define new-font (load-font "-*-helvetica-bold-r-*-*-14-*-*-*-*-*-*-*"))

  (define* (show-greeting (snd 0) (chn 0))
  ;; show a red "hi!" in the helvetica bold font on a gray background
    (let ((ls (left-sample snd chn))
	  (rs (right-sample snd chn)))
      (if (and (< ls 1000)
	       (> rs 1000))
	  (let ((pos (x->position (/ 1000.0 (srate))))
		(old-color (foreground-color))
		(cr (make-cairo (car (channel-widgets snd chn))))) ; make-cairo needed in Gtk, returns #f otherwise
	    (set! (foreground-color) (make-color .75 .75 .75))
	    (fill-rectangle pos 10 50 20 snd chn time-graph #f cr)
	    (set! (foreground-color) (make-color 1 0 0))
            (if new-font (set! (current-font) new-font))
	    (draw-string "hi!" (+ pos 5) 12 snd chn time-graph cr)
	    (set! (foreground-color) old-color)
	    (free-cairo cr)))))
make-channel-drop-site snd chn
set-channel-drop drop snd chn

make-channel-drop-site shows how to add a drop site panel to a channel. set-channel-drop changes the channel's graph's drop function to 'drop', a function of 3 arguments, the dropped filename (a string) and the current sound and channel number.

make-pixmap widget strs

make-pixmap turns an XPM-style description into pixmap. Briefly an XPM pixmap description is an array of strings; the first gives the size in pixels of the pixmap, and the number of colors; the next set give characters followed by the color desired for that character; then comes the pixmap itself using those characters. The following defines a 16 X 12 arrow using 6 colors:

(define arrow-strs (list
  "16 12 6 1"
  " 	c None s None"
  ".	c gray50"
  "X	c black"
  "o	c white"
  "O	c yellow"
  "-      c ivory2 s basiccolor"
  "--------X---------"
  "---------X--------"
  "----------X-------"
  "-----------X------"
  "------------X-----"
  "XXXXXXXXXXXXXX----"
  "------------X-----"
  "-----------X------"
  "----------X-------"
  "---------X--------"
  "--------X---------"
  "-------X----------"))

(make-pixmap (cadr (main-widgets)) arrow-strs) then creates the actual pixmap. The 'widget' argument is needed to give us access to the current colormap and so on. (cadr (main-widgets)) is just Snd's outer shell, which will do the trick in most cases. See new-backgrounds.scm for many examples. The following example paints all of Snd's widgets using the same background:

(for-each-child 
  (cadr (main-widgets))
  (lambda (w) 
    (XtSetValues w (list XmNbackgroundPixmap wd))
    (if (XmIsLabel w)
        (let ((val (cadr (XtVaGetValues w (list XmNlabelType 0)))))
          (if (= val XmPIXMAP)
  	      (XtVaSetValues w (list XmNlabelPixmap wd)))))))

You can also use bitmaps:

(define right-arrow (list
   #x00 #x04 #x10 #x08 #x00 #x10 #x04 #x20 #x00 #x40 #xa5 #xbf
   #x00 #x40 #x04 #x20 #x00 #x10 #x10 #x08 #x00 #x04 #x00 #x00))
    
(define (bitmap->pixmap widget bits width height)
  (XCreateBitmapFromData (XtDisplay widget) (XtWindow widget) bits width height))
make-variable-display page-name variable-name (type 'text) (range (list 0.0 1.0))
variable-display val widget

make-variable-display sets up a display point (a dialog) for an arbitrary expression which is updated via variable-display. The latter returns its argument, so it acts as a sort of probe, picking out any arbitrary point in an instrument and displaying it as the instrument is running. Display points can be organized as pages in a notebook widget:

(define wid (make-variable-display "do-loop" "i*2" 'text))
(define wid1 (make-variable-display "do-loop" "i" 'text))
(do ((i 0 (+ i 1)))
    ((= i 10))
  (variable-display (* (variable-display i wid1) 2) wid))

The 'type' argument to make-variable-display can be one of 'text 'scale, 'graph, 'spectrum, or 'meter. It determines the kind of widget(s) used to display that variable. The 'graph and 'spectrum cases create Snd channel displays, accessible via a sound (and channel 0); these respond to the various channel-related functions such as show-transform-peaks, although you have to give the sound explicitly:

(define wid2 (make-variable-display "do-loop" "x" 'spectrum))
(set! (show-transform-peaks (car wid2)) #t)

Each graph or spectrum display is placed in its own pane (this is a desperate kludge), whereas all the others are ordered vertically in a single pane. The 'scale choice has an additional argument that gives the range of the scale as a list (low high):

(define wid2 (make-variable-display "do-loop" "i*2" 'scale '(-1.0 1.0)))

You can watch a generator's state on a sample-by-sample basis by putting it in a text display:

(define wid1 (make-variable-display "simp" "beg" 'text))
(define wid2 (make-variable-display "simp" "oscil" 'text))
(define wid3 (make-variable-display "simp" "outa" 'graph))
(definstrument (simp)
  (let* ((beg 0)
	 (dur 1000)
	 (end (+ beg dur))
	 (osc (make-oscil 440.0)))
    (do ((i beg (+ i 1)))
	((= i end))
      (variable-display i wid1)
      (variable-display
        (oscil (variable-display osc wid2) 0.0)
       wid3))))
(simp)
variable display

To clear display state, there's also variable-display-reset.

mark-sync-color new-color

mark-sync-color uses the draw-mark-hook to set the color of sync'd marks. (This is a no-op in Gtk+Cairo).

menu-option menu-name

menu-option returns the widget associated with a given menu item name ("Print" for example). This is actually a bad idea since the menu names can change without warning.

select-file func title dir filter help

select-file starts a file selection dialog, running 'func' if a file is selected:

 (add-to-menu 0 "Insert File" 
   (lambda () 
     (select-file
       insert-sound
       "Insert File" "." "*" "file will be inserted at cursor")))
show-all-atoms 

show-all-atoms displays all current X atom names (there are several hundred of these atoms normally).

show-disk-space 

show-disk-space adds a label in the status area which shows the current amount of disk space available on the partition of the associated sound. There's a picture of it in action above (add-mark-pane).

make-sound-box name parent select-func peak-func sounds args
show-sounds-in-directory (dir ".")

make-sound-box makes a container of sound file icons, each icon containing a little sketch of the waveform, the length of the file, and the filename. What happens when an icon is selected is up to 'select-func'. However, if you drag (via button 2) the icon to the menubar, that sound is opened, and if you drag it to a channel graph, it is mixed at the mouse location in that channel. 'select-func' called when sound icon is selected; it is passed the sound file's name. 'peak-func' (if any) tells the soundbox code where to find any associated peak env files. 'sounds' is list of sound file names. 'args' is list of resource settings for each icon.

(make-sound-box "sounds"
		((main-widgets) 3)
                snd-print
		*peak-env-dir*
		(list "oboe.snd" "pistol.snd" "cardinal.snd" "storm.snd")
		())

show-sounds-in-directory calls make-sound-box, filling it with any sounds found in the directory passed as its argument (which defaults to the current directory).

show-sounds-in-directory
snd-clock-icon snd hour

snd-clock-icon replaces Snd's hourglass with a (very primitive) clock.

upon-save-yourself thunk

upon-save-yourself causes 'thunk' (a function of no arguments) to be called if the window manager sends a SAVE_YOURSELF message.

upon-take-focus thunk

upon-take-focus causes 'thunk' (a function of no arguments) to be called whenever Snd receives focus from the window manager.

with-minmax-button 

with-minmax-button adds an open/close button to each sound's pane. To activate it:

(hook-push after-open-hook with-minmax-button)
unzync 
zync 

The pair zync and unzync cause the y-axis zoom sliders of a multichannel file to move together (zync) or separately (unzync, the default).

see also:   motif   gtk   dialogs   graphics   menus   enved
snd-test

snd-test.scm and snd-test.rb are test suites for Snd. The simplest use is:

snd -l snd-test

which will run all the tests, assuming you have the various sound files it is expecting to find. You can run a particular test with:

snd -l snd-test 23

which runs test 23. snd-test is primarily useful to non-developers as a source of a huge number of examples.

sndwarp

This is a translation from CLM of Bret Battey's sndwarp instrument, itself based on Richard Karpen's sndwarp csound generator. It is similar to expsrc.

sndwarp beg dur file 
      (amp 1.0)
      (amp-env '(0 1 100 1))  ; amplitude envelope
      (stretch 1.0)           ; time stretch — 2.0 -> twice as long
      (srate 1.0)             ; src — 0.5 -> octave down
      (inputbeg 0.0)          ; source file start point
      (wsize 0.1)             ; size of windows in seconds
      (randw 0.02)            ; randomness of wsize
      (overlaps 15)           ; window overlaps per sec
      (time-ptr #f)           ; #f=stretch mode, #t=time-ptr mode
      (scale-time-ptr #f)     ; #f=absolute, #t=rescale
      (zero-start-time-ptr #f); #t=start at 0
      (window-offset #f)      ; #f=spread windows evenly
      (loc 0.5)               ; stereo loc, 0=left, 1=right
      (rev 0.1)               ; reverb amount
      (srcwidth 5)            ; src interpolation width

Many of the parameters can also be envelopes. The source has commentary which I'll slightly paraphrase here for convenience. 'time-ptr' is a flag that determines whether stretching or time-pointer mode is to be used in interpreting the 'stretch' parameter. In stretch mode, the value of 'stretch' scales the time of the sound. For example, a value of 2 will stretch the sound In time-ptr mode, the value(s) of 'stretch' are readin pointers into the soundfile. For example, to read through a file backwards from 2 seconds at half speed, use a stretch envelope such as '(0 2 1 0) with a 4 second note duration. 'scale-time-ptr' is a flag that determines whether the time-ptr envelope is interpreted in absolute seconds or rescaled to fit the duration of the input sound file. 'zero-start-time-ptr' is a flag that determines (in time-ptr mode) whether the first section of the windows start at time-ptr = 0. 'window-offset' is a flag that determines how the windows are offset in time.

(with-sound () (sndwarp 0 1 "oboe.snd"))
(with-sound () (sndwarp 0 4 "oboe.snd" :stretch 2.0 :srate 0.5))
see also:   clm-expsrc   expsrc   pvoc   rubber   ssb-bank
spectr

The spectr files were translated by Michael Scholz from CLM's spectr.clm. They contain a large set of instrument steady-state spectra, gathered many years ago (before 1976) by James A Moorer. The variable names are taken from the file names used by JAM, but by the time I got around to rescuing the data from mouldering magtapes, he had long since moved on, so I don't actually know what instrument some of the labels refer to. The data is in the form of a bunch of lists, each given a name:

(define  trp-gs5 '(  1.02 .0114  2.02 .0346  3.02 .0045  4.04 .0013  5.06 .0002))

which (I think) refers to a trumpet playing the note gs5. The first number is the harmonic, the second its amplitude, the third the next harmonic, then its amplitude, and so on. These spectra can be used directly in the instrument spectra in clm-ins.scm.

see also:   two-tab
stochastic

stochastic is Bill Sack's implementation of Xenakis' Dynamic Stochastic Synthesis as heard in his GENDY3, S.709, Legende d'Eer, etc.

stochastic start dur
           (amp .9)       ; overall amplitude
           (bits 16)      ; resolution of the wave's amplitude dimension
           (xmin 1)       ; minimum number of samples between time breakpoints, must be >= 1
           (xmax 20)      ; maximum number of samples between time breakpoints
           (xwig 0)       ; amplitude applied to random walk function in time dimension
           (xstep 1)      ; quantization of freedom in time dimension, in samples, minimum: 1
           (ywig 0)       ; amplitude applied to random walk function in amplitude dimension, as %amp
           (xfb 0)        ; FIR filter
           (init-array '((10 0) (10 1) (10 0) (10 -.7) (10 0) (10 .5) 
                         (10 0) (10 -.3) (10 0) (10 .2) (10 0) (10 -.1)))
                          ; initial x and y breakpoints for wave,
                          ;    x values must be integers >= 1, y values between -1.0 and 1.0

stochastic.ins in the CLM tarball has an elaborate Common Music-based example. Here is one that is much simpler, but very loud:

(with-sound () (stochastic 0 10 :xwig .25 :ywig 10.0))
strad

strad.scm is a translation (by Michael Scholz) of CLM's strad.ins (by Juan Reyes). It implements a physical model of a bowed string with stiffness.

v and fmv

The fm violin was my favorite instrument while working in the 70's and 80's, primarily on the Samson box. It was developed in Mus10 (ca 1977) based on ideas of John Chowning.

fm-violin startime dur frequency amplitude
	    (fm-index 1.0)                        ; scales all indices
	    (amp-env '(0 0  25 1  75 1  100 0))   ; amplitude envelope
	    (periodic-vibrato-rate 5.0) 
	    (random-vibrato-rate 16.0)            ; jitter added to vibrato
	    (periodic-vibrato-amplitude 0.0025) 
	    (random-vibrato-amplitude 0.005)
	    (noise-amount 0.0)                    ; noise added to modulation
	    (noise-freq 1000.0)
	    (ind-noise-freq 10.0)                 ; index envelope jitter
	    (ind-noise-amount 0.0)
	    (amp-noise-freq 20.0)                 ; amplitude envelope jitter
	    (amp-noise-amount 0.0)
	    (gliss-env '(0 0  100 0))             ; frequency envelope
	    (glissando-amount 0.0) 
	    (fm1-env '(0 1  25 .4  75 .6  100 0)) ; 1:1 modulator amp (fm index) env
	    (fm2-env '(0 1  25 .4  75 .6  100 0)) ; 3:1 mod env
	    (fm3-env '(0 1  25 .4  75 .6  100 0)) ; 4:1 mod env
	    (fm1-rat 1.0)                         ; 1:1 actual mod:carrier freq ratio
	    (fm2-rat 3.0)	                  ; 3:1 same
	    (fm3-rat 4.0)                         ; 4:1 same
	    (fm1-index #f)                        ; 1:1 mod local index scaler
	    (fm2-index #f)                        ; 3:1 same
	    (fm3-index #f)                        ; 4:1 same
	    (degree 0)
	    (distance 1.0)
	    (reverb-amount 0.01)
	    (base 1.0)                            ; amp env base (1.0 = line segments)

Most of these parameters are for special cases; normally you need only:

Scheme:    (with-sound () (fm-violin 0 1 440 .1))
Ruby:      with_sound() do fm_violin_rb(0, 1, 440, .1, [[:fm_index, 2.0]]) end

fm-violin sets up several parallel modulators of one carrier (see fm.html for details, or (ah nostalgia...) Schottstaedt, "The Simulation of Natural Instrument Tones Using Frequency Modulation with a Complex Modulating Wave", CMJ vol 1 no 4 1977 p46-50). The modulators themselves are modulated (vibrato, noise, etc). The FM indices were chosen to try to mimic violin or cello sounds over a wide range of frequencies. The various envelope "jitter" parameters set up slow moving random changes in the associated envelopes; in some case this can produce a much richer sound. There's no limit on what this instrument can do; nearly all my compositions in the 80's used it. To hear some of the effects, load fmviolin.clm (it is a CLM notelist, but it is completely compatible with Snd/Scheme).

fmv.scm (or v.rb in Ruby) implements the fm-violin as a CLM-style generator, making it possible to call the violin anywhere a generator could be called; since each call on the fm-violin function produces the next sample of the given violin, this form of the fm-violin is easy to call in "real-time" situations. Any other CLM-style instrument could be rewritten in the same form.

make-fm-violin
    frequency amplitude (fm-index 1.0) (amp-env #f) 
    (periodic-vibrato-rate 5.0) (random-vibrato-rate 16.0)
    (periodic-vibrato-amplitude 0.0025) (random-vibrato-amplitude 0.005) 
    (noise-amount 0.0) (noise-freq 1000.0)
    (ind-noise-freq 10.0) (ind-noise-amount 0.0) 
    (amp-noise-freq 20.0) (amp-noise-amount 0.0) (gliss-env #f)
    (fm1-env #f) (fm2-env #f) (fm3-env #f) 
    (fm1-rat 1.0) (fm2-rat 3.0) (fm3-rat 4.0) 
    (fm1-index #f) (fm2-index #f) (fm3-index #f) (base 1.0)

fm-violin gen
fm-violin-ins [same args as original violin in v.scm]

fm-violin-ins shows how this generator can be fitted into the original fm-violin code. The plethora of arguments is an historical artifact; normally only a few of them are used at a time. There are two examples of calling this generator in fmv.scm, the simpler one being:

(define test-v 
  (lambda (beg dur freq amp amp-env)
    (let ((v (make-fm-violin
	      freq amp 
	      :amp-env (let ((e (make-env (or amp-env '(0 0 1 1 2 0)) 
					  :scaler amp 
					  :length dur)))
			 (lambda () (env e)))))
	  (data (channel->float-vector beg dur)))
      (do ((i 0 (+ i 1)))
	  ((= i dur))
	(set! (data i) (+ (data i)
                          (v))))
      (set-samples beg dur data))))

Here we are setting up an fm-violin generator (via make-fm-violin), then calling it 'dur' times, mixing its output into the current data (this could also use mix-float-vector and so on). The generator is called via (v). As can be seen here, each envelope is treated as a function called on each sample very much like the "as-needed" input in src or granulate; the envelopes could actually be any arbitrary function you like (see test-v1 in fmv.scm which uses an oscillator as one of the fm index envelopes). One complication in some "real-time" situations is that you don't know in advance how long a note will be; in this case, the envelope generating functions should have attack and decay ramps, triggered by note-on and note-off; once the ramp has reached its end point, the end value should be held; the note itself should be called until it has had time to ramp off.

I can't resist including an historical digression. Here is a Mus10 version of fm-violin (in this code ":=" is used in place of the original SAIL left arrow character, and so on):

ARRAY GlissFunc, DecayFunc, AttackFunc, SineWave, AmpFunc(512);
SYNTH(Sinewave); 1,1 999;
SEG(AmpFunc); 0,0 1,25 1,50 0,75 0,100;
SEG(GlissFunc);0,1 1,50, 0,100;
SEG(AttackFunc);0,0 1,100;
SEG(DecayFunc);1,1 .6,5 .3,10 .15,25 .07,50 0,100;
	
INSTRUMENT VN1;
VARIABLE Reset1,Noise,/NewMag,OtherFreq,/Gliss,Distance,Stereo,
	Freq,Amp1,Amp2,Duration,AttackTime,DecayTime,Memory1,
	Index1,Index2,Index3,scFreq,DecayLength,Switch1,Switch2,
	/Mod1,/Mod2,/Mod3,/Env,/Att,/Vibrato,IMult,/Snd,
	/Flutter,VibRate,VibAmp,/Ramp,/Decay,VibSwitch,LogFreq,
	GlissLength,Bowing,DecayCall,VibCall,GlissCall,RampCall;
	
Memory1:=1;
	
I_ONLY BEGIN
  Duration:=P2;
  Freq:=P3;
  Amp1:=P4;
  Amp2:=P5;
  OtherFreq:=P6;
  IF Freq>=C THEN Freq:=Freq+Freq/100;
  IF Freq<C THEN Freq:=Freq-20/Freq;
	
  Switch1:=P14;
  Switch2:=1-Switch1;
  IMult:=P7-(Switch2/4);
  VibSwitch:=P8;
  Bowing:=P9;
	
  Distance:=P10;
  Stereo:=P11;
  Noise:=P12;
  GlissLength:=P13;
  LogFreq:=ALOG(Freq);
  
  DecayCall:=VibCall:=RampCall:=GlissCall:=20;
  IF Amp1=Amp2 THEN RampCall:=SRATE;
  IF Freq=OtherFreq THEN GlissCall:=SRATE;
  IF VibSwitch=0 THEN VibCall:=SRATE;
  IF Switch1=1 THEN DecayCall:=SRATE;
	
  Vibrate:=5.25+RAND*.75;
  VibAmp:=.006+RAND*.001;
	
  IF Bowing=0
    THEN
      IF Memory1>.08
	THEN
	  BEGIN
	  DecayTime:=.7;
	  AttackTime:=.2;
	  END
	ELSE
	  BEGIN
	  DecayTime:=.7;
	  AttackTime:=.05;
	  Noise:=0;
	  END
    ELSE
      IF Memory1>.05
	THEN
	  BEGIN
	  DecayTime:=.05;
	  AttackTime:=.2;
	  END
	ELSE
	  BEGIN
	  DecayTime:=.05;
	  AttackTime:=.05;
	  Noise:=0;
	  END;
	
  Memory1:=DecayTime;
	
  IF AttackTime+DecayTime>=Duration
    THEN
      BEGIN
      AttackTime:=Duration*AttackTime;
      DecayTime:=DecayTime*Duration;
      IF AttackTime<=.05 THEN AttackTime:=Duration-DecayTime-.01;
      END;
	
  ScFreq:=Freq*MAG;
  DecayLength:=1000/Freq;
  IF Switch1=0 THEN Noise:=.1;
  Index1:=7.5*IMult/LogFreq;
  Index2:=5/SQRT(Freq);
  Index3:=IMult*30*(8.5-LogFreq)/Freq;
END;
	
Decay:=Switch1+EXPEN[DecayCall](Switch2,MAG*20/DecayLength,DecayFunc);
ENV:=Switch2+LINEN[20](Switch1,AttackTime/20,DecayTime/20,Duration/20,AmpFunc,Reset1:=0);
Ramp:=Amp1+NOSCIL[RampCall](Amp2-Amp1,20*MAG/Duration,AttackFunc);
Gliss:=Freq+EXPEN[GlissCall](OtherFreq-Freq,20*MAG/GlissLength,GlissFunc);
FLutter:=RANDI[VibCall](1,200*Mag);
Vibrato:=NOSCIL[VibCall](ENV,Vibrate*MAG*20,SineWave);
Att:=1-EXPEN[20](1,MAG*640,AttackFunc);
	
NewMag:=(1+Flutter*.005)*(1+Vibrato*VibAmp)*(1+RANDI(Noise*Att,2000*Mag))*Gliss*Mag;
	
Mod1:=NOSCIL(Decay*ScFreq*(Att+Index1),NewMag,Sinewave);
Mod2:=NOSCIL(Decay*ScFreq*(Att+Index2),4*NewMag,Sinewave);
Mod3:=NOSCIL(Decay*ScFreq*(Att+Index3),3*NewMag,Sinewave);
Snd:=ZOSCIL(Decay*ENV*Ramp,NewMag+Mod1+Mod2+Mod3,Sinewave);
OUTA:=OUTA+Snd*0.5;
END;
at the park, copyright Patte Wood at home
thennow

This instrument required about 60 seconds of computing on a PDP-10 (a $250,000 minicomputer) for 1 second of sound (our normal sampling rate was 12800). Since the PDP was massively time-shared, 60 seconds of computing could involve many minutes of sitting around watching AI scientists play Space War. Mus10 was an extension of Music V for the PDP-10 family of computers. To give a feel for how one worked in those days, here's a brief quote from the Mus10 manual (by Tovar and Leland Smith, May 1977):

The following generates  1 second of a  440 Hz sine wave  followed by
1/2 sec. of a  660Hz sine wave. The output goes to a file, MUSIC.MSB,
which is written on DSKM.  

COMMENT Fill array with sine wave;
ARRAY SINETABLE[511];
FOR I:=0 STEP 1 UNTIL 511 DO SINETABLE[I]:=SIN(2*PI/512);

INSTRUMENT SINE;
  COMMENT Generate simple sine wave.  P4 = Amplitude, P3 = frequency;
  OUTA:=OUTA+OSCIL(P4,P3*MAG,SINETABLE);
  END;

COMMENT Now, generate the sound;
PLAY ;
  SIMP 0, 1, 440, 1000;
  SIMP 1, 1/2, 660, 1000;
  FINISH;

The computation involved was considered so burdensome, that the names of the main users were posted in the AI lab halls, apparently to try to get us to go away. I was normally the primary user (in terms of computrons) for the entire lab, and I had no intention of going away. In the Samson box world, this (in its initial "chorus" version) was:

Instrument(Violin);
RECORD_POINTER(seg) nullfunc;
INTEGER ARRAY gens[1:4],indgens[1:6], GensA[1:4],AmpGens[1:2];
					! synthesizer addresses;
REAL ARRAY ratsA[1:4],Indrats[1:6],ratsB[1:4],AmpRats[1:2];
					! envelope data;
INTEGER ModGens1Sum,i,FuncOffSet,k,GenOutLoc,GenInLoc,ModGens2Sum,x1,x2;

Pars(<(InsName,Beg,Dur,Freq,Amp,Function AmpFunc,Function IndFunc,IndMult,
	SkewMult,Nothing,PcRev,No11,No12,No13,Function SkewFunc)>);
					! the parameters of this instrument;

Dbugit(Pns);				! debugging aid;
GenOutLoc:=CASE (Pn[1] MOD 4) OF (Outma,Outmb,Outmc,Outmd);
					! OUTMA is channel 1, OUTMB channel 2, etc;
if freq>srate/3 then return;		! note too high, so leave it out;
x1:=3;					! modulating frequency checks;
x2:=4;					! (we want them less than srate/2);
If x1*freq>srate/2 Then x1:=1;
If x2*freq>srate/2 then x2:=1;
amp:=Amp/2;				! two carriers, so halve the amplitude;

waiter(Beg);				! wait for the beginning of the note;

indRats[1]:=(x1*Freq*IndMult*((8.5-log(freq))/(3+(freq/1000)))*4/srate) MIN .999;
indRats[2]:=(x2*Freq*IndMult*(1/(freq^.5))*4/srate) MIN .999;
indRats[3]:=(freq*IndMult*(5/log(freq))*4/srate) MIN .999;
indrats[4]:=indrats[1]; indrats[5]:=indrats[2]; indrats[6]:=indrats[3];

ratsA[1]:=x1; ratsA[2]:=x2;     ratsA[3]:=1;     ratsA[4]:=1;	
ratsB[1]:=x1+.002; ratsB[2]:=x2+.003;     ratsB[3]:=1.002;     ratsB[4]:=1;	
					! this is the skewing for the chorus effect;
Gens[1]:=Osc(Pns,ModGens1Sum);		! now set up the oscillators;
Gens[2]:=Osc(Pns,ModGens1Sum);
Gens[3]:=Osc(Pns,ModGens1Sum);
Gens[4]:=Osc(Pns,genInLoc,ModGens1Sum);	! carrier 1;

GensA[1]:=Osc(Pns,ModGens2Sum);
GensA[2]:=Osc(Pns,ModGens2Sum);
GensA[3]:=Osc(Pns,ModGens2Sum);
GensA[4]:=Osc(Pns,genInLoc,ModGens2Sum);! carrier 2;

indgens[1]:=gens[1];   indgens[2]:=gens[2];  indgens[3]:=gens[3];
indgens[4]:=gensA[1];   indgens[5]:=gensA[2];  indgens[6]:=gensA[3];
					! set up envelope addressing;

ModSig(Pns,GenOutLoc,GenInLoc,1-pcRev);	! send signal to DACs;
ModSig(Pns,RevIn,GenInLoc,pcRev);	! and signal to reverberator;

AmpGens[1]:=Gens[4]; AmpGens[2]:=GensA[4]; AmpRats[1]:=1; AmpRats[2]:=1;
					! now add the envelopes;
AddArrEnv(Pns,AmpGens,2,"A",0,Amp/2,AmpFunc,AmpRats);
AddArrEnv(Pns,IndGens,6,"A",0,1,IndFunc,Indrats);
AddArrEnv(Pns,Gens,4,"F",freq,Freq*skewmult,skewfunc,ratsA,
	5,.011,.011,nullfunc,6,.017,.017,nullfunc,0,0);
AddArrEnv(Pns,GensA,4,"F",freq,Freq*skewmult,skewfunc,ratsA,
	6,.010,.010,nullfunc,5,.017,.017,nullfunc,1,0);
End!Instrument(Pns);			! deallocation;

The Sambox version eventually became incredibly complicated, mainly to try to handle note list problems in the instrument. The Samson box could run about 5 or 6 of these in "real-time", similar to a modern-day 500 MHz Pentium running CLM. The parallel in the Sambox world to the SIMP example above is (this is taken from SAMBOX.BIL, November 1984):

    Instrument(Simp);
    Integer Gen1;
    Gen1:=Osc(Pns,OutA,Zero,SineMode,0,0,Pn[3]);
    AddEnv(Pns,Gen1,"A",0,Pn[4],Pf[5]);
    End_Instrument(Pns);

The Common Lisp version of this is:

(definstrument simp (start-time duration frequency amplitude
                     &optional (amp-env '(0 0 50 1 100 0)))
  (multiple-value-bind (beg end) (times->samples start-time duration)
    (let ((s (make-oscil frequency))
          (amp (make-env amp-env :scaler amplitude :duration duration)))
      (run
       (loop for i from beg below end do
         (outa i (* (env amp) (oscil s))))))))

In Common Lisp, the fm-violin became (fm.html, 1989):

(definstrument violin (beg end frequency amplitude fm-index)
  (let* ((frq-scl (hz->radians frequency))
         (maxdev (* frq-scl fm-index))
         (index1 (* maxdev (/ 5.0 (log frequency))))
         (index2 (* maxdev 3.0 (/ (- 8.5 (log frequency)) (+ 3.0 (/ frequency 1000)))))
         (index3 (* maxdev (/ 4.0 (sqrt frequency))))
         (carrier (make-oscil frequency))
         (fmosc1 (make-oscil frequency))
         (fmosc2 (make-oscil (* 3 frequency)))
         (fmosc3 (make-oscil (* 4 frequency)))
         (ampf  (make-env '(0 0 25 1 75 1 100 0) :scaler amplitude))
         (indf1 (make-env '(0 1 25 .4 75 .6 100 0) :scaler index1))
         (indf2 (make-env '(0 1 25 .4 75 .6 100 0) :scaler index2))
         (indf3 (make-env '(0 1 25 .4 75 .6 100 0) :scaler index3))
         (pervib (make-triangle-wave :frequency 5 :amplitude (* .0025 frq-scl)))
         (ranvib (make-randi :frequency 16 :amplitude (* .005 frq-scl)))
         (vib 0.0))
    (run
     (loop for i from beg to end do
       (setf vib (+ (triangle-wave pervib) (randi ranvib)))
       (outa i (* (env ampf)
                  (oscil carrier
                         (+ vib 
                            (* (env indf1) (oscil fmosc1 vib))
                            (* (env indf2) (oscil fmosc2 (* 3.0 vib)))
                            (* (env indf3) (oscil fmosc3 (* 4.0 vib)))))))))))

or in its actual (non-simplified) form:

(defun bit20 (x)			;Samson box modifier got 20 bit int interpreted as fraction 
  (if (>= x (expt 2 19))                ;(keep fm-violin compatible with old note lists)
      (float (/ (- x (expt 2 20)) (expt 2 19)))
    (float (/ x (expt 2 19)))))

(defun make-frobber-function (beg end frobl)
  (let ((result (list beg))
	(val (bit20 (cadr frobl))))
    (loop for x in frobl by #'cddr and 
              y in (cdr frobl) by #'cddr do
      (when (and (>= x beg)
		 (<= x end))
	(push val result)
	(push x result)
	(setf val (bit20 y))))
    (push val result)
    (push end result)
    (push val result)
    (nreverse result)))

(definstrument fm-violin 
  (startime dur frequency amplitude &key
	    (fm-index 1.0)
	    (amp-env '(0 0  25 1  75 1  100 0))
	    (periodic-vibrato-rate 5.0) 
            (random-vibrato-rate 16.0)
	    (periodic-vibrato-amplitude 0.0025) 
            (random-vibrato-amplitude 0.005)
	    (noise-amount 0.0) (noise-freq 1000.0)
	    (ind-noise-freq 10.0) (ind-noise-amount 0.0)
	    (amp-noise-freq 20.0) (amp-noise-amount 0.0)
	    (gliss-env '(0 0  100 0)) (glissando-amount 0.0) 
	    (fm1-env '(0 1  25 .4  75 .6  100 0)) 
            (fm2-env '(0 1  25 .4  75 .6  100 0)) 
            (fm3-env '(0 1  25 .4  75 .6  100 0))
	    (fm1-rat 1.0) (fm2-rat 3.0)	 (fm3-rat 4.0)                    
	    (fm1-index nil) (fm2-index nil) (fm3-index nil)
	    (base nil) (frobber nil)
	    (reverb-amount 0.01)
	    (index-type :violin)
	    (degree nil) (distance 1.0) (degrees nil)
	    (no-waveshaping nil) (denoise nil)
	    (denoise-dur .1) (denoise-amp .005)
	    &allow-other-keys)
  (if (> (abs amplitude) 1.0) 
      (setf amplitude (clm-cerror ".1?" .1 #'numberp "amplitude = ~A?" amplitude)))
  (if (<= (abs frequency) 1.0) 
      (setf frequency (clm-cerror "440.0?" 440.0 #'numberp "frequency = ~A?" frequency)))
  (let* ((beg (floor (* startime *srate*)))
	 (end (+ beg (floor (* dur *srate*))))
	 (frq-scl (hz->radians frequency))
	 (modulate (not (zerop fm-index)))
	 (maxdev (* frq-scl fm-index))
	 (vln (not (eq index-type :cello)))
	 (logfreq (log frequency))
	 (sqrtfreq (sqrt frequency))
	 (index1 (or fm1-index (min pi (* maxdev (/ (if vln 5.0 7.5) logfreq)))))
	 (index2 (or fm2-index (min pi (* maxdev 3.0 (if vln 
							     (/ (- 8.5 logfreq) (+ 3.0 (* frequency .001)))
							   (/ 15.0 sqrtfreq))))))
	 (index3 (or fm3-index (min pi (* maxdev (/ (if vln 4.0 8.0) sqrtfreq)))))

	 (easy-case (and (not no-waveshaping)
			 (zerop noise-amount)
			 (eq fm1-env fm2-env)
			 (eq fm1-env fm3-env)
			 (zerop (- fm1-rat (floor fm1-rat)))
			 (zerop (- fm2-rat (floor fm2-rat)))
			 (zerop (- fm3-rat (floor fm3-rat)))
			 (zerop (nth-value 1 (floor fm2-rat fm1-rat)))
			 (zerop (nth-value 1 (floor fm3-rat fm1-rat)))))
	 (coeffs (and easy-case modulate
	 	      (partials->polynomial
	 	       (list fm1-rat index1
	 		     (floor fm2-rat fm1-rat) index2
	 		     (floor fm3-rat fm1-rat) index3))))
	 ;; that is, we're doing the polynomial evaluation using fm1osc running at fm1-rat * frequency
	 ;; so everything in the polynomial table should be in terms of harmonics of fm1-rat
	 
	 (norm (or (and easy-case modulate 1.0) index1))
	 
	 (carrier (make-oscil frequency))
	 (fmosc1  (and modulate (make-oscil (* fm1-rat frequency))))
	 (fmosc2  (and modulate (or easy-case (make-oscil (* fm2-rat frequency)))))
	 (fmosc3  (and modulate (or easy-case (make-oscil (* fm3-rat frequency)))))
	 (ampf  (make-env 
                  (if denoise
                       (reduce-amplitude-quantization-noise amp-env dur amplitude denoise-dur denoise-amp) 
                     amp-env)
	          amplitude :base base :duration dur))
	 (indf1 (and modulate (make-env fm1-env norm :duration dur)))
	 (indf2 (and modulate (or easy-case (make-env fm2-env index2 :duration dur))))
	 (indf3 (and modulate (or easy-case (make-env fm3-env index3 :duration dur))))
	 (frqf (make-env gliss-env (* glissando-amount frq-scl) :duration dur))
	 (pervib (make-triangle-wave periodic-vibrato-rate (* periodic-vibrato-amplitude frq-scl)))
	 (ranvib (make-rand-interp random-vibrato-rate (* random-vibrato-amplitude frq-scl)))
	 (fm-noi (if (and (/= 0.0 noise-amount)
			  (null frobber))
		     (make-rand noise-freq (* pi noise-amount))))
	 (ind-noi (if (and (/= 0.0 ind-noise-amount) (/= 0.0 ind-noise-freq))
		      (make-rand-interp ind-noise-freq ind-noise-amount)))
	 (amp-noi (if (and (/= 0.0 amp-noise-amount) (/= 0.0 amp-noise-freq))
		      (make-rand-interp amp-noise-freq amp-noise-amount)))
	 (frb-env (if (and (/= 0.0 noise-amount) frobber)
		      (make-env (make-frobber-function startime (+ startime dur) frobber) :duration dur
				:base 0	:scaler (* two-pi noise-amount))))
	 (vib 0.0) 
	 (modulation 0.0)
	 (loc (make-locsig :degree (or degree degrees (random 90.0)) 
                :reverb reverb-amount :distance distance))
	 (fuzz 0.0)
	 (ind-fuzz 1.0)
	 (amp-fuzz 1.0))
    (run
     (loop for i from beg to end do
       (if (/= 0.0 noise-amount)
	   (if (null frobber)
	       (setf fuzz (rand fm-noi))
	     (setf fuzz (env frb-env))))
       (setf vib (+ (env frqf) (triangle-wave pervib) (rand_interp ranvib)))
       (if ind-noi (setf ind-fuzz (+ 1.0 (rand-interp ind-noi))))
       (if amp-noi (setf amp-fuzz (+ 1.0 (rand-interp amp-noi))))
       (if modulate
	   (if easy-case
	       (setf modulation
		 (* (env indf1) 
		    (polynomial coeffs (oscil fmosc1 vib)))) ;(* vib fm1-rat)??
	     (setf modulation
	       (+ (* (env indf1) (oscil fmosc1 (+ (* fm1-rat vib) fuzz)))
		  (* (env indf2) (oscil fmosc2 (+ (* fm2-rat vib) fuzz)))
		  (* (env indf3) (oscil fmosc3 (+ (* fm3-rat vib) fuzz)))))))
       (locsig loc i
	     (* (env ampf) amp-fuzz
		(oscil carrier (+ vib (* ind-fuzz modulation)))))))))

which is very similar to the Scheme version (v.scm). And I just found this out on the net; I'm no csound expert, so I merely quote what I find:

;ORC
; edited by R. Pinkston, modified for use with MIDI2CS by R. Borrmann
;
;==========================================================================;
;                Schottstaedt FM String Instrument from Dodge              ;
;                                                                          ;
;p4 = amp p5 = pch p6 = rise p7 = dec p8 = vibdel p9 = vibwth p10 = vibrte ;
;==========================================================================;
;        sr      =       44100
;        kr      =       4410
;        ksmps   =       10
;        nchnls  =       1
;
;                instr   1

par
  p_maxamplitude 32000
  p_cps
endpar

        iamp    =       p4

        irise   = .2    ;p6
        idec    = .2    ;p7
        ivibdel = .75   ;p8
        ivibwth = .03   ;p9
        ivibrte = 5.5   ;p10

        ifc     =       p5
        ifm1    =       ifc
        ifm2    =       ifc*3
        ifm3    =       ifc*4
        indx1   =       7.5/log(ifc)    ;range from ca 2 to 1
        indx2   =       15/sqrt(ifc)    ;range from ca 2.6 to .5
        indx3   =       1.25/sqrt(ifc)  ;range from ca .2 to .038
        kvib    init    0 

                timout  0,ivibdel,transient  ;delays vibrato for p8 seconds
        kvbctl  linen   1,.5,p3-ivibdel,.1   ;vibrato control envelope
        krnd    randi   .0075,15        ;random deviation in vib width 
        kvib    oscili  kvbctl*ivibwth+krnd,ivibrte*kvbctl,1 ;vibrato generator
               
transient:
        timout  .2,p3,continue          ;execute for .2 secs only
        ktrans  linseg  1,.2,0,1,0      ;transient envelope 
        anoise  randi   ktrans,.2*ifc   ;noise... 
        attack  oscil   anoise,2000,1   ;...centered around 2kHz

continue: 
        amod1   oscili  ifm1*(indx1+ktrans),ifm1,1
        amod2   oscili  ifm2*(indx2+ktrans),ifm2,1
        amod3   oscili  ifm3*(indx3+ktrans),ifm3,1
        asig    oscili  iamp,(ifc+amod1+amod2+amod3)*(1+kvib),1
        asig    linen   asig+attack,irise,p3,idec
;                out     asig
; 
;                endin
        aright  = asig
        aleft   = asig

There's a C/CLM version of this instrument in sndlib.html. The body of the fm-violin in C/CLM is:

      if (noise_amount != 0.0) fuzz = mus_rand(fmnoi,0.0);
      if (frqf) vib = mus_env(frqf); else vib = 0.0;
      vib += mus_triangle_wave(pervib, 0.0) + 
             mus_rand_interp(ranvib, 0.0);
      if (easy_case)
        modulation = mus_env(indf1) * 
                     mus_polynomial(coeffs, mus_oscil(fmosc1, vib, 0.0), npartials);
      else
        modulation = mus_env(indf1) * mus_oscil(fmosc1, (fuzz + fm1_rat * vib), 0.0) +
                     mus_env(indf2) * mus_oscil(fmosc2, (fuzz + fm2_rat * vib), 0.0) +
                     mus_env(indf3) * mus_oscil(fmosc3, (fuzz + fm3_rat * vib), 0.0);
      mus_locsig(loc, i, mus_env(ampf) *
                         mus_oscil(carrier, vib + indfuzz * modulation, 0.0));

And here is the Ruby version, written by Michael Scholz (see examp.rb):

#
# fm_violin([start=0.0[, dur=1.0[, freq=440.0[, amp=0.3[, *args]]]]])
#

def fm_violin(start = 0.0, dur = 1.0, freq = 440.0, amp = 0.3, *args)
  include Math;			# PI

  usage = "fm_violin([start=0.0[, dur=1.0[, freq=440.0[, amp=0.3[, *args]]]]])

	[:fm_index, 1.0]
	[:amp_env, [0, 0, 25, 1, 75, 1, 100, 0]]
	[:periodic_vibrato_rate, 5.0]
	[:random_vibrato_rate, 16.0]
	[:periodic_vibrato_amp, 0.0025]
	[:random_vibrato_amp, 0.005]
	[:noise_amount, 0.0]
	[:noise_freq, 1000.0]
	[:ind_noise_freq, 10.0]
	[:ind_noise_amount, 0.0]
	[:amp_noise_freq, 20.0]
	[:amp_noise_amount, 0.0]
	[:gliss_env, [0, 0,  100, 0]]
	[:gliss_amount, 0.0]
	[:fm1_env, [0, 1, 25, 0.4, 75, 0.6, 100, 0]]
	[:fm2_env, [0, 1, 25, 0.4, 75, 0.6, 100, 0]]
	[:fm3_env, [0, 1, 25, 0.4, 75, 0.6, 100, 0]]
	[:fm1_rat, 1.0]
	[:fm2_rat, 3.0]
	[:fm3_rat, 4.0]
	[:fm1_index, false]
	[:fm2_index, false]
	[:fm3_index, false]
	[:base, 1.0]
	[:reverb_amount, 0.01]
	[:index_type, :violin]
	[:degree, false]
	[:distance, 1.0]
	[:degrees, false]

  Ruby: fm_violin(0, 1, 440, .1, [[:fm_index, 2.0]])
 Scheme: (fm-violin 0 1 440 .1 :fm-index 2.0)\n\n";

  fm_index = (args.assoc(:fm_index)[1] rescue 1.0);
  amp_env = (args.assoc(:amp_env)[1] rescue [0, 0, 25, 1, 75, 1, 100, 0]);
  periodic_vibrato_rate = (args.assoc(:periodic_vibrato_rate)[1] rescue 5.0);
  random_vibrato_rate = (args.assoc(:random_vibrato_rate)[1] rescue 16.0);
  periodic_vibrato_amp = (args.assoc(:periodic_vibrato_amp)[1] rescue 0.0025);
  random_vibrato_amp = (args.assoc(:random_vibrato_amp)[1] rescue 0.005);
  noise_amount = (args.assoc(:noise_amount)[1] rescue 0.0);
  noise_freq = (args.assoc(:noise_freq)[1] rescue 1000.0);
  ind_noise_freq = (args.assoc(:ind_noise_freq)[1] rescue 10.0);
  ind_noise_amount = (args.assoc(:ind_noise_amount)[1] rescue 0.0);
  amp_noise_freq = (args.assoc(:amp_noise_freq)[1] rescue 20.0);
  amp_noise_amount = (args.assoc(:amp_noise_amount)[1] rescue 0.0);
  gliss_env = (args.assoc(:gliss_env)[1] rescue [0, 0,  100, 0]);
  gliss_amount = (args.assoc(:gliss_amount)[1] rescue 0.0);
  fm1_env = (args.assoc(:fm1_env)[1] rescue [0, 1, 25, 0.4, 75, 0.6, 100, 0]);
  fm2_env = (args.assoc(:fm2_env)[1] rescue [0, 1, 25, 0.4, 75, 0.6, 100, 0]);
  fm3_env = (args.assoc(:fm3_env)[1] rescue [0, 1, 25, 0.4, 75, 0.6, 100, 0]);
  fm1_rat = (args.assoc(:fm1_rat)[1] rescue 1.0);
  fm2_rat = (args.assoc(:fm2_rat)[1] rescue 3.0);
  fm3_rat = (args.assoc(:fm3_rat)[1] rescue 4.0);
  fm1_index = (args.assoc(:fm1_index)[1] rescue false);
  fm2_index = (args.assoc(:fm2_index)[1] rescue false);
  fm3_index = (args.assoc(:fm3_index)[1] rescue false);
  base = (args.assoc(:base)[1] rescue 1.0);
  reverb_amount = (args.assoc(:reverb_amount)[1] rescue 0.01);
  index_type = (args.assoc(:index_type)[1] rescue :violin);
  degree = (args.assoc(:degree)[1] rescue false);
  distance = (args.assoc(:distance)[1] rescue 1.0);
  degrees = (args.assoc(:degrees)[1] rescue false);

  srate = (srate() rescue $rbm_srate);
  chans = (channels() rescue $rbm_channels);
  beg = (srate * start).round;
  len = (srate * dur).round;
  frq_scl = hz2radians(freq);
  modulate = fm_index.nonzero?;
  maxdev = frq_scl * fm_index;
  vln = (not (index_type == :cello))
  logfreq = log(freq);
  sqrtfreq = sqrt(freq);
  index1 = (fm1_index or [PI, maxdev * (vln ? 5.0 : 7.5) / logfreq].min);
  index2 = (fm2_index or [PI, maxdev * 3.0 * 
	      (vln ? ((8.5 - logfreq) / (3.0 + freq * 0.001)) : (15.0 / sqrtfreq))].min);
  index3 = (fm3_index or [PI, maxdev * (vln ? 4.0 : 8.0) / sqrtfreq].min);
  easy_case = (noise_amount.zero? and
	       (fm1_env == fm2_env) and 
	       (fm1_env == fm3_env) and 
	       (fm1_rat - fm1_rat.floor).zero? and 
	       (fm2_rat - fm2_rat.floor).zero? and 
	       (fm3_rat - fm3_rat.floor).zero?);
  coeffs = (easy_case and modulate and 
	    partials2polynomial([fm1_rat, index1, 
				  (fm2_rat / fm1_rat).floor, index2,
				  (fm3_rat / fm1_rat).floor, index3]));
  norm = ((easy_case and modulate and 1.0) or index1);
  carrier = make_oscil(freq);
  fmosc1 = (modulate and make_oscil(fm1_rat * freq));
  fmosc2 = (modulate and (easy_case or make_oscil(fm2_rat * freq)));
  fmosc3 = (modulate and (easy_case or make_oscil(fm3_rat * freq)));
  ampf = make_env(amp_env, amp, dur, 0.0, base);
  indf1 = (modulate and make_env(fm1_env, norm, dur));
  indf2 = (modulate and (easy_case or make_env(fm2_env, index2, dur)));
  indf3 = (modulate and (easy_case or make_env(fm3_env, index3, dur)));
  frqf = make_env(gliss_env, gliss_amount * frq_scl, dur);
  pervib = make_triangle_wave(periodic_vibrato_rate, periodic_vibrato_amp *  frq_scl);
  ranvib = make_rand_interp(random_vibrato_rate, random_vibrato_amp * frq_scl);
  fm_noi = (noise_amount.nonzero? and make_rand(noise_freq, PI * noise_amount));
  ind_noi = ((ind_noise_amount.nonzero? and ind_noise_freq.nonzero?) and 
	     make_rand_interp(ind_noise_freq, ind_noise_amount));
  amp_noi = ((amp_noise_amount.nonzero? and amp_noise_freq.nonzero?) and
	     make_rand_interp(amp_noise_freq, amp_noise_amount));
  vib = 0.0;
  modulation = 0.0;
  # make_locsig(degree=0.0, distance=1.0, reverb=0.0, output, revout, chans=1, type=Mus_linear)
  # Ruby's rand() is shadowed by CLM's rand(), that's why mus_random().abs.
  loc = make_locsig((degree or degrees or mus_random(90.0).abs), 
		    distance, reverb_amount, false, false, chans);
  fuzz = 0.0;
  ind_fuzz = 1.0;
  amp_fuzz = 1.0;
  out_data = make_vct(len);

  vct_map!(out_data,
	   lambda { | |
	     fuzz = rand(fm_noi) if noise_amount.nonzero?;
	     vib = env(frqf) + triangle_wave(pervib) + rand_interp(ranvib);
	     ind_fuzz = 1.0 + rand_interp(ind_noi) if ind_noi;
	     amp_fuzz = 1.0 + rand_interp(amp_noi) if amp_noi;

	     if(modulate)
	       if(easy_case)
		 modulation = env(indf1) * polynomial(coeffs, oscil(fmosc1, vib));
	       else
		 modulation = env(indf1) * oscil(fmosc1, fm1_rat * vib + fuzz) +
		   env(indf2) * oscil(fmosc2, fm2_rat * vib + fuzz) +
		   env(indf3) * oscil(fmosc3, fm3_rat * vib + fuzz);
	       end
	     end

	     env(ampf) * amp_fuzz * oscil(carrier, vib + ind_fuzz * modulation);
	   });

  if(chans == 2)
    mix_vct(vct_scale!(vct_copy(out_data), locsig_ref(loc, 1)), beg, $rbm_snd, 1, false);
    mix_vct(vct_scale!(out_data, locsig_ref(loc, 0)), beg, $rbm_snd, 0, false);
  else
    mix_vct(out_data, beg, $rbm_snd, 0, false);
  end
rescue
  die(usage + "fm_violin()");
end

ws

with-sound provides a way to package up a bunch of instrument calls into a new sound file, and open that file in Snd when the computation is complete. To hear (and see) the fm-violin, for example, we first load with-sound and the instrument:

;; Scheme:
(load "ws.scm")
(load "v.scm")
# Ruby:
load("ws.rb")
load("v.rb")
\ Forth:
"clm.fs" file-eval
"clm-ins.fs" file-eval

Then call with-sound, accepting the default sound file settings, with one fm-violin note at A4 (440 Hz):

(with-sound ()
  (fm-violin 0 1 440 .1))

with_sound() do 
  fm_violin_rb(0, 1, 440, 0.1) 
end
0 1 440 0.1 ' fm-violin with-sound


The body of with-sound can hold any number of notes, or any arbitrary code. For example, say we want to hear an arpeggio from the fm-violin:

(with-sound ()
  (do ((i 0 (+ i 1)))
      ((= i 4))                ; 4 notes in all
    (fm-violin (* i 0.25)      ; notes 1/4 secs apart
               0.25            ; each note 1/4 sec long
               (* 220.0 (+ i 1)); go up by 220 Hz on each note
               .1)))           ; all notes .1 amp

with-sound opens an output object, either a sound file, or a vector: (*output*), and optionally a reverb output object: *reverb*. Each instrument uses out-any to add its sounds to the *output* results. with-sound next sets up a variety of variables describing the current output, and establishes an environment where various problems can be handled nicely (in Scheme, a dynamic-wind with various debugging hooks). Then the with-sound body is evaluated, presumably producing sound. Once evaluated, the outputs are closed, and if reverb is requested, the reverberator is run. Once complete, with-sound prints out statistics (if :statistics is #t), scales the result (if :scale-to), and plays it (if :play is #t). Then, if the output is a sound file (and :to-snd is #t), with-sound opens it in Snd, first closing any previous sound with the same name (this makes it easier to call with-sound over and over while trying out some patch). with-sound returns its :output argument.

  with-sound
          (output *clm-file-name*)               ; output file name ("test.snd")
	  (channels *clm-channels*)              ; channels in output (1)
          (srate *clm-srate*)                    ; output sampling rate (44100)
	  (sample-type *clm-sample-type*)        ; output sample data type (mus-bfloat or mus-lshort)
	  (header-type *clm-header-type*)        ; output header type (mus-next or mus-aifc)
	  (comment #f)                           ; any comment to store in the header (a string)
	  (verbose *clm-verbose*)                ; if #t, print out some info
	  (reverb *clm-reverb*)                  ; reverb instrument (jc-reverb)
	  (reverb-data *clm-reverb-data*)        ; arguments passed to the reverb
	  (reverb-channels *clm-reverb-channels*); chans in the reverb intermediate file
          (revfile *clm-reverb-file-name*)       ; reverb intermediate output file name ("test.rev")
	  (continue-old-file #f)                 ; if #t, continue a previous computation
	  (statistics *clm-statistics*)          ; if #t, print info at end of with-sound (compile time, maxamps)
	  (scaled-by #f)                         ; is a number, scale output by that amp
	  (scaled-to #f)                         ; if a number, scale the output to peak at that amp
	  (play *clm-play*)                      ; if #t, play the sound automatically
	  (to-snd *to-snd*)                      ; if #t, open the output file in Snd

The with-sound syntax may look sightly odd; we include the arguments in the first list, then everything after that is evaluated as a note list.

(with-sound (:srate 44100 :channels 2 :output "test.snd")
  (fm-violin 0 1 440 .1)
  (fm-violin 1 1 660 .1))

produces a sound file with two fm-violin notes; the sound file is named "test.snd", is stero, and has a sampling rate of 44100.

(with-sound (:reverb jc-reverb :statistics #t :play #t) 
  (fm-violin 0 1 440 .1 :reverb-amount .3))

produces one fm-violin note, heavily reverberated, and plays it, printing this info:

> (with-sound (:reverb jc-reverb :statistics #t :play #t) 
    (fm-violin 0 1 440 .1 :reverb-amount .3))
test.snd:
maxamp: 0.3038
rev max: 0.0300
compute time: 0.030

It's often hard to predict how loud a set of notes is going to be, so we can use "scaled-to" to set its final amplitude:

(with-sound (:scale-to .5) 
  (do ((i 0 (+ i 1))) ((= i 10)) (fm-violin 0 i 440.0 (random 1.0))))

Here are examples in Ruby and Forth:

:with_sound(:channels, 2, :play, false, :statistics, true) do 
  fm_violin_rb(0, 1, 440, 0.1); 
  fm_violin_rb(1, 1, 660, 0.1);
  end
# filename: "test.snd"
#    chans: 2, srate: 22050
#   length: 2.000 (44100 framples)
#   format: big endian short (16 bits) [Sun/Next]
#     real: 2.248  (utime 2.240, stime 0.000)
#    ratio: 1.12  (uratio 1.12)
#  max out: [0.098, 0.024]
#<With_Snd: output: "test.snd", channels: 2, srate: 22050>

and in Forth:

snd> 0.0 1.0 330.0 0.5 ' simp :play #f :channels 2 with-sound
\ filename: test.snd
\    chans: 2, srate: 22050
\   format: little endian float (32 bits) [Sun/Next]
\   length: 1.000  (22050 framples)
\     real: 0.162  (utime 0.267, stime 0.000)
\    ratio: 0.16  (uratio 0.27)
\ maxamp A: 0.500 (near 0.680 secs)
\ maxamp B: 0.000 (near 0.000 secs)
\  comment: Written on Fri Jul 14 07:41:47 PDT 2006 by bil at cat using clm (fth) of 30-Jun-06

The default values listed above (*clm-srate* and friends) are set in ws.scm:

(define *clm-file-name*          "test.snd")
(define *clm-srate*              *default-output-srate*)       ; 44100
(define *clm-channels*           *default-output-chans*)       ; 1
(define *clm-sample-type*        *default-output-sample-type*) ; mus-lfloat
(define *clm-header-type*        *default-output-header-type*) ; mus-next
(define *clm-verbose*            #f)
(define *clm-play*               #f)
(define *clm-statistics*         #f)
(define *clm-reverb*             #f)
(define *clm-reverb-channels*    1)
(define *clm-reverb-data*        ())
(define *clm-reverb-file-name*   "test.rev")
(define *clm-table-size*         512)
(define *clm-default-frequency*  0.0)
(define *clm-file-buffer-size*   65536)
(define *clm-locsig-type*        mus-interp-linear)
(define *clm-clipped*            #t)
(define *clm-array-print-length* *print-length*)  ; 12
(define *clm-player*             #f)
(define *clm-notehook*           #f)
(define *to-snd*                 #t)
(define *reverb*                 #f)
(define *output*                 #f)
(define *clm-delete-reverb*      #f)

You can set any of these to permanently change with-sound's defaults

> (set! *clm-file-name* "test.aif")
#<unspecified>
> (set! *clm-srate* 44100)
#<unspecified>
> (set! *clm-channels* 2)
#<unspecified>
> (set! *clm-header-type* mus-aifc)
#<unspecified>
> (set! *clm-sample-type* mus-bfloat)
#<unspecified>
> (with-sound ()  (fm-violin 0 1 440 .1))test.aif:
"test.aif"
> (srate "test.aif")
44100
> (channels "test.aif")
2

To display the entire sound automatically (independent of after-open-hook), use with-full-sound:

(define-macro (with-full-sound args . body)
  `(let ((snd (with-sound-helper (lambda () ,@body) ,@args)))
     (set! (x-bounds *snd-opened-sound*) (list 0.0 (/ (framples *snd-opened-sound*) (srate *snd-opened-sound*))))
     snd))

Since with-sound returns the new sound's file name, we save that, get the new sound's index (*snd-opened-sound*), and set the x-bounds to display the full sound, then return the file name. You could obviously customize this any way you like. To continue adding notes to an existing file, set 'continue-old-file':

(with-sound (:continue-old-file #t) (fm-violin 0 1 440 .1))

The "notehook" argument is a function called each time an instrument is called:

> (with-sound (:notehook (lambda (name . args) 
                          (snd-print (format #f "~%;~A: ~A" name (caddr args)))))
   (fm-violin 0 1 440 .1) 
   (fm-violin 1 1 660 .1))
;fm-violin: 440
;fm-violin: 660
"test.snd"

The arguments passed to the notehook function are the current instrument name (a string) and all its arguments. definstrument implements the notehook feature. The "output" argument can be a vector as well as a filename:

(with-sound (:output (make-float-vector 44100 0.0)) (fm-violin 0 1 440 .1))

See fade.scm, snd-test.scm.

definstrument

definstrument is very much like define*, but with added code to support notehook and (for Common Music) *definstrument-hook*. It uses old CL-style documentation strings. An instrument that wants to cooperate fully with with-sound and Common Music has the form:

(definstrument (ins args)
  (let ...
    (do ((i start (+ i 1)))
        ((= i end))
      (outa i ...))))

definstrument is an extension of define*, so its arguments are handled as optional keyword arguments:

(definstrument (simp beg dur (frequency 440.0) (amplitude 0.1))
  (let ((os (make-oscil frequency)))
     (do ((i 0 (+ i 1))) ((= i dur))
       (outa (+ i beg) (* amplitude (oscil os))))))

(with-sound () 
  (simp 0 10000) 
  (simp 10000 10000 550.0 :amplitude 0.1) 
  (simp 20000 10000 :amplitude 0.2))

You don't have to use definstrument; in the next example we make a Shepard tone by calling the oscils and whatnot directly in the with-sound body:

(define (shepard-tone)
  (let ((x 0.0)
	(incr .000001)               ; sets speed of glissandoes
	(oscs (make-vector 12)))
    (do ((i 0 (+ i 1)))
	((= i 12))
      (set! (oscs i) (make-oscil :frequency 0.0)))
    (with-sound (:srate 44100)
     (do ((samp 0 (+ 1 samp)))
         ((= samp 300000))
       (let ((sum 0.0))
	 (do ((i 0 (+ i 1)))
	     ((= i 12))
	   (let ((loc (+ x (/ i 12.0))))  ; location of current oscil in overall trajectory
	     (if (> loc 1.0) (set! loc (- loc 1.0)))
	     (set! sum (+ sum (* (let ((y (- 4.0 (* 8.0 loc))))
	                           (exp (* -0.5 y y)))  ; Gaussian normal curve as amplitude envelope
			         (oscil (oscs i) 
			                (hz->radians (expt 2.0 (+ 2 (* loc 12.0))))))))))
                                        ;; (- 1.0 loc) to go down
	 (set! x (+ x incr))
	 (outa samp (* .1 sum)))))))
shepard tone spectrum

There are several other versions of with-sound: with-temp-sound, with-mixed-sound, sound-let, clm-load, and the Common Music handles, init-with-sound and finish-with-sound. with-temp-sound and sound-let set up temporary bindings for embedded with-sounds.

sound-let

sound-let is a form of let* that creates temporary sound files within with-sound. Its syntax is a combination of let* and with-sound: with-sound:

(sound-let ((temp-1 () (fm-violin 0 1 440 .1))
            (temp-2 () (fm-violin 0 2 660 .1)
                       (fm-violin .125 .5 880 .1)))
  (granulate-sound temp-1 0 2 0 2)     ;temp-1's value is the name of the temporary file
  (granulate-sound temp-2 1 1 0 2))

This creates two temporary files and passes them along to the subsequent calls on granulate-sound. The first list after the sound file identifier (i.e. after "temp-1" in the example) is the list of with-sound options to be passed along when creating this temporary file. These default to :output with a unique name generated internally, and all other variables are taken from the overall (enclosing) with-sound. The rest of the list is the body of the associated with-sound. The difference between sound-let and an embedded with-sound is primarily that sound-let names and later deletes the temporary files it creates, whereas with-sound leaves its explicitly named output intact (and tries to open it in Snd, which can be confusing in this context). Here's another example:

  (with-sound ()
    (sound-let ((temp-sound () (fm-violin 0 1 440 .1))) ; create temp-sound with an fm-violin note
       (pins 0.0 2.0 temp-sound 1.0 :time-scaler 2.0))  ; stretch it with the pins instrument (clm-ins.scm)
    (fm-violin 1 1 550 .1))                             ; add another fm-violin note
with-temp-sound

with-temp-sound is like sound-let, but does not delete its output file:

  (with-sound ()
    (let ((temp-sound (with-temp-sound () (fm-violin 0 1 440 .1))))
      (clm-expsrc 0 2 temp-sound 2.0 1.0 1.0)))

Here are Ruby examples:

with_sound() do
  clm_mix(with_sound(:output, "hiho.snd") do
            fm_violin_rb(0, 1, 440, 0.1)
          end.output, :scale, 0.5)
end

with_sound() do
  with_mix "s1", %Q{
  sound_let(lambda do fm_violin_rb(0, 1, 440, 0.1) end) do |tmp|
    clm_mix(tmp)
  end
  }
end
with-mixed-sound

with-mixed-sound is a variant of with-sound that creates a "mix" for each note in the notelist. If you move the mixes around, you can write out the new note list via with-mixed-sound->notelist. In multichannel files, all the channels associated with a note are sync'd together, so if you drag one, the others follow. Also, if you click a mix tag, the corresponding note in the notelist is displayed in the status area.

(with-mixed-sound () 
  (fm-violin 0 .1 440 .1) 
  (fm-violin 1 .1 660 .1))

(with-mixed-sound (:channels 2) 
  (fm-violin 0 .1 440 .1 :degree 0) 
  (fm-violin 1 .1 660 .1 :degree 45))

There's also a quick sound file mixer named mus-file-mix:

mus-file-mix outfile infile (outloc 0) (framples) (inloc 0) mixer envs

This function mixes 'infile' into 'outfile' starting at 'outloc' in 'outfile' and 'inloc' in 'infile', mixing 'framples' framples into 'outfile'. 'framples' defaults to the length of 'infile'. If 'mixer', use it to scale the various channels; if 'envs' (an array of envelope generators), use it in conjunction with mixer to scale and envelope all the various ins and outs. 'outfile' can also be a frample->file generator, and 'infile' can be a file->frample generator.

(with-sound () 
  (fm-violin 0 .1 440 .1) 
  (mus-file-mix *output* "oboe.snd") 
  (fm-violin .1 .1 660 .1))
with-marked-sound

with-marked-sound is yet another version of with-sound that adds a mark at the start of each note.

clm-load

clm-load provides a slightly different way to load a notelist. Its first argument is a filename, assumed to be a text file containing notes (equivalent to the body of with-sound). The rest of the arguments to clm-load are the usual with-sound arguments, if any. For example, if we have a file named clm-load-test.clm with these contents:

(fm-violin 0 1 440 .1)
(fm-violin 1 1 660 .1)

then (clm-load "clm-load-test.clm") is the same as (with-sound () (fm-violin 0 1 440 .1) (fm-violin 1 1 660 .1)). Similarly for, (clm-load "clm-load-test.clm" :srate 44100 :channels 2) and so on.

init-with-sound

init-with-sound and finish-with-sound split with-sound into two pieces, primarily for Common Music's benefit.

(define w (init-with-sound :scaled-to .5))
(fm-violin 0 1 440 .1)
(finish-with-sound w)

is equivalent to

(with-sound (:scaled-to .5)
  (fm-violin 0 1 440 .1))
other stuff associated with with-sound

The *clm-* variables are saved in the save-state file by ws-save-state, which may not be a good idea — feedback welcome! Two more convenience functions are ->frequency and ->sample. ->frequency takes either a number or a common-music pitch symbol ('c4 is middle C), and returns either the number or the frequency associated with that pitch:

> (->frequency 'cs5)
554.365261953744

It's optional second argument can be #t to get integer ratios, rather than the default equal temperment. ->sample returns a sample number given a time in seconds:

> (->sample 1.0)
44100

mix-notelists takes any number of notelist arguments, and returns a new notelist with all the input notes sorted by begin time.

(mix-notelists '((fm-violin 0 1 440 .1)
		 (fm-violin 1 1 550 .1))
	       '((bird 0 .1 )
		 (bird .2 .1)
		 (bird 1.2 .3)
		 (bird .5 .5)))

((bird 0 0.1) (fm-violin 0 1 440 0.1) (bird 0.2 0.1) (bird 0.5 0.5) (fm-violin 1 1 550 0.1) (bird 1.2 0.3))
zip
make-zipper ramp-env frame-size frame-env
zipper gen in1 in2
zip-sound beg dur file1 file2 ramp size

The zipper generator performs a kind of cross fade, but not one that tries to be smooth! It marches through the two sounds taking equal short portions of each, then abutting them while resampling so that as one takes less overall frame space, the other takes more. The 'frame-size' argument is the maximum length of each twosome in seconds (for initial array allocation), the 'frame-env' argument determines the current such length as new frames are needed, and the 'ramp-env' argument determines which of the files gets more space in the frame (0: all first, 1: all second). The following function sets up two sounds, an upward ramp and a downward ramp, then zips them together:

(define (ramp-test)
  (let ((data (make-float-vector 10000 0.0)))
    (new-sound "new-0.snd")
    (do ((i 0 (+ i 1))) ((= i 10000)) 
      (set! (data i) (* i .0001)))
    (float-vector->channel data 0 10000 0)
    (new-sound "new-1.snd")
    (do ((i 0 (+ i 1))) ((= i 10000)) 
      (set! (data i) (- 1.0 (* i .0001))))
    (float-vector->channel data 0 10000 1)
    (let* ((dur (framples))
	   (zp (make-zipper (make-env '(0 0 1 1) :length dur)
			    0.05
			    (make-env (list 0 (* (srate) 0.05)) :length dur)))
	  (reader0 (make-sampler 0 0 0))
	  (reader1 (make-sampler 0 1 0)))
      (map-channel (lambda (val) (zipper zp reader0 reader1))))))
zipper ramp output

Needless to say, this is not intended to be a suave, romantic gesture!

zip-sound applies the zipper to a pair of sounds:

(zip-sound 0 1 "fyow.snd" "now.snd" '(0 0 1 1) .05)
(zip-sound 0 3 "mb.snd" "fyow.snd" '(0 0 1.0 0 1.5 1.0 3.0 1.0) .025)
snd-16.1/bess.rb0000644000076400007640000003752712306421672011635 0ustar bilbil#!/usr/local/bin/ruby -wd # bess -- Translation of Bill Schottstaedt's bess.scm to Ruby. # Copyright (c) 2002--2009 Michael Scholz # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. begin require 'rubygems' rescue LoadError end file = File.basename __FILE__ banner = "This is #{file.upcase} v1.9, (C) 2002--2009 Michael Scholz" def warn(*args) str = format(*args) << ($! ? ": #{$!}" : "") << "\n" str << (($@ and $DEBUG) ? "\n[#{$@.join("\n")}]" : "") $stdout.print str $! = nil end def die(*args) warn(*args) exit 1 end def rbm_require(lib) require lib.to_s rescue ScriptError die "\aScriptError" end 1.upto(15) do |i| trap(i) do |sig| die("\nSignal #{sig} received. Process #{$$} canceled.") end end class Bess def initialize(banner, file) @bufsize = 256 @srate = 22050 @chans = 1 @play = 0.0 @freq = 220.0 @fm_index1 = 1.0 @fm_ratio1 = 1 @amp = 0.5 @sliderback = "lightsteelblue" @background = "lightsteelblue1" @low_freq = 40.0 @high_freq = 2000.0 @high_index1 = 3.0 @high_ratio = 10 get_options(banner, file) rbm_require(:libxm) rbm_require(:sndlib) set_mus_srate(@srate) end def get_options(banner, file) vers = false help = false vers_msg = "#{banner} #{file.capitalize} comes with ABSOLUTELY NO WARRANTY. You may redistribute copies of #{file.capitalize} under the terms of the GNU General Public License. For more information about these matters, see the file named COPYING." help_msg = "#{banner} #{file.capitalize} is a Ruby script working with sndlib.so and libxm.so which must be in the Ruby library path, for example in /usr/local/lib/ruby/site_ruby, or the environment variable $RUBYLIB must be set correctly. It opens the DAC, creates some scale widgets, and starts two CLM oscillators doing frequency modulation in semi-real-time. This is a translation of bess.scm of Bill Schottstaedt\'s Snd sound editor. Default values shown in brackets. Usage: #{file} [ options ] [ -- X options ] -p, --play play immediately (#{@play.nonzero? ? "yes" : "no"}) -f, --frequency NUMBER frequency between #{@low_freq} and #{@high_freq} (#{@freq}) -i, --index1 NUMBER fm_index1 between 0 and #{@high_index1} (#{@fm_index1}) -r, --ratio NUMBER ratio between 0 and #{@high_ratio} (#{@fm_ratio1}) -a, --amplitude NUMBER amplitude between 0 and 1 (#{@amp}) -B, --bufsize NUMBER buffer size (#{@bufsize}) -S, --srate NUMBER sampling rate (#{@srate}) -C, --channels NUMBER number of channels (#{@chans}) -b --background COLOR background color (#{@background}) -s, --sliderback COLOR slider background color (#{@sliderback}) -V, --version display version information and exit -h, --help display this help message and exit Example: #{file} -pf1000 -r3 -b ivory1 -s ivory3" rbm_require "getoptlong" GetoptLong.new(["--play", "-p", GetoptLong::NO_ARGUMENT], ["--frequency", "-f", GetoptLong::REQUIRED_ARGUMENT], ["--index1", "-i", GetoptLong::REQUIRED_ARGUMENT], ["--ratio", "-r", GetoptLong::REQUIRED_ARGUMENT], ["--amplitude", "-a", GetoptLong::REQUIRED_ARGUMENT], ["--bufsize", "-B", GetoptLong::REQUIRED_ARGUMENT], ["--srate", "-S", GetoptLong::REQUIRED_ARGUMENT], ["--channels", "-C", GetoptLong::REQUIRED_ARGUMENT], ["--background", "-b", GetoptLong::REQUIRED_ARGUMENT], ["--sliderback", "-s", GetoptLong::REQUIRED_ARGUMENT], ["--version", "-V", GetoptLong::NO_ARGUMENT], ["--help", "-h", GetoptLong::NO_ARGUMENT]).each do |name, arg| case name when "--play" @play = 1.0 when "--frequency" @freq = arg.to_f.abs @freq = @freq < @low_freq ? @low_freq : @freq > @high_freq ? @high_freq : @freq when "--index1" ind = arg.to_f.abs @fm_index1 = ind > @high_index1 ? @high_index1 : ind when "--ratio" rat = arg.to_i.abs @fm_ratio1 = rat > @high_ratio ? @high_ratio : rat when "--amplitude" amp = arg.to_f.abs @amp = amp > 1 ? 1 : amp when "--bufsize" @bufsize = arg.to_i when "--srate" @srate = arg.to_i when "--channels" @chans = arg.to_i when "--sliderback" @sliderback = arg when "--background" @background = arg when "--version" vers = true when "--help" help = true end end die help_msg if help die vers_msg if vers end def get_color(color) col = RXColor() dpy = RXtDisplay(@shell_app[0]) cmap = RDefaultColormap(dpy, RDefaultScreen(dpy)) warn("Can't allocate #{color.inspect}!") if RXAllocNamedColor(dpy, cmap, color, col, col).zero? Rpixel(col) end def set_label(wid, *args) RXtVaSetValues(wid, [RXmNlabelString, RXmStringCreate(format(*args), RXmFONTLIST_DEFAULT_TAG)]) end def make_label(wid, name) RXtCreateManagedWidget(name, RxmLabelWidgetClass, @form, [RXmNleftAttachment, RXmATTACH_FORM, RXmNbottomAttachment, RXmATTACH_NONE, RXmNtopAttachment, RXmATTACH_WIDGET, RXmNtopWidget, wid, RXmNrightAttachment, RXmATTACH_NONE, RXmNalignment, RXmALIGNMENT_END, RXmNwidth, 80, #114, RXmNrecomputeSize, false, RXmNbackground, get_color(@background)]) end def make_scale_label(wid) RXtCreateManagedWidget("label", RxmLabelWidgetClass, @form, [RXmNleftAttachment, RXmATTACH_WIDGET, RXmNleftWidget, wid, RXmNbottomAttachment, RXmATTACH_NONE, RXmNtopAttachment, RXmATTACH_OPPOSITE_WIDGET, RXmNtopWidget, wid, RXmNrightAttachment, RXmATTACH_NONE, RXmNbackground, get_color(@background)]) end def make_scale(wid) RXtCreateManagedWidget("scale", RxmScaleWidgetClass, @form, [RXmNleftAttachment, RXmATTACH_WIDGET, RXmNleftWidget, wid, RXmNbottomAttachment, RXmATTACH_NONE, RXmNtopAttachment, RXmATTACH_OPPOSITE_WIDGET, RXmNtopWidget, wid, RXmNrightAttachment, RXmATTACH_FORM, RXmNshowValue, false, RXmNorientation, RXmHORIZONTAL, RXmNbackground, get_color(@sliderback)]) end def make_scales(wid, name, val, callback) label = make_scale_label(make_label(wid, name)) scale = make_scale(label) set_label(label, val.kind_of?(Integer) ? "%8d" : "%8.3f", val) RXtAddCallback(scale, RXmNdragCallback, callback, label) RXtAddCallback(scale, RXmNvalueChangedCallback, callback ,label) scale end def start_dac(&body) args = [$0] + $* @shell_app = RXtVaOpenApplication("FM", args.length, args, RapplicationShellWidgetClass, [RXmNallowShellResize, true, RXmNtitle, "FM forever!"]) RXtAddEventHandler(@shell_app[0], 0, true, lambda do |w, c, i, f| R_XEditResCheckMessages(w, c, i, f) end) @form = RXtCreateManagedWidget("form", RxmFormWidgetClass, @shell_app[0], [RXmNresizePolicy, RXmRESIZE_GROW, RXmNbackground, get_color(@background)]) play_button = RXtCreateManagedWidget("play", RxmToggleButtonWidgetClass, @form, [RXmNtopAttachment, RXmATTACH_FORM, RXmNleftAttachment, RXmATTACH_FORM, RXmNrightAttachment, RXmATTACH_NONE, RXmNbottomAttachment, RXmATTACH_NONE, RXmNbackground, get_color(@background)]) RXmToggleButtonSetState(play_button, @play.nonzero? ? true : false, false) RXtAddCallback(play_button, RXmNvalueChangedCallback, lambda do |w, c, i| @play = Rset(i) ? 1.0 : 0.0 end) quit_button = RXtCreateManagedWidget(" quit ", RxmPushButtonWidgetClass, @form, [RXmNtopAttachment, RXmATTACH_FORM, RXmNleftAttachment, RXmATTACH_NONE, RXmNrightAttachment, RXmATTACH_FORM, RXmNbottomAttachment, RXmATTACH_NONE, RXmNbackground, get_color(@background)]) RXtAddCallback(quit_button, RXmNactivateCallback, lambda do |w, c, i| exit(0) end) wid = make_scales(play_button, " carrier:", @freq, lambda do |w, c, i| @freq = @low_freq + Rvalue(i) * ((@high_freq - @low_freq) / 100.0) set_label(c, "%8.3f", @freq) end) RXmScaleSetValue(wid, (100 * (@freq - @low_freq) / (@high_freq - @low_freq)).round) wid = make_scales(wid, " amplitude:", @amp, lambda do |w, c, i| @amp = Rvalue(i) / 100.0 set_label(c, "%8.3f", @amp) end) RXmScaleSetValue(wid, (100 * @amp).round) wid = make_scales(wid, "fm index 1:", @fm_index1, lambda do |w, c, i| @fm_index1 = Rvalue(i) * (@high_index1 / 100.0) set_label(c, "%8.3f", @fm_index1) end) RXmScaleSetValue(wid, (100 * @fm_index1 / @high_index1).round) wid = make_scales(wid, "c/m ratio 1:", @fm_ratio1, lambda do |w, c, i| @fm_ratio1 = (Rvalue(i) * (@high_ratio / 100.0)).round set_label(c, "%8d", @fm_ratio1) end) RXmScaleSetValue(wid, (@fm_ratio1 * 100 / @high_ratio).round) if defined? @fm_index2 wid = make_scales(wid, "fm index 2:", @fm_index2, lambda do |w, c, i| @fm_index2 = Rvalue(i) * (@high_index2 / 100.0) set_label(c, "%8.3f", @fm_index2) end) RXmScaleSetValue(wid, (100 * @fm_index2 / @high_index2).round) wid = make_scales(wid, "c/m ratio 2:", @fm_ratio2, lambda do |w, c, i| @fm_ratio2 = (Rvalue(i) * (@high_ratio / 100.0)).round set_label(c, "%8d", @fm_ratio2) end) RXmScaleSetValue(wid, (@fm_ratio2 * 100 / @high_ratio).round) end if defined? @fm_index3 wid = make_scales(wid, "fm index 3:", @fm_index2, lambda do |w, c, i| @fm_index2 = Rvalue(i) * (@high_index3 / 100.0) set_label(c, "%8.3f", @fm_index2) end) RXmScaleSetValue(wid, (100 * @fm_index3 / @high_index3).round) wid = make_scales(wid, "c/m ratio 3:", @fm_ratio3, lambda do |w, c, i| @fm_ratio3 = (Rvalue(i) * (@high_ratio / 100.0)).round set_label(c, "%8d", @fm_ratio3) end) RXmScaleSetValue(wid, (@fm_ratio3 * 100 / @high_ratio).round) end proc = nil data = make_sound_data(@chans, @bufsize) port = mus_audio_open_output(0, @srate, @chans, Mus_lshort, @bufsize * 2) die("Can't open DAC!") if port < 0 RXmAddWMProtocolCallback(@shell_app[0], RXmInternAtom(RXtDisplay(@shell_app[0]), "WM_DELETE_WINDOW", false), lambda do |w, c, i| RXtRemoveWorkProc(proc) mus_audio_close(port) end, false) proc = RXtAppAddWorkProc(@shell_app[1], lambda do |dummy| @bufsize.times do |i| @chans.times do |c| sound_data_set!(data, c, i, body.call) end end mus_audio_write(port, data, @bufsize) false end) RXtRealizeWidget(@shell_app[0]) RXtAppMainLoop(@shell_app[1]) rescue die("start_dac() { ... }") end end # test functions def bess(banner, file, &body) b = Bess.new(banner, file) b.make_ffm() b.start_dac() do b.instance_eval(&body) end rescue die("bess(banner, file, osf, mdf) { ... }") end class Bess def make_fm @osc = make_oscil(0.0) @mod = make_oscil(0.0) end def fm @amp * @play * oscil(@osc, in_hz(@freq) + @fm_index1 * oscil(@mod, in_hz(@fm_ratio1 * @freq))) end def make_ffm @osc = make_oscil(0.0) @md1 = make_oscil(0.0) @md2 = make_oscil(0.0) @md3 = make_oscil(0.0) @fm_index1 = 1.0 @fm_index2 = 0.0 @fm_index3 = 0.0 @fm_ratio1 = 1 @fm_ratio2 = 1 @fm_ratio3 = 1 @high_index2 = 3.0 @high_index2 = 1.0 @high_index3 = 0.25 @amp = 0.5 end def ffm_rb @amp * @play * oscil(@osc, in_hz(@freq) + @fm_index1 * oscil(@md1, in_hz(@fm_ratio1 * @freq)) + @fm_index2 * oscil(@md2, in_hz(@fm_ratio2 * @freq)) + @fm_index3 * oscil(@md3, in_hz(@fm_ratio3 * @freq))) end def ffm ffm_c(@amp, @play, @freq, @fm_index1, @fm_index2, @fm_index3, @fm_ratio1, @fm_ratio2, @fm_ratio3, @osc, @md1, @md2, @md3) end rbm_require 'inline' include Inline inline do |ffm_c| fft_c.c " #include #include typedef struct { mus_any *gen; VALUE *vcts; int nvcts; void *input_ptree; } mus_xen; double fft_c(double amp, double play, double freq, double fm_index1, double fm_index2, double fm_index3, double fm_ratio1, double fm_ratio2, double fm_ratio3, mus_any *osc, mus_any *md1, mus_any *md2, mus_any *md3) { return (amp * play * mus_oscil(osc, mus_hz2radians(freq) + fm_index1 * mus_oscil(md1, mus_hz2radians(fm_ratio1 * freq), 0.0) + fm_index2 * mus_oscil(md2, mus_hz2radians(fm_ratio2 * freq), 0.0) + fm_index3 * mus_oscil(md3, mus_hz2radians(fm_ratio3 * freq), 0.0), 0.0)); }" end end begin bess(banner, file) do ffm_rb() end end # bess.rb ends here snd-16.1/README.Snd0000644000076400007640000004542712622467372011765 0ustar bilbilSnd Snd is a sound editor. It currently runs on nearly all Unix-based systems, including Mac OSX and Cygwin. To build Snd, get the sources from ftp://ccrma-ftp.stanford.edu/pub/Lisp/snd-16.tar.gz gzip -d snd-16.tar.gz tar xf snd-16.tar cd snd-16 ./configure make and if you like, su root, then make install The configure script has a bunch of arguments: Extension language: --with-s7 use s7 (the default, a version of Scheme). --with-ruby use Ruby as the extension language. If you build Ruby from the sources, remember to use the --enable-shared switch. Otherwise ruby.pc is messed up. If ruby.pc (or equivalent) is missing, tools/make-config-pc.rb can make one: make-config-pc.rb > ruby.pc mv ruby.pc /usr/local/lib/pkgconfig/ruby.pc You may also have to set PKG_CONFIG_PATH: PKG_CONFIG_PATH=.:/opt/X11/lib/pkgconfig/ ./configure --with-gtk --with-ruby --with-portaudio --with-forth use Forth (Mike Scholz's FTH) as the extension language. --without-extension-language build Snd without any extension language Graphics: --with-motif use Motif. If it's in some odd location, you can provide that info: ./configure LDFLAGS="-L/usr/X11R6/lib" CFLAGS="-I/usr/X11R6/include" --with-motif in FC, install the motif, motif-devel, and libXpm-devel packages. in *BSD, pkg install open-motif, or perhaps use pkgin? in Debian, apt-get install libmotif4, libmotif-dev, libxt-dev, libxpm-dev --with-gtk use Gtk+ --with-gui make Snd with graphics support (actually intended for use as --without-gui) --with-gl include support for OpenGL (default: no, Motif only) --with-gl2ps include gl2ps (postscript output from OpenGL graphics) Audio: --with-alsa use ALSA if possible (the default in Linux) --with-oss use OSS (not tested in a long time) --with-jack use the Jack library which needs libsamplerate --with-pulseaudio use PulseAudio (untested) --without-audio do not include audio support. This also affects the GUI (play buttons are omitted). Other options: --with-gmp use gmp, mpfr, and mpc to implement multiprecision arithmetic --with-ladspa include LADSPA plugin support (default: yes in Linux) --with-temp-dir directory to use for temp files (default: ".") --with-save-dir directory to use for saved-state files (default: ".") --with-doc-dir directory to search for documentation If the configure/make process fails, please send me (bil@ccrma.stanford.edu) the files mus-config.h, config.log, and makefile, created (or updated) by configure. In general, if some switch is ignored, check that you have installed the "devel" package. For example, --with-ruby won't work unless you have installed the ruby-devel package. Snd comes with s7, but if you insist on building Snd without any extension language, you'll find that it's severely limited in what it can do. Snd can also be built without any graphics toolkit. Without either the GUI or an extension language, however, there's nothing it can do. Here at CCRMA, we use this configure invocation: ./configure --with-jack --with-temp-dir=/zap Version info: if Gtk, then Gtk+ 2.13 or later and Cairo 1.6.4 or later if Motif, then Motif 2.n but not Lesstif in Linux, if ALSA, then ALSA 1.0 or later if Ruby, Ruby 1.8.0 or later. if Forth, any version if s7, version 3.0 or later (it comes with Snd). if GSL, version 1.0 or later ---------------------------------------------------------------- The customization/extension languages are either s7, Ruby, or Forth. Much of Snd's functionality is loaded as needed from the Scheme, Ruby, or Forth files found in the tarball (*.scm, *.rb, and *.fs). You can run Snd without these files, but there's no reason to! Just add the directory containing those files to the "load-path". In s7, (set! *load-path* (cons "/home/bil/cl" *load-path*)) *load-path* is the list of directories that s7 looks at when trying to find a file to load. Here I've added "/home/bil/cl" so that Snd can find its sources no matter what directory I run it in. If you create a file named ~/.snd_s7 and put such a line in it, you'll never have to think about it again. In the other languages: Ruby: $LOAD_PATH.push("/home/bil/cl") Forth: "/home/bil/cl" add-load-path ---------------------------------------------------------------- The documentation is in snd.html, extsnd.html, grfsnd.html, sndscm.html, sndlib.html, sndclm.html, fm.html, and s7.html. A brief change log is in HISTORY.Snd. The mailing list for Snd is the same as that for Common Music: cmdist@ccrma.stanford.edu. To subscribe, visit http://ccrma-mail.stanford.edu/mailman/listinfo/cmdist To follow the Snd CVS repository, the first time you need to cvs -d:pserver:anonymous@snd.cvs.sourceforge.net:/cvsroot/snd login cvs -z3 -d:pserver:anonymous@snd.cvs.sourceforge.net:/cvsroot/snd co cvs-snd When prompted for a password for anonymous, press the Enter key. After that, you go to your local cvs-snd directory and cvs update ---------------------------------------------------------------- This software is available to anyone who is interested, free gratis for nothing, without warranties of any kind (see the file COPYING for legalese). Send bug reports or suggestions to bil@ccrma.stanford.edu. ---------------------------------------------------------------- Authors: Bill Schottstaedt Michael Scholz Rick Taube, Andrew Burnson, Donny Ward: C++ and Windows wizardry. Kjetil S. Matheussen: the Jack support and many other improvements. Dave Phillips: the tutorial, new-effects.scm, and many other files. Fernando Lopez-Lezcano: the current ALSA support. Rick Taube and Anders Vinjar: CM scheme files ported to Snd Tito Latini: many bugfixes. Richard W.E. Furse: the original LADSPA support. Nick Bailey: the ESD support. Volker Kuhlmann and Seppo Ingalsuo: the Solaris port. Seppo Ingalsuo: the HPUX port. Juan Reyes: the DEC Alpha port. Guenter Geiger and Stefan Schwandter: the Linux Alpha port. Paul Davis: the original ALSA support. Steven Schultz and Mike Scholz: the *BSD ports. Ludger Brummer and Charles Nichols: the Mac-OSX port. Thomas Klausner and Mike Scholz: the NetBSD port. Steve Beet: minGW Plus many other contributions from Fernando Lopez-Lezcano, Tom Roth, Fabio Furlanete, Rick Taube, Anders Vinjar, Olivier Doare, Ville Koskinen, Andrew Burnson. In terms of number of lines, the languages used in Snd/Sndlib are: C, Scheme, Ruby, Forth, Emacs Lisp, Fortran, and Lua (altogether about 750k lines). ---------------------------------------------------------------- If you hit a bug, don't just sit there weeping -- send me (bil@ccrma.stanford.edu) a description of it! If it's something like a segfault, you have gdb, and you can build Snd from the sources, it would help me a lot if you could build it with the -g switch, then gdb snd run where The 'where' command should print out the current stack trace which is extremely helpful to me in tracking down the problem. It can also be helpful to move to the first Snd-related function in the stack (via the 'up' command), then type info locals This will print out the value of the local variables. In most cases, that's all I need to fix the bug immediately. If Snd appears to be hung, you can gdb snd run where ---------------------------------------------------------------- TROUBLES: ---- audio (a can of worms) ---- If nothing plays in Linux (try aplay for example), and the sound preferences have no effect, look for the pulseaudio daemon, and kill it. In OpenBSD, use pulseaudio: ./configure --with-gmp --with-gtk --with-pulseaudio CFLAGS=-ftrampolines LDFLAGS=-pthread In X86 Solaris, you may need to install Jurgen Keil's audio drivers. They can be found at http://www.tools.de/solaris. Here are some suggestions from Russell Aspinwall: Assuming you are using the Java Desktop System, then if there is sound you will find a speaker in the lower right hand corner, if there is a red line through it then it has not detected the sound card. To find the audio device , as root run # prtconf -pv > /tmp/prtconf.txt open prtconf.txt in text editor and search for "Audio Device", this will give the pci identifiers. grep /etc/driver_aliases for those pci identifiers and this will identify the Device Driver. # mixerctl should return [some description of the audio hardware] But I still have not managed to get output on my machine. Apparently the audio card thinks it's the local network controller or something. ---- ALSA: ---- Only versions from 1.0 of ALSA are supported. An addendum: in my system, I have a wretched sound card in my machine, and an EMI 2|6 connected to a USB connector. So the EMI device is "hw:1" in Alsa terms, and since I never want to use the internal sound card, I have this line in my ~/.cshrc file: setenv MUS_ALSA_DEVICE "hw:1" But this number seems to be set randomly at boot time! And sometimes, Alsa in its infinite wisdom mutes the playback device. So, now I have these lines executing at startup: amixer sset PCM,0 80% unmute amixer sset Mic,0 80% If you use 100% (meaning, give me full amplitude output), it's the same as 0!! On a different machine, I use: setenv MUS_ALSA_DEVICE "plughw:0" If you get some complaint like ;Invalid argument: cannot set hardware parameters for default try setting: (set! (mus-alsa-device) "plughw:0") or (set! (mus-alsa-device) "plughw:1") then try playing again. The "default" device is always completely broken. ---- Motif: ---- Only Motif 2.n is supported. Be sure to get the Motif development package if you want to build Snd (you need the Motif headers). On 64-bit machines, use motif 2.3.2 or later. ---- Gtk+: ---- Only Gtk 2.13 or later is supported. If you get an error like: Gtk-WARNING **: you can find where it occurs by: gdb snd run --g-fatal-warnings where In some cases, if you installed gtk from an RPM file, you also need to install gtk-devel. ---- Mac OSX: ---- You can use either Motif or Gtk running under X11; to start Snd from an ordinary shell, use the open-x11 command: open-x11 snd or (in later versions of OSX) just start snd, and X should start automatically. To install X11, first, install the X11SDK and X11User packages. The first is in one of the Installer directories, the second (in OSX 10.4) is on the first install disk under System/Installation/Packages/X11User.pkg or some such name. These give you the X11 server and its header files. There are several ways to go from here; the simplest is probably to use Darwin Ports as outlined by Hans Fugal: I installed openmotif and gsl with Darwin Ports: sudo port install openmotif sudo port install gsl Then I did the regular: ./configure --with-motif --with-ruby make sudo make install open-x11 /usr/local/bin/snd If you get some complaint about identifiers that look like they come from libSM or libICE, add -lICE -lSM to the end of the library list in the makefile. If C-f (and other such commands) doesn't work, either try toggling the "w" button, or enable pointer focus: (set! (with-pointer-focus) #t) If the openmotif package forgot to include libXm.a (Motif), a version is at ccrma-ftp. If the Mac loader complains that it it out of date, run ranlib: ranlib libXm.a (you may need to admin privileges to do this). See also the cmdist archives for tips from Juan Pampin and others. Here's some info from Josh Mattoon: "It turns out everything required for snd is now in fink! sudo fink install openmotif3 fftw So... after a loooong compilation process (fftw required g77) I had everything in place. But ./configure couldn't find them, d'oh. My simple solution was to pass in the CFLAGS and LDFLAGS as so: CFLAGS=-I/sw/include LDFLAGS="-L/sw/lib -lmx -bind_at_load" ./configure \ --with-gl --with-editres This was after a bit of trial and error. The linker couldn't find some symbols that turned out to be in libmx, so I added that, and the linker also suggested the bind_at_load (though I'm not totally sure what that means)." (fftw is optional in Snd). Adam Tinsdale had better luck with this: CFLAGS=-I/sw/include LDFLAGS="-L/sw/lib -lmx -bind_at_load" ./configure \ --with-motif --without-fftw The dac-size variable seems to matter a lot in OSX. If you're getting distorted playback, try various powers of 2. It defaults to 64. Rick Taube mentions this for tracing the load process: [...]you can set the DYLD_PRINT_LIBRARIES shell variable: DYLD_PRINT_LIBRARIES=1 export DYLD_PRINT_LIBRARIES some other useful dylib variables: DYLD_FRAMEWORK_PATH DYLD_FALLBACK_FRAMEWORK_PATH DYLD_LIBRARY_PATH DYLD_FALLBACK_LIBRARY_PATH So, here's the detailed step-by-step method, thanks to Cris Ewing: This build was done on a Mac G4 Powerbook with OS X 10.3 (panther). The first step (and it is a vital one) is to make sure that your version of fink is fully up-to-date. Start by running $ fink selfupdate $ fink update-all Next, verify that you have a working version of X11 on your machine. This must include the development libs found in the X11SDK. If you are using apple's version of X11, the SDK package is _not_ installed by default when you install X11. You have to do a custom install from the XCode disk to get the package. Once all this is in place, use fink to install openmotif3 $ fink install openmotif3 You can also use fink to install the fftw package. It takes a really long time to build, but helps to speed up the fft-based functions in snd. $ fink install fftw Next, download and untar the latest snd sources from ccrma $ ./configure CFLAGS="-I/sw/include" LDFLAGS="-L/sw/lib -lmx -bind_at_load" --with-motif --with-motif-prefix=/sw This config was run from a bash shell. If you are using tcsh (and you might be if you upgraded to panther) then you will have to omit the part about CFLAGS and LDFLAGS above. Instead, you can set these through the shell by running % setenv LDFLAGS "-L/sw/lib -lmx -bind_at_load"" % setenv CFLAGS "-I/sw/include" After this, you're nearly home: $ make $ sudo make install (you need to sudo make install, because it will install an snd-executable in /usr/local/bin) In OSX 10.5, I had to add Xft, Xmu, and fontconfig to the MOTIF_LIBS line in makefile: MOTIF_LIBS = -L/usr/X11/lib -R/usr/X11/lib -lSM -lICE -lXft -lXmu -lfontconfig /usr/X11R6-old/lib/libXm.a -L/usr/X11R6-old/lib -lXt -lXp -lX11 -lSM -lICE -lXext -lXpm (the X11R6-old business came about because I didn't remake libXm, but the OSX installation process moved the previous X11R6 directory to X11R6 1, which is untypable). In OSX 10.6.8, Ludger Brummer suggests: ./configure CFLAGS="-arch i386 -I/sw/include" LDFLAGS="-L/sw/lib -lmx -bind_at_load" --with-motif Here's a note from Brooke Mitchell: How to install snd on Mac OSX Snow Leopard using homebrew: --have you installed Developer Tools??? 1) install openmotif osx package (http://www.ist.co.uk/downloads/motif_download.html) open terminal: export DYLD_LIBRARY_PATH=/usr/OpenMotif/lib 2) install homebrew: /usr/bin/ruby -e "$(curl -fsSL https://raw.github.com/gist/323731)" 3) install dependencies. brew install libffi (repository link should be fixed, otherwise terminal: brew edit libffi change line 4:" url'sourceware.org:/pub/libffi/libffi-3.0.9.tar.gz'" brew install --HEAD guile then: brew install fftw ...wait 4) compile the source ./configure \ --with-motif-prefix=/usr/OpenMotif (--with-ruby //if you want ruby) edit makefile. add to line 19: ORIGINAL_LDFLAGS = /usr/OpenMotif/lib make sudo make install -------- For homebrew+gtk, here are the CFLAGS and LDFLAGS I used: GTK_CFLAGS = -pthread -I/usr/local/include/gtk-3.0 -I/usr/local/include/atk-1.0 -I/usr/local/include/cairo -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libpng12 -I/usr/local/Cellar/glib/2.40.0_1/lib/glib-2.0/include -D_REENTRANT -I/usr/local/Cellar/gdk-pixbuf/2.30.7/include/gdk-pixbuf-2.0 -I/usr/local/Cellar/libpng/1.6.10/include/libpng16 -I/usr/local/Cellar/glib/2.40.0_1/include/glib-2.0 -I/usr/local/Cellar/glib/2.40.0_1/lib/glib-2.0/include -I/usr/local/opt/gettext/include LDFLAGS = -L/usr/local/lib /usr/local/lib/libcairo.a /usr/local/lib/libpng.a /usr/local/lib/libcairo-gobject.a -lgtk-3.0 -lglib-2.0 -lpango-1.0 /usr/local/lib/libpixman-1.a -lgmodule-2.0 -lgobject-2.0 -lfontconfig -lfreetype -lgdk_pixbuf-2.0 -lpangocairo-1.0 -lgdk-3.0 -lgio-2.0 -lharfbuzz -lpangoft2-1.0 /usr/local/lib/liblzma.a -L/usr/lib -lz -framework Foundation -framework CoreGraphics but don't waste your time; it looks like crap, and dies with "No GSetting schemas" or something. -------- FreeBSD 9.n -------- If the Snd compilation fails with complaints about the complex trig functions (ccosh etc), here are some suggestions from Mike Scholz: FBSD has CFLAGS=-fno-strict-aliasing as a default for base and ports. With GCC you can use: % ./configure CFLAGS=-fno-strict-aliasing Or at least set -fno-builtin: % ./configure CFLAGS=-fno-builtin Or use clang without the aforementioned flags: % ./configure CC=clang There is also a port in /usr/ports/audio/snd with version 13.0 from August 2012. -------- Debian -------- The last time I installed Debian (via netinstall) I installed the following Snd-related packages by hand: libgmp-dev fftw-dev libgtk-3-dev libmpfr-dev libmpc-dev libgsl0-dev libasound2-dev libgl1-mesa-dev and for Fedora Core 22: yum install gcc tcsh rxvt emacs fftw3 fftw3-devel gtk3 gtk3-devel alsa-lib alsa-lib-devel gsl gsl-devel gmp gmp-devel mpfr mpfr-devel libmpc libmpc-devel ruby ruby-devel motif motif-devel libXpm-devel clang mesa-libGLU-devel xorg-x11-fonts-misc valgrind yum groupinstall "LXDE" reboot to get LXDE listed in the login settings snd-16.1/analog-filter.rb0000644000076400007640000004253212306421672013415 0ustar bilbil# analog-filter.rb -- analog-filter.scm --> analog-filter.rb -*- snd-ruby -*- # Translator/Author: Michael Scholz # Created: Tue Aug 01 22:58:31 CEST 2006 # Changed: Wed Nov 17 22:07:58 CET 2010 # Commentary: # # ;;; various even order analog filters, based primarily on Anders Johansson's (GPL'd) code # # module Analog_filter # make_butterworth_lowpass(n, fc) # make_butterworth_highpass(n, fc) # make_butterworth_bandpass(n, fl, fh) # make_butterworth_bandstop(n, fl, fh) # # make_chebyshev_lowpass(n, fc, ripple = 1.0) # make_chebyshev_highpass(n, fc, ripple = 1.0) # make_chebyshev_bandpass(n, fl, fh, ripple = 1.0) # make_chebyshev_bandstop(n, fl, fh, ripple = 1.0) # # make_inverse_chebyshev_lowpass(n, fc, loss_dB = 60.0) # make_inverse_chebyshev_highpass(n, fc, loss_dB = 60.0) # make_inverse_chebyshev_bandpass(n, fl, fh, loss_dB = 60.0) # make_inverse_chebyshev_bandstop(n, fl, fh, loss_dB = 60.0) # # make_bessel_lowpass(n, fc) # make_bessel_highpass(n, fc) # make_bessel_bandpass(n, fl, fh) # make_bessel_bandstop(n, fl, fh) # # make_elliptic_lowpass(n, fc, ripple = 1.0, loss_dB = 60.0) # make_elliptic_highpass(n, fc, ripple = 1.0, loss_dB = 60.0) # make_elliptic_bandpass(n, fl, fh, ripple = 1.0, loss_dB = 60.0) # make_elliptic_bandstop(n, fl, fh, ripple = 1.0, loss_dB = 60.0) # # Code: require "clm" require "dsp" module Analog_filter def analog2digital(n, num, den, fz) g = 1.0 wc = tan(PI * fz) wcc = wc * wc c = Vct.new(2 * n) j = 0 k = 0 0.step(n - 1, 2) do |i| nt0 = num[j + 0] / wcc nt1 = num[j + 1] / wc nt2 = num[j + 2] dt0 = den[j + 0] / wcc dt1 = den[j + 1] / wc dt2 = den[j + 2] kd = dt0 + dt1 + dt2 kn = nt0 + nt1 + nt2 c[k + 0] = (2.0 * dt2 - 2.0 * dt0) / kd c[k + 1] = (dt0 + (-dt1) + dt2) / kd c[k + 2] = (2.0 * nt2 - 2.0 * nt0) / kn c[k + 3] = (nt0 + (-nt1) + nt2) / kn g *= (kn / kd) j += 3 k += 4 end a = [] b = [] k = 0 0.step(n - 1, 2) do |i| a.unshift(vct(c[k + 3], c[k + 2], c[k + 3])) b.unshift(vct(1.0, c[k], c[k + 1])) k += 4 end [cascade2canonical(a).scale!(g), cascade2canonical(b)] end def prototype2highpass(n, num, den) g = 1.0 numt = Vct.new(num.length) dent = Vct.new(den.length) i = 0 0.step(n - 1, 2) do |k| g *= (num[i + 2] / den[i + 2]) numt[i + 0] = 1.0 numt[i + 1] = num[i + 1] / num[i + 2] numt[i + 2] = num[i + 0] / num[i + 2] dent[i + 0] = 1.0 dent[i + 1] = den[i + 1] / den[i + 2] dent[i + 2] = den[i + 0] / den[i + 2] i += 3 end numt[0] = g [numt, dent] end # # === BUTTERWORTH === # def butterworth_prototype(n) len = (n * 3) / 2 num = Vct.new(len) den = Vct.new(len) n2 = 2.0 * n j = 0 1.step(n - 1, 2) do |w| num[j + 0] = 0.0 num[j + 1] = 0.0 num[j + 2] = 1.0 den[j + 0] = 1.0 den[j + 1] = 2.0 * cos((w * PI) / n2) den[j + 2] = 1.0 j += 3 end [num, den] end # n = order, fc = cutoff freq (srate = 1.0) add_help(:make_butterworth_lowpass, "make_butterworth_lowpass(n, fc): \ returns a lowpass Buttterworth filter; N = order, \ FC = cutoff freq (srate = 1.0): make_butterworth_lowpass(8, 0.1)") def make_butterworth_lowpass(n, fc) if n.odd? then n += 1 end proto = butterworth_prototype(n) coeffs = analog2digital(n, proto[0], proto[1], fc) make_filter(:xcoeffs, coeffs[0], :ycoeffs, coeffs[1]) end add_help(:make_butterworth_highpass, "make_butterworth_highpass(n, fc): \ returns a highpass Buttterworth filter; N = order, \ FC = cutoff freq (srate = 1.0): make_butterworth_highpass(8, 0.1)") def make_butterworth_highpass(n, fc) if n.odd? then n += 1 end proto = butterworth_prototype(n) hproto = prototype2highpass(n, proto[0], proto[1]) coeffs = analog2digital(n, hproto[0], hproto[1], fc) make_filter(:xcoeffs, coeffs[0], :ycoeffs, coeffs[1]) end add_help(:make_butterworth_bandpass, "make_butterworth_bandpass(n, fl, fh): \ returns a bandpass Buttterworth filter; N = order, \ FL and FH are (1.0-based) edge freqs: make_butterworth_bandpass(4, 0.1, 0.2)") def make_butterworth_bandpass(n, fl, fh) lp = make_butterworth_lowpass(n, fh) hp = make_butterworth_highpass(n, fl) lambda do |y| filter(lp, filter(hp, y)) end end add_help(:make_butterworth_bandstop, "make_butterworth_bandstop(n, fl, fh): \ returns a bandstop Buttterworth filter; N = order, \ FL and FH are (1.0-based) edge freqs: make_butterworth_bandstop(4, 0.1, 0.2)") def make_butterworth_bandstop(n, fl, fh) lp = make_butterworth_lowpass(n, fl) hp = make_butterworth_highpass(n, fh) lambda do |y| filter(lp, y) + filter(hp, y) end end # # === CHEBYSHEV === # # ripple in dB (positive) def chebyshev_prototype(n, ripple = 1.0) e = sqrt((10.0 ** (0.1 * ripple)) - 1.0) v0 = asinh(1.0 / e) / n.to_f len = (n * 3) / 2 n2 = 2.0 * n sinhv0 = sinh(v0) coshv0 = cosh(v0) num = Vct.new(len) den = Vct.new(len) j = 0 1.step(n - 1, 2) do |l| lpi = l * PI u = -(sinhv0 * sin(lpi / n2)) w = coshv0 * cos(lpi / n2) num[j + 0] = 0.0 num[j + 1] = 0.0 num[j + 2] = 1.0 den[j + 0] = 1.0 den[j + 1] = -2.0 * u den[j + 2] = u * u + w * w j += 3 end num[2] = (2.0 ** (2 - n)) / (3.2 ** (log(ripple) / log(10.0))) [num, den] end # n = order, fc = cutoff freq (srate = 1.0) add_help(:make_chebyshev_lowpass, "make_chebyshev_lowpass(n, fc, ripple=1.0): \ returns a lowpass Chebyshev filter; N = order, \ FC = cutoff freq (srate = 1.0): make_chebyshev_lowpass(8, 0.1)") def make_chebyshev_lowpass(n, fc, ripple = 1.0) if n.odd? then n += 1 end proto = chebyshev_prototype(n, ripple) coeffs = analog2digital(n, proto[0], proto[1], fc) make_filter(:xcoeffs, coeffs[0], :ycoeffs, coeffs[1]) end add_help(:make_chebyshev_highpass, "make_chebyshev_highpass(n, fc, ripple=1.0): \ returns a highpass Chebyshev filter; N = order, \ FC = cutoff freq (srate = 1.0): make_chebyshev_highpass(8, 0.1, 0.01)") def make_chebyshev_highpass(n, fc, ripple = 1.0) if n.odd? then n += 1 end proto = chebyshev_prototype(n, ripple) hproto = prototype2highpass(n, proto[0], proto[1]) coeffs = analog2digital(n, hproto[0], hproto[1], fc) make_filter(:xcoeffs, coeffs[0], :ycoeffs, coeffs[1]) end add_help(:make_chebyshev_bandpass, "make_chebyshev_bandpass(n, fl, fh, ripple=1.0): \ returns a bandpass Chebyshev filter; N = order, \ FL and FH = edge freq (srate = 1.0): make_chebyshev_highpass(8, 0.1, 0.01)") def make_chebyshev_bandpass(n, fl, fh, ripple = 1.0) lp = make_chebyshev_lowpass(n, fh, ripple) hp = make_chebyshev_highpass(n, fl, ripple) lambda do |y| filter(lp, filter(hp, y)) end end add_help(:make_chebyshev_bandstop, "make_chebyshev_bandstop(n, fl, fh, ripple=1.0): \ returns a bandstop Chebyshev filter; N = order, \ FL and FH = edge freqs (srate = 1.0): make_chebyshev_bandstop(8, 0.1, 0.4, 0.01)") def make_chebyshev_bandstop(n, fl, fh, ripple = 1.0) lp = make_chebyshev_lowpass(n, fl, ripple) hp = make_chebyshev_highpass(n, fh, ripple) lambda do |y| filter(lp, y) + filter(hp, y) end end # # === INVERSE CHEBYSHEV === # def inverse_chebyshev_prototype(n, loss_dB = 60.0) e = sqrt(1.0 / (10.0 ** (0.1 * loss_dB) - 1.0)) v0 = asinh(1.0 / e) / n.to_f len = (n * 3) / 2 n2 = 2.0 * n num = Vct.new(len) den = Vct.new(len) pl = 0.0 j = 0 1.0.step(n - 1, 2.0) do |l| lpi = l * PI u = -(sinh(v0) * sin(lpi / n2)) w = cosh(v0) * cos(lpi / n2) t = 1.0 / sin(((l + pl) * PI) / n2) num[j + 0] = 1.0 num[j + 1] = 0.0 num[j + 2] = t * t den[j + 0] = 1.0 den[j + 1] = (-2.0 * u) / (u * u + w * w) den[j + 2] = 1.0 / (u * u + w * w) j += 3 end [num, den, 1.122 ** -loss_dB] end # n = order, fc = cutoff freq (srate = 1.0) add_help(:make_inverse_chebyshev_lowpass, "make_inverse_chebyshev_lowpass(n, fc, loss_dB=60.0): \ returns a lowpass inverse-Chebyshev filter; N = order, \ FC = cutoff freq (srate = 1.0): make_inverse_chebyshev_lowpass(10, 0.4, 120)") def make_inverse_chebyshev_lowpass(n, fc, loss_dB = 60.0) if n.odd? then n += 1 end proto = inverse_chebyshev_prototype(n, loss_dB) coeffs = analog2digital(n, proto[0], proto[1], fc) make_filter(:xcoeffs, coeffs[0].scale!(proto[2]), :ycoeffs, coeffs[1]) end add_help(:make_inverse_chebyshev_highpass, "make_inverse_chebyshev_highpass(n, fc, loss_dB=60.0): \ returns a highpass inverse-Chebyshev filter; N = order, \ FC = cutoff freq (srate = 1.0): make_inverse_chebyshev_highpass(10, 0.1, 120)") def make_inverse_chebyshev_highpass(n, fc, loss_dB = 60.0) if n.odd? then n += 1 end proto = inverse_chebyshev_prototype(n, loss_dB) hproto = prototype2highpass(n, proto[0], proto[1]) coeffs = analog2digital(n, hproto[0], hproto[1], fc) make_filter(:xcoeffs, coeffs[0].scale!(proto[2]), :ycoeffs, coeffs[1]) end add_help(:make_inverse_chebyshev_bandpass, "make_inverse_chebyshev_bandpass(n, fl, fh, loss_dB=60.0): \ returns a bandpass inverse-Chebyshev filter; N = order, \ FL and FH are edge freqs (srate = 1.0): make_inverse_chebyshev_bandpass(8, 0.1, 0.4)") def make_inverse_chebyshev_bandpass(n, fl, fh, loss_dB = 60.0) lp = make_inverse_chebyshev_lowpass(n, fh, loss_dB) hp = make_inverse_chebyshev_highpass(n, fl, loss_dB) lambda do |y| filter(lp, filter(hp, y)) end end add_help(:make_inverse_chebyshev_bandstop, "make_inverse_chebyshev_bandstop(n, fl, fh, loss_dB=60.0): \ returns a bandstop inverse-Chebyshev filter; N = order, \ FL and FH are edge freqs (srate = 1.0): make_inverse_chebyshev_bandstop(8, 0.1, 0.4, 90)") def make_inverse_chebyshev_bandstop(n, fl, fh, loss_dB = 60.0) lp = make_inverse_chebyshev_lowpass(n, fl, loss_dB) hp = make_inverse_chebyshev_highpass(n, fh, loss_dB) lambda do |y| filter(lp, y) + filter(hp, y) end end if provided? :gsl # requires with-gsl if defined? gsl_roots # gsl_roots isn't defined for ruby in snd-xen.c # # === BESSEL(-Thompson) === # def fact(n) x = 1 2.upto(n) do |i| x *= i end x end def bessel_i(n) Vct.new(n + 1) do |i| fact(2 * n - i) / ((2 ** (n - i)) * fact(i) * fact(n - i)) end end def bessel_prototype(n) len = (n * 3) / 2 num = Vct.new(len) den = Vct.new(len) b2 = bessel_i(n) p = gsl_roots(b2.to_a) p.map! do |x| x / (b2[0] ** (1.0 / n)) end j = 0 0.step(n - 1, 2) do |i| num[j + 0] = 0.0 num[j + 0] = 0.0 num[j + 2] = 1.0 den[j + 0] = 1.0 den[j + 0] = -2.0 * p[i].real den[j + 2] = (p[i] * p[i + 1]).real j += 3 end [num, den] end add_help(:make_bessel_lowpass, "make_bessel_lowpass(n, fc): \ returns a lowpass Bessel filter; N = order, \ FC = cutoff freq (srate = 1.0): make_bessel_lowpass(4, 0.1)") def make_bessel_lowpass(n, fc) if n.odd? then n += 1 end proto = bessel_prototype(n) coeffs = analog2digital(n, proto[0], proto[1], fc) make_filter(:xcoeffs, coeffs[0], :ycoeffs, coeffs[1]) end add_help(:make_bessel_highpass, "make_bessel_highpass(n, fc): \ returns a highpass Bessel filter; N = order, \ FC = cutoff freq (srate = 1.0): make_bessel_highpass(8, 0.1)") def make_bessel_highpass(n, fc) if n.odd? then n += 1 end proto = bessel_prototype(n) hproto = prototype2highpass(n, proto[0], proto[1]) coeffs = analog2digital(n, hproto[0], hproto[1], fc) make_filter(:xcoeffs, coeffs[0], :ycoeffs, coeffs[1]) end add_help(:make_bessel_bandpass, "make_bessel_bandpass(n, fl, fh): \ returns a bandpass Bessel filter; N = order, \ FL and FH are edge freqs (srate = 1.0): make_bessel_bandpass(4, 0.1, 0.2)") def make_bessel_bandpass(n, fl, fh) lp = make_bessel_lowpass(n, fh) hp = make_bessel_highpass(n, fl) lambda do |y| filter(lp, filter(hp, y)) end end add_help(:make_bessel_bandstop, "make_bessel_bandstop(n, fl, fh): \ returns a bandstop Bessel filter; N = order, \ FL and FH are edge freqs (srate = 1.0): make_bessel_bandstop(8, 0.1, 0.2)") def make_bessel_bandstop(n, fl, fh, ripple = 1.0, loss_dB = 60.0) lp = make_bessel_lowpass(n, fl) hp = make_bessel_highpass(n, fh) lambda do |y| filter(lp, y) + filter(hp, y) end end end # # === ELLIPTIC === # def minimize_function(f, xmin, xmax, arg1 = nil, arg2 = nil) fx = snd_func(f, xmin, arg1, arg2) n = 20 x = Vct.new(n) n.times do |i| step = (xmax - xmin) / (n - 1.0) s = xmin (n - 1).times do |j| x[j] = s s += step end x[n - 1] = xmax n.times do |j| ft = snd_func(f, x[j], arg1, arg2) if ft < fx fx = ft xmax = (j < (n - 1)) ? x[j + 1] : x[n - 1] xmin = j > 0 ? x[j - 1] : x[0] end end end (xmax + xmin) / 2.0 end def findm(m, arg1, arg2) (gsl_ellipk(m) / gsl_ellipk(1.0 - m) - arg1).abs end def findv(u, arg1, arg2) vals = gsl_ellipj(u, arg1) (arg2 - vals[0] / vals[1]).abs end def elliptic_prototype(n, ripple = 1.0, loss_dB = 60.0) e = sqrt((10.0 ** (0.1 * ripple)) - 1.0) k1 = e / sqrt((10.0 ** (0.1 * loss_dB)) - 1.0) k1p = sqrt(1.0 - k1 * k1) kr = m = k = 0.0 len = (n * 3) / 2 num = Vct.new(len) den = Vct.new(len) g = 1.0 eps = 0.0000001 if (1.0 - k1p * k1p).abs > eps kr = n.to_f * (gsl_ellipk(k1 * k1) / gsl_ellipk(k1p * k1p)) end m = minimize_function(:findm, 0.001, 0.999, kr) k = gsl_ellipk(m) cv = Vct.new((0.5 * 3 * (n + 1)).floor) j = 0 0.step(n - 1, 2) do |i| vals = gsl_ellipj(((i + 1) * k) / n.to_f, m) sn, cn, dn = vals[0..2] cv[j + 0] = sn cv[j + 1] = cn cv[j + 2] = dn z = Complex(0.0, -1.0) / (sqrt(m) * sn) pz = (z * make_rectangular(z.real, -z.imag)).real g /= pz num[j + 0] = 1.0 num[j + 1] = -2.0 * z.real num[j + 2] = pz j += 3 end optarg0 = k1p * k1p optarg1 = 1.0 / e minf = minimize_function(:findv, 0.0, 1.0 / e, optarg0, optarg1) v0 = (k * minf) / (n.to_f * gsl_ellipk(k * k1)) vals = gsl_ellipj(v0, 1.0 - m) sn, cn, dn = vals[0..2] j = 0 0.step(n - 1, 2) do |i| p = -(cv[j + 1] * cv[j + 2] * sn * cn + (Complex(0.0, 1.0) * cv[j + 0] * dn)) / (1.0 - (cv[j + 2] * sn * cv[j + 2] * sn)) pp = (p * make_rectangular(p.real, -p.imag)).real g *= pp den[j + 0] = 1.0 den[j + 1] = -2.0 * p.real den[j + 2] = pp j += 3 end g = (g / sqrt(1.0 + e * e)).abs [num, den, g] end # n = order, fc = cutoff freq (srate = 1.0) add_help(:make_elliptic_lowpass, "make_elliptic_lowpass(n, fc, ripple=1.0, loss_dB=60.0): \ returns a lowpass elliptic filter; N = order, \ FC = cutoff freq (srate = 1.0): make_elliptic_lowpass(8, 0.25, 0.01, 90)") def make_elliptic_lowpass(n, fc, ripple = 1.0, loss_dB = 60.0) if n.odd? then n += 1 end proto = elliptic_prototype(n, ripple, loss_dB) coeffs = analog2digital(n, proto[0], proto[1], fc) make_filter(:xcoeffs, coeffs[0].scale!(proto[2]), :ycoeffs, coeffs[1]) end add_help(:make_elliptic_highpass, "make_elliptic_highpass(n, fc, ripple=1.0, loss_dB=60.0): \ returns a highpass elliptic filter; N = order, \ FC = cutoff freq (srate = 1.0): make_elliptic_highpass(8, 0.25, 0.01, 90)") def make_elliptic_highpass(n, fc, ripple = 1.0, loss_dB = 60.0) if n.odd? then n += 1 end proto = elliptic_prototype(n, ripple, loss_dB) hproto = prototype2highpass(n, proto[0], proto[1]) coeffs = analog2digital(n, hproto[0], hproto[1], fc) make_filter(:xcoeffs, coeffs[0].scale!(proto[2]), :ycoeffs, coeffs[1]) end add_help(:make_elliptic_bandpass, "make_elliptic_bandpass(n, fl, fh, ripple=1.0, loss_dB=60.0): \ returns a bandpass elliptic filter; N = order, \ FL and FH are edge freqs (srate = 1.0): make_elliptic_bandpass(6, 0.1, 0.2, 0.1, 90)") def make_elliptic_bandpass(n, fl, fh, ripple = 1.0, loss_dB = 60.0) lp = make_elliptic_lowpass(n, fh, ripple, loss_dB) hp = make_elliptic_highpass(n, fl, ripple, loss_dB) lambda do |y| filter(lp, filter(hp, y)) end end add_help(:make_elliptic_bandstop, "make_elliptic_bandstop(n, fl, fh, ripple=1.0, loss_dB=60.0): \ returns a bandstop elliptic filter; N = order, \ FL and FH are edge freqs (srate = 1.0): make_elliptic_bandstop(6, 0.1, 0.2, 0.1, 90)") def make_elliptic_bandstop(n, fl, fh, ripple = 1.0, loss_dB = 60.0) lp = make_elliptic_lowpass(n, fl, ripple, loss_dB) hp = make_elliptic_highpass(n, fh, ripple, loss_dB) lambda do |y| filter(lp, y) + filter(hp, y) end end end end include Analog_filter # analog-filter.rb ends here snd-16.1/peak-phases.scm0000644000076400007640000313756712626046436013277 0ustar bilbil(provide 'snd-peak-phases.scm) (load "primes.scm") ;;; multiply these phases by pi before use as initial-phases (and use sin, not cos -- see tstall below) ;;; to translate these peaks into the more standard crest-factor, (/ (* peak (sqrt 2)) (sqrt N)) ;;; in the all harmonics case, these go from 1.356 (20) to 1.406 (106) leaving aside N<8 ;;; the square root => sqrt(2), so 1.414 is not good. (define fv float-vector) ;;; ---------------------------------------- all harmonics ---------------------------------------- (define noid-min-peak-phases (vector (vector 1 1.0 (fv 0)) (vector 2 1.76 (fv 0 0)) ;; the 1.76 can be calculated (given here that 0 is the min) ;; take derivative of sin(x) + sin(2x) = cos(x) + 2cos(2x) ;; use cos(2x) = 2cos^2(x) - 1 to turn this into a quadratic polynomial in cos(x) ;; 4cos^2(x) + cos(x) - 2 ;; let x be cos(x), quadratic formula gives (-1 + sqrt(33))/8, [poly-roots (float-vector -2 1 4) -> (0.59307033081725 -0.84307033081725)] ;; take acos of that to get cos(x): ;; (acos (+ -1/8 (/ (sqrt (+ 1 32)) 8))) -> 0.93592945566133 ;; plug that into the original: ;; (+ (sin 0.93592945566133) (sin (* 2 0.93592945566133))) -> 1.7601725930461 ;; see smax in clm.c -- this works for small n ;; ;; for 1+3, diff is 12cos^3x-8cosx so (acos 0) = pi/2 is a red-herring, but 3cos^2x-2 -> x = (sqrt 2/3), (acos (sqrt 2/3)) -> 0.61547970867039 ;; and (+ (sin 0.61547970867039) (sin (* 3 0.61547970867039))) is 1.539600717839 and ;; 1.5396 + 0.4604 * sin(initial-phase) is very close. ;; ;; we can show that phase=0 is the global min by using simultaneous non-linear equations: ;; ;; let peak-loc = (acos (/ (- (sqrt 33) 1) 8)) ;; peak (+ (sin peak-loc) (sin (* 2 peak-loc))) ;; and assume we're focusing on the 1st min (not pi) ;; ;; sin(peak-loc) + sin(2*peak-loc + phase) <= peak ;; so sin(2*peak-loc (i.e. 1.8718) + phase) < (peak - sin(peak-loc)) = 0.9551, but that means phase >= 0 (sin is going down at this point) ;; sin(-peak-loc) + sin(2*(-peak-loc) + phase) >= -peak ;; so sin(2*(-peak-loc) + phase) >= -(peak - sin(peak-loc)) = -0.9551, so phase <= 0 (sin is going up) ;; so phase must be 0 [this argument assumes the peak loc is not jumping around randomly] ;; ;; I think we can play the same game in n=3 case, but now there are 6 (12?) peaks to fiddle with and 4 global mins ;; so it's messier. ;; there's always an equivalent point found by flipping the even harmonics, and another pair at 2-val (symmetry around 0) ;; so there are 4 equivalent points. A function that returns the other 3 given 1 is at the end of this file. ;;; 3 all -------------------------------------------------------------------------------- (vector 3 2.1949383250709 (fv 0 0 1) 1.9798054823226 (fv 0.0 5.897251124274717204443163609539624303579E-1 3.166675693251937984129540382127743214369E-1) 1.9798054823222 (fv 0.0 4.102748875720859667026729766803327947855E-1 1.683332430673265878162681019603041931987E0) 1.9798054823226 (fv 0.0 1.58972511242745917492413809668505564332E0 3.166675693251493894919690319511573761702E-1) 1.9798054823222 (fv 0.0 1.410274887572085966702672976680332794785E0 1.683332430673265878162681019603041931987E0) ;; :(tstall (fv 0 62/39 19/60)) ;; (1.979860844111887127172689015942912379187E0 5.5534000000004) ;; same for (fv 0 23/39 19/60), always the case (it's symmetric in the 2nd), sin(x) +/- sin(2x + a) + sin(3x + b) ;; :(tstall (fv 0.0 5.897251124274717204443163609539624303579E-1 3.166675693251937984129540382127743214369E-1) 0.0000001) ;; (1.979806197137575924716806491964687429097E0 0.1714663000039) 1.9797181063317 (fv 0.0 0.41022177723939 1.6832780274654) 1.979716725384 (fv 0.0 1.5897793760084 0.31672588155614) 1.9797162690553 (fv 0.0 1.4102202429311 1.6832728267862) ;; polynomial is surprisingly good: ;; :all 3 (fv 1.9797767193773 0.066455282926612 1.7863254855475) ;; big fft 1.979806 #(0.000000 0.410275 1.683332) ) ;;; 4 all -------------------------------------------------------------------------------- (vector 4 2.2962718935302 (fv 0 1 1 1) 2.040 (fv 0 33/35 67/50 10/9) ;(vector 0 1/9 17/24 71/36) -- 2.04242 2.04012799263 (fv 0.000 0.072 0.674 1.912) 2.04012799263 (fv 0.000 0.928 1.326 1.088) 2.04012799263 (fv 0.000 1.072 0.674 0.912) 2.04012799263 (fv 0.000 1.928 1.326 0.088) 2.0392323180235 (fv 0.0 9.429973765023149656627765580196864902973E-1 1.340090256365081833322960846999194473028E0 1.112605206055434337031329050660133361816E0) 2.038956 (fv 0.000000 0.944585 1.341508 1.115059) 2.038954 (fv 0.000000 1.055406 0.658486 0.884929) 2.038954 (fv 0.000000 0.055405 0.658485 1.884926) 2.038954 (fv 0.000000 1.944593 1.341515 0.115071) ;; :all 4 (fv 2.060278672942 -0.70579973196553 0.90455920034382) ;; big fft 2.039104 #(0.000000 0.055486 0.658542 1.885004) 2.039103 #(0.000000 0.055488 0.658545 1.885009) ) ;;; 5 all -------------------------------------------------------------------------------- ; 2.23 (vector 5 2.5405211753511 (fv 0 1 0 0 0) 2.3434929847717 (fv 0.0 0.84531772136688 1.6645057201385 1.4203575849533 1.5933285951614) 2.3434844481891 (fv 0.0 1.8453152570243 1.6649825491504 0.42142125263938 1.5942588576594) 2.343549 (fv 0.000000 1.845237 1.664402 0.420189 1.593154) 2.343533 (fv 0.000000 1.154716 0.335535 0.579695 0.406714) 2.343497 (fv 0.000000 0.845320 1.664496 1.420334 1.593308) 2.343527 (fv 0.000000 0.154667 0.335503 1.579672 0.406698) 2.343513 (fv 0.000000 0.154687 0.335490 1.579647 0.406677) 2.343508 (fv 0.000000 1.845332 1.664532 0.420369 1.593338) ;; pp: 2.343485 (fv 0.000000 1.154683 0.335509 0.579687 0.406716) ) ;;; 6 all -------------------------------------------------------------------------------- ; 2.4494 (vector 6 2.8200183503167 (fv 0 0 0 0 1 0) 2.5598928928375 (fv 0.0 0.91140931844711 0.34124284982681 1.3568490743637 1.4451304674149 1.2563138008118) 2.5509102344513 (fv 0.0 0.88722838124921 0.26020415169852 1.2966409163042 1.3233535939997 1.15281977798) 2.5493413065822 (fv 0.0 0.88655948906463 0.26426014425456 1.3003055923199 1.3306838066896 1.1573162129407) 2.549466 (fv 0.000000 1.113453 1.735461 0.699472 0.668803 0.842320) 2.549414 (fv 0.000000 0.886661 0.264519 1.300599 1.331194 1.157723) 2.549386 (fv 0.000000 0.113427 1.735535 1.699526 0.668940 1.842412) 2.549385 (fv 0.000000 1.886568 0.264458 0.300485 1.331039 0.157570) 2.549360 (fv 0.000000 0.886491 0.264319 1.300337 1.330828 1.157371) ) ;;; 7 all -------------------------------------------------------------------------------- ; 2.64575 (vector 7 3.072141248417 (fv 0 0 0 1 1 0 1) 2.639426 (fv 0.000000 0.904980 0.986109 1.721148 1.291116 1.621443 0.966099) 2.639402 (fv 0.000000 0.095202 1.014213 1.278914 0.709149 1.378847 1.034223) 2.639371 (fv 0.000000 1.095652 1.014884 0.279318 0.709755 0.379605 1.035166) 2.639364 (fv 0.000000 1.904695 0.985719 0.720925 1.290796 0.621014 0.965536) ) ;;; 8 all -------------------------------------------------------------------------------- ; 2.8284 (vector 8 3.4905790371793 (fv 0 1 0 0 1 1 1 0) 2.795099 (fv 0.000000 1.333103 1.192134 0.394213 1.162609 1.955320 1.855302 0.126169) 2.794748 (fv 0.000000 0.333225 1.192073 1.394414 1.162519 0.954914 1.855082 1.126189) 2.794737 (fv 0.000000 1.666686 0.807757 0.605305 0.837099 1.044558 0.144428 0.873255) 2.794719 (fv 0.000000 0.666709 0.807769 1.605408 0.837217 0.044625 0.144433 1.873342) 2.794585 (fv 0.000000 0.666699 0.807707 1.605285 0.837106 0.044540 0.144374 1.873180) ;; pp: 2.880745 (fv 0.000000 0.873927 1.696839 1.009332 0.354675 0.227015 0.156852 0.523641) ;; big fft 2.794684 #(0.000000 0.333223 1.192169 1.394521 1.162690 0.955202 1.855341 1.126445) ) ;;; 9 all -------------------------------------------------------------------------------- (vector 9 3.5954569026984 (fv 0 1 1 0 1 0 1 1 1) 2.962087 (fv 0.000000 0.872517 1.501013 0.464057 -0.056897 1.063020 1.251698 1.436014 1.254131) 2.962094 (fv 0.000000 1.127564 0.498862 1.535743 0.056794 0.936657 0.748023 0.563510 0.745376) 2.962065 (fv 0.000000 -0.127444 1.501316 1.464492 -0.056263 0.063823 1.252240 0.437075 1.255320) 2.961916 (fv 0.000000 0.127632 0.498978 0.536080 0.057253 -0.062716 0.748729 1.564172 0.746161) 2.961829 (fv 0.000000 1.872309 1.500693 1.463585 1.942384 0.062267 1.250564 0.435026 1.252813) 2.961652 (fv 0.000000 1.872337 1.500914 1.463820 1.942618 0.062504 1.251193 0.435609 1.253539) ;; pp: 2.961653 (fv 0.000000 0.872337 1.500915 0.463821 1.942617 1.062504 1.251196 1.435614 1.253542) ) ;;; 10 all -------------------------------------------------------------------------------- ; 3.162 (vector 10 3.7587492407668 (fv 0 1 1 0 1 1 1 0 0 0) 3.102964 (fv 0.000000 0.071632 0.396251 0.504925 0.052683 0.212597 1.057168 -0.172275 1.102043 0.501144) 3.102823 (fv 0.000000 1.070629 0.394872 1.503703 0.050925 1.211208 1.054650 0.825637 1.099957 1.498128) 3.102782 (fv 0.000000 0.927743 1.602314 0.494139 -0.054832 0.785103 0.940332 1.169212 0.894844 0.494709) 3.102734 (fv 0.000000 1.928606 1.603786 1.495372 -0.052790 1.786999 0.942669 0.172108 0.897837 1.498611) 3.102303 (fv 0.000000 -0.071891 1.603086 1.494633 -0.053985 1.786024 0.941426 0.170569 0.896122 1.496522) ;; pp: 3.270687 (fv 0.000000 1.665169 -0.138115 1.364203 0.226693 -0.150959 1.661874 0.514042 1.098209 1.445028) ) ;;; 11 all -------------------------------------------------------------------------------- ; 3.31662 (vector 11 3.8018732822274 (fv 0 1 0 0 1 0 0 0 1 1 1) 3.218745 (fv 0.000000 1.518100 1.908924 1.617043 1.540909 0.660141 -0.056826 0.670660 1.165195 1.212229 0.198401) 3.218587 (fv 0.000000 0.518100 1.908924 0.617043 1.540909 1.660141 -0.056826 1.670660 1.165195 0.212229 0.198401) 3.218514 (fv 0.000000 0.481786 0.091759 0.383540 0.459429 1.340439 0.058075 1.330988 0.836240 0.789345 -0.196819) 3.218444 (fv 0.000000 0.482127 0.090769 0.383093 0.459045 1.339823 0.056682 1.328792 0.834826 0.787716 -0.199032) 3.217965 (fv 0.000000 0.482287 0.091029 0.383292 0.459507 1.340271 0.057231 1.329368 0.835616 0.788459 -0.198129) ;; pp: 3.468683 (fv 0.000000 0.627804 1.366835 0.412917 1.258123 0.658181 0.350130 1.736695 1.823585 1.864191 0.254629) ) ;;; 12 all -------------------------------------------------------------------------------- ; 3.464 (vector 12 3.7616552322386 (fv 0 1 1 0 0 1 0 1 0 0 0 0) 3.389586 (fv 0.000000 0.076743 0.348321 0.615321 0.763893 0.188090 0.117764 1.147735 1.461927 0.591300 1.497863 0.867456) 3.389547 (fv 0.000000 -0.079085 1.648740 1.380212 1.228354 1.804105 1.875295 0.844196 0.527781 1.396624 0.490362 1.119947) 3.389430 (fv 0.000000 1.081078 0.354514 1.624157 0.776410 1.200581 0.129241 0.162495 1.480822 1.614178 1.518801 1.892528) 3.389128 (fv 0.000000 1.076659 0.348730 1.615059 0.764020 1.188577 0.117561 0.148053 1.462454 1.591386 1.497945 1.868055) 3.388654 (fv 0.000000 1.076620 0.347797 1.614462 0.764164 1.188107 0.116910 0.147164 1.461571 1.590619 1.496557 1.866148) ;; pp: 3.546003 (fv 0.000000 0.813150 -1.878303 1.450426 -0.112095 -1.110299 -0.487466 -0.181683 0.060170 -0.004101 -0.103775 -0.960524) ) ;;; 13 all -------------------------------------------------------------------------------- ; 3.6055 (vector 13 4.1211657406183 (fv 0 0 0 0 0 0 1 1 0 0 1 0 1) 3.525309 (fv 0.000000 1.051846 0.170520 1.635159 0.455907 1.511384 -0.147127 1.055447 1.000548 0.097871 0.005880 0.160672 0.616896) 3.525164 (fv 0.000000 0.947554 1.827637 0.362791 1.540717 0.485315 0.143016 0.940517 0.994364 1.896615 -0.012058 1.833412 1.375539) 3.525069 (fv 0.000000 0.947187 1.827546 0.362752 1.541123 0.485247 0.142279 0.941021 0.994821 1.896143 -0.012766 1.832600 1.375866) ;; tstall (flip odds): 3.5254909 (fv 0.000000 0.051846 0.170520 0.635159 0.455907 0.511384 -0.147127 0.055447 1.000548 1.097871 0.005880 1.160672 0.616896) 3.525038 (fv 0.000000 0.946517 1.827042 0.361916 1.539603 0.484426 0.141403 0.938505 0.992273 1.893878 -0.015423 1.830018 1.372777) 3.524879 (fv 0.000000 0.948502 1.829668 0.364984 1.544240 0.488687 0.147763 0.945396 1.000061 1.903153 -0.004551 1.840699 1.384079) 3.524127 (fv 0.000000 0.948325 1.829839 0.364837 1.544231 0.489035 0.147691 0.944940 1.000036 1.902764 -0.004752 1.840449 1.384160) ;; pp: 3.850623 (fv 0.000000 0.969515 0.236902 1.700081 1.532485 1.012414 0.716276 0.879825 0.831162 1.111747 1.357361 -0.014630 0.962342) ) ;;; 14 all -------------------------------------------------------------------------------- ; 3.7416 (vector 14 4.1603193984251 (fv 0 1 0 1 1 0 1 0 0 0 1 0 0 0) 3.613280 (fv 0.000000 0.028982 0.530538 0.496734 -0.474935 -0.580078 0.104750 1.488617 -0.565757 -0.157842 -1.258035 -0.057079 0.253472 -0.294346) 3.613121 (fv 0.000000 0.028974 0.530453 0.496128 -0.475742 -0.580534 0.104588 -0.512201 1.433649 1.841085 0.741103 -0.058374 0.252301 -0.295482) 3.612244 (fv 0.000000 0.028654 0.530107 0.495786 -0.476137 -0.581023 0.103729 -0.513152 1.433095 1.840437 0.739729 -0.059420 0.251093 -0.296875) ;; pp: 3.738333 (fv 0.000000 0.876144 1.749283 0.255257 1.233908 0.925717 1.713300 0.790918 0.423428 0.079568 -0.060539 0.064404 0.601933 0.291808) ) ;;; 15 all -------------------------------------------------------------------------------- ; 3.8729 (vector 15 4.4060654286219 (fv 0 1 0 1 0 1 1 1 1 1 0 1 1 0 0) ; 3.87298 (3.8729833462074) 3.768991 (fv 0.000000 0.863434 1.069349 1.651266 0.272078 0.287377 1.735528 1.050008 0.997192 -0.020076 1.092043 1.658049 1.188297 1.641481 1.391589) 3.768033 (fv 0.000000 0.863152 1.069135 1.651353 0.271851 0.287255 1.735115 1.049678 0.996877 -0.020587 1.091869 1.657562 1.187769 1.641176 1.391193) ;; pp: 3.859726 (fv 0.000000 0.426404 1.082257 -0.378600 0.672681 0.084435 0.794375 -0.135830 -0.492292 -0.747360 0.439828 0.395595 0.865535 0.672400 -1.271921) ) ;;; 16 all -------------------------------------------------------------------------------- (vector 16 4.5445760745314 (fv 0 1 1 0 1 0 1 0 0 0 1 1 0 0 0 0) 3.875080 (fv 0.000000 0.730612 0.678979 1.195144 1.632126 1.276744 -0.008560 1.467028 0.525375 0.204869 -0.166129 -0.115302 1.317856 1.622654 0.244306 1.412402) 3.873760 (fv 0.000000 0.727564 0.672436 1.188603 1.622426 1.266314 -0.018679 1.451325 0.507181 0.185750 -0.189066 -0.140317 1.293402 1.595942 0.216437 1.382779) ;; pp: 3.898248 (fv 0.000000 0.999637 1.627971 0.563839 1.354119 0.602036 1.818873 1.125095 0.889883 0.658070 0.547416 0.178002 0.696357 0.711221 1.277932 1.486763) ) ;;; 17 all -------------------------------------------------------------------------------- ; 4.1231 (vector 17 4.7654988506492 (fv 0 0 0 0 1 1 0 1 0 0 1 1 1 0 1 1 1) 3.981459 (fv 0.000000 0.520484 1.429480 0.505816 -0.891395 0.114390 0.146335 0.416197 0.938893 0.898753 0.507264 0.650687 -0.081499 -0.607990 0.213218 -0.096782 -0.652476) 3.980210 (fv 0.000000 0.519908 1.429364 0.506455 -0.889349 0.115888 0.147799 0.418944 0.941982 0.901488 0.510707 0.653289 -0.078010 -0.603698 0.217190 -0.091931 -0.646982) ;; pp: 4.025451 (fv 0.000000 0.806442 1.640772 0.524823 1.518315 0.179778 1.375417 0.889535 -0.006539 1.626695 1.126057 1.328368 0.940320 1.091090 1.265244 1.868967 -0.027469) ) ;;; 18 all -------------------------------------------------------------------------------- ; 4.24264 (vector 18 4.795 (fv 0 0 0 0 0 0 0 1 1 0 0 1 0 0 1 0 1 0) 4.145376 (fv 0.000000 0.815970 1.442468 0.022437 0.838057 0.561089 1.647234 0.678944 1.711039 1.021597 1.327383 0.016884 -0.030470 1.937927 0.480054 1.947188 1.779952 1.482341) 4.139748 #(0.000000 0.841029 1.468092 0.061368 0.883567 0.618102 1.726318 0.769330 1.807136 1.123961 1.445068 0.140416 0.092314 0.077559 0.642622 0.110176 1.960387 1.676428) 4.139675 #(0.000000 0.843694 1.471411 0.063968 0.889446 0.622071 1.732660 0.775711 1.815657 1.135238 1.453657 0.151363 0.100548 0.088867 0.654716 0.119261 -0.025900 1.692198) ) ;;; 19 all -------------------------------------------------------------------------------- ; 4.35889 (vector 19 4.957 (fv 0 1 0 0 1 1 1 1 1 1 0 0 1 1 1 0 1 0 1) 4.220950 (fv 0.000000 0.963878 0.724427 1.142775 1.347933 0.681634 0.858134 1.165699 1.071759 -0.202310 0.544201 1.698473 0.575529 0.392352 1.327300 -0.513540 0.980505 1.004716 0.307249) 4.218225 #(0.000000 0.975837 0.737298 1.163191 1.372213 0.708367 0.893430 1.205301 1.114000 -0.155007 0.595375 1.754296 0.630178 0.457584 1.398341 -0.439927 1.059040 1.087418 0.391362) ;; pp: 4.321309 (fv 0.000000 0.745098 1.155175 -0.037958 0.532342 1.473567 0.665377 -0.049708 1.767937 0.914818 -0.119772 -0.388406 1.775638 1.206519 1.079401 1.118695 1.930701 1.737887 -0.008406) ) ;;; 20 all -------------------------------------------------------------------------------- ; 4.4721 (vector 20 5.202707605727 (fv 0 0 0 0 1 1 0 1 0 0 1 0 1 1 1 0 1 1 1 0) 4.288981 (fv 0.000000 1.288096 1.467454 -0.169090 1.858403 0.280935 0.217741 -0.031571 0.876318 1.220549 0.027164 0.381448 1.736192 1.508757 1.292734 0.007137 1.225400 0.645757 1.237414 0.420948) 4.287997 #(0.000000 1.306723 1.491084 -0.138208 -0.106223 0.318045 0.270418 0.024135 0.938829 1.289927 0.097314 0.462063 -0.166575 1.604629 1.393707 0.120917 1.335729 0.768117 1.366096 0.562618) ;; pp: 4.467948 (fv 0.000000 0.926509 1.348679 0.244038 1.242002 0.019828 1.173056 0.068338 1.504010 1.041584 0.276603 1.806452 1.767012 1.665479 1.374797 1.361818 1.827476 0.132481 0.796064 0.727142) ) ;;; 21 all -------------------------------------------------------------------------------- ; 4.5825 (vector 21 5.3164971341632 (fv 0 0 0 1 0 1 1 1 1 1 0 1 1 0 1 1 0 0 0 1 0) 4.482399 (fv 0.000000 1.397497 1.231727 1.288294 -0.006341 1.417563 -0.224775 1.544084 0.158820 1.058039 0.318600 1.788531 1.041209 0.988222 1.527762 0.536397 0.600751 0.298693 0.721205 1.590350 -0.083320) ;; pp: 4.574194 (fv 0.000000 0.830108 1.212818 -0.114835 0.663864 1.570276 0.585550 1.478198 0.603181 0.202958 1.649503 0.901982 0.255866 0.012434 0.019243 -0.386770 -0.332788 -0.375429 0.023280 0.553342 0.478240) ;;20+1 4.466298 #(0.000000 0.909097 0.238169 0.468983 0.883242 -0.050068 0.873199 0.299129 0.119990 0.693144 0.718516 0.626261 1.588601 1.027074 -0.097623 0.296983 1.533310 -0.381362 -0.344831 0.732964 0.856609) 4.446059 #(0.000000 0.180019 0.218530 0.984925 -0.958137 -0.620910 0.483363 0.553272 0.541028 -0.013728 0.552503 0.454333 1.235179 -1.297121 0.258699 -0.559729 -0.469061 0.813196 -0.429872 0.235309 -0.551694) 4.442505 #(0.000000 0.229264 0.300308 1.095021 -0.794869 -0.465067 0.642830 0.761336 0.766200 0.262204 0.844388 0.785992 1.557676 -0.940794 0.628826 -0.139027 -0.056712 1.215181 0.022101 0.740212 -0.084960) ) ;;; 22 all -------------------------------------------------------------------------------- ; 4.6904 (vector 22 5.292244006282 (fv 0 0 1 1 1 0 0 1 1 0 1 1 0 0 0 0 0 0 1 0 1 0) 4.586632 (fv 0.000000 -0.097347 1.080504 0.590888 -0.253961 1.023423 0.714156 1.899465 -0.021982 0.277218 1.158938 0.994197 1.053415 1.055197 1.429563 0.904330 0.879709 1.421582 0.356096 1.550705 0.340822 1.056446) ;; pp: 4.652382 (fv 0.000000 0.770633 1.384088 0.317715 1.400813 0.382294 1.252492 0.280512 1.930558 1.151783 0.690579 0.045402 0.011035 1.255532 1.463333 1.386585 0.797105 0.928163 1.091040 1.178341 1.461782 1.888245) ;; 20+2 4.571664 #(0.000000 1.311821 0.851164 0.580547 0.048402 1.274604 0.456442 1.682804 0.779139 1.627033 1.074351 1.013793 0.652224 0.595232 0.638584 1.055905 1.176957 1.287858 0.085124 0.572185 1.547525 0.045133) 4.539850 #(0.000000 1.877088 1.220531 0.766350 0.912511 -0.049264 -0.015453 1.476348 0.128719 1.226510 1.377381 1.241269 1.228768 0.089299 1.482606 0.589500 -0.172007 0.157776 0.679537 0.684018 -0.353829 0.532234) ) ;;; 23 all -------------------------------------------------------------------------------- ; 4.7958 (vector 23 5.3592889520338 (fv 0 0 1 1 0 1 1 0 0 1 1 1 1 0 0 1 0 1 0 1 1 1 1) 4.605166 (fv 0.000000 0.690307 -0.223703 0.265767 1.214689 0.913389 0.192629 1.489393 1.370656 0.848931 0.362934 0.592228 0.586290 0.001276 1.085398 1.699229 1.577973 0.044583 0.292577 1.343812 0.079208 -0.074880 0.197817) 4.603716 #(0.000000 0.728519 -0.170578 0.343467 1.289714 1.021005 0.302988 1.638069 1.530207 1.013139 0.545865 0.789599 0.817820 0.223908 1.348504 -0.016545 -0.131209 0.351331 0.607617 -0.321862 0.423879 0.291671 0.585222) ;; pp: 4.710615 (fv 0.000000 0.902511 1.536988 0.243249 1.001545 1.634662 0.695827 1.858861 0.975507 -0.294658 1.045533 0.585569 -0.187029 1.386517 1.153500 1.032794 1.102165 0.705294 0.968823 1.234672 1.719694 1.916952 0.231307) ) ;;; 24 all -------------------------------------------------------------------------------- ; 4.89897 (vector 24 5.6358969066981 (fv 0 0 0 1 0 1 1 1 0 0 0 1 1 0 1 1 1 1 1 1 0 1 1 0) 4.728042 (fv 0.000000 1.858980 1.366314 1.303093 0.303565 0.363906 -0.013052 0.288365 1.150614 1.733252 0.305478 1.054343 0.956930 0.688496 0.150610 0.766590 0.723928 0.358579 1.444965 0.475911 1.678841 0.331630 0.146133 0.753447) ;; pp: 4.889570 (fv 0.000000 0.652535 1.042108 0.029625 0.992596 0.108788 0.963358 1.727152 1.075228 0.458712 1.655013 0.983185 0.212822 0.044079 1.553136 1.514188 1.228593 0.684074 0.951192 1.149281 1.171121 1.382495 1.676492 0.457795) ;; 23+1 4.797502 #(0.000000 0.815912 -0.489010 0.238747 0.464672 -0.791156 -0.258728 1.104213 0.634676 0.636859 0.115975 -0.179694 0.187452 -0.818880 0.261843 -0.587852 -0.717075 0.590119 -0.373998 0.804963 -0.982681 -0.821174 -0.611885 -0.513579) ) ;;; 25 all -------------------------------------------------------------------------------- ; 5 (vector 25 5.6488965032573 (fv 0 1 0 1 1 0 1 1 0 0 1 1 1 0 0 0 1 0 1 1 1 1 1 1 0) 4.852860 (fv 0.000000 0.230967 1.727317 0.450764 0.017370 0.018890 0.465256 0.875082 0.612377 0.658132 0.067557 0.830777 0.581695 -0.075473 -0.106051 1.748399 0.582315 0.898509 1.395989 0.676438 1.853985 1.350704 1.785330 0.662329 1.015229) ;; pp: 4.921362 (fv 0.000000 0.851508 1.100092 -0.096894 0.569229 1.392351 1.000621 -0.034780 0.968948 0.124084 0.790431 -0.082333 0.100565 1.032584 0.439519 0.313536 0.111622 0.176204 1.585564 1.488261 0.160713 -0.042818 0.611461 0.760689 0.720307) ;; 24+1? 4.867199 #(0.000000 0.511988 0.599074 1.109026 -0.258266 -0.311525 -0.180815 0.514703 -0.058310 0.500087 -0.447647 -1.097227 -0.392984 -0.773229 -0.739391 1.039107 0.423028 -0.118139 1.262658 1.681945 -0.043110 1.191717 1.700807 0.042704 -0.767223) ) ;;; 26 all -------------------------------------------------------------------------------- ; 5.0990 (vector 26 5.7865648269653 (fv 0 1 0 0 1 1 0 1 1 0 0 0 0 0 0 0 1 0 1 0 0 1 1 1 0 0) 5.004963 (fv 0.000000 0.356503 0.613044 0.799459 0.607543 -0.552567 0.275717 0.954617 0.539225 0.390115 0.747516 -0.287816 0.661916 1.821078 -0.045167 -0.217306 1.531723 0.896950 0.283527 0.968137 0.942126 0.004913 -0.474898 0.935500 1.374671 0.106691) 4.982437 #(0.000000 0.157773 0.357579 0.470573 0.208359 -1.095460 -0.324361 0.305853 -0.246382 -0.421030 -0.124942 -1.314179 -0.526336 0.680713 -1.271118 -1.537428 0.186315 -0.648152 -1.272801 -0.741946 -0.801258 -1.769664 -0.386094 -1.048075 -0.774396 -0.009812) 4.981911 #(0.000000 0.114804 0.305276 0.394495 0.122048 -1.227102 -0.469461 0.152164 -0.415952 -0.596715 -0.349375 -1.548844 -0.778154 0.402539 -1.542539 -1.840236 -0.152677 -0.992660 -1.641041 -1.138828 -1.199533 -0.219776 -0.823305 -1.512557 -1.273176 -0.520822) ;; pp: 5.069005 (fv 0.000000 0.693839 1.223177 0.171124 0.655819 1.659284 0.862412 0.167152 1.036280 0.233275 1.065043 0.332100 0.088514 1.217811 0.718617 0.463929 -0.022907 0.301609 1.664942 1.593693 1.159306 1.575199 1.658356 1.791865 0.367495 0.523068) ;; 25+1 5.143899 (fv 0.000000 0.339898 1.703660 0.334703 -0.033066 0.152772 0.352050 0.937913 0.431489 0.569881 0.083296 0.920798 0.392044 -0.279901 -0.309500 1.803373 0.465037 0.973772 1.156286 0.616150 1.812432 1.192020 1.791336 0.747339 0.851095 0.182401) ) ;;; 27 all -------------------------------------------------------------------------------- ; 5.1961 (vector 27 5.8753981590271 (fv 0 1 1 0 1 1 0 1 0 1 0 0 1 0 0 0 0 0 0 1 1 1 0 0 0 1 0) 5.063979 (fv 0.000000 1.181312 1.011523 -0.037795 0.952214 0.743188 0.046346 -0.011550 1.593930 1.829003 1.926981 0.836368 0.497093 0.820784 0.581154 1.308971 0.813642 0.203348 0.448693 0.869589 1.163120 0.319576 0.498929 -0.074366 0.820574 1.666665 0.421783) ;; pp: 5.178190 (fv 0.000000 0.576339 1.415874 0.213916 0.629425 1.693659 0.296051 1.239867 0.501966 1.807544 0.478176 -0.072336 1.103954 0.283214 0.269354 -0.586084 0.967552 0.762560 0.644862 0.769649 0.453206 0.327359 1.119459 1.407959 1.575398 0.090804 0.240986) ;; 26+1 5.126119 #(0.000000 0.900772 1.219713 0.169043 1.065297 1.224400 0.165897 0.980264 0.050341 1.214424 0.625722 0.135385 1.464791 0.070454 0.417426 0.174034 0.437373 0.493624 0.582463 1.623009 1.820016 1.778385 0.847413 1.132593 0.293556 1.847407 0.436103) ) ;;; 28 all -------------------------------------------------------------------------------- ; 5.2915 (vector 28 6.0962085723877 (fv 0 1 0 1 0 1 1 0 1 0 0 1 0 0 1 1 0 0 0 1 0 0 0 0 0 1 1 1) 5.157284 (fv 0.000000 0.613262 -0.034248 0.167107 1.753362 0.009121 1.168065 1.319935 0.754215 1.452315 0.403030 1.384036 -0.445049 1.700477 0.448730 1.102474 0.302577 0.114957 0.813938 -1.221580 0.733588 -0.228287 1.379195 0.775101 0.357079 0.863661 0.744441 -0.542730) 5.156726 #(0.000000 0.621583 -0.025615 0.185073 1.770611 0.035230 1.190822 1.343738 0.783921 1.481359 0.438924 1.421434 -0.401379 1.746999 0.501100 1.159948 0.364927 0.179358 0.879866 -1.146659 0.808429 -0.150109 1.458018 0.864191 0.450456 0.959743 0.840089 -0.445751) ;; pp: 5.257514 (fv 0.000000 0.637044 1.032618 -0.063334 0.493709 1.172496 0.265676 1.071428 0.186660 1.119263 0.450916 1.523906 0.926797 0.655305 -0.125687 1.119620 1.002091 0.595772 0.366822 0.141548 0.074245 -0.326675 0.086270 0.158575 0.648670 0.735199 1.036773 -0.335597) ) ;;; 29 all -------------------------------------------------------------------------------- ; 5.38516 (vector 29 6.168496131897 (fv 0 1 1 0 1 1 0 0 1 0 1 1 1 1 1 1 1 0 0 1 1 1 0 0 1 0 1 0 1) 5.241325 (fv 0.000000 1.424549 1.434579 0.952506 0.877300 1.948583 1.592791 0.964559 0.950012 1.429458 0.788068 0.556113 0.404906 0.813692 1.604109 0.138120 0.925420 1.345282 1.048370 1.281239 1.347177 1.752489 1.781053 0.782127 0.063659 1.163981 0.330203 1.128951 1.871926) ;; pp: 5.354004 (fv 0.000000 0.686564 1.165583 1.805539 0.645303 1.392789 0.389959 1.584227 0.184212 1.132208 0.594808 1.885153 0.760508 0.108139 1.597930 1.248057 0.449409 0.388311 -0.040221 -0.137762 0.035489 0.097197 1.554759 1.643774 1.707832 0.439164 0.286463 0.690398 1.001814) ;; 28+1 5.309949 #(0.000000 0.846874 0.241547 0.392668 0.105733 0.593095 -0.055728 1.769258 1.471201 0.259232 1.487017 0.394902 0.593301 0.594134 1.608339 0.527615 1.618053 1.488443 0.038033 0.264977 0.515061 1.719999 1.612303 0.816240 0.367893 0.553084 0.901271 1.615714 0.762730) ) ;;; 30 all -------------------------------------------------------------------------------- ; 5.4772 (vector 30 6.257221698761 (fv 0 1 0 1 1 1 1 0 0 1 0 0 0 1 1 0 0 1 1 0 1 0 0 1 1 1 1 1 0 1) 5.361273 (fv 0.000000 1.372797 0.670580 1.057136 -0.495516 0.360919 0.095174 0.542106 0.748047 0.327246 -0.458569 -0.196062 0.499790 0.195141 -0.041091 1.640040 0.876134 1.017379 1.243023 0.157336 0.532420 -0.270945 0.222972 -0.454366 0.519190 0.206280 0.985739 0.329627 0.782987 0.753526) ;; pp: 5.457123 (fv 0.000000 0.579295 1.086489 0.271361 0.351869 1.393293 0.343724 1.326421 0.262824 0.711061 0.185497 1.430027 0.435525 0.024911 1.289605 1.541120 0.534068 0.426466 1.770822 1.448308 1.691046 1.363221 0.940381 1.411829 1.232407 1.698674 -0.061281 0.480912 0.397265 0.093509) 5.457522 #(0.000000 0.180374 0.737535 -0.629271 -0.119582 0.936316 1.168308 1.717509 -0.402864 -0.373354 0.211140 0.477066 1.180570 -1.170786 0.943217 0.201779 -0.611919 0.922150 1.095538 0.984255 -0.262406 0.845304 1.611083 0.846240 0.705768 -0.037782 -0.632928 0.048519 -0.449702 1.337980) ;; 29+1 5.407828 #(0.000000 1.401096 1.376571 1.008941 1.027589 -0.085696 1.660515 0.983168 0.985870 1.410812 0.796458 0.476205 0.194328 1.091142 1.765086 0.052662 1.081109 1.265325 0.992243 1.285402 1.599846 1.557990 0.374401 1.559263 0.508151 1.671660 0.671171 1.718845 -0.085252 0.533771) ) ;;; 31 all -------------------------------------------------------------------------------- ; 5.56776 (vector 31 6.3243918418884 (fv 0 0 1 1 1 1 0 1 1 1 0 0 1 0 1 1 0 1 1 0 1 1 1 0 0 0 1 0 1 1 1) 5.479252 (fv 0.000000 1.715332 0.740879 1.282120 0.005121 1.133820 1.648029 0.843835 0.870127 0.362478 -0.012264 1.508703 0.898921 1.010311 1.653601 0.519170 0.543334 0.643526 1.650052 0.937580 0.006302 1.745072 0.413200 1.629321 0.671152 0.807947 1.140772 1.157434 0.674253 1.101147 1.176272) 5.478665 #(0.000000 1.772425 0.803174 1.328405 0.081611 1.219664 1.725421 0.969769 1.009467 0.524607 0.150580 1.691934 1.088386 1.212688 1.849460 0.777872 0.785597 0.893510 -0.072450 1.225337 0.333131 0.071155 0.764064 0.012661 1.020004 1.202423 1.541822 1.587594 1.095956 1.541832 1.635240) 5.457715 #(0.000000 0.335441 1.084827 0.018253 0.737437 1.328926 0.232615 1.324648 1.548727 1.102230 0.582938 0.356482 1.414652 1.240061 0.257198 0.650632 1.787556 1.748026 -0.020851 0.033891 1.146224 0.784975 1.568424 1.015644 1.832440 -0.392011 -0.347982 -0.739222 -0.325456 -0.578410 0.397608) 5.453054 #(0.000000 0.330034 1.062392 -0.018048 0.701747 1.293007 0.182311 1.269874 1.478913 1.017407 0.501409 0.269712 1.315062 1.138628 0.142159 0.526931 -0.345056 1.613950 -0.162150 -0.111306 0.991533 0.609140 1.408136 0.828750 1.658057 -0.598529 -0.552356 -0.936876 -0.551564 -0.796775 0.156224) ;; pp: 5.506117 (fv 0.000000 0.677676 1.291605 1.787569 0.657442 1.382372 0.087522 0.893379 -0.050356 0.800441 -0.050934 1.224977 0.724031 1.793437 1.031051 0.628566 0.200527 1.931215 1.228105 1.043046 0.856098 0.884359 0.667113 1.148772 0.506576 0.784927 0.816254 1.304861 1.786988 1.852001 0.224722) ;;; 30+1 5.550882 #(0.000000 1.425022 0.538933 1.069581 -0.597930 0.307695 0.154011 0.587861 0.779449 0.144783 -0.543105 -0.308223 0.381009 0.256948 -0.103754 1.614961 0.898101 1.043268 1.242618 0.013120 0.441700 -0.261691 0.222365 -0.327392 0.395779 0.143572 0.965764 0.164756 0.636599 0.716823 0.000189) ) ;;; 32 all -------------------------------------------------------------------------------- ; 5.65685 (vector 32 6.4451498985291 (fv 0 0 0 0 0 0 0 0 1 1 0 1 0 0 1 0 0 0 1 1 0 1 1 0 0 0 1 1 1 0 1 0) 5.525650 (fv 0.000000 -0.351133 1.293972 -0.243467 0.375774 0.341597 0.388720 0.121948 0.157486 1.353778 0.236182 0.278745 0.140738 1.315014 1.717753 1.193420 1.734782 1.635830 0.448546 0.657631 0.934238 0.325644 1.910640 1.330301 0.498135 1.394503 1.747576 0.388629 0.706077 0.075100 0.832948 -0.013902) ;; pp: 5.604748 (fv 0.000000 0.799811 1.174111 -0.060224 0.824446 1.499635 0.054636 1.116026 0.103247 0.980855 0.143722 1.410098 0.567912 -0.275862 1.109567 0.582020 0.052513 1.796805 1.346558 0.470148 0.633702 0.311062 0.341355 0.120966 0.347342 -0.087220 -0.235617 0.166536 0.617003 0.982789 1.015963 1.699479) ) ;;; 33 all -------------------------------------------------------------------------------- ; 5.74456 (vector 33 6.5579299926758 (fv 0 1 1 0 1 1 0 1 0 0 0 0 1 1 1 1 0 1 0 1 1 0 0 0 1 0 0 0 1 0 0 0 0) 5.631190 (fv 0.000000 0.097616 0.529848 0.847242 0.662939 0.833596 1.914696 0.035703 0.153599 0.327398 1.407575 -0.021932 0.932495 1.243452 0.370234 0.653095 -0.062589 1.855791 0.441043 0.248847 0.782346 0.465080 -0.161731 0.929949 0.594824 1.321736 1.693332 1.192619 0.260596 1.271517 1.690356 1.109725 0.567421) 5.610410 #(0.000000 0.121938 0.577637 0.964946 0.701543 0.945275 0.057342 0.144831 0.337733 0.549414 1.625058 0.265950 1.238074 1.576246 0.724815 0.984490 0.297228 0.251221 0.699155 0.548588 1.186306 0.951889 0.285802 1.345917 1.014217 1.823546 0.088927 1.726245 0.867511 1.795939 0.286630 1.739958 1.218430) 5.608483 #(0.000000 0.127672 0.575757 0.971725 0.693309 0.950898 0.070948 0.160557 0.341181 0.560186 1.645087 0.281844 1.260852 1.598287 0.730804 1.014936 0.316122 0.275621 0.725241 0.597914 1.221833 0.996203 0.324966 1.372541 1.062261 1.875167 0.130133 1.748519 0.894847 1.849289 0.335743 1.776799 1.261232) ;; pp: 5.744046 (fv 0.000000 0.648617 1.091146 -0.080415 0.482263 1.100917 0.071191 1.062577 0.109918 0.836095 -0.052549 1.287445 0.382948 1.391104 0.926942 0.308725 1.631613 0.947331 0.900375 0.124874 0.064712 1.506574 1.488794 1.444593 1.476988 1.247778 1.089616 1.639634 -0.152998 -0.001330 0.434944 0.915078 0.903432) ;; 32+1 5.661968 (fv 0.000000 -0.352238 1.421554 -0.062497 0.287660 0.210756 0.410931 0.134572 0.285343 1.484578 0.353937 0.356204 0.097780 1.509309 1.823077 1.336946 1.794210 1.915189 0.597192 0.803204 1.197066 0.523451 0.168550 1.601444 0.858978 1.682815 0.027376 0.555153 1.077928 0.275560 1.108578 0.224908 -0.307634) ) ;;; 34 all -------------------------------------------------------------------------------- ; 5.8309518 (vector 34 6.6782836914062 (fv 0 0 1 1 0 0 1 0 1 0 0 1 1 0 0 0 1 0 1 1 0 0 0 1 1 1 1 1 1 0 1 0 0 0) 5.716435 (fv 0.000000 1.537850 0.239691 0.279680 1.093753 0.273847 0.872235 1.496985 1.522928 0.760723 1.655491 0.025814 1.234543 0.204722 1.320964 0.722548 0.795411 1.810303 1.109323 1.456118 1.072015 0.656715 1.724740 1.409441 -0.521616 1.350972 1.541354 1.489386 0.627886 0.677049 0.878489 -0.127150 -0.020441 0.557443) 5.715522 #(0.000000 1.535834 0.312631 0.280224 1.148017 0.182965 0.826725 1.571414 1.581831 0.887796 1.704031 0.067574 1.286355 0.321441 1.363349 0.812149 0.980936 1.891675 1.179822 1.532746 1.177536 0.667908 1.925108 1.578399 -0.430841 1.453028 1.642459 1.613448 0.724642 0.739942 1.051391 0.000286 0.024547 0.665325) 5.715061 #(0.000000 1.557376 0.316186 0.303275 1.175381 0.206598 0.863890 1.615342 1.613470 0.958427 1.750728 0.111536 1.351364 0.386942 1.439281 0.903963 1.075401 -0.020759 1.279610 1.643520 1.269919 0.800947 0.050818 1.687932 -0.298939 1.577236 -0.205754 -0.244682 0.852707 0.888744 1.194917 0.175251 0.202437 0.844132) ;; pp: 5.801677 (fv 0.000000 0.960590 1.230620 -0.161839 0.543814 1.323075 0.313096 0.853533 -0.212153 1.135960 -0.100861 0.915755 0.332189 1.257774 0.850007 0.263168 1.528284 0.501744 0.475602 -0.081405 1.503307 1.166122 1.260528 0.746339 0.481380 0.722221 0.959406 1.108477 0.637618 0.962601 1.236659 1.273002 -0.011533 0.165609) ) ;;; 35 all -------------------------------------------------------------------------------- ; 5.9160 (vector 35 6.7637429237366 (fv 0 1 1 0 1 1 1 1 1 0 0 1 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 1 0 1 0 1 0 0) 5.764294 (fv 0.000000 0.100183 1.398707 0.822554 1.459800 0.154045 1.619372 1.535907 1.542373 0.876004 1.322076 1.293113 1.412723 0.146555 1.058946 0.645359 1.390817 1.072269 0.132103 0.365169 1.845456 1.487696 0.791518 1.753949 0.991873 1.205376 0.200418 -0.166259 0.161894 -0.021712 0.362318 0.686081 1.632970 0.565468 0.901578) 5.761550 #(0.000000 0.109331 1.415904 0.863973 1.504657 0.200254 1.669142 1.598436 1.595369 0.964840 1.410141 1.378302 1.505772 0.261951 1.178950 0.757734 1.524984 1.223665 0.264922 0.531725 0.000853 1.660270 0.971853 -0.071328 1.201271 1.414050 0.409445 0.053601 0.377052 0.191601 0.609357 0.945758 -0.105595 0.829816 1.179558) ;; pp: 5.895826 (fv 0.000000 0.643741 1.250469 1.867865 0.530176 1.122535 0.024737 1.205120 0.194580 0.988315 1.702722 0.964190 0.348453 1.456006 0.520276 -0.302930 1.556990 0.638548 -0.211365 1.748454 1.424618 0.940371 0.466444 0.212559 0.146415 0.251126 0.228984 -0.138555 0.352126 0.459061 0.664909 1.353503 1.665947 1.723726 0.002732) ) ;;; 36 all -------------------------------------------------------------------------------- ; 6 (vector 36 6.8008880615234 (fv 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 1 0 1 0 1 0 1 1 0 0 1 1 1 0 0 0 0 0 0 1) 5.926043 (fv 0.000000 1.020111 0.677817 0.140140 0.932921 0.775557 0.190635 1.853238 0.762697 0.237889 0.277245 0.161572 1.553054 0.008070 0.283378 1.674361 -0.347149 0.590912 0.944213 0.823255 0.043034 -0.091562 0.229555 1.352871 0.981843 0.171776 0.581947 0.691871 1.000348 0.829120 1.162722 1.690975 0.634924 1.730234 0.452876 1.429867) ;; pp: 5.876240 (fv 0.000000 0.880722 1.509714 0.204909 0.817303 1.618536 0.560409 1.279749 0.308262 -0.524358 0.395653 -0.826907 0.386964 -0.034537 1.535549 1.090154 0.375322 1.512598 1.132860 1.558960 0.892393 0.587406 0.099621 0.325394 -0.086852 -0.097620 -0.036583 0.411674 0.423371 -0.013442 0.469946 0.536299 1.271922 -0.393606 -0.170370 0.277903) 5.872670 #(0.000000 1.008642 1.468259 0.136066 0.832884 1.675080 0.561995 1.215779 0.176163 -0.645512 0.301135 -0.915574 0.346533 -0.147416 1.414097 1.167654 0.437921 1.345264 1.026772 1.438289 0.848806 0.422687 -0.153016 0.254467 -0.256778 -0.257882 -0.180820 0.369974 0.206740 -0.196159 0.361067 0.357334 1.155902 -0.541647 -0.334470 0.076521) 5.871695 #(0.000000 0.976078 1.428851 0.077798 0.772784 1.602082 0.472100 1.111861 0.058266 -0.754466 0.191131 -1.049850 0.189192 -0.311703 1.251680 0.977617 0.232753 1.137715 0.806190 1.201023 0.616244 0.157943 -0.415443 -0.020130 -0.548605 -0.551223 -0.509170 0.040073 -0.121612 -0.560043 -0.007571 -0.025396 0.766768 -0.951503 -0.743309 -0.341165) ;; 35+1 5.968866 #(0.000000 0.133611 1.230434 0.841852 1.312856 0.529755 1.370310 1.332590 1.580324 0.930341 1.428865 1.755052 1.561249 -0.230712 1.582178 0.486609 1.188339 0.984457 0.043840 -0.015979 -0.155552 1.235391 0.874947 1.643065 1.184316 0.952918 0.543242 -0.381983 0.458292 0.068269 0.575524 0.723748 -0.044728 0.683083 1.573491 0.035965) ) ;;; 37 all -------------------------------------------------------------------------------- ; 6.0827 (vector 37 7.0251078605652 (fv 0 0 0 0 1 0 0 1 0 0 1 1 1 1 1 0 0 1 0 0 1 1 1 0 0 0 1 0 0 0 0 1 0 1 0 0 0) 5.927989 (fv 0.000000 1.362671 1.825924 0.295316 1.739841 1.835463 1.048945 1.351967 0.301179 0.388225 1.780488 1.534131 0.435239 0.318363 -0.101295 0.220840 0.998360 1.646237 1.362259 0.730890 0.388056 1.327874 0.110340 1.924981 0.324484 0.429209 1.542714 0.665030 0.018148 0.321441 1.812097 0.446891 1.633693 1.056009 1.344989 1.426723 1.818561) 5.918646 #(0.000000 1.276868 1.775826 0.292236 1.788221 1.829337 1.043839 1.351449 0.259082 0.375705 1.700935 1.487286 0.337951 0.306327 -0.126317 0.091444 0.949870 1.546870 1.374856 0.654967 0.351723 1.285561 0.074903 1.824326 0.227704 0.400930 1.466430 0.609151 0.009920 0.222861 1.672440 0.383746 1.542055 1.018281 1.254945 1.323042 1.739217) 5.918139 #(0.000000 1.268085 1.769551 0.285066 1.784410 1.812873 1.034440 1.342674 0.256292 0.366678 1.679577 1.477236 0.317949 0.294007 -0.148484 0.067735 0.925643 1.526359 1.349946 0.624511 0.326721 1.258438 0.049695 1.798322 0.189031 0.360477 1.435009 0.581192 -0.024865 0.191624 1.638560 0.341145 1.503234 0.980493 1.208657 1.269237 1.688696) ;; pp: 5.974361 (fv 0.000000 0.722538 1.156373 1.818176 0.424359 1.001884 -0.224545 0.967675 0.089627 0.943734 -0.013572 0.947114 1.914887 1.102823 0.609766 -0.045075 0.989242 0.549752 1.615428 1.344389 0.949028 0.684491 0.483044 1.586745 1.704247 1.024089 1.360720 1.162825 1.209506 1.208578 0.870877 1.201701 1.782696 0.290706 0.253842 0.466340 0.855161) ) ;;; 38 all -------------------------------------------------------------------------------- ; 6.1644 (vector 38 7.0688242912292 (fv 0 0 1 1 0 1 0 1 0 1 1 1 0 1 0 1 1 0 1 0 0 0 0 1 0 0 0 0 0 1 1 0 1 1 0 0 0 0) 6.106333 (fv 0.000000 0.434523 1.232452 1.590516 0.836713 0.138216 -0.095509 1.537371 0.469612 0.772082 0.748819 1.723571 1.820323 0.854103 0.903800 0.048646 1.316356 0.369282 0.213334 0.798970 0.966914 1.376827 0.274641 1.618764 1.873131 -0.092091 -0.470518 1.150403 0.773945 1.198395 0.586433 1.306012 0.434228 0.963298 1.320012 1.145313 0.975992 1.528312) ;; pp: 6.069129 (fv 0.000000 0.353204 1.147865 -0.165608 0.617213 1.415461 0.231168 1.083939 0.117365 0.131316 1.707213 1.274701 0.816253 0.960543 -0.063212 0.270965 1.418066 0.902830 1.619238 0.591718 0.977208 0.940720 1.787513 0.746703 0.165197 1.177699 0.830675 1.652814 1.371740 1.118022 1.133381 1.232097 1.370669 1.218425 0.194971 -0.026100 0.615354 0.750336) ;; 37+1 6.055823 (fv 0.000000 1.140317 1.804958 0.269386 1.581973 1.647143 0.908514 1.357676 0.255360 0.413319 1.759464 1.403831 0.462290 0.275768 -0.260643 0.081477 0.945988 1.674168 1.558839 0.619719 0.448569 1.181188 0.261467 0.173066 0.317765 0.523175 1.483135 0.623965 0.065573 0.279749 1.647027 0.558187 1.546480 1.177439 1.567967 1.574734 1.849511 0.049835) ) ;;; 39 all -------------------------------------------------------------------------------- ; 6.2449 (vector 39 7.1506487936623 (fv 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 1 0 1 0 0 1 1 0 1 0 1 1 0 0 0 1 0 1 1 0 0 0 1) 6.123916 (fv 0.000000 0.040215 0.172894 1.637830 1.177239 0.763654 -0.119272 0.532576 0.565933 -0.105342 -0.131500 0.223610 0.603849 1.034619 1.719874 1.942807 1.262885 -0.012239 1.521972 1.205939 0.909582 1.593149 1.660841 1.495691 0.901808 0.173365 0.594080 1.535985 0.099680 1.416781 0.772460 -0.143795 1.283054 1.611294 1.560252 0.291114 1.497861 0.152708 0.428638) 6.123617 #(0.000000 0.022194 0.139382 1.578109 1.109939 0.686598 -0.209261 0.437705 0.449420 -0.232701 -0.273875 0.070822 0.433690 0.853619 1.527629 -0.258054 1.050086 -0.235174 1.275677 0.950078 0.647199 1.303772 1.358361 1.189190 0.591278 -0.165906 0.244128 1.187114 -0.273717 1.031390 0.371517 -0.540240 0.858520 1.177992 1.114387 -0.172733 1.027118 -0.340480 -0.076231) ;; pp: 6.206556 (fv 0.000000 0.714125 0.999676 1.714571 0.529099 1.103279 1.739177 0.796762 1.681925 0.899057 1.703669 0.970830 1.925662 0.861561 -0.048288 1.636413 0.684994 0.118298 1.376444 0.590000 0.292657 1.963808 1.418598 1.344996 0.647105 0.610362 0.012866 0.209613 -0.013687 0.186819 0.011104 -0.022072 0.158390 0.584179 1.099029 1.037543 1.650004 1.749468 0.443068) ) ;;; 40 all -------------------------------------------------------------------------------- ; 6.3245 (vector 40 7.3913831710815 (fv 0 1 0 1 0 1 0 0 0 1 1 0 0 1 0 0 0 0 1 0 1 1 0 0 1 0 0 1 1 1 1 0 0 0 1 0 0 0 0 0) 6.288342 (fv 0.000000 1.454424 1.336242 0.229719 0.982419 1.371484 1.659070 1.721074 -0.039860 0.456961 0.523564 1.259764 0.318922 0.087125 -0.000634 1.738216 -0.345360 -0.093074 0.023146 0.160891 -0.147874 1.232278 0.789559 0.888228 0.482450 1.447335 0.166012 1.058063 1.516605 1.834071 1.250289 0.562291 1.417730 1.678824 0.619402 -0.109426 1.547164 0.339656 1.224949 0.726676) ;; pp.scm using (+ pi (/ pi 40)) and (- (/ pi 2)) 6.236401 (fv 0.000000 0.772219 1.201231 0.091963 0.183059 1.041989 1.811758 0.387321 1.330915 0.336134 1.429758 0.457811 -0.040075 1.279315 -0.162113 0.993833 0.310259 1.390530 1.133639 0.515117 -0.283405 1.239507 1.056859 0.563309 0.888313 0.077823 -0.241421 1.625166 1.389376 1.528163 1.539643 1.801710 1.314626 1.482031 0.189224 0.088532 0.546429 0.832570 1.329921 1.394636) ;; 39+1 6.223875 #(0.000000 0.017488 0.395122 1.676489 1.264189 0.771372 -0.011418 0.532062 0.348765 -0.291944 -0.034478 0.399358 0.691637 1.117218 1.716574 0.114046 1.298557 0.074462 1.617194 1.080550 1.108787 1.427161 1.645893 1.492515 0.908836 0.183198 0.586816 1.733289 0.192174 1.419647 0.686684 -0.174875 1.274049 1.555620 1.606137 0.123322 1.462205 0.157438 0.491542 -0.249961) ) ;;; 41 all -------------------------------------------------------------------------------- ; 6.4031 (vector 41 7.4106826782227 (fv 0 0 1 1 0 0 0 1 0 0 0 1 0 1 0 1 0 0 1 1 0 1 1 1 1 1 1 0 1 0 1 1 0 1 0 0 0 1 1 1 1) 6.328763 (fv 0.000000 1.142395 1.764533 -0.297234 1.214342 1.074168 0.499096 0.455971 1.425043 1.900660 0.405160 0.299024 -1.901144 1.886599 1.644748 1.176229 0.661037 1.678309 0.464540 0.540147 1.345672 0.396385 -0.079815 0.750463 0.469580 0.512532 0.818295 0.900948 1.176821 -0.024695 0.941067 1.661160 0.722192 0.141569 0.127463 0.210921 0.877068 0.077777 1.493046 0.191845 0.414613) 6.279752 #(0.000000 1.039440 1.670537 -0.269122 1.058663 1.073053 0.461356 0.338125 1.379608 1.686032 0.168477 0.220127 -0.046702 -0.025677 1.700045 1.127479 0.601951 1.764849 0.395397 0.778987 1.079511 0.525179 -0.400733 0.741798 0.221415 0.104621 0.721445 0.669340 0.961099 -0.201573 0.643173 1.703776 0.553797 -0.208803 -0.109492 0.033494 0.694117 0.116494 1.191608 0.020301 0.131256) 6.278483 #(0.000000 1.038469 1.689102 -0.246889 1.070891 1.081477 0.456681 0.352855 1.380232 1.717208 0.185595 0.242413 -0.037760 -0.028341 1.684169 1.135689 0.606635 1.756147 0.422850 0.765104 1.090059 0.552553 -0.368817 0.733599 0.247441 0.131196 0.725118 0.703272 0.972734 -0.170957 0.673987 1.704514 0.578697 -0.183550 -0.096757 0.046184 0.705164 0.130867 1.217191 0.056397 0.199710) ;; 40+1 6.357979 #(0.000000 -0.014992 0.249240 1.543670 1.126815 0.662312 -0.052816 0.619055 0.369857 -0.115477 -0.003391 0.180442 0.565001 0.924831 1.661456 -0.128503 1.291579 -0.077357 1.542827 0.991944 0.960719 1.395109 1.631218 1.333505 0.925448 -0.150607 0.489479 1.798022 -0.099011 1.252747 0.567676 -0.055660 1.075602 1.407498 1.261622 0.087709 1.323935 -0.086458 0.259809 -0.431448 0.139996) ) ;;; 42 all -------------------------------------------------------------------------------- ; 6.4807 (vector 42 7.6252284049988 (fv 0 0 1 1 0 0 1 1 1 0 0 0 1 0 1 1 0 0 1 0 1 1 0 1 0 1 0 0 1 0 1 1 1 0 0 0 0 0 0 0 0 0) 6.458009 (fv 0.000000 1.779914 1.358689 1.879744 1.431714 1.455314 0.050417 0.106324 1.650278 0.287736 1.685176 1.015814 0.661574 0.193645 0.754970 0.912901 1.865274 -0.192264 1.123351 1.730828 0.304030 1.844656 1.379904 1.178786 0.508869 0.433728 0.920606 1.193377 1.562403 0.705424 1.521220 0.671316 1.715032 0.818246 0.696173 0.646766 1.054986 -0.067193 0.041834 0.484025 0.025667 0.817193) ;; pp: 6.432404 (fv 0.000000 0.970539 1.075055 0.363395 0.562687 1.503003 0.305818 1.159109 -0.331893 0.844703 -0.625323 0.633095 -0.150641 1.248856 0.138597 1.484859 0.287309 -0.516557 0.004989 0.635673 0.412760 0.072104 -0.034630 0.781885 1.052252 0.670637 0.477407 0.370916 -0.497791 0.214269 0.268953 -0.018432 0.090095 0.191222 0.329896 1.234637 1.181873 1.460275 -0.201010 0.565027 0.336488 1.227322) ;; 41+1 6.374134 #(0.000000 1.160594 -0.035009 -0.337995 1.287896 1.152937 0.370349 0.599654 1.434075 0.331903 0.337639 0.227520 0.031784 0.056373 1.754183 1.233325 0.766762 -0.105337 0.381752 0.608417 1.177813 0.853286 -0.000702 0.980553 0.580193 0.503346 0.721433 1.102554 1.338903 -0.104016 1.021288 -0.193635 0.638903 0.186655 0.282480 0.311801 1.029234 0.514030 1.400087 0.298091 0.559980 -0.413468) ) ;;; 43 all -------------------------------------------------------------------------------- ; 6.5574 (vector 43 7.6619415283203 (fv 0 1 0 1 0 1 1 1 1 0 1 0 1 1 1 0 0 0 0 0 1 1 0 0 0 1 0 1 0 0 1 1 0 1 0 0 0 0 0 0 0 1 1) 6.474636 (fv 0.000000 1.150199 1.694193 1.156056 0.712558 0.642330 1.062359 0.333465 0.208319 1.376434 0.672147 0.421707 0.175691 0.110131 0.012554 0.457050 1.790874 1.449901 0.302494 0.007271 0.824529 0.122259 0.582806 0.097251 0.623774 0.359297 1.299289 0.938333 1.768060 0.180654 1.104716 1.340371 1.395970 0.480619 1.800871 0.228016 0.933560 0.262964 0.673103 1.298731 1.471774 -0.223423 0.770589) ;; 42+1 6.484540 #(0.000000 0.799805 0.296138 -0.181661 1.243255 0.972255 0.211011 0.157981 1.334009 0.607658 0.666111 0.172358 0.489130 0.433262 0.074913 -0.108461 0.327642 -0.177912 0.391650 0.361860 1.366441 1.197611 0.114750 0.879694 0.781347 0.470866 0.964657 1.349973 1.443504 0.050313 1.040919 -0.331503 1.092413 0.101381 0.547246 0.325671 1.577550 0.316146 1.327141 0.900920 0.939639 -0.347989 0.327657) ) ;;; 44 all -------------------------------------------------------------------------------- ; 6.6332 (vector 44 7.9767818450928 (fv 0 1 0 0 1 1 0 1 1 0 1 1 0 0 0 1 1 1 1 1 0 1 1 0 0 0 1 0 0 0 0 0 0 0 1 1 1 0 0 1 0 1 0 1) 6.544063 (fv 0.000000 0.521564 0.221232 0.526957 -0.268317 1.919404 -0.035203 -0.157289 0.069290 1.705251 1.788014 0.459816 0.274398 0.505529 1.163758 0.357930 -1.720040 0.469129 0.146265 1.215606 1.405712 0.742844 1.668145 1.402279 0.067840 0.255308 0.567789 0.756058 -0.027555 1.587315 0.915687 1.314433 0.227656 0.688969 1.566702 0.434208 -0.041884 1.283408 0.878206 0.471503 1.018383 0.062893 1.376612 0.157588) ;; 43+1 6.617718 #(0.000000 0.929303 0.214195 -0.305607 1.575411 0.960005 0.543631 0.816651 1.159803 0.112080 0.077010 0.590695 -0.040249 -0.288217 1.448848 1.235788 0.754544 -0.407692 0.476307 0.769330 1.241658 1.259441 0.282090 0.960527 0.572071 0.268642 0.862727 -0.063301 1.181813 0.657762 0.694907 0.056205 0.912295 0.475141 0.694152 0.927496 1.094556 1.105653 1.775202 -0.143116 1.075592 -0.229850 0.469130 -0.375239) ) ;;; 45 all -------------------------------------------------------------------------------- ; 6.7082 (vector 45 8.1777801513672 (fv 0 1 0 1 1 0 0 1 1 0 1 0 1 1 1 1 0 1 1 0 1 1 0 1 1 1 1 0 1 1 1 0 0 0 0 0 1 0 1 0 0 0 1 1 1) 6.629206 (fv 0.000000 0.961180 -0.043617 -0.239190 1.278111 0.166389 0.542833 0.768578 1.444629 -0.095831 1.211952 -0.026602 1.739185 0.951577 1.809231 0.253449 0.320575 0.356270 1.309005 0.639731 1.394153 0.026971 -0.051944 0.744827 0.030297 -0.420287 0.144422 1.021322 1.302658 0.297709 -0.048481 -0.152658 1.144902 1.677136 1.170155 1.132592 1.153458 -0.076024 1.369092 1.009916 0.503324 -0.247395 0.103592 1.569752 0.081999) 6.624045 #(0.000000 1.027137 -0.006949 -0.241567 1.292392 0.249243 0.688163 0.937733 1.490593 0.055551 1.221039 0.178575 1.739730 1.011821 -0.089036 0.442654 0.375914 0.532475 1.410268 0.844396 1.467724 0.085993 0.105745 0.803510 0.299479 -0.089745 0.369095 1.074672 1.565553 0.558935 0.123221 0.059937 1.431538 -0.190214 1.489626 1.543857 1.489693 0.130690 1.680298 1.260465 0.724859 0.164445 0.433945 -0.212764 0.411030) 6.612690 #(0.000000 0.809914 0.760766 -0.199070 0.584393 1.010129 -0.444768 -0.272636 0.950655 0.770420 -0.288810 0.049214 -1.454088 0.191424 -1.076560 -0.306479 -0.326951 -1.245176 0.685415 0.506132 0.101749 0.628099 0.641810 0.560186 1.064779 -0.804404 -0.612448 0.708592 1.898500 0.642577 0.682702 -0.598959 -1.216733 -1.420060 0.084743 0.265460 1.286043 0.185429 1.160604 0.022683 -0.437513 0.122344 -0.218434 -0.653674 -1.002688) ;; 44+1 6.714595 #(0.000000 0.564364 0.130777 0.656228 -0.319916 1.775107 -0.124290 -0.070841 0.124442 1.500414 1.820670 0.445101 0.236733 0.416487 1.155210 0.503587 -1.734245 0.426011 0.254073 1.069259 1.324509 0.611279 1.824321 1.376553 -0.114105 0.172880 0.631450 0.863080 -0.077524 1.662079 0.769087 1.304043 0.122140 0.610255 1.653927 0.326711 -0.168576 1.291324 0.851943 0.606010 1.047149 0.079373 1.047078 0.035371 -0.264517) ) ;;; 46 all -------------------------------------------------------------------------------- ; 6.7823 (vector 46 8.22203540802 (fv 0 1 0 1 0 0 0 0 1 0 0 1 1 0 1 1 1 0 0 0 1 1 1 0 1 1 1 0 0 0 1 0 1 1 0 0 1 0 0 1 0 1 0 0 0 0) 6.691037 (fv 0.000000 1.445996 1.082935 1.926602 0.599270 0.110590 0.061353 0.197460 1.126524 0.801213 0.136799 1.544533 0.424316 0.988423 1.042912 0.904549 0.394264 1.877367 1.781398 0.106378 0.814176 1.462479 1.299353 0.505357 0.691608 0.079788 0.741755 1.296349 0.923407 1.954315 1.519832 1.193777 1.868646 1.501978 -0.016089 0.928107 1.377054 1.114171 1.348483 1.466927 0.885968 1.244812 -0.112245 0.649026 0.159882 0.999017) ;; 45+1 6.737496 #(0.000000 0.891082 0.437629 -0.631499 1.355029 0.088312 0.525030 0.893686 1.472031 -0.146846 0.973741 0.114371 1.794819 1.120888 1.803610 0.267646 0.313821 0.176598 1.483030 0.561548 1.444435 0.111178 -0.116383 0.572485 0.384889 -0.539242 -0.000026 1.504176 1.488659 0.718239 -0.059775 0.251172 1.363526 1.830593 1.709614 1.067908 1.076519 0.522533 1.398513 0.992929 0.954368 -0.123192 0.213695 1.865385 0.089802 -0.018905) ) ;;; 47 all -------------------------------------------------------------------------------- ; 6.8556 (vector 47 8.3221893310547 (fv 0 0 1 0 1 0 0 0 0 1 0 0 1 1 1 1 1 0 1 0 1 0 1 1 1 0 1 1 1 1 0 1 1 0 0 1 1 0 0 1 0 1 1 0 1 0 0) 6.827640 (fv 0.000000 1.713417 0.880595 0.228916 0.656232 0.000986 0.228917 -0.027955 1.208960 0.359921 0.457263 0.229897 0.942770 1.345553 -0.054940 0.652154 0.967593 1.474188 0.749564 1.214391 0.623653 1.483712 1.914097 -0.195445 1.486123 0.775521 1.114155 1.267810 1.798008 0.660315 0.102413 1.302210 1.004781 1.037205 1.145399 0.299807 1.478644 1.078433 0.364686 1.769537 0.263449 0.339932 0.328599 1.167886 1.782492 1.089675 1.333666) ;; pp.scm 6.756605 (fv 0.000000 0.765562 1.030062 1.788209 0.493707 1.020553 1.799942 0.685170 1.481088 0.566613 1.302518 0.066670 1.157386 0.282906 1.328526 0.161298 1.388649 0.879050 1.843229 1.039366 0.409576 -0.055025 1.222366 0.535280 0.169247 1.679128 1.342099 0.894436 0.643082 0.345708 0.301808 -0.401334 0.022950 1.550170 1.565812 1.633017 1.764984 1.880338 1.607034 1.569498 0.111731 0.416082 0.781558 0.894597 1.438223 1.659212 0.166997) ) ;;; 48 all -------------------------------------------------------------------------------- ; 6.9282 (vector 48 8.4671268463135 (fv 0 0 0 0 1 0 1 1 1 1 1 0 0 1 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 1 0 1 0 0 1 0 1 0 0 1 0 0 1 1 0 0 1 1) 6.861797 (fv 0.000000 0.598880 1.244788 1.029903 1.049082 0.596958 1.659653 1.333585 0.658254 1.786003 1.335584 0.009329 0.382880 1.914281 0.167535 0.198984 1.572176 1.516863 0.640701 0.516067 0.942009 -0.405338 1.601326 0.836539 0.796978 0.739838 0.171913 0.969497 0.363583 0.469203 1.258504 0.656687 1.162915 0.889585 1.702682 0.725369 0.456133 0.349105 0.208023 0.802519 1.129136 1.479603 0.312580 1.579555 0.353334 0.757965 1.599847 0.626811) ;; 47+1 6.892392 #(0.000000 0.688844 1.275690 -0.029196 0.666687 1.219038 1.796126 0.686703 1.387045 0.299015 1.486000 0.217586 1.168099 0.122356 1.320410 0.506266 1.401144 0.705689 0.099274 1.001293 0.250881 -0.338513 1.011906 0.589633 -0.026149 1.658621 0.999181 0.670111 0.425438 0.181969 0.283085 -0.428382 -0.237009 1.436619 1.467751 1.345785 1.658556 -0.130875 1.611827 1.446511 -0.136029 0.162128 0.614874 0.798756 1.306679 1.726452 0.077838 -0.060906) ;; 50-2 6.804078 #(0.000000 0.874821 0.948620 -0.030050 0.326575 1.258972 -0.088513 0.113859 0.340515 -0.014269 1.691477 0.675893 0.119114 -0.035346 1.426532 1.152480 0.791174 0.976063 0.731143 1.014136 1.203667 0.311022 -0.203371 1.591275 1.628122 -0.181766 0.450459 0.902610 0.339563 -0.440014 -0.112189 0.959920 1.425584 0.089561 1.717366 0.518887 0.024084 1.133195 1.349821 0.385099 1.797184 0.189610 0.147986 1.156584 -0.006309 1.527354 0.195815 0.002013) ) ;;; 49 all -------------------------------------------------------------------------------- ; 7 (vector 49 8.5157623291016 (fv 0 1 1 0 0 0 0 0 1 0 0 1 1 0 1 0 1 1 1 1 0 0 1 1 1 0 1 1 0 0 0 0 1 0 0 1 0 1 1 1 0 0 0 0 1 0 1 0 0) 6.911687 (fv 0.000000 1.423917 -0.117078 -0.215912 1.065526 1.018507 0.645263 1.632151 0.540556 0.415851 1.870183 1.161732 0.983376 1.723916 0.372700 0.063452 0.534166 1.512588 1.454603 0.719318 0.962295 1.537720 1.562020 1.433858 0.930756 1.181983 1.504188 -0.167777 1.662278 0.680834 0.246207 0.675469 0.268474 1.089455 0.369548 -0.146942 -0.055836 1.091821 1.976652 0.486415 1.202030 0.175707 0.854435 0.506884 1.646470 0.139127 0.235704 1.857608 0.297006) ;; 50-1 6.910295 #(0.000000 1.059948 1.102312 -0.154766 0.271011 1.001259 -0.322228 0.611181 1.084580 0.193049 1.708690 0.549448 0.114307 -0.112275 1.323751 1.621007 1.041438 1.446405 0.346446 0.779211 0.803707 0.229069 1.620947 -0.129471 -0.141064 0.581982 -0.069220 1.242954 -0.424957 -0.059702 -0.076232 1.090459 1.897927 -0.587283 0.232044 0.877329 -0.465364 1.521832 1.430023 0.510607 0.119336 0.032708 0.304452 0.848312 0.725150 0.798920 0.612486 0.214940 1.234846) 6.907185 #(0.000000 1.059469 1.114179 -0.150791 0.258478 0.994889 -0.336259 0.599168 1.084896 0.192104 1.698208 0.543042 0.115884 -0.128271 1.314296 1.621485 1.044197 1.442142 0.334969 0.776113 0.823403 0.227295 1.618113 -0.132905 -0.144839 0.578330 -0.074014 1.260097 -0.447140 -0.067108 -0.086664 1.078815 1.896924 -0.604152 0.214555 0.862267 -0.492164 1.511993 1.411560 0.503434 0.119933 0.010833 0.282277 0.838215 0.717315 0.788849 0.600355 0.201253 1.210362) ) ;;; 50 all -------------------------------------------------------------------------------- ; 7.071 (vector 50 8.7809114456177 (fv 0 0 1 0 1 0 1 0 0 0 1 1 1 1 0 0 0 0 0 0 1 0 0 1 1 0 0 0 0 1 0 1 0 0 1 1 1 1 0 1 1 1 0 1 1 0 1 0 0 1) 7.001572 (fv 0.000000 1.510483 0.569660 1.177547 -0.063746 1.651491 0.398933 1.945813 1.189455 0.886784 0.877834 1.209513 -0.281791 0.817195 0.562593 1.509576 -0.448618 -0.075249 1.004074 1.022851 1.197099 0.475529 0.725043 0.148549 0.625214 0.676229 0.641014 0.276388 1.297552 1.512294 0.880442 -0.093329 0.470630 1.205879 -0.595773 0.927383 1.198964 0.435022 1.291534 0.884451 -0.190056 1.483748 1.136079 1.665203 0.167401 0.524695 0.182147 -0.336866 0.803181 1.503900) ;; 49+1 7.064944 #(0.000000 1.558009 -0.108565 -0.226913 0.920197 1.180894 0.537671 1.554384 0.613756 0.458358 0.091191 1.387557 0.869986 1.858139 0.547904 0.135691 0.583740 1.710905 1.421339 0.744505 1.032127 1.414994 1.701011 1.686329 0.940524 1.064348 1.388446 -0.279583 1.723434 0.898036 0.320378 0.547937 0.335420 1.264319 0.407052 0.022184 -0.017105 0.905945 1.912730 0.523724 1.239641 0.158867 0.840449 0.693502 1.785642 0.002311 0.342012 1.897108 0.429747 0.359280) ;; 51-1? 6.967233 #(0.000000 0.970268 1.092398 1.888744 0.176055 1.242915 -0.182630 0.498873 0.714528 0.065776 1.516006 0.488189 0.172228 1.824642 1.137081 1.246514 0.918186 1.083274 0.311853 0.739323 0.800717 0.461460 1.390793 1.467948 1.702761 -0.157496 0.172343 0.955766 -0.200187 -0.202194 -0.109455 0.590305 1.500923 -0.065490 1.470764 0.488682 -0.351464 1.288146 1.359535 0.275868 1.584539 0.037303 -0.097518 0.950689 0.185166 0.880435 0.283304 -0.239816 1.354407 1.605268) 6.966444 #(0.000000 0.969561 1.094228 1.889603 0.178237 1.243506 -0.179029 0.498784 0.715615 0.064553 1.519591 0.490911 0.171201 1.825529 1.138600 1.243991 0.920476 1.084610 0.315165 0.739666 0.806931 0.459500 1.392905 1.470398 1.703973 -0.154232 0.175316 0.961121 -0.195877 -0.203581 -0.104914 0.596805 1.500152 -0.064411 1.474852 0.495330 -0.345550 1.291380 1.361659 0.279253 1.587805 0.037979 -0.094175 0.955070 0.189359 0.883451 0.286407 -0.239876 1.359571 1.605865) ) ;;; 51 all -------------------------------------------------------------------------------- ; 7.141 (vector 51 8.8213935921978 (fv 0 0 1 0 1 1 1 1 1 0 1 1 1 0 1 0 1 1 1 1 1 1 1 0 0 1 0 1 0 0 0 0 0 1 1 1 1 0 1 1 1 0 0 1 0 1 1 1 0 0 1) 7.062061 (fv 0.000000 1.277482 1.272374 1.604932 -0.114681 1.091849 -0.113655 0.581995 0.517152 0.112646 1.392203 0.473053 0.525951 1.781540 1.014930 1.311666 0.597941 1.173291 0.649975 0.688396 0.657382 0.570575 1.699334 1.669408 1.662666 -0.233111 0.196711 0.718758 -0.174442 0.105462 -0.039308 0.924279 1.329687 1.401301 1.538357 0.347724 -0.110320 1.449195 1.223831 0.349599 1.470761 0.191238 1.885833 0.819453 0.145490 0.967802 0.015777 -0.014902 1.276127 1.513254 0.227467) 7.061972 #(0.000000 1.276628 1.273765 1.607581 -0.114970 1.091264 -0.113040 0.580864 0.516735 0.113082 1.390932 0.474109 0.525638 1.784132 1.017927 1.316859 0.597754 1.174733 0.647452 0.691328 0.661372 0.567341 1.701460 1.671297 1.665426 -0.232474 0.194748 0.720612 -0.170875 0.103745 -0.037365 0.924964 1.329745 1.406880 1.540907 0.349954 -0.109891 1.449476 1.227519 0.347601 1.477324 0.191963 1.887908 0.821661 0.147626 0.967297 0.015607 -0.013051 1.280470 1.516669 0.226095) ) ;;; 52 all -------------------------------------------------------------------------------- ; 7.211 (vector 52 8.9920463562012 (fv 0 1 1 0 1 0 0 0 0 0 1 0 0 0 1 0 1 1 1 0 0 1 1 0 1 1 0 1 0 1 0 0 0 0 1 0 0 0 1 1 0 0 0 1 1 1 0 0 0 0 0 0) 7.134954 (fv 0.000000 0.621560 1.464578 1.482376 0.135707 1.345519 0.584967 0.540885 1.784345 0.393329 1.745283 0.530433 1.414971 1.247472 1.329889 0.999552 0.933504 1.580199 0.519254 0.315472 0.473007 1.123477 -0.056053 0.241576 0.391709 1.244898 1.883529 1.120931 1.698334 -0.149261 0.218191 1.134898 0.533381 1.222211 0.249553 -0.114715 1.262472 0.846800 0.877356 0.688478 0.673983 1.103698 1.385836 1.036560 1.331275 0.414915 1.604362 0.874160 0.543444 1.406115 1.239524 0.816202) 7.131761 #(0.000000 0.537475 1.434186 1.485257 0.169881 1.416948 0.579251 0.545053 1.903917 0.399401 1.765906 0.542670 1.396121 1.264296 1.322696 0.985374 0.995894 1.591655 0.505552 0.250919 0.433406 1.124308 -0.040021 0.168815 0.391865 1.242269 1.875020 1.121196 1.704677 -0.131089 0.170120 1.111726 0.615076 1.228577 0.309881 -0.149015 1.305694 0.861912 0.914108 0.664306 0.720147 1.136263 1.351328 1.011200 1.402304 0.485461 1.536405 0.819898 0.530949 1.451849 1.212610 0.799774) ;; 51+1 7.189639 #(0.000000 1.613047 1.226926 1.461226 -0.208975 1.160308 0.015278 0.874276 0.441796 0.145203 1.228806 0.566007 0.867165 1.631256 1.099751 1.575849 0.905365 1.096254 1.105187 0.482059 0.890391 0.608271 1.917275 1.824879 1.614793 0.165400 0.031023 0.768526 0.036022 0.101130 0.266024 1.042278 1.643239 1.401788 1.800366 0.504130 0.383632 -0.022284 1.238194 0.732080 1.858191 0.525715 0.107150 0.590054 0.832408 1.192418 0.215401 0.405342 1.484800 1.897855 1.002469 0.467126) ) ;;; 53 all -------------------------------------------------------------------------------- ; 7.280 (vector 53 9.0914754867554 (fv 0 1 0 1 0 1 1 0 1 0 0 1 0 0 1 1 0 1 1 0 1 0 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 0 1 1 1 0 1 0 1 1 1 0 0 1 1 0 0) 7.198047 (fv 0.000000 0.609644 0.849387 1.600527 1.158365 1.715833 0.524245 -0.059778 0.291176 0.319451 0.985683 1.372433 1.089427 1.749317 1.594481 0.166060 0.927925 -0.362027 0.850015 1.635397 0.732972 1.007069 0.880865 0.290674 0.176669 0.886718 1.772633 0.908528 -0.020813 0.082874 0.257671 1.590012 0.330359 1.893554 1.401328 1.102801 0.720925 0.360594 1.357080 1.833049 0.574052 1.403405 1.851942 1.638866 1.670052 -0.125543 1.654904 0.840665 0.189500 1.798641 0.330271 0.101100 1.702877) ;; 54-1 7.246308 #(0.000000 1.532310 -0.094995 1.372753 -0.225031 1.502079 0.056954 0.367578 1.317903 -0.308906 0.288435 -0.135988 0.144140 1.007501 -0.258190 0.832754 1.691061 0.210863 0.421782 1.089380 1.093649 0.443939 0.473594 0.319946 1.564712 -0.127810 1.590182 1.208800 1.280863 -0.068396 1.806097 1.025552 0.141011 1.391092 0.873396 0.397519 1.327658 0.757527 1.353264 0.340770 0.460425 0.732779 1.339617 0.707719 1.128519 1.697349 1.656716 0.826604 0.294361 0.406394 0.110907 1.094470 0.337662) ) ;;; 54 all -------------------------------------------------------------------------------- ; 7.348 (vector 54 9.1825122833252 (fv 0 1 0 1 0 1 1 0 1 1 0 0 1 0 1 0 0 0 1 1 1 0 0 0 1 1 1 1 0 0 1 0 1 1 1 1 1 1 0 1 1 1 0 1 1 0 0 0 0 1 0 0 1 1) 7.253898 (fv 0.000000 1.663275 -0.127344 1.382101 -0.144643 1.243444 0.071415 0.455351 1.200018 -0.228088 0.114774 0.009236 0.130605 1.041538 -0.220166 0.676007 1.432141 0.450339 0.554653 1.087402 1.040513 0.270076 0.433523 0.188787 1.457394 -0.061608 1.604147 1.071620 1.033490 -0.059301 1.622008 1.136168 0.012303 1.419176 0.768515 0.526817 1.171505 0.678139 1.461086 0.399056 0.554571 0.834287 1.199853 0.770698 1.010430 1.778823 1.630548 0.874770 0.206125 0.453526 0.079377 1.237714 0.535149 0.779971) 7.251376 #(0.000000 1.671606 -0.132668 1.341878 -0.143910 1.246587 0.061425 0.494279 1.199722 -0.185866 0.117035 0.003655 0.151884 1.021723 -0.210779 0.641242 1.366533 0.459003 0.565412 1.109528 1.023492 0.285228 0.454125 0.242355 1.465689 -0.057208 1.627387 1.006195 1.007496 -0.044962 1.574220 1.136668 0.030509 1.454684 0.778081 0.519496 1.098118 0.703324 1.453053 0.377008 0.578494 0.803467 1.196201 0.736893 1.011210 1.821383 1.576365 0.863547 0.163595 0.432959 0.102185 1.227214 0.512712 0.787061) ) ;;; 55 all -------------------------------------------------------------------------------- ; 7.416 (vector 55 9.0889595835043 (fv 0 0 1 0 0 1 0 0 1 1 0 0 1 1 1 1 1 0 0 0 1 1 0 0 0 1 0 0 0 0 1 1 1 1 1 1 0 1 0 1 1 1 0 1 1 1 1 1 0 1 1 0 1 0 1) 7.328036 (fv 0.000000 0.947722 0.378414 1.734925 1.134763 1.116950 -0.197611 1.060282 0.984801 1.744033 0.450580 0.852453 1.635373 0.966832 1.084419 1.003901 1.404608 1.476265 -0.291566 1.533682 1.691990 0.972863 0.920394 1.410967 0.405768 0.418479 1.362359 0.024022 1.434953 0.091943 0.952661 1.025574 1.292952 0.834214 1.423909 0.663594 1.666584 0.346034 0.453528 -0.158265 1.069551 0.339500 0.250235 -0.001369 1.635787 0.775741 0.405595 1.391152 1.825120 -0.221132 -0.233774 0.866177 1.169485 0.610484 1.501517) ;; 54+1 7.432099 #(0.000000 1.618747 -0.153449 1.551651 0.057022 0.983319 0.329322 0.592671 1.061368 -0.265451 0.093666 0.073689 0.191970 0.941940 -0.226532 0.630718 1.504459 0.398912 0.677456 0.969759 0.922508 0.474687 0.473824 0.106191 1.485519 0.211317 1.508720 1.087336 1.052013 0.035924 1.550864 1.050089 0.185510 1.339619 0.715238 0.544593 0.922333 0.813638 1.418714 0.428930 0.510114 0.892067 1.174189 0.405049 1.026718 -0.076773 1.305507 0.682450 0.215555 0.324834 -0.145842 1.269187 0.603278 0.899585 -0.345857) ) ;;; 56 all -------------------------------------------------------------------------------- ; 7.483 (vector 56 9.1394176483154 (fv 0 1 0 1 1 0 1 0 1 1 0 0 0 1 0 0 1 0 1 0 1 0 0 0 1 0 0 0 0 1 1 0 0 0 1 1 0 1 1 0 0 1 1 1 1 0 0 0 1 0 1 1 1 1 1 0) 7.349437 (fv 0.000000 1.546087 1.523699 -0.222814 1.563242 0.073887 1.226569 1.346857 0.292837 1.634387 -0.251778 0.060895 -0.022143 1.595396 1.558207 0.543894 0.524391 1.131307 0.107395 0.049540 1.190567 0.105407 1.309188 1.049686 1.847136 1.739252 0.730834 0.631473 0.965848 1.428286 1.258515 1.585209 1.811352 1.268900 -0.020138 0.642231 1.575017 1.141819 0.549674 0.685664 0.941820 0.311404 0.683359 0.230880 0.725054 -0.246162 1.525527 0.596605 1.235099 0.021275 1.782957 1.875900 1.027532 0.553643 1.151157 -1.905652) ) ;;; 57 all -------------------------------------------------------------------------------- ; 7.5498 (vector 57 9.370246887207 (fv 0 1 1 0 1 0 1 0 0 0 1 1 1 1 0 0 0 1 1 1 0 1 1 0 0 1 1 1 0 1 0 0 0 0 0 0 0 0 1 1 0 1 0 1 1 0 0 0 1 0 0 1 1 0 1 0 0) 7.442633 (fv 0.000000 0.628456 1.084630 0.786609 1.548782 0.496773 0.435493 0.422694 1.803774 0.918361 0.997194 1.049098 0.185525 0.660957 1.525706 1.561906 1.871425 -0.071743 1.628047 1.493214 -0.116955 0.206404 -0.134909 1.268493 0.758821 0.611040 1.564268 1.138473 1.072129 1.438518 1.711282 0.723211 0.929199 1.378242 0.744685 0.403345 1.655964 0.451399 1.464052 1.394001 0.957137 1.897197 1.337811 0.214489 1.090057 0.644474 1.099729 1.418576 0.330091 1.432560 0.258645 0.901692 0.058744 1.707516 1.251524 1.445949 1.245045) 7.441636 #(0.000000 0.622348 1.085878 0.781116 1.543398 0.503464 0.436201 0.436360 1.804081 0.922203 0.997170 1.054550 0.182189 0.658266 1.514505 1.560476 1.876098 -0.073438 1.631568 1.494541 -0.115431 0.197586 -0.136568 1.260188 0.759194 0.602693 1.552249 1.137538 1.078917 1.441614 1.707363 0.723396 0.932457 1.367004 0.727498 0.408065 1.643814 0.447632 1.455697 1.392558 0.945330 1.895625 1.343191 0.216675 1.082075 0.643569 1.094957 1.407053 0.340178 1.425341 0.271660 0.889612 0.056066 1.700603 1.245948 1.440641 1.250791) ;; 56+1 7.588529 #(0.000000 1.559006 1.528143 -0.234828 1.510743 0.072763 1.134383 1.362254 0.303204 1.570684 -0.091506 0.027141 0.127155 1.600459 1.489127 0.559851 0.585109 1.217750 0.060591 0.195572 1.371350 0.291252 1.406886 1.100984 -0.016324 1.766768 0.695302 0.610137 0.999643 1.441896 1.186797 1.655783 1.557906 1.163328 -0.045033 0.552673 1.529458 1.154094 0.507727 0.569429 0.791719 0.355519 0.577628 0.178344 0.617622 -0.241675 1.589877 0.728380 1.261435 0.065292 1.580960 -0.002275 1.148223 0.618586 1.286855 -1.867003 0.103477) ) ;;; 58 all -------------------------------------------------------------------------------- ; 7.6157 (vector 58 9.4419231414795 (fv 0 0 1 1 1 0 1 1 0 0 0 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 1 0 1 1 1 1 0 1 0 0 1 1 0 0 1 1 1 0 1 0 1 0 1 1 0 1 1 0 0 0 0 1) 7.593225 (fv 0.000000 0.986536 1.505069 0.859324 0.384061 0.501999 -0.052945 0.091682 1.243523 1.160936 0.166126 1.095539 1.756174 -0.122227 0.552109 1.557396 0.685859 1.585162 1.476945 1.055076 1.281043 0.783847 1.368420 0.615588 0.179246 0.641014 1.029588 -0.186574 0.302199 -0.049566 0.358796 -0.163645 1.827318 0.906618 1.173192 -0.306816 0.026558 0.176625 -0.050521 -0.001713 0.047940 0.417922 -0.025755 0.782149 0.436145 0.202813 1.499347 0.776547 1.362707 0.702487 -0.159222 1.853688 0.812543 0.355313 1.668872 1.299867 1.606542 0.186584) ;; pp: 7.586012 (fv 0.000000 0.718317 1.202315 0.028202 0.604627 1.135917 1.727021 0.381274 1.040230 1.739246 0.978472 1.777017 0.523285 1.243580 0.029135 1.381437 0.426286 1.404192 0.617991 1.834215 0.844002 0.191054 1.403866 0.517083 0.013036 1.338892 0.991152 0.141969 1.593581 0.974013 0.805540 -0.094361 1.826176 1.316543 1.040287 0.818373 0.169416 0.148481 -0.005247 1.691109 1.757644 1.290544 1.656395 1.204579 1.394324 1.303854 1.338185 1.515030 1.707660 1.781840 0.030717 0.283137 0.603418 0.969911 1.476088 1.200110 0.180175 0.633552) ;; pp1: 7.594343 (fv 0.000000 0.749835 1.196036 0.047415 0.621780 1.104858 1.683423 0.410089 0.997331 1.769746 1.019444 1.735512 0.510619 1.182024 0.010849 1.425649 0.362140 1.372448 0.624015 1.767029 0.754918 0.170009 1.406108 0.542718 -0.053715 1.339230 0.959996 0.102424 1.529396 0.978636 0.817177 -0.083573 1.854806 1.266587 1.089732 0.774700 0.147541 0.176983 -0.055229 1.674926 1.784675 1.300584 1.684703 1.169175 1.432021 1.273282 1.317555 1.468408 1.655397 1.821619 -0.009845 0.244752 0.605771 0.971746 1.410204 1.112895 0.141141 0.622757) 7.604882 (fv 0.000000 1.003143 -0.865267 0.010219 -0.099642 -0.478021 -0.093216 0.744325 -0.039294 -0.002416 0.551785 0.316654 -0.123222 0.301399 -0.383480 -0.165893 -0.726009 0.524402 0.651077 -0.962303 0.315215 -0.603015 0.258064 -0.340148 -0.256538 -0.041913 -0.379049 -0.712938 -0.349442 0.451149 -0.446083 0.896871 -0.490206 -0.472734 0.420264 0.151583 0.131069 0.834014 0.859212 0.483964 -0.544840 -0.090156 0.432176 -0.243993 -0.843563 -0.050600 -0.631713 0.342919 0.025289 0.027400 1.444366 -0.042492 -1.145968 0.638141 -0.833781 -0.384767 -0.149344 0.896836) ;; 57+1 7.533390 #(0.000000 0.631892 1.030548 0.996535 1.749363 0.527130 0.477024 0.368639 1.802926 1.003296 1.026792 0.861445 0.354012 0.677047 1.520092 1.568568 1.887052 -0.077599 1.681866 1.559188 -0.163779 -0.032281 -0.010624 1.336711 0.753633 0.560677 1.590572 1.250944 1.018806 1.569329 1.806513 0.820053 1.037991 1.389344 0.762236 0.480656 1.661302 0.465658 1.499904 1.500135 0.971523 1.890287 1.276369 0.072382 1.249962 0.582710 1.223535 1.436175 0.383524 1.412000 0.135455 0.769171 0.142483 1.827353 1.151930 1.547046 1.202745 -0.195258) 7.481139 #(0.000000 0.494120 0.912027 1.088506 1.796520 0.662315 0.621396 0.504785 1.809811 0.899674 1.186628 0.627937 0.587445 0.746949 1.418182 1.435063 1.844205 -0.044267 1.752818 1.424221 -0.141018 -0.093784 -0.133478 1.461699 0.840220 0.767006 1.740731 1.152491 1.108382 1.653182 1.853596 0.981136 1.198681 1.579726 0.839579 0.463906 1.810603 0.643978 1.514569 1.529989 1.033048 0.123830 1.430921 0.210010 1.371841 0.593103 1.143424 1.331116 0.451352 1.357884 0.020742 0.723087 0.311054 -0.015301 1.089900 1.570530 1.273463 -0.350924) 7.472170 #(0.000000 0.430844 0.953515 1.095387 1.834428 0.602659 0.597853 0.392425 1.797011 0.826392 1.113427 0.446408 0.529227 0.680942 1.329125 1.343688 1.818639 -0.122172 1.616802 1.292467 -0.195382 -0.212590 -0.247151 1.374774 0.796549 0.699593 1.645545 0.964816 1.084815 1.558580 1.737062 0.927802 1.039786 1.477445 0.712702 0.296961 1.758646 0.488444 1.376075 1.455278 0.882990 -0.037083 1.238179 0.077306 1.133427 0.444398 0.934392 1.211465 0.276242 1.242882 -0.192105 0.541924 0.088132 -0.286088 0.846397 1.327678 1.119123 -0.618251) ) ;;; 59 all -------------------------------------------------------------------------------- ; 7.6811 (vector 59 9.4819116592407 (fv 0 1 0 0 1 0 1 1 1 0 0 1 0 1 0 0 0 1 0 1 0 1 1 1 0 0 1 0 1 0 0 0 0 0 0 1 1 0 0 0 1 0 1 1 1 1 0 0 1 1 0 1 1 1 1 1 1 0 0) 7.633759 (fv 0.000000 -0.102106 0.411390 1.377383 1.497595 0.124070 0.977823 0.515946 1.620540 0.196166 1.145526 -0.281630 -0.195296 1.404391 0.189637 1.328165 -0.070129 0.678415 0.164240 0.284857 -0.029704 0.602274 0.993542 1.271589 0.492176 0.728322 0.791637 0.338071 1.390375 1.125972 0.444347 0.171840 0.693527 1.264131 0.439002 1.477092 0.989010 0.611429 0.828210 0.480652 -1.722373 1.692898 0.138317 0.412855 0.367615 1.849818 1.092865 1.381771 0.372051 1.523953 1.713816 0.119731 0.675902 0.655871 0.560189 0.993051 1.958772 1.303462 0.504587) ;; 60-1 7.668205 (fv 0.000000 0.260999 0.306319 0.829788 0.601433 -0.678190 0.032714 -0.031883 1.182121 0.436499 0.860411 1.529871 0.029506 -0.270659 1.490132 0.906453 0.632531 -0.000842 1.433413 0.099705 1.394290 1.492347 1.704612 0.859780 -0.064335 0.888916 0.823173 -0.092258 1.655169 1.087888 0.521033 0.694079 0.255286 0.100258 0.664742 0.255239 -0.004409 -0.020809 -0.246563 0.401722 0.426493 1.163559 0.741366 0.718411 0.770050 0.987515 -0.377733 -0.050194 0.650015 -0.412935 -0.094285 0.634376 0.230847 1.070214 0.078695 0.757129 0.097582 0.734853 -0.028246) ; 58+1 7.567729 #(0.000000 0.753874 1.108606 0.974281 0.283985 0.662033 0.650997 0.171167 1.713034 0.855505 1.018749 0.891985 0.435917 0.540560 1.459830 1.555159 -0.222214 -0.376165 1.777521 1.607719 -0.138482 -0.185224 0.145078 1.584935 1.029502 0.327951 1.867036 1.174458 1.172033 1.652747 -0.202580 1.284972 0.919829 1.617599 1.002052 0.275343 0.183263 0.550709 1.391786 1.438151 1.764529 0.225407 1.674751 0.321832 1.364256 0.748496 1.336450 1.931791 0.857675 1.688807 0.307620 0.802036 0.148078 0.020000 1.074227 1.654778 1.010253 0.016684 -0.457710) 7.555219 #(0.000000 0.684018 1.137315 0.968223 0.237663 0.655411 0.703581 0.179129 1.756606 0.877973 1.046593 1.013282 0.452948 0.616147 1.401809 1.505193 -0.202722 -0.390244 1.724472 1.616182 -0.097477 -0.170782 0.119472 1.497307 1.040170 0.317714 1.813227 1.115091 1.108189 1.689417 -0.262762 1.307718 0.931892 1.606817 0.960377 0.411286 0.247771 0.642681 1.412085 1.412909 1.797063 0.172164 1.740367 0.372886 1.379890 0.765467 1.444968 -0.036026 0.938248 1.692947 0.425883 0.844447 0.152098 -0.006221 1.039656 1.801143 1.018286 -0.026353 -0.556475) ) ;;; 60 all -------------------------------------------------------------------------------- ; 7.7459 (vector 60 9.575254043103 (fv 0 0 0 0 1 0 0 0 1 1 0 0 1 0 1 0 0 1 1 1 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 1 0 0 0 1 0 1 1 0 0 0 1 1 1 1 1 0 0 1 1) 7.588747 (fv 0.000000 0.303100 0.261228 0.917131 0.691793 -0.677124 0.027342 -0.014801 1.166154 0.416979 0.851167 1.410955 0.139409 -0.306122 1.416862 1.054300 0.792442 0.062922 1.507148 0.118287 1.375215 1.459904 1.620963 0.828106 -0.237368 0.987982 0.753194 0.096604 1.712227 1.239483 0.673351 0.871862 0.125962 0.260000 0.626286 0.147473 0.131774 0.201212 -0.194457 0.538798 0.418147 1.292448 0.871870 0.794549 0.988888 1.131816 -0.166311 0.052304 0.543793 -0.229410 0.113585 0.733683 0.271039 1.008427 1.788452 0.654055 0.106430 0.828086 0.097436 0.376461) ) ;;; 61 all -------------------------------------------------------------------------------- ; 7.8102 (vector 61 9.9175914844707 (fv 0 0 0 1 0 1 1 1 1 1 1 0 0 0 1 1 0 1 1 0 1 0 1 1 1 1 1 0 1 0 0 0 0 1 1 0 0 0 1 0 1 0 1 0 0 0 1 1 0 1 1 0 0 1 0 1 1 0 0 1 1) 7.764539 (fv 0.000000 0.501749 1.326260 -0.002830 0.440140 1.954758 -0.008202 0.999918 0.013473 0.542424 0.025115 0.566063 0.591900 -0.196853 0.709527 1.494974 0.701049 1.000710 1.261876 0.543883 0.605458 1.371875 -0.020772 0.931648 0.804346 0.926420 0.633175 0.027958 1.257581 0.427959 1.076239 -0.091270 1.537981 0.146252 0.640848 0.257921 1.798714 0.191485 0.663913 1.946117 1.528077 1.065296 -0.320137 1.459211 1.030583 1.751744 1.068882 0.287431 0.162869 0.095930 0.749409 1.433537 1.416981 -0.082974 0.219907 0.200900 1.575224 1.106230 0.733650 1.327996 1.447241) ;; pp: 7.753858 (fv 0.000000 0.319725 1.167003 1.840366 0.153760 1.056380 1.530371 0.068799 1.142107 1.630458 0.891055 1.372619 0.446834 1.091219 0.302492 1.393205 0.356103 1.143793 0.345744 1.558858 0.517245 1.731373 1.219460 0.122291 1.292388 0.849768 0.068299 1.373758 1.017991 0.385053 1.507703 1.138013 0.742591 0.285609 -0.125056 1.492440 1.058816 0.934160 0.593744 0.533680 -0.158800 0.426341 1.446080 1.766771 1.695866 1.560056 1.478090 1.737231 1.729597 0.116298 0.076540 -0.001350 0.001958 0.473570 1.021992 1.263777 1.530152 1.876463 0.039103 0.812610 1.066132) ;; 60+1 7.729878 #(0.000000 0.501241 0.237606 0.978914 0.682320 -0.738346 0.003863 0.191015 1.258332 0.203094 0.830345 1.438000 0.152627 -0.532209 1.427014 1.183594 0.624701 0.243054 1.493579 0.176931 1.408163 1.569029 1.678314 1.134453 -0.499872 1.081037 0.741424 0.444731 -0.070094 1.364678 0.717892 0.199159 0.000037 0.421827 0.501644 0.000638 0.131801 0.556608 -0.305504 0.649919 0.349420 1.653016 0.747436 0.624576 1.071688 1.251490 -0.264205 0.104670 0.467823 -0.348124 0.060239 0.441345 0.332223 0.905903 -0.014010 1.116703 0.324059 1.085578 0.038446 0.393074 -0.044048) 7.729641 #(0.000000 0.463648 0.245219 0.945196 0.651048 -0.734088 -0.016499 0.184730 1.247724 0.212438 0.819397 1.428152 0.148261 -0.535985 1.427158 1.161684 0.581178 0.249034 1.491750 0.150878 1.346200 1.564279 1.670074 1.129799 -0.517659 1.083110 0.682400 0.429246 1.869837 1.323050 0.738685 0.117986 -0.006088 0.376783 0.463179 -0.062397 0.035476 0.478607 -0.302119 0.573529 0.313684 1.619169 0.720247 0.569804 1.007611 1.154366 -0.364804 0.027671 0.390125 -0.440484 -0.028117 0.397064 0.225794 0.831365 -0.099773 1.002690 0.244315 1.000681 -0.071291 0.315345 -0.100933) 7.724678 #(0.000000 0.468911 0.239568 0.955993 0.660017 -0.740608 -0.005773 0.183020 1.262803 0.205104 0.825719 1.427337 0.148985 -0.545646 1.421878 1.165785 0.583348 0.241399 1.492038 0.153867 1.352915 1.564264 1.676784 1.122923 -0.525089 1.072617 0.697447 0.431113 1.876815 1.332016 0.730929 0.138318 -0.020534 0.383941 0.464477 -0.046001 0.053991 0.488682 -0.308619 0.592538 0.314268 1.634774 0.717562 0.581911 1.005194 1.161246 -0.358260 0.043757 0.409907 -0.425384 -0.020488 0.390805 0.247045 0.840009 -0.081618 1.014893 0.255614 1.022742 -0.054507 0.325271 -0.099612) ) ;;; 62 all -------------------------------------------------------------------------------- ; 7.8740 (vector 62 9.9292116165161 (fv 0 0 0 1 1 1 1 0 1 0 1 1 1 1 1 0 0 1 1 0 1 0 1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 1 0 0 1 0 1 1 1 1 0 0 0 1 0 0 0 0 1 1 0 0 0 0 1 0) 7.792971 (fv 0.000000 0.798156 1.779815 0.185967 1.670273 1.438952 1.815697 1.053871 0.087440 0.689337 0.052342 1.443903 1.423782 0.060887 1.727890 0.158639 0.952692 0.005318 0.914138 1.225205 0.683016 0.673829 0.109419 1.593849 0.225994 1.125995 0.418481 0.240605 0.743642 0.622844 0.353010 1.543180 1.534972 1.657806 0.217386 1.492286 1.132686 0.760213 1.147881 1.490201 0.001889 1.030507 1.289026 1.160822 0.387338 1.616191 1.464636 1.793960 1.874455 0.680274 1.683218 1.490668 0.689023 0.705366 0.946252 1.171040 0.109657 1.208442 0.793211 0.697986 1.263366 1.490757) ) ;;; 63 all -------------------------------------------------------------------------------- ; 7.9372 (vector 63 9.9555234909058 (fv 0 0 0 1 0 1 1 0 1 1 1 1 1 1 1 0 0 1 1 1 0 1 1 0 1 0 1 1 0 1 0 0 1 1 0 0 1 0 0 1 0 0 1 1 1 1 1 0 0 1 1 1 0 1 0 1 0 0 0 1 0 1 0) 7.900930 (fv 0.000000 0.112702 0.086876 0.634314 1.554089 0.214604 -0.203567 1.256800 0.100458 0.246503 1.488987 0.107459 1.914177 1.161772 1.897454 0.320257 1.283205 0.869894 1.466310 1.256681 0.167147 1.720679 0.949230 1.041227 1.129363 1.077459 1.317157 1.129579 0.390441 1.000383 0.208075 1.779398 1.501532 1.375523 -0.023235 1.338796 1.635364 1.234484 1.323162 0.435451 0.903475 1.821268 1.474898 0.271740 1.558504 0.547732 0.837920 0.522756 0.001164 1.566827 1.197274 1.065607 0.155490 1.019206 1.516032 -0.064964 -0.144993 0.026714 1.048953 1.812875 0.299023 0.685547 0.728053) 7.876881 (fv 0.000000 0.730162 1.053547 1.853555 0.252740 0.906538 1.566071 0.152709 1.015626 1.877411 0.660255 1.513063 -0.004442 1.023537 0.043516 0.973208 -0.080949 0.883081 -0.126245 1.080582 0.224101 1.423101 0.674610 1.604094 0.756913 0.381286 1.606872 1.293154 0.397443 1.644011 1.075770 0.644269 0.164589 -0.255888 1.331182 0.886941 0.357762 0.438290 1.706681 1.847928 1.153249 1.311949 1.226087 1.303371 0.783267 0.589091 0.697039 0.351577 0.554862 0.724022 0.729451 0.902218 0.841292 1.194121 1.061823 1.429706 0.001167 -0.011629 0.776088 1.037188 1.244629 1.522995 0.260285) ;; 62+1 7.805914 #(0.000000 0.601934 1.819111 0.471849 1.796784 1.557939 -0.026564 1.127818 0.479364 1.051771 0.128278 1.076188 1.581105 0.002062 1.593371 -0.164858 0.669949 -0.006771 0.676728 1.318085 0.880976 0.767111 0.655478 1.155761 0.306644 0.952223 0.140967 -0.196485 0.579088 0.861236 0.136455 1.859532 1.366764 1.343580 -0.020718 1.262958 0.917610 0.622309 1.387853 1.550991 -0.057003 1.281603 1.600851 1.216655 0.278309 1.739420 1.301224 -0.116573 -0.098586 0.465030 1.677940 1.531395 1.096719 0.709448 0.878166 1.233881 -0.104305 1.481973 0.932474 0.299442 0.967864 1.232287 -0.358064) 7.800306 #(0.000000 0.593041 1.814687 0.483090 1.809567 1.570434 -0.010963 1.133312 0.508100 1.082828 0.132800 1.081295 1.609650 0.004376 1.602307 -0.148895 0.679922 0.003650 0.695902 1.342115 0.911951 0.821441 0.666366 1.192523 0.330741 0.982706 0.167927 -0.164040 0.595303 0.873621 0.175773 1.884907 1.412718 1.374024 -0.003632 1.286158 0.950933 0.635806 1.438790 1.594221 -0.018194 1.324380 1.640059 1.280459 0.314889 1.818114 1.342146 -0.063931 -0.074642 0.525213 1.767962 1.608859 1.143810 0.780779 0.927340 1.305959 -0.057784 1.556344 1.011039 0.353582 0.998321 1.295658 -0.292113) ) ;;; 64 all -------------------------------------------------------------------------------- ; 8 (vector 64 9.957244923706 (fv 0 0 0 0 0 0 0 1 1 0 1 0 1 0 0 1 0 1 0 0 0 0 0 1 0 0 1 1 1 0 1 0 1 0 1 1 1 0 1 1 0 0 1 0 1 0 0 0 0 1 1 0 1 1 0 1 1 0 0 1 1 1 1 1) 7.941887 (fv 0.000000 0.078350 0.185008 1.926703 0.321363 1.181646 1.402668 0.610982 0.623089 1.216601 1.332592 -0.291595 1.818855 1.612142 0.352450 -0.172928 1.880133 1.280898 1.910145 0.775896 0.915424 1.581714 0.463086 0.548034 1.045305 1.495776 -1.677351 1.247040 0.522690 1.227534 1.269499 0.212698 -0.052232 1.635256 1.888480 1.734142 1.150438 1.012285 0.389543 -0.097094 -0.358616 1.129328 0.215283 0.611096 0.487394 1.263156 0.637871 1.355777 0.092029 0.148467 1.060411 0.413204 1.241091 0.569303 1.457881 0.998119 0.874341 0.432403 1.077636 0.523921 0.747328 1.722616 0.867015 0.916274) ;; pp.scm: 7.992914 (fv 0.000000 0.651329 1.088511 1.713470 0.442276 0.963521 1.501931 0.310181 1.212960 -0.011104 0.778232 1.515305 0.316833 1.237177 0.296916 1.189311 0.026642 1.098222 -0.017818 1.134719 0.273596 1.474260 0.550810 1.706455 0.919546 0.198719 1.526951 0.883788 0.268629 1.826193 1.021575 0.329612 -0.041590 1.516394 1.042877 0.648305 0.185654 -0.069051 1.607952 1.190320 1.094592 0.588439 0.829542 0.393611 0.610572 0.171199 0.117077 0.152394 -0.147682 0.017404 0.185404 0.037181 0.373288 0.371013 0.642715 0.482850 0.968331 1.382474 1.590294 -0.024057 0.298876 0.749699 1.152958 1.682631) ;; 63+1 7.860026 #(0.000000 0.809578 1.898769 0.467844 0.006957 1.570179 0.166964 1.399056 0.441035 1.263158 0.221043 1.092426 1.474756 0.007976 1.573880 0.092893 0.611450 0.051852 0.479088 1.319456 0.803792 1.198336 0.735571 1.265423 0.465756 0.760698 0.362640 -0.062961 0.627636 0.844966 -0.014667 1.769347 1.323936 1.245960 0.116850 1.375744 0.996394 0.370750 1.317375 1.741914 -0.329960 1.202157 1.458151 1.120658 0.217396 1.857269 1.281001 -0.057938 -0.080468 0.444525 1.682891 1.595713 1.143362 0.554820 0.939242 1.248217 -0.289778 1.508665 1.074317 0.351970 0.956968 1.151169 -0.275737 -0.049296) 7.856464 #(0.000000 0.822234 1.908730 0.467749 0.006656 1.612213 0.171726 1.378057 0.490600 1.283019 0.198540 1.138986 1.474359 0.023573 1.618066 0.107006 0.645127 0.046120 0.470802 1.320344 0.831192 1.192841 0.749343 1.290871 0.485677 0.828180 0.364554 -0.060479 0.620764 0.905935 -0.004028 1.773415 1.346206 1.276795 0.145101 1.369520 1.077798 0.374122 1.316067 1.750075 -0.308445 1.240419 1.495628 1.155630 0.297494 1.866545 1.311588 -0.004376 -0.041514 0.509113 1.692680 1.642970 1.149448 0.643495 0.990275 1.299612 -0.217370 1.583383 1.064236 0.447176 1.021444 1.233603 -0.209539 0.030332) ) ;;; 65 all -------------------------------------------------------------------------------- ; 8.0622 (vector 65 10.157649040222 (fv 0 0 1 1 1 0 0 0 1 0 1 0 0 0 1 0 0 1 1 0 0 0 0 0 0 1 0 0 1 0 1 1 0 0 0 0 1 0 1 1 0 0 1 1 1 1 0 1 1 0 0 1 1 0 1 0 0 0 0 0 0 1 0 1 0) 8.034868 (fv 0.000000 -0.445401 1.151245 1.279345 1.476130 1.870307 1.647070 -0.199190 0.996479 1.841605 1.029874 1.628641 0.687865 0.948026 1.437242 1.472256 1.713531 0.116128 0.684445 1.801135 -0.030628 1.120947 0.852540 1.164480 1.740537 0.856297 1.486946 0.172686 0.895511 0.630282 1.378315 0.169569 1.750827 0.453225 1.137053 0.474570 0.449455 1.468205 1.690172 0.505222 -0.186497 0.479672 0.299749 1.440549 1.876899 0.243582 0.699167 0.152947 0.932331 0.165767 1.486581 1.086937 1.179952 1.305509 1.186761 0.971873 0.910187 0.131821 0.021623 1.435803 1.077493 0.071755 1.363290 0.536054 0.282812) ;; pp: 7.973113 (fv 0.000000 0.586863 1.108547 1.809568 0.236474 0.932200 1.490976 0.236358 1.190604 -0.011282 0.981987 1.626061 0.541325 1.333541 0.166220 1.028548 0.073540 1.235912 0.201403 1.061871 0.289618 1.557561 0.463038 1.533243 0.718960 -0.031407 1.248624 0.634414 -0.029632 1.295765 0.653432 0.144947 1.300831 1.398877 0.579343 0.760977 0.024336 1.714192 1.357070 0.952728 0.458396 0.300957 -0.033236 0.181552 1.850554 1.728158 1.394294 1.294304 1.438841 1.230165 1.383584 1.610036 1.601644 1.798980 0.041945 -0.165907 -0.108364 0.492371 0.832142 1.280146 1.457449 -0.051803 0.040231 0.532391 1.056982) ;; 65+1 7.989976 #(0.000000 0.717074 1.790137 0.303763 0.122314 1.682143 0.216359 1.275289 0.381110 1.232945 0.219920 1.195050 1.544622 0.012541 1.697713 0.164535 0.808696 -0.033093 0.436931 1.424336 0.953440 1.075346 0.847229 1.377732 0.455680 0.844396 0.388170 -0.232520 0.566111 1.006265 0.239235 -0.064356 1.478182 1.310771 0.100992 1.360730 1.120501 0.518973 1.403629 1.737998 -0.215831 1.519996 1.486448 1.299685 0.264762 0.058410 1.261254 0.113761 -0.018088 0.416310 -0.086576 1.654308 1.428048 0.818894 0.929752 1.422804 -0.004686 1.681128 1.117926 0.396261 1.114085 1.263468 -0.302127 -0.143751 0.249776) 7.986549 #(0.000000 0.705159 -0.181004 0.217327 0.156922 1.778990 0.191147 1.113801 0.272034 1.171044 0.257920 1.334728 -0.188087 -0.096820 -0.018998 0.262759 0.954023 -0.039897 0.341389 1.444996 0.917955 1.089303 1.099624 1.600822 0.474003 1.078678 0.419361 -0.346529 0.769135 1.102121 0.462514 0.194004 1.393289 1.207814 0.168583 1.451937 1.578978 0.606330 1.663672 1.685805 -0.285434 1.500953 1.544223 1.459210 0.522782 0.144120 1.248342 0.284057 0.175310 0.542283 0.012495 1.586311 1.315843 1.018961 1.170529 -0.156886 0.147650 -0.231754 1.368201 0.537962 1.411226 1.416444 -0.114344 -0.050059 0.647067) ) ;;; 66 all -------------------------------------------------------------------------------- ; 8.1240 (vector 66 10.208241079264 (fv 0 1 0 0 0 0 1 1 0 1 1 1 0 0 1 1 0 1 0 1 0 1 1 1 0 0 0 0 0 1 0 0 1 1 1 1 1 1 0 0 0 1 0 1 1 0 1 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 1 0 0) 8.056638 (fv 0.000000 1.161331 1.936583 0.473825 1.730430 1.710083 1.722704 0.938539 0.650961 -0.301116 0.711382 0.874289 0.712393 1.263523 0.315048 0.391659 1.059022 0.363325 1.881127 0.161704 0.986800 1.590034 -0.289492 0.615410 -0.014906 1.387045 1.412270 1.265945 0.128543 0.445787 0.121476 1.705959 1.084173 1.066949 0.774156 0.933891 1.279265 0.297308 0.298325 1.512363 0.271282 1.243162 1.580605 1.521644 0.312598 0.465014 1.006013 0.269153 1.083812 0.157700 1.646414 0.707835 0.598039 1.973506 0.954025 0.104991 0.944717 0.038847 0.538283 0.734911 0.143649 0.104089 0.567333 0.271330 0.665962 0.751070) ;; 67-1 8.057849 #(0.000000 0.557868 1.277675 0.035082 0.606360 1.351203 1.836909 0.715558 1.256481 1.526554 0.538579 1.530425 0.580514 1.498578 0.116903 0.933739 0.019326 0.887252 -0.086797 0.604738 1.551540 0.736914 0.131651 1.149747 0.282533 1.227997 0.618183 0.164429 1.585108 1.228651 0.546852 -0.196864 1.480532 0.533190 -0.284020 1.599530 1.236535 0.954887 0.575524 0.413221 -0.000524 0.162211 1.214867 0.627804 0.589019 0.838842 0.451898 0.970982 0.399993 0.164558 0.108022 0.046075 0.027216 0.532334 0.358013 0.837176 0.729555 1.147175 0.936661 1.785417 0.184687 0.636068 0.955301 1.150651 1.841869 1.851218) 8.044495 #(0.000000 0.581065 1.291916 0.059254 0.617899 1.347083 1.813127 0.736507 1.273944 1.499042 0.544683 1.521865 0.547535 1.489105 0.122725 0.930947 -0.019577 0.828332 -0.123574 0.579943 1.554404 0.681236 0.080353 1.124307 0.249845 1.207295 0.630833 0.181490 1.580635 1.191264 0.544001 -0.219496 1.461932 0.541340 -0.290780 1.610474 1.275097 0.940533 0.570196 0.341107 -0.017602 0.133281 1.166976 0.573116 0.556656 0.758376 0.419521 0.906007 0.305727 0.149020 0.017843 0.033007 -0.043063 0.469814 0.304703 0.839693 0.673714 1.093033 0.885579 1.735487 0.146827 0.560866 0.914370 1.104996 1.771632 1.846520) ) ;;; 67 all -------------------------------------------------------------------------------- ; 8.1853 (vector 67 10.422191619873 (fv 0 1 1 0 0 0 1 1 1 0 0 0 0 0 1 1 0 1 1 0 0 0 1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 1 1 0 1 1 1 0 1 0 0 1 0 1 0 1 1 1 0 1 1 0 1) 8.144904 (fv 0.000000 0.836848 1.681555 1.191647 0.070261 0.942251 1.797644 1.070294 0.265921 1.462866 0.142770 0.004389 0.118755 0.795004 0.861059 0.364013 1.094070 0.938540 1.352932 1.681133 0.801557 -0.166830 1.660232 1.811404 -0.089491 1.793031 0.410641 1.462829 0.992048 -0.005221 0.624981 -0.049054 -0.100216 0.046599 -0.054149 1.061978 0.471687 -0.484886 1.299787 0.103592 0.873660 1.581185 1.539111 1.747106 0.867454 1.194479 0.984380 1.039016 -0.137566 1.440640 0.758746 0.623227 0.623868 1.161467 1.535042 0.328555 1.691644 -0.115223 0.929805 1.714954 0.103897 1.241682 1.520953 1.062392 0.666399 0.064868 1.788882) ;; pp: 8.072785 (fv 0.000000 0.714480 1.141487 -0.059495 0.626617 1.143106 1.724186 0.562381 1.166774 1.775820 0.595712 1.588031 0.453186 1.514340 0.088154 0.928491 -0.033585 0.878492 -0.006785 0.660928 1.635393 0.709844 0.143551 1.201690 0.276956 1.367207 0.639357 0.086720 1.577267 1.234748 0.475681 -0.133351 1.448411 0.486601 -0.203691 1.708040 1.315311 0.962381 0.408017 0.396955 1.868803 -0.051618 1.159243 0.738595 0.693611 0.852762 0.510509 0.806906 0.489441 0.162663 0.197789 0.090682 0.076822 0.594675 0.394390 0.961428 0.800767 1.169831 1.000600 1.531863 1.954261 0.431033 0.762550 1.024871 1.795795 1.769037 0.290496) ) ;;; 68 all -------------------------------------------------------------------------------- ; 8.2462 (vector 68 10.460547747753 (fv 0 0 1 0 1 0 0 0 1 1 1 1 1 0 1 0 0 0 1 1 1 1 1 0 1 0 1 0 1 0 0 0 0 0 0 1 0 1 0 1 0 0 1 0 1 1 0 0 0 0 1 0 0 0 0 1 1 0 1 1 1 0 0 1 1 0 0 1) 8.168157 (fv 0.000000 0.354978 1.878673 1.059221 0.759731 0.956747 0.711479 0.720163 0.372733 0.204844 0.455442 0.097446 1.506513 0.919884 0.814781 0.935488 0.786490 1.074073 1.203975 1.052443 0.726494 1.730845 0.062987 1.716136 1.412039 0.233751 0.090641 -0.003605 0.550389 0.691280 1.313887 0.137194 1.521036 1.556316 0.070039 0.198694 1.780701 0.986693 1.284403 1.408455 0.102332 1.273719 0.728671 0.008237 1.436719 1.092816 0.742660 1.480879 0.410157 1.288179 0.559234 1.425899 1.219179 0.189574 0.471285 1.159537 -0.028955 1.469388 0.210392 1.141156 -0.135055 0.687474 1.468060 -0.235268 0.553950 0.681055 0.986756 1.515599) ;; 69-1 8.134657 #(0.000000 0.790373 1.239220 0.460881 1.120937 1.102394 0.719196 1.260788 1.351581 0.150109 0.706820 1.708757 0.126405 0.573565 0.873737 1.541466 0.883699 0.146819 0.862233 -0.420165 0.374490 0.879454 1.601783 1.026685 -0.075871 -0.210918 0.449967 0.015278 0.084909 0.099093 -0.094596 1.643405 -0.042800 1.741808 0.515794 1.802790 0.939496 -0.125366 1.455519 0.180731 0.916674 -0.121997 0.876713 0.618219 0.625033 -0.767565 0.178266 0.158103 -0.126698 1.357885 1.217166 -0.144966 -0.267986 0.336938 0.761158 0.645268 0.017305 1.693864 1.248389 0.629256 0.208779 -0.415265 -0.031605 -0.400471 0.725040 0.782451 0.715907 0.712328) ) ;;; 69 all -------------------------------------------------------------------------------- ; 8.3066 (vector 69 10.495518383865 (fv 0 0 1 1 1 0 1 1 1 0 0 1 0 0 1 1 0 1 1 0 1 1 1 0 0 0 1 1 1 0 1 0 0 1 0 1 0 1 1 1 0 0 0 0 1 1 0 1 1 1 1 1 1 1 1 0 1 0 1 0 0 1 0 0 1 1 0 0 0) 8.197146 (fv 0.000000 0.551719 0.168788 -0.171535 0.603472 1.646430 0.831219 -0.112901 1.600971 0.776706 -0.257580 1.457106 0.729936 0.539913 1.421843 0.548661 0.072361 0.728562 0.364648 -0.109430 1.359599 1.471812 0.472868 -0.088533 0.623026 0.167759 1.605110 0.053141 0.996253 1.258861 1.710199 1.079237 0.316774 0.568130 0.226861 -0.084943 1.702544 1.075688 0.298153 0.507109 1.291563 1.177929 1.707324 -0.001439 0.386332 0.512557 0.380487 0.243873 1.516865 0.101344 -0.768813 1.646072 0.275192 0.139649 1.389985 1.576705 0.346880 0.446918 1.441036 0.376743 1.075298 0.134005 0.942798 0.778785 1.014815 1.144279 1.213481 1.047075 1.249788) ;; 70-1 8.143974 #(0.000000 0.563151 1.347234 0.372166 1.011160 1.230491 0.749402 1.243692 1.327484 0.188943 0.690097 1.705036 0.306148 0.675830 0.924357 1.699354 0.831298 0.036827 0.920452 -0.161127 0.378618 1.012001 1.732453 1.018416 0.093399 -0.223999 0.415971 -0.093239 0.157176 -0.107480 -0.077653 1.591872 -0.197575 1.675265 0.529602 1.688724 1.228937 -0.066917 1.910851 0.147616 0.958159 0.065098 0.692177 0.777376 0.643403 -0.410706 0.296222 0.415687 -0.096263 1.411122 1.263478 0.068706 -0.286121 0.572877 1.080715 0.960873 -0.048076 1.732249 1.330711 0.695044 0.195422 -0.180667 0.159809 -0.240900 0.873699 0.964556 0.811214 0.629243 -0.017179) ) ;;; 70 all -------------------------------------------------------------------------------- ; 8.3666 (vector 70 10.532930374146 (fv 0 1 1 1 1 1 0 1 1 0 1 1 0 1 1 1 0 0 1 0 0 0 1 0 0 0 0 1 0 1 0 1 0 0 0 1 0 0 0 1 1 1 1 0 0 1 0 0 0 1 1 0 0 0 0 0 0 1 1 1 1 0 1 0 1 1 0 0 0 0) 8.176963 (fv 0.000000 0.587989 1.431825 0.221285 0.960638 1.245837 0.795275 1.178692 1.324313 0.151685 0.789663 1.805305 0.407280 0.848410 1.089893 1.582619 0.871354 1.940142 1.022672 -0.098747 0.444755 1.081717 1.884930 1.020069 0.094475 0.162127 0.516048 0.043396 0.218952 -0.075886 0.177709 1.517609 -0.008561 1.566136 0.502844 1.768539 1.199988 0.053518 1.941460 0.082194 1.231659 0.182374 0.578473 0.843872 0.777996 -0.220205 0.467426 0.426401 0.154145 1.445497 1.004198 0.090981 -0.148632 0.673583 1.270739 1.002492 -0.085118 1.727335 1.374618 0.568333 0.205667 -0.017872 0.120962 -0.075966 0.957264 1.025234 0.841047 0.662525 -0.011036 1.297608) ) ;;; 71 all -------------------------------------------------------------------------------- ; 8.4261 (vector 71 10.610488331633 (fv 0 1 0 1 0 1 1 0 1 0 1 1 1 1 1 0 1 1 0 0 0 1 0 1 1 0 1 0 0 1 1 0 0 0 0 0 0 1 0 0 1 1 0 0 0 1 1 1 1 0 1 1 1 0 1 0 1 0 0 1 1 0 0 0 0 1 1 1 1 1 0) 8.319609 (fv 0.000000 0.140438 -0.156343 1.390907 0.216508 0.199081 1.047301 1.430567 0.016863 1.549577 0.363516 1.057536 -0.217538 0.646697 0.414461 0.993065 1.127770 0.877766 0.873392 0.440804 0.760841 0.449527 0.494946 1.105821 0.463488 1.200046 1.158237 0.977607 1.309426 0.772719 -0.483517 0.568526 0.817490 0.531524 0.272201 1.656272 -0.164981 0.659567 1.062868 -0.123485 1.015493 0.120132 0.671070 0.461022 1.766703 1.319785 0.775590 0.108288 0.757022 1.176333 1.486331 1.779348 -0.137633 1.540074 -0.041450 0.361903 1.057755 1.116867 0.573932 0.250328 1.480465 0.262890 0.893036 1.148682 1.046983 0.264942 1.618761 0.311598 1.395691 0.570219 0.159607) ;; 70+1 8.333845 #(0.000000 0.741042 1.489019 -0.124872 1.268392 1.336326 0.512548 0.937748 0.951723 0.152568 1.028858 -0.243353 0.086205 0.754698 1.441559 1.417305 1.142670 0.184075 0.610630 -0.436955 0.403625 1.323364 0.186977 1.074933 -0.224436 -0.269303 1.049190 0.015439 -0.107110 0.312582 0.157384 1.210121 0.061920 -0.163401 -0.010172 1.328828 -0.661526 -0.792391 -0.010926 -0.210071 1.441868 0.452979 0.227037 0.940601 0.552485 -0.755529 0.905193 -0.467293 0.369813 1.273291 1.124208 -0.504204 0.400118 0.917761 0.809535 0.178683 -0.004496 -0.260484 -0.237370 0.532021 0.652869 0.225451 -0.671013 0.610113 1.148179 1.320266 0.936680 0.634471 0.405144 1.190440 0.850770) 8.312176 #(0.000000 0.874002 1.383024 0.378933 0.799884 1.165596 0.533309 1.282741 0.886396 0.160934 0.729340 0.018471 0.256784 0.836821 0.836340 1.632305 0.875224 0.107603 1.058269 -0.313629 0.260148 1.563506 0.301401 1.147223 0.010044 0.210590 0.782179 0.044072 -0.074852 0.152561 0.153788 1.381267 -0.147303 1.443749 -0.014793 1.548909 0.014576 -0.121925 0.202272 0.029847 1.157828 0.486406 0.678816 1.002783 0.802159 -0.032653 0.703505 0.093729 0.211124 1.142051 1.177369 -0.359654 -0.078427 0.818294 0.971684 0.534909 -0.090789 -0.374344 1.667746 0.494486 0.436543 0.088578 -0.362483 0.515273 1.078602 1.312304 0.992479 0.513991 0.105033 1.004668 0.388247) ) ;;; 72 all -------------------------------------------------------------------------------- ; 8.4853 (vector 72 10.800657366855 (fv 0 1 1 0 1 0 0 1 1 1 1 0 1 1 1 1 0 1 1 0 0 1 1 0 0 0 0 1 1 1 1 0 0 0 0 0 1 1 0 0 0 0 1 0 0 0 1 0 1 0 1 0 0 1 1 0 0 0 1 1 1 1 0 1 0 0 0 0 0 0 1 0) 8.472893 (fv 0.000000 -0.093428 0.860520 0.651650 0.036400 1.174208 -0.214755 0.653075 0.661176 1.355137 1.759893 1.116459 1.283776 0.222435 0.388195 1.541066 0.171819 0.911538 0.292609 1.508023 0.997352 1.385529 0.022962 0.061408 -0.061153 0.241196 0.345845 0.923448 0.626801 0.283115 0.129077 0.499608 0.703807 0.614285 0.908458 0.403245 1.817077 1.458947 0.221667 1.213107 1.163972 1.117128 0.465749 0.627880 0.010093 0.512887 0.278332 0.535697 1.736410 -0.297420 0.467311 1.419905 1.531806 0.300181 0.244309 1.719696 1.200428 1.778805 1.081039 0.613164 1.654092 1.161237 1.675808 0.051072 0.709895 1.432879 0.690303 1.567340 0.453011 1.156931 0.253055 -0.113821) ;; pp.scm: 8.398072 (fv 0.000000 0.721030 0.948975 1.651519 0.233429 1.256419 1.215593 0.048780 1.144871 0.213229 0.880829 1.692382 0.366636 0.960208 1.629523 0.574770 1.546769 0.517973 1.617121 0.416046 1.542708 0.301404 1.290249 0.820158 0.258866 0.894435 0.090675 1.532038 0.985523 -0.034703 1.528561 0.881196 0.099225 -0.003432 1.044040 0.536864 -0.131692 1.029980 1.151362 0.675489 -0.005731 -0.378928 1.525987 1.057922 0.658986 0.443501 0.074450 0.429490 -0.435612 0.068631 -0.209332 1.531485 1.585628 1.667775 1.257877 1.589580 1.146646 -0.378411 1.726866 -0.167738 -0.290459 -0.269650 0.365115 0.370457 0.748015 1.193861 1.678605 0.010066 0.170551 0.863723 0.838123 1.538906) ) ;;; 73 all -------------------------------------------------------------------------------- ; 8.5440 (vector 73 10.773231506348 (fv 0 0 1 1 0 0 1 1 1 0 0 0 1 1 1 1 1 0 0 0 0 0 0 1 1 1 0 1 0 1 1 1 0 1 1 0 1 1 0 0 1 0 0 1 0 1 1 1 1 1 0 1 1 1 1 0 1 1 0 1 1 1 0 0 1 0 1 0 1 0 0 1 1) 8.432898 (fv 0.000000 -1.848123 0.239060 1.464251 0.628713 1.091837 0.714118 0.011434 1.168318 0.062880 1.015397 -0.328225 1.126530 0.965816 1.106076 -0.063170 1.197633 -1.809778 0.091864 0.972492 1.580451 1.036972 -0.065401 1.876586 0.421742 1.575936 0.943040 0.998651 1.251175 1.731410 0.520979 0.344525 -0.022728 1.604302 0.415026 0.363810 0.330426 1.053516 0.529548 0.585862 1.282692 0.064995 0.245738 0.033146 -0.021970 -0.243322 -0.102869 1.628985 0.462863 1.533635 0.132871 0.079809 0.450013 1.062550 1.900737 0.507033 1.228155 0.664499 0.381483 1.660810 1.361854 0.409741 0.569163 0.877009 1.830036 -0.331099 1.110302 0.325340 1.299368 0.004038 0.123887 1.612282 0.588683) 8.433132 (fv 0.000000 -1.847444 0.237344 1.464638 0.628887 1.093285 0.714406 0.013323 1.168036 0.063810 1.016680 -0.328601 1.126593 0.966206 1.107076 -0.063367 1.197228 -1.807287 0.093599 0.972529 1.580674 1.036337 -0.065390 1.875846 0.422275 1.575682 0.944151 0.999284 1.251360 1.730976 0.519804 0.344632 -0.023064 1.604915 0.415187 0.364741 0.329769 1.054442 0.530131 0.585700 1.283021 0.065351 0.245840 0.033137 -0.021137 -0.245019 -0.102624 1.631439 0.462301 1.532901 0.133014 0.079045 0.450558 1.061941 1.898554 0.507196 1.226904 0.663782 0.379349 1.659890 1.360030 0.408513 0.568905 0.876030 1.829471 -0.331743 1.109442 0.325360 1.299379 0.003611 0.124368 1.612931 0.587209) ) ;;; 74 all -------------------------------------------------------------------------------- ; 8.6023 (vector 74 10.684138298035 (fv 0 1 1 0 0 1 1 1 1 1 0 1 0 0 0 1 1 1 1 1 1 1 0 0 0 1 0 0 1 0 1 0 1 0 0 1 0 1 0 0 0 0 0 1 0 0 0 0 1 1 1 0 0 1 1 0 1 1 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 1) 8.497103 (fv 0.000000 1.325782 0.182538 1.505234 0.945874 -0.041671 1.080868 0.605444 0.042184 0.866151 0.092779 0.735532 1.859565 0.020319 1.317206 0.107906 1.193633 1.487996 0.330731 0.601261 1.523499 -0.092194 -0.139866 0.997309 1.096776 -0.197191 1.061243 0.954641 0.070885 1.639404 0.509022 -0.561148 1.719565 1.632249 0.046116 -0.076359 1.376098 -0.015465 1.245129 0.220256 -0.000849 1.641349 1.603215 1.034336 0.812483 1.278349 1.510965 -0.515530 0.337854 1.060139 1.372801 0.633196 -0.113165 0.038608 0.288776 0.637200 0.027245 0.289307 1.083582 1.060936 0.972742 0.986362 -0.049682 0.384401 -0.025034 0.779020 0.227500 0.842052 1.419898 1.088862 -0.034683 -0.286302 1.416569 1.188508) ) ;;; 75 all -------------------------------------------------------------------------------- ; 8.6603 (vector 75 10.935811368418 (fv 0 1 0 1 0 1 1 0 0 0 0 0 0 1 1 0 0 0 1 1 1 1 1 0 1 0 1 0 0 1 0 0 0 1 0 0 0 0 0 1 1 0 1 0 0 0 1 1 0 1 1 1 0 0 0 0 1 1 0 1 1 1 1 1 0 1 0 0 1 1 0 1 0 1 1) 8.611733 (fv 0.000000 1.755991 1.257704 1.380660 0.149810 0.888775 1.327127 0.155263 0.151577 1.307367 0.881185 1.244394 1.574597 0.297434 0.440838 1.532006 1.732873 0.955224 1.870085 1.039379 1.279345 1.370265 1.314175 1.228630 1.384735 1.656856 0.776266 0.604534 0.261984 1.021399 1.199829 0.578676 0.077339 1.180219 1.340992 0.303192 0.817942 1.840717 0.738716 0.586273 0.790045 1.068192 1.408743 0.034139 1.236420 0.200452 1.339574 1.564413 1.584603 1.696238 1.745531 0.073419 1.093015 0.201959 1.123150 0.434940 -0.158552 1.357895 0.030228 1.300705 0.831156 0.431680 0.205560 1.314167 1.822576 0.046350 0.064332 0.206633 1.539706 0.841946 1.061607 0.243862 0.776250 0.362661 1.442056) ;; pp: 8.821449 (fv 0.000000 0.643920 1.130972 1.690238 0.292464 0.869774 1.528895 0.096431 0.833368 1.732367 0.427956 1.133243 1.895101 0.800425 1.503313 0.355825 1.366323 0.344133 1.388010 0.331489 1.394341 0.485612 1.420333 0.688914 1.775329 0.789323 0.036609 1.415234 0.580136 1.640322 0.948602 0.310562 1.639770 0.988134 0.358709 1.824434 1.269806 0.767195 0.219365 1.612634 1.203169 0.799392 0.490094 0.057192 1.813674 1.532055 1.111172 0.983185 0.529777 0.494315 0.164905 0.200436 0.060224 0.054336 1.844838 1.742836 -0.015897 1.650654 1.808368 1.772294 1.907511 0.205329 0.331823 0.493249 0.521115 0.584376 0.981386 1.313449 1.561550 1.968782 0.480174 0.693653 1.229745 1.573452 0.052739) ;; 74+1 8.558162 #(0.000000 1.299463 0.144766 1.482206 0.852041 0.041751 0.945435 0.663483 0.032304 0.784185 0.138079 0.757000 1.655016 -0.051151 1.355972 0.142680 1.361194 1.375515 0.355950 0.322113 1.647006 -0.122201 -0.167635 1.027227 0.946767 -0.181720 1.159893 0.860801 0.046383 1.617661 0.451596 -0.634275 1.845795 1.639204 0.033347 -0.058314 1.256252 0.010245 1.129872 0.165186 -0.262708 1.745515 1.511527 1.020459 0.814780 1.270884 1.648219 -0.420679 0.234869 1.046009 1.235347 0.477491 0.107721 -0.063079 0.160473 0.709557 -0.087490 0.220254 0.843552 0.987545 0.718476 0.992398 -0.027851 0.215501 0.090914 0.848865 0.253479 0.800849 1.468047 1.086774 -0.125845 -0.438777 1.410433 1.246292 0.092658) ;; 76-1 9.623 (fv 0.000000 0.389242 -0.170662 1.421644 1.248164 0.164000 0.718605 1.792721 0.677210 1.518595 0.963267 -0.186472 1.263794 1.595425 0.383743 0.443182 1.535243 0.669172 1.194047 0.802827 1.746269 0.569800 1.408025 1.796723 1.258639 0.620093 0.886554 0.863256 0.711462 1.456391 -0.186271 0.639923 1.414383 -0.059653 0.858601 0.618312 0.847274 0.301714 0.319909 0.359052 0.817062 -0.212571 0.558016 0.169995 1.152558 0.886044 1.332154 0.013242 0.369659 -0.032997 1.710630 1.029547 0.363359 -0.095703 0.197840 0.264645 1.078918 0.774045 1.172991 1.082380 0.650868 1.140749 0.194089 0.747056 0.734148 0.248352 1.094670 0.793873 -0.197763 1.665030 0.915389 0.675623 1.504323 1.585265 1.586133) ) ;;; 76 all -------------------------------------------------------------------------------- ; 8.7178 (vector 76 10.689208030701 (fv 0 0 1 1 1 0 0 1 0 1 1 1 0 1 1 0 0 0 0 0 0 0 1 0 1 0 1 0 0 0 1 0 0 1 1 1 0 1 0 0 0 1 0 1 1 0 1 1 0 1 1 1 0 0 1 1 0 1 0 1 1 0 1 1 1 1 0 0 0 1 0 0 1 0 0 0) 8.622898 (fv 0.000000 0.389242 -0.170662 1.421644 1.248164 0.164000 0.718605 1.792721 0.677210 1.518595 0.963267 -0.186472 1.263794 1.595425 0.383743 0.443182 1.535243 0.669172 1.194047 0.802827 1.746269 0.569800 1.408025 1.796723 1.258639 0.620093 0.886554 0.863256 0.711462 1.456391 -0.186271 0.639923 1.414383 -0.059653 0.858601 0.618312 0.847274 0.301714 0.319909 0.359052 0.817062 -0.212571 0.558016 0.169995 1.152558 0.886044 1.332154 0.013242 0.369659 -0.032997 1.710630 1.029547 0.363359 -0.095703 0.197840 0.264645 1.078918 0.774045 1.172991 1.082380 0.650868 1.140749 0.194089 0.747056 0.734148 0.248352 1.094670 0.793873 -0.197763 1.665030 0.915389 0.675623 1.504323 1.585265 1.586133 1.087431) ) ;;; 77 all -------------------------------------------------------------------------------- ; 8.7750 (vector 77 11.114716461811 (fv 0 1 0 0 1 1 1 1 1 0 0 1 0 1 0 1 0 1 1 0 0 0 0 0 0 1 0 1 0 0 1 1 1 1 0 1 1 0 0 1 0 1 0 0 1 1 1 0 1 0 1 0 0 0 0 0 1 1 0 0 0 1 0 0 1 1 0 0 0 1 0 1 1 0 0 0 0) 8.693626 (fv 0.000000 0.342470 0.518102 0.602103 1.407511 1.793531 0.096346 0.250378 0.943784 0.388159 0.656038 0.296223 1.141950 0.214103 0.212479 0.828756 1.402312 1.692057 0.511954 0.158583 -0.254149 0.373835 0.095344 -0.147316 0.784069 0.081610 -0.056393 0.798330 0.705534 1.696239 0.742515 1.236436 -0.107133 1.590407 0.658892 -0.033009 -0.161883 1.612218 1.476439 0.692575 -0.060023 1.224517 0.875204 0.501273 0.494798 0.327706 1.600469 0.607079 0.567961 0.917115 0.716199 1.138396 0.731691 -0.084350 0.371809 0.181536 0.739186 1.478965 0.762792 0.759384 1.499056 1.662862 1.474568 1.752637 0.981158 1.382311 0.543578 -0.609814 1.825975 0.848970 1.045950 0.310451 0.519502 0.003348 1.354017 -0.105098 1.298274) ) ;;; 78 all -------------------------------------------------------------------------------- ; 8.8318 (vector 78 11.471938943963 (fv 0 1 1 0 1 0 0 0 0 1 0 0 1 0 1 1 1 0 0 1 1 0 0 1 1 0 1 1 1 0 0 0 1 0 1 1 1 1 0 0 0 1 1 1 0 1 0 0 1 0 1 0 1 1 1 1 1 1 1 0 0 0 1 0 0 0 0 0 1 0 0 1 1 1 0 0 0 1) 8.722411 (fv 0.000000 1.255512 1.230399 0.081980 0.091889 1.621099 0.342591 1.837930 1.553347 0.020611 1.397162 1.790981 1.252453 0.690562 0.318059 1.053703 0.774563 1.716197 0.556425 0.552259 0.785064 1.839927 0.777897 1.437066 0.895405 0.585543 1.604873 0.287802 1.218230 1.490317 0.738166 1.716918 1.559725 1.441156 1.459900 0.634618 1.118581 1.560941 1.459563 0.686391 0.612299 1.393780 -0.080258 0.668424 0.483242 1.297761 1.805261 0.997133 1.633324 0.413677 0.790560 1.306313 0.980643 1.877269 0.988455 0.158400 0.345980 0.044253 -0.181533 1.453766 -0.079535 1.631519 0.486812 0.259728 0.034933 -0.142793 0.162924 0.999804 0.854260 0.983588 1.417702 1.583925 0.160842 -0.232352 1.810021 0.235258 1.847667 1.008413) ) ;;; 79 all -------------------------------------------------------------------------------- ; 8.8882 (vector 79 11.334476470947 (fv 0 0 1 1 1 0 0 1 0 1 0 0 1 1 1 1 0 0 0 1 0 1 1 0 0 1 0 1 1 0 0 0 0 0 0 1 0 1 0 1 0 1 0 1 1 1 1 0 1 1 0 1 1 0 0 0 0 0 1 0 0 0 1 1 0 0 1 0 0 0 1 1 0 0 0 0 0 1 0) 8.845367 (fv 0.000000 1.238318 1.165090 1.291700 0.803595 0.614248 1.388497 1.905092 0.146964 0.775475 0.093294 -0.057178 0.069260 0.967289 0.726888 1.927694 0.404014 -0.050125 1.170622 0.795731 0.415661 0.113117 0.949983 0.547877 0.937155 0.147536 1.182414 0.680260 0.043365 0.406697 0.191985 0.520170 0.649818 0.646884 0.567272 1.384599 1.089945 0.420022 1.776381 1.388186 1.481564 0.061642 1.806781 0.638535 0.038366 1.606509 1.826388 1.366478 1.328019 0.480776 1.683074 0.476259 0.537766 1.179629 1.609320 1.234604 0.090600 0.429089 1.028733 0.835166 0.689618 1.227466 0.068475 0.130750 1.461448 1.601183 1.627224 0.857096 1.862391 0.455364 1.260302 0.135047 1.550455 0.219288 0.922341 0.004761 0.651583 1.409352 1.642849) ;; pp: 8.789422 (fv 0.000000 0.841271 1.349529 1.890897 0.486913 1.229207 1.764686 0.291323 1.071234 1.657114 0.392223 1.196564 -0.051237 1.012534 1.818519 0.557943 1.398685 0.101423 1.163908 0.287712 1.222706 0.108952 1.110220 0.148905 1.491258 0.557702 1.639140 0.711113 1.834003 1.123857 0.414123 1.736420 1.249713 0.566166 1.633495 0.696955 0.342141 1.602019 1.390394 0.718811 0.378092 1.687751 1.289262 0.793430 0.544409 0.190417 1.780346 1.824595 1.124520 1.532834 0.805430 0.739198 0.373300 -0.106662 1.921342 -0.093028 1.851981 1.677334 0.037484 1.564822 1.520739 1.501603 1.425816 1.592847 1.805684 0.130893 0.254917 0.439595 0.443645 0.715009 0.911405 1.240948 -0.028352 0.369153 0.881458 1.168966 1.410521 1.748339 0.400660) ) ;;; 80 all -------------------------------------------------------------------------------- ; 8.9443 (vector 80 11.30185508728 (fv 0 1 1 1 1 1 0 1 0 0 1 1 0 0 1 0 1 1 0 0 0 1 1 1 1 1 0 1 0 0 0 1 1 0 0 1 1 0 1 1 1 0 0 0 0 1 0 1 0 1 0 1 1 0 0 1 1 1 0 1 0 1 1 1 1 1 1 1 1 0 1 0 1 0 0 1 0 0 1 0) 8.831605 (fv 0.000000 0.718457 0.752874 0.707265 1.105140 1.556866 1.675971 1.743288 1.737050 1.402684 0.726424 0.001544 0.787560 0.610707 0.221912 0.548490 1.255462 0.532840 1.735795 1.159475 0.139393 0.566082 0.477708 1.186070 0.213588 1.697938 1.877210 -0.027617 0.446036 -0.097653 1.420626 0.288659 1.413894 1.358919 0.713009 -0.285435 0.875204 0.375292 0.708148 0.907015 0.596415 1.676708 -0.002236 0.617188 -0.254880 0.679354 1.396570 0.024604 0.491384 1.191175 0.583286 0.255907 0.583959 0.646881 1.743044 0.166682 0.513542 1.079013 0.694687 0.379588 0.528146 0.707196 1.408903 1.510794 1.151055 0.672700 0.297721 -0.154036 1.059849 1.480109 0.687072 0.133333 1.264870 -0.326181 0.342810 1.875130 1.918140 1.634313 0.782341 -0.170226) ) ;;; 81 all -------------------------------------------------------------------------------- ; 9 (vector 81 11.22668050284 (fv 0 0 0 0 1 1 1 1 1 1 0 1 1 0 0 0 1 0 1 1 1 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 1 1 0 0 0 1 0 0 1 1 0 1 1 0 0 0 1 0 1 0 0 1 0 0 1 0 1 1 1 1 1 0 0 1 0 1 0 0 0 0 0 1 0 1) 8.961491 (fv 0.000000 0.634711 0.914288 0.369120 0.489315 1.342522 0.647705 1.766421 1.148272 1.455934 0.450010 0.224566 1.110702 0.040996 1.346853 1.773154 1.255402 0.752437 1.110884 0.031625 1.597766 0.103816 1.912905 -0.011027 0.863686 0.820253 1.302167 1.352505 1.039370 0.116915 0.947518 1.168519 0.272351 1.514646 1.808891 0.551022 1.359986 0.703545 0.651408 1.697573 1.001093 1.819478 -0.153070 -0.020542 0.748602 1.669047 0.373021 0.491577 0.705265 0.740848 -0.189697 0.502215 0.348836 0.005306 -0.207198 0.930183 -0.631614 1.639932 1.773044 1.357496 1.130593 0.312825 1.896666 0.201668 1.169961 0.899991 0.382267 -0.065252 0.308097 0.095309 1.059630 -0.075945 1.147344 0.303812 -0.113244 -0.220507 0.240152 1.567520 0.130729 0.128142 -0.134246) ;; pp: 8.909320 (fv 0.000000 0.637783 1.093840 1.736075 0.229438 0.855956 1.363854 0.030260 0.521624 1.242121 0.051165 0.675419 1.614595 0.476873 1.278688 0.012785 0.817110 -0.304934 0.720383 -0.202920 0.733695 0.107439 1.315558 0.129614 1.122993 0.193244 1.234642 0.403581 1.725244 0.895732 0.205820 1.636536 0.593082 1.809528 1.260391 0.470119 -0.070091 1.399098 0.818162 0.271203 1.928340 1.562814 0.865292 0.051460 1.916623 1.232135 1.265689 0.734799 0.654116 0.188660 0.092307 1.641866 1.468875 0.817027 0.972897 0.621305 0.637924 0.617240 0.962249 0.473819 0.518139 0.286173 0.438785 0.267011 0.412016 0.426579 0.834941 1.189978 1.256888 1.096694 1.389245 1.442391 -0.226908 0.347927 0.458943 0.982038 1.505430 1.850054 0.061414 0.437908 0.768823) ) ;;; 82 all -------------------------------------------------------------------------------- ; 9.0554 (vector 82 11.601468306037 (fv 0 0 0 1 0 0 0 0 0 1 0 1 1 0 0 1 1 1 0 1 1 1 1 1 1 0 0 0 1 1 0 0 1 1 1 0 1 0 0 1 0 1 0 1 1 1 1 1 1 1 0 1 0 0 0 1 0 1 1 0 1 1 1 0 0 0 1 1 0 1 0 0 0 0 0 1 1 1 0 0 1 0) 9.074372 (fv 0.000000 1.648602 0.113059 0.965847 0.614379 1.876939 0.598065 0.033495 1.128904 0.535962 0.404933 0.340847 -0.287176 1.664997 0.944124 0.484563 1.365390 -0.175780 1.135023 1.030858 0.610885 1.630994 0.348969 1.892603 0.337558 0.278067 1.048537 1.676406 0.392409 0.207975 0.887089 1.313518 1.800663 1.007393 0.181812 -0.074478 0.144619 1.511865 1.173214 0.664191 1.387698 1.632837 0.132108 0.353188 0.227412 1.024174 1.607289 0.662392 -0.023377 -0.428601 1.063517 1.407784 1.563623 0.788150 1.561202 0.023129 0.361493 1.608137 1.816713 0.962416 0.274252 0.900687 0.860331 0.458473 0.118859 0.572111 0.805640 1.846370 0.649018 0.713232 0.291663 -1.866918 0.486252 0.300849 0.355338 1.356604 0.996671 0.882787 1.511703 1.110696 1.774461 0.441695) ;; pp: 8.942054 (fv 0.000000 0.741190 1.211121 1.767480 0.098390 0.839201 1.102556 -0.209453 0.453250 1.122839 0.064920 0.959867 1.388767 0.263801 1.292900 0.219769 1.265994 0.422114 1.103821 -0.093210 0.755477 0.000245 0.969187 1.607339 1.053959 0.313625 1.046034 0.279348 1.465040 0.751688 0.022843 1.470315 0.592990 1.853486 1.118710 0.593243 1.855200 0.862858 0.945784 0.185739 1.601158 1.076300 0.669622 0.291600 1.841348 1.175765 0.663836 0.601642 0.369909 1.837262 -0.023948 1.335189 1.343186 0.755277 0.855544 0.293163 0.518573 0.368668 0.285100 0.386831 1.688397 0.163703 0.172910 0.313842 -0.159903 -0.137818 0.212922 0.539645 0.627827 0.897666 0.865830 1.159886 1.047275 1.360198 1.762925 0.204264 1.078567 0.797293 1.200018 1.357729 0.204458 0.441846) ) ;;; 83 all -------------------------------------------------------------------------------- ; 9.1104 (vector 83 11.429935034332 (fv 0 1 1 0 0 0 0 0 1 0 1 1 1 1 1 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 1 1 0 0 0 1 1 1 1 0 0 0 0 1 1 0 1 1 0 0 1 1 1 0 0 1 0 0 1 0 1 0 1 1 0 1 0 1 0 1 0 0 0 1 0 0 0 0 1 1 0 0) 8.938600 (fv 0.000000 0.414028 0.125789 1.159865 0.086238 0.817482 0.340516 1.199339 -0.170286 1.744945 1.587696 1.158800 1.281058 0.190384 1.473320 0.235428 1.621261 0.225261 1.644931 -0.137023 1.525995 0.691219 0.557902 1.528647 -0.234276 -0.009740 0.044217 0.592778 0.909815 0.773874 0.836299 0.726340 0.981312 0.618405 0.408288 0.150201 0.908250 0.109103 0.413166 0.847395 0.541585 1.672450 1.474939 0.635397 0.153870 -0.014899 1.455728 0.983819 0.181154 0.726107 0.638924 1.106663 0.611788 0.238433 0.670956 1.522770 1.842401 0.939513 -0.051810 1.267322 0.323759 1.831419 1.004026 -0.159128 0.287041 0.349723 0.402841 0.045990 0.570998 1.374651 1.603295 0.760887 1.460939 -0.002747 0.693326 1.517648 0.987805 0.554027 0.029827 0.036863 0.188640 0.849464 1.347102) ) ;;; 84 all -------------------------------------------------------------------------------- ; 9.1652 (vector 84 11.774056434631 (fv 0 1 1 1 0 0 1 0 1 1 0 1 0 1 0 0 0 1 1 1 1 0 0 0 1 1 1 0 0 0 1 1 0 1 1 1 0 1 1 1 1 0 1 1 0 0 1 0 1 1 0 0 1 1 0 0 0 0 0 0 1 0 1 1 1 1 0 0 0 0 0 0 0 1 0 0 1 0 0 1 0 1 0 1) 9.023210 (fv 0.000000 0.159304 -0.208530 0.193874 1.193993 0.513874 0.193906 1.420202 1.601162 0.069662 0.596870 0.499106 1.879705 1.298791 1.380896 1.011752 1.567079 1.088823 0.586749 1.189212 0.187019 0.623891 0.443258 1.756821 0.221910 -0.166048 1.505325 1.956699 0.145006 0.858253 1.259810 1.292214 -0.292005 0.449812 -0.218977 -0.354252 1.219999 0.997645 1.646540 1.482430 0.239288 -0.155628 0.755326 1.705293 0.967714 0.360450 0.143064 1.152089 0.481087 0.972815 0.614833 1.330922 0.788019 0.726428 0.572863 1.454284 1.031818 0.764416 0.692179 1.019395 0.005944 0.083543 1.745841 0.713648 0.857380 1.260681 1.338561 0.608841 1.025699 1.518383 0.107569 1.492751 -0.040716 0.923284 0.288212 0.772164 -0.210851 0.728511 0.794985 1.593926 1.082153 1.208449 1.606070 0.581831) ) ;;; 85 all -------------------------------------------------------------------------------- ; 9.2195 (vector 85 11.927130699158 (fv 0 0 0 0 1 0 0 1 0 0 0 1 1 1 1 0 0 1 0 0 1 0 1 0 1 0 1 0 0 0 1 1 0 1 1 1 1 0 1 0 0 0 1 0 1 0 1 0 1 1 0 0 1 1 1 1 1 0 0 1 1 1 0 1 1 1 1 1 0 1 0 0 1 0 1 1 0 0 0 1 1 1 1 0 1) 9.127702 (fv 0.000000 0.377539 0.047529 1.429700 0.417181 1.140688 0.738197 -0.138709 -0.448043 0.627123 1.392127 1.819604 0.611302 1.321770 0.758910 1.628764 1.577483 0.372253 0.761090 0.479480 0.236979 1.110344 0.805106 1.644437 0.008357 0.656171 0.991297 -0.054354 1.739257 1.797129 1.125137 0.066677 1.422676 0.455091 0.389601 0.812550 0.569451 1.358336 1.535806 0.395945 0.917012 1.261389 0.975555 0.676523 1.340562 0.262979 0.348691 0.300647 1.560755 0.036844 0.912709 1.718241 0.914499 1.035722 0.712055 1.556119 1.328161 1.240892 0.216373 0.897089 0.626805 0.862584 0.585791 1.306757 0.828290 1.426360 0.918009 1.215542 0.443071 1.531104 1.274055 0.636447 0.998872 0.647434 1.352131 -0.267987 0.709420 0.317461 -0.001614 0.037126 -0.160098 1.679742 0.637515 0.582751 0.080874) ;; 84+1 9.178091 #(0.000000 0.092570 -0.328688 0.101879 1.164231 0.484791 0.263025 1.451681 1.371169 0.108316 0.583377 0.421708 0.063889 1.308369 1.554699 0.834440 1.382249 1.018775 0.556330 1.227389 0.358177 0.557221 0.316807 0.026851 0.347091 -0.193100 1.503856 1.682820 0.057602 0.906412 1.391283 1.172258 -0.306686 0.435069 -0.568978 -0.558083 1.240277 0.880388 1.809028 1.648747 0.142044 -0.051135 0.843030 1.589081 1.068210 0.522719 0.218341 1.007282 0.577304 0.998448 0.637448 1.458645 0.805087 0.732402 0.662530 1.436936 1.230072 0.780536 0.678657 1.336068 0.047814 0.297831 1.418569 0.786054 0.797109 1.410904 1.430707 0.466713 0.866817 1.332398 -0.186495 1.178146 -0.048740 1.088830 0.300282 0.620896 -0.201097 0.818687 0.773330 1.535207 1.274976 1.303891 1.667213 0.674931 -0.125079) ;; 86-1 9.057437 #(0.000000 0.570249 1.184584 1.763388 0.253739 0.874255 1.649278 -0.092856 0.545746 1.441082 0.012387 0.739864 1.567229 0.641869 1.248428 -0.258864 0.979020 0.106196 1.239561 0.188339 0.720317 1.206705 0.453833 1.256155 0.621647 1.775821 0.919384 0.039412 0.513365 0.132311 1.564752 0.722942 -0.071448 0.948131 0.009774 -0.016202 1.545153 0.487923 1.885615 1.372906 0.427563 1.527257 1.364251 0.890503 0.310553 1.662790 1.384147 1.043036 0.692189 -0.262514 1.340606 1.191753 0.846965 0.759339 0.701652 0.227347 0.525330 -0.260407 1.542211 1.308169 1.173799 1.057289 0.913467 1.783655 0.864914 1.204813 0.682233 0.998463 0.661854 1.098908 1.112695 1.765172 1.335644 1.631977 -0.249510 -0.168729 0.097422 0.642025 1.050451 1.546328 0.006675 0.099459 0.586892 1.021930 1.127145) 9.056499 #(0.000000 0.570308 1.184668 1.763370 0.253738 0.874213 1.649266 -0.092904 0.545708 1.441048 0.012251 0.739873 1.567319 0.641927 1.248333 -0.259041 0.979149 0.106269 1.239451 0.188403 0.720423 1.206709 0.453748 1.256279 0.621678 1.775878 0.919381 0.039448 0.513410 0.132072 1.564796 0.722923 -0.071345 0.948116 0.009644 -0.016259 1.545160 0.488035 1.885525 1.372878 0.427535 1.527093 1.364161 0.890433 0.310618 1.662754 1.384111 1.043150 0.692172 -0.262652 1.340519 1.191733 0.846909 0.759400 0.701644 0.227485 0.525106 -0.260481 1.542300 1.308046 1.173799 1.057405 0.913483 1.783592 0.864774 1.204856 0.682218 0.998396 0.661847 1.098951 1.112628 1.765109 1.335517 1.632001 -0.249528 -0.168911 0.097451 0.641933 1.050350 1.546283 0.006653 0.099465 0.586819 1.021860 1.127109) ) ;;; 86 all -------------------------------------------------------------------------------- ; 9.27362 (vector 86 11.780031204224 (fv 0 0 1 1 1 1 0 1 0 1 0 1 0 0 0 1 0 0 0 1 0 1 0 1 1 0 0 0 1 1 1 1 1 1 0 0 1 1 1 0 1 1 0 1 1 0 0 1 0 1 1 1 0 1 1 0 1 1 1 0 1 0 0 0 0 1 0 1 1 1 0 0 1 1 0 0 0 0 1 0 0 1 0 1 1 0) 9.206953 (fv 0.000000 -0.339088 0.933342 -0.128298 1.099279 0.084536 0.851599 -0.014992 1.465425 1.307317 0.418122 0.289943 1.668778 0.506500 1.696171 1.171193 0.792416 0.989400 0.972892 1.055909 1.790099 1.474165 1.862965 1.486120 1.916599 0.452792 1.686062 0.595804 0.951171 -0.158372 0.842834 1.045604 0.896962 0.721188 0.145646 1.627929 1.192540 1.524829 0.808536 1.173303 0.835497 0.870602 1.525244 1.506688 0.379810 0.397104 0.800652 0.803279 1.193873 1.751911 0.273257 0.582749 0.328287 1.542626 0.758388 0.690207 1.020504 0.688526 -0.031652 0.949811 0.197494 0.391786 1.605605 0.223632 0.906957 1.312801 1.428402 0.597149 1.497710 -0.659689 1.704635 0.962819 1.427359 1.450510 1.282944 1.167035 0.635413 0.328489 1.735204 0.771081 1.542497 0.207128 0.104268 1.136822 -0.363620 0.034704) ;; 87-1 9.154099 #(0.000000 0.546512 1.116802 1.888989 0.250808 0.822374 1.651582 -0.005692 0.626109 1.455571 0.073330 0.769650 1.652439 0.510220 1.146206 -0.051780 0.983214 -0.011253 1.055524 0.058792 0.798885 1.375789 0.494600 1.319397 0.591354 1.783545 0.902610 -0.070574 0.807019 0.110199 1.541898 0.751946 0.067110 0.972246 0.094850 1.874652 1.395502 0.413454 1.892267 1.394755 0.404089 1.604275 1.353279 0.912134 0.279923 1.677474 1.359302 1.024954 0.494212 -0.204624 1.444381 1.142405 0.986643 0.784929 0.720869 0.142356 0.321014 -0.264424 1.700672 1.171217 1.168722 0.911571 0.897262 1.490697 0.828456 1.047805 0.694648 0.985672 0.794358 1.062298 1.103188 1.595006 1.521040 1.764525 -0.106047 0.016946 0.120669 0.643435 1.011018 1.433782 0.064397 0.052151 0.670043 1.097438 1.450840 1.829744) ) ;;; 87 all -------------------------------------------------------------------------------- ; 9.3274 (vector 87 11.76194265333 (fv 0 0 1 1 1 1 1 0 0 1 0 1 0 1 0 0 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 0 1 1 1 1 0 1 0 1 0 0 0 0 0 1 0 1 0 1 1 1 0 1 1 0 1 0 0 1 0 1 1 0 0 1 1 1 0 0 0 1 1 0 1 1 1 0 1 0 0 0 0 0 1 1 1) 9.336088 (fv 0.000000 0.935303 -0.305855 0.639666 -0.205066 0.575166 1.878633 -0.031633 0.332111 0.265245 0.447761 1.471005 0.466239 1.074654 0.243517 0.903095 0.071080 0.582837 0.986978 1.432105 0.143848 1.529993 0.888064 0.154620 1.746534 1.298224 1.092204 0.252914 1.241973 -0.114644 0.118634 1.005127 -0.195946 0.639640 0.754289 -0.065632 0.714364 1.300342 0.839106 1.256746 0.582262 1.885531 1.298010 0.384388 0.185574 1.168220 1.586291 1.242180 1.296083 0.391273 0.262871 0.811036 0.806565 0.431451 1.015342 1.630813 1.685662 -0.062763 0.311437 -0.322103 1.934808 -0.217239 0.478902 -0.218460 1.046362 0.603169 1.523851 1.302931 0.360083 0.678610 0.838126 1.626723 0.408089 0.150785 0.439104 0.575446 0.524826 1.662738 0.111387 1.179455 0.712858 0.531389 0.286195 0.456407 0.251572 1.398780 1.753711) ;; pp:start point was (pp.scm, make-pp.scm): pi+pi/87 and -pi/2 9.201148 (fv 0.000000 0.606264 1.286641 1.633640 0.300135 0.826873 1.570361 0.039518 0.674212 1.390759 0.031099 0.782113 1.606099 0.456663 1.310938 -0.012755 1.011947 1.962275 1.031324 1.924212 0.700369 1.463259 0.449090 1.418882 0.516579 1.837916 1.056960 -0.026846 1.090144 0.187208 1.379580 0.694876 0.055771 0.972409 0.040906 1.575865 1.149936 0.410530 1.850809 1.237404 0.345035 1.553764 1.235369 0.825540 0.101389 1.583999 1.336472 0.955112 0.350910 -0.239863 1.473194 1.184033 1.132454 0.656789 0.797039 0.036147 0.315231 -0.255734 1.842540 1.250679 1.177721 1.108481 0.895012 1.358540 0.880609 0.969577 0.756153 1.004262 0.902032 1.003387 1.132762 1.561102 1.534103 1.804297 0.070209 -0.024117 0.069086 0.402650 0.873594 1.402800 1.716632 1.930312 0.453843 0.755753 1.442497 1.742394 -0.135628) ) ;;; 88 all -------------------------------------------------------------------------------- ; 9.3808 (vector 88 11.638312339783 (fv 0 1 1 0 1 1 1 1 0 0 1 1 1 1 0 0 0 1 1 1 0 1 1 1 0 0 0 1 1 0 0 1 1 0 1 0 0 0 0 0 0 0 0 0 1 0 1 1 1 0 0 1 1 0 1 0 1 1 0 1 0 0 0 0 1 1 1 0 1 0 1 0 1 0 0 1 0 0 1 1 0 0 1 1 1 1 1 1) 9.316523 (fv 0.000000 0.878486 0.456733 1.616494 0.833842 1.630288 0.213084 0.318066 0.387075 1.258199 0.888074 1.626323 1.385324 1.449641 1.788877 1.459694 0.074476 0.796586 0.333918 0.652336 0.086019 1.093159 0.327760 0.026729 0.468210 0.200167 0.537074 1.539924 -0.274885 1.353211 0.267108 0.236471 1.407050 0.990605 0.724714 0.464124 0.495860 1.314621 -0.030616 0.350065 0.839694 0.794947 -0.082046 0.540462 1.600245 0.715450 0.591095 1.608103 0.808561 1.476715 1.175725 0.089220 0.447550 -0.172825 1.173712 -0.287102 0.416439 1.195370 1.285929 1.007325 0.957271 -0.013128 1.194681 1.765216 1.741310 1.202198 1.235154 1.112410 1.116838 1.017962 0.227564 0.013993 0.930616 0.757675 -0.297628 0.560900 0.173387 0.493968 1.241443 0.533916 1.114281 1.119507 0.538020 0.529723 1.672789 1.594826 0.538626 1.278733) ;; 87 + 1 (pp) 9.255901 #(0.000000 0.704719 1.188893 1.675767 0.096018 0.845936 1.487824 0.078995 0.667889 1.297691 -0.023647 0.780968 1.603472 0.340759 1.204870 0.026757 1.150149 0.124316 1.065077 1.884618 0.609326 1.416953 0.372499 1.356073 0.453572 1.767703 1.001278 -0.238843 0.931840 0.205018 1.420053 0.675690 0.112242 1.052571 0.089462 1.485924 1.236180 0.407150 1.816803 1.284565 0.400450 1.410505 1.095373 0.831937 0.217112 1.631168 1.291427 1.030080 0.299217 -0.282356 1.506750 1.204044 1.185604 0.656589 0.898458 0.004864 0.154258 -0.340896 1.825973 1.369257 1.104084 0.921755 0.900302 1.295845 0.824555 1.094591 0.785023 1.079180 0.885480 0.926136 0.942138 1.655789 1.435560 1.812571 -0.053178 0.016700 0.075866 0.223760 0.836926 1.243772 1.565476 1.835913 0.515899 0.597634 1.438547 1.710832 -0.154189 0.323632) ) ;;; 89 all -------------------------------------------------------------------------------- ; 9.4340 (vector 89 12.148494905477 (fv 0 0 0 0 0 1 1 0 0 0 1 0 1 0 0 0 0 0 0 1 0 1 0 1 0 0 0 0 1 1 0 0 1 0 1 1 1 1 1 1 0 0 1 0 0 1 0 1 0 0 0 0 0 1 1 0 1 1 0 1 0 0 1 0 1 1 0 0 1 1 0 0 1 0 1 0 1 1 1 0 0 1 1 0 0 0 0 0 1) 9.351480 (fv 0.000000 0.115345 0.952969 1.130622 0.084058 0.254252 0.443202 0.470071 0.932794 0.466331 0.591979 0.457396 1.528107 0.715257 1.847307 0.403253 0.673874 1.456603 0.267262 0.304798 0.064020 -0.007350 0.259234 -0.287472 0.913317 0.595047 1.491194 0.951199 1.469407 0.524123 -0.304693 -0.076445 1.827209 1.059199 1.449793 1.495662 0.754984 0.852314 0.216817 0.724819 0.597427 1.273980 0.926620 0.643916 0.066061 0.625597 1.284699 0.657854 0.605911 1.653365 1.442076 1.033587 -0.542590 1.262635 1.257414 1.117301 0.126208 0.112501 1.272548 0.912632 0.005045 0.757226 0.049364 -0.033316 1.800311 -0.300949 0.310947 1.267820 0.529700 0.817110 -0.265053 1.152779 -0.048439 0.296709 1.270792 1.398568 -1.703554 0.050635 0.940556 0.440806 1.384526 0.885947 -0.609539 0.281434 0.391260 0.168064 1.027217 1.891400 0.923378) ;; 90-1: 9.353077 #(0.000000 0.101446 0.552891 0.728107 0.524893 0.145214 1.596053 1.301540 0.926397 0.496933 0.459068 0.452889 -0.240583 1.847402 1.625502 1.401709 1.344010 1.170760 1.113124 0.952056 0.990499 1.326791 1.137187 1.344890 1.398023 1.149659 1.097175 1.559308 1.708797 -0.021498 0.416394 0.386368 0.384056 0.606232 0.977603 1.375793 1.270354 1.302953 0.359489 0.616160 1.115795 1.441415 1.647690 0.643610 0.895244 0.975118 1.685984 -0.077953 0.815100 1.503675 0.336177 0.774857 1.287785 1.833629 0.348295 1.088177 0.209087 0.777608 -0.029670 0.123001 1.329891 0.059409 1.263588 0.016222 0.685238 1.233668 0.561348 1.497739 1.015119 0.057179 0.615014 1.898096 0.865835 1.905681 0.688463 -0.268308 1.169876 0.259887 1.566670 1.025132 -0.067077 1.290408 0.701373 0.247065 1.395004 1.347652 0.414191 -0.013443 1.694985) 9.345721 #(0.000000 0.103486 0.551861 0.726996 0.523771 0.144646 1.597548 1.302819 0.925442 0.494761 0.457372 0.448545 -0.241478 1.847854 1.625226 1.401271 1.344622 1.169875 1.113623 0.952209 0.990633 1.328837 1.137936 1.343935 1.399193 1.149690 1.096126 1.561038 1.711408 -0.022261 0.415937 0.388160 0.384297 0.607557 0.979556 1.373917 1.270638 1.303704 0.361732 0.614655 1.116132 1.440007 1.647123 0.645566 0.896623 0.974182 1.687056 -0.077314 0.812365 1.506132 0.337144 0.772963 1.287030 1.834127 0.348950 1.088801 0.208217 0.776609 -0.031553 0.124342 1.329352 0.062088 1.264941 0.018704 0.686528 1.235155 0.563447 1.498951 1.015729 0.058587 0.616286 1.897192 0.867074 1.907854 0.688520 -0.265323 1.172547 0.258395 1.566059 1.027835 -0.069245 1.293131 0.701031 0.244435 1.397502 1.346741 0.412354 -0.014152 1.693363) ) ;;; 90 all -------------------------------------------------------------------------------- ; 9.4868 (vector 90 12.059710502625 (fv 0 0 1 0 1 0 0 0 1 1 1 0 0 1 0 0 1 0 1 0 1 1 1 1 0 0 0 0 1 0 1 0 1 0 1 0 0 0 0 1 0 1 1 0 1 1 0 0 1 1 0 1 1 0 1 0 0 1 0 1 1 1 1 1 1 0 0 0 1 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 1 1 0 0 0 0) 9.398614 (fv 0.000000 0.892706 1.062256 0.213835 0.203111 1.398668 1.054220 0.038528 1.142619 0.118583 0.457258 1.631677 1.573493 1.353053 0.245939 0.098142 1.245835 1.513894 0.025359 0.747716 0.843192 1.216875 0.015492 0.415459 0.312421 1.153905 1.780617 0.437612 -0.400304 -0.029367 1.378815 -0.215560 0.280582 1.233159 0.249478 0.201675 0.961263 0.048927 0.571980 0.265611 0.963409 1.336060 0.891681 1.142504 1.421083 1.162603 1.027272 0.851118 0.849549 0.034892 1.199036 0.308700 1.882141 0.734414 0.473371 1.758626 0.761172 0.952217 -0.108344 1.230664 0.088942 0.737287 0.280477 0.684695 1.865274 1.638095 0.534719 0.573717 0.414603 0.759210 0.580912 -0.293171 0.034364 1.872658 1.705405 0.725925 -0.286371 0.704217 0.268789 0.757724 0.268458 1.430890 1.325737 1.264595 0.335646 0.223092 0.572527 0.875084 0.723299 0.490792) ;; 91-1 9.369284 #(0.000000 0.030596 0.512977 0.726782 0.477829 0.081885 1.589694 1.322061 1.083902 0.559521 0.448753 0.385931 -0.189736 1.722513 1.513355 1.392162 1.333913 1.122941 1.145305 1.071310 1.267721 1.283537 1.282341 1.395603 1.460843 1.220013 1.214982 1.532704 1.680386 -0.041828 0.369697 0.425933 0.371638 0.589333 1.041407 1.225589 1.172832 1.376354 0.162279 0.498805 1.164883 1.416170 1.867958 0.505897 0.978762 1.054842 1.522372 -0.063766 0.952495 1.463756 0.521257 0.824505 1.179094 1.811681 0.447390 1.180931 0.235815 0.652944 -0.161883 -0.021774 1.283901 -0.087905 1.281512 -0.144202 0.579788 1.336977 0.409226 1.333107 0.963576 0.011530 0.529499 1.655761 0.578200 1.742908 0.613593 -0.239938 1.074047 0.302129 1.602392 0.926017 -0.218685 1.216630 0.428055 0.183727 1.506714 1.185120 0.296902 -0.071562 1.483831 0.585762) ) ;;; 91 all -------------------------------------------------------------------------------- ; 9.5394 (vector 91 12.130150794983 (fv 0 1 1 0 0 0 1 0 0 0 0 1 0 1 1 1 1 0 0 1 0 1 0 1 1 0 0 0 1 0 0 0 0 0 1 0 0 1 1 0 1 0 0 0 1 0 1 0 1 0 1 0 0 0 0 1 1 1 1 1 1 0 0 0 1 1 0 0 0 1 0 0 1 0 1 1 1 0 0 0 1 0 0 1 0 0 1 1 1 1 0) 9.460641 (fv 0.000000 0.436117 1.518395 1.686873 0.685584 1.390220 1.721023 1.218901 0.617875 0.942031 0.798753 1.787198 0.914695 1.067725 0.500698 1.164934 1.198775 0.318349 0.110243 1.683123 1.771564 0.104141 0.404057 1.512291 -0.053002 0.635555 0.485286 0.639133 1.522433 0.362468 1.841483 -0.018649 1.636664 1.891231 -0.092223 0.000560 1.591693 0.345850 0.362361 0.150153 0.525106 1.675920 1.376159 0.544954 1.155066 0.115196 0.924275 -0.119311 1.123186 0.422131 1.628623 0.610317 0.891460 1.679635 0.315850 0.345138 -0.095637 1.712298 -0.241584 0.926203 1.708802 0.312769 0.179387 0.288518 0.999840 0.990421 1.415220 1.453610 0.512219 1.890115 0.694941 1.068928 1.023842 0.497685 1.095073 1.132736 1.716879 -0.012368 0.180422 1.245447 0.380145 -0.172552 1.441547 0.152524 1.430740 1.014319 0.944154 0.113921 1.674916 -0.025585 0.846123) ;; 92-1 9.406571 #(0.000000 0.070183 0.558945 0.616954 0.488264 0.097581 1.643944 1.396224 1.158953 0.725014 0.517196 0.327654 -0.169876 1.614114 1.687774 1.412838 1.174539 1.259505 1.130798 1.052361 1.015956 1.267208 1.254231 1.379495 1.394559 1.223329 1.348807 1.448672 1.402107 -0.114780 0.204211 0.407141 0.213819 0.557195 0.878563 1.293773 1.227658 1.440547 0.218508 0.668102 0.992197 1.450344 1.592835 0.514105 0.745631 1.232389 1.450929 -0.020833 0.958476 1.514641 0.316511 0.755172 1.221264 1.755846 0.507669 1.139584 0.110724 0.749907 0.055238 0.050342 1.322976 0.038212 1.303755 -0.169105 0.463456 1.427795 0.697605 1.381025 0.968559 0.022635 0.695622 1.792840 0.529902 1.903317 0.747931 -0.193306 0.982955 0.298689 1.702098 1.077145 -0.265151 1.140052 0.371003 -0.055705 1.235675 1.006638 0.294853 1.755510 1.459678 0.647624 -0.081756) ) ;;; 92 all -------------------------------------------------------------------------------- ; 9.5917 (vector 92 12.009957507951 (fv 0 0 0 1 0 1 0 0 0 1 1 0 0 1 1 0 1 0 0 1 1 0 1 1 0 0 1 1 1 0 0 1 0 1 1 1 0 0 0 0 0 1 1 1 1 0 1 0 0 0 0 1 0 0 1 0 1 0 0 0 1 1 1 0 0 1 1 1 1 1 1 1 0 1 0 1 0 1 0 0 1 1 1 1 1 1 1 1 0 1 0 1) 9.517966 (fv 0.000000 0.086823 0.747623 -0.085371 0.122456 -0.230268 0.119188 1.361402 1.167782 0.037384 1.047768 0.553092 0.649815 1.008382 0.794506 0.305054 1.023759 0.770450 1.886190 0.685208 0.379196 0.684576 0.589903 0.070635 1.842447 1.673609 -0.393612 0.098157 1.794112 0.846616 0.025307 0.910127 0.590170 1.608490 0.410052 1.692507 -0.369713 0.406231 1.469315 1.471065 0.951373 1.130104 0.531009 1.015991 1.488443 0.280351 0.460606 1.244663 1.053735 0.254819 0.300775 0.994290 1.059430 1.061070 1.049296 1.008564 -0.162768 1.637847 1.291833 1.037154 0.364051 0.144913 0.533100 1.075664 1.325409 -0.343880 0.931404 1.449787 0.745214 0.874779 -0.406152 1.757226 1.474675 0.453343 1.845066 0.544094 1.158828 0.100488 1.840683 0.221106 0.924537 1.893930 0.736114 1.402591 0.613840 0.057492 0.409601 -0.093628 1.271558 0.626825 0.949050 -0.217069) ;; 93-1 9.419885 (fv 0.000000 0.069529 0.633901 0.633608 0.570434 0.157518 1.715794 1.321616 1.084449 0.794466 0.425008 0.283514 -0.131990 1.646881 1.533838 1.442714 1.177599 1.239726 1.207883 1.015321 0.976921 1.262383 1.278818 1.276322 1.338824 1.226865 1.318320 1.361295 1.375488 -0.072989 0.149612 0.367026 0.181636 0.504697 0.851522 1.286853 1.425655 1.395838 0.306909 0.627046 0.973004 1.385102 1.455309 0.477354 0.684776 1.138509 1.548279 -0.072451 0.798558 1.262715 0.056514 0.791921 1.056616 1.695546 0.434938 1.116470 0.025573 0.789168 -0.006184 0.138467 1.335319 0.002519 1.259750 -0.081984 0.549375 1.443475 0.683161 1.338585 0.966058 1.876977 0.624731 1.787187 0.503447 1.917935 0.840074 -0.187662 1.042424 0.183738 1.737882 1.038721 -0.194530 1.214452 0.488651 0.014114 1.273532 1.004556 0.303820 1.746128 1.409399 0.765865 0.191028 1.596552) ) ;;; 93 all -------------------------------------------------------------------------------- ; 9.6437 (vector 93 12.125471062226 (fv 0 1 0 0 0 0 1 0 1 0 1 1 1 0 1 0 0 0 1 1 1 0 1 1 1 1 0 1 0 0 1 0 1 0 0 1 1 0 0 1 0 1 1 0 1 1 1 0 1 0 1 0 1 1 1 1 0 0 0 1 0 0 1 1 0 0 0 0 1 1 1 0 0 0 1 0 0 0 1 0 0 1 0 0 1 1 0 1 1 1 1 1 1) 9.668780 (fv 0.000000 1.502492 1.735960 1.811396 -0.104957 0.482636 0.500559 -0.183071 -0.047836 1.299077 0.116243 0.998697 1.692766 0.951722 0.883989 1.357273 1.702880 0.882694 1.095034 1.397512 0.329332 0.527364 0.298917 0.655212 0.187816 0.424294 1.150209 0.114579 0.252718 -0.217705 0.508106 -0.043801 0.270810 1.167969 0.982839 0.517943 0.010809 1.845815 1.098777 0.567160 0.419087 1.030585 1.503183 1.837046 1.638737 1.381290 1.657079 1.137100 1.564675 -0.040237 0.809480 0.832346 1.587671 -0.164235 1.557353 -0.318789 1.412269 1.419735 0.213834 0.923183 0.158106 0.606199 0.283874 -0.361272 1.495430 1.475886 0.334771 1.534489 0.873427 -0.175602 1.422400 0.168157 0.667278 1.332909 0.520912 0.514379 1.506377 1.240021 1.795506 1.354822 0.149370 0.097693 1.231885 1.499794 1.191816 0.402471 1.807112 1.364329 0.383172 1.438070 0.658534 1.737005 0.518886) ;; pp: 9.412639 (fv 0.000000 0.102641 0.679230 0.798388 0.598526 0.445036 1.682481 1.416478 1.010866 0.838753 0.518866 0.185140 -0.260801 1.643327 1.645133 1.587871 1.510095 1.367190 1.252764 1.075109 0.997402 1.226792 1.097666 1.109286 1.266675 1.142806 1.396415 1.366757 1.323435 -0.151657 0.110933 0.254314 0.125232 0.426419 0.874355 1.227943 1.386454 1.437438 0.183960 0.673205 0.896736 1.317085 1.421345 0.557215 0.650544 0.979705 1.599286 -0.027664 0.967924 1.389243 -0.027060 0.800953 1.098758 1.686133 0.493843 1.257456 0.105617 0.800125 0.006765 0.139250 1.353019 -0.059007 1.198209 0.066444 0.431719 1.470864 0.547882 1.294688 0.757592 1.690943 0.714913 1.735237 0.542409 1.804533 0.779629 -0.296056 1.090213 0.178123 1.832019 1.000948 -0.131923 1.161644 0.360890 0.065736 1.232224 0.792139 0.176636 1.688866 1.432871 0.734257 0.042563 1.592538 0.764029) ) ;;; 94 all -------------------------------------------------------------------------------- ; 9.6954 (vector 94 12.510846178591 (fv 0 0 0 1 1 1 0 1 0 0 1 1 0 0 1 1 0 1 1 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 1 1 1 1 1 0 0 1 0 0 1 1 1 1 0 1 0 0 0 1 1 1 0 0 0 1 0 0 1 0 1 0 0 0 1 0 0 1 0 0 1 0 1 0 0 0 0 0 0 0 1 0 0 1 1 1 1 0 1 0) 9.614457 (fv 0.000000 0.354827 0.986082 0.678218 0.074619 1.069713 1.084979 -0.010872 1.376391 1.050934 0.019873 0.645649 0.930266 1.023286 -0.324271 0.129791 1.399266 0.790347 1.024795 0.364675 1.268057 0.467841 0.596106 0.634764 0.920301 0.577212 1.246648 0.805833 -0.021659 -0.091918 0.865047 0.408442 1.292571 1.382486 -0.396633 1.688655 0.645075 1.689205 0.543001 -0.020503 1.556121 1.527556 1.671083 1.274725 1.683665 1.385648 1.434218 0.579921 1.533529 0.946387 1.280342 1.067943 -0.140266 0.061709 0.145137 0.716787 0.346453 1.817745 0.110851 1.072741 1.054881 1.191219 0.552352 1.218769 1.077324 -0.052815 -0.201076 1.253349 1.375788 0.845621 0.366991 0.916267 0.628985 1.420824 1.381120 0.247768 0.913794 -0.038130 1.360273 -0.162096 1.251116 1.166185 0.322598 1.024569 1.763375 0.466730 1.066807 0.067495 0.545386 1.308131 1.358919 0.937638 0.693078 0.195493) ;; 93+1 9.543681 #(0.000000 0.070784 0.635867 0.742637 0.475019 0.302813 1.825409 1.378229 1.077426 0.877718 0.610301 0.202771 -0.182277 1.673466 1.553357 1.494058 1.368050 1.336285 1.249015 1.094284 1.026782 1.245912 1.085605 1.018283 1.167850 1.013374 1.392524 1.418879 1.281568 -0.274841 -0.022454 0.129657 0.125509 0.504384 0.935744 1.276977 1.483975 1.477426 0.196761 0.675603 0.862408 1.192185 1.459380 0.549610 0.569998 1.001464 1.695499 0.066362 0.898853 1.281654 0.050116 0.806388 1.047653 1.730201 0.520253 1.351614 0.000078 1.010541 -0.167505 0.168460 1.307105 0.008313 1.198293 0.190292 0.394166 1.604739 0.575546 1.381303 0.832277 1.821709 0.813449 1.752392 0.618919 0.026374 0.880532 -0.283635 1.155422 0.216026 1.884068 1.144874 -0.171918 1.125849 0.302834 -0.082892 1.104687 0.762677 0.111766 1.593198 1.158618 0.738387 -0.017688 1.548369 0.670450 -0.209765) ) ;;; 95 all -------------------------------------------------------------------------------- ; 9.7468 (vector 95 12.431831359863 (fv 0 1 0 1 0 0 0 0 1 0 1 0 0 1 1 0 0 1 1 1 1 0 0 1 0 1 1 0 1 0 0 1 1 1 1 0 0 1 0 0 1 1 1 0 0 1 0 1 1 0 0 1 1 0 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 0 1 0 0 0 0 0 1 1 1 0 1 1 0 1 1 1 0 1 0 1 0 0 0 1 1) 9.594917 (fv 0.000000 1.389542 1.176101 1.128189 0.857825 0.606938 0.053944 1.193702 0.869053 0.060247 1.681618 -0.018030 0.093189 1.777775 1.314304 1.617940 0.848617 -0.108633 0.918764 1.157666 0.455570 1.631612 1.168101 0.785976 0.402697 1.470789 1.252874 0.702336 1.782377 1.673658 1.631189 1.349352 1.050241 0.712255 1.786745 0.232201 0.625268 1.043139 1.455512 1.195110 0.998337 0.283110 0.709026 0.841439 0.900171 1.560899 0.398341 0.605576 1.226269 0.101415 0.662630 -0.080073 0.123777 0.243381 0.746050 1.688701 0.805710 -0.417799 1.076341 1.138430 0.020724 1.738280 0.026371 0.359523 1.207908 0.092412 0.589896 1.141872 0.833369 1.211938 0.834700 0.366724 0.985159 0.093930 1.781990 0.844009 1.324575 1.222996 -0.119995 1.044915 0.191275 1.202233 0.891410 1.663012 1.114750 1.562345 -0.205599 1.605273 0.019367 1.356810 0.858474 1.006151 -0.416772 0.195895 1.774084) ) ;;; 96 all -------------------------------------------------------------------------------- ; 9.7980 (vector 96 12.586637130548 (fv 0 0 1 1 0 0 0 0 1 0 0 1 0 1 1 1 0 1 0 1 1 0 1 0 1 1 1 0 0 1 0 0 1 0 1 1 1 1 1 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0 1 1 1 0 0 0 1 1 0 1 1 0 1 1 1 0 1 1 0 0 1 1 0 1 1 1 1 0 0 0 0 1 1 1 1 0 1 0 0 1 1 1) 9.698754 (fv 0.000000 1.686945 0.467972 0.353719 0.039839 1.529803 1.113587 1.518769 0.069518 0.641616 0.744046 1.828910 0.013471 -0.229934 0.181085 -0.011815 0.130449 1.033538 1.435542 1.445735 1.524439 1.088117 0.632800 0.518998 -0.093855 1.447748 -0.258898 0.540666 0.708408 1.141240 0.388952 0.533151 0.107615 0.843908 1.797589 1.037747 1.105446 0.651000 0.775586 -0.512743 0.563193 0.707947 1.740714 1.753866 0.373300 1.459832 0.879332 1.133261 0.035182 1.481640 1.284446 0.744828 1.229402 -0.449568 1.081113 -0.235470 0.939023 1.698241 1.413068 -0.279150 0.681300 1.084041 -0.075079 0.087600 0.709157 -0.062761 0.870661 0.903931 0.019006 1.008038 -0.009901 1.442216 1.097881 0.558710 1.835109 1.151033 1.232982 1.137424 0.991349 -0.312466 0.156001 0.908045 0.922926 1.582365 1.057816 0.119723 1.368068 0.167350 -0.363438 0.279779 0.391520 0.751632 -0.048111 1.271729 1.046123 1.547668) ;; 95+1 9.726779 #(0.000000 1.272536 1.234689 1.036804 0.806804 0.685514 -0.233507 1.195648 0.974626 -0.133690 1.612184 -0.250031 0.153834 1.639158 1.448966 1.429020 0.841318 0.036800 0.809280 1.124317 0.410517 1.790247 0.947605 0.878411 0.284331 1.437808 1.242148 0.609187 1.691642 1.608067 1.542734 1.433245 1.048694 0.695483 1.770228 0.049652 0.565924 1.008807 1.378374 1.235802 0.944856 0.275648 0.688876 0.690791 0.947538 1.724048 0.507279 0.344409 1.011255 0.053102 0.655524 0.015954 -0.000803 0.135128 0.906712 1.703603 0.898426 -0.371698 1.225250 0.634585 -0.033241 1.655363 -0.118205 0.384853 1.242318 0.157876 0.169651 1.065989 0.596048 1.102812 0.663038 0.195163 0.860121 -0.157778 1.681909 0.740009 1.139644 0.978398 -0.218097 0.770242 0.520081 1.060101 0.721838 1.327594 1.028501 1.403966 -0.169752 1.470700 0.038544 1.145229 0.628698 0.803002 -0.539861 0.036303 1.343341 -0.219240) ) ;;; 97 all -------------------------------------------------------------------------------- ; 9.8489 (vector 97 12.585 (fv 0 1 0 1 1 1 0 0 0 0 1 0 1 0 0 0 1 1 0 1 0 0 1 0 0 0 1 1 1 1 0 0 1 1 1 1 0 1 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 1 0 0 1 1 0 1 0 1 1 0 0 1 1 0 0 1 0 0 0 1 1 1 1 1 0 1 0 0 0 1 1 1 0 1 1 0 1) 9.811290 (fv 0.000000 1.599348 0.923331 0.142353 1.275817 1.382624 1.510378 0.732924 0.806532 1.015499 0.620826 1.882699 1.212790 0.807183 -0.023255 1.516389 1.732605 -0.201884 -0.277404 -0.055883 0.240940 0.731931 1.673522 0.086425 1.587574 0.602365 1.160815 1.229056 1.456929 0.833735 0.852700 0.201630 1.357627 0.458255 0.370269 1.445354 0.215612 1.445930 1.140683 1.395090 0.893305 1.761792 0.069580 1.477150 1.261329 0.799176 -0.171506 -0.046281 0.037534 0.945505 0.457403 -0.446133 -0.016772 1.686139 0.929506 1.761163 1.283945 0.714187 0.030687 1.699690 1.935312 -0.149630 1.586492 0.783961 1.445990 1.058255 1.383027 0.027818 1.949317 0.450708 0.615659 0.863171 1.311974 0.506328 0.888408 1.633309 0.234089 1.362300 1.207491 0.660429 0.454914 0.801172 1.438508 0.392994 1.045451 0.178268 0.808166 0.169353 0.379391 0.545139 1.796419 0.579129 1.221213 0.829753 -0.091400 0.706540 1.245414) ;; pp: 9.860243 (fv 0.000000 0.680977 0.966253 1.634215 0.365093 0.771173 1.259550 0.007495 0.693755 1.428280 0.352398 1.032784 1.549276 0.384182 1.088250 1.711305 0.715748 1.441436 0.402491 1.285065 0.056701 0.943326 1.812606 1.043581 -0.072780 0.808810 1.940683 1.225707 -0.029466 1.139541 0.383446 1.652614 0.799608 1.845091 0.834727 0.161218 1.415263 0.601512 1.879909 1.404443 0.587018 1.806810 1.169986 0.643827 -0.082912 1.345651 0.782502 0.239840 1.583476 1.376880 0.682406 0.262024 1.847899 1.521309 1.138292 0.467250 0.281908 -0.070976 1.718683 1.523340 1.285749 0.765922 0.681731 0.268165 0.290564 0.046020 0.082000 1.791305 1.766394 1.373062 1.769852 1.419717 1.707739 1.313906 1.401690 1.527792 1.718640 1.280023 1.582817 1.850590 0.103668 0.041251 0.363022 0.586729 0.741602 0.886403 0.989519 1.522393 1.709847 0.193187 0.406948 0.736802 1.329603 1.619101 -0.034816 0.612167 1.088037) ;; 98-1 9.733625 #(0.000000 -0.316389 0.763514 1.085136 -0.007054 1.613164 0.368355 0.497362 0.266819 0.792626 1.605095 0.379462 0.795808 0.617439 0.340832 1.408797 0.884588 0.777692 -0.061819 1.329857 1.611199 0.024913 1.778069 1.061965 1.317076 1.286538 -0.063928 0.439816 1.190286 1.720423 -0.281159 0.284236 1.261293 1.715607 1.258044 1.027201 0.992940 1.404704 0.918469 0.571955 0.670954 -0.578424 1.681045 1.759567 -0.365702 0.685884 0.480691 0.685380 0.103522 0.029224 1.512644 0.122325 0.600548 0.070986 0.493468 0.652824 -0.059890 1.290005 1.370566 0.135509 0.143591 -0.197126 0.478025 0.315521 0.839450 0.083388 0.553358 1.161959 0.770340 1.132488 0.641596 1.702281 0.277494 1.930557 0.772636 0.175945 1.352904 0.123527 1.448091 0.194310 0.330488 1.631688 1.302741 0.566332 1.521760 0.740046 0.257004 1.532435 0.681554 0.238673 0.612205 0.128510 1.851063 0.280067 1.237302 -0.034034 0.240185) ) ;;; 98 all -------------------------------------------------------------------------------- ; 9.8995 (vector 98 12.724907890996 (fv 0 0 1 0 1 1 0 0 0 0 1 1 1 1 0 0 0 1 1 0 1 0 0 0 1 0 1 1 0 1 1 0 1 0 1 0 1 0 1 1 0 0 0 1 1 0 0 0 1 1 0 0 0 0 0 1 0 0 0 1 0 0 1 1 0 0 1 0 0 0 1 0 1 1 1 1 1 0 0 1 0 0 0 0 0 0 0 1 0 0 1 0 1 0 0 1 1 1) 9.767029 (fv 0.000000 -0.188323 0.675144 1.162326 -0.152620 1.669640 0.370125 0.494628 0.190555 0.715197 1.719005 0.377693 1.013961 0.545798 0.345914 1.535759 0.968261 0.937780 -0.119329 1.630311 1.635898 0.029531 1.850111 1.208612 1.298337 1.226547 0.020306 0.388794 1.210462 1.649716 -0.158605 0.268380 1.285081 1.672163 1.145021 0.908520 1.140268 1.468740 0.844848 0.440912 0.760836 -0.415872 1.889804 1.724959 -0.229249 0.766901 0.564605 0.613211 0.221081 -0.012880 1.521722 -0.044019 0.593078 0.034669 0.491432 0.559669 -0.045684 1.255880 1.344088 0.070215 0.282883 -0.229690 0.625053 0.504422 0.811212 -0.012186 0.589513 1.241057 0.831526 1.215774 0.684110 1.651422 0.305036 1.891476 0.747710 0.040696 1.539490 0.154881 1.456564 0.357589 0.123799 1.523900 1.179657 0.504889 1.418226 0.850462 0.009923 1.481216 0.600938 0.216302 0.543002 0.255145 1.787452 0.279328 1.172852 -0.085076 0.199219 1.196556) ) ;;; 99 all -------------------------------------------------------------------------------- ; 9.9499 (vector 99 13.002375571256 (fv 0 1 1 0 1 1 0 1 1 0 0 1 0 1 0 1 1 1 0 0 1 1 0 1 0 1 0 1 0 0 1 1 1 1 1 0 1 1 0 0 0 1 0 0 1 1 0 0 0 0 0 1 0 1 0 0 0 1 0 0 1 0 1 0 1 1 0 0 1 1 1 1 0 0 0 0 0 0 0 1 0 0 1 0 1 0 0 1 0 0 0 1 1 1 0 1 0 0 0) 9.856524 (fv 0.000000 0.532142 1.131528 0.051928 1.654946 0.271228 1.101349 1.560647 1.619023 1.108572 0.726033 0.727251 -0.132854 0.360041 0.670224 1.663602 -0.493942 -0.197685 1.604359 1.799803 1.040897 0.122580 0.382051 1.681979 0.430500 1.558581 0.044836 1.543992 1.439831 0.906809 1.334494 1.667502 1.130520 0.467062 1.310080 0.675817 0.797910 0.443927 1.274100 0.336343 0.146059 -0.192316 0.742563 0.471697 1.596436 -0.009686 1.651640 1.837904 0.406037 0.558091 -0.016989 1.479179 0.903735 1.116299 -0.060825 0.179513 -0.026846 1.811414 0.072416 -0.014783 0.060148 0.361427 1.207468 0.945662 0.068194 1.516887 0.004488 0.212016 0.737847 -0.343051 0.746533 0.527238 1.812564 0.462282 1.376985 0.882738 1.070840 1.718397 0.663551 0.922534 1.724192 -0.576637 1.416748 1.206588 0.385428 0.383601 1.504489 1.636715 0.253055 1.809058 0.862228 1.855156 1.029803 0.604391 1.515278 0.827373 1.237016 1.652558 1.330582) ;; 100-1 9.837088 #(0.000000 0.501632 0.934877 -0.406945 1.720666 0.060221 0.986624 1.296415 1.868188 0.930965 0.372307 0.709017 -0.252505 0.160880 0.812384 1.543611 -0.433820 -0.259337 1.687543 1.624404 0.816138 0.040401 0.111607 -0.236070 0.269290 1.314408 0.264913 1.524076 1.510591 0.672939 1.225301 1.486867 1.198432 0.684715 1.400436 0.809536 0.790904 0.226400 1.325157 0.378418 0.148020 -0.182631 0.691385 0.400855 1.875888 -0.034659 1.584706 0.098304 0.424031 0.680276 -0.260219 1.393931 1.457882 1.172138 0.294071 0.176446 -0.047801 -0.268365 -0.154114 0.172473 0.026218 0.381410 0.486670 0.694651 0.137283 1.339580 -0.408431 0.346779 0.297247 -0.681534 0.303276 0.742358 1.426415 0.456204 1.180942 0.678579 1.815369 1.742844 0.288364 0.833505 1.638509 -0.777919 1.367299 1.067232 -0.002137 0.375276 1.602540 1.654913 0.141825 1.294416 0.790392 1.752947 1.096531 0.330167 1.510639 0.495286 1.348117 1.506107 1.279426) 9.827383 #(0.000000 0.489851 0.987809 -0.394189 1.760605 0.036969 0.958351 1.266375 1.844806 0.928905 0.347370 0.708814 -0.213250 0.135838 0.840288 1.524164 -0.453078 -0.222429 1.664862 1.650792 0.843217 0.096982 0.106278 -0.254905 0.311964 1.356301 0.208474 1.484260 1.533307 0.693746 1.221284 1.494648 1.192154 0.704448 1.399404 0.773577 0.730819 0.230112 1.305343 0.384931 0.092126 -0.177018 0.678108 0.424573 1.876518 -0.110628 1.580149 0.105746 0.460598 0.667046 -0.301428 1.430147 1.462027 1.200592 0.294468 0.132684 -0.034510 -0.232945 -0.131872 0.235724 -0.003826 0.390220 0.478949 0.708773 0.158613 1.284193 -0.406418 0.372748 0.269091 -0.683069 0.298317 0.742905 1.467502 0.490499 1.200844 0.658586 1.777690 1.768714 0.250192 0.808599 1.653844 -0.705600 1.331238 1.087732 0.038158 0.351212 1.574369 1.702783 0.145504 1.240857 0.779939 1.689313 1.071204 0.299434 1.500921 0.518280 1.343637 1.492826 1.331082) ) ;;; 100 all -------------------------------------------------------------------------------- ; 10 (vector 100 12.998435541498 (fv 0 1 1 0 1 0 1 0 0 1 0 0 0 0 1 1 0 1 0 0 1 1 1 1 1 0 0 1 0 0 1 1 1 1 1 0 1 0 1 0 0 0 1 0 1 1 0 1 0 1 0 1 1 1 0 1 1 0 0 0 0 0 1 1 1 1 0 1 0 1 1 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0 0 1 1 1 0 0 0 1 0 0 0 0) 9.934540 (fv 0.000000 -0.003002 1.124858 1.923310 1.313585 0.903273 0.269057 1.550768 -0.053877 1.309350 0.259003 0.111356 1.649851 -0.475532 0.829676 0.358899 1.751244 0.579333 0.816025 0.729724 0.670859 0.992375 1.547721 -0.006147 1.191599 -0.084864 -0.001041 0.113001 0.580223 -0.405864 1.746923 1.268810 1.705215 1.056469 -0.197189 1.293674 0.934396 0.701720 0.582761 1.455750 1.232104 0.066182 1.464245 1.672004 0.239530 1.711330 -0.092878 0.399845 1.787310 0.046607 0.724822 1.735381 1.288901 0.460956 0.591963 0.996187 1.917259 0.311027 0.319804 1.898631 1.336795 0.632408 0.203462 1.031863 1.346167 0.931351 0.938341 -0.021240 0.003608 0.259606 1.507194 1.470684 0.324860 1.386425 0.298636 1.353945 1.922770 1.226486 0.467967 1.127400 0.946778 1.636808 0.285401 1.555027 1.572734 1.271086 1.042408 1.022431 1.651957 1.039348 0.338431 0.852870 0.945331 1.308135 1.631151 1.286426 0.091020 0.620928 0.894381 1.712980) ;; 99+1 9.840430 #(0.000000 0.622605 0.940347 -0.023879 1.823374 0.046101 0.987386 1.386868 1.714786 1.047746 0.546094 0.770951 -0.265661 0.292412 0.888118 1.675189 -0.427745 -0.167443 1.762203 1.576180 0.923298 0.110300 0.331275 1.952651 0.241655 1.589880 0.276846 1.519665 1.333705 0.834984 1.249804 1.700983 1.188281 0.627881 1.352135 0.781883 0.873102 0.286686 1.236704 0.305170 0.118608 -0.061299 0.746712 0.436256 1.850021 0.025967 1.523851 0.111789 0.590538 0.644667 -0.043430 1.449342 1.285442 1.251443 0.387240 0.168668 -0.008131 -0.077897 -0.090554 0.128941 0.292252 0.590066 0.910912 0.845002 0.114157 1.267409 -0.143231 0.405284 0.467262 -0.510143 0.597548 0.663042 1.615835 0.378343 1.456219 0.634771 1.512841 1.710315 0.498665 0.804929 1.545845 -0.422582 1.525481 1.254165 0.184553 0.563406 1.423281 1.785321 0.228158 1.573508 0.775481 1.683423 1.226447 0.381675 1.467512 0.862051 1.538318 1.641940 1.350297 0.135931) 9.835590 #(0.000000 0.570539 0.883467 -0.014746 1.809284 0.037164 0.942356 1.400420 1.689848 1.054845 0.548531 0.724602 -0.281675 0.241599 0.863477 1.691280 -0.386312 -0.167207 1.712242 1.554897 0.916947 0.154344 0.337144 -0.027896 0.191502 1.562234 0.293369 1.468239 1.368021 0.858183 1.215102 1.710412 1.168343 0.641872 1.384374 0.758703 0.847326 0.232955 1.203009 0.285135 0.164856 0.006319 0.731916 0.364606 1.825894 0.043345 1.457606 0.099304 0.693634 0.599315 -0.080515 1.358403 1.276512 1.306804 0.350411 0.153823 -0.066078 -0.056199 -0.130700 0.138204 0.313702 0.671650 0.858922 0.893029 0.081041 1.207722 -0.186661 0.401736 0.459231 -0.571478 0.607326 0.634928 1.590455 0.322847 1.466431 0.635387 1.523516 1.640986 0.518971 0.735455 1.517620 -0.440561 1.538277 1.209947 0.169421 0.568757 1.501995 1.704851 0.248785 1.539090 0.803108 1.622622 1.319362 0.357166 1.483707 0.858733 1.549787 1.667959 1.355314 0.166782) 9.828147 #(0.000000 0.606381 0.917097 -0.052963 1.840850 0.076195 1.000382 1.379573 1.713959 1.056049 0.567183 0.755185 -0.243029 0.240141 0.901208 1.696896 -0.401067 -0.172213 1.702278 1.572589 0.995369 0.092107 0.339155 -0.047255 0.209942 1.548195 0.250627 1.493833 1.397582 0.850788 1.234138 1.694866 1.205737 0.609514 1.413541 0.774375 0.843373 0.256747 1.182652 0.287452 0.151651 -0.040175 0.718613 0.370108 1.797287 0.037564 1.483372 0.063366 0.673221 0.647681 -0.130882 1.410330 1.289134 1.259368 0.378589 0.179096 -0.077706 -0.126123 -0.197835 0.087734 0.222460 0.660561 0.798643 0.833272 0.064575 1.260850 -0.205610 0.363184 0.404543 -0.579680 0.559469 0.652793 1.526709 0.333879 1.432283 0.642498 1.543163 1.637538 0.499172 0.795803 1.495177 -0.493071 1.544279 1.224387 0.125780 0.527014 1.451448 1.716932 0.232752 1.503302 0.799684 1.669661 1.257116 0.363202 1.442143 0.833946 1.525977 1.616490 1.388269 0.088027) ) ;;; 101 all -------------------------------------------------------------------------------- ; 10.0499 (vector 101 13.219774246216 (fv 0 0 1 1 0 0 0 1 1 1 1 0 1 1 0 0 1 1 1 0 0 0 0 1 1 0 1 0 1 1 0 0 1 0 0 1 1 1 1 1 1 1 0 0 0 1 0 0 1 1 1 1 0 0 1 1 1 1 0 1 1 1 0 1 0 0 0 1 1 0 1 0 1 0 1 0 0 1 1 0 0 1 0 1 1 1 1 0 0 1 0 1 0 0 0 1 0 0 1 0 0) ;; pp.scm: 9.969423 (fv 0.000000 0.594013 1.021081 1.737097 -0.040619 0.752674 1.481517 0.041655 0.616216 1.273976 -0.239494 0.706555 1.350693 0.121717 0.873486 1.615554 0.502899 0.859104 0.100209 1.240389 0.001564 0.940100 -0.110501 0.399212 1.639677 0.823186 1.849867 0.970964 1.815596 0.977295 1.876945 1.029064 0.250663 1.106062 0.440754 1.692440 0.937531 0.143047 1.343876 0.363444 1.897361 0.954251 0.489534 1.687124 1.352147 0.540407 -0.261830 1.349441 0.704373 0.447495 1.734922 1.090380 0.653989 0.307022 1.449780 1.794904 0.808626 0.497093 0.423383 -0.280469 1.640122 1.217125 1.143712 0.677390 0.472908 0.243924 0.123084 -0.178887 1.588534 1.317289 1.403860 1.454850 1.459048 1.165832 1.237401 1.000847 1.421104 1.051039 1.364625 1.447050 1.541757 1.176845 1.530906 1.723380 1.795645 0.095341 0.481918 0.307978 0.454615 1.009308 0.963604 1.200422 1.757436 -0.015019 0.420112 1.020994 1.127410 1.866034 -0.291409 0.497289 1.096855) ;; 100+1 9.935434 #(0.000000 0.608940 0.851264 -0.183247 1.727138 0.122260 0.917387 1.478656 1.680087 0.974509 0.439323 0.791848 -0.400157 0.270939 0.826559 1.771349 -0.433691 -0.112515 1.672261 1.661638 0.947155 -0.005681 0.389466 0.024556 0.225657 1.489635 0.270053 1.524879 1.478658 0.920158 1.189636 1.632789 1.150797 0.730326 1.420509 0.804787 0.804256 0.161800 1.160606 0.404414 0.173309 -0.015766 0.808661 0.387616 1.832938 0.006849 1.436327 0.251026 0.730578 0.634439 -0.102483 1.314743 1.381684 1.164318 0.424834 0.251180 -0.031006 -0.152152 -0.160917 -0.051668 0.286561 0.725355 0.786811 0.879068 0.251667 1.304955 -0.186646 0.532400 0.492416 -0.418753 0.613717 0.827376 1.513960 0.266304 1.474733 0.648266 1.615446 1.681220 0.455322 0.845513 1.730307 -0.669948 1.389624 1.537351 0.147023 0.449375 1.548892 1.696954 0.063719 1.612335 0.578406 1.747879 1.363473 0.348630 1.578073 0.726784 1.512834 1.528359 1.464039 0.047404 0.063700) ) ;;; 102 all -------------------------------------------------------------------------------- ; 10.0995 (vector 102 13.194128990173 (fv 0 0 1 1 1 0 0 0 1 0 0 1 1 1 1 0 1 0 0 1 0 0 1 1 1 0 0 0 1 1 1 0 1 0 1 0 1 1 0 1 0 1 1 0 0 0 1 0 0 1 0 0 1 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 1 1 0 0 1 1 0 1 1 0 1 1 1 1 0 1 0 0 1 0 1 0 1 0 1 0 0 0) 10.088316 (fv 0.000000 0.095626 0.514266 0.420449 0.749499 0.992394 -0.193393 0.039052 0.057117 1.575374 1.352773 1.322452 0.794003 0.750383 0.756593 0.273089 1.675537 0.407815 0.550801 -0.538502 0.957909 1.336960 1.614983 0.508708 1.910222 1.874209 0.940387 0.222605 0.538045 1.356000 1.741919 0.598382 1.550605 1.131133 0.773140 -0.232481 0.055269 1.822145 0.659426 -0.100655 1.261624 0.557410 0.214081 0.588453 0.458097 0.577319 1.055339 1.792023 0.525700 0.097434 0.222735 0.356704 1.885210 0.037676 0.938171 0.984298 1.949046 1.455206 0.941409 1.068679 0.637889 0.330852 0.138031 1.619860 0.674126 -0.251106 1.183963 1.959835 0.213213 0.066073 0.132459 0.329261 0.847485 0.503486 0.122913 0.684764 1.979054 0.659531 0.231782 1.341252 0.124898 0.707447 -0.419234 0.913042 1.413830 0.741236 1.664719 1.833486 -0.410776 0.347702 1.045974 -0.368342 0.123701 1.012180 1.052039 1.226053 0.364036 1.015550 1.423284 1.022491 0.770674 1.877516) ;; pp: 10.025038 (fv 0.000000 0.605553 0.983049 1.667341 0.280594 0.813730 1.347579 0.067151 0.773566 1.170135 -0.000437 0.776577 1.339736 0.097477 0.851330 1.565309 0.392180 1.136191 -0.027326 0.943192 1.737718 0.813011 1.699444 0.599876 1.617440 0.776150 1.855177 0.961431 1.915827 0.882986 1.666203 0.596064 -0.104064 1.326950 0.560052 1.687567 0.667080 1.807593 1.118197 0.382149 1.651756 0.780071 0.152645 1.439416 0.767927 0.282152 1.693680 1.210781 0.759553 0.009785 1.134002 0.817236 0.333315 0.071267 1.596603 1.242164 0.957402 0.421360 -0.130961 1.394848 1.288611 0.865712 0.865151 0.398958 0.298422 -0.229411 1.889300 1.384404 1.672436 1.144983 1.294122 0.887806 0.874167 0.414036 1.058747 0.759420 0.922388 0.730377 0.900207 0.658168 0.691340 0.678324 0.551776 0.884009 1.344859 1.136367 1.415423 1.606731 1.827838 -0.020510 0.115669 0.332208 0.674134 1.028023 1.276947 1.696675 0.283199 0.564387 1.040113 1.365277 -0.292333 0.240887) ;; 100+2 10.007699 #(0.000000 0.699259 0.886512 -0.027935 1.951661 0.038656 0.782145 1.495632 1.825902 1.099844 0.475719 1.085184 -0.119480 0.345084 0.668327 1.655215 -0.443184 -0.222547 1.620205 1.430704 0.954443 0.138630 0.492113 0.019065 0.360482 1.757422 0.157902 1.550392 1.470306 0.988675 1.229630 1.690004 1.105453 0.565169 1.377624 0.841390 0.797989 0.376013 1.289740 0.395261 0.327620 0.083381 0.811382 0.494890 1.711550 0.206485 1.428555 0.082286 0.761093 0.622976 0.077603 1.537629 1.287362 1.146947 0.366315 0.298958 -0.023089 -0.278375 -0.121615 0.126454 0.360907 0.413437 0.811052 0.779664 0.308170 1.185116 -0.261499 0.353036 0.563752 -0.254871 0.625520 0.581032 1.603887 0.363229 1.270011 0.973174 1.589594 1.789366 0.533330 0.642520 1.506401 -0.681000 1.607118 1.357272 0.089328 0.463060 1.308512 1.901050 0.296922 1.480369 0.840448 1.959389 1.137022 0.183179 1.512091 0.749846 1.564567 1.660530 1.343282 0.039704 0.123170 -0.256915) ) ;;; 103 all -------------------------------------------------------------------------------- ; 10.1489 (vector 103 13.435972213745 (fv 0 1 1 0 0 1 0 0 1 1 0 0 1 0 0 0 1 0 1 1 0 1 1 1 1 1 1 1 0 1 0 0 0 0 0 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 1 0 0 0 0 0 1 1 1 0 1 0 0 0 0 1 0 0 0 1 1 0 0 0 1 0 1 0 0 1 1 1 0 1 0 0 1 0 1 1 0 1 1 0 0 1 0 1) 10.072606 (fv 0.000000 0.775992 0.789071 0.551328 0.298530 -0.168268 0.810417 1.541024 0.478641 0.826848 0.407673 0.769783 0.052469 0.071330 0.252339 -0.003477 1.565238 1.042251 1.681717 0.063581 0.058867 1.442741 0.917343 1.448313 1.294486 -0.061724 0.478951 1.132882 1.128620 1.082449 0.123678 0.578486 1.003285 0.918654 0.241363 0.278868 -0.414912 1.418211 0.927244 1.134797 0.489863 -0.664481 0.529310 0.940119 1.393533 0.416277 0.044802 1.197865 0.283028 1.514978 1.590639 1.159829 1.236485 1.237279 0.109313 1.090962 1.341243 0.602478 1.179629 0.285726 1.482652 0.648833 1.308230 1.743441 1.346535 0.727031 0.061582 0.907076 -0.185896 1.479865 0.775766 1.389852 -0.161651 1.518832 0.594834 0.022777 -0.099476 0.851631 0.289254 1.413652 0.958286 -0.309988 0.125895 0.222920 0.633318 0.584266 0.503924 0.660246 1.182087 1.319466 1.213616 1.220516 0.662413 1.589230 0.875855 1.466144 0.036061 0.139801 0.986962 0.226038 0.202950 0.978447 0.999923) 10.023934 #(0.000000 0.753951 0.779673 0.518393 0.316206 -0.218083 0.870139 1.504736 0.508331 0.809688 0.422025 0.773554 0.037541 0.011964 0.304036 -0.003721 1.596496 1.002801 1.709587 -0.064057 -0.025768 1.445605 0.900990 1.377053 1.302865 -0.071628 0.443866 1.140251 1.156707 1.055832 0.196967 0.522965 0.962707 0.915851 0.186338 0.326806 -0.419425 1.382164 0.924290 1.127505 0.506077 -0.717365 0.490628 0.923836 1.311668 0.417410 -0.037217 1.246121 0.223044 1.428120 1.587827 1.073312 1.216073 1.312023 0.011344 1.054200 1.272110 0.513048 1.232588 0.290590 1.484043 0.603027 1.228594 1.651785 1.264921 0.718395 0.081981 0.874691 -0.108206 1.415361 0.782165 1.369202 -0.230282 1.487595 0.594625 -0.026402 -0.131347 0.854028 0.304794 1.364105 0.950801 -0.275135 0.155865 0.133819 0.584290 0.570116 0.430581 0.629602 1.186517 1.300988 1.131914 1.156254 0.652711 1.526271 0.724500 1.498674 -0.060166 0.161032 0.948319 0.277002 0.145951 0.963056 1.070311) ) ;;; 104 all -------------------------------------------------------------------------------- ; 10.1980 (vector 104 13.330215043333 (fv 0 1 1 1 1 1 0 0 1 1 1 1 0 1 0 0 0 0 0 0 0 1 0 0 0 0 1 1 0 1 1 0 1 0 1 1 0 0 0 1 1 1 0 0 1 1 1 1 0 1 0 1 1 1 1 1 1 0 0 0 1 1 1 1 0 0 1 0 1 1 0 1 0 1 0 1 0 1 0 0 0 1 0 0 1 1 1 0 1 1 0 1 0 1 0 1 1 0 1 1 1 1 1 0) 10.124244 (fv 0.000000 1.622675 1.706946 0.969141 1.395974 1.097698 0.150298 1.207570 1.449278 0.836769 1.526696 -0.147627 1.089028 1.314193 0.833408 0.265551 0.958522 0.397626 0.447242 0.837858 1.676927 0.883730 1.604731 0.779720 0.388122 0.713835 1.704244 0.052983 0.837107 0.054588 0.549459 0.093126 1.768139 0.144405 0.937970 0.532416 -0.149569 1.622840 1.586484 0.686471 0.830291 0.095651 0.908595 0.259853 -0.301519 0.855324 -0.014912 0.748872 1.538644 -0.030037 0.020462 0.792578 0.531283 0.625746 0.346250 0.434570 0.703831 1.586850 1.489275 1.435865 0.300417 1.125540 0.355002 0.123270 0.728375 0.039493 1.718698 1.307117 0.118823 0.358408 0.405752 1.413026 1.454448 0.630369 0.900592 1.792896 1.090807 1.061221 1.814531 1.630768 0.510555 0.618481 1.214968 0.122072 0.455822 1.727623 0.073245 -0.177442 0.329678 1.542732 1.673278 -0.469931 -0.007785 0.142142 0.231493 0.623628 0.711468 0.673585 0.185009 1.333716 0.659875 0.472080 1.635059 0.745116) ;; 103+1 10.275285 #(0.000000 0.766045 0.758318 0.527263 0.297602 -0.220660 0.843254 1.514408 0.485353 0.812135 0.348878 0.775197 0.047879 0.029543 0.283642 0.002716 1.604201 1.035276 1.656724 -0.040752 0.022899 1.491112 0.898813 1.356951 1.324619 -0.033929 0.459965 1.111102 1.133048 1.011882 0.204025 0.504974 0.921280 0.802500 0.220289 0.307291 -0.400054 1.435114 0.877954 1.160776 0.500458 -0.700012 0.491131 0.918641 1.205216 0.410209 0.061124 1.219224 0.201639 1.418580 1.569885 1.076223 1.149827 1.271335 0.104510 1.096467 1.299860 0.536464 1.174176 0.267049 1.435559 0.590482 1.183704 1.667286 1.299866 0.752687 0.061344 0.872137 -0.023202 1.396793 0.800897 1.378479 -0.284533 1.542592 0.617940 -0.056150 -0.076140 0.860473 0.211375 1.366917 1.010531 -0.227839 0.171693 0.186622 0.600417 0.530929 0.483380 0.644987 1.142519 1.358336 1.101883 1.125957 0.647607 1.571711 0.728839 1.592844 -0.003107 0.163651 0.931816 0.281116 0.161282 0.950629 1.042875 -0.059815) ) ;;; 105 all -------------------------------------------------------------------------------- ; 10.2470 (vector 105 13.595993876506 (fv 0 1 0 0 1 1 0 0 1 1 0 1 0 1 0 1 1 1 0 1 1 0 1 1 0 0 1 0 1 0 0 0 0 1 0 1 1 1 0 0 0 1 0 1 1 1 0 0 1 0 0 0 1 0 1 1 1 1 0 1 1 0 1 0 1 0 1 1 1 1 1 1 0 1 1 0 1 1 1 1 1 0 1 1 0 1 0 0 0 1 1 0 0 1 1 1 0 0 1 1 1 0 0 1 0) 10.169606 (fv 0.000000 0.591462 0.235800 1.321672 1.356594 -0.405542 0.538022 0.615762 0.326243 1.062550 -0.153260 -0.031444 1.233243 1.770308 1.085997 1.514420 0.095655 1.000755 -0.065552 -0.053493 1.481942 0.777394 0.483679 1.419470 0.159850 -0.259703 0.126983 0.478035 1.178492 1.111834 1.075738 1.268063 0.962249 1.943997 1.083333 1.538989 0.307093 1.387414 1.941208 1.284189 -0.012780 1.356158 1.317824 1.095171 0.472030 0.459214 1.096373 0.477967 0.565821 1.566421 0.590639 1.381435 1.150189 0.197776 0.315906 0.587160 0.629501 0.853485 0.797405 -0.187739 1.489470 1.296970 0.273664 0.102171 1.749652 1.601370 1.902817 1.658081 0.403983 0.138955 1.356476 1.693746 1.125750 0.916183 1.246086 0.386904 -0.248158 0.148664 0.070783 0.819794 -0.019914 0.547099 0.323707 -0.046514 1.635194 0.435105 0.156523 0.390396 -0.277746 0.665321 0.200546 1.082837 1.059380 -0.041536 0.592565 0.634526 1.116414 0.039718 0.575393 -0.178156 1.655927 0.370318 0.615340 1.693958 1.282592) ) ;;; 106 all -------------------------------------------------------------------------------- ; 10.2956 (vector 106 13.200031373463 (fv 0 0 1 0 1 0 0 1 0 0 0 1 1 0 0 1 0 0 1 0 1 0 0 1 0 0 0 0 1 0 0 1 0 1 1 1 0 1 0 1 1 1 1 0 0 0 0 1 0 1 1 1 1 1 1 1 1 1 0 0 1 0 1 0 1 1 1 0 0 1 0 0 0 0 0 1 1 0 0 1 0 1 1 0 0 1 1 1 1 1 1 0 0 1 1 0 1 1 0 0 0 0 0 1 0 1) 10.233770 (fv 0.000000 0.055119 -0.050942 1.221658 1.069634 0.969833 -0.120088 0.537260 0.774846 1.097793 1.607343 1.125046 1.248849 0.110938 0.000911 -0.176700 1.224234 0.974172 0.258380 0.044520 0.328839 0.706861 1.491508 0.262253 0.850888 0.129635 0.528138 0.085967 1.206179 1.203105 -0.212392 0.552998 1.277370 0.069273 1.300991 0.395491 0.052184 1.017350 -0.139116 0.060719 1.223876 0.765705 1.643712 0.809882 1.480192 -0.160266 1.133315 0.396498 1.706614 0.389700 1.530945 1.033706 0.669577 0.953867 0.549025 0.735362 1.230749 1.732990 0.576594 1.599366 0.250495 1.206074 1.016404 1.623424 1.318513 0.223760 1.354914 1.140942 0.138240 0.414002 0.134404 1.756706 -0.015032 -0.196090 0.317193 0.119056 -0.492220 1.081019 0.025882 -0.092539 1.764132 1.357709 0.458311 1.060374 1.019483 -0.126097 0.259596 0.137076 0.020444 0.418031 0.040745 0.523959 1.133024 0.593829 1.429205 1.802013 0.365195 0.248492 1.498863 -0.344913 0.359725 1.657142 1.374238 1.289802 -0.217105 1.333949) ) ;;; 107 all -------------------------------------------------------------------------------- ; 10.3441 (vector 107 13.224366750161 (fv 0 1 0 1 1 1 0 0 1 1 0 1 1 0 0 1 1 0 0 1 1 0 1 0 1 1 1 0 0 0 1 0 0 1 0 0 0 1 0 1 0 0 1 0 1 1 0 1 1 0 0 1 1 0 1 0 1 1 0 0 1 0 1 0 0 0 1 1 1 0 1 0 1 1 0 1 1 1 1 1 1 0 1 0 1 1 1 1 0 1 0 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1) 10.273899 (fv 0.000000 1.285870 0.722685 1.695642 1.789973 0.495199 0.001511 0.648393 1.565696 0.756830 0.421656 -0.184836 0.187469 1.381401 1.501800 0.551266 1.079110 0.129360 0.283265 1.059394 -0.217105 1.758613 1.156467 0.305791 0.018881 1.709795 1.386465 1.716357 0.543922 -0.077767 0.376814 1.917356 1.703183 0.375846 1.314995 1.049255 -0.015490 1.182770 0.105614 1.125738 1.580574 0.196175 0.043631 0.176951 1.523484 1.504279 0.024743 0.233174 0.051990 0.885176 0.485127 0.978870 1.366279 1.841166 1.225239 0.599047 0.937430 1.422432 0.950869 1.195765 0.360876 1.187450 1.491233 0.274262 0.123358 1.276789 1.498182 1.151090 1.495794 1.385360 0.511524 1.320969 1.040843 1.323508 0.526850 1.486006 0.358172 -0.084804 0.784722 0.263761 0.033435 1.669885 0.179635 1.097636 0.771172 0.674320 0.095788 1.426496 1.763465 0.078301 1.972016 1.520526 1.431005 0.272982 0.550020 1.118797 -0.453975 1.686563 1.286924 1.481496 1.458102 0.550556 0.115818 1.002355 0.493193 0.718245 1.621218) ) ;;; 108 all -------------------------------------------------------------------------------- ; 10.3923 (vector 108 13.534 (fv 0 1 1 0 0 0 0 1 0 1 0 0 1 1 0 1 1 1 0 1 1 0 0 0 0 1 0 1 0 0 0 1 0 1 0 0 1 0 1 0 1 1 0 0 1 1 0 1 1 0 1 0 0 1 0 0 0 0 0 1 1 1 0 0 0 1 0 0 0 0 0 1 1 0 1 1 1 0 1 0 1 1 1 0 0 0 0 1 1 1 1 1 1 0 0 1 0 1 1 0 1 0 1 0 0 0 0 1) 10.312988 (fv 0.000000 1.293654 0.754043 1.806542 1.109001 0.766775 1.436021 1.627340 0.528605 1.806494 1.181378 0.013554 0.353388 0.092480 0.431618 0.200495 0.904126 0.741464 0.675051 -0.110957 1.146773 1.810641 0.552983 0.275055 0.835876 1.123930 -0.182193 -0.339155 0.645146 0.163632 0.868047 1.269556 0.830686 1.219557 1.665806 1.060039 1.944315 -0.011848 0.365415 0.718256 0.624511 1.571990 0.113371 0.572031 1.797961 0.876379 0.068642 0.072119 0.553161 0.329387 0.545574 0.337595 1.647194 1.034042 0.468339 1.774314 0.240404 1.846502 1.142528 1.223731 0.832499 0.428931 0.643890 1.257704 1.085969 0.643637 0.429070 0.971966 0.109095 0.689833 0.417898 1.804672 1.346983 0.150026 0.404292 0.575881 1.441149 0.533070 -0.177095 0.298641 0.921545 1.086883 0.410704 0.849120 1.518187 1.874571 0.517824 1.242109 -0.053714 0.834159 0.276990 1.956354 1.765190 1.537622 1.530954 -0.106766 1.325278 -0.071959 1.045056 0.533410 0.699958 0.068418 0.070057 1.204618 1.620552 1.072110 1.372120 0.848823) ) ;;; 109 all -------------------------------------------------------------------------------- ; 10.440306508911 (vector 109 13.496821304096 (fv 0 0 0 1 0 1 0 1 1 0 1 0 0 1 0 0 1 1 1 1 1 0 1 1 1 0 1 1 0 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 0 0 1 0 1 1 0 0 0 1 1 0 0 1 0 0 1 0 1 0 0 1 0 0 0 1 0 1 1 1 0 1 1 1 0 0 1 1 1 0 0 1 0 1 0 0 0 1 0 1 1 1 0 1 1 0 1 1 1 1 0 0 0 0) 10.432370 (fv 0.000000 0.222737 0.395964 0.267704 0.984627 0.196896 1.257313 -0.049947 0.063508 1.503629 1.207170 0.259470 1.634989 1.732463 0.102120 1.779072 -0.448069 1.030982 -0.170238 0.241134 1.050790 1.545206 1.217799 1.632326 -0.260618 1.981321 1.563052 0.646224 0.963725 1.195450 1.382468 0.912278 -0.055446 -0.043084 1.544497 1.444807 0.819657 0.741044 0.122396 1.518758 -0.047192 1.432176 0.150062 1.445372 1.689041 1.538858 1.607305 0.672865 0.037321 1.002894 0.706157 0.845104 0.402627 1.438914 1.038104 1.050343 0.380185 1.252881 -0.144926 -0.130041 -0.022885 1.740880 1.268140 -0.038596 0.221618 0.937959 1.603605 0.465293 -0.010315 0.708519 1.255289 0.623840 0.892628 0.632806 0.245713 1.831669 -0.020202 0.561348 0.735902 1.121505 0.850852 0.147905 1.162108 1.085140 0.352699 1.043580 0.226572 1.785966 0.379633 0.873437 1.384309 1.785370 1.080206 1.256403 1.169325 0.672865 1.444061 0.325194 0.278183 1.165719 -0.193709 1.182201 0.138301 0.079081 1.231522 0.798589 -0.014107 0.372822 1.050722) ;; [checked] ;; pp: 10.450104 (fv 0.000000 0.623079 1.000690 1.676565 0.329793 0.812365 1.369654 0.033036 0.636775 1.205357 1.818620 0.518482 1.271099 -0.006177 0.798686 1.518819 0.365150 1.120280 1.863547 0.825398 1.655423 0.561458 1.434421 0.357234 1.260951 0.112744 1.108421 0.195312 1.204468 0.187317 1.151003 0.344529 1.318670 0.493356 1.634474 0.713838 1.719668 0.894392 0.187447 1.393869 0.631586 1.857642 1.152308 0.558736 1.895158 0.937863 0.284606 1.593849 1.131320 0.496395 1.862604 1.450055 1.017002 0.269052 1.590119 1.223313 0.766679 0.191870 1.793336 1.442714 0.950223 0.613488 0.158729 1.978172 1.504759 1.404948 0.934115 0.506811 0.307861 0.053560 0.056210 1.784308 1.658677 1.460879 1.312182 1.175464 0.793270 0.871641 0.543638 0.736870 0.773799 0.716297 0.645633 0.912396 0.319672 0.772867 0.727345 0.920587 0.879052 1.066787 1.359741 1.428609 1.742928 0.019718 0.299864 0.439508 0.461036 0.748673 0.838321 1.439140 1.960382 0.367463 0.781933 1.129021 1.394803 1.904930 0.281191 0.715525 1.133222) ;; ppe: 10.470162 (fv 0.000000 0.451543 0.456061 0.147873 0.922547 -0.015839 1.326621 0.024116 -0.214919 1.809411 1.260411 -0.041222 1.497661 1.558073 1.813230 1.792964 -0.178738 0.909655 0.169254 0.063699 1.161084 1.372145 1.379335 1.141902 -0.228933 1.774907 1.529928 0.313058 1.032527 0.848013 1.268723 1.218902 1.606823 -0.185860 1.765043 1.039756 0.745126 0.269721 0.154169 1.685147 -0.249171 1.208381 0.488385 1.400686 1.729831 1.462720 1.767018 0.760244 0.226518 1.299640 0.590535 1.231728 0.337540 1.363389 1.096692 0.848743 0.528317 1.290759 1.823255 0.006608 0.050582 1.737871 1.377769 0.292561 0.372415 1.032383 1.772564 0.594274 1.989312 0.990074 1.229632 0.208396 0.695371 0.886409 0.070239 1.725783 -0.164935 0.277786 0.838920 1.005114 0.874184 0.343822 0.665942 0.650106 0.585298 0.979509 -0.150741 1.631833 0.286195 1.077553 1.249512 1.979846 1.138840 1.144065 1.361495 0.626673 1.081435 -0.100313 0.333711 1.298242 -0.025467 1.240351 0.507433 -0.065459 1.581161 0.747520 -0.025829 0.466153 1.514665) ;; 108+1 10.457243 #(0.000000 1.269530 0.760051 1.729694 1.122945 0.814880 1.466156 1.631086 0.616903 1.786832 1.344985 0.030797 0.418832 0.037877 0.373313 0.275814 0.977767 0.677872 0.673791 -0.065296 1.118192 1.826436 0.508528 0.285632 0.821565 1.103219 -0.267070 -0.330900 0.618539 0.170243 0.892990 1.223460 0.764058 1.162302 1.620423 0.957344 0.023461 -0.059770 0.381474 0.692706 0.660066 1.703495 0.098695 0.624314 1.751336 0.844891 0.120502 0.057294 0.621996 0.319901 0.586587 0.186646 1.685806 0.974557 0.474304 1.735548 0.234787 1.810600 1.138824 1.194376 0.872559 0.435412 0.677166 1.290849 1.011702 0.701077 0.322755 0.950082 0.024752 0.607227 0.415633 1.702576 1.323090 0.195261 0.365091 0.675664 1.408251 0.606997 -0.208324 0.308915 0.941088 1.034722 0.364193 0.967725 1.444390 1.941283 0.456248 1.293589 0.032476 0.805832 0.141117 1.965347 1.709815 1.528055 1.586120 -0.152788 1.361484 0.019126 1.044770 0.500796 0.670659 0.067435 -0.009310 1.226198 1.603811 1.046583 1.365223 0.883194 0.193296) ;; 110-1 10.322689 #(0.000000 0.462741 1.225949 -0.043832 0.328249 1.203588 1.366455 0.188790 0.662494 1.254935 0.088331 0.613339 1.462149 0.115526 0.949842 1.737591 0.506946 1.154137 -0.032436 0.629976 1.492938 0.520189 1.718079 0.515487 1.428565 0.137996 1.083472 0.059980 1.139261 0.225618 1.233707 0.316895 1.419668 0.505397 -0.033495 1.176194 0.083251 0.973170 -0.022020 1.079081 0.404451 -0.075399 0.954069 0.083319 1.505012 0.979962 0.145560 1.327979 0.617711 0.036057 1.210156 0.994048 0.360797 0.174071 1.687531 1.240584 0.732227 -0.166972 1.189885 0.961323 0.562443 0.160936 1.676083 1.644780 1.189431 1.265120 0.457405 -0.062176 -0.195559 1.385371 1.408492 1.397143 0.885687 1.094863 0.605162 1.202260 0.535171 0.604107 -0.037920 -0.116681 -0.077010 -0.133672 0.060191 0.259325 0.089984 -0.015913 0.025781 0.203482 0.430865 0.266253 0.224375 0.677975 0.937860 1.248001 1.478415 1.717389 -0.074246 -0.120586 0.330859 0.557195 1.125288 1.605582 1.607504 0.218383 0.840491 1.393138 1.612134 0.160685 0.161037) 10.322461 #(0.000000 0.462674 1.225929 -0.043823 0.328289 1.203623 1.366492 0.188811 0.662499 1.254926 0.088298 0.613331 1.462150 0.115531 0.949884 1.737576 0.506973 1.154095 -0.032430 0.630002 1.492901 0.520199 1.718088 0.515495 1.428578 0.137955 1.083433 0.059942 1.139302 0.225628 1.233696 0.316931 1.419646 0.505419 -0.033497 1.176199 0.083263 0.973159 -0.022043 1.079044 0.404491 -0.075384 0.954089 0.083290 1.505001 0.979986 0.145592 1.327990 0.617711 0.036068 1.210133 0.994076 0.360795 0.174016 1.687546 1.240574 0.732273 -0.167006 1.189898 0.961364 0.562444 0.160956 1.676079 1.644808 1.189461 1.265171 0.457402 -0.062179 -0.195550 1.385369 1.408507 1.397115 0.885691 1.094876 0.605175 1.202259 0.535204 0.604108 -0.037958 -0.116695 -0.076978 -0.133663 0.060171 0.259320 0.089947 -0.015900 0.025779 0.203485 0.430891 0.266250 0.224373 0.677986 0.937839 1.248001 1.478410 1.717359 -0.074278 -0.120509 0.330877 0.557156 1.125282 1.605553 1.607549 0.218369 0.840506 1.393115 1.612150 0.160649 0.161027) ) ;;; 110 all -------------------------------------------------------------------------------- ; 10.4881 (vector 110 13.592092514038 (fv 0 0 1 0 0 1 1 1 0 1 0 1 1 0 1 0 0 0 0 1 0 0 1 0 0 1 1 0 1 1 1 0 0 1 1 0 1 1 1 1 0 1 1 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 1 1 0 1 1 0 0 1 1 0 0 0 0 1 1 1 1 1 1 0 0 1 1 1 1 0 1 1 1 1 0 0 0 1 1 1 0 1 1 1 1 1 1 0 1 0 1 0 1 0 1) 10.443826 (fv 0.000000 0.966857 -0.310939 0.754018 -0.215289 0.050408 1.345912 1.407669 0.917300 1.537339 0.464664 1.377382 -0.129707 1.562018 0.873176 0.378480 1.188634 1.002593 1.467403 -0.157591 0.611052 1.240086 1.200021 0.642960 0.011727 1.278266 0.757206 1.221576 1.173971 1.148607 0.352945 0.591698 0.569729 0.204560 1.805523 0.091751 0.494475 0.741755 1.173490 0.125853 1.836232 0.189233 1.047389 0.359034 0.299905 1.335669 1.331935 0.866342 1.429328 0.175988 0.321575 0.808716 0.418347 0.305766 0.587213 0.859103 1.233827 1.612185 0.649515 1.232962 0.438531 1.088539 1.160206 1.276056 0.991705 0.605889 1.920272 1.294151 0.591700 0.477186 -0.114311 0.103729 0.053546 1.057780 1.113226 0.935069 0.869987 0.585069 1.193799 0.314064 1.564843 1.009796 1.434593 -0.061294 0.394207 1.540076 0.463315 1.070060 1.005570 -0.247697 1.209164 0.032912 1.882456 0.617912 -0.419949 0.119714 0.033254 -0.149035 1.146172 0.301556 1.043038 0.611637 1.119274 -0.185496 1.474180 0.910726 0.869288 0.008729 1.113223 0.605574) ;; pp: 10.416677 (fv 0.000000 0.636826 1.168776 1.802237 0.316567 0.986572 1.395425 0.009381 0.711647 1.264223 1.932392 0.627165 1.472185 0.196446 0.915303 1.747756 0.298057 1.087093 -0.098251 0.679800 1.474105 0.503701 1.516136 0.488851 1.222583 0.157308 1.093122 0.014882 1.111898 0.174280 1.267353 0.186944 1.319383 0.570938 1.741756 0.793533 -0.092041 0.821354 -0.104426 1.044239 0.485714 1.864668 0.984585 0.108795 1.386239 0.942801 0.150487 1.312495 0.693148 -0.057522 1.440466 0.911264 0.464590 -0.106316 1.425558 0.757031 0.414982 -0.197207 1.393462 0.845365 0.655558 0.173740 1.724477 1.622714 1.133952 1.113326 0.491749 0.027662 -0.081584 1.624363 1.523158 1.483424 1.009127 1.065663 0.489911 0.865535 0.429699 0.506066 0.168610 0.091635 -0.004728 0.101995 0.057231 0.244394 0.215629 0.140294 0.025423 0.249165 0.312773 0.491767 0.509301 0.585407 1.082514 1.193775 1.427418 1.634094 0.038165 -0.066305 0.261200 0.531951 1.008338 1.495805 1.630762 0.003123 0.564786 1.124822 1.373512 0.020469 0.093862 0.692170) ) ;;; 111 all -------------------------------------------------------------------------------- ; 10.5357 (vector 111 13.80813938144 (fv 0 1 0 0 0 1 0 0 1 1 1 1 0 1 0 1 0 0 1 1 1 0 1 0 0 0 0 0 1 0 0 0 1 0 1 0 0 1 0 1 1 1 0 1 1 0 0 1 0 0 0 0 1 0 1 1 1 1 0 1 1 0 0 1 0 1 1 1 0 1 0 0 1 0 1 0 0 1 1 0 1 0 0 1 0 0 0 0 1 0 1 0 0 0 1 1 1 0 0 0 0 0 0 0 1 0 0 0 1 1 1) 10.489680 (fv 0.000000 1.276377 0.968620 -0.218445 1.901880 0.088071 1.832261 1.338375 0.312772 1.516596 -0.040044 1.173079 0.061551 1.259985 1.326413 -0.075796 1.430603 0.457729 0.555673 0.169939 0.778858 0.499517 1.015059 1.507495 0.252622 0.024778 0.982934 -0.060048 0.808349 1.306234 -0.213685 0.893109 1.680180 0.816232 1.412440 1.447865 1.309405 0.967681 0.468074 1.167299 -0.294730 0.516281 1.115680 1.346378 1.503302 1.329509 0.069846 0.507313 -0.050602 1.169163 1.172511 1.329654 1.283831 1.273536 0.082962 0.472668 1.944396 -0.083515 1.629124 1.133239 1.648857 0.792610 0.954204 1.052081 0.877455 0.393129 1.388896 0.794997 1.052606 1.611060 1.743638 -0.167971 0.888631 0.570983 1.576402 0.843125 0.114093 0.127173 -0.133155 0.386550 0.090826 -0.017777 0.548430 0.313331 0.380367 1.607846 1.086331 0.772909 1.643444 0.182619 1.863239 1.234660 1.568659 0.555853 0.450573 1.731233 0.287714 1.462361 1.635622 0.921500 0.450553 1.230974 -0.314374 1.516211 0.633822 0.309849 1.238687 0.080817 0.340326 0.819921 0.108053) ;; pp: 10.643017 (fv 0.000000 0.596037 0.998452 1.643602 0.188094 0.782119 1.390123 1.810388 0.670975 1.236188 1.928555 0.736392 1.354483 0.006575 0.718278 1.554028 0.172799 1.022616 1.853097 0.691617 1.671397 0.482108 1.396206 0.302319 1.140585 0.111154 0.983122 0.056085 1.055691 0.244450 1.330135 0.199631 1.342393 0.616747 1.511753 0.573545 1.630931 0.744657 -0.127581 1.276167 0.582439 1.726242 0.856228 0.208204 1.620801 0.767397 -0.120308 1.331917 0.688933 0.171660 1.532348 0.908708 0.322624 0.027670 1.377420 0.714808 0.162920 1.602731 1.164131 0.775892 0.384718 0.044281 1.527000 1.328705 0.880737 0.584683 0.141627 1.752084 1.448907 1.433198 0.874054 1.138685 0.574512 0.605078 0.161111 0.252563 -0.040319 -0.061275 1.677664 1.534157 1.653785 1.516730 1.618593 1.597830 1.517008 1.764779 1.586607 1.708185 1.767619 1.608773 1.820236 0.130593 0.415076 0.510025 0.490569 0.957514 1.270290 1.288854 1.456687 1.689789 0.173097 0.338870 0.690795 1.081327 1.548637 1.886234 0.458387 0.722046 1.068087 1.577951 0.177921) ;; 112-1 10.443480 #(0.000000 -0.037648 1.480547 0.898464 0.849030 0.715984 0.623417 1.093452 1.045921 0.246543 -0.344784 0.997605 0.429765 1.643868 1.074256 0.709084 1.236163 1.022832 0.593800 1.797589 1.639095 0.499474 0.451589 0.525734 0.819269 1.059245 1.215835 0.300337 0.312343 0.508727 1.809376 1.802285 0.733765 0.697253 0.213017 0.226942 0.966882 -0.054080 1.879864 1.400510 1.357810 0.290115 0.291026 1.461469 1.516948 0.034933 0.486567 0.403300 0.540306 0.175821 0.605359 0.053443 -0.120390 0.105172 0.600333 0.664197 1.296750 -0.152576 0.244035 0.980125 0.718707 -0.396109 0.441995 0.857389 0.411314 0.615877 0.959296 0.472542 0.178066 1.504140 1.379940 1.172606 -0.073019 1.778815 0.168644 0.842220 -0.533009 0.218109 1.118845 -0.068508 0.820652 0.991755 -0.019081 1.121993 1.252324 1.508966 1.128293 0.270315 0.609971 -0.037115 1.065942 0.157780 1.138199 0.066912 1.242092 -0.087703 0.391351 0.761091 0.405427 0.623899 1.599600 0.333353 -0.321760 0.806575 1.571941 1.193797 1.308207 1.479299 1.022704 -0.056211 1.366886) ) ;;; 112 all -------------------------------------------------------------------------------- ; 10.5830 (vector 112 13.719 (fv 0 1 1 0 1 1 0 0 1 1 0 0 1 0 0 1 1 1 1 1 0 0 1 1 1 1 0 0 0 0 0 0 0 1 1 1 0 1 0 1 0 0 0 1 1 1 0 1 1 1 0 1 0 1 1 1 1 0 1 1 1 0 0 1 0 0 1 1 1 1 0 0 1 0 1 1 0 1 0 0 1 1 0 0 0 1 0 0 0 0 1 0 1 0 1 0 1 1 0 0 0 0 0 1 0 0 0 0 1 1 0 0) 10.459590 (fv 0.000000 -0.062913 1.592216 0.942127 0.779122 0.819196 0.718354 1.051311 1.122277 0.289276 -0.312849 0.932738 0.364926 1.651917 1.193754 0.735359 1.259741 0.983056 0.504666 1.898067 1.619072 0.449638 0.460210 0.529471 0.685535 0.885439 1.297728 0.246636 0.353836 0.474674 1.786116 1.844574 0.794031 0.522576 0.168364 0.225941 0.884728 0.029172 1.770209 1.576812 1.352123 0.112130 0.389134 1.458224 1.532633 -0.027079 0.404717 0.274263 0.478667 0.228414 0.618491 0.032636 -0.068031 -0.092335 0.583363 0.722295 1.283590 -0.207344 0.372473 0.858879 0.815320 -0.324439 0.478159 0.803167 0.466456 0.633813 0.914568 0.438946 0.113725 1.518872 1.409010 1.227714 -0.134104 1.718626 0.277412 0.813327 -0.439158 0.260660 1.183284 -0.118611 0.754421 1.157336 0.232930 1.195932 1.264381 1.427453 1.112389 0.316426 0.581550 -0.107354 0.998672 0.153435 1.101697 1.916684 1.183525 -0.016743 0.301725 0.815282 0.398182 0.676231 1.536900 0.451259 -0.254624 0.791021 1.692791 1.255094 1.233704 1.361151 1.046040 0.024905 1.319507 0.390306) ) ;;; 113 all -------------------------------------------------------------------------------- ; 10.6301 (vector 113 14.027848738379 (fv 0 0 1 1 1 0 1 1 0 1 1 0 1 0 1 1 0 1 0 1 1 0 1 1 1 0 1 0 1 0 0 1 1 0 0 1 1 1 1 1 0 1 0 1 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 0 1 0 0 1 0 0 0 0 1 0 0 0 1 1 0 1 0 1 0 0 1 1 1 1 1 0 0 0 1 0 0 1 0 1 1 1 0 0 1 0 1 1 1 1 1 0 0 0 1 1 1) 10.600374 (fv 0.000000 0.803646 1.150583 -0.063719 0.153874 1.101937 1.517661 1.839236 0.205434 0.503789 1.408027 1.282481 0.272193 0.581489 0.335632 0.191891 1.772311 1.188767 0.099798 1.108690 0.011443 -0.134966 0.851026 0.685097 0.180285 -0.598894 0.447561 0.453948 1.859577 0.373971 -0.017010 1.368747 0.811506 1.286383 1.607236 0.428535 0.456478 0.425986 0.560105 1.702212 1.615194 -0.029581 1.141022 0.404596 0.679875 1.483164 0.383858 0.334137 1.078889 1.358586 1.100321 0.206891 -0.260760 1.245372 1.320253 -0.104904 0.095400 0.153720 1.818561 0.632022 0.857521 -0.124243 1.123425 -0.152970 0.639127 0.101388 0.775543 0.547622 0.403455 1.168990 1.099889 1.089210 1.061140 1.095647 -0.008863 1.297497 0.125060 1.432503 0.841141 0.967915 1.177416 0.211122 0.724975 0.094432 1.035737 1.190949 0.605535 -0.311727 1.252767 0.699524 1.428815 0.329899 0.934047 0.582587 0.113129 0.668360 0.786133 0.103091 0.745732 1.809761 0.414589 0.231740 -0.023699 1.470163 1.649059 1.087085 1.691589 1.869557 0.611645 1.538351 0.985815 1.244743 0.786305) ;; pp: 10.533209 (fv 0.000000 0.701701 1.023037 1.805117 0.325103 0.864669 1.301988 0.041817 0.605545 1.212149 1.794798 0.682259 1.361354 0.200642 1.040014 1.570001 0.413916 1.135956 1.836914 0.609510 1.482300 0.433561 1.396354 0.242061 1.189941 0.064290 0.924650 1.865499 0.844070 1.972890 1.045011 0.019512 1.010788 0.256118 1.454283 0.372006 1.414933 0.757156 1.833026 0.854510 0.058898 1.301933 0.794807 0.059810 1.092848 0.343912 1.857250 1.216439 0.367607 1.585969 1.093436 0.524265 1.847968 1.349059 0.839561 0.495981 1.801236 1.298227 0.638863 0.266374 1.658935 1.480658 0.907119 0.639357 0.037985 1.986216 1.525743 1.288722 0.717261 0.704091 0.182223 0.044649 1.629714 1.819647 1.366848 1.330078 1.172022 1.015716 0.897536 0.806098 0.193895 0.422839 0.374579 0.235069 0.423986 0.463374 0.446056 0.493571 0.177728 0.437229 0.621846 0.665477 0.619012 0.807147 1.289974 1.297164 1.517281 1.924928 0.144210 0.370826 0.244142 0.591610 0.749322 1.350513 1.818547 -0.017393 0.517731 1.113988 1.244052 1.823099 0.067707 0.517248 0.930474) ;; 112+1 10.576527 #(0.000000 -0.099725 1.731869 1.126572 0.894565 0.787291 0.763373 1.116837 1.193937 0.158815 -0.328224 1.005844 0.228474 1.576738 1.262088 0.726943 1.268236 1.028150 0.589551 1.934756 1.609372 0.549105 0.446947 0.675880 0.714883 0.715628 1.363097 0.197217 0.353490 0.498917 1.784841 1.858473 0.777450 0.430951 0.142623 0.145377 1.039521 0.058101 1.806559 1.621009 1.395572 0.126961 0.400552 1.407730 1.420143 0.113046 0.482937 0.384809 0.357336 0.283000 0.705514 -0.045003 0.046604 -0.167904 0.589381 0.672696 1.241252 -0.116645 0.444533 0.866902 0.717018 -0.308546 0.397419 0.905566 0.584026 0.513164 0.877715 0.340382 0.028422 1.468619 1.404513 1.266203 -0.129199 1.813800 0.484278 0.806396 -0.359344 0.323726 1.188865 -0.113226 0.736080 1.212752 0.152030 1.358239 1.256305 1.492197 1.073162 0.176415 0.460366 -0.046759 0.938493 0.111495 1.045740 -0.030211 1.265442 0.071430 0.331346 0.715146 0.333258 0.829360 1.647336 0.578653 -0.323225 0.799001 1.641979 1.340856 1.121452 1.538434 1.235479 0.162729 1.417493 0.473155 0.256349) ) ;;; 114 all -------------------------------------------------------------------------------- ; 10.6771 (vector 114 13.847382931726 (fv 0 1 1 1 1 1 0 0 1 1 1 0 1 0 0 0 1 1 0 1 0 1 1 1 1 0 1 0 1 1 1 0 0 0 0 1 0 1 1 1 0 1 1 1 1 1 0 1 1 0 1 1 0 1 0 0 1 0 1 0 1 1 0 1 1 0 1 1 1 0 0 1 1 1 0 1 0 1 0 1 0 0 0 1 0 0 0 0 0 1 1 1 0 1 1 1 1 0 0 1 0 0 0 1 1 1 1 1 1 0 0 0 0 1) 10.628224 (fv 0.000000 0.615672 0.948130 0.747004 0.833637 0.289537 1.854717 0.930205 1.803295 1.161499 -0.674663 0.075654 -0.069447 1.150337 -0.219431 0.096417 1.741068 -0.016217 1.826914 -0.308775 0.152833 0.789042 0.803929 0.462314 0.626523 1.267262 0.400780 0.962101 1.687986 0.905206 0.268457 0.651715 0.114771 1.475643 0.044755 0.228029 0.514674 0.188213 -0.185396 1.589097 0.877857 -0.230405 1.243228 1.194822 1.559225 1.498045 0.808593 -0.017518 1.442649 1.211002 1.811223 0.625459 1.384771 0.613911 0.308197 1.431371 1.357215 1.098185 0.214395 1.664025 1.740860 1.399478 0.567842 0.816563 1.298643 1.214440 0.204096 1.160510 1.171795 0.002888 0.712001 0.408799 0.129596 0.526919 1.018226 1.540087 1.326981 1.269312 0.284234 1.408491 0.614427 1.282597 0.201606 0.407636 1.049940 -0.424432 1.688488 0.609780 -0.014895 -0.443393 1.774217 1.192149 -0.353060 1.542744 1.597711 0.829765 0.335469 0.940418 1.687078 -0.157090 1.505994 0.110351 1.069331 0.286269 -0.198482 1.240708 -0.041616 1.268700 0.079424 0.525193 1.036769 0.352036 1.456021 -0.218427) ;; pp: 10.517948 (fv 0.000000 0.513150 0.874296 0.883964 0.730138 0.492200 1.910349 0.914831 -0.079055 1.078332 -0.626669 0.137543 -0.184379 1.218055 -0.394114 -0.038192 1.661163 0.020764 -0.078690 -0.096176 0.170832 0.906574 0.889519 0.505117 0.670269 1.228477 0.365822 0.917034 1.728829 0.934323 0.199610 0.715554 0.056223 1.583731 0.085811 0.136885 0.354627 0.123817 -0.315376 1.492556 0.991663 -0.233639 1.201411 1.218512 1.753756 1.719460 0.679044 -0.197393 1.570682 1.193787 1.873756 0.557014 1.432466 0.588568 0.309382 1.651394 1.357542 1.190693 0.264093 1.733513 1.676510 1.179474 0.616239 0.734925 1.107757 1.048586 0.066290 1.132123 1.205852 -0.090603 0.754355 0.838256 -0.013038 0.421890 0.968163 1.389079 1.284090 1.323690 0.432981 1.323326 0.730210 1.395732 0.109710 0.246664 1.169930 -0.449126 1.545991 0.365384 0.076032 -0.458822 1.876049 1.124853 -0.255218 1.423147 1.451143 0.955505 0.281503 0.928421 1.983790 -0.130994 1.684131 0.142847 1.010533 0.452692 -0.386536 1.218551 -0.132981 1.371320 0.120371 0.410528 1.083879 0.496636 1.350228 -0.127680) ) ;;; 115 all -------------------------------------------------------------------------------- ; 10.7238 (vector 115 14.359978160099 (fv 0 0 0 0 1 1 1 0 0 0 0 1 0 1 1 0 0 1 0 0 0 1 0 0 1 0 0 1 1 1 1 0 1 1 1 1 0 1 1 1 0 1 1 1 1 0 1 0 1 0 0 1 1 0 1 1 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 1 1 1 1 0 0 1 1 0 1 0 1 0 1 0 1 0 1 1 0 1 1 0 1 0 0 0 0 0 0 0 0 1 1 0 1 1 1 1 0 0 0 1 0) 10.651124 (fv 0.000000 0.205632 0.521043 1.123267 0.039976 1.837568 0.645276 0.444856 1.235953 1.614101 0.576705 -0.032817 0.913102 0.971540 0.123207 0.744147 0.392163 1.071292 -0.098894 1.183735 0.447902 1.029195 1.008083 1.241655 1.280374 0.851598 0.236819 1.816127 -0.109787 0.735910 1.359965 1.270732 -0.070459 0.794811 1.337404 0.069925 0.240715 0.381811 0.943512 0.073841 0.371201 0.917351 1.527618 1.440973 1.203354 1.349081 1.416186 1.496910 0.596478 1.312074 0.317957 1.177389 1.248077 0.233191 1.529687 -0.003737 0.662497 0.466830 0.261424 0.663736 1.797196 0.273538 -0.239584 0.345229 -0.159975 1.144743 1.462922 0.849868 0.439184 0.064973 -0.068494 1.400482 0.060773 0.986838 0.519130 0.531890 1.046288 1.063229 -0.449183 0.987082 0.473670 0.722114 1.227775 0.954889 0.100062 1.512033 0.697126 0.308149 0.914574 -0.044099 1.083776 1.037385 0.163494 1.178786 0.886753 1.659086 0.598578 0.720776 -0.009109 0.443556 -0.035564 0.124043 0.119757 0.888837 0.603645 0.075938 0.648026 1.218123 0.325603 0.011855 -0.390969 1.523387 0.517639 0.461045 0.382395) ;; pp: 10.692099 (fv 0.000000 0.682108 1.004779 1.652402 0.376256 0.931307 1.336301 -0.042653 0.588667 1.131321 1.748894 0.607835 1.177352 0.067431 0.978893 1.474587 0.304669 1.111594 1.772579 0.564007 1.383113 0.290881 1.312527 0.215649 0.998467 1.886147 0.914831 1.987244 0.837886 1.778286 0.954819 0.007952 0.956821 0.049735 1.234469 0.317950 1.546668 0.474841 1.665959 0.756708 1.898394 0.922825 0.371276 1.716491 0.889079 0.061723 1.582232 0.834088 0.114964 1.594440 0.728947 -0.028372 1.273062 0.885177 0.297790 1.790777 1.254681 1.031275 0.275613 1.607695 1.196021 0.692250 0.421770 -0.204945 1.512060 0.983139 0.944306 0.546267 0.135875 1.788546 1.584465 1.138761 1.024708 0.473784 0.573120 0.243555 0.106429 0.088753 1.821567 1.941212 1.609147 1.360828 1.169556 1.150415 1.008492 1.219522 1.057528 1.215083 1.411123 0.944912 1.124604 1.295606 1.527918 1.383902 1.570266 -0.108659 -0.107049 0.292041 0.547918 0.923643 1.165187 1.026903 1.427566 1.557678 -0.113193 0.455092 0.823626 1.321739 1.608732 1.934769 0.561130 0.698218 1.143434 1.648015 0.348542) ;; 114+1 10.621744 #(0.000000 0.519128 0.786784 0.918158 0.650178 0.457293 1.964414 0.915637 -0.037992 1.187864 -0.612331 0.073197 0.008576 1.197804 -0.364310 0.047620 1.612311 0.098163 -0.054077 -0.087970 0.039413 0.986129 0.969342 0.451170 0.648283 1.253012 0.349815 0.949459 1.680558 0.960988 0.220312 0.666892 -0.069695 1.584459 0.070346 0.154295 0.414900 0.222762 -0.268103 1.413909 0.961497 -0.210113 1.203087 1.172411 1.792543 1.742069 0.706989 -0.208070 1.562128 1.211841 0.011662 0.482644 1.455971 0.642656 0.264522 1.637721 1.461442 1.154901 0.149110 1.871307 1.810194 1.307963 0.530941 0.678563 1.057540 1.204932 0.204765 1.173394 1.102820 -0.082769 0.639150 0.715081 -0.172130 0.444439 1.033638 1.431627 1.223005 1.352911 0.473564 1.345853 0.701386 1.441324 0.065510 0.263153 1.148218 -0.395379 1.422829 0.339640 0.186555 -0.374702 1.783978 1.192276 -0.175028 1.327174 1.534754 1.031453 0.306400 0.980338 0.017668 -0.122396 1.685264 0.121507 0.952038 0.457874 -0.310268 1.350976 -0.129566 1.387678 0.182170 0.404390 1.132228 0.552993 1.477216 -0.117535 0.087972) ) ;;; 116 all -------------------------------------------------------------------------------- ; 10.7703 (vector 116 14.175787507646 (fv 0 1 0 1 0 1 1 1 1 1 0 1 1 1 0 1 0 1 1 1 0 0 0 1 1 1 1 1 1 1 0 0 0 1 1 0 0 0 0 1 1 0 1 0 1 0 0 1 1 1 0 0 0 0 0 1 0 1 1 0 1 1 0 1 0 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 0 0 1 0 0 1 0 1 1 1 0 0 0 1 1 0 1 1 0 0 1 1 1 0 0 1 0 0 0 0 0 1 0 1 1 0) 10.666895 (fv 0.000000 0.794041 0.130396 1.155449 0.575356 1.670182 1.438030 0.802411 -0.073881 0.612189 1.011030 0.243247 1.424701 1.360754 0.519915 1.303274 0.114440 0.486440 1.248641 -0.062831 1.818237 1.003329 1.774020 0.995383 0.217514 0.236196 0.918414 0.251978 0.240543 1.203872 1.193015 1.546847 0.668684 0.276657 0.720261 0.041331 0.124685 1.052830 -0.470877 1.036338 0.454033 1.208580 1.059685 0.252464 0.910634 -0.469687 1.282886 1.260566 1.714177 0.148852 1.558794 0.117249 1.208112 1.206944 1.379709 1.280227 -0.397300 1.912745 1.609055 0.469506 1.102260 0.207876 1.456855 1.808614 1.436770 0.080959 1.197513 1.183739 1.574767 0.068412 1.162064 0.609158 0.566278 1.029997 1.123257 -0.210554 1.006729 1.012851 0.184672 1.531574 1.788773 1.233395 0.609493 0.767948 1.753741 1.423961 0.953617 0.300031 0.940377 0.324215 0.472402 0.042965 0.104811 0.217444 1.091263 1.136923 1.660947 0.519559 1.199475 -0.360436 1.523678 1.224456 -0.014998 1.278905 -0.475457 -0.462757 0.028990 0.974163 1.009397 0.422500 0.343570 0.466660 0.909671 0.746952 -0.297506 0.078048) ) ;;; 117 all -------------------------------------------------------------------------------- ; 10.8167 (vector 117 14.136 (fv 0 1 1 1 0 0 1 1 0 0 1 0 0 1 0 1 1 1 1 1 1 1 1 1 1 0 0 1 0 1 0 1 1 1 0 1 0 0 0 1 0 1 0 0 0 1 1 1 1 1 1 0 1 1 0 1 1 0 1 0 0 0 0 1 0 0 1 0 0 0 0 1 1 1 0 0 1 1 1 0 0 0 1 0 0 1 1 1 1 1 0 1 0 1 1 0 1 1 1 1 1 0 0 0 1 0 1 1 0 1 0 0 0 1 0 0 1) 10.740323 (fv 0.000000 1.376267 1.204802 1.617264 0.013985 1.562933 1.297010 -0.381289 0.175690 0.812406 0.271907 -0.572032 0.505210 1.569967 0.483045 1.266493 1.587294 0.516881 0.600232 0.990644 0.302416 1.037870 1.417076 1.853643 -0.147420 0.890223 1.567662 0.981809 0.815941 1.608390 -0.281550 0.201337 1.556451 1.125175 -0.236163 1.445336 0.258466 0.600771 0.570165 0.048623 0.131732 0.130088 0.167451 1.924952 -0.030799 0.148010 1.615329 0.361965 0.025922 1.817684 1.449080 1.328054 1.692177 0.082231 0.922069 0.868297 0.602630 -0.302067 1.498947 0.796296 -0.211597 1.912831 0.263824 1.087462 0.264795 1.339326 0.746964 1.555264 0.991573 0.792728 0.572734 0.831900 1.561482 0.487864 1.625032 1.584684 1.155708 1.141107 1.673417 0.421621 -0.187613 1.264593 1.627549 0.823098 0.254093 0.097500 0.358549 1.789940 1.103526 1.081236 0.794597 1.136333 1.473853 1.388624 -0.112319 0.798455 -0.090384 -0.176678 0.782426 -0.241572 0.802635 1.296656 0.310053 1.464029 0.628323 1.034158 1.019782 -0.078897 0.005414 1.234988 0.557243 0.357637 -0.491315 0.727622 1.220297 0.073271 0.925087) ) ;;; 118 all -------------------------------------------------------------------------------- ; 10.8628 (vector 118 14.207115029287 (fv 0 1 1 1 1 1 1 0 1 0 0 1 1 1 1 0 0 0 1 0 1 0 1 1 0 0 1 0 1 0 0 0 1 0 0 0 0 1 1 1 1 0 0 1 0 0 1 1 1 1 1 0 0 1 0 0 0 1 1 1 1 1 0 0 1 1 0 0 0 0 1 1 0 1 0 1 1 1 1 1 1 1 0 1 0 0 1 0 1 1 0 0 1 1 1 0 1 1 0 1 1 1 1 0 1 1 1 1 0 1 0 1 0 1 0 0 0 0) 10.789998 (fv 0.000000 -0.175913 -0.143823 0.018273 0.027771 0.767311 -0.171214 1.636246 0.351281 1.388337 0.882351 1.707573 0.469183 0.078893 1.085758 0.618150 0.277129 0.703491 1.759709 -0.452169 1.251866 0.357896 0.724274 0.269975 1.838904 1.530293 1.426834 1.312699 0.647676 1.426356 1.595332 0.060341 0.690735 0.318521 0.226388 0.557313 0.682546 0.405400 0.629229 1.956450 1.295086 1.263226 1.531833 -0.446064 1.088083 -0.430622 1.100111 0.930366 1.309892 0.353356 1.791502 1.255481 1.229378 1.253262 1.406532 0.024314 1.063085 1.088221 0.123383 1.238746 1.005923 0.642418 1.110925 0.453476 -0.290616 1.496832 1.287503 0.244996 1.530267 0.834163 0.976178 0.556214 0.154839 1.049337 1.096181 0.549254 -0.047077 0.951697 1.030491 0.147772 0.888048 0.978379 -0.017946 1.704759 1.894288 0.751630 1.629711 1.581497 1.015790 1.546094 0.769995 1.519488 -0.226811 0.116498 -0.232287 0.274508 1.259352 1.098443 1.128583 0.216589 1.343006 0.117206 0.662844 -0.110291 1.010752 0.251673 1.029907 -0.274450 1.835049 0.199877 0.646328 1.080725 0.210236 1.055491 1.898124 0.072310 0.796446 1.191135) ) ;;; 119 all -------------------------------------------------------------------------------- ; 10.9087 (vector 119 14.502624011553 (fv 0 1 0 0 1 0 0 1 1 1 1 1 0 1 0 1 1 1 0 1 1 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 1 0 0 1 0 1 0 0 1 1 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 1 1 0 0 1 0 1 1 1 0 0 0 1 0 1 1 1 1 0 0 1 1 0 1 1 1 0 0 1 0 1 1 0 1 1 1 0 0 1 0 1 0 1 0 0) 10.894037 (fv 0.000000 0.630386 0.843125 1.285949 0.340650 -0.017357 0.327019 1.384996 1.081793 1.397782 0.680727 0.599720 0.760758 1.651799 1.943215 0.601150 0.438753 0.220032 0.283706 0.321338 1.848806 -0.818805 1.279239 0.233383 -0.265065 0.149488 0.866113 1.211455 -0.153192 1.086507 -0.117739 0.108345 0.296077 0.924788 0.407609 0.257469 1.108157 0.337516 1.501434 -0.160734 0.937661 1.194914 0.677862 1.064411 -0.083066 0.280209 0.164734 0.604351 1.488726 0.546557 -0.173942 0.258452 -0.144704 1.931749 1.121694 0.070973 1.246077 0.433607 -0.015989 1.447158 1.307009 0.290513 1.032586 0.483509 0.866614 0.896091 0.118763 0.703456 1.160811 -0.272718 1.618947 0.922379 0.186934 0.444686 0.391527 -0.170445 0.686201 0.072390 -0.083273 0.261424 1.315326 1.343146 -0.078550 0.581799 0.100158 0.342044 0.531455 0.823995 0.311378 0.398507 -0.067564 1.021721 0.099971 0.375472 1.694822 -0.129069 0.760774 0.760279 0.907128 1.373425 1.265414 0.699858 -0.214864 -0.228584 1.101084 1.533737 1.209100 1.477560 0.508584 0.989498 0.862450 0.271802 1.549833 0.881136 1.017209 0.041014 1.240632 1.019564 1.718786) ;; pp: 10.835933 (fv 0.000000 0.654099 1.035661 1.681354 0.271205 0.793039 1.296335 0.060400 0.653112 1.232942 1.881379 0.620355 1.199841 0.014260 0.823834 1.413032 0.189484 0.947478 1.588848 0.403300 1.280378 0.215388 1.137801 1.956237 0.732861 1.657436 0.792204 1.789188 0.703767 1.598762 0.539735 1.541253 0.421443 1.469357 0.779053 -0.021286 1.026341 0.083226 1.233425 0.357509 1.441485 0.752264 1.858411 1.012419 0.073105 1.341491 0.748507 0.322726 1.533912 0.715880 0.027861 1.454725 0.694006 -0.082536 1.358750 0.823835 0.158492 1.802363 1.289166 0.871603 0.288280 1.653699 1.258131 0.754564 0.197129 -0.135159 1.406727 1.305489 0.902560 0.505625 0.165621 1.980298 1.711088 1.181402 1.035732 0.515951 0.573196 0.077979 0.369360 -0.029664 0.027976 1.710591 1.639472 1.419449 1.489927 1.072898 1.080212 0.909135 0.903629 1.096948 0.947039 1.126463 1.358955 0.953854 1.137457 1.170488 1.431020 1.393091 1.493097 1.708464 0.028863 0.359918 0.447603 0.693507 1.013920 0.980939 1.193095 1.522944 -0.124582 0.421795 0.849849 1.081289 1.559178 0.036966 0.454552 0.747770 1.437228 1.496079 0.068555) ) ;;; 120 all -------------------------------------------------------------------------------- ; 10.9545 (vector 120 14.534638752286 (fv 0 0 0 0 0 1 0 1 1 0 1 0 1 1 1 0 1 1 1 1 1 1 1 1 0 1 0 0 0 0 0 1 1 0 0 1 1 1 0 0 1 1 0 0 1 1 1 0 1 0 0 0 1 1 1 1 1 0 0 0 0 0 1 1 1 0 1 0 1 1 1 0 0 1 1 1 0 0 1 0 1 1 0 0 0 1 0 1 1 0 0 1 1 0 1 1 0 1 0 1 1 1 0 0 1 1 1 1 1 1 1 0 1 0 1 1 0 1 0 0) 10.877907 (fv 0.000000 1.760966 1.432317 0.661698 0.093764 0.677833 1.324379 0.560678 0.084000 1.893101 0.982568 0.231983 0.030976 1.869849 0.114160 0.803943 1.697252 0.187259 0.348967 1.325837 0.129934 0.628168 -0.292961 -0.172670 0.424548 1.491809 -0.230282 0.327899 -0.371234 1.709483 0.949653 0.922124 1.730156 1.323261 1.332457 0.313981 1.342414 0.100580 0.697678 0.026744 -0.054235 1.341652 -0.009876 1.698348 0.248931 -0.183551 1.470018 1.710913 1.251473 0.727247 1.872729 0.011341 0.025061 0.694946 1.531659 0.478715 1.097259 0.657341 1.219034 0.633776 0.382770 0.377028 0.092620 0.800796 0.434789 0.301288 0.942251 -0.118601 -0.116547 1.180657 1.270834 0.986907 0.237837 0.780073 1.628870 -0.280374 -0.194405 0.622013 0.090032 1.411166 0.490814 -0.298299 1.291149 1.730249 1.587675 1.193266 0.285035 0.236562 1.437795 0.582458 1.521211 0.605547 0.877830 1.441130 1.061898 0.936396 1.257893 0.016398 -0.126771 0.102714 1.392810 1.183106 1.832099 1.740994 0.232560 0.367779 0.656921 -0.130561 0.093991 0.079826 0.694300 1.076720 1.076648 -0.154506 1.074489 -0.219932 0.141670 -0.212932 0.458505 1.362796) ) ;;; 121 all -------------------------------------------------------------------------------- ; 11 (vector 121 14.184466362 (fv 0 1 0 1 0 1 1 0 0 0 0 1 1 1 1 0 0 1 1 1 1 0 0 1 0 0 1 0 0 0 1 1 0 1 0 1 0 1 1 1 1 1 0 0 0 0 1 1 1 1 1 0 0 1 0 0 1 0 1 1 0 1 1 1 1 1 1 1 0 1 0 1 1 0 1 1 0 1 1 1 0 0 0 1 0 1 1 1 0 1 0 0 0 1 0 0 0 1 1 0 1 0 1 1 0 0 0 1 0 0 0 0 1 0 0 0 1 1 1 1 1) 10.924906 (fv 0.000000 1.021993 1.334449 0.689448 0.491891 0.317117 0.185100 1.316740 0.942417 -0.055518 1.467945 1.216575 0.460144 1.613483 1.346938 0.351666 1.534737 1.166463 0.663385 1.751743 0.887304 0.686057 0.353407 0.640903 0.247744 0.051185 1.683771 0.607042 -0.642997 1.586265 1.428130 1.293714 0.376348 1.687396 1.342115 1.114987 0.421788 0.173805 0.664896 0.744172 1.338635 0.611663 0.948619 1.727026 0.108093 1.757613 1.759583 0.684030 0.701845 0.897975 1.291554 1.678993 -0.010218 1.672340 1.419180 0.531998 1.055064 0.071044 -0.158722 1.660752 -0.273616 1.601063 0.212433 0.488138 0.674057 0.101023 0.258204 0.323292 0.370652 0.521650 1.206457 1.206236 0.768851 0.204856 0.771378 0.971274 -0.207666 0.711434 0.295654 1.831769 0.464965 1.896472 0.968538 0.024673 1.250922 1.351355 0.486851 0.833273 1.147617 1.669210 0.770997 -0.072413 0.463363 1.323688 1.050580 1.732192 0.819244 0.777660 1.040697 0.078135 0.787038 1.358361 0.700196 0.074501 0.587042 0.515371 1.216302 0.852496 0.581485 0.849691 1.814480 1.077357 0.162962 0.766524 -0.151640 0.240975 0.296067 0.314628 1.286198 0.210485 0.583580) ) ;;; 122 all -------------------------------------------------------------------------------- ; 11.0454 (vector 122 14.536 (fv 0 1 1 0 0 0 1 1 0 0 1 1 0 0 0 0 1 0 0 0 1 0 1 1 1 1 1 1 0 1 1 1 1 1 0 1 0 1 0 0 1 1 1 1 0 1 1 1 1 1 0 0 1 0 0 0 1 1 1 1 1 0 1 1 0 1 1 0 0 0 1 0 1 0 1 1 1 0 0 0 1 0 0 1 0 1 1 0 1 0 1 1 0 0 1 1 1 1 1 0 1 0 1 1 1 0 0 1 0 1 1 0 0 0 1 1 1 1 1 0 0 0) 10.949841 (fv 0.000000 1.704153 0.121290 0.688837 1.244030 1.262068 -0.197896 0.413249 1.197451 1.272156 0.642587 1.292432 1.783982 0.043702 1.158291 1.164647 1.692639 1.493672 1.007369 1.436042 1.725774 0.880017 0.375925 1.616969 0.128447 1.149978 1.084930 0.463608 1.105848 1.530070 1.424718 0.719589 0.763768 0.288678 1.156946 0.691396 0.064365 0.469636 1.091974 0.426323 1.090313 0.491849 0.938048 1.656418 0.459182 0.976494 0.376276 1.451323 1.601769 -0.407170 0.538990 1.732338 0.050678 1.192103 0.536699 0.739148 1.592439 -0.026377 0.032581 0.995911 0.348311 -0.030558 1.293098 0.192261 0.610689 1.016189 0.912642 1.102218 1.291663 0.930392 1.417016 1.312774 1.826696 0.250091 0.993926 0.681381 0.628174 0.441959 1.489842 0.532045 1.179384 0.517873 0.125155 1.064841 1.980073 0.744857 1.235778 1.280286 1.634199 -0.058763 1.206383 1.265460 1.054717 0.853628 1.196638 0.872935 -0.314369 0.468836 0.081998 0.420778 1.325508 1.934649 1.587718 1.251054 -0.176641 -0.893762 0.381112 0.198904 0.283702 1.674181 1.521739 0.754893 1.659031 0.756575 0.235790 -0.129516 1.697508 -0.350053 0.868125 -0.095111 1.099831 0.951722) ) ;;; 123 all -------------------------------------------------------------------------------- ; 11.0905 (vector 123 14.67458183944 (fv 0 0 1 1 1 0 0 1 1 1 1 1 0 1 1 0 1 1 0 0 1 1 0 0 1 1 1 1 0 0 1 0 1 0 1 0 0 0 1 1 0 1 1 1 0 1 1 1 1 1 0 0 1 0 0 0 1 1 0 0 0 1 1 1 1 1 1 0 1 1 0 1 1 0 1 0 1 1 0 1 0 1 1 1 1 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 1 0 1 1 0 1 0 0 1 0 0 0 0 0 1 0 1 0 0 0 1 0 1) 11.089811 (fv 0.000000 -0.095705 0.502046 0.843201 1.262416 0.051297 -0.136069 1.229943 0.769550 -0.394544 1.202311 0.030935 0.212789 0.180234 1.202646 1.847334 1.298798 1.298567 0.826116 1.899995 0.130966 0.229988 0.849236 1.354957 0.175337 -0.090289 1.376955 0.986456 0.858952 -0.348674 -0.073167 -0.218495 1.696358 1.036669 1.130688 0.308330 0.510630 1.786938 -0.105214 0.654929 1.564764 1.314058 0.677163 -0.213165 1.538085 0.616182 0.862650 0.165337 -0.034200 1.035704 0.813627 1.106006 1.740931 0.014126 1.052235 0.657556 1.858826 0.165758 0.630519 0.409633 -0.040211 1.543795 1.391268 -0.071463 1.608090 0.360070 -0.066709 0.298864 0.437480 -0.144723 -0.061475 0.229100 1.150525 0.049068 -0.178297 1.796933 1.253507 1.460767 1.254789 1.053122 -0.014640 1.158719 1.833281 -0.100606 1.043660 0.125118 1.383020 0.234098 0.814218 -0.263454 1.710640 0.541462 0.096383 0.540963 -0.022417 0.505975 1.860187 1.286017 0.269581 0.338845 0.988364 0.065927 0.952682 1.381585 1.156408 1.384314 0.622434 1.536785 0.876899 0.457680 0.787662 1.764741 0.741434 -0.166817 0.104157 0.779344 1.374068 1.055092 1.250202 1.254085 1.185506 -0.050283 -0.314919) ;; pp: 11.016135 (fv 0.000000 0.647630 1.074276 1.756268 0.251422 0.804135 1.421127 0.040524 0.665959 1.111755 1.848209 0.635476 1.226811 0.078653 0.744267 1.473903 0.238865 0.830996 1.602610 0.483888 1.291535 0.032720 0.918740 1.769630 0.682055 1.658606 0.644590 1.383351 0.360438 1.331009 0.396705 1.499558 0.394585 1.332297 0.284286 1.367163 0.697156 1.873754 1.072911 0.259822 1.429562 0.401628 1.434105 0.713387 0.052744 1.073687 0.172805 1.418890 0.502359 0.008598 1.451186 0.715950 -0.032063 1.332938 0.645483 -0.170523 1.375389 0.799087 0.277881 1.623936 1.051516 0.728226 0.326139 1.759949 1.287776 0.814001 0.247394 -0.079677 1.277221 1.247278 0.815434 0.548501 0.120625 1.806890 1.668828 1.491775 0.975860 0.670802 0.343501 0.107101 -0.116370 1.739084 1.782173 1.584916 1.517015 1.084964 1.270093 0.937194 1.142225 0.603049 0.902612 0.582213 0.697513 0.723238 0.854795 0.946568 1.173389 0.894182 1.104017 0.982296 1.332899 1.077929 1.505566 1.771677 1.766832 0.125556 0.284805 0.740017 0.785432 0.946551 1.254134 1.343675 1.825955 0.281285 0.688963 0.928919 1.510642 0.002528 0.243797 0.692027 1.356775 1.422418 -0.003671) ) ;;; 124 all -------------------------------------------------------------------------------- ; 11.1355 (vector 124 14.607 (fv 0 0 0 1 0 1 1 1 1 0 0 0 1 1 1 1 1 0 0 1 0 1 1 0 0 1 1 0 1 0 1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 1 0 0 1 1 0 1 0 1 1 0 1 0 1 1 0 0 1 0 0 1 0 1 1 1 0 1 0 1 1 1 0 1 0 1 1 1 0 1 1 0 0 1 1 1 1 1 0 0 1 0 1 1 1 1 0 1 1 0 0 0 0 0 0 0 1 1 1 1 1 0 1 1 1 0 0 0 1) 11.060270 (fv 0.000000 0.155441 1.710148 0.675606 0.991885 0.930398 0.521431 0.244313 1.630742 0.168790 0.137270 0.000305 -0.043062 0.897696 0.964832 0.045064 0.425268 0.964217 1.290413 0.929170 0.235812 1.335949 0.057667 0.001006 1.068524 0.446791 1.393120 0.549817 1.466180 -0.642251 1.637204 0.595543 0.457077 0.355722 0.196249 1.437718 -0.302241 1.024336 1.392207 1.340742 0.398137 0.737820 0.315317 0.261053 0.730496 0.895111 0.489074 0.360451 1.441085 0.496392 1.486058 1.322042 1.007323 -0.126599 0.931744 1.784266 0.161232 0.306266 0.415406 0.681040 1.790701 0.980642 -0.005904 1.343074 0.136975 0.027551 -0.124807 1.525812 0.151673 1.852354 0.924568 1.280951 0.029602 0.736180 1.201925 0.667470 1.226105 0.326690 0.609507 -0.393588 1.467285 1.671123 1.358186 0.541731 1.122604 1.867616 -0.473631 -0.417534 0.660754 1.837680 1.546497 0.596764 1.110785 0.215660 0.434300 0.180279 1.110604 0.505631 1.274765 1.668673 0.193680 0.673308 0.543007 1.365849 -0.310522 0.237117 0.174423 1.731063 0.766964 0.281277 -0.402143 0.989963 0.637238 0.526844 0.787012 1.257855 0.717061 0.758671 0.882050 1.342356 0.626910 1.083549 0.608055 0.472324) ) ;;; 125 all -------------------------------------------------------------------------------- ; 11.1803 (vector 125 14.985 (fv 0 0 0 0 1 0 0 1 0 0 1 1 0 0 0 1 0 0 1 0 1 1 1 1 1 0 0 1 0 1 1 1 0 0 1 0 0 0 1 1 0 1 0 1 0 1 0 1 1 1 1 1 0 1 0 1 1 0 1 0 0 1 1 1 0 0 0 1 1 1 0 1 0 0 0 0 1 0 0 0 0 0 1 1 1 0 0 1 1 0 0 0 0 1 0 0 0 1 1 0 1 0 1 1 1 1 1 0 0 0 0 0 1 0 0 1 0 0 1 0 0 0 0 1 0) ;; 11.16794 11.160786 (fv 0.000000 1.015332 1.208067 1.409127 0.622612 0.043137 0.789070 0.545823 0.370412 0.925346 1.157620 0.165772 1.424901 0.898702 1.656211 0.988303 1.801194 1.470568 1.745983 0.609307 -0.597689 0.731241 -0.142723 0.984230 0.073162 1.875752 0.335696 1.602183 0.142368 0.017160 0.448032 0.120103 0.041279 0.523055 0.073650 1.053879 -0.306921 1.513911 1.101021 1.602539 -0.121119 0.641316 -0.004631 1.595461 1.743817 0.418939 0.589672 1.179156 0.811957 1.197450 1.342788 1.287174 1.574681 1.241671 0.609625 0.929510 0.079585 0.612922 1.100363 0.431650 -0.459913 0.120058 0.264463 0.028955 1.140993 0.787792 1.007154 0.514281 1.114045 1.286846 1.241625 0.916235 0.449091 1.255016 0.869776 0.016192 1.421914 1.225032 1.302610 0.650162 0.956126 0.761196 -0.213826 0.222275 -0.426223 1.123082 0.506980 1.405113 0.081703 0.828457 1.262806 1.843366 0.399948 0.473729 -0.529905 1.215838 1.003418 1.687511 0.432881 1.055890 1.071502 1.087648 0.147867 -0.002533 0.317269 1.612891 -0.180768 1.003458 1.820527 0.761821 1.137143 0.352919 -0.090034 1.456553 0.819912 0.115658 0.246973 0.936701 1.319554 0.851128 1.479387 0.046130 1.488656 0.854373 0.867709) ;; pp.scm: 11.105486 (fv 0.000000 0.668250 1.004851 1.665604 0.270207 0.823031 1.317389 1.895775 0.442735 1.092420 1.706335 0.316469 1.053513 1.851731 0.426377 1.214568 0.111950 0.768130 1.567897 0.318224 1.096474 0.028789 0.851033 1.730934 0.518266 1.394840 0.485490 1.534760 0.346603 1.302654 0.195595 1.075240 0.149474 1.131730 0.186045 1.296000 0.352391 1.439364 0.663850 1.837274 0.958873 0.121068 1.316333 0.242865 1.517748 0.747235 1.882566 1.040766 0.534079 1.729417 0.993163 0.496721 1.811700 1.002981 0.317419 1.678987 0.959753 0.256596 1.817235 1.299690 0.756280 0.292629 1.822282 1.254136 0.905795 0.232927 1.675869 1.252625 0.924210 0.377830 0.081344 1.650592 1.565111 1.210398 0.823930 0.495597 0.170992 -0.097351 1.629713 1.238397 1.141529 0.804262 0.860680 0.603481 0.666502 0.428034 0.395443 0.132689 1.849680 0.035737 1.395931 1.824957 1.358060 1.651982 1.606952 1.718179 1.670215 1.887548 1.688422 1.844666 -0.292284 0.050366 -0.101906 0.075572 0.305815 0.606639 0.913420 1.030088 1.512470 1.549064 1.827384 0.007726 0.106419 0.461039 0.753337 1.221334 1.792974 0.097112 0.617097 1.170484 1.176316 1.664541 0.165974 0.635539 1.022624) ;; pp1: 11.114689 (fv 0.000000 0.681978 1.028261 1.706912 0.292133 0.848775 1.343922 1.911777 0.451105 1.069054 1.693074 0.301918 1.035579 1.825832 0.435611 1.230581 0.111624 0.750696 1.574421 0.321180 1.071098 -0.013053 0.852483 1.783026 0.524168 1.371392 0.475241 1.562570 0.337915 1.270461 0.221125 1.100498 0.123076 1.107894 0.160645 1.270692 0.306224 1.479440 0.658107 1.838424 0.945824 0.091726 1.332313 0.238983 1.552958 0.749521 1.839061 1.045392 0.486297 1.712081 0.982243 0.539957 1.767541 0.934362 0.293124 1.675620 0.993763 0.206674 1.792070 1.270778 0.729123 0.284390 1.801314 1.282266 0.918468 0.252050 1.650401 1.232066 0.903570 0.313672 0.087588 1.657912 1.543341 1.232872 0.839991 0.464849 0.196039 -0.147366 1.653544 1.258396 1.123045 0.770121 0.900031 0.618800 0.692026 0.397188 0.475351 0.152075 1.894219 0.030184 1.418582 1.854056 1.299662 1.631587 1.652019 1.730754 1.687797 1.916199 1.730490 1.823361 -0.277080 0.063403 -0.121338 0.021902 0.284828 0.586626 0.860176 0.999715 1.490642 1.510249 1.792225 0.008814 0.113621 0.391836 0.733891 1.237143 1.809005 0.128227 0.638952 1.175937 1.156619 1.663599 0.187027 0.654280 1.021025) ) ;;; 126 all -------------------------------------------------------------------------------- ; 11.224972 (vector 126 14.67419786533 (fv 0 0 1 0 0 0 0 1 1 0 1 1 1 1 1 1 0 0 1 1 0 0 1 1 1 0 0 1 0 1 0 0 1 1 1 1 1 0 1 1 0 0 0 1 0 1 1 0 1 0 1 1 0 1 0 1 0 1 0 0 0 1 1 0 0 0 0 1 0 0 1 1 0 1 0 1 0 0 1 1 1 1 1 1 1 0 0 0 1 1 1 0 0 0 0 0 1 1 1 0 1 0 1 1 0 0 1 0 0 1 0 0 1 1 0 1 0 0 0 0 1 0 0 0 0 0) 11.145483 (fv 0.000000 0.899293 0.378495 1.289186 0.777288 0.858338 1.619831 1.737202 1.951674 0.835017 -0.087625 1.707725 0.328507 0.828194 -0.110415 0.084984 1.000160 0.933659 1.329981 0.403112 1.465299 0.867776 0.736209 0.286670 0.614444 0.936369 0.873213 0.123325 0.103437 0.033532 0.337773 1.704277 1.195946 1.204920 1.015411 0.867778 0.772767 0.521662 1.281071 0.987342 0.207100 0.684428 0.579999 1.230109 0.833339 0.874869 1.325709 1.214223 -0.039340 1.273384 0.554903 0.324879 0.897065 0.122734 0.357179 1.405113 1.382262 1.052698 1.093027 0.696151 1.256101 1.113094 1.329670 0.549960 1.774690 1.419208 1.188823 1.415491 0.266597 0.476692 0.360990 0.613975 1.834829 -0.016278 0.893804 0.177235 -0.162182 0.465943 0.846924 0.105182 0.478317 0.762411 0.169998 0.509253 1.306498 1.829812 0.517679 0.137251 1.279904 1.030500 -0.049960 1.650399 1.720514 0.164442 0.994973 1.525343 0.937775 1.609285 1.534911 -0.677300 0.133781 0.129445 0.518965 -0.144758 1.037002 1.052666 0.841376 0.157786 1.034141 0.219735 1.379782 0.222272 1.298276 0.072801 0.604052 1.220954 0.022881 1.817683 0.809301 0.789103 1.114921 0.656136 -0.111384 0.132814 1.271527 0.712891) ) ;;; 127 all -------------------------------------------------------------------------------- ; 11.269427 (vector 127 14.851 (fv 0 0 1 0 0 1 0 0 1 1 1 0 1 1 1 1 0 1 1 1 1 0 0 1 1 0 0 0 1 0 1 1 0 1 0 1 0 0 1 1 1 0 0 0 0 0 1 1 0 0 0 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 0 1 0 1 1 1 0 1 1 0 1 1 0 1 1 0 0 1 0 1 0 1 0 1 0 1 1 1 1 1 0 1 0 0 0 0 1 0 1 0 1 1 0 0 1 1 0 0 1 0 0 0 0 1 0 1 0 1 1 0) 11.176112 (fv 0.000000 1.071888 1.248428 0.289874 1.246619 0.289572 1.760445 0.245569 1.154033 1.309416 0.081159 1.849794 1.710269 1.368867 1.052576 -0.398246 -0.001522 1.370275 0.292491 1.626710 1.166078 1.755696 1.227481 0.377631 0.354241 0.127104 0.305667 -0.167076 0.018149 1.234977 0.220914 0.373111 0.199191 1.136953 0.209502 1.631334 0.736118 -0.280026 0.637855 0.997502 0.069226 0.738973 1.836372 1.422035 0.641751 0.717645 0.227787 1.627490 0.896625 1.164185 1.181473 0.283052 0.793654 1.893617 0.958053 1.877395 0.211241 0.448741 0.465207 1.415492 1.261864 1.182640 0.217781 0.211053 1.936678 0.848219 1.690040 -0.183682 -0.275325 0.916325 0.426519 1.353568 0.171309 0.590049 0.503441 0.438773 0.014163 -0.062159 0.869887 -0.128424 0.144319 1.756020 1.717018 -0.046012 0.125572 0.279523 0.175456 1.083651 1.091291 1.212635 1.168385 1.392580 -0.189037 0.240170 0.866374 1.580620 1.749254 1.502399 1.243019 0.251600 -0.018231 1.414780 0.773115 0.067214 1.323483 0.617886 1.663914 0.351482 0.571589 1.123483 1.679985 0.501109 1.035832 1.346170 1.289512 1.663306 0.584848 0.500505 -0.031006 0.055228 0.131713 1.510949 0.309811 1.293736 1.414224 0.248635 1.517857) ) ;;; 128 all -------------------------------------------------------------------------------- ; 11.313708498985 (vector 128 15.138 (fv 0 1 1 0 1 0 0 1 0 0 0 0 1 0 1 1 1 1 0 1 0 0 0 1 0 1 1 0 1 0 0 0 1 0 0 1 0 0 0 1 1 1 1 1 1 0 1 0 0 1 1 0 0 0 1 0 0 1 1 1 1 0 1 1 1 1 1 0 1 0 1 1 0 1 1 1 1 1 1 1 0 1 0 0 0 1 1 0 0 0 0 1 0 0 1 0 0 1 1 1 0 1 0 1 0 0 1 1 1 1 0 0 0 0 1 0 0 1 1 1 1 0 0 1 0 0 1 1) 11.309209 (fv 0.000000 1.243323 0.073338 1.687189 1.124666 1.389841 0.847573 1.018728 0.290645 0.447958 0.152825 0.408946 1.554733 1.027824 0.742595 1.417320 1.174719 0.230635 0.137711 0.205770 -0.223930 -0.484352 0.868175 0.460794 0.073208 1.470166 -0.048840 -0.141098 1.057707 1.534980 0.337573 1.200647 1.372018 -0.041548 0.602859 1.849030 -0.103678 0.815675 0.107720 0.796671 0.027496 0.761821 1.113332 0.855622 0.650295 0.713381 0.490023 1.179238 -0.088446 0.282357 -0.437849 1.210715 1.321994 0.443637 1.300839 1.352381 -0.001933 0.442309 -0.088426 0.287664 0.126405 -0.108646 0.637631 0.580452 1.256195 1.182134 1.382836 1.180662 1.171900 0.353945 1.569554 0.076717 1.316852 1.092094 0.641656 0.578236 1.268290 1.296116 0.291194 1.287832 1.351802 0.877933 0.046043 0.135350 0.952936 1.137202 0.623256 -0.396801 0.327118 0.077316 0.800999 0.673083 1.387941 0.952139 1.436716 0.326423 0.697455 0.564179 1.047968 0.663414 0.327317 0.386236 0.415974 0.266450 1.112215 0.646830 0.208505 1.019398 -0.208967 0.964650 0.120229 1.347295 1.011374 1.053660 1.549663 0.688863 1.745386 0.772703 1.031951 0.182902 0.350269 0.873751 1.129081 1.610214 -0.035633 1.365829 0.190640 1.177284) ;; pp: 11.210356 (fv 0.000000 0.529477 1.092204 1.655320 0.240176 0.840083 1.290316 0.036113 0.414482 1.184815 1.733487 0.475904 1.226699 -0.054687 0.544000 1.373024 0.096261 0.605273 1.510542 0.229851 0.972933 -0.008717 0.768966 1.800241 0.536684 1.336088 0.309226 1.164728 0.254148 1.069819 0.021808 0.945032 -0.039508 0.972460 -0.067607 1.002895 0.197048 1.366967 0.351763 1.540663 0.648980 1.698360 0.730857 0.118485 1.274417 0.283223 1.327398 0.691807 0.012365 1.128647 0.533746 1.871605 1.252479 0.321809 1.476722 1.286815 0.557929 1.863054 1.365020 0.715719 -0.012609 1.699347 1.092581 0.354365 -0.098429 1.602411 1.106114 0.622866 0.186170 1.647857 1.109362 0.904818 0.566992 0.283406 1.734276 1.302248 1.135583 0.996099 0.637141 0.319233 -0.334659 -0.051454 1.363705 1.553533 1.027907 1.065457 0.795998 0.486251 0.704843 0.431262 0.496789 0.160271 0.268391 -0.277422 -0.064873 -0.149375 -0.202682 0.078495 -0.086833 -0.064332 0.234996 -0.109719 0.180200 0.196396 0.559877 0.436602 0.563596 0.942230 1.157161 1.450532 1.353287 1.969232 0.307428 0.330752 0.455679 0.656549 1.076389 1.439415 1.817226 0.185723 0.623808 1.021760 1.554273 1.872894 0.258818 0.595831 0.908779 1.816125) ) ;;; 256 all -------------------------------------------------------------------------------- (16) (vector 256 23.353 (fv 0 0 1 1 0 1 1 1 1 1 1 0 1 0 0 1 0 0 1 1 1 1 1 0 0 0 0 1 0 1 0 0 0 0 0 0 1 1 0 0 0 0 1 0 0 1 1 1 1 1 0 1 1 1 1 1 0 1 0 1 0 1 0 1 0 0 1 0 0 1 0 0 1 0 1 1 0 1 1 0 1 0 1 1 0 0 1 0 1 0 1 1 1 0 1 1 1 1 1 0 0 1 0 1 0 1 0 0 0 0 1 1 0 1 1 0 1 1 1 0 0 0 1 1 0 0 0 0 0 0 0 1 0 1 0 1 0 0 0 0 0 0 1 1 0 1 0 1 0 1 0 0 1 1 1 0 0 1 1 0 0 0 0 1 1 1 0 0 0 1 0 0 1 1 1 0 1 0 1 0 1 0 0 1 0 1 0 1 1 0 0 0 0 1 1 1 1 1 1 1 1 0 1 0 0 0 1 0 0 0 1 1 1 1 1 0 0 1 1 0 0 1 1 1 0 1 1 0 0 0 1 1 1 0 0 1 1 0 0 1 0 0 1 0 0 1 0 0 1 1 0 0 1 0 0 1) 16.061041 (fv 0.000000 0.925796 0.374630 -0.108513 -0.821698 -0.025087 -0.506195 0.298783 0.035173 0.012160 0.459017 0.128871 0.955347 -0.719489 0.827601 0.829509 -0.132131 0.534593 0.213472 -0.471818 -0.764121 0.240055 -0.480081 0.847706 -0.032870 -0.481128 0.761455 -0.211601 0.010004 0.568923 -0.059172 -0.017957 0.170478 -0.613989 -0.042068 -0.938552 -1.012251 0.796792 -0.038645 -0.426760 -0.192132 -0.528083 -0.017037 -0.489368 0.355556 0.515110 0.821955 -0.244212 -0.238511 -0.789603 0.734511 0.783320 0.368778 -0.600810 0.581954 0.316603 0.874508 -1.013265 0.262565 0.824972 0.323390 -0.162260 -0.116223 -0.866816 -0.634726 0.764949 -0.318122 0.145813 0.067938 0.841588 -0.127386 -0.237218 -0.267186 -0.539198 0.835759 -0.143418 0.496218 0.887615 0.191628 0.011726 -0.612239 0.722732 -0.991602 0.938142 -0.612137 -0.577649 0.191369 -0.198359 0.337475 0.755205 0.683654 -0.318641 -0.814741 -0.354751 0.276257 0.469693 0.801805 -0.420187 0.880092 -0.544351 -0.948063 -0.889987 0.198598 -0.517903 -0.352606 -0.663604 -0.191808 -0.767415 -0.712906 0.924699 -0.850674 -0.237297 -0.047403 0.885741 -0.631553 0.768862 -0.094846 0.448006 -0.666459 -0.850386 0.514580 0.225037 0.511035 0.964534 -0.769372 0.838413 0.741093 0.377443 0.167837 0.877026 -0.054752 0.586836 -0.861511 1.030824 -0.288593 -0.124961 0.009157 -0.927185 0.163383 0.645894 -0.013717 -0.492535 -0.082090 0.437620 0.389280 -0.586666 0.905444 -0.102217 0.591427 -0.168941 0.306715 0.219495 -0.472513 -0.146685 0.752590 0.629396 0.714907 -0.507356 -0.442117 0.799056 0.422576 0.662410 -0.341174 -0.732367 0.014039 -0.183894 0.905125 -0.870456 -0.053268 -0.141515 -0.799646 0.336566 -0.304144 0.389935 0.399830 0.307027 -0.871155 0.107846 0.738408 -0.473227 0.903561 -0.708458 0.732745 -0.039953 -0.750947 0.595806 0.272676 0.007716 0.005802 0.007590 0.079344 0.221588 -0.936127 -0.035027 0.033764 -0.726372 -0.868892 0.770707 -0.383408 -0.651714 0.527250 -0.719737 0.519993 0.226575 0.223677 -0.873550 0.461070 0.964642 -0.617656 -0.035337 -0.800003 -0.139782 0.456176 0.867699 -0.523192 0.078855 0.641942 -0.831683 0.649701 -0.186292 0.569982 -0.772489 -0.286347 -0.113877 -0.219001 0.574600 0.095286 0.790223 0.375659 0.208137 0.644267 -0.013565 0.348413 -0.089854 0.753366 0.482545 0.088959 0.879933 -0.175976 0.137202 0.015772 0.222959 -0.016971 -0.184196 0.277924 0.739236 -0.669637 -0.868483 0.795679 0.675602 0.826275 0.073079 0.690996 0.894373 0.004910 0.425706) ;; pp: 16.350377 (fv 0.000000 0.552796 0.999754 1.596338 0.126332 0.673759 1.143594 1.786231 0.239358 0.837076 1.376094 -0.027483 0.557207 1.197707 1.840730 0.374019 1.046415 1.758004 0.340195 0.989599 1.620624 0.260723 0.941286 1.573013 0.271552 0.902927 1.633570 0.349820 1.063867 1.825055 0.557595 1.306577 0.088807 0.790267 1.529892 0.294932 1.020408 1.744984 0.604757 1.412603 0.281886 1.100728 1.889905 0.686280 1.553865 0.453907 1.302529 0.100750 0.984465 -0.035558 0.826606 1.720865 0.586422 1.445731 0.436162 1.366180 0.314278 1.261198 0.174270 1.139476 0.076878 0.981955 0.014752 1.001254 0.023464 1.025553 0.021016 1.003733 0.047800 1.070120 0.227544 1.225662 0.275497 1.290238 0.339903 1.445648 0.643098 1.696622 0.736906 1.856892 0.946479 0.080466 1.251303 0.348155 1.578331 0.792557 1.845915 0.951067 0.268564 1.510384 0.657787 1.813775 1.031959 0.320499 1.463662 0.701523 0.024031 1.255492 0.480762 1.684919 1.051974 0.424109 1.601000 0.892871 0.243024 1.614521 1.010751 0.221241 1.491807 0.862210 0.215650 1.557126 0.968758 0.385009 1.808699 1.162553 0.511515 1.916283 1.311004 0.789593 0.295563 1.706075 1.087230 0.543068 0.069395 1.561470 0.989040 0.453388 -0.108044 1.480909 1.040634 0.572985 0.051211 1.625308 1.183041 0.686760 0.302383 1.860622 1.529645 0.987474 0.557505 0.084969 1.853756 1.336365 0.952019 0.595441 0.210294 1.971086 1.605010 1.282084 1.025620 0.569157 0.327228 1.866582 1.606594 1.434632 1.017654 0.911350 0.391676 0.232063 0.001884 1.730059 1.574735 1.286832 1.121780 0.801569 0.646973 0.508234 0.242177 0.255472 1.901657 1.795256 1.544468 1.353518 1.252299 1.049061 0.957214 0.842369 0.785364 0.631556 0.708280 0.450967 0.377024 0.408728 0.166649 0.302099 0.202780 0.096226 0.047151 -0.060241 -0.054511 -0.141528 0.011242 -0.035439 -0.105943 -0.008495 0.261657 -0.027784 0.212454 0.144202 0.244055 0.276291 0.439789 0.497793 0.528548 0.655999 0.693233 0.786857 0.888896 1.103132 1.128106 1.412355 1.557348 1.790407 1.883313 0.127747 0.354527 0.531053 0.664039 0.693143 1.026705 1.248860 1.533013 1.656903 -0.153410 0.211226 0.477106 0.861202 1.107385 1.382365 1.702920 1.856715 0.292313 0.666914 1.015054 1.228045 1.584336 1.886548 0.103276 0.465850 0.933761 1.404258 1.699106 0.163965 0.511514 0.978218 1.466876 1.813824 0.330510 0.850353 1.126689 1.666255 0.008649 0.560148 1.018515 1.617664) ) ;;; 512 all -------------------------------------------------------------------------------- (22.627) (vector 512 34.212551772691 (fv 0 0 1 1 0 0 0 0 1 0 0 0 1 0 0 1 0 0 1 1 0 0 1 1 1 0 1 1 1 0 0 1 1 1 0 0 1 1 1 0 1 0 0 0 0 1 1 1 0 0 1 0 0 1 1 0 0 1 0 0 0 1 0 1 1 1 0 1 0 0 1 0 0 1 0 0 0 0 0 1 1 0 0 1 0 1 0 0 0 0 1 0 0 0 1 0 1 1 1 1 1 0 1 1 0 1 1 1 1 0 0 0 0 0 0 1 1 1 0 0 1 0 0 0 0 1 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 1 0 0 1 1 1 0 0 1 0 1 1 0 0 1 0 1 0 0 1 1 1 0 1 0 0 1 0 0 1 0 0 0 1 0 1 1 0 0 0 1 1 1 0 0 0 0 1 1 1 0 1 0 0 1 1 0 1 0 0 0 0 0 0 1 0 0 0 1 1 0 1 0 1 0 0 0 0 1 1 1 0 0 0 0 0 0 0 1 0 1 1 0 0 1 0 0 0 1 0 1 0 0 1 1 1 0 0 1 0 1 1 1 1 0 1 1 1 1 0 0 1 0 0 1 0 0 1 1 1 1 0 0 1 1 1 1 0 0 0 1 0 0 0 1 1 1 0 0 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 0 0 0 1 0 0 1 0 1 0 1 1 1 1 0 0 1 0 0 1 1 0 1 0 1 1 0 0 0 1 0 1 1 0 0 1 1 1 0 0 1 0 0 1 1 1 1 0 0 1 0 1 1 1 1 1 1 1 0 0 0 1 0 1 1 1 0 1 0 1 1 1 1 0 1 0 1 0 1 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 1 0 1 1 0 1 0 1 1 0 0 1 1 0 0 0 1 0 0 1 1 0 0 0 0 1 0 0 0 0 1 1 0 0 0 0 1 0 1 0 0 1 0 0 0 0 0 0 0 1 0 0 1 0 1 0 1 1 0 1 1 1 0 0 1 1 1 1 1 0 0 0 0 1 1 0 0 0 0 1 1 1 0 1 0 1 0 0 1 0 0 1 0 0 1 1 1 0 0 0 0 0 1 0 1) ;; from (try-all :all 512 513 1.0491155462743 0.38189660798029) = 28.3830 23.664022 (fv 0.000000 0.427568 1.639326 1.360155 1.811218 1.092160 0.747868 1.186461 0.447302 0.141557 0.619324 1.833463 1.544347 0.007451 1.194940 0.942391 1.467079 0.598818 0.341862 0.856599 -0.009623 1.790305 0.303605 1.433809 1.210097 1.744422 0.850431 0.701542 1.184133 0.353157 0.158700 0.631775 1.816582 1.649038 0.151955 1.319099 1.140756 1.686037 0.836885 0.603284 1.210040 0.328240 0.128897 0.747775 1.857031 1.647146 0.229954 1.360640 1.181891 1.738203 0.916825 0.772560 1.263892 0.487557 0.357369 0.837989 0.072479 1.952904 0.462538 1.655604 1.530780 0.044826 1.188380 1.093422 1.643465 0.760457 0.671146 1.165553 0.382517 0.270309 0.819071 0.053545 1.937012 0.495125 1.742677 1.542501 0.125650 1.325748 1.210027 1.732088 0.935701 0.824564 1.323484 0.585708 0.506420 1.029721 0.338323 0.187075 0.760806 0.050676 1.850037 0.464992 1.677973 1.565113 0.144103 1.317521 1.321113 1.874238 1.016306 1.069091 1.608386 0.796518 0.769622 1.333499 0.614032 0.483343 1.064146 0.380172 0.255809 0.868411 0.110092 0.019745 0.602426 1.831203 1.791424 0.362161 1.643680 1.595486 0.149263 1.495555 1.407870 1.984422 1.287342 1.186467 1.794990 1.091502 0.997302 1.627715 0.925839 0.869778 1.436400 0.757469 0.721612 1.297170 0.565566 0.560684 1.139226 0.428000 0.421240 0.966706 0.319226 0.330813 0.889093 0.219241 0.195335 0.812296 0.094799 0.052902 0.683712 0.010896 1.971130 0.608327 1.935753 1.931121 0.569627 1.867175 1.867249 0.441783 1.801138 1.790921 0.371408 1.777986 1.738617 0.401066 1.733047 1.661490 0.354101 1.627871 1.606589 0.288724 1.577834 1.666020 0.321728 1.651393 1.656482 0.323319 1.730257 1.617220 0.293458 1.714829 1.659553 0.344931 1.670147 1.687943 0.352602 1.662557 1.707106 0.369928 1.772978 1.748463 0.482487 1.829720 1.820057 0.586300 1.834899 1.928514 0.630781 1.937126 0.006886 0.678213 0.089703 0.093158 0.772429 0.211946 0.205897 0.907314 0.295511 0.339317 1.025320 0.390289 0.436223 1.172670 0.563140 0.575421 1.326146 0.743539 0.740636 1.478962 0.859750 0.923341 1.622809 0.996123 1.103566 1.788348 1.176067 1.280213 -0.047092 1.383754 1.395483 0.152500 1.517048 1.632989 0.388897 1.741484 1.847120 0.652366 0.024054 0.131465 0.878250 0.336434 0.307596 1.072008 0.542503 0.578597 1.334996 0.751250 0.821777 1.656098 1.025574 1.190055 1.955170 1.316203 1.418474 0.154347 1.615247 1.696950 0.413353 1.897018 -0.040080 0.750302 0.194941 0.311683 1.127700 0.508014 0.639251 1.420913 0.883930 0.954476 1.736379 1.219406 1.363982 0.067216 1.594026 1.696195 0.520754 1.968937 0.073197 0.846293 0.295874 0.412637 1.264631 0.683696 0.770777 1.578119 1.049706 1.256677 0.075650 1.516235 1.661663 0.486701 1.923042 0.102476 0.897895 0.421239 0.520799 1.398872 0.764863 0.918394 1.741709 1.285842 1.432958 0.285406 1.740186 1.875561 0.693279 0.189999 0.363512 1.130608 0.742662 0.877597 1.690466 1.167157 1.260179 0.095687 1.647656 1.862836 0.750171 0.242633 0.398738 1.269810 0.693295 0.943617 1.819562 1.329456 1.523078 0.289946 1.903623 0.046720 0.919252 0.382106 0.589683 1.382685 1.026289 1.195161 0.073095 1.610391 1.738812 0.696675 0.192997 0.388398 1.259408 0.742094 1.024183 1.864212 1.458122 1.534179 0.402744 -0.061224 0.271156 1.098904 0.634032 0.812991 1.726192 1.349800 1.524054 0.405111 1.914339 0.225666 1.134052 0.737598 0.871970 1.836536 1.374934 1.616164 0.466416 0.050312 0.256071 1.130926 0.806016 0.967517 1.857501 1.430024 1.677286 0.624674 0.171527 0.493105 1.331230 0.893429 1.180472 0.103949 1.752760 1.965087 0.889376 0.401019 0.670116 1.685650 1.210490 1.475318 0.371575 0.023405 0.308232 1.175094 0.785590 1.015636 -0.029618 1.589597 1.841867 0.744953 0.423044 0.654663 1.649721 1.235327 1.552140 0.505770 0.153285 0.430626 1.295928 0.916060 1.261458 0.277022 1.879571 0.086016 1.069989 0.709985 0.993888 -0.020550 1.578106 1.903961 0.873960 0.405819 0.766821 1.720050 1.395240 1.689328 0.591580 0.237019 0.518171 1.489451 1.175876 1.436552 0.419316 0.110972 0.456395 1.431851 1.135703 1.433153 0.412157 0.047498 0.368496 1.359894 0.994487 1.371051 0.374236 -0.007165 0.356413 1.341081 0.997966 1.348371 0.388959 0.042648 0.317800 1.336452 1.006864 1.349497 0.415416 0.057830 0.422080 1.335388 1.091374 1.397964 0.381417 0.219147 0.454116 1.473546 1.128064 1.458934 0.561157 0.201897 0.582036 1.638190 1.188476 1.678318 0.658219 0.380328 0.735596 1.749438 1.526079 1.911184 0.877724 0.628235 0.991698 0.058067 1.723282 0.138422 1.198701 0.866452 1.210404 0.321220 0.058540 0.420700 1.466851 1.211297 1.555352 0.603793 0.342675 0.773740 1.815254 1.579109 1.942762 1.000717 0.737614 1.114407 0.230063 0.006013 0.382590 1.515868 1.246214 1.651494 0.773676 0.514207 0.940214 0.045277) ) ;;; 1024 all -------------------------------------------------------------------------------- (32) (vector 1024 54.490282136658 (fv 0 0 0 1 0 1 0 1 1 1 0 1 0 1 1 1 0 1 0 0 0 1 1 0 0 1 1 0 0 0 1 0 1 0 0 0 0 0 0 1 0 1 0 0 1 1 0 0 0 1 0 0 0 1 1 1 1 0 0 1 0 0 0 0 1 0 1 0 0 1 0 1 0 0 1 1 1 1 1 0 1 1 0 0 0 1 1 1 0 0 0 1 1 0 1 0 0 0 0 0 1 0 1 1 1 1 1 0 1 1 1 1 1 1 0 0 0 1 1 1 1 0 1 0 1 1 1 1 0 1 1 1 1 1 1 1 0 1 0 1 0 1 0 0 0 1 1 1 1 1 1 1 1 1 0 1 0 1 1 1 1 1 1 0 1 1 0 1 0 1 1 0 0 0 1 0 0 1 1 0 0 0 0 1 1 0 0 0 1 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 0 0 1 0 1 1 0 1 1 1 1 1 0 0 1 1 1 1 0 1 1 1 1 0 1 1 0 0 1 1 1 0 0 1 1 0 0 0 1 1 0 1 1 1 0 1 1 1 1 1 1 1 1 1 0 1 1 0 1 1 0 0 0 0 0 1 0 0 0 1 1 0 1 1 1 1 1 1 0 0 0 0 0 1 0 0 0 1 0 0 1 0 0 0 0 0 1 1 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 1 0 0 1 0 1 0 0 1 1 1 0 0 0 0 1 0 1 1 1 1 0 1 0 1 0 1 0 0 1 1 1 0 0 0 0 1 1 0 0 1 0 0 1 0 0 1 1 0 0 0 0 1 1 0 0 0 1 1 1 1 0 1 1 0 0 1 1 1 1 1 1 0 1 1 0 0 0 0 0 1 1 0 1 0 1 0 0 0 1 0 1 0 1 1 1 1 0 1 1 0 1 1 0 1 1 0 1 1 1 0 0 1 1 0 1 1 0 0 1 0 0 1 0 0 0 1 0 1 0 0 0 1 1 0 1 1 1 0 1 0 1 1 0 0 0 0 1 1 1 0 1 1 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 1 0 1 0 1 0 0 1 0 0 0 1 0 1 1 0 1 1 0 1 1 1 0 1 0 1 1 0 1 0 0 0 0 1 1 0 0 0 0 1 0 1 1 0 1 0 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 1 1 0 0 0 1 0 0 1 0 0 1 1 1 0 0 0 1 1 0 1 1 1 0 1 0 1 0 1 0 1 1 0 0 0 1 1 0 1 1 1 1 0 1 1 0 1 1 0 1 1 1 0 0 1 1 0 0 0 0 1 0 1 1 1 1 0 1 0 0 0 0 0 0 1 0 0 1 1 1 1 1 1 0 0 0 1 0 1 1 1 0 0 0 0 0 1 1 0 0 0 1 0 1 1 0 0 1 0 0 0 1 1 0 0 1 1 0 1 0 1 0 1 1 1 0 1 1 0 0 1 1 0 1 0 0 0 1 0 0 1 1 0 0 0 1 1 1 0 0 1 0 1 0 0 0 0 1 0 0 1 1 0 1 0 1 1 1 1 0 1 0 0 1 1 0 0 1 0 0 0 0 1 1 0 0 0 1 1 0 0 0 0 0 1 1 1 1 1 0 0 1 0 1 1 0 1 0 0 0 1 1 1 0 1 0 1 0 1 0 0 1 1 1 0 1 0 0 1 1 1 0 1 1 1 1 0 0 1 1 1 0 0 1 0 0 0 1 1 1 0 1 0 1 1 0 0 1 0 1 0 1 1 1 1 1 0 0 0 1 1 1 0 0 0 0 1 1 1 0 1 1 0 1 0 0 1 1 0 0 0 1 1 0 1 1 0 0 0 0 1 1 1 0 0 0 1 1 0 1 1 1 0 0 0 0 1 0 0 0 1 0 1 1 1 1 0 1 0 1 0 0 1 0 0 0 0 0 1 1 1 0 1 0 0 1 0 0 1 1 1 0 0 1 1 0 1 1 0 0 1 0 0 1 1 0 0 0 1 0 1 1 0 0 1 1 0 1 1 1 0 1 1 1 0 1 0 0 0 0 0 1 1 0 1 0 0 1 1 1 0 0 0 0 0 0 1 0 1 0 0 1 0 1 1 0 1 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 1 0 1 1 0 1 1 1 1 0 1 0 1 0 0 0 0 1 0 0 1 0 0 0 1 0 1 0 0 0 1 0 1 0 1 1 1 1 0) ;; from (try-all :all 1024 1025 0.0030465754082342 1.0966230312279) = 39.6408 -- starting point for next 33.410875 (fv 0.000000 0.258148 0.589168 0.994411 1.357701 1.683025 0.069074 0.453421 0.797628 1.185816 1.582436 1.938092 0.307108 0.753155 1.054506 1.465084 1.815186 0.241264 0.539120 0.935358 1.344730 1.757342 0.087826 0.560243 0.909870 1.313450 1.644065 0.104593 0.476633 0.874522 1.288326 1.742330 0.203193 0.590704 1.014919 1.387211 1.858546 0.251755 0.613119 1.088831 1.500246 1.956678 0.355205 0.836294 1.268025 1.705878 0.108690 0.586645 1.046489 1.430729 1.904826 0.322624 0.787698 1.277011 1.718145 0.125412 0.585092 1.047194 1.448174 1.936035 0.420374 0.902587 1.333104 1.856924 0.327896 0.858579 1.268399 1.749900 0.253263 0.677442 1.219161 1.714857 0.177166 0.633557 1.169787 1.640415 0.140512 0.621582 1.091651 1.607728 0.104564 0.583756 1.118053 1.652294 0.153513 0.714859 1.194251 1.697620 0.276971 0.782347 1.313258 1.816056 0.294830 0.852045 1.367731 1.912889 0.443181 0.976528 1.489519 0.048647 0.602555 1.171111 1.696946 0.267367 0.808494 1.328988 1.847036 0.429147 0.989539 1.554476 0.119989 0.631320 1.259112 1.823414 0.393440 0.968836 1.504033 0.126560 0.727472 1.269985 1.846490 0.405486 1.041942 1.582030 0.184859 0.803907 1.384064 0.001185 0.565238 1.185485 1.799966 0.388364 0.991281 1.615016 0.210322 0.777733 1.381829 -0.001858 0.601802 1.237656 1.865352 0.533475 1.133402 1.742192 0.420236 1.017900 1.625681 0.265207 0.907047 1.531875 0.165179 0.869961 1.486073 0.135412 0.775460 1.391805 0.032701 0.662061 1.355447 -0.029896 0.673845 1.349264 0.011611 0.729065 1.361114 0.013249 0.666596 1.353522 -0.007100 0.647754 1.363243 0.014621 0.674314 1.412588 0.079158 0.792604 1.491853 0.154571 0.839031 1.536947 0.216086 0.941461 1.657001 0.337150 1.060668 1.746479 0.482706 1.226119 1.946733 0.643851 1.336905 0.013042 0.754294 1.496162 0.232890 0.988475 1.681309 0.448137 1.146402 1.881464 0.552981 1.297819 0.098645 0.832913 1.606715 0.332666 1.035466 1.818940 0.554955 1.343968 0.085509 0.792214 1.558162 0.368596 1.106235 1.895172 0.644633 1.405521 0.165480 0.925201 1.747451 0.473692 1.324609 0.053177 0.850917 1.628773 0.424746 1.258663 0.036370 0.797966 1.564071 0.352485 1.148447 -0.002783 0.797088 1.561969 0.392501 1.189092 -0.019088 0.843646 1.634513 0.453206 1.275296 0.054828 0.916548 1.733451 0.558960 1.389762 0.203638 1.054862 1.897500 0.708809 1.574733 0.423071 1.215266 0.027342 0.899322 1.791858 0.620622 1.492274 0.320845 1.174701 0.051833 0.913009 1.796449 0.665146 1.471491 0.328743 1.193965 0.076732 0.978576 1.811604 0.666355 1.562427 0.437112 1.309285 0.223487 1.113773 0.007247 0.849622 1.753745 0.664875 1.576770 0.455394 1.360922 0.282060 1.150668 0.049047 0.927118 1.816088 0.739465 1.705374 0.642039 1.518132 0.405444 1.340122 0.312878 1.226245 0.139772 1.077510 -0.018816 0.936435 1.857875 0.823248 1.722658 0.669787 1.630579 0.550282 1.483551 0.473002 1.439850 0.374042 1.322563 0.264157 1.241756 0.176119 1.137549 0.127690 1.073354 0.045113 0.987362 -0.009728 0.938618 1.894769 0.930534 1.889094 0.819648 1.834591 0.887814 1.825305 0.751612 1.788639 0.781856 1.799187 0.761171 1.765995 0.797679 1.787953 0.747401 1.771597 0.793400 1.786941 0.805798 1.801885 0.838640 1.863755 0.878598 1.883687 0.921909 -0.012600 0.953576 0.028661 1.053164 0.071002 1.090274 0.114661 1.146587 0.180317 1.267377 0.271949 1.348847 0.373158 1.422115 0.472335 1.601819 0.584885 1.638612 0.781047 1.776789 0.821569 1.888293 0.973656 0.059587 1.102322 0.189225 1.264548 0.323677 1.429081 0.526711 1.594088 0.678108 1.711258 0.856227 1.948913 1.030332 0.171134 1.248971 0.337083 1.456252 0.496413 1.599787 0.743435 1.845411 0.979199 0.069456 1.191262 0.312034 1.362623 0.533174 1.673105 0.803847 1.903793 1.042569 0.150816 1.299359 0.434192 1.602414 0.715947 1.838326 1.018218 0.157768 1.253948 0.407857 1.573899 0.779851 1.904361 1.060636 0.223176 1.356991 0.495392 1.680203 0.833630 0.009780 1.167530 0.315957 1.492554 0.654024 1.856891 1.023069 0.220534 1.440206 0.582264 1.748500 0.970294 0.123193 1.307613 0.556564 1.730012 0.926711 0.113171 1.343735 0.556253 1.746273 0.934223 0.123997 1.384091 0.614003 1.782610 1.015379 0.224947 1.465548 0.684093 1.908440 1.124583 0.358057 1.642940 0.875505 0.064339 1.292308 0.557537 1.782713 1.008802 0.272821 1.511713 0.764842 0.030194 1.274549 0.483182 1.727237 1.016792 0.261776 1.522862 0.796446 0.042895 1.304520 0.619998 1.876690 1.148478 0.428322 1.679455 1.004325 0.300377 1.550416 0.835254 0.173352 1.448704 0.698650 -0.033801 1.272024 0.597214 1.859218 1.200705 0.517289 1.763401 1.106977 0.387334 1.700638 1.066989 0.326662 1.604820 0.962763 0.281408 1.585892 0.935892 0.271981 1.571275 0.916662 0.291788 1.570649 0.930716 0.269192 1.579444 0.969565 0.290012 1.615565 0.990795 0.311402 1.657094 0.994116 0.432873 1.757318 1.056873 0.417532 1.795268 1.185595 0.580763 1.918349 1.267276 0.656331 0.049168 1.401813 0.749992 0.176783 1.556953 0.966950 0.314017 1.682209 1.095751 0.473881 1.821750 1.291249 0.673330 0.057423 1.460592 0.890407 0.273536 1.708953 1.094797 0.541733 1.932285 1.354523 0.747235 0.170227 1.592085 1.015544 0.439882 1.847343 1.288875 0.701630 0.111506 1.621007 1.032815 0.491968 1.882621 1.348432 0.738302 0.277658 1.682524 1.144243 0.582029 0.024994 1.499949 0.920010 0.401061 1.889106 1.372403 0.804920 0.264480 1.729722 1.190624 0.695948 0.173617 1.607894 1.119209 0.625052 0.097713 1.558780 1.044363 0.564907 0.006836 1.535288 0.979484 0.498306 0.016897 1.518916 1.048287 0.505482 0.034846 1.537224 1.038826 0.583381 0.066441 1.582671 1.095360 0.652592 0.165653 1.666405 1.195978 0.749638 0.244931 1.794728 1.302261 0.855517 0.402763 1.919243 1.506054 0.990141 0.529140 0.090161 1.628924 1.232711 0.756188 0.320069 1.866574 1.434290 1.010093 0.586649 0.125842 1.632778 1.248832 0.786217 0.395146 1.983594 1.522744 1.184214 0.725738 0.283806 1.853291 1.411973 1.029503 0.623510 0.190003 1.817951 1.405723 0.998692 0.625566 0.196526 1.824631 1.367636 1.002432 0.638505 0.270362 1.867749 1.456887 1.107903 0.666557 0.365450 1.943932 1.534564 1.164468 0.812181 0.417778 0.109315 1.746468 1.348757 1.018766 0.607455 0.251719 1.902085 1.522432 1.168361 0.826689 0.501772 0.186624 1.829613 1.504989 1.149945 0.826038 0.430311 0.156773 1.805915 1.442117 1.129384 0.789359 0.448838 0.128070 1.860262 1.509251 1.221965 0.897472 0.558148 0.251257 1.927642 1.640546 1.338781 1.036792 0.710068 0.403207 0.109563 1.811625 1.572455 1.213598 0.939472 0.623448 0.409350 0.066783 1.811153 1.483733 1.240294 0.962497 0.677702 0.428980 0.151873 1.860959 1.600097 1.372939 1.073698 0.858833 0.549541 0.358709 0.048040 1.780703 1.499339 1.321408 1.026078 0.811519 0.563815 0.272950 0.101217 1.778901 1.584563 1.357171 1.096114 0.901285 0.691896 0.423414 0.187540 0.012408 1.741503 1.538220 1.375071 1.132353 0.924933 0.712966 0.501385 0.301492 0.064052 1.847152 1.740905 1.454340 1.287762 1.094301 0.900958 0.693746 0.504913 0.275695 0.137705 -0.008305 1.750189 1.585524 1.414196 1.262553 1.013251 0.925388 0.715978 0.553457 0.407454 0.213702 0.088434 1.972600 1.762556 1.622037 1.422263 1.305690 1.086572 0.965745 0.818250 0.679809 0.548833 0.434281 0.274574 0.162711 -0.016721 1.874108 1.711171 1.634760 1.470116 1.433824 1.198309 1.122645 0.994884 0.863715 0.716974 0.651737 0.505774 0.376030 0.305317 0.172395 0.043840 1.956668 1.879928 1.790226 1.657792 1.628858 1.503591 1.453387 1.399691 1.283663 1.175444 1.093586 1.015878 0.867180 0.833771 0.733456 0.751208 0.644973 0.524402 0.519350 0.448915 0.402270 0.223991 0.272710 0.178576 0.121816 0.014901 -0.008456 0.000722 1.948116 1.864026 1.799285 1.772492 1.761973 1.729645 1.648114 1.613644 1.601091 1.593669 1.506616 1.533589 1.464454 1.452519 1.424863 1.443072 1.448035 1.385776 1.402879 1.416069 1.400653 1.366739 1.389222 1.353373 1.316055 1.338545 1.366489 1.376447 1.387658 1.386874 1.383521 1.414816 1.478876 1.431144 1.443821 1.476250 1.453501 1.470783 1.513891 1.537062 1.574083 1.565440 1.667183 1.688265 1.726029 1.812251 1.818225 1.909534 1.893859 1.960853 -1.792261 0.049720 0.115471 0.168584 0.227816 0.312337 0.320765 0.432479 0.460834 0.497553 0.618812 0.667533 0.714551 0.786901 0.873018 0.948666 1.026741 1.049685 1.177075 1.308478 1.411491 1.456896 1.608694 1.673563 1.762266 1.858920 1.974208 0.033942 0.165671 0.243992 0.350794 0.473925 0.585735 0.737599 0.804002 0.963652 1.066959 1.216838 1.312134 1.446813 1.594176 1.676806 1.816313 1.965577 0.113977 0.201793 0.324796 0.449133 0.633633 0.769013 0.895692 1.061461 1.163832 1.372251 1.483231 1.640906 1.802011 -0.030958 0.155600 0.377255 0.507459 0.640650 0.847956 1.016719 1.214303 1.427027 1.567855 1.764212 1.940432 0.043642 0.292095 0.470854 0.648508 0.820657 1.060906 1.222563 1.354202 1.598601 1.737516 -0.028100 0.202713 0.374375 0.584831 0.817057 1.020703 1.253416 1.457146 1.644498 1.875195 0.140343 0.371551 0.579412 0.847798 1.090746 1.313318 1.565314 1.779179 -1.706782 0.198770 0.511497 0.711566 0.950424 1.152889 1.372135 1.700365 1.869801 0.181432 0.440942 0.691235 0.983921 1.186243 1.477055 1.750551 0.035866 0.314930 0.558441 0.801324 1.080423 1.361289 1.616783 1.906440 0.211190 0.450778 0.806041 1.119162 1.408538 1.703492 0.007343 0.317836 0.612325 0.935395 1.211907 1.545362 1.855618 0.133582 0.501303 0.746887 1.072480 1.396132 1.651845 -0.008716 0.328392 0.710493 1.027135 1.346260 1.695106 0.085660) ) ;;; 2048 all -------------------------------------------------------------------------------- (45.254) (vector 2048 89.570060996356 (fv 0 1 1 0 0 1 1 0 0 1 1 1 0 0 0 1 0 0 0 0 1 1 0 1 0 0 1 1 1 0 1 0 1 1 1 0 0 1 0 1 0 0 1 1 0 1 1 0 1 0 1 0 0 0 1 1 1 1 0 0 0 0 1 0 1 1 1 1 0 1 0 0 1 0 1 0 0 1 0 1 1 1 0 0 1 0 1 0 1 0 1 1 0 1 0 0 1 0 0 1 0 0 1 1 0 0 1 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 1 1 0 0 1 1 1 1 1 1 1 1 0 1 0 0 0 0 1 0 1 0 1 0 1 1 1 1 1 0 1 0 0 0 1 1 0 0 1 1 1 0 0 0 0 1 1 1 0 0 0 0 1 1 1 1 0 1 0 1 1 0 0 0 0 1 1 1 1 0 0 1 1 1 1 0 1 0 1 0 0 1 1 0 0 1 1 0 1 0 0 1 1 1 1 0 1 0 0 0 0 0 0 0 1 1 0 0 1 1 0 0 0 0 0 0 1 0 1 0 1 1 0 1 1 1 0 0 1 1 0 1 1 1 0 1 1 0 1 0 1 1 0 1 0 0 1 1 0 0 1 0 0 1 0 0 0 1 1 0 1 0 1 1 0 0 1 0 0 1 1 1 0 1 0 1 0 0 1 1 0 1 1 1 1 0 1 0 1 0 1 0 1 1 1 0 1 0 1 0 1 0 0 1 1 0 1 0 1 1 1 0 1 1 0 1 0 1 0 1 1 1 1 0 1 1 1 1 0 0 0 1 0 0 1 1 0 1 1 0 0 0 0 1 0 0 1 0 1 0 0 0 1 1 0 0 1 1 0 0 1 1 1 0 1 0 0 1 1 0 1 0 1 0 1 0 0 1 1 0 0 1 0 1 1 1 1 0 0 1 0 1 0 1 0 0 1 0 1 1 0 0 1 0 1 1 1 0 0 1 0 1 0 1 1 1 0 1 1 1 1 1 1 0 0 1 0 1 1 1 0 1 0 1 1 0 1 0 1 0 0 1 1 1 1 0 0 0 1 1 1 1 1 0 0 1 0 0 0 0 0 1 1 1 1 0 0 0 1 0 0 1 0 1 0 1 0 0 0 1 0 1 1 1 1 0 0 0 1 1 0 1 0 1 1 0 1 0 1 0 1 0 0 0 0 1 0 0 1 1 0 0 0 1 0 1 0 0 1 0 1 0 0 0 0 1 1 0 1 0 0 1 1 0 0 1 1 1 0 0 1 1 1 1 1 1 1 1 0 1 0 1 0 0 1 0 0 1 0 0 0 1 0 1 0 0 1 1 0 0 1 0 0 0 0 0 0 0 0 1 1 0 0 0 1 0 1 1 0 0 1 1 0 0 1 1 0 1 1 1 0 1 1 0 1 1 1 0 0 1 1 0 1 0 1 0 0 1 0 0 1 1 0 1 0 1 0 0 1 0 0 1 1 0 0 0 0 1 1 0 1 0 1 1 0 0 0 1 1 1 1 1 1 0 0 1 0 1 1 1 1 1 0 1 1 0 0 0 0 1 0 0 0 0 0 0 1 1 0 0 1 0 1 0 0 0 1 1 0 0 1 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 1 0 0 1 0 1 1 0 0 1 0 1 1 0 1 1 0 1 0 0 0 1 0 0 0 0 0 1 1 1 1 0 0 0 1 1 0 0 1 0 0 1 1 0 0 0 0 0 1 1 1 0 0 1 1 1 1 0 0 0 1 0 0 1 1 1 1 1 0 0 1 1 1 1 0 1 0 1 0 1 0 0 0 0 1 1 0 1 0 1 0 0 0 0 0 0 1 0 1 0 1 1 0 1 0 1 0 1 0 1 0 1 1 1 1 0 0 0 0 0 1 1 0 0 1 1 0 0 0 0 1 0 1 1 1 1 0 1 1 0 1 0 1 1 1 0 0 1 0 1 1 0 0 0 0 1 1 1 0 1 1 1 1 1 0 1 0 0 0 0 0 1 1 0 0 1 0 1 0 1 1 0 0 1 0 0 0 1 0 1 0 0 1 0 1 0 0 1 1 1 0 0 0 0 0 1 1 0 1 0 1 0 1 0 0 0 0 1 0 0 1 1 0 0 1 0 1 1 1 1 1 0 0 1 0 0 0 1 1 1 1 1 0 0 0 0 1 0 0 1 1 0 1 1 0 1 0 0 1 0 1 1 1 0 1 1 1 0 1 1 0 0 0 0 0 0 1 1 1 1 1 1 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 1 1 1 0 1 1 1 0 1 1 1 1 1 1 1 0 1 0 0 1 1 0 0 1 1 1 1 1 1 0 0 0 0 1 0 0 1 0 1 0 1 1 1 0 1 1 0 0 1 1 0 1 0 0 1 1 1 0 0 0 1 1 1 0 0 0 0 1 0 0 1 0 0 1 0 1 1 1 1 1 0 0 0 0 0 0 0 1 1 0 1 0 1 1 1 1 1 1 1 1 0 1 1 1 1 0 0 1 0 1 0 1 1 0 1 1 1 1 0 1 0 1 0 0 1 0 1 0 1 1 1 1 0 1 1 1 0 0 0 1 1 0 1 0 0 1 0 0 1 0 1 1 1 0 0 1 0 1 0 1 1 1 0 1 0 0 0 1 1 1 1 0 0 1 1 1 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0 1 1 0 1 1 0 0 0 0 0 1 0 0 0 1 1 0 1 0 0 1 1 0 0 0 0 0 1 1 1 0 0 0 1 1 1 1 0 1 0 0 0 0 0 1 1 1 1 0 0 0 1 0 1 1 1 1 0 1 1 0 0 1 1 0 1 1 1 1 1 1 0 1 1 1 1 0 1 0 0 0 0 1 1 0 0 1 0 0 1 0 1 0 1 1 0 0 1 1 0 1 0 1 0 0 1 1 1 1 1 1 0 1 1 0 1 1 0 0 1 1 1 1 0 0 1 0 1 0 0 1 0 0 1 1 1 1 0 0 0 1 0 1 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 1 0 1 0 1 0 1 0 0 1 0 1 1 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 1 0 0 0 1 0 1 1 0 0 1 1 0 1 0 1 1 0 1 0 0 1 1 0 0 1 0 1 0 1 1 0 0 0 0 0 0 0 0 1 0 0 1 0 0 1 1 0 0 0 0 1 0 0 1 1 0 0 1 1 1 0 0 1 0 1 1 0 0 0 0 1 1 1 0 0 0 1 1 0 0 0 0 1 0 0 0 0 0 1 1 0 1 1 0 0 0 1 1 0 1 1 1 0 1 0 0 0 0 0 0 0 0 1 0 1 1 0 1 1 1 1 1 1 1 1 1 1 0 0 1 1 0 0 1 1 1 0 0 1 0 1 1 0 1 1 1 1 1 0 1 1 1 0 1 1 0 1 0 0 1 1 0 1 1 1 0 1 1 1 0 0 0 1 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 1 1 0 0 0 1 1 0 1 1 1 1 1 0 0 0 0 0 0 0 1 1 0 1 0 1 0 1 1 0 0 0 0 0 0 1 1 1 1 0 0 1 0 1 0 0 1 0 0 1 1 1 1 0 1 1 0 0 0 0 1 0 0 1 0 0 1 1 0 0 1 0 0 1 0 1 1 1 0 1 0 0 0 0 1 0 1 0 1 1 1 0 1 1 1 1 1 0 0 1 1 1 1 0 0 1 0 0 0 0 0 1 0 0 1 1 0 1 1 0 1 1 0 1 0 1 0 1 1 1 1 1 0 1 1 0 0 1 1 1 0 1 1 1 0 1 0 1 0 0 1 0 0 1 0 0 1 1 0 1 1 0 0 0 0 0 0 1 0 0 1 1 0 1 0 0 0 0 1 1 1 1 0 1 0 1 0 1 0 1 1 0 0 0 0 1 0 1 0 1 0 1 0 1 0 0 1 1 0 1 0 0 1 0 0 0 0 1 0 0 0 0 1 1 1 1 1 0 0 0 1 0 0 0 0 0 1 1 1 1 0 0 0 0 1 0 1 1 0 0 0 1 0 1 1 1 1 0 1 1 1 1 0 0 1 0 0 1 1 1 1 0 0 0 0 0 0 1 0 1 0 1 1 1 0 0 1 0 1 1 1 1 1 1 1 1 0 0 1 0 0 0 0 0 0 1 1 1 1 0 0 0 1 0 1 1 0 0 0 0 0 0 1 1 0 1 1 0 0 1 1 0 1 1 0 1 1 0 1 0 0 0 1 0 0 1 1 1 0 0 0 0 0 1 0 1 1 0 1 0 0 1 0 0 0 1 1 0 0 0 1 1 0 0 0 1 0 0 1 0 1 1 1 0 0 1 0 0 1 1 0 0 0 0 0 0 1 1 0 1 0 0 1 0 0 0 0 0 1 0 0 1 0 0 1 1 1 1 0 1 0 0 1 1 0 0 0 0 0 0 0 1 0 1 0 0 1 0 0 0 0 1 1 0 0 0 1 1 0 1 1 1 1 0) ;; from (try-all :all 2048 2049 1.0476749041086 0.34832901677121) = 55.7655 start for next 50.205430 (fv 0.000000 0.435841 1.590025 1.333909 1.800782 0.936896 0.640772 1.054371 0.276465 0.022204 0.420173 1.637156 1.317845 1.822696 0.936038 0.684182 1.165979 0.256451 0.034146 0.530882 1.581638 1.361041 1.855482 0.981545 0.775560 1.219427 0.308786 0.074234 0.592840 1.697019 1.456943 1.894603 1.053571 0.870395 1.260578 0.415941 0.216750 0.664998 1.768556 1.530284 0.017758 1.155044 0.880167 1.399032 0.522236 0.296590 0.788933 1.883168 1.702734 0.130840 1.241124 1.015672 1.506862 0.618786 0.413989 0.882191 0.040812 1.770208 0.266965 1.415350 1.179212 1.617452 0.837073 0.560382 1.039153 0.189709 0.008982 0.428192 1.582302 1.375969 1.775847 1.001684 0.722251 1.221935 0.371046 0.124429 0.658497 1.801753 1.557144 0.055429 1.167445 0.965998 1.463160 0.590632 0.421360 0.870506 1.979716 1.785918 0.217687 1.423155 1.229053 1.677639 0.820116 0.622279 1.118801 0.227079 0.047207 0.530002 1.646116 1.495215 1.938348 1.092314 0.858748 1.368355 0.507435 0.300967 0.831830 1.945902 1.701826 0.241789 1.346179 1.176339 1.698123 0.782522 0.593683 1.099893 0.220752 0.071121 0.492713 1.698729 1.537108 0.003593 1.112312 0.923924 1.420945 0.591862 0.368816 0.876237 0.024325 1.841665 0.349974 1.496560 1.313963 1.781383 0.909134 0.778966 1.228602 0.360482 0.169252 0.720535 1.827819 1.642014 0.151850 1.298858 1.132119 1.583582 0.775812 0.613883 1.034899 0.197663 0.038469 0.550873 1.681101 1.473296 0.002756 1.168244 0.976999 1.468806 0.641511 0.472463 0.917530 0.115543 1.932746 0.461045 1.615860 1.421110 1.916591 1.100326 0.915266 1.450442 0.570898 0.409829 0.895347 0.064350 1.886870 0.368337 1.508665 1.402167 1.875808 1.089074 0.915502 1.348721 0.569668 0.334905 0.845366 0.062665 1.931036 0.423161 1.570481 1.376249 1.892683 1.058012 0.892579 1.382946 0.530863 0.389584 0.911546 0.066065 1.944943 0.431750 1.524837 1.397825 1.916894 1.103011 0.925384 1.421598 0.609580 0.450668 0.957299 0.103861 0.017005 0.489835 1.632099 1.491083 0.040341 1.187478 1.048136 1.580660 0.750188 0.526672 1.095701 0.287178 0.103106 0.633176 1.805673 1.635672 0.181746 1.340109 1.155467 1.751104 0.863186 0.725371 1.256183 0.417821 0.247907 0.731305 1.971687 1.812887 0.362885 1.544484 1.346445 1.843347 1.064098 0.903511 1.425141 0.615217 0.470411 0.992301 0.186866 0.055090 0.515270 1.737073 1.613907 0.129315 1.316755 1.145516 1.689159 0.887610 0.688556 1.250192 0.483418 0.277491 0.831631 -0.015312 1.878418 0.427015 1.584482 1.443552 1.963597 1.131045 1.053018 1.569404 0.748022 0.602632 1.105250 0.310334 0.191836 0.693611 1.868001 1.741296 0.244951 1.472171 1.322184 1.879876 1.046328 0.929137 1.487162 0.690252 0.536393 1.028834 0.241099 0.137310 0.681359 1.872418 1.703102 0.276974 1.417116 1.322284 1.892467 1.055982 0.931972 1.453120 0.680784 0.569223 1.072473 0.292525 0.179779 0.702639 1.907779 1.763892 0.296945 1.502504 1.403596 1.895642 1.078898 1.020313 1.582828 0.728374 0.631181 1.177822 0.386973 0.229679 0.763366 -0.020603 1.884762 0.449056 1.615978 1.445670 0.076665 1.319406 1.139316 1.687368 0.868342 0.754364 1.316715 0.562902 0.373746 0.962616 0.143265 0.060537 0.597136 1.794156 1.674512 0.244828 1.423610 1.307469 1.861513 1.128650 1.011922 1.509496 0.793005 0.646450 1.183857 0.401441 0.274501 0.848007 0.152648 1.938838 0.515464 1.751327 1.585203 0.128719 1.344067 1.257980 1.813937 1.034672 0.961830 1.482792 0.710147 0.627952 1.158173 0.396545 0.308224 0.839308 0.084640 1.949979 0.467374 1.766014 1.652675 0.156038 1.404099 1.323696 1.916673 1.129204 1.007203 1.565692 0.792625 0.676519 1.246538 0.476588 0.355046 0.897504 0.154095 0.032713 0.616322 1.822050 1.713319 0.339487 1.549436 1.415806 -0.029700 1.251496 1.105739 1.706293 0.927616 0.827632 1.429701 0.652859 0.511881 1.153658 0.364245 0.227734 0.828965 0.039610 1.955264 0.489121 1.779904 1.680272 0.264792 1.492297 1.379563 1.958496 1.182126 1.073866 1.647475 0.887025 0.759908 1.352711 0.598690 0.504193 1.064292 0.364855 0.256068 0.821048 0.072182 1.978457 0.553596 1.801077 1.686861 0.245374 1.501095 1.463244 0.048757 1.270724 1.195638 1.795159 0.991907 0.929823 1.498115 0.775504 0.635637 1.221022 0.502033 0.392861 1.015769 0.238715 0.139376 0.772010 -0.001203 1.966386 0.502478 1.754699 1.653913 0.238134 1.455433 1.421962 0.005716 1.237219 1.195953 1.785244 1.034444 0.946973 1.522226 0.772000 0.724085 1.279219 0.566698 0.471639 1.081117 0.318698 0.216243 0.869842 0.093780 0.035928 0.580682 1.866189 1.774688 0.335441 1.640447 1.567092 0.150911 1.385331 1.332318 1.956070 1.197687 1.107245 1.722318 0.935373 0.939612 1.481560 0.775194 0.705562 1.294862 0.556921 0.470799 1.085453 0.374791 0.241371 0.872640 0.127624 0.032808 0.648015 1.958410 1.857207 0.450764 1.687826 1.673077 0.276455 1.524057 1.465118 0.092578 1.331259 1.262485 1.865029 1.129716 1.070468 1.691226 0.954621 0.907368 1.547298 0.800536 0.754442 1.318798 0.655491 0.523948 1.167921 0.458202 0.394916 0.974268 0.209530 0.172260 0.769859 0.045732 -0.027787 0.639418 1.895968 1.831369 0.455565 1.755348 1.702164 0.323430 1.549605 1.507505 0.099809 1.366067 1.343189 1.936579 1.213931 1.207459 1.780054 1.037769 1.005956 1.688129 0.918293 0.876995 1.491983 0.755576 0.731170 1.306379 0.613008 0.560202 1.151819 0.453386 0.401075 1.052899 0.336562 0.307092 0.918155 0.200321 0.133534 0.755336 0.041372 -0.036174 0.643495 1.904976 1.892087 0.486352 1.795593 1.721679 0.369291 1.607795 1.576284 0.213583 1.494045 1.463382 0.080370 1.381980 1.326067 1.977786 1.247994 1.213791 1.878128 1.145632 1.125599 1.744040 1.003768 0.975298 1.655044 0.946812 0.902005 1.481429 0.838355 0.806420 1.384034 0.676425 0.687951 1.289459 0.584933 0.544028 1.143652 0.530696 0.446531 1.060469 0.381371 0.383221 0.985636 0.284345 0.259040 0.894751 0.181035 0.155719 0.802236 0.121624 0.058494 0.696055 -0.033257 -0.009001 0.631717 1.933686 1.907503 0.526027 1.815256 1.827541 0.422361 1.751874 1.770954 0.332622 1.681580 1.649270 0.311710 1.607800 1.583524 0.245744 1.540534 1.499654 0.148625 1.457370 1.373290 0.075021 1.394843 1.347459 -0.005752 1.303682 1.317955 1.926281 1.233373 1.253750 1.868046 1.183593 1.200479 1.828734 1.154318 1.138091 1.739705 1.063036 1.026015 1.760005 1.052209 0.997647 1.670582 1.013683 0.946378 1.618597 0.957911 0.901792 1.567409 0.889999 0.912144 1.559979 0.891151 0.880294 1.500532 0.874896 0.781828 1.470208 0.813331 0.808539 1.418100 0.746813 0.751008 1.419231 0.717221 0.726739 1.410727 0.731944 0.676864 1.409264 0.642315 0.664365 1.364908 0.686123 0.651596 1.257741 0.652814 0.617542 1.306260 0.604389 0.592953 1.273395 0.605575 0.615524 1.252456 0.600454 0.596734 1.273260 0.596265 0.607909 1.252575 0.565927 0.570637 1.242139 0.541616 0.579959 1.248588 0.553529 0.579117 1.248565 0.574621 0.589047 1.309100 0.589822 0.602557 1.287938 0.578939 0.630286 1.280033 0.567074 0.622654 1.240139 0.594827 0.651875 1.291451 0.614140 0.689991 1.288405 0.659401 0.658369 1.319440 0.687094 0.674513 1.346708 0.688976 0.753907 1.375336 0.762674 0.739012 1.414601 0.787609 0.775338 1.420075 0.806180 0.800733 1.486208 0.845147 0.821967 1.516891 0.910404 0.867286 1.542889 0.887043 0.903213 1.634817 0.952223 0.964661 1.682581 0.979874 1.017143 1.672617 0.994877 1.107400 1.788990 1.110961 1.073654 1.789664 1.138909 1.162757 1.815050 1.225817 1.210897 1.926791 1.302244 1.265372 -0.026931 1.330408 1.387907 0.023026 1.451566 1.422994 0.130173 1.484590 1.521586 0.183712 1.551561 1.583662 0.282642 1.591114 1.655077 0.304500 1.684251 1.694195 0.429792 1.769650 1.808357 0.487540 1.818396 1.853851 0.530630 1.955039 -0.119812 0.676604 0.023437 0.063422 0.780580 0.147218 0.198738 0.872448 0.220227 0.252425 0.986952 0.295255 0.393016 1.036257 0.448018 0.427099 1.156162 0.552881 0.530707 1.267911 0.635862 0.680452 1.365591 0.735775 0.797614 1.468054 0.829271 0.858249 1.597356 0.963427 0.979328 1.664777 1.072381 1.131497 1.848461 1.213953 1.199832 1.960555 1.304633 1.318228 0.076788 1.452570 1.479484 0.164500 1.572776 1.636533 0.356533 1.684649 1.726841 0.451773 1.812513 1.874046 0.543934 1.930798 1.972699 0.744026 0.063643 0.159361 0.823095 0.219497 0.299864 0.954777 0.358746 0.414413 1.115727 0.519760 0.542990 1.311137 0.651203 0.710761 1.454950 0.772652 0.872236 1.543810 0.968311 1.006341 1.723434 1.088664 1.231621 1.884135 1.281249 1.347331 0.036078 1.419412 1.446527 0.204240 1.613579 1.679100 0.340114 1.736107 1.840278 0.571743 1.943781 0.023224 0.697394 0.138951 0.151958 0.882054 0.266019 0.342269 1.098555 0.488882 0.520277 1.270261 0.682615 0.682051 1.423350 0.809398 0.923761 1.649263 1.068684 1.091760 1.803833 1.223733 1.263221 0.017517 1.421547 1.466248 0.224731 1.593966 1.649396 0.409457 1.781845 1.845835 0.622136 -0.009609 0.077538 0.792485 0.188358 0.288489 1.013605 0.431185 0.495730 1.211960 0.604816 0.676648 1.456905 0.844139 0.905285 1.630909 1.032426 1.128266 1.853145 1.262038 1.300211 0.056675 1.467598 1.530064 0.291293 1.687552 1.755257 0.468236 1.938565 -0.011915 0.736090 0.173114 0.213450 0.994156 0.364997 0.457458 1.187825 0.639595 0.686838 1.462796 0.854330 0.903639 1.704943 1.071752 1.179798 1.898999 1.338040 1.405342 0.147449 1.639838 1.676028 0.379818 1.815921 1.886234 0.634529 0.079207 0.176862 0.921077 0.270512 0.406031 1.127890 0.593242 0.648029 1.403498 0.841450 0.919674 1.687653 1.135150 1.209027 1.975682 1.393578 1.449497 0.153208 1.639075 1.709636 0.452445 1.874711 0.022432 0.714196 0.206678 0.205405 0.997873 0.413099 0.533511 1.297878 0.703835 0.801048 1.536439 0.962427 1.059551 1.860285 1.319040 1.383017 0.135002 1.534723 1.648532 0.422108 1.844915 1.956976 0.704238 0.117947 0.249102 1.002403 0.473197 0.500625 1.262507 0.728698 0.830758 1.550450 1.042097 1.137051 1.913071 1.319323 1.401617 0.205540 1.634001 1.717675 0.487628 1.929708 0.032724 0.779967 0.225924 0.383724 1.109069 0.562827 0.649848 1.460986 0.840877 0.966680 1.747337 1.203625 1.315331 0.088823 1.496248 1.629011 0.431806 1.822514 1.942005 0.728686 0.158211 0.297041 1.029719 0.522309 0.626677 1.357536 0.800226 0.986575 1.730215 1.163174 1.231016 0.034610 1.521930 1.589379 0.414306 1.841215 1.927232 0.696438 0.186996 0.290301 1.088563 0.519977 0.648216 1.417722 0.845987 1.012127 1.780754 1.219818 1.368384 0.133468 1.552692 1.697685 0.489975 1.948146 0.025352 0.835325 0.308902 0.425789 1.189446 0.647629 0.780553 1.534982 0.953650 1.144994 1.982784 1.383491 1.490496 0.239036 1.733469 1.907366 0.658487 0.109199 0.230682 1.052834 0.517391 0.608626 1.405419 0.866368 0.974067 1.812201 1.250521 1.390848 0.148194 1.623658 1.769017 0.559808 0.019981 0.093630 0.962157 0.385643 0.557254 1.332258 0.775494 0.936936 1.712764 1.224080 1.333572 0.130012 1.553976 1.733749 0.509265 0.048320 0.120671 0.899273 0.371543 0.562577 1.333084 0.820342 0.953357 1.769820 1.220433 1.358228 0.127107 1.579894 1.763318 0.586085 0.056061 0.168973 0.987419 0.437016 0.613035 1.379444 0.892129 1.014623 1.821313 1.267297 1.418105 0.246254 1.755013 1.842641 0.624100 0.156213 0.268757 1.103436 0.559665 0.758240 1.532549 1.036259 1.153852 1.946220 1.432069 1.593807 0.418226 1.855454 0.035725 0.832622 0.314591 0.476792 1.257265 0.773297 0.905003 1.712302 1.200651 1.350735 0.149477 1.642212 1.802991 0.603766 0.109674 0.272495 1.104655 0.552848 0.662208 1.508113 0.969884 1.222187 1.957345 1.483565 1.659081 0.418223 1.951257 0.147291 0.901050 0.444550 0.555960 1.394491 0.833321 1.009746 1.850858 1.330172 1.483655 0.313675 1.811415 -0.000236 0.794841 0.301262 0.490013 1.322742 0.745660 0.925074 1.784514 1.271636 1.375387 0.219194 1.716991 1.919514 0.731082 0.283071 0.394652 1.209183 0.703971 0.883949 1.723347 1.226581 1.417977 0.169502 1.728678 1.897967 0.751809 0.206641 0.351287 1.193966 0.679687 0.833001 1.679398 1.202836 1.369136 0.221180 1.698828 1.890944 0.736466 0.259414 0.428156 1.246968 0.715069 0.887462 1.766067 1.234005 1.366933 0.267319 1.785542 1.921115 0.782951 0.288312 0.432145 1.324227 0.812529 0.987537 1.849387 1.334204 1.550652 0.384742 1.887557 0.032221 0.888154 0.427508 0.583364 1.373198 0.935366 1.078859 1.962687 1.425781 1.648177 0.492137 0.010583 0.174236 1.065860 0.556317 0.711714 1.613293 1.102246 1.261519 0.161159 1.621868 1.845116 0.621649 0.151344 0.408750 1.266111 0.733611 0.981402 1.781143 1.313677 1.478251 0.389746 1.864238 0.058118 0.877935 0.412750 0.590919 1.454967 0.995341 1.160158 0.052979 1.551988 1.735067 0.575701 0.113408 0.309369 1.203349 0.691004 0.901203 1.755113 1.285355 1.469400 0.316179 1.835734 0.063761 0.937353 0.419020 0.615917 1.461648 1.030447 1.209615 0.096211 1.589011 1.815774 0.626322 0.175182 0.402805 1.254295 0.809294 0.981937 1.881195 1.349170 1.565323 0.444505 1.905301 0.141863 1.013394 0.599160 0.768860 1.639481 1.173121 1.378015 0.207298 1.781004 -0.005481 0.841053 0.359648 0.584036 1.466213 1.014043 1.198019 0.047150 1.611088 1.803839 0.693503 0.251733 0.378659 1.292988 0.846097 1.025550 1.895967 1.457063 1.643561 0.544671 0.078331 0.286831 1.144981 0.701288 0.911563 1.800290 1.360060 1.533921 0.464563 1.970167 0.187072 1.028247 0.574824 0.822213 1.719286 1.250441 1.465682 0.304625 1.883042 0.150589 0.966248 0.508969 0.740351 1.592154 1.164985 1.396695 0.251798 1.797977 0.055983 0.893992 0.460716 0.676688 1.575389 1.096148 1.354511 0.224581 1.739098 0.014063 0.882137 0.432033 0.697360 1.575477 1.060614 1.342466 0.184638 1.767539 1.986710 0.880248 0.447116 0.686853 1.534981 1.149302 1.322036 0.217110 1.750455 -0.028293 0.927727 0.463276 0.699948 1.574079 1.122276 1.344937 0.239499 1.798792 0.041111 0.901108 0.502016 0.734564 1.619516 1.235793 1.392027 0.313428 1.875178 0.114986 0.986008 0.554567 0.774672 1.670995 1.277666 1.490688 0.422851 1.938664 0.192686 1.081363 0.636062 0.878896 1.801674 1.320125 1.610705 0.510337 0.119965 0.288198 1.229365 0.736391 0.974652 1.921844 1.522756 1.760341 0.627784 0.195364 0.424026 1.350173 0.914137 1.149417 0.055182 1.641041 1.885754 0.774177 0.341638 0.609082 1.476268 1.075234 1.336728 0.232957 1.816024 0.059891 0.977615 0.583895 0.818725 1.691585 1.233407 1.522719 0.426347 -0.011898 0.222340 1.211913 0.738174 1.037566 1.889523 1.491590 1.769255 0.654387 0.200388 0.477881 1.388587 0.995612 1.263033 0.151400 1.737244 1.994853 0.888393 0.448480 0.715631 1.639779 1.266990 1.475739 0.402022 0.001228 0.277508 1.193996 0.717293 1.022382 1.945731 1.528880 1.769925 0.676796 0.308016 0.544866 1.452245 1.056044 1.374139 0.251435 1.839100 0.082677 1.030130 0.593594 0.869317 1.751919 1.380599 1.660743 0.544875 0.134766 0.419262 1.359116 0.926374 1.200425 0.154745 1.776244 0.028854 0.907934 0.517864 0.744877 1.733023 1.291145 1.589046 0.524515 0.143068 0.380331 1.270800 0.877957 1.158416 0.095496 1.721531 1.962074 0.894065 0.487382 0.748783 1.673707 1.270037 1.572661 0.487139 0.118310 0.353424 1.330880 0.967912 1.217091 0.192030 1.746726 -0.008521 0.972139 0.569214 0.836629 1.792874 1.387645 1.624565 0.632818 0.169837 0.496488 1.391429 1.038248 1.276246 0.204951 1.839860 0.124740 1.060001 0.657481 0.979959 1.891365 1.498561 1.801028 0.717400 0.315222 0.620564 1.593479 1.178952 1.451115 0.404598 -0.005528 0.313885 1.242306 0.875831 1.127959 0.103028 1.705375 0.012699 0.926034 0.577294 0.846113 1.771401 1.375194 1.686187 0.652973 0.275173 0.528957 1.475197 1.099695 1.450803 0.394864 0.006041 0.319714 1.201074 0.888068 1.130526 0.060555 1.730127 0.003973 0.970567 0.557199 0.876983 1.840537 1.453875 1.730436 0.638584 0.293627 0.612145 1.531639 1.167803 1.518469 0.454591 0.106958 0.368985 1.332865 0.982631 1.260304 0.220211 1.799722 0.130226 1.090090 0.701451 1.045234 1.992618 1.626535 1.912666 0.832021 0.542880 0.767909 1.778263 1.387748 1.677161 0.622205 0.269109 0.574635 1.558243 1.182994 1.450696 0.491452 0.103672 0.400119 1.344518 0.981223 1.258072 0.251476 1.912489 0.232691 1.206418 0.805953 1.119358 0.155055 1.751168 0.097851 1.025890 0.706010 0.960410 1.942316 1.626433 1.884328 0.851879 0.504554 0.821261 1.761778 1.407905 1.711340 0.647584 0.347790 0.647152 1.648746 1.244924 1.563845 0.588763 0.158974 0.503437 1.536265 1.121954 1.454121 0.423763 0.114434 0.400278 1.338609 0.993706 1.358821 0.328396 1.956735 0.261393 1.267373 0.955613 1.253328 0.224608 1.856628 0.199058 1.200999 0.819656 1.137486 0.135404 1.793163 0.131100 1.078350 0.741351 1.039393 0.045261 1.699515 0.034737 0.942610 0.684756 0.956308 1.947394 1.633657 1.953278 0.904052 0.580961 0.913879 1.941411 1.519052 1.840622 0.910119 0.527420 0.861293 1.849422 1.475381 1.830601 0.799091 0.501857 0.787766 1.823294 1.467731 1.806424 0.805269 0.474582 0.781946 1.776540 1.418537 1.762883 0.746070 0.408613 0.726389 1.745127 1.428283 1.754540 0.728069 0.441878 0.746600 1.796204 1.449997 1.776429 0.722670 0.436401 0.744719 1.778994 1.480572 1.763916 0.815336 0.489032 0.764749 1.811814 1.487438 1.838366 0.811299 0.501320 0.823771 1.854833 1.502868 1.856794 0.827719 0.514633 0.852477 1.882215 1.488580 1.848649 0.877645 0.587786 0.926814 1.877153 1.575992 1.906019 0.886676 0.595984 0.881146 1.940054 1.606287 1.971408 0.988642 0.638192 0.966941 -0.034374 1.681077 0.038373 1.056408 0.657252 1.076689 0.087476 1.760605 0.121715 1.145163 0.789531 1.173448 0.151127 1.823534 0.220276 1.230586 0.960040 1.285670 0.295263 1.934113 0.314088 1.332202 1.053238 1.375323 0.392866 0.077220 0.422213 1.491168 1.127803 1.497376 0.554172 0.257811 0.586449 1.609325 1.351152 1.703027 0.627074 0.353088 0.709213 1.720064 1.442884 1.782680 0.814896 0.553387 0.852715 1.895941 1.554321 1.962098 1.013833 0.655921 0.994618 0.054934 1.764435 0.062870 1.163046 0.871528 1.257156 0.223435 1.905372 0.338569 1.306277 0.999931 1.337253 0.417104 0.138892 0.412245 1.511698 1.256056 1.543124 0.590173 0.339601 0.650455 1.683826 1.408811 1.811474 0.828456 0.526423 0.859787 1.896452 1.608591 1.948197 0.987654 0.706760 1.085696 0.133347 1.825976 0.258446 1.274079 0.944752 1.296320 0.326958 0.024339 0.456524 1.468787 1.203458 1.509480 0.615416 0.269963 0.688191 1.723537 1.390152 1.854907 0.886894 0.581734 0.936911 -0.009509 1.698888 0.060556 1.142012 0.859242 1.247280 0.274968 1.947669 0.305504 1.435482 1.121364 1.480498 0.522708 0.241328 0.603319 1.705040 1.426237 1.816412 0.844853 0.559458 0.950007 -0.864208 1.718587 0.075844 1.114880 0.838172 1.221123 0.266618 0.058618 0.363782 1.417961 1.157081 1.554190 0.607338 0.348635 0.729484 1.765027 1.524808 1.887413 0.942863 0.666378 1.035608 0.084672 1.857745 0.236807 1.282523 1.041036 1.443839 0.463754 0.200441 0.623163 1.679375 1.373487 1.771844 0.850867 0.606126 0.995693 0.033893 1.821449 0.146087 1.202112 0.961147 1.370514 0.434572 0.169771 0.556607 1.637108 1.396269 1.729452 0.842038 0.609721 0.932603 0.015326) ) )) ;; :all 65536 (320.768635104 1.6604741485419 0.83776099628482) 0.52033682944489 ;; :all 65536 (309.91637906494 0.64007539845073 4.5547029008803e-05) 0.5172334495671 (0) ;; :all 65536 (303.64661814299 1.3570805366568 -4.6971909684279e-05) 0.5153905931919 (200) ;; :all 131072 (438.77509431894 1.4462367399126 2.0944027696821) 0.51631398987158 (sqrt: 362) ;;; ---------------------------------------- odd numbered harmonics ---------------------------------------- (define nodd-min-peak-phases (vector (vector 1 1.0 (fv 0) ) (vector 2 1.539 (fv 0 0) ) ;;; 3 odd -------------------------------------------------------------------------------- (vector 3 1.7548747062683 (fv 0 1 1) 1.7393749801561 (fv 0.0 1.205686890924528215096600547440175432712E0 1.297035953235478072942399307976302225143E0) 1.7387926578522 (fv 0.0 1.2094986438751 1.3025436401367) 1.7387455701828 (fv 0.0 0.79018270969391 0.69699490070343) 1.738745 (fv 0.000000 1.209826 1.303017) 1.738744 (fv 0.000000 0.790172 0.696980) ) ;;; 4 odd -------------------------------------------------------------------------------- (vector 4 2.19460272789 (fv 0 1 0 0) 2.050 (fv 0 39/25 26/29 27/22) 2.048743724823 (fv 0 111/256 281/256 195/256) 2.0466175079346 (fv 0 223/512 563/512 49/64) 2.045218 (fv 0.000000 1.563819 0.899661 1.233860) 2.045217 (fv 0.000000 0.436172 1.100327 0.766122) ) ;;; 5 odd -------------------------------------------------------------------------------- ; 2.2360679 (vector 5 2.7317879199982 (fv 0 1 1 0 0) 2.3731805734023 (fv 0 7/16 7/4 5/8 7/16) 2.307252 (fv 0.000000 0.393369 1.754476 0.596108 0.424804) 2.307253 (fv 0.000000 1.606636 0.245540 1.403918 1.575230) ) ;;; 6 odd -------------------------------------------------------------------------------- ; 2.44948 (vector 6 2.8638670444489 (fv 0 0 0 0 1 0) 2.522759 (fv 0.000000 1.360421 1.129847 1.035439 1.320248 0.102465) 2.522749 (fv 0.000000 0.639403 0.869779 0.964074 0.679243 -0.103102) ) ;;; 7 odd -------------------------------------------------------------------------------- ; 2.64575 (vector 7 2.9204399585724 (fv 0 0 0 1 1 0 1) 2.618497 (fv 0.000000 1.527527 0.524623 0.177241 0.453108 1.577456 1.970355) 2.618376 (fv 0.000000 0.474123 1.477585 1.824644 1.552691 0.429533 0.035303) 2.618302 (fv 0.000000 0.474154 1.477730 1.824846 1.552894 0.429720 0.035636) ) ;;; 8 odd -------------------------------------------------------------------------------- ; 2.828427 (vector 8 3.2507002353668 (fv 0 1 1 0 1 1 1 0) 2.8071956634521 (fv 0 109/128 7/4 1 13/16 123/64 21/128 43/128) 2.790858 (fv 0.000000 0.802399 1.672681 0.887888 0.680265 1.767889 0.004580 0.126233) 2.790799 (fv 0.000000 1.197514 0.327251 1.112061 1.319778 0.232086 -0.004810 -0.126263) 2.790663 (fv 0.000000 1.196617 0.325818 1.109894 1.316877 0.229200 -0.008217 -0.130363) ) ;;; 9 odd -------------------------------------------------------------------------------- ; 3 (vector 9 3.4140722751617 (fv 0 0 1 1 1 1 0 1 0) 2.886575 (fv 0.000000 0.394663 0.625974 1.648922 0.070810 1.803585 1.908749 0.903752 0.378081) 2.886464 (fv 0.000000 1.605518 1.374012 0.351118 1.929257 0.196622 0.091381 1.096286 1.622082) 2.886241 (fv 0.000000 1.605727 1.374318 0.351747 1.930232 0.197770 0.092557 1.097753 1.623786) ) ;;; 10 odd -------------------------------------------------------------------------------- ; 3.162277 (vector 10 3.5391488075256 (fv 0 0 1 1 0 1 0 0 0 0) 3.054055 (fv 0.000000 0.508058 0.119325 0.663858 1.627094 1.847660 0.043999 1.283121 0.512586 0.295891) 3.054035 (fv 0.000000 0.528914 0.163543 0.741593 1.737455 -0.019531 0.179460 1.441592 0.691200 0.513749) 3.054019 (fv 0.000000 1.467927 1.828996 1.243932 0.242207 -0.005741 1.795358 0.528965 1.275954 1.445527) 3.053923 (fv 0.000000 0.530606 0.167556 0.749983 1.748996 -0.005015 0.193787 1.458258 0.709754 0.536958) 3.053807 (fv 0.000000 0.524885 0.155185 0.727764 -0.282439 -0.043214 0.155190 1.412864 0.658810 0.474600) 3.053435 (fv 0.000000 0.525383 0.155614 0.727601 -0.282536 -0.043650 0.155330 1.412909 0.659050 0.474369) ) ;;; 11 odd -------------------------------------------------------------------------------- ; 3.31662 (vector 11 3.6182308197021 (fv 0 0 0 1 1 1 0 1 1 0 1) ; 3.31662 3.177383 (fv 0.000000 1.758655 0.386236 -0.008172 1.159122 0.785208 0.739625 0.606297 1.367332 0.311355 0.827147) 3.177220 (fv 0.000000 0.232935 1.599549 -0.005436 0.822576 1.185453 1.230375 1.357659 0.594255 1.644007 1.122113) 3.177201 (fv 0.000000 1.748294 0.370273 -0.021500 1.141958 0.751903 0.709536 0.566072 1.323348 0.262962 0.769859) 3.177182 (fv 0.000000 1.764972 0.396592 0.001274 1.171590 0.806702 0.760785 0.632485 1.395663 0.343598 0.864498) 3.177098 (fv 0.000000 1.745038 0.362715 -0.030740 1.128748 0.736155 0.690326 0.545405 1.303285 0.236832 0.743503) 3.176608 (fv 0.000000 1.744464 0.362417 -0.030039 1.129933 0.735652 0.691339 0.545454 1.302582 0.237082 0.742494) ) ;;; 12 odd -------------------------------------------------------------------------------- ; 3.464101 (vector 12 4.0 (fv 0 0 1 1 0 0 0 0 0 1 0 1) 3.363698 (fv 0.000000 0.073271 0.585961 0.960666 0.978302 0.113696 1.500041 1.186734 1.772452 0.944338 1.321484 0.602060) 3.362737 (fv 0.000000 -0.077029 1.405769 1.027930 1.006574 1.870564 0.481680 0.791450 0.202834 1.026360 0.648485 1.363973) 3.361884 (fv 0.000000 -0.077168 1.405944 1.028559 1.007566 1.871331 0.482574 0.792122 0.203932 1.027727 0.649507 1.365630) ) ;;; 13 odd -------------------------------------------------------------------------------- ; 3.60555 (vector 13 3.8778836727142 (fv 0 0 1 1 0 0 1 0 1 0 0 0 0) 3.476053 (fv 0.000000 0.380793 0.961293 0.353157 0.446308 0.965358 0.539394 0.172183 -0.067910 0.976833 -0.486927 1.072643 -0.036066) 3.475486 (fv 0.000000 1.620375 1.040657 1.650169 1.557159 1.039441 1.466014 -0.165746 0.075570 1.032228 0.496820 0.937529 0.047188) 3.475452 (fv 0.000000 1.620672 1.042066 1.652912 1.561748 1.044454 1.472771 -0.159565 0.082334 1.041828 0.507070 0.948164 0.058404) 3.474532 (fv 0.000000 1.621213 1.042646 1.653413 1.561849 1.044891 1.473168 -0.158623 0.083544 1.042513 0.507800 0.949479 0.059341) ) ;;; 14 odd -------------------------------------------------------------------------------- ; 3.741657 (vector 14 4.2842662512094 (fv 0 1 1 0 0 1 1 1 0 1 0 0 0 0) 3.606512 (fv 0.000000 0.785150 1.482463 -0.077041 0.773052 0.357080 1.202237 -0.069790 1.584889 0.769902 0.652503 0.409520 0.740393 0.675317) 3.600425 (fv 0.000000 1.139545 0.351170 -0.114733 0.966482 1.234831 0.292454 1.539190 0.009726 0.589539 0.769919 0.798632 0.417679 0.467195) 3.599409 (fv 0.000000 0.851134 1.636505 0.091221 1.006010 0.744090 1.678264 0.418648 -0.048848 1.351639 1.174737 1.143087 1.519418 1.448182) 3.598494 (fv 0.000000 0.850577 1.637081 0.089423 1.006545 0.749551 1.681409 0.420517 -0.044040 1.351533 1.177890 1.148728 1.524043 1.447267) ) ;;; 15 odd -------------------------------------------------------------------------------- ; 3.872983 (vector 15 4.4701427567987 (fv 0 1 0 0 1 0 1 1 1 1 1 0 0 1 1) 3.739752 (fv 0.000000 1.191367 0.176518 1.591145 1.710423 1.309889 1.422724 0.785426 1.754948 1.707551 1.122738 1.744847 0.127913 0.663567 0.776627) 3.738430 (fv 0.000000 1.190239 0.174514 1.589466 1.706591 1.305812 1.416225 0.779885 1.746839 1.699566 1.113488 1.734421 0.117674 0.652032 0.763074) ) ;;; 16 odd -------------------------------------------------------------------------------- ; 4 (vector 16 4.5778832343715 (fv 0 1 1 0 0 0 0 1 0 0 1 1 1 0 1 0) 3.858242 (fv 0.000000 0.144652 0.676444 0.017002 0.269119 1.012194 1.772841 1.585260 1.809100 0.289620 1.399960 0.670537 0.175237 0.296937 -0.017357 1.108803) 3.857020 (fv 0.000000 0.144607 0.675956 0.016527 0.269112 1.012147 1.772535 1.584482 1.808783 0.289484 1.400085 0.669674 0.174650 0.295492 -0.017769 1.108482) ) ;;; 17 odd -------------------------------------------------------------------------------- ; 4.12310 (vector 17 4.5790815353394 (fv 0 1 0 0 1 0 0 0 1 0 0 1 1 1 1 0 0) 3.927805 (fv 0.000000 0.618908 0.864629 1.180783 1.677629 1.929621 0.580975 1.820904 0.468136 1.289907 0.485211 0.029658 1.160895 0.856998 0.644358 0.814931 0.296558) 3.926355 (fv 0.000000 0.619515 0.864447 1.181990 1.677700 1.930862 0.582927 1.823955 0.470265 1.290931 0.488790 0.031736 1.163146 0.861017 0.648828 0.818286 0.301049) ) ;;; 18 odd -------------------------------------------------------------------------------- ; 4.2426406 (vector 18 4.801501750946 (fv 0 1 0 1 0 0 0 1 1 0 1 0 0 1 0 0 0 0) 4.071185 (fv 0.000000 0.956640 1.083713 0.493342 0.797185 0.138960 0.613585 0.388904 -0.007616 0.968034 0.616152 1.753096 0.351362 1.174080 1.220111 1.511627 0.186455 1.775153) 4.069528 (fv 0.000000 0.956814 1.082990 0.493213 0.796608 0.137780 0.611831 0.387091 -0.011186 0.965014 0.614046 1.752338 0.348807 1.169857 1.216059 1.508238 0.182073 1.770765) ) ;;; 19 odd -------------------------------------------------------------------------------- ; 4.358898 (vector 19 4.8924918279945 (fv 0 1 1 0 0 1 1 0 1 0 1 0 0 1 1 1 1 1 1) 4.173923 (fv 0.000000 0.329738 1.407540 1.252167 0.448297 0.551162 1.341659 1.859617 1.357020 0.222879 0.553639 1.254187 0.641694 -0.208417 1.489583 1.646436 1.391179 1.758274 1.299312) 4.171858 (fv 0.000000 0.330499 1.406874 1.250304 0.450026 0.551790 1.342413 1.858827 1.359366 0.223792 0.553485 1.256415 0.641759 -0.208630 1.490602 1.646088 1.388713 1.758053 1.297635) ) ;;; 20 odd -------------------------------------------------------------------------------- ; 4.472135 (vector 20 5.043 (fv 0 1 0 1 0 0 0 0 0 0 1 0 1 1 0 0 0 1 1 0) 4.357980 (fv 0.000000 0.074668 -0.007236 0.182274 -0.090904 0.683075 1.087950 1.620610 1.402047 0.349796 1.096502 -0.498958 0.949574 -0.321894 1.411823 0.831379 -0.654670 0.294879 -0.284984 1.407225) ) ;;; 21 odd -------------------------------------------------------------------------------- ; 4.5825756 (vector 21 5.1372244578347 (fv 0 1 1 1 0 0 0 0 1 1 1 0 1 1 1 1 0 1 1 0 1) 4.448460 (fv 0.000000 1.232455 0.090847 0.908719 0.292484 1.788804 -0.065161 1.337389 1.076226 0.741452 1.053336 1.212537 1.463874 0.812811 1.503269 1.665124 0.651549 0.032446 1.058206 1.235365 -0.036822) ) ;;; 22 odd -------------------------------------------------------------------------------- ; 4.6904157 (vector 22 5.1805551751198 (fv 0 1 0 1 0 1 0 0 1 0 1 1 0 0 1 1 0 0 0 0 0 0) 4.581017 (fv 0.000000 0.180996 0.414015 1.937535 0.354831 0.584078 1.521008 1.778595 1.533807 1.338106 -0.034930 1.700610 0.808153 0.348626 1.850606 -0.102689 0.038967 0.664253 1.395687 0.513457 1.627689 0.472162) ) ;;; 23 odd -------------------------------------------------------------------------------- ; 4.7958315 (vector 23 5.4125407453101 (fv 0 0 0 1 1 1 1 0 0 1 0 1 0 1 1 1 1 0 1 1 0 0 1) 4.661614 (fv 0.000000 0.402662 0.143299 -0.307618 -0.213995 0.796949 1.006633 1.285380 1.569840 0.564104 0.342477 0.293161 1.200899 0.723618 0.539973 0.518746 0.907665 0.184015 1.163786 0.995418 -1.860771 1.039418 -0.124574) ) ;;; 24 odd -------------------------------------------------------------------------------- ; 4.89897948 (vector 24 5.6193280144865 (fv 0 1 0 0 1 0 1 0 1 1 0 0 1 0 1 1 0 0 1 1 1 1 1 1) 4.786434 (fv 0.000000 0.498846 1.191572 1.399155 0.479838 1.497230 -0.058887 0.823598 0.010384 0.864577 0.051220 1.057330 0.998513 1.799328 -0.041050 0.199658 0.646825 0.272218 0.034139 0.159133 0.043804 -0.115906 1.177655 0.690674) ) ;;; 25 odd -------------------------------------------------------------------------------- ; 5 (vector 25 5.7220960914079 (fv 0 1 0 0 0 0 0 1 0 1 0 0 1 0 1 1 1 0 1 1 0 0 0 1 1) 4.886819 (fv 0.000000 -0.128793 0.647898 0.792536 -0.285146 0.144218 1.160103 1.183437 -0.004858 -0.239530 1.215352 0.277973 0.699697 1.110172 0.616181 1.458993 0.406636 0.121039 0.182656 -0.085662 1.058149 0.147121 0.546131 0.378165 0.309175) ) ;;; 26 odd -------------------------------------------------------------------------------- ; 5.0990 (vector 26 5.8537594936002 (fv 0 0 0 0 1 1 1 1 0 0 1 0 0 1 0 0 1 1 1 0 1 1 1 1 0 1) 5.006443 (fv 0.000000 1.694135 1.368613 1.372881 0.625230 0.749494 1.218456 1.691757 1.088538 0.652397 -0.134215 1.088115 0.314540 0.197061 0.715518 1.230349 1.542812 -0.159343 1.427261 1.767442 0.867761 1.850745 0.671024 -0.112496 0.172562 0.147817) ) ;;; 27 odd -------------------------------------------------------------------------------- ; 5.196152 (vector 27 5.8637111082051 (fv 0 0 1 1 0 0 1 0 1 0 0 1 0 1 0 0 0 1 0 0 0 0 0 1 1 1 1) 5.088823 (fv 0.000000 0.108028 1.216984 1.164689 0.975005 -0.022884 0.035464 -0.148996 0.575654 1.005987 1.378471 0.117457 0.956928 1.741009 0.131397 -0.243584 0.873140 0.514628 1.810242 0.918281 0.161062 1.222969 1.595595 1.233298 1.211975 1.332117 1.297417) ) ;;; 28 odd -------------------------------------------------------------------------------- ; 5.291502 (vector 28 6.0276107788086 (fv 0 0 1 1 1 0 0 0 1 0 1 1 1 0 1 1 1 1 1 1 0 0 1 0 0 1 0 1) 5.088899 (fv 0.000000 1.695594 -0.042323 0.221585 0.121059 0.906440 0.747864 0.144725 -0.170880 0.198031 0.623261 -0.016920 1.187997 1.805776 0.526952 0.257290 0.181436 1.671568 1.634262 0.482276 1.385748 1.687591 0.368532 1.304502 0.925524 0.205838 0.775793 0.352193) ) ;;; 29 odd -------------------------------------------------------------------------------- ; 5.385164 (vector 29 6.0348020511367 (fv 0 1 1 1 1 0 0 0 1 1 0 1 0 1 1 0 0 1 0 0 1 1 1 0 1 1 1 1 1) 5.263365 (fv 0.000000 0.151064 0.558177 0.735081 1.367806 -0.011277 1.649265 0.435302 1.718318 1.203162 0.977127 1.010028 0.703023 1.591655 0.710208 0.371369 0.285721 1.400549 0.654738 0.961707 0.849244 0.833954 0.047113 1.107680 1.103136 1.834278 0.611441 1.521356 0.107658) ) ;;; 30 odd -------------------------------------------------------------------------------- ; 5.4772255 (vector 30 6.2357559204102 (fv 0 1 0 1 0 1 1 0 0 1 1 0 1 1 0 0 0 0 1 1 1 1 0 1 1 1 1 0 1 1) 5.353062 (fv 0.000000 -0.273797 0.780589 0.428126 1.742006 0.813705 1.826779 0.243133 0.799231 0.444552 0.600071 1.280010 -0.037027 0.801371 0.587721 1.132556 0.784854 1.819749 1.361833 1.646165 1.057885 0.274456 0.188906 0.072120 0.645190 1.511097 1.900389 1.698668 1.288971 1.535352) ) ;;; 31 odd -------------------------------------------------------------------------------- ; 5.56776 (vector 31 6.1342258453369 (fv 0 0 1 0 0 0 0 0 1 0 1 1 1 0 1 1 1 0 1 1 0 1 0 1 1 1 1 0 0 1 1) 5.418933 (fv 0.000000 1.386056 -0.055103 1.470738 1.133338 0.301486 1.278842 0.118113 0.785586 0.164711 0.277129 1.264947 0.805303 0.592921 0.251470 0.348783 0.666372 0.600263 0.392807 1.237206 -0.185182 1.790868 1.684032 0.764715 0.385641 1.091814 0.146242 0.339596 0.884327 1.106807 0.158763) ) ;;; 32 odd -------------------------------------------------------------------------------- ; 5.65685 (vector 32 6.3532226957365 (fv 0 1 1 0 0 1 0 1 0 1 1 0 0 1 1 1 0 0 0 0 1 0 1 1 1 1 1 1 0 1 1 1) 5.563263 (fv 0.000000 0.861343 1.208721 0.520795 1.054113 1.500902 0.176395 1.932292 0.475897 1.249746 1.078677 0.960255 1.432432 1.363500 0.301492 1.951062 1.402695 1.767079 1.762968 0.052405 1.191435 0.031852 1.950934 1.508841 1.124488 1.063642 0.897258 1.672866 0.358501 1.273522 0.844792 1.935288) ) ;;; 33 odd -------------------------------------------------------------------------------- ; 5.74456 (vector 33 6.4944429397583 (fv 0 1 0 0 1 0 1 0 1 1 0 0 1 0 0 1 1 1 1 1 1 1 0 1 1 1 0 0 0 1 1 1 0) 5.602961 (fv 0.000000 1.602314 1.153414 1.251950 1.483737 0.842898 0.331110 1.775787 1.322292 1.204304 1.308143 0.894156 0.779513 0.992393 1.543652 0.196767 0.377438 0.791269 1.809959 1.067569 0.948715 1.605054 1.761811 1.528262 1.622887 0.603858 1.560497 -0.275070 0.725193 1.894504 0.570411 -0.063928 0.717166) ) ;;; 34 odd -------------------------------------------------------------------------------- ; 5.8309518 (vector 34 6.5771403312683 (fv 0 0 1 1 0 1 0 1 0 1 1 1 0 0 1 1 0 1 0 0 1 0 0 0 0 0 0 0 1 1 1 1 0 0) 5.740544 (fv 0.000000 1.128136 0.272558 -0.038354 0.299624 0.550945 0.313230 0.243494 0.297552 -0.035270 1.018110 0.345979 1.524929 0.448210 1.252682 0.941202 0.533185 0.349491 1.187324 0.383773 0.599245 -0.155984 1.372487 0.578854 1.244062 1.476419 0.215593 0.058496 0.148247 1.077304 1.406503 0.859804 1.327046 0.146527) ) ;;; 35 odd -------------------------------------------------------------------------------- ; 5.9160 (vector 35 6.7392678260803 (fv 0 1 1 1 1 1 0 0 1 0 0 0 0 1 1 0 0 1 1 0 0 0 1 0 1 1 0 0 0 0 1 0 1 0 0) 5.833275 (fv 0.000000 0.446552 1.591598 1.665970 0.393066 0.930519 1.356028 1.466278 0.225797 1.216894 0.009583 0.233020 1.866671 1.148796 1.079614 1.602870 0.201424 1.366765 -0.045388 1.214248 0.402056 0.196949 1.726073 1.538289 -0.146596 -0.105825 1.452686 0.350527 1.133547 0.212285 1.683225 0.967867 0.587559 1.049939 0.968758) ) ;;; 36 odd -------------------------------------------------------------------------------- ; 6 (vector 36 6.8277182579041 (fv 0 1 1 0 1 1 0 1 1 1 1 0 0 1 1 0 0 1 1 0 0 0 0 0 1 1 0 1 0 1 0 1 0 0 0 0) 5.977640 (fv 0.000000 -0.070466 1.538192 0.984355 0.488221 1.019554 1.547512 1.704002 1.584416 0.668394 -0.001385 0.884114 1.504028 -0.187464 0.437132 1.457048 0.752720 0.480053 1.746828 0.789836 0.816665 1.133277 1.144098 1.330854 0.114924 1.293712 1.538716 1.521496 0.841528 0.693020 1.172435 0.408530 0.666143 -0.084621 1.417045 -0.037001) ;; 35+1 6.030643 #(0.000000 1.022108 1.134386 0.040000 1.020689 1.082726 -0.154753 1.098409 0.988397 0.898657 1.161207 0.157216 -0.172638 1.251128 1.003109 0.170160 0.036385 0.822058 1.148915 -0.012280 -0.203882 0.002376 0.142366 -0.019253 0.880987 1.211008 -0.244514 0.790432 -0.315814 0.996657 -0.069816 0.913294 0.063655 0.034201 0.148650 -0.048872) 6.023572 #(0.000000 1.006794 1.135292 0.054179 1.034731 1.098175 -0.131238 1.084424 0.944530 0.864373 1.175974 0.171650 -0.115246 1.244948 1.003278 0.206506 0.095902 0.771056 1.143860 -0.009618 -0.227281 -0.055671 0.132916 -0.028444 0.924379 1.277595 -0.228977 0.811154 -0.325012 1.010432 -0.091469 1.009174 0.052639 0.009978 0.088793 -0.099301) ) ;;; 37 odd -------------------------------------------------------------------------------- ; 6.0827 (vector 37 7.0 (fv 0 1 0 0 0 1 1 1 0 0 0 1 0 1 0 1 1 1 1 0 1 0 0 0 1 1 0 0 1 0 0 1 0 0 0 0 0) 6.019116 (fv 0.000000 1.198867 1.849092 0.935330 1.781957 0.496846 0.026335 0.303736 1.089299 1.074310 1.006658 1.377317 0.271438 1.654659 0.071833 0.494433 1.198697 -0.081156 0.936704 0.883271 1.529398 0.425484 0.218240 1.480439 1.569267 1.446099 0.465358 0.265303 1.385278 0.810099 0.212275 0.106695 0.522036 0.380536 0.175723 0.325421 -0.016008) ) ;;; 38 odd -------------------------------------------------------------------------------- ; 6.1644 (vector 38 7.027690410614 (fv 0 0 1 1 0 0 1 1 0 1 0 1 0 1 0 1 1 1 0 0 0 0 1 1 1 0 1 1 0 1 0 0 1 0 0 0 0 0) 6.144266 (fv 0.000000 0.459111 0.978423 1.181967 1.503059 1.306778 0.862780 1.146756 1.405445 1.059554 0.793798 1.421482 1.624819 0.940808 1.764974 -0.199270 0.756440 1.330911 0.861332 0.933256 0.734269 -0.017456 1.393657 0.220679 1.806219 0.259427 -0.110057 1.180170 1.136238 0.286941 1.541821 0.220515 1.089015 1.358525 1.068195 1.590398 0.413700 0.247552) ;; 37+1 6.138688 #(0.000000 1.046261 1.784835 0.956057 1.812170 0.474533 0.170721 0.206638 1.084578 1.210612 0.877325 1.304868 0.216526 1.666615 0.017582 0.377950 1.122637 -0.152317 0.759942 0.908307 1.610556 0.619180 0.252252 1.289240 1.682699 1.456452 0.437125 0.204631 1.313659 1.057657 0.251390 0.015459 0.426277 0.374256 0.211841 0.291412 0.083784 0.055093) 6.109073 #(0.000000 0.982171 1.705612 0.986921 1.873378 0.509690 0.102590 0.186755 1.133224 1.164029 0.874124 1.283945 0.138084 1.739224 -0.073147 0.350734 1.013698 -0.141497 0.646696 0.873432 1.551583 0.589738 0.246954 1.196679 1.600352 1.425024 0.430454 0.103410 1.227168 1.077407 0.227980 -0.028101 0.385573 0.330289 0.176030 0.160255 0.005449 0.061254) 6.108235 #(0.000000 0.982140 1.705650 0.987359 1.873951 0.509617 0.101844 0.187009 1.133759 1.164160 0.874009 1.284219 0.137756 1.739325 -0.073001 0.350923 1.012778 -0.140699 0.646579 0.873989 1.552501 0.590083 0.247447 1.196795 1.599951 1.425383 0.431367 0.103900 1.228072 1.077985 0.228759 -0.027472 0.386360 0.330507 0.175983 0.160536 0.005039 0.061859) ) ;;; 39 odd -------------------------------------------------------------------------------- ; 6.2449 (vector 39 7.2362656593323 (fv 0 1 1 0 0 1 1 0 0 1 0 0 1 0 1 1 1 0 0 0 0 1 0 1 1 0 1 1 1 0 0 0 1 0 0 0 0 0 0) 6.181539 (fv 0.000000 0.390214 1.432668 1.784856 0.372658 0.651343 0.590730 1.420862 1.232876 1.274776 1.031604 0.648830 1.314325 1.550338 0.798266 0.829350 0.920173 0.286182 1.175424 0.776791 1.481341 -0.170207 1.810272 0.591377 1.604472 0.287027 1.660006 1.308050 0.895442 0.027306 0.915319 0.337380 0.586293 1.687170 1.285611 1.205943 1.760871 1.039296 0.923977) ) ;;; 40 odd -------------------------------------------------------------------------------- ; 6.3245 (vector 40 7.5038495063782 (fv 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 1 1 0 0 1 1 0 1 1 1 1 0 0 1 0 1 1 0 1 0 1 0 1 1 1) 6.272478 (fv 0.000000 1.284197 1.055354 1.062168 0.387815 0.825054 0.121504 1.716073 1.070732 1.544312 0.376494 1.037163 0.380448 0.304545 1.428265 0.150454 0.740589 -1.906896 0.496136 -0.130727 1.453974 1.546206 0.424585 1.220704 1.332527 1.409234 0.400583 1.072058 1.397035 -0.550500 0.327899 1.771283 0.928925 0.550551 1.392166 1.184654 1.462753 1.291611 1.910777 1.578007) ) ;;; 41 odd -------------------------------------------------------------------------------- ; 6.4031 (vector 41 7.7093445316966 (fv 0 1 1 0 1 0 1 1 1 1 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 1 1 1 0 0 0 1 0 0 1 0 1 1 1 0 1) 6.321636 (fv 0.000000 0.581881 1.284007 1.435590 0.968036 0.414485 0.203921 -0.085398 1.011694 1.215509 0.697775 0.907045 0.006237 0.289299 0.751565 0.182523 1.917428 0.830815 0.908047 0.267572 -0.061197 0.319855 0.591342 1.699511 1.912692 1.683447 0.192711 0.461781 0.828435 1.122559 0.524721 1.057548 0.753199 0.901168 -0.077807 0.957092 -0.092721 1.453709 0.349112 1.539336 1.035529) ) ;;; 42 odd -------------------------------------------------------------------------------- ; 6.4807 (vector 42 7.77445936203 (fv 0 1 1 0 0 0 0 1 1 1 0 1 1 0 0 1 0 0 1 1 1 1 1 0 1 0 1 0 0 0 1 1 0 1 0 1 1 0 1 1 1 1) 6.403222 (fv 0.000000 0.615457 1.471291 0.696790 0.198813 1.064683 0.257669 1.499443 1.009189 1.331704 -0.126692 0.668087 -0.151536 1.235993 1.351147 1.834812 1.622001 1.575606 0.387431 1.123625 1.738720 0.186291 -0.093048 -0.362694 1.268339 0.808624 0.147243 0.174237 0.939940 0.098301 1.557405 1.899768 1.063327 1.398074 1.503515 -0.309876 1.592871 1.047295 0.347548 0.500256 0.502585 1.050388) ) ;;; 43 odd -------------------------------------------------------------------------------- ; 6.5574 (vector 43 7.7573688953539 (fv 0 1 0 0 0 1 0 0 1 0 1 1 1 0 1 1 1 0 1 1 1 0 0 0 0 0 1 1 1 0 0 0 1 0 0 0 0 1 0 1 1 0 1) 6.474181 (fv 0.000000 0.163031 0.868018 0.644438 0.499955 0.314476 0.501651 0.136276 0.115801 1.311189 1.257885 1.003167 1.668510 0.653556 0.900535 0.185303 1.792109 1.097281 0.880040 0.351492 0.533331 1.402396 1.722630 -0.341451 0.699659 1.677594 1.684893 1.301554 -0.032447 0.458521 1.242927 0.587312 1.726991 0.987710 0.168427 1.112409 0.233710 0.476465 1.063291 1.023410 1.387257 1.104431 1.814614) ) ;;; 44 odd -------------------------------------------------------------------------------- ; 6.6332 (vector 44 7.9338580613871 (fv 0 1 0 0 0 1 0 1 1 1 1 0 1 1 0 0 0 0 1 0 0 1 1 0 0 0 1 1 1 0 1 0 0 1 0 0 0 1 0 0 1 0 0 0) 6.599250 (fv 0.000000 0.351178 1.306835 1.466283 1.319851 0.565360 0.401323 -0.237018 1.055625 0.418518 0.685726 1.681541 1.845435 1.019294 1.472175 1.617323 0.599443 0.202024 1.548869 0.896807 1.498980 -0.449736 0.958935 0.672395 0.465421 0.363298 0.745996 0.800573 1.320237 0.704768 1.103042 1.233693 0.653096 1.449790 0.411870 1.110453 0.556583 1.736823 0.345497 0.024788 0.937504 1.224464 1.559019 1.346766) ) ;;; 45 odd -------------------------------------------------------------------------------- ; 6.7082 (vector 45 8.1351366043091 (fv 0 0 1 0 1 0 1 1 0 0 1 0 1 1 1 0 0 0 1 1 0 1 1 0 0 1 0 0 0 0 0 1 0 0 0 1 1 0 1 0 1 0 0 0 0) 6.624897 (fv 0.000000 1.004365 0.475962 1.144412 0.404466 0.708852 0.590380 0.024072 1.172296 1.113281 1.630362 1.256665 1.314082 0.342438 0.579726 1.460036 0.838934 0.298273 1.354989 1.643563 1.558056 1.967600 0.749164 1.349815 0.523705 0.276619 1.145711 1.733713 1.155806 1.020242 0.468578 1.677226 1.799379 1.623813 1.799356 0.670303 1.547676 1.429802 1.095547 0.114545 0.743241 1.141259 0.963105 1.247487 0.978965) ) ;;; 46 odd -------------------------------------------------------------------------------- ; 6.7823 (vector 46 8.1455316543579 (fv 0 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 0 1 1 0 0 1 0 0 0 1 1 1 1 0 0 0 1 1 1 0 1 1 0 1 0 0 0 0 1) 6.709237 (fv 0.000000 0.588728 0.764172 0.948247 0.778447 1.268756 0.080491 -0.381973 0.448541 1.688302 0.583900 0.609230 0.913000 1.244782 0.098190 0.458033 0.787717 0.012905 0.854674 1.035325 1.255759 0.507374 1.208176 0.514489 0.741105 1.441899 0.585374 1.583344 0.643511 1.525932 1.201616 0.846916 0.319659 0.030560 0.895113 0.341984 -0.007305 1.588064 0.007988 0.334683 0.349739 -0.215667 -0.068989 1.488454 0.988215 0.867211) ) ;;; 47 odd -------------------------------------------------------------------------------- ; 6.8556 (vector 47 8.336971282959 (fv 0 0 1 1 0 0 0 1 1 0 0 1 0 0 1 0 0 0 0 0 0 1 1 0 1 0 1 1 1 1 0 0 0 0 1 0 1 0 1 0 0 0 0 0 1 1 0) 6.785244 (fv 0.000000 0.898263 0.698671 0.821497 0.370262 0.536725 0.016930 1.555315 1.553643 1.249848 -0.203480 1.765177 0.026588 0.111231 -0.039332 0.662791 0.096267 1.286138 1.353013 0.226230 0.057438 1.648120 -0.088502 0.524016 1.306955 -0.084552 0.350695 1.753518 1.303444 0.678968 0.693452 0.498589 1.005882 1.660165 0.430707 0.068634 0.587061 1.130543 1.939600 0.152146 1.459634 0.723147 1.428638 0.763075 1.800028 1.481715 0.488673) ) ;;; 48 odd -------------------------------------------------------------------------------- ; 6.9282 (vector 48 8.35563071219336 (fv 0 1 0 0 1 0 1 1 1 1 1 0 0 0 1 0 1 0 1 1 1 0 1 1 1 1 1 1 0 1 0 0 1 0 0 1 1 0 0 0 1 1 0 1 0 0 0 1) 6.828028 (fv 0.000000 0.998004 1.077433 0.148071 1.527370 -0.144913 1.645316 1.723923 0.412024 1.174877 0.494923 1.411660 0.605628 1.628272 1.064698 1.228914 0.098971 0.692407 0.395792 1.297327 -0.001580 1.140646 1.342219 1.577941 0.241000 1.510351 1.184692 1.697190 1.378912 1.591005 -0.082196 0.468455 0.883072 0.625939 0.755107 0.095773 0.293743 0.637279 1.770381 1.345208 0.924216 0.393583 0.137327 1.278382 0.157871 0.442417 0.371701 -0.029442) ) ;;; 49 odd -------------------------------------------------------------------------------- ; 7 (vector 49 8.57458718352971 (fv 0 0 0 1 1 1 1 0 1 1 1 1 0 0 0 0 0 1 1 1 1 0 1 1 0 1 1 1 1 0 0 1 1 1 0 1 1 1 0 0 1 0 0 1 0 0 0 1 0) 6.988750 (fv 0.000000 -0.166791 0.066489 1.162315 1.337152 0.223301 0.045811 -0.093825 1.332601 1.728915 0.870363 0.493056 0.773831 1.546388 0.179602 0.790122 1.699394 1.317163 1.725149 1.408847 1.015662 0.639057 1.163324 0.986617 1.318547 -0.170292 0.080070 1.239083 1.484292 1.779081 0.940479 0.037560 -0.006305 1.151063 0.903661 1.767180 1.162011 1.427957 0.814000 1.843040 0.477534 1.459006 0.756363 0.414970 1.321498 0.061120 0.265825 0.092137 0.202930) ) ;;; 50 odd -------------------------------------------------------------------------------- ; 7.07 (vector 50 8.711 (fv 0 0 0 0 1 1 1 1 0 1 0 0 1 0 1 1 0 1 0 1 0 1 0 1 0 1 1 0 0 0 0 0 0 0 0 0 1 1 0 1 1 0 0 1 1 0 0 0 1 1) 6.947137 (fv 0.000000 1.361221 1.058873 0.255818 1.371652 1.848584 -0.002271 1.052656 0.139885 0.680884 0.885258 1.006144 1.663943 1.665052 1.470510 1.693036 0.091983 0.825894 1.755289 1.033123 0.055566 1.508725 0.691199 1.233170 0.641006 1.442066 1.557992 1.909688 0.175284 1.577225 1.678517 1.358807 1.558359 1.883371 1.133931 1.053187 0.137949 1.901321 0.058023 0.971798 1.378739 0.843519 0.357409 0.498187 1.235125 0.734586 0.653589 0.242791 1.085625 -0.043484) ) ;;; 51 odd -------------------------------------------------------------------------------- ; 7.141 (vector 51 8.5829010009766 (fv 0 1 0 0 1 1 1 1 0 0 1 1 0 0 0 1 0 1 1 1 0 0 0 1 1 1 1 1 1 1 1 1 1 0 1 0 1 0 0 1 1 1 0 1 0 0 1 0 0 1 0) 7.087726 (fv 0.000000 0.875029 0.865937 0.367918 1.900818 0.762934 0.081270 0.353365 0.070375 -0.037477 1.275772 -0.100171 1.088567 1.481918 0.798713 1.260047 0.731048 1.035501 1.384103 0.728234 0.608922 1.769831 1.228331 0.727930 1.038826 -0.062865 0.731133 1.490525 1.564219 0.530975 0.845759 -0.127106 1.209031 0.537607 1.042200 0.906452 -0.105250 0.353212 0.368083 1.395843 1.206034 1.694293 0.348968 0.222228 0.523051 0.375570 0.283017 1.406111 0.934909 0.587260 0.940073) ) ;;; 52 odd -------------------------------------------------------------------------------- ; 7.211 (vector 52 8.8599758148193 (fv 0 0 0 1 0 1 1 1 0 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 1 1 0 0 0 1 1 0 0 0 1 0 1 0 1 1 0 1 0 0 0 1) 7.080087 (fv 0.000000 0.216994 0.815073 0.651401 0.471967 0.035007 -0.067747 0.660856 0.580235 0.052345 1.785696 0.529423 0.205578 -0.247148 1.238971 0.096672 0.952857 0.166426 0.759284 1.719458 0.161518 1.592928 0.883009 0.245604 1.208605 0.995562 0.029395 0.487673 1.152615 0.362903 0.721410 0.862934 0.090743 0.014994 0.082182 0.993529 1.056537 1.708353 0.746025 -0.333233 1.155949 0.740213 0.619117 1.020646 1.502770 1.347142 1.371490 1.480724 0.363059 1.828476 0.147552 0.424061) ) ;;; 53 odd -------------------------------------------------------------------------------- ; 7.280 (vector 53 9.037 (fv 0 1 0 1 1 1 0 0 1 1 1 0 1 0 0 0 1 0 0 0 0 0 1 1 1 1 1 1 0 1 1 0 1 0 1 1 1 1 0 1 1 1 1 0 1 1 0 0 1 0 1 1 0) 7.252601 (fv 0.000000 1.316368 0.101159 0.287376 -0.120486 -0.146148 -0.293575 0.279566 1.566833 0.692861 -0.116203 1.111486 1.592177 1.082742 0.010661 0.754630 0.400780 0.795713 1.670109 1.185717 1.226796 -0.120012 0.262637 0.206364 0.738299 0.157263 0.604374 0.683095 1.946305 -0.043066 0.580881 1.320138 -0.043078 1.307240 1.171743 0.356072 0.398418 -0.096678 0.059824 1.235855 0.057573 -0.031810 1.322088 0.600804 1.405030 -0.237620 -0.007423 -0.083489 1.021491 1.628805 -0.222749 0.516076 0.301362) ) ;;; 54 odd -------------------------------------------------------------------------------- ; 7.348 (vector 54 9.025 (fv 0 1 1 0 1 1 1 0 1 1 1 0 1 0 0 0 0 0 1 0 1 0 1 1 0 1 0 0 1 1 1 0 1 1 1 1 1 0 0 1 1 1 1 1 0 1 0 1 1 0 1 1 0 0) 7.328138 (fv 0.000000 0.352535 1.363504 0.096670 1.597330 -0.030072 1.222144 1.243528 0.696875 0.968663 0.162138 1.056566 0.539804 0.008667 0.316670 -0.098837 1.225380 -0.112322 0.244903 0.436331 1.746403 0.122260 0.091220 1.558109 1.217585 1.412994 0.339182 0.690620 1.846588 1.658518 0.529876 1.420789 0.398352 0.612668 1.926173 0.676632 0.529358 1.076039 0.628593 -0.021834 1.281928 0.607717 0.819453 1.795488 1.260788 0.439390 0.834961 1.345636 1.190831 1.783406 -0.135996 0.097131 0.579836 0.358027) ) ;;; 55 odd -------------------------------------------------------------------------------- ; 7.416 (vector 55 9.2039985656738 (fv 0 0 1 1 1 0 1 0 0 1 1 1 0 1 0 0 1 1 0 1 1 1 0 1 1 1 0 0 0 1 1 1 0 1 0 0 1 0 0 0 0 0 0 0 1 1 0 1 0 1 0 0 1 1 1) 7.364233 (fv 0.000000 0.395190 -0.153867 1.307052 0.778840 1.201427 1.584425 -0.091689 1.563398 0.221226 1.485388 0.595790 -0.041635 0.380534 0.103234 0.445988 1.706774 1.178799 1.315522 1.096083 0.260274 -0.072891 0.228062 0.239593 1.575799 0.203611 0.427975 1.251992 1.620128 0.666682 0.636489 0.025180 0.388251 0.546392 1.107252 0.996609 1.708598 0.607806 -0.354744 1.114522 1.187212 0.060556 1.020751 1.136440 0.719385 1.579705 0.166783 0.736570 0.421572 0.534881 0.141987 1.649951 0.500500 0.386302 -0.074892) ) ;;; 56 odd -------------------------------------------------------------------------------- ; 7.483 (vector 56 9.3816785812378 (fv 0 0 1 1 1 0 1 0 1 1 1 1 1 0 1 0 1 1 0 0 1 1 1 0 0 0 0 0 0 1 1 0 0 1 0 0 1 1 1 1 0 1 0 1 0 0 0 0 0 0 1 0 1 1 1 0) 7.419120 (fv 0.000000 0.417128 1.082491 1.276854 0.765982 1.295111 1.835030 1.786443 0.675192 1.020185 0.394420 0.359608 0.697463 1.166247 0.564899 1.087103 0.889865 0.844186 1.419287 1.562675 0.248998 1.869468 1.111986 1.294693 1.863255 0.052934 0.338636 1.626312 1.601681 -0.021561 1.462490 1.791020 0.409025 1.675990 1.011444 1.359048 1.605820 1.247285 1.024241 0.457113 0.153603 0.242127 1.175155 0.206257 1.412766 1.496703 -0.140135 1.270904 0.393803 1.315634 0.897708 1.585792 0.563930 1.722379 1.612675 1.047507) ) ;;; 57 odd -------------------------------------------------------------------------------- ; 7.549 (vector 57 9.3903837203979 (fv 0 1 0 1 0 0 0 0 1 1 0 1 0 1 0 0 0 1 0 0 1 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 1 0 0 1 1 0 1 1 1 1 1 1 0 1 0 0 0 0 1 1 0) 7.488896 (fv 0.000000 -0.127939 1.380652 0.701541 0.779535 0.090662 1.662797 0.879717 1.570316 1.307786 1.211090 0.971455 0.738042 1.474139 1.501173 1.322773 -0.333947 0.651999 1.407414 0.559437 0.970911 0.613447 1.441437 0.387240 1.769723 0.695953 -0.175580 0.102181 0.180022 1.529463 0.468743 0.084931 0.062956 0.298511 0.524008 0.924744 1.286647 1.428978 0.334028 1.302926 0.807711 0.283976 0.097723 1.284073 0.038191 0.329167 1.275797 0.351298 1.518403 1.571791 0.227818 0.842734 0.707030 0.435243 0.618490 0.867851 1.852691) ) ;;; 58 odd -------------------------------------------------------------------------------- ; 7.6157 (vector 58 9.5893135070801 (fv 0 1 1 0 1 0 1 1 0 0 0 0 0 0 1 0 1 1 1 1 0 1 1 1 0 1 0 0 1 1 1 0 0 1 1 1 0 1 1 1 0 1 1 1 1 1 1 1 0 0 0 0 1 1 0 1 0 0) 7.585947 (fv 0.000000 0.517595 -0.138781 1.328351 0.394157 0.908218 0.526218 1.063012 1.239066 1.277916 1.783309 1.590363 0.539572 1.425376 1.601385 0.376842 0.888852 1.358950 1.916790 1.468314 0.490842 0.036065 1.359391 1.047397 0.699655 1.225098 0.065253 0.350008 0.483077 1.188989 1.002860 0.893562 0.202836 0.208109 1.801392 1.050084 -0.102454 1.813439 1.482474 -0.166271 1.426695 0.563055 -0.225427 0.436837 1.102639 0.467507 0.283291 1.511898 0.400494 1.606371 -0.049354 1.495330 -0.267319 0.336083 0.925094 0.220186 1.902233 -0.035784) ) ;;; 59 odd -------------------------------------------------------------------------------- ; 7.681 (vector 59 9.5173864364624 (fv 0 1 1 1 0 0 0 0 0 1 1 0 1 0 0 1 0 0 1 0 0 1 0 1 1 1 0 0 0 1 1 1 1 1 1 1 1 1 1 0 0 0 1 0 0 0 1 1 0 1 1 0 1 0 1 0 1 1 0) 7.617785 (fv 0.000000 1.762340 0.513621 1.350480 0.395272 0.369068 0.305583 0.831518 1.232517 0.676844 0.014044 1.888953 1.633364 1.298874 0.424500 1.402106 0.715815 1.275937 1.488547 1.873193 1.738228 0.570388 0.057875 1.975863 0.297300 1.563912 0.772704 0.090655 0.241787 1.145030 0.785784 1.432008 1.006607 1.408581 0.812224 0.224382 0.926131 0.944185 -0.064326 0.205583 1.060366 0.673429 1.237483 1.421583 0.464247 1.651757 1.984268 1.030220 1.489122 1.350599 0.646010 1.371095 0.262034 0.720620 1.557135 1.181053 0.745491 0.926931 1.443337) ) ;;; 60 odd -------------------------------------------------------------------------------- ; 7.7459 (vector 60 9.6560277938843 (fv 0 1 0 0 0 1 0 0 1 0 0 1 1 1 1 1 1 1 1 0 1 0 0 1 0 1 0 0 1 0 0 1 1 0 0 0 0 0 0 1 0 0 0 1 1 1 0 0 0 0 1 0 1 1 1 0 0 1 0 0) 7.699628 (fv 0.000000 -0.021305 0.599580 1.675097 0.724803 0.358532 0.890770 0.765518 0.237166 0.821603 0.185949 0.996346 -0.076908 1.733595 1.718331 -0.080896 1.631867 0.229557 1.219113 -0.444442 1.509828 0.286787 0.741904 1.151478 1.816287 -0.008152 -0.169986 1.514652 0.248473 1.296089 1.211441 0.399013 0.342384 1.801962 0.377537 0.181714 1.809056 1.599925 0.494049 0.298590 0.110648 0.855221 1.804868 0.666943 1.224265 1.636192 1.425598 0.559152 0.087897 0.972335 -0.105600 1.103327 1.345409 0.428767 -0.084957 1.609410 0.060258 0.846549 0.678506 0.580784) ) ;;; 61 odd -------------------------------------------------------------------------------- ; 7.8102 (vector 61 9.6689287776524 (fv 0 0 0 0 1 0 1 1 0 0 1 1 0 1 1 0 0 0 1 0 1 1 0 1 0 0 1 0 1 0 0 1 1 0 1 0 0 0 1 1 1 0 0 1 1 0 0 0 0 1 0 0 0 0 0 0 0 1 1 1 1) 7.775467 (fv 0.000000 -0.343145 0.781525 1.809127 0.251480 0.512435 0.079273 1.157280 0.819596 0.391398 -0.518556 1.678636 0.560600 0.125318 0.035700 1.744672 1.824327 1.087291 1.692006 0.706036 0.269610 1.403225 1.233897 0.487088 1.476172 -0.284871 0.794501 1.368364 0.656660 0.974817 1.000338 0.175726 1.024682 0.865508 0.404847 0.718158 0.071740 1.457732 -0.480756 0.735357 1.217441 0.811494 1.022056 0.829877 1.509011 1.174960 1.639594 0.781475 -0.011943 1.221853 -0.208689 0.133149 0.650142 1.217107 -0.446658 0.092120 -0.062880 0.676055 0.910707 0.946198 0.780527) ) ;;; 62 odd -------------------------------------------------------------------------------- ; 7.8740 (vector 62 9.7982149124146 (fv 0 0 1 1 0 1 0 0 1 0 0 0 0 1 1 0 1 1 1 0 1 0 0 1 1 0 1 1 0 0 0 1 0 0 1 1 0 1 0 1 1 0 1 1 1 0 1 0 0 0 0 1 0 0 0 0 1 1 1 0 0 0) 7.816985 (fv 0.000000 0.185485 -0.254761 0.263400 0.632430 0.127767 1.483161 1.282005 1.556675 0.709224 0.293439 0.049467 -0.087443 1.425471 0.595679 0.678957 0.447779 0.382124 0.717681 0.082649 -1.563917 -0.140691 0.229960 0.339346 0.083428 0.640485 0.923623 -0.076532 1.385224 0.166806 1.518517 1.222370 1.575074 0.899045 0.324075 1.508603 -0.064272 0.115115 0.407781 0.298344 1.252368 1.084082 0.264721 0.922346 1.331199 0.689780 0.795795 1.526817 0.163429 0.888100 0.510259 1.478381 0.318687 1.341508 1.785614 0.798865 0.525568 1.053899 1.308203 0.410567 -0.026960 1.103176) ) ;;; 63 odd -------------------------------------------------------------------------------- ; 7.9372 (vector 63 9.8550319671631 (fv 0 0 0 0 0 1 1 1 1 1 1 0 1 0 1 1 1 0 1 0 0 0 0 0 1 1 1 0 1 1 0 1 1 0 1 0 0 0 1 0 1 0 0 1 0 0 0 0 1 1 0 0 0 1 0 1 1 0 0 0 1 1 0) 7.904133 (fv 0.000000 1.545501 0.155683 0.898914 0.625696 0.564119 0.345790 0.703891 0.981672 1.014462 1.740323 0.008567 -0.039871 0.470077 1.202746 0.366398 0.367999 1.293490 0.310624 1.016687 1.843528 0.474437 1.864085 0.859066 0.880435 1.525047 0.949229 0.065485 0.658928 0.625456 0.890422 0.157110 0.668174 1.537633 -0.133525 1.887056 1.094821 1.580831 1.506736 1.621226 1.791740 1.492769 0.830911 0.166732 1.797834 0.044991 1.834240 1.000450 1.479368 0.610232 0.816463 1.240492 0.107919 -0.111385 1.348751 1.167090 0.907202 0.154866 1.422414 0.720983 0.430601 -0.041659 0.656229) ) ;;; 64 odd -------------------------------------------------------------------------------- ; 8 (vector 64 10.0 (fv 0 1 1 0 1 0 0 1 0 0 1 1 0 0 0 0 1 1 1 0 1 1 1 0 1 1 1 1 0 0 1 1 0 0 1 0 1 0 1 0 0 0 1 1 0 0 1 0 0 1 0 0 0 1 1 1 1 0 0 0 0 0 0 0) 7.957414 (fv 0.000000 0.941670 0.218463 1.054436 0.821282 0.779097 1.084317 0.220811 0.530574 -0.001214 1.277468 1.056444 1.434429 0.244804 0.635637 0.374642 1.294283 0.051882 1.563945 0.856817 0.659797 0.848723 0.789207 0.004337 0.642492 -0.752744 0.794434 0.546992 1.340010 0.716341 1.722360 1.081100 1.009399 0.345867 1.393328 1.377443 1.264631 0.487017 1.142544 0.031648 0.469271 -0.098334 -0.019627 0.567023 1.791954 0.511740 0.421519 0.992945 1.133377 1.668348 -0.054246 0.158608 -0.042808 1.772093 0.331126 0.762153 1.499580 1.813299 1.079657 1.088576 0.368377 1.519001 0.864479 0.914946) ) ;;; 65 odd -------------------------------------------------------------------------------- ; 8.0622 (vector 65 10.169842720032 (fv 0 0 1 1 0 0 1 0 1 0 1 1 0 1 1 0 1 1 1 1 1 0 1 0 1 1 1 0 1 1 0 1 0 1 0 1 1 1 1 1 0 0 1 1 0 0 0 0 1 1 0 0 1 1 1 1 1 1 0 0 0 0 1 0 1) 8.041843 (fv 0.000000 1.510279 1.423698 1.698060 1.501053 1.180996 -0.085543 1.272940 0.246128 1.452754 1.116882 0.406181 0.071379 0.504041 0.790673 1.684489 -0.028841 0.150831 0.258232 0.575724 1.903805 0.049803 1.632670 1.087031 1.406375 1.614155 0.540793 1.593111 0.703911 1.182639 1.722176 0.257146 -0.290703 0.360167 1.805766 1.244616 1.636667 1.267448 1.403263 0.048920 1.072378 0.033352 0.081404 0.128813 0.847252 1.224433 1.268463 0.838170 0.941587 1.720222 0.172123 0.951570 1.520723 1.306591 0.465991 -0.022358 1.791525 1.039956 0.489959 1.798920 0.197346 1.247948 0.566292 0.910361 0.850668) ) ;;; 66 odd -------------------------------------------------------------------------------- ; 8.1240 (vector 66 10.212840820553 (fv 0 0 0 0 0 1 1 1 1 0 0 0 1 1 0 1 0 0 1 0 0 1 1 1 1 0 0 1 1 1 0 0 1 1 0 1 1 0 0 0 1 0 1 0 0 0 1 0 1 0 1 0 1 1 0 1 0 0 0 0 0 0 0 0 1 0) 8.137089 (fv 0.000000 0.867002 -0.091284 0.941017 0.985813 1.124822 -0.061065 0.794288 1.395872 1.715915 0.180754 1.493753 0.091406 -0.059796 0.775109 -0.175925 1.503403 0.926368 0.549523 0.719653 -0.225722 0.805496 0.016786 1.138759 0.185499 1.460462 1.586490 0.459741 1.668207 1.371214 0.709682 0.824263 0.306383 0.060221 1.519433 1.454263 1.678352 0.268698 0.281303 0.104475 0.990641 -0.061422 1.164978 0.345674 0.648924 1.140977 0.632657 0.963358 1.933250 0.002500 1.501010 0.074909 0.787595 1.107851 1.157288 1.691148 1.812947 1.291647 1.327838 1.731755 1.607111 1.129367 0.868934 1.256116 1.509418 0.963219) 8.095195 (fv 0.000000 0.946051 -0.069946 0.931149 1.114323 1.098389 -0.039332 0.877524 1.318916 1.775911 0.245290 1.539842 0.131201 -0.108794 0.748602 -0.153383 1.475925 0.851225 0.482687 0.831474 -0.195116 0.598903 -0.150418 1.241002 0.075671 1.415619 1.425349 0.401276 1.645496 1.378829 0.717955 0.820749 0.280776 0.102463 1.505118 1.466659 1.804612 0.370381 0.198640 0.039917 0.927835 0.130993 1.362388 0.264055 0.657827 1.168088 0.670275 0.998910 -0.080695 -0.000494 1.446059 0.092607 0.764024 1.120077 1.135001 1.626300 -0.038234 1.325677 1.373468 1.689492 1.591066 1.008988 0.840459 1.246657 1.459948 0.945345) ) ;;; 67 odd -------------------------------------------------------------------------------- ; 8.1853 (vector 67 10.209677696228 (fv 0 1 0 1 1 1 0 1 1 0 0 1 0 1 1 1 1 0 1 1 1 0 1 1 1 1 1 0 0 1 1 0 1 1 1 1 0 0 0 1 0 1 1 1 0 0 1 0 1 1 0 0 0 0 1 0 0 1 0 1 0 1 1 1 1 0 1) 8.127999 (fv 0.000000 0.156189 0.759312 0.316632 1.612933 0.605013 0.952530 0.423099 -0.112233 1.447269 0.863131 0.200670 1.538179 0.172873 0.737196 0.916694 1.524894 1.423218 1.337268 0.799228 0.023760 0.359774 1.033535 1.252717 0.399347 1.736421 0.199827 0.358145 1.847858 -0.157369 -0.118965 -0.296280 1.764663 0.918422 0.547247 0.781682 -0.101912 1.939111 1.078792 1.928250 0.777073 0.358591 1.566766 0.658960 0.895914 1.285541 1.636763 -0.098157 1.684110 0.891684 1.386081 0.068089 0.497477 0.528377 0.140207 0.953073 0.655659 0.018618 0.774991 0.503967 1.384065 0.100041 0.959741 0.153740 0.654728 0.200720 0.384936) ) ;;; 68 odd -------------------------------------------------------------------------------- ; 8.24621 (vector 68 10.359804316765 (fv 0 0 1 1 1 0 1 0 0 0 1 1 1 1 1 1 0 1 0 1 0 0 1 1 0 1 1 1 0 0 1 1 1 1 0 0 1 0 0 1 1 0 1 0 1 1 0 1 1 1 1 1 1 0 1 1 1 1 0 0 0 0 1 0 0 0 1 0) 8.204414 (fv 0.000000 0.279095 1.647677 0.913913 0.663406 0.323080 0.240930 0.148599 0.780719 0.015227 1.335435 0.919514 1.070941 0.877126 0.293550 1.686752 0.481693 0.755701 0.785320 0.815615 1.595420 1.293383 0.426688 0.494705 1.026142 0.549725 1.259770 -0.007824 0.278489 0.224750 0.082547 0.719555 0.355973 0.908801 0.541094 0.432336 1.241602 1.708744 0.772870 1.505613 -0.137480 0.654507 1.657469 0.849573 0.009380 1.611286 1.676352 1.046709 1.432096 0.979028 1.747525 0.522938 0.318568 1.148496 -0.245690 0.703484 0.171945 1.485079 1.659272 -0.006233 0.283657 1.852744 1.398727 0.371514 0.974831 1.325922 0.719933 0.483798) ) ;;; 69 odd -------------------------------------------------------------------------------- ; 8.3066 (vector 69 10.452348709106 (fv 0 0 1 0 0 1 1 1 1 1 0 0 1 0 0 1 0 0 1 0 0 0 0 0 0 1 1 0 0 0 1 0 1 1 1 1 0 1 0 1 1 0 1 1 0 0 0 1 1 0 0 1 0 1 1 1 0 1 0 1 0 0 0 0 0 0 1 0 1) 8.274908 (fv 0.000000 1.788801 1.283513 -0.242756 0.145250 0.146755 0.584479 1.353542 0.821070 0.189803 1.413669 0.749926 1.058442 1.185407 1.095039 1.015258 0.161858 0.034929 0.498704 0.198138 1.711445 0.157768 0.616185 1.421248 1.168404 0.254474 1.519482 -0.175837 0.581687 0.194579 0.931780 -0.336100 0.287461 1.495068 0.039168 1.507647 0.993152 1.382317 1.231363 0.721890 1.622206 1.080570 0.186638 0.155662 0.909604 1.203958 1.050254 1.890059 0.428940 0.701250 -0.160137 0.279994 1.502298 0.567568 0.585424 0.686015 -0.246566 0.662061 0.986133 1.103373 0.572438 0.607162 -0.159332 0.926622 1.112278 0.937694 0.624990 1.345312 0.670451) ) ;;; 70 odd -------------------------------------------------------------------------------- ; 8.3666 (vector 70 10.431521047498 (fv 0 1 0 0 0 0 1 1 1 1 0 0 1 0 1 0 0 1 1 0 1 0 1 1 0 1 0 0 0 1 1 1 1 0 1 0 0 1 1 1 0 0 0 1 0 0 1 1 0 1 1 0 0 1 0 0 0 1 0 1 0 1 1 1 1 1 1 1 1 1) 8.328488 (fv 0.000000 1.209391 0.655351 -0.224668 0.270551 0.912782 1.006468 0.115362 1.639506 1.394128 1.775544 -0.158964 -0.191285 0.916307 -0.148807 -0.343643 0.171981 0.447415 0.684977 -0.187759 0.122627 0.642332 0.846737 0.920787 0.824105 -0.455822 1.004331 0.650453 0.327784 -0.378239 0.335174 0.883411 0.475111 1.924029 1.429019 1.351303 -0.183533 1.395982 0.599233 0.896200 1.135652 0.575692 1.213789 1.853140 0.377792 1.790714 0.835251 1.493542 0.305236 1.538414 0.647163 0.263422 1.348466 1.037276 0.893701 1.108073 -0.492190 -0.249170 1.081128 0.973414 0.593299 0.786885 0.003725 0.855855 1.605169 1.050037 0.831705 1.193285 0.128148 0.709803) ) ;;; 71 odd -------------------------------------------------------------------------------- ; 8.4261 (vector 71 10.642364501953 (fv 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 0 1 0 0 1 0 1 0 1 0 1 0 1 0 0 1 1 0 1 0 0 0 0 1 0 0 1 1 1 0 1 1 0 1 0 0 0 0 0 1 0 0 0 1 0 0 1 1 1 1 0 0 1 1 0 0) 8.475519 (fv 0.000000 1.238076 0.753931 1.905336 0.009769 0.107430 -0.130621 1.591198 0.182824 0.768320 1.146473 0.823523 0.829676 0.742699 -0.276539 0.324236 1.092544 0.415195 1.670265 1.207403 0.977157 1.540240 1.842707 1.816863 1.497289 1.724381 0.528087 1.371720 0.846254 0.443580 1.148328 1.771135 -0.168351 0.710309 -0.056239 1.109626 1.555511 -0.110149 0.103207 0.997197 1.006113 0.446860 1.034785 1.366376 1.616338 -0.046807 1.211677 1.130244 1.187406 1.353421 0.750549 1.080694 1.186040 0.268525 1.418417 0.401769 1.093799 -0.192487 0.855080 0.124908 -0.060822 1.069669 1.270728 0.527632 1.877202 0.240913 -0.052204 1.530974 1.498303 0.436500 1.851527) ;; from this, but :odd 71 0.53864770353023 (fv 9.9351872829636 -0.2379167494546 3.1853837584999)?? ;; 9.9437 (fv 0.0000 1.0614 0.0950 1.1008 0.0787 1.0289 1.9512 0.8458 1.7125 0.5514 1.3626 0.1459 0.9014 1.6290 0.3289 1.0010 1.6452 0.2617 0.8503 1.4112 1.9442 0.4494 0.9268 1.3764 1.7982 0.1921 0.5583 0.8967 1.2072 1.4899 1.7449 1.9720 0.1713 0.3428 0.4865 0.6024 0.6904 0.7507 0.7831 0.7878 0.7646 0.7136 0.6349 0.5283 0.3939 0.2316 0.0416 1.8238 1.5781 1.3047 1.0034 0.6744 0.3175 1.9328 1.5203 1.0800 0.6119 0.1159 1.5922 1.0407 0.4613 1.8541 1.2192 0.5564 1.8658 1.1474 0.4012 1.6272 0.8253 1.9957 1.1382 ) 8.471193 (fv 0.000000 1.251993 0.120909 1.147167 0.101021 0.991005 0.102768 0.840256 1.667018 0.493083 1.454975 0.236751 0.930972 1.613715 0.282901 1.264934 1.852683 0.309294 0.763244 1.396502 0.016107 0.421575 0.832061 0.905495 1.670197 0.206770 0.024145 0.415927 1.292038 1.512037 1.549693 1.890115 0.264325 -0.038970 0.344515 0.662351 0.896654 0.664956 0.697808 0.735895 0.787344 0.830776 0.256004 0.590650 0.201668 0.204354 0.381917 1.530833 1.289723 1.098254 0.882568 0.234043 0.016492 0.014075 1.543842 0.771174 0.029614 -0.188598 1.614192 0.901328 0.316437 -0.299368 1.157490 0.464174 -0.326258 1.156953 0.332845 1.674680 0.336028 -0.185110 1.185822) 8.406561 (fv 0.000000 1.136768 0.110422 1.080469 0.111645 0.980565 0.087135 0.892409 1.705799 0.484945 1.412134 0.209542 0.909173 1.678801 0.332063 1.134599 1.765595 0.287552 0.824497 1.474171 0.122562 0.547316 0.786695 0.921126 1.628959 0.181855 0.048990 0.491779 1.249164 1.531973 1.630614 -0.083456 0.308877 -0.134450 0.334308 0.596938 0.779083 0.610588 0.769576 0.748353 0.930715 0.765564 0.342767 0.573683 0.144254 0.219685 0.317964 1.469956 1.186980 1.051035 0.789756 0.253764 0.026652 -0.023543 1.467574 0.724088 0.114734 -0.223070 1.555542 0.968486 0.132084 -0.314737 1.118620 0.462013 -0.390063 1.067074 0.324923 1.582422 0.354510 -0.234876 1.172540) ) ;;; 72 odd -------------------------------------------------------------------------------- ; 8.4853 (vector 72 10.880306243896 (fv 0 0 1 0 0 1 0 1 0 0 0 0 0 0 0 1 1 0 0 1 0 0 0 0 1 1 0 0 1 1 0 1 0 1 0 1 0 1 1 1 1 0 0 1 1 0 0 0 0 0 1 0 0 1 0 0 1 0 1 0 1 1 0 1 1 1 0 0 0 0 0 1) 8.366430 (fv 0.000000 1.529157 0.709835 0.191619 0.777505 1.673931 1.052039 1.157229 0.197845 1.188203 0.205209 0.808312 1.907251 0.734102 1.471024 1.752009 0.976735 0.215092 1.669497 0.039070 0.308185 0.805661 0.414650 0.685942 0.933087 1.104471 0.869537 0.010581 1.431457 1.039490 0.654718 0.051163 1.637896 0.041328 0.434461 1.596916 0.630066 0.513683 1.126090 1.472280 0.029687 0.729904 0.900726 0.364456 0.829387 0.775767 0.087943 1.122617 0.054278 0.980310 0.814649 1.331669 0.404897 1.438813 0.751132 1.069103 1.033498 0.950755 0.588560 0.206118 0.697556 1.364322 0.007771 0.225318 -0.029948 1.266843 1.008881 -0.515131 0.251545 0.235634 0.009431 1.881826) ) ;;; 73 odd -------------------------------------------------------------------------------- ; 8.5440 (vector 73 10.907942771912 (fv 0 1 0 1 1 0 1 0 0 0 1 0 0 1 0 0 0 0 0 0 1 1 0 1 1 1 1 0 0 1 1 1 1 0 1 1 1 1 0 0 1 1 0 0 1 1 0 1 1 1 1 0 1 1 0 0 0 0 1 1 1 1 1 0 0 1 1 1 1 0 1 0 1) 8.514653 (fv 0.000000 1.403201 0.376583 -0.053235 1.209136 1.524715 0.146380 -0.261365 0.834173 1.272975 1.772227 0.023615 0.314599 1.515420 0.115615 0.532763 0.813612 1.148749 0.624829 1.610666 0.428301 0.533410 1.364035 0.688805 -0.345103 -0.033075 0.031988 1.294508 1.610808 0.200563 1.512417 1.458407 0.018985 0.336604 -0.051222 0.346655 1.033154 0.703796 1.103730 1.139661 0.592095 0.478459 0.370549 0.620498 -0.386452 0.468708 0.040902 1.488975 0.539537 0.999795 0.347372 0.354446 0.387241 1.176009 1.306213 0.778993 0.280166 0.010910 0.034863 0.320352 1.620759 0.391262 0.863014 -0.075789 1.338588 1.092040 0.260638 1.463660 0.169121 0.826134 0.241084 1.728130 -0.116721) ) ;;; 74 odd -------------------------------------------------------------------------------- ; 8.6023 (vector 74 11.262331896 (fv 0 0 1 1 1 0 0 1 1 0 0 1 0 1 1 0 1 1 0 1 0 1 1 0 1 1 0 0 0 0 0 0 1 0 0 1 1 1 0 0 1 1 1 0 0 0 0 1 1 1 1 0 1 0 0 0 0 1 0 1 0 1 0 1 1 1 1 0 1 0 0 1 1 0) 8.487915 (fv 0.000000 0.229202 0.328610 0.886519 0.913243 -0.092303 1.469261 1.392280 0.102684 0.875868 1.119399 -0.375546 1.138609 1.792722 0.270873 0.158504 1.300583 0.337402 0.457798 0.994721 0.720190 1.266403 1.157785 0.204200 0.832717 1.368187 -0.207911 0.551921 0.143469 0.767289 -0.041673 0.248888 0.686134 1.808117 1.719833 1.634354 -0.372228 1.923379 1.132948 1.667043 0.857041 1.387145 0.637791 -0.326159 0.280564 1.478231 0.572776 0.063470 1.115045 1.234238 1.093760 0.166042 1.189669 0.933614 0.159392 1.594960 1.079073 1.251388 1.747471 1.137640 1.343339 1.096317 0.655141 0.037576 1.286106 -0.396608 1.310863 1.072774 0.013655 0.220749 -0.215382 0.087335 1.489739 0.952386) ) ;;; 75 odd -------------------------------------------------------------------------------- ; 8.6603 (vector 75 10.942812919617 (fv 0 0 0 1 0 1 0 0 0 1 1 0 1 1 1 0 0 0 0 0 0 0 1 1 0 1 1 1 0 0 1 1 0 0 0 0 0 1 1 0 0 0 1 0 1 1 0 1 1 0 1 0 1 1 0 1 0 0 0 0 0 1 1 0 1 0 0 1 1 0 0 1 0 1 1) 8.649507 (fv 0.000000 1.109688 1.876179 -0.024908 0.874394 0.094974 0.967726 0.182001 1.798004 0.764080 1.705983 0.246581 0.919892 -0.031641 0.074543 1.466120 -0.542452 1.308866 1.354893 0.937217 0.141091 0.972731 1.649929 0.076730 0.306081 1.082330 -0.056612 -0.033267 0.417204 0.002975 0.510299 0.334065 0.921554 0.578842 0.861949 0.516829 0.507298 0.089901 1.846522 0.266232 1.636125 0.773196 1.708397 0.143239 0.982116 1.755516 1.504659 0.043743 0.095624 0.325057 0.879744 1.064185 1.252657 0.311473 1.870059 0.309527 1.581011 1.908962 0.734045 1.785988 0.038323 0.023116 0.922283 0.858183 0.320752 1.741469 1.289108 0.871189 -0.238214 1.531119 1.355752 0.609175 0.669122 0.984951 0.033177) ) ;;; 76 odd -------------------------------------------------------------------------------- ; 8.7178 (vector 76 11.21743106842 (fv 0 0 1 1 0 0 0 1 0 1 1 1 1 1 1 1 1 0 1 1 0 0 0 1 0 1 1 1 0 0 0 1 1 0 0 0 0 1 1 0 0 1 0 0 0 0 0 1 0 1 0 0 0 0 1 0 1 1 0 1 0 0 1 0 1 0 1 1 1 0 0 0 0 0 0 0) 8.651279 (fv 0.000000 0.173353 0.839453 0.789458 1.213196 0.485342 1.020793 1.079117 1.510944 0.872759 1.658963 0.469539 1.282086 0.224500 1.187595 1.001928 0.601189 0.457802 1.523606 0.013310 0.486526 1.038767 0.887428 0.818932 0.429987 0.518887 0.949464 1.376735 0.275451 0.805159 0.132159 1.431344 0.575428 0.009721 1.711880 1.360202 0.416637 0.859810 0.491831 0.882963 0.253397 0.012929 1.530000 0.177927 1.883242 1.959160 0.357646 1.604277 0.939839 1.031583 0.502599 0.924357 -0.060587 1.148550 0.762073 0.585290 1.515308 1.022656 0.505967 0.958132 1.937796 0.289650 0.388753 1.349929 0.430727 1.688517 1.350532 0.156971 0.890960 0.708951 1.606885 1.582622 1.628222 1.565608 0.127771 0.825769) ) ;;; 77 odd -------------------------------------------------------------------------------- ; 8.7750 (vector 77 11.192246437073 (fv 0 1 0 1 1 0 1 0 0 0 0 0 1 0 1 0 0 1 1 0 1 0 0 1 0 1 0 0 0 0 0 1 0 0 0 1 0 1 0 0 0 1 1 0 1 1 0 1 0 0 0 1 1 1 1 0 0 1 1 0 1 1 1 0 0 1 1 1 0 1 1 0 0 0 0 0 0) 8.707019 (fv 0.000000 1.733898 1.602888 1.700625 0.951967 1.205480 0.494785 0.079322 1.861432 1.411332 0.615577 0.456043 0.176616 0.522662 0.530871 0.948923 1.312747 1.035434 -0.217439 1.260792 0.366350 -0.233439 0.849314 1.174459 -0.193276 1.451248 0.290403 1.453670 0.668542 0.644436 1.306523 1.198202 0.657361 0.888118 1.964614 0.824349 -1.765380 0.784141 0.143386 -0.053030 0.033585 0.726269 -0.055055 0.121221 1.064245 1.578078 0.715470 -0.211778 1.194974 -0.095151 0.313319 0.914111 -0.007802 0.154723 0.086177 1.895682 1.191957 -0.344176 -0.285803 0.072705 0.944928 0.649978 0.107843 0.251480 -0.267013 1.016287 0.107966 1.055797 1.067984 1.857635 0.230948 0.492625 0.104053 0.572353 1.732176 0.353482 0.821975) ) ;;; 78 odd -------------------------------------------------------------------------------- ; 8.8318 (vector 78 11.455265310659 (fv 0 0 1 0 0 0 0 0 0 0 1 1 0 1 1 1 0 1 0 0 0 0 0 0 0 1 1 0 0 0 0 1 1 1 1 0 1 1 1 1 0 1 0 1 1 1 0 1 0 1 1 0 0 1 1 0 0 1 1 0 0 1 0 1 1 1 0 1 0 0 1 0 1 0 1 1 0 0) 8.715270 (fv 0.000000 1.669247 0.757594 0.165819 0.288294 0.684770 0.557521 0.680526 1.097350 0.470057 1.849497 1.090608 0.922922 1.129049 0.104794 -0.129005 0.326960 -0.051784 1.142568 0.483331 0.896117 0.813482 0.302867 0.073158 -0.168821 0.656167 0.700004 1.004810 -0.007423 -0.189996 0.560929 0.412734 0.830296 1.110767 -0.043008 0.613326 0.576197 0.610404 1.233787 0.583712 0.887457 1.853983 1.162911 1.497407 0.204463 1.117898 1.731543 1.711291 0.816677 1.207698 1.691953 0.214296 -0.046452 0.692536 0.108168 0.208702 0.459557 1.630550 -0.229002 1.446147 1.208030 -0.028606 1.708585 1.336818 1.004606 0.393864 1.182948 -0.208442 1.255124 0.056920 1.572769 0.643674 1.170025 0.291140 1.025254 0.562266 0.633856 0.124004) ) ;;; 79 odd -------------------------------------------------------------------------------- ; 8.8882 (vector 79 11.54291004024 (fv 0 0 1 1 1 0 0 1 0 1 1 1 1 1 1 1 0 0 0 1 1 0 1 0 0 1 0 0 0 0 0 1 1 0 1 0 0 1 1 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 1 1 0 0 1 1 0 1 0 0 0 1 0 0 1 1 1 0 0 1 0 1 0 1 0) 8.864559 (fv 0.000000 0.357256 0.036759 1.292339 -1.618603 1.176406 0.544736 0.398074 0.109043 0.617241 0.697903 1.118083 1.422870 1.215951 0.004362 1.621202 0.264308 0.010496 1.213090 1.597753 -0.054911 1.223572 0.202448 0.615339 0.757193 0.130847 1.245098 1.256256 1.117774 0.701640 1.170787 1.057213 -0.087146 1.024522 1.105914 1.493238 0.672326 0.950638 -0.158430 0.266150 1.329043 0.773121 1.527296 -0.078973 1.669452 1.490229 0.141063 1.057903 0.727028 1.146281 0.010335 0.602841 1.428986 1.325796 1.320411 -0.094534 0.491229 0.443206 1.223761 0.317919 0.333487 -0.004296 1.074159 1.511918 1.245758 0.213171 1.140531 1.245789 0.552067 1.083032 0.600490 0.777304 0.106919 1.336123 1.060329 1.059212 0.289692 1.668881 1.086200) ) ;;; 80 odd -------------------------------------------------------------------------------- ; 8.9443 (vector 80 11.122416496277 (fv 0 0 0 0 1 1 0 0 1 0 1 0 0 0 1 1 1 1 1 0 0 0 1 0 1 0 1 1 1 0 0 0 0 0 1 0 0 0 1 1 0 1 1 1 0 0 0 1 0 1 0 0 0 0 1 0 0 1 0 0 1 0 1 0 0 0 0 0 0 1 0 1 0 0 1 1 1 0 1 1) 8.870144 (fv 0.000000 0.655710 0.591720 1.625031 0.418269 1.346736 0.349691 1.735905 1.181438 1.185938 0.537355 1.048431 0.310338 0.725392 0.138830 -0.162626 -0.012235 1.033480 1.181949 0.616925 1.912794 0.918753 0.626238 0.223870 0.664522 -0.078088 0.256973 1.394811 0.721353 1.350998 0.870615 0.111718 1.175636 1.041732 -0.087582 0.658928 1.024480 -0.106481 0.957206 0.153547 0.343423 1.369668 0.634606 0.765343 -0.148776 0.328436 0.827668 1.133483 1.461950 0.929478 0.348570 1.212214 0.446866 0.848436 0.219387 1.773456 1.168998 0.793903 0.614230 1.089360 1.446367 1.640320 0.120507 0.926616 0.816912 0.468029 0.525200 0.868913 1.510302 1.541893 -0.030330 0.055242 0.070867 0.042035 1.687456 0.144651 -0.241563 0.096801 -0.095086 0.917714) ) ;;; 81 odd -------------------------------------------------------------------------------- ; 9 (vector 81 11.372210502625 (fv 0 0 1 0 1 0 0 0 1 0 0 1 1 1 1 0 1 0 1 0 1 0 0 0 0 1 1 0 0 1 0 1 1 1 1 0 1 0 1 1 0 0 0 1 0 0 1 1 0 1 0 1 0 0 1 1 0 0 0 0 1 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 1 1 0 1 1) 8.926326 (fv 0.000000 0.164735 -0.380225 0.081555 1.097918 1.524480 0.077656 0.977304 0.407700 0.831319 0.533822 0.615403 1.642513 -0.058036 0.444751 1.446330 0.995710 0.841112 0.528746 0.832226 0.248085 0.502898 1.190162 0.745146 -0.208212 0.492995 1.110378 0.980131 0.817203 1.338834 1.000001 1.336192 1.804389 0.900670 0.555661 1.748659 0.603816 0.728857 -0.167279 1.058563 1.176033 1.277029 1.122180 1.127499 -0.224172 0.316000 1.080199 0.508511 0.252234 0.338999 0.400496 1.857653 0.607017 0.245631 0.807136 -0.037588 -0.063570 1.552479 1.126540 0.180335 0.976685 0.410774 1.244176 1.541645 1.450598 0.050542 0.208414 1.102430 0.959489 0.189328 0.354550 1.724776 1.384943 0.545643 1.965929 0.479461 0.756949 1.038515 -0.004640 1.477899 0.906680) ) ;;; 82 odd -------------------------------------------------------------------------------- ; 9.0554 (vector 82 11.662058134504 (fv 0 1 0 0 0 0 0 1 0 0 1 0 1 1 1 1 1 0 0 1 0 0 1 1 0 1 1 1 0 1 0 1 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 1 1 0 0 0 1 0 0 1 1 0 0 0 1 0 1 0 0 1 1 1 0 1 1 1 0 0 0 0 1 0 1 1 0 0) 8.895498 (fv 0.000000 1.650756 0.929235 0.669074 0.458613 1.575883 1.406092 1.106790 0.596730 0.021347 1.134970 0.616933 1.701827 0.504785 1.614982 1.519418 0.470952 1.289129 0.059550 0.427695 0.231422 1.559220 0.383709 0.161407 0.068209 -0.031038 1.865998 -0.109083 1.124535 0.249567 0.520329 0.463755 1.759816 0.122747 -0.063135 1.879507 0.089457 0.845717 1.061947 -0.248630 -0.240924 0.207853 1.548893 0.621489 0.599673 1.031885 -0.104736 1.726398 0.898686 0.128558 0.928155 1.723232 0.730130 1.329452 0.779285 1.207734 0.370523 1.269134 1.812531 0.562255 0.696469 1.440871 0.214062 1.838981 0.082605 1.605017 1.504365 0.122097 0.273097 0.895327 0.555120 -0.358045 0.959494 0.864915 1.049696 1.458692 1.063317 -0.105762 0.240946 0.516137 0.295184 -0.035654) ) ;;; 83 odd -------------------------------------------------------------------------------- ; 9.1104 (vector 83 11.732900669843 (fv 0 0 0 1 1 1 1 1 0 0 0 0 0 1 0 0 0 0 1 0 1 1 0 0 1 0 1 1 1 1 1 1 1 0 1 0 1 1 0 1 1 0 1 0 0 1 1 1 0 1 0 1 0 0 1 1 0 0 1 1 0 0 1 1 1 1 1 0 0 0 0 1 0 0 0 1 0 1 0 0 0 0 1) 9.060733 (fv 0.000000 0.847614 1.074595 0.345210 0.202371 1.511917 1.112425 0.572830 1.582187 0.218687 0.979697 0.829284 0.504832 0.409321 1.581223 1.031036 0.666780 1.347208 1.680503 1.486577 0.618089 -0.256946 0.905019 0.230952 0.059969 -0.145434 0.545921 0.384376 1.384380 0.665205 1.583895 0.055621 1.669433 1.386960 1.917214 0.552314 1.477586 0.229404 -0.049820 0.210015 -0.192839 1.819422 0.656731 1.258726 0.062676 0.649682 -0.033937 1.076469 0.763030 0.654748 1.032680 0.850557 0.101236 1.303860 1.683735 0.917766 1.133625 0.788918 0.091033 0.752267 0.650807 0.661591 0.956487 -0.151184 1.699725 0.067039 0.562858 0.669739 1.945082 0.507537 0.168655 1.291963 1.367257 0.073343 1.018407 0.584241 1.284655 0.733315 0.794277 0.838058 0.819351 1.776021 0.236189) ) ;;; 84 odd -------------------------------------------------------------------------------- ; 9.1652 (vector 84 11.626023292542 (fv 0 0 1 0 0 0 1 0 0 1 1 1 0 1 1 0 1 0 0 0 0 0 1 0 0 1 1 1 0 1 0 1 1 0 1 1 0 1 0 1 0 0 0 0 1 1 1 1 0 1 0 0 0 1 0 1 1 0 1 0 0 0 0 0 1 0 0 0 0 0 0 1 1 1 0 0 0 1 1 0 0 1 0 1) 9.185550 (fv 0.000000 -0.021653 -0.040601 1.163796 1.903509 0.943755 0.646624 1.866284 1.925515 0.123826 0.553199 0.965947 -0.075756 1.082744 1.817561 1.285536 1.050220 0.807240 0.605743 0.429498 0.508235 1.302559 1.611197 -0.514061 0.753992 1.700832 1.582166 0.521137 0.493019 0.834823 1.698189 0.272829 1.846496 1.874128 0.834101 0.281869 1.080560 1.438521 0.953941 1.280344 1.022208 1.661905 1.607595 1.126422 0.777808 0.689451 0.023149 0.691721 0.542242 0.838865 0.011483 1.098563 0.333470 0.611697 0.199907 -0.091248 0.912993 0.515958 1.079940 1.005613 0.731323 0.930947 0.301128 0.363360 0.978049 -0.000124 -0.516420 0.523117 0.574889 0.270432 1.275532 0.818251 1.531964 1.322842 0.207974 1.087144 1.315578 0.094014 1.345898 1.884730 0.414183 1.230212 1.440972 0.367718) ;; (fv 10.778808034738 -0.227659005925 3.1786048937356) ;; 10.7788 (fv 0.0000 0.9393 1.9022 0.8886 1.8986 0.9322 1.9893 1.0700 0.1743 1.3021 0.4535 1.6284 0.8269 0.0490 1.2946 0.5638 1.8566 1.1729 0.5128 1.8762 1.2632 0.6738 0.1079 1.5656 1.0469 0.5517 0.0801 1.6320 1.2075 0.8066 0.4292 0.0754 1.7452 1.4385 1.1554 0.8959 0.6599 0.4474 0.2586 0.0933 1.9515 1.8334 1.7387 1.6677 1.6202 1.5963 1.5959 1.6191 1.6659 1.7362 1.8301 1.9476 0.0886 0.2531 0.4413 0.6530 0.8882 1.1471 1.4295 1.7354 0.0649 0.4180 0.7947 1.1949 1.6186 0.0660 0.5368 1.0313 1.5493 0.0909 0.6560 1.2448 1.8570 0.4929 1.1522 1.8352 0.5417 1.2718 0.0254 0.8027 1.6034 0.4278 1.2757 0.1471 ) 9.165706 (fv 0.000000 0.934656 0.009740 0.892912 1.914788 0.817407 -0.047164 1.003969 0.164884 1.249319 0.380071 1.616476 0.954376 0.202231 1.312292 0.604557 -0.077459 1.312472 0.754364 -0.003767 1.276135 0.650523 0.170854 1.618591 1.053160 0.577476 -0.205916 1.453889 1.286143 0.889924 0.243897 -0.239706 1.833300 1.444468 1.151374 0.857183 0.586020 0.323924 0.036983 0.119493 -0.037558 1.940953 1.593882 -0.092635 1.798428 1.555339 1.399215 1.467642 1.835150 1.833867 -0.004678 -0.067916 0.264183 0.072836 0.826599 0.656778 1.089237 1.011513 1.337524 1.652586 0.118011 0.621082 0.947811 1.150679 1.538842 -0.108726 0.395215 0.886557 1.570811 -0.049501 0.809380 1.348209 1.743527 0.295071 1.055258 1.946886 0.463731 1.299054 0.188329 0.827519 0.037317 0.845744 1.341936 0.257273) 9.138477 (fv 0.000000 1.077136 0.063003 0.974335 0.001930 0.872203 0.017246 1.080670 0.235219 1.252888 0.378851 1.612382 0.956324 0.200975 1.336006 0.666511 -0.109401 1.250621 0.645704 -0.034379 1.373066 0.621844 0.153419 1.662637 1.014313 0.564772 -0.158790 1.458303 1.312400 0.935605 0.228083 -0.303405 1.933909 1.508310 1.203183 0.851210 0.700949 0.260045 0.137593 0.186330 -0.029149 0.093187 1.669321 -0.022893 1.804433 1.569916 1.547568 1.535838 1.866608 1.883016 0.163191 -0.079249 0.336381 0.043460 0.741963 0.718443 1.177177 1.028118 1.387506 1.729902 0.144100 0.716901 1.003307 1.132902 1.504355 -0.063217 0.409728 0.962060 1.632348 0.020339 0.842809 1.386919 1.688164 0.250155 0.883600 1.992873 0.466027 1.340844 0.278519 0.955099 -0.020386 0.926876 1.398431 0.248264) 9.133456 (fv 0.000000 1.059401 0.031287 0.939386 -0.017860 0.901644 0.001799 1.027990 0.230681 1.311963 0.341928 1.644077 0.966811 0.236475 1.300649 0.692497 -0.027953 1.347389 0.723063 -0.003313 1.322772 0.582050 0.159545 1.703814 1.026586 0.555590 -0.158337 1.444034 1.321735 1.003900 0.274358 -0.325622 1.927342 1.457207 1.230507 0.919830 0.720469 0.244803 0.085297 0.173845 -0.048361 0.080359 1.671325 0.039907 1.736091 1.631912 1.486133 1.471880 1.784848 1.922823 0.107240 -0.103436 0.280519 -0.025774 0.700275 0.720167 1.157653 1.036798 1.295565 1.717341 0.156191 0.724169 1.042098 1.172208 1.529978 -0.089227 0.426393 0.952547 1.692201 0.117254 0.809203 1.354853 1.694705 0.278490 0.926144 0.035100 0.434956 1.402186 0.356337 0.912787 0.017302 1.021860 1.401595 0.333844) ) ;;; 85 odd -------------------------------------------------------------------------------- ; 9.2195 (vector 85 11.829360154975 (fv 0 0 0 1 0 0 1 0 0 0 1 1 1 0 1 0 0 0 0 0 1 0 1 0 0 1 1 0 1 0 1 0 0 1 0 1 0 0 1 0 1 1 1 1 1 0 0 0 0 1 1 1 0 1 0 0 0 0 0 0 1 0 0 1 1 0 0 1 0 0 1 0 0 0 0 1 1 1 0 0 0 1 1 0 1) 9.172932 (fv 0.000000 1.198268 -0.046093 0.496651 0.155499 0.438914 1.717129 -0.153996 0.255959 0.942459 -0.112043 1.664994 1.597976 1.071752 0.293731 1.489898 -0.088206 1.402767 1.814932 1.099748 -0.400724 1.351064 1.265640 1.075629 0.060651 -0.371046 0.814537 0.326687 0.633977 1.654428 1.582553 0.618025 1.054016 1.391986 1.098803 0.284271 1.476963 1.042434 1.922088 0.305413 -0.626240 1.791879 1.777727 0.678099 1.505684 1.182071 0.629820 1.357783 0.665420 0.341784 0.926591 0.193623 1.006880 1.192651 -0.116178 0.080172 1.591790 1.522361 0.438822 1.766471 0.395503 1.446548 -0.046614 0.961931 0.316539 0.616763 1.087859 0.290761 0.142685 0.155135 0.508154 0.686168 1.471184 1.165229 0.372220 0.294409 0.404832 -1.767095 1.243980 0.993281 1.007462 0.784244 1.104711 1.671816 0.086342) ) ;;; 86 odd -------------------------------------------------------------------------------- ; 9.2736 (vector 86 12.140432277993 (fv 0 0 0 1 0 0 0 0 1 1 0 0 1 0 1 0 1 0 0 0 1 1 1 1 1 1 1 1 0 1 1 0 1 1 1 1 1 1 1 0 1 1 0 1 1 0 0 0 0 1 0 0 1 1 1 1 1 0 1 1 0 0 1 0 0 0 1 0 0 1 0 1 0 0 1 0 1 1 1 1 0 0 0 1 0 1) 9.213343 (fv 0.000000 0.676268 0.369198 1.486263 -0.026625 0.678855 0.928889 1.200870 0.763422 0.131815 -0.064018 0.334478 0.754549 0.549209 0.781916 -0.164085 1.831169 -0.359871 0.452632 0.395640 1.217523 1.666783 1.263104 0.462675 0.487261 1.713262 0.419400 0.982422 0.818648 0.009279 0.749148 0.986045 1.410580 0.251205 1.543152 0.685375 0.249458 0.699138 0.175620 0.312944 1.884362 1.099441 1.640835 1.728596 -0.397229 1.509431 0.364317 1.073248 1.571193 0.690550 1.201949 -0.104903 0.984182 0.850373 -0.106842 1.582861 -0.052279 0.837387 1.423896 1.118738 -0.077783 0.539913 1.394923 -0.009295 1.541216 0.438460 0.217352 0.527395 0.855264 0.357004 0.424674 0.870332 0.435096 0.770273 0.096843 1.702425 0.991351 1.315154 1.133850 0.440564 0.044541 0.788769 0.138246 -0.080948 1.096067 0.575869) ) ;;; 87 odd -------------------------------------------------------------------------------- ; 9.32737905 (vector 87 11.937030388359 (fv 0 0 1 1 1 1 1 1 0 1 1 1 0 1 0 1 0 1 0 1 0 0 1 0 1 1 1 1 0 0 0 1 0 0 1 0 1 1 1 1 0 1 1 1 1 0 0 1 0 1 0 0 1 0 1 1 0 0 0 0 1 1 0 0 1 1 0 0 1 1 0 0 0 0 1 1 0 0 1 0 0 0 0 1 1 1 1) 9.317037 (fv 0.000000 1.269780 0.764198 1.382169 0.560101 1.397366 0.619615 1.110127 1.074742 0.786154 0.097129 0.187903 1.280480 1.001234 0.625991 -0.253578 0.524611 0.642531 0.754319 1.395067 1.865340 0.173765 1.213561 0.413784 0.704706 0.640451 1.483492 1.299442 0.783307 0.912207 0.977809 1.588075 -0.173310 1.063721 0.534821 0.450809 0.251070 0.792950 1.489833 1.745329 1.098607 0.960633 0.682333 0.343541 0.677820 0.343804 -0.007548 0.114569 1.083276 0.044826 0.931689 1.109596 -0.582840 1.287598 0.295851 -0.261696 1.183896 0.581304 -0.088958 1.623439 0.434479 0.025514 0.230711 1.672013 0.717129 1.395826 0.682208 -0.299168 -0.096350 -0.604219 1.679467 0.411395 0.711815 1.234251 0.324421 0.995113 0.167630 0.383406 0.968742 0.310771 0.425004 0.820195 0.922682 1.343873 0.606017 -0.248788 1.112139) ) ;;; 88 odd -------------------------------------------------------------------------------- ; 9.3808 (vector 88 12.128922775356 (fv 0 1 0 1 0 0 0 1 1 1 1 1 1 1 1 0 0 0 1 0 0 0 0 0 1 0 0 1 1 0 1 0 0 1 0 0 1 0 0 1 1 1 0 0 0 0 0 0 1 0 1 1 1 0 0 1 1 0 0 1 0 1 0 1 1 0 1 0 1 1 1 0 1 1 1 1 1 1 0 0 1 0 1 1 0 0 0 1) 9.324023 (fv 0.000000 0.720070 1.146170 1.623229 0.919914 1.475051 1.669418 0.417706 1.222880 1.077800 0.636671 0.109954 0.709268 0.401961 1.342317 0.470950 1.038199 -0.014165 -0.223115 1.401527 0.255061 -0.053613 1.038430 1.524899 0.900064 0.540757 0.958685 1.268571 0.665381 1.798791 1.658869 0.625852 0.519615 0.589311 -0.003435 1.345809 -0.056260 0.616788 0.290786 1.478184 0.854964 0.750706 1.853143 1.837616 0.068009 0.196260 1.496079 0.820255 1.744388 0.146057 0.230788 1.434358 -0.205448 1.616936 0.981163 0.921532 1.591565 1.188825 -0.476209 1.518808 0.443241 0.115647 0.334751 1.367563 0.160132 1.179927 1.012776 0.498582 1.276116 0.704338 1.396987 -0.001804 0.959954 1.167324 1.287070 1.914346 1.400505 1.413492 1.484414 -0.463663 0.122173 0.488918 -0.038072 1.041389 -0.101511 -0.067115 1.661217 1.643428) ) ;;; 89 odd -------------------------------------------------------------------------------- ; 9.4340 (vector 89 12.362 (fv 0 1 1 0 1 1 1 0 0 0 1 0 0 1 0 1 1 1 1 0 0 1 0 0 0 0 0 1 1 0 0 1 1 1 1 0 1 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 1 1 1 1 1 0 0 1 0 1 1 1 0 1 1 1 1 0 1 1 0 1 0 1 0 1 1 1 0 0 0 1 0 1 1 1 0) 9.331615 (fv 0.000000 0.049094 0.763150 0.136548 0.483778 0.759076 0.333224 1.220929 0.134557 0.764345 0.615745 -0.054859 0.470862 1.549452 1.042755 0.304443 0.281140 1.178803 1.496311 1.304814 1.254180 1.214938 -0.188361 1.642263 1.456263 1.200682 1.159330 0.518402 1.259168 1.450349 0.156876 1.423052 0.526144 0.557187 0.211944 1.876505 0.927439 -0.029530 0.421763 1.206664 0.690297 1.789526 1.067082 0.003086 0.897179 1.065326 1.434687 0.576391 -0.150316 1.287422 1.126966 1.259277 1.431443 0.305104 0.343134 0.824875 1.068860 1.722713 1.668311 0.909968 1.314221 0.346498 0.614998 0.306500 1.059400 1.495807 -0.733779 1.277563 0.627585 1.184462 -0.276841 0.360604 0.535684 -0.101891 0.124422 1.197248 0.778353 1.945787 1.307086 0.922575 0.921600 0.870062 1.105219 1.606237 0.868032 -0.120196 0.316193 -0.191814 0.432808) ) ;;; 90 odd -------------------------------------------------------------------------------- ; 9.4868 (vector 90 12.309 (fv 0 0 0 0 1 1 0 1 1 0 1 1 0 0 1 1 0 1 0 0 1 0 1 1 1 1 0 0 0 0 0 0 1 1 0 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 0 1 1 0 0 0 1 1 1 0 1 1 1 0 0 1 0 1 0 1 1 1 1 0 0 0 1 0 1 0 1 0 1 0 1 0 0 0 1) 9.421684 (fv 0.000000 0.773463 -0.034237 0.815187 0.818292 -0.048506 -0.025177 1.145716 1.124687 -0.087471 0.982715 1.911529 0.885016 -0.169554 0.478422 0.410159 1.012688 0.169228 0.764485 0.758910 1.289872 0.618276 -0.229660 1.549110 0.758331 0.279930 1.553579 0.672439 0.162166 0.690601 0.847281 1.562839 1.023152 1.146052 1.063766 0.943600 -0.316637 0.816595 1.430319 0.223152 0.862408 0.935019 0.764642 0.942440 1.888157 1.614273 1.641359 1.139335 1.700104 1.516977 1.001915 0.698936 0.890613 1.412580 1.482707 0.374132 0.486389 0.409585 0.664613 0.728056 0.135717 1.017586 1.427256 0.114262 0.459920 0.985474 0.828118 0.029864 1.115880 0.182529 0.074455 0.121011 1.384155 1.498024 1.812648 0.488592 0.254186 1.880026 1.059948 0.152702 0.760476 0.236696 1.396118 1.492214 0.743805 1.035917 1.060796 0.484826 0.509085 -0.305704) ) ;;; 91 odd -------------------------------------------------------------------------------- ; 9.5394 (vector 91 12.351367950439 (fv 0 1 0 1 1 0 1 1 0 1 0 1 0 0 1 0 1 0 0 0 0 0 1 0 0 1 0 1 0 0 1 1 1 0 0 0 1 0 1 1 1 1 1 1 0 1 1 1 1 1 0 1 1 0 0 0 1 1 1 1 1 0 1 1 1 1 1 0 0 0 1 0 0 0 1 1 0 1 1 1 0 0 1 0 0 1 1 1 1 1 0) 9.456608 (fv 0.000000 0.103422 0.965610 0.946880 1.775735 -0.122619 1.034051 0.168472 0.730448 0.272671 0.778481 0.021689 0.033093 0.984786 1.059637 0.145824 1.327186 1.317989 0.064861 1.738590 0.743092 0.115729 -0.009073 0.235258 1.253963 0.597261 1.473274 1.451939 1.654969 1.556762 -0.031925 0.584248 1.188923 1.752060 0.699420 0.272619 1.021928 1.546707 1.001394 0.687724 1.015815 0.834084 -0.085438 1.600278 0.991105 1.336531 1.547902 0.640465 0.462581 1.062100 1.213310 0.321259 0.291622 0.063730 0.566090 0.852786 0.847201 -0.174185 1.395263 1.222072 0.870150 0.708746 0.513822 0.978903 0.739358 1.760219 0.991895 1.423353 0.493188 0.952658 -0.084183 1.857020 1.060335 -0.192588 0.702407 1.144217 1.162221 1.656319 1.357097 0.810997 -0.196628 1.185541 1.692605 1.048778 1.191279 0.597890 1.575870 0.403387 0.283378 0.378021 0.172627) ) ;;; 92 odd -------------------------------------------------------------------------------- ; 9.5916630 (vector 92 12.280749613899 (fv 0 1 0 0 1 0 0 0 1 1 1 1 0 0 1 1 0 0 0 1 1 0 1 1 1 1 1 0 0 1 1 0 0 0 0 0 1 1 0 0 0 1 0 1 1 1 1 0 1 0 1 0 1 0 1 1 0 0 1 0 1 0 0 0 1 0 0 1 0 0 0 1 1 0 0 1 0 0 0 0 0 0 0 1 1 0 0 0 0 1 0 1) 9.552661 (fv 0.000000 1.217977 1.385618 0.939614 0.500483 1.851006 0.319542 1.708679 0.556310 0.891376 0.674923 0.365733 -0.175465 0.892985 1.540146 0.973262 0.317469 1.925159 0.685389 1.371188 0.200154 1.709968 0.177693 -0.300538 0.695154 0.829261 0.826887 0.518213 1.033752 1.220316 0.472703 1.153927 1.069740 0.054639 0.285291 1.692400 0.723359 -0.010143 1.422901 0.759732 0.421539 1.178988 0.292771 1.282542 0.969261 0.723210 1.587532 1.451565 0.985309 0.576854 0.032105 1.279589 0.637040 0.836814 1.053214 1.607968 0.083343 0.618958 1.664826 -0.072056 0.366474 1.110340 1.463534 0.789016 1.455017 1.061490 0.999534 0.659448 0.541265 1.191626 1.594463 0.899514 1.279707 0.844186 0.855539 -0.116804 0.909316 1.750334 1.598414 1.853269 0.368452 0.535158 0.818452 1.438032 0.503813 0.301666 0.154109 0.506999 0.079492 -0.057406 1.894913 0.600742) ) ;;; 93 odd -------------------------------------------------------------------------------- ; 9.6437 (vector 93 12.403578299298 (fv 0 1 1 1 1 0 1 1 1 0 0 0 1 1 1 1 0 1 1 1 1 1 1 0 1 1 0 1 0 0 1 1 0 1 0 1 1 0 0 0 1 0 0 0 1 1 1 0 1 1 0 1 1 1 0 1 1 1 0 0 0 0 0 1 0 0 1 0 1 0 1 1 0 1 1 0 1 0 1 0 1 0 1 1 1 1 0 0 1 0 1 1 1) 9.628761 (fv 0.000000 1.192712 1.317592 0.793671 0.099933 -0.070495 0.916675 1.443504 0.876536 1.333886 0.502339 0.879490 0.963974 1.813405 1.616449 1.406560 0.249623 1.099165 1.684130 0.971324 1.504790 0.210004 -0.334645 1.442259 0.574758 1.021850 0.284510 0.399479 0.184247 1.487488 1.612401 -0.235561 -0.129797 0.178650 -0.371978 0.920412 -0.107159 0.561074 0.178586 0.184745 -0.019738 0.790773 0.250122 1.738768 1.375989 -0.216295 -0.331946 0.885688 1.988915 0.048056 0.095104 0.757409 -0.209034 0.574534 0.777126 1.337323 -0.015675 1.471677 1.723082 0.373584 0.844517 1.228790 1.358490 1.817661 1.097143 1.261125 0.949204 1.719884 0.720744 1.257519 0.078221 -0.091904 0.999562 0.486340 0.282135 0.639284 -0.163690 1.618168 0.349231 0.088441 0.985965 0.932832 1.613134 0.712978 1.300533 1.211114 1.605834 1.719815 0.768198 -0.076989 1.468170 1.231822 0.852206) ) ;;; 94 odd -------------------------------------------------------------------------------- ; 9.6954 (vector 94 12.789479876738 (fv 0 1 0 1 1 0 0 1 0 1 1 0 0 1 0 0 1 1 0 1 1 1 0 0 1 1 1 0 0 0 1 0 1 1 1 1 0 0 1 1 0 0 1 0 1 0 1 1 1 1 1 0 0 1 1 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 0 1 1 1 1 0 0 1 0 1 1 1 1 0 1 0 0 0 1 0 1 0 1 1) 9.653914 (fv 0.000000 1.588712 0.970594 0.765681 0.768893 0.708013 1.088997 0.348116 1.304828 0.302466 0.484457 0.598101 1.195823 1.750495 0.723696 -0.394564 1.399290 0.440079 0.957225 0.110914 1.178680 -1.746723 0.306178 1.424281 0.083938 -0.026412 0.531864 1.282735 0.186630 0.411663 1.537740 0.224065 -0.422374 0.338118 1.366092 0.348038 0.469097 0.358167 1.178154 1.072296 0.953715 0.778556 0.718707 0.831159 0.966980 0.639988 0.294231 -0.156503 1.325326 0.192979 0.424804 0.332961 0.198719 0.405180 1.172779 0.251315 0.565156 0.903572 0.754645 0.195819 1.584153 1.274227 0.370217 1.346701 0.041617 1.218979 0.515044 1.085194 0.964032 1.907141 0.492814 1.684100 -0.290159 1.467461 0.104316 0.280575 0.761449 1.432721 1.137691 0.132533 1.823280 1.230711 -0.052109 1.493267 1.265211 0.071008 1.206644 0.630379 0.639830 0.932228 -0.085525 1.738146 1.623323 0.751204) ) ;;; 95 odd -------------------------------------------------------------------------------- ; 9.7468 (vector 95 12.575266058635 (fv 0 1 1 0 1 0 1 0 1 1 1 0 0 0 1 0 1 0 0 0 1 0 0 0 1 1 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 1 0 0 0 1 0 1 1 0 1 0 0 0 1 1 0 1 1 1 1 1 0 0 0 1 1 0 1 0 0 1 1 0 1 0 0 0 0 0 0 0 1 1 0 1 1 0 0 0 0 1 0 0 0) 9.716924 (fv 0.000000 1.295576 0.051583 -0.370221 1.659103 1.560139 0.883258 1.136184 1.446082 0.336165 0.984827 1.426922 1.840974 1.223315 0.635432 0.990680 0.332450 0.247993 0.361771 1.193162 0.200656 1.699397 1.071493 0.299430 0.743325 0.167398 0.140913 0.844624 1.382714 1.375685 0.647006 0.229451 0.386840 1.780080 0.889230 1.061105 0.116922 0.567648 1.435830 1.255231 0.833620 1.820993 1.158323 0.868650 0.833531 0.419654 1.734245 1.273400 1.062531 1.460253 0.175543 0.639252 0.712611 1.085237 0.872288 1.639660 -0.093743 0.087045 -0.323684 1.687923 1.002234 -0.168363 1.044853 -0.114093 1.195353 -0.026012 0.883764 1.512322 0.102179 0.114077 1.256119 1.084835 0.251990 0.992344 0.663746 0.903707 0.809231 1.141845 1.353235 1.559958 0.119755 1.444404 1.912417 1.220976 -0.164602 -0.295612 1.393445 0.425402 1.426929 1.201811 0.614353 -0.027563 1.025805 1.054465 0.134046) ) ;;; 96 odd -------------------------------------------------------------------------------- ; 9.7980 (vector 96 12.803173065186 (fv 0 0 0 0 0 1 1 0 1 0 1 0 0 0 0 0 1 1 0 1 0 1 0 1 0 0 1 1 1 1 0 0 1 1 1 0 0 1 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 1 1 1 1 0 1 1 0 0 0 1 0 0 0 0 1 1 0 1 1 1 0 1 0 1 1 1 0 1 0 0 1 1 0) 9.759447 (fv 0.000000 0.435576 1.538976 0.230825 0.102821 0.263319 0.997316 0.091618 0.472323 -0.103132 0.585027 1.906149 0.670612 1.002137 1.281685 0.083578 0.271396 0.433634 0.733402 0.099534 0.807149 -0.070119 0.575530 -0.103613 0.335070 1.262648 1.473382 0.330894 0.589593 0.216256 0.350636 1.350446 1.836442 1.560161 1.205882 0.649393 0.812682 0.141066 1.111869 -0.141497 1.693969 1.777393 0.080165 0.375196 0.449681 -0.067423 0.754077 0.868345 1.797143 0.793576 0.568117 0.646818 1.350309 1.187659 1.791215 0.862642 1.742949 1.213798 0.583814 0.650546 0.965237 1.015772 0.605956 0.144297 0.285298 -0.351085 1.282066 0.474001 0.642725 0.511289 1.457452 0.929763 1.241810 0.227521 0.228779 1.199150 1.811444 -0.006366 0.744946 0.179491 1.361847 -0.378016 1.423650 1.452225 1.393417 1.335482 0.037183 1.548694 0.890495 0.461455 1.744132 0.896894 0.307836 1.812808 0.221251 0.928513) ) ;;; 97 odd -------------------------------------------------------------------------------- ; 9.8489 (vector 97 12.837450993031 (fv 0 0 1 1 0 1 1 0 0 0 1 0 1 1 0 1 0 1 1 0 0 0 1 1 0 0 0 0 1 1 1 1 1 1 0 1 1 1 0 0 1 1 0 0 1 1 1 1 0 0 0 1 0 1 0 0 1 0 0 1 0 1 0 0 0 0 1 1 1 0 1 0 1 0 0 1 1 1 1 1 1 1 0 1 0 0 0 1 0 1 0 0 1 1 0 1 1) 9.832277 (fv 0.000000 0.379259 1.470054 0.135241 -0.137798 1.476571 0.223942 1.269139 1.617761 0.578479 1.659896 0.192321 0.628723 1.030748 0.068332 0.935772 0.702035 -0.308246 0.093619 0.687832 0.312122 0.952725 0.646784 0.815901 0.600402 0.700649 0.257079 0.728929 1.512814 0.133748 -0.161439 1.667289 1.756964 0.419090 1.460039 1.221568 0.216587 0.357346 0.560096 0.621329 1.423958 -0.140419 -0.285305 1.752977 0.296245 1.796763 0.502171 1.837539 -0.068388 -0.176521 1.655407 0.652714 1.571976 1.231728 0.781936 1.899698 1.696905 1.070324 0.093931 0.071079 0.376824 0.772939 1.099059 0.004831 0.221806 1.727680 0.800189 0.011067 0.690398 0.512420 0.475317 0.941280 1.720146 1.587206 0.923080 0.792083 0.180477 -0.133205 1.214230 1.814657 0.679279 0.282075 1.334889 1.751170 1.536951 0.882536 0.418450 0.834681 -0.026902 0.654794 0.680161 1.077779 1.525535 0.824205 1.102618 0.673911 -0.106249) ) ;;; 98 odd -------------------------------------------------------------------------------- ; 9.8995 (vector 98 12.972 (fv 0 0 1 1 1 0 1 1 0 1 0 1 0 1 0 0 1 0 0 1 0 1 0 1 1 1 0 1 1 1 0 0 1 1 1 1 1 1 1 0 0 0 1 0 1 0 1 0 0 1 1 1 1 1 0 0 0 1 0 0 1 0 0 0 1 1 1 0 0 0 1 1 1 1 0 1 1 1 0 0 0 1 0 1 1 0 1 1 0 0 0 0 0 1 0 0 1 0) 9.918320 (fv 0.000000 1.126272 0.810135 -0.157043 -0.284411 1.014546 1.656515 0.886620 0.589412 -0.165849 0.041656 1.689870 -0.133502 1.386309 0.753684 1.607028 0.455527 0.729530 1.603812 -0.176801 0.980471 1.557823 1.120428 0.608500 -0.040856 1.654422 1.694414 1.546900 1.545046 0.721205 0.133219 1.189224 1.204719 1.195353 1.299299 -0.156627 0.826681 -0.088693 0.692437 1.036020 0.358333 1.488711 1.027717 0.069063 1.141577 0.328360 0.719016 0.851669 0.356065 0.712122 1.039551 1.236061 1.577925 0.317909 -0.158255 0.050224 -0.509790 1.519264 0.203085 -0.063235 0.037529 0.962155 1.059331 0.698574 0.810336 0.743673 1.683751 0.457113 0.419520 0.759860 1.462788 1.502247 0.636526 0.416346 0.963144 1.154048 0.694553 0.104918 -0.349860 1.108892 1.631062 0.589884 1.392769 1.258082 0.568391 0.753256 1.211016 0.009043 0.817095 0.265385 1.455548 1.585953 1.547698 1.855964 1.737942 0.229735 1.055700 1.696455) ;; pp: 9.852643 (fv 0.000000 0.515219 1.262972 1.697020 0.335436 0.889905 1.519089 0.044736 0.650497 1.270750 -0.178917 0.674989 1.450432 0.254900 1.097572 -0.107043 0.651195 1.335130 0.272796 1.297874 0.224159 0.962708 0.053062 1.193382 0.101327 0.836439 -0.105754 1.215012 0.128574 1.109391 0.442046 1.523411 0.553345 1.725474 0.541762 -0.127793 1.417975 0.631717 1.576620 0.767281 0.059112 1.609436 1.033347 0.556109 1.727081 1.010442 0.702568 -0.141336 1.349027 0.669399 0.583528 0.147350 1.497924 0.934945 0.610721 0.101044 -0.019997 1.772284 1.165297 0.883648 0.540756 0.695909 0.051843 0.036770 1.823953 1.940217 1.253231 1.381574 1.135330 0.962885 1.084109 1.188033 1.135270 0.827723 0.748628 1.126276 1.272339 0.770370 1.246808 1.223016 1.570254 1.399310 1.628085 1.829166 -0.154940 0.353005 0.721669 0.726808 0.892330 1.197955 1.533013 0.212675 0.669097 1.140181 1.156217 1.790457 0.422623 0.510791) ) ;;; 99 odd -------------------------------------------------------------------------------- ; 9.9499 (vector 99 13.000000000002 (fv 0 1 0 1 1 0 1 0 0 1 1 1 1 0 1 0 0 1 0 1 1 1 1 0 0 1 1 1 1 1 0 0 0 1 0 0 0 0 1 0 1 1 0 0 1 0 0 0 0 1 1 0 1 0 0 0 0 1 0 1 0 1 0 0 0 1 1 0 0 1 1 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0 0 1 1 0 1 1 1 1 1 1 0) 9.927757 (fv 0.000000 0.612324 0.079141 1.434202 1.000660 0.891242 1.012263 -0.017562 0.996629 0.611063 1.321217 1.621637 1.504948 1.624898 0.001412 0.412734 0.326019 1.366721 1.072960 0.116515 0.715979 -0.740444 1.161301 1.297736 1.041757 0.027020 1.458453 1.107119 0.363908 1.415543 1.763457 0.255777 0.686434 -0.085735 0.651473 1.217063 -0.047283 1.151992 0.790695 -0.152103 1.647917 0.508714 0.628648 1.408143 1.292464 0.474000 1.003650 0.520847 0.629804 0.218082 0.785490 -0.232867 0.391411 1.172299 0.273141 1.313231 0.427739 0.013232 0.516032 0.610598 1.282766 1.029342 0.967918 1.073490 0.454858 0.915907 0.522595 0.274119 0.827376 0.861574 -0.158909 -0.432703 1.871750 1.122982 0.647824 -0.195710 0.262542 1.053968 0.565099 0.024117 0.401586 0.264805 1.587960 -0.370184 1.152346 1.774247 0.242656 0.316777 1.195086 1.067518 1.112347 0.688842 1.446613 0.608318 1.321142 -0.167020 0.907334 1.022140 1.062351) ) ;;; 100 odd -------------------------------------------------------------------------------- ; 10 (vector 100 13.117680368039 (fv 0 1 1 1 0 1 1 1 1 0 1 1 0 1 1 0 1 0 0 1 0 1 1 0 0 0 0 1 1 1 0 0 1 1 1 1 1 0 1 0 1 1 0 0 1 0 0 0 1 0 1 0 1 1 0 0 1 1 0 0 0 1 0 1 0 1 1 1 1 0 1 1 0 0 1 1 1 1 0 0 0 1 0 0 1 1 1 0 1 0 0 1 1 1 0 0 0 0 0 0) 9.967820 (fv 0.000000 1.016486 1.075466 0.675161 0.574401 1.527303 0.369311 1.093743 1.758162 0.649535 1.329616 0.683289 -0.464743 0.488528 0.846167 1.093202 0.188464 -0.009742 1.328398 -0.092736 0.866724 1.306141 0.236206 -0.048398 0.065984 1.250377 0.880265 0.529903 1.908284 0.909975 0.870318 1.170730 0.401807 0.051428 1.546047 -0.084383 1.553645 1.723234 -0.192262 -0.005451 0.846559 1.396413 0.793410 1.734419 0.268618 0.782362 0.300041 0.085963 0.406528 -0.058412 0.759019 0.311738 0.688186 1.163736 0.207596 0.957152 0.518038 -0.238894 1.966069 0.254028 0.497859 0.406362 0.948142 0.108565 0.809242 0.618274 0.008503 1.224166 0.619792 -0.063172 1.170177 1.631095 0.360399 0.496092 1.173684 1.571576 1.461266 0.250954 0.485376 0.293914 0.241987 0.266855 1.299097 1.747740 -0.157940 1.025403 0.055859 0.443647 -0.030039 1.366811 0.369467 1.523632 1.262832 1.148761 0.265795 -0.397124 0.678718 0.978216 1.111928 1.121642) ) ;;; 101 odd -------------------------------------------------------------------------------- ; 10.0499 (vector 101 13.28250751675 (fv 0 1 1 1 0 0 1 1 1 0 1 1 1 0 1 0 1 0 0 0 0 0 0 1 1 1 0 0 0 1 0 0 0 0 0 1 0 1 1 0 0 0 0 0 0 0 1 1 0 1 1 0 1 0 0 0 1 1 0 0 0 0 0 1 1 0 1 0 1 1 0 1 0 1 0 1 1 0 0 1 0 0 1 1 1 0 0 1 0 1 0 0 0 1 0 0 0 0 0 1 1) 9.964634 (fv 0.000000 -0.073111 1.535769 -0.102555 0.949824 0.661791 1.376397 0.389320 1.429271 1.382915 0.702074 0.190023 0.165010 0.880936 1.053717 0.381858 1.515003 1.204543 0.504035 0.920455 0.391206 0.949414 1.113429 0.554900 1.897469 1.768789 1.766679 1.550589 0.402518 0.254763 0.394916 1.625563 0.833640 0.744524 0.452145 -0.082936 0.892795 1.873582 1.781184 -0.418454 1.636196 -0.022737 0.903335 -0.412208 1.924024 0.194797 -0.087158 0.651748 1.188278 0.341571 0.583987 1.814760 1.207941 1.789448 0.551284 0.991618 0.259118 0.282624 1.011184 1.611901 1.372798 1.012968 0.839711 1.331909 1.264042 0.325794 0.343316 -0.075857 -0.460634 0.488689 1.512646 1.806638 1.012723 -0.303497 1.575625 0.027198 0.002241 1.290806 1.657896 1.438044 0.654010 1.150362 0.652919 1.476118 -0.053999 -0.024155 0.726437 0.454484 1.497660 0.765182 0.287065 1.425963 0.079052 0.750136 1.836142 1.337567 -0.185862 1.924720 -0.153672 0.400041 1.450120) ) ;;; 102 odd -------------------------------------------------------------------------------- ; 10.0995 (vector 102 13.159336831147 (fv 0 1 0 1 0 0 0 1 1 1 1 1 0 1 1 1 0 0 0 1 1 0 1 0 0 0 1 0 0 1 0 0 1 1 1 1 0 1 1 1 0 0 0 0 0 0 1 1 1 0 1 0 0 0 0 1 1 1 1 1 0 1 1 1 0 1 1 1 1 1 0 0 1 0 1 1 0 1 1 1 0 1 1 1 1 0 1 0 1 1 0 1 1 0 0 0 1 1 0 1 1 0) 10.045766 (fv 0.000000 -0.279070 0.173878 0.081403 1.768938 1.607495 0.603256 0.555897 0.375867 1.098499 0.557935 1.658062 0.679353 0.435605 1.704584 0.882188 0.675710 1.226519 -0.017413 0.221732 -0.211376 1.307302 0.689909 0.655783 0.993058 0.615004 1.764502 1.131327 0.119482 0.185094 1.035751 1.439320 1.373211 1.418236 0.503946 0.310742 0.195150 1.345393 1.645648 0.392993 0.050135 0.685592 0.243679 0.754096 0.965418 1.162001 1.767714 0.912263 1.540226 0.989163 0.153496 1.180193 0.495181 0.826820 -0.194339 1.268780 1.482827 -0.154668 1.003093 0.057371 1.563631 1.606126 0.908893 1.017810 0.439667 -0.174146 0.280275 0.399111 1.342959 -0.098826 1.087834 1.050762 0.557805 0.752893 -0.400427 0.095731 0.689016 0.552247 0.778927 0.058727 0.428406 0.269116 0.480708 0.192361 0.563638 0.686642 0.128600 1.864221 -0.045520 1.018032 1.780635 -0.005046 0.881801 1.021244 0.513775 1.482476 0.956890 0.518235 1.186738 -0.018819 1.609204 0.515712) ) ;;; 103 odd -------------------------------------------------------------------------------- ; 10.1489 (vector 103 13.142812158651 (fv 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 1 1 0 0 0 1 1 1 0 0 1 1 0 1 0 0 1 0 1 1 0 0 1 0 0 1 1 0 1 1 1 1 0 0 1 0 1 0 1 0 0 0 1 1 0 1 0 1 1 0 1 0 0 0 0 0 1 1 0 0 0 0 0 0 1 0 0 1 0 0 0 1 1 0 1 0 0 0 1 0 1 0 1) 10.102476 (fv 0.000000 1.369258 0.406430 1.487363 1.300312 1.174178 0.725871 1.118946 0.567934 1.507074 1.421940 0.060397 1.553534 0.366960 0.264364 -0.027869 1.681923 0.350717 1.364154 0.204515 -0.180262 0.842363 0.287472 1.198426 1.756374 1.259211 0.898266 0.187309 0.401610 0.535873 0.048012 0.851696 1.323060 0.925186 0.678890 0.097118 1.570744 0.545725 0.858166 1.853728 0.291531 1.096726 1.166849 -0.045402 1.179837 -0.111020 0.643454 0.486562 1.084325 0.673411 1.808268 0.331853 0.761303 0.506929 0.948787 0.125433 1.093138 1.172704 1.300823 -0.087765 1.061422 -0.231489 1.345595 1.007175 0.463207 0.567128 0.417701 0.867458 1.827132 1.618306 -0.235698 1.268358 1.413906 0.291274 -0.510359 1.287040 0.555326 0.694591 1.555786 1.225983 1.844314 0.908000 0.867329 0.232081 1.454227 0.972019 1.069240 0.133107 0.915878 0.821231 0.471133 1.434428 0.215881 0.667043 0.772841 0.944850 1.153588 0.551253 0.882554 1.134378 0.032596 -0.042233 1.758816) ) ;;; 104 odd -------------------------------------------------------------------------------- ; 10.1980 (vector 104 13.176067352295 (fv 0 0 0 1 1 0 1 1 1 0 1 1 1 0 1 0 0 0 0 0 1 1 1 1 0 0 1 0 0 1 1 0 0 1 1 1 1 0 1 0 1 0 0 1 0 0 1 0 0 1 0 1 0 0 0 1 1 0 1 0 0 0 1 1 1 0 1 1 1 1 1 1 1 0 1 1 0 1 0 1 1 1 1 1 1 1 0 0 0 1 0 1 0 1 0 0 1 0 0 1 1 1 1 0) 10.168550 (fv 0.000000 0.863337 -0.113966 0.952335 1.179324 1.344589 0.086001 1.784568 0.040939 -0.278342 0.492392 1.373041 1.589416 0.305140 1.040154 0.306852 0.639739 1.605433 -0.082316 1.171614 0.018705 0.877480 0.742834 1.013469 -0.394587 0.679538 1.685340 1.015860 0.451982 1.273683 0.656961 1.380347 0.930414 0.629931 0.875751 1.106458 0.854029 1.097615 0.942886 1.634232 -0.087153 1.214976 0.912099 1.026106 0.377766 0.938615 0.980356 0.179306 0.223817 1.145177 1.622990 0.100820 0.989970 1.826246 0.934306 0.310115 -0.012658 0.179983 -0.026220 0.755024 0.027968 0.662514 0.819461 1.633236 1.403644 1.156857 1.356308 1.542286 1.253871 1.012715 0.852908 0.924116 0.022097 0.368327 -0.090612 1.052696 -0.034185 0.655336 -0.097080 -0.157717 1.261805 0.337757 0.457703 1.158886 1.296591 0.128958 1.630443 0.809473 0.920747 1.393423 0.696288 0.328360 1.336354 1.510499 1.486152 1.947494 0.779240 0.349685 0.612445 1.433252 1.461547 0.826387 0.679858 -0.337976) ) ;;; 105 odd -------------------------------------------------------------------------------- ; 10.2470 (vector 105 13.491228801467 (fv 0 1 1 1 1 0 1 0 0 1 0 1 1 0 0 0 1 0 1 0 1 1 0 0 1 0 0 1 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0 0 0 1 1 1 0 1 1 1 1 1 0 0 1 0 1 0 1 0 1 0 1 0 0 1 1 1 0 0 1 1 1 0 1 0 1 0 1 1 0 1 1 0 0 0 0 1 1 1 1 1 1 0 0 1 1 0 0 0) 10.115828 (fv 0.000000 0.049019 1.344835 1.091641 0.665700 0.968893 0.648602 0.707898 1.514354 1.538919 0.526334 1.493761 1.624995 0.707437 0.593803 0.874212 1.543010 1.853745 0.426397 0.026573 1.615940 1.506593 0.465693 1.159200 -0.404908 1.664358 0.782410 1.352302 -0.234654 1.360029 1.390064 0.562127 0.900595 -0.305834 1.198378 1.369945 1.005775 0.397773 0.628843 1.626964 0.837449 1.061154 1.446306 1.380391 1.599960 0.270806 1.328543 -0.187842 -0.215850 0.275407 1.674813 1.481684 0.685411 -0.076514 1.172112 0.021028 -0.282040 0.805083 0.169438 0.519532 1.238467 0.912197 -0.108203 0.770912 1.223603 1.260598 0.243317 1.416653 -0.085803 1.793597 1.018898 0.209596 0.637018 0.680644 1.218601 -0.251927 1.342315 0.794662 0.530948 1.151958 0.965018 0.768542 0.003792 0.487969 1.528116 0.185132 1.582165 0.376426 0.269883 0.979543 1.678175 1.757906 1.492507 0.386900 1.219606 0.328787 1.292795 -0.100060 0.401454 0.164930 0.339091 0.226350 0.418706 -0.115549 1.296351) ) ;;; 106 odd -------------------------------------------------------------------------------- ; 10.2956 (vector 106 13.091135978699 (fv 0 0 0 0 1 0 1 0 1 1 1 1 1 1 1 0 1 0 1 1 0 0 1 1 1 0 1 1 1 1 1 0 1 1 0 0 0 0 1 1 1 1 0 1 0 0 1 0 1 0 0 0 1 1 0 0 0 0 0 1 1 1 0 0 1 1 1 1 1 1 0 1 0 0 1 0 1 1 0 0 1 1 0 0 0 1 0 0 0 1 0 1 1 0 0 0 0 0 1 1 1 0 1 1 1 0) 10.198335 (fv 0.000000 0.831679 1.059524 0.595983 0.203261 1.202829 1.655547 1.163399 0.731912 1.050991 -0.085268 1.049064 0.669107 0.707558 1.587356 0.103456 0.095032 1.177165 1.677580 0.458849 0.488238 1.294418 -0.328225 1.742764 0.960376 0.232688 1.221102 1.139466 1.165521 0.274312 -0.217213 1.769983 -0.106435 0.980799 0.424668 1.120797 1.738923 1.408831 0.326124 1.349134 0.307375 0.275240 0.392410 1.221176 0.352509 0.866366 0.344959 0.656333 0.909394 0.940268 0.976614 0.141881 0.684412 0.786921 -0.062121 -0.010568 1.690036 -0.088688 1.427313 -0.052874 1.785355 0.109989 0.958795 1.179624 0.324837 1.229886 1.616903 1.768092 1.318950 1.675999 1.563712 0.225381 0.575251 0.774252 -0.022742 1.783220 1.405786 0.332796 1.613495 1.352845 1.308309 0.373980 1.918112 1.162561 0.910064 1.737277 1.152808 -0.033675 0.058425 1.406045 -0.253836 0.991335 1.479963 0.005130 1.832773 0.614974 0.073456 1.352269 1.161897 0.192184 0.857686 0.091488 0.263380 1.392944 0.202339 1.603064) ) ;;; 107 odd -------------------------------------------------------------------------------- ; 10.3441 (vector 107 13.537808159641 (fv 0 0 0 1 1 1 0 1 0 1 0 0 1 0 0 1 0 0 0 0 0 0 0 1 0 0 0 1 1 1 1 0 0 1 0 0 1 0 1 1 0 1 1 0 0 0 0 0 1 1 1 1 0 1 1 1 0 0 1 0 0 0 1 0 1 0 1 1 0 0 1 1 0 0 0 1 1 0 0 0 0 1 1 1 0 1 1 1 0 1 1 0 0 1 0 1 0 1 0 0 1 0 1 1 1 0 1) 10.295953 (fv 0.000000 1.453513 1.655211 0.102988 0.785431 1.249929 -0.025066 1.750838 0.347673 1.604380 1.551092 0.115495 1.639861 1.667898 0.228709 1.701673 0.201321 1.045139 -0.312647 0.175688 0.855996 0.160415 1.472612 0.763114 0.800624 0.361142 1.295288 0.490786 -0.039842 -0.032740 0.339591 1.592008 0.669279 0.117545 -0.109117 1.018536 0.901071 0.716433 0.346971 1.020475 -0.173945 0.889314 0.077058 1.765220 1.318363 1.591641 1.626283 0.012132 1.508938 0.471426 0.670071 1.171727 0.339306 0.138717 0.336161 0.439088 1.260263 -0.187548 0.396198 0.258209 0.100455 1.039650 0.818140 1.958400 1.117502 0.697124 1.567939 -0.332396 0.783424 1.205431 0.709006 -0.344647 0.483889 0.499549 -0.063258 0.695169 0.972581 0.387305 1.779513 -0.022586 1.856190 0.369348 0.297097 0.538965 0.115827 0.894957 1.816307 1.006210 1.611567 -0.212466 -0.136556 0.733243 0.881259 0.131239 1.843996 -0.064517 1.632049 0.217595 1.203085 0.867259 0.064249 0.691138 1.782204 1.811114 1.580857 1.070340 1.558270) ) ;;; 108 odd -------------------------------------------------------------------------------- ; 10.3923 (vector 108 13.472808406168 (fv 0 1 1 1 0 1 1 1 1 1 1 0 0 1 1 0 0 0 0 0 0 1 0 0 1 0 1 0 0 0 0 1 0 0 1 0 0 0 1 0 1 0 0 0 0 1 1 0 1 0 0 0 1 1 0 0 0 1 0 0 1 1 1 1 0 0 1 1 1 1 0 0 0 1 0 0 1 1 1 1 1 1 0 0 0 0 1 0 0 0 1 0 0 0 1 0 1 1 0 0 0 1 0 1 0 0 1 0) 10.325467 (fv 0.000000 1.823999 0.121670 1.358801 0.589768 1.029967 -0.433790 1.041582 -1.274122 0.780646 -0.169734 1.604597 1.010159 1.810789 0.632723 -0.206688 0.463178 1.073646 1.521165 -0.178712 1.523791 0.423100 0.144424 0.899019 -0.452142 0.547962 0.895764 1.662227 0.346193 1.471302 -0.164671 -1.901696 0.406602 0.262326 0.474119 -0.030228 1.801622 1.325384 1.588387 0.343116 0.445611 0.273212 0.831258 1.871029 -0.312461 1.896993 1.025139 0.721577 0.726171 0.338346 0.861017 1.378901 0.847116 0.469202 -0.383235 0.452023 -0.496006 1.102062 1.102044 1.646809 0.311243 -0.456688 0.949926 0.520943 0.921326 0.643117 0.781598 1.182150 0.966506 0.456713 0.498859 1.075971 1.927079 0.160322 0.159648 0.419881 0.925743 0.446322 0.326978 1.459788 0.903977 -0.021458 1.063237 1.175806 1.223175 0.258595 0.623246 1.572004 0.621332 1.978290 1.546402 1.672410 0.423727 1.205710 1.436589 0.182917 0.251425 0.718333 -1.375705 0.497395 0.186440 0.550196 0.272118 1.380692 1.012574 0.305814 1.433937 0.098087) ) ;;; 109 odd -------------------------------------------------------------------------------- ; 10.4403 (vector 109 13.798 (fv 0 0 1 0 1 0 0 1 0 0 1 1 1 0 1 1 0 0 0 0 0 1 1 1 0 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 0 1 0 0 1 0 0 0 1 0 0 1 0 1 0 1 1 1 0 0 0 1 1 1 0 0 0 1 1 1 1 0 0 0 1 0 0 1 1 1 0 0 1 1 0 1 0 1 1 0 1 1 1 1 1 0 1 0 0 0 1 0 1 0 0 1 1 0 0) 10.413972 (fv 0.000000 -0.329332 1.852441 0.301192 0.479205 1.938689 1.086891 1.271023 0.729396 1.367900 1.483662 1.203078 1.940935 0.158023 0.999249 1.513297 0.973974 0.871966 0.600005 0.917499 0.064963 1.625056 1.204390 0.450307 0.459827 1.379619 0.277893 0.390957 1.292297 1.095127 0.941246 0.509853 0.476400 1.479425 1.214972 0.999425 1.144172 0.402758 1.277806 -1.541834 1.224224 0.408937 -0.140267 1.012505 1.167342 0.593542 1.500901 0.801861 0.428256 0.363108 1.278773 0.897271 1.754344 0.238279 0.787476 1.405582 1.439989 1.293816 1.237720 0.491493 1.514000 1.092355 0.055457 1.477338 0.699004 0.040279 0.957508 1.786210 0.481649 0.726028 0.215740 0.216870 1.343437 -0.395385 1.669265 -0.047054 1.724398 0.984510 0.441756 -0.012720 0.257871 1.485641 -0.121426 0.687863 0.835502 1.004805 1.663485 0.780698 1.042433 1.097029 1.089236 1.689246 1.096756 0.293532 0.899560 -0.005695 0.471699 1.241990 1.396400 -0.542444 0.294633 1.091314 0.356171 0.908370 0.648337 1.936350 -0.128643 0.053871 0.188853) ) ;;; 110 odd -------------------------------------------------------------------------------- ; 10.4881 (vector 110 13.576010454591 (fv 0 1 0 0 1 0 0 0 1 1 1 1 0 0 1 1 0 1 0 0 0 1 0 1 1 0 1 1 1 1 0 0 1 0 1 1 0 0 0 1 0 1 0 1 1 1 1 0 1 1 0 0 0 1 1 1 0 0 1 0 0 0 0 0 1 0 0 1 0 0 1 1 1 0 0 0 0 1 0 0 1 0 0 1 0 1 0 1 0 0 0 1 1 1 1 1 1 1 0 1 1 0 0 1 1 0 1 0 1 0) 10.408073 (fv 0.000000 1.583299 1.129147 0.924363 0.405386 0.106463 0.654471 1.235816 1.676675 1.424024 -0.320821 -0.106137 1.651584 1.223458 1.376470 0.070578 0.035561 0.618393 1.591071 1.247092 1.420738 1.407145 1.068993 1.180774 1.368120 -0.309458 -0.227815 -0.257077 0.341569 0.189699 1.898096 1.209271 -0.362341 0.480813 1.176223 1.497789 1.567432 0.970389 -0.047452 0.764481 1.364232 1.546603 0.838685 0.519999 0.785088 1.840526 0.201375 0.694162 0.995107 0.138310 0.417265 -0.004223 1.430441 0.548174 0.456155 0.879102 0.021026 0.612402 1.448544 1.143273 1.475463 0.804075 0.821149 0.175404 1.164546 0.079156 1.149637 1.448505 1.656091 1.757415 0.521205 0.257194 1.707629 0.482292 1.377093 0.507438 0.991226 -0.612661 0.868064 0.306724 0.414844 0.138628 0.061298 1.129023 1.487975 0.706799 -0.099480 1.383589 0.290834 1.123787 -0.072238 0.982011 0.038233 1.760058 0.405531 0.016972 -0.604791 1.005236 1.670267 -0.215358 1.779967 0.879139 0.413047 1.290874 0.860692 0.804540 1.190191 0.135277 0.110128 0.732322) ) ;;; 111 odd -------------------------------------------------------------------------------- ; 10.5357 (vector 111 13.709900383304 (fv 0 0 0 1 1 0 1 0 0 0 1 1 0 0 0 0 1 0 0 1 0 1 0 1 1 1 0 0 1 1 0 0 1 0 0 1 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 1 1 0 1 0 0 1 0 0 0 1 0 0 1 1 1 1 1 1 0 0 0 1 1 1 1 1 0 1 0 0 1 0 1 1 0 0 0 0 0 1 0 1 1 1 1 1 0 0 1 0 1 0) 10.588903 (fv 0.000000 0.083293 0.444830 -0.213766 0.524915 -0.005956 1.175907 0.783294 -0.343790 -0.015069 1.676924 0.021997 -0.012805 1.023472 0.864450 1.922773 1.431731 1.374839 1.561767 1.633583 0.198147 0.245727 1.910466 0.995751 0.091514 1.666123 0.750477 1.953152 1.512135 0.025831 0.969938 0.804619 0.507564 0.688555 -0.027332 1.433090 0.812479 0.893934 1.245019 0.835304 0.404414 0.839838 0.338429 -0.112731 0.636982 0.099621 1.080987 1.292673 0.177317 1.292327 1.284755 0.253860 0.748555 1.591323 1.605479 0.445460 1.332537 -0.181589 1.668331 0.627699 0.074537 0.208177 0.135644 0.846946 0.614940 0.479986 0.443281 0.299879 1.767930 1.411021 -0.391645 0.057816 1.376551 1.471560 -0.203049 0.453124 0.061036 0.704839 1.379390 1.848624 0.771131 -0.036797 0.007834 1.611881 1.733830 0.412751 1.415257 0.544650 1.539165 0.414455 1.242586 0.195280 0.522916 0.859907 1.238816 -0.090313 -0.027707 -0.025034 0.375248 1.748950 1.440534 1.222909 0.018270 -0.118073 0.275708 1.112569 0.089742 1.167857 1.617530 0.755934 0.450427) ;; pp: 10.417134 (fv 0.000000 0.334233 1.073081 1.649039 0.219597 0.888802 1.379829 0.088335 0.555458 1.328032 1.801862 0.615319 1.429043 0.326004 0.993452 1.804613 0.545160 1.317910 1.885616 0.678140 1.509274 0.323491 1.236504 0.282786 1.199970 0.195704 1.232493 0.160017 0.897560 -0.082586 1.086392 0.182366 1.277299 0.339072 1.485948 0.630905 1.802953 0.832621 -0.132126 1.110982 0.486291 1.681037 0.774846 -0.032051 1.638442 0.870514 -0.093334 1.333411 0.747525 0.167590 1.347374 0.845491 0.233833 1.720211 1.112373 0.655737 0.273424 1.815808 1.225426 0.609827 0.164644 -0.241753 1.556306 1.087036 0.843899 0.560878 -0.058558 1.838311 1.465620 1.239758 1.091378 0.528065 0.791149 0.332440 0.584210 0.055836 0.449981 1.753070 0.093654 1.657239 1.503059 1.399887 1.433488 1.544146 1.513188 1.637379 1.822882 1.796041 1.687813 1.720729 1.754274 -0.098151 -0.072877 0.197474 0.504171 0.827563 1.033490 1.323144 1.356797 1.748728 -0.150347 0.352269 0.632744 0.932570 1.684081 0.187586 0.495859 1.035344 1.327590 1.648341 0.358056) ) ;;; 112 odd -------------------------------------------------------------------------------- ; 10.5830 (vector 112 13.92684841156 (fv 0 0 0 1 0 1 0 0 1 0 0 1 1 0 0 0 0 0 1 0 1 1 0 0 1 0 0 1 0 0 0 1 0 1 0 0 1 0 1 0 0 1 1 0 0 1 0 1 1 1 1 1 0 1 1 1 1 0 1 1 0 1 1 0 0 0 1 1 0 0 0 1 1 0 0 1 1 0 1 0 1 1 1 1 0 0 0 0 0 0 1 1 0 1 0 1 0 1 1 1 1 1 0 0 0 0 0 1 1 0 0 1) ;; 10.58293147 10.582025 (fv 0.000000 0.311823 0.137469 0.765085 0.247252 0.880370 1.452735 0.240993 1.506478 0.780197 1.183194 1.086565 0.032933 1.780577 0.281098 0.764676 0.712557 1.579682 1.277796 1.238223 1.014207 -0.140323 1.716730 1.644672 1.253593 0.578221 0.527661 0.367318 1.131386 1.012757 0.285059 0.010509 0.097401 1.699590 0.802620 1.600737 0.550167 1.026747 0.562219 0.378187 0.150437 0.522055 0.022316 1.717789 0.186746 1.186644 0.914782 0.563095 1.653911 0.869696 0.117700 1.053735 0.935756 -0.055221 0.653101 1.059195 -0.397205 1.469022 0.238158 0.393902 0.410251 0.955768 1.001018 1.337003 0.602349 0.798689 0.307413 -0.479763 0.463243 1.296128 0.608105 0.417995 0.073111 0.291455 0.483686 0.231728 0.630836 1.131231 -0.228753 0.669521 1.185569 -0.089761 1.130815 0.778132 1.502582 1.555252 1.149912 0.577946 0.284522 1.467470 0.172271 0.275044 1.633737 1.228854 0.152388 0.342365 1.574177 0.099351 0.042391 1.025180 1.146998 1.437785 0.647927 1.566576 1.091754 1.532311 1.602420 0.887895 1.387294 0.660060 1.356768 -0.056782) ) ;;; 113 odd -------------------------------------------------------------------------------- ; 10.6301 (vector 113 13.825498858186 (fv 0 1 1 0 1 1 1 0 0 1 0 1 1 1 0 1 0 1 1 0 0 0 1 0 0 0 0 1 1 0 0 1 1 1 1 1 0 1 0 0 0 0 0 0 1 0 1 0 0 0 0 0 1 1 1 0 1 1 1 1 0 0 1 0 1 0 1 0 1 0 0 1 1 0 0 0 0 0 0 0 1 0 0 1 0 1 0 0 0 0 0 1 1 1 0 0 1 0 0 1 1 0 1 1 1 0 0 1 1 0 1 0 0) 10.586426 (fv 0.000000 0.880973 0.176609 1.175777 0.325354 1.332354 0.320489 -0.071032 0.810398 1.764286 1.047524 1.891121 1.274870 -0.462450 -0.016593 1.802245 -0.046896 0.623724 0.697636 1.104725 0.928560 1.531658 1.767776 1.410783 1.560300 0.841358 1.754992 0.695860 1.109332 0.811865 0.787805 0.897767 0.126996 1.290009 1.439543 1.231735 0.428818 0.217484 1.274411 0.676699 0.491905 0.907831 0.251383 0.502017 0.436195 1.271188 0.390987 0.252204 1.423164 1.333446 1.284283 0.685749 0.387192 1.752967 0.379905 1.873082 0.147356 1.600693 0.620101 0.533661 0.873916 1.687058 0.856213 0.905702 0.279125 1.651302 0.425155 1.158445 0.384556 1.685623 1.738609 0.620191 0.166765 0.760816 0.887704 1.876641 1.612703 0.207434 0.310898 1.383166 0.834523 0.489910 -0.069256 0.030910 0.047326 1.374933 1.678060 0.495762 1.058376 0.337747 0.859288 0.994496 0.384200 0.735993 0.843904 0.381801 0.488130 0.839325 0.731059 1.159772 1.973051 0.569688 1.423018 1.561321 1.485614 0.834971 1.215611 1.015531 -0.080496 -0.203441 0.704520 0.652007 1.385821) ) ;;; 114 odd -------------------------------------------------------------------------------- ; 10.6771 (vector 114 13.920305720092 (fv 0 0 1 0 1 1 0 0 1 0 1 0 1 1 0 0 0 1 1 1 1 0 1 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 0 1 0 1 1 0 1 0 0 1 0 1 1 1 0 0 0 0 0 1 0 0 0 0 1 0 1 0 1 0 1 0 0 0 1 1 0 1 1 1 0 1 1 1 0 1 0 0 1 1 0 0 0 1 1 1 0 1 1 1 1 1 1 0 0 1 0 0 0 0) 10.620769 (fv 0.000000 -0.265733 0.572658 0.316585 0.923883 1.614948 0.728669 0.692865 0.985653 1.596503 0.291068 0.153708 1.761462 0.140269 1.183433 -0.379854 1.503387 1.143776 0.747711 1.619251 0.404594 1.157009 0.378840 0.537946 0.751007 0.739900 0.914353 1.624008 0.450778 0.962869 0.588872 1.869278 0.721483 1.557011 0.902276 0.776013 1.285044 0.345048 1.685952 1.091106 0.263288 1.107778 -0.009439 0.420734 1.806464 1.410193 1.769595 1.251788 0.691963 1.604897 1.666646 1.531003 0.963757 -0.680527 1.705352 1.126307 -0.203837 0.277321 0.178995 1.809866 0.763029 0.031476 0.539819 0.755127 0.685061 1.837935 0.717076 1.848829 1.364997 0.950055 -0.061791 1.853324 0.123916 -0.136693 1.146568 0.362176 0.781284 1.598429 1.120688 1.139170 0.560329 -0.015310 0.331374 1.472918 0.199430 0.303861 1.321918 1.569172 1.548780 -0.090459 1.912266 0.810039 -0.152547 1.372081 1.425080 0.264711 1.614349 0.175290 0.789472 1.260114 1.370945 1.918464 1.489942 1.397616 0.963993 0.516634 0.516943 1.244942 0.283787 1.709141 1.616073 0.810759 1.316742 1.696489) ) ;;; 115 odd -------------------------------------------------------------------------------- ; 10.7238 (vector 115 14.20306968689 (fv 0 1 1 0 1 1 0 0 1 1 0 0 0 0 0 0 1 0 1 0 1 1 1 0 0 1 1 0 1 0 1 1 1 0 1 0 1 1 1 1 1 0 1 0 0 1 1 1 0 0 1 1 0 1 0 1 0 0 0 0 1 1 0 0 0 1 1 0 0 0 0 1 0 1 0 0 0 1 1 0 0 0 0 0 1 1 1 1 1 0 0 1 0 1 0 1 0 0 0 0 0 0 1 0 0 1 0 0 1 1 1 0 1 1 1) 10.674304 (fv 0.000000 0.789887 -0.303859 -0.033056 0.759195 0.636525 0.248364 0.847489 1.259597 0.571635 0.950311 0.503307 0.311625 1.283873 0.845368 0.051963 1.567172 1.288876 0.243542 0.283164 1.566596 0.754789 1.490536 0.039434 0.168217 0.197813 0.961175 1.000724 0.173724 1.453836 -0.299975 0.087165 1.672267 1.098120 1.146505 0.379755 1.328375 0.651767 1.173825 0.650295 0.441141 0.865349 1.257754 -0.111945 0.068441 1.538745 0.068967 1.734610 1.208209 0.079563 -0.236732 0.216584 0.140036 0.340430 0.008574 0.036605 0.315028 0.890542 0.307266 0.065201 -0.267238 -0.016662 1.283003 0.528002 -0.402562 1.186323 0.829551 0.025932 0.882753 0.264357 1.091661 1.076730 -0.001406 0.040934 0.042083 1.567774 0.906679 0.687134 0.720339 0.063372 0.406664 1.457338 1.400253 1.359707 1.217492 0.090043 -0.918052 0.816288 1.443080 -0.046946 0.555663 0.622694 1.800570 0.513267 0.655836 0.746318 1.849833 1.129389 1.637640 0.403829 -0.005965 0.883415 0.100025 0.540813 0.541888 0.996530 1.501665 1.855318 1.257420 0.578586 0.925447 0.264080 0.596871 0.828008 0.353618) ) ;;; 116 odd -------------------------------------------------------------------------------- ; 10.7703 (vector 116 13.887789451571 (fv 0 0 1 0 1 0 0 0 0 1 1 0 0 1 1 0 1 1 1 0 1 1 1 1 0 1 0 1 0 1 0 1 0 1 0 0 1 0 0 0 0 0 0 0 1 1 0 0 0 1 0 1 1 1 0 1 1 0 1 1 0 0 1 1 0 1 1 1 1 0 0 0 1 1 0 1 1 1 1 1 0 1 1 1 1 0 0 0 0 0 1 1 1 1 1 1 1 1 0 1 1 0 1 1 1 0 1 0 0 1 0 1 1 0 1 0) 10.733274 (fv 0.000000 0.476000 1.878001 1.180059 0.831300 1.453614 0.786219 1.052031 1.218138 0.179523 0.743868 1.265853 0.031570 1.636184 -0.152324 0.778296 0.271634 1.469546 0.565495 1.807809 0.217280 0.159382 1.049221 0.170285 0.221763 0.774648 0.398259 0.637279 -0.107284 0.312805 1.776901 0.160502 1.717634 1.119938 1.391025 0.105351 1.023277 1.530674 1.548380 -0.251006 0.488559 1.544222 0.177807 0.661206 0.257716 1.053732 0.893027 1.445098 1.722088 0.002770 1.151812 1.061439 0.110999 0.865286 0.781438 1.277991 0.502793 0.943734 0.798521 1.333645 1.654972 1.679619 0.259243 0.886975 0.069664 1.517348 1.237826 1.551946 0.514540 1.258563 1.258071 1.027685 1.355844 1.909459 1.281504 1.171068 0.250655 1.622642 0.211675 1.522349 -0.092396 0.705855 1.861520 0.183629 0.746566 0.759808 0.250024 -0.159043 1.664858 0.237853 -0.217693 1.217376 1.459590 1.517349 1.206266 0.478670 -0.380779 0.210779 0.338305 1.433407 1.043804 0.854323 0.392836 1.702198 1.439694 -0.141576 1.283279 0.715495 0.734335 1.585749 1.775978 1.654290 -0.315773 0.174327 1.442380 0.993240) ) ;;; 117 odd -------------------------------------------------------------------------------- ; 10.8167 (vector 117 14.427604264985 (fv 0 1 1 1 0 1 1 1 0 0 1 1 1 1 1 1 1 0 0 0 0 1 1 0 1 1 1 0 1 1 1 0 1 0 1 1 1 1 1 0 0 1 1 1 0 0 0 0 1 1 1 0 1 0 1 0 0 0 1 0 0 0 1 1 1 1 1 1 1 1 0 1 1 0 0 1 1 0 1 0 1 1 0 1 0 1 1 1 0 0 1 0 1 1 0 0 0 1 0 0 1 0 0 1 0 0 0 1 1 0 1 0 1 1 0 1 1) 10.783290 (fv 0.000000 0.108967 0.680440 -0.039849 1.073915 0.982905 0.909467 1.470260 1.730853 0.840580 1.309090 0.612716 1.548112 -0.231227 1.489945 0.841297 1.245447 0.244987 0.849971 -0.022279 0.452974 0.810744 1.489407 1.567278 1.188237 0.772892 0.113419 0.906478 1.169175 -0.156676 0.507744 1.684543 1.686412 1.219650 1.843836 0.541605 0.346082 0.043904 -0.079283 1.469849 1.567795 0.179241 -0.068928 0.912255 0.602511 1.574715 0.695060 1.133392 -0.425958 0.610886 1.496396 0.865636 0.895412 1.362633 1.653811 1.404165 0.041681 1.692317 1.094403 0.739550 1.239428 0.479228 1.439160 0.986149 0.801910 1.514113 0.963332 0.281851 0.106127 1.599308 -0.004925 1.893302 1.411671 1.244923 0.383170 0.517813 0.421067 1.058052 0.153400 0.778671 0.754438 1.880309 0.023746 1.476647 0.081600 1.798573 0.432245 0.735923 0.440628 -0.064421 1.249491 0.136405 1.735439 1.868665 1.565831 0.435031 0.537457 0.904590 1.634892 1.124196 0.408216 0.769901 0.281419 1.398400 0.260352 0.021213 0.275268 0.681889 -0.074136 0.502025 0.237163 1.241676 1.638668 0.242962 0.026823 1.133262 1.452416) ) ;;; 118 odd -------------------------------------------------------------------------------- ; 10.8628 (vector 118 14.399567650824 (fv 0 1 0 0 0 1 0 0 1 0 0 1 1 0 0 0 1 1 1 1 1 1 1 1 0 0 1 1 0 0 1 0 1 1 1 0 0 0 0 1 1 0 1 1 0 0 0 1 1 1 0 0 1 0 0 0 1 1 1 1 1 0 1 0 0 1 1 1 1 1 0 0 1 0 0 0 0 1 0 1 0 1 1 1 0 0 1 0 1 0 0 0 0 1 1 1 0 1 0 1 1 1 1 0 0 1 1 1 0 1 1 1 1 1 1 1 0 1) 10.812235 (fv 0.000000 1.507972 1.809575 1.323971 0.671235 0.977919 0.397118 0.294709 0.400614 1.800046 0.492728 1.565979 -0.363038 1.100463 1.075231 0.502016 0.457037 0.406728 0.228418 0.756367 1.513939 0.347068 1.450936 0.868009 1.501709 0.352220 -0.413052 -0.148923 0.240400 1.115439 0.653043 -0.505473 -0.021974 1.853042 0.586305 0.428092 0.050201 0.752546 1.451411 1.228490 1.754283 1.881544 0.485306 1.754300 0.007006 0.163634 0.582385 0.998129 -0.090614 0.952205 1.425714 1.513296 1.570494 -0.259048 0.529336 1.498547 1.326491 -0.594238 1.538496 0.728657 0.444244 1.055319 1.385207 0.874327 0.074427 1.100816 1.734905 0.605814 1.533043 1.017063 0.482871 0.438583 1.108829 1.808956 0.029357 0.297016 -0.063569 0.780909 1.283400 0.359665 -0.032425 1.363808 0.687851 1.190450 1.438414 1.141910 1.126025 1.239471 0.136191 1.489911 1.026641 0.526687 0.890040 -0.022700 0.140687 -0.353757 1.164330 1.005641 0.099661 1.220163 1.081145 1.773078 1.376716 1.458019 0.703593 0.987305 1.493840 1.628605 0.957392 -0.054994 1.652856 0.431213 1.736293 -0.162073 0.279632 -0.110283 1.166212 1.877544) ) ;;; 119 odd -------------------------------------------------------------------------------- ; 10.9087 (vector 119 14.464 (fv 0 0 1 1 0 0 0 0 1 0 1 0 1 1 1 0 1 0 1 0 0 1 0 0 1 1 0 0 0 0 1 1 1 0 1 1 1 0 1 0 0 0 1 1 1 0 0 0 1 0 0 0 0 0 0 1 1 0 1 1 0 1 0 1 1 0 0 0 0 1 0 1 1 1 0 0 0 0 0 1 0 0 1 0 0 0 1 1 1 0 0 1 0 0 1 0 1 0 1 1 0 1 0 1 0 1 1 1 1 0 1 1 1 1 0 1 1 1 1) 10.915923 (fv 0.000000 1.468971 -0.070109 0.743471 0.865207 0.740713 1.375563 1.856253 1.493876 0.001446 1.555119 1.873527 0.486379 1.616655 0.160602 1.367247 0.912321 0.764636 0.328487 -0.313335 0.385982 0.645370 0.408989 -0.210208 1.638205 0.329206 1.585495 1.658528 -0.015737 0.563000 0.062305 -0.007952 1.615694 0.120849 0.556636 1.351804 1.028805 0.044823 -0.249641 0.450875 -0.188130 1.054822 1.658005 0.732611 1.051144 0.181032 -0.061461 0.014104 0.174656 1.497989 1.287601 1.362445 0.209461 0.902894 1.389971 0.577406 1.285084 1.677882 0.836076 1.093131 -0.061912 0.754157 0.925122 0.984483 0.745399 1.783690 0.907228 0.093044 0.001514 0.775385 1.257954 1.480444 1.312457 1.195686 1.427916 1.726017 1.291212 1.845006 1.072451 0.380596 -0.077482 -0.030557 0.660125 1.346002 0.823989 0.235481 1.377946 1.450150 0.552324 0.398627 1.336527 0.073526 0.466630 0.590308 0.928946 0.828743 -0.154986 1.149963 0.492935 1.772069 0.204388 1.490853 -0.315475 0.097407 1.157089 0.698006 1.513716 1.488764 0.923673 0.108745 1.168110 0.729608 1.392132 1.740139 1.454066 0.757828 1.227068 0.584339 1.581610) ;; pp: 11.037707 (fv 0.000000 0.330663 0.977506 1.486310 0.146671 0.619852 1.212563 1.835260 0.429131 1.137767 1.722966 0.554725 1.336956 0.080712 0.852554 1.473118 0.165981 0.811544 1.502696 0.343077 1.371306 0.205531 0.905257 1.934366 1.020467 1.933150 0.730878 1.550089 0.565733 1.543669 0.452622 1.507940 0.734165 1.641237 0.799367 0.020448 1.044223 0.039537 1.305538 0.570880 1.458969 0.622353 1.797356 0.986890 0.251789 1.442933 0.753665 0.270337 1.533653 0.647011 -0.011278 1.435253 0.493723 -0.176024 1.395851 0.880365 0.222324 1.709439 1.376910 0.824516 0.330942 1.733291 1.350769 0.852276 0.247847 -0.101792 1.361637 1.450559 0.694333 0.792939 0.273393 1.916534 1.612649 1.136729 1.027650 0.745376 0.479123 0.468161 -0.088607 0.141257 1.721063 1.745485 1.474071 1.547129 1.195469 1.231545 0.976850 0.989136 1.181833 0.899203 1.200899 1.168317 1.143250 1.360858 1.307442 1.171633 1.402153 1.656644 1.531180 1.874515 0.028657 0.416186 0.465448 0.590264 1.056005 1.152867 1.387578 1.553815 0.076236 0.350372 0.561320 1.007917 1.385094 1.972832 0.449173 0.459147 1.193699 1.594244 0.056947) ;; 118+1 10.815476 (fv 0.000000 1.511627 1.860509 1.251771 0.680390 0.954029 0.497464 0.422082 0.549359 1.789096 0.627036 1.559684 -0.285316 1.102920 1.110972 0.497639 0.358913 0.339963 0.170351 0.820368 1.613321 0.311453 1.667587 0.845824 1.477518 0.323382 -0.462336 -0.121701 0.278431 1.251253 0.730313 -0.512813 0.050332 1.905719 0.581701 0.491221 0.037053 0.850077 1.454447 1.218666 1.827857 1.931466 0.444700 1.716033 0.031317 0.208955 0.719947 1.025308 -0.162952 0.941579 1.416409 1.490055 1.661028 -0.177347 0.601149 1.427738 1.318738 -0.598055 1.513344 0.818145 0.331744 0.938565 1.416971 0.755203 0.134509 1.154206 1.729909 0.622158 1.596632 1.050190 0.348364 0.402844 1.083937 1.814009 0.098380 0.333506 -0.078532 0.814360 1.186888 0.456002 0.118529 1.475204 0.706833 1.153688 1.398936 1.202344 1.140027 1.452557 0.124581 1.538313 1.096684 0.449897 0.816791 -0.073645 0.157032 -0.377184 1.176926 0.948380 0.061745 1.231800 0.991632 1.829471 1.268286 1.394920 0.669763 0.966107 1.360959 1.524586 1.033990 0.094975 1.707832 0.468762 1.695289 -0.249729 0.213611 -0.109788 1.260368 1.791243 -0.325923) ) ;;; 120 odd -------------------------------------------------------------------------------- ; 10.9545 (vector 120 14.530112637252 (fv 0 0 0 1 0 0 0 1 0 1 0 0 1 0 1 0 1 0 1 0 0 1 1 0 0 1 1 0 0 1 1 1 1 1 1 1 0 0 1 0 1 1 1 1 0 0 0 1 1 0 1 1 0 1 1 0 0 0 0 0 1 1 1 0 0 0 0 1 1 1 1 0 1 1 1 1 1 1 0 0 0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 1 1 1 0 1 0 1 0 0 0 0 0 1 0 0 0 1 1 0 1 1 0) 10.908578 (fv 0.000000 1.631022 1.381443 1.212465 0.280876 1.393291 0.111686 0.270527 0.978937 1.227425 0.890939 1.651369 1.764648 0.695615 1.236913 0.727116 0.698874 1.130809 0.997193 1.306023 0.313921 0.604505 1.499034 1.434773 -0.031959 0.721966 0.805711 1.401787 1.847562 -0.006201 0.484669 -0.092885 0.221199 -0.183123 0.140129 0.993753 0.357992 0.281932 0.966898 0.230227 1.509169 0.180321 0.405315 1.445457 0.491155 0.993111 -0.061813 1.514617 0.638001 0.451798 1.136956 1.109239 0.762301 -0.132886 1.231861 1.405253 0.200172 0.005626 1.367415 0.727395 0.860721 1.277905 0.564602 1.311600 0.590071 0.237783 1.173320 1.731939 0.366179 -0.147635 0.520386 1.741652 0.218116 1.635795 0.602629 0.928717 0.628620 0.437182 1.782199 0.939080 1.479011 0.992710 1.705346 0.225711 0.000961 0.770434 1.683323 1.555459 0.976408 0.318440 0.438208 0.262452 1.689840 0.975712 0.209291 0.727490 0.382719 1.065032 0.672130 0.702874 0.107185 1.755713 1.841965 0.283698 0.562788 -0.058140 0.525625 0.471391 -0.086606 1.741760 0.455380 1.248256 1.359448 0.404279 1.132787 1.054875 0.443335 0.808907 0.713857 0.102341) ) ;;; 121 odd -------------------------------------------------------------------------------- ; 11 (vector 121 14.355115628334 (fv 0 0 1 0 0 1 1 0 0 0 1 1 0 1 0 0 1 0 0 1 1 1 1 0 1 1 0 1 1 1 0 1 0 1 0 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 0 0 1 0 0 0 0 1 1 1 0 0 1 0 0 0 1 1 0 1 1 1 0 1 0 0 1 0 1 1 1 0 1 0 0 1 1 0 0 0 0 0 1 1 1 0 0 1 1 0 0 0 1 0 1 0 0 0 0 1 1 1 1 0 1 0 0) 10.999150 (fv 0.000000 0.719860 0.938641 0.400955 1.830792 0.217487 1.930089 0.909842 0.382707 1.104036 1.362552 1.609877 0.538869 1.202159 1.228082 0.918074 0.761902 0.900279 1.079854 0.387994 0.099489 0.100875 1.443224 0.976872 1.189188 0.334621 0.186401 1.007773 1.759908 1.802561 0.304789 0.800487 0.421388 1.531470 0.342409 1.763739 0.609609 0.238091 0.387711 0.077698 1.394770 1.550045 1.073770 -0.012632 0.461456 0.365441 0.558370 -0.144510 0.377065 -0.136065 0.495723 0.024372 0.599268 0.707454 1.784582 0.849322 0.801737 -0.000698 0.370684 -0.319990 0.047344 1.411089 -0.180064 1.795978 1.184028 0.211991 0.750419 1.558447 0.936061 0.770891 0.210380 0.477885 0.773230 1.314821 1.776398 0.360518 0.353595 1.763194 0.626584 0.453820 1.817369 0.757593 0.448588 0.747723 1.349523 0.084314 0.839331 0.432101 1.175829 -0.480593 1.521898 1.472118 0.461937 -0.352155 0.231781 1.128258 1.179502 -0.264358 1.594681 1.130852 1.819287 1.407276 0.357399 0.261689 0.296975 1.241018 0.528908 0.936623 1.018062 1.507272 1.409703 0.904346 -0.089508 0.657699 0.797276 1.771059 0.906319 0.794023 0.195827 -0.015182 1.382236) ;; pp: 10.964853 (fv 0.000000 0.398403 0.789366 1.639224 0.095384 0.603386 1.413253 -0.024715 0.418890 1.292082 1.611148 0.340631 1.108765 1.695063 0.580930 1.343797 0.280670 0.901558 1.616611 0.471137 1.087682 0.133909 0.906863 1.859279 0.568482 1.631317 0.654611 1.507476 0.361682 1.510922 0.499281 1.470975 0.300411 1.347262 0.617157 1.704177 0.828780 1.880799 1.043180 0.289911 1.416774 0.542005 1.546439 0.900363 0.167177 1.249035 0.407571 1.759267 1.085148 0.584948 1.716513 0.882082 0.508912 1.827501 0.986992 0.387974 1.888925 1.337010 0.836823 0.307293 1.641585 1.441301 0.767423 0.352201 1.694822 1.489433 0.858014 0.699679 0.213088 1.881335 1.746103 0.996170 1.013175 0.481879 0.378821 0.145113 1.583267 1.647206 1.099338 0.993610 1.018212 0.718965 0.851336 0.334482 0.624100 0.047757 0.264635 -0.323610 -0.302771 0.007865 1.748671 1.715799 0.102814 0.097582 0.089500 0.089824 -0.047495 0.097783 0.230671 0.371131 0.395035 0.485871 1.031900 1.248794 1.442726 1.594017 1.850116 0.167236 0.339312 0.429488 0.766566 1.120859 1.686086 0.133797 0.674257 1.033037 1.205258 1.718874 0.166520 0.534447 1.081831) ) ;;; 122 odd -------------------------------------------------------------------------------- ; 11.0454 (vector 122 14.266534958875 (fv 0 0 1 0 1 1 0 1 0 0 0 0 1 1 1 1 0 0 1 1 1 0 0 1 1 0 1 0 0 0 0 0 1 1 0 0 1 0 0 1 0 0 0 1 1 0 0 1 0 1 1 1 1 0 1 1 1 0 0 0 1 0 1 0 1 0 0 1 1 1 1 0 1 0 0 0 0 0 1 0 1 0 0 1 1 0 0 1 0 1 1 0 0 1 1 1 0 0 0 0 0 0 1 0 0 0 0 1 0 1 0 0 0 0 0 0 1 1 0 1 0 1) 11.010771 (fv 0.000000 1.285362 1.109765 1.769522 1.118511 0.025809 1.380894 -0.023810 -0.040154 0.477589 1.538986 0.261754 1.175104 0.132069 1.284014 1.937597 1.377797 1.405930 1.758393 1.282889 1.486625 -0.056321 1.528467 0.214498 1.235960 0.342086 0.501436 1.266150 1.154766 0.072612 1.295064 1.657622 1.389498 0.272462 0.259989 -0.421623 0.539671 -0.109400 1.457518 0.782406 0.238503 1.568707 0.742855 0.582523 1.544996 0.568221 1.469856 -0.013151 1.702120 1.738232 0.495569 1.623452 0.280213 1.398587 0.655444 -0.357815 -0.175614 -0.641353 0.853648 0.913786 0.039735 0.805399 0.987536 1.353101 0.200447 1.531233 0.925738 1.853509 -0.339223 0.575217 0.991404 0.868567 0.980697 0.661437 0.825668 0.642114 1.923343 0.222086 1.058889 0.329972 0.424129 1.343097 -0.325621 0.616372 0.777895 1.290746 0.563995 1.114886 -0.032692 0.303925 0.022515 1.568213 1.005956 0.993523 0.945016 1.316628 1.600265 0.004312 0.404044 0.508968 1.509703 1.266589 -0.292614 0.449335 0.327309 -0.027947 0.095691 -0.305771 -0.038174 1.851423 0.567671 0.373102 0.032065 1.664572 1.263320 0.558380 0.899406 0.824927 1.437277 1.639347 0.806318 0.739271) ) ;;; 123 odd -------------------------------------------------------------------------------- ; 11.0905 (vector 123 14.795100232697 (fv 0 1 0 1 0 0 1 0 0 0 0 1 1 1 1 0 1 0 1 0 0 1 1 1 0 0 1 0 0 0 0 0 0 0 1 0 0 1 0 1 1 0 1 0 0 1 1 1 0 1 1 0 1 0 1 1 1 0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 1 0 0 1 1 1 1 0 0 0 0 0 0 0 1 1 0 1 1 1 0 0 1 1 1 0 0 1 0 1 1 1 0 1 0 0 1 1 0 0 1 0 1 1 1 0 0 1 0 1 0) 11.117974 (fv 0.000000 1.262698 1.743243 1.074484 0.862475 0.785191 0.510312 0.582728 0.572628 -0.088059 1.664778 1.092330 -0.084164 1.734977 0.143912 0.402913 0.514775 1.115307 1.630947 0.922571 1.361065 0.426472 0.818315 0.052105 0.105138 1.201879 0.422607 1.251988 1.202423 -0.257950 0.069201 -0.064548 0.721964 0.891435 1.163338 0.489652 0.800922 1.113478 0.729679 1.592733 0.127179 0.300890 1.709393 0.172666 1.452078 -0.215073 0.642218 0.228379 0.403691 1.149702 0.347815 1.145024 0.203450 1.473310 1.349864 0.832166 1.109084 1.584188 0.087952 0.610084 0.356770 0.605944 1.021694 0.463739 1.799512 1.527466 0.330450 0.923701 1.275830 1.440075 0.070553 0.931440 1.867718 1.401219 0.527205 0.524478 1.943022 1.358574 1.765573 0.269987 0.599212 0.397347 0.099304 -0.004043 0.750837 0.311340 0.977644 0.259270 0.829971 0.677623 1.491913 0.411691 1.356052 1.394632 0.542733 1.451416 1.005068 0.285973 0.960285 1.132877 -0.136129 0.201370 1.788028 -0.448022 -0.229434 1.007668 -0.665334 0.552776 -0.103552 1.183857 -0.521659 1.255730 0.912247 1.532970 1.479294 1.441480 1.200164 0.598200 1.369457 1.661067 0.851812 0.484837 1.318223) ;; pp: 11.220425 (fv 0.000000 0.365848 1.054393 1.548722 0.083290 0.846622 1.243796 1.975082 0.530118 1.107798 1.698368 0.394906 1.261238 1.932773 0.709817 1.516065 0.289612 0.915816 1.713378 0.516514 1.369027 0.084750 0.935528 1.825369 0.700695 1.570817 0.581567 1.522187 0.450938 1.444224 0.424228 1.427039 0.366241 1.246498 0.294330 1.489859 0.444710 1.600045 0.769131 1.818819 0.882796 0.180405 1.318163 0.438713 1.518577 0.911091 0.311354 1.423178 0.560415 -0.093959 1.444287 0.598087 1.777270 1.408474 0.711081 0.112383 1.490437 0.904666 0.286560 1.771712 1.145544 0.724678 0.267468 1.796311 1.311228 0.841811 0.365537 1.880834 1.503328 1.287234 0.819314 0.526370 -0.077772 1.787440 1.491417 1.044589 1.141961 0.479419 0.379101 0.330996 -0.143470 1.807816 1.736856 1.461325 1.278241 1.506158 1.106149 1.221780 0.919096 1.122923 0.682195 0.948573 0.684101 0.822257 0.900682 0.969747 0.998896 1.031330 0.981000 1.116626 1.207464 1.514496 1.484110 1.685927 -0.131788 0.102608 0.256377 0.543811 0.846258 1.358549 1.270751 1.590115 -0.239901 0.243476 0.677754 0.899634 1.476294 1.901976 0.254194 0.661350 1.294177 1.496684 0.048409) ;; 122 + 1 11.250448 (fv 0.000000 1.302757 1.104016 1.882979 1.077650 0.053765 1.380440 0.003809 -0.046007 0.495357 1.519889 0.149797 1.197260 0.142817 1.219075 1.962202 1.461975 1.397810 1.755477 1.312034 1.459888 0.010987 1.489492 0.259453 1.259472 0.317472 0.521518 1.299213 1.226523 0.026938 1.296841 1.668722 1.337105 0.314301 0.330300 -0.438601 0.526089 -0.123698 1.469579 0.756219 0.172470 1.621261 0.778923 0.588722 1.542018 0.631414 1.527628 -0.038678 1.791364 1.687889 0.422304 1.584058 0.300597 1.413330 0.639674 -0.328087 -0.133739 -0.644241 0.881718 0.903075 -0.003259 0.764074 1.053115 1.364090 0.158374 1.544589 0.996921 1.813142 -0.279028 0.566236 1.039397 0.862143 0.979166 0.609771 0.860576 0.627137 1.959235 0.243884 1.018838 0.390319 0.475059 1.332423 -0.275526 0.611933 0.766476 1.331409 0.615945 1.094395 -0.004564 0.363420 -0.045135 1.527572 1.077299 0.997558 1.035936 1.286389 1.540261 0.059435 0.352601 0.552519 1.479640 1.199179 -0.317815 0.440438 0.336153 -0.013127 0.157566 -0.304297 -0.069647 1.901289 0.528335 0.359084 -0.007292 1.702466 1.215578 0.562997 0.913601 0.801948 1.409876 1.632172 0.750795 0.670695 -0.003034) ;; 124 - 1 11.087851 (fv 0.000000 0.624121 0.261315 1.181018 0.329816 0.723473 -0.058557 1.121126 0.418750 -0.560184 0.201221 -0.009188 0.964547 0.675383 0.540517 1.692402 0.238659 0.271713 0.649234 1.358679 -0.523949 0.096515 1.070752 0.415974 1.194076 0.398537 0.119705 1.390687 1.865110 0.657711 0.628353 0.094042 -0.039698 0.818092 0.264925 1.627819 0.564214 1.707948 1.323380 0.532853 1.528599 0.040464 0.169356 1.020624 1.633435 0.566927 0.135046 0.139973 1.154314 0.011466 -0.490861 0.640253 0.477507 1.036610 0.601286 0.864853 1.673244 0.103614 0.490773 0.239735 1.004984 0.751604 0.598287 0.049449 -0.383209 0.952738 0.587827 1.358167 1.134886 0.996730 1.062079 1.715631 0.870675 -0.669782 1.719322 1.286177 0.181430 1.375280 1.727572 0.723568 0.180864 0.793875 1.229108 1.479462 0.352987 0.476172 0.647844 0.506675 0.826807 0.037970 0.147029 -0.376170 -0.079080 -0.448861 -0.361893 0.784673 0.253239 1.081508 0.018537 1.194702 1.598635 -0.278698 1.403864 0.071060 0.431595 1.221066 1.608714 0.689332 0.715718 0.497216 1.832187 1.548074 1.325487 -0.697479 1.412701 -0.064789 1.545460 1.865863 0.574246 1.018052 0.826593 0.850894 0.538141) ) ;;; 124 odd -------------------------------------------------------------------------------- ; 11.1355 (vector 124 14.82254124518 (fv 0 0 0 0 1 0 0 1 1 1 0 1 1 1 0 0 1 1 1 0 0 0 1 1 0 0 0 0 1 0 1 0 0 1 0 1 0 0 0 0 0 1 0 1 1 0 1 0 0 0 0 0 1 1 1 0 1 0 1 0 1 0 1 0 0 1 0 0 0 0 0 1 1 1 0 0 1 0 0 1 1 1 1 1 1 1 0 1 1 1 0 0 0 1 0 0 1 1 1 0 0 1 0 1 1 1 0 1 0 0 1 1 0 1 1 0 0 0 1 0 0 0 0 0) 11.133385 (fv 0.000000 0.737767 0.242894 1.222279 0.471270 0.719745 -0.111581 1.125372 0.519029 -0.602995 0.207831 -0.019375 0.977253 0.730038 0.549277 1.736357 0.178856 0.378067 0.703036 1.285405 -0.440424 0.022976 1.081105 0.394590 1.176445 0.423028 0.024758 1.348044 1.875622 0.693243 0.631295 0.154785 -0.072026 0.840426 0.310333 1.680668 0.596016 1.796624 1.329261 0.552169 1.550621 -0.029191 0.120286 1.042346 1.643782 0.557105 0.100245 0.192082 1.115887 -0.044021 -0.568040 0.660295 0.446779 0.996296 0.543383 0.887166 1.696504 0.164237 0.565638 0.240616 0.980219 0.676086 0.528834 0.128308 -0.348116 0.973101 0.673237 1.259063 1.135685 0.928208 1.088345 1.731248 0.837036 -0.669991 1.701824 1.338691 0.198045 1.382482 1.748178 0.598583 0.174133 0.840707 1.239171 1.490991 0.324491 0.560298 0.680939 0.488255 0.866976 0.067351 0.114746 -0.374109 -0.011129 -0.482864 -0.335823 0.770685 0.238886 1.104919 -0.086380 1.175827 1.697828 -0.309033 1.420456 0.050528 0.410791 1.224188 1.576124 0.696620 0.749167 0.492507 1.752832 1.565235 1.317346 -0.708509 1.533585 -0.144615 1.567818 1.921771 0.617703 1.048643 0.900156 0.810098 0.470909 -0.287077) ;; pp: 11.348159 (fv 0.000000 0.420291 0.994113 1.605062 0.142556 0.741991 1.232518 1.818784 0.570117 1.112532 1.715041 0.498288 1.242193 1.903819 0.738569 1.440312 0.052035 0.859274 1.700608 0.416370 1.222707 0.007385 0.792200 1.771446 0.548685 1.661284 0.559436 1.442669 0.358986 1.258045 0.260744 1.254293 0.320180 1.305252 0.361287 1.403913 0.572629 1.603076 0.693636 1.846854 1.012682 0.188863 1.352443 0.397048 1.645973 0.881785 0.066704 1.295103 0.504646 1.870898 1.303297 0.570018 1.829957 1.080888 0.545590 1.923840 1.269013 0.679145 0.161303 1.594647 0.985227 0.464326 0.012233 1.568478 1.180634 0.730528 0.110665 1.618518 1.175834 0.879996 0.432189 0.136812 1.777876 1.490107 1.188949 0.907621 0.550479 0.242984 -0.059790 1.929821 1.371631 1.423168 1.146477 0.972409 0.858534 0.924887 0.595740 0.679411 0.488048 0.636418 0.072322 0.281040 0.204879 0.089915 0.287853 0.416670 0.453983 0.352329 0.503511 0.432486 0.571020 0.790600 0.687796 1.008010 1.155356 1.385540 1.648000 1.747132 0.045146 0.425981 0.717415 0.741128 1.002981 1.282324 1.660931 0.156386 0.411627 0.950904 1.417985 1.747974 0.260323 0.677519 1.016797 1.669557) ;; 125-1 11.120334 (fv 0.000000 0.836933 0.196277 0.584882 0.301240 1.853484 1.324094 0.689541 0.969365 0.207127 0.815576 1.493174 1.646002 1.091372 1.338767 0.007260 0.223249 1.375996 0.396818 0.809290 0.595471 0.291935 0.828280 1.079040 -0.045835 0.055676 0.687157 1.387372 0.387604 1.113048 0.635795 -0.184152 0.086995 0.683755 -0.523880 0.957683 0.004250 0.887892 -0.247566 0.473338 0.863028 1.537875 1.279363 1.883742 -0.079415 1.606587 1.410357 1.815201 1.258365 -0.140836 0.062288 -0.117723 0.136197 0.025366 0.240444 0.337975 0.245314 1.565210 1.190385 0.061707 1.059358 1.066927 -0.243845 -0.140470 0.080704 -0.220916 0.436644 1.755266 1.123977 1.300903 1.292668 0.127266 0.478120 0.197515 0.674823 1.740766 0.286316 1.346417 -0.000673 0.759878 1.360448 0.328373 -0.116210 1.391350 1.022226 1.179474 0.838754 0.041237 0.614743 0.475843 0.203018 1.724933 1.421322 0.133569 1.485945 -0.070709 -0.071535 1.023240 0.511154 0.013014 1.379753 0.972914 1.226974 1.882336 0.135006 1.035934 -0.225880 1.034246 0.410768 0.390305 1.143196 1.223233 0.144114 1.611032 0.509896 1.218446 0.494123 -0.071045 0.511805 0.489583 0.116710 1.542243 0.745207 0.200411) ) ;;; 125 odd -------------------------------------------------------------------------------- ; 11.1803 (vector 125 14.82163143158 (fv 0 0 1 1 0 0 1 1 0 0 1 1 1 0 1 1 0 1 0 0 0 0 1 1 1 0 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 1 0 1 1 0 0 1 1 1 0 1 0 0 0 0 0 0 1 0 0 1 0 1 0 1 0 1 1 1 1 1 1 0 1 1 1 1 1 1 0 0 0 1 1 1 0 1 0 0 1 0 1 1 1 0 1 1 1 0 1 0 1 0 0 1 1 0 1 1 0 1 0 0 1 1 1 0 0) 11.122080 (fv 0.000000 0.847003 0.165605 0.564848 0.227076 1.866949 1.345525 0.694388 0.959809 0.220564 0.772501 1.602410 1.604719 1.034958 1.311625 0.093909 0.283228 1.337145 0.377730 0.845137 0.466461 0.350583 0.723543 1.140286 -0.106738 0.112805 0.654453 1.405583 0.488341 1.115481 0.791692 -0.180702 0.024701 0.675117 -0.401907 0.966930 1.823188 0.970009 -0.163692 0.487827 0.774136 1.664048 1.147399 1.934923 -0.055579 1.590906 1.404741 1.937024 1.297324 -0.074406 0.012276 -0.101828 0.157087 0.049344 0.227099 0.402796 0.390545 1.452083 1.063131 0.134397 1.038993 1.058234 -0.172834 -0.157850 -0.051398 -0.166122 0.368524 1.765197 1.164117 1.233067 1.255917 0.100656 0.389203 0.162934 0.701475 1.871318 0.234658 1.379710 -0.022077 0.663615 1.352469 0.392445 -0.083922 1.307168 0.973714 1.219169 0.823481 0.152576 0.585169 0.393119 0.296805 1.754607 1.427512 0.110549 1.353534 -0.062637 0.005406 0.988733 0.551978 -0.032302 1.396422 1.051496 1.232496 1.873765 0.104448 1.090614 -0.186610 1.107217 0.405013 0.371843 1.166939 1.223105 0.199359 1.547104 0.541567 1.118832 0.462118 -0.111041 0.497800 0.551619 0.175381 1.513543 0.771791 0.282381 0.491699) ) ;;; 126 odd -------------------------------------------------------------------------------- ; 11.2250 (vector 126 14.961482935205 (fv 0 1 0 0 1 1 1 0 0 0 1 1 0 0 0 0 0 0 0 1 1 1 1 0 0 0 1 1 0 1 0 1 0 0 1 1 1 1 1 1 1 0 0 0 1 0 1 1 1 1 0 0 0 1 0 1 0 1 1 0 1 1 0 1 0 1 1 0 0 1 1 1 1 0 0 0 1 1 0 1 0 1 0 1 0 1 0 0 0 0 0 1 0 0 1 1 0 1 1 0 0 0 0 1 1 0 0 1 1 0 1 1 1 0 1 1 1 0 1 0 0 0 1 1 0 1) 11.217157 (fv 0.000000 1.333463 1.865492 -0.356718 0.933752 -0.563391 0.868454 1.227379 1.262853 1.734302 0.789925 0.887286 1.032388 0.794621 1.230657 -0.133505 -0.396357 0.347068 1.645124 0.776662 -0.030992 0.148253 0.191160 1.597265 0.105283 0.900423 1.230893 1.571345 0.370052 -0.251197 0.174670 0.404122 -0.082381 0.889967 -0.215160 -0.008260 -0.099660 1.159763 0.889422 1.423884 0.871705 1.850409 0.087109 1.706676 0.622672 0.936165 1.688780 1.528677 0.346829 0.012071 -0.088550 -0.030577 -0.043782 -0.058951 0.933603 1.070465 1.475594 1.531127 0.991234 0.010808 0.356054 0.157103 0.451907 -0.030459 -0.024818 0.523063 -0.129422 0.815521 1.075724 0.055269 0.750932 1.244054 1.306512 0.899391 -0.257291 1.664054 0.588171 1.065503 1.219153 1.371075 1.522174 0.737588 1.228742 1.773501 0.629941 0.387629 0.029457 1.398967 0.393091 1.680074 1.275817 0.905734 0.977246 -0.221887 1.339886 1.268897 1.260526 0.645165 1.510347 1.465708 0.394415 0.283387 1.630537 1.623821 0.888008 0.433073 0.790823 0.410278 1.398034 -0.237262 0.505122 -0.149516 0.721213 -0.202493 0.454561 1.014466 0.552452 1.112325 -1.848818 1.758603 1.154778 1.507049 0.724439 0.691362 -0.014103 1.227764) ) ;;; 127 odd -------------------------------------------------------------------------------- ; 11.2694 (vector 127 14.695912364919 (fv 0 0 1 0 1 1 0 0 1 1 1 0 1 0 1 0 1 1 1 1 0 1 1 1 1 0 1 1 1 0 1 0 1 0 0 0 1 0 0 0 0 1 0 0 0 1 1 1 0 0 0 1 0 0 1 1 0 1 1 1 1 1 0 0 1 1 1 1 1 0 0 0 1 0 0 1 1 1 0 0 0 1 1 0 1 0 1 0 1 1 0 0 1 1 0 0 0 0 0 0 1 1 0 1 0 1 0 0 1 0 0 1 0 0 1 1 1 0 1 0 0 0 0 0 0 0 0) 11.267676 (fv 0.000000 0.469645 0.796786 0.361018 -0.201613 1.310280 0.989111 0.525386 1.353693 0.378912 -0.241786 1.383164 1.533963 0.433890 0.325960 -0.352400 0.296358 0.481541 1.224829 0.787501 0.393768 1.211089 1.363561 0.247670 0.870376 1.154368 0.308126 1.041640 0.835212 1.804302 0.606799 0.022246 1.619342 1.154695 0.087857 0.758989 -0.028398 1.810844 1.763099 -0.171773 1.163226 0.592499 1.004685 0.695738 1.351120 0.977805 1.234286 1.609466 1.168845 1.598062 -0.321012 0.375057 0.817093 1.176853 0.878725 0.404937 0.672879 0.953648 1.504900 1.779440 0.534644 1.065489 -0.364994 1.703967 1.257601 -0.285618 0.908588 1.590737 1.087624 0.949190 1.204116 1.100315 0.879186 1.728483 1.796612 1.248626 1.298091 0.553842 1.379947 1.414383 0.591234 -0.228889 0.158060 -0.027394 0.157851 1.486700 0.372769 1.034786 0.707926 1.165159 0.328389 0.640197 0.421469 0.024384 1.129354 0.412245 0.531741 0.551732 0.008170 1.397227 1.653335 0.820170 0.216962 1.538735 0.975199 1.704359 0.157705 -0.426269 0.813101 0.999429 0.880927 1.743457 1.627725 0.094175 0.211869 0.002839 0.900464 1.204980 1.320644 1.281147 0.386967 0.783858 1.096686 0.213553 1.120859 -0.145308 0.996884) ) ;;; 128 odd -------------------------------------------------------------------------------- ; 11.3137 (vector 128 14.876242756695 (fv 0 1 0 0 1 1 1 1 1 1 0 1 1 1 0 1 0 1 1 0 1 0 1 1 0 1 1 1 0 0 1 0 1 1 1 1 1 1 1 1 0 0 1 1 1 0 1 0 1 0 0 0 1 0 0 0 0 1 0 1 0 1 0 1 1 0 1 0 0 1 0 0 0 1 1 1 1 1 0 0 1 1 1 1 1 0 1 0 0 1 0 0 1 1 0 0 0 1 0 1 0 0 0 1 1 1 0 1 1 1 0 0 0 0 0 0 1 1 1 1 0 1 1 0 1 1 0 1) 11.261196 (fv 0.000000 0.166552 0.658187 0.892812 0.275075 0.681304 0.935134 0.976324 1.751013 1.223679 0.531374 0.670158 0.738172 0.131342 0.784571 -0.001918 0.261947 -0.271711 1.074675 0.180917 0.495904 1.378525 0.720362 0.537440 1.116473 -0.311806 0.462073 0.021129 0.764859 1.361657 1.645691 -0.164691 0.135735 1.576068 0.824450 0.335134 1.099359 0.719625 0.791638 0.999013 0.348593 0.103014 1.062792 0.739933 1.675943 0.488371 0.860700 0.759566 1.276788 -0.135237 0.780818 -0.165115 1.024663 -0.327864 0.608127 1.454969 0.958609 0.555060 1.331156 0.762777 0.625297 1.411237 1.470303 1.190821 0.207444 0.108639 1.023133 1.165243 1.464221 1.564262 0.616076 0.019451 0.729986 0.402652 0.078552 0.454134 0.152695 0.263463 0.361958 1.475980 0.276689 1.365673 0.254488 -0.143709 1.946127 0.309551 1.760348 1.294342 0.981564 0.863637 1.477654 -0.019128 0.751338 0.878849 0.050601 0.063334 1.353561 1.669390 1.451518 0.535767 0.012898 0.428045 -0.011136 0.975409 -0.201088 0.677802 0.866124 0.188482 0.625213 1.342113 1.315837 0.879874 0.445664 1.081775 0.978490 1.662778 0.529736 1.946523 1.542905 0.571344 1.054205 0.430980 0.402697 -0.095096 1.487261 1.198691 1.754313 1.700742) ) ;;; 256 odd -------------------------------------------------------------------------------- (vector 256 22.546259712247 (fv 0 1 1 1 0 1 0 0 1 0 1 0 0 1 0 0 1 1 0 0 1 0 0 0 1 1 0 0 1 1 1 0 1 1 0 0 0 1 0 0 0 1 1 0 0 1 0 0 0 1 0 1 1 0 0 0 0 1 1 1 1 0 1 0 0 0 0 0 1 0 0 0 1 1 1 0 1 1 1 1 0 1 0 1 1 0 0 1 0 0 0 1 1 0 1 1 1 1 0 1 1 0 1 1 0 1 1 1 0 1 1 1 1 0 0 0 0 0 1 1 0 0 1 0 1 0 0 0 0 1 1 1 0 1 1 1 0 0 0 0 1 0 1 1 0 1 0 1 0 1 0 0 0 0 0 1 0 1 1 0 1 1 1 1 1 1 0 1 1 1 0 1 0 0 0 1 1 0 0 1 0 1 1 0 1 0 1 1 0 1 1 0 0 1 1 0 1 0 0 1 0 1 1 1 0 1 0 1 0 1 1 0 1 1 0 0 0 0 0 1 1 1 1 1 1 0 1 1 0 1 1 0 0 1 1 1 0 0 1 0 1 0 0 1 1 0 0 0 0 0 1 0 1 0 0 1) 16.932554 (fv 0.000000 0.299828 1.705033 -0.245282 1.517634 -0.512250 1.852696 -0.212031 1.625444 0.510314 1.972741 0.173230 1.725475 1.547901 0.804668 1.394746 0.173496 0.531764 0.731522 -0.060988 0.953386 0.234883 1.327931 1.710749 0.682372 1.593381 0.151697 0.696761 0.537335 1.969147 0.015426 0.808226 1.907797 1.558581 1.628528 1.165756 1.125630 1.795673 0.141122 0.016332 1.288127 0.941042 0.739123 0.972611 0.864761 0.875493 1.065737 0.205053 1.185762 0.863116 -0.053729 1.247127 1.771030 0.213109 0.203770 1.794944 0.080805 1.593027 0.197375 0.662307 -0.007433 1.307614 1.700096 0.641288 -0.016776 0.227057 0.210364 1.170957 1.587764 0.027010 1.239534 0.423010 0.803348 -0.009082 0.446764 0.636465 0.493264 -0.127025 0.112814 0.882192 1.818458 -0.107988 0.396084 1.293132 0.043609 1.657883 0.579794 0.180007 1.771600 1.131077 0.309105 0.137609 1.680511 0.060225 1.648041 -0.009446 0.270642 0.473937 1.608416 -0.014724 1.203911 1.240003 1.624613 1.562696 0.423323 0.330495 1.342929 0.063255 0.191341 0.910443 0.987286 0.949497 1.223867 1.261957 1.880192 0.302246 1.712139 1.779224 1.265963 1.777754 0.696982 1.379173 0.849932 1.580925 0.603387 1.028575 0.637130 0.740605 0.190997 1.448533 1.601710 1.704646 0.662313 0.835536 0.132357 0.868721 1.868738 1.555439 0.857103 1.813342 0.384273 0.308585 0.123611 1.182477 1.477561 1.678828 1.369057 1.213135 0.205042 0.425013 1.472803 1.396888 1.212323 1.858077 1.187399 0.010710 1.114100 1.840176 0.270787 0.093299 1.447701 0.449012 1.201616 1.113975 0.530506 1.655828 1.255713 -0.011414 0.956758 0.101851 1.223128 0.632983 0.423115 0.389217 1.423871 0.446874 1.820967 -0.029749 -0.443778 1.464394 0.868892 0.727400 0.578567 1.659072 1.017705 1.973528 -0.008925 0.757464 0.297947 -0.349297 0.883303 0.128256 1.200088 1.880227 0.584973 0.246525 0.618040 0.702249 1.255753 -0.329844 0.271022 0.297799 1.233191 1.390939 1.235027 0.303733 0.154150 0.491021 1.847433 1.056124 1.120988 1.805844 0.419548 1.016328 0.066448 0.893486 1.505832 0.702704 1.551981 1.267138 0.736198 0.947423 0.706820 -0.380019 0.873753 1.478444 0.561669 0.158253 0.016654 0.113131 1.644053 0.533397 0.826036 1.694860 0.852972 1.098260 0.229336 0.855766 1.051022 1.369585 0.520607 1.599761 1.473656 0.002020 0.572466 1.209260 1.275104 1.740654 1.738870 1.725547 1.490686 0.651000 0.118628 -0.196423 0.917329 0.845710) ) ;;; 512 odd -------------------------------------------------------------------------------- (vector 512 35.541 (fv 0 1 1 0 0 1 0 0 1 0 1 0 0 1 0 0 0 0 1 0 1 0 1 1 0 1 1 1 1 0 0 1 1 0 0 0 1 1 1 1 0 0 1 0 0 1 1 1 1 0 0 1 0 1 1 0 1 0 0 0 0 0 0 0 1 1 1 0 1 0 0 1 1 0 0 0 0 1 0 1 1 0 0 1 1 0 1 0 1 0 1 0 0 0 1 1 1 0 1 0 1 1 0 1 0 0 0 0 0 0 1 0 0 1 1 1 1 1 0 1 1 1 0 0 0 1 1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 0 1 1 0 0 0 0 1 0 1 1 0 0 0 1 1 1 0 1 0 1 1 1 1 0 0 1 1 0 0 1 1 0 0 0 1 1 0 0 0 0 0 1 1 0 0 1 0 0 0 1 1 0 1 0 1 1 0 0 0 1 0 0 1 1 0 1 1 1 0 1 0 1 0 1 1 0 1 0 0 1 0 0 1 1 0 0 1 0 1 1 0 1 1 0 1 0 0 0 0 0 0 1 1 1 0 1 0 0 0 0 0 0 1 0 0 0 1 1 0 1 0 1 0 0 0 0 1 1 0 1 0 0 1 1 0 1 1 0 0 1 0 0 0 1 0 0 0 0 1 1 0 1 0 1 0 0 1 1 1 1 0 1 1 1 0 1 1 1 1 1 0 1 0 1 0 0 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 0 1 0 0 1 1 1 0 0 0 1 0 0 0 1 0 0 1 0 0 1 0 1 0 0 0 0 0 1 1 0 1 1 1 0 0 0 0 1 1 1 1 1 1 0 1 1 0 0 1 0 1 1 0 0 1 0 0 0 1 1 1 1 1 1 1 1 1 1 0 1 1 0 1 0 0 1 1 1 0 1 1 1 1 0 0 1 0 0 0 1 1 0 1 1 0 0 1 0 0 0 0 1 0 1 1 1 1 1 0 1 0 0 0 1 0 0 1 0 1 0 1 1 0 1 0 0 0 0 1 0 1 0 1 0 1 1 0 1 1 0 1 1 1 0 1 1 1 0 1 0 0 1 0 1 0 0 0 0 0 0 1 1 1 0 1 0 0) ;; from (try-all :odd 512 513 0.0057812032540294 1.0142361702487) = 28.7291 start for next 23.716849 (fv 0.000000 1.386177 0.713008 0.003452 1.325461 0.665248 0.008142 1.314724 0.691474 0.066339 1.435981 0.804093 0.172765 1.522234 0.893751 0.277258 1.610102 1.005246 0.376177 1.775441 1.206877 0.615802 0.010188 1.376708 0.765127 0.173375 1.635776 1.029586 0.489561 1.940906 1.346730 0.810290 0.190213 1.646200 1.058365 0.502081 -0.085212 1.398947 0.892744 0.400807 1.903960 1.353268 0.833725 0.289010 1.806848 1.257743 0.707460 0.242200 1.750575 1.251783 0.742940 0.232633 1.756296 1.281177 0.783502 0.304115 1.846750 1.350399 0.916463 0.494039 0.029209 1.596080 1.095129 0.687317 0.229205 1.736704 1.290854 0.857342 0.417897 0.006810 1.604785 1.207241 0.745888 0.368498 1.939438 1.557313 1.176888 0.751323 0.345064 1.946256 1.587416 1.205053 0.847721 0.500526 0.105201 1.713914 1.348245 0.999166 0.643810 0.294307 -0.009291 1.648246 1.318017 0.946007 0.571567 0.250113 1.948602 1.641225 1.351970 1.040145 0.722431 0.402249 0.068667 1.761778 1.483321 1.168792 0.902292 0.622562 0.393716 0.071396 1.793757 1.520668 1.253207 0.968382 0.706598 0.478102 0.212208 1.966285 1.706429 1.495684 1.219831 0.986339 0.727326 0.553916 0.347750 0.133150 1.913130 1.701236 1.512062 1.283083 1.044773 0.859493 0.685612 0.480978 0.318075 0.155658 1.970256 1.731367 1.604854 1.456327 1.268574 1.110936 0.962304 0.806527 0.641956 0.496465 0.404452 0.274399 0.124501 -0.069746 1.814128 1.693756 1.567361 1.452982 1.402427 1.267889 1.106117 1.025358 0.944270 0.854118 0.753166 0.662874 0.577504 0.540814 0.454691 0.364705 0.334774 0.260515 0.174172 0.114008 0.059753 0.021108 1.967795 1.940561 1.926108 1.817829 1.816578 1.829230 1.763717 1.746146 1.768340 1.735638 1.694243 1.717300 1.700307 1.673492 1.703276 1.765354 1.728149 1.721871 1.792759 1.836518 1.790659 1.869572 1.931889 1.911416 -0.049508 0.040552 0.076661 0.124548 0.190446 0.213683 0.290047 0.374351 0.444676 0.515097 0.588488 0.695903 0.781037 0.806660 0.921756 1.050977 1.179273 1.276197 1.323471 1.440301 1.570781 1.698955 1.827110 1.973403 0.095016 0.228855 0.385876 0.488292 0.634453 0.804119 0.947283 1.092378 1.233063 1.412122 1.598977 1.789895 1.950360 0.140199 0.270111 0.484542 0.676076 0.875520 1.062416 1.258627 1.458192 1.707297 1.921954 0.119209 0.298949 0.581405 0.769515 1.026853 1.223167 1.513273 1.727029 -0.017306 0.209900 0.500939 0.701672 0.977279 1.216826 1.499384 1.779833 0.099435 0.337187 0.641811 0.927329 1.208595 1.453552 1.744657 0.045196 0.356852 0.724238 1.011858 1.349837 1.617935 1.987915 0.263154 0.637781 0.962300 1.293802 1.623598 1.910194 0.353508 0.625937 1.050232 1.343506 1.742985 0.092929 0.488000 0.864319 1.233651 1.609043 0.033469 0.414020 0.804580 1.109133 1.582193 1.963439 0.408246 0.805244 1.229890 1.616430 -0.005644 0.499002 0.871222 1.383619 1.742006 0.241871 0.636412 1.111292 1.523864 0.013426 0.430112 0.957489 1.390576 1.854792 0.298131 0.775965 1.336493 1.765508 0.284032 0.739560 1.225735 1.770015 0.245509 0.759950 1.283127 1.750994 0.271698 0.822357 1.329050 1.911458 0.424517 0.913054 1.452733 0.010207 0.507166 1.142838 1.653176 0.267116 0.766064 1.355041 1.954872 0.526119 1.075422 1.710371 0.220956 0.795713 1.455244 0.009017 0.572263 1.233742 1.805199 0.351214 1.029595 1.670810 0.244898 0.937764 1.599384 0.123281 0.827498 1.421956 0.071912 0.728628 1.352525 0.045071 0.629616 1.340343 -0.005599 0.656031 1.375774 0.006637 0.704005 1.346778 0.026276 0.793500 1.469628 0.149189 0.900114 1.563003 0.245092 0.942737 1.649937 0.383461 1.127594 1.833496 0.630173 1.303349 0.131274 0.795917 1.555017 0.354577 1.010369 1.836168 0.566636 1.392645 0.086446 0.905432 1.674552 0.357250 1.244274 1.933313 0.772802 1.613083 0.347109 1.198474 -0.009249 0.816204 1.581830 0.444697 1.252833 0.100839 0.820624 1.756368 0.556323 1.425952 0.202073 1.114604 1.862430 0.795077 1.577287 0.478129 1.375476 0.190400 1.049976 -0.001037 0.879181 1.750477 0.621432 1.466044 0.413933 1.258876 0.154463 1.083320 0.023406 0.861084 1.792442 0.739423 1.747839 0.555786 1.545715 0.467356 1.398174 0.305932 1.268574 0.245015 1.132661 0.145880 1.048422 0.017779 0.982729 1.923364 0.991511 1.957307 0.987170 1.902716 0.862590 1.910349 0.888567 1.920187 0.891111 1.886256 0.901663 1.918496 0.888352 1.914645 0.897685 -0.010739 0.984051 0.045577 1.089818 0.179909 1.199148 0.242854 1.360751 0.407503 1.407270 0.484554 1.541970 0.605558 1.705736 0.805033 1.904246 0.915747 0.018600 1.130323 0.275353 1.311301 0.394011 1.535459 0.601518 1.753472 0.894346 0.028620 1.161824 0.267287 1.447242 0.509507 1.658579 0.805465 0.032994 1.137888 0.321598 1.466044 0.648028 1.757642 1.015016 0.177874 1.323344 0.563863 1.750425 0.967203 0.229423 1.447094 0.698358) ) ;;; 1024 odd -------------------------------------------------------------------------------- (vector 1024 52.508 (fv 0 1 0 1 0 0 1 1 0 1 0 1 0 0 1 0 1 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 1 1 1 1 1 1 1 0 0 1 0 1 1 0 0 1 0 1 1 0 1 1 0 0 0 1 0 0 1 0 0 1 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 1 1 1 0 0 0 0 1 1 1 1 1 1 0 1 1 1 1 1 0 0 0 1 1 0 0 0 0 0 0 0 0 1 1 1 1 1 0 1 0 0 1 0 0 0 0 1 0 0 1 0 0 1 1 0 1 0 0 1 1 0 0 0 0 0 0 1 1 1 1 1 1 0 1 1 1 0 1 0 0 1 0 0 1 1 0 1 1 0 0 1 1 0 1 0 1 0 1 1 0 1 0 0 0 0 1 1 1 1 0 1 1 1 0 0 0 0 0 0 1 1 1 0 1 0 0 1 1 0 0 0 1 1 0 0 0 1 0 0 0 0 0 0 1 0 1 1 0 1 1 0 1 0 1 1 0 0 1 0 0 1 0 0 0 0 0 0 1 0 0 0 1 0 1 0 1 1 1 0 0 1 1 1 0 1 0 0 1 1 0 0 1 1 1 0 1 0 1 1 0 0 0 1 0 0 0 0 0 0 1 1 0 0 1 1 1 1 1 0 0 0 1 1 0 1 1 0 1 0 1 0 1 0 1 0 0 1 1 1 0 1 1 1 1 1 0 0 0 0 1 0 0 1 0 0 0 0 0 1 0 0 1 1 0 1 0 0 0 0 0 0 1 1 1 1 0 1 0 1 1 0 0 0 1 1 1 0 0 1 0 1 1 1 1 0 0 0 1 0 1 1 0 1 1 1 1 0 1 1 0 1 0 1 1 1 0 0 1 1 0 1 0 1 0 0 1 1 0 0 1 1 1 0 1 0 0 0 1 1 1 1 0 0 1 0 0 0 1 1 1 0 0 0 1 1 1 1 0 0 1 0 1 0 1 0 0 1 1 0 1 1 0 1 1 1 0 0 1 0 1 0 0 1 1 0 1 0 1 1 0 0 0 1 0 0 1 0 0 1 1 0 1 0 1 1 0 1 1 0 0 1 1 0 0 1 1 0 1 1 0 1 0 0 1 1 0 1 1 1 1 0 1 1 0 0 1 1 0 1 0 1 0 0 1 0 1 0 1 1 1 1 0 1 0 1 1 0 0 1 0 0 0 1 0 1 0 0 0 1 0 1 1 1 1 0 1 1 1 1 1 1 0 0 0 1 1 1 0 1 1 1 1 0 1 1 1 1 0 0 0 1 1 0 0 1 0 1 1 0 0 1 0 1 1 0 1 1 0 0 0 0 0 0 1 0 1 0 1 1 0 0 1 1 1 1 1 0 1 0 0 0 1 1 1 0 1 1 0 0 1 0 0 1 0 0 0 1 0 1 0 0 1 1 1 1 1 1 1 1 0 1 1 1 1 0 1 0 1 1 0 1 0 0 1 1 0 0 1 0 0 0 0 0 1 0 1 0 1 1 1 0 0 1 0 1 0 1 1 1 1 1 0 1 0 1 1 1 1 0 1 0 1 0 1 1 1 0 1 0 0 1 1 1 1 0 1 1 1 0 1 1 1 1 1 0 1 0 0 1 1 1 0 0 0 0 1 0 0 1 1 1 1 1 1 1 0 1 0 0 1 1 0 1 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 1 0 1 1 0 0 1 1 1 1 0 0 1 0 1 0 0 0 1 0 0 0 1 1 1 1 1 1 0 0 1 0 0 1 1 0 0 1 1 1 1 0 0 0 0 0 1 1 1 1 0 1 0 1 1 1 1 1 0 0 0 1 1 1 1 1 1 1 0 1 1 1 0 0 0 0 0 0 0 1 1 1 1 0 1 0 0 1 0 0 1 0 0 0 1 0 1 0 1 1 0 1 1 1 0 0 1 1 1 1 1 1 1 0 1 0 1 1 0 1 1 0 0 0 1 1 0 0 1 1 0 1 1 1 1 1 0 0 0 0 1 0 0 1 0 1 1 1 0 0 1 0 1 1 0 0 0 1 0 1 0 0 0 0 0 1 0 1 0 0 1 1 0 0 0 1 0 0 1 1 1 0 1 1 0 1 1 0 1 0 1 1 0 0 1 0 0 1 0 0 0 0 0 1 1 1 0 1 0 0 0 1 0 0 0 0 1 1 0 1 0 1 0 0 0 0 0 1 0 0 1 1 1 1 0 1 0 0 1 1 0 0 0 0 0 1 0 1 0 1 0 1 1 0 0) ;; pp: 34.392721 (fv 0.000000 1.317015 0.674779 1.982962 1.240298 0.528350 1.833009 1.184236 0.493774 1.806145 1.182946 0.448825 1.821424 1.151757 0.480986 1.763416 1.095092 0.480961 1.791102 1.089742 0.425064 1.810482 1.139747 0.479199 1.851874 1.159831 0.593521 1.908566 1.257454 0.624639 1.923688 1.356173 0.730179 0.065917 1.453464 0.796504 0.143823 1.498311 0.930898 0.268139 1.670589 1.071439 0.437215 1.830479 1.211388 0.579275 1.944545 1.352798 0.782323 0.163213 1.546183 0.998593 0.372903 1.740779 1.173402 0.607928 1.957457 1.421061 0.794849 0.200913 1.627038 1.034849 0.443314 1.872228 1.278283 0.705912 0.120047 1.589838 1.008630 0.435503 1.873305 1.305243 0.750876 0.182690 1.613160 1.076228 0.522005 1.956954 1.342360 0.862346 0.285706 1.760264 1.217014 0.657381 0.105715 1.596004 1.072881 0.509956 1.989648 1.482549 0.909572 0.382452 1.811853 1.285963 0.790319 0.256573 1.787382 1.233231 0.764390 0.267593 1.710421 1.204241 0.717040 0.198483 1.666956 1.176156 0.629456 0.175734 1.712604 1.178350 0.682452 0.188929 1.683627 1.202732 0.719895 0.262572 1.790292 1.295239 0.795972 0.278798 1.833102 1.391719 0.903871 0.449916 1.974967 1.508707 1.037936 0.583107 0.141605 1.703044 1.238440 0.740044 0.299258 1.855225 1.429576 0.989596 0.514764 0.062488 1.647875 1.166263 0.761797 0.338506 1.886563 1.481742 1.044532 0.567257 0.147738 1.716688 1.294451 0.881968 0.450214 0.034958 1.623040 1.198786 0.793126 0.363888 1.989592 1.572534 1.171188 0.776534 0.389043 1.952235 1.569973 1.168583 0.777864 0.378289 -0.001325 1.586748 1.247726 0.850390 0.447022 0.074915 1.698680 1.326882 0.923704 0.565421 0.237083 1.853803 1.462394 1.056831 0.725010 0.363991 0.012216 1.652820 1.277504 0.885858 0.571701 0.222046 1.859385 1.459785 1.149298 0.900479 0.511390 0.159291 1.820323 1.458104 1.134095 0.799510 0.484897 0.157474 1.805324 1.476907 1.156786 0.816645 0.506771 0.217712 1.883199 1.597354 1.267437 0.968501 0.643403 0.348141 0.020835 1.704752 1.434890 1.117956 0.830415 0.530503 0.257242 1.947331 1.636892 1.333893 1.094111 0.807494 0.497231 0.208241 1.915803 1.637253 1.344506 1.123056 0.818815 0.558438 0.305779 0.033645 1.746424 1.518158 1.254602 0.968482 0.703273 0.446681 0.191633 1.923009 1.675267 1.476497 1.243700 0.963799 0.702657 0.470865 0.216712 1.947604 1.723443 1.524612 1.317633 1.059361 0.803260 0.606501 0.385543 0.151108 1.924868 1.695521 1.503299 1.281531 1.057219 0.859940 0.639048 0.449655 0.223761 0.026912 1.843647 1.609629 1.457584 1.243217 1.015301 0.856152 0.640867 0.449759 0.305372 0.109063 1.942683 1.700967 1.531585 1.369794 1.168417 1.002048 0.845104 0.663340 0.497202 0.326517 0.140599 1.976113 1.831407 1.680660 1.549301 1.318125 1.191866 1.065805 0.880646 0.703951 0.550638 0.452796 0.318542 0.141930 -0.012601 1.907136 1.768430 1.584977 1.494785 1.346262 1.172515 1.087240 0.966198 0.858840 0.703924 0.583577 0.474879 0.356476 0.197334 0.117696 0.015827 1.890727 1.784295 1.703630 1.595638 1.506189 1.428853 1.274571 1.233343 1.102367 1.018735 0.924053 0.785452 0.761105 0.689124 0.597680 0.499179 0.407270 0.343269 0.277076 0.175925 0.088491 0.032717 1.967765 1.919505 1.879027 1.804127 1.733139 1.641796 1.606538 1.554956 1.479897 1.436117 1.392760 1.340159 1.307310 1.256130 1.185964 1.154240 1.120113 1.056364 1.031418 1.011146 1.002760 0.949072 0.908672 0.908037 0.883988 0.852980 0.834564 0.819259 0.795425 0.760734 0.784982 0.783111 0.748706 0.732608 0.767981 0.770232 0.734127 0.724984 0.741588 0.719772 0.746177 0.752984 0.689077 0.730980 0.788291 0.778438 0.770103 0.834963 0.846761 0.844355 0.877284 0.886824 0.967748 0.943247 0.953145 0.998516 1.074936 1.134627 1.111633 1.183518 1.239447 1.257881 1.304163 1.349165 1.420127 1.460314 1.496520 1.556878 1.614974 1.710803 1.681591 1.773792 1.838949 1.957629 0.007509 0.060966 0.115693 0.179937 0.241468 0.370584 0.498441 0.512979 0.546150 0.672229 0.777236 0.837830 0.920719 1.012615 1.155268 1.230312 1.320616 1.421802 1.501826 1.610987 1.679360 1.836841 1.934427 0.048217 0.190841 0.256986 0.405599 0.477014 0.615469 0.744693 0.842741 1.035072 1.099483 1.194667 1.378972 1.515049 1.643373 1.758812 1.911300 0.069797 0.206668 0.341125 0.455780 0.613455 0.755668 0.907850 1.081007 1.195602 1.383308 1.535129 1.721055 1.878218 0.041536 0.189026 0.353901 0.557274 0.704028 0.848737 1.054909 1.205891 1.405592 1.560938 1.774026 1.957109 0.091600 0.275670 0.473243 0.686721 0.885668 1.094370 1.301170 1.471171 1.681947 1.843932 0.083106 0.309503 0.504329 0.657776 0.958045 1.134304 1.324317 1.567796 1.766909 -0.010677 0.204548 0.402525 0.672227 0.872133 1.100672 1.351290 1.618868 1.843408 0.075626 0.310891 0.533995 0.758681 1.049764 1.305644 1.509216 1.751579 -0.013073 0.274157 0.516916 0.787195 1.008768 1.270118 1.566936 1.844511 0.111113 0.352928 0.603624 0.891444 1.163881 1.458453 1.733841 0.023761 0.272991 0.561395 0.839977 1.118462 1.400784 1.742015 0.003935 0.343587 0.574049 0.863833 1.186411 1.499354 1.787869 0.097742 0.435769 0.722422 1.020105 1.302404 1.633505 1.971294 0.287332 0.601601 0.938262 1.263087 1.592727 1.925082 0.218290 0.545858 0.867906 1.215434 1.551258 1.932054 0.206490 0.558053 0.870542 1.249383 1.578868 1.965694 0.297948 0.669516 1.033694 1.365067 1.747836 0.132641 0.442218 0.763117 1.198426 1.557543 1.923389 0.271522 0.661990 1.014563 1.444192 1.797008 0.161991 0.524112 0.888782 1.298446 1.718909 0.076039 0.484430 0.839832 1.306121 1.668787 0.083313 0.435491 0.879913 1.257582 1.690719 0.080308 0.506436 0.891141 1.311805 1.764926 0.152722 0.559148 0.971038 1.448176 1.861615 0.252724 0.712441 1.076577 1.539614 1.971176 0.471842 0.835551 1.309070 1.717329 0.180700 0.636594 1.064174 1.544102 -0.007762 0.416278 0.869839 1.382020 1.815476 0.242696 0.711954 1.170869 1.650991 0.114702 0.570777 1.081829 1.495277 0.019284 0.487771 0.924782 1.480485 1.900085 0.404735 0.867120 1.327489 1.826631 0.358328 0.808934 1.333994 1.818046 0.333979 0.806858 1.380168 1.806454 0.359466 0.853343 1.382938 1.862803 0.340011 0.872790 1.396435 1.899417 0.442767 0.947972 1.493994 1.980445 0.529919 1.068138 1.589158 0.137689 0.663574 1.181143 1.752788 0.322938 0.820947 1.373072 1.889133 0.445963 0.992038 1.528221 0.095252 0.632298 1.198655 1.748035 0.297075 0.936319 1.444019 0.047595 0.589072 1.154608 1.695982 0.330959 0.852209 1.389811 0.077042 0.588685 1.198301 1.795185 0.391299 0.937105 1.523925 0.144908 0.714581 1.301387 1.939659 0.493164 1.107096 1.703099 0.316955 0.870409 1.501496 0.129186 0.711707 1.317045 1.978135 0.584637 1.224551 1.868953 0.442970 1.080315 1.707774 0.357018 0.974517 1.620426 0.235492 0.841352 1.521747 0.123410 0.790984 1.421592 0.064670 0.723003 1.351207 0.045603 0.693853 1.324941 1.912908 0.655177 1.230998 1.943702 0.623916 1.262813 1.966107 0.647728 1.291260 -0.014812 0.660846 1.298115 1.981874 0.677526 1.342226 0.031840 0.703622 1.442866 0.109986 0.793203 1.504134 0.206491 0.825844 1.597562 0.229750 0.978345 1.663467 0.352650 1.124308 1.766717 0.525984 1.219293 1.922574 0.634505 1.397287 0.124002 0.815463 1.541148 0.270810 0.971099 1.707596 0.437736 1.212172 1.890534 0.685239 1.396549 0.142117 0.918957 1.612171 0.353680 1.097854 1.856615 0.625689 1.360735 0.144106 0.868556 1.645077 0.371361 1.159444 1.934695 0.709026 1.444089 0.261765 0.979371 1.759253 0.586016 1.331408 0.040944 0.869861 1.656050 0.398966 1.230315 -0.011049 0.832509 1.590410 0.444043 1.224804 1.942115 0.805768 1.569036 0.391426 1.193271 0.004924 0.842160 1.602154 0.437188 1.258662 0.040043 0.863713 1.717625 0.507115 1.354811 0.156612 1.008626 1.821294 0.688919 1.479431 0.297482 1.146867 -1.810005 0.794603 1.643039 0.507902 1.394627 0.290315 1.060141 1.927240 0.768749 1.644777 0.486261 1.317365 0.218780 1.036302 1.922905 0.779349 1.630284 0.563756 1.406014 0.271501 1.141687 0.041164 0.874901 1.775827 0.668920 1.546772 0.364463 1.296432 0.170145 1.097114 1.973808 0.882000 1.792309 0.693487 1.612279 0.474678 1.407303 0.261600 1.229905 0.148970 1.031540 1.947561 0.833597 1.730941 0.706036 1.602109 0.526360 1.446317 0.373717 1.307908 0.239206 1.185883 0.110452 1.032954 1.964211 0.907562 1.815735 0.787542 1.710692 0.656401 1.632264 0.576380 1.564089 0.528884 1.469549 0.431489 1.360957 0.347473 1.293543 0.222180 1.220673 0.162142 1.148842 0.133424 1.094691 0.066720 1.019692 -0.006786 1.047790 0.011236 0.965321 -0.001627 0.937877 1.944261 0.948457 1.895707 0.938491 1.920374 0.874935 1.899449 0.872969 1.896569 0.903922 1.912216 0.936328 1.952448 0.974497 -0.020866 1.017959 0.034307 1.070969 0.074184 1.113113 0.135779 1.148879 0.214381 1.271662 0.291028 1.343329 0.357341 1.403370 0.477523 1.529396 0.455395 1.531182 0.601378 1.631083 0.711227 1.779155 0.803158 1.876551 0.904319 -0.035936 1.056817 0.081070 1.174378 0.241814 1.361054 0.443021 1.490091 0.588025 1.673301 0.764365 1.818515 0.913749 -1.572594 1.052243 0.145347 1.264925 0.396952 1.483333 0.517869 1.682100 0.797822 1.866022 0.903075 0.059188 1.174828 0.259185 1.333418 0.505568 1.549370 0.702792 1.812741 0.956324 0.074522 1.232362 0.362743 1.384904 0.593454 1.680361 0.825559 -0.014856 1.137655 0.232493 1.374902 0.524195 1.748587 0.847680 -0.019007 1.123158 0.242002 1.489181 0.571161 1.741577 0.879445 0.077203 1.250223 0.427139 1.517047 0.773877 1.934390 1.107301 0.293756 1.489154 0.668130 1.818952 0.975240 0.242147 1.451579) ) ;;; 2048 odd -------------------------------------------------------------------------------- (vector 2048 83.108 (fv 0 1 1 0 1 0 1 0 1 1 1 0 0 0 0 0 1 0 1 1 0 1 1 0 0 1 1 0 1 1 0 1 1 1 1 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 0 0 0 1 0 0 0 1 0 1 1 1 1 0 1 1 0 0 1 0 1 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 0 1 1 0 1 1 0 0 0 1 1 1 1 0 0 0 1 0 1 1 1 1 1 0 0 0 0 0 0 1 0 0 0 1 1 1 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0 0 0 1 1 0 0 0 1 0 1 1 1 0 1 0 0 1 0 1 1 1 1 0 1 0 1 0 1 0 0 1 0 1 0 0 0 1 1 0 1 1 1 0 1 1 0 0 1 0 1 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 0 1 1 1 0 1 0 0 0 1 1 0 1 0 1 1 0 0 1 1 0 1 0 1 1 1 0 1 1 0 1 1 1 0 1 1 0 1 0 1 1 1 0 0 0 1 0 1 0 0 1 1 0 1 0 0 1 1 1 0 1 0 1 0 1 0 1 0 1 0 0 0 1 1 1 1 1 0 1 1 1 0 0 1 1 1 1 1 0 1 1 0 0 0 1 0 1 1 1 0 0 0 0 0 0 1 0 1 1 0 1 1 1 1 1 0 1 0 1 0 1 1 1 1 1 1 1 0 1 1 1 1 1 0 1 0 1 0 0 1 0 0 1 0 1 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 0 1 1 1 0 0 0 1 1 1 0 0 0 0 0 0 1 1 1 1 0 0 1 0 0 1 0 0 1 1 1 0 1 0 0 0 0 1 1 1 1 0 0 1 0 0 1 1 0 1 0 0 0 0 1 0 1 1 0 0 0 1 1 1 0 1 1 0 1 0 0 0 1 1 0 0 1 0 0 0 0 1 1 1 1 1 0 0 1 1 0 0 0 1 0 1 0 0 1 0 1 0 0 0 1 1 1 0 1 0 0 1 0 0 0 0 1 1 1 1 0 0 1 1 1 1 1 0 1 0 0 1 0 0 1 1 0 1 0 0 0 0 1 1 0 1 1 0 1 1 1 0 0 1 0 0 0 0 1 0 1 1 1 0 1 0 1 0 0 1 1 1 0 1 1 0 1 1 0 1 1 1 0 0 1 1 0 0 1 1 0 0 0 1 0 1 1 0 0 1 1 1 1 1 1 0 0 0 1 0 1 0 0 0 1 0 1 1 1 1 0 1 0 0 1 0 0 0 0 1 0 0 0 1 0 0 1 1 1 0 0 0 0 1 0 0 1 0 1 0 1 1 1 0 1 0 1 0 0 0 0 1 0 0 1 0 1 1 0 1 0 1 0 0 0 0 0 0 1 0 0 1 1 1 1 1 0 0 1 0 0 0 1 0 1 0 0 1 0 1 1 0 1 0 0 0 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 0 1 1 0 1 0 0 0 0 1 0 0 0 0 1 0 1 1 0 0 0 1 0 1 1 1 0 0 0 1 0 1 1 0 1 0 0 0 1 0 0 1 0 0 1 1 0 1 1 1 1 0 0 1 0 0 1 1 0 0 1 1 0 1 0 1 0 0 0 0 0 0 0 1 0 0 0 1 0 1 1 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 1 0 1 1 0 0 0 1 0 0 1 1 0 0 1 1 1 0 0 1 1 1 0 0 0 1 0 0 1 1 1 0 1 1 0 1 1 0 1 0 1 0 1 0 1 1 0 0 1 1 0 1 0 1 1 1 1 0 0 0 0 1 1 0 1 0 1 1 0 0 0 1 1 1 1 1 0 0 0 1 0 1 1 1 1 1 0 1 0 0 0 0 0 0 0 0 1 1 0 1 0 0 1 1 1 1 0 0 0 0 1 0 1 0 0 1 0 0 0 0 0 1 1 0 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 1 0 1 0 1 0 0 1 0 0 1 1 1 0 1 0 0 0 0 0 0 0 0 1 0 1 1 1 1 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 1 1 0 1 1 1 0 0 0 1 0 1 0 1 0 0 1 0 1 1 1 1 1 1 1 1 1 0 0 1 1 0 0 0 1 1 0 1 1 0 1 0 1 0 1 1 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 1 1 1 0 0 1 1 1 0 1 1 0 0 1 1 1 1 1 0 0 0 0 0 1 0 0 0 1 0 1 0 0 0 0 1 0 1 1 0 0 1 1 1 0 1 1 0 1 1 1 1 1 1 1 0 1 1 1 1 0 0 1 0 0 1 0 1 1 0 1 1 1 0 1 1 0 1 1 0 0 0 1 1 1 0 1 1 0 1 1 0 1 0 1 0 0 1 0 0 0 0 0 1 1 1 0 0 0 0 0 1 0 1 0 1 0 0 1 1 0 1 0 1 0 0 0 0 0 1 0 1 0 0 1 1 1 0 0 0 0 0 1 0 1 0 0 0 1 1 0 1 1 1 0 0 1 1 1 0 0 0 1 0 1 0 1 1 1 0 0 1 0 1 0 0 1 0 0 1 0 1 0 0 1 0 1 0 1 1 1 0 1 0 0 0 1 1 1 0 1 1 1 1 1 1 0 1 1 0 0 1 1 0 1 1 0 0 0 1 1 0 0 0 1 0 0 1 0 0 0 0 0 1 0 1 1 0 0 0 0 1 0 1 1 1 0 0 0 1 1 1 1 0 1 0 1 1 0 0 0 0 0 1 0 1 1 0 0 0 1 1 0 0 1 0 0 1 0 1 0 0 1 1 1 1 0 0 1 1 1 1 1 1 0 1 1 1 0 1 0 1 0 0 1 1 0 0 0 1 0 1 1 0 0 1 0 0 1 0 0 1 0 1 1 0 1 1 0 1 1 1 0 0 0 1 0 0 1 1 0 1 0 0 0 1 0 0 1 0 1 1 1 0 1 1 1 1 0 1 1 0 1 0 1 1 0 1 0 0 0 0 1 0 0 0 1 0 0 1 0 1 1 1 1 0 0 0 0 1 1 0 1 0 0 1 1 1 1 1 0 0 1 0 0 0 1 0 0 0 0 1 1 0 0 1 0 1 0 0 1 0 0 1 1 0 1 1 0 0 0 0 1 1 0 0 0 1 1 1 0 1 0 0 0 0 0 1 0 0 1 1 1 0 0 0 0 0 1 1 0 1 1 1 0 1 1 0 0 1 0 0 0 1 0 1 0 0 1 1 0 1 0 0 0 0 1 0 1 1 1 0 1 0 1 1 1 1 1 1 0 1 1 0 0 0 1 0 1 1 0 0 1 1 1 1 0 0 0 1 0 0 1 1 0 0 1 0 1 0 0 0 1 0 1 1 1 0 0 0 1 1 1 0 0 1 1 1 0 0 1 1 1 1 0 0 0 0 0 1 0 0 0 0 0 1 1 0 1 1 1 1 0 0 1 0 1 0 1 0 1 0 1 1 1 1 0 0 0 0 1 0 1 0 0 1 1 0 0 1 1 0 0 1 0 0 0 1 0 0 0 0 0 0 0 1 1 0 1 1 1 1 0 0 1 1 0 1 1 1 1 1 0 1 0 0 1 0 0 1 0 0 0 1 0 1 1 0 1 1 1 1 1 1 1 0 1 0 1 1 0 0 1 1 1 1 0 0 0 0 1 1 0 1 0 0 1 1 1 0 0 1 0 0 0 1 0 0 0 0 1 0 1 0 1 1 0 0 1 0 1 0 0 0 1 1 0 1 0 1 1 1 1 1 0 0 1 1 1 1 1 0 1 0 0 1 1 0 0 1 0 0 0 1 0 1 0 0 1 1 0 0 0 1 1 1 0 1 1 0 1 1 1 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 1 1 0 1 0 1 1 1 0 1 0 0 0 0 1 1 1 0 0 0 1 1 0 0 1 1 1 0 1 0 1 0 1 1 0 0 1 0 0 0 1 0 1 0 1 0 1 0 1 0 1 0 0 0 0 1 1 1 0 0 1 1 0 1 1 0 1 1 0 1 1 0 0 1 1 1 0 1 1 0 1 0 0 0 1 0 1 1 1 1 0 0 1 1 0 1 0 1 1 1 0 1 0 0 0 1 0 0 1 1 1 0 0 0 1 1 1 0 1 1 0 1 0 0 1 1 1 1 1 0 0 1 1 0 0 0 1 1 1 0 0 1 1 1 1 0 0 1 0 1 1 1 0 0 0 0 1 1 1 1 0 0 1 0 1 0 1 1 0 1 0 1 1 1 1 1 1 1 1 1 1 0 0 0 1 0 0 0 1 1 1 1 0 0 1 1 1 1 0 1 1 1 0 0 0 0) ;; pp: 49.287435 (fv 0.000000 1.163050 0.277646 1.373554 0.532725 1.655947 0.820565 1.927219 1.072745 0.213781 1.356870 0.485766 1.631061 0.742006 1.904473 1.072791 0.168162 1.327500 0.482508 1.618303 0.771705 1.904773 1.075185 0.215222 1.331659 0.505811 1.654486 0.806874 1.967453 1.148945 0.298519 1.468811 0.620677 1.776228 0.916764 0.084037 1.276979 0.394330 1.564305 0.749970 1.921810 1.121962 0.283495 1.432158 0.569765 1.736470 0.945747 0.080800 1.281360 0.443507 1.625343 0.807138 1.931288 1.158701 0.321739 1.530411 0.700718 1.890240 1.080826 0.244264 1.426463 0.600267 1.774421 0.956059 0.179462 1.370744 0.545050 1.731587 0.953856 0.145408 1.309295 0.511421 1.720420 0.940468 0.138677 1.323833 0.526937 1.717512 0.960485 0.118979 1.328593 0.512297 1.743197 0.943001 0.142257 1.379625 0.549098 1.794241 0.979771 0.180869 1.419130 0.639674 1.850039 1.057471 0.290050 1.461420 0.718417 1.916269 1.159248 0.376289 1.563835 0.838106 0.037452 1.264868 0.508203 1.717190 0.935903 0.151060 1.445292 0.635249 1.867259 1.091222 0.317894 1.534564 0.808426 0.018427 1.266394 0.501751 1.761251 0.969688 0.237229 1.447668 0.716233 1.967410 1.198658 0.437002 1.692103 0.935631 0.200934 1.451676 0.665324 1.935418 1.194689 0.438772 1.699157 0.941183 0.203098 1.450490 0.729357 1.974455 1.213355 0.514075 1.770795 1.016076 0.295868 1.541971 0.834628 0.084952 1.374773 0.619458 1.894143 1.155880 0.407649 1.664716 0.945886 0.261286 1.509195 0.790733 0.047158 1.339941 0.639173 1.891712 1.178155 0.440268 1.738740 1.006239 0.332871 1.560537 0.905839 0.183339 1.475973 0.742124 0.065572 1.351730 0.625747 1.922985 1.191379 0.495991 1.756410 1.042066 0.381601 1.688479 0.992449 0.276849 1.595880 0.892119 0.200958 1.480411 0.818652 0.063966 1.413208 0.715156 0.060494 1.306176 0.640302 1.933579 1.251340 0.581804 1.880299 1.222695 0.508151 1.829141 1.161265 0.457492 1.752607 1.117371 0.435825 1.739733 1.091313 0.385593 1.723501 1.053105 0.375468 1.675086 1.049746 0.382492 1.691106 1.002188 0.342988 1.668975 1.033939 0.350582 1.709840 1.039364 0.383857 1.699746 1.051825 0.373545 1.743567 1.077799 0.434091 1.756970 1.053381 0.443137 1.778145 1.141987 0.502378 1.868431 1.182592 0.530883 1.877105 1.221950 0.588162 -0.002020 1.300304 0.652550 0.036320 1.381929 0.759328 0.108443 1.476502 0.816837 0.213269 1.571344 0.932844 0.309569 1.662539 1.059667 0.419312 1.755499 1.147048 0.543079 1.922420 1.264945 0.657934 0.013132 1.401680 0.801987 0.158358 1.552678 0.920579 0.315474 1.699024 1.059115 0.446156 1.851458 1.209975 0.614230 1.975779 1.374097 0.796121 0.175298 1.591247 0.945333 0.354628 1.747078 1.154595 0.559485 1.967019 1.333396 0.720565 0.122103 1.526595 0.940456 0.327202 1.755683 1.117391 0.561694 1.958381 1.361193 0.803458 0.184110 1.616629 1.006925 0.442089 1.829688 1.261188 0.655027 0.090202 1.509923 0.945564 0.313543 1.753214 1.130948 0.568508 0.031964 1.450068 0.852461 0.283077 1.729985 1.127584 0.580935 -0.001861 1.435678 0.878175 0.293173 1.719785 1.184765 0.606034 0.040632 1.478744 0.942562 0.348499 1.801185 1.227587 0.696736 0.112509 1.564761 0.997649 0.448218 1.895579 1.324465 0.786873 0.273294 1.679282 1.152398 0.603084 0.027394 1.495848 0.964252 0.380193 1.852378 1.306385 0.788058 0.249156 1.687499 1.121997 0.611298 0.090174 1.559009 0.973272 0.464823 1.921940 1.378762 0.867253 0.345833 1.810423 1.301030 0.744928 0.252599 1.735986 1.205901 0.677471 0.145109 1.614381 1.080917 0.586366 0.083099 1.542748 1.001440 0.520731 0.003110 1.438773 0.930269 0.427623 1.972229 1.416238 0.940471 0.422555 1.905093 1.411628 0.878267 0.378282 1.870882 1.386240 0.872844 0.369185 1.888119 1.372843 0.868051 0.364903 1.849288 1.377695 0.870674 0.392638 1.894252 1.393508 0.953494 0.447692 1.964212 1.461256 0.958900 0.491909 0.001252 1.522315 1.032375 0.545182 0.047665 1.604571 1.102550 0.587351 0.146687 1.653910 1.193132 0.725831 0.238418 1.753114 1.296242 0.838033 0.349570 1.877468 1.384694 0.938419 0.481820 0.045217 1.557648 1.099375 0.609911 0.138825 1.670480 1.217161 0.761162 0.340569 1.849982 1.398484 0.929634 0.476983 0.033188 1.587225 1.150229 0.660516 0.218545 1.773455 1.321194 0.875537 0.412455 1.975569 1.556914 1.085507 0.655478 0.222974 1.781550 1.346518 0.898635 0.461489 0.030688 1.577108 1.128616 0.706201 0.284734 1.848941 1.423074 1.012127 0.550319 0.127044 1.684664 1.271718 0.847352 0.414193 1.990134 1.521095 1.136567 0.750291 0.337126 1.862249 1.460431 1.049297 0.669842 0.216907 1.819953 1.412426 0.984992 0.572590 0.137306 1.767447 1.330047 0.905950 0.512494 0.103808 1.706053 1.292143 0.937524 0.519078 0.097820 1.712597 1.292745 0.903437 0.500926 0.107737 1.719337 1.308083 0.905177 0.496968 0.133013 1.759477 1.355972 0.957870 0.560591 0.197890 1.801611 1.398075 1.020267 0.618113 0.240199 1.874548 1.486894 1.113092 0.726528 0.377432 1.957833 1.606621 1.229674 0.862702 0.506555 0.105441 1.735997 1.326469 0.994534 0.620808 0.244606 1.879074 1.511642 1.143326 0.775799 0.401368 0.075791 1.702891 1.377919 1.004500 0.619170 0.276148 1.905577 1.568310 1.206071 0.869241 0.512412 0.122276 1.822305 1.441374 1.069500 0.718082 0.389240 0.063602 1.687756 1.378724 0.999805 0.650714 0.332978 1.980285 1.636670 1.301261 0.946200 0.636798 0.314748 1.971775 1.637355 1.287360 0.964448 0.629994 0.298934 1.960682 1.641690 1.343792 1.003153 0.675512 0.317256 0.019972 1.693194 1.366188 1.021532 0.736417 0.404438 0.047067 1.755472 1.430810 1.127679 0.827156 0.504993 0.204999 1.869602 1.559982 1.266750 0.972466 0.612460 0.337579 0.023582 1.728936 1.434699 1.106015 0.784009 0.538390 0.203285 1.928266 1.597064 1.317846 1.015077 0.718614 0.443946 0.127570 1.807078 1.525053 1.247182 0.954079 0.675954 0.383769 0.077633 1.801620 1.532606 1.255462 0.983867 0.644793 0.353207 0.086592 1.828378 1.554513 1.293246 0.994370 0.712475 0.454107 0.144932 1.895728 1.591466 1.368095 1.085410 0.814684 0.542596 0.266934 0.005277 1.745816 1.477185 1.204917 0.948437 0.678999 0.410227 0.182102 1.882179 1.612229 1.401104 1.147230 0.888055 0.606492 0.343709 0.087358 1.853764 1.632545 1.312124 1.126022 0.888426 0.609422 0.346571 0.088432 1.864069 1.624618 1.413636 1.129791 0.907899 0.664305 0.453125 0.192741 1.939732 1.724665 1.446730 1.208735 1.009088 0.791036 0.553547 0.269865 0.050008 1.869993 1.607891 1.398702 1.178112 0.955620 0.721846 0.505763 0.260159 0.071405 1.830854 1.568352 1.366891 1.174316 0.942949 0.745228 0.526140 0.332456 0.118352 1.885916 1.701433 1.472261 1.239299 1.044248 0.831700 0.625882 0.454237 0.215857 0.017252 1.819254 1.615407 1.449492 1.196228 0.982253 0.820818 0.604584 0.442977 0.216483 0.024304 1.829511 1.646493 1.443177 1.275320 1.091080 0.881819 0.729119 0.498708 0.327643 0.166437 1.958363 1.799653 1.588527 1.414994 1.260561 1.019025 0.883661 0.702271 0.505868 0.333038 0.161804 1.992906 1.833629 1.635304 1.475105 1.312466 1.145459 0.986121 0.827858 0.611131 0.477466 0.312332 0.162403 1.993033 1.816815 1.647505 1.499793 1.348955 1.165690 1.035882 0.893667 0.723295 0.585232 0.422874 0.271934 0.113531 1.952972 1.802172 1.650708 1.483461 1.343486 1.218552 1.084842 0.927073 0.776245 0.635502 0.458305 0.373982 0.258566 0.082490 1.916515 1.785127 1.662029 1.542014 1.401296 1.288328 1.126154 1.007559 0.889400 0.744625 0.632843 0.508419 0.378037 0.200669 0.085018 0.008202 1.848031 1.734169 1.614621 1.493930 1.370837 1.302166 1.164868 1.024290 0.930883 0.834625 0.701624 0.606512 0.466962 0.388720 0.279406 0.140918 0.032687 1.927348 1.811775 1.710266 1.620460 1.492805 1.381998 1.317908 1.197423 1.122147 0.998133 0.894736 0.822100 0.734668 0.601331 0.525309 0.427892 0.326892 0.282159 0.156951 0.069505 1.983007 1.895744 1.832368 1.741307 1.671465 1.579508 1.479397 1.407456 1.341307 1.292493 1.172022 1.054844 1.025425 0.938514 0.866058 0.788578 0.719667 0.627909 0.568933 0.499665 0.417215 0.362650 0.295768 0.225056 0.146637 0.113130 0.045846 1.971304 1.915101 1.840250 1.815002 1.742119 1.655607 1.609235 1.549662 1.484722 1.419617 1.408714 1.318908 1.280672 1.236078 1.178979 1.119651 1.066519 1.044417 1.008080 0.950081 0.924323 0.862134 0.835117 0.809024 0.773528 0.699906 0.685111 0.616527 0.592797 0.532897 0.500140 0.456585 0.437938 0.409107 0.390095 0.358332 0.312446 0.308676 0.240543 0.209907 0.216831 0.210411 0.161769 0.125653 0.125949 0.116670 0.080163 0.075626 0.045297 0.004806 -0.000881 0.026299 1.965793 1.933605 1.942786 1.944348 1.952614 1.952589 1.927103 1.902751 1.909232 1.908039 1.900517 1.879669 1.891581 1.879298 1.891872 1.877416 1.870643 1.886309 1.944953 1.916353 1.939154 1.880988 1.904419 1.908941 1.910254 1.932089 1.969282 1.952058 1.945000 1.980171 0.011419 0.039090 0.041500 0.047816 0.085029 0.081559 0.110170 0.137541 0.124670 0.182784 0.191545 0.201628 0.268114 0.278620 0.284381 0.311542 0.326223 0.361901 0.375616 0.463339 0.474532 0.486778 0.532068 0.571238 0.610468 0.633708 0.681958 0.718256 0.773051 0.824140 0.873293 0.876610 0.910965 0.966901 1.003523 1.070562 1.122780 1.175620 1.208791 1.265780 1.302068 1.370182 1.451044 1.483311 1.520585 1.580432 1.644102 1.730843 1.770789 1.797830 1.879017 1.937891 0.019856 0.060042 0.124553 0.170564 0.216811 0.336571 0.366439 0.419283 0.547803 0.615076 0.686756 0.743054 0.808192 0.868812 0.967965 1.030425 1.105495 1.195851 1.276820 1.343432 1.439087 1.529664 1.600300 1.698173 1.760479 1.837558 1.924128 0.038094 0.120241 0.214007 0.317951 0.407855 0.504676 0.570855 0.654240 0.764928 0.855805 0.954502 1.051709 1.155105 1.262197 1.344793 1.435407 1.543123 1.670772 1.770468 1.865799 1.988288 0.099499 0.209570 0.297997 0.416558 0.512994 0.646099 0.763826 0.829292 0.972586 1.100975 1.192463 1.318284 1.435661 1.552010 1.667446 1.796953 1.895828 0.041405 0.168834 0.302036 0.399196 0.525607 0.643567 0.817912 0.935908 1.049011 1.178889 1.349363 1.470533 1.565826 1.734269 1.896736 0.005501 0.133187 0.267100 0.426661 0.580310 0.701157 0.855104 0.989792 1.134964 1.281741 1.433081 1.557022 1.743754 1.844434 0.034007 0.156833 0.323091 0.480395 0.650146 0.794963 0.940476 1.107393 1.252731 1.423226 1.591762 1.737804 1.887833 0.066146 0.199816 0.395900 0.573298 0.691305 0.879701 1.072741 1.236826 1.402627 1.563880 1.718916 1.915062 0.045140 0.237581 0.438738 0.580798 0.784617 0.966030 1.127512 1.284041 1.500016 1.652029 1.856424 0.063337 0.220388 0.388642 0.607545 0.805909 0.974538 1.152853 1.362173 1.532955 1.747946 1.927504 0.137055 0.324156 0.511474 0.727234 0.929245 1.096943 1.311277 1.529510 1.717204 1.929354 0.136096 0.316537 0.493748 0.725549 0.936978 1.151687 1.364715 1.550641 1.788754 1.967369 0.214151 0.411319 0.596806 0.843522 1.075423 1.273303 1.508848 1.709102 1.926626 0.164669 0.367063 0.581444 0.843645 1.064477 1.297447 1.488808 1.750805 1.965800 0.201438 0.416395 0.646546 0.890452 1.084015 1.348861 1.594443 1.818075 0.050802 0.296115 0.523258 0.792692 1.017642 1.273538 1.482331 1.728422 1.963843 0.219496 0.485923 0.690905 0.954474 1.220165 1.432291 1.730053 1.984033 0.222784 0.506499 0.721622 1.020753 1.264124 1.484071 1.737442 0.008877 0.293763 0.536176 0.800572 1.062039 1.344801 1.603165 1.888281 0.130074 0.414558 0.656092 0.938783 1.204182 1.472600 1.715585 0.025355 0.292603 0.583538 0.845516 1.127921 1.372150 1.695546 1.966468 0.221543 0.530377 0.793558 1.098411 1.356632 1.654543 1.955535 0.215710 0.523709 0.795967 1.100511 1.400246 1.690427 1.972022 0.266207 0.566998 0.873330 1.145759 1.473687 1.732502 0.041309 0.361298 0.681781 0.985976 1.233662 1.568222 1.842062 0.150190 0.511624 0.781348 1.087933 1.430677 1.711532 0.035866 0.350229 0.682226 0.921244 1.280371 1.577240 1.931037 0.233182 0.556380 0.877749 1.201053 1.529754 1.819573 0.176157 0.513656 0.816790 1.153452 1.451900 1.807514 0.113756 0.472986 0.806765 1.112493 1.445282 1.798965 0.093781 0.440000 0.772831 1.149981 1.498818 1.820883 0.161426 0.511652 0.813634 1.170367 1.539558 1.880179 0.197605 0.545597 0.908196 1.248869 1.624027 1.993151 0.291418 0.679658 1.035077 1.372909 1.711740 0.072351 0.454139 0.769060 1.133182 1.524037 1.903171 0.230092 0.617044 0.952001 1.338296 1.713107 0.075994 0.443935 0.779891 1.161968 1.532485 1.934216 0.232916 0.643695 1.033693 1.388978 1.763418 0.158282 0.531564 0.923030 1.280607 1.680049 0.033058 0.432091 0.830342 1.225022 1.574525 1.980673 0.372020 0.765894 1.154297 1.543700 1.929241 0.336874 0.704501 1.078420 1.502864 1.874394 0.278411 0.673779 1.082558 1.485362 1.892655 0.272103 0.679143 1.126508 1.483018 1.858194 0.311886 0.706336 1.119689 1.515117 1.930234 0.352607 0.728958 1.180615 1.582674 -0.011458 0.382422 0.817149 1.225669 1.663555 0.072122 0.522136 0.931979 1.334156 1.759365 0.194206 0.619361 1.047129 1.473102 1.908252 0.351516 0.772083 1.179926 1.644483 0.044574 0.475749 0.917446 1.334503 1.758597 0.228962 0.656066 1.131261 1.531736 1.952420 0.415411 0.858312 1.294649 1.758848 0.189426 0.612886 1.083380 1.497505 1.985693 0.443336 0.886511 1.331150 1.813863 0.233070 0.676790 1.130099 1.603581 0.055302 0.540261 0.998997 1.449019 1.920455 0.358725 0.844856 1.264985 1.778111 0.235398 0.686816 1.158649 1.610447 0.090461 0.550418 1.066038 1.507364 1.994625 0.420151 0.944881 1.409278 1.887639 0.359391 0.848416 1.314772 1.770668 0.248792 0.760921 1.244402 1.756852 0.252652 0.703484 1.163404 1.654408 0.164679 0.655036 1.142941 1.625021 0.133904 0.622543 1.126263 1.630291 0.123546 0.625620 1.093073 1.619368 0.102469 0.606535 1.087101 1.587765 0.099897 0.628994 1.136702 1.620371 0.161959 0.636159 1.142893 1.681191 0.151857 0.677434 1.211596 1.703772 0.227926 0.771686 1.266146 1.802804 0.317100 0.816843 1.330334 1.861595 0.386103 0.907612 1.408022 1.955543 0.472098 0.989797 1.544380 0.060134 0.607569 1.120958 1.622179 0.202636 0.754702 1.259644 1.800413 0.355305 0.852467 1.427250 1.936931 0.476054 1.030783 1.560498 0.106947 0.646657 1.237864 1.760957 0.297533 0.839061 1.392090 1.981467 0.509204 1.041723 1.622010 0.107363 0.685230 1.282738 1.821548 0.392932 0.943170 1.514801 0.035058 0.608491 1.175191 1.746330 0.299139 0.879938 1.445070 -0.001787 0.554868 1.132782 1.683410 0.273212 0.846311 1.408423 0.003830 0.577097 1.115510 1.694824 0.296676 0.868917 1.443750 0.022513 0.593863 1.183583 1.773899 0.348573 0.938190 1.535508 0.069825 0.715089 1.266797 1.883415 0.452363 1.042844 1.630007 0.194710 0.822770 1.421686 0.006472 0.621176 1.225177 1.804178 0.408934 1.002193 1.614950 0.209691 0.797600 1.413215 0.043022 0.605270 1.230426 1.842139 0.430016 1.071181 1.656314 0.292321 0.899593 1.524578 0.123367 0.722937 1.338216 1.965637 0.591781 1.216201 1.814694 0.429343 1.061910 1.690552 0.337918 0.935448 1.583594 0.173086 0.798338 1.428447 0.077432 0.684896 1.325474 1.963397 0.593516 1.253180 1.853700 0.531347 1.151683 1.746520 0.425377 1.027823 1.699093 0.333177 0.972850 1.609902 0.254362 0.906653 1.526954 0.225847 0.835769 1.466855 0.149601 0.794755 1.472543 0.118131 0.734656 1.404030 0.060242 0.727045 1.340500 0.029564 0.718625 1.343988 -0.004346 0.685714 1.342591 1.966238 0.667503 1.349852 -0.002971 0.703210 1.357155 0.009465 0.670856 1.356398 0.013330 0.698167 1.342918 0.045357 0.716155 1.383634 0.066321 0.749850 1.425646 0.130825 0.789828 1.468799 0.124200 0.833100 1.513466 0.184968 0.911501 1.594174 0.253162 0.976866 1.658160 0.318972 1.008058 1.691692 0.429447 1.114864 1.830218 0.507740 1.192600 1.907363 0.627089 1.308050 -0.023869 0.692513 1.415262 0.119283 0.836039 1.521751 0.244980 0.952758 1.642834 0.365258 1.090581 1.783116 0.502517 1.253315 1.907048 0.640444 1.381762 0.084253 0.818390 1.500682 0.258511 0.959052 1.666093 0.436675 1.168622 1.860895 0.574076 1.283511 0.009657 0.798719 1.538205 0.214051 0.952450 1.698753 0.447784 1.186388 1.858247 0.626974 1.347987 0.102119 0.855522 1.567443 0.343708 1.048347 1.808415 0.563378 1.317260 0.037027 0.798248 1.543255 0.284540 1.038822 1.782415 0.536310 1.274786 0.033989 0.801778 1.518276 0.287239 1.093224 1.832048 0.574059 1.361341 0.088951 0.857131 1.626231 0.399419 1.160410 1.908691 0.691937 1.400996 0.198198 1.010876 1.783108 0.552378 1.321187 0.069810 0.822885 1.649640 0.398546 1.161881 1.992740 0.718709 1.494106 0.274327 1.069239 1.874949 0.654740 1.412139 0.213263 1.030112 1.748596 0.568168 1.374868 0.155842 0.909714 1.739498 0.532008 1.295260 0.100142 0.892104 1.684374 0.494276 1.299126 0.082168 0.868839 1.674733 0.523178 1.308308 0.060301 0.901403 1.723633 0.527144 1.315281 0.095071 0.928769 1.769688 0.546110 1.365559 0.165197 0.991664 1.800022 0.649448 1.439023 0.280113 1.099551 1.892902 0.728472 1.558461 0.355122 1.155267 0.036651 0.803555 1.642245 0.486101 1.329471 0.153373 0.982109 1.814973 0.657477 1.472081 0.306013 1.138804 1.982639 0.806632 1.637032 0.492622 1.340692 0.166678 0.988021 1.860739 0.705110 1.541783 0.378007 1.213916 0.031456 0.923334 1.732364 0.624150 1.479737 0.314949 1.150499 0.017070 0.859860 1.709562 0.576208 1.451144 0.288172 1.156845 0.018462 0.888828 1.738856 0.600882 1.451392 0.305358 1.162471 0.071454 0.893471 1.790525 0.655173 1.527197 0.387534 1.299810 0.149548 1.016876 1.901076 0.773925 1.669962 0.533885 1.422131 0.264889 1.162826 0.053904 0.925273 1.783822 0.699297 1.593338 0.446127 1.329094 0.254005 1.148241 0.039106 0.936392 1.775754 0.686922 1.585294 0.459409 1.358560 0.246673 1.169932 0.062721 0.983726 1.860184 0.765327 1.652246 0.576169 1.499099 0.384989 1.260554 0.200648 1.126723 -0.014215 0.905397 1.801886 0.753345 1.641865 0.558767 1.467752 0.368838 1.294027 0.198410 1.090981 0.052952 0.991699 1.874409 0.806543 1.749760 0.655559 1.568484 0.520862 1.412201 0.366118 1.291778 0.238178 1.186893 0.061166 0.989290 1.973099 0.910404 1.832384 0.729437 1.723776 0.611997 1.559408 0.503451 1.415081 0.384261 1.301727 0.266130 1.222404 0.110539 1.064083 0.035684 0.943491 1.931964 0.862767 1.795698 0.762421 1.744397 0.666272 1.629091 0.597084 1.552001 0.500765 1.485981 0.446479 1.384691 0.357775 1.317093 0.302197 1.238922 0.194762 1.180556 0.151639 1.104156 0.074275 1.063876 0.008701 0.973523 1.931938 0.929619 1.899785 0.841696 1.876181 0.845013 1.791292 0.775116 1.753572 0.692830 1.726733 0.701663 1.665288 0.631802 1.649201 0.617241 1.594365 0.594942 1.588591 0.590950 1.543461 0.545092 1.544258 0.510400 1.542625 0.487864 1.489414 0.513606 1.491923 0.493471 1.497027 0.496715 1.533646 0.485406 1.488094 0.496820 1.543844 0.524720 1.515833 0.565220 1.558524 0.600489 1.612307 0.598486 1.630142 0.583528 1.626331 0.601297 1.642574 0.701670 1.674391 0.711291 1.729818 0.761143 1.763746 0.824000 1.826874 0.860664 1.866172 0.942874 1.940443 0.980274 -0.790948 1.041163 0.048939 1.113624 0.095128 1.190982 0.189672 1.265115 0.274570 1.325492 0.374151 1.447798) ) )) ;; :odd 65536 (311.51645615075 1.5666759234657 2.0944106499714) 0.51769778542275 (100) ;;; ---------------------------------------- prime-numbered harmonics (and 1st) ---------------------------------------- (define primoid-min-peak-phases (vector (vector 1 1.0 (fv 0) ) (vector 2 1.76 (fv 0 1) ) ;;; 3 prime -------------------------------------------------------------------------------- (vector 3 2.1949384212494 (fv 0 0 1) 1.980 (fv 0 62/39 13/41) ; 1 2 3 -- same as :all in this case 1.9798574987316 (fv 0.0 1.5896952797511 0.31654707828801) 1.9798030853271 (fv 0.0 1.5897271633148 0.31667485833168) ) ;;; 4 prime -------------------------------------------------------------------------------- (vector 4 2.5978584289551 (fv 0 0 1 1) ;2.2039985204158 (fv 0 0 12 4) / 20 2.1930510997772 (fv 0.000 0.996 0.596 0.217) 2.1930510997772 (fv 0.000 1.996 0.596 0.217) 2.1930510997772 (fv 0.000 0.004 1.404 1.783) 2.1927945613861 (fv 0.0 1.0065363103693 1.4072853370949 1.7873527125308) 2.1921416218407 (fv 0.0 1.0052774357064 1.4058145325161 1.7854903085184) 2.1921210289001 (fv 0.0 1.0052587985992 1.4057868719101 1.7854607105255) ) ;;; 5 prime -------------------------------------------------------------------------------- (vector 5 2.7172040939331 (fv 0 0 1 0 0) 2.476848 (fv 0.000000 1.577434 0.385232 1.294742 1.022952) 2.476837 (fv 0.000000 0.422530 1.614642 0.705077 0.976763) ) ;;; 6 prime -------------------------------------------------------------------------------- (vector 6 3.1241359710693 (fv 0 0 0 1 0 0) 2.805574 (fv 0.000000 1.568945 0.034019 1.082417 0.900415 0.797509) 2.805492 (fv 0.000000 0.431060 -0.033992 0.917551 1.099550 1.202470) 2.805413 (fv 0.000000 0.431110 -0.033974 0.917615 1.099635 1.202594) ) ;;; 7 prime -------------------------------------------------------------------------------- (vector 7 3.4886319637299 (fv 0 1 1 0 0 0 0) 3.061861 (fv 0.000000 0.715739 0.261422 0.169339 0.062479 1.180650 0.330190) 3.061763 (fv 0.000000 0.715523 0.261251 0.168577 0.061828 1.179155 0.328665) ) ;;; 8 prime -------------------------------------------------------------------------------- (vector 8 3.7088720798492 (fv 0 0 0 0 0 0 1 0) 3.263115 (fv 0.000000 0.207652 0.035023 1.752163 0.064249 0.346105 1.403170 0.065734) 3.262977 (fv 0.000000 0.792550 1.965637 0.248661 1.936840 1.655647 0.598935 1.936915) 3.262789 (fv 0.000000 0.792261 1.965087 0.247823 1.935907 1.654053 0.597010 1.934463) ) ;;; 9 prime -------------------------------------------------------------------------------- (vector 9 3.9154822826385 (fv 0 0 0 1 1 1 0 0 0) 3.382645 (fv 0.000000 0.562589 0.520940 1.521127 1.682374 0.721497 0.805534 1.254209 0.726847) 3.382399 (fv 0.000000 1.437745 1.479554 0.480268 0.319088 1.280870 1.197460 0.749784 1.277141) 3.382150 (fv 0.000000 1.437471 1.479039 0.479171 0.317977 1.279012 1.195104 0.746644 1.274032) ) ;;; 10 prime -------------------------------------------------------------------------------- (vector 10 4.1209712028503 (fv 0 0 1 0 0 0 1 0 0 0) 3.602602 (fv 0.000000 1.405079 0.694565 0.388252 0.756491 1.849937 0.076683 1.023761 0.374165 1.226329) 3.602329 (fv 0.000000 0.594431 1.305346 1.611464 1.243212 0.149889 1.922392 0.975619 1.625276 0.772405) 3.601897 (fv 0.000000 0.594605 1.305309 1.611462 1.242927 0.149405 1.922318 0.974872 1.624292 0.771826) ) ;;; 11 prime -------------------------------------------------------------------------------- (vector 11 4.4176635742188 (fv 0 0 1 0 0 0 0 0 0 1 0) 3.779046 (fv 0.000000 0.211414 1.453486 1.827574 1.811694 1.949216 1.313595 0.823256 1.334141 0.127849 0.824659) 3.778444 (fv 0.000000 0.211392 1.453207 1.827566 1.811268 1.948666 1.312975 0.822389 1.333108 0.126706 0.823083) ) ;;; 12 prime -------------------------------------------------------------------------------- (vector 12 4.3595271110535 (fv 0 0 0 0 0 0 1 0 1 1 0 1) 3.936657 (fv 0.000000 0.367346 0.997085 1.763425 1.295636 0.140826 0.757652 1.565853 1.284651 0.304758 0.331248 0.325474) 3.936584 (fv 0.000000 0.366730 0.995852 1.762390 1.293763 0.137304 0.753397 1.560313 1.278944 0.297723 0.322472 0.315856) 3.935928 (fv 0.000000 0.367095 0.996695 1.763345 1.295131 0.139476 0.755820 1.563961 1.282494 0.302360 0.327995 0.321982) ) ;;; 13 prime -------------------------------------------------------------------------------- (vector 13 4.8980793952942 (fv 0 0 0 1 0 0 1 1 1 1 1 1 0) 4.155503 (fv 0.000000 1.115751 0.463368 0.110540 0.613302 1.581997 1.394002 -0.005270 1.724217 0.023531 1.743892 0.616897 0.124222) 4.155104 (fv 0.000000 0.888606 1.516761 -0.128988 1.376524 0.383262 0.572385 -0.041726 0.228441 1.918487 0.187862 1.304384 1.779710) 4.154486 (fv 0.000000 0.888925 1.516611 -0.128449 1.377349 0.383874 0.573640 -0.040502 0.230047 1.920090 0.190320 1.307111 1.782269) ) ;;; 14 prime -------------------------------------------------------------------------------- (vector 14 4.827317237854 (fv 0 0 0 0 1 0 0 0 0 1 1 0 0 0) 4.325356 (fv 0.000000 0.359558 1.885647 0.244632 1.221244 1.839379 1.316045 0.525308 0.483244 1.183590 1.084986 0.271051 0.780356 0.855105) 4.324364 (fv 0.000000 0.359123 1.885242 0.244967 1.221612 1.840358 1.317076 0.526663 0.485486 1.185929 1.087828 0.273652 0.783599 0.859686) ) ;;; 15 prime -------------------------------------------------------------------------------- (vector 15 5.116711139679 (fv 0 0 0 0 1 1 0 0 1 0 0 0 1 1 1) 4.467959 (fv 0.000000 1.165302 0.822381 1.719844 1.177673 0.000074 -0.047034 0.249259 0.174863 0.272306 -0.034377 1.204925 0.800910 1.798882 0.085175) 4.465870 #(0.000000 1.195783 0.875671 1.808021 1.309702 0.184662 0.170474 0.531131 0.521153 0.683109 0.474077 -0.194026 1.432983 0.523484 0.889349) ) ;;; 16 prime -------------------------------------------------------------------------------- (vector 16 5.2015118598938 (fv 0 0 0 0 1 1 0 0 1 0 0 0 1 1 1 1) 4.602505 (fv 0.000000 0.065822 0.364277 0.133567 0.202441 1.541212 1.225002 0.832999 1.687176 1.503245 1.015565 1.715739 1.103351 1.602678 1.102870 1.723542) 4.600306 #(0.000000 0.087862 0.378855 0.177701 0.258884 1.624830 1.330220 0.960734 1.836164 1.680878 1.236729 1.958382 1.391766 1.922763 1.425076 0.083217) ) ;;; 17 prime -------------------------------------------------------------------------------- (vector 17 5.5318970680237 (fv 0 0 1 1 1 1 0 0 0 0 1 0 0 1 1 0 1) 4.719141 (fv 0.000000 0.742295 1.745265 1.857635 0.393094 0.085265 0.379253 1.692020 1.022244 0.008090 1.067230 1.241546 0.650781 0.027258 1.334059 1.354939 0.974983) 4.718649 #(0.000000 0.751159 1.770960 1.891296 0.451714 0.167219 0.486669 1.820262 1.171314 0.188288 1.302438 1.491326 0.945450 0.342701 1.668608 1.730493 1.394926) ) ;;; 18 prime -------------------------------------------------------------------------------- (vector 18 5.518 (fv 0 0 1 0 1 1 1 1 0 0 0 0 1 0 0 0 0 0) 4.855354 (fv 0.000000 0.761212 1.399765 1.386893 -0.022155 1.259519 0.806762 0.461717 0.840663 0.867450 0.860949 1.743030 1.407070 0.651538 1.045391 1.279111 0.110257 1.307989) 4.855108 #(0.000000 0.750207 1.384561 1.357598 -0.059069 1.202337 0.735689 0.367843 0.732570 0.743255 0.704408 1.570924 1.212329 0.426050 0.813634 1.013534 -0.181098 0.979190) ) ;;; 19 prime -------------------------------------------------------------------------------- (vector 19 5.7069295560724 (fv 0 1 1 0 1 1 0 1 0 1 1 1 0 1 0 0 0 1 1) 5.015020 (fv 0.000000 1.616061 1.626145 1.313686 1.626275 1.187207 1.456980 0.377509 -0.071549 0.474989 0.997350 1.285450 0.372950 1.499943 0.593785 0.033723 1.161466 0.319734 1.064282) 4.998754 #(0.000000 1.645363 1.697584 1.402853 1.761967 1.410480 1.731078 0.730841 0.373575 0.971264 1.632848 -0.032567 1.185342 0.399132 1.548900 1.042245 0.314528 1.610838 0.400814) ) ;;; 20 prime -------------------------------------------------------------------------------- (vector 20 5.8879864574703 (fv 0 0 1 0 0 0 0 0 1 1 0 1 1 1 1 0 1 1 1 1) 5.188618 (fv 0.000000 1.304708 0.831211 0.731788 0.021326 1.272273 1.777479 0.002778 1.612017 0.397413 0.057603 1.250739 0.234023 0.556087 0.011742 0.753589 1.624826 0.625035 1.017719 0.079500) 5.182566 #(0.000000 1.263246 0.762194 0.608532 -0.162633 0.980718 1.431801 -0.440489 1.122128 -0.196813 -0.666076 0.455149 -0.710850 -0.505486 -1.097448 -0.446751 0.276095 -0.871587 -0.537639 -1.622748) ) ;;; 21 prime -------------------------------------------------------------------------------- (vector 21 6.1138607493652 (fv 0 0 1 0 0 1 0 0 0 0 1 1 1 0 1 0 1 0 0 1 0) 5.324980 (fv 0.000000 0.284388 0.190620 0.601870 1.760108 0.865412 0.509624 0.391482 -0.117180 0.413220 1.669494 1.501699 0.066514 0.632948 0.866546 1.073191 0.975355 1.318609 0.054208 1.081180 1.759607) 5.323612 #(0.000000 0.280854 0.184723 0.594540 1.747745 0.845155 0.483640 0.360116 -0.153262 0.371609 1.613941 1.441516 -0.006745 0.553330 0.784905 0.983522 0.871481 1.204293 -0.066217 0.952578 1.624372) ) ;;; 22 prime -------------------------------------------------------------------------------- (vector 22 6.3374844973589 (fv 0 0 1 1 1 0 1 0 1 1 0 1 0 1 0 0 1 0 0 0 0 0) 5.444390 (fv 0.000000 1.499825 1.282805 1.145752 0.718322 0.527629 0.660515 1.924701 0.466877 0.510672 0.652853 0.187109 1.099971 0.084112 0.857217 -0.068874 1.056229 1.751779 1.460546 0.258516 0.957206 1.594508) 5.433554 #(0.000000 1.486514 1.390599 1.149545 0.921462 0.702749 0.884951 0.283286 0.900936 0.913025 1.182081 0.780309 1.832213 0.822636 1.714820 0.783014 0.057705 0.842269 0.698584 1.561603 0.224265 0.995298) ) ;;; 23 prime -------------------------------------------------------------------------------- (vector 23 6.5309901747782 (fv 0 0 1 0 0 1 1 1 0 0 0 0 1 1 0 1 1 0 1 1 1 1 1) 5.563562 (fv 0.000000 0.281094 0.583074 0.221311 1.169287 1.340406 0.217839 0.992042 0.637288 1.632696 0.471670 0.404966 0.171954 0.469626 0.291125 0.731904 1.276906 1.527897 0.612764 0.143351 1.082353 1.486999 1.452340) 5.562290 #(0.000000 0.285874 0.595224 0.235000 1.193968 1.380397 0.263651 1.051885 0.699527 1.708311 0.571007 0.512971 0.292952 0.607887 0.434888 0.887469 1.457277 1.731817 0.825388 0.371687 1.321790 1.739434 1.728651) ) ;;; 24 prime -------------------------------------------------------------------------------- (vector 24 6.5623834870329 (fv 0 0 1 1 0 0 0 0 0 1 0 1 1 1 0 0 1 0 1 1 0 0 0 0) 5.645656 (fv 0.000000 0.825211 1.870903 1.169702 1.224751 0.476917 -0.084281 -0.215343 1.779853 1.403261 0.289331 1.689966 -0.267939 1.131483 1.839470 1.455399 1.365050 0.422908 0.906355 0.161003 0.266551 0.763039 1.248766 1.436520) 5.642196 #(0.000000 0.890373 -0.094314 1.286595 1.344700 0.673123 0.114259 0.064347 0.093887 1.778664 0.785400 0.193244 0.317478 1.782787 0.521724 0.200559 0.236076 1.409678 1.913185 1.269474 1.450265 -0.052106 0.501351 0.830713) ) ;;; 25 prime -------------------------------------------------------------------------------- (vector 25 6.635721206665 (fv 0 0 1 0 0 1 1 0 1 1 0 0 1 0 0 0 1 1 1 1 1 0 0 1 1) 5.810785 (fv 0.000000 0.563705 1.200194 1.330185 1.448503 0.304746 -0.097873 1.178970 1.307797 0.187993 1.570595 0.364607 -0.021932 1.552639 -0.223928 1.041142 1.388107 1.015775 1.883861 0.551891 1.621094 0.871585 1.482986 0.450455 0.538066) ) ;;; 26 prime -------------------------------------------------------------------------------- (vector 26 6.8401503562927 (fv 0 1 0 0 0 1 0 0 1 1 0 1 1 1 1 0 0 0 1 0 1 0 1 0 0 1) 6.060342 (fv 0.000000 -0.041165 -0.003731 0.423811 0.999953 0.846414 -0.006772 1.678875 0.280560 0.164498 1.427575 0.432370 0.295956 0.293617 -0.083444 1.838911 -0.050243 0.444002 1.425675 0.812741 0.728420 0.505166 0.737245 1.256666 1.911599 0.384822) 6.058136 #(0.000000 -0.021770 0.018901 0.439476 1.003477 0.859441 0.019351 1.721839 0.345805 0.234535 1.519443 0.503441 0.356442 0.416885 0.030839 -0.020167 0.056498 0.603049 1.590340 0.966971 0.922202 0.689424 0.952624 1.488151 0.129980 0.653028) 6.056645 #(0.000000 -0.016558 0.026579 0.448353 1.015651 0.876809 0.043994 1.754158 0.381360 0.275434 1.572444 0.558006 0.419413 0.493841 0.110178 0.066677 0.147843 0.710739 1.703199 1.084656 1.051087 0.819777 1.096976 1.639534 0.286953 0.830565) ;; 25+1 6.122073 (fv 0.000000 0.460498 1.557923 1.378525 1.718931 0.447198 0.063372 0.871474 1.497987 0.124645 1.393742 0.468348 -0.079259 1.274284 -0.437034 1.081613 1.726707 1.093435 1.712067 0.466467 1.547007 0.967081 1.258363 0.304978 0.430183 0.007813) ;; 27-1 6.163135 (fv 0.000000 0.728435 -0.162948 -0.044439 -0.171766 1.094395 0.029113 0.072422 1.082217 0.879605 -0.111434 1.156162 1.018106 0.872058 0.997367 0.178509 -0.068227 -0.141285 1.119460 -0.213041 0.834585 -0.226205 0.775314 -0.211931 0.098174 0.839934) ;; 24+2 6.157978 (fv 0.000000 0.747592 -0.138036 -0.096812 -0.252632 1.140904 0.038566 0.088301 1.237633 1.010838 0.001393 0.982309 1.045743 0.842207 0.970725 0.281016 0.130720 0.128208 1.180011 0.026054 0.957275 -0.052702 1.071527 -0.026637 0.338920 1.156596) ) ;;; 27 prime -------------------------------------------------------------------------------- (vector 27 6.9491486549377 (fv 0 1 0 0 0 0 0 0 1 0 1 0 0 0 1 1 0 1 0 1 1 1 0 1 1 0 1) 6.133994 (fv 0.000000 1.619323 0.268498 0.605329 0.261788 1.741906 1.690385 1.044397 0.095253 1.526766 0.682732 1.844188 1.227922 -0.046848 0.854154 -0.053734 1.525611 0.460071 0.230079 1.191101 1.252287 1.704028 -0.029667 1.798141 1.802482 1.571525 0.379519) ) ;;; 28 prime -------------------------------------------------------------------------------- (vector 28 7.1576952934265 (fv 0 1 1 0 1 1 1 1 0 1 1 1 0 0 1 0 1 1 0 0 1 1 0 1 1 1 0 0) 6.190947 (fv 0.000000 0.460822 1.000235 0.802902 1.169351 0.023696 1.059034 0.557253 0.339303 -0.037893 0.757652 1.745281 0.808299 1.572816 1.228654 0.154747 0.925847 0.957314 0.565556 0.484885 0.864794 1.110639 0.659146 1.596331 1.587743 0.524304 1.470688 0.086831) ) ;;; 29 prime -------------------------------------------------------------------------------- (vector 29 7.2415904369233 (fv 0 0 1 1 1 0 0 1 0 0 0 0 0 0 1 1 1 1 0 1 0 1 1 0 1 1 1 1 0) 6.364996 (fv 0.000000 0.899299 0.027883 1.660781 0.583908 0.594226 1.394105 1.009420 -0.076432 0.063436 1.779221 1.537249 1.002516 1.590894 -0.057219 1.023692 1.515341 1.279493 0.140022 -0.035094 0.723643 0.484040 0.612756 1.373872 1.209603 1.304864 0.985337 0.845953 0.581252) ) ;;; 30 prime -------------------------------------------------------------------------------- (vector 30 7.1189651489258 (fv 0 0 1 1 1 0 1 1 0 0 1 1 0 1 0 1 1 1 1 0 0 0 0 0 0 1 0 0 1 0) 6.451812 (fv 0.000000 1.683608 0.803658 0.933316 0.850814 1.701341 1.277986 1.473972 1.214431 1.898492 0.954836 1.784293 1.951482 1.381903 0.107238 0.105553 1.260609 1.566570 0.409971 0.385253 1.590967 0.968660 0.054889 0.914665 1.664915 1.656054 1.094096 1.343614 0.650979 0.864222) ) ;;; 31 prime -------------------------------------------------------------------------------- (vector 31 7.4906754493713 (fv 0 0 1 0 1 1 1 1 1 0 0 0 1 1 1 0 1 1 1 0 1 1 0 1 1 1 0 1 0 1 1) 6.701515 (fv 0.000000 0.707031 0.658082 0.778665 1.395076 0.565253 0.395956 1.065744 1.710897 0.801620 1.512714 1.121124 1.688469 1.338401 0.622466 1.725968 1.295045 0.892738 0.244280 0.958065 0.828867 0.800413 0.064995 1.349330 1.878947 0.861664 0.695097 1.073201 0.907698 1.910585 0.416756) ;; 30+1 6.615976 (fv 0.000000 1.619082 0.923169 1.083084 0.781957 1.611725 1.231796 1.488577 1.226090 0.083999 1.020558 1.699217 -0.014673 1.346295 -0.063182 -0.022308 1.145334 1.655017 0.305814 0.373230 1.594198 0.992544 0.008700 0.844473 1.661053 1.801356 0.850925 1.501091 0.639723 0.929876 0.176165) ) ;;; 32 prime -------------------------------------------------------------------------------- (vector 32 7.6309351921082 (fv 0 0 1 1 1 1 1 1 1 0 0 1 1 1 0 0 0 0 0 0 0 1 0 0 1 0 0 1 0 0 1 0) 6.829554 (fv 0.000000 0.353769 0.512450 0.072420 0.585526 0.147200 0.899992 1.177093 0.978539 1.319655 0.744178 0.765351 0.245581 0.971119 0.793076 1.664663 0.073560 1.968693 0.219541 -0.142255 1.387234 0.796908 0.143099 1.544481 1.359170 -0.183896 0.300411 0.910906 1.770472 1.091214 0.308566 1.575721) ;; 31+1 6.864557 (fv 0.000000 1.684531 0.907871 0.937049 0.576460 1.576459 1.338803 1.563265 1.353157 -0.035626 1.089066 1.735003 -0.147935 1.441252 -0.039130 -0.134227 1.098931 1.555167 0.496142 0.453987 1.332697 1.055734 0.066385 0.757972 1.840407 1.616574 0.776929 1.400044 0.751413 0.894663 0.088525 0.248633) ;; 33-1 6.772281 (fv 0.000000 -0.104424 1.369006 0.833384 0.832316 0.684545 1.080484 0.996539 1.125140 0.264781 0.104162 1.034076 1.132845 0.966270 -0.147521 -0.070104 -0.108305 0.137329 0.336575 0.120508 -0.030229 1.160998 -0.149314 0.018366 1.122475 -0.088339 0.190809 0.749038 -0.017283 -0.181633 0.895249 0.011511) ) ;;; 33 prime -------------------------------------------------------------------------------- (vector 33 7.7389698028564 (fv 0 1 0 1 0 0 0 1 0 0 0 1 0 0 1 0 1 0 0 1 1 1 1 1 0 1 0 1 0 0 1 1 0) 6.846444 (fv 0.000000 1.540730 1.269040 0.749184 0.961715 0.756150 0.876752 0.416027 1.022774 0.964239 1.083376 0.550495 1.494046 0.196678 0.925862 0.362000 0.602774 1.401166 0.181115 1.142230 0.264880 0.003237 0.994773 0.034504 0.433160 0.985315 1.781928 0.301442 1.605371 1.626266 0.719713 0.024414 0.683173) ) ;;; 34 prime -------------------------------------------------------------------------------- (vector 34 7.9624452590942 (fv 0 0 0 1 1 1 1 0 0 0 1 1 0 0 1 1 1 0 1 0 1 1 0 1 1 1 1 1 1 1 1 0 0 0) 6.991192 (fv 0.000000 1.753519 0.200582 1.709673 0.364080 0.826783 0.339745 0.629017 1.916751 1.209744 1.171294 -1.878381 1.379347 0.682133 1.526150 -0.403398 1.590798 1.225400 1.046260 0.612397 0.683970 1.216405 0.626313 0.038228 1.289324 1.063867 0.495350 0.036835 0.806562 1.424403 1.251942 0.446062 1.562643 0.395827) ) ;;; 35 prime -------------------------------------------------------------------------------- (vector 35 8.0019035339355 (fv 0 0 1 1 0 0 0 1 1 1 0 0 0 0 1 1 0 0 0 0 0 1 0 0 0 0 1 0 1 1 1 0 0 0 0) 7.163607 (fv 0.000000 1.266503 0.439150 0.502027 -0.033212 1.025554 1.236433 1.852606 1.521580 0.894650 0.982935 1.338812 0.175216 1.929333 1.483026 0.812681 0.144350 1.543173 0.347773 0.191753 0.996456 1.584603 0.595312 0.526825 0.409349 0.179419 0.765371 0.331481 0.734526 0.534073 1.395010 0.148584 0.213643 0.199292 1.071967) ;; 34+1 7.250722 (fv 0.000000 1.833406 0.276500 1.676183 0.284824 0.952861 0.274961 0.549393 1.855724 1.259088 1.170735 -1.972280 1.233657 0.707290 1.353858 -0.502547 1.522469 1.324648 0.749540 0.580274 0.753018 1.178005 0.466257 0.194427 1.292227 0.949230 0.518969 0.114495 0.772899 1.429905 1.258425 0.333692 1.615077 0.323568 0.024260) ;; 36-1 7.226635 (fv 0.000000 0.015639 1.313898 1.067017 0.012678 0.205933 -0.220601 0.741706 1.132622 1.273222 0.064153 -0.061062 0.016379 -0.109368 1.266070 0.708642 0.100132 0.506303 0.326245 0.009869 0.128374 0.656500 0.103915 0.211137 -0.048847 0.134642 0.911060 -0.081204 1.078761 0.959214 1.298439 0.058469 -0.265528 -0.047843 0.487719) ;; 37-2 7.337307 (fv 0.000000 1.255715 1.209445 1.285464 0.609971 1.084010 0.746511 0.131735 0.992588 -0.165317 1.349080 0.347697 1.563547 0.269558 1.052909 1.187133 0.630960 0.126283 1.974444 0.920793 0.149276 0.235777 0.684763 0.805570 1.167945 0.309490 0.732548 0.639985 1.194191 -0.082787 0.442732 0.130132 1.297597 1.522523 -0.004298) ;; 36-1 again 7.270607 (fv 0.000000 1.224685 0.688298 0.933888 0.799409 1.040304 0.882804 1.691450 1.134732 0.118453 1.557180 0.586802 1.344681 0.201498 1.086994 1.546739 0.883322 0.653756 0.179650 1.296869 -0.225456 -0.099064 0.999391 0.575486 1.210161 0.192596 0.624682 0.585705 1.229555 0.174654 0.165564 0.036132 1.525777 1.424254 0.061875) ) ;;; 36 prime -------------------------------------------------------------------------------- (vector 36 8.3031883239746 (fv 0 0 0 1 0 1 1 0 0 1 0 1 0 0 0 0 1 0 1 1 1 0 0 0 1 1 0 0 0 1 1 0 0 0 0 0) 7.274340 (fv 0.000000 0.295214 1.648256 0.584870 0.666257 0.185867 0.791897 0.205307 0.094941 1.078003 0.393529 1.106172 0.869922 0.874970 0.914168 -0.075429 0.352173 -0.206951 1.433194 0.016874 1.804925 1.769354 0.780563 1.415336 1.733698 0.569376 0.514365 1.527457 0.738716 1.585860 0.004452 0.303849 0.468887 1.200500 1.687045 -0.272506) ;; 34+2 7.326328 (fv 0.000000 0.224320 -0.145696 0.800619 0.068109 0.664686 1.202282 -0.026091 0.124729 1.390134 0.094406 0.787084 -0.284049 0.196932 0.011705 -0.061258 1.288162 0.209106 0.650222 0.837106 1.144479 -0.004444 -0.079317 -0.252873 1.282751 1.105461 -0.151235 -0.220044 0.048391 0.784914 0.800542 0.208916 -0.135577 0.180326 -0.083829 0.058422) ;; 37-1 7.188203 (fv 0.000000 1.311785 0.710177 0.919863 0.806114 1.220385 0.913244 1.649138 1.158903 -0.117650 1.420543 0.532433 1.420824 0.031354 1.130470 1.529113 0.851075 0.566610 -0.022612 1.109803 -0.179865 -0.219467 1.014788 0.671450 1.268941 0.095596 0.593655 0.518696 1.410763 0.018554 0.158212 0.022548 1.368086 1.347905 1.919434 1.204584) ) ;;; 37 prime -------------------------------------------------------------------------------- (vector 37 8.4775905609131 (fv 0 0 1 0 0 0 1 0 0 0 0 0 1 0 1 0 0 0 0 1 1 0 1 1 0 1 0 1 1 0 1 0 1 0 0 1 1) 7.291595 (fv 0.000000 1.385574 1.094219 1.256844 0.579410 1.074351 0.652085 1.737017 1.132509 0.023783 1.497034 0.201580 1.618763 0.156207 1.295800 1.067404 0.684624 0.145230 1.829069 1.057901 0.013674 0.026959 0.892842 0.719241 1.431201 0.175608 0.784924 0.608541 1.031616 0.099402 0.526982 -0.079447 1.301608 1.399791 1.919478 1.303159 1.654914) ) ;;; 38 prime -------------------------------------------------------------------------------- (vector 38 8.5527725219727 (fv 0 0 0 0 1 1 0 0 0 1 1 1 1 0 0 0 0 1 0 1 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0) 7.395907 (fv 0.000000 0.229361 1.165787 -0.110257 0.360118 0.958030 0.069946 0.724227 0.169462 0.629891 1.545997 1.736970 0.340776 1.117984 1.362890 -0.333746 0.304546 0.284267 1.101870 -0.220411 1.748591 0.492644 0.009938 0.667006 1.844837 0.974373 0.297199 0.452149 0.892727 0.659717 0.488303 1.523287 0.213584 0.164389 -0.141331 1.392379 0.641595 0.183921) ) ;;; 39 prime -------------------------------------------------------------------------------- (vector 39 8.8173857964668 (fv 0 0 1 0 1 1 0 0 0 0 0 1 1 1 0 1 0 1 1 1 1 1 1 0 1 1 0 1 0 0 0 0 0 1 1 0 0 1 0) 7.452083 (fv 0.000000 -0.003327 0.916189 -0.059920 1.642633 1.388547 0.951086 0.403885 -0.174730 0.969870 0.918579 1.463076 0.392796 0.310790 1.322505 1.568519 -0.013721 1.080957 1.546749 1.334291 1.196748 1.241477 0.666226 0.658367 0.483066 0.709740 0.970447 1.021587 1.015221 1.154977 1.464323 0.177481 1.236124 1.797764 1.373028 0.022625 0.381731 1.433474 1.548372) ) ;;; 40 prime -------------------------------------------------------------------------------- (vector 40 8.9134502410889 (fv 0 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 1 0 0 1 0 0 0 0 1 1 0 1 1 0 1) 7.703588 (fv 0.000000 1.735488 1.656851 1.224286 0.044381 0.581732 0.870499 0.678243 0.396963 1.559949 1.753552 0.343685 1.182244 0.436049 0.704051 1.315848 0.612950 0.283482 1.616300 0.417655 1.870367 0.045128 0.404846 0.027986 1.838093 1.350622 0.788217 0.264993 1.270928 0.453126 0.746731 1.438328 0.714772 1.669939 -0.004462 0.932368 1.451203 0.182154 1.479009 1.559243) ;; 39+1 7.542973 (fv 0.000000 -0.041200 1.048990 -0.088096 1.469596 1.426659 0.704430 0.532863 -0.271666 1.021284 0.854349 1.691302 0.165173 0.234052 1.293759 1.553143 -0.290199 1.111317 1.388897 1.428535 1.198923 1.295686 0.607124 0.554003 0.553080 0.829915 1.372981 1.113790 0.892248 1.036179 1.715559 0.155629 1.485519 1.734906 1.416427 0.111242 0.390867 1.435517 1.580034 0.394829) ) ;;; 41 prime -------------------------------------------------------------------------------- (vector 41 9.1567583084106 (fv 0 1 0 0 0 1 0 1 0 0 0 1 1 0 0 1 0 1 1 0 0 1 1 0 0 0 0 1 0 0 0 0 0 0 0 1 1 1 0 0 0) 7.865855 (fv 0.000000 0.608338 -0.060098 1.260166 0.343974 0.016950 -0.247861 -0.127427 0.108013 -0.084777 1.510985 0.480995 1.445979 -0.013184 1.345726 0.790782 0.040458 1.554753 1.065658 0.404394 0.487625 0.747477 1.296516 0.562390 1.713973 0.682704 0.619563 0.946390 0.938148 0.771516 1.743852 1.318578 0.561202 0.223419 0.656108 1.580261 0.293473 0.865769 0.313306 1.414219 0.732206) ;; 40 + 1 7.720320 (fv 0.000000 -0.115191 1.182807 0.023805 1.562688 1.390669 0.693038 0.384401 -0.432021 0.902901 0.808566 1.764939 0.071559 0.180956 1.306988 1.386263 -0.325917 1.184850 1.379486 1.267820 1.088531 1.531591 0.443244 0.383528 0.465953 0.767254 1.394223 1.223657 0.755343 1.085342 1.737843 0.118005 1.556067 1.593289 1.235706 0.152645 0.264917 1.446707 1.588810 0.262147 0.136941) ) ;;; 42 prime -------------------------------------------------------------------------------- (vector 42 9.2193641662598 (fv 0 0 0 1 1 0 1 1 0 0 1 0 0 0 0 1 1 1 0 1 0 1 1 1 1 1 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0) 7.967849 (fv 0.000000 -0.295563 -0.099748 1.645998 0.994997 1.211069 1.302259 1.702033 0.311003 1.380194 1.021127 1.240710 0.343052 -0.024723 0.792276 0.383501 1.598556 0.301882 1.243030 0.805694 1.869672 1.515585 0.818223 0.277882 0.151155 1.792151 0.439910 1.043803 1.106182 0.814125 1.169477 0.353168 0.087800 0.390591 1.058086 1.167577 0.254783 0.202834 1.385207 0.802821 0.860337 0.585161) ;; 41+1 7.869767 (fv 0.000000 -0.061943 1.138293 -0.062352 1.677941 1.387789 0.696129 0.354209 -0.606277 0.820682 0.889412 1.749845 0.156626 0.153950 1.241240 1.226387 -0.243954 1.180563 1.446765 1.133383 1.088516 1.534516 0.379614 0.441871 0.531294 0.625705 1.211996 1.249505 0.811274 1.137271 1.690807 0.091208 1.719416 1.589298 1.288167 0.231299 0.255350 1.544776 1.691946 0.324682 0.145604 -0.146627) ) ;;; 43 prime -------------------------------------------------------------------------------- (vector 43 9.4329051971436 (fv 0 0 1 0 0 1 0 0 1 0 0 0 0 0 0 0 1 1 0 1 1 1 0 0 0 0 0 0 1 0 0 0 0 1 0 1 1 0 0 0 0 1 1) 8.045098 (fv 0.000000 1.817726 0.258426 -0.110242 1.213496 0.116841 0.189488 1.576716 0.807175 0.814618 0.974723 1.682997 0.507481 0.400625 1.207987 1.609632 0.042496 -0.018345 0.188609 1.537320 1.421611 1.487985 0.125474 1.195313 1.777900 0.097292 1.089983 0.284602 -0.035452 0.114851 -0.014176 0.684966 0.713816 1.698239 1.505014 0.277355 1.721721 1.307506 0.790560 -0.024590 1.696281 0.234403 1.469880) ;; 44-1 7.936372 (fv 0.000000 0.547620 0.739031 1.442428 0.549512 0.577585 0.459986 1.527195 1.215306 0.359566 1.254454 1.014209 0.650822 0.596119 0.113760 0.896295 1.336762 1.511746 1.057661 0.208519 1.475881 1.168554 0.473943 0.693948 1.550424 1.853884 0.945372 1.595949 0.778275 1.634785 0.682180 0.046625 1.212650 1.360060 1.301003 1.439535 -0.124409 0.942540 0.731761 1.333209 0.714942 0.471897 0.650290) ) ;;; 44 prime -------------------------------------------------------------------------------- (vector 44 9.6263332366943 (fv 0 0 1 0 0 1 1 1 0 1 0 0 1 0 0 0 0 1 0 0 1 0 0 0 1 1 0 1 0 0 0 0 0 0 1 0 0 0 1 0 1 1 0 1) 8.176709 (fv 0.000000 1.257550 0.185092 0.796030 0.965692 0.874957 0.509986 0.767942 0.341523 0.782136 0.038164 0.864386 1.769646 0.079272 0.204040 1.740714 1.803726 0.921433 1.521099 0.318212 0.489644 0.199834 1.292293 1.253087 0.592822 0.223282 1.099161 1.260064 0.604685 -0.025938 0.319010 0.021098 0.567021 1.052022 1.286473 1.481285 1.059939 -0.262037 0.222072 1.063305 0.811574 1.525604 0.928719 1.796860) ;; 45-1 8.096356 (fv 0.000000 0.562197 0.780059 1.445061 0.297993 0.361779 0.450977 1.579753 1.251177 0.406295 1.140037 1.270462 0.688429 0.742666 0.310753 0.814792 1.242058 1.590925 1.239292 0.244955 1.563091 1.453652 0.466187 0.926031 1.420624 1.869915 0.975705 1.750035 0.662252 1.713066 0.628893 0.005473 1.403763 1.231668 1.313745 1.548647 0.181657 1.165934 0.757198 1.479137 0.584746 0.478571 0.777834 -0.217890) ) ;;; 45 prime -------------------------------------------------------------------------------- (vector 45 9.7923860549927 (fv 0 1 1 0 1 0 1 0 0 1 0 0 0 0 1 0 1 1 1 1 0 1 1 0 1 0 1 0 0 0 0 0 0 1 0 1 0 0 1 1 0 0 0 1 1) 8.156599 (fv 0.000000 0.504922 0.822887 1.454973 0.213937 0.312131 0.458345 1.480849 1.269108 0.365243 1.136961 1.370780 0.828694 0.744612 0.260671 0.781252 1.246491 1.660559 1.261864 0.159271 1.560422 1.570906 0.366422 0.845904 1.468563 1.922211 0.928352 1.793476 0.526909 1.787205 0.580505 0.086715 1.290991 1.241712 1.319383 1.542592 0.148589 1.164537 0.833531 1.339389 0.578898 0.484755 0.736594 -0.242427 0.801799) ) ;;; 46 prime -------------------------------------------------------------------------------- (vector 46 9.7220277786255 (fv 0 0 1 0 0 1 0 1 1 0 1 1 0 1 1 1 0 1 1 0 0 0 1 1 1 0 0 1 1 0 1 1 1 1 1 1 0 0 0 1 1 0 1 0 1 0) 8.261457 (fv 0.000000 0.441366 0.083292 1.447582 1.080353 0.774431 1.031820 0.396571 -0.029186 1.855247 0.017145 1.352007 1.097546 -0.117433 1.240120 0.492762 0.418188 1.012485 1.839598 0.629307 1.143304 0.248686 0.786166 1.148481 0.944111 0.160389 0.887598 1.383912 1.951363 0.089194 -0.493379 0.490615 1.318218 0.811054 1.210433 0.709880 -0.035076 1.496491 0.871523 0.967276 1.296575 1.252407 1.309942 0.517653 0.515382 1.088417) ) ;;; 47 prime -------------------------------------------------------------------------------- (vector 47 10.0 (fv 0 0 1 1 0 0 1 0 1 0 1 1 1 1 0 0 1 0 1 1 1 0 1 0 0 0 1 1 0 1 0 0 1 1 0 1 0 0 0 0 1 0 0 1 1 0 0) 8.421570 (fv 0.000000 1.199171 0.222010 0.019659 0.963763 0.124932 1.211729 1.737991 1.094580 1.129734 1.190285 0.683207 -0.164112 0.760349 0.581192 1.729176 1.903941 0.164043 1.172610 0.400191 0.298724 1.638863 1.039149 1.877811 1.604178 1.896976 0.373311 1.442981 1.057507 1.304308 1.366346 0.989245 1.435551 1.273331 -0.037405 1.342363 0.026228 1.277440 1.325955 1.225688 -0.091448 1.243683 1.490056 0.134719 0.038689 0.617889 0.397223) ;; 46+1 8.268289 (fv 0.000000 0.357443 0.232912 1.380147 1.115226 0.794363 1.003118 0.354162 -0.098010 1.882974 0.011731 1.431470 1.060533 -0.173886 1.243389 0.433576 0.427301 0.932883 1.964789 0.661151 1.135623 0.224910 0.703565 1.198466 0.988252 0.007869 0.877345 1.478313 1.822166 0.223930 -0.274799 0.527743 1.328214 0.957522 1.199220 0.836897 0.009700 1.499725 0.828964 0.836474 1.158394 1.390117 1.252214 0.607531 0.602372 1.108309 -0.308979) ) ;;; 48 prime -------------------------------------------------------------------------------- (vector 48 10.073040962219 (fv 0 0 0 1 1 1 1 1 0 1 0 0 1 1 1 1 1 0 1 0 0 0 0 1 1 0 0 0 1 0 0 0 0 1 1 1 1 0 0 0 1 0 0 0 1 1 0 1) 8.468727 (fv 0.000000 0.332125 1.567930 1.667264 0.442332 0.427404 0.736248 1.688653 -0.012194 0.001963 0.946717 0.783117 0.528363 1.021452 0.764794 0.424311 0.975629 0.318718 -0.017782 0.452256 -0.011646 0.634442 1.620045 1.251183 1.855810 -0.212250 0.823868 1.371356 1.272442 0.687371 1.532020 1.114788 -0.144494 0.601199 1.707870 0.646890 1.378450 0.845449 0.429827 0.928104 1.365712 1.152987 1.849756 1.181620 0.737310 0.960075 0.285625 -0.264250) ) ;;; 49 prime -------------------------------------------------------------------------------- (vector 49 10.209 (fv 0 1 1 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 1 0 1 1 1 1 0 1 1 1 0 1 0 1 1 0 1 0 1 1 0 0 1 0 1 1 1 0 0 0 0) 8.635701 (fv 0.000000 1.497567 0.290121 0.986848 0.952275 0.318809 -0.087393 0.815566 0.755417 1.644345 1.093196 1.596845 1.195048 1.825278 0.352544 1.500396 0.111683 1.721871 0.368622 0.016610 1.166008 0.992742 0.548001 1.794858 -0.049088 0.145023 0.031735 0.501144 1.167443 1.072488 1.771198 1.965444 1.813832 0.055643 1.178365 0.731304 -0.108216 1.823862 1.684500 1.505474 0.962838 1.663276 0.896417 -0.047513 0.341741 0.867962 0.622940 1.858325 1.225407) ;; 48+1 8.663039 (fv 0.000000 0.233282 1.589447 1.671036 0.438087 0.414167 0.679012 1.728850 0.023692 0.137515 1.015881 0.702030 0.655508 0.905046 0.682763 0.579979 1.082390 0.228729 -0.103033 0.415057 0.029242 0.738968 1.600166 1.205869 1.975508 -0.109422 0.921796 1.220834 1.561720 0.608646 1.497185 1.060920 -0.116318 0.565733 1.743370 0.776166 1.333349 0.886037 0.536440 0.806648 1.332765 1.166311 1.868868 1.215596 0.738421 0.985296 0.279827 -0.366830 0.092455) ;; 51-2 8.582839 (fv 0.000000 1.015072 1.263701 0.053109 -0.198567 -0.119876 -0.074305 0.688310 -0.022609 -0.056918 -0.335561 1.264545 0.175435 0.115160 0.045329 0.044221 0.357377 1.286502 1.011774 0.136492 0.790313 1.216480 1.412877 1.287840 -0.457032 1.185491 0.632250 1.022556 0.092623 0.762340 0.282587 1.173246 0.884457 -0.232556 1.275664 0.026771 1.001804 1.127230 -0.112893 0.390785 1.060560 -0.011579 0.935318 0.798092 1.155912 -0.045270 0.311662 -0.007451 -0.291556) ) ;;; 50 prime -------------------------------------------------------------------------------- (vector 50 10.402973175049 (fv 0 0 1 0 0 0 1 1 1 0 1 1 0 0 1 1 1 0 0 0 0 1 0 0 0 1 1 0 1 0 1 0 0 0 0 1 0 1 1 0 0 0 1 1 1 0 0 1 1 1) 8.676090 (fv 0.000000 1.487746 1.059441 1.025372 1.327289 1.088034 0.562677 1.658212 1.275003 1.216651 1.253782 1.464671 0.843363 1.799547 0.053937 0.685289 -0.108899 0.042484 1.103905 1.939714 1.165290 1.002239 0.949057 0.182130 0.764686 0.473808 0.974801 0.114296 0.831687 0.096978 1.328258 1.232106 1.944542 0.907302 0.451517 -0.196659 0.834303 1.063413 0.149435 1.600622 0.877347 1.358710 0.921698 1.475066 0.048402 1.601242 0.635073 1.286124 0.058142 1.221762) ) ;;; 51 prime -------------------------------------------------------------------------------- (vector 51 10.5841327092253 (fv 0 1 0 0 0 1 0 0 0 0 0 1 1 0 0 1 0 1 1 1 1 0 0 0 0 0 0 1 1 0 1 1 0 0 0 1 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1) 8.652946 (fv 0.000000 0.552138 1.581370 0.856634 0.465868 0.045489 1.205822 1.403218 0.756158 -0.011738 -0.321071 1.578958 0.777145 -0.086815 1.971735 0.371739 1.194751 0.827647 1.040995 0.971514 -0.103101 0.019110 0.372121 0.808088 0.569420 0.781614 0.253334 1.524564 0.516258 0.490039 0.356392 1.792991 0.344408 0.177045 1.267803 0.433404 0.355268 0.458783 0.927023 0.366207 1.155001 1.183690 0.095395 1.563819 1.892864 1.168287 1.234142 0.740278 0.190550 0.004346 0.616333) ) ;;; 52 prime -------------------------------------------------------------------------------- (vector 52 10.64324760437 (fv 0 0 0 1 0 0 1 0 1 0 0 1 1 1 0 0 0 0 1 0 1 1 0 0 0 0 1 0 0 0 1 0 1 0 0 1 1 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0) 8.817479 (fv 0.000000 0.192798 -0.100823 0.105700 1.730433 1.638226 1.781516 0.446103 1.408775 0.715209 0.415865 -0.245030 1.066219 1.674348 0.092550 0.243790 1.271420 0.492458 1.433072 -0.090924 1.409056 0.418163 -0.043783 1.528262 0.043370 1.470310 -0.026080 0.499433 0.961527 0.302716 0.768317 0.686930 1.132134 1.628592 0.701543 1.788137 -0.034028 1.911798 1.160323 1.534119 1.837005 0.994515 0.926867 1.263245 0.147467 1.441753 0.596623 1.430563 0.749640 0.874777 1.097276 0.882051) ) ;;; 53 prime -------------------------------------------------------------------------------- (vector 53 10.678050692694 (fv 0 1 0 0 1 0 0 0 0 0 1 0 1 0 0 1 0 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0 0 0 0 0 1 1 0 0 0 1 0 1 0 0 1 1 1 1 1 1 0) 8.953081 (fv 0.000000 0.788009 1.225451 0.347894 0.336100 0.208645 0.898104 1.918038 1.003547 1.827170 1.665391 0.306753 1.689654 -0.198226 0.387896 0.060438 0.532055 0.677523 0.983575 1.778621 1.222864 0.337168 0.648048 -0.059018 1.548622 0.344050 1.142170 1.624821 1.518580 1.046929 0.925606 0.370284 1.876402 0.554168 0.470781 0.776401 0.841340 0.579159 -0.039732 0.259208 1.047217 1.262845 0.826737 1.840523 0.361249 1.360958 0.974324 0.708988 1.467968 0.681409 0.951917 1.111614 0.104759) ) ;;; 54 prime -------------------------------------------------------------------------------- (vector 54 10.582709312439 (fv 0 0 1 1 1 0 0 0 0 0 0 1 1 0 1 1 0 0 0 1 1 1 1 1 1 0 0 1 0 0 0 0 1 1 0 1 0 1 0 1 0 0 1 1 0 0 1 1 0 0 1 0 1 1) 9.112388 (fv 0.000000 1.372093 1.646727 1.761844 1.071783 1.166972 0.499625 1.353759 1.094968 1.557358 1.723230 0.305306 1.364143 0.672762 0.599554 1.674554 1.196343 0.689593 0.333493 0.212755 0.120333 -0.065165 1.426986 0.808156 0.885002 1.618233 0.075135 0.412240 1.106276 -0.040331 -0.211790 1.351271 1.357179 1.301081 0.221358 0.762445 1.564667 0.202710 0.573995 1.689552 -0.051477 0.301020 1.046697 1.701827 0.907077 1.277114 0.971869 1.525859 1.752503 0.167031 0.961443 1.737745 0.154432 0.302453) ;; 53+1: 8.998093 (fv 0.000000 0.833931 1.255875 0.472195 0.500550 0.340958 0.889757 0.121823 0.999320 0.070168 1.822021 0.295115 1.599399 -0.278061 0.379867 0.053981 0.523149 0.552145 1.083746 1.542483 1.125023 0.280437 0.929583 0.145648 1.540352 0.570681 1.206535 1.391546 1.500834 1.280825 0.880416 0.297287 1.694488 0.607699 0.578077 0.733733 1.017737 0.538903 -0.079031 0.194742 1.159273 1.400820 0.893900 1.836755 0.359898 1.011475 0.991536 0.601097 1.637805 0.711833 1.160027 0.904915 0.240256 -0.100113) ) ;;; 55 prime -------------------------------------------------------------------------------- (vector 55 10.806410031758 (fv 0 0 1 1 1 1 1 0 0 0 1 1 1 0 0 0 0 0 1 1 1 0 1 0 1 0 0 1 0 0 0 1 1 1 0 0 0 0 1 1 1 0 1 0 0 1 0 0 0 0 0 1 0 0 0) 9.146479 (fv 0.000000 0.967563 0.927691 -0.360864 0.609958 0.765470 0.915027 1.392793 0.614248 0.953214 1.344500 -0.018857 0.737576 1.736931 1.631618 1.349440 1.307993 0.206073 1.281714 1.103145 0.628925 0.887703 0.370354 -0.354414 1.471798 1.220261 -1.840190 0.459998 0.319058 1.569823 -0.402409 1.289240 1.207248 1.401276 1.334659 0.647076 0.124770 0.659947 1.220235 0.570854 1.506684 0.326123 0.300730 0.226766 1.668245 0.069090 1.091084 1.792555 0.448614 1.706735 1.552724 -0.117313 1.845004 0.249242 0.002966) ) ;;; 56 prime -------------------------------------------------------------------------------- (vector 56 10.976176261902 (fv 0 0 1 0 1 1 1 1 0 1 1 1 0 0 1 1 1 1 0 0 0 1 1 0 1 1 0 1 1 0 1 1 1 0 0 1 1 0 1 0 0 0 1 1 1 0 0 0 0 1 1 1 1 1 1 1) 9.398396 (fv 0.000000 0.094656 0.695846 1.603834 1.096947 0.190376 1.605668 0.402610 1.589743 -0.046719 0.479899 1.053090 1.455624 1.475630 1.560612 1.146935 -0.097134 1.379647 0.063965 0.026372 0.001091 0.417420 0.372665 0.295880 0.375803 1.735862 -0.241158 0.226369 0.344276 0.614802 1.609054 1.733862 -0.048343 1.607193 0.295369 0.796984 0.953479 0.777849 -0.315058 -0.215768 1.445593 0.800481 -0.018312 0.085983 1.492275 1.800390 0.955850 0.344132 0.748720 -0.182377 -0.021909 0.550436 1.590599 1.124545 1.577258 1.243187) ; 55+1 9.213442 (fv 0.000000 0.950801 0.904714 -0.508703 0.661009 0.831586 0.884308 1.497773 0.634206 0.800998 1.332469 0.044201 0.725326 1.681333 1.804312 1.427989 1.278065 0.225748 1.222051 1.044010 0.570030 1.029930 0.330187 -0.354523 1.385937 1.248658 -1.994529 0.420806 0.301325 1.707662 -0.449043 1.164884 1.219283 1.466837 1.371490 0.636485 0.172055 0.643834 1.272809 0.563267 1.543526 0.353044 0.368529 0.213972 1.758208 0.147525 1.155503 1.739729 0.512727 1.742754 1.612106 -0.186498 1.717200 0.213592 0.028127 -0.105694) ) ;;; 57 prime -------------------------------------------------------------------------------- (vector 57 11.247724533081 (fv 0 0 1 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 1 0 1 0 1 1 0 1 1 0 0 0 1 0 0 0 1 0 1 1 0 1 0 0 1 0 0 0 0 0 1 1) 9.567937 (fv 0.000000 -0.074489 1.764667 1.562855 -0.045942 1.688785 0.424094 0.788093 1.318249 1.699500 1.597710 0.759778 0.347915 -0.095100 0.967999 1.558373 1.224410 -0.005793 1.163013 1.817831 1.260212 1.123377 0.674940 0.664211 1.043062 -0.159530 1.686511 0.775041 1.335210 0.664604 0.251332 0.046341 0.133324 0.094858 -0.073202 1.314310 1.874591 1.317512 0.082927 1.516375 0.524906 0.812252 0.819331 0.420977 1.188424 0.646402 1.644694 0.551897 0.757891 1.055306 1.295231 1.095924 0.627116 1.401110 0.235317 1.483585 0.936274) ;; old 56+1 9.529594 (fv 0.000000 0.147122 0.761626 1.581775 0.991521 0.303398 1.538303 0.250231 1.516156 -0.033991 0.496296 1.098128 1.450885 1.473689 1.672255 1.122803 -0.210233 1.300861 0.064078 0.004743 0.013527 0.414701 0.325782 0.261492 0.363241 1.708852 -0.205248 0.171322 0.269253 0.615657 1.654144 1.808189 -0.053761 1.665701 0.276750 0.872232 1.105105 0.764170 -0.448707 -0.286149 1.484838 0.786694 -0.015133 0.173812 1.436796 1.864880 0.980591 0.327079 0.799812 -0.230067 -0.066056 0.534676 1.508154 1.155564 1.645708 1.183535 0.088307) ;; 56+1 9.246042 (fv 0.000000 1.068254 0.912344 -0.579409 0.699964 0.833848 0.899690 1.280880 0.729555 0.772814 1.165620 0.113563 0.958418 1.776654 1.746943 1.402708 1.254651 0.244552 1.303164 0.938450 0.572896 0.902407 0.419733 -0.424031 1.525432 1.318732 -1.856680 0.294120 0.271355 1.825185 -0.454382 1.066744 1.206377 1.513453 1.348624 0.487546 0.090590 0.574392 1.204512 0.396962 1.588976 0.339722 0.399778 0.196224 1.725471 0.086935 1.086444 1.835851 0.439978 1.611137 1.567240 -0.063335 1.719558 0.447194 0.045334 -0.250234 0.164616) ) ;;; 58 prime -------------------------------------------------------------------------------- (vector 58 11.261419321863 (fv 0 0 1 0 0 1 0 0 0 0 1 1 0 0 0 1 0 1 1 1 1 1 1 1 0 1 1 1 1 1 0 0 0 1 0 0 1 1 1 1 0 0 1 0 0 1 0 1 1 1 1 0 1 1 1 0 1 1) 9.496347 (fv 0.000000 0.059743 0.548997 0.530263 0.226709 0.929160 -0.003047 0.125973 0.533773 1.548469 1.087643 1.570490 0.714949 0.863084 1.167817 1.094596 0.710052 1.511445 0.483704 1.291778 1.179203 1.180959 0.109073 0.094424 -0.384843 0.103787 0.722897 0.948977 1.484212 0.671726 0.961877 1.358209 1.232685 1.456297 0.651862 0.171910 0.370224 1.284842 1.052862 0.918644 1.853795 0.756435 1.065168 1.308648 0.977275 0.827028 1.655929 0.742384 0.217339 0.808896 0.296638 1.208667 1.265590 0.019271 0.389600 0.183945 0.533565 1.638734) ;; 57+1 9.428825 (fv 0.000000 1.018908 0.901444 -0.615819 0.860485 0.681403 0.932140 1.367257 0.748226 0.856986 1.087905 -0.048047 0.777707 1.778584 1.735112 1.472731 1.253932 0.300987 1.373471 0.844264 0.566375 0.847406 0.280264 -0.528105 1.424599 1.371262 -0.084608 0.304532 0.358385 1.652997 -0.476953 1.150522 1.226908 1.441019 1.199333 0.513348 0.039957 0.545771 1.150857 0.473094 1.508935 0.466022 0.322870 0.315957 1.725788 0.047786 1.078150 1.717254 0.429354 1.592876 1.500586 -0.142982 1.851065 0.442979 -0.034671 -0.282154 0.042441 0.094078) ) ;;; 59 prime -------------------------------------------------------------------------------- (vector 59 11.34253692627 (fv 0 0 0 1 0 1 0 1 1 1 0 0 1 0 1 1 0 0 1 0 0 0 1 0 1 0 0 1 0 1 1 0 1 0 0 0 1 0 0 1 0 0 0 1 0 0 1 1 0 0 0 0 1 0 0 0 0 1 1) 9.424456 (fv 0.000000 0.987831 1.263819 0.296674 0.942023 0.441708 0.159032 1.836629 0.018568 -0.056141 1.409550 -0.045051 1.184001 1.106575 0.859402 0.865929 1.344330 -0.022715 1.852739 1.494636 -0.146236 1.538496 0.317717 1.985293 0.734507 0.982797 0.398619 1.595615 1.945403 0.701589 1.197367 1.012887 0.543978 1.174908 1.430788 -0.128888 0.147545 0.984537 1.324816 1.549298 0.656696 -0.006636 1.201874 1.148588 0.795564 1.108773 1.687645 0.571018 0.266043 1.954157 1.006840 0.084613 0.524554 1.761460 0.208641 0.094850 0.141845 0.437731 0.909728) ) ;;; 60 prime -------------------------------------------------------------------------------- (vector 60 11.512454032898 (fv 0 0 0 0 1 0 1 1 0 0 0 0 0 1 0 1 1 0 0 0 0 1 0 0 1 1 1 1 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 1 1 1 1 1 1 1 0 1 1 0 0 1 1 1 1 0) 9.657740 (fv 0.000000 1.547780 1.677673 1.073672 -0.181562 1.466665 0.178185 1.296168 1.180984 0.799114 0.182696 1.568868 1.363180 0.494840 -0.056028 1.003607 1.541063 0.417763 1.700695 0.183440 0.905951 0.331420 0.794062 0.890276 1.122192 1.798420 0.731798 0.770804 1.703299 0.813575 0.660992 1.187791 1.645314 1.481351 1.240486 1.798220 0.254797 0.358769 1.758554 0.791594 0.131877 0.642084 0.956267 -0.226021 -0.095209 1.368914 1.922174 1.414955 -0.029158 0.411776 1.206976 1.720135 0.221233 0.679698 1.694654 0.956928 0.036757 1.792835 0.004408 0.786308) ;; 59+1 9.567932 (fv 0.000000 0.987181 1.155730 0.332214 0.959672 0.422609 0.139164 1.858170 1.971933 -0.085625 1.367690 0.092445 1.162248 1.070252 0.880093 0.923540 1.286688 -0.075166 1.802993 1.583654 -0.058064 1.544851 0.459865 -0.017801 0.622918 1.081434 0.420245 1.717169 1.954432 0.771937 1.209324 0.923890 0.475411 1.176878 1.472899 -0.165713 0.114758 1.012016 1.333064 1.459949 0.672973 0.014198 1.279333 1.152000 0.797283 1.103957 1.630723 0.491103 0.146670 1.964833 1.081703 0.052456 0.483259 1.761154 0.245675 0.138222 0.019396 0.460673 0.907223 -0.053470) ) ;;; 61 prime -------------------------------------------------------------------------------- (vector 61 11.850807189941 (fv 0 0 1 0 1 0 0 1 0 0 0 1 0 1 0 0 0 0 0 1 0 1 1 0 0 1 0 1 1 1 1 1 1 1 1 0 0 1 0 0 0 1 1 1 1 1 0 1 1 0 0 0 1 1 1 0 0 0 0 0 1) 9.848207 (fv 0.000000 0.465768 1.502052 1.208112 1.687111 1.098823 0.136558 1.242624 0.803898 1.305434 0.569022 0.707134 0.107360 0.681230 1.626786 1.180372 0.428544 0.064966 0.220601 0.606687 1.112200 0.761343 0.147814 1.074432 0.974575 0.150330 0.295078 1.965080 0.596171 1.395202 1.511902 0.719123 0.058806 0.162986 1.356055 1.017221 1.069746 0.022458 1.119273 0.473964 1.602481 0.117785 0.745272 0.467208 1.699348 0.892580 0.864605 0.883970 -0.281719 1.309124 0.657105 1.259919 1.224601 1.818239 1.863265 0.645463 0.762464 -0.184384 0.778659 1.743798 0.403645) ;; 60+1 9.674304 (fv 0.000000 0.942988 1.185184 0.401228 0.922656 0.384439 0.124613 1.797598 1.871679 -0.085568 1.287716 0.127521 1.211990 1.110404 1.018269 0.906936 1.241998 -0.006224 1.802916 1.625042 -0.136580 1.655334 0.507522 0.019978 0.578715 1.045428 0.440588 1.674467 1.983824 0.788229 1.261730 0.967897 0.387538 1.232060 1.526658 -0.187478 0.170755 1.104323 1.383734 1.532583 0.668063 0.082609 1.255511 1.174792 0.795177 1.135630 1.640793 0.324749 0.311806 1.930005 1.005470 -0.027359 0.440238 1.824355 0.182093 -0.005304 0.026835 0.470199 0.945827 0.102044 -0.110982) ) ;;; 62 prime -------------------------------------------------------------------------------- (vector 62 11.709966659546 (fv 0 0 0 0 0 1 1 1 1 1 1 1 0 1 0 0 0 1 0 1 1 1 1 1 1 0 1 1 1 1 0 1 1 1 0 0 1 0 0 1 1 1 0 1 0 0 1 0 0 0 1 1 0 1 0 0 0 1 1 0 1 0) 9.787654 (fv 0.000000 0.164735 0.495571 0.194524 1.700130 -0.039330 1.112293 0.631854 1.622240 0.234398 0.057253 0.622061 1.299807 1.150659 1.089362 1.262936 0.326220 0.146372 0.440190 0.705699 0.320098 1.480138 -0.723459 0.298112 1.483411 -0.413300 0.234477 1.688059 0.592934 1.563752 1.095288 0.196837 0.912297 -0.114061 -0.100816 0.101717 1.569678 0.725974 1.210511 1.268915 0.220895 1.789986 0.880755 0.550271 0.862882 1.562267 1.201540 0.696671 0.139442 0.617496 0.156201 0.378889 1.874933 0.550733 0.693398 0.120666 0.641553 1.379939 0.633855 1.283976 1.797799 0.211762) ;; 63-1 9.733736 (fv 0.000000 -0.139952 0.119957 0.369616 1.566294 0.358962 1.150575 0.658899 1.145823 0.565498 0.818035 -0.078756 0.339361 0.036853 -0.081445 1.284492 0.104736 1.510521 0.937147 0.788271 1.526814 1.396514 1.280490 1.469510 1.789649 0.285213 0.650226 0.881585 0.728974 1.810762 -0.044930 1.659215 0.713447 0.623929 1.496774 0.951425 0.357075 1.369241 1.674041 0.637986 0.902200 0.722908 0.299878 -0.044061 0.733643 0.407073 1.473577 0.408899 -0.199740 0.425185 0.345580 1.674452 0.584665 1.350356 0.031128 1.247150 0.256688 0.635884 0.503839 0.135030 0.263417 1.006656) ) ;;; 63 prime -------------------------------------------------------------------------------- (vector 63 11.975765228271 (fv 0 0 0 1 1 0 0 1 0 1 0 1 1 0 1 1 1 0 0 0 0 0 1 1 0 1 1 0 0 0 1 1 1 1 1 0 1 0 0 0 1 0 1 0 1 1 1 1 1 0 0 0 1 0 0 0 1 0 0 0 0 1 0) 9.712956 (fv 0.000000 -0.211512 0.128156 0.205336 1.631792 0.223993 1.120077 0.677974 1.189520 0.635587 0.786994 -0.140042 0.270508 0.031528 -0.026718 1.271754 0.161836 1.519308 0.919403 0.725190 1.656604 1.430895 1.216006 1.507263 1.740613 0.380045 0.740422 0.860394 0.644699 1.785241 -0.063336 1.757196 0.670969 0.631113 1.432730 0.929994 0.449373 1.355893 1.665671 0.697673 0.900343 0.706516 0.261640 0.022846 0.779166 0.410962 1.451999 0.372853 -0.213671 0.428231 0.418722 1.770544 0.502738 1.423557 0.029160 1.322724 0.247556 0.608992 0.392989 0.101597 0.240746 1.015503 0.321046) ) ;;; 64 prime -------------------------------------------------------------------------------- (vector 64 11.932915769505 (fv 0 0 1 1 0 0 1 1 1 0 1 1 0 0 0 0 0 1 1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1 1 1 0 1 0 0 1 1 0 0 0 1 0 0 0 0 0 1 1 0 0 1 0 1 1 1 1 0 1 1) 9.911897 (fv 0.000000 -0.176519 0.277243 1.457679 0.409823 0.492128 1.258703 0.953828 0.451970 -0.035755 1.413815 0.576790 1.007663 1.557197 0.406393 0.901721 0.935399 0.344434 0.058666 -0.004874 0.033568 0.266354 0.964058 1.260921 0.110946 0.586184 1.551133 0.560107 1.655832 1.431146 0.094791 0.726936 0.404173 1.258539 0.363860 0.287498 0.704556 1.358694 0.848351 1.352219 1.358382 1.634548 0.646434 0.536511 1.151363 1.507902 0.370229 -0.111562 0.018845 1.351430 0.613337 0.524145 0.030867 1.602701 0.958191 0.774983 0.900142 1.319974 1.665985 0.954409 0.571244 0.683517 0.257283 0.560359) ) ;;; 65 prime -------------------------------------------------------------------------------- (vector 65 12.264873504639 (fv 0 0 0 0 1 1 1 1 1 0 0 1 1 0 0 1 0 1 0 1 1 1 1 0 0 0 1 1 1 1 1 0 1 0 1 0 1 1 0 1 0 0 0 0 0 0 1 0 0 0 1 1 0 0 1 1 0 0 1 1 1 1 0 1 0) 10.245810 (fv 0.000000 1.314885 -0.128565 -0.061767 0.245423 0.308150 0.666161 1.799635 0.121779 1.318087 1.095106 1.813764 1.363803 0.687883 0.082989 1.252556 0.674431 0.081538 1.120705 -0.053380 0.222404 0.418326 1.266348 1.095265 1.090145 0.914385 0.672015 0.091667 0.221386 0.230885 1.047444 0.950558 0.582123 1.829143 1.939330 0.054401 0.665085 0.669868 1.410783 0.893429 1.398299 1.087907 0.120341 1.456277 0.134554 1.548051 0.155644 0.252207 0.317819 0.803060 0.255268 0.011364 1.407071 1.292331 1.862089 -0.144291 1.528219 0.241256 -0.215537 1.071975 0.180828 1.509027 1.608200 1.880646 0.432459) ;; 64+1 10.041913 (fv 0.000000 -0.231597 0.347996 1.329229 0.210946 0.358775 1.318136 0.940959 0.423445 -0.059602 1.487652 0.528102 0.959962 1.627507 0.242008 0.890416 1.013953 0.381481 0.048421 0.000955 0.073351 0.222260 0.956448 1.250606 0.032874 0.581396 1.552144 0.533024 1.803356 1.588620 0.155988 0.709145 0.416103 1.098822 0.371144 0.488313 0.641224 1.409761 0.769076 1.378012 1.338517 1.672969 0.693576 0.622573 1.111879 1.498797 0.384021 -0.285902 0.098531 1.294593 0.540682 0.514444 0.031708 1.544980 0.882941 0.833995 0.886145 1.471130 1.590019 0.959450 0.407950 0.787696 0.104075 0.545846 0.096608) ) ;;; 66 prime -------------------------------------------------------------------------------- (vector 66 12.090668678284 (fv 0 0 0 1 1 1 1 1 0 1 1 1 1 1 0 1 1 1 1 0 0 1 1 1 0 1 1 1 1 1 1 0 1 1 0 1 1 0 1 0 0 0 0 1 0 1 1 1 0 1 1 1 0 0 0 1 1 1 1 0 0 0 0 1 1 0) 10.065843 (fv 0.000000 -0.332278 0.420111 1.296912 0.003400 0.570050 1.383101 1.228319 0.329402 0.002928 0.332461 0.786693 1.331535 0.237292 1.020996 0.126259 1.613105 1.241426 -0.367526 0.057745 0.063068 1.144890 0.058649 0.546763 0.792290 0.527577 1.597907 0.336733 0.558202 0.349266 0.412838 -0.066236 0.132007 1.032081 0.645360 0.084627 0.218015 0.961024 1.464682 1.216442 1.186753 0.039444 1.139907 1.145545 1.026317 1.617341 0.492061 1.804706 -0.218027 0.872723 0.567401 1.745335 1.259266 0.682677 1.100993 1.200392 1.089304 0.237539 0.552581 0.047166 0.743492 0.228597 1.363708 0.915715 -0.032741 0.312099) ) ;;; 67 prime -------------------------------------------------------------------------------- (vector 67 12.20425496356 (fv 0 1 0 1 1 0 1 1 1 1 1 0 1 1 0 1 1 0 1 0 0 1 0 1 1 1 1 0 0 0 0 1 1 1 1 0 1 1 1 0 0 0 1 0 0 1 1 1 1 1 0 0 1 1 0 1 0 1 1 1 0 0 1 1 1 1 1) 10.320633 (fv 0.000000 -0.066702 1.242059 1.936441 0.363520 0.137300 1.303419 1.038801 0.086937 0.040742 0.388452 0.616008 0.087295 0.258798 0.692201 0.072909 1.551804 1.636838 1.398740 0.687317 1.022745 0.988646 1.580618 0.947110 0.593084 0.854099 0.599585 1.071060 0.286673 0.719337 0.932505 1.632806 1.461969 0.862483 1.295247 0.807609 -0.156076 1.297879 1.679745 0.135687 1.421850 1.188268 0.748752 1.493420 1.296035 0.019305 0.979542 0.607739 1.082240 1.014220 1.355630 1.025509 1.427015 0.501576 0.029659 1.501116 0.667518 0.375063 0.738972 1.634670 1.190958 0.695412 0.198543 0.008987 0.953545 0.492193 0.512363) ;; 66+1 10.270103 (fv 0.000000 -0.339086 0.529826 1.196633 0.017211 0.503338 1.254976 1.117868 0.397424 -0.207937 0.422035 0.795324 1.396533 0.167749 1.073809 0.015795 1.618310 1.175144 -0.342555 0.080333 0.003741 1.084430 -0.010093 0.560025 0.867130 0.369945 1.456200 0.444129 0.652644 0.167650 0.320656 -0.145242 0.307342 1.062944 0.883767 0.299612 0.277397 1.030332 1.417097 1.462867 1.323580 0.189769 1.089141 0.993348 0.915509 1.413244 0.654039 1.674522 -0.169566 0.974872 0.769627 1.866694 1.124536 0.783559 1.039716 1.307670 1.055658 0.169272 0.711344 0.060085 0.731555 0.347823 1.529167 0.605251 0.021941 0.493045 -0.306702) ;; 63+4 10.427697 (fv 0.000000 0.966407 0.007580 1.117030 0.884875 -0.175736 1.107926 1.097831 1.037576 0.927078 0.966085 0.319675 1.083926 1.106087 -0.189435 0.791093 0.993213 0.299434 1.143696 -0.196739 -0.029109 0.887111 0.277418 0.908738 0.949002 0.901486 1.105128 -0.045569 -0.301510 0.181857 -0.008960 0.833755 0.782101 0.955244 1.472884 0.046447 1.032739 0.722326 0.974274 -0.002839 -0.169106 0.164428 1.138848 0.015499 -0.200081 0.988166 0.843017 1.122563 0.966722 1.090406 0.167301 -0.055129 1.042886 1.189957 0.335648 0.995142 0.029028 1.138068 1.075538 0.633942 0.180537 0.051411 0.928317 0.861628 0.910920 0.920218 1.020151) ) ;;; 68 prime -------------------------------------------------------------------------------- (vector 68 12.466281890869 (fv 0 0 1 1 1 1 0 0 0 0 1 0 0 1 1 1 1 1 0 1 1 1 1 1 1 0 1 1 0 1 0 0 1 0 1 1 1 0 1 1 1 1 0 1 0 0 0 0 1 1 0 1 0 1 0 0 0 0 0 1 1 0 1 0 0 1 0 1) 10.396366 (fv 0.000000 0.186038 1.693540 -0.027216 1.013938 1.733700 0.097268 1.072327 -0.058595 1.297512 -0.223714 1.812708 1.571967 1.911449 0.105375 0.724913 0.167937 1.379937 1.003328 0.296337 -0.012219 0.740941 0.185685 1.450530 0.967328 0.422187 -0.221136 1.128630 1.299506 1.950429 -0.063323 -0.049468 0.618925 -0.250368 1.155850 1.363266 1.946601 1.896273 0.663379 0.530614 -0.343257 1.261470 -0.040006 0.308974 1.407553 1.782235 1.820125 1.703055 0.892390 0.956493 1.267334 1.223362 0.886365 0.857699 0.303604 1.740946 1.505785 1.372752 0.598965 0.555179 0.138411 0.702673 0.141261 1.356921 1.480871 1.810731 0.336170 1.491601) ;; 69-1: 10.294332 (fv 0.000000 1.774482 1.200978 1.227268 1.382220 0.282793 1.553903 1.732456 0.753211 0.760153 1.851640 1.366776 1.204200 0.843725 0.253043 0.277483 0.103836 -0.065448 1.410455 0.651921 1.994318 0.062621 0.954681 0.275021 0.597686 1.119852 0.016268 -0.163905 1.984242 1.567894 0.922417 -0.007109 1.063508 1.828059 0.334844 1.052665 1.253633 1.262611 1.579598 0.998618 1.505098 1.876188 0.866523 -0.096826 0.810066 0.678537 0.661302 -0.487197 0.199269 0.661440 1.362169 1.024823 0.238200 0.872311 1.253153 1.455210 0.266625 1.222868 1.015892 1.101616 1.115849 0.596998 1.881890 -0.207678 1.082090 0.165311 1.300155 1.153433) ) ;;; 69 prime -------------------------------------------------------------------------------- (vector 69 12.29846572876 (fv 0 0 1 0 0 1 1 0 1 1 0 1 0 1 0 1 0 1 0 1 1 0 0 0 1 1 1 1 1 1 0 1 1 0 1 1 0 0 0 1 1 1 1 0 0 0 1 0 1 0 1 1 1 1 0 1 0 1 0 0 0 1 0 0 1 0 0 0 0) 10.373386 (fv 0.000000 1.755739 1.344798 1.270777 1.245975 0.212147 1.637341 1.674637 0.780881 0.678256 0.020823 1.453992 1.251154 0.906274 0.263210 0.219658 0.201277 -0.006107 1.482279 0.690309 1.943780 0.107940 0.891912 0.210217 0.501788 1.062586 1.748465 -0.256216 1.793890 1.653062 0.760504 1.930618 1.125386 1.733012 0.392253 1.017032 1.329369 1.438951 1.614342 0.946373 1.511397 1.735151 0.924137 -0.243047 0.908372 0.619579 0.722525 -0.263766 0.070586 0.505534 1.390127 1.112173 0.360123 0.888486 1.115007 1.574719 0.192671 1.168644 1.072297 1.024494 1.027776 0.495929 1.728234 0.030466 1.010825 0.303774 1.356890 1.301979 0.677665) ) ;;; 70 prime -------------------------------------------------------------------------------- (vector 70 12.665026664734 (fv 0 1 0 0 1 0 0 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 0 1 1 0 0 0 1 1 1 1 1 1 0 1 0 0 1 1 0 1 1 0 1 1 0 1 1 1 1 1 1 0 1 0 1 0 1 0 0 0 0 1 1 1 1 1 0 0) 10.403198 (fv 0.000000 0.659269 0.149246 -0.229331 0.464031 1.037303 0.297808 1.605092 1.041553 1.638786 0.968456 1.081487 0.986031 0.766531 0.645236 0.176746 0.062926 0.650627 0.887571 0.432390 0.968052 1.660369 1.053082 0.034606 1.910731 1.746043 1.683430 0.821251 1.040772 1.932221 1.382437 0.501614 -0.111054 0.532350 0.190557 0.045053 1.319570 -0.066664 0.486188 1.777508 1.395223 0.491473 0.176001 0.623855 1.347864 1.207736 1.451417 1.558733 1.414717 1.920228 0.418857 1.530616 0.099510 0.214659 0.967449 -0.145006 1.519241 0.691963 1.366826 0.718889 0.337519 0.685633 1.635424 0.816319 0.060380 1.097292 0.149441 0.900329 0.876399 0.145344) ) ;;; 71 prime -------------------------------------------------------------------------------- (vector 71 12.609085083008 (fv 0 1 0 1 1 1 1 1 0 1 0 1 0 1 0 1 1 0 0 0 0 1 0 0 0 0 1 1 1 0 0 1 1 1 0 0 0 0 1 1 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 1 1 0 1 1 0 1 1 0) 10.523064 (fv 0.000000 0.688011 0.968837 0.940634 1.605222 0.888784 0.799658 0.986589 0.551066 0.615309 0.653186 0.893971 1.635005 0.515944 0.737309 0.499869 0.965484 1.166543 1.233403 1.277963 0.357632 0.184373 0.829321 0.533549 0.654127 1.345320 0.132782 0.366320 0.049851 1.315507 0.714178 1.332359 1.090257 0.069099 0.561445 1.760121 1.667327 0.986854 0.112329 0.614048 1.104774 0.212197 1.392955 0.553988 0.863015 1.668891 1.231650 0.232935 1.786061 0.865166 0.966113 0.257005 0.993747 -0.000704 1.235807 0.060112 1.258818 1.073792 0.276968 0.278092 1.838200 0.920318 1.799026 1.603861 0.357301 0.246709 0.264914 0.955910 0.731514 1.325161 1.347000) ) ;;; 72 prime -------------------------------------------------------------------------------- (vector 72 12.708446502686 (fv 0 0 1 0 0 0 1 1 0 1 1 1 0 0 0 1 0 0 0 1 1 0 1 1 1 0 1 0 1 0 1 1 0 0 0 0 1 1 0 0 0 1 1 0 1 1 1 0 0 1 1 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1) 10.579571 (fv 0.000000 1.526666 1.114036 -0.188699 1.569783 1.061483 1.461941 0.746029 1.509803 1.264040 0.039120 0.005480 1.670375 0.087176 1.602839 1.411297 1.630968 0.248800 0.070549 1.021733 -0.228089 1.869979 1.152734 0.098898 0.604652 0.265485 1.435929 0.170559 0.737250 0.104974 0.731428 1.774793 1.550528 -0.147974 1.870001 1.248377 1.256893 0.177185 1.205217 1.218210 1.654506 -0.048160 1.262662 0.659765 1.099483 0.193101 1.327235 0.693549 1.139270 0.170053 0.767850 1.284172 -0.044820 1.663616 1.015434 0.890883 1.694823 0.554893 0.622406 0.662793 0.328828 0.995738 1.236624 0.150517 1.587539 1.302619 0.103369 0.398303 0.131685 0.921928 1.168883 0.112924) ) ;;; 73 prime -------------------------------------------------------------------------------- (vector 73 12.877750118249 (fv 0 1 0 0 0 0 0 0 0 0 1 1 0 1 1 1 1 1 1 0 0 0 1 0 1 0 0 1 0 0 0 1 0 0 0 1 0 0 1 0 1 0 1 0 0 0 1 1 1 0 0 0 1 1 0 0 1 0 0 0 0 1 0 0 0 1 0 1 0 1 0 1 0) 10.737656 (fv 0.000000 0.602102 0.352641 0.632006 1.552371 0.296077 1.082110 0.013914 1.761810 0.456416 0.737747 0.295270 1.253093 0.753406 0.547256 0.051955 1.746228 0.377469 0.418110 0.901371 0.231886 1.499847 1.247926 1.681473 1.281726 0.414399 -0.025093 0.354821 1.545561 1.180195 1.073840 1.640054 1.311359 1.388818 1.571352 1.435069 -0.082478 0.162069 0.705649 -0.084633 0.587089 0.167800 -0.063043 0.159333 0.913473 1.004072 1.669680 0.741708 1.378872 1.360081 0.270841 1.349751 1.013148 0.450718 0.226120 0.098676 0.779207 1.870363 0.442457 1.048600 1.409639 0.334422 1.713108 0.607567 1.451973 0.551597 1.404406 0.821452 1.414792 0.265647 0.470100 0.101296 1.610504) ;; 72+1 10.689130 (fv 0.000000 1.525750 1.157802 -0.130495 1.566135 1.068083 1.436324 0.699061 1.496431 1.345845 -0.045471 -0.032146 1.656974 0.163846 1.519166 1.394757 1.503557 0.183007 0.248242 1.068642 -0.134987 1.855031 1.116717 -0.022218 0.511499 0.347386 1.347662 0.149072 0.778251 0.082394 0.706357 1.835299 1.598933 -0.137332 1.800937 1.334976 1.258225 0.107942 1.165982 1.097698 1.720927 -0.060245 1.266550 0.522159 1.151393 0.179388 1.306382 0.759803 1.190783 0.160999 0.709993 1.280967 -0.169862 1.562918 1.019413 0.839429 1.731380 0.566096 0.647229 0.704371 0.329975 1.072857 1.320759 0.275029 1.479112 1.297543 0.103782 0.366305 0.194503 1.011614 1.086013 0.243622 -0.036669) ) ;;; 74 prime -------------------------------------------------------------------------------- (vector 74 13.115156173706 (fv 0 1 1 0 0 0 1 1 0 0 1 1 1 0 0 1 0 0 1 0 1 0 0 1 0 0 1 0 1 0 1 0 0 1 1 1 0 1 0 0 0 1 0 0 0 0 0 0 1 0 1 0 0 1 1 1 0 1 1 0 1 1 0 1 1 1 1 1 0 0 0 0 0 1) 10.649887 (fv 0.000000 0.311188 1.290942 0.614169 0.538966 0.384100 0.109850 0.021551 0.798332 1.375278 0.593955 1.270048 0.158912 1.156782 1.030374 0.821590 0.254106 0.736652 -0.160646 1.527962 0.008622 1.070061 1.131441 1.654723 1.927687 1.286729 -0.139272 1.540344 0.234722 1.262327 0.958913 0.415825 0.099669 0.142462 -0.047631 -0.219606 0.497897 0.164613 1.298918 -0.030959 0.077929 0.023069 -0.048674 1.490524 1.421741 1.027040 1.916604 1.756080 0.253777 0.507377 0.665062 0.691819 1.450238 1.738862 1.010067 1.810972 1.515691 0.044783 0.082536 1.267984 0.419709 0.481882 1.832483 1.839130 0.674123 0.733681 1.236692 0.099256 1.206529 1.152388 -0.150515 0.755739 -0.177039 0.279539) ) ;;; 75 prime -------------------------------------------------------------------------------- (vector 75 13.254356384277 (fv 0 0 0 1 0 1 1 0 0 0 0 1 0 0 1 1 0 0 0 0 0 0 1 0 1 1 1 1 1 0 1 0 0 1 1 1 0 1 0 1 0 1 1 0 0 1 0 0 1 1 0 1 0 1 1 1 0 0 0 0 0 0 1 0 0 1 1 0 0 1 1 1 0 1 1) 11.022299 (fv 0.000000 0.351470 1.008124 1.291533 1.352523 1.219130 1.555492 -0.093523 0.793123 1.710126 0.845582 1.377487 0.007190 1.144398 0.030789 1.388046 0.801302 1.006307 1.228947 1.174967 0.712656 1.235684 0.437185 1.685920 1.628311 0.432535 1.406407 0.211487 1.631733 1.309990 0.088839 1.823347 0.645147 0.984102 0.938592 0.791055 1.200055 1.653923 1.369127 1.660169 1.684809 1.277014 1.423374 1.618705 1.761213 0.185242 0.737016 0.819843 1.700256 1.790111 1.582839 0.397943 0.430644 0.413691 1.861593 0.597392 0.781277 0.169222 1.035252 0.907321 0.225899 -0.109171 1.673244 0.994007 0.840763 0.321135 1.684359 1.522767 0.808080 0.918598 -0.016940 0.115899 0.890010 0.043957 1.335248) ;; 74+1 10.845278 (fv 0.000000 0.303549 1.218741 0.552551 0.569127 0.472240 0.245073 0.036162 0.777257 1.317108 0.637687 1.223165 0.113140 1.175025 0.935816 0.812633 0.204261 0.775370 -0.063348 1.606612 -0.062866 1.039670 1.212702 1.714844 1.899468 1.335566 -0.020119 1.590425 0.290190 1.193213 1.001576 0.516379 0.026311 0.170930 -0.096650 -0.315084 0.554428 0.144183 1.271300 0.005031 0.147859 0.041442 -0.048782 1.533805 1.480719 1.134329 1.851707 1.704199 0.286268 0.581546 0.690124 0.731502 1.497188 1.734408 1.013517 -0.010349 1.506433 0.024492 0.040181 1.200857 0.486442 0.422051 1.858040 1.837071 0.586958 0.629092 1.226159 0.139529 1.240473 1.272372 -0.245955 0.719958 -0.223615 0.281302 0.252047) ) ;;; 76 prime -------------------------------------------------------------------------------- (vector 76 13.288178191792 (fv 0 0 0 1 0 1 0 1 0 1 0 1 1 1 1 0 1 1 1 1 0 0 0 0 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 1 1 0 0 1 0 1 1 0 1 1 0 0 0 1 1 0 1 1 0 1 1 1 0 0 0 0 1 0 0 0 1 0 1) 11.052689 (fv 0.000000 1.173531 0.914653 0.927606 1.833325 0.572990 1.228121 1.340974 0.777818 0.101179 0.922381 0.727758 0.848668 1.622591 0.600587 1.207357 0.483679 -0.135739 0.789693 0.557916 0.529588 0.315324 1.810649 0.126643 0.909249 1.640326 1.342327 -0.052236 0.755820 1.799623 0.462177 -0.288032 0.651075 1.169254 1.824988 0.704237 0.880995 1.859829 0.036089 0.149448 0.542052 0.160045 1.646079 0.860838 1.752249 1.025660 0.604221 0.046575 0.711402 1.553525 1.214111 0.036075 0.479955 0.029596 1.070090 1.208893 1.207610 0.470868 0.758081 1.507527 0.678107 0.675805 1.580182 1.324295 0.061587 0.955350 1.218409 1.880195 0.596793 0.165057 0.646006 0.454851 -0.080576 1.833376 0.764382 0.602862) ;; 75+1 10.919127 (fv 0.000000 0.249051 1.283752 0.578538 0.465889 0.328282 0.397520 0.048700 0.732044 1.506763 0.870470 1.024466 0.125905 1.199969 1.200490 0.828996 0.327349 0.743916 -0.083081 1.581866 -0.022026 1.010771 1.314126 1.641110 1.977207 1.418126 -0.002727 1.553515 0.292061 1.103162 1.068475 0.567360 0.089633 0.183619 -0.243814 -0.246117 0.459882 0.118225 1.182209 0.017390 0.042772 0.114593 -0.081235 1.493721 1.405420 1.147867 1.909741 1.653034 0.237976 0.515913 0.601555 0.768092 1.451311 1.697940 1.055226 -0.095470 1.438708 0.052821 -0.122724 1.275935 0.441115 0.338376 1.822506 1.852761 0.555244 0.752898 1.362553 0.167682 1.066534 1.298923 -0.414288 0.895495 -0.078589 0.121695 0.415788 -0.032714) ) ;;; 77 prime -------------------------------------------------------------------------------- (vector 77 13.158900260925 (fv 0 0 0 1 0 0 0 0 0 1 0 0 1 1 1 0 0 1 1 0 1 1 0 0 1 1 1 1 1 1 0 1 1 1 0 1 1 1 0 1 0 1 1 1 1 0 1 0 1 1 0 1 1 0 0 0 1 1 0 1 1 0 1 0 0 0 0 0 0 1 0 1 1 1 1 1 1) 10.802937 (fv 0.000000 1.170348 0.872365 1.938370 0.176318 1.425001 1.816351 0.600885 0.838206 0.617008 0.862854 1.459906 1.685266 -0.294339 0.340282 0.188975 1.272363 0.222263 0.754500 0.303643 1.420294 0.520239 1.223316 1.153660 0.209190 1.335123 1.331714 0.719154 0.909245 -0.009852 0.827474 -0.139034 0.531790 0.623898 0.587466 0.935238 0.452213 -0.149439 0.923750 0.885640 -0.429219 0.037445 0.354080 0.150061 0.302072 1.423031 0.130250 -0.009435 0.571653 0.410660 0.194501 1.802956 0.455392 0.509514 1.619972 1.373513 1.082720 1.024058 0.798330 0.005055 0.529388 0.193199 0.652877 0.658529 1.505933 1.232728 0.171053 1.366924 1.004855 0.355582 1.506276 0.574068 1.502183 1.005869 -0.239104 1.730993 -0.006156) ) ;;; 78 prime -------------------------------------------------------------------------------- (vector 78 13.498236182018 (fv 0 0 1 1 0 0 0 1 0 0 0 0 0 1 0 0 1 1 1 1 0 1 0 0 0 1 0 1 1 1 0 1 0 0 1 0 0 0 1 1 1 0 1 0 1 0 0 1 0 0 0 1 0 1 0 0 0 0 1 1 0 0 1 0 0 0 1 1 1 1 0 0 0 1 1 0 0 1) 11.128810 (fv 0.000000 1.556151 1.350766 1.079560 1.627456 1.824396 0.970239 1.719188 0.076491 0.356551 0.956437 1.450393 1.649467 1.028644 0.913293 0.244507 0.114759 1.070289 1.644113 1.454817 0.980418 0.918084 0.619510 1.767585 1.807117 0.656270 1.762010 0.672983 0.042023 -0.071247 0.983492 -0.081135 0.135693 0.114828 1.357805 -0.252941 1.850579 1.671928 0.257832 0.920719 0.631282 0.706947 1.321680 1.346893 -0.182371 -0.272451 0.054087 1.657623 0.055118 0.350677 1.314600 0.063294 0.902678 0.105522 1.670846 0.405032 -0.075578 -0.012369 -0.068016 1.298918 0.818077 -0.266776 0.759067 0.508057 -0.040066 1.459059 0.532881 1.133191 1.019843 -0.486096 1.086169 0.894532 1.300427 1.601490 0.616399 1.768752 1.000095 1.636458) ;; 77+1 11.104393 (fv 0.000000 1.124037 0.854979 1.945811 0.208140 1.468398 1.815990 0.611918 0.912844 0.730140 0.961369 1.376309 1.803559 -0.243021 0.398976 0.193476 1.338837 0.340346 0.793855 0.341671 1.410779 0.565778 1.176931 1.048390 0.277106 1.445162 1.185150 0.642492 0.933385 0.019030 0.859542 -0.113411 0.532157 0.598476 0.550518 0.931780 0.311264 -0.108835 0.867767 0.932278 -0.351004 0.021213 0.390636 0.076987 0.338139 1.457487 0.082705 1.889708 0.513158 0.413795 0.138548 1.809057 0.494899 0.552125 1.690745 1.358244 1.250637 0.989495 0.775385 1.847135 0.528873 0.242941 0.558866 0.669472 1.484739 1.334473 0.249966 1.409992 1.022049 0.346238 1.534652 0.641930 1.394789 0.932978 -0.210333 1.769933 -0.083609 -0.106856) ) ;;; 79 prime -------------------------------------------------------------------------------- (vector 79 13.178678233398 (fv 0 0 1 0 0 0 1 1 0 0 1 0 1 1 1 1 1 1 1 1 1 0 1 0 1 0 1 1 0 1 0 0 0 0 1 1 0 0 0 0 1 0 1 0 1 0 1 0 0 1 1 0 0 0 0 0 1 0 0 1 1 1 0 0 0 1 0 1 0 0 0 0 0 1 0 1 1 0 1) 11.177833 (fv 0.000000 1.310798 1.470398 1.323367 0.553981 1.135824 0.783258 1.090444 0.524280 1.788975 1.639185 0.764585 0.676397 1.561727 -0.046007 0.428923 1.763449 0.011640 0.636361 1.341212 0.004579 1.608860 0.575061 0.243266 0.907181 0.977184 1.726699 0.431482 0.140827 0.464141 1.057140 1.400168 0.289408 0.838151 1.631807 1.530460 1.501458 0.566438 1.487014 0.015110 1.680036 1.296993 1.364424 0.039821 1.528230 0.589464 0.715462 0.552663 -0.017058 1.149326 1.516482 -0.030051 0.582733 -0.149911 0.234725 0.517539 1.013720 0.964483 -0.295150 -0.068887 -0.069035 1.472439 0.368231 1.600803 0.316013 0.723864 0.014324 0.524613 1.419685 1.673198 -0.043005 -0.029455 1.487321 1.686189 1.173017 1.833259 1.763911 1.426155 0.892867) ) ;;; 80 prime -------------------------------------------------------------------------------- (vector 80 13.547472953796 (fv 0 1 1 1 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 0 0 0 0 1 0 0 1 0 1 1 1 1 1 1 1 0 0 0 1 1 1 0 0 1 1 0 0 0 1 1 1 1 0 1 0 0 0 1 1 0 0 0 0 1 0 1 1 1 1 1 0 0 1 0 0 1 0 1 0 1) 11.451369 (fv 0.000000 -0.011188 0.391305 0.222144 0.025668 0.977359 0.513223 0.531901 0.360643 0.616841 1.341911 0.888846 1.600347 1.373974 0.123418 0.279769 -0.016126 0.463887 1.222914 1.957299 0.569052 1.699668 0.580517 1.202146 1.407428 1.172831 0.507495 0.800333 0.267556 -0.108002 1.745992 0.435164 1.044228 1.843822 0.030677 1.871048 0.542929 1.649600 0.514183 1.864352 0.330625 0.131744 0.409433 0.986423 1.602974 0.780283 0.138004 1.178452 0.747173 1.116954 0.917346 0.796903 0.356061 1.164738 0.640385 1.216938 0.366648 0.258624 0.900284 0.041536 1.817962 1.403113 1.192348 0.700576 1.370480 0.286847 0.603480 0.172807 1.255252 0.148259 1.272121 0.592895 1.744785 0.951797 1.489669 1.384870 1.365248 1.727217 1.576364 1.630892) ;; 79+1 11.248369 (fv 0.000000 1.320660 1.562587 1.230907 0.791500 1.111831 0.776332 1.212269 0.471199 1.929248 1.797736 0.814341 0.620835 1.395121 -0.166860 0.291055 1.737100 0.070444 0.531137 1.293083 0.075352 1.711864 0.539841 0.274514 0.922582 0.992421 1.608388 0.391268 0.216699 0.537576 0.886521 1.411196 0.301396 0.827503 1.619143 1.601542 1.558307 0.639158 1.445488 -0.167072 1.736837 1.279584 1.414784 0.077225 1.537483 0.689000 0.730293 0.519349 -0.104713 1.140696 1.722734 -0.057361 0.493518 -0.183111 0.352303 0.572659 0.917617 1.016232 -0.317574 -0.040058 -0.065357 1.491653 0.416263 1.654521 0.241001 0.536870 0.065165 0.568896 1.612372 1.840754 0.054958 0.057425 1.377368 1.668931 1.097005 1.763836 1.887359 1.244817 0.894926 -0.107373) ) ;;; 81 prime -------------------------------------------------------------------------------- (vector 81 13.652944564819 (fv 0 0 0 1 0 0 0 0 0 0 1 0 1 1 1 0 0 1 1 0 0 0 1 0 1 0 0 1 0 0 1 0 1 0 1 0 0 0 1 0 1 0 0 0 0 1 0 0 1 1 0 0 0 1 1 1 1 0 1 0 0 1 1 0 0 1 1 1 1 0 0 0 0 0 1 1 0 0 1 1 1) 11.500874 (fv 0.000000 0.060156 1.198187 0.010810 -0.059627 1.336892 0.174682 0.177182 0.303039 0.507728 0.174616 0.162104 0.767672 0.283268 0.740356 1.244073 0.411651 0.771082 0.597722 1.646364 0.130092 1.399674 1.196320 1.542256 1.814795 0.969378 1.368552 0.008802 1.647015 1.538679 0.957584 0.562757 0.185463 0.612441 1.264483 1.129777 -0.291833 0.231345 1.808426 -0.095607 1.827790 0.807634 0.929515 0.025793 1.640598 1.271614 1.470525 0.036943 0.657753 0.872430 1.519719 0.128077 0.109048 0.492656 -0.089269 0.591629 -0.109776 0.882829 0.675418 0.557752 1.879709 0.050861 1.363712 1.313213 0.120759 0.673965 0.894225 1.390640 -0.198915 1.435867 0.650146 0.682721 0.919339 1.509191 0.176654 0.428794 0.550059 1.279511 0.067206 1.270072 0.509792) ;; 80+1 11.318789 (fv 0.000000 1.312875 1.595991 1.250300 0.860994 1.125394 0.798611 1.212371 0.450471 1.878426 1.854513 0.914795 0.516574 1.401974 -0.113348 0.191503 1.535380 0.090102 0.579969 1.358286 0.094046 1.749820 0.409421 0.342346 0.891748 1.034938 1.701846 0.411592 0.161183 0.550475 0.945261 1.433769 0.390250 0.782945 1.725670 1.526810 1.626189 0.651868 1.370885 -0.153655 1.876481 1.236862 1.409437 0.102929 1.494796 0.718278 0.752798 0.534726 -0.125235 1.053652 1.624242 -0.009527 0.513674 -0.193412 0.274147 0.590252 0.888478 1.001277 -0.294725 -0.017970 0.022617 1.502755 0.474472 1.669991 0.292823 0.423633 -0.068585 0.472411 1.717891 1.789153 0.120369 -0.013158 1.253256 1.671744 1.049132 1.799303 1.831390 1.289936 0.966946 -0.056458 0.096803) ) ;;; 82 prime -------------------------------------------------------------------------------- (vector 82 14.126787045134 (fv 0 1 0 1 1 1 1 0 0 0 1 1 1 0 0 0 1 1 1 0 1 1 0 0 0 1 0 0 1 0 0 1 1 1 1 0 1 1 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 0 0 1 1 0 1 0 0 1 0 1 1 0 1 1 1 1 0 1 0 0) 11.462533 (fv 0.000000 1.174537 -0.036810 1.449073 0.002634 1.412064 0.527823 1.690777 0.901678 -0.091711 1.027422 0.397477 1.526657 0.088004 0.143741 1.426347 1.215238 1.051627 0.132305 0.242096 1.932884 0.204037 1.515523 0.068047 0.117753 1.158626 0.459284 1.081363 0.079849 0.326802 0.035989 0.012387 0.861938 0.605551 1.407324 0.411725 0.979703 0.090881 0.271335 0.152506 0.410872 1.149930 0.566324 1.611304 1.416641 0.010695 1.743925 0.323768 0.693725 0.691039 0.186118 0.191067 0.629603 -0.034867 0.109309 0.522152 1.478755 1.337464 1.245454 -0.020762 0.796712 1.449381 1.763960 0.000713 0.577015 1.247460 1.754051 1.376869 0.724941 0.407841 1.068454 1.226119 0.726352 1.657000 0.543820 1.177669 0.881363 0.120220 0.019239 0.418519 0.727327 0.208388) ;; 81+1 11.476728 (fv 0.000000 1.354025 1.769404 1.190492 0.845403 1.129164 0.681502 1.298591 0.526568 1.843796 1.839481 0.929391 0.545970 1.407502 -0.189236 0.155330 1.457831 0.110325 0.689064 1.222186 0.140271 1.863572 0.397423 0.425505 0.924253 1.034491 1.746896 0.221413 0.062871 0.570198 0.961166 1.514028 0.333971 0.850400 1.784003 1.484569 1.642647 0.680600 1.387654 -0.169385 1.868168 1.192895 1.317483 0.057642 1.550333 0.713537 0.826588 0.568782 -0.116091 1.031193 1.647713 0.076692 0.476679 -0.258739 0.325137 0.519423 0.928625 1.015174 -0.230419 -0.032172 0.037533 1.492936 0.495027 1.663321 0.378454 0.435791 -0.107582 0.529403 1.716992 1.827784 0.057964 -0.044990 1.256674 1.627386 1.007381 1.757651 1.738780 1.265746 1.051412 0.004277 0.076991 0.034105) ;; 83-1 11.480416 (fv 0.000000 0.454164 1.374754 0.722227 0.986349 1.377355 1.172894 0.123589 1.410636 1.726879 1.302862 1.602018 1.474058 1.472070 0.412168 1.770446 1.982011 1.625710 0.940561 0.534669 0.102735 0.053883 0.631657 1.350304 0.393669 0.521507 -0.049446 0.629634 1.041110 1.379158 -0.156331 1.690517 0.010013 1.800842 0.947691 1.681261 1.009361 1.763476 0.941228 1.218725 1.847726 0.614247 1.223796 0.150627 0.820237 0.298534 1.321472 0.537094 1.742045 0.701084 0.211813 0.587227 0.340134 0.598492 1.566318 1.525148 0.920822 1.421639 1.608617 0.590851 0.062396 0.476310 0.647458 0.340763 1.923701 0.385843 0.256835 1.446458 1.741785 0.470072 1.939455 0.907485 0.836540 0.652790 1.796743 1.327810 0.106788 1.646107 1.364400 0.210392 0.634295 1.443213) ) ;;; 83 prime -------------------------------------------------------------------------------- (vector 83 14.019070339131 (fv 0 1 1 0 0 0 1 1 0 1 1 0 1 0 0 1 0 1 0 0 1 0 0 0 1 1 1 0 1 1 1 0 0 0 1 0 0 1 0 0 1 0 0 0 0 0 1 1 1 1 0 0 1 0 1 1 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 1 1 1 0 0 1 1 1 0 0 0 1) 11.495305 (fv 0.000000 0.489724 1.459665 0.744876 0.880930 1.487259 1.179525 0.143969 1.398705 1.711637 1.229644 1.599300 1.480153 1.405136 0.390934 1.640936 1.928348 1.588509 0.860260 0.449815 0.093357 1.993956 0.692831 1.455573 0.371844 0.551569 -0.014841 0.652289 1.000821 1.372208 -0.157122 1.697110 0.020676 1.736939 1.000046 1.712927 0.862704 1.740081 0.913067 1.344458 1.894797 0.629049 1.175321 0.159464 0.992773 0.367516 1.362985 0.576721 1.753109 0.776625 0.227603 0.452205 0.315264 0.636900 1.541376 1.554828 0.983967 1.431020 1.527430 0.561443 -0.018728 0.579720 0.634527 0.252657 1.931947 0.472631 0.403447 1.506115 1.700022 0.443875 1.857223 0.863365 0.830784 0.658374 1.791596 1.216322 0.200510 1.645886 1.544611 0.129139 0.651447 1.366065 0.329410) ) ;;; 84 prime -------------------------------------------------------------------------------- (vector 84 14.024940956301 (fv 0 1 0 1 1 0 0 0 1 1 0 1 0 0 0 0 1 1 0 1 1 0 1 0 0 1 1 0 1 0 0 1 0 1 1 0 0 0 0 0 1 0 0 1 1 1 1 1 1 0 1 0 0 0 0 0 1 0 0 0 0 1 1 0 0 0 0 0 0 1 0 0 0 0 0 1 0 1 1 0 1 1 1 0) 11.536851 (fv 0.000000 1.288171 1.222912 1.421316 0.994256 1.309106 0.862461 -0.365885 -0.460542 0.530989 0.804830 1.140139 0.788715 0.769440 0.941320 -0.061500 1.897753 1.285116 0.647118 0.948482 1.478812 1.645309 -0.360540 1.475165 0.480180 0.398442 1.131834 0.453887 0.828958 0.223971 1.033478 0.103677 1.715711 0.595485 0.422094 0.246530 1.081093 0.706350 0.534924 0.737096 0.520740 1.348231 0.027898 1.430351 0.071366 0.456025 1.024992 0.563780 1.148663 1.244878 0.023430 1.078768 -0.035007 1.108834 0.481954 -0.628990 0.715248 0.675907 1.709977 0.563135 1.037605 0.888801 0.556599 0.958729 0.571715 1.126122 -0.072129 1.378438 0.187340 0.783805 0.989989 0.112073 -0.183972 1.388719 1.544777 0.651714 0.568338 1.234814 0.056527 0.901152 1.674263 0.800528 0.192396 0.655541) ) ;;; 85 prime -------------------------------------------------------------------------------- (vector 85 14.253310943921 (fv 0 0 1 1 1 0 0 0 1 1 0 0 1 1 1 1 0 1 1 1 1 0 0 0 0 0 1 1 0 0 0 0 0 0 0 1 1 1 1 0 1 0 1 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 1 0 1 1 1 0 0 1 1 1 0 0 1 0 0 1 0 1 0 0 0 0 0 0 1 0 1) 11.588928 (fv 0.000000 0.051144 0.232251 1.722677 0.580164 1.682133 1.175152 1.551429 1.040385 1.746433 0.629958 1.774843 0.701195 0.931344 1.300787 -0.092863 1.300643 1.259885 1.530011 1.258206 1.393028 0.930782 0.485840 1.244517 -0.032618 0.062247 0.154622 1.065009 0.904299 1.262092 0.852812 0.408235 0.633914 1.770716 1.085864 1.265219 1.003699 1.255985 1.195701 1.382932 0.704891 0.246143 0.639193 1.457010 0.146909 1.982729 0.165366 1.294717 0.624758 1.669440 0.868773 0.953753 0.230896 0.915079 -0.212743 0.773612 0.218470 1.122339 1.601419 1.730078 1.474786 -0.488722 1.796889 1.514239 1.703114 -0.437786 0.743917 1.859124 1.287147 1.160254 0.159597 0.817545 1.148746 -0.204270 1.716652 0.382598 -0.057580 0.598631 0.343212 0.230053 1.103741 1.603024 0.720362 -0.247891 -0.077598) ) ;;; 86 prime -------------------------------------------------------------------------------- (vector 86 14.017106967247 (fv 0 0 1 1 1 0 0 1 1 0 1 1 1 1 0 1 1 0 1 0 1 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 1 0 0 0 0 0 1 1 1 0 1 1 0 0 0 0 0 0 1 1 0 0 1 0 1 0 0 0 1 0 1 1 0 0 1 0 0 1 1 0 0 0 0 1 0 1 1 1) 11.517897 (fv 0.000000 1.259153 0.753054 1.764686 1.049517 1.125067 1.190973 0.991011 1.742456 0.708907 0.178161 0.559310 1.128716 0.240782 0.729992 0.303371 0.569838 1.273658 0.861674 0.290602 0.694623 0.362989 0.243116 1.696103 0.326714 1.481176 0.105867 1.763155 0.389638 1.096089 1.860461 0.384795 1.595111 0.327309 0.224303 1.457357 0.863276 1.221159 0.474861 0.148710 1.484645 1.778010 1.802629 1.714822 1.122256 0.709074 0.540633 -0.317254 0.997156 1.115917 0.123376 1.869025 1.339712 0.876345 1.682733 0.893530 0.998209 1.642978 1.224902 0.836368 1.948885 0.464451 1.058190 1.080864 1.538683 1.521142 0.009248 0.654339 -0.126350 0.282369 0.636445 1.771914 0.323435 1.302976 0.483884 1.466774 1.898584 0.571020 1.479654 0.824385 0.735539 0.638514 1.340179 1.302713 1.869702 1.497079) ) ;;; 87 prime -------------------------------------------------------------------------------- (vector 87 13.98394199918 (fv 0 0 0 0 1 0 0 1 0 0 1 1 0 1 0 0 0 0 1 1 0 1 0 1 1 1 0 1 0 0 1 0 0 1 1 1 0 0 1 1 1 1 1 0 0 0 1 0 1 1 0 1 1 0 1 1 1 0 0 1 0 0 1 0 0 0 1 0 0 1 1 1 0 1 0 1 1 1 1 1 1 1 1 0 0 0 0) 11.888688 (fv 0.000000 0.482398 1.227138 1.272721 0.078687 1.831113 1.162310 1.536977 1.689231 0.888900 -0.147273 1.167875 0.136674 0.075484 0.629027 1.034119 0.307327 0.024754 1.634526 1.779718 -0.119653 0.312698 0.930420 1.385321 1.107173 1.761414 0.822994 0.223996 0.948219 0.050573 1.181566 -0.076310 1.414999 0.950580 1.442020 0.563152 0.962072 1.833788 0.503591 1.266688 1.037104 0.455604 0.146748 1.270845 0.375842 1.270415 0.973599 0.773789 1.316233 0.694384 1.909797 0.637408 1.683609 1.640242 0.084358 0.069276 0.823261 1.794579 0.489470 1.507812 0.467715 1.270885 1.378929 1.892053 0.446100 1.349825 1.591977 0.875580 1.281794 0.089884 0.566164 1.762552 1.251149 0.938610 1.580460 1.542270 0.684665 0.182715 1.926062 0.347598 0.716836 1.752700 1.597850 1.520331 1.622999 0.031320 1.757914) ;; 86 + 1 11.612976 (fv 0.000000 1.296504 0.726706 1.718822 1.046681 1.126904 1.153426 0.940241 1.708793 0.818644 0.107576 0.530980 1.122499 0.334577 0.735679 0.325192 0.616360 1.132997 0.845995 0.287311 0.640223 0.397260 0.270000 1.691583 0.368381 1.503691 0.176791 1.719860 0.415279 1.070108 1.956631 0.329587 1.654694 0.271910 0.194847 1.468802 0.897532 1.267673 0.483007 0.130123 1.446495 1.802533 1.802082 1.708319 1.123221 0.822012 0.552025 -0.324423 0.903301 1.074684 0.198879 1.961955 1.280447 0.787297 1.695626 0.996555 1.020892 1.595011 1.302967 0.813723 1.889725 0.419999 1.093466 1.051442 1.549928 1.587010 -0.012516 0.597662 -0.094834 0.261495 0.632231 1.919100 0.281141 1.272306 0.493568 1.244869 1.877721 0.661378 1.459138 0.814695 0.650143 0.614249 1.318253 1.365141 1.852338 1.532615 -0.014292) ) ;;; 88 prime -------------------------------------------------------------------------------- (vector 88 14.825139803345 (fv 0 0 0 0 1 0 1 1 0 1 1 0 0 1 0 0 0 0 0 0 1 0 1 0 1 1 1 1 1 0 1 1 1 0 0 1 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 1 1 1 0 0 1 0 0 1 0 1 0 0 0 1 1 0 0 0 0 1 1 0 1 1 1 1 0 0 1 1 1 1 0 1 1 0) 11.988941 (fv 0.000000 0.784577 0.582655 -0.034103 0.163974 0.329543 0.693568 0.791635 0.508446 0.396915 1.248395 0.826252 1.437835 1.346260 1.098554 0.836111 0.285181 0.833650 0.396981 0.462954 0.362450 1.183096 1.004262 0.908804 0.301743 1.532670 0.011752 -0.072123 0.996811 1.778401 0.688894 0.044599 0.465473 0.579840 0.996613 0.177680 1.437542 0.677747 1.616279 0.045690 0.566144 1.136899 0.636783 0.355278 1.821475 1.658271 1.588631 1.539506 1.624123 1.239000 1.605890 0.921379 1.791768 0.223451 1.057625 1.753981 0.669208 1.245749 0.682902 0.319986 0.831757 1.041603 0.551747 0.279645 1.731984 0.406762 1.759751 -0.021178 1.248606 0.309853 0.756421 0.658187 1.127576 -0.365423 1.909061 0.823437 1.017441 0.941761 1.686220 0.570407 1.741961 1.705746 1.303576 0.477079 0.894393 0.214957 1.446786 0.714971) ;; 87+1 11.814735 (fv 0.000000 1.368148 0.691154 1.687498 1.039684 1.203556 1.189736 1.006697 1.714307 0.763256 0.064985 0.571039 1.207048 0.283865 0.790295 0.371929 0.626841 1.136922 0.897180 0.250579 0.703180 0.367153 0.285039 1.638464 0.403793 1.574680 0.178418 1.768394 0.361495 1.131365 1.971622 0.329290 1.677397 0.231014 0.189969 1.483487 0.936641 1.267305 0.514462 0.133317 1.438805 1.804423 1.766680 1.772823 1.080035 0.819063 0.520465 -0.385910 0.897901 1.088041 0.197160 0.026953 1.297496 0.779688 1.684839 1.075719 1.000862 1.653028 1.332924 0.886650 1.939949 0.418280 1.124021 1.085155 1.563576 1.537898 -0.095926 0.685710 -0.089908 0.297752 0.611005 1.863915 0.336806 1.344864 0.522590 1.267887 1.872098 0.632836 1.388439 0.783559 0.644197 0.609366 1.338438 1.322505 1.876261 1.537568 -0.063978 -0.021791) ) ;;; 89 prime -------------------------------------------------------------------------------- (vector 89 14.69031483888 (fv 0 1 0 1 1 0 0 1 1 0 1 1 0 0 1 0 0 1 1 0 1 1 1 0 1 0 0 0 0 1 1 0 1 1 1 1 0 0 1 1 0 1 1 1 0 1 1 1 1 1 1 1 1 0 0 0 0 1 0 1 1 0 0 1 0 1 0 1 1 1 0 0 0 0 1 0 0 0 1 0 1 1 1 0 1 0 1 1 1) 12.145572 (fv 0.000000 0.358269 1.288170 -0.001864 0.867779 1.364244 1.109375 1.164634 -0.016236 -0.166115 0.449176 1.706240 1.833933 -0.037127 1.772608 0.464339 0.514549 -0.440413 0.091904 1.161505 1.250171 0.825773 0.104691 1.330145 0.165858 0.782047 0.989298 1.471958 -1.844798 0.511831 1.629263 1.091421 0.075823 0.883705 0.737372 1.834115 1.253424 0.188184 -0.236434 0.698883 0.462924 1.137084 1.094253 1.071593 1.735305 1.138289 1.560372 0.992360 1.412813 1.873908 0.448635 -0.005058 0.329007 1.672360 0.604898 1.727995 0.648160 0.750281 0.125793 1.632855 1.581670 1.571564 1.278678 0.191912 0.145586 1.306040 0.445369 -0.231408 -0.001410 1.354497 1.551515 1.659096 -0.403896 0.821589 1.439452 1.005908 1.563170 1.260522 0.450255 1.234179 0.926658 0.279960 0.002426 1.200149 1.285451 0.986678 0.303114 1.568249 0.304851) ;; 88+1 11.787567 (fv 0.000000 1.314164 0.689513 1.628993 1.144940 1.224705 1.150205 1.016059 1.723195 0.713105 0.005841 0.484975 1.239550 0.341275 0.773786 0.398433 0.655094 1.170929 1.038464 0.301899 0.723090 0.410530 0.287119 1.633201 0.260609 1.623354 0.115980 1.879009 0.455545 1.070015 0.017172 0.270422 1.692490 0.233092 0.152980 1.556192 0.883089 1.261531 0.502559 0.146173 1.438907 1.785157 1.804773 1.715166 1.064977 0.807912 0.565628 -0.439659 0.842957 1.290534 0.179519 -0.023924 1.443203 0.792272 1.565433 1.032012 0.991867 1.644953 1.337404 0.854036 0.023578 0.413260 1.087165 1.065012 1.583652 1.496116 -0.065654 0.692422 -0.146363 0.297624 0.616209 1.798178 0.385485 1.334745 0.400370 1.168196 1.828136 0.707167 1.548668 0.793572 0.670466 0.690206 1.451727 1.295947 1.819151 1.442501 -0.262177 -0.013858 0.006952) ) ;;; 90 prime -------------------------------------------------------------------------------- (vector 90 14.831111851861 (fv 0 1 1 0 1 0 0 0 0 0 1 1 1 0 0 0 1 0 0 1 0 1 0 1 0 0 1 0 0 0 1 0 1 1 0 1 1 0 1 0 1 1 0 0 0 1 0 1 1 0 1 0 0 1 1 1 1 0 1 1 1 1 0 0 0 0 1 1 1 1 0 1 0 1 0 0 0 0 1 0 1 1 1 0 0 1 0 1 1 1) 12.022848 (fv 0.000000 0.304537 1.829033 1.070382 1.207038 0.596236 0.255424 0.517237 0.518037 0.555724 0.263998 -0.092809 0.086181 1.031798 1.764620 1.155127 1.629595 1.381762 0.374989 1.817825 0.178145 1.717460 -0.421617 0.620765 1.435692 1.136975 0.618586 -0.142602 0.257261 0.632270 1.492625 0.098530 0.089288 1.438957 0.096419 -0.388671 1.239417 1.591519 1.418382 0.224847 0.327382 1.847389 0.645292 1.057386 0.245292 0.974759 0.113802 0.520412 0.536708 1.166960 -0.123664 0.466667 1.597708 0.387840 1.876598 1.035063 1.402503 0.035393 0.945965 1.170137 1.338358 1.449697 1.072439 0.060883 1.296995 1.652836 0.462073 1.502645 1.166005 1.209720 0.739421 0.202107 1.382598 0.210680 0.451167 1.145693 0.222332 1.637533 0.245553 0.987799 0.980876 1.068255 -0.276826 -0.417000 1.573560 0.382232 0.604329 -0.155944 1.170763 0.979682) ) ;;; 91 prime -------------------------------------------------------------------------------- (vector 91 14.702056847646 (fv 0 1 1 0 1 1 1 0 0 1 1 0 1 1 0 1 0 1 0 1 1 0 1 1 0 1 0 0 0 0 0 0 0 1 1 0 0 0 0 1 1 0 0 1 0 0 0 0 0 1 0 1 1 1 0 0 0 0 1 0 0 0 1 1 0 1 1 0 1 0 1 1 0 1 1 1 1 1 0 0 0 0 1 1 0 0 0 0 1 1 0) 12.084424 (fv 0.000000 1.661963 0.526933 0.737897 1.547408 1.147810 -0.075617 1.067829 0.852458 1.831985 1.111705 1.210703 0.536594 1.562730 1.564495 0.931257 1.183443 1.206159 1.917460 -0.142965 1.673803 1.211553 1.446589 0.613092 0.971147 0.710033 1.752892 1.683084 1.418254 1.337958 1.028503 0.530465 0.358051 0.607198 0.374767 1.422247 1.801820 -0.023693 0.571429 0.547868 -0.171993 -0.069230 0.452658 0.503964 0.822577 0.139237 1.564879 1.109027 0.054201 0.693725 1.047747 0.930670 0.524559 -1.746051 0.764531 1.459015 0.440040 0.505370 1.433135 1.753190 0.597210 0.403986 1.752023 0.224587 -0.006227 1.424459 1.006632 1.837329 0.717913 1.423544 0.374217 1.561701 0.508321 0.662754 0.466739 0.959175 1.632864 0.950048 1.612332 0.591280 -0.303047 1.088472 1.746777 0.350796 0.275475 0.538357 0.642430 0.726819 1.423969 -0.019252 0.614624) ) ;;; 92 prime -------------------------------------------------------------------------------- (vector 92 14.556435035882 (fv 0 0 1 0 1 1 0 0 0 0 1 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 1 0 0 1 1 0 1 0 1 1 0 1 1 0 1 1 1 1 0 0 0 1 0 1 0 1 1 1 1 1 1 1 0 0 0 1 0 1 0 0 1 0 0 1 1 1 0 1 0 0 1 1 0 1 0 0 1 0 0 0 1 0 1 0 0 0) 12.111629 (fv 0.000000 1.123677 1.203180 1.174948 1.560019 1.384341 0.367155 0.099459 1.212291 0.682305 1.716557 0.261123 0.730999 0.903465 1.369526 0.155486 0.590372 -0.569988 0.244209 0.083007 1.764474 0.389454 0.365639 1.245993 1.816418 0.730704 -0.475666 0.929928 1.528963 0.279291 0.611191 0.845099 1.029972 1.753120 1.126371 1.838017 0.163977 1.146545 0.659479 1.341785 0.566953 0.273863 0.527929 0.012905 1.508411 1.113794 0.790470 1.810888 0.619444 1.306005 1.764955 0.757522 1.532832 1.638004 1.292139 -0.220293 1.326791 0.207925 0.021426 0.636407 0.595067 0.920176 1.364542 1.317600 0.792553 1.523336 0.199497 1.310295 1.126679 1.660906 0.580494 1.441629 1.307014 -0.149187 1.422606 1.228427 0.874268 1.519111 1.056591 1.949465 -0.426058 1.208008 1.301151 1.521711 0.452094 0.671757 0.665097 0.498102 0.181724 0.953835 0.725167 1.124133) ) ;;; 93 prime -------------------------------------------------------------------------------- (vector 93 14.994668960571 (fv 0 1 0 1 0 0 1 0 1 1 0 1 1 1 0 0 1 0 0 0 1 0 0 0 1 1 1 1 0 1 0 1 0 0 1 0 0 1 0 1 0 1 1 1 1 0 0 0 1 1 1 1 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 0 0 0 1 1 0 1 0 1 1 0 1 0 1 0 0 0 0 1 1 0 0 1) 12.323397 (fv 0.000000 0.199963 1.180724 -0.024343 1.226375 -0.402136 0.168523 1.313836 1.060714 1.370552 -0.471865 0.051393 1.826180 -0.226097 1.794079 0.176177 0.029279 1.765656 -0.022993 0.924413 1.319281 1.348871 0.657083 1.021102 0.556079 1.679658 0.119278 0.154784 0.786857 0.314106 1.909349 1.379970 0.486239 0.159940 1.547391 1.177792 0.671257 -0.176460 1.805002 1.892101 1.067471 1.153719 0.249337 0.426943 1.568658 0.284044 0.861446 -0.338286 0.531428 1.450755 0.605670 0.121121 1.131478 1.187561 1.041801 1.153378 1.486202 0.325760 0.201023 0.376157 0.907130 0.389618 0.779509 0.246617 0.355275 0.698575 1.371835 1.170196 1.188933 0.531048 0.008203 1.693556 0.426031 -0.330917 0.226068 0.478929 -0.022448 0.820583 0.181321 1.394112 0.214726 0.952096 1.780527 0.477402 0.370644 0.018381 1.506735 0.676340 -0.005190 1.098917 1.472044 0.136836 1.154585) ;; 92+1 11.941773 (fv 0.000000 1.137688 1.089778 1.068356 1.532544 1.432457 0.360804 -0.026160 1.251592 0.723161 1.753475 0.321792 0.652597 0.831785 1.248203 0.098788 0.605754 -0.620144 0.303325 -0.047105 1.719165 0.369582 0.426774 1.169373 1.859324 0.741230 -0.571365 0.881904 1.545056 0.328084 0.606744 0.850606 0.996606 1.766597 1.046556 1.767688 0.237622 1.228793 0.632423 1.337245 0.542894 0.162245 0.534219 0.069759 1.516061 1.102446 0.948393 1.619738 0.549855 1.379503 1.785272 0.859611 1.503940 1.656139 1.246212 -0.223489 1.412206 0.325338 0.101699 0.705391 0.747074 0.979316 1.385520 1.241306 0.625921 1.535144 0.140376 1.223617 1.154594 1.635856 0.580110 1.431599 1.354268 -0.085341 1.513604 1.083083 0.960280 1.481804 1.049034 1.936911 -0.305123 1.144650 1.328494 1.401780 0.463677 0.612788 0.648525 0.589928 0.274669 0.913704 0.769534 1.048236 -0.031107) ) ;;; 94 prime -------------------------------------------------------------------------------- (vector 94 14.811392756555 (fv 0 0 0 1 0 0 1 0 0 0 1 1 0 0 1 1 1 1 1 0 0 1 0 1 0 1 1 0 1 1 0 0 0 1 0 1 1 1 1 1 1 1 0 1 1 1 0 0 0 0 1 0 0 0 0 1 1 1 0 0 0 1 1 0 0 1 0 1 0 1 1 0 0 1 1 0 0 0 0 0 1 1 0 0 0 1 0 0 0 0 1 0 0 0) 12.372284 (fv 0.000000 0.443961 0.975468 0.665627 0.603420 0.053131 0.306985 1.398862 1.315822 1.027281 0.141353 0.068859 0.515109 1.551710 0.559483 1.154898 1.062171 1.088212 0.844250 0.492324 -0.085203 0.372997 1.377703 1.412362 1.590941 0.015253 -0.053671 1.084827 1.672259 1.823973 0.424632 1.792989 0.693404 1.273404 0.373397 1.282394 -0.222604 0.823730 1.821435 0.830056 0.905326 1.119027 0.338679 0.323132 1.572257 1.693368 1.617589 1.262068 1.377617 -0.071238 1.120960 0.924011 0.108375 0.409469 0.705856 1.358638 1.649735 1.159074 1.592832 0.679108 1.663652 1.223795 0.200633 -0.160917 1.201748 0.776569 0.821633 0.259058 0.902729 0.178012 1.711364 0.349704 0.758303 0.750335 0.936872 0.168192 0.485748 0.828259 1.367780 0.601135 0.970970 1.052074 1.846930 -0.031412 0.332694 1.027172 1.579686 0.520946 0.479472 0.979137 -0.124751 1.022187 0.809346 1.384445) ;; 93+1 12.114932 (fv 0.000000 1.123175 1.150884 1.058343 1.465121 1.413282 0.350764 0.114071 1.226428 0.791079 1.790932 0.440109 0.565381 0.734544 1.327723 -0.001005 0.566798 -0.729477 0.316829 -0.017120 1.801895 0.389351 0.381914 1.198959 1.820572 0.721571 -0.570163 0.955754 1.536499 0.370558 0.593528 0.885066 1.037479 1.768525 1.105455 1.756351 0.226836 1.186245 0.651550 1.384674 0.494435 0.218370 0.473389 0.034709 1.487137 1.083964 0.911945 1.641974 0.559886 1.326260 1.842092 0.870886 1.399307 1.629693 1.284916 -0.226560 1.347506 0.289919 0.059989 0.740638 0.739763 0.950849 1.395859 1.190558 0.656884 1.519451 0.124394 1.191107 1.225318 1.686413 0.517977 1.395642 1.256343 -0.098747 1.532037 1.044403 0.978522 1.573287 0.994934 1.946711 -0.367453 1.259056 1.292220 1.531327 0.451283 0.592779 0.641359 0.711046 0.198007 0.990565 0.746192 1.039960 -0.062670 0.073205) ) ;;; 95 prime -------------------------------------------------------------------------------- (vector 95 15.240 (fv 0 0 0 1 1 1 1 1 0 0 1 1 1 1 0 0 1 1 0 1 1 1 1 1 0 0 1 0 0 1 1 1 0 0 1 1 0 1 1 0 0 1 1 1 1 0 1 0 0 0 1 0 1 1 0 1 1 1 1 0 1 1 0 1 0 0 0 1 0 1 0 1 1 0 0 1 0 0 1 0 0 0 0 0 1 1 0 0 1 1 1 0 0 0 1) 12.459772 (fv 0.000000 0.308397 0.934622 0.587781 1.397996 1.615701 1.668964 1.492915 1.308563 0.159020 1.213403 -0.279408 1.096006 1.085558 0.623876 0.907176 0.667480 1.557434 1.743106 1.498468 1.233171 0.109361 0.947947 -0.262447 0.459131 0.819588 -0.021230 0.492364 0.906782 0.461816 0.056526 0.050587 0.383393 0.910532 0.762726 0.098762 0.955132 1.150421 0.604248 0.259751 1.309549 1.704622 1.855016 0.399458 0.217387 0.513436 1.433314 0.218651 0.133592 1.857292 0.423016 0.136928 0.083580 1.034506 1.391713 0.293770 0.897050 0.785540 0.765384 1.736279 0.958030 0.524446 0.709466 0.374572 1.361583 0.387916 0.039566 1.900932 -0.119192 0.460590 -0.150181 0.605728 1.448737 1.077599 1.714282 1.351134 0.667262 0.278426 0.183437 0.118876 0.258415 0.843668 0.748044 1.868376 0.252888 1.363041 0.638212 1.171836 0.388947 0.935784 0.020120 0.828215 -0.177354 1.862097 0.788220) ;; 94+1 12.114676 (fv 0.000000 1.049345 1.220803 1.147373 1.381621 1.355515 0.454825 -0.009436 1.057569 0.663900 1.874811 0.433507 0.556807 0.623352 1.242792 0.067786 0.465225 -0.661340 0.331985 0.032227 1.933091 0.432343 0.547379 1.107124 1.846431 0.517946 -0.547570 0.897607 1.611921 0.403112 0.647511 0.899598 0.890804 1.716130 0.996200 1.713540 0.243854 1.180551 0.688999 1.559934 0.583466 0.197293 0.600073 0.000101 1.458490 0.994760 0.956495 1.648139 0.660393 1.228976 1.774516 0.893844 1.390831 1.720570 1.135089 -0.091470 1.277862 0.255881 0.036343 0.799886 0.761090 0.891306 1.295964 1.096543 0.475861 1.537136 0.091181 1.218377 1.140426 1.690539 0.527790 1.400945 1.266740 -0.072678 1.541904 1.035302 1.038433 1.493972 1.075712 0.036991 -0.268077 1.190854 1.324282 1.468048 0.376266 0.545926 0.611626 0.692246 0.190910 0.902204 0.677044 1.063647 0.021187 0.238133 0.189775) ) ;;; 96 prime -------------------------------------------------------------------------------- (vector 96 15.135 (fv 0 1 1 0 1 0 1 1 0 0 0 0 0 0 1 1 1 1 0 0 1 1 0 1 1 0 0 0 1 1 0 0 0 1 1 1 1 0 0 0 0 1 1 0 1 1 0 0 0 0 0 0 1 0 1 0 0 1 1 0 0 0 1 1 0 0 1 1 1 0 1 1 1 1 1 1 1 1 0 1 1 0 1 0 1 0 1 1 1 1 1 1 0 0 1 0) 12.492843 (fv 0.000000 0.873070 1.523025 1.689063 1.621286 0.209607 1.316613 0.108148 0.756280 0.640008 0.419483 0.710721 0.117557 0.928853 0.153806 1.300975 1.239985 1.289571 0.156284 0.662086 0.349173 1.208328 1.779199 0.633972 1.299682 1.009543 0.022986 0.835814 1.094725 0.331638 0.023179 0.982537 0.733828 1.430422 0.013874 0.572853 1.429326 1.360223 0.715744 1.266448 0.151948 -0.250137 0.209445 1.031335 1.611402 0.877878 0.362241 0.304460 0.144893 0.651630 1.742329 -0.323477 0.366805 -0.060410 1.858308 0.038329 0.825659 1.544770 1.420995 1.255395 1.068254 0.786905 1.057541 1.015027 0.909813 1.295370 1.205379 0.957770 1.601794 1.221780 -0.114116 0.749254 1.369402 1.509613 0.642078 1.929687 1.163562 0.908511 0.510199 1.519292 0.122002 1.225494 0.717297 1.501496 1.345341 1.759811 1.056238 0.842883 0.086174 -0.090366 1.445692 1.226504 0.003120 1.148302 0.440021 0.622101) ;; 95+1: 12.292710 (fv 0.000000 0.988646 1.162429 1.171314 1.353255 1.405759 0.327802 0.036207 1.152154 0.760541 1.790856 0.433527 0.499858 0.656756 1.296573 0.100791 0.476489 -0.653216 0.158372 -0.037710 1.892726 0.409386 0.436140 1.049351 1.766476 0.708019 -0.505881 0.843836 1.661627 0.229932 0.569810 0.855526 0.889991 1.754840 1.079009 1.690629 0.282542 1.176826 0.695771 1.456983 0.462708 0.168189 0.469857 -0.027597 1.521311 1.099282 0.982686 1.576751 0.669770 1.287335 1.818933 0.859497 1.442403 1.798895 1.290873 -0.254434 1.216440 0.266504 0.064071 0.816920 0.860902 0.922870 1.417663 1.159681 0.595958 1.424400 0.223626 1.172296 1.139585 1.606147 0.520047 1.392856 1.257846 -0.113917 1.518583 1.050121 0.979442 1.573289 0.984941 0.063610 -0.290095 1.277068 1.272139 1.596596 0.361931 0.600022 0.601776 0.740696 0.153344 0.997841 0.670149 1.019583 -0.020870 0.222109 0.072606 -0.120463) ) ;;; 97 prime -------------------------------------------------------------------------------- (vector 97 15.404807595571 (fv 0 0 0 1 0 1 0 1 0 1 1 0 1 1 1 1 1 0 0 1 0 1 0 0 1 1 1 0 1 0 0 0 0 1 0 1 1 0 0 0 0 1 0 1 0 0 1 1 0 0 1 1 0 0 0 0 1 1 1 1 1 0 0 1 0 1 0 0 1 1 1 1 0 0 0 0 0 0 1 0 0 1 1 0 0 0 1 0 1 0 0 1 0 1 1 0 1) 12.614880 (fv 0.000000 1.284279 0.149066 0.562607 0.268625 0.641221 0.361525 0.485960 -0.169882 0.664945 1.289316 0.500133 0.276653 0.768466 1.755836 1.046199 1.488691 0.489610 1.701223 1.395902 0.323258 1.026098 0.187307 0.308257 0.739745 0.789576 0.492878 1.589801 0.464866 1.368873 1.280528 0.783754 1.321490 0.013196 1.554947 1.672951 1.438390 1.698792 0.240337 1.015821 1.431743 -0.194791 0.030419 0.391715 0.797023 1.035054 1.666367 1.927621 0.564941 0.590092 0.408995 0.415222 1.147686 0.588418 0.024767 -0.204650 -0.157255 1.351342 1.609704 0.733349 1.898358 0.761937 1.674424 1.298247 0.616295 1.801868 0.366757 0.227606 0.881755 0.435048 0.566914 -0.068726 1.464351 0.867461 0.114711 1.507714 0.831540 0.049432 0.189086 0.282295 1.125245 -0.244779 0.442202 1.591355 -0.090711 1.248227 1.649885 0.616280 1.727109 0.815894 0.698498 -0.049477 0.179382 1.436511 0.773196 0.738555 0.962998) ;; 96+1 12.398175 (fv 0.000000 0.974270 1.133417 1.101751 1.279979 1.359434 0.467927 0.007144 1.127487 0.748820 1.781756 0.396487 0.493733 0.688975 1.203401 0.019970 0.359263 -0.697201 0.166440 -0.073865 1.841340 0.479438 0.471569 1.120468 1.818011 0.722611 -0.578854 0.797365 1.619794 0.192675 0.470320 0.880530 0.894647 1.773867 1.129911 1.684306 0.298114 1.192448 0.753562 1.463120 0.415850 0.230519 0.523840 -0.047429 1.497367 1.045637 0.968082 1.645436 0.623475 1.314407 1.792633 0.841218 1.383624 1.923347 1.362714 -0.210443 1.197651 0.311815 0.117464 0.802332 0.840490 0.962756 1.351153 1.154240 0.658169 1.483444 0.257624 1.139948 1.196778 1.594898 0.489729 1.391360 1.298495 -0.114146 1.474319 1.038981 0.962592 1.548377 0.947581 0.030073 -0.290725 1.335845 1.310097 1.567936 0.325931 0.520450 0.493969 0.704044 0.140441 0.974535 0.754580 0.981153 0.043144 0.213245 0.187923 -0.104791 0.154449) ) ;;; 98 prime -------------------------------------------------------------------------------- (vector 98 15.435913738557 (fv 0 0 0 0 1 1 1 0 1 1 1 1 1 0 1 1 1 1 1 0 0 1 0 1 0 1 1 0 1 1 1 0 0 1 0 1 1 1 0 1 0 1 0 1 0 1 0 1 0 0 1 1 1 1 0 0 1 1 0 0 1 1 0 1 1 1 1 1 1 1 1 1 0 0 1 0 1 0 0 0 1 1 0 0 1 1 1 0 1 0 1 0 0 0 1 1 1 0) 12.753270 (fv 0.000000 0.786132 0.095307 1.867898 0.883791 1.021595 1.308123 1.131908 0.540702 0.504302 1.434468 1.493630 0.417411 0.284692 1.504062 1.429716 1.676581 -0.039254 0.683934 0.973509 0.648393 1.434613 -0.061544 1.814076 0.647769 0.683085 1.793781 0.237679 0.776690 1.663998 0.170625 1.433546 1.041819 1.122171 1.897558 1.320541 0.723949 1.237497 0.689348 1.846291 1.246028 1.446201 0.606616 1.671663 1.464134 0.585342 0.644021 0.435796 0.213425 1.357738 1.586232 1.545703 0.819890 1.367545 0.012567 0.450279 0.655234 0.788890 0.591992 0.545966 1.254900 0.392933 1.583204 0.076358 1.856160 0.823271 1.021281 1.623051 1.585893 1.245898 0.683755 0.476818 1.035792 1.047834 -0.069790 -0.004312 -0.361114 1.398618 1.383822 0.421997 1.705664 0.029556 -0.066198 0.051203 1.722364 1.322079 1.292928 1.662147 -0.016256 1.310728 1.707597 1.375469 1.546348 1.943030 -0.036451 0.558144 -0.266574 0.833410) ;; 99-1 12.622612 (fv 0.000000 1.601197 0.675735 0.824937 1.585712 1.856247 0.097348 -0.128093 1.025651 0.480455 0.954279 0.347491 0.626587 0.694458 0.898162 1.272532 0.684634 1.137767 1.643934 1.521275 1.047103 0.680901 1.232138 0.886175 0.603433 0.065324 -0.003442 1.143022 1.262279 1.001078 1.502240 1.539684 0.387527 -0.240796 0.914257 1.021072 0.830135 0.895349 0.823768 1.454208 -0.127486 1.570891 0.443883 0.892431 1.170381 1.366309 0.941425 0.702939 0.571855 0.280140 1.656638 0.472320 0.260055 1.153301 0.949715 0.148316 1.066487 0.427830 0.818544 -0.167385 0.411934 0.330689 0.887299 0.734213 1.728731 0.063612 0.466751 0.013162 -0.447231 0.444351 1.131814 0.061263 1.074639 0.944421 1.055502 -0.026068 1.648026 1.034453 1.399998 0.887501 0.104617 0.511260 1.435502 0.677269 0.344898 0.942483 -0.009809 0.923335 0.650809 -0.003419 1.067454 1.910756 0.250458 1.576481 0.901923 1.611933 1.145031 0.515175) ;; 97+1 12.554819 (fv 0.000000 0.994754 1.201978 1.095875 1.228090 1.349063 0.520404 -0.005278 1.113744 0.684830 1.821835 0.418458 0.556811 0.671609 1.340860 -0.027127 0.490888 -0.669559 0.196112 -0.069433 1.791636 0.479800 0.480819 1.161113 1.931188 0.706820 -0.575437 0.825517 1.635684 0.154310 0.437054 0.834616 0.805687 1.760916 1.041481 1.654400 0.268843 1.252679 0.716018 1.507696 0.427453 0.212559 0.610822 -0.045110 1.474585 1.069280 0.938458 1.658424 0.606033 1.274272 1.871557 0.851412 1.378375 1.849718 1.305539 -0.196977 1.250436 0.271972 0.159635 0.861188 0.835566 1.009947 1.382413 1.136755 0.601730 1.508016 0.177040 1.096731 1.112114 1.556213 0.514409 1.424495 1.306796 -0.096547 1.551938 0.983953 0.982538 1.547826 0.947292 0.070780 -0.301979 1.274952 1.268078 1.506608 0.343339 0.539960 0.515360 0.716545 0.138903 1.075775 0.830359 1.045994 0.028008 0.165284 0.183640 -0.064893 0.128193 -0.025514) ) ;;; 99 prime -------------------------------------------------------------------------------- (vector 99 15.391923904419 (fv 0 0 1 0 1 0 0 1 0 0 0 1 1 0 1 1 1 0 1 1 1 0 0 1 0 0 0 0 0 1 1 0 0 1 1 0 0 0 1 0 0 1 1 0 1 1 1 0 1 1 0 1 1 1 1 1 1 1 1 0 1 1 1 0 0 1 1 1 0 0 0 0 0 1 1 1 1 1 0 1 1 0 1 0 0 0 0 1 1 0 1 0 1 1 1 1 1 1 0) ;; started at 13.08 12.671121 (fv 0.000000 1.578825 0.666211 0.726552 1.538384 1.791570 0.099320 -0.160491 0.989473 0.596822 1.035192 0.247178 0.628445 0.721303 0.845175 1.341449 0.627742 1.157974 1.573300 1.577559 1.146243 0.642518 1.253235 0.873141 0.677674 1.983841 -0.058813 1.145842 1.258749 1.002052 1.540728 1.596826 0.319265 -0.110992 0.873225 1.001714 0.958663 0.883044 0.804615 1.392171 -0.105346 1.566142 0.586138 0.950489 1.209868 1.332589 1.087730 0.608633 0.545623 0.189852 1.681493 0.487350 0.405093 1.121113 0.988264 0.089589 1.002114 0.406924 0.857351 -0.106561 0.434389 0.315978 0.874454 0.677274 1.738995 0.126523 0.418419 -0.034288 -0.514474 0.544729 1.186629 0.091214 1.023974 0.889868 1.105258 -0.014030 1.568529 1.019817 1.384214 0.868550 0.027819 0.525808 1.447056 0.636493 0.394992 1.091277 -0.079518 0.886075 0.569418 -0.004838 1.104104 1.810908 0.227707 1.565455 0.923044 1.560572 1.031354 0.513130 1.131259) ) ;;; 100 prime -------------------------------------------------------------------------------- (vector 100 15.637986183167 (fv 0 1 0 1 0 0 0 0 1 1 0 1 1 0 0 1 0 1 0 1 1 0 1 0 1 0 1 0 0 1 0 0 0 1 0 1 1 1 1 1 0 0 1 0 0 0 0 0 0 1 0 0 1 1 0 1 0 0 1 0 0 1 1 0 1 1 1 0 0 1 1 0 0 1 1 0 0 0 1 1 1 0 0 0 0 1 0 0 1 1 0 0 0 0 0 1 0 0 1 1) 12.957637 (fv 0.000000 1.386453 1.370643 1.628038 1.538390 0.424621 1.485227 0.897618 0.907971 0.449160 0.163275 1.571834 1.093156 0.838120 0.247905 1.436852 0.372882 -0.220773 1.118451 0.054878 1.267282 0.565411 0.289581 0.731340 0.458703 -0.367224 -0.030109 0.334428 1.397987 0.598724 0.901920 1.214518 -0.004754 1.438150 1.307411 0.016366 1.337284 1.304934 1.171963 0.021267 0.117441 0.560545 0.340812 1.151463 1.666509 1.019303 -0.015114 0.880146 1.373879 0.049199 1.503584 1.604549 0.862952 0.189305 0.529694 1.029077 0.778339 1.706291 1.914727 1.273598 1.699313 -0.031345 -0.253493 1.258299 1.649412 1.077808 1.672514 1.251013 0.462905 1.384023 0.091088 1.738772 0.445974 1.424109 1.582876 1.988433 0.984011 1.200230 -0.169021 0.062775 1.511082 0.660711 1.089055 0.545793 1.273058 1.509833 0.626971 0.715771 1.564417 1.945654 0.972744 0.969507 1.754542 1.683747 0.602245 0.329311 0.710216 0.150434 1.629408 1.227167) ;; 99+1 12.716986 (fv 0.000000 1.614268 0.794652 0.719356 1.522693 1.839206 0.053187 -0.216045 1.077547 0.626072 0.992447 0.258424 0.613665 0.666154 0.797791 1.297151 0.666442 1.138663 1.568655 1.598721 1.081507 0.701607 1.189990 0.875992 0.670799 0.120588 0.002798 1.147193 1.214233 0.961367 1.487074 1.498267 0.315736 -0.163747 0.892348 0.853335 0.781180 0.904959 0.815695 1.365580 -0.161311 1.770543 0.467808 0.858870 1.202500 1.263259 1.179260 0.605694 0.567979 0.170780 1.783259 0.557899 0.419137 1.246376 1.015382 0.060732 1.143789 0.421313 0.784488 -0.191174 0.582308 0.326318 0.868037 0.700245 1.775099 0.084259 0.487674 0.052341 -0.505041 0.601192 1.234546 0.060079 0.970347 0.831571 1.221404 0.028687 1.689191 1.030841 1.384017 0.852184 0.054733 0.492124 1.493372 0.743678 0.351949 0.983070 -0.060785 0.924421 0.622513 0.041911 1.106639 1.715696 0.158455 1.595681 0.922989 1.564481 1.036395 0.544443 1.152503 -0.027178) ) ;;; 101 prime -------------------------------------------------------------------------------- (vector 101 15.735968313601 (fv 0 1 1 0 1 0 0 0 1 0 0 0 1 0 1 0 0 0 0 0 0 0 1 0 1 0 1 1 1 0 1 1 0 0 0 0 1 1 0 1 0 0 0 0 1 1 1 0 0 1 1 1 1 0 0 1 0 0 0 1 0 1 1 0 1 0 0 0 1 0 1 0 1 0 1 1 0 1 1 0 0 1 1 0 1 1 0 1 0 1 1 0 1 0 0 0 0 0 0 0 1) 12.909758 (fv 0.000000 0.720714 -0.182655 1.565457 0.753622 0.130143 0.334294 1.650697 0.417832 0.048827 0.344422 1.486401 0.292931 1.799521 1.111655 1.558792 -0.221559 1.531040 0.348578 0.973695 0.761485 1.268033 0.273978 1.313895 1.704221 0.068165 0.481602 0.743938 -0.351235 -0.099468 0.085867 1.467502 0.670175 1.060411 0.557784 1.309992 0.991970 0.107757 0.556296 0.077508 1.974081 0.189947 1.303789 1.238050 0.718111 0.534076 0.252095 1.598289 1.547761 1.182866 0.464613 1.755609 0.089102 1.246032 0.080260 1.036577 0.473927 0.107892 0.368036 0.986840 0.765140 -0.036059 1.290823 0.227451 0.726294 -0.006595 0.616819 -0.359117 0.861664 1.267742 1.139832 0.077396 1.257827 0.004277 1.664182 0.904514 1.106007 1.213475 0.580481 1.709443 0.640563 0.036194 0.492519 1.274675 0.574901 0.832654 0.371185 0.344722 0.998543 0.576680 0.369414 0.177252 0.865880 0.137875 0.239059 0.486022 1.121460 0.939339 0.230403 0.470154 0.464729) ;; 102-1 12.654378 (fv 0.000000 0.039802 1.217841 -0.018794 -0.264350 1.648606 -0.106572 1.436093 1.744759 1.197340 1.116039 0.322269 -0.319802 1.429760 1.337731 1.367755 1.294986 0.934427 1.178285 0.242928 0.397639 0.030160 0.470705 0.489509 0.721431 0.877160 0.586365 1.300090 0.056753 0.396042 0.694396 -0.123538 0.601882 1.828235 1.061453 1.208202 1.515734 1.300848 0.385739 1.295236 0.466727 1.125610 1.584167 0.360500 0.430768 1.515128 1.002486 1.429469 1.701067 0.146032 1.922601 1.668726 1.734188 0.898236 1.467655 0.751985 1.587598 0.572766 0.063367 1.242347 -0.141898 0.518327 1.188113 1.385035 1.498198 -0.400261 -0.058961 1.288706 1.366806 0.035365 1.606021 -0.052356 0.617357 0.512726 0.520602 1.405519 1.969640 -0.459289 0.438819 1.509996 1.047832 0.536024 0.230428 0.540739 1.290987 1.664498 0.615778 1.436029 1.298481 1.467348 0.158627 0.119363 1.098827 0.065055 0.380410 0.835569 0.455358 0.512707 1.391092 0.922515 1.335905) ) ;;; 102 prime -------------------------------------------------------------------------------- (vector 102 15.374809992584 (fv 0 0 1 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 1 1 0 1 1 1 0 0 0 0 0 1 0 1 0 0 1 0 1 0 0 0 0 0 1 1 0 0 1 0 1 1 1 0 1 1 0 0 1 1 1 1 0 1 0 1 1 0 1 1 0 0 1 1 0 0 0 1 1 1 0 0 1 0 0 1 0 1 0 0 1 1 0 0 0 1 0 0 0 1) 13.125163 (fv 0.000000 0.284570 1.185932 0.254020 0.458026 1.777924 0.273972 0.352012 0.871247 1.673334 1.496604 0.270045 1.591827 -0.188397 0.589501 1.091682 1.741121 0.196787 0.525310 1.321393 1.205053 -0.057392 1.556520 -1.961535 1.179860 1.122770 0.814829 1.500056 -0.069946 0.070497 1.237530 1.280644 0.820936 1.402645 0.152660 1.210341 0.842206 0.369359 0.105608 0.811471 0.529059 0.041857 1.655756 0.893298 1.337926 1.496211 1.428234 0.556092 0.432069 0.925348 1.205854 1.544664 1.704644 1.229630 0.303212 1.758935 1.188278 1.467436 1.586279 1.260300 1.300112 1.011729 1.695629 1.060370 1.604385 0.957028 1.624378 0.311506 0.745336 0.578867 0.572336 1.655636 0.424967 1.250130 0.974803 1.251963 1.312562 0.463398 -0.038700 1.540879 0.156800 0.564982 0.689178 0.544052 1.778377 0.813450 0.561441 0.695184 0.270384 1.438063 0.744019 1.224468 0.148794 1.411742 1.416148 0.158444 1.282043 0.332184 1.434585 0.991269 -0.118131 -0.014118) ;; 103-1 12.631141 (fv 0.000000 0.074843 1.219158 -0.027199 -0.254073 1.624605 -0.135701 1.453877 1.755897 1.198675 1.090421 0.272002 -0.249474 1.447439 1.360955 1.341148 1.290153 0.969167 1.135329 0.243792 0.418984 1.946250 0.601544 0.456951 0.765282 0.872982 0.576621 1.365615 0.094262 0.399525 0.677984 -0.086420 0.567433 1.780255 1.046981 1.205389 1.534885 1.234066 0.439028 1.336514 0.490354 1.104410 1.622676 0.382214 0.417306 1.496561 0.975909 1.398390 1.624475 0.141661 1.921427 1.688187 1.741843 0.901238 1.419496 0.813192 1.607447 0.585967 -0.020824 1.251511 -0.203691 0.513177 1.192285 1.326136 1.473869 -0.455142 -0.016589 1.259703 1.293519 0.048863 1.685391 -0.099881 0.662916 0.500247 0.557103 1.438861 1.941547 -0.474933 0.373608 1.542760 1.006189 0.593009 0.247793 0.539650 1.340923 1.675659 0.620550 1.469642 1.328665 1.442498 0.149610 0.049207 1.111223 0.085126 0.353623 0.826677 0.461777 0.518667 1.404379 0.899861 1.337308 0.525132) ) ;;; 103 prime -------------------------------------------------------------------------------- (vector 103 16.296298498866 (fv 0 0 1 0 1 1 1 0 0 1 1 1 0 1 0 1 0 1 0 0 0 0 1 1 0 1 1 0 1 1 1 1 1 0 1 1 0 1 0 1 1 1 1 0 0 0 1 0 1 0 1 1 1 0 0 1 1 1 0 1 1 1 0 1 1 1 1 0 0 0 1 0 0 1 0 1 0 1 0 0 0 1 0 1 0 0 1 1 0 1 0 0 0 0 0 0 1 1 1 1 1 1 1) 13.256855 (fv 0.000000 0.253687 0.364122 0.283681 0.599056 0.452778 1.412525 1.578158 0.723002 1.502688 0.469327 0.823618 0.138223 0.170924 -0.041881 1.730522 0.763213 0.124296 1.756004 0.298966 0.867744 1.163387 -0.026926 0.637630 1.135341 0.124472 0.638511 0.161082 1.417534 1.311969 1.355755 0.769867 -0.015620 1.263904 0.253925 1.195956 0.435477 0.207251 1.875570 0.589212 -0.141939 1.489218 1.811390 0.546189 -0.100127 1.137591 0.512565 0.982503 0.208205 0.661546 0.459680 0.647870 0.862493 1.703684 1.626808 1.293610 1.244032 1.833651 0.313984 0.098233 0.713078 -0.030639 0.471225 0.283054 1.436428 1.697146 0.363648 0.928407 1.232119 0.232840 0.986487 -0.076225 0.058237 1.691889 0.445904 1.400974 1.534686 0.353656 1.081845 0.844988 1.752497 1.490478 0.820514 0.624503 1.244095 0.481359 1.092852 1.038822 0.122193 0.306870 1.545599 1.882053 0.840143 1.618524 0.664876 1.172112 0.425428 1.063389 1.459465 1.132826 0.707914 0.476065 0.729618) ;; 104-1 12.891616 (fv 0.000000 0.020230 1.100455 -0.027655 -0.341498 1.573639 -0.166459 1.336909 1.614334 1.265242 1.070753 0.200336 -0.139945 1.315758 1.256048 1.330780 1.163466 0.897749 1.119686 0.362299 0.301310 1.883571 0.506864 0.431140 0.779158 0.861103 0.563763 1.317182 0.358448 0.581384 0.662511 -0.059228 0.585764 1.735705 1.134223 1.253804 1.488711 1.296145 0.401006 1.318547 0.409838 1.063168 1.784758 0.605346 0.454705 1.514331 1.036227 1.443746 1.590100 0.152638 1.937048 1.659118 1.596372 0.834928 1.202317 0.791629 1.638040 0.394481 0.036287 1.308852 -0.027851 0.483382 1.137070 1.471797 1.436021 -0.339247 1.959465 1.416371 1.274782 -0.056416 1.618621 0.073487 0.645516 0.465048 0.562814 1.499952 1.962975 -0.425202 0.177209 1.576794 1.092923 0.684292 0.216536 0.469811 1.278388 1.697283 0.494244 1.421192 1.305461 1.352595 0.145716 0.152674 1.146529 0.138563 0.239706 0.891463 0.397696 0.605319 1.317917 0.759776 1.395135 0.600443 1.308594) ) ;;; 104 prime -------------------------------------------------------------------------------- (vector 104 15.919013023376 (fv 0 1 0 1 1 0 0 1 0 1 0 1 0 0 1 1 0 0 1 1 0 1 0 0 0 0 1 0 0 0 1 1 0 1 1 1 1 1 0 1 1 1 1 0 0 1 0 1 1 0 0 0 0 1 0 0 0 1 1 1 0 1 1 0 0 0 0 1 0 1 1 1 1 0 0 1 1 0 1 1 0 1 0 1 0 1 1 1 0 1 0 0 1 1 1 0 0 1 1 0 1 0 0 1) 12.987392 (fv 0.000000 0.019656 1.020820 -0.122857 -0.383416 1.743762 -0.077551 1.285344 1.556500 1.347778 1.007108 0.271391 -0.017599 1.323289 1.224441 1.254961 1.192419 0.950226 1.083964 0.356128 0.296702 1.898956 0.423819 0.431784 0.740632 0.838009 0.555934 1.287966 0.437690 0.641910 0.602950 -0.082685 0.609730 1.650999 1.107220 1.287768 1.459073 1.340092 0.368618 1.276887 0.523746 1.035407 1.951274 0.598910 0.440828 1.523180 1.064599 1.442876 1.610632 0.084831 1.933213 1.678415 1.492367 0.869607 1.168981 0.759731 1.683066 0.461763 1.964877 1.344876 -0.085783 0.568560 1.208659 1.424190 1.445388 -0.303350 1.915514 1.421848 1.165687 -0.066096 1.641117 0.068094 0.584541 0.457188 0.559162 1.501643 1.956646 -0.560037 0.043217 1.538096 1.142301 0.678432 0.239030 0.380298 1.373491 1.617773 0.449327 1.348144 1.243227 1.328890 0.139617 0.253213 1.094223 0.214901 0.235818 0.939054 0.321415 0.563100 1.348449 0.703267 1.435425 0.687968 1.242454 -0.344280) ) ;;; 105 prime -------------------------------------------------------------------------------- (vector 105 16.038356734428 (fv 0 0 0 1 0 1 1 0 0 0 0 1 0 0 0 0 0 0 1 1 0 1 0 0 0 1 0 1 1 1 1 1 0 0 0 1 0 1 0 0 0 0 1 1 1 0 0 0 0 0 0 0 1 1 0 1 0 1 1 0 1 1 1 1 1 1 0 0 0 0 1 1 0 0 1 1 1 0 0 1 1 1 0 0 0 1 1 0 1 1 1 0 1 0 0 0 1 1 1 1 1 1 0 1 0) 13.058436 (fv 0.000000 0.018841 0.195855 0.206420 0.065633 1.458550 0.564954 0.584050 0.255393 0.821477 0.473289 1.497087 0.488701 0.595510 1.763919 1.795152 1.020709 0.148507 1.419452 -0.190874 1.252819 -0.115417 1.572364 1.086172 1.203320 0.123978 1.519196 1.337538 1.222474 1.661628 1.792441 1.530814 0.073522 0.146382 0.880812 1.383907 1.455106 1.313842 0.612949 1.097744 0.661951 0.056058 0.292577 0.309700 1.553938 1.839317 1.798626 0.412574 -0.220475 0.391331 1.230536 1.329793 -0.061036 0.863566 1.369439 -0.108592 1.446517 1.870258 0.562986 0.909666 0.015512 0.313473 0.325423 1.421234 1.107012 0.906081 -0.185513 0.052032 0.945263 0.140137 1.151954 1.558716 1.433167 -0.154754 1.358982 -0.108152 1.794830 0.776903 1.411273 0.506284 0.746113 0.870064 0.655404 0.430773 1.492137 1.947814 1.106281 1.476409 1.624757 1.670125 1.262143 0.090556 0.017948 1.208649 1.518613 0.097884 0.893396 1.883764 0.459504 1.072858 0.258050 0.025247 0.792929 1.431035 1.911968) ) ;;; 106 prime -------------------------------------------------------------------------------- (vector 106 15.730461834714 (fv 0 1 0 1 1 1 1 0 0 0 1 0 1 0 1 1 1 0 0 0 1 1 0 1 0 1 1 0 0 0 1 1 1 1 1 0 0 0 1 1 1 1 0 0 0 1 1 0 0 1 1 1 1 0 1 0 0 1 0 1 1 1 1 1 1 1 0 0 1 1 1 1 0 0 1 1 0 0 1 0 0 1 0 1 1 0 1 1 0 1 0 0 0 0 0 0 0 1 1 1 1 0 1 1 0 1) 13.079950 (fv 0.000000 0.991683 1.667079 0.952198 -0.158134 0.908256 -0.128985 1.883696 0.540349 0.614398 0.596989 0.783975 1.428368 1.597136 0.736884 1.252068 1.305873 0.231319 1.020117 1.388373 0.377031 1.796792 1.091025 -0.916486 1.247592 1.449627 1.096507 0.594132 -0.088485 1.169711 1.329459 0.003695 0.368539 -0.180221 0.842521 1.314435 1.291992 1.272149 0.292625 1.025337 1.197144 0.687141 1.597409 1.201509 1.264866 0.210655 0.462014 0.072105 1.054043 0.490923 0.945944 1.071461 0.064888 0.965001 1.073253 1.205548 1.546442 0.256599 0.512902 -0.205146 0.188856 1.063444 0.616804 1.743279 0.914154 0.807038 1.016753 1.132350 0.990751 0.400337 1.345943 0.880688 0.534474 0.323663 1.462334 0.913980 0.240611 1.904272 0.651788 0.182999 -0.180558 -0.266742 1.405697 0.476547 1.309300 1.415664 1.075072 1.577006 1.108476 0.911007 -0.337178 0.168855 1.245061 1.768086 1.542431 1.828360 0.829179 1.275739 -0.086776 0.463079 -0.336090 0.362914 1.505253 0.753982 0.654367 1.043320) ) ;;; 107 prime -------------------------------------------------------------------------------- (vector 107 16.2013 (fv 0 0 1 1 0 0 0 0 1 0 0 0 0 0 0 1 0 1 1 1 1 0 1 0 1 0 0 1 0 0 1 0 1 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 1 1 0 1 0 1 0 1 0 0 1 1 0 1 1 1 1 0 1 1 0 1 0 1 1 1 0 1 1 0 0 1 1 1 1 0 1 1 0 0 0 0 0 1 1 0 0 1 1 0 1 1 1 0 0 1 1 1) 13.454325 (fv 0.000000 0.389504 0.200622 1.043121 0.761894 1.811391 1.013338 -0.029178 1.657156 0.071414 1.541808 1.697328 1.530731 0.828486 0.142611 0.827276 0.363623 0.731067 0.344946 0.056374 1.429426 0.761263 0.713573 1.043714 1.789986 0.913538 0.284688 1.632024 0.219315 1.596281 0.482719 0.716103 0.082813 0.889064 1.454911 -0.018694 1.031913 0.769500 1.225826 1.094301 0.011285 1.403439 1.540236 1.228421 1.198312 0.763787 1.489126 0.037842 1.393526 1.595697 1.484515 1.699381 0.910044 0.346999 1.483481 0.762896 0.323372 1.323234 0.494595 1.056252 0.710041 0.505300 0.227945 0.637730 1.459638 1.234710 0.493803 1.016315 0.230683 0.093113 0.713556 0.351744 1.777886 0.983943 0.185348 0.658457 0.665347 0.215532 0.767846 1.194595 0.781272 1.709017 0.088709 0.815194 0.381579 0.627948 1.674861 0.568794 1.433122 0.535438 1.473475 1.534920 1.207161 0.582128 0.284193 0.977855 0.959238 0.627080 0.292937 0.193644 0.627895 1.586822 1.256893 1.318535 0.663707 0.022219 1.167626) ;; 106+1 13.202367 (fv 0.000000 1.000613 1.684756 1.030591 -0.144674 0.930087 -0.073206 1.869216 0.492462 0.667691 0.532693 0.721976 1.419258 1.577138 0.740297 1.322068 1.346534 0.154223 1.065715 1.368889 0.410182 1.822841 1.125450 -0.885511 1.290555 1.433074 1.046721 0.707499 -0.124656 1.201693 1.347393 0.018662 0.502177 -0.078873 0.756433 1.230311 1.259142 1.367069 0.315216 1.023759 1.259356 0.661168 1.411343 1.215010 1.266771 0.189892 0.505302 -0.011494 1.187732 0.519532 0.949942 1.050962 -0.019894 1.078182 0.992807 1.143414 1.633065 0.324324 0.492441 -0.218768 0.188780 0.963413 0.578702 1.692089 1.002935 0.841457 1.096611 1.231089 0.982778 0.479408 1.297577 0.816566 0.491832 0.381540 1.447787 0.924630 0.221301 1.796849 0.662118 0.111778 -0.098285 -0.205921 1.443651 0.375879 1.302820 1.419045 1.157539 1.514324 1.141534 0.934891 -0.258550 0.136149 1.293417 1.740995 1.504775 1.852338 0.849037 1.301984 -0.143638 0.497510 -0.382560 0.320355 1.490322 0.666001 0.663075 0.925267 0.075096) ) ;;; 108 prime -------------------------------------------------------------------------------- (vector 108 16.517358779907 (fv 0 1 0 0 0 0 0 1 0 1 1 1 1 1 0 1 1 1 1 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 1 0 1 1 0 0 0 1 0 0 0 0 1 1 0 1 1 1 1 0 0 0 1 0 1 0 0 1 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 1 0 1 0 1 1 0 1 0 1 1 0 0 0 1 0 1 1 0 1 1 0 1 0 1 0 1) 13.566156 (fv 0.000000 0.728699 0.665336 1.259359 0.312955 1.409197 -0.227152 1.537467 1.153791 1.627076 -0.109225 0.091841 1.196044 0.651957 1.667279 0.297872 1.708304 1.600040 1.279774 0.976975 0.859888 1.094622 0.659631 0.928550 0.001741 -0.027962 0.214582 0.238151 1.673247 1.887884 0.736064 0.892280 0.140937 0.557264 1.253347 0.704162 0.470712 1.242786 0.158371 0.301659 0.524953 1.272263 1.156799 -0.239176 0.540826 0.229025 0.331628 1.768533 0.578592 1.809543 0.717505 1.699923 1.628036 -0.006910 1.357544 -0.139327 0.574888 1.440391 0.790214 1.511908 0.799982 0.339724 0.692982 0.670833 0.340679 0.340555 1.796897 1.303289 0.258157 0.027036 0.818761 0.552085 1.636862 0.719532 0.280874 1.446822 1.675335 0.170540 0.167079 0.487215 1.068313 1.129396 0.130584 -0.078228 1.601308 0.067975 0.896148 0.221651 0.232515 0.805049 1.470867 0.339643 0.563679 1.554585 0.968287 0.574484 1.097469 1.601363 0.583017 1.789341 1.359201 1.858560 0.117486 0.025512 1.678463 -0.072670 -0.213093 1.615471) ;; 107+1 13.161718 (fv 0.000000 0.987739 1.733133 1.054188 -0.119939 0.910849 0.010896 1.915591 0.510331 0.662472 0.507733 0.711187 1.421434 1.531951 0.698359 1.366502 1.433114 0.162830 1.031829 1.385260 0.380744 1.872146 1.120453 -0.900242 1.311562 1.361998 1.093182 0.717990 -0.097277 1.161510 1.367817 0.082904 0.485601 -0.064734 0.731587 1.181418 1.308157 1.250173 0.316423 1.011227 1.301355 0.644463 1.445963 1.205118 1.208647 0.244654 0.589262 -0.059634 1.176596 0.571146 1.043371 1.083159 0.006076 1.077933 0.991663 1.165270 1.605164 0.390047 0.441435 -0.106544 0.175661 1.010931 0.543321 1.751721 0.965777 0.870079 1.024670 1.181296 0.990067 0.440808 1.351390 0.806214 0.421993 0.407648 1.468845 0.828507 0.187943 1.771172 0.634836 0.107090 -0.067569 -0.177001 1.469562 0.463678 1.334677 1.387523 1.126011 1.572881 1.170585 1.010919 -0.335535 0.129689 1.331430 1.676924 1.536965 1.783188 0.838550 1.260495 -0.084649 0.463288 -0.384118 0.341860 1.494266 0.699617 0.647486 0.913118 0.121686 0.025406) ) ;;; 109 prime -------------------------------------------------------------------------------- (vector 109 16.726722717285 (fv 0 0 1 0 0 0 1 0 0 0 0 1 0 1 0 1 0 0 0 1 0 0 1 1 1 1 0 0 0 1 1 1 0 0 1 0 0 1 0 1 0 1 1 0 0 1 0 1 0 1 1 0 0 1 1 0 1 1 0 0 0 0 1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 1 1 1 1 0 1 1 0 0 0 1 1 0 1 0 1 1 0 1 1 1 1 0 1 1 0 1 1 1) 13.649150 (fv 0.000000 1.372685 -0.023096 0.764121 0.652451 1.161206 0.008161 0.316013 0.797732 0.714473 0.487368 1.050633 1.595865 0.070630 1.790292 1.172057 1.415647 1.153468 1.827169 0.230707 0.215213 0.858764 0.278893 1.454000 0.649000 1.487731 -0.093971 1.467452 0.578832 1.089439 0.854711 1.680527 0.623468 0.213876 1.468708 0.944679 1.289165 0.802006 0.813501 1.223343 1.569276 1.613534 0.610297 0.672562 1.232493 0.103141 1.459267 0.251097 0.877797 0.013403 1.560238 0.500350 1.399744 0.774367 0.659639 0.252122 0.824594 0.812839 0.861276 1.156805 0.833828 1.345402 0.790424 1.718416 0.402535 0.733335 1.522110 0.842132 1.600144 1.051832 -0.203657 0.911191 0.314178 0.284195 1.331343 0.434428 0.490954 1.410099 0.311769 1.658687 1.103289 1.173009 0.197955 0.613754 0.369986 0.003017 -0.302157 0.765490 1.656484 0.479210 0.563523 0.438269 0.714490 -0.012143 1.495468 -0.063161 0.479473 0.509000 1.902431 1.448189 0.587148 0.187985 1.316513 1.133117 1.008029 0.693260 0.907818 1.116038 0.394946) ;; 108+1 13.143741 (fv 0.000000 0.981295 1.812666 1.117956 -0.185500 0.887133 -0.042123 1.869958 0.605292 0.660698 0.487240 0.624166 1.449694 1.534689 0.782613 1.451064 1.414295 0.227989 1.073340 1.379009 0.377980 1.849622 1.090582 -0.935851 1.300468 1.325519 1.018826 0.640677 -0.151618 1.157148 1.372788 0.030561 0.535214 0.003928 0.716545 1.230702 1.288510 1.214069 0.401399 1.044897 1.420969 0.699802 1.461844 1.182797 1.140031 0.222134 0.599399 -0.075721 1.205878 0.475321 1.079680 1.212881 -0.096955 1.107746 1.109769 1.169670 1.644352 0.462528 0.400247 -0.075889 0.244499 0.883273 0.555132 1.799341 1.047944 0.815280 0.989170 1.236643 1.002684 0.340197 1.339964 0.830022 0.342213 0.420385 1.313509 0.797027 0.138670 1.741420 0.612419 0.142853 -0.104009 -0.165428 1.519255 0.376528 1.265335 1.374075 1.080427 1.589793 1.292179 1.057071 -0.356737 0.109826 1.273643 1.715122 1.539078 1.804591 0.847821 1.225593 -0.104087 0.410682 -0.411370 0.366927 1.453570 0.665830 0.721383 0.960549 0.197868 0.027654 -0.001988) ) ;;; 110 prime -------------------------------------------------------------------------------- (vector 110 16.455888332339 (fv 0 1 1 0 1 1 1 1 1 0 0 1 0 0 0 0 0 1 0 0 0 1 1 1 0 0 1 1 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 0 1 0 1 0 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 0 0 0 0 0 1 0 0 1 0 0 0 1 0 1 0 1 0 0 1 1 0 1 0 1 0 1 1 0 1 0 1 1 0 0 1 0 0 1 1 1 1) 13.753511 (fv 0.000000 0.848399 0.494893 1.537753 0.056503 1.192968 1.014976 1.000380 0.176221 0.063643 0.945853 -0.068422 1.888547 0.530097 1.932585 0.363227 0.205713 0.801411 0.700920 0.687774 0.323313 0.855436 1.706412 1.023431 1.539017 1.189953 0.005598 1.402697 1.398321 0.097413 0.650843 0.983076 -0.039672 1.076216 1.303860 0.579074 0.077434 1.403649 0.444054 1.850591 1.616413 0.004099 1.016957 0.276287 0.460935 1.424558 0.455559 1.774494 1.736742 0.257321 1.711197 0.589769 0.080807 0.068711 1.794312 0.030231 1.983460 1.792079 0.697501 1.563642 0.912299 1.306605 0.631662 1.306070 -0.020912 0.369231 0.339819 1.307905 -0.099842 0.333029 0.056818 -0.061161 0.558252 1.627518 -0.126860 1.759233 1.646547 0.826803 -0.148545 1.670003 1.989516 1.496557 0.799184 0.829408 0.352552 1.567755 1.722037 1.366413 1.337959 0.542553 0.828268 -0.090626 1.570252 0.921528 0.763668 1.791188 0.313328 1.353716 0.012540 0.577255 1.197100 -0.067959 0.264526 0.484251 0.882328 0.325360 0.489410 0.497137 1.466498 0.363086) ;; 109+1 13.385857 (fv 0.000000 1.005423 1.782283 1.037310 -0.213053 0.879928 -0.046517 1.873303 0.602952 0.747924 0.548631 0.551919 1.533520 1.564233 0.767686 1.439845 1.429058 0.210745 1.048360 1.272572 0.420497 1.907528 1.007798 -0.875985 1.280681 1.283565 1.002224 0.663448 -0.175829 1.191021 1.396519 0.008645 0.463633 -0.035145 0.773513 1.183723 1.280027 1.209216 0.370736 1.024088 1.346178 0.572424 1.493165 1.210957 1.190749 0.243885 0.627363 -0.093472 1.163170 0.538660 1.062757 1.203025 -0.076830 1.020755 1.065456 1.180141 1.616909 0.426164 0.442881 -0.033300 0.224949 0.880028 0.544694 1.835856 0.965989 0.842443 0.993190 1.292542 0.995849 0.354562 1.374934 0.864622 0.357717 0.414238 1.429257 0.844435 0.199497 1.704803 0.599091 0.164856 -0.041591 -0.188982 1.576927 0.379552 1.197978 1.412448 1.100509 1.573418 1.244031 1.006949 -0.394739 0.102675 1.270463 1.672535 1.525836 1.772058 0.832852 1.187053 -0.004100 0.474378 -0.431920 0.321063 1.410302 0.680526 0.673358 0.951529 0.162772 0.079611 0.022569 0.116743) ) ;;; 111 prime -------------------------------------------------------------------------------- (vector 111 16.6662 (fv 0 1 0 1 0 0 0 1 1 0 0 1 0 0 1 1 0 1 0 1 1 0 0 0 1 1 1 1 1 0 1 1 1 0 0 0 1 1 0 1 0 0 0 0 1 1 0 0 1 0 1 1 0 1 0 0 1 1 0 1 0 1 1 1 1 1 1 0 1 1 0 1 0 0 0 0 1 1 1 1 1 0 0 1 0 1 0 1 1 1 0 1 0 1 1 0 1 1 0 0 1 1 0 0 0 1 1 0 1 0 0) 13.722535 (fv 0.000000 0.609754 0.477824 0.498205 -0.160828 1.311478 1.827872 1.163524 0.877088 0.528558 0.012460 0.425841 0.347225 1.111527 1.506620 1.410636 0.996952 -0.131493 1.544916 1.238729 0.920166 1.777555 1.246912 0.483008 1.025725 -0.124782 0.923160 0.448660 1.543112 1.342373 1.038202 0.935130 1.601650 0.963178 1.878258 0.588174 1.312098 0.758893 0.091784 1.903351 1.707234 0.845481 0.771218 1.534277 0.275800 0.904288 0.700394 1.584631 1.096911 0.048546 1.076681 -0.004790 1.712699 1.002701 0.028040 0.631055 0.000599 0.321247 1.728365 1.696152 0.050007 0.370978 0.617539 1.556864 1.281962 1.845086 1.923574 1.593500 1.577659 0.887043 0.956244 1.403764 1.038378 1.157002 1.529481 1.305687 0.017547 0.326930 0.654165 -0.007752 -0.267214 1.694215 0.852596 1.259529 0.832944 0.035647 0.361584 1.075053 1.075715 1.409307 1.062617 -0.201186 0.434486 -0.180399 1.188883 -0.221873 1.452975 -0.020938 0.072031 0.208492 1.474047 1.409906 0.615391 1.726165 0.685592 0.292682 1.428870 0.069915 -0.271563 0.353890 1.174756) ;; 110+1 13.484289 (fv 0.000000 0.995043 1.654854 0.951488 -0.186960 0.850693 -0.104052 1.791806 0.632389 0.741244 0.372539 0.536429 1.585222 1.564873 0.754743 1.533715 1.436886 0.265913 1.082971 1.345237 0.422609 1.896766 1.047262 -0.941259 1.315104 1.247825 1.012008 0.626763 -0.163895 1.147771 1.361070 0.089508 0.489357 -0.001980 0.747126 1.129161 1.312043 1.244841 0.335129 1.099634 1.435470 0.558588 1.594865 1.187385 1.215330 0.231616 0.653215 -0.079848 1.147198 0.522561 1.074244 1.189158 0.024016 1.002127 1.145705 1.183921 1.636771 0.398476 0.358443 -0.058263 0.246181 0.942683 0.482681 1.823368 1.038771 0.798364 0.979012 1.260203 1.008839 0.331481 1.329527 0.889282 0.388705 0.378727 1.394091 0.860317 0.191774 1.792101 0.682065 0.246000 -0.121897 -0.155296 1.603714 0.392748 1.177859 1.362462 1.085317 1.557823 1.337471 1.045764 -0.299177 0.095852 1.207771 1.749557 1.574722 1.798042 0.795838 1.277804 -0.046897 0.399079 -0.477065 0.322241 1.436449 0.774690 0.635047 0.952898 0.197693 0.020089 0.072586 0.105711 -0.061722) ) ;;; 112 prime -------------------------------------------------------------------------------- (vector 112 16.697049415765 (fv 0 0 1 0 1 0 0 0 0 1 0 1 0 0 1 1 0 1 1 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 0 0 0 0 0 1 1 0 1 0 1 1 1 0 0 1 0 1 0 0 0 0 1 0 1 0 0 0 0 0 1 1 1 0 1 1 0 0 1 1 0 1 0 0 0 1 0 0 1 0 1 0 0 1 0 1 0 1 0 0 1 0 0 0 1 1 0 1 1 1) 13.804835 (fv 0.000000 0.660626 0.012013 1.067055 1.731382 0.878320 0.900685 1.333334 0.681047 1.863220 1.352916 0.703854 1.515374 0.461716 0.898953 1.919840 0.286167 0.735654 -0.086197 0.617448 0.511110 1.353376 1.062165 1.636012 0.515505 1.399695 1.421287 -0.379478 0.731516 0.180102 1.567557 1.923199 -0.007316 1.368320 1.294564 0.578724 1.657029 0.985867 0.321763 1.643211 0.183594 -0.095598 1.792723 0.880687 0.335377 0.402596 1.614065 0.786600 0.590837 0.174605 0.357314 0.363837 -0.136455 0.186803 1.076928 1.936757 0.633832 1.217976 0.067642 0.078632 0.866945 1.729624 0.916168 1.228002 1.090442 0.162856 0.012895 1.357444 0.829157 1.905883 0.224325 1.392049 1.223672 1.768609 0.413025 0.871017 1.661030 1.831359 0.223665 1.475164 0.272068 0.564210 0.622152 1.113002 0.676345 -0.006078 1.737306 1.187465 0.535707 1.077110 1.810506 1.386823 0.000557 1.452387 1.030585 0.842150 -0.158625 1.174437 0.579578 -0.079023 1.196883 0.846201 0.482764 0.945473 0.701184 0.898505 0.170202 0.481114 0.605193 0.955521 -0.054086 0.358715) ;; 111+1 13.560854 (fv 0.000000 0.996200 1.682628 0.999634 -0.183169 0.941340 -0.063380 1.872352 0.588785 0.718316 0.404204 0.564721 1.640073 1.488214 0.688322 1.540833 1.402097 0.325664 1.088557 1.271965 0.430614 -0.023931 1.082172 -0.819505 1.289052 1.272358 1.016703 0.615500 -0.063492 1.173776 1.419856 0.160057 0.471424 0.025687 0.794626 1.093604 1.347648 1.313640 0.365769 1.198433 1.539259 0.590650 1.625522 1.236869 1.255735 0.261849 0.614310 -0.133810 1.106507 0.525198 1.040282 1.242100 -0.009151 0.940124 1.120632 1.244098 1.583333 0.484225 0.270298 -0.091909 0.275038 0.915341 0.498191 1.846447 1.147765 0.805686 0.960525 1.293095 0.980148 0.249336 1.277364 0.859717 0.447170 0.347316 1.500244 0.749545 0.120155 1.639932 0.628998 0.242589 -0.052482 -0.149374 1.587211 0.461604 1.136482 1.323997 1.019660 1.587802 1.220439 1.097627 -0.381422 0.113408 1.209314 1.808025 1.585895 1.749582 0.823561 1.289475 0.074159 0.350519 -0.613785 0.308515 1.554187 0.783853 0.541355 0.955629 0.179584 0.128995 -0.001165 0.025208 -0.107472 -0.097625) ) ;;; 113 prime -------------------------------------------------------------------------------- (vector 113 16.203890830538 (fv 0 1 0 1 0 0 1 1 1 1 0 1 1 1 1 1 0 1 0 0 0 0 0 1 0 1 0 0 1 1 1 0 0 1 1 0 1 0 1 0 1 1 0 1 0 1 1 0 0 0 1 0 1 0 1 1 1 1 1 1 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 0 0 1 0 1 1 0 1 1 1 0 1 1 0 0 1 0 1 1 0 1 0 0 1 0 0 0 1 0 1) 13.613456 (fv 0.000000 0.554013 -0.189590 1.040342 1.895741 0.972257 1.983763 0.925350 1.413107 1.187039 0.890581 -0.092527 0.648924 0.275297 1.034974 0.578278 1.412961 1.217860 0.290211 0.146756 1.277989 1.797973 1.243546 0.309623 0.588952 0.766281 1.732300 0.158146 0.970241 1.057713 0.155581 0.740347 -0.278224 0.813051 0.090610 1.633987 0.141253 1.362430 1.811341 0.106172 0.560908 0.975141 0.414465 1.325189 1.317848 1.670918 1.310037 0.138103 1.544695 0.427642 0.688876 1.115251 0.104011 1.249484 1.283379 -0.217415 1.248803 -0.055143 1.377781 1.794050 -0.051929 -0.190679 -0.001958 1.872135 1.015649 0.017838 -0.117121 0.829495 -0.198380 0.905735 0.272607 0.619166 1.647347 0.816228 0.007369 0.650952 0.045714 0.308454 0.434057 0.201848 1.245915 0.933121 1.619736 1.351637 0.362509 1.868147 1.070766 1.188359 0.400988 0.049686 0.087230 0.628970 0.077489 1.262876 0.220162 0.869503 1.130712 0.267514 1.396227 1.721653 1.550102 1.446927 1.155950 0.841581 0.384623 1.977430 1.631746 0.006140 0.715062 1.236385 1.051311 0.995413 0.371400) ) ;;; 114 prime -------------------------------------------------------------------------------- (vector 114 16.442732865586 (fv 0 0 1 1 0 0 1 1 0 0 0 0 1 1 1 0 1 0 1 1 0 0 0 0 0 1 1 1 1 0 1 1 1 1 1 0 1 1 0 0 1 0 1 1 1 1 1 0 0 0 0 1 0 1 0 0 1 0 1 1 1 0 1 0 0 0 0 1 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 1 1 1 0 1 1 0 1 0 0 1 0 1 0 0 0 1 0 0 1) 14.166020 (fv 0.000000 1.038356 0.826275 1.128674 -0.125090 1.829063 1.262013 1.160559 1.519516 1.502014 1.857796 1.525394 0.946893 1.361851 0.493317 1.621550 0.040839 0.825455 1.881008 1.165270 1.273827 0.159303 1.756090 1.393155 1.413051 0.957215 0.252091 1.226129 -0.094317 0.742943 1.002043 1.336572 1.592258 -0.082802 1.594640 0.366562 0.390860 1.427038 1.739079 0.663205 0.933325 1.484965 0.194283 0.375410 0.493300 0.605961 1.748551 0.279636 1.804517 0.357640 0.998348 0.681772 0.367098 0.467866 1.810315 1.933552 1.894370 1.189828 1.415118 1.834729 1.938426 1.415450 0.009074 1.747634 1.249287 0.770928 -0.115261 1.409451 1.246513 0.675514 1.266338 1.477875 -0.114148 0.185420 0.629532 1.098645 0.874254 0.446592 0.243371 0.516051 1.248852 0.028651 -0.007127 1.709807 1.312205 0.257361 1.279674 0.901557 0.855388 1.469222 1.328726 1.208217 1.433035 1.922664 0.274941 0.148828 0.367238 -0.254062 1.751340 0.773665 1.053171 0.567664 1.773987 1.113690 1.183578 1.066952 0.102607 0.071815 1.625657 1.255723 1.028659 0.085305 0.356288 0.418655) ;; 113+1 13.529505 (fv 0.000000 0.609603 -0.150717 1.144620 1.885952 1.029695 -0.017328 1.023651 1.375935 1.049542 0.876959 -0.157071 0.712430 0.086142 1.092731 0.678537 1.443976 1.204147 0.360088 0.209607 1.268934 1.814390 1.230253 0.384833 0.625288 0.787682 1.706820 0.104070 0.975842 1.091508 0.162798 0.719194 -0.185681 0.851344 0.004406 1.551988 0.158850 1.400167 1.727125 0.074860 0.565161 0.958867 0.364724 1.349213 1.351889 1.679509 1.314199 0.132307 1.403589 0.369532 0.648564 1.160585 -0.009001 1.392847 1.218123 -0.146011 1.322032 -0.127699 1.286444 1.741589 -0.086769 -0.151954 0.062929 1.896116 1.063027 0.005563 -0.069693 0.819283 -0.185224 0.958608 0.217640 0.593867 1.814658 0.753485 -0.046094 0.586286 0.067659 0.127457 0.558174 0.155027 1.389478 0.905687 1.516935 1.472391 0.370204 1.903438 1.085058 1.201428 0.394426 0.093638 0.098055 0.586236 0.108735 1.290199 0.287019 0.975146 1.134274 0.275315 1.391551 1.689333 1.493530 1.402264 1.275785 0.772955 0.474442 0.009426 1.766587 0.112461 0.593436 1.228805 0.896377 1.061049 0.277890 -0.013199) ) ;;; 115 prime -------------------------------------------------------------------------------- (vector 115 16.774665887963 (fv 0 1 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 1 0 1 1 1 0 0 0 0 0 1 0 0 0 1 1 0 1 0 0 1 0 0 1 0 1 0 0 1 1 0 0 0 1 1 1 0 0 0 0 0 1 0 0 1 1 1 1 1 1 1 1 0 0 0 1 0 0 0 1 1 0 0 1 0 0 1 0 0 0 1 0 1 0 1 0 0 0 0 0 1 1 1 0 0 1 1 0 1 1 0 1 1 1 0 1 0) 14.106616 (fv 0.000000 1.570092 0.362453 1.337474 0.264875 0.921400 0.355874 1.476538 0.382397 0.690102 0.627233 1.283297 1.585161 0.461353 0.250428 0.070613 -0.478768 0.954888 0.726879 1.251951 0.417891 0.945598 0.563852 0.084589 0.533104 0.472131 1.084144 1.608792 0.044337 1.518184 0.783171 0.484129 1.900804 -0.149622 0.399475 1.517825 0.218983 1.531509 -0.230530 0.567148 1.520162 -0.082961 1.681948 0.292123 0.756368 0.448131 1.473802 1.014666 -0.012646 1.572834 1.242744 0.425093 -0.031699 0.769537 1.112143 1.298398 0.333581 1.945824 -0.101577 1.894990 1.397266 1.272345 1.210062 1.810802 0.715502 0.534600 1.359024 1.288083 -0.103335 0.078475 0.156596 1.496646 1.076856 0.312782 0.361663 1.568537 1.496774 0.979145 1.697729 0.843520 0.130906 1.341892 0.946201 1.950539 0.684184 1.344931 0.821452 1.479748 1.308019 0.296269 1.793184 0.500147 0.839533 0.057599 0.886809 0.752434 1.587024 1.203157 1.022448 0.212093 1.492893 0.209714 0.165780 1.402030 -0.307350 0.474032 1.513784 1.517441 1.459089 1.632203 1.421380 1.032369 0.154966 0.002531 0.304007) ;; 114+1 13.732359 (fv 0.000000 0.572178 -0.139025 0.983887 1.920434 1.123578 1.978353 0.968214 1.349051 1.117228 0.839675 -0.190533 0.694004 0.125250 1.107764 0.641260 1.405169 1.199788 0.276763 0.250348 1.204416 1.682914 1.257883 0.312057 0.695310 0.801198 1.682635 0.125698 0.950119 1.070718 0.245730 0.776193 -0.167540 0.949181 -0.042356 1.548062 0.106820 1.334788 1.742804 0.109905 0.567469 0.997715 0.375385 1.298162 1.314791 1.688434 1.235156 0.141282 1.427214 0.400188 0.631107 1.144708 -0.003109 1.362927 1.143332 -0.234998 1.276203 -0.143654 1.307422 1.689156 -0.014380 -0.262664 0.075462 1.880295 1.062640 0.101776 -0.026648 0.801460 -0.217311 0.971985 0.270988 0.672521 1.816202 0.778522 0.051104 0.549038 0.052885 0.201837 0.612616 0.180579 1.355932 0.900040 1.595492 1.482393 0.476525 1.886230 0.983641 1.114556 0.404677 0.048952 0.080076 0.569993 0.080539 1.262764 0.266797 0.946313 1.101489 0.203645 1.377876 1.725578 1.491484 1.434839 1.127583 0.826060 0.448266 0.008333 1.780636 0.098825 0.586600 1.122038 0.995066 1.017216 0.354291 0.057246 0.069092) ) ;;; 116 prime -------------------------------------------------------------------------------- (vector 116 16.812931137234 (fv 0 1 0 0 1 0 0 0 1 1 1 0 0 0 0 0 1 0 1 0 0 1 1 1 1 0 0 1 0 0 0 0 1 0 0 1 0 0 0 1 0 1 0 1 0 1 0 0 0 1 0 1 0 1 1 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 1 1 1 1 1 0 0 0 0 1 0 1 1 0 0 1 0 0 0 1 1 1 1 0 1 1 1 0 0 1 0 1 0 0 1 0 1 0 0 0 0 1 1 1 0 0) 14.328742 (fv 0.000000 0.856207 0.986788 0.751460 1.884184 1.255896 0.144210 1.208511 0.255866 1.782286 0.019244 0.566742 0.407768 -0.089210 1.344767 1.018853 -0.034882 0.530119 1.597864 0.501326 -0.230774 -0.097023 -0.000389 0.665472 1.635375 1.228232 1.206358 0.850292 0.888987 0.993112 0.654339 0.818974 0.003413 1.565831 0.042608 0.878547 0.321526 0.088958 0.292372 -0.331777 0.700821 0.894714 0.005944 -0.346944 0.114845 1.049758 0.798720 0.790858 0.117448 1.021841 0.389934 0.399103 0.195343 1.878118 1.577823 0.477002 0.256545 1.229924 -0.002011 0.133077 0.537008 0.396216 0.701816 0.985840 1.738910 0.328555 0.541523 0.876819 0.876185 0.445666 0.685165 1.594949 0.620581 -0.127456 0.921400 0.311110 1.793307 0.275641 1.366815 0.824915 0.239454 0.832837 1.417323 1.769240 0.980992 1.239944 1.591029 -0.051475 1.486421 1.525417 -0.025657 0.653170 1.313243 1.650610 1.580897 1.618532 0.633267 0.393928 1.496919 -0.276408 0.878277 0.281939 0.351152 0.468289 1.618075 1.571369 0.984717 1.909405 0.851519 1.720488 0.929949 1.296555 1.289941 0.911398 0.225491 0.695200) ;; 115+1 13.782751 (fv 0.000000 1.670105 0.303378 1.514771 0.060477 0.906403 0.370378 1.628880 0.301098 0.717479 0.564448 1.198544 1.701046 0.489974 0.092684 0.106689 -0.600359 0.960290 0.727113 1.181333 0.468036 0.933578 0.612714 0.102105 0.439119 0.536613 0.989488 1.668598 -0.080124 1.683573 0.654250 0.599004 1.870044 -0.069895 0.298556 1.555710 0.285805 1.565873 -0.205135 0.563645 1.519179 -0.152285 1.687696 0.402404 0.955645 0.241673 1.401865 1.046960 -0.019116 1.640885 1.197901 0.505391 0.095168 0.718441 1.181463 1.406618 0.309258 1.952979 -0.107329 1.969648 1.502137 1.090118 1.043918 1.702710 0.780485 0.583772 1.473922 1.490931 -0.163373 0.133574 0.135840 1.533071 1.015158 0.398692 0.320450 1.364722 1.538313 0.970480 1.636937 0.963390 0.136800 1.340905 1.204598 0.054477 0.486418 1.417827 0.808183 1.530254 1.191144 0.320075 1.853919 0.467453 0.809752 0.120164 0.781600 0.697424 1.379599 1.216021 0.948183 0.099657 1.566373 0.116729 -0.093843 1.319423 -0.420543 0.691568 1.660724 1.496943 1.401099 1.619305 1.446415 0.867038 0.105822 0.158044 0.282349 -0.011943) ) ;;; 117 prime -------------------------------------------------------------------------------- (vector 117 17.5997 (fv 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0 1 1 0 0 0 1 0 1 0 1 1 0 0 0 0 0 0 0 1 0 1 0 1 1 0 1 1 0 0 1 0 1 0 0 0 0 0 1 0 1 0 0 0 0 1 1 1 1 0 1 0 1 0 0 1 1 1 1 0 0 0 0 1 0 1 0 1 1 1 1 1 0 1 0 1 0 0 1 0 1 0 1 1 0 1 0 1 1 0 1 1 0 1 1 1 1 0 0 1) 14.497812 (fv 0.000000 0.224426 0.992019 0.138711 1.176503 1.236445 0.315077 1.906428 0.448900 0.678218 -0.088951 0.205668 0.157937 1.760779 0.121986 1.314615 1.230068 1.510274 1.468208 1.579772 0.156575 1.223695 1.547174 0.976223 0.294979 0.682844 1.254567 0.255930 0.581609 0.421918 0.606116 0.691338 0.828316 1.627063 1.800785 0.001165 -0.086581 0.763116 0.639955 0.291470 1.735899 0.422553 0.362144 1.186351 1.590842 0.426463 0.245182 0.967296 0.891425 0.519158 0.866605 1.346855 0.815662 0.075921 1.039570 1.274467 1.634408 1.602113 1.536366 0.552713 0.810604 0.673899 0.744845 0.479678 1.304967 1.905715 1.460213 0.317282 1.748084 -0.013722 -1.881692 0.174856 -0.080552 1.785033 0.698053 0.094949 0.417990 0.698446 0.985481 1.584075 1.403772 0.388703 0.009472 1.646671 1.128281 1.234472 1.443078 1.392782 1.271405 0.499301 0.604344 -0.127230 1.264738 1.785688 0.416206 1.113044 0.215095 1.469439 0.236533 0.117496 0.271632 1.034059 1.537681 0.722701 1.631698 0.103905 0.435634 0.027785 0.196356 1.018099 1.623844 0.142536 1.403226 -0.013797 0.598011 1.913682 0.626571) ;; 116 + 1 13.889211 (fv 0.000000 1.679442 0.299199 1.367111 0.052770 0.927297 0.328215 1.615881 0.302404 0.707696 0.516039 1.151316 1.673258 0.534217 0.190986 0.074151 -0.598397 0.913919 0.765928 1.260413 0.423264 1.023745 0.609735 0.153506 0.453539 0.468256 1.018228 1.788765 -0.068307 1.692855 0.624116 0.609141 1.910624 -0.022395 0.256365 1.514074 0.233219 1.516754 -0.154609 0.590788 1.514050 -0.043651 1.742187 0.341087 0.951970 0.371363 1.447587 1.079612 0.057107 1.623815 1.214707 0.567773 0.057804 0.791128 1.221209 1.383201 0.340554 -0.013292 -0.005609 1.947264 1.370803 1.062963 1.024336 1.739421 0.767066 0.671699 1.426918 1.511148 -0.149781 0.104225 0.061945 1.535119 0.940075 0.392689 0.259023 1.411809 1.598917 0.941897 1.683270 0.884953 0.108874 1.319701 1.100749 -0.050961 0.639728 1.429813 0.861586 1.511163 1.232212 0.240917 1.860927 0.406637 0.844627 0.125914 0.873615 0.651653 1.385473 1.135755 0.994702 0.030143 1.590457 0.161005 0.055154 1.334956 -0.459106 0.663912 1.678280 1.514956 1.365867 1.519273 1.441132 0.891112 0.176832 0.115181 0.351957 -0.175561 0.176948) ) ;;; 118 prime -------------------------------------------------------------------------------- (vector 118 17.181785583496 (fv 0 0 0 1 0 0 1 1 1 0 0 0 1 0 0 1 0 0 0 1 0 1 1 1 1 1 0 1 1 1 0 1 0 1 0 0 0 0 1 1 0 1 1 1 0 0 0 1 1 0 0 0 0 1 1 1 0 0 0 0 0 1 1 1 0 1 1 0 1 0 0 0 1 1 1 1 0 0 1 1 1 1 1 0 1 1 0 0 0 1 1 1 0 1 0 1 0 1 1 0 0 0 1 1 0 0 0 0 1 0 1 1 0 0 1 0 1 0) 14.497443 (fv 0.000000 1.591354 0.741888 1.722967 -0.237709 0.685421 0.503550 1.254854 0.808656 0.911251 0.050157 0.861734 0.314280 1.341176 0.379991 0.875641 1.466708 0.300573 0.954767 1.385324 0.125132 0.348374 0.577011 1.655837 0.564307 0.582376 1.167510 0.907420 0.444532 0.218679 1.737312 0.252903 0.411946 1.083113 -0.185163 0.978023 -0.109963 1.511202 0.503851 1.662809 0.033875 0.523452 0.521481 0.883976 -0.357599 0.187161 0.880047 1.490736 0.844255 0.801313 0.683070 1.279258 1.624126 0.834042 1.570571 1.331665 0.812207 0.082063 -0.178779 0.727851 0.635760 0.472598 0.529740 1.710166 0.757477 0.262267 0.672628 0.403198 0.034164 -0.022037 0.130101 1.350219 1.105735 1.695932 0.323683 1.252068 0.744970 1.161905 1.322245 0.994864 0.697837 1.637816 0.396302 1.702348 -0.270747 -0.077800 0.225947 1.713037 1.228521 1.665048 1.679022 1.393803 0.704244 0.296414 -0.016270 0.947613 1.856633 1.384283 0.527416 0.984409 1.396798 0.351021 0.292270 0.549569 1.663499 0.778229 0.016680 1.156232 0.122381 0.159439 0.648535 0.193057 0.084166 -0.213455 0.477204 0.673154 0.992874 0.783540) ;; 117+1 13.955663 (fv 0.000000 1.656893 0.312860 1.406022 0.045609 0.940726 0.323204 1.558622 0.313593 0.699110 0.536076 1.119751 1.657613 0.469730 0.215020 0.137907 -0.614064 0.902352 0.821797 1.171991 0.441310 1.059221 0.661850 0.277594 0.394536 0.546400 0.968850 1.793240 -0.073575 1.622506 0.677941 0.641837 1.952355 -0.044282 0.215122 1.490798 0.302768 1.506837 -0.235108 0.508030 1.520891 -0.097109 1.755394 0.256002 1.007243 0.327520 1.464098 1.079175 0.017892 1.590910 1.290254 0.601225 -0.032662 0.654468 1.229419 1.312262 0.353655 -0.032649 0.034883 1.896617 1.433210 1.047605 1.126390 1.674282 0.764405 0.618210 1.508232 1.671380 -0.173491 0.106521 0.149565 1.507742 0.949278 0.443666 0.317362 1.314645 1.634673 0.873102 1.588608 0.915021 0.172843 1.351037 1.151673 -0.042685 0.619993 1.550214 0.823729 1.429222 1.211772 0.248747 1.864022 0.374155 0.849134 0.123908 0.792603 0.736151 1.435290 1.198233 1.078587 0.058874 1.626102 0.122469 0.017624 1.330950 -0.499655 0.706598 1.629594 1.438050 1.370171 1.549897 1.430173 0.915025 0.119087 0.070759 0.413439 -0.125417 0.236481 -0.031842) ) ;;; 119 prime -------------------------------------------------------------------------------- (vector 119 17.167841346875 (fv 0 1 0 1 1 1 1 0 0 1 0 1 0 0 1 1 1 1 0 0 1 1 1 1 1 0 1 1 1 1 1 0 1 0 0 0 0 1 1 1 0 1 0 0 1 0 1 1 1 1 0 1 0 0 1 1 1 1 1 0 0 1 0 0 1 0 0 0 0 0 1 1 1 0 1 1 0 1 1 1 1 0 0 0 0 0 1 0 1 0 0 0 0 1 1 0 0 1 0 0 1 0 1 1 1 1 1 1 0 0 0 1 1 0 1 1 0 1 1) 14.390682 (fv 0.000000 1.375664 1.071878 1.242281 0.449872 0.997239 0.326902 1.844870 0.041292 1.299611 1.550408 0.729190 0.953350 0.209856 0.257680 0.853205 0.858641 1.807278 0.814295 0.490323 1.317949 0.220101 1.124178 0.689692 0.845713 1.610142 0.807190 0.053107 0.167263 1.261235 1.535767 1.158168 0.246566 1.099513 1.210170 1.481156 0.887639 1.096230 0.144442 0.446125 0.627726 -0.213400 0.869947 0.988021 1.647446 0.493250 1.672678 1.658411 -0.130924 1.196700 0.900590 0.905506 1.144054 1.144682 1.583644 1.532418 1.405419 1.861571 1.337158 1.938890 1.060547 0.949400 1.139259 1.324089 1.811791 1.700889 0.580433 -0.043873 0.685223 0.393731 1.345217 0.593893 0.307423 0.675865 1.845148 0.894101 0.377727 1.240396 0.150868 0.234381 0.772691 0.408668 1.155960 1.889975 0.784676 1.158424 1.614216 1.924591 0.178912 0.577105 0.980476 1.603643 0.495073 -0.104468 1.507041 0.927685 1.105445 1.078554 0.022413 0.000361 0.338859 1.519222 0.863311 0.615320 0.570559 1.762687 0.669024 0.026456 1.421100 1.955221 0.629611 -0.125129 1.900181 -0.021163 -0.020189 1.567842 0.924421 1.826999 0.630355) ;; 118+1 14.018618 (fv 0.000000 1.667367 0.322872 1.356274 0.058995 0.960979 0.391067 1.596203 0.294396 0.668831 0.482386 1.201983 1.684789 0.511518 0.202150 0.119421 -0.566103 0.969879 0.710276 1.185777 0.439002 1.081943 0.730732 0.236637 0.526675 0.480731 1.028367 1.739731 -0.138846 1.593254 0.713861 0.553938 1.957692 0.049573 0.238503 1.491899 0.251089 1.428730 -0.126673 0.452175 1.482756 -0.053077 1.780248 0.323594 0.960159 0.318559 1.403830 1.045323 0.072970 1.671965 1.340192 0.627012 0.093313 0.726626 1.260031 1.369364 0.271099 0.039064 -0.011301 1.960494 1.463622 1.056374 1.121811 1.627859 0.817517 0.663209 1.409881 1.612732 -0.152806 0.038886 0.274896 1.521348 0.915556 0.404329 0.221685 1.199737 1.694611 0.915335 1.572323 0.961485 0.112089 1.311173 1.127868 -0.177640 0.609597 1.415894 0.807680 1.506084 1.239635 0.162405 1.866700 0.317949 0.857946 0.112683 0.879435 0.694750 1.339170 1.270491 1.111213 0.092592 1.497893 0.151420 0.069449 1.319832 -0.496262 0.680555 1.680836 1.536147 1.322680 1.555058 1.410956 0.888418 0.228998 0.018175 0.403145 -0.128572 0.219741 -0.075154 -0.155224) ) ;;; 120 prime -------------------------------------------------------------------------------- (vector 120 17.067 (fv 0 1 0 1 1 1 0 1 0 0 1 0 0 1 0 0 0 0 0 1 1 1 0 1 0 1 0 1 1 1 0 0 1 1 1 1 0 1 1 1 0 1 0 1 0 1 0 1 1 1 1 1 1 0 1 0 1 1 1 0 1 1 0 1 1 0 0 0 0 1 1 1 1 0 0 1 0 1 1 0 1 0 1 1 0 0 1 1 1 1 1 1 0 0 1 1 0 0 0 1 0 0 0 0 1 0 0 0 0 1 1 0 1 1 0 1 0 0 1 0) 14.458666 (fv 0.000000 1.293108 0.698019 1.317447 0.029496 0.078825 1.245576 0.933427 0.917420 1.172126 0.357395 1.156156 0.879865 0.129592 1.181392 0.882110 0.690853 1.687107 0.025873 0.234607 1.243328 0.528035 0.272217 0.646247 0.920540 -0.212257 1.217024 1.877596 1.938817 0.737497 0.901785 1.059044 1.128268 0.954000 0.339889 0.097863 -0.055556 1.539115 0.342970 1.531145 0.894486 1.025619 0.519579 0.900743 0.956748 -0.133937 0.256714 0.139176 0.495069 1.185608 1.684763 0.822374 0.580038 0.873037 1.366028 1.356196 1.900731 0.458911 0.428437 1.433784 -0.025135 1.471236 0.210352 1.314750 0.475084 0.493167 0.205827 0.317580 1.227052 1.530659 1.302191 0.347571 0.409940 0.502737 1.688087 1.230409 1.337757 1.342952 1.903513 0.955786 -0.215055 0.487009 1.948923 1.411678 0.225274 0.421106 0.203875 0.568136 0.977570 1.560054 1.164692 1.211841 0.037236 1.165323 0.284280 0.274360 0.776762 0.207157 -0.008462 -0.022949 0.633618 1.519303 0.349119 1.348337 0.561608 1.136896 0.486384 1.690665 0.939858 1.037942 0.628883 1.115783 0.551269 0.261357 0.835768 0.754522 0.995311 0.736018 1.536035 -0.082119) ;; 119+1 14.042466 (fv 0.000000 1.695702 0.296711 1.338908 -0.078265 1.044647 0.445401 1.570773 0.356080 0.726875 0.562835 1.121698 1.696368 0.511401 0.207025 0.089500 -0.565140 0.942644 0.652808 1.167682 0.412919 0.987661 0.705879 0.198820 0.440865 0.512441 1.083421 1.751114 -0.069762 1.661970 0.763824 0.509555 1.981466 0.038582 0.269865 1.492095 0.267412 1.351405 -0.147933 0.429115 1.485596 -0.131353 1.737203 0.373649 0.934842 0.295981 1.401570 1.025505 0.159868 1.751013 1.267064 0.606930 0.033477 0.655345 1.307003 1.298431 0.292781 -0.055933 0.016301 1.947579 1.426247 1.012103 1.014686 1.610683 0.794183 0.636102 1.398468 1.630487 -0.106933 0.019245 0.234173 1.454561 0.871538 0.489427 0.182807 1.191314 1.653186 0.812730 1.596587 0.968349 0.144419 1.254337 1.168160 -0.201543 0.642098 1.430541 0.891933 1.544951 1.231299 0.070309 1.961946 0.325740 0.895972 0.097452 0.983847 0.726652 1.390398 1.237569 1.108864 0.162933 1.463000 0.108857 0.104118 1.340850 -0.457424 0.750886 1.757915 1.530952 1.370214 1.508778 1.434766 0.846018 0.114800 0.004043 0.307829 -0.143116 0.279204 -0.090078 -0.107619 0.067028) ) ;;; 121 prime -------------------------------------------------------------------------------- (vector 121 17.782977183017 (fv 0 0 1 0 1 0 0 1 1 1 0 1 1 0 0 0 0 1 1 0 0 0 1 0 0 0 0 1 1 1 1 0 1 1 1 0 0 1 1 1 1 0 0 1 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 1 1 0 1 0 0 0 1 1 0 1 0 0 0 0 0 1 0 1 1 1 0 1 1 1 1 0 0 0 0 1 1 1 0 1 0 1 0 0 1 1 0 1 0 0 0 0 0 1 1 0 0 0 1 0 1 0 1 0 0) 14.145310 (fv 0.000000 -0.025891 1.793636 0.033424 0.540007 1.698366 1.937124 -0.609559 0.386368 0.372251 1.167122 0.009884 1.449702 0.151646 0.129257 0.221923 0.286263 0.194141 1.256596 -0.022208 0.587239 1.364223 1.036771 0.840539 0.300738 0.487086 1.849878 -0.356013 -0.244608 -0.042719 1.244769 1.401449 0.301842 1.027056 1.091793 0.623370 1.184562 0.517907 0.649838 0.331082 0.619154 1.467356 0.525086 0.836576 0.132708 0.186394 1.646954 1.207107 -0.124102 1.434383 0.438192 1.403615 1.086842 1.456374 0.098749 0.654033 1.469902 -0.092397 0.999549 0.914715 1.334656 0.842194 0.762721 1.400578 1.518574 1.628966 0.557815 0.576931 -0.575198 0.632751 1.009717 1.185394 -0.060402 1.274789 1.032399 -0.216393 1.814193 1.597562 0.558478 0.044897 1.319287 0.285577 -0.020660 1.082584 0.821657 1.849151 0.241943 0.297525 1.569624 1.593287 0.604518 1.347238 0.159734 0.361474 0.136103 1.298636 0.140131 1.192829 1.398339 0.674275 0.995843 0.943454 0.693721 0.589259 1.642401 1.051611 -0.266130 0.115428 0.439245 0.514540 1.691776 1.063362 0.306592 0.883309 1.563638 -0.186910 0.971866 0.448146 0.177042 1.080065 0.466207) ) ;;; 122 prime -------------------------------------------------------------------------------- (vector 122 17.876078447724 (fv 0 1 1 1 0 0 1 0 1 0 1 1 0 0 1 1 0 1 1 1 0 1 1 0 1 0 0 0 1 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0 0 0 1 1 1 1 1 1 0 0 1 1 1 1 1 0 0 0 1 0 0 0 1 0 1 0 0 0 1 1 1 1 0 1 0 0 0 0 1 0 0 0 0 0 0 0 1 0 1 1 0 1 1 1 0 1 1 1 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 1 1 0 1) 14.809716 (fv 0.000000 0.670494 1.886159 1.577487 1.777777 0.820522 0.567040 1.808673 1.691383 1.749354 0.999669 0.365962 -0.283305 1.315547 1.858625 0.083801 0.099076 1.593409 0.962399 0.938500 1.204685 1.174037 0.436114 0.616669 1.449802 0.424694 -0.043743 0.290754 0.536765 1.858591 1.302286 0.144562 1.898540 1.713336 0.304273 0.606056 -0.343580 1.320384 1.725243 1.070484 1.043894 1.041218 1.783423 1.623935 -0.119894 0.812509 0.330462 0.830339 1.651746 1.473863 0.826929 0.035844 0.962490 1.154392 0.108692 0.207697 -0.125372 0.785657 0.181654 0.507958 -0.099870 0.817795 0.576379 1.616959 1.203159 1.408060 0.803943 1.042280 0.347552 1.737313 1.151753 0.038129 1.376834 1.472899 0.308707 -0.055847 1.688664 1.527458 1.503192 0.428260 1.398802 0.697613 0.797253 1.257898 1.721624 0.405578 1.003490 0.227680 1.041522 0.134919 1.342074 1.464937 0.605066 -0.038087 1.389658 0.040933 0.121007 0.729584 0.212582 0.373515 1.668140 -0.235335 0.732650 0.289389 1.049347 -0.077662 0.429686 0.147005 1.585407 1.353860 1.815248 1.314972 0.285783 1.787337 1.040122 0.959573 1.461408 0.006176 1.591906 -0.004243 1.203878 1.856838) ;; from 121+1 14.077769 (fv 0.000000 -0.102882 1.749236 -0.004117 0.483853 1.765874 1.938255 -0.600392 0.405831 0.339694 1.084448 1.949979 1.449950 0.179825 0.196465 0.250508 0.230057 0.267538 1.186702 -0.013547 0.609348 1.275263 1.002412 0.929479 0.351264 0.550827 1.866085 -0.207369 -0.221459 -0.043981 1.181650 1.372732 0.322165 0.950666 1.016902 0.608561 1.206924 0.503654 0.566235 0.334378 0.545128 1.400875 0.599963 0.865496 0.228459 0.195440 1.563459 1.162224 -0.092823 1.463200 0.340144 1.432985 0.949791 1.498279 0.068471 0.623276 1.392543 -0.178909 0.913012 0.880422 1.353490 0.813253 0.747974 1.430440 1.480413 1.631261 0.640181 0.621156 -0.581884 0.645199 1.046241 1.177765 0.048757 1.254481 1.019786 -0.266200 1.761071 1.575419 0.546658 -0.000712 1.213661 0.352510 -0.036380 1.089333 0.735910 1.940744 0.321816 0.327061 1.683870 1.638125 0.601090 1.278317 0.270163 0.360522 0.023473 1.250704 0.243204 1.199993 1.329172 0.588810 0.966119 0.939463 0.761317 0.553614 1.599868 1.062777 -0.228048 0.241966 0.388550 0.647592 1.729999 1.118550 0.325131 0.887699 1.516026 -0.170170 1.006043 0.421332 0.259983 1.062250 0.497913 0.166635) ) ;;; 123 prime -------------------------------------------------------------------------------- (vector 123 17.273 (fv 0 0 0 0 0 0 1 0 1 1 1 0 0 0 1 0 1 0 0 1 1 0 1 0 0 0 0 0 0 0 0 1 1 1 1 1 0 1 1 1 0 1 0 0 1 0 1 1 0 1 0 1 1 0 1 0 0 1 1 0 0 0 1 1 1 1 0 1 1 0 1 1 0 1 0 1 1 1 1 1 0 1 1 1 1 0 0 0 1 1 0 1 1 1 1 1 1 1 1 0 1 0 1 0 0 0 1 0 0 1 0 1 1 1 0 1 0 1 0 0 1 0 0) 14.606318 (fv 0.000000 0.018375 0.589471 0.983384 0.991984 0.372395 -0.040275 0.299423 1.756771 0.367581 1.925315 0.431987 -0.091930 1.365768 0.790238 1.730935 1.453895 0.945086 0.541022 0.665855 -0.133333 1.898784 1.614955 0.125913 -0.075642 1.042483 1.409785 1.598074 0.355453 1.697472 1.704234 0.447761 0.702787 1.037349 1.268895 1.641450 0.389018 0.691038 0.964549 0.799007 -0.028923 0.682141 1.218121 0.346438 0.248506 0.187480 1.166792 0.799601 1.529262 1.053370 1.663430 1.815223 1.438810 1.297963 0.281072 0.228128 0.996820 1.126305 0.635366 1.152238 1.612305 0.687034 0.492102 0.223406 1.290673 0.404319 0.673144 1.585101 1.003033 0.671106 0.630415 0.262596 -0.092794 0.970586 -0.143151 1.120737 0.513895 1.346570 0.209142 0.468700 0.483816 0.465304 -0.188333 0.812984 1.400518 1.773921 1.423889 0.414054 -0.317948 0.988906 0.349734 -0.120165 0.609604 -0.196752 0.649574 0.752742 0.402866 1.001890 0.667657 -0.097642 -0.022329 0.780061 0.422052 0.637506 0.933615 0.491032 1.329969 0.891484 0.826863 0.432342 1.071482 1.483913 0.545228 0.886707 1.473772 1.459843 1.911936 0.601733 -0.070730 1.820410 1.529051 0.044995 0.589246) ;; 122+1 14.218431 (fv 0.000000 -0.071277 1.809148 -0.020616 0.407111 1.755823 1.904945 -0.715971 0.341233 0.449964 1.085208 0.031030 1.532200 0.268807 0.148267 0.268084 0.272209 0.202242 1.223891 -0.064002 0.629461 1.331632 1.050525 0.887285 0.370000 0.565442 1.910419 -0.226719 -0.262129 -0.049320 1.111879 1.377442 0.321129 0.921437 0.982936 0.703155 1.229920 0.446816 0.492798 0.314076 0.541522 1.414758 0.522185 0.801174 0.218712 0.168371 1.631951 1.208384 -0.085808 1.408101 0.423643 1.324899 0.982011 1.466628 0.095538 0.635570 1.314596 -0.072617 1.020892 0.911989 1.330565 0.770391 0.725410 1.510974 1.479974 1.759621 0.639552 0.614948 -0.510015 0.641435 0.965296 1.113277 0.074254 1.206499 1.003706 -0.366482 1.772703 1.570225 0.592942 0.091270 1.226107 0.311704 0.007633 0.964361 0.718780 1.974845 0.242071 0.343141 1.709800 1.693786 0.483738 1.265900 0.338851 0.340533 0.047929 1.263159 0.240281 1.186223 1.427920 0.613439 0.969107 0.960914 0.712662 0.596951 1.686986 1.021249 -0.262802 0.214377 0.402786 0.561682 1.740484 1.058116 0.341115 0.933358 1.469760 -0.231395 1.023135 0.404403 0.200269 1.060708 0.484072 0.072981 0.045518) ) ;;; 124 prime -------------------------------------------------------------------------------- (vector 124 17.868420183527 (fv 0 0 0 1 0 0 1 1 0 1 0 1 0 0 0 0 0 1 1 1 1 1 1 0 1 0 0 1 1 1 0 1 1 0 1 1 1 0 0 1 0 1 1 1 0 1 1 0 0 0 1 1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 1 1 0 1 1 1 0 1 1 0 1 0 1 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 0 0 0 1 1 0 0 0 1 0 0 0 0 1 1 1 1 0 1 0 0 0 1 0 0 1 1 0 0 1) 14.790618 (fv 0.000000 1.222162 0.999539 1.142487 1.505674 0.123191 1.078191 1.428308 0.398665 0.193203 0.342797 1.160548 0.272137 0.744922 1.397108 1.629980 0.516700 0.161533 1.540757 0.951466 1.306414 1.131481 0.340080 0.022600 1.902411 0.678905 -0.266096 0.618248 -0.195173 1.348860 1.656222 0.843246 1.086674 0.610041 0.732222 1.576567 -0.001222 1.325305 -0.206092 0.061466 0.937472 0.938375 0.951723 1.351728 0.822770 1.101763 0.749753 0.602996 1.016336 0.240295 1.282512 0.877283 1.675716 1.308583 0.020424 0.112525 1.125186 0.567562 1.325344 0.286941 1.392684 1.457107 1.070715 1.116929 0.019425 1.553921 0.611895 0.374394 1.517480 0.357614 0.351325 1.265831 1.671035 0.028656 0.694185 0.608779 0.968580 0.705917 0.557377 -0.050792 0.760543 1.517363 0.410154 1.478833 1.629314 1.203011 0.602580 1.412252 0.251943 1.776030 1.689098 1.335837 1.695826 1.914988 1.139727 1.661355 -0.008029 1.815582 0.952555 0.813836 0.589787 1.222025 1.184138 0.133013 1.235368 -0.243658 1.554911 0.580687 0.939871 0.323060 0.942785 1.574937 1.605974 1.858030 0.079942 -0.197497 0.010513 0.448075 -0.013192 0.950902 1.198378 1.685266 1.111201 1.137042) ;; 123+1 14.279834 (fv 0.000000 -0.081380 1.782165 -0.062634 0.363611 1.777729 1.870086 -0.748456 0.397000 0.457689 1.108119 0.004930 1.540452 0.247288 0.180358 0.333199 0.182296 0.178249 1.230554 -0.108533 0.646062 1.305622 0.825072 0.858877 0.381906 0.623442 1.836712 -0.249134 -0.191182 -0.125952 1.112553 1.374523 0.342721 0.833331 0.944734 0.720943 1.282090 0.390216 0.453997 0.358637 0.493600 1.372859 0.624272 0.735874 0.299299 0.184937 1.617155 1.281616 -0.070863 1.469387 0.307926 1.334541 0.930607 1.487203 0.131059 0.597353 1.290211 -0.242352 1.036453 0.942866 1.246650 0.636276 0.826032 1.531105 1.485955 1.813085 0.625741 0.627771 -0.579465 0.642188 0.969289 1.138476 0.074565 1.189823 0.939892 -0.416570 1.739435 1.565378 0.588268 0.099664 1.234765 0.379725 -0.063217 0.934469 0.845969 1.930710 0.181988 0.295750 1.696778 1.677311 0.505493 1.249700 0.433102 0.439581 0.020795 1.231023 0.285770 1.217649 1.421529 0.551828 0.924619 0.972048 0.789871 0.556108 1.717849 1.016229 -0.325643 0.376556 0.293594 0.487260 1.648794 1.072609 0.281420 0.961161 1.519437 -0.241812 1.031705 0.425825 0.197195 1.096632 0.361878 0.106170 -0.074233 0.005979) ) ;;; 125 prime -------------------------------------------------------------------------------- (vector 125 17.637776156888 (fv 0 1 1 0 1 0 0 1 0 1 0 0 1 1 0 0 0 1 0 0 1 1 0 0 1 1 1 1 0 1 1 0 0 0 0 1 1 0 0 0 1 1 1 1 0 0 0 0 1 0 1 0 1 0 0 0 1 0 0 0 1 1 0 0 0 1 0 0 1 1 1 0 1 0 0 0 0 1 0 0 0 0 1 1 1 1 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 0 1 1 1) 14.772411 (fv 0.000000 1.488367 0.539453 0.636319 1.701536 0.864646 0.653079 -0.015234 -0.146959 -0.016393 1.159310 0.253720 0.483376 0.791134 0.148523 1.139178 0.651015 0.419622 1.011424 1.343222 0.375202 1.487445 1.136349 1.264222 1.195821 1.118452 0.058438 0.180283 -0.364874 1.141390 0.108460 0.432578 1.082489 -0.344327 0.561149 -0.050777 0.153514 0.046289 0.013379 0.201861 0.723817 0.636257 0.099730 -0.252366 1.579710 1.247947 0.727318 0.604484 0.768675 1.814508 0.866882 0.945446 1.203952 0.553202 1.570818 0.438899 1.210503 0.074303 1.805294 1.142851 0.477720 0.743449 -0.030259 0.761798 0.442190 0.180723 0.743309 -0.143585 1.116545 1.404371 0.204979 0.238499 1.331119 1.234638 1.176686 1.242725 0.433339 0.737611 -0.052694 0.108421 1.540317 0.211091 1.637087 0.618282 0.999958 1.643481 0.805826 1.863967 0.824505 0.797379 0.836059 -0.009548 1.065334 1.608230 -0.042496 0.454917 0.581669 0.915626 0.146732 0.685151 0.520442 1.115897 0.367688 0.129909 1.145807 0.921815 0.252576 -0.010734 0.180757 1.854774 0.546533 1.532747 1.382619 0.143523 0.214257 0.954384 0.657013 1.826584 1.432640 0.172761 -0.181378 1.290872 1.519863 0.506886 0.104986) ;; 124+1 14.335616 (fv 0.000000 -0.073704 1.756721 -0.027521 0.555274 1.787030 1.851198 -0.739687 0.444117 0.371512 1.030097 0.041170 1.545538 0.189519 0.163161 0.279241 0.173564 0.127795 1.239047 -0.127708 0.674274 1.329026 0.927305 0.921971 0.291034 0.575583 1.919448 -0.265928 -0.189299 -0.242314 1.071327 1.320148 0.401414 0.885029 1.046562 0.775451 1.215839 0.374013 0.421290 0.242139 0.417910 1.413086 0.643233 0.744664 0.179383 0.219870 1.572661 1.345306 -0.060756 1.371806 0.318705 1.344767 0.903717 1.446972 0.029587 0.642047 1.254548 -0.199918 1.025990 0.987502 1.268140 0.763438 0.716412 1.540475 1.448750 1.854247 0.619685 0.691226 -0.557884 0.607847 0.974173 1.151524 -0.000158 1.208581 0.923167 -0.344361 1.808080 1.613014 0.625897 0.097908 1.229154 0.352252 -0.000924 0.978476 0.892610 1.915124 0.237884 0.295218 1.727938 1.672743 0.433468 1.238004 0.487776 0.417610 0.023342 1.153124 0.251246 1.196960 1.459291 0.552975 0.974914 0.953186 0.742186 0.557329 1.742338 1.006012 -0.331621 0.294231 0.321006 0.465332 1.742325 1.134043 0.251983 0.900167 1.477710 -0.206427 1.075443 0.425293 0.211597 1.112385 0.321994 0.162492 -0.098661 0.047474 0.072546) ) ;;; 126 prime -------------------------------------------------------------------------------- (vector 126 18.284595039843 (fv 0 0 0 0 1 1 1 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 0 1 0 0 0 0 0 0 0 0 1 1 0 0 1 1 1 1 1 0 1 1 0 0 1 0 0 0 1 0 1 1 1 1 1 0 0 1 1 0 1 0 1 1 1 1 1 1 0 0 1 0 1 0 0 0 0 1 1 0 1 1 0 0 1 0 0 1 1 0 0 1 0 1 1 0 0 1 1 1 1 0 0 0 1 1 0 0 1 0 1 1 1 0 1) 14.919977 (fv 0.000000 1.469803 0.590807 0.764079 1.791170 0.333377 0.787711 1.497688 1.425800 1.198769 -0.142602 1.315353 -0.073058 1.238142 -0.046252 1.358363 0.881227 0.034517 0.376307 0.332870 0.693500 1.217503 0.199404 -0.446423 0.007791 1.544042 1.693684 1.705920 0.539256 1.329303 -0.184478 1.516336 1.012314 1.494800 1.597619 0.336783 1.080235 0.583130 1.276101 1.725256 0.652789 1.276830 1.460138 1.593259 0.514539 1.170620 1.278633 0.619783 1.325249 1.591358 0.207365 1.060129 0.815013 0.040269 1.468914 0.227402 0.515366 0.731820 0.621073 0.837063 1.275146 0.259307 0.585385 0.909317 0.921047 0.261764 0.230595 1.268807 1.340737 0.628738 0.406147 1.678580 0.814730 0.487283 1.140440 0.869819 1.474812 0.775855 -0.116531 0.130586 0.641169 1.517310 1.370799 1.423659 0.321563 0.178649 1.411675 1.146911 0.966764 1.521079 1.121859 -0.427787 0.506332 1.644605 1.138614 1.523684 0.664505 0.648038 0.075277 0.416802 0.443365 1.235830 1.173282 1.107298 0.136026 -0.032457 1.449977 -0.023926 1.087880 -0.136228 1.342249 1.136201 1.846662 0.865407 0.833970 1.810099 1.018847 -0.107251 0.065627 1.367299 0.507024 0.142912 1.416639 0.609252 0.711456 0.417251) ;; 127 - 1 14.478183 (fv 0.000000 0.930861 1.435103 1.015217 0.133148 0.287358 1.954448 0.877191 -0.313979 0.188033 1.404924 0.797822 1.641089 -0.072460 0.883498 1.253629 0.955039 1.649989 1.112182 0.909200 1.887346 0.566087 0.831325 1.595619 1.015259 1.132981 1.214225 1.758075 1.475152 1.620993 0.072446 -0.059078 -0.182289 -0.039338 0.155445 0.529297 0.046388 1.441668 0.535178 0.222607 0.659275 1.874433 0.311495 1.718719 0.434358 1.778879 1.619012 0.517997 0.354459 -0.261087 0.248995 1.922764 0.605114 1.052457 -0.265751 1.118974 0.375392 1.608325 1.902594 0.729575 1.283255 1.305350 0.868120 1.355763 1.680987 0.242830 0.477218 1.016250 0.628871 -0.030446 0.679211 1.826138 1.874720 1.129680 1.690954 1.195384 0.889438 1.205646 1.461460 -0.453690 0.712708 1.258870 1.879622 1.875344 1.343716 1.283838 0.647289 0.933542 0.025722 -0.304513 0.859639 0.850257 0.333502 1.942927 1.798084 1.335700 0.932797 0.281618 -0.061736 1.117606 1.074494 0.424155 0.429073 1.579564 1.707609 0.889204 0.016152 1.499631 0.327239 1.110073 0.816898 0.676932 0.517090 0.873228 0.943685 1.557236 1.328668 0.393069 1.595818 0.801812 0.427544 0.632088 1.930520 1.052145 0.001869 0.373834) ) ;;; 127 prime -------------------------------------------------------------------------------- (vector 127 18.198689419357 (fv 0 0 0 1 0 0 1 0 1 0 0 0 1 0 1 1 1 0 0 1 0 1 1 0 1 0 1 0 0 0 0 1 0 1 1 0 1 1 1 1 0 1 0 0 1 1 1 0 0 1 1 0 1 1 1 1 0 1 1 0 1 0 1 1 1 1 0 1 0 0 0 0 1 1 0 1 1 0 0 0 0 0 0 1 1 0 0 1 0 1 1 1 1 1 1 1 1 0 1 1 0 1 1 0 1 1 0 1 0 0 0 0 1 1 0 1 0 1 1 0 0 0 1 1 1 1 1) 14.912432 (fv 0.000000 -0.112564 0.330831 0.563931 0.720452 1.659462 1.770279 1.222445 1.859857 0.126001 0.651461 1.215294 -0.233033 0.427403 0.814844 0.606037 1.919973 0.930971 0.148326 0.698675 1.110446 0.338577 1.107127 0.863142 1.130521 0.352666 0.715295 1.098761 0.639947 1.470989 0.137887 1.186298 0.901174 1.895291 0.359770 0.973168 1.699946 0.771080 1.375904 -0.248826 1.181644 1.789978 0.712701 0.277767 1.875124 0.813518 1.712932 0.451921 0.276945 1.323596 1.302350 1.483287 1.090079 0.743389 1.264854 1.950370 0.782969 0.914279 0.320477 0.990740 0.622004 0.030993 0.934242 0.961767 0.268688 1.789126 0.206081 0.101936 -0.529878 1.903369 0.539774 1.823204 -0.147241 0.928082 0.776302 1.167127 1.638509 1.576221 0.666141 0.750484 0.892326 0.100670 1.158426 0.166814 1.186903 1.306719 1.235546 0.635532 0.425679 1.719459 0.863874 0.092801 1.266262 1.369621 1.347298 0.966081 0.206817 0.754899 1.254971 0.922627 0.087389 0.135770 0.821247 0.230310 1.412479 0.655130 0.149628 1.814319 1.923709 1.016259 0.975859 0.575686 1.520455 1.205512 0.978744 1.845650 0.833521 0.220528 0.380346 0.141961 -0.028883 0.515081 0.897680 0.876651 0.794347 1.289685 0.792317) ;; 128-1 14.536393 (fv 0.000000 0.910972 1.475131 1.009861 0.062727 0.222323 1.938743 0.836711 -0.379271 0.255108 1.367947 0.841274 1.648864 0.015930 0.884691 1.125991 0.989606 1.607929 1.107388 0.857011 1.831346 0.433218 0.833149 1.592445 1.050762 1.008151 1.363530 1.700977 1.491038 1.682961 0.086100 -0.103806 -0.179348 0.003896 0.165438 0.493687 0.089620 1.387284 0.581547 0.176309 0.705269 1.811651 0.301490 1.707605 0.333845 1.832817 1.652148 0.600871 0.309714 -0.231587 0.303261 1.879368 0.673797 1.138199 -0.287759 1.071255 0.390644 1.597999 1.895638 0.729896 1.280128 1.313792 0.920129 1.387655 1.675038 0.226144 0.498585 1.104083 0.607578 0.005976 0.644124 1.859066 1.816208 1.159654 1.721231 1.377183 0.892151 1.087634 1.544878 -0.427006 0.761009 1.308993 1.890672 1.804683 1.325584 1.333615 0.649826 0.878906 0.043600 -0.222822 0.983855 0.725901 0.429955 1.892651 1.820617 1.395993 0.939478 0.246907 -0.065788 1.167118 1.004041 0.432075 0.450312 1.618752 1.686873 0.868341 1.893872 1.401676 0.376204 1.113598 0.748962 0.732995 0.557016 0.919800 0.871855 1.529811 1.275389 0.387399 1.586418 0.758929 0.456983 0.576267 1.810711 1.106484 0.012213 0.311973 1.081248) ) ;;; 128 prime -------------------------------------------------------------------------------- (vector 128 18.276384353638 (fv 0 0 1 0 1 0 0 0 0 1 0 0 0 1 1 0 1 1 1 1 0 1 1 1 0 0 0 0 0 1 0 0 1 1 0 1 1 0 0 0 0 0 1 0 1 0 1 0 1 1 0 1 0 0 0 0 1 1 0 1 1 1 0 1 1 1 0 1 1 0 1 1 1 0 1 1 0 0 1 1 0 0 1 1 0 1 0 0 1 1 0 0 1 0 0 1 0 1 1 1 1 0 1 1 1 0 0 1 0 0 0 0 1 1 1 1 1 1 0 1 0 1 1 0 1 0 0 1) 14.551285 (fv 0.000000 0.924459 1.485422 0.985256 0.056811 0.219930 1.908499 0.913743 -0.403193 0.259904 1.334649 0.827148 1.624714 -0.021872 0.937257 1.122813 0.961899 1.532146 1.148701 0.868319 1.827482 0.356035 0.897995 1.553711 0.943178 0.960525 1.352917 1.720117 1.523327 1.617955 0.013172 -0.149597 -0.137644 -0.034035 0.111097 0.498787 0.121406 1.399436 0.620595 0.082527 0.702328 1.824635 0.362315 1.752651 0.335052 1.794344 1.642190 0.610334 0.262361 -0.222978 0.248243 1.869656 0.644580 1.192948 -0.312319 1.070271 0.368940 1.593867 1.836900 0.676177 1.276819 1.276408 0.936758 1.361721 1.692175 0.215294 0.511916 1.079847 0.588820 0.055407 0.579633 1.891289 1.810098 1.133091 1.733591 1.452365 0.980479 1.078929 1.556717 -0.427469 0.779143 1.336023 1.912299 1.782248 1.339461 1.329616 0.616924 0.917615 0.006788 -0.195359 0.981816 0.758001 0.419952 1.868089 1.758394 1.479010 0.921655 0.244745 -0.038674 1.158515 0.987245 0.469852 0.442126 1.652528 1.699770 0.900506 1.793377 1.368738 0.405805 1.083967 0.706228 0.759055 0.550546 0.985536 0.835398 1.537041 1.252754 0.414912 1.587016 0.741668 0.441787 0.537126 1.829954 1.207186 -0.038603 0.324826 1.093300 0.845470) ) ;;; 256 prime -------------------------------------------------------------------------------- (vector 256 27.740 (fv 0 1 0 1 0 1 0 1 0 0 0 0 0 1 1 0 1 0 1 1 1 1 1 1 0 1 1 0 1 0 1 0 0 1 0 1 0 0 0 0 0 1 1 0 0 1 1 0 0 1 1 1 0 1 0 0 1 1 1 1 1 1 0 0 1 0 0 0 1 0 1 0 1 1 1 0 0 0 0 0 0 1 1 0 1 0 1 1 0 0 0 0 1 0 0 1 1 1 1 1 1 0 1 1 1 0 0 0 0 1 0 1 0 1 0 1 0 0 0 0 1 0 0 0 1 0 0 1 0 1 1 1 1 0 0 0 0 0 1 1 1 1 0 0 0 1 0 1 1 0 1 1 0 1 0 0 0 0 0 1 1 0 0 0 0 0 0 1 0 0 1 1 0 0 1 1 0 1 0 1 1 0 0 0 1 1 0 1 0 1 1 1 0 0 0 1 0 0 1 0 1 0 0 0 1 0 0 1 1 1 0 0 1 1 0 0 1 0 1 1 0 1 1 0 0 0 1 1 0 1 0 1 0 0 1 0 0 1 1 1 1 1 1 1 0 1 1 1 0 0 1 0 0 0 0 1) 23.954812 (fv 0.000000 1.204657 1.078759 1.682184 0.289433 1.857298 -0.103078 0.812130 1.708916 1.896961 1.156555 1.703874 1.227021 0.182267 1.041071 0.489158 1.008682 0.135723 0.046495 1.634992 0.566031 1.311776 1.337489 0.673226 1.836763 0.159154 0.202747 0.341271 0.471573 0.119586 1.124289 1.100574 1.091468 1.313210 0.642853 0.117292 -0.058379 0.647409 0.710309 0.207284 0.060417 0.146614 1.530493 1.426852 1.584556 0.403196 0.281684 1.359791 1.211733 1.335753 1.885602 1.477601 0.688497 0.894421 1.600991 1.328569 0.005997 0.453096 0.992624 0.185444 0.508566 0.835246 0.264281 0.242464 0.561992 0.572786 1.360366 0.402158 1.414686 0.275179 0.381572 -0.113917 0.093761 0.181937 1.876554 0.763184 0.742398 0.316668 0.919942 0.466632 1.953058 0.269310 1.678357 0.562522 0.033550 0.978955 0.884214 0.441468 1.069549 1.818992 0.418629 1.336178 1.464108 0.008854 1.818306 0.399905 1.080809 0.763485 0.787603 1.378379 0.936433 0.806686 0.536881 1.819028 1.671276 0.786432 1.275261 1.884577 0.933469 1.355576 1.479258 0.462174 0.332804 0.282457 0.550215 0.317652 0.454496 0.923565 0.787078 1.464952 0.107434 1.071904 1.315331 0.744343 0.731492 0.092424 1.422672 1.730219 1.887932 1.793030 0.347585 0.560825 1.039175 1.321464 0.820946 1.971856 1.662872 1.726858 0.163305 0.618347 1.843241 1.984311 0.060498 0.046747 0.257781 0.365656 1.677750 -0.207494 0.053362 0.938280 1.295484 0.245637 0.522272 1.268074 1.776463 1.391102 0.235187 1.356696 0.411477 0.726380 0.608354 1.031435 0.374485 1.212534 0.683978 1.636985 -0.020727 1.002990 0.490099 1.193211 1.072433 1.116935 0.177132 1.577198 1.488833 1.426992 0.196808 1.359200 0.812178 0.923445 1.498869 0.535636 1.325569 0.453085 0.957271 0.999087 0.721363 0.748530 0.296873 0.424017 1.951248 0.179282 0.622927 -0.057442 0.420195 1.292402 0.421561 0.376166 1.549061 0.996315 0.165646 0.418099 0.201640 0.421702 0.831456 0.106402 1.463327 0.005503 1.240637 0.776492 0.181978 0.800991 0.047810 1.685961 1.102672 1.488982 0.855213 0.435527 1.756187 1.183435 0.997613 0.162344 0.965285 0.203761 1.756880 0.117280 1.723671 0.647873 1.760056 1.248565 0.397491 1.167098 0.048428 0.194870 -0.145837 0.946144 1.336821 0.037491 0.496156 0.411789 1.814729 0.171113 0.774274 1.046076 0.369134 1.865905 1.353847 0.811560 1.792633 0.305766 0.578868 1.799589 0.584644 1.768023 1.140595 0.983334) ) ;;; 512 prime -------------------------------------------------------------------------------- (vector 512 43.486 (fv 0 1 0 0 1 0 0 0 0 0 1 1 1 0 0 0 0 0 1 1 1 0 1 0 1 0 0 0 0 1 0 1 1 1 1 1 1 0 0 1 0 0 0 1 1 1 1 1 1 1 1 0 1 1 1 1 0 0 1 1 0 1 0 0 1 1 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 1 1 1 0 0 1 0 1 0 1 0 0 1 1 0 1 1 0 0 1 0 1 0 1 1 1 0 1 1 0 0 0 1 1 1 0 0 1 1 1 1 0 0 0 0 1 0 0 0 1 0 1 0 0 0 0 0 1 0 1 0 1 0 1 1 0 0 1 1 0 0 1 0 0 0 0 1 0 1 1 0 0 1 1 1 0 1 1 1 1 1 1 0 0 1 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 1 1 1 1 0 0 0 1 0 1 0 1 0 1 1 0 1 0 0 1 0 0 0 1 0 1 1 1 1 0 0 0 1 1 1 0 1 1 1 1 0 1 1 1 1 1 1 1 1 1 0 0 1 0 1 1 1 1 0 0 0 1 1 0 1 1 1 0 1 0 0 0 0 1 1 0 0 1 1 0 1 0 0 1 0 0 0 1 1 0 0 0 1 1 0 1 0 0 1 0 0 1 1 1 0 0 0 0 1 1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0 0 1 0 0 1 1 0 1 1 0 1 0 1 0 1 0 1 1 0 0 1 1 0 0 0 1 0 0 0 1 1 1 1 0 0 1 1 1 1 1 1 0 1 1 1 1 1 0 1 0 0 1 0 1 0 1 0 1 0 0 1 1 1 1 1 1 0 1 1 0 0 0 1 1 0 0 1 0 1 1 1 1 1 0 1 1 1 0 0 0 0 1 0 1 1 1 0 0 1 1 1 0 0 1 0 0 1 0 1 0 1 1 1 1 1 1 0 1 1 1 0 0 1 1 1 0 0 0 1 1 0 1 0 1 0 0 1 1 1 1 1 1 0 1 1 0 0 1 0 0 1 1 1 1 0 0 1 0 0 1 0 1 0 0 1 1 1 0 0 1 0 1 1 1 0 0 1 1 1 1 1 1 1 1 0 1) 38.602884 (fv 0.000000 1.082143 1.690042 0.893575 0.756109 0.365343 0.807438 0.940757 0.585435 0.342350 0.594341 1.140652 1.817226 1.102492 0.331462 1.612595 0.512173 -1.909591 0.094152 0.360726 0.151765 0.706858 0.749498 1.906233 1.235313 0.796232 0.500830 0.064536 1.490244 0.959772 0.522500 0.779779 0.400580 1.439171 1.288511 1.693600 1.634346 1.612029 0.250323 0.286364 -0.273948 -0.057072 0.444920 0.673291 1.660718 0.950511 -0.044480 1.277714 0.922828 1.742498 0.067040 1.123761 0.731844 1.393404 1.039320 1.324896 1.831174 0.387406 1.709067 0.274769 1.267431 0.959919 0.715608 1.693570 0.000362 1.870214 0.699669 0.668933 0.997821 -0.008050 1.092934 0.993144 0.278118 0.973866 0.508203 1.715050 0.139916 0.132362 1.047327 -0.053979 0.185439 0.405403 1.344059 0.788131 1.083324 0.893261 1.764451 1.883814 1.299760 0.554300 0.979273 1.155257 1.533722 0.768283 0.256481 0.366299 0.921394 1.649597 0.976718 0.165847 0.006944 0.856772 0.899715 1.074092 0.112821 1.082075 0.258835 0.138175 -0.004825 0.001351 1.429175 0.630347 0.684026 0.531342 0.847633 0.762458 0.815632 0.219787 0.092949 0.202477 0.797900 -0.145417 -0.117708 1.761218 0.769741 1.161104 1.342323 0.523211 0.405201 0.497008 0.787122 1.231664 1.866867 0.811507 1.822296 0.236359 -0.004728 0.793757 0.887814 1.429788 1.804982 1.942786 0.923502 0.603222 0.794618 0.368216 1.088308 0.796327 0.542686 1.544013 1.716025 0.878200 1.782174 0.062214 0.364255 0.646601 0.833457 0.599270 0.751311 0.607033 1.116295 0.605117 1.252490 0.144452 0.065646 0.340371 1.042827 1.788314 1.880686 0.569623 0.189168 0.776287 1.195192 0.727742 0.491941 0.571446 0.260116 1.294844 -0.224851 1.513707 1.029946 1.744464 -0.045793 1.705297 0.170929 0.776558 1.159210 1.100586 0.974908 0.889723 0.131669 1.514065 0.483669 0.374957 1.765248 0.173880 1.574655 0.579673 1.075226 1.695626 0.618344 0.910042 1.785601 1.685191 1.340397 -0.031592 1.930247 1.607968 0.311691 1.234826 1.008031 0.136574 0.693831 1.350593 1.790691 1.248723 0.321392 0.332409 0.211515 0.677389 0.675342 0.748083 1.542146 0.537541 0.945052 0.644544 1.587504 -0.198604 0.497285 1.589685 1.631769 -0.102021 1.434262 0.504366 1.007294 -0.071908 0.889783 0.106723 1.597262 1.184125 1.385914 1.784083 1.814813 1.444514 0.168106 0.275712 -0.230240 1.482952 1.749244 0.624319 0.820132 0.038543 0.453451 1.192705 1.551536 0.933988 1.412615 0.290421 0.996887 0.879431 1.841715 0.672561 0.642185 1.873294 1.346219 1.516340 0.034439 -0.025203 0.114641 1.027748 0.436673 1.695049 0.946949 0.531849 0.288148 0.279537 1.094778 0.375490 0.307554 0.627782 0.418409 0.832934 0.666935 0.114950 -0.053285 1.218299 1.879745 0.386673 0.915368 -0.165173 1.124058 0.466149 1.878428 1.629128 1.512993 0.806896 0.046040 1.932554 1.129093 0.063911 0.559840 1.823056 0.947920 0.467855 1.479381 1.855655 0.408469 1.725599 1.305170 0.270211 0.911615 0.523954 1.318986 1.354400 1.104393 0.792536 0.687738 1.816953 0.079500 1.734615 0.148004 0.393542 1.491324 1.809997 0.036899 1.917219 0.036016 1.292915 1.439271 0.992174 0.734749 0.043086 0.632449 1.678465 1.214089 0.407041 1.157576 0.467194 1.849834 1.465874 1.299867 0.452820 0.577350 1.178402 0.504471 1.704246 1.529399 0.119449 1.587272 1.187154 1.736018 1.251019 0.054071 0.448967 1.151610 -0.041983 -0.058564 1.189234 1.429143 1.489017 0.205182 1.257753 0.994036 0.781546 0.390902 0.744400 1.772431 0.919261 0.499894 0.419934 0.281518 0.736860 0.910447 1.681100 1.722013 1.141474 0.827377 0.320102 0.007503 0.593080 1.581219 0.475353 0.227567 1.630156 0.895436 0.162740 0.389713 0.427078 0.505436 0.990570 0.227561 1.922194 1.293488 0.525156 0.798692 0.804781 1.222760 -0.002373 0.214414 1.011966 1.489753 0.749041 1.209362 1.542616 0.129806 1.948618 0.096126 0.340987 1.210097 1.746925 0.607998 0.771692 0.843752 0.870293 0.931325 1.216995 -0.219011 0.558727 0.605157 0.764943 0.813267 0.109796 0.025290 0.418750 0.976910 0.611063 1.425653 1.312703 1.416454 1.541723 0.279510 0.000239 1.660016 0.196937 1.482933 0.237398 1.048222 1.226372 0.074770 0.565242 0.782888 1.814840 1.669287 0.878760 1.658003 1.628831 0.063412 1.934276 0.152397 1.633067 1.697411 0.919379 1.358819 1.021028 1.568829 0.560019 1.191100 1.722100 0.879855 0.967865 1.958702 0.180163 1.190964 1.472899 0.387723 1.635329 -0.004167 1.194302 0.101361 0.922515 1.847355 1.174116 0.380497 0.721821 1.201075 1.612741 1.020268 -0.168817 0.406276 1.455790 1.666789 0.232089 1.791143 1.515844 0.427944 0.351285 1.732308 0.954418 0.569378 1.065546 1.527300 1.587063 1.317922 0.415597 0.001422 1.240139 0.099248 1.639437 1.663543 0.562245 1.762090 1.669121 1.738347 1.503729 0.665114 0.450457 0.358214 1.358391 1.040768 0.320330 -0.191120 1.844458) ) ;;; 1024 prime -------------------------------------------------------------------------------- (vector 1024 70.140 (fv 0 0 1 1 0 1 0 0 0 0 0 0 1 1 0 0 0 0 1 1 0 1 1 0 1 0 1 0 0 0 0 0 1 0 1 0 0 0 0 1 0 0 1 1 1 0 1 0 1 0 0 1 0 0 1 1 1 0 1 1 1 0 1 1 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 1 0 0 1 1 0 0 1 0 1 1 0 0 1 0 0 1 1 1 1 1 1 0 1 1 1 1 1 1 0 0 1 0 0 1 1 1 1 0 0 1 1 1 1 1 1 0 1 1 0 1 0 0 1 1 0 0 1 1 1 1 0 0 1 1 1 0 0 0 1 1 0 0 0 0 1 0 1 0 1 1 1 1 0 1 0 1 1 0 1 1 0 0 0 1 1 0 0 1 0 1 0 1 0 1 0 1 1 1 1 0 1 0 1 1 0 1 1 1 0 1 0 1 0 0 0 1 0 0 1 0 1 0 0 1 0 1 0 0 0 1 0 1 0 1 0 0 1 1 0 1 0 0 0 0 1 0 1 1 0 0 0 1 0 0 1 1 1 0 0 1 1 0 1 0 1 1 1 1 0 0 0 1 1 1 1 1 0 1 0 1 1 0 1 0 1 1 1 0 0 1 1 1 1 0 1 0 0 1 1 0 0 1 0 1 1 0 0 1 0 0 0 1 1 1 1 0 1 0 1 0 0 1 0 0 0 1 0 0 0 0 1 1 0 0 0 1 1 0 1 0 0 1 0 1 0 1 1 1 1 0 1 1 1 0 1 0 1 1 1 1 1 1 1 1 1 0 1 1 0 0 1 0 1 1 0 1 0 0 1 1 1 1 0 0 1 1 1 1 1 0 0 1 1 1 1 0 1 0 1 1 1 1 0 0 1 0 1 0 1 1 0 0 0 0 0 1 1 0 1 1 1 1 1 0 0 1 1 0 0 1 0 1 0 0 0 0 0 1 1 0 0 0 0 0 1 0 0 0 1 0 1 1 1 0 1 1 0 1 0 1 1 1 1 1 1 0 0 1 0 0 1 1 0 1 1 1 1 1 1 0 0 1 0 1 1 1 0 0 0 0 1 1 0 1 1 1 0 0 1 0 1 1 0 1 1 0 1 0 0 1 1 1 0 1 1 0 0 0 0 0 1 1 0 1 0 1 0 1 0 0 1 1 0 0 0 1 1 1 1 1 0 1 1 0 1 0 0 0 0 1 0 0 1 0 0 0 1 0 0 1 1 0 0 1 0 1 0 0 0 0 0 1 1 0 0 1 0 0 1 1 1 1 0 0 1 1 1 0 0 1 0 1 1 0 1 0 0 1 1 1 1 0 1 1 1 1 1 1 1 0 0 1 0 1 0 1 0 0 1 1 0 0 1 1 0 1 1 1 0 1 1 1 0 1 0 1 1 1 1 1 0 1 0 1 1 0 0 0 0 0 0 1 1 1 1 1 0 1 1 1 1 0 1 1 1 0 0 0 0 0 1 0 0 1 0 0 1 1 1 1 1 1 1 1 1 0 0 1 1 1 0 1 0 1 0 1 1 1 1 0 1 0 1 0 0 0 1 0 0 0 1 1 0 1 1 0 1 0 0 1 1 0 1 1 1 0 0 1 0 1 1 1 0 1 0 1 0 1 1 0 1 1 1 0 1 1 0 1 0 0 1 1 0 1 1 0 0 1 1 0 0 0 0 0 1 0 1 0 1 1 1 1 0 1 1 1 1 0 1 1 0 0 1 1 0 1 0 1 0 0 0 0 1 1 0 1 1 1 0 0 1 1 1 0 1 0 1 0 0 1 1 0 1 1 0 0 1 1 0 0 0 1 1 0 0 1 1 1 1 1 0 1 0 0 0 0 1 0 1 0 0 0 1 0 0 0 0 1 1 0 1 0 1 0 0 1 0 0 1 0 1 0 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 1 1 0 1 1 0 0 0 0 0 1 1 0 1 0 0 1 1 1 1 1 1 1 0 0 0 0 0 1 1 0 0 1 1 0 0 1 0 1 1 1 1 0 1 1 0 1 1 0 1 0 0 1 1 0 0 1 0 0 0 1 1 0 0 1 0 0 1 0 1 0 1 1 1 1 0 0 0 1 1 0 1 1 0 0 1 0 1 1 1 0 0 1 0 0 1 0 0 0 0 1 1 0 1 0 1 1 0 0 1 1 1 0 1 1 0 1 0 0 0 0 1 0 1 1 0 1 0 0 1 1 0 1 0 0 0 0 0 0 0 1 1 1 1 0 0 1 0 1 0 1 1) 65.349256 (fv 0.000000 -0.129848 0.969209 0.836351 0.061754 1.032484 0.051397 -0.047672 0.218624 0.018916 -0.064346 -0.087720 0.896115 1.194836 0.077672 -0.093665 -0.097710 -0.086592 0.949666 1.122929 -0.067767 0.950039 1.122745 0.018018 0.930855 -0.245701 0.859196 -0.118393 -0.017421 0.154025 -0.211100 -0.109137 0.940842 -0.140564 0.967517 -0.167684 0.023269 0.025376 -0.045911 0.903419 -0.200515 -0.239733 0.820269 1.087952 1.103155 -0.067139 0.794572 -0.000447 0.796383 -0.050127 -0.097253 1.071546 0.028226 0.109239 0.999458 0.870447 0.946254 -0.081085 1.245293 0.861076 0.913395 -0.009593 0.921868 1.075746 0.111204 0.213778 0.007799 0.861516 0.879520 1.119282 1.112758 0.023180 0.087708 -0.039342 0.017034 -0.142251 -0.066926 0.123437 -0.087868 0.910913 0.108597 -0.196132 1.069560 1.014239 0.192506 0.075011 0.674937 -0.174632 1.062546 0.982886 -0.071153 -0.102231 1.008769 -0.021251 -0.043692 0.910660 1.203363 0.930076 1.192149 1.079643 1.139869 -0.102933 0.892075 1.081967 1.117296 1.069641 0.961155 0.889926 0.104236 -0.012679 1.018557 0.083425 0.102764 1.041332 1.049506 1.057530 0.927572 -0.192969 -0.132492 0.997314 1.171628 1.067315 1.038820 1.033745 1.322831 -0.007981 0.994085 0.965156 0.070645 1.143780 -0.097751 -0.035141 1.081372 0.841845 0.110341 -0.016561 1.124066 1.050833 0.937074 0.926741 -0.150226 0.056436 0.964946 1.014226 0.961483 0.200116 -0.027025 -0.042596 0.873435 1.128675 -0.074217 0.034750 0.002625 0.037174 1.052187 -0.007505 1.057468 -0.020629 0.954765 1.162873 0.836305 0.919671 0.176115 0.867824 0.159416 0.913293 0.972493 -0.057629 0.902111 0.973589 -0.086627 -0.008031 -0.139087 0.943821 1.137966 0.070214 -0.004563 0.871135 -0.028372 0.970905 -0.036782 0.845326 0.108872 0.880706 -0.063917 0.888627 0.925543 1.066596 0.853571 -0.093806 0.904332 -0.112339 0.945758 0.871634 -0.096140 1.001890 1.129246 0.963672 0.170539 1.085873 0.061910 1.045363 -0.043655 0.071480 -0.112838 1.140479 -0.203871 0.018032 0.967477 -0.109462 0.786798 0.159117 0.091987 1.000511 0.121439 0.998700 0.114766 0.043124 -0.051500 1.039391 -0.116269 0.884009 0.038584 0.870599 -0.009894 -0.177026 1.208055 1.281757 0.041090 1.074146 -0.185247 -0.160109 -0.084894 -0.013678 1.116236 0.043626 0.914436 1.186335 0.008002 -0.013450 -0.068550 0.867764 -0.069795 0.028624 1.053037 1.105179 1.148503 -0.078114 -0.107345 0.808140 0.888280 -0.101397 0.863680 -0.177989 0.805880 0.985054 0.997369 0.970739 0.045371 0.041317 -0.112380 1.007911 0.837435 0.969586 0.893134 1.011096 0.079245 0.911597 -0.043743 1.012740 1.031412 0.069924 0.910651 0.066980 0.855519 1.128309 1.046886 -0.009687 -0.147082 0.900969 1.137525 0.881305 1.084781 -0.031000 1.031283 0.123503 -0.135598 0.951868 0.887466 -0.122854 -0.039498 1.017664 -0.102471 1.018993 1.022945 0.093609 0.101814 1.044330 -0.102747 0.051954 0.001832 1.002061 1.025387 0.930853 0.958319 0.146189 0.932064 0.106399 1.032653 0.014707 0.032026 0.879101 -0.027770 0.031687 0.111934 0.802921 -0.076047 0.059286 0.065123 0.128711 0.974155 1.040636 -0.158251 -0.044445 -0.146345 1.152523 0.901758 -0.061750 0.921515 0.108254 -0.128639 1.088615 0.119335 1.107712 0.012965 0.831934 0.917791 0.827352 0.931376 0.029208 0.968659 1.110903 1.139422 0.103217 0.804597 0.104877 1.024813 1.110962 1.158506 1.074313 0.918885 1.091629 1.052239 1.155470 0.969547 0.176177 1.193274 1.000806 0.167489 -0.087811 1.272916 0.090580 0.837388 0.853777 0.021673 0.795498 0.153088 -0.039163 0.886259 0.953876 0.846456 0.902225 0.108103 -0.023242 1.091272 0.796242 1.011212 0.961046 1.021211 0.039001 -0.032781 1.042170 1.131254 1.092307 0.999148 0.071362 0.869992 0.079822 1.110594 1.044065 1.166722 0.955017 0.117000 0.059709 1.113545 0.131377 1.023012 -0.114272 0.975103 0.983023 -0.046717 0.032378 0.224959 -0.069345 0.040516 1.089631 0.899237 0.136151 0.832552 1.215356 0.881670 0.944211 0.848668 0.152316 -0.124640 0.919395 0.853571 0.038901 0.049308 1.049839 -0.129701 1.004425 -0.052754 0.002949 -0.037696 0.133904 -0.020847 0.967100 0.902003 0.019567 -0.130260 -0.157473 -0.071944 0.135523 0.944472 -0.199005 -0.011428 -0.057531 1.218722 0.021172 0.873547 0.871952 0.950595 -0.066828 0.911583 0.960085 0.059484 1.216384 -0.015251 0.921576 1.107399 1.190526 1.009427 1.067453 1.067973 0.105850 -0.001821 0.968722 0.047666 0.095350 1.060487 0.951973 0.082517 1.139249 1.053557 0.799986 0.981175 0.927100 1.108483 -0.113217 0.056334 0.923079 -0.168060 1.160952 1.109659 0.931859 0.005663 0.016298 0.221144 -0.021547 1.134376 1.041640 -0.085720 1.009292 1.001582 0.885811 0.011233 0.110421 0.907129 0.093259 0.973361 0.842954 0.055170 1.054987 1.014198 -0.048044 0.812989 -0.144503 0.010466 1.029196 0.774851 0.843001 0.004633 1.225056 0.948512 -0.001831 -0.091454 -0.110441 0.000770 0.042991 0.840050 0.957463 0.073186 1.131453 -0.127608 1.100834 0.028867 0.991329 -0.079297 0.226099 1.081074 1.094744 -0.196334 -0.315150 -0.099639 0.860961 1.022403 0.767717 0.956186 1.242205 -0.055123 0.982544 1.115183 0.186049 0.867447 -0.036624 0.161043 -0.021433 0.029621 0.825744 0.027361 -0.010122 1.051195 0.027158 0.125747 -0.012676 1.018144 0.217569 -0.139580 1.065948 0.653885 0.017558 0.122910 1.005607 -0.024503 1.016854 0.118126 0.117812 0.209380 0.129761 0.103368 0.851695 0.818381 -0.060532 0.047740 1.092005 0.126179 -0.128900 1.046458 1.172438 0.945933 0.969409 0.186286 0.067827 0.866733 1.045200 1.053391 0.154799 -0.076177 1.034977 -0.251459 0.843987 1.036970 0.109710 1.081980 -0.054976 -0.104881 0.977835 0.917720 1.151081 1.224827 0.036178 1.178894 0.852252 1.170082 1.170461 0.979772 0.962385 0.904510 0.000036 -0.069878 0.919872 0.173255 1.075581 -0.013411 1.144951 -0.113696 0.013363 1.098609 1.014644 -0.003549 -0.244091 0.859325 1.071514 0.043866 1.123524 0.973631 0.994259 0.294619 0.940489 0.920230 0.796504 -0.004450 1.029035 -0.000831 0.920995 1.002150 0.986683 1.009523 1.089643 0.007497 1.152282 0.045887 1.088386 0.885838 -0.027924 0.051985 -0.076538 -0.224663 0.028256 -0.124194 0.724391 1.154873 0.792085 0.945537 1.154353 0.115964 0.986499 0.966811 1.012457 1.019910 -0.144866 0.815479 0.985586 0.913383 -0.150963 0.023412 -0.040408 -0.003953 0.004799 0.998876 0.002820 -0.098213 1.057293 -0.129926 0.137392 1.102538 1.079292 1.089070 1.130675 1.020925 1.154058 1.123118 0.858700 0.978386 0.138491 0.154692 1.041549 1.046975 1.030488 -0.158543 0.870238 0.064134 0.875614 -0.094478 0.900905 0.880022 1.134267 0.779059 0.063545 1.070040 -0.086015 1.008573 0.109322 -0.247240 0.015151 1.151193 -0.102164 0.087261 0.007995 0.854703 1.140979 -0.090975 0.812937 1.001838 0.168940 0.981369 -0.006072 -0.134631 1.058021 1.081911 0.004162 1.014677 0.995130 1.055979 -0.015306 0.058775 1.111668 0.059318 1.008648 0.996646 0.848989 -0.109175 1.102945 0.116474 0.906494 -0.120660 0.877452 0.886871 0.085411 0.884701 1.181621 1.062561 0.189097 0.973371 1.214908 0.001252 1.030678 0.152018 -0.037592 1.176813 0.948804 0.061120 1.019977 1.028438 -0.000808 0.087217 0.826864 0.893273 -0.207696 -0.074786 -0.108728 0.152240 -0.121688 0.980366 -0.049309 0.988905 0.044844 1.037851 0.979360 0.997856 1.209193 0.179051 1.004545 0.962175 1.139200 1.064077 0.021192 0.871727 0.976645 -0.060807 -0.016180 1.233966 0.984256 -0.044995 0.845917 0.182605 0.998382 0.007096 -0.023173 -0.024155 0.146239 1.013539 0.995536 0.048524 1.174691 1.141919 1.101145 -0.104732 0.114083 1.102748 0.983142 1.123097 -0.131915 1.072939 -0.138725 0.845004 -0.163152 -0.079593 1.018944 1.012216 0.030165 1.054447 0.994960 0.152361 -0.060656 1.093567 0.946563 0.106698 0.153793 -0.034551 1.295949 0.943407 -0.163119 0.067866 1.194305 0.979105 1.022403 1.106721 0.934941 -0.016105 1.092573 -0.050474 0.132465 0.025768 0.046448 0.920971 0.032186 0.827060 -0.132549 0.143363 0.083704 0.912578 -0.030293 0.096970 -0.039315 -0.023765 1.016646 0.854818 -0.052889 1.056921 0.089890 1.018924 0.081699 -0.114805 0.930082 -0.021013 0.109704 0.995297 -0.078029 1.125314 0.178931 0.020308 -0.221485 1.187702 0.047629 0.040061 1.015073 0.069320 0.060090 -0.115159 1.088644 -0.081572 0.068986 0.955768 0.084087 0.114901 1.013399 0.080815 -0.114939 1.007244 -0.059946 1.062447 1.043256 0.100314 1.021597 1.004933 -0.021577 -0.187720 -0.061395 -0.075323 -0.009496 0.985795 0.872323 -0.046461 0.888848 -0.053261 -0.110021 1.099191 0.979002 1.060305 1.062463 1.171427 0.691334 1.098940 0.054888 -0.017909 -0.010409 -0.111589 0.082490 0.948398 1.144871 0.127743 0.031811 1.026180 1.046146 -0.030210 -0.103802 0.989801 -0.310437 1.153393 1.012685 0.952894 1.001378 0.015652 1.054587 1.328504 -0.151531 1.037238 1.151575 0.030623 1.108802 -0.028053 0.044671 0.901073 0.934031 0.058498 0.039050 1.065155 0.024139 -0.131291 -0.082086 0.854526 1.154246 -0.049980 -0.184925 1.049877 -0.115467 -0.018300 1.001119 0.057983 1.189518 -0.114544 1.258100 1.123841 0.961039 1.070424 -0.124628 0.209509 0.034004 0.948762 1.100182 0.083224 0.948264 1.081482 0.076927 -0.000455 0.950737 0.098354 1.005742 1.019785 0.974317 0.230726 -0.067827 1.165865 0.048218 -0.058027 0.937849 0.079916 -0.012394 0.069161 0.050349 0.906284 0.832283 0.101171 0.790746 0.156878 0.740395 1.017554 0.191391 0.080956 1.000597 0.844203 0.944456 -0.111179 0.982617 1.037761 0.099785 0.851180 0.116591 0.142708 -0.015906 0.096645 0.965791 0.020953 0.925519 1.197465 -0.055737 1.095928 -0.064679 0.010255 0.936661 1.178645 0.190866 1.141107 0.130145 0.023056 0.121484 0.185090 -0.056773 0.100045 0.069574 1.039529 0.996635 1.085726 0.949189 -0.165723 -0.039203 1.116369 -0.064244 0.940174 -0.154655 1.121041 0.902088) ) ;;; 2048 prime -------------------------------------------------------------------------------- (vector 2048 102.619 (fv 0 0 0 0 1 1 1 1 0 0 1 1 0 0 1 1 1 0 1 0 1 0 0 0 1 1 1 1 1 0 1 1 1 0 1 1 0 1 1 1 1 0 1 1 1 0 1 1 1 1 1 0 1 0 1 1 1 0 0 1 0 1 1 1 1 1 0 1 1 0 1 0 0 1 0 0 0 1 1 0 1 0 1 0 0 1 0 1 0 0 0 1 1 0 1 0 0 1 1 1 1 1 1 1 0 0 0 1 0 0 1 1 1 0 1 0 0 0 1 0 1 1 0 1 0 0 1 0 1 0 0 0 0 1 1 0 1 0 1 0 1 1 0 0 1 1 1 0 0 0 1 1 1 0 0 1 1 1 1 0 0 0 0 1 1 1 1 1 0 1 1 1 1 1 0 1 0 0 0 1 1 0 0 0 0 1 1 1 1 1 0 1 1 0 0 1 1 0 0 0 1 0 0 1 0 0 0 1 0 1 0 1 1 0 1 1 0 0 1 1 1 0 0 0 1 1 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 0 0 1 0 1 0 1 0 1 1 1 0 0 1 1 1 1 1 1 0 0 1 0 1 0 1 0 1 1 0 0 1 1 1 1 0 0 1 0 1 1 0 1 0 1 1 1 0 0 1 1 1 0 1 0 0 1 0 0 0 0 0 1 1 1 1 1 0 0 1 0 1 0 1 0 0 1 0 1 1 1 1 0 1 1 1 0 1 1 0 1 1 1 0 1 1 1 1 0 1 0 1 0 0 1 0 0 1 1 1 0 1 0 0 1 1 1 1 0 0 1 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 0 0 0 1 1 1 0 0 1 0 1 0 1 0 0 1 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 0 0 1 1 1 0 0 1 1 0 1 1 0 1 0 0 1 0 0 0 1 1 1 0 0 0 0 1 1 0 1 1 0 1 1 0 0 0 0 1 1 1 1 0 1 0 0 0 0 0 0 1 0 1 0 1 0 1 0 1 0 1 1 1 1 0 1 0 1 0 1 0 1 1 1 0 0 1 1 0 1 1 0 0 1 1 1 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 1 0 1 1 1 0 1 1 1 1 0 1 1 0 0 1 0 1 1 0 0 0 0 1 1 0 0 1 1 0 1 1 0 1 0 1 0 0 0 0 1 1 0 0 1 1 0 1 0 0 0 0 0 0 0 1 1 1 1 0 0 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 0 1 1 0 0 1 1 1 1 0 1 0 0 0 1 1 0 1 1 1 1 1 1 1 0 0 1 0 1 1 0 1 1 0 1 0 0 0 0 1 1 1 0 1 1 0 1 0 1 0 0 0 1 0 0 1 0 1 1 1 0 0 0 0 1 1 0 1 0 0 0 1 0 0 1 1 1 0 1 1 1 0 0 1 0 0 1 1 0 1 0 1 0 1 0 0 0 0 0 0 0 1 1 0 0 0 1 1 0 1 1 0 1 1 0 1 0 0 1 1 1 1 0 0 0 1 1 1 1 0 0 0 1 1 1 1 1 0 1 0 0 0 0 1 0 0 1 1 1 0 0 1 1 1 1 1 1 1 0 1 0 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 0 0 1 0 1 1 0 0 0 0 1 0 0 0 0 1 1 0 1 1 0 0 0 0 0 1 0 1 1 1 1 1 0 1 0 1 1 0 0 1 0 0 1 0 1 1 0 0 1 1 1 1 0 1 0 1 1 1 1 1 1 0 0 1 0 0 0 1 1 1 1 1 0 1 1 1 0 1 0 1 0 0 0 1 0 0 1 1 0 0 1 0 0 0 0 1 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 1 1 0 1 1 1 1 0 1 1 1 1 1 1 0 0 1 1 1 0 1 0 0 0 1 1 0 1 1 1 1 0 1 0 0 1 0 0 1 1 1 0 0 1 1 0 0 0 1 1 1 1 0 1 0 0 1 1 0 0 0 1 1 1 0 1 0 1 0 1 1 0 1 0 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 1 1 1 0 1 1 1 0 0 1 0 1 1 1 0 1 1 0 0 1 1 0 1 0 0 0 1 1 1 1 1 1 1 0 1 1 1 0 0 1 0 0 1 1 0 1 1 0 1 0 0 0 0 0 1 1 0 1 1 0 1 1 1 0 1 1 0 0 1 0 1 1 0 0 0 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 0 1 0 1 1 1 0 0 1 0 1 0 1 0 1 0 0 1 0 1 1 0 0 0 0 0 1 1 1 0 1 1 0 0 1 0 1 0 0 1 1 1 1 0 0 0 1 1 1 1 0 1 1 1 0 0 1 0 1 1 0 1 1 0 1 0 0 1 1 1 1 1 0 0 0 1 1 0 0 0 1 1 0 0 1 1 0 0 1 0 0 0 1 1 0 0 0 1 1 1 0 1 0 0 1 0 1 1 0 1 1 1 0 1 0 0 0 0 0 0 1 1 1 1 1 0 0 1 0 1 1 1 0 1 0 0 1 1 1 0 0 1 1 1 1 0 1 1 1 0 0 1 0 1 1 0 1 1 1 0 1 1 0 1 0 1 0 1 0 0 0 0 1 1 1 1 0 0 0 1 0 0 1 1 0 0 0 0 1 0 0 0 1 0 1 1 0 0 1 1 1 1 0 0 1 1 1 0 0 1 0 1 1 1 1 0 1 1 0 1 1 0 0 0 0 0 1 0 0 1 0 1 1 0 1 0 1 1 0 0 0 1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 1 0 0 0 1 1 0 0 1 1 0 0 1 0 1 0 0 1 1 0 0 0 1 1 1 0 1 0 0 0 1 0 0 0 0 0 1 1 0 0 0 0 1 1 1 1 1 1 0 1 1 0 1 1 0 1 0 0 0 0 0 0 1 0 1 1 0 1 1 0 1 1 0 1 0 1 1 0 1 0 0 1 1 1 0 1 1 1 0 0 0 1 1 1 0 1 0 0 0 1 0 1 1 0 0 1 0 0 0 1 0 1 0 1 1 0 0 1 1 0 1 1 1 1 0 0 1 0 1 1 0 1 1 0 1 0 1 0 0 1 1 0 1 1 0 0 1 0 1 0 0 0 0 1 1 1 0 0 0 0 1 1 1 0 0 1 1 1 1 1 0 1 0 1 1 1 0 1 0 1 0 0 1 1 1 1 0 1 0 1 0 0 0 1 0 0 0 1 0 1 1 1 0 1 1 1 0 0 0 0 0 1 1 0 0 1 0 1 1 0 1 0 1 0 1 1 0 0 0 0 1 0 0 0 1 0 1 1 0 1 1 0 0 0 1 1 1 1 0 0 0 0 0 0 0 1 0 0 0 1 1 1 1 1 0 0 0 1 1 1 0 1 1 0 0 1 0 1 0 1 0 0 0 1 0 0 0 1 0 0 1 0 0 1 0 1 1 0 1 0 1 1 0 0 0 0 0 0 0 1 0 1 0 0 1 1 0 1 0 0 0 0 1 0 0 1 1 0 0 0 0 0 0 0 1 0 0 0 1 0 1 0 1 1 0 0 0 1 1 1 0 1 1 1 1 0 1 1 0 1 0 1 1 1 0 0 1 1 1 1 1 0 0 1 0 1 0 1 1 0 1 1 1 1 1 1 1 0 1 0 1 1 0 1 0 0 1 0 1 0 0 0 0 1 1 1 1 0 0 1 1 0 1 0 0 0 0 0 1 1 0 1 1 0 1 1 1 1 1 1 1 0 1 1 0 1 0 0 0 0 0 1 1 0 0 0 0 0 1 0 1 1 0 0 0 1 0 0 0 1 1 0 1 1 1 1 1 1 1 1 0 1 0 0 0 1 1 0 0 1 1 1 0 0 1 0 1 1 1 0 1 0 0 1 0 1 0 0 0 1 0 0 1 0 1 0 0 1 1 1 0 0 0 1 0 1 1 0 1 0 0 1 0 1 0 1 1 0 1 1 0 0 0 1 0 0 1 0 0 1 1 1 0 1 0 0 1 1 1 1 1 1 1 1 0 1 1 1 0 0 1 1 0 0 1 0 1 1 1 0 0 1 0 1 1 1 0 1 0 0 0 1 0 0 0 0 1 1 1 0 1 0 0 0 0 1 0 1 1 1 0 1 0 1 1 1 0 1 0 0 0 1 0 1 0 1 1 0 0 0 0 1 1 1 1 0 0 1 0 1 1 1 1 0 1 0 1 1 1 1 0 1 1 1 0 1 0 0 0 0 0 0 1 1 1 0 1 1 0 1 1 0 1 0 1 1 0 1 1 1 1 1 0 0 1 0 1 1 1 1 1 1 0 0 0 0 1 1 1 1 0 0 1 1 1 1 1 1 0 1 0 0 1 1 0 1 0 0 0 0 1 1 1) 95.904258 (fv 0.000000 -0.184827 -0.106502 -0.094974 0.803466 0.945074 0.963289 0.946874 -0.103266 0.049155 1.087214 0.886218 0.016107 0.059052 1.086003 0.896052 0.832875 0.168267 0.929954 0.104821 0.801629 0.032075 0.032796 0.227531 0.906532 1.124909 1.032850 0.878053 0.813900 -0.267885 0.885447 1.090714 0.853533 -0.000373 1.207049 0.922018 0.048308 0.893672 0.856221 0.975035 0.868154 0.098949 0.791588 1.196055 0.919249 -0.152557 0.991948 1.006717 1.133320 1.186246 0.920884 -0.060763 0.895777 0.020781 0.811521 0.941459 0.931533 0.044866 -0.116604 0.896466 0.029517 1.096540 0.918555 0.948344 0.929326 1.133930 0.012583 0.960301 1.199033 0.051836 1.012281 -0.182278 -0.104579 0.982487 0.083391 -0.235240 0.238134 0.851365 1.147123 -0.183897 0.931617 0.014719 0.969454 0.114930 -0.007528 0.927332 0.038357 0.920680 -0.081674 -0.182395 -0.011442 1.061361 0.921566 -0.084353 1.041705 0.161045 -0.067878 1.074036 0.941106 0.966219 0.919599 1.168159 1.032081 0.945189 0.044320 0.039817 -0.089720 1.130429 -0.069569 -0.278003 0.838588 0.754892 0.905296 0.076030 0.931578 0.143938 -0.063198 0.009752 0.994216 -0.018389 1.061023 0.998466 -0.064949 0.889855 -0.094736 -0.151667 1.224271 -0.191231 0.981083 0.017183 -0.228680 -0.064528 -0.051088 0.940309 1.101261 -0.034752 0.950794 -0.088223 1.190759 0.000979 1.058816 1.106846 0.070946 0.194156 1.093892 0.886993 1.017953 -0.051739 -0.284107 0.024602 0.969253 1.247816 0.935610 -0.089803 0.006657 0.841177 1.059923 1.023429 0.866137 0.046390 -0.124782 -0.252595 0.166144 1.083896 1.139053 0.949050 1.094868 1.174455 -0.189695 1.188365 1.031424 1.009889 1.067591 0.935164 0.237409 0.909064 0.009677 -0.177665 0.046406 1.016694 1.057379 -0.055836 0.052713 -0.065039 0.120813 0.836055 1.178838 0.902715 0.920359 0.806116 -0.117471 1.158887 0.994531 -0.009494 -0.163337 1.040739 1.131213 0.025531 -0.009616 0.139395 0.950856 -0.014744 0.115132 1.125894 -0.190579 0.101124 -0.125308 0.963704 0.026526 1.118700 0.022614 0.807945 0.913877 0.030742 0.927436 0.988232 -0.140750 0.124385 0.986885 0.991816 1.146772 -0.062919 0.074766 -0.034226 1.128490 0.957963 1.096308 1.046278 -0.048364 0.116505 1.136521 1.090002 -0.014238 -0.112155 1.033034 1.160610 -0.094599 0.068313 1.266010 1.098976 0.044651 0.131033 -0.116651 -0.075950 1.046348 0.030055 0.793219 -0.117150 1.124225 -0.160989 1.100541 1.045178 0.962828 -0.073358 -0.019227 1.173791 1.059709 0.937667 0.966884 0.928018 1.041334 -0.201315 0.174562 1.021851 -0.049449 0.907458 -0.107815 1.126703 0.073928 0.982065 0.825831 -0.033241 0.067472 0.917284 0.902681 1.015596 0.904075 -0.075353 -0.108265 0.963265 -0.090615 0.920339 0.977780 0.090733 0.904078 0.000883 1.347356 1.014221 0.985375 -0.100963 0.008783 0.942615 1.002685 1.149002 0.158462 0.917602 -0.099583 -0.025442 1.103430 0.071006 -0.151207 0.055689 -0.038941 0.098832 0.911418 1.062737 0.996744 0.760254 0.996130 0.014262 0.032851 0.956371 0.019061 0.996091 0.200667 1.164966 0.045741 0.060264 1.166834 -0.025387 0.966912 1.043716 0.969667 1.084931 -0.065039 0.974364 0.980017 0.844958 0.179207 0.723395 1.083973 -0.074447 0.912360 1.089065 1.005958 -0.119354 1.049441 0.937401 0.912303 0.937357 0.078173 0.927334 -0.094425 0.851189 0.132753 0.133028 1.043045 0.054936 -0.083812 0.903122 1.042637 1.178266 -0.107401 1.047050 -0.128737 0.160133 0.840861 0.896100 1.126802 0.903407 0.262267 0.053879 0.947798 -0.144016 -0.003985 0.146029 0.074915 0.771488 1.227288 0.890268 0.933106 1.075829 0.057968 0.066132 0.249704 -0.017827 0.090465 -0.047385 -0.060718 0.123360 0.988529 0.904277 -0.005465 -0.084169 -0.247831 0.999998 0.910292 1.144645 0.071091 0.088886 1.023713 -0.025414 0.984571 -0.240585 0.967555 -0.138539 0.196983 1.010405 -0.049670 -0.081707 0.064139 0.997860 0.836573 1.161272 -0.021657 0.041743 -0.127308 0.045553 0.018541 -0.044739 0.088082 0.142342 0.114457 1.055260 1.064567 -0.119380 -0.070251 -0.004341 0.963091 -0.120638 0.258819 1.053558 0.878500 1.069022 -0.123646 -0.014321 1.121295 1.085748 -0.044674 0.870738 0.685253 -0.051358 1.001113 -0.231350 0.033853 0.961438 0.037712 -0.113045 0.108555 1.037350 1.011749 1.028331 -0.080798 0.196328 0.059651 0.046311 0.977929 0.955683 -0.011917 0.990010 0.826271 0.043303 1.009806 1.189345 0.021063 0.072917 0.057585 0.061242 0.879010 0.849055 1.018528 0.955494 -0.055041 1.189587 -0.028346 -0.082984 0.099423 -0.024146 0.146930 -0.067314 0.849801 0.213148 0.924340 0.080454 0.905046 -0.129837 0.863551 -0.015056 1.161555 -0.111647 0.827215 0.819815 1.100249 1.048851 0.084224 1.096872 0.064524 1.027164 0.125925 0.828778 -0.032148 1.059894 1.017072 0.834004 -0.032573 -0.063582 1.159025 1.022326 0.063607 1.022556 1.099517 0.097842 0.150138 1.115534 0.951150 0.988949 0.155650 -0.134289 -0.115258 1.037176 1.021182 0.975772 1.072700 1.222345 0.924272 0.973662 0.930252 0.059705 0.077967 -0.109443 -0.103486 0.972696 -0.144205 0.802195 0.975677 0.802607 -0.042079 1.071307 1.022073 0.907916 1.035902 -0.048853 0.907965 0.883285 0.084385 -0.108649 0.944568 0.005988 0.933534 1.065312 -0.070265 -0.076879 -0.017044 -0.098932 1.208925 0.930986 -0.119229 -0.037509 1.090406 0.992176 -0.000651 0.937690 0.916741 -0.066544 1.095679 -0.058814 1.036581 -0.051849 -0.017058 -0.030283 0.051491 0.954183 0.950362 -0.021757 -0.062612 1.017252 0.855360 0.008584 0.998471 0.053177 -0.102277 -0.071410 -0.113602 0.020219 0.047660 0.112990 0.815120 1.152303 1.067537 1.052888 0.004076 0.157730 0.930208 0.885789 0.948613 1.018989 0.998994 -0.098675 0.134960 0.084711 0.092822 0.103312 -0.196457 1.024530 1.108457 0.891294 1.054699 1.016928 -0.022703 0.811591 1.004965 -0.017036 0.232325 0.973190 1.052258 1.071581 1.167101 -0.078778 1.126544 0.054092 0.108866 0.166665 1.087490 0.998143 -0.013409 0.871172 0.885040 1.019108 1.127064 1.196444 0.957927 0.852239 -0.008268 -0.145143 1.063054 -0.026011 1.007974 0.983277 -0.031336 1.126868 0.969557 0.015995 0.940510 0.206836 -0.166196 0.069999 0.106477 0.969534 0.962793 1.057184 0.039570 1.013939 0.966957 -0.186086 1.043328 0.103727 0.826020 0.082145 0.142187 0.193131 0.806568 -0.194497 0.073921 0.929470 0.014750 1.003891 1.130669 0.912871 -0.166896 -0.010434 0.224001 0.019969 0.882091 1.015999 0.050540 0.927299 -0.028913 0.088865 -0.038210 0.838785 0.179969 -0.063760 0.909551 0.970913 0.864195 -0.147216 1.017549 0.931612 1.076838 0.174334 -0.004854 1.146351 -0.071188 0.005023 0.983870 0.987921 -0.073293 1.144937 -0.008273 1.069178 0.160218 0.940671 -0.099513 -0.160986 -0.053460 -0.000349 -0.066930 0.258818 0.037651 0.899944 1.011860 -0.024019 0.049159 -0.114396 0.997122 0.988277 -0.086170 1.100402 0.827506 -0.071549 1.014472 0.830365 -0.029296 1.033932 -0.095907 -0.073030 0.967696 1.060165 0.920338 1.199129 -0.072200 0.053416 -0.126898 1.108390 0.903008 1.109424 0.964135 -0.083890 0.099047 -0.111937 1.079528 1.230021 1.124700 0.946124 1.081677 -0.089364 1.123287 0.082817 -0.048549 0.013111 -0.005217 1.016286 0.025359 -0.151572 1.137235 1.013948 1.006359 -0.020039 -0.117293 1.111762 0.892597 1.058754 0.795600 0.996014 0.931963 1.115786 -0.029889 0.877043 -0.234877 1.149674 1.027911 1.261517 0.048880 0.113954 -0.024127 0.075365 -0.048636 0.036252 0.831941 0.943628 0.982317 0.918776 1.086510 0.931126 -0.077364 0.039915 1.020953 -0.068839 0.962253 0.910823 0.025853 0.065365 0.021206 -0.021296 0.872652 0.026536 -0.052762 0.003250 0.029539 0.991921 1.021217 -0.042456 0.777756 0.980840 0.078981 -0.130613 0.133311 -0.065841 -0.085861 1.178451 0.115564 1.082062 1.015392 0.928586 0.967073 1.156891 -0.010223 0.936469 -0.154645 0.995277 1.073333 -0.010159 -0.073318 1.117785 0.123446 0.035440 0.914424 0.055982 1.255170 0.975126 0.021080 -0.037628 1.048938 0.871136 1.107293 0.955878 -0.056277 1.017033 0.090456 0.993267 0.757034 1.002409 0.941223 0.920711 1.181339 0.032023 -0.085516 0.974206 -0.026907 0.142086 -0.002800 0.952901 1.119119 1.039547 0.762175 1.056838 -0.114595 0.884738 0.718220 0.960728 -0.156479 1.189199 -0.165202 0.904637 -0.041429 -0.050488 -0.179745 1.054673 -0.082418 0.030881 1.160170 0.821960 -0.086297 0.010350 0.932553 0.035420 -0.009593 0.011040 0.051718 0.904123 0.028769 0.100605 1.033920 -0.169584 1.086360 1.131494 0.107596 -0.114123 0.021393 0.010364 -0.152848 0.035197 0.012279 -0.133590 -0.062321 1.204840 0.937029 -0.068386 1.145671 0.973614 1.135843 0.883055 0.070061 0.997608 1.003482 0.989245 1.204030 1.197676 0.838535 0.029369 -0.215349 1.060468 0.880276 0.931456 0.125650 1.132780 -0.117697 0.200533 0.075686 1.191015 1.016195 0.037000 1.110074 0.982317 0.982573 0.824837 -0.229925 1.006482 -0.062451 -0.057872 0.979641 -0.230341 -0.020939 1.006077 0.857917 1.098933 -0.267219 0.043265 0.935436 0.964162 -0.007168 0.164970 0.165342 1.068220 0.945315 0.948634 1.023862 -0.029831 0.992343 0.020292 0.067126 0.932456 0.808919 0.096733 0.000609 0.083113 1.019237 0.858419 1.013183 0.098990 0.930352 -0.062223 1.082324 -0.042610 1.104376 0.999943 -0.136202 0.964477 -0.092847 1.096219 1.036690 1.110447 0.987439 0.893158 0.111588 -0.094486 0.748732 0.981962 1.023640 1.021660 0.931300 1.325728 0.988586 0.832724 0.042650 -0.080219 -0.124412 0.083378 -0.047165 0.013229 0.179035 1.036229 0.106634 -0.154080 0.015828 -0.138512 0.228898 0.970943 1.152854 0.994299 1.087348 1.079495 -0.014073 0.985630 1.046303 0.921605 -0.148486 -0.082307 1.049524 0.140156 1.012720 0.976567 0.874688 -0.045198 1.031276 0.883380 0.011846 -0.003498 1.009216 0.885002 0.172619 0.843282 0.029227 -0.097679 -0.125796 0.933874 0.978897 0.725114 0.844720 1.075252 0.947844 0.926610 0.182857 0.841432 1.040159 0.998281 0.169201 0.136041 1.216461 0.161331 -0.074244 1.061895 0.862101 0.118827 1.150273 1.131402 0.028905 0.802992 -0.116645 0.004795 -0.035171 -0.225349 -0.011793 1.004637 1.052814 0.132105 0.965384 1.075721 0.233900 0.952135 0.901143 1.131006 0.032321 1.011176 0.873840 0.182329 -0.079077 0.896822 0.005166 0.903099 1.092780 -0.025076 -0.019178 0.015239 0.984311 1.216486 0.992874 0.054129 0.144836 0.099554 0.103521 0.100432 -0.026631 0.042079 0.163741 1.041917 0.792159 0.979852 0.977128 0.103524 1.113377 -0.157199 1.027202 0.929073 1.074076 -0.112317 0.199279 0.760239 0.001430 1.277148 0.009244 0.986963 0.109581 1.086070 -0.134094 0.327295 0.686709 -0.296672 0.932890 0.968488 0.216488 0.165531 0.285075 -0.094601 -0.165028 0.950486 0.963591 0.864035 -0.065266 1.013992 0.911092 -0.094152 -0.152792 1.070739 -0.039448 1.166353 -0.004048 0.032871 0.996625 1.100064 1.255396 0.839630 -0.081969 0.162263 0.140738 1.003998 0.779814 0.961648 1.146742 0.167212 0.925641 1.185256 0.824157 -0.033666 -0.007601 0.908697 0.230017 0.822888 0.740994 0.033372 1.160544 1.098836 -0.044005 1.021078 0.126042 0.049334 0.898357 1.032574 0.865757 0.947486 0.886121 0.055309 0.044278 -0.037421 1.134951 0.864539 -0.011595 -0.007199 0.067683 1.090102 1.092557 0.046997 0.027613 0.949146 0.875265 0.136983 -0.135656 0.985803 -0.132003 0.135341 0.013222 1.091309 1.098115 0.015599 0.119349 0.014805 1.069340 1.102334 1.032680 -0.031084 0.906554 -0.088863 0.069579 1.064396 0.128172 1.022790 1.107156 -0.057182 0.995012 1.054566 1.042520 -0.160709 1.125070 -0.094154 0.046403 -0.069345 0.119373 -0.184893 0.070830 1.044722 1.098693 1.111409 1.135049 0.985119 0.066473 0.058424 1.004842 -0.094015 1.117752 0.799547 1.268968 0.039520 0.996895 -0.102408 -0.030667 0.930842 1.078283 1.102597 0.055578 0.110127 0.923904 1.005813 0.918634 1.079133 -0.099263 0.905943 1.047321 0.848243 -0.009403 -0.068258 1.012623 -0.037975 1.142196 0.851851 0.109046 1.141382 0.890904 0.996832 -0.088058 1.288646 1.097971 -0.100491 0.918525 0.015332 1.145115 0.117738 1.014796 -0.205627 -0.177297 -0.006318 0.055035 1.183699 0.900390 1.055439 1.182836 0.107470 0.210820 -0.154634 1.100666 0.004257 0.125613 0.849489 1.120995 -0.046236 -0.066772 0.011079 -0.102932 0.932197 0.023264 0.246085 0.163405 0.869069 0.102531 1.077511 0.954854 0.038602 0.079792 0.927047 0.983181 1.030696 0.962590 -0.055603 -0.107934 1.126555 0.946728 1.063664 0.137033 -0.128875 0.885196 0.091522 0.893839 1.007955 0.978475 0.978266 0.067848 1.038168 1.090875 -0.061309 1.116028 1.016019 0.011872 -0.108054 0.108874 0.083760 0.113696 1.116111 0.014309 0.005128 1.099189 -0.004973 1.325065 1.221479 0.028469 1.235019 -0.212490 0.962518 1.027151 -0.044149 0.142639 0.155400 0.936540 -0.039180 0.937115 -0.085578 1.019973 1.270603 0.140594 0.061038 1.087655 0.063712 1.177018 -0.029958 0.758319 0.051019 -0.094233 0.962416 -0.006348 -0.003660 0.019678 1.112579 1.058837 -0.108754 0.005081 0.979604 0.909652 -0.162160 0.189741 1.115396 -0.046934 0.809487 0.174222 -0.004756 1.140939 0.812895 0.050537 0.171915 -0.128895 0.969610 0.953147 1.047572 0.122563 0.889198 -0.104048 0.001916 -0.008785 1.172703 -0.213570 -0.114233 -0.152007 -0.161789 -0.132968 1.055565 0.784424 0.202349 -0.012066 0.004158 -0.039121 1.114936 0.962613 0.954226 1.105200 0.985756 1.026320 -0.117780 0.866616 1.000189 -0.163224 0.999105 1.165142 0.001717 1.023313 -0.052468 -0.233246 -0.078417 -0.014831 0.008989 0.105092 1.100102 -0.114187 0.962275 0.827359 -0.135499 1.155899 0.983914 -0.197096 0.920622 0.925756 0.074101 1.105182 0.068112 0.889324 0.995794 -0.181975 1.079197 -0.174077 -0.086147 1.108775 0.836038 0.920177 0.069115 1.056833 1.065288 1.011220 0.037095 -0.051383 0.059023 0.966919 0.975420 0.992209 -0.050411 1.034776 0.060947 0.024827 0.189251 1.128565 -0.026102 0.882647 1.113292 0.059688 -0.055524 1.097931 -0.076831 0.148308 0.009684 0.993343 0.181407 0.980680 -0.253676 1.203786 0.837538 -0.111906 -0.046920 0.992998 1.138650 0.102810 0.732933 0.974495 1.134363 0.841220 -0.244832 0.191984 1.089926 -0.014286 1.033093 0.795315 0.027888 1.086315 0.921910 0.023081 1.023830 0.070684 1.183612 -0.197469 -0.072227 1.175515 1.132615 0.147372 1.165071 0.693358 0.086944 0.167356 1.154251 0.067038 1.011388 0.195281 0.162053 0.058855 0.118483 1.091391 1.199083 0.861074 0.152693 -0.184650 -0.275426 0.016699 1.041744 1.082925 0.896020 -0.212005 -0.028325 0.837564 1.192865 0.964038 1.140280 0.832699 0.060523 1.017736 0.007067 1.222558 0.776881 1.025602 0.136510 1.065558 0.031534 1.120667 -0.017440 -0.095844 0.986588 0.811881 1.008160 1.083596 -0.057608 1.030774 -0.185755 1.016553 -0.060277 0.044570 0.071469 1.026382 -0.218238 -0.134819 0.125155 1.052665 0.219534 1.053074 0.975626 0.942097 0.042773 0.914988 0.904458 1.068383 0.122945 -0.160737 0.195111 -0.112309 0.079404 0.873713 0.743694 -0.042029 0.017013 1.026689 -0.033216 0.846494 1.151063 -0.096712 0.933521 -0.150138 0.998351 0.097766 1.014397 1.003826 0.249110 -0.089820 -0.095115 -0.041617 1.005328 -0.026956 0.282608 -0.227117 0.900497 0.151081 1.074944 0.999410 0.070956 0.989252 1.046830 0.036838 0.060586 0.119680 1.033878 1.147593 1.072223 1.038019 -0.063806 -0.066418 -0.094579 0.121532 0.058665 0.065637 0.015630 1.033625 -0.167401 -0.044227 0.109799 1.069494 0.978455 0.951966 0.848373 1.183717 0.052564 -0.139052 0.109210 1.056692 1.084067 0.913136 0.026099 0.888367 1.004145 -0.006357 -0.186626 1.147417 0.008987 1.033956 0.198511 1.087879 0.153898 -0.007073 -0.053729 0.960733 -0.079153 -0.112602 0.118601 1.127696 0.124208 -0.118455 1.113389 -0.141400 0.095581 0.831887 0.079625 1.065606 1.064953 -0.043117 0.883460 -0.117838 0.984417 1.073930 -0.020071 -0.020565 -0.110661 -0.029427 0.000735 0.129840 -0.059144 0.853604 0.029159 1.153760 -0.035371 0.120975 0.829886 0.902305 0.004019 1.024841 -0.008315 -0.040841 0.081011 0.034157 0.925135 0.026143 -0.146226 0.818801 0.997553 -0.057337 0.039344 0.045043 -0.058730 0.061450 0.034397 0.032312 1.021479 0.069734 0.032385 -0.034352 1.143739 0.128130 0.837756 0.143447 1.191780 1.005715 -0.145746 0.060156 -0.089751 0.993522 1.117964 1.113924 -0.051214 0.989301 1.131346 0.978070 1.120586 -0.104089 0.755209 0.911168 0.043338 0.799533 -0.065789 1.035956 1.103884 1.108033 -0.011160 0.018199 1.076458 1.033226 1.049461 0.927281 0.875446 -0.132488 -0.016539 1.040494 -0.085837 0.845351 0.082137 0.957295 0.975488 -0.233161 1.046308 0.968283 1.119329 0.799388 0.835437 1.198178 1.006967 -0.080996 1.022071 0.222670 1.054955 1.028112 0.145964 0.775125 0.053077 -0.139928 0.982870 0.012204 1.181785 -0.055209 0.064440 0.028436 -0.055658 0.988257 0.885626 0.925751 1.041503 -0.102556 0.199169 0.817618 1.118232 -0.154162 1.103379 0.161217 0.043204 0.038827 0.297793 0.101115 1.084585 0.911258 -0.017387 1.093864 1.174369 -0.052884 1.010587 1.084918 1.042023 0.988052 1.008470 1.079842 0.911711 -0.105412 1.049916 0.966051 -0.030853 0.634323 0.027996 0.065373 0.165603 -0.198745 0.121133 0.904870 0.798116 0.109313 -0.023197 -0.012270 -0.099679 -0.007982 0.957938 0.064886 1.066324 0.891833 0.030809 0.008848 -0.058683 1.151904 -0.064909 0.005548 0.092447 0.994226 0.980543 0.036553 0.977629 0.908112 1.053035 1.015332 1.120582 1.029707 0.935519 0.767415 -0.107332 1.106993 0.051063 -0.090849 -0.152447 1.074408 0.930237 -0.134191 -0.041339 1.154220 0.912402 0.915882 -0.155688 0.004278 1.005960 -0.029173 0.929692 0.891253 0.904414 -0.022210 0.912185 0.032760 -0.175809 1.064184 0.004444 1.023131 0.014814 0.025559 0.065555 0.781532 -0.029379 -0.197955 0.897852 -0.013217 1.093294 0.004968 -0.102189 1.031592 0.748643 0.996666 0.053363 -0.174095 0.022123 1.073767 0.026629 0.817199 0.923850 0.016734 1.000997 0.181206 0.011231 0.956073 0.190711 0.864217 -0.176983 1.016978 1.028389 0.023092 0.841323 1.197465 -0.032185 -0.023935 -0.154948 0.938794 0.022079 0.018001 0.863273 0.095137 -0.103529 1.048691 1.044424 1.076913 -0.091685 1.016448 0.235867 -0.191122 1.021688 0.903834 1.103008 1.062811 0.974671 0.808982 0.919788 0.797299 0.003866 0.924240 1.138022 1.138392 -0.086041 -0.072381 1.089510 0.997304 -0.196238 -0.081117 0.998652 -0.136927 1.094476 1.025478 1.128812 -0.043799 -0.160622 1.202644 -0.097115 1.028359 1.128248 1.149200 0.046912 1.215106 0.095300 0.230991 -0.177631 1.060265 0.025009 -0.087069 -0.045585 0.107297 0.905981 1.067101 1.105134 0.200901 0.832244 -0.158358 0.063741 -0.002433 0.178939 1.150184 -0.013758 0.739082 0.970621 1.116445 -0.077580 0.874011 -0.000811 0.757786 1.027494 0.948749 0.128206 1.197540 -0.121973 -0.035650 0.227456 1.012591 0.093402 0.788900 0.046330 1.127347 0.937960 0.147998 0.295156 0.047168 -0.449697 1.185666 1.027567 1.056837 0.896828 0.093411 0.188188 1.051113 0.196550 0.986178 0.963111 1.064836 0.986799 0.068409 0.940694 0.044600 0.930849 0.776664 1.119660 0.877476 -0.187121 0.889222 0.896426 1.114193 0.109176 0.974296 0.017034 0.058848 0.003626 -0.056434 -0.053055 -0.327863 1.110462 1.191687 0.833810 -0.093180 1.062518 0.877602 0.130458 1.046517 0.945395 -0.042202 0.884421 0.076614 0.998365 0.963405 -0.042360 1.233324 1.032498 0.850640 0.878991 1.172081 -0.131938 0.138522 1.031223 -0.060356 1.045766 1.146384 1.014251 1.035122 1.033944 0.910994 0.140291 0.017496 0.074785 0.017803 1.051564 0.940908 1.102397 0.914000 -0.151381 -0.037398 0.841172 0.980431 0.926522 1.010521 0.906633 0.898542 -0.046207 1.056040 -0.119697 -0.388635 1.042092 1.062407 -0.114191 0.973897 0.038767 0.170771 0.104476 0.108748 0.973779 0.829369 0.903094) ) ) ) ;;; ---------------------------------------- even-numbered harmonics (and fundamental) ---------------------------------------- (define neven-min-peak-phases (vector (vector 1 1.0 (fv 0) ) (vector 2 1.7601724863052 (fv 0 0) ) ;;; 3 even -------------------------------------------------------------------------------- (vector 3 2.2325525283813 (fv 0 0 0) 2.0235652605711 (fv 0 33/64 63/128) 2.0214650630951 (fv 0.0 0.52414411306381 0.48787820339203) 2.021465 (fv 0.000000 0.475854 0.512123) 2.021465 (fv 0.000000 0.524145 0.487877) 2.021465 (fv 0.000000 1.475854 1.512123) ; etc ) ;;; 4 even -------------------------------------------------------------------------------- (vector 4 2.8359191417694 (fv 0 0 0 0) 2.450505601523 (fv 0 3/16 21/32 15/32) ;2.434727537119 (fv 0 37 52 46) / 31 2.4311048984528 (fv 0.000 0.191 0.672 0.479) 2.4311048984528 (fv 0.000 0.809 0.328 0.521) ;; (optit :even 4 1/4 (expt 2 -100) 2.8359191417694 (fv 0 0 0 0)) 2.4308773660653 (fv 0.0 -1.907463741733863571425899863243103027344E-1 -6.709215487223971763341978657990694046021E-1 -4.783757035623090736464746441924944519997E-1) ;; (optit :even 4 1/4 (expt 2 -100) 2.450505601523 (fv 0 3/16 21/32 15/32)) 2.430877366065 (fv 0.0 1.907463741737958073940717440564185380936E-1 6.709215487230322239042834553401917219162E-1 4.783757035631506226991405128501355648041E-1) 2.4305741786957 (fv 0.0 0.19146482345276 0.67236139177392 0.47990912646831) ) ;;; 5 even -------------------------------------------------------------------------------- (vector 5 2.816308259964 (fv 0 1 0 0 0) 2.6048328876495 (fv 0.0 1.7889379262924 0.49464252591133 0.018512051552534 0.013387856073678) 2.604848 (fv 0.000000 0.211049 1.505353 1.981536 -0.013355) ) ;;; 6 even -------------------------------------------------------------------------------- (vector 6 2.9795869831363 (fv 0 0 1 0 0 0) 2.8369779013614 (fv 0.0 0.17925976781335 1.4035822186281 0.79344665247706 0.91203230191116 1.0958477007498) 2.836991 (fv 0.000000 0.178390 1.402472 0.792230 0.912414 1.093877) 2.836980 (fv 0.000000 1.821818 0.597785 1.208038 1.087532 0.906567) 2.836978 (fv 0.000000 1.178373 0.402442 1.792189 1.912334 0.093818) 2.836972 (fv 0.000000 1.178483 0.402570 -0.207680 -0.087726 0.094035) 2.836966 (fv 0.000000 0.821717 1.597697 0.207985 0.087685 -0.093549) 2.836953 (fv 0.000000 0.821609 1.597559 0.207843 0.087745 -0.093780) ) ;;; 7 even -------------------------------------------------------------------------------- (vector 7 3.3825581073761 (fv 0 0 0 0 0 1 0) 3.0470769405365 (fv 0.0 0.503662109375 0.87483215332031 1.0009307861328 1.2656555175781 0.71012878417969 0.30850219726562) 3.0469672679901 (fv 0.0 0.50373814372209 0.87540721456314 1.0012873875657 1.2663739438299 0.71078327011007 0.30959991380794) 3.046965 (fv 0.000000 0.503616 0.874674 1.000689 1.265332 0.709676 0.308046) ) ;;; 8 even -------------------------------------------------------------------------------- (vector 8 3.611234664917 (fv 0 0 0 0 0 1 0 0) 3.197691 (fv 0.000000 1.463442 0.984712 1.413077 0.862890 0.889575 1.684691 1.613214) 3.197689 (fv 0.000000 0.536983 1.016250 0.588185 1.138902 1.112562 0.318083 0.389844) 3.197673 (fv 0.000000 0.463394 -0.015494 0.412641 1.862274 -0.111008 0.683799 0.612199) 3.197643 (fv 0.000000 1.536907 0.016088 1.587997 0.138641 0.112256 1.317694 1.389405) 3.197539 (fv 0.000000 1.536753 0.015811 1.587753 0.138248 0.111716 1.317048 1.388715) ) ;;; 9 even -------------------------------------------------------------------------------- (vector 9 4.0601739883423 (fv 0 0 0 0 0 0 1 1 0) 3.454235 (fv 0.000000 1.380130 1.542684 1.103203 1.094600 0.755189 1.642794 1.504783 0.092364) 3.454343 (fv 0.000000 0.380149 0.542653 0.103243 0.094157 1.755278 0.642603 0.504207 1.092117) 3.454167 (fv 0.000000 1.619814 1.457133 1.896576 1.905245 0.244460 1.356830 1.494866 0.907164) 3.454104 (fv 0.000000 1.619789 1.457225 1.896592 1.905347 0.244468 1.356940 1.495046 0.907280) 3.453978 (fv 0.000000 1.619848 1.457320 1.896841 1.905503 0.244896 1.357384 1.495389 0.907798) ) ;;; 10 even -------------------------------------------------------------------------------- (vector 10 4.0054845809937 (fv 0 1 1 0 0 0 0 0 1 0) 3.559069 (fv 0.000000 0.728493 1.283356 1.458356 0.068046 1.297046 -0.008724 1.763762 1.458102 1.082546) 3.559031 (fv 0.000000 1.271816 0.716134 0.541742 -0.068143 0.702758 0.008941 0.237259 0.543599 0.918279) 3.558934 (fv 0.000000 0.270311 1.713387 1.540231 0.930533 1.700561 1.006089 1.239216 1.544459 1.919820) 3.558711 (fv 0.000000 0.271020 1.715408 1.541006 0.931409 1.702058 1.007613 1.237445 1.543048 1.918285) ) ;;; 11 even -------------------------------------------------------------------------------- (vector 11 4.2368197441101 (fv 0 0 1 1 0 1 1 1 0 0 0) 3.656997 (fv 0.000000 0.364553 0.246524 0.545081 1.820586 -0.010486 0.065265 0.895857 0.689390 0.398119 1.238723) 3.656853 (fv 0.000000 0.636042 0.753996 0.455733 1.180490 1.011649 0.936897 0.106845 0.312362 0.605377 1.764604) 3.656814 (fv 0.000000 1.363823 1.245209 1.543687 0.818338 0.986715 1.061848 1.892251 1.683956 1.393470 0.233084) 3.656676 (fv 0.000000 1.635670 1.752596 1.453762 0.177717 0.008296 -0.065661 1.103599 1.306278 1.601279 0.759437) 3.656141 (fv 0.000000 1.635206 1.752773 1.453484 0.177816 0.008586 -0.066147 1.102294 1.308244 1.599463 0.758738) ) ;;; 12 even -------------------------------------------------------------------------------- (vector 12 4.4100483425078 (fv 0 0 0 1 1 0 1 0 0 0 0 0) 3.787770 (fv 0.000000 1.448638 0.653979 0.460567 1.750296 1.187409 1.823828 0.621465 0.835166 0.896814 0.649295 0.954712) 3.787607 (fv 0.000000 1.552098 0.349619 0.543969 1.255255 1.818801 1.184427 0.387699 0.175349 0.115468 0.364328 0.059990) 3.787594 (fv 0.000000 0.551763 1.347551 1.541126 0.252553 0.815620 0.180247 1.383525 1.170726 1.109400 1.357991 1.052935) 3.786929 (fv 0.000000 0.551301 1.345490 1.538545 0.249324 0.811835 0.175379 1.377915 1.164645 1.102028 1.349918 1.044104) ) ;;; 13 even -------------------------------------------------------------------------------- (vector 13 4.4076361656189 (fv 0 0 1 0 1 1 0 0 1 1 1 1 1) 3.973518 (fv 0.000000 1.227848 0.569459 0.032525 1.602849 0.995992 1.561449 0.851502 1.005100 0.700156 1.033637 1.225072 1.740227) 3.973285 (fv 0.000000 0.221343 1.559694 1.013474 0.580564 -0.035047 0.522724 -0.190833 -0.044249 1.645456 -0.025041 0.160741 0.667019) 3.973148 (fv 0.000000 0.225623 1.564256 1.022022 0.590378 -0.019884 0.539658 -0.171656 -0.022033 1.670109 0.001495 0.190555 0.699291) 3.973041 (fv 0.000000 0.226214 1.565751 1.024299 0.592784 -0.015292 0.545848 -0.164098 -0.014254 1.677783 0.010954 0.201582 0.710821) 3.972554 (fv 0.000000 0.227025 1.566229 1.025033 0.594027 -0.014872 0.545046 -0.165560 -0.014836 1.678196 0.010096 0.200561 0.709954) ) ;;; 14 even -------------------------------------------------------------------------------- (vector 14 4.5770673751831 (fv 0 1 1 0 0 1 1 1 1 1 1 0 1 0) 4.097747 (fv 0.000000 0.927497 0.986240 1.222647 1.417439 1.485272 1.245695 0.840056 0.775783 1.393795 0.027626 0.815063 1.945062 1.449403) 4.096703 (fv 0.000000 0.927014 0.985352 1.221418 1.415761 1.483290 1.243140 0.836933 0.772657 1.390170 0.023348 0.810693 1.940171 1.444293) ) ;;; 15 even -------------------------------------------------------------------------------- (vector 15 4.7838921546936 (fv 0 0 0 0 0 1 1 1 1 0 1 1 1 0 1) 4.193545 (fv 0.000000 1.673990 1.704095 0.184742 0.312157 1.759699 0.661838 0.338558 1.336129 0.060082 0.592895 0.470075 0.323799 1.690560 1.851587) 4.193539 (fv 0.000000 1.674972 1.705674 0.187574 0.315997 1.764079 0.667192 0.344813 1.343115 0.068186 0.601740 0.479341 0.334140 1.702389 1.863580) 4.192089 (fv 0.000000 1.673474 1.702683 0.182852 0.310553 1.756894 0.658556 0.335052 1.332116 0.055950 0.587971 0.464438 0.317829 1.684035 1.844319) ) ;;; 16 even -------------------------------------------------------------------------------- (vector 16 5.0737318992615 (fv 0 1 1 1 1 1 1 1 0 0 1 1 1 0 1 0) 4.326467 (fv 0.000000 0.954646 0.857741 0.564427 0.380619 -0.030405 0.027220 0.443651 0.347240 0.290827 1.057423 1.274647 0.193509 1.337335 0.715554 1.355809) 4.326323 (fv 0.000000 0.953094 0.856111 0.562335 0.378555 -0.035716 0.021343 0.437774 0.341052 0.283988 1.049334 1.266917 0.184364 1.326298 0.704383 1.343207) 4.325044 (fv 0.000000 0.953571 0.856165 0.561119 0.376819 -0.035768 0.021241 0.436352 0.339200 0.281830 1.047126 1.263828 0.181703 1.324018 0.701028 1.340302) ) ;;; 17 even -------------------------------------------------------------------------------- (vector 17 5.2332563400269 (fv 0 0 0 0 0 0 0 1 1 0 1 0 0 1 1 1 0) 4.464096 (fv 0.000000 1.478399 1.021179 1.293532 1.222041 1.188322 1.479616 1.284032 0.091138 1.349289 0.401522 0.364537 -0.044880 1.268488 1.386805 0.039323 0.607489) 4.463016 (fv 0.000000 1.478182 1.023133 1.293051 1.222719 1.187462 1.479990 1.285327 0.088371 1.348357 0.403976 0.365587 -0.044469 1.267681 1.387786 0.039745 0.610112) ) ;;; 18 even -------------------------------------------------------------------------------- (vector 18 5.3310880661011 (fv 0 1 1 1 1 0 0 1 0 1 1 0 0 0 1 0 0 0) 4.569421 (fv 0.000000 1.011793 0.580064 1.185332 1.624771 0.036509 -0.103084 0.721775 1.089226 0.493658 0.073953 1.074825 1.595710 1.108207 1.196849 1.497424 1.163445 0.995437) ) ;;; 19 even -------------------------------------------------------------------------------- (vector 19 5.4619059562683 (fv 0 0 1 0 0 0 0 0 0 0 1 0 0 1 1 1 0 0 0) 4.741489 (fv 0.000000 1.217162 0.660633 0.437661 1.320878 1.235636 0.094939 -0.184508 -0.090396 0.415156 1.119340 1.141612 0.652398 0.817014 0.525642 1.150459 0.295913 0.906911 0.831168) ) ;;; 20 even -------------------------------------------------------------------------------- (vector 20 5.5266017913818 (fv 0 0 1 1 1 0 0 0 1 0 1 1 0 1 1 1 1 1 1 0) 4.839482 (fv 0.000000 0.882739 0.097549 0.018330 1.302731 0.272028 1.407538 1.702479 0.580972 1.045015 0.992304 1.669564 0.673981 0.282219 0.289947 0.363499 1.033218 0.803741 0.771035 0.508087) ) ;;; 21 even -------------------------------------------------------------------------------- (vector 21 5.6849967470046 (fv 0 0 0 0 1 1 0 0 0 1 0 0 1 1 0 1 0 0 0 0 0) 4.919735 (fv 0.000000 -0.021966 1.377831 1.499470 -0.139205 1.937761 0.320320 0.217546 0.069290 0.938854 1.308616 0.123782 0.469963 1.818882 1.581666 1.414927 0.056553 1.301602 0.788305 1.336052 0.607478) ) ;;; 22 even -------------------------------------------------------------------------------- (vector 22 5.8572781078687 (fv 0 1 0 0 1 1 0 1 0 1 0 0 1 1 1 0 0 0 0 0 0 0) 5.055233 (fv 0.000000 -1.550778 1.843415 0.900724 0.955590 0.677531 1.390686 0.133831 1.229871 1.016503 1.245622 1.546957 -1.869615 1.414871 -0.060378 -0.077148 1.210164 1.132173 0.909114 1.325478 1.285781 0.509617) ) ;;; 23 even -------------------------------------------------------------------------------- (vector 23 5.9208135892745 (fv 0 0 1 0 0 1 0 0 0 0 1 0 0 0 1 0 1 1 1 0 0 0 0) 5.147900 (fv 0.000000 0.493561 0.617878 0.386087 -0.215675 1.136922 0.632292 0.891205 1.398746 0.878537 0.676611 0.945565 0.610792 -0.182076 0.354229 1.383426 1.649635 0.414770 0.152656 0.561509 0.267633 1.102796 1.466348) ) ;;; 24 even -------------------------------------------------------------------------------- (vector 24 6.0318420391191 (fv 0 1 0 0 1 1 1 0 0 1 1 1 1 0 0 1 0 1 1 1 1 1 1 0) 5.253162 (fv 0.000000 0.045084 0.641921 -0.205904 0.266767 1.228115 0.912709 0.214922 1.487762 1.357882 0.864877 0.404420 0.601935 0.594931 0.069420 1.052347 1.659787 1.624121 0.035857 0.245103 1.406872 0.042697 -0.053953 0.167577) ;; nce: 5.253153 (fv 0.000000 0.045202 0.642246 -0.205352 0.266926 1.228585 0.913398 0.215740 1.488650 1.358650 0.865965 0.405240 0.603061 0.596132 0.070695 1.053498 1.661316 1.625634 0.037488 0.246663 1.408918 0.044558 -0.052337 0.169870) ) ;;; 25 even -------------------------------------------------------------------------------- (vector 25 6.1513186981755 (fv 0 0 1 0 1 0 0 0 0 1 1 1 0 0 0 1 0 0 1 1 0 1 1 1 1) 5.403228 (fv 0.000000 0.045060 1.794212 1.406802 1.249045 0.257853 0.430644 -0.020674 0.209605 1.159346 1.742584 0.244624 1.006989 0.948352 0.613996 0.229169 0.745474 0.773295 0.271006 1.529917 0.384835 1.822065 0.327936 0.153008 0.689262) ;; nce: 5.408253 (fv 0.000000 -0.043635 1.870808 1.373617 1.322838 0.337670 0.345509 0.039602 0.231587 1.174477 1.746219 0.272425 1.051956 0.894710 0.701095 0.201178 0.713607 0.745859 0.396015 1.495521 0.465720 1.748739 0.254514 0.207309 0.670746) ) ;;; 26 even -------------------------------------------------------------------------------- (vector 26 6.2921685546205 (fv 0 0 1 0 1 0 0 0 0 0 0 0 0 1 1 1 1 0 0 1 0 0 1 1 0 0) 5.452331 (fv 0.000000 0.051327 0.204117 1.807782 0.408597 -0.021081 0.115796 0.407761 0.824888 0.626144 0.637118 0.067354 0.844059 0.574978 -0.127497 -0.091341 1.702516 0.546084 0.986055 1.260143 0.631019 1.781357 1.305578 1.812413 0.666374 0.989339) ) ;;; 27 even -------------------------------------------------------------------------------- (vector 27 6.2436904245852 (fv 0 1 1 0 0 0 0 0 1 0 0 0 0 1 0 0 1 1 1 0 1 0 0 0 0 0 1) 5.620374 (fv 0.000000 -0.021456 0.516604 0.372410 0.864531 1.336703 -0.209149 1.689313 0.033950 1.772624 0.571345 1.616802 0.355488 1.092886 1.391271 1.240098 1.111612 0.854249 0.888716 0.157123 -0.311986 1.252460 1.082038 -0.272435 1.564985 0.964546 1.600742) ) ;;; 28 even -------------------------------------------------------------------------------- (vector 28 6.5361909866333 (fv 0 0 1 1 0 1 1 0 0 1 0 1 0 1 0 0 1 1 1 0 0 1 1 1 1 1 1 1) 5.731679 (fv 0.000000 1.447589 1.395977 0.797533 1.295906 1.462640 1.534875 1.774902 1.013697 0.705377 0.626264 1.242696 1.362454 0.181714 0.805604 1.271981 0.570662 1.779635 -0.124462 1.352040 -0.225912 1.764222 0.153642 1.298969 0.773437 0.201599 0.803480 0.102660) ;; nce: 5.757769 (fv 0.000000 -0.064452 1.194800 0.947245 0.026529 0.920008 0.673833 0.051447 -0.007043 1.637680 1.814843 1.945096 0.720067 0.530198 0.753640 0.603773 1.296939 0.860024 0.197512 0.571117 0.903138 1.152266 0.326717 0.457781 -0.069831 0.864587 1.677694 0.471749) ) ;;; 29 even -------------------------------------------------------------------------------- (vector 29 6.6767044067383 (fv 0 1 0 0 0 1 0 1 0 1 1 1 0 0 1 0 0 1 0 1 1 1 1 0 0 1 1 1 1) 5.766338 (fv 0.000000 1.750571 1.825931 1.106253 0.681108 0.654013 0.530242 0.078216 0.174544 1.354195 1.454712 1.045782 1.722411 1.607453 0.347380 0.849326 0.377709 1.136286 1.004911 0.970793 0.410809 0.919085 1.010160 0.193230 0.966878 0.662369 1.289507 1.533180 0.429508) ) ;;; 30 even -------------------------------------------------------------------------------- (vector 30 6.6998701095581 (fv 0 0 0 1 0 1 1 0 1 1 1 1 1 0 0 0 0 1 1 1 1 0 1 1 1 0 1 1 1 0) 5.906955 (fv 0.000000 0.906624 1.374273 1.276597 -0.178673 0.094922 0.333601 0.129339 0.400307 0.946356 1.401096 0.557587 0.654474 1.274947 0.061009 -0.048005 1.903626 1.753056 1.439902 1.944968 1.607217 1.115332 0.419220 1.617499 1.734563 1.091117 0.095163 0.781775 -0.001559 1.852411) ;; nce: 5.930402 (fv 0.000000 -0.023546 1.489564 1.475097 0.916826 0.864026 1.899229 1.607559 0.910332 0.924096 1.371927 0.795577 0.542873 0.396054 0.844978 1.658639 0.174074 0.939529 1.326938 1.039010 1.301858 1.417763 1.619561 1.723680 0.850267 0.018519 1.089727 0.405902 1.206335 1.833260) ) ;;; 31 even -------------------------------------------------------------------------------- (vector 31 6.8660564422607 (fv 0 1 0 0 1 1 0 1 1 1 0 1 0 0 0 0 0 1 0 0 1 0 1 0 0 1 1 1 0 0 0) 5.987789 (fv 0.000000 1.294084 1.380328 1.151198 1.131917 1.032100 1.467500 1.317593 1.561230 1.149337 1.426512 0.310391 0.093956 -0.092069 1.618651 0.385482 1.276093 0.768907 0.092705 1.372235 0.935730 0.030657 0.353616 1.817773 0.372502 0.700675 1.341184 1.537494 1.331726 0.302069 0.818207) ) ;;; 32 even -------------------------------------------------------------------------------- (vector 32 6.9974670410156 (fv 0 0 0 1 1 1 0 1 0 0 1 1 1 0 0 0 1 0 0 1 1 0 1 0 0 0 0 0 0 0 1 0) 6.061091 (fv 0.000000 0.284769 1.824838 0.360868 1.114185 0.962149 1.153553 1.836957 0.183317 1.504519 0.431670 1.106470 0.465083 1.359049 1.532974 1.672623 0.833072 1.851412 -0.259099 1.829526 0.240313 0.782734 0.067562 1.704922 0.670838 0.000337 1.835105 1.184487 1.464400 1.660678 0.971147 1.137597) ) ;;; 33 even -------------------------------------------------------------------------------- (vector 33 6.978609085083 (fv 0 0 0 0 1 0 0 0 1 1 1 1 0 0 0 0 0 0 1 0 0 0 1 0 0 1 1 0 1 0 1 1 0) 6.162617 (fv 0.000000 -0.095863 -0.402980 1.394421 -0.306134 0.366840 0.337119 0.377845 0.129322 0.155850 1.349812 0.235845 0.252319 0.242909 1.431344 1.664418 1.236043 1.670315 1.653641 0.461681 0.695631 0.916345 0.353418 1.885954 1.309177 0.582371 1.382992 1.788982 0.399357 0.760664 0.154447 0.882692 0.073082) ) ;;; 34 even -------------------------------------------------------------------------------- (vector 34 7.2615523338318 (fv 0 1 0 0 1 0 1 1 0 1 0 1 1 1 0 0 0 1 0 1 1 1 0 0 1 1 1 1 1 1 1 1 0 0) 6.222816 (fv 0.000000 -0.031974 0.094234 0.502100 0.850042 0.574691 0.752336 1.914959 -0.024174 0.146232 0.295078 1.383128 -0.007584 0.943763 1.235227 0.413741 0.587141 -0.053979 1.839683 0.252526 0.156123 0.682869 0.409598 -0.127649 0.823619 0.505563 1.228553 1.452425 1.154757 0.224780 1.122198 1.589227 1.075252 0.529430) ) ;;; 35 even -------------------------------------------------------------------------------- (vector 35 7.2921919822693 (fv 0 0 0 0 0 1 0 1 1 1 0 0 0 1 0 0 1 1 0 1 0 0 1 1 1 0 0 0 0 1 0 0 0 0 0) 6.362258 (fv 0.000000 -0.109595 1.553671 0.219728 0.238496 1.170971 0.131935 0.808676 1.471325 1.403853 0.916637 1.560710 -0.099827 1.196395 0.221158 1.202313 0.775632 0.876517 1.782554 1.124579 1.420710 0.952275 0.641256 1.819844 1.425015 -0.516862 1.352551 1.568353 1.482981 0.524776 0.577204 0.865347 -0.128894 -0.102429 0.426519) ) ;;; 36 even -------------------------------------------------------------------------------- (vector 36 7.3326554298401 (fv 0 0 1 0 1 0 1 1 0 0 1 1 1 0 1 1 0 0 1 1 1 1 0 0 1 1 1 1 1 0 1 0 0 0 0 0) 6.432117 (fv 0.000000 0.004340 0.086403 1.388728 0.898065 1.458617 0.131985 1.657435 1.521273 1.472417 0.951218 1.324245 1.241442 1.395549 0.150266 1.064974 0.650640 1.427046 1.086279 0.098701 0.328772 1.795832 1.461165 0.857821 1.693245 1.032679 1.245848 0.174782 -0.135078 0.155045 -0.013817 0.388292 0.719587 1.603641 0.575715 0.836424) ;; nce: 6.433446 (fv 0.000000 -0.039571 0.060618 1.408936 0.882042 1.447670 0.143068 1.639607 1.518329 1.469129 0.942793 1.305387 1.226395 1.375800 0.162353 1.047466 0.675921 1.406954 1.102981 0.111251 0.337382 1.829176 1.494772 0.804464 1.712328 1.039053 1.250692 0.166362 -0.143216 0.133112 -0.012403 0.370517 0.701621 1.606484 0.581751 0.854317) ) ;;; 37 even -------------------------------------------------------------------------------- (vector 37 7.4919209480286 (fv 0 1 1 0 0 1 1 1 0 0 0 1 0 0 1 0 1 1 0 1 0 0 1 1 1 0 1 0 0 0 1 0 0 0 0 0 0) ;; ce: 6.533287 (fv 0.000000 0.011564 0.880733 1.522736 0.250376 0.789024 1.673119 0.570623 1.276735 0.341425 -0.532081 0.348007 -0.836598 0.457646 -0.009210 1.409326 1.013302 0.369886 1.439731 1.104224 1.371479 0.882940 0.611993 0.167228 0.213651 -0.123007 -0.145430 -0.035562 0.326284 0.342544 0.027533 0.469211 0.589131 1.242729 -0.350729 -0.122043 0.359222) ) ;;; 38 even -------------------------------------------------------------------------------- (vector 38 7.669114112854 (fv 0 1 1 1 0 1 1 0 0 1 0 1 0 0 0 1 1 0 1 1 0 1 1 1 0 0 0 1 0 1 1 0 0 0 0 0 0 0) 6.536590 (fv 0.000000 -0.020563 1.377251 1.769036 0.243537 1.765876 1.779834 1.045673 1.286350 0.293614 0.321305 1.723518 1.560003 0.401205 0.333918 -0.059485 0.232219 0.960903 1.594163 1.401434 0.649608 0.412099 1.329747 0.099455 1.939824 0.267997 0.403580 1.515217 0.579512 0.002234 0.262847 1.800156 0.419089 1.615975 1.110793 1.305676 1.421012 1.714827) ) ;;; 39 even -------------------------------------------------------------------------------- (vector 39 8.0062685830938 (fv 0 0 0 1 1 0 1 0 1 0 1 1 1 0 1 0 1 1 0 1 0 0 0 0 1 0 0 0 0 0 1 1 0 1 1 0 0 0 0) 6.683157 (fv 0.000000 1.091390 0.284404 0.240879 1.660743 1.656550 0.223587 1.552502 0.232972 0.325977 1.767287 0.511127 0.573904 0.685387 0.354731 1.006014 0.648089 0.445081 1.696394 0.327980 -0.210151 0.338005 -0.052572 -0.119111 0.551717 1.087945 0.035621 1.385382 0.802270 1.342811 0.005749 0.410111 0.489512 1.361009 1.309724 1.490142 1.368577 0.636471 0.518214) ) ;;; 40 even -------------------------------------------------------------------------------- (vector 40 8.0304555793911 (fv 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 1 0 1 0 0 1 1 0 1 0 1 1 0 0 0 1 0 1 1 0 0 0 1) 6.748142 (fv 0.000000 0.029455 0.022065 0.136105 1.638522 1.203180 0.744941 -0.148784 0.506171 0.560051 -0.084723 -0.078289 0.149301 0.575133 1.046850 1.733499 1.932780 1.304846 -0.055855 1.484587 1.130478 0.869457 1.564935 1.665772 1.478237 0.851162 0.123617 0.568797 1.544770 0.060395 1.377474 0.739849 -0.238843 1.303906 1.521850 1.552033 0.224167 1.493979 0.103832 0.387098) ) ;;; 41 even -------------------------------------------------------------------------------- (vector 41 8.2169809341431 (fv 0 1 1 1 0 1 0 1 1 1 1 0 0 0 1 0 1 1 1 0 1 1 1 1 1 0 1 1 1 0 0 1 1 1 0 0 1 0 0 1 0) 6.881035 (fv 0.000000 0.133290 0.436430 -0.019956 0.597994 -0.299445 0.298044 -0.291816 -0.125561 1.379945 1.227240 1.012471 0.995085 0.165521 0.059156 -0.315277 -0.410140 1.321719 -0.217071 0.006502 1.718169 0.636248 0.520158 0.977079 1.417462 -0.764436 1.377242 0.286309 1.475385 1.360726 0.551504 -0.329940 1.190956 0.377718 1.221012 1.703028 0.053941 0.664915 1.563928 1.320457 0.168607) ) ;;; 42 even -------------------------------------------------------------------------------- (vector 42 8.3605623245239 (fv 0 1 1 1 0 1 0 0 0 1 0 0 1 1 1 0 0 0 1 0 1 1 0 1 0 1 1 1 1 0 0 1 0 0 0 1 0 0 0 0 0 1) 6.941481 (fv 0.000000 -0.007293 1.286795 1.752349 -0.276621 1.210682 0.997503 0.480778 0.607692 1.419140 -0.000887 0.317063 0.225619 -1.792990 -0.085405 1.621718 1.141369 0.612500 1.711137 0.371822 0.494518 1.158070 0.720118 -0.061260 0.895705 0.558493 0.565336 0.673764 0.965927 1.131140 0.011389 1.067604 1.758075 0.687249 0.164819 0.032158 0.192333 0.816334 0.404498 1.292703 0.160108 0.486834) ) ;;; 43 even -------------------------------------------------------------------------------- (vector 43 8.3471550144283 (fv 0 1 0 1 0 1 0 0 0 1 1 1 1 1 1 1 0 1 0 0 0 0 1 0 0 1 0 0 0 0 1 1 0 0 0 0 1 1 0 0 1 0 0) 7.055197 (fv 0.000000 0.047763 1.657931 1.619393 1.901312 1.535197 1.519084 0.139389 -0.012074 1.734976 0.124057 1.726677 0.967925 0.859090 0.315172 0.782383 0.749080 1.794616 -0.192964 1.214822 1.594002 0.299675 1.830679 1.396713 1.089896 0.461626 0.318824 0.888695 1.307168 1.600142 0.874003 1.625797 0.872538 1.803252 0.868969 0.618677 0.932144 0.968270 1.700058 0.258149 0.614848 0.031586 0.805044) ) ;;; 44 even -------------------------------------------------------------------------------- (vector 44 8.4271850585938 (fv 0 0 1 0 0 1 1 0 1 0 1 0 0 0 1 0 1 0 1 1 0 0 0 1 0 0 1 1 1 0 0 0 0 1 1 0 0 0 1 1 1 1 1 1) 7.048255 (fv 0.000000 -0.024272 1.042039 1.706381 0.915231 0.667566 0.791468 1.060500 0.486474 0.357952 1.448848 0.555099 0.559674 0.047957 0.101663 0.263196 0.561105 1.754886 1.445748 0.607834 0.094941 0.549126 0.219045 0.643754 0.108792 0.622710 0.657739 1.176141 0.892775 1.899443 0.047927 1.097541 1.395320 1.432930 0.524754 1.590031 -0.111160 0.804186 0.328664 0.621384 1.470620 1.417525 -0.298999 1.020701) ) ;;; 45 even -------------------------------------------------------------------------------- (vector 45 8.6353975051189 (fv 0 0 1 0 0 1 1 0 1 1 0 1 1 0 0 0 1 1 1 1 1 0 1 1 0 0 0 1 0 0 0 0 0 0 0 1 1 1 0 0 1 0 1 0 1) 7.165216 (fv 0.000000 0.100769 0.427512 0.242955 0.443088 -0.380155 1.940929 -0.101098 -0.133968 -0.026473 1.678192 1.774836 0.508005 0.350465 0.553068 1.094302 0.286670 -1.617200 0.541014 0.212204 1.154970 1.344936 0.804485 1.614258 1.391670 0.188798 0.475817 0.610176 0.585642 -0.044233 1.516307 0.921356 1.091747 0.246161 0.592046 1.532410 0.320765 0.050475 1.141805 0.866052 0.300507 0.986581 -0.103223 1.338567 0.196051) ) ;;; 46 even -------------------------------------------------------------------------------- (vector 46 8.7939519711145 (fv 0 1 0 1 1 1 0 1 0 1 1 0 1 0 1 1 1 1 1 0 0 1 1 1 1 0 0 0 1 0 0 1 1 0 0 0 1 0 1 1 1 1 1 1 1 0) 7.276006 (fv 0.000000 -0.054506 1.032755 -0.130142 -0.261502 1.224902 0.252129 0.556107 0.758621 1.480820 -0.142360 1.184737 0.014000 1.776705 0.882036 1.883695 0.222183 0.298085 0.448405 1.172485 0.678362 1.341204 0.081280 -0.085381 0.763100 -0.029414 -0.367000 0.048240 1.040410 1.413704 0.227444 -0.058776 -0.204130 1.202166 1.632528 1.205475 1.219937 1.182203 -0.061521 1.269256 0.937830 0.491219 -0.180909 0.028085 1.489097 0.059386) ) ;;; 47 even -------------------------------------------------------------------------------- (vector 47 8.7835607528687 (fv 0 0 0 0 1 0 1 0 1 0 0 0 0 1 1 0 0 1 0 1 0 0 1 1 1 1 0 1 0 1 1 1 0 0 1 0 0 1 0 0 0 1 1 1 1 1 1) 7.292551 (fv 0.000000 -0.062265 1.442422 1.057676 1.927078 0.605872 0.092606 0.058532 0.177290 1.141099 0.824596 0.143569 1.542821 0.439342 0.943358 1.070588 0.909454 0.332472 1.825929 1.744493 0.079522 0.781524 1.378798 1.290207 0.477850 0.651309 0.041772 0.753335 1.194909 0.871931 1.816269 1.466251 1.199198 1.733301 1.531356 -0.102896 0.905701 1.309802 1.098908 1.238880 1.394185 0.875551 1.145434 -0.145313 0.593458 0.073230 0.938656) ) ;;; 48 even -------------------------------------------------------------------------------- (vector 48 8.9965600967407 (fv 0 1 1 0 1 0 0 0 0 0 0 0 0 1 1 1 0 1 1 0 0 0 1 0 0 1 0 0 0 0 0 1 1 0 1 0 1 0 0 0 1 1 1 0 1 0 1 1) ;; ce: 7.406994 (fv 0.000000 0.047945 0.826536 0.973372 1.740017 0.529769 1.008330 1.827057 0.727986 1.449120 0.514522 1.295511 0.015768 1.206235 0.269772 1.336523 0.110706 1.398598 0.887898 1.776715 1.044804 0.419039 -0.057090 1.238424 0.514960 0.147966 1.655287 1.338551 0.870612 0.661410 0.361317 0.267510 -0.382725 -0.031215 1.567563 1.583622 1.671939 1.775367 1.875910 1.638385 1.546190 0.129055 0.397477 0.763475 0.970476 1.468225 1.622446 0.158949) ) ;;; 49 even -------------------------------------------------------------------------------- (vector 49 9.1650037765503 (fv 0 1 0 1 0 0 1 1 0 1 0 1 0 0 0 0 1 1 0 0 0 0 0 1 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 1 1 1 1 1 0 1 0 0 0) ;; ce: 7.532053 (fv 0.000000 0.041305 0.532327 1.215473 1.024214 1.052795 0.585923 1.613470 1.301563 0.656356 1.815283 1.368492 -0.020005 0.356482 1.940348 0.124177 0.127083 1.593092 1.501593 0.678778 0.554128 0.952456 -0.422395 1.575963 0.870840 0.819687 0.743668 0.245617 0.895216 0.369895 0.471783 1.223006 0.679195 1.170671 0.931311 1.629049 0.745807 0.483912 0.397101 0.224181 0.816909 1.126241 1.477811 0.320980 1.574780 0.412692 0.741112 1.583749 0.654625) ) ;;; 50 even -------------------------------------------------------------------------------- (vector 50 9.1582123370176 (fv 0 1 0 0 1 0 0 0 1 1 0 0 1 0 1 1 1 0 1 1 1 1 0 0 1 0 1 1 1 1 0 1 0 0 0 0 1 0 0 0 1 0 1 1 1 1 0 0 0 1) ;; ce: 7.553949 (fv 0.000000 0.001153 1.444901 -0.126735 -0.207597 1.037485 0.982912 0.657278 1.609015 0.548946 0.388265 1.860455 1.146064 0.991559 1.714083 0.419464 0.114879 0.538313 1.517340 1.406138 0.768916 1.006070 1.575014 1.565071 1.458974 0.980173 1.203265 1.481696 -0.150280 1.613515 0.690225 0.227360 0.618441 0.290246 1.012000 0.302852 -0.136236 -0.046604 1.075996 0.025371 0.550031 1.195469 0.193455 0.810822 0.527380 1.640757 0.113795 0.191137 1.871211 0.281051) ) ;;; 51 even -------------------------------------------------------------------------------- (vector 51 9.3615226745605 (fv 0 0 0 1 1 1 1 0 1 0 1 1 0 1 0 0 0 1 1 0 0 1 1 0 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 1 0 0 0 1 0 1 0 0 1 1 0) ;; nce: 7.601889 (fv 0.000000 -0.097299 1.522524 0.604656 1.190459 -0.046061 1.637924 0.391838 1.914014 1.191379 0.937217 0.903859 1.190560 -0.310642 0.795112 0.607488 1.496318 -0.432640 -0.101925 0.993972 1.031274 1.167246 0.466609 0.643027 0.235799 0.569210 0.641350 0.632197 0.268712 1.299950 1.493958 0.876871 -0.115765 0.447597 1.299543 -0.601543 0.991250 1.221680 0.433618 1.269835 0.891674 -0.222937 1.508906 1.194487 1.696510 0.136336 0.547118 0.154250 -0.399784 0.814800 1.474647) ) ;;; 52 even -------------------------------------------------------------------------------- (vector 52 9.449512348335 (fv 0 1 1 1 1 1 1 0 0 0 0 0 0 1 1 1 0 1 0 0 1 0 1 1 1 0 0 1 1 0 1 0 0 0 1 0 1 0 0 0 1 1 1 1 0 1 1 1 1 0 1 1) ;; ce: 7.715514 (fv 0.000000 -0.034843 1.299671 1.297722 1.635310 -0.140716 1.100950 -0.118100 0.547763 0.498559 0.115301 1.387617 0.497862 0.517177 1.775867 1.036003 1.303001 0.627699 1.126538 0.667873 0.716185 0.672233 0.573373 1.713393 1.674703 1.675881 -0.219625 0.205462 0.688511 -0.167042 0.095308 -0.056923 0.925655 1.318413 1.379568 1.567357 0.318805 -0.064577 1.458169 1.228224 0.320505 1.504325 0.170852 1.908593 0.774335 0.156462 0.959528 -0.009590 -0.029886 1.318052 1.521653 0.208620) ) ;;; 53 even -------------------------------------------------------------------------------- (vector 53 9.6159172058105 (fv 0 1 0 1 1 1 1 1 1 1 1 0 0 0 1 1 0 0 0 0 0 1 1 1 1 0 1 0 0 1 0 0 0 0 1 0 1 0 1 0 0 0 0 0 1 0 0 1 1 0 0 1 0) 7.750487 (fv 0.000000 0.036779 0.620619 1.389030 1.448590 0.206060 1.401187 0.716369 0.552235 0.039103 0.347305 1.846613 0.552018 1.491421 1.339207 1.372862 1.129023 1.023345 1.671571 0.563034 0.162746 0.439370 1.163228 -0.070535 0.315773 0.561792 1.174490 1.839925 1.161557 1.788132 0.000155 0.215127 1.156326 0.635275 1.204301 0.236777 -0.137602 1.267159 0.914139 0.933059 0.732878 0.757869 1.209147 1.287260 1.087065 1.355017 0.578394 1.465757 0.725442 0.562270 1.513798 1.240390 0.721272) ) ;;; 54 even -------------------------------------------------------------------------------- (vector 54 9.5190944671631 (fv 0 1 0 1 1 1 1 1 1 1 0 0 1 0 0 1 1 1 1 1 1 1 0 0 1 1 0 1 1 1 0 0 0 0 1 1 0 0 0 1 1 1 1 0 1 1 1 0 1 0 1 0 1 1) 7.845083 (fv 0.000000 0.061451 0.633202 0.842273 1.609750 1.150617 1.710229 0.507090 -0.042557 0.310551 0.314728 0.987790 1.351858 1.063896 1.713078 1.603814 0.132592 0.924440 -0.380633 0.855851 1.637781 0.813597 1.013698 0.861640 0.327742 0.192164 0.896540 1.734094 0.874167 -0.001625 0.106463 0.214754 1.657275 0.272925 1.907315 1.437104 1.086576 0.701261 0.411048 1.402011 1.872416 0.559924 1.401281 1.776842 1.632661 1.672063 -0.088862 1.645896 0.861803 0.137030 1.828399 0.307366 0.083970 1.711361) ) ;;; 55 even -------------------------------------------------------------------------------- (vector 55 9.6719217300415 (fv 0 1 0 0 1 0 1 1 0 0 1 0 1 0 1 0 1 0 1 1 0 1 0 1 1 1 0 0 1 1 0 0 1 0 0 0 0 1 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 1 1) ;; ce: 7.908224 (fv 0.000000 -0.006122 1.706850 -0.138031 1.409264 -0.179924 1.291393 0.095673 0.477101 1.213765 -0.191085 0.117017 0.016865 0.128090 1.052814 -0.223928 0.648751 1.402762 0.456990 0.553356 1.095940 1.027495 0.299767 0.447120 0.205834 1.452671 -0.085699 1.609363 1.101039 1.058600 -0.087300 1.595987 1.179897 0.004643 1.423903 0.778740 0.553053 1.139184 0.724189 1.453952 0.381783 0.586983 0.831862 1.181073 0.788144 1.024391 1.771531 1.598505 0.863121 0.198894 0.450345 0.085968 1.228457 0.544951 0.771388) ) ;;; 56 even -------------------------------------------------------------------------------- (vector 56 9.6809562784664 (fv 0 0 0 1 0 0 1 0 0 1 1 0 0 1 1 1 1 1 0 0 0 1 1 0 0 0 1 0 0 0 0 1 1 1 1 1 1 0 1 0 1 1 1 0 1 1 1 1 1 0 1 1 0 1 0 1) ;; ce: 8.011195 (fv 0.000000 0.008210 0.905992 0.396571 1.720897 1.158304 1.138541 -0.149073 1.014952 1.018591 1.745765 0.438732 0.854592 1.654860 1.011019 1.080405 0.999544 1.358343 1.494524 -0.322084 1.515909 1.690243 0.974840 0.937768 1.405811 0.436415 0.424543 1.360935 -0.014499 1.482939 0.090605 0.959441 1.032814 1.287153 0.868562 1.424617 0.689023 1.690605 0.303801 0.396076 -0.120753 1.039594 0.342297 0.231504 -0.042441 1.626406 0.755064 0.442808 1.366653 1.769637 -0.205340 -0.239797 0.934356 1.176593 0.655901 1.488666) ) ;;; 57 even -------------------------------------------------------------------------------- (vector 57 9.8992366790771 (fv 0 0 1 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 1 0 1 0 0 1 0 1 1 1 1 0 0 0 0 1 0 0 0 0 1 1 1 1 0 0 0 1 0 1 0 0 1 1 0 0 1) ;; ce: 7.998443 (fv 0.000000 -0.014666 1.566831 1.522473 -0.249684 1.548885 0.061859 1.226467 1.343794 0.283370 1.644204 -0.263860 0.040445 -0.006696 1.612019 1.549636 0.536480 0.507272 1.129223 0.096416 0.070654 1.146329 0.116347 1.310955 1.044576 1.855920 1.741244 0.737054 0.646099 0.980172 1.413425 1.269711 1.581860 1.800144 1.281998 -0.058342 0.653062 1.547228 1.144145 0.578917 0.690679 0.861263 0.345954 0.676296 0.259007 0.725329 -0.285685 1.547409 0.602010 1.240793 0.038406 1.789143 1.881017 1.026132 0.600098 1.097228 -1.919911) ) ;;; 58 even -------------------------------------------------------------------------------- (vector 58 9.8761510848999 (fv 0 1 1 1 1 1 0 0 0 1 0 0 0 1 1 1 1 0 1 1 0 0 0 1 1 0 1 0 0 0 1 1 1 1 1 1 0 1 1 1 1 1 1 0 1 1 0 1 0 0 1 1 0 1 0 0 0 1) 8.102746 (fv 0.000000 0.021804 0.347449 0.712574 0.904596 1.645925 0.230015 0.473992 0.104969 1.934740 1.209012 1.104800 1.062683 0.358409 0.785934 1.465266 1.235573 1.772411 0.072477 1.559281 1.754795 0.147077 0.219637 0.050078 1.441852 0.333339 0.672730 1.789640 1.230725 1.303568 1.622831 1.659814 0.995447 1.205094 1.295826 0.837873 0.521849 1.476121 0.531055 1.439237 1.534776 0.923559 1.866584 1.504388 0.402718 1.262304 0.589470 1.403389 1.379169 0.218840 1.535374 0.130494 0.618342 0.285582 1.711521 1.399310 1.463120 1.577451) ;; nce: 8.160514 (fv 0.000000 0.018101 0.649039 1.105139 0.805799 1.552840 0.507143 0.455093 0.410985 1.820561 0.914505 0.984750 1.066413 0.191884 0.653627 1.510871 1.561405 1.875189 -0.078120 1.639973 1.489309 -0.122302 0.187579 -0.137707 1.247718 0.796984 0.621022 1.565078 1.132796 1.098952 1.427880 1.663078 0.762131 0.965307 1.352999 0.722067 0.412348 1.684775 0.457834 1.443318 1.385930 0.962906 1.869715 1.351690 0.195092 1.084773 0.690763 1.132481 1.402235 0.306205 1.443881 0.266933 0.858427 0.045513 1.705481 1.280871 1.423605 1.246177) ) ;;; 59 even -------------------------------------------------------------------------------- (vector 59 10.094394683838 (fv 0 1 1 0 1 0 1 0 0 0 1 1 1 0 0 1 1 1 1 0 0 0 0 0 1 0 1 1 0 1 1 0 1 0 0 0 1 1 0 1 1 0 0 0 1 1 0 1 1 1 0 1 1 1 1 1 1 1 1) 8.194538 (fv 0.000000 0.192440 1.064997 1.405447 0.666893 0.441718 0.460123 -0.029893 0.102290 1.233991 1.287456 0.262828 0.891341 1.622477 -0.078945 0.794492 1.676056 0.757298 1.625170 1.288224 1.021602 1.270621 0.622162 1.173256 0.639594 0.085293 0.804874 1.211161 -0.067577 0.210901 0.178378 0.446246 -0.092053 1.813463 1.120832 1.269392 -0.271084 1.861664 0.195222 0.087459 0.045547 0.257753 0.386709 0.151559 1.002452 0.352762 0.090741 1.494023 0.840240 1.424148 0.778422 -0.109268 1.896909 0.853535 0.284500 1.503148 1.606229 1.606587 0.287318) ) ;;; 60 even -------------------------------------------------------------------------------- (vector 60 10.333255371943 (fv 0 0 0 1 0 1 1 1 1 0 1 1 0 0 1 0 0 1 1 0 1 0 0 1 0 1 0 1 0 1 0 0 1 1 0 0 0 1 1 1 1 0 0 1 0 0 0 0 1 0 0 0 0 1 1 1 1 1 0 0) 8.312421 (fv 0.000000 0.016764 0.099999 0.395290 1.344482 1.502674 0.248570 0.971438 0.736859 1.561216 0.263938 1.242184 -0.428796 -0.122031 1.528486 0.190921 1.269506 0.099840 0.618839 0.286668 0.310580 0.121766 0.645000 0.953645 1.140529 0.456214 0.631806 0.922426 0.396932 1.354468 1.176819 0.515695 0.171198 0.662750 1.320434 0.506395 1.565445 0.874857 0.531897 0.782628 0.471079 -1.819575 1.656923 0.206815 0.413621 0.205859 1.749126 1.236787 1.333671 0.085487 1.468799 1.666444 0.266215 0.649751 0.639546 0.431656 1.171882 1.863798 1.376382 0.482890) ;; ce: 8.297419 (fv 0.000000 -0.050827 -0.093113 0.415337 1.376502 1.483467 0.139153 0.992518 0.529850 1.653904 0.191931 1.095275 -0.256090 -0.161285 1.405742 0.150354 1.336151 -0.049296 0.676639 0.179468 0.223738 -0.026447 0.633754 1.009834 1.247179 0.478290 0.662079 0.748655 0.357085 1.374703 1.160927 0.429236 0.231499 0.680606 1.275377 0.482417 1.486029 0.955636 0.656194 0.784771 0.415616 -1.691681 1.767041 0.147548 0.371057 0.291191 1.824186 1.135403 1.361375 0.394251 1.554796 1.735953 0.147583 0.633615 0.589877 0.598198 0.971637 1.904531 1.249959 0.504018) ) ;;; 61 even -------------------------------------------------------------------------------- (vector 61 10.120587847566 (fv 0 0 0 0 0 1 0 0 0 1 1 0 0 1 0 1 0 0 1 1 1 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 1 0 0 0 1 0 1 1 0 0 0 1 1 1 1 1 0 0 1 1) ;; ce: 8.246633 (fv 0.000000 0.014137 0.312612 0.249295 0.935740 0.710600 -0.670222 0.029791 0.000981 1.147441 0.399682 0.888394 1.440126 0.108877 -0.294608 1.403751 1.053458 0.779516 0.066815 1.543587 0.107940 1.359190 1.494404 1.618478 0.815280 -0.244135 0.981345 0.739684 0.088784 1.710138 1.218977 0.672306 0.896304 0.148600 0.266242 0.612315 0.136648 0.136688 0.184375 -0.198309 0.518044 0.411032 1.286324 0.855547 0.828794 0.991646 1.167294 -0.167119 0.070397 0.487614 -0.198225 0.121902 0.696143 0.291992 0.984667 1.799531 0.623251 0.161592 0.779281 0.099176 0.369046) ) ;;; 62 even -------------------------------------------------------------------------------- (vector 62 10.318392753601 (fv 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 1 1 1 1 0 1 0 1 0 1 0 1 0 1 1 0 0 0 0 1 0 1 1 0 1 1 0 1 1 1 1 1 0 0 1 0 1 1 0 0 1 1 0 0 1 1) 8.390962 (fv 0.000000 0.864131 -0.039302 0.501838 0.179590 0.198870 0.408743 -0.099436 -0.035241 1.399095 1.555420 1.066003 1.126029 -0.412606 0.371657 1.690168 1.511157 0.827619 0.057876 1.184261 0.354886 0.869166 0.825315 1.069197 0.055544 0.926747 0.994446 -0.406535 1.243161 1.409918 0.623323 1.296612 0.600545 1.814707 1.913723 0.665613 1.150575 0.642943 -0.000728 0.108004 1.148509 1.338004 0.731747 0.682804 1.190657 0.379742 0.514953 0.586813 0.784946 1.269079 1.453729 1.496418 0.332671 -0.412333 0.644169 0.803815 1.053593 1.563066 0.967726 0.733563 -0.027726 1.710240) ) ;;; 63 even -------------------------------------------------------------------------------- (vector 63 10.45694065094 (fv 0 0 1 0 0 1 0 1 1 0 0 1 1 1 1 1 1 1 1 0 0 0 1 0 0 0 0 0 0 0 1 0 1 0 0 0 1 0 0 1 1 1 0 0 0 0 1 0 1 0 0 1 1 1 0 0 0 0 0 1 1 1 0) 8.413888 (fv 0.000000 0.010634 0.820887 1.791906 0.180821 1.699733 1.457775 1.781040 1.049055 0.063682 0.656198 -0.016519 1.426220 1.490473 0.018505 1.749295 0.166920 0.934178 0.018879 0.949939 1.163838 0.694420 0.665805 0.087679 1.619302 0.169784 1.099805 0.390614 0.230991 0.703447 0.620497 0.345622 1.520041 1.514348 1.626503 0.238228 1.445149 1.071455 0.772257 1.186699 1.488207 -0.090097 0.947955 1.288711 1.143854 0.328539 1.581009 1.516219 1.752145 1.825272 0.656629 1.607807 1.482688 0.741468 0.684282 0.938749 1.078766 0.076298 1.127102 0.768415 0.654765 1.253057 1.466721) ) ;;; 64 even -------------------------------------------------------------------------------- (vector 64 10.487 (fv 0 0 0 0 1 0 1 1 0 0 1 1 1 1 0 0 0 0 1 1 0 1 0 1 0 0 0 1 0 0 1 0 1 0 0 1 1 0 0 0 1 0 1 1 0 1 1 0 0 0 1 0 1 0 0 0 0 0 0 0 1 1 1 1) 8.500897 (fv 0.000000 -0.110230 0.253682 0.149208 0.517156 1.680690 0.261962 -0.311932 1.499119 0.134139 0.193946 1.528316 0.126448 1.680960 0.957330 -0.015272 0.163098 1.233151 0.955877 1.516677 1.271750 0.225924 1.801609 0.924065 0.996478 1.135973 0.892170 1.311436 1.257336 0.314351 0.968388 0.136861 1.841069 1.348391 1.398845 -0.195293 1.345125 1.529238 1.112945 1.363188 0.328366 0.804723 1.816185 1.478898 0.163962 1.500837 0.226838 0.805475 0.515967 0.095385 1.528024 1.274946 0.915048 0.129649 1.022985 1.362093 -0.189345 -0.123957 -0.176055 0.992212 1.710004 0.183155 0.509794 0.492211) ) ;;; 65 even -------------------------------------------------------------------------------- (vector 65 10.593795776367 (fv 0 1 1 1 1 0 0 0 1 1 0 0 0 0 1 1 0 0 0 0 0 1 1 0 1 1 1 1 1 0 1 1 1 1 0 0 0 0 1 0 0 1 1 1 0 1 1 1 0 1 0 1 0 1 1 1 1 1 1 0 1 1 0 1 0) ;; ce: 8.609777 (fv 0.000000 0.010286 0.073308 0.156025 1.953119 0.326605 1.156187 1.359503 0.615092 0.625095 1.209776 1.377583 -0.310622 1.815585 1.618945 0.328652 -0.127781 1.904210 1.297763 1.916187 0.801813 0.929154 1.581967 0.478151 0.556340 1.031862 1.480609 -1.661291 1.218834 0.549647 1.223081 1.263443 0.189207 -0.057436 1.688891 1.890453 1.705454 1.164550 1.023002 0.394890 -0.072758 -0.362543 1.102983 0.220165 0.570828 0.506586 1.236790 0.668284 1.330270 0.072079 0.187084 1.026028 0.423887 1.229321 0.594086 1.447463 0.979393 0.850808 0.463831 1.022159 0.562154 0.740405 1.709952 0.862548 0.909149) ) ;;; 66 even -------------------------------------------------------------------------------- (vector 66 10.77367179842 (fv 0 0 1 1 1 0 1 1 1 0 1 1 0 1 0 0 0 0 0 1 0 1 1 0 0 1 1 0 0 1 1 1 1 0 1 1 1 1 1 0 1 0 1 1 1 1 1 1 0 0 1 0 1 0 1 0 0 1 1 1 1 0 0 1 1 0) ;; ce: 8.678699 (fv 0.000000 0.454997 1.496948 0.519770 1.672039 0.567223 1.755017 0.736664 1.985212 1.381007 0.655920 0.131168 1.193358 0.617219 1.831999 1.143743 0.488405 0.001490 1.636224 1.056726 0.387222 0.101202 1.826852 1.187505 0.710721 0.377670 0.096617 1.812536 1.688958 1.476343 1.264972 1.142558 1.049579 0.690750 1.195534 0.929938 1.522099 1.266451 1.390797 1.538518 1.605610 1.574083 1.889598 0.006801 0.695550 0.832932 1.160944 1.293180 1.683176 0.244325 0.530816 1.180483 1.812767 0.268820 0.993683 1.695534 1.919653 0.449948 1.560150 0.338318 1.266700 1.853107 0.910590 1.381060 0.420174 1.311948) ) ;;; 67 even -------------------------------------------------------------------------------- (vector 67 10.668939590454 (fv 0 1 1 0 0 0 1 0 1 1 1 1 1 1 1 0 0 1 0 1 0 0 0 1 1 1 1 1 0 0 0 0 1 1 0 1 0 0 0 1 0 0 0 1 1 1 1 0 1 1 0 0 1 1 0 1 0 0 1 0 1 0 0 1 0 0 0) ;; ce: 8.715278 (fv 0.000000 -0.048714 1.201233 1.932201 0.432152 1.784378 1.706119 1.715110 0.918127 0.634326 -0.280426 0.736091 0.881233 0.715749 1.255373 0.306961 0.430124 1.043814 0.355900 1.887422 0.161687 0.974683 1.590380 -0.300251 0.580494 -0.035950 1.388432 1.396578 1.262995 0.125471 0.427569 0.132635 1.747845 1.090690 1.059664 0.781885 0.922127 1.269399 0.290961 0.283370 1.543322 0.245179 1.267332 1.559397 1.540498 0.278811 0.442330 0.979302 0.305622 1.057402 0.123531 1.659773 0.687811 0.574242 1.988850 0.928855 0.118304 0.916897 0.064414 0.547707 0.733829 0.168859 0.108897 0.552498 0.271579 0.641458 0.722670) ) ;;; 68 even -------------------------------------------------------------------------------- (vector 68 10.834321813096 (fv 0 1 0 0 0 1 0 0 1 1 0 1 1 0 0 0 0 0 1 0 0 0 0 1 1 0 0 0 0 0 1 0 0 1 0 1 1 1 1 1 1 0 0 0 0 1 1 1 0 0 1 0 0 1 1 1 1 0 1 1 0 0 0 0 1 0 1 0) ;; ce: 8.754943 (fv 0.000000 0.006701 0.662467 1.132456 -0.029127 0.614111 1.150467 1.706479 0.619454 1.199242 1.758840 0.562498 1.597544 0.407921 1.558651 0.097672 0.926756 -0.032275 0.853950 0.002762 0.680777 1.599641 0.725147 0.147702 1.201496 0.263849 1.380478 0.615269 0.086221 1.573333 1.233822 0.463104 -0.134996 1.463347 0.467790 -0.201328 1.692933 1.307865 0.941345 0.423601 0.364303 1.897445 -0.044200 1.168331 0.738828 0.662829 0.834882 0.503840 0.773952 0.485349 0.168198 0.227087 0.122039 0.075266 0.590053 0.402757 0.920519 0.805378 1.169878 1.002493 1.566599 1.933905 0.435730 0.760806 1.023096 1.785992 1.801946 0.257114) ) ;;; 69 even -------------------------------------------------------------------------------- (vector 69 11.164121627808 (fv 0 0 0 1 1 0 1 1 0 0 0 1 0 1 1 1 0 0 0 1 1 1 1 1 1 0 0 0 0 0 1 0 1 1 1 1 1 1 0 1 1 1 1 0 0 1 1 1 0 0 1 0 0 1 0 0 0 1 0 1 0 0 0 0 1 0 0 1 0) 8.870351 (fv 0.000000 -0.002928 0.090043 1.728264 1.193144 0.838010 0.865027 0.720973 0.639322 0.246096 0.057627 0.302959 -0.048089 1.638389 0.900762 0.946630 1.090094 0.801115 1.083281 1.325801 0.953024 0.800047 1.660883 0.042716 1.927302 1.582152 0.107129 0.057190 -0.097633 0.434745 0.530943 1.556013 -0.117080 1.617479 1.566580 -0.082197 0.137002 1.745306 1.025473 1.476477 1.524388 0.192617 1.281951 0.528156 0.227376 1.631586 1.077576 0.616842 1.479500 0.199402 1.336867 0.525138 1.593133 1.323175 0.217188 0.498012 1.287694 0.007842 1.310482 0.013236 0.970642 -0.011247 0.684481 1.560396 -0.131105 0.613388 0.586300 0.981366 1.715362) ;; ce: 8.871460 (fv 0.000000 0.024677 0.348753 1.853212 1.026433 0.764498 0.988619 0.726212 0.717099 0.354110 0.211391 0.453497 0.101716 1.483433 0.914508 0.822283 0.913048 0.815074 1.083064 1.158865 1.024685 0.695931 1.752852 0.025183 1.742985 1.441890 0.242171 0.072208 0.012411 0.538299 0.676243 1.315025 0.155925 1.560315 1.592984 0.078875 0.242794 1.804492 0.950070 1.285093 1.411716 0.049957 1.246246 0.728985 0.030862 1.434432 1.085297 0.759494 1.436818 0.422412 1.268623 0.590795 1.364269 1.235546 0.170900 0.477972 1.127120 -0.054549 1.479098 0.172668 1.199653 -0.107230 0.674735 1.486658 -0.230242 0.542693 0.703829 0.966900 1.458811) ) ;;; 70 even -------------------------------------------------------------------------------- (vector 70 11.188811302185 (fv 0 1 1 1 0 0 1 0 0 1 0 1 0 1 0 1 1 0 0 1 1 1 0 0 0 1 1 0 0 0 1 0 1 1 1 1 0 0 1 0 0 0 0 0 0 0 1 1 1 0 1 1 1 0 1 1 0 1 1 1 1 1 1 1 0 0 1 0 1 1) ;; ce: 8.848811 (fv 0.000000 0.246703 1.002261 0.886061 0.801873 1.809738 1.108544 0.562043 1.825392 1.804522 1.262385 0.421389 0.361557 1.923401 1.951742 1.062427 0.438003 0.228289 1.097160 1.013865 0.764041 0.470243 0.831289 0.101425 1.763202 0.709481 0.498799 0.216191 0.861166 0.122620 0.547738 1.235046 0.857238 0.383439 0.822746 0.754977 0.703208 0.715041 0.359010 1.832044 0.247507 1.317151 1.405217 0.206638 0.707472 1.340219 1.707159 1.823029 1.938700 1.479437 0.258261 1.667534 0.316971 1.157956 1.277369 0.826722 1.196822 0.248386 0.546752 1.821030 1.066474 1.952221 1.238401 0.305398 0.369743 0.877722 1.232005 1.532682 1.629962 0.062770) ) ;;; 71 even -------------------------------------------------------------------------------- (vector 71 11.146488189697 (fv 0 1 1 1 0 1 0 1 0 1 0 0 0 1 0 0 1 0 1 1 0 0 1 0 0 0 1 1 1 1 1 0 1 1 1 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 1 1 0 1 1 0 1 0 0 0 0 1 1 1 1 0 0 0 1 1 0) ;; ce: 8.877033 (fv 0.000000 0.494925 1.537244 0.892084 0.150008 1.375283 0.111396 0.180070 1.039621 1.603551 0.974071 0.067462 1.566530 0.645476 1.559374 0.286202 1.250076 1.040362 0.597158 0.170031 1.495084 0.538551 1.605790 0.911462 0.561795 0.131327 0.669920 1.494711 1.488338 0.162432 0.349959 1.071758 0.876821 1.835299 1.877472 1.338427 1.055237 0.961547 0.343936 0.685277 1.268629 0.932565 0.412531 1.233930 1.960684 0.356135 1.869394 1.068031 1.470058 1.669216 1.450884 1.495861 1.103585 1.290131 0.589390 1.675751 1.864756 1.328404 1.588855 1.689588 1.394915 1.481997 1.790524 0.376533 0.659979 0.194369 0.714680 1.009374 1.293563 1.133522 0.906132) ) ;;; 72 even -------------------------------------------------------------------------------- (vector 72 11.323646371629 (fv 0 0 1 0 1 0 1 1 0 1 0 1 1 1 1 1 0 1 1 0 0 0 1 0 1 1 0 1 0 0 1 1 0 0 0 0 0 0 1 0 0 1 1 0 0 0 1 1 1 1 0 1 1 1 0 1 0 1 0 0 1 1 0 0 0 0 1 1 1 1 1 0) 8.985526 (fv 0.000000 -0.132001 0.251840 -0.152367 1.238134 0.223104 0.102612 0.998567 1.283059 0.195894 1.573363 0.407537 1.033361 -0.202081 0.593147 0.635495 1.000647 1.220151 0.876169 0.891935 0.590452 0.848621 0.474219 0.520369 1.077034 0.562333 1.205154 1.187120 1.031050 1.268084 0.666333 -0.432529 0.483326 0.764356 0.428610 0.084679 1.685196 -0.154809 0.749260 1.099715 -0.153921 1.175926 0.117589 0.701530 0.528397 1.669792 1.315998 0.695987 0.047259 0.736352 1.073555 1.525504 1.860608 -0.168018 1.587814 -0.029717 0.367471 1.076978 0.934753 0.510954 0.369425 1.530708 0.338598 0.869566 1.012951 0.841118 0.372289 1.598627 0.202786 1.450618 0.578685 0.231358) ;; nce: 8.996610 (fv 0.000000 0.020435 0.148826 -0.173981 1.377729 0.211130 0.166992 1.053622 1.458337 0.005572 1.576161 0.391690 1.074146 -0.213327 0.588223 0.422230 0.994634 1.149413 0.858889 0.855458 0.451324 0.722371 0.451607 0.485779 1.099748 0.481778 1.183724 1.119200 0.986503 1.262651 0.778215 -0.493824 0.577630 0.838272 0.526378 0.254738 1.698601 -0.156321 0.698602 1.048110 -0.140804 0.991469 0.138073 0.652727 0.457506 1.770023 1.311357 0.782250 0.170414 0.740584 1.195615 1.519642 1.761376 -0.154135 1.542454 -0.027224 0.389381 1.045008 1.107881 0.609081 0.244277 1.495852 0.294775 0.922470 1.153689 1.027914 0.296649 1.621186 0.277016 1.409256 0.557607 0.152023) ) ;;; 73 even -------------------------------------------------------------------------------- (vector 73 11.416394233704 (fv 0 0 0 0 0 1 0 0 1 0 0 1 0 0 0 0 0 0 1 1 0 0 1 0 0 1 0 0 1 1 1 0 0 0 1 1 0 1 1 0 1 1 1 0 0 0 0 0 0 1 1 0 1 0 1 0 1 0 1 1 0 0 0 1 0 1 0 1 1 0 0 0 0) ;; ce: 9.061347 (fv 0.000000 -0.013492 0.700057 0.971458 1.656489 0.226217 1.266397 1.217251 0.034107 1.132703 0.209805 0.859555 1.676063 0.359664 0.948491 1.631395 0.566735 1.564253 0.503600 1.614448 0.423074 1.551405 0.311534 1.292368 0.836304 0.277624 0.872873 0.108697 1.546043 0.974228 -0.054286 1.516659 0.873622 0.075543 -0.025545 1.027508 0.575666 -0.130582 1.023997 1.136740 0.704834 -0.015132 -0.346526 1.509690 1.112218 0.655940 0.431045 0.092523 0.384582 -0.406961 0.058570 -0.216957 1.536312 1.587308 1.645182 1.277358 1.546578 1.141387 -0.381783 1.707248 -0.163708 -0.313272 -0.263055 0.347717 0.363093 0.778459 1.216671 1.669453 -0.038813 0.148398 0.866038 0.847643 1.513063) ) ;;; 74 even -------------------------------------------------------------------------------- (vector 74 11.47264289856 (fv 0 0 0 1 0 0 0 0 1 1 0 0 1 1 0 1 1 1 0 0 0 1 0 0 0 1 0 1 0 1 1 1 1 0 0 0 0 1 0 0 1 1 1 1 1 0 1 0 0 1 0 1 0 0 0 1 0 0 0 0 0 0 1 0 0 0 1 1 0 1 1 0 1 1) ;; ce: 9.134480 (fv 0.000000 0.102279 0.371397 0.523001 1.843248 1.152941 1.651341 1.411384 0.791794 0.097952 1.057024 0.161099 0.857363 0.427397 0.372120 0.661194 1.523876 0.922082 -0.041073 -0.033604 0.996743 1.697191 1.295880 0.242720 0.296660 0.925120 0.229105 1.701968 1.808512 0.155026 0.755549 1.603330 1.534401 1.305218 1.056671 1.959110 0.012243 0.095634 0.866653 0.499791 0.642664 1.366362 0.320578 0.556112 0.471836 0.546071 0.453257 0.620145 0.487633 1.413108 0.647644 1.248023 1.294495 1.814325 0.514274 1.440895 0.132821 0.969503 0.559010 0.339598 1.732485 1.513938 0.682886 0.936970 1.342790 0.397470 0.364797 1.929409 1.198862 0.270546 1.048858 1.252852 0.860205 0.013479) ) ;;; 75 even -------------------------------------------------------------------------------- (vector 75 11.479255355845 (fv 0 0 1 1 0 0 1 1 1 1 1 0 1 0 0 0 1 1 1 1 1 1 1 0 0 0 1 0 0 1 0 1 0 1 0 0 1 0 1 0 0 0 0 0 1 0 0 0 0 1 1 1 0 0 1 1 0 1 1 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 1) ;; ce: 9.136718 (fv 0.000000 0.002886 1.335455 0.159358 1.480181 0.946385 -0.044639 1.084031 0.633473 0.070872 0.846110 0.073920 0.712875 1.849807 0.002049 1.333644 0.084510 1.217578 1.455838 0.351015 0.583697 1.521673 -0.105875 -0.161704 1.008277 1.067855 -0.227255 1.066234 0.968179 0.069816 1.652420 0.515209 -0.583628 1.701274 1.644474 0.045597 -0.072256 1.396842 -0.036343 1.242335 0.205214 -0.046339 1.655176 1.585631 1.056865 0.812824 1.251896 1.501857 -0.501015 0.327372 1.079894 1.360106 0.639144 -0.102077 0.025865 0.258537 0.650404 0.029251 0.316419 1.073801 1.065871 0.953311 0.976263 -0.016818 0.369518 -0.028524 0.754304 0.267168 0.876021 1.386930 1.128217 -0.044803 -0.305853 1.417010 1.210349) ) ;;; 76 even -------------------------------------------------------------------------------- (vector 76 11.477294510597 (fv 0 0 1 0 1 0 1 0 0 1 0 0 1 1 0 0 0 0 0 1 1 1 0 1 0 1 0 0 1 0 1 1 1 0 1 1 1 0 0 1 1 1 1 1 1 0 0 1 1 1 1 0 0 1 0 0 0 1 0 1 0 1 1 1 1 1 0 1 1 0 0 0 0 1 1 1) ;; ce: 9.274323 (fv 0.000000 -0.012165 1.750183 1.230595 1.387108 0.131448 0.902665 1.325819 0.139220 0.132421 1.315838 0.916320 1.247629 1.543004 0.326242 0.479315 1.525889 1.714627 0.992625 1.849378 1.028201 1.309429 1.365818 1.322280 1.222257 1.381076 1.644593 0.773733 0.614835 0.306624 1.009114 1.162734 0.610055 0.099066 1.125761 1.356329 0.324777 0.800340 1.850117 0.710340 0.610191 0.810114 1.107918 1.417728 -0.023776 1.259738 0.196765 1.355631 1.575090 1.576385 1.741085 1.748236 0.050375 1.081011 0.178534 1.097122 0.438057 -0.170346 1.371443 0.019537 1.307599 0.833238 0.430491 0.202986 1.382655 1.791419 0.002565 0.061873 0.176928 1.554826 0.852820 1.065814 0.297645 0.742549 0.387652 1.429885) ) ;;; 77 even -------------------------------------------------------------------------------- (vector 77 11.594018936157 (fv 0 1 0 1 1 1 1 1 0 1 0 0 1 1 1 0 0 0 1 0 1 0 1 1 1 0 1 0 1 0 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 0 1 1 0 1 0 1 1 0 1 1 0 0 1 1 0 0 1 0 1 0 0 0 0 1 0 0 0 0 0 0 1) ;; ce: 9.277681 (fv 0.000000 -0.007935 0.356695 -0.167840 1.436050 1.267495 0.166108 0.719740 1.788089 0.701383 1.502062 0.971109 -0.201146 1.261312 1.596232 0.380082 0.436900 1.530759 0.673592 1.168750 0.815135 1.757429 0.573966 1.406748 1.792933 1.256151 0.643583 0.884960 0.868508 0.759790 1.464002 -0.196244 0.635729 1.419530 -0.026848 0.857441 0.646295 0.815860 0.331225 0.324537 0.379771 0.793029 -0.189194 0.533286 0.175986 1.162021 0.894997 1.330799 0.028604 0.329088 -0.042751 1.722552 1.010170 0.365295 -0.089972 0.186813 0.250172 1.045796 0.805669 1.150679 1.074682 0.666765 1.119179 0.223717 0.745979 0.727191 0.250299 1.103832 0.833082 -0.215344 1.645081 0.897326 0.690160 1.501085 1.581868 1.570534 1.086810) ) ;;; 78 even -------------------------------------------------------------------------------- (vector 78 11.940728787203 (fv 0 1 0 0 1 1 0 1 1 1 0 1 0 0 1 0 1 1 0 0 0 1 0 1 0 0 0 0 1 1 1 0 1 0 0 1 1 0 1 0 0 1 1 1 0 0 1 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 1 1 0 0 0 0 1 0 1 1 1 1 1 0 0) 9.335941 (fv 0.000000 1.404748 1.136727 0.627680 0.129528 0.271686 0.002711 1.737837 1.295987 1.387168 0.097658 1.822832 0.846464 1.039100 1.481322 0.895294 0.827592 0.841157 0.429643 0.718521 1.651578 0.732848 0.670593 1.833752 0.966314 1.266799 1.852734 1.169793 1.403542 0.722295 1.054728 1.444480 1.323054 1.351419 0.414445 0.928183 1.497407 0.895056 0.003473 1.202042 1.804296 0.448756 1.139768 0.075452 1.121542 0.477216 1.723231 0.402648 0.668323 0.045598 1.846940 0.961710 0.765295 1.814929 0.327072 0.120487 1.324670 1.238079 1.405578 -0.005216 1.466365 1.535268 1.050547 0.249219 1.956711 0.420435 0.291291 0.855796 1.032224 0.874733 1.340034 0.852331 1.473861 1.078790 -0.021411 0.624891 0.620475 1.381664) ) ;;; 79 even -------------------------------------------------------------------------------- (vector 79 11.878196632448 (fv 0 0 1 1 0 1 0 0 1 0 0 1 1 0 1 0 0 1 1 1 0 0 1 1 1 1 0 0 1 0 1 0 0 0 1 1 0 1 0 0 0 1 1 1 0 1 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 1 1 0 0 1 0 0 0 0 1 1 1) ;; ce: 9.380733 (fv 0.000000 0.510780 0.252633 0.712748 0.045825 0.533290 0.570911 1.782693 1.778269 1.965545 0.949265 0.812889 1.687090 1.664308 1.581407 1.710616 0.952117 1.113251 0.535130 1.949191 0.392710 1.113892 0.673455 0.088774 1.234594 1.234700 1.363303 0.874218 0.053582 1.508928 0.207664 0.009853 1.481504 1.794166 0.192648 0.693227 0.386323 1.341036 0.276027 0.630139 0.405686 0.785949 0.090167 1.080676 0.339556 0.634603 1.972094 0.909674 0.642872 1.742555 1.044458 1.900464 0.893867 1.044986 0.466092 0.081355 1.748407 0.417739 0.609777 0.867444 0.996078 1.921822 0.146017 1.547350 1.786775 0.079134 0.379049 1.145195 0.491146 0.827840 1.444544 0.381774 1.018247 0.133450 0.186735 0.732527 1.660451 1.720421 1.438682) ) ;;; 80 even -------------------------------------------------------------------------------- (vector 80 11.989325523376 (fv 0 1 0 0 1 0 0 1 1 0 1 0 0 1 1 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 0 1 0 1 1 0 1 0 1 0 1 0 1 0 0 0 0 1 1 0 0 1 1 1 1 0 1 1 0 1 0 1 1 0 0 0 0) ;; ce: 9.493437 (fv 0.000000 -0.003056 0.871305 1.349319 1.858308 0.466908 1.244422 1.764043 0.291426 1.076281 1.682758 0.386304 1.182056 -0.041504 1.018049 1.794160 0.591085 1.410404 0.075268 1.154361 0.262047 1.215494 0.086813 1.119384 0.112085 1.492482 0.546321 1.626715 0.687674 1.840924 1.113879 0.412411 1.693842 1.217772 0.566191 1.613902 0.702693 0.386708 1.626693 1.362021 0.738932 0.368846 1.672871 1.299617 0.788427 0.551598 0.187991 1.803477 1.774821 1.164009 1.487614 0.770019 0.742630 0.390398 -0.088422 1.923288 -0.109062 1.842146 1.690251 0.008381 1.550824 1.531659 1.497616 1.396079 1.603050 1.793260 0.154336 0.252178 0.425516 0.421130 0.697112 0.901699 1.252555 0.016759 0.375241 0.855613 1.211546 1.433945 1.792863 0.351953) ) ;;; 81 even -------------------------------------------------------------------------------- (vector 81 11.979215621948 (fv 0 0 1 0 1 0 1 1 0 0 1 0 0 0 0 0 1 0 0 1 0 0 0 0 1 0 1 0 1 0 0 0 1 1 1 1 1 1 0 1 1 1 1 1 0 1 0 0 1 0 0 1 1 0 0 0 1 1 1 0 0 0 1 1 1 1 1 1 1 0 0 1 0 0 0 1 1 1 1 1 0) ;; ce: 9.529325 (fv 0.000000 -0.003984 0.725186 0.743737 0.729531 1.119765 1.541925 1.678935 1.738481 1.721543 1.393185 0.731045 0.019478 0.771584 0.581855 0.216656 0.563399 1.242114 0.560651 1.738359 1.170491 0.159270 0.566126 0.483569 1.182790 0.181604 1.706151 1.854339 -0.002194 0.437844 -0.070207 1.440872 0.286463 1.398996 1.367061 0.708028 -0.290957 0.883528 0.399205 0.712176 0.881360 0.586332 1.691690 -0.045439 0.598789 -0.244443 0.663603 1.393152 0.011936 0.502973 1.160110 0.596199 0.257846 0.544341 0.629333 1.752684 0.177491 0.528429 1.038556 0.728481 0.384225 0.529890 0.711236 1.400194 1.498453 1.156244 0.653763 0.305758 -0.155269 1.073363 1.458379 0.702870 0.141716 1.302726 -0.329814 0.298639 1.892688 1.900138 1.655169 0.812034 -0.182220) ) ;;; 82 even -------------------------------------------------------------------------------- (vector 82 11.74796962738 (fv 0 0 0 0 0 0 1 1 1 0 0 1 1 0 1 1 0 0 1 0 1 1 1 1 1 0 0 1 0 0 0 1 0 0 0 0 0 1 1 0 1 1 1 1 0 0 0 0 1 1 0 1 1 1 0 0 1 1 1 1 0 1 1 1 1 0 1 0 0 1 1 1 0 0 0 1 1 0 1 0 1 0) ;; ce: 9.530985 (fv 0.000000 0.002581 0.665465 1.069477 1.708629 0.244744 0.815275 1.389506 0.072967 0.518149 1.258636 0.104869 0.672550 1.578904 0.486254 1.275378 -0.016236 0.797153 -0.276393 0.747043 -0.159462 0.727529 0.109229 1.313965 0.107559 1.101244 0.135391 1.229652 0.386704 1.699152 0.875100 0.220480 1.674529 0.566929 1.803565 1.281089 0.420527 -0.095373 1.451514 0.833105 0.334393 1.926106 1.521915 0.797742 0.037620 1.890450 1.238469 1.288596 0.773237 0.606049 0.213821 0.049140 1.607755 1.437666 0.833194 0.946550 0.684670 0.626164 0.630512 0.902897 0.480081 0.471365 0.308602 0.413372 0.258949 0.442607 0.453613 0.854111 1.173261 1.257079 1.135118 1.379336 1.476222 -0.234240 0.311478 0.480664 1.015136 1.521091 1.852304 0.056526 0.425563 0.785949) ) ;;; 83 even -------------------------------------------------------------------------------- (vector 83 11.931811297539 (fv 0 0 1 1 0 1 1 0 0 1 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 1 1 1 0 0 0 0 0 0 0 1 0 0 1 1 1 1 1 1 1 0 0 0 0 1 1 1 0 0 1 0 1 1 0 0 0 1 1 0 0 0 1 0 1 0 1 1 0 0 1) ;; ce: 9.549360 (fv 0.000000 0.032288 0.834116 1.401416 0.035368 0.406563 1.177626 1.509613 0.291626 0.972552 1.726763 0.692721 1.687201 0.129594 1.085873 0.204017 1.139515 0.273445 1.482102 0.192295 1.080179 1.979882 1.285941 0.340403 0.985304 0.533609 1.865099 0.628799 1.889210 1.180384 0.539244 1.842377 1.350512 0.512399 1.815213 1.164340 0.726996 -0.012813 1.099275 1.226281 0.551613 0.011231 1.538277 1.191883 0.928674 0.507861 1.826344 1.417654 1.468918 1.265287 0.819366 0.969679 0.428274 0.455249 1.949916 0.041645 1.591382 1.883937 1.784338 1.762163 1.899526 1.307740 1.800619 1.929764 0.063585 1.701620 1.807254 0.159705 0.531560 0.710036 1.009902 1.081386 1.423742 1.377653 1.714397 0.170534 0.667428 1.526663 1.444085 1.827303 0.046079 0.991518 1.278845) ) ;;; 84 even -------------------------------------------------------------------------------- (vector 84 12.426499838032 (fv 0 0 1 1 0 0 0 0 0 1 0 1 1 1 1 1 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 1 1 0 0 0 1 1 1 1 0 0 0 0 1 1 0 1 1 0 0 1 1 1 0 0 1 0 0 1 0 1 0 1 1 0 1 0 1 0 1 0 0 0 1 0 0 0 0 1 1 0 0) ;; ce: 9.633962 (fv 0.000000 0.374922 1.183581 1.290870 0.705975 0.037122 1.139367 1.048350 0.334310 1.326801 1.647856 1.857607 1.812109 0.301068 1.658406 1.344389 0.416349 0.219667 1.233884 1.040486 1.625160 1.657982 1.232289 1.436356 0.879314 1.500837 0.083989 0.524445 1.496583 0.195492 0.415250 0.867702 1.173743 1.828747 1.840334 -0.001715 0.114874 1.289221 0.907468 1.568406 0.412257 0.461669 1.993995 0.175480 1.741500 1.629849 1.860704 1.739722 1.644034 1.223183 0.177672 0.444348 1.320675 1.200379 1.245918 0.030713 1.304971 1.969297 1.489901 0.864880 0.577011 0.034043 1.934323 1.447131 0.730445 1.571480 0.003554 0.387041 0.486597 1.351900 0.594794 1.157107 0.726867 1.857734 0.748709 1.799335 1.043537 0.919611 0.874828 0.732255 1.153375 1.608544 0.740331 1.571952) ) ;;; 85 even -------------------------------------------------------------------------------- (vector 85 12.270205061432 (fv 0 0 1 0 1 1 1 1 0 0 0 1 1 1 1 1 0 0 1 0 1 1 0 0 1 1 0 1 0 1 1 0 0 0 0 0 0 1 0 0 1 0 1 0 1 1 0 0 1 1 0 0 0 0 0 0 0 1 1 1 1 0 1 1 0 0 1 0 1 1 1 1 0 0 1 0 1 0 0 0 1 0 0 0 1) 9.693668 (fv 0.000000 0.195989 0.490949 0.331600 0.887562 0.028445 1.546017 1.385311 0.812190 1.115113 1.801497 0.487288 0.525794 0.074082 1.723182 1.944316 1.781964 0.421600 0.177518 1.829367 0.571078 1.783004 0.344177 0.329133 1.891108 0.440324 0.259558 0.143603 0.779362 1.104207 1.976902 0.561742 0.767039 1.340228 0.253563 1.774888 1.741378 1.554241 1.474673 0.298807 0.272176 1.211675 1.002346 0.130871 1.176937 0.697418 0.199450 0.178715 1.330092 0.855241 1.512332 1.331159 0.219055 1.811575 1.934102 1.939888 1.043996 0.748687 0.643521 0.780509 1.267694 0.441215 0.667193 0.454905 1.688291 1.972173 0.503377 0.756581 0.239100 0.784029 1.470486 0.189182 1.795940 0.379978 1.569889 1.093199 1.711138 0.905143 0.045022 0.285289 1.219061 0.953496 1.196694 1.742789 0.902060) ;; nce: 9.690941 (fv 0.000000 -0.005460 0.145938 -0.187800 0.177698 1.176520 0.517469 0.210175 1.436686 1.607383 0.066090 0.593136 0.482635 1.868920 1.291310 1.386910 1.029893 1.540100 1.084274 0.614905 1.153312 0.206651 0.588776 0.424148 1.780700 0.201677 -0.148794 1.539105 1.959298 0.153524 0.855868 1.263643 1.287920 -0.293735 0.438019 -0.206018 -0.356273 1.231052 1.001435 1.635849 1.476715 0.216231 -0.158631 0.753539 1.686606 0.980832 0.355756 0.168014 1.126044 0.500388 0.943877 0.638970 1.307633 0.790226 0.733504 0.595806 1.464991 1.037472 0.754676 0.719213 1.040414 0.002877 0.074104 1.737856 0.729741 0.862345 1.242108 1.321487 0.621750 1.011073 1.510125 0.085724 1.514690 -0.060524 0.938871 0.309540 0.743320 -0.211769 0.753436 0.803987 1.556267 1.083936 1.193072 1.598509 0.578392) ) ;;; 86 even -------------------------------------------------------------------------------- (vector 86 12.791990425787 (fv 0 0 1 1 0 0 1 0 1 1 1 0 1 1 0 0 0 0 0 1 0 0 0 1 0 1 0 1 0 1 0 1 1 0 1 0 0 0 1 0 0 1 0 1 0 0 1 0 0 1 1 0 0 0 1 0 0 0 1 1 1 1 1 1 0 0 0 0 1 0 0 1 0 0 0 1 1 0 0 0 0 1 1 1 0 0) 9.804520 (fv 0.000000 0.137494 0.326172 0.010382 1.487613 0.505001 1.228062 0.954717 -0.127893 -0.290666 0.636565 1.325872 1.732483 0.567284 1.353499 0.704440 1.806655 1.469223 0.382393 0.706107 0.545460 0.307640 1.039546 0.875080 1.787391 0.105900 0.639604 0.989302 -0.045857 1.717167 1.835064 1.163334 0.033557 1.525348 0.510815 0.463389 0.777198 0.612036 1.665125 1.493136 0.475659 1.095674 1.296538 1.117478 0.603294 1.233039 0.344624 0.414746 0.337889 1.713708 0.141791 0.820548 1.699043 0.899800 0.803706 0.771637 1.413475 1.319088 1.268258 0.265658 0.770528 0.659195 0.900807 0.683986 1.290180 0.800356 1.418815 1.036184 1.201710 0.337696 1.582663 1.435772 0.606855 1.068190 0.540979 1.320205 -0.195129 0.714820 0.387530 0.040243 0.270436 -0.038662 1.702501 0.563408 0.676006 0.165316) ;; nce: 9.779022 (fv 0.000000 0.012842 0.387371 0.019737 1.439011 0.434664 1.128389 0.730743 -0.150815 -0.440514 0.639771 1.390058 1.794981 0.621810 1.311431 0.767684 1.625416 1.570273 0.387894 0.736564 0.474233 0.261823 1.118332 0.820501 1.669010 0.015560 0.675733 0.978312 -0.064261 1.739844 1.817488 1.131007 0.062688 1.453390 0.448140 0.394070 0.831458 0.606366 1.363181 1.537589 0.426586 0.909340 1.240040 0.972834 0.683746 1.305881 0.259400 0.331948 0.295699 1.578329 0.042939 0.918607 1.689154 0.940724 1.007722 0.753380 1.536736 1.334795 1.258278 0.206096 0.883227 0.623082 0.840214 0.596829 1.277982 0.836896 1.407813 0.924493 1.193604 0.465208 1.513477 1.273116 0.679902 0.975579 0.664944 1.360910 -0.287799 0.710949 0.308010 -0.006577 0.020520 -0.156639 1.682660 0.621205 0.561199 0.080346) ) ;;; 87 even -------------------------------------------------------------------------------- (vector 87 12.625063286678 (fv 0 0 0 1 1 1 1 0 1 0 1 0 1 0 0 0 1 0 0 0 1 0 1 0 1 1 0 0 0 1 1 1 1 1 1 0 0 1 1 1 0 1 1 0 1 1 0 0 1 0 1 1 1 0 1 1 0 1 1 1 0 1 0 0 0 0 1 0 1 1 1 0 0 1 1 0 0 0 0 1 0 0 1 0 1 1 0) 9.874660 (fv 0.000000 0.366900 0.585885 0.360276 1.741378 1.383744 0.806085 0.218985 1.748601 1.513484 1.913086 1.499231 1.804617 1.560415 0.976184 0.564077 0.614555 0.706893 1.155782 1.743949 0.256106 1.587276 1.479629 0.499900 0.621596 1.318438 0.505053 -0.000351 1.493931 0.351932 1.677582 1.117619 1.631442 0.001969 0.286212 0.372264 0.187053 0.296894 0.961309 0.849648 1.557109 1.714474 -0.039206 1.347988 1.896634 1.217858 1.504538 0.380552 0.871895 1.911392 0.768943 1.752782 0.535064 0.764217 0.468880 0.181130 0.490835 1.212121 1.451975 1.107304 0.551132 0.225217 0.930971 0.652946 1.821236 0.839189 1.745456 0.283826 1.910401 1.397382 1.626785 0.236815 0.165723 1.103589 1.501862 1.903299 0.205800 0.189795 0.285228 0.129502 1.654212 0.651262 -0.043737 0.438462 1.813853 0.852642 1.712123) ;; nce: 9.877641 (fv 0.000000 -0.021457 -0.332767 0.963844 -0.139669 1.122611 0.073163 0.865822 -0.025982 1.478876 1.300682 0.423658 0.322274 1.661211 0.500543 1.705512 1.176402 0.809437 0.981075 0.972708 1.087640 1.788381 1.486099 1.855937 1.496729 1.909818 0.429000 1.696291 0.561926 0.965567 -0.162109 0.839848 1.033495 0.899864 0.728978 0.135257 1.630992 1.197929 1.514698 0.814714 1.165293 0.851600 0.892043 1.519176 1.529996 0.381556 0.396698 0.783215 0.824621 1.214567 1.738938 0.263930 0.560204 0.335777 1.558427 0.771167 0.709316 1.002333 0.687389 -0.031156 0.967435 0.220860 0.392729 1.627417 0.223702 0.908693 1.299159 1.409401 0.619154 1.469733 -0.654637 1.678656 0.999708 1.410546 1.423816 1.288829 1.153651 0.643357 0.343990 1.755018 0.782145 1.521746 0.184384 0.116670 1.179413 -0.365261 0.035182) ) ;;; 88 even -------------------------------------------------------------------------------- (vector 88 12.661032846106 (fv 0 0 0 1 1 1 1 1 0 0 1 0 1 0 1 0 0 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 0 1 1 1 1 0 1 0 1 0 0 0 0 0 1 0 1 0 1 1 1 0 1 1 0 1 0 0 1 0 1 1 0 0 1 1 1 0 0 0 1 1 0 1 1 1 0 1 0 0 0 0 0 1 1 1) ;; ce: 9.812216 (fv 0.000000 0.055268 0.583779 1.234211 1.628798 0.277023 0.822779 1.625146 0.035507 0.649602 1.426919 0.034524 0.760555 1.584090 0.426236 1.297108 -0.064648 1.003285 1.954848 1.040940 1.931089 0.684474 1.457006 0.442932 1.400956 0.522371 1.821243 1.045778 -0.071524 1.059165 0.175444 1.376515 0.683418 0.093932 0.976929 0.065328 1.602577 1.185163 0.398809 1.873751 1.266959 0.334189 1.528861 1.254369 0.874420 0.121432 1.565807 1.331351 0.966676 0.377764 -0.254628 1.470234 1.160191 1.088192 0.680440 0.787715 0.046065 0.265716 -0.241611 1.809516 1.268665 1.177712 1.068293 0.934673 1.317512 0.907560 0.977837 0.781524 0.997530 0.958638 1.010309 1.152240 1.559668 1.510870 1.793541 0.022384 -0.034413 0.066685 0.419014 0.865510 1.381137 1.729658 1.950350 0.466719 0.747652 1.418392 1.765101 -0.161755) ) ;;; 89 even -------------------------------------------------------------------------------- (vector 89 12.335865540187 (fv 0 0 1 1 0 1 1 1 1 0 0 1 1 1 1 0 0 0 1 1 1 0 1 1 1 0 0 0 1 1 0 0 1 1 0 1 0 0 0 0 0 0 0 0 0 1 0 1 1 1 0 0 1 1 0 1 0 1 1 0 1 0 0 0 0 1 1 1 0 1 0 1 0 1 0 0 1 0 0 1 1 0 0 1 1 1 1 1 1) ;; ce: 9.997916 (fv 0.000000 0.020244 0.870163 0.459782 1.610176 0.844000 1.631839 0.198513 0.309236 0.389591 1.266554 0.907717 1.601376 1.371297 1.457522 1.745042 1.476212 0.073975 0.814060 0.353740 0.627872 0.101452 1.077167 0.352892 0.063779 0.448255 0.216020 0.534427 1.535778 -0.255643 1.360537 0.276814 0.262932 1.399548 0.980210 0.702925 0.453704 0.501694 1.341730 0.007203 0.345436 0.837214 0.770776 -0.073243 0.532634 1.583256 0.698601 0.593928 1.599304 0.808070 1.440125 1.148274 0.114072 0.434799 -0.164129 1.193330 -0.269745 0.418138 1.192504 1.289901 0.986576 0.905136 0.005956 1.233570 1.751871 1.723660 1.197839 1.205999 1.118756 1.106261 1.003380 0.216161 0.037880 0.928786 0.755785 -0.278629 0.531970 0.188018 0.465858 1.197436 0.572455 1.090538 1.091674 0.532343 0.511453 1.688563 1.590718 0.571898 1.255870) ) ;;; 90 even -------------------------------------------------------------------------------- (vector 90 12.716424196959 (fv 0 1 1 0 1 1 0 0 0 1 1 1 1 0 1 1 1 0 1 1 1 1 1 1 0 1 1 1 1 0 0 1 1 1 1 0 0 0 0 0 0 1 1 0 1 0 0 1 1 1 1 1 1 1 0 0 1 0 0 1 0 1 1 0 1 0 0 1 1 0 0 1 1 0 1 0 1 0 0 0 1 0 0 0 1 1 1 1 1 0) ;; ce: 10.013305 (fv 0.000000 0.276249 0.662327 1.808806 0.247081 1.503786 1.940324 0.419803 0.731998 1.474410 1.308170 1.676869 1.811609 1.215798 0.664610 0.066241 0.912393 1.461826 0.512334 1.631743 1.956766 1.975237 0.185753 0.741305 0.480828 1.966454 1.916940 1.119423 0.845500 1.620533 0.975449 0.450183 0.934883 1.109333 0.667354 1.305384 1.605133 1.189882 1.538095 1.240075 1.975310 0.162522 1.100171 1.036777 1.043788 0.744032 1.593875 0.517982 0.225081 0.407155 1.741456 1.796412 1.700950 0.367751 0.443832 0.733427 0.886793 0.217138 0.457578 1.931221 1.821137 1.223426 0.206884 1.785700 -0.026139 0.112791 0.288549 1.184345 0.406919 0.005051 0.510070 1.732554 1.458011 0.524459 1.130913 0.434368 0.819466 0.015795 0.021375 1.211968 0.985111 0.213416 0.003383 0.752814 1.988526 0.349626 0.383655 1.548554 0.699363 -0.001079) ) ;;; 91 even -------------------------------------------------------------------------------- (vector 91 12.853587071592 (fv 0 0 0 1 1 0 0 1 0 0 1 1 1 0 1 1 0 0 0 0 0 0 0 0 1 0 1 1 0 1 1 1 0 1 0 0 1 1 1 0 1 0 1 1 1 1 1 0 0 1 0 1 1 1 1 0 0 1 0 1 0 0 1 1 1 0 0 1 0 0 1 1 1 1 1 0 1 1 1 0 1 1 1 0 1 0 1 1 1 0 0) ;; ce: 10.062777 (fv 0.000000 -0.044026 0.916183 1.049904 0.191738 0.191234 1.416236 1.067714 0.063138 1.147303 0.129837 0.429350 1.643604 1.587481 1.357034 0.252125 0.130779 1.268840 1.505767 0.040246 0.758000 0.845409 1.205711 0.041467 0.397400 0.371419 1.129085 1.761538 0.418123 -0.386013 -0.020991 1.418674 -0.227521 0.262381 1.257327 0.247702 0.200474 1.000030 0.059835 0.524653 0.278663 0.930707 1.291316 0.903105 1.153153 1.399218 1.175091 1.040190 0.853009 0.848960 0.050279 1.156146 0.310675 1.870226 0.711775 0.475029 1.761660 0.754317 0.936989 -0.122427 1.219572 0.099878 0.730317 0.306957 0.685890 1.871434 1.660611 0.509309 0.546923 0.432379 0.751420 0.579102 -0.249566 -0.007122 1.880100 1.723260 0.707224 -0.253994 0.741449 0.308553 0.722662 0.266964 1.454100 1.331867 1.250657 0.301803 0.242062 0.553976 0.852613 0.695715 0.487374) ) ;;; 92 even -------------------------------------------------------------------------------- (vector 92 12.754180011349 (fv 0 1 1 1 0 0 1 1 0 1 1 0 1 1 0 1 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 1 1 1 1 1 0 1 1 1 1 1 1 0 1 1 1 0 1 0 0 1 1 1 0 1 1 0 0 1 1 1 1 1 0 0 0 1 0 0 0 0 1 0 0 1 1 1 1 1 1 1 0 0 0 1 1 0 1 1 1 0) ;; ce: 10.123598 (fv 0.000000 0.031164 0.420530 1.499100 1.680395 0.704037 1.385766 1.730884 1.246618 0.630183 0.903224 0.818406 1.762884 0.926615 1.036829 0.514947 1.139487 1.191198 0.306323 0.126221 1.698783 1.815556 0.082954 0.421957 1.558085 -0.046639 0.629395 0.492462 0.620351 1.539766 0.337850 1.829874 -0.029044 1.650869 1.891900 -0.107840 0.000042 1.651572 0.308113 0.328220 0.164791 0.503391 1.668351 1.327181 0.552781 1.134137 0.130061 0.912409 -0.106533 1.117087 0.419486 1.645903 0.619628 0.903437 1.717082 0.277879 0.300313 -0.111169 1.701263 -0.282651 0.916960 1.725278 0.299760 0.206730 0.258427 0.976768 1.006419 1.405478 1.458477 0.511219 1.976132 0.649673 1.067569 1.036236 0.561892 1.032699 1.113462 1.760313 -0.031912 0.151642 1.253446 0.366329 -0.207662 1.411375 0.168281 1.402361 1.015831 0.966440 0.109303 1.719898 -0.033652 0.850348) ) ;;; 93 even -------------------------------------------------------------------------------- (vector 93 12.876626968384 (fv 0 0 0 1 1 0 0 0 0 1 0 1 1 1 1 1 0 1 0 1 0 0 0 0 0 1 0 1 1 1 0 0 0 1 1 1 0 0 1 1 0 0 1 0 0 1 1 0 1 0 0 1 0 0 0 0 1 1 0 0 1 1 0 1 0 1 0 1 1 1 0 1 1 0 1 0 1 0 0 1 0 0 0 0 0 0 0 1 1 1 0 0 0) 10.120779 (fv 0.000000 -0.035376 0.073991 0.427701 -0.282243 -0.018747 0.215658 -0.153445 1.426646 1.066559 1.939228 0.906624 0.410081 0.611941 0.984019 1.022397 0.624511 1.012954 0.533644 1.662254 0.644321 0.184706 0.621632 0.642800 -0.008009 1.949179 1.710653 -0.084032 0.277398 1.824022 0.699251 0.129968 1.020811 0.661971 1.702058 0.534563 1.888605 -0.287827 0.144583 1.379920 1.385073 1.054451 1.007433 0.338841 0.857467 1.489234 0.309837 0.300057 1.146999 0.772495 0.275152 0.667315 1.064213 0.727453 1.142263 1.118538 0.931092 1.595399 1.937578 1.220927 0.920538 0.541725 0.173459 0.580373 1.100745 1.191038 -0.340664 1.515332 1.223959 0.649170 0.846642 -0.414943 0.030223 1.461947 0.288064 0.141033 0.634411 1.011893 0.138288 1.584616 0.333385 0.901662 0.043826 0.951055 1.409243 0.569338 0.143517 0.644810 -0.103707 1.742249 0.748991 1.014192 0.003204) ) ;;; 94 even -------------------------------------------------------------------------------- (vector 94 12.991560374803 (fv 0 0 1 0 0 0 0 1 0 1 0 1 1 1 0 1 0 0 0 1 1 1 0 1 1 1 1 0 1 0 0 1 0 1 0 0 1 1 0 0 1 0 1 1 0 1 1 1 0 1 0 1 0 1 1 1 1 0 0 0 1 0 0 1 1 0 0 0 0 1 1 1 0 0 0 1 0 0 0 1 0 0 1 0 0 1 1 0 1 1 1 1 1 1) ;; ce: 10.168153 (fv 0.000000 0.158749 0.428472 1.119399 1.397485 1.337099 1.326309 0.765212 0.646549 0.366853 0.358406 0.186940 -0.004160 1.693556 1.760221 1.908281 -0.019516 0.044061 0.077064 0.115948 0.108699 0.200075 0.580690 0.574214 0.728439 1.050221 1.095053 1.499686 1.600782 1.705303 0.371346 0.785397 1.061620 1.118378 1.565155 0.180785 0.671073 0.956955 1.179900 0.062702 0.732776 1.104782 1.678100 1.936449 1.211526 1.440956 1.926880 0.701684 1.206989 0.357893 0.937759 1.642399 0.674496 1.095199 1.838835 0.811161 1.664081 0.728543 1.536793 0.935285 1.167394 0.592984 1.298896 0.711769 1.719531 0.207782 1.415604 0.678365 1.539785 1.187347 0.265338 1.410498 0.621725 1.553961 0.975230 0.124475 1.147511 0.723691 1.974302 1.764820 1.095390 0.083191 1.554760 0.873910 0.746004 0.060230 1.781492 1.338588 0.986007 0.875321 0.329252 1.786619 1.490792 0.801318) ) ;;; 95 even -------------------------------------------------------------------------------- (vector 95 12.939489078295 (fv 0 0 1 1 1 1 1 0 1 1 1 1 0 1 1 1 0 0 0 0 1 0 0 0 0 1 1 0 1 0 1 0 1 0 1 1 0 1 1 1 0 0 0 1 0 1 0 0 0 0 1 1 1 1 0 1 0 0 0 1 0 1 0 0 0 0 0 0 1 1 1 1 0 1 1 0 0 0 0 1 0 0 1 1 0 0 1 1 0 1 1 0 0 1 0) ;; ce: 10.274816 (fv 0.000000 0.191955 0.747873 1.620627 1.444931 1.117449 0.280309 0.480520 1.626406 1.210786 1.123735 0.279148 1.110058 1.602457 1.869386 0.773421 1.408758 0.850581 0.528012 0.913946 0.482409 1.573182 0.994233 1.305292 1.545980 0.033608 1.905037 0.750852 0.522232 1.918658 0.047508 1.217238 0.972743 0.083444 0.371581 0.796063 1.083361 0.261908 1.433959 0.521900 0.192999 1.966737 0.129605 0.500888 0.331274 0.913857 0.815429 1.023459 0.478085 1.566987 1.222813 1.708572 1.719376 0.723585 1.103104 1.428438 0.152348 0.040494 1.696898 0.190236 1.378447 1.550950 1.870103 1.503205 0.324210 0.355888 1.476257 1.524550 1.168199 1.485278 1.191081 0.963527 1.662530 1.621072 0.604273 0.737525 1.817225 0.670588 1.938761 1.575766 0.221849 1.885601 1.971423 1.331586 0.219292 1.195712 0.125970 0.883030 0.146163 0.807704 1.769915 -0.019375 1.792299 1.733519 1.458753) ) ;;; 96 even -------------------------------------------------------------------------------- (vector 96 13.077001047978 (fv 0 0 1 0 1 0 0 0 0 1 0 1 0 0 1 1 0 0 1 1 1 1 0 0 1 0 1 1 0 1 0 0 1 1 1 1 0 0 1 0 0 1 1 1 0 0 1 0 1 1 0 0 1 1 0 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 0 1 0 0 0 0 0 1 1 1 0 1 1 0 1 1 1 0 1 0 1 0 0 0 1 1) ;; ce: 10.249441 (fv 0.000000 0.009923 1.397522 1.166061 1.129381 0.862136 0.621841 0.072414 1.181071 0.867293 0.079004 1.693135 -0.014893 0.108345 1.780717 1.327197 1.625536 0.881623 1.921096 0.933503 1.182023 0.476766 1.614305 1.196403 0.811564 0.443720 1.497667 1.275176 0.722032 1.799828 1.704575 1.646983 1.348940 1.072546 0.729932 1.823713 0.260241 0.680766 1.080411 1.441731 1.246268 1.050406 0.336794 0.747049 0.875357 0.924454 1.579785 0.440504 0.667236 1.229671 0.158392 0.708858 1.967741 0.138461 0.274346 0.799091 1.692696 0.840214 1.597165 1.145148 1.181538 0.078566 1.784249 0.079340 0.404851 1.249515 0.162426 0.631488 1.171930 0.883287 1.256995 0.882531 0.425580 1.043774 0.166379 1.858551 0.915286 1.404785 1.287221 1.948447 1.096165 0.270960 1.267765 0.984855 1.705672 1.206954 1.635747 1.831700 1.675862 0.020775 1.394335 0.961664 1.111073 1.653261 0.221394 1.853173) ) ;;; 97 even -------------------------------------------------------------------------------- (vector 97 12.969611395004 (fv 0 0 0 0 0 1 1 0 0 1 0 0 0 0 0 0 1 0 1 0 1 0 0 0 0 0 0 0 1 0 1 0 0 1 1 1 1 1 0 0 1 0 0 0 0 1 1 0 1 1 0 1 0 0 1 0 1 1 0 0 0 1 1 0 0 0 0 0 0 1 1 0 1 0 1 0 1 0 1 1 1 1 0 1 1 0 0 1 1 0 0 0 0 0 1 1 0) ;; ce: 10.353915 (fv 0.000000 0.014320 1.699930 0.475338 0.327588 0.038537 1.537175 1.151125 1.532968 0.067981 0.615972 0.753995 1.850077 0.031584 -0.245176 0.175732 0.019153 0.133227 1.047045 1.449249 1.470511 1.537141 1.108379 0.638023 0.512045 -0.123137 1.442397 -0.285045 0.550401 0.725732 1.137347 0.384697 0.518421 0.107675 0.832943 1.779119 1.053524 1.101550 0.692043 0.797241 -0.542271 0.567053 0.702166 1.746525 1.756713 0.337727 1.446061 0.906449 1.109794 0.007168 1.480499 1.290329 0.754314 1.222669 -0.462191 1.087068 -0.251963 0.941593 1.663909 1.425711 -0.319978 0.693993 1.098604 -0.057825 0.103974 0.674596 -0.040855 0.861405 0.891647 0.007811 0.988956 -0.007355 1.453777 1.088127 0.560798 1.836913 1.159295 1.225761 1.137877 0.994253 -0.314791 0.194425 0.944400 0.940972 1.573317 1.084581 0.080135 1.392169 0.150957 -0.334184 0.271188 0.375796 0.741022 -0.072930 1.298672 1.087468 1.547582) ) ;;; 98 even -------------------------------------------------------------------------------- (vector 98 13.468658765207 (fv 0 0 1 0 1 1 1 0 0 0 0 1 0 1 0 0 0 1 1 0 1 0 0 1 0 0 0 1 1 1 1 0 0 1 1 1 1 0 1 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 1 0 0 1 1 0 1 0 1 1 0 0 1 1 0 0 1 0 0 0 1 1 1 1 1 0 1 0 0 0 1 1 1 0 1 1 0 1) ;; ce: 10.480580 (fv 0.000000 0.029942 1.595740 0.929637 0.140250 1.273956 1.370085 1.486506 0.768736 0.810999 0.987699 0.622931 1.874848 1.232431 0.796670 -0.004456 1.530075 1.744503 -0.182347 -0.272539 -0.039867 0.251416 0.711006 1.684207 0.083442 1.563617 0.619745 1.154797 1.221621 1.412817 0.843588 0.857496 0.194384 1.348416 0.436247 0.378473 1.472625 0.199665 1.452604 1.135822 1.388047 0.919731 1.753351 0.083481 1.454770 1.242435 0.826611 -0.194897 -0.034005 0.041385 0.915233 0.468973 -0.449881 -0.034037 1.686105 0.937405 1.775189 1.272187 0.656772 0.051128 1.735808 1.941754 -0.153834 1.560953 0.798180 1.420628 1.100906 1.382273 0.014181 1.975964 0.450586 0.615591 0.885414 1.287826 0.533661 0.896633 1.605571 0.202012 1.330045 1.186911 0.653866 0.460432 0.799268 1.432588 0.419263 1.021867 0.188412 0.775135 0.208746 0.411264 0.553114 1.806129 0.584153 1.223473 0.816232 -0.069138 0.707217 1.215423) ) ;;; 99 even -------------------------------------------------------------------------------- (vector 99 13.341398779709 (fv 0 1 1 0 0 1 1 1 0 0 0 1 1 1 0 1 1 1 0 1 1 0 1 1 0 1 0 0 0 0 1 0 0 0 0 0 0 1 1 1 0 0 0 0 1 1 0 0 1 0 1 1 1 1 0 1 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 1 1 0 1 1 0 0 0 1 1 0 0 1 0 0 0 1 0 1 0 1 1 0 0 1 1 0 1) 10.395229 (fv 0.000000 0.706072 1.286640 0.926913 0.137440 1.547226 0.117224 1.604362 0.484929 0.893678 0.211396 1.934935 1.381569 0.741431 1.002510 1.548591 1.501995 1.642732 0.386486 0.063170 0.535977 1.363015 0.485356 1.002502 1.149707 1.971779 0.610054 0.176963 1.296429 0.848185 0.077879 0.989380 0.162448 1.939484 1.081728 1.291006 1.781243 0.747318 1.861605 -0.003717 0.355879 1.413789 0.958311 0.004291 0.617108 1.378378 1.118347 1.632856 0.492813 0.823307 1.406872 1.588630 0.799940 0.218833 0.397527 1.627895 0.349077 0.557886 0.566534 1.362311 0.876480 1.822463 0.047284 1.726490 0.281473 1.360892 1.302327 0.630439 0.026319 0.398853 1.499306 1.696667 1.409746 0.843535 1.156093 0.782651 0.844572 0.996729 0.505075 0.454056 0.125470 0.633842 0.812248 1.139044 1.201855 0.936107 1.075661 1.055341 1.239337 1.081381 1.450660 0.544145 0.960193 1.261524 0.471575 0.159670 1.647942 0.617964 0.426032) ) ;;; 100 even -------------------------------------------------------------------------------- (vector 100 13.512077331543 (fv 0 1 0 1 1 0 1 1 0 1 1 1 0 1 1 1 0 1 0 1 0 1 1 0 1 1 1 1 1 0 1 1 1 0 1 1 1 1 0 0 0 0 1 0 1 1 0 1 1 0 1 1 1 0 0 0 1 1 0 0 1 0 1 0 0 0 0 0 0 1 1 0 1 1 1 0 1 0 0 1 0 1 0 1 1 1 1 1 1 0 0 0 1 1 0 0 0 0 0 0) 10.472141 (fv 0.000000 -0.079327 0.575962 1.216890 -0.014744 1.794579 0.223351 1.035736 1.450027 1.621511 1.146130 0.664482 0.663607 -0.266960 0.246822 0.754872 1.746592 -0.423496 -0.112090 1.668859 1.661047 0.950742 0.085504 0.302466 1.790192 0.512158 1.549763 -0.087872 1.606339 1.457814 0.979132 1.246348 1.572286 1.270907 0.557192 1.282392 0.773062 0.627296 0.449140 1.192929 0.105994 0.224683 -0.182519 0.743965 0.463017 1.607410 -0.217575 1.706348 1.917272 0.364576 0.425823 0.089107 1.477241 0.882347 1.143269 0.061661 0.026397 0.093540 1.833116 0.100956 -0.001875 0.084325 0.282798 1.183349 0.971365 0.306714 1.553029 0.062053 0.155585 0.754942 -0.336663 0.692895 0.554870 1.705080 0.442045 1.319460 0.995119 1.023180 1.734006 0.775241 1.099502 1.819778 -0.446034 1.513278 1.247469 0.530165 0.247921 1.473754 1.799924 0.292965 1.840516 0.908343 1.781887 1.143210 0.571911 1.546526 0.744154 1.261450 1.702101 1.407355) ) ;;; 101 even -------------------------------------------------------------------------------- (vector 101 13.916260357992 (fv 0 1 1 1 1 0 0 0 1 1 0 1 1 0 1 1 1 1 1 0 0 0 1 1 0 1 1 1 1 1 0 1 0 0 0 1 0 0 1 0 1 1 0 0 1 0 0 1 1 1 0 1 0 1 0 0 1 1 1 1 1 1 0 1 1 0 1 0 1 1 0 0 0 0 1 1 0 1 1 1 1 0 1 1 1 0 1 1 0 0 0 0 0 1 1 0 0 0 1 0 1) ;; ce: 10.577830 (fv 0.000000 0.230088 0.489949 1.896308 0.933068 0.593501 0.422308 0.060228 1.624707 0.198599 1.858938 1.074760 1.176893 0.981397 1.101455 0.671865 0.424692 0.090154 1.204682 1.678470 1.838266 0.024568 0.595975 1.448081 0.084971 1.587793 0.520717 0.874796 1.272960 1.935410 1.267081 1.651444 1.443667 0.106075 1.743028 0.700933 0.469120 0.378892 0.399951 0.519935 1.685545 1.698426 0.785883 0.473603 0.884326 1.731208 1.464294 1.924822 0.636901 0.305356 0.801079 1.744433 1.003951 0.836001 0.264502 0.624042 1.251558 0.465073 1.095465 1.359393 1.201558 0.893610 0.464655 0.265401 1.373759 1.898225 1.761890 -0.002084 1.345698 1.606225 0.081343 1.615987 1.843685 0.952555 0.240683 1.457724 0.753500 1.550264 1.132929 0.635603 1.553592 1.597112 0.562720 1.442901 1.005554 1.242061 1.201605 1.261095 1.477713 0.348336 0.005918 1.590197 0.313622 0.668027 1.281558 1.857136 1.788055 0.849243 1.615883 0.119440 1.251097) ) ;;; 102 even -------------------------------------------------------------------------------- (vector 102 13.554303556646 (fv 0 0 1 0 0 0 0 0 0 0 0 0 1 1 0 1 1 1 1 1 1 1 1 0 1 0 1 1 1 1 0 1 1 1 0 1 0 0 1 1 0 1 1 1 0 0 0 1 0 0 1 0 1 1 1 0 1 0 0 1 0 0 1 0 1 0 0 1 1 1 0 0 1 1 1 1 0 0 0 0 1 0 1 1 1 0 1 1 0 0 1 1 1 0 0 0 1 1 1 0 1 0) ;; ce: 10.573986 (fv 0.000000 0.455448 1.592339 0.516746 1.755302 0.430730 1.719525 0.951344 -0.011584 1.094962 0.249269 1.210204 0.681046 1.814999 1.100181 0.342805 1.598301 0.973279 1.813912 1.543187 1.213360 0.476019 1.876128 1.338406 0.323141 0.086213 1.782029 1.276211 0.922086 0.263981 1.923412 1.289879 0.951410 0.707896 0.012549 1.851646 1.630674 1.384243 1.051926 0.762336 0.305766 0.298705 1.874016 1.899771 1.620966 1.734952 1.429925 1.177184 1.271518 1.112585 1.351310 1.169594 1.017169 1.072042 1.161752 0.892462 1.662674 1.237843 1.407508 1.778309 1.632181 -0.005924 0.137286 0.529299 0.602002 0.855550 1.115330 1.528193 1.708150 1.986964 0.217781 0.770088 1.353099 1.819055 0.042966 0.583719 0.854932 1.780394 1.890656 0.692898 1.277125 1.902467 0.022802 0.892858 1.554169 0.132068 0.918216 1.832708 0.149377 0.742587 1.856221 0.273349 1.013342 0.114623 0.855957 1.713909 0.875532 1.432041 0.715192 1.022773 0.307135 1.424286) ) ;;; 103 even -------------------------------------------------------------------------------- (vector 103 13.923377530893 (fv 0 1 0 1 1 1 0 1 1 0 0 1 0 0 1 1 1 1 0 1 1 0 0 1 0 0 0 0 0 0 1 1 0 0 0 1 0 0 1 1 0 1 0 1 0 1 0 1 1 0 0 0 0 1 0 1 0 0 1 1 0 1 1 0 1 0 1 0 1 1 1 1 1 1 1 1 1 0 0 1 1 1 0 0 1 1 0 0 0 0 1 1 1 1 1 0 0 0 0 1 0 1 0) ;; ce: 10.655070 (fv 0.000000 0.098203 0.840876 1.375107 0.153742 0.905827 1.598049 0.226902 1.106387 1.951313 0.409173 1.416206 0.300008 0.991894 1.877024 0.769923 1.633937 0.581083 1.464525 0.440302 1.508923 0.447643 1.643543 0.650572 1.662974 0.812624 0.114340 1.320550 0.512587 1.607339 0.712150 1.624256 0.673697 0.132515 1.684625 1.034157 0.294350 1.413417 0.670789 0.070085 1.514860 0.928557 0.150294 1.635889 1.040664 0.560013 0.195302 1.710399 1.367615 1.043173 0.402177 1.662716 1.456941 1.147051 0.985707 0.632104 0.408799 0.275068 1.862616 1.424547 1.082981 1.090416 0.822477 0.915783 0.592819 0.610365 0.257982 0.450718 0.126885 0.491389 0.133294 0.376246 0.118720 0.195423 1.887844 0.645109 0.531798 0.762689 0.732490 0.998025 0.912568 1.060467 1.162384 1.198622 1.637406 0.207879 0.126974 0.580167 0.848976 1.222343 1.532632 1.780660 0.095903 0.581413 1.052384 1.441822 1.990917 0.734482 1.101269 1.710370 0.157742 0.650375 1.262955) ) ;;; 104 even -------------------------------------------------------------------------------- (vector 104 14.080453047533 (fv 0 0 0 1 0 0 1 1 1 0 1 1 0 1 0 0 1 0 1 1 0 0 1 1 1 0 0 1 1 0 1 0 1 1 1 0 0 1 1 1 1 0 1 0 0 1 0 0 0 0 1 1 1 1 0 0 0 0 0 1 0 0 0 1 0 0 1 0 1 0 1 0 1 0 1 1 0 0 1 1 1 0 1 0 0 1 0 0 1 1 0 0 0 0 0 0 1 1 1 1 1 1 1 1) ;; ce: 10.681525 (fv 0.000000 -0.024256 0.783678 0.790357 0.543059 0.305361 -0.134503 0.818664 1.525254 0.494738 0.824462 0.413278 0.768548 0.076204 0.116598 0.283930 0.002578 1.585676 1.025319 1.696095 0.040592 0.097252 1.464874 0.943760 1.446445 1.337085 -0.054264 0.475515 1.125978 1.147471 1.094995 0.186610 0.588805 0.970144 0.882957 0.245963 0.284357 -0.394290 1.437271 0.927960 1.125343 0.492129 -0.680606 0.536491 0.927855 1.405256 0.384789 0.057902 1.208331 0.288662 1.508156 1.581082 1.167052 1.243667 1.226450 0.112600 1.111908 1.348016 0.638821 1.169461 0.306222 1.466381 0.659007 1.306085 1.700156 1.339421 0.711646 0.085484 0.909896 -0.178331 1.447928 0.767489 1.399367 -0.197416 1.574394 0.605814 -0.011981 -0.082006 0.824364 0.264841 1.418643 0.988277 -0.314078 0.146715 0.221811 0.630751 0.576546 0.496630 0.654974 1.143866 1.326186 1.202136 1.173988 0.681397 1.563605 0.912110 1.479070 0.009348 0.151736 0.948455 0.251873 0.215256 0.959463 1.013975) ) ;;; 105 even -------------------------------------------------------------------------------- (vector 105 14.023490699521 (fv 0 1 1 1 0 1 0 0 1 1 1 1 1 0 1 1 0 0 0 0 1 1 1 0 1 1 1 1 1 0 0 0 1 0 1 0 0 0 1 1 0 0 0 0 1 0 1 0 0 0 1 0 0 0 1 0 1 0 0 1 0 1 0 1 1 1 0 1 0 0 1 1 0 0 1 0 1 0 0 1 0 0 0 0 1 0 1 1 0 0 1 0 1 1 0 0 0 1 1 0 1 1 1 0 0) ;; ce: 10.762178 (fv 0.000000 0.397875 0.415370 0.882172 0.546824 1.353988 1.428323 0.899356 0.371635 0.978504 0.763060 1.852147 0.544169 0.212342 0.787152 0.707632 0.540670 1.634630 1.456913 1.887455 0.659515 1.903305 1.487136 0.606049 0.181640 0.198532 0.870626 0.299967 1.007267 0.225649 1.806738 0.672311 0.647212 0.706876 1.445160 0.654294 0.635429 0.365790 0.507155 0.852393 0.362305 0.862000 0.544259 1.758526 1.506465 1.313083 0.892464 0.407338 1.550831 0.757533 1.555137 -0.026848 1.155141 1.305207 1.788542 1.889285 0.358766 1.027604 0.314507 0.587817 0.916345 0.200487 1.411080 1.048840 1.178903 0.194143 1.901728 1.960301 1.945844 1.173118 1.765984 0.206171 1.625946 0.040059 1.626954 0.263952 1.564387 1.266244 1.622196 0.755369 0.949828 0.255858 0.753659 1.729344 1.050369 1.743664 1.440420 0.145640 0.301718 1.174665 0.822890 1.317300 1.570892 0.407998 0.956005 1.432600 0.239369 0.699233 1.040355 0.955730 0.525379 0.245609 0.402988 1.983561 1.494957) ) ;;; 106 even -------------------------------------------------------------------------------- (vector 106 14.077123010357 (fv 0 0 1 1 0 1 1 0 0 0 0 0 0 0 1 0 1 0 0 1 1 1 1 1 1 0 1 0 1 1 1 0 1 1 1 1 0 1 1 0 0 0 1 1 1 1 1 0 0 1 0 1 1 1 1 0 1 1 1 0 1 1 1 0 0 0 0 0 1 1 1 0 0 1 1 0 1 0 0 1 1 0 1 0 0 0 0 1 0 1 0 1 0 0 1 1 0 0 0 0 1 1 1 0 1 1) ;; ce: 10.830737 (fv 0.000000 -0.005846 0.570672 0.234799 1.335287 1.359588 -0.419716 0.539638 0.608529 0.339921 1.061903 -0.158242 -0.044398 1.229716 1.763841 1.099423 1.509512 0.089726 1.005316 -0.075124 -0.066461 1.466196 0.771111 0.468552 1.415804 0.138963 -0.245805 0.138836 0.477088 1.188902 1.132158 1.069838 1.264025 0.968611 1.914288 1.097597 1.541915 0.300326 1.372837 1.925102 1.312271 -0.023238 1.373743 1.323233 1.094484 0.489712 0.482163 1.087861 0.500643 0.570320 1.558451 0.587192 1.367163 1.157295 0.201827 0.338548 0.589886 0.627255 0.836138 0.810466 -0.203530 1.496837 1.317835 0.258851 0.104005 1.762383 1.590637 1.892947 1.673713 0.391886 0.132951 1.390857 1.679677 1.113406 0.925816 1.243522 0.395898 -0.235350 0.125786 0.071751 0.796497 -0.006564 0.517719 0.324240 -0.029479 1.648460 0.422894 0.173347 0.366226 -0.269652 0.667311 0.224137 1.099578 1.062306 -0.039311 0.586541 0.652636 1.087861 0.037847 0.544588 -0.167470 1.665629 0.356235 0.598705 1.690854 1.284152) ) ;;; 107 even -------------------------------------------------------------------------------- (vector 107 13.979104817741 (fv 0 0 0 1 0 1 0 0 1 0 0 0 1 1 0 0 1 0 0 1 0 1 0 0 1 0 0 0 0 1 0 0 1 0 1 1 1 0 1 0 1 1 1 1 0 0 0 0 1 0 1 1 1 1 1 1 1 1 1 0 0 1 0 1 0 1 1 1 0 0 1 0 0 0 0 0 1 1 0 0 1 0 1 1 0 0 1 1 1 1 1 1 0 0 1 1 0 1 1 0 0 0 0 0 1 0 1) ;; ce: 10.937211 (fv 0.000000 -0.004224 0.060024 -0.045111 1.214471 1.071129 0.959468 -0.117229 0.526421 0.777989 1.101830 1.594870 1.129631 1.240597 0.114410 -0.015477 -0.160025 1.227190 0.975588 0.257050 0.062807 0.334972 0.704097 1.491576 0.263834 0.840227 0.134041 0.515784 0.095610 1.204429 1.214110 -0.209995 0.542934 1.280779 0.060334 1.305652 0.399609 0.055093 1.015156 -0.124325 0.060155 1.228735 0.771913 1.621598 0.808853 1.471209 -0.169978 1.121641 0.399914 1.719441 0.379423 1.503274 1.042517 0.685780 0.947470 0.570388 0.750717 1.227614 1.713741 0.574606 1.613832 0.259018 1.237457 1.030851 1.608948 1.331324 0.222275 1.365789 1.141241 0.137043 0.400610 0.136266 1.777801 -0.008027 -0.188345 0.319469 0.129091 -0.503698 1.075061 0.022495 -0.104170 1.746336 1.362807 0.487726 1.046216 1.025881 -0.113705 0.257262 0.139668 0.033537 0.410121 0.067540 0.536883 1.096402 0.595602 1.418336 1.800057 0.344577 0.240890 1.498996 -0.357281 0.342654 1.655013 1.372406 1.308709 -0.240755 1.334030) ) ;;; 108 even -------------------------------------------------------------------------------- (vector 108 14.201394892821 (fv 0 0 1 0 1 1 1 0 0 1 1 0 1 1 0 0 1 1 0 0 1 1 0 1 0 1 1 1 0 0 0 1 0 0 1 0 0 0 1 0 1 0 0 1 0 1 1 0 1 1 0 0 1 1 0 1 0 1 1 0 0 1 0 1 0 0 0 1 1 1 0 1 0 1 1 0 1 1 1 1 1 1 0 1 0 1 1 1 1 0 1 0 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1) ;; ce: 10.928835 (fv 0.000000 0.001349 1.292491 0.733848 1.693309 1.799399 0.481169 -0.003953 0.631395 1.556718 0.747743 0.394608 -0.163614 0.178289 1.389719 1.500511 0.566775 1.069628 0.140033 0.292869 1.057556 -0.232775 1.757479 1.152928 0.313785 -0.002063 1.713110 1.409517 1.701701 0.540017 -0.081333 0.363976 1.907649 1.714406 0.366131 1.312522 1.061649 -0.016307 1.204902 0.111229 1.131127 1.599963 0.195405 0.048689 0.148454 1.536192 1.518659 0.029237 0.220432 0.060747 0.889494 0.493752 0.976299 1.363602 1.809211 1.216107 0.616567 0.927578 1.398521 0.961300 1.194676 0.366929 1.180567 1.477072 0.270916 0.119650 1.287137 1.475762 1.163703 1.481070 1.371759 0.541244 1.311014 1.044588 1.313660 0.533979 1.490951 0.356285 -0.069909 0.767914 0.271739 0.014710 1.682385 0.162634 1.095329 0.775810 0.661086 0.068467 1.450209 1.785189 0.063589 1.966358 1.523081 1.437414 0.274911 0.580082 1.089239 -0.463689 1.664646 1.305111 1.466902 1.475663 0.556905 0.115271 0.981770 0.504641 0.709948 1.631495) ) ;;; 109 even -------------------------------------------------------------------------------- (vector 109 14.476561866583 (fv 0 1 0 1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 1 0 0 0 1 0 0 0 0 1 1 1 0 0 1 0 1 1 1 0 0 1 0 1 0 0 1 1 1 1 1 0 0 0 0 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 0 0 0 1 0 1 1 0 0 1 0 0 0 1 1 0 0 1 1 1 0 1 1 0 1 0 0 1 1 1 1 0 1 1 1) ;; ce: 10.962218 (fv 0.000000 -0.020139 1.296818 0.759398 1.805908 1.100728 0.800122 1.439412 1.622620 0.514993 1.795449 1.209391 0.020235 0.358160 0.092111 0.419753 0.215041 0.890857 0.739133 0.655070 -0.097603 1.149145 1.795049 0.529356 0.278854 0.849651 1.115508 -0.203443 -0.316571 0.636461 0.169404 0.863285 1.244658 0.826671 1.217995 1.641136 1.077104 1.940135 -0.019991 0.361800 0.684590 0.618864 1.574258 0.100541 0.539464 1.815288 0.854878 0.087950 0.096927 0.551713 0.357857 0.524099 0.322958 1.655523 1.025258 0.447127 1.801347 0.241837 1.863980 1.144261 1.218309 0.839437 0.457453 0.658738 1.245153 1.083988 0.663284 0.430502 0.960078 0.132118 0.667264 0.423888 1.801298 1.342075 0.136707 0.381362 0.568108 1.442671 0.522741 -0.163023 0.297994 0.902549 1.034272 0.408426 0.838530 1.491663 1.889043 0.510513 1.243885 -0.037162 0.829406 0.263055 1.957688 1.777764 1.532407 1.532356 -0.098135 1.343701 -0.090007 1.030266 0.540482 0.697946 0.058406 0.051557 1.224797 1.605931 1.084281 1.340523 0.856409) ) ;;; 110 even -------------------------------------------------------------------------------- (vector 110 14.141825477743 (fv 0 0 0 0 1 0 1 0 1 1 0 1 0 0 1 0 0 1 1 1 1 1 0 1 1 1 0 1 1 0 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 0 0 1 0 1 1 0 0 0 1 1 0 0 1 0 0 1 0 1 0 0 1 0 0 0 1 0 1 1 1 0 1 1 1 0 0 1 1 1 0 0 1 0 1 0 0 0 1 0 1 1 1 0 1 1 0 1 1 1 1 0 0 0 0) ;; ce: 11.083621 (fv 0.000000 0.102224 0.391557 0.595597 0.594876 1.372717 0.692712 1.820557 0.592991 0.744933 0.284097 0.094534 1.236489 0.656692 0.836105 1.286301 1.045083 0.906213 0.452242 1.303365 1.815972 0.742162 1.260200 1.034689 1.519277 1.714910 0.030360 1.701396 0.878133 1.252260 1.563515 1.824493 1.440884 0.550691 0.625323 0.322441 0.255155 1.747348 1.715563 1.206982 0.695445 1.179481 0.756077 1.528329 0.919865 1.229029 1.159425 1.320573 0.445003 1.914934 0.957065 0.751755 0.916124 0.636546 1.677594 1.368208 1.478534 0.887675 1.827907 0.505854 0.598384 0.760342 0.616916 0.235984 0.997501 1.394766 0.145444 0.892122 1.825648 1.436307 0.231097 0.844561 0.320584 0.655075 0.450233 0.147790 1.886750 0.073198 0.684099 0.980548 1.422263 1.230129 0.607855 1.708107 1.670067 1.087055 1.809960 1.108445 0.779703 1.445375 0.004959 0.570411 1.025881 0.429647 0.658700 0.663819 0.227169 1.057047 0.056802 0.087954 1.060399 1.762629 1.235596 0.276822 0.266842 1.518690 1.130656 0.442538 0.924181 1.667970) ) ;;; 111 even -------------------------------------------------------------------------------- (vector 111 14.043108609984 (fv 0 1 1 0 0 1 1 1 0 0 1 0 0 0 0 1 0 1 0 1 1 0 0 0 0 0 0 0 1 0 1 1 0 1 1 0 1 0 0 0 1 0 0 1 1 1 0 0 0 1 1 1 0 1 0 1 0 1 0 1 1 1 1 0 0 1 1 1 1 1 0 1 1 0 0 1 0 0 1 1 1 1 0 1 0 0 1 1 0 0 0 0 0 0 1 0 0 0 1 1 1 1 1 1 0 1 1 1 1 0 1) ;; ce: 11.044285 (fv 0.000000 0.158015 0.933037 1.614942 0.438728 1.109662 1.925788 0.472812 1.243741 0.106020 0.791740 1.640176 0.492268 1.485008 0.348988 1.215620 0.210371 0.907594 1.877045 0.815828 1.746879 0.708997 1.883211 1.043991 0.199639 1.074067 0.180622 1.253869 0.348260 1.556554 0.806309 0.044157 1.125294 0.382590 1.810361 1.146217 0.335649 1.611965 0.680338 1.937389 1.233789 0.766403 0.308709 1.641326 0.874950 0.294876 0.039653 1.398544 0.690400 0.241248 1.690671 1.329862 0.933824 0.621841 0.215994 1.901023 1.430062 1.233607 0.739730 0.472666 0.123106 0.067252 1.738994 1.459373 1.478846 1.201845 1.291598 0.805256 0.526423 0.555011 0.429805 0.468900 0.550665 0.287845 0.418385 0.091842 0.561234 0.306326 0.551107 0.349285 0.443927 0.497444 0.741730 0.889477 1.210808 1.343091 1.439025 1.479999 1.836181 0.047632 0.373687 0.550415 0.777036 1.388872 1.698564 0.091159 0.463192 0.987707 1.050209 1.564941 1.953806 0.531885 1.227608 1.522869 0.053791 0.776531 1.501133 1.889970 0.686171 0.911252 1.640718) ) ;;; 112 even -------------------------------------------------------------------------------- (vector 112 14.53456401825 (fv 0 0 0 1 0 0 0 1 1 0 0 0 1 0 1 0 1 0 1 0 0 0 0 1 1 1 0 0 0 0 1 0 1 1 1 1 1 1 0 1 0 0 1 1 1 0 0 0 0 1 0 0 1 0 0 1 1 1 1 0 1 1 0 0 1 0 0 0 0 0 1 1 1 1 0 1 0 0 1 0 0 1 0 0 0 0 0 0 1 0 0 0 1 0 1 0 0 0 0 0 0 0 1 1 1 0 0 1 1 0 0 1) ;; ce: 11.132899 (fv 0.000000 -0.004199 1.283910 0.989370 -0.208623 1.916334 0.074521 1.835438 1.334006 0.305929 1.500009 -0.074494 1.168847 0.049877 1.276892 1.333761 -0.092116 1.454810 0.477624 0.576171 0.178508 0.764025 0.524952 1.017918 1.503303 0.222438 0.024354 0.989207 -0.051649 0.790422 1.303684 -0.215343 0.911639 1.672316 0.816315 1.393173 1.438934 1.325167 0.960271 0.472591 1.161764 -0.301446 0.550621 1.114416 1.344136 1.489640 1.336572 0.050968 0.500820 -0.057732 1.192684 1.166393 1.318354 1.292569 1.273498 0.099165 0.438587 1.952651 -0.094274 1.629010 1.153422 1.621198 0.812392 0.958180 1.035359 0.874583 0.398809 1.397735 0.813120 1.083168 1.586479 1.738041 -0.184237 0.887045 0.555348 1.573618 0.841883 0.094362 0.127164 -0.091421 0.370018 0.132149 0.004963 0.522483 0.330656 0.374322 1.610332 1.059431 0.769509 1.653723 0.151945 1.881470 1.251612 1.570585 0.545409 0.439130 1.754244 0.242385 1.453705 1.649898 0.928413 0.488588 1.234024 -0.316648 1.499904 0.614604 0.329349 1.231718 0.063978 0.324984 0.806167 0.116728) ) ;;; 113 even -------------------------------------------------------------------------------- (vector 113 14.699631659332 (fv 0 0 1 1 0 1 1 0 0 1 1 0 0 1 0 0 1 1 1 1 1 0 0 1 1 1 1 0 0 0 0 0 0 0 1 1 1 0 1 0 1 0 0 0 1 1 1 0 1 1 1 0 1 0 1 1 1 1 0 1 1 1 0 0 1 0 0 1 1 1 1 0 0 1 0 1 1 0 1 0 0 1 1 0 0 0 1 0 0 0 0 1 0 1 0 1 0 1 1 0 0 0 0 0 1 0 0 0 0 1 1 0 0) ;; ce: 11.086230 (fv 0.000000 -0.000389 -0.085077 1.561730 0.939636 0.783800 0.822356 0.753902 1.063386 1.064106 0.248945 -0.331235 0.891273 0.384236 1.666476 1.209055 0.747827 1.261264 0.977109 0.473018 1.869842 1.640635 0.426272 0.493282 0.533612 0.678013 0.886344 1.278452 0.240683 0.355081 0.485535 1.773399 1.825457 0.749792 0.520365 0.198490 0.250957 0.893317 0.038147 1.767495 1.585752 1.382949 0.153130 0.345263 1.470526 1.544311 -0.012268 0.353892 0.265833 0.472828 0.199271 0.570776 0.068734 -0.052674 -0.058660 0.544786 0.747249 1.268098 -0.214510 0.394163 0.864637 0.802715 -0.354031 0.495687 0.772508 0.500088 0.648134 0.893273 0.437351 0.101751 1.505344 1.430317 1.237725 -0.133160 1.737117 0.276904 0.819294 -0.436692 0.255417 1.171282 -0.127128 0.741289 1.135948 0.224854 1.189320 1.263745 1.436981 1.094323 0.315920 0.551659 -0.076936 0.988425 0.147044 1.117725 1.898145 1.201889 0.000719 0.311682 0.796660 0.441683 0.674490 1.525693 0.432480 -0.261252 0.793197 1.692433 1.264116 1.229766 1.345051 1.012949 0.026436 1.326999 0.385241) ) ;;; 114 even -------------------------------------------------------------------------------- (vector 114 14.492 (fv 0 1 0 1 0 1 0 0 1 0 0 0 1 0 0 1 1 0 1 1 0 0 1 1 0 1 1 0 0 1 0 1 1 0 1 0 0 0 1 0 1 1 1 0 0 0 1 1 1 1 1 0 1 1 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 1 0 0 0 1 0 1 0 1 1 0 0 1 1 1 0 0 1 1 0 1 1 0 0 0 1 1 0 0 0 0 1 0 1 1 0 1 0 1 0 0 0 0 0 1) ;; ce: 11.157135 (fv 0.000000 -0.039464 0.696620 1.049808 1.784392 0.325544 0.858380 1.305402 0.025713 0.621307 1.231983 1.810377 0.686152 1.384942 0.194646 1.038532 1.591698 0.399402 1.138014 1.856685 0.607032 1.487902 0.438056 1.390980 0.254957 1.178058 0.067020 0.938265 1.875276 0.851076 0.004242 1.047055 0.045055 1.007007 0.277254 1.473760 0.430329 1.411705 0.732780 1.815871 0.875020 0.057294 1.303464 0.776395 0.029104 1.052938 0.330119 1.901182 1.233681 0.357134 1.566517 1.090726 0.497634 1.859625 1.337968 0.810851 0.475823 1.810735 1.275081 0.613201 0.249187 1.680606 1.475238 0.917317 0.615081 0.035115 1.985536 1.555790 1.295493 0.711316 0.674571 0.194958 0.031526 1.689053 1.752486 1.376552 1.332463 1.199628 1.038471 0.887824 0.776195 0.244582 0.396901 0.380408 0.272363 0.437965 0.462200 0.460243 0.479976 0.174041 0.442325 0.587458 0.662414 0.624435 0.793505 1.270764 1.312001 1.527872 1.906728 0.154209 0.367925 0.274540 0.568448 0.741643 1.347518 1.802398 -0.015484 0.528377 1.078486 1.236948 1.800583 0.083771 0.530926 0.938750) ) ;;; 115 even -------------------------------------------------------------------------------- (vector 115 14.568 (fv 0 1 0 1 0 0 1 1 0 1 0 1 0 1 0 1 0 0 0 1 0 0 1 1 1 1 0 1 0 0 0 0 1 1 0 1 1 1 1 1 1 1 1 1 1 1 0 1 1 0 1 1 1 0 1 0 0 1 1 1 0 1 1 0 0 1 0 1 0 0 0 1 0 0 1 0 1 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 1 1 0 0 0 0 1 1 0 0 0 0 1 1 0 1 0 1 0 0 1 1 1) ;; ce: 11.164043 (fv 0.000000 -0.007735 0.519521 0.853408 0.869518 0.698179 0.507264 1.931615 0.907177 -0.081980 1.081445 -0.614824 0.113202 -0.200689 1.235563 -0.410618 -0.044424 1.664294 0.004420 -0.047758 -0.084756 0.183149 0.916469 0.869368 0.512976 0.672797 1.215314 0.375058 0.915864 1.704866 0.936574 0.218869 0.698296 0.045271 1.628914 0.078964 0.149407 0.338531 0.117882 -0.320994 1.491596 1.006019 -0.240429 1.202447 1.241878 1.751514 1.720285 0.676992 -0.221839 1.582392 1.209034 1.838537 0.581983 1.407446 0.568243 0.270174 1.675976 1.382944 1.186838 0.261842 1.726931 1.658063 1.186047 0.622126 0.744214 1.106115 1.040724 0.077608 1.153074 1.203757 -0.097198 0.746254 0.828552 0.000738 0.431630 0.964545 1.375943 1.286789 1.299809 0.427471 1.340955 0.754972 1.408156 0.094923 0.222079 1.183606 -0.446708 1.549043 0.356824 0.090057 -0.448761 1.856851 1.141144 -0.262172 1.428502 1.426364 0.962275 0.289782 0.928089 1.983331 -0.130528 1.708026 0.141800 0.998440 0.458314 -0.400945 1.256766 -0.158747 1.393865 0.122714 0.409705 1.066166 0.512662 1.368814 -0.157203) ) ;;; 116 even -------------------------------------------------------------------------------- (vector 116 15.016979484255 (fv 0 0 0 1 1 0 0 1 1 1 0 1 0 0 0 0 1 1 1 1 1 0 1 0 0 0 0 0 1 1 0 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 0 1 1 0 1 0 1 0 0 1 0 0 0 1 0 1 0 0 1 1 0 1 1 1 0 1 1 1 0 1 0 1 0 1 0 0 1 0 1 1 0 1 1 0 1 1 1 0 0 0 1 1 1 1 0 0 0 1 0 0 1 1 0 1 1 0 0 1 1 1) ;; ce: 11.308873 (fv 0.000000 0.106229 0.367548 0.759703 1.450113 0.465588 0.341776 1.222993 1.113540 1.977777 0.446611 1.479153 0.955230 1.992164 0.113898 1.375014 0.059260 1.796441 0.549529 1.451646 0.822821 0.184153 0.830995 0.917449 1.204323 1.332702 0.993172 0.476637 0.152682 0.285363 1.211807 1.922965 1.934074 0.639385 1.616893 0.230624 1.048187 1.300335 1.518811 0.179696 1.385435 1.756315 0.391503 1.071522 1.058267 0.918446 1.149703 1.296773 1.452377 0.657106 1.424678 0.536336 1.485981 1.611780 0.685035 0.081570 0.627797 1.372075 1.222404 1.169964 1.598122 0.868152 1.372826 0.969303 1.586861 1.193094 0.604224 0.998617 0.464449 0.148345 1.841878 1.782198 1.348866 0.090916 1.094752 0.710300 0.820593 1.392694 1.514436 0.049760 1.558012 1.165815 1.487314 0.076812 1.896177 1.104849 0.595775 1.855654 1.593410 0.247419 1.353710 0.594589 0.610661 1.819899 0.938600 0.733465 1.567730 0.600698 0.773170 0.184194 0.659368 0.319562 0.537696 0.610429 1.447619 1.265473 0.841708 1.485819 0.127545 1.328769 1.079928 0.763531 0.772097 1.829006 1.877480 1.871926) ) ;;; 117 even -------------------------------------------------------------------------------- (vector 117 14.875072951405 (fv 0 0 0 1 1 0 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 0 0 1 1 1 0 1 1 0 0 0 1 0 0 1 0 0 1 0 1 0 1 0 0 0 1 1 0 1 0 1 1 1 0 1 0 1 0 0 0 0 0 0 0 1 0 1 1 1 1 1 0 1 0 1 1 0 1 0 0 1 0 1 1 0 0 1 1 0 1 0 0 1 1 1 0 0 0 1 0 1 1 1 1 1 0 0 1 1 1 1 1 0 1 1 0) ;; ce: 11.316924 (fv 0.000000 0.002007 0.781183 0.142859 1.136983 0.564897 1.668822 1.434278 0.786253 -0.066154 0.611443 0.995393 0.251112 1.435273 1.364551 0.525535 1.314966 0.129127 0.479417 1.253995 -0.066213 1.791978 1.010496 1.762957 1.001915 0.214345 0.247689 0.903489 0.260750 0.253476 1.207167 1.205379 1.535712 0.678624 0.281388 0.707771 0.067718 0.139190 1.072777 -0.486251 1.036395 0.468802 1.185352 1.038535 0.280173 0.909530 -0.484113 1.287468 1.260568 1.711487 0.150804 1.583879 0.090810 1.204628 1.205628 1.363904 1.302202 -0.374153 1.893817 1.633143 0.456452 1.096868 0.228741 1.451713 1.797254 1.457252 0.043295 1.213733 1.209057 1.602790 0.068325 1.156775 0.622551 0.595184 1.038306 1.138842 -0.234118 1.017885 1.021316 0.185827 1.543882 1.771287 1.232077 0.638733 0.782279 1.727494 1.416897 0.927851 0.310771 0.940398 0.359593 0.479087 0.049395 0.127472 0.206640 1.096147 1.150359 1.659289 0.531691 1.180395 -0.391853 1.508862 1.232699 -0.058238 1.293947 -0.476640 -0.441677 -0.000097 0.976133 1.008107 0.426436 0.349033 0.468049 0.890361 0.742074 -0.282223 0.097574) ) ;;; 118 even -------------------------------------------------------------------------------- (vector 118 14.774983755641 (fv 0 1 1 1 1 0 0 1 1 1 1 0 1 1 0 0 0 0 1 1 0 1 0 0 1 0 0 1 1 0 1 1 1 1 0 1 0 0 0 0 0 1 1 0 0 0 0 0 1 0 1 0 0 0 1 1 1 1 0 0 1 1 0 0 1 1 0 1 0 1 1 0 1 1 0 0 0 1 1 0 1 1 1 1 1 1 1 0 0 0 1 1 0 1 0 1 0 1 1 1 1 1 0 0 1 1 0 0 0 1 0 1 1 0 0 1 1 1) ;; ce: 11.484440 (fv 0.000000 0.001991 1.371443 1.203612 1.612576 0.004093 1.549674 1.288096 -0.387029 0.195003 0.810853 0.270601 -0.577973 0.504742 1.563436 0.486759 1.262262 1.570710 0.506761 0.593681 0.979316 0.335707 1.012168 1.408672 1.854537 -0.158648 0.922395 1.542523 0.986042 0.834203 1.587297 -0.259646 0.182780 1.551059 1.155567 -0.257572 1.455112 0.260440 0.601953 0.584384 0.049890 0.147201 0.144045 0.167346 1.932438 -0.017361 0.127366 1.610439 0.342924 0.013626 1.817380 1.463720 1.349166 1.704788 0.073700 0.915288 0.862503 0.591911 -0.314143 1.485517 0.827715 -0.237036 1.912130 0.274385 1.072007 0.283372 1.321692 0.776602 1.550269 0.993130 0.787661 0.571393 0.826289 1.556852 0.493665 1.623055 1.585319 1.166393 1.153368 1.675993 0.390711 -0.188185 1.283768 1.613360 0.827291 0.287448 0.106800 0.359659 1.804631 1.116403 1.085383 0.798175 1.148482 1.482094 1.397430 -0.132223 0.799212 -0.083458 -0.185498 0.780581 -0.264041 0.816859 1.276724 0.301164 1.464050 0.647926 1.027415 1.036757 -0.070219 0.009504 1.202438 0.566235 0.360100 -0.509218 0.735525 1.198215 0.064044 0.933335) ) ;;; 119 even -------------------------------------------------------------------------------- (vector 119 14.971 (fv 0 1 0 0 1 0 1 0 0 1 1 1 0 1 1 0 0 0 0 0 0 0 0 1 0 1 1 0 0 1 1 1 1 0 0 0 1 1 0 1 0 1 1 1 1 0 1 0 0 1 1 1 1 1 1 0 1 1 1 0 1 0 1 1 0 0 0 1 1 0 0 1 0 1 0 1 0 1 1 1 1 1 1 0 0 1 1 0 0 1 0 0 1 1 1 1 0 1 0 0 0 1 1 1 1 0 0 0 0 1 0 0 1 1 0 1 0 1 1) ;; ce: 11.482774 (fv 0.000000 0.022508 -0.154621 -0.133560 0.019055 0.044006 0.744199 -0.189660 1.646970 0.323873 1.389900 0.872285 1.714451 0.465026 0.101347 1.045318 0.619662 0.299667 0.695492 1.761299 -0.465991 1.247091 0.360217 0.709249 0.270723 1.861018 1.538710 1.394055 1.300550 0.683046 1.420419 1.591103 0.068117 0.694826 0.315654 0.206747 0.551524 0.669546 0.407597 0.609362 1.957764 1.313475 1.269191 1.535059 -0.453483 1.127112 -0.438414 1.098010 0.925063 1.295295 0.349547 1.800021 1.265884 1.210725 1.261945 1.409059 0.031987 1.064471 1.087820 0.131065 1.230087 1.008698 0.646880 1.108562 0.465537 -0.286867 1.491020 1.274669 0.240579 1.517428 0.852795 0.970665 0.563004 0.179967 1.049271 1.080429 0.558118 -0.026181 0.946833 1.033681 0.158731 0.889882 0.983418 -0.020663 1.724961 1.892566 0.743055 1.647217 1.582049 1.007387 1.541602 0.779919 1.494250 -0.227797 0.081916 -0.223533 0.250776 1.270562 1.106978 1.124428 0.217158 1.341937 0.121564 0.628868 -0.092377 1.005391 0.266805 1.036087 -0.286050 1.835950 0.190028 0.634731 1.031073 0.250385 1.062823 1.900473 0.065255 0.789889 1.186094) ) ;;; 120 even -------------------------------------------------------------------------------- (vector 120 15.153992567168 (fv 0 0 1 1 0 0 1 0 1 0 0 1 0 0 1 0 1 1 0 0 1 0 1 1 0 0 1 0 0 0 1 1 1 0 0 1 1 1 0 0 0 0 1 0 0 1 0 0 1 0 1 1 1 1 1 1 1 0 1 0 0 0 0 1 0 1 0 0 0 1 1 0 0 0 1 1 0 0 0 0 0 1 1 0 0 0 0 0 1 0 1 1 1 1 1 1 1 0 0 1 1 1 0 1 1 0 1 1 1 0 1 0 0 0 0 0 1 1 1 0) ;; ce: 11.467293 (fv 0.000000 0.182387 0.991318 1.555550 0.388952 1.165472 1.861486 0.514097 1.467680 0.222754 0.972121 1.805786 0.710465 1.475951 0.467146 1.464916 0.222083 1.170792 0.137691 0.926627 1.940353 0.964985 0.072695 1.174272 0.187090 1.145640 0.255557 1.524936 0.697660 1.793860 0.870660 1.991349 1.164698 0.214289 1.427601 0.920631 0.315825 1.506380 0.771158 0.081551 1.397459 0.660219 0.101946 1.376912 0.742252 1.975042 1.384246 0.994395 0.741688 0.116508 1.476904 0.995545 0.574556 -0.050092 1.395747 1.037641 0.654167 0.178367 0.000799 1.661003 1.401198 1.027447 0.549822 0.319024 -0.009775 1.643655 1.451741 1.190761 1.247596 1.019397 0.814792 0.637301 0.619820 0.528955 0.206546 0.210086 1.907606 0.080551 1.852358 0.220977 0.039775 0.240556 0.118697 0.201230 0.183490 0.410415 0.195004 0.346621 0.384871 0.552316 0.919228 0.966578 1.294194 1.669482 1.481782 1.816544 0.045277 0.459121 0.610971 0.884884 1.313099 1.767978 0.251484 0.557317 0.967847 1.457578 1.608185 1.982656 0.491182 1.030233 1.763557 0.343009 0.756305 1.429088 0.071947 0.646318 1.100378 0.016785 0.234469 0.966926) ) ;;; 121 even -------------------------------------------------------------------------------- (vector 121 14.652157793709 (fv 0 0 1 1 0 0 1 0 0 1 1 0 0 1 0 1 1 1 0 0 0 0 1 1 0 0 1 0 0 0 0 1 0 1 0 1 1 1 1 0 1 1 0 1 1 1 1 0 1 1 0 0 1 1 0 0 1 0 1 0 0 0 0 0 0 0 0 1 1 1 0 1 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 1 1 0 0 0 0 1 1 0 0 1 0 1 0 0 0 1 1 1 0 0 0 1 0 1 1 1 0 0 0 1) ;; ce: 11.519858 (fv 0.000000 0.011378 1.753896 1.437136 0.631135 0.114781 0.660482 1.334498 0.581894 0.089402 1.905979 0.990187 0.248688 0.037998 1.898481 0.142274 0.776484 1.706556 0.191753 0.338054 1.318431 0.126497 0.601712 -0.255350 -0.163162 0.402669 1.476694 -0.235785 0.342102 -0.362582 1.698550 0.968284 0.940716 1.711626 1.326298 1.313163 0.329811 1.359487 0.105165 0.702440 0.022566 -0.069577 1.342187 0.008210 1.716840 0.240520 -0.171785 1.502743 1.676402 1.248370 0.723049 1.865376 0.001307 0.034537 0.684465 1.516715 0.492834 1.116078 0.672438 1.182471 0.641149 0.373795 0.379475 0.145636 0.762178 0.433641 0.347370 0.948832 -0.132296 -0.133379 1.190338 1.266604 1.009701 0.238209 0.752479 1.596905 -0.296398 -0.192578 0.605136 0.075081 1.420344 0.466284 -0.288768 1.297330 1.689017 1.567153 1.185252 0.260951 0.236638 1.431783 0.599599 1.509650 0.653104 0.899471 1.457027 1.068607 0.961380 1.256645 0.033616 -0.139517 0.092125 1.417841 1.213189 1.821992 1.761054 0.238734 0.417918 0.642844 -0.104823 0.081427 0.065359 0.670607 1.054994 1.082441 -0.176585 1.119180 -0.224101 0.108660 -0.203752 0.470242 1.351870) ) ;;; 122 even -------------------------------------------------------------------------------- (vector 122 15.057187309653 (fv 0 0 1 0 1 0 1 1 0 0 0 0 1 1 1 1 0 0 1 1 1 1 0 0 1 0 0 1 0 0 0 1 1 0 1 0 1 0 1 1 1 1 1 0 0 0 0 1 1 1 1 1 0 0 1 0 0 1 0 1 1 0 1 1 1 1 1 1 1 0 1 0 1 1 0 1 1 0 1 1 1 0 0 0 1 0 1 1 1 0 1 0 0 0 1 0 0 0 1 1 0 1 0 1 1 0 0 0 1 0 0 0 0 1 0 0 0 1 1 1 1 1) ;; ce: 11.608575 (fv 0.000000 0.491043 0.007498 0.791398 0.660542 0.960014 1.233279 1.608131 1.227878 1.325414 0.833262 0.826707 1.074054 0.805872 0.453534 0.680408 0.163876 1.857437 1.971814 1.942244 1.528127 1.170281 1.451447 1.612886 0.379280 0.469353 0.748640 0.861019 0.289879 1.554726 0.245277 0.578277 0.944303 0.525039 0.312641 0.462849 0.710444 0.524042 0.736659 1.743905 0.289146 1.405383 1.146345 1.959424 1.266837 0.105168 0.264372 0.716079 0.180416 0.676462 1.349909 0.242201 1.112324 1.903652 0.096097 0.298665 1.938506 0.907637 0.445138 0.676772 1.018566 1.538692 1.890411 1.037889 1.754475 0.454828 0.375080 1.028535 1.584256 0.107387 0.732227 1.941438 0.410085 0.465514 0.392267 1.461968 0.104792 1.428078 0.866762 0.928264 0.963879 0.060101 0.001979 1.538408 1.110694 0.832374 1.363340 1.030944 1.856655 0.680542 1.663245 1.268139 0.925891 1.913766 1.292282 1.484272 0.663172 0.251878 0.695143 1.443461 0.967688 0.177908 1.246199 1.066133 0.923551 1.951433 0.308206 1.532986 1.662559 1.880618 0.612432 0.084712 1.836918 1.410469 0.509104 0.078690 0.955183 1.487132 0.007102 1.473132 0.898543 1.722166) ) ;;; 123 even -------------------------------------------------------------------------------- (vector 123 15.156582832336 (fv 0 0 0 1 1 0 1 0 0 0 0 0 1 1 0 0 1 0 1 0 1 0 0 0 0 0 0 1 1 0 0 0 1 1 1 0 1 0 1 1 1 1 0 0 0 1 1 1 1 1 0 1 0 1 1 1 0 1 1 0 1 0 0 1 0 1 1 0 1 0 1 1 1 1 0 0 1 1 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 1 1 0 0 1 0 1 1 1 0 0 1 0 0 0 0 1 1 0 1 0 0 0 1 1 0 1 1 1 0) ;; ce: 11.636238 (fv 0.000000 -0.006745 1.718129 0.124324 0.694087 1.248162 1.264742 -0.205335 0.401180 1.175941 1.275199 0.664232 1.306473 1.775017 0.032088 1.172990 1.182530 1.684652 1.496052 1.018965 1.419875 1.724105 0.881080 0.365436 1.623371 0.118184 1.144470 1.090686 0.455215 1.110091 1.537843 1.409976 0.722528 0.766713 0.291253 1.154526 0.688621 0.079128 0.455767 1.072502 0.449509 1.072583 0.529271 0.933123 1.665962 0.456257 0.965966 0.378656 1.446789 1.599052 -0.405591 0.510787 1.741784 0.047873 1.179439 0.534603 0.738060 1.583394 -0.036662 0.033912 0.990276 0.359185 -0.041714 1.309428 0.206155 0.615264 1.013822 0.916642 1.092385 1.276567 0.943657 1.397941 1.325784 1.841099 0.255550 0.983848 0.698027 0.630229 0.444618 1.485280 0.538087 1.172707 0.510703 0.139282 1.060931 1.974722 0.748366 1.241445 1.282543 1.643915 -0.055670 1.226488 1.259535 1.054944 0.867004 1.180445 0.871590 -0.304557 0.449098 0.105044 0.415180 1.325658 1.915647 1.593801 1.274805 -0.206650 -0.888906 0.385364 0.203928 0.267603 1.679470 1.529346 0.775016 1.650475 0.752800 0.231942 -0.128889 1.695246 -0.352686 0.872132 -0.113288 1.107634 0.969190) ) ;;; 124 even -------------------------------------------------------------------------------- (vector 124 15.192802705519 (fv 0 1 0 1 0 0 0 0 0 1 1 0 0 0 0 1 0 1 1 1 0 0 0 0 0 0 1 0 1 0 0 1 1 0 1 1 0 0 0 1 0 1 0 1 0 0 0 1 1 1 1 0 1 1 0 0 0 1 1 1 1 1 1 1 0 0 1 0 0 1 1 1 0 1 0 1 1 1 1 0 0 1 0 0 1 1 1 1 1 0 0 0 1 0 0 0 0 1 1 1 0 0 1 0 1 1 1 1 1 0 1 1 1 0 1 0 0 1 0 1 0 0 1 0) ;; ce: 11.657070 (fv 0.000000 -0.014444 0.618588 1.072923 1.770483 0.269156 0.799491 1.415133 0.042486 0.667402 1.107625 1.860582 0.629761 1.228415 0.069647 0.757140 1.477152 0.235584 0.874179 1.620964 0.498598 1.283127 0.032336 0.931298 1.753048 0.690202 1.655180 0.637473 1.388106 0.380043 1.352876 0.417570 1.513619 0.398780 1.331736 0.297986 1.356056 0.723808 1.880303 1.075552 0.270324 1.454538 0.409485 1.419750 0.727467 0.088163 1.085380 0.180158 1.411841 0.476674 0.009315 1.487690 0.712294 -0.024891 1.362496 0.659010 -0.191074 1.370827 0.842745 0.281346 1.600375 1.056928 0.756127 0.303601 1.748097 1.271638 0.793604 0.293922 -0.112046 1.276835 1.265355 0.825565 0.530280 0.127474 1.794406 1.661127 1.499821 1.002415 0.662420 0.351459 0.106647 -0.108853 1.731304 1.778120 1.591760 1.488839 1.111393 1.249609 0.941574 1.119732 0.633391 0.859266 0.602796 0.706230 0.723444 0.862387 0.960018 1.160855 0.914474 1.092081 1.010153 1.292261 1.124565 1.486704 1.752791 1.765950 0.121592 0.301316 0.732598 0.775797 0.931505 1.227451 1.354358 1.806530 0.301686 0.668653 0.912777 1.521847 -0.005389 0.243631 0.695894 1.356048 1.421601 -0.009388) ) ;;; 125 even -------------------------------------------------------------------------------- (vector 125 15.340427254326 (fv 0 1 0 0 1 1 1 0 1 1 1 1 0 1 1 1 1 0 0 1 1 1 1 1 1 0 1 0 1 1 0 1 0 0 0 1 1 1 1 1 0 1 0 1 0 0 0 0 0 0 0 1 1 0 0 1 0 0 1 1 1 0 0 0 0 1 0 0 1 0 0 1 0 1 0 1 1 1 1 0 0 0 0 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 1 1 0 1 1 1 0 0 0 1 1 1 1 0 1 1 0 0 0 1 0 1 0 1 0 0 0) ;; ce: 11.726117 (fv 0.000000 -0.030799 0.144449 1.728737 0.676919 0.980768 0.920869 0.523856 0.255848 1.651421 0.139364 0.110259 -0.007857 -0.065476 0.898902 0.948218 0.041888 0.431499 0.955394 1.279597 0.899810 0.236632 1.338434 0.051979 0.022413 1.076247 0.455727 1.395710 0.537276 1.454562 -0.640673 1.646766 0.563227 0.468669 0.349014 0.207631 1.436456 -0.313434 1.039871 1.394849 1.334026 0.410015 0.714625 0.314535 0.295044 0.730112 0.878789 0.469330 0.349941 1.427732 0.501996 1.482747 1.311352 1.023386 -0.133711 0.934640 1.777275 0.139714 0.307620 0.411617 0.680605 1.805628 0.987833 -0.006267 1.325295 0.129226 0.029571 -0.131946 1.571497 0.134896 1.855074 0.957063 1.276873 0.033353 0.738862 1.196621 0.702473 1.212401 0.334974 0.594964 -0.391144 1.491428 1.659733 1.324319 0.593336 1.121378 1.836235 -0.494188 -0.410122 0.669230 1.852484 1.550441 0.612411 1.088978 0.233243 0.429977 0.213254 1.111633 0.529727 1.280152 1.687453 0.208804 0.661537 0.543046 1.373269 -0.302027 0.236049 0.167939 1.751438 0.754446 0.306753 -0.393681 0.981979 0.613716 0.543141 0.783701 1.211717 0.696576 0.743400 0.902651 1.308022 0.648265 1.051117 0.596115 0.465417) ) ;;; 126 even -------------------------------------------------------------------------------- (vector 126 15.28212621738 (fv 0 1 0 1 1 0 1 1 0 1 1 1 1 0 1 1 1 1 1 0 1 1 0 0 0 1 0 1 1 1 0 0 1 1 1 0 1 0 0 1 1 1 1 0 1 1 0 0 1 0 0 0 1 0 0 1 1 1 1 1 0 0 0 1 1 1 1 0 0 1 1 1 0 1 0 1 1 0 0 1 1 1 1 1 1 1 0 0 0 0 0 1 0 1 0 1 1 1 1 0 0 1 1 1 0 1 1 0 1 0 0 1 0 0 1 1 1 0 1 0 0 0 0 0 1 1) ;; ce: 11.728732 (fv 0.000000 0.080423 0.859652 1.251285 0.001006 0.708480 1.329479 1.910986 0.575680 1.212005 1.941153 0.634379 1.324750 0.149467 1.036506 1.708281 0.612012 1.577838 0.338405 1.197595 0.029554 0.897812 1.895059 0.811840 1.778431 0.660286 1.607791 0.800800 1.947497 0.840295 1.874911 0.873100 1.809637 0.999296 0.039834 1.184996 0.352552 1.522062 0.693733 0.018959 1.247028 0.457540 1.699479 1.003229 -0.011631 1.387625 0.675778 1.873479 1.137263 0.739657 0.006673 1.350424 0.946270 0.348539 1.590673 1.018988 0.508851 1.844396 1.236918 0.897127 0.426111 1.973108 1.634669 1.217265 0.734120 0.464551 1.899258 1.421045 1.113676 0.840738 0.386615 0.153879 1.864697 1.811230 1.560296 1.258544 1.008246 0.775514 0.569961 0.379626 0.120794 0.073632 1.824999 1.979635 1.804273 1.934045 1.809824 1.823348 1.667350 1.525160 1.703620 1.223510 1.668539 1.353060 1.680931 1.768624 1.959157 0.014225 0.272244 0.168722 0.385113 0.365860 0.784448 0.739738 0.967615 1.309874 1.705334 0.092760 0.302680 0.844130 0.978941 1.342601 1.583162 1.784704 0.228093 0.608194 1.171628 1.840667 0.207453 0.811900 1.464070 1.557525 0.111382 0.715963 1.219826 1.691486) ) ;;; 127 even -------------------------------------------------------------------------------- (vector 127 15.237931718393 (fv 0 0 0 1 0 0 0 0 1 1 0 1 1 1 1 1 1 0 0 1 1 0 0 1 1 1 0 0 1 0 1 0 0 1 1 1 1 1 0 1 1 0 0 0 1 0 1 1 0 1 0 1 1 0 1 0 1 0 1 0 0 0 1 1 0 0 0 0 1 0 0 1 1 0 1 0 1 0 0 1 1 1 1 1 1 1 0 0 0 1 1 1 0 0 0 0 0 1 1 1 0 1 0 1 1 0 0 1 0 0 1 0 0 1 1 0 1 0 0 0 0 1 0 0 0 0 0) ;; ce: 11.791982 (fv 0.000000 -0.006501 0.895946 0.390502 1.267039 0.777220 0.845244 1.619366 1.738905 1.963883 0.834239 -0.095420 1.729892 0.328487 0.839467 -0.107042 0.077371 1.006289 0.934388 1.316468 0.399445 1.446071 0.867321 0.749721 0.310809 0.608045 0.928981 0.860186 0.132975 0.107680 0.035103 0.310673 1.698683 1.209244 1.219344 1.008158 0.868768 0.774429 0.524607 1.259150 0.968654 0.225551 0.670254 0.584349 1.206486 0.849939 0.881353 1.316256 1.223028 -0.051550 1.266841 0.533270 0.307133 0.871408 0.135067 0.350791 1.392175 1.398704 1.054665 1.094835 0.720758 1.235433 1.111126 1.315441 0.540735 1.759697 1.421149 1.220945 1.416174 0.271820 0.476065 0.346906 0.599580 1.865670 -0.010232 0.873428 0.191144 -0.138143 0.473276 0.793750 0.140345 0.466125 0.753788 0.166751 0.509961 1.311817 1.848999 0.485052 0.151803 1.266182 1.022497 -0.055512 1.662000 1.747291 0.161074 0.983665 1.511467 0.958919 1.602506 1.536897 -0.682895 0.108054 0.153831 0.495344 -0.168193 1.039701 1.035352 0.840794 0.198694 1.029171 0.222780 1.379441 0.220019 1.296462 0.080553 0.616328 1.212980 -0.006268 1.810129 0.820776 0.816381 1.107475 0.666818 -0.087937 0.128508 1.246653 0.713705) ) ;;; 128 even -------------------------------------------------------------------------------- (vector 128 15.651492555885 (fv 0 0 0 1 0 0 1 0 0 1 1 1 0 1 1 1 1 0 1 1 1 1 0 0 1 1 0 0 0 1 0 1 1 0 1 0 1 0 0 1 1 1 0 0 0 0 0 1 1 0 0 0 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 0 1 0 1 1 1 0 1 1 0 1 1 0 1 1 0 0 1 0 1 0 1 0 1 0 1 1 1 1 1 0 1 0 0 0 0 1 0 1 0 1 1 0 0 1 1 0 0 1 0 0 0 0 1 0 1 0 1 1 0) ;; ce: 11.856765 (fv 0.000000 0.002702 1.085974 1.244165 0.302147 1.259231 0.307623 1.789071 0.248647 1.161010 1.314907 0.079451 1.835817 1.698549 1.371220 1.062438 -0.405684 -0.007858 1.415666 0.290877 1.615872 1.200022 1.723864 1.253269 0.379007 0.343005 0.128516 0.302246 -0.164454 0.039402 1.245595 0.229693 0.371762 0.212878 1.130208 0.211997 1.630376 0.731113 -0.271994 0.633039 1.003806 0.078215 0.728092 1.810709 1.419272 0.630789 0.702176 0.258274 1.627944 0.906125 1.142708 1.149739 0.327453 0.775766 1.891018 0.949407 1.868463 0.197100 0.436054 0.455859 1.396494 1.235603 1.184602 0.213251 0.192580 1.964426 0.843243 1.673738 -0.209417 -0.268734 0.946608 0.413048 1.382483 0.177431 0.571412 0.488003 0.422161 0.038021 -0.036166 0.871695 -0.124327 0.115262 1.774007 1.705740 -0.048183 0.114070 0.284773 0.198720 1.083200 1.095261 1.210900 1.153612 1.411655 -0.216841 0.226895 0.871232 1.590562 1.732972 1.482631 1.243964 0.261758 -0.017247 1.413734 0.786022 0.083529 1.333636 0.641441 1.707810 0.335402 0.567273 1.111144 1.682879 0.513761 1.029576 1.342257 1.314503 1.650528 0.559848 0.478412 -0.031753 0.050313 0.117019 1.542665 0.315940 1.287375 1.423028 0.248383 1.516714) ) ;;; 256 even -------------------------------------------------------------------------------- (vector 256 24.434719362486 (fv 0 1 1 0 0 0 0 0 0 1 1 0 1 0 0 0 1 1 1 0 1 1 0 1 0 1 1 1 1 0 1 0 0 1 1 0 1 0 1 1 0 1 1 0 0 1 1 1 1 0 0 0 0 1 1 1 0 1 1 1 1 0 0 1 0 1 0 1 1 0 1 1 0 0 1 0 1 0 0 1 1 0 0 0 0 1 0 1 1 1 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 1 0 0 0 0 1 0 1 0 1 0 0 0 1 0 0 0 1 0 1 1 1 1 0 1 0 0 0 1 1 1 1 0 1 1 0 0 0 0 0 1 1 0 0 1 0 0 1 1 1 0 0 0 0 1 1 0 0 0 1 0 0 0 1 1 1 1 1 0 0 0 0 0 0 1 0 0 0 1 0 0 0 1 0 1 1 0 0 1 1 1 1 1 1 0 1 1 1 0 0 0 1 0 0 1 1 1 0 0 1 1 0 0 1 0 0 0 1 1 1 0 1 1 1 0 0 0 1 1 1 0 0 1 0 1 0 0 1 0 0 1 0 0 0 0 1 1 0 1 1 1) ;; ce: 16.895858 (fv 0.000000 -0.009189 0.902358 0.365887 -0.111323 -0.780998 -0.023618 -0.522343 0.279380 0.055265 -0.008058 0.474170 0.130008 0.951121 -0.734333 0.844285 0.824339 -0.107239 0.507621 0.164958 -0.496056 -0.789687 0.259333 -0.449818 0.843661 -0.030179 -0.474099 0.774618 -0.182868 0.024412 0.577418 -0.074812 -0.020675 0.192634 -0.599606 -0.070169 -0.948055 -0.992660 0.778395 -0.043578 -0.432579 -0.186685 -0.510874 -0.014069 -0.480270 0.346549 0.508024 0.846868 -0.259984 -0.239547 -0.834355 0.758428 0.757435 0.373609 -0.602450 0.574091 0.372351 0.871018 -1.004894 0.279914 0.796533 0.315579 -0.170724 -0.162430 -0.867211 -0.645076 0.714848 -0.271719 0.114112 0.067143 0.832100 -0.116990 -0.262191 -0.281235 -0.535795 0.830911 -0.182047 0.489779 0.867411 0.246384 -0.008329 -0.604672 0.770953 -0.982833 0.931441 -0.618590 -0.552932 0.209497 -0.183212 0.365740 0.769646 0.703588 -0.289040 -0.817528 -0.369365 0.293481 0.472048 0.790519 -0.426911 0.891352 -0.538143 -0.944128 -0.920976 0.221321 -0.509927 -0.348596 -0.644560 -0.213342 -0.745624 -0.706666 0.930922 -0.848273 -0.242448 -0.036301 0.898791 -0.590640 0.780449 -0.061417 0.458673 -0.691004 -0.831524 0.551686 0.225320 0.474068 0.953196 -0.781398 0.825342 0.760168 0.391595 0.124100 0.860713 -0.055973 0.585971 -0.869796 1.059960 -0.289476 -0.119142 0.020537 -0.912617 0.156202 0.608148 0.008605 -0.492103 -0.103742 0.428971 0.411193 -0.565692 0.935156 -0.112585 0.617223 -0.155032 0.327195 0.230999 -0.493871 -0.157653 0.741876 0.652071 0.725265 -0.509926 -0.435321 0.803678 0.422316 0.647203 -0.330251 -0.717114 -0.003821 -0.171433 0.905326 -0.870296 -0.075782 -0.123811 -0.827857 0.305695 -0.297883 0.361037 0.368875 0.307670 -0.861180 0.111296 0.743619 -0.505788 0.890369 -0.751559 0.768455 0.001867 -0.755119 0.593706 0.249715 0.003021 0.017365 -0.006817 0.077961 0.209405 -0.908703 -0.016914 0.016411 -0.745949 -0.862316 0.805206 -0.373876 -0.644818 0.552974 -0.723400 0.564147 0.221354 0.241461 -0.891285 0.457125 0.981689 -0.591672 -0.034527 -0.765054 -0.120687 0.438528 0.848881 -0.507062 0.069395 0.639313 -0.825275 0.641684 -0.188946 0.565634 -0.791635 -0.287596 -0.132874 -0.202513 0.559214 0.080018 0.796540 0.338441 0.210736 0.641999 0.009248 0.322360 -0.028925 0.697480 0.479428 0.122723 0.885702 -0.174527 0.157389 0.019802 0.207762 -0.007817 -0.188184 0.284891 0.769384 -0.699713 -0.860470 0.816560 0.661637 0.821235 0.090760 0.680062 0.906877 -0.017234) ) ;;; 512 even -------------------------------------------------------------------------------- (vector 512 35.776 (fv 0 0 1 1 0 1 0 1 1 1 1 1 1 0 1 1 1 0 1 0 0 0 0 1 0 0 1 0 0 1 1 0 0 0 0 0 0 1 0 1 1 1 1 1 0 0 1 1 0 0 1 0 1 1 1 0 1 1 1 1 0 0 0 1 1 1 1 0 1 0 1 0 0 0 1 1 0 1 1 0 0 1 1 1 1 1 0 1 0 1 0 1 0 1 0 0 1 0 1 0 1 1 0 1 1 1 1 0 1 1 1 1 1 0 1 0 1 1 1 1 0 1 1 1 0 1 1 0 1 0 0 0 0 0 1 0 0 0 1 1 0 0 1 1 1 1 1 1 1 0 0 1 0 1 1 0 0 0 0 0 1 1 1 1 1 0 0 1 1 1 1 0 1 1 1 0 1 0 1 1 0 1 1 0 0 0 1 1 0 1 1 1 0 1 1 1 1 0 1 0 1 0 1 0 0 0 1 0 1 0 1 1 1 1 1 1 1 1 0 1 1 0 1 0 0 1 1 0 0 0 0 1 0 0 1 0 1 1 0 1 0 0 1 1 1 0 1 1 0 1 0 0 0 0 0 0 0 1 1 0 1 1 0 1 0 1 1 0 1 1 1 0 0 1 0 1 1 0 0 1 1 1 0 1 1 0 0 1 0 0 0 1 1 0 1 1 0 0 1 1 0 0 0 0 0 0 0 1 1 0 0 0 1 1 0 1 0 1 1 0 1 0 1 0 1 1 0 1 0 1 1 1 0 1 0 1 1 1 0 1 0 0 0 1 0 0 1 0 0 0 0 0 1 1 0 1 0 0 0 1 0 1 0 1 1 1 0 0 0 0 0 1 1 1 0 0 1 0 1 1 0 0 1 0 0 1 1 1 1 1 1 1 1 1 1 0 1 0 0 1 0 1 1 0 1 1 1 1 1 1 0 0 0 1 1 1 0 1 1 1 1 1 1 1 1 1 0 0 1 1 0 0 0 0 1 1 0 1 1 1 0 0 1 0 1 1 1 1 0 1 1 0 0 1 1 1 0 0 1 1 0 0 0 0 0 1 1 1 1 1 0 1 0 0 0 0 1 0 1 1 1 0 0 1 0 0 1 0 0 0 0 1 1 1 0 0 1 0 0 0 1 1 0 1 1 1 1 1 1 0 0 1) ;; from (try-all :even 512 513 0.0057725498034576 0.26769012113045) = 29.0733 ;; ce: 24.510365 (fv 0.000000 -0.019547 0.424156 1.640830 1.364680 1.818776 1.105842 0.737080 1.188869 0.460419 0.154877 0.614397 1.827954 1.526781 0.018169 1.203682 0.956144 1.444331 0.584264 0.344508 0.856804 -0.002275 1.790988 0.291010 1.439116 1.211881 1.741084 0.845603 0.707294 1.180635 0.339890 0.164786 0.645301 1.820612 1.656940 0.157290 1.307936 1.130965 1.686613 0.833679 0.620052 1.209627 0.322209 0.138398 0.734419 1.838268 1.653494 0.235420 1.341020 1.194471 1.729004 0.905361 0.771623 1.262727 0.487832 0.366383 0.843119 0.069579 1.963835 0.460118 1.649699 1.520680 0.055018 1.185740 1.101098 1.643899 0.752530 0.667948 1.169078 0.382792 0.269771 0.820501 0.061364 1.929744 0.493658 1.740499 1.549752 0.138458 1.334798 1.217842 1.724754 0.932476 0.823652 1.326258 0.605394 0.510375 1.024728 0.340933 0.185795 0.774497 0.036705 1.862931 0.456043 1.668642 1.590302 0.139925 1.318436 1.326961 1.864132 1.011509 1.051965 1.624689 0.808072 0.775618 1.339118 0.606082 0.484361 1.076072 0.379297 0.250899 0.852275 0.110682 0.007792 0.595200 1.830378 1.789905 0.359788 1.659536 1.611286 0.154864 1.497402 1.399711 1.998779 1.270070 1.199870 1.801564 1.085483 1.010139 1.613933 0.921049 0.862702 1.434888 0.750644 0.728545 1.284532 0.570978 0.570652 1.118882 0.422457 0.414420 0.977086 0.320768 0.330042 0.881914 0.218609 0.199085 0.805391 0.088964 0.043485 0.695205 -0.000491 1.966513 0.612316 1.930538 1.950727 0.563038 1.854742 1.879285 0.451929 1.795108 1.794421 0.370361 1.783471 1.745602 0.399279 1.738776 1.661161 0.350902 1.625174 1.614568 0.302843 1.577093 1.678861 0.313770 1.663823 1.660571 0.328157 1.709209 1.610846 0.310206 1.720381 1.669108 0.335355 1.656296 1.693491 0.346281 1.654195 1.699773 0.373651 1.773772 1.752470 0.473140 1.826907 1.822715 0.581620 1.832675 1.919552 0.622630 1.929526 0.005176 0.677897 0.085092 0.090877 0.761048 0.206124 0.205634 0.890197 0.304835 0.339949 1.002646 0.395940 0.448746 1.152273 0.561345 0.581101 1.310704 0.737714 0.744961 1.486545 0.848210 0.931544 1.627529 1.007712 1.110684 1.778206 1.199087 1.278685 -0.040639 1.383705 1.405450 0.148513 1.511196 1.633778 0.391073 1.740722 1.849679 0.658438 0.031218 0.137149 0.870371 0.331222 0.296051 1.070588 0.528400 0.591834 1.345092 0.751955 0.829846 1.642139 1.030239 1.201544 1.943718 1.298486 1.407002 0.143893 1.607481 1.695116 0.415675 1.905744 -0.027620 0.742513 0.206291 0.320377 1.123679 0.506496 0.647078 1.425059 0.880594 0.962991 1.736110 1.225483 1.369479 0.064842 1.600531 1.706861 0.517054 1.973656 0.069623 0.837048 0.295925 0.404900 1.263222 0.684812 0.775618 1.577141 1.057937 1.264522 0.064638 1.531997 1.682245 0.471443 1.922985 0.104388 0.897292 0.423113 0.526550 1.412335 0.758158 0.917306 1.736464 1.285171 1.451805 0.278569 1.745150 1.879876 0.677038 0.183709 0.366812 1.118883 0.736257 0.864386 1.688806 1.159516 1.253423 0.100375 1.645658 1.871576 0.762011 0.249411 0.395560 1.273133 0.699592 0.948774 1.805372 1.338330 1.530595 0.294092 1.900787 0.034538 0.923012 0.390364 0.586314 1.386265 1.030145 1.202559 0.071001 1.609371 1.743831 0.671235 0.194183 0.391537 1.251984 0.751826 1.009573 1.860932 1.448367 1.525073 0.422286 -0.073409 0.262981 1.099563 0.626545 0.818453 1.723102 1.361444 1.531582 0.390953 1.909101 0.215438 1.139977 0.737652 0.881882 1.821234 1.380301 1.618894 0.473317 0.045322 0.250969 1.146414 0.800355 0.959156 1.857842 1.429019 1.673847 0.622261 0.184525 0.502145 1.323715 0.914639 1.172552 0.096636 1.761155 1.977345 0.871966 0.396190 0.668483 1.677724 1.221155 1.466337 0.368967 0.009966 0.302335 1.180746 0.786475 1.025502 -0.022711 1.584463 1.830638 0.746555 0.413840 0.650268 1.656745 1.224810 1.557055 0.513491 0.173029 0.435007 1.290629 0.926051 1.263115 0.272344 1.896521 0.084566 1.048863 0.725520 0.987362 -0.027617 1.571108 1.900984 0.869809 0.386916 0.758635 1.730437 1.409025 1.672233 0.588812 0.243929 0.511763 1.494695 1.169935 1.437757 0.431437 0.111507 0.458811 1.437247 1.136523 1.434884 0.401589 0.040030 0.372128 1.370962 0.999488 1.378913 0.377301 -0.009324 0.355264 1.331258 1.008855 1.339035 0.373593 0.044480 0.312196 1.329497 1.000220 1.342701 0.417261 0.083063 0.411303 1.346062 1.090657 1.409862 0.373501 0.211768 0.447452 1.458597 1.131955 1.458774 0.553807 0.205989 0.569249 1.645656 1.188483 1.668112 0.674809 0.371651 0.732131 1.751447 1.522458 1.904784 0.884407 0.617430 0.990830 0.073047 1.730004 0.133217 1.189522 0.869836 1.203019 0.328634 0.051596 0.424552 1.471161 1.210755 1.549745 0.605989 0.343260 0.768857 1.816839 1.581320 1.934635 1.014299 0.737558 1.116115 0.236955 0.018173 0.380416 1.539634 1.251595 1.652099 0.829587 0.536746 0.936033) ) ;;; 1024 even -------------------------------------------------------------------------------- (vector 1024 51.895 (fv 0 1 0 0 0 1 1 0 0 0 0 1 0 1 0 1 1 1 1 0 1 0 0 1 0 1 0 1 1 1 1 0 1 1 1 1 1 0 1 1 0 1 1 0 0 1 1 1 1 0 1 0 1 0 0 1 0 0 1 1 1 0 1 1 0 0 1 0 1 1 1 0 0 1 0 0 0 0 1 1 0 1 1 0 1 0 0 0 0 1 0 0 0 1 1 1 1 0 1 0 1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 1 0 1 1 0 1 0 0 1 1 1 0 1 1 0 0 0 1 1 1 0 1 1 1 0 0 0 0 0 1 1 0 1 1 1 1 0 1 0 1 1 1 0 1 0 1 0 1 1 0 0 0 1 0 1 1 1 0 1 0 1 1 0 1 0 0 0 0 0 0 1 1 1 0 1 0 0 1 1 1 1 0 0 0 0 0 0 1 0 1 0 0 1 1 0 1 0 1 1 1 0 1 0 1 0 1 0 0 0 0 1 1 1 1 0 1 0 1 1 1 1 1 0 0 1 0 1 0 1 0 1 0 1 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 1 0 1 1 1 0 1 1 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 1 0 1 1 1 0 1 1 0 1 1 1 0 0 1 1 0 1 0 0 0 0 0 0 1 1 0 0 1 1 1 0 1 0 1 0 0 1 0 0 0 1 0 0 1 1 1 1 1 1 0 1 0 0 1 1 0 0 1 0 1 0 0 1 1 1 1 0 1 0 0 0 1 1 1 0 0 0 0 1 0 0 1 1 1 0 0 1 0 1 0 1 0 1 0 1 1 1 0 1 1 0 0 1 1 0 0 0 0 0 1 0 1 0 0 0 1 0 0 0 1 0 1 1 1 0 0 1 1 0 1 1 0 1 1 1 1 0 0 1 0 0 1 1 1 0 1 0 0 0 1 1 1 0 0 0 1 0 1 0 1 1 1 1 1 1 0 0 1 1 1 1 0 1 0 1 0 0 1 1 1 1 0 0 1 1 1 0 0 0 0 1 0 1 0 0 1 1 1 1 1 0 0 0 0 1 0 1 0 1 0 1 1 0 0 1 0 0 1 1 0 0 0 1 0 0 1 0 0 0 0 1 1 1 1 1 1 0 0 0 0 1 0 1 0 0 0 1 0 0 1 0 0 0 1 1 0 1 0 0 1 0 1 1 1 0 0 0 1 1 1 0 1 0 1 0 0 1 0 1 1 0 1 0 0 1 1 0 0 0 1 0 1 1 0 1 1 1 1 0 1 0 0 0 0 1 1 1 0 1 1 0 0 1 1 0 1 0 1 1 1 1 1 1 1 1 0 0 0 1 0 0 1 0 0 1 1 1 1 0 0 0 1 1 1 1 1 0 1 0 0 0 1 1 0 0 1 0 0 0 1 0 0 1 1 0 0 1 1 0 1 0 0 0 0 0 1 0 0 1 1 0 0 0 0 1 1 0 0 1 1 1 0 1 1 1 0 1 0 0 0 1 0 0 1 0 0 0 0 0 1 1 1 1 0 0 0 0 0 1 0 0 1 1 1 1 1 1 1 0 1 0 1 0 0 0 0 1 0 0 1 0 0 0 1 0 1 0 0 1 0 1 0 0 1 0 0 0 0 1 1 1 0 1 1 1 1 1 0 0 0 0 1 1 1 0 0 1 0 0 1 1 1 1 0 0 1 0 0 0 1 0 1 1 1 1 1 0 0 0 0 1 0 1 0 1 0 0 1 0 0 1 1 1 0 0 1 1 0 0 1 1 1 1 0 1 0 1 0 0 0 1 1 0 1 0 0 0 1 0 0 1 1 1 1 0 0 1 1 0 0 0 1 0 0 1 0 1 1 0 1 0 0 0 1 0 1 0 1 0 0 0 1 0 1 1 0 1 0 1 0 0 1 0 0 0 0 1 1 0 1 1 1 1 1 1 1 0 0 1 1 1 1 1 0 0 0 0 0 1 0 0 1 0 0 1 1 1 0 0 1 0 0 0 1 1 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 1 0 1 0 1 0 1 0 1 1 1 0 1 0 1 1 0 0 1 1 1 1 1 1 1 1 1 0 0 1 1 0 0 1 1 1 0 0 1 1 1 1 1 0 1 0 1 1 1 0 0 1 0 0 0 1 1 1 0 0 1 1 1 1 1 0 1 0 1 1 0 0 0 1 1 0 0 1 0 1 1 1 0 0 1 1 1 1 0 0) ;; ce: 34.486667 (fv 0.000000 0.010065 0.257552 0.593803 0.986349 1.354691 1.689002 0.065945 0.448419 0.795563 1.178916 1.585370 1.936149 0.310262 0.750710 1.056729 1.463725 1.825064 0.240816 0.539819 0.934214 1.340840 1.748800 0.092213 0.555713 0.915825 1.311840 1.650847 0.107697 0.477455 0.875194 1.288435 1.748432 0.197793 0.591516 1.015839 1.387092 1.854496 0.260210 0.614591 1.088807 1.497165 1.960609 0.347241 0.837150 1.265241 1.711792 0.103196 0.588662 1.043276 1.427385 1.898809 0.315073 0.790510 1.283232 1.726769 0.124226 0.582532 1.048754 1.444755 1.928781 0.425680 0.899080 1.335881 1.855991 0.327701 0.850115 1.267294 1.746464 0.254433 0.681023 1.221402 1.713475 0.176608 0.633457 1.170011 1.638469 0.136940 0.628672 1.079274 1.611588 0.107068 0.579047 1.125534 1.649825 0.159484 0.714499 1.195717 1.694762 0.283005 0.777095 1.317639 1.818676 0.294685 0.848021 1.366508 1.912960 0.442114 0.974399 1.491097 0.046085 0.607725 1.172318 1.701676 0.262890 0.804042 1.333049 1.847711 0.428372 0.986686 1.556422 0.120990 0.632701 1.249707 1.826221 0.398395 0.969062 1.507301 0.132868 0.725711 1.273823 1.851630 0.403540 1.046615 1.591703 0.182065 0.801530 1.386897 0.003430 0.562296 1.182148 1.798000 0.384640 0.992083 1.618128 0.211791 0.774713 1.389562 -0.001657 0.608366 1.236020 1.865011 0.529780 1.135532 1.738754 0.419570 1.019563 1.624992 0.265061 0.904049 1.533452 0.168181 0.865137 1.479101 0.127557 0.777817 1.390745 0.031342 0.661481 1.347873 -0.028252 0.673301 1.341813 0.012139 0.723533 1.359095 0.015081 0.667348 1.354810 -0.010820 0.651242 1.361901 0.014799 0.676361 1.414902 0.077676 0.777314 1.483046 0.156058 0.835487 1.534362 0.214249 0.944327 1.656367 0.337182 1.061518 1.736952 0.487837 1.221677 1.941805 0.641987 1.334519 0.012624 0.761615 1.493616 0.235055 0.987696 1.681644 0.449481 1.152512 1.880553 0.557489 1.300096 0.093548 0.829304 1.606739 0.333558 1.038662 1.817653 0.564596 1.346595 0.088231 0.789038 1.556219 0.364445 1.109277 1.894547 0.648472 1.394876 0.167696 0.927734 1.744135 0.473122 1.327580 0.053170 0.846408 1.630482 0.424396 1.252576 0.026366 0.794678 1.571738 0.353780 1.148629 -0.009061 0.802059 1.560730 0.388025 1.189760 -0.020908 0.838019 1.634252 0.450483 1.274303 0.061988 0.909080 1.739029 0.567344 1.395698 0.191004 1.056594 1.900321 0.701479 1.570664 0.420443 1.216101 0.035038 0.906051 1.794894 0.619739 1.485033 0.319328 1.177367 0.049998 0.912455 1.796694 0.663275 1.464877 0.322458 1.201076 0.079874 0.975135 1.812753 0.671629 1.550884 0.438265 1.308416 0.227568 1.107771 0.008272 0.852340 1.757258 0.665419 1.573359 0.450697 1.364674 0.288498 1.149330 0.046861 0.927672 1.818815 0.731499 1.703383 0.640630 1.515945 0.404842 1.338883 0.309581 1.223075 0.140786 1.078108 -0.017158 0.933921 1.856585 0.819946 1.718757 0.674573 1.629213 0.552624 1.480565 0.473092 1.440553 0.370780 1.316286 0.261652 1.233065 0.181284 1.136614 0.128844 1.063581 0.043473 0.988622 -0.007730 0.942926 1.896166 0.930670 1.890388 0.822783 1.839642 0.888701 1.829032 0.748117 1.787911 0.785711 1.793168 0.753464 1.768597 0.785917 1.789379 0.746424 1.769933 0.789526 1.789893 0.806228 1.806824 0.845014 1.858918 0.876599 1.887462 0.916183 -0.011424 0.947836 0.026544 1.052806 0.074297 1.092552 0.117837 1.145621 0.172062 1.271069 0.265950 1.343262 0.368273 1.426940 0.471985 1.600258 0.591440 1.643063 0.779963 1.778002 0.823172 1.887460 0.980164 0.056312 1.104881 0.194563 1.270671 0.317598 1.432357 0.527173 1.586831 0.679001 1.710986 0.856576 1.952932 1.034214 0.168860 1.247239 0.332452 1.455153 0.496571 1.598578 0.746454 1.841506 0.980194 0.065850 1.191729 0.313463 1.362280 0.540259 1.674133 0.807281 1.901298 1.046989 0.152754 1.296905 0.437367 1.599457 0.712142 1.832022 1.021052 0.159471 1.255226 0.399699 1.567354 0.776219 1.903366 1.055241 0.221691 1.359842 0.508090 1.682588 0.830923 0.010406 1.164777 0.321654 1.495630 0.648746 1.854778 1.028798 0.224012 1.437178 0.587301 1.746745 0.969426 0.124185 1.311647 0.558251 1.730677 0.926291 0.114111 1.341596 0.557527 1.745728 0.936491 0.127337 1.383134 0.617625 1.786691 1.023246 0.229459 1.472437 0.676585 1.907197 1.123237 0.355057 1.633938 0.880784 0.058692 1.279872 0.552335 1.779394 1.011586 0.276736 1.508029 0.759625 0.024536 1.276380 0.493761 1.728419 1.013811 0.266997 1.523472 0.795713 0.046243 1.307283 0.623236 1.877970 1.148383 0.427672 1.683629 1.001954 0.298274 1.554589 0.835462 0.173731 1.457407 0.693880 -0.034472 1.275602 0.593467 1.866633 1.210093 0.521728 1.772084 1.113712 0.385701 1.695457 1.069859 0.333163 1.607126 0.969652 0.282736 1.586932 0.934788 0.272131 1.571926 0.921386 0.293345 1.575513 0.936770 0.269737 1.574193 0.968165 0.284669 1.613899 0.986360 0.310459 1.654676 0.993511 0.432366 1.747611 1.058842 0.426357 1.800267 1.182611 0.576028 1.923944 1.270340 0.656610 0.044384 1.408707 0.752047 0.170780 1.558617 0.971026 0.315606 1.679451 1.091283 0.469917 1.819954 1.288114 0.668750 0.054741 1.461129 0.888977 0.275646 1.712213 1.100500 0.539170 1.932708 1.357198 0.750588 0.169930 1.599158 1.015737 0.433884 1.847466 1.290316 0.699471 0.106715 1.618980 1.039270 0.483584 1.877301 1.355281 0.739383 0.283415 1.680260 1.142458 0.582946 0.025158 1.503785 0.917235 0.402386 1.888910 1.374775 0.801742 0.267251 1.729725 1.190453 0.690588 0.170200 1.607615 1.116870 0.626944 0.099949 1.558114 1.042989 0.565792 0.001984 1.534796 0.981050 0.506989 0.024697 1.512493 1.045167 0.509838 0.035449 1.540981 1.040413 0.579777 0.067009 1.583544 1.092800 0.643044 0.165297 1.660919 1.190925 0.750261 0.244662 1.789497 1.303951 0.852702 0.402882 1.925637 1.511267 0.983904 0.525287 0.093612 1.625678 1.236625 0.751894 0.317275 1.862598 1.434730 1.003450 0.590395 0.130259 1.632064 1.251831 0.793529 0.395744 1.982905 1.518992 1.185899 0.724078 0.280841 1.851085 1.414649 1.036031 0.628024 0.190307 1.817967 1.407380 0.997638 0.626750 0.187117 1.827944 1.364014 1.005368 0.643575 0.271950 1.870132 1.455625 1.102716 0.663688 0.366474 1.947786 1.531948 1.165389 0.820292 0.417060 0.106203 1.736409 1.349795 1.017056 0.602019 0.247808 1.904232 1.522798 1.168173 0.822339 0.502122 0.190982 1.830461 1.503095 1.146005 0.824132 0.425448 0.163732 1.809535 1.439358 1.134762 0.787451 0.444950 0.125696 1.859821 1.507864 1.225427 0.898766 0.552383 0.249459 1.921771 1.641843 1.335828 1.036153 0.712405 0.407286 0.113814 1.810275 1.573082 1.216807 0.937380 0.622140 0.413886 0.065441 1.811766 1.479615 1.239853 0.962208 0.676221 0.428567 0.149787 1.861526 1.595913 1.378366 1.072254 0.858051 0.546952 0.352387 0.048977 1.781409 1.500802 1.320643 1.034780 0.814060 0.561026 0.270289 0.105077 1.781981 1.587128 1.356228 1.096895 0.899561 0.695426 0.422635 0.191053 0.015040 1.742763 1.540766 1.372440 1.135422 0.929280 0.712972 0.501615 0.300048 0.059338 1.847659 1.743466 1.446302 1.288333 1.097146 0.896394 0.693469 0.504749 0.273709 0.134422 -0.008122 1.752436 1.590209 1.416861 1.263443 1.015309 0.919786 0.724562 0.550733 0.413427 0.220154 0.085059 1.972253 1.758570 1.618664 1.418349 1.309492 1.092633 0.962125 0.822521 0.683138 0.548516 0.433745 0.271343 0.157018 -0.024488 1.878961 1.706051 1.633364 1.472286 1.423267 1.197350 1.130839 0.991815 0.864748 0.717411 0.656940 0.500335 0.378398 0.306249 0.174522 0.042370 1.957239 1.876551 1.787343 1.657177 1.630866 1.501218 1.454476 1.399481 1.281728 1.174679 1.094880 1.013897 0.872646 0.836534 0.733703 0.745572 0.645048 0.520901 0.517442 0.446338 0.403105 0.220915 0.272964 0.177893 0.121891 0.010365 -0.003026 -0.000541 1.946558 1.858421 1.798242 1.770282 1.765566 1.731024 1.646864 1.612063 1.606047 1.594080 1.512626 1.534901 1.459982 1.452555 1.426312 1.441887 1.450640 1.394928 1.401770 1.413824 1.398282 1.361199 1.386696 1.351788 1.315050 1.337782 1.369731 1.375462 1.382434 1.387327 1.390480 1.425063 1.472649 1.428947 1.444989 1.479959 1.454545 1.459856 1.514843 1.537769 1.564144 1.568551 1.669900 1.683717 1.723822 1.813102 1.823001 1.907890 1.890197 1.964939 -1.797036 0.049327 0.116611 0.169727 0.229816 0.312230 0.322585 0.436099 0.459978 0.494355 0.617621 0.657990 0.713966 0.784856 0.873687 0.939607 1.031179 1.056185 1.173421 1.311953 1.410978 1.454966 1.612093 1.676857 1.761378 1.862190 1.974384 0.042558 0.158632 0.245595 0.350975 0.483237 0.594289 0.729058 0.805700 0.959748 1.072984 1.213228 1.313277 1.445492 1.585944 1.673320 1.810642 1.960761 0.110169 0.205253 0.318753 0.449203 0.638254 0.764806 0.903920 1.064434 1.168013 1.366785 1.485581 1.644159 1.803584 -0.028237 0.153100 0.380114 0.509401 0.641451 0.849001 1.016399 1.215481 1.423241 1.573069 1.764733 1.942264 0.047242 0.295850 0.470228 0.640443 0.830347 1.055180 1.227983 1.357851 1.599606 1.739714 -0.029549 0.205220 0.379610 0.585030 0.816103 1.019847 1.251050 1.461935 1.647821 1.868576 0.147180 0.369132 0.579279 0.840715 1.094368 1.320093 1.565710 1.787983 -1.714361 0.195527 0.507750 0.710357 0.949912 1.153061 1.372724 1.700420 1.865502 0.178913 0.436041 0.694461 0.986729 1.187621 1.476665 1.752454 0.027539 0.321199 0.550142 0.802831 1.077337 1.362471 1.620159 1.900867 0.213014 0.446588 0.803703 1.113716 1.403572 1.697697 0.018021 0.315688 0.615559 0.932639 1.205074 1.541734 1.854009 0.125499 0.502519 0.744264 1.071360 1.395926 1.658298 -0.006671 0.333250 0.704886 1.026706 1.348527 1.693526) ) ;;; 2048 even -------------------------------------------------------------------------------- (vector 2048 87.471149563312 (fv 0 0 1 0 1 1 0 0 0 0 1 0 1 1 1 1 0 1 0 1 1 1 1 0 1 0 0 0 0 0 1 0 1 1 1 1 1 0 0 0 1 1 1 0 0 1 0 0 0 1 1 1 1 1 1 0 1 1 0 0 0 1 0 1 0 0 1 1 0 1 1 0 0 1 0 1 1 0 0 0 0 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 0 1 1 1 0 1 1 1 0 0 1 1 1 1 0 1 0 1 0 1 0 0 1 1 1 0 0 1 0 0 1 1 1 0 0 1 1 0 1 1 0 0 0 0 1 1 0 0 1 1 1 0 0 0 1 1 1 0 0 0 1 0 0 0 1 1 0 0 1 0 0 0 0 0 0 0 0 1 0 1 1 0 0 1 0 1 1 1 0 1 1 1 0 1 0 0 1 1 1 1 1 1 0 1 1 1 0 1 0 0 0 0 0 0 1 1 1 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 1 0 1 0 1 0 0 1 0 0 0 0 0 1 1 0 0 1 1 1 0 1 0 0 0 1 1 1 1 0 1 0 0 0 1 1 1 0 0 0 1 1 1 1 0 0 1 0 1 0 1 1 0 1 1 1 1 1 1 0 1 1 1 0 0 0 1 0 1 1 0 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 1 1 0 1 1 1 1 0 0 0 1 1 1 0 0 1 0 0 1 1 0 1 0 0 0 0 0 0 1 0 1 0 0 0 1 0 1 0 0 1 0 0 0 1 1 1 0 1 1 1 0 1 1 1 1 0 1 0 0 1 0 0 1 0 0 0 1 1 0 1 0 1 1 1 0 0 0 1 0 1 0 0 0 1 1 1 1 1 0 0 0 0 0 0 1 1 0 0 1 0 1 1 0 0 1 0 1 0 0 1 1 1 0 1 0 0 1 0 0 0 0 1 0 1 0 0 0 1 0 1 1 1 0 1 1 0 0 1 0 1 0 1 0 0 1 0 1 0 0 0 1 1 0 0 1 1 0 0 0 0 1 1 0 0 0 0 0 1 0 1 0 0 1 1 1 1 0 1 1 0 0 0 0 1 1 0 0 1 0 1 1 1 0 1 1 1 1 0 0 1 0 0 0 0 1 1 1 0 0 0 1 0 0 1 1 1 1 1 1 0 1 1 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 1 1 1 0 0 1 1 1 1 1 1 0 0 1 0 1 1 1 1 1 0 1 0 1 1 1 0 1 1 1 1 0 1 0 1 1 0 0 1 1 1 0 0 0 1 1 1 0 1 0 1 1 1 0 0 0 0 1 0 0 1 1 1 1 1 1 0 1 1 1 0 0 0 0 0 1 1 1 0 0 1 0 1 0 1 0 1 1 0 1 1 0 0 1 0 0 1 1 1 0 0 1 0 1 0 0 0 0 1 1 0 0 1 1 1 0 1 1 0 1 0 1 1 0 1 0 1 1 1 0 0 0 1 1 0 0 0 1 1 0 1 1 0 1 1 0 0 0 0 0 1 0 0 0 0 1 1 0 0 0 1 0 0 1 1 0 1 0 1 0 0 1 0 1 1 0 0 1 1 1 0 0 1 0 0 1 0 1 0 0 1 1 0 0 0 0 1 0 0 0 0 0 0 1 1 1 1 0 1 0 0 0 1 1 0 1 0 1 0 0 0 1 0 1 0 1 1 1 0 1 1 0 0 1 1 1 0 1 1 0 1 1 1 0 0 1 0 0 1 0 0 1 0 0 1 1 0 0 0 0 0 0 1 1 1 0 0 1 0 0 1 1 1 1 0 0 0 1 0 0 1 0 0 1 0 0 0 1 0 1 0 1 1 0 1 0 1 0 1 0 1 0 0 1 0 0 1 0 1 1 0 1 1 0 0 0 1 0 1 0 1 0 0 0 1 0 1 1 1 0 0 1 1 1 0 0 1 0 0 0 0 1 1 0 0 1 1 0 0 0 0 0 1 0 0 1 0 1 1 0 0 0 0 1 1 0 1 1 0 1 0 0 1 0 1 0 0 1 0 1 0 0 0 1 0 0 0 0 0 0 0 1 0 1 0 1 0 1 0 0 1 1 0 1 0 0 0 1 1 1 1 1 1 0 1 1 0 1 0 0 0 0 1 1 1 1 1 0 1 1 1 1 0 1 1 1 0 1 0 0 1 0 1 1 0 0 1 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0 1 1 0 0 1 0 1 1 1 0 0 0 0 1 0 1 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 1 0 1 0 1 0 1 0 0 1 1 1 0 1 0 0 1 1 0 0 0 1 0 0 0 0 1 0 1 1 0 1 1 0 0 0 1 1 1 0 1 0 0 0 0 0 1 0 0 0 0 1 1 1 1 0 0 1 1 1 0 0 0 1 0 1 1 1 1 1 0 0 1 0 1 1 0 0 0 0 1 1 1 0 1 1 1 0 1 1 0 0 0 1 0 1 1 1 0 1 0 0 0 0 0 1 1 0 0 0 1 1 1 1 1 0 0 1 1 0 1 1 1 0 0 0 0 0 0 1 0 0 1 0 0 0 1 1 0 0 1 1 0 0 1 0 0 1 1 1 1 0 1 0 0 1 0 0 1 1 1 0 0 1 0 0 1 1 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 1 0 1 0 0 0 1 1 0 1 0 0 0 0 1 1 0 0 1 1 1 0 1 0 1 1 0 0 1 0 1 1 1 0 1 0 1 0 1 1 0 1 0 0 0 0 1 0 1 0 0 0 1 1 1 1 0 1 1 0 0 1 1 1 0 1 1 0 1 0 1 1 0 0 0 1 1 0 0 1 1 0 0 1 0 1 1 1 1 0 0 1 1 1 1 0 1 1 0 1 0 0 0 1 1 0 1 0 0 0 0 1 0 1 0 0 1 1 0 1 0 0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 1 0 1 1 1 1 1 1 0 1 1 0 0 1 1 1 0 0 0 0 1 0 0 0 1 1 0 1 0 0 1 1 0 1 1 0 1 1 1 0 0 1 0 1 1 1 0 0 1 0 0 1 0 0 0 0 0 0 1 0 0 1 1 1 1 0 1 1 1 1 1 1 1 1 1 0 0 1 1 1 0 1 1 1 1 1 0 1 0 0 0 1 1 1 0 1 1 0 0 1 0 0 1 1 0 1 0 0 0 1 0 0 1 1 1 1 1 1 0 0 1 1 1 1 0 1 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 1 1 1 1 1 1 1 0 1 1 0 0 1 1 0 1 0 1 1 0 1 0 1 1 0 1 0 0 0 1 0 0 1 1 1 1 1 0 1 1 0 0 1 1 1 1 0 1 1 1 0 1 1 1 0 0 0 0 0 0 1 1 0 0 1 1 0 0 1 0 0 0 1 1 0 1 1 1 1 0 1 1 0 1 1 0 0 1 0 0 1 0 1 0 0 0 1 0 0 0 1 1 1 1 0 1 0 1 1 0 0 0 0 1 1 0 0 1 0 1 1 0 0 0 1 1 0 0 0 0 1 0 1 1 0 1 0 0 1 1 0 1 1 1 1 0 0 0 1 0 0 0 1 1 0 1 1 1 1 1 1 0 0 0 1 1 1 1 1 0 1 0 0 0 0 0 1 1 1 1 1 1 1 0 0 1 1 0 1 1 1 1 0 0 1 1 0 0 0 1 1 0 1 0 0 1 0 1 0 1 1 1 0 1 1 1 1 0 0 1 1 1 1 1 0 1 0 0 0 1 0 1 1 1 0 1 0 1 0 1 1 0 1 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 1 1 0 1 0 1 1 0 1 0 0 0 1 1 0 0 1 0 1 0 0 0 1 0 0 0 1 1 0 1 0 1 0 1 1 1 1 1 1 1 0 1 0 0 0 0 0 0 1 0 1 0 0 1 1 0 1 1 0 1 1 0 1 0 0 1 0 1 0 1 1 0 0 0 1 1 0 1 0 0 1 0 1 1 0 0 0 0 1 0 0 1 0 1 1 0 0 0 1 1 0 0 1 0 0 0 0 1 1 1 0 1 1 1 0 0 0 0 0 0 1 1 1 1 0 1 1 0 1 1 1 0 0 1 1 1 0 1 1 0 0 1 1 1 1 0 1 0 1 1 1 1 0 0 1 1 1 1 1 0 1 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 1 1 0 0 1 1 1 1 1 0 0 1 0 0 1 1 1 1 1 1 0 1 1 1 0 1 1 0 1 0 0 0 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 1 1 1 1 1 0 1 0 0 1 1) ;; (try-all :even 2048 2049 0.0014328746687631 0.51217918249646) = 56.93601 start for next ;; ce: 50.887273 (fv 0.000000 -0.001703 0.433172 1.590778 1.336810 1.796101 0.945990 0.630649 1.068973 0.276030 0.019619 0.418921 1.642205 1.314880 1.815562 0.937954 0.690335 1.166456 0.260174 0.033467 0.534551 1.577952 1.359691 1.855935 0.978115 0.778145 1.214744 0.305514 0.073250 0.585950 1.700979 1.456846 1.891326 1.051448 0.870291 1.262779 0.419868 0.209104 0.667538 1.764244 1.534253 0.022691 1.157333 0.886455 1.397513 0.522770 0.305417 0.791572 1.882641 1.706581 0.124613 1.245754 1.016938 1.507704 0.621789 0.423116 0.882723 0.034318 1.775279 0.266045 1.420137 1.176158 1.620182 0.842558 0.553079 1.037944 0.182615 0.005162 0.432646 1.577593 1.375077 1.777427 0.999839 0.726166 1.218120 0.366911 0.123723 0.662290 1.808464 1.555557 0.050943 1.161441 0.961088 1.469391 0.581778 0.421014 0.869182 1.964711 1.782785 0.217679 1.412311 1.228590 1.681851 0.818320 0.617489 1.120821 0.226824 0.041870 0.539030 1.644423 1.496409 1.937912 1.088438 0.861771 1.374952 0.504902 0.301816 0.831900 1.946273 1.700988 0.237333 1.351841 1.174113 1.697709 0.766188 0.601502 1.097799 0.223664 0.073707 0.490731 1.705779 1.529713 0.004900 1.114151 0.927806 1.413217 0.593263 0.370397 0.876728 0.024219 1.840075 0.345172 1.498140 1.311278 1.774455 0.911735 0.779474 1.231046 0.351370 0.170176 0.732535 1.828332 1.647912 0.151754 1.304922 1.134715 1.583698 0.773654 0.612595 1.042987 0.199634 0.036653 0.549756 1.681847 1.475587 0.005194 1.173802 0.977842 1.470305 0.643755 0.476622 0.917721 0.111850 1.936419 0.450243 1.616355 1.416777 1.915014 1.098462 0.907664 1.447783 0.570918 0.405291 0.889269 0.066991 1.881365 0.373330 1.508358 1.402579 1.870612 1.085131 0.920739 1.348392 0.568783 0.336415 0.843225 0.063446 1.926774 0.418106 1.565445 1.379520 1.897103 1.050320 0.891564 1.380927 0.530987 0.385626 0.908446 0.068664 1.943935 0.430612 1.518729 1.398232 1.924184 1.103625 0.924587 1.417433 0.610522 0.456479 0.953409 0.112059 0.013043 0.495872 1.633744 1.493163 0.038519 1.187544 1.048687 1.588579 0.748576 0.532785 1.100237 0.281535 0.104911 0.635452 1.811612 1.634030 0.184177 1.345558 1.153862 1.750039 0.857060 0.732788 1.250092 0.418042 0.246015 0.725057 1.972355 1.807991 0.351695 1.540788 1.347415 1.848165 1.067747 0.908528 1.413312 0.618180 0.467879 0.991799 0.190738 0.053795 0.507730 1.744900 1.620134 0.124619 1.318661 1.152397 1.685590 0.894836 0.688791 1.239521 0.488835 0.282246 0.831794 -0.015794 1.883123 0.431031 1.583860 1.447618 1.964025 1.125655 1.064343 1.569856 0.748855 0.603708 1.107653 0.309052 0.196774 0.696407 1.871049 1.742283 0.240318 1.473905 1.321207 1.881514 1.047815 0.924156 1.493868 0.689863 0.543896 1.026203 0.246976 0.140944 0.678125 1.870899 1.706720 0.276250 1.408196 1.319078 1.889412 1.061123 0.937583 1.451370 0.684034 0.567548 1.075578 0.293854 0.180105 0.705838 1.911360 1.764817 0.292975 1.493988 1.411105 1.895989 1.081687 1.012629 1.575334 0.718344 0.628406 1.174951 0.386415 0.230260 0.768066 -0.015753 1.886981 0.454216 1.616098 1.441778 0.077596 1.316514 1.144927 1.696140 0.867400 0.757625 1.309429 0.563210 0.364175 0.954929 0.137349 0.057751 0.597415 1.789122 1.677288 0.252684 1.417924 1.313555 1.862237 1.126315 1.015807 1.510443 0.802206 0.652057 1.184565 0.404523 0.277585 0.843687 0.148971 1.933489 0.514414 1.743011 1.592866 0.129290 1.346399 1.259419 1.817805 1.029171 0.962338 1.475532 0.708188 0.633076 1.151811 0.395581 0.307725 0.834201 0.078405 1.959228 0.466843 1.769721 1.650538 0.159441 1.402559 1.321215 1.914285 1.128095 1.014297 1.571134 0.803693 0.677208 1.246457 0.469701 0.356795 0.908733 0.149102 0.035900 0.615966 1.826481 1.708851 0.339243 1.554134 1.413247 -0.028956 1.251019 1.106816 1.704569 0.926586 0.827768 1.430366 0.655894 0.524343 1.153832 0.363573 0.234391 0.825975 0.037037 1.955590 0.487803 1.776970 1.679179 0.270247 1.494959 1.379330 1.956206 1.186819 1.071982 1.644518 0.897716 0.759160 1.349574 0.601679 0.512657 1.067152 0.367997 0.259056 0.818805 0.070970 1.979460 0.551129 1.797928 1.685198 0.237267 1.508404 1.457352 0.047420 1.261021 1.192815 1.789893 0.995526 0.930294 1.496757 0.778086 0.636312 1.222185 0.505076 0.392642 1.016934 0.236492 0.140361 0.774022 0.001411 1.961469 0.498526 1.750119 1.648169 0.240766 1.450209 1.419896 0.004281 1.237513 1.195486 1.793570 1.030159 0.946491 1.529067 0.769460 0.726220 1.269159 0.564615 0.472841 1.084479 0.322182 0.217540 0.870218 0.092806 0.039652 0.580465 1.871900 1.768958 0.330755 1.643083 1.574291 0.148815 1.382016 1.330434 1.953984 1.191904 1.113085 1.729795 0.935173 0.941506 1.487573 0.777735 0.706146 1.300602 0.552074 0.471965 1.086702 0.368313 0.238388 0.870358 0.129144 0.034415 0.647185 1.956907 1.855191 0.450494 1.695322 1.674270 0.277115 1.525710 1.462245 0.090299 1.329096 1.259635 1.870782 1.128184 1.069973 1.694787 0.953585 0.907980 1.546930 0.802555 0.747675 1.322734 0.664094 0.527920 1.163169 0.460332 0.399285 0.970040 0.217204 0.171752 0.769371 0.047350 -0.025234 0.632915 1.894302 1.830249 0.455254 1.760595 1.701533 0.321139 1.541634 1.515918 0.102674 1.367783 1.346029 1.941486 1.223287 1.213347 1.782946 1.029999 1.005092 1.692642 0.911840 0.875191 1.494140 0.757479 0.727400 1.310293 0.611635 0.559689 1.154763 0.453641 0.402989 1.051223 0.342693 0.309148 0.919084 0.199108 0.132609 0.759042 0.053229 -0.033954 0.648811 1.906240 1.894740 0.483288 1.798246 1.730147 0.369025 1.616846 1.576788 0.217080 1.494201 1.461719 0.088483 1.386902 1.325078 1.982480 1.249756 1.217589 1.872681 1.143670 1.127132 1.742603 1.001258 0.969685 1.653400 0.948140 0.903244 1.474757 0.844045 0.804740 1.381313 0.669059 0.696990 1.287624 0.590259 0.542974 1.139086 0.529408 0.444238 1.060949 0.381119 0.387330 0.982887 0.274265 0.262799 0.892622 0.182183 0.155238 0.802580 0.125716 0.062385 0.697970 -0.029110 -0.005740 0.631814 1.935506 1.905147 0.526743 1.805035 1.822539 0.427610 1.754204 1.769095 0.334244 1.671094 1.648758 0.313430 1.604455 1.580989 0.249732 1.534106 1.501925 0.141332 1.456591 1.376333 0.087064 1.395898 1.349285 -0.007846 1.309141 1.324784 1.926752 1.235223 1.257013 1.870695 1.183965 1.196890 1.833185 1.161076 1.134259 1.737981 1.066217 1.029285 1.761061 1.046404 1.003567 1.669085 1.015282 0.945700 1.628153 0.957401 0.910198 1.578015 0.892702 0.920061 1.560411 0.892643 0.883270 1.499087 0.881141 0.786754 1.465346 0.814870 0.806704 1.420951 0.745568 0.748981 1.428779 0.724569 0.722331 1.414318 0.735199 0.680304 1.412191 0.642055 0.663317 1.362918 0.692620 0.652852 1.255275 0.655029 0.616540 1.306668 0.607368 0.596378 1.278318 0.605729 0.626127 1.248672 0.605969 0.598531 1.270199 0.590247 0.604018 1.248420 0.564539 0.573991 1.243120 0.541247 0.581568 1.247013 0.548311 0.583389 1.254363 0.570054 0.592870 1.314918 0.584147 0.601170 1.285128 0.585385 0.636800 1.268157 0.564860 0.618673 1.241680 0.593206 0.649499 1.294308 0.619335 0.690828 1.290074 0.662251 0.659564 1.319465 0.684267 0.676527 1.346573 0.684074 0.749941 1.376399 0.760563 0.735778 1.409735 0.781193 0.776861 1.424608 0.803012 0.794890 1.482330 0.849249 0.820388 1.516581 0.910615 0.864461 1.540065 0.895368 0.913334 1.630286 0.950361 0.962747 1.686669 0.985439 1.020247 1.674781 0.998529 1.106931 1.784420 1.109819 1.080550 1.792617 1.141848 1.167488 1.815820 1.225904 1.216862 1.932151 1.308230 1.267897 -0.026968 1.330184 1.385176 0.022707 1.458233 1.415333 0.128552 1.487923 1.523242 0.191001 1.550003 1.584242 0.283355 1.596921 1.662782 0.308217 1.689429 1.701664 0.432683 1.765615 1.799785 0.477706 1.814969 1.847473 0.536692 1.956606 -0.125001 0.671687 0.021081 0.062099 0.778322 0.143122 0.195164 0.870404 0.217515 0.248340 0.992771 0.296311 0.393796 1.036703 0.444136 0.428455 1.144392 0.545916 0.532816 1.274635 0.638559 0.682382 1.366079 0.738438 0.791235 1.469530 0.832133 0.861591 1.597033 0.965134 0.975949 1.660906 1.074595 1.121780 1.850802 1.205711 1.200292 1.955639 1.297951 1.320764 0.075418 1.456186 1.481933 0.158684 1.566840 1.641287 0.359580 1.677476 1.730799 0.448508 1.815321 1.873655 0.540161 1.931330 1.974330 0.742536 0.063433 0.156314 0.825290 0.223991 0.306298 0.962765 0.360970 0.418863 1.127740 0.516243 0.542975 1.312005 0.652439 0.710545 1.452213 0.776568 0.871797 1.548353 0.973587 1.004549 1.725321 1.089618 1.233086 1.882229 1.280829 1.345266 0.036253 1.417172 1.451706 0.202998 1.622238 1.674924 0.340016 1.728728 1.833591 0.567298 1.946042 0.023405 0.702356 0.135275 0.153799 0.884198 0.265400 0.340889 1.099730 0.493458 0.526956 1.267239 0.676407 0.690082 1.422573 0.812500 0.926029 1.644040 1.074851 1.097114 1.811626 1.221109 1.268846 0.019885 1.418865 1.465834 0.226550 1.602283 1.642652 0.409600 1.782663 1.847764 0.612518 -0.014414 0.080272 0.793644 0.189642 0.287941 1.015956 0.430798 0.498270 1.212055 0.606553 0.678263 1.458990 0.847157 0.901708 1.629236 1.030896 1.120792 1.854770 1.260369 1.292084 0.058109 1.472251 1.530032 0.298666 1.686445 1.750885 0.465407 1.926615 -0.015762 0.736186 0.179728 0.219514 0.995121 0.367989 0.459496 1.186779 0.640597 0.690551 1.458450 0.858324 0.911511 1.699195 1.068188 1.186092 1.897316 1.337175 1.402416 0.144009 1.638297 1.673138 0.373403 1.812913 1.888979 0.630635 0.080370 0.169331 0.914815 0.273060 0.393754 1.122091 0.596144 0.640794 1.390765 0.839105 0.918214 1.680880 1.131151 1.205710 1.974811 1.393861 1.452322 0.156477 1.645144 1.718367 0.451059 1.878144 0.022469 0.716191 0.203622 0.204052 1.000934 0.419218 0.531168 1.297295 0.702318 0.799989 1.534195 0.962961 1.059623 1.864764 1.322381 1.390676 0.140300 1.535535 1.653796 0.423232 1.846167 1.958815 0.705134 0.115159 0.251430 1.006465 0.470237 0.504026 1.267250 0.734232 0.836445 1.549915 1.039694 1.136664 1.905550 1.321296 1.400727 0.208474 1.633666 1.709003 0.486386 1.940896 0.025205 0.789590 0.229116 0.395199 1.113150 0.560152 0.653681 1.459139 0.830910 0.975236 1.738577 1.210343 1.308624 0.093706 1.493739 1.620053 0.424641 1.828846 1.940485 0.729339 0.163547 0.294790 1.029106 0.522695 0.623772 1.363366 0.795679 0.991955 1.735746 1.166232 1.233433 0.033448 1.517164 1.590656 0.407889 1.837549 1.928075 0.698672 0.187906 0.288583 1.089091 0.525365 0.646727 1.419503 0.847075 1.003035 1.770682 1.222701 1.368528 0.132834 1.552702 1.702988 0.486356 1.942867 0.028321 0.834453 0.305865 0.427874 1.193367 0.646670 0.777994 1.535326 0.959127 1.141152 1.974723 1.386313 1.482039 0.241727 1.733430 1.907279 0.652190 0.113225 0.233654 1.053634 0.521015 0.606360 1.407458 0.868195 0.979596 1.802838 1.252544 1.387190 0.144685 1.620697 1.765258 0.551267 0.016634 0.102630 0.966227 0.379774 0.557760 1.339080 0.772792 0.943942 1.714448 1.227165 1.340588 0.135412 1.553794 1.733262 0.505137 0.052411 0.115242 0.903954 0.369383 0.566147 1.338694 0.822997 0.955372 1.767911 1.219397 1.351801 0.123533 1.574789 1.767438 0.582707 0.059344 0.173569 0.987297 0.434401 0.616641 1.368611 0.898977 1.018679 1.815949 1.269299 1.423987 0.244273 1.756592 1.844278 0.628834 0.156429 0.267440 1.098495 0.557657 0.757430 1.527200 1.032316 1.157667 1.941839 1.435329 1.592128 0.417339 1.857219 0.027921 0.825078 0.326257 0.472209 1.266409 0.776877 0.907550 1.713542 1.197483 1.352897 0.148954 1.643699 1.805895 0.598148 0.109639 0.271416 1.099053 0.556356 0.664165 1.505314 0.973330 1.224262 1.958351 1.490436 1.656174 0.418476 1.960327 0.146807 0.899660 0.444751 0.550436 1.400125 0.831060 1.011690 1.850969 1.328814 1.486005 0.311620 1.812294 -0.006342 0.797723 0.305173 0.491901 1.322423 0.745375 0.923548 1.782732 1.275234 1.378532 0.222379 1.713386 1.920722 0.741433 0.280929 0.401426 1.209280 0.698837 0.886341 1.726784 1.225163 1.413939 0.172159 1.726536 1.893106 0.754636 0.203236 0.351446 1.190416 0.680791 0.829406 1.684757 1.210208 1.371232 0.224484 1.699825 1.891292 0.738873 0.258642 0.425836 1.243225 0.713196 0.891190 1.771850 1.235681 1.368819 0.270358 1.784768 1.928168 0.781510 0.284144 0.430703 1.331232 0.807861 0.993486 1.852203 1.325750 1.549374 0.376307 1.889520 0.034521 0.884377 0.427788 0.583618 1.373059 0.934920 1.074386 1.964373 1.419552 1.645249 0.489767 0.008746 0.185928 1.061283 0.556624 0.715745 1.608195 1.103831 1.267216 0.164802 1.613900 1.850921 0.624698 0.161160 0.408839 1.261772 0.735470 0.975590 1.782335 1.311907 1.475716 0.390097 1.869546 0.060780 0.873934 0.410643 0.589799 1.451558 0.998661 1.152970 0.054633 1.557268 1.731872 0.575393 0.117821 0.307307 1.198887 0.683313 0.897819 1.753607 1.284857 1.473685 0.314273 1.836871 0.060820 0.932547 0.420398 0.613590 1.461860 1.038061 1.203207 0.095116 1.584547 1.810340 0.624226 0.177690 0.397754 1.253072 0.802314 0.987311 1.879162 1.342549 1.566135 0.442620 1.908917 0.137619 1.011650 0.599336 0.755517 1.642027 1.174961 1.369054 0.211942 1.782659 -0.010486 0.840251 0.357521 0.581790 1.461271 1.014049 1.200403 0.044641 1.613689 1.808581 0.690100 0.250270 0.388899 1.294231 0.842257 1.021201 1.901029 1.462877 1.641210 0.546531 0.075531 0.291167 1.142643 0.703128 0.915213 1.799433 1.361706 1.526251 0.463549 1.971569 0.185024 1.029933 0.578985 0.824751 1.713096 1.250117 1.463497 0.301505 1.881822 0.143407 0.962817 0.507734 0.729352 1.590586 1.169240 1.393909 0.249757 1.802780 0.053110 0.895331 0.464179 0.669201 1.582612 1.097231 1.355127 0.231353 1.735403 0.021720 0.880348 0.431395 0.697354 1.573165 1.060767 1.347507 0.185124 1.772265 1.983494 0.879718 0.443530 0.687541 1.535902 1.151743 1.322419 0.212153 1.745041 -0.024853 0.929578 0.461659 0.706048 1.575808 1.122374 1.345663 0.241665 1.798693 0.038133 0.893828 0.497759 0.738405 1.619233 1.230529 1.391018 0.311367 1.875986 0.111417 0.982712 0.552692 0.779545 1.673926 1.277817 1.495634 0.424964 1.933807 0.193663 1.085748 0.635034 0.877002 1.797408 1.324014 1.603040 0.515913 0.114700 0.279027 1.230954 0.738758 0.971164 1.923699 1.522824 1.758904 0.629325 0.199968 0.431971 1.357304 0.920686 1.144660 0.047634 1.638457 1.887367 0.770386 0.339803 0.608798 1.474763 1.082399 1.336813 0.240373 1.815488 0.071521 0.978055 0.575127 0.812951 1.691650 1.236419 1.523987 0.428018 -0.014053 0.227398 1.211471 0.739843 1.033454 1.889876 1.490608 1.764875 0.650358 0.197774 0.479040 1.394298 0.990877 1.266721 0.153708 1.743738 1.993903 0.889105 0.452779 0.717556 1.641719 1.258531 1.472505 0.400527 0.003181 0.277816 1.190582 0.720088 1.018145 1.947482 1.529759 1.763205 0.679772 0.305019 0.551595 1.459782 1.056328 1.376741 0.254961 1.837237 0.083779 1.033490 0.597121 0.863372 1.752800 1.369817 1.661724 0.554009 0.132249 0.412929 1.366488 0.929237 1.205521 0.153686 1.780997 0.028187 0.910073 0.518459 0.747299 1.736440 1.285832 1.584544 0.515963 0.139650 0.379555 1.267964 0.869992 1.153100 0.094361 1.717865 1.955775 0.900339 0.490824 0.754072 1.676728 1.277159 1.570274 0.491155 0.127499 0.354589 1.327580 0.971916 1.203157 0.189781 1.749254 -0.000141 0.971242 0.569275 0.834995 1.792334 1.386324 1.620367 0.641313 0.177512 0.493821 1.395372 1.027112 1.276574 0.195767 1.840052 0.118782 1.057366 0.655353 0.981627 1.889857 1.497516 1.809949 0.727076 0.311895 0.619859 1.589373 1.177776 1.446089 0.402884 -0.013138 0.323859 1.242590 0.872932 1.139811 0.103389 1.705727 0.012476 0.932654 0.580713 0.844428 1.776557 1.375650 1.683357 0.653489 0.286018 0.530346 1.477873 1.102629 1.446550 0.391220 0.013493 0.315912 1.191737 0.889652 1.135899 0.064317 1.726753 0.008311 0.973187 0.561368 0.881325 1.835182 1.452878 1.728216 0.640203 0.296506 0.611465 1.537761 1.163681 1.521594 0.455106 0.113603 0.376193 1.335690 0.990813 1.252928 0.217355 1.798201 0.130538 1.099312 0.694187 1.042508 1.990873 1.625313 1.908796 0.833102 0.534393 0.775983 1.784275 1.381831 1.684754 0.630094 0.272616 0.575688 1.559911 1.184625 1.453679 0.491431 0.104067 0.400708 1.342106 0.977889 1.261797 0.248038 1.904884 0.237792 1.209205 0.805676 1.119936 0.155727 1.752922 0.098394 1.023110 0.709066 0.956558 1.945167 1.621782 1.885544 0.851378 0.511350 0.815303 1.752479 1.417551 1.712996 0.651328 0.341725 0.648800 1.652874 1.229749 1.564655 0.595314 0.162557 0.496357 1.536686 1.115189 1.443475 0.423294 0.108662 0.395018 1.332526 0.999816 1.352353 0.328398 1.960089 0.256657 1.276205 0.950110 1.251154 0.223763 1.856947 0.198310 1.202811 0.823347 1.139257 0.137493 1.791954 0.126818 1.077613 0.742716 1.034617 0.042667 1.702855 0.035869 0.942965 0.683955 0.962192 1.957952 1.636826 1.953521 0.904062 0.576569 0.908521 1.946168 1.527121 1.835900 0.915076 0.530360 0.860954 1.848124 1.476416 1.825816 0.801278 0.498232 0.791951 1.825898 1.460369 1.801238 0.807022 0.470147 0.775520 1.782957 1.421022 1.758922 0.747391 0.412834 0.729983 1.748458 1.430447 1.754281 0.725069 0.444203 0.754125 1.805117 1.457795 1.776284 0.724624 0.428724 0.744488 1.781494 1.483810 1.771396 0.825589 0.485350 0.772930 1.812210 1.489700 1.842892 0.808972 0.497919 0.826699 1.849758 1.501581 1.863781 0.830698 0.510646 0.856199 1.880392 1.487637 1.841337 0.883565 0.587660 0.933592 1.879899 1.575694 1.912690 0.882053 0.596355 0.876449 1.942318 1.604954 1.957913 0.991402 0.632658 0.965194 -0.031486 1.680264 0.039739 1.057207 0.660079 1.072774 0.084190 1.760660 0.122642 1.146243 0.783356 1.166710 0.158916 1.820281 0.220718 1.231907 0.956518 1.285669 0.300669 1.936753 0.315132 1.335110 1.060246 1.374454 0.394758 0.082667 0.417144 1.497357 1.121455 1.497524 0.558460 0.253594 0.585079 1.609798 1.353184 1.698378 0.628590 0.358364 0.702657 1.718959 1.448521 1.778728 0.811121 0.552978 0.858398 1.901305 1.551915 1.964990 1.006942 0.659821 0.990952 0.063543 1.773494 0.063737 1.160916 0.874963 1.254235 0.227903 1.909287 0.327897 1.310953 0.994777 1.331010 0.411728 0.136015 0.418712 1.516878 1.254075 1.541807 0.597800 0.341732 0.654709 1.684819 1.408026 1.806837 0.819367 0.523512 0.857369 1.895100 1.607979 1.949425 0.987941 0.703347 1.084034 0.136539 1.830122 0.250645 1.285193 0.947170 1.289548 0.328696 0.029933 0.461597 1.469311 1.207559 1.503925 0.619432 0.268080 0.678945 1.716381 1.398922 1.858266 0.884402 0.579547 0.942855 -0.007780 1.697643 0.060832 1.147089 0.859119 1.243156 0.279683 1.948552 0.303518 1.436858 1.120717 1.478393 0.523558 0.237367 0.599745 1.706188 1.421576 1.811698 0.850440 0.556037 0.945518 -0.871745 1.728994 0.072385 1.111766 0.835570 1.223297 0.269709 0.056622 0.355706 1.422876 1.147014 1.551471 0.600627 0.344660 0.724082 1.763987 1.516159 1.882823 0.942715 0.661410 1.033320 0.094097 1.855748 0.231455 1.280646 1.044202 1.442450 0.460350 0.194810 0.625856 1.678168 1.370560 1.773190 0.847696 0.600688 1.001562 0.035016 1.824811 0.145896 1.197674 0.963152 1.364275 0.436987 0.180547 0.564604 1.641854 1.399407 1.733896 0.850418 0.609483 0.927674) ) )) ;;; triangle waves in place of sinusoids have different mimima at different places, so ;;; we can't simplify in that direction ;;; the waveforms for a given number of peaks are surprisingly similar -- :odd and :even in particular ;;; this includes cases involving all sines (0 and 1), as compared to all cosines (1/2 and 3/2) (define (tstodd phs) (let ((len (length phs)) (incr 0.0001) (mx 0.0) (loc 0.0)) (do ((x 0.0 (+ x incr))) ((> x (* 2 pi)) (list mx loc)) (let ((val 0.0)) (do ((k 0 (+ k 1)) (j 1 (+ j 2))) ((= k len)) (set! val (+ val (sin (+ (* j x) (* pi (phs k))))))) (if (> (abs val) mx) (begin (set! mx (abs val)) (set! loc x))))))) (define (tstoddderiv x phs) (let ((sum 0.0) (len (length phs))) (do ((i 0 (+ i 1)) (j 1 (+ j 2))) ((= i len) sum) (set! sum (+ sum (* j (cos (+ (* j x) (* pi (phs i)))))))))) (define* (tstall phs phs1) (if (real? phs) (set! phs phs1)) (let ((len (length phs)) (incr 0.0001) (mx 0.0) (loc 0.0)) (do ((x 0.0 (+ x incr))) ((> x (* 2 pi)) (list mx loc)) (let ((val 0.0)) (do ((k 0 (+ k 1)) (j 1 (+ j 1))) ((= k len)) (set! val (+ val (sin (+ (* j x) (* pi (phs k))))))) (if (> (abs val) mx) (begin (set! mx (abs val)) (set! loc x))))))) (define (tstallf mult phs) (let ((len (length phs)) (incr 0.0001) (mx 0.0) (loc 0.0)) (do ((x 0.0 (+ x incr))) ((> x (* 2 pi)) (list mx loc)) (let ((val 0.0)) (do ((k 0 (+ k 1)) (j 1 (+ j 1))) ((= k len)) (if (= k (- len 1)) (set! val (+ val (* mult (sin (+ (* j x) (* pi (phs k))))))) (set! val (+ val (sin (+ (* j x) (* pi (phs k)))))))) (if (> (abs val) mx) (begin (set! mx (abs val)) (set! loc x))))))) (define (tsteven phs) (let ((len (length phs)) (incr 0.0001) (mx 0.0) (loc 0.0)) (do ((x 0.0 (+ x incr))) ((> x (* 2 pi)) (list mx loc)) (let ((val 0.0)) (do ((k 0 (+ k 1))) ((= k len)) (set! val (+ val (sin (+ (* (max (* 2 k) 1) x) (* pi (phs k))))))) (if (> (abs val) mx) (begin (set! mx (abs val)) (set! loc x))))))) (define (tstprime phs) (let ((len (length phs)) (incr 0.0001) (mx 0.0) (loc 0.0)) (do ((x 0.0 (+ x incr))) ((> x (* 2 pi)) (list mx loc)) (let ((val 0.0)) (do ((k 0 (+ k 1))) ((= k len)) (set! val (+ val (sin (+ (* (primes k) x) (* pi (phs k))))))) (if (> (abs val) mx) (begin (set! mx (abs val)) (set! loc x))))))) (define (tstallderiv x phs) (let ((sum 0.0) (len (length phs))) (do ((i 0 (+ i 1)) (j 1 (+ j 1))) ((= i len) sum) (set! sum (+ sum (* j (cos (+ (* j x) (* pi (phs i)))))))))) (define (get-best choice n) (define (vector-find-if func vect) (let ((len (length vect)) (result #f)) (do ((i 0 (+ i 1))) ((or (= i len) result) result) (set! result (func (vect i)))))) (vector-find-if (lambda (val) (and val (vector? val) (= (val 0) n) (let ((a-val (val 1)) (a-len (length val)) (a-data (val 2))) (do ((k 3 (+ 1 k))) ((= k a-len)) (if (and (number? (val k)) (< (val k) a-val)) (begin (set! a-val (val k)) (set! a-data (val (+ k 1)))))) (list a-val a-data)))) (if (eq? choice :all) noid-min-peak-phases (if (eq? choice :odd) nodd-min-peak-phases (if (eq? choice :even) neven-min-peak-phases primoid-min-peak-phases))))) (define (showall len) (let* ((phs-data (get-best :all len)) (phs (cadr phs-data)) (mx (car phs-data)) (v (make-float-vector (ceiling (+ (* 2 pi 1000) 2)))) (incr 0.001)) (do ((x 0.0 (+ x incr)) (i 0 (+ i 1))) ((> x (* 2 pi))) (let ((val 0.0)) (do ((k 0 (+ k 1)) (j 1 (+ j 1))) ((= k len)) (set! val (+ val (sin (+ (* j x) (* pi (phs k))))))) (set! (v i) val))) (new-sound) (float-vector->channel v) (set! (y-bounds) (list (- mx) mx)))) (define (showphases mx phs) (let ((v (make-float-vector (ceiling (+ (* 2 pi 1000) 2)))) (incr 0.001) (len (length phs))) (do ((x 0.0 (+ x incr)) (i 0 (+ i 1))) ((> x (* 2 pi))) (let ((val 0.0)) (do ((k 0 (+ k 1)) (j 1 (+ j 1))) ((= k len)) (set! val (+ val (sin (+ (* j x) (* pi (phs k))))))) (set! (v i) val))) (new-sound) (float-vector->channel v) (set! (y-bounds) (list (- mx) mx)))) (define (showodd len) (let* ((phs-data (get-best :odd len)) (phs (cadr phs-data)) (mx (car phs-data)) (v (make-float-vector (ceiling (+ (* 2 pi 1000) 2)))) (incr 0.001)) (do ((x 0.0 (+ x incr)) (i 0 (+ i 1))) ((> x (* 2 pi))) (let ((val 0.0)) (do ((k 0 (+ k 1)) (j 1 (+ j 2))) ((= k len)) (set! val (+ val (sin (+ (* j x) (* pi (phs k))))))) (set! (v i) val))) (new-sound) (float-vector->channel v) (set! (y-bounds) (list (- mx) mx)))) (define (showdiff n1 n2) (let* ((len (length n1)) (data (make-float-vector len))) (do ((i 0 (+ i 1))) ((= i len)) (set! (data i) (modulo (- (n1 i) (n2 i)) 2.0)) (if (> (data i) 1.0) (set! (data i) (- (data i) 2.0)) (if (< (data i) -1) (set! (data i) (+ (data i) 2.0))))) (new-sound) (float-vector->channel data) )) (define (differ snd) (let ((x 0.0)) (map-channel (lambda (y) (let ((res (- y x))) (set! x y) res)) 0 #f snd 0))) (define (find-other-mins peak-amp peak-phases) ;; given a point, find the 3 other matching points (this assumes all harmonics, but the other cases are similar; ;; in the even case, we'd flip all above 0, not just every other one, because they're all even, but we end ;; up with 4 equivalent points as before -- step by 1 not 2 in the 1st and 3rd loops below. In the odd and ;; prime cases, I can only think of 2 such points, the symmetry being around 0 (2-val)). (let ((temp-phases (copy peak-phases)) (n (length peak-phases)) (results ())) ;; flip evens (do ((i 1 (+ i 2))) ((>= i n)) (set! (temp-phases i) (modulo (+ (temp-phases i) 1.0) 2.0))) (let ((val (car (tstall temp-phases)))) (if (> (abs (- val peak-amp)) .001) (format #t ";~A -> ~A?~%" peak-amp val)) (set! results (cons (list val temp-phases) results))) ;; get case symmetric around 0 (set! temp-phases (copy peak-phases)) (do ((i 1 (+ i 1))) ((= i n)) (set! (temp-phases i) (modulo (- 2.0 (temp-phases i)) 2.0))) (let ((val (car (tstall temp-phases)))) (if (> (abs (- val peak-amp)) .001) (format #t ";~A -> ~A?~%" peak-amp val)) (set! results (cons (list val temp-phases) results))) ;; flip evens on the previous case (set! temp-phases (copy temp-phases)) (do ((i 1 (+ i 2))) ((>= i n)) (set! (temp-phases i) (modulo (+ (temp-phases i) 1.0) 2.0))) (let ((val (car (tstall temp-phases)))) (if (> (abs (- val peak-amp)) .001) (format #t ";~A -> ~A?~%" peak-amp val)) (set! results (cons (list val temp-phases) results))) ; (format #f "~{~{~,8F ~A~%~}~}" (reverse results)) results )) ;;; :(find-other-mins (car (tstall (fv 0.0 0.1 0.2 0.3))) (fv 0.0 0.1 0.2 0.3)) ;;; 3.49630991 (fv 0.0 1.1 0.2 1.3) ;;; 3.49630680 (fv 0.0 1.9 1.8 1.7) ;;; 3.49630979 (fv 0.0 0.9 1.8 0.7) (define (canonicalize-one i p) (let ((data (get-best :all i))) (let ((old-peak (car data)) (old-phases (cadr data))) (let ((phases (copy old-phases))) (if (< (phases 2) -1.0) (set! (phases 2) (+ (phases 2) 2.0)) (if (> (phases 2) 1.0) (set! (phases 2) (- (phases 2) 2.0)))) (if (< (phases 2) 0.0) (do ((j 1 (+ j 1))) ((>= j i)) (set! (phases j) (modulo (- 2.0 (phases j)) 2.0)))) (if (< (phases 1) -1.0) (set! (phases 1) (+ (phases 1) 2.0)) (if (> (phases 1) 1.0) (set! (phases 1) (- (phases 1) 2.0)))) (if (< (phases 1) 0.0) ; this is an "even" harmonic (do ((j 1 (+ j 2))) ((>= j i)) (set! (phases j) (modulo (+ 1.0 (phases j)) 2.0)))) (do ((j 1 (+ j 1))) ((= j i)) (if (< (phases j) -1.0) (set! (phases j) (+ (phases j) 2.0)) (if (> (phases j) 1.0) (set! (phases j) (- (phases j) 2.0))))) (let ((new-peak-info (tstall phases))) (let ((new-peak (car new-peak-info))) (if (> (abs (- new-peak old-peak)) .001) (format *stderr* "oops: ~D: ~A ~A~%" i old-peak new-peak)) (format p "(vector ~D ~,6F (fv " i new-peak) (do ((k 1 (+ k 1))) ((= k i)) (format p "~,6F " (phases (- k 1)))) (format p "~,6F))~% ;; loc: ~F~%~%" (phases (- i 1)) (/ (cadr new-peak-info) pi)))))))) (define (canonicalize) ;; this is slow because we call tstall on each one (call-with-output-file "pp4.scm" (lambda (p) (format p "(define noid-min-peak-phases (vector~%~%(vector 1 1.0 (fv 0))~%(vector 2 1.76 (fv 0 0))~%~%") (do ((i 3 (+ i 1))) ((> i 128)) (format *stderr* "~D " i) (canonicalize-one i p)) (format p "))~%")))) (if (provided? 'snd) (set! (print-length) 123123) (set! (*s7* 'print-length) 123123)) (define (show-mins i) (let ((data (get-best :all i))) (let ((other-mins (apply find-other-mins data))) (let ((pk1 (cadr data)) (pk2 (cadar other-mins)) (pk3 (cadadr other-mins)) (pk4 (cadr (caddr other-mins)))) (if (or (> (abs (- (caar other-mins) (car data))) .001) (> (abs (- (caadr other-mins) (car data))) .001) (> (abs (- (caaddr other-mins) (car data))) .001)) (format #t "trouble in ~D: ~A ~A~%" i data other-mins)) (let ((phases (sort! (list pk1 pk2 pk3 pk4) (lambda (a b) (< (a 1) (b 1)))))) (format #t "~,8F~% ~A~% ~A~% ~A~% ~A~%" (data 0) (phases 0) (phases 1) (phases 2) (phases 3) )))))) ;; (09) ;; 1 Mar 5446.42 ;; 1 Apr 5405.890 ;; 1 May 5138.261 ;; 1 Jun 5061.829 ;; 1 Jul 4669.101 ;; 1 Aug 4633.454 ;; 1 Sep 4616.517 ;; 1 Oct 4592.994 ;; 1 Nov 4560.903 ;; 1 Dec 4541.710 ;; (10) ;; 1 Jan 4360.644 ;; 1 Feb 4292.451 ;; 1 Mar 4280.782 ;; 1 Apr 4272.964 ;; 1 May 4267.719 ;; 1 Jun 4261.356 ;; 1 Jul 4244.312, sqrts: 82 74 0 0 ;; 1 Aug 4218.456, sqrts: 82 74 0 0 ;; 1 Sep 4209.464, sqrts: 85 74 0 0 (9.5330) ;; 1 Oct 4202.347, sqrts: 89 75 0 0 (6.9438) ;; 1 Nov 4198.764, sqrts: 94 78 0 0 (5.5196) ;; 1 Dec 4196.395, sqrts: 98 84 0 0 (4.1226) ;; (11) ;; 1 Jan 4194.669, sqrts: 101 91 0 0 (2.9465) ;; 1 Feb 4194.106, sqrts: 105 91 0 0 (2.5054) ;; 1 Mar 4193.048, sqrts: 110 95 0 0 (1.6862) ;; 1 Apr 4188.373, sqrts: 114 104 0 0 (0.8505) ;; 1 May 4186.610, sqrts: 114 105 0 0 (0.6439) ;; 1 Jun 4186.498, sqrts: 115 105 0 0 (0.5422) ;; 1 Nov 4186.465, sqrts: 116 105 0 0 (0.5095) ;; 1 Dec 4186.315, sqrts: 117 108 0 0 (0.4198) ;; (12) ;; 1 Jan 4185.693, sqrts: 118 112 0 0 (0.3225) ;; 1 Feb 4185.458, sqrts: 119 113 0 0 (0.2534) ;; 1 Mar 4185.289, sqrts: 119 115 0 0 (0.1710) ;; 1 Apr 4185.029, sqrts: 120 115 0 0 (0.1464) ;; 1 Nov 4184.742, sqrts: 120 115 0 0 (0.1429) ;; 1 Dec 4184.727, sqrts: 121 115 0 0 (0.1349) ;; (13) ;; 1 Feb 4184.520, sqrts: 122 115 0 0 (0.1159) ;; 1 Jun 4184.160, sqrts: 122 118 0 0 (0.0926) ;; 1 Aug 4183.948, sqrts: 122 118 0 0 (0.0440) ;; 1 Sep 4183.825, sqrts: 122 119 0 0 (0.0382) ;; 1 Oct 4183.673, sqrts: 122 119 0 0 (0.0382) ;; 1 Nov 4183.616, sqrts: 122 119 0 0 (0.0382) ;; 1 Dec 4183.180, sqrts: 122 120 0 0 (0.0361) ;; (14) ;; 1 Jan 4183.004, sqrts: 122 120 0 0 (0.0346) ;; 1 Mar 4182.956, sqrts: 122 120 0 0 (0.0346) ;; 1 Apr 4182.919, sqrts: 122 120 0 0 (0.0346) ;; 1 May 4182.759, sqrts: 122 120 0 0 (0.0346) ;; 1 Jun 4177.414, sqrts: 122 120 0 0 (0.0346) ;; 1 Jul 4174.620, sqrts: 122 120 0 0 (0.0346) ;; 1 Aug 4171.810, sqrts: 122 120 0 0 (0.0346) ;; 1 Sep 4169.400, sqrts: 122 120 0 0 (0.0346) ;; 1 Oct 4166.886, sqrts: 122 121 0 0 (0.0242) ;; 1 Nov 4163.522, sqrts: 122 122 0 0 (0.0000) ;; 1 Dec 4161.032, sqrts: 122 122 0 0 (0.0000) ;; (15) ;; 1 Jan 4158.938 ;; 1 Feb 4156.526 ;; 1 Mar 4154.769 ;; 1 Apr 4154.180 ;; 1 May 4153.716 ;; 1 Jun 4153.330 ;; 1 Jul 4152.859 ;; 1 Aug 4152.637 ;; 1 Sep 4152.306 ;; 1 Oct 4152.200 ;; 1 Nov 4152.089 ; all 0.4860 (20) to 0.4987 (106), dist: 0.0000, 13.5427 ; odd 0.4820 (11) to 0.5000 (112), dist: 0.0000, 8.5572 ; even 0.5085 (115) to 0.5242 (22), dist: 57.6719, 0.0000 ; prime 0.5445 (24) to 0.5540 (67), dist: 232.5954, 0.0000 ;(test-all-phases #f) in test-phases.scm #| <2> (test-all-phases #f) ;all peaks... Mon 26-Oct-2015 13:11 (0.001495737399423547 101) ;odd peaks... Mon 26-Oct-2015 13:17 (0.001687315629258279 125) ;even peaks... Mon 26-Oct-2015 13:21 (0.001467169674692848 4) ;prime peaks... Mon 26-Oct-2015 13:25 (0.001975582609148319 2048) ;all done! Mon 26-Oct-2015 13:30 ";all done! Mon 26-Oct-2015 13:30 |# ;;; gad161: clean-up-evens ;;; t139.scm: show-circle (Motif-based) ;;; t283.scm: poly stuff ;;; tmp26.scm sqrt graph ;;; t404.scm for averages, graphed via graph-averages.scm ;;; t405.scm for function searcher snd-16.1/rhypar.cms0000644000076400007640000001224611071234170012345 0ustar bilbil;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; Jean Claude Risset's rhythm paradox: the increasing beat. ;;; =================================== ;;; Docs: ;;; Risset, J. C. (1991). ;;; Current Directions in Computer Music Research, ;;; chapter Paradoxical Sounds, (pp. 149-158) ;;; ;;; John Pierce, The Science of Musical Sound. ;;; ;;; Snd (guile scheme) code by Juan Reyes ;;; juanig ccrma.Stanford (dot) EDU ;;; (c) MMVII ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Snd initialize (if needed) ;;; ;; ;; (use-modules (ice-9 optargs)) ;; ;; (provide 'snd-clm-ins.scm) ;; (if (not (provided? 'snd-ws.scm)) (load-from-path "ws.scm")) ;; (if (not (provided? 'snd-env.scm)) (load-from-path "env.scm")) ;;; Dependency: ;;; ;;; (load "ws.scm") ;;; ;;; ;;; Overall amplitude gaussian ;;; (define ampgaussian (lambda (t m) (let* ((s m) ;; Max Iterations (r (/ s 2)) ;; Half Max Iterations (sigma 4.0)) ;; sigma > 1 convex curve ;; (exp (* (* (/ -1 2) (* sigma sigma)) (expt (- (/ t r) 1) 2))) ))) ;;; define e (define e (exp 1)) ;;; ;;; Normal curve for increasing / decreasing beat ;;; (define jcrcurve (lambda (t m) ;; m = max number of iterations (let ((k (* (/ -1 m) (log 32)))) (expt e (* k t)))) ) ;;; ;;; Simple one OSCIL intrument with a fast attack (percussive) ADSR envelope ;;; (definstrument (beats start duration freq amp :key (percu-env '(0 0 8 1 100 0)) ) (let* ((beg (seconds->samples start)) (length (+ beg (seconds->samples duration))) (signal (make-oscil :frequency freq)) ;;; ;;; here we have our envelope ;;; (percuenv (make-env :envelope percu-env :scaler amp :base 32 :duration duration ))) (run (lambda () (do ((i beg (1+ i))) ((= i length)) (begin (outa i (* (env percuenv) (oscil signal)) *output* ) ) ))))) ;;; (with-sound () (beats 0 1.25 1000 0.7)) ;;; ;;; Simple case: ;;; =========== ;;; This case is shown on J. Pierce The Science of Musical Sound ;;; ;;; Each of the beats is constructed with a sine frequency of (1000Hz) ;;; the beats are multiplied by a percussive envelope (see definstrument). ;;; ;;; The individual beat is repeated at a rate 'r' (Hz) over a ;;; specific time period [see (define jcrcuve) ]. ;;; ;;; A number of patterns in geometric relation are constructed. Each ;;; of this patterns has a different envelope for the amplitude (overall ;;; amplitude gaussian) which furthermore be summed and multiplied to ;;; create a single beat. ;;; ;;; When these patterns are combined, they create a perception illusion ;;; of tempo increasing, when in reality , tempo remains the same. ;;; (define simpleparad (lambda (notes r) (with-sound() (let ((sta 0.00) (sta2 0.00) (rhy (/ 1 r))) ;;; (do ((i 0 (1+ i))) ((= i notes)) (begin (let ((rhythm (+ 3.35464e-4 (* rhy (jcrcurve i notes))))) (beats sta rhythm 600 0.25) (set! sta (+ sta rhy))) )) ;;; (do ((h 2 (* 2 h))) ((= h 32)) (begin (set! sta2 0.0) (do ((i 0 (1+ i))) ((= i h)) (do ((j 0 (1+ j))) ((= j notes )) (begin (let ((rhythm (+ 3.35464e-4 (* (/ 1 (* h r)) (jcrcurve i notes))))) (beats sta2 rhythm 600 0.25) (set! sta2 (+ sta2 (/ 1 (* h r)) ))) ) ))) ) )) )) ;;; ;;; (simpleparad 33 0.425) ;;; (simpleparad 10 0.5) ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; Complex case: ;;; =========== ;;; This case is shown on J.C. Risset's Pradoxical Sounds ;;; ;;; The concept for the complex case is almost the same although, the ;;; illusion is achieved by having the listener focus on the beat which ;;; has the loudest amplitude. Here we use a normal curve [(ampgaussian)] ;;; to handle the amplitude on each of the patterns. By the same token ;;; amplitudes are further superimposed against each other and ;;; against rhythm beats. ;;; ;;; (define complexparad (lambda (notes r) (with-sound() (let ((sta 0.00) (sta2 0.00) (rhy (/ 1 r))) ;;; (do ((i 0 (1+ i))) ((= i notes)) (begin (let ((rhythm (+ 3.35464e-4 (* rhy (jcrcurve i notes))))) (beats sta rhythm 400 (* 0.25 (ampgaussian i notes))) (set! sta (+ sta rhy))) )) ;;; (do ((h 2 (* 2 h))) ((= h 32)) (begin (set! sta2 0.0) (do ((i 0 (1+ i))) ((= i h)) (do ((j 0 (1+ j))) ((= j notes )) (begin (let ((rhythm (+ 3.35464e-4 (* (/ 1 (* h r)) (jcrcurve i notes))))) (beats sta2 rhythm 400 (* 0.25 (ampgaussian j notes))) (set! sta2 (+ sta2 (/ 1 (* h r)) ))) ) ))) ) )) )) ;;; ;;; (complexparad 66 1.25) ;;; (complexparad 66 1.45) ;;; ;;; ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; snd-16.1/snd-genv.c0000644000076400007640000012340512555416057012237 0ustar bilbil#include "snd.h" /* envelope editor and viewer */ static GtkWidget *enved_dialog = NULL; static GtkWidget *enved_apply_button, *enved_apply2_button, *enved_cancel_button, *enved_drawer, *show_button; static GtkWidget *enved_save_button = NULL, *enved_reset_button, *fir_button = NULL; static GtkWidget *enved_revert_button, *enved_undo_button, *enved_redo_button, *brktxtL, *enved_graph_button; static GtkWidget *flt_button, *amp_button, *src_button, *rbrow, *clip_button; static GtkWidget *enved_name_label, *enved_text_label, *enved_dB_button, *enved_order_label; static GtkWidget *lin_button, *lerow, *baseScale, *baseLabel, *baseValue, *enved_selection_button, *selrow, *unrow; static GtkAdjustment *baseAdj, *orderAdj; static gc_t *gc, *rgc, *ggc; static slist *env_list = NULL; static const char *env_names[3] = {"amp env:", "flt env:", "src env:"}; static bool showing_all_envs = false; /* edit one env (0), or view all currently defined envs (1) */ static bool apply_to_selection = false, we_turned_selection_off = false; static int env_window_width = 0; static int env_window_height = 0; static chan_info *active_channel = NULL, *last_active_channel = NULL; static env* selected_env = NULL; /* if during view, one env is clicked, it is "selected" and can be pasted elsewhere */ static env* active_env = NULL; /* env currently being edited */ static axis_info *axis = NULL; static axis_info *gray_ap = NULL; static bool is_FIR = true; static bool old_clipping = false; static bool ignore_button_release = false; axis_info *enved_make_axis(const char *name, graphics_context *ax, int ex0, int ey0, int width, int height, mus_float_t xmin, mus_float_t xmax, mus_float_t ymin, mus_float_t ymax, printing_t printing) { init_env_axes(axis, name, ex0, ey0, width, height, xmin, xmax, ymin, ymax, printing); return(axis); } static void display_env(env *e, const char *name, gc_t *cur_gc, int x0, int y0, int width, int height, bool dots, printing_t printing) { ss->enved->with_dots = dots; axis->ax->gc = cur_gc; env_editor_display_env(ss->enved, e, axis->ax, name, x0, y0, width, height, printing); } void display_enved_env_with_selection(env *e, const char *name, int x0, int y0, int width, int height, bool dots, printing_t printing) { /* called in a loop through all envs during view_envs (called only from env_redisplay_1 below) */ display_env(e, name, (selected_env == e) ? rgc : gc, x0, y0, width, height, dots, printing); } static void reflect_segment_state(void); static void prepare_env_edit(env *new_env) { prepare_enved_edit(new_env); if (new_env->base == 1.0) set_enved_style(ENVELOPE_LINEAR); else { set_enved_style(ENVELOPE_EXPONENTIAL); set_enved_base(new_env->base); } reflect_segment_state(); } void set_enved_redo_sensitive(bool val) {set_sensitive(enved_redo_button, val);} void set_enved_revert_sensitive(bool val) {set_sensitive(enved_revert_button, val);} void set_enved_undo_sensitive(bool val) {set_sensitive(enved_undo_button, val);} void set_enved_save_sensitive(bool val) {set_sensitive(enved_save_button, val);} void set_enved_show_sensitive(bool val) {set_sensitive(show_button, val);} void make_scrolled_env_list(void) { int n, size; size = enved_all_envs_top(); slist_clear(env_list); for (n = 0; n < size; n++) slist_append(env_list, enved_all_names(n)); gtk_widget_show(env_list->scroller); } void enved_reflect_peak_env_completion(snd_info *sp) { if ((enved_dialog) && (active_channel) && (enved_with_wave(ss))) { if (active_channel->sound == sp) env_redisplay(); } } void new_active_channel_alert(void) { if (enved_dialog) { /* if showing current active channel in gray, update */ active_channel = current_channel(); env_redisplay(); } } static void dismiss_enved_callback(GtkWidget *w, gpointer context) { gtk_widget_hide(enved_dialog); } static gint delete_enved_dialog(GtkWidget *w, GdkEvent *event, gpointer context) { gtk_widget_hide(enved_dialog); return(true); } static void help_enved_callback(GtkWidget *w, gpointer context) { envelope_editor_dialog_help(); } static void force_update(GtkWidget *wid) { if ((wid) && (WIDGET_TO_WINDOW(wid))) { gdk_window_invalidate_rect(GDK_WINDOW(WIDGET_TO_WINDOW(wid)), NULL, true); gdk_window_process_updates(GDK_WINDOW(WIDGET_TO_WINDOW(wid)), true); } } static bool within_selection_src = false; static void apply_enved(void) { if (active_env) { active_channel = current_channel(); if (active_channel) { char *origin = NULL, *estr = NULL; set_sensitive(enved_apply_button, false); set_sensitive(enved_apply2_button, false); set_stock_button_label(enved_cancel_button, I_STOP); force_update(enved_cancel_button); switch (enved_target(ss)) { case ENVED_AMPLITUDE: #if HAVE_FORTH origin = mus_format("%s%s %s drop", estr = env_to_string(active_env), (apply_to_selection) ? "" : " 0 " PROC_FALSE, (apply_to_selection) ? S_env_selection : S_env_channel); #else origin = mus_format("%s" PROC_OPEN "%s%s", to_proc_name((apply_to_selection) ? S_env_selection : S_env_channel), estr = env_to_string(active_env), (apply_to_selection) ? "" : PROC_SEP "0" PROC_SEP PROC_FALSE); #endif apply_env(active_channel, active_env, 0, current_samples(active_channel), apply_to_selection, origin, NULL, C_int_to_Xen_integer(AT_CURRENT_EDIT_POSITION), 0); /* calls update_graph, I think, but in short files that doesn't update the amp-env */ if (enved_with_wave(ss)) env_redisplay(); if (estr) free(estr); if (origin) free(origin); break; case ENVED_SPECTRUM: #if HAVE_FORTH origin = mus_format("%s %d%s %s drop", estr = env_to_string(active_env), enved_filter_order(ss), (apply_to_selection) ? "" : " 0 " PROC_FALSE, (apply_to_selection) ? S_filter_selection : S_filter_channel); #else origin = mus_format("%s" PROC_OPEN "%s" PROC_SEP "%d%s", to_proc_name((apply_to_selection) ? S_filter_selection : S_filter_channel), estr = env_to_string(active_env), enved_filter_order(ss), (apply_to_selection) ? "" : PROC_SEP "0" PROC_SEP PROC_FALSE); #endif apply_filter(active_channel, (is_FIR) ? enved_filter_order(ss) : 0, active_env, origin, NULL, apply_to_selection, NULL, NULL, C_int_to_Xen_integer(AT_CURRENT_EDIT_POSITION), 0, false); if (estr) free(estr); if (origin) free(origin); break; case ENVED_SRATE: { int i, j; env *max_env = NULL; max_env = copy_env(active_env); for (i = 0, j = 1; i < max_env->pts; i++, j += 2) if (max_env->data[j] < .01) max_env->data[j] = .01; within_selection_src = true; src_env_or_num(active_channel, max_env, 0.0, false, "Enved: src", apply_to_selection, NULL, C_int_to_Xen_integer(AT_CURRENT_EDIT_POSITION), 0); within_selection_src = false; max_env = free_env(max_env); if (enved_with_wave(ss)) env_redisplay(); } break; } set_sensitive(enved_apply_button, true); set_sensitive(enved_apply2_button, true); set_stock_button_label(enved_cancel_button, I_GO_AWAY); } } } static void env_redisplay_1(printing_t printing) { if (enved_dialog_is_active()) { bool clear_cr = false; if ((printing == NOT_PRINTING) && (!(ss->cr))) { /* we can get here from display_channel_data_with_size with an existing ss->cr */ ss->cr = make_cairo(WIDGET_TO_WINDOW(enved_drawer)); clear_cr = true; } if (!(ss->cr)) return; cairo_push_group(ss->cr); cairo_set_source_rgba(ss->cr, gc->bg_color->red, gc->bg_color->green, gc->bg_color->blue, gc->bg_color->alpha); cairo_rectangle(ss->cr, 0, 0, env_window_width, env_window_height); cairo_fill(ss->cr); if (showing_all_envs) { int x0, x1, y0, y1; x0 = axis->x_axis_x0; x1 = axis->x_axis_x1; y0 = axis->y_axis_y0; y1 = axis->y_axis_y1; view_envs(env_window_width, env_window_height, NOT_PRINTING); /* NOT_PRINTING because we're not using the eps stuff here */ axis->x_axis_x0 = x0; axis->x_axis_x1 = x1; axis->y_axis_y0 = y0; axis->y_axis_y1 = y1; } else { char *name = NULL; name = (char *)gtk_entry_get_text(GTK_ENTRY(enved_text_label)); if (!name) name = (char *)"noname"; if ((enved_with_wave(ss)) && (active_channel) && (!(active_channel->squelch_update))) { if ((enved_target(ss) == ENVED_SPECTRUM) && (active_env) && (is_FIR) && (printing == NOT_PRINTING)) display_frequency_response(active_env, axis, gray_ap->ax, enved_filter_order(ss), enved_in_dB(ss)); enved_show_background_waveform(axis, gray_ap, apply_to_selection, (enved_target(ss) == ENVED_SPECTRUM), NOT_PRINTING); } display_env(active_env, name, gc, 0, 0, env_window_width, env_window_height, true, NOT_PRINTING); } cairo_pop_group_to_source(ss->cr); cairo_paint(ss->cr); if ((printing == NOT_PRINTING) && (clear_cr)) { free_cairo(ss->cr); ss->cr = NULL; } } } void env_redisplay(void) { env_redisplay_1(NOT_PRINTING); } void env_redisplay_with_print(void) { env_redisplay_1(PRINTING); } void update_enved_background_waveform(chan_info *cp) { if ((enved_dialog_is_active()) && (enved_with_wave(ss)) && (enved_target(ss) == ENVED_AMPLITUDE) && (cp == active_channel) && ((!apply_to_selection) || (selection_is_active_in_channel(cp)))) env_redisplay(); } static void enved_filter_order_callback(GtkWidget *w, gpointer data) { set_enved_filter_order(gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(enved_order_label))); } static void clear_point_label(void); static void clear_genv_error(void) { if (brktxtL) clear_point_label(); } static gint unpost_genv_error(gpointer data) { clear_genv_error(); return(0); } static void errors_to_genv_text(const char *msg, void *data) { gtk_label_set_text(GTK_LABEL(brktxtL), msg); g_timeout_add_full(0, (guint32)5000, unpost_genv_error, NULL, NULL); } static void text_field_activated(GtkWidget *w, gpointer context) { /* might be breakpoints to load or an envelope name ( in enved text field) */ char *str = NULL; str = (char *)gtk_entry_get_text(GTK_ENTRY(w)); if ((str) && (*str)) { env *e = NULL; while (isspace((int)(*str))) str++; e = name_to_env(str); if (!e) { if (isalpha((int)(str[0]))) { alert_envelope_editor(str, copy_env(active_env)); add_or_edit_symbol(str, active_env); set_sensitive(enved_save_button, false); env_redisplay(); /* updates label */ } else { redirect_errors_to(errors_to_genv_text, NULL); e = string_to_env(str); redirect_errors_to(NULL, NULL); } } if (e) { if (active_env) { #define ENVED_TEMP_NAME "enved-backup" /* save current under a temp name! -- user might have mistakenly reused a name */ alert_envelope_editor((char *)ENVED_TEMP_NAME, copy_env(active_env)); add_or_edit_symbol(ENVED_TEMP_NAME, active_env); active_env = free_env(active_env); } active_env = copy_env(e); set_enved_env_list_top(0); prepare_env_edit(active_env); set_sensitive(enved_save_button, true); set_sensitive(enved_undo_button, false); set_sensitive(enved_revert_button, false); env_redisplay(); free_env(e); } } } static void enved_save_button_pressed(GtkWidget *w, gpointer context) { char *name = NULL; if (active_env == NULL) return; name = (char *)gtk_entry_get_text(GTK_ENTRY(enved_text_label)); if ((!name) || (!(*name))) name = (char *)"unnamed"; alert_envelope_editor(name, copy_env(active_env)); add_or_edit_symbol(name, active_env); set_sensitive(enved_save_button, false); env_redisplay(); } static void apply_enved_callback(GtkWidget *w, gpointer context) { /* apply current envs to currently sync'd channels */ apply_enved(); last_active_channel = active_channel; } static void undo_and_apply_enved_callback(GtkWidget *w, gpointer context) { /* undo upto previous amp env, then apply */ /* this blindly undoes the previous edit (assumed to be an envelope) -- if the user made some other change in the meantime, too bad */ if ((active_channel) && (active_channel == last_active_channel)) { active_channel->squelch_update = true; undo_edit_with_sync(active_channel, 1); active_channel->squelch_update = false; clear_status_area(active_channel->sound); } apply_enved(); last_active_channel = active_channel; } static void reflect_segment_state(void) { if ((enved_dialog) && (active_env) && (!(showing_all_envs))) env_redisplay(); } static void select_or_edit_env(int pos) { if (showing_all_envs) { showing_all_envs = false; set_button_label(show_button, "view envs"); } if (active_env) active_env = free_env(active_env); selected_env = position_to_env(pos); if (!selected_env) return; active_env = selected_env; gtk_entry_set_text(GTK_ENTRY(enved_text_label), enved_all_names(pos)); set_enved_env_list_top(0); prepare_env_edit(active_env); set_sensitive(enved_undo_button, false); set_sensitive(enved_revert_button, false); set_sensitive(enved_save_button, false); env_redisplay(); } #define BLANK_LABEL " " static void clear_point_label(void) { gtk_label_set_text(GTK_LABEL(brktxtL), BLANK_LABEL); } static char brkpt_buf[LABEL_BUFFER_SIZE]; static void enved_display_point_label(mus_float_t x, mus_float_t y) { if ((enved_in_dB(ss)) && (min_dB(ss) < -60)) snprintf(brkpt_buf, LABEL_BUFFER_SIZE, "%.3f : %.5f", x, y); else snprintf(brkpt_buf, LABEL_BUFFER_SIZE, "%.3f : %.3f", x, y); gtk_label_set_text(GTK_LABEL(brktxtL), brkpt_buf); } static gboolean enved_drawer_button_motion(GtkWidget *w, GdkEventMotion *ev, gpointer data) { int evx, evy; GdkModifierType state; oclock_t motion_time = 0; ignore_button_release = false; if (BUTTON1_PRESSED(EVENT_STATE(ev))) { if (EVENT_IS_HINT(ev)) window_get_pointer(ev, &evx, &evy, &state); else { evx = (int)(EVENT_X(ev)); evy = (int)(EVENT_Y(ev)); motion_time = EVENT_TIME(ev); if ((motion_time - ss->enved->down_time) < 100) return(false); } } else return(false); if (!showing_all_envs) { mus_float_t x, y; env_editor_button_motion_with_xy(ss->enved, evx, evy, motion_time, active_env, &x, &y); enved_display_point_label(x, y); env_redisplay(); } return(false); } static gboolean enved_drawer_button_press(GtkWidget *w, GdkEventButton *ev, gpointer data) { ss->enved->down_time = EVENT_TIME(ev); ss->enved->env_dragged = false; if (showing_all_envs) { int pos; pos = hit_env((int)(EVENT_X(ev)), (int)(EVENT_Y(ev)), env_window_width, env_window_height); slist_select(env_list, pos); if ((pos >= 0) && (pos < enved_all_envs_top())) { select_or_edit_env(pos); ignore_button_release = true; } } else { if (!active_env) { active_env = default_env(1.0, 0.0); active_env->base = enved_base(ss); env_redisplay(); /* needed to get current_xs set up correctly */ } if (env_editor_button_press(ss->enved, (int)(EVENT_X(ev)), (int)(EVENT_Y(ev)), EVENT_TIME(ev), active_env)) env_redisplay(); enved_display_point_label(ungrf_x(ss->enved->axis, EVENT_X(ev)), env_editor_ungrf_y_dB(ss->enved, (int)(EVENT_Y(ev)))); set_sensitive(enved_save_button, true); set_sensitive(enved_undo_button, true); set_sensitive(enved_revert_button, true); } return(false); } static gboolean enved_drawer_button_release(GtkWidget *w, GdkEventButton *ev, gpointer data) { if (ignore_button_release) ignore_button_release = false; else { if (!showing_all_envs) { env_editor_button_release(ss->enved, active_env); env_redisplay(); clear_point_label(); } } return(false); } static gboolean enved_drawer_expose(GtkWidget *w, GdkEventExpose *ev, gpointer data) { env_window_width = widget_width(w); env_window_height = widget_height(w); env_redisplay(); return(false); } static gboolean enved_drawer_resize(GtkWidget *w, GdkEventConfigure *ev, gpointer data) { /* update display, can be either view of all envs or sequence of current envs */ env_window_width = widget_width(w); env_window_height = widget_height(w); env_redisplay(); return(false); } static void show_button_pressed(GtkWidget *w, gpointer context) { /* if show all (as opposed to show current), loop through loaded LV_LISTs */ showing_all_envs = (!showing_all_envs); set_button_label(show_button, (showing_all_envs) ? "edit env" : "view envs"); env_redisplay(); } static void enved_selection_button_pressed(GtkWidget *w, gpointer context) { apply_to_selection = (!apply_to_selection); widget_modify_bg(enved_selection_button, GTK_STATE_NORMAL, (apply_to_selection) ? ss->yellow : ss->basic_color); set_sensitive(enved_apply2_button, true); if ((enved_with_wave(ss)) && (!showing_all_envs)) env_redisplay(); } static void enved_revert_button_pressed(GtkWidget *w, gpointer context) { revert_env_edit(); if (active_env) active_env = free_env(active_env); active_env = enved_next_env(); if (active_env == NULL) text_field_activated(enved_text_label, NULL); env_redisplay(); } static void enved_undo_button_pressed(GtkWidget *w, gpointer context) { undo_env_edit(); if (active_env) active_env = free_env(active_env); active_env = enved_next_env(); env_redisplay(); } static void enved_redo_button_pressed(GtkWidget *w, gpointer context) { redo_env_edit(); if (active_env) active_env = free_env(active_env); active_env = enved_next_env(); env_redisplay(); } static void reflect_apply_state(void) { gtk_label_set_text(GTK_LABEL(enved_name_label), env_names[enved_target(ss)]); widget_modify_bg(amp_button, GTK_STATE_NORMAL, (enved_target(ss) == ENVED_AMPLITUDE) ? ss->yellow : ss->basic_color); widget_modify_bg(flt_button, GTK_STATE_NORMAL, (enved_target(ss) == ENVED_SPECTRUM) ? ss->yellow : ss->basic_color); widget_modify_bg(src_button, GTK_STATE_NORMAL, (enved_target(ss) == ENVED_SRATE) ? ss->yellow : ss->basic_color); if ((!showing_all_envs) && (enved_with_wave(ss))) env_redisplay(); } static void flt_button_pressed(GtkWidget *w, gpointer context) { in_set_enved_target(ENVED_SPECTRUM); old_clipping = enved_clipping(ss); set_enved_clipping(true); reflect_apply_state(); } static void amp_button_pressed(GtkWidget *w, gpointer context) { if (enved_target(ss) == ENVED_SPECTRUM) set_enved_clipping(old_clipping); in_set_enved_target(ENVED_AMPLITUDE); reflect_apply_state(); } static void src_button_pressed(GtkWidget *w, gpointer context) { if (enved_target(ss) == ENVED_SPECTRUM) set_enved_clipping(old_clipping); in_set_enved_target(ENVED_SRATE); reflect_apply_state(); } static void enved_reset(void) { set_enved_clipping(DEFAULT_ENVED_CLIPPING); set_enved_style(ENVELOPE_LINEAR); set_enved_power(DEFAULT_ENVED_POWER); set_enved_base(DEFAULT_ENVED_BASE); set_enved_target(DEFAULT_ENVED_TARGET); set_enved_with_wave(DEFAULT_ENVED_WITH_WAVE); set_enved_in_dB(DEFAULT_ENVED_IN_DB); set_enved_filter_order(DEFAULT_ENVED_FILTER_ORDER); if (active_env) active_env = free_env(active_env); #if HAVE_SCHEME active_env = string_to_env("'(0 0 1 0)"); #endif #if HAVE_FORTH active_env = string_to_env("'( 0 0 1 0 )"); #endif #if HAVE_RUBY active_env = string_to_env("[0, 0, 1, 0]"); #endif set_enved_env_list_top(0); prepare_env_edit(active_env); set_sensitive(enved_save_button, true); reflect_enved_style(); env_redisplay(); } static void enved_reset_button_pressed(GtkWidget *w, gpointer context) { enved_reset(); } static void env_browse_callback(const char *name, int row, void *data) { select_or_edit_env(row); } static void enved_graph_button_callback(GtkWidget *w, gpointer context) { in_set_enved_with_wave(TOGGLE_BUTTON_ACTIVE(w)); env_redisplay(); } static void enved_dB_button_callback(GtkWidget *w, gpointer context) { in_set_enved_in_dB(TOGGLE_BUTTON_ACTIVE(w)); env_redisplay(); } static void clip_button_callback(GtkWidget *w, gpointer context) { in_set_enved_clipping(TOGGLE_BUTTON_ACTIVE(w)); } static void make_base_label(mus_float_t bval) { char *sfs, *buf; int i, len, scale_len; len = (int)(enved_power(ss) * 4); if (len < 32) len = 32; sfs = (char *)calloc(len, sizeof(char)); snprintf(sfs, len, "%.3f", bval); scale_len = (int)(enved_power(ss) + 3); if (scale_len < 32) scale_len = 32; buf = (char *)calloc(scale_len, sizeof(char)); for (i = 0; i < scale_len - 1; i++) buf[i] = sfs[i]; gtk_label_set_text(GTK_LABEL(baseValue), buf); free(sfs); free(buf); in_set_enved_base(bval); if ((active_env) && (!(showing_all_envs))) { if (enved_save_button) set_sensitive(enved_save_button, true); /* what about undo/redo here? */ active_env->base = enved_base(ss); if (active_env->base == 1.0) set_enved_style(ENVELOPE_LINEAR); else set_enved_style(ENVELOPE_EXPONENTIAL); env_redisplay(); } } static void base_changed(mus_float_t val) { mus_float_t bval; if (val == 0) bval = 0.0; else { if (val == 0.5) bval = 1.0; else { if (val > 0.5) bval = pow(1.0 + (10.0 * ((val - 0.5) * 2)), enved_power(ss)); else bval = pow((val * 2), enved_power(ss) - 1.0); } } make_base_label(bval); } static void reflect_changed_base(mus_float_t val) { mus_float_t ival; if (val <= 0.0) ival = 0.0; else { if (val == 1.0) ival = 0.5; else { if (val <= 1.0) ival = pow(val, 1.0 / (enved_power(ss) - 1.0)) * 0.5; else ival = (0.5 + ((0.5 * (pow(val, (1.0 / (enved_power(ss)))) - 1)) / 10.0)); } } if (baseAdj) { ADJUSTMENT_SET_VALUE(baseAdj, ival); make_base_label(val); } } static void make_linear(GtkWidget *w, gpointer context) { reflect_changed_base(1.0); set_enved_style(ENVELOPE_LINEAR); } static void base_changed_callback(GtkAdjustment *adj, gpointer context) { base_changed(ADJUSTMENT_VALUE(adj)); } static gboolean fir_button_pressed(GtkWidget *w, GdkEventButton *ev, gpointer data) { is_FIR = (!is_FIR); gtk_label_set_text(GTK_LABEL(fir_button), (is_FIR) ? "fir" : "fft"); if (enved_with_wave(ss)) env_redisplay(); return(false); } static void reflect_sound_state(void) { bool file_on; file_on = (bool)(any_selected_sound()); set_sensitive(enved_apply_button, file_on); set_sensitive(enved_apply2_button, file_on); } static Xen reflect_file_in_enved(Xen hook_or_reason) { if (enved_dialog) reflect_sound_state(); return(Xen_false); } Xen_wrap_1_arg(reflect_file_in_enved_w, reflect_file_in_enved) #define BB_MARGIN 3 GtkWidget *create_envelope_editor(void) { if (!enved_dialog) { GtkWidget *mainform, *enved_help_button, *leftbox, *bottombox, *leftframe, *toprow, *bottomrow; enved_dialog = gtk_dialog_new(); #if GTK_CHECK_VERSION(3, 14, 0) gtk_window_set_transient_for(GTK_WINDOW(enved_dialog), GTK_WINDOW(MAIN_SHELL(ss))); #endif add_dialog_style(enved_dialog); SG_SIGNAL_CONNECT(enved_dialog, "delete_event", delete_enved_dialog, NULL); gtk_window_set_title(GTK_WINDOW(enved_dialog), "Edit Envelope"); sg_make_resizable(enved_dialog); gtk_container_set_border_width(GTK_CONTAINER(enved_dialog), 4); gtk_widget_realize(enved_dialog); gtk_window_resize(GTK_WINDOW(enved_dialog), 500, 500); widget_modify_bg(enved_dialog, GTK_STATE_NORMAL, ss->basic_color); gc = gc_new(); gc_set_background(gc, ss->white); gc_set_foreground(gc, ss->black); rgc = gc_new(); gc_set_background(rgc, ss->white); gc_set_foreground(rgc, ss->red); ggc = gc_new(); gc_set_background(ggc, ss->white); gc_set_foreground(ggc, ss->enved_waveform_color); enved_help_button = gtk_dialog_add_button(GTK_DIALOG(enved_dialog), "Help", GTK_RESPONSE_NONE); enved_reset_button = gtk_dialog_add_button(GTK_DIALOG(enved_dialog), "Clear graph", GTK_RESPONSE_NONE); enved_cancel_button = gtk_dialog_add_button(GTK_DIALOG(enved_dialog), I_GO_AWAY, GTK_RESPONSE_NONE); enved_apply2_button = gtk_dialog_add_button(GTK_DIALOG(enved_dialog), "Undo&Apply", GTK_RESPONSE_NONE); enved_apply_button = gtk_dialog_add_button(GTK_DIALOG(enved_dialog), "Apply", GTK_RESPONSE_NONE); gtk_widget_set_name(enved_help_button, "dialog_button"); gtk_widget_set_name(enved_cancel_button, "dialog_button"); gtk_widget_set_name(enved_apply_button, "dialog_button"); gtk_widget_set_name(enved_apply2_button, "dialog_button"); gtk_widget_set_name(enved_reset_button, "dialog_button"); SG_SIGNAL_CONNECT(enved_cancel_button, "clicked", dismiss_enved_callback, NULL); SG_SIGNAL_CONNECT(enved_reset_button, "clicked", enved_reset_button_pressed, NULL); SG_SIGNAL_CONNECT(enved_help_button, "clicked", help_enved_callback, NULL); SG_SIGNAL_CONNECT(enved_apply2_button, "clicked", undo_and_apply_enved_callback, NULL); SG_SIGNAL_CONNECT(enved_apply_button, "clicked", apply_enved_callback, NULL); #if GTK_CHECK_VERSION(3, 0, 0) add_highlight_button_style(enved_cancel_button); add_highlight_button_style(enved_apply_button); add_highlight_button_style(enved_apply2_button); add_highlight_button_style(enved_reset_button); add_highlight_button_style(enved_help_button); #endif gtk_widget_show(enved_cancel_button); gtk_widget_show(enved_apply_button); gtk_widget_show(enved_apply2_button); gtk_widget_show(enved_reset_button); gtk_widget_show(enved_help_button); mainform = gtk_hbox_new(false, 0); /* buttons + graph */ gtk_box_pack_start(GTK_BOX(DIALOG_CONTENT_AREA(enved_dialog)), mainform, true, true, 0); leftframe = gtk_frame_new(NULL); gtk_box_pack_start(GTK_BOX(mainform), leftframe, false, false, 0); gtk_frame_set_shadow_type(GTK_FRAME(leftframe), GTK_SHADOW_ETCHED_IN); gtk_widget_show(leftframe); widget_modify_bg(leftframe, GTK_STATE_NORMAL, ss->black); leftbox = gtk_vbox_new(false, 0); gtk_container_add(GTK_CONTAINER(leftframe), leftbox); gtk_widget_show(leftbox); bottombox = gtk_vbox_new(false, 0); gtk_box_pack_start(GTK_BOX(DIALOG_CONTENT_AREA(enved_dialog)), bottombox, false, false, 4); gtk_widget_show(bottombox); enved_drawer = gtk_drawing_area_new(); gtk_box_pack_start(GTK_BOX(mainform), enved_drawer, true, true, 0); gtk_widget_set_events(enved_drawer, GDK_ALL_EVENTS_MASK); widget_modify_bg(enved_drawer, GTK_STATE_NORMAL, ss->white); widget_modify_fg(enved_drawer, GTK_STATE_NORMAL, ss->black); gtk_widget_show(enved_drawer); show_button = gtk_button_new_with_label("view envs"); gtk_button_set_relief(GTK_BUTTON(show_button), GTK_RELIEF_HALF); gtk_box_pack_start(GTK_BOX(leftbox), show_button, false, false, BB_MARGIN); SG_SIGNAL_CONNECT(show_button, "clicked", show_button_pressed, NULL); #if GTK_CHECK_VERSION(3, 0, 0) add_highlight_button_style(show_button); #endif gtk_widget_show(show_button); enved_save_button = gtk_button_new_with_label("define it"); gtk_button_set_relief(GTK_BUTTON(enved_save_button), GTK_RELIEF_HALF); gtk_box_pack_start(GTK_BOX(leftbox), enved_save_button, false, false, BB_MARGIN); SG_SIGNAL_CONNECT(enved_save_button, "clicked", enved_save_button_pressed, NULL); #if GTK_CHECK_VERSION(3, 0, 0) add_highlight_button_style(enved_save_button); #endif gtk_widget_show(enved_save_button); enved_revert_button = gtk_button_new_with_label("revert "); gtk_button_set_relief(GTK_BUTTON(enved_revert_button), GTK_RELIEF_HALF); gtk_box_pack_start(GTK_BOX(leftbox), enved_revert_button, false, false, BB_MARGIN); SG_SIGNAL_CONNECT(enved_revert_button, "clicked", enved_revert_button_pressed, NULL); #if GTK_CHECK_VERSION(3, 0, 0) add_highlight_button_style(enved_revert_button); #endif gtk_widget_show(enved_revert_button); unrow = gtk_hbox_new(false, 0); gtk_box_pack_start(GTK_BOX(leftbox), unrow, false, false, BB_MARGIN); gtk_widget_show(unrow); enved_undo_button = gtk_button_new_with_label(" undo "); gtk_button_set_relief(GTK_BUTTON(enved_undo_button), GTK_RELIEF_HALF); gtk_box_pack_start(GTK_BOX(unrow), enved_undo_button, true, true, BB_MARGIN); SG_SIGNAL_CONNECT(enved_undo_button, "clicked", enved_undo_button_pressed, NULL); #if GTK_CHECK_VERSION(3, 0, 0) add_highlight_button_style(enved_undo_button); #endif gtk_widget_show(enved_undo_button); enved_redo_button = gtk_button_new_with_label(" redo "); gtk_button_set_relief(GTK_BUTTON(enved_redo_button), GTK_RELIEF_HALF); gtk_box_pack_start(GTK_BOX(unrow), enved_redo_button, true, true, BB_MARGIN); SG_SIGNAL_CONNECT(enved_redo_button, "clicked", enved_redo_button_pressed, NULL); #if GTK_CHECK_VERSION(3, 0, 0) add_highlight_button_style(enved_redo_button); #endif gtk_widget_show(enved_redo_button); rbrow = gtk_hbox_new(false, 0); gtk_box_pack_start(GTK_BOX(leftbox), rbrow, false, false, BB_MARGIN); gtk_widget_show(rbrow); amp_button = gtk_button_new_with_label("amp"); gtk_button_set_relief(GTK_BUTTON(amp_button), GTK_RELIEF_HALF); gtk_box_pack_start(GTK_BOX(rbrow), amp_button, true, true, BB_MARGIN); SG_SIGNAL_CONNECT(amp_button, "clicked", amp_button_pressed, NULL); #if GTK_CHECK_VERSION(3, 0, 0) add_highlight_button_style(amp_button); #endif gtk_widget_show(amp_button); flt_button = gtk_button_new_with_label("flt"); gtk_button_set_relief(GTK_BUTTON(flt_button), GTK_RELIEF_HALF); gtk_box_pack_start(GTK_BOX(rbrow), flt_button, true, true, BB_MARGIN); SG_SIGNAL_CONNECT(flt_button, "clicked", flt_button_pressed, NULL); #if GTK_CHECK_VERSION(3, 0, 0) add_highlight_button_style(flt_button); #endif gtk_widget_show(flt_button); src_button = gtk_button_new_with_label("src"); gtk_button_set_relief(GTK_BUTTON(src_button), GTK_RELIEF_HALF); gtk_box_pack_start(GTK_BOX(rbrow), src_button, true, true, BB_MARGIN); SG_SIGNAL_CONNECT(src_button, "clicked", src_button_pressed, NULL); #if GTK_CHECK_VERSION(3, 0, 0) add_highlight_button_style(src_button); #endif gtk_widget_show(src_button); selrow = gtk_hbox_new(false, 0); gtk_box_pack_start(GTK_BOX(leftbox), selrow, false, false, BB_MARGIN); gtk_widget_show(selrow); enved_selection_button = gtk_button_new_with_label("selection"); gtk_button_set_relief(GTK_BUTTON(enved_selection_button), GTK_RELIEF_HALF); gtk_box_pack_start(GTK_BOX(selrow), enved_selection_button, true, true, BB_MARGIN); SG_SIGNAL_CONNECT(enved_selection_button, "clicked", enved_selection_button_pressed, NULL); #if GTK_CHECK_VERSION(3, 0, 0) add_highlight_button_style(enved_selection_button); #endif gtk_widget_show(enved_selection_button); env_list = slist_new_with_title("envs:", leftbox, NULL, 0, BOX_PACK); env_list->select_callback = env_browse_callback; if (enved_all_envs_top() > 0) make_scrolled_env_list(); toprow = gtk_hbox_new(false, 0); gtk_box_pack_start(GTK_BOX(bottombox), toprow, false, false, 0); gtk_widget_show(toprow); bottomrow = gtk_hbox_new(false, 0); gtk_box_pack_start(GTK_BOX(bottombox), bottomrow, false, false, 0); gtk_widget_show(bottomrow); { GtkWidget* sep; sep = gtk_hseparator_new(); gtk_box_pack_end(GTK_BOX(DIALOG_CONTENT_AREA(enved_dialog)), sep, false, false, 8); gtk_widget_show(sep); } #define LEFT_MARGIN 8 enved_name_label = gtk_label_new("amp env:"); widget_set_margin_left(enved_name_label, LEFT_MARGIN); gtk_box_pack_start(GTK_BOX(toprow), enved_name_label, false, false, 0); gtk_widget_show(enved_name_label); enved_text_label = snd_entry_new_with_size(toprow, 28); SG_SIGNAL_CONNECT(enved_text_label, "activate", text_field_activated, NULL); brktxtL = gtk_label_new(BLANK_LABEL); gtk_box_pack_start(GTK_BOX(toprow), brktxtL, false, false, 6); gtk_widget_show(brktxtL); enved_dB_button = gtk_check_button_new_with_label("dB"); SG_SIGNAL_CONNECT(enved_dB_button, "toggled", enved_dB_button_callback, NULL); gtk_box_pack_end(GTK_BOX(toprow), enved_dB_button, false, false, 4); gtk_widget_show(enved_dB_button); enved_graph_button = gtk_check_button_new_with_label("wave"); SG_SIGNAL_CONNECT(enved_graph_button, "toggled", enved_graph_button_callback, NULL); gtk_box_pack_end(GTK_BOX(toprow), enved_graph_button, false, false, 4); gtk_widget_show(enved_graph_button); clip_button = gtk_check_button_new_with_label("clip"); SG_SIGNAL_CONNECT(clip_button, "toggled", clip_button_callback, NULL); gtk_box_pack_end(GTK_BOX(toprow), clip_button, false, false, 4); gtk_widget_show(clip_button); baseLabel = gtk_label_new("exp:"); widget_set_margin_left(baseLabel, LEFT_MARGIN); gtk_box_pack_start(GTK_BOX(bottomrow), baseLabel, false, false, 4); gtk_widget_show(baseLabel); baseValue = gtk_label_new("1.000"); gtk_box_pack_start(GTK_BOX(bottomrow), baseValue, false, false, 4); gtk_widget_show(baseValue); lerow = gtk_vbox_new(false, 0); gtk_box_pack_start(GTK_BOX(bottomrow), lerow, true, true, 8); gtk_widget_show(lerow); { GtkWidget* sep; sep = gtk_vseparator_new(); gtk_box_pack_start(GTK_BOX(lerow), sep, false, false, 8); gtk_widget_show(sep); } baseAdj = (GtkAdjustment *)gtk_adjustment_new(0.5, 0.0, 1.0, 0.001, 0.01, .1); baseScale = gtk_hscrollbar_new(GTK_ADJUSTMENT(baseAdj)); widget_modify_bg(baseScale, GTK_STATE_NORMAL, ss->position_color); SG_SIGNAL_CONNECT(baseAdj, "value_changed", base_changed_callback, NULL); /* gtk_box_pack_start(GTK_BOX(bottomrow), baseScale, true, true, 4); */ gtk_box_pack_start(GTK_BOX(lerow), baseScale, true, true, 0); gtk_widget_show(baseScale); { /* try to center the linear button */ GtkWidget *hr, *rb, *lb; hr = gtk_hbox_new(false, 0); gtk_box_pack_start(GTK_BOX(lerow), hr, false, false, 4); gtk_widget_show(hr); rb = gtk_label_new(""); gtk_box_pack_start(GTK_BOX(hr), rb, true, true, 2); gtk_widget_show(rb); lb = gtk_label_new(""); gtk_box_pack_end(GTK_BOX(hr), lb, true, true, 2); gtk_widget_show(lb); lin_button = gtk_button_new_with_label("1.0"); gtk_box_pack_start(GTK_BOX(hr), lin_button, false, false, 4); SG_SIGNAL_CONNECT(lin_button, "clicked", make_linear, NULL); #if GTK_CHECK_VERSION(3, 0, 0) add_center_button_style(lin_button); #endif gtk_widget_show(lin_button); } orderAdj = (GtkAdjustment *)gtk_adjustment_new(20, 2, 100000, 2, 10, 0); enved_order_label = gtk_spin_button_new(GTK_ADJUSTMENT(orderAdj), 0.0, 0); gtk_box_pack_end(GTK_BOX(bottomrow), enved_order_label, false, false, 4); gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(enved_order_label), true); SG_SIGNAL_CONNECT(orderAdj, "value_changed", enved_filter_order_callback, NULL); SG_SIGNAL_CONNECT(enved_order_label, "enter_notify_event", spin_button_focus_callback, NULL); SG_SIGNAL_CONNECT(enved_order_label, "leave_notify_event", spin_button_unfocus_callback, NULL); gtk_widget_show(enved_order_label); /* fir_button = gtk_button_new_with_label((is_FIR) ? "fir" : "fft"); */ /* SG_SIGNAL_CONNECT(eb, "clicked", fir_button_pressed, NULL); */ { GtkWidget *eb; eb = gtk_event_box_new(); gtk_box_pack_end(GTK_BOX(bottomrow), eb, false, false, 4); widget_set_margin_left(eb, 8); widget_modify_bg(eb, GTK_STATE_NORMAL, ss->basic_color); gtk_widget_set_events(eb, GDK_BUTTON_PRESS_MASK); SG_SIGNAL_CONNECT(eb, "button_press_event", fir_button_pressed, NULL); gtk_widget_show(eb); fir_button = gtk_label_new("fir"); gtk_container_add(GTK_CONTAINER(eb), fir_button); gtk_widget_show(fir_button); } gtk_widget_show(mainform); gtk_widget_show(enved_dialog); axis = (axis_info *)calloc(1, sizeof(axis_info)); axis->ax = (graphics_context *)calloc(1, sizeof(graphics_context)); axis->ax->wn = WIDGET_TO_WINDOW(enved_drawer); axis->ax->w = enved_drawer; axis->ax->gc = gc; axis->ax->current_font = AXIS_NUMBERS_FONT(ss); gray_ap = (axis_info *)calloc(1, sizeof(axis_info)); gray_ap->ax = (graphics_context *)calloc(1, sizeof(graphics_context)); gray_ap->graph_active = true; gray_ap->ax->wn = WIDGET_TO_WINDOW(enved_drawer); gray_ap->ax->w = enved_drawer; gray_ap->ax->gc = ggc; gray_ap->ax->current_font = AXIS_NUMBERS_FONT(ss); SG_SIGNAL_CONNECT(enved_drawer, DRAW_SIGNAL, enved_drawer_expose, NULL); SG_SIGNAL_CONNECT(enved_drawer, "configure_event", enved_drawer_resize, NULL); SG_SIGNAL_CONNECT(enved_drawer, "button_press_event", enved_drawer_button_press, NULL); SG_SIGNAL_CONNECT(enved_drawer, "button_release_event", enved_drawer_button_release, NULL); SG_SIGNAL_CONNECT(enved_drawer, "motion_notify_event", enved_drawer_button_motion, NULL); if (enved_all_envs_top() == 0) set_sensitive(show_button, false); set_sensitive(enved_revert_button, false); set_sensitive(enved_undo_button, false); set_sensitive(enved_redo_button, false); set_sensitive(enved_save_button, false); if (!(selection_is_active())) set_sensitive(enved_selection_button, false); set_toggle_button(clip_button, enved_clipping(ss), false, NULL); set_toggle_button(enved_graph_button, enved_with_wave(ss), false, NULL); set_toggle_button(enved_dB_button, enved_in_dB(ss), false, NULL); reflect_apply_state(); reflect_segment_state(); reflect_sound_state(); set_dialog_widget(ENVED_DIALOG, enved_dialog); Xen_add_to_hook_list(ss->snd_open_file_hook, reflect_file_in_enved_w, "enved-file-open-handler", "enved dialog's file-open-hook handler"); } else raise_dialog(enved_dialog); env_window_width = widget_width(enved_drawer); env_window_height = widget_height(enved_drawer); active_channel = current_channel(); env_redisplay(); return(enved_dialog); } void set_enved_clipping(bool val) { in_set_enved_clipping(val); if (enved_dialog) set_toggle_button(clip_button, val, false, NULL); } void reflect_enved_style(void) { reflect_segment_state(); } void set_enved_target(enved_target_t val) { in_set_enved_target(val); if (enved_dialog) reflect_apply_state(); } void set_enved_with_wave(bool val) { in_set_enved_with_wave(val); if (enved_dialog) set_toggle_button(enved_graph_button, val, false, NULL); } void set_enved_in_dB(bool val) { in_set_enved_in_dB(val); if (enved_dialog) set_toggle_button(enved_dB_button, val, false, NULL); } void set_enved_base(mus_float_t val) { in_set_enved_base(val); if (enved_dialog) reflect_changed_base(val); } bool enved_dialog_is_active(void) { return((enved_dialog) && (widget_is_active(enved_dialog))); } void set_enved_filter_order(int order) { if ((order > 0) && (order < 2000)) { if (order & 1) {in_set_enved_filter_order(order + 1);} else {in_set_enved_filter_order(order);} if (enved_dialog) { widget_int_to_text(enved_order_label, enved_filter_order(ss)); if ((enved_target(ss) == ENVED_SPECTRUM) && (enved_with_wave(ss)) && (!showing_all_envs)) env_redisplay(); } } } void enved_reflect_selection(bool on) { if ((enved_dialog) && (!within_selection_src)) { set_sensitive(enved_selection_button, on); if ((apply_to_selection) && (!on)) { apply_to_selection = false; we_turned_selection_off = true; } if ((on) && (we_turned_selection_off)) { apply_to_selection = true; } widget_modify_bg(enved_selection_button, GTK_STATE_NORMAL, (apply_to_selection) ? ss->yellow : ss->basic_color); if ((enved_target(ss) != ENVED_SPECTRUM) && (enved_with_wave(ss)) && (!showing_all_envs)) env_redisplay(); } } void color_enved_waveform(color_info *pix) { if (enved_dialog) { gc_set_foreground(ggc, pix); if ((enved_with_wave(ss)) && (enved_dialog)) env_redisplay(); } } static Xen g_enved_envelope(void) { #define H_enved_envelope "(" S_enved_envelope "): current envelope editor displayed (active) envelope" return(env_to_xen(active_env)); } static Xen g_set_enved_envelope(Xen e) { Xen_check_type(Xen_is_list(e) || Xen_is_string(e) || Xen_is_symbol(e), e, 1, S_set S_enved_envelope, "a list, symbol, or string"); if (active_env) active_env = free_env(active_env); if ((Xen_is_string(e)) || (Xen_is_symbol(e))) active_env = name_to_env((Xen_is_string(e)) ? Xen_string_to_C_string(e) : Xen_symbol_to_C_string(e)); else active_env = xen_to_env(e); if ((!active_env) && (!(Xen_is_list(e)))) Xen_error(NO_SUCH_ENVELOPE, Xen_list_2(C_string_to_Xen_string(S_set S_enved_envelope ": bad envelope arg: ~A"), e)); if (enved_dialog) env_redisplay(); return(e); } static Xen g_enved_filter(void) { #define H_enved_filter "(" S_enved_filter "): envelope editor FIR/FFT filter choice (" PROC_TRUE ": FIR)" return(C_bool_to_Xen_boolean(is_FIR)); } static Xen g_set_enved_filter(Xen type) { Xen_check_type(Xen_is_boolean(type), type, 1, S_set S_enved_filter, "boolean"); is_FIR = Xen_boolean_to_C_bool(type); if (fir_button) gtk_label_set_text(GTK_LABEL(fir_button), (is_FIR) ? "fir" : "fft"); return(type); } Xen_wrap_no_args(g_enved_filter_w, g_enved_filter) Xen_wrap_1_arg(g_set_enved_filter_w, g_set_enved_filter) Xen_wrap_no_args(g_enved_envelope_w, g_enved_envelope) Xen_wrap_1_arg(g_set_enved_envelope_w, g_set_enved_envelope) void g_init_gxenv(void) { Xen_define_dilambda(S_enved_filter, g_enved_filter_w, H_enved_filter, S_set S_enved_filter, g_set_enved_filter_w, 0, 0, 1, 0); Xen_define_dilambda(S_enved_envelope, g_enved_envelope_w, H_enved_envelope, S_set S_enved_envelope, g_set_enved_envelope_w, 0, 0, 1, 0); } snd-16.1/musglyphs.scm0000644000076400007640000004117512620411146013077 0ustar bilbil;; this file loads the music symbol glyphs in cmn-glyphs.lisp (from the cmn package), ;;; each function in that package becomes a Scheme function of the form: ;;; name x y size style snd chn ax ;;; style: #t for lines, #f (default) for filled polygon ;;; ;;; although Snd based here, all this file needs externally are draw-lines, draw-dot, and fill-polygon (provide 'snd-musglyphs.scm) (define make-polygon (lambda (args) (define (total-length vects len) (if (null? vects) len (if (vector? (car vects)) (total-length (cdr vects) (+ len (length (car vects)))) (if (car vects) (total-length (cdr vects) (+ len 1)) (total-length (cdr vects) len))))) (define (set-vals vects start vals) (if (null? vects) vals (if (vector? (car vects)) (let* ((vect (car vects)) (len (length vect))) (do ((i 0 (+ 1 i))) ((= i len)) (set! (vals (+ start i)) (vect i))) (set-vals (cdr vects) (+ start len) vals)) (if (car vects) (begin (set! (vals start) (car vects)) (set-vals (cdr vects) (+ start 1) vals)) (set-vals (cdr vects) start vals))))) (set-vals args 0 (make-vector (total-length args 0))))) (define (make-bezier-1 x0 y0 x1 y1 x2 y2 x3 y3 n) ;; creates a line-segment approximation of a bezier curve: n = number of segments ;; this is built into Snd as make-bezier, but I wanted an all Scheme version (let* ((cx (* 3 (- x1 x0))) (cy (* 3 (- y1 y0))) (bx (- (* 3 (- x2 x1)) cx)) (by (- (* 3 (- y2 y1)) cy)) (ax (- x3 (+ x0 cx bx))) (ay (- y3 (+ y0 cy by))) (incr (/ 1.0 n)) (pts (make-vector (* 2 (+ n 1))))) (set! (pts 0) x0) (set! (pts 1) y0) (do ((i 0 (+ 1 i)) (val incr (+ val incr))) ((> i n) pts) (set! (pts (* i 2)) (floor (+ x0 (* val (+ cx (* val (+ bx (* val ax)))))))) (set! (pts (+ (* i 2) 1)) (floor (+ y0 (* val (+ cy (* val (+ by (* val ay))))))))))) ;; pass our Snd context into the graphics procedures (there's probably a cleaner way) (define ps-snd 0) (define ps-chn 0) (define ps-ax 0) (define yoff 0) (define xoff 0) ;; now make a little Postscript interpreter... (define curx 0) ; the Postscript "path" handlers (define cury 0) (define pathlist ()) (define ps-size 50) (define bezier-segments 50) (define (->x x) (floor (+ xoff (* ps-size x)))) (define (->y y) ;; Postscript is right side up, X is upside-down (floor (- yoff (* ps-size y)))) ;; now functions and macros to make it possible to load the original Common Lisp glyphs directly (define (moveto score x y) (set! curx x) (set! cury y) #f) (define (rmoveto score x y) (set! curx (+ curx x)) (set! cury (+ cury y)) #f) (define (curveto score x0 y0 x1 y1 x2 y2) (set! pathlist (cons (make-bezier-1 (->x curx) (->y cury) (->x x0) (->y y0) (->x x1) (->y y1) (->x x2) (->y y2) bezier-segments) pathlist)) (set! curx x2) (set! cury y2) #f) (define (lineto score x y) (let ((v (make-vector 2))) (set! (v 0) (->x x)) (set! (v 1) (->y y)) (set! curx x) (set! cury y) (set! pathlist (cons v pathlist)) #f)) (define (rlineto score x y) (let ((v (make-vector 2))) (set! curx (+ curx x)) (set! cury (+ cury y)) (set! (v 0) (->x curx)) (set! (v 1) (->y cury)) (set! pathlist (cons v pathlist)) #f)) (define* (fill-in score :rest args) (if (pair? pathlist) (let ((cr (make-cairo (car (channel-widgets ps-snd ps-chn))))) (fill-polygon (make-polygon (reverse pathlist)) ps-snd ps-chn ps-ax cr) (free-cairo cr))) (set! pathlist ()) #f) (define (draw score arg) (if (pair? pathlist) (let ((cr (make-cairo (car (channel-widgets ps-snd ps-chn))))) (draw-lines (make-polygon (reverse pathlist)) ps-snd ps-chn ps-ax cr) (free-cairo cr))) (set! pathlist ()) #f) (define (circle score x0 y0 rad . rest) (let ((cr (make-cairo (car (channel-widgets ps-snd ps-chn))))) (draw-dot (->x x0) (->y y0) (floor (* ps-size rad 2)) ps-snd ps-chn ps-ax cr) (free-cairo cr))) (define-macro (defvar name value) `(define ,name ,value)) (define-macro (setf a b) `(set! ,a ,b)) (define-macro (defun name ignored-args . body) ;; in cmn-glyphs every defun has two args, the "score" and an optional "style" `(define ,name (lambda args ((lambda (score style) ; needed by the procedure body (let ((arglen (length args)) (style #f)) (if (> arglen 0) (set! xoff (list-ref args 0))) (if (> arglen 1) (set! yoff (list-ref args 1))) (if (> arglen 2) (set! ps-size (list-ref args 2))) (if (> arglen 3) (set! style (list-ref args 3))) (if (> arglen 4) (set! ps-snd (list-ref args 4))) (if (> arglen 5) (set! ps-chn (list-ref args 5))) (if (> arglen 6) (set! ps-ax (list-ref args 6))) ,@body)) #f #f)))) (define t #t) (define-macro (in-package name) #f) (define (music-font score) #f) (define g-mustext (lambda args #f)) (define (output-type score) #f) ;(if (defined? 'declare) (define old-declare declare) (define old-declare #f)) ;(define (declare args) #f) (define sound-comment comment) ;(define comment ; (dilambda ; (lambda* ((scr #f) (msg 0)) ; "(comment (scr #f) (msg 0)) tries to make musglyph.scm safe for comments" ; (if (or (number? msg) ; (not scr)) ; (sound-comment scr))) ; (lambda* (snd (val #f)) ; (if (not val) ; (apply (setter sound-comment) (list #f snd)) ; (apply (setter sound-comment) (list snd val)))))) ;(load "loop.scm") ; Rick's loop implementation (cm/src/loop.scm) (define progn begin) (load "cmn-glyphs.lisp") ;;; a portion of CMN here to make it easier to display notes (define (frequency->note-octave-and-accidental freq) (define (frequency->pitch freq) (floor (* 12 (+ (log (/ freq 16.351) 2) (/ 1.0 24))))) (define (pitch->note-octave-and-accidental pitch) (let* ((pclass (modulo pitch 12)) (octave (floor (/ pitch 12))) (cclass (case pclass ((0 1) 0) ; c-sharp ((2) 1) ((3 4) 2) ; e-flat ((5 6) 3) ; f-sharp ((7) 4) ((8 9) 5) ; a-flat (else 6)))) ; b-flat (list pclass octave (if (or (= pclass 1) (= pclass 6)) :sharp (and (or (= pclass 3) (= pclass 8) (= pclass 10)) :flat)) cclass pitch))) (pitch->note-octave-and-accidental (frequency->pitch freq))) (define note-data->pclass car) (define note-data->octave cadr) (define note-data->accidental caddr) (define note-data->cclass cadddr) (define (note-data->pitch val) (list-ref val 4)) (define (draw-staff x0 y0 width line-sep) (let ((cr (make-cairo (car (channel-widgets ps-snd ps-chn))))) (do ((line 0 (+ 1 line)) (x x0) (y y0 (+ y line-sep))) ((= line 5)) (draw-line x y (+ x width) y ps-snd ps-chn time-graph cr)) (free-cairo cr))) (define treble-tag-y 30) (define bass-tag-y (+ treble-tag-y (* 4 *mix-waveform-height*))) (define (draw-a-note freq dur x0 ty0 size with-clef treble) (let* ((line-sep (* size .250)) (note-data (frequency->note-octave-and-accidental freq)) (accidental (note-data->accidental note-data)) (cclass (note-data->cclass note-data)) (octave (note-data->octave note-data)) ;(pitch (note-data->pitch note-data)) (y0 (if treble treble-tag-y bass-tag-y)) (width (* (+ (if with-clef (if treble 0.9 1.2) 0.75) (if accidental 0.1 0.0) (if (< dur .8) 0.5 0.0)) size)) (line (if treble (+ (* (- 5 octave) 7) (- 3 cclass)) (+ (* (- 3 octave) 7) (- 5 cclass)))) (notehead-x x0) (notehead-y y0)) (draw-staff x0 y0 width line-sep) (if with-clef (begin (if treble (draw-treble-clef x0 (+ y0 (* size .76)) size) (draw-bass-clef (+ x0 (* size .075)) (+ y0 (* size .26)) size)) (set! x0 (+ x0 (* size .8)))) (if accidental (set! x0 (+ x0 (* size .1))) (set! x0 (+ x0 (* size .25))))) ;; accidental (if accidental (begin ((if (eq? accidental :sharp) draw-sharp draw-flat) x0 (+ y0 (* .02 size) (* line-sep 0.5 line)) size) (set! x0 (+ x0 (* .25 size))))) ;; notehead (set! notehead-y (+ y0 (* .02 size) (* line-sep 0.5 line))) (set! notehead-x x0) ((if (< dur 1.5) draw-quarter-note (if (< dur 3.5) draw-half-note draw-whole-note)) notehead-x notehead-y size) ;; leger line(s) (if (> line 9) (do ((i 10 (+ i 2))) ((>= i line)) (fill-rectangle (- x0 (* .1 size)) (+ y0 (* -.02 size) (* line-sep 0.5 i)) (* .5 size) (* .05 size)))) (if (< line 0) (do ((i -2 (- i 2))) ((< i line)) (fill-rectangle (- x0 (* .1 size)) (+ y0 (* -.02 size) (* line-sep 0.5 i)) (* .5 size) (* .05 size)))) ;; stem (if (< dur 3) (if (> line 3) ;; stem up (fill-rectangle (+ x0 (* size .25)) (+ y0 (* .02 size) (* size -0.8) (* line-sep 0.5 line)) (* size .05) (* size 0.8)) (fill-rectangle (- x0 (* size .02)) (+ y0 (* line-sep line 0.5)) (* size .05) (* size 0.8)))) ;; flags (if (< dur .6) (let ((base (+ y0 (* line-sep 0.5 line)))) (if (> line 2) (draw-8th-flag-up (+ x0 (* size .25)) (+ base (* size -0.6)) size) (draw-8th-flag-down x0 (+ base (* .7 size)) size)) (if (< dur .3) (begin (if (> line 2) (draw-extend-flag-up (+ x0 (* size .25)) (+ base (* size -0.8)) size) (draw-extend-flag-down x0 (+ base (* .9 size)) size)) (if (< dur .15) (if (> line 2) (draw-extend-flag-up (+ x0 (* size .25)) (+ base (* size -1.0)) size) (draw-extend-flag-down x0 (+ base (* 1.1 size)) size))))))) (list notehead-x notehead-y))) #| ;; this is the example in the documentation (define (draw-mix-tag id ox oy x y) (let ((width *mix-tag-width*) (height *mix-tag-height*) (home (mix-home id))) (if (not (= oy -1)) ; already erased? (fill-rectangle (- ox 1 (/ width 2)) (- oy 1 height) (+ width 2) (+ height 2) (car home) (cadr home) time-graph #t)) (fill-rectangle (- x (/ width 2)) (- y height) width height (car home) (cadr home)))) (hook-push draw-mix-hook (lambda (hook) (let ((id (hook 'id)) (ox (hook 'old-x)) (oy (hook 'old-y)) (x (hook 'x)) (y (hook 'y))) (draw-mix-tag id ox oy x y) (draw-a-note (or (mix-property 'frequency id) 440.0) (/ (length id) (srate)) x y (* 2 *mix-waveform-height*) #f (eq? (mix-property 'instrument id) 'violin))) (set! (hook 'result) #t))) (hook-push after-graph-hook (lambda (hook) (let ((size (* 2 *mix-waveform-height*))) (draw-staff 0 treble-tag-y (* 1.0 size) (* .25 size)) (draw-staff 0 bass-tag-y (* 1.0 size) (* .25 size)) (draw-treble-clef 0 (+ treble-tag-y (* size .76)) size) (draw-bass-clef (* size .075) (+ bass-tag-y (* size .26)) size)))) (set! *mix-waveform-height* 20) (let ((oldie (find-sound "test.snd"))) (if (sound? oldie) (close-sound oldie))) (let ((index (new-sound "test.snd" :channels 1))) (define (violin beg dur freq amp) (let* ((frq-hz (* 2 (->frequency freq #t))) (id (car (mix (with-temp-sound () (fm-violin 0 dur frq-hz amp)) (->sample beg) 0 index 0 ; start, file in-chan, sound, channel #t #t)))) ; with tag and auto-delete (set! (mix-property 'frequency id) frq-hz) (set! (mix-property 'instrument id) 'violin))) (define (cello beg dur freq amp) (let* ((frq-hz (* 2 (->frequency freq #t))) (id (car (mix (with-temp-sound () (fm-violin 0 dur frq-hz amp :fm-index 1.5)) (->sample beg) 0 index 0 #t #t)))) (set! (mix-property 'frequency id) frq-hz) (set! (mix-property 'instrument id) 'cello))) (as-one-edit (lambda () (violin 0 1 'e4 .2) (violin 1 1.5 'g4 .2) (violin 2.5 .5 'g3 .2) (cello 0 1 'c3 .2) (cello 1 1.5 'e3 .2) (cello 2.5 .5 'g2 .2) (violin 3 3 'f4 .2) (cello 3 3 'd3 .2) (violin 6 1 'e4 .2) (violin 7 1 'g3 .2) (violin 8 1 'e4 .2) (cello 6 1 'c3 .2) (cello 7 1 'g2 .2) (cello 8 1 'c3 .2) (violin 9 3 'd4 .2) (cello 9 3 'b2 .2) (violin 12 1 'f4 .2) (violin 13 1.5 'a4 .2) (violin 14.5 .5 'g3 .2) (cello 12 1 'd3 .2) (cello 13 1.5 'f3 .2) (cello 14.5 .5 'g2 .2) (violin 15 3 'g4 .2) (cello 15 3 'e3 .2) (violin 18 1 'f4 .2) (violin 19 1 'g3 .2) (violin 20 1 'f4 .2) (cello 18 1 'd3 .2) (cello 19 1 'g2 .2) (cello 20 1 'd3 .2) (violin 21 3 'e4 .2) (cello 21 3 'c3 .2)))) |# #| ;;; here is the same example, but with vertical drag interpreted as pitch change, and the ;;; note head itself is the mix tag: (set! *show-mix-waveforms* #f) (hook-push draw-mix-hook (lambda (hook) (let* ((id (hook 'id)) (x (hook 'x)) (y (hook 'y)) (xy (draw-a-note (or (mix-property 'frequency id) 440.0) (/ (length id) (srate)) x y (* 2 *mix-waveform-height*) #f (eq? (mix-property 'instrument id) 'violin))) (note-x (round (car xy))) (note-y (round (- (cadr xy) *mix-tag-height*)))) (if (not (mix-property 'original-tag-y id)) (begin (set! (mix-property 'original-frequency id) (mix-property 'frequency id)) (set! (mix-property 'original-tag-y id) note-y) (set! (mix-property 'interval id) 0))) (set! (hook 'result) (list note-x note-y))))) (hook-push after-graph-hook (lambda (hook) (let ((size (* 2 *mix-waveform-height*))) (draw-staff 0 treble-tag-y (* 1.0 size) (* .25 size)) (draw-staff 0 bass-tag-y (* 1.0 size) (* .25 size)) (draw-treble-clef 0 (+ treble-tag-y (* size .76)) size) (draw-bass-clef (* size .075) (+ bass-tag-y (* size .26)) size)))) (hook-push mix-drag-hook (lambda (hook) (let* ((n (hook 'id)) (x (hook 'x)) (y (hook 'y)) (orig-y (mix-property 'original-tag-y n))) (if orig-y (let ((interval (round (/ (* 12 (- (+ *mix-tag-height* orig-y) y)) (* 2 *mix-waveform-height*)))) (current-interval (mix-property 'interval n))) ;; this gives the number of semitones we have drifted (if (not (= current-interval interval)) (begin (set! (mix-property 'interval n) interval) (set! (mix-property 'frequency n) (* (mix-property 'original-frequency n) (expt 2.0 (/ interval 12.0))))))))))) (hook-push mix-release-hook (lambda (hook) (let ((n (hook 'id)) (samps (hook 'samples))) (as-one-edit (lambda () (set! (mix-position id) (+ samps (mix-position id))) (let ((interval (mix-property 'interval id))) (if (not (= interval 0)) (let ((last-interval (mix-property 'last-interval id))) (if (or (not last-interval) (not (= last-interval interval))) (set! (mix-speed id) (expt 2.0 (/ interval 12.0)))))) (set! (mix-property 'last-interval id) interval)))) (set! (hook 'result) #t)))) (set! *mix-waveform-height* 20) (let ((oldie (find-sound "test.snd"))) (if (sound? oldie) (close-sound oldie))) (let ((violin-sync 1) (violin-color (make-color 0 0 0.85)) ; blueish (cello-sync 2) (cello-color (make-color 1 .7 0)) ; orangeish (index (new-sound "test.snd" :channels 1))) ; :size (* 22050 22)))) (define (violin beg dur freq amp) (let* ((frq-hz (* 2 (->frequency freq #t))) (id (car (mix (with-temp-sound () (fm-violin 0 dur frq-hz amp)) (->sample beg) 0 index 0 ; start, file in-chan, sound, channel #t #t)))) ; with tag and auto-delete (set! (mix-property 'frequency id) frq-hz) (set! (mix-property 'instrument id) 'violin) (set! (mix-sync id) violin-sync) (set! (mix-color id) violin-color))) (define (cello beg dur freq amp) (let* ((frq-hz (* 2 (->frequency freq #t))) (id (car (mix (with-temp-sound () (fm-violin 0 dur frq-hz amp :fm-index 1.5)) (->sample beg) 0 index 0 #t #t)))) (set! (mix-property 'frequency id) frq-hz) (set! (mix-property 'instrument id) 'cello) (set! (mix-sync id) cello-sync) (set! (mix-color id) cello-color))) (as-one-edit (lambda () (violin 0 1 'e4 .2) (violin 1 1.5 'g4 .2) (violin 2.5 .5 'g3 .2) (cello 0 1 'c3 .2) (cello 1 1.5 'e3 .2) (cello 2.5 .5 'g2 .2) (violin 3 3 'f4 .2) (cello 3 3 'd3 .2) (violin 6 1 'e4 .2) (violin 7 1 'g3 .2) (violin 8 1 'e4 .2) (cello 6 1 'c3 .2) (cello 7 1 'g2 .2) (cello 8 1 'c3 .2) (violin 9 3 'd4 .2) (cello 9 3 'b2 .2) (violin 12 1 'f4 .2) (violin 13 1.5 'a4 .2) (violin 14.5 .5 'g3 .2) (cello 12 1 'd3 .2) (cello 13 1.5 'f3 .2) (cello 14.5 .5 'g2 .2) (violin 15 3 'g4 .2) (cello 15 3 'e3 .2) (violin 18 1 'f4 .2) (violin 19 1 'g3 .2) (violin 20 1 'f4 .2) (cello 18 1 'd3 .2) (cello 19 1 'g2 .2) (cello 20 1 'd3 .2) (violin 21 3 'e4 .2) (cello 21 3 'c3 .2) index))) |# snd-16.1/rgb.fs0000644000076400007640000007170312306421672011452 0ustar bilbil\ rgb.fs -- rgb.scm|rb --> rgb.fs \ Author: Michael Scholz \ Created: Fri Aug 18 16:57:43 CEST 2006 \ Changed: Fri Mar 23 22:50:07 CET 2012 \ Commentary: \ \ ;;; X11 color names converted to Snd colors \ ;; tan -> tawny 24-Aug-01 \ \ e.g.: jet-colormap set-colormap drop \ \ Code: 1.00 0.98 0.98 make-color constant snow 0.97 0.97 1.00 make-color constant ghost-white 0.96 0.96 0.96 make-color constant white-smoke 0.86 0.86 0.86 make-color constant gainsboro 1.00 0.98 0.94 make-color constant floral-white 0.99 0.96 0.90 make-color constant old-lace 0.98 0.94 0.90 make-color constant linen 0.98 0.92 0.84 make-color constant antique-white 1.00 0.93 0.83 make-color constant papaya-whip 1.00 0.92 0.80 make-color constant blanched-almond 1.00 0.89 0.77 make-color constant bisque 1.00 0.85 0.72 make-color constant peach-puff 1.00 0.87 0.68 make-color constant navajo-white 1.00 0.89 0.71 make-color constant moccasin 1.00 0.97 0.86 make-color constant cornsilk 1.00 1.00 0.94 make-color constant ivory 1.00 0.98 0.80 make-color constant lemon-chiffon 1.00 0.96 0.93 make-color constant seashell 0.94 1.00 0.94 make-color constant honeydew 0.96 1.00 0.98 make-color constant mint-cream 0.94 1.00 1.00 make-color constant azure 0.94 0.97 1.00 make-color constant alice-blue 0.90 0.90 0.98 make-color constant lavender 1.00 0.94 0.96 make-color constant lavender-blush 1.00 0.89 0.88 make-color constant misty-rose 1.00 1.00 1.00 make-color constant white 0.00 0.00 0.00 make-color constant black 0.18 0.31 0.31 make-color constant dark-slate-gray 0.18 0.31 0.31 make-color constant dark-slate-grey 0.41 0.41 0.41 make-color constant dim-gray 0.41 0.41 0.41 make-color constant dim-grey 0.44 0.50 0.56 make-color constant slate-gray 0.44 0.50 0.56 make-color constant slate-grey 0.46 0.53 0.60 make-color constant light-slate-gray 0.46 0.53 0.60 make-color constant light-slate-grey 0.74 0.74 0.74 make-color constant gray 0.74 0.74 0.74 make-color constant grey 0.82 0.82 0.82 make-color constant light-grey 0.82 0.82 0.82 make-color constant light-gray 0.10 0.10 0.44 make-color constant midnight-blue 0.00 0.00 0.50 make-color constant navy 0.00 0.00 0.50 make-color constant navy-blue 0.39 0.58 0.93 make-color constant cornflower-blue 0.28 0.24 0.54 make-color constant dark-slate-blue 0.41 0.35 0.80 make-color constant slate-blue 0.48 0.41 0.93 make-color constant medium-slate-blue 0.52 0.44 1.00 make-color constant light-slate-blue 0.00 0.00 0.80 make-color constant medium-blue 0.25 0.41 0.88 make-color constant royal-blue 0.00 0.00 1.00 make-color constant blue 0.12 0.56 1.00 make-color constant dodger-blue 0.00 0.75 1.00 make-color constant deep-sky-blue 0.53 0.80 0.92 make-color constant sky-blue 0.53 0.80 0.98 make-color constant light-sky-blue 0.27 0.51 0.70 make-color constant steel-blue 0.69 0.77 0.87 make-color constant light-steel-blue 0.68 0.84 0.90 make-color constant light-blue 0.69 0.87 0.90 make-color constant powder-blue 0.68 0.93 0.93 make-color constant pale-turquoise 0.00 0.80 0.82 make-color constant dark-turquoise 0.28 0.82 0.80 make-color constant medium-turquoise 0.25 0.87 0.81 make-color constant turquoise 0.00 1.00 1.00 make-color constant cyan 0.87 1.00 1.00 make-color constant light-cyan 0.37 0.62 0.62 make-color constant cadet-blue 0.40 0.80 0.66 make-color constant medium-aquamarine 0.50 1.00 0.83 make-color constant aquamarine 0.00 0.39 0.00 make-color constant dark-green 0.33 0.42 0.18 make-color constant dark-olive-green 0.56 0.73 0.56 make-color constant dark-sea-green 0.18 0.54 0.34 make-color constant sea-green 0.23 0.70 0.44 make-color constant medium-sea-green 0.12 0.70 0.66 make-color constant light-sea-green 0.59 0.98 0.59 make-color constant pale-green 0.00 1.00 0.50 make-color constant spring-green 0.48 0.98 0.00 make-color constant lawn-green 0.00 1.00 0.00 make-color constant green 0.50 1.00 0.00 make-color constant chartreuse 0.00 0.98 0.60 make-color constant medium-spring-green 0.68 1.00 0.18 make-color constant green-yellow 0.20 0.80 0.20 make-color constant lime-green 0.60 0.80 0.20 make-color constant yellow-green 0.13 0.54 0.13 make-color constant forest-green 0.42 0.55 0.14 make-color constant olive-drab 0.74 0.71 0.42 make-color constant dark-khaki 0.94 0.90 0.55 make-color constant khaki 0.93 0.91 0.66 make-color constant pale-goldenrod 0.98 0.98 0.82 make-color constant light-goldenrod-yellow 1.00 1.00 0.87 make-color constant light-yellow 1.00 1.00 0.00 make-color constant yellow 1.00 0.84 0.00 make-color constant gold 0.93 0.86 0.51 make-color constant light-goldenrod 0.85 0.64 0.12 make-color constant goldenrod 0.72 0.52 0.04 make-color constant dark-goldenrod 0.73 0.56 0.56 make-color constant rosy-brown 0.80 0.36 0.36 make-color constant indian-red 0.54 0.27 0.07 make-color constant saddle-brown 0.62 0.32 0.18 make-color constant sienna 0.80 0.52 0.25 make-color constant peru 0.87 0.72 0.53 make-color constant burlywood 0.96 0.96 0.86 make-color constant beige 0.96 0.87 0.70 make-color constant wheat 0.95 0.64 0.37 make-color constant sandy-brown \ tan collides with Scheme built-in -- tawny suggested by Dave Phillips 0.82 0.70 0.55 make-color constant tawny 0.82 0.41 0.12 make-color constant chocolate 0.70 0.13 0.13 make-color constant firebrick 0.64 0.16 0.16 make-color constant brown 0.91 0.59 0.48 make-color constant dark-salmon 0.98 0.50 0.45 make-color constant salmon 1.00 0.62 0.48 make-color constant light-salmon 1.00 0.64 0.00 make-color constant orange 1.00 0.55 0.00 make-color constant dark-orange 1.00 0.50 0.31 make-color constant coral 0.94 0.50 0.50 make-color constant light-coral 1.00 0.39 0.28 make-color constant tomato 1.00 0.27 0.00 make-color constant orange-red 1.00 0.00 0.00 make-color constant red 1.00 0.41 0.70 make-color constant hot-pink 1.00 0.08 0.57 make-color constant deep-pink 1.00 0.75 0.79 make-color constant pink 1.00 0.71 0.75 make-color constant light-pink 0.86 0.44 0.57 make-color constant pale-violet-red 0.69 0.19 0.37 make-color constant maroon 0.78 0.08 0.52 make-color constant medium-violet-red 0.81 0.12 0.56 make-color constant violet-red 1.00 0.00 1.00 make-color constant magenta 0.93 0.51 0.93 make-color constant violet 0.86 0.62 0.86 make-color constant plum 0.85 0.44 0.84 make-color constant orchid 0.73 0.33 0.82 make-color constant medium-orchid 0.60 0.20 0.80 make-color constant dark-orchid 0.58 0.00 0.82 make-color constant dark-violet 0.54 0.17 0.88 make-color constant blue-violet 0.62 0.12 0.94 make-color constant purple 0.57 0.44 0.86 make-color constant medium-purple 0.84 0.75 0.84 make-color constant thistle 1.00 0.98 0.98 make-color constant snow1 0.93 0.91 0.91 make-color constant snow2 0.80 0.79 0.79 make-color constant snow3 0.54 0.54 0.54 make-color constant snow4 1.00 0.96 0.93 make-color constant seashell1 0.93 0.89 0.87 make-color constant seashell2 0.80 0.77 0.75 make-color constant seashell3 0.54 0.52 0.51 make-color constant seashell4 1.00 0.93 0.86 make-color constant antiquewhite1 0.93 0.87 0.80 make-color constant antiquewhite2 0.80 0.75 0.69 make-color constant antiquewhite3 0.54 0.51 0.47 make-color constant antiquewhite4 1.00 0.89 0.77 make-color constant bisque1 0.93 0.83 0.71 make-color constant bisque2 0.80 0.71 0.62 make-color constant bisque3 0.54 0.49 0.42 make-color constant bisque4 1.00 0.85 0.72 make-color constant peachpuff1 0.93 0.79 0.68 make-color constant peachpuff2 0.80 0.68 0.58 make-color constant peachpuff3 0.54 0.46 0.39 make-color constant peachpuff4 1.00 0.87 0.68 make-color constant navajowhite1 0.93 0.81 0.63 make-color constant navajowhite2 0.80 0.70 0.54 make-color constant navajowhite3 0.54 0.47 0.37 make-color constant navajowhite4 1.00 0.98 0.80 make-color constant lemonchiffon1 0.93 0.91 0.75 make-color constant lemonchiffon2 0.80 0.79 0.64 make-color constant lemonchiffon3 0.54 0.54 0.44 make-color constant lemonchiffon4 1.00 0.97 0.86 make-color constant cornsilk1 0.93 0.91 0.80 make-color constant cornsilk2 0.80 0.78 0.69 make-color constant cornsilk3 0.54 0.53 0.47 make-color constant cornsilk4 1.00 1.00 0.94 make-color constant ivory1 0.93 0.93 0.87 make-color constant ivory2 0.80 0.80 0.75 make-color constant ivory3 0.54 0.54 0.51 make-color constant ivory4 0.94 1.00 0.94 make-color constant honeydew1 0.87 0.93 0.87 make-color constant honeydew2 0.75 0.80 0.75 make-color constant honeydew3 0.51 0.54 0.51 make-color constant honeydew4 1.00 0.94 0.96 make-color constant lavenderblush1 0.93 0.87 0.89 make-color constant lavenderblush2 0.80 0.75 0.77 make-color constant lavenderblush3 0.54 0.51 0.52 make-color constant lavenderblush4 1.00 0.89 0.88 make-color constant mistyrose1 0.93 0.83 0.82 make-color constant mistyrose2 0.80 0.71 0.71 make-color constant mistyrose3 0.54 0.49 0.48 make-color constant mistyrose4 0.94 1.00 1.00 make-color constant azure1 0.87 0.93 0.93 make-color constant azure2 0.75 0.80 0.80 make-color constant azure3 0.51 0.54 0.54 make-color constant azure4 0.51 0.43 1.00 make-color constant slateblue1 0.48 0.40 0.93 make-color constant slateblue2 0.41 0.35 0.80 make-color constant slateblue3 0.28 0.23 0.54 make-color constant slateblue4 0.28 0.46 1.00 make-color constant royalblue1 0.26 0.43 0.93 make-color constant royalblue2 0.23 0.37 0.80 make-color constant royalblue3 0.15 0.25 0.54 make-color constant royalblue4 0.00 0.00 1.00 make-color constant blue1 0.00 0.00 0.93 make-color constant blue2 0.00 0.00 0.80 make-color constant blue3 0.00 0.00 0.54 make-color constant blue4 0.12 0.56 1.00 make-color constant dodgerblue1 0.11 0.52 0.93 make-color constant dodgerblue2 0.09 0.45 0.80 make-color constant dodgerblue3 0.06 0.30 0.54 make-color constant dodgerblue4 0.39 0.72 1.00 make-color constant steelblue1 0.36 0.67 0.93 make-color constant steelblue2 0.31 0.58 0.80 make-color constant steelblue3 0.21 0.39 0.54 make-color constant steelblue4 0.00 0.75 1.00 make-color constant deepskyblue1 0.00 0.70 0.93 make-color constant deepskyblue2 0.00 0.60 0.80 make-color constant deepskyblue3 0.00 0.41 0.54 make-color constant deepskyblue4 0.53 0.80 1.00 make-color constant skyblue1 0.49 0.75 0.93 make-color constant skyblue2 0.42 0.65 0.80 make-color constant skyblue3 0.29 0.44 0.54 make-color constant skyblue4 0.69 0.88 1.00 make-color constant lightskyblue1 0.64 0.82 0.93 make-color constant lightskyblue2 0.55 0.71 0.80 make-color constant lightskyblue3 0.37 0.48 0.54 make-color constant lightskyblue4 0.77 0.88 1.00 make-color constant slategray1 0.72 0.82 0.93 make-color constant slategray2 0.62 0.71 0.80 make-color constant slategray3 0.42 0.48 0.54 make-color constant slategray4 0.79 0.88 1.00 make-color constant lightsteelblue1 0.73 0.82 0.93 make-color constant lightsteelblue2 0.63 0.71 0.80 make-color constant lightsteelblue3 0.43 0.48 0.54 make-color constant lightsteelblue4 0.75 0.93 1.00 make-color constant lightblue1 0.70 0.87 0.93 make-color constant lightblue2 0.60 0.75 0.80 make-color constant lightblue3 0.41 0.51 0.54 make-color constant lightblue4 0.87 1.00 1.00 make-color constant lightcyan1 0.82 0.93 0.93 make-color constant lightcyan2 0.70 0.80 0.80 make-color constant lightcyan3 0.48 0.54 0.54 make-color constant lightcyan4 0.73 1.00 1.00 make-color constant paleturquoise1 0.68 0.93 0.93 make-color constant paleturquoise2 0.59 0.80 0.80 make-color constant paleturquoise3 0.40 0.54 0.54 make-color constant paleturquoise4 0.59 0.96 1.00 make-color constant cadetblue1 0.55 0.89 0.93 make-color constant cadetblue2 0.48 0.77 0.80 make-color constant cadetblue3 0.32 0.52 0.54 make-color constant cadetblue4 0.00 0.96 1.00 make-color constant turquoise1 0.00 0.89 0.93 make-color constant turquoise2 0.00 0.77 0.80 make-color constant turquoise3 0.00 0.52 0.54 make-color constant turquoise4 0.00 1.00 1.00 make-color constant cyan1 0.00 0.93 0.93 make-color constant cyan2 0.00 0.80 0.80 make-color constant cyan3 0.00 0.54 0.54 make-color constant cyan4 0.59 1.00 1.00 make-color constant darkslategray1 0.55 0.93 0.93 make-color constant darkslategray2 0.47 0.80 0.80 make-color constant darkslategray3 0.32 0.54 0.54 make-color constant darkslategray4 0.50 1.00 0.83 make-color constant aquamarine1 0.46 0.93 0.77 make-color constant aquamarine2 0.40 0.80 0.66 make-color constant aquamarine3 0.27 0.54 0.45 make-color constant aquamarine4 0.75 1.00 0.75 make-color constant darkseagreen1 0.70 0.93 0.70 make-color constant darkseagreen2 0.61 0.80 0.61 make-color constant darkseagreen3 0.41 0.54 0.41 make-color constant darkseagreen4 0.33 1.00 0.62 make-color constant seagreen1 0.30 0.93 0.58 make-color constant seagreen2 0.26 0.80 0.50 make-color constant seagreen3 0.18 0.54 0.34 make-color constant seagreen4 0.60 1.00 0.60 make-color constant palegreen1 0.56 0.93 0.56 make-color constant palegreen2 0.48 0.80 0.48 make-color constant palegreen3 0.33 0.54 0.33 make-color constant palegreen4 0.00 1.00 0.50 make-color constant springgreen1 0.00 0.93 0.46 make-color constant springgreen2 0.00 0.80 0.40 make-color constant springgreen3 0.00 0.54 0.27 make-color constant springgreen4 0.00 1.00 0.00 make-color constant green1 0.00 0.93 0.00 make-color constant green2 0.00 0.80 0.00 make-color constant green3 0.00 0.54 0.00 make-color constant green4 0.50 1.00 0.00 make-color constant chartreuse1 0.46 0.93 0.00 make-color constant chartreuse2 0.40 0.80 0.00 make-color constant chartreuse3 0.27 0.54 0.00 make-color constant chartreuse4 0.75 1.00 0.24 make-color constant olivedrab1 0.70 0.93 0.23 make-color constant olivedrab2 0.60 0.80 0.20 make-color constant olivedrab3 0.41 0.54 0.13 make-color constant olivedrab4 0.79 1.00 0.44 make-color constant darkolivegreen1 0.73 0.93 0.41 make-color constant darkolivegreen2 0.63 0.80 0.35 make-color constant darkolivegreen3 0.43 0.54 0.24 make-color constant darkolivegreen4 1.00 0.96 0.56 make-color constant khaki1 0.93 0.90 0.52 make-color constant khaki2 0.80 0.77 0.45 make-color constant khaki3 0.54 0.52 0.30 make-color constant khaki4 1.00 0.92 0.54 make-color constant lightgoldenrod1 0.93 0.86 0.51 make-color constant lightgoldenrod2 0.80 0.74 0.44 make-color constant lightgoldenrod3 0.54 0.50 0.30 make-color constant lightgoldenrod4 1.00 1.00 0.87 make-color constant lightyellow1 0.93 0.93 0.82 make-color constant lightyellow2 0.80 0.80 0.70 make-color constant lightyellow3 0.54 0.54 0.48 make-color constant lightyellow4 1.00 1.00 0.00 make-color constant yellow1 0.93 0.93 0.00 make-color constant yellow2 0.80 0.80 0.00 make-color constant yellow3 0.54 0.54 0.00 make-color constant yellow4 1.00 0.84 0.00 make-color constant gold1 0.93 0.79 0.00 make-color constant gold2 0.80 0.68 0.00 make-color constant gold3 0.54 0.46 0.00 make-color constant gold4 1.00 0.75 0.14 make-color constant goldenrod1 0.93 0.70 0.13 make-color constant goldenrod2 0.80 0.61 0.11 make-color constant goldenrod3 0.54 0.41 0.08 make-color constant goldenrod4 1.00 0.72 0.06 make-color constant darkgoldenrod1 0.93 0.68 0.05 make-color constant darkgoldenrod2 0.80 0.58 0.05 make-color constant darkgoldenrod3 0.54 0.39 0.03 make-color constant darkgoldenrod4 1.00 0.75 0.75 make-color constant rosybrown1 0.93 0.70 0.70 make-color constant rosybrown2 0.80 0.61 0.61 make-color constant rosybrown3 0.54 0.41 0.41 make-color constant rosybrown4 1.00 0.41 0.41 make-color constant indianred1 0.93 0.39 0.39 make-color constant indianred2 0.80 0.33 0.33 make-color constant indianred3 0.54 0.23 0.23 make-color constant indianred4 1.00 0.51 0.28 make-color constant sienna1 0.93 0.47 0.26 make-color constant sienna2 0.80 0.41 0.22 make-color constant sienna3 0.54 0.28 0.15 make-color constant sienna4 1.00 0.82 0.61 make-color constant burlywood1 0.93 0.77 0.57 make-color constant burlywood2 0.80 0.66 0.49 make-color constant burlywood3 0.54 0.45 0.33 make-color constant burlywood4 1.00 0.90 0.73 make-color constant wheat1 0.93 0.84 0.68 make-color constant wheat2 0.80 0.73 0.59 make-color constant wheat3 0.54 0.49 0.40 make-color constant wheat4 1.00 0.64 0.31 make-color constant tan1 0.93 0.60 0.29 make-color constant tan2 0.80 0.52 0.25 make-color constant tan3 0.54 0.35 0.17 make-color constant tan4 1.00 0.50 0.14 make-color constant chocolate1 0.93 0.46 0.13 make-color constant chocolate2 0.80 0.40 0.11 make-color constant chocolate3 0.54 0.27 0.07 make-color constant chocolate4 1.00 0.19 0.19 make-color constant firebrick1 0.93 0.17 0.17 make-color constant firebrick2 0.80 0.15 0.15 make-color constant firebrick3 0.54 0.10 0.10 make-color constant firebrick4 1.00 0.25 0.25 make-color constant brown1 0.93 0.23 0.23 make-color constant brown2 0.80 0.20 0.20 make-color constant brown3 0.54 0.14 0.14 make-color constant brown4 1.00 0.55 0.41 make-color constant salmon1 0.93 0.51 0.38 make-color constant salmon2 0.80 0.44 0.33 make-color constant salmon3 0.54 0.30 0.22 make-color constant salmon4 1.00 0.62 0.48 make-color constant lightsalmon1 0.93 0.58 0.45 make-color constant lightsalmon2 0.80 0.50 0.38 make-color constant lightsalmon3 0.54 0.34 0.26 make-color constant lightsalmon4 1.00 0.64 0.00 make-color constant orange1 0.93 0.60 0.00 make-color constant orange2 0.80 0.52 0.00 make-color constant orange3 0.54 0.35 0.00 make-color constant orange4 1.00 0.50 0.00 make-color constant darkorange1 0.93 0.46 0.00 make-color constant darkorange2 0.80 0.40 0.00 make-color constant darkorange3 0.54 0.27 0.00 make-color constant darkorange4 1.00 0.45 0.34 make-color constant coral1 0.93 0.41 0.31 make-color constant coral2 0.80 0.36 0.27 make-color constant coral3 0.54 0.24 0.18 make-color constant coral4 1.00 0.39 0.28 make-color constant tomato1 0.93 0.36 0.26 make-color constant tomato2 0.80 0.31 0.22 make-color constant tomato3 0.54 0.21 0.15 make-color constant tomato4 1.00 0.27 0.00 make-color constant orangered1 0.93 0.25 0.00 make-color constant orangered2 0.80 0.21 0.00 make-color constant orangered3 0.54 0.14 0.00 make-color constant orangered4 1.00 0.00 0.00 make-color constant red1 0.93 0.00 0.00 make-color constant red2 0.80 0.00 0.00 make-color constant red3 0.54 0.00 0.00 make-color constant red4 1.00 0.08 0.57 make-color constant deeppink1 0.93 0.07 0.54 make-color constant deeppink2 0.80 0.06 0.46 make-color constant deeppink3 0.54 0.04 0.31 make-color constant deeppink4 1.00 0.43 0.70 make-color constant hotpink1 0.93 0.41 0.65 make-color constant hotpink2 0.80 0.37 0.56 make-color constant hotpink3 0.54 0.23 0.38 make-color constant hotpink4 1.00 0.71 0.77 make-color constant pink1 0.93 0.66 0.72 make-color constant pink2 0.80 0.57 0.62 make-color constant pink3 0.54 0.39 0.42 make-color constant pink4 1.00 0.68 0.72 make-color constant lightpink1 0.93 0.63 0.68 make-color constant lightpink2 0.80 0.55 0.58 make-color constant lightpink3 0.54 0.37 0.39 make-color constant lightpink4 1.00 0.51 0.67 make-color constant palevioletred1 0.93 0.47 0.62 make-color constant palevioletred2 0.80 0.41 0.54 make-color constant palevioletred3 0.54 0.28 0.36 make-color constant palevioletred4 1.00 0.20 0.70 make-color constant maroon1 0.93 0.19 0.65 make-color constant maroon2 0.80 0.16 0.56 make-color constant maroon3 0.54 0.11 0.38 make-color constant maroon4 1.00 0.24 0.59 make-color constant violetred1 0.93 0.23 0.55 make-color constant violetred2 0.80 0.20 0.47 make-color constant violetred3 0.54 0.13 0.32 make-color constant violetred4 1.00 0.00 1.00 make-color constant magenta1 0.93 0.00 0.93 make-color constant magenta2 0.80 0.00 0.80 make-color constant magenta3 0.54 0.00 0.54 make-color constant magenta4 1.00 0.51 0.98 make-color constant orchid1 0.93 0.48 0.91 make-color constant orchid2 0.80 0.41 0.79 make-color constant orchid3 0.54 0.28 0.54 make-color constant orchid4 1.00 0.73 1.00 make-color constant plum1 0.93 0.68 0.93 make-color constant plum2 0.80 0.59 0.80 make-color constant plum3 0.54 0.40 0.54 make-color constant plum4 0.87 0.40 1.00 make-color constant mediumorchid1 0.82 0.37 0.93 make-color constant mediumorchid2 0.70 0.32 0.80 make-color constant mediumorchid3 0.48 0.21 0.54 make-color constant mediumorchid4 0.75 0.24 1.00 make-color constant darkorchid1 0.70 0.23 0.93 make-color constant darkorchid2 0.60 0.20 0.80 make-color constant darkorchid3 0.41 0.13 0.54 make-color constant darkorchid4 0.61 0.19 1.00 make-color constant purple1 0.57 0.17 0.93 make-color constant purple2 0.49 0.15 0.80 make-color constant purple3 0.33 0.10 0.54 make-color constant purple4 0.67 0.51 1.00 make-color constant mediumpurple1 0.62 0.47 0.93 make-color constant mediumpurple2 0.54 0.41 0.80 make-color constant mediumpurple3 0.36 0.28 0.54 make-color constant mediumpurple4 1.00 0.88 1.00 make-color constant thistle1 0.93 0.82 0.93 make-color constant thistle2 0.80 0.71 0.80 make-color constant thistle3 0.54 0.48 0.54 make-color constant thistle4 0.00 0.00 0.00 make-color constant gray0 0.00 0.00 0.00 make-color constant grey0 0.01 0.01 0.01 make-color constant gray1 0.01 0.01 0.01 make-color constant grey1 0.02 0.02 0.02 make-color constant gray2 0.02 0.02 0.02 make-color constant grey2 0.03 0.03 0.03 make-color constant gray3 0.03 0.03 0.03 make-color constant grey3 0.04 0.04 0.04 make-color constant gray4 0.04 0.04 0.04 make-color constant grey4 0.05 0.05 0.05 make-color constant gray5 0.05 0.05 0.05 make-color constant grey5 0.06 0.06 0.06 make-color constant gray6 0.06 0.06 0.06 make-color constant grey6 0.07 0.07 0.07 make-color constant gray7 0.07 0.07 0.07 make-color constant grey7 0.08 0.08 0.08 make-color constant gray8 0.08 0.08 0.08 make-color constant grey8 0.09 0.09 0.09 make-color constant gray9 0.09 0.09 0.09 make-color constant grey9 0.10 0.10 0.10 make-color constant gray10 0.10 0.10 0.10 make-color constant grey10 0.11 0.11 0.11 make-color constant gray11 0.11 0.11 0.11 make-color constant grey11 0.12 0.12 0.12 make-color constant gray12 0.12 0.12 0.12 make-color constant grey12 0.13 0.13 0.13 make-color constant gray13 0.13 0.13 0.13 make-color constant grey13 0.14 0.14 0.14 make-color constant gray14 0.14 0.14 0.14 make-color constant grey14 0.15 0.15 0.15 make-color constant gray15 0.15 0.15 0.15 make-color constant grey15 0.16 0.16 0.16 make-color constant gray16 0.16 0.16 0.16 make-color constant grey16 0.17 0.17 0.17 make-color constant gray17 0.17 0.17 0.17 make-color constant grey17 0.18 0.18 0.18 make-color constant gray18 0.18 0.18 0.18 make-color constant grey18 0.19 0.19 0.19 make-color constant gray19 0.19 0.19 0.19 make-color constant grey19 0.20 0.20 0.20 make-color constant gray20 0.20 0.20 0.20 make-color constant grey20 0.21 0.21 0.21 make-color constant gray21 0.21 0.21 0.21 make-color constant grey21 0.22 0.22 0.22 make-color constant gray22 0.22 0.22 0.22 make-color constant grey22 0.23 0.23 0.23 make-color constant gray23 0.23 0.23 0.23 make-color constant grey23 0.24 0.24 0.24 make-color constant gray24 0.24 0.24 0.24 make-color constant grey24 0.25 0.25 0.25 make-color constant gray25 0.25 0.25 0.25 make-color constant grey25 0.26 0.26 0.26 make-color constant gray26 0.26 0.26 0.26 make-color constant grey26 0.27 0.27 0.27 make-color constant gray27 0.27 0.27 0.27 make-color constant grey27 0.28 0.28 0.28 make-color constant gray28 0.28 0.28 0.28 make-color constant grey28 0.29 0.29 0.29 make-color constant gray29 0.29 0.29 0.29 make-color constant grey29 0.30 0.30 0.30 make-color constant gray30 0.30 0.30 0.30 make-color constant grey30 0.31 0.31 0.31 make-color constant gray31 0.31 0.31 0.31 make-color constant grey31 0.32 0.32 0.32 make-color constant gray32 0.32 0.32 0.32 make-color constant grey32 0.33 0.33 0.33 make-color constant gray33 0.33 0.33 0.33 make-color constant grey33 0.34 0.34 0.34 make-color constant gray34 0.34 0.34 0.34 make-color constant grey34 0.35 0.35 0.35 make-color constant gray35 0.35 0.35 0.35 make-color constant grey35 0.36 0.36 0.36 make-color constant gray36 0.36 0.36 0.36 make-color constant grey36 0.37 0.37 0.37 make-color constant gray37 0.37 0.37 0.37 make-color constant grey37 0.38 0.38 0.38 make-color constant gray38 0.38 0.38 0.38 make-color constant grey38 0.39 0.39 0.39 make-color constant gray39 0.39 0.39 0.39 make-color constant grey39 0.40 0.40 0.40 make-color constant gray40 0.40 0.40 0.40 make-color constant grey40 0.41 0.41 0.41 make-color constant gray41 0.41 0.41 0.41 make-color constant grey41 0.42 0.42 0.42 make-color constant gray42 0.42 0.42 0.42 make-color constant grey42 0.43 0.43 0.43 make-color constant gray43 0.43 0.43 0.43 make-color constant grey43 0.44 0.44 0.44 make-color constant gray44 0.44 0.44 0.44 make-color constant grey44 0.45 0.45 0.45 make-color constant gray45 0.45 0.45 0.45 make-color constant grey45 0.46 0.46 0.46 make-color constant gray46 0.46 0.46 0.46 make-color constant grey46 0.47 0.47 0.47 make-color constant gray47 0.47 0.47 0.47 make-color constant grey47 0.48 0.48 0.48 make-color constant gray48 0.48 0.48 0.48 make-color constant grey48 0.49 0.49 0.49 make-color constant gray49 0.49 0.49 0.49 make-color constant grey49 0.50 0.50 0.50 make-color constant gray50 0.50 0.50 0.50 make-color constant grey50 0.51 0.51 0.51 make-color constant gray51 0.51 0.51 0.51 make-color constant grey51 0.52 0.52 0.52 make-color constant gray52 0.52 0.52 0.52 make-color constant grey52 0.53 0.53 0.53 make-color constant gray53 0.53 0.53 0.53 make-color constant grey53 0.54 0.54 0.54 make-color constant gray54 0.54 0.54 0.54 make-color constant grey54 0.55 0.55 0.55 make-color constant gray55 0.55 0.55 0.55 make-color constant grey55 0.56 0.56 0.56 make-color constant gray56 0.56 0.56 0.56 make-color constant grey56 0.57 0.57 0.57 make-color constant gray57 0.57 0.57 0.57 make-color constant grey57 0.58 0.58 0.58 make-color constant gray58 0.58 0.58 0.58 make-color constant grey58 0.59 0.59 0.59 make-color constant gray59 0.59 0.59 0.59 make-color constant grey59 0.60 0.60 0.60 make-color constant gray60 0.60 0.60 0.60 make-color constant grey60 0.61 0.61 0.61 make-color constant gray61 0.61 0.61 0.61 make-color constant grey61 0.62 0.62 0.62 make-color constant gray62 0.62 0.62 0.62 make-color constant grey62 0.63 0.63 0.63 make-color constant gray63 0.63 0.63 0.63 make-color constant grey63 0.64 0.64 0.64 make-color constant gray64 0.64 0.64 0.64 make-color constant grey64 0.65 0.65 0.65 make-color constant gray65 0.65 0.65 0.65 make-color constant grey65 0.66 0.66 0.66 make-color constant gray66 0.66 0.66 0.66 make-color constant grey66 0.67 0.67 0.67 make-color constant gray67 0.67 0.67 0.67 make-color constant grey67 0.68 0.68 0.68 make-color constant gray68 0.68 0.68 0.68 make-color constant grey68 0.69 0.69 0.69 make-color constant gray69 0.69 0.69 0.69 make-color constant grey69 0.70 0.70 0.70 make-color constant gray70 0.70 0.70 0.70 make-color constant grey70 0.71 0.71 0.71 make-color constant gray71 0.71 0.71 0.71 make-color constant grey71 0.72 0.72 0.72 make-color constant gray72 0.72 0.72 0.72 make-color constant grey72 0.73 0.73 0.73 make-color constant gray73 0.73 0.73 0.73 make-color constant grey73 0.74 0.74 0.74 make-color constant gray74 0.74 0.74 0.74 make-color constant grey74 0.75 0.75 0.75 make-color constant gray75 0.75 0.75 0.75 make-color constant grey75 0.76 0.76 0.76 make-color constant gray76 0.76 0.76 0.76 make-color constant grey76 0.77 0.77 0.77 make-color constant gray77 0.77 0.77 0.77 make-color constant grey77 0.78 0.78 0.78 make-color constant gray78 0.78 0.78 0.78 make-color constant grey78 0.79 0.79 0.79 make-color constant gray79 0.79 0.79 0.79 make-color constant grey79 0.80 0.80 0.80 make-color constant gray80 0.80 0.80 0.80 make-color constant grey80 0.81 0.81 0.81 make-color constant gray81 0.81 0.81 0.81 make-color constant grey81 0.82 0.82 0.82 make-color constant gray82 0.82 0.82 0.82 make-color constant grey82 0.83 0.83 0.83 make-color constant gray83 0.83 0.83 0.83 make-color constant grey83 0.84 0.84 0.84 make-color constant gray84 0.84 0.84 0.84 make-color constant grey84 0.85 0.85 0.85 make-color constant gray85 0.85 0.85 0.85 make-color constant grey85 0.86 0.86 0.86 make-color constant gray86 0.86 0.86 0.86 make-color constant grey86 0.87 0.87 0.87 make-color constant gray87 0.87 0.87 0.87 make-color constant grey87 0.87 0.87 0.87 make-color constant gray88 0.87 0.87 0.87 make-color constant grey88 0.89 0.89 0.89 make-color constant gray89 0.89 0.89 0.89 make-color constant grey89 0.89 0.89 0.89 make-color constant gray90 0.89 0.89 0.89 make-color constant grey90 0.91 0.91 0.91 make-color constant gray91 0.91 0.91 0.91 make-color constant grey91 0.92 0.92 0.92 make-color constant gray92 0.92 0.92 0.92 make-color constant grey92 0.93 0.93 0.93 make-color constant gray93 0.93 0.93 0.93 make-color constant grey93 0.94 0.94 0.94 make-color constant gray94 0.94 0.94 0.94 make-color constant grey94 0.95 0.95 0.95 make-color constant gray95 0.95 0.95 0.95 make-color constant grey95 0.96 0.96 0.96 make-color constant gray96 0.96 0.96 0.96 make-color constant grey96 0.96 0.96 0.96 make-color constant gray97 0.96 0.96 0.96 make-color constant grey97 0.98 0.98 0.98 make-color constant gray98 0.98 0.98 0.98 make-color constant grey98 0.98 0.98 0.98 make-color constant gray99 0.98 0.98 0.98 make-color constant grey99 1.00 1.00 1.00 make-color constant gray100 1.00 1.00 1.00 make-color constant grey100 0.66 0.66 0.66 make-color constant dark-grey 0.66 0.66 0.66 make-color constant dark-gray 0.00 0.00 0.54 make-color constant dark-blue 0.00 0.54 0.54 make-color constant dark-cyan 0.54 0.00 0.54 make-color constant dark-magenta 0.54 0.00 0.00 make-color constant dark-red 0.56 0.93 0.56 make-color constant light-green \ rgb.fs ends here snd-16.1/snd-g0.h0000644000076400007640000005320512513027722011602 0ustar bilbil#ifndef SND_G0_H #define SND_G0_H #include #if GTK_CHECK_VERSION(3, 0, 0) #include #else #include #endif #if HAVE_GL #if GTK_CHECK_VERSION(3, 16, 0) #include #else #undef HAVE_GL #define HAVE_GL 0 #endif #endif #include "glistener.h" #define HAVE_GTK_ADJUSTMENT_GET_UPPER GTK_CHECK_VERSION(2, 14, 0) #define HAVE_GTK_WIDGET_GET_VISIBLE GTK_CHECK_VERSION(2, 18, 0) #define HAVE_GTK_WIDGET_GET_MAPPED GTK_CHECK_VERSION(2, 19, 0) #define HAVE_GTK_GRID_NEW GTK_CHECK_VERSION(3, 0, 0) #define HAVE_GTK_HEADER_BAR_NEW GTK_CHECK_VERSION(3, 8, 0) #include #define LOTSA_PIXELS 10000 #define BACKGROUND_QUIT false #define BACKGROUND_CONTINUE true #define BACKGROUND_REMOVE(func) g_source_remove(func) #define BACKGROUND_ADD(func, data) add_work_proc(func, (gpointer)data) #define TIMEOUT_ARGS gpointer context #define TIMEOUT_TYPE gint #define TIMEOUT_RESULT return(0); #define CALL_TIMEOUT(Func, Wait, Data) g_timeout_add_full(0, Wait, Func, (gpointer)Data, NULL) #define timeout_result_t guint #define TIMEOUT_REMOVE(Id) g_source_remove(Id) typedef enum {WITH_DEFAULT_BACKGROUND, WITH_WHITE_BACKGROUND} snd_entry_bg_t; #define widget_t GtkWidget* #if (!HAVE_GTK_WIDGET_GET_VISIBLE) /* 2.17 -- actually 2.14 also complains but it doesn't provide gtk_widget_get_visible! */ #define widget_is_active(Wid) GTK_WIDGET_VISIBLE(Wid) #else #define widget_is_active(Wid) gtk_widget_get_visible(Wid) #endif #define activate_widget(Wid) gtk_widget_show(Wid) #define deactivate_widget(Wid) gtk_widget_hide(Wid) /* no accessors: */ #define EVENT_WINDOW(Ev) (Ev)->window #define EVENT_BUTTON(Ev) (Ev)->button /* #define EVENT_TYPE(Ev) (Ev)->type */ #define EVENT_KEYVAL(Ev) (Ev)->keyval #define EVENT_IS_HINT(Ev) (Ev)->is_hint #if (!GTK_CHECK_VERSION(3, 0, 0)) #define EVENT_AREA_WIDTH(Ev) (Ev)->area.width #define EVENT_AREA_HEIGHT(Ev) (Ev)->area.height #define widget_set_margin_left(W, M) #define widget_set_margin_right(W, M) #else #if (GTK_CHECK_VERSION(3, 12, 0)) #define widget_set_margin_left(W, M) #define widget_set_margin_right(W, M) #else #define widget_set_margin_left(W, M) gtk_widget_set_margin_left(W, M) #define widget_set_margin_right(W, M) gtk_widget_set_margin_right(W, M) #endif #endif #if (GTK_CHECK_VERSION(3, 0, 0)) && defined(__GNUC__) && (!(defined(__cplusplus))) #define EVENT_STATE(Ev) ({ GdkModifierType Type; gdk_event_get_state((GdkEvent *)Ev, &Type); Type; }) #define EVENT_TIME(Ev) gdk_event_get_time((GdkEvent *)Ev) #define EVENT_X(Ev) ({ gdouble x, y; gdk_event_get_coords((GdkEvent *)Ev, &x, &y); x; }) #define EVENT_Y(Ev) ({ gdouble x, y; gdk_event_get_coords((GdkEvent *)Ev, &x, &y); y; }) /* there's also gtk_get_event_widget */ #else #define EVENT_STATE(Ev) (Ev)->state #define EVENT_TIME(Ev) (Ev)->time #define EVENT_X(Ev) (Ev)->x #define EVENT_Y(Ev) (Ev)->y #endif /* gtk 3.n changes -- nearly every widget used in Snd has been deprecated... */ #ifdef GTK_IS_FONT_CHOOSER_WIDGET /* can't use GTK_IS_VBOX here because it is now always defined, and blathers constantly during compilation */ #undef GTK_IS_VBOX #define GTK_IS_VBOX(Obj) GTK_IS_BOX(Obj) #undef GTK_IS_HBOX #define GTK_IS_HBOX(Obj) GTK_IS_BOX(Obj) #undef GTK_IS_VPANED #define GTK_IS_VPANED(Obj) GTK_IS_PANED(Obj) #undef GTK_IS_HPANED #define GTK_IS_HPANED(Obj) GTK_IS_PANED(Obj) #define gtk_vbox_new(H, S) gtk_box_new(GTK_ORIENTATION_VERTICAL, S) #define gtk_hbox_new(H, S) gtk_box_new(GTK_ORIENTATION_HORIZONTAL, S) #define gtk_vscrollbar_new(S) gtk_scrollbar_new(GTK_ORIENTATION_VERTICAL, S) #define gtk_hscrollbar_new(S) gtk_scrollbar_new(GTK_ORIENTATION_HORIZONTAL, S) /* #define gtk_vscale_new(S) gtk_scale_new(GTK_ORIENTATION_VERTICAL, S) */ #define gtk_hscale_new(S) gtk_scale_new(GTK_ORIENTATION_HORIZONTAL, S) #define gtk_vpaned_new() gtk_paned_new(GTK_ORIENTATION_VERTICAL) #define gtk_hpaned_new() gtk_paned_new(GTK_ORIENTATION_HORIZONTAL) #define gtk_vseparator_new() gtk_separator_new(GTK_ORIENTATION_VERTICAL) #define gtk_hseparator_new() gtk_separator_new(GTK_ORIENTATION_HORIZONTAL) /* 3.4: table widget replaced by grid (also box eventually, I think) */ #undef GTK_TABLE #define GTK_TABLE(Obj) GTK_GRID(Obj) #define gtk_table_new(Rows, Cols, Homogeneous) gtk_grid_new() #define gtk_table_set_homogeneous(Obj, Val) do {gtk_grid_set_row_homogeneous(Obj, Val); gtk_grid_set_column_homogeneous(Obj, Val);} while (0) #define gtk_table_set_row_spacings(Obj, Val) gtk_grid_set_row_spacing(Obj, Val) #define gtk_table_set_col_spacings(Obj, Val) gtk_grid_set_column_spacing(Obj, Val) #define gtk_table_attach_defaults(Obj, Wid, Left, Right, Top, Bottom) gtk_grid_attach(Obj, Wid, Left, Top, Right - Left, Bottom - Top) #define gtk_table_attach(Obj, Wid, Left, Right, Top, Bottom, XOptions, YOptions, Xpad, YPad) gtk_grid_attach(Obj, Wid, Left, Top, Right - Left, Bottom - Top) #define window_get_pointer(Event, X, Y, Mask) gdk_window_get_device_position(EVENT_WINDOW(Event), gdk_event_get_device((GdkEvent *)Event), X, Y, Mask) #define widget_set_hexpand(Wid, Val) gtk_widget_set_hexpand(Wid, Val) #define widget_set_vexpand(Wid, Val) gtk_widget_set_vexpand(Wid, Val) #else #define window_get_pointer(Event, X, Y, Mask) gdk_window_get_pointer(EVENT_WINDOW(Event), X, Y, Mask) #define widget_set_hexpand(Wid, Val) #define widget_set_vexpand(Wid, Val) #endif /* 3.16: gdk_cursor_new removed */ #if GTK_CHECK_VERSION(3, 16, 0) #define GDK_CURSOR_NEW(Type) gdk_cursor_new_for_display(gdk_display_get_default(), Type) #else #define GDK_CURSOR_NEW(Type) gdk_cursor_new(Type) #endif #define Xen_wrap_widget(Value) ((Value) ? Xen_list_2(C_string_to_Xen_symbol("GtkWidget_"), Xen_wrap_C_pointer(Value)) : Xen_false) #define Xen_wrap_window(Value) ((Value) ? Xen_list_2(C_string_to_Xen_symbol("GdkWindow_"), Xen_wrap_C_pointer(Value)) : Xen_false) #define Xen_unwrap_widget(Value) (Xen_is_pair(Value) ? (GtkWidget *)(Xen_unwrap_C_pointer(Xen_cadr(Value))) : NULL) #define Xen_is_widget(Value) (Xen_is_pair(Value) && (Xen_car(Value) == C_string_to_Xen_symbol("GtkWidget_"))) #define Xen_wrap_pixel(Value) Xen_list_2(C_string_to_Xen_symbol("color_t"), Xen_wrap_C_pointer((unsigned long)Value)) #define Xen_unwrap_pixel(Value) (color_t)(Xen_unwrap_C_pointer(Xen_cadr(Value))) #define Xen_is_pixel(Value) (Xen_is_list(Value) && (Xen_list_length(Value) >= 2) && (Xen_is_symbol(Xen_car(Value))) && \ (strcmp("color_t", Xen_symbol_to_C_string(Xen_car(Value))) == 0)) /* unfortunately, we can't just make PIXEL into a C type here -- it is called * XM_PIXEL in xm.c and in that context, it assumes the layout given above. */ #define NULL_WIDGET NULL #define SG_SIGNAL_CONNECT(Widget, Signal, Function, Data) g_signal_connect(G_OBJECT(Widget), Signal, G_CALLBACK(Function), (gpointer)Data) /* GtkType -> GType, GtkSignalFunc -> GCallback version 2.13.4 7-Jul-08 */ #if HAVE_GTK_ADJUSTMENT_GET_UPPER /* 2.13.6 */ #define WIDGET_TO_WINDOW(Widget) gtk_widget_get_window(Widget) #define DIALOG_CONTENT_AREA(Dialog) gtk_dialog_get_content_area(GTK_DIALOG(Dialog)) #define ADJUSTMENT_VALUE(Adjust) gtk_adjustment_get_value(GTK_ADJUSTMENT(Adjust)) #define ADJUSTMENT_PAGE_SIZE(Adjust) gtk_adjustment_get_page_size(GTK_ADJUSTMENT(Adjust)) #define ADJUSTMENT_SET_PAGE_SIZE(Adjust, Value) gtk_adjustment_set_page_size(GTK_ADJUSTMENT(Adjust), Value) #else #define WIDGET_TO_WINDOW(Widget) ((Widget)->window) #define DIALOG_CONTENT_AREA(Dialog) ((GTK_DIALOG(Dialog))->vbox) #define ADJUSTMENT_VALUE(Adjust) ((GTK_ADJUSTMENT(Adjust))->value) #define ADJUSTMENT_PAGE_SIZE(Adjust) ((GTK_ADJUSTMENT(Adjust))->page_size) #define ADJUSTMENT_SET_PAGE_SIZE(Adjust, Value) (GTK_ADJUSTMENT(Adjust))->page_size = Value #endif #define ADJUSTMENT_SET_VALUE(Adjust, Value) gtk_adjustment_set_value(GTK_ADJUSTMENT(Adjust), (gdouble)(Value)) /* this is different from setting the value field directly because it calls gtk_adjustment_value_changed * which itself is different (generates a different signal) from gtk_adjustment_changed. */ #define TOGGLE_BUTTON_ACTIVE(Button) gtk_toggle_button_get_active((GTK_TOGGLE_BUTTON(Button))) #define BIN_CHILD(Bin) gtk_bin_get_child(GTK_BIN(Bin)) #if GTK_CHECK_VERSION(3, 0, 0) #define DRAW_SIGNAL "draw" #else #define DRAW_SIGNAL "expose_event" #endif #if GTK_CHECK_VERSION(2, 18, 0) #define SET_CAN_FOCUS(Wid) gtk_widget_set_can_focus(Wid, true) #define UNSET_CAN_FOCUS(Wid) gtk_widget_set_can_focus(Wid, false) #else #define SET_CAN_FOCUS(Wid) GTK_WIDGET_SET_FLAGS(Wid, GTK_CAN_FOCUS) #define UNSET_CAN_FOCUS(Wid) GTK_WIDGET_UNSET_FLAGS(Wid, GTK_CAN_FOCUS) #endif #define idle_t guint #define idle_func_t gboolean #define any_pointer_t gpointer #define oclock_t guint32 typedef struct { int x, y; } point_t; #define rgb_t gdouble #define RGB_MAX 1.0 #define float_to_rgb(Val) (rgb_t)(Val) #define rgb_to_float(Val) Val typedef struct { rgb_t red, green, blue, alpha; } color_info; typedef color_info* color_t; typedef struct { color_t fg_color, bg_color; } gc_t; #define picture_t cairo_surface_t #if GTK_CHECK_VERSION(3, 0, 0) typedef GdkWindow Drawable; #define DRAWABLE(Widget) GDK_WINDOW(Widget) /* as far as I can see, UPDATE_CONTINUOUS is now built-in */ #define gtk_range_get_update_policy(W) 0 #define gtk_range_set_update_policy(W, V) #define GTK_UPDATE_CONTINUOUS 0 #else typedef GdkDrawable Drawable; #define DRAWABLE(Widget) GDK_DRAWABLE(Widget) #endif typedef struct { gc_t *gc; Drawable *wn; PangoFontDescription *current_font; GtkWidget *w; } graphics_context; typedef struct slist { GtkWidget *scroller, *topics, *label, *box; GtkWidget **items; int num_items, items_size, selected_item; void (*select_callback)(const char *name, int row, void *data); void *select_callback_data; bool (*button_press_callback)(GdkEventButton *event, void *data); void *button_press_callback_data; } slist; #define SLIST_NO_ITEM_SELECTED -1 typedef enum {NOT_A_SCANF_WIDGET, SRATE_WIDGET, CHANS_WIDGET, DATA_LOCATION_WIDGET, SAMPLES_WIDGET} scanf_widget_t; typedef struct { GtkWidget *srate_text, *chans_text, *comment_text, *location_text, *samples_text, *error_text; GtkWidget *dialog, *src_button, *auto_comment_button; mus_header_t current_header_type; mus_sample_t current_sample_type; int sample_types, header_type_pos, sample_type_pos; scanf_widget_t scanf_widget, error_widget; bool src, auto_comment; gulong *reflection_ids; slist *header_type_list, *sample_type_list; char *saved_comment; } file_data; #define DEFAULT_TINY_FONT "Sans 8" #define DEFAULT_PEAKS_FONT "Times Medium 10" #define DEFAULT_BOLD_PEAKS_FONT "Times Bold 10" #define DEFAULT_AXIS_NUMBERS_FONT "Sans 10" #define DEFAULT_AXIS_LABEL_FONT "Times Medium 14" #define DEFAULT_LISTENER_FONT "Monospace 11" typedef enum {CONTAINER_ADD, PANED_ADD1, BOX_PACK, TABLE_ATTACH} widget_add_t; typedef enum {WITHOUT_CHANNELS_FIELD, WITH_CHANNELS_FIELD, WITH_EXTRACT_CHANNELS_FIELD} dialog_channels_t; typedef enum {WITHOUT_SAMPLES_FIELD, WITH_SAMPLES_FIELD} dialog_samples_t; typedef enum {WITHOUT_DATA_LOCATION_FIELD, WITH_DATA_LOCATION_FIELD} dialog_data_location_t; typedef enum {WITHOUT_HEADER_TYPE_FIELD, WITH_HEADER_TYPE_FIELD} dialog_header_type_t; typedef enum {WITHOUT_COMMENT_FIELD, WITH_COMMENT_FIELD} dialog_comment_t; #define MAIN_SHELL(a) (a)->mainshell #define MAIN_WINDOW(a) (a)->mainwindow #define MAIN_PANE(a) (a)->mainpane #define SOUND_PANE(a) (a)->soundpane #define SOUND_PANE_BOX(a) (a)->soundpanebox #define AXIS_NUMBERS_FONT(a) (a)->axis_numbers_fnt #define AXIS_LABEL_FONT(a) (a)->axis_label_fnt #define LISTENER_FONT(a) (a)->listener_fnt #define TINY_FONT(a) (a)->tiny_fnt #define PEAKS_FONT(a) (a)->peaks_fnt #define BOLD_PEAKS_FONT(a) (a)->bold_peaks_fnt #define KEY_TO_NAME(key) gdk_keyval_name(key) #define DEFAULT_GRAPH_CURSOR GDK_CROSSHAIR #define snd_ShiftMask GDK_SHIFT_MASK #define snd_ControlMask GDK_CONTROL_MASK #if (!HAVE_SUN) #define snd_MetaMask GDK_MOD1_MASK #else #define snd_MetaMask (GDK_MOD1_MASK | GDK_MOD4_MASK) #endif #define BUTTON1_PRESSED(State) ((State) & GDK_BUTTON1_MASK) /* now pull in the key names (gdk/gdkkeysyms.h) * KEY_ added to all these names in gtk 2.90.7 */ #if defined(GDK_KEY_Shift_L) #define snd_K_Shift_L GDK_KEY_Shift_L #define snd_K_space GDK_KEY_space #define snd_K_openparen GDK_KEY_parenleft #define snd_K_closeparen GDK_KEY_parenright #define snd_K_plus GDK_KEY_plus #define snd_K_minus GDK_KEY_minus #define snd_K_period GDK_KEY_period #define snd_K_slash GDK_KEY_slash #define snd_K_0 GDK_KEY_0 #define snd_K_1 GDK_KEY_1 #define snd_K_2 GDK_KEY_2 #define snd_K_3 GDK_KEY_3 #define snd_K_4 GDK_KEY_4 #define snd_K_5 GDK_KEY_5 #define snd_K_6 GDK_KEY_6 #define snd_K_7 GDK_KEY_7 #define snd_K_8 GDK_KEY_8 #define snd_K_9 GDK_KEY_9 #define snd_K_less GDK_KEY_less #define snd_K_greater GDK_KEY_greater #define snd_K_A GDK_KEY_A #define snd_K_B GDK_KEY_B #define snd_K_C GDK_KEY_C #define snd_K_D GDK_KEY_D #define snd_K_E GDK_KEY_E #define snd_K_F GDK_KEY_F #define snd_K_G GDK_KEY_G #define snd_K_H GDK_KEY_H #define snd_K_I GDK_KEY_I #define snd_K_J GDK_KEY_J #define snd_K_K GDK_KEY_K #define snd_K_L GDK_KEY_L #define snd_K_M GDK_KEY_M #define snd_K_N GDK_KEY_N #define snd_K_O GDK_KEY_O #define snd_K_P GDK_KEY_P #define snd_K_Q GDK_KEY_Q #define snd_K_R GDK_KEY_R #define snd_K_S GDK_KEY_S #define snd_K_T GDK_KEY_T #define snd_K_U GDK_KEY_U #define snd_K_V GDK_KEY_V #define snd_K_W GDK_KEY_W #define snd_K_X GDK_KEY_X #define snd_K_Y GDK_KEY_Y #define snd_K_Z GDK_KEY_Z #define snd_K_underscore GDK_KEY_underscore #define snd_K_a GDK_KEY_a #define snd_K_b GDK_KEY_b #define snd_K_c GDK_KEY_c #define snd_K_d GDK_KEY_d #define snd_K_e GDK_KEY_e #define snd_K_f GDK_KEY_f #define snd_K_g GDK_KEY_g #define snd_K_h GDK_KEY_h #define snd_K_i GDK_KEY_i #define snd_K_j GDK_KEY_j #define snd_K_k GDK_KEY_k #define snd_K_l GDK_KEY_l #define snd_K_m GDK_KEY_m #define snd_K_n GDK_KEY_n #define snd_K_o GDK_KEY_o #define snd_K_p GDK_KEY_p #define snd_K_q GDK_KEY_q #define snd_K_r GDK_KEY_r #define snd_K_s GDK_KEY_s #define snd_K_t GDK_KEY_t #define snd_K_u GDK_KEY_u #define snd_K_v GDK_KEY_v #define snd_K_w GDK_KEY_w #define snd_K_x GDK_KEY_x #define snd_K_y GDK_KEY_y #define snd_K_z GDK_KEY_z #define snd_K_Home GDK_KEY_Home #define snd_K_Left GDK_KEY_Left #define snd_K_Up GDK_KEY_Up #define snd_K_Right GDK_KEY_Right #define snd_K_Down GDK_KEY_Down #define snd_keypad_Insert GDK_KEY_KP_Insert #define snd_keypad_Delete GDK_KEY_KP_Delete #define snd_keypad_Multiply GDK_KEY_KP_Multiply #define snd_keypad_Add GDK_KEY_KP_Add #define snd_keypad_Subtract GDK_KEY_KP_Subtract #define snd_keypad_Divide GDK_KEY_KP_Divide #define snd_keypad_Decimal GDK_KEY_KP_Decimal #define snd_keypad_Enter GDK_KEY_KP_Enter #define snd_keypad_Up GDK_KEY_KP_Up #define snd_keypad_Down GDK_KEY_KP_Down #define snd_keypad_Left GDK_KEY_KP_Left #define snd_keypad_Right GDK_KEY_KP_Right #define snd_keypad_0 GDK_KEY_KP_0 #define snd_keypad_1 GDK_KEY_KP_1 #define snd_keypad_2 GDK_KEY_KP_2 #define snd_keypad_3 GDK_KEY_KP_3 #define snd_keypad_4 GDK_KEY_KP_4 #define snd_keypad_5 GDK_KEY_KP_5 #define snd_keypad_6 GDK_KEY_KP_6 #define snd_keypad_7 GDK_KEY_KP_7 #define snd_keypad_8 GDK_KEY_KP_8 #define snd_keypad_9 GDK_KEY_KP_9 #define snd_K_Tab GDK_KEY_Tab #else /* ---------------- old version ---------------- */ #define snd_K_Shift_L GDK_Shift_L #define snd_K_space GDK_space #define snd_K_openparen GDK_parenleft #define snd_K_closeparen GDK_parenright #define snd_K_plus GDK_plus #define snd_K_minus GDK_minus #define snd_K_period GDK_period #define snd_K_slash GDK_slash #define snd_K_0 GDK_0 #define snd_K_1 GDK_1 #define snd_K_2 GDK_2 #define snd_K_3 GDK_3 #define snd_K_4 GDK_4 #define snd_K_5 GDK_5 #define snd_K_6 GDK_6 #define snd_K_7 GDK_7 #define snd_K_8 GDK_8 #define snd_K_9 GDK_9 #define snd_K_less GDK_less #define snd_K_greater GDK_greater #define snd_K_A GDK_A #define snd_K_B GDK_B #define snd_K_C GDK_C #define snd_K_D GDK_D #define snd_K_E GDK_E #define snd_K_F GDK_F #define snd_K_G GDK_G #define snd_K_H GDK_H #define snd_K_I GDK_I #define snd_K_J GDK_J #define snd_K_K GDK_K #define snd_K_L GDK_L #define snd_K_M GDK_M #define snd_K_N GDK_N #define snd_K_O GDK_O #define snd_K_P GDK_P #define snd_K_Q GDK_Q #define snd_K_R GDK_R #define snd_K_S GDK_S #define snd_K_T GDK_T #define snd_K_U GDK_U #define snd_K_V GDK_V #define snd_K_W GDK_W #define snd_K_X GDK_X #define snd_K_Y GDK_Y #define snd_K_Z GDK_Z #define snd_K_underscore GDK_underscore #define snd_K_a GDK_a #define snd_K_b GDK_b #define snd_K_c GDK_c #define snd_K_d GDK_d #define snd_K_e GDK_e #define snd_K_f GDK_f #define snd_K_g GDK_g #define snd_K_h GDK_h #define snd_K_i GDK_i #define snd_K_j GDK_j #define snd_K_k GDK_k #define snd_K_l GDK_l #define snd_K_m GDK_m #define snd_K_n GDK_n #define snd_K_o GDK_o #define snd_K_p GDK_p #define snd_K_q GDK_q #define snd_K_r GDK_r #define snd_K_s GDK_s #define snd_K_t GDK_t #define snd_K_u GDK_u #define snd_K_v GDK_v #define snd_K_w GDK_w #define snd_K_x GDK_x #define snd_K_y GDK_y #define snd_K_z GDK_z #define snd_K_Home GDK_Home #define snd_K_Left GDK_Left #define snd_K_Up GDK_Up #define snd_K_Right GDK_Right #define snd_K_Down GDK_Down #define snd_keypad_Insert GDK_KP_Insert #define snd_keypad_Delete GDK_KP_Delete #define snd_keypad_Multiply GDK_KP_Multiply #define snd_keypad_Add GDK_KP_Add #define snd_keypad_Subtract GDK_KP_Subtract #define snd_keypad_Divide GDK_KP_Divide #define snd_keypad_Decimal GDK_KP_Decimal #define snd_keypad_Enter GDK_KP_Enter #define snd_keypad_Up GDK_KP_Up #define snd_keypad_Down GDK_KP_Down #define snd_keypad_Left GDK_KP_Left #define snd_keypad_Right GDK_KP_Right #define snd_keypad_0 GDK_KP_0 #define snd_keypad_1 GDK_KP_1 #define snd_keypad_2 GDK_KP_2 #define snd_keypad_3 GDK_KP_3 #define snd_keypad_4 GDK_KP_4 #define snd_keypad_5 GDK_KP_5 #define snd_keypad_6 GDK_KP_6 #define snd_keypad_7 GDK_KP_7 #define snd_keypad_8 GDK_KP_8 #define snd_keypad_9 GDK_KP_9 #define snd_K_Tab GDK_Tab #endif #if GTK_CHECK_VERSION(3, 10, 0) /* see the "Icon Naming Specification" */ #define ICON_ADD "Add" #define ICON_APPLY "Apply" #define ICON_CANCEL "process-stop" #define ICON_CLEAR "edit-clear" #define ICON_CLOSE "window-close" #define ICON_COPY "edit-copy" #define ICON_CUT "edit-cut" #define ICON_EDIT "Edit" #define ICON_FIND "edit-find" #define ICON_FULLSCREEN "view-fullscreen" #define ICON_GOTO_FIRST "go-first" #define ICON_GOTO_LAST "go-last" #define ICON_GO_BACK "go-previous" #define ICON_GO_FORWARD "go-next" #define ICON_HELP "help-browser" #define ICON_MEDIA_FORWARD "media-skip-forward" #define ICON_MEDIA_PLAY "media-playback-start" #define ICON_MEDIA_STOP "media-playback-stop" #define ICON_NEW "document-new" #define ICON_OK "Ok" #define ICON_OPEN "document-open" #define ICON_PASTE "edit-paste" #define ICON_PREFERENCES "Preferences" #define ICON_PRINT "document-print" #define ICON_QUIT "application-exit" #define ICON_REDO "edit-redo" #define ICON_REFRESH "view-refresh" #define ICON_REVERT_TO_SAVED "document-revert" #define ICON_SAVE "document-save" #define ICON_SAVE_AS "document-save-as" #define ICON_SELECT_ALL "edit-select-all" #define ICON_SELECT_COLOR "Select color" #define ICON_UNDO "edit-undo" #define ICON_ZOOM_IN "zoom-in" #define ICON_ZOOM_OUT "zoom-out" GtkWidget *button_new_with_icon(const gchar *label); #define image_new_with_icon(Icon, Size) gtk_image_new_from_icon_name(Icon, Size) #else #define ICON_ADD GTK_STOCK_ADD #define ICON_APPLY GTK_STOCK_APPLY #define ICON_CANCEL GTK_STOCK_CANCEL #define ICON_CLEAR GTK_STOCK_CLEAR #define ICON_CLOSE GTK_STOCK_CLOSE #define ICON_COPY GTK_STOCK_COPY #define ICON_CUT GTK_STOCK_CUT #define ICON_EDIT GTK_STOCK_EDIT #define ICON_FIND GTK_STOCK_FIND #define ICON_FULLSCREEN GTK_STOCK_FULLSCREEN #define ICON_GOTO_FIRST GTK_STOCK_GOTO_FIRST #define ICON_GOTO_LAST GTK_STOCK_GOTO_LAST #define ICON_GO_BACK GTK_STOCK_GO_BACK #define ICON_GO_FORWARD GTK_STOCK_GO_FORWARD #define ICON_HELP GTK_STOCK_HELP #define ICON_MEDIA_FORWARD GTK_STOCK_MEDIA_FORWARD #define ICON_MEDIA_PLAY GTK_STOCK_MEDIA_PLAY #define ICON_MEDIA_STOP GTK_STOCK_MEDIA_STOP #define ICON_NEW GTK_STOCK_NEW #define ICON_OK GTK_STOCK_OK #define ICON_OPEN GTK_STOCK_OPEN #define ICON_PASTE GTK_STOCK_PASTE #define ICON_PREFERENCES GTK_STOCK_PREFERENCES #define ICON_PRINT GTK_STOCK_PRINT #define ICON_QUIT GTK_STOCK_QUIT #define ICON_REDO GTK_STOCK_REDO #define ICON_REFRESH GTK_STOCK_REFRESH #define ICON_REVERT_TO_SAVED GTK_STOCK_REVERT_TO_SAVED #define ICON_SAVE GTK_STOCK_SAVE #define ICON_SAVE_AS GTK_STOCK_SAVE_AS #define ICON_SELECT_ALL GTK_STOCK_SELECT_ALL #define ICON_SELECT_COLOR GTK_STOCK_SELECT_COLOR #define ICON_UNDO GTK_STOCK_UNDO #define ICON_ZOOM_IN GTK_STOCK_ZOOM_IN #define ICON_ZOOM_OUT GTK_STOCK_ZOOM_OUT #define button_new_with_icon(Icon) gtk_button_new_from_stock(Icon) #define image_new_with_icon(Icon, Size) gtk_image_new_from_stock(Icon, Size) #endif #endif snd-16.1/pvoc.scm0000644000076400007640000003063712447035374012030 0ustar bilbil;;; versions of the Moore-Klingbeil-Trevisani-Edwards phase-vocoder (provide 'snd-pvoc.scm) (define make-pvocoder (let ((documentation "(make-pvocoder fftsize overlap interp analyze edit synthesize) makes a new (Scheme-based, not CLM) phase-vocoder generator")) (lambda* (fftsize overlap interp analyze edit synthesize) (let* ((N (or fftsize 512)) (N2 (floor (/ N 2))) (hop (or overlap 4)) (D (floor (/ N hop)))) ;; basic: fftsize overlap ;; everything else via closures (interp in particular) ;; pv: counter ("output" here) ;; interp ;; fftsize ("N"), hop ("D") ;; in-counter ("filptr") ;; hamming window scaled ;; slot for in-coming data ("in-data") (created on first call) ;; float-vectors: ampinc amp freqinc phaseinc phase lastphase ;; funcs: analysize, edit, resynthesize (list interp ;output interp ;interp 0 ;filptr N ;N (let ((window (make-fft-window hamming-window fftsize))) (float-vector-scale! window (/ 2.0 (* 0.54 fftsize))) ;den = hamming window integrated window) ; window D ;D #f ;in-data (created in pvocoder gen) (make-float-vector fftsize) ;ampinc (make-float-vector fftsize) ;freqs (make-float-vector N2) ;amps (make-float-vector N2) ;phaseinc (make-float-vector N2) ;phases (make-float-vector N2) ;lastphaseinc analyze edit synthesize))))) ;;; pvocoder generator: ;; input data func ;; analysis func with fallback ;; editing func with fallback ;; resynthesis func with fallback (define* (sine-bank amps phases size) (let ((len (or size (length amps))) (sum 0.0)) (do ((i 0 (+ i 1))) ((= i len)) (set! sum (+ sum (* (amps i) (sin (phases i)))))) sum)) (define pvocoder (let ((documentation "(pvocoder pv input) is the phase-vocoder generator associated with make-pvocoder")) (lambda (pv input) ;; pvocoder list accessors (define (pvoc-output pv) (pv 0)) (define (set-pvoc-output pv val) (set! (pv 0) val)) (define (pvoc-interp pv) (pv 1)) (define (set-pvoc-interp pv val) (set! (pv 1) val)) (define (pvoc-filptr pv) (pv 2)) (define (set-pvoc-filptr pv val) (set! (pv 2) val)) (define (pvoc-N pv) (pv 3)) (define (pvoc-window pv) (pv 4)) (define (pvoc-D pv) (pv 5)) (define (pvoc-in-data pv) (pv 6)) (define (set-pvoc-in-data pv val) (set! (pv 6) val)) (define (pvoc-ampinc pv) (pv 7)) (define (pvoc-freqs pv) (pv 8)) (define (pvoc-amps pv) (pv 9)) (define (pvoc-phaseinc pv) (pv 10)) (define (pvoc-phases pv) (pv 11)) (define (pvoc-lastphase pv) (pv 12)) (define (pvoc-analyze pv) (pv 13)) (define (pvoc-edit pv) (pv 14)) (define (pvoc-synthesize pv) (pv 15)) (let ((pi2 (* 2.0 pi))) (if (>= (pvoc-output pv) (pvoc-interp pv)) ;; get next block of amp/phase info (let ((N (pvoc-N pv)) (D (pvoc-D pv)) (amps (pvoc-ampinc pv)) (freqs (pvoc-freqs pv)) (filptr (pvoc-filptr pv))) (if (pvoc-analyze pv) ((pvoc-analyze pv) pv input) ;; if no analysis func: (begin (fill! freqs 0.0) (set-pvoc-output pv 0) (if (not (pvoc-in-data pv)) (begin (set-pvoc-in-data pv (make-float-vector N)) (do ((i 0 (+ i 1))) ((= i N)) (set! ((pvoc-in-data pv) i) (input)))) (let ((indat (pvoc-in-data pv))) ;; extra loop here since I find the optimized case confusing (we could dispense with the data move) (float-vector-move! indat 0 D) (do ((i (- N D) (+ i 1))) ((= i N)) (set! (indat i) (input))))) (let ((buf (modulo filptr N))) (if (= buf 0) (begin (fill! amps 0.0) (float-vector-add! amps (pvoc-in-data pv)) (float-vector-multiply! amps (pvoc-window pv))) (begin (do ((k 0 (+ k 1))) ((= k N)) (set! (amps buf) (* ((pvoc-window pv) k) ((pvoc-in-data pv) k))) (set! buf (+ 1 buf)) (if (= buf N) (set! buf 0)))))) (set-pvoc-filptr pv (+ filptr D)) (mus-fft amps freqs N 1) (rectangular->polar amps freqs))) (if (pvoc-edit pv) ((pvoc-edit pv) pv) (let ((lp (pvoc-lastphase pv)) (pscl (/ 1.0 D)) (kscl (/ pi2 N)) (lim (floor (/ N 2)))) ;; if no editing func: (do ((k 0 (+ k 1))) ((= k lim)) (let ((phasediff (remainder (- (freqs k) (lp k)) pi2))) (float-vector-set! lp k (freqs k)) (if (> phasediff pi) (set! phasediff (- phasediff pi2)) (if (< phasediff (- pi)) (set! phasediff (+ phasediff pi2)))) (set! (freqs k) (+ (* pscl phasediff) (* k kscl))))))) (let ((scl (/ 1.0 (pvoc-interp pv)))) (float-vector-subtract! amps (pvoc-amps pv)) (float-vector-subtract! freqs (pvoc-phaseinc pv)) (float-vector-scale! amps scl) (float-vector-scale! freqs scl) ))) (set-pvoc-output pv (+ 1 (pvoc-output pv))) (if (pvoc-synthesize pv) ((pvoc-synthesize pv) pv) ;; if no synthesis func: ;; synthesize next sample (begin (float-vector-add! (pvoc-amps pv) (pvoc-ampinc pv)) (float-vector-add! (pvoc-phaseinc pv) (pvoc-freqs pv)) (float-vector-add! (pvoc-phases pv) (pvoc-phaseinc pv)) (sine-bank (pvoc-amps pv) (pvoc-phases pv)))) )))) #| (let* ((ind (open-sound "oboe.snd")) (pv (make-pvocoder 256 4 64)) (rd (make-sampler 0))) (map-channel (lambda (y) (pvocoder pv (lambda () (rd)))))) |# #| ;;; ---------------- same thing using phase-vocoder gen (define test-pv-1 (lambda (freq) (let* ((reader (make-sampler 0)) (pv (make-phase-vocoder (lambda (dir) (next-sample reader)) 512 4 128 1.0 #f ;no change to analysis #f ;no change to edits #f ;no change to synthesis ))) (map-channel (lambda (val) (phase-vocoder pv)))))) (define test-pv-2 (lambda (freq) (let* ((reader (make-sampler 0)) (pv (make-phase-vocoder (lambda (dir) (next-sample reader)) 512 4 128 freq #f ;no change to analysis #f #f ; no change to synthesis ))) (map-channel (lambda (val) (phase-vocoder pv)))))) (define test-pv-3 (lambda (time) (let* ((reader (make-sampler 0)) (pv (make-phase-vocoder (lambda (dir) (next-sample reader)) 512 4 (floor (* 128 time)) 1.0 #f ;no change to analysis #f ;no change to edits #f ;no change to synthesis )) (len (floor (* time (framples)))) (data (make-float-vector len))) (do ((i 0 (+ i 1))) ((= i len)) (set! (data i) (phase-vocoder pv))) (free-sampler reader) (float-vector->channel data 0 len)))) (define test-pv-4 (lambda (gate) (let* ((reader (make-sampler 0)) (pv (make-phase-vocoder (lambda (dir) (next-sample reader)) 512 4 128 1.0 #f ;no change to analysis (lambda (v) (let ((N (mus-length v))) (do ((i 0 (+ i 1))) ((= i N)) (if (< ((phase-vocoder-amp-increments v) i) gate) (float-vector-set! (phase-vocoder-amp-increments v) i 0.0))) #t)) #f ;no change to synthesis ))) (map-channel (lambda (val) (phase-vocoder pv)))))) |# ;;; -------- another version of the phase vocoder -------- (define pvoc (let ((documentation "(pvoc fftsize overlap time pitch gate hoffset snd chn) applies the phase vocoder algorithm to the current sound (i.e. fft analysis, oscil bank resynthesis). 'pitch' specifies the pitch transposition ratio, 'time' - specifies the time dilation ratio, 'gate' specifies a resynthesis gate in dB (partials with amplitudes lower than the gate value will not be synthesized), 'hoffset is a pitch offset in Hz.")) (lambda* ((fftsize 512) (overlap 4) (time 1.0) (pitch 1.0) (gate 0.0) (hoffset 0.0) (snd 0) (chn 0)) (let* ((len (framples)) (filptr 0) ; index into the file (pi2 (* 2 pi)) ; handy constant (sr (srate)) (N fftsize) ; fft size (N2 (floor (/ N 2))) ;; (Nw fftsize) ;; window size -- currently restricted to the fftsize (D (floor (/ fftsize overlap))) ; decimation factor (how often do we take an fft) (interp (* (floor (/ fftsize overlap)) time)) ; interpolation factor how often do we synthesize ;; take a resynthesis gate specificed in dB, convert to linear amplitude (syngate (if (= 0.0 gate) 0.0 (expt 10 (/ (- (abs gate)) 20)))) (poffset (hz->radians hoffset)) (window (make-fft-window hamming-window fftsize)) (fdr (make-float-vector N)) ; buffer for real fft data (fdi (make-float-vector N)) ; buffer for imaginary fft data (lastphase (make-float-vector N2)) ;; last phase change (lastamp (make-float-vector N2)) ;; last sampled amplitude (lastfreq (make-float-vector N2)) ;; last sampled frequency (ampinc (make-float-vector N2)) ;; amplitude interpolation increment (freqinc (make-float-vector N2)) ;; frequency interpolation increments ;; expresses the fundamental in terms of radians per output sample (fundamental (/ pi2 N)) (output interp) ; count of samples that have been output ;; (nextpct 10.0) ; how often to print out the percentage complete message (outlen (floor (* time len))) (out-data (make-float-vector (max len outlen))) (in-data (channel->float-vector 0 (* N 2) snd chn)) (in-data-beg 0) (obank (make-oscil-bank lastfreq (make-float-vector N2 0.0) lastamp))) (set! window (float-vector-scale! window (/ 2.0 (* 0.54 fftsize)))) ;den = hamming window integrated (do ((i 0 (+ i 1))) ((>= i outlen)) (if (>= output interp) ;; if all the samples have been output then do the next frame (let ((buffix (modulo filptr N))) ; buffix is the index into the input buffer ; it wraps around circularly as time increases in the input (set! output 0) ; reset the output sample counter ;; save the old amplitudes and frequencies (fill! lastamp 0.0) (fill! lastfreq 0.0) (float-vector-add! lastamp fdr) (float-vector-add! lastfreq fdi) (do ((k 0 (+ k 1))) ((= k N)) ;; apply the window and then stuff into the input array (set! (fdr buffix) (* (window k) (in-data (- filptr in-data-beg)))) (set! filptr (+ 1 filptr)) ;; increment the buffer index with wrap around (set! buffix (+ 1 buffix)) (if (>= buffix N) (set! buffix 0))) ;; rewind the file for the next hop (set! filptr (- filptr (- N D))) (if (> filptr (+ in-data-beg N)) (begin (set! in-data-beg filptr) (set! in-data (channel->float-vector in-data-beg (* N 2) snd chn)))) ;; no imaginary component input so zero out fdi (fill! fdi 0.0) ;; compute the fft (mus-fft fdr fdi N 1) ;; now convert into magnitude and interpolated frequency (do ((k 0 (+ k 1))) ((= k N2)) (let* ((a (fdr k)) (b (fdi k)) (mag (sqrt (+ (* a a) (* b b)))) (phase 0) (phasediff 0)) (set! (fdr k) mag) ;; current amp stored in fdr ;; mag is always positive ;; if it is zero then the phase difference is zero (if (> mag 0) (begin (set! phase (- (atan b a))) (set! phasediff (- phase (lastphase k))) (set! (lastphase k) phase) ;; frequency wrapping from Moore p. 254 (if (> phasediff pi) (do () ((<= phasediff pi)) (set! phasediff (- phasediff pi2)))) (if (< phasediff (- pi)) (do () ((>= phasediff (- pi))) (set! phasediff (+ phasediff pi2)))))) ;; current frequency stored in fdi ;; scale by the pitch transposition (set! (fdi k) (* pitch (+ (/ (* phasediff sr) (* D sr)) (* k fundamental) poffset))) ;; resynthesis gating (if (< (fdr k) syngate) (set! (fdr k) 0.0)) ;; take (lastamp k) and count up to (fdr k) ;; interpolating by ampinc (set! (ampinc k) (/ (- (fdr k) (lastamp k)) interp)) ;; take (lastfreq k) and count up to (fdi k) ;; interpolating by freqinc (set! (freqinc k) (/ (- (fdi k) (lastfreq k)) interp)))))) ;; loop over the partials interpolate frequency and amplitude (float-vector-add! lastamp ampinc) (float-vector-add! lastfreq freqinc) (float-vector-set! out-data i (oscil-bank obank)) (set! output (+ 1 output))) (float-vector->channel out-data 0 (max len outlen)))))) snd-16.1/index.scm0000644000076400007640000000353712625630553012165 0ustar bilbil;;; Snd documentation index (generated by make-index.scm) (provide 'snd-index.scm) (define html (let ((documentation "(html arg) where arg can be a string, symbol, or procedure looks for a corresponding url and if one is found, and the Snd documentation can be found, calls *html-program* with that url")) (lambda (obj) (let ((goto-html (lambda (n) ;; look for doc on current dir, then html dir, then global dir ;; snd.html is what we'll search for (let ((dir (if (file-exists? "snd.html") (getcwd) (if (and (string? *html-dir*) (file-exists? (string-append *html-dir* "/snd.html"))) *html-dir* (if (file-exists? "/usr/share/doc/snd-16/snd.html") "/usr/share/doc/snd-16" (if (file-exists? "/usr/local/share/doc/snd-16/snd.html") "/usr/local/share/doc/snd-16" (if (file-exists? "/usr/doc/snd-16/snd.html") "/usr/doc/snd-16" (if (file-exists? "/usr/share/doc/snd-15/snd.html") "/usr/share/doc/snd-15" (if (file-exists? "/usr/local/share/doc/snd-15/snd.html") "/usr/local/share/doc/snd-15" (and (file-exists? "/usr/doc/snd-15/snd.html") "/usr/doc/snd-15")))))))))) (if dir (system (string-append *html-program* " file:" dir "/" n))))))) (let ((name (if (string? obj) obj (if (symbol? obj) (symbol->string obj) (let ((doc (and (procedure? obj) (procedure-documentation obj)))) (if (and (string? doc) (char=? (doc 0) #\()) (let ((pos (char-position ") " doc))) (and pos (substring doc 1 pos))))))))) (if (and name (string? name)) (let ((url (snd-url name))) (if url (goto-html url) (snd-print (format #f "no url for ~A?" name)))) (snd-print (format #f "no doc for ~A?" name)))))))) snd-16.1/NEWS0000644000076400007640000000031512626144464011042 0ustar bilbilSnd 16.1: most of my time went into lint.scm, but the harder I work on it, the longer my TODO list. s7: :key and :optional removed. checked: gtk 3.19.1|2|3, sbcl 1.3.0|1, GSL 2.0 Thanks!: Norman Gray snd-16.1/gl2ps.c0000644000076400007640000055217712306421667011556 0ustar bilbil/* * GL2PS, an OpenGL to PostScript Printing Library * Copyright (C) 1999-2012 C. Geuzaine * * This program is free software; you can redistribute it and/or * modify it under the terms of either: * * a) the GNU Library General Public License as published by the Free * Software Foundation, either version 2 of the License, or (at your * option) any later version; or * * b) the GL2PS License as published by Christophe Geuzaine, either * version 2 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See either * the GNU Library General Public License or the GL2PS License for * more details. * * You should have received a copy of the GNU Library General Public * License along with this library in the file named "COPYING.LGPL"; * if not, write to the Free Software Foundation, Inc., 51 Franklin * Street, Fifth Floor, Boston, MA 02110-1301, USA. * * You should have received a copy of the GL2PS License with this * library in the file named "COPYING.GL2PS"; if not, I will be glad * to provide one. * * For the latest info about gl2ps and a full list of contributors, * see http://www.geuz.org/gl2ps/. * * Please report all bugs and problems to . */ #include "gl2ps.h" #include #include #include #include #include #include #if defined(GL2PS_HAVE_ZLIB) #include #endif #if defined(GL2PS_HAVE_LIBPNG) #include #endif /********************************************************************* * * Private definitions, data structures and prototypes * *********************************************************************/ /* Magic numbers (assuming that the order of magnitude of window coordinates is 10^3) */ #define GL2PS_EPSILON 5.0e-3F #define GL2PS_ZSCALE 1000.0F #define GL2PS_ZOFFSET 5.0e-2F #define GL2PS_ZOFFSET_LARGE 20.0F #define GL2PS_ZERO(arg) (fabs(arg) < 1.e-20) /* Primitive types */ #define GL2PS_NO_TYPE -1 #define GL2PS_TEXT 1 #define GL2PS_POINT 2 #define GL2PS_LINE 3 #define GL2PS_QUADRANGLE 4 #define GL2PS_TRIANGLE 5 #define GL2PS_PIXMAP 6 #define GL2PS_IMAGEMAP 7 #define GL2PS_IMAGEMAP_WRITTEN 8 #define GL2PS_IMAGEMAP_VISIBLE 9 #define GL2PS_SPECIAL 10 /* BSP tree primitive comparison */ #define GL2PS_COINCIDENT 1 #define GL2PS_IN_FRONT_OF 2 #define GL2PS_IN_BACK_OF 3 #define GL2PS_SPANNING 4 /* 2D BSP tree primitive comparison */ #define GL2PS_POINT_COINCIDENT 0 #define GL2PS_POINT_INFRONT 1 #define GL2PS_POINT_BACK 2 /* Internal feedback buffer pass-through tokens */ #define GL2PS_BEGIN_OFFSET_TOKEN 1 #define GL2PS_END_OFFSET_TOKEN 2 #define GL2PS_BEGIN_BOUNDARY_TOKEN 3 #define GL2PS_END_BOUNDARY_TOKEN 4 #define GL2PS_BEGIN_STIPPLE_TOKEN 5 #define GL2PS_END_STIPPLE_TOKEN 6 #define GL2PS_POINT_SIZE_TOKEN 7 #define GL2PS_LINE_WIDTH_TOKEN 8 #define GL2PS_BEGIN_BLEND_TOKEN 9 #define GL2PS_END_BLEND_TOKEN 10 #define GL2PS_SRC_BLEND_TOKEN 11 #define GL2PS_DST_BLEND_TOKEN 12 #define GL2PS_IMAGEMAP_TOKEN 13 #define GL2PS_DRAW_PIXELS_TOKEN 14 #define GL2PS_TEXT_TOKEN 15 typedef enum { T_UNDEFINED = -1, T_CONST_COLOR = 1, T_VAR_COLOR = 1<<1, T_ALPHA_1 = 1<<2, T_ALPHA_LESS_1 = 1<<3, T_VAR_ALPHA = 1<<4 } GL2PS_TRIANGLE_PROPERTY; typedef GLfloat GL2PSxyz[3]; typedef GLfloat GL2PSplane[4]; typedef struct _GL2PSbsptree2d GL2PSbsptree2d; struct _GL2PSbsptree2d { GL2PSplane plane; GL2PSbsptree2d *front, *back; }; typedef struct { GLint nmax, size, incr, n; char *array; } GL2PSlist; typedef struct _GL2PSbsptree GL2PSbsptree; struct _GL2PSbsptree { GL2PSplane plane; GL2PSlist *primitives; GL2PSbsptree *front, *back; }; typedef struct { GL2PSxyz xyz; GL2PSrgba rgba; } GL2PSvertex; typedef struct { GL2PSvertex vertex[3]; int prop; } GL2PStriangle; typedef struct { GLshort fontsize; char *str, *fontname; /* Note: for a 'special' string, 'alignment' holds the format (PostScript, PDF, etc.) of the special string */ GLint alignment; GLfloat angle; } GL2PSstring; typedef struct { GLsizei width, height; /* Note: for an imagemap, 'type' indicates if it has already been written to the file or not, and 'format' indicates if it is visible or not */ GLenum format, type; GLfloat zoom_x, zoom_y; GLfloat *pixels; } GL2PSimage; typedef struct _GL2PSimagemap GL2PSimagemap; struct _GL2PSimagemap { GL2PSimage *image; GL2PSimagemap *next; }; typedef struct { GLshort type, numverts; GLushort pattern; char boundary, offset, culled; GLint factor; GLfloat width; GL2PSvertex *verts; union { GL2PSstring *text; GL2PSimage *image; } data; } GL2PSprimitive; typedef struct { #if defined(GL2PS_HAVE_ZLIB) Bytef *dest, *src, *start; uLongf destLen, srcLen; #else int dummy; #endif } GL2PScompress; typedef struct{ GL2PSlist* ptrlist; int gsno, fontno, imno, shno, maskshno, trgroupno; int gsobjno, fontobjno, imobjno, shobjno, maskshobjno, trgroupobjno; } GL2PSpdfgroup; typedef struct { /* General */ GLint format, sort, options, colorsize, colormode, buffersize; char *title, *producer, *filename; GLboolean boundary, blending; GLfloat *feedback, offset[2], lastlinewidth; GLint viewport[4], blendfunc[2], lastfactor; GL2PSrgba *colormap, lastrgba, threshold, bgcolor; GLushort lastpattern; GL2PSvertex lastvertex; GL2PSlist *primitives, *auxprimitives; FILE *stream; GL2PScompress *compress; GLboolean header; /* BSP-specific */ GLint maxbestroot; /* Occlusion culling-specific */ GLboolean zerosurfacearea; GL2PSbsptree2d *imagetree; GL2PSprimitive *primitivetoadd; /* PDF-specific */ int streamlength; GL2PSlist *pdfprimlist, *pdfgrouplist; int *xreflist; int objects_stack; /* available objects */ int extgs_stack; /* graphics state object number */ int font_stack; /* font object number */ int im_stack; /* image object number */ int trgroupobjects_stack; /* xobject numbers */ int shader_stack; /* shader object numbers */ int mshader_stack; /* mask shader object numbers */ /* for image map list */ GL2PSimagemap *imagemap_head; GL2PSimagemap *imagemap_tail; } GL2PScontext; typedef struct { void (*printHeader)(void); void (*printFooter)(void); void (*beginViewport)(GLint viewport[4]); GLint (*endViewport)(void); void (*printPrimitive)(void *data); void (*printFinalPrimitive)(void); const char *file_extension; const char *description; } GL2PSbackend; /* The gl2ps context. gl2ps is not thread safe (we should create a local GL2PScontext during gl2psBeginPage) */ static GL2PScontext *gl2ps = NULL; /* Need to forward-declare this one */ static GLint gl2psPrintPrimitives(void); /********************************************************************* * * Utility routines * *********************************************************************/ static void gl2psMsg(GLint level, const char *fmt, ...) { va_list args; if(!(gl2ps->options & GL2PS_SILENT)){ switch(level){ case GL2PS_INFO : fprintf(stderr, "GL2PS info: "); break; case GL2PS_WARNING : fprintf(stderr, "GL2PS warning: "); break; case GL2PS_ERROR : fprintf(stderr, "GL2PS error: "); break; } va_start(args, fmt); vfprintf(stderr, fmt, args); va_end(args); fprintf(stderr, "\n"); } /* if(level == GL2PS_ERROR) exit(1); */ } static void *gl2psMalloc(size_t size) { void *ptr; if(!size) return NULL; ptr = malloc(size); if(!ptr){ gl2psMsg(GL2PS_ERROR, "Couldn't allocate requested memory"); return NULL; } return ptr; } static void *gl2psRealloc(void *ptr, size_t size) { void *orig = ptr; if(!size) return NULL; ptr = realloc(orig, size); if(!ptr){ gl2psMsg(GL2PS_ERROR, "Couldn't reallocate requested memory"); free(orig); return NULL; } return ptr; } static void gl2psFree(void *ptr) { if(!ptr) return; free(ptr); } static int gl2psWriteBigEndian(unsigned long data, int bytes) { int i; int size = sizeof(unsigned long); for(i = 1; i <= bytes; ++i){ fputc(0xff & (data >> (size - i) * 8), gl2ps->stream); } return bytes; } /* zlib compression helper routines */ #if defined(GL2PS_HAVE_ZLIB) static void gl2psSetupCompress(void) { gl2ps->compress = (GL2PScompress*)gl2psMalloc(sizeof(GL2PScompress)); gl2ps->compress->src = NULL; gl2ps->compress->start = NULL; gl2ps->compress->dest = NULL; gl2ps->compress->srcLen = 0; gl2ps->compress->destLen = 0; } static void gl2psFreeCompress(void) { if(!gl2ps->compress) return; gl2psFree(gl2ps->compress->start); gl2psFree(gl2ps->compress->dest); gl2ps->compress->src = NULL; gl2ps->compress->start = NULL; gl2ps->compress->dest = NULL; gl2ps->compress->srcLen = 0; gl2ps->compress->destLen = 0; } static int gl2psAllocCompress(unsigned int srcsize) { gl2psFreeCompress(); if(!gl2ps->compress || !srcsize) return GL2PS_ERROR; gl2ps->compress->srcLen = srcsize; gl2ps->compress->destLen = (int)ceil(1.001 * gl2ps->compress->srcLen + 12); gl2ps->compress->src = (Bytef*)gl2psMalloc(gl2ps->compress->srcLen); gl2ps->compress->start = gl2ps->compress->src; gl2ps->compress->dest = (Bytef*)gl2psMalloc(gl2ps->compress->destLen); return GL2PS_SUCCESS; } static void *gl2psReallocCompress(unsigned int srcsize) { if(!gl2ps->compress || !srcsize) return NULL; if(srcsize < gl2ps->compress->srcLen) return gl2ps->compress->start; gl2ps->compress->srcLen = srcsize; gl2ps->compress->destLen = (int)ceil(1.001 * gl2ps->compress->srcLen + 12); gl2ps->compress->src = (Bytef*)gl2psRealloc(gl2ps->compress->src, gl2ps->compress->srcLen); gl2ps->compress->start = gl2ps->compress->src; gl2ps->compress->dest = (Bytef*)gl2psRealloc(gl2ps->compress->dest, gl2ps->compress->destLen); return gl2ps->compress->start; } static int gl2psWriteBigEndianCompress(unsigned long data, int bytes) { int i; int size = sizeof(unsigned long); for(i = 1; i <= bytes; ++i){ *gl2ps->compress->src = (Bytef)(0xff & (data >> (size-i) * 8)); ++gl2ps->compress->src; } return bytes; } static int gl2psDeflate(void) { /* For compatibility with older zlib versions, we use compress(...) instead of compress2(..., Z_BEST_COMPRESSION) */ return compress(gl2ps->compress->dest, &gl2ps->compress->destLen, gl2ps->compress->start, gl2ps->compress->srcLen); } #endif static int gl2psPrintf(const char* fmt, ...) { int ret; va_list args; #if defined(GL2PS_HAVE_ZLIB) static char buf[1024]; char *bufptr = buf; GLboolean freebuf = GL_FALSE; unsigned int oldsize = 0; #if !defined(GL2PS_HAVE_NO_VSNPRINTF) /* Try writing the string to a 1024 byte buffer. If it is too small to fit, keep trying larger sizes until it does. */ size_t bufsize = sizeof(buf); #endif if(gl2ps->options & GL2PS_COMPRESS){ va_start(args, fmt); #if defined(GL2PS_HAVE_NO_VSNPRINTF) ret = vsprintf(buf, fmt, args); #else ret = vsnprintf(bufptr, bufsize, fmt, args); #endif va_end(args); #if !defined(GL2PS_HAVE_NO_VSNPRINTF) while(ret >= (bufsize - 1) || ret < 0){ /* Too big. Allocate a new buffer. */ bufsize *= 2; if(freebuf == GL_TRUE) gl2psFree(bufptr); bufptr = (char *)gl2psMalloc(bufsize); freebuf = GL_TRUE; va_start(args, fmt); ret = vsnprintf(bufptr, bufsize, fmt, args); va_end(args); } #endif oldsize = gl2ps->compress->srcLen; gl2ps->compress->start = (Bytef*)gl2psReallocCompress(oldsize + ret); memcpy(gl2ps->compress->start + oldsize, bufptr, ret); if(freebuf == GL_TRUE) gl2psFree(bufptr); ret = 0; } else{ #endif va_start(args, fmt); ret = vfprintf(gl2ps->stream, fmt, args); va_end(args); #if defined(GL2PS_HAVE_ZLIB) } #endif return ret; } static void gl2psPrintGzipHeader(void) { #if defined(GL2PS_HAVE_ZLIB) char tmp[10] = {'\x1f', '\x8b', /* magic numbers: 0x1f, 0x8b */ 8, /* compression method: Z_DEFLATED */ 0, /* flags */ 0, 0, 0, 0, /* time */ 2, /* extra flags: max compression */ '\x03'}; /* OS code: 0x03 (Unix) */ if(gl2ps->options & GL2PS_COMPRESS){ gl2psSetupCompress(); /* add the gzip file header */ fwrite(tmp, 10, 1, gl2ps->stream); } #endif } static void gl2psPrintGzipFooter(void) { #if defined(GL2PS_HAVE_ZLIB) int n; uLong crc, len; char tmp[8]; if(gl2ps->options & GL2PS_COMPRESS){ if(Z_OK != gl2psDeflate()){ gl2psMsg(GL2PS_ERROR, "Zlib deflate error"); } else{ /* determine the length of the header in the zlib stream */ n = 2; /* CMF+FLG */ if(gl2ps->compress->dest[1] & (1<<5)){ n += 4; /* DICTID */ } /* write the data, without the zlib header and footer */ fwrite(gl2ps->compress->dest+n, gl2ps->compress->destLen-(n+4), 1, gl2ps->stream); /* add the gzip file footer */ crc = crc32(0L, gl2ps->compress->start, gl2ps->compress->srcLen); for(n = 0; n < 4; ++n){ tmp[n] = (char)(crc & 0xff); crc >>= 8; } len = gl2ps->compress->srcLen; for(n = 4; n < 8; ++n){ tmp[n] = (char)(len & 0xff); len >>= 8; } fwrite(tmp, 8, 1, gl2ps->stream); } gl2psFreeCompress(); gl2psFree(gl2ps->compress); gl2ps->compress = NULL; } #endif } /* The list handling routines */ static void gl2psListRealloc(GL2PSlist *list, GLint n) { if(!list){ gl2psMsg(GL2PS_ERROR, "Cannot reallocate NULL list"); return; } if(n <= 0) return; if(!list->array){ list->nmax = n; list->array = (char*)gl2psMalloc(list->nmax * list->size); } else{ if(n > list->nmax){ list->nmax = ((n - 1) / list->incr + 1) * list->incr; list->array = (char*)gl2psRealloc(list->array, list->nmax * list->size); } } } static GL2PSlist *gl2psListCreate(GLint n, GLint incr, GLint size) { GL2PSlist *list; if(n < 0) n = 0; if(incr <= 0) incr = 1; list = (GL2PSlist*)gl2psMalloc(sizeof(GL2PSlist)); list->nmax = 0; list->incr = incr; list->size = size; list->n = 0; list->array = NULL; gl2psListRealloc(list, n); return list; } static void gl2psListReset(GL2PSlist *list) { if(!list) return; list->n = 0; } static void gl2psListDelete(GL2PSlist *list) { if(!list) return; gl2psFree(list->array); gl2psFree(list); } static void gl2psListAdd(GL2PSlist *list, void *data) { if(!list){ gl2psMsg(GL2PS_ERROR, "Cannot add into unallocated list"); return; } list->n++; gl2psListRealloc(list, list->n); memcpy(&list->array[(list->n - 1) * list->size], data, list->size); } static int gl2psListNbr(GL2PSlist *list) { if(!list) return 0; return list->n; } static void *gl2psListPointer(GL2PSlist *list, GLint idx) { if(!list){ gl2psMsg(GL2PS_ERROR, "Cannot point into unallocated list"); return NULL; } if((idx < 0) || (idx >= list->n)){ gl2psMsg(GL2PS_ERROR, "Wrong list index in gl2psListPointer"); return NULL; } return &list->array[idx * list->size]; } static void gl2psListSort(GL2PSlist *list, int (*fcmp)(const void *a, const void *b)) { if(!list) return; qsort(list->array, list->n, list->size, fcmp); } static void gl2psListAction(GL2PSlist *list, void (*action)(void *data)) { GLint i; for(i = 0; i < gl2psListNbr(list); i++){ (*action)(gl2psListPointer(list, i)); } } static void gl2psListActionInverse(GL2PSlist *list, void (*action)(void *data)) { GLint i; for(i = gl2psListNbr(list); i > 0; i--){ (*action)(gl2psListPointer(list, i-1)); } } #if defined(GL2PS_HAVE_LIBPNG) static void gl2psListRead(GL2PSlist *list, int index, void *data) { if((index < 0) || (index >= list->n)) gl2psMsg(GL2PS_ERROR, "Wrong list index in gl2psListRead"); memcpy(data, &list->array[index * list->size], list->size); } static void gl2psEncodeBase64Block(unsigned char in[3], unsigned char out[4], int len) { static const char cb64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; out[0] = cb64[ in[0] >> 2 ]; out[1] = cb64[ ((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4) ]; out[2] = (len > 1) ? cb64[ ((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6) ] : '='; out[3] = (len > 2) ? cb64[ in[2] & 0x3f ] : '='; } static void gl2psListEncodeBase64(GL2PSlist *list) { unsigned char *buffer, in[3], out[4]; int i, n, index, len; n = list->n * list->size; buffer = (unsigned char*)gl2psMalloc(n * sizeof(unsigned char)); memcpy(buffer, list->array, n * sizeof(unsigned char)); gl2psListReset(list); index = 0; while(index < n) { len = 0; for(i = 0; i < 3; i++) { if(index < n){ in[i] = buffer[index]; len++; } else{ in[i] = 0; } index++; } if(len) { gl2psEncodeBase64Block(in, out, len); for(i = 0; i < 4; i++) gl2psListAdd(list, &out[i]); } } gl2psFree(buffer); } #endif /* Helpers for rgba colors */ static GLboolean gl2psSameColor(GL2PSrgba rgba1, GL2PSrgba rgba2) { if(!GL2PS_ZERO(rgba1[0] - rgba2[0]) || !GL2PS_ZERO(rgba1[1] - rgba2[1]) || !GL2PS_ZERO(rgba1[2] - rgba2[2])) return GL_FALSE; return GL_TRUE; } static GLboolean gl2psVertsSameColor(const GL2PSprimitive *prim) { int i; for(i = 1; i < prim->numverts; i++){ if(!gl2psSameColor(prim->verts[0].rgba, prim->verts[i].rgba)){ return GL_FALSE; } } return GL_TRUE; } static GLboolean gl2psSameColorThreshold(int n, GL2PSrgba rgba[], GL2PSrgba threshold) { int i; if(n < 2) return GL_TRUE; for(i = 1; i < n; i++){ if(fabs(rgba[0][0] - rgba[i][0]) > threshold[0] || fabs(rgba[0][1] - rgba[i][1]) > threshold[1] || fabs(rgba[0][2] - rgba[i][2]) > threshold[2]) return GL_FALSE; } return GL_TRUE; } static void gl2psSetLastColor(GL2PSrgba rgba) { int i; for(i = 0; i < 3; ++i){ gl2ps->lastrgba[i] = rgba[i]; } } static GLfloat gl2psGetRGB(GL2PSimage *im, GLuint x, GLuint y, GLfloat *red, GLfloat *green, GLfloat *blue) { GLsizei width = im->width; GLsizei height = im->height; GLfloat *pixels = im->pixels; GLfloat *pimag; /* OpenGL image is from down to up, PS image is up to down */ switch(im->format){ case GL_RGBA: pimag = pixels + 4 * (width * (height - 1 - y) + x); break; case GL_RGB: default: pimag = pixels + 3 * (width * (height - 1 - y) + x); break; } *red = *pimag; pimag++; *green = *pimag; pimag++; *blue = *pimag; pimag++; return (im->format == GL_RGBA) ? *pimag : 1.0F; } /* Helper routines for pixmaps */ static GL2PSimage *gl2psCopyPixmap(GL2PSimage *im) { int size; GL2PSimage *image = (GL2PSimage*)gl2psMalloc(sizeof(GL2PSimage)); image->width = im->width; image->height = im->height; image->format = im->format; image->type = im->type; image->zoom_x = im->zoom_x; image->zoom_y = im->zoom_y; switch(image->format){ case GL_RGBA: size = image->height * image->width * 4 * sizeof(GLfloat); break; case GL_RGB: default: size = image->height * image->width * 3 * sizeof(GLfloat); break; } image->pixels = (GLfloat*)gl2psMalloc(size); memcpy(image->pixels, im->pixels, size); return image; } static void gl2psFreePixmap(GL2PSimage *im) { if(!im) return; gl2psFree(im->pixels); gl2psFree(im); } #if defined(GL2PS_HAVE_LIBPNG) #if !defined(png_jmpbuf) # define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf) #endif static void gl2psUserWritePNG(png_structp png_ptr, png_bytep data, png_size_t length) { unsigned int i; GL2PSlist *png = (GL2PSlist*)png_get_io_ptr(png_ptr); for(i = 0; i < length; i++) gl2psListAdd(png, &data[i]); } static void gl2psUserFlushPNG(png_structp png_ptr) { (void) png_ptr; /* not used */ } static void gl2psConvertPixmapToPNG(GL2PSimage *pixmap, GL2PSlist *png) { png_structp png_ptr; png_infop info_ptr; unsigned char *row_data; GLfloat dr, dg, db; int row, col; if(!(png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL))) return; if(!(info_ptr = png_create_info_struct(png_ptr))){ png_destroy_write_struct(&png_ptr, NULL); return; } if(setjmp(png_jmpbuf(png_ptr))) { png_destroy_write_struct(&png_ptr, &info_ptr); return; } png_set_write_fn(png_ptr, (void *)png, gl2psUserWritePNG, gl2psUserFlushPNG); png_set_compression_level(png_ptr, Z_DEFAULT_COMPRESSION); png_set_IHDR(png_ptr, info_ptr, pixmap->width, pixmap->height, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); png_write_info(png_ptr, info_ptr); row_data = (unsigned char*)gl2psMalloc(3 * pixmap->width * sizeof(unsigned char)); for(row = 0; row < pixmap->height; row++){ for(col = 0; col < pixmap->width; col++){ gl2psGetRGB(pixmap, col, row, &dr, &dg, &db); row_data[3*col] = (unsigned char)(255. * dr); row_data[3*col+1] = (unsigned char)(255. * dg); row_data[3*col+2] = (unsigned char)(255. * db); } png_write_row(png_ptr, (png_bytep)row_data); } gl2psFree(row_data); png_write_end(png_ptr, info_ptr); png_destroy_write_struct(&png_ptr, &info_ptr); } #endif /* Helper routines for text strings */ static GLint gl2psAddText(GLint type, const char *str, const char *fontname, GLshort fontsize, GLint alignment, GLfloat angle, GL2PSrgba color) { GLfloat pos[4]; GL2PSprimitive *prim; GLboolean valid; if(!gl2ps || !str || !fontname) return GL2PS_UNINITIALIZED; if(gl2ps->options & GL2PS_NO_TEXT) return GL2PS_SUCCESS; glGetBooleanv(GL_CURRENT_RASTER_POSITION_VALID, &valid); if(GL_FALSE == valid) return GL2PS_SUCCESS; /* the primitive is culled */ glGetFloatv(GL_CURRENT_RASTER_POSITION, pos); prim = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive)); prim->type = type; prim->boundary = 0; prim->numverts = 1; prim->verts = (GL2PSvertex*)gl2psMalloc(sizeof(GL2PSvertex)); prim->verts[0].xyz[0] = pos[0]; prim->verts[0].xyz[1] = pos[1]; prim->verts[0].xyz[2] = pos[2]; prim->culled = 0; prim->offset = 0; prim->pattern = 0; prim->factor = 0; prim->width = 1; if (color) memcpy(prim->verts[0].rgba, color, 4 * sizeof(float)); else glGetFloatv(GL_CURRENT_RASTER_COLOR, prim->verts[0].rgba); prim->data.text = (GL2PSstring*)gl2psMalloc(sizeof(GL2PSstring)); prim->data.text->str = (char*)gl2psMalloc((strlen(str)+1)*sizeof(char)); strcpy(prim->data.text->str, str); prim->data.text->fontname = (char*)gl2psMalloc((strlen(fontname)+1)*sizeof(char)); strcpy(prim->data.text->fontname, fontname); prim->data.text->fontsize = fontsize; prim->data.text->alignment = alignment; prim->data.text->angle = angle; gl2psListAdd(gl2ps->auxprimitives, &prim); glPassThrough(GL2PS_TEXT_TOKEN); return GL2PS_SUCCESS; } static GL2PSstring *gl2psCopyText(GL2PSstring *t) { GL2PSstring *text = (GL2PSstring*)gl2psMalloc(sizeof(GL2PSstring)); text->str = (char*)gl2psMalloc((strlen(t->str)+1)*sizeof(char)); strcpy(text->str, t->str); text->fontname = (char*)gl2psMalloc((strlen(t->fontname)+1)*sizeof(char)); strcpy(text->fontname, t->fontname); text->fontsize = t->fontsize; text->alignment = t->alignment; text->angle = t->angle; return text; } static void gl2psFreeText(GL2PSstring *text) { if(!text) return; gl2psFree(text->str); gl2psFree(text->fontname); gl2psFree(text); } /* Helpers for blending modes */ static GLboolean gl2psSupportedBlendMode(GLenum sfactor, GLenum dfactor) { /* returns TRUE if gl2ps supports the argument combination: only two blending modes have been implemented so far */ if( (sfactor == GL_SRC_ALPHA && dfactor == GL_ONE_MINUS_SRC_ALPHA) || (sfactor == GL_ONE && dfactor == GL_ZERO) ) return GL_TRUE; return GL_FALSE; } static void gl2psAdaptVertexForBlending(GL2PSvertex *v) { /* Transforms vertex depending on the actual blending function - currently the vertex v is considered as source vertex and his alpha value is changed to 1.0 if source blending GL_ONE is active. This might be extended in the future */ if(!v || !gl2ps) return; if(gl2ps->options & GL2PS_NO_BLENDING || !gl2ps->blending){ v->rgba[3] = 1.0F; return; } switch(gl2ps->blendfunc[0]){ case GL_ONE: v->rgba[3] = 1.0F; break; default: break; } } static void gl2psAssignTriangleProperties(GL2PStriangle *t) { /* int i; */ t->prop = T_VAR_COLOR; /* Uncommenting the following lines activates an even more fine grained distinction between triangle types - please don't delete, a remarkable amount of PDF handling code inside this file depends on it if activated */ /* t->prop = T_CONST_COLOR; for(i = 0; i < 3; ++i){ if(!GL2PS_ZERO(t->vertex[0].rgba[i] - t->vertex[1].rgba[i]) || !GL2PS_ZERO(t->vertex[1].rgba[i] - t->vertex[2].rgba[i])){ t->prop = T_VAR_COLOR; break; } } */ if(!GL2PS_ZERO(t->vertex[0].rgba[3] - t->vertex[1].rgba[3]) || !GL2PS_ZERO(t->vertex[1].rgba[3] - t->vertex[2].rgba[3])){ t->prop |= T_VAR_ALPHA; } else{ if(t->vertex[0].rgba[3] < 1) t->prop |= T_ALPHA_LESS_1; else t->prop |= T_ALPHA_1; } } static void gl2psFillTriangleFromPrimitive(GL2PStriangle *t, GL2PSprimitive *p, GLboolean assignprops) { t->vertex[0] = p->verts[0]; t->vertex[1] = p->verts[1]; t->vertex[2] = p->verts[2]; if(GL_TRUE == assignprops) gl2psAssignTriangleProperties(t); } static void gl2psInitTriangle(GL2PStriangle *t) { int i; GL2PSvertex vertex = { {-1.0F, -1.0F, -1.0F}, {-1.0F, -1.0F, -1.0F, -1.0F} }; for(i = 0; i < 3; i++) t->vertex[i] = vertex; t->prop = T_UNDEFINED; } /* Miscellaneous helper routines */ static GL2PSprimitive *gl2psCopyPrimitive(GL2PSprimitive *p) { GL2PSprimitive *prim; if(!p){ gl2psMsg(GL2PS_ERROR, "Trying to copy an empty primitive"); return NULL; } prim = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive)); prim->type = p->type; prim->numverts = p->numverts; prim->boundary = p->boundary; prim->offset = p->offset; prim->pattern = p->pattern; prim->factor = p->factor; prim->culled = p->culled; prim->width = p->width; prim->verts = (GL2PSvertex*)gl2psMalloc(p->numverts*sizeof(GL2PSvertex)); memcpy(prim->verts, p->verts, p->numverts * sizeof(GL2PSvertex)); switch(prim->type){ case GL2PS_PIXMAP : prim->data.image = gl2psCopyPixmap(p->data.image); break; case GL2PS_TEXT : case GL2PS_SPECIAL : prim->data.text = gl2psCopyText(p->data.text); break; default: break; } return prim; } static GLboolean gl2psSamePosition(GL2PSxyz p1, GL2PSxyz p2) { if(!GL2PS_ZERO(p1[0] - p2[0]) || !GL2PS_ZERO(p1[1] - p2[1]) || !GL2PS_ZERO(p1[2] - p2[2])) return GL_FALSE; return GL_TRUE; } /********************************************************************* * * 3D sorting routines * *********************************************************************/ static GLfloat gl2psComparePointPlane(GL2PSxyz point, GL2PSplane plane) { return (plane[0] * point[0] + plane[1] * point[1] + plane[2] * point[2] + plane[3]); } static GLfloat gl2psPsca(GLfloat *a, GLfloat *b) { return (a[0]*b[0] + a[1]*b[1] + a[2]*b[2]); } static void gl2psPvec(GLfloat *a, GLfloat *b, GLfloat *c) { c[0] = a[1]*b[2] - a[2]*b[1]; c[1] = a[2]*b[0] - a[0]*b[2]; c[2] = a[0]*b[1] - a[1]*b[0]; } static GLfloat gl2psNorm(GLfloat *a) { return (GLfloat)sqrt(a[0]*a[0] + a[1]*a[1] + a[2]*a[2]); } static void gl2psGetNormal(GLfloat *a, GLfloat *b, GLfloat *c) { GLfloat norm; gl2psPvec(a, b, c); if(!GL2PS_ZERO(norm = gl2psNorm(c))){ c[0] = c[0] / norm; c[1] = c[1] / norm; c[2] = c[2] / norm; } else{ /* The plane is still wrong despite our tests in gl2psGetPlane. Let's return a dummy value for now (this is a hack: we should do more intelligent tests in GetPlane) */ c[0] = c[1] = 0.0F; c[2] = 1.0F; } } static void gl2psGetPlane(GL2PSprimitive *prim, GL2PSplane plane) { GL2PSxyz v = {0.0F, 0.0F, 0.0F}, w = {0.0F, 0.0F, 0.0F}; switch(prim->type){ case GL2PS_TRIANGLE : case GL2PS_QUADRANGLE : v[0] = prim->verts[1].xyz[0] - prim->verts[0].xyz[0]; v[1] = prim->verts[1].xyz[1] - prim->verts[0].xyz[1]; v[2] = prim->verts[1].xyz[2] - prim->verts[0].xyz[2]; w[0] = prim->verts[2].xyz[0] - prim->verts[0].xyz[0]; w[1] = prim->verts[2].xyz[1] - prim->verts[0].xyz[1]; w[2] = prim->verts[2].xyz[2] - prim->verts[0].xyz[2]; if((GL2PS_ZERO(v[0]) && GL2PS_ZERO(v[1]) && GL2PS_ZERO(v[2])) || (GL2PS_ZERO(w[0]) && GL2PS_ZERO(w[1]) && GL2PS_ZERO(w[2]))){ plane[0] = plane[1] = 0.0F; plane[2] = 1.0F; plane[3] = -prim->verts[0].xyz[2]; } else{ gl2psGetNormal(v, w, plane); plane[3] = - plane[0] * prim->verts[0].xyz[0] - plane[1] * prim->verts[0].xyz[1] - plane[2] * prim->verts[0].xyz[2]; } break; case GL2PS_LINE : v[0] = prim->verts[1].xyz[0] - prim->verts[0].xyz[0]; v[1] = prim->verts[1].xyz[1] - prim->verts[0].xyz[1]; v[2] = prim->verts[1].xyz[2] - prim->verts[0].xyz[2]; if(GL2PS_ZERO(v[0]) && GL2PS_ZERO(v[1]) && GL2PS_ZERO(v[2])){ plane[0] = plane[1] = 0.0F; plane[2] = 1.0F; plane[3] = -prim->verts[0].xyz[2]; } else{ if(GL2PS_ZERO(v[0])) w[0] = 1.0F; else if(GL2PS_ZERO(v[1])) w[1] = 1.0F; else w[2] = 1.0F; gl2psGetNormal(v, w, plane); plane[3] = - plane[0] * prim->verts[0].xyz[0] - plane[1] * prim->verts[0].xyz[1] - plane[2] * prim->verts[0].xyz[2]; } break; case GL2PS_POINT : case GL2PS_PIXMAP : case GL2PS_TEXT : case GL2PS_SPECIAL : case GL2PS_IMAGEMAP: plane[0] = plane[1] = 0.0F; plane[2] = 1.0F; plane[3] = -prim->verts[0].xyz[2]; break; default : gl2psMsg(GL2PS_ERROR, "Unknown primitive type in BSP tree"); plane[0] = plane[1] = plane[3] = 0.0F; plane[2] = 1.0F; break; } } static void gl2psCutEdge(GL2PSvertex *a, GL2PSvertex *b, GL2PSplane plane, GL2PSvertex *c) { GL2PSxyz v; GLfloat sect, psca; v[0] = b->xyz[0] - a->xyz[0]; v[1] = b->xyz[1] - a->xyz[1]; v[2] = b->xyz[2] - a->xyz[2]; if(!GL2PS_ZERO(psca = gl2psPsca(plane, v))) sect = -gl2psComparePointPlane(a->xyz, plane) / psca; else sect = 0.0F; c->xyz[0] = a->xyz[0] + v[0] * sect; c->xyz[1] = a->xyz[1] + v[1] * sect; c->xyz[2] = a->xyz[2] + v[2] * sect; c->rgba[0] = (1 - sect) * a->rgba[0] + sect * b->rgba[0]; c->rgba[1] = (1 - sect) * a->rgba[1] + sect * b->rgba[1]; c->rgba[2] = (1 - sect) * a->rgba[2] + sect * b->rgba[2]; c->rgba[3] = (1 - sect) * a->rgba[3] + sect * b->rgba[3]; } static void gl2psCreateSplitPrimitive(GL2PSprimitive *parent, GL2PSplane plane, GL2PSprimitive *child, GLshort numverts, GLshort *index0, GLshort *index1) { GLshort i; if(parent->type == GL2PS_IMAGEMAP){ child->type = GL2PS_IMAGEMAP; child->data.image = parent->data.image; } else{ if(numverts > 4){ gl2psMsg(GL2PS_WARNING, "%d vertices in polygon", numverts); numverts = 4; } switch(numverts){ case 1 : child->type = GL2PS_POINT; break; case 2 : child->type = GL2PS_LINE; break; case 3 : child->type = GL2PS_TRIANGLE; break; case 4 : child->type = GL2PS_QUADRANGLE; break; default: child->type = GL2PS_NO_TYPE; break; } } child->boundary = 0; /* FIXME: not done! */ child->culled = parent->culled; child->offset = parent->offset; child->pattern = parent->pattern; child->factor = parent->factor; child->width = parent->width; child->numverts = numverts; child->verts = (GL2PSvertex*)gl2psMalloc(numverts * sizeof(GL2PSvertex)); for(i = 0; i < numverts; i++){ if(index1[i] < 0){ child->verts[i] = parent->verts[index0[i]]; } else{ gl2psCutEdge(&parent->verts[index0[i]], &parent->verts[index1[i]], plane, &child->verts[i]); } } } static void gl2psAddIndex(GLshort *index0, GLshort *index1, GLshort *nb, GLshort i, GLshort j) { GLint k; for(k = 0; k < *nb; k++){ if((index0[k] == i && index1[k] == j) || (index1[k] == i && index0[k] == j)) return; } index0[*nb] = i; index1[*nb] = j; (*nb)++; } static GLshort gl2psGetIndex(GLshort i, GLshort num) { return (i < num - 1) ? i + 1 : 0; } static GLint gl2psTestSplitPrimitive(GL2PSprimitive *prim, GL2PSplane plane) { GLint type = GL2PS_COINCIDENT; GLshort i, j; GLfloat d[5]; for(i = 0; i < prim->numverts; i++){ d[i] = gl2psComparePointPlane(prim->verts[i].xyz, plane); } if(prim->numverts < 2){ return 0; } else{ for(i = 0; i < prim->numverts; i++){ j = gl2psGetIndex(i, prim->numverts); if(d[j] > GL2PS_EPSILON){ if(type == GL2PS_COINCIDENT) type = GL2PS_IN_BACK_OF; else if(type != GL2PS_IN_BACK_OF) return 1; if(d[i] < -GL2PS_EPSILON) return 1; } else if(d[j] < -GL2PS_EPSILON){ if(type == GL2PS_COINCIDENT) type = GL2PS_IN_FRONT_OF; else if(type != GL2PS_IN_FRONT_OF) return 1; if(d[i] > GL2PS_EPSILON) return 1; } } } return 0; } static GLint gl2psSplitPrimitive(GL2PSprimitive *prim, GL2PSplane plane, GL2PSprimitive **front, GL2PSprimitive **back) { GLshort i, j, in = 0, out = 0, in0[5], in1[5], out0[5], out1[5]; GLint type; GLfloat d[5]; type = GL2PS_COINCIDENT; for(i = 0; i < prim->numverts; i++){ d[i] = gl2psComparePointPlane(prim->verts[i].xyz, plane); } switch(prim->type){ case GL2PS_POINT : if(d[0] > GL2PS_EPSILON) type = GL2PS_IN_BACK_OF; else if(d[0] < -GL2PS_EPSILON) type = GL2PS_IN_FRONT_OF; else type = GL2PS_COINCIDENT; break; default : for(i = 0; i < prim->numverts; i++){ j = gl2psGetIndex(i, prim->numverts); if(d[j] > GL2PS_EPSILON){ if(type == GL2PS_COINCIDENT) type = GL2PS_IN_BACK_OF; else if(type != GL2PS_IN_BACK_OF) type = GL2PS_SPANNING; if(d[i] < -GL2PS_EPSILON){ gl2psAddIndex(in0, in1, &in, i, j); gl2psAddIndex(out0, out1, &out, i, j); type = GL2PS_SPANNING; } gl2psAddIndex(out0, out1, &out, j, -1); } else if(d[j] < -GL2PS_EPSILON){ if(type == GL2PS_COINCIDENT) type = GL2PS_IN_FRONT_OF; else if(type != GL2PS_IN_FRONT_OF) type = GL2PS_SPANNING; if(d[i] > GL2PS_EPSILON){ gl2psAddIndex(in0, in1, &in, i, j); gl2psAddIndex(out0, out1, &out, i, j); type = GL2PS_SPANNING; } gl2psAddIndex(in0, in1, &in, j, -1); } else{ gl2psAddIndex(in0, in1, &in, j, -1); gl2psAddIndex(out0, out1, &out, j, -1); } } break; } if(type == GL2PS_SPANNING){ *back = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive)); *front = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive)); gl2psCreateSplitPrimitive(prim, plane, *back, out, out0, out1); gl2psCreateSplitPrimitive(prim, plane, *front, in, in0, in1); } return type; } static void gl2psDivideQuad(GL2PSprimitive *quad, GL2PSprimitive **t1, GL2PSprimitive **t2) { *t1 = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive)); *t2 = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive)); (*t1)->type = (*t2)->type = GL2PS_TRIANGLE; (*t1)->numverts = (*t2)->numverts = 3; (*t1)->culled = (*t2)->culled = quad->culled; (*t1)->offset = (*t2)->offset = quad->offset; (*t1)->pattern = (*t2)->pattern = quad->pattern; (*t1)->factor = (*t2)->factor = quad->factor; (*t1)->width = (*t2)->width = quad->width; (*t1)->verts = (GL2PSvertex*)gl2psMalloc(3 * sizeof(GL2PSvertex)); (*t2)->verts = (GL2PSvertex*)gl2psMalloc(3 * sizeof(GL2PSvertex)); (*t1)->verts[0] = quad->verts[0]; (*t1)->verts[1] = quad->verts[1]; (*t1)->verts[2] = quad->verts[2]; (*t1)->boundary = ((quad->boundary & 1) ? 1 : 0) | ((quad->boundary & 2) ? 2 : 0); (*t2)->verts[0] = quad->verts[0]; (*t2)->verts[1] = quad->verts[2]; (*t2)->verts[2] = quad->verts[3]; (*t2)->boundary = ((quad->boundary & 4) ? 2 : 0) | ((quad->boundary & 8) ? 4 : 0); } static int gl2psCompareDepth(const void *a, const void *b) { const GL2PSprimitive *q, *w; GLfloat dq = 0.0F, dw = 0.0F, diff; int i; q = *(const GL2PSprimitive* const*)a; w = *(const GL2PSprimitive* const*)b; for(i = 0; i < q->numverts; i++){ dq += q->verts[i].xyz[2]; } dq /= (GLfloat)q->numverts; for(i = 0; i < w->numverts; i++){ dw += w->verts[i].xyz[2]; } dw /= (GLfloat)w->numverts; diff = dq - dw; if(diff > 0.){ return -1; } else if(diff < 0.){ return 1; } else{ return 0; } } static int gl2psTrianglesFirst(const void *a, const void *b) { const GL2PSprimitive *q, *w; q = *(const GL2PSprimitive* const*)a; w = *(const GL2PSprimitive* const*)b; return (q->type < w->type ? 1 : -1); } static GLint gl2psFindRoot(GL2PSlist *primitives, GL2PSprimitive **root) { GLint i, j, count, best = 1000000, idx = 0; GL2PSprimitive *prim1, *prim2; GL2PSplane plane; GLint maxp; if(!gl2psListNbr(primitives)){ gl2psMsg(GL2PS_ERROR, "Cannot fint root in empty primitive list"); return 0; } *root = *(GL2PSprimitive**)gl2psListPointer(primitives, 0); if(gl2ps->options & GL2PS_BEST_ROOT){ maxp = gl2psListNbr(primitives); if(maxp > gl2ps->maxbestroot){ maxp = gl2ps->maxbestroot; } for(i = 0; i < maxp; i++){ prim1 = *(GL2PSprimitive**)gl2psListPointer(primitives, i); gl2psGetPlane(prim1, plane); count = 0; for(j = 0; j < gl2psListNbr(primitives); j++){ if(j != i){ prim2 = *(GL2PSprimitive**)gl2psListPointer(primitives, j); count += gl2psTestSplitPrimitive(prim2, plane); } if(count > best) break; } if(count < best){ best = count; idx = i; *root = prim1; if(!count) return idx; } } /* if(index) gl2psMsg(GL2PS_INFO, "GL2PS_BEST_ROOT was worth it: %d", index); */ return idx; } else{ return 0; } } static void gl2psFreeImagemap(GL2PSimagemap *list) { GL2PSimagemap *next; while(list != NULL){ next = list->next; gl2psFree(list->image->pixels); gl2psFree(list->image); gl2psFree(list); list = next; } } static void gl2psFreePrimitive(void *data) { GL2PSprimitive *q; q = *(GL2PSprimitive**)data; gl2psFree(q->verts); if(q->type == GL2PS_TEXT || q->type == GL2PS_SPECIAL){ gl2psFreeText(q->data.text); } else if(q->type == GL2PS_PIXMAP){ gl2psFreePixmap(q->data.image); } gl2psFree(q); } static void gl2psAddPrimitiveInList(GL2PSprimitive *prim, GL2PSlist *list) { GL2PSprimitive *t1, *t2; if(prim->type != GL2PS_QUADRANGLE){ gl2psListAdd(list, &prim); } else{ gl2psDivideQuad(prim, &t1, &t2); gl2psListAdd(list, &t1); gl2psListAdd(list, &t2); gl2psFreePrimitive(&prim); } } static void gl2psFreeBspTree(GL2PSbsptree **tree) { if(*tree){ if((*tree)->back) gl2psFreeBspTree(&(*tree)->back); if((*tree)->primitives){ gl2psListAction((*tree)->primitives, gl2psFreePrimitive); gl2psListDelete((*tree)->primitives); } if((*tree)->front) gl2psFreeBspTree(&(*tree)->front); gl2psFree(*tree); *tree = NULL; } } static GLboolean gl2psGreater(GLfloat f1, GLfloat f2) { if(f1 > f2) return GL_TRUE; else return GL_FALSE; } static GLboolean gl2psLess(GLfloat f1, GLfloat f2) { if(f1 < f2) return GL_TRUE; else return GL_FALSE; } static void gl2psBuildBspTree(GL2PSbsptree *tree, GL2PSlist *primitives) { GL2PSprimitive *prim, *frontprim = NULL, *backprim = NULL; GL2PSlist *frontlist, *backlist; GLint i, idx; tree->front = NULL; tree->back = NULL; tree->primitives = gl2psListCreate(1, 2, sizeof(GL2PSprimitive*)); idx = gl2psFindRoot(primitives, &prim); gl2psGetPlane(prim, tree->plane); gl2psAddPrimitiveInList(prim, tree->primitives); frontlist = gl2psListCreate(1, 2, sizeof(GL2PSprimitive*)); backlist = gl2psListCreate(1, 2, sizeof(GL2PSprimitive*)); for(i = 0; i < gl2psListNbr(primitives); i++){ if(i != idx){ prim = *(GL2PSprimitive**)gl2psListPointer(primitives,i); switch(gl2psSplitPrimitive(prim, tree->plane, &frontprim, &backprim)){ case GL2PS_COINCIDENT: gl2psAddPrimitiveInList(prim, tree->primitives); break; case GL2PS_IN_BACK_OF: gl2psAddPrimitiveInList(prim, backlist); break; case GL2PS_IN_FRONT_OF: gl2psAddPrimitiveInList(prim, frontlist); break; case GL2PS_SPANNING: gl2psAddPrimitiveInList(backprim, backlist); gl2psAddPrimitiveInList(frontprim, frontlist); gl2psFreePrimitive(&prim); break; } } } if(gl2psListNbr(tree->primitives)){ gl2psListSort(tree->primitives, gl2psTrianglesFirst); } if(gl2psListNbr(frontlist)){ gl2psListSort(frontlist, gl2psTrianglesFirst); tree->front = (GL2PSbsptree*)gl2psMalloc(sizeof(GL2PSbsptree)); gl2psBuildBspTree(tree->front, frontlist); } else{ gl2psListDelete(frontlist); } if(gl2psListNbr(backlist)){ gl2psListSort(backlist, gl2psTrianglesFirst); tree->back = (GL2PSbsptree*)gl2psMalloc(sizeof(GL2PSbsptree)); gl2psBuildBspTree(tree->back, backlist); } else{ gl2psListDelete(backlist); } gl2psListDelete(primitives); } static void gl2psTraverseBspTree(GL2PSbsptree *tree, GL2PSxyz eye, GLfloat epsilon, GLboolean (*compare)(GLfloat f1, GLfloat f2), void (*action)(void *data), int inverse) { GLfloat result; if(!tree) return; result = gl2psComparePointPlane(eye, tree->plane); if(GL_TRUE == compare(result, epsilon)){ gl2psTraverseBspTree(tree->back, eye, epsilon, compare, action, inverse); if(inverse){ gl2psListActionInverse(tree->primitives, action); } else{ gl2psListAction(tree->primitives, action); } gl2psTraverseBspTree(tree->front, eye, epsilon, compare, action, inverse); } else if(GL_TRUE == compare(-epsilon, result)){ gl2psTraverseBspTree(tree->front, eye, epsilon, compare, action, inverse); if(inverse){ gl2psListActionInverse(tree->primitives, action); } else{ gl2psListAction(tree->primitives, action); } gl2psTraverseBspTree(tree->back, eye, epsilon, compare, action, inverse); } else{ gl2psTraverseBspTree(tree->front, eye, epsilon, compare, action, inverse); gl2psTraverseBspTree(tree->back, eye, epsilon, compare, action, inverse); } } static void gl2psRescaleAndOffset(void) { GL2PSprimitive *prim; GLfloat minZ, maxZ, rangeZ, scaleZ; GLfloat factor, units, area, dZ, dZdX, dZdY, maxdZ; int i, j; if(!gl2psListNbr(gl2ps->primitives)) return; /* get z-buffer range */ prim = *(GL2PSprimitive**)gl2psListPointer(gl2ps->primitives, 0); minZ = maxZ = prim->verts[0].xyz[2]; for(i = 1; i < prim->numverts; i++){ if(prim->verts[i].xyz[2] < minZ) minZ = prim->verts[i].xyz[2]; if(prim->verts[i].xyz[2] > maxZ) maxZ = prim->verts[i].xyz[2]; } for(i = 1; i < gl2psListNbr(gl2ps->primitives); i++){ prim = *(GL2PSprimitive**)gl2psListPointer(gl2ps->primitives, i); for(j = 0; j < prim->numverts; j++){ if(prim->verts[j].xyz[2] < minZ) minZ = prim->verts[j].xyz[2]; if(prim->verts[j].xyz[2] > maxZ) maxZ = prim->verts[j].xyz[2]; } } rangeZ = (maxZ - minZ); /* rescale z-buffer coordinate in [0,GL2PS_ZSCALE], to make it of the same order of magnitude as the x and y coordinates */ scaleZ = GL2PS_ZERO(rangeZ) ? GL2PS_ZSCALE : (GL2PS_ZSCALE / rangeZ); /* avoid precision loss (we use floats!) */ if(scaleZ > 100000.F) scaleZ = 100000.F; /* apply offsets */ for(i = 0; i < gl2psListNbr(gl2ps->primitives); i++){ prim = *(GL2PSprimitive**)gl2psListPointer(gl2ps->primitives, i); for(j = 0; j < prim->numverts; j++){ prim->verts[j].xyz[2] = (prim->verts[j].xyz[2] - minZ) * scaleZ; } if((gl2ps->options & GL2PS_SIMPLE_LINE_OFFSET) && (prim->type == GL2PS_LINE)){ if(gl2ps->sort == GL2PS_SIMPLE_SORT){ prim->verts[0].xyz[2] -= GL2PS_ZOFFSET_LARGE; prim->verts[1].xyz[2] -= GL2PS_ZOFFSET_LARGE; } else{ prim->verts[0].xyz[2] -= GL2PS_ZOFFSET; prim->verts[1].xyz[2] -= GL2PS_ZOFFSET; } } else if(prim->offset && (prim->type == GL2PS_TRIANGLE)){ factor = gl2ps->offset[0]; units = gl2ps->offset[1]; area = (prim->verts[1].xyz[0] - prim->verts[0].xyz[0]) * (prim->verts[2].xyz[1] - prim->verts[1].xyz[1]) - (prim->verts[2].xyz[0] - prim->verts[1].xyz[0]) * (prim->verts[1].xyz[1] - prim->verts[0].xyz[1]); if(!GL2PS_ZERO(area)){ dZdX = ((prim->verts[2].xyz[1] - prim->verts[1].xyz[1]) * (prim->verts[1].xyz[2] - prim->verts[0].xyz[2]) - (prim->verts[1].xyz[1] - prim->verts[0].xyz[1]) * (prim->verts[2].xyz[2] - prim->verts[1].xyz[2])) / area; dZdY = ((prim->verts[1].xyz[0] - prim->verts[0].xyz[0]) * (prim->verts[2].xyz[2] - prim->verts[1].xyz[2]) - (prim->verts[2].xyz[0] - prim->verts[1].xyz[0]) * (prim->verts[1].xyz[2] - prim->verts[0].xyz[2])) / area; maxdZ = (GLfloat)sqrt(dZdX * dZdX + dZdY * dZdY); } else{ maxdZ = 0.0F; } dZ = factor * maxdZ + units; prim->verts[0].xyz[2] += dZ; prim->verts[1].xyz[2] += dZ; prim->verts[2].xyz[2] += dZ; } } } /********************************************************************* * * 2D sorting routines (for occlusion culling) * *********************************************************************/ static GLint gl2psGetPlaneFromPoints(GL2PSxyz a, GL2PSxyz b, GL2PSplane plane) { GLfloat n; plane[0] = b[1] - a[1]; plane[1] = a[0] - b[0]; n = (GLfloat)sqrt(plane[0]*plane[0] + plane[1]*plane[1]); plane[2] = 0.0F; if(!GL2PS_ZERO(n)){ plane[0] /= n; plane[1] /= n; plane[3] = -plane[0]*a[0]-plane[1]*a[1]; return 1; } else{ plane[0] = -1.0F; plane[1] = 0.0F; plane[3] = a[0]; return 0; } } static void gl2psFreeBspImageTree(GL2PSbsptree2d **tree) { if(*tree){ if((*tree)->back) gl2psFreeBspImageTree(&(*tree)->back); if((*tree)->front) gl2psFreeBspImageTree(&(*tree)->front); gl2psFree(*tree); *tree = NULL; } } static GLint gl2psCheckPoint(GL2PSxyz point, GL2PSplane plane) { GLfloat pt_dis; pt_dis = gl2psComparePointPlane(point, plane); if(pt_dis > GL2PS_EPSILON) return GL2PS_POINT_INFRONT; else if(pt_dis < -GL2PS_EPSILON) return GL2PS_POINT_BACK; else return GL2PS_POINT_COINCIDENT; } static void gl2psAddPlanesInBspTreeImage(GL2PSprimitive *prim, GL2PSbsptree2d **tree) { GLint ret = 0; GLint i; GLint offset = 0; GL2PSbsptree2d *head = NULL, *cur = NULL; if((*tree == NULL) && (prim->numverts > 2)){ /* don't cull if transparent for(i = 0; i < prim->numverts - 1; i++) if(prim->verts[i].rgba[3] < 1.0F) return; */ head = (GL2PSbsptree2d*)gl2psMalloc(sizeof(GL2PSbsptree2d)); for(i = 0; i < prim->numverts-1; i++){ if(!gl2psGetPlaneFromPoints(prim->verts[i].xyz, prim->verts[i+1].xyz, head->plane)){ if(prim->numverts-i > 3){ offset++; } else{ gl2psFree(head); return; } } else{ break; } } head->back = NULL; head->front = NULL; for(i = 2+offset; i < prim->numverts; i++){ ret = gl2psCheckPoint(prim->verts[i].xyz, head->plane); if(ret != GL2PS_POINT_COINCIDENT) break; } switch(ret){ case GL2PS_POINT_INFRONT : cur = head; for(i = 1+offset; i < prim->numverts-1; i++){ if(cur->front == NULL){ cur->front = (GL2PSbsptree2d*)gl2psMalloc(sizeof(GL2PSbsptree2d)); } if(gl2psGetPlaneFromPoints(prim->verts[i].xyz, prim->verts[i+1].xyz, cur->front->plane)){ cur = cur->front; cur->front = NULL; cur->back = NULL; } } if(cur->front == NULL){ cur->front = (GL2PSbsptree2d*)gl2psMalloc(sizeof(GL2PSbsptree2d)); } if(gl2psGetPlaneFromPoints(prim->verts[i].xyz, prim->verts[offset].xyz, cur->front->plane)){ cur->front->front = NULL; cur->front->back = NULL; } else{ gl2psFree(cur->front); cur->front = NULL; } break; case GL2PS_POINT_BACK : for(i = 0; i < 4; i++){ head->plane[i] = -head->plane[i]; } cur = head; for(i = 1+offset; i < prim->numverts-1; i++){ if(cur->front == NULL){ cur->front = (GL2PSbsptree2d*)gl2psMalloc(sizeof(GL2PSbsptree2d)); } if(gl2psGetPlaneFromPoints(prim->verts[i+1].xyz, prim->verts[i].xyz, cur->front->plane)){ cur = cur->front; cur->front = NULL; cur->back = NULL; } } if(cur->front == NULL){ cur->front = (GL2PSbsptree2d*)gl2psMalloc(sizeof(GL2PSbsptree2d)); } if(gl2psGetPlaneFromPoints(prim->verts[offset].xyz, prim->verts[i].xyz, cur->front->plane)){ cur->front->front = NULL; cur->front->back = NULL; } else{ gl2psFree(cur->front); cur->front = NULL; } break; default: gl2psFree(head); return; } (*tree) = head; } } static GLint gl2psCheckPrimitive(GL2PSprimitive *prim, GL2PSplane plane) { GLint i; GLint pos; pos = gl2psCheckPoint(prim->verts[0].xyz, plane); for(i = 1; i < prim->numverts; i++){ pos |= gl2psCheckPoint(prim->verts[i].xyz, plane); if(pos == (GL2PS_POINT_INFRONT | GL2PS_POINT_BACK)) return GL2PS_SPANNING; } if(pos & GL2PS_POINT_INFRONT) return GL2PS_IN_FRONT_OF; else if(pos & GL2PS_POINT_BACK) return GL2PS_IN_BACK_OF; else return GL2PS_COINCIDENT; } static GL2PSprimitive *gl2psCreateSplitPrimitive2D(GL2PSprimitive *parent, GLshort numverts, GL2PSvertex *vertx) { GLint i; GL2PSprimitive *child = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive)); if(parent->type == GL2PS_IMAGEMAP){ child->type = GL2PS_IMAGEMAP; child->data.image = parent->data.image; } else { switch(numverts){ case 1 : child->type = GL2PS_POINT; break; case 2 : child->type = GL2PS_LINE; break; case 3 : child->type = GL2PS_TRIANGLE; break; case 4 : child->type = GL2PS_QUADRANGLE; break; default: child->type = GL2PS_NO_TYPE; break; /* FIXME */ } } child->boundary = 0; /* FIXME: not done! */ child->culled = parent->culled; child->offset = parent->offset; child->pattern = parent->pattern; child->factor = parent->factor; child->width = parent->width; child->numverts = numverts; child->verts = (GL2PSvertex*)gl2psMalloc(numverts * sizeof(GL2PSvertex)); for(i = 0; i < numverts; i++){ child->verts[i] = vertx[i]; } return child; } static void gl2psSplitPrimitive2D(GL2PSprimitive *prim, GL2PSplane plane, GL2PSprimitive **front, GL2PSprimitive **back) { /* cur will hold the position of the current vertex prev will hold the position of the previous vertex prev0 will hold the position of the vertex number 0 v1 and v2 represent the current and previous vertices, respectively flag is set if the current vertex should be checked against the plane */ GLint cur = -1, prev = -1, i, v1 = 0, v2 = 0, flag = 1, prev0 = -1; /* list of vertices that will go in front and back primitive */ GL2PSvertex *front_list = NULL, *back_list = NULL; /* number of vertices in front and back list */ GLshort front_count = 0, back_count = 0; for(i = 0; i <= prim->numverts; i++){ v1 = i; if(v1 == prim->numverts){ if(prim->numverts < 3) break; v1 = 0; v2 = prim->numverts - 1; cur = prev0; } else if(flag){ cur = gl2psCheckPoint(prim->verts[v1].xyz, plane); if(i == 0){ prev0 = cur; } } if(((prev == -1) || (prev == cur) || (prev == 0) || (cur == 0)) && (i < prim->numverts)){ if(cur == GL2PS_POINT_INFRONT){ front_count++; front_list = (GL2PSvertex*)gl2psRealloc(front_list, sizeof(GL2PSvertex)*front_count); front_list[front_count-1] = prim->verts[v1]; } else if(cur == GL2PS_POINT_BACK){ back_count++; back_list = (GL2PSvertex*)gl2psRealloc(back_list, sizeof(GL2PSvertex)*back_count); back_list[back_count-1] = prim->verts[v1]; } else{ front_count++; front_list = (GL2PSvertex*)gl2psRealloc(front_list, sizeof(GL2PSvertex)*front_count); front_list[front_count-1] = prim->verts[v1]; back_count++; back_list = (GL2PSvertex*)gl2psRealloc(back_list, sizeof(GL2PSvertex)*back_count); back_list[back_count-1] = prim->verts[v1]; } flag = 1; } else if((prev != cur) && (cur != 0) && (prev != 0)){ if(v1 != 0){ v2 = v1-1; i--; } front_count++; front_list = (GL2PSvertex*)gl2psRealloc(front_list, sizeof(GL2PSvertex)*front_count); gl2psCutEdge(&prim->verts[v2], &prim->verts[v1], plane, &front_list[front_count-1]); back_count++; back_list = (GL2PSvertex*)gl2psRealloc(back_list, sizeof(GL2PSvertex)*back_count); back_list[back_count-1] = front_list[front_count-1]; flag = 0; } prev = cur; } *front = gl2psCreateSplitPrimitive2D(prim, front_count, front_list); *back = gl2psCreateSplitPrimitive2D(prim, back_count, back_list); gl2psFree(front_list); gl2psFree(back_list); } static GLint gl2psAddInBspImageTree(GL2PSprimitive *prim, GL2PSbsptree2d **tree) { GLint ret = 0; GL2PSprimitive *frontprim = NULL, *backprim = NULL; /* FIXME: until we consider the actual extent of text strings and pixmaps, never cull them. Otherwise the whole string/pixmap gets culled as soon as the reference point is hidden */ if(prim->type == GL2PS_PIXMAP || prim->type == GL2PS_TEXT || prim->type == GL2PS_SPECIAL){ return 1; } if(*tree == NULL){ if((prim->type != GL2PS_IMAGEMAP) && (GL_FALSE == gl2ps->zerosurfacearea)){ gl2psAddPlanesInBspTreeImage(gl2ps->primitivetoadd, tree); } return 1; } else{ switch(gl2psCheckPrimitive(prim, (*tree)->plane)){ case GL2PS_IN_BACK_OF: return gl2psAddInBspImageTree(prim, &(*tree)->back); case GL2PS_IN_FRONT_OF: if((*tree)->front != NULL) return gl2psAddInBspImageTree(prim, &(*tree)->front); else return 0; case GL2PS_SPANNING: gl2psSplitPrimitive2D(prim, (*tree)->plane, &frontprim, &backprim); ret = gl2psAddInBspImageTree(backprim, &(*tree)->back); if((*tree)->front != NULL){ if(gl2psAddInBspImageTree(frontprim, &(*tree)->front)){ ret = 1; } } gl2psFree(frontprim->verts); gl2psFree(frontprim); gl2psFree(backprim->verts); gl2psFree(backprim); return ret; case GL2PS_COINCIDENT: if((*tree)->back != NULL){ gl2ps->zerosurfacearea = GL_TRUE; ret = gl2psAddInBspImageTree(prim, &(*tree)->back); gl2ps->zerosurfacearea = GL_FALSE; if(ret) return ret; } if((*tree)->front != NULL){ gl2ps->zerosurfacearea = GL_TRUE; ret = gl2psAddInBspImageTree(prim, &(*tree)->front); gl2ps->zerosurfacearea = GL_FALSE; if(ret) return ret; } if(prim->type == GL2PS_LINE) return 1; else return 0; } } return 0; } static void gl2psAddInImageTree(void *data) { GL2PSprimitive *prim = *(GL2PSprimitive **)data; gl2ps->primitivetoadd = prim; if(prim->type == GL2PS_IMAGEMAP && prim->data.image->format == GL2PS_IMAGEMAP_VISIBLE){ prim->culled = 1; } else if(!gl2psAddInBspImageTree(prim, &gl2ps->imagetree)){ prim->culled = 1; } else if(prim->type == GL2PS_IMAGEMAP){ prim->data.image->format = GL2PS_IMAGEMAP_VISIBLE; } } /* Boundary construction */ static void gl2psAddBoundaryInList(GL2PSprimitive *prim, GL2PSlist *list) { GL2PSprimitive *b; GLshort i; GL2PSxyz c; c[0] = c[1] = c[2] = 0.0F; for(i = 0; i < prim->numverts; i++){ c[0] += prim->verts[i].xyz[0]; c[1] += prim->verts[i].xyz[1]; } c[0] /= prim->numverts; c[1] /= prim->numverts; for(i = 0; i < prim->numverts; i++){ if(prim->boundary & (GLint)pow(2., i)){ b = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive)); b->type = GL2PS_LINE; b->offset = prim->offset; b->pattern = prim->pattern; b->factor = prim->factor; b->culled = prim->culled; b->width = prim->width; b->boundary = 0; b->numverts = 2; b->verts = (GL2PSvertex*)gl2psMalloc(2 * sizeof(GL2PSvertex)); #if 0 /* FIXME: need to work on boundary offset... */ v[0] = c[0] - prim->verts[i].xyz[0]; v[1] = c[1] - prim->verts[i].xyz[1]; v[2] = 0.0F; norm = gl2psNorm(v); v[0] /= norm; v[1] /= norm; b->verts[0].xyz[0] = prim->verts[i].xyz[0] +0.1*v[0]; b->verts[0].xyz[1] = prim->verts[i].xyz[1] +0.1*v[1]; b->verts[0].xyz[2] = prim->verts[i].xyz[2]; v[0] = c[0] - prim->verts[gl2psGetIndex(i, prim->numverts)].xyz[0]; v[1] = c[1] - prim->verts[gl2psGetIndex(i, prim->numverts)].xyz[1]; norm = gl2psNorm(v); v[0] /= norm; v[1] /= norm; b->verts[1].xyz[0] = prim->verts[gl2psGetIndex(i, prim->numverts)].xyz[0] +0.1*v[0]; b->verts[1].xyz[1] = prim->verts[gl2psGetIndex(i, prim->numverts)].xyz[1] +0.1*v[1]; b->verts[1].xyz[2] = prim->verts[gl2psGetIndex(i, prim->numverts)].xyz[2]; #else b->verts[0].xyz[0] = prim->verts[i].xyz[0]; b->verts[0].xyz[1] = prim->verts[i].xyz[1]; b->verts[0].xyz[2] = prim->verts[i].xyz[2]; b->verts[1].xyz[0] = prim->verts[gl2psGetIndex(i, prim->numverts)].xyz[0]; b->verts[1].xyz[1] = prim->verts[gl2psGetIndex(i, prim->numverts)].xyz[1]; b->verts[1].xyz[2] = prim->verts[gl2psGetIndex(i, prim->numverts)].xyz[2]; #endif b->verts[0].rgba[0] = 0.0F; b->verts[0].rgba[1] = 0.0F; b->verts[0].rgba[2] = 0.0F; b->verts[0].rgba[3] = 0.0F; b->verts[1].rgba[0] = 0.0F; b->verts[1].rgba[1] = 0.0F; b->verts[1].rgba[2] = 0.0F; b->verts[1].rgba[3] = 0.0F; gl2psListAdd(list, &b); } } } static void gl2psBuildPolygonBoundary(GL2PSbsptree *tree) { GLint i; GL2PSprimitive *prim; if(!tree) return; gl2psBuildPolygonBoundary(tree->back); for(i = 0; i < gl2psListNbr(tree->primitives); i++){ prim = *(GL2PSprimitive**)gl2psListPointer(tree->primitives, i); if(prim->boundary) gl2psAddBoundaryInList(prim, tree->primitives); } gl2psBuildPolygonBoundary(tree->front); } /********************************************************************* * * Feedback buffer parser * *********************************************************************/ static void gl2psAddPolyPrimitive(GLshort type, GLshort numverts, GL2PSvertex *verts, GLint offset, GLushort pattern, GLint factor, GLfloat width, char boundary) { GL2PSprimitive *prim; prim = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive)); prim->type = type; prim->numverts = numverts; prim->verts = (GL2PSvertex*)gl2psMalloc(numverts * sizeof(GL2PSvertex)); memcpy(prim->verts, verts, numverts * sizeof(GL2PSvertex)); prim->boundary = boundary; prim->offset = offset; prim->pattern = pattern; prim->factor = factor; prim->width = width; prim->culled = 0; /* FIXME: here we should have an option to split stretched tris/quads to enhance SIMPLE_SORT */ gl2psListAdd(gl2ps->primitives, &prim); } static GLint gl2psGetVertex(GL2PSvertex *v, GLfloat *p) { GLint i; v->xyz[0] = p[0]; v->xyz[1] = p[1]; v->xyz[2] = p[2]; if(gl2ps->colormode == GL_COLOR_INDEX && gl2ps->colorsize > 0){ i = (GLint)(p[3] + 0.5); v->rgba[0] = gl2ps->colormap[i][0]; v->rgba[1] = gl2ps->colormap[i][1]; v->rgba[2] = gl2ps->colormap[i][2]; v->rgba[3] = gl2ps->colormap[i][3]; return 4; } else{ v->rgba[0] = p[3]; v->rgba[1] = p[4]; v->rgba[2] = p[5]; v->rgba[3] = p[6]; return 7; } } static void gl2psParseFeedbackBuffer(GLint used) { char flag; GLushort pattern = 0; GLboolean boundary; GLint i, sizeoffloat, count, v, vtot, offset = 0, factor = 0, auxindex = 0; GLfloat lwidth = 1.0F, psize = 1.0F; GLfloat *current; GL2PSvertex vertices[3]; GL2PSprimitive *prim; GL2PSimagemap *node; current = gl2ps->feedback; boundary = gl2ps->boundary = GL_FALSE; while(used > 0){ if(GL_TRUE == boundary) gl2ps->boundary = GL_TRUE; switch((GLint)*current){ case GL_POINT_TOKEN : current ++; used --; i = gl2psGetVertex(&vertices[0], current); current += i; used -= i; gl2psAddPolyPrimitive(GL2PS_POINT, 1, vertices, 0, pattern, factor, psize, 0); break; case GL_LINE_TOKEN : case GL_LINE_RESET_TOKEN : current ++; used --; i = gl2psGetVertex(&vertices[0], current); current += i; used -= i; i = gl2psGetVertex(&vertices[1], current); current += i; used -= i; gl2psAddPolyPrimitive(GL2PS_LINE, 2, vertices, 0, pattern, factor, lwidth, 0); break; case GL_POLYGON_TOKEN : count = (GLint)current[1]; current += 2; used -= 2; v = vtot = 0; while(count > 0 && used > 0){ i = gl2psGetVertex(&vertices[v], current); gl2psAdaptVertexForBlending(&vertices[v]); current += i; used -= i; count --; vtot++; if(v == 2){ if(GL_TRUE == boundary){ if(!count && vtot == 2) flag = 1|2|4; else if(!count) flag = 2|4; else if(vtot == 2) flag = 1|2; else flag = 2; } else flag = 0; gl2psAddPolyPrimitive(GL2PS_TRIANGLE, 3, vertices, offset, pattern, factor, 1, flag); vertices[1] = vertices[2]; } else v ++; } break; case GL_BITMAP_TOKEN : case GL_DRAW_PIXEL_TOKEN : case GL_COPY_PIXEL_TOKEN : current ++; used --; i = gl2psGetVertex(&vertices[0], current); current += i; used -= i; break; case GL_PASS_THROUGH_TOKEN : switch((GLint)current[1]){ case GL2PS_BEGIN_OFFSET_TOKEN : offset = 1; break; case GL2PS_END_OFFSET_TOKEN : offset = 0; break; case GL2PS_BEGIN_BOUNDARY_TOKEN : boundary = GL_TRUE; break; case GL2PS_END_BOUNDARY_TOKEN : boundary = GL_FALSE; break; case GL2PS_END_STIPPLE_TOKEN : pattern = factor = 0; break; case GL2PS_BEGIN_BLEND_TOKEN : gl2ps->blending = GL_TRUE; break; case GL2PS_END_BLEND_TOKEN : gl2ps->blending = GL_FALSE; break; case GL2PS_BEGIN_STIPPLE_TOKEN : current += 2; used -= 2; pattern = (GLushort)current[1]; current += 2; used -= 2; factor = (GLint)current[1]; break; case GL2PS_SRC_BLEND_TOKEN : current += 2; used -= 2; gl2ps->blendfunc[0] = (GLint)current[1]; break; case GL2PS_DST_BLEND_TOKEN : current += 2; used -= 2; gl2ps->blendfunc[1] = (GLint)current[1]; break; case GL2PS_POINT_SIZE_TOKEN : current += 2; used -= 2; psize = current[1]; break; case GL2PS_LINE_WIDTH_TOKEN : current += 2; used -= 2; lwidth = current[1]; break; case GL2PS_IMAGEMAP_TOKEN : prim = (GL2PSprimitive *)gl2psMalloc(sizeof(GL2PSprimitive)); prim->type = GL2PS_IMAGEMAP; prim->boundary = 0; prim->numverts = 4; prim->verts = (GL2PSvertex *)gl2psMalloc(4 * sizeof(GL2PSvertex)); prim->culled = 0; prim->offset = 0; prim->pattern = 0; prim->factor = 0; prim->width = 1; node = (GL2PSimagemap*)gl2psMalloc(sizeof(GL2PSimagemap)); node->image = (GL2PSimage*)gl2psMalloc(sizeof(GL2PSimage)); node->image->type = 0; node->image->format = 0; node->image->zoom_x = 1.0F; node->image->zoom_y = 1.0F; node->next = NULL; if(gl2ps->imagemap_head == NULL) gl2ps->imagemap_head = node; else gl2ps->imagemap_tail->next = node; gl2ps->imagemap_tail = node; prim->data.image = node->image; current += 2; used -= 2; i = gl2psGetVertex(&prim->verts[0], ¤t[1]); current += i; used -= i; node->image->width = (GLint)current[2]; current += 2; used -= 2; node->image->height = (GLint)current[2]; prim->verts[0].xyz[0] = prim->verts[0].xyz[0] - (int)(node->image->width / 2) + 0.5F; prim->verts[0].xyz[1] = prim->verts[0].xyz[1] - (int)(node->image->height / 2) + 0.5F; for(i = 1; i < 4; i++){ for(v = 0; v < 3; v++){ prim->verts[i].xyz[v] = prim->verts[0].xyz[v]; prim->verts[i].rgba[v] = prim->verts[0].rgba[v]; } prim->verts[i].rgba[v] = prim->verts[0].rgba[v]; } prim->verts[1].xyz[0] = prim->verts[1].xyz[0] + node->image->width; prim->verts[2].xyz[0] = prim->verts[1].xyz[0]; prim->verts[2].xyz[1] = prim->verts[2].xyz[1] + node->image->height; prim->verts[3].xyz[1] = prim->verts[2].xyz[1]; sizeoffloat = sizeof(GLfloat); v = 2 * sizeoffloat; vtot = node->image->height + node->image->height * ((node->image->width - 1) / 8); node->image->pixels = (GLfloat*)gl2psMalloc(v + vtot); node->image->pixels[0] = prim->verts[0].xyz[0]; node->image->pixels[1] = prim->verts[0].xyz[1]; for(i = 0; i < vtot; i += sizeoffloat){ current += 2; used -= 2; if((vtot - i) >= 4) memcpy(&(((char*)(node->image->pixels))[i + v]), &(current[2]), sizeoffloat); else memcpy(&(((char*)(node->image->pixels))[i + v]), &(current[2]), vtot - i); } current++; used--; gl2psListAdd(gl2ps->primitives, &prim); break; case GL2PS_DRAW_PIXELS_TOKEN : case GL2PS_TEXT_TOKEN : if(auxindex < gl2psListNbr(gl2ps->auxprimitives)) gl2psListAdd(gl2ps->primitives, gl2psListPointer(gl2ps->auxprimitives, auxindex++)); else gl2psMsg(GL2PS_ERROR, "Wrong number of auxiliary tokens in buffer"); break; } current += 2; used -= 2; break; default : gl2psMsg(GL2PS_WARNING, "Unknown token in buffer"); current ++; used --; break; } } gl2psListReset(gl2ps->auxprimitives); } /********************************************************************* * * PostScript routines * *********************************************************************/ static void gl2psWriteByte(unsigned char byte) { unsigned char h = byte / 16; unsigned char l = byte % 16; gl2psPrintf("%x%x", h, l); } static void gl2psPrintPostScriptPixmap(GLfloat x, GLfloat y, GL2PSimage *im) { GLuint nbhex, nbyte, nrgb, nbits; GLuint row, col, ibyte, icase; GLfloat dr, dg, db, fgrey; unsigned char red = 0, green = 0, blue = 0, b, grey; GLuint width = (GLuint)im->width; GLuint height = (GLuint)im->height; /* FIXME: should we define an option for these? Or just keep the 8-bit per component case? */ int greyscale = 0; /* set to 1 to output greyscale image */ int nbit = 8; /* number of bits per color compoment (2, 4 or 8) */ if((width <= 0) || (height <= 0)) return; gl2psPrintf("gsave\n"); gl2psPrintf("%.2f %.2f translate\n", x, y); gl2psPrintf("%.2f %.2f scale\n", width * im->zoom_x, height * im->zoom_y); if(greyscale){ /* greyscale */ gl2psPrintf("/picstr %d string def\n", width); gl2psPrintf("%d %d %d\n", width, height, 8); gl2psPrintf("[ %d 0 0 -%d 0 %d ]\n", width, height, height); gl2psPrintf("{ currentfile picstr readhexstring pop }\n"); gl2psPrintf("image\n"); for(row = 0; row < height; row++){ for(col = 0; col < width; col++){ gl2psGetRGB(im, col, row, &dr, &dg, &db); fgrey = (0.30F * dr + 0.59F * dg + 0.11F * db); grey = (unsigned char)(255. * fgrey); gl2psWriteByte(grey); } gl2psPrintf("\n"); } nbhex = width * height * 2; gl2psPrintf("%%%% nbhex digit :%d\n", nbhex); } else if(nbit == 2){ /* color, 2 bits for r and g and b; rgbs following each other */ nrgb = width * 3; nbits = nrgb * nbit; nbyte = nbits / 8; if((nbyte * 8) != nbits) nbyte++; gl2psPrintf("/rgbstr %d string def\n", nbyte); gl2psPrintf("%d %d %d\n", width, height, nbit); gl2psPrintf("[ %d 0 0 -%d 0 %d ]\n", width, height, height); gl2psPrintf("{ currentfile rgbstr readhexstring pop }\n"); gl2psPrintf("false 3\n"); gl2psPrintf("colorimage\n"); for(row = 0; row < height; row++){ icase = 1; col = 0; b = 0; for(ibyte = 0; ibyte < nbyte; ibyte++){ if(icase == 1) { if(col < width) { gl2psGetRGB(im, col, row, &dr, &dg, &db); } else { dr = dg = db = 0; } col++; red = (unsigned char)(3. * dr); green = (unsigned char)(3. * dg); blue = (unsigned char)(3. * db); b = red; b = (b<<2) + green; b = (b<<2) + blue; if(col < width) { gl2psGetRGB(im, col, row, &dr, &dg, &db); } else { dr = dg = db = 0; } col++; red = (unsigned char)(3. * dr); green = (unsigned char)(3. * dg); blue = (unsigned char)(3. * db); b = (b<<2) + red; gl2psWriteByte(b); b = 0; icase++; } else if(icase == 2) { b = green; b = (b<<2) + blue; if(col < width) { gl2psGetRGB(im, col, row, &dr, &dg, &db); } else { dr = dg = db = 0; } col++; red = (unsigned char)(3. * dr); green = (unsigned char)(3. * dg); blue = (unsigned char)(3. * db); b = (b<<2) + red; b = (b<<2) + green; gl2psWriteByte(b); b = 0; icase++; } else if(icase == 3) { b = blue; if(col < width) { gl2psGetRGB(im, col, row, &dr, &dg, &db); } else { dr = dg = db = 0; } col++; red = (unsigned char)(3. * dr); green = (unsigned char)(3. * dg); blue = (unsigned char)(3. * db); b = (b<<2) + red; b = (b<<2) + green; b = (b<<2) + blue; gl2psWriteByte(b); b = 0; icase = 1; } } gl2psPrintf("\n"); } } else if(nbit == 4){ /* color, 4 bits for r and g and b; rgbs following each other */ nrgb = width * 3; nbits = nrgb * nbit; nbyte = nbits / 8; if((nbyte * 8) != nbits) nbyte++; gl2psPrintf("/rgbstr %d string def\n", nbyte); gl2psPrintf("%d %d %d\n", width, height, nbit); gl2psPrintf("[ %d 0 0 -%d 0 %d ]\n", width, height, height); gl2psPrintf("{ currentfile rgbstr readhexstring pop }\n"); gl2psPrintf("false 3\n"); gl2psPrintf("colorimage\n"); for(row = 0; row < height; row++){ col = 0; icase = 1; for(ibyte = 0; ibyte < nbyte; ibyte++){ if(icase == 1) { if(col < width) { gl2psGetRGB(im, col, row, &dr, &dg, &db); } else { dr = dg = db = 0; } col++; red = (unsigned char)(15. * dr); green = (unsigned char)(15. * dg); gl2psPrintf("%x%x", red, green); icase++; } else if(icase == 2) { blue = (unsigned char)(15. * db); if(col < width) { gl2psGetRGB(im, col, row, &dr, &dg, &db); } else { dr = dg = db = 0; } col++; red = (unsigned char)(15. * dr); gl2psPrintf("%x%x", blue, red); icase++; } else if(icase == 3) { green = (unsigned char)(15. * dg); blue = (unsigned char)(15. * db); gl2psPrintf("%x%x", green, blue); icase = 1; } } gl2psPrintf("\n"); } } else{ /* 8 bit for r and g and b */ nbyte = width * 3; gl2psPrintf("/rgbstr %d string def\n", nbyte); gl2psPrintf("%d %d %d\n", width, height, 8); gl2psPrintf("[ %d 0 0 -%d 0 %d ]\n", width, height, height); gl2psPrintf("{ currentfile rgbstr readhexstring pop }\n"); gl2psPrintf("false 3\n"); gl2psPrintf("colorimage\n"); for(row = 0; row < height; row++){ for(col = 0; col < width; col++){ gl2psGetRGB(im, col, row, &dr, &dg, &db); red = (unsigned char)(255. * dr); gl2psWriteByte(red); green = (unsigned char)(255. * dg); gl2psWriteByte(green); blue = (unsigned char)(255. * db); gl2psWriteByte(blue); } gl2psPrintf("\n"); } } gl2psPrintf("grestore\n"); } static void gl2psPrintPostScriptImagemap(GLfloat x, GLfloat y, GLsizei width, GLsizei height, const unsigned char *imagemap){ int i, size; if((width <= 0) || (height <= 0)) return; size = height + height * (width - 1) / 8; gl2psPrintf("gsave\n"); gl2psPrintf("%.2f %.2f translate\n", x, y); gl2psPrintf("%d %d scale\n%d %d\ntrue\n", width, height,width, height); gl2psPrintf("[ %d 0 0 -%d 0 %d ] {<", width, height); for(i = 0; i < size; i++){ gl2psWriteByte(*imagemap); imagemap++; } gl2psPrintf(">} imagemask\ngrestore\n"); } static void gl2psPrintPostScriptHeader(void) { time_t now; /* Since compression is not part of the PostScript standard, compressed PostScript files are just gzipped PostScript files ("ps.gz" or "eps.gz") */ gl2psPrintGzipHeader(); time(&now); if(gl2ps->format == GL2PS_PS){ gl2psPrintf("%%!PS-Adobe-3.0\n"); } else{ gl2psPrintf("%%!PS-Adobe-3.0 EPSF-3.0\n"); } gl2psPrintf("%%%%Title: %s\n" "%%%%Creator: GL2PS %d.%d.%d%s, %s\n" "%%%%For: %s\n" "%%%%CreationDate: %s" "%%%%LanguageLevel: 3\n" "%%%%DocumentData: Clean7Bit\n" "%%%%Pages: 1\n", gl2ps->title, GL2PS_MAJOR_VERSION, GL2PS_MINOR_VERSION, GL2PS_PATCH_VERSION, GL2PS_EXTRA_VERSION, GL2PS_COPYRIGHT, gl2ps->producer, ctime(&now)); if(gl2ps->format == GL2PS_PS){ gl2psPrintf("%%%%Orientation: %s\n" "%%%%DocumentMedia: Default %d %d 0 () ()\n", (gl2ps->options & GL2PS_LANDSCAPE) ? "Landscape" : "Portrait", (gl2ps->options & GL2PS_LANDSCAPE) ? (int)gl2ps->viewport[3] : (int)gl2ps->viewport[2], (gl2ps->options & GL2PS_LANDSCAPE) ? (int)gl2ps->viewport[2] : (int)gl2ps->viewport[3]); } gl2psPrintf("%%%%BoundingBox: %d %d %d %d\n" "%%%%EndComments\n", (gl2ps->options & GL2PS_LANDSCAPE) ? (int)gl2ps->viewport[1] : (int)gl2ps->viewport[0], (gl2ps->options & GL2PS_LANDSCAPE) ? (int)gl2ps->viewport[0] : (int)gl2ps->viewport[1], (gl2ps->options & GL2PS_LANDSCAPE) ? (int)gl2ps->viewport[3] : (int)gl2ps->viewport[2], (gl2ps->options & GL2PS_LANDSCAPE) ? (int)gl2ps->viewport[2] : (int)gl2ps->viewport[3]); /* RGB color: r g b C (replace C by G in output to change from rgb to gray) Grayscale: r g b G Font choose: size fontname FC Text string: (string) x y size fontname S?? Rotated text string: (string) angle x y size fontname S??R Point primitive: x y size P Line width: width W Line start: x y LS Line joining last point: x y L Line end: x y LE Flat-shaded triangle: x3 y3 x2 y2 x1 y1 T Smooth-shaded triangle: x3 y3 r3 g3 b3 x2 y2 r2 g2 b2 x1 y1 r1 g1 b1 ST */ gl2psPrintf("%%%%BeginProlog\n" "/gl2psdict 64 dict def gl2psdict begin\n" "0 setlinecap 0 setlinejoin\n" "/tryPS3shading %s def %% set to false to force subdivision\n" "/rThreshold %g def %% red component subdivision threshold\n" "/gThreshold %g def %% green component subdivision threshold\n" "/bThreshold %g def %% blue component subdivision threshold\n", (gl2ps->options & GL2PS_NO_PS3_SHADING) ? "false" : "true", gl2ps->threshold[0], gl2ps->threshold[1], gl2ps->threshold[2]); gl2psPrintf("/BD { bind def } bind def\n" "/C { setrgbcolor } BD\n" "/G { 0.082 mul exch 0.6094 mul add exch 0.3086 mul add neg 1.0 add setgray } BD\n" "/W { setlinewidth } BD\n"); gl2psPrintf("/FC { findfont exch /SH exch def SH scalefont setfont } BD\n" "/SW { dup stringwidth pop } BD\n" "/S { FC moveto show } BD\n" "/SBC{ FC moveto SW -2 div 0 rmoveto show } BD\n" "/SBR{ FC moveto SW neg 0 rmoveto show } BD\n" "/SCL{ FC moveto 0 SH -2 div rmoveto show } BD\n" "/SCC{ FC moveto SW -2 div SH -2 div rmoveto show } BD\n" "/SCR{ FC moveto SW neg SH -2 div rmoveto show } BD\n" "/STL{ FC moveto 0 SH neg rmoveto show } BD\n" "/STC{ FC moveto SW -2 div SH neg rmoveto show } BD\n" "/STR{ FC moveto SW neg SH neg rmoveto show } BD\n"); /* rotated text routines: same nameanem with R appended */ gl2psPrintf("/FCT { FC translate 0 0 } BD\n" "/SR { gsave FCT moveto rotate show grestore } BD\n" "/SBCR{ gsave FCT moveto rotate SW -2 div 0 rmoveto show grestore } BD\n" "/SBRR{ gsave FCT moveto rotate SW neg 0 rmoveto show grestore } BD\n" "/SCLR{ gsave FCT moveto rotate 0 SH -2 div rmoveto show grestore} BD\n"); gl2psPrintf("/SCCR{ gsave FCT moveto rotate SW -2 div SH -2 div rmoveto show grestore} BD\n" "/SCRR{ gsave FCT moveto rotate SW neg SH -2 div rmoveto show grestore} BD\n" "/STLR{ gsave FCT moveto rotate 0 SH neg rmoveto show grestore } BD\n" "/STCR{ gsave FCT moveto rotate SW -2 div SH neg rmoveto show grestore } BD\n" "/STRR{ gsave FCT moveto rotate SW neg SH neg rmoveto show grestore } BD\n"); gl2psPrintf("/P { newpath 0.0 360.0 arc closepath fill } BD\n" "/LS { newpath moveto } BD\n" "/L { lineto } BD\n" "/LE { lineto stroke } BD\n" "/T { newpath moveto lineto lineto closepath fill } BD\n"); /* Smooth-shaded triangle with PostScript level 3 shfill operator: x3 y3 r3 g3 b3 x2 y2 r2 g2 b2 x1 y1 r1 g1 b1 STshfill */ gl2psPrintf("/STshfill {\n" " /b1 exch def /g1 exch def /r1 exch def /y1 exch def /x1 exch def\n" " /b2 exch def /g2 exch def /r2 exch def /y2 exch def /x2 exch def\n" " /b3 exch def /g3 exch def /r3 exch def /y3 exch def /x3 exch def\n" " gsave << /ShadingType 4 /ColorSpace [/DeviceRGB]\n" " /DataSource [ 0 x1 y1 r1 g1 b1 0 x2 y2 r2 g2 b2 0 x3 y3 r3 g3 b3 ] >>\n" " shfill grestore } BD\n"); /* Flat-shaded triangle with middle color: x3 y3 r3 g3 b3 x2 y2 r2 g2 b2 x1 y1 r1 g1 b1 Tm */ gl2psPrintf(/* stack : x3 y3 r3 g3 b3 x2 y2 r2 g2 b2 x1 y1 r1 g1 b1 */ "/Tm { 3 -1 roll 8 -1 roll 13 -1 roll add add 3 div\n" /* r = (r1+r2+r3)/3 */ /* stack : x3 y3 g3 b3 x2 y2 g2 b2 x1 y1 g1 b1 r */ " 3 -1 roll 7 -1 roll 11 -1 roll add add 3 div\n" /* g = (g1+g2+g3)/3 */ /* stack : x3 y3 b3 x2 y2 b2 x1 y1 b1 r g b */ " 3 -1 roll 6 -1 roll 9 -1 roll add add 3 div" /* b = (b1+b2+b3)/3 */ /* stack : x3 y3 x2 y2 x1 y1 r g b */ " C T } BD\n"); /* Split triangle in four sub-triangles (at sides middle points) and call the STnoshfill procedure on each, interpolating the colors in RGB space: x3 y3 r3 g3 b3 x2 y2 r2 g2 b2 x1 y1 r1 g1 b1 STsplit (in procedure comments key: (Vi) = xi yi ri gi bi) */ gl2psPrintf("/STsplit {\n" " 4 index 15 index add 0.5 mul\n" /* x13 = (x1+x3)/2 */ " 4 index 15 index add 0.5 mul\n" /* y13 = (y1+y3)/2 */ " 4 index 15 index add 0.5 mul\n" /* r13 = (r1+r3)/2 */ " 4 index 15 index add 0.5 mul\n" /* g13 = (g1+g3)/2 */ " 4 index 15 index add 0.5 mul\n" /* b13 = (b1+b3)/2 */ " 5 copy 5 copy 25 15 roll\n"); /* at his point, stack = (V3) (V13) (V13) (V13) (V2) (V1) */ gl2psPrintf(" 9 index 30 index add 0.5 mul\n" /* x23 = (x2+x3)/2 */ " 9 index 30 index add 0.5 mul\n" /* y23 = (y2+y3)/2 */ " 9 index 30 index add 0.5 mul\n" /* r23 = (r2+r3)/2 */ " 9 index 30 index add 0.5 mul\n" /* g23 = (g2+g3)/2 */ " 9 index 30 index add 0.5 mul\n" /* b23 = (b2+b3)/2 */ " 5 copy 5 copy 35 5 roll 25 5 roll 15 5 roll\n"); /* stack = (V3) (V13) (V23) (V13) (V23) (V13) (V23) (V2) (V1) */ gl2psPrintf(" 4 index 10 index add 0.5 mul\n" /* x12 = (x1+x2)/2 */ " 4 index 10 index add 0.5 mul\n" /* y12 = (y1+y2)/2 */ " 4 index 10 index add 0.5 mul\n" /* r12 = (r1+r2)/2 */ " 4 index 10 index add 0.5 mul\n" /* g12 = (g1+g2)/2 */ " 4 index 10 index add 0.5 mul\n" /* b12 = (b1+b2)/2 */ " 5 copy 5 copy 40 5 roll 25 5 roll 15 5 roll 25 5 roll\n"); /* stack = (V3) (V13) (V23) (V13) (V12) (V23) (V13) (V1) (V12) (V23) (V12) (V2) */ gl2psPrintf(" STnoshfill STnoshfill STnoshfill STnoshfill } BD\n"); /* Gouraud shaded triangle using recursive subdivision until the difference between corner colors does not exceed the thresholds: x3 y3 r3 g3 b3 x2 y2 r2 g2 b2 x1 y1 r1 g1 b1 STnoshfill */ gl2psPrintf("/STnoshfill {\n" " 2 index 8 index sub abs rThreshold gt\n" /* |r1-r2|>rth */ " { STsplit }\n" " { 1 index 7 index sub abs gThreshold gt\n" /* |g1-g2|>gth */ " { STsplit }\n" " { dup 6 index sub abs bThreshold gt\n" /* |b1-b2|>bth */ " { STsplit }\n" " { 2 index 13 index sub abs rThreshold gt\n" /* |r1-r3|>rht */ " { STsplit }\n" " { 1 index 12 index sub abs gThreshold gt\n" /* |g1-g3|>gth */ " { STsplit }\n" " { dup 11 index sub abs bThreshold gt\n" /* |b1-b3|>bth */ " { STsplit }\n" " { 7 index 13 index sub abs rThreshold gt\n"); /* |r2-r3|>rht */ gl2psPrintf(" { STsplit }\n" " { 6 index 12 index sub abs gThreshold gt\n" /* |g2-g3|>gth */ " { STsplit }\n" " { 5 index 11 index sub abs bThreshold gt\n" /* |b2-b3|>bth */ " { STsplit }\n" " { Tm }\n" /* all colors sufficiently similar */ " ifelse }\n" " ifelse }\n" " ifelse }\n" " ifelse }\n" " ifelse }\n" " ifelse }\n" " ifelse }\n" " ifelse }\n" " ifelse } BD\n"); gl2psPrintf("tryPS3shading\n" "{ /shfill where\n" " { /ST { STshfill } BD }\n" " { /ST { STnoshfill } BD }\n" " ifelse }\n" "{ /ST { STnoshfill } BD }\n" "ifelse\n"); gl2psPrintf("end\n" "%%%%EndProlog\n" "%%%%BeginSetup\n" "/DeviceRGB setcolorspace\n" "gl2psdict begin\n" "%%%%EndSetup\n" "%%%%Page: 1 1\n" "%%%%BeginPageSetup\n"); if(gl2ps->options & GL2PS_LANDSCAPE){ gl2psPrintf("%d 0 translate 90 rotate\n", (int)gl2ps->viewport[3]); } gl2psPrintf("%%%%EndPageSetup\n" "mark\n" "gsave\n" "1.0 1.0 scale\n"); if(gl2ps->options & GL2PS_DRAW_BACKGROUND){ gl2psPrintf("%g %g %g C\n" "newpath %d %d moveto %d %d lineto %d %d lineto %d %d lineto\n" "closepath fill\n", gl2ps->bgcolor[0], gl2ps->bgcolor[1], gl2ps->bgcolor[2], (int)gl2ps->viewport[0], (int)gl2ps->viewport[1], (int)gl2ps->viewport[2], (int)gl2ps->viewport[1], (int)gl2ps->viewport[2], (int)gl2ps->viewport[3], (int)gl2ps->viewport[0], (int)gl2ps->viewport[3]); } } static void gl2psPrintPostScriptColor(GL2PSrgba rgba) { if(!gl2psSameColor(gl2ps->lastrgba, rgba)){ gl2psSetLastColor(rgba); gl2psPrintf("%g %g %g C\n", rgba[0], rgba[1], rgba[2]); } } static void gl2psResetPostScriptColor(void) { gl2ps->lastrgba[0] = gl2ps->lastrgba[1] = gl2ps->lastrgba[2] = -1.; } static void gl2psEndPostScriptLine(void) { int i; if(gl2ps->lastvertex.rgba[0] >= 0.){ gl2psPrintf("%g %g LE\n", gl2ps->lastvertex.xyz[0], gl2ps->lastvertex.xyz[1]); for(i = 0; i < 3; i++) gl2ps->lastvertex.xyz[i] = -1.; for(i = 0; i < 4; i++) gl2ps->lastvertex.rgba[i] = -1.; } } static void gl2psParseStipplePattern(GLushort pattern, GLint factor, int *nb, int array[10]) { int i, n; int on[8] = {0, 0, 0, 0, 0, 0, 0, 0}; int off[8] = {0, 0, 0, 0, 0, 0, 0, 0}; char tmp[16]; /* extract the 16 bits from the OpenGL stipple pattern */ for(n = 15; n >= 0; n--){ tmp[n] = (char)(pattern & 0x01); pattern >>= 1; } /* compute the on/off pixel sequence */ n = 0; for(i = 0; i < 8; i++){ while(n < 16 && !tmp[n]){ off[i]++; n++; } while(n < 16 && tmp[n]){ on[i]++; n++; } if(n >= 15){ i++; break; } } /* store the on/off array from right to left, starting with off pixels. The PostScript specification allows for at most 11 elements in the on/off array, so we limit ourselves to 5 on/off couples (our longest possible array is thus [on4 off4 on3 off3 on2 off2 on1 off1 on0 off0]) */ *nb = 0; for(n = i - 1; n >= 0; n--){ array[(*nb)++] = factor * on[n]; array[(*nb)++] = factor * off[n]; if(*nb == 10) break; } } static int gl2psPrintPostScriptDash(GLushort pattern, GLint factor, const char *str) { int len = 0, i, n, array[10]; if(pattern == gl2ps->lastpattern && factor == gl2ps->lastfactor) return 0; gl2ps->lastpattern = pattern; gl2ps->lastfactor = factor; if(!pattern || !factor){ /* solid line */ len += gl2psPrintf("[] 0 %s\n", str); } else{ gl2psParseStipplePattern(pattern, factor, &n, array); len += gl2psPrintf("["); for(i = 0; i < n; i++){ if(i) len += gl2psPrintf(" "); len += gl2psPrintf("%d", array[i]); } len += gl2psPrintf("] 0 %s\n", str); } return len; } static void gl2psPrintPostScriptPrimitive(void *data) { int newline; GL2PSprimitive *prim; prim = *(GL2PSprimitive**)data; if((gl2ps->options & GL2PS_OCCLUSION_CULL) && prim->culled) return; /* Every effort is made to draw lines as connected segments (i.e., using a single PostScript path): this is the only way to get nice line joins and to not restart the stippling for every line segment. So if the primitive to print is not a line we must first finish the current line (if any): */ if(prim->type != GL2PS_LINE) gl2psEndPostScriptLine(); switch(prim->type){ case GL2PS_POINT : gl2psPrintPostScriptColor(prim->verts[0].rgba); gl2psPrintf("%g %g %g P\n", prim->verts[0].xyz[0], prim->verts[0].xyz[1], 0.5 * prim->width); break; case GL2PS_LINE : if(!gl2psSamePosition(gl2ps->lastvertex.xyz, prim->verts[0].xyz) || !gl2psSameColor(gl2ps->lastrgba, prim->verts[0].rgba) || gl2ps->lastlinewidth != prim->width || gl2ps->lastpattern != prim->pattern || gl2ps->lastfactor != prim->factor){ /* End the current line if the new segment does not start where the last one ended, or if the color, the width or the stippling have changed (multi-stroking lines with changing colors is necessary until we use /shfill for lines; unfortunately this means that at the moment we can screw up line stippling for smooth-shaded lines) */ gl2psEndPostScriptLine(); newline = 1; } else{ newline = 0; } if(gl2ps->lastlinewidth != prim->width){ gl2ps->lastlinewidth = prim->width; gl2psPrintf("%g W\n", gl2ps->lastlinewidth); } gl2psPrintPostScriptDash(prim->pattern, prim->factor, "setdash"); gl2psPrintPostScriptColor(prim->verts[0].rgba); gl2psPrintf("%g %g %s\n", prim->verts[0].xyz[0], prim->verts[0].xyz[1], newline ? "LS" : "L"); gl2ps->lastvertex = prim->verts[1]; break; case GL2PS_TRIANGLE : if(!gl2psVertsSameColor(prim)){ gl2psResetPostScriptColor(); gl2psPrintf("%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g ST\n", prim->verts[2].xyz[0], prim->verts[2].xyz[1], prim->verts[2].rgba[0], prim->verts[2].rgba[1], prim->verts[2].rgba[2], prim->verts[1].xyz[0], prim->verts[1].xyz[1], prim->verts[1].rgba[0], prim->verts[1].rgba[1], prim->verts[1].rgba[2], prim->verts[0].xyz[0], prim->verts[0].xyz[1], prim->verts[0].rgba[0], prim->verts[0].rgba[1], prim->verts[0].rgba[2]); } else{ gl2psPrintPostScriptColor(prim->verts[0].rgba); gl2psPrintf("%g %g %g %g %g %g T\n", prim->verts[2].xyz[0], prim->verts[2].xyz[1], prim->verts[1].xyz[0], prim->verts[1].xyz[1], prim->verts[0].xyz[0], prim->verts[0].xyz[1]); } break; case GL2PS_QUADRANGLE : gl2psMsg(GL2PS_WARNING, "There should not be any quad left to print"); break; case GL2PS_PIXMAP : gl2psPrintPostScriptPixmap(prim->verts[0].xyz[0], prim->verts[0].xyz[1], prim->data.image); break; case GL2PS_IMAGEMAP : if(prim->data.image->type != GL2PS_IMAGEMAP_WRITTEN){ gl2psPrintPostScriptColor(prim->verts[0].rgba); gl2psPrintPostScriptImagemap(prim->data.image->pixels[0], prim->data.image->pixels[1], prim->data.image->width, prim->data.image->height, (const unsigned char*)(&(prim->data.image->pixels[2]))); prim->data.image->type = GL2PS_IMAGEMAP_WRITTEN; } break; case GL2PS_TEXT : gl2psPrintPostScriptColor(prim->verts[0].rgba); gl2psPrintf("(%s) ", prim->data.text->str); if(prim->data.text->angle) gl2psPrintf("%g ", prim->data.text->angle); gl2psPrintf("%g %g %d /%s ", prim->verts[0].xyz[0], prim->verts[0].xyz[1], prim->data.text->fontsize, prim->data.text->fontname); switch(prim->data.text->alignment){ case GL2PS_TEXT_C: gl2psPrintf(prim->data.text->angle ? "SCCR\n" : "SCC\n"); break; case GL2PS_TEXT_CL: gl2psPrintf(prim->data.text->angle ? "SCLR\n" : "SCL\n"); break; case GL2PS_TEXT_CR: gl2psPrintf(prim->data.text->angle ? "SCRR\n" : "SCR\n"); break; case GL2PS_TEXT_B: gl2psPrintf(prim->data.text->angle ? "SBCR\n" : "SBC\n"); break; case GL2PS_TEXT_BR: gl2psPrintf(prim->data.text->angle ? "SBRR\n" : "SBR\n"); break; case GL2PS_TEXT_T: gl2psPrintf(prim->data.text->angle ? "STCR\n" : "STC\n"); break; case GL2PS_TEXT_TL: gl2psPrintf(prim->data.text->angle ? "STLR\n" : "STL\n"); break; case GL2PS_TEXT_TR: gl2psPrintf(prim->data.text->angle ? "STRR\n" : "STR\n"); break; case GL2PS_TEXT_BL: default: gl2psPrintf(prim->data.text->angle ? "SR\n" : "S\n"); break; } break; case GL2PS_SPECIAL : /* alignment contains the format for which the special output text is intended */ if(prim->data.text->alignment == GL2PS_PS || prim->data.text->alignment == GL2PS_EPS) gl2psPrintf("%s\n", prim->data.text->str); break; default : break; } } static void gl2psPrintPostScriptFooter(void) { gl2psPrintf("grestore\n" "showpage\n" "cleartomark\n" "%%%%PageTrailer\n" "%%%%Trailer\n" "end\n" "%%%%EOF\n"); gl2psPrintGzipFooter(); } static void gl2psPrintPostScriptBeginViewport(GLint viewport[4]) { GLint idx; GLfloat rgba[4]; int x = viewport[0], y = viewport[1], w = viewport[2], h = viewport[3]; glRenderMode(GL_FEEDBACK); if(gl2ps->header){ gl2psPrintPostScriptHeader(); gl2ps->header = GL_FALSE; } gl2psPrintf("gsave\n" "1.0 1.0 scale\n"); if(gl2ps->options & GL2PS_DRAW_BACKGROUND){ if(gl2ps->colormode == GL_RGBA || gl2ps->colorsize == 0){ glGetFloatv(GL_COLOR_CLEAR_VALUE, rgba); } else{ glGetIntegerv(GL_INDEX_CLEAR_VALUE, &idx); rgba[0] = gl2ps->colormap[idx][0]; rgba[1] = gl2ps->colormap[idx][1]; rgba[2] = gl2ps->colormap[idx][2]; rgba[3] = 1.0F; } gl2psPrintf("%g %g %g C\n" "newpath %d %d moveto %d %d lineto %d %d lineto %d %d lineto\n" "closepath fill\n", rgba[0], rgba[1], rgba[2], x, y, x+w, y, x+w, y+h, x, y+h); } gl2psPrintf("newpath %d %d moveto %d %d lineto %d %d lineto %d %d lineto\n" "closepath clip\n", x, y, x+w, y, x+w, y+h, x, y+h); } static GLint gl2psPrintPostScriptEndViewport(void) { GLint res; res = gl2psPrintPrimitives(); gl2psPrintf("grestore\n"); return res; } static void gl2psPrintPostScriptFinalPrimitive(void) { /* End any remaining line, if any */ gl2psEndPostScriptLine(); } /* definition of the PostScript and Encapsulated PostScript backends */ static GL2PSbackend gl2psPS = { gl2psPrintPostScriptHeader, gl2psPrintPostScriptFooter, gl2psPrintPostScriptBeginViewport, gl2psPrintPostScriptEndViewport, gl2psPrintPostScriptPrimitive, gl2psPrintPostScriptFinalPrimitive, "ps", "Postscript" }; static GL2PSbackend gl2psEPS = { gl2psPrintPostScriptHeader, gl2psPrintPostScriptFooter, gl2psPrintPostScriptBeginViewport, gl2psPrintPostScriptEndViewport, gl2psPrintPostScriptPrimitive, gl2psPrintPostScriptFinalPrimitive, "eps", "Encapsulated Postscript" }; /********************************************************************* * * LaTeX routines * *********************************************************************/ static void gl2psPrintTeXHeader(void) { char name[256]; time_t now; int i; if(gl2ps->filename && strlen(gl2ps->filename) < 256){ for(i = (int)strlen(gl2ps->filename) - 1; i >= 0; i--){ if(gl2ps->filename[i] == '.'){ strncpy(name, gl2ps->filename, i); name[i] = '\0'; break; } } if(i <= 0) strcpy(name, gl2ps->filename); } else{ strcpy(name, "untitled"); } time(&now); fprintf(gl2ps->stream, "%% Title: %s\n" "%% Creator: GL2PS %d.%d.%d%s, %s\n" "%% For: %s\n" "%% CreationDate: %s", gl2ps->title, GL2PS_MAJOR_VERSION, GL2PS_MINOR_VERSION, GL2PS_PATCH_VERSION, GL2PS_EXTRA_VERSION, GL2PS_COPYRIGHT, gl2ps->producer, ctime(&now)); fprintf(gl2ps->stream, "\\setlength{\\unitlength}{1pt}\n" "\\begin{picture}(0,0)\n" "\\includegraphics{%s}\n" "\\end{picture}%%\n" "%s\\begin{picture}(%d,%d)(0,0)\n", name, (gl2ps->options & GL2PS_LANDSCAPE) ? "\\rotatebox{90}{" : "", (int)gl2ps->viewport[2], (int)gl2ps->viewport[3]); } static void gl2psPrintTeXPrimitive(void *data) { GL2PSprimitive *prim; prim = *(GL2PSprimitive**)data; switch(prim->type){ case GL2PS_TEXT : fprintf(gl2ps->stream, "\\fontsize{%d}{0}\n\\selectfont", prim->data.text->fontsize); fprintf(gl2ps->stream, "\\put(%g,%g)", prim->verts[0].xyz[0], prim->verts[0].xyz[1]); if(prim->data.text->angle) fprintf(gl2ps->stream, "{\\rotatebox{%g}", prim->data.text->angle); fprintf(gl2ps->stream, "{\\makebox(0,0)"); switch(prim->data.text->alignment){ case GL2PS_TEXT_C: fprintf(gl2ps->stream, "{"); break; case GL2PS_TEXT_CL: fprintf(gl2ps->stream, "[l]{"); break; case GL2PS_TEXT_CR: fprintf(gl2ps->stream, "[r]{"); break; case GL2PS_TEXT_B: fprintf(gl2ps->stream, "[b]{"); break; case GL2PS_TEXT_BR: fprintf(gl2ps->stream, "[br]{"); break; case GL2PS_TEXT_T: fprintf(gl2ps->stream, "[t]{"); break; case GL2PS_TEXT_TL: fprintf(gl2ps->stream, "[tl]{"); break; case GL2PS_TEXT_TR: fprintf(gl2ps->stream, "[tr]{"); break; case GL2PS_TEXT_BL: default: fprintf(gl2ps->stream, "[bl]{"); break; } fprintf(gl2ps->stream, "\\textcolor[rgb]{%g,%g,%g}{{%s}}", prim->verts[0].rgba[0], prim->verts[0].rgba[1], prim->verts[0].rgba[2], prim->data.text->str); if(prim->data.text->angle) fprintf(gl2ps->stream, "}"); fprintf(gl2ps->stream, "}}\n"); break; case GL2PS_SPECIAL : /* alignment contains the format for which the special output text is intended */ if (prim->data.text->alignment == GL2PS_TEX) fprintf(gl2ps->stream, "%s\n", prim->data.text->str); break; default : break; } } static void gl2psPrintTeXFooter(void) { fprintf(gl2ps->stream, "\\end{picture}%s\n", (gl2ps->options & GL2PS_LANDSCAPE) ? "}" : ""); } static void gl2psPrintTeXBeginViewport(GLint viewport[4]) { (void) viewport; /* not used */ glRenderMode(GL_FEEDBACK); if(gl2ps->header){ gl2psPrintTeXHeader(); gl2ps->header = GL_FALSE; } } static GLint gl2psPrintTeXEndViewport(void) { return gl2psPrintPrimitives(); } static void gl2psPrintTeXFinalPrimitive(void) { } /* definition of the LaTeX backend */ static GL2PSbackend gl2psTEX = { gl2psPrintTeXHeader, gl2psPrintTeXFooter, gl2psPrintTeXBeginViewport, gl2psPrintTeXEndViewport, gl2psPrintTeXPrimitive, gl2psPrintTeXFinalPrimitive, "tex", "LaTeX text" }; /********************************************************************* * * PDF routines * *********************************************************************/ static int gl2psPrintPDFCompressorType(void) { #if defined(GL2PS_HAVE_ZLIB) if(gl2ps->options & GL2PS_COMPRESS){ return fprintf(gl2ps->stream, "/Filter [/FlateDecode]\n"); } #endif return 0; } static int gl2psPrintPDFStrokeColor(GL2PSrgba rgba) { int i, offs = 0; gl2psSetLastColor(rgba); for(i = 0; i < 3; ++i){ if(GL2PS_ZERO(rgba[i])) offs += gl2psPrintf("%.0f ", 0.); else if(rgba[i] < 1e-4 || rgba[i] > 1e6) /* avoid %e formatting */ offs += gl2psPrintf("%f ", rgba[i]); else offs += gl2psPrintf("%g ", rgba[i]); } offs += gl2psPrintf("RG\n"); return offs; } static int gl2psPrintPDFFillColor(GL2PSrgba rgba) { int i, offs = 0; for(i = 0; i < 3; ++i){ if(GL2PS_ZERO(rgba[i])) offs += gl2psPrintf("%.0f ", 0.); else if(rgba[i] < 1e-4 || rgba[i] > 1e6) /* avoid %e formatting */ offs += gl2psPrintf("%f ", rgba[i]); else offs += gl2psPrintf("%g ", rgba[i]); } offs += gl2psPrintf("rg\n"); return offs; } static int gl2psPrintPDFLineWidth(GLfloat lw) { if(GL2PS_ZERO(lw)) return gl2psPrintf("%.0f w\n", 0.); else if(lw < 1e-4 || lw > 1e6) /* avoid %e formatting */ return gl2psPrintf("%f w\n", lw); else return gl2psPrintf("%g w\n", lw); } static void gl2psPutPDFText(GL2PSstring *text, int cnt, GLfloat x, GLfloat y) { GLfloat rad, crad, srad; if(text->angle == 0.0F){ gl2ps->streamlength += gl2psPrintf ("BT\n" "/F%d %d Tf\n" "%f %f Td\n" "(%s) Tj\n" "ET\n", cnt, text->fontsize, x, y, text->str); } else{ rad = (GLfloat)(3.141593F * text->angle / 180.0F); srad = (GLfloat)sin(rad); crad = (GLfloat)cos(rad); gl2ps->streamlength += gl2psPrintf ("BT\n" "/F%d %d Tf\n" "%f %f %f %f %f %f Tm\n" "(%s) Tj\n" "ET\n", cnt, text->fontsize, crad, srad, -srad, crad, x, y, text->str); } } static void gl2psPutPDFSpecial(GL2PSstring *text) { gl2ps->streamlength += gl2psPrintf("%s\n", text->str); } static void gl2psPutPDFImage(GL2PSimage *image, int cnt, GLfloat x, GLfloat y) { gl2ps->streamlength += gl2psPrintf ("q\n" "%d 0 0 %d %f %f cm\n" "/Im%d Do\n" "Q\n", (int)image->width, (int)image->height, x, y, cnt); } static void gl2psPDFstacksInit(void) { gl2ps->objects_stack = 7 /* FIXED_XREF_ENTRIES */ + 1; gl2ps->extgs_stack = 0; gl2ps->font_stack = 0; gl2ps->im_stack = 0; gl2ps->trgroupobjects_stack = 0; gl2ps->shader_stack = 0; gl2ps->mshader_stack = 0; } static void gl2psPDFgroupObjectInit(GL2PSpdfgroup *gro) { if(!gro) return; gro->ptrlist = NULL; gro->fontno = gro->gsno = gro->imno = gro->maskshno = gro->shno = gro->trgroupno = gro->fontobjno = gro->imobjno = gro->shobjno = gro->maskshobjno = gro->gsobjno = gro->trgroupobjno = -1; } /* Build up group objects and assign name and object numbers */ static void gl2psPDFgroupListInit(void) { int i; GL2PSprimitive *p = NULL; GL2PSpdfgroup gro; int lasttype = GL2PS_NO_TYPE; GL2PSrgba lastrgba = {-1.0F, -1.0F, -1.0F, -1.0F}; GLushort lastpattern = 0; GLint lastfactor = 0; GLfloat lastwidth = 1; GL2PStriangle lastt, tmpt; int lastTriangleWasNotSimpleWithSameColor = 0; if(!gl2ps->pdfprimlist) return; gl2ps->pdfgrouplist = gl2psListCreate(500, 500, sizeof(GL2PSpdfgroup)); gl2psInitTriangle(&lastt); for(i = 0; i < gl2psListNbr(gl2ps->pdfprimlist); ++i){ p = *(GL2PSprimitive**)gl2psListPointer(gl2ps->pdfprimlist, i); switch(p->type){ case GL2PS_PIXMAP: gl2psPDFgroupObjectInit(&gro); gro.ptrlist = gl2psListCreate(1, 2, sizeof(GL2PSprimitive*)); gro.imno = gl2ps->im_stack++; gl2psListAdd(gro.ptrlist, &p); gl2psListAdd(gl2ps->pdfgrouplist, &gro); break; case GL2PS_TEXT: gl2psPDFgroupObjectInit(&gro); gro.ptrlist = gl2psListCreate(1, 2, sizeof(GL2PSprimitive*)); gro.fontno = gl2ps->font_stack++; gl2psListAdd(gro.ptrlist, &p); gl2psListAdd(gl2ps->pdfgrouplist, &gro); break; case GL2PS_LINE: if(lasttype != p->type || lastwidth != p->width || lastpattern != p->pattern || lastfactor != p->factor || !gl2psSameColor(p->verts[0].rgba, lastrgba)){ gl2psPDFgroupObjectInit(&gro); gro.ptrlist = gl2psListCreate(1, 2, sizeof(GL2PSprimitive*)); gl2psListAdd(gro.ptrlist, &p); gl2psListAdd(gl2ps->pdfgrouplist, &gro); } else{ gl2psListAdd(gro.ptrlist, &p); } lastpattern = p->pattern; lastfactor = p->factor; lastwidth = p->width; lastrgba[0] = p->verts[0].rgba[0]; lastrgba[1] = p->verts[0].rgba[1]; lastrgba[2] = p->verts[0].rgba[2]; break; case GL2PS_POINT: if(lasttype != p->type || lastwidth != p->width || !gl2psSameColor(p->verts[0].rgba, lastrgba)){ gl2psPDFgroupObjectInit(&gro); gro.ptrlist = gl2psListCreate(1,2,sizeof(GL2PSprimitive*)); gl2psListAdd(gro.ptrlist, &p); gl2psListAdd(gl2ps->pdfgrouplist, &gro); } else{ gl2psListAdd(gro.ptrlist, &p); } lastwidth = p->width; lastrgba[0] = p->verts[0].rgba[0]; lastrgba[1] = p->verts[0].rgba[1]; lastrgba[2] = p->verts[0].rgba[2]; break; case GL2PS_TRIANGLE: gl2psFillTriangleFromPrimitive(&tmpt, p, GL_TRUE); lastTriangleWasNotSimpleWithSameColor = !(tmpt.prop & T_CONST_COLOR && tmpt.prop & T_ALPHA_1) || !gl2psSameColor(tmpt.vertex[0].rgba, lastt.vertex[0].rgba); if(lasttype == p->type && tmpt.prop == lastt.prop && lastTriangleWasNotSimpleWithSameColor){ /* Check here for last alpha */ gl2psListAdd(gro.ptrlist, &p); } else{ gl2psPDFgroupObjectInit(&gro); gro.ptrlist = gl2psListCreate(1, 2, sizeof(GL2PSprimitive*)); gl2psListAdd(gro.ptrlist, &p); gl2psListAdd(gl2ps->pdfgrouplist, &gro); } lastt = tmpt; break; case GL2PS_SPECIAL: gl2psPDFgroupObjectInit(&gro); gro.ptrlist = gl2psListCreate(1, 2, sizeof(GL2PSprimitive*)); gl2psListAdd(gro.ptrlist, &p); gl2psListAdd(gl2ps->pdfgrouplist, &gro); break; default: break; } lasttype = p->type; } } static void gl2psSortOutTrianglePDFgroup(GL2PSpdfgroup *gro) { GL2PStriangle t; GL2PSprimitive *prim = NULL; if(!gro) return; if(!gl2psListNbr(gro->ptrlist)) return; prim = *(GL2PSprimitive**)gl2psListPointer(gro->ptrlist, 0); if(prim->type != GL2PS_TRIANGLE) return; gl2psFillTriangleFromPrimitive(&t, prim, GL_TRUE); if(t.prop & T_CONST_COLOR && t.prop & T_ALPHA_LESS_1){ gro->gsno = gl2ps->extgs_stack++; gro->gsobjno = gl2ps->objects_stack ++; } else if(t.prop & T_CONST_COLOR && t.prop & T_VAR_ALPHA){ gro->gsno = gl2ps->extgs_stack++; gro->gsobjno = gl2ps->objects_stack++; gro->trgroupno = gl2ps->trgroupobjects_stack++; gro->trgroupobjno = gl2ps->objects_stack++; gro->maskshno = gl2ps->mshader_stack++; gro->maskshobjno = gl2ps->objects_stack++; } else if(t.prop & T_VAR_COLOR && t.prop & T_ALPHA_1){ gro->shno = gl2ps->shader_stack++; gro->shobjno = gl2ps->objects_stack++; } else if(t.prop & T_VAR_COLOR && t.prop & T_ALPHA_LESS_1){ gro->gsno = gl2ps->extgs_stack++; gro->gsobjno = gl2ps->objects_stack++; gro->shno = gl2ps->shader_stack++; gro->shobjno = gl2ps->objects_stack++; } else if(t.prop & T_VAR_COLOR && t.prop & T_VAR_ALPHA){ gro->gsno = gl2ps->extgs_stack++; gro->gsobjno = gl2ps->objects_stack++; gro->shno = gl2ps->shader_stack++; gro->shobjno = gl2ps->objects_stack++; gro->trgroupno = gl2ps->trgroupobjects_stack++; gro->trgroupobjno = gl2ps->objects_stack++; gro->maskshno = gl2ps->mshader_stack++; gro->maskshobjno = gl2ps->objects_stack++; } } /* Main stream data */ static void gl2psPDFgroupListWriteMainStream(void) { int i, j, lastel; GL2PSprimitive *prim = NULL, *prev = NULL; GL2PSpdfgroup *gro; GL2PStriangle t; if(!gl2ps->pdfgrouplist) return; for(i = 0; i < gl2psListNbr(gl2ps->pdfgrouplist); ++i){ gro = (GL2PSpdfgroup*)gl2psListPointer(gl2ps->pdfgrouplist, i); lastel = gl2psListNbr(gro->ptrlist) - 1; if(lastel < 0) continue; prim = *(GL2PSprimitive**)gl2psListPointer(gro->ptrlist, 0); switch(prim->type){ case GL2PS_POINT: gl2ps->streamlength += gl2psPrintf("1 J\n"); gl2ps->streamlength += gl2psPrintPDFLineWidth(prim->width); gl2ps->streamlength += gl2psPrintPDFStrokeColor(prim->verts[0].rgba); for(j = 0; j <= lastel; ++j){ prim = *(GL2PSprimitive**)gl2psListPointer(gro->ptrlist, j); gl2ps->streamlength += gl2psPrintf("%f %f m %f %f l\n", prim->verts[0].xyz[0], prim->verts[0].xyz[1], prim->verts[0].xyz[0], prim->verts[0].xyz[1]); } gl2ps->streamlength += gl2psPrintf("S\n"); gl2ps->streamlength += gl2psPrintf("0 J\n"); break; case GL2PS_LINE: /* We try to use as few paths as possible to draw lines, in order to get nice stippling even when the individual segments are smaller than the stipple */ gl2ps->streamlength += gl2psPrintPDFLineWidth(prim->width); gl2ps->streamlength += gl2psPrintPDFStrokeColor(prim->verts[0].rgba); gl2ps->streamlength += gl2psPrintPostScriptDash(prim->pattern, prim->factor, "d"); /* start new path */ gl2ps->streamlength += gl2psPrintf("%f %f m\n", prim->verts[0].xyz[0], prim->verts[0].xyz[1]); for(j = 1; j <= lastel; ++j){ prev = prim; prim = *(GL2PSprimitive**)gl2psListPointer(gro->ptrlist, j); if(!gl2psSamePosition(prim->verts[0].xyz, prev->verts[1].xyz)){ /* the starting point of the new segment does not match the end point of the previous line, so we end the current path and start a new one */ gl2ps->streamlength += gl2psPrintf("%f %f l\n", prev->verts[1].xyz[0], prev->verts[1].xyz[1]); gl2ps->streamlength += gl2psPrintf("%f %f m\n", prim->verts[0].xyz[0], prim->verts[0].xyz[1]); } else{ /* the two segements are connected, so we just append to the current path */ gl2ps->streamlength += gl2psPrintf("%f %f l\n", prim->verts[0].xyz[0], prim->verts[0].xyz[1]); } } /* end last path */ gl2ps->streamlength += gl2psPrintf("%f %f l\n", prim->verts[1].xyz[0], prim->verts[1].xyz[1]); gl2ps->streamlength += gl2psPrintf("S\n"); break; case GL2PS_TRIANGLE: gl2psFillTriangleFromPrimitive(&t, prim, GL_TRUE); gl2psSortOutTrianglePDFgroup(gro); /* No alpha and const color: Simple PDF draw orders */ if(t.prop & T_CONST_COLOR && t.prop & T_ALPHA_1){ gl2ps->streamlength += gl2psPrintPDFFillColor(t.vertex[0].rgba); for(j = 0; j <= lastel; ++j){ prim = *(GL2PSprimitive**)gl2psListPointer(gro->ptrlist, j); gl2psFillTriangleFromPrimitive(&t, prim, GL_FALSE); gl2ps->streamlength += gl2psPrintf("%f %f m\n" "%f %f l\n" "%f %f l\n" "h f\n", t.vertex[0].xyz[0], t.vertex[0].xyz[1], t.vertex[1].xyz[0], t.vertex[1].xyz[1], t.vertex[2].xyz[0], t.vertex[2].xyz[1]); } } /* Const alpha < 1 and const color: Simple PDF draw orders and an extra extended Graphics State for the alpha const */ else if(t.prop & T_CONST_COLOR && t.prop & T_ALPHA_LESS_1){ gl2ps->streamlength += gl2psPrintf("q\n" "/GS%d gs\n", gro->gsno); gl2ps->streamlength += gl2psPrintPDFFillColor(prim->verts[0].rgba); for(j = 0; j <= lastel; ++j){ prim = *(GL2PSprimitive**)gl2psListPointer(gro->ptrlist, j); gl2psFillTriangleFromPrimitive(&t, prim, GL_FALSE); gl2ps->streamlength += gl2psPrintf("%f %f m\n" "%f %f l\n" "%f %f l\n" "h f\n", t.vertex[0].xyz[0], t.vertex[0].xyz[1], t.vertex[1].xyz[0], t.vertex[1].xyz[1], t.vertex[2].xyz[0], t.vertex[2].xyz[1]); } gl2ps->streamlength += gl2psPrintf("Q\n"); } /* Variable alpha and const color: Simple PDF draw orders and an extra extended Graphics State + Xobject + Shader object for the alpha mask */ else if(t.prop & T_CONST_COLOR && t.prop & T_VAR_ALPHA){ gl2ps->streamlength += gl2psPrintf("q\n" "/GS%d gs\n" "/TrG%d Do\n", gro->gsno, gro->trgroupno); gl2ps->streamlength += gl2psPrintPDFFillColor(prim->verts[0].rgba); for(j = 0; j <= lastel; ++j){ prim = *(GL2PSprimitive**)gl2psListPointer(gro->ptrlist, j); gl2psFillTriangleFromPrimitive(&t, prim, GL_FALSE); gl2ps->streamlength += gl2psPrintf("%f %f m\n" "%f %f l\n" "%f %f l\n" "h f\n", t.vertex[0].xyz[0], t.vertex[0].xyz[1], t.vertex[1].xyz[0], t.vertex[1].xyz[1], t.vertex[2].xyz[0], t.vertex[2].xyz[1]); } gl2ps->streamlength += gl2psPrintf("Q\n"); } /* Variable color and no alpha: Shader Object for the colored triangle(s) */ else if(t.prop & T_VAR_COLOR && t.prop & T_ALPHA_1){ gl2ps->streamlength += gl2psPrintf("/Sh%d sh\n", gro->shno); } /* Variable color and const alpha < 1: Shader Object for the colored triangle(s) and an extra extended Graphics State for the alpha const */ else if(t.prop & T_VAR_COLOR && t.prop & T_ALPHA_LESS_1){ gl2ps->streamlength += gl2psPrintf("q\n" "/GS%d gs\n" "/Sh%d sh\n" "Q\n", gro->gsno, gro->shno); } /* Variable alpha and color: Shader Object for the colored triangle(s) and an extra extended Graphics State + Xobject + Shader object for the alpha mask */ else if(t.prop & T_VAR_COLOR && t.prop & T_VAR_ALPHA){ gl2ps->streamlength += gl2psPrintf("q\n" "/GS%d gs\n" "/TrG%d Do\n" "/Sh%d sh\n" "Q\n", gro->gsno, gro->trgroupno, gro->shno); } break; case GL2PS_PIXMAP: for(j = 0; j <= lastel; ++j){ prim = *(GL2PSprimitive**)gl2psListPointer(gro->ptrlist, j); gl2psPutPDFImage(prim->data.image, gro->imno, prim->verts[0].xyz[0], prim->verts[0].xyz[1]); } break; case GL2PS_TEXT: for(j = 0; j <= lastel; ++j){ prim = *(GL2PSprimitive**)gl2psListPointer(gro->ptrlist, j); gl2ps->streamlength += gl2psPrintPDFFillColor(prim->verts[0].rgba); gl2psPutPDFText(prim->data.text, gro->fontno, prim->verts[0].xyz[0], prim->verts[0].xyz[1]); } break; case GL2PS_SPECIAL: for(j = 0; j <= lastel; ++j){ prim = *(GL2PSprimitive**)gl2psListPointer(gro->ptrlist, j); gl2psPutPDFSpecial(prim->data.text); } default: break; } } } /* Graphics State names */ static int gl2psPDFgroupListWriteGStateResources(void) { GL2PSpdfgroup *gro; int offs = 0; int i; offs += fprintf(gl2ps->stream, "/ExtGState\n" "<<\n" "/GSa 7 0 R\n"); for(i = 0; i < gl2psListNbr(gl2ps->pdfgrouplist); ++i){ gro = (GL2PSpdfgroup*)gl2psListPointer(gl2ps->pdfgrouplist, i); if(gro->gsno >= 0) offs += fprintf(gl2ps->stream, "/GS%d %d 0 R\n", gro->gsno, gro->gsobjno); } offs += fprintf(gl2ps->stream, ">>\n"); return offs; } /* Main Shader names */ static int gl2psPDFgroupListWriteShaderResources(void) { GL2PSpdfgroup *gro; int offs = 0; int i; offs += fprintf(gl2ps->stream, "/Shading\n" "<<\n"); for(i = 0; i < gl2psListNbr(gl2ps->pdfgrouplist); ++i){ gro = (GL2PSpdfgroup*)gl2psListPointer(gl2ps->pdfgrouplist, i); if(gro->shno >= 0) offs += fprintf(gl2ps->stream, "/Sh%d %d 0 R\n", gro->shno, gro->shobjno); if(gro->maskshno >= 0) offs += fprintf(gl2ps->stream, "/TrSh%d %d 0 R\n", gro->maskshno, gro->maskshobjno); } offs += fprintf(gl2ps->stream,">>\n"); return offs; } /* Images & Mask Shader XObject names */ static int gl2psPDFgroupListWriteXObjectResources(void) { int i; GL2PSprimitive *p = NULL; GL2PSpdfgroup *gro; int offs = 0; offs += fprintf(gl2ps->stream, "/XObject\n" "<<\n"); for(i = 0; i < gl2psListNbr(gl2ps->pdfgrouplist); ++i){ gro = (GL2PSpdfgroup*)gl2psListPointer(gl2ps->pdfgrouplist, i); if(!gl2psListNbr(gro->ptrlist)) continue; p = *(GL2PSprimitive**)gl2psListPointer(gro->ptrlist, 0); switch(p->type){ case GL2PS_PIXMAP: gro->imobjno = gl2ps->objects_stack++; if(GL_RGBA == p->data.image->format) /* reserve one object for image mask */ gl2ps->objects_stack++; offs += fprintf(gl2ps->stream, "/Im%d %d 0 R\n", gro->imno, gro->imobjno); case GL2PS_TRIANGLE: if(gro->trgroupno >=0) offs += fprintf(gl2ps->stream, "/TrG%d %d 0 R\n", gro->trgroupno, gro->trgroupobjno); break; default: break; } } offs += fprintf(gl2ps->stream,">>\n"); return offs; } /* Font names */ static int gl2psPDFgroupListWriteFontResources(void) { int i; GL2PSpdfgroup *gro; int offs = 0; offs += fprintf(gl2ps->stream, "/Font\n<<\n"); for(i = 0; i < gl2psListNbr(gl2ps->pdfgrouplist); ++i){ gro = (GL2PSpdfgroup*)gl2psListPointer(gl2ps->pdfgrouplist, i); if(gro->fontno < 0) continue; gro->fontobjno = gl2ps->objects_stack++; offs += fprintf(gl2ps->stream, "/F%d %d 0 R\n", gro->fontno, gro->fontobjno); } offs += fprintf(gl2ps->stream, ">>\n"); return offs; } static void gl2psPDFgroupListDelete(void) { int i; GL2PSpdfgroup *gro = NULL; if(!gl2ps->pdfgrouplist) return; for(i = 0; i < gl2psListNbr(gl2ps->pdfgrouplist); ++i){ gro = (GL2PSpdfgroup*)gl2psListPointer(gl2ps->pdfgrouplist,i); gl2psListDelete(gro->ptrlist); } gl2psListDelete(gl2ps->pdfgrouplist); gl2ps->pdfgrouplist = NULL; } /* Print 1st PDF object - file info */ static int gl2psPrintPDFInfo(void) { int offs; time_t now; struct tm *newtime; time(&now); newtime = gmtime(&now); offs = fprintf(gl2ps->stream, "1 0 obj\n" "<<\n" "/Title (%s)\n" "/Creator (GL2PS %d.%d.%d%s, %s)\n" "/Producer (%s)\n", gl2ps->title, GL2PS_MAJOR_VERSION, GL2PS_MINOR_VERSION, GL2PS_PATCH_VERSION, GL2PS_EXTRA_VERSION, GL2PS_COPYRIGHT, gl2ps->producer); if(!newtime){ offs += fprintf(gl2ps->stream, ">>\n" "endobj\n"); return offs; } offs += fprintf(gl2ps->stream, "/CreationDate (D:%d%02d%02d%02d%02d%02d)\n" ">>\n" "endobj\n", newtime->tm_year+1900, newtime->tm_mon+1, newtime->tm_mday, newtime->tm_hour, newtime->tm_min, newtime->tm_sec); return offs; } /* Create catalog and page structure - 2nd and 3th PDF object */ static int gl2psPrintPDFCatalog(void) { return fprintf(gl2ps->stream, "2 0 obj\n" "<<\n" "/Type /Catalog\n" "/Pages 3 0 R\n" ">>\n" "endobj\n"); } static int gl2psPrintPDFPages(void) { return fprintf(gl2ps->stream, "3 0 obj\n" "<<\n" "/Type /Pages\n" "/Kids [6 0 R]\n" "/Count 1\n" ">>\n" "endobj\n"); } /* Open stream for data - graphical objects, fonts etc. PDF object 4 */ static int gl2psOpenPDFDataStream(void) { int offs = 0; offs += fprintf(gl2ps->stream, "4 0 obj\n" "<<\n" "/Length 5 0 R\n" ); offs += gl2psPrintPDFCompressorType(); offs += fprintf(gl2ps->stream, ">>\n" "stream\n"); return offs; } /* Stream setup - Graphics state, fill background if allowed */ static int gl2psOpenPDFDataStreamWritePreface(void) { int offs; offs = gl2psPrintf("/GSa gs\n"); if(gl2ps->options & GL2PS_DRAW_BACKGROUND){ offs += gl2psPrintPDFFillColor(gl2ps->bgcolor); offs += gl2psPrintf("%d %d %d %d re\n", (int)gl2ps->viewport[0], (int)gl2ps->viewport[1], (int)gl2ps->viewport[2], (int)gl2ps->viewport[3]); offs += gl2psPrintf("f\n"); } return offs; } /* Use the functions above to create the first part of the PDF*/ static void gl2psPrintPDFHeader(void) { int offs = 0; gl2ps->pdfprimlist = gl2psListCreate(500, 500, sizeof(GL2PSprimitive*)); gl2psPDFstacksInit(); gl2ps->xreflist = (int*)gl2psMalloc(sizeof(int) * gl2ps->objects_stack); #if defined(GL2PS_HAVE_ZLIB) if(gl2ps->options & GL2PS_COMPRESS){ gl2psSetupCompress(); } #endif gl2ps->xreflist[0] = 0; offs += fprintf(gl2ps->stream, "%%PDF-1.4\n"); gl2ps->xreflist[1] = offs; offs += gl2psPrintPDFInfo(); gl2ps->xreflist[2] = offs; offs += gl2psPrintPDFCatalog(); gl2ps->xreflist[3] = offs; offs += gl2psPrintPDFPages(); gl2ps->xreflist[4] = offs; offs += gl2psOpenPDFDataStream(); gl2ps->xreflist[5] = offs; /* finished in gl2psPrintPDFFooter */ gl2ps->streamlength = gl2psOpenPDFDataStreamWritePreface(); } /* The central primitive drawing */ static void gl2psPrintPDFPrimitive(void *data) { GL2PSprimitive *prim = *(GL2PSprimitive**)data; if((gl2ps->options & GL2PS_OCCLUSION_CULL) && prim->culled) return; prim = gl2psCopyPrimitive(prim); /* deep copy */ gl2psListAdd(gl2ps->pdfprimlist, &prim); } /* close stream and ... */ static int gl2psClosePDFDataStream(void) { int offs = 0; #if defined(GL2PS_HAVE_ZLIB) if(gl2ps->options & GL2PS_COMPRESS){ if(Z_OK != gl2psDeflate()) gl2psMsg(GL2PS_ERROR, "Zlib deflate error"); else fwrite(gl2ps->compress->dest, gl2ps->compress->destLen, 1, gl2ps->stream); gl2ps->streamlength += gl2ps->compress->destLen; offs += gl2ps->streamlength; gl2psFreeCompress(); } #endif offs += fprintf(gl2ps->stream, "endstream\n" "endobj\n"); return offs; } /* ... write the now known length object */ static int gl2psPrintPDFDataStreamLength(int val) { return fprintf(gl2ps->stream, "5 0 obj\n" "%d\n" "endobj\n", val); } /* Put the info created before in PDF objects */ static int gl2psPrintPDFOpenPage(void) { int offs; /* Write fixed part */ offs = fprintf(gl2ps->stream, "6 0 obj\n" "<<\n" "/Type /Page\n" "/Parent 3 0 R\n" "/MediaBox [%d %d %d %d]\n", (int)gl2ps->viewport[0], (int)gl2ps->viewport[1], (int)gl2ps->viewport[2], (int)gl2ps->viewport[3]); if(gl2ps->options & GL2PS_LANDSCAPE) offs += fprintf(gl2ps->stream, "/Rotate -90\n"); offs += fprintf(gl2ps->stream, "/Contents 4 0 R\n" "/Resources\n" "<<\n" "/ProcSet [/PDF /Text /ImageB /ImageC] %%/ImageI\n"); return offs; /* End fixed part, proceeds in gl2psPDFgroupListWriteVariableResources() */ } static int gl2psPDFgroupListWriteVariableResources(void) { int offs = 0; /* a) Graphics States for shader alpha masks*/ offs += gl2psPDFgroupListWriteGStateResources(); /* b) Shader and shader masks */ offs += gl2psPDFgroupListWriteShaderResources(); /* c) XObjects (Images & Shader Masks) */ offs += gl2psPDFgroupListWriteXObjectResources(); /* d) Fonts */ offs += gl2psPDFgroupListWriteFontResources(); /* End resources and page */ offs += fprintf(gl2ps->stream, ">>\n" ">>\n" "endobj\n"); return offs; } /* Standard Graphics State */ static int gl2psPrintPDFGSObject(void) { return fprintf(gl2ps->stream, "7 0 obj\n" "<<\n" "/Type /ExtGState\n" "/SA false\n" "/SM 0.02\n" "/OP false\n" "/op false\n" "/OPM 0\n" "/BG2 /Default\n" "/UCR2 /Default\n" "/TR2 /Default\n" ">>\n" "endobj\n"); } /* Put vertex' edge flag (8bit) and coordinates (32bit) in shader stream */ static int gl2psPrintPDFShaderStreamDataCoord(GL2PSvertex *vertex, int (*action)(unsigned long data, int size), GLfloat dx, GLfloat dy, GLfloat xmin, GLfloat ymin) { int offs = 0; unsigned long imap; GLfloat diff; double dmax = ~1UL; char edgeflag = 0; /* FIXME: temp bux fix for 64 bit archs: */ if(sizeof(unsigned long) == 8) dmax = dmax - 2048.; offs += (*action)(edgeflag, 1); /* The Shader stream in PDF requires to be in a 'big-endian' order */ if(GL2PS_ZERO(dx * dy)){ offs += (*action)(0, 4); offs += (*action)(0, 4); } else{ diff = (vertex->xyz[0] - xmin) / dx; if(diff > 1) diff = 1.0F; else if(diff < 0) diff = 0.0F; imap = (unsigned long)(diff * dmax); offs += (*action)(imap, 4); diff = (vertex->xyz[1] - ymin) / dy; if(diff > 1) diff = 1.0F; else if(diff < 0) diff = 0.0F; imap = (unsigned long)(diff * dmax); offs += (*action)(imap, 4); } return offs; } /* Put vertex' rgb value (8bit for every component) in shader stream */ static int gl2psPrintPDFShaderStreamDataRGB(GL2PSvertex *vertex, int (*action)(unsigned long data, int size)) { int offs = 0; unsigned long imap; double dmax = ~1UL; /* FIXME: temp bux fix for 64 bit archs: */ if(sizeof(unsigned long) == 8) dmax = dmax - 2048.; imap = (unsigned long)((vertex->rgba[0]) * dmax); offs += (*action)(imap, 1); imap = (unsigned long)((vertex->rgba[1]) * dmax); offs += (*action)(imap, 1); imap = (unsigned long)((vertex->rgba[2]) * dmax); offs += (*action)(imap, 1); return offs; } /* Put vertex' alpha (8/16bit) in shader stream */ static int gl2psPrintPDFShaderStreamDataAlpha(GL2PSvertex *vertex, int (*action)(unsigned long data, int size), int sigbyte) { int offs = 0; unsigned long imap; double dmax = ~1UL; /* FIXME: temp bux fix for 64 bit archs: */ if(sizeof(unsigned long) == 8) dmax = dmax - 2048.; if(sigbyte != 8 && sigbyte != 16) sigbyte = 8; sigbyte /= 8; imap = (unsigned long)((vertex->rgba[3]) * dmax); offs += (*action)(imap, sigbyte); return offs; } /* Put a triangles raw data in shader stream */ static int gl2psPrintPDFShaderStreamData(GL2PStriangle *triangle, GLfloat dx, GLfloat dy, GLfloat xmin, GLfloat ymin, int (*action)(unsigned long data, int size), int gray) { int i, offs = 0; GL2PSvertex v; if(gray && gray != 8 && gray != 16) gray = 8; for(i = 0; i < 3; ++i){ offs += gl2psPrintPDFShaderStreamDataCoord(&triangle->vertex[i], action, dx, dy, xmin, ymin); if(gray){ v = triangle->vertex[i]; offs += gl2psPrintPDFShaderStreamDataAlpha(&v, action, gray); } else{ offs += gl2psPrintPDFShaderStreamDataRGB(&triangle->vertex[i], action); } } return offs; } static void gl2psPDFRectHull(GLfloat *xmin, GLfloat *xmax, GLfloat *ymin, GLfloat *ymax, GL2PStriangle *triangles, int cnt) { int i, j; *xmin = triangles[0].vertex[0].xyz[0]; *xmax = triangles[0].vertex[0].xyz[0]; *ymin = triangles[0].vertex[0].xyz[1]; *ymax = triangles[0].vertex[0].xyz[1]; for(i = 0; i < cnt; ++i){ for(j = 0; j < 3; ++j){ if(*xmin > triangles[i].vertex[j].xyz[0]) *xmin = triangles[i].vertex[j].xyz[0]; if(*xmax < triangles[i].vertex[j].xyz[0]) *xmax = triangles[i].vertex[j].xyz[0]; if(*ymin > triangles[i].vertex[j].xyz[1]) *ymin = triangles[i].vertex[j].xyz[1]; if(*ymax < triangles[i].vertex[j].xyz[1]) *ymax = triangles[i].vertex[j].xyz[1]; } } } /* Writes shaded triangle gray == 0 means write RGB triangles gray == 8 8bit-grayscale (for alpha masks) gray == 16 16bit-grayscale (for alpha masks) */ static int gl2psPrintPDFShader(int obj, GL2PStriangle *triangles, int size, int gray) { int i, offs = 0, vertexbytes, done = 0; GLfloat xmin, xmax, ymin, ymax; switch(gray){ case 0: vertexbytes = 1+4+4+1+1+1; break; case 8: vertexbytes = 1+4+4+1; break; case 16: vertexbytes = 1+4+4+2; break; default: gray = 8; vertexbytes = 1+4+4+1; break; } gl2psPDFRectHull(&xmin, &xmax, &ymin, &ymax, triangles, size); offs += fprintf(gl2ps->stream, "%d 0 obj\n" "<< " "/ShadingType 4 " "/ColorSpace %s " "/BitsPerCoordinate 32 " "/BitsPerComponent %d " "/BitsPerFlag 8 " "/Decode [%f %f %f %f 0 1 %s] ", obj, (gray) ? "/DeviceGray" : "/DeviceRGB", (gray) ? gray : 8, xmin, xmax, ymin, ymax, (gray) ? "" : "0 1 0 1"); #if defined(GL2PS_HAVE_ZLIB) if(gl2ps->options & GL2PS_COMPRESS){ gl2psAllocCompress(vertexbytes * size * 3); for(i = 0; i < size; ++i) gl2psPrintPDFShaderStreamData(&triangles[i], xmax-xmin, ymax-ymin, xmin, ymin, gl2psWriteBigEndianCompress, gray); if(Z_OK == gl2psDeflate() && 23 + gl2ps->compress->destLen < gl2ps->compress->srcLen){ offs += gl2psPrintPDFCompressorType(); offs += fprintf(gl2ps->stream, "/Length %d " ">>\n" "stream\n", (int)gl2ps->compress->destLen); offs += gl2ps->compress->destLen * fwrite(gl2ps->compress->dest, gl2ps->compress->destLen, 1, gl2ps->stream); done = 1; } gl2psFreeCompress(); } #endif if(!done){ /* no compression, or too long after compression, or compress error -> write non-compressed entry */ offs += fprintf(gl2ps->stream, "/Length %d " ">>\n" "stream\n", vertexbytes * 3 * size); for(i = 0; i < size; ++i) offs += gl2psPrintPDFShaderStreamData(&triangles[i], xmax-xmin, ymax-ymin, xmin, ymin, gl2psWriteBigEndian, gray); } offs += fprintf(gl2ps->stream, "\nendstream\n" "endobj\n"); return offs; } /* Writes a XObject for a shaded triangle mask */ static int gl2psPrintPDFShaderMask(int obj, int childobj) { int offs = 0, len; offs += fprintf(gl2ps->stream, "%d 0 obj\n" "<<\n" "/Type /XObject\n" "/Subtype /Form\n" "/BBox [ %d %d %d %d ]\n" "/Group \n<<\n/S /Transparency /CS /DeviceRGB\n" ">>\n", obj, (int)gl2ps->viewport[0], (int)gl2ps->viewport[1], (int)gl2ps->viewport[2], (int)gl2ps->viewport[3]); len = (childobj>0) ? strlen("/TrSh sh\n") + (int)log10((double)childobj)+1 : strlen("/TrSh0 sh\n"); offs += fprintf(gl2ps->stream, "/Length %d\n" ">>\n" "stream\n", len); offs += fprintf(gl2ps->stream, "/TrSh%d sh\n", childobj); offs += fprintf(gl2ps->stream, "endstream\n" "endobj\n"); return offs; } /* Writes a Extended graphics state for a shaded triangle mask if simplealpha ist true the childobj argument is ignored and a /ca statement will be written instead */ static int gl2psPrintPDFShaderExtGS(int obj, int childobj) { int offs = 0; offs += fprintf(gl2ps->stream, "%d 0 obj\n" "<<\n", obj); offs += fprintf(gl2ps->stream, "/SMask << /S /Alpha /G %d 0 R >> ", childobj); offs += fprintf(gl2ps->stream, ">>\n" "endobj\n"); return offs; } /* a simple graphics state */ static int gl2psPrintPDFShaderSimpleExtGS(int obj, GLfloat alpha) { int offs = 0; offs += fprintf(gl2ps->stream, "%d 0 obj\n" "<<\n" "/ca %g" ">>\n" "endobj\n", obj, alpha); return offs; } /* Similar groups of functions for pixmaps and text */ static int gl2psPrintPDFPixmapStreamData(GL2PSimage *im, int (*action)(unsigned long data, int size), int gray) { int x, y, shift; GLfloat r, g, b, a; if(im->format != GL_RGBA && gray) return 0; if(gray && gray != 8 && gray != 16) gray = 8; gray /= 8; shift = (sizeof(unsigned long) - 1) * 8; for(y = 0; y < im->height; ++y){ for(x = 0; x < im->width; ++x){ a = gl2psGetRGB(im, x, y, &r, &g, &b); if(im->format == GL_RGBA && gray){ (*action)((unsigned long)(a * 255) << shift, gray); } else{ (*action)((unsigned long)(r * 255) << shift, 1); (*action)((unsigned long)(g * 255) << shift, 1); (*action)((unsigned long)(b * 255) << shift, 1); } } } switch(gray){ case 0: return 3 * im->width * im->height; case 1: return im->width * im->height; case 2: return 2 * im->width * im->height; default: return 3 * im->width * im->height; } } static int gl2psPrintPDFPixmap(int obj, int childobj, GL2PSimage *im, int gray) { int offs = 0, done = 0, sigbytes = 3; if(gray && gray !=8 && gray != 16) gray = 8; if(gray) sigbytes = gray / 8; offs += fprintf(gl2ps->stream, "%d 0 obj\n" "<<\n" "/Type /XObject\n" "/Subtype /Image\n" "/Width %d\n" "/Height %d\n" "/ColorSpace %s \n" "/BitsPerComponent 8\n", obj, (int)im->width, (int)im->height, (gray) ? "/DeviceGray" : "/DeviceRGB" ); if(GL_RGBA == im->format && gray == 0){ offs += fprintf(gl2ps->stream, "/SMask %d 0 R\n", childobj); } #if defined(GL2PS_HAVE_ZLIB) if(gl2ps->options & GL2PS_COMPRESS){ gl2psAllocCompress((int)(im->width * im->height * sigbytes)); gl2psPrintPDFPixmapStreamData(im, gl2psWriteBigEndianCompress, gray); if(Z_OK == gl2psDeflate() && 23 + gl2ps->compress->destLen < gl2ps->compress->srcLen){ offs += gl2psPrintPDFCompressorType(); offs += fprintf(gl2ps->stream, "/Length %d " ">>\n" "stream\n", (int)gl2ps->compress->destLen); offs += gl2ps->compress->destLen * fwrite(gl2ps->compress->dest, gl2ps->compress->destLen, 1, gl2ps->stream); done = 1; } gl2psFreeCompress(); } #endif if(!done){ /* no compression, or too long after compression, or compress error -> write non-compressed entry */ offs += fprintf(gl2ps->stream, "/Length %d " ">>\n" "stream\n", (int)(im->width * im->height * sigbytes)); offs += gl2psPrintPDFPixmapStreamData(im, gl2psWriteBigEndian, gray); } offs += fprintf(gl2ps->stream, "\nendstream\n" "endobj\n"); return offs; } static int gl2psPrintPDFText(int obj, GL2PSstring *s, int fontnumber) { int offs = 0; offs += fprintf(gl2ps->stream, "%d 0 obj\n" "<<\n" "/Type /Font\n" "/Subtype /Type1\n" "/Name /F%d\n" "/BaseFont /%s\n" "/Encoding /MacRomanEncoding\n" ">>\n" "endobj\n", obj, fontnumber, s->fontname); return offs; } /* Write the physical objects */ static int gl2psPDFgroupListWriteObjects(int entryoffs) { int i,j; GL2PSprimitive *p = NULL; GL2PSpdfgroup *gro; int offs = entryoffs; GL2PStriangle *triangles; int size = 0; if(!gl2ps->pdfgrouplist) return offs; for(i = 0; i < gl2psListNbr(gl2ps->pdfgrouplist); ++i){ gro = (GL2PSpdfgroup*)gl2psListPointer(gl2ps->pdfgrouplist, i); if(!gl2psListNbr(gro->ptrlist)) continue; p = *(GL2PSprimitive**)gl2psListPointer(gro->ptrlist, 0); switch(p->type){ case GL2PS_POINT: break; case GL2PS_LINE: break; case GL2PS_TRIANGLE: size = gl2psListNbr(gro->ptrlist); triangles = (GL2PStriangle*)gl2psMalloc(sizeof(GL2PStriangle) * size); for(j = 0; j < size; ++j){ p = *(GL2PSprimitive**)gl2psListPointer(gro->ptrlist, j); gl2psFillTriangleFromPrimitive(&triangles[j], p, GL_TRUE); } if(triangles[0].prop & T_VAR_COLOR){ gl2ps->xreflist[gro->shobjno] = offs; offs += gl2psPrintPDFShader(gro->shobjno, triangles, size, 0); } if(triangles[0].prop & T_ALPHA_LESS_1){ gl2ps->xreflist[gro->gsobjno] = offs; offs += gl2psPrintPDFShaderSimpleExtGS(gro->gsobjno, triangles[0].vertex[0].rgba[3]); } if(triangles[0].prop & T_VAR_ALPHA){ gl2ps->xreflist[gro->gsobjno] = offs; offs += gl2psPrintPDFShaderExtGS(gro->gsobjno, gro->trgroupobjno); gl2ps->xreflist[gro->trgroupobjno] = offs; offs += gl2psPrintPDFShaderMask(gro->trgroupobjno, gro->maskshno); gl2ps->xreflist[gro->maskshobjno] = offs; offs += gl2psPrintPDFShader(gro->maskshobjno, triangles, size, 8); } gl2psFree(triangles); break; case GL2PS_PIXMAP: gl2ps->xreflist[gro->imobjno] = offs; offs += gl2psPrintPDFPixmap(gro->imobjno, gro->imobjno+1, p->data.image, 0); if(p->data.image->format == GL_RGBA){ gl2ps->xreflist[gro->imobjno+1] = offs; offs += gl2psPrintPDFPixmap(gro->imobjno+1, -1, p->data.image, 8); } break; case GL2PS_TEXT: gl2ps->xreflist[gro->fontobjno] = offs; offs += gl2psPrintPDFText(gro->fontobjno,p->data.text,gro->fontno); break; case GL2PS_SPECIAL : /* alignment contains the format for which the special output text is intended */ if(p->data.text->alignment == GL2PS_PDF) offs += fprintf(gl2ps->stream, "%s\n", p->data.text->str); break; default: break; } } return offs; } /* All variable data has been written at this point and all required functioninality has been gathered, so we can write now file footer with cross reference table and trailer */ static void gl2psPrintPDFFooter(void) { int i, offs; gl2psPDFgroupListInit(); gl2psPDFgroupListWriteMainStream(); offs = gl2ps->xreflist[5] + gl2ps->streamlength; offs += gl2psClosePDFDataStream(); gl2ps->xreflist[5] = offs; offs += gl2psPrintPDFDataStreamLength(gl2ps->streamlength); gl2ps->xreflist[6] = offs; gl2ps->streamlength = 0; offs += gl2psPrintPDFOpenPage(); offs += gl2psPDFgroupListWriteVariableResources(); gl2ps->xreflist = (int*)gl2psRealloc(gl2ps->xreflist, sizeof(int) * (gl2ps->objects_stack + 1)); gl2ps->xreflist[7] = offs; offs += gl2psPrintPDFGSObject(); gl2ps->xreflist[8] = offs; gl2ps->xreflist[gl2ps->objects_stack] = gl2psPDFgroupListWriteObjects(gl2ps->xreflist[8]); /* Start cross reference table. The file has to been opened in binary mode to preserve the 20 digit string length! */ fprintf(gl2ps->stream, "xref\n" "0 %d\n" "%010d 65535 f \n", gl2ps->objects_stack, 0); for(i = 1; i < gl2ps->objects_stack; ++i) fprintf(gl2ps->stream, "%010d 00000 n \n", gl2ps->xreflist[i]); fprintf(gl2ps->stream, "trailer\n" "<<\n" "/Size %d\n" "/Info 1 0 R\n" "/Root 2 0 R\n" ">>\n" "startxref\n%d\n" "%%%%EOF\n", gl2ps->objects_stack, gl2ps->xreflist[gl2ps->objects_stack]); /* Free auxiliary lists and arrays */ gl2psFree(gl2ps->xreflist); gl2psListAction(gl2ps->pdfprimlist, gl2psFreePrimitive); gl2psListDelete(gl2ps->pdfprimlist); gl2psPDFgroupListDelete(); #if defined(GL2PS_HAVE_ZLIB) if(gl2ps->options & GL2PS_COMPRESS){ gl2psFreeCompress(); gl2psFree(gl2ps->compress); gl2ps->compress = NULL; } #endif } /* PDF begin viewport */ static void gl2psPrintPDFBeginViewport(GLint viewport[4]) { int offs = 0; GLint idx; GLfloat rgba[4]; int x = viewport[0], y = viewport[1], w = viewport[2], h = viewport[3]; glRenderMode(GL_FEEDBACK); if(gl2ps->header){ gl2psPrintPDFHeader(); gl2ps->header = GL_FALSE; } offs += gl2psPrintf("q\n"); if(gl2ps->options & GL2PS_DRAW_BACKGROUND){ if(gl2ps->colormode == GL_RGBA || gl2ps->colorsize == 0){ glGetFloatv(GL_COLOR_CLEAR_VALUE, rgba); } else{ glGetIntegerv(GL_INDEX_CLEAR_VALUE, &idx); rgba[0] = gl2ps->colormap[idx][0]; rgba[1] = gl2ps->colormap[idx][1]; rgba[2] = gl2ps->colormap[idx][2]; rgba[3] = 1.0F; } offs += gl2psPrintPDFFillColor(rgba); offs += gl2psPrintf("%d %d %d %d re\n" "W\n" "f\n", x, y, w, h); } else{ offs += gl2psPrintf("%d %d %d %d re\n" "W\n" "n\n", x, y, w, h); } gl2ps->streamlength += offs; } static GLint gl2psPrintPDFEndViewport(void) { GLint res; res = gl2psPrintPrimitives(); gl2ps->streamlength += gl2psPrintf("Q\n"); return res; } static void gl2psPrintPDFFinalPrimitive(void) { } /* definition of the PDF backend */ static GL2PSbackend gl2psPDF = { gl2psPrintPDFHeader, gl2psPrintPDFFooter, gl2psPrintPDFBeginViewport, gl2psPrintPDFEndViewport, gl2psPrintPDFPrimitive, gl2psPrintPDFFinalPrimitive, "pdf", "Portable Document Format" }; /********************************************************************* * * SVG routines * *********************************************************************/ static void gl2psSVGGetCoordsAndColors(int n, GL2PSvertex *verts, GL2PSxyz *xyz, GL2PSrgba *rgba) { int i, j; for(i = 0; i < n; i++){ xyz[i][0] = verts[i].xyz[0]; xyz[i][1] = gl2ps->viewport[3] - verts[i].xyz[1]; xyz[i][2] = 0.0F; for(j = 0; j < 4; j++) rgba[i][j] = verts[i].rgba[j]; } } static void gl2psSVGGetColorString(GL2PSrgba rgba, char str[32]) { int r = (int)(255. * rgba[0]); int g = (int)(255. * rgba[1]); int b = (int)(255. * rgba[2]); int rc = (r < 0) ? 0 : (r > 255) ? 255 : r; int gc = (g < 0) ? 0 : (g > 255) ? 255 : g; int bc = (b < 0) ? 0 : (b > 255) ? 255 : b; sprintf(str, "#%2.2x%2.2x%2.2x", rc, gc, bc); } static void gl2psPrintSVGHeader(void) { int x, y, width, height; char col[32]; time_t now; time(&now); if (gl2ps->options & GL2PS_LANDSCAPE){ x = (int)gl2ps->viewport[1]; y = (int)gl2ps->viewport[0]; width = (int)gl2ps->viewport[3]; height = (int)gl2ps->viewport[2]; } else{ x = (int)gl2ps->viewport[0]; y = (int)gl2ps->viewport[1]; width = (int)gl2ps->viewport[2]; height = (int)gl2ps->viewport[3]; } /* Compressed SVG files (.svgz) are simply gzipped SVG files */ gl2psPrintGzipHeader(); gl2psPrintf("\n"); gl2psPrintf("\n", width, height, x, y, width, height); gl2psPrintf("%s\n", gl2ps->title); gl2psPrintf("\n"); gl2psPrintf("Creator: GL2PS %d.%d.%d%s, %s\n" "For: %s\n" "CreationDate: %s", GL2PS_MAJOR_VERSION, GL2PS_MINOR_VERSION, GL2PS_PATCH_VERSION, GL2PS_EXTRA_VERSION, GL2PS_COPYRIGHT, gl2ps->producer, ctime(&now)); gl2psPrintf("\n"); gl2psPrintf("\n"); gl2psPrintf("\n"); if(gl2ps->options & GL2PS_DRAW_BACKGROUND){ gl2psSVGGetColorString(gl2ps->bgcolor, col); gl2psPrintf("\n", col, (int)gl2ps->viewport[0], (int)gl2ps->viewport[1], (int)gl2ps->viewport[2], (int)gl2ps->viewport[1], (int)gl2ps->viewport[2], (int)gl2ps->viewport[3], (int)gl2ps->viewport[0], (int)gl2ps->viewport[3]); } /* group all the primitives and disable antialiasing */ gl2psPrintf("\n"); } static void gl2psPrintSVGSmoothTriangle(GL2PSxyz xyz[3], GL2PSrgba rgba[3]) { int i; GL2PSxyz xyz2[3]; GL2PSrgba rgba2[3]; char col[32]; /* Apparently there is no easy way to do Gouraud shading in SVG without explicitly pre-defining gradients, so for now we just do recursive subdivision */ if(gl2psSameColorThreshold(3, rgba, gl2ps->threshold)){ gl2psSVGGetColorString(rgba[0], col); gl2psPrintf("\n", xyz[0][0], xyz[0][1], xyz[1][0], xyz[1][1], xyz[2][0], xyz[2][1]); } else{ /* subdivide into 4 subtriangles */ for(i = 0; i < 3; i++){ xyz2[0][i] = xyz[0][i]; xyz2[1][i] = 0.5F * (xyz[0][i] + xyz[1][i]); xyz2[2][i] = 0.5F * (xyz[0][i] + xyz[2][i]); } for(i = 0; i < 4; i++){ rgba2[0][i] = rgba[0][i]; rgba2[1][i] = 0.5F * (rgba[0][i] + rgba[1][i]); rgba2[2][i] = 0.5F * (rgba[0][i] + rgba[2][i]); } gl2psPrintSVGSmoothTriangle(xyz2, rgba2); for(i = 0; i < 3; i++){ xyz2[0][i] = 0.5F * (xyz[0][i] + xyz[1][i]); xyz2[1][i] = xyz[1][i]; xyz2[2][i] = 0.5F * (xyz[1][i] + xyz[2][i]); } for(i = 0; i < 4; i++){ rgba2[0][i] = 0.5F * (rgba[0][i] + rgba[1][i]); rgba2[1][i] = rgba[1][i]; rgba2[2][i] = 0.5F * (rgba[1][i] + rgba[2][i]); } gl2psPrintSVGSmoothTriangle(xyz2, rgba2); for(i = 0; i < 3; i++){ xyz2[0][i] = 0.5F * (xyz[0][i] + xyz[2][i]); xyz2[1][i] = xyz[2][i]; xyz2[2][i] = 0.5F * (xyz[1][i] + xyz[2][i]); } for(i = 0; i < 4; i++){ rgba2[0][i] = 0.5F * (rgba[0][i] + rgba[2][i]); rgba2[1][i] = rgba[2][i]; rgba2[2][i] = 0.5F * (rgba[1][i] + rgba[2][i]); } gl2psPrintSVGSmoothTriangle(xyz2, rgba2); for(i = 0; i < 3; i++){ xyz2[0][i] = 0.5F * (xyz[0][i] + xyz[1][i]); xyz2[1][i] = 0.5F * (xyz[1][i] + xyz[2][i]); xyz2[2][i] = 0.5F * (xyz[0][i] + xyz[2][i]); } for(i = 0; i < 4; i++){ rgba2[0][i] = 0.5F * (rgba[0][i] + rgba[1][i]); rgba2[1][i] = 0.5F * (rgba[1][i] + rgba[2][i]); rgba2[2][i] = 0.5F * (rgba[0][i] + rgba[2][i]); } gl2psPrintSVGSmoothTriangle(xyz2, rgba2); } } static void gl2psPrintSVGDash(GLushort pattern, GLint factor) { int i, n, array[10]; if(!pattern || !factor) return; /* solid line */ gl2psParseStipplePattern(pattern, factor, &n, array); gl2psPrintf("stroke-dasharray=\""); for(i = 0; i < n; i++){ if(i) gl2psPrintf(","); gl2psPrintf("%d", array[i]); } gl2psPrintf("\" "); } static void gl2psEndSVGLine(void) { int i; if(gl2ps->lastvertex.rgba[0] >= 0.){ gl2psPrintf("%g,%g\"/>\n", gl2ps->lastvertex.xyz[0], gl2ps->viewport[3] - gl2ps->lastvertex.xyz[1]); for(i = 0; i < 3; i++) gl2ps->lastvertex.xyz[i] = -1.; for(i = 0; i < 4; i++) gl2ps->lastvertex.rgba[i] = -1.; } } static void gl2psPrintSVGPixmap(GLfloat x, GLfloat y, GL2PSimage *pixmap) { #if defined(GL2PS_HAVE_LIBPNG) GL2PSlist *png; unsigned char c; int i; /* The only image types supported by the SVG standard are JPEG, PNG and SVG. Here we choose PNG, and since we want to embed the image directly in the SVG stream (and not link to an external image file), we need to encode the pixmap into PNG in memory, then encode it into base64. */ png = gl2psListCreate(pixmap->width * pixmap->height * 3, 1000, sizeof(unsigned char)); gl2psConvertPixmapToPNG(pixmap, png); gl2psListEncodeBase64(png); gl2psPrintf("height, pixmap->width, pixmap->height); gl2psPrintf("xlink:href=\"data:image/png;base64,"); for(i = 0; i < gl2psListNbr(png); i++){ gl2psListRead(png, i, &c); gl2psPrintf("%c", c); } gl2psPrintf("\"/>\n"); gl2psListDelete(png); #else (void) x; (void) y; (void) pixmap; /* not used */ gl2psMsg(GL2PS_WARNING, "GL2PS must be compiled with PNG support in " "order to embed images in SVG streams"); #endif } static void gl2psPrintSVGPrimitive(void *data) { GL2PSprimitive *prim; GL2PSxyz xyz[4]; GL2PSrgba rgba[4]; char col[32]; int newline; prim = *(GL2PSprimitive**)data; if((gl2ps->options & GL2PS_OCCLUSION_CULL) && prim->culled) return; /* We try to draw connected lines as a single path to get nice line joins and correct stippling. So if the primitive to print is not a line we must first finish the current line (if any): */ if(prim->type != GL2PS_LINE) gl2psEndSVGLine(); gl2psSVGGetCoordsAndColors(prim->numverts, prim->verts, xyz, rgba); switch(prim->type){ case GL2PS_POINT : gl2psSVGGetColorString(rgba[0], col); gl2psPrintf("\n", xyz[0][0], xyz[0][1], 0.5 * prim->width); break; case GL2PS_LINE : if(!gl2psSamePosition(gl2ps->lastvertex.xyz, prim->verts[0].xyz) || !gl2psSameColor(gl2ps->lastrgba, prim->verts[0].rgba) || gl2ps->lastlinewidth != prim->width || gl2ps->lastpattern != prim->pattern || gl2ps->lastfactor != prim->factor){ /* End the current line if the new segment does not start where the last one ended, or if the color, the width or the stippling have changed (we will need to use multi-point gradients for smooth-shaded lines) */ gl2psEndSVGLine(); newline = 1; } else{ newline = 0; } gl2ps->lastvertex = prim->verts[1]; gl2psSetLastColor(prim->verts[0].rgba); gl2ps->lastlinewidth = prim->width; gl2ps->lastpattern = prim->pattern; gl2ps->lastfactor = prim->factor; if(newline){ gl2psSVGGetColorString(rgba[0], col); gl2psPrintf("width); if(rgba[0][3] < 1.0F) gl2psPrintf("stroke-opacity=\"%g\" ", rgba[0][3]); gl2psPrintSVGDash(prim->pattern, prim->factor); gl2psPrintf("points=\"%g,%g ", xyz[0][0], xyz[0][1]); } else{ gl2psPrintf("%g,%g ", xyz[0][0], xyz[0][1]); } break; case GL2PS_TRIANGLE : gl2psPrintSVGSmoothTriangle(xyz, rgba); break; case GL2PS_QUADRANGLE : gl2psMsg(GL2PS_WARNING, "There should not be any quad left to print"); break; case GL2PS_PIXMAP : gl2psPrintSVGPixmap(xyz[0][0], xyz[0][1], prim->data.image); break; case GL2PS_TEXT : gl2psSVGGetColorString(prim->verts[0].rgba, col); gl2psPrintf("data.text->fontsize); if(prim->data.text->angle) gl2psPrintf("transform=\"rotate(%g, %g, %g)\" ", -prim->data.text->angle, xyz[0][0], xyz[0][1]); switch(prim->data.text->alignment){ case GL2PS_TEXT_C: gl2psPrintf("text-anchor=\"middle\" baseline-shift=\"%d\" ", -prim->data.text->fontsize / 2); break; case GL2PS_TEXT_CL: gl2psPrintf("text-anchor=\"start\" baseline-shift=\"%d\" ", -prim->data.text->fontsize / 2); break; case GL2PS_TEXT_CR: gl2psPrintf("text-anchor=\"end\" baseline-shift=\"%d\" ", -prim->data.text->fontsize / 2); break; case GL2PS_TEXT_B: gl2psPrintf("text-anchor=\"middle\" baseline-shift=\"0\" "); break; case GL2PS_TEXT_BR: gl2psPrintf("text-anchor=\"end\" baseline-shift=\"0\" "); break; case GL2PS_TEXT_T: gl2psPrintf("text-anchor=\"middle\" baseline-shift=\"%d\" ", -prim->data.text->fontsize); break; case GL2PS_TEXT_TL: gl2psPrintf("text-anchor=\"start\" baseline-shift=\"%d\" ", -prim->data.text->fontsize); break; case GL2PS_TEXT_TR: gl2psPrintf("text-anchor=\"end\" baseline-shift=\"%d\" ", -prim->data.text->fontsize); break; case GL2PS_TEXT_BL: default: /* same as GL2PS_TEXT_BL */ gl2psPrintf("text-anchor=\"start\" baseline-shift=\"0\" "); break; } if(!strcmp(prim->data.text->fontname, "Times-Roman")) gl2psPrintf("font-family=\"Times\">"); else if(!strcmp(prim->data.text->fontname, "Times-Bold")) gl2psPrintf("font-family=\"Times\" font-weight=\"bold\">"); else if(!strcmp(prim->data.text->fontname, "Times-Italic")) gl2psPrintf("font-family=\"Times\" font-style=\"italic\">"); else if(!strcmp(prim->data.text->fontname, "Times-BoldItalic")) gl2psPrintf("font-family=\"Times\" font-style=\"italic\" font-weight=\"bold\">"); else if(!strcmp(prim->data.text->fontname, "Helvetica-Bold")) gl2psPrintf("font-family=\"Helvetica\" font-weight=\"bold\">"); else if(!strcmp(prim->data.text->fontname, "Helvetica-Oblique")) gl2psPrintf("font-family=\"Helvetica\" font-style=\"oblique\">"); else if(!strcmp(prim->data.text->fontname, "Helvetica-BoldOblique")) gl2psPrintf("font-family=\"Helvetica\" font-style=\"oblique\" font-weight=\"bold\">"); else if(!strcmp(prim->data.text->fontname, "Courier-Bold")) gl2psPrintf("font-family=\"Courier\" font-weight=\"bold\">"); else if(!strcmp(prim->data.text->fontname, "Courier-Oblique")) gl2psPrintf("font-family=\"Courier\" font-style=\"oblique\">"); else if(!strcmp(prim->data.text->fontname, "Courier-BoldOblique")) gl2psPrintf("font-family=\"Courier\" font-style=\"oblique\" font-weight=\"bold\">"); else gl2psPrintf("font-family=\"%s\">", prim->data.text->fontname); gl2psPrintf("%s\n", prim->data.text->str); break; case GL2PS_SPECIAL : /* alignment contains the format for which the special output text is intended */ if(prim->data.text->alignment == GL2PS_SVG) gl2psPrintf("%s\n", prim->data.text->str); break; default : break; } } static void gl2psPrintSVGFooter(void) { gl2psPrintf("\n"); gl2psPrintf("\n"); gl2psPrintGzipFooter(); } static void gl2psPrintSVGBeginViewport(GLint viewport[4]) { GLint idx; char col[32]; GLfloat rgba[4]; int x = viewport[0], y = viewport[1], w = viewport[2], h = viewport[3]; glRenderMode(GL_FEEDBACK); if(gl2ps->header){ gl2psPrintSVGHeader(); gl2ps->header = GL_FALSE; } if(gl2ps->options & GL2PS_DRAW_BACKGROUND){ if(gl2ps->colormode == GL_RGBA || gl2ps->colorsize == 0){ glGetFloatv(GL_COLOR_CLEAR_VALUE, rgba); } else{ glGetIntegerv(GL_INDEX_CLEAR_VALUE, &idx); rgba[0] = gl2ps->colormap[idx][0]; rgba[1] = gl2ps->colormap[idx][1]; rgba[2] = gl2ps->colormap[idx][2]; rgba[3] = 1.0F; } gl2psSVGGetColorString(rgba, col); gl2psPrintf("\n", col, x, gl2ps->viewport[3] - y, x + w, gl2ps->viewport[3] - y, x + w, gl2ps->viewport[3] - (y + h), x, gl2ps->viewport[3] - (y + h)); } gl2psPrintf("\n", x, y, w, h); gl2psPrintf(" \n", x, gl2ps->viewport[3] - y, x + w, gl2ps->viewport[3] - y, x + w, gl2ps->viewport[3] - (y + h), x, gl2ps->viewport[3] - (y + h)); gl2psPrintf("\n"); gl2psPrintf("\n", x, y, w, h); } static GLint gl2psPrintSVGEndViewport(void) { GLint res; res = gl2psPrintPrimitives(); gl2psPrintf("\n"); return res; } static void gl2psPrintSVGFinalPrimitive(void) { /* End any remaining line, if any */ gl2psEndSVGLine(); } /* definition of the SVG backend */ static GL2PSbackend gl2psSVG = { gl2psPrintSVGHeader, gl2psPrintSVGFooter, gl2psPrintSVGBeginViewport, gl2psPrintSVGEndViewport, gl2psPrintSVGPrimitive, gl2psPrintSVGFinalPrimitive, "svg", "Scalable Vector Graphics" }; /********************************************************************* * * PGF routines * *********************************************************************/ static void gl2psPrintPGFColor(GL2PSrgba rgba) { if(!gl2psSameColor(gl2ps->lastrgba, rgba)){ gl2psSetLastColor(rgba); fprintf(gl2ps->stream, "\\color[rgb]{%f,%f,%f}\n", rgba[0], rgba[1], rgba[2]); } } static void gl2psPrintPGFHeader(void) { time_t now; time(&now); fprintf(gl2ps->stream, "%% Title: %s\n" "%% Creator: GL2PS %d.%d.%d%s, %s\n" "%% For: %s\n" "%% CreationDate: %s", gl2ps->title, GL2PS_MAJOR_VERSION, GL2PS_MINOR_VERSION, GL2PS_PATCH_VERSION, GL2PS_EXTRA_VERSION, GL2PS_COPYRIGHT, gl2ps->producer, ctime(&now)); fprintf(gl2ps->stream, "\\begin{pgfpicture}\n"); if(gl2ps->options & GL2PS_DRAW_BACKGROUND){ gl2psPrintPGFColor(gl2ps->bgcolor); fprintf(gl2ps->stream, "\\pgfpathrectanglecorners{" "\\pgfpoint{%dpt}{%dpt}}{\\pgfpoint{%dpt}{%dpt}}\n" "\\pgfusepath{fill}\n", (int)gl2ps->viewport[0], (int)gl2ps->viewport[1], (int)gl2ps->viewport[2], (int)gl2ps->viewport[3]); } } static void gl2psPrintPGFDash(GLushort pattern, GLint factor) { int i, n, array[10]; if(pattern == gl2ps->lastpattern && factor == gl2ps->lastfactor) return; gl2ps->lastpattern = pattern; gl2ps->lastfactor = factor; if(!pattern || !factor){ /* solid line */ fprintf(gl2ps->stream, "\\pgfsetdash{}{0pt}\n"); } else{ gl2psParseStipplePattern(pattern, factor, &n, array); fprintf(gl2ps->stream, "\\pgfsetdash{"); for(i = 0; i < n; i++) fprintf(gl2ps->stream, "{%dpt}", array[i]); fprintf(gl2ps->stream, "}{0pt}\n"); } } static const char *gl2psPGFTextAlignment(int align) { switch(align){ case GL2PS_TEXT_C : return "center"; case GL2PS_TEXT_CL : return "west"; case GL2PS_TEXT_CR : return "east"; case GL2PS_TEXT_B : return "south"; case GL2PS_TEXT_BR : return "south east"; case GL2PS_TEXT_T : return "north"; case GL2PS_TEXT_TL : return "north west"; case GL2PS_TEXT_TR : return "north east"; case GL2PS_TEXT_BL : default : return "south west"; } } static void gl2psPrintPGFPrimitive(void *data) { GL2PSprimitive *prim; prim = *(GL2PSprimitive**)data; switch(prim->type){ case GL2PS_POINT : /* Points in openGL are rectangular */ gl2psPrintPGFColor(prim->verts[0].rgba); fprintf(gl2ps->stream, "\\pgfpathrectangle{\\pgfpoint{%fpt}{%fpt}}" "{\\pgfpoint{%fpt}{%fpt}}\n\\pgfusepath{fill}\n", prim->verts[0].xyz[0]-0.5*prim->width, prim->verts[0].xyz[1]-0.5*prim->width, prim->width,prim->width); break; case GL2PS_LINE : gl2psPrintPGFColor(prim->verts[0].rgba); if(gl2ps->lastlinewidth != prim->width){ gl2ps->lastlinewidth = prim->width; fprintf(gl2ps->stream, "\\pgfsetlinewidth{%fpt}\n", gl2ps->lastlinewidth); } gl2psPrintPGFDash(prim->pattern, prim->factor); fprintf(gl2ps->stream, "\\pgfpathmoveto{\\pgfpoint{%fpt}{%fpt}}\n" "\\pgflineto{\\pgfpoint{%fpt}{%fpt}}\n" "\\pgfusepath{stroke}\n", prim->verts[1].xyz[0], prim->verts[1].xyz[1], prim->verts[0].xyz[0], prim->verts[0].xyz[1]); break; case GL2PS_TRIANGLE : if(gl2ps->lastlinewidth != 0){ gl2ps->lastlinewidth = 0; fprintf(gl2ps->stream, "\\pgfsetlinewidth{0.01pt}\n"); } gl2psPrintPGFColor(prim->verts[0].rgba); fprintf(gl2ps->stream, "\\pgfpathmoveto{\\pgfpoint{%fpt}{%fpt}}\n" "\\pgflineto{\\pgfpoint{%fpt}{%fpt}}\n" "\\pgflineto{\\pgfpoint{%fpt}{%fpt}}\n" "\\pgfpathclose\n" "\\pgfusepath{fill,stroke}\n", prim->verts[2].xyz[0], prim->verts[2].xyz[1], prim->verts[1].xyz[0], prim->verts[1].xyz[1], prim->verts[0].xyz[0], prim->verts[0].xyz[1]); break; case GL2PS_TEXT : fprintf(gl2ps->stream, "{\n\\pgftransformshift{\\pgfpoint{%fpt}{%fpt}}\n", prim->verts[0].xyz[0], prim->verts[0].xyz[1]); if(prim->data.text->angle) fprintf(gl2ps->stream, "\\pgftransformrotate{%f}{", prim->data.text->angle); fprintf(gl2ps->stream, "\\pgfnode{rectangle}{%s}{\\fontsize{%d}{0}\\selectfont", gl2psPGFTextAlignment(prim->data.text->alignment), prim->data.text->fontsize); fprintf(gl2ps->stream, "\\textcolor[rgb]{%g,%g,%g}{{%s}}", prim->verts[0].rgba[0], prim->verts[0].rgba[1], prim->verts[0].rgba[2], prim->data.text->str); fprintf(gl2ps->stream, "}{}{\\pgfusepath{discard}}}\n"); break; case GL2PS_SPECIAL : /* alignment contains the format for which the special output text is intended */ if (prim->data.text->alignment == GL2PS_PGF) fprintf(gl2ps->stream, "%s\n", prim->data.text->str); break; default : break; } } static void gl2psPrintPGFFooter(void) { fprintf(gl2ps->stream, "\\end{pgfpicture}\n"); } static void gl2psPrintPGFBeginViewport(GLint viewport[4]) { GLint idx; GLfloat rgba[4]; int x = viewport[0], y = viewport[1], w = viewport[2], h = viewport[3]; glRenderMode(GL_FEEDBACK); if(gl2ps->header){ gl2psPrintPGFHeader(); gl2ps->header = GL_FALSE; } fprintf(gl2ps->stream, "\\begin{pgfscope}\n"); if(gl2ps->options & GL2PS_DRAW_BACKGROUND){ if(gl2ps->colormode == GL_RGBA || gl2ps->colorsize == 0){ glGetFloatv(GL_COLOR_CLEAR_VALUE, rgba); } else{ glGetIntegerv(GL_INDEX_CLEAR_VALUE, &idx); rgba[0] = gl2ps->colormap[idx][0]; rgba[1] = gl2ps->colormap[idx][1]; rgba[2] = gl2ps->colormap[idx][2]; rgba[3] = 1.0F; } gl2psPrintPGFColor(rgba); fprintf(gl2ps->stream, "\\pgfpathrectangle{\\pgfpoint{%dpt}{%dpt}}" "{\\pgfpoint{%dpt}{%dpt}}\n" "\\pgfusepath{fill}\n", x, y, w, h); } fprintf(gl2ps->stream, "\\pgfpathrectangle{\\pgfpoint{%dpt}{%dpt}}" "{\\pgfpoint{%dpt}{%dpt}}\n" "\\pgfusepath{clip}\n", x, y, w, h); } static GLint gl2psPrintPGFEndViewport(void) { GLint res; res = gl2psPrintPrimitives(); fprintf(gl2ps->stream, "\\end{pgfscope}\n"); return res; } static void gl2psPrintPGFFinalPrimitive(void) { } /* definition of the PGF backend */ static GL2PSbackend gl2psPGF = { gl2psPrintPGFHeader, gl2psPrintPGFFooter, gl2psPrintPGFBeginViewport, gl2psPrintPGFEndViewport, gl2psPrintPGFPrimitive, gl2psPrintPGFFinalPrimitive, "tex", "PGF Latex Graphics" }; /********************************************************************* * * General primitive printing routine * *********************************************************************/ /* Warning: the ordering of the backends must match the format #defines in gl2ps.h */ static GL2PSbackend *gl2psbackends[] = { &gl2psPS, /* 0 */ &gl2psEPS, /* 1 */ &gl2psTEX, /* 2 */ &gl2psPDF, /* 3 */ &gl2psSVG, /* 4 */ &gl2psPGF /* 5 */ }; static void gl2psComputeTightBoundingBox(void *data) { GL2PSprimitive *prim; int i; prim = *(GL2PSprimitive**)data; for(i = 0; i < prim->numverts; i++){ if(prim->verts[i].xyz[0] < gl2ps->viewport[0]) gl2ps->viewport[0] = (GLint)prim->verts[i].xyz[0]; if(prim->verts[i].xyz[0] > gl2ps->viewport[2]) gl2ps->viewport[2] = (GLint)(prim->verts[i].xyz[0] + 0.5F); if(prim->verts[i].xyz[1] < gl2ps->viewport[1]) gl2ps->viewport[1] = (GLint)prim->verts[i].xyz[1]; if(prim->verts[i].xyz[1] > gl2ps->viewport[3]) gl2ps->viewport[3] = (GLint)(prim->verts[i].xyz[1] + 0.5F); } } static GLint gl2psPrintPrimitives(void) { GL2PSbsptree *root; GL2PSxyz eye = {0.0F, 0.0F, 100.0F * GL2PS_ZSCALE}; GLint used; used = glRenderMode(GL_RENDER); if(used < 0){ gl2psMsg(GL2PS_INFO, "OpenGL feedback buffer overflow"); return GL2PS_OVERFLOW; } if(used > 0) gl2psParseFeedbackBuffer(used); gl2psRescaleAndOffset(); if(gl2ps->header){ if(gl2psListNbr(gl2ps->primitives) && (gl2ps->options & GL2PS_TIGHT_BOUNDING_BOX)){ gl2ps->viewport[0] = gl2ps->viewport[1] = 100000; gl2ps->viewport[2] = gl2ps->viewport[3] = -100000; gl2psListAction(gl2ps->primitives, gl2psComputeTightBoundingBox); } (gl2psbackends[gl2ps->format]->printHeader)(); gl2ps->header = GL_FALSE; } if(!gl2psListNbr(gl2ps->primitives)){ /* empty feedback buffer and/or nothing else to print */ return GL2PS_NO_FEEDBACK; } switch(gl2ps->sort){ case GL2PS_NO_SORT : gl2psListAction(gl2ps->primitives, gl2psbackends[gl2ps->format]->printPrimitive); gl2psListAction(gl2ps->primitives, gl2psFreePrimitive); /* reset the primitive list, waiting for the next viewport */ gl2psListReset(gl2ps->primitives); break; case GL2PS_SIMPLE_SORT : gl2psListSort(gl2ps->primitives, gl2psCompareDepth); if(gl2ps->options & GL2PS_OCCLUSION_CULL){ gl2psListActionInverse(gl2ps->primitives, gl2psAddInImageTree); gl2psFreeBspImageTree(&gl2ps->imagetree); } gl2psListAction(gl2ps->primitives, gl2psbackends[gl2ps->format]->printPrimitive); gl2psListAction(gl2ps->primitives, gl2psFreePrimitive); /* reset the primitive list, waiting for the next viewport */ gl2psListReset(gl2ps->primitives); break; case GL2PS_BSP_SORT : root = (GL2PSbsptree*)gl2psMalloc(sizeof(GL2PSbsptree)); gl2psBuildBspTree(root, gl2ps->primitives); if(GL_TRUE == gl2ps->boundary) gl2psBuildPolygonBoundary(root); if(gl2ps->options & GL2PS_OCCLUSION_CULL){ gl2psTraverseBspTree(root, eye, -GL2PS_EPSILON, gl2psLess, gl2psAddInImageTree, 1); gl2psFreeBspImageTree(&gl2ps->imagetree); } gl2psTraverseBspTree(root, eye, GL2PS_EPSILON, gl2psGreater, gl2psbackends[gl2ps->format]->printPrimitive, 0); gl2psFreeBspTree(&root); /* reallocate the primitive list (it's been deleted by gl2psBuildBspTree) in case there is another viewport */ gl2ps->primitives = gl2psListCreate(500, 500, sizeof(GL2PSprimitive*)); break; } gl2psbackends[gl2ps->format]->printFinalPrimitive(); return GL2PS_SUCCESS; } /********************************************************************* * * Public routines * *********************************************************************/ GL2PSDLL_API GLint gl2psBeginPage(const char *title, const char *producer, GLint viewport[4], GLint format, GLint sort, GLint options, GLint colormode, GLint colorsize, GL2PSrgba *colormap, GLint nr, GLint ng, GLint nb, GLint buffersize, FILE *stream, const char *filename) { GLint idx; int i; if(gl2ps){ gl2psMsg(GL2PS_ERROR, "gl2psBeginPage called in wrong program state"); return GL2PS_ERROR; } gl2ps = (GL2PScontext*)gl2psMalloc(sizeof(GL2PScontext)); if(format >= 0 && format < (GLint)(sizeof(gl2psbackends) / sizeof(gl2psbackends[0]))){ gl2ps->format = format; } else { gl2psMsg(GL2PS_ERROR, "Unknown output format: %d", format); gl2psFree(gl2ps); gl2ps = NULL; return GL2PS_ERROR; } switch(sort){ case GL2PS_NO_SORT : case GL2PS_SIMPLE_SORT : case GL2PS_BSP_SORT : gl2ps->sort = sort; break; default : gl2psMsg(GL2PS_ERROR, "Unknown sorting algorithm: %d", sort); gl2psFree(gl2ps); gl2ps = NULL; return GL2PS_ERROR; } if(stream){ gl2ps->stream = stream; } else{ gl2psMsg(GL2PS_ERROR, "Bad file pointer"); gl2psFree(gl2ps); gl2ps = NULL; return GL2PS_ERROR; } gl2ps->header = GL_TRUE; gl2ps->maxbestroot = 10; gl2ps->options = options; gl2ps->compress = NULL; gl2ps->imagemap_head = NULL; gl2ps->imagemap_tail = NULL; if(gl2ps->options & GL2PS_USE_CURRENT_VIEWPORT){ glGetIntegerv(GL_VIEWPORT, gl2ps->viewport); } else{ for(i = 0; i < 4; i++){ gl2ps->viewport[i] = viewport[i]; } } if(!gl2ps->viewport[2] || !gl2ps->viewport[3]){ gl2psMsg(GL2PS_ERROR, "Incorrect viewport (x=%d, y=%d, width=%d, height=%d)", gl2ps->viewport[0], gl2ps->viewport[1], gl2ps->viewport[2], gl2ps->viewport[3]); gl2psFree(gl2ps); gl2ps = NULL; return GL2PS_ERROR; } gl2ps->threshold[0] = nr ? 1.0F / (GLfloat)nr : 0.064F; gl2ps->threshold[1] = ng ? 1.0F / (GLfloat)ng : 0.034F; gl2ps->threshold[2] = nb ? 1.0F / (GLfloat)nb : 0.100F; gl2ps->colormode = colormode; gl2ps->buffersize = buffersize > 0 ? buffersize : 2048 * 2048; for(i = 0; i < 3; i++){ gl2ps->lastvertex.xyz[i] = -1.0F; } for(i = 0; i < 4; i++){ gl2ps->lastvertex.rgba[i] = -1.0F; gl2ps->lastrgba[i] = -1.0F; } gl2ps->lastlinewidth = -1.0F; gl2ps->lastpattern = 0; gl2ps->lastfactor = 0; gl2ps->imagetree = NULL; gl2ps->primitivetoadd = NULL; gl2ps->zerosurfacearea = GL_FALSE; gl2ps->pdfprimlist = NULL; gl2ps->pdfgrouplist = NULL; gl2ps->xreflist = NULL; /* get default blending mode from current OpenGL state (enabled by default for SVG) */ gl2ps->blending = (gl2ps->format == GL2PS_SVG) ? GL_TRUE : glIsEnabled(GL_BLEND); glGetIntegerv(GL_BLEND_SRC, &gl2ps->blendfunc[0]); glGetIntegerv(GL_BLEND_DST, &gl2ps->blendfunc[1]); if(gl2ps->colormode == GL_RGBA){ gl2ps->colorsize = 0; gl2ps->colormap = NULL; glGetFloatv(GL_COLOR_CLEAR_VALUE, gl2ps->bgcolor); } else if(gl2ps->colormode == GL_COLOR_INDEX){ if(!colorsize || !colormap){ gl2psMsg(GL2PS_ERROR, "Missing colormap for GL_COLOR_INDEX rendering"); gl2psFree(gl2ps); gl2ps = NULL; return GL2PS_ERROR; } gl2ps->colorsize = colorsize; gl2ps->colormap = (GL2PSrgba*)gl2psMalloc(gl2ps->colorsize * sizeof(GL2PSrgba)); memcpy(gl2ps->colormap, colormap, gl2ps->colorsize * sizeof(GL2PSrgba)); glGetIntegerv(GL_INDEX_CLEAR_VALUE, &idx); gl2ps->bgcolor[0] = gl2ps->colormap[idx][0]; gl2ps->bgcolor[1] = gl2ps->colormap[idx][1]; gl2ps->bgcolor[2] = gl2ps->colormap[idx][2]; gl2ps->bgcolor[3] = 1.0F; } else{ gl2psMsg(GL2PS_ERROR, "Unknown color mode in gl2psBeginPage"); gl2psFree(gl2ps); gl2ps = NULL; return GL2PS_ERROR; } if(!title){ gl2ps->title = (char*)gl2psMalloc(sizeof(char)); gl2ps->title[0] = '\0'; } else{ gl2ps->title = (char*)gl2psMalloc((strlen(title)+1)*sizeof(char)); strcpy(gl2ps->title, title); } if(!producer){ gl2ps->producer = (char*)gl2psMalloc(sizeof(char)); gl2ps->producer[0] = '\0'; } else{ gl2ps->producer = (char*)gl2psMalloc((strlen(producer)+1)*sizeof(char)); strcpy(gl2ps->producer, producer); } if(!filename){ gl2ps->filename = (char*)gl2psMalloc(sizeof(char)); gl2ps->filename[0] = '\0'; } else{ gl2ps->filename = (char*)gl2psMalloc((strlen(filename)+1)*sizeof(char)); strcpy(gl2ps->filename, filename); } gl2ps->primitives = gl2psListCreate(500, 500, sizeof(GL2PSprimitive*)); gl2ps->auxprimitives = gl2psListCreate(100, 100, sizeof(GL2PSprimitive*)); gl2ps->feedback = (GLfloat*)gl2psMalloc(gl2ps->buffersize * sizeof(GLfloat)); glFeedbackBuffer(gl2ps->buffersize, GL_3D_COLOR, gl2ps->feedback); glRenderMode(GL_FEEDBACK); return GL2PS_SUCCESS; } GL2PSDLL_API GLint gl2psEndPage(void) { GLint res; if(!gl2ps) return GL2PS_UNINITIALIZED; res = gl2psPrintPrimitives(); if(res != GL2PS_OVERFLOW) (gl2psbackends[gl2ps->format]->printFooter)(); fflush(gl2ps->stream); gl2psListDelete(gl2ps->primitives); gl2psListDelete(gl2ps->auxprimitives); gl2psFreeImagemap(gl2ps->imagemap_head); gl2psFree(gl2ps->colormap); gl2psFree(gl2ps->title); gl2psFree(gl2ps->producer); gl2psFree(gl2ps->filename); gl2psFree(gl2ps->feedback); gl2psFree(gl2ps); gl2ps = NULL; return res; } GL2PSDLL_API GLint gl2psBeginViewport(GLint viewport[4]) { if(!gl2ps) return GL2PS_UNINITIALIZED; (gl2psbackends[gl2ps->format]->beginViewport)(viewport); return GL2PS_SUCCESS; } GL2PSDLL_API GLint gl2psEndViewport(void) { GLint res; if(!gl2ps) return GL2PS_UNINITIALIZED; res = (gl2psbackends[gl2ps->format]->endViewport)(); /* reset last used colors, line widths */ gl2ps->lastlinewidth = -1.0F; return res; } GL2PSDLL_API GLint gl2psTextOptColor(const char *str, const char *fontname, GLshort fontsize, GLint alignment, GLfloat angle, GL2PSrgba color) { return gl2psAddText(GL2PS_TEXT, str, fontname, fontsize, alignment, angle, color); } GL2PSDLL_API GLint gl2psTextOpt(const char *str, const char *fontname, GLshort fontsize, GLint alignment, GLfloat angle) { return gl2psAddText(GL2PS_TEXT, str, fontname, fontsize, alignment, angle, NULL); } GL2PSDLL_API GLint gl2psText(const char *str, const char *fontname, GLshort fontsize) { return gl2psAddText(GL2PS_TEXT, str, fontname, fontsize, GL2PS_TEXT_BL, 0.0F, NULL); } GL2PSDLL_API GLint gl2psSpecial(GLint format, const char *str) { return gl2psAddText(GL2PS_SPECIAL, str, "", 0, format, 0.0F, NULL); } GL2PSDLL_API GLint gl2psDrawPixels(GLsizei width, GLsizei height, GLint xorig, GLint yorig, GLenum format, GLenum type, const void *pixels) { int size, i; const GLfloat *piv; GLfloat pos[4], zoom_x, zoom_y; GL2PSprimitive *prim; GLboolean valid; if(!gl2ps || !pixels) return GL2PS_UNINITIALIZED; if((width <= 0) || (height <= 0)) return GL2PS_ERROR; if(gl2ps->options & GL2PS_NO_PIXMAP) return GL2PS_SUCCESS; if((format != GL_RGB && format != GL_RGBA) || type != GL_FLOAT){ gl2psMsg(GL2PS_ERROR, "gl2psDrawPixels only implemented for " "GL_RGB/GL_RGBA, GL_FLOAT pixels"); return GL2PS_ERROR; } glGetBooleanv(GL_CURRENT_RASTER_POSITION_VALID, &valid); if(GL_FALSE == valid) return GL2PS_SUCCESS; /* the primitive is culled */ glGetFloatv(GL_CURRENT_RASTER_POSITION, pos); glGetFloatv(GL_ZOOM_X, &zoom_x); glGetFloatv(GL_ZOOM_Y, &zoom_y); prim = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive)); prim->type = GL2PS_PIXMAP; prim->boundary = 0; prim->numverts = 1; prim->verts = (GL2PSvertex*)gl2psMalloc(sizeof(GL2PSvertex)); prim->verts[0].xyz[0] = pos[0] + xorig; prim->verts[0].xyz[1] = pos[1] + yorig; prim->verts[0].xyz[2] = pos[2]; prim->culled = 0; prim->offset = 0; prim->pattern = 0; prim->factor = 0; prim->width = 1; glGetFloatv(GL_CURRENT_RASTER_COLOR, prim->verts[0].rgba); prim->data.image = (GL2PSimage*)gl2psMalloc(sizeof(GL2PSimage)); prim->data.image->width = width; prim->data.image->height = height; prim->data.image->zoom_x = zoom_x; prim->data.image->zoom_y = zoom_y; prim->data.image->format = format; prim->data.image->type = type; switch(format){ case GL_RGBA: if(gl2ps->options & GL2PS_NO_BLENDING || !gl2ps->blending){ /* special case: blending turned off */ prim->data.image->format = GL_RGB; size = height * width * 3; prim->data.image->pixels = (GLfloat*)gl2psMalloc(size * sizeof(GLfloat)); piv = (const GLfloat*)pixels; for(i = 0; i < size; ++i, ++piv){ prim->data.image->pixels[i] = *piv; if(!((i + 1) % 3)) ++piv; } } else{ size = height * width * 4; prim->data.image->pixels = (GLfloat*)gl2psMalloc(size * sizeof(GLfloat)); memcpy(prim->data.image->pixels, pixels, size * sizeof(GLfloat)); } break; case GL_RGB: default: size = height * width * 3; prim->data.image->pixels = (GLfloat*)gl2psMalloc(size * sizeof(GLfloat)); memcpy(prim->data.image->pixels, pixels, size * sizeof(GLfloat)); break; } gl2psListAdd(gl2ps->auxprimitives, &prim); glPassThrough(GL2PS_DRAW_PIXELS_TOKEN); return GL2PS_SUCCESS; } GL2PSDLL_API GLint gl2psDrawImageMap(GLsizei width, GLsizei height, const GLfloat position[3], const unsigned char *imagemap){ int size, i; int sizeoffloat = sizeof(GLfloat); if(!gl2ps || !imagemap) return GL2PS_UNINITIALIZED; if((width <= 0) || (height <= 0)) return GL2PS_ERROR; size = height + height * ((width - 1) / 8); glPassThrough(GL2PS_IMAGEMAP_TOKEN); glBegin(GL_POINTS); glVertex3f(position[0], position[1],position[2]); glEnd(); glPassThrough((GLfloat)width); glPassThrough((GLfloat)height); for(i = 0; i < size; i += sizeoffloat){ const float *value = (const float*)imagemap; glPassThrough(*value); imagemap += sizeoffloat; } return GL2PS_SUCCESS; } GL2PSDLL_API GLint gl2psEnable(GLint mode) { GLint tmp; if(!gl2ps) return GL2PS_UNINITIALIZED; switch(mode){ case GL2PS_POLYGON_OFFSET_FILL : glPassThrough(GL2PS_BEGIN_OFFSET_TOKEN); glGetFloatv(GL_POLYGON_OFFSET_FACTOR, &gl2ps->offset[0]); glGetFloatv(GL_POLYGON_OFFSET_UNITS, &gl2ps->offset[1]); break; case GL2PS_POLYGON_BOUNDARY : glPassThrough(GL2PS_BEGIN_BOUNDARY_TOKEN); break; case GL2PS_LINE_STIPPLE : glPassThrough(GL2PS_BEGIN_STIPPLE_TOKEN); glGetIntegerv(GL_LINE_STIPPLE_PATTERN, &tmp); glPassThrough((GLfloat)tmp); glGetIntegerv(GL_LINE_STIPPLE_REPEAT, &tmp); glPassThrough((GLfloat)tmp); break; case GL2PS_BLEND : glPassThrough(GL2PS_BEGIN_BLEND_TOKEN); break; default : gl2psMsg(GL2PS_WARNING, "Unknown mode in gl2psEnable: %d", mode); return GL2PS_WARNING; } return GL2PS_SUCCESS; } GL2PSDLL_API GLint gl2psDisable(GLint mode) { if(!gl2ps) return GL2PS_UNINITIALIZED; switch(mode){ case GL2PS_POLYGON_OFFSET_FILL : glPassThrough(GL2PS_END_OFFSET_TOKEN); break; case GL2PS_POLYGON_BOUNDARY : glPassThrough(GL2PS_END_BOUNDARY_TOKEN); break; case GL2PS_LINE_STIPPLE : glPassThrough(GL2PS_END_STIPPLE_TOKEN); break; case GL2PS_BLEND : glPassThrough(GL2PS_END_BLEND_TOKEN); break; default : gl2psMsg(GL2PS_WARNING, "Unknown mode in gl2psDisable: %d", mode); return GL2PS_WARNING; } return GL2PS_SUCCESS; } GL2PSDLL_API GLint gl2psPointSize(GLfloat value) { if(!gl2ps) return GL2PS_UNINITIALIZED; glPassThrough(GL2PS_POINT_SIZE_TOKEN); glPassThrough(value); return GL2PS_SUCCESS; } GL2PSDLL_API GLint gl2psLineWidth(GLfloat value) { if(!gl2ps) return GL2PS_UNINITIALIZED; glPassThrough(GL2PS_LINE_WIDTH_TOKEN); glPassThrough(value); return GL2PS_SUCCESS; } GL2PSDLL_API GLint gl2psBlendFunc(GLenum sfactor, GLenum dfactor) { if(!gl2ps) return GL2PS_UNINITIALIZED; if(GL_FALSE == gl2psSupportedBlendMode(sfactor, dfactor)) return GL2PS_WARNING; glPassThrough(GL2PS_SRC_BLEND_TOKEN); glPassThrough((GLfloat)sfactor); glPassThrough(GL2PS_DST_BLEND_TOKEN); glPassThrough((GLfloat)dfactor); return GL2PS_SUCCESS; } GL2PSDLL_API GLint gl2psSetOptions(GLint options) { if(!gl2ps) return GL2PS_UNINITIALIZED; gl2ps->options = options; return GL2PS_SUCCESS; } GL2PSDLL_API GLint gl2psGetOptions(GLint *options) { if(!gl2ps) { *options = 0; return GL2PS_UNINITIALIZED; } *options = gl2ps->options; return GL2PS_SUCCESS; } GL2PSDLL_API const char *gl2psGetFileExtension(GLint format) { if(format >= 0 && format < (GLint)(sizeof(gl2psbackends) / sizeof(gl2psbackends[0]))) return gl2psbackends[format]->file_extension; else return "Unknown format"; } GL2PSDLL_API const char *gl2psGetFormatDescription(GLint format) { if(format >= 0 && format < (GLint)(sizeof(gl2psbackends) / sizeof(gl2psbackends[0]))) return gl2psbackends[format]->description; else return "Unknown format"; } GL2PSDLL_API GLint gl2psGetFileFormat() { return gl2ps->format; } snd-16.1/snd-prefs.c0000644000076400007640000037455012471707040012420 0ustar bilbil/* this file included as text in snd-g|xprefs.c */ static void int_to_textfield(widget_t w, int val) { char *str; str = (char *)calloc(16, sizeof(char)); snprintf(str, 16, "%d", val); SET_TEXT(w, str); free(str); } static void mus_long_t_to_textfield(widget_t w, mus_long_t val) { char *str; str = (char *)calloc(32, sizeof(char)); snprintf(str, 32, "%lld", val); SET_TEXT(w, str); free(str); } static void float_to_textfield(widget_t w, mus_float_t val) { char *str; str = (char *)calloc(12, sizeof(char)); snprintf(str, 12, "%.3f", val); SET_TEXT(w, str); free(str); } static void float_1_to_textfield(widget_t w, mus_float_t val) { char *str; str = (char *)calloc(12, sizeof(char)); snprintf(str, 12, "%.1f", val); SET_TEXT(w, str); free(str); } static TIMEOUT_TYPE unpost_any_error(TIMEOUT_ARGS) { prefs_info *prf = (prefs_info *)context; prf->got_error = false; black_text(prf); set_label(prf->label, prf->saved_label); if (prf->reflect_func) (*(prf->reflect_func))(prf); TIMEOUT_RESULT } static void any_error_to_text(const char *msg, void *data) { prefs_info *prf = (prefs_info *)data; prf->got_error = true; red_text(prf); set_label(prf->label, msg); TIMEOUT(unpost_any_error); } static void redirect_post_prefs_error(const char *msg, void *data) { post_prefs_error(msg, (prefs_info *)data); } static int prefs_size = 0, prefs_top = 0; static prefs_info **prefs = NULL; static void remember_pref(prefs_info *prf, void (*reflect_func)(struct prefs_info *prf), void (*save_func)(struct prefs_info *prf, FILE *fd), const char *(*help_func)(struct prefs_info *prf), void (*clear_func)(struct prefs_info *prf), void (*revert_func)(struct prefs_info *prf)) { if (prefs_size == 0) { prefs_size = 100; prefs = (prefs_info **)calloc(prefs_size, sizeof(prefs_info *)); } else { if (prefs_top >= prefs_size) { int i; prefs_size += 100; prefs = (prefs_info **)realloc(prefs, prefs_size * sizeof(prefs_info *)); for (i = prefs_top; i < prefs_size; i++) prefs[i] = NULL; } } prf->reflect_func = reflect_func; prf->save_func = save_func; prf->help_func = help_func; prf->clear_func = clear_func; prf->revert_func = revert_func; prefs[prefs_top++] = prf; if ((help_func) && (prf->label)) { if (prf->var_name) { char *str; str = mus_format("%s\n See %s for more info.", (*help_func)(prf), prf->var_name); add_tooltip(prf->label, str); /* don't free it... */ } else add_tooltip(prf->label, (*help_func)(prf)); } } static void reflect_prefs(void) { int i; for (i = 0; i < prefs_top; i++) { prefs_info *prf; prf = prefs[i]; if ((prf) && (prf->reflect_func)) (*(prf->reflect_func))(prf); } } static void revert_prefs(void) { int i; for (i = 0; i < prefs_top; i++) { prefs_info *prf; prf = prefs[i]; if ((prf) && (prf->revert_func)) (*(prf->revert_func))(prf); } } static void clear_prefs(void) { int i; for (i = 0; i < prefs_top; i++) { prefs_info *prf; prf = prefs[i]; if ((prf) && (prf->clear_func)) (*(prf->clear_func))(prf); } } static void preferences_revert_or_clear(bool revert) { clear_prefs_dialog_error(); if (revert) revert_prefs(); else { snd_set_global_defaults(true); clear_prefs(); } reflect_prefs(); prefs_unsaved = false; if (prefs_saved_filename) { char *fullname; fullname = mus_expand_filename(prefs_saved_filename); if (mus_file_probe(fullname)) snd_remove(fullname, IGNORE_CACHE); free(prefs_saved_filename); free(fullname); prefs_saved_filename = NULL; } prefs_set_dialog_title(NULL); } static bool local_access(char *dir) { int err; char *temp; temp = shorter_tempnam(dir, "snd_"); err = mus_file_create(temp); if (err != -1) { snd_close(err, temp); snd_remove(temp, IGNORE_CACHE); } free(temp); return(err != -1); } static bool is_string_member(const char *val, char **lst, int len) { int i; if ((len == 0) || (!lst) || (!val)) return(false); for (i = 0; i < len; i++) if (mus_strcmp(val, lst[i])) return(true); return(false); } static char **load_path_to_string_array(int *len) { char **cdirs = NULL; int dir_len = 0, j = 0; Xen dirs; dirs = Xen_load_path; dir_len = Xen_list_length(dirs); if (dir_len > 0) { int i; cdirs = (char **)calloc(dir_len, sizeof(char *)); for (i = 0; i < dir_len; i++) { const char *path; path = Xen_string_to_C_string(Xen_list_ref(dirs, i)); if ((path) && (!(is_string_member(path, cdirs, j)))) /* try to remove duplicates */ cdirs[j++] = mus_strdup(path); } } (*len) = j; return(cdirs); } static void add_local_load_path(FILE *fd, char *path) { #if HAVE_RUBY fprintf(fd, "if (not $LOAD_PATH.include?(\"%s\")) then $LOAD_PATH.push(\"%s\") end\n", path, path); #endif #if HAVE_FORTH /* this already checks */ fprintf(fd, "\"%s\" add-load-path\n", path); /* no drop here */ #endif #if HAVE_SCHEME fprintf(fd, "(if (not (member \"%s\" *load-path*)) (set! *load-path* (cons \"%s\" *load-path*)))\n", path, path); #endif } #if HAVE_EXTENSION_LANGUAGE static void save_prefs(void) { char *fullname; const char *filename; FILE *fd; /* save_options_in_prefs passes us the filename after calling save_options which handles all * the simple cases. */ filename = save_options_in_prefs(); if (!filename) return; fullname = mus_expand_filename(filename); fd = FOPEN(fullname, "a"); if (fd) { char **current_dirs = NULL; int i, current_dirs_len = 0; fprintf(fd, "\n"); /* LOAD_PATH has the current load-path list, * GET_TEXT(load_path_text_widget) has the current text (independent of activation) * include_load_path has whatever the last set it to. * * load_path_to_string_array can turn the LOAD_PATH into a char** array. * * load-path needs to be set even if a later init file adds to it; we need a true * load-path, but this can be called repeatedly, and across executions, so we * don't want to fill up the list with repetitions */ current_dirs = load_path_to_string_array(¤t_dirs_len); if (current_dirs) for (i = current_dirs_len - 1; i >= 0; i--) /* consing on front, so keep original order of paths */ add_local_load_path(fd, current_dirs[i]); /* don't try to be smart about startup paths -- just include everybody */ if ((include_load_path) && (!(is_string_member(include_load_path, current_dirs, current_dirs_len)))) add_local_load_path(fd, include_load_path); if (load_path_text_widget) { char *unchecked_load_path = NULL; unchecked_load_path = GET_TEXT(load_path_text_widget); if ((unchecked_load_path) && /* text widget has an entry */ (local_access(unchecked_load_path)) && /* it's a legit path */ (!(is_string_member(unchecked_load_path, current_dirs, current_dirs_len))) && /* it's not in LOAD_PATH */ (!(mus_strcmp(unchecked_load_path, include_load_path)))) /* it's not already included above */ add_local_load_path(fd, unchecked_load_path); if (unchecked_load_path) {free_TEXT(unchecked_load_path);} /* a no-op in gtk */ } if (current_dirs) { for (i = 0; i < current_dirs_len; i++) if (current_dirs[i]) free(current_dirs[i]); free(current_dirs); current_dirs = NULL; } /* now finally the load path is set up, so we can call load if we need to */ for (i = 0; i < prefs_top; i++) { prefs_info *prf; prf = prefs[i]; if ((prf) && (prf->save_func)) (*(prf->save_func))(prf, fd); } snd_fclose(fd, filename); } else snd_error("can't save preferences: %s %s", filename, snd_io_strerror()); free(fullname); prefs_unsaved = false; prefs_set_dialog_title(filename); } #endif static char *trim_string(const char *str) { int i = 0, len, j = 0, k, m; char *trimmed_str; len = strlen(str); trimmed_str = (char *)calloc(len + 1, sizeof(char)); while ((i < len) && (isspace((int)str[i]))) i++; k = len - 1; while ((k > i) && (isspace((int)str[k]))) k--; for (m = i; m <= k; m++) trimmed_str[j++] = str[m]; return(trimmed_str); } static char key_buf[16]; static char *possibly_quote(char *key) { int i, j, len; len = mus_strlen(key); if (len > 12) len = 12; for (i = 0, j = 0; i < len; i++) if (!(isspace((int)key[i]))) { if ((j == 0) && (isalpha((int)key[i]))) key_buf[j++] = '\"'; key_buf[j++] = key[i]; } if ((key_buf[0] == '\"') && (key_buf[j - 1] != '\"')) key_buf[j++] = '\"'; key_buf[j++] = '\0'; #if 0 fprintf(stderr,"return key %s\n", key_buf); #endif return(key_buf); } /* ---------------- auto-resize ---------------- */ static bool rts_auto_resize = DEFAULT_AUTO_RESIZE; static void reflect_auto_resize(prefs_info *prf) {SET_TOGGLE(prf->toggle, auto_resize(ss));} static void resize_toggle(prefs_info *prf) {set_auto_resize(GET_TOGGLE(prf->toggle));} static void revert_auto_resize(prefs_info *prf) {set_auto_resize(rts_auto_resize);} static void save_auto_resize(prefs_info *prf, FILE *ignore) {rts_auto_resize = auto_resize(ss);} static const char *help_auto_resize(prefs_info *prf) { return("\ If this option is set, Snd's main window \n\ changes size as sounds come and go. "); } /* ---------------- ask-before-overwrite ---------------- */ static bool rts_ask_before_overwrite = DEFAULT_ASK_BEFORE_OVERWRITE; static void reflect_ask_before_overwrite(prefs_info *prf) {SET_TOGGLE(prf->toggle, ask_before_overwrite(ss));} static void overwrite_toggle(prefs_info *prf) {set_ask_before_overwrite(GET_TOGGLE(prf->toggle));} static void revert_ask_before_overwrite(prefs_info *prf) {set_ask_before_overwrite(rts_ask_before_overwrite);} static void save_ask_before_overwrite(prefs_info *prf, FILE *ignore) {rts_ask_before_overwrite = ask_before_overwrite(ss);} static const char *help_ask_before_overwrite(prefs_info *prf) { return("\ If this option is set, Snd will ask you before \n\ it overwrites an existing sound. "); } /* ---------------- show-controls ---------------- */ static bool rts_show_controls = DEFAULT_SHOW_CONTROLS; static void reflect_show_controls(prefs_info *prf) {SET_TOGGLE(prf->toggle, in_show_controls(ss));} static void controls_toggle(prefs_info *prf) {set_show_controls(GET_TOGGLE(prf->toggle));} static void revert_show_controls(prefs_info *prf) {set_show_controls(rts_show_controls);} static void save_show_controls(prefs_info *prf, FILE *ignore) {rts_show_controls = in_show_controls(ss);} /* ---------------- just-sounds ---------------- */ static bool rts_just_sounds = DEFAULT_JUST_SOUNDS; static void prefs_reflect_just_sounds(prefs_info *prf) {SET_TOGGLE(prf->toggle, just_sounds(ss));} static void just_sounds_toggle(prefs_info *prf) {set_just_sounds(GET_TOGGLE(prf->toggle));} static void revert_just_sounds(prefs_info *prf) {set_just_sounds(rts_just_sounds);} static void save_just_sounds(prefs_info *prf, FILE *ignore) {rts_just_sounds = just_sounds(ss);} /* ---------------- verbose-cursor ---------------- */ static bool rts_with_verbose_cursor = DEFAULT_WITH_VERBOSE_CURSOR; static void reflect_with_verbose_cursor(prefs_info *prf) {SET_TOGGLE(prf->toggle, with_verbose_cursor(ss));} static void with_verbose_cursor_toggle(prefs_info *prf) {set_with_verbose_cursor(GET_TOGGLE(prf->toggle));} static void revert_with_verbose_cursor(prefs_info *prf) {set_with_verbose_cursor(rts_with_verbose_cursor);} static void save_with_verbose_cursor(prefs_info *prf, FILE *ignore) {rts_with_verbose_cursor = with_verbose_cursor(ss);} /* ---------------- graphs-horizontal ---------------- */ static bool rts_graphs_horizontal = DEFAULT_GRAPHS_HORIZONTAL; static void reflect_graphs_horizontal(prefs_info *prf) {SET_TOGGLE(prf->toggle, graphs_horizontal(ss));} static void graphs_horizontal_toggle(prefs_info *prf) {in_set_graphs_horizontal(GET_TOGGLE(prf->toggle));} static void revert_graphs_horizontal(prefs_info *prf) {in_set_graphs_horizontal(rts_graphs_horizontal);} static void save_graphs_horizontal(prefs_info *prf, FILE *ignore) {rts_graphs_horizontal = graphs_horizontal(ss);} /* ---------------- show-y-zero ---------------- */ static bool rts_show_y_zero = DEFAULT_SHOW_Y_ZERO; static void reflect_show_y_zero(prefs_info *prf) {SET_TOGGLE(prf->toggle, show_y_zero(ss));} static void y_zero_toggle(prefs_info *prf) {set_show_y_zero(GET_TOGGLE(prf->toggle));} static void revert_show_y_zero(prefs_info *prf) {set_show_y_zero(rts_show_y_zero);} static void save_show_y_zero(prefs_info *prf, FILE *ignore) {rts_show_y_zero = show_y_zero(ss);} /* ---------------- show-grid ---------------- */ static with_grid_t rts_show_grid = DEFAULT_SHOW_GRID; static void reflect_show_grid(prefs_info *prf) {SET_TOGGLE(prf->toggle, show_grid(ss) == WITH_GRID);} static void grid_toggle(prefs_info *prf) {set_show_grid(((GET_TOGGLE(prf->toggle)) ? WITH_GRID : NO_GRID));} static void revert_show_grid(prefs_info *prf) {set_show_grid(rts_show_grid);} static void save_show_grid(prefs_info *prf, FILE *ignore) {rts_show_grid = show_grid(ss);} /* ---------------- fft-log-magnitude ---------------- */ static bool rts_fft_log_magnitude = DEFAULT_FFT_LOG_MAGNITUDE; static void reflect_fft_log_magnitude(prefs_info *prf) {SET_TOGGLE(prf->toggle, fft_log_magnitude(ss));} static void log_magnitude_toggle(prefs_info *prf) {set_fft_log_magnitude(GET_TOGGLE(prf->toggle));} static void revert_fft_log_magnitude(prefs_info *prf) {set_fft_log_magnitude(rts_fft_log_magnitude);} static void save_fft_log_magnitude(prefs_info *prf, FILE *ignore) {rts_fft_log_magnitude = fft_log_magnitude(ss);} /* ---------------- fft-log-frequency ---------------- */ static bool rts_fft_log_frequency = DEFAULT_FFT_LOG_FREQUENCY; static void reflect_fft_log_frequency(prefs_info *prf) {SET_TOGGLE(prf->toggle, fft_log_frequency(ss));} static void log_frequency_toggle(prefs_info *prf) {set_fft_log_frequency(GET_TOGGLE(prf->toggle));} static void revert_fft_log_frequency(prefs_info *prf) {set_fft_log_frequency(rts_fft_log_frequency);} static void save_fft_log_frequency(prefs_info *prf, FILE *ignore) {rts_fft_log_frequency = fft_log_frequency(ss);} /* ---------------- dac-combines-channels ---------------- */ static bool rts_dac_combines_channels = DEFAULT_DAC_COMBINES_CHANNELS; static void reflect_dac_combines_channels(prefs_info *prf) {SET_TOGGLE(prf->toggle, dac_combines_channels(ss));} static void dac_combines_channels_toggle(prefs_info *prf) {set_dac_combines_channels(GET_TOGGLE(prf->toggle));} static void revert_dac_combines_channels(prefs_info *prf) {set_dac_combines_channels(rts_dac_combines_channels);} static void save_dac_combines_channels(prefs_info *prf, FILE *ignore) {rts_dac_combines_channels = dac_combines_channels(ss);} /* ---------------- show-listener ---------------- */ static bool rts_show_listener = false, prefs_show_listener = false; static void reflect_show_listener(prefs_info *prf) { prefs_show_listener = listener_is_visible(); SET_TOGGLE(prf->toggle, prefs_show_listener); } static void show_listener_toggle(prefs_info *prf) { prefs_show_listener = GET_TOGGLE(prf->toggle); handle_listener(prefs_show_listener); } static void save_show_listener(prefs_info *prf, FILE *fd) { rts_show_listener = prefs_show_listener; } static void revert_show_listener(prefs_info *prf) { prefs_show_listener = rts_show_listener; handle_listener(rts_show_listener); } static void clear_show_listener(prefs_info *prf) { prefs_show_listener = false; handle_listener(false); } /* ---------------- basic-color ---------------- */ /* we need the original color (Clear), the last saved color (Revert) * the colors are updated continuously, so the current color variable (and the reflection func) is irrelevant * so: * set original in snd-gxmain or somewhere * set rts in prefs dialog startup * reflect_color: a no-op * save_color: save current color_t value in rts value (actual fd output dealt with elsewhere) * clear_color: set to original (leave rts value alone) * revert_color: set to rts (leave original alone) * help_color: built-in via color variable name * color_func: set color based on rgb values */ static color_t saved_basic_color; static void save_basic_color(prefs_info *prf, FILE *ignore) {saved_basic_color = ss->basic_color;} static void basic_color_func(prefs_info *prf, float r, float g, float b) {set_basic_color(rgb_to_color(r, g, b));} static void revert_basic_color(prefs_info *prf) { scale_set_color(prf, saved_basic_color); set_basic_color(saved_basic_color); } static void clear_basic_color(prefs_info *prf) { scale_set_color(prf, ss->basic_color); set_basic_color(ss->orig_basic_color); } /* ---------------- highlight-color ---------------- */ static color_t saved_highlight_color; static void save_highlight_color(prefs_info *prf, FILE *ignore) {saved_highlight_color = ss->highlight_color;} static void highlight_color_func(prefs_info *prf, float r, float g, float b) {set_highlight_color(rgb_to_color(r, g, b));} static void revert_highlight_color(prefs_info *prf) { scale_set_color(prf, saved_highlight_color); set_highlight_color(saved_highlight_color); } static void clear_highlight_color(prefs_info *prf) { scale_set_color(prf, ss->orig_highlight_color); set_highlight_color(ss->orig_highlight_color); } /* ---------------- position-color ---------------- */ static color_t saved_position_color; static void save_position_color(prefs_info *prf, FILE *ignore) {saved_position_color = ss->position_color;} static void position_color_func(prefs_info *prf, float r, float g, float b) {set_position_color(rgb_to_color(r, g, b));} static void revert_position_color(prefs_info *prf) { scale_set_color(prf, saved_position_color); set_position_color(saved_position_color); } static void clear_position_color(prefs_info *prf) { scale_set_color(prf, ss->orig_position_color); set_position_color(ss->orig_position_color); } /* ---------------- zoom-color ---------------- */ static color_t saved_zoom_color; static void save_zoom_color(prefs_info *prf, FILE *ignore) {saved_zoom_color = ss->zoom_color;} static void zoom_color_func(prefs_info *prf, float r, float g, float b) {set_zoom_color(rgb_to_color(r, g, b));} static void revert_zoom_color(prefs_info *prf) { scale_set_color(prf, saved_zoom_color); set_zoom_color(saved_zoom_color); } static void clear_zoom_color(prefs_info *prf) { scale_set_color(prf, ss->orig_zoom_color); set_zoom_color(ss->orig_zoom_color); } /* ---------------- cursor-color ---------------- */ static color_t saved_cursor_color; static void save_cursor_color(prefs_info *prf, FILE *ignore) {saved_cursor_color = ss->cursor_color;} static void cursor_color_func(prefs_info *prf, float r, float g, float b) { color_cursor(rgb_to_color(r, g, b)); for_each_chan(update_graph); } static void revert_cursor_color(prefs_info *prf) { scale_set_color(prf, saved_cursor_color); color_cursor(saved_cursor_color); } static void clear_cursor_color(prefs_info *prf) { scale_set_color(prf, ss->orig_cursor_color); color_cursor(ss->orig_cursor_color); } /* ---------------- data-color ---------------- */ static color_t saved_data_color; static void save_data_color(prefs_info *prf, FILE *ignore) {saved_data_color = ss->data_color;} static void data_color_func(prefs_info *prf, float r, float g, float b) {set_data_color(rgb_to_color(r, g, b));} static void revert_data_color(prefs_info *prf) { scale_set_color(prf, saved_data_color); set_data_color(saved_data_color); } static void clear_data_color(prefs_info *prf) { scale_set_color(prf, ss->orig_data_color); set_data_color(ss->orig_data_color); } /* ---------------- graph-color ---------------- */ static color_t saved_graph_color; static void save_graph_color(prefs_info *prf, FILE *ignore) {saved_graph_color = ss->graph_color;} static void graph_color_func(prefs_info *prf, float r, float g, float b) {set_graph_color(rgb_to_color(r, g, b));} static void revert_graph_color(prefs_info *prf) { scale_set_color(prf, saved_graph_color); set_graph_color(saved_graph_color); } static void clear_graph_color(prefs_info *prf) { scale_set_color(prf, ss->orig_graph_color); set_graph_color(ss->orig_graph_color); } /* ---------------- selected-data-color ---------------- */ static color_t saved_selected_data_color; static void save_selected_data_color(prefs_info *prf, FILE *ignore) {saved_selected_data_color = ss->selected_data_color;} static void selected_data_color_func(prefs_info *prf, float r, float g, float b) {set_selected_data_color(rgb_to_color(r, g, b));} static void revert_selected_data_color(prefs_info *prf) { scale_set_color(prf, saved_selected_data_color); set_selected_data_color(saved_selected_data_color); } static void clear_selected_data_color(prefs_info *prf) { scale_set_color(prf, ss->orig_selected_data_color); set_selected_data_color(ss->orig_selected_data_color); } /* ---------------- selected-graph-color ---------------- */ static color_t saved_selected_graph_color; static void save_selected_graph_color(prefs_info *prf, FILE *ignore) {saved_selected_graph_color = ss->selected_graph_color;} static void selected_graph_color_func(prefs_info *prf, float r, float g, float b) {set_selected_graph_color(rgb_to_color(r, g, b));} static void revert_selected_graph_color(prefs_info *prf) { scale_set_color(prf, saved_selected_graph_color); set_selected_graph_color(saved_selected_graph_color); } static void clear_selected_graph_color(prefs_info *prf) { scale_set_color(prf, ss->orig_selected_graph_color); set_selected_graph_color(ss->orig_selected_graph_color); } /* ---------------- selection-color ---------------- */ static void set_selection_color(color_t color) { color_selection(color); for_each_chan(update_graph); } static color_t saved_selection_color; static void save_selection_color(prefs_info *prf, FILE *ignore) {saved_selection_color = ss->selection_color;} static void selection_color_func(prefs_info *prf, float r, float g, float b) {set_selection_color(rgb_to_color(r, g, b));} static void revert_selection_color(prefs_info *prf) { scale_set_color(prf, saved_selection_color); set_selection_color(saved_selection_color); } static void clear_selection_color(prefs_info *prf) { scale_set_color(prf, ss->orig_selection_color); set_selection_color(ss->orig_selection_color); } /* ---------------- mark-color ---------------- */ static color_t saved_mark_color; static void save_mark_color(prefs_info *prf, FILE *ignore) {saved_mark_color = ss->mark_color;} static void mark_color_func(prefs_info *prf, float r, float g, float b) {color_marks(rgb_to_color(r, g, b));} static void revert_mark_color(prefs_info *prf) { scale_set_color(prf, saved_mark_color); color_marks(saved_mark_color); } static void clear_mark_color(prefs_info *prf) { scale_set_color(prf, ss->orig_mark_color); color_marks(ss->orig_mark_color); } /* ---------------- mix-color (waveform) ---------------- */ static color_t saved_mix_color; static void save_mix_color(prefs_info *prf, FILE *ignore) {saved_mix_color = ss->mix_color;} static void mix_color_func(prefs_info *prf, float r, float g, float b) {color_mixes(rgb_to_color(r, g, b));} static void revert_mix_color(prefs_info *prf) { scale_set_color(prf, saved_mix_color); color_mixes(saved_mix_color); } static void clear_mix_color(prefs_info *prf) { scale_set_color(prf, ss->orig_mix_color); color_mixes(ss->orig_mix_color); } /* ---------------- listener-color ---------------- */ static color_t saved_listener_color; static void save_listener_color(prefs_info *prf, FILE *ignore) {saved_listener_color = ss->listener_color;} static void listener_color_func(prefs_info *prf, float r, float g, float b) {color_listener(rgb_to_color(r, g, b));} static void revert_listener_color(prefs_info *prf) { scale_set_color(prf, saved_listener_color); color_listener(saved_listener_color); } static void clear_listener_color(prefs_info *prf) { scale_set_color(prf, ss->orig_listener_color); color_listener(ss->orig_listener_color); } /* ---------------- listener-text-color ---------------- */ static color_t saved_listener_text_color; static void save_listener_text_color(prefs_info *prf, FILE *ignore) {saved_listener_text_color = ss->listener_text_color;} static void listener_text_color_func(prefs_info *prf, float r, float g, float b) {color_listener_text(rgb_to_color(r, g, b));} static void revert_listener_text_color(prefs_info *prf) { scale_set_color(prf, saved_listener_text_color); color_listener_text(saved_listener_text_color); } static void clear_listener_text_color(prefs_info *prf) { scale_set_color(prf, ss->orig_listener_text_color); color_listener_text(ss->orig_listener_text_color); } /* ---------------- axis-label-font ---------------- */ static char *rts_axis_label_font = NULL; static TIMEOUT_TYPE axis_label_font_error_erase_func(TIMEOUT_ARGS) { prefs_info *prf = (prefs_info *)context; SET_TEXT(prf->text, axis_label_font(ss)); TIMEOUT_RESULT } static void save_axis_label_font(prefs_info *prf, FILE *ignore) { if (rts_axis_label_font) free(rts_axis_label_font); rts_axis_label_font = mus_strdup(axis_label_font(ss)); } static void reflect_axis_label_font(prefs_info *prf) {SET_TEXT(prf->text, axis_label_font(ss));} static void revert_axis_label_font(prefs_info *prf) {set_axis_label_font(rts_axis_label_font);} static void clear_axis_label_font(prefs_info *prf) {set_axis_label_font(ss->orig_axis_label_font);} static void axis_label_font_text(prefs_info *prf) { char *str; str = GET_TEXT(prf->text); if ((!str) || (!(*str))) { SET_TEXT(prf->text, axis_label_font(ss)); return; } if (!(set_axis_label_font(str))) { SET_TEXT(prf->text, "can't find that font"); TIMEOUT(axis_label_font_error_erase_func); } if (str) {free_TEXT(str);} } /* ---------------- axis-numbers-font ---------------- */ static char *rts_axis_numbers_font = NULL; static TIMEOUT_TYPE axis_numbers_font_error_erase_func(TIMEOUT_ARGS) { prefs_info *prf = (prefs_info *)context; SET_TEXT(prf->text, axis_numbers_font(ss)); TIMEOUT_RESULT } static void save_axis_numbers_font(prefs_info *prf, FILE *ignore) { if (rts_axis_numbers_font) free(rts_axis_numbers_font); rts_axis_numbers_font = mus_strdup(axis_numbers_font(ss)); } static void reflect_axis_numbers_font(prefs_info *prf) {SET_TEXT(prf->text, axis_numbers_font(ss));} static void revert_axis_numbers_font(prefs_info *prf) {set_axis_numbers_font(rts_axis_numbers_font);} static void clear_axis_numbers_font(prefs_info *prf) {set_axis_numbers_font(ss->orig_axis_numbers_font);} static void axis_numbers_font_text(prefs_info *prf) { char *str; str = GET_TEXT(prf->text); if ((!str) || (!(*str))) { SET_TEXT(prf->text, axis_numbers_font(ss)); return; } if (!(set_axis_numbers_font(str))) { SET_TEXT(prf->text, "can't find that font"); TIMEOUT(axis_numbers_font_error_erase_func); } if (str) {free_TEXT(str);} } /* ---------------- peaks-font ---------------- */ static char *rts_peaks_font = NULL; static TIMEOUT_TYPE peaks_font_error_erase_func(TIMEOUT_ARGS) { prefs_info *prf = (prefs_info *)context; SET_TEXT(prf->text, peaks_font(ss)); TIMEOUT_RESULT } static void save_peaks_font(prefs_info *prf, FILE *ignore) { if (rts_peaks_font) free(rts_peaks_font); rts_peaks_font = mus_strdup(peaks_font(ss)); } static void reflect_peaks_font(prefs_info *prf) {SET_TEXT(prf->text, peaks_font(ss));} static void revert_peaks_font(prefs_info *prf) {set_peaks_font(rts_peaks_font);} static void clear_peaks_font(prefs_info *prf) {set_peaks_font(ss->orig_peaks_font);} static void peaks_font_text(prefs_info *prf) { char *str; str = GET_TEXT(prf->text); if ((!str) || (!(*str))) { SET_TEXT(prf->text, peaks_font(ss)); return; } if (!(set_peaks_font(str))) { SET_TEXT(prf->text, "can't find that font"); TIMEOUT(peaks_font_error_erase_func); } if (str) {free_TEXT(str);} } /* ---------------- bold-peaks-font ---------------- */ static char *rts_bold_peaks_font = NULL; static TIMEOUT_TYPE bold_peaks_font_error_erase_func(TIMEOUT_ARGS) { prefs_info *prf = (prefs_info *)context; SET_TEXT(prf->text, bold_peaks_font(ss)); TIMEOUT_RESULT } static void save_bold_peaks_font(prefs_info *prf, FILE *ignore) { if (rts_bold_peaks_font) free(rts_bold_peaks_font); rts_bold_peaks_font = mus_strdup(bold_peaks_font(ss)); } static void reflect_bold_peaks_font(prefs_info *prf) {SET_TEXT(prf->text, bold_peaks_font(ss));} static void revert_bold_peaks_font(prefs_info *prf) {set_bold_peaks_font(rts_bold_peaks_font);} static void clear_bold_peaks_font(prefs_info *prf) {set_bold_peaks_font(ss->orig_bold_peaks_font);} static void bold_peaks_font_text(prefs_info *prf) { char *str; str = GET_TEXT(prf->text); if ((!str) || (!(*str))) { SET_TEXT(prf->text, bold_peaks_font(ss)); return; } if (!(set_bold_peaks_font(str))) { SET_TEXT(prf->text, "can't find that font"); TIMEOUT(bold_peaks_font_error_erase_func); } if (str) {free_TEXT(str);} } /* ---------------- tiny-font ---------------- */ static char *rts_tiny_font = NULL; static TIMEOUT_TYPE tiny_font_error_erase_func(TIMEOUT_ARGS) { prefs_info *prf = (prefs_info *)context; SET_TEXT(prf->text, tiny_font(ss)); TIMEOUT_RESULT } static void save_tiny_font(prefs_info *prf, FILE *ignore) { if (rts_tiny_font) free(rts_tiny_font); rts_tiny_font = mus_strdup(tiny_font(ss)); } static void reflect_tiny_font(prefs_info *prf) {SET_TEXT(prf->text, tiny_font(ss));} static void revert_tiny_font(prefs_info *prf) {set_tiny_font(rts_tiny_font);} static void clear_tiny_font(prefs_info *prf) {set_tiny_font(ss->orig_tiny_font);} static void tiny_font_text(prefs_info *prf) { char *str; str = GET_TEXT(prf->text); if ((!str) || (!(*str))) { SET_TEXT(prf->text, tiny_font(ss)); return; } if (!(set_tiny_font(str))) { SET_TEXT(prf->text, "can't find that font"); TIMEOUT(tiny_font_error_erase_func); } if (str) {free_TEXT(str);} } /* ---------------- listener-font ---------------- */ static char *rts_listener_font = NULL; static TIMEOUT_TYPE listener_font_error_erase_func(TIMEOUT_ARGS) { prefs_info *prf = (prefs_info *)context; SET_TEXT(prf->text, listener_font(ss)); TIMEOUT_RESULT } static void save_listener_font(prefs_info *prf, FILE *ignore) { if (rts_listener_font) free(rts_listener_font); rts_listener_font = mus_strdup(listener_font(ss)); } static void reflect_listener_font(prefs_info *prf) {SET_TEXT(prf->text, listener_font(ss));} static void revert_listener_font(prefs_info *prf) {set_listener_font(rts_listener_font);} static void clear_listener_font(prefs_info *prf) {set_listener_font(ss->orig_listener_font);} static void listener_font_text(prefs_info *prf) { char *str; str = GET_TEXT(prf->text); if ((!str) || (!(*str))) { SET_TEXT(prf->text, listener_font(ss)); return; } if (!(set_listener_font(str))) { SET_TEXT(prf->text, "can't find that font"); TIMEOUT(listener_font_error_erase_func); } if (str) {free_TEXT(str);} } /* ---------------- save-state-file ---------------- */ static char *rts_save_state_file = NULL; static void reflect_save_state_file(prefs_info *prf) { SET_TEXT(prf->text, save_state_file(ss)); } static void revert_save_state_file(prefs_info *prf) { if (save_state_file(ss)) free(save_state_file(ss)); in_set_save_state_file(mus_strdup(rts_save_state_file)); } static void save_save_state_file(prefs_info *prf, FILE *ignore) { if (rts_save_state_file) free(rts_save_state_file); rts_save_state_file = mus_strdup(save_state_file(ss)); } static void save_state_file_text(prefs_info *prf) { char *str, *file = NULL; str = GET_TEXT(prf->text); if ((!str) || (!(*str))) file = mus_strdup(DEFAULT_SAVE_STATE_FILE); else file = mus_strdup(str); if (save_state_file(ss)) free(save_state_file(ss)); in_set_save_state_file(file); if (str) {free_TEXT(str);} } /* ---------------- temp-dir ---------------- */ static char *rts_temp_dir = NULL; static void reflect_temp_dir(prefs_info *prf) { SET_TEXT(prf->text, temp_dir(ss)); } static void revert_temp_dir(prefs_info *prf) { if (temp_dir(ss)) free(temp_dir(ss)); set_temp_dir(mus_strdup(rts_temp_dir)); } static void save_temp_dir(prefs_info *prf, FILE *ignore) { if (rts_temp_dir) free(rts_temp_dir); rts_temp_dir = mus_strdup(temp_dir(ss)); } static TIMEOUT_TYPE temp_dir_error_erase_func(TIMEOUT_ARGS) { prefs_info *prf = (prefs_info *)context; SET_TEXT(prf->text, rts_temp_dir); TIMEOUT_RESULT } static void temp_dir_text(prefs_info *prf) { char *str = NULL, *dir = NULL; str = GET_TEXT(prf->text); if ((!str) || (!(*str))) dir = MUS_DEFAULT_TEMP_DIR; else dir = str; if (local_access(dir)) { if (temp_dir(ss)) free(temp_dir(ss)); set_temp_dir(mus_strdup(dir)); } else { SET_TEXT(prf->text, "can't access that directory"); TIMEOUT(temp_dir_error_erase_func); } #if USE_MOTIF if (str) XtFree(str); #endif } /* ---------------- save-dir ---------------- */ static char *rts_save_dir = NULL; static void reflect_save_dir(prefs_info *prf) { SET_TEXT(prf->text, save_dir(ss)); } static void revert_save_dir(prefs_info *prf) { if (save_dir(ss)) free(save_dir(ss)); set_save_dir(mus_strdup(rts_save_dir)); } static void save_save_dir(prefs_info *prf, FILE *ignore) { if (rts_save_dir) free(rts_save_dir); rts_save_dir = mus_strdup(save_dir(ss)); } static TIMEOUT_TYPE save_dir_error_erase_func(TIMEOUT_ARGS) { prefs_info *prf = (prefs_info *)context; SET_TEXT(prf->text, rts_save_dir); TIMEOUT_RESULT } static void save_dir_text(prefs_info *prf) { char *str = NULL, *dir = NULL; str = GET_TEXT(prf->text); if ((!str) || (!(*str))) dir = MUS_DEFAULT_SAVE_DIR; else dir = str; if (local_access(dir)) { if (save_dir(ss)) free(save_dir(ss)); set_save_dir(mus_strdup(dir)); } else { SET_TEXT(prf->text, "can't access that directory"); TIMEOUT(save_dir_error_erase_func); } #if USE_MOTIF if (str) XtFree(str); #endif } #if HAVE_LADSPA /* ---------------- ladspa-dir ---------------- */ static char *rts_ladspa_dir = NULL; static void reflect_ladspa_dir(prefs_info *prf) { SET_TEXT(prf->text, ladspa_dir(ss)); } static void revert_ladspa_dir(prefs_info *prf) { if (ladspa_dir(ss)) free(ladspa_dir(ss)); set_ladspa_dir(mus_strdup(rts_ladspa_dir)); } static void save_ladspa_dir(prefs_info *prf, FILE *ignore) { if (rts_ladspa_dir) free(rts_ladspa_dir); rts_ladspa_dir = mus_strdup(ladspa_dir(ss)); } static void ladspa_dir_text(prefs_info *prf) { char *str; str = GET_TEXT(prf->text); if (ladspa_dir(ss)) free(ladspa_dir(ss)); if (str) { set_ladspa_dir(mus_strdup(str)); free_TEXT(str); } else set_ladspa_dir(mus_strdup(DEFAULT_LADSPA_DIR)); } static const char *help_ladspa_dir(prefs_info *prf) { return("This sets the location of the ladspa libraries"); } #endif #if USE_MOTIF /* ---------------- view-files directory ---------------- */ static char *rts_vf_directory = NULL; static void reflect_view_files_directory(prefs_info *prf) { SET_TEXT(prf->text, view_files_find_any_directory()); } static void revert_view_files_directory(prefs_info *prf) { if (rts_vf_directory) view_files_add_directory(NULL_WIDGET, (const char *)rts_vf_directory); } static void save_view_files_directory(prefs_info *prf, FILE *fd) { if (rts_vf_directory) free(rts_vf_directory); rts_vf_directory = mus_strdup(view_files_find_any_directory()); if (rts_vf_directory) { #if HAVE_SCHEME fprintf(fd, "(%s \"%s\")\n", S_add_directory_to_view_files_list, rts_vf_directory); #endif #if HAVE_RUBY fprintf(fd, "%s(\"%s\")\n", to_proc_name(S_add_directory_to_view_files_list), rts_vf_directory); #endif #if HAVE_FORTH fprintf(fd, "\"%s\" %s drop\n", rts_vf_directory, S_add_directory_to_view_files_list); #endif } } static void view_files_directory_text(prefs_info *prf) { char *str; str = GET_TEXT(prf->text); if (str) { view_files_add_directory(NULL_WIDGET, (const char *)str); free_TEXT(str); } } #endif /* ---------------- html-program ---------------- */ static char *rts_html_program = NULL; static void reflect_html_program(prefs_info *prf) { SET_TEXT(prf->text, html_program(ss)); } static void revert_html_program(prefs_info *prf) { if (html_program(ss)) free(html_program(ss)); set_html_program(mus_strdup(rts_html_program)); } static void save_html_program(prefs_info *prf, FILE *ignore) { if (rts_html_program) free(rts_html_program); rts_html_program = mus_strdup(html_program(ss)); } static void html_program_text(prefs_info *prf) { char *str; str = GET_TEXT(prf->text); if (html_program(ss)) free(html_program(ss)); if (str) { set_html_program(mus_strdup(str)); free_TEXT(str); } else set_html_program(mus_strdup(DEFAULT_HTML_PROGRAM)); } /* ---------------- listener-prompt ---------------- */ static char *rts_listener_prompt = NULL; static void reflect_listener_prompt(prefs_info *prf) { SET_TEXT(prf->text, listener_prompt(ss)); } static void revert_listener_prompt(prefs_info *prf) { if (rts_listener_prompt) { if (listener_prompt(ss)) free(listener_prompt(ss)); set_listener_prompt(mus_strdup(rts_listener_prompt)); } } static void save_listener_prompt(prefs_info *prf, FILE *ignore) { if (rts_listener_prompt) free(rts_listener_prompt); rts_listener_prompt = mus_strdup(listener_prompt(ss)); } static void listener_prompt_text(prefs_info *prf) { char *str; str = GET_TEXT(prf->text); if (str) { if (listener_prompt(ss)) free(listener_prompt(ss)); set_listener_prompt(mus_strdup(str)); free_TEXT(str); } } /* ---------------- show-transform-peaks ---------------- */ static bool rts_show_transform_peaks = DEFAULT_SHOW_TRANSFORM_PEAKS; static int rts_max_transform_peaks = DEFAULT_MAX_TRANSFORM_PEAKS; static void reflect_transform_peaks(prefs_info *prf) { SET_TOGGLE(prf->toggle, show_transform_peaks(ss)); int_to_textfield(prf->text, max_transform_peaks(ss)); } static void revert_transform_peaks(prefs_info *prf) { set_show_transform_peaks(rts_show_transform_peaks); set_max_transform_peaks(rts_max_transform_peaks); } static void save_transform_peaks(prefs_info *prf, FILE *ignore) { rts_show_transform_peaks = show_transform_peaks(ss); rts_max_transform_peaks = max_transform_peaks(ss); } static void transform_peaks_toggle(prefs_info *prf) { set_show_transform_peaks(GET_TOGGLE(prf->toggle)); } static void max_peaks_text(prefs_info *prf) { char *str; str = GET_TEXT(prf->text); if ((str) && (*str)) { int value = 0; redirect_errors_to(any_error_to_text, (void *)prf); value = string_to_int(str, 0, "max peaks"); redirect_errors_to(NULL, NULL); if (!(prf->got_error)) set_max_transform_peaks(value); free_TEXT(str); } } /* ---------------- show-mix-waveforms ---------------- */ static bool rts_show_mix_waveforms = DEFAULT_SHOW_MIX_WAVEFORMS; static int rts_mix_waveform_height = DEFAULT_MIX_WAVEFORM_HEIGHT; static void reflect_mix_waveforms(prefs_info *prf) { SET_TOGGLE(prf->toggle, show_mix_waveforms(ss)); int_to_textfield(prf->text, mix_waveform_height(ss)); } static void revert_mix_waveforms(prefs_info *prf) { set_show_mix_waveforms(rts_show_mix_waveforms); set_mix_waveform_height(rts_mix_waveform_height); } static void save_mix_waveforms(prefs_info *prf, FILE *ignore) { rts_show_mix_waveforms = show_mix_waveforms(ss); rts_mix_waveform_height = mix_waveform_height(ss); } static void show_mix_waveforms_toggle(prefs_info *prf) { set_show_mix_waveforms(GET_TOGGLE(prf->toggle)); } static void mix_waveform_height_text(prefs_info *prf) { char *str; str = GET_TEXT(prf->text); if ((str) && (*str)) { int value = 0; redirect_errors_to(any_error_to_text, (void *)prf); value = string_to_int(str, 0, "mix waveform height"); redirect_errors_to(NULL, NULL); if (!(prf->got_error)) set_mix_waveform_height(value); free_TEXT(str); } } /* ---------------- selection-creates-region, max-regions ---------------- */ static bool rts_selection_creates_region = DEFAULT_SELECTION_CREATES_REGION; static int rts_max_regions = DEFAULT_MAX_REGIONS; static void reflect_selection_creates_region(prefs_info *prf) { SET_TOGGLE(prf->toggle, selection_creates_region(ss)); int_to_textfield(prf->text, max_regions(ss)); } static void revert_selection_creates_region(prefs_info *prf) { set_selection_creates_region(rts_selection_creates_region); in_set_max_regions(rts_max_regions); } static void save_selection_creates_region(prefs_info *prf, FILE *ignore) { rts_selection_creates_region = selection_creates_region(ss); rts_max_regions = max_regions(ss); } static void selection_creates_region_toggle(prefs_info *prf) { set_selection_creates_region(GET_TOGGLE(prf->toggle)); } static void max_regions_text(prefs_info *prf) { char *str; str = GET_TEXT(prf->text); if ((str) && (*str)) { int value = 0; redirect_errors_to(any_error_to_text, (void *)prf); value = string_to_int(str, 0, "max regions"); redirect_errors_to(NULL, NULL); if (!(prf->got_error)) in_set_max_regions(value); free_TEXT(str); } } /* ---------------- sinc width ---------------- */ static int rts_sinc_width = DEFAULT_SINC_WIDTH; static void reflect_sinc_width(prefs_info *prf) {int_to_textfield(prf->text, sinc_width(ss));} static void revert_sinc_width(prefs_info *prf) {set_sinc_width(rts_sinc_width);} static void save_sinc_width(prefs_info *prf, FILE *ignore) {rts_sinc_width = sinc_width(ss);} static void sinc_width_text(prefs_info *prf) { char *str; str = GET_TEXT(prf->text); if ((str) && (*str)) { int value = 0; redirect_errors_to(any_error_to_text, (void *)prf); value = string_to_int(str, 0, "sinc width"); redirect_errors_to(NULL, NULL); if (!(prf->got_error)) set_sinc_width(value); free_TEXT(str); } } /* ---------------- print-length ---------------- */ static int rts_print_length = DEFAULT_PRINT_LENGTH; static void reflect_print_length(prefs_info *prf) {int_to_textfield(prf->text, print_length(ss));} static void revert_print_length(prefs_info *prf) {set_print_length(rts_print_length); mus_vct_set_print_length(rts_print_length);} static void save_print_length(prefs_info *prf, FILE *ignore) {rts_print_length = print_length(ss);} static void print_length_text(prefs_info *prf) { char *str; str = GET_TEXT(prf->text); if ((str) && (*str)) { int value = 0; redirect_errors_to(any_error_to_text, (void *)prf); value = string_to_int(str, 0, "print length"); redirect_errors_to(NULL, NULL); if (!(prf->got_error)) { set_print_length(value); mus_vct_set_print_length(value); /* the clm array print length variable will be taken care of when ww.scm is loaded in the new context */ } free_TEXT(str); } } /* ---------------- dac-size ---------------- */ static int rts_dac_size = DEFAULT_DAC_SIZE; static void reflect_dac_size(prefs_info *prf) {int_to_textfield(prf->text, dac_size(ss));} static void revert_dac_size(prefs_info *prf) {set_dac_size(rts_dac_size);} static void save_dac_size(prefs_info *prf, FILE *ignore) {rts_dac_size = dac_size(ss);} static void dac_size_text(prefs_info *prf) { char *str; str = GET_TEXT(prf->text); if ((str) && (*str)) { int value = 0; redirect_errors_to(any_error_to_text, (void *)prf); value = string_to_int(str, 0, "dac size"); redirect_errors_to(NULL, NULL); if (!(prf->got_error)) set_dac_size(value); free_TEXT(str); } } /* ---------------- min-dB ---------------- */ static mus_float_t rts_min_dB = DEFAULT_MIN_DB; static void reflect_min_dB(prefs_info *prf) {float_1_to_textfield(prf->text, min_dB(ss));} static void revert_min_dB(prefs_info *prf) {set_min_dB(rts_min_dB);} static void save_min_dB(prefs_info *prf, FILE *ignore) {rts_min_dB = min_dB(ss);} static void min_dB_text(prefs_info *prf) { char *str; str = GET_TEXT(prf->text); if ((str) && (*str)) { float value; redirect_errors_to(any_error_to_text, (void *)prf); value = (float)string_to_mus_float_t(str, -100000.0, "min dB"); redirect_errors_to(NULL, NULL); if ((!(prf->got_error)) && (value < 0.0)) set_min_db(value); /* snd-chn.c -- redisplays */ free_TEXT(str); } } /* ---------------- fft-window-beta ---------------- */ static mus_float_t rts_fft_window_beta = DEFAULT_FFT_WINDOW_BETA; static void reflect_fft_window_beta(prefs_info *prf) { SET_SCALE(fft_window_beta(ss) / prf->scale_max); float_to_textfield(prf->text, fft_window_beta(ss)); } static void revert_fft_window_beta(prefs_info *prf) {set_fft_window_beta(rts_fft_window_beta);} static void save_fft_window_beta(prefs_info *prf, FILE *ignore) {rts_fft_window_beta = fft_window_beta(ss);} static void fft_window_beta_scale_callback(prefs_info *prf) {set_fft_window_beta(GET_SCALE() * prf->scale_max);} static void fft_window_beta_text_callback(prefs_info *prf) { char *str; str = GET_TEXT(prf->text); if ((str) && (*str)) { float value; redirect_errors_to(any_error_to_text, (void *)prf); value = (float)string_to_mus_float_t(str, 0.0, "fft beta"); redirect_errors_to(NULL, NULL); if ((!(prf->got_error)) && (value <= prf->scale_max)) { set_fft_window_beta(value); SET_SCALE(value / prf->scale_max); } free_TEXT(str); } } /* ---------------- grid-density ---------------- */ static mus_float_t rts_grid_density = DEFAULT_GRID_DENSITY; static void reflect_grid_density(prefs_info *prf) { SET_SCALE(grid_density(ss) / prf->scale_max); float_to_textfield(prf->text, grid_density(ss)); } static void revert_grid_density(prefs_info *prf) {set_grid_density(rts_grid_density);} static void save_grid_density(prefs_info *prf, FILE *ignore) {rts_grid_density = grid_density(ss);} static void grid_density_scale_callback(prefs_info *prf) {set_grid_density(GET_SCALE() * prf->scale_max);} static void grid_density_text_callback(prefs_info *prf) { char *str; str = GET_TEXT(prf->text); if ((str) && (*str)) { float value; redirect_errors_to(any_error_to_text, (void *)prf); value = (float)string_to_mus_float_t(str, 0.0, "grid density"); redirect_errors_to(NULL, NULL); if ((!(prf->got_error)) && (value <= prf->scale_max)) { set_grid_density(value); SET_SCALE(value / prf->scale_max); } free_TEXT(str); } } /* ---------------- sync style ---------------- */ static sync_style_t rts_sync_style = DEFAULT_SYNC_STYLE; static void revert_sync_style(prefs_info *prf) {set_sync_style(rts_sync_style);} static void clear_sync_style(prefs_info *prf) {set_sync_style(DEFAULT_SYNC_STYLE);} static void save_sync_style(prefs_info *prf, FILE *ignore) {rts_sync_style = sync_style(ss);} static const char *help_sync_style(prefs_info *prf) { return("\ Many operations can operate either on all channels at once,\n\ or only on the currently selected channel. If 'within each sound'\n\ is set, the channels within a sound are tied together, but not\n\ across sounds."); } static void reflect_sync_style(prefs_info *prf) { rts_sync_style = sync_style(ss); SET_TOGGLE(prf->toggle, rts_sync_style == SYNC_BY_SOUND); SET_TOGGLE(prf->toggle2, rts_sync_style == SYNC_ALL); } static void sync1_choice(prefs_info *prf) { if (GET_TOGGLE(prf->toggle)) rts_sync_style = SYNC_BY_SOUND; else rts_sync_style = SYNC_NONE; SET_TOGGLE(prf->toggle2, false); set_sync_style(rts_sync_style); } static void sync2_choice(prefs_info *prf) { if (GET_TOGGLE(prf->toggle2)) rts_sync_style = SYNC_ALL; else rts_sync_style = SYNC_NONE; SET_TOGGLE(prf->toggle, false); set_sync_style(rts_sync_style); } /* ---------------- mark-tag size ---------------- */ static int rts_mark_tag_width = DEFAULT_MARK_TAG_WIDTH, rts_mark_tag_height = DEFAULT_MARK_TAG_HEIGHT; static void reflect_mark_tag_size(prefs_info *prf) { int_to_textfield(prf->text, mark_tag_width(ss)); int_to_textfield(prf->rtxt, mark_tag_height(ss)); } static void revert_mark_tag_size(prefs_info *prf) { set_mark_tag_width(rts_mark_tag_width); set_mark_tag_height(rts_mark_tag_height); } static void save_mark_tag_size(prefs_info *prf, FILE *ignore) { rts_mark_tag_width = mark_tag_width(ss); rts_mark_tag_height = mark_tag_height(ss); } static TIMEOUT_TYPE mark_tag_width_erase_func(TIMEOUT_ARGS) { prefs_info *prf = (prefs_info *)context; int_to_textfield(prf->text, mark_tag_width(ss)); TIMEOUT_RESULT } static TIMEOUT_TYPE mark_tag_height_erase_func(TIMEOUT_ARGS) { prefs_info *prf = (prefs_info *)context; int_to_textfield(prf->rtxt, mark_tag_height(ss)); TIMEOUT_RESULT } static void mark_tag_width_error(const char *msg, void *data) { prefs_info *prf = (prefs_info *)data; SET_TEXT(prf->text, "must be > 0"); TIMEOUT(mark_tag_width_erase_func); } static void mark_tag_height_error(const char *msg, void *data) { prefs_info *prf = (prefs_info *)data; SET_TEXT(prf->rtxt, "must be > 0"); TIMEOUT(mark_tag_height_erase_func); } static void mark_tag_size_text(prefs_info *prf) { char *str; str = GET_TEXT(prf->text); if ((str) && (*str)) { int width = 0; redirect_errors_to(mark_tag_width_error, (void *)prf); width = string_to_int(str, 1, "mark tag width"); redirect_errors_to(NULL, NULL); if (width > 0) set_mark_tag_width(width); free_TEXT(str); str = GET_TEXT(prf->rtxt); if ((str) && (*str)) { int height; redirect_errors_to(mark_tag_height_error, (void *)prf); height = string_to_int(str, 1, "mark tag height"); redirect_errors_to(NULL, NULL); if (height > 0) set_mark_tag_height(height); free_TEXT(str); } } } /* ---------------- mix-tag size ---------------- */ static int rts_mix_tag_width = DEFAULT_MIX_TAG_WIDTH, rts_mix_tag_height = DEFAULT_MIX_TAG_HEIGHT; static void reflect_mix_tag_size(prefs_info *prf) { int_to_textfield(prf->text, mix_tag_width(ss)); int_to_textfield(prf->rtxt, mix_tag_height(ss)); } static void revert_mix_tag_size(prefs_info *prf) { set_mix_tag_width(rts_mix_tag_width); set_mix_tag_height(rts_mix_tag_height); } static void save_mix_tag_size(prefs_info *prf, FILE *ignore) { rts_mix_tag_width = mix_tag_width(ss); rts_mix_tag_height = mix_tag_height(ss); } static TIMEOUT_TYPE mix_tag_width_erase_func(TIMEOUT_ARGS) { prefs_info *prf = (prefs_info *)context; int_to_textfield(prf->text, mix_tag_width(ss)); TIMEOUT_RESULT } static TIMEOUT_TYPE mix_tag_height_erase_func(TIMEOUT_ARGS) { prefs_info *prf = (prefs_info *)context; int_to_textfield(prf->rtxt, mix_tag_height(ss)); TIMEOUT_RESULT } static void mix_tag_width_error(const char *msg, void *data) { prefs_info *prf = (prefs_info *)data; SET_TEXT(prf->text, "must be > 0"); TIMEOUT(mix_tag_width_erase_func); } static void mix_tag_height_error(const char *msg, void *data) { prefs_info *prf = (prefs_info *)data; SET_TEXT(prf->rtxt, "must be > 0"); TIMEOUT(mix_tag_height_erase_func); } static void mix_tag_size_text(prefs_info *prf) { char *str; str = GET_TEXT(prf->text); if ((str) && (*str)) { int width = 0; redirect_errors_to(mix_tag_width_error, (void *)prf); width = string_to_int(str, 1, "mix tag width"); redirect_errors_to(NULL, NULL); if (width > 0) set_mix_tag_width(width); free_TEXT(str); str = GET_TEXT(prf->rtxt); if ((str) && (*str)) { int height; redirect_errors_to(mix_tag_height_error, (void *)prf); height = string_to_int(str, 1, "mix tag height"); redirect_errors_to(NULL, NULL); if (height > 0) set_mix_tag_height(height); free_TEXT(str); } } } /* ---------------- start up size ---------------- */ static int rts_init_window_width = DEFAULT_INIT_WINDOW_WIDTH, rts_init_window_height = DEFAULT_INIT_WINDOW_HEIGHT; static void revert_init_window_size(prefs_info *prf) { ss->init_window_width = rts_init_window_width; ss->init_window_height = rts_init_window_height; } static void reflect_init_window_size(prefs_info *prf) { char *str; str = mus_format("%d", ss->init_window_width); SET_TEXT(prf->text, str); free(str); str = mus_format("%d", ss->init_window_height); SET_TEXT(prf->rtxt, str); free(str); } static void clear_init_window_size(prefs_info *prf) { ss->init_window_width = DEFAULT_INIT_WINDOW_WIDTH; ss->init_window_height = DEFAULT_INIT_WINDOW_HEIGHT; } static void save_init_window_size(prefs_info *prf, FILE *ignore) { rts_init_window_width = ss->init_window_width; rts_init_window_height = ss->init_window_height; } static TIMEOUT_TYPE startup_width_erase_func(TIMEOUT_ARGS) { prefs_info *prf = (prefs_info *)context; int_to_textfield(prf->text, ss->init_window_width); TIMEOUT_RESULT } static TIMEOUT_TYPE startup_height_erase_func(TIMEOUT_ARGS) { prefs_info *prf = (prefs_info *)context; int_to_textfield(prf->rtxt, ss->init_window_height); TIMEOUT_RESULT } static void startup_width_error(const char *msg, void *data) { prefs_info *prf = (prefs_info *)data; SET_TEXT(prf->text, "must be > 0"); TIMEOUT(startup_width_erase_func); } static void startup_height_error(const char *msg, void *data) { prefs_info *prf = (prefs_info *)data; SET_TEXT(prf->rtxt, "must be > 0"); TIMEOUT(startup_height_erase_func); } static void startup_size_text(prefs_info *prf) { char *str; str = GET_TEXT(prf->text); if ((str) && (*str)) { int width = 0; redirect_errors_to(startup_width_error, (void *)prf); width = string_to_int(str, 1, "startup width"); redirect_errors_to(NULL, NULL); if (width > 0) ss->init_window_width = width; free_TEXT(str); str = GET_TEXT(prf->rtxt); if ((str) && (*str)) { int height; redirect_errors_to(startup_height_error, (void *)prf); height = string_to_int(str, 1, "startup height"); redirect_errors_to(NULL, NULL); if (height > 0) ss->init_window_height = height; free_TEXT(str); } } } /* ---------------- ask-about-unsaved-edits ---------------- */ static bool rts_unsaved_edits = DEFAULT_ASK_ABOUT_UNSAVED_EDITS; static void revert_unsaved_edits(prefs_info *prf) {set_ask_about_unsaved_edits(rts_unsaved_edits);} static void clear_unsaved_edits(prefs_info *prf) {set_ask_about_unsaved_edits(DEFAULT_ASK_ABOUT_UNSAVED_EDITS);} static void save_unsaved_edits(prefs_info *prf, FILE *fd) {rts_unsaved_edits = ask_about_unsaved_edits(ss);} static void reflect_unsaved_edits(prefs_info *prf) {SET_TOGGLE(prf->toggle, ask_about_unsaved_edits(ss));} static void unsaved_edits_toggle(prefs_info *prf) {set_ask_about_unsaved_edits(GET_TOGGLE(prf->toggle));} static const char *help_unsaved_edits(prefs_info *prf) { return("\ This option looks for unsaved edits when you \n\ close a file, or exit Snd. If it finds any, it \n\ asks you whether you want to save them."); } /* ---------------- with-inset-graph ---------------- */ static bool rts_with_inset_graph = DEFAULT_WITH_INSET_GRAPH; static void revert_with_inset_graph(prefs_info *prf) {set_with_inset_graph(rts_with_inset_graph);} static void clear_with_inset_graph(prefs_info *prf) {set_with_inset_graph(DEFAULT_WITH_INSET_GRAPH);} static void reflect_with_inset_graph(prefs_info *prf) {SET_TOGGLE(prf->toggle, with_inset_graph(ss));} static void with_inset_graph_toggle(prefs_info *prf) { set_with_inset_graph(GET_TOGGLE(prf->toggle)); for_each_chan(update_graph); } static void save_with_inset_graph(prefs_info *prf, FILE *fd) { rts_with_inset_graph = GET_TOGGLE(prf->toggle); set_with_inset_graph(rts_with_inset_graph); } static const char *help_inset_graph(prefs_info *prf) { return("\ This option displays a small graph of the entire sound \n\ in the upper right corner of the screen with an indication \n\ of where the current window is. If you click somewhere in the \n\ little graph, the cursor and main window are moved to that spot."); } /* ---------------- with-smpte-label ---------------- */ static bool rts_with_smpte_label = DEFAULT_WITH_SMPTE_LABEL; static void revert_smpte(prefs_info *prf) {set_with_smpte_label(rts_with_smpte_label);} static void clear_smpte(prefs_info *prf) {set_with_smpte_label(DEFAULT_WITH_SMPTE_LABEL);} static void reflect_smpte(prefs_info *prf) {SET_TOGGLE(prf->toggle, with_smpte_label(ss));} static void smpte_toggle(prefs_info *prf) { set_with_smpte_label(GET_TOGGLE(prf->toggle)); for_each_chan(update_graph); } static void save_smpte(prefs_info *prf, FILE *fd) { rts_with_smpte_label = GET_TOGGLE(prf->toggle); set_with_smpte_label(rts_with_smpte_label); } static const char *help_smpte(prefs_info *prf) { return(" This option displays the SMPTE data in the time domain graph. "); } /* ---------------- with-pointer-focus ---------------- */ static bool rts_with_pointer_focus = DEFAULT_WITH_POINTER_FOCUS; static void revert_with_pointer_focus(prefs_info *prf) {set_with_pointer_focus(rts_with_pointer_focus);} static void clear_with_pointer_focus(prefs_info *prf) {set_with_pointer_focus(DEFAULT_WITH_POINTER_FOCUS);} static void with_pointer_focus_toggle(prefs_info *prf) {set_with_pointer_focus(GET_TOGGLE(prf->toggle));} static void reflect_with_pointer_focus(prefs_info *prf) {SET_TOGGLE(prf->toggle, with_pointer_focus(ss));} static void save_with_pointer_focus(prefs_info *prf, FILE *fd) { rts_with_pointer_focus = GET_TOGGLE(prf->toggle); set_with_pointer_focus(rts_with_pointer_focus); } static const char *help_pointer_focus(prefs_info *prf) { return("\ If this option is set, when the mouse moves over a \n\ text or graph widget, the widget is activated. "); } /* ---------------- cursor-size ---------------- */ static int rts_cursor_size = DEFAULT_CURSOR_SIZE; #define MIN_CURSOR_SIZE 1 #define MAX_CURSOR_SIZE 500 static void revert_cursor_size(prefs_info *prf) {set_cursor_size(rts_cursor_size);} static void save_cursor_size(prefs_info *prf, FILE *ignore) {rts_cursor_size = cursor_size(ss);} static void reflect_cursor_size(prefs_info *prf) { int_to_textfield(prf->text, cursor_size(ss)); SET_SENSITIVE(prf->arrow_up, cursor_size(ss) < MAX_CURSOR_SIZE); SET_SENSITIVE(prf->arrow_down, cursor_size(ss) > MIN_CURSOR_SIZE); } static void cursor_size_up(prefs_info *prf) { int size; size = cursor_size(ss) + 1; if (size >= MAX_CURSOR_SIZE) SET_SENSITIVE(prf->arrow_up, false); if (size > MIN_CURSOR_SIZE) SET_SENSITIVE(prf->arrow_down, true); set_cursor_size(size); int_to_textfield(prf->text, cursor_size(ss)); } static void cursor_size_down(prefs_info *prf) { int size; size = cursor_size(ss) - 1; if (size <= MIN_CURSOR_SIZE) SET_SENSITIVE(prf->arrow_down, false); if (size < MAX_CURSOR_SIZE) SET_SENSITIVE(prf->arrow_up, true); set_cursor_size(size); int_to_textfield(prf->text, cursor_size(ss)); } static void cursor_size_from_text(prefs_info *prf) { char *str; str = GET_TEXT(prf->text); if ((str) && (*str)) { int size; prf->got_error = false; redirect_errors_to(redirect_post_prefs_error, (void *)prf); size = string_to_int(str, 0, "cursor size"); redirect_errors_to(NULL, NULL); free_TEXT(str); if (!(prf->got_error)) { if (size >= MIN_CURSOR_SIZE) { if (size <= MAX_CURSOR_SIZE) set_cursor_size(size); else va_post_prefs_error("%s > %d?", prf, str, MAX_CURSOR_SIZE); } else va_post_prefs_error("%s < %d?", prf, str, MIN_CURSOR_SIZE); } else prf->got_error = false; } else post_prefs_error("no size?", prf); } /* ---------------- dot-size ---------------- */ static int rts_dot_size = DEFAULT_DOT_SIZE; #define MIN_DOT_SIZE 0 #define MAX_DOT_SIZE 100 static void revert_dot_size(prefs_info *prf) {set_dot_size(rts_dot_size);} static void save_dot_size(prefs_info *prf, FILE *ignore) {rts_dot_size = dot_size(ss);} static void reflect_dot_size(prefs_info *prf) { int_to_textfield(prf->text, dot_size(ss)); SET_SENSITIVE(prf->arrow_up, dot_size(ss) < MAX_DOT_SIZE); SET_SENSITIVE(prf->arrow_down, dot_size(ss) > MIN_DOT_SIZE); } static void dot_size_up(prefs_info *prf) { int size; size = dot_size(ss) + 1; if (size >= MAX_DOT_SIZE) SET_SENSITIVE(prf->arrow_up, false); if (size > MIN_DOT_SIZE) SET_SENSITIVE(prf->arrow_down, true); set_dot_size(size); int_to_textfield(prf->text, dot_size(ss)); } static void dot_size_down(prefs_info *prf) { int size; size = dot_size(ss) - 1; if (size <= MIN_DOT_SIZE) SET_SENSITIVE(prf->arrow_down, false); if (size < MAX_DOT_SIZE) SET_SENSITIVE(prf->arrow_up, true); set_dot_size(size); int_to_textfield(prf->text, dot_size(ss)); } static void dot_size_from_text(prefs_info *prf) { char *str; str = GET_TEXT(prf->text); if ((str) && (*str)) { int size; prf->got_error = false; redirect_errors_to(redirect_post_prefs_error, (void *)prf); size = string_to_int(str, 0, "dot size"); redirect_errors_to(NULL, NULL); free_TEXT(str); if (!(prf->got_error)) { if (size >= MIN_DOT_SIZE) { if (size <= MAX_DOT_SIZE) set_dot_size(size); else va_post_prefs_error("%s > %d?", prf, str, MAX_DOT_SIZE); } else va_post_prefs_error("%s < %d?", prf, str, MIN_DOT_SIZE); } else prf->got_error = false; } else post_prefs_error("no size?", prf); } /* ---------------- fft-size ---------------- */ static mus_long_t rts_fft_size = DEFAULT_TRANSFORM_SIZE; #define MAX_TRANSFORM_SIZE 1073741824 #define MIN_TRANSFORM_SIZE 2 static void revert_fft_size(prefs_info *prf) {set_transform_size(rts_fft_size);} static void save_fft_size(prefs_info *prf, FILE *ignore) {rts_fft_size = transform_size(ss);} static void reflect_fft_size(prefs_info *prf) { mus_long_t_to_textfield(prf->text, transform_size(ss)); SET_SENSITIVE(prf->arrow_up, transform_size(ss) < MAX_TRANSFORM_SIZE); SET_SENSITIVE(prf->arrow_down, transform_size(ss) > MIN_TRANSFORM_SIZE); } static void fft_size_up(prefs_info *prf) { mus_long_t size; size = transform_size(ss) * 2; if (size >= MAX_TRANSFORM_SIZE) SET_SENSITIVE(prf->arrow_up, false); if (size > MIN_TRANSFORM_SIZE) SET_SENSITIVE(prf->arrow_down, true); set_transform_size(size); mus_long_t_to_textfield(prf->text, transform_size(ss)); } static void fft_size_down(prefs_info *prf) { mus_long_t size; size = transform_size(ss) / 2; if (size <= MIN_TRANSFORM_SIZE) SET_SENSITIVE(prf->arrow_down, false); if (size < MAX_TRANSFORM_SIZE) SET_SENSITIVE(prf->arrow_up, true); set_transform_size(size); mus_long_t_to_textfield(prf->text, transform_size(ss)); } static void fft_size_from_text(prefs_info *prf) { char *str; str = GET_TEXT(prf->text); if ((str) && (*str)) { mus_long_t size; prf->got_error = false; redirect_errors_to(redirect_post_prefs_error, (void *)prf); size = string_to_mus_long_t(str, MIN_TRANSFORM_SIZE, "size"); redirect_errors_to(NULL, NULL); free_TEXT(str); if (!(prf->got_error)) { if (is_power_of_2(size)) { if (size <= MAX_TRANSFORM_SIZE) set_transform_size(size); else va_post_prefs_error("%s > %d?", prf, str, MAX_TRANSFORM_SIZE); } else post_prefs_error("size must be a power of 2", prf); } else prf->got_error = false; } } /* ---------------- with-tracking-cursor ---------------- */ static tracking_cursor_t rts_with_tracking_cursor = DEFAULT_WITH_TRACKING_CURSOR; static mus_float_t rts_cursor_update_interval = DEFAULT_CURSOR_UPDATE_INTERVAL; static int rts_cursor_location_offset = DEFAULT_CURSOR_LOCATION_OFFSET; static void revert_with_tracking_cursor(prefs_info *prf) { set_with_tracking_cursor(ss, rts_with_tracking_cursor); set_cursor_update_interval(rts_cursor_update_interval); set_cursor_location_offset(rts_cursor_location_offset); } static void save_with_tracking_cursor(prefs_info *prf, FILE *ignore) { rts_with_tracking_cursor = with_tracking_cursor(ss); rts_cursor_update_interval = cursor_update_interval(ss); rts_cursor_location_offset = cursor_location_offset(ss); } static void reflect_with_tracking_cursor(prefs_info *prf) { SET_TOGGLE(prf->toggle, (with_tracking_cursor(ss) != DONT_TRACK)); int_to_textfield(prf->rtxt, cursor_location_offset(ss)); float_to_textfield(prf->text, cursor_update_interval(ss)); } static void with_tracking_cursor_toggle(prefs_info *prf) { set_with_tracking_cursor(ss, (GET_TOGGLE(prf->toggle)) ? TRACK_AND_RETURN : DONT_TRACK); } static void cursor_location_text(prefs_info *prf) { char *str; str = GET_TEXT(prf->text); if ((str) && (*str)) { float interval; redirect_errors_to(any_error_to_text, (void *)prf); interval = (float)string_to_mus_float_t(str, 0.0, "cursor offset"); redirect_errors_to(NULL, NULL); if (!(prf->got_error)) set_cursor_update_interval(interval); free_TEXT(str); str = GET_TEXT(prf->rtxt); if ((str) && (*str)) { int loc; redirect_errors_to(any_error_to_text, (void *)prf); loc = string_to_int(str, 0, "cursor offset"); redirect_errors_to(NULL, NULL); if (!(prf->got_error)) set_cursor_location_offset(loc); free_TEXT(str); } } } /* ---------------- channel-style ---------------- */ static channel_style_t rts_channel_style = DEFAULT_CHANNEL_STYLE; static const char *channel_styles[NUM_CHANNEL_STYLES] = {"separate ", "combined ", "superimposed"}; static void reflect_channel_style(prefs_info *prf) {set_radio_button(prf, (int)channel_style(ss));} static void revert_channel_style(prefs_info *prf) {set_channel_style(rts_channel_style);} static void save_channel_style(prefs_info *prf, FILE *ignore) {rts_channel_style = channel_style(ss);} static void channel_style_choice(prefs_info *prf) { if (GET_TOGGLE(prf->radio_button)) set_channel_style((channel_style_t)which_radio_button(prf)); } /* ---------------- cursor-style ---------------- */ static cursor_style_t rts_cursor_style = DEFAULT_CURSOR_STYLE; #define NUM_CURSOR_STYLES 2 static const char *cursor_styles[NUM_CURSOR_STYLES] = {"cross ", "line"}; static void reflect_cursor_style(prefs_info *prf) {set_radio_button(prf, (int)cursor_style(ss));} static void revert_cursor_style(prefs_info *prf) {set_cursor_style(rts_cursor_style);} static void save_cursor_style(prefs_info *prf, FILE *ignore) {rts_cursor_style = cursor_style(ss);} static void cursor_style_choice(prefs_info *prf) { if (GET_TOGGLE(prf->radio_button)) set_cursor_style((cursor_style_t)which_radio_button(prf)); } /* ---------------- tracking-cursor-style ---------------- */ static cursor_style_t rts_tracking_cursor_style = DEFAULT_CURSOR_STYLE; static void reflect_tracking_cursor_style(prefs_info *prf) {set_radio_button(prf, (int)tracking_cursor_style(ss));} static void revert_tracking_cursor_style(prefs_info *prf) {in_set_tracking_cursor_style(rts_tracking_cursor_style);} static void save_tracking_cursor_style(prefs_info *prf, FILE *ignore) {rts_tracking_cursor_style = tracking_cursor_style(ss);} static void tracking_cursor_style_choice(prefs_info *prf) { if (GET_TOGGLE(prf->radio_button)) in_set_tracking_cursor_style((cursor_style_t)which_radio_button(prf)); } /* ---------------- transform-graph-type ---------------- */ static graph_type_t rts_transform_graph_type = DEFAULT_TRANSFORM_GRAPH_TYPE; #define NUM_TRANSFORM_GRAPH_TYPES 3 static const char *transform_graph_types[NUM_TRANSFORM_GRAPH_TYPES] = {"normal ", "sonogram ", "spectrogram"}; static void reflect_transform_graph_type(prefs_info *prf) {set_radio_button(prf, (int)transform_graph_type(ss));} static void revert_transform_graph_type(prefs_info *prf) {set_transform_graph_type(rts_transform_graph_type);} static void save_transform_graph_type(prefs_info *prf, FILE *ignore) {rts_transform_graph_type = transform_graph_type(ss);} static void transform_graph_type_choice(prefs_info *prf) { if (GET_TOGGLE(prf->radio_button)) set_transform_graph_type((graph_type_t)which_radio_button(prf)); } /* ---------------- transform-normalization ---------------- */ static fft_normalize_t rts_transform_normalization = DEFAULT_TRANSFORM_NORMALIZATION; static const char *transform_normalizations[NUM_TRANSFORM_NORMALIZATIONS] = {"none ", "by channel ", "by sound ", "global"}; static void reflect_transform_normalization(prefs_info *prf) {set_radio_button(prf, (int)transform_normalization(ss));} static void revert_transform_normalization(prefs_info *prf) {set_transform_normalization(rts_transform_normalization);} static void save_transform_normalization(prefs_info *prf, FILE *ignore) {rts_transform_normalization = transform_normalization(ss);} static void transform_normalization_choice(prefs_info *prf) { if (GET_TOGGLE(prf->radio_button)) set_transform_normalization((fft_normalize_t)which_radio_button(prf)); } /* ---------------- graph-style ---------------- */ static graph_style_t rts_graph_style = DEFAULT_GRAPH_STYLE; static const char *graph_styles[NUM_GRAPH_STYLES] = {"line ", "dot ", "filled ", "dot+line ", "lollipop"}; static void reflect_graph_style(prefs_info *prf) {set_radio_button(prf, (int)graph_style(ss));} static void revert_graph_style(prefs_info *prf) {set_graph_style(rts_graph_style);} static void save_graph_style(prefs_info *prf, FILE *ignore) {rts_graph_style = graph_style(ss);} static void graph_style_choice(prefs_info *prf) { if (GET_TOGGLE(prf->radio_button)) set_graph_style((graph_style_t)which_radio_button(prf)); } /* ---------------- speed control ---------------- */ static speed_style_t rts_speed_control_style = DEFAULT_SPEED_CONTROL_STYLE; static int rts_speed_control_tones = DEFAULT_SPEED_CONTROL_TONES; #define MIN_SPEED_CONTROL_SEMITONES 1 static const char *speed_control_styles[NUM_SPEED_CONTROL_STYLES] = {"float ", "ratio ", "semitones:"}; static void show_speed_control_semitones(prefs_info *prf) { int_to_textfield(prf->text, speed_control_tones(ss)); SET_SENSITIVE(prf->arrow_down, (speed_control_tones(ss) > MIN_SPEED_CONTROL_SEMITONES)); } static void speed_control_up(prefs_info *prf) { in_set_speed_control_tones(ss, speed_control_tones(ss) + 1); show_speed_control_semitones(prf); } static void speed_control_down(prefs_info *prf) { in_set_speed_control_tones(ss, speed_control_tones(ss) - 1); show_speed_control_semitones(prf); } static void speed_control_text(prefs_info *prf) { char *str; str = GET_TEXT(prf->text); if ((str) && (*str)) { int tones; prf->got_error = false; redirect_errors_to(redirect_post_prefs_error, (void *)prf); tones = string_to_int(str, MIN_SPEED_CONTROL_SEMITONES, "semitones"); redirect_errors_to(NULL, NULL); free_TEXT(str); if (!(prf->got_error)) { in_set_speed_control_tones(ss, tones); SET_SENSITIVE(prf->arrow_down, (speed_control_tones(ss) > MIN_SPEED_CONTROL_SEMITONES)); } else prf->got_error = false; } } static void reflect_speed_control(prefs_info *prf) { set_radio_button(prf, (int)speed_control_style(ss)); show_speed_control_semitones(prf); } static void speed_control_choice(prefs_info *prf) { if (GET_TOGGLE(prf->radio_button)) in_set_speed_control_style(ss, (speed_style_t)which_radio_button(prf)); } static void revert_speed_control(prefs_info *prf) { in_set_speed_control_style(ss, rts_speed_control_style); in_set_speed_control_tones(ss, rts_speed_control_tones); } static void save_speed_control(prefs_info *prf, FILE *ignore) { rts_speed_control_style = speed_control_style(ss); rts_speed_control_tones = speed_control_tones(ss); } /* ---------------- default-output-chans etc ---------------- */ static int rts_default_output_chans = DEFAULT_OUTPUT_CHANS; static int rts_default_output_srate = DEFAULT_OUTPUT_SRATE; static mus_sample_t rts_default_output_sample_type = DEFAULT_OUTPUT_SAMPLE_TYPE; static mus_header_t rts_default_output_header_type = DEFAULT_OUTPUT_HEADER_TYPE; static prefs_info *output_sample_type_prf = NULL, *output_header_type_prf = NULL; #define NUM_OUTPUT_CHAN_CHOICES 4 static const char *output_chan_choices[NUM_OUTPUT_CHAN_CHOICES] = {"1 ", "2 ", "4 ", "8"}; static int output_chans[NUM_OUTPUT_CHAN_CHOICES] = {1, 2, 4, 8}; #define NUM_OUTPUT_SRATE_CHOICES 4 static const char *output_srate_choices[NUM_OUTPUT_SRATE_CHOICES] = {"8000 ", "22050 ", "44100 ", "48000"}; static int output_srates[NUM_OUTPUT_SRATE_CHOICES] = {8000, 22050, 44100, 48000}; #define NUM_OUTPUT_HEADER_TYPE_CHOICES 7 static const char *output_header_type_choices[NUM_OUTPUT_HEADER_TYPE_CHOICES] = {"aifc ", "wave ", "au ", "rf64 ", "nist ", "aiff ", "caff"}; static mus_header_t output_header_types[NUM_OUTPUT_HEADER_TYPE_CHOICES] = {MUS_AIFC, MUS_RIFF, MUS_NEXT, MUS_RF64, MUS_NIST, MUS_AIFF, MUS_CAFF}; #define NUM_OUTPUT_SAMPLE_TYPE_CHOICES 4 static const char *output_sample_type_choices[NUM_OUTPUT_SAMPLE_TYPE_CHOICES] = {"short ", "int ", "float ", "double"}; static mus_sample_t output_sample_types[NUM_OUTPUT_SAMPLE_TYPE_CHOICES] = {MUS_LSHORT, MUS_LINT, MUS_LFLOAT, MUS_LDOUBLE}; static mus_sample_t header_to_sample_type(mus_header_t ht, mus_sample_t samp_type) { /* nist -> short or int (lb) aiff -> short or int (b) aifc -> any (b) next -> any (b) wave -> any (l) caff -> any */ switch (ht) { case MUS_NEXT: case MUS_AIFC: switch (samp_type) { case MUS_LSHORT: return(MUS_BSHORT); break; case MUS_LINT: return(MUS_BINT); break; case MUS_LFLOAT: return(MUS_BFLOAT); break; case MUS_LDOUBLE: return(MUS_BDOUBLE); break; default: break; } break; case MUS_AIFF: switch (samp_type) { case MUS_LSHORT: return(MUS_BSHORT); break; case MUS_LINT: return(MUS_BINT); break; case MUS_LFLOAT: case MUS_LDOUBLE: case MUS_BFLOAT: case MUS_BDOUBLE: return(MUS_BINT); break; default: break; } break; case MUS_NIST: switch (samp_type) { case MUS_LFLOAT: case MUS_LDOUBLE: return(MUS_LINT); break; case MUS_BFLOAT: case MUS_BDOUBLE: return(MUS_BINT); break; default: break; } break; case MUS_RF64: case MUS_RIFF: switch (samp_type) { case MUS_BSHORT: return(MUS_LSHORT); break; case MUS_BINT: return(MUS_LINT); break; case MUS_BFLOAT: return(MUS_LFLOAT); break; case MUS_BDOUBLE: return(MUS_LDOUBLE); break; default: break; } break; case MUS_CAFF: if (samp_type == MUS_LINT) return(MUS_LINTN); if (samp_type == MUS_BINT) return(MUS_BINTN); break; default: break; } return(samp_type); } static int chans_to_button(int chans) { int i; for (i = 0; i < NUM_OUTPUT_CHAN_CHOICES; i++) if (chans == output_chans[i]) return(i); return(0); } static void reflect_default_output_chans(prefs_info *prf) {set_radio_button(prf, chans_to_button(default_output_chans(ss)));} static void revert_default_output_chans(prefs_info *prf) {set_default_output_chans(rts_default_output_chans);} static void save_default_output_chans(prefs_info *prf, FILE *ignore) {rts_default_output_chans = default_output_chans(ss);} static void default_output_chans_choice(prefs_info *prf) { if (GET_TOGGLE(prf->radio_button)) set_default_output_chans(output_chans[which_radio_button(prf)]); } static int srate_to_button(int srate) { int i; for (i = 0; i < NUM_OUTPUT_SRATE_CHOICES; i++) if (output_srates[i] == srate) return(i); return(0); } static void reflect_default_output_srate(prefs_info *prf) {set_radio_button(prf, srate_to_button(default_output_srate(ss)));} static void revert_default_output_srate(prefs_info *prf) {set_default_output_srate(rts_default_output_srate);} static void save_default_output_srate(prefs_info *prf, FILE *ignore) {rts_default_output_srate = default_output_srate(ss);} static void default_output_srate_choice(prefs_info *prf) { if (GET_TOGGLE(prf->radio_button)) set_default_output_srate(output_srates[which_radio_button(prf)]); } static void reflect_default_output_header_type(prefs_info *prf) { int which = -1; switch (default_output_header_type(ss)) { case MUS_AIFC: which = 0; break; case MUS_AIFF: which = 5; break; case MUS_RIFF: which = 1; break; case MUS_RF64: which = 3; break; case MUS_NEXT: which = 2; break; case MUS_NIST: which = 4; break; case MUS_CAFF: which = 6; break; default: break; } set_radio_button(prf, which); } static void revert_default_output_header_type(prefs_info *prf) { set_default_output_header_type(rts_default_output_header_type); } static void save_default_output_header_type(prefs_info *prf, FILE *ignore) { rts_default_output_header_type = default_output_header_type(ss); } static void reflect_default_output_sample_type(prefs_info *prf) { int which = -1; switch (default_output_sample_type(ss)) { case MUS_LINT: case MUS_BINT: which = 1; break; case MUS_LSHORT: case MUS_BSHORT: which = 0; break; case MUS_LFLOAT: case MUS_BFLOAT: which = 2; break; case MUS_LDOUBLE: case MUS_BDOUBLE: which = 3; break; default: break; } set_radio_button(prf, which); } static void default_output_header_type_choice(prefs_info *prf) { if (GET_TOGGLE(prf->radio_button)) { set_default_output_header_type(output_header_types[which_radio_button(prf)]); set_default_output_sample_type(header_to_sample_type(default_output_header_type(ss), default_output_sample_type(ss))); reflect_default_output_sample_type(output_sample_type_prf); } } static void revert_default_output_sample_type(prefs_info *prf) { set_default_output_sample_type(rts_default_output_sample_type); } static void save_default_output_sample_type(prefs_info *prf, FILE *ignore) { rts_default_output_sample_type = default_output_sample_type(ss); } static void default_output_sample_type_choice(prefs_info *prf) { if (GET_TOGGLE(prf->radio_button)) { int which; which = which_radio_button(prf); set_default_output_sample_type(output_sample_types[which]); switch (default_output_sample_type(ss)) { case MUS_LSHORT: switch (default_output_header_type(ss)) { case MUS_AIFC: case MUS_AIFF: case MUS_NEXT: set_default_output_sample_type(MUS_BSHORT); break; default: break; } break; case MUS_LINT: switch (default_output_header_type(ss)) { case MUS_AIFC: case MUS_AIFF: case MUS_NEXT: set_default_output_sample_type(MUS_BINT); break; default: break; } break; case MUS_LFLOAT: switch (default_output_header_type(ss)) { case MUS_AIFC: case MUS_NEXT: set_default_output_sample_type(MUS_BFLOAT); break; case MUS_AIFF: set_default_output_header_type(MUS_AIFC); set_default_output_sample_type(MUS_BFLOAT); break; case MUS_NIST: set_default_output_header_type(MUS_RIFF); break; default: break; } break; case MUS_LDOUBLE: switch (default_output_header_type(ss)) { case MUS_AIFC: case MUS_NEXT: set_default_output_sample_type(MUS_BDOUBLE); break; case MUS_AIFF: set_default_output_header_type(MUS_AIFC); set_default_output_sample_type(MUS_BDOUBLE); break; case MUS_NIST: set_default_output_header_type(MUS_RIFF); break; default: break; } break; default: break; } reflect_default_output_header_type(output_header_type_prf); } } /* ---------------- raw sound defaults ---------------- */ static int rts_raw_chans = DEFAULT_OUTPUT_CHANS; static int rts_raw_srate = DEFAULT_OUTPUT_SRATE; static mus_sample_t rts_raw_sample_type = DEFAULT_OUTPUT_SAMPLE_TYPE; static void revert_raw_chans(prefs_info *prf) { int srate = 0, chans = 0; mus_sample_t samp_type = MUS_UNKNOWN_SAMPLE; mus_header_raw_defaults(&srate, &chans, &samp_type); chans = rts_raw_chans; mus_header_set_raw_defaults(srate, chans, samp_type); } static void save_raw_chans(prefs_info *prf, FILE *ignore) { int srate = 0, chans = 0; mus_sample_t samp_type = MUS_UNKNOWN_SAMPLE; mus_header_raw_defaults(&srate, &chans, &samp_type); rts_raw_chans = chans; } static void reflect_raw_chans(prefs_info *prf) { int srate = 0, chans = 0; mus_sample_t samp_type = MUS_UNKNOWN_SAMPLE; mus_header_raw_defaults(&srate, &chans, &samp_type); int_to_textfield(prf->text, chans); } static void raw_chans_choice(prefs_info *prf) { char *str; str = GET_TEXT(prf->text); if (str) { int srate = 0, chans = 0; mus_sample_t samp_type = MUS_UNKNOWN_SAMPLE; mus_header_raw_defaults(&srate, &chans, &samp_type); redirect_errors_to(any_error_to_text, (void *)prf); chans = string_to_int(str, 1, "raw chans"); redirect_errors_to(NULL, NULL); if (!(prf->got_error)) mus_header_set_raw_defaults(srate, chans, samp_type); free_TEXT(str); } } static void revert_raw_srate(prefs_info *prf) { int srate = 0, chans = 0; mus_sample_t samp_type = MUS_UNKNOWN_SAMPLE; mus_header_raw_defaults(&srate, &chans, &samp_type); srate = rts_raw_srate; mus_header_set_raw_defaults(srate, chans, samp_type); } static void save_raw_srate(prefs_info *prf, FILE *ignore) { int srate = 0, chans = 0; mus_sample_t samp_type = MUS_UNKNOWN_SAMPLE; mus_header_raw_defaults(&srate, &chans, &samp_type); rts_raw_srate = srate; } static void reflect_raw_srate(prefs_info *prf) { int srate = 0, chans = 0; mus_sample_t samp_type = MUS_UNKNOWN_SAMPLE; mus_header_raw_defaults(&srate, &chans, &samp_type); int_to_textfield(prf->text, srate); } static void raw_srate_choice(prefs_info *prf) { char *str; str = GET_TEXT(prf->text); if (str) { int srate = 0, chans = 0; mus_sample_t samp_type = MUS_UNKNOWN_SAMPLE; mus_header_raw_defaults(&srate, &chans, &samp_type); redirect_errors_to(any_error_to_text, (void *)prf); srate = string_to_int(str, 1, "raw srate"); redirect_errors_to(NULL, NULL); if (!(prf->got_error)) mus_header_set_raw_defaults(srate, chans, samp_type); free_TEXT(str); } } static char *raw_sample_type_to_string(mus_sample_t samp_type) { /* the "mus-" prefix carries no information in this context, so strip it off */ const char *name; name = mus_sample_type_to_string(samp_type); if (name) { char *rtn; int i, j, len; len = strlen(name); rtn = (char *)calloc(len, sizeof(char)); for (i = 0, j = 4; j < len; i++, j++) { if (name[j] == '-') { rtn[i] = 'u'; return(rtn); } else rtn[i] = name[j]; } return(rtn); } return(mus_strdup("unknown")); } static void revert_raw_sample_type(prefs_info *prf) { int srate = 0, chans = 0; mus_sample_t samp_type = MUS_UNKNOWN_SAMPLE; mus_header_raw_defaults(&srate, &chans, &samp_type); samp_type = rts_raw_sample_type; mus_header_set_raw_defaults(srate, chans, samp_type); } static void save_raw_sample_type(prefs_info *prf, FILE *ignore) { int srate = 0, chans = 0; mus_sample_t samp_type = MUS_UNKNOWN_SAMPLE; mus_header_raw_defaults(&srate, &chans, &samp_type); rts_raw_sample_type = samp_type; } static void reflect_raw_sample_type(prefs_info *prf) { int srate = 0, chans = 0; mus_sample_t samp_type = MUS_UNKNOWN_SAMPLE; char *str; mus_header_raw_defaults(&srate, &chans, &samp_type); str = raw_sample_type_to_string(samp_type); SET_TEXT(prf->text, str); free(str); } static char **raw_sample_type_choices = NULL; static void raw_sample_type_from_text(prefs_info *prf) { char *str; str = GET_TEXT(prf->text); if (str) { int i, srate = 0, chans = 0; mus_sample_t samp_type = MUS_UNKNOWN_SAMPLE; mus_header_raw_defaults(&srate, &chans, &samp_type); for (i = 0; i < MUS_NUM_SAMPLES - 1; i++) if (STRCMP(raw_sample_type_choices[i], str) == 0) { mus_header_set_raw_defaults(srate, chans, (mus_sample_t)(i + 1)); /* skipping MUS_UNKNOWN_SAMPLE = 0 */ reflect_raw_sample_type(prf); free_TEXT(str); return; } } } #if USE_MOTIF static void raw_sample_type_from_menu(prefs_info *prf, char *value) { int i, srate = 0, chans = 0; mus_sample_t samp_type = MUS_UNKNOWN_SAMPLE; mus_header_raw_defaults(&srate, &chans, &samp_type); for (i = 0; i < MUS_NUM_SAMPLES - 1; i++) if (STRCMP(raw_sample_type_choices[i], value) == 0) { mus_header_set_raw_defaults(srate, chans, (mus_sample_t)(i + 1)); SET_TEXT(prf->text, raw_sample_type_choices[i]); return; } } #endif /* ---------------- with-toolbar ---------------- */ static bool rts_with_toolbar = DEFAULT_WITH_TOOLBAR; static const char *help_with_toolbar(prefs_info *prf) { return(" If this is set, a toolbar is displayed. "); } static void revert_with_toolbar(prefs_info *prf) {set_with_toolbar_and_display(rts_with_toolbar);} static void clear_with_toolbar(prefs_info *prf) {set_with_toolbar_and_display(DEFAULT_WITH_TOOLBAR);} static void reflect_with_toolbar(prefs_info *prf) {SET_TOGGLE(prf->toggle, with_toolbar(ss));} static void save_with_toolbar(prefs_info *prf, FILE *fd) {rts_with_toolbar = with_toolbar(ss);} static void toggle_with_toolbar(prefs_info *prf) {set_with_toolbar_and_display(GET_TOGGLE(prf->toggle));} /* ---------------- with-tooltips ---------------- */ static bool rts_with_tooltips = DEFAULT_WITH_TOOLTIPS; static const char *help_with_tooltips(prefs_info *prf) { return(" If this is set, tooltips may be displayed. "); } static void revert_with_tooltips(prefs_info *prf) {set_with_tooltips(rts_with_tooltips);} static void clear_with_tooltips(prefs_info *prf) {set_with_tooltips(DEFAULT_WITH_TOOLTIPS);} static void reflect_with_tooltips(prefs_info *prf) {SET_TOGGLE(prf->toggle, with_tooltips(ss));} static void save_with_tooltips(prefs_info *prf, FILE *fd) {rts_with_tooltips = with_tooltips(ss);} static void toggle_with_tooltips(prefs_info *prf) {set_with_tooltips(GET_TOGGLE(prf->toggle));} #if USE_GTK /* ---------------- with-menu-icons ---------------- */ static bool rts_with_menu_icons = DEFAULT_WITH_MENU_ICONS; static const char *help_with_menu_icons(prefs_info *prf) { return(" If this is set, some menus include icons. "); } static void revert_with_menu_icons(prefs_info *prf) {set_with_menu_icons(rts_with_menu_icons);} static void clear_with_menu_icons(prefs_info *prf) {set_with_menu_icons(DEFAULT_WITH_MENU_ICONS);} static void reflect_with_menu_icons(prefs_info *prf) {SET_TOGGLE(prf->toggle, with_menu_icons(ss));} static void save_with_menu_icons(prefs_info *prf, FILE *fd) {rts_with_menu_icons = with_menu_icons(ss);} static void toggle_with_menu_icons(prefs_info *prf) {set_with_menu_icons(GET_TOGGLE(prf->toggle));} #endif /* ---------------- remember-sound-state ---------------- */ static bool rts_remember_sound_state = DEFAULT_REMEMBER_SOUND_STATE; static const char *help_remember_sound_state(prefs_info *prf) { return("\ This option causes Snd to save most of a sound's display \n\ state when it is closed, and if that same sound is later re-opened, \n\ Snd restores the previous state. This only takes effect upon restarting Snd."); } static void revert_remember_sound_state(prefs_info *prf) {set_remember_sound_state(rts_remember_sound_state);} static void clear_remember_sound_state(prefs_info *prf) {set_remember_sound_state(DEFAULT_REMEMBER_SOUND_STATE);} static void reflect_remember_sound_state(prefs_info *prf) {SET_TOGGLE(prf->toggle, remember_sound_state(ss));} static void save_remember_sound_state(prefs_info *prf, FILE *fd) {rts_remember_sound_state = remember_sound_state(ss);} static void toggle_remember_sound_state(prefs_info *prf) {set_remember_sound_state(GET_TOGGLE(prf->toggle));} /* ---------------- show-axes ---------------- */ static show_axes_t rts_show_axes = DEFAULT_SHOW_AXES; static const char *show_axes_choices[NUM_SHOW_AXES] = {"none", "X and Y", "just X", "X and Y unlabelled", "just X unlabelled", "bare X"}; static void reflect_show_axes(prefs_info *prf) {SET_TEXT(prf->text, (char *)show_axes_choices[(int)show_axes(ss)]);} static void revert_show_axes(prefs_info *prf) {set_show_axes(rts_show_axes);} static void clear_show_axes(prefs_info *prf) {set_show_axes(DEFAULT_SHOW_AXES);} static void save_show_axes(prefs_info *prf, FILE *ignore) {rts_show_axes = show_axes(ss);} #if USE_MOTIF static void show_axes_from_menu(prefs_info *prf, char *value) { int i; for (i = 0; i < NUM_SHOW_AXES; i++) if (mus_strcmp(value, show_axes_choices[i])) { set_show_axes((show_axes_t)i); SET_TEXT(prf->text, value); return; } } #endif static void show_axes_from_text(prefs_info *prf) { char *str; str = GET_TEXT(prf->text); if ((str) && (*str)) { char *trimmed_str; trimmed_str = trim_string(str); free_TEXT(str); if (mus_strlen(trimmed_str) > 0) { int i, curpos = -1; for (i = 0; i < NUM_SHOW_AXES; i++) if (STRCMP(trimmed_str, show_axes_choices[i]) == 0) { curpos = i; break; } if (curpos >= 0) set_show_axes((show_axes_t)curpos); else post_prefs_error("unknown axis choice", prf); } else post_prefs_error("need an axis choice", prf); free(trimmed_str); } else post_prefs_error("need an axis choice", prf); } /* ---------------- x-axis-style ---------------- */ static x_axis_style_t rts_x_axis_style = DEFAULT_X_AXIS_STYLE; static const char *x_axis_styles[NUM_X_AXIS_STYLES] = {"seconds", "samples", "% of total", "beats", "measures", "clock"}; static void reflect_x_axis_style(prefs_info *prf) {SET_TEXT(prf->text, (char *)x_axis_styles[(int)x_axis_style(ss)]);} static void revert_x_axis_style(prefs_info *prf) {set_x_axis_style(rts_x_axis_style);} static void clear_x_axis_style(prefs_info *prf) {set_x_axis_style(DEFAULT_X_AXIS_STYLE);} static void save_x_axis_style(prefs_info *prf, FILE *ignore) {rts_x_axis_style = x_axis_style(ss);} #if USE_MOTIF static void x_axis_style_from_menu(prefs_info *prf, char *value) { int i; for (i = 0; i < NUM_X_AXIS_STYLES; i++) if (mus_strcmp(value, x_axis_styles[i])) { set_x_axis_style((x_axis_style_t)i); SET_TEXT(prf->text, value); return; } } #endif static void x_axis_style_from_text(prefs_info *prf) { char *str; str = GET_TEXT(prf->text); if ((str) && (*str)) { char *trimmed_str; trimmed_str = trim_string(str); free_TEXT(str); if (mus_strlen(trimmed_str) > 0) { int i, curpos = -1; for (i = 0; i < NUM_X_AXIS_STYLES; i++) if (STRCMP(trimmed_str, x_axis_styles[i]) == 0) { curpos = i; break; } if (curpos >= 0) set_x_axis_style((x_axis_style_t)curpos); else post_prefs_error("unknown axis style", prf); } else post_prefs_error("need an axis style", prf); free(trimmed_str); } else post_prefs_error("need an axis style", prf); } /* ---------------- transform-type ---------------- */ static int rts_transform_type = DEFAULT_TRANSFORM_TYPE; static const char *transform_types[NUM_BUILTIN_TRANSFORM_TYPES] = {"Fourier", "Wavelet", "Walsh", "Autocorrelate", "Cepstrum", "Haar"}; static list_completer_info *transform_type_completer_info = NULL; static void reflect_transform_type(prefs_info *prf) { SET_TEXT(prf->text, (char *)transform_types[mus_iclamp(0, transform_type(ss), NUM_BUILTIN_TRANSFORM_TYPES - 1)]); } static void revert_transform_type(prefs_info *prf) {set_transform_type(rts_transform_type);} static void clear_transform_type(prefs_info *prf) {set_transform_type(DEFAULT_TRANSFORM_TYPE);} static void save_transform_type(prefs_info *prf, FILE *ignore) {rts_transform_type = transform_type(ss);} static char *transform_type_completer(widget_t w, const char *text, void *data) { if (!transform_type_completer_info) { transform_type_completer_info = (list_completer_info *)calloc(1, sizeof(list_completer_info)); transform_type_completer_info->exact_match = false; transform_type_completer_info->values = (char **)transform_types; transform_type_completer_info->num_values = NUM_BUILTIN_TRANSFORM_TYPES; transform_type_completer_info->values_size = NUM_BUILTIN_TRANSFORM_TYPES; } return(list_completer(w, text, (void *)transform_type_completer_info)); } #if USE_MOTIF static void transform_type_from_menu(prefs_info *prf, char *value) { int i; for (i = 0; i < NUM_BUILTIN_TRANSFORM_TYPES; i++) if (mus_strcmp(value, transform_types[i])) { set_transform_type(i); SET_TEXT(prf->text, value); return; } } #endif static void transform_type_from_text(prefs_info *prf) { char *str; str = GET_TEXT(prf->text); if ((str) && (*str)) { char *trimmed_str; trimmed_str = trim_string(str); free_TEXT(str); if (mus_strlen(trimmed_str) > 0) { int i, curpos = -1; for (i = 0; i < NUM_BUILTIN_TRANSFORM_TYPES; i++) if (STRCMP(trimmed_str, transform_types[i]) == 0) { curpos = i; break; } if (curpos >= 0) set_transform_type(curpos); else post_prefs_error("unknown tranform", prf); } else post_prefs_error("no transform?", prf); free(trimmed_str); } else post_prefs_error("no transform?", prf); } /* -------- fft-window -------- */ static mus_fft_window_t rts_fft_window = DEFAULT_FFT_WINDOW; static void reflect_fft_window(prefs_info *prf) {SET_TEXT(prf->text, (char *)mus_fft_window_name(fft_window(ss)));} static void revert_fft_window(prefs_info *prf) {set_fft_window(rts_fft_window);} static void clear_fft_window(prefs_info *prf) {set_fft_window(DEFAULT_FFT_WINDOW);} static void save_fft_window(prefs_info *prf, FILE *ignore) {rts_fft_window = fft_window(ss);} static list_completer_info *fft_window_completer_info = NULL; static char *fft_window_completer(widget_t w, const char *text, void *data) { if (!fft_window_completer_info) { fft_window_completer_info = (list_completer_info *)calloc(1, sizeof(list_completer_info)); fft_window_completer_info->exact_match = false; fft_window_completer_info->values = (char **)mus_fft_window_names(); fft_window_completer_info->num_values = MUS_NUM_FFT_WINDOWS; fft_window_completer_info->values_size = MUS_NUM_FFT_WINDOWS; } return(list_completer(w, text, (void *)fft_window_completer_info)); } #if USE_MOTIF static void fft_window_from_menu(prefs_info *prf, char *value) { int i; for (i = 0; i < MUS_NUM_FFT_WINDOWS; i++) if (mus_strcmp(value, mus_fft_window_name((mus_fft_window_t)i))) { set_fft_window((mus_fft_window_t)i); SET_TEXT(prf->text, value); return; } } #endif static void fft_window_from_text(prefs_info *prf) { char *str; str = GET_TEXT(prf->text); if ((str) && (*str)) { char *trimmed_str; trimmed_str = trim_string(str); free_TEXT(str); if (mus_strlen(trimmed_str) > 0) { int i, curpos = -1; for (i = 0; i < MUS_NUM_FFT_WINDOWS; i++) if (STRCMP(trimmed_str, mus_fft_window_name((mus_fft_window_t)i)) == 0) { curpos = i; break; } if (curpos >= 0) set_fft_window((mus_fft_window_t)curpos); else post_prefs_error("unknown window", prf); } else post_prefs_error("no window?", prf); free(trimmed_str); } else post_prefs_error("no window?", prf); } /* ---------------- colormap ---------------- */ static int rts_colormap = DEFAULT_COLOR_MAP; static char *colormap_completer(widget_t w, const char *text, void *data) { list_completer_info *compinfo; char **cmaps; int i, len; char *result; len = num_colormaps(); cmaps = (char **)calloc(len, sizeof(char *)); for (i = 0; i < len; i++) cmaps[i] = colormap_name(i); compinfo = (list_completer_info *)calloc(1, sizeof(list_completer_info)); compinfo->exact_match = false; compinfo->values = (char **)mus_fft_window_names(); compinfo->num_values = len; compinfo->values_size = len; result = list_completer(w, text, (void *)compinfo); free(cmaps); return(result); } static void reflect_colormap(prefs_info *prf) {SET_TEXT(prf->text, colormap_name(color_map(ss)));} static void clear_colormap(prefs_info *prf) {set_color_map(DEFAULT_COLOR_MAP);} static void save_colormap(prefs_info *prf, FILE *ignore) {rts_colormap = color_map(ss);} static void revert_colormap(prefs_info *prf) { if (!(is_colormap(rts_colormap))) rts_colormap = DEFAULT_COLOR_MAP; set_color_map(rts_colormap); } static void colormap_from_text(prefs_info *prf) { char *str; str = GET_TEXT(prf->text); if ((str) && (*str)) { char *trimmed_str; trimmed_str = trim_string(str); free_TEXT(str); if (mus_strlen(trimmed_str) > 0) { int i, len, curpos = -1; len = num_colormaps(); for (i = 0; i < len; i++) if ((colormap_name(i)) && (STRCMP(trimmed_str, colormap_name(i)) == 0)) { curpos = i; break; } if (is_colormap(curpos)) set_color_map(curpos); else post_prefs_error("unknown colormap", prf); } else post_prefs_error("no colormap?", prf); free(trimmed_str); } else post_prefs_error("no colormap?", prf); } #if USE_MOTIF static void colormap_from_menu(prefs_info *prf, char *value) { int i, len; len = num_colormaps(); for (i = 0; i < len; i++) if (mus_strcmp(value, colormap_name(i))) { set_color_map(i); SET_TEXT(prf->text, value); return; } } #endif /* ---------------- peak-envs ---------------- */ static bool include_peak_envs = false, rts_peak_envs = false; static char *include_peak_env_directory = NULL, *rts_peak_env_directory = NULL; static const char *help_peak_envs(prefs_info *prf) { return("\ When a very large file is first opened, Snd scans \n\ all the data to build up an overall representation of \n\ the sound. If you like to view the entire sound upon \n\ opening it, you can speed up the process a lot by saving \n\ this initial representation. The data is called a 'peak-env' file \n\ and it resides in the 'peak-env-dir'."); } static bool find_peak_envs(void) { return(peak_env_dir(ss)); } static void clear_peak_envs(prefs_info *prf) { if (include_peak_env_directory) free(include_peak_env_directory); include_peak_env_directory = NULL; include_peak_envs = false; } static void revert_peak_envs(prefs_info *prf) { if (include_peak_env_directory) free(include_peak_env_directory); include_peak_env_directory = mus_strdup(rts_peak_env_directory); include_peak_envs = rts_peak_envs; } static void save_peak_envs(prefs_info *prf, FILE *fd) { rts_peak_envs = GET_TOGGLE(prf->toggle); if (rts_peak_env_directory) free(rts_peak_env_directory); rts_peak_env_directory = mus_strdup(include_peak_env_directory); } static void reflect_peak_envs(prefs_info *prf) { SET_TOGGLE(prf->toggle, include_peak_envs); SET_TEXT(prf->text, include_peak_env_directory); } static void peak_envs_toggle(prefs_info *prf) { include_peak_envs = GET_TOGGLE(prf->toggle); } static void peak_envs_text(prefs_info *prf) { char *str; str = GET_TEXT(prf->text); if ((str) && (*str)) { if (include_peak_env_directory) {free(include_peak_env_directory); include_peak_env_directory = NULL;} include_peak_env_directory = mus_strdup(str); free_TEXT(str); } } /* ---------------- load path ---------------- */ static char *rts_load_path = NULL; static const char *help_load_path(prefs_info *prf) { static char *hlp = NULL; char *temp = NULL; if (hlp) free(hlp); hlp = mus_format("Much of Snd's functionality is loaded as needed \n\ from the Scheme, Ruby, or Forth files found in the Snd tarball. \n\ You can run Snd without these files, but there's no reason to! \n\ Just add the directory containing them to the load path \n\ variable %s. " Xen_language " searches these directories \n\ for any *." Xen_file_extension " files that it can't find elsewhere. \n\ The current load path list is: \n\n%s\n", #if HAVE_RUBY ", $LOAD_PATH", #else #if HAVE_FORTH || HAVE_SCHEME ", *load-path*", #else "", #endif #endif temp = (char *)Xen_object_to_C_string(Xen_load_path)); #if HAVE_SCHEME if (temp) free(temp); #endif return(hlp); } static char *find_sources(void) /* returns directory name where it finds extensions.* */ { char *file = NULL; #define BASE_FILE "extensions." Xen_file_extension #if HAVE_SCHEME /* mimic Forth code below -- get *load-path* value and run through it */ { int i, len, base_len; Xen load_path; load_path = Xen_load_path; len = Xen_list_length(load_path); base_len = strlen(BASE_FILE); for (i = 0; i < len; i++) { char *fname; const char *path; int flen; path = Xen_string_to_C_string(Xen_list_ref(load_path, i)); flen = base_len + 32 + strlen(path); fname = (char *)calloc(flen, sizeof(char)); snprintf(fname, flen, "%s/%s", path, BASE_FILE); if (mus_file_probe(fname)) { file = fname; break; } } } #endif #if HAVE_RUBY { Xen xfile; xfile = rb_find_file(C_string_to_Xen_string(BASE_FILE)); if (Xen_is_string(xfile)) file = mus_expand_filename(Xen_string_to_C_string(xfile)); } #endif #if HAVE_FORTH { /* taken from fth/src/misc.c -- fth_find_file looks for an already-loaded file */ int i, len, base_len; Xen load_path; load_path = Xen_load_path; len = fth_array_length(load_path); base_len = strlen(BASE_FILE); for (i = 0; i < len; i++) { char *fname, *path; int flen; path = fth_string_ref(fth_array_ref(load_path, i)); flen = base_len + 32 + strlen(path); fname = (char *)calloc(flen, sizeof(char)); snprintf(fname, flen, "%s/%s", path, BASE_FILE); if (mus_file_probe(fname)) { file = fname; break; } } } #endif if (file) { int len, exts_len; len = mus_strlen(file); exts_len = strlen(BASE_FILE); if (len > exts_len) file[len - exts_len - 1] = '\0'; return(file); } return(NULL); } static void clear_load_path(prefs_info *prf) { char *str; str = find_sources(); SET_TEXT(prf->text, str); if (str) { black_text(prf); free(str); } else { red_text(prf); } } static void revert_load_path(prefs_info *prf) { SET_TEXT(prf->text, rts_load_path); if (rts_load_path) black_text(prf); else { red_text(prf); } } static void reflect_load_path(prefs_info *prf) {} static void load_path_text(prefs_info *prf) { char *str; str = GET_TEXT(prf->text); if ((!str) || (!(*str))) return; if (local_access(str)) { black_text(prf); if (include_load_path) free(include_load_path); include_load_path = mus_strdup(str); Xen_add_to_load_path(include_load_path); } if (str) {free_TEXT(str);} } /* ---------------- initial bounds ---------------- */ static mus_float_t rts_initial_beg = DEFAULT_INITIAL_BEG, rts_initial_dur = DEFAULT_INITIAL_DUR; static bool rts_full_duration = DEFAULT_SHOW_FULL_DURATION; static const char *help_initial_bounds(prefs_info *prf) { return("\ Normally Snd displays just the first 0.1 seconds of a \n\ sound in its initial graph. This option sets either new \n\ bounds for that display, or directs Snd to display the entire sound."); } static char *initial_bounds_to_string(void) { return(mus_format("%.2f : %.2f", initial_beg(ss), initial_dur(ss))); } static void save_initial_bounds(prefs_info *prf, FILE *fd) { rts_full_duration = GET_TOGGLE(prf->toggle); } static void reflect_initial_bounds(prefs_info *prf) { /* text has beg : dur, toggle true if full dur */ char *str; str = initial_bounds_to_string(); SET_TEXT(prf->text, str); free(str); SET_TOGGLE(prf->toggle, show_full_duration(ss)); } static void revert_initial_bounds(prefs_info *prf) { set_initial_beg(rts_initial_beg); set_initial_dur(rts_initial_dur); set_show_full_duration(rts_full_duration); } static void clear_initial_bounds(prefs_info *prf) { set_initial_beg(DEFAULT_INITIAL_BEG); set_initial_dur(DEFAULT_INITIAL_DUR); set_show_full_duration(DEFAULT_SHOW_FULL_DURATION); } static void initial_bounds_toggle(prefs_info *prf) { set_show_full_duration(GET_TOGGLE(prf->toggle)); } static void initial_bounds_text(prefs_info *prf) { float beg = 0.0, dur = 0.1; char *str; str = GET_TEXT(prf->text); sscanf(str, "%f : %f", &beg, &dur); set_initial_beg(beg); set_initial_dur(dur); free_TEXT(str); } /* ---------------- keys ---------------- */ static void reflect_key(prefs_info *prf, const char *key_name) { key_info *ki; ki = find_prefs_key(key_name); SET_TOGGLE(prf->toggle, ki->c); SET_TOGGLE(prf->toggle2, ki->m); SET_TOGGLE(prf->toggle3, ki->x); SET_TEXT(prf->text, ki->key); free(ki); } static void save_key(prefs_info *prf, FILE *fd, char *(*binder)(char *key, bool c, bool m, bool x)) { char *key; key = GET_TEXT(prf->text); if ((key) && (*key)) { char *expr; expr = (*binder)(key, GET_TOGGLE(prf->toggle), GET_TOGGLE(prf->toggle2), GET_TOGGLE(prf->toggle3)); fprintf(fd, "%s", expr); free(expr); free_TEXT(key); } } static void key_bind(prefs_info *prf, char *(*binder)(char *key, bool c, bool m, bool x)) { char *key; bool ctrl, meta, cx; key = GET_TEXT(prf->text); ctrl = GET_TOGGLE(prf->toggle); meta = GET_TOGGLE(prf->toggle2); cx = GET_TOGGLE(prf->toggle3); if ((key) && (*key)) { char *expr; expr = (*binder)(key, ctrl, meta, cx); free_TEXT(key); Xen_eval_C_string(expr); free(expr); } } static void clear_key(prefs_info *prf, const char *name) { key_info *ki; ki = find_prefs_key(name); if (ki) { if (ki->key) { int state = 0; if (ki->c) state |= 4; if (ki->m) state |= 8; #if USE_MOTIF set_keymap_entry((int)XStringToKeysym(ki->key), state, 0, Xen_undefined, ki->x, name, name); #else set_keymap_entry((int)gdk_keyval_from_name(ki->key), state, 0, Xen_undefined, ki->x, name, name); #endif } free(ki); } } /* -------- key: play all chans from cursor -------- */ static const char *help_play_from_cursor(prefs_info *prf) { return(" This option binds a key to play the entire sound. "); } static char *make_pfc(char *key, bool ctrl, bool meta, bool cx) { #if HAVE_SCHEME return(mus_format("(bind-key %s %d (lambda () (set! (pausing) #f) (play (cursor))) %s \"play sound from cursor\" \"play-from-cursor\")\n", possibly_quote(key), ((ctrl) ? 4 : 0) + ((meta) ? 8 : 0), (cx) ? "#t" : "#f")); #endif #if HAVE_RUBY return(mus_format("bind_key(%s, %d, lambda do\n set_pausing(false)\n play(cursor())\n end, %s, \"play sound from cursor\", \"play-from-cursor\")\n", possibly_quote(key), ((ctrl) ? 4 : 0) + ((meta) ? 8 : 0), (cx) ? "true" : "false")); #endif #if HAVE_FORTH return(mus_format("%s %d lambda: <{ }> #f set-pausing drop #f #f #f cursor play drop ; %s \"play sound from cursor\" \"play-from-cursor\" bind-key drop\n", possibly_quote(key), ((ctrl) ? 4 : 0) + ((meta) ? 8 : 0), (cx) ? "#t" : "#f")); #endif return(NULL); } static void reflect_play_from_cursor(prefs_info *prf) { reflect_key(prf, "play-from-cursor"); } static void save_pfc(prefs_info *prf, FILE *fd) { save_key(prf, fd, make_pfc); } static void bind_play_from_cursor(prefs_info *prf) { key_bind(prf, make_pfc); } static void clear_play_from_cursor(prefs_info *prf) { clear_key(prf, "play-from-cursor"); } /* -------- key: show all of sound -------- */ static const char *help_show_all(prefs_info *prf) { return("\ This option binds a key to show all of the current sound \n\ in the current time domain window, equivalent to moving the \n\ 'zoom' slider all the way to the right."); } static char *make_show_all(char *key, bool ctrl, bool meta, bool cx) { #if HAVE_SCHEME return(mus_format("(bind-key %s %d (lambda () \ (let ((old-sync (sync))) \ (set! (sync) (1+ (sync-max))) \ (set! (x-bounds) (list 0.0 (/ (framples) (srate)))) \ (set! (sync) old-sync))) %s \"show entire sound\" \"show-all\")\n", possibly_quote(key), ((ctrl) ? 4 : 0) + ((meta) ? 8 : 0), (cx) ? "#t" : "#f")); #endif #if HAVE_RUBY return(mus_format("bind_key(%s, %d, lambda do\n\ old_sync = sync()\n\ sync(1 + sync_max())\n\ set_x_bounds([0.0, framples() / srate()])\n\ set_sync(old_sync)\n\ end, %s, \"show entire sound\", \"show-all\")\n", possibly_quote(key), ((ctrl) ? 4 : 0) + ((meta) ? 8 : 0), (cx) ? "true" : "false")); #endif #if HAVE_FORTH return(mus_format("%s %d lambda: <{ }> #f sync sync-max 1+ #f set-sync drop '( 0.0 #f #f #f framples #f srate f/ ) #f #f set-x-bounds drop #f set-sync ; %s \"show entire sound\" \"show-all\" bind-key drop\n", possibly_quote(key), ((ctrl) ? 4 : 0) + ((meta) ? 8 : 0), (cx) ? "#t" : "#f")); #endif return(NULL); } static void reflect_show_all(prefs_info *prf) { reflect_key(prf, "show-all"); } static void save_show_all(prefs_info *prf, FILE *fd) { save_key(prf, fd, make_show_all); } static void bind_show_all(prefs_info *prf) { key_bind(prf, make_show_all); } static void clear_show_all(prefs_info *prf) { clear_key(prf, "show-all"); } /* -------- key: select all of sound -------- */ static const char *help_select_all(prefs_info *prf) { return("\ This option binds a key to select all of the current sound. \n\ The 'Select all' Edit menu item follows the 'sync' buttons when \n\ deciding which channels to select."); } static char *make_select_all(char *key, bool ctrl, bool meta, bool cx) { #if HAVE_SCHEME return(mus_format("(bind-key %s %d (lambda () \ (let ((old-sync (sync))) \ (set! (sync) (1+ (sync-max))) \ (select-all) \ (set! (sync) old-sync))) %s \"select entire sound\" \"select-all\")\n", possibly_quote(key), ((ctrl) ? 4 : 0) + ((meta) ? 8 : 0), (cx) ? "#t" : "#f")); #endif #if HAVE_RUBY return(mus_format("bind_key(%s, %d, lambda do\n\ old_sync = sync()\n\ sync(1 + sync_max())\n\ select_all()\n\ set_sync(old_sync)\n\ end, %s, \"select entire sound\", \"select-all\")\n", possibly_quote(key), ((ctrl) ? 4 : 0) + ((meta) ? 8 : 0), (cx) ? "true" : "false")); #endif #if HAVE_FORTH return(mus_format("%s %d lambda: <{ }> #f sync sync-max 1+ #f set-sync drop #f #f select-all drop #f set-sync ; %s \"select entire sound\" \"select-all\" bind-key drop\n", possibly_quote(key), ((ctrl) ? 4 : 0) + ((meta) ? 8 : 0), (cx) ? "#t" : "#f")); #endif return(NULL); } static void reflect_select_all(prefs_info *prf) { reflect_key(prf, "select-all"); } static void save_select_all(prefs_info *prf, FILE *fd) { save_key(prf, fd, make_select_all); } static void bind_select_all(prefs_info *prf) { key_bind(prf, make_select_all); } static void clear_select_all(prefs_info *prf) { clear_key(prf, "select-all"); } /* -------- key: undo all edits -------- */ static const char *help_revert(prefs_info *prf) { return("\ This option binds a key to undo any edits in the current sound, \n\ equivalent to the File:Revert menu item."); } static char *make_revert(char *key, bool ctrl, bool meta, bool cx) { #if HAVE_SCHEME return(mus_format("(bind-key %s %d revert-sound %s \"undo all edits\" \"revert-sound\")\n", possibly_quote(key), ((ctrl) ? 4 : 0) + ((meta) ? 8 : 0), (cx) ? "#t" : "#f")); #endif #if HAVE_RUBY return(mus_format("bind_key(%s, %d, lambda do\n revert_sound()\n end, %s, \"undo all edits\", \"revert-sound\")\n", possibly_quote(key), ((ctrl) ? 4 : 0) + ((meta) ? 8 : 0), (cx) ? "true" : "false")); #endif #if HAVE_FORTH return(mus_format("%s %d lambda: <{ }> #f revert-sound ; %s \"undo all edits\" \"revert-sound\" bind-key drop\n", possibly_quote(key), ((ctrl) ? 4 : 0) + ((meta) ? 8 : 0), (cx) ? "#t" : "#f")); #endif return(NULL); } static void reflect_revert(prefs_info *prf) { reflect_key(prf, "revert-sound"); } static void save_revert(prefs_info *prf, FILE *fd) { save_key(prf, fd, make_revert); } static void bind_revert(prefs_info *prf) { key_bind(prf, make_revert); } static void clear_revert_sound(prefs_info *prf) { clear_key(prf, "revert-sound"); } /* -------- key: exit -------- */ static const char *help_exit(prefs_info *prf) { return("\ This option binds a key to exit from Snd, \n\ equivalent to the File:Exit menu item."); } static char *make_exit(char *key, bool ctrl, bool meta, bool cx) { #if HAVE_SCHEME return(mus_format("(bind-key %s %d exit %s \"exit\" \"exit\")\n", possibly_quote(key), ((ctrl) ? 4 : 0) + ((meta) ? 8 : 0), (cx) ? "#t" : "#f")); #endif #if HAVE_RUBY return(mus_format("bind_key(%s, %d, lambda do\n exit()\n end, %s, \"exit\", \"exit\")\n", possibly_quote(key), ((ctrl) ? 4 : 0) + ((meta) ? 8 : 0), (cx) ? "true" : "false")); #endif #if HAVE_FORTH return(mus_format("%s %d lambda: <{ }> 0 snd-exit ; %s \"exit\" \"exit\" bind-key drop\n", possibly_quote(key), ((ctrl) ? 4 : 0) + ((meta) ? 8 : 0), (cx) ? "#t" : "#f")); #endif return(NULL); } static void reflect_exit(prefs_info *prf) { reflect_key(prf, "exit"); } static void save_exit(prefs_info *prf, FILE *fd) { save_key(prf, fd, make_exit); } static void bind_exit(prefs_info *prf) { key_bind(prf, make_exit); } static void clear_exit(prefs_info *prf) { clear_key(prf, "exit"); } /* -------- key: goto maxamp -------- */ static const char *help_goto_maxamp(prefs_info *prf) { return("\ This option binds a key to move the view (and cursor) to the \n\ position of the current channel's maximum sample."); } static char *make_goto_maxamp(char *key, bool ctrl, bool meta, bool cx) { #if HAVE_SCHEME return(mus_format("(bind-key %s %d (lambda () (set! (cursor) (maxamp-position))) %s \"goto maxamp\" \"goto-maxamp\")\n", possibly_quote(key), ((ctrl) ? 4 : 0) + ((meta) ? 8 : 0), (cx) ? "#t" : "#f")); #endif #if HAVE_RUBY return(mus_format("bind_key(%s, %d, lambda do\n set_cursor(maxamp_position())\n end, %s, \"goto maxamp\", \"goto-maxamp\")\n", possibly_quote(key), ((ctrl) ? 4 : 0) + ((meta) ? 8 : 0), (cx) ? "true" : "false")); #endif #if HAVE_FORTH return(mus_format("%s %d lambda: <{ }> #f #f #f maxamp-position #f #f #f set-cursor ; %s \"goto maxamp\" \"goto-maxamp\" bind-key drop\n", possibly_quote(key), ((ctrl) ? 4 : 0) + ((meta) ? 8 : 0), (cx) ? "#t" : "#f")); #endif return(NULL); } static void reflect_goto_maxamp(prefs_info *prf) { reflect_key(prf, "goto-maxamp"); } static void save_goto_maxamp(prefs_info *prf, FILE *fd) { save_key(prf, fd, make_goto_maxamp); } static void bind_goto_maxamp(prefs_info *prf) { key_bind(prf, make_goto_maxamp); } static void clear_goto_maxamp(prefs_info *prf) { clear_key(prf, "goto-maxamp"); } /* -------- key: show selection -------- */ static const char *help_show_selection(prefs_info *prf) { return("\ This option binds a key to cause the current selection to \n\ fill the time domain graph."); } static char *make_show_selection(char *key, bool ctrl, bool meta, bool cx) { #if HAVE_SCHEME return(mus_format("(bind-key %s %d show-selection %s \"show selection\" \"show-selection\")\n", possibly_quote(key), ((ctrl) ? 4 : 0) + ((meta) ? 8 : 0), (cx) ? "#t" : "#f")); #endif #if HAVE_RUBY return(mus_format("bind_key(%s, %d, lambda do\n show_selection()\n end, %s, \"show selection\", \"show-selection\")\n", possibly_quote(key), ((ctrl) ? 4 : 0) + ((meta) ? 8 : 0), (cx) ? "true" : "false")); #endif #if HAVE_FORTH return(mus_format("%s %d ' show-selection %s \"show selection\" \"show-selection\" bind-key drop\n", possibly_quote(key), ((ctrl) ? 4 : 0) + ((meta) ? 8 : 0), (cx) ? "#t" : "#f")); #endif return(NULL); } static void reflect_show_selection(prefs_info *prf) { reflect_key(prf, "show-selection"); } static void save_show_selection(prefs_info *prf, FILE *fd) { save_key(prf, fd, make_show_selection); } static void bind_show_selection(prefs_info *prf) { key_bind(prf, make_show_selection); } static void clear_show_selection(prefs_info *prf) { clear_key(prf, "show-selection"); } static const char *help_show_controls(prefs_info *prf) { return("\ The control panel is the set of playback controls \n\ under the sound graphs. It is normally hidden. "); } static const char *help_selection_creates_region(prefs_info *prf) { return("\ This determines whether a region is created whenever \n\ you make a selection. "); } static const char *help_just_sounds(prefs_info *prf) { return("\ The various file dialogs can restrict the files \n\ displayed to just sound files. This sets the default\n\ value of the 'just sounds' button in those dialogs. "); } static const char *help_temp_dir(prefs_info *prf) { return("\ Snd sometimes needs a place to write a temporary \n\ file. This is the directory to use. "); } static const char *help_save_dir(prefs_info *prf) { return("\ When you choose the Options: Save state item, \n\ the saved settings are placed in a file in this directory. "); } static const char *help_save_state_file(prefs_info *prf) { return("\ When you choose Options: Save state, the state \n\ is saved in this file, in the save directory. "); } static const char *help_html_program(prefs_info *prf) { return("\ The help dialog has links to the Snd documentation, \n\ and this option gives the name of the HTML viewer to use. "); } static const char *help_default_output_chans(prefs_info *prf) { return("\ This sets the default number of output channels \n\ when a new sound is started. "); } static const char *help_default_output_srate(prefs_info *prf) { return("\ This sets the default sampling rate when a new \n\ sound is opened. "); } static const char *help_default_output_header_type(prefs_info *prf) { return("\ This sets the default output header type (AIFC, etc) \n\ when a new sound is opened. "); } static const char *help_default_output_sample_type(prefs_info *prf) { return("\ This sets the default sample type (big-endian float, etc) \n\ when a new sound is opened. "); } static const char *help_with_verbose_cursor(prefs_info *prf) { return("\ If this is set, the cursor's position and the underlying \n\ sample's value are displayed in the status area as the cursor moves. "); } static const char *help_with_tracking_cursor(prefs_info *prf) { return("\ If this is set, the cursor always tries to show where the playback \n\ is in the sound as it is played. It is only an approximation. "); } static const char *help_cursor_size(prefs_info *prf) { return(" This sets the cursor size in pixels. "); } static const char *help_cursor_style(prefs_info *prf) { return(" This sets the cursor shape. "); } static const char *help_tracking_cursor_style(prefs_info *prf) { return(" This sets the tracking cursor shape (the 'tracking cursor'\n\ tries to show where you are in the sound while it is begin played). "); } static const char *help_cursor_color(prefs_info *prf) { return(" This is the cursor color. "); } static const char *help_basic_color(prefs_info *prf) { return(" This is the main background color used throughout Snd. "); } static const char *help_highlight_color(prefs_info *prf) { return(" This color is used for highlighted items. "); } static const char *help_position_color(prefs_info *prf) { return(" This is the color of the position-related sliders. "); } static const char *help_zoom_color(prefs_info *prf) { return(" This is the color of the zoom-related sliders. "); } static const char *help_graph_style(prefs_info *prf) { return("\ This sets how sound data is displayed. Normally samples \n\ are joined by lines, but you can also display them as isolated \n\ dots, or as filled polygons, or as dots-on-stilts, as in the DSP \n\ textbooks. "); } static const char *help_dot_size(prefs_info *prf) { return("\ If the graph style uses dots, this sets the dot size. "); } static const char *help_channel_style(prefs_info *prf) { return("\ When a sound has more than one channel, this chooses how \n\ to lay them out: in separate windows, combined in one window \n\ or superimposed on each other in a single graph. "); } static const char *help_graphs_horizontal(prefs_info *prf) { return("\ This chooses whether sounds are layed out horizontally or vertically. "); } static const char *help_show_y_zero(prefs_info *prf) { return("\ If this is set, each channel graph includes a line at y=0. "); } static const char *help_show_grid(prefs_info *prf) { return("\ If this option is set, each channel graph has a grid, sort \n\ of like engineering graph paper. "); } static const char *help_grid_density(prefs_info *prf) { return("\ If grids are in use, this sets how close the lines are. "); } static const char *help_show_axes(prefs_info *prf) { return(" This chooses which axes to display. "); } static const char *help_x_axis_style(prefs_info *prf) { return(" This sets the x axis labelling. "); } static const char *help_data_color(prefs_info *prf) { return(" This is the waveform color in unselected graphs. "); } static const char *help_graph_color(prefs_info *prf) { return(" This is the background color in unselected graphs. "); } static const char *help_selected_data_color(prefs_info *prf) { return(" This is the waveform color in a selected graph. "); } static const char *help_selected_graph_color(prefs_info *prf) { return(" This is the background color in a selected graph. "); } static const char *help_selection_color(prefs_info *prf) { return(" This is the color used to show the current selection. "); } static const char *help_axis_label_font(prefs_info *prf) { return(" This is a font used to label axes. "); } static const char *help_axis_numbers_font(prefs_info *prf) { return(" This is the font used for axis numbers. "); } static const char *help_peaks_font(prefs_info *prf) { return(" This is the font used in the FFT peaks listing. "); } static const char *help_bold_peaks_font(prefs_info *prf) { return("\ This is the font used in the FFT peaks list\n\ to show a major peak. "); } static const char *help_transform_graph_type(prefs_info *prf) { return("\ FFT results can be displayed as a waveform, a sonogram, \n\ or a spectrogram. "); } static const char *help_transform_type(prefs_info *prf) { return("\ This chooses the kind of transform displayed \n\ in the fft graph. "); } static const char *help_fft_window(prefs_info *prf) { return(" This sets the fft data window. "); } static const char *help_fft_window_beta(prefs_info *prf) { return(" If the FFT window has an associated parameter, this sets it. "); } static const char *help_colormap(prefs_info *prf) { return(" If the FFT is being displayed as a sonogram or spectrogram,\n\ this sets the colormap to use. "); } static const char *help_fft_log_magnitude(prefs_info *prf) { return(" If this option is set, the FFTs show the magnitude axis using a log scale. "); } static const char *help_min_dB(prefs_info *prf) { return("\ If the FFT graphs are using a dB scale, this sets the\n\ minimum dB value displayed. "); } static const char *help_fft_log_frequency(prefs_info *prf) { return(" If this is set, FFTs show the frequency axis using a log scale. "); } static const char *help_transform_normalization(prefs_info *prf) { return(" This chooses whether FFT data is normalized before display. "); } static const char *help_mark_color(prefs_info *prf) { return(" This is the mark color. "); } static const char *help_mix_color(prefs_info *prf) { return(" This is the color of the mix handle. "); } static const char *help_sinc_width(prefs_info *prf) { return("\ If sampling rate conversion is needed, this sets \n\ the width of the sinc used for low-pass filtering. "); } static const char *help_show_listener(prefs_info *prf) { return(" This option chooses whether to open the listener window. "); } static const char *help_listener_prompt(prefs_info *prf) { return(" This is the prompt displayed in the listener window. "); } static const char *help_print_length(prefs_info *prf) { return("\ When a vector is printed in the listener, this sets\n\ the maximum number of values displayed. "); } static const char *help_listener_font(prefs_info *prf) { return(" This is the font used in the listener. "); } static const char *help_listener_color(prefs_info *prf) { return(" This is the background color of the listener. "); } static const char *help_dac_size(prefs_info *prf) { return(" This is the DAC buffer size. "); } static const char *help_dac_combines_channels(prefs_info *prf) { return("\ If the DAC has fewer output channels than the sound you\n\ want to play, and this option is set, then the extra \n\ channels are mixed into the existing ones. "); } #if USE_MOTIF static const char *help_view_files_directory(prefs_info *prf) { return(" This directory is added to the View:files dialog's list. "); } #endif static const char *help_raw_chans(prefs_info *prf) { return("\ When a raw (no header) sound is opened, this sets the \n\ default number of channels. "); } static const char *help_raw_srate(prefs_info *prf) { return("\ When a raw (no header) sound is opened, this sets the \n\ default sampling rate. "); } static const char *help_raw_sample_type(prefs_info *prf) { return("\ When a raw (no header) sound is opened, this sets the \n\ default sample type. "); } static const char *help_tiny_font(prefs_info *prf) { return(" When graph space is tight, Snd uses this font. "); } static const char *help_fft_size(prefs_info *prf) { return(" This is the default FFT size. "); } static const char *help_transform_peaks(prefs_info *prf) { return(" If this is set, FFTs include peak listings. "); } static const char *help_mark_tag_size(prefs_info *prf) { return(" This is the size of the upper tag on a mark. "); } static const char *help_mix_tag_size(prefs_info *prf) { return(" This sets the mix tag size. "); } static const char *help_mix_waveforms(prefs_info *prf) { return(" If this is set, mixes display their waveforms. "); } static const char *help_speed_control(prefs_info *prf) { return("\ This chooses how the speed control in the control panel\n\ divides up the speeds; as a continuous scale, by simple ratios, etc. "); } static const char *help_listener_text_color(prefs_info *prf) { return(" This is the listener text color. "); } static const char *help_init_window_size(prefs_info *prf) { return(" This sets Snd's size when it first comes up. "); } snd-16.1/snd-completion.c0000644000076400007640000004562012502665142013444 0ustar bilbil#include "snd.h" #include "sndlib-strings.h" #include "clm-strings.h" static char *current_match = NULL; /* TAB completion requires knowing what is currently defined, which requires scrounging * around in the symbol tables */ #if HAVE_SCHEME typedef struct { const char *text; int matches, len; } match_info; static bool compare_names(const char *symbol_name, void *data) { match_info *m = (match_info *)data; if (strncmp(m->text, symbol_name, m->len) == 0) { m->matches++; add_possible_completion(symbol_name); if (current_match == NULL) current_match = mus_strdup(symbol_name); else { int j, curlen; curlen = mus_strlen(current_match); for (j = 0; j < curlen; j++) if (current_match[j] != symbol_name[j]) { current_match[j] = '\0'; break; } } } return(false); } static int completions(const char *text) { match_info *m; int matches; m = (match_info *)calloc(1, sizeof(match_info)); m->text = text; m->len = strlen(text); m->matches = 0; s7_for_each_symbol_name(s7, compare_names, (void *)m); matches = m->matches; free(m); return(matches); } #endif #if HAVE_RUBY static Xen snd_rb_methods(void) { /* returns all the functions we defined */ Xen argv[1]; argv[0] = Xen_true; return(rb_class_private_instance_methods(1, argv, rb_mKernel)); /* rb_ary_new here -- should we free? */ } static int completions(const char *text) { Xen tab; int i, n, len, matches = 0; tab = snd_rb_methods(); n = Xen_vector_length(tab); len = strlen(text); for (i = 0; i < n; ++i) { char *sym; Xen handle; handle = Xen_vector_ref(tab, i); sym = Xen_object_to_C_string(handle); if (strncmp(text, sym, len) == 0) { matches++; add_possible_completion(sym); if (current_match == NULL) current_match = mus_strdup(sym); else { int j, curlen; curlen = mus_strlen(current_match); for (j = 0; j < curlen; j++) if (current_match[j] != sym[j]) { current_match[j] = '\0'; break; } } } } return(matches); } #endif #if HAVE_FORTH static int completions(const char *text) { Xen tab = fth_find_in_wordlist(text); int i, matches = Xen_vector_length(tab); for (i = 0; i < matches; i++) { char *sym = Xen_string_to_C_string(Xen_vector_ref(tab, i)); add_possible_completion(sym); if (current_match == NULL) current_match = mus_strdup(sym); else { int j, curlen; curlen = mus_strlen(current_match); for (j = 0; j < curlen; j++) if (current_match[j] != sym[j]) { current_match[j] = '\0'; break; } } } return(matches); } #endif #if (!HAVE_EXTENSION_LANGUAGE) static int completions(const char *text) {return(0);} #endif #if HAVE_FORTH static bool is_separator(char c) { /* only space is separator */ return(!(isgraph((int)c))); } #else static bool is_separator(char c) { return((!(isalpha((int)c))) && (!(isdigit((int)c))) && #if HAVE_RUBY (c != '?') && (c != '!') && (c != '_') && #endif #if HAVE_SCHEME (c != '-') && (c != '_') && (c != '>') && (c != '?') && (c != '!') && (c != '=') && (c != '<') && (c != '*') && (c != '+') && (c != '%') && (c != ':') && (c != '/') && #endif (c != '$')); } #endif char *direct_completions(const char *str) { int matches = 0; current_match = NULL; clear_possible_completions(); set_completion_matches(0); set_save_completions(true); matches = completions(str); set_completion_matches(matches); set_save_completions(false); return(current_match); } char *expression_completer(widget_t w, const char *original_text, void *data) { int len, beg, matches = 0; /* first back up to some delimiter to get the current expression */ current_match = NULL; set_completion_matches(0); if ((original_text) && (*original_text)) { const char *text; int i; len = strlen(original_text); for (i = len - 1; i >= 0; i--) if (is_separator(original_text[i])) break; beg = i + 1; if (beg == len) { /* returning original = no-op response to which seems useless; * so, if it's a function that we recognize and that function has its own completer, call it? * result null -> return original (current behavior), else append result as selection to current; * this way, I think it's easy to clear the suggested completion (cursor at end, so backspace deletes all). * or scan back through full text (assuming listener or history available) and find match? */ return(mus_strdup(original_text)); } if (beg > 0) text = (const char *)(original_text + beg); else text = original_text; matches = completions(text); } else return(mus_strdup(original_text)); set_completion_matches(matches); if ((current_match) && (*current_match)) { if (beg == 0) return(current_match); else { char *text; len = mus_strlen(current_match) + beg + 2; text = (char *)calloc(len, sizeof(char)); strncpy(text, original_text, beg); strcat(text, current_match); free(current_match); return(text); } } return(mus_strdup(original_text)); } /* -------- saved choices -------- */ #define BEST_COMPLETIONS 64 static char *best_completions[BEST_COMPLETIONS]; void preload_best_completions(void) { /* set up the array with some reasonable first choices */ int n = 0; best_completions[n++] = mus_strdup(S_open_sound); best_completions[n++] = mus_strdup(S_channels); best_completions[n++] = mus_strdup(S_close_sound); best_completions[n++] = mus_strdup(S_cursor); best_completions[n++] = mus_strdup(S_env_channel); best_completions[n++] = mus_strdup(S_file_name); best_completions[n++] = mus_strdup(S_framples); best_completions[n++] = mus_strdup(S_map_channel); best_completions[n++] = mus_strdup(S_maxamp); best_completions[n++] = mus_strdup(S_play); best_completions[n++] = mus_strdup(S_save_sound); best_completions[n++] = mus_strdup(S_scale_channel); best_completions[n++] = mus_strdup(S_srate); best_completions[n++] = mus_strdup("with-sound"); best_completions[n++] = mus_strdup(S_outa); best_completions[n++] = mus_strdup("*output*"); best_completions[n++] = mus_strdup("lambda"); best_completions[n++] = mus_strdup("define"); } void save_completion_choice(const char *selection) { int i; char *cur = NULL, *old = NULL; cur = mus_strdup(selection); for (i = 0; i < BEST_COMPLETIONS; i++) { old = best_completions[i]; best_completions[i] = cur; if ((!old) || (mus_strcmp(old, cur))) break; cur = old; } if (old) free(old); } int find_best_completion(char **choices, int num_choices) { int i, k; for (i = 0; (i < BEST_COMPLETIONS) && (best_completions[i]); i++) for (k = 0; k < num_choices; k++) if (mus_strcmp(choices[k], best_completions[i])) return(k + 1); /* row numbering is 1-based */ return(1); } /* ---------------- EXPRESSION/FILENAME COMPLETIONS ---------------- */ typedef char *(*completer_func)(widget_t w, const char *text, void *data); static completer_func *completer_funcs = NULL; typedef void (*multicompleter_func)(widget_t w, void *data); static multicompleter_func *multicompleter_funcs = NULL; static void **completer_data = NULL; static int completer_funcs_size = 0; static int completer_funcs_end = 0; int add_completer_func(char *(*func)(widget_t w, const char *text, void *context), void *data) { if (completer_funcs_size == completer_funcs_end) { completer_funcs_size += 8; if (completer_funcs == NULL) { completer_funcs = (completer_func *)calloc(completer_funcs_size, sizeof(completer_func)); multicompleter_funcs = (multicompleter_func *)calloc(completer_funcs_size, sizeof(multicompleter_func)); completer_data = (void **)calloc(completer_funcs_size, sizeof(void *)); } else { int i; completer_funcs = (completer_func *)realloc(completer_funcs, completer_funcs_size * sizeof(completer_func)); multicompleter_funcs = (multicompleter_func *)realloc(multicompleter_funcs, completer_funcs_size * sizeof(multicompleter_func)); completer_data = (void **)realloc(completer_data, completer_funcs_size * sizeof(void *)); for (i = completer_funcs_end; i < completer_funcs_size; i++) completer_data[i] = NULL; } } completer_funcs[completer_funcs_end] = func; completer_data[completer_funcs_end] = data; completer_funcs_end++; return(completer_funcs_end - 1); } int add_completer_func_with_multicompleter(char *(*func)(widget_t w, const char *text, void *context), void *data, void (*multi_func)(widget_t w, void *data)) { int row; row = add_completer_func(func, data); multicompleter_funcs[row] = multi_func; return(row); } static int completion_matches = 0; int get_completion_matches(void) {return(completion_matches);} void set_completion_matches(int matches) {completion_matches = matches;} static bool save_completions = 0; static char **possible_completions = NULL; static int possible_completions_size = 0; static int possible_completions_ctr = 0; void set_save_completions(bool save) {save_completions = save;} void add_possible_completion(const char *text) { if (save_completions) { if (possible_completions_size == possible_completions_ctr) { possible_completions_size += 16; if (possible_completions == NULL) possible_completions = (char **)calloc(possible_completions_size, sizeof(char *)); else { int i; possible_completions = (char **)realloc(possible_completions, possible_completions_size * sizeof(char *)); for (i = possible_completions_ctr; i < possible_completions_size; i++) possible_completions[i] = NULL; } } if (possible_completions[possible_completions_ctr]) free(possible_completions[possible_completions_ctr]); possible_completions[possible_completions_ctr] = mus_strdup(text); possible_completions_ctr++; } } int get_possible_completions_size(void) { return(possible_completions_ctr); } char **get_possible_completions(void) { return(possible_completions); } void handle_completions(widget_t w, int completer) { if ((completer >= 0) && (completer < completer_funcs_end) && (multicompleter_funcs[completer])) (*multicompleter_funcs[completer])(w, completer_data[completer]); } char *complete_text(widget_t w, const char *text, int func) { /* given text, call proc table entry func, return new text (not text!) */ completion_matches = -1; /* i.e. no completer */ possible_completions_ctr = 0; if ((func >= 0) && (func < completer_funcs_end)) return((*completer_funcs[func])(w, text, completer_data[func])); else return(mus_strdup(text)); } void clear_possible_completions(void) { int i; for (i = 0; i < possible_completions_size; i++) if (possible_completions[i]) { free(possible_completions[i]); possible_completions[i] = NULL; } possible_completions_ctr = 0; } static list_completer_info *srate_info = NULL; static void init_srate_list(void) { if (srate_info == NULL) { int loc = 0; srate_info = (list_completer_info *)calloc(1, sizeof(list_completer_info)); srate_info->exact_match = true; srate_info->values_size = 16; srate_info->values = (char **)calloc(srate_info->values_size, sizeof(char *)); srate_info->values[loc++] = mus_strdup("44100"); srate_info->values[loc++] = mus_strdup("22050"); srate_info->values[loc++] = mus_strdup("8000"); srate_info->values[loc++] = mus_strdup("48000"); srate_info->num_values = loc; } } void add_srate_to_completion_list(int srate) { char *str; int i; init_srate_list(); str = (char *)malloc(16 * sizeof(char)); snprintf(str, 16, "%d", srate); for (i = 0; i < srate_info->num_values; i++) if (mus_strcmp(srate_info->values[i], str)) { free(str); return; } if (srate_info->num_values >= srate_info->values_size) { srate_info->values_size += 16; srate_info->values = (char **)realloc(srate_info->values, srate_info->values_size * sizeof(char *)); for (i = srate_info->num_values; i < srate_info->values_size; i++) srate_info->values[i] = NULL; } srate_info->values[srate_info->num_values++] = str; } char *srate_completer(widget_t w, const char *text, void * data) { init_srate_list(); return(list_completer(w, text, (void *)srate_info)); } #ifndef _MSC_VER #include #endif enum {ANY_FILE_TYPE, SOUND_FILE_TYPE}; static char *filename_completer_1(widget_t w, const char *text, int file_type) { /* assume text is a partial filename */ /* get directory name, opendir, read files checking for match */ /* return name of same form as original (i.e. don't change user's directory indication) */ /* if directory, add "/" -- is_directory(name) static in snd-xfile.c */ char *full_name = NULL, *dir_name = NULL, *file_name = NULL, *current_match = NULL; int i, j, k, len, curlen, matches = 0; DIR *dpos; if (mus_strlen(text) == 0) return(NULL); full_name = mus_expand_filename(text); len = mus_strlen(full_name); for (i = len - 1; i > 0; i--) if (full_name[i] == '/') break; dir_name = (char *)calloc(i + 1, sizeof(char)); strncpy(dir_name, full_name, i); file_name = (char *)calloc(len - i + 2, sizeof(char)); for (j = 0, k = i + 1; k < len; j++, k++) file_name[j] = full_name[k]; if (full_name) { free(full_name); full_name = NULL; } len = mus_strlen(file_name); if ((dpos = opendir(dir_name)) != NULL) { struct dirent *dirp; while ((dirp = readdir(dpos)) != NULL) if ((dirp->d_name[0] != '.') && (strncmp(dirp->d_name, file_name, len) == 0)) /* match dirp->d_name against rest of text */ { if ((file_type == ANY_FILE_TYPE) || (is_sound_file(dirp->d_name))) { matches++; add_possible_completion(dirp->d_name); if (current_match == NULL) current_match = mus_strdup(dirp->d_name); else { curlen = strlen(current_match); for (j = 0; j < curlen; j++) if (current_match[j] != dirp->d_name[j]) { current_match[j] = '\0'; break; } } } } if (closedir(dpos) != 0) snd_error("closedir %s failed (%s)!", dir_name, snd_io_strerror()); } if (dir_name) free(dir_name); if (file_name) free(file_name); set_completion_matches(matches); if ((current_match) && (*current_match)) { /* attach matched portion to user's indication of dir */ len = mus_strlen(text); for (i = len - 1; i >= 0; i--) if (text[i] == '/') break; if (i < 0) return(current_match); curlen = strlen(current_match) + len + 3; file_name = (char *)calloc(curlen, sizeof(char)); strncpy(file_name, text, i + 1); strcat(file_name, current_match); if (is_directory(file_name)) strcat(file_name, "/"); free(current_match); return(file_name); } return(mus_strdup(text)); } char *filename_completer(widget_t w, const char *text, void *data) { return(filename_completer_1(w, text, ANY_FILE_TYPE)); } char *sound_filename_completer(widget_t w, const char *text, void *data) { return(filename_completer_1(w, text, SOUND_FILE_TYPE)); } static int find_indentation(char *str, int loc) { int line_beg = 0, open_paren = -1, parens, i; parens = 0; for (i = loc - 1; i >= 0; i--) { if (str[i] == ')') parens--; if (str[i] == '(') parens++; if (parens == 1) { open_paren = i; break; } } if (open_paren == -1) return(1); if (open_paren == 0) return(3); for (i = open_paren - 1; i > 0; i--) if (str[i] == '\n') { line_beg = i; break; } if (line_beg == 0) return(1); return(open_paren - line_beg + 2); } char *complete_listener_text(char *old_text, int end, bool *try_completion, char **to_file_text) { int len, i, k, spaces, text_pos = 0, cr_pos = 0; char *new_text = NULL, *file_text = NULL, *new_file = NULL; len = strlen(old_text); for (i = len - 1; i > 0; i--) { if (old_text[i] == '\n') { /* tab as indentation */ /* look at previous line to decide */ spaces = find_indentation(old_text, i); if (spaces > 0) { file_text = (char *)calloc(spaces + 1, sizeof(char)); for (k = 0; k < spaces; k++) file_text[k] = ' '; file_text[spaces] = 0; append_listener_text(end, file_text); free(file_text); file_text = NULL; } (*try_completion) = false; return(NULL); } if (old_text[i] == ';') { /* this isn't quite right, but how much effort should we put in it? */ spaces = 20; for (k = i - 1; k > 0; k--) if (old_text[k] == '\n') { cr_pos = k; break; } else if ((!(isspace((int)(old_text[k])))) && (text_pos == 0)) text_pos = k; if (text_pos > 0) text_pos -= cr_pos; if (cr_pos == 0) spaces--; if (text_pos < spaces) { file_text = (char *)calloc(spaces + 2, sizeof(char)); for (k = text_pos + 1; k < spaces; k++) file_text[k - text_pos - 1] = ' '; file_text[spaces] = ';'; file_text[spaces + 1] = 0; append_listener_text(end - 1, file_text); free(file_text); file_text = NULL; } (*try_completion) = false; return(NULL); } if (old_text[i] == '\"') { file_text = mus_strdup((char *)(old_text + i + 1)); new_file = filename_completer(NULL_WIDGET, file_text, NULL); len = mus_strlen(new_file); if (len > 0) { len += i + 2; new_text = (char *)calloc(len, sizeof(char)); strncpy(new_text, old_text, i + 1); strcat(new_text, new_file); free(new_file); } break; } if (isspace((int)(old_text[i]))) break; } if (new_text == NULL) new_text = expression_completer(NULL_WIDGET, old_text, NULL); (*try_completion) = true; (*to_file_text) = file_text; return(new_text); } char *list_completer(widget_t w, const char *text, void *data) { list_completer_info *info = (list_completer_info *)data; int i, j = 0, len, matches = 0, current_match = -1; char *trimmed_text; set_completion_matches(0); /* check for null text */ len = mus_strlen(text); if (len == 0) return(mus_strdup(text)); /* strip away leading and trailing white space */ trimmed_text = (char *)calloc(len + 1, sizeof(char)); for (i = 0; i < len; i++) if (!(isspace((int)text[i]))) trimmed_text[j++] = text[i]; if (j == 0) { free(trimmed_text); return(mus_strdup(text)); } /* check for match(es) against values */ if (info->exact_match) { for (i = 0; i < info->num_values; i++) if ((info->values[i]) && (strncmp(info->values[i], trimmed_text, len) == 0)) { matches++; current_match = i; } } else { for (i = 0; i < info->num_values; i++) if ((info->values[i]) && (STRNCMP(info->values[i], trimmed_text, len) == 0)) { matches++; current_match = i; } } free(trimmed_text); if (matches != 1) return(mus_strdup(text)); set_completion_matches(1); return(mus_strdup(info->values[current_match])); } snd-16.1/freeverb.scm0000644000076400007640000001773012621460666012660 0ustar bilbil;;; freeverb.scm -- CLM -> Snd/Scheme translation of freeverb.ins ;; Translator/Author: Michael Scholz ;; Last: Thu Apr 24 01:32:15 CEST 2003 ;; Version: $Revision: 1.2 $ ;;; Original notes of Fernando Lopez-Lezcano ;; Freeverb - Free, studio-quality reverb SOURCE CODE in the public domain ;; ;; Written by Jezar at Dreampoint, June 2000 ;; http://www.dreampoint.co.uk ;; ;; Translated into clm-2 by Fernando Lopez-Lezcano ;; Version 1.0 for clm-2 released in January 2001 ;; http://ccrma.stanford.edu/~nando/clm/freeverb/ ;; ;; Changes to the original code by Jezar (by Fernando Lopez-Lezcano): ;; - the clm version can now work with a mono input or an n-channel input ;; stream (in the latter case the number of channels of the input and output ;; streams must match. ;; - the "wet" parameter has been eliminated as it does not apply to the model ;; that clm uses to generate reverberation ;; - the "width" parameter name has been changed to :global. It now controls the ;; coefficients of an NxN matrix that specifies how the output of the reverbs ;; is mixed into the output stream. ;; - predelays for the input channels have been added. ;; - damping can be controlled individually for each channel. ;; For more information see clm-2/freeverb/index.html [MS] ;;; changed to accommodate run and mono output, bill 11-Jun-06 ;;; use the filtered-comb gen, bill 29-Jun-06 ;;; optimized slightly, bill 17-Sep-12 ;;; changed to use float-vectors, not frames and mixers 11-Oct-13 ;;; Code: (provide 'snd-freeverb.scm) (if (provided? 'snd) (require snd-ws.scm) (require sndlib-ws.scm)) (definstrument (freeverb (room-decay 0.5) (damping 0.5) (global 0.3) (predelay 0.03) (output-gain 1.0) output-mixer (scale-room-decay 0.28) (offset-room-decay 0.7) (combtuning '(1116 1188 1277 1356 1422 1491 1557 1617)) (allpasstuning '(556 441 341 225)) (scale-damping 0.4) (stereo-spread 23) (decay-time 1.0) verbose) (let ((startime 0.0) (dur (+ decay-time (mus-sound-duration (mus-file-name *reverb*)))) (out-chans (channels *output*)) (in-chans (channels *reverb*)) (srate-scale (/ *clm-srate* 44100.0)) (room-decay-val (+ (* room-decay scale-room-decay) offset-room-decay)) (numcombs (length combtuning)) (numallpasses (length allpasstuning))) (let ((beg (seconds->samples startime)) (end (seconds->samples (+ startime dur))) (out-buf (make-float-vector out-chans 0.0)) (f-out (make-float-vector out-chans 0.0)) (f-in (make-float-vector in-chans 0.0)) (predelays (make-vector in-chans)) (fcombs (make-vector (* out-chans numcombs))) (allpasses (make-vector (* out-chans numallpasses))) (local-gain (if (= out-chans 1) global (+ (/ (- 1.0 global) (- 1 (/ 1.0 out-chans))) (/ 1.0 out-chans)))) (global-gain 0.0)) (set! global-gain (if (= out-chans 1) local-gain (/ (- out-chans (* local-gain out-chans)) (- (* out-chans out-chans) out-chans)))) (if verbose (format #t ";;; freeverb: ~d input channels, ~d output channels~%" in-chans out-chans)) (if (and (> in-chans 1) (not (= in-chans out-chans))) (error "input must be mono or input channels must equal output channels")) (let ((out-mix (or output-mixer (let ((v (make-float-vector (list out-chans out-chans) 0.0))) (do ((i 0 (+ i 1))) ((= i out-chans)) (do ((j 0 (+ j 1))) ((= j out-chans)) (set! (v i j) (/ (* output-gain (if (= i j) local-gain global-gain)) out-chans)))) v)))) (do ((c 0 (+ 1 c))) ((= c in-chans)) (set! (predelays c) (make-delay :size (round (* *clm-srate* (if (number? predelay) predelay (predelay c))))))) (do ((c 0 (+ 1 c))) ((= c out-chans)) (do ((i 0 (+ i 1))) ((= i numcombs)) (let* ((tuning (combtuning i)) (len (floor (* srate-scale tuning))) (dmp (* scale-damping (if (number? damping) damping (damping i))))) (if (odd? c) (set! len (+ len (floor (* srate-scale stereo-spread))))) (set! (fcombs (+ (* c numcombs) i)) (make-filtered-comb :size len :scaler room-decay-val :filter (make-one-zero :a0 (- 1.0 dmp) :a1 dmp)))))) (do ((c 0 (+ 1 c))) ((= c out-chans)) (do ((i 0 (+ i 1))) ((= i numallpasses)) (let* ((tuning (allpasstuning i)) (len (floor (* srate-scale tuning)))) (if (odd? c) (set! len (+ len (floor (* srate-scale stereo-spread))))) (set! (allpasses (+ (* c numallpasses) i)) (make-all-pass :size len :feedforward -1 :feedback 0.5))))) (if (= out-chans in-chans 1) (let ((amp (out-mix 0 0)) (pdelay (predelays 0))) (set! allpasses (make-all-pass-bank allpasses)) (set! fcombs (make-filtered-comb-bank fcombs)) (do ((i beg (+ i 1))) ((= i end)) (outa i (* amp (all-pass-bank allpasses (filtered-comb-bank fcombs (delay pdelay (ina i *reverb*)))))))) (let ((allp-c (make-vector out-chans)) (fcmb-c (make-vector out-chans))) (do ((c 0 (+ c 1))) ((= c out-chans)) (set! (allp-c c) (make-vector numallpasses)) (set! (fcmb-c c) (make-vector numcombs))) (do ((c 0 (+ c 1))) ((= c out-chans)) (do ((j 0 (+ j 1))) ((= j numcombs)) (set! ((fcmb-c c) j) (fcombs (+ j (* c numcombs))))) (do ((j 0 (+ j 1))) ((= j numallpasses)) (set! ((allp-c c) j) (allpasses (+ j (* c numallpasses))))) (set! (allp-c c) (make-all-pass-bank (allp-c c))) (set! (fcmb-c c) (make-filtered-comb-bank (fcmb-c c)))) (if (= in-chans out-chans 5) (let ((allp0 (vector-ref allp-c 0)) (allp1 (vector-ref allp-c 1)) (allp2 (vector-ref allp-c 2)) (allp3 (vector-ref allp-c 3)) (allp4 (vector-ref allp-c 4)) (fcmb0 (vector-ref fcmb-c 0)) (fcmb1 (vector-ref fcmb-c 1)) (fcmb2 (vector-ref fcmb-c 2)) (fcmb3 (vector-ref fcmb-c 3)) (fcmb4 (vector-ref fcmb-c 4)) (dly0 (vector-ref predelays 0)) (dly1 (vector-ref predelays 1)) (dly2 (vector-ref predelays 2)) (dly3 (vector-ref predelays 3)) (dly4 (vector-ref predelays 4))) (do ((i beg (+ i 1))) ((= i end)) (file->frample *reverb* i f-in) (float-vector-set! f-out 0 (all-pass-bank allp0 (filtered-comb-bank fcmb0 (delay dly0 (float-vector-ref f-in 0))))) (float-vector-set! f-out 1 (all-pass-bank allp1 (filtered-comb-bank fcmb1 (delay dly1 (float-vector-ref f-in 1))))) (float-vector-set! f-out 2 (all-pass-bank allp2 (filtered-comb-bank fcmb2 (delay dly2 (float-vector-ref f-in 2))))) (float-vector-set! f-out 3 (all-pass-bank allp3 (filtered-comb-bank fcmb3 (delay dly3 (float-vector-ref f-in 3))))) (float-vector-set! f-out 4 (all-pass-bank allp4 (filtered-comb-bank fcmb4 (delay dly4 (float-vector-ref f-in 4))))) (frample->file *output* i (frample->frample out-mix f-out out-chans out-buf out-chans)))) (if (> in-chans 1) (do ((i beg (+ i 1))) ((= i end)) (file->frample *reverb* i f-in) (do ((c 0 (+ c 1))) ((= c out-chans)) (float-vector-set! f-out c (all-pass-bank (vector-ref allp-c c) (filtered-comb-bank (vector-ref fcmb-c c) (delay (vector-ref predelays c) (float-vector-ref f-in c)))))) (frample->file *output* i (frample->frample out-mix f-out out-chans out-buf out-chans))) (let ((pdelay (predelays 0))) (do ((i beg (+ i 1))) ((= i end)) (let ((val (delay pdelay (ina i *reverb*)))) (do ((c 0 (+ c 1))) ((= c out-chans)) (float-vector-set! f-out c (all-pass-bank (vector-ref allp-c c) (filtered-comb-bank (vector-ref fcmb-c c) val)))) (frample->file *output* i (frample->frample out-mix f-out out-chans out-buf out-chans))))))))))))) ;;; (with-sound (:statistics #t :reverb freeverb :reverb-data '(:output-gain 3.0)) (outa 0 .5 *reverb*)) ;;; (with-sound (:channels 2 :reverb-channels 2 :statistics #t :reverb freeverb :reverb-data '(:output-gain 3.0)) (outa 0 .5 *reverb*) (outb 0 .1 *reverb*)) snd-16.1/snd-data.c0000644000076400007640000006775712625322202012214 0ustar bilbil#include "snd.h" chan_info *make_chan_info(chan_info *cip, int chan, snd_info *sound) { chan_info *cp; /* may be re-used */ if (!cip) { cp = (chan_info *)calloc(1, sizeof(chan_info)); cp->ax = (graphics_context *)calloc(1, sizeof(graphics_context)); switch (chan % 4) { case 0: cp->combined_data_color = ss->black; break; case 1: cp->combined_data_color = ss->red; break; case 2: cp->combined_data_color = ss->green; break; case 3: cp->combined_data_color = ss->blue; break; } #if USE_GTK cp->progress_pct = -1.0; #endif cp->last_sonogram = NULL; cp->last_wavogram = NULL; cp->temp_sonogram = NULL; cp->inset_graph = NULL; #if HAVE_GL cp->gl_fft_list = NO_LIST; cp->gl_wavo_list = NO_LIST; #endif cp->edit_hook = Xen_false; cp->edit_hook_loc = NOT_A_GC_LOC; cp->after_edit_hook = Xen_false; cp->after_edit_hook_loc = NOT_A_GC_LOC; cp->undo_hook = Xen_false; cp->undo_hook_loc = NOT_A_GC_LOC; cp->properties = Xen_false; /* will be a vector of 1 element if it's ever used */ cp->properties_loc = NOT_A_GC_LOC; cp->active = CHANNEL_INACTIVE; } else cp = cip; cp->chan = chan; cp->sound = sound; cp->sound_ctr = NOT_A_SOUND; cp->edit_ctr = -1; cp->sound_size = 0; cp->edit_size = 0; cp->cursor_on = false; cp->cursor_visible = false; cp->fft_cursor_visible = false; cp->show_sonogram_cursor = show_sonogram_cursor(ss); cp->selection_visible = false; cp->editable = true; /* must be unset (region display, variable display, etc) */ cp->cursor_style = cursor_style(ss); cp->tracking_cursor_style = tracking_cursor_style(ss); cp->cursor_size = cursor_size(ss); cp->cursor_proc = Xen_undefined; cp->cursor_proc_loc = NOT_A_GC_LOC; cp->squelch_update = false; cp->show_y_zero = show_y_zero(ss); cp->show_grid = show_grid(ss); cp->show_marks = show_marks(ss); cp->time_graph_type = time_graph_type(ss); cp->wavo_hop = wavo_hop(ss); cp->wavo_trace = wavo_trace(ss); cp->max_transform_peaks = max_transform_peaks(ss); cp->show_transform_peaks = show_transform_peaks(ss); cp->zero_pad = zero_pad(ss); cp->with_verbose_cursor = with_verbose_cursor(ss); cp->fft_log_frequency = fft_log_frequency(ss); cp->fft_log_magnitude = fft_log_magnitude(ss); cp->fft_with_phases = fft_with_phases(ss); cp->min_dB = min_dB(ss); cp->lin_dB = ss->lin_dB; cp->in_as_one_edit = 0; cp->wavelet_type = wavelet_type(ss); cp->spectro_x_angle = spectro_x_angle(ss); cp->spectro_y_angle = spectro_y_angle(ss); cp->spectro_z_angle = spectro_z_angle(ss); cp->spectro_x_scale = spectro_x_scale(ss); cp->spectro_y_scale = spectro_y_scale(ss); cp->spectro_z_scale = spectro_z_scale(ss); cp->spectrum_end = spectrum_end(ss); cp->spectrum_start = spectrum_start(ss); cp->spectro_hop = spectro_hop(ss); cp->fft_window_alpha = fft_window_alpha(ss); cp->fft_window_beta = fft_window_beta(ss); cp->transform_size = transform_size(ss); cp->transform_graph_type = transform_graph_type(ss); cp->fft_window = fft_window(ss); cp->transform_type = transform_type(ss); cp->transform_normalization = transform_normalization(ss); cp->show_mix_waveforms = show_mix_waveforms(ss); cp->time_graph_style = graph_style(ss); cp->lisp_graph_style = graph_style(ss); cp->transform_graph_style = graph_style(ss); cp->graphs_horizontal = graphs_horizontal(ss); cp->dot_size = dot_size(ss); cp->grid_density = grid_density(ss); cp->x_axis_style = x_axis_style(ss); cp->beats_per_minute = beats_per_minute(ss); cp->beats_per_measure = beats_per_measure(ss); cp->show_axes = show_axes(ss); cp->graph_time_on = true; /* the default state (button is set when we start) */ cp->graph_transform_on = false; cp->printing = NOT_PRINTING; cp->waiting_to_make_graph = false; cp->new_peaks = false; cp->sonogram_data = NULL; cp->lisp_info = NULL; cp->amp_control = NULL; cp->hookable = WITH_HOOK; cp->cx = 0; cp->cy = 0; cp->fft_cx = 0; cp->selection_transform_size = 0; if (cp->last_sonogram) { free(cp->last_sonogram); cp->last_sonogram = NULL; } if (cp->last_wavogram) { free(cp->last_wavogram); cp->last_wavogram = NULL; } if (cp->inset_graph) clear_inset_graph(cp); cp->active = CHANNEL_INITIALIZED; return(cp); } static chan_info *free_chan_info(chan_info *cp) { /* this does not free the associated widgets -- they are merely unmanaged */ cp->active = CHANNEL_INACTIVE; /* need an indication right away that this channel is being deleted -- during free_snd_info (close-sound), * an error may occur (an edit list temp file might have vanished for example), and normally Snd * attempts to post an error message in the sound's status area. To force this out, we have to * call XmUpdate or equivalent, which can cause all the sound's channels to attempt to redisplay; * since the one causing the error is half-deallocated, trouble can ensue. So both the channel * and the sound have "active" flags that are true only when everything is ship-shape. */ chan_info_cleanup(cp); cp->squelch_update = true; cp->axis = free_axis_info(cp->axis); if (cp->fft) cp->fft = free_fft_info(cp->fft); cp_free_fft_state(cp); cp->graph_transform_on = false; cp->printing = NOT_PRINTING; cp->graph_time_on = true; if (cp->edits) free_edit_list(cp); if (cp->sounds) free_sound_list(cp); free_channel_mixes(cp); cp->sound = NULL; /* a backpointer */ cp->cursor_on = false; cp->cursor_visible = false; cp->fft_cursor_visible = false; cp->show_sonogram_cursor = false; cp->selection_visible = false; if (cp->amp_control) { /* not sure this is the right thing */ free(cp->amp_control); cp->amp_control = NULL; } if (Xen_is_procedure(cp->cursor_proc)) { snd_unprotect_at(cp->cursor_proc_loc); cp->cursor_proc = Xen_undefined; cp->cursor_proc_loc = NOT_A_GC_LOC; } if (Xen_is_vector(cp->properties)) /* using vector as node for GC */ Xen_vector_set(cp->properties, 0, Xen_empty_list); cp->waiting_to_make_graph = false; if (cp->sonogram_data) free_sono_info(cp); if (cp->temp_sonogram) { /* special case -- background fft process never got a chance to run */ if (cp->temp_sonogram == cp->last_sonogram) cp->last_sonogram = NULL; free_sonogram_fft_state(cp->temp_sonogram); free(cp->temp_sonogram); cp->temp_sonogram = NULL; } if (cp->last_sonogram) { free_sonogram_fft_state(cp->last_sonogram); free(cp->last_sonogram); cp->last_sonogram = NULL; } if (cp->last_wavogram) { free(cp->last_wavogram); cp->last_wavogram = NULL; } if (cp->lisp_info) { free_lisp_info(cp); cp->lisp_info = NULL; } cp->graph_lisp_on = false; cp->selection_transform_size = 0; if (cp->as_one_edit_positions) { free(cp->as_one_edit_positions); cp->as_one_edit_positions = NULL; cp->as_one_edit_positions_size = 0; } if (Xen_is_hook(cp->edit_hook)) { Xen_clear_hook_list(cp->edit_hook); snd_unprotect_at(cp->edit_hook_loc); cp->edit_hook = Xen_false; cp->edit_hook_loc = NOT_A_GC_LOC; } if (Xen_is_hook(cp->after_edit_hook)) { Xen_clear_hook_list(cp->after_edit_hook); snd_unprotect_at(cp->after_edit_hook_loc); cp->after_edit_hook = Xen_false; cp->after_edit_hook_loc = NOT_A_GC_LOC; } if (Xen_is_hook(cp->undo_hook)) { Xen_clear_hook_list(cp->undo_hook); snd_unprotect_at(cp->undo_hook_loc); cp->undo_hook = Xen_false; cp->undo_hook_loc = NOT_A_GC_LOC; } if (cp->inset_graph) clear_inset_graph(cp); return(cp); /* pointer is left for possible future re-use */ } snd_info *make_basic_snd_info(int chans) { snd_info *sp = NULL; sp = (snd_info *)calloc(1, sizeof(snd_info)); sp->chans = (chan_info **)calloc(chans, sizeof(chan_info *)); sp->allocated_chans = chans; sp->properties = Xen_false; /* will be a vector of 1 element if it's ever used */ sp->properties_loc = NOT_A_GC_LOC; #if USE_NO_GUI sp->snd_widgets = false; /* it's a bool if no gui */ #endif return(sp); } void initialize_control_panel(snd_info *sp) { sp->expand_control = DEFAULT_EXPAND_CONTROL; sp->expand_control_min = expand_control_min(ss); sp->expand_control_max = expand_control_max(ss); sp->last_expand_control = 0.0; sp->saved_expand_control = 0.0; sp->expand_control_on = DEFAULT_EXPAND_CONTROL_ON; sp->amp_control = DEFAULT_AMP_CONTROL; sp->amp_control_min = amp_control_min(ss); sp->amp_control_max = amp_control_max(ss); sp->last_amp_control = 1.0; sp->saved_amp_control = 1.0; sp->speed_control = fabs(DEFAULT_SPEED_CONTROL); sp->speed_control_min = speed_control_min(ss); sp->speed_control_max = speed_control_max(ss); sp->last_speed_control = 1.0; sp->saved_speed_control = 1.0; if (DEFAULT_SPEED_CONTROL > 0.0) sp->speed_control_direction = 1; else sp->speed_control_direction = -1; sp->contrast_control_on = DEFAULT_CONTRAST_CONTROL_ON; sp->contrast_control = DEFAULT_CONTRAST_CONTROL; sp->contrast_control_min = contrast_control_min(ss); sp->contrast_control_max = contrast_control_max(ss); sp->contrast_control_amp = contrast_control_amp(ss); sp->last_contrast_control = contrast_control_min(ss); sp->saved_contrast_control = contrast_control_min(ss); sp->reverb_control_on = DEFAULT_REVERB_CONTROL_ON; sp->filter_control_on = DEFAULT_FILTER_CONTROL_ON; sp->expand_control_length = expand_control_length(ss); sp->expand_control_ramp = expand_control_ramp(ss); sp->expand_control_hop = expand_control_hop(ss); sp->expand_control_jitter = expand_control_jitter(ss); sp->reverb_control_feedback = reverb_control_feedback(ss); sp->reverb_control_lowpass = reverb_control_lowpass(ss); sp->reverb_control_scale = DEFAULT_REVERB_CONTROL_SCALE; sp->reverb_control_scale_min = reverb_control_scale_min(ss); sp->reverb_control_scale_max = reverb_control_scale_max(ss); sp->reverb_control_decay = reverb_control_decay(ss); sp->speed_control_tones = speed_control_tones(ss); sp->speed_control_style = speed_control_style(ss); sp->speed_control_numerator = 1; sp->speed_control_denominator = 1; sp->last_reverb_control_scale = 0.0; sp->saved_reverb_control_scale = 0.0; sp->reverb_control_length = DEFAULT_REVERB_CONTROL_LENGTH; sp->reverb_control_length_min = reverb_control_length_min(ss); sp->reverb_control_length_max = reverb_control_length_max(ss); sp->last_reverb_control_length = 0.0; sp->saved_reverb_control_length = 0.0; sp->filter_control_order = filter_control_order(ss); sp->filter_control_in_dB = filter_control_in_dB(ss); sp->filter_control_in_hz = filter_control_in_hz(ss); if (sp->filter_control_in_hz) sp->filter_control_xmax = (mus_float_t)(snd_srate(sp) / 2); else sp->filter_control_xmax = 1.0; sp->filter_control_changed = false; sp->saved_controls = NULL; } snd_info *make_snd_info(snd_info *sip, const char *filename, file_info *hdr, int snd_slot, read_only_t read_only) { snd_info *sp = NULL; int chans, i; /* assume file has been found and header read before reaching us */ /* if a reused pointer, may need to extend current chans array */ chans = hdr->chans; if (!sip) { sp = make_basic_snd_info(chans); } else { sp = sip; if (sp->allocated_chans < chans) { sp->chans = (chan_info **)realloc(sp->chans, chans * sizeof(chan_info *)); for (i = sp->allocated_chans; i < chans; i++) sp->chans[i] = NULL; sp->allocated_chans = chans; } } sp->user_read_only = read_only; /* need to be sure this is set before any hooks run */ sp->bomb_in_progress = false; sp->index = snd_slot; sp->nchans = chans; sp->hdr = hdr; sp->inuse = SOUND_NORMAL; sp->filename = mus_strdup(filename); sp->short_filename = filename_without_directory(sp->filename); /* a pointer into filename, not a new string */ sp->sync = DEFAULT_SYNC; sp->previous_sync = sp->sync; initialize_control_panel(sp); sp->selectpos = -1; if (chans > 1) { if (ss->update_sound_channel_style != NOT_A_CHANNEL_STYLE) { sp->channel_style = ss->update_sound_channel_style; ss->update_sound_channel_style = NOT_A_CHANNEL_STYLE; } else sp->channel_style = channel_style(ss); } else sp->channel_style = CHANNELS_SEPARATE; sp->selected_channel = NO_SELECTION; sp->playing = 0; sp->applying = false; sp->lacp = NULL; sp->delete_me = NULL; sp->name_string = NULL; sp->active = true; return(sp); } void free_snd_info(snd_info *sp) { int i; #if (!USE_NO_GUI) env_editor *edp; /* make sure trough colors are ok upon reuse */ if (sp->reverb_control_on != DEFAULT_REVERB_CONTROL_ON) toggle_reverb_button(sp, DEFAULT_REVERB_CONTROL_ON); if (sp->expand_control_on != DEFAULT_EXPAND_CONTROL_ON) toggle_expand_button(sp, DEFAULT_EXPAND_CONTROL_ON); if (sp->contrast_control_on != DEFAULT_CONTRAST_CONTROL_ON) toggle_contrast_button(sp, DEFAULT_CONTRAST_CONTROL_ON); edp = sp->flt; if (edp) { edp->edited = false; edp->env_dragged = false; edp->env_pos = 0; edp->click_to_delete = false; } set_filter_text(sp, ""); #endif /* leave most for reuse as in free_chan_info */ sp->active = false; sp->selectpos = -1; sp->sync = 0; snd_info_cleanup(sp); sp->previous_sync = sp->sync; for (i = 0; i < sp->nchans; i++) if (sp->chans[i]) sp->chans[i] = free_chan_info(sp->chans[i]); sp->inuse = SOUND_IDLE; sp->playing = 0; sp->bomb_in_progress = false; sp->applying = false; sp->channel_style = CHANNELS_SEPARATE; sp->user_read_only = FILE_READ_WRITE; sp->file_read_only = FILE_READ_WRITE; sp->need_update = false; sp->file_unreadable = false; if (Xen_is_vector(sp->properties)) /* using vector as node for GC */ Xen_vector_set(sp->properties, 0, Xen_empty_list); sp->selected_channel = NO_SELECTION; sp->short_filename = NULL; /* was a pointer into filename */ if (sp->filename) free(sp->filename); sp->filename = NULL; if (sp->filter_control_envelope) sp->filter_control_envelope = free_env(sp->filter_control_envelope); if (sp->saved_controls) free_controls(sp); sp->delete_me = NULL; if (sp->name_string) free(sp->name_string); sp->name_string = NULL; sp->lacp = NULL; sp->hdr = free_file_info(sp->hdr); if (sp->edited_region) clear_region_backpointer(sp); clear_players(); reflect_mix_change(ANY_MIX_ID); if (Xen_hook_has_list(ss->effects_hook)) run_hook(ss->effects_hook, Xen_empty_list, S_effects_hook); } snd_info *completely_free_snd_info(snd_info *sp) { int i; free_snd_info(sp); for (i = 0; i < sp->allocated_chans; i++) { chan_info *cp; cp = sp->chans[i]; if (cp) { if (Xen_is_vector(cp->properties)) { snd_unprotect_at(cp->properties_loc); cp->properties_loc = NOT_A_GC_LOC; } if (cp->inset_graph) free_inset_graph(cp); cp->active = CHANNEL_FREED; free(cp); /* it's possible to have dangling readers (snd_fd) with pointers to this channel (see note in snd-edits.c under unlist_reader) */ } } free(sp->chans); if (Xen_is_vector(sp->properties)) { snd_unprotect_at(sp->properties_loc); sp->properties_loc = NOT_A_GC_LOC; } free(sp); return(NULL); } void for_each_chan_with_int(void (*func)(chan_info *ncp, int val), int value) { int i; for (i = 0; i < ss->max_sounds; i++) { int j; snd_info *sp; chan_info *cp; sp = ss->sounds[i]; if ((sp) && ((sp->inuse == SOUND_NORMAL) || (sp->inuse == SOUND_WRAPPER))) for (j = 0; j < sp->nchans; j++) if ((cp = ((chan_info *)(sp->chans[j])))) (*func)(cp, value); } } void for_each_chan_with_mus_long_t(void (*func)(chan_info *ncp, mus_long_t val), mus_long_t value) { int i; for (i = 0; i < ss->max_sounds; i++) { int j; snd_info *sp; chan_info *cp; sp = ss->sounds[i]; if ((sp) && ((sp->inuse == SOUND_NORMAL) || (sp->inuse == SOUND_WRAPPER))) for (j = 0; j < sp->nchans; j++) if ((cp = ((chan_info *)(sp->chans[j])))) (*func)(cp, value); } } void for_each_chan_with_bool(void (*func)(chan_info *ncp, bool val), bool value) { int i; for (i = 0; i < ss->max_sounds; i++) { int j; snd_info *sp; chan_info *cp; sp = ss->sounds[i]; if ((sp) && ((sp->inuse == SOUND_NORMAL) || (sp->inuse == SOUND_WRAPPER))) for (j = 0; j < sp->nchans; j++) if ((cp = ((chan_info *)(sp->chans[j])))) (*func)(cp, value); } } void for_each_chan_with_float(void (*func)(chan_info *ncp, mus_float_t val), mus_float_t value) { int i; for (i = 0; i < ss->max_sounds; i++) { int j; snd_info *sp; chan_info *cp; sp = ss->sounds[i]; if ((sp) && ((sp->inuse == SOUND_NORMAL) || (sp->inuse == SOUND_WRAPPER))) for (j = 0; j < sp->nchans; j++) if ((cp = ((chan_info *)(sp->chans[j])))) (*func)(cp, value); } } void for_each_chan(void (*func)(chan_info *ncp)) { int i; for (i = 0; i < ss->max_sounds; i++) { int j; snd_info *sp; chan_info *cp; sp = ss->sounds[i]; if ((sp) && ((sp->inuse == SOUND_NORMAL) || (sp->inuse == SOUND_WRAPPER))) for (j = 0; j < sp->nchans; j++) if ((cp = ((chan_info *)(sp->chans[j])))) (*func)(cp); } } void for_each_normal_chan_with_void(void (*func)(chan_info *ncp, void *ptr), void *userptr) { int i; for (i = 0; i < ss->max_sounds; i++) { int j; snd_info *sp; chan_info *cp; sp = ss->sounds[i]; if ((sp) && (sp->inuse == SOUND_NORMAL)) for (j = 0; j < sp->nchans; j++) if ((cp = ((chan_info *)(sp->chans[j])))) (*func)(cp, userptr); } } void for_each_normal_chan_with_int(void (*func)(chan_info *ncp, int val), int value) { int i; for (i = 0; i < ss->max_sounds; i++) { int j; snd_info *sp; chan_info *cp; sp = ss->sounds[i]; if ((sp) && (sp->inuse == SOUND_NORMAL)) for (j = 0; j < sp->nchans; j++) if ((cp = ((chan_info *)(sp->chans[j])))) (*func)(cp, value); } } void for_each_normal_chan_with_refint(void (*func)(chan_info *ncp, int *val), int *value) { int i; for (i = 0; i < ss->max_sounds; i++) { int j; snd_info *sp; chan_info *cp; sp = ss->sounds[i]; if ((sp) && (sp->inuse == SOUND_NORMAL)) for (j = 0; j < sp->nchans; j++) if ((cp = ((chan_info *)(sp->chans[j])))) (*func)(cp, value); } } void for_each_normal_chan(void (*func)(chan_info *ncp)) { int i; for (i = 0; i < ss->max_sounds; i++) { int j; snd_info *sp; chan_info *cp; sp = ss->sounds[i]; if ((sp) && (sp->inuse == SOUND_NORMAL)) for (j = 0; j < sp->nchans; j++) if ((cp = ((chan_info *)(sp->chans[j])))) (*func)(cp); } } void for_each_sound_chan_with_int(snd_info *sp, void (*func)(chan_info *ncp, int val1), int value) { int j; chan_info *cp; for (j = 0; j < sp->nchans; j++) if ((cp = sp->chans[j])) (*func)(cp, value); } bool map_over_sound_chans(snd_info *sp, bool (*func)(chan_info *ncp)) { int j; bool val = false; chan_info *cp; for (j = 0; j < sp->nchans; j++) if ((cp = sp->chans[j])) { val = (*func)(cp); if (val) return(val); } return(val); } void for_each_sound_chan(snd_info *sp, void (*func)(chan_info *ncp)) { int j; chan_info *cp; for (j = 0; j < sp->nchans; j++) if ((cp = sp->chans[j])) (*func)(cp); } void for_each_sound(void (*func)(snd_info *usp)) { int i; for (i = 0; i < ss->max_sounds; i++) { snd_info *sp; sp = ss->sounds[i]; if ((sp) && (sp->inuse == SOUND_NORMAL)) (*func)(sp); } } void for_each_sound_with_void(void (*func)(snd_info *usp, void *ptr), void *userptr) { int i; for (i = 0; i < ss->max_sounds; i++) { snd_info *sp; sp = ss->sounds[i]; if ((sp) && (sp->inuse == SOUND_NORMAL)) (*func)(sp, userptr); } } void for_each_separate_chan(void (*func)(chan_info *ncp)) { /* used only to lock/unlock panes */ int i; for (i = 0; i < ss->max_sounds; i++) { snd_info *sp; sp = ss->sounds[i]; if ((sp) && (sp->inuse == SOUND_NORMAL)) { if (sp->channel_style != CHANNELS_SEPARATE) (*func)(sp->chans[0]); else for_each_sound_chan(sp, func); } } } bool snd_ok(snd_info *sp) { return((sp) && (sp->inuse != SOUND_IDLE) && (sp->active)); } int active_channels(virtual_channels_t count_virtual_channels) { int chans = 0, i; for (i = 0; i < ss->max_sounds; i++) { snd_info *sp; sp = ss->sounds[i]; if (snd_ok(sp) && (sp->inuse != SOUND_WRAPPER)) { if ((count_virtual_channels == WITH_VIRTUAL_CHANNELS) || (sp->channel_style == CHANNELS_SEPARATE)) chans += sp->nchans; else chans++; } } return(chans); } #define SOUNDS_ALLOC_SIZE 4 int find_free_sound_slot(int desired_chans) { int i, j; snd_info *sp; /* first try to find an unused slot that can accommodate desired_chans (to reduce Widget creation) */ if (ss->reloading_updated_file > 0) { /* snd_update should change the underlying slot only when it has to (user increased chans) */ sp = ss->sounds[ss->reloading_updated_file - 1]; if ((sp == NULL) || ((sp->inuse == SOUND_IDLE) && (sp->allocated_chans >= desired_chans))) return(ss->reloading_updated_file - 1); } for (i = 0; i < ss->max_sounds; i++) { sp = ss->sounds[i]; if ((sp) && (sp->inuse == SOUND_IDLE) && (sp->allocated_chans == desired_chans)) return(i); } for (i = 0; i < ss->max_sounds; i++) { sp = ss->sounds[i]; if ((sp) && (sp->inuse == SOUND_IDLE) && (sp->allocated_chans > desired_chans)) return(i); } for (i = 0; i < ss->max_sounds; i++) { sp = ss->sounds[i]; if (sp == NULL) return(i); if (sp->inuse == SOUND_IDLE) return(i); } j = ss->max_sounds; ss->max_sounds += SOUNDS_ALLOC_SIZE; ss->sounds = (snd_info **)realloc(ss->sounds, ss->max_sounds * sizeof(snd_info *)); for (i = j; i < ss->max_sounds; i++) ss->sounds[i] = NULL; return(j); } int find_free_sound_slot_for_channel_display(void) { int i, j; for (i = 0; i < ss->max_sounds; i++) if (ss->sounds[i] == NULL) return(i); j = ss->max_sounds; ss->max_sounds += SOUNDS_ALLOC_SIZE; ss->sounds = (snd_info **)realloc(ss->sounds, ss->max_sounds * sizeof(snd_info *)); for (i = j; i < ss->max_sounds; i++) ss->sounds[i] = NULL; return(j); } static snd_info *any_active_sound(void) { int i; for (i = 0; i < ss->max_sounds; i++) { snd_info *sp; sp = ss->sounds[i]; if ((sp) && (sp->inuse == SOUND_NORMAL)) return(sp); } return(NULL); } snd_info *selected_sound(void) { if ((ss->selected_sound != NO_SELECTION) && (snd_ok(ss->sounds[ss->selected_sound]))) return(ss->sounds[ss->selected_sound]); ss->selected_sound = NO_SELECTION; return(NULL); } snd_info *any_selected_sound(void) { snd_info *sp; sp = selected_sound(); if (!sp) sp = any_active_sound(); return(sp); } chan_info *any_selected_channel(snd_info *sp) { int chan = 0; if (sp->selected_channel != NO_SELECTION) chan = sp->selected_channel; if ((sp->chans[chan]) && (sp->chans[chan]->active > CHANNEL_INITIALIZED)) return(sp->chans[chan]); return(NULL); } chan_info *selected_channel(void) { if (ss->selected_sound != NO_SELECTION) { snd_info *sp; sp = ss->sounds[ss->selected_sound]; if ((sp->inuse == SOUND_NORMAL) && (sp->selected_channel != NO_SELECTION)) return(sp->chans[sp->selected_channel]); } return(NULL); } static Xen select_sound_hook; static Xen select_channel_hook; static int current_selectpos = 0; static void select_sound(snd_info *sp) { if ((sp == NULL) || (sp->inuse != SOUND_NORMAL)) return; if (Xen_hook_has_list(select_sound_hook)) run_hook(select_sound_hook, Xen_list_1(C_int_to_Xen_sound(sp->index)), S_select_sound_hook); if (ss->selected_sound != sp->index) { reflect_sound_selection(sp); ss->selected_sound = sp->index; new_active_channel_alert(); reflect_save_as_sound_selection(sp->short_filename); } sp->selectpos = current_selectpos++; if (Xen_hook_has_list(ss->effects_hook)) run_hook(ss->effects_hook, Xen_empty_list, S_effects_hook); } chan_info *color_selected_channel(snd_info *sp) { chan_info *ncp; ncp = sp->chans[sp->selected_channel]; recolor_graph(ncp, true); ncp->selected = true; update_graph(ncp); /* update any indication of change in selected channel (channel id for example) */ return(ncp); } void select_channel(snd_info *sp, int chan) { chan_info *cp; if ((sp == NULL) || (sp->inuse != SOUND_NORMAL)) return; cp = selected_channel(); if (cp != sp->chans[chan]) { chan_info *ncp; sp->selected_channel = chan; select_sound(sp); if (cp) { recolor_graph(cp, false); cp->selected = false; if (sp != cp->sound) cp->sound->selected_channel = NO_SELECTION; update_graph(cp); } if (Xen_hook_has_list(select_channel_hook)) run_hook(select_channel_hook, Xen_list_2(C_int_to_Xen_sound(sp->index), C_int_to_Xen_integer(chan)), S_select_channel_hook); ncp = color_selected_channel(sp); goto_graph(ncp); } } chan_info *current_channel(void) { snd_info *sp = NULL; if (ss->selected_sound != NO_SELECTION) sp = ss->sounds[ss->selected_sound]; else sp = any_active_sound(); if (sp) return(any_selected_channel(sp)); return(NULL); } sync_info *free_sync_info(sync_info *si) { if (si) { if (si->begs) free(si->begs); si->begs = NULL; if (si->cps) free(si->cps); si->cps = NULL; free(si); } return(NULL); } int syncd_channels(int sync) { if (sync != 0) { int i, chans = 0; snd_info *sp; for (i = 0; i < ss->max_sounds; i++) { sp = ss->sounds[i]; if ((sp) && (sp->inuse == SOUND_NORMAL) && (sp->sync == sync)) chans += sp->nchans; } return(chans); } return(0); } sync_info *snd_sync(int sync) { int chans; snd_info *sp; chans = syncd_channels(sync); if (chans > 0) { int i, j; sync_info *si; si = (sync_info *)calloc(1, sizeof(sync_info)); si->begs = (mus_long_t *)calloc(chans, sizeof(mus_long_t)); si->cps = (chan_info **)calloc(chans, sizeof(chan_info *)); si->chans = chans; for (i = 0, j = 0; i < ss->max_sounds; i++) { int k; sp = ss->sounds[i]; if ((sp) && (sp->inuse == SOUND_NORMAL) && (sp->sync == sync)) for (k = 0; k < sp->nchans; k++, j++) si->cps[j] = sp->chans[k]; } return(si); } return(NULL); } sync_info *make_simple_sync(chan_info *cp, mus_long_t beg) { sync_info *si; si = (sync_info *)calloc(1, sizeof(sync_info)); si->chans = 1; si->cps = (chan_info **)calloc(1, sizeof(chan_info *)); si->cps[0] = cp; si->begs = (mus_long_t *)calloc(1, sizeof(mus_long_t)); si->begs[0] = beg; return(si); } sync_info *sync_to_chan(chan_info *cp) { snd_info *sp; sp = cp->sound; if (sp->sync != 0) return(snd_sync(sp->sync)); return(make_simple_sync(cp, 0)); } snd_info *find_sound(const char *name, int nth) { char *sname; int i, which = 0; if (name == NULL) return(NULL); sname = filename_without_directory(name); for (i = 0; i < ss->max_sounds; i++) { snd_info *sp; sp = ss->sounds[i]; if ((sp) && (sp->inuse == SOUND_NORMAL)) if ((mus_strcmp(name, sp->short_filename)) || (mus_strcmp(name, sp->filename)) || (mus_strcmp(sname, sp->short_filename))) { if (which == nth) return(sp); which++; } } return(NULL); } void g_init_data(void) { #define H_select_sound_hook S_select_sound_hook " (snd): called whenever a sound is selected." #define H_select_channel_hook S_select_channel_hook " (snd chn): called whenever a channel is selected. \ Its arguments are the sound index and the channel number." select_sound_hook = Xen_define_hook(S_select_sound_hook, "(make-hook 'snd)", 1, H_select_sound_hook); select_channel_hook = Xen_define_hook(S_select_channel_hook, "(make-hook 'snd 'chn)", 2, H_select_channel_hook); } snd-16.1/hooks.rb0000644000076400007640000002701012476114577012021 0ustar bilbil# hooks.rb -- hook-related functions # Author: Michael Scholz # Created: 03/12/21 13:48:01 # Changed: 15/02/27 23:12:08 # If class Hook isn't compiled in, here is the corresponding Ruby # class and the initialization of all global hooks. =begin # example in extsnd.html, "Channel-specific hooks" def protect(snd = false, chn = false) edit_pos = edit_position(snd, chn) hook = edit_hook(snd, chn) hook.reset_hook! hook.add_hook!("protect") do | | snd_print("protected") if val = edit_position(snd, chn) < edit_pos val end end def unprotect(snd = false, chn = false) edit_hook(snd, chn).reset_hook! end =end # Snd_hooks an array containing all global hook variables # # $var_hook.member?("name of hook") # $var_hook.show or # describe_hook(hook) prints code of hook procedures if file exists # $var.run_hook_by_name(name, *args) # # with_local_hook(hook, *procs, &thunk) # reset_all_hooks() clears all hook procedures require "clm" unless defined?(Hook) class Hook include Enumerable def initialize(name, arity = 0, help = "") @name = name @arity = arity @procs = [] if string?(help) and (not help.empty?) add_help(name, help) end end attr_reader :name, :arity def add_hook!(name, &body) @procs.push([name, body]) end def remove_hook!(name) @procs.delete(@procs.assoc(name)) end def reset_hook! @procs.clear end def run_hook(&body) self.to_a.each(&body) end alias each run_hook def call(*args) ret = nil self.run_hook do |prc| ret = prc.call(*args) end ret end def to_a @procs.map do |ary| ary.last end end def length @procs.length end alias size length def empty? @procs.empty? end def describe get_help(@name) end alias documentation describe def names @procs.map do |ary| ary.first end end def inspect format("#<%s name: %p, arity: %d, procs[%d]: %p>", self.class, @name, @arity, self.length, self.names) end end def make_hook(name, arity = 0, help = "", hook_name = nil, &body) error_str = "make_hook(name, arity=0, help=\"\", hook_name=nil, &body): \ need a String or Symbol, not %p" var_sym = case name when Symbol name when String name.intern else raise format(error_str, name) end if var_sym.to_s.split(//).first != "$" var_sym = format("$%s", var_sym.to_s).intern end unless (var = Hook.instance_eval("#{var_sym} if defined?(#{var_sym})")) var = Hook.new(var_sym.to_s, arity, help) end if block_given? unless string?(hook_name) hook_name = format("%s hook", var_sym.to_s) end var.add_hook!(hook_name, &body) end Hook.instance_eval("#{var_sym} = var") end def hook?(obj) obj.kind_of?(Hook) end $after_apply_controls_hook = Hook.new("$after_apply_controls_hook", 1) $after_graph_hook = Hook.new("$after_graph_hook", 2) $after_lisp_graph_hook = Hook.new("$after_lisp_graph_hook", 2) $after_open_hook = Hook.new("$after_open_hook", 1) $after_save_as_hook = Hook.new("$after_save_as_hook", 3) $after_save_state_hook = Hook.new("$after_save_state_hook", 1) $after_transform_hook = Hook.new("$after_transform_hook", 3) $bad_header_hook = Hook.new("$bad_header_hook", 1) $before_close_hook = Hook.new("$before_close_hook", 1) $before_exit_hook = Hook.new("$before_exit_hook", 0) $before_save_as_hook = Hook.new("$before_save_as_hook", 7) $before_save_state_hook = Hook.new("$before_save_state_hook", 1) $before_transform_hook = Hook.new("$before_transform_hook", 2) $clip_hook = Hook.new("$clip_hook", 1) $close_hook = Hook.new("$close_hook", 1) $dac_hook = Hook.new("$dac_hook", 1) $draw_mark_hook = Hook.new("$draw_mark_hook", 1) $draw_mix_hook = Hook.new("$draw_mix_hook", 5) $drop_hook = Hook.new("$drop_hook", 1) $during_open_hook = Hook.new("$during_open_hook", 3) $effects_hook = Hook.new("$effects_hook", 0) $enved_hook = Hook.new("$enved_hook", 5) $exit_hook = Hook.new("$exit_hook", 0) $graph_hook = Hook.new("$graph_hook", 4) $help_hook = Hook.new("$help_hook", 2) $initial_graph_hook = Hook.new("$initial_graph_hook", 3) $key_press_hook = Hook.new("$key_press_hook", 4) $lisp_graph_hook = Hook.new("$lisp_graph_hook", 2) $listener_click_hook = Hook.new("$listener_click_hook", 1) $mark_click_hook = Hook.new("$mark_click_hook", 1) $mark_drag_hook = Hook.new("$mark_drag_hook", 1) $mark_hook = Hook.new("$mark_hook", 4) $mix_click_hook = Hook.new("$mix_click_hook", 1) $mix_drag_hook = Hook.new("$mix_drag_hook", 3) $mix_release_hook = Hook.new("$mix_release_hook", 2) $mouse_click_hook = Hook.new("$mouse_click_hook", 7) $mouse_drag_hook = Hook.new("$mouse_drag_hook", 6) $mouse_enter_graph_hook = Hook.new("$mouse_enter_graph_hook", 2) $mouse_enter_label_hook = Hook.new("$mouse_enter_label_hook", 3) $mouse_enter_listener_hook = Hook.new("$mouse_enter_listener_hook", 1) $mouse_enter_text_hook = Hook.new("$mouse_enter_text_hook", 1) $mouse_leave_graph_hook = Hook.new("$mouse_leave_graph_hook", 2) $mouse_leave_label_hook = Hook.new("$mouse_leave_label_hook", 3) $mouse_leave_listener_hook = Hook.new("$mouse_leave_listener_hook", 1) $mouse_leave_text_hook = Hook.new("$mouse_leave_text_hook", 1) $mouse_press_hook = Hook.new("$mouse_press_hook", 6) $mus_error_hook = Hook.new("$mus_error_hook", 2) $name_click_hook = Hook.new("$name_click_hook", 1) $new_sound_hook = Hook.new("$new_sound_hook", 1) $new_widget_hook = Hook.new("$new_widget_hook", 1) $open_hook = Hook.new("$open_hook", 1) $open_raw_sound_hook = Hook.new("$open_raw_sound_hook", 2) $orientation_hook = Hook.new("$orientation_hook", 0) $output_comment_hook = Hook.new("$output_comment_hook", 1) $play_hook = Hook.new("$play_hook", 1) $read_hook = Hook.new("$read_hook", 1) $save_hook = Hook.new("$save_hook", 2) $save_state_hook = Hook.new("$save_state_hook", 1) $select_channel_hook = Hook.new("$select_channel_hook", 2) $select_sound_hook = Hook.new("$select_sound_hook", 1) $snd_error_hook = Hook.new("$snd_error_hook", 1) $snd_warning_hook = Hook.new("$snd_warning_hook", 1) $start_playing_hook = Hook.new("$start_playing_hook", 1) $start_playing_selection_hook = Hook.new("$start_playing_selection_hook", 0) $stop_dac_hook = Hook.new("$stop_dac_hook", 0) $stop_playing_hook = Hook.new("$stop_playing_hook", 1) $stop_playing_selection_hook = Hook.new("$stop_playing_selection_hook", 0) $update_hook = Hook.new("$update_hook", 1) # unless --without-gui $color_hook = Hook.new("$color_hook", 0) end class Hook def to_names @procs.map do |ary| ary.first end end def member?(name) to_names.member?(name) end alias included? member? # This works only with newer ruby versions (I assume >= 1.8.x). # Proc#to_s must return # not only # #! def to_str self.each do |prc| # cover printf's %x Snd.display(prc.to_str.gsub(/%/, "%%")) end nil end alias show to_str def run_hook_by_name(name, *args) if prc = @procs.assoc(name) prc.last.call(*args) end end end def describe_hook(hook) hook.show end add_help(:with_local_hook, "with_local_hook(hook, *procs, &thunk) \ Evaluates THUNK with HOOK set to PROCS, \ then restores HOOK to its previous state.") def with_local_hook(hook, *procs, &thunk) old_procs = [] hook.to_names.each do |name| old_procs.push(hook.remove_hook!(name)) end hook.reset_hook! procs.each do |prc| hook.add_hook!(prc.object_id.to_s, &prc) end thunk.call rescue Interrupt, ScriptError, StandardError Snd.display(verbose_message_string(true, nil, get_func_name)) ensure hook.reset_hook! old_procs.each do |name, prc| hook.add_hook!(name, &prc) end end if defined? $after_graph_hook Snd_hooks = [$after_apply_controls_hook, $after_graph_hook, $after_lisp_graph_hook, $after_open_hook, $after_save_as_hook, $after_save_state_hook, $after_transform_hook, $bad_header_hook, $before_close_hook, $before_exit_hook, $before_save_as_hook, $before_save_state_hook, $before_transform_hook, $clip_hook, $close_hook, $draw_mark_hook, $draw_mix_hook, $drop_hook, $during_open_hook, $effects_hook, $enved_hook, $exit_hook, $graph_hook, $help_hook, $initial_graph_hook, $key_press_hook, $lisp_graph_hook, $listener_click_hook, $mark_click_hook, $mark_drag_hook, $mark_hook, $mix_click_hook, $mix_drag_hook, $mix_release_hook, $mouse_click_hook, $mouse_drag_hook, $mouse_enter_graph_hook, $mouse_enter_label_hook, $mouse_enter_listener_hook, $mouse_enter_text_hook, $mouse_leave_graph_hook, $mouse_leave_label_hook, $mouse_leave_listener_hook, $mouse_leave_text_hook, $mouse_press_hook, $mus_error_hook, $name_click_hook, $new_sound_hook, $new_widget_hook, $open_hook, $open_raw_sound_hook, $orientation_hook, $output_comment_hook, $play_hook, $read_hook, $save_hook, $save_state_hook, $select_channel_hook, $select_sound_hook, $snd_error_hook, $snd_warning_hook, $start_playing_hook, $start_playing_selection_hook, $stop_playing_hook, $stop_playing_selection_hook, $update_hook] unless provided? :snd_nogui Snd_hooks.push($color_hook) end def reset_all_hooks Snd_hooks.each do |h| h.kind_of?(Hook) and h.reset_hook! end Snd.sounds.each do |snd| channels(snd).times do |chn| (h = edit_hook(snd, chn)).kind_of?(Hook) and h.reset_hook! (h = after_edit_hook(snd, chn)).kind_of?(Hook) and h.reset_hook! (h = undo_hook(snd, chn)).kind_of?(Hook) and h.reset_hook! end end end end # hooks.rb ends here snd-16.1/clm2xen.c0000644000076400007640000160064412614436173012071 0ustar bilbil/* tie CLM module into Scheme, Ruby, or Forth */ /* if the optimizer stops working inexplicably, look for any symbols used before this that * might shadow a generator name; one such case was (make-hook 'env...) in snd-env.c * * (env env) is accepted by the optimizer in error */ #include "mus-config.h" #if USE_SND #include "snd.h" #endif #include #include #include #include #include #include #include #include #ifndef _MSC_VER #include #else #include #pragma warning(disable: 4244) #endif #include "_sndlib.h" #include "xen.h" #include "clm.h" #include "sndlib2xen.h" #include "vct.h" #include "clm2xen.h" #include "clm-strings.h" #ifndef TWO_PI #define TWO_PI (2.0 * M_PI) #endif #ifndef PROC_FALSE #if HAVE_RUBY #define PROC_FALSE "false" #define PROC_TRUE "true" #else #define PROC_FALSE "#f" #define PROC_TRUE "#t" #endif #endif /* -------------------------------------------------------------------------------- */ #if HAVE_SCHEME static bool mus_simple_out_any_to_file(mus_long_t samp, mus_float_t val, int chan, mus_any *IO) { rdout *gen = (rdout *)IO; if ((chan < gen->chans) && (samp <= gen->data_end) && (samp >= gen->data_start)) { gen->obufs[chan][samp - gen->data_start] += val; if (samp > gen->out_end) gen->out_end = samp; return(true); } return(false); } #endif /* -------------------------------------------------------------------------------- */ struct mus_xen { mus_any *gen; int nvcts; #if HAVE_SCHEME bool free_data; #endif Xen *vcts; /* one for each accessible mus_float_t array (wrapped up here in a vct) */ struct mus_xen *next; }; enum {MUS_DATA_WRAPPER, MUS_INPUT_FUNCTION, MUS_ANALYZE_FUNCTION, MUS_EDIT_FUNCTION, MUS_SYNTHESIZE_FUNCTION, MUS_SELF_WRAPPER, MUS_INPUT_DATA, MUS_MAX_VCTS}; static mus_xen *mx_free_lists[8] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; static mus_xen *mx_alloc(int vcts) { mus_xen *p; if (mx_free_lists[vcts]) { p = mx_free_lists[vcts]; mx_free_lists[vcts] = p->next; return(p); } p = (mus_xen *)malloc(sizeof(mus_xen)); p->nvcts = vcts; if (vcts > 0) p->vcts = (Xen *)malloc(vcts * sizeof(Xen)); else p->vcts = NULL; #if HAVE_SCHEME p->free_data = false; #endif return(p); } static void mx_free(mus_xen *p) { #if HAVE_SCHEME if (p->free_data) { s7_xf_attach(s7, (void *)(p->vcts[MUS_INPUT_DATA])); p->free_data = false; } #endif p->next = mx_free_lists[p->nvcts]; mx_free_lists[p->nvcts] = p; } mus_any *mus_xen_gen(mus_xen *x) {return(x->gen);} #define mus_xen_to_mus_any(Gn) (((mus_xen *)Gn)->gen) #if (!HAVE_SCHEME) #define XEN_NULL 0 #define Xen_real_to_C_double_if_bound(Xen_Arg, C_Val, Caller, ArgNum) \ if (Xen_is_bound(Xen_Arg)) {if (Xen_is_number(Xen_Arg)) C_Val = Xen_real_to_C_double(Xen_Arg); else Xen_check_type(false, Xen_Arg, ArgNum, Caller, "a number");} #define Xen_to_C_double_or_error(Xen_Arg, C_Val, Caller, ArgNum) \ do {C_Val = 0.0; if (Xen_is_number(Xen_Arg)) C_Val = Xen_real_to_C_double(Xen_Arg); else Xen_check_type(false, Xen_Arg, ArgNum, Caller, "a number");} while (0) #define Xen_real_to_C_double_with_caller(Xen_Arg, Caller) Xen_real_to_C_double(Xen_Arg) #define Xen_to_C_integer_or_error(Xen_Arg, C_Val, Caller, ArgNum) \ do {if (Xen_is_integer(Xen_Arg)) C_Val = Xen_integer_to_C_int(Xen_Arg); else {C_Val = 0.0; Xen_check_type(false, Xen_Arg, ArgNum, Caller, "an integer");}} while (0) #if (HAVE_FORTH) || (HAVE_RUBY) #define Xen_object_ref_checked(Obj, Type) (Xen_c_object_is_type(Obj, Type) ? Xen_object_ref(Obj) : NULL) #else #define Xen_object_ref_checked(Obj, Type) NULL #endif #else #define Xen_real_to_C_double_if_bound(Xen_Arg, C_Val, Caller, ArgNum) if (Xen_is_bound(Xen_Arg)) C_Val = (double)s7_number_to_real_with_caller(s7, Xen_Arg, Caller) #define Xen_to_C_double_or_error(Xen_Arg, C_Val, Caller, ArgNum) C_Val = (double)s7_number_to_real_with_caller(s7, Xen_Arg, Caller) #define Xen_real_to_C_double_with_caller(Xen_Arg, Caller) s7_number_to_real_with_caller(s7, Xen_Arg, Caller) #define Xen_to_C_integer_or_error(Xen_Arg, C_Val, Caller, ArgNum) \ do {if (s7_is_integer(Xen_Arg)) C_Val = s7_integer(Xen_Arg); else {C_Val = 0.0; Xen_check_type(false, Xen_Arg, ArgNum, Caller, "an integer");}} while (0) #define Xen_object_ref_checked(Obj, Type) s7_object_value_checked(Obj, Type) #define XEN_NULL NULL #endif static int local_error_type = MUS_NO_ERROR; static char *local_error_msg = NULL; static void local_mus_error(int type, char *msg) { local_error_type = type; if (local_error_msg) free(local_error_msg); local_error_msg = mus_strdup(msg); } static Xen clm_mus_error(int type, const char *msg, const char *caller) { /* mus_error returns an int, which is a bother in this context */ mus_error(type, "%s: %s", caller, msg); return(Xen_false); } #define CLM_ERROR Xen_make_error_type("mus-error") static void clm_error(const char *caller, const char *msg, Xen val) { Xen_error(CLM_ERROR, Xen_list_4(C_string_to_Xen_string("~A: ~A ~A"), C_string_to_Xen_string(caller), C_string_to_Xen_string(msg), val)); } /* ---------------- optional-key ---------------- */ int mus_optkey_unscramble(const char *caller, int nkeys, Xen *keys, Xen *args, int *orig) { /* implement the &optional-key notion in CLM */ /* "keys" holds the keywords the calling function accepts, * upon return, if a key was given in the arglist or its position had a value, the corresponding value is in its keys location * "nkeys is the size of "keys" * "args" contains the original arguments passed to the function in order * it should be of size nkeys * 2, and any trailing (unspecified) args should be Xen_undefined * "orig" should be of size nkeys, and will contain upon return the 1-based location of the original keyword value argument * (it is intended for error reports) */ int arg_ctr = 0, key_start = 0, rtn_ctr = 0, nargs, nargs_end; bool keying = false, key_found = false; nargs = nkeys * 2; nargs_end = nargs - 1; while ((arg_ctr < nargs) && (Xen_is_bound(args[arg_ctr]))) { Xen key; key = args[arg_ctr]; if (!(Xen_is_keyword(key))) { if (keying) clm_error(caller, "unmatched value within keyword section?", key); /* type checking on the actual values has to be the caller's problem */ if (arg_ctr >= nkeys) /* we aren't handling a keyword arg, so the underlying args should only take nkeys args */ clm_error(caller, "extra trailing args?", key); keys[arg_ctr] = key; orig[arg_ctr] = arg_ctr + 1; arg_ctr++; key_start = arg_ctr; rtn_ctr++; } else { int i; Xen val; val = args[arg_ctr + 1]; if ((arg_ctr == nargs_end) || (!(Xen_is_bound(val)))) clm_error(caller, "keyword without value?", key); if (Xen_is_keyword(val)) clm_error(caller, "two keywords in a row?", key); keying = true; key_found = false; for (i = key_start; i < nkeys; i++) { if (Xen_keyword_is_eq(keys[i], key)) { keys[i] = val; arg_ctr += 2; orig[i] = arg_ctr; rtn_ctr++; key_found = true; break; } } if (!key_found) { /* either there's a redundant keyword pair or a keyword that 'caller' doesn't recognize */ clm_error(caller, "redundant or invalid key found", key); /* normally (all local cases) the error returns */ arg_ctr += 2; } } } return(rtn_ctr); } static mus_float_t optkey_float_error(Xen key, int n, const char *caller) { Xen_check_type(false, key, n, caller, "a number"); return(0.0); } #define Xen_optkey_to_float(Original_key, Key, Caller, N, Def) \ ((Xen_keyword_is_eq(Original_key, Key)) ? Def : ((Xen_is_number(Key)) ? Xen_real_to_C_double(Key) : optkey_float_error(Key, N, Caller))) mus_float_t mus_optkey_to_float(Xen key, const char *caller, int n, mus_float_t def) { if (Xen_is_number(key)) return(Xen_real_to_C_double(key)); if (!(Xen_is_keyword(key))) Xen_check_type(false, key, n, caller, "a number"); return(def); } static int optkey_int_error(Xen key, int n, const char *caller) { Xen_check_type(false, key, n, caller, "an integer"); return(0); } #define Xen_optkey_to_int(Original_key, Key, Caller, N, Def) \ ((Xen_keyword_is_eq(Original_key, Key)) ? Def : ((Xen_is_integer(Key)) ? Xen_integer_to_C_int(Key) : optkey_int_error(Key, N, Caller))) int mus_optkey_to_int(Xen key, const char *caller, int n, int def) { if (Xen_is_integer(key)) return(Xen_integer_to_C_int(key)); if (!(Xen_is_keyword(key))) Xen_check_type(false, key, n, caller, "an integer"); return(def); } bool mus_optkey_to_bool(Xen key, const char *caller, int n, bool def) { if (Xen_is_boolean(key)) return(Xen_boolean_to_C_bool(key)); if (!(Xen_is_keyword(key))) Xen_check_type(false, key, n, caller, "#f or #t"); return(def); } static mus_long_t optkey_llong_error(Xen key, int n, const char *caller) { Xen_check_type(false, key, n, caller, "an integer"); return(0); } #define Xen_optkey_to_mus_long_t(Original_key, Key, Caller, N, Def) \ ((Xen_keyword_is_eq(Original_key, Key)) ? Def : ((Xen_is_integer(Key)) ? Xen_llong_to_C_llong(Key) : optkey_llong_error(Key, N, Caller))) mus_long_t mus_optkey_to_mus_long_t(Xen key, const char *caller, int n, mus_long_t def) { if (Xen_is_integer(key)) return(Xen_llong_to_C_llong(key)); if (!(Xen_is_keyword(key))) Xen_check_type(false, key, n, caller, "a sample number or size"); return(def); } const char *mus_optkey_to_string(Xen key, const char *caller, int n, char *def) { if (Xen_is_string(key)) return(Xen_string_to_C_string(key)); if ((!(Xen_is_keyword(key))) && (!(Xen_is_false(key)))) Xen_check_type(false, key, n, caller, "a string"); return(def); } static vct *mus_optkey_to_vct(Xen key, const char *caller, int n, vct *def) { if (mus_is_vct(key)) return(Xen_to_vct(key)); if ((!(Xen_is_keyword(key))) && (!(Xen_is_false(key)))) Xen_check_type(false, key, n, caller, "a " S_vct); return(def); } static bool local_arity_ok(Xen proc, int args) /* from snd-xen.c minus (inconvenient) gc protection */ { #if HAVE_SCHEME return(s7_is_aritable(s7, proc, args)); #else Xen arity; int rargs; arity = Xen_arity(proc); rargs = Xen_integer_to_C_int(arity); #if HAVE_RUBY return(xen_rb_arity_ok(rargs, args)); #endif #if HAVE_FORTH return(rargs == args); #endif #endif return(true); } Xen mus_optkey_to_procedure(Xen key, const char *caller, int n, Xen def, int required_args, const char *err) { /* in this case, it's faster to look for the keyword first */ if ((!(Xen_is_keyword(key))) && (!(Xen_is_false(key)))) { Xen_check_type(Xen_is_procedure(key), key, n, caller, "a procedure"); if (!(local_arity_ok(key, required_args))) Xen_bad_arity_error(caller, n, key, err); return(key); } return(def); } /* ---------------- clm keywords ---------------- */ static Xen kw_frequency, kw_initial_phase, kw_wave, kw_amplitude, kw_r, kw_ratio, kw_size, kw_a0, kw_a1, kw_a2, kw_b1, kw_b2, kw_max_size, kw_input, kw_srate, kw_file, kw_channel, kw_start, kw_initial_contents, kw_initial_element, kw_scaler, kw_feedforward, kw_feedback, kw_radius, kw_partials, kw_a, kw_n, kw_order, kw_x_coeffs, kw_y_coeffs, kw_envelope, kw_base, kw_duration, kw_offset, kw_end, kw_direction, kw_degree, kw_distance, kw_reverb, kw_output, kw_fft_size, kw_expansion, kw_length, kw_hop, kw_ramp, kw_jitter, kw_type, kw_channels, kw_filter, kw_revout, kw_width, kw_edit, kw_synthesize, kw_analyze, kw_interp, kw_overlap, kw_pitch, kw_distribution, kw_coeffs, kw_kind; static void init_keywords(void) { /* in Ruby there's rb_intern of the symbol -- is it safe? */ kw_frequency = Xen_make_keyword("frequency"); kw_initial_phase = Xen_make_keyword("initial-phase"); kw_wave = Xen_make_keyword("wave"); kw_amplitude = Xen_make_keyword("amplitude"); kw_r = Xen_make_keyword("r"); kw_ratio = Xen_make_keyword("ratio"); kw_size = Xen_make_keyword("size"); kw_a0 = Xen_make_keyword("a0"); kw_a1 = Xen_make_keyword("a1"); kw_a2 = Xen_make_keyword("a2"); kw_b1 = Xen_make_keyword("b1"); kw_b2 = Xen_make_keyword("b2"); kw_max_size = Xen_make_keyword("max-size"); kw_input = Xen_make_keyword("input"); kw_srate = Xen_make_keyword("srate"); kw_file = Xen_make_keyword("file"); kw_channel = Xen_make_keyword("channel"); kw_start = Xen_make_keyword("start"); /* make-readin */ kw_initial_contents = Xen_make_keyword("initial-contents"); kw_initial_element = Xen_make_keyword("initial-element"); kw_scaler = Xen_make_keyword("scaler"); kw_feedforward = Xen_make_keyword("feedforward"); kw_feedback = Xen_make_keyword("feedback"); kw_radius = Xen_make_keyword("radius"); kw_partials = Xen_make_keyword("partials"); kw_a = Xen_make_keyword("a"); kw_n = Xen_make_keyword("n"); kw_order = Xen_make_keyword("order"); kw_x_coeffs = Xen_make_keyword("xcoeffs"); kw_y_coeffs = Xen_make_keyword("ycoeffs"); kw_envelope = Xen_make_keyword("envelope"); kw_base = Xen_make_keyword("base"); kw_duration = Xen_make_keyword("duration"); kw_offset = Xen_make_keyword("offset"); kw_end = Xen_make_keyword("end"); kw_direction = Xen_make_keyword("direction"); kw_degree = Xen_make_keyword("degree"); kw_distance = Xen_make_keyword("distance"); kw_reverb = Xen_make_keyword("reverb"); kw_output = Xen_make_keyword("output"); kw_fft_size = Xen_make_keyword("fft-size"); kw_expansion = Xen_make_keyword("expansion"); kw_length = Xen_make_keyword("length"); kw_hop = Xen_make_keyword("hop"); kw_ramp = Xen_make_keyword("ramp"); kw_jitter = Xen_make_keyword("jitter"); kw_type = Xen_make_keyword("type"); kw_channels = Xen_make_keyword("channels"); kw_filter = Xen_make_keyword("filter"); kw_revout = Xen_make_keyword("revout"); kw_width = Xen_make_keyword("width"); kw_edit = Xen_make_keyword("edit"); kw_synthesize = Xen_make_keyword("synthesize"); kw_analyze = Xen_make_keyword("analyze"); kw_interp = Xen_make_keyword("interp"); kw_overlap = Xen_make_keyword("overlap"); kw_pitch = Xen_make_keyword("pitch"); kw_distribution = Xen_make_keyword("distribution"); kw_coeffs = Xen_make_keyword("coeffs"); kw_kind = Xen_make_keyword("kind"); } /* ---------------- *clm-table-size* ---------------- */ static mus_long_t clm_table_size = MUS_CLM_DEFAULT_TABLE_SIZE; #if HAVE_SCHEME static s7_pointer clm_table_size_symbol; #endif mus_long_t clm_default_table_size_c(void) {return(clm_table_size);} static Xen g_clm_table_size(void) {return(C_llong_to_Xen_llong(clm_table_size));} static Xen g_set_clm_table_size(Xen val) { mus_long_t size; #define H_clm_table_size "(" S_clm_table_size "): the default table size for most generators (512)" Xen_check_type(Xen_is_llong(val), val, 1, S_set S_clm_table_size, "an integer"); size = Xen_llong_to_C_llong(val); if ((size <= 0) || (size > mus_max_table_size())) Xen_out_of_range_error(S_set S_clm_table_size, 1, val, "invalid size (see mus-max-table-size)"); clm_table_size = size; #if HAVE_SCHEME s7_symbol_set_value(s7, clm_table_size_symbol, s7_make_integer(s7, clm_table_size)); #endif return(C_llong_to_Xen_llong(clm_table_size)); } /* ---------------- *clm-default-frequency* ---------------- */ static mus_float_t clm_default_frequency = MUS_CLM_DEFAULT_FREQUENCY; #if HAVE_SCHEME static s7_pointer clm_default_frequency_symbol; #endif mus_float_t clm_default_frequency_c(void) {return(clm_default_frequency);} static Xen g_clm_default_frequency(void) {return(C_double_to_Xen_real(clm_default_frequency));} static Xen g_set_clm_default_frequency(Xen val) { #define H_clm_default_frequency "(" S_clm_default_frequency "): the default frequency for most generators (0.0)" Xen_check_type(Xen_is_double(val), val, 1, S_set S_clm_default_frequency, "a number"); clm_default_frequency = Xen_real_to_C_double(val); #if HAVE_SCHEME s7_symbol_set_value(s7, clm_default_frequency_symbol, s7_make_real(s7, clm_default_frequency)); #endif return(val); } /* ---------------- AM and simple stuff ---------------- */ static const char *fft_window_xen_names[MUS_NUM_FFT_WINDOWS] = {S_rectangular_window, S_hann_window, S_welch_window, S_parzen_window, S_bartlett_window, S_hamming_window, S_blackman2_window, S_blackman3_window, S_blackman4_window, S_exponential_window, S_riemann_window, S_kaiser_window, S_cauchy_window, S_poisson_window, S_gaussian_window, S_tukey_window, S_dolph_chebyshev_window, S_hann_poisson_window, S_connes_window, S_samaraki_window, S_ultraspherical_window, S_bartlett_hann_window, S_bohman_window, S_flat_top_window, S_blackman5_window, S_blackman6_window, S_blackman7_window, S_blackman8_window, S_blackman9_window, S_blackman10_window, S_rv2_window, S_rv3_window, S_rv4_window, S_mlt_sine_window, S_papoulis_window, S_dpss_window, S_sinc_window }; const char *mus_fft_window_xen_name(mus_fft_window_t i) {return(fft_window_xen_names[(int)i]);} static Xen g_mus_file_buffer_size(void) { #define H_mus_file_buffer_size "(" S_mus_file_buffer_size "): current CLM IO buffer size (default is 8192)" return(C_llong_to_Xen_llong(mus_file_buffer_size())); } #if HAVE_SCHEME static s7_pointer mus_file_buffer_size_symbol; #endif static Xen g_mus_set_file_buffer_size(Xen val) { mus_long_t len; Xen_check_type(Xen_is_llong(val), val, 1, S_set S_mus_file_buffer_size, "an integer"); len = Xen_llong_to_C_llong(val); if (len <= 0) Xen_out_of_range_error(S_set S_mus_file_buffer_size, 1, val, "must be > 0"); mus_set_file_buffer_size(len); #if HAVE_SCHEME s7_symbol_set_value(s7, mus_file_buffer_size_symbol, s7_make_integer(s7, len)); #endif return(val); } static Xen g_radians_to_hz(Xen val) { #define H_radians_to_hz "(" S_radians_to_hz " rads): convert radians per sample to frequency in Hz: rads * srate / (2 * pi)" mus_float_t x; Xen_to_C_double_or_error(val, x, S_radians_to_hz, 1); return(C_double_to_Xen_real(mus_radians_to_hz(x))); } static Xen g_hz_to_radians(Xen val) { #define H_hz_to_radians "(" S_hz_to_radians " hz): convert frequency in Hz to radians per sample: hz * 2 * pi / srate" mus_float_t x; Xen_to_C_double_or_error(val, x, S_hz_to_radians, 1); return(C_double_to_Xen_real(mus_hz_to_radians(x))); } static Xen g_radians_to_degrees(Xen val) { #define H_radians_to_degrees "(" S_radians_to_degrees " rads): convert radians to degrees: rads * 360 / (2 * pi)" mus_float_t x; Xen_to_C_double_or_error(val, x, S_radians_to_degrees, 1); return(C_double_to_Xen_real(mus_radians_to_degrees(x))); } static Xen g_degrees_to_radians(Xen val) { #define H_degrees_to_radians "(" S_degrees_to_radians " deg): convert degrees to radians: deg * 2 * pi / 360" mus_float_t x; Xen_to_C_double_or_error(val, x, S_degrees_to_radians, 1); return(C_double_to_Xen_real(mus_degrees_to_radians(x))); } static Xen g_db_to_linear(Xen val) { #define H_db_to_linear "(" S_db_to_linear " db): convert decibel value db to linear value: pow(10, db / 20)" mus_float_t x; Xen_to_C_double_or_error(val, x, S_db_to_linear, 1); return(C_double_to_Xen_real(mus_db_to_linear(x))); } static Xen g_linear_to_db(Xen val) { #define H_linear_to_db "(" S_linear_to_db " lin): convert linear value to decibels: 20 * log10(lin)" mus_float_t x; Xen_to_C_double_or_error(val, x, S_linear_to_db, 1); return(C_double_to_Xen_real(mus_linear_to_db(x))); } static Xen g_even_weight(Xen val) { #define H_even_weight "(" S_even_weight " x): return the even weight of x" mus_float_t x; Xen_to_C_double_or_error(val, x, S_even_weight, 1); return(C_double_to_Xen_real(mus_even_weight(x))); } static Xen g_odd_weight(Xen val) { #define H_odd_weight "(" S_odd_weight " x): return the odd weight of x" mus_float_t x; Xen_to_C_double_or_error(val, x, S_odd_weight, 1); return(C_double_to_Xen_real(mus_odd_weight(x))); } static Xen g_even_multiple(Xen val1, Xen val2) { #define H_even_multiple "(" S_even_multiple " x y): return the even multiple of x and y" mus_float_t x, y; Xen_to_C_double_or_error(val1, x, S_even_multiple, 1); Xen_to_C_double_or_error(val2, y, S_even_multiple, 2); return(C_double_to_Xen_real(mus_even_multiple(x, y))); } static Xen g_odd_multiple(Xen val1, Xen val2) { #define H_odd_multiple "(" S_odd_multiple " x y): return the odd multiple of x and y" mus_float_t x, y; Xen_to_C_double_or_error(val1, x, S_odd_multiple, 1); Xen_to_C_double_or_error(val2, y, S_odd_multiple, 2); return(C_double_to_Xen_real(mus_odd_multiple(x, y))); } static Xen g_seconds_to_samples(Xen val) { #define H_seconds_to_samples "(" S_seconds_to_samples " secs): use " S_mus_srate " to convert seconds to samples" mus_float_t x; Xen_to_C_double_or_error(val, x, S_seconds_to_samples, 1); return(C_llong_to_Xen_llong(mus_seconds_to_samples(x))); } static Xen g_samples_to_seconds(Xen val) { #define H_samples_to_seconds "(" S_samples_to_seconds " samps): use " S_mus_srate " to convert samples to seconds" Xen_check_type(Xen_is_llong(val), val, 1, S_samples_to_seconds, "a number"); return(C_double_to_Xen_real(mus_samples_to_seconds(Xen_llong_to_C_llong(val)))); } #if HAVE_SCHEME static s7_pointer clm_srate_symbol; #endif static Xen g_mus_srate(void) { #define H_mus_srate "(" S_mus_srate "): current sampling rate" return(C_double_to_Xen_real(mus_srate())); } static Xen g_mus_set_srate(Xen val) { mus_float_t sr; Xen_check_type(Xen_is_number(val), val, 1, S_set S_mus_srate, "a number"); sr = Xen_real_to_C_double(val); if (sr != mus_srate()) { if (sr <= 0.0) Xen_out_of_range_error(S_set S_mus_srate, 1, val, "must be > 0.0"); mus_set_srate(sr); #if HAVE_SCHEME s7_symbol_set_value(s7, clm_srate_symbol, s7_make_real(s7, sr)); #endif } return(val); } #if HAVE_SCHEME static s7_pointer mus_float_equal_fudge_factor_symbol; #endif static Xen g_mus_float_equal_fudge_factor(void) { #define H_mus_float_equal_fudge_factor "(" S_mus_float_equal_fudge_factor "): floating point equality fudge factor" return(C_double_to_Xen_real(mus_float_equal_fudge_factor())); } static Xen g_mus_set_float_equal_fudge_factor(Xen val) { mus_float_t factor; Xen_check_type(Xen_is_number(val), val, 1, S_set S_mus_float_equal_fudge_factor, "a number"); factor = Xen_real_to_C_double(val); if (factor != mus_float_equal_fudge_factor()) { mus_set_float_equal_fudge_factor(factor); #if HAVE_SCHEME s7_symbol_set_value(s7, mus_float_equal_fudge_factor_symbol, s7_make_real(s7, factor)); #endif } return(val); } #if HAVE_SCHEME static s7_pointer mus_array_print_length_symbol; #endif static Xen g_mus_array_print_length(void) { #define H_mus_array_print_length "(" S_mus_array_print_length "): current clm array print length (default is 8). This \ affects error reporting and generator descriptions. Array (" S_vct ") elements beyond this length are represented by '...'" return(C_int_to_Xen_integer(mus_array_print_length())); } static Xen g_mus_set_array_print_length(Xen val) { int len; Xen_check_type(Xen_is_integer(val), val, 1, S_set S_mus_array_print_length, "an integer"); len = Xen_integer_to_C_int(val); if (len != mus_array_print_length()) { if (len < 0) Xen_out_of_range_error(S_set S_mus_array_print_length, 1, val, "must be >= 0"); mus_set_array_print_length(len); #if HAVE_SCHEME s7_symbol_set_value(s7, mus_array_print_length_symbol, s7_make_integer(s7, len)); #endif } return(val); } static Xen g_ring_modulate(Xen val1, Xen val2) { #define H_ring_modulate "(" S_ring_modulate " s1 s2): s1 * s2 (sample by sample multiply)" Xen_check_type(Xen_is_number(val1), val1, 1, S_ring_modulate, "a number"); Xen_check_type(Xen_is_number(val2), val2, 2, S_ring_modulate, "a number"); return(C_double_to_Xen_real(mus_ring_modulate(Xen_real_to_C_double(val1), Xen_real_to_C_double(val2)))); } static Xen g_amplitude_modulate(Xen val1, Xen val2, Xen val3) { #define H_amplitude_modulate "(" S_amplitude_modulate " carrier in1 in2): in1 * (carrier + in2)" Xen_check_type(Xen_is_number(val1), val1, 1, S_amplitude_modulate, "a number"); Xen_check_type(Xen_is_number(val2), val2, 2, S_amplitude_modulate, "a number"); Xen_check_type(Xen_is_number(val3), val3, 3, S_amplitude_modulate, "a number"); return(C_double_to_Xen_real(mus_amplitude_modulate(Xen_real_to_C_double(val1), Xen_real_to_C_double(val2), Xen_real_to_C_double(val3)))); } static Xen g_contrast_enhancement(Xen val1, Xen val2) { mus_float_t index = 1.0; /* this is the default in clm.html and mus.lisp */ #define H_contrast_enhancement "(" S_contrast_enhancement " sig (index 1.0)): sin(sig * pi / 2 + index * sin(sig * 2 * pi))" Xen_check_type(Xen_is_number(val1), val1, 1, S_contrast_enhancement, "a number"); if (Xen_is_bound(val2)) { Xen_check_type(Xen_is_number(val2), val2, 2, S_contrast_enhancement, "a number"); index = Xen_real_to_C_double(val2); } return(C_double_to_Xen_real(mus_contrast_enhancement(Xen_real_to_C_double(val1), index))); } static Xen g_dot_product(Xen val1, Xen val2, Xen size) { #define H_dot_product "(" S_dot_product " v1 v2 (size)): sum of v1[i] * v2[i] (also named scalar product)" vct *v1, *v2; mus_long_t len; Xen_check_type(mus_is_vct(val1), val1, 1, S_dot_product, "a " S_vct); Xen_check_type(mus_is_vct(val2), val2, 2, S_dot_product, "a " S_vct); Xen_check_type(Xen_is_llong_or_unbound(size), size, 3, S_dot_product, "an integer"); v1 = Xen_to_vct(val1); v2 = Xen_to_vct(val2); if (Xen_is_llong(size)) { len = Xen_llong_to_C_llong(size); if (len == 0) return(C_double_to_Xen_real(0.0)); if (len < 0) Xen_out_of_range_error(S_dot_product, 3, size, "size < 0?"); if (len > mus_vct_length(v1)) len = mus_vct_length(v1); } else len = mus_vct_length(v1); if (len > mus_vct_length(v2)) len = mus_vct_length(v2); return(C_double_to_Xen_real(mus_dot_product(mus_vct_data(v1), mus_vct_data(v2), len))); } #if HAVE_COMPLEX_TRIG && HAVE_COMPLEX_NUMBERS && (!HAVE_RUBY) #if defined(__sun) && defined(__SVR4) #undef _Complex_I #define _Complex_I 1.0fi #endif #define S_edot_product "edot-product" static Xen g_edot_product(Xen val1, Xen val2) { #define H_edot_product "(" S_edot_product " freq data): sum of (e^freq*i) * data[i]" mus_long_t i, len; vct *v = NULL; complex double freq; complex double *vals; Xen result; Xen_check_type(Xen_is_complex(val1), val1, 1, S_edot_product, "complex"); Xen_check_type((mus_is_vct(val2)) || (Xen_is_vector(val2)), val2, 2, S_edot_product, "a " S_vct); freq = Xen_complex_to_C_complex(val1); if (mus_is_vct(val2)) { v = Xen_to_vct(val2); len = mus_vct_length(v); } else { len = Xen_vector_length(val2); } vals = (complex double *)calloc(len, sizeof(complex double)); if (mus_is_vct(val2)) { mus_float_t *vdata; vdata = mus_vct_data(v); for (i = 0; i < len; i++) vals[i] = vdata[i]; } else { for (i = 0; i < len; i++) vals[i] = Xen_complex_to_C_complex(Xen_vector_ref(val2, i)); } result = C_complex_to_Xen_complex(mus_edot_product(freq, vals, len)); free(vals); return(result); } #endif typedef enum {G_RECTANGULAR_POLAR, G_POLAR_RECTANGULAR, G_RECTANGULAR_MAGNITUDES} xclm_window_t; static Xen g_fft_window_1(xclm_window_t choice, Xen val1, Xen val2, Xen ulen, const char *caller) { vct *v1, *v2; mus_long_t len; Xen_check_type(mus_is_vct(val1), val1, 1, caller, "a " S_vct); Xen_check_type(mus_is_vct(val2), val2, 2, caller, "a " S_vct); Xen_check_type(Xen_is_llong_or_unbound(ulen), ulen, 3, caller, "an integer"); v1 = Xen_to_vct(val1); v2 = Xen_to_vct(val2); if (Xen_is_llong(ulen)) { len = Xen_llong_to_C_llong(ulen); if (len == 0) return(Xen_false); if (len < 0) Xen_out_of_range_error(caller, 3, ulen, "size < 0?"); if (len > mus_vct_length(v1)) len = mus_vct_length(v1); } else len = mus_vct_length(v1); if (len > mus_vct_length(v2)) len = mus_vct_length(v2); switch (choice) { case G_RECTANGULAR_POLAR: mus_rectangular_to_polar(mus_vct_data(v1), mus_vct_data(v2), len); break; case G_RECTANGULAR_MAGNITUDES: mus_rectangular_to_magnitudes(mus_vct_data(v1), mus_vct_data(v2), len); break; case G_POLAR_RECTANGULAR: mus_polar_to_rectangular(mus_vct_data(v1), mus_vct_data(v2), len); break; } return(val1); } static Xen g_rectangular_to_polar(Xen val1, Xen val2) { #define H_rectangular_to_polar "(" S_rectangular_to_polar " rl im): convert real/imaginary \ data in " S_vct "s rl and im from rectangular form (fft output) to polar form (a spectrum)" return(g_fft_window_1(G_RECTANGULAR_POLAR, val1, val2, Xen_undefined, S_rectangular_to_polar)); } static Xen g_rectangular_to_magnitudes(Xen val1, Xen val2) { #define H_rectangular_to_magnitudes "(" S_rectangular_to_magnitudes " rl im): convert real/imaginary \ data in " S_vct "s rl and im from rectangular form (fft output) to polar form, but ignore the phases" return(g_fft_window_1(G_RECTANGULAR_MAGNITUDES, val1, val2, Xen_undefined, S_rectangular_to_magnitudes)); } static Xen g_polar_to_rectangular(Xen val1, Xen val2) { #define H_polar_to_rectangular "(" S_polar_to_rectangular " rl im): convert real/imaginary \ data in " S_vct "s rl and im from polar (spectrum) to rectangular (fft)" return(g_fft_window_1(G_POLAR_RECTANGULAR, val1, val2, Xen_undefined, S_polar_to_rectangular)); } #if HAVE_SCHEME #if (!WITH_GMP) #define PF2_TO_PF(CName, Cfnc) \ static s7_pointer CName ## _pf_a(s7_scheme *sc, s7_pointer **p) \ { \ s7_pf_t f; \ s7_pointer x, y; \ f = (s7_pf_t)(**p); (*p)++; \ x = f(sc, p); \ f = (s7_pf_t)(**p); (*p)++; \ y = f(sc, p); \ return(Cfnc); \ } \ static s7_pf_t CName ## _pf(s7_scheme *sc, s7_pointer expr) \ { \ if ((s7_is_pair(s7_cdr(expr))) && (s7_is_pair(s7_cddr(expr))) && (s7_is_null(sc, s7_cdddr(expr))) && \ (s7_arg_to_pf(sc, s7_cadr(expr))) && \ (s7_arg_to_pf(sc, s7_caddr(expr)))) \ return(CName ## _pf_a); \ return(NULL); \ } PF2_TO_PF(rectangular_to_polar, g_rectangular_to_polar(x, y)) PF2_TO_PF(polar_to_rectangular, g_polar_to_rectangular(x, y)) PF2_TO_PF(rectangular_to_magnitudes, g_rectangular_to_magnitudes(x, y)) #endif #endif static Xen g_mus_fft(Xen url, Xen uim, Xen len, Xen usign) { #define H_mus_fft "(" S_mus_fft " rl im (len) (dir 1)): return the fft of " S_vct "s rl and im which contain \ the real and imaginary parts of the data; len should be a power of 2, dir = 1 for fft, -1 for inverse-fft" int sign; mus_long_t n; vct *v1, *v2; Xen_check_type((mus_is_vct(url)), url, 1, S_mus_fft, "a " S_vct); Xen_check_type((mus_is_vct(uim)), uim, 2, S_mus_fft, "a " S_vct); v1 = Xen_to_vct(url); v2 = Xen_to_vct(uim); if (Xen_is_integer(usign)) sign = Xen_integer_to_C_int(usign); else sign = 1; if (Xen_is_llong(len)) { n = Xen_llong_to_C_llong(len); if (n <= 0) Xen_out_of_range_error(S_mus_fft, 3, len, "size <= 0?"); if (n > mus_max_malloc()) Xen_out_of_range_error(S_mus_fft, 3, len, "size too large (see mus-max-malloc)"); if (n > mus_vct_length(v1)) n = mus_vct_length(v1); } else n = mus_vct_length(v1); if (n > mus_vct_length(v2)) n = mus_vct_length(v2); if (!(is_power_of_2(n))) { mus_float_t nf; int np; nf = (log(n) / log(2.0)); np = (int)nf; n = (mus_long_t)pow(2.0, np); } if (n > 0) mus_fft(mus_vct_data(v1), mus_vct_data(v2), n, sign); /* * in fftw, there's the extra complex array allocation, so for n = 2^29 * (and doubles for vcts as well as fftw), we need 24.6 Gbytes, and the FFT * takes 144 secs on a 2.4 GHz machine. (Similarly, 2^28 needs 12.6 Gb * and takes 61 secs). */ return(url); } static Xen g_make_fft_window(Xen type, Xen size, Xen ubeta, Xen ualpha) { #if HAVE_SCHEME #define make_window_example "(" S_make_fft_window " " S_hamming_window " 256)" #endif #if HAVE_RUBY #define make_window_example "make_fft_window(Hamming_window, 256)" #endif #if HAVE_FORTH #define make_window_example "hamming-window 256 make-fft-window" #endif #define H_make_fft_window "(" S_make_fft_window " type size (beta 0.0) (alpha 0.0)): -> fft data window (a " S_vct "). \ type is one of the sndlib fft window identifiers such as " S_kaiser_window ", beta \ is the window family parameter, if any:\n " make_window_example mus_float_t beta = 0.0, alpha = 0.0; mus_long_t n; int fft_window; mus_float_t *data; Xen_check_type(Xen_is_integer(type), type, 1, S_make_fft_window, "an integer (window type)"); Xen_check_type(Xen_is_llong(size), size, 2, S_make_fft_window, "an integer"); if (Xen_is_number(ubeta)) beta = Xen_real_to_C_double(ubeta); if (Xen_is_number(ualpha)) alpha = Xen_real_to_C_double(ualpha); n = Xen_llong_to_C_llong(size); if (n <= 0) Xen_out_of_range_error(S_make_fft_window, 2, size, "size <= 0?"); if (n > mus_max_malloc()) Xen_out_of_range_error(S_make_fft_window, 2, size, "size too large (see mus-max-malloc)"); fft_window = Xen_integer_to_C_int(type); if (!(mus_is_fft_window(fft_window))) Xen_out_of_range_error(S_make_fft_window, 1, type, "unknown fft window"); data = (mus_float_t *)malloc(n * sizeof(mus_float_t)); mus_make_fft_window_with_window((mus_fft_window_t)fft_window, n, beta, alpha, data); return(xen_make_vct(n, data)); } static Xen g_spectrum(Xen url, Xen uim, Xen uwin, Xen utype) { #define H_mus_spectrum "(" S_spectrum " rl im window (type 1)): \ real and imaginary data in " S_vct "s rl and im, returns (in rl) the spectrum thereof; \ window is the fft data window (a " S_vct " as returned by " S_make_fft_window "), \ and type determines how the spectral data is scaled:\n\ 0 = data in dB,\n\ 1 (default) = linear and normalized\n\ 2 = linear and un-normalized." int type; mus_long_t n; vct *v1, *v2, *v3 = NULL; Xen_check_type((mus_is_vct(url)), url, 1, S_spectrum, "a " S_vct); Xen_check_type((mus_is_vct(uim)), uim, 2, S_spectrum, "a " S_vct); if (!Xen_is_false(uwin)) Xen_check_type((mus_is_vct(uwin)), uwin, 3, S_spectrum, "a " S_vct " or " PROC_FALSE); v1 = Xen_to_vct(url); v2 = Xen_to_vct(uim); if (!Xen_is_false(uwin)) v3 = Xen_to_vct(uwin); n = mus_vct_length(v1); if (n > mus_vct_length(v2)) n = mus_vct_length(v2); if ((v3) && (n > mus_vct_length(v3))) n = mus_vct_length(v3); if (!(is_power_of_2(n))) { mus_float_t nf; int np; nf = (log(n) / log(2.0)); np = (int)nf; n = (int)pow(2.0, np); } if (Xen_is_integer(utype)) type = Xen_integer_to_C_int(utype); else type = 1; /* linear normalized */ if ((type < 0) || (type > 2)) Xen_out_of_range_error(S_spectrum, 4, utype, "type must be 0..2"); if (n > 0) mus_spectrum(mus_vct_data(v1), mus_vct_data(v2), (v3) ? (mus_vct_data(v3)) : NULL, n, (mus_spectrum_t)type); return(url); } static Xen g_autocorrelate(Xen reals) { #define H_autocorrelate "(" S_autocorrelate " data): in place autocorrelation of data (a " S_vct ")" /* assumes length is power of 2 */ vct *v1 = NULL; Xen_check_type(mus_is_vct(reals), reals, 1, S_autocorrelate, "a " S_vct); v1 = Xen_to_vct(reals); if (mus_vct_length(v1) > 0) mus_autocorrelate(mus_vct_data(v1), mus_vct_length(v1)); return(reals); } static Xen g_correlate(Xen data1, Xen data2) { #define H_correlate "(" S_correlate " data1 data2): in place cross-correlation of data1 and data2 (both " S_vct "s)" mus_long_t size; vct *v1 = NULL, *v2 = NULL; Xen_check_type(mus_is_vct(data1), data1, 1, S_correlate, "a " S_vct); Xen_check_type(mus_is_vct(data2), data2, 2, S_correlate, "a " S_vct); v1 = Xen_to_vct(data1); v2 = Xen_to_vct(data2); if (mus_vct_length(v1) < mus_vct_length(v2)) size = mus_vct_length(v1); else size = mus_vct_length(v2); if (size > 0) mus_correlate(mus_vct_data(v1), mus_vct_data(v2), size); return(data1); } static Xen g_convolution(Xen url1, Xen url2, Xen un) { #define H_mus_convolution "(" S_convolution " v1 v2 (len)): convolution \ of " S_vct "s v1 with v2, using fft of size len (a power of 2), result in v1" mus_long_t n; vct *v1, *v2; Xen_check_type((mus_is_vct(url1)), url1, 1, S_convolution, "a " S_vct); Xen_check_type((mus_is_vct(url2)), url2, 2, S_convolution, "a " S_vct); v1 = Xen_to_vct(url1); v2 = Xen_to_vct(url2); if (Xen_is_integer(un)) { n = Xen_llong_to_C_llong(un); if (n <= 0) Xen_out_of_range_error(S_convolution, 3, un, "size <= 0?"); if (n > mus_max_malloc()) Xen_out_of_range_error(S_convolution, 3, un, "size too large (see mus-max-malloc)"); if (n > mus_vct_length(v1)) n = mus_vct_length(v1); } else n = mus_vct_length(v1); if (n > mus_vct_length(v2)) n = mus_vct_length(v2); if (!(is_power_of_2(n))) { mus_float_t nf; int np; nf = (log(n) / log(2.0)); np = (int)nf; n = (int)pow(2.0, np); } if (n > 0) mus_convolution(mus_vct_data(v1), mus_vct_data(v2), n); return(url1); } static Xen g_polynomial(Xen arr, Xen x) { #define H_polynomial "(" S_polynomial " coeffs x): evaluate a polynomial at x. coeffs are in order \ of degree, so coeff[0] is the constant term." #if (!HAVE_SCHEME) Xen_check_type(Xen_is_number(x), x, 2, S_polynomial, "a number"); #endif if (mus_is_vct(arr)) { vct *v; v = Xen_to_vct(arr); return(C_double_to_Xen_real(mus_polynomial(mus_vct_data(v), Xen_real_to_C_double_with_caller(x, S_polynomial), mus_vct_length(v)))); } Xen_check_type(Xen_is_vector(arr), arr, 1, S_polynomial, "a vector or " S_vct); { mus_float_t sum, cx; int i, ncoeffs; ncoeffs = Xen_vector_length(arr); if (ncoeffs <= 0) return(C_double_to_Xen_real(0.0)); if (ncoeffs == 1) return(Xen_vector_ref(arr, 0)); /* just a constant term */ cx = Xen_real_to_C_double_with_caller(x, S_polynomial); sum = Xen_real_to_C_double_with_caller(Xen_vector_ref(arr, ncoeffs - 1), S_polynomial); for (i = ncoeffs - 2; i >= 0; i--) sum = (sum * cx) + Xen_real_to_C_double_with_caller(Xen_vector_ref(arr, i), S_polynomial); return(C_double_to_Xen_real(sum)); } } static Xen g_array_interp(Xen obj, Xen phase, Xen size) /* opt size */ { #define H_array_interp "(" S_array_interp " v phase (size)): v[phase] \ taking into account wrap-around (size is size of data), with linear interpolation if phase is not an integer." mus_long_t len; vct *v; Xen_check_type(mus_is_vct(obj), obj, 1, S_array_interp, "a " S_vct); #if (!HAVE_SCHEME) Xen_check_type(Xen_is_number(phase), phase, 2, S_array_interp, "a number"); #endif Xen_check_type(Xen_is_llong_or_unbound(size), size, 3, S_array_interp, "an integer"); v = Xen_to_vct(obj); if (Xen_is_bound(size)) { len = Xen_llong_to_C_llong(size); if (len <= 0) Xen_out_of_range_error(S_array_interp, 3, size, "size <= 0?"); if (len > mus_vct_length(v)) len = mus_vct_length(v); } else len = mus_vct_length(v); if (len == 0) return(C_double_to_Xen_real(0.0)); return(C_double_to_Xen_real(mus_array_interp(mus_vct_data(v), Xen_real_to_C_double_with_caller(phase, S_array_interp), len))); } static Xen g_mus_interpolate(Xen type, Xen x, Xen obj, Xen size, Xen yn1) { #define H_mus_interpolate "(" S_mus_interpolate " type x v (size) (yn1 0.0)): interpolate in \ data ('v' is a " S_vct ") using interpolation 'type', such as " S_mus_interp_linear "." mus_long_t len; int itype; vct *v; mus_float_t y = 0.0; Xen_check_type(Xen_is_integer(type), type, 1, S_mus_interpolate, "an integer (interp type such as " S_mus_interp_all_pass ")"); Xen_check_type(Xen_is_number(x), x, 2, S_mus_interpolate, "a number"); Xen_check_type(mus_is_vct(obj), obj, 3, S_mus_interpolate, "a " S_vct); Xen_check_type(Xen_is_llong_or_unbound(size), size, 4, S_mus_interpolate, "an integer"); Xen_check_type(Xen_is_number_or_unbound(yn1), yn1, 5, S_mus_interpolate, "a number"); itype = Xen_integer_to_C_int(type); if (!(mus_is_interp_type(itype))) Xen_out_of_range_error(S_mus_interpolate, 1, type, "unknown interp type"); v = Xen_to_vct(obj); if (Xen_is_bound(size)) { len = Xen_llong_to_C_llong(size); if (len <= 0) Xen_out_of_range_error(S_mus_interpolate, 4, size, "size <= 0?"); if (len > mus_vct_length(v)) len = mus_vct_length(v); } else len = mus_vct_length(v); if (len == 0) return(C_double_to_Xen_real(0.0)); if (Xen_is_number(yn1)) y = Xen_real_to_C_double(yn1); return(C_double_to_Xen_real(mus_interpolate((mus_interp_t)itype, Xen_real_to_C_double(x), mus_vct_data(v), len, y))); } /* ---------------- mus-xen struct ---------------- */ static Xen_object_type_t mus_xen_tag; bool mus_is_xen(Xen obj) {return(Xen_c_object_is_type(obj, mus_xen_tag));} #define Xen_to_C_generator(Xen_Arg, X_Val, C_Val, Checker, Caller, Descr) \ Xen_check_type((X_Val = (mus_xen *)Xen_object_ref_checked(Xen_Arg, mus_xen_tag)) && (Checker(C_Val = (mus_any *)mus_xen_to_mus_any(X_Val))), Xen_Arg, 1, Caller, Descr) #define Xen_to_C_any_generator(Xen_Arg, X_Val, C_Val, Caller, Descr) \ Xen_check_type((X_Val = (mus_xen *)Xen_object_ref_checked(Xen_Arg, mus_xen_tag)) && (C_Val = (mus_any *)mus_xen_to_mus_any(X_Val)), Xen_Arg, 1, Caller, Descr) static Xen g_is_mus_generator(Xen obj) { #define H_is_mus_generator "(" S_is_mus_generator " obj): " PROC_TRUE " if 'obj' is a CLM generator." return(C_bool_to_Xen_boolean(mus_is_xen(obj))); } #if HAVE_SCHEME static Xen_object_mark_t mark_mus_xen(void *obj) #else static Xen_object_mark_t mark_mus_xen(Xen obj) #endif { mus_xen *ms; #if HAVE_RUBY || HAVE_SCHEME /* rb_gc_mark and scheme_mark_object pass us the actual value, not the Xen wrapper */ ms = (mus_xen *)obj; #endif #if HAVE_FORTH ms = Xen_to_mus_xen(obj); #endif if (ms->vcts) { int i, lim; lim = MUS_SELF_WRAPPER; if (ms->nvcts < lim) lim = ms->nvcts; #if HAVE_SCHEME if (ms->free_data) { for (i = 0; i < lim; i++) if ((i != MUS_INPUT_FUNCTION) && (i != MUS_INPUT_DATA) && (Xen_is_bound(ms->vcts[i]))) xen_gc_mark(ms->vcts[i]); return; } #endif for (i = 0; i < lim; i++) if (Xen_is_bound(ms->vcts[i])) xen_gc_mark(ms->vcts[i]); } #if HAVE_RUBY return(NULL); #endif #if (!HAVE_EXTENSION_LANGUAGE) return(0); #endif } static void mus_xen_free(mus_xen *ms) { mus_free(ms->gen); ms->gen = NULL; mx_free(ms); } Xen_wrap_free(mus_xen, free_mus_xen, mus_xen_free) #if HAVE_SCHEME static char *print_mus_xen(s7_scheme *sc, void *obj) { return(mus_describe(((mus_xen *)obj)->gen)); } static bool s7_equalp_mus_xen(void *val1, void *val2) { return(mus_equalp(((mus_xen *)val1)->gen, ((mus_xen *)val2)->gen)); } #endif enum {G_FILTER_STATE, G_FILTER_XCOEFFS, G_FILTER_YCOEFFS}; /* G_FILTER_STATE must = MUS_DATA_WRAPPER = 0 */ enum {G_LOCSIG_DATA, G_LOCSIG_REVDATA, G_LOCSIG_OUT, G_LOCSIG_REVOUT}; static Xen mus_xen_copy(mus_xen *ms) { /* return an object -> copied mus_xen -> copied mus_any gen */ mus_xen *np; np = mx_alloc(ms->nvcts); np->gen = mus_copy(ms->gen); if (ms->nvcts > 0) { if (ms->nvcts == 1) { if ((mus_is_env(np->gen)) || /* do the most common case first */ (mus_is_formant_bank(np->gen))) np->vcts[MUS_DATA_WRAPPER] = ms->vcts[MUS_DATA_WRAPPER]; else { if ((mus_is_comb_bank(np->gen)) || (mus_is_all_pass_bank(np->gen)) || (mus_is_filtered_comb_bank(np->gen))) { /* set up objects for new gens so that they will eventually be GC'd */ Xen v; int i, len; len = Xen_vector_length(ms->vcts[MUS_DATA_WRAPPER]); v = Xen_make_vector(len, Xen_false); np->vcts[MUS_DATA_WRAPPER] = v; for (i = 0; i < len; i++) Xen_vector_set(v, i, mus_xen_to_object(mus_any_to_mus_xen(mus_bank_generator(np->gen, i)))); } else np->vcts[MUS_DATA_WRAPPER] = xen_make_vct_wrapper(mus_length(np->gen), mus_data(np->gen)); } } else { if (ms->nvcts == 2) { if (mus_is_pulsed_env(np->gen)) { /* mus_free taken care of by copied pulsed_env gen */ np->vcts[0] = Xen_false; np->vcts[1] = Xen_false; } else { if (mus_is_filtered_comb(np->gen)) { np->vcts[0] = xen_make_vct_wrapper(mus_length(np->gen), mus_data(np->gen)); np->vcts[1] = Xen_false; /* filt gen but it's not wrapped */ } else { np->vcts[0] = ms->vcts[0]; np->vcts[1] = ms->vcts[1]; } } } else { if (ms->nvcts == 3) { if (mus_is_oscil_bank(np->gen)) { np->vcts[0] = ms->vcts[0]; np->vcts[1] = xen_make_vct_wrapper(mus_length(np->gen), mus_data(np->gen)); np->vcts[2] = ms->vcts[2]; } else { np->vcts[G_FILTER_STATE] = xen_make_vct_wrapper(mus_length(np->gen), mus_data(np->gen)); np->vcts[G_FILTER_XCOEFFS] = ms->vcts[G_FILTER_XCOEFFS]; np->vcts[G_FILTER_YCOEFFS] = ms->vcts[G_FILTER_YCOEFFS]; } } else { int i; for (i = 0; i < ms->nvcts; i++) np->vcts[i] = ms->vcts[i]; if (mus_is_granulate(np->gen)) np->vcts[MUS_DATA_WRAPPER] = xen_make_vct_wrapper(mus_granulate_grain_max_length(np->gen), mus_data(np->gen)); if ((mus_is_convolve(np->gen)) || (mus_is_src(np->gen)) || (mus_is_granulate(np->gen)) || (mus_is_phase_vocoder(np->gen))) { Xen c_obj; c_obj = mus_xen_to_object(np); np->vcts[MUS_SELF_WRAPPER] = c_obj; mus_generator_copy_feeders(np->gen, ms->gen); return(c_obj); } } } } } return(mus_xen_to_object(np)); } #if HAVE_RUBY static Xen mus_xen_to_s(Xen obj) { char *str; Xen result; str = mus_describe(Xen_to_mus_any(obj)); result = C_string_to_Xen_string(str); if (str) free(str); return(result); } #endif #if HAVE_FORTH static Xen print_mus_xen(Xen obj) { char *str; Xen result; str = mus_describe(Xen_to_mus_any(obj)); result = fth_make_string_format("#<%s>", str); if (str) free(str); return(result); } #endif #if (!HAVE_SCHEME) static Xen equalp_mus_xen(Xen obj1, Xen obj2) { if ((!(mus_is_xen(obj1))) || (!(mus_is_xen(obj2)))) return(Xen_false); return(C_bool_to_Xen_boolean(mus_equalp(Xen_to_mus_any(obj1), Xen_to_mus_any(obj2)))); } #endif #if HAVE_RUBY || HAVE_FORTH static Xen mus_xen_apply(Xen gen, Xen arg1, Xen arg2) { #if HAVE_FORTH Xen_check_type(mus_is_xen(gen), gen, 1, S_mus_apply, "a generator"); #endif return(C_double_to_Xen_real(mus_run(Xen_to_mus_any(gen), (Xen_is_number(arg1)) ? Xen_real_to_C_double(arg1) : 0.0, (Xen_is_number(arg2)) ? Xen_real_to_C_double(arg2) : 0.0))); } #endif #if HAVE_SCHEME /* these are for mus_xen_tag, so need not handle float-vectors */ static Xen mus_xen_apply(s7_scheme *sc, Xen gen, Xen args) { if (s7_is_pair(args)) { mus_float_t arg1, arg2; arg1 = s7_number_to_real_with_caller(sc, s7_car(args), "mus-apply"); args = s7_cdr(args); if (s7_is_pair(args)) arg2 = s7_number_to_real_with_caller(sc, s7_car(args), "mus-apply"); else arg2 = 0.0; return(s7_make_real(s7, mus_run(Xen_to_mus_any(gen), arg1, arg2))); } return(s7_make_real(s7, mus_run(Xen_to_mus_any(gen), 0.0, 0.0))); } static Xen s7_mus_length(s7_scheme *sc, Xen obj) { return(g_mus_length(obj)); } static Xen g_mus_copy(Xen gen); static Xen s7_mus_copy(s7_scheme *sc, Xen args) { return(g_mus_copy(s7_car(args))); } #endif Xen mus_xen_to_object(mus_xen *gn) /* global for user-defined gens */ { return(Xen_make_object(mus_xen_tag, gn, mark_mus_xen, free_mus_xen)); } Xen mus_xen_to_object_with_vct(mus_xen *gn, Xen v) /* global for user-defined gens */ { gn->vcts[MUS_DATA_WRAPPER] = v; return(Xen_make_object(mus_xen_tag, gn, mark_mus_xen, free_mus_xen)); } mus_any *mus_optkey_to_mus_any(Xen key, const char *caller, int n, mus_any *def) { /* from Michael Scholz's sndins.c */ if (!(Xen_is_keyword(key))) { Xen_check_type(mus_is_xen(key), key, n, caller, "a clm generator or keyword"); return(Xen_to_mus_any(key)); } return(def); } static Xen mus_optkey_to_input_procedure(Xen key, const char *caller, int n, Xen def, int required_args, const char *err) { if (Xen_is_procedure(key)) { if (!(local_arity_ok(key, required_args))) Xen_bad_arity_error(caller, n, key, err); return(key); } if (mus_is_xen(key)) { if (!(mus_is_input(Xen_to_mus_any(key)))) Xen_wrong_type_arg_error(caller, n, key, "an input generator"); return(key); } if ((!(Xen_is_keyword(key))) && (!(Xen_is_false(key)))) Xen_check_type(false, key, n, caller, "a procedure or input generator"); return(def); } /* ---------------- wrappers ---------------- */ mus_xen *mus_any_to_mus_xen(mus_any *ge) { mus_xen *gn; gn = mx_alloc(0); gn->gen = ge; return(gn); } mus_xen *mus_any_to_mus_xen_with_vct(mus_any *ge, Xen v) { mus_xen *gn; gn = mx_alloc(1); gn->gen = ge; gn->vcts[MUS_DATA_WRAPPER] = v; return(gn); } mus_xen *mus_any_to_mus_xen_with_two_vcts(mus_any *ge, Xen v1, Xen v2) { mus_xen *gn; gn = mx_alloc(2); gn->gen = ge; gn->vcts[MUS_DATA_WRAPPER] = v1; gn->vcts[MUS_INPUT_FUNCTION] = v2; return(gn); } /* ---------------- generic functions ---------------- */ static Xen g_mus_reset(Xen gen) { #define H_mus_reset "(" S_mus_reset " gen): clear out gen, setting it to its default starting state" mus_xen *ms; ms = (mus_xen *)Xen_object_ref_checked(gen, mus_xen_tag); if (ms) { mus_reset(ms->gen); return(gen); } #if HAVE_SCHEME if (s7_is_float_vector(gen)) { s7_int len; len = s7_vector_length(gen); if (len > 0) memset((void *)s7_float_vector_elements(gen), 0, len * sizeof(s7_double)); return(gen); } { s7_pointer func; func = s7_method(s7, gen, s7_make_symbol(s7, "mus-reset")); if (func != Xen_undefined) return(s7_apply_function(s7, func, s7_list(s7, 1, gen))); } #endif Xen_check_type(false, gen, 1, S_mus_reset, "a generator"); return(gen); } #if HAVE_SCHEME static s7_pointer mus_copy_symbol, copy_function; #endif static Xen g_mus_copy(Xen gen) { #define H_mus_copy "(" S_mus_copy " gen): return a copy of gen" mus_xen *ms; ms = (mus_xen *)Xen_object_ref_checked(gen, mus_xen_tag); if (ms) return(mus_xen_copy(ms)); #if HAVE_SCHEME { s7_pointer func; func = s7_method(s7, gen, mus_copy_symbol); if (func == copy_function) return(s7_copy(s7, s7_list(s7, 1, gen))); if (func != Xen_undefined) return(s7_apply_function(s7, func, s7_list(s7, 1, gen))); } #endif Xen_check_type(false, gen, 1, S_mus_copy, "a generator"); return(gen); } static Xen g_mus_run(Xen gen, Xen arg1, Xen arg2) { #define H_mus_run "(" S_mus_run " gen (arg1 0.0) (arg2 0.0)): apply gen to arg1 and arg2" mus_xen *ms; ms = (mus_xen *)Xen_object_ref_checked(gen, mus_xen_tag); if (ms) { mus_float_t a1 = 0.0, a2 = 0.0; Xen_real_to_C_double_if_bound(arg1, a1, S_mus_run, 2); Xen_real_to_C_double_if_bound(arg2, a2, S_mus_run, 3); return(C_double_to_Xen_real(mus_run(ms->gen, a1, a2))); } #if HAVE_SCHEME { s7_pointer func; func = s7_method(s7, gen, s7_make_symbol(s7, "mus-run")); if (func != Xen_undefined) return(s7_apply_function(s7, func, s7_list(s7, 3, gen, arg1, arg2))); } #endif Xen_check_type(false, gen, 1, S_mus_run, "a generator"); return(C_double_to_Xen_real(0.0)); } static Xen g_mus_apply(Xen arglist) { #define H_mus_apply "(" S_mus_apply " gen args...): apply gen to args" mus_xen *ms; Xen gen; int arglist_len; arglist_len = Xen_list_length(arglist); if ((arglist_len > 3) || (arglist_len == 0)) return(C_double_to_Xen_real(0.0)); gen = Xen_car(arglist); ms = (mus_xen *)Xen_object_ref_checked(gen, mus_xen_tag); if (ms) { mus_any *g; g = ms->gen; if (arglist_len == 1) return(C_double_to_Xen_real(mus_apply(g, 0.0, 0.0))); if (arglist_len == 2) return(C_double_to_Xen_real(mus_apply(g, Xen_real_to_C_double(Xen_cadr(arglist)), 0.0))); return(C_double_to_Xen_real(mus_apply(g, Xen_real_to_C_double_with_caller(Xen_cadr(arglist), "mus-apply"), Xen_real_to_C_double_with_caller(Xen_caddr(arglist), "mus-apply")))); } #if HAVE_SCHEME { s7_pointer func; func = s7_method(s7, gen, s7_make_symbol(s7, "mus-apply")); if (func != Xen_undefined) return(s7_apply_function(s7, func, arglist)); } #endif Xen_check_type(false, Xen_car(arglist), 1, S_mus_apply, "a generator"); return(C_double_to_Xen_real(0.0)); } static Xen g_mus_describe(Xen gen) { #define H_mus_describe "(" S_mus_describe " gen): return a string describing the state of CLM generator generator" mus_xen *ms; ms = (mus_xen *)Xen_object_ref_checked(gen, mus_xen_tag); if (ms) { Xen result; char *str; str = mus_describe(ms->gen); result = C_string_to_Xen_string(str); if (str) free(str); return(result); } #if HAVE_SCHEME { s7_pointer func; func = s7_method(s7, gen, s7_make_symbol(s7, "mus-describe")); if (func != Xen_undefined) return(s7_apply_function(s7, func, s7_list(s7, 1, gen))); } #endif Xen_check_type(false, gen, 1, S_mus_describe, "a generator"); return(gen); } #if HAVE_SCHEME #define mus_double_generic(Caller, CLM_case, Symbol) \ mus_xen *gn; \ s7_pointer func; \ gn = (mus_xen *)Xen_object_ref_checked(gen, mus_xen_tag); \ if (gn) return(C_double_to_Xen_real(CLM_case(gn->gen))); \ func = s7_method(s7, gen, Symbol); \ if (func != Xen_undefined) return(s7_apply_function(s7, func, s7_list(s7, 1, gen))); \ Xen_check_type(false, gen, 1, Caller, "a generator"); \ return(gen); #define mus_set_double_generic(Caller, CLM_case) \ mus_xen *gn; \ s7_pointer func; \ gn = (mus_xen *)Xen_object_ref_checked(gen, mus_xen_tag); \ Xen_check_type(Xen_is_double(val), val, 2, S_set Caller, "a float"); \ if (gn) {CLM_case(gn->gen, Xen_real_to_C_double(val)); return(val);} \ func = s7_method(s7, gen, s7_make_symbol(s7, Caller)); \ if ((func != Xen_undefined) && (s7_procedure_setter(s7, func))) \ return(s7_apply_function(s7, s7_procedure_setter(s7, func), s7_list(s7, 2, gen, val))); \ Xen_check_type(false, gen, 1, S_set Caller, "a generator"); \ return(val); #define mus_long_long_generic(Caller, CLM_case) \ mus_xen *gn; \ s7_pointer func; \ gn = (mus_xen *)Xen_object_ref_checked(gen, mus_xen_tag); \ if (gn) return(C_llong_to_Xen_llong(CLM_case(gn->gen))); \ func = s7_method(s7, gen, s7_make_symbol(s7, Caller)); \ if (func != Xen_undefined) return(s7_apply_function(s7, func, s7_list(s7, 1, gen))); \ Xen_check_type(false, gen, 1, Caller, "a generator"); \ return(gen); #define mus_set_long_long_generic(Caller, CLM_case) \ mus_xen *gn; \ s7_pointer func; \ gn = (mus_xen *)Xen_object_ref_checked(gen, mus_xen_tag); \ Xen_check_type(Xen_is_integer(val), val, 2, Caller, "an integer"); \ if (gn) {CLM_case(gn->gen, Xen_llong_to_C_llong(val)); return(val);} \ func = s7_method(s7, gen, s7_make_symbol(s7, Caller)); \ if ((func != Xen_undefined) && (s7_procedure_setter(s7, func))) \ return(s7_apply_function(s7, s7_procedure_setter(s7, func), s7_list(s7, 2, gen, val))); \ Xen_check_type(false, gen, 1, Caller, "a generator"); \ return(val); #define mus_int_generic(Caller, CLM_case) \ mus_xen *gn; \ s7_pointer func; \ gn = (mus_xen *)Xen_object_ref_checked(gen, mus_xen_tag); \ if (gn) return(C_int_to_Xen_integer(CLM_case(gn->gen))); \ func = s7_method(s7, gen, s7_make_symbol(s7, Caller)); \ if (func != Xen_undefined) return(s7_apply_function(s7, func, s7_list(s7, 1, gen))); \ Xen_check_type(false, gen, 1, Caller, "a generator"); \ return(gen); #else #define mus_double_generic(Caller, CLM_case, Symbol) \ mus_xen *gn; \ gn = (mus_xen *)Xen_object_ref_checked(gen, mus_xen_tag); \ if (!gn) Xen_check_type(false, gen, 1, Caller, "a generator"); \ return(C_double_to_Xen_real(CLM_case(gn->gen))); #define mus_set_double_generic(Caller, CLM_case) \ mus_xen *gn; \ gn = (mus_xen *)Xen_object_ref_checked(gen, mus_xen_tag); \ if (!gn) Xen_check_type(false, gen, 1, S_set Caller, "a generator"); \ Xen_check_type(Xen_is_double(val), val, 2, S_set Caller, "a float"); \ CLM_case(gn->gen, Xen_real_to_C_double(val)); \ return(val); #define mus_long_long_generic(Caller, CLM_case) \ mus_xen *gn; \ gn = (mus_xen *)Xen_object_ref_checked(gen, mus_xen_tag); \ if (!gn) Xen_check_type(false, gen, 1, Caller, "a generator"); \ return(C_llong_to_Xen_llong(CLM_case(gn->gen))); #define mus_set_long_long_generic(Caller, CLM_case) \ mus_xen *gn; \ gn = (mus_xen *)Xen_object_ref_checked(gen, mus_xen_tag); \ if (!gn) Xen_check_type(false, gen, 1, S_set Caller, "a generator"); \ Xen_check_type(Xen_is_integer(val), val, 2, S_set Caller, "an integer"); \ CLM_case(gn->gen, Xen_llong_to_C_llong(val)); \ return(val); #define mus_int_generic(Caller, CLM_case) \ mus_xen *gn; \ gn = (mus_xen *)Xen_object_ref_checked(gen, mus_xen_tag); \ if (!gn) Xen_check_type(false, gen, 1, Caller, "a generator"); \ return(C_int_to_Xen_integer(CLM_case(gn->gen))); #endif #if HAVE_SCHEME static Xen sym_frequency, sym_phase, sym_scaler, sym_increment, sym_width, sym_offset, sym_feedforward, sym_feedback; #endif static Xen g_mus_frequency(Xen gen) { #define H_mus_frequency "(" S_mus_frequency " gen): gen's frequency (Hz)" mus_double_generic(S_mus_frequency, mus_frequency, sym_frequency); } static Xen g_mus_set_frequency(Xen gen, Xen val) { mus_set_double_generic(S_mus_frequency, mus_set_frequency); } static Xen g_mus_phase(Xen gen) { #define H_mus_phase "(" S_mus_phase " gen): gen's current phase (radians)" mus_double_generic(S_mus_phase, mus_phase, sym_phase); } static Xen g_mus_set_phase(Xen gen, Xen val) { mus_set_double_generic(S_mus_phase, mus_set_phase); } static Xen g_mus_scaler(Xen gen) { #define H_mus_scaler "(" S_mus_scaler " gen): gen's scaler, if any. This is often an amplitude adjustment of some sort." mus_double_generic(S_mus_scaler, mus_scaler, sym_scaler); } static Xen g_mus_set_scaler(Xen gen, Xen val) { mus_set_double_generic(S_mus_scaler, mus_set_scaler); } static Xen g_mus_feedforward(Xen gen) { #define H_mus_feedforward "(" S_mus_feedforward " gen): gen's feedforward field" mus_double_generic(S_mus_feedforward, mus_scaler, sym_feedforward); } static Xen g_mus_set_feedforward(Xen gen, Xen val) { mus_set_double_generic(S_mus_feedforward, mus_set_scaler); } static Xen g_mus_feedback(Xen gen) { #define H_mus_feedback "(" S_mus_feedback " gen): gen's " S_mus_feedback " field" mus_double_generic(S_mus_feedback, mus_increment, sym_feedback); } static Xen g_mus_set_feedback(Xen gen, Xen val) { mus_set_double_generic(S_mus_feedback, mus_set_increment); } static Xen g_mus_width(Xen gen) { #define H_mus_width "(" S_mus_width " gen): gen's width, if any. This is usually a table size." mus_double_generic(S_mus_width, mus_width, sym_width); } static Xen g_mus_set_width(Xen gen, Xen val) { mus_set_double_generic(S_mus_width, mus_set_width); } static Xen g_mus_offset(Xen gen) { #define H_mus_offset "(" S_mus_offset " gen): gen's offset, if any" mus_double_generic(S_mus_offset, mus_offset, sym_offset); } static Xen g_mus_set_offset(Xen gen, Xen val) { mus_set_double_generic(S_mus_offset, mus_set_offset); } static Xen g_mus_increment(Xen gen) { #define H_mus_increment "(" S_mus_increment " gen): gen's " S_mus_increment " field, if any" mus_double_generic(S_mus_increment, mus_increment, sym_increment); } static Xen g_mus_set_increment(Xen gen, Xen val) { mus_set_double_generic(S_mus_increment, mus_set_increment); } static Xen g_mus_hop(Xen gen) { #define H_mus_hop "(" S_mus_hop " gen): gen's " S_mus_hop " field" mus_long_long_generic(S_mus_hop, mus_hop); } static Xen g_mus_set_hop(Xen gen, Xen val) { mus_set_long_long_generic(S_mus_hop, mus_set_hop); } static Xen g_mus_ramp(Xen gen) { #define H_mus_ramp "(" S_mus_ramp " gen): granulate generator's " S_mus_ramp " field" mus_long_long_generic(S_mus_ramp, mus_ramp); } static Xen g_mus_set_ramp(Xen gen, Xen val) { mus_set_long_long_generic(S_mus_ramp, mus_set_ramp); } static Xen g_mus_location(Xen gen) { #define H_mus_location "(" S_mus_location " gen): gen's " S_mus_location " field, if any" mus_long_long_generic(S_mus_location, mus_location); } static Xen g_mus_set_location(Xen gen, Xen val) { mus_set_long_long_generic(S_mus_location, mus_set_location); } static Xen g_mus_order(Xen gen) { #define H_mus_order "(" S_mus_order " gen): gen's order, if any" mus_long_long_generic(S_mus_order, mus_length); } static Xen g_mus_channel(Xen gen) { #define H_mus_channel "(" S_mus_channel " gen): gen's " S_mus_channel " field, if any" mus_int_generic(S_mus_channel, mus_channel); } static Xen g_mus_interp_type(Xen gen) { #define H_mus_interp_type "(" S_mus_interp_type " gen): gen's " S_mus_interp_type " field, if any" mus_int_generic(S_mus_interp_type, mus_channels); } static Xen g_mus_type(Xen gen) { #define H_mus_type "(" S_mus_type " gen): gen's type" mus_int_generic(S_mus_type, mus_type); } static Xen g_mus_name(Xen gen) { #define H_mus_name "(" S_mus_name " gen): gen's (type) name, if any" mus_xen *ms; ms = (mus_xen *)Xen_object_ref_checked(gen, mus_xen_tag); if (ms) return(C_string_to_Xen_string(mus_name(mus_xen_to_mus_any(ms)))); #if HAVE_SCHEME { s7_pointer func; func = s7_method(s7, gen, s7_make_symbol(s7, "mus-name")); if (func != Xen_undefined) return(s7_apply_function(s7, func, s7_list(s7, 1, gen))); } #endif Xen_check_type(false, gen, 1, S_mus_name, "a generator"); return(gen); } Xen g_mus_file_name(Xen gen) { #define H_mus_file_name "(" S_mus_file_name " gen): file associated with gen, if any" mus_xen *gn; gn = (mus_xen *)Xen_object_ref_checked(gen, mus_xen_tag); if (gn) return(C_string_to_Xen_string(mus_file_name(gn->gen))); #if HAVE_SCHEME { s7_pointer func; func = s7_method(s7, gen, s7_make_symbol(s7, S_mus_file_name)); if (func != Xen_undefined) return(s7_apply_function(s7, func, s7_list(s7, 1, gen))); } #endif Xen_check_type(false, gen, 1, S_mus_file_name, "a generator"); return(gen); } Xen g_mus_data(Xen gen) { #define H_mus_data "(" S_mus_data " gen): gen's internal data (a " S_vct "), if any" mus_xen *ms; ms = (mus_xen *)Xen_object_ref_checked(gen, mus_xen_tag); if (ms) { if (ms->vcts) return(ms->vcts[MUS_DATA_WRAPPER]); else return(Xen_false); } #if HAVE_SCHEME { s7_pointer func; func = s7_method(s7, gen, s7_make_symbol(s7, S_mus_data)); if (func != Xen_undefined) return(s7_apply_function(s7, func, s7_list(s7, 1, gen))); } #endif Xen_check_type(false, gen, 1, S_mus_data, "a generator"); return(gen); } static Xen g_mus_set_data(Xen gen, Xen val) { mus_xen *ms; ms = (mus_xen *)Xen_object_ref_checked(gen, mus_xen_tag); if (ms) { Xen_check_type((mus_is_vct(val)), val, 2, S_set S_mus_data, "a " S_vct); if (ms->vcts) { vct *v; mus_any *ma; v = Xen_to_vct(val); ma = ms->gen; mus_set_data(ma, mus_vct_data(v)); /* TO REMEMBER: if allocated, should have freed, and set to not allocated */ ms->vcts[MUS_DATA_WRAPPER] = val; return(val); } } #if HAVE_SCHEME { s7_pointer func; func = s7_method(s7, gen, s7_make_symbol(s7, "mus-data")); if ((func != Xen_undefined) && (s7_procedure_setter(s7, func))) return(s7_apply_function(s7, s7_procedure_setter(s7, func), s7_list(s7, 2, gen, val))); } #endif Xen_check_type(false, gen, 1, S_set S_mus_data, "a generator with a data field"); return(Xen_false); } static Xen c_xcoeffs(mus_xen *ms) { mus_any *g; g = ms->gen; if (ms->vcts) { if (mus_is_polywave(g)) return(ms->vcts[0]); if (ms->nvcts > G_FILTER_XCOEFFS) return(ms->vcts[G_FILTER_XCOEFFS]); } if ((mus_is_one_zero(g)) || (mus_is_one_pole(g)) || (mus_is_two_zero(g)) || (mus_is_two_pole(g))) return(xen_make_vct_wrapper(3, mus_xcoeffs(g))); return(Xen_false); } static Xen g_mus_xcoeffs(Xen gen) { #define H_mus_xcoeffs "(" S_mus_xcoeffs " gen): gen's filter xcoeffs (" S_vct " of coefficients on inputs)" mus_xen *ms; ms = (mus_xen *)Xen_object_ref_checked(gen, mus_xen_tag); if (ms) return(c_xcoeffs(ms)); #if HAVE_SCHEME { s7_pointer func; func = s7_method(s7, gen, s7_make_symbol(s7, "mus-xcoeffs")); if (func != Xen_undefined) return(s7_apply_function(s7, func, s7_list(s7, 1, gen))); } #endif Xen_check_type(false, gen, 1, S_mus_xcoeffs, "a generator"); return(gen); } static Xen g_mus_ycoeffs(Xen gen) { #define H_mus_ycoeffs "(" S_mus_ycoeffs " gen): gen's filter ycoeffs (" S_vct " of coefficients on outputs)" mus_xen *ms; ms = (mus_xen *)Xen_object_ref_checked(gen, mus_xen_tag); if (ms) { mus_any *g; g = ms->gen; if (ms->vcts) { if ((mus_is_polywave(Xen_to_mus_any(gen))) && (ms->nvcts == 2)) return(ms->vcts[1]); if (ms->nvcts > G_FILTER_YCOEFFS) return(ms->vcts[G_FILTER_YCOEFFS]); } if ((mus_is_one_zero(g)) || (mus_is_one_pole(g)) || (mus_is_two_zero(g)) || (mus_is_two_pole(g))) return(xen_make_vct_wrapper(3, mus_ycoeffs(g))); return(Xen_false); } #if HAVE_SCHEME { s7_pointer func; func = s7_method(s7, gen, s7_make_symbol(s7, "mus-ycoeffs")); if (func != Xen_undefined) return(s7_apply_function(s7, func, s7_list(s7, 1, gen))); } #endif Xen_check_type(false, gen, 1, S_mus_ycoeffs, "a generator"); return(gen); } static Xen g_mus_xcoeff(Xen gen, Xen index) { #define H_mus_xcoeff "(" S_mus_xcoeff " gen index): gen's filter xcoeff value at index (0-based)" mus_xen *ms; ms = (mus_xen *)Xen_object_ref_checked(gen, mus_xen_tag); if (ms) { int ind = 0; Xen_to_C_integer_or_error(index, ind, S_mus_xcoeff, 2); if (ind < 0) Xen_out_of_range_error(S_mus_xcoeff, 2, index, "index must be non-negative"); return(C_double_to_Xen_real(mus_xcoeff(mus_xen_to_mus_any(ms), ind))); } #if HAVE_SCHEME { s7_pointer func; func = s7_method(s7, gen, s7_make_symbol(s7, "mus-xcoeff")); if (func != Xen_undefined) return(s7_apply_function(s7, func, s7_list(s7, 2, gen, index))); } #endif Xen_check_type(false, gen, 1, S_mus_xcoeff, "a generator"); return(index); } static Xen g_mus_set_xcoeff(Xen gen, Xen index, Xen val) { mus_xen *ms; ms = (mus_xen *)Xen_object_ref_checked(gen, mus_xen_tag); if (ms) { int ind = 0; mus_float_t x; Xen_to_C_integer_or_error(index, ind, S_set S_mus_xcoeff, 2); Xen_to_C_double_or_error(val, x, S_set S_mus_xcoeff, 3); if (ind < 0) Xen_out_of_range_error(S_set S_mus_xcoeff, 2, index, "index must be non-negative"); mus_set_xcoeff(mus_xen_to_mus_any(ms), ind, x); return(val); } #if HAVE_SCHEME { s7_pointer func; func = s7_method(s7, gen, s7_make_symbol(s7, "mus-xcoeff")); if ((func != Xen_undefined) && (s7_procedure_setter(s7, func))) return(s7_apply_function(s7, s7_procedure_setter(s7, func), s7_list(s7, 3, gen, index, val))); } #endif Xen_check_type(false, gen, 1, S_set S_mus_xcoeff, "a generator"); return(val); } static Xen g_mus_ycoeff(Xen gen, Xen index) { #define H_mus_ycoeff "(" S_mus_ycoeff " gen index): gen's filter ycoeff value at index (0-based)" mus_xen *ms; ms = (mus_xen *)Xen_object_ref_checked(gen, mus_xen_tag); if (ms) { int ind = 0; Xen_to_C_integer_or_error(index, ind, S_mus_ycoeff, 2); if (ind < 0) Xen_out_of_range_error(S_mus_ycoeff, 2, index, "index must be non-negative"); return(C_double_to_Xen_real(mus_ycoeff(mus_xen_to_mus_any(ms), ind))); } #if HAVE_SCHEME { s7_pointer func; func = s7_method(s7, gen, s7_make_symbol(s7, "mus-ycoeff")); if (func != Xen_undefined) return(s7_apply_function(s7, func, s7_list(s7, 2, gen, index))); } #endif Xen_check_type(false, gen, 1, S_mus_ycoeff, "a generator"); return(index); } static Xen g_mus_set_ycoeff(Xen gen, Xen index, Xen val) { mus_xen *ms; ms = (mus_xen *)Xen_object_ref_checked(gen, mus_xen_tag); if (ms) { int ind = 0; mus_float_t x; Xen_to_C_integer_or_error(index, ind, S_set S_mus_ycoeff, 2); Xen_to_C_double_or_error(val, x, S_set S_mus_ycoeff, 3); if (ind < 0) Xen_out_of_range_error(S_set S_mus_ycoeff, 2, index, "index must be non-negative"); mus_set_ycoeff(mus_xen_to_mus_any(ms), ind, x); return(val); } #if HAVE_SCHEME { s7_pointer func; func = s7_method(s7, gen, s7_make_symbol(s7, "mus-ycoeff")); if ((func != Xen_undefined) && (s7_procedure_setter(s7, func))) return(s7_apply_function(s7, s7_procedure_setter(s7, func), s7_list(s7, 3, gen, index, val))); } #endif Xen_check_type(false, gen, 1, S_set S_mus_ycoeff, "a generator"); return(val); } Xen g_mus_channels(Xen gen) { #define H_mus_channels "(" S_mus_channels " gen): gen's " S_mus_channels " field, if any" mus_xen *gn; gn = (mus_xen *)Xen_object_ref_checked(gen, mus_xen_tag); if (gn) return(C_int_to_Xen_integer(mus_channels(gn->gen))); #if HAVE_SCHEME if (mus_is_vct(gen)) { if (Xen_vector_rank(gen) > 1) return(C_int_to_Xen_integer(s7_vector_dimensions(gen)[0])); else return(C_int_to_Xen_integer(1)); } #else if (mus_is_vct(gen)) return(C_int_to_Xen_integer(1)); #endif #if HAVE_SCHEME { s7_pointer func; func = s7_method(s7, gen, s7_make_symbol(s7, "mus-channels")); if (func != Xen_undefined) return(s7_apply_function(s7, func, s7_list(s7, 1, gen))); } #endif Xen_check_type(false, gen, 1, S_mus_channels, "an output generator, " S_vct ", or sound-data object"); return(Xen_false); /* make compiler happy */ } Xen g_mus_length(Xen gen) { #define H_mus_length "(" S_mus_length " gen): gen's length, if any" mus_xen *gn; gn = (mus_xen *)Xen_object_ref_checked(gen, mus_xen_tag); if (gn) return(C_llong_to_Xen_llong(mus_length(gn->gen))); if (mus_is_vct(gen)) return(C_int_to_Xen_integer(mus_vct_length(Xen_to_vct(gen)))); #if HAVE_SCHEME { s7_pointer func; func = s7_method(s7, gen, s7_make_symbol(s7, "mus-length")); if (func != Xen_undefined) return(s7_apply_function(s7, func, s7_list(s7, 1, gen))); } #endif Xen_check_type(false, gen, 1, S_mus_length, "a generator, " S_vct ", or sound-data object"); return(Xen_false); /* make compiler happy */ } static Xen g_mus_set_length(Xen gen, Xen val) { mus_xen *ms; ms = (mus_xen *)Xen_object_ref_checked(gen, mus_xen_tag); if (ms) { mus_long_t len = 0; mus_any *ptr = NULL; Xen_to_C_integer_or_error(val, len, S_set S_mus_length, 2); if (len <= 0) Xen_out_of_range_error(S_set S_mus_length, 1, val, "must be > 0"); ptr = ms->gen; if ((!mus_is_env(ptr)) && (!mus_is_src(ptr))) /* set length doesn't refer to data vct here */ { if ((ms->vcts) && (!(Xen_is_eq(ms->vcts[MUS_DATA_WRAPPER], Xen_undefined)))) { vct *v; v = Xen_to_vct(ms->vcts[MUS_DATA_WRAPPER]); if ((v) && (len > mus_vct_length(v))) Xen_out_of_range_error(S_set S_mus_length, 1, val, "must be <= current data size"); /* set_offset refers only to env, set_width only to square_wave et al, set_location only readin */ /* filters are protected by keeping allocated_size and not allowing arrays to be set */ } } mus_set_length(ptr, len); return(val); } #if HAVE_SCHEME { s7_pointer func; func = s7_method(s7, gen, s7_make_symbol(s7, "mus-length")); if ((func != Xen_undefined) && (s7_procedure_setter(s7, func))) return(s7_apply_function(s7, s7_procedure_setter(s7, func), s7_list(s7, 2, gen, val))); } #endif Xen_check_type(false, gen, 1, S_set S_mus_length, "a generator"); return(val); } /* ---------------- oscil ---------------- */ static Xen g_make_oscil(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_make_oscil "(" S_make_oscil " (frequency *clm-default-frequency*) (initial-phase 0.0)): return a new " S_oscil " (sinewave) generator" mus_any *ge; mus_float_t freq, phase = 0.0; freq = clm_default_frequency; if (Xen_is_bound(arg1)) { if (!Xen_is_bound(arg2)) { Xen_check_type(Xen_is_number(arg1), arg1, 1, S_make_oscil, "a number"); freq = Xen_real_to_C_double(arg1); if (freq > (0.5 * mus_srate())) Xen_out_of_range_error(S_make_oscil, 1, arg1, "freq > srate/2?"); } else { int vals; Xen args[4]; Xen keys[2]; int orig_arg[2] = {0, 0}; keys[0] = kw_frequency; keys[1] = kw_initial_phase; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; vals = mus_optkey_unscramble(S_make_oscil, 2, keys, args, orig_arg); if (vals > 0) { freq = Xen_optkey_to_float(kw_frequency, keys[0], S_make_oscil, orig_arg[0], freq); if (freq > (0.5 * mus_srate())) Xen_out_of_range_error(S_make_oscil, orig_arg[0], keys[0], "freq > srate/2?"); phase = Xen_optkey_to_float(kw_initial_phase, keys[1], S_make_oscil, orig_arg[1], phase); } } } ge = mus_make_oscil(freq, phase); if (ge) return(mus_xen_to_object(mus_any_to_mus_xen(ge))); return(Xen_false); } static Xen g_oscil(Xen osc, Xen fm, Xen pm) { #define H_oscil "(" S_oscil " gen (fm 0.0) (pm 0.0)): next sample from " S_oscil " gen: val = sin(phase + pm); phase += (freq + fm)" #define Q_oscil s7_make_circular_signature(s7, 2, 3, s7_make_symbol(s7, "float?"), s7_make_symbol(s7, "oscil?"), s7_make_symbol(s7, "real?")) mus_float_t fm1; mus_any *g = NULL; mus_xen *gn; Xen_to_C_generator(osc, gn, g, mus_is_oscil, S_oscil, "an oscil"); if (!Xen_is_bound(fm)) return(C_double_to_Xen_real(mus_oscil_unmodulated(g))); if (!Xen_is_bound(pm)) return(C_double_to_Xen_real(mus_oscil_fm(g, Xen_real_to_C_double(fm)))); fm1 = Xen_real_to_C_double(fm); if (fm1 == 0.0) return(C_double_to_Xen_real(mus_oscil_pm(g, Xen_real_to_C_double(pm)))); return(C_double_to_Xen_real(mus_oscil(g, fm1, Xen_real_to_C_double(pm)))); } static Xen g_is_oscil(Xen os) { #define H_is_oscil "(" S_is_oscil " gen): " PROC_TRUE " if gen is an " S_oscil return(C_bool_to_Xen_boolean((mus_is_xen(os)) && (mus_is_oscil(Xen_to_mus_any(os))))); } static Xen g_make_oscil_bank(Xen freqs, Xen phases, Xen amps, XEN stable) { #define H_make_oscil_bank "(" S_make_oscil_bank " freqs phases amps stable): return a new oscil-bank generator. (freqs in radians)" mus_any *ge = NULL; vct *f, *p, *a = NULL; mus_xen *gn; Xen_check_type(mus_is_vct(freqs), freqs, 1, S_make_oscil_bank, "a " S_vct); Xen_check_type(mus_is_vct(phases), phases, 2, S_make_oscil_bank, "a " S_vct); Xen_check_type(Xen_is_boolean_or_unbound(stable), stable, 3, S_make_oscil_bank, "a boolean"); f = Xen_to_vct(freqs); p = Xen_to_vct(phases); if (mus_is_vct(amps)) a = Xen_to_vct(amps); ge = mus_make_oscil_bank(mus_vct_length(f), mus_vct_data(f), mus_vct_data(p), (a) ? mus_vct_data(a) : NULL, Xen_is_true(stable)); /* Xen_is_true looks specifically for #t */ gn = mx_alloc(3); gn->gen = ge; gn->vcts[0] = freqs; gn->vcts[1] = phases; gn->vcts[2] = amps; return(mus_xen_to_object(gn)); } static Xen g_is_oscil_bank(Xen os) { #define H_is_oscil_bank "(" S_is_oscil_bank " gen): " PROC_TRUE " if gen is an " S_oscil_bank return(C_bool_to_Xen_boolean((mus_is_xen(os)) && (mus_is_oscil_bank(Xen_to_mus_any(os))))); } static Xen g_oscil_bank(Xen g) { #define H_oscil_bank "(" S_oscil_bank " bank): sum an array of oscils" mus_any *ob = NULL; mus_xen *gn; Xen_to_C_generator(g, gn, ob, mus_is_oscil_bank, S_oscil_bank, "an oscil-bank generator"); return(C_double_to_Xen_real(mus_oscil_bank(ob))); } /* ---------------- delay ---------------- */ typedef enum {G_DELAY, G_COMB, G_NOTCH, G_ALL_PASS, G_FCOMB} xclm_delay_t; static Xen g_make_delay_1(xclm_delay_t choice, Xen arglist) { mus_any *ge = NULL, *filt = NULL; const char *caller = NULL; Xen args[18]; Xen keys[9]; Xen xen_filt = Xen_false; int orig_arg[9] = {0, 0, 0, 0, 0, 0, 0, (int)MUS_INTERP_NONE, 0}; int vals, i, argn = 0; mus_long_t max_size = -1, size = -1; int interp_type = (int)MUS_INTERP_NONE; mus_float_t *line = NULL; mus_float_t scaler = 0.0, feedback = 0.0, feedforward = 0.0; vct *initial_contents = NULL; Xen orig_v = Xen_false; /* initial-contents can be a vct */ mus_float_t initial_element = 0.0; int scaler_key = -1, feedback_key = -1, feedforward_key = -1, size_key = -1, initial_contents_key = -1; int initial_element_key = -1, max_size_key = -1, interp_type_key = -1, filter_key = -1; switch (choice) { case G_DELAY: caller = S_make_delay; break; case G_COMB: caller = S_make_comb; scaler_key = argn; keys[argn++] = kw_scaler; break; case G_FCOMB: caller = S_make_filtered_comb; scaler_key = argn; keys[argn++] = kw_scaler; break; case G_NOTCH: caller = S_make_notch; scaler_key = argn; keys[argn++] = kw_scaler; break; case G_ALL_PASS: caller = S_make_all_pass; feedback_key = argn; keys[argn++] = kw_feedback; feedforward_key = argn; keys[argn++] = kw_feedforward; break; } size_key = argn; keys[argn++] = kw_size; initial_contents_key = argn; keys[argn++] = kw_initial_contents; initial_element_key = argn; keys[argn++] = kw_initial_element; max_size_key = argn; keys[argn++] = kw_max_size; interp_type_key = argn; keys[argn++] = kw_type; filter_key = argn; keys[argn++] = kw_filter; { Xen p; int a2, arglist_len; a2 = argn * 2; arglist_len = Xen_list_length(arglist); if (arglist_len > a2) clm_error(caller, "too many arguments!", arglist); for (i = 0, p = arglist; i < arglist_len; i++, p = Xen_cdr(p)) args[i] = Xen_car(p); for (i = arglist_len; i < a2; i++) args[i] = Xen_undefined; } vals = mus_optkey_unscramble(caller, argn, keys, args, orig_arg); if (vals > 0) { bool size_set = false, max_size_set = false; /* try to catch obvious type/range errors before allocations * a major complication here is that size can be 0 */ if (!(Xen_is_keyword(keys[size_key]))) { size = Xen_optkey_to_mus_long_t(kw_size, keys[size_key], caller, orig_arg[size_key], size); /* size can be 0? -- surely we need a line in any case? */ if (size < 0) Xen_out_of_range_error(caller, orig_arg[size_key], keys[size_key], "size < 0?"); if (size > mus_max_table_size()) Xen_out_of_range_error(caller, orig_arg[size_key], keys[size_key], "size too large (see mus-max-table-size)"); size_set = true; } if (!(Xen_is_keyword(keys[max_size_key]))) { max_size = Xen_optkey_to_mus_long_t(kw_max_size, keys[max_size_key], caller, orig_arg[max_size_key], max_size); /* -1 = unset */ if (max_size <= 0) Xen_out_of_range_error(caller, orig_arg[max_size_key], keys[max_size_key], "max-size <= 0?"); if (max_size > mus_max_table_size()) Xen_out_of_range_error(caller, orig_arg[max_size_key], keys[max_size_key], "max-size too large (see mus-max-table-size)"); max_size_set = true; } if (Xen_is_keyword(keys[interp_type_key])) { /* if type not given, if max_size, assume linear interp (for possible tap), else no interp */ if ((max_size_set) && (max_size != size)) interp_type = (int)MUS_INTERP_LINEAR; else interp_type = (int)MUS_INTERP_NONE; } else { interp_type = Xen_optkey_to_int(kw_type, keys[interp_type_key], caller, orig_arg[interp_type_key], (int)MUS_INTERP_LINEAR); if (!(mus_is_interp_type(interp_type))) Xen_out_of_range_error(caller, orig_arg[interp_type_key], keys[interp_type_key], "no such interp-type"); } initial_element = Xen_optkey_to_float(kw_initial_element, keys[initial_element_key], caller, orig_arg[initial_element_key], initial_element); switch (choice) { case G_DELAY: break; case G_COMB: case G_NOTCH: case G_FCOMB: scaler = Xen_optkey_to_float(kw_scaler, keys[scaler_key], caller, orig_arg[scaler_key], scaler); break; case G_ALL_PASS: feedback = Xen_optkey_to_float(kw_feedback, keys[feedback_key], caller, orig_arg[feedback_key], feedback); feedforward = Xen_optkey_to_float(kw_feedforward, keys[feedforward_key], caller, orig_arg[feedforward_key], feedforward); break; } if (!(Xen_is_keyword(keys[filter_key]))) { if (choice != G_FCOMB) clm_error(caller, "filter arg passed??", keys[filter_key]); Xen_check_type(mus_is_xen(keys[filter_key]), keys[filter_key], orig_arg[filter_key], caller, "filter arg must be a generator"); xen_filt = keys[filter_key]; filt = Xen_to_mus_any(xen_filt); } if (!(Xen_is_keyword(keys[initial_contents_key]))) { if (!(Xen_is_keyword(keys[initial_element_key]))) Xen_out_of_range_error(caller, orig_arg[initial_contents_key], keys[initial_contents_key], "initial-contents and initial-element in same call?"); if (mus_is_vct(keys[initial_contents_key])) { initial_contents = Xen_to_vct(keys[initial_contents_key]); orig_v = keys[initial_contents_key]; } else { if (Xen_is_list(keys[initial_contents_key])) { int len; len = Xen_list_length(keys[initial_contents_key]); if (len <= 0) Xen_error(NO_DATA, Xen_list_2(C_string_to_Xen_string("~A: initial-contents not a proper list?"), C_string_to_Xen_string(caller))); orig_v = xen_list_to_vct(keys[initial_contents_key]); initial_contents = Xen_to_vct(orig_v); /* do I need to protect this until we read its contents? -- no extlang stuff except error returns */ } else Xen_check_type(Xen_is_false(keys[initial_contents_key]), keys[initial_contents_key], orig_arg[initial_contents_key], caller, "a " S_vct " or a list"); } if (initial_contents) { if (size_set) { if (size > mus_vct_length(initial_contents)) Xen_out_of_range_error(caller, orig_arg[initial_contents_key], keys[initial_contents_key], "size > initial-contents length"); } else size = mus_vct_length(initial_contents); if (max_size_set) { if (max_size > mus_vct_length(initial_contents)) Xen_out_of_range_error(caller, orig_arg[initial_contents_key], keys[initial_contents_key], "max-size > initial-contents length"); } else max_size = mus_vct_length(initial_contents); } } } /* here size can be (user-set to) 0, but max_size needs to be a reasonable allocation size */ if (size < 0) size = 1; if (max_size < size) { if (size == 0) max_size = 1; else max_size = size; } if (initial_contents == NULL) { line = (mus_float_t *)malloc(max_size * sizeof(mus_float_t)); if (line == NULL) return(clm_mus_error(MUS_MEMORY_ALLOCATION_FAILED, "can't allocate delay line", caller)); orig_v = xen_make_vct(max_size, line); if (initial_element != 0.0) { for (i = 0; i < max_size; i++) line[i] = initial_element; } else memset((void *)line, 0, max_size * sizeof(mus_float_t)); } else { line = mus_vct_data(initial_contents); } { mus_error_handler_t *old_error_handler; old_error_handler = mus_error_set_handler(local_mus_error); switch (choice) { case G_DELAY: ge = mus_make_delay(size, line, max_size, (mus_interp_t)interp_type); break; case G_COMB: ge = mus_make_comb(scaler, size, line, max_size, (mus_interp_t)interp_type); break; case G_NOTCH: ge = mus_make_notch(scaler, size, line, max_size, (mus_interp_t)interp_type); break; case G_ALL_PASS: ge = mus_make_all_pass(feedback, feedforward, size, line, max_size, (mus_interp_t)interp_type); break; case G_FCOMB: ge = mus_make_filtered_comb(scaler, size, line, max_size, (mus_interp_t)interp_type, filt); break; } mus_error_set_handler(old_error_handler); } if (ge) { if (choice != G_FCOMB) return(mus_xen_to_object(mus_any_to_mus_xen_with_vct(ge, orig_v))); return(mus_xen_to_object(mus_any_to_mus_xen_with_two_vcts(ge, orig_v, xen_filt))); } return(clm_mus_error(local_error_type, local_error_msg, caller)); } static Xen g_make_delay(Xen args) { #define H_make_delay "(" S_make_delay " (size) (initial-contents) (initial-element 0.0) (max-size) (type mus-interp-linear)): \ return a new delay line of size elements. \ If the delay length will be changing at run-time, max-size sets its maximum length, so\n\ (" S_make_delay " len :max-size (+ len 10))\n\ provides 10 extra elements of delay for subsequent phasing or flanging. \ initial-contents can be either a list or a " S_vct "." if ((Xen_is_pair(args)) && (!Xen_is_pair(Xen_cdr(args)))) { Xen val, v; mus_any *ge; mus_long_t size, max_size; mus_float_t *line; mus_error_handler_t *old_error_handler; val = Xen_car(args); Xen_check_type(Xen_is_integer(val), val, 1, S_make_delay, "an integer"); size = Xen_integer_to_C_int(val); if (size < 0) Xen_out_of_range_error(S_make_delay, 1, val, "size < 0?"); if (size > mus_max_table_size()) Xen_out_of_range_error(S_make_delay, 1, val, "size too large (see mus-max-table-size)"); if (size == 0) max_size = 1; else max_size = size; line = (mus_float_t *)calloc(max_size, sizeof(mus_float_t)); v = xen_make_vct(max_size, line); /* we need this for mus-data */ old_error_handler = mus_error_set_handler(local_mus_error); ge = mus_make_delay(size, line, max_size, MUS_INTERP_NONE); mus_error_set_handler(old_error_handler); if (ge) return(mus_xen_to_object(mus_any_to_mus_xen_with_vct(ge, v))); return(clm_mus_error(local_error_type, local_error_msg, S_make_delay)); } return(g_make_delay_1(G_DELAY, args)); } static Xen g_make_comb(Xen args) { #define H_make_comb "(" S_make_comb " (scaler) (size) (initial-contents) (initial-element 0.0) (max-size) (type " S_mus_interp_linear ")): \ return a new comb filter (a delay line with a scaler on the feedback) of size elements. \ If the comb length will be changing at run-time, max-size sets its maximum length. \ initial-contents can be either a list or a " S_vct "." return(g_make_delay_1(G_COMB, args)); } static Xen g_make_filtered_comb(Xen args) { #define H_make_filtered_comb "(" S_make_filtered_comb " (scaler) (size) (initial-contents) (initial-element 0.0) (max-size) (type " S_mus_interp_linear ") :filter): \ return a new filtered comb filter (a delay line with a scaler and a filter on the feedback) of size elements. \ If the comb length will be changing at run-time, max-size sets its maximum length. \ initial-contents can be either a list or a " S_vct "." return(g_make_delay_1(G_FCOMB, args)); } static Xen g_make_notch(Xen args) { #define H_make_notch "(" S_make_notch " (scaler) (size) (initial-contents) (initial-element 0.0) (max-size) (type " S_mus_interp_linear ")): \ return a new notch filter (a delay line with a scaler on the feedforward) of size elements. \ If the notch length will be changing at run-time, max-size sets its maximum length. \ initial-contents can be either a list or a " S_vct "." return(g_make_delay_1(G_NOTCH, args)); } static Xen g_make_all_pass(Xen args) { #define H_make_all_pass "(" S_make_all_pass " (feedback) (feedforward) (size) (initial-contents) (initial-element 0.0) (max-size) (type " S_mus_interp_linear ")): \ return a new allpass filter (a delay line with a scalers on both the feedback and the feedforward). \ If the " S_all_pass " length will be changing at run-time, max-size sets its maximum length. \ initial-contents can be either a list or a " S_vct "." return(g_make_delay_1(G_ALL_PASS, args)); } typedef enum {G_MOVING_AVERAGE, G_MOVING_MAX, G_MOVING_NORM} xclm_moving_t; static Xen g_make_moving_any(xclm_moving_t choice, const char *caller, Xen arglist) { mus_any *ge = NULL; Xen args[8]; Xen keys[4]; int orig_arg[4] = {0, 0, 0, 0}; int vals, i, argn = 0, arglist_len; mus_long_t size = -1; mus_float_t scaler = 1.0, sum = 0.0; vct *initial_contents = NULL; Xen orig_v = Xen_false, p; mus_float_t initial_element = 0.0; mus_float_t *line = NULL; int scaler_key = -1, size_key, initial_contents_key, initial_element_key; mus_error_handler_t *old_error_handler; size_key = argn; keys[argn++] = kw_size; if (choice == G_MOVING_NORM) { scaler_key = argn; keys[argn++] = kw_scaler; } initial_contents_key = argn; keys[argn++] = kw_initial_contents; initial_element_key = argn; keys[argn++] = kw_initial_element; arglist_len = Xen_list_length(arglist); if (arglist_len > 8) clm_error(caller, "too many arguments!", arglist); for (i = 0, p = arglist; i < arglist_len; i++, p = Xen_cdr(p)) args[i] = Xen_car(p); for (i = arglist_len; i < argn * 2; i++) args[i] = Xen_undefined; vals = mus_optkey_unscramble(caller, argn, keys, args, orig_arg); if (vals > 0) { bool size_set = false; if (!(Xen_is_keyword(keys[size_key]))) { size = Xen_optkey_to_mus_long_t(kw_size, keys[size_key], caller, orig_arg[size_key], size); /* size can be 0? -- surely we need a line in any case? */ if (size < 0) Xen_out_of_range_error(caller, orig_arg[size_key], keys[size_key], "size < 0?"); if (size > mus_max_table_size()) Xen_out_of_range_error(caller, orig_arg[size_key], keys[size_key], "size too large (see mus-max-table-size)"); size_set = true; } if (choice == G_MOVING_NORM) scaler = Xen_optkey_to_float(kw_scaler, keys[scaler_key], caller, orig_arg[scaler_key], scaler); initial_element = Xen_optkey_to_float(kw_initial_element, keys[initial_element_key], caller, orig_arg[initial_element_key], initial_element); if (!(Xen_is_keyword(keys[initial_contents_key]))) { if (!(Xen_is_keyword(keys[initial_element_key]))) Xen_out_of_range_error(caller, orig_arg[initial_contents_key], keys[initial_contents_key], "initial-contents and initial-element in same call?"); if (mus_is_vct(keys[initial_contents_key])) { initial_contents = Xen_to_vct(keys[initial_contents_key]); orig_v = keys[initial_contents_key]; } else { if (Xen_is_list(keys[initial_contents_key])) { int len; len = Xen_list_length(keys[initial_contents_key]); if (len <= 0) Xen_error(NO_DATA, Xen_list_2(C_string_to_Xen_string("~A: initial-contents not a proper list?"), C_string_to_Xen_string(caller))); orig_v = xen_list_to_vct(keys[initial_contents_key]); initial_contents = Xen_to_vct(orig_v); /* do I need to protect this until we read its contents? -- no extlang stuff except error returns */ } else Xen_check_type(Xen_is_false(keys[initial_contents_key]), keys[initial_contents_key], orig_arg[initial_contents_key], caller, "a " S_vct " or a list"); } if (initial_contents) { if (size_set) { if (size > mus_vct_length(initial_contents)) Xen_out_of_range_error(caller, orig_arg[initial_contents_key], keys[initial_contents_key], "size > initial-contents length"); } else size = mus_vct_length(initial_contents); } } } if (size < 0) size = 1; if (size == 0) Xen_out_of_range_error(caller, 0, C_llong_to_Xen_llong(size), "size = 0?"); if (initial_contents == NULL) { line = (mus_float_t *)malloc(size * sizeof(mus_float_t)); if (line == NULL) return(clm_mus_error(MUS_MEMORY_ALLOCATION_FAILED, "can't allocate delay line", caller)); orig_v = xen_make_vct(size, line); if (initial_element != 0.0) { for (i = 0; i < size; i++) line[i] = initial_element; sum = initial_element * size; } else memset((void *)line, 0, size * sizeof(mus_float_t)); } else { line = mus_vct_data(initial_contents); if ((line) && (choice == G_MOVING_AVERAGE)) { sum = line[0]; for (i = 1; i < size; i++) sum += line[i]; } } old_error_handler = mus_error_set_handler(local_mus_error); switch (choice) { case G_MOVING_AVERAGE: ge = mus_make_moving_average_with_initial_sum(size, line, sum); break; case G_MOVING_MAX: ge = mus_make_moving_max(size, line); break; case G_MOVING_NORM: ge = mus_make_moving_norm(size, line, scaler); break; } mus_error_set_handler(old_error_handler); if (ge) return(mus_xen_to_object(mus_any_to_mus_xen_with_vct(ge, orig_v))); return(clm_mus_error(local_error_type, local_error_msg, caller)); } static Xen g_make_moving_average(Xen args) { #define H_make_moving_average "(" S_make_moving_average " (size) (initial-contents) (initial-element 0.0)): \ return a new moving_average generator. initial-contents can be either a list or a " S_vct "." return(g_make_moving_any(G_MOVING_AVERAGE, S_make_moving_average, args)); } static Xen g_make_moving_max(Xen args) { #define H_make_moving_max "(" S_make_moving_max " (size) (initial-contents) (initial-element 0.0)): \ return a new moving-max generator. initial-contents can be either a list or a " S_vct "." return(g_make_moving_any(G_MOVING_MAX, S_make_moving_max, args)); } static Xen g_make_moving_norm(Xen args) { #define H_make_moving_norm "(" S_make_moving_norm " (size (scaler 1.0))): return a new moving-norm generator." return(g_make_moving_any(G_MOVING_NORM, S_make_moving_norm, args)); } static Xen g_delay(Xen obj, Xen input, Xen pm) { #define H_delay "(" S_delay " gen (val 0.0) (pm 0.0)): \ delay val according to the delay line's length and pm ('phase-modulation'). \ If pm is greater than 0.0, the max-size argument used to create gen should have accommodated its maximum value." mus_any *g = NULL; mus_xen *gn; Xen_to_C_generator(obj, gn, g, mus_is_delay, S_delay, "a delay line"); if (!Xen_is_bound(input)) return(C_double_to_Xen_real(mus_delay_unmodulated(g, 0.0))); if (!Xen_is_bound(pm)) return(C_double_to_Xen_real(mus_delay_unmodulated(g, Xen_real_to_C_double(input)))); return(C_double_to_Xen_real(mus_delay(g, Xen_real_to_C_double(input), Xen_real_to_C_double(pm)))); } static Xen g_delay_tick(Xen obj, Xen input) { #define H_delay_tick "(" S_delay_tick " gen (val 0.0)): \ delay val according to the delay line's length. This merely 'ticks' the delay line forward.\ The argument 'val' is returned." mus_float_t in1 = 0.0; mus_any *g = NULL; mus_xen *gn; Xen_to_C_generator(obj, gn, g, mus_is_delay, S_delay_tick, "a delay line"); Xen_real_to_C_double_if_bound(input, in1, S_delay_tick, 2); return(C_double_to_Xen_real(mus_delay_tick(g, in1))); } static Xen g_notch(Xen obj, Xen input, Xen pm) { #define H_notch "(" S_notch " gen (val 0.0) (pm 0.0)): notch filter val, pm changes the delay length." mus_float_t in1 = 0.0, pm1 = 0.0; mus_any *g = NULL; mus_xen *gn; Xen_to_C_generator(obj, gn, g, mus_is_notch, S_notch, "a notch filter"); Xen_real_to_C_double_if_bound(input, in1, S_notch, 2); Xen_real_to_C_double_if_bound(pm, pm1, S_notch, 3); return(C_double_to_Xen_real(mus_notch(g, in1, pm1))); } static Xen g_comb(Xen obj, Xen input, Xen pm) { #define H_comb "(" S_comb " gen (val 0.0) (pm 0.0)): comb filter val, pm changes the delay length." mus_float_t in1 = 0.0, pm1 = 0.0; mus_any *g = NULL; mus_xen *gn; Xen_to_C_generator(obj, gn, g, mus_is_comb, S_comb, "a comb generator"); Xen_real_to_C_double_if_bound(input, in1, S_comb, 2); Xen_real_to_C_double_if_bound(pm, pm1, S_comb, 3); return(C_double_to_Xen_real(mus_comb(g, in1, pm1))); } static Xen g_make_comb_bank(Xen arg) { #define H_make_comb_bank "(" S_make_comb_bank " gens): return a new comb-bank generator." mus_any *ge = NULL; mus_any **gens; int i, j, size; Xen_check_type(Xen_is_vector(arg), arg, 1, S_make_comb_bank, "a vector of comb generators"); size = Xen_vector_length(arg); if (size == 0) return(Xen_false); gens = (mus_any **)calloc(size, sizeof(mus_any *)); for (i = 0, j = 0; i < size; i++) { Xen g; g = Xen_vector_ref(arg, i); if (mus_is_xen(g)) { mus_any *fg; fg = Xen_to_mus_any(g); if (mus_is_comb(fg)) gens[j++] = fg; } } if (j > 0) ge = mus_make_comb_bank(j, gens); free(gens); if (ge) return(mus_xen_to_object(mus_any_to_mus_xen_with_vct(ge, arg))); return(Xen_false); } static Xen g_is_comb_bank(Xen os) { #define H_is_comb_bank "(" S_is_comb_bank " gen): " PROC_TRUE " if gen is a " S_comb_bank return(C_bool_to_Xen_boolean((mus_is_xen(os)) && (mus_is_comb_bank(Xen_to_mus_any(os))))); } static Xen g_comb_bank(Xen gens, Xen inp) { #define H_comb_bank "(" S_comb_bank " bank inval): sum an array of " S_comb " filters." mus_any *bank = NULL; mus_xen *gn; mus_float_t x = 0.0; Xen_to_C_generator(gens, gn, bank, mus_is_comb_bank, S_comb_bank, "a comb-bank generator"); Xen_real_to_C_double_if_bound(inp, x, S_comb_bank, 2); return(C_double_to_Xen_real(mus_comb_bank(bank, x))); } static Xen g_filtered_comb(Xen obj, Xen input, Xen pm) { #define H_filtered_comb "(" S_filtered_comb " gen (val 0.0) (pm 0.0)): filtered comb filter val, pm changes the delay length." mus_float_t in1 = 0.0, pm1 = 0.0; mus_any *g = NULL; mus_xen *gn; Xen_to_C_generator(obj, gn, g, mus_is_filtered_comb, S_filtered_comb, "a filtered-comb generator"); Xen_real_to_C_double_if_bound(input, in1, S_filtered_comb, 2); Xen_real_to_C_double_if_bound(pm, pm1, S_filtered_comb, 3); return(C_double_to_Xen_real(mus_filtered_comb(g, in1, pm1))); } static Xen g_make_filtered_comb_bank(Xen arg) { #define H_make_filtered_comb_bank "(" S_make_filtered_comb_bank " gens): return a new filtered_comb-bank generator." mus_any *ge = NULL; mus_any **gens; int i, j, size; Xen_check_type(Xen_is_vector(arg), arg, 1, S_make_filtered_comb_bank, "a vector of filtered_comb generators"); size = Xen_vector_length(arg); if (size == 0) return(Xen_false); gens = (mus_any **)calloc(size, sizeof(mus_any *)); for (i = 0, j = 0; i < size; i++) { Xen g; g = Xen_vector_ref(arg, i); if (mus_is_xen(g)) { mus_any *fg; fg = Xen_to_mus_any(g); if (mus_is_filtered_comb(fg)) gens[j++] = fg; } } if (j > 0) ge = mus_make_filtered_comb_bank(j, gens); free(gens); if (ge) return(mus_xen_to_object(mus_any_to_mus_xen_with_vct(ge, arg))); return(Xen_false); } static Xen g_is_filtered_comb_bank(Xen os) { #define H_is_filtered_comb_bank "(" S_is_filtered_comb_bank " gen): " PROC_TRUE " if gen is a " S_filtered_comb_bank return(C_bool_to_Xen_boolean((mus_is_xen(os)) && (mus_is_filtered_comb_bank(Xen_to_mus_any(os))))); } static Xen g_filtered_comb_bank(Xen gens, Xen inp) { #define H_filtered_comb_bank "(" S_filtered_comb_bank " bank inval): sum an array of " S_filtered_comb " filters." mus_any *bank = NULL; mus_xen *gn; mus_float_t x = 0.0; Xen_to_C_generator(gens, gn, bank, mus_is_filtered_comb_bank, S_filtered_comb_bank, "a filtered-comb-bank generator"); Xen_real_to_C_double_if_bound(inp, x, S_filtered_comb_bank, 2); return(C_double_to_Xen_real(mus_filtered_comb_bank(bank, x))); } static Xen g_all_pass(Xen obj, Xen input, Xen pm) { #define H_all_pass "(" S_all_pass " gen (val 0.0) (pm 0.0)): all-pass filter val, pm changes the delay length." mus_float_t in1 = 0.0, pm1 = 0.0; mus_any *g = NULL; mus_xen *gn; Xen_to_C_generator(obj, gn, g, mus_is_all_pass, S_all_pass, "an all-pass filter"); Xen_real_to_C_double_if_bound(input, in1, S_all_pass, 2); Xen_real_to_C_double_if_bound(pm, pm1, S_all_pass, 3); return(C_double_to_Xen_real(mus_all_pass(g, in1, pm1))); } static Xen g_make_all_pass_bank(Xen arg) { #define H_make_all_pass_bank "(" S_make_all_pass_bank " gens): return a new all_pass-bank generator." mus_any *ge = NULL; mus_any **gens; int i, j, size; Xen_check_type(Xen_is_vector(arg), arg, 1, S_make_all_pass_bank, "a vector of all_pass generators"); size = Xen_vector_length(arg); if (size == 0) return(Xen_false); gens = (mus_any **)calloc(size, sizeof(mus_any *)); for (i = 0, j = 0; i < size; i++) { Xen g; g = Xen_vector_ref(arg, i); if (mus_is_xen(g)) { mus_any *fg; fg = Xen_to_mus_any(g); if (mus_is_all_pass(fg)) gens[j++] = fg; } } if (j > 0) ge = mus_make_all_pass_bank(j, gens); free(gens); if (ge) return(mus_xen_to_object(mus_any_to_mus_xen_with_vct(ge, arg))); return(Xen_false); } static Xen g_is_all_pass_bank(Xen os) { #define H_is_all_pass_bank "(" S_is_all_pass_bank " gen): " PROC_TRUE " if gen is a " S_all_pass_bank return(C_bool_to_Xen_boolean((mus_is_xen(os)) && (mus_is_all_pass_bank(Xen_to_mus_any(os))))); } static Xen g_all_pass_bank(Xen gens, Xen inp) { #define H_all_pass_bank "(" S_all_pass_bank " bank inval): sum an array of " S_all_pass " filters." mus_any *bank = NULL; mus_xen *gn; mus_float_t x = 0.0; Xen_to_C_generator(gens, gn, bank, mus_is_all_pass_bank, S_all_pass_bank, "an all-pass-bank generator"); Xen_real_to_C_double_if_bound(inp, x, S_all_pass_bank, 2); return(C_double_to_Xen_real(mus_all_pass_bank(bank, x))); } static Xen g_moving_average(Xen obj, Xen input) { #define H_moving_average "(" S_moving_average " gen (val 0.0)): moving window average." mus_float_t in1 = 0.0; mus_any *g = NULL; mus_xen *gn; Xen_to_C_generator(obj, gn, g, mus_is_moving_average, S_moving_average, "a moving-average generator"); Xen_real_to_C_double_if_bound(input, in1, S_moving_average, 2); return(C_double_to_Xen_real(mus_moving_average(g, in1))); } static Xen g_moving_max(Xen obj, Xen input) { #define H_moving_max "(" S_moving_max " gen (val 0.0)): moving window max." mus_float_t in1 = 0.0; mus_any *g = NULL; mus_xen *gn; Xen_to_C_generator(obj, gn, g, mus_is_moving_max, S_moving_max, "a moving-max generator"); Xen_real_to_C_double_if_bound(input, in1, S_moving_max, 2); return(C_double_to_Xen_real(mus_moving_max(g, in1))); } static Xen g_moving_norm(Xen obj, Xen input) { #define H_moving_norm "(" S_moving_norm " gen (val 0.0)): moving window norm." mus_float_t in1 = 0.0; mus_any *g = NULL; mus_xen *gn; Xen_to_C_generator(obj, gn, g, mus_is_moving_norm, S_moving_norm, "a moving-norm generator"); Xen_real_to_C_double_if_bound(input, in1, S_moving_norm, 2); return(C_double_to_Xen_real(mus_moving_norm(g, in1))); } static Xen g_tap(Xen obj, Xen loc) { #define H_tap "(" S_tap " gen (pm 0.0)): tap the " S_delay " generator offset by pm" mus_float_t dloc = 0.0; mus_any *g = NULL; mus_xen *gn; Xen_to_C_generator(obj, gn, g, mus_is_tap, S_tap, "a delay line tap"); Xen_real_to_C_double_if_bound(loc, dloc, S_tap, 3); return(C_double_to_Xen_real(mus_tap(g, dloc))); } static Xen g_is_tap(Xen obj) { #define H_is_tap "(" S_is_tap " gen): " PROC_TRUE " if gen is a delay line tap" return(C_bool_to_Xen_boolean((mus_is_xen(obj)) && (mus_is_tap(Xen_to_mus_any(obj))))); } static Xen g_is_delay(Xen obj) { #define H_is_delay "(" S_is_delay " gen): " PROC_TRUE " if gen is a delay line" return(C_bool_to_Xen_boolean((mus_is_xen(obj)) && (mus_is_delay(Xen_to_mus_any(obj))))); } static Xen g_is_comb(Xen obj) { #define H_is_comb "(" S_is_comb " gen): " PROC_TRUE " if gen is a comb filter" return(C_bool_to_Xen_boolean((mus_is_xen(obj)) && (mus_is_comb(Xen_to_mus_any(obj))))); } static Xen g_is_filtered_comb(Xen obj) { #define H_is_filtered_comb "(" S_is_filtered_comb " gen): " PROC_TRUE " if gen is a filtered-comb filter" return(C_bool_to_Xen_boolean((mus_is_xen(obj)) && (mus_is_filtered_comb(Xen_to_mus_any(obj))))); } static Xen g_is_notch(Xen obj) { #define H_is_notch "(" S_is_notch " gen): " PROC_TRUE " if gen is a notch filter" return(C_bool_to_Xen_boolean((mus_is_xen(obj)) && (mus_is_notch(Xen_to_mus_any(obj))))); } static Xen g_is_all_pass(Xen obj) { #define H_is_all_pass "(" S_is_all_pass " gen): " PROC_TRUE " if gen is an all-pass filter" return(C_bool_to_Xen_boolean((mus_is_xen(obj)) && (mus_is_all_pass(Xen_to_mus_any(obj))))); } static Xen g_is_moving_average(Xen obj) { #define H_is_moving_average "(" S_is_moving_average " gen): " PROC_TRUE " if gen is a moving-average generator" return(C_bool_to_Xen_boolean((mus_is_xen(obj)) && (mus_is_moving_average(Xen_to_mus_any(obj))))); } static Xen g_is_moving_max(Xen obj) { #define H_is_moving_max "(" S_is_moving_max " gen): " PROC_TRUE " if gen is a moving-max generator" return(C_bool_to_Xen_boolean((mus_is_xen(obj)) && (mus_is_moving_max(Xen_to_mus_any(obj))))); } static Xen g_is_moving_norm(Xen obj) { #define H_is_moving_norm "(" S_is_moving_norm " gen): " PROC_TRUE " if gen is a moving-norm generator" return(C_bool_to_Xen_boolean((mus_is_xen(obj)) && (mus_is_moving_norm(Xen_to_mus_any(obj))))); } /* -------- ncos -------- */ static Xen g_is_ncos(Xen obj) { #define H_is_ncos "(" S_is_ncos " gen): " PROC_TRUE " if gen is an " S_ncos " generator" return(C_bool_to_Xen_boolean((mus_is_xen(obj)) && (mus_is_ncos(Xen_to_mus_any(obj))))); } static Xen g_make_ncos(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_make_ncos "(" S_make_ncos " (frequency *clm-default-frequency*) (n 1)): \ return a new " S_ncos " generator, producing a sum of 'n' equal amplitude cosines." mus_any *ge; Xen args[4]; Xen keys[2]; int orig_arg[2] = {0, 0}; int vals, n = 1; mus_float_t freq; freq = clm_default_frequency; keys[0] = kw_frequency; keys[1] = kw_n; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; vals = mus_optkey_unscramble(S_make_ncos, 2, keys, args, orig_arg); if (vals > 0) { freq = Xen_optkey_to_float(kw_frequency, keys[0], S_make_ncos, orig_arg[0], freq); if (freq > (0.5 * mus_srate())) Xen_out_of_range_error(S_make_ncos, orig_arg[0], keys[0], "freq > srate/2?"); n = Xen_optkey_to_int(kw_n, keys[1], S_make_ncos, orig_arg[1], n); if (n <= 0) Xen_out_of_range_error(S_make_ncos, orig_arg[1], keys[1], "n <= 0?"); } ge = mus_make_ncos(freq, n); if (ge) return(mus_xen_to_object(mus_any_to_mus_xen(ge))); return(Xen_false); } static Xen g_ncos(Xen obj, Xen fm) { #define H_ncos "(" S_ncos " gen (fm 0.0)): get the next sample from 'gen', an " S_ncos " generator" mus_float_t fm1 = 0.0; mus_any *g = NULL; mus_xen *gn; Xen_to_C_generator(obj, gn, g, mus_is_ncos, S_ncos, "an ncos generator"); Xen_real_to_C_double_if_bound(fm, fm1, S_ncos, 2); return(C_double_to_Xen_real(mus_ncos(g, fm1))); } /* -------- nsin -------- */ static Xen g_is_nsin(Xen obj) { #define H_is_nsin "(" S_is_nsin " gen): " PROC_TRUE " if gen is an " S_nsin " generator" return(C_bool_to_Xen_boolean((mus_is_xen(obj)) && (mus_is_nsin(Xen_to_mus_any(obj))))); } static Xen g_make_nsin(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_make_nsin "(" S_make_nsin " (frequency *clm-default-frequency*) (n 1)): \ return a new " S_nsin " generator, producing a sum of 'n' equal amplitude sines" mus_any *ge; Xen args[4]; Xen keys[2]; int orig_arg[2] = {0, 0}; int vals, n = 1; mus_float_t freq; freq = clm_default_frequency; keys[0] = kw_frequency; keys[1] = kw_n; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; vals = mus_optkey_unscramble(S_make_nsin, 2, keys, args, orig_arg); if (vals > 0) { freq = Xen_optkey_to_float(kw_frequency, keys[0], S_make_nsin, orig_arg[0], freq); if (freq > (0.5 * mus_srate())) Xen_out_of_range_error(S_make_nsin, orig_arg[0], keys[0], "freq > srate/2?"); n = Xen_optkey_to_int(kw_n, keys[1], S_make_nsin, orig_arg[1], n); if (n <= 0) Xen_out_of_range_error(S_make_nsin, orig_arg[1], keys[1], "n <= 0?"); } ge = mus_make_nsin(freq, n); if (ge) return(mus_xen_to_object(mus_any_to_mus_xen(ge))); return(Xen_false); } static Xen g_nsin(Xen obj, Xen fm) { #define H_nsin "(" S_nsin " gen (fm 0.0)): get the next sample from 'gen', an " S_nsin " generator" mus_float_t fm1 = 0.0; mus_any *g = NULL; mus_xen *gn; Xen_to_C_generator(obj, gn, g, mus_is_nsin, S_nsin, "an nsin generator"); Xen_real_to_C_double_if_bound(fm, fm1, S_nsin, 2); return(C_double_to_Xen_real(mus_nsin(g, fm1))); } /* ---------------- rand, rand_interp ---------------- */ #define RANDOM_DISTRIBUTION_TABLE_SIZE 512 #define RANDOM_DISTRIBUTION_ENVELOPE_SIZE 50 static mus_float_t *inverse_integrate(Xen dist, int data_size) { /* e = env possibly starting < 0 */ int e_size = RANDOM_DISTRIBUTION_ENVELOPE_SIZE; mus_float_t *e, *data; int i, e_len, lim, e_loc = 2; Xen ex0, ex1, ey0, ey1; mus_float_t x, x0, x1, xincr, y0, y1, sum, first_sum, last_sum = 0.0; lim = (e_size + 1) * 2; e = (mus_float_t *)calloc(lim, sizeof(mus_float_t)); e_len = Xen_list_length(dist); ex0 = Xen_list_ref(dist, 0); ex1 = Xen_list_ref(dist, e_len - 2); x0 = Xen_real_to_C_double(ex0); /* get x range first */ x1 = Xen_real_to_C_double(ex1); xincr = (x1 - x0) / (mus_float_t)e_size; /* now true x1 */ ex1 = Xen_list_ref(dist, 2); x1 = Xen_real_to_C_double(ex1); ey0 = Xen_list_ref(dist, 1); ey1 = Xen_list_ref(dist, 3); y0 = Xen_real_to_C_double(ey0); y1 = Xen_real_to_C_double(ey1); sum = y0; first_sum = sum; for (i = 0, x = x0; i < lim; i += 2, x += xincr) { e[i] = sum; last_sum = sum; e[i + 1] = x; while ((x >= x1) && ((e_loc + 2) < e_len)) { x0 = x1; y0 = y1; e_loc += 2; ex1 = Xen_list_ref(dist, e_loc); ey1 = Xen_list_ref(dist, e_loc + 1); x1 = Xen_real_to_C_double(ex1); y1 = Xen_real_to_C_double(ey1); } if ((x == x0) || (x0 == x1)) sum += y0; else sum += (y0 + (y1 - y0) * (x - x0) / (x1 - x0)); } xincr = (last_sum - first_sum) / (mus_float_t)(data_size - 1); data = (mus_float_t *)calloc(data_size, sizeof(mus_float_t)); x0 = e[0]; x1 = e[2]; y0 = e[1]; y1 = e[3]; e_len = lim; e_loc = 2; for (i = 0, x = first_sum; i < data_size; i++, x += xincr) { while ((x >= x1) && ((e_loc + 2) < e_len)) { x0 = x1; y0 = y1; e_loc += 2; x1 = e[e_loc]; y1 = e[e_loc + 1]; } if ((x == x0) || (x0 == x1)) data[i] = y0; else data[i] = (y0 + (y1 - y0) * (x - x0) / (x1 - x0)); } free(e); return(data); } static Xen g_make_noi(bool rand_case, const char *caller, Xen arglist) { mus_any *ge = NULL; Xen args[10]; Xen keys[5]; int orig_arg[5] = {0, 0, 0, 0, 0}; int vals; mus_float_t freq, base = 1.0; mus_float_t *distribution = NULL; Xen orig_v = Xen_false; int distribution_size = RANDOM_DISTRIBUTION_TABLE_SIZE; freq = clm_default_frequency; keys[0] = kw_frequency; keys[1] = kw_amplitude; keys[2] = kw_envelope; keys[3] = kw_distribution; keys[4] = kw_size; { int i, arglist_len; Xen p; arglist_len = Xen_list_length(arglist); if (arglist_len > 10) clm_error(caller, "too many arguments!", arglist); for (i = 0, p = arglist; i < arglist_len; i++, p = Xen_cdr(p)) args[i] = Xen_car(p); for (i = arglist_len; i < 10; i++) args[i] = Xen_undefined; } vals = mus_optkey_unscramble(caller, 5, keys, args, orig_arg); if (vals > 0) { freq = Xen_optkey_to_float(kw_frequency, keys[0], caller, orig_arg[0], freq); if (freq > mus_srate()) Xen_out_of_range_error(caller, orig_arg[0], keys[0], "freq > srate/2?"); base = Xen_optkey_to_float(kw_amplitude, keys[1], caller, orig_arg[1], base); distribution_size = Xen_optkey_to_int(kw_size, keys[4], caller, orig_arg[4], distribution_size); if (distribution_size <= 0) Xen_out_of_range_error(caller, orig_arg[4], keys[4], "distribution size <= 0?"); if (distribution_size > mus_max_table_size()) Xen_out_of_range_error(caller, orig_arg[4], keys[4], "distribution size too large (see mus-max-table-size)"); if (!(Xen_is_keyword(keys[2]))) /* i.e. envelope arg was specified */ { int len; Xen_check_type(Xen_is_list(keys[2]), keys[2], orig_arg[2], caller, "an envelope"); len = Xen_list_length(keys[2]); if ((len < 4) || (len & 1)) clm_error(caller, "bad distribution envelope", keys[2]); /* envelope and distribution are incompatible */ if (!(Xen_is_keyword(keys[3]))) clm_error(caller, ":envelope and :distribution in same call?", keys[3]); distribution = inverse_integrate(keys[2], distribution_size); orig_v = xen_make_vct(distribution_size, distribution); } else { if (!(Xen_is_keyword(keys[3]))) /* i.e. distribution arg was specified */ { Xen_check_type(mus_is_vct(keys[3]) || Xen_is_false(keys[3]), keys[3], orig_arg[3], caller, "a " S_vct); if (mus_is_vct(keys[3])) { vct *v = NULL; orig_v = keys[3]; v = mus_optkey_to_vct(orig_v, caller, orig_arg[3], NULL); distribution_size = mus_vct_length(v); distribution = mus_vct_data(v); } } } } if (!distribution) { if (rand_case) ge = mus_make_rand(freq, base); else ge = mus_make_rand_interp(freq, base); } else { if (rand_case) ge = mus_make_rand_with_distribution(freq, base, distribution, distribution_size); else ge = mus_make_rand_interp_with_distribution(freq, base, distribution, distribution_size); } if (ge) { if (mus_is_vct(orig_v)) return(mus_xen_to_object(mus_any_to_mus_xen_with_vct(ge, orig_v))); return(mus_xen_to_object(mus_any_to_mus_xen(ge))); } return(Xen_false); } static Xen g_make_rand_interp(Xen arglist) { #define H_make_rand_interp "(" S_make_rand_interp " (frequency *clm-default-frequency*) (amplitude 1.0) (envelope) (distribution) (size)): \ return a new " S_rand_interp " generator, producing linearly interpolated random numbers. \ frequency is the rate at which new end-points are chosen." return(g_make_noi(false, S_make_rand_interp, arglist)); } static Xen g_make_rand(Xen arglist) { #define H_make_rand "(" S_make_rand " (frequency *clm-default-frequency*) (amplitude 1.0) (envelope) (distribution) (size)): \ return a new " S_rand " generator, producing a sequence of random numbers (a step function). \ frequency is the rate at which new numbers are chosen." return(g_make_noi(true, S_make_rand, arglist)); } static Xen g_rand(Xen obj, Xen fm) { #define H_rand "(" S_rand " gen (fm 0.0)): gen's current random number. \ fm modulates the rate at which the current number is changed." mus_float_t fm1 = 0.0; mus_any *g = NULL; mus_xen *gn; Xen_to_C_generator(obj, gn, g, mus_is_rand, S_rand, "a rand generator"); Xen_real_to_C_double_if_bound(fm, fm1, S_rand, 2); return(C_double_to_Xen_real(mus_rand(g, fm1))); } static Xen g_is_rand(Xen obj) { #define H_is_rand "(" S_is_rand " gen): " PROC_TRUE " if gen is a " S_rand return(C_bool_to_Xen_boolean((mus_is_xen(obj)) && (mus_is_rand(Xen_to_mus_any(obj))))); } static Xen g_rand_interp(Xen obj, Xen fm) { #define H_rand_interp "(" S_rand_interp " gen (fm 0.0)): gen's current (interpolating) random number. \ fm modulates the rate at which new segment end-points are chosen." mus_float_t fm1 = 0.0; mus_any *g = NULL; mus_xen *gn; Xen_to_C_generator(obj, gn, g, mus_is_rand_interp, S_rand_interp, "a rand-interp generator"); Xen_real_to_C_double_if_bound(fm, fm1, S_rand_interp, 2); return(C_double_to_Xen_real(mus_rand_interp(g, fm1))); } static Xen g_is_rand_interp(Xen obj) { #define H_is_rand_interp "(" S_is_rand_interp " gen): " PROC_TRUE " if gen is a " S_rand_interp return(C_bool_to_Xen_boolean((mus_is_xen(obj)) && (mus_is_rand_interp(Xen_to_mus_any(obj))))); } static Xen g_mus_random(Xen a) { #define H_mus_random "(" S_mus_random " val): a random number between -val and val. \ the built-in 'random' function returns values between 0 and its argument" mus_float_t x; Xen_to_C_double_or_error(a, x, S_mus_random, 1); return(C_double_to_Xen_real(mus_random(x))); } static Xen g_mus_rand_seed(void) { #define H_mus_rand_seed "(" S_mus_rand_seed "): the random number seed; \ this can be used to re-run a particular random number sequence." return(C_int_to_Xen_integer(mus_rand_seed())); } static Xen g_mus_set_rand_seed(Xen a) { Xen_check_type(Xen_is_integer(a), a, 1, S_set S_mus_rand_seed, "an integer"); mus_set_rand_seed((unsigned long)Xen_integer_to_C_int(a)); return(a); } /* ---------------- table lookup ---------------- */ static Xen g_is_table_lookup(Xen obj) { #define H_is_table_lookup "(" S_is_table_lookup " gen): " PROC_TRUE " if gen is a " S_table_lookup return(C_bool_to_Xen_boolean((mus_is_xen(obj)) && (mus_is_table_lookup(Xen_to_mus_any(obj))))); } static Xen g_partials_to_wave(Xen partials, Xen utable, Xen normalize) { #define H_partials_to_wave "(" S_partials_to_wave " partials wave (normalize " PROC_FALSE ")): \ take a list or " S_vct " of partials (harmonic number and associated amplitude) and produce \ a waveform for use in " S_table_lookup ". If wave (a " S_vct ") is not given, \ a new one is created. If normalize is " PROC_TRUE ", the resulting waveform goes between -1.0 and 1.0.\n\ (set! gen (" S_make_table_lookup " 440.0 :wave (" S_partials_to_wave " '(1 1.0 2 .5))))" vct *f; Xen table; mus_float_t *partial_data = NULL; mus_long_t len = 0; bool partials_allocated = true; #if HAVE_SCHEME int gc_loc; #endif Xen_check_type(mus_is_vct(partials) || Xen_is_list(partials), partials, 1, S_partials_to_wave, "a list or a " S_vct); Xen_check_type(mus_is_vct(utable) || Xen_is_false(utable) || (!(Xen_is_bound(utable))), utable, 2, S_partials_to_wave, "a " S_vct " or " PROC_FALSE); Xen_check_type(Xen_is_boolean_or_unbound(normalize), normalize, 3, S_partials_to_wave, "a boolean"); if (mus_is_vct(partials)) { vct *v; v = Xen_to_vct(partials); partial_data = mus_vct_data(v); len = mus_vct_length(v); partials_allocated = false; } else { len = Xen_list_length(partials); if (len == 0) Xen_error(NO_DATA, Xen_list_2(C_string_to_Xen_string("~A: partials list empty?"), C_string_to_Xen_string(S_partials_to_wave))); if (!(Xen_is_number(Xen_car(partials)))) Xen_check_type(false, partials, 1, S_partials_to_wave, "a list of numbers (partial numbers with amplitudes)"); } if (len & 1) Xen_error(BAD_TYPE, Xen_list_3(C_string_to_Xen_string("~A: odd length partials list? ~A"), C_string_to_Xen_string(S_partials_to_wave), partials)); if ((!Xen_is_bound(utable)) || (!(mus_is_vct(utable)))) { mus_float_t *wave; wave = (mus_float_t *)calloc(clm_table_size, sizeof(mus_float_t)); if (wave == NULL) return(clm_mus_error(MUS_MEMORY_ALLOCATION_FAILED, "can't allocate wave table", S_partials_to_wave)); table = xen_make_vct(clm_table_size, wave); } else table = utable; #if HAVE_SCHEME gc_loc = s7_gc_protect(s7, table); #endif f = Xen_to_vct(table); if (!partial_data) { Xen lst; int i; partial_data = (mus_float_t *)malloc(len * sizeof(mus_float_t)); if (partial_data == NULL) return(clm_mus_error(MUS_MEMORY_ALLOCATION_FAILED, "can't allocate partials table", S_partials_to_wave)); for (i = 0, lst = Xen_copy_arg(partials); i < len; i++, lst = Xen_cdr(lst)) partial_data[i] = Xen_real_to_C_double(Xen_car(lst)); } mus_partials_to_wave(partial_data, len / 2, mus_vct_data(f), mus_vct_length(f), (Xen_is_true(normalize))); if (partials_allocated) free(partial_data); #if HAVE_SCHEME s7_gc_unprotect_at(s7, gc_loc); #endif return(table); } static Xen g_phase_partials_to_wave(Xen partials, Xen utable, Xen normalize) { vct *f; Xen table; mus_float_t *partial_data = NULL; mus_long_t len = 0; bool partials_allocated = true; #if HAVE_SCHEME int gc_loc; #endif #if HAVE_SCHEME #define pp2w_example "(" S_make_table_lookup " 440.0 :wave (" S_phase_partials_to_wave " (list 1 .75 0.0 2 .25 (* 3.14159 .5))))" #endif #if HAVE_RUBY #define pp2w_example "make_table_lookup(440.0, :wave, phase_partials2wave([1.0, 0.75, 0.0, 2.0, 0.25, 3.14159 * 0.5]))" #endif #if HAVE_FORTH #define pp2w_example "440.0 0.0 '( 1.0 0.75 0.0 2.0 0.25 3.14159 0.5 f* ) #f #f phase-partials->wave make-table-lookup" #endif #define H_phase_partials_to_wave "(" S_phase_partials_to_wave " partials wave (normalize " PROC_FALSE ")): \ take a list or " S_vct " of partials (harmonic number, amplitude, initial phase) and produce \ a waveform for use in " S_table_lookup ". If wave (a " S_vct ") is not given, \ a new one is created. If normalize is " PROC_TRUE ", the resulting waveform goes between -1.0 and 1.0.\n " pp2w_example Xen_check_type(mus_is_vct(partials) || Xen_is_list(partials), partials, 1, S_phase_partials_to_wave, "a list or a " S_vct); Xen_check_type(mus_is_vct(utable) || Xen_is_false(utable) || (!(Xen_is_bound(utable))), utable, 2, S_phase_partials_to_wave, "a " S_vct " or " PROC_FALSE); Xen_check_type(Xen_is_boolean_or_unbound(normalize), normalize, 3, S_phase_partials_to_wave, "a boolean"); if (mus_is_vct(partials)) { vct *v; v = Xen_to_vct(partials); partial_data = mus_vct_data(v); len = mus_vct_length(v); partials_allocated = false; } else { len = Xen_list_length(partials); if (len == 0) Xen_error(NO_DATA, Xen_list_2(C_string_to_Xen_string("~A: partials list empty?"), C_string_to_Xen_string(S_phase_partials_to_wave))); if (!(Xen_is_number(Xen_car(partials)))) Xen_check_type(false, partials, 1, S_phase_partials_to_wave, "a list of numbers (partial numbers with amplitudes and phases)"); } if ((len % 3) != 0) Xen_error(Xen_make_error_type("wrong-type-arg"), Xen_list_3(C_string_to_Xen_string("~A: partials list, ~A, should have 3 entries for each harmonic (number amp phase)"), C_string_to_Xen_string(S_phase_partials_to_wave), partials)); if ((!Xen_is_bound(utable)) || (!(mus_is_vct(utable)))) { mus_float_t *wave; wave = (mus_float_t *)calloc(clm_table_size, sizeof(mus_float_t)); if (wave == NULL) return(clm_mus_error(MUS_MEMORY_ALLOCATION_FAILED, "can't allocate wave table", S_phase_partials_to_wave)); table = xen_make_vct(clm_table_size, wave); } else table = utable; #if HAVE_SCHEME gc_loc = s7_gc_protect(s7, table); #endif f = Xen_to_vct(table); if (!partial_data) { int i; Xen lst; partial_data = (mus_float_t *)malloc(len * sizeof(mus_float_t)); if (partial_data == NULL) return(clm_mus_error(MUS_MEMORY_ALLOCATION_FAILED, "can't allocate partials table", S_phase_partials_to_wave)); for (i = 0, lst = Xen_copy_arg(partials); i < len; i++, lst = Xen_cdr(lst)) partial_data[i] = Xen_real_to_C_double(Xen_car(lst)); } mus_phase_partials_to_wave(partial_data, len / 3, mus_vct_data(f), mus_vct_length(f), (Xen_is_true(normalize))); if (partials_allocated) free(partial_data); #if HAVE_SCHEME s7_gc_unprotect_at(s7, gc_loc); #endif return(table); } static Xen g_make_table_lookup(Xen arglist) { #define H_make_table_lookup "(" S_make_table_lookup " (frequency *clm-default-frequency*) (initial-phase 0.0) (wave) (size clm-table-size) (type)): \ return a new " S_table_lookup " generator. \ The default table size is 512; use :size to set some other size, or pass your own " S_vct " as the 'wave'.\n\ (set! gen (" S_make_table_lookup " 440.0 :wave (" S_partials_to_wave " '(1 1.0))))\n\ is the same in effect as " S_make_oscil ". 'type' sets the interpolation choice which defaults to " S_mus_interp_linear "." mus_any *ge; int vals; mus_long_t table_size = clm_table_size; Xen args[10]; Xen keys[5]; int orig_arg[5] = {0, 0, 0, 0, MUS_INTERP_LINEAR}; mus_float_t freq, phase = 0.0; mus_float_t *table = NULL; Xen orig_v = Xen_false; int interp_type = (int)MUS_INTERP_LINEAR; freq = clm_default_frequency; keys[0] = kw_frequency; keys[1] = kw_initial_phase; keys[2] = kw_wave; keys[3] = kw_size; keys[4] = kw_type; { int i, arglist_len; Xen p; arglist_len = Xen_list_length(arglist); if (arglist_len > 10) clm_error(S_make_table_lookup, "too many arguments!", arglist); for (i = 0, p = arglist; i < arglist_len; i++, p = Xen_cdr(p)) args[i] = Xen_car(p); for (i = arglist_len; i < 10; i++) args[i] = Xen_undefined; } vals = mus_optkey_unscramble(S_make_table_lookup, 5, keys, args, orig_arg); if (vals > 0) { vct *v = NULL; freq = Xen_optkey_to_float(kw_frequency, keys[0], S_make_table_lookup, orig_arg[0], freq); if (freq > (0.5 * mus_srate())) Xen_out_of_range_error(S_make_table_lookup, orig_arg[0], keys[0], "freq > srate/2?"); phase = Xen_optkey_to_float(kw_initial_phase, keys[1], S_make_table_lookup, orig_arg[1], phase); if (phase < 0.0) Xen_out_of_range_error(S_make_table_lookup, orig_arg[1], keys[1], "initial phase <= 0.0?"); /* is this actually an error? */ v = mus_optkey_to_vct(keys[2], S_make_table_lookup, orig_arg[2], NULL); if (v) { orig_v = keys[2]; table = mus_vct_data(v); table_size = mus_vct_length(v); } table_size = Xen_optkey_to_mus_long_t(kw_size, keys[3], S_make_table_lookup, orig_arg[3], table_size); if (table_size <= 0) Xen_out_of_range_error(S_make_table_lookup, orig_arg[3], keys[3], "size <= 0?"); if (table_size > mus_max_table_size()) Xen_out_of_range_error(S_make_table_lookup, orig_arg[3], keys[3], "size too large (see mus-max-table-size)"); if ((v) && (table_size > mus_vct_length(v))) Xen_out_of_range_error(S_make_table_lookup, orig_arg[3], keys[3], "table size > wave size"); interp_type = Xen_optkey_to_int(kw_type, keys[4], S_make_table_lookup, orig_arg[4], interp_type); if (!(mus_is_interp_type(interp_type))) Xen_out_of_range_error(S_make_table_lookup, orig_arg[4], keys[4], "no such interp-type"); } if (!(mus_is_vct(orig_v))) { table = (mus_float_t *)calloc(table_size, sizeof(mus_float_t)); if (table == NULL) return(clm_mus_error(MUS_MEMORY_ALLOCATION_FAILED, "can't allocate table-lookup table", S_make_table_lookup)); orig_v = xen_make_vct(table_size, table); } ge = mus_make_table_lookup(freq, phase, table, table_size, (mus_interp_t)interp_type); return(mus_xen_to_object(mus_any_to_mus_xen_with_vct(ge, orig_v))); } static Xen g_table_lookup(Xen obj, Xen fm) { #define H_table_lookup "(" S_table_lookup " gen (fm 0.0)): interpolated table-lookup \ with 'wrap-around' when gen's phase marches off either end of its table." mus_float_t fm1 = 0.0; mus_any *g = NULL; mus_xen *gn; Xen_to_C_generator(obj, gn, g, mus_is_table_lookup, S_table_lookup, "a table-lookup generator"); Xen_real_to_C_double_if_bound(fm, fm1, S_table_lookup, 2); return(C_double_to_Xen_real(mus_table_lookup(g, fm1))); } /* ---------------- sawtooth et al ---------------- */ typedef enum {G_SAWTOOTH_WAVE, G_SQUARE_WAVE, G_TRIANGLE_WAVE, G_PULSE_TRAIN} xclm_wave_t; static Xen g_make_sw(xclm_wave_t type, mus_float_t def_phase, Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6) { mus_any *ge = NULL; const char *caller = NULL; Xen args[6]; Xen keys[3]; int orig_arg[3] = {0, 0, 0}; int vals; mus_float_t freq, base = 1.0, phase; freq = clm_default_frequency; phase = def_phase; switch (type) { case G_SAWTOOTH_WAVE: caller = S_make_sawtooth_wave; break; case G_SQUARE_WAVE: caller = S_make_square_wave; break; case G_TRIANGLE_WAVE: caller = S_make_triangle_wave; break; case G_PULSE_TRAIN: caller = S_make_pulse_train; break; } keys[0] = kw_frequency; keys[1] = kw_amplitude; keys[2] = kw_initial_phase; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; vals = mus_optkey_unscramble(caller, 3, keys, args, orig_arg); if (vals > 0) { freq = Xen_optkey_to_float(kw_frequency, keys[0], caller, orig_arg[0], freq); if (freq > mus_srate()) Xen_out_of_range_error(caller, orig_arg[0], keys[0], "freq > srate/2?"); base = Xen_optkey_to_float(kw_amplitude, keys[1], caller, orig_arg[1], base); phase = Xen_optkey_to_float(kw_initial_phase, keys[2], caller, orig_arg[2], phase); } switch (type) { case G_SAWTOOTH_WAVE: ge = mus_make_sawtooth_wave(freq, base, phase); break; case G_SQUARE_WAVE: ge = mus_make_square_wave(freq, base, phase); break; case G_TRIANGLE_WAVE: ge = mus_make_triangle_wave(freq, base, phase); break; case G_PULSE_TRAIN: ge = mus_make_pulse_train(freq, base, phase); break; } if (ge) return(mus_xen_to_object(mus_any_to_mus_xen(ge))); return(Xen_false); } static Xen g_make_sawtooth_wave(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6) { #define H_make_sawtooth_wave "(" S_make_sawtooth_wave " (frequency *clm-default-frequency*) (amplitude 1.0) (initial-phase 0.0)): \ return a new " S_sawtooth_wave " generator." return(g_make_sw(G_SAWTOOTH_WAVE, M_PI, arg1, arg2, arg3, arg4, arg5, arg6)); } static Xen g_make_square_wave(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6) { #define H_make_square_wave "(" S_make_square_wave " (frequency *clm-default-frequency*) (amplitude 1.0) (initial-phase 0.0)): \ return a new " S_square_wave " generator." return(g_make_sw(G_SQUARE_WAVE, 0.0, arg1, arg2, arg3, arg4, arg5, arg6)); } static Xen g_make_triangle_wave(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6) { #define H_make_triangle_wave "(" S_make_triangle_wave " (frequency *clm-default-frequency*) (amplitude 1.0) (initial-phase 0.0)): \ return a new " S_triangle_wave " generator." return(g_make_sw(G_TRIANGLE_WAVE, 0.0, arg1, arg2, arg3, arg4, arg5, arg6)); } static Xen g_make_pulse_train(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6) { #define H_make_pulse_train "(" S_make_pulse_train " (frequency *clm-default-frequency*) (amplitude 1.0) (initial-phase 0.0)): \ return a new " S_pulse_train " generator. This produces a sequence of impulses." return(g_make_sw(G_PULSE_TRAIN, TWO_PI, arg1, arg2, arg3, arg4, arg5, arg6)); } static Xen g_sawtooth_wave(Xen obj, Xen fm) { #define H_sawtooth_wave "(" S_sawtooth_wave " gen (fm 0.0)): next sawtooth sample from generator" mus_float_t fm1 = 0.0; mus_any *g = NULL; mus_xen *gn; Xen_to_C_generator(obj, gn, g, mus_is_sawtooth_wave, S_sawtooth_wave, "a sawtooth-wave generator"); Xen_real_to_C_double_if_bound(fm, fm1, S_sawtooth_wave, 2); return(C_double_to_Xen_real(mus_sawtooth_wave(g, fm1))); } static Xen g_square_wave(Xen obj, Xen fm) { #define H_square_wave "(" S_square_wave " gen (fm 0.0)): next square wave sample from generator" mus_float_t fm1 = 0.0; mus_any *g = NULL; mus_xen *gn; Xen_to_C_generator(obj, gn, g, mus_is_square_wave, S_square_wave, "a square-wave generator"); Xen_real_to_C_double_if_bound(fm, fm1, S_square_wave, 2); return(C_double_to_Xen_real(mus_square_wave(g, fm1))); } static Xen g_triangle_wave(Xen obj, Xen fm) { #define H_triangle_wave "(" S_triangle_wave " gen (fm 0.0)): next triangle wave sample from generator" mus_float_t fm1 = 0.0; mus_any *g = NULL; mus_xen *gn; Xen_to_C_generator(obj, gn, g, mus_is_triangle_wave, S_triangle_wave, "a triangle-wave generator"); Xen_real_to_C_double_if_bound(fm, fm1, S_triangle_wave, 2); return(C_double_to_Xen_real(mus_triangle_wave(g, fm1))); } static Xen g_pulse_train(Xen obj, Xen fm) { #define H_pulse_train "(" S_pulse_train " gen (fm 0.0)): next pulse train sample from generator" mus_float_t fm1 = 0.0; mus_any *g = NULL; mus_xen *gn; Xen_to_C_generator(obj, gn, g, mus_is_pulse_train, S_pulse_train, "a pulse-train generator"); Xen_real_to_C_double_if_bound(fm, fm1, S_pulse_train, 2); return(C_double_to_Xen_real(mus_pulse_train(g, fm1))); } static Xen g_is_sawtooth_wave(Xen obj) { #define H_is_sawtooth_wave "(" S_is_sawtooth_wave " gen): " PROC_TRUE " if gen is a " S_sawtooth_wave return(C_bool_to_Xen_boolean((mus_is_xen(obj)) && (mus_is_sawtooth_wave(Xen_to_mus_any(obj))))); } static Xen g_is_square_wave(Xen obj) { #define H_is_square_wave "(" S_is_square_wave " gen): " PROC_TRUE " if gen is a " S_square_wave return(C_bool_to_Xen_boolean((mus_is_xen(obj)) && (mus_is_square_wave(Xen_to_mus_any(obj))))); } static Xen g_is_triangle_wave(Xen obj) { #define H_is_triangle_wave "(" S_is_triangle_wave " gen): " PROC_TRUE " if gen is a " S_triangle_wave return(C_bool_to_Xen_boolean((mus_is_xen(obj)) && (mus_is_triangle_wave(Xen_to_mus_any(obj))))); } static Xen g_is_pulse_train(Xen obj) { #define H_is_pulse_train "(" S_is_pulse_train " gen): " PROC_TRUE " if gen is a " S_pulse_train return(C_bool_to_Xen_boolean((mus_is_xen(obj)) && (mus_is_pulse_train(Xen_to_mus_any(obj))))); } /* ---------------- asymmetric-fm ---------------- */ static Xen g_make_asymmetric_fm(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6, Xen arg7, Xen arg8) { #define H_make_asymmetric_fm "(" S_make_asymmetric_fm " (frequency *clm-default-frequency*) (initial-phase 0.0) (r 1.0) (ratio 1.0)): \ return a new " S_asymmetric_fm " generator." mus_any *ge; Xen args[8]; Xen keys[4]; int orig_arg[4] = {0, 0, 0, 0}; int vals; mus_float_t freq, phase = 0.0, r = 1.0, ratio = 1.0; freq = clm_default_frequency; keys[0] = kw_frequency; keys[1] = kw_initial_phase; keys[2] = kw_r; keys[3] = kw_ratio; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; args[6] = arg7; args[7] = arg8; vals = mus_optkey_unscramble(S_make_asymmetric_fm, 4, keys, args, orig_arg); if (vals > 0) { freq = Xen_optkey_to_float(kw_frequency, keys[0], S_make_asymmetric_fm, orig_arg[0], freq); if (freq > (0.5 * mus_srate())) Xen_out_of_range_error(S_make_asymmetric_fm, orig_arg[0], keys[0], "freq > srate/2?"); phase = Xen_optkey_to_float(kw_initial_phase, keys[1], S_make_asymmetric_fm, orig_arg[1], phase); r = Xen_optkey_to_float(kw_r, keys[2], S_make_asymmetric_fm, orig_arg[2], r); ratio = Xen_optkey_to_float(kw_ratio, keys[3], S_make_asymmetric_fm, orig_arg[3], ratio); } ge = mus_make_asymmetric_fm(freq, phase, r, ratio); if (ge) return(mus_xen_to_object(mus_any_to_mus_xen(ge))); return(Xen_false); } static Xen g_asymmetric_fm(Xen obj, Xen index, Xen fm) { #define H_asymmetric_fm "(" S_asymmetric_fm " gen (index 0.0) (fm 0.0)): next sample from asymmetric fm generator" mus_float_t fm1 = 0.0, index1 = 0.0; mus_any *g = NULL; mus_xen *gn; Xen_to_C_generator(obj, gn, g, mus_is_asymmetric_fm, S_asymmetric_fm, "an asymmetric-fm generator"); Xen_real_to_C_double_if_bound(fm, fm1, S_asymmetric_fm, 2); Xen_real_to_C_double_if_bound(index, index1, S_asymmetric_fm, 3); return(C_double_to_Xen_real(mus_asymmetric_fm(g, index1, fm1))); } static Xen g_is_asymmetric_fm(Xen obj) { #define H_is_asymmetric_fm "(" S_is_asymmetric_fm " gen): " PROC_TRUE " if gen is a " S_asymmetric_fm return(C_bool_to_Xen_boolean((mus_is_xen(obj)) && (mus_is_asymmetric_fm(Xen_to_mus_any(obj))))); } /* ---------------- simple filters ---------------- */ typedef enum {G_ONE_POLE, G_ONE_ZERO, G_TWO_POLE, G_TWO_ZERO} xclm_filter_t; static const char *smpflts[6] = {S_make_one_pole, S_make_one_zero, S_make_two_pole, S_make_two_zero}; static Xen g_make_smpflt_1(xclm_filter_t choice, Xen arg1, Xen arg2, Xen arg3, Xen arg4) { mus_any *gen = NULL; Xen args[4]; Xen keys[2]; int orig_arg[2] = {0, 0}; int vals; mus_float_t a0 = 0.0; mus_float_t a1 = 0.0; switch (choice) { case G_ONE_ZERO: keys[0] = kw_a0; keys[1] = kw_a1; break; case G_ONE_POLE: keys[0] = kw_a0; keys[1] = kw_b1; break; default: keys[0] = kw_frequency; keys[1] = kw_radius; break; } args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; vals = mus_optkey_unscramble(smpflts[choice], 2, keys, args, orig_arg); if (vals > 0) { a0 = mus_optkey_to_float(keys[0], smpflts[choice], orig_arg[0], a0); a1 = mus_optkey_to_float(keys[1], smpflts[choice], orig_arg[1], a1); } switch (choice) { case G_ONE_ZERO: gen = mus_make_one_zero(a0, a1); break; case G_ONE_POLE: gen = mus_make_one_pole(a0, a1); break; case G_TWO_ZERO: gen = mus_make_two_zero_from_frequency_and_radius(a0, a1); break; case G_TWO_POLE: gen = mus_make_two_pole_from_frequency_and_radius(a0, a1); break; default: break; } if (gen) return(mus_xen_to_object(mus_any_to_mus_xen(gen))); return(Xen_false); } static Xen g_make_one_zero(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_make_one_zero "(" S_make_one_zero " a0 a1): return a new " S_one_zero " filter; a0*x(n) + a1*x(n-1)" return(g_make_smpflt_1(G_ONE_ZERO, arg1, arg2, arg3, arg4)); } static Xen g_make_one_pole(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_make_one_pole "(" S_make_one_pole " a0 b1): return a new " S_one_pole " filter; a0*x(n) - b1*y(n-1)" return(g_make_smpflt_1(G_ONE_POLE, arg1, arg2, arg3, arg4)); } static Xen g_make_smpflt_2(xclm_filter_t choice, Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6) { mus_any *gen = NULL; Xen args[6]; Xen keys[3]; int orig_arg[3] = {0, 0, 0}; int vals; mus_float_t a0 = 0.0; mus_float_t a1 = 0.0; mus_float_t a2 = 0.0; if (choice == G_TWO_ZERO) { keys[0] = kw_a0; keys[1] = kw_a1; keys[2] = kw_a2; } else { keys[0] = kw_a0; keys[1] = kw_b1; keys[2] = kw_b2; } args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; vals = mus_optkey_unscramble(smpflts[choice], 3, keys, args, orig_arg); if (vals > 0) { a0 = Xen_optkey_to_float(kw_a0, keys[0], smpflts[choice], orig_arg[0], a0); a1 = mus_optkey_to_float(keys[1], smpflts[choice], orig_arg[1], a1); a2 = mus_optkey_to_float(keys[2], smpflts[choice], orig_arg[2], a2); } if (choice == G_TWO_ZERO) gen = mus_make_two_zero(a0, a1, a2); else gen = mus_make_two_pole(a0, a1, a2); if (gen) return(mus_xen_to_object(mus_any_to_mus_xen(gen))); return(Xen_false); } static bool found_polar_key(Xen arg) { return((Xen_is_keyword(arg)) && ((Xen_keyword_is_eq(arg, kw_radius)) || (Xen_keyword_is_eq(arg, kw_frequency)))); } static bool found_coeff_key(Xen arg) { return((Xen_is_keyword(arg)) && (!(Xen_keyword_is_eq(arg, kw_radius))) && (!(Xen_keyword_is_eq(arg, kw_frequency)))); } static Xen g_make_two_zero(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6) { #define H_make_two_zero "(" S_make_two_zero " a0 a1 a2) or (" S_make_two_zero " frequency radius): return a new " S_two_zero " filter; \ a0*x(n) + a1*x(n-1) + a2*x(n-2)" if ((Xen_is_bound(arg2)) && /* 0 or 1 args -> coeffs */ (!(Xen_is_bound(arg5)))) /* 5 or more args -> coeffs */ { if ((found_polar_key(arg1)) || (found_polar_key(arg2)) || /* if arg1 is frequency as number, then arg2 is either key or number */ ((!(Xen_is_bound(arg3))) && /* make a guess that if 2 args, no keys, and a0 > 20, it is intended as a frequency */ (!(found_coeff_key(arg1))) && ((Xen_is_number(arg1)) && (Xen_real_to_C_double(arg1) >= 20.0)))) return(g_make_smpflt_1(G_TWO_ZERO, arg1, arg2, arg3, arg4)); } return(g_make_smpflt_2(G_TWO_ZERO, arg1, arg2, arg3, arg4, arg5, arg6)); } static Xen g_make_two_pole(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6) { #define H_make_two_pole "(" S_make_two_pole " a0 b1 b2) or (" S_make_two_pole " frequency radius): return a new " S_two_pole " filter; \ a0*x(n) - b1*y(n-1) - b2*y(n-2)" if ((Xen_is_bound(arg2)) && /* 0 or 1 args -> coeffs */ (!(Xen_is_bound(arg5)))) /* 5 or more args -> coeffs */ { if ((found_polar_key(arg1)) || (found_polar_key(arg2)) || /* if arg1 is frequency as number, then arg2 is either key or number */ ((!(Xen_is_bound(arg3))) && (!(found_coeff_key(arg1))) && ((Xen_is_number(arg1)) && (Xen_real_to_C_double(arg1) >= 2.0)))) return(g_make_smpflt_1(G_TWO_POLE, arg1, arg2, arg3, arg4)); } return(g_make_smpflt_2(G_TWO_POLE, arg1, arg2, arg3, arg4, arg5, arg6)); } static Xen g_one_zero(Xen obj, Xen fm) { #define H_one_zero "(" S_one_zero " gen (input 0.0)): one zero filter of input" mus_float_t fm1 = 0.0; mus_any *g = NULL; mus_xen *gn; Xen_to_C_generator(obj, gn, g, mus_is_one_zero, S_one_zero, "a one-zero filter"); Xen_real_to_C_double_if_bound(fm, fm1, S_one_zero, 2); return(C_double_to_Xen_real(mus_one_zero(g, fm1))); } static Xen g_one_pole(Xen obj, Xen fm) { #define H_one_pole "(" S_one_pole " gen (input 0.0)): one pole filter of input" mus_float_t fm1 = 0.0; mus_any *g = NULL; mus_xen *gn; Xen_to_C_generator(obj, gn, g, mus_is_one_pole, S_one_pole, "a one-pole filter"); Xen_real_to_C_double_if_bound(fm, fm1, S_one_pole, 2); return(C_double_to_Xen_real(mus_one_pole(g, fm1))); } static Xen g_two_zero(Xen obj, Xen fm) { #define H_two_zero "(" S_two_zero " gen (input 0.0)): two zero filter of input" mus_float_t fm1 = 0.0; mus_any *g = NULL; mus_xen *gn; Xen_to_C_generator(obj, gn, g, mus_is_two_zero, S_two_zero, "a two-zero filter"); Xen_real_to_C_double_if_bound(fm, fm1, S_two_zero, 2); return(C_double_to_Xen_real(mus_two_zero(g, fm1))); } static Xen g_two_pole(Xen obj, Xen fm) { #define H_two_pole "(" S_two_pole " gen (input 0.0)): two pole filter of input" mus_float_t fm1 = 0.0; mus_any *g = NULL; mus_xen *gn; Xen_to_C_generator(obj, gn, g, mus_is_two_pole, S_two_pole, "a two-pole filter"); Xen_real_to_C_double_if_bound(fm, fm1, S_two_pole, 2); return(C_double_to_Xen_real(mus_two_pole(g, fm1))); } static Xen g_is_one_zero(Xen obj) { #define H_is_one_zero "(" S_is_one_zero " gen): " PROC_TRUE " if gen is a " S_one_zero return(C_bool_to_Xen_boolean((mus_is_xen(obj)) && (mus_is_one_zero(Xen_to_mus_any(obj))))); } static Xen g_is_one_pole(Xen obj) { #define H_is_one_pole "(" S_is_one_pole " gen): " PROC_TRUE " if gen is a " S_one_pole return(C_bool_to_Xen_boolean((mus_is_xen(obj)) && (mus_is_one_pole(Xen_to_mus_any(obj))))); } static Xen g_is_two_zero(Xen obj) { #define H_is_two_zero "(" S_is_two_zero " gen): " PROC_TRUE " if gen is a " S_two_zero return(C_bool_to_Xen_boolean((mus_is_xen(obj)) && (mus_is_two_zero(Xen_to_mus_any(obj))))); } static Xen g_is_two_pole(Xen obj) { #define H_is_two_pole "(" S_is_two_pole " gen): " PROC_TRUE " if gen is a " S_two_pole return(C_bool_to_Xen_boolean((mus_is_xen(obj)) && (mus_is_two_pole(Xen_to_mus_any(obj))))); } /* ---------------- formant ---------------- */ static Xen g_make_frm(bool formant_case, const char *caller, Xen arg1, Xen arg2, Xen arg3, Xen arg4) { mus_any *ge; int vals; Xen args[4]; Xen keys[2]; int orig_arg[2] = {0, 0}; mus_float_t freq = 0.0, radius = 0.0; keys[0] = kw_frequency; keys[1] = kw_radius; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; vals = mus_optkey_unscramble(caller, 2, keys, args, orig_arg); if (vals > 0) { freq = Xen_optkey_to_float(kw_frequency, keys[0], caller, orig_arg[0], freq); if (freq > (0.5 * mus_srate())) Xen_out_of_range_error(caller, orig_arg[0], keys[0], "freq > srate/2?"); radius = Xen_optkey_to_float(kw_radius, keys[1], caller, orig_arg[1], radius); } if (formant_case) { ge = mus_make_formant(freq, radius); if (ge) { mus_xen *gn; gn = mus_any_to_mus_xen(ge); return(mus_xen_to_object(gn)); } } else { ge = mus_make_firmant(freq, radius); if (ge) return(mus_xen_to_object(mus_any_to_mus_xen(ge))); } return(Xen_false); } static Xen g_formant(Xen gen, Xen input, Xen freq) { #define H_formant "(" S_formant " gen (input 0.0) freq-in-radians): next sample from resonator generator" mus_float_t in1 = 0.0; mus_any *g = NULL; mus_xen *gn; Xen_to_C_generator(gen, gn, g, mus_is_formant, S_formant, "a formant generator"); Xen_real_to_C_double_if_bound(input, in1, S_formant, 2); if (Xen_is_bound(freq)) return(C_double_to_Xen_real(mus_formant_with_frequency(g, in1, Xen_real_to_C_double(freq)))); return(C_double_to_Xen_real(mus_formant(g, in1))); } static Xen g_make_formant(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_make_formant "(" S_make_formant " frequency radius): \ return a new formant generator (a resonator). radius sets the pole radius (in terms of the 'unit circle'). \ frequency sets the resonance center frequency (Hz)." return(g_make_frm(true, S_make_formant, arg1, arg2, arg3, arg4)); } static Xen g_is_formant(Xen os) { #define H_is_formant "(" S_is_formant " gen): " PROC_TRUE " if gen is a " S_formant return(C_bool_to_Xen_boolean((mus_is_xen(os)) && (mus_is_formant(Xen_to_mus_any(os))))); } static Xen g_set_formant_radius_and_frequency(Xen gen, Xen rad, Xen frq) { #define H_mus_set_formant_radius_and_frequency "(" S_mus_set_formant_radius_and_frequency " gen radius frequency): set " S_formant " \ generator gen's radius and frequency" mus_any *g = NULL; mus_float_t radius, frequency; mus_xen *gn; Xen_to_C_generator(gen, gn, g, mus_is_formant, S_mus_set_formant_radius_and_frequency, "a formant generator"); Xen_to_C_double_or_error(rad, radius, S_mus_set_formant_radius_and_frequency, 2); Xen_to_C_double_or_error(frq, frequency, S_mus_set_formant_radius_and_frequency, 3); mus_set_formant_radius_and_frequency(g, radius, frequency); return(rad); } static Xen g_set_formant_frequency(Xen gen, Xen frq) { #define H_mus_set_formant_frequency "(" S_mus_set_formant_frequency " gen frequency): set " S_formant " generator gen's frequency" mus_any *g = NULL; mus_float_t frequency; mus_xen *gn; Xen_to_C_generator(gen, gn, g, mus_is_formant, S_mus_set_formant_frequency, "a formant generator"); Xen_to_C_double_or_error(frq, frequency, S_mus_set_formant_frequency, 2); mus_set_formant_frequency(g, frequency); return(frq); } static Xen g_make_formant_bank(Xen frms, Xen amps) { #define H_make_formant_bank "(" S_make_formant_bank " gens amps): return a new formant-bank generator." mus_any *ge = NULL; mus_any **gens; int i, j, size; vct *v = NULL; Xen_check_type(Xen_is_vector(frms), frms, 1, S_make_formant_bank, "a vector of formant generators"); /* need size and elements -> mus_any */ size = Xen_vector_length(frms); if (size == 0) return(Xen_false); gens = (mus_any **)calloc(size, sizeof(mus_any *)); if (Xen_is_bound(amps)) { v = Xen_to_vct(amps); if (!v) Xen_check_type(false, amps, 2, S_make_formant_bank, "a " S_vct " if anything"); } for (i = 0, j = 0; i < size; i++) { Xen g; g = Xen_vector_ref(frms, i); if (mus_is_xen(g)) { mus_any *fg; fg = Xen_to_mus_any(g); if (mus_is_formant(fg)) gens[j++] = fg; } } if (j > 0) ge = mus_make_formant_bank(j, gens, (v) ? mus_vct_data(v) : NULL); free(gens); if (ge) { if (v) return(mus_xen_to_object(mus_any_to_mus_xen_with_two_vcts(ge, frms, amps))); return(mus_xen_to_object(mus_any_to_mus_xen_with_vct(ge, frms))); } return(Xen_false); } static Xen g_is_formant_bank(Xen os) { #define H_is_formant_bank "(" S_is_formant_bank " gen): " PROC_TRUE " if gen is a " S_formant_bank return(C_bool_to_Xen_boolean((mus_is_xen(os)) && (mus_is_formant_bank(Xen_to_mus_any(os))))); } static Xen g_formant_bank(Xen gens, Xen inp) { #define H_formant_bank "(" S_formant_bank " gens inval): sum a bank of " S_formant " generators" mus_any *bank = NULL; mus_xen *gn; Xen_to_C_generator(gens, gn, bank, mus_is_formant_bank, S_formant_bank, "a formant-bank generator"); if (mus_is_vct(inp)) return(C_double_to_Xen_real(mus_formant_bank_with_inputs(bank, mus_vct_data(Xen_to_vct(inp))))); if (Xen_is_number(inp)) return(C_double_to_Xen_real(mus_formant_bank(bank, Xen_real_to_C_double(inp)))); if (!Xen_is_bound(inp)) return(C_double_to_Xen_real(mus_formant_bank(bank, 0.0))); Xen_check_type(false, inp, 2, S_formant_bank, "a number or a " S_vct); return(Xen_false); } /* ---------------- one-pole-all-pass ---------------- */ static Xen g_make_one_pole_all_pass(Xen arg1, Xen arg2) { #define H_make_one_pole_all_pass "(" S_make_one_pole_all_pass " size coeff): return a new one-pole-all-pass generator." mus_any *ge = NULL; int size; mus_float_t coeff; Xen_check_type(Xen_is_integer(arg1), arg1, 1, S_make_one_pole_all_pass, "an integer"); #if (!HAVE_SCHEME) Xen_check_type(Xen_is_number(arg2), arg2, 2, S_make_one_pole_all_pass, "a number"); #endif size = Xen_integer_to_C_int(arg1); if (size < 0) Xen_out_of_range_error(S_make_one_pole_all_pass, 1, arg1, "size < 0?"); if (size == 0) return(Xen_false); coeff = Xen_real_to_C_double(arg2); ge = mus_make_one_pole_all_pass(size, coeff); if (ge) return(mus_xen_to_object(mus_any_to_mus_xen(ge))); return(Xen_false); } static Xen g_is_one_pole_all_pass(Xen os) { #define H_is_one_pole_all_pass "(" S_is_one_pole_all_pass " gen): " PROC_TRUE " if gen is a " S_one_pole_all_pass return(C_bool_to_Xen_boolean((mus_is_xen(os)) && (mus_is_one_pole_all_pass(Xen_to_mus_any(os))))); } static Xen g_one_pole_all_pass(Xen gen, Xen fm) { #define H_one_pole_all_pass "(" S_one_pole_all_pass " gen (input 0.0)): run a one-pole-all-pass generator" mus_float_t in1 = 0.0; mus_any *g = NULL; mus_xen *gn; Xen_to_C_generator(gen, gn, g, mus_is_one_pole_all_pass, S_one_pole_all_pass, "a one-pole-all-pass generator"); Xen_real_to_C_double_if_bound(fm, in1, S_one_pole_all_pass, 2); return(C_double_to_Xen_real(mus_one_pole_all_pass(g, in1))); } /* ---------------- firmant ---------------- */ static Xen g_make_firmant(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_make_firmant "(" S_make_firmant " frequency radius): \ return a new firmant generator (a resonator). radius sets the pole radius (in terms of the 'unit circle'). \ frequency sets the resonance center frequency (Hz)." return(g_make_frm(false, S_make_firmant, arg1, arg2, arg3, arg4)); } static Xen g_is_firmant(Xen os) { #define H_is_firmant "(" S_is_firmant " gen): " PROC_TRUE " if gen is a " S_firmant " generator" return(C_bool_to_Xen_boolean((mus_is_xen(os)) && (mus_is_firmant(Xen_to_mus_any(os))))); } static Xen g_firmant(Xen gen, Xen input, Xen freq) { #define H_firmant "(" S_firmant " gen (input 0.0) freq-in-radians): next sample from resonator generator" mus_float_t in1 = 0.0; mus_any *g = NULL; mus_xen *gn; Xen_to_C_generator(gen, gn, g, mus_is_firmant, S_firmant, "a firmant generator"); Xen_real_to_C_double_if_bound(input, in1, S_firmant, 2); if (Xen_is_bound(freq)) return(C_double_to_Xen_real(mus_firmant_with_frequency(g, in1, Xen_real_to_C_double(freq)))); return(C_double_to_Xen_real(mus_firmant(g, in1))); } static mus_float_t mus_pink_noise(vct *v) { int i, size; mus_float_t sum = 0.0, amp, x; mus_float_t *data; size = mus_vct_length(v); data = mus_vct_data(v); amp = data[0]; for (i = 2, x = 0.5; i < size; i += 2, x *= 0.5) { sum += data[i]; data[i + 1] -= x; if (data[i + 1] < 0.0) { data[i] = mus_random(amp); data[i + 1] += 1.0; } } return(sum + mus_random(amp)); } #define S_pink_noise "pink-noise" static Xen g_pink_noise(Xen gens) { #define H_pink_noise "(pink-noise gens) generates an approximation to pink noise." int size; vct *v; Xen_check_type((mus_is_vct(gens)) && (Xen_vector_rank(gens) == 1), gens, 1, S_pink_noise, "a " S_vct); v = Xen_to_vct(gens); size = mus_vct_length(v); if (size == 0) return(XEN_ZERO); /* needs to be upper case for Forth/Ruby */ Xen_check_type((size & 1) == 0, gens, 1, S_pink_noise, "an even length " S_vct); return(C_double_to_Xen_real(mus_pink_noise(v))); } #if HAVE_SCHEME static s7_double piano_noise(s7_int *g, s7_double noi) { g[0] = ((g[0] * 1103515245) + 12345) & 0xffffffff; noi *= (((s7_double)g[0] * 4.6566128730774e-10) - 1.0); return(noi); } #define S_piano_noise "piano-noise" static Xen g_piano_noise(Xen gen, XEN amp) { #define H_piano_noise "(piano-noise gen amp) generates the noise used in the piano instrument." if (!s7_is_int_vector(gen)) s7_wrong_type_arg_error(s7, S_piano_noise, 1, gen, "an int-vector"); if (!s7_is_real(amp)) s7_wrong_type_arg_error(s7, S_piano_noise, 2, amp, "a real"); return(C_double_to_Xen_real(piano_noise(s7_int_vector_elements(gen), Xen_real_to_C_double(amp)))); } #define S_singer_filter "singer-filter" static Xen g_singer_filter(Xen start, Xen end, Xen tmp, Xen dline1, Xen dline2, Xen coeffs) { #define H_singer_filter "this is an optimization for the singer instrument" int j, k, beg, lim; s7_double *d1, *d2, *cf; s7_double temp, x; if (!s7_is_integer(start)) s7_wrong_type_arg_error(s7, S_singer_filter, 1, start, "an integer"); if (!s7_is_integer(end)) s7_wrong_type_arg_error(s7, S_singer_filter, 2, end, "an integer"); if (!s7_is_real(tmp)) s7_wrong_type_arg_error(s7, S_singer_filter, 3, tmp, "a real"); if (!s7_is_float_vector(dline1)) s7_wrong_type_arg_error(s7, S_singer_filter, 4, dline1, "a float-vector"); if (!s7_is_float_vector(dline2)) s7_wrong_type_arg_error(s7, S_singer_filter, 5, dline2, "a float-vector"); if (!s7_is_float_vector(coeffs)) s7_wrong_type_arg_error(s7, S_singer_filter, 6, coeffs, "a float-vector"); x = 0.0; beg = s7_integer(start); lim = s7_integer(end); d1 = s7_float_vector_elements(dline1); d2 = s7_float_vector_elements(dline2); cf = s7_float_vector_elements(coeffs); temp = s7_number_to_real(s7, tmp); for (k = beg, j = beg + 1; j < lim; k++, j++) { s7_double temp1; x = d2[j + 1]; d2[j] = x + (cf[j] * (d1[k] - x)); temp1 = temp; temp = d1[k] + d2[j] - x; d1[k] = temp1; } return(s7_make_real(s7, temp)); } #define S_singer_nose_filter "singer-nose-filter" static Xen g_singer_nose_filter(Xen end, Xen tmp, Xen dline1, Xen dline2, Xen coeffs) { #define H_singer_nose_filter "this is an optimization for the singer instrument" int j, k, lim; s7_double *d1, *d2, *cf; s7_double reftemp, temp; if (!s7_is_integer(end)) s7_wrong_type_arg_error(s7, S_singer_nose_filter, 1, end, "an integer"); if (!s7_is_real(tmp)) s7_wrong_type_arg_error(s7, S_singer_nose_filter, 2, tmp, "a real"); if (!s7_is_float_vector(dline1)) s7_wrong_type_arg_error(s7, S_singer_nose_filter, 3, dline1, "a float-vector"); if (!s7_is_float_vector(dline2)) s7_wrong_type_arg_error(s7, S_singer_nose_filter, 4, dline2, "a float-vector"); if (!s7_is_float_vector(coeffs)) s7_wrong_type_arg_error(s7, S_singer_nose_filter, 5, coeffs, "a float-vector"); reftemp = 0.0; lim = s7_integer(end); d1 = s7_float_vector_elements(dline1); d2 = s7_float_vector_elements(dline2); cf = s7_float_vector_elements(coeffs); temp = s7_number_to_real(s7, tmp); for (k = 1, j = 2; j < lim; k++, j++) { s7_double t1; reftemp = cf[j] * (d1[k] - d2[j + 1]); d2[j] = d2[j + 1] + reftemp; t1 = temp; temp = d1[k] + reftemp; d1[k] = t1; } return(s7_make_real(s7, temp)); } #endif /* ---------------- wave-train ---------------- */ static Xen g_make_wave_train(Xen arglist) { #define H_make_wave_train "(" S_make_wave_train " (frequency *clm-default-frequency*) (initial-phase 0.0) (wave) (size clm-table-size) (type)): \ return a new wave-train generator (an extension of pulse-train). Frequency is \ the repetition rate of the wave found in wave. Successive waves can overlap." mus_any *ge; Xen args[10]; Xen keys[5]; int orig_arg[5] = {0, 0, 0, 0, MUS_INTERP_LINEAR}; int vals; mus_long_t wsize = clm_table_size; Xen orig_v = Xen_false; mus_float_t freq, phase = 0.0; mus_float_t *wave = NULL; int interp_type = (int)MUS_INTERP_LINEAR; freq = clm_default_frequency; keys[0] = kw_frequency; keys[1] = kw_initial_phase; keys[2] = kw_wave; keys[3] = kw_size; keys[4] = kw_type; { Xen p; int i, arglist_len; arglist_len = Xen_list_length(arglist); if (arglist_len > 10) clm_error(S_make_wave_train, "too many arguments!", arglist); for (i = 0, p = arglist; i < arglist_len; i++, p = Xen_cdr(p)) args[i] = Xen_car(p); for (i = arglist_len; i < 10; i++) args[i] = Xen_undefined; } vals = mus_optkey_unscramble(S_make_wave_train, 5, keys, args, orig_arg); if (vals > 0) { vct *v = NULL; freq = Xen_optkey_to_float(kw_frequency, keys[0], S_make_wave_train, orig_arg[0], freq); if (freq > (0.5 * mus_srate())) Xen_out_of_range_error(S_make_wave_train, orig_arg[0], keys[0], "freq > srate/2?"); if (freq < 0.0) Xen_out_of_range_error(S_make_wave_train, orig_arg[0], keys[0], "freq < 0.0?"); phase = Xen_optkey_to_float(kw_initial_phase, keys[1], S_make_wave_train, orig_arg[1], phase); if (phase < 0.0) Xen_out_of_range_error(S_make_wave_train, orig_arg[1], keys[1], "phase < 0.0?"); v = mus_optkey_to_vct(keys[2], S_make_wave_train, orig_arg[2], NULL); if (v) { orig_v = keys[2]; wave = mus_vct_data(v); wsize = mus_vct_length(v); } wsize = Xen_optkey_to_mus_long_t(kw_size, keys[3], S_make_wave_train, orig_arg[3], wsize); if (wsize <= 0) Xen_out_of_range_error(S_make_wave_train, orig_arg[3], keys[3], "size <= 0?"); if (wsize > mus_max_table_size()) Xen_out_of_range_error(S_make_wave_train, orig_arg[3], keys[3], "size too large (see mus-max-table-size)"); if ((v) && (wsize > mus_vct_length(v))) Xen_out_of_range_error(S_make_wave_train, orig_arg[3], keys[3], "table size > wave size"); interp_type = Xen_optkey_to_int(kw_type, keys[4], S_make_wave_train, orig_arg[4], interp_type); if (!(mus_is_interp_type(interp_type))) Xen_out_of_range_error(S_make_wave_train, orig_arg[4], keys[4], "no such interp-type"); } if (wave == NULL) { wave = (mus_float_t *)calloc(wsize, sizeof(mus_float_t)); if (wave == NULL) return(clm_mus_error(MUS_MEMORY_ALLOCATION_FAILED, "can't allocate wave-train table", S_make_wave_train)); orig_v = xen_make_vct(wsize, wave); } ge = mus_make_wave_train(freq, phase, wave, wsize, (mus_interp_t)interp_type); return(mus_xen_to_object(mus_any_to_mus_xen_with_vct(ge, orig_v))); } static Xen g_wave_train(Xen obj, Xen fm) { #define H_wave_train "(" S_wave_train " gen (fm 0.0)): next sample of " S_wave_train mus_float_t fm1 = 0.0; mus_any *g = NULL; mus_xen *gn; Xen_to_C_generator(obj, gn, g, mus_is_wave_train, S_wave_train, "a wave-train generator"); Xen_real_to_C_double_if_bound(fm, fm1, S_wave_train, 2); return(C_double_to_Xen_real(mus_wave_train(g, fm1))); } static Xen g_is_wave_train(Xen obj) { #define H_is_wave_train "(" S_is_wave_train " gen): " PROC_TRUE " if gen is a " S_wave_train return(C_bool_to_Xen_boolean((mus_is_xen(obj)) && (mus_is_wave_train(Xen_to_mus_any(obj))))); } /* ---------------- waveshaping ---------------- */ enum {NO_PROBLEM_IN_LIST, NULL_LIST, ODD_LENGTH_LIST, NON_NUMBER_IN_LIST, NEGATIVE_NUMBER_IN_LIST, HUGE_NUMBER_IN_LIST}; static const char *list_to_partials_error_to_string(int code) { switch (code) { case NO_PROBLEM_IN_LIST: return("~A: nothing wrong with partials list?? ~A"); break; case NULL_LIST: return("~A: partials list is null, ~A"); break; case ODD_LENGTH_LIST: return("~A: partials list has an odd number of elements: ~A"); break; case NON_NUMBER_IN_LIST: return("~A: partials list has a non-numerical element: ~A"); break; case NEGATIVE_NUMBER_IN_LIST: return("~A: partials list has a partial number that is negative: ~A"); break; case HUGE_NUMBER_IN_LIST: return("~A: partials list has a partial number that is too large: ~A"); break; } return("~A: unknown error, ~A"); } static mus_float_t *list_to_partials(Xen harms, int *npartials, int *error_code) { int listlen, i, maxpartial = 0, curpartial; mus_float_t *partials = NULL; Xen lst; listlen = Xen_list_length(harms); if (listlen == 0) { (*error_code) = NULL_LIST; return(NULL); } if (listlen & 1) { (*error_code) = ODD_LENGTH_LIST; return(NULL); } if (!(Xen_is_number(Xen_car(harms)))) { (*error_code) = NON_NUMBER_IN_LIST; return(NULL); } /* the list is '(partial-number partial-amp ... ) */ (*error_code) = NO_PROBLEM_IN_LIST; for (i = 0, lst = Xen_copy_arg(harms); i < listlen; i += 2, lst = Xen_cddr(lst)) { if ((!(Xen_is_number(Xen_car(lst)))) || (!(Xen_is_number(Xen_cadr(lst))))) { (*error_code) = NON_NUMBER_IN_LIST; return(NULL); } curpartial = Xen_integer_to_C_int(Xen_car(lst)); if (curpartial < 0) { (*error_code) = NEGATIVE_NUMBER_IN_LIST; return(NULL); } if (curpartial > maxpartial) maxpartial = curpartial; } if (maxpartial > 10000000) { (*error_code) = NEGATIVE_NUMBER_IN_LIST; return(NULL); } partials = (mus_float_t *)calloc(maxpartial + 1, sizeof(mus_float_t)); /* here and elsewhere? this won't be null until we touch it in linux, but that gloms up all our * code with once-in-a-billion-years error checks. */ if (partials == NULL) mus_error(MUS_MEMORY_ALLOCATION_FAILED, "can't allocate waveshaping partials list"); (*npartials) = maxpartial + 1; for (i = 0, lst = Xen_copy_arg(harms); i < listlen; i += 2, lst = Xen_cddr(lst)) { curpartial = Xen_integer_to_C_int(Xen_car(lst)); partials[curpartial] = (mus_float_t)Xen_real_to_C_double(Xen_cadr(lst)); } return(partials); } static mus_float_t *mus_vct_to_partials(vct *v, int *npartials, int *error_code) { int len, i, maxpartial, curpartial; mus_float_t *partials = NULL, *vdata; len = mus_vct_length(v); if (len == 0) { (*error_code) = NULL_LIST; return(NULL); } if (len & 1) { (*error_code) = ODD_LENGTH_LIST; return(NULL); } (*error_code) = NO_PROBLEM_IN_LIST; vdata = mus_vct_data(v); maxpartial = (int)(vdata[0]); if (maxpartial < 0) (*error_code) = NEGATIVE_NUMBER_IN_LIST; else { for (i = 2; i < len; i += 2) { curpartial = (int)(vdata[i]); if (curpartial > maxpartial) maxpartial = curpartial; if (curpartial < 0) (*error_code) = NEGATIVE_NUMBER_IN_LIST; } } if ((*error_code) != NO_PROBLEM_IN_LIST) return(NULL); partials = (mus_float_t *)calloc(maxpartial + 1, sizeof(mus_float_t)); if (partials == NULL) mus_error(MUS_MEMORY_ALLOCATION_FAILED, "can't allocate waveshaping partials list"); (*npartials) = maxpartial + 1; for (i = 0; i < len; i += 2) { curpartial = (int)(vdata[i]); partials[curpartial] = vdata[i + 1]; } return(partials); } static mus_float_t *mus_vector_to_partials(Xen v, int *npartials, int *error_code) { int len, i, maxpartial, curpartial; mus_float_t *partials = NULL; len = Xen_vector_length(v); if (len == 0) { (*error_code) = NULL_LIST; return(NULL); } if (len & 1) { (*error_code) = ODD_LENGTH_LIST; return(NULL); } (*error_code) = NO_PROBLEM_IN_LIST; maxpartial = (int)(Xen_integer_to_C_int(Xen_vector_ref(v, 0))); if (maxpartial < 0) (*error_code) = NEGATIVE_NUMBER_IN_LIST; else { for (i = 2; i < len; i += 2) { curpartial = (int)(Xen_integer_to_C_int(Xen_vector_ref(v, i))); if (curpartial > maxpartial) maxpartial = curpartial; if (curpartial < 0) (*error_code) = NEGATIVE_NUMBER_IN_LIST; } } if ((*error_code) != NO_PROBLEM_IN_LIST) return(NULL); partials = (mus_float_t *)calloc(maxpartial + 1, sizeof(mus_float_t)); if (partials == NULL) mus_error(MUS_MEMORY_ALLOCATION_FAILED, "can't allocate waveshaping partials list"); (*npartials) = maxpartial + 1; for (i = 0; i < len; i += 2) { curpartial = (int)(Xen_integer_to_C_int(Xen_vector_ref(v, i))); partials[curpartial] = Xen_real_to_C_double(Xen_vector_ref(v, i + 1)); } return(partials); } static Xen g_partials_to_polynomial(Xen amps, Xen ukind) { #if HAVE_SCHEME #define p2p_example "(let ((v0 (partials->polynomial '(1 1.0 2 1.0)))\n (os (make-oscil)))\n (polynomial v0 (oscil os)))" #endif #if HAVE_RUBY #define p2p_example "v0 = partials2polynomial([1, 1.0, 2, 1.0])\n os = make_oscil()\n polynomial(v0, oscil(os))" #endif #if HAVE_FORTH #define p2p_example "'( 1 1.0 2 1.0 ) partials->polynomial value v0\n make-oscil value os\n v0 os 0.0 0.0 oscil polynomial" #endif #define H_partials_to_polynomial "(" S_partials_to_polynomial " partials (kind " S_mus_chebyshev_first_kind ")): \ produce a Chebyshev polynomial suitable for use with the " S_polynomial " generator \ to create (via waveshaping) the harmonic spectrum described by the partials argument:\n " p2p_example int npartials = 0; mus_polynomial_t kind = MUS_CHEBYSHEV_FIRST_KIND; mus_float_t *partials = NULL, *wave; int error = NO_PROBLEM_IN_LIST; Xen_check_type(mus_is_vct(amps) || Xen_is_list(amps), amps, 1, S_partials_to_polynomial, "a list or a " S_vct); Xen_check_type(Xen_is_integer_or_unbound(ukind), ukind, 2, S_partials_to_polynomial, "either " S_mus_chebyshev_first_kind " or " S_mus_chebyshev_second_kind); if (Xen_is_integer(ukind)) { int ck; ck = Xen_integer_to_C_int(ukind); if ((ck >= MUS_CHEBYSHEV_EITHER_KIND) && (ck <= MUS_CHEBYSHEV_SECOND_KIND)) kind = (mus_polynomial_t)ck; else Xen_out_of_range_error(S_partials_to_polynomial, 2, ukind, "unknown Chebyshev polynomial kind"); } if (mus_is_vct(amps)) partials = mus_vct_to_partials(Xen_to_vct(amps), &npartials, &error); else partials = list_to_partials(amps, &npartials, &error); if (partials == NULL) Xen_error(NO_DATA, Xen_list_3(C_string_to_Xen_string(list_to_partials_error_to_string(error)), C_string_to_Xen_string(S_partials_to_polynomial), amps)); wave = mus_partials_to_polynomial(npartials, partials, kind); /* wave == partials; in both vct and list cases, partials is newly allocated */ return(xen_make_vct(npartials, wave)); } static Xen g_normalize_partials(Xen partials) { #define H_normalize_partials "(" S_normalize_partials " partials) scales the \ partial amplitudes in the " S_vct " or list 'partials' by the inverse of their sum (so that they add to 1.0)." vct *v; Xen xv = Xen_false; Xen_check_type(((Xen_is_list(partials)) && (!Xen_is_null(partials))) || (mus_is_vct(partials)), partials, 1, S_normalize_partials, "a " S_vct " or (non-empty) list"); if (mus_is_vct(partials)) xv = partials; else xv = xen_list_to_vct(partials); v = Xen_to_vct(xv); if ((mus_vct_length(v) > 1) && ((mus_vct_length(v) & 1) == 0)) mus_normalize_partials(mus_vct_length(v) / 2, mus_vct_data(v)); else Xen_error(BAD_TYPE, Xen_list_3(C_string_to_Xen_string("~A: partials, ~A, must be a non-empty list or " S_vct " of even length (partial-number partial-amp ...)"), C_string_to_Xen_string(S_normalize_partials), partials)); return(xv); } static mus_float_t *vector_to_float_array(Xen v) { mus_float_t *data; mus_long_t i, len; len = Xen_vector_length(v); data = (mus_float_t *)malloc(len * sizeof(mus_float_t)); for (i = 0; i < len; i++) data[i] = Xen_real_to_C_double(Xen_vector_ref(v, i)); return(data); } static Xen g_chebyshev_tu_sum(Xen x, Xen tn, Xen un) { #define H_chebyshev_tu_sum "(" S_mus_chebyshev_tu_sum " x tn un) returns the sum of the weighted\ Chebyshev polynomials Tn and Un (vectors or " S_vct "s), with phase x." bool need_free = false; int len = 0; mus_float_t *tdata = NULL, *udata = NULL; Xen result; Xen_check_type(Xen_is_double(x), x, 1, S_mus_chebyshev_tu_sum, "a float"); if ((mus_is_vct(tn)) && (mus_is_vct(un))) { vct *Tn, *Un; Tn = Xen_to_vct(tn); tdata = mus_vct_data(Tn); Un = Xen_to_vct(un); udata = mus_vct_data(Un); len = mus_vct_length(Tn); if (len == 0) return(C_double_to_Xen_real(0.0)); if (len != mus_vct_length(Un)) return(C_double_to_Xen_real(0.0)); } else { if ((Xen_is_vector(tn)) && (Xen_is_vector(un))) { len = Xen_vector_length(tn); if (len == 0) return(C_double_to_Xen_real(0.0)); if (len != Xen_vector_length(un)) return(C_double_to_Xen_real(0.0)); tdata = vector_to_float_array(tn); udata = vector_to_float_array(un); need_free = true; } else { Xen_check_type(false, tn, 1, S_mus_chebyshev_tu_sum, "both arrays should be either " S_vct "s or vectors"); } } result = C_double_to_Xen_real(mus_chebyshev_tu_sum(Xen_real_to_C_double(x), len, tdata, udata)); if (need_free) { free(tdata); free(udata); } return(result); } static Xen g_chebyshev_t_sum(Xen x, Xen tn) { #define H_chebyshev_t_sum "(" S_mus_chebyshev_t_sum " x tn) returns the sum of the weighted \ Chebyshev polynomials Tn (a " S_vct ")." bool need_free = false; int len = 0; mus_float_t *data = NULL; Xen result; Xen_check_type(Xen_is_double(x), x, 1, S_mus_chebyshev_t_sum, "a float"); if (mus_is_vct(tn)) { vct *Tn; Tn = Xen_to_vct(tn); data = mus_vct_data(Tn); len = mus_vct_length(Tn); if (len == 0) return(C_double_to_Xen_real(0.0)); } else { if (Xen_is_vector(tn)) { len = Xen_vector_length(tn); if (len == 0) return(C_double_to_Xen_real(0.0)); data = vector_to_float_array(tn); need_free = true; } else Xen_check_type(false, tn, 1, S_mus_chebyshev_t_sum, "a " S_vct " or a vector"); } result = C_double_to_Xen_real(mus_chebyshev_t_sum(Xen_real_to_C_double(x), len, data)); if (need_free) free(data); return(result); } static Xen g_chebyshev_u_sum(Xen x, Xen un) { #define H_chebyshev_u_sum "(" S_mus_chebyshev_u_sum " x un) returns the sum of the weighted \ Chebyshev polynomials Un (a " S_vct ")." bool need_free = false; int len = 0; mus_float_t *data = NULL; Xen result; Xen_check_type(Xen_is_double(x), x, 1, S_mus_chebyshev_u_sum, "a float"); if (mus_is_vct(un)) { vct *Un; Un = Xen_to_vct(un); len = mus_vct_length(Un); if (len == 0) return(C_double_to_Xen_real(0.0)); data = mus_vct_data(Un); } else { if (Xen_is_vector(un)) { len = Xen_vector_length(un); if (len == 0) return(C_double_to_Xen_real(0.0)); data = vector_to_float_array(un); need_free = true; } else Xen_check_type(false, un, 1, S_mus_chebyshev_u_sum, "a " S_vct " or a vector"); } result = C_double_to_Xen_real(mus_chebyshev_u_sum(Xen_real_to_C_double(x), len, data)); if (need_free) free(data); return(result); } /* ---------------- polyshape ---------------- */ static Xen g_polyshape(Xen obj, Xen index, Xen fm) { #define H_polyshape "(" S_polyshape " gen (index 1.0) (fm 0.0)): next sample of polynomial-based waveshaper" mus_float_t fm1 = 0.0, index1 = 1.0; mus_any *g = NULL; mus_xen *gn; Xen_to_C_generator(obj, gn, g, mus_is_polyshape, S_polyshape, "a polyshape generator"); Xen_real_to_C_double_if_bound(index, index1, S_polyshape, 2); Xen_real_to_C_double_if_bound(fm, fm1, S_polyshape, 3); return(C_double_to_Xen_real(mus_polyshape(g, index1, fm1))); } static Xen g_is_polyshape(Xen obj) { #define H_is_polyshape "(" S_is_polyshape " gen): " PROC_TRUE " if gen is a " S_polyshape return(C_bool_to_Xen_boolean((mus_is_xen(obj)) && (mus_is_polyshape(Xen_to_mus_any(obj))))); } static Xen g_make_polyshape(Xen arglist) { #define H_make_polyshape "(" S_make_polyshape " (frequency *clm-default-frequency*) (initial-phase 0.0) (coeffs) (partials '(1 1)) (kind " S_mus_chebyshev_first_kind ")): \ return a new polynomial-based waveshaping generator:\n\ (" S_make_polyshape " :coeffs (" S_partials_to_polynomial " '(1 1.0)))\n\ is the same in effect as " S_make_oscil mus_any *ge; Xen args[10]; Xen keys[5]; int orig_arg[5] = {0, 0, 0, 0, 0}; int vals, csize = 0, npartials = 0; Xen orig_v = Xen_false; mus_float_t freq, phase = 0.0; /* * if we followed the definition directly, the initial phase default would be M_PI_2 (pi/2) so that * we drive the Tn's with a cosine. But I've always used sine instead, so I think I'll leave * it that way. There is no difference in the output waveform except an overall phase * offset. So, with sine, the phases rotate through cos sin -cos -sin... rather than being all cos, * but these add to exactly the same actual wave -- what you'd expect since Tn doesn't know * where we started. This also does not affect "signification". */ mus_float_t *coeffs = NULL; mus_polynomial_t kind = MUS_CHEBYSHEV_FIRST_KIND; freq = clm_default_frequency; keys[0] = kw_frequency; keys[1] = kw_initial_phase; keys[2] = kw_coeffs; keys[3] = kw_partials; keys[4] = kw_kind; { int i, arglist_len; Xen p; arglist_len = Xen_list_length(arglist); if (arglist_len > 10) clm_error(S_make_polyshape, "too many arguments!", arglist); for (i = 0, p = arglist; i < arglist_len; i++, p = Xen_cdr(p)) args[i] = Xen_car(p); for (i = arglist_len; i < 10; i++) args[i] = Xen_undefined; } vals = mus_optkey_unscramble(S_make_polyshape, 5, keys, args, orig_arg); if (vals > 0) { vct *v = NULL; int ck; freq = Xen_optkey_to_float(kw_frequency, keys[0], S_make_polyshape, orig_arg[0], freq); if (freq > (0.5 * mus_srate())) Xen_out_of_range_error(S_make_polyshape, orig_arg[0], keys[0], "freq > srate/2?"); phase = Xen_optkey_to_float(kw_initial_phase, keys[1], S_make_polyshape, orig_arg[2], phase); ck = Xen_optkey_to_int(kw_kind, keys[4], S_make_polyshape, orig_arg[4], (int)kind); if ((ck >= MUS_CHEBYSHEV_EITHER_KIND) && (ck <= MUS_CHEBYSHEV_SECOND_KIND)) kind = (mus_polynomial_t)ck; else Xen_out_of_range_error(S_make_polyshape, orig_arg[4], keys[4], "unknown Chebyshev polynomial kind"); v = mus_optkey_to_vct(keys[2], S_make_polyshape, orig_arg[2], NULL); if (v) { orig_v = keys[2]; coeffs = mus_vct_data(v); csize = mus_vct_length(v); } else { if (!(Xen_is_keyword(keys[3]))) { mus_float_t *partials = NULL; int error = NO_PROBLEM_IN_LIST; if (mus_is_vct(keys[3])) partials = mus_vct_to_partials(Xen_to_vct(keys[3]), &npartials, &error); else { Xen_check_type(Xen_is_list(keys[3]), keys[3], orig_arg[3], S_make_polyshape, "a list or a " S_vct); partials = list_to_partials(keys[3], &npartials, &error); } if (partials == NULL) Xen_error(NO_DATA, Xen_list_3(C_string_to_Xen_string(list_to_partials_error_to_string(error)), C_string_to_Xen_string(S_make_polyshape), keys[3])); coeffs = mus_partials_to_polynomial(npartials, partials, kind); csize = npartials; /* coeffs = partials here, so don't delete */ } } } if (!coeffs) { /* clm.html says '(1 1) is the default */ mus_float_t *data; data = (mus_float_t *)malloc(2 * sizeof(mus_float_t)); data[0] = 0.0; data[1] = 1.0; coeffs = mus_partials_to_polynomial(2, data, kind); csize = 2; } if (Xen_is_false(orig_v)) orig_v = xen_make_vct(csize, coeffs); ge = mus_make_polyshape(freq, phase, coeffs, csize, kind); if (ge) return(mus_xen_to_object(mus_any_to_mus_xen_with_vct(ge, orig_v))); return(Xen_false); } /* ---------------- polywave ---------------- */ static Xen g_polywave(Xen obj, Xen fm) { #define H_polywave "(" S_polywave " gen (fm 0.0)): next sample of polywave waveshaper" mus_float_t fm1 = 0.0; mus_any *g = NULL; mus_xen *gn; Xen_to_C_generator(obj, gn, g, mus_is_polywave, S_polywave, "a polywave generator"); Xen_real_to_C_double_if_bound(fm, fm1, S_polywave, 3); return(C_double_to_Xen_real(mus_polywave(g, fm1))); } static Xen g_is_polywave(Xen obj) { #define H_is_polywave "(" S_is_polywave " gen): " PROC_TRUE " if gen is a " S_polywave " generator" return(C_bool_to_Xen_boolean((mus_is_xen(obj)) && (mus_is_polywave(Xen_to_mus_any(obj))))); } static Xen g_make_polywave(Xen arglist) { #define H_make_polywave "(" S_make_polywave " (frequency *clm-default-frequency*) (partials '(1 1)) (type " S_mus_chebyshev_first_kind ") xcoeffs ycoeffs): \ return a new polynomial-based waveshaping generator. (" S_make_polywave " :partials (float-vector 1 1.0)) is the same in effect as " S_make_oscil "." mus_any *ge; Xen args[10]; Xen keys[5]; int orig_arg[5] = {0, 0, 0, 0, 0}; int vals, n = 0, npartials = 0; Xen orig_x = Xen_false, orig_y = Xen_false; mus_float_t freq; mus_float_t *xcoeffs = NULL, *ycoeffs = NULL, *partials = NULL; mus_polynomial_t kind = MUS_CHEBYSHEV_FIRST_KIND; int error = NO_PROBLEM_IN_LIST; freq = clm_default_frequency; keys[0] = kw_frequency; keys[1] = kw_partials; keys[2] = kw_type; keys[3] = kw_x_coeffs; keys[4] = kw_y_coeffs; { int i, arglist_len; Xen p; arglist_len = Xen_list_length(arglist); if (arglist_len > 10) clm_error(S_make_polywave, "too many arguments!", arglist); for (i = 0, p = arglist; i < arglist_len; i++, p = Xen_cdr(p)) args[i] = Xen_car(p); for (i = arglist_len; i < 10; i++) args[i] = Xen_undefined; } vals = mus_optkey_unscramble(S_make_polywave, 5, keys, args, orig_arg); if (vals > 0) { vct *v; int type; freq = Xen_optkey_to_float(kw_frequency, keys[0], S_make_polywave, orig_arg[0], freq); if (freq > (0.5 * mus_srate())) Xen_out_of_range_error(S_make_polywave, orig_arg[0], keys[0], "freq > srate/2?"); type = Xen_optkey_to_int(kw_type, keys[2], S_make_polywave, orig_arg[2], (int)kind); if ((type >= MUS_CHEBYSHEV_EITHER_KIND) && (type <= MUS_CHEBYSHEV_BOTH_KINDS)) kind = (mus_polynomial_t)type; else Xen_out_of_range_error(S_make_polywave, orig_arg[2], keys[2], "unknown Chebyshev polynomial kind"); if (!(Xen_is_keyword(keys[1]))) /* partials were supplied */ { if (mus_is_vct(keys[1])) partials = mus_vct_to_partials(Xen_to_vct(keys[1]), &npartials, &error); else { if (Xen_is_vector(keys[1])) partials = mus_vector_to_partials(keys[1], &npartials, &error); else { Xen_check_type(Xen_is_list(keys[1]), keys[1], orig_arg[1], S_make_polywave, "a list or a " S_vct); partials = list_to_partials(keys[1], &npartials, &error); } } if (partials == NULL) /* here if null, something went wrong in the translation functions */ Xen_error(NO_DATA, Xen_list_3(C_string_to_Xen_string(list_to_partials_error_to_string(error)), C_string_to_Xen_string(S_make_polywave), keys[1])); xcoeffs = partials; n = npartials; orig_x = xen_make_vct(n, xcoeffs); /* xcoeffs = partials here, so don't delete */ } if (!(Xen_is_keyword(keys[3]))) { Xen_check_type(mus_is_vct(keys[3]), keys[3], orig_arg[3], S_make_polywave, "a " S_vct); orig_x = keys[3]; v = Xen_to_vct(orig_x); n = mus_vct_length(v); xcoeffs = mus_vct_data(v); } if (!(Xen_is_keyword(keys[4]))) { /* make-polyoid in generators.scm */ int yn; Xen_check_type(mus_is_vct(keys[4]), keys[4], orig_arg[4], S_make_polywave, "a " S_vct); orig_y = keys[4]; v = Xen_to_vct(orig_y); yn = mus_vct_length(v); if ((n == 0) || (yn < n)) n = yn; ycoeffs = mus_vct_data(v); } } if (!xcoeffs) { /* clm.html says '(1 1) is the default but table-lookup is 0? */ mus_float_t *data; data = (mus_float_t *)malloc(2 * sizeof(mus_float_t)); data[0] = 0.0; data[1] = 1.0; xcoeffs = data; n = 2; orig_x = xen_make_vct(n, xcoeffs); } if (ycoeffs) { ge = mus_make_polywave_tu(freq, xcoeffs, ycoeffs, n); if (ge) return(mus_xen_to_object(mus_any_to_mus_xen_with_two_vcts(ge, orig_x, orig_y))); } ge = mus_make_polywave(freq, xcoeffs, n, kind); if (ge) return(mus_xen_to_object(mus_any_to_mus_xen_with_vct(ge, orig_x))); return(Xen_false); } /* ---------------- nrxysin and nrxycos ---------------- */ static Xen g_is_nrxysin(Xen obj) { #define H_is_nrxysin "(" S_is_nrxysin " gen): " PROC_TRUE " if gen is an " S_nrxysin " generator" return(C_bool_to_Xen_boolean((mus_is_xen(obj)) && (mus_is_nrxysin(Xen_to_mus_any(obj))))); } static Xen g_is_nrxycos(Xen obj) { #define H_is_nrxycos "(" S_is_nrxycos " gen): " PROC_TRUE " if gen is an " S_nrxycos " generator" return(C_bool_to_Xen_boolean((mus_is_xen(obj)) && (mus_is_nrxycos(Xen_to_mus_any(obj))))); } static Xen g_nrxysin(Xen obj, Xen fm) { #define H_nrxysin "(" S_nrxysin " gen (fm 0.0)): next sample of nrxysin generator" mus_float_t fm1 = 0.0; mus_any *g = NULL; mus_xen *gn; Xen_to_C_generator(obj, gn, g, mus_is_nrxysin, S_nrxysin, "an nrxysin generator"); Xen_real_to_C_double_if_bound(fm, fm1, S_nrxysin, 2); return(C_double_to_Xen_real(mus_nrxysin(g, fm1))); } static Xen g_nrxycos(Xen obj, Xen fm) { #define H_nrxycos "(" S_nrxycos " gen (fm 0.0)): next sample of nrxycos generator" mus_float_t fm1 = 0.0; mus_any *g = NULL; mus_xen *gn; Xen_to_C_generator(obj, gn, g, mus_is_nrxycos, S_nrxycos, "an nrxycos generator"); Xen_real_to_C_double_if_bound(fm, fm1, S_nrxycos, 2); return(C_double_to_Xen_real(mus_nrxycos(g, fm1))); } static Xen g_make_nrxy(bool sin_case, const char *caller, Xen arglist) { mus_any *ge; Xen args[8]; Xen keys[4]; int orig_arg[4] = {0, 0, 0, 0}; int vals; mus_float_t freq, r = 0.5, ratio = 1.0; int n = 1; freq = clm_default_frequency; keys[0] = kw_frequency; keys[1] = kw_ratio; keys[2] = kw_n; keys[3] = kw_r; { int i, arglist_len; Xen p; arglist_len = Xen_list_length(arglist); if (arglist_len > 8) clm_error(caller, "too many arguments!", arglist); for (i = 0, p = arglist; i < arglist_len; i++, p = Xen_cdr(p)) args[i] = Xen_car(p); for (i = arglist_len; i < 8; i++) args[i] = Xen_undefined; } vals = mus_optkey_unscramble(caller, 4, keys, args, orig_arg); if (vals > 0) { freq = Xen_optkey_to_float(kw_frequency, keys[0], caller, orig_arg[0], freq); if (freq > (0.5 * mus_srate())) Xen_out_of_range_error(caller, orig_arg[0], keys[0], "freq > srate/2?"); ratio = Xen_optkey_to_float(kw_ratio, keys[1], caller, orig_arg[1], ratio); n = Xen_optkey_to_int(kw_n, keys[2], caller, orig_arg[2], n); if (n < 0) Xen_out_of_range_error(caller, orig_arg[2], keys[2], "n (sidebands) < 0?"); r = Xen_optkey_to_float(kw_r, keys[3], caller, orig_arg[3], r); if ((r >= 1.0) || (r <= -1.0)) Xen_out_of_range_error(caller, orig_arg[3], keys[3], "r (sideband amp ratio) not within -1.0 to 1.0?"); /* if not with doubles, this actually maxes out around .99999999 because mus_optkey_to_float (apparently) rounds up */ } if (sin_case) ge = mus_make_nrxysin(freq, ratio, n, r); else ge = mus_make_nrxycos(freq, ratio, n, r); if (ge) return(mus_xen_to_object(mus_any_to_mus_xen(ge))); return(Xen_false); } static Xen g_make_nrxysin(Xen arglist) { #define H_make_nrxysin "(" S_make_nrxysin " (frequency *clm-default-frequency*) (ratio 1.0) (n 1) (r 0.5)): \ return a new nrxysin generator." return(g_make_nrxy(true, S_make_nrxysin, arglist)); } static Xen g_make_nrxycos(Xen arglist) { #define H_make_nrxycos "(" S_make_nrxycos " (frequency *clm-default-frequency*) (ratio 1.0) (n 1) (r 0.5)): \ return a new nrxycos generator." return(g_make_nrxy(false, S_make_nrxycos, arglist)); } /* ---------------- rxyksin and rxykcos ---------------- */ static Xen g_is_rxyksin(Xen obj) { #define H_is_rxyksin "(" S_is_rxyksin " gen): " PROC_TRUE " if gen is an " S_rxyksin " generator" return(C_bool_to_Xen_boolean((mus_is_xen(obj)) && (mus_is_rxyksin(Xen_to_mus_any(obj))))); } static Xen g_is_rxykcos(Xen obj) { #define H_is_rxykcos "(" S_is_rxykcos " gen): " PROC_TRUE " if gen is an " S_rxykcos " generator" return(C_bool_to_Xen_boolean((mus_is_xen(obj)) && (mus_is_rxykcos(Xen_to_mus_any(obj))))); } static Xen g_rxyksin(Xen obj, Xen fm) { #define H_rxyksin "(" S_rxyksin " gen (fm 0.0)): next sample of rxyksin generator" mus_float_t fm1 = 0.0; mus_any *g = NULL; mus_xen *gn; Xen_to_C_generator(obj, gn, g, mus_is_rxyksin, S_rxyksin, "an rxyksin generator"); Xen_real_to_C_double_if_bound(fm, fm1, S_rxyksin, 2); return(C_double_to_Xen_real(mus_rxyksin(g, fm1))); } static Xen g_rxykcos(Xen obj, Xen fm) { #define H_rxykcos "(" S_rxykcos " gen (fm 0.0)): next sample of rxykcos generator" mus_float_t fm1 = 0.0; mus_any *g = NULL; mus_xen *gn; Xen_to_C_generator(obj, gn, g, mus_is_rxykcos, S_rxykcos, "an rxykcos generator"); Xen_real_to_C_double_if_bound(fm, fm1, S_rxykcos, 2); return(C_double_to_Xen_real(mus_rxykcos(g, fm1))); } static Xen g_make_rxyk(bool sin_case, const char *caller, Xen arglist) { mus_any *ge; Xen args[6]; Xen keys[3]; int orig_arg[3] = {0, 0, 0}; int vals; mus_float_t freq, r = 0.5, ratio = 1.0; /* original in generators.scm assumes initial-phase = 0.0 */ freq = clm_default_frequency; keys[0] = kw_frequency; keys[1] = kw_ratio; keys[2] = kw_r; { int i, arglist_len; Xen p; arglist_len = Xen_list_length(arglist); if (arglist_len > 6) clm_error(caller, "too many arguments!", arglist); for (i = 0, p = arglist; i < arglist_len; i++, p = Xen_cdr(p)) args[i] = Xen_car(p); for (i = arglist_len; i < 6; i++) args[i] = Xen_undefined; } vals = mus_optkey_unscramble(caller, 3, keys, args, orig_arg); if (vals > 0) { freq = Xen_optkey_to_float(kw_frequency, keys[0], caller, orig_arg[0], freq); if (freq > (0.5 * mus_srate())) Xen_out_of_range_error(caller, orig_arg[0], keys[0], "freq > srate/2?"); ratio = Xen_optkey_to_float(kw_ratio, keys[1], caller, orig_arg[1], ratio); r = Xen_optkey_to_float(kw_r, keys[2], caller, orig_arg[2], r); } if (sin_case) ge = mus_make_rxyksin(freq, 0.0, r, ratio); else ge = mus_make_rxykcos(freq, 0.0, r, ratio); if (ge) return(mus_xen_to_object(mus_any_to_mus_xen(ge))); return(Xen_false); } static Xen g_make_rxyksin(Xen arglist) { #define H_make_rxyksin "(" S_make_rxyksin " (frequency *clm-default-frequency*) (initial-phase 0.0) (ratio 1.0) (r 0.5)): \ return a new rxyksin generator." return(g_make_rxyk(true, S_make_rxyksin, arglist)); } static Xen g_make_rxykcos(Xen arglist) { #define H_make_rxykcos "(" S_make_rxykcos " (frequency *clm-default-frequency*) (initial-phase 0.0) (ratio 1.0) (r 0.5)): \ return a new rxykcos generator." return(g_make_rxyk(false, S_make_rxykcos, arglist)); } /* ---------------- filter ---------------- */ typedef enum {G_FILTER, G_FIR_FILTER, G_IIR_FILTER} xclm_fir_t; static Xen g_make_fir_coeffs(Xen order, Xen envl) { #define H_make_fir_coeffs "(" S_make_fir_coeffs " order v): turn spectral envelope in " S_vct " v into coeffs for FIR filter" int size; mus_float_t *a; vct *v; Xen_check_type(Xen_is_integer(order), order, 1, S_make_fir_coeffs, "int"); Xen_check_type(mus_is_vct(envl), envl, 2, S_make_fir_coeffs, "a " S_vct); v = Xen_to_vct(envl); size = Xen_integer_to_C_int(order); if (size != mus_vct_length(v)) Xen_error(CLM_ERROR, Xen_list_3(C_string_to_Xen_string(S_make_fir_coeffs ": order ~A != " S_vct " length ~A"), order, envl)); a = mus_make_fir_coeffs(Xen_integer_to_C_int(order), mus_vct_data(v), NULL); return(xen_make_vct(mus_vct_length(v), a)); } static Xen g_is_filter(Xen obj) { #define H_is_filter "(" S_is_filter " gen): " PROC_TRUE " if gen is a " S_filter return(C_bool_to_Xen_boolean((mus_is_xen(obj)) && (mus_is_filter(Xen_to_mus_any(obj))))); } static Xen g_is_fir_filter(Xen obj) { #define H_is_fir_filter "(" S_is_fir_filter " gen): " PROC_TRUE " if gen is an " S_fir_filter return(C_bool_to_Xen_boolean((mus_is_xen(obj)) && (mus_is_fir_filter(Xen_to_mus_any(obj))))); } static Xen g_is_iir_filter(Xen obj) { #define H_is_iir_filter "(" S_is_iir_filter " gen): " PROC_TRUE " if gen is an " S_iir_filter return(C_bool_to_Xen_boolean((mus_is_xen(obj)) && (mus_is_iir_filter(Xen_to_mus_any(obj))))); } static Xen g_filter(Xen obj, Xen input) { #define H_filter "(" S_filter " gen (input 0.0)): next sample from filter" mus_any *g = NULL; mus_xen *gn; mus_float_t x = 0.0; Xen_to_C_generator(obj, gn, g, mus_is_filter, S_filter, "a filter"); Xen_real_to_C_double_if_bound(input, x, S_filter, 2); return(C_double_to_Xen_real(mus_filter(g, x))); } static Xen g_fir_filter(Xen obj, Xen input) { #define H_fir_filter "(" S_fir_filter " gen (input 0.0)): next sample from FIR filter" mus_any *g = NULL; mus_xen *gn; mus_float_t x = 0.0; Xen_to_C_generator(obj, gn, g, mus_is_fir_filter, S_fir_filter, "an FIR filter"); Xen_real_to_C_double_if_bound(input, x, S_fir_filter, 2); return(C_double_to_Xen_real(mus_fir_filter(g, x))); } static Xen g_iir_filter(Xen obj, Xen input) { #define H_iir_filter "(" S_iir_filter " gen (input 0.0)): next sample from IIR filter" mus_any *g = NULL; mus_xen *gn; mus_float_t x = 0.0; Xen_to_C_generator(obj, gn, g, mus_is_iir_filter, S_iir_filter, "an IIR filter"); Xen_real_to_C_double_if_bound(input, x, S_iir_filter, 2); return(C_double_to_Xen_real(mus_iir_filter(g, x))); } static Xen g_make_filter_1(xclm_fir_t choice, Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6) { Xen xwave = Xen_undefined, ywave = Xen_undefined; mus_any *fgen = NULL; Xen args[8]; Xen keys[4]; int orig_arg[4] = {0, 0, 0, 0}; vct *x = NULL, *y = NULL; int vals, order = 0; const char *caller; if (choice == G_FILTER) caller = S_make_filter; else if (choice == G_FIR_FILTER) caller = S_make_fir_filter; else caller = S_make_iir_filter; keys[0] = kw_order; keys[1] = kw_x_coeffs; keys[2] = kw_y_coeffs; keys[3] = kw_coeffs; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; args[6] = Xen_undefined; args[7] = Xen_undefined; vals = mus_optkey_unscramble(caller, 4, keys, args, orig_arg); if (vals > 0) { if (!(Xen_is_keyword(keys[0]))) { order = Xen_optkey_to_int(kw_order, keys[0], caller, orig_arg[0], 0); if (order <= 0) Xen_out_of_range_error(caller, orig_arg[0], keys[0], "order <= 0?"); } if (!(Xen_is_keyword(keys[1]))) { Xen_check_type(mus_is_vct(keys[1]), keys[1], orig_arg[1], caller, "a " S_vct); if (choice == G_IIR_FILTER) { ywave = keys[1]; y = Xen_to_vct(ywave); } else { xwave = keys[1]; x = Xen_to_vct(xwave); } } if (!(Xen_is_keyword(keys[2]))) { Xen_check_type(mus_is_vct(keys[2]), keys[2], orig_arg[2], caller, "a " S_vct); ywave = keys[2]; y = Xen_to_vct(ywave); } if ((choice != G_FILTER) && (!(Xen_is_keyword(keys[3])))) { if (choice == G_IIR_FILTER) clm_error(caller, "redundant arg passed to " S_make_iir_filter "?", keys[3]); else clm_error(caller, "redundant arg passed to " S_make_fir_filter "?", keys[3]); } } if (choice == G_FILTER) { if (y == NULL) choice = G_FIR_FILTER; else { if (x == NULL) choice = G_IIR_FILTER; } } if (((x == NULL) && (choice != G_IIR_FILTER)) || ((y == NULL) && (choice != G_FIR_FILTER))) Xen_error(NO_DATA, Xen_list_2(C_string_to_Xen_string("~A: no coeffs?"), C_string_to_Xen_string(caller))); if (order == 0) { if (x) order = mus_vct_length(x); else order = mus_vct_length(y); } else { if ((x) && (order > mus_vct_length(x))) { Xen_error(CLM_ERROR, Xen_list_4(C_string_to_Xen_string("~A: xcoeffs, ~A, must match order, ~A"), C_string_to_Xen_string(caller), keys[1], keys[0])); } else { if ((y) && (order > mus_vct_length(y))) Xen_error(CLM_ERROR, Xen_list_4(C_string_to_Xen_string("~A: ycoeffs, ~A, must match order, ~A"), C_string_to_Xen_string(caller), keys[2], keys[0])); else { if ((x) && (y) && (mus_vct_length(x) != mus_vct_length(y))) Xen_error(CLM_ERROR, Xen_list_4(C_string_to_Xen_string("~A: coeffs must be same length. x len: ~A, y len: ~A"), C_string_to_Xen_string(caller), C_int_to_Xen_integer(mus_vct_length(x)), C_int_to_Xen_integer(mus_vct_length(y)))); } } } switch (choice) { case G_FILTER: fgen = mus_make_filter(order, mus_vct_data(x), mus_vct_data(y), NULL); break; case G_FIR_FILTER: fgen = mus_make_fir_filter(order, mus_vct_data(x), NULL); break; case G_IIR_FILTER: fgen = mus_make_iir_filter(order, mus_vct_data(y), NULL); break; } if (fgen) { mus_xen *gn = NULL; gn = mx_alloc(3); gn->gen = fgen; /* delay gn allocation since make_filter can throw an error */ gn->vcts[G_FILTER_STATE] = xen_make_vct_wrapper(order, mus_data(fgen)); gn->vcts[G_FILTER_XCOEFFS] = xwave; gn->vcts[G_FILTER_YCOEFFS] = ywave; return(mus_xen_to_object(gn)); } return(Xen_false); } static Xen g_make_filter(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6) { #define H_make_filter "(" S_make_filter " order xcoeffs ycoeffs): return a new direct form FIR/IIR filter, coeff args are " S_vct "s" return(g_make_filter_1(G_FILTER, arg1, arg2, arg3, arg4, arg5, arg6)); } static Xen g_make_fir_filter(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_make_fir_filter "(" S_make_fir_filter " order xcoeffs): return a new FIR filter, xcoeffs a " S_vct return(g_make_filter_1(G_FIR_FILTER, arg1, arg2, arg3, arg4, Xen_undefined, Xen_undefined)); } static Xen g_make_iir_filter(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_make_iir_filter "(" S_make_iir_filter " order ycoeffs): return a new IIR filter, ycoeffs a " S_vct return(g_make_filter_1(G_IIR_FILTER, arg1, arg2, arg3, arg4, Xen_undefined, Xen_undefined)); } /* ---------------- env ---------------- */ static Xen g_is_env(Xen obj) { #define H_is_env "(" S_is_env " gen): " PROC_TRUE " if gen is a " S_env return(C_bool_to_Xen_boolean((mus_is_xen(obj)) && (mus_is_env(Xen_to_mus_any(obj))))); } static Xen g_env(Xen obj) { #define H_env "(" S_env " gen): next sample from envelope generator" mus_any *g = NULL; mus_xen *gn; Xen_to_C_generator(obj, gn, g, mus_is_env, S_env, "an env generator"); return(C_double_to_Xen_real(mus_env(g))); } static Xen g_make_env(Xen arglist) { #define H_make_env "(" S_make_env " envelope (scaler 1.0) (duration) (offset 0.0) (base 1.0) (end) (length)): \ return a new envelope generator. 'envelope' is a list, vector, or " S_vct " of break-point pairs. To create the envelope, \ these points are offset by 'offset', scaled by 'scaler', and mapped over the time interval defined by \ either 'duration' (seconds) or 'length' (samples). If 'base' is 1.0, the connecting segments \ are linear, if 0.0 you get a step function, and anything else produces an exponential connecting segment." mus_any *ge; Xen args[14]; Xen keys[7]; int orig_arg[7] = {0, 0, 0, 0, 0, 0, 0}; int vals, i; mus_float_t base = 1.0, scaler = 1.0, offset = 0.0, duration = 0.0; mus_long_t end = 0, dur = -1; int npts = 0; mus_float_t *brkpts = NULL; vct *v = NULL; keys[0] = kw_envelope; keys[1] = kw_scaler; keys[2] = kw_duration; keys[3] = kw_offset; keys[4] = kw_base; keys[5] = kw_end; keys[6] = kw_length; { int arglist_len; Xen p; arglist_len = Xen_list_length(arglist); if (arglist_len > 14) clm_error(S_make_env, "too many arguments!", arglist); for (i = 0, p = arglist; i < arglist_len; i++, p = Xen_cdr(p)) args[i] = Xen_car(p); for (i = arglist_len; i < 14; i++) args[i] = Xen_undefined; } vals = mus_optkey_unscramble(S_make_env, 7, keys, args, orig_arg); if (vals > 0) { scaler = Xen_optkey_to_float(kw_scaler, keys[1], S_make_env, orig_arg[1], 1.0); duration = Xen_optkey_to_float(kw_duration, keys[2], S_make_env, orig_arg[2], 0.0); if ((duration < 0.0) || ((duration == 0.0) && (!Xen_is_keyword(keys[2])))) Xen_out_of_range_error(S_make_env, orig_arg[2], keys[2], "duration <= 0.0?"); offset = Xen_optkey_to_float(kw_offset, keys[3], S_make_env, orig_arg[3], 0.0); base = Xen_optkey_to_float(kw_base, keys[4], S_make_env, orig_arg[4], 1.0); if (base < 0.0) Xen_out_of_range_error(S_make_env, orig_arg[4], keys[4], "base < 0.0?"); end = Xen_optkey_to_mus_long_t(kw_end, keys[5], S_make_env, orig_arg[5], 0); if (end < 0) Xen_out_of_range_error(S_make_env, orig_arg[5], keys[5], "end < 0?"); dur = Xen_optkey_to_mus_long_t(kw_length, keys[6], S_make_env, orig_arg[6], 0); if (dur < 0) Xen_out_of_range_error(S_make_env, orig_arg[6], keys[6], "length < 0?"); /* env data is a list, checked last to let the preceding throw wrong-type error before calloc */ if (!(Xen_is_keyword(keys[0]))) { int len; Xen vect = XEN_NULL; if (mus_is_vct(keys[0])) { v = Xen_to_vct(keys[0]); len = mus_vct_length(v); if ((len < 2) || (len & 1)) Xen_error(BAD_TYPE, Xen_list_2(C_string_to_Xen_string(S_make_env ": " S_vct " is a bogus breakpoints list, ~A"), keys[0])); } else { #if HAVE_SCHEME /* in Ruby and Forth vectors and lists are the same, so stay with the old code */ if (Xen_is_vector(keys[0])) { vect = keys[0]; len = Xen_vector_length(vect); if ((len < 2) || (len & 1)) Xen_error(BAD_TYPE, Xen_list_2(C_string_to_Xen_string(S_make_env ": vector is a bogus breakpoints list, ~A"), vect)); } else { #endif Xen_check_type(Xen_is_list(keys[0]), keys[0], orig_arg[0], S_make_env, "a list, vector, or " S_vct); len = Xen_list_length(keys[0]); if (len == 0) Xen_error(NO_DATA, Xen_list_2(C_string_to_Xen_string(S_make_env ": null env? ~A"), keys[0])); if (Xen_is_list(Xen_car(keys[0]))) len *= 2; else { if (len & 1) Xen_error(BAD_TYPE, Xen_list_2(C_string_to_Xen_string(S_make_env ": odd length breakpoints list? ~A"), keys[0])); if (!(Xen_is_number(Xen_car(keys[0])))) Xen_check_type(false, keys[0], orig_arg[0], S_make_env, "a list of numbers (breakpoints)"); } } #if HAVE_SCHEME } #endif npts = len / 2; if (v) brkpts = mus_vct_data(v); else { brkpts = (mus_float_t *)malloc(len * sizeof(mus_float_t)); if (brkpts == NULL) return(clm_mus_error(MUS_MEMORY_ALLOCATION_FAILED, "can't allocate env list", S_make_env)); if (vect) { for (i = 0; i < len; i++) brkpts[i] = Xen_real_to_C_double(Xen_vector_ref(vect, i)); } else { Xen lst; if (Xen_is_number(Xen_car(keys[0]))) { for (i = 0, lst = Xen_copy_arg(keys[0]); (i < len) && (!Xen_is_null(lst)); i++, lst = Xen_cdr(lst)) brkpts[i] = Xen_real_to_C_double(Xen_car(lst)); } else { for (i = 0, lst = Xen_copy_arg(keys[0]); (i < len) && (!Xen_is_null(lst)); i += 2, lst = Xen_cdr(lst)) { Xen el; el = Xen_car(lst); if ((Xen_is_pair(el)) && (Xen_is_number(Xen_car(el))) && (Xen_is_pair(Xen_cdr(el))) && (Xen_is_number(Xen_cadr(el)))) { brkpts[i] = Xen_real_to_C_double(Xen_car(el)); brkpts[i + 1] = Xen_real_to_C_double(Xen_cadr(el)); } else { Xen_error(BAD_TYPE, Xen_list_2(C_string_to_Xen_string(S_make_env ": odd breakpoints list? ~A"), keys[0])); } } } } } } } if (brkpts == NULL) { Xen_error(NO_DATA, Xen_list_1(C_string_to_Xen_string(S_make_env ": no envelope?"))); } if (dur > 0) { if ((end > 0) && ((end + 1) != dur)) { if ((!v) && (brkpts)) {free(brkpts); brkpts = NULL;} Xen_error(CLM_ERROR, Xen_list_3(C_string_to_Xen_string(S_make_env ": end, ~A, and dur, ~A, specified, but dur != end+1"), keys[5], keys[6])); } end = dur - 1; } /* (make-env '(0 1 1 0) :duration most-positive-fixnum) -> env linear, pass: 0 (dur: -9223372036854775808)... */ if ((end <= 0) && (duration <= 0.0)) Xen_out_of_range_error(S_make_env, 0, C_double_to_Xen_real(duration), "duration <= 0.0?"); if (duration > (24 * 3600 * 365)) Xen_out_of_range_error(S_make_env, 0, C_double_to_Xen_real(duration), "duration > year?"); { mus_error_handler_t *old_error_handler; old_error_handler = mus_error_set_handler(local_mus_error); ge = mus_make_env(brkpts, npts, scaler, offset, base, duration, end, NULL); mus_error_set_handler(old_error_handler); } if (ge) { if (v) return(mus_xen_to_object(mus_any_to_mus_xen_with_vct(ge, keys[0]))); /* in s7, keys[0] == v */ return(mus_xen_to_object(mus_any_to_mus_xen_with_vct(ge, xen_make_vct(mus_env_breakpoints(ge) * 2, brkpts)))); } return(clm_mus_error(local_error_type, local_error_msg, S_make_env)); } static Xen g_env_interp(Xen x, Xen env1) /* "env" causes trouble in Objective-C!! */ { #define H_env_interp "(" S_env_interp " x env): value of envelope env at x" Xen_check_type(Xen_is_number(x), x, 1, S_env_interp, "a number"); Xen_check_type((mus_is_xen(env1)) && (mus_is_env(Xen_to_mus_any(env1))), env1, 2, S_env_interp, "an env generator"); return(C_double_to_Xen_real(mus_env_interp(Xen_real_to_C_double(x), Xen_to_mus_any(env1)))); } /* mus_env_any calls the C function itself, so we pass it connect_func, * connect_func uses the function passed as an argument to g_env_any. * I can't think of a cleaner way to handle this except via nested functions. * Both versions seem to work ok with recursive env-any calls. */ static Xen current_connect_func; static mus_float_t connect_func(mus_float_t val) { return(Xen_real_to_C_double(Xen_call_with_1_arg(current_connect_func, C_double_to_Xen_real(val), S_env_any " connect function"))); } static Xen g_env_any(Xen e, Xen func) { Xen val; Xen old_connect_func = Xen_false; #define H_env_any "(" S_env_any " e func) uses 'func' to connect the dots in the env 'e'" Xen_check_type((mus_is_xen(e)) && (mus_is_env(Xen_to_mus_any(e))), e, 1, S_env_any, "an env generator"); Xen_check_type((Xen_is_procedure(func)) && (Xen_is_aritable(func, 1)), func, 2, S_env_any, "a function of one arg"); old_connect_func = current_connect_func; current_connect_func = func; val = C_double_to_Xen_real(mus_env_any(Xen_to_mus_any(e), connect_func)); current_connect_func = old_connect_func; return(val); } #define S_envelope_interp "envelope-interp" static Xen g_envelope_interp(Xen ux, Xen e, Xen ubase) { #define H_envelope_interp "(envelope-interp x e (base 1.0)) -> value of e at x; base controls connecting segment type: (envelope-interp .3 '(0 0 .5 1 1 0)) -> .6" mus_float_t x, base = 1.0, x0, y0, y1; Xen_check_type(Xen_is_number(ux), ux, 1, S_envelope_interp, "a number"); Xen_check_type(Xen_is_list(e), e, 2, S_envelope_interp, "a list"); if (Xen_is_null(e)) return(Xen_integer_zero); x = Xen_real_to_C_double(ux); if (Xen_is_bound(ubase)) base = Xen_real_to_C_double(ubase); x0 = Xen_real_to_C_double(Xen_car(e)); while (true) { mus_float_t x1; Xen ey; if (!Xen_is_pair(Xen_cdr(e))) Xen_check_type(false, e, 2, S_envelope_interp, "a list of breakpoint values"); ey = Xen_cadr(e); if ((x <= x0) || (!Xen_is_pair(Xen_cddr(e)))) return(ey); x1 = Xen_real_to_C_double(Xen_caddr(e)); if (x < x1) { if (base == 0.0) return(ey); y0 = Xen_real_to_C_double(ey); y1 = Xen_real_to_C_double(Xen_cadddr(e)); if (y0 == y1) return(ey); if (base == 1.0) return(C_double_to_Xen_real(y0 + ((x - x0) * (y1 - y0) / (x1 - x0)))); return(C_double_to_Xen_real(y0 + (((y1 - y0) / (base - 1.0)) * (pow(base, (x - x0) / (x1 - x0)) - 1.0)))); } e = Xen_cddr(e); x0 = x1; } return(Xen_false); } /* -------------------------------- pulsed-env -------------------------------- */ static Xen g_make_pulsed_env(Xen e, Xen dur, Xen frq) { #define H_make_pulsed_env "(" S_make_pulsed_env " envelope duration frequency) returns a pulsed-env generator." Xen gp, ge; mus_any *pl; gp = g_make_pulse_train(frq, Xen_undefined, Xen_undefined, Xen_undefined, Xen_undefined, Xen_undefined); ge = g_make_env(Xen_list_3(e, C_double_to_Xen_real(1.0), dur)); pl = mus_make_pulsed_env(Xen_to_mus_any(ge), Xen_to_mus_any(gp)); return(mus_xen_to_object(mus_any_to_mus_xen_with_two_vcts(pl, ge, gp))); } static Xen g_is_pulsed_env(Xen os) { #define H_is_pulsed_env "(" S_is_pulsed_env " gen) returns " PROC_TRUE " if gen is a pulsed-env generator." return(C_bool_to_Xen_boolean((mus_is_xen(os)) && (mus_is_pulsed_env(Xen_to_mus_any(os))))); } static Xen g_pulsed_env(Xen g, Xen fm) { #define H_pulsed_env "(" S_pulsed_env " gen fm) runs a pulsed-env generator." mus_any *pl = NULL; Xen_check_type((mus_is_xen(g)) && (mus_is_pulsed_env(pl = Xen_to_mus_any(g))), g, 1, S_pulsed_env, "a pulsed-env object"); if (Xen_is_number(fm)) return(C_double_to_Xen_real(mus_pulsed_env(pl, Xen_real_to_C_double(fm)))); return(C_double_to_Xen_real(mus_pulsed_env_unmodulated(pl))); } /* ---------------- io ---------------- */ #if (!HAVE_RUBY) #define S_output "*output*" #define S_reverb "*reverb*" #else #define S_output "output" #define S_reverb "reverb" #endif static Xen clm_output, clm_reverb; /* *output* and *reverb* at extlang level -- these can be output streams, vct, sound-data objects etc */ #if (HAVE_SCHEME) static Xen clm_output_slot = NULL, clm_reverb_slot = NULL; #define CLM_OUTPUT s7_slot_value(clm_output_slot) #define CLM_REVERB s7_slot_value(clm_reverb_slot) #else #define CLM_OUTPUT Xen_variable_ref(S_output) #define CLM_REVERB Xen_variable_ref(S_reverb) #endif static Xen g_is_mus_input(Xen obj) { #define H_is_mus_input "(" S_is_mus_input " gen): " PROC_TRUE " if gen is an input generator" return(C_bool_to_Xen_boolean((mus_is_xen(obj)) && (mus_is_input(Xen_to_mus_any(obj))))); } static Xen g_is_mus_output(Xen obj) { #define H_is_mus_output "(" S_is_mus_output " gen): " PROC_TRUE " if gen is an output generator" return(C_bool_to_Xen_boolean((mus_is_xen(obj)) && (mus_is_output(Xen_to_mus_any(obj))))); } static Xen g_is_file_to_sample(Xen obj) { #define H_is_file_to_sample "(" S_is_file_to_sample " gen): " PROC_TRUE " if gen is a " S_file_to_sample " generator" return(C_bool_to_Xen_boolean((mus_is_xen(obj)) && (mus_is_file_to_sample(Xen_to_mus_any(obj))))); } static Xen mus_clm_output(void) {return(CLM_OUTPUT);} static Xen mus_clm_reverb(void) {return(CLM_REVERB);} static Xen g_is_file_to_frample(Xen obj) { #define H_is_file_to_frample "(" S_is_file_to_frample " gen): " PROC_TRUE " if gen is a " S_file_to_frample " generator" return(C_bool_to_Xen_boolean((mus_is_xen(obj)) && (mus_is_file_to_frample(Xen_to_mus_any(obj))))); } static Xen g_is_sample_to_file(Xen obj) { #define H_is_sample_to_file "(" S_is_sample_to_file " gen): " PROC_TRUE " if gen is a " S_sample_to_file " generator" return(C_bool_to_Xen_boolean((mus_is_xen(obj)) && (mus_is_sample_to_file(Xen_to_mus_any(obj))))); } static Xen g_is_frample_to_file(Xen obj) { #define H_is_frample_to_file "(" S_is_frample_to_file " gen): " PROC_TRUE " if gen is a " S_frample_to_file " generator" return(C_bool_to_Xen_boolean((mus_is_xen(obj)) && (mus_is_frample_to_file(Xen_to_mus_any(obj))))); } #if HAVE_SCHEME static mus_float_t (*in_any_2)(mus_long_t pos, int chn); #endif static Xen g_in_any_1(const char *caller, Xen frample, int in_chan, Xen inp) { mus_long_t pos; Xen_check_type(Xen_is_integer(frample), frample, 1, caller, "an integer"); pos = Xen_llong_to_C_llong(frample); if (pos < 0) Xen_out_of_range_error(caller, 1, frample, "location should be >= 0"); if (in_chan < 0) Xen_out_of_range_error(caller, 2, C_int_to_Xen_integer(in_chan), "must be >= 0"); #if HAVE_SCHEME if (Xen_is_false(inp)) return(C_double_to_Xen_real(0.0)); /* ws.scm default for *clm-reverb* is #f */ if (inp == CLM_REVERB) return(s7_make_real(s7, in_any_2(pos, in_chan))); #endif if (mus_is_xen(inp)) { Xen_check_type(mus_is_input(Xen_to_mus_any(inp)), inp, 3, caller, "an input generator"); return(C_double_to_Xen_real(mus_in_any(pos, in_chan, (mus_any *)Xen_to_mus_any(inp)))); } if (mus_is_vct(inp)) { #if HAVE_SCHEME if (pos < s7_vector_length(inp)) { if (s7_vector_rank(inp) > 1) return(s7_vector_ref_n(s7, inp, 2, in_chan, pos)); return(s7_vector_ref(s7, inp, pos)); } return(C_double_to_Xen_real(0.0)); #else vct *v; mus_float_t *vdata; v = Xen_to_vct(inp); vdata = mus_vct_data(v); if (pos < mus_vct_length(v)) return(C_double_to_Xen_real(vdata[pos])); return(C_double_to_Xen_real(0.0)); #endif } if (Xen_is_vector(inp)) { if (pos < Xen_vector_length(inp)) return(Xen_vector_ref(inp, pos)); } return(C_double_to_Xen_real(0.0)); } static Xen g_in_any(Xen frample, Xen chan, Xen inp) { #define H_in_any "(" S_in_any " frample chan stream): input stream sample at frample in channel chan" Xen_check_type(Xen_is_integer(chan), chan, 2, S_in_any, "an integer"); return(g_in_any_1(S_in_any, frample, Xen_integer_to_C_int(chan), inp)); } static Xen g_ina(Xen frample, Xen inp) { #define H_ina "(" S_ina " frample stream): input stream sample in channel 0 at frample" return(g_in_any_1(S_ina, frample, 0, inp)); } static Xen g_inb(Xen frample, Xen inp) { #define H_inb "(" S_inb " frample stream): input stream sample in channel 1 at frample" return(g_in_any_1(S_inb, frample, 1, inp)); } #if (!HAVE_SCHEME) static Xen out_any_2(Xen outp, mus_long_t pos, mus_float_t inv, int chn, const char *caller) #else static Xen fallback_out_any_2(Xen outp, mus_long_t pos, mus_float_t inv, int chn, const char *caller) #endif { mus_xen *gn; gn = (mus_xen *)Xen_object_ref_checked(outp, mus_xen_tag); if (gn) { /* mus_out_any will check the writer so output_p is pointless */ mus_out_any(pos, inv, chn, mus_xen_to_mus_any(gn)); return(Xen_integer_zero); } if (mus_is_vct(outp)) { mus_float_t *vdata; vct *v; v = xen_to_vct(outp); vdata = mus_vct_data(v); if (Xen_vector_rank(outp) == 1) { if (chn == 0) { if (pos < mus_vct_length(v)) vdata[pos] += inv; } } #if HAVE_SCHEME else { s7_int *offsets; offsets = s7_vector_offsets(outp); pos += (chn * offsets[0]); if (pos < mus_vct_length(v)) vdata[pos] += inv; } #endif return(Xen_integer_zero); } if (Xen_is_vector(outp)) { if (pos < Xen_vector_length(outp)) Xen_vector_set(outp, pos, C_double_to_Xen_real(Xen_real_to_C_double(Xen_vector_ref(outp, pos)) + inv)); } return(Xen_integer_zero); } #if HAVE_SCHEME static Xen (*out_any_2)(mus_long_t pos, mus_float_t inv, int chn, const char *caller); bool mus_simple_out_any_to_file(mus_long_t samp, mus_float_t val, int chan, mus_any *IO); bool mus_simple_outa_to_file(mus_long_t samp, mus_float_t val, mus_any *IO); static mus_xen *clm_output_gn = NULL; static mus_any *clm_output_gen = NULL; static vct *clm_output_vct; static Xen out_any_2_to_mus_xen(mus_long_t pos, mus_float_t inv, int chn, const char *caller) { mus_out_any(pos, inv, chn, clm_output_gen); return(xen_zero); } static Xen safe_out_any_2_to_mus_xen(mus_long_t pos, mus_float_t inv, int chn, const char *caller) { if (!mus_simple_out_any_to_file(pos, inv, chn, clm_output_gen)) mus_safe_out_any_to_file(pos, inv, chn, clm_output_gen); return(xen_zero); } static Xen out_any_2_to_vct(mus_long_t pos, mus_float_t inv, int chn, const char *caller) { mus_float_t *vdata; vdata = mus_vct_data(clm_output_vct); #if (!HAVE_SCHEME) if ((chn == 0) && (pos < mus_vct_length(clm_output_vct))) vdata[pos] += inv; #else if (Xen_vector_rank(clm_output_vct) == 1) { if ((chn == 0) && (pos < mus_vct_length(clm_output_vct))) vdata[pos] += inv; } else { s7_int chans; chans = s7_vector_dimensions(clm_output_vct)[0]; if (chn < chans) { s7_int chan_len; chan_len = s7_vector_dimensions(clm_output_vct)[1]; if (pos < chan_len) vdata[chn * chan_len + pos] += inv; } } #endif return(xen_zero); } static Xen out_any_2_to_vector(mus_long_t pos, mus_float_t inv, int chn, const char *caller) { if (pos < Xen_vector_length(CLM_OUTPUT)) Xen_vector_set(CLM_OUTPUT, pos, C_double_to_Xen_real(Xen_real_to_C_double(Xen_vector_ref(CLM_OUTPUT, pos)) + inv)); return(xen_zero); } static Xen out_any_2_no_op(mus_long_t pos, mus_float_t inv, int chn, const char *caller) { return(xen_zero); } static s7_pointer g_clm_output_set(s7_scheme *sc, s7_pointer args) { s7_pointer new_output; new_output = s7_cadr(args); clm_output_gn = (mus_xen *)Xen_object_ref_checked(new_output, mus_xen_tag); if (clm_output_gn) { out_any_2 = out_any_2_to_mus_xen; clm_output_gen = clm_output_gn->gen; if (mus_out_any_is_safe(clm_output_gen)) out_any_2 = safe_out_any_2_to_mus_xen; } else { clm_output_gen = NULL; if (mus_is_vct(new_output)) { out_any_2 = out_any_2_to_vct; clm_output_vct = xen_to_vct(new_output); } else { if (Xen_is_vector(new_output)) { out_any_2 = out_any_2_to_vector; } else out_any_2 = out_any_2_no_op; } } return(new_output); } /* need in_any_2(pos, 0, caller) -> double + safe case + none-file cases */ static mus_xen *clm_input_gn; static mus_any *clm_input_gen; static vct *clm_input_vct; static mus_float_t in_any_2_to_mus_xen(mus_long_t pos, int chn) { return(mus_in_any(pos, chn, clm_input_gen)); } static mus_float_t safe_in_any_2_to_mus_xen(mus_long_t pos, int chn) { return(mus_file_to_sample(clm_input_gen, pos, chn)); } static mus_float_t in_any_2_to_vct(mus_long_t pos, int chn) { mus_float_t *vdata; vdata = mus_vct_data(clm_input_vct); if ((chn == 0) && (pos < mus_vct_length(clm_input_vct))) return(vdata[pos]); return(0.0); } static mus_float_t in_any_2_to_vector(mus_long_t pos, int chn) { if (pos < Xen_vector_length(CLM_REVERB)) return(Xen_real_to_C_double(Xen_vector_ref(CLM_REVERB, pos))); return(0.0); } static mus_float_t in_any_2_no_op(mus_long_t pos, int chn) { return(0.0); } static s7_pointer g_clm_reverb_set(s7_scheme *sc, s7_pointer args) { s7_pointer new_input; new_input = s7_cadr(args); clm_input_gn = (mus_xen *)Xen_object_ref_checked(new_input, mus_xen_tag); if (clm_input_gn) { in_any_2 = in_any_2_to_mus_xen; clm_input_gen = clm_input_gn->gen; if (mus_in_any_is_safe(clm_input_gen)) in_any_2 = safe_in_any_2_to_mus_xen; } else { if (mus_is_vct(new_input)) { in_any_2 = in_any_2_to_vct; clm_input_vct = xen_to_vct(new_input); } else { if (Xen_is_vector(new_input)) { in_any_2 = in_any_2_to_vector; } else in_any_2 = in_any_2_no_op; } } return(new_input); } #endif #define S_out_bank "out-bank" static Xen g_out_bank(Xen gens, Xen loc, Xen inval) { #define H_out_bank "(out-bank gens location val) calls each generator in the gens vector, passing it the argument val, then \ sends that output to the output channels in the vector order (the first generator writes to outa, the second to outb, etc)." mus_long_t pos; int i, size; mus_float_t x = 0.0; Xen_check_type(Xen_is_integer(loc), loc, 2, S_out_bank, "an integer"); pos = Xen_llong_to_C_llong(loc); if (pos < 0) Xen_out_of_range_error(S_out_bank, 2, loc, "must be >= 0"); Xen_check_type(Xen_is_vector(gens), gens, 1, S_out_bank, "a vector of generators"); size = Xen_vector_length(gens); Xen_check_type(Xen_is_number(inval), inval, 3, S_out_bank, "a number"); x = Xen_real_to_C_double(inval); #if HAVE_SCHEME for (i = 0; i < size; i++) { mus_any *g = NULL; mus_xen *gn; Xen_to_C_any_generator(Xen_vector_ref(gens, i), gn, g, S_out_bank, "an output generator"); out_any_2(pos, mus_apply(g, x, 0.0), i, S_out_bank); } #else for (i = 0; i < size; i++) { mus_any *g = NULL; mus_xen *gn; Xen_to_C_any_generator(Xen_vector_ref(gens, i), gn, g, S_out_bank, "an output generator"); out_any_2(CLM_OUTPUT, pos, mus_apply(g, x, 0.0), i, S_out_bank); } #endif return(inval); } static Xen g_out_any_1(const char *caller, Xen frample, int chn, Xen val, Xen outp) { mus_long_t pos = 0; mus_float_t inv; if (chn < 0) Xen_out_of_range_error(caller, 3, C_int_to_Xen_integer(chn), "must be >= 0"); Xen_to_C_integer_or_error(frample, pos, caller, 1); if (pos < 0) Xen_out_of_range_error(caller, 1, frample, "must be >= 0"); Xen_to_C_double_or_error(val, inv, caller, 2); if (!Xen_is_bound(outp)) #if (!HAVE_SCHEME) return(out_any_2(CLM_OUTPUT, pos, inv, chn, caller)); #else return(out_any_2(pos, inv, chn, caller)); #endif #if (!HAVE_SCHEME) return(out_any_2(outp, pos, inv, chn, caller)); #else if (outp == CLM_OUTPUT) return(out_any_2(pos, inv, chn, caller)); return(fallback_out_any_2(outp, pos, inv, chn, caller)); #endif } static Xen g_out_any(Xen frample, Xen val, Xen chan, Xen outp) { #define H_out_any "(" S_out_any " frample val chan stream): add val to output stream at frample in channel chan" Xen_check_type(Xen_is_integer(chan), chan, 3, S_out_any, "an integer"); return(g_out_any_1(S_out_any, frample, Xen_integer_to_C_int(chan), val, outp)); } static Xen g_outa(Xen frample, Xen val, Xen outp) { #define H_outa "(" S_outa " frample val stream): add val to output stream at frample in channel 0" return(g_out_any_1(S_outa, frample, 0, val, outp)); } static Xen g_outb(Xen frample, Xen val, Xen outp) { #define H_outb "(" S_outb " frample val stream): add val to output stream at frample in channel 1" return(g_out_any_1(S_outb, frample, 1, val, outp)); } static Xen g_outc(Xen frample, Xen val, Xen outp) { #define H_outc "(" S_outc " frample val stream): add val to output stream at frample in channel 2" return(g_out_any_1(S_outc, frample, 2, val, outp)); } static Xen g_outd(Xen frample, Xen val, Xen outp) { #define H_outd "(" S_outd " frample val stream): add val to output stream at frample in channel 3" return(g_out_any_1(S_outd, frample, 3, val, outp)); } static Xen g_mus_close(Xen ptr) { #define H_mus_close "(" S_mus_close " gen): close the IO stream managed by 'gen' (a sample->file generator, for example)" if (mus_is_xen(ptr)) return(C_int_to_Xen_integer(mus_close_file((mus_any *)Xen_to_mus_any(ptr)))); Xen_check_type(mus_is_vct(ptr) || Xen_is_false(ptr) || Xen_is_vector(ptr), ptr, 1, S_mus_close, "an IO gen or its outa equivalent"); return(Xen_integer_zero); } static Xen g_make_file_to_sample(Xen name, Xen buffer_size) { #define H_make_file_to_sample "(" S_make_file_to_sample " filename buffer-size): return an input generator reading 'filename' (a sound file)" mus_any *ge; mus_long_t size; Xen_check_type(Xen_is_string(name), name, 1, S_make_file_to_sample, "a string"); Xen_check_type(Xen_is_llong_or_unbound(buffer_size), buffer_size, 2, S_make_file_to_sample, "an integer"); if (!(mus_file_probe(Xen_string_to_C_string(name)))) Xen_error(NO_SUCH_FILE, Xen_list_3(C_string_to_Xen_string(S_make_file_to_sample ": ~S, ~A"), name, C_string_to_Xen_string(STRERROR(errno)))); if (Xen_is_llong(buffer_size)) { size = Xen_llong_to_C_llong(buffer_size); if (size <= 0) Xen_out_of_range_error(S_make_file_to_sample, 2, buffer_size, "must be > 0"); } else size = mus_file_buffer_size(); ge = mus_make_file_to_sample_with_buffer_size(Xen_string_to_C_string(name), size); if (ge) return(mus_xen_to_object(mus_any_to_mus_xen(ge))); return(Xen_false); } static Xen g_file_to_sample(Xen obj, Xen samp, Xen chan) { #define H_file_to_sample "(" S_file_to_sample " obj frample chan): sample value in sound file read by 'obj' in channel chan at frample" int channel = 0; mus_any *g = NULL; mus_xen *gn; Xen_to_C_generator(obj, gn, g, mus_is_input, S_file_to_sample, "an input generator"); Xen_check_type(Xen_is_llong(samp), samp, 2, S_file_to_sample, "an integer"); if (Xen_is_bound(chan)) { Xen_check_type(Xen_is_integer(chan), chan, 3, S_file_to_sample, "an integer"); channel = Xen_integer_to_C_int(chan); } return(C_double_to_Xen_real(mus_file_to_sample(g, Xen_llong_to_C_llong(samp), channel))); } static Xen g_make_sample_to_file(Xen name, Xen chans, Xen out_format, Xen out_type, Xen comment) { #if HAVE_SCHEME #define make_sample_to_file_example "(" S_make_sample_to_file " \"test.snd\" 2 mus-lshort mus-riff)" #endif #if HAVE_RUBY #define make_sample_to_file_example "\"test.snd\" 2 Mus_lshort Mus_riff make_sample2file" #endif #if HAVE_FORTH #define make_sample_to_file_example "\"test.snd\" 2 mus-lshort mus-riff make-sample->file" #endif #define H_make_sample_to_file "(" S_make_sample_to_file " filename chans sample-type header-type comment): \ return an output generator writing the sound file 'filename' which is set up to have \ 'chans' channels of 'sample-type' samples with a header of 'header-type'. The latter \ should be sndlib identifiers:\n " make_sample_to_file_example mus_sample_t df = MUS_OUT_SAMPLE_TYPE; Xen_check_type(Xen_is_string(name), name, 1, S_make_sample_to_file, "a string"); Xen_check_type(Xen_is_integer_or_unbound(chans), chans, 2, S_make_sample_to_file, "an integer"); Xen_check_type(Xen_is_integer_or_unbound(out_format), out_format, 3, S_make_sample_to_file, "an integer (sample type)"); Xen_check_type(Xen_is_integer_or_unbound(out_type), out_type, 4, S_make_sample_to_file, "an integer (header type)"); if (Xen_is_integer(out_format)) df = (mus_sample_t)Xen_integer_to_C_int(out_format); if (mus_is_sample_type(df)) { mus_header_t ht = MUS_NEXT; if (Xen_is_integer(out_type)) ht = (mus_header_t)Xen_integer_to_C_int(out_type); if (mus_is_header_type(ht)) { int chns = 1; if (Xen_is_integer(chans)) chns = Xen_integer_to_C_int(chans); if (chns > 0) { mus_any *rgen; rgen = mus_make_sample_to_file_with_comment(Xen_string_to_C_string(name), chns, df, ht, (Xen_is_string(comment)) ? Xen_string_to_C_string(comment) : NULL); if (rgen) return(mus_xen_to_object(mus_any_to_mus_xen(rgen))); } else Xen_out_of_range_error(S_make_sample_to_file, 2, chans, "chans <= 0?"); } else Xen_out_of_range_error(S_make_sample_to_file, 4, out_type, "invalid header type"); } else Xen_out_of_range_error(S_make_sample_to_file, 3, out_format, "invalid sample type"); return(Xen_false); } static Xen g_continue_sample_to_file(Xen name) { #define H_continue_sample_to_file "(" S_continue_sample_to_file " filename): return an output generator \ that reopens an existing sound file 'filename' ready for output via " S_sample_to_file mus_any *rgen = NULL; Xen_check_type(Xen_is_string(name), name, 1, S_continue_sample_to_file, "a string"); rgen = mus_continue_sample_to_file(Xen_string_to_C_string(name)); if (rgen) return(mus_xen_to_object(mus_any_to_mus_xen(rgen))); return(Xen_false); } static Xen g_sample_to_file(Xen obj, Xen samp, Xen chan, Xen val) { #define H_sample_to_file "(" S_sample_to_file " obj samp chan val): add val to the output stream \ handled by the output generator 'obj', in channel 'chan' at frample 'samp'" mus_any *g = NULL; mus_xen *gn; Xen_to_C_any_generator(obj, gn, g, S_sample_to_file, "an output generator"); Xen_check_type(mus_is_output(g), obj, 1, S_sample_to_file, "an output generator"); Xen_check_type(Xen_is_integer(samp), samp, 2, S_sample_to_file, "an integer"); Xen_check_type(Xen_is_integer(chan), chan, 3, S_sample_to_file, "an integer"); Xen_check_type(Xen_is_number(val), val, 4, S_sample_to_file, "a number"); mus_sample_to_file(g, Xen_llong_to_C_llong(samp), Xen_integer_to_C_int(chan), Xen_real_to_C_double(val)); return(val); } static Xen g_sample_to_file_add(Xen obj1, Xen obj2) { #define H_sample_to_file_add "(" S_sample_to_file_add " obj1 obj2): mixes obj2 (an output generator) into obj1 (also an output generator)" mus_any *g1 = NULL, *g2 = NULL; mus_xen *gn1, *gn2; Xen_to_C_any_generator(obj1, gn1, g1, S_sample_to_file_add, "an output generator"); Xen_to_C_any_generator(obj2, gn2, g2, S_sample_to_file_add, "an output generator"); Xen_check_type(mus_is_output(g1), obj1, 1, S_sample_to_file_add, "an output generator"); Xen_check_type(mus_is_output(g2), obj2, 2, S_sample_to_file_add, "an output generator"); mus_sample_to_file_add(g1, g2); return(obj1); } static Xen g_make_file_to_frample(Xen name, Xen buffer_size) { #define H_make_file_to_frample "(" S_make_file_to_frample " filename buffer-size): return an input generator reading 'filename' (a sound file)" mus_any *ge; mus_long_t size; Xen_check_type(Xen_is_string(name), name, 1, S_make_file_to_frample, "a string"); Xen_check_type(Xen_is_llong_or_unbound(buffer_size), buffer_size, 2, S_make_file_to_frample, "an integer"); if (!(mus_file_probe(Xen_string_to_C_string(name)))) Xen_error(NO_SUCH_FILE, Xen_list_3(C_string_to_Xen_string(S_make_file_to_frample ": ~S, ~A"), name, C_string_to_Xen_string(STRERROR(errno)))); if (Xen_is_llong(buffer_size)) { size = Xen_llong_to_C_llong(buffer_size); if (size <= 0) Xen_out_of_range_error(S_make_file_to_frample, 2, buffer_size, "must be > 0"); } else size = mus_file_buffer_size(); ge = mus_make_file_to_frample_with_buffer_size(Xen_string_to_C_string(name), size); if (ge) return(mus_xen_to_object(mus_any_to_mus_xen(ge))); return(Xen_false); } static Xen g_file_to_frample(Xen obj, Xen samp, Xen outfr) { #define H_file_to_frample "(" S_file_to_frample " obj samp outf): frample of samples at frample 'samp' in sound file read by 'obj'" Xen_check_type((mus_is_xen(obj)) && (mus_is_input(Xen_to_mus_any(obj))), obj, 1, S_file_to_frample, "an input generator"); Xen_check_type(Xen_is_integer(samp), samp, 2, S_file_to_frample, "an integer"); mus_file_to_frample(Xen_to_mus_any(obj), Xen_llong_to_C_llong(samp), mus_vct_data(Xen_to_vct(outfr))); return(outfr); } static Xen g_make_frample_to_file(Xen name, Xen chans, Xen out_format, Xen out_type, Xen comment) { #if HAVE_SCHEME #define make_frample_to_file_example "(" S_make_frample_to_file " \"test.snd\" 2 mus-lshort mus-riff)" #endif #if HAVE_RUBY #define make_frample_to_file_example "\"test.snd\" 2 Mus_lshort Mus_riff make_frample2file" #endif #if HAVE_FORTH #define make_frample_to_file_example "\"test.snd\" 2 mus-lshort mus-riff make-frample->file" #endif #define H_make_frample_to_file "(" S_make_frample_to_file " filename chans sample-type header-type comment): \ return an output generator writing the sound file 'filename' which is set up to have \ 'chans' channels of 'sample-type' samples with a header of 'header-type'. The latter \ should be sndlib identifiers:\n " make_frample_to_file_example mus_any *fgen = NULL; Xen_check_type(Xen_is_string(name), name, 1, S_make_frample_to_file, "a string"); Xen_check_type(Xen_is_integer_or_unbound(chans), chans, 2, S_make_frample_to_file, "an integer"); Xen_check_type(Xen_is_integer_or_unbound(out_format), out_format, 3, S_make_frample_to_file, "an integer (sample type id)"); Xen_check_type(Xen_is_integer_or_unbound(out_type), out_type, 4, S_make_frample_to_file, "an integer (header-type id)"); fgen = mus_make_frample_to_file_with_comment(Xen_string_to_C_string(name), (Xen_is_integer(chans)) ? Xen_integer_to_C_int(chans) : 1, (Xen_is_integer(out_format)) ? (mus_sample_t)Xen_integer_to_C_int(out_format) : MUS_OUT_SAMPLE_TYPE, (Xen_is_integer(out_type)) ? (mus_header_t)Xen_integer_to_C_int(out_type) : MUS_NEXT, (Xen_is_string(comment)) ? Xen_string_to_C_string(comment) : NULL); if (fgen) return(mus_xen_to_object(mus_any_to_mus_xen(fgen))); return(Xen_false); } static Xen g_continue_frample_to_file(Xen name) { #define H_continue_frample_to_file "(" S_continue_frample_to_file " filename): return an output generator \ that reopens an existing sound file 'filename' ready for output via " S_frample_to_file mus_any *rgen = NULL; Xen_check_type(Xen_is_string(name), name, 1, S_continue_frample_to_file, "a string"); rgen = mus_continue_frample_to_file(Xen_string_to_C_string(name)); if (rgen) return(mus_xen_to_object(mus_any_to_mus_xen(rgen))); return(Xen_false); } static Xen g_frample_to_file(Xen obj, Xen samp, Xen val) { #define H_frample_to_file "(" S_frample_to_file " obj samp val): add frample 'val' to the output stream \ handled by the output generator 'obj' at frample 'samp'" mus_xen *gn; gn = (mus_xen *)Xen_object_ref_checked(obj, mus_xen_tag); Xen_check_type(((gn) && (mus_is_output(gn->gen))), obj, 1, S_frample_to_file, "an output generator"); Xen_check_type(Xen_is_integer(samp), samp, 2, S_frample_to_file, "an integer"); mus_frample_to_file(gn->gen, Xen_llong_to_C_llong(samp), mus_vct_data(Xen_to_vct(val))); return(val); } /* ---------------- readin ---------------- */ static Xen g_is_readin(Xen obj) { #define H_is_readin "(" S_is_readin " gen): " PROC_TRUE " if gen is a " S_readin return(C_bool_to_Xen_boolean((mus_is_xen(obj)) && (mus_is_readin(Xen_to_mus_any(obj))))); } static Xen g_readin(Xen obj) { #define H_readin "(" S_readin " gen): next sample from readin generator (a sound file reader)" mus_any *g = NULL; mus_xen *gn; Xen_to_C_generator(obj, gn, g, mus_is_readin, S_readin, "a readin generator"); return(C_double_to_Xen_real(mus_readin(g))); } static Xen g_make_readin(Xen arglist) { #define H_make_readin "(" S_make_readin " file (channel 0) (start 0) (direction 1) size): \ return a new readin (file input) generator reading the sound file 'file' starting at frample \ 'start' in channel 'channel' and reading forward if 'direction' is not -1" /* optkey file channel start direction size */ mus_any *ge; const char *file = NULL; Xen args[10]; Xen keys[5]; int orig_arg[5] = {0, 0, 0, 0, 0}; int vals, chans; mus_long_t buffer_size; int channel = 0, direction = 1; mus_long_t start = 0; keys[0] = kw_file; keys[1] = kw_channel; keys[2] = kw_start; keys[3] = kw_direction; keys[4] = kw_size; buffer_size = mus_file_buffer_size(); /* this is only 8192! (clm.h MUS_DEFAULT_FILE_BUFFER_SIZE) */ { int i, arglist_len; Xen p; arglist_len = Xen_list_length(arglist); if (arglist_len > 10) clm_error(S_make_readin, "too many arguments!", arglist); for (i = 0, p = arglist; i < arglist_len; i++, p = Xen_cdr(p)) args[i] = Xen_car(p); for (i = arglist_len; i < 10; i++) args[i] = Xen_undefined; } vals = mus_optkey_unscramble(S_make_readin, 5, keys, args, orig_arg); if (vals > 0) { file = mus_optkey_to_string(keys[0], S_make_readin, orig_arg[0], NULL); /* not copied */ channel = Xen_optkey_to_int(kw_channel, keys[1], S_make_readin, orig_arg[1], channel); if (channel < 0) Xen_out_of_range_error(S_make_readin, orig_arg[1], keys[1], "channel < 0?"); start = Xen_optkey_to_mus_long_t(kw_start, keys[2], S_make_readin, orig_arg[2], start); direction = Xen_optkey_to_int(kw_direction, keys[3], S_make_readin, orig_arg[3], direction); buffer_size = Xen_optkey_to_mus_long_t(kw_size, keys[4], S_make_readin, orig_arg[4], buffer_size); if (buffer_size <= 0) Xen_out_of_range_error(S_make_readin, orig_arg[4], keys[4], "must be > 0"); } if (file == NULL) Xen_out_of_range_error(S_make_readin, orig_arg[0], keys[0], "no file name given"); if (!(mus_file_probe(file))) Xen_error(NO_SUCH_FILE, Xen_list_3(C_string_to_Xen_string(S_make_readin ": ~S, ~A"), C_string_to_Xen_string(file), C_string_to_Xen_string(STRERROR(errno)))); chans = mus_sound_chans(file); if (chans <= 0) Xen_error(BAD_HEADER, Xen_list_2(C_string_to_Xen_string(S_make_readin ": ~S chans <= 0?"), C_string_to_Xen_string(file))); if (channel >= chans) Xen_out_of_range_error(S_make_readin, orig_arg[1], keys[1], "channel > available chans?"); ge = mus_make_readin_with_buffer_size(file, channel, start, direction, buffer_size); if (ge) return(mus_xen_to_object(mus_any_to_mus_xen(ge))); return(Xen_false); } /* ---------------- locsig ---------------- */ static Xen g_locsig_ref(Xen obj, Xen chan) { #define H_locsig_ref "(" S_locsig_ref " gen chan): locsig 'gen' channel 'chan' scaler" Xen_check_type((mus_is_xen(obj)) && (mus_is_locsig(Xen_to_mus_any(obj))), obj, 1, S_locsig_ref, "a locsig generator"); Xen_check_type(Xen_is_integer(chan), chan, 2, S_locsig_ref, "an integer"); return(C_double_to_Xen_real(mus_locsig_ref(Xen_to_mus_any(obj), Xen_integer_to_C_int(chan)))); } static Xen g_locsig_set(Xen obj, Xen chan, Xen val) { #define H_locsig_set "(" S_locsig_set " gen chan val): set the locsig generator's channel 'chan' scaler to 'val'" Xen_check_type((mus_is_xen(obj)) && (mus_is_locsig(Xen_to_mus_any(obj))), obj, 1, S_locsig_set, "a locsig generator"); Xen_check_type(Xen_is_integer(chan), chan, 2, S_locsig_set, "an integer"); #if (!HAVE_SCHEME) Xen_check_type(Xen_is_number(val), val, 3, S_locsig_set, "a number"); mus_locsig_set(Xen_to_mus_any(obj), Xen_integer_to_C_int(chan), Xen_real_to_C_double(val)); #else mus_locsig_set(Xen_to_mus_any(obj), Xen_integer_to_C_int(chan), s7_number_to_real_with_caller(s7, val, S_locsig_set)); #endif return(val); } static Xen g_locsig_reverb_ref(Xen obj, Xen chan) { #define H_locsig_reverb_ref "(" S_locsig_reverb_ref " gen chan): locsig reverb channel 'chan' scaler" Xen_check_type((mus_is_xen(obj)) && (mus_is_locsig(Xen_to_mus_any(obj))), obj, 1, S_locsig_reverb_ref, "a locsig generator"); Xen_check_type(Xen_is_integer(chan), chan, 2, S_locsig_reverb_ref, "an integer"); return(C_double_to_Xen_real(mus_locsig_reverb_ref(Xen_to_mus_any(obj), Xen_integer_to_C_int(chan)))); } static Xen g_locsig_reverb_set(Xen obj, Xen chan, Xen val) { #define H_locsig_reverb_set "(" S_locsig_reverb_set " gen chan val): set the locsig reverb channel 'chan' scaler to 'val'" Xen_check_type((mus_is_xen(obj)) && (mus_is_locsig(Xen_to_mus_any(obj))), obj, 1, S_locsig_reverb_set, "a locsig generator"); Xen_check_type(Xen_is_integer(chan), chan, 2, S_locsig_reverb_set, "an integer"); #if (!HAVE_SCHEME) Xen_check_type(Xen_is_number(val), val, 3, S_locsig_reverb_set, "a number"); mus_locsig_reverb_set(Xen_to_mus_any(obj), Xen_integer_to_C_int(chan), Xen_real_to_C_double(val)); #else mus_locsig_reverb_set(Xen_to_mus_any(obj), Xen_integer_to_C_int(chan), s7_number_to_real_with_caller(s7, val, S_locsig_reverb_set)); #endif return(val); } static Xen g_is_locsig(Xen obj) { #define H_is_locsig "(" S_is_locsig " gen): " PROC_TRUE " if gen is a " S_locsig return(C_bool_to_Xen_boolean((mus_is_xen(obj)) && (mus_is_locsig(Xen_to_mus_any(obj))))); } static void mus_locsig_or_move_sound_to_vct_or_sound_data(mus_xen *ms, mus_any *loc_gen, mus_long_t pos, bool from_locsig) { mus_float_t *outfr = NULL, *revfr = NULL; Xen output, reverb; #if HAVE_SCHEME int chans, rev_chans; #endif if (pos < 0) return; if (from_locsig) { outfr = mus_locsig_outf(loc_gen); revfr = mus_locsig_revf(loc_gen); #if HAVE_SCHEME chans = mus_locsig_channels(loc_gen); rev_chans = mus_locsig_reverb_channels(loc_gen); #endif } else { outfr = mus_move_sound_outf(loc_gen); revfr = mus_move_sound_revf(loc_gen); #if HAVE_SCHEME chans = mus_move_sound_channels(loc_gen); rev_chans = mus_move_sound_reverb_channels(loc_gen); #endif } output = ms->vcts[G_LOCSIG_OUT]; if (outfr) { if (mus_is_vct(output)) { vct *v; mus_float_t *vdata; v = Xen_to_vct(output); vdata = mus_vct_data(v); if (Xen_vector_rank(output) == 1) { if (pos < mus_vct_length(v)) vdata[pos] += outfr[0]; } #if HAVE_SCHEME else { s7_int chan_len; chan_len = s7_vector_dimensions(output)[1]; /* '(4 20) so each chan len is [1] */ if (pos < chan_len) { int i; for (i = 0; i < chans; i++) vdata[i * chan_len + pos] += outfr[i]; } } #endif } else { if ((Xen_is_vector(output)) && (pos < Xen_vector_length(output))) Xen_vector_set(output, pos, C_double_to_Xen_real(Xen_real_to_C_double(Xen_vector_ref(output, pos)) + outfr[0])); } } if ((revfr) && (Xen_is_bound(ms->vcts[G_LOCSIG_REVOUT]))) { reverb = ms->vcts[G_LOCSIG_REVOUT]; if (mus_is_vct(reverb)) { vct *v; mus_float_t *vdata; v = Xen_to_vct(reverb); vdata = mus_vct_data(v); if (Xen_vector_rank(reverb) == 1) { if (pos < mus_vct_length(v)) vdata[pos] += revfr[0]; } #if HAVE_SCHEME else { s7_int chan_len; chan_len = s7_vector_dimensions(reverb)[1]; if (pos < chan_len) { int i; for (i = 0; i < rev_chans; i++) vdata[i * chan_len + pos] += revfr[i]; } } #endif } else { if ((Xen_is_vector(reverb)) && (pos < Xen_vector_length(reverb))) Xen_vector_set(reverb, pos, C_double_to_Xen_real(Xen_real_to_C_double(Xen_vector_ref(reverb, pos)) + revfr[0])); } } } static Xen g_locsig(Xen xobj, Xen xpos, Xen xval) { #define H_locsig "(" S_locsig " gen loc val): add 'val' to the output of locsig at frample 'loc'" mus_any *loc_gen; mus_xen *ms; mus_long_t pos; mus_float_t fval; ms = (mus_xen *)Xen_object_ref_checked(xobj, mus_xen_tag); if (!ms) Xen_check_type(false, xobj, 1, S_locsig, "a locsig generator"); loc_gen = ms->gen; Xen_check_type(mus_is_locsig(loc_gen), xobj, 1, S_locsig, "a locsig generator"); Xen_check_type(Xen_is_integer(xpos), xpos, 2, S_locsig, "an integer"); pos = Xen_llong_to_C_llong(xpos); if (pos < 0) Xen_out_of_range_error(S_locsig, 2, xpos, "must be >= 0"); #if (!HAVE_SCHEME) Xen_check_type(Xen_is_number(xval), xval, 3, S_locsig, "a number"); fval = Xen_real_to_C_double(xval); #else fval = s7_number_to_real_with_caller(s7, xval, S_locsig); #endif mus_locsig(loc_gen, pos, fval); return(xval); /* changed 30-June-06 to return val rather than a wrapped frample */ } static mus_interp_t clm_locsig_type = MUS_INTERP_LINEAR; static Xen g_locsig_type(void) { #define H_locsig_type "(" S_locsig_type "): locsig interpolation type, either " S_mus_interp_linear " or " S_mus_interp_sinusoidal "." return(C_int_to_Xen_integer((int)clm_locsig_type)); } static Xen g_set_locsig_type(Xen val) { mus_interp_t newval; Xen_check_type(Xen_is_integer(val), val, 1, S_locsig_type, S_mus_interp_linear " or " S_mus_interp_sinusoidal); newval = (mus_interp_t)Xen_integer_to_C_int(val); if ((newval == MUS_INTERP_LINEAR) || (newval == MUS_INTERP_SINUSOIDAL)) clm_locsig_type = newval; return(C_int_to_Xen_integer((int)clm_locsig_type)); } static void clm_locsig_detour(mus_any *ptr, mus_long_t pos) { mus_xen *ms; ms = (mus_xen *)mus_locsig_closure(ptr); /* now check for vct/sound-data special cases */ if (ms->nvcts == 4) mus_locsig_or_move_sound_to_vct_or_sound_data(ms, ms->gen, pos, true); } static Xen g_make_locsig(Xen arglist) { #define H_make_locsig "(" S_make_locsig " (degree 0.0) (distance 1.0) (reverb 0.0) (output *output*) (revout *reverb*) (channels (mus-channels *output*)) (type " S_mus_interp_linear ")): \ return a new generator for signal placement in n channels. Channel 0 corresponds to 0 degrees." mus_any *ge; mus_any *outp = NULL, *revp = NULL; Xen args[14]; Xen keys[7]; Xen ov = Xen_undefined, rv = Xen_undefined; Xen keys3 = Xen_undefined, keys4 = Xen_undefined; int orig_arg[7] = {0, 0, 0, 0, 0, 0, 0}; int vals, out_chans = -1, rev_chans = -1; mus_interp_t type; mus_float_t degree = 0.0, distance = 1.0, reverb = 0.0; type = clm_locsig_type; keys[0] = kw_degree; keys[1] = kw_distance; keys[2] = kw_reverb; keys[3] = kw_output; keys[4] = kw_revout; keys[5] = kw_channels; keys[6] = kw_type; { int i, arglist_len; Xen p; arglist_len = Xen_list_length(arglist); if (arglist_len > 14) clm_error(S_make_locsig, "too many arguments!", arglist); for (i = 0, p = arglist; i < arglist_len; i++, p = Xen_cdr(p)) args[i] = Xen_car(p); for (i = arglist_len; i < 14; i++) args[i] = Xen_undefined; } vals = mus_optkey_unscramble(S_make_locsig, 7, keys, args, orig_arg); if (vals > 0) { degree = Xen_optkey_to_float(kw_degree, keys[0], S_make_locsig, orig_arg[0], degree); distance = Xen_optkey_to_float(kw_distance, keys[1], S_make_locsig, orig_arg[1], distance); reverb = Xen_optkey_to_float(kw_reverb, keys[2], S_make_locsig, orig_arg[2], reverb); if (!(Xen_is_keyword(keys[3]))) keys3 = keys[3]; if (!(Xen_is_keyword(keys[4]))) keys4 = keys[4]; if (!(Xen_is_keyword(keys[5]))) { Xen_check_type(Xen_is_integer(keys[5]), keys[5], orig_arg[5], S_make_locsig, "an integer"); out_chans = Xen_integer_to_C_int(keys[5]); if (out_chans < 0) Xen_out_of_range_error(S_make_locsig, orig_arg[5], keys[5], "chans < 0?"); if (out_chans > mus_max_table_size()) Xen_out_of_range_error(S_make_locsig, orig_arg[5], keys[5], "too many chans"); } type = (mus_interp_t)Xen_optkey_to_int(kw_type, keys[6], S_make_locsig, orig_arg[6], (int)type); if ((type != MUS_INTERP_LINEAR) && (type != MUS_INTERP_SINUSOIDAL)) Xen_out_of_range_error(S_make_locsig, orig_arg[6], keys[6], "type must be " S_mus_interp_linear " or " S_mus_interp_sinusoidal "."); } if (!Xen_is_bound(keys3)) keys3 = CLM_OUTPUT; if (!Xen_is_bound(keys4)) keys4 = CLM_REVERB; /* try to default output to *output* and reverb to *reverb*, if they're currently set and not closed */ /* mus_close is actually mus_close_file = sample_to_file_end = free and nullify obufs so we're hoping dynamic-wind works... */ if ((mus_is_xen(keys3)) && (mus_is_output(Xen_to_mus_any(keys3)))) { outp = (mus_any *)Xen_to_mus_any(keys3); if (out_chans < 0) out_chans = mus_channels((mus_any *)outp); } else { if (mus_is_vct(keys3)) ov = keys3; else Xen_check_type(Xen_is_keyword(keys[3]) || Xen_is_false(keys[3]), keys[3], orig_arg[3], S_make_locsig, "an output gen, " S_vct ", vector, or a sound-data object"); #if HAVE_SCHEME if ((out_chans < 0) && (s7_is_vector(ov)) && (s7_vector_rank(ov) > 1)) out_chans = s7_vector_dimensions(ov)[0]; #endif } if ((mus_is_xen(keys4)) && (mus_is_output(Xen_to_mus_any(keys4)))) { revp = (mus_any *)Xen_to_mus_any(keys4); if (rev_chans < 0) rev_chans = mus_channels((mus_any *)revp); } else { if (mus_is_vct(keys4)) { rv = keys4; rev_chans = 1; #if HAVE_SCHEME if (Xen_vector_rank(rv) > 1) rev_chans = s7_vector_dimensions(rv)[0]; #endif } else Xen_check_type(Xen_is_keyword(keys[4]) || Xen_is_false(keys[4]), keys[4], orig_arg[4], S_make_locsig, "a reverb output generator"); } if (out_chans < 0) out_chans = 1; if (rev_chans < 0) rev_chans = 0; ge = mus_make_locsig(degree, distance, reverb, out_chans, outp, rev_chans, revp, type); if (ge) { mus_xen *gn; if (((Xen_is_bound(ov)) && (!Xen_is_false(ov))) || ((Xen_is_bound(rv)) && (!Xen_is_false(rv)))) gn = mx_alloc(4); else gn = mx_alloc(2); /* these two are for the mus-data and mus-xcoeffs methods in Scheme (etc) = MUS_DATA_WRAPPER and G_FILTER_XCOEFFS */ if (out_chans > 0) gn->vcts[G_LOCSIG_DATA] = xen_make_vct_wrapper(out_chans, mus_data(ge)); else gn->vcts[G_LOCSIG_DATA] = Xen_undefined; if (rev_chans > 0) gn->vcts[G_LOCSIG_REVDATA] = xen_make_vct_wrapper(rev_chans, mus_xcoeffs(ge)); else gn->vcts[G_LOCSIG_REVDATA] = Xen_undefined; if (gn->nvcts == 4) { mus_locsig_set_detour(ge, clm_locsig_detour); gn->vcts[G_LOCSIG_OUT] = ov; gn->vcts[G_LOCSIG_REVOUT] = rv; mus_set_environ(ge, (void *)gn); } gn->gen = ge; return(mus_xen_to_object(gn)); } return(Xen_false); } static Xen g_move_locsig(Xen obj, Xen degree, Xen distance) { #define H_move_locsig "(" S_move_locsig " gen degree distance): move locsig gen to reflect degree and distance" Xen_check_type((mus_is_xen(obj)) && (mus_is_locsig(Xen_to_mus_any(obj))), obj, 1, S_move_locsig, "a locsig generator"); #if (!HAVE_SCHEME) Xen_check_type(Xen_is_number(degree), degree, 2, S_move_locsig, "a number in degrees"); Xen_check_type(Xen_is_number(distance), distance, 3, S_move_locsig, "a number > 1.0"); mus_move_locsig(Xen_to_mus_any(obj), Xen_real_to_C_double(degree), Xen_real_to_C_double(distance)); #else mus_move_locsig(Xen_to_mus_any(obj), s7_number_to_real_with_caller(s7, degree, S_move_locsig), s7_number_to_real_with_caller(s7, distance, S_move_locsig)); #endif return(obj); } /* ---------------- move-sound ---------------- */ static Xen g_is_move_sound(Xen obj) { #define H_is_move_sound "(" S_is_move_sound " gen): " PROC_TRUE " if gen is a " S_move_sound return(C_bool_to_Xen_boolean((mus_is_xen(obj)) && (mus_is_move_sound(Xen_to_mus_any(obj))))); } static Xen g_move_sound(Xen obj, Xen loc, Xen val) { #define H_move_sound "(" S_move_sound " gen loc val): dlocsig run-time generator handling 'val' at sample 'loc'" mus_any *move_gen; mus_xen *ms; mus_long_t pos; mus_float_t fval; Xen_check_type(mus_is_xen(obj), obj, 1, S_move_sound, "a move-sound generator"); ms = Xen_to_mus_xen(obj); move_gen = (mus_any *)(ms->gen); Xen_check_type(mus_is_move_sound(move_gen), obj, 1, S_move_sound, "a move-sound generator"); Xen_check_type(Xen_is_integer(loc), loc, 2, S_move_sound, "an integer"); Xen_check_type(Xen_is_number(val), val, 3, S_move_sound, "a number"); pos = Xen_llong_to_C_llong(loc); if (pos < 0) Xen_out_of_range_error(S_move_sound, 2, loc, "must be >= 0"); fval = Xen_real_to_C_double(val); mus_move_sound(move_gen, pos, fval); return(val); } static mus_any **xen_vector_to_mus_any_array(Xen vect) { mus_any **gens; mus_long_t i, len; if (!(Xen_is_vector(vect))) return(NULL); len = Xen_vector_length(vect); gens = (mus_any **)calloc(len, sizeof(mus_any *)); for (i = 0; i < len; i++) if (mus_is_xen(Xen_vector_ref(vect, i))) gens[i] = Xen_to_mus_any(Xen_vector_ref(vect, i)); return(gens); } static int *xen_vector_to_int_array(Xen vect) { int *vals; mus_long_t i, len; len = Xen_vector_length(vect); vals = (int *)calloc(len, sizeof(int)); for (i = 0; i < len; i++) vals[i] = Xen_integer_to_C_int(Xen_vector_ref(vect, i)); return(vals); } static void clm_move_sound_detour(mus_any *ptr, mus_long_t pos) { mus_xen *ms; ms = (mus_xen *)mus_move_sound_closure(ptr); /* now check for vct/sound-data special cases */ if (ms->nvcts == 4) mus_locsig_or_move_sound_to_vct_or_sound_data(ms, ms->gen, pos, false); } static Xen g_make_move_sound(Xen dloc_list, Xen outp, Xen revp) { Xen ov = Xen_undefined, rv = Xen_undefined; mus_any *ge, *dopdly, *dopenv, *globrevenv = NULL, *output = NULL, *revput = NULL; mus_any **out_delays, **out_envs, **rev_envs; int *out_map; mus_long_t start, end; int outchans = 0, revchans = 0; Xen ref; #define H_make_move_sound "(" S_make_move_sound " dloc-list (out *output*) (rev *reverb*)): make a dlocsig run-time generator" /* dloc-list is (list start end outchans revchans dopdly dopenv revenv outdelays outenvs revenvs outmap) */ /* outdelays envs and revenvs are vectors */ Xen_check_type(Xen_is_list(dloc_list) && (Xen_list_length(dloc_list) == 11), dloc_list, 1, S_make_move_sound, "a dlocsig list"); if (!Xen_is_bound(outp)) outp = CLM_OUTPUT; if (!Xen_is_bound(revp)) revp = CLM_REVERB; if (mus_is_xen(outp)) { output = Xen_to_mus_any(outp); Xen_check_type(mus_is_output(output), outp, 2, S_make_move_sound, "output stream"); } else { if ((mus_is_vct(outp)) || (Xen_is_false(outp)) || (!Xen_is_bound(outp))) ov = outp; else Xen_check_type(false, outp, 2, S_make_move_sound, "output stream, " S_vct ", or a sound-data object"); } if (mus_is_xen(revp)) { revput = Xen_to_mus_any(revp); Xen_check_type(mus_is_output(revput), revp, 3, S_make_move_sound, "reverb stream"); } else { if ((mus_is_vct(revp)) || (Xen_is_false(revp)) || (!Xen_is_bound(revp))) rv = revp; else Xen_check_type(false, revp, 3, S_make_move_sound, "reverb stream, " S_vct ", or a sound-data object"); } ref = Xen_list_ref(dloc_list, 0); Xen_check_type(Xen_is_llong(ref), ref, 1, S_make_move_sound, "dlocsig list[0] (start): a sample number"); start = Xen_llong_to_C_llong(ref); ref = Xen_list_ref(dloc_list, 1); Xen_check_type(Xen_is_llong(ref), ref, 1, S_make_move_sound, "dlocsig list[1] (end): a sample number"); end = Xen_llong_to_C_llong(ref); ref = Xen_list_ref(dloc_list, 2); Xen_check_type(Xen_is_integer(ref), ref, 1, S_make_move_sound, "dlocsig list[2] (outchans): an integer"); outchans = Xen_integer_to_C_int(ref); ref = Xen_list_ref(dloc_list, 3); Xen_check_type(Xen_is_integer(ref), ref, 1, S_make_move_sound, "dlocsig list[3] (revchans): an integer"); revchans = Xen_integer_to_C_int(ref); ref = Xen_list_ref(dloc_list, 4); Xen_check_type(mus_is_xen(ref), ref, 1, S_make_move_sound, "dlocsig list[4] (doppler delay): a delay generator"); dopdly = Xen_to_mus_any(ref); Xen_check_type(mus_is_delay(dopdly), ref, 1, S_make_move_sound, "dlocsig list[4] (doppler delay): a delay generator"); ref = Xen_list_ref(dloc_list, 5); Xen_check_type(mus_is_xen(ref), ref, 1, S_make_move_sound, "dlocsig list[5] (doppler env): an env generator"); dopenv = Xen_to_mus_any(ref); Xen_check_type(mus_is_env(dopenv), ref, 1, S_make_move_sound, "dlocsig list[5] (doppler env): an env generator"); ref = Xen_list_ref(dloc_list, 6); Xen_check_type(Xen_is_false(ref) || mus_is_xen(ref), ref, 1, S_make_move_sound, "dlocsig list[6] (global rev env): an env generator"); if (mus_is_xen(ref)) { globrevenv = Xen_to_mus_any(ref); Xen_check_type(mus_is_env(globrevenv), ref, 1, S_make_move_sound, "dlocsig list[6] (global rev env): an env generator"); } ref = Xen_list_ref(dloc_list, 7); Xen_check_type(Xen_is_vector(ref) && ((int)Xen_vector_length(ref) >= outchans), ref, 1, S_make_move_sound, "dlocsig list[7] (out delays): a vector of delay gens"); ref = Xen_list_ref(dloc_list, 8); Xen_check_type(Xen_is_false(ref) || (Xen_is_vector(ref) && ((int)Xen_vector_length(ref) >= outchans)), ref, 1, S_make_move_sound, "dlocsig list[8] (out envs): " PROC_FALSE " or a vector of envs"); ref = Xen_list_ref(dloc_list, 9); Xen_check_type(Xen_is_false(ref) || (Xen_is_vector(ref) && ((int)Xen_vector_length(ref) >= revchans)), ref, 1, S_make_move_sound, "dlocsig list[9] (rev envs): " PROC_FALSE " or a vector of envs"); ref = Xen_list_ref(dloc_list, 10); Xen_check_type(Xen_is_vector(ref) && ((int)Xen_vector_length(ref) >= outchans), ref, 1, S_make_move_sound, "dlocsig list[10] (out map): vector of ints"); /* put off allocation until all type error checks are done */ out_delays = xen_vector_to_mus_any_array(Xen_list_ref(dloc_list, 7)); out_envs = xen_vector_to_mus_any_array(Xen_list_ref(dloc_list, 8)); rev_envs = xen_vector_to_mus_any_array(Xen_list_ref(dloc_list, 9)); out_map = xen_vector_to_int_array(Xen_list_ref(dloc_list, 10)); ge = mus_make_move_sound(start, end, outchans, revchans, dopdly, dopenv, globrevenv, out_delays, out_envs, rev_envs, out_map, output, revput, true, false); /* free outer arrays but not gens */ if (ge) { mus_xen *gn; if (((Xen_is_bound(ov)) && (!Xen_is_false(ov))) || ((Xen_is_bound(rv)) && (!Xen_is_false(rv)))) gn = mx_alloc(4); else gn = mx_alloc(1); gn->vcts[G_LOCSIG_DATA] = dloc_list; /* it is crucial that the list be gc-protected! */ if (gn->nvcts == 4) { mus_move_sound_set_detour(ge, clm_move_sound_detour); gn->vcts[G_LOCSIG_OUT] = ov; gn->vcts[G_LOCSIG_REVOUT] = rv; gn->vcts[G_LOCSIG_REVDATA] = Xen_undefined; mus_set_environ(ge, (void *)gn); } gn->gen = ge; return(mus_xen_to_object(gn)); } return(Xen_false); } /* ---------------- src ---------------- */ static Xen xen_one, xen_minus_one; #if HAVE_SCHEME static Xen as_needed_arglist; static s7_pointer env_symbol, polywave_symbol, triangle_wave_symbol, rand_interp_symbol, oscil_symbol; static s7_pointer multiply_symbol, add_symbol, vector_ref_symbol, quote_symbol, cos_symbol, comb_bank_symbol; static mus_float_t as_needed_input_float(void *ptr, int direction) { mus_xen *gn = (mus_xen *)ptr; return(s7_real(gn->vcts[MUS_INPUT_DATA])); } static mus_float_t as_needed_block_input_float(void *ptr, int direction, mus_float_t *data, mus_long_t start, mus_long_t end) { mus_xen *gn = (mus_xen *)ptr; mus_float_t val; mus_long_t i, lim4; lim4 = end - 4; val = (mus_float_t)s7_real(gn->vcts[MUS_INPUT_DATA]); /* set in the chooser below */ for (i = start; i <= lim4;) { data[i++] = val; data[i++] = val; data[i++] = val; data[i++] = val; } for (;i < end; i++) data[i] = val; return(val); } static mus_float_t as_needed_input_any(void *ptr, int direction) { mus_xen *gn = (mus_xen *)ptr; s7_set_car(as_needed_arglist, (direction == 1) ? xen_one : xen_minus_one); return(s7_number_to_real(s7, s7_apply_function(s7, gn->vcts[MUS_INPUT_FUNCTION], as_needed_arglist))); } #endif static mus_float_t as_needed_input_generator(void *ptr, int direction) { #if HAVE_EXTENSION_LANGUAGE return(mus_apply((mus_any *)(((mus_xen *)ptr)->vcts[MUS_INPUT_DATA]), 0.0, 0.0)); #else return(0.0); #endif } static mus_float_t as_needed_block_input_generator(void *ptr, int direction, mus_float_t *data, mus_long_t start, mus_long_t end) { #if HAVE_EXTENSION_LANGUAGE mus_any *g; mus_long_t i; g = (mus_any *)(((mus_xen *)ptr)->vcts[MUS_INPUT_DATA]); for (i = start; i < end; i++) data[i] = mus_apply(g, 0.0, 0.0); #endif return(0.0); } static mus_float_t as_needed_input_readin(void *ptr, int direction) { #if HAVE_EXTENSION_LANGUAGE return(mus_readin((mus_any *)(((mus_xen *)ptr)->vcts[MUS_INPUT_DATA]))); #else return(0.0); #endif } static mus_float_t as_needed_block_input_readin(void *ptr, int direction, mus_float_t *data, mus_long_t start, mus_long_t end) { #if HAVE_EXTENSION_LANGUAGE mus_any *g; mus_long_t i; g = (mus_any *)(((mus_xen *)ptr)->vcts[MUS_INPUT_DATA]); for (i = start; i < end; i++) data[i] = mus_readin(g); #endif return(0.0); } #if USE_SND && HAVE_SCHEME static mus_float_t as_needed_input_sampler(void *ptr, int direction) { return(read_sample((snd_fd *)(((mus_xen *)ptr)->vcts[MUS_INPUT_DATA]))); } static mus_float_t as_needed_block_input_sampler(void *ptr, int direction, mus_float_t *data, mus_long_t start, mus_long_t end) { snd_fd *p; mus_long_t i; p = (snd_fd *)(((mus_xen *)ptr)->vcts[MUS_INPUT_DATA]); for (i = start; i < end; i++) data[i] = read_sample(p); return(0.0); } mus_float_t read_sample_with_direction(void *p, int dir); static mus_float_t as_needed_input_sampler_with_direction(void *ptr, int direction) { return(read_sample_with_direction((snd_fd *)(((mus_xen *)ptr)->vcts[MUS_INPUT_DATA]), direction)); } static mus_float_t as_needed_block_input_sampler_with_direction(void *ptr, int direction, mus_float_t *data, mus_long_t start, mus_long_t end) { snd_fd *p; mus_long_t i; p = (snd_fd *)(((mus_xen *)ptr)->vcts[MUS_INPUT_DATA]); for (i = start; i < end; i++) data[i] = read_sample_with_direction(p, direction); return(0.0); } #endif static mus_float_t as_needed_input_func(void *ptr, int direction) /* intended for "as-needed" input funcs */ { mus_xen *gn = (mus_xen *)ptr; if (gn) { Xen in_obj; in_obj = gn->vcts[MUS_INPUT_FUNCTION]; if (Xen_is_procedure(in_obj)) return(Xen_real_to_C_double(Xen_unprotected_call_with_1_arg(gn->vcts[MUS_INPUT_FUNCTION], (direction == 1) ? xen_one : xen_minus_one))); } return(0.0); } #if HAVE_SCHEME static mus_float_t as_needed_input_rf(void *ptr, int direction) { mus_xen *gn = (mus_xen *)ptr; if (gn) { s7_rf_t rf; s7_pointer *top, *p; rf = (s7_rf_t)(gn->vcts[MUS_INPUT_FUNCTION]); top = s7_xf_top(s7, (void *)(gn->vcts[MUS_INPUT_DATA])); p = top; return(rf(s7, &p)); } return(0.0); } static mus_float_t as_needed_block_input_rf(void *ptr, int direction, mus_float_t *data, mus_long_t start, mus_long_t end) { mus_xen *gn = (mus_xen *)ptr; if (gn) { mus_long_t i; s7_rf_t rf; s7_pointer *top, *p; rf = (s7_rf_t)(gn->vcts[MUS_INPUT_FUNCTION]); top = s7_xf_top(s7, (void *)(gn->vcts[MUS_INPUT_DATA])); for (i = start; i < end; i++) { p = top; data[i] = rf(s7, &p); } } return(0.0); } #endif static void set_as_needed_input_choices(mus_any *gen, Xen obj, mus_xen *gn) { /* fprintf(stderr, "set_as_needed_input for %s: %s\n", mus_name(gen), DISPLAY(obj)); */ if (mus_is_xen(obj)) /* input function is a generator */ { mus_any *p; p = Xen_to_mus_any(obj); if (p) { #if HAVE_EXTENSION_LANGUAGE gn->vcts[MUS_INPUT_DATA] = (Xen)p; #endif if (mus_is_readin(p)) mus_generator_set_feeders(gen, as_needed_input_readin, as_needed_block_input_readin); else mus_generator_set_feeders(gen, as_needed_input_generator, as_needed_block_input_generator); return; } } #if HAVE_SCHEME if (Xen_is_procedure(obj)) { s7_pointer body; body = s7_closure_body(s7, obj); if (s7_is_pair(body)) { if (s7_is_null(s7, s7_cdr(body))) { s7_pointer res; res = s7_car(body); if (s7_is_real(res)) { gn->vcts[MUS_INPUT_DATA] = res; mus_generator_set_feeders(gen, as_needed_input_float, as_needed_block_input_float); return; } if (s7_is_pair(res)) { if (s7_is_symbol(s7_car(res))) { s7_pointer fcar; fcar = s7_symbol_value(s7, s7_car(res)); if (s7_rf_function(s7, fcar)) { s7_rf_t rf; s7_pointer old_e, e; e = s7_sublet(s7, s7_closure_let(s7, obj), s7_nil(s7)); old_e = s7_set_curlet(s7, e); s7_xf_new(s7, e); rf = s7_rf_function(s7, fcar)(s7, res); if (rf) { /* fprintf(stderr, "try %s\n", DISPLAY(res)); */ gn->vcts[MUS_INPUT_DATA] = (s7_pointer)s7_xf_detach(s7); gn->vcts[MUS_INPUT_FUNCTION] = (s7_pointer)rf; gn->free_data = true; mus_generator_set_feeders(gen, as_needed_input_rf, as_needed_block_input_rf); s7_set_curlet(s7, old_e); return; } s7_xf_free(s7); s7_set_curlet(s7, old_e); } } #if USE_SND { s7_pointer arg; arg = s7_car(s7_closure_args(s7, obj)); if ((arg == s7_caddr(res)) && (s7_car(res) == s7_make_symbol(s7, "read-sample-with-direction"))) { gn->vcts[MUS_INPUT_DATA] = (Xen)xen_to_sampler(s7_symbol_local_value(s7, s7_cadr(res), s7_closure_let(s7, obj))); mus_generator_set_feeders(gen, as_needed_input_sampler_with_direction, as_needed_block_input_sampler_with_direction); return; } } #endif } } } #if USE_SND /* check for a sampler (snd-edits.c) */ if (is_sampler(obj)) { gn->vcts[MUS_INPUT_DATA] = (Xen)xen_to_sampler(obj); mus_generator_set_feeders(gen, as_needed_input_sampler, as_needed_block_input_sampler); return; } mus_generator_set_feeders(gen, as_needed_input_any, NULL); return; #endif } #endif mus_generator_set_feeders(gen, as_needed_input_func, NULL); } static Xen g_mus_clear_sincs(void) { mus_clear_sinc_tables(); return(Xen_false); } static Xen g_is_src(Xen obj) { #define H_is_src "(" S_is_src " gen): " PROC_TRUE " if gen is an " S_src return(C_bool_to_Xen_boolean((mus_is_xen(obj)) && (mus_is_src(Xen_to_mus_any(obj))))); } #define SRC_CHANGE_MAX 1000000.0 static Xen g_src(Xen obj, Xen pm, Xen func) { #define H_src "(" S_src " gen (pm 0.0) input-function): next sampling rate conversion sample. \ 'pm' can be used to change the sampling rate on a sample-by-sample basis. 'input-function' \ is a function of one argument (the current input direction, normally ignored) that is called \ internally whenever a new sample of input data is needed. If the associated " S_make_src " \ included an 'input' argument, input-function is ignored." mus_float_t pm1 = 0.0; mus_xen *gn; mus_any *g = NULL; Xen_to_C_generator(obj, gn, g, mus_is_src, S_src, "an src generator"); Xen_real_to_C_double_if_bound(pm, pm1, S_src, 2); /* if sr_change (pm1) is ridiculous, complain! */ if ((pm1 > SRC_CHANGE_MAX) || (pm1 < -SRC_CHANGE_MAX)) Xen_out_of_range_error(S_src, 2, pm, "src change too large"); if (!Xen_is_bound(gn->vcts[MUS_INPUT_DATA])) { if (Xen_is_procedure(func)) { if (Xen_is_aritable(func, 1)) gn->vcts[MUS_INPUT_FUNCTION] = func; else Xen_bad_arity_error(S_src, 3, func, "src input function wants 1 arg"); } } return(C_double_to_Xen_real(mus_src(g, pm1, NULL))); } static void set_gn_gen(void *p, mus_any *g) { mus_xen *gn = (mus_xen *)p; gn->gen = g; } static Xen g_make_src(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6) { #define H_make_src "(" S_make_src " input (srate 1.0) (width 10)): \ return a new sampling-rate conversion generator (using 'warped sinc interpolation'). \ 'srate' is the ratio between the new rate and the old. 'width' is the sine \ width (effectively the steepness of the low-pass filter), normally between 10 and 100. \ 'input' if given is an open file stream." Xen in_obj = Xen_undefined; mus_xen *gn; mus_any *ge = NULL; int vals, wid = 0; /* 0 here picks up the current default width in clm.c */ Xen args[6]; Xen keys[3]; int orig_arg[3] = {0, 0, 0}; mus_float_t srate = 1.0; keys[0] = kw_input; keys[1] = kw_srate; keys[2] = kw_width; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; vals = mus_optkey_unscramble(S_make_src, 3, keys, args, orig_arg); if (vals > 0) { in_obj = mus_optkey_to_input_procedure(keys[0], S_make_src, orig_arg[0], Xen_undefined, 1, "src input procedure takes 1 arg"); srate = Xen_optkey_to_float(kw_srate, keys[1], S_make_src, orig_arg[1], srate); /* srate can be negative => read in reverse */ wid = Xen_optkey_to_int(kw_width, keys[2], S_make_src, orig_arg[2], wid); if (wid < 0) Xen_out_of_range_error(S_make_src, orig_arg[2], keys[2], "width < 0?"); if (wid > 2000) Xen_out_of_range_error(S_make_src, orig_arg[2], keys[2], "width > 2000?"); } gn = mx_alloc(MUS_MAX_VCTS); {int i; for (i = 0; i < MUS_MAX_VCTS; i++) gn->vcts[i] = Xen_undefined;} /* mus_make_src assumes it can invoke the input function! */ gn->vcts[MUS_INPUT_FUNCTION] = in_obj; { mus_error_handler_t *old_error_handler; old_error_handler = mus_error_set_handler(local_mus_error); ge = mus_make_src_with_init(NULL, srate, wid, gn, set_gn_gen); mus_error_set_handler(old_error_handler); } if (ge) { Xen src_obj; #if HAVE_SCHEME int loc; #endif gn->gen = ge; src_obj = mus_xen_to_object(gn); #if HAVE_SCHEME loc = s7_gc_protect(s7, src_obj); #endif /* src_init can call an input function which can trigger the GC, so we need to GC-protect the new object */ gn->vcts[MUS_SELF_WRAPPER] = src_obj; set_as_needed_input_choices(ge, in_obj, gn); mus_src_init(ge); #if HAVE_SCHEME s7_gc_unprotect_at(s7, loc); #endif return(src_obj); } free(gn->vcts); free(gn); return(clm_mus_error(local_error_type, local_error_msg, S_make_src)); } /* ---------------- granulate ---------------- */ static Xen g_is_granulate(Xen obj) { #define H_is_granulate "(" S_is_granulate " gen): " PROC_TRUE " if gen is a " S_granulate " generator" return(C_bool_to_Xen_boolean((mus_is_xen(obj)) && (mus_is_granulate(Xen_to_mus_any(obj))))); } static int grnedit(void *ptr) { mus_xen *gn = (mus_xen *)ptr; return(Xen_integer_to_C_int(Xen_unprotected_call_with_1_arg(gn->vcts[MUS_EDIT_FUNCTION], gn->vcts[MUS_SELF_WRAPPER]))); } static Xen g_granulate(Xen obj, Xen func, Xen edit_func) { #define H_granulate "(" S_granulate " gen input-func edit-func): next sample from granular synthesis generator" mus_xen *gn; mus_any *g = NULL; Xen_to_C_generator(obj, gn, g, mus_is_granulate, S_granulate, "a granulate generator"); if ((Xen_is_bound(func)) && (!Xen_is_bound(gn->vcts[MUS_INPUT_DATA]))) { if (Xen_is_procedure(func)) { if (Xen_is_aritable(func, 1)) gn->vcts[MUS_INPUT_FUNCTION] = func; else Xen_bad_arity_error(S_granulate, 2, func, "granulate input function wants 1 arg"); } if (Xen_is_procedure(edit_func)) { if (Xen_is_aritable(edit_func, 1)) { if (!(Xen_is_bound(gn->vcts[MUS_EDIT_FUNCTION]))) /* default value is Xen_undefined */ { mus_granulate_set_edit_function(gn->gen, grnedit); gn->vcts[MUS_EDIT_FUNCTION] = edit_func; } } else Xen_bad_arity_error(S_granulate, 3, edit_func, "granulate edit function wants 1 arg"); } } return(C_double_to_Xen_real(mus_granulate(g, NULL))); } static Xen g_make_granulate(Xen arglist) { #define H_make_granulate "(" S_make_granulate " input (expansion 1.0) (length .15) (scaler .6) (hop .05) (ramp .4) (jitter 1.0) max-size edit): \ return a new granular synthesis generator. 'length' is the grain length (seconds), 'expansion' is the ratio in timing \ between the new and old (expansion > 1.0 slows things down), 'scaler' scales the grains \ to avoid overflows, 'hop' is the spacing (seconds) between successive grains upon output. \ 'jitter' controls the randomness in that spacing, 'input' can be a file pointer. 'edit' can \ be a function of one arg, the current granulate generator. It is called just before \ a grain is added into the output buffer. The current grain is accessible via " S_mus_data ". \ The edit function, if any, should return the length in samples of the grain, or 0." Xen in_obj = Xen_undefined; mus_xen *gn; mus_any *ge; Xen args[18]; Xen keys[9]; int orig_arg[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; int vals, maxsize = 0; mus_float_t expansion = 1.0, segment_length = .15, segment_scaler = .6, ramp_time = .4, output_hop = .05; mus_float_t jitter = 1.0; Xen edit_obj = Xen_undefined, grn_obj; keys[0] = kw_input; keys[1] = kw_expansion; keys[2] = kw_length; keys[3] = kw_scaler; keys[4] = kw_hop; keys[5] = kw_ramp; keys[6] = kw_jitter; keys[7] = kw_max_size; keys[8] = kw_edit; { int i, arglist_len; Xen p; arglist_len = Xen_list_length(arglist); if (arglist_len > 18) clm_error(S_make_granulate, "too many arguments!", arglist); for (i = 0, p = arglist; i < arglist_len; i++, p = Xen_cdr(p)) args[i] = Xen_car(p); for (i = arglist_len; i < 18; i++) args[i] = Xen_undefined; } vals = mus_optkey_unscramble(S_make_granulate, 9, keys, args, orig_arg); if (vals > 0) { in_obj = mus_optkey_to_input_procedure(keys[0], S_make_granulate, orig_arg[0], Xen_undefined, 1, "granulate input procedure takes 1 arg"); expansion = Xen_optkey_to_float(kw_expansion, keys[1], S_make_granulate, orig_arg[1], expansion); if (expansion <= 0.0) Xen_out_of_range_error(S_make_granulate, orig_arg[1], keys[1], "expansion <= 0.0?"); segment_length = Xen_optkey_to_float(kw_length, keys[2], S_make_granulate, orig_arg[2], segment_length); if (segment_length <= 0.0) Xen_out_of_range_error(S_make_granulate, orig_arg[2], keys[2], "segment-length <= 0.0?"); segment_scaler = Xen_optkey_to_float(kw_scaler, keys[3], S_make_granulate, orig_arg[3], segment_scaler); if (segment_scaler == 0.0) Xen_out_of_range_error(S_make_granulate, orig_arg[3], keys[3], "segment-scaler should be greater than 0.0?"); output_hop = Xen_optkey_to_float(kw_hop, keys[4], S_make_granulate, orig_arg[4], output_hop); if (output_hop <= 0.0) Xen_out_of_range_error(S_make_granulate, orig_arg[4], keys[4], "hop <= 0?"); if (output_hop > 3600.0) Xen_out_of_range_error(S_make_granulate, orig_arg[4], keys[4], "hop > 3600?"); if ((segment_length + output_hop) > 60.0) /* multiplied by srate in mus_make_granulate in array allocation */ Xen_out_of_range_error(S_make_granulate, orig_arg[2], Xen_list_2(keys[2], keys[4]), "segment_length + output_hop too large!"); ramp_time = Xen_optkey_to_float(kw_ramp, keys[5], S_make_granulate, orig_arg[5], ramp_time); if ((ramp_time < 0.0) || (ramp_time > 0.5)) Xen_out_of_range_error(S_make_granulate, orig_arg[5], keys[5], "ramp must be between 0.0 and 0.5"); jitter = Xen_optkey_to_float(kw_jitter, keys[6], S_make_granulate, orig_arg[6], jitter); Xen_check_type((jitter >= 0.0) && (jitter < 100.0), keys[6], orig_arg[6], S_make_granulate, "0.0 .. 100.0"); maxsize = Xen_optkey_to_int(kw_max_size, keys[7], S_make_granulate, orig_arg[7], maxsize); if ((maxsize > mus_max_malloc()) || (maxsize < 0) || ((maxsize == 0) && (!Xen_is_keyword(keys[7])))) Xen_out_of_range_error(S_make_granulate, orig_arg[7], keys[7], "max-size invalid"); edit_obj = mus_optkey_to_procedure(keys[8], S_make_granulate, orig_arg[8], Xen_undefined, 1, "granulate edit procedure takes 1 arg"); } gn = mx_alloc(MUS_MAX_VCTS); {int i; for (i = 0; i < MUS_MAX_VCTS; i++) gn->vcts[i] = Xen_undefined;} { mus_error_handler_t *old_error_handler; old_error_handler = mus_error_set_handler(local_mus_error); ge = mus_make_granulate(NULL, expansion, segment_length, segment_scaler, output_hop, ramp_time, jitter, maxsize, (!Xen_is_bound(edit_obj) ? NULL : grnedit), (void *)gn); mus_error_set_handler(old_error_handler); } if (ge) { gn->vcts[MUS_DATA_WRAPPER] = xen_make_vct_wrapper(mus_granulate_grain_max_length(ge), mus_data(ge)); gn->vcts[MUS_INPUT_FUNCTION] = in_obj; gn->vcts[MUS_EDIT_FUNCTION] = edit_obj; gn->gen = ge; grn_obj = mus_xen_to_object(gn); gn->vcts[MUS_SELF_WRAPPER] = grn_obj; set_as_needed_input_choices(ge, in_obj, gn); return(grn_obj); } free(gn->vcts); free(gn); return(clm_mus_error(local_error_type, local_error_msg, S_make_granulate)); } /* ---------------- convolve ---------------- */ static Xen g_is_convolve(Xen obj) { #define H_is_convolve "(" S_is_convolve " gen): " PROC_TRUE " if gen is a " S_convolve " generator" return(C_bool_to_Xen_boolean((mus_is_xen(obj)) && (mus_is_convolve(Xen_to_mus_any(obj))))); } static Xen g_convolve(Xen obj, Xen func) { #define H_convolve_gen "(" S_convolve " gen input-func): next sample from convolution generator" mus_xen *gn; mus_any *g = NULL; Xen_to_C_generator(obj, gn, g, mus_is_convolve, S_convolve, "a convolve generator"); if (!Xen_is_bound(gn->vcts[MUS_INPUT_DATA])) { if (Xen_is_procedure(func)) { if (Xen_is_aritable(func, 1)) gn->vcts[MUS_INPUT_FUNCTION] = func; else Xen_bad_arity_error(S_convolve, 2, func, "convolve input function wants 1 arg"); } } return(C_double_to_Xen_real(mus_convolve(g, NULL))); } /* filter-size? */ static Xen g_make_convolve(Xen arglist) { #define H_make_convolve "(" S_make_convolve " input filter fft-size): \ return a new convolution generator which convolves its input with the impulse response 'filter'." mus_xen *gn; mus_any *ge; Xen args[6]; Xen keys[3]; int orig_arg[3] = {0, 0, 0}; int vals; vct *filter = NULL; Xen filt = Xen_undefined, in_obj = Xen_undefined; mus_long_t fftlen, fft_size = 0; keys[0] = kw_input; keys[1] = kw_filter; keys[2] = kw_fft_size; { int i, arglist_len; Xen p; arglist_len = Xen_list_length(arglist); if (arglist_len > 6) clm_error(S_make_convolve, "too many arguments!", arglist); for (i = 0, p = arglist; i < arglist_len; i++, p = Xen_cdr(p)) args[i] = Xen_car(p); for (i = arglist_len; i < 6; i++) args[i] = Xen_undefined; } vals = mus_optkey_unscramble(S_make_convolve, 3, keys, args, orig_arg); if (vals > 0) { in_obj = mus_optkey_to_input_procedure(keys[0], S_make_convolve, orig_arg[0], Xen_undefined, 1, "convolve input procedure takes 1 arg"); filter = mus_optkey_to_vct(keys[1], S_make_convolve, orig_arg[1], NULL); if (filter) filt = keys[1]; fft_size = Xen_optkey_to_mus_long_t(kw_fft_size, keys[2], S_make_convolve, orig_arg[2], fft_size); if ((fft_size < 0) || ((fft_size == 0) && (!Xen_is_keyword(keys[2]))) || (fft_size > mus_max_malloc())) Xen_out_of_range_error(S_make_convolve, orig_arg[2], keys[2], "fft-size invalid (see mus-max-malloc))"); } if (filter == NULL) Xen_error(NO_DATA, Xen_list_1(C_string_to_Xen_string(S_make_convolve ": no impulse (filter)?"))); if (is_power_of_2(mus_vct_length(filter))) fftlen = mus_vct_length(filter) * 2; else fftlen = (mus_long_t)pow(2.0, 1 + (int)(log((mus_float_t)(mus_vct_length(filter) + 1)) / log(2.0))); if (fft_size < fftlen) fft_size = fftlen; gn = mx_alloc(MUS_MAX_VCTS); {int i; for (i = 0; i < MUS_MAX_VCTS; i++) gn->vcts[i] = Xen_undefined;} { mus_error_handler_t *old_error_handler; old_error_handler = mus_error_set_handler(local_mus_error); ge = mus_make_convolve(NULL, mus_vct_data(filter), fft_size, mus_vct_length(filter), gn); mus_error_set_handler(old_error_handler); } if (ge) { Xen c_obj; gn->vcts[MUS_INPUT_FUNCTION] = in_obj; gn->vcts[MUS_ANALYZE_FUNCTION] = filt; /* why is this here? GC protection? (might be a locally-allocated vct as from file->vct) */ gn->gen = ge; c_obj = mus_xen_to_object(gn); gn->vcts[MUS_SELF_WRAPPER] = c_obj; set_as_needed_input_choices(ge, in_obj, gn); return(c_obj); } free(gn->vcts); free(gn); return(clm_mus_error(local_error_type, local_error_msg, S_make_convolve)); } static Xen g_convolve_files(Xen file1, Xen file2, Xen maxamp, Xen outfile) { #define H_convolve_files "(" S_convolve_files " file1 file2 maxamp output-file): convolve \ file1 and file2 writing outfile after scaling the convolution result to maxamp." const char *f1, *f2, *f3; mus_float_t maxval = 1.0; Xen_check_type(Xen_is_string(file1), file1, 1, S_convolve_files, "a string"); Xen_check_type(Xen_is_string(file2), file2, 2, S_convolve_files, "a string"); Xen_check_type(Xen_is_number_or_unbound(maxamp), maxamp, 3, S_convolve_files, "a number"); Xen_check_type((!Xen_is_bound(outfile)) || (Xen_is_string(outfile)), outfile, 4, S_convolve_files, "a string"); f1 = Xen_string_to_C_string(file1); f2 = Xen_string_to_C_string(file2); if (Xen_is_string(outfile)) f3 = Xen_string_to_C_string(outfile); else f3 = "tmp.snd"; if (Xen_is_number(maxamp)) maxval = Xen_real_to_C_double(maxamp); mus_convolve_files(f1, f2, maxval, f3); return(C_string_to_Xen_string(f3)); } /* ---------------- phase-vocoder ---------------- */ /* pvedit pvanalyze pvsynthesize: * these three functions provide a path for the call (clm.c) (*(pv->edit))(pv->closure) * which is calling a user-supplied edit function within the particular phase-vocoder * generator's context. "closure" is an uninterpreted void pointer passed in by the * user, and passed here as the edit function argument. In this file, pv->edit is * &pvedit, and (void *)ptr is closure; in make_phase_vocoder we set closure to be * the mus_xen object that shadows the phase-vocoder generator, with two special * pointers in the vcts field: vcts[MUS_EDIT_FUNCTION] is the (Scheme-side) function * passed by the user, and vcts[MUS_SELF_WRAPPER] is a pointer to the (Scheme-relevant) * object that packages the mus_xen pointer for Scheme. This way, the user's * (make-phase-vocoder ... (lambda (v) (mus-length v)) ...) * treats v as the current pv gen, vcts[MUS_SELF_WRAPPER] = v, vcts[MUS_EDIT_FUNCTION] = * the lambda form, mus_xen obj->gen is the C-side pv struct pointer. See above * under as_needed_input_func for more verbiage. (All this complication arises because clm.c * is pure C -- no notion that Scheme might be the caller, and the user's pv.scm * or whatever is pure Scheme -- no notion that C is actually doing the work, * and we have to tie everything together here including the Scheme-C-Scheme-C * call chains). */ static int pvedit(void *ptr) { mus_xen *gn = (mus_xen *)ptr; return(Xen_boolean_to_C_bool(Xen_unprotected_call_with_1_arg(gn->vcts[MUS_EDIT_FUNCTION], gn->vcts[MUS_SELF_WRAPPER]))); } static mus_float_t pvsynthesize(void *ptr) { mus_xen *gn = (mus_xen *)ptr; return(Xen_real_to_C_double(Xen_unprotected_call_with_1_arg(gn->vcts[MUS_SYNTHESIZE_FUNCTION], gn->vcts[MUS_SELF_WRAPPER]))); } static bool pvanalyze(void *ptr, mus_float_t (*input)(void *arg1, int direction)) { mus_xen *gn = (mus_xen *)ptr; /* we can only get input func if it's already set up by the outer gen call, so (?) we can use that function here */ return(Xen_boolean_to_C_bool(Xen_unprotected_call_with_2_args(gn->vcts[MUS_ANALYZE_FUNCTION], gn->vcts[MUS_SELF_WRAPPER], gn->vcts[MUS_INPUT_FUNCTION]))); } static Xen g_is_phase_vocoder(Xen obj) { #define H_is_phase_vocoder "(" S_is_phase_vocoder " gen): " PROC_TRUE " if gen is an " S_phase_vocoder return(C_bool_to_Xen_boolean((mus_is_xen(obj)) && (mus_is_phase_vocoder(Xen_to_mus_any(obj))))); } static Xen g_phase_vocoder(Xen obj, Xen func, Xen analyze_func, Xen edit_func, Xen synthesize_func) { #define H_phase_vocoder "(" S_phase_vocoder " gen input-function analyze-func edit-func synthesize-func): next phase vocoder value" mus_xen *gn; mus_any *g = NULL; Xen_to_C_generator(obj, gn, g, mus_is_phase_vocoder, S_phase_vocoder, "a phase-vocoder generator"); if (Xen_is_bound(func)) { bool (*analyze)(void *arg, mus_float_t (*input)(void *arg1, int direction)) = NULL; int (*edit)(void *arg) = NULL; mus_float_t (*synthesize)(void *arg) = NULL; if ((Xen_is_procedure(func)) && (!Xen_is_bound(gn->vcts[MUS_INPUT_DATA]))) { if (Xen_is_aritable(func, 1)) gn->vcts[MUS_INPUT_FUNCTION] = func; /* as_needed_input_func set at make time will pick this up */ else Xen_bad_arity_error(S_phase_vocoder, 2, func, S_phase_vocoder " input function wants 1 arg"); } if (Xen_is_procedure(analyze_func)) { if (Xen_is_aritable(analyze_func, 2)) { gn->vcts[MUS_ANALYZE_FUNCTION] = analyze_func; analyze = pvanalyze; } else Xen_bad_arity_error(S_phase_vocoder, 3, analyze_func, S_phase_vocoder " analyze function wants 2 args"); } if (Xen_is_procedure(edit_func)) { if (Xen_is_aritable(edit_func, 1)) { gn->vcts[MUS_EDIT_FUNCTION] = edit_func; edit = pvedit; } else Xen_bad_arity_error(S_phase_vocoder, 4, edit_func, S_phase_vocoder " edit function wants 1 arg"); } if (Xen_is_procedure(synthesize_func)) { if (Xen_is_aritable(synthesize_func, 1)) { gn->vcts[MUS_SYNTHESIZE_FUNCTION] = synthesize_func; synthesize = pvsynthesize; } else Xen_bad_arity_error(S_phase_vocoder, 5, synthesize_func, S_phase_vocoder " synthesize function wants 1 arg"); } return(C_double_to_Xen_real(mus_phase_vocoder_with_editors(g, NULL, analyze, edit, synthesize))); } return(C_double_to_Xen_real(mus_phase_vocoder(g, NULL))); } static Xen g_make_phase_vocoder(Xen arglist) { #if HAVE_SCHEME #define pv_example "(" S_make_phase_vocoder " #f 512 4 256 1.0 #f #f #f)" #define pv_edit_example "(" S_make_phase_vocoder " #f 512 4 256 1.0\n\ (lambda (v infunc) (snd-print \"analyzing\") #t)\n\ (lambda (v) (snd-print \"editing\") #t)\n\ (lambda (v) (snd-print \"resynthesizing\") 0.0))" #endif #if HAVE_RUBY #define pv_example "make_phase_vocoder(false, 512, 4, 256, 1.0, false, false, false)" #define pv_edit_example "make_phase_vocoder(false, 512, 4, 256, 1.0,\n\ lambda do | v, infunc | snd_print(\"analyzing\"); true end,\n\ lambda do | v | snd_print(\"editing\"); true end,\n\ lambda do | v | snd_print(\"resynthesizing\"); 0.0 end)" #endif #if HAVE_FORTH #define pv_example "#f 512 4 256 1.0 #f #f #f " S_make_phase_vocoder #define pv_edit_example "#f 512 4 256 1.0\n\ lambda: <{ v infunc -- f }> \"analyzing\" snd-print drop #t ;\n\ lambda: <{ v -- n }> \"editing\" snd-print drop #t ;\n\ lambda: <{ v -- r }> \"resynthesizing\" snd-print drop 0.0 ; " S_make_phase_vocoder #endif #define H_make_phase_vocoder "(" S_make_phase_vocoder " input fft-size overlap interp pitch analyze edit synthesize): \ return a new phase-vocoder generator; input is the input function (it can be set at run-time), analyze, edit, \ and synthesize are either " PROC_FALSE " or functions that replace the default innards of the generator, fft-size, overlap \ and interp set the fftsize, the amount of overlap between ffts, and the time between new analysis calls. \ 'analyze', if given, takes 2 args, the generator and the input function; if it returns " PROC_TRUE ", the default analysis \ code is also called. 'edit', if given, takes 1 arg, the generator; if it returns " PROC_TRUE ", the default edit code \ is run. 'synthesize' is a function of 1 arg, the generator; it is called to get the current vocoder \ output. \n\n " pv_example "\n\n " pv_edit_example Xen in_obj = Xen_undefined, edit_obj = Xen_undefined, synthesize_obj = Xen_undefined, analyze_obj = Xen_undefined; mus_xen *gn; mus_any *ge; Xen args[16]; Xen keys[8]; Xen pv_obj; int orig_arg[8] = {0, 0, 0, 0, 0, 0, 0, 0}; int vals; int fft_size = 512, overlap = 4, interp = 128; mus_float_t pitch = 1.0; keys[0] = kw_input; keys[1] = kw_fft_size; keys[2] = kw_overlap; keys[3] = kw_interp; keys[4] = kw_pitch; keys[5] = kw_analyze; keys[6] = kw_edit; keys[7] = kw_synthesize; { int i, arglist_len; Xen p; arglist_len = Xen_list_length(arglist); if (arglist_len > 16) clm_error(S_make_phase_vocoder, "too many arguments!", arglist); for (i = 0, p = arglist; i < arglist_len; i++, p = Xen_cdr(p)) args[i] = Xen_car(p); for (i = arglist_len; i < 16; i++) args[i] = Xen_undefined; } vals = mus_optkey_unscramble(S_make_phase_vocoder, 8, keys, args, orig_arg); if (vals > 0) { in_obj = mus_optkey_to_input_procedure(keys[0], S_make_phase_vocoder, orig_arg[0], Xen_undefined, 1, S_phase_vocoder " input procedure takes 1 arg"); fft_size = Xen_optkey_to_int(kw_fft_size, keys[1], S_make_phase_vocoder, orig_arg[1], fft_size); if (fft_size <= 1) Xen_out_of_range_error(S_make_phase_vocoder, orig_arg[1], keys[1], "fft size <= 1?"); if (fft_size > mus_max_malloc()) Xen_out_of_range_error(S_make_phase_vocoder, orig_arg[1], keys[1], "fft size too large (see mus-max-malloc)"); if (!is_power_of_2(fft_size)) Xen_out_of_range_error(S_make_phase_vocoder, orig_arg[1], keys[1], "fft size must be power of 2"); overlap = Xen_optkey_to_int(kw_overlap, keys[2], S_make_phase_vocoder, orig_arg[2], overlap); if (overlap <= 0) Xen_out_of_range_error(S_make_phase_vocoder, orig_arg[2], keys[2], "overlap <= 0?"); interp = Xen_optkey_to_int(kw_interp, keys[3], S_make_phase_vocoder, orig_arg[3], interp); if (interp <= 0) Xen_out_of_range_error(S_make_phase_vocoder, orig_arg[3], keys[3], "interp <= 0?"); pitch = Xen_optkey_to_float(kw_pitch, keys[4], S_make_phase_vocoder, orig_arg[4], pitch); analyze_obj = mus_optkey_to_procedure(keys[5], S_make_phase_vocoder, orig_arg[5], Xen_undefined, 2, S_phase_vocoder " analyze procedure takes 2 args"); edit_obj = mus_optkey_to_procedure(keys[6], S_make_phase_vocoder, orig_arg[6], Xen_undefined, 1, S_phase_vocoder " edit procedure takes 1 arg"); synthesize_obj = mus_optkey_to_procedure(keys[7], S_make_phase_vocoder, orig_arg[7], Xen_undefined, 1, S_phase_vocoder " synthesize procedure takes 1 arg"); } gn = mx_alloc(MUS_MAX_VCTS); {int i; for (i = 0; i < MUS_MAX_VCTS; i++) gn->vcts[i] = Xen_undefined;} { mus_error_handler_t *old_error_handler; old_error_handler = mus_error_set_handler(local_mus_error); ge = mus_make_phase_vocoder(NULL, fft_size, overlap, interp, pitch, (!Xen_is_bound(analyze_obj) ? NULL : pvanalyze), (!Xen_is_bound(edit_obj) ? NULL : pvedit), (!Xen_is_bound(synthesize_obj) ? NULL : pvsynthesize), (void *)gn); mus_error_set_handler(old_error_handler); } if (ge) { gn->vcts[MUS_INPUT_FUNCTION] = in_obj; gn->vcts[MUS_EDIT_FUNCTION] = edit_obj; gn->vcts[MUS_ANALYZE_FUNCTION] = analyze_obj; gn->vcts[MUS_SYNTHESIZE_FUNCTION] = synthesize_obj; gn->gen = ge; pv_obj = mus_xen_to_object(gn); /* need scheme-relative backpointer for possible function calls */ gn->vcts[MUS_SELF_WRAPPER] = pv_obj; set_as_needed_input_choices(ge, in_obj, gn); return(pv_obj); } free(gn->vcts); free(gn); return(clm_mus_error(local_error_type, local_error_msg, S_make_phase_vocoder)); } static Xen g_phase_vocoder_amps(Xen pv) { #define H_phase_vocoder_amps "(" S_phase_vocoder_amps " gen): " S_vct " containing the current output sinusoid amplitudes" mus_float_t *amps; int len; mus_xen *gn; Xen_check_type((mus_is_xen(pv)) && (mus_is_phase_vocoder(Xen_to_mus_any(pv))), pv, 1, S_phase_vocoder_amps, "a " S_phase_vocoder " generator"); gn = Xen_to_mus_xen(pv); amps = mus_phase_vocoder_amps(gn->gen); len = (int)mus_length(gn->gen); return(xen_make_vct_wrapper(len / 2, amps)); } static Xen g_phase_vocoder_freqs(Xen pv) { #define H_phase_vocoder_freqs "(" S_phase_vocoder_freqs " gen): " S_vct " containing the current output sinusoid frequencies" mus_float_t *amps; int len; mus_xen *gn; Xen_check_type((mus_is_xen(pv)) && (mus_is_phase_vocoder(Xen_to_mus_any(pv))), pv, 1, S_phase_vocoder_freqs, "a " S_phase_vocoder " generator"); gn = Xen_to_mus_xen(pv); amps = mus_phase_vocoder_freqs(gn->gen); len = (int)mus_length(gn->gen); return(xen_make_vct_wrapper(len, amps)); } static Xen g_phase_vocoder_phases(Xen pv) { #define H_phase_vocoder_phases "(" S_phase_vocoder_phases " gen): " S_vct " containing the current output sinusoid phases" mus_float_t *amps; int len; mus_xen *gn; Xen_check_type((mus_is_xen(pv)) && (mus_is_phase_vocoder(Xen_to_mus_any(pv))), pv, 1, S_phase_vocoder_phases, "a " S_phase_vocoder " generator"); gn = Xen_to_mus_xen(pv); amps = mus_phase_vocoder_phases(gn->gen); len = (int)mus_length(gn->gen); return(xen_make_vct_wrapper(len / 2, amps)); } static Xen g_phase_vocoder_amp_increments(Xen pv) { #define H_phase_vocoder_amp_increments "(" S_phase_vocoder_amp_increments " gen): " S_vct " containing the current output sinusoid amplitude increments per sample" mus_float_t *amps; int len; mus_xen *gn; Xen_check_type((mus_is_xen(pv)) && (mus_is_phase_vocoder(Xen_to_mus_any(pv))), pv, 1, S_phase_vocoder_amp_increments, "a " S_phase_vocoder " generator"); gn = Xen_to_mus_xen(pv); amps = mus_phase_vocoder_amp_increments(gn->gen); len = (int)mus_length(gn->gen); return(xen_make_vct_wrapper(len, amps)); } static Xen g_phase_vocoder_phase_increments(Xen pv) { #define H_phase_vocoder_phase_increments "(" S_phase_vocoder_phase_increments " gen): " S_vct " containing the current output sinusoid phase increments" mus_float_t *amps; int len; mus_xen *gn; Xen_check_type((mus_is_xen(pv)) && (mus_is_phase_vocoder(Xen_to_mus_any(pv))), pv, 1, S_phase_vocoder_phase_increments, "a " S_phase_vocoder " generator"); gn = Xen_to_mus_xen(pv); amps = mus_phase_vocoder_phase_increments(gn->gen); len = (int)mus_length(gn->gen); return(xen_make_vct_wrapper(len / 2, amps)); } /* -------- ssb-am -------- */ static Xen g_is_ssb_am(Xen obj) { #define H_is_ssb_am "(" S_is_ssb_am " gen): " PROC_TRUE " if gen is a " S_ssb_am return(C_bool_to_Xen_boolean((mus_is_xen(obj)) && (mus_is_ssb_am(Xen_to_mus_any(obj))))); } static Xen g_make_ssb_am(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_make_ssb_am "(" S_make_ssb_am " (frequency *clm-default-frequency*) (order 40)): \ return a new " S_ssb_am " generator." #define MUS_MAX_SSB_ORDER 65536 mus_any *ge; Xen args[4]; Xen keys[2]; int orig_arg[2] = {0, 0}; int vals; int order = 40; mus_float_t freq; freq = clm_default_frequency; keys[0] = kw_frequency; keys[1] = kw_order; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; vals = mus_optkey_unscramble(S_make_ssb_am, 2, keys, args, orig_arg); if (vals > 0) { freq = Xen_optkey_to_float(kw_frequency, keys[0], S_make_ssb_am, orig_arg[0], freq); if (freq > (0.5 * mus_srate())) Xen_out_of_range_error(S_make_ssb_am, orig_arg[0], keys[0], "freq > srate/2?"); order = Xen_optkey_to_int(kw_order, keys[1], S_make_ssb_am, orig_arg[1], order); if (order <= 0) Xen_out_of_range_error(S_make_ssb_am, orig_arg[1], keys[1], "order <= 0?"); if (order > MUS_MAX_SSB_ORDER) Xen_out_of_range_error(S_make_ssb_am, orig_arg[1], keys[1], "order too large?"); } ge = mus_make_ssb_am(freq, order); if (ge) return(mus_xen_to_object(mus_any_to_mus_xen(ge))); return(Xen_false); } static Xen g_ssb_am(Xen obj, Xen insig, Xen fm) { #define H_ssb_am "(" S_ssb_am " gen (insig 0.0) (fm 0.0)): get the next sample from " S_ssb_am " generator" mus_float_t insig1 = 0.0; mus_any *g = NULL; mus_xen *gn; Xen_to_C_generator(obj, gn, g, mus_is_ssb_am, S_ssb_am, "an ssb-am generator"); Xen_real_to_C_double_if_bound(insig, insig1, S_ssb_am, 2); if (Xen_is_bound(fm)) { Xen_check_type(Xen_is_number(fm), fm, 3, S_ssb_am, "a number"); return(C_double_to_Xen_real(mus_ssb_am(g, insig1, Xen_real_to_C_double(fm)))); } return(C_double_to_Xen_real(mus_ssb_am_unmodulated(g, insig1))); } #define S_mus_frandom "mus-frandom" #define S_mus_irandom "mus-irandom" static Xen g_mus_frandom(Xen val) { return(C_double_to_Xen_real(mus_frandom(Xen_real_to_C_double_with_caller(val, S_mus_frandom)))); } static Xen g_mus_irandom(Xen val) { mus_long_t ind; Xen_to_C_integer_or_error(val, ind, S_mus_irandom, 1); return(C_int_to_Xen_integer(mus_irandom(ind))); } static Xen mus_clm_output(void); static Xen mus_clm_reverb(void); /* Xen out, Xen in, Xen ost, Xen olen, Xen ist, Xen mx, Xen envs */ static Xen g_mus_file_mix(Xen args) { #define H_mus_file_mix "(" S_mus_file_mix " outfile infile (outloc 0) (framples) (inloc 0) matrix envs): \ mix infile into outfile starting at outloc in outfile and inloc in infile \ mixing 'framples' framples into 'outfile'. framples defaults to the length of infile. If matrix, \ use it to scale the various channels; if envs (an array of envelope generators), use \ it in conjunction with matrix to scale/envelope all the various ins and outs. \ 'outfile' can also be a " S_frample_to_file " generator, and 'infile' can be a " S_file_to_frample " generator." Xen arg, out, in; mus_any *outf = NULL, *inf = NULL; mus_float_t *matrix = NULL; mus_any ***envs1 = NULL; int i; mus_long_t ostart = 0, istart = 0, osamps = 0; int in_chans = 0, out_chans = 0, mx_chans = 0, in_size = 0; /* mus_mix in clm.c assumes the envs array is large enough */ const char *outfile = NULL, *infile = NULL; /* -------- setup output gen -------- */ arg = args; out = Xen_car(arg); Xen_check_type(Xen_is_string(out) || ((mus_is_xen(out)) && (mus_is_output(Xen_to_mus_any(out)))), out, 1, S_mus_file_mix, "a filename or a " S_frample_to_file " generator"); if (Xen_is_string(out)) { outfile = Xen_string_to_C_string(out); if (!mus_file_probe(outfile)) Xen_error(NO_SUCH_FILE, Xen_list_2(C_string_to_Xen_string(S_mus_file_mix ": no such file, ~S"), out)); out_chans = mus_sound_chans(outfile); if (out_chans <= 0) Xen_error(BAD_HEADER, Xen_list_2(C_string_to_Xen_string(S_mus_file_mix ": ~S output chans <= 0"), out)); } else { outf = Xen_to_mus_any(out); out_chans = mus_channels(outf); } /* -------- setup input gen -------- */ arg = Xen_cdr(arg); in = Xen_car(arg); Xen_check_type(Xen_is_string(in) || ((mus_is_xen(in)) && (mus_is_input(Xen_to_mus_any(in)))), in, 2, S_mus_file_mix, "a filename or a " S_file_to_frample " generator"); if (Xen_is_string(in)) { infile = Xen_string_to_C_string(in); if (!mus_file_probe(infile)) Xen_error(NO_SUCH_FILE, Xen_list_2(C_string_to_Xen_string(S_mus_file_mix ": no such file, ~S"), in)); in_chans = mus_sound_chans(infile); if (in_chans <= 0) Xen_error(BAD_HEADER, Xen_list_2(C_string_to_Xen_string(S_mus_file_mix ": ~S input chans <= 0"), in)); osamps = mus_sound_framples(infile); } else { inf = Xen_to_mus_any(in); in_chans = mus_channels(inf); osamps = mus_length(inf); } /* inf and outf only exist during the rest of the arglist scan if not infile or outfile. * we need to delay making the inf/outf gens in this case to greatly simplify error handling. */ /* rest of args are optional */ arg = Xen_cdr(arg); if (!Xen_is_null(arg)) { Xen ost; ost = Xen_car(arg); Xen_check_type(Xen_is_integer(ost), ost, 3, S_mus_file_mix, "an integer"); ostart = Xen_llong_to_C_llong(ost); arg = Xen_cdr(arg); if (!Xen_is_null(arg)) { Xen olen; olen = Xen_car(arg); Xen_check_type(Xen_is_integer(olen), olen, 4, S_mus_file_mix, "an integer"); osamps = Xen_llong_to_C_llong(olen); if (osamps <= 0) return(Xen_false); arg = Xen_cdr(arg); if (!Xen_is_null(arg)) { Xen ist; ist = Xen_car(arg); Xen_check_type(Xen_is_integer(ist), ist, 5, S_mus_file_mix, "an integer"); istart = Xen_llong_to_C_llong(ist); arg = Xen_cdr(arg); if (!Xen_is_null(arg)) { Xen mx; mx = Xen_car(arg); Xen_check_type((mus_is_vct(mx)) || (Xen_is_false(mx)), mx, 6, S_mus_file_mix, "a " S_vct); if (mus_is_vct(mx)) { matrix = mus_vct_data(Xen_to_vct(mx)); mx_chans = (int)sqrt(mus_vct_length(Xen_to_vct(mx))); } arg = Xen_cdr(arg); if (!Xen_is_null(arg)) { Xen envs; envs = Xen_car(arg); Xen_check_type((Xen_is_false(envs)) || (Xen_is_vector(envs)), envs, 7, S_mus_file_mix, "a vector of envs"); if (Xen_is_vector(envs)) { int in_len = 0, out_len, j, out_size; /* pack into a C-style array of arrays of env pointers */ in_len = Xen_vector_length(envs); if (in_len == 0) Xen_error(BAD_TYPE, Xen_list_2(C_string_to_Xen_string(S_mus_file_mix ": env vector, ~A, can't be empty"), envs)); for (i = 0; i < in_len; i++) { Xen datum; datum = Xen_vector_ref(envs, i); if (!(Xen_is_vector(datum))) Xen_error(BAD_TYPE, Xen_list_2(C_string_to_Xen_string(S_mus_file_mix ": vector, ~A, must contain vectors of envelopes"), datum)); } out_len = Xen_vector_length(Xen_vector_ref(envs, 0)); if (in_len < in_chans) in_size = in_chans; else in_size = in_len; if (out_len < out_chans) out_size = out_chans; else out_size = out_len; envs1 = (mus_any ***)malloc(in_size * sizeof(mus_any **)); for (i = 0; i < in_size; i++) envs1[i] = (mus_any **)calloc(out_size, sizeof(mus_any *)); for (i = 0; i < in_len; i++) for (j = 0; j < out_len; j++) { Xen datum1; datum1 = Xen_vector_ref(Xen_vector_ref(envs, i), j); if (mus_is_xen(datum1)) { if (mus_is_env(Xen_to_mus_any(datum1))) envs1[i][j] = Xen_to_mus_any(datum1); else { for (i = 0; i < in_size; i++) if (envs1[i]) free(envs1[i]); free(envs1); Xen_error(BAD_TYPE, Xen_list_4(C_string_to_Xen_string(S_mus_file_mix ": vector, ~A at ~A ~A, must contain an envelope"), datum1, C_int_to_Xen_integer(i), C_int_to_Xen_integer(j))); } } } } } } } } } if ((infile) && (outfile)) mus_file_mix(outfile, infile, ostart, osamps, istart, matrix, mx_chans, envs1); else { if (infile) inf = mus_make_file_to_frample(infile); if (outfile) outf = mus_continue_sample_to_file(outfile); mus_file_mix_with_reader_and_writer(outf, inf, ostart, osamps, istart, matrix, mx_chans, envs1); if (infile) mus_free((mus_any *)inf); if (outfile) mus_free((mus_any *)outf); } if (envs1) { for (i = 0; i < in_size; i++) if (envs1[i]) free(envs1[i]); free(envs1); } return(Xen_true); } /* Xen file, Xen beg, Xen dur, Xen mx, Xen revmx, Xen envs, Xen srcs, Xen srcenv, Xen outstream, Xen revstream */ static Xen g_mus_file_mix_with_envs(Xen args) { #define H_mus_file_mix_with_envs "(" S_mus_file_mix_with_envs " file beg dur mx revmx envs srcs srcenv out rev) is an extension of " S_mus_file_mix ", primarily \ intended to speed up the fullmix instrument. file is a vector of readin generators. beg is the sample at which to start mixing \ output, dur is the number of samples to write. mx is a matrix, revmx is either #f or a matrix. " int i, in_chans, out_chans, mx_chans = 0, rev_chans = 0, rev_mix_chans = 0; mus_long_t st, nd; mus_any *s_env = NULL, *ostr, *rstr = NULL; mus_any **mix_envs, **mix_srcs, **mix_rds; mus_xen *gn; Xen ve, arg, file, beg, dur, mx, revmx, envs, srcs, srcenv, outstream, revstream; mus_float_t *mix = NULL, *rev_mix = NULL; i = Xen_list_length(args); if ((i < 8) || (i > 10)) /* no wrong-number-of-args error in xen.h, so I'll use out-of-range */ Xen_out_of_range_error(S_mus_file_mix_with_envs, 0, args, "wrong number of args"); arg = args; file = Xen_car(arg); Xen_check_type(Xen_is_vector(file), file, 1, S_mus_file_mix_with_envs, "a vector of readin generators"); in_chans = Xen_vector_length(file); arg = Xen_cdr(arg); beg = Xen_car(arg); Xen_check_type(Xen_is_integer(beg), beg, 2, S_mus_file_mix_with_envs, "an integer"); st = Xen_integer_to_C_int(beg); arg = Xen_cdr(arg); dur = Xen_car(arg); Xen_check_type(Xen_is_integer(dur), dur, 3, S_mus_file_mix_with_envs, "an integer"); nd = st + Xen_integer_to_C_int(dur); arg = Xen_cdr(arg); mx = Xen_car(arg); if (mus_is_vct(mx)) { mix = mus_vct_data(Xen_to_vct(mx)); mx_chans = (int)sqrt(mus_vct_length(Xen_to_vct(mx))); } arg = Xen_cdr(arg); revmx = Xen_car(arg); if (mus_is_vct(revmx)) { rev_mix = mus_vct_data(Xen_to_vct(revmx)); rev_mix_chans = (int)sqrt(mus_vct_length(Xen_to_vct(revmx))); } arg = Xen_cdr(arg); envs = Xen_car(arg); if (!Xen_is_false(envs)) Xen_check_type(Xen_is_vector(envs), envs, 6, S_mus_file_mix_with_envs, "a vector of env generators"); arg = Xen_cdr(arg); srcs = Xen_car(arg); if (!Xen_is_false(srcs)) Xen_check_type(Xen_is_vector(srcs), srcs, 7, S_mus_file_mix_with_envs, "a vector of src generators"); arg = Xen_cdr(arg); srcenv = Xen_car(arg); if (!Xen_is_false(srcenv)) { gn = (mus_xen *)Xen_object_ref_checked(srcenv, mus_xen_tag); if (!gn) Xen_check_type(false, srcenv, 8, S_mus_file_mix_with_envs, "an env generator"); s_env = gn->gen; Xen_check_type(mus_is_env(s_env), srcenv, 8, S_mus_file_mix_with_envs, "an env generator"); } revstream = Xen_false; arg = Xen_cdr(arg); if (!Xen_is_null(arg)) { outstream = Xen_car(arg); gn = (mus_xen *)Xen_object_ref_checked(outstream, mus_xen_tag); if (!gn) Xen_check_type(false, outstream, 9, S_mus_file_mix_with_envs, "an output generator"); ostr = gn->gen; arg = Xen_cdr(arg); if (!Xen_is_null(arg)) revstream = Xen_car(arg); } else ostr = Xen_to_mus_any(mus_clm_output()); out_chans = mus_channels(ostr); if (rev_mix) { if (!Xen_is_false(revstream)) { gn = (mus_xen *)Xen_object_ref_checked(revstream, mus_xen_tag); if (!gn) Xen_check_type(false, revstream, 10, S_mus_file_mix_with_envs, "an output generator"); rstr = gn->gen; } else rstr = Xen_to_mus_any(mus_clm_reverb()); rev_chans = mus_channels(rstr); } mix_rds = (mus_any **)calloc(in_chans, sizeof(mus_any *)); mix_srcs = (mus_any **)calloc(in_chans, sizeof(mus_any *)); for (i = 0; i < in_chans; i++) mix_rds[i] = Xen_to_mus_any(Xen_vector_ref(file, i)); if (Xen_is_vector(srcs)) { for (i = 0; i < in_chans; i++) { ve = Xen_vector_ref(srcs, i); if (!Xen_is_false(ve)) mix_srcs[i] = Xen_to_mus_any(ve); } } mix_envs = (mus_any **)calloc(in_chans * out_chans, sizeof(mus_any *)); if (Xen_is_vector(envs)) for (i = 0; i < in_chans * out_chans; i++) { ve = Xen_vector_ref(envs, i); if (!Xen_is_false(ve)) mix_envs[i] = Xen_to_mus_any(ve); } { mus_long_t samp; int outp; mus_float_t src_env_val = 0.0; mus_float_t *infs, *out_frample, *rev_frample = NULL; infs = (mus_float_t *)calloc(in_chans, sizeof(mus_float_t)); out_frample = (mus_float_t *)calloc(out_chans, sizeof(mus_float_t)); if (rev_mix) rev_frample = (mus_float_t *)calloc(rev_chans, sizeof(mus_float_t)); if (in_chans == 1) { mus_any *s = NULL, *r = NULL; s = mix_srcs[0]; if (!s) r = mix_rds[0]; for (samp = st; samp < nd; samp++) { for (outp = 0; outp < out_chans; outp++) { mus_any *e; e = mix_envs[outp]; if (e) mix[outp] = mus_env(e); } if (s_env) src_env_val = mus_env(s_env); if (s) infs[0] = mus_src(s, src_env_val, NULL); else { if (r) infs[0] = mus_readin(r); else infs[0] = 0.0; } mus_frample_to_file(ostr, samp, mus_frample_to_frample(mix, mx_chans, infs, in_chans, out_frample, out_chans)); if (rev_mix) mus_frample_to_file(rstr, samp, mus_frample_to_frample(rev_mix, rev_mix_chans, infs, in_chans, rev_frample, rev_chans)); } } else { for (samp = st; samp < nd; samp++) { int inp, off; for (inp = 0, off = 0; inp < in_chans; inp++, off += mx_chans) for (outp = 0; outp < out_chans; outp++) { mus_any *e; e = mix_envs[inp * out_chans + outp]; /* this is different from the matrix setup -- I don't know why */ if (e) mix[off + outp] = mus_env(e); } if (s_env) src_env_val = mus_env(s_env); for (inp = 0; inp < in_chans; inp++) { mus_any *s; s = mix_srcs[inp]; if (s) infs[inp] = mus_src(s, src_env_val, NULL); else { s = mix_rds[inp]; if (s) infs[inp] = mus_readin(s); else infs[inp] = 0.0; } } mus_frample_to_file(ostr, samp, mus_frample_to_frample(mix, mx_chans, infs, in_chans, out_frample, out_chans)); if (rev_mix) mus_frample_to_file(rstr, samp, mus_frample_to_frample(rev_mix, rev_mix_chans, infs, in_chans, rev_frample, rev_chans)); } } free(infs); free(out_frample); if (rev_frample) free(rev_frample); } free(mix_rds); free(mix_srcs); free(mix_envs); return(Xen_false); } static Xen g_frample_to_frample(Xen mx, Xen infr, Xen inchans, Xen outfr, Xen outchans) { #define H_frample_to_frample "(" S_frample_to_frample " matrix in-data in-chans out-data out-chans): pass frample in-data through matrix \ returning frample out-data; this is a matrix multiply of matrix and in-data" int ins, outs, mxs; vct *vin, *vout, *vmx; Xen_check_type(mus_is_vct(mx), mx, 1, S_frample_to_frample, "a " S_vct); Xen_check_type(mus_is_vct(infr), infr, 2, S_frample_to_frample, "a " S_vct); Xen_check_type(mus_is_vct(outfr), outfr, 4, S_frample_to_frample, "a " S_vct); Xen_check_type(Xen_is_integer(inchans), inchans, 3, S_frample_to_frample, "an integer"); Xen_check_type(Xen_is_integer(outchans), outchans, 5, S_frample_to_frample, "an integer"); ins = Xen_integer_to_C_int(inchans); vin = Xen_to_vct(infr); if (mus_vct_length(vin) < ins) ins = mus_vct_length(vin); if (ins <= 0) return(outfr); outs = Xen_integer_to_C_int(outchans); vout = Xen_to_vct(outfr); if (mus_vct_length(vout) < outs) outs = mus_vct_length(vout); if (outs <= 0) return(outfr); vmx = Xen_to_vct(mx); mxs = (int)sqrt(mus_vct_length(vmx)); mus_frample_to_frample(mus_vct_data(vmx), mxs, mus_vct_data(vin), ins, mus_vct_data(vout), outs); return(outfr); } #if HAVE_SCHEME #ifndef _MSC_VER #include #include static struct timeval overall_start_time; #define S_get_internal_real_time "get-internal-real-time" #define S_internal_time_units_per_second "internal-time-units-per-second" static Xen g_get_internal_real_time(void) { #define H_get_internal_real_time "(" S_get_internal_real_time ") returns the number of seconds since \ the program started. The number is in terms of " S_internal_time_units_per_second ", usually 1" struct timezone z0; struct timeval t0; mus_float_t secs; gettimeofday(&t0, &z0); secs = difftime(t0.tv_sec, overall_start_time.tv_sec); return(C_double_to_Xen_real(secs + 0.000001 * (t0.tv_usec - overall_start_time.tv_usec))); } #else static Xen g_get_internal_real_time(void) {return(C_double_to_Xen_real(0.0));} #endif Xen_wrap_no_args(g_get_internal_real_time_w, g_get_internal_real_time) #endif /* -------------------------------- scheme-side optimization -------------------------------- */ #if HAVE_SCHEME #if (!WITH_GMP) #define car(E) s7_car(E) #define cdr(E) s7_cdr(E) #define cadr(E) s7_cadr(E) #define caddr(E) s7_caddr(E) #define cadddr(E) s7_cadddr(E) #define cadddr(E) s7_cadddr(E) static mus_float_t mus_nsin_unmodulated(mus_any *p) {return(mus_nsin(p, 0.0));} static mus_float_t mus_ncos_unmodulated(mus_any *p) {return(mus_ncos(p, 0.0));} static mus_float_t mus_nrxysin_unmodulated(mus_any *p) {return(mus_nrxysin(p, 0.0));} static mus_float_t mus_nrxycos_unmodulated(mus_any *p) {return(mus_nrxycos(p, 0.0));} static mus_float_t mus_rxyksin_unmodulated(mus_any *p) {return(mus_rxyksin(p, 0.0));} static mus_float_t mus_rxykcos_unmodulated(mus_any *p) {return(mus_rxykcos(p, 0.0));} static mus_float_t mus_square_wave_unmodulated(mus_any *p) {return(mus_square_wave(p, 0.0));} static mus_float_t mus_sawtooth_wave_unmodulated(mus_any *p) {return(mus_sawtooth_wave(p, 0.0));} static mus_float_t mus_src_simple(mus_any *p) {return(mus_src(p, 0.0, NULL));} static mus_float_t mus_src_two(mus_any *p, mus_float_t x) {return(mus_src(p, x, NULL));} static mus_float_t mus_granulate_simple(mus_any *p) {return(mus_granulate_with_editor(p, NULL, NULL));} static mus_float_t mus_convolve_simple(mus_any *p) {return(mus_convolve(p, NULL));} static mus_float_t mus_phase_vocoder_simple(mus_any *p) {return(mus_phase_vocoder(p, NULL));} #define mus_oscil_rf mus_oscil_unmodulated #define mus_polywave_rf mus_polywave_unmodulated #define mus_ncos_rf mus_ncos_unmodulated #define mus_nsin_rf mus_nsin_unmodulated #define mus_nrxycos_rf mus_nrxycos_unmodulated #define mus_nrxysin_rf mus_nrxysin_unmodulated #define mus_rxykcos_rf mus_rxykcos_unmodulated #define mus_rxyksin_rf mus_rxyksin_unmodulated #define mus_rand_rf mus_rand_unmodulated #define mus_rand_interp_rf mus_rand_interp_unmodulated #define mus_readin_rf mus_readin #define mus_env_rf mus_env #define mus_pulsed_env_rf mus_pulsed_env_unmodulated #define mus_oscil_bank_rf mus_oscil_bank #define mus_table_lookup_rf mus_table_lookup_unmodulated #define mus_sawtooth_wave_rf mus_sawtooth_wave_unmodulated #define mus_pulse_train_rf mus_pulse_train_unmodulated #define mus_triangle_wave_rf mus_triangle_wave_unmodulated #define mus_square_wave_rf mus_square_wave_unmodulated #define mus_wave_train_rf mus_wave_train_unmodulated #define mus_convolve_rf mus_convolve_simple #define mus_src_rf mus_src_simple #define mus_granulate_rf mus_granulate_simple #define mus_phase_vocoder_rf mus_phase_vocoder_simple static mus_float_t mus_one_pole_rf(mus_any *p) {return(mus_one_pole(p, 0.0));} static mus_float_t mus_two_pole_rf(mus_any *p) {return(mus_two_pole(p, 0.0));} static mus_float_t mus_one_zero_rf(mus_any *p) {return(mus_one_zero(p, 0.0));} static mus_float_t mus_two_zero_rf(mus_any *p) {return(mus_two_zero(p, 0.0));} static mus_float_t mus_delay_rf(mus_any *p) {return(mus_delay_unmodulated(p, 0.0));} static mus_float_t mus_comb_rf(mus_any *p) {return(mus_comb_unmodulated(p, 0.0));} static mus_float_t mus_comb_bank_rf(mus_any *p) {return(mus_comb_bank(p, 0.0));} static mus_float_t mus_all_pass_bank_rf(mus_any *p) {return(mus_all_pass_bank(p, 0.0));} static mus_float_t mus_notch_rf(mus_any *p) {return(mus_notch_unmodulated(p, 0.0));} static mus_float_t mus_all_pass_rf(mus_any *p) {return(mus_all_pass_unmodulated(p, 0.0));} static mus_float_t mus_one_pole_all_pass_rf(mus_any *p) {return(mus_one_pole_all_pass(p, 0.0));} static mus_float_t mus_moving_average_rf(mus_any *p) {return(mus_moving_average(p, 0.0));} static mus_float_t mus_moving_max_rf(mus_any *p) {return(mus_moving_max(p, 0.0));} static mus_float_t mus_moving_norm_rf(mus_any *p) {return(mus_moving_norm(p, 0.0));} static mus_float_t mus_filter_rf(mus_any *p) {return(mus_filter(p, 0.0));} static mus_float_t mus_fir_filter_rf(mus_any *p) {return(mus_fir_filter(p, 0.0));} static mus_float_t mus_iir_filter_rf(mus_any *p) {return(mus_iir_filter(p, 0.0));} static mus_float_t mus_polyshape_rf(mus_any *p) {return(mus_polyshape_unmodulated(p, 1.0));} static mus_float_t mus_filtered_comb_rf(mus_any *p) {return(mus_filtered_comb_unmodulated(p, 0.0));} static mus_float_t mus_filtered_comb_bank_rf(mus_any *p) {return(mus_filtered_comb_bank(p, 0.0));} static mus_float_t mus_asymmetric_fm_rf(mus_any *p) {return(mus_asymmetric_fm_unmodulated(p, 0.0));} static mus_float_t mus_formant_rf(mus_any *p) {return(mus_formant(p, 0.0));} static mus_float_t mus_firmant_rf(mus_any *p) {return(mus_firmant(p, 0.0));} static mus_float_t mus_ssb_am_rf_1(mus_any *p) {return(mus_ssb_am(p, 0.0, 0.0));} static mus_any *cadr_gen(s7_scheme *sc, s7_pointer expr) { s7_pointer sym, o; mus_xen *gn; sym = s7_cadr(expr); if (!s7_is_symbol(sym)) return(NULL); if (s7_xf_is_stepper(sc, sym)) return(NULL); o = s7_symbol_value(sc, sym); gn = (mus_xen *)s7_object_value_checked(o, mus_xen_tag); if (!gn) return(NULL); return(gn->gen); } static s7_rf_t caddr_rf(s7_scheme *sc, s7_pointer a2, s7_rf_t func) { s7_int loc; s7_pointer val_sym, val; s7_rf_t rf; s7_rp_t rp; val_sym = car(a2); if (!s7_is_symbol(val_sym)) return(NULL); val = s7_symbol_value(sc, val_sym); rp = s7_rf_function(sc, val); if (!rp) return(NULL); loc = s7_xf_store(sc, NULL); rf = rp(sc, a2); if (!rf) return(NULL); s7_xf_store_at(sc, loc, (s7_pointer)rf); return(func); } #define GEN_RF_1(Type, Func) \ static s7_double Type ## _rf_g(s7_scheme *sc, s7_pointer **p) \ { \ mus_any *g; g = (mus_any *)(**p); (*p)++; \ return(Func(g)); \ } \ static s7_rf_t Type ## _rf(s7_scheme *sc, s7_pointer expr) \ { \ mus_any *g; \ if (!s7_is_null(sc, s7_cddr(expr))) return(NULL); \ g = cadr_gen(sc, expr); \ if ((g) && (mus_is_ ## Type(g))) {s7_xf_store(sc, (s7_pointer)g); return(Type ## _rf_g);} \ return(NULL); \ } \ static s7_pointer is_ ## Type ## _pf_g(s7_scheme *sc, s7_pointer **p) \ { \ mus_xen *gn; \ s7_pf_t pf; pf = (s7_pf_t)(**p); (*p)++; \ gn = (mus_xen *)s7_object_value_checked(pf(sc, p), mus_xen_tag); \ return(s7_make_boolean(sc, (gn) && (mus_is_ ## Type(gn->gen)))); \ } \ static s7_pf_t is_ ## Type ## _pf(s7_scheme *sc, s7_pointer expr) \ { \ if (!s7_is_null(sc, s7_cddr(expr))) return(NULL); \ if (s7_arg_to_pf(sc, s7_cadr(expr))) return(is_ ## Type ## _pf_g); \ return(NULL); \ } #define GEN_RF(Type, Func1, Func2) \ static s7_double Type ## _rf_g(s7_scheme *sc, s7_pointer **p) \ { \ mus_any *g; g = (mus_any *)(*(*p)); (*p)++; \ return(Func1(g)); \ } \ static s7_double Type ## _rf_gr(s7_scheme *sc, s7_pointer **p) \ { \ s7_pointer a2; \ mus_any *g; g = (mus_any *)(*(*p)); (*p)++; \ a2 = (**p); (*p)++; \ return(Func2(g, s7_number_to_real(sc, a2))); \ } \ static s7_double Type ## _rf_gs(s7_scheme *sc, s7_pointer **p) \ { \ s7_double a2; \ mus_any *g; g = (mus_any *)(*(*p)); (*p)++; \ a2 = s7_slot_real_value(sc, **p, #Type); (*p)++; \ return(Func2(g, a2)); \ } \ static s7_double Type ## _rf_gx(s7_scheme *sc, s7_pointer **p) \ { \ s7_rf_t f; \ mus_any *g; g = (mus_any *)(*(*p)); (*p)++; \ f = (s7_rf_t)(**p); (*p)++; \ return(Func2(g, f(sc, p))); \ } \ static s7_rf_t Type ## _rf(s7_scheme *sc, s7_pointer expr) \ { \ mus_any *g; \ g = cadr_gen(sc, expr); \ if ((g) && (mus_is_ ## Type(g))) \ { \ s7_pointer a2; \ s7_xf_store(sc, (s7_pointer)g); \ if (s7_is_null(sc, s7_cddr(expr))) return(Type ## _rf_g); \ if (!s7_is_null(sc, s7_cdddr(expr))) return(NULL); \ a2 = caddr(expr); \ if (s7_is_real(a2)) {s7_xf_store(sc, a2); return(Type ## _rf_gr);} \ if (s7_is_symbol(a2)) \ { \ s7_pointer slot; \ slot = s7_slot(sc, a2); \ if (slot != xen_undefined) {s7_xf_store(sc, (s7_pointer)slot); return(Type ## _rf_gs);} \ return(NULL); \ } \ if (s7_is_pair(a2)) \ return(caddr_rf(sc, a2, Type ## _rf_gx)); \ } \ return(NULL); \ } \ static s7_pointer is_ ## Type ## _pf_g(s7_scheme *sc, s7_pointer **p) \ { \ mus_xen *gn; \ s7_pf_t pf; pf = (s7_pf_t)(**p); (*p)++; \ gn = (mus_xen *)s7_object_value_checked(pf(sc, p), mus_xen_tag); \ return(s7_make_boolean(sc, (gn) && (mus_is_ ## Type(gn->gen)))); \ } \ static s7_pf_t is_ ## Type ## _pf(s7_scheme *sc, s7_pointer expr) \ { \ if (!s7_is_null(sc, s7_cddr(expr))) return(NULL); \ if (s7_arg_to_pf(sc, s7_cadr(expr))) return(is_ ## Type ## _pf_g); \ return(NULL); \ } GEN_RF(all_pass, mus_all_pass_rf, mus_all_pass_unmodulated) GEN_RF(asymmetric_fm, mus_asymmetric_fm_rf, mus_asymmetric_fm_unmodulated) GEN_RF(comb, mus_comb_rf, mus_comb_unmodulated) GEN_RF(comb_bank, mus_comb_bank_rf, mus_comb_bank) GEN_RF(all_pass_bank, mus_all_pass_bank_rf, mus_all_pass_bank) GEN_RF_1(convolve, mus_convolve_rf) GEN_RF(delay, mus_delay_rf, mus_delay_unmodulated) GEN_RF_1(env, mus_env_rf) GEN_RF(filter, mus_filter_rf, mus_filter) GEN_RF(filtered_comb, mus_filtered_comb_rf, mus_filtered_comb_unmodulated) GEN_RF(filtered_comb_bank, mus_filtered_comb_bank_rf, mus_filtered_comb_bank) GEN_RF(fir_filter, mus_fir_filter_rf, mus_fir_filter) GEN_RF(firmant, mus_firmant_rf, mus_firmant) GEN_RF(formant, mus_formant_rf, mus_formant) GEN_RF_1(granulate, mus_granulate_rf) GEN_RF(iir_filter, mus_iir_filter_rf, mus_iir_filter) GEN_RF(moving_average, mus_moving_average_rf, mus_moving_average) GEN_RF(moving_max, mus_moving_max_rf, mus_moving_max) GEN_RF(moving_norm, mus_moving_norm_rf, mus_moving_norm) GEN_RF(ncos, mus_ncos_rf, mus_ncos) GEN_RF(notch, mus_notch_rf, mus_notch_unmodulated) GEN_RF(nrxycos, mus_nrxycos_rf, mus_nrxycos) GEN_RF(nrxysin, mus_nrxysin_rf, mus_nrxysin) GEN_RF(nsin, mus_nsin_rf, mus_nsin) GEN_RF(one_pole, mus_one_pole_rf, mus_one_pole) GEN_RF(one_pole_all_pass, mus_one_pole_all_pass_rf, mus_one_pole_all_pass) GEN_RF(one_zero, mus_one_zero_rf, mus_one_zero) GEN_RF(oscil, mus_oscil_rf, mus_oscil_fm) GEN_RF_1(oscil_bank, mus_oscil_bank_rf) GEN_RF_1(phase_vocoder, mus_phase_vocoder_rf) GEN_RF(polyshape, mus_polyshape_rf, mus_polyshape_unmodulated) GEN_RF(polywave, mus_polywave_rf, mus_polywave) GEN_RF(pulse_train, mus_pulse_train_rf, mus_pulse_train) GEN_RF(pulsed_env, mus_pulsed_env_rf, mus_pulsed_env) GEN_RF(rand, mus_rand_rf, mus_rand) GEN_RF(rand_interp, mus_rand_interp_rf, mus_rand_interp) GEN_RF_1(readin, mus_readin_rf) GEN_RF(rxykcos, mus_rxykcos_rf, mus_rxykcos) GEN_RF(rxyksin, mus_rxyksin_rf, mus_rxyksin) GEN_RF(sawtooth_wave, mus_sawtooth_wave_rf, mus_sawtooth_wave) GEN_RF(square_wave, mus_square_wave_rf, mus_square_wave) GEN_RF(src, mus_src_rf, mus_src_two) GEN_RF(table_lookup, mus_table_lookup_rf, mus_table_lookup) GEN_RF(triangle_wave, mus_triangle_wave_rf, mus_triangle_wave) GEN_RF(two_pole, mus_two_pole_rf, mus_two_pole) GEN_RF(two_zero, mus_two_zero_rf, mus_two_zero) GEN_RF(wave_train, mus_wave_train_rf, mus_wave_train) GEN_RF(ssb_am, mus_ssb_am_rf_1, mus_ssb_am_unmodulated) GEN_RF(tap, mus_tap_unmodulated, mus_tap) static s7_double oscil_rf_sxx(s7_scheme *sc, s7_pointer **p) { s7_rf_t rf1, rf2; s7_double v1, v2; mus_any *g; g = (mus_any *)(*(*p)); (*p)++; rf1 = (s7_rf_t)(**p); (*p)++; v1 = rf1(sc, p); rf2 = (s7_rf_t)(**p); (*p)++; v2 = rf2(sc, p); return(mus_oscil(g, v1, v2)); } static s7_double oscil_rf_ssx(s7_scheme *sc, s7_pointer **p) { s7_rf_t rf1; s7_pointer s1; s7_double v1; mus_any *g; g = (mus_any *)(*(*p)); (*p)++; s1 = (**p); (*p)++; rf1 = (s7_rf_t)(**p); (*p)++; v1 = rf1(sc, p); return(mus_oscil(g, s7_slot_real_value(sc, s1, "oscil"), v1)); } static s7_double oscil_rf_sss(s7_scheme *sc, s7_pointer **p) { s7_pointer s1, s2; mus_any *g; g = (mus_any *)(*(*p)); (*p)++; s1 = (**p); (*p)++; s2 = (**p); (*p)++; return(mus_oscil(g, s7_slot_real_value(sc, s1, "oscil"), s7_slot_real_value(sc, s2, "oscil"))); } static s7_double oscil_rf_srs(s7_scheme *sc, s7_pointer **p) { s7_pointer s1, s2; mus_any *g; g = (mus_any *)(*(*p)); (*p)++; s1 = (**p); (*p)++; s2 = (**p); (*p)++; return(mus_oscil(g, s7_number_to_real(sc, s1), s7_slot_real_value(sc, s2, "oscil"))); } static s7_double oscil_rf_srx(s7_scheme *sc, s7_pointer **p) { s7_rf_t rf1; s7_pointer s1; s7_double v1; mus_any *g; g = (mus_any *)(*(*p)); (*p)++; s1 = (**p); (*p)++; rf1 = (s7_rf_t)(**p); (*p)++; v1 = rf1(sc, p); return(mus_oscil(g, s7_number_to_real(sc, s1), v1)); } static s7_rf_t oscil_rf_3(s7_scheme *sc, s7_pointer expr) { mus_any *g; int len; len = s7_list_length(sc, expr); g = cadr_gen(sc, expr); if (!g) return(NULL); if (len < 4) return(oscil_rf(sc, expr)); if (len > 5) return(NULL); s7_xf_store(sc, (s7_pointer)g); return(s7_rf_2(sc, cdr(expr), NULL, NULL, NULL, oscil_rf_srs, oscil_rf_sss, NULL, oscil_rf_srx, oscil_rf_ssx, oscil_rf_sxx)); } static s7_double comb_rf_sxx(s7_scheme *sc, s7_pointer **p) { s7_rf_t rf1, rf2; s7_double v1; mus_any *g; g = (mus_any *)(*(*p)); (*p)++; rf1 = (s7_rf_t)(**p); (*p)++; v1 = rf1(sc, p); rf2 = (s7_rf_t)(**p); (*p)++; return(mus_comb(g, v1, rf2(sc, p))); } static s7_double comb_rf_ssx(s7_scheme *sc, s7_pointer **p) { s7_rf_t rf1; s7_pointer s1; mus_any *g; g = (mus_any *)(*(*p)); (*p)++; s1 = (**p); (*p)++; rf1 = (s7_rf_t)(**p); (*p)++; return(mus_comb(g, s7_slot_real_value(sc, s1, "comb"), rf1(sc, p))); } static s7_double comb_rf_sss(s7_scheme *sc, s7_pointer **p) { s7_pointer s1, s2; mus_any *g; g = (mus_any *)(*(*p)); (*p)++; s1 = (**p); (*p)++; s2 = (**p); (*p)++; return(mus_comb(g, s7_slot_real_value(sc, s1, "comb"), s7_slot_real_value(sc, s2, "comb"))); } static s7_rf_t comb_rf_3(s7_scheme *sc, s7_pointer expr) { mus_any *g; int len; len = s7_list_length(sc, expr); if (len < 4) return(comb_rf(sc, expr)); if (len > 5) return(NULL); g = cadr_gen(sc, expr); if ((!g) || (!mus_is_comb(g))) return(NULL); s7_xf_store(sc, (s7_pointer)g); return(s7_rf_2(sc, cdr(expr), NULL, NULL, NULL, NULL, comb_rf_sss, NULL, NULL, comb_rf_ssx, comb_rf_sxx)); } static s7_double notch_rf_sxx(s7_scheme *sc, s7_pointer **p) { s7_rf_t rf1, rf2; s7_double v1; mus_any *g; g = (mus_any *)(*(*p)); (*p)++; rf1 = (s7_rf_t)(**p); (*p)++; v1 = rf1(sc, p); rf2 = (s7_rf_t)(**p); (*p)++; return(mus_notch(g, v1, rf2(sc, p))); } static s7_rf_t notch_rf_3(s7_scheme *sc, s7_pointer expr) { mus_any *g; int len; len = s7_list_length(sc, expr); if (len < 4) return(notch_rf(sc, expr)); if (len > 5) return(NULL); g = cadr_gen(sc, expr); if ((!g) || (!mus_is_notch(g))) return(NULL); s7_xf_store(sc, (s7_pointer)g); return(s7_rf_2(sc, cdr(expr), NULL, NULL, NULL, NULL, NULL, NULL, NULL,NULL, notch_rf_sxx)); } static s7_double delay_rf_sxx(s7_scheme *sc, s7_pointer **p) { s7_rf_t rf1, rf2; s7_double v1; mus_any *g; g = (mus_any *)(*(*p)); (*p)++; rf1 = (s7_rf_t)(**p); (*p)++; v1 = rf1(sc, p); rf2 = (s7_rf_t)(**p); (*p)++; return(mus_delay(g, v1, rf2(sc, p))); } static s7_rf_t delay_rf_3(s7_scheme *sc, s7_pointer expr) { mus_any *g; int len; len = s7_list_length(sc, expr); if (len < 4) return(delay_rf(sc, expr)); if (len > 5) return(NULL); g = cadr_gen(sc, expr); if ((!g) || (!mus_is_delay(g))) return(NULL); s7_xf_store(sc, (s7_pointer)g); return(s7_rf_2(sc, cdr(expr), NULL, NULL, NULL, NULL, NULL, NULL, NULL,NULL, delay_rf_sxx)); } static s7_double all_pass_rf_sxx(s7_scheme *sc, s7_pointer **p) { s7_rf_t rf1, rf2; s7_double v1; mus_any *g; g = (mus_any *)(*(*p)); (*p)++; rf1 = (s7_rf_t)(**p); (*p)++; v1 = rf1(sc, p); rf2 = (s7_rf_t)(**p); (*p)++; return(mus_all_pass(g, v1, rf2(sc, p))); } static s7_rf_t all_pass_rf_3(s7_scheme *sc, s7_pointer expr) { mus_any *g; int len; len = s7_list_length(sc, expr); if (len < 4) return(all_pass_rf(sc, expr)); if (len > 5) return(NULL); g = cadr_gen(sc, expr); if ((!g) || (!mus_is_all_pass(g))) return(NULL); s7_xf_store(sc, (s7_pointer)g); return(s7_rf_2(sc, cdr(expr), NULL, NULL, NULL, NULL, NULL, NULL, NULL,NULL, all_pass_rf_sxx)); } static s7_double ssb_am_rf_sss(s7_scheme *sc, s7_pointer **p) { s7_pointer s1, s2; mus_any *g; g = (mus_any *)(*(*p)); (*p)++; s1 = (**p); (*p)++; s2 = (**p); (*p)++; return(mus_ssb_am(g, s7_slot_real_value(sc, s1, "ssb-am"), s7_slot_real_value(sc, s2, "ssb-am"))); } static s7_rf_t ssb_am_rf_3(s7_scheme *sc, s7_pointer expr) { mus_any *g; int len; len = s7_list_length(sc, expr); if (len < 4) return(ssb_am_rf(sc, expr)); if (len > 5) return(NULL); g = cadr_gen(sc, expr); if ((!g) || (!mus_is_ssb_am(g))) return(NULL); s7_xf_store(sc, (s7_pointer)g); return(s7_rf_2(sc, cdr(expr), NULL, NULL, NULL, NULL, ssb_am_rf_sss, NULL, NULL, NULL, NULL)); } static s7_double formant_rf_ssx(s7_scheme *sc, s7_pointer **p) { s7_rf_t rf1; s7_pointer s1; mus_any *g; g = (mus_any *)(*(*p)); (*p)++; s1 = (**p); (*p)++; rf1 = (s7_rf_t)(**p); (*p)++; return(mus_formant_with_frequency(g, s7_slot_real_value(sc, s1, "formant"), rf1(sc, p))); } static s7_double formant_rf_sss(s7_scheme *sc, s7_pointer **p) { s7_pointer s1, s2; mus_any *g; g = (mus_any *)(*(*p)); (*p)++; s1 = (**p); (*p)++; s2 = (**p); (*p)++; return(mus_formant_with_frequency(g, s7_slot_real_value(sc, s1, "formant"), s7_slot_real_value(sc, s2, "formant"))); } static s7_rf_t formant_rf_3(s7_scheme *sc, s7_pointer expr) { mus_any *g; int len; len = s7_list_length(sc, expr); if (len < 4) return(formant_rf(sc, expr)); if (len > 5) return(NULL); g = cadr_gen(sc, expr); if ((!g) || (!mus_is_formant(g))) return(NULL); s7_xf_store(sc, (s7_pointer)g); return(s7_rf_2(sc, cdr(expr), NULL, NULL, NULL, NULL, formant_rf_sss, NULL, NULL, formant_rf_ssx, NULL)); } /* formant-bank: c g r, or v for with_inputs */ static s7_double formant_bank_rf_s(s7_scheme *sc, s7_pointer **p) { mus_any *bank; s7_pointer slot; bank = (mus_any *)(**p); (*p)++; slot = (**p); (*p)++; return(mus_formant_bank(bank, s7_slot_real_value(sc, slot, "formant-bank"))); } static s7_double formant_bank_rf_r(s7_scheme *sc, s7_pointer **p) { mus_any *bank; s7_pointer slot; bank = (mus_any *)(**p); (*p)++; slot = (**p); (*p)++; return(mus_formant_bank(bank, s7_number_to_real(sc, slot))); } static s7_double formant_bank_rf_x(s7_scheme *sc, s7_pointer **p) { mus_any *bank; s7_rf_t r1; bank = (mus_any *)(**p); (*p)++; r1 = (s7_rf_t)(**p); (*p)++; return(mus_formant_bank(bank, r1(sc, p))); } static s7_double formant_bank_rf_v(s7_scheme *sc, s7_pointer **p) { mus_any *bank; s7_double *els; bank = (mus_any *)(**p); (*p)++; els = (s7_double *)(**p); (*p)++; return(mus_formant_bank_with_inputs(bank, els)); } static s7_rf_t formant_bank_rf(s7_scheme *sc, s7_pointer expr) { mus_any *g; if (!s7_is_null(sc, s7_cdddr(expr))) return(NULL); g = cadr_gen(sc, expr); if ((g) && (mus_is_formant_bank(g))) { s7_pointer a1, val_sym, val; s7_int loc; s7_rf_t rf; s7_xf_store(sc, (s7_pointer)g); a1 = caddr(expr); if (s7_is_symbol(a1)) { s7_pointer slot; slot = s7_slot(sc, a1); if (slot == xen_undefined) return(NULL); val = s7_slot_value(slot); if (s7_is_real(val)) { s7_xf_store(sc, (s7_pointer)slot); return(formant_bank_rf_s); } if (s7_is_float_vector(val)) { s7_xf_store(sc, (s7_pointer)s7_float_vector_elements(val)); return(formant_bank_rf_v); } return(NULL); } if (s7_is_real(a1)) { s7_xf_store(sc, a1); return(formant_bank_rf_r); } if (!s7_is_pair(a1)) return(NULL); val_sym = car(a1); if (!s7_is_symbol(val_sym)) return(NULL); val = s7_symbol_value(sc, val_sym); if (!s7_rf_function(sc, val)) return(NULL); loc = s7_xf_store(sc, NULL); rf = s7_rf_function(sc, val)(sc, a1); if (!rf) return(NULL); s7_xf_store_at(sc, loc, (s7_pointer)rf); return(formant_bank_rf_x); } return(NULL); } static s7_double set_formant_frequency_rf_x(s7_scheme *sc, s7_pointer **p) { mus_any *f; s7_rf_t r1; f = (mus_any *)(**p); (*p)++; r1 = (s7_rf_t)(**p); (*p)++; return(mus_set_formant_frequency(f, r1(sc, p))); } static s7_rf_t set_formant_frequency_rf(s7_scheme *sc, s7_pointer expr) { mus_any *g; if (!s7_is_null(sc, s7_cdddr(expr))) return(NULL); g = cadr_gen(sc, expr); if ((g) && (mus_is_formant(g))) { s7_pointer a1; a1 = s7_caddr(expr); if (s7_is_pair(a1)) { s7_int loc; s7_pointer val, val_sym; s7_rf_t rf; val_sym = car(a1); if (!s7_is_symbol(val_sym)) return(NULL); val = s7_symbol_value(sc, val_sym); if (!s7_rf_function(sc, val)) return(NULL); s7_xf_store(sc, (s7_pointer)g); loc = s7_xf_store(sc, NULL); rf = s7_rf_function(sc, val)(sc, a1); if (!rf) return(NULL); s7_xf_store_at(sc, loc, (s7_pointer)rf); return(set_formant_frequency_rf_x); } } return(NULL); } static s7_double outa_x_rf(s7_scheme *sc, s7_pointer **p) { s7_int ind; s7_double val; s7_rf_t rf; ind = s7_slot_integer_value(**p); (*p)++; rf = (s7_rf_t)(**p); (*p)++; val = rf(sc, p); out_any_2(ind, val, 0, S_outa); return(val); } static s7_double outa_x_rf_checked(s7_scheme *sc, s7_pointer **p) { s7_pointer ind; s7_double val; s7_rf_t rf; ind = s7_slot_value(**p); (*p)++; if (!s7_is_integer(ind)) s7_wrong_type_arg_error(s7, S_outa, 1, ind, "an integer"); rf = (s7_rf_t)(**p); (*p)++; val = rf(sc, p); out_any_2(s7_integer(ind), val, 0, S_outa); return(val); } static s7_double outa_s_rf(s7_scheme *sc, s7_pointer **p) { s7_double val; s7_int ind; ind = s7_slot_integer_value(**p); (*p)++; val = s7_slot_real_value(sc, **p, "outa"); (*p)++; out_any_2(ind, val, 0, S_outa); return(val); } static s7_double outa_s_rf_checked(s7_scheme *sc, s7_pointer **p) { s7_double val; s7_pointer ind; ind = s7_slot_value(**p); (*p)++; if (!s7_is_integer(ind)) s7_wrong_type_arg_error(s7, S_outa, 1, ind, "an integer"); val = s7_slot_real_value(sc, **p, "outa"); (*p)++; out_any_2(s7_integer(ind), val, 0, S_outa); return(val); } static s7_double outa_x_rf_to_mus_xen(s7_scheme *sc, s7_pointer **p) { s7_double val; s7_int pos; s7_rf_t rf; pos = s7_slot_integer_value(**p); (*p)++; rf = (s7_rf_t)(**p); (*p)++; val = rf(sc, p); if (!mus_simple_out_any_to_file(pos, val, 0, clm_output_gen)) mus_safe_out_any_to_file(pos, val, 0, clm_output_gen); return(val); } static s7_double outa_s_rf_to_mus_xen(s7_scheme *sc, s7_pointer **p) { s7_double val; s7_int pos; pos = s7_slot_integer_value(**p); (*p)++; val = s7_slot_real_value(sc, **p, "outa"); (*p)++; if (!mus_simple_out_any_to_file(pos, val, 0, clm_output_gen)) mus_safe_out_any_to_file(pos, val, 0, clm_output_gen); return(val); } static s7_double outb_x_rf(s7_scheme *sc, s7_pointer **p) { s7_int ind; s7_double val; s7_rf_t rf; ind = s7_slot_integer_value(**p); (*p)++; rf = (s7_rf_t)(**p); (*p)++; val = rf(sc, p); out_any_2(ind, val, 1, S_outb); return(val); } static s7_double outb_s_rf(s7_scheme *sc, s7_pointer **p) { s7_int ind; s7_double val; ind = s7_slot_integer_value(**p); (*p)++; val = s7_slot_real_value(sc, **p, "outb"); (*p)++; out_any_2(ind, val, 1, S_outb); return(val); } static s7_double mul_env_x_rf(s7_scheme *sc, s7_pointer **p); static s7_double mul_env_polywave_x_rf(s7_scheme *sc, s7_pointer **p); static s7_double outa_mul_env_x_rf(s7_scheme *sc, s7_pointer **p) { s7_double val; s7_int pos; s7_rf_t r2; mus_any *g; pos = s7_slot_integer_value(**p); (*p) += 3; g = (mus_any *)(**p); (*p)++; r2 = (s7_rf_t)(**p); (*p)++; val = mus_env(g) * r2(sc, p); if (!mus_simple_out_any_to_file(pos, val, 0, clm_output_gen)) mus_safe_out_any_to_file(pos, val, 0, clm_output_gen); return(val); } static s7_double outa_mul_env_polywave_x_rf(s7_scheme *sc, s7_pointer **p) { s7_double val; s7_int pos; s7_rf_t r2; mus_any *e, *o; pos = s7_slot_integer_value(**p); (*p) += 3; e = (mus_any *)(**p); (*p) += 2; o = (mus_any *)(**p); (*p)++; r2 = (s7_rf_t)(**p); (*p)++; val = mus_env(e) * mus_polywave(o, r2(sc, p)); if (!mus_simple_out_any_to_file(pos, val, 0, clm_output_gen)) mus_safe_out_any_to_file(pos, val, 0, clm_output_gen); return(val); } static s7_double outa_mul_env_polywave_env_rf(s7_scheme *sc, s7_pointer **p) { s7_double val; s7_int pos; mus_any *e, *o, *fe; pos = s7_slot_integer_value(**p); (*p) += 3; e = (mus_any *)(**p); (*p) += 2; o = (mus_any *)(**p); (*p) += 2; fe = (mus_any *)(**p); (*p)++; val = mus_env(e) * mus_polywave(o, mus_env(fe)); if (!mus_simple_out_any_to_file(pos, val, 0, clm_output_gen)) mus_safe_out_any_to_file(pos, val, 0, clm_output_gen); return(val); } static s7_rf_t out_rf(s7_scheme *sc, s7_pointer expr, int chan) { s7_pointer ind_sym, ind, ind_slot, val_sym, val, val_expr; s7_rf_t rf = NULL; if (!s7_is_null(sc, s7_cdddr(expr))) return(NULL); ind_sym = s7_cadr(expr); if (!s7_is_symbol(ind_sym)) return(NULL); ind_slot = s7_slot(sc, ind_sym); if (ind_slot == xen_undefined) return(NULL); ind = s7_slot_value(ind_slot); if (!s7_is_integer(ind)) return(NULL); if (ind < 0) return(NULL); s7_xf_store(sc, ind_slot); val_expr = s7_caddr(expr); if (s7_is_symbol(val_expr)) { s7_pointer slot; slot = s7_slot(sc, val_expr); if (slot == xen_undefined) return(NULL); s7_xf_store(sc, slot); } else { s7_int loc; if (!s7_is_pair(val_expr)) return(NULL); val_sym = car(val_expr); if (!s7_is_symbol(val_sym)) return(NULL); val = s7_symbol_value(sc, val_sym); if (!s7_rf_function(sc, val)) return(NULL); loc = s7_xf_store(sc, NULL); rf = s7_rf_function(sc, val)(sc, val_expr); if (!rf) return(NULL); s7_xf_store_at(sc, loc, (s7_pointer)rf); } if (s7_is_stepper(ind_slot)) { if (chan == 0) { if (out_any_2 == safe_out_any_2_to_mus_xen) { if (rf == mul_env_polywave_x_rf) { s7_pointer fm; fm = s7_caddr(s7_caddr(val_expr)); if ((s7_is_pair(fm)) && (s7_car(fm) == env_symbol) && (s7_is_symbol(s7_cadr(fm)))) return(outa_mul_env_polywave_env_rf); return(outa_mul_env_polywave_x_rf); } if (rf == mul_env_x_rf) return(outa_mul_env_x_rf); return((rf) ? outa_x_rf_to_mus_xen : outa_s_rf_to_mus_xen); } return((rf) ? outa_x_rf : outa_s_rf); } return((rf) ? outb_x_rf : outb_s_rf); } if (chan == 0) return((rf) ? outa_x_rf_checked : outa_s_rf_checked); return(NULL); } static s7_rf_t outa_rf(s7_scheme *sc, s7_pointer expr) { return(out_rf(sc, expr, 0)); } static s7_rf_t outb_rf(s7_scheme *sc, s7_pointer expr) { return(out_rf(sc, expr, 1)); } static s7_double sample_to_file_rf_g(s7_scheme *sc, s7_pointer **p) { /* (sample->file obj samp chan[always int] val) */ s7_int ind, chan; mus_any *lc; s7_double val; s7_rf_t rf; lc = (mus_any *)(**p); (*p)++; ind = s7_slot_integer_value(**p); (*p)++; chan = s7_integer(**p); (*p)++; rf = (s7_rf_t)(**p); (*p)++; val = rf(sc, p); mus_sample_to_file(lc, ind, chan, val); return(val); } static s7_rf_t sample_to_file_rf(s7_scheme *sc, s7_pointer expr) { s7_pointer ind_sym, ind, ind_slot, chan, val_sym, val, val_expr; s7_int loc; s7_rf_t rf; mus_any *lc; lc = cadr_gen(sc, expr); if ((!lc) || (!mus_is_sample_to_file(lc))) return(NULL); ind_sym = s7_caddr(expr); if (!s7_is_symbol(ind_sym)) return(NULL); ind_slot = s7_slot(sc, ind_sym); if ((ind_slot == xen_undefined) || (!s7_is_stepper(ind_slot))) return(NULL); ind = s7_slot_value(ind_slot); if (!s7_is_integer(ind)) return(NULL); chan = s7_cadddr(expr); if (!s7_is_integer(chan)) return(NULL); val_expr = s7_car(s7_cddddr(expr)); if (!s7_is_pair(val_expr)) return(NULL); val_sym = s7_car(val_expr); if (!s7_is_symbol(val_sym)) return(NULL); val = s7_symbol_value(sc, val_sym); if (!s7_rf_function(sc, val)) return(NULL); s7_xf_store(sc, (s7_pointer)lc); s7_xf_store(sc, ind_slot); s7_xf_store(sc, chan); loc = s7_xf_store(sc, NULL); rf = s7_rf_function(sc, val)(sc, val_expr); if (!rf) return(NULL); s7_xf_store_at(sc, loc, (s7_pointer)rf); return(sample_to_file_rf_g); } static s7_double locsig_rf_x(s7_scheme *sc, s7_pointer **p) { s7_int ind; mus_any *lc; s7_double val; s7_rf_t rf; lc = (mus_any *)(**p); (*p)++; ind = s7_slot_integer_value(**p); (*p)++; rf = (s7_rf_t)(**p); (*p)++; val = rf(sc, p); mus_locsig(lc, ind, val); return(val); } static s7_double locsig_rf_x_checked(s7_scheme *sc, s7_pointer **p) { s7_pointer ind; mus_any *lc; s7_double val; s7_rf_t rf; lc = (mus_any *)(**p); (*p)++; ind = s7_slot_value(**p); (*p)++; if (!s7_is_integer(ind)) s7_wrong_type_arg_error(s7, S_locsig, 2, ind, "an integer"); rf = (s7_rf_t)(**p); (*p)++; val = rf(sc, p); mus_locsig(lc, s7_integer(ind), val); return(val); } static s7_double fm_violin_rf(s7_scheme *sc, s7_pointer **p); static s7_double locsig_fm_violin_rf(s7_scheme *sc, s7_pointer **p) { s7_int ind; mus_any *lc, *e, *o, *fp, *a; s7_double val, vib; lc = (mus_any *)(**p); (*p)++; ind = s7_slot_integer_value(**p); (*p) += 3; /* fm_violin_rf */ e = (mus_any *)(**p); (*p) += 2; o = (mus_any *)(**p); (*p) += 2; vib = s7_slot_real_value(sc, **p, "oscil"); (*p) += 3; a = (mus_any *)(**p); (*p) += 2; fp = (mus_any *)(**p); (*p)++; val = mus_env(e) * mus_oscil_fm(o, vib + (mus_env(a) * mus_polywave(fp, vib))); mus_locsig(lc, ind, val); return(val); } static s7_rf_t locsig_rf(s7_scheme *sc, s7_pointer expr) { s7_pointer ind_sym, ind, ind_slot, val_sym, val, val_expr; s7_int loc; s7_rf_t rf; mus_any *lc; lc = cadr_gen(sc, expr); if ((!lc) || (!mus_is_locsig(lc))) return(NULL); ind_sym = s7_caddr(expr); if (!s7_is_symbol(ind_sym)) return(NULL); ind_slot = s7_slot(sc, ind_sym); if (ind_slot == xen_undefined) return(NULL); ind = s7_slot_value(ind_slot); if (!s7_is_integer(ind)) return(NULL); val_expr = s7_cadddr(expr); if (!s7_is_pair(val_expr)) return(NULL); val_sym = s7_car(val_expr); if (!s7_is_symbol(val_sym)) return(NULL); val = s7_symbol_value(sc, val_sym); if (!s7_rf_function(sc, val)) return(NULL); s7_xf_store(sc, (s7_pointer)lc); s7_xf_store(sc, ind_slot); loc = s7_xf_store(sc, NULL); rf = s7_rf_function(sc, val)(sc, val_expr); if (!rf) return(NULL); s7_xf_store_at(sc, loc, (s7_pointer)rf); if (rf == fm_violin_rf) return(locsig_fm_violin_rf); return((s7_is_stepper(ind_slot)) ? locsig_rf_x : locsig_rf_x_checked); } static s7_double move_sound_rf_g(s7_scheme *sc, s7_pointer **p) { s7_int ind; mus_any *lc; s7_double val; s7_rf_t rf; lc = (mus_any *)(**p); (*p)++; ind = s7_slot_integer_value(**p); (*p)++; rf = (s7_rf_t)(**p); (*p)++; val = rf(sc, p); mus_move_sound(lc, ind, val); return(val); } static s7_rf_t move_sound_rf(s7_scheme *sc, s7_pointer expr) { s7_pointer ind_sym, ind, ind_slot, val_sym, val, val_expr; s7_int loc; s7_rf_t rf; mus_any *lc; lc = cadr_gen(sc, expr); if ((!lc) || (!mus_is_move_sound(lc))) return(NULL); ind_sym = s7_caddr(expr); if (!s7_is_symbol(ind_sym)) return(NULL); ind_slot = s7_slot(sc, ind_sym); if ((ind_slot == xen_undefined) || (!s7_is_stepper(ind_slot))) return(NULL); ind = s7_slot_value(ind_slot); if (!s7_is_integer(ind)) return(NULL); val_expr = s7_cadddr(expr); if (!s7_is_pair(val_expr)) return(NULL); val_sym = s7_car(val_expr); if (!s7_is_symbol(val_sym)) return(NULL); val = s7_symbol_value(sc, val_sym); if (!s7_rf_function(sc, val)) return(NULL); s7_xf_store(sc, (s7_pointer)lc); s7_xf_store(sc, ind_slot); loc = s7_xf_store(sc, NULL); rf = s7_rf_function(sc, val)(sc, val_expr); if (!rf) return(NULL); s7_xf_store_at(sc, loc, (s7_pointer)rf); return(move_sound_rf_g); } static s7_double out_bank_rf_1(s7_scheme *sc, s7_pointer **p) { s7_double val; s7_rf_t rf; s7_int loc; mus_any *g1; g1 = (mus_any *)(**p); (*p)++; loc = s7_slot_integer_value(**p); (*p)++; rf = (s7_rf_t)(**p); (*p)++; val = rf(sc, p); if (mus_is_delay(g1)) out_any_2(loc, mus_delay_unmodulated_noz(g1, val), 0, "out-bank"); else out_any_2(loc, mus_all_pass_unmodulated_noz(g1, val), 0, "out-bank"); return(val); } static s7_double mul_s_comb_bank_x_rf(s7_scheme *sc, s7_pointer **p); static s7_double out_bank_rf_comb_bank_1(s7_scheme *sc, s7_pointer **p) { s7_double val, s1; s7_rf_t rf; s7_int loc; mus_any *g1, *o; g1 = (mus_any *)(**p); (*p)++; loc = s7_slot_integer_value(**p); (*p) += 2; s1 = s7_slot_real_value(sc, **p, "out-bank"); (*p) += 2; o = (mus_any *)(**p); (*p)++; rf = (s7_rf_t)(**p); (*p)++; val = s1 * mus_comb_bank(o, rf(sc, p)); if (mus_is_delay(g1)) out_any_2(loc, mus_delay_unmodulated_noz(g1, val), 0, "out-bank"); else out_any_2(loc, mus_all_pass_unmodulated_noz(g1, val), 0, "out-bank"); return(val); } static s7_double out_bank_rf_comb_bank_2(s7_scheme *sc, s7_pointer **p) { s7_double val, s1; s7_rf_t rf; s7_int loc; mus_any *g1, *g2, *o; g1 = (mus_any *)(**p); (*p)++; g2 = (mus_any *)(**p); (*p)++; loc = s7_slot_integer_value(**p); (*p) += 2; s1 = s7_slot_real_value(sc, **p, "out-bank"); (*p) += 2; o = (mus_any *)(**p); (*p)++; rf = (s7_rf_t)(**p); (*p)++; val = s1 * mus_comb_bank(o, rf(sc, p)); if (mus_is_delay(g1)) { out_any_2(loc, mus_delay_unmodulated_noz(g1, val), 0, "out-bank"); out_any_2(loc, mus_delay_unmodulated_noz(g2, val), 1, "out-bank"); } else { out_any_2(loc, mus_all_pass_unmodulated_noz(g1, val), 0, "out-bank"); out_any_2(loc, mus_all_pass_unmodulated_noz(g2, val), 1, "out-bank"); } return(val); } static s7_double out_bank_rf_2(s7_scheme *sc, s7_pointer **p) { s7_double val; s7_rf_t rf; s7_int loc; mus_any *g1, *g2; g1 = (mus_any *)(**p); (*p)++; g2 = (mus_any *)(**p); (*p)++; loc = s7_slot_integer_value(**p); (*p)++; rf = (s7_rf_t)(**p); (*p)++; val = rf(sc, p); if (mus_is_delay(g1)) { out_any_2(loc, mus_delay_unmodulated_noz(g1, val), 0, "out-bank"); out_any_2(loc, mus_delay_unmodulated_noz(g2, val), 1, "out-bank"); } else { out_any_2(loc, mus_all_pass_unmodulated_noz(g1, val), 0, "out-bank"); out_any_2(loc, mus_all_pass_unmodulated_noz(g2, val), 1, "out-bank"); } return(val); } static s7_double out_bank_rf_4(s7_scheme *sc, s7_pointer **p) { s7_double val; s7_rf_t rf; s7_int loc; mus_any *g1, *g2, *g3, *g4; g1 = (mus_any *)(**p); (*p)++; g2 = (mus_any *)(**p); (*p)++; g3 = (mus_any *)(**p); (*p)++; g4 = (mus_any *)(**p); (*p)++; loc = s7_slot_integer_value(**p); (*p)++; rf = (s7_rf_t)(**p); (*p)++; val = rf(sc, p); if (mus_is_delay(g1)) { out_any_2(loc, mus_delay_unmodulated_noz(g1, val), 0, "out-bank"); out_any_2(loc, mus_delay_unmodulated_noz(g2, val), 1, "out-bank"); out_any_2(loc, mus_delay_unmodulated_noz(g3, val), 2, "out-bank"); out_any_2(loc, mus_delay_unmodulated_noz(g4, val), 3, "out-bank"); } else { out_any_2(loc, mus_all_pass_unmodulated_noz(g1, val), 0, "out-bank"); out_any_2(loc, mus_all_pass_unmodulated_noz(g2, val), 1, "out-bank"); out_any_2(loc, mus_all_pass_unmodulated_noz(g3, val), 2, "out-bank"); out_any_2(loc, mus_all_pass_unmodulated_noz(g4, val), 3, "out-bank"); } return(val); } static s7_rf_t out_bank_rf(s7_scheme *sc, s7_pointer expr) { s7_pointer ind_sym, ind, ind_slot, val_sym, val, val_expr, filts; s7_int loc; s7_rf_t rf; s7_int i, len; mus_xen *gn; mus_any *g; s7_pointer *els; filts = s7_cadr(expr); if (!s7_is_symbol(filts)) return(NULL); filts = s7_symbol_value(sc, filts); if (!s7_is_vector(filts)) return(NULL); len = s7_vector_length(filts); if ((len != 1) && (len != 2) && (len != 4)) return(NULL); els = s7_vector_elements(filts); gn = (mus_xen *)s7_object_value_checked(els[0], mus_xen_tag); if (!gn) return(NULL); g = gn->gen; if ((!mus_is_delay(g)) && (!mus_is_all_pass(g))) return(NULL); for (i = 0; i < len; i++) s7_xf_store(sc, (s7_pointer)((mus_xen *)s7_object_value(els[i]))->gen); ind_sym = s7_caddr(expr); if (!s7_is_symbol(ind_sym)) return(NULL); ind_slot = s7_slot(sc, ind_sym); if ((ind_slot == xen_undefined) || (!s7_is_stepper(ind_slot))) return(NULL); ind = s7_slot_value(ind_slot); if (!s7_is_integer(ind)) return(NULL); s7_xf_store(sc, ind_slot); val_expr = s7_cadddr(expr); if (!s7_is_pair(val_expr)) return(NULL); val_sym = s7_car(val_expr); if (!s7_is_symbol(val_sym)) return(NULL); val = s7_symbol_value(sc, val_sym); if (!s7_rf_function(sc, val)) return(NULL); loc = s7_xf_store(sc, NULL); rf = s7_rf_function(sc, val)(sc, val_expr); if (!rf) return(NULL); s7_xf_store_at(sc, loc, (s7_pointer)rf); if (len == 1) { if (rf == mul_s_comb_bank_x_rf) return(out_bank_rf_comb_bank_1); return(out_bank_rf_1); } if (len == 2) { if (rf == mul_s_comb_bank_x_rf) return(out_bank_rf_comb_bank_2); return(out_bank_rf_2); } return(out_bank_rf_4); } static s7_double file_to_sample_rf_ss(s7_scheme *sc, s7_pointer **p) { s7_int ind; mus_any *stream; stream = (mus_any *)(**p); (*p)++; ind = s7_slot_integer_value(**p); (*p)++; return(mus_file_to_sample(stream, ind, 0)); } static s7_rf_t file_to_sample_rf(s7_scheme *sc, s7_pointer expr) { s7_pointer ind_sym, ind_slot, ind, sym, o; mus_xen *gn; sym = s7_cadr(expr); if (!s7_is_symbol(sym)) return(NULL); o = s7_symbol_value(sc, sym); gn = (mus_xen *)s7_object_value_checked(o, mus_xen_tag); if (!gn) return(NULL); s7_xf_store(sc, (s7_pointer)(gn->gen)); if (!s7_is_null(sc, s7_cdddr(expr))) return(NULL); ind_sym = s7_caddr(expr); if (!s7_is_symbol(ind_sym)) return(NULL); ind_slot = s7_slot(sc, ind_sym); if ((ind_slot == xen_undefined) || (!s7_is_stepper(ind_slot))) return(NULL); ind = s7_slot_value(ind_slot); if (!s7_is_integer(ind)) return(NULL); s7_xf_store(sc, ind_slot); return(file_to_sample_rf_ss); } static s7_pointer file_to_frample_pf_sss(s7_scheme *sc, s7_pointer **p) { /* (file->frample gen loc fv) -> fv */ s7_pointer fv; s7_int ind; mus_any *stream; stream = (mus_any *)(**p); (*p)++; ind = s7_slot_integer_value(**p); (*p)++; fv = s7_slot_value(**p); (*p)++; mus_file_to_frample(stream, ind, s7_float_vector_elements(fv)); return(fv); } static s7_pf_t file_to_frample_pf(s7_scheme *sc, s7_pointer expr) { s7_pointer ind_sym, ind_slot, fv_slot, fv_sym, sym, o; mus_xen *gn; if (!s7_is_null(sc, s7_cddddr(expr))) return(NULL); sym = s7_cadr(expr); if (!s7_is_symbol(sym)) return(NULL); o = s7_symbol_value(sc, sym); gn = (mus_xen *)s7_object_value_checked(o, mus_xen_tag); if (!gn) return(NULL); s7_xf_store(sc, (s7_pointer)(gn->gen)); ind_sym = s7_caddr(expr); if (!s7_is_symbol(ind_sym)) return(NULL); ind_slot = s7_slot(sc, ind_sym); if ((ind_slot == xen_undefined) || (!s7_is_stepper(ind_slot))) return(NULL); if (!s7_is_integer(s7_slot_value(ind_slot))) return(NULL); s7_xf_store(sc, ind_slot); fv_sym = s7_cadddr(expr); if (!s7_is_symbol(fv_sym)) return(NULL); fv_slot = s7_slot(sc, fv_sym); if (fv_slot == xen_undefined) return(NULL); if (!s7_is_float_vector(s7_slot_value(fv_slot))) return(NULL); s7_xf_store(sc, fv_slot); return(file_to_frample_pf_sss); } static s7_pointer frample_to_file_pf_sss(s7_scheme *sc, s7_pointer **p) { /* (frample->file gen loc fv) -> fv */ s7_pointer fv; s7_int ind; mus_any *stream; stream = (mus_any *)(**p); (*p)++; ind = s7_slot_integer_value(**p); (*p)++; fv = s7_slot_value(**p); (*p)++; mus_frample_to_file(stream, ind, s7_float_vector_elements(fv)); return(fv); } static s7_pointer frample_to_file_pf_ssx(s7_scheme *sc, s7_pointer **p) { /* (frample->file gen loc fv) -> fv */ s7_pointer fv; s7_int ind; s7_pf_t pf; mus_any *stream; stream = (mus_any *)(**p); (*p)++; ind = s7_slot_integer_value(**p); (*p)++; pf = (s7_pf_t)(**p); (*p)++; fv = pf(sc, p); mus_frample_to_file(stream, ind, s7_float_vector_elements(fv)); return(fv); } static s7_pf_t frample_to_file_pf(s7_scheme *sc, s7_pointer expr) { s7_pointer ind_sym, ind_slot, fv_slot, fv_sym, sym, o; mus_xen *gn; if (!s7_is_null(sc, s7_cddddr(expr))) return(NULL); sym = s7_cadr(expr); if (!s7_is_symbol(sym)) return(NULL); o = s7_symbol_value(sc, sym); gn = (mus_xen *)s7_object_value_checked(o, mus_xen_tag); if (!gn) return(NULL); s7_xf_store(sc, (s7_pointer)(gn->gen)); ind_sym = s7_caddr(expr); if (!s7_is_symbol(ind_sym)) return(NULL); ind_slot = s7_slot(sc, ind_sym); if ((ind_slot == xen_undefined) || (!s7_is_stepper(ind_slot))) return(NULL); if (!s7_is_integer(s7_slot_value(ind_slot))) return(NULL); s7_xf_store(sc, ind_slot); fv_sym = s7_cadddr(expr); if (s7_is_symbol(fv_sym)) { fv_slot = s7_slot(sc, fv_sym); if (fv_slot == xen_undefined) return(NULL); if (!s7_is_float_vector(s7_slot_value(fv_slot))) return(NULL); s7_xf_store(sc, fv_slot); return(frample_to_file_pf_sss); } if (s7_is_pair(fv_sym)) { s7_pp_t pp; s7_pf_t pf; s7_int loc; pp = s7_pf_function(sc, s7_symbol_value(sc, s7_car(fv_sym))); if (!pp) return(NULL); loc = s7_xf_store(sc, NULL); pf = pp(sc, fv_sym); if (!pf) return(NULL); s7_xf_store_at(sc, loc, (s7_pointer)pf); return(frample_to_file_pf_ssx); } return(NULL); } static s7_pointer frample_to_frample_pf_all_s(s7_scheme *sc, s7_pointer **p) { s7_pointer matrix, in_data, in_chans, out_data, out_chans; matrix = s7_slot_value(**p); (*p)++; in_data = s7_slot_value(**p); (*p)++; in_chans = s7_slot_value(**p); (*p)++; out_data = s7_slot_value(**p); (*p)++; out_chans = s7_slot_value(**p); (*p)++; mus_frample_to_frample(s7_float_vector_elements(matrix), (int)sqrt(s7_vector_length(matrix)), s7_float_vector_elements(in_data), s7_integer(in_chans), s7_float_vector_elements(out_data), s7_integer(out_chans)); return(out_data); } static s7_pf_t frample_to_frample_pf(s7_scheme *sc, s7_pointer expr) { s7_int i; s7_pointer p; for (i = 0, p = s7_cdr(expr); (s7_is_pair(p)) && (i < 5); i++, p = s7_cdr(p)) { if (s7_is_symbol(s7_car(p))) { s7_pointer slot; slot = s7_slot(sc, s7_car(p)); if (slot == xen_undefined) return(NULL); s7_xf_store(sc, slot); } else return(NULL); } if ((i == 5) && (s7_is_null(sc, p))) return(frample_to_frample_pf_all_s); return(NULL); } static s7_double ina_rf_ss(s7_scheme *sc, s7_pointer **p) { s7_int ind; mus_any *stream; ind = s7_slot_integer_value(**p); (*p)++; stream = (mus_any *)(**p); (*p)++; return(mus_in_any(ind, 0, stream)); } static s7_double ina_rf_ss_checked(s7_scheme *sc, s7_pointer **p) { s7_pointer ind; mus_any *stream; ind = s7_slot_value(**p); (*p)++; if (!s7_is_integer(ind)) s7_wrong_type_arg_error(s7, S_ina, 1, ind, "an integer"); stream = (mus_any *)(**p); (*p)++; return(mus_in_any(s7_integer(ind), 0, stream)); } static s7_double inb_rf_ss(s7_scheme *sc, s7_pointer **p) { s7_int ind; mus_any *stream; ind = s7_slot_integer_value(**p); (*p)++; stream = (mus_any *)(**p); (*p)++; return(mus_in_any(ind, 1, stream)); } static s7_double inb_rf_ss_checked(s7_scheme *sc, s7_pointer **p) { s7_pointer ind; mus_any *stream; ind = s7_slot_value(**p); (*p)++; if (!s7_is_integer(ind)) s7_wrong_type_arg_error(s7, S_inb, 1, ind, "an integer"); stream = (mus_any *)(**p); (*p)++; return(mus_in_any(s7_integer(ind), 1, stream)); } static s7_double ina_rf_fv(s7_scheme *sc, s7_pointer **p) { s7_pointer fv; s7_int index; index = s7_slot_integer_value(**p); (*p)++; fv = (**p); (*p)++; if ((index >= 0) && (index < s7_vector_length(fv))) return(s7_float_vector_elements(fv)[index]); return(0.0); } static s7_rf_t in_rf(s7_scheme *sc, s7_pointer expr, int chan) { s7_pointer ind_sym, ind_slot, ind, sym, o; mus_xen *gn; if (!s7_is_null(sc, s7_cdddr(expr))) return(NULL); ind_sym = s7_cadr(expr); if (!s7_is_symbol(ind_sym)) return(NULL); ind_slot = s7_slot(sc, ind_sym); if (ind_slot == xen_undefined) return(NULL); ind = s7_slot_value(ind_slot); if (!s7_is_integer(ind)) return(NULL); s7_xf_store(sc, ind_slot); sym = s7_caddr(expr); if (!s7_is_symbol(sym)) return(NULL); o = s7_symbol_value(sc, sym); if (s7_is_float_vector(o)) { if ((chan == 0) && (s7_is_stepper(ind_slot))) { s7_xf_store(sc, o); return(ina_rf_fv); } return(NULL); } gn = (mus_xen *)s7_object_value_checked(o, mus_xen_tag); if (!gn) return(NULL); s7_xf_store(sc, (s7_pointer)(gn->gen)); if (s7_is_stepper(ind_slot)) { if (chan == 0) return(ina_rf_ss); return(inb_rf_ss); } if (chan == 0) return(ina_rf_ss_checked); return(inb_rf_ss_checked); } static s7_rf_t ina_rf(s7_scheme *sc, s7_pointer expr) { return(in_rf(sc, expr, 0)); } static s7_rf_t inb_rf(s7_scheme *sc, s7_pointer expr) { return(in_rf(sc, expr, 1)); } static s7_double in_any_rf_srs(s7_scheme *sc, s7_pointer **p) { s7_int ind, chan; mus_any *stream; ind = s7_slot_integer_value(**p); (*p)++; chan = s7_integer(**p); (*p)++; stream = (mus_any *)(**p); (*p)++; return(mus_in_any(ind, chan, stream)); } static s7_rf_t in_any_rf(s7_scheme *sc, s7_pointer expr) { s7_pointer ind_sym, ind_slot, ind, sym, o, chan; mus_xen *gn; if (!s7_is_null(sc, s7_cddddr(expr))) return(NULL); ind_sym = s7_cadr(expr); if (!s7_is_symbol(ind_sym)) return(NULL); ind_slot = s7_slot(sc, ind_sym); if ((ind_slot == xen_undefined) || (!s7_is_stepper(ind_slot))) return(NULL); ind = s7_slot_value(ind_slot); if (!s7_is_integer(ind)) return(NULL); s7_xf_store(sc, ind_slot); chan = s7_caddr(expr); if (!s7_is_integer(chan)) return(NULL); s7_xf_store(sc, chan); sym = s7_cadddr(expr); if (!s7_is_symbol(sym)) return(NULL); o = s7_symbol_value(sc, sym); gn = (mus_xen *)s7_object_value_checked(o, mus_xen_tag); if (!gn) return(NULL); s7_xf_store(sc, (s7_pointer)(gn->gen)); return(in_any_rf_srs); } #define RF2_TO_RF(CName, Rfnc) \ static s7_double CName ## _rf_r2(s7_scheme *sc, s7_pointer **p) \ { \ s7_rf_t f; \ s7_double x, y; \ f = (s7_rf_t)(**p); (*p)++; x = f(sc, p); \ f = (s7_rf_t)(**p); (*p)++; y = f(sc, p); \ return(Rfnc); \ } \ static s7_rf_t CName ## _rf(s7_scheme *sc, s7_pointer expr) \ { \ if ((s7_is_pair(s7_cdr(expr))) && (s7_is_pair(s7_cddr(expr))) && (s7_is_null(sc, s7_cdddr(expr))) && \ (s7_arg_to_rf(sc, s7_cadr(expr))) && \ (s7_arg_to_rf(sc, s7_caddr(expr)))) \ return(CName ## _rf_r2); \ return(NULL); \ } #define RF_0(Call) \ static s7_double Call ## _rf_0(s7_scheme *sc, s7_pointer **p) \ { \ return(mus_ ## Call()); \ } \ static s7_rf_t Call ## _rf(s7_scheme *sc, s7_pointer expr) \ { \ if (!s7_is_null(sc, s7_cdr(expr))) return(NULL); \ return(Call ## _rf_0); \ } RF_0(srate) #define RF_1(Call) \ static s7_double Call ## _rf_s(s7_scheme *sc, s7_pointer **p) \ { \ s7_pointer slot; \ slot = (**p); (*p)++; \ return(mus_ ## Call(s7_slot_real_value(sc, slot, #Call))); \ } \ static s7_double Call ## _rf_c(s7_scheme *sc, s7_pointer **p) \ { \ s7_pointer slot; \ slot = (**p); (*p)++; \ return(mus_ ## Call(s7_number_to_real(sc, slot))); \ } \ static s7_double Call ## _rf_r(s7_scheme *sc, s7_pointer **p) \ { \ s7_rf_t r; \ r = (s7_rf_t)(**p); (*p)++; \ return(mus_ ## Call(r(sc, p))); \ } \ static s7_rf_t Call ## _rf(s7_scheme *sc, s7_pointer expr) \ { \ return(s7_rf_1(sc, expr, Call ## _rf_c, Call ## _rf_s, Call ## _rf_r)); \ } RF_1(odd_weight) RF_1(even_weight) RF_1(hz_to_radians) RF_1(radians_to_hz) RF_1(db_to_linear) RF_1(linear_to_db) RF_1(radians_to_degrees) RF_1(degrees_to_radians) RF_1(random) RF2_TO_RF(contrast_enhancement, mus_contrast_enhancement(x, y)) RF2_TO_RF(odd_multiple, mus_odd_multiple(x, y)) RF2_TO_RF(even_multiple, mus_even_multiple(x, y)) RF2_TO_RF(ring_modulate, x * y) static s7_double polynomial_rf_ss(s7_scheme *sc, s7_pointer **p) { s7_pointer s1; s7_double s2; s1 = s7_slot_value(**p); (*p)++; s2 = s7_slot_real_value(sc, **p, "polynomial"); (*p)++; return(mus_polynomial(s7_float_vector_elements(s1), s2, s7_vector_length(s1))); } static s7_double polynomial_rf_sx(s7_scheme *sc, s7_pointer **p) { s7_pointer s1; s7_rf_t r1; s1 = s7_slot_value(**p); (*p)++; r1 = (s7_rf_t)(**p); (*p)++; return(mus_polynomial(s7_float_vector_elements(s1), r1(sc, p), s7_vector_length(s1))); } static s7_rf_t polynomial_rf(s7_scheme *sc, s7_pointer expr) { if ((s7_is_symbol(s7_cadr(expr))) && (s7_is_float_vector(s7_symbol_value(sc, s7_cadr(expr))))) return(s7_rf_2(sc, expr, NULL, NULL, NULL, NULL, polynomial_rf_ss, NULL, NULL, polynomial_rf_sx, NULL)); return(NULL); } static s7_double pink_noise_rf_v(s7_scheme *sc, s7_pointer **p) { s7_pointer s1; s1 = s7_slot_value(**p); (*p)++; return(mus_pink_noise(s1)); } static s7_rf_t pink_noise_rf(s7_scheme *sc, s7_pointer expr) { if (s7_is_symbol(s7_cadr(expr))) { s7_pointer slot; slot = s7_slot(sc, s7_cadr(expr)); if (s7_is_float_vector(s7_slot_value(slot))) { s7_xf_store(sc, slot); return(pink_noise_rf_v); } } return(NULL); } static s7_double piano_noise_rf_vr(s7_scheme *sc, s7_pointer **p) { s7_pointer s1; s7_double s2; s1 = s7_slot_value(**p); (*p)++; s2 = s7_slot_real_value(sc, **p, "piano-noise"); (*p)++; return(piano_noise(s7_int_vector_elements(s1), s2)); } static s7_rf_t piano_noise_rf(s7_scheme *sc, s7_pointer expr) { if ((s7_is_symbol(s7_cadr(expr))) && (s7_is_symbol(s7_caddr(expr)))) { s7_pointer slot1, slot2; slot1 = s7_slot(sc, s7_cadr(expr)); slot2 = s7_slot(sc, s7_caddr(expr)); if ((s7_is_int_vector(s7_slot_value(slot1))) && (s7_is_real(s7_slot_value(slot2)))) { s7_xf_store(sc, slot1); s7_xf_store(sc, slot2); return(piano_noise_rf_vr); } } return(NULL); } static s7_double array_interp_rf_sxr(s7_scheme *sc, s7_pointer **p) { s7_pointer s1; s7_int c2; s7_rf_t r1; s7_double x; s1 = s7_slot_value(**p); (*p)++; r1 = (s7_rf_t)(**p); (*p)++; x = r1(sc, p); c2 = s7_integer(**p); (*p)++; return(mus_array_interp(s7_float_vector_elements(s1), x, c2)); } static s7_double array_interp_rf_sxs(s7_scheme *sc, s7_pointer **p) { s7_pointer s1; s7_int s2; s7_rf_t r1; s7_double x; s1 = s7_slot_value(**p); (*p)++; r1 = (s7_rf_t)(**p); (*p)++; x = r1(sc, p); s2 = s7_slot_integer_value(**p); (*p)++; return(mus_array_interp(s7_float_vector_elements(s1), x, s2)); } static s7_rf_t array_interp_rf(s7_scheme *sc, s7_pointer expr) { if (s7_is_symbol(s7_cadr(expr))) { s7_pointer rst, fv; rst = cdr(expr); fv = s7_slot(sc, s7_car(rst)); if ((fv != xen_undefined) && (s7_is_float_vector(s7_slot_value(fv)))) { if ((!s7_is_null(sc, s7_cddr(rst))) && (s7_is_null(sc, s7_cdddr(rst)))) { s7_xf_store(sc, fv); return(s7_rf_2(sc, rst, NULL, NULL, array_interp_rf_sxr, NULL, NULL, array_interp_rf_sxs, NULL, NULL, NULL)); } } } return(NULL); } static s7_double am_rf_rsx(s7_scheme *sc, s7_pointer **p) { s7_double c1, c2; s7_rf_t r1; c1 = s7_number_to_real(sc, **p); (*p)++; c2 = s7_slot_real_value(sc, **p, "amplitude-modulation"); (*p)++; r1 = (s7_rf_t)(**p); (*p)++; return(mus_amplitude_modulate(c1, c2, r1(sc, p))); } static s7_rf_t am_rf(s7_scheme *sc, s7_pointer expr) { s7_pointer a1, a2, a3; a1 = s7_cadr(expr); a2 = s7_caddr(expr); a3 = s7_cadddr(expr); if ((s7_is_real(a1)) && (s7_is_symbol(a2)) && (s7_is_pair(a3))) { s7_rp_t rp; s7_rf_t rf; s7_int loc; s7_pointer sym, val; s7_xf_store(sc, a1); val = s7_slot(sc, a2); if (val == xen_undefined) return(NULL); s7_xf_store(sc, val); sym = car(a3); if (!s7_is_symbol(sym)) return(NULL); val = s7_symbol_value(sc, sym); rp = s7_rf_function(sc, val); if (!rp) return(NULL); loc = s7_xf_store(sc, NULL); rf = rp(sc, a3); if (!rf) return(NULL); s7_xf_store_at(sc, loc, (s7_pointer)rf); return(am_rf_rsx); } return(NULL); } static s7_double mul_env_x_rf(s7_scheme *sc, s7_pointer **p) { s7_rf_t r2; mus_any *g; (*p)++; g = (mus_any *)(**p); (*p)++; r2 = (s7_rf_t)(**p); (*p)++; return(mus_env(g) * r2(sc, p)); } static s7_double mul_env_oscil_x_rf(s7_scheme *sc, s7_pointer **p) { s7_rf_t r2; mus_any *e, *o; (*p)++; e = (mus_any *)(**p); (*p) += 2; o = (mus_any *)(**p); (*p)++; r2 = (s7_rf_t)(**p); (*p)++; return(mus_env(e) * mus_oscil_fm(o, r2(sc, p))); } static s7_double fm_violin_rf(s7_scheme *sc, s7_pointer **p) { mus_any *e, *o, *fp, *a; s7_double vib; (*p)++; e = (mus_any *)(**p); (*p) += 2; o = (mus_any *)(**p); (*p) += 2; vib = s7_slot_real_value(sc, **p, "oscil"); (*p) += 3; a = (mus_any *)(**p); (*p) += 2; fp = (mus_any *)(**p); (*p)++; return(mus_env(e) * mus_oscil_fm(o, vib + (mus_env(a) * mus_polywave(fp, vib)))); } static s7_double mul_env_polywave_x_rf(s7_scheme *sc, s7_pointer **p) { s7_rf_t r2; mus_any *e, *o; (*p)++; e = (mus_any *)(**p); (*p) += 2; o = (mus_any *)(**p); (*p)++; r2 = (s7_rf_t)(**p); (*p)++; return(mus_env(e) * mus_polywave(o, r2(sc, p))); } static s7_double mul_env_polywave_s_rf(s7_scheme *sc, s7_pointer **p) { s7_double s1; mus_any *e, *o; (*p)++; e = (mus_any *)(**p); (*p) += 2; o = (mus_any *)(**p); (*p)++; s1 = s7_slot_real_value(sc, **p, "polywave"); (*p)++; return(mus_env(e) * mus_polywave(o, s1)); } static s7_double mul_s_comb_bank_x_rf(s7_scheme *sc, s7_pointer **p) { s7_rf_t r1; s7_double s1; mus_any *o; s1 = s7_slot_real_value(sc, **p, "comb-bank"); (*p) += 2; o = (mus_any *)(**p); (*p)++; r1 = (s7_rf_t)(**p); (*p)++; return(s1 * mus_comb_bank(o, r1(sc, p))); } static s7_rp_t initial_multiply_rf; static s7_rf_t clm_multiply_rf(s7_scheme *sc, s7_pointer expr) { s7_rf_t f; f = initial_multiply_rf(sc, expr); if ((f) && (s7_is_null(sc, s7_cdddr(expr)))) { s7_pointer a1, a2; a1 = s7_cadr(expr); a2 = s7_caddr(expr); if (s7_is_pair(a1)) { if ((s7_car(a1) == env_symbol) && (s7_is_pair(a2)) && (s7_is_symbol(s7_cadr(a1))) && (s7_is_null(sc, s7_cdddr(expr)))) { if ((s7_is_symbol(s7_cadr(a2))) && (s7_is_null(sc, s7_cdddr(a2)))) { if (s7_is_pair(s7_caddr(a2))) { if (s7_car(a2) == oscil_symbol) { s7_pointer fm; fm = s7_caddr(a2); if ((s7_car(fm) == add_symbol) && (s7_is_symbol(s7_cadr(fm))) && (s7_is_pair(s7_caddr(fm)))) { s7_pointer vib_sym; vib_sym = s7_cadr(fm); fm = s7_caddr(fm); if ((s7_car(fm) == multiply_symbol) && (s7_is_pair(s7_cadr(fm))) && (s7_caadr(fm) == env_symbol) && (s7_is_pair(s7_caddr(fm))) && (s7_is_null(sc, s7_cdddr(fm)))) { fm = s7_caddr(fm); if ((s7_car(fm) == polywave_symbol) && (s7_is_symbol(s7_cadr(fm))) && (s7_is_symbol(s7_caddr(fm))) && (s7_caddr(fm) == vib_sym)) return(fm_violin_rf); } } return(mul_env_oscil_x_rf); } else { if (s7_car(a2) == polywave_symbol) return(mul_env_polywave_x_rf); } } if (s7_is_symbol(s7_caddr(a2))) { if (s7_car(a2) == polywave_symbol) return(mul_env_polywave_s_rf); } } return(mul_env_x_rf); } } else { if ((s7_is_symbol(a1)) && (s7_is_pair(a2)) && (s7_is_symbol(s7_cadr(a2))) && (s7_car(a2) == comb_bank_symbol) && (s7_is_pair(s7_caddr(a2))) && (s7_is_null(sc, s7_cdddr(a2)))) return(mul_s_comb_bank_x_rf); } } return(f); } static s7_double add_env_ri_rf(s7_scheme *sc, s7_pointer **p) { mus_any *e, *o; (*p)++; e = (mus_any *)(**p); (*p) += 2; o = (mus_any *)(**p); (*p)++; return(mus_env(e) + mus_rand_interp_unmodulated(o)); } static s7_double add_tri_ri_rf(s7_scheme *sc, s7_pointer **p) { mus_any *e, *o; (*p)++; /* triangle-wave */ e = (mus_any *)(**p); (*p) += 2; /* rand-interp */ o = (mus_any *)(**p); (*p)++; return(mus_triangle_wave_unmodulated(e) + mus_rand_interp_unmodulated(o)); } static s7_rp_t initial_add_rf; static s7_rf_t clm_add_rf(s7_scheme *sc, s7_pointer expr) { s7_rf_t f; f = initial_add_rf(sc, expr); if (f) { s7_pointer a1, a2; a1 = s7_cadr(expr); a2 = s7_caddr(expr); if ((s7_is_pair(a1)) && (s7_is_pair(a2)) && (s7_car(a2) == rand_interp_symbol) && (s7_is_symbol(s7_cadr(a1))) && (s7_is_symbol(s7_cadr(a2))) && (s7_is_null(sc, s7_cddr(a1))) && (s7_is_null(sc, s7_cddr(a2))) && (s7_is_null(sc, s7_cdddr(expr)))) { if (s7_car(a1) == triangle_wave_symbol) return(add_tri_ri_rf); if (s7_car(a1) == env_symbol) return(add_env_ri_rf); } } return(f); } static s7_double env_rf_v(s7_scheme *sc, s7_pointer **p) { s7_pointer v; mus_xen *gn; s7_Int ind; v = (**p); (*p)++; ind = s7_slot_integer_value(**p); (*p)++; if ((ind < 0) || (ind >= s7_vector_length(v))) s7_out_of_range_error(s7, "vector-ref", 2, s7_make_integer(sc, ind), "must fit in vector"); gn = (mus_xen *)s7_object_value_checked(s7_vector_elements(v)[ind], mus_xen_tag); return(mus_env(gn->gen)); } static s7_rf_t env_rf_1(s7_scheme *sc, s7_pointer expr) { if ((s7_is_pair(expr)) && (s7_is_pair(cdr(expr))) && (s7_is_pair(cadr(expr)))) { s7_pointer a1; a1 = s7_cadr(expr); if ((s7_car(a1) == vector_ref_symbol) && (s7_is_symbol(s7_cadr(a1))) && (s7_is_symbol(s7_caddr(a1))) && (s7_is_null(sc, s7_cdddr(a1)))) { s7_pointer s1, s2, v, ind; s7_pointer *els; int i, vlen; s1 = s7_cadr(a1); s2 = s7_caddr(a1); v = s7_symbol_value(sc, s1); if (!s7_is_vector(v)) return(NULL); vlen = s7_vector_length(v); els = s7_vector_elements(v); for (i= 0; i < vlen; i++) { mus_xen *gn; gn = (mus_xen *)s7_object_value_checked(els[i], mus_xen_tag); if ((!gn) || (!(gn->gen)) || (!mus_is_env(gn->gen))) return(NULL); } ind = s7_slot(sc, s2); if ((ind == xen_undefined) || (!s7_is_integer(s7_slot_value(ind)))) return(NULL); s7_xf_store(sc, v); s7_xf_store(sc, ind); return(env_rf_v); } } return(env_rf(sc, expr)); } static s7_double chebyshev_t_rf_a(s7_scheme *sc, s7_pointer **p) { s7_rf_t rf; s7_pf_t pf; s7_double x; s7_pointer fv; rf = (s7_rf_t)(**p); (*p)++; x = rf(sc, p); pf = (s7_pf_t)(**p); (*p)++; fv = pf(sc, p); return(mus_chebyshev_t_sum(x, s7_vector_length(fv), s7_float_vector_elements(fv))); } static s7_rf_t chebyshev_t_rf(s7_scheme *sc, s7_pointer expr) { if ((s7_is_pair(s7_cdr(expr))) && (s7_is_pair(s7_cddr(expr))) && (s7_is_null(sc, s7_cdddr(expr))) && (s7_arg_to_rf(sc, s7_cadr(expr))) && (s7_arg_to_pf(sc, s7_caddr(expr)))) return(chebyshev_t_rf_a); return(NULL); } static s7_double chebyshev_u_rf_a(s7_scheme *sc, s7_pointer **p) { s7_rf_t rf; s7_pf_t pf; s7_double x; s7_pointer fv; rf = (s7_rf_t)(**p); (*p)++; x = rf(sc, p); pf = (s7_pf_t)(**p); (*p)++; fv = pf(sc, p); return(mus_chebyshev_u_sum(x, s7_vector_length(fv), s7_float_vector_elements(fv))); } static s7_rf_t chebyshev_u_rf(s7_scheme *sc, s7_pointer expr) { if ((s7_is_pair(s7_cdr(expr))) && (s7_is_pair(s7_cddr(expr))) && (s7_is_null(sc, s7_cdddr(expr))) && (s7_arg_to_rf(sc, s7_cadr(expr))) && (s7_arg_to_pf(sc, s7_caddr(expr)))) return(chebyshev_u_rf_a); return(NULL); } static s7_double chebyshev_tu_rf_a(s7_scheme *sc, s7_pointer **p) { s7_rf_t rf; s7_pf_t pf; s7_double x; s7_pointer t, u; rf = (s7_rf_t)(**p); (*p)++; x = rf(sc, p); pf = (s7_pf_t)(**p); (*p)++; t = pf(sc, p); pf = (s7_pf_t)(**p); (*p)++; u = pf(sc, p); return(mus_chebyshev_tu_sum(x, s7_vector_length(t), s7_float_vector_elements(t), s7_float_vector_elements(u))); } static s7_rf_t chebyshev_tu_rf(s7_scheme *sc, s7_pointer expr) { if ((s7_is_pair(s7_cdr(expr))) && (s7_is_pair(s7_cddr(expr))) && (s7_is_pair(s7_cdddr(expr))) && (s7_is_null(sc, s7_cddddr(expr))) && (s7_arg_to_rf(sc, s7_cadr(expr))) && (s7_arg_to_pf(sc, s7_caddr(expr))) && (s7_arg_to_pf(sc, s7_cadddr(expr)))) return(chebyshev_tu_rf_a); return(NULL); } #define PF2_TO_RF(CName, Cfnc) \ static s7_double CName ## _rf_a(s7_scheme *sc, s7_pointer **p) \ { \ s7_pf_t f; \ s7_pointer x, y; \ f = (s7_pf_t)(**p); (*p)++; \ x = f(sc, p); \ f = (s7_pf_t)(**p); (*p)++; \ y = f(sc, p); \ return(Cfnc); \ } \ static s7_rf_t CName ## _rf(s7_scheme *sc, s7_pointer expr) \ { \ if ((s7_is_pair(s7_cdr(expr))) && (s7_is_pair(s7_cddr(expr))) && (s7_is_null(sc, s7_cdddr(expr))) && \ (s7_arg_to_pf(sc, s7_cadr(expr))) && \ (s7_arg_to_pf(sc, s7_caddr(expr)))) \ return(CName ## _rf_a); \ return(NULL); \ } static s7_double c_dot_product(s7_scheme *sc, s7_pointer x, s7_pointer y) { s7_int len, lim; len = s7_vector_length(x); lim = s7_vector_length(y); if (lim < len) len = lim; if (len == 0) return(0.0); return(mus_dot_product(s7_float_vector_elements(x), s7_float_vector_elements(y), len)); } PF2_TO_RF(dot_product, c_dot_product(sc, x, y)) static s7_pointer mus_fft_pf_i2(s7_scheme *sc, s7_pointer **p) { s7_pf_t pf; s7_if_t xf; s7_pointer rl, im; s7_int size, dir; pf = (s7_pf_t)(**p); (*p)++; rl = pf(sc, p); pf = (s7_pf_t)(**p); (*p)++; im = pf(sc, p); xf = (s7_if_t)(**p); (*p)++; size = xf(sc, p); xf = (s7_if_t)(**p); (*p)++; dir = xf(sc, p); mus_fft(s7_float_vector_elements(rl), s7_float_vector_elements(im), size, dir); return(rl); } static s7_pointer mus_fft_pf_i1(s7_scheme *sc, s7_pointer **p) { s7_pf_t pf; s7_if_t xf; s7_pointer rl, im; s7_int size; pf = (s7_pf_t)(**p); (*p)++; rl = pf(sc, p); pf = (s7_pf_t)(**p); (*p)++; im = pf(sc, p); xf = (s7_if_t)(**p); (*p)++; size = xf(sc, p); mus_fft(s7_float_vector_elements(rl), s7_float_vector_elements(im), size, 1); return(rl); } static s7_pointer mus_fft_pf_i0(s7_scheme *sc, s7_pointer **p) { s7_pf_t pf; s7_pointer rl, im; pf = (s7_pf_t)(**p); (*p)++; rl = pf(sc, p); pf = (s7_pf_t)(**p); (*p)++; im = pf(sc, p); mus_fft(s7_float_vector_elements(rl), s7_float_vector_elements(im), s7_vector_length(rl), 1); return(rl); } static s7_pf_t mus_fft_pf(s7_scheme *sc, s7_pointer expr) { if ((s7_is_pair(s7_cdr(expr))) && (s7_is_pair(s7_cddr(expr)))) { s7_pointer trailers; if (!s7_arg_to_pf(sc, s7_cadr(expr))) return(NULL); if (!s7_arg_to_pf(sc, s7_caddr(expr))) return(NULL); trailers = s7_cdddr(expr); if (s7_is_null(sc, trailers)) return(mus_fft_pf_i0); if (!s7_arg_to_if(sc, s7_car(trailers))) return(NULL); if (s7_is_null(sc, s7_cdr(trailers))) return(mus_fft_pf_i1); if (!s7_arg_to_if(sc, s7_cadr(trailers))) return(NULL); if (!s7_is_null(sc, s7_cddr(trailers))) return(NULL); return(mus_fft_pf_i2); } return(NULL); } #define MG_RF(Method, Func) \ static s7_double mus_ ## Method ## _rf_g(s7_scheme *sc, s7_pointer **p) \ { \ mus_any *g; g = (mus_any *)(**p); (*p)++; \ return(Func(g)); \ } \ static s7_rf_t mus_ ## Method ## _rf(s7_scheme *sc, s7_pointer expr) \ { \ mus_any *g; \ if (!s7_is_null(sc, s7_cddr(expr))) return(NULL); \ g = cadr_gen(sc, expr); \ if (g) {s7_xf_store(sc, (s7_pointer)g); return(mus_ ## Method ## _rf_g);} \ return(NULL); \ } #define MG_IF(Method, Func) \ static s7_int mus_ ## Method ## _if_g(s7_scheme *sc, s7_pointer **p) \ { \ mus_any *g; g = (mus_any *)(**p); (*p)++; \ return(Func(g)); \ } \ static s7_if_t mus_ ## Method ## _if(s7_scheme *sc, s7_pointer expr) \ { \ mus_any *g; \ if (!s7_is_null(sc, s7_cddr(expr))) return(NULL); \ g = cadr_gen(sc, expr); \ if (g) {s7_xf_store(sc, (s7_pointer)g); return(mus_ ## Method ## _if_g);} \ return(NULL); \ } #define PF_PF(Method, Func) \ static s7_pointer mus_ ## Method ## _pf_g(s7_scheme *sc, s7_pointer **p) \ { \ s7_pf_t f; \ s7_pointer g; \ f = (s7_pf_t)(**p); (*p)++; \ g = f(sc, p); \ return(Func(g)); \ } \ static s7_pf_t mus_ ## Method ## _pf(s7_scheme *sc, s7_pointer expr) \ { \ if (!s7_is_null(sc, s7_cddr(expr))) return(NULL); \ if (s7_arg_to_pf(sc, s7_cadr(expr))) return(mus_ ## Method ## _pf_g); \ return(NULL); \ } MG_RF(scaler, mus_scaler) MG_RF(phase, mus_phase) MG_RF(frequency, mus_frequency) MG_RF(offset, mus_offset) MG_RF(width, mus_width) MG_RF(increment, mus_increment) MG_RF(feedforward, mus_feedforward) MG_RF(feedback, mus_feedback) MG_IF(length, mus_length) MG_IF(order, mus_order) MG_IF(location, mus_location) MG_IF(channel, mus_channel) MG_IF(channels, mus_channels) MG_IF(ramp, mus_ramp) MG_IF(hop, mus_hop) PF_PF(data, g_mus_data) PF_PF(reset, g_mus_reset) #if 0 MG_RFIF(xcoeff, mus_xcoeff) MG_RFIF(ycoeff, mus_ycoeff) MG_PF(xcoeffs, c_mus_xcoeffs) -- x|ycoeffs are complicated and may involve wrapper creation MG_PF(ycoeffs, c_mus_ycoeffs) MG_PF(file_name, c_mus_file_name) -- requires c->xen string creation MG_PF(copy, c_mus_copy) -- allocation #endif #endif /* gmp */ static void init_choosers(s7_scheme *sc) { #if (!WITH_GMP) s7_pointer f; #endif env_symbol = s7_make_symbol(sc, "env"); comb_bank_symbol = s7_make_symbol(sc, "comb-bank"); vector_ref_symbol = s7_make_symbol(sc, "vector-ref"); polywave_symbol = s7_make_symbol(sc, "polywave"); triangle_wave_symbol = s7_make_symbol(sc, "triangle-wave"); rand_interp_symbol = s7_make_symbol(sc, "rand-interp"); oscil_symbol = s7_make_symbol(sc, "oscil"); multiply_symbol = s7_make_symbol(sc, "*"); add_symbol = s7_make_symbol(sc, "+"); quote_symbol = s7_make_symbol(sc, "quote"); cos_symbol = s7_make_symbol(sc, "cos"); mus_copy_symbol = s7_make_symbol(sc, "mus-copy"); copy_function = s7_name_to_value(sc, "copy"); sym_frequency = s7_make_symbol(sc, S_mus_frequency); sym_phase = s7_make_symbol(sc, S_mus_phase); sym_scaler = s7_make_symbol(sc, S_mus_scaler); sym_increment = s7_make_symbol(sc, S_mus_increment); sym_width = s7_make_symbol(sc, S_mus_width); sym_offset = s7_make_symbol(sc, S_mus_offset); sym_feedforward = s7_make_symbol(sc, S_mus_feedforward); sym_feedback = s7_make_symbol(sc, S_mus_feedback); #if (!WITH_GMP) f = s7_name_to_value(sc, "*"); initial_multiply_rf = s7_rf_function(sc, f); s7_rf_set_function(f, clm_multiply_rf); f = s7_name_to_value(sc, "+"); initial_add_rf = s7_rf_function(sc, f); s7_rf_set_function(f, clm_add_rf); s7_rf_set_function(s7_name_to_value(sc, S_outa), outa_rf); s7_rf_set_function(s7_name_to_value(sc, S_outb), outb_rf); s7_rf_set_function(s7_name_to_value(sc, S_ina), ina_rf); s7_rf_set_function(s7_name_to_value(sc, S_file_to_sample), file_to_sample_rf); s7_pf_set_function(s7_name_to_value(sc, S_file_to_frample), file_to_frample_pf); s7_pf_set_function(s7_name_to_value(sc, S_frample_to_file), frample_to_file_pf); s7_pf_set_function(s7_name_to_value(sc, S_frample_to_frample), frample_to_frample_pf); s7_rf_set_function(s7_name_to_value(sc, S_oscil), oscil_rf_3); s7_rf_set_function(s7_name_to_value(sc, S_polywave), polywave_rf); s7_rf_set_function(s7_name_to_value(sc, S_wave_train), wave_train_rf); s7_rf_set_function(s7_name_to_value(sc, S_granulate), granulate_rf); s7_rf_set_function(s7_name_to_value(sc, S_ncos), ncos_rf); s7_rf_set_function(s7_name_to_value(sc, S_nrxycos), nrxycos_rf); s7_rf_set_function(s7_name_to_value(sc, S_env), env_rf_1); s7_rf_set_function(s7_name_to_value(sc, S_readin), readin_rf); s7_rf_set_function(s7_name_to_value(sc, S_one_pole), one_pole_rf); s7_rf_set_function(s7_name_to_value(sc, S_moving_average), moving_average_rf); s7_rf_set_function(s7_name_to_value(sc, S_moving_max), moving_max_rf); s7_rf_set_function(s7_name_to_value(sc, S_fir_filter), fir_filter_rf); s7_rf_set_function(s7_name_to_value(sc, S_triangle_wave), triangle_wave_rf); s7_rf_set_function(s7_name_to_value(sc, S_pulse_train), pulse_train_rf); s7_rf_set_function(s7_name_to_value(sc, S_rand_interp), rand_interp_rf); s7_rf_set_function(s7_name_to_value(sc, S_formant), formant_rf_3); s7_rf_set_function(s7_name_to_value(sc, S_one_pole_all_pass), one_pole_all_pass_rf); s7_rf_set_function(s7_name_to_value(sc, S_delay), delay_rf_3); s7_rf_set_function(s7_name_to_value(sc, S_formant_bank), formant_bank_rf); s7_rf_set_function(s7_name_to_value(sc, S_oscil_bank), oscil_bank_rf); s7_rf_set_function(s7_name_to_value(sc, S_rand), rand_rf); s7_rf_set_function(s7_name_to_value(sc, S_filter), filter_rf); s7_rf_set_function(s7_name_to_value(sc, S_table_lookup), table_lookup_rf); s7_rf_set_function(s7_name_to_value(sc, S_src), src_rf); s7_rf_set_function(s7_name_to_value(sc, S_sawtooth_wave), sawtooth_wave_rf); s7_rf_set_function(s7_name_to_value(sc, S_inb), inb_rf); s7_rf_set_function(s7_name_to_value(sc, S_in_any), in_any_rf); s7_rf_set_function(s7_name_to_value(sc, S_polynomial), polynomial_rf); s7_rf_set_function(s7_name_to_value(sc, S_pink_noise), pink_noise_rf); s7_rf_set_function(s7_name_to_value(sc, S_piano_noise), piano_noise_rf); s7_rf_set_function(s7_name_to_value(sc, S_nsin), nsin_rf); s7_rf_set_function(s7_name_to_value(sc, S_nrxysin), nrxysin_rf); s7_rf_set_function(s7_name_to_value(sc, S_rxyksin), rxyksin_rf); s7_rf_set_function(s7_name_to_value(sc, S_rxykcos), rxykcos_rf); s7_rf_set_function(s7_name_to_value(sc, S_tap), tap_rf); s7_rf_set_function(s7_name_to_value(sc, S_comb), comb_rf_3); s7_rf_set_function(s7_name_to_value(sc, S_comb_bank), comb_bank_rf); s7_rf_set_function(s7_name_to_value(sc, S_notch), notch_rf_3); s7_rf_set_function(s7_name_to_value(sc, S_two_zero), two_zero_rf); s7_rf_set_function(s7_name_to_value(sc, S_one_zero), one_zero_rf); s7_rf_set_function(s7_name_to_value(sc, S_two_pole), two_pole_rf); s7_rf_set_function(s7_name_to_value(sc, S_moving_norm), moving_norm_rf); s7_rf_set_function(s7_name_to_value(sc, S_iir_filter), iir_filter_rf); s7_rf_set_function(s7_name_to_value(sc, S_square_wave), square_wave_rf); s7_rf_set_function(s7_name_to_value(sc, S_firmant), firmant_rf); s7_rf_set_function(s7_name_to_value(sc, S_all_pass), all_pass_rf_3); s7_rf_set_function(s7_name_to_value(sc, S_all_pass_bank), all_pass_bank_rf); s7_rf_set_function(s7_name_to_value(sc, S_polyshape), polyshape_rf); s7_rf_set_function(s7_name_to_value(sc, S_pulsed_env), pulsed_env_rf); s7_rf_set_function(s7_name_to_value(sc, S_ssb_am), ssb_am_rf_3); s7_rf_set_function(s7_name_to_value(sc, S_asymmetric_fm), asymmetric_fm_rf); s7_rf_set_function(s7_name_to_value(sc, S_filtered_comb), filtered_comb_rf); s7_rf_set_function(s7_name_to_value(sc, S_filtered_comb_bank), filtered_comb_bank_rf); s7_rf_set_function(s7_name_to_value(sc, S_move_sound), move_sound_rf); s7_rf_set_function(s7_name_to_value(sc, S_locsig), locsig_rf); s7_rf_set_function(s7_name_to_value(sc, S_out_bank), out_bank_rf); s7_rf_set_function(s7_name_to_value(sc, S_phase_vocoder), phase_vocoder_rf); s7_rf_set_function(s7_name_to_value(sc, S_convolve), convolve_rf); s7_rf_set_function(s7_name_to_value(sc, S_sample_to_file), sample_to_file_rf); s7_rf_set_function(s7_name_to_value(sc, S_mus_srate), srate_rf); s7_rf_set_function(s7_name_to_value(sc, S_contrast_enhancement), contrast_enhancement_rf); s7_rf_set_function(s7_name_to_value(sc, S_mus_set_formant_frequency), set_formant_frequency_rf); s7_rf_set_function(s7_name_to_value(sc, S_odd_weight), odd_weight_rf); s7_rf_set_function(s7_name_to_value(sc, S_even_weight), even_weight_rf); s7_rf_set_function(s7_name_to_value(sc, S_odd_multiple), odd_multiple_rf); s7_rf_set_function(s7_name_to_value(sc, S_even_multiple), even_multiple_rf); s7_rf_set_function(s7_name_to_value(sc, S_hz_to_radians), hz_to_radians_rf); s7_rf_set_function(s7_name_to_value(sc, S_radians_to_hz), radians_to_hz_rf); s7_rf_set_function(s7_name_to_value(sc, S_radians_to_degrees), radians_to_degrees_rf); s7_rf_set_function(s7_name_to_value(sc, S_degrees_to_radians), degrees_to_radians_rf); s7_rf_set_function(s7_name_to_value(sc, S_db_to_linear), db_to_linear_rf); s7_rf_set_function(s7_name_to_value(sc, S_linear_to_db), linear_to_db_rf); s7_rf_set_function(s7_name_to_value(sc, S_mus_random), random_rf); s7_rf_set_function(s7_name_to_value(sc, S_amplitude_modulate), am_rf); s7_rf_set_function(s7_name_to_value(sc, S_ring_modulate), ring_modulate_rf); s7_rf_set_function(s7_name_to_value(sc, S_array_interp), array_interp_rf); s7_pf_set_function(s7_name_to_value(sc, S_is_all_pass), is_all_pass_pf); s7_pf_set_function(s7_name_to_value(sc, S_is_asymmetric_fm), is_asymmetric_fm_pf); s7_pf_set_function(s7_name_to_value(sc, S_is_comb), is_comb_pf); s7_pf_set_function(s7_name_to_value(sc, S_is_comb_bank), is_comb_bank_pf); s7_pf_set_function(s7_name_to_value(sc, S_is_all_pass_bank), is_all_pass_bank_pf); s7_pf_set_function(s7_name_to_value(sc, S_is_convolve), is_convolve_pf); s7_pf_set_function(s7_name_to_value(sc, S_is_delay), is_delay_pf); s7_pf_set_function(s7_name_to_value(sc, S_is_env), is_env_pf); s7_pf_set_function(s7_name_to_value(sc, S_is_filter), is_filter_pf); s7_pf_set_function(s7_name_to_value(sc, S_is_filtered_comb), is_filtered_comb_pf); s7_pf_set_function(s7_name_to_value(sc, S_is_filtered_comb_bank), is_filtered_comb_bank_pf); s7_pf_set_function(s7_name_to_value(sc, S_is_fir_filter), is_fir_filter_pf); s7_pf_set_function(s7_name_to_value(sc, S_is_firmant), is_firmant_pf); s7_pf_set_function(s7_name_to_value(sc, S_is_formant), is_formant_pf); s7_pf_set_function(s7_name_to_value(sc, S_is_granulate), is_granulate_pf); s7_pf_set_function(s7_name_to_value(sc, S_is_iir_filter), is_iir_filter_pf); s7_pf_set_function(s7_name_to_value(sc, S_is_moving_average), is_moving_average_pf); s7_pf_set_function(s7_name_to_value(sc, S_is_moving_max), is_moving_max_pf); s7_pf_set_function(s7_name_to_value(sc, S_is_moving_norm), is_moving_norm_pf); s7_pf_set_function(s7_name_to_value(sc, S_is_ncos), is_ncos_pf); s7_pf_set_function(s7_name_to_value(sc, S_is_notch), is_notch_pf); s7_pf_set_function(s7_name_to_value(sc, S_is_nrxycos), is_nrxycos_pf); s7_pf_set_function(s7_name_to_value(sc, S_is_nrxysin), is_nrxysin_pf); s7_pf_set_function(s7_name_to_value(sc, S_is_nsin), is_nsin_pf); s7_pf_set_function(s7_name_to_value(sc, S_is_one_pole), is_one_pole_pf); s7_pf_set_function(s7_name_to_value(sc, S_is_one_pole_all_pass), is_one_pole_all_pass_pf); s7_pf_set_function(s7_name_to_value(sc, S_is_one_zero), is_one_zero_pf); s7_pf_set_function(s7_name_to_value(sc, S_is_oscil), is_oscil_pf); s7_pf_set_function(s7_name_to_value(sc, S_is_oscil_bank), is_oscil_bank_pf); s7_pf_set_function(s7_name_to_value(sc, S_is_phase_vocoder), is_phase_vocoder_pf); s7_pf_set_function(s7_name_to_value(sc, S_is_polyshape), is_polyshape_pf); s7_pf_set_function(s7_name_to_value(sc, S_is_polywave), is_polywave_pf); s7_pf_set_function(s7_name_to_value(sc, S_is_pulse_train), is_pulse_train_pf); s7_pf_set_function(s7_name_to_value(sc, S_is_pulsed_env), is_pulsed_env_pf); s7_pf_set_function(s7_name_to_value(sc, S_is_rand), is_rand_pf); s7_pf_set_function(s7_name_to_value(sc, S_is_rand_interp), is_rand_interp_pf); s7_pf_set_function(s7_name_to_value(sc, S_is_readin), is_readin_pf); s7_pf_set_function(s7_name_to_value(sc, S_is_rxykcos), is_rxykcos_pf); s7_pf_set_function(s7_name_to_value(sc, S_is_rxyksin), is_rxyksin_pf); s7_pf_set_function(s7_name_to_value(sc, S_is_sawtooth_wave), is_sawtooth_wave_pf); s7_pf_set_function(s7_name_to_value(sc, S_is_square_wave), is_square_wave_pf); s7_pf_set_function(s7_name_to_value(sc, S_is_src), is_src_pf); s7_pf_set_function(s7_name_to_value(sc, S_is_table_lookup), is_table_lookup_pf); s7_pf_set_function(s7_name_to_value(sc, S_is_triangle_wave), is_triangle_wave_pf); s7_pf_set_function(s7_name_to_value(sc, S_is_two_pole), is_two_pole_pf); s7_pf_set_function(s7_name_to_value(sc, S_is_two_zero), is_two_zero_pf); s7_pf_set_function(s7_name_to_value(sc, S_is_wave_train), is_wave_train_pf); s7_pf_set_function(s7_name_to_value(sc, S_is_ssb_am), is_ssb_am_pf); s7_pf_set_function(s7_name_to_value(sc, S_is_tap), is_tap_pf); s7_rf_set_function(s7_name_to_value(sc, S_dot_product), dot_product_rf); s7_pf_set_function(s7_name_to_value(sc, S_mus_fft), mus_fft_pf); s7_pf_set_function(s7_name_to_value(sc, S_rectangular_to_polar), rectangular_to_polar_pf); s7_pf_set_function(s7_name_to_value(sc, S_polar_to_rectangular), polar_to_rectangular_pf); s7_pf_set_function(s7_name_to_value(sc, S_rectangular_to_magnitudes), rectangular_to_magnitudes_pf); s7_rf_set_function(s7_name_to_value(sc, S_mus_chebyshev_t_sum), chebyshev_t_rf); s7_rf_set_function(s7_name_to_value(sc, S_mus_chebyshev_u_sum), chebyshev_u_rf); s7_rf_set_function(s7_name_to_value(sc, S_mus_chebyshev_tu_sum), chebyshev_tu_rf); s7_pf_set_function(s7_name_to_value(sc, S_mus_data), mus_data_pf); s7_pf_set_function(s7_name_to_value(sc, S_mus_reset), mus_reset_pf); s7_rf_set_function(s7_name_to_value(sc, S_mus_scaler), mus_scaler_rf); s7_rf_set_function(s7_name_to_value(sc, S_mus_phase), mus_phase_rf); s7_rf_set_function(s7_name_to_value(sc, S_mus_frequency), mus_frequency_rf); s7_rf_set_function(s7_name_to_value(sc, S_mus_offset), mus_offset_rf); s7_rf_set_function(s7_name_to_value(sc, S_mus_width), mus_width_rf); s7_rf_set_function(s7_name_to_value(sc, S_mus_increment), mus_increment_rf); s7_rf_set_function(s7_name_to_value(sc, S_mus_feedforward), mus_feedforward_rf); s7_rf_set_function(s7_name_to_value(sc, S_mus_feedback), mus_feedback_rf); s7_if_set_function(s7_name_to_value(sc, S_mus_length), mus_length_if); s7_if_set_function(s7_name_to_value(sc, S_mus_order), mus_order_if); s7_if_set_function(s7_name_to_value(sc, S_mus_location), mus_location_if); s7_if_set_function(s7_name_to_value(sc, S_mus_channel), mus_channel_if); s7_if_set_function(s7_name_to_value(sc, S_mus_channels), mus_channels_if); s7_if_set_function(s7_name_to_value(sc, S_mus_ramp), mus_ramp_if); s7_if_set_function(s7_name_to_value(sc, S_mus_hop), mus_hop_if); #endif /* gmp */ } #endif /*s7 */ Xen_wrap_no_args(g_mus_srate_w, g_mus_srate) Xen_wrap_1_arg(g_mus_set_srate_w, g_mus_set_srate) Xen_wrap_no_args(g_mus_float_equal_fudge_factor_w, g_mus_float_equal_fudge_factor) Xen_wrap_1_arg(g_mus_set_float_equal_fudge_factor_w, g_mus_set_float_equal_fudge_factor) Xen_wrap_no_args(g_mus_array_print_length_w, g_mus_array_print_length) Xen_wrap_1_arg(g_mus_set_array_print_length_w, g_mus_set_array_print_length) Xen_wrap_1_arg(g_radians_to_hz_w, g_radians_to_hz) Xen_wrap_1_arg(g_hz_to_radians_w, g_hz_to_radians) Xen_wrap_1_arg(g_radians_to_degrees_w, g_radians_to_degrees) Xen_wrap_1_arg(g_degrees_to_radians_w, g_degrees_to_radians) Xen_wrap_1_arg(g_db_to_linear_w, g_db_to_linear) Xen_wrap_1_arg(g_linear_to_db_w, g_linear_to_db) Xen_wrap_1_arg(g_even_weight_w, g_even_weight) Xen_wrap_1_arg(g_odd_weight_w, g_odd_weight) Xen_wrap_2_args(g_even_multiple_w, g_even_multiple) Xen_wrap_2_args(g_odd_multiple_w, g_odd_multiple) Xen_wrap_1_arg(g_seconds_to_samples_w, g_seconds_to_samples) Xen_wrap_1_arg(g_samples_to_seconds_w, g_samples_to_seconds) Xen_wrap_2_args(g_ring_modulate_w, g_ring_modulate) Xen_wrap_3_args(g_amplitude_modulate_w, g_amplitude_modulate) Xen_wrap_2_optional_args(g_contrast_enhancement_w, g_contrast_enhancement) Xen_wrap_3_optional_args(g_dot_product_w, g_dot_product) #if HAVE_COMPLEX_TRIG && HAVE_COMPLEX_NUMBERS && (!HAVE_RUBY) Xen_wrap_2_args(g_edot_product_w, g_edot_product) #endif Xen_wrap_2_args(g_polynomial_w, g_polynomial) Xen_wrap_4_optional_args(g_make_fft_window_w, g_make_fft_window) Xen_wrap_4_optional_args(g_mus_fft_w, g_mus_fft) Xen_wrap_4_optional_args(g_spectrum_w, g_spectrum) Xen_wrap_1_arg(g_autocorrelate_w, g_autocorrelate) Xen_wrap_2_args(g_correlate_w, g_correlate) Xen_wrap_3_optional_args(g_convolution_w, g_convolution) Xen_wrap_2_args(g_rectangular_to_polar_w, g_rectangular_to_polar) Xen_wrap_2_args(g_rectangular_to_magnitudes_w, g_rectangular_to_magnitudes) Xen_wrap_2_args(g_polar_to_rectangular_w, g_polar_to_rectangular) Xen_wrap_3_optional_args(g_array_interp_w, g_array_interp) Xen_wrap_5_optional_args(g_mus_interpolate_w, g_mus_interpolate) Xen_wrap_1_arg(g_mus_describe_w, g_mus_describe) Xen_wrap_1_arg(g_mus_name_w, g_mus_name) Xen_wrap_3_optional_args(g_mus_run_w, g_mus_run) Xen_wrap_1_arg(g_mus_phase_w, g_mus_phase) Xen_wrap_2_args(g_mus_set_phase_w, g_mus_set_phase) Xen_wrap_1_arg(g_mus_width_w, g_mus_width) Xen_wrap_2_args(g_mus_set_width_w, g_mus_set_width) Xen_wrap_1_arg(g_mus_scaler_w, g_mus_scaler) Xen_wrap_2_args(g_mus_set_scaler_w, g_mus_set_scaler) Xen_wrap_1_arg(g_mus_feedforward_w, g_mus_feedforward) Xen_wrap_2_args(g_mus_set_feedforward_w, g_mus_set_feedforward) Xen_wrap_1_arg(g_mus_reset_w, g_mus_reset) Xen_wrap_1_arg(g_mus_copy_w, g_mus_copy) Xen_wrap_1_arg(g_mus_offset_w, g_mus_offset) Xen_wrap_2_args(g_mus_set_offset_w, g_mus_set_offset) Xen_wrap_1_arg(g_mus_frequency_w, g_mus_frequency) Xen_wrap_2_args(g_mus_set_frequency_w, g_mus_set_frequency) Xen_wrap_1_arg(g_mus_length_w, g_mus_length) Xen_wrap_1_arg(g_mus_file_name_w, g_mus_file_name) Xen_wrap_2_args(g_mus_set_length_w, g_mus_set_length) Xen_wrap_1_arg(g_mus_type_w, g_mus_type) Xen_wrap_1_arg(g_mus_order_w, g_mus_order) Xen_wrap_1_arg(g_mus_data_w, g_mus_data) Xen_wrap_2_args(g_mus_set_data_w, g_mus_set_data) Xen_wrap_1_arg(g_is_oscil_w, g_is_oscil) Xen_wrap_3_optional_args(g_oscil_w, g_oscil) Xen_wrap_1_arg(g_is_oscil_bank_w, g_is_oscil_bank) Xen_wrap_1_arg(g_oscil_bank_w, g_oscil_bank) Xen_wrap_any_args(g_mus_apply_w, g_mus_apply) Xen_wrap_any_args(g_make_delay_w, g_make_delay) Xen_wrap_any_args(g_make_comb_w, g_make_comb) Xen_wrap_any_args(g_make_filtered_comb_w, g_make_filtered_comb) Xen_wrap_any_args(g_make_notch_w, g_make_notch) Xen_wrap_any_args(g_make_all_pass_w, g_make_all_pass) Xen_wrap_any_args(g_make_moving_average_w, g_make_moving_average) Xen_wrap_any_args(g_make_moving_max_w, g_make_moving_max) Xen_wrap_any_args(g_make_moving_norm_w, g_make_moving_norm) Xen_wrap_3_optional_args(g_delay_w, g_delay) Xen_wrap_2_optional_args(g_delay_tick_w, g_delay_tick) Xen_wrap_2_optional_args(g_tap_w, g_tap) Xen_wrap_3_optional_args(g_notch_w, g_notch) Xen_wrap_3_optional_args(g_comb_w, g_comb) Xen_wrap_3_optional_args(g_filtered_comb_w, g_filtered_comb) Xen_wrap_3_optional_args(g_all_pass_w, g_all_pass) Xen_wrap_2_optional_args(g_moving_average_w, g_moving_average) Xen_wrap_2_optional_args(g_moving_max_w, g_moving_max) Xen_wrap_2_optional_args(g_moving_norm_w, g_moving_norm) Xen_wrap_1_arg(g_is_tap_w, g_is_tap) Xen_wrap_1_arg(g_is_delay_w, g_is_delay) Xen_wrap_1_arg(g_is_notch_w, g_is_notch) Xen_wrap_1_arg(g_is_comb_w, g_is_comb) Xen_wrap_1_arg(g_is_filtered_comb_w, g_is_filtered_comb) Xen_wrap_1_arg(g_is_all_pass_w, g_is_all_pass) Xen_wrap_1_arg(g_is_moving_average_w, g_is_moving_average) Xen_wrap_1_arg(g_is_moving_max_w, g_is_moving_max) Xen_wrap_1_arg(g_is_moving_norm_w, g_is_moving_norm) Xen_wrap_2_optional_args(g_ncos_w, g_ncos) Xen_wrap_1_arg(g_is_ncos_w, g_is_ncos) Xen_wrap_2_optional_args(g_nsin_w, g_nsin) Xen_wrap_1_arg(g_is_nsin_w, g_is_nsin) Xen_wrap_any_args(g_make_rand_w, g_make_rand) Xen_wrap_any_args(g_make_rand_interp_w, g_make_rand_interp) Xen_wrap_2_optional_args(g_rand_w, g_rand) Xen_wrap_2_optional_args(g_rand_interp_w, g_rand_interp) Xen_wrap_1_arg(g_is_rand_w, g_is_rand) Xen_wrap_1_arg(g_is_rand_interp_w, g_is_rand_interp) Xen_wrap_1_arg(g_mus_random_w, g_mus_random) Xen_wrap_no_args(g_mus_rand_seed_w, g_mus_rand_seed) Xen_wrap_1_arg(g_mus_set_rand_seed_w, g_mus_set_rand_seed) Xen_wrap_1_arg(g_is_table_lookup_w, g_is_table_lookup) Xen_wrap_any_args(g_make_table_lookup_w, g_make_table_lookup) Xen_wrap_2_optional_args(g_table_lookup_w, g_table_lookup) Xen_wrap_3_optional_args(g_partials_to_wave_w, g_partials_to_wave) Xen_wrap_3_optional_args(g_phase_partials_to_wave_w, g_phase_partials_to_wave) Xen_wrap_6_optional_args(g_make_sawtooth_wave_w, g_make_sawtooth_wave) Xen_wrap_2_optional_args(g_sawtooth_wave_w, g_sawtooth_wave) Xen_wrap_1_arg(g_is_sawtooth_wave_w, g_is_sawtooth_wave) Xen_wrap_6_optional_args(g_make_triangle_wave_w, g_make_triangle_wave) Xen_wrap_2_optional_args(g_triangle_wave_w, g_triangle_wave) Xen_wrap_1_arg(g_is_triangle_wave_w, g_is_triangle_wave) Xen_wrap_6_optional_args(g_make_square_wave_w, g_make_square_wave) Xen_wrap_2_optional_args(g_square_wave_w, g_square_wave) Xen_wrap_1_arg(g_is_square_wave_w, g_is_square_wave) Xen_wrap_6_optional_args(g_make_pulse_train_w, g_make_pulse_train) Xen_wrap_2_optional_args(g_pulse_train_w, g_pulse_train) Xen_wrap_1_arg(g_is_pulse_train_w, g_is_pulse_train) Xen_wrap_3_args(g_make_pulsed_env_w, g_make_pulsed_env) Xen_wrap_2_optional_args(g_pulsed_env_w, g_pulsed_env) Xen_wrap_1_arg(g_is_pulsed_env_w, g_is_pulsed_env) Xen_wrap_3_optional_args(g_asymmetric_fm_w, g_asymmetric_fm) Xen_wrap_1_arg(g_is_asymmetric_fm_w, g_is_asymmetric_fm) Xen_wrap_4_optional_args(g_make_one_zero_w, g_make_one_zero) Xen_wrap_2_optional_args(g_one_zero_w, g_one_zero) Xen_wrap_1_arg(g_is_one_zero_w, g_is_one_zero) Xen_wrap_4_optional_args(g_make_one_pole_w, g_make_one_pole) Xen_wrap_2_optional_args(g_one_pole_w, g_one_pole) Xen_wrap_1_arg(g_is_one_pole_w, g_is_one_pole) Xen_wrap_6_optional_args(g_make_two_zero_w, g_make_two_zero) Xen_wrap_2_optional_args(g_two_zero_w, g_two_zero) Xen_wrap_1_arg(g_is_two_zero_w, g_is_two_zero) Xen_wrap_6_optional_args(g_make_two_pole_w, g_make_two_pole) Xen_wrap_2_optional_args(g_two_pole_w, g_two_pole) Xen_wrap_1_arg(g_is_two_pole_w, g_is_two_pole) Xen_wrap_1_arg(g_is_formant_w, g_is_formant) Xen_wrap_4_optional_args(g_make_formant_w, g_make_formant) Xen_wrap_3_optional_args(g_formant_w, g_formant) Xen_wrap_2_optional_args(g_formant_bank_w, g_formant_bank) Xen_wrap_1_arg(g_is_formant_bank_w, g_is_formant_bank) Xen_wrap_2_optional_args(g_make_formant_bank_w, g_make_formant_bank) Xen_wrap_1_arg(g_is_firmant_w, g_is_firmant) Xen_wrap_4_optional_args(g_make_firmant_w, g_make_firmant) Xen_wrap_3_optional_args(g_firmant_w, g_firmant) Xen_wrap_1_arg(g_is_one_pole_all_pass_w, g_is_one_pole_all_pass) Xen_wrap_2_args(g_make_one_pole_all_pass_w, g_make_one_pole_all_pass) Xen_wrap_2_optional_args(g_one_pole_all_pass_w, g_one_pole_all_pass) Xen_wrap_2_args(g_set_formant_frequency_w, g_set_formant_frequency) Xen_wrap_3_args(g_set_formant_radius_and_frequency_w, g_set_formant_radius_and_frequency) Xen_wrap_5_args(g_frample_to_frample_w, g_frample_to_frample) Xen_wrap_any_args(g_make_wave_train_w, g_make_wave_train) Xen_wrap_2_optional_args(g_wave_train_w, g_wave_train) Xen_wrap_1_arg(g_is_wave_train_w, g_is_wave_train) Xen_wrap_any_args(g_make_polyshape_w, g_make_polyshape) Xen_wrap_3_optional_args(g_polyshape_w, g_polyshape) Xen_wrap_1_arg(g_is_polyshape_w, g_is_polyshape) Xen_wrap_2_optional_args(g_partials_to_polynomial_w, g_partials_to_polynomial) Xen_wrap_1_arg(g_normalize_partials_w, g_normalize_partials) Xen_wrap_2_args(g_chebyshev_t_sum_w, g_chebyshev_t_sum) Xen_wrap_2_args(g_chebyshev_u_sum_w, g_chebyshev_u_sum) Xen_wrap_3_args(g_chebyshev_tu_sum_w, g_chebyshev_tu_sum) Xen_wrap_any_args(g_make_polywave_w, g_make_polywave) Xen_wrap_2_optional_args(g_polywave_w, g_polywave) Xen_wrap_1_arg(g_is_polywave_w, g_is_polywave) Xen_wrap_any_args(g_make_nrxysin_w, g_make_nrxysin) Xen_wrap_2_optional_args(g_nrxysin_w, g_nrxysin) Xen_wrap_1_arg(g_is_nrxysin_w, g_is_nrxysin) Xen_wrap_any_args(g_make_nrxycos_w, g_make_nrxycos) Xen_wrap_2_optional_args(g_nrxycos_w, g_nrxycos) Xen_wrap_1_arg(g_is_nrxycos_w, g_is_nrxycos) Xen_wrap_any_args(g_make_rxyksin_w, g_make_rxyksin) Xen_wrap_2_optional_args(g_rxyksin_w, g_rxyksin) Xen_wrap_1_arg(g_is_rxyksin_w, g_is_rxyksin) Xen_wrap_any_args(g_make_rxykcos_w, g_make_rxykcos) Xen_wrap_2_optional_args(g_rxykcos_w, g_rxykcos) Xen_wrap_1_arg(g_is_rxykcos_w, g_is_rxykcos) Xen_wrap_6_optional_args(g_make_filter_w, g_make_filter) Xen_wrap_2_optional_args(g_filter_w, g_filter) Xen_wrap_1_arg(g_is_filter_w, g_is_filter) Xen_wrap_4_optional_args(g_make_fir_filter_w, g_make_fir_filter) Xen_wrap_2_args(g_make_fir_coeffs_w, g_make_fir_coeffs) Xen_wrap_2_optional_args(g_fir_filter_w, g_fir_filter) Xen_wrap_1_arg(g_is_fir_filter_w, g_is_fir_filter) Xen_wrap_4_optional_args(g_make_iir_filter_w, g_make_iir_filter) Xen_wrap_2_optional_args(g_iir_filter_w, g_iir_filter) Xen_wrap_1_arg(g_is_iir_filter_w, g_is_iir_filter) Xen_wrap_1_arg(g_mus_xcoeffs_w, g_mus_xcoeffs) Xen_wrap_1_arg(g_mus_ycoeffs_w, g_mus_ycoeffs) Xen_wrap_2_args(g_mus_xcoeff_w, g_mus_xcoeff) Xen_wrap_3_args(g_mus_set_xcoeff_w, g_mus_set_xcoeff) Xen_wrap_2_args(g_mus_ycoeff_w, g_mus_ycoeff) Xen_wrap_3_args(g_mus_set_ycoeff_w, g_mus_set_ycoeff) Xen_wrap_1_arg(g_is_env_w, g_is_env) Xen_wrap_1_arg(g_env_w, g_env) Xen_wrap_any_args(g_make_env_w, g_make_env) Xen_wrap_2_args(g_env_interp_w, g_env_interp) Xen_wrap_3_optional_args(g_envelope_interp_w, g_envelope_interp) Xen_wrap_2_args(g_env_any_w, g_env_any) Xen_wrap_1_arg(g_is_file_to_sample_w, g_is_file_to_sample) Xen_wrap_2_optional_args(g_make_file_to_sample_w, g_make_file_to_sample) Xen_wrap_3_optional_args(g_file_to_sample_w, g_file_to_sample) Xen_wrap_1_arg(g_is_sample_to_file_w, g_is_sample_to_file) Xen_wrap_5_optional_args(g_make_sample_to_file_w, g_make_sample_to_file) Xen_wrap_1_arg(g_continue_sample_to_file_w, g_continue_sample_to_file) Xen_wrap_4_args(g_sample_to_file_w, g_sample_to_file) Xen_wrap_2_args(g_sample_to_file_add_w, g_sample_to_file_add) Xen_wrap_1_arg(g_is_file_to_frample_w, g_is_file_to_frample) Xen_wrap_2_optional_args(g_make_file_to_frample_w, g_make_file_to_frample) Xen_wrap_3_optional_args(g_file_to_frample_w, g_file_to_frample) Xen_wrap_1_arg(g_continue_frample_to_file_w, g_continue_frample_to_file) Xen_wrap_1_arg(g_is_frample_to_file_w, g_is_frample_to_file) Xen_wrap_3_args(g_frample_to_file_w, g_frample_to_file) Xen_wrap_5_optional_args(g_make_frample_to_file_w, g_make_frample_to_file) Xen_wrap_1_arg(g_is_mus_input_w, g_is_mus_input) Xen_wrap_1_arg(g_is_mus_output_w, g_is_mus_output) Xen_wrap_3_args(g_in_any_w, g_in_any) Xen_wrap_2_args(g_ina_w, g_ina) Xen_wrap_2_args(g_inb_w, g_inb) Xen_wrap_4_optional_args(g_out_any_w, g_out_any) Xen_wrap_3_optional_args(g_outa_w, g_outa) Xen_wrap_3_optional_args(g_outb_w, g_outb) Xen_wrap_3_optional_args(g_outc_w, g_outc) Xen_wrap_3_optional_args(g_outd_w, g_outd) Xen_wrap_1_arg(g_mus_close_w, g_mus_close) Xen_wrap_no_args(g_mus_file_buffer_size_w, g_mus_file_buffer_size) Xen_wrap_1_arg(g_mus_set_file_buffer_size_w, g_mus_set_file_buffer_size) Xen_wrap_1_arg(g_is_readin_w, g_is_readin) Xen_wrap_1_arg(g_readin_w, g_readin) Xen_wrap_any_args(g_make_readin_w, g_make_readin) Xen_wrap_1_arg(g_mus_channel_w, g_mus_channel) Xen_wrap_1_arg(g_mus_interp_type_w, g_mus_interp_type) Xen_wrap_1_arg(g_mus_location_w, g_mus_location) Xen_wrap_2_args(g_mus_set_location_w, g_mus_set_location) Xen_wrap_1_arg(g_mus_increment_w, g_mus_increment) Xen_wrap_2_args(g_mus_set_increment_w, g_mus_set_increment) Xen_wrap_1_arg(g_mus_feedback_w, g_mus_feedback) Xen_wrap_2_args(g_mus_set_feedback_w, g_mus_set_feedback) Xen_wrap_1_arg(g_is_locsig_w, g_is_locsig) Xen_wrap_3_args(g_locsig_w, g_locsig) Xen_wrap_any_args(g_make_locsig_w, g_make_locsig) Xen_wrap_3_args(g_move_locsig_w, g_move_locsig) Xen_wrap_no_args(g_locsig_type_w, g_locsig_type) Xen_wrap_1_arg(g_set_locsig_type_w, g_set_locsig_type) Xen_wrap_1_arg(g_mus_channels_w, g_mus_channels) Xen_wrap_2_args(g_locsig_ref_w, g_locsig_ref) Xen_wrap_2_args(g_locsig_reverb_ref_w, g_locsig_reverb_ref) Xen_wrap_3_args(g_locsig_set_w, g_locsig_set) Xen_wrap_3_args(g_locsig_reverb_set_w, g_locsig_reverb_set) Xen_wrap_1_arg(g_is_move_sound_w, g_is_move_sound) Xen_wrap_3_args(g_move_sound_w, g_move_sound) Xen_wrap_3_optional_args(g_make_move_sound_w, g_make_move_sound) Xen_wrap_no_args(g_mus_clear_sincs_w, g_mus_clear_sincs) Xen_wrap_1_arg(g_is_src_w, g_is_src) Xen_wrap_3_optional_args(g_src_w, g_src) Xen_wrap_6_optional_args(g_make_src_w, g_make_src) Xen_wrap_1_arg(g_is_granulate_w, g_is_granulate) Xen_wrap_3_optional_args(g_granulate_w, g_granulate) Xen_wrap_any_args(g_make_granulate_w, g_make_granulate) Xen_wrap_1_arg(g_mus_ramp_w, g_mus_ramp) Xen_wrap_2_args(g_mus_set_ramp_w, g_mus_set_ramp) Xen_wrap_1_arg(g_is_convolve_w, g_is_convolve) Xen_wrap_2_optional_args(g_convolve_w, g_convolve) Xen_wrap_any_args(g_make_convolve_w, g_make_convolve) Xen_wrap_4_optional_args(g_convolve_files_w, g_convolve_files) Xen_wrap_1_arg(g_is_phase_vocoder_w, g_is_phase_vocoder) Xen_wrap_5_optional_args(g_phase_vocoder_w, g_phase_vocoder) Xen_wrap_any_args(g_make_phase_vocoder_w, g_make_phase_vocoder) Xen_wrap_1_arg(g_phase_vocoder_amp_increments_w, g_phase_vocoder_amp_increments) Xen_wrap_1_arg(g_phase_vocoder_amps_w, g_phase_vocoder_amps) Xen_wrap_1_arg(g_phase_vocoder_freqs_w, g_phase_vocoder_freqs) Xen_wrap_1_arg(g_phase_vocoder_phases_w, g_phase_vocoder_phases) Xen_wrap_1_arg(g_phase_vocoder_phase_increments_w, g_phase_vocoder_phase_increments) Xen_wrap_1_arg(g_mus_hop_w, g_mus_hop) Xen_wrap_2_args(g_mus_set_hop_w, g_mus_set_hop) Xen_wrap_4_optional_args(g_make_ssb_am_w, g_make_ssb_am) Xen_wrap_3_optional_args(g_ssb_am_w, g_ssb_am) Xen_wrap_1_arg(g_is_ssb_am_w, g_is_ssb_am) Xen_wrap_no_args(g_clm_table_size_w, g_clm_table_size) Xen_wrap_1_arg(g_set_clm_table_size_w, g_set_clm_table_size) Xen_wrap_no_args(g_clm_default_frequency_w, g_clm_default_frequency) Xen_wrap_1_arg(g_set_clm_default_frequency_w, g_set_clm_default_frequency) Xen_wrap_1_arg(g_is_mus_generator_w, g_is_mus_generator) Xen_wrap_1_arg(g_mus_frandom_w, g_mus_frandom) Xen_wrap_1_arg(g_mus_irandom_w, g_mus_irandom) Xen_wrap_4_optional_args(g_make_oscil_w, g_make_oscil) Xen_wrap_4_optional_args(g_make_ncos_w, g_make_ncos) Xen_wrap_4_optional_args(g_make_oscil_bank_w, g_make_oscil_bank) Xen_wrap_4_optional_args(g_make_nsin_w, g_make_nsin) Xen_wrap_8_optional_args(g_make_asymmetric_fm_w, g_make_asymmetric_fm) Xen_wrap_any_args(g_mus_file_mix_w, g_mus_file_mix) Xen_wrap_any_args(g_mus_file_mix_with_envs_w, g_mus_file_mix_with_envs) Xen_wrap_2_optional_args(g_comb_bank_w, g_comb_bank) Xen_wrap_1_arg(g_is_comb_bank_w, g_is_comb_bank) Xen_wrap_1_arg(g_make_comb_bank_w, g_make_comb_bank) Xen_wrap_2_optional_args(g_filtered_comb_bank_w, g_filtered_comb_bank) Xen_wrap_1_arg(g_is_filtered_comb_bank_w, g_is_filtered_comb_bank) Xen_wrap_1_arg(g_make_filtered_comb_bank_w, g_make_filtered_comb_bank) Xen_wrap_2_optional_args(g_all_pass_bank_w, g_all_pass_bank) Xen_wrap_1_arg(g_is_all_pass_bank_w, g_is_all_pass_bank) Xen_wrap_1_arg(g_make_all_pass_bank_w, g_make_all_pass_bank) Xen_wrap_1_arg(g_pink_noise_w, g_pink_noise) Xen_wrap_3_args(g_out_bank_w, g_out_bank) #if HAVE_SCHEME Xen_wrap_2_args(g_piano_noise_w, g_piano_noise) Xen_wrap_6_args(g_singer_filter_w, g_singer_filter) Xen_wrap_5_args(g_singer_nose_filter_w, g_singer_nose_filter) #endif #if HAVE_SCHEME static s7_pointer acc_clm_srate(s7_scheme *sc, s7_pointer args) {return(g_mus_set_srate(s7_cadr(args)));} static s7_pointer acc_clm_default_frequency(s7_scheme *sc, s7_pointer args) {return(g_set_clm_default_frequency(s7_cadr(args)));} static s7_pointer acc_clm_table_size(s7_scheme *sc, s7_pointer args) {return(g_set_clm_table_size(s7_cadr(args)));} static s7_pointer acc_mus_file_buffer_size(s7_scheme *sc, s7_pointer args) {return(g_mus_set_file_buffer_size(s7_cadr(args)));} static s7_pointer acc_mus_float_equal_fudge_factor(s7_scheme *sc, s7_pointer args) {return(g_mus_set_float_equal_fudge_factor(s7_cadr(args)));} static s7_pointer acc_mus_array_print_length(s7_scheme *sc, s7_pointer args) {return(g_mus_set_array_print_length(s7_cadr(args)));} #endif #if HAVE_SCHEME static char *mus_generator_to_readable_string(s7_scheme *sc, void *obj) { char *str; str = (char *)malloc(64 * sizeof(char)); snprintf(str, 64, "#<%s>", mus_name(((mus_xen *)obj)->gen)); return(str); /* we need a new function to fill this role */ /* s7_error(sc, s7_make_symbol(sc, "io-error"), s7_list(sc, 1, s7_make_string(sc, "can't write a clm generator readably"))); */ /* return(NULL); */ } #endif static void mus_xen_init(void) { #if HAVE_SCHEME s7_pointer s, i, p, t, r, c, f, v, b, d; s7_pointer pcl_ct, pl_rcr, pl_bt, pl_ir, pl_cc, pl_ccic, pl_ccrr, pl_fc, pl_fcif, pl_cs, pl_ff, pl_tt, pl_fffifi, pl_ffftii, pl_fffi, pl_fti, pl_fif, pl_fiir, pl_fttb, pl_ic, pl_rciir, pl_rcir, pl_ririt, pl_rcrr, pl_rirt, pl_riirfff, pl_rirfff, pl_rrpr, pcl_zt, pl_sc, pl_sssrs, pl_tc, pl_ct, pl_ici, pl_i, pl_fcf, pl_dcr, pl_dr, pl_dffi, pl_dfri, pl_dirfir, pl_dc, pl_dci, pl_dcir, pl_dv, pl_dvir, pl_drf, pl_drc, pl_diit, pl_dit, pl_dct, pl_d; #endif mus_initialize(); current_connect_func = Xen_false; #if HAVE_SCHEME mus_xen_tag = s7_new_type_x(s7, "", print_mus_xen, free_mus_xen, s7_equalp_mus_xen, mark_mus_xen, mus_xen_apply, NULL, s7_mus_length, s7_mus_copy, NULL, NULL); as_needed_arglist = Xen_list_1(Xen_integer_zero); Xen_GC_protect(as_needed_arglist); s7_set_object_print_readably(mus_xen_tag, mus_generator_to_readable_string); s = s7_make_symbol(s7, "string?"); i = s7_make_symbol(s7, "integer?"); p = s7_make_symbol(s7, "pair?"); t = s7_t(s7); r = s7_make_symbol(s7, "real?"); c = s7_make_symbol(s7, "c-object?"); f = s7_make_symbol(s7, "float-vector?"); v = s7_make_symbol(s7, "vector?"); b = s7_make_symbol(s7, "boolean?"); d = s7_make_symbol(s7, "float?"); pcl_ct = s7_make_circular_signature(s7, 1, 2, c, t); pcl_zt = s7_make_circular_signature(s7, 1, 2, s7_make_signature(s7, 2, b, c), t); pl_bt = s7_make_signature(s7, 2, b, t); pl_rcr = s7_make_signature(s7, 3, r, c, r); pl_d = s7_make_signature(s7, 1, d); pl_dcr = s7_make_circular_signature(s7, 2, 3, d, c, r); pl_dct = s7_make_signature(s7, 3, d, c, t); pl_dci = s7_make_circular_signature(s7, 2, 3, d, c, i); pl_dcir = s7_make_signature(s7, 4, d, c, i, r); pl_dr = s7_make_circular_signature(s7, 1, 2, d, r); pl_dffi = s7_make_signature(s7, 4, d, f, f, i); pl_dfri = s7_make_signature(s7, 4, d, f, r, i); pl_dirfir = s7_make_signature(s7, 6, d, i, r, f, i, r); pl_dc = s7_make_signature(s7, 2, d, c); pl_dv = s7_make_signature(s7, 2, d, v); pl_dvir = s7_make_signature(s7, 4, d, v, i, r); pl_drf = s7_make_circular_signature(s7, 2, 3, d, r, f); pl_drc = s7_make_signature(s7, 3, d, r, c); pl_diit = s7_make_signature(s7, 4, d, i, i, t); pl_dit = s7_make_signature(s7, 3, d, i, t); pl_ir = s7_make_signature(s7, 2, i, r); pl_i = s7_make_circular_signature(s7, 0, 1, i); pl_ct = s7_make_signature(s7, 2, c, t); pl_cc = s7_make_circular_signature(s7, 1, 2, c, c); pl_ici = s7_make_signature(s7, 3, i, c, i); pl_ccic = s7_make_signature(s7, 3, c, c, i, c); pl_ccrr = s7_make_signature(s7, 4, c, c, r, r); pl_fc = s7_make_signature(s7, 2, s7_make_signature(s7, 2, f, b), c); pl_cs = s7_make_signature(s7, 2, c, s); pl_ff = s7_make_circular_signature(s7, 1, 2, f, f); pl_tt = s7_make_signature(s7, 2, t, t); pl_fcf = s7_make_signature(s7, 3, f, c, f); pl_fffifi = s7_make_signature(s7, 6, f, f, f, i, f, i); pl_ffftii = s7_make_signature(s7, 6, f, f, f, t, i, i); pl_fffi = s7_make_circular_signature(s7, 3, 4, f, f, f, i); pl_fti = s7_make_signature(s7, 3, f, t, i); pl_fif = s7_make_signature(s7, 3, f, i, f); pl_fiir = s7_make_signature(s7, 4, f, i, i, r); pl_fttb = s7_make_signature(s7, 4, f, t, t, b); pl_ic = s7_make_signature(s7, 2, i, c); pl_rciir = s7_make_signature(s7, 5, r, c, i, i, r); pl_rcir = s7_make_signature(s7, 4, r, c, i, r); pl_ririt = s7_make_signature(s7,5, r, i, r, i, t); pl_rcrr = s7_make_signature(s7, 4, r, c, r, r); pl_rirt = s7_make_signature(s7, 4, r, i, r, t); pl_riirfff = s7_make_signature(s7, 7, r, i, i, r, f, f, f); pl_rirfff = s7_make_signature(s7, 6, r, i, r, f, f, f); pl_rrpr = s7_make_signature(s7, 4, r, r, p, r); pl_sc = s7_make_signature(s7, 2, s, c); pl_sssrs = s7_make_signature(s7, 5, s, s, s, r, s); pl_tc = s7_make_signature(s7, 2, t, c); pl_fcif = s7_make_signature(s7, 4, f, c, i, f); #else mus_xen_tag = Xen_make_object_type("Mus", sizeof(mus_xen)); #endif xen_one = C_int_to_Xen_integer(1); Xen_GC_protect(xen_one); xen_minus_one = C_int_to_Xen_integer(-1); Xen_GC_protect(xen_minus_one); #if HAVE_FORTH fth_set_object_inspect(mus_xen_tag, print_mus_xen); fth_set_object_equal(mus_xen_tag, equalp_mus_xen); fth_set_object_mark(mus_xen_tag, mark_mus_xen); fth_set_object_free(mus_xen_tag, free_mus_xen); fth_set_object_apply(mus_xen_tag, Xen_procedure_cast mus_xen_apply, 0, 2, 0); #endif #if HAVE_RUBY rb_define_method(mus_xen_tag, "to_s", Xen_procedure_cast mus_xen_to_s, 0); rb_define_method(mus_xen_tag, "eql?", Xen_procedure_cast equalp_mus_xen, 1); rb_define_method(mus_xen_tag, "frequency", Xen_procedure_cast g_mus_frequency, 0); rb_define_method(mus_xen_tag, "frequency=", Xen_procedure_cast g_mus_set_frequency, 1); rb_define_method(mus_xen_tag, "phase", Xen_procedure_cast g_mus_phase, 0); rb_define_method(mus_xen_tag, "phase=", Xen_procedure_cast g_mus_set_phase, 1); rb_define_method(mus_xen_tag, "scaler", Xen_procedure_cast g_mus_scaler, 0); rb_define_method(mus_xen_tag, "scaler=", Xen_procedure_cast g_mus_set_scaler, 1); rb_define_method(mus_xen_tag, "width", Xen_procedure_cast g_mus_width, 0); rb_define_method(mus_xen_tag, "width=", Xen_procedure_cast g_mus_set_width, 1); rb_define_method(mus_xen_tag, "offset", Xen_procedure_cast g_mus_offset, 0); rb_define_method(mus_xen_tag, "offset=", Xen_procedure_cast g_mus_set_offset, 1); rb_define_method(mus_xen_tag, "reset", Xen_procedure_cast g_mus_reset, 0); /* rb_define_method(mus_xen_tag, "copy", Xen_procedure_cast g_mus_copy, 0); */ rb_define_method(mus_xen_tag, "length", Xen_procedure_cast g_mus_length, 0); rb_define_method(mus_xen_tag, "length=", Xen_procedure_cast g_mus_set_length, 1); rb_define_method(mus_xen_tag, "data", Xen_procedure_cast g_mus_data, 0); rb_define_method(mus_xen_tag, "data=", Xen_procedure_cast g_mus_set_data, 1); rb_define_method(mus_xen_tag, "feedforward", Xen_procedure_cast g_mus_feedforward, 0); rb_define_method(mus_xen_tag, "feedforward=", Xen_procedure_cast g_mus_set_feedforward, 1); rb_define_method(mus_xen_tag, "feedback", Xen_procedure_cast g_mus_feedback, 0); rb_define_method(mus_xen_tag, "feedback=", Xen_procedure_cast g_mus_set_increment, 1); rb_define_method(mus_xen_tag, "order", Xen_procedure_cast g_mus_order, 0); rb_define_method(mus_xen_tag, "type", Xen_procedure_cast g_mus_type, 0); rb_define_method(mus_xen_tag, "order=", Xen_procedure_cast g_mus_set_length, 1); rb_define_method(mus_xen_tag, "call", Xen_procedure_cast mus_xen_apply, 2); rb_define_method(mus_xen_tag, "location", Xen_procedure_cast g_mus_location, 0); rb_define_method(mus_xen_tag, "location=", Xen_procedure_cast g_mus_set_location, 1); rb_define_method(mus_xen_tag, "increment", Xen_procedure_cast g_mus_increment, 0); rb_define_method(mus_xen_tag, "increment=", Xen_procedure_cast g_mus_set_increment, 1); rb_define_method(mus_xen_tag, "channels", Xen_procedure_cast g_mus_channels, 0); rb_define_method(mus_xen_tag, "channel", Xen_procedure_cast g_mus_channel, 0); rb_define_method(mus_xen_tag, "interp_type", Xen_procedure_cast g_mus_interp_type, 0); rb_define_method(mus_xen_tag, "xcoeffs", Xen_procedure_cast g_mus_xcoeffs, 0); rb_define_method(mus_xen_tag, "ycoeffs", Xen_procedure_cast g_mus_ycoeffs, 0); rb_define_method(mus_xen_tag, "xcoeff", Xen_procedure_cast g_mus_xcoeff, 1); rb_define_method(mus_xen_tag, "ycoeff", Xen_procedure_cast g_mus_ycoeff, 1); /* rb_define_method(mus_xen_tag, "xcoeff=", Xen_procedure_cast g_mus_set_xcoeff, 1); rb_define_method(mus_xen_tag, "ycoeff=", Xen_procedure_cast g_mus_set_ycoeff, 1); */ rb_define_method(mus_xen_tag, "ramp", Xen_procedure_cast g_mus_ramp, 0); rb_define_method(mus_xen_tag, "ramp=", Xen_procedure_cast g_mus_set_ramp, 1); rb_define_method(mus_xen_tag, "hop", Xen_procedure_cast g_mus_hop, 0); rb_define_method(mus_xen_tag, "hop=", Xen_procedure_cast g_mus_set_hop, 1); rb_define_method(mus_xen_tag, "name", Xen_procedure_cast g_mus_name, 0); rb_define_method(mus_xen_tag, "file_name", Xen_procedure_cast g_mus_file_name, 0); #endif init_keywords(); Xen_define_typed_dilambda(S_mus_srate, g_mus_srate_w, H_mus_srate, S_set S_mus_srate, g_mus_set_srate_w, 0, 0, 1, 0, pl_d, pl_dr); Xen_define_typed_dilambda(S_mus_float_equal_fudge_factor, g_mus_float_equal_fudge_factor_w, H_mus_float_equal_fudge_factor, S_set S_mus_float_equal_fudge_factor, g_mus_set_float_equal_fudge_factor_w, 0, 0, 1, 0, pl_d, pl_dr); Xen_define_typed_dilambda(S_mus_array_print_length, g_mus_array_print_length_w, H_mus_array_print_length, S_set S_mus_array_print_length, g_mus_set_array_print_length_w, 0, 0, 1, 0, pl_i, pl_i); Xen_define_typed_dilambda(S_clm_table_size, g_clm_table_size_w, H_clm_table_size, S_set S_clm_table_size, g_set_clm_table_size_w, 0, 0, 1, 0, pl_i, pl_i); Xen_define_typed_dilambda(S_clm_default_frequency, g_clm_default_frequency_w, H_clm_default_frequency, S_set S_clm_default_frequency, g_set_clm_default_frequency_w, 0, 0, 1, 0, pl_d, pl_dr); #if HAVE_SCHEME clm_srate_symbol = s7_define_variable(s7, "*clm-srate*", s7_make_real(s7, MUS_DEFAULT_SAMPLING_RATE)); s7_symbol_set_access(s7, clm_srate_symbol, s7_make_function(s7, "[acc-clm-srate]", acc_clm_srate, 2, 0, false, "accessor")); clm_default_frequency_symbol = s7_define_variable(s7, "*" S_clm_default_frequency "*", s7_make_real(s7, MUS_CLM_DEFAULT_FREQUENCY)); s7_symbol_set_documentation(s7, clm_default_frequency_symbol, "*clm-default-frequency*: the default frequency for most generators (0.0)"); s7_symbol_set_access(s7, clm_default_frequency_symbol, s7_make_function(s7, "[acc-clm-default-frequency]", acc_clm_default_frequency, 2, 0, false, "accessor")); clm_table_size_symbol = s7_define_variable(s7, "*" S_clm_table_size "*", s7_make_integer(s7, MUS_CLM_DEFAULT_TABLE_SIZE)); s7_symbol_set_documentation(s7, clm_table_size_symbol, "*clm-table-size*: the default table size for most generators (512)"); s7_symbol_set_access(s7, clm_table_size_symbol, s7_make_function(s7, "[acc-clm-table-size]", acc_clm_table_size, 2, 0, false, "accessor")); mus_file_buffer_size_symbol = s7_define_variable(s7, "*clm-file-buffer-size*", s7_make_integer(s7, MUS_DEFAULT_FILE_BUFFER_SIZE)); s7_symbol_set_access(s7, mus_file_buffer_size_symbol, s7_make_function(s7, "[acc-mus-file-buffer-size]", acc_mus_file_buffer_size, 2, 0, false, "accessor")); mus_float_equal_fudge_factor_symbol = s7_define_variable(s7, "*" S_mus_float_equal_fudge_factor "*", s7_make_real(s7, 0.0000001)); /* clm.c */ s7_symbol_set_documentation(s7, mus_float_equal_fudge_factor_symbol, "*mus-float-equal-fudge-factor*: floating point equality fudge factor"); s7_symbol_set_access(s7, mus_float_equal_fudge_factor_symbol, s7_make_function(s7, "[acc-mus-float-equal-fudge-factor]", acc_mus_float_equal_fudge_factor, 2, 0, false, "accessor")); mus_array_print_length_symbol = s7_define_variable(s7, "*" S_mus_array_print_length "*", s7_make_integer(s7, MUS_DEFAULT_ARRAY_PRINT_LENGTH)); s7_symbol_set_documentation(s7, mus_array_print_length_symbol, "*mus-array-print-length*: current clm array print length (default is 8)."); s7_symbol_set_access(s7, mus_array_print_length_symbol, s7_make_function(s7, "[acc-mus-array-print-length]", acc_mus_array_print_length, 2, 0, false, "accessor")); #endif Xen_define_typed_procedure(S_radians_to_hz, g_radians_to_hz_w, 1, 0, 0, H_radians_to_hz, pl_dr); Xen_define_typed_procedure(S_hz_to_radians, g_hz_to_radians_w, 1, 0, 0, H_hz_to_radians, pl_dr); Xen_define_typed_procedure(S_radians_to_degrees, g_radians_to_degrees_w, 1, 0, 0, H_radians_to_degrees, pl_dr); Xen_define_typed_procedure(S_degrees_to_radians, g_degrees_to_radians_w, 1, 0, 0, H_degrees_to_radians, pl_dr); Xen_define_typed_procedure(S_db_to_linear, g_db_to_linear_w, 1, 0, 0, H_db_to_linear, pl_dr); Xen_define_typed_procedure(S_linear_to_db, g_linear_to_db_w, 1, 0, 0, H_linear_to_db, pl_dr); Xen_define_typed_procedure(S_even_weight, g_even_weight_w, 1, 0, 0, H_even_weight, pl_dr); Xen_define_typed_procedure(S_odd_weight, g_odd_weight_w, 1, 0, 0, H_odd_weight, pl_dr); Xen_define_typed_procedure(S_even_multiple, g_even_multiple_w, 2, 0, 0, H_even_multiple, pl_dr); Xen_define_typed_procedure(S_odd_multiple, g_odd_multiple_w, 2, 0, 0, H_odd_multiple, pl_dr); Xen_define_typed_procedure(S_seconds_to_samples, g_seconds_to_samples_w, 1, 0, 0, H_seconds_to_samples, pl_ir); Xen_define_typed_procedure(S_samples_to_seconds, g_samples_to_seconds_w, 1, 0, 0, H_samples_to_seconds, pl_dr); Xen_define_typed_procedure(S_ring_modulate, g_ring_modulate_w, 2, 0, 0, H_ring_modulate, pl_dr); Xen_define_typed_procedure(S_amplitude_modulate, g_amplitude_modulate_w, 3, 0, 0, H_amplitude_modulate, pl_dr); Xen_define_typed_procedure(S_contrast_enhancement, g_contrast_enhancement_w, 1, 1, 0, H_contrast_enhancement, pl_dr); Xen_define_typed_procedure(S_dot_product, g_dot_product_w, 2, 1, 0, H_dot_product, pl_dffi); #if HAVE_COMPLEX_TRIG && HAVE_COMPLEX_NUMBERS && (!HAVE_RUBY) Xen_define_typed_procedure(S_edot_product, g_edot_product_w, 2, 0, 0, H_edot_product, NULL); #endif Xen_define_typed_procedure(S_polynomial, g_polynomial_w, 2, 0, 0, H_polynomial, pl_dfri); Xen_define_typed_procedure(S_make_fft_window, g_make_fft_window_w, 2, 2, 0, H_make_fft_window, pl_fiir); Xen_define_typed_procedure(S_mus_fft, g_mus_fft_w, 2, 2, 0, H_mus_fft, pl_fffi); Xen_define_typed_procedure(S_spectrum, g_spectrum_w, 3, 1, 0, H_mus_spectrum, pl_ffftii); Xen_define_typed_procedure(S_autocorrelate, g_autocorrelate_w, 1, 0, 0, H_autocorrelate, pl_ff); Xen_define_typed_procedure(S_correlate, g_correlate_w, 2, 0, 0, H_correlate, pl_ff); Xen_define_typed_procedure(S_convolution, g_convolution_w, 2, 1, 0, H_mus_convolution, pl_fffi); Xen_define_typed_procedure(S_rectangular_to_polar, g_rectangular_to_polar_w, 2, 0, 0, H_rectangular_to_polar, pl_ff); Xen_define_typed_procedure(S_rectangular_to_magnitudes, g_rectangular_to_magnitudes_w, 2, 0, 0, H_rectangular_to_magnitudes, pl_ff); Xen_define_typed_procedure(S_polar_to_rectangular, g_polar_to_rectangular_w, 2, 0, 0, H_polar_to_rectangular, pl_ff); Xen_define_typed_procedure(S_array_interp, g_array_interp_w, 2, 1, 0, H_array_interp, pl_dfri); Xen_define_typed_procedure(S_mus_interpolate, g_mus_interpolate_w, 3, 2, 0, H_mus_interpolate, pl_dirfir); Xen_define_typed_procedure(S_mus_frandom, g_mus_frandom_w, 1, 0, 0, "random reals", pl_dr); Xen_define_typed_procedure(S_mus_irandom, g_mus_irandom_w, 1, 0, 0, "random integers", pl_i); Xen_define_constant(S_rectangular_window, MUS_RECTANGULAR_WINDOW, "The un-window, so to speak"); Xen_define_constant(S_hann_window, MUS_HANN_WINDOW, "A simple raised cosine window"); Xen_define_constant(S_welch_window, MUS_WELCH_WINDOW, "A triangular window squared"); Xen_define_constant(S_parzen_window, MUS_PARZEN_WINDOW, "A triangular window"); Xen_define_constant(S_bartlett_window, MUS_BARTLETT_WINDOW, "A triangular window"); Xen_define_constant(S_bartlett_hann_window, MUS_BARTLETT_HANN_WINDOW, "A combination of the bartlett and hann windows"); Xen_define_constant(S_bohman_window, MUS_BOHMAN_WINDOW, "A weighted cosine window"); Xen_define_constant(S_flat_top_window, MUS_FLAT_TOP_WINDOW, "A sum of cosines window"); Xen_define_constant(S_hamming_window, MUS_HAMMING_WINDOW, "A raised cosine"); Xen_define_constant(S_blackman2_window, MUS_BLACKMAN2_WINDOW, "second order cosine window"); Xen_define_constant(S_blackman3_window, MUS_BLACKMAN3_WINDOW, "third order cosine window"); Xen_define_constant(S_blackman4_window, MUS_BLACKMAN4_WINDOW, "4th order cosine window"); Xen_define_constant(S_blackman5_window, MUS_BLACKMAN5_WINDOW, "5th order cosine window"); Xen_define_constant(S_blackman6_window, MUS_BLACKMAN6_WINDOW, "6th order cosine window"); Xen_define_constant(S_blackman7_window, MUS_BLACKMAN7_WINDOW, "7th order cosine window"); Xen_define_constant(S_blackman8_window, MUS_BLACKMAN8_WINDOW, "8th order cosine window"); Xen_define_constant(S_blackman9_window, MUS_BLACKMAN9_WINDOW, "9th order cosine window"); Xen_define_constant(S_blackman10_window, MUS_BLACKMAN10_WINDOW, "10th order cosine window"); Xen_define_constant(S_exponential_window, MUS_EXPONENTIAL_WINDOW, "An inverted triangle from exp"); Xen_define_constant(S_riemann_window, MUS_RIEMANN_WINDOW, "sinc-based window"); Xen_define_constant(S_kaiser_window, MUS_KAISER_WINDOW, "Bessel I0 based window"); Xen_define_constant(S_cauchy_window, MUS_CAUCHY_WINDOW, "window based on 1/(1+sqr(angle)"); Xen_define_constant(S_poisson_window, MUS_POISSON_WINDOW, "window based on exp(-angle)"); Xen_define_constant(S_gaussian_window, MUS_GAUSSIAN_WINDOW, "window based on exp(-sqr(angle))"); Xen_define_constant(S_tukey_window, MUS_TUKEY_WINDOW, "window based on truncated cosine"); Xen_define_constant(S_dolph_chebyshev_window, MUS_DOLPH_CHEBYSHEV_WINDOW, "window from inverse fft (using Chebyshev Tn)"); Xen_define_constant(S_connes_window, MUS_CONNES_WINDOW, "triangle window squared twice"); Xen_define_constant(S_hann_poisson_window, MUS_HANN_POISSON_WINDOW, "poisson window * hann window"); Xen_define_constant(S_samaraki_window, MUS_SAMARAKI_WINDOW, "window from inverse fft (using Chebyshev Un)"); Xen_define_constant(S_ultraspherical_window, MUS_ULTRASPHERICAL_WINDOW, "window from inverse fft (using Ultraspherical Cn)"); Xen_define_constant(S_rv2_window, MUS_RV2_WINDOW, "Rife-Vincent second order window (Hann extension)"); Xen_define_constant(S_rv3_window, MUS_RV3_WINDOW, "Rife-Vincent third order window (Hann extension)"); Xen_define_constant(S_rv4_window, MUS_RV4_WINDOW, "Rife-Vincent 4th order window (Hann extension)"); Xen_define_constant(S_mlt_sine_window, MUS_MLT_SINE_WINDOW, "modulated lapped transform sine window"); Xen_define_constant(S_papoulis_window, MUS_PAPOULIS_WINDOW, "papoulise window"); Xen_define_constant(S_dpss_window, MUS_DPSS_WINDOW, "proplate spheroidal (slepian) window"); Xen_define_constant(S_sinc_window, MUS_SINC_WINDOW, "sinc (Lanczos) window"); Xen_define_constant(S_mus_interp_linear, MUS_INTERP_LINEAR, "locsig/delay linear interpolation"); Xen_define_constant(S_mus_interp_sinusoidal, MUS_INTERP_SINUSOIDAL, "locsig sinusoidal interpolation"); Xen_define_constant(S_mus_interp_all_pass, MUS_INTERP_ALL_PASS, "delay interpolation"); Xen_define_constant(S_mus_interp_lagrange, MUS_INTERP_LAGRANGE, "second order lagrange interpolation"); Xen_define_constant(S_mus_interp_hermite, MUS_INTERP_HERMITE, "third order hermite interpolation"); Xen_define_constant(S_mus_interp_none, MUS_INTERP_NONE, "no interpolation -- step func"); Xen_define_constant(S_mus_interp_bezier, MUS_INTERP_BEZIER, "bezier interpolation"); Xen_define_constant(S_mus_chebyshev_first_kind, MUS_CHEBYSHEV_FIRST_KIND, "Chebyshev polynomial of first kind, for " S_partials_to_polynomial); Xen_define_constant(S_mus_chebyshev_second_kind, MUS_CHEBYSHEV_SECOND_KIND, "Chebyshev polynomial of second kind, for " S_partials_to_polynomial); Xen_define_constant(S_mus_chebyshev_both_kinds, MUS_CHEBYSHEV_BOTH_KINDS, "use both Chebyshev polynomials in polywave"); Xen_define_typed_procedure(S_mus_describe, g_mus_describe_w, 1, 0, 0, H_mus_describe, pl_sc); Xen_define_typed_procedure(S_mus_file_name, g_mus_file_name_w, 1, 0, 0, H_mus_file_name, pl_sc); Xen_define_typed_procedure(S_mus_reset, g_mus_reset_w, 1, 0, 0, H_mus_reset, pl_tc); Xen_define_typed_procedure(S_mus_copy, g_mus_copy_w, 1, 0, 0, H_mus_copy, pl_cc); Xen_define_procedure(S_mus_run, g_mus_run_w, 1, 2, 0, H_mus_run); Xen_define_typed_procedure(S_mus_name, g_mus_name_w, 1, 0, 0, H_mus_name, pl_sc); Xen_define_typed_dilambda(S_mus_phase, g_mus_phase_w, H_mus_phase, S_set S_mus_phase, g_mus_set_phase_w, 1, 0, 2, 0, pl_dc, pl_dcr); Xen_define_typed_dilambda(S_mus_scaler, g_mus_scaler_w, H_mus_scaler, S_set S_mus_scaler, g_mus_set_scaler_w, 1, 0, 2, 0, pl_dc, pl_dcr); Xen_define_typed_dilambda(S_mus_width, g_mus_width_w, H_mus_width, S_set S_mus_width, g_mus_set_width_w, 1, 0, 2, 0, pl_ic, pl_ici); Xen_define_typed_dilambda(S_mus_frequency, g_mus_frequency_w, H_mus_frequency, S_set S_mus_frequency, g_mus_set_frequency_w, 1, 0, 2, 0, pl_dc, pl_dcr); Xen_define_typed_dilambda(S_mus_length, g_mus_length_w, H_mus_length, S_set S_mus_length, g_mus_set_length_w, 1, 0, 2, 0, pl_ic, pl_ici); Xen_define_typed_dilambda(S_mus_data, g_mus_data_w, H_mus_data, S_set S_mus_data, g_mus_set_data_w, 1, 0, 2, 0, pl_fc, pl_fcf); Xen_define_typed_dilambda(S_mus_xcoeff, g_mus_xcoeff_w, H_mus_xcoeff, S_set S_mus_xcoeff, g_mus_set_xcoeff_w, 2, 0, 3, 0, pl_dci, pl_dcir); Xen_define_typed_dilambda(S_mus_ycoeff, g_mus_ycoeff_w, H_mus_ycoeff, S_set S_mus_ycoeff, g_mus_set_ycoeff_w, 2, 0, 3, 0, pl_dci, pl_dcir); Xen_define_typed_dilambda(S_mus_offset, g_mus_offset_w, H_mus_offset, S_set S_mus_offset, g_mus_set_offset_w, 1, 0, 2, 0, pl_dc, pl_dcr); Xen_define_typed_procedure(S_mus_xcoeffs, g_mus_xcoeffs_w, 1, 0, 0, H_mus_xcoeffs, pl_fc); Xen_define_typed_procedure(S_mus_ycoeffs, g_mus_ycoeffs_w, 1, 0, 0, H_mus_ycoeffs, pl_fc); Xen_define_typed_procedure(S_is_oscil, g_is_oscil_w, 1, 0, 0, H_is_oscil, pl_bt); Xen_define_typed_procedure(S_oscil, g_oscil_w, 1, 2, 0, H_oscil, Q_oscil); Xen_define_typed_procedure(S_is_oscil_bank, g_is_oscil_bank_w, 1, 0, 0, H_is_oscil_bank, pl_bt); Xen_define_typed_procedure(S_oscil_bank, g_oscil_bank_w, 1, 0, 0, H_oscil_bank, pl_dc); Xen_define_procedure(S_mus_apply, g_mus_apply_w, 0, 0, 1, H_mus_apply); Xen_define_typed_procedure(S_make_delay, g_make_delay_w, 0, 0, 1, H_make_delay, pcl_ct); Xen_define_typed_procedure(S_make_comb, g_make_comb_w, 0, 0, 1, H_make_comb, pcl_ct); Xen_define_typed_procedure(S_make_filtered_comb, g_make_filtered_comb_w, 0, 0, 1, H_make_filtered_comb, pcl_ct); Xen_define_typed_procedure(S_make_notch, g_make_notch_w, 0, 0, 1, H_make_notch, pcl_ct); Xen_define_typed_procedure(S_make_all_pass, g_make_all_pass_w, 0, 0, 1, H_make_all_pass, pcl_ct); Xen_define_typed_procedure(S_make_moving_average, g_make_moving_average_w, 0, 0, 1, H_make_moving_average, pcl_ct); Xen_define_typed_procedure(S_make_moving_max, g_make_moving_max_w, 0, 0, 1, H_make_moving_max, pcl_ct); Xen_define_typed_procedure(S_make_moving_norm, g_make_moving_norm_w, 0, 0, 1, H_make_moving_norm, pcl_ct); Xen_define_typed_procedure(S_delay, g_delay_w, 1, 2, 0, H_delay, pl_dcr); Xen_define_typed_procedure(S_delay_tick, g_delay_tick_w, 1, 1, 0, H_delay_tick, pl_dcr); Xen_define_typed_procedure(S_tap, g_tap_w, 1, 1, 0, H_tap, pl_dcr); Xen_define_typed_procedure(S_notch, g_notch_w, 1, 2, 0, H_notch, pl_dcr); Xen_define_typed_procedure(S_comb, g_comb_w, 1, 2, 0, H_comb, pl_dcr); Xen_define_typed_procedure(S_filtered_comb, g_filtered_comb_w, 1, 2, 0, H_filtered_comb, pl_dcr); Xen_define_typed_procedure(S_all_pass, g_all_pass_w, 1, 2, 0, H_all_pass, pl_dcr); Xen_define_typed_procedure(S_moving_average, g_moving_average_w, 1, 1, 0, H_moving_average, pl_dcr); Xen_define_typed_procedure(S_moving_max, g_moving_max_w, 1, 1, 0, H_moving_max, pl_dcr); Xen_define_typed_procedure(S_moving_norm, g_moving_norm_w, 1, 1, 0, H_moving_norm, pl_dcr); Xen_define_typed_procedure(S_is_tap, g_is_tap_w, 1, 0, 0, H_is_tap, pl_bt); Xen_define_typed_procedure(S_is_delay, g_is_delay_w, 1, 0, 0, H_is_delay, pl_bt); Xen_define_typed_procedure(S_is_notch, g_is_notch_w, 1, 0, 0, H_is_notch, pl_bt); Xen_define_typed_procedure(S_is_comb, g_is_comb_w, 1, 0, 0, H_is_comb, pl_bt); Xen_define_typed_procedure(S_is_filtered_comb, g_is_filtered_comb_w, 1, 0, 0, H_is_filtered_comb, pl_bt); Xen_define_typed_procedure(S_is_all_pass, g_is_all_pass_w, 1, 0, 0, H_is_all_pass, pl_bt); Xen_define_typed_procedure(S_is_moving_average, g_is_moving_average_w, 1, 0, 0, H_is_moving_average, pl_bt); Xen_define_typed_procedure(S_is_moving_max, g_is_moving_max_w, 1, 0, 0, H_is_moving_max, pl_bt); Xen_define_typed_procedure(S_is_moving_norm, g_is_moving_norm_w, 1, 0, 0, H_is_moving_norm, pl_bt); Xen_define_typed_procedure(S_comb_bank, g_comb_bank_w, 1, 1, 0, H_comb_bank, pl_dcr); Xen_define_typed_procedure(S_is_comb_bank, g_is_comb_bank_w, 1, 0, 0, H_is_comb_bank, pl_bt); Xen_define_typed_procedure(S_make_comb_bank, g_make_comb_bank_w, 1, 0, 0, H_make_comb_bank, pcl_ct); Xen_define_typed_procedure(S_filtered_comb_bank, g_filtered_comb_bank_w, 1, 1, 0, H_filtered_comb_bank, pl_dcr); Xen_define_typed_procedure(S_is_filtered_comb_bank, g_is_filtered_comb_bank_w, 1, 0, 0, H_is_filtered_comb_bank, pl_bt); Xen_define_typed_procedure(S_make_filtered_comb_bank, g_make_filtered_comb_bank_w, 1, 0, 0, H_make_filtered_comb_bank, pcl_ct); Xen_define_typed_procedure(S_all_pass_bank, g_all_pass_bank_w, 1, 1, 0, H_all_pass_bank, pl_dcr); Xen_define_typed_procedure(S_is_all_pass_bank, g_is_all_pass_bank_w, 1, 0, 0, H_is_all_pass_bank, pl_bt); Xen_define_typed_procedure(S_make_all_pass_bank, g_make_all_pass_bank_w, 1, 0, 0, H_make_all_pass_bank, pcl_ct); Xen_define_typed_procedure(S_pink_noise, g_pink_noise_w, 1, 0, 0, H_pink_noise, pl_dv); Xen_define_typed_procedure(S_out_bank, g_out_bank_w, 3, 0, 0, H_out_bank, pl_dvir); Xen_define_typed_dilambda(S_mus_feedback, g_mus_feedback_w, H_mus_feedback, S_set S_mus_feedback, g_mus_set_feedback_w, 1, 0, 2, 0, pl_dc, pl_dcr); Xen_define_typed_dilambda(S_mus_feedforward, g_mus_feedforward_w, H_mus_feedforward, S_set S_mus_feedforward, g_mus_set_feedforward_w, 1, 0, 2, 0, pl_dc, pl_dcr); Xen_define_typed_procedure(S_make_rand, g_make_rand_w, 0, 0, 1, H_make_rand, pcl_ct); Xen_define_typed_procedure(S_make_rand_interp, g_make_rand_interp_w, 0, 0, 1, H_make_rand_interp, pcl_ct); #if HAVE_RUBY rb_define_alias(rb_mKernel, "kernel_rand", "rand"); #endif Xen_define_typed_procedure(S_rand, g_rand_w, 1, 1, 0, H_rand, pl_dcr); Xen_define_typed_procedure(S_rand_interp, g_rand_interp_w, 1, 1, 0, H_rand_interp, pl_dcr); Xen_define_typed_procedure(S_is_rand, g_is_rand_w, 1, 0, 0, H_is_rand, pl_bt); Xen_define_typed_procedure(S_is_rand_interp, g_is_rand_interp_w, 1, 0, 0, H_is_rand_interp, pl_bt); Xen_define_typed_procedure(S_mus_random, g_mus_random_w, 1, 0, 0, H_mus_random, pl_dr); Xen_define_typed_dilambda(S_mus_rand_seed, g_mus_rand_seed_w, H_mus_rand_seed, S_set S_mus_rand_seed, g_mus_set_rand_seed_w, 0, 0, 1, 0, pl_i, pl_i); Xen_define_typed_procedure(S_ncos, g_ncos_w, 1, 1, 0, H_ncos, pl_dcr); Xen_define_typed_procedure(S_is_ncos, g_is_ncos_w, 1, 0, 0, H_is_ncos, pl_bt); Xen_define_typed_procedure(S_nsin, g_nsin_w, 1, 1, 0, H_nsin, pl_dcr); Xen_define_typed_procedure(S_is_nsin, g_is_nsin_w, 1, 0, 0, H_is_nsin, pl_bt); Xen_define_typed_procedure(S_is_table_lookup, g_is_table_lookup_w, 1, 0, 0, H_is_table_lookup, pl_bt); Xen_define_typed_procedure(S_make_table_lookup, g_make_table_lookup_w, 0, 0, 1, H_make_table_lookup, pcl_ct); Xen_define_typed_procedure(S_table_lookup, g_table_lookup_w, 1, 1, 0, H_table_lookup, pl_dcr); Xen_define_typed_procedure(S_partials_to_wave, g_partials_to_wave_w, 1, 2, 0, H_partials_to_wave, pl_fttb); Xen_define_typed_procedure(S_phase_partials_to_wave, g_phase_partials_to_wave_w, 1, 2, 0, H_phase_partials_to_wave, pl_fttb); Xen_define_typed_procedure(S_make_sawtooth_wave, g_make_sawtooth_wave_w, 0, 6, 0, H_make_sawtooth_wave, pcl_ct); Xen_define_typed_procedure(S_sawtooth_wave, g_sawtooth_wave_w, 1, 1, 0, H_sawtooth_wave, pl_dcr); Xen_define_typed_procedure(S_is_sawtooth_wave, g_is_sawtooth_wave_w, 1, 0, 0, H_is_sawtooth_wave, pl_bt); Xen_define_typed_procedure(S_make_triangle_wave, g_make_triangle_wave_w, 0, 6, 0, H_make_triangle_wave, pcl_ct); Xen_define_typed_procedure(S_triangle_wave, g_triangle_wave_w, 1, 1, 0, H_triangle_wave, pl_dcr); Xen_define_typed_procedure(S_is_triangle_wave, g_is_triangle_wave_w, 1, 0, 0, H_is_triangle_wave, pl_bt); Xen_define_typed_procedure(S_make_square_wave, g_make_square_wave_w, 0, 6, 0, H_make_square_wave, pcl_ct); Xen_define_typed_procedure(S_square_wave, g_square_wave_w, 1, 1, 0, H_square_wave, pl_dcr); Xen_define_typed_procedure(S_is_square_wave, g_is_square_wave_w, 1, 0, 0, H_is_square_wave, pl_bt); Xen_define_typed_procedure(S_make_pulse_train, g_make_pulse_train_w, 0, 6, 0, H_make_pulse_train, pcl_ct); Xen_define_typed_procedure(S_pulse_train, g_pulse_train_w, 1, 1, 0, H_pulse_train, pl_dcr); Xen_define_typed_procedure(S_is_pulse_train, g_is_pulse_train_w, 1, 0, 0, H_is_pulse_train, pl_bt); Xen_define_typed_procedure(S_make_pulsed_env, g_make_pulsed_env_w, 3, 0, 0, H_make_pulsed_env, pcl_ct); Xen_define_typed_procedure(S_pulsed_env, g_pulsed_env_w, 1, 1, 0, H_pulsed_env, pl_dcr); Xen_define_typed_procedure(S_is_pulsed_env, g_is_pulsed_env_w, 1, 0, 0, H_is_pulsed_env, pl_bt); Xen_define_typed_procedure(S_asymmetric_fm, g_asymmetric_fm_w, 1, 2, 0, H_asymmetric_fm, pl_dcr); Xen_define_typed_procedure(S_is_asymmetric_fm, g_is_asymmetric_fm_w, 1, 0, 0, H_is_asymmetric_fm, pl_bt); Xen_define_typed_procedure(S_make_one_zero, g_make_one_zero_w, 0, 4, 0, H_make_one_zero, pcl_ct); Xen_define_typed_procedure(S_one_zero, g_one_zero_w, 1, 1, 0, H_one_zero, pl_dcr); Xen_define_typed_procedure(S_is_one_zero, g_is_one_zero_w, 1, 0, 0, H_is_one_zero, pl_bt); Xen_define_typed_procedure(S_make_one_pole, g_make_one_pole_w, 0, 4, 0, H_make_one_pole, pcl_ct); Xen_define_typed_procedure(S_one_pole, g_one_pole_w, 1, 1, 0, H_one_pole, pl_dcr); Xen_define_typed_procedure(S_is_one_pole, g_is_one_pole_w, 1, 0, 0, H_is_one_pole, pl_bt); Xen_define_typed_procedure(S_make_two_zero, g_make_two_zero_w, 0, 6, 0, H_make_two_zero, pcl_ct); Xen_define_typed_procedure(S_two_zero, g_two_zero_w, 1, 1, 0, H_two_zero, pl_dcr); Xen_define_typed_procedure(S_is_two_zero, g_is_two_zero_w, 1, 0, 0, H_is_two_zero, pl_bt); Xen_define_typed_procedure(S_make_two_pole, g_make_two_pole_w, 0, 6, 0, H_make_two_pole, pcl_ct); Xen_define_typed_procedure(S_two_pole, g_two_pole_w, 1, 1, 0, H_two_pole, pl_dcr); Xen_define_typed_procedure(S_is_two_pole, g_is_two_pole_w, 1, 0, 0, H_is_two_pole, pl_bt); Xen_define_typed_procedure(S_make_wave_train, g_make_wave_train_w, 0, 0, 1, H_make_wave_train, pcl_ct); Xen_define_typed_procedure(S_wave_train, g_wave_train_w, 1, 1, 0, H_wave_train, pl_dcr); Xen_define_typed_procedure(S_is_wave_train, g_is_wave_train_w, 1, 0, 0, H_is_wave_train, pl_bt); Xen_define_typed_procedure(S_is_formant, g_is_formant_w, 1, 0, 0, H_is_formant, pl_bt); Xen_define_typed_procedure(S_make_formant, g_make_formant_w, 0, 4, 0, H_make_formant, pcl_ct); Xen_define_typed_procedure(S_formant, g_formant_w, 1, 2, 0, H_formant, pl_dcr); Xen_define_typed_procedure(S_formant_bank, g_formant_bank_w, 1, 1, 0, H_formant_bank, pl_dcr); Xen_define_typed_procedure(S_is_formant_bank, g_is_formant_bank_w, 1, 0, 0, H_is_formant_bank, pl_bt); Xen_define_typed_procedure(S_make_formant_bank, g_make_formant_bank_w, 1, 1, 0, H_make_formant_bank, pcl_zt); Xen_define_typed_procedure(S_is_firmant, g_is_firmant_w, 1, 0, 0, H_is_firmant, pl_bt); Xen_define_typed_procedure(S_make_firmant, g_make_firmant_w, 0, 4, 0, H_make_firmant, pcl_ct); Xen_define_typed_procedure(S_firmant, g_firmant_w, 1, 2, 0, H_firmant, pl_dcr); Xen_define_typed_procedure(S_is_one_pole_all_pass, g_is_one_pole_all_pass_w, 1, 0, 0, H_is_one_pole_all_pass, pl_bt); Xen_define_typed_procedure(S_make_one_pole_all_pass, g_make_one_pole_all_pass_w, 2, 0, 0, H_make_one_pole_all_pass, pcl_ct); Xen_define_typed_procedure(S_one_pole_all_pass, g_one_pole_all_pass_w, 1, 1, 0, H_one_pole_all_pass, pl_dcr); Xen_define_typed_procedure(S_mus_set_formant_frequency, g_set_formant_frequency_w, 2, 0, 0, H_mus_set_formant_frequency, pl_rcr); Xen_define_typed_procedure(S_mus_set_formant_radius_and_frequency, g_set_formant_radius_and_frequency_w, 3, 0, 0, H_mus_set_formant_radius_and_frequency, pl_rcrr); Xen_define_typed_procedure(S_make_polyshape, g_make_polyshape_w, 0, 0, 1, H_make_polyshape, pcl_ct); Xen_define_typed_procedure(S_polyshape, g_polyshape_w, 1, 2, 0, H_polyshape, pl_dcr); Xen_define_typed_procedure(S_is_polyshape, g_is_polyshape_w, 1, 0, 0, H_is_polyshape, pl_bt); Xen_define_typed_procedure(S_partials_to_polynomial, g_partials_to_polynomial_w, 1, 1, 0, H_partials_to_polynomial, pl_fti); Xen_define_typed_procedure(S_normalize_partials, g_normalize_partials_w, 1, 0, 0, H_normalize_partials, pl_tt); Xen_define_typed_procedure(S_mus_chebyshev_t_sum, g_chebyshev_t_sum_w, 2, 0, 0, H_chebyshev_t_sum, pl_drf); Xen_define_typed_procedure(S_mus_chebyshev_u_sum, g_chebyshev_u_sum_w, 2, 0, 0, H_chebyshev_u_sum, pl_drf); Xen_define_typed_procedure(S_mus_chebyshev_tu_sum, g_chebyshev_tu_sum_w, 3, 0, 0, H_chebyshev_tu_sum, pl_drf); Xen_define_typed_procedure(S_make_polywave, g_make_polywave_w, 0, 0, 1, H_make_polywave, pcl_ct); Xen_define_typed_procedure(S_polywave, g_polywave_w, 1, 1, 0, H_polywave, pl_dcr); Xen_define_typed_procedure(S_is_polywave, g_is_polywave_w, 1, 0, 0, H_is_polywave, pl_bt); Xen_define_typed_procedure(S_make_nrxysin, g_make_nrxysin_w, 0, 0, 1, H_make_nrxysin, pcl_ct); Xen_define_typed_procedure(S_nrxysin, g_nrxysin_w, 1, 1, 0, H_nrxysin, pl_dcr); Xen_define_typed_procedure(S_is_nrxysin, g_is_nrxysin_w, 1, 0, 0, H_is_nrxysin, pl_bt); Xen_define_typed_procedure(S_make_nrxycos, g_make_nrxycos_w, 0, 0, 1, H_make_nrxycos, pcl_ct); Xen_define_typed_procedure(S_nrxycos, g_nrxycos_w, 1, 1, 0, H_nrxycos, pl_dcr); Xen_define_typed_procedure(S_is_nrxycos, g_is_nrxycos_w, 1, 0, 0, H_is_nrxycos, pl_bt); Xen_define_typed_procedure(S_make_rxyksin, g_make_rxyksin_w, 0, 0, 1, H_make_rxyksin, pl_ct); Xen_define_typed_procedure(S_rxyksin, g_rxyksin_w, 1, 1, 0, H_rxyksin, pl_dcr); Xen_define_typed_procedure(S_is_rxyksin, g_is_rxyksin_w, 1, 0, 0, H_is_rxyksin, pl_bt); Xen_define_typed_procedure(S_make_rxykcos, g_make_rxykcos_w, 0, 0, 1, H_make_rxykcos, pcl_ct); Xen_define_typed_procedure(S_rxykcos, g_rxykcos_w, 1, 1, 0, H_rxykcos, pl_dcr); Xen_define_typed_procedure(S_is_rxykcos, g_is_rxykcos_w, 1, 0, 0, H_is_rxykcos, pl_bt); Xen_define_typed_procedure(S_make_filter, g_make_filter_w, 0, 6, 0, H_make_filter, pcl_ct); Xen_define_typed_procedure(S_filter, g_filter_w, 1, 1, 0, H_filter, pl_dcr); Xen_define_typed_procedure(S_is_filter, g_is_filter_w, 1, 0, 0, H_is_filter, pl_bt); Xen_define_typed_procedure(S_make_fir_coeffs, g_make_fir_coeffs_w, 2, 0, 0, H_make_fir_coeffs, pl_fif); Xen_define_typed_procedure(S_make_fir_filter, g_make_fir_filter_w, 0, 4, 0, H_make_fir_filter, pcl_ct); Xen_define_typed_procedure(S_fir_filter, g_fir_filter_w, 1, 1, 0, H_fir_filter, pl_dcr); Xen_define_typed_procedure(S_is_fir_filter, g_is_fir_filter_w, 1, 0, 0, H_is_fir_filter, pl_bt); Xen_define_typed_procedure(S_make_iir_filter, g_make_iir_filter_w, 0, 4, 0, H_make_iir_filter, pcl_ct); Xen_define_typed_procedure(S_iir_filter, g_iir_filter_w, 1, 1, 0, H_iir_filter, pl_dcr); Xen_define_typed_procedure(S_is_iir_filter, g_is_iir_filter_w, 1, 0, 0, H_is_iir_filter, pl_bt); Xen_define_typed_procedure(S_mus_order, g_mus_order_w, 1, 0, 0, H_mus_order, pl_ic); Xen_define_typed_procedure(S_mus_type, g_mus_type_w, 1, 0, 0, H_mus_type, pl_ic); Xen_define_typed_procedure(S_is_env, g_is_env_w, 1, 0, 0, H_is_env, pl_bt); Xen_define_typed_procedure(S_env, g_env_w, 1, 0, 0, H_env, pl_dc); Xen_define_typed_procedure(S_make_env, g_make_env_w, 0, 0, 1, H_make_env, pcl_ct); Xen_define_typed_procedure(S_env_interp, g_env_interp_w, 2, 0, 0, H_env_interp, pl_drc); Xen_define_typed_procedure(S_envelope_interp, g_envelope_interp_w, 2, 1, 0, H_envelope_interp, pl_rrpr); Xen_define_typed_procedure(S_env_any, g_env_any_w, 2, 0, 0, H_env_any, pl_dct); Xen_define_typed_procedure(S_is_locsig, g_is_locsig_w, 1, 0, 0, H_is_locsig, pl_bt); Xen_define_typed_procedure(S_locsig, g_locsig_w, 3, 0, 0, H_locsig, pl_rcr); Xen_define_typed_procedure(S_make_locsig, g_make_locsig_w, 0, 0, 1, H_make_locsig, pcl_ct); Xen_define_typed_procedure(S_move_locsig, g_move_locsig_w, 3, 0, 0, H_move_locsig, pl_ccrr); Xen_define_typed_procedure(S_mus_channels, g_mus_channels_w, 1, 0, 0, H_mus_channels, pl_ic); #if HAVE_RUBY Xen_define_procedure(S_locsig_ref, g_locsig_ref_w, 2, 0, 0, H_locsig_ref); Xen_define_procedure(S_locsig_reverb_ref, g_locsig_reverb_ref_w, 2, 0, 0, H_locsig_reverb_ref); #endif Xen_define_typed_procedure(S_locsig_set, g_locsig_set_w, 3, 0, 0, H_locsig_set, pl_rcir); #if HAVE_SCHEME || HAVE_FORTH Xen_define_typed_dilambda(S_locsig_ref, g_locsig_ref_w, H_locsig_ref, S_set S_locsig_ref, g_locsig_set_w, 2, 0, 3, 0, pl_dci, pl_dcir); Xen_define_typed_dilambda(S_locsig_reverb_ref, g_locsig_reverb_ref_w, H_locsig_reverb_ref, S_locsig_reverb_set, g_locsig_reverb_set_w, 2, 0, 3, 0, pl_dci, pl_dcir); #endif Xen_define_typed_procedure(S_locsig_reverb_set, g_locsig_reverb_set_w, 3, 0, 0, H_locsig_reverb_set, pl_rcir); Xen_define_typed_dilambda(S_locsig_type, g_locsig_type_w, H_locsig_type, S_set S_locsig_type, g_set_locsig_type_w, 0, 0, 1, 0, pl_i, pl_i); Xen_define_typed_procedure(S_is_move_sound, g_is_move_sound_w, 1, 0, 0, H_is_move_sound, pl_bt); Xen_define_typed_procedure(S_move_sound, g_move_sound_w, 3, 0, 0, H_move_sound, pl_rcr); Xen_define_typed_procedure(S_make_move_sound, g_make_move_sound_w, 1, 2, 0, H_make_move_sound, pcl_ct); Xen_define_typed_procedure(S_is_file_to_sample, g_is_file_to_sample_w, 1, 0, 0, H_is_file_to_sample, pl_bt); Xen_define_typed_procedure(S_make_file_to_sample, g_make_file_to_sample_w, 1, 1, 0, H_make_file_to_sample, pcl_ct); Xen_define_typed_procedure(S_file_to_sample, g_file_to_sample_w, 2, 1, 0, H_file_to_sample, pl_dci); Xen_define_typed_procedure(S_is_sample_to_file, g_is_sample_to_file_w, 1, 0, 0, H_is_sample_to_file, pl_bt); Xen_define_typed_procedure(S_make_sample_to_file, g_make_sample_to_file_w, 1, 4, 0, H_make_sample_to_file, pcl_ct); Xen_define_typed_procedure(S_continue_sample_to_file, g_continue_sample_to_file_w, 1, 0, 0, H_continue_sample_to_file, pl_cs); Xen_define_typed_procedure(S_sample_to_file, g_sample_to_file_w, 4, 0, 0, H_sample_to_file, pl_rciir); Xen_define_typed_procedure(S_sample_to_file_add, g_sample_to_file_add_w, 2, 0, 0, H_sample_to_file_add, pl_cc); Xen_define_typed_procedure(S_is_file_to_frample, g_is_file_to_frample_w, 1, 0, 0, H_is_file_to_frample, pl_bt); Xen_define_typed_procedure(S_make_file_to_frample, g_make_file_to_frample_w, 1, 1, 0, H_make_file_to_frample, pcl_ct); Xen_define_typed_procedure(S_file_to_frample, g_file_to_frample_w, 2, 1, 0, H_file_to_frample, pl_ccic); Xen_define_typed_procedure(S_continue_frample_to_file, g_continue_frample_to_file_w, 1, 0, 0, H_continue_frample_to_file, pl_cs); Xen_define_typed_procedure(S_is_frample_to_file, g_is_frample_to_file_w, 1, 0, 0, H_is_frample_to_file, pl_bt); Xen_define_typed_procedure(S_frample_to_file, g_frample_to_file_w, 3, 0, 0, H_frample_to_file, pl_fcif); Xen_define_typed_procedure(S_make_frample_to_file, g_make_frample_to_file_w, 1, 4, 0, H_make_frample_to_file, pcl_zt); Xen_define_typed_procedure(S_is_mus_input, g_is_mus_input_w, 1, 0, 0, H_is_mus_input, pl_bt); Xen_define_typed_procedure(S_is_mus_output, g_is_mus_output_w, 1, 0, 0, H_is_mus_output, pl_bt); Xen_define_typed_procedure(S_in_any, g_in_any_w, 3, 0, 0, H_in_any, pl_diit); Xen_define_typed_procedure(S_ina, g_ina_w, 2, 0, 0, H_ina, pl_dit); Xen_define_typed_procedure(S_inb, g_inb_w, 2, 0, 0, H_inb, pl_dit); Xen_define_typed_procedure(S_out_any, g_out_any_w, 3, 1, 0, H_out_any, pl_ririt); Xen_define_typed_procedure(S_outa, g_outa_w, 2, 1, 0, H_outa, pl_rirt); Xen_define_typed_procedure(S_outb, g_outb_w, 2, 1, 0, H_outb, pl_rirt); Xen_define_typed_procedure(S_outc, g_outc_w, 2, 1, 0, H_outc, pl_rirt); Xen_define_typed_procedure(S_outd, g_outd_w, 2, 1, 0, H_outd, pl_rirt); Xen_define_typed_procedure(S_mus_close, g_mus_close_w, 1, 0, 0, H_mus_close, pl_tc); Xen_define_typed_dilambda(S_mus_file_buffer_size, g_mus_file_buffer_size_w, H_mus_file_buffer_size, S_set S_mus_file_buffer_size, g_mus_set_file_buffer_size_w, 0, 0, 1, 0, pl_i, pl_i); Xen_define_typed_procedure(S_is_readin, g_is_readin_w, 1, 0, 0, H_is_readin, pl_bt); Xen_define_typed_procedure(S_readin, g_readin_w, 1, 0, 0, H_readin, pl_dc); Xen_define_typed_procedure(S_make_readin, g_make_readin_w, 0, 0, 1, H_make_readin, pcl_ct); Xen_define_typed_procedure(S_mus_channel, g_mus_channel_w, 1, 0, 0, H_mus_channel, pl_ic); Xen_define_typed_procedure(S_mus_interp_type, g_mus_interp_type_w, 1, 0, 0, H_mus_interp_type, pl_ic); Xen_define_typed_dilambda(S_mus_location, g_mus_location_w, H_mus_location, S_set S_mus_location, g_mus_set_location_w, 1, 0, 2, 0, pl_ic, pl_ici); Xen_define_typed_dilambda(S_mus_increment, g_mus_increment_w, H_mus_increment, S_set S_mus_increment, g_mus_set_increment_w, 1, 0, 2, 0, pl_dc, pl_dcr); Xen_define_typed_procedure(S_is_granulate, g_is_granulate_w, 1, 0, 0, H_is_granulate, pl_bt); Xen_define_typed_procedure(S_granulate, g_granulate_w, 1, 2, 0, H_granulate, pl_dc); Xen_define_typed_procedure(S_make_granulate, g_make_granulate_w, 0, 0, 1, H_make_granulate, pcl_ct); Xen_define_typed_dilambda(S_mus_ramp, g_mus_ramp_w, H_mus_ramp, S_set S_mus_ramp, g_mus_set_ramp_w, 1, 0, 2, 0, pl_dc, pl_dcr); Xen_define_typed_procedure(S_clear_sincs, g_mus_clear_sincs_w, 0, 0, 0, "clears out any sinc tables", NULL); Xen_define_typed_procedure(S_is_src, g_is_src_w, 1, 0, 0, H_is_src, pl_bt); Xen_define_typed_procedure(S_src, g_src_w, 1, 2, 0, H_src, pl_dcr); Xen_define_typed_procedure(S_make_src, g_make_src_w, 0, 6, 0, H_make_src, pcl_ct); Xen_define_typed_procedure(S_is_convolve, g_is_convolve_w, 1, 0, 0, H_is_convolve, pl_bt); Xen_define_typed_procedure(S_convolve, g_convolve_w, 1, 1, 0, H_convolve_gen, pl_dc); Xen_define_typed_procedure(S_make_convolve, g_make_convolve_w, 0, 0, 1, H_make_convolve, pcl_ct); Xen_define_typed_procedure(S_convolve_files, g_convolve_files_w, 2, 2, 0, H_convolve_files, pl_sssrs); Xen_define_typed_procedure(S_is_phase_vocoder, g_is_phase_vocoder_w, 1, 0, 0, H_is_phase_vocoder, pl_bt); Xen_define_typed_procedure(S_phase_vocoder, g_phase_vocoder_w, 1, 4, 0, H_phase_vocoder, pl_dc); Xen_define_typed_procedure(S_make_phase_vocoder, g_make_phase_vocoder_w, 0, 0, 1, H_make_phase_vocoder, pcl_ct); Xen_define_typed_procedure(S_phase_vocoder_amp_increments, g_phase_vocoder_amp_increments_w, 1, 0, 0, H_phase_vocoder_amp_increments, pl_fc); Xen_define_typed_procedure(S_phase_vocoder_amps, g_phase_vocoder_amps_w, 1, 0, 0, H_phase_vocoder_amps, pl_fc); Xen_define_typed_procedure(S_phase_vocoder_freqs, g_phase_vocoder_freqs_w, 1, 0, 0, H_phase_vocoder_freqs, pl_fc); Xen_define_typed_procedure(S_phase_vocoder_phases, g_phase_vocoder_phases_w, 1, 0, 0, H_phase_vocoder_phases, pl_fc); Xen_define_typed_procedure(S_phase_vocoder_phase_increments, g_phase_vocoder_phase_increments_w, 1, 0, 0, H_phase_vocoder_phase_increments, pl_fc); Xen_define_typed_dilambda(S_mus_hop, g_mus_hop_w, H_mus_hop, S_set S_mus_hop, g_mus_set_hop_w, 1, 0, 2, 0, pl_dc, pl_dcr); Xen_define_typed_procedure(S_make_ssb_am, g_make_ssb_am_w, 0, 4, 0, H_make_ssb_am, pcl_ct); Xen_define_typed_procedure(S_ssb_am, g_ssb_am_w, 1, 2, 0, H_ssb_am, pl_dcr); Xen_define_typed_procedure(S_is_ssb_am, g_is_ssb_am_w, 1, 0, 0, H_is_ssb_am, pl_bt); Xen_define_typed_procedure(S_is_mus_generator, g_is_mus_generator_w, 1, 0, 0, H_is_mus_generator, pl_bt); Xen_define_variable(S_output, clm_output, Xen_false); Xen_define_variable(S_reverb, clm_reverb, Xen_false); #if HAVE_SCHEME { s7_pointer clm_output_accessor, clm_reverb_accessor; /* these are globals in s7, so they aren't going to move */ clm_output_slot = s7_slot(s7, clm_output); clm_reverb_slot = s7_slot(s7, clm_reverb); out_any_2 = out_any_2_to_mus_xen; /* these can't be safe functions */ clm_output_accessor = s7_make_function(s7, "(set " S_output ")", g_clm_output_set, 2, 0, false, "called if " S_output " is set"); s7_symbol_set_access(s7, s7_make_symbol(s7, S_output), clm_output_accessor); clm_reverb_accessor = s7_make_function(s7, "(set " S_reverb ")", g_clm_reverb_set, 2, 0, false, "called if " S_reverb " is set"); s7_symbol_set_access(s7, s7_make_symbol(s7, S_reverb), clm_reverb_accessor); } #endif #if HAVE_SCHEME && (!_MSC_VER) Xen_define_typed_procedure(S_get_internal_real_time, g_get_internal_real_time_w, 0, 0, 0, H_get_internal_real_time, NULL); Xen_define_constant(S_internal_time_units_per_second, 1, "units used by " S_get_internal_real_time); #endif #if HAVE_SCHEME Xen_define_typed_procedure(S_piano_noise, g_piano_noise_w, 2, 0, 0, H_piano_noise, pl_dcr); Xen_define_typed_procedure(S_singer_filter, g_singer_filter_w, 6, 0, 0, H_singer_filter, pl_riirfff); Xen_define_typed_procedure(S_singer_nose_filter, g_singer_nose_filter_w, 5, 0, 0, H_singer_nose_filter, pl_rirfff); #endif Xen_define_typed_procedure(S_make_oscil, g_make_oscil_w, 0, 4, 0, H_make_oscil, pcl_ct); Xen_define_typed_procedure(S_make_ncos, g_make_ncos_w, 0, 4, 0, H_make_ncos, pcl_ct); Xen_define_typed_procedure(S_make_oscil_bank, g_make_oscil_bank_w, 2, 2, 0, H_make_oscil_bank, pcl_ct); Xen_define_typed_procedure(S_make_nsin, g_make_nsin_w, 0, 4, 0, H_make_nsin, pcl_ct); Xen_define_typed_procedure(S_make_asymmetric_fm, g_make_asymmetric_fm_w, 0, 8, 0, H_make_asymmetric_fm, pcl_ct); Xen_define_typed_procedure(S_mus_file_mix, g_mus_file_mix_w, 0, 0, 1, H_mus_file_mix, NULL); Xen_define_typed_procedure(S_mus_file_mix_with_envs, g_mus_file_mix_with_envs_w, 0, 0, 1, H_mus_file_mix_with_envs, NULL); /* actually 8 2 0 I think */ Xen_define_typed_procedure(S_frample_to_frample, g_frample_to_frample_w, 5, 0, 0, H_frample_to_frample, pl_fffifi); #if HAVE_SCHEME init_choosers(s7); #endif /* -------- clm-print (see also snd-xen.c) -------- */ #if (!USE_SND) #if HAVE_FORTH Xen_eval_C_string("<'> fth-print alias clm-print ( fmt args -- )"); #endif #if HAVE_RUBY Xen_eval_C_string("def clm_print(str, *args)\n\ $stdout.print format(str, *args)\n\ end"); #endif #endif Xen_provide_feature("clm"); { char *clm_version; clm_version = mus_format("clm%d", MUS_VERSION); Xen_provide_feature(clm_version); free(clm_version); } #if HAVE_SCHEME && (!_MSC_VER) { struct timezone z0; gettimeofday(&overall_start_time, &z0); } #endif } void Init_sndlib(void) { mus_sndlib_xen_initialize(); mus_vct_init(); mus_xen_init(); #if HAVE_SCHEME if (sizeof(mus_float_t) != sizeof(s7_double)) fprintf(stderr, "in s7-clm, s7_double must match mus_float_t. Currently s7_double has %d bytes, but mus_float_t has %d\n", (int)sizeof(s7_double), (int)sizeof(mus_float_t)); #endif } #if HAVE_SCHEME void s7_init_sndlib(s7_scheme *sc) { s7_xen_initialize(sc); Init_sndlib(); } #endif snd-16.1/sndlib-ws.scm0000644000076400007640000004116212616767665012773 0ustar bilbil;;; with-sound for a sndlib-only context (no Snd editor) (provide 'sndlib-ws.scm) (set! *clm-srate* 44100) (define *clm-file-name* "test.snd") (define *clm-channels* 1) (define *clm-sample-type* mus-lfloat) (define *clm-header-type* mus-next) (define *clm-verbose* #f) (define *clm-play* #f) (define *clm-statistics* #f) (define *clm-reverb* #f) (define *clm-reverb-channels* 1) (define *clm-reverb-data* ()) (define *clm-locsig-type* mus-interp-linear) (define *clm-clipped* #t) (define *clm-array-print-length* 12) (define *clm-player* #f) (define *clm-notehook* #f) (define *clm-with-sound-depth* 0) ; for CM, not otherwise used (define *clm-delete-reverb* #f) ; should with-sound clean up reverb stream (set! *clm-file-buffer-size* 65536) (define (times->samples beg dur) "(times->samples beg dur) converts beg and (+ beg dur) to samples, returning both in a list" (list (seconds->samples beg) (seconds->samples (+ beg dur)))) ;;; -------- definstrument -------- ;(define definstrument define*) -- old form 2-Nov-05 (define *definstrument-hook* #f) ; for CM (define-macro (definstrument args . body) (let* ((name (car args)) (targs (cdr args)) (utargs (let ((arg-names ())) (for-each (lambda (a) (if (not (keyword? a)) (if (symbol? a) (set! arg-names (cons a arg-names)) (set! arg-names (cons (car a) arg-names))))) targs) (reverse arg-names)))) `(begin (define* (,name ,@targs) (if *clm-notehook* (*clm-notehook* (symbol->string ',name) ,@utargs)) ,@body) ,@(if *definstrument-hook* (list (*definstrument-hook* name targs)) (list))))) ;;; -------- with-sound -------- (define* (with-sound-helper thunk (output *clm-file-name*) (channels *clm-channels*) (srate *clm-srate*) (sample-type *clm-sample-type*) (header-type *clm-header-type*) (comment #f) (verbose *clm-verbose*) (reverb *clm-reverb*) (revfile "test.rev") (reverb-data *clm-reverb-data*) (reverb-channels *clm-reverb-channels*) (continue-old-file #f) (statistics *clm-statistics*) (scaled-to #f) (scaled-by #f) (play *clm-play*) (clipped 'unset) (notehook *clm-notehook*) ; (with-sound (:notehook (lambda args (display args))) (fm-violin 0 1 440 .1)) (ignore-output #f)) "with-sound-helper is the business portion of the with-sound macro" (let* ((old-srate *clm-srate*) (old-*output* *output*) (old-*reverb* *reverb*) (old-notehook *clm-notehook*) (old-verbose *clm-verbose*) (output-to-file (string? output)) (output-1 (if (and output-to-file (or scaled-to scaled-by)) (string-append output ".temp") output)) ; protect during nesting (reverb-1 revfile) (reverb-to-file (and reverb (string? revfile)))) (if ignore-output (begin (set! output-1 *clm-file-name*) (set! output-to-file (string? output-1)))) (dynamic-wind (lambda () (set! *clm-verbose* verbose) (set! *clm-notehook* notehook) (set! (locsig-type) *clm-locsig-type*) (set! (mus-array-print-length) *clm-array-print-length*) (if (equal? clipped 'unset) (if (and (or scaled-by scaled-to) (member sample-type (list mus-bfloat mus-lfloat mus-bdouble mus-ldouble))) (set! (mus-clipping) #f) (set! (mus-clipping) *clm-clipped*)) (set! (mus-clipping) clipped)) (set! *clm-srate* srate)) (lambda () (if output-to-file (begin (if continue-old-file (begin (set! *output* (continue-sample->file output-1)) (set! *clm-srate* (mus-sound-srate output-1))) (begin (if (file-exists? output-1) (delete-file output-1)) (set! *output* (make-sample->file output-1 channels sample-type header-type comment))))) (begin (if (and (not continue-old-file) (vector? output-1)) (fill! output-1 0.0)) (set! *output* output-1))) (if reverb (if reverb-to-file (begin (if continue-old-file (set! *reverb* (continue-sample->file reverb-1)) (begin (if (file-exists? reverb-1) (delete-file reverb-1)) (set! *reverb* (make-sample->file reverb-1 reverb-channels sample-type header-type))))) (begin (if (and (not continue-old-file) (vector? reverb-1)) (fill! reverb-1 0.0)) (set! *reverb* reverb-1)))) (let ((start (if statistics (get-internal-real-time))) (flush-reverb #f) (cycles 0) (revmax #f)) (catch 'mus-error thunk (lambda args (format #t ";~%with-sound mus-error: ~{~A~^ ~}~%" (cdr args)) (set! flush-reverb #t))) (if (and reverb (not flush-reverb)) ; i.e. not interrupted by error and trying to jump out (begin (if reverb-to-file (mus-close *reverb*)) (if statistics (if reverb-to-file (set! revmax (cadr (mus-sound-maxamp reverb-1))) (if (float-vector? reverb-1) (set! revmax (float-vector-peak reverb-1))))) (if reverb-to-file (set! *reverb* (make-file->sample reverb-1))) (apply reverb reverb-data) ; here is the reverb call(!) (if reverb-to-file (mus-close *reverb*)) )) (if output-to-file (mus-close *output*)) (if statistics (begin (set! cycles (- (get-internal-real-time) start)) (format #t "~%;~A:~% maxamp~A:~{ ~,4F~}~%~A compute time: ~,3F~%" (if output-to-file (if (or scaled-to scaled-by) (substring output-1 0 (- (length output-1) 5)) output-1) (if (vector? output-1) "vector" "flush")) (if (or scaled-to scaled-by) " (before scaling)" "") (if output-to-file (let ((lst (mus-sound-maxamp output-1))) (do ((i 0 (+ i 2))) ((>= i (length lst))) (list-set! lst i (/ (list-ref lst i) *clm-srate*))) lst) (if (float-vector? output-1) (list (float-vector-peak output-1)) '(0.0))) (if revmax (format #f " rev max: ~,4F~%" revmax) "") cycles))) (if (or scaled-to scaled-by) (if output-to-file (let ((scaling (or scaled-by (let* ((mx-lst (mus-sound-maxamp output-1)) (mx (if (not (null? mx-lst)) (cadr mx-lst) 1.0))) (do ((i 1 (+ i 2))) ((>= i (length mx-lst)) (/ scaled-to mx)) (set! mx (max mx (list-ref mx-lst i))))))) (out-file (substring output-1 0 (- (length output-1) 5)))) (let ((g (make-sample->file out-file channels sample-type header-type #f))) (mus-close g)) (mus-file-mix out-file output-1 0 (mus-sound-framples output-1) 0 (let ((mx (make-float-vector (list channels channels) 0.0))) (do ((i 0 (+ i 1))) ((= i channels) mx) (set! (mx i i) scaling)))) (delete-file output-1) (set! output-1 (substring output-1 0 (- (length output-1) 5)))) (if (float-vector? output-1) (if scaled-to (let ((pk (float-vector-peak output-1))) (if (> pk 0.0) (float-vector-scale! output-1 (/ scaled-to pk)))) (float-vector-scale! output-1 scaled-by))))) (if (and *clm-player* play output-to-file) (*clm-player* output-1))) output-1) (lambda () (set! *clm-verbose* old-verbose) (set! *clm-notehook* old-notehook) (if *reverb* (begin (mus-close *reverb*) (set! *reverb* old-*reverb*))) (if *output* (begin (if (mus-output? *output*) (mus-close *output*)) (set! *output* old-*output*))) (set! *clm-srate* old-srate))))) (define-macro (with-sound args . body) `(with-sound-helper (lambda () ,@body) ,@args)) ;;; -------- with-temp-sound -------- (define-macro (with-temp-sound args . body) `(let ((old-file-name *clm-file-name*)) ;; with-sound but using tempnam for output (can be over-ridden by explicit :output) (dynamic-wind (lambda () (set! *clm-file-name* (tmpnam))) (lambda () (with-sound-helper (lambda () ,@body) ,@args)) ; dynamic-wind returns this as its result (lambda () (set! *clm-file-name* old-file-name))))) ;;; -------- clm-load -------- (define (clm-load file . args) "(clm-load file . args) loads 'file' in the context of with-sound" (apply with-sound-helper (lambda () (load file)) args)) ;;; -------- sound-let -------- ;;; ;;; (with-sound () (sound-let ((a () (fm-violin 0 .1 440 .1))) (mus-file-mix "test.snd" a))) (define-macro (sound-let snds . body) `(let ((temp-files ())) (begin (let ((val (let ,(map (lambda (arg) (if (> (length arg) 2) `(,(car arg) (with-temp-sound ,(cadr arg) ,@(cddr arg))) arg)) snds) ,@body))) ; sound-let body (for-each (lambda (file) ; clean up all local temps (if (and (string? file) ; is it a file? (file-exists? file)) (delete-file file))) temp-files) val)))) ; return body result ;;; -------- Common Music -------- (define* (init-with-sound (srate *clm-srate*) (output *clm-file-name*) (channels *clm-channels*) (header-type *clm-header-type*) data-format (sample-type *clm-sample-type*) (comment #f) ;(verbose *clm-verbose*) ; why is this commented out? (reverb *clm-reverb*) (revfile "test.rev") (reverb-data *clm-reverb-data*) (reverb-channels *clm-reverb-channels*) (continue-old-file #f) (statistics *clm-statistics*) (scaled-to #f) (play *clm-play*) (scaled-by #f)) "(init-with-sound . args) is the first half of with-sound; it sets up the CLM output choices, reverb, etc. Use \ finish-with-sound to complete the process." (let ((old-srate *clm-srate*) (start (if statistics (get-internal-real-time))) (output-to-file (string? output)) (reverb-to-file (and reverb (string? revfile)))) (set! *clm-srate* srate) (if output-to-file (if continue-old-file (begin (set! *output* (continue-sample->file output)) (set! *clm-srate* (mus-sound-srate output))) (begin (if (file-exists? output) (delete-file output)) (set! *output* (make-sample->file output channels (or data-format sample-type) header-type comment)))) (begin (if (and (not continue-old-file) (vector output)) (fill! output 0.0)) (set! *output* output))) (if reverb (if reverb-to-file (if continue-old-file (set! *reverb* (continue-sample->file revfile)) (begin (if (file-exists? revfile) (delete-file revfile)) (set! *reverb* (make-sample->file revfile reverb-channels (or data-format sample-type) header-type)))) (begin (if (and (not continue-old-file) (vector? revfile)) (fill! revfile 0.0)) (set! *reverb* revfile)))) (list 'with-sound-data output reverb revfile old-srate statistics #f ;to-snd scaled-to scaled-by play reverb-data start))) (define (finish-with-sound wsd) "(finish-with-sound wsd) closes the notelist process started by init-with-sound" (if (eq? (car wsd) 'with-sound-data) (let ((output (list-ref wsd 1)) (reverb (list-ref wsd 2)) (revfile (list-ref wsd 3)) (old-srate (list-ref wsd 4)) ;(statistics (list-ref wsd 5)) ;(to-snd (list-ref wsd 6)) ;(scaled-to (list-ref wsd 7)) ;(scaled-by (list-ref wsd 8)) ;(play (list-ref wsd 9)) (reverb-data (list-ref wsd 10)) ;(start (list-ref wsd 11)) ) (if reverb (begin (mus-close *reverb*) (if (string? revfile) (set! *reverb* (make-file->sample revfile)) (set! *reverb* revfile)) (apply reverb reverb-data) (mus-close *reverb*))) (if (mus-output? *output*) (mus-close *output*)) (set! *clm-srate* old-srate) output) (throw 'wrong-type-arg (list "finish-with-sound" wsd)))) (define wsdat-play ; for cm (dilambda (lambda (w) "accessor for play field of init-with-sound struct" (list-ref w 9)) (lambda (w val) (list-set! w 9 val)))) (define ->frequency (let ((main-pitch (/ 440.0 (expt 2.0 (/ 57 12)))) ; a4 = 440Hz is pitch 57 in our numbering (last-octave 0) ; octave number can be omitted (ratios (vector 1.0 256/243 9/8 32/27 81/64 4/3 1024/729 3/2 128/81 27/16 16/9 243/128 2.0))) (lambda* (pitch pythagorean) ; pitch can be pitch name or actual frequency "(->frequency pitch pythagorean) returns the frequency (Hz) of the 'pitch', a CLM/CM style note name as a \ symbol: 'e4 for example. If 'pythagorean', the frequency calculation uses small-integer ratios, rather than equal-tempered tuning." (if (symbol? pitch) (let* ((name (string-downcase (symbol->string pitch))) (base-char (name 0)) (sign-char (and (> (length name) 1) (not (char-numeric? (name 1))) (not (char=? (name 1) #\n)) (name 1))) (octave-char (if (and (> (length name) 1) (char-numeric? (name 1))) (name 1) (if (and (> (length name) 2) (char-numeric? (name 2))) (name 2) #f))) (base (modulo (+ 5 (- (char->integer base-char) (char->integer #\a))) 7)) ; c-based (diatonic) octaves (sign (if (not sign-char) 0 (if (char=? sign-char #\f) -1 1))) (octave (if octave-char (- (char->integer octave-char) (char->integer #\0)) last-octave)) (base-pitch (+ sign (case base ((0) 0) ((1) 2) ((2) 4) ((3) 5) ((4) 7) ((5) 9) ((6) 11)))) (et-pitch (+ base-pitch (* 12 octave)))) (set! last-octave octave) (if pythagorean (* main-pitch (expt 2 octave) (ratios base-pitch)) (* main-pitch (expt 2.0 (/ et-pitch 12))))) pitch)))) (define (->sample beg) "(->sample time-in-seconds) -> time-in-samples" (round (* (if (not (null? (sounds))) (srate) *clm-srate*) beg))) ;;; -------- defgenerator -------- ;;; (defgenerator osc a b) ;;; (defgenerator (osc :methods (list (cons 'mus-frequency (lambda (obj) 100.0)))) a b) (define-macro (defgenerator struct-name . fields) (define (list->bindings lst) (let ((len (length lst))) (let ((nlst (make-list (* len 2)))) (do ((old lst (cdr old)) (nsym nlst (cddr nsym))) ((null? old) nlst) (if (pair? (car old)) (begin (set-car! (cdr nsym) (caar old)) (set-car! nsym (list 'quote (caar old)))) (begin (set-car! (cdr nsym) (car old)) (set-car! nsym (list 'quote (car old))))))))) (let* ((name (if (pair? struct-name) (car struct-name) struct-name)) (sname (if (string? name) name (symbol->string name))) (wrapper (or (and (pair? struct-name) (or (and (> (length struct-name) 2) (equal? (struct-name 1) :make-wrapper) (struct-name 2)) (and (= (length struct-name) 5) (equal? (struct-name 3) :make-wrapper) (struct-name 4)))) (lambda (gen) gen))) (methods (and (pair? struct-name) (or (and (> (length struct-name) 2) (equal? (struct-name 1) :methods) (struct-name 2)) (and (= (length struct-name) 5) (equal? (struct-name 3) :methods) (struct-name 4)))))) `(begin (define ,(string->symbol (string-append sname "?")) #f) (define ,(string->symbol (string-append "make-" sname)) #f) (let ((gen-type ',(string->symbol (string-append "+" sname "+"))) (gen-methods (and ,methods (apply inlet ,methods)))) (set! ,(string->symbol (string-append sname "?")) (lambda (obj) (and (let? obj) (eq? (obj 'mus-generator-type) gen-type)))) (set! ,(string->symbol (string-append "make-" sname)) (lambda* ,(map (lambda (n) (if (pair? n) n (list n 0.0))) fields) (,wrapper (openlet ,(if methods `(sublet gen-methods ,@(list->bindings (reverse fields)) 'mus-generator-type gen-type) `(inlet 'mus-generator-type gen-type ,@(list->bindings fields))))))))))) ;;; -------------------------------------------------------------------------------- ;;; ;;; functions from Snd that are used in some instruments ;;; these replacements assume that the Snd functions are not present (define* (file-name name) (if (string? name) (mus-expand-filename name) (mus-file-name name))) (define srate mus-sound-srate) (define (channels . args) (let ((obj (car args))) (if (string? obj) (mus-sound-chans obj) (mus-channels obj)))) ;;; I think length is handled by s7 for all types (define (framples . args) (let ((obj (car args))) (if (string? obj) (mus-sound-framples obj) (length obj)))) (define snd-print display) (define snd-warning display) (define snd-display (lambda args (apply format (append (list #t) (cdr args))))) (define (snd-error str) (error 'mus-error str)) (define snd-tempnam tmpnam) snd-16.1/selection.scm0000644000076400007640000001326312447054526013042 0ustar bilbil;;; selection.scm -- selection-related functions ;;; ;;; swap-selection-channels ;;; replace-with-selection ;;; selection-members ;;; make-selection ;;; filter-selection-and-smooth ;;; with-temporary-selection (provide 'snd-selection.scm) (if (not (defined? 'all-chans)) (define (all-chans) (let ((sndlist ()) (chnlist ())) (for-each (lambda (snd) (do ((i (- (channels snd) 1) (- i 1))) ((< i 0)) (set! sndlist (cons snd sndlist)) (set! chnlist (cons i chnlist)))) (sounds)) (list sndlist chnlist)))) ;;; -------- swap selection chans (define swap-selection-channels (let ((documentation "(swap-selection-channels) swaps the currently selected data's channels")) (lambda () (define find-selection-sound (lambda (not-this) (let ((scs (all-chans))) (call-with-exit (lambda (return) (map (lambda (snd chn) (if (and (selection-member? snd chn) (or (null? not-this) (not (equal? snd (car not-this))) (not (= chn (cadr not-this))))) (return (list snd chn)))) (car scs) (cadr scs))))))) (if (selection?) (if (= (selection-chans) 2) (let* ((beg (selection-position)) (len (selection-framples)) (snd-chn0 (find-selection-sound ())) (snd-chn1 (find-selection-sound snd-chn0))) (if snd-chn1 (swap-channels (car snd-chn0) (cadr snd-chn0) (car snd-chn1) (cadr snd-chn1) beg len) (error 'wrong-number-of-channels "swap-selection-channels needs two channels to swap"))) (error 'wrong-number-of-channels "swap-selection-channels needs a stereo selection")) (error 'no-active-selection "swap-selection-channels needs a selection"))))) ;;; -------- replace-with-selection (define replace-with-selection (let ((documentation "(replace-with-selection) replaces the samples from the cursor with the current selection")) (lambda () (let ((beg (cursor)) (len (selection-framples))) (insert-selection beg) ; put in the selection before deletion, since delete-samples can deactivate the selection (delete-samples (+ beg len) len))))) ;;; -------- selection-members ;;; ;;; returns a list of lists of (snd chn): channels in current selection (define selection-members (let ((documentation "(selection-members) -> list of lists of (snd chn) indicating the channels participating in the current selection.")) (lambda () (let ((sndlist ())) (if (selection?) (map (lambda (snd) (do ((i (- (channels snd) 1) (- i 1))) ((< i 0)) (if (selection-member? snd i) (set! sndlist (cons (list snd i) sndlist))))) (sounds))) sndlist)))) ;;; -------- make-selection ;;; the regularized form of this would use dur not end (define make-selection (let ((documentation "(make-selection beg end snd chn) makes a selection like make-region but without creating a region. make-selection follows snd's sync field, and applies to all snd's channels if chn is not specified. end defaults to end of channel, beg defaults to 0, snd defaults to the currently selected sound.")) (lambda* (beg end snd chn) (let ((current-sound (or snd (selected-sound) (car (sounds))))) (define (add-chan-to-selection s0 s1 s c) (set! (selection-member? s c) #t) (set! (selection-position s c) (or s0 0)) (set! (selection-framples s c) (- (or (and (number? s1) (+ 1 s1)) (framples s c)) (or s0 0)))) (if (not (sound? current-sound)) (error 'no-such-sound "make-selection can't find sound")) (let ((current-sync (sync current-sound))) (unselect-all) (if (number? chn) (add-chan-to-selection beg end snd chn) (for-each (lambda (s) (if (or (eq? snd #t) (equal? s current-sound) (and (not (= current-sync 0)) (= current-sync (sync s)))) (do ((i 0 (+ 1 i))) ((= i (channels s))) (add-chan-to-selection beg end s i)))) (sounds)))))))) ;;; -------- with-temporary-selection (define with-temporary-selection (let ((documentation "(with-temporary-selection thunk beg dur snd chn) saves the current selection placement, makes a new selection \ of the data from sample beg to beg + dur in the given channel. It then calls thunk, and restores the previous selection (if any). It returns whatever 'thunk' returned.")) (lambda (thunk beg dur snd chn) (let ((seldata (and (selection?) (car (selection-members))))) (if (selection?) (set! seldata (append seldata (list (selection-position) (selection-framples))))) (make-selection beg (- (+ beg dur) 1) snd chn) (let ((result (thunk))) (if seldata (make-selection (caddr seldata) (- (+ (caddr seldata) (cadddr seldata)) 1) (car seldata) (cadr seldata)) (unselect-all)) result))))) ;;; -------- filter-selection-and-smooth (define filter-selection-and-smooth (let ((documentation "(filter-selection-and-smooth ramp-dur flt order) applies 'flt' (via filter-sound) to \ the selection, the smooths the edges with a ramp whose duration is 'ramp-dur' (in seconds)")) (lambda* (ramp-dur flt order) (let ((temp-file (snd-tempnam))) (save-selection temp-file) (let ((selsnd (open-sound temp-file))) (filter-sound flt (or order (length flt)) selsnd) (let ((tmp-dur (samples->seconds (framples selsnd)))) (set! (sync selsnd) (+ 1 (sync-max))) ; make sure env-sound hits all chans (env-sound (list 0 0 ramp-dur 1 (- tmp-dur ramp-dur) 1 tmp-dur 0) 0 #f 1.0 selsnd) (save-sound selsnd) (close-sound selsnd) (env-selection (list 0 1 ramp-dur 0 (- tmp-dur ramp-dur) 0 tmp-dur 1)))) (mix temp-file (selection-position) #t #f #f #f #f))))) ;;; (filter-selection-and-smooth .01 (float-vector .25 .5 .5 .5 .25)) snd-16.1/old-music5.f0000644000076400007640000010557612306421672012504 0ustar bilbilC MUSIC V, Max Mathews C C typed in from old XGP output C file last written 19Jun75 MUSIC5[M5,GM] (I believe GM = George McKee) C SAIL C C The main typos are 'I' vs 1 -- the printout is so old and faded that C I can barely make out which is correct sometimes. And there are space C characters that were dropped by the printer. Also I haven't used C fortran since the early '80s -- I scarcely remember how this is supposed C to look. C C Mus11 says ifile(n,rnam) is the same as open(n,rnam,0,'RDO',,,'UNF') C C Bill Schottstaedt, 26-Apr-08 C C [page 1-1] -- these are the original XGP pages to help me find my place C PASS1 PASS 1 MAIN PROGRAM C PASS1 *** MUSIC V *** THIS VERSION RUNS ON THE PDP10, JULY 14,1971 COMMON P(100),IP(10),D(2000),IPDP DATA IPDP/0/ C*****PDP ***** IPDP WAS ADDED TO COMMON LIST IN PLACE OF ENTRY FEATURE. 99 FORMAT(' TYPE FILE NAME'/) 999 FORMAT(A5) TYPE 99 ACCEPT 999,FLNM CALL IFILE(1,FLNM) C*****ABOVE 5 LINES FOR PDP10 ******** C INITIALIZATION C NOMINAL SAMPLING RATE. D(4) = 10000.0 C ERROR FLAG IP(2)=0 P(2)=0.0 C C NWRITE = 2 NWRITE=20 C**** PDP DSK0=DEVICE 20 ****** CC REWIND NWRITE CC CALL READ0 CALL READ1 C********PDP ******** C MAIN LOOP 100 CALL READ1 I1=P(1) IF (I1.GE.1.AND.I1.LE.12) GO TO 103 IP(2)=1 CC WRITE (6,200) PRINT 200 C********PDP ******** 200 FORMAT(' NON-EXISTENT OPCODE ON DATA STATEMENT') GO TO 100 103 GO TO (1,1,1,1,5,6,7,1,9,1,1,12),I1 1 CALL WRITE1 (NWRITE) GO TO 100 5 PRINT 110 CC 5 WRITE (6, 110) C********PDP ******** 110 FORMAT(' END OF SECTION IN PASS 1') GO TO 1 6 CALL WRITE1 (NWRITE) C C WRITE (6, 111) PRINT 111 C********PDP ******** 111 FORMAT (' END OF PASS 1') IF(IP(2).EQ.1) CALL HARVEY CALL EXIT C SET VARIABLES IN PASS 1 7 I2=P(3) I3=I2+IP(1)-4 DO 104 I4=I2,I3 104 D(14)=P(14-I2+4) GO TO 100 9 I6=P(3) IF (I6.GE.1.AND.I6.LE.5) GO TO 107 IP(2)=1 CC WRITE (6,201) C [page 1-2] PRINT 201 C********PDP ******** 201 FORMAT(' NON-EXISTENT PLF SUBROUTINE CALLED') GO TO 100 12 CALL WRITE1 (NWRITE) GO TO 7 107 GO TO (21,22,23,24,25),I6 21 CALL PLF1 GO TO 100 22 CALL PLF2 GO TO 100 23 CALL PLF3 GO TO 100 24 CALL PLF4 GO TO 100 25 CALL PLF5 GO TO 100 END C WRITE1 PASS 1 DATA-WRITING ROUTINE C *** MUSIC V *** SUBROUTINE WRITE1(N) COMMON P(100),IP(10) K=IP(1) WRITE(N )K,(P(J),J=1,K) RETURN END SUBROUTINE PLF COMMON P(100),IP(10),D(2000) CC ENTRY PLF1 CC ENTRY PLF2 CC ENTRY PLF3 CC ENTRY PLF4 CC ENTRY PLF5 END C ERRO1 GENERAL ERROR ROUTINE C ***MUSIC V *** SUBROUTINE ERROR(I) PRINT 100,I 100 FORMAT(13HERROR OF TYPEI5) RETURN END SUBROUTINE HARVEY CC WRITE (6,1) PRINT 1 C********PDP ********* 1 FORMAT(' WHERE IS HARVEY') CALL EXIT END SUBROUTINE MOVR(IBCD,LA,LB) DIMENSION IBCD(300) DO 1 J=LA,LB CC 1 IBCD(J)=I5-(IBCD(J))/16777216 C********PDP ******** 1 IBCD(J)=IBCD(J)/536870912-48 2 DUMMY=0 C TO SET BREAKPOINT. RETURN END C [page 2-1] C READ1 INTERPRETATIVE READING ROUTINE C**** MUSIC V **** SUBROUTINE READ1 COMMON P(100),IP(10),D(2000),IPDP C*****PDP ***** IPDP WAS ADDED TO COMMON LIST IN PLACE OF ENTRY FEATURE DIMENSION CARD(129),ICAR(128),IBCD(300),LOP(3,30) DIMENSION BCD(300) DIMENSION IBC(12),IVT(4) EQUIVALENCE(CARD,ICAR) EQUIVALENCE(BCD,IBCD) DATA NOPS,NBC,NC/26,3,72/ DATA IDEC,ISTAR/'.','*'/ CCC DATA IBC(1),IBC(2),IBC(3),IBC(4)/'=',' ',',','-'/ DATA IBC(1),IBC(2),IBC(3),IBC(4)/';',' ',',','-'/ C********NO!!!!! THE CHARACTER = HAS BEEN SUBSTITUTED FOR C THE SEMICOLON AS THE END OF STATEMENT DELIMITER DATA IVT/'P','F','B','V'/ DATA LOP/'N','O','T','I','N','S','G','E','N','S','V','3', 1 'S','E','C','T','E','R','S','V','1','S','V','2','P','L','F', 2 'P','L','S','S','I','3','S','I','A','C','O','M','E','N','D', 3 'O','U','T','O','S','C','A','D','2','R','A','N','E','N','V', 4 'S','T','R','A','D','3','A','D','4','M','L','T','F','L','T', 5 'R','A','H','S','E','T',0,0,0,0,0,0,0,0,0,0,0,0/ C********LAST 12 LOCATIONS NOT YET USED. **** PDP ******** EQUIVALENCE (JSEMI,IBC(1)), (JBLANK,IBC(2)) C TO SCAN INPUT DATA TO #, ORGANIZE FIELDS AND PRINT IF(IPDP.EQ.0) GO TO 99 C********PDP ******** IF (END+SNA8-1.) 10,10,90 10 IBK=2 END=0 ERR=0 NUMU=0 ISEMI=1 L=3 J=0 11 I=I+1 IF(I.GT.NC) GO TO 15 IF(J.EQ.299) GO TO 21 DO 13 N=1,NBC IF(ICAR(I)-IBC(N)) 13,12,13 12 GO TO (20,16,18),N C ; BLA , 13 CONTINUE J=J+1 IBCD(J)=ICAR(I) IBK=1 GO TO 11 14 IBK=N GO TO 11 CC 15 READ (5,1,ERR=95,END=95) (CARD(I),I=1,NC) C********PDP ******** 15 READ (1,1,ERR=95,END=95) I, (CARD(I),I=1,NC) C*****PDP ***** FIRST 'I' IS FOR PDP LINE NUMBERS! 1 FORMAT(I,128A1) CC 1 FORMAT(128A1) PRINT 2,(CARD(I),I=1,NC) 2 FORMAT(1H 128A1) I=0 C [page 2-2] GO TO 11 16 GO TO (17,11,11),IBK 17 IBK=N J=J+1 IBCD(J)=JBLANK GO TO (11,21),ISEMI 18 GO TO (17,14,19),IBK 19 J=J+1 IBCD(J)=0 GO TO 17 20 ISEMI=2 GO TO (17,21,19),IBK 21 J=J+1 IBCD(J)=JSEMI C TO SCAN FOR OP CODE DO 24 N=1,NOPS M=N DO 23 K=1,3 IF (IBCD(K)-LOP(K,N)) 24,23,24 23 CONTINUE GO TO 26 24 CONTINUE GO TO 40 26 NP=1 27 L=L+1 IF (IBCD(L)-JBLANK) 27,29,27 29 GO TO (100,200,300,400,500,600,700,800,900,10000,1100,1200,1300, 1217 ,201,202,203,204,205,206,207,208,209,210,211,212),M C OP CODE 1 TO PLAY NOTE 100 P(1)=1. GO TO 30 C OP CODE 2 TO DEFINE INSTRUMENT 200 P(1)=2. IDEF=1 N1=1 GO TO 70 2000 P(2)=XN N1=2 GO TO 70 2001 P(3)=XN IP(1)=3 GO TO 50 C OUT BOX 201 P(3)=101. NPW=2 IF (STER) 220,220,2011 2011 SNA8=1. STER=0 GO TO 220 C OSCILLATOR 202 P(3)=102. NPW=5 GO TO 220 C ADD 2 203 P(3)=103. NPW=3 GO TO 220 C RANDOM AND INTERPOLATE 204 P(3)=104. NPW=6 C [page 2-3] GO TO 220 C LINEAR ENVELOPE GENERATOR 205 P(3)=105. NPW=7 GO TO 220 C STEREO OUT BOX 206 P(3)=106. NPW=3 IF(STER)220,2061,220 2061 SNA8=1. STER=1. GO TO 220 C THREE INPUT ADDER 207 P(3)=107. NPW=4 GO TO 220 C FOUR INPUT ADDER 208 P(3)=108. NPW=5 GO TO 220 C MULTIPLIER 209 P(3)=109. NPW=3 GO TO 220 C FILTER 210 P(3)=112. NPW=4 GO TO 220 C RANDOM AND HOLD 211 P(3)=111. NPW=5 GO TO 220 C SET NEW FUNCTION 212 P(3)=110. NPW=1 GO TO 220 C END OF INSTRUMENT 217 IP(1)=2 IDEF=0 END=1. GO TO 50 C UNNAMED UNIT - NUMERICAL NAME ASSUMED 218 N1=8 NUMU=1 L=0 GO TO 70 219 M=XN+14. IF(XN.LT.11.)GO TO 29 P(3)=XN C TO INTERPRET VARS IN UNIT DEFS 220 NP=3 221 IF(IBCD(L+1)-JSEMI) 222,240,222 222 NP=NP+1 L=L+1 DO 223 N=1,4 IF(IBCD(L)-IVT(N))223,225,223 223 CONTINUE 224 L=L+1 IF(IBCD(L).EQ.JBLANK)GO TO 46 GO TO 224 C [page 2-4] 225 GO TO (231,232,233,234),N C P TYPE 231 N1=3 GO TO 70 2311 P(NP)=XN GO TO 221 C F TYPE 232 N1=4 GO TO 70 2321 P(NP)=-(XN+100.) GO TO 221 C B TYPE 233 N1=5 GO TO 70 2331 P(NP)=-XN GO TO 221 C V TYPE 234 N1=6 GO TO 70 2341 P(NP)=XN+100. GO TO 221 240 IF(NUMU.EQ.1)GO TO 242 241 IF(NPW+3-NP)42,242,42 242 IP(1)=NP GO TO 50 C OP CODE 3 - TO GENERATE FUNCTION 300 P(1)=3. GO TO 30 C OP CODE 4 -- TO SET PARAM 3RD PASS 400 P(1)=4. GO TO 30 C OP CODE 5 TO END SEC 500 P(1)=5. GO TO 30 C OP CODE 6 TO TERMINATE PIECE 600 P(1)=6. GO TO 30 C OP CODE 7 TO SET PARAM 1ST PASS 700 P(1)=7. GO T0 30 C OP CODE 8 TO SET PARAM 2ND PASS 800 P(1)=8. GO TO 30 C OP CODE 9 TO EXECUTE SUB 1ST PASS 900 P(1)=9. GO TO 30 C OP CODE 10 TO EXECUTE SUB 2ND PASS 1000 P(1)=10. GO TO 30 C OP CODE 11 TO SET INTEGER 3RD PASS 1100 P(1)=11. GO TO 30 C OP CODE 12 TO SET INTEGER ALL PASSES 1200 P(1)=12. GO TO 30 C OP CODE 13 FOR COMMENTS 1300 IF(IBCD(L)-JSEMI)1301,10,1301 1301 L=L+1 GO TO 1300 C TO STORE PFIELDS C [page 2-5] 30 IF(IDEF)32,32,43 32 IF(IBCD(L+1)-JSEMI)33,34,33 33 NP=NP+1 N1=7 GO TO 70 331 P(NP)=XN GO TO 32 34 IP(1)=NP IF(NP-1)47,47,50 C ERRORS 40 IF(IDEF)41,41,218 41 L=L+1 IF(IBCD(L).NE.JSEMI)GO TO 41 PRINT 3 3 FORMAT(26H OP CODE NOT UNDERSTOOD) GO TO 49 42 PRINT 4 4 FORMAT(44H UNIT CONTAINS WRONG NUMBER OF PARAMETERS) GO TO 49 43 PRINT 5 5 FORMAT(36H INSTRUMENT DEFINITION INCOMPLETE) ERR=1. IDEF=0 GO TO 32 44 PRINT 6 6 FORMAT(25H ERROR IN NUMERIC DATA) ERR=1. IF(NUMU.EQ.1)GO TO 45 GO TO 30 45 PRINT 7 7 FORMAT(46H+ FOR UNIT DESIGNATION) P(3)=0. GO TO 220 46 PRINT 8 8 FORMAT(40H IMPROPER VARIABLE IN UNIT DEFINITION) ERR=1. GO TO 221 47 PRINT 9 9 FORMAT(24H STATEMENT INCOMPLETE) 49 IP(2)=1 GO TO 10 50 IF(ERR.EQ.1.) GO TO 49 RETURN C CONVERSION OF NUMERIC FIELD TO FLOATING POINT 70 SGN=1. IF (IBCD(L+1).NE.IBC(4)) GO TO 79 SGN=-1. L=L+1 79 L1=L+1 LD=L1 XN=0. 71 L=L+1 C *** I DON'T UNDERSTAND THIS PART OF THE SCANNER! CC IF(IBCD(L).EQ.JBLANK) GO TO 77 IF (IBCD(L)-JBLANK)72,77,72 C THIS LOOKS FOR #S, LETTERS, BLANKS, DECI.PTS, & *S. OTHERWISE=ERROR!? C ******** PDP ******** 72 IF(IBCD(L).LT.10)GO TO 71 IF(IBCD(L)-IDEC)74,71,74 74 IF(IBCD(L)-ISTAR)76,71,76 C [page 2-6] 76 GO TO 71 C ERROR CHECK IS REMOVED! C** NEXT 2 LINES BY-PASSED*** 76 L=L+1 IF(IBCD(L).EQ.JBLANK) GO TO 44 GO TO 76 77 IF(IBCD(L1)-ISTAR)80,78,80 78 XN=P(NP) GO TO 89 80 DO 81 LL=L1,L LD=LL IF (IBCD(LL)-IDEC)81,82,81 81 CONTINUE 82 IEX=0 LA=L1 LB=LD-1 IF(LD-L1)86,86,83 83 IEX=LD-LA 84 CALL MOVR (IBCD,LA,LB) DO 85 LL=LA,LB IEX=IEX-1 X1=IBCD(LL) 85 XN=XN+XI*10.**IEX 86 IF(L-LB-2)88,88,87 87 LA=LD+1 LB=L-1 GO TO 84 88 XN=XN*SGN 89 GO TO (2000,2001,2311,2321,2331,2341,331,219),N1 C TO WRITE S1A8 FOR MONO STEREO CONTROL 90 P(1)=12. P(3)=8. P(4)=STER IP(1)=4 END=0. SNA8=0. GO TO 50 C FOR PREMATURE END OF FILE ON INPUT 95 NP=2 IP(2)=1 L=0 IBCD(1)=JSEMI GO TO 600 C TO INITIALIZE CC ENTRY READ0 CC READ (5,1,ERR=95,END=95) (CARD(I),I=1,NC) C********PDP ******** 99 READ (1,1,ERR=95,END=95) I,(CARD(I),I=1,NC) C*****PDP ***** FIRST 'I' IS FOR PDP LINE NUMBERS! CC WRITE (6,2) (CARD(I),I=1,NC) PRINT 2,(CARD(I),I=1,NC) C********PDP ******** IPDP=1 I=0 IDEF=0 IBK=2 STER=0. END=0. SNA8=0. RETURN END C [page 3-1] C PASS 2 MAIN PROGRAM C *** MUSIC V *** DIMENSION G(1000),I(1000),T(1000),D(10000),P(100),IP(10) COMMON IP,P,G,I,T,D,IXJQ,TLAST,BLAST C INITIALIZING PROGRAM C NOMINAL SAMPLING RATE, NOTE PARAMETER LENGTH, NUMBER OF CARDS C NO OF OP CODES, PASS 11 REPORT PRINT PARAMETER G(1)=0. G(2)=0. G(4)=10000.0 NPAR=10000 NCAR=1000 NOPC=12 IXJQ=0 IEND=0 C C***** NREAD=2 C C***** NWRITE=3 NREAD=20 NWRITE=21 REWIND NREAD REWIND NWRITE C INITIALIZE SECTION 150 ID=1 IN=1 TLAST=0. BLAST=0. C READ SECTION OF DATA 106 CALL READ2 (NREAD) I1=IP(1) D(ID)=I1 I(IN)=ID T(IN)=P(2) DO 100 I2=1,I1 I3=ID+I2 100 D(I3)=P(I2) ID=ID+I1+1 IF(ID-NPAR)102,102,101 101 CALL ERROR(20) STOP 102 IN=IN+1 IF (IN-NCAR)103,103,101 103 IF (P(1)-5.0)104,110,104 104 IF (P(1)-6.0)106,105,106 105 IEND=1 GO TO 110 C SORT SECTION C*** NOT USED ****** 110 CALL SORTFL 110 IN=IN-1 CALL SORT(T(1),T(2),IN,I) C EXECUTE OP CODES M SECTION 120 DO 1 I4=1,IN I5=I(I4) I6=D(I5+1) IF(I6)121,121,122 121 CALL ERROR(21) GO TO 1 122 IF (I6-NOPC)123,123,121 123 GO TO (2,2,2,2,2,2,7,8,7,10,2,8),I6 7 CALL ERROR(22) GO TO 1 C [page 3-2] 8 I7=D(I5) I8=I5+4 I9=I5+I7 I10=IFIX(D(15+3))-I8 DO 124 I11=I8,I9 I12=I10+I11 124 G(I12)=D(I11) IF(I6-I2)1,2,1 10 I13=D(I5+3) IP(2)=I5 IF(I13)125,125,126 125 CALL ERROR(23) GO TO 1 126 IF(I13-5)127,127,125 127 GO TO (21,22,23,24,25),I13 21 CALL PLS1 GO TO 1 22 CALL PLS2 GO TO 1 23 CALL PLS3 GO TO 1 24 CALL PLS4 GO TO 1 25 CALL PLS5 GO TO 1 C WRITE OUT SECTION 2 IP(1)=D(I5) I18=IP(1) DO 133 I19=1,I18 I20=I19+I5 133 P(I19)=D(I20) CALL WRITE2 (NWRITE) 1 CONTINUE C END OF SECTION OR PASS 140 IF(IEND)141,141,143 141 PRINT 142 142 FORMAT (' END OF SECTION PASS II') GO TO 150 143 PRINT 144 144 FORMAT (' END OF PASS II') STOP END C READ2 PASS 2 DATA INPUT ROUTINE C *** MUSIC V *** SUBROUTINE READ2(N) DIMENSION IP(10),P(100) COMMON IP,P READ(N)K,(P(J),J=1,K) IP(1)=K RETURN END C SORT SORTING PROGRAM C *** MUSIC V *** SUBROUTINE SORT(A,B,N,L) DIMENSION A(N),L(N) C C SORT SORTS THE A ARRAY INTO ASCENDING NUMERICAL ORDER, PERFORMING C THE SAME OPERATIONS ON ARRAY L AS ON A C N1=N-1 C [page 3-3] DO 10 I=1,N1 IN=I+1 DO 20 J=IN,N IF(A(I).LE.A(J))GO TO 20 T=A(I) A(I)=A(J) A(J)=T NT=L(I) L(I)=L(J) L(J)=NT 20 CONTINUE 10 CONTINUE RETURN C C*********** ENTRY SORTFL C C*********** RETURN END C WRIT2 DATA OUTPUTING ROUTINE FOR PASS 2 C *** MUSIC V *** SUBROUTINE WRITE2(N) COMMON IP(10),P(100),G(1000),I(1000),T(1000),D(10000),IXJQ,TLAST,BLAST IF(G(2).EQ.0.)GO TO 150 X=P(2) Y=P(4) ILOC=G(2) IF(P(1).NE.1.)GO TO 50 P(4)=P(4)*60./CON(G,ILOC,P(2)) 50 P(2)=TLAST+(P(2)-BLAST)*60./CON(G,ILOC,P(2)) TLAST=P(2) BLAST=X 150 CALL CONVT K=IP(1) WRITE(N)K,(P(J),J=1,K) C *** PASS II REPORT IS OPTIONAL *** IF(G(1).NE.0.) RETURN IF(IXJQ.EQ.0) PRINT 100 IXJQ=10 100 FORMAT(15H1PASS II REPORT/11H0(WORD CNT)) PRINT 101,K,(P(J),J=1,K) IF(G(2).NE.0.) PRINT 102,X,Y 101 FORMAT(I8,10(F9.3)) 102 FORMAT(1H+,110X,2HB=,F7.4,2HD=,F7.4) RETURN END C CON2 PASS 2 FUNCTION INTERPOLATOR C *** MUSIC V *** FUNCTION CON(G,I,T) DIMENSION G(1) DO 10 J=1,1000,2 IF (G(J)-T) 10,20,30 30 CON = G(J-1)+((T-G(J-2))/(G(J)-G(J-2)))*(G(J+1)-G(J-1)) RETURN 10 CONTINUE 20 CON = G(J+1) RETURN END C CONVT FOR UNIT GENERATORS CHECK C C DUMMY NO OPERATION ACTUALLY PERFORMED C******WHEN DUMMY IS REMOVED ANOTHER CONVT MUST!!!! BE LOADED!!!***** C [page 3-4] C*** SUBROUTINE CONVT C*** COMMON IP(10),P(100),G(1000) C*** RETURN C*** END C ERRO1 GENERAL ERROR ROUTINE C *** MUSIC V *** SUBROUTINE ERROR(I) PRINT 100,I 100 FORMAT(' ERROR OF TYPE',I5) RETURN END C C***** SUBROUTINE PLS C C***** ENTRY PLS1 C C***** ENTRY PLS2 C C***** ENTRY PLS3 C C***** ENTRY PLS4 C C***** ENTRY PLS5 SUBROUTINE PLS1 RETURN END SUBROUTINE PLS2 RETURN END SUBROUTINE PLS3 RETURN END SUBROUTINE PLS4 RETURN END SUBROUTINE PLS5 RETURN END C [page 4-1] C PASS3 PASS 3 MAIN PROGRAM C *** MUSIC V *** C DATA SPECIFICATION INTEGER PEAK DIMENSION T(50),TI(50),ITI(50) COMMON I(15000),P(100)/PARM/IP(20)/FINOUT/PEAK,NRSOR C C******** DATA IIIRD/Z5EECE66D/ DATA IIIRD/976545367/ C SET I ARRAY =0 (7/10/69) DATA I/15000*0/ C***************** C INITIALIZATION OF PIECE C ARBITRARY STARTING NUMBER FOR SUBROUTINE RANDU I(7)=IIIRD IP9=IP(9) PEAK=0 NRSOR=0 C********NREAD=3 C********NWRITE=2 NREAD=21 C PDP DSK1=DEV.21 NWRITE=1 C PDP DSK=DEV.1 REWIND NREAD REWIND NWRITE TYPE 10001 ACCEPT 10002,FLNM,IDSK C TYPE 'PASS2' OR FILENAME + ANY POS.NUMB. TO WRITE SMPLS ON DSK. IF(FLNM.EQ.' '.OR.FLNM.EQ.'PASS2')FLNM='FOR21' CALL IFILE(21,FLNM) IF(IDSK.LE.0) GO TO 10003 J='MUSAA' CALL PUTFILE(J) C IF IDSK>=1, SAMPLES WILL BE WRITTEN ON DSK (MUSAA.DMD) IDSK=0 GO TO 10002 10003 IDSK=-1 10001 FORMAT(' TYPE FILE NAME'/) 10002 FORMAT(A5,I) C**** ABOVE FOR PDP 10 ****** SCLFT=IP(12) I(2)=IP(4) MS1=IP(7) MS3=MS1+(IP(8)*IP(9))-1 MS2=IP(8) I(4)=IP(3) MOUT=IP(10) C INITIALIZATION OF SECTION 5 T(1)=0.0 DO 220 N1=MS1,MS3,MS2 220 I(N1)=-1 DO 221 N1=1,IP9 221 TI(N1)=1000000. C MAIN CARD READING LOOP 204 CALL DATA (NREAD) IF(P(2)-T(1))200,200,244 200 IOP=P(1) IF(IOP)201,201,202 201 CALL ERROR(1) GO TO 204 C [page 4-2] 202 IF(IP(1)-IOP)201,203,203 203 GO TO (1,2,3,4,5,6,201,201,201,201,11,11),IOP 11 IVAR=P(3) IVARE=IVAR+I(1)-4 DO 297 N1=IVAR,IVARE IVARP=N1-IVAR+4 297 I(N1)=P(IVARP) GO TO 204 3 IGEN=P(3) GO TO (281,282,283,284,285),IGEN 281 CALL GEN1 GO TO 204 282 CALL GEN2 GO TO 204 283 CALL GEN3 GO TO 204 284 CALL GEN4 GO TO 204 285 CALL GEN5 GO TO 204 4 IVAR=P(3) IVARE=IVAR+I(1)-4 DO 296 N1=IVAR,IVARE IVARP=N1-IVAR+4 296 I(N1+100)=P(IVARP)*SCLFT GO TO 204 6 CALL FROUT3(IDSK) STOP C ENTER NOTE TO BE PLAYED 1 DO 230 N1=MS1,MS3,MS2 IF(I(N1)+1)230,231,230 230 CONTINUE CALL ERROR(2) GO TO 204 231 M1=N1 M2=N1+I(1)-1 M3=M2+1 M4=N1+IP(8)-1 DO 232 N1=M1,M2 M5=N1-M1+1 232 I(N1)=P(M5)*SCLFT I(M1)=P(3) DO 233 N1=M3,M4 233 I(N1)=0 DO 235 N1=1,IP9 IF(TI(N1)-1000000.)235,234,235 234 TI(N1)=P(2)+P(4) ITI(N1)=M1 GO TO 204 235 CONTINUE CALL ERROR(3) GO TO 204 C DEFINE INSTRUMENT 2 M1=I(2) M2=IP(5)+IFIX(P(3)) I(M2)=M1 218 CALL DATA (NREAD) IF(I(1)-2)210,210,211 210 I(M1)=0 I(2)=M1+1 C [page 4-3] GO TO 204 211 I(M1)=P(3) M3=I(1) I(M1+1)=M1+M3-1 M1=M1+2 DO 217 N1=4,M3 M5=P(N1) IF(M5)212,213,213 212 IF(M5+100)300,301,301 300 I(M1)=-IP(2)+(M5+101)*IP(6) GO TO 216 301 I(M1)=-IP(13)+(M5+1)*IP(14) GO TO 216 213 IF(M5-100)214,214,215 214 I(M1)=M5 GO TO 216 215 I(M1)=M5+262144 216 M1=M1+1 217 CONTINUE GO TO 218 C PLAY TO ACTION TIME 244 T(2)=P(2) 250 TMIN=1000000. IREST=1 DO 241 N1=1,IP9 IF(TMIN-TI(N1))241,241,240 240 TMIN=TI(N1) MNOTE=N1 241 CONTINUE IF(1000000.-TMIN)251,251,243 243 IF(TMIN-T(2))245,245,246 245 T(3)=TMIN GO TO 260 246 T(3)=T(2) GO TO 260 247 IF(T(1)-T(2))249,200,200 249 TI(MNOTE)=1000000. M2=ITI(MNOTE) I(M2)=-1 GO TO 250 C SETUP REST 251 T(3)=T(2) IREST=2 GO TO 260 C PLAY 260 ISAM=(T(3)-T(1))*FLOAT(I(4))+.5 T(1)=T(3) IF(ISAM)247,247,266 266 IF(ISAM-IP(14))262,262,263 262 I(5)=ISAM ISAM=0 GO TO 264 263 I(5)=IP(14) ISAM=ISAM-IP(14) 264 IF(I(8))290,290,291 290 M3=MOUT+I(5)-1 MSAMP=I(5) GO TO 292 291 M3=MOUT+(2*I(5))-1 MSAMP=2*I(5) C [page 4-4] 292 DO 267 N1=MOUT,M3 267 I(N1)=0 GO TO (268,265),IREST 268 DO 270 NS1=MS1,MS3,MS2 IF(I(NS1)+1)271,270,271 C GO THROUGH UNIT GENERATORS IN INSTRUMENT 271 I(3)=NS1 IGEN=IP(5)+I(NS1) IGEN=I(IGEN) 272 I(6)=IGEN CC***** IF((IGEN)-101)293,294,294 CC***** 293 CALL SAMGEN(I) CC***** ABOVE FOR MACHINE LANG. UNIT GENERATORS ****** CC***** GO TO 295 294 CALL FORSAM 295 IGEN=I(IGEN+1) IF(I(IGEN))270,270,272 270 CONTINUE 265 CALL SAMOUT(IDSK,MSAMP) IF(ISAM)247,247,266 END C [page 5-1] C FORS3 FORTRAN UNIT GENERATOR ROUTINE C *** MUSIC V *** SUBROUTINE FORSAM DIMENSION I(15000),P(100),IP(20),L(8),M(8) COMMON I,P/PARM/IP EQUIVALENCE (M1,M(1)),(M2,M(2)),(M3,M(3)),(M4,M(4)),(M5,M(5)),(M6,M(6)),(M7,M(7)),(M8,M(8)),(L1,L(1)),(L2,L(2)),(L3,L(3)),(L4,L(4)),(L5,L(5)),(L6,L(6)),(L7,L(7)),(L8,L(8)),(RN1,IRN1),(RN3,IRN3),(RN,IRN) C C***** DATA IMULT/Z5EECE66D/ DATA IIIRD/976545367/ SFI=1./FLOAT(IP(12)) SFF=1./FLOAT(IP(15)) SFID=FLOAT(IP(12)) SFXX=FLOAT(IP(12))/FLOAT(IP(15)) XNFUN=IP(6)-1 C COMMON INITIALIZATION OF GENERATORS N1=I(6)+2 N2=I(N1-1)-1 DO 204 J1=N1,N2 J2=J1-N1+1 IF(I(J1))200,201,201 200 L(J2)=-I(J1) M(J2)=1 GO TO 204 201 M(J2)=0 IF(I(J1)-262144)202,202,203 C*****WHAT DOES THE BIG NUMBER DO????? 202 L(J2)=I(J1)+I(3)-1 GO TO 204 203 L(J2)=I(J1)-262144 204 CONTINUE NSAM=I(5) N3=I(N1-2) NGEN=N3-100 GO TO (101,102,103,104,105,106,107,108,109,110,111,112),NGEN 112 RETURN C UNIT GENERATORS C OUTPUT BOX 101 IF(M1)260,260,261 260 IN1=I(L1) 261 CONTINUE DO 270 J3=1,NSAM IF(M1)265,265,264 264 J4=L1+J3-1 IN1=I(J4) 265 J5=L2+J3-1 I(J5)=IN1+I(J5) 270 CONTINUE RETURN C OSCILLATOR 102 SUM=FLOAT(I(L5))*SFI IF(M1)280,280,281 280 AMP=FLOAT(I(L1))*SFI 281 IF(M2)282,282,283 282 FREQ=FLOAT(I(L2))*SFI 283 CONTINUE DO 293 J3=1,NSAM J4=INT(SUM)+L4 F=FLOAT(I(J4)) C [page 5-2] IF(M2)285,285,286 285 SUM=SUM+FREQ GO TO 290 286 J4=L2+J3-1 SUM=SUM+FLOAT(I(J4))*SFI CC 290 IF(SUM-XNFUN)288,287,287 290 IF(SUM.GE.XNFUN)GO TO 287 CC 287 SUM=SUM-XNFUN IF(SUM.LT.0.0)GO TO 289 288 J5=L3+J3-1 IF(M1)291,291,292 291 I(J5)=IFIX(AMP*F*SFXX) GO TO 293 C************ 287 SUM=SUM-XNFUN GO TO 288 289 SUM=SUM+XNFUN GO TO 288 C**********ABOVE FOR FM (NEG. FREQ. TO OSCIL) 292 J6=L1+J3-1 I(J5)=IFIX(FLOAT(I(J6))*F*SFF) 293 CONTINUE I(L5)=IFIX(SUM*SFID) RETURN C ADD TWO BOX 103 IF(M1)250,250,251 250 IN1=I(L1) 251 IF(M2)252,252,253 252 IN2=I(L2) 253 DO 258 J3=1,NSAM IF(M1)255,255,254 254 J4=L1+J3-1 IN1=I(J4) 255 IF(M2)257,257,256 256 J5=L2+J3-1 IN2=I(J5) 257 J6=L3+J3-1 I(J6)=IN1+IN2 258 CONTINUE RETURN C RANDOM INTERPOLATING GENERATOR 104 SUM=FLOAT(I(L4))*SFI IF(M1)310,310,311 310 XIN1=FLOAT(I(L1))*SFI 311 IF(M2)312,312,313 312 XIN2=FLOAT(I(L2))*SFI 313 IRN1=I(L5) IRN3=I(L6) DO 340 J3=1,NSAM IF(M1)316,316,315 315 J4=L1+J3-1 XIN1=FLOAT(I(J4))*SFI 316 IF(M2)318,318,317 317 J5=L2+J3-1 XIN2=FLOAT(I(J5))*SFI 318 IF(SUM-XNFUN)320,319,319 319 SUM=SUM-XNFUN I(7)=IABS(I(7)*IMULT) RN4=(2.*FLOAT(I(7))*SFF-1.) RN2=RN4-RN3 C [page 5-3] RN1=RN3 RN3=RN4 GO TO 321 320 RN2=RN3-RN1 321 J7=L3+J3-1 I(J7)=XIN1*(RN1+(RN2*SUM)/XNFUN)*SFID SUM=SUM+XIN2 340 CONTINUE I(L4)=IFIX(SUM*SFID) I(L5)=IRN1 I(L6)=IRN3 RETURN C ENVELOPE GENERATOR 105 SUM=FLOAT(I(L7))*SFI IF(M1)380,380,381 380 XIN1=FLOAT(I(L1))*SFI 381 IF(M4)382,382,383 382 XIN4=FLOAT(I(L4))*SFI 383 IF(M5)384,384,385 384 XIN5=FLOAT(I(L5))*SFI 385 IF(M6)386,386,387 386 XIN6=FLOAT(I(L6))*SFI 387 X1=XNFUN/4. X2=2.*X1 X3=3.*X1 DO 403 J3=1,NSAM J4=INT(SUM)+L2 F=FLOAT(I(J4)) IF(M1)405,405,404 404 J8=L1+J3-1 XIN1=FLOAT(I(J8))*SFI 405 IF(SUM-XNFUN)389,388,388 388 SUM=SUM-XNFUN 389 IF(SUM-X1)390,390,393 390 IF(M4)392,392,391 391 J4=L4+J3-1 XIN4=FLOAT(I(J4))*SFI 392 SUM=SUM+XIN4 GO TO 402 393 IF(SUM-X2)394,394,397 394 IF(M5)396,396,395 395 J5=L5+J3-1 XIN5=FLOAT(I(J5))*SFI 396 SUM=SUM+XIN5 GO TO 402 397 IF(M6)400,400,399 399 J6=L6+J3-1 XIN6=FLOAT(I(J6))*SFI 400 SUM=SUM+XIN6 402 J7=L3+J3-1 I(J7)=IFIX(XIN1*F*SFXX) 403 CONTINUE I(L7)=IFIX(SUM*SFID) RETURN C STEREO OUTPUT BOX 106 IF(M1)500,500,501 500 IN1=I(L1) 501 IF(M2)502,502,503 502 IN2=I(L2) 503 NSSAM=2*NSAM C [page 5-4] C 6/29/70 L.C.SMITH ICT=0 DO 510 J3=1,NSSAM,2 IF(M1) 505,505,504 C C*** 504 J4=L1+J3-1 504 J4=L1+ICT IN1=I(J4) 505 J5=L3+J3-1 I(J5)=IN1+I(J5) IF(M2)507,507,506 C C*** 506 J4=L2+J3-1 506 J4=L2+ICT IN2=I(J4) 507 J5=L3+J3 I(J5)=IN2+I(J5) 510 CONTINUE RETURN C ADD 3 BOX 107 IF(M1)750,750,751 750 IN1=I(L1) 751 IF(M2)752,752,753 752 IN2=I(L2) 753 IF(M3)754,754,755 754 IN3=I(L3) 755 DO 780 J3=1,NSAM IF(M1)757,757,756 756 J4=L1+J3-1 IN1=I(J4) 757 IF(M2)759,759,758 758 J5=L2+J3-1 IN2=I(J5) 759 IF(M3)761,761,760 760 J6=L3+J3-1 IN3=I(J6) 761 J7=L4+J3-1 I(J7)=IN1+IN2+IN3 780 CONTINUE RETURN C ADD 4 BOX 108 IF(M1)850,850,851 850 IN1=I(L1) 851 IF(M2)852,852,853 852 IN2=I(L2) 853 IF(M3)854,854,855 854 IN3=I(L3) 855 IF(M4)856,856,857 856 IN4=I(L4) 857 DO 880 J3=1,NSAM IF(M1)859,859,858 858 J4=L1+J3-1 IN1=I(J4) 859 IF(M2)861,861,860 860 J5=L2+J3-1 IN2=I(J5) 861 IF(M3)863,863,862 862 J6=L3+J3-1 IN3=I(J6) 863 IF(M4)865,865,864 864 J7=L4+J3-1 IN4=I(J7) C [page 5-5] 865 J8=L5+J3-1 I(J8)=IN1+IN2+IN3+IN4 880 CONTINUE RETURN C MULTIPLIER 109 IF(M1)900,900,901 900 XIN1=FLOAT(I(L1))*SFI 901 IF(M2)902,902,903 902 XIN2=FLOAT(I(L2))*SFI 903 DO 908 J=1,NSAM IF(M1)905,905,904 904 J4=L1+J3-1 XIN1=FLOAT(I(J4))*SFI 905 IF(M2)907,907,906 906 J5=L2+J3-1 XIN2=FLOAT(I(J5))*SFI 907 J6=L3+J3-1 I(J6)=XIN1*XIN2*SFID 908 CONTINUE RETURN C SET NEW FUNCTION IN OSC OR ENV 110 ILOC=N1+6 IF(I(N1+1).EQ.105) ILOC=N1+4 IN1=I(3)+I(N1)-1 IIN1=I(IN1)/IP(12) IF(IIN1)960,960,955 955 I(ILOC)=-IP(2)-(IIN1-1)*IP(6) 960 RETURN C RANDOM AND HOLD GENERATOR 111 SUM=FLOAT(I(L4))*SFI IF(M1)910,910,911 910 XIN1=FLOAT(I(L1))*SFI 911 IF(M2)912,912,913 912 XIN2=FLOAT(I(L2))*SFI 913 IRN=I(L5) DO 940 J3=1,NSAM IF(M1)916,916,915 915 J4=L1+J3-1 XIN1=FLOAT(I(J4))*SFI 916 IF(M2)918,918,917 917 J5=L2+J3-1 XIN2=FLOAT(I(J5))*SFI 918 IF(SUM-XNFUN)920,919,919 919 SUM=SUM-XNFUN I(7)=IABS(I(7)*IMULT) RN=(2.*FLOAT(I(7))*SFF-1.) 920 J7=L3+J3-1 I(J7)=XIN1*RN*SFID SUM=SUM+XIN2 940 CONTINUE I(L4)=IFIX(SUM*SFID) I(L5)=IRN RETURN END C [page 6-1] C GEN1 FUNCTION GENERATOR 1 C *** MUSIC V *** SUBROUTINE GEN1 DIMENSION I(15000),P(100),IP(20) COMMON I,P/PARM/IP N1=IP(2)+(IFIX(P(4))-1)*IP(6) M1=7 SCLFT=IP(15) 102 IF(P(M1+1))103,103,100 100 V1=P(M1-2)*SCLFT V2=(P(M1)-P(M1-2))/(P(M1+1)-P(M1-1))*SCLFT MA=N1+IFIX(P(M1-1)) MB=N1+IFIX(P(M1+1))-1 DO 101 J=MA,MB XJ=J-MA 101 I(J)=V1+V2*XJ IF(IFIX(P(M1+1)).EQ.(IP(6)-1))GO TO 103 M1=M1+2 GO TO 102 103 I(MB+1)=P(M1)*SCLFT RETURN END C GEN2 FUNCTION GENERATOR 2 c *** MUSIC V *** SUBROUTINE GEN2 DIMENSION I(15000),P(100),IP(20),A(7000) COMMON I,P/PARM/IP EQUIVALENCE(I,A) SCLFT=IP(15) N1=IP(2)+(IFIX(P(4))-1)*IP(6) N2=N1+IP(6)-1 DO 101 K1=N1,N2 101 A(K1)=0.0 FAC=6.283185/(FLOAT(IP(6))-1.0) NMAX=I(1) N3=5+INT(ABS(P(NMAX)))-1 IF(N3-5)104,100,100 100 DO 103 J=5,N3 FACK=FAC*FLOAT(J-4) DO 102 K=N1,N2 102 A(K)=A(K)+SIN(FACK*FLOAT(K-N1))*P(J) 103 CONTINUE 104 N4=N3+1 N5=I(1)-1 IF(N5-N4)114,105,105 105 DO 107 J1=N4,N5 FACK=FAC*FLOAT(J1-N4) DO 106 K1=N1,N2 106 A(K1)=A(K1)+COS(FACK*FLOAT(K1-N1))*P(J1) 107 CONTINUE 114 CONTINUE IF(P(NMAX))112,112,108 108 FMAX=0.0 DO 110 K2=N1,N2 IF(ABS(A(K2))-FMAX)110,110,109 109 FMAX=ABS(A(K2)) 110 CONTINUE 113 DO 111 K3=N1,N2 111 I(K3)=(A(K3)*SCLFT*.99999)/FMAX RETURN C [page 6-2] 112 FMAX=.99999 GO TO 113 END C GEN3 FUNCTION GENERATOR 3 C *** MUSIC V *** C ASSUMPTIONS--P(4) = THE NUMBER OF THE FUNCTION TO BE GENERATED, C I(1) = WORD COUNT FOR CURRENT DATA RECORD C P(5) = THE BEGINNING THE THE LIST OF DESCRIPTION NUMBERS C IP(2) = THE BEGINNING SUBSCRIPT FOR FUNCTIONS IN THE I ARRAY, C IP(6) = THE LENGTH OF THE FUNCTIONS C IP(15) = SCALE FACTOR FOR STORED FUNCTIONS C SUBROUTINE GEN3 COMMON I(15000),P(100) /PARM/ IP(20) N=I(1)-5 NL=5 SCLFT=IP(15) LL=IP(6) RMIN=0 RMAX=0 NR=NL+N DO 10 J=NL,NR IF(P(J).GT.RMAX) RMAX=P(J) 10 IF(P(J).LT.RMIN) RMIN=P(J) DIV=AMAX1(ABS(RMIN),ABS(RMAX)) N1 = IP(2) + (IFIX(P(4))-1)*IP(6) I(N1)=(P(NL)/DIV)*SCLFT LAST=N1 DO 100 J=1,N LL = LL-LL/(N-J+1) IX = N1+IP(6)-LL-1 IX2 = NL+J I(IX)=(P(IX2)/DIV)*SCLFT DELTA=FLOAT(I(IX))-FLOAT(I(LAST)) NR = IX-LAST-1 SEG = NR+1 HNCR=DELTA/SEG DO 50 K=1,NR IX2 = LAST+K 50 I(IX2)=FLOAT(I(IX2-1))+HNCR 100 LAST=IX RETURN END C DATA3 PASS 3 DATA INPUTING ROUTINE C *** MUSIC V *** SUBROUTINE DATA(N) COMMON I(15000),P(100) READ(N) K,(P(J),J=1,K) I(1)=K RETURN END C PARM CONTROL DATA SPECIFICATION FOR PASS 3 C *** MUSIC V *** C C IP(1) = NUMBER OF OP CODES C IP(2) = BEGINNING SUBSCRIPT OF FIRST FUNCTION C IP(3) = STANDARD SAMPLING RATE C IP(4) = BEGINNING SUBSCRIPT OF INSTRUMENT DEFINITIONS C IP(5) = BEGINNING OF LOCATION TABLE FOR INSTRUMENT DEFINITIONS C IP(6) = LENGTH OF FUNCTIONS C [page 6-3] C IP(7) = BEGINNING OF NOTE CARD PARAMETERS C IP(8) = LENGTH OF NOTE CARD PARAMETER BLOCKS C IP(9) = NUMBER OF NOTE CARD PARAMETER BLOCKS C IP(10) = BEGINNING OF OUTPUT DATA BLOCK C IP(11) = SOUND ZERO (SILENCE VALUE) C IP(12) = SCALE FACTOR FOR NOTE CARD PARAMETERS C IP(13) = BEGINNING OF GENERATOR INPUT-OUTPUT BLOCKS C IP(14) = LENGTH OF GENERATOR INPUT-OUTPUT BLOCKS C IP(15) = SCALE FACTOR FOR FUNCTIONS C BLOCK DATA COMMON /PARM/IP(20) DATA IP/12,512,10000,14500,14400,512,13000,35,40,6657,2048, 1 "1000000,6657,512,"377777777777,5*0/ C**** BIG NUMB. IS IBM360'S BIGGEST. 1 65536,6657,512,Z7FFFFFFF/ END C**** SUBROUTINE DUM C**** ENTRY SAMGEN C**** ENTRY GEN4 C**** ENTRY GEN5 C**** END SUBROUTINE SAMGEN RETURN END SUBROUTINE GEN4 END SUBROUTINE GEN5 END C **** DUMMY SUBROUTINES **** SUBROUTINE FROUT3(IDSK) C TERMINATE OUTPUT INTEGER PEAK COMMON I(15000),P(100)/PARM/IP(20)/FINOUT/PEAK,NRSOR K=IP(10) L=IP(10)+IP(14)-1 DO 1 J=K,L 1 I(J)=0 CALL SAMOUT(IDSK,IP(14)) C REWIND NWRITE C WRITE(6,10) PEAK,NRSOR TYPE 10,PEAK,NRSOR C CALL EXIT IF(IDSK.LT.0)CALL EXIT J=IP(10) L=J+1024 DO 2 K=J,L 2 I(K)=0 C WILL WRITE 1024 0'S ON DSK. CALL FASTOUT(I(J),1024) CALL FINFILE CALL EXIT 10 FORMAT ('0PEAK AMPLITUDE WAS',I8/'0NUMBER OF SAMPLES OUT OF RANGE WAS',I8) END C DSMOUT DEBUG SAMOUT C *** MUSIC V *** C [page 6-4] C DEBUG SAMOUT SUBROUTINE SAMOUT(IDSK,N) DIMENSION IDBUF(2000),MS(3) C*** IDSK IS FLAG TO WRITE SAMPLES ON DSK -- PDP **** C*** IDBUF WILL STORE PACKED SAMPLES. **** DIMENSION I(15000),T(10),P(100),IP(20) COMMON I,P/PARM/IP/FINOUT/PEAK,NRSOR INTEGER PEAK IF(IDSK.GE.0) GO TO 99 N1=N PRINT 100,N1 100 FORMAT(7H OUTPUTI6,8H SAMPLES) N2=IP(10)-1 N3=10 GO TO 104 106 DO 101 L=1,10 J=N2+L 101 T(L)=FLOAT(I(J))/FLOAT(IP(12)) PRINT 102, (T(K),K=1,N3) 102 FORMAT(1H 10F11.4) N2=N2+10 N1=N1-10 IF(N1)103,103,104 103 RETURN 104 IF(N1-10)105,106,106 105 N3=N1 GO TO 106 99 J=IDSK+1 M1=IP(10) M2=0 ISC=IP(12) IDSK=IDSK+N C COUNTS SAMPLES TO DATE DO 1 K=J,IDSK N1=I(M1+M2)/ISC IF(N1.GT.PEAK)PEAK=N1 IDBUF(K)=N1 1 M2=M2+1 IF(IDSK.LT.768)RETURN KL=0 DO 2 K=1,768,3 KL=KL+1 KJ=K-1 MS(1)=IDBUF(K) IF(MS(1).EQ.2048) MS(1)=2047 C A 2048 IN THE 12 LEFT HAND BITS CREATES PROBLEMS DO 3 L=2,3 MS(L)=IDBUF(KJ+L) 3 IF(MS(L).LT.0) MS(L)=4096+MS(L) 2 IDBUF(KL)=MS(3)+MS(2)*4096+MS(1)*16777216 C PACKS 3 SMPLS TO A 36-BIT WORD. 4096=2**12, 16---=2**24. C MS(1) HAS LEFT HAND 12 BITS; MS(2), MIDDLE 12 BITS; MS(3), RIGHT 12. C NEGATIVE NUMBERS RUN FROM 4096(I.E. -1) TO 2049(I.E. -2048). CALL FASTOUT(IDBUF(1),256) J=IDSK-768 IF(J.LT.1) GO TO 4 DO 5 K=1,J 5 IDBUF(K)=IDBUF(768+K) C [page 6-5] 4 IDSK=J RETURN END C ERROR1 GENERAL ERROR ROUTINE C *** MUSIC V *** SUBROUTINE ERROR(I) PRINT 100,I 100 FORMAT(' ERROR OF TYPE',I5) RETURN END snd-16.1/sndplay.c0000644000076400007640000001272312474410636012165 0ustar bilbil/* sndplay plays sounds */ #include "mus-config.h" #include #include #include #include "_sndlib.h" #ifndef _MSC_VER #include #endif #include #if __APPLE__ #define BUFFER_SIZE 256 #else #ifdef _MSC_VER /* this setting from Scott Middleton (actually used 8096) */ #define BUFFER_SIZE 8192 #else #define BUFFER_SIZE 4096 #endif #endif #if __APPLE__ #define OutSample float #define MUS_CONVERT(samp) (float)(samp) #else #define OutSample short #define MUS_SAMPLE_TO_SHORT(n) ((short)((n) * (1 << 15))) #define MUS_CONVERT(samp) MUS_SAMPLE_TO_SHORT(samp) #endif /* 22-Nov-00: moved alsa support to separate block */ /* 8-Apr-04: added start/end (seconds-based) args */ /* 2-Nov-05: added -volume arg (removed later) */ /* 22-July-08: added -mutable arg */ /* 1-May-12: removed alsa special case */ int main(int argc, char *argv[]) { int fd, afd, i, j, n, k, chans, srate; mus_long_t framples, m; mus_float_t **bufs; OutSample *obuf; int buffer_size = BUFFER_SIZE, curframples, sample_size, out_chans, outbytes; char *name = NULL; mus_long_t start = 0, end = 0; double begin_time = 0.0, end_time = 0.0; int mutate = 1, include_mutate = 0; if (argc == 1) { printf("usage: sndplay file [-start 1.0] [-end 1.0] [-bufsize %d] [-buffers 2x12] [-describe]\n", BUFFER_SIZE); exit(0); } mus_sound_initialize(); for (i = 1; i < argc; i++) { if (strcmp(argv[i], "-buffers") == 0) { #if (HAVE_OSS || HAVE_ALSA) static char x_string[2] = {'x','\0'}; char *arg; int a, b; arg = strtok(argv[i + 1], x_string); a = atoi(arg); arg = strtok(NULL, x_string); b = atoi(arg); mus_oss_set_buffers(a, b); #endif i++; } else { if (strcmp(argv[i], "-bufsize") == 0) { buffer_size = atoi(argv[i + 1]); i++; } else { if (strcmp(argv[i], "-start") == 0) { begin_time = atof(argv[i + 1]); i++; } else { if (strcmp(argv[i], "-end") == 0) { end_time = atof(argv[i + 1]); i++; } else { if (strcmp(argv[i], "-mutable") == 0) { mutate = atoi(argv[i + 1]); include_mutate = 1; i++; } else name = argv[i]; }}}}} if (name == NULL) { printf("usage: sndplay file [-start 1.0] [-end 1.0] [-bufsize %d] [-buffers 2x12] [-mutable 1]\n", BUFFER_SIZE); exit(0); } afd = -1; if (!(mus_is_header_type(mus_sound_header_type(name)))) { fprintf(stderr, "can't play %s (header type: %s?)\n", name, mus_header_type_name(mus_header_type())); exit(0); } if (!(mus_is_sample_type(mus_sound_sample_type(name)))) { fprintf(stderr, "can't play %s (sample type: %s (%s)?)\n", name, mus_sample_type_name(mus_sound_sample_type(name)), mus_header_original_sample_type_name(mus_sound_original_sample_type(name), mus_sound_header_type(name))); exit(0); } fd = mus_sound_open_input(name); if (fd != -1) { chans = mus_sound_chans(name); if (chans > 2) { int available_chans; available_chans = mus_audio_device_channels(MUS_AUDIO_DEFAULT); if (available_chans < chans) { fprintf(stderr, "%s has %d channels, but we can only handle %d\n", name, chans, available_chans); exit(1); } } out_chans = chans; srate = mus_sound_srate(name); framples = mus_sound_framples(name); sample_size = mus_bytes_per_sample(MUS_AUDIO_COMPATIBLE_SAMPLE_TYPE); start = (mus_long_t)(begin_time * srate); if (start > 0) mus_file_seek_frample(fd, start); if (end_time > 0.0) end = (mus_long_t)(end_time * srate); else end = framples; if ((end - start) < framples) framples = end - start; bufs = (mus_float_t **)calloc(chans, sizeof(mus_float_t *)); for (i = 0; i < chans; i++) bufs[i] = (mus_float_t *)calloc(buffer_size, sizeof(mus_float_t)); obuf = (OutSample *)calloc(buffer_size * out_chans, sizeof(OutSample)); outbytes = buffer_size * out_chans * sample_size; for (m = 0; m < framples; m += buffer_size) { if ((m + buffer_size) <= framples) curframples = buffer_size; else curframples = framples - m; mus_file_read(fd, start + m, curframples, chans, bufs); /* some systems are happier if we read the file before opening the dac */ /* at this point the data is in separate arrays of mus_sample_t's */ if (chans == 1) { for (k = 0; k < curframples; k++) obuf[k] = MUS_CONVERT(bufs[0][k]); } else { if (chans == 2) { for (k = 0, n = 0; k < curframples; k++, n += 2) { obuf[n] = MUS_CONVERT(bufs[0][k]); obuf[n + 1] = MUS_CONVERT(bufs[1][k]); } } else { for (k = 0, j = 0; k < curframples; k++, j += chans) { for (n = 0; n < chans; n++) obuf[j + n] = MUS_CONVERT(bufs[n][k]); } } } #if __APPLE__ if (include_mutate == 1) mus_audio_output_properties_mutable(mutate); #endif if (afd == -1) { afd = mus_audio_open_output(MUS_AUDIO_DEFAULT, srate, out_chans, MUS_AUDIO_COMPATIBLE_SAMPLE_TYPE, outbytes); if (afd == -1) break; } outbytes = curframples * out_chans * sample_size; mus_audio_write(afd, (char *)obuf, outbytes); } if (afd != -1) mus_audio_close(afd); mus_sound_close_input(fd); for (i = 0; i < chans; i++) free(bufs[i]); free(bufs); free(obuf); } return(0); } snd-16.1/sndlib.h0000644000076400007640000005141112571434530011765 0ustar bilbil#ifndef SNDLIB_H #define SNDLIB_H #define SNDLIB_VERSION 24 #define SNDLIB_REVISION 4 #define SNDLIB_DATE "1-Sep-15" #include #include #include /* not sure how to handle this one cleanly: */ #ifndef __cplusplus #ifndef _MSC_VER #include #else #ifndef true #define bool unsigned char #define true 1 #define false 0 #endif #endif #endif typedef double mus_float_t; typedef long long int mus_long_t; #if defined(__sun) && defined(__SVR4) #define HAVE_SUN 1 #endif #ifdef _MSC_VER /* I got these from gmp.h */ #if defined (__GNUC__) #define MUS_EXPORT __declspec(__dllexport__) #else #define MUS_EXPORT __declspec(dllexport) #endif #else #define MUS_EXPORT #endif #ifndef MUS_LITTLE_ENDIAN #if WORDS_BIGENDIAN #define MUS_LITTLE_ENDIAN 0 #else #define MUS_LITTLE_ENDIAN 1 #endif #endif typedef enum {MUS_UNKNOWN_HEADER, MUS_NEXT, MUS_AIFC, MUS_RIFF, MUS_RF64, MUS_BICSF, MUS_NIST, MUS_INRS, MUS_ESPS, MUS_SVX, MUS_VOC, MUS_SNDT, MUS_RAW, MUS_SMP, MUS_AVR, MUS_IRCAM, MUS_SD1, MUS_SPPACK, MUS_MUS10, MUS_HCOM, MUS_PSION, MUS_MAUD, MUS_IEEE, MUS_MATLAB, MUS_ADC, MUS_MIDI, MUS_SOUNDFONT, MUS_GRAVIS, MUS_COMDISCO, MUS_GOLDWAVE, MUS_SRFS, MUS_MIDI_SAMPLE_DUMP, MUS_DIAMONDWARE, MUS_ADF, MUS_SBSTUDIOII, MUS_DELUSION, MUS_FARANDOLE, MUS_SAMPLE_DUMP, MUS_ULTRATRACKER, MUS_YAMAHA_SY85, MUS_YAMAHA_TX16W, MUS_DIGIPLAYER, MUS_COVOX, MUS_AVI, MUS_OMF, MUS_QUICKTIME, MUS_ASF, MUS_YAMAHA_SY99, MUS_KURZWEIL_2000, MUS_AIFF, MUS_PAF, MUS_CSL, MUS_FILE_SAMP, MUS_PVF, MUS_SOUNDFORGE, MUS_TWINVQ, MUS_AKAI4, MUS_IMPULSETRACKER, MUS_KORG, MUS_NVF, MUS_CAFF, MUS_MAUI, MUS_SDIF, MUS_OGG, MUS_FLAC, MUS_SPEEX, MUS_MPEG, MUS_SHORTEN, MUS_TTA, MUS_WAVPACK, MUS_SOX, MUS_NUM_HEADERS} mus_header_t; typedef enum {MUS_UNKNOWN_SAMPLE, MUS_BSHORT, MUS_MULAW, MUS_BYTE, MUS_BFLOAT, MUS_BINT, MUS_ALAW, MUS_UBYTE, MUS_B24INT, MUS_BDOUBLE, MUS_LSHORT, MUS_LINT, MUS_LFLOAT, MUS_LDOUBLE, MUS_UBSHORT, MUS_ULSHORT, MUS_L24INT, MUS_BINTN, MUS_LINTN, MUS_BFLOAT_UNSCALED, MUS_LFLOAT_UNSCALED, MUS_BDOUBLE_UNSCALED, MUS_LDOUBLE_UNSCALED, MUS_NUM_SAMPLES} mus_sample_t; #ifndef MUS_AUDIO_COMPATIBLE_SAMPLE_TYPE #if WORDS_BIGENDIAN #if __APPLE__ #define MUS_AUDIO_COMPATIBLE_SAMPLE_TYPE MUS_BFLOAT #else #define MUS_AUDIO_COMPATIBLE_SAMPLE_TYPE MUS_BSHORT #endif #else #if __APPLE__ #define MUS_AUDIO_COMPATIBLE_SAMPLE_TYPE MUS_LFLOAT #else #define MUS_AUDIO_COMPATIBLE_SAMPLE_TYPE MUS_LSHORT #endif #endif #endif #ifndef MUS_OUT_SAMPLE_TYPE #if WORDS_BIGENDIAN #define MUS_OUT_SAMPLE_TYPE MUS_BDOUBLE #else #define MUS_OUT_SAMPLE_TYPE MUS_LDOUBLE #endif #endif #define MUS_IGNORE_SAMPLE MUS_NUM_SAMPLES /* MUS_LINTN and MUS_BINTN refer to 32 bit ints with 31 bits of fraction -- the data is left justified */ /* "unscaled" means the float value is used directly (i.e. not as -1.0 to 1.0, but (probably) -32768.0 to 32768.0) */ #define MUS_NIST_SHORTPACK 2 #define MUS_AIFF_IMA_ADPCM 99 #define MUS_AUDIO_PACK_SYSTEM(n) ((n) << 16) #define MUS_AUDIO_SYSTEM(n) (((n) >> 16) & 0xffff) #define MUS_AUDIO_DEVICE(n) ((n) & 0xffff) #define MUS_AUDIO_DEFAULT 0 #define MUS_ERROR -1 enum {MUS_NO_ERROR, MUS_NO_FREQUENCY, MUS_NO_PHASE, MUS_NO_GEN, MUS_NO_LENGTH, MUS_NO_DESCRIBE, MUS_NO_DATA, MUS_NO_SCALER, MUS_MEMORY_ALLOCATION_FAILED, MUS_CANT_OPEN_FILE, MUS_NO_SAMPLE_INPUT, MUS_NO_SAMPLE_OUTPUT, MUS_NO_SUCH_CHANNEL, MUS_NO_FILE_NAME_PROVIDED, MUS_NO_LOCATION, MUS_NO_CHANNEL, MUS_NO_SUCH_FFT_WINDOW, MUS_UNSUPPORTED_SAMPLE_TYPE, MUS_HEADER_READ_FAILED, MUS_UNSUPPORTED_HEADER_TYPE, MUS_FILE_DESCRIPTORS_NOT_INITIALIZED, MUS_NOT_A_SOUND_FILE, MUS_FILE_CLOSED, MUS_WRITE_ERROR, MUS_HEADER_WRITE_FAILED, MUS_CANT_OPEN_TEMP_FILE, MUS_INTERRUPTED, MUS_BAD_ENVELOPE, MUS_AUDIO_CHANNELS_NOT_AVAILABLE, MUS_AUDIO_SRATE_NOT_AVAILABLE, MUS_AUDIO_SAMPLE_TYPE_NOT_AVAILABLE, MUS_AUDIO_NO_INPUT_AVAILABLE, MUS_AUDIO_CONFIGURATION_NOT_AVAILABLE, MUS_AUDIO_WRITE_ERROR, MUS_AUDIO_SIZE_NOT_AVAILABLE, MUS_AUDIO_DEVICE_NOT_AVAILABLE, MUS_AUDIO_CANT_CLOSE, MUS_AUDIO_CANT_OPEN, MUS_AUDIO_READ_ERROR, MUS_AUDIO_CANT_WRITE, MUS_AUDIO_CANT_READ, MUS_AUDIO_NO_READ_PERMISSION, MUS_CANT_CLOSE_FILE, MUS_ARG_OUT_OF_RANGE, MUS_NO_CHANNELS, MUS_NO_HOP, MUS_NO_WIDTH, MUS_NO_FILE_NAME, MUS_NO_RAMP, MUS_NO_RUN, MUS_NO_INCREMENT, MUS_NO_OFFSET, MUS_NO_XCOEFF, MUS_NO_YCOEFF, MUS_NO_XCOEFFS, MUS_NO_YCOEFFS, MUS_NO_RESET, MUS_BAD_SIZE, MUS_CANT_CONVERT, MUS_READ_ERROR, MUS_NO_FEEDFORWARD, MUS_NO_FEEDBACK, MUS_NO_INTERP_TYPE, MUS_NO_POSITION, MUS_NO_ORDER, MUS_NO_COPY, MUS_CANT_TRANSLATE, MUS_NUM_ERRORS}; /* keep this list in sync with mus_error_names in sound.c and snd-test.scm|rb */ #define MUS_LOOP_INFO_SIZE 8 #ifdef __cplusplus extern "C" { #endif /* -------- sound.c -------- */ #ifdef __GNUC__ MUS_EXPORT int mus_error(int error, const char *format, ...) __attribute__ ((format (printf, 2, 3))); MUS_EXPORT void mus_print(const char *format, ...) __attribute__ ((format (printf, 1, 2))); MUS_EXPORT char *mus_format(const char *format, ...) __attribute__ ((format (printf, 1, 2))); #else MUS_EXPORT int mus_error(int error, const char *format, ...); MUS_EXPORT void mus_print(const char *format, ...); MUS_EXPORT char *mus_format(const char *format, ...); #endif typedef void mus_error_handler_t(int type, char *msg); MUS_EXPORT mus_error_handler_t *mus_error_set_handler(mus_error_handler_t *new_error_handler); MUS_EXPORT const char *mus_error_type_to_string(int err); typedef void mus_print_handler_t(char *msg); MUS_EXPORT mus_print_handler_t *mus_print_set_handler(mus_print_handler_t *new_print_handler); typedef mus_float_t mus_clip_handler_t(mus_float_t val); MUS_EXPORT mus_clip_handler_t *mus_clip_set_handler(mus_clip_handler_t *new_clip_handler); MUS_EXPORT mus_clip_handler_t *mus_clip_set_handler_and_checker(mus_clip_handler_t *new_clip_handler, bool (*checker)(void)); MUS_EXPORT mus_long_t mus_sound_samples(const char *arg); MUS_EXPORT mus_long_t mus_sound_framples(const char *arg); MUS_EXPORT int mus_sound_datum_size(const char *arg); MUS_EXPORT mus_long_t mus_sound_data_location(const char *arg); MUS_EXPORT int mus_sound_chans(const char *arg); MUS_EXPORT int mus_sound_srate(const char *arg); MUS_EXPORT mus_header_t mus_sound_header_type(const char *arg); MUS_EXPORT mus_sample_t mus_sound_sample_type(const char *arg); MUS_EXPORT int mus_sound_original_sample_type(const char *arg); MUS_EXPORT mus_long_t mus_sound_comment_start(const char *arg); MUS_EXPORT mus_long_t mus_sound_comment_end(const char *arg); MUS_EXPORT mus_long_t mus_sound_length(const char *arg); MUS_EXPORT int mus_sound_fact_samples(const char *arg); MUS_EXPORT time_t mus_sound_write_date(const char *arg); MUS_EXPORT int mus_sound_type_specifier(const char *arg); MUS_EXPORT int mus_sound_block_align(const char *arg); MUS_EXPORT int mus_sound_bits_per_sample(const char *arg); MUS_EXPORT int mus_sound_set_chans(const char *arg, int val); MUS_EXPORT int mus_sound_set_srate(const char *arg, int val); MUS_EXPORT mus_header_t mus_sound_set_header_type(const char *arg, mus_header_t val); MUS_EXPORT mus_sample_t mus_sound_set_sample_type(const char *arg, mus_sample_t val); MUS_EXPORT int mus_sound_set_data_location(const char *arg, mus_long_t val); MUS_EXPORT int mus_sound_set_samples(const char *arg, mus_long_t val); MUS_EXPORT const char *mus_header_type_name(mus_header_t type); MUS_EXPORT const char *mus_header_type_to_string(mus_header_t type); MUS_EXPORT const char *mus_sample_type_name(mus_sample_t samp_type); MUS_EXPORT const char *mus_sample_type_to_string(mus_sample_t samp_type); MUS_EXPORT const char *mus_sample_type_short_name(mus_sample_t samp_type); MUS_EXPORT char *mus_sound_comment(const char *name); MUS_EXPORT int mus_bytes_per_sample(mus_sample_t samp_type); MUS_EXPORT float mus_sound_duration(const char *arg); MUS_EXPORT int mus_sound_initialize(void); MUS_EXPORT int mus_sound_override_header(const char *arg, int srate, int chans, mus_sample_t samp_type, mus_header_t type, mus_long_t location, mus_long_t size); MUS_EXPORT int mus_sound_forget(const char *name); MUS_EXPORT int mus_sound_prune(void); MUS_EXPORT void mus_sound_report_cache(FILE *fp); MUS_EXPORT int *mus_sound_loop_info(const char *arg); MUS_EXPORT void mus_sound_set_loop_info(const char *arg, int *loop); MUS_EXPORT int mus_sound_mark_info(const char *arg, int **mark_ids, int **mark_positions); MUS_EXPORT int mus_sound_open_input(const char *arg); MUS_EXPORT int mus_sound_open_output(const char *arg, int srate, int chans, mus_sample_t sample_type, mus_header_t header_type, const char *comment); MUS_EXPORT int mus_sound_reopen_output(const char *arg, int chans, mus_sample_t samp_type, mus_header_t type, mus_long_t data_loc); MUS_EXPORT int mus_sound_close_input(int fd); MUS_EXPORT int mus_sound_close_output(int fd, mus_long_t bytes_of_data); #define mus_sound_read(Fd, Beg, End, Chans, Bufs) mus_file_read(Fd, Beg, End, Chans, Bufs) #define mus_sound_write(Fd, Beg, End, Chans, Bufs) mus_file_write(Fd, Beg, End, Chans, Bufs) MUS_EXPORT mus_long_t mus_sound_maxamps(const char *ifile, int chans, mus_float_t *vals, mus_long_t *times); MUS_EXPORT int mus_sound_set_maxamps(const char *ifile, int chans, mus_float_t *vals, mus_long_t *times); MUS_EXPORT bool mus_sound_maxamp_exists(const char *ifile); MUS_EXPORT bool mus_sound_channel_maxamp_exists(const char *file, int chan); MUS_EXPORT mus_float_t mus_sound_channel_maxamp(const char *file, int chan, mus_long_t *pos); MUS_EXPORT void mus_sound_channel_set_maxamp(const char *file, int chan, mus_float_t mx, mus_long_t pos); MUS_EXPORT mus_long_t mus_file_to_array(const char *filename, int chan, mus_long_t start, mus_long_t samples, mus_float_t *array); MUS_EXPORT int mus_array_to_file(const char *filename, mus_float_t *ddata, mus_long_t len, int srate, int channels); MUS_EXPORT const char *mus_array_to_file_with_error(const char *filename, mus_float_t *ddata, mus_long_t len, int srate, int channels); MUS_EXPORT mus_long_t mus_file_to_float_array(const char *filename, int chan, mus_long_t start, mus_long_t samples, mus_float_t *array); MUS_EXPORT int mus_float_array_to_file(const char *filename, mus_float_t *ddata, mus_long_t len, int srate, int channels); MUS_EXPORT mus_float_t **mus_sound_saved_data(const char *arg); MUS_EXPORT void mus_sound_set_saved_data(const char *arg, mus_float_t **data); MUS_EXPORT void mus_file_save_data(int tfd, mus_long_t framples, mus_float_t **data); /* -------- audio.c -------- */ MUS_EXPORT int mus_audio_open_output(int dev, int srate, int chans, mus_sample_t samp_type, int size); MUS_EXPORT int mus_audio_open_input(int dev, int srate, int chans, mus_sample_t samp_type, int size); MUS_EXPORT int mus_audio_write(int line, char *buf, int bytes); MUS_EXPORT int mus_audio_close(int line); MUS_EXPORT int mus_audio_read(int line, char *buf, int bytes); MUS_EXPORT int mus_audio_initialize(void); MUS_EXPORT char *mus_audio_moniker(void); MUS_EXPORT int mus_audio_api(void); MUS_EXPORT mus_sample_t mus_audio_compatible_sample_type(int dev); #if HAVE_OSS || HAVE_ALSA MUS_EXPORT void mus_oss_set_buffers(int num, int size); MUS_EXPORT char *mus_alsa_playback_device(void); MUS_EXPORT char *mus_alsa_set_playback_device(const char *name); MUS_EXPORT char *mus_alsa_capture_device(void); MUS_EXPORT char *mus_alsa_set_capture_device(const char *name); MUS_EXPORT char *mus_alsa_device(void); MUS_EXPORT char *mus_alsa_set_device(const char *name); MUS_EXPORT int mus_alsa_buffer_size(void); MUS_EXPORT int mus_alsa_set_buffer_size(int size); MUS_EXPORT int mus_alsa_buffers(void); MUS_EXPORT int mus_alsa_set_buffers(int num); MUS_EXPORT bool mus_alsa_squelch_warning(void); MUS_EXPORT bool mus_alsa_set_squelch_warning(bool val); #endif #if __APPLE__ MUS_EXPORT bool mus_audio_output_properties_mutable(bool mut); #endif MUS_EXPORT int mus_audio_device_channels(int dev); MUS_EXPORT mus_sample_t mus_audio_device_sample_type(int dev); /* -------- io.c -------- */ MUS_EXPORT int mus_file_open_descriptors(int tfd, const char *arg, mus_sample_t df, int ds, mus_long_t dl, int dc, mus_header_t dt); MUS_EXPORT int mus_file_open_read(const char *arg); MUS_EXPORT bool mus_file_probe(const char *arg); MUS_EXPORT int mus_file_open_write(const char *arg); MUS_EXPORT int mus_file_create(const char *arg); MUS_EXPORT int mus_file_reopen_write(const char *arg); MUS_EXPORT int mus_file_close(int fd); MUS_EXPORT mus_long_t mus_file_seek_frample(int tfd, mus_long_t frample); MUS_EXPORT mus_long_t mus_file_read(int fd, mus_long_t beg, mus_long_t end, int chans, mus_float_t **bufs); MUS_EXPORT mus_long_t mus_file_read_chans(int fd, mus_long_t beg, mus_long_t end, int chans, mus_float_t **bufs, mus_float_t **cm); MUS_EXPORT int mus_file_write(int tfd, mus_long_t beg, mus_long_t end, int chans, mus_float_t **bufs); MUS_EXPORT mus_long_t mus_file_read_any(int tfd, mus_long_t beg, int chans, mus_long_t nints, mus_float_t **bufs, mus_float_t **cm); MUS_EXPORT mus_long_t mus_file_read_file(int tfd, mus_long_t beg, int chans, mus_long_t nints, mus_float_t **bufs); MUS_EXPORT mus_long_t mus_file_read_buffer(int charbuf_sample_type, mus_long_t beg, int chans, mus_long_t nints, mus_float_t **bufs, char *charbuf); MUS_EXPORT int mus_file_write_file(int tfd, mus_long_t beg, mus_long_t end, int chans, mus_float_t **bufs); MUS_EXPORT int mus_file_write_buffer(int charbuf_sample_type, mus_long_t beg, mus_long_t end, int chans, mus_float_t **bufs, char *charbuf, bool clipped); MUS_EXPORT char *mus_expand_filename(const char *name); MUS_EXPORT char *mus_getcwd(void); MUS_EXPORT bool mus_clipping(void); MUS_EXPORT bool mus_set_clipping(bool new_value); MUS_EXPORT bool mus_file_clipping(int tfd); MUS_EXPORT int mus_file_set_clipping(int tfd, bool clipped); MUS_EXPORT int mus_file_set_header_type(int tfd, mus_header_t type); MUS_EXPORT mus_header_t mus_file_header_type(int tfd); MUS_EXPORT char *mus_file_fd_name(int tfd); MUS_EXPORT int mus_file_set_chans(int tfd, int chans); MUS_EXPORT int mus_iclamp(int lo, int val, int hi); MUS_EXPORT mus_long_t mus_oclamp(mus_long_t lo, mus_long_t val, mus_long_t hi); MUS_EXPORT mus_float_t mus_fclamp(mus_float_t lo, mus_float_t val, mus_float_t hi); /* for CLM */ /* these are needed to clear a saved lisp image to the just-initialized state */ MUS_EXPORT void mus_reset_io_c(void); MUS_EXPORT void mus_reset_headers_c(void); MUS_EXPORT void mus_reset_audio_c(void); MUS_EXPORT int mus_samples_bounds(unsigned char *data, int bytes, int chan, int chans, mus_sample_t samp_type, mus_float_t *min_samp, mus_float_t *max_samp); MUS_EXPORT mus_long_t mus_max_malloc(void); MUS_EXPORT mus_long_t mus_set_max_malloc(mus_long_t new_max); MUS_EXPORT mus_long_t mus_max_table_size(void); MUS_EXPORT mus_long_t mus_set_max_table_size(mus_long_t new_max); MUS_EXPORT char *mus_strdup(const char *str); MUS_EXPORT int mus_strlen(const char *str); MUS_EXPORT bool mus_strcmp(const char *str1, const char *str2); MUS_EXPORT char *mus_strcat(char *errmsg, const char *str, int *err_size); /* -------- headers.c -------- */ MUS_EXPORT bool mus_is_sample_type(int n); MUS_EXPORT bool mus_is_header_type(int n); MUS_EXPORT mus_long_t mus_header_samples(void); MUS_EXPORT mus_long_t mus_header_data_location(void); MUS_EXPORT int mus_header_chans(void); MUS_EXPORT int mus_header_srate(void); MUS_EXPORT mus_header_t mus_header_type(void); MUS_EXPORT mus_sample_t mus_header_sample_type(void); MUS_EXPORT mus_long_t mus_header_comment_start(void); MUS_EXPORT mus_long_t mus_header_comment_end(void); MUS_EXPORT int mus_header_type_specifier(void); MUS_EXPORT int mus_header_bits_per_sample(void); MUS_EXPORT int mus_header_fact_samples(void); MUS_EXPORT int mus_header_block_align(void); MUS_EXPORT int mus_header_loop_mode(int which); MUS_EXPORT int mus_header_loop_start(int which); MUS_EXPORT int mus_header_loop_end(int which); MUS_EXPORT int mus_header_mark_position(int id); MUS_EXPORT int mus_header_mark_info(int **marker_ids, int **marker_positions); MUS_EXPORT int mus_header_base_note(void); MUS_EXPORT int mus_header_base_detune(void); MUS_EXPORT void mus_header_set_raw_defaults(int sr, int chn, mus_sample_t frm); MUS_EXPORT void mus_header_raw_defaults(int *sr, int *chn, mus_sample_t *frm); MUS_EXPORT mus_long_t mus_header_true_length(void); MUS_EXPORT int mus_header_original_sample_type(void); MUS_EXPORT mus_long_t mus_samples_to_bytes(mus_sample_t samp_type, mus_long_t size); MUS_EXPORT mus_long_t mus_bytes_to_samples(mus_sample_t samp_type, mus_long_t size); MUS_EXPORT int mus_header_read(const char *name); MUS_EXPORT int mus_header_write(const char *name, mus_header_t type, int srate, int chans, mus_long_t loc, mus_long_t size_in_samples, mus_sample_t samp_type, const char *comment, int len); MUS_EXPORT int mus_write_header(const char *name, mus_header_t type, int in_srate, int in_chans, mus_long_t size_in_samples, mus_sample_t samp_type, const char *comment); MUS_EXPORT mus_long_t mus_header_aux_comment_start(int n); MUS_EXPORT mus_long_t mus_header_aux_comment_end(int n); MUS_EXPORT int mus_header_initialize(void); MUS_EXPORT bool mus_header_writable(mus_header_t type, mus_sample_t samp_type); MUS_EXPORT void mus_header_set_aiff_loop_info(int *data); MUS_EXPORT int mus_header_sf2_entries(void); MUS_EXPORT char *mus_header_sf2_name(int n); MUS_EXPORT int mus_header_sf2_start(int n); MUS_EXPORT int mus_header_sf2_end(int n); MUS_EXPORT int mus_header_sf2_loop_start(int n); MUS_EXPORT int mus_header_sf2_loop_end(int n); MUS_EXPORT const char *mus_header_original_sample_type_name(int samp_type, mus_header_t type); MUS_EXPORT bool mus_header_no_header(const char *name); MUS_EXPORT char *mus_header_riff_aux_comment(const char *name, mus_long_t *starts, mus_long_t *ends); MUS_EXPORT char *mus_header_aiff_aux_comment(const char *name, mus_long_t *starts, mus_long_t *ends); MUS_EXPORT int mus_header_change_chans(const char *filename, mus_header_t type, int new_chans); MUS_EXPORT int mus_header_change_srate(const char *filename, mus_header_t type, int new_srate); MUS_EXPORT int mus_header_change_type(const char *filename, mus_header_t new_type, mus_sample_t new_sample_type); MUS_EXPORT int mus_header_change_sample_type(const char *filename, mus_header_t type, mus_sample_t new_sample_type); MUS_EXPORT int mus_header_change_location(const char *filename, mus_header_t type, mus_long_t new_location); MUS_EXPORT int mus_header_change_comment(const char *filename, mus_header_t type, const char *new_comment); MUS_EXPORT int mus_header_change_data_size(const char *filename, mus_header_t type, mus_long_t bytes); typedef void mus_header_write_hook_t(const char *filename); MUS_EXPORT mus_header_write_hook_t *mus_header_write_set_hook(mus_header_write_hook_t *new_hook); /* these are internal to sndlib */ void mus_bint_to_char(unsigned char *j, int x); void mus_lint_to_char(unsigned char *j, int x); void mus_bfloat_to_char(unsigned char *j, float x); void mus_lfloat_to_char(unsigned char *j, float x); void mus_bshort_to_char(unsigned char *j, short x); void mus_lshort_to_char(unsigned char *j, short x); void mus_bdouble_to_char(unsigned char *j, double x); void mus_blong_to_char(unsigned char *j, mus_long_t x); void mus_llong_to_char(unsigned char *j, mus_long_t x); int mus_char_to_bint(const unsigned char *inp); int mus_char_to_lint(const unsigned char *inp); mus_long_t mus_char_to_llong(const unsigned char *inp); mus_long_t mus_char_to_blong(const unsigned char *inp); int mus_char_to_uninterpreted_int(const unsigned char *inp); float mus_char_to_bfloat(const unsigned char *inp); float mus_char_to_lfloat(const unsigned char *inp); short mus_char_to_bshort(const unsigned char *inp); short mus_char_to_lshort(const unsigned char *inp); unsigned short mus_char_to_ubshort(const unsigned char *inp); unsigned short mus_char_to_ulshort(const unsigned char *inp); double mus_char_to_ldouble(const unsigned char *inp); double mus_char_to_bdouble(const unsigned char *inp); unsigned int mus_char_to_ubint(const unsigned char *inp); unsigned int mus_char_to_ulint(const unsigned char *inp); #ifdef __cplusplus } #endif #if (!DISABLE_DEPRECATED) #define mus_header_format mus_header_sample_type #define mus_header_original_format mus_header_original_sample_type #define mus_header_original_format_name mus_header_original_sample_type_name #define mus_header_change_format mus_header_change_sample_type #define mus_sound_original_format mus_sound_original_sample_type #define MUS_AUDIO_COMPATIBLE_FORMAT MUS_AUDIO_COMPATIBLE_SAMPLE_TYPE #define MUS_OUT_FORMAT MUS_OUT_SAMPLE_TYPE #define MUS_AUDIO_FORMAT_NOT_AVAILABLE MUS_AUDIO_SAMPLE_TYPE_NOT_AVAILABLE #define mus_audio_compatible_format mus_audio_compatible_sample_type #define mus_audio_device_format mus_audio_device_sample_type #endif #endif snd-16.1/snd-file.c0000644000076400007640000040664412603035272012216 0ustar bilbil#include "snd.h" #include "snd-file.h" #include "sndlib-strings.h" /* -------------------------------- basic file attributes -------------------------------- */ #ifdef _MSC_VER mus_long_t disk_kspace(const char *filename) {return(1234567);} #else #include #include #include #if __bsdi__ || __NetBSD__ #include #endif mus_long_t disk_kspace(const char *filename) { #if HAVE_SUN statvfs_t buf; /* else dumb compiler complaint */ #else struct statvfs buf; #endif mus_long_t err; err = statvfs(filename, &buf); if (err == 0) { if (buf.f_frsize == 1024) return(buf.f_bfree); return((mus_long_t)(buf.f_frsize * ((double)(buf.f_bfree) / 1024.0))); } return(err); } #endif bool is_link_file(const char *filename) { #if __MINGW32__ return(false); #else struct stat statbuf; #ifndef _MSC_VER return((stat(filename, &statbuf) >= 0) && (S_ISLNK(statbuf.st_mode))); #else return((stat(filename, &statbuf) == 0) && (S_ISLNK(statbuf.st_mode))); #endif #endif } bool is_directory(const char *filename) { struct stat statbuf; #ifndef _MSC_VER return((stat(filename, &statbuf) >= 0) && (S_ISDIR(statbuf.st_mode))); #else return((stat(filename, &statbuf) == 0) && (S_ISDIR(statbuf.st_mode))); #endif } time_t file_write_date(const char *filename) { struct stat statbuf; int err; if (!filename) return((time_t)0); err = stat(filename, &statbuf); if (err < 0) return((time_t)err); return((time_t)(statbuf.st_mtime)); } const char *short_sample_type_name(mus_sample_t sndlib_sample_type, const char *filename) { if (mus_is_sample_type(sndlib_sample_type)) return(mus_sample_type_short_name(sndlib_sample_type)); else return(mus_header_original_sample_type_name(mus_sound_original_sample_type(filename), mus_sound_header_type(filename))); } static void forget_filename(const char *filename, char **names) { int i, j = 0; for (i = 0; i < FILENAME_LIST_SIZE; i++) if ((names[i]) && (strcmp(names[i], filename) == 0)) { free(names[i]); names[i] = NULL; } for (i = 0; i < FILENAME_LIST_SIZE; i++) if (names[i]) { if (i != j) { names[j] = names[i]; names[i] = NULL; } j++; } } void remember_filename(const char *filename, char **names) { int i; forget_filename(filename, names); /* clear out old copy, if any, then compact the list */ if (names[FILENAME_LIST_SIZE - 1]) free(names[FILENAME_LIST_SIZE - 1]); for (i = FILENAME_LIST_SIZE - 1; i > 0; i--) names[i] = names[i - 1]; names[0] = mus_strdup(filename); } char **make_filename_list(void) { return((char **)calloc(FILENAME_LIST_SIZE, sizeof(char *))); } static char *preloaded_files[FILENAME_LIST_SIZE]; void preload_filenames(char **files) { int i; for (i = 0; (i < FILENAME_LIST_SIZE) && (preloaded_files[i]); i++) files[i] = mus_strdup(preloaded_files[i]); } int recent_files_size(void) { /* return how many files in the preloaded list are not currently open (for Open Recent menu item) */ int i, size = 0; for (i = 0; (i < FILENAME_LIST_SIZE) && (preloaded_files[i]); i++) if ((!(find_sound(preloaded_files[i], 0))) && (mus_file_probe(preloaded_files[i]))) size++; return(size); } char **recent_files(void) { int i, j = 0; char **new_list; new_list = make_filename_list(); for (i = 0; (i < FILENAME_LIST_SIZE) && (preloaded_files[i]); i++) if ((!(find_sound(preloaded_files[i], 0))) && (mus_file_probe(preloaded_files[i]))) new_list[j++] = mus_strdup(preloaded_files[i]); return(new_list); } /* -------------------------------- file filters -------------------------------- */ #define INITIAL_FILE_FILTERS_SIZE 4 Xen g_expand_vector(Xen vector, int new_size) { int i, len; Xen new_vect; len = Xen_vector_length(vector); new_vect = Xen_make_vector(new_size, Xen_false); Xen_GC_protect(new_vect); for (i = 0; i < len; i++) { Xen_vector_set(new_vect, i, Xen_vector_ref(vector, i)); Xen_vector_set(vector, i, Xen_false); } #if HAVE_RUBY || HAVE_FORTH Xen_GC_unprotect(vector); #endif return(new_vect); } static bool file_filter_ok(Xen name, Xen proc, const char *caller) { char *errmsg; Xen_check_type(Xen_is_string(name), name, 1, caller, "a string"); Xen_check_type(Xen_is_procedure(proc), proc, 2, caller, "a procedure of 1 arg (filename)"); errmsg = procedure_ok(proc, 1, caller, "file filter", 2); if (errmsg) { Xen errstr; errstr = C_string_to_Xen_string(errmsg); free(errmsg); snd_bad_arity_error(caller, errstr, proc); return(false); } return(true); } static Xen g_add_file_filter(Xen name, Xen proc) { #define H_add_file_filter "(" S_add_file_filter " name proc) -- add proc with identifier name to file filter list. \n\ (add-file-filter \"just .snd\" \n\ (lambda (name) \n\ (string=? \".snd\" (substring name (- (length name) 4)))))\n\ restricts the displayed files to .snd files." if (file_filter_ok(name, proc, S_add_file_filter)) { int i, len; len = ss->file_filters_size; for (i = 0; i < len; i++) { if (Xen_is_false(Xen_vector_ref(ss->file_filters, i))) { Xen_vector_set(ss->file_filters, i, Xen_list_2(name, proc)); return(C_int_to_Xen_integer(i)); } } ss->file_filters_size = len * 2; ss->file_filters = g_expand_vector(ss->file_filters, ss->file_filters_size); Xen_vector_set(ss->file_filters, len, Xen_list_2(name, proc)); return(C_int_to_Xen_integer(len)); } return(Xen_false); } static Xen g_delete_file_filter(Xen index) { #define H_delete_file_filter "(" S_delete_file_filter " index) -- delete proc with identifier index from file filter list" int pos; Xen_check_type(Xen_is_integer(index), index, 1, S_delete_file_filter, "a file-filter function index"); pos = Xen_integer_to_C_int(index); if ((pos >= 0) && (pos < ss->file_filters_size)) { #if USE_GTK && (!HAVE_RUBY) /* in the gtk case, the function might be in use anyway, so we need to protect it */ if (Xen_is_list(Xen_vector_ref(ss->file_filters, pos))) Xen_GC_protect(Xen_cadr(Xen_vector_ref(ss->file_filters, pos))); /* in ruby Xen_GC_protect takes the address of the arg, so we need a variable or something */ #endif Xen_vector_set(ss->file_filters, pos, Xen_false); } return(index); } /* -------------------------------- directory readers -------------------------------- */ static dir_info *make_dir_info(const char *name) { dir_info *dp; dp = (dir_info *)calloc(1, sizeof(dir_info)); dp->files = (sort_info **)calloc(32, sizeof(sort_info *)); dp->dir_name = mus_strdup(name); dp->len = 0; dp->size = 32; return(dp); } static sort_info *make_sort_info(const char *filename, const char *full_filename) { sort_info *ptr; ptr = (sort_info *)calloc(1, sizeof(sort_info)); ptr->filename = mus_strdup(filename); /* not mus_strdup -> these are glomming up memlog */ ptr->full_filename = mus_strdup(full_filename); return(ptr); } static sort_info *free_sort_info(sort_info *ptr) { if (ptr) { if (ptr->filename) free(ptr->filename); if (ptr->full_filename) free(ptr->full_filename); free(ptr); } return(NULL); } dir_info *free_dir_info(dir_info *dp) { if (dp->dir_name) free(dp->dir_name); if (dp->files) { int i; for (i = 0; i < dp->len; i++) if (dp->files[i]) dp->files[i] = free_sort_info(dp->files[i]); free(dp->files); } free(dp); return(NULL); } static void add_filename_to_dir_info(dir_info *dp, const char *name, const char *fullname) { dp->files[dp->len] = make_sort_info(name, fullname); dp->len++; if (dp->len == dp->size) { int i; dp->size += 32; dp->files = (sort_info **)realloc(dp->files, dp->size * sizeof(sort_info *)); for (i = dp->size - 32; i < dp->size; i++) dp->files[i] = NULL; } } static void load_dir(DIR *dpos, dir_info *dp, bool (*filter)(const char *filename)) { struct dirent *dirp; char *fullname; int fullname_start = 0, path_max = 0; #ifndef _MSC_VER path_max = pathconf("/", _PC_PATH_MAX); #endif if (path_max < 1024) { #if defined(PATH_MAX) path_max = PATH_MAX; #endif if (path_max < 1024) path_max = 1024; } fullname = (char *)calloc(path_max, sizeof(char)); strcopy(fullname, dp->dir_name, path_max); fullname_start = strlen(dp->dir_name); while ((dirp = readdir(dpos)) != NULL) if (dirp->d_name[0] != '.') { strcat(fullname, dirp->d_name); if (filter(fullname)) add_filename_to_dir_info(dp, dirp->d_name, fullname); fullname[fullname_start] = '\0'; } free(fullname); } static bool not_is_directory(const char *name) { return(!(is_directory(name))); } dir_info *find_files_in_dir(const char *name) { #ifdef _MSC_VER return(NULL); #else DIR *dpos; dir_info *dp = NULL; dpos = opendir(name); if (dpos) { dp = make_dir_info(name); load_dir(dpos, dp, not_is_directory); if (closedir(dpos) != 0) snd_error("closedir %s failed (%s)!", name, snd_io_strerror()); } return(dp); #endif } static Xen filter_func; static bool filter_xen(const char *name) { return(Xen_boolean_to_C_bool(Xen_call_with_1_arg(filter_func, C_string_to_Xen_string(name), "filter func"))); } dir_info *find_filtered_files_in_dir(const char *name, int filter_choice) { #ifdef _MSC_VER return(NULL); #else DIR *dpos; dir_info *dp = NULL; if ((dpos = opendir(name)) != NULL) { bool (*filter)(const char *filename); if (filter_choice == JUST_SOUNDS_FILTER) filter = is_sound_file; else { int filter_pos; filter = filter_xen; filter_pos = filter_choice - 2; if ((filter_pos >= 0) && (filter_pos < ss->file_filters_size)) filter_func = Xen_cadr(Xen_vector_ref(ss->file_filters, filter_pos)); else { snd_warning("no such file-filter (%d)", filter_pos); closedir(dpos); return(find_files_in_dir(name)); } } dp = make_dir_info(name); load_dir(dpos, dp, filter); if (closedir(dpos) != 0) snd_error("closedir %s failed (%s)!", name, snd_io_strerror()); } return(dp); #endif } static dir_info *find_files_from_pattern(dir_info *dp, const char *pattern); dir_info *find_filtered_files_in_dir_with_pattern(const char *name, int filter_choice, const char *pattern) { dir_info *full_dir, *pattern_dir; if (filter_choice != NO_FILE_FILTER) full_dir = find_filtered_files_in_dir(name, filter_choice); else full_dir = find_files_in_dir(name); pattern_dir = find_files_from_pattern(full_dir, pattern); free_dir_info(full_dir); return(pattern_dir); } /* -------- sound file extensions list -------- */ static char **sound_file_extensions = NULL; static int sound_file_extensions_size = 0; static int sound_file_extensions_end = 0; static int default_sound_file_extensions = 0; const char **get_sound_file_extensions(void) {return((const char **)sound_file_extensions);} int sound_file_extensions_length(void) {return(sound_file_extensions_end);} static void add_sound_file_extension(const char *ext) { int i; if ((!ext) || (!(*ext))) return; for (i = 0; i < sound_file_extensions_end; i++) if (strcmp(ext, sound_file_extensions[i]) == 0) return; if (sound_file_extensions_end == sound_file_extensions_size) { sound_file_extensions_size += 8; if (sound_file_extensions == NULL) sound_file_extensions = (char **)calloc(sound_file_extensions_size, sizeof(char *)); else sound_file_extensions = (char **)realloc(sound_file_extensions, sound_file_extensions_size * sizeof(char *)); } sound_file_extensions[sound_file_extensions_end] = mus_strdup(ext); sound_file_extensions_end++; } void init_sound_file_extensions(void) { add_sound_file_extension("snd"); add_sound_file_extension("aiff"); add_sound_file_extension("aif"); add_sound_file_extension("wav"); add_sound_file_extension("WAV"); add_sound_file_extension("au"); add_sound_file_extension("aifc"); add_sound_file_extension("voc"); add_sound_file_extension("wve"); add_sound_file_extension("sf2"); add_sound_file_extension("rf64"); add_sound_file_extension("caf"); #if HAVE_OGG add_sound_file_extension("ogg"); #endif #if HAVE_SPEEX add_sound_file_extension("speex"); /* ?? */ #endif #if HAVE_FLAC add_sound_file_extension("flac"); #endif #if HAVE_MIDI add_sound_file_extension("mid"); #endif #if HAVE_MPEG add_sound_file_extension("mpeg"); add_sound_file_extension("mp3"); #endif #if HAVE_TTA add_sound_file_extension("tta"); #endif #if HAVE_WAVPACK add_sound_file_extension("wv"); #endif default_sound_file_extensions = sound_file_extensions_end; } void save_added_sound_file_extensions(FILE *fd) { int i; if (sound_file_extensions_end > default_sound_file_extensions) for (i = default_sound_file_extensions; i < sound_file_extensions_end; i++) { #if HAVE_SCHEME fprintf(fd, "(%s \"%s\")\n", S_add_sound_file_extension, sound_file_extensions[i]); #endif #if HAVE_RUBY fprintf(fd, "%s(\"%s\")\n", to_proc_name(S_add_sound_file_extension), sound_file_extensions[i]); #endif #if HAVE_FORTH fprintf(fd, "\"%s\" %s drop\n", sound_file_extensions[i], S_add_sound_file_extension); #endif } } /* mus_header_read here (or stripped-down equivalent) was very slow, and is just as easy to * fool as an extension check (file might start with the word ".snd" or whatever). */ bool is_sound_file(const char *name) { int i, dot_loc = -1, len; if (!name) return(false); len = mus_strlen(name); for (i = 0; i < len; i++) if (name[i] == '.') dot_loc = i; /* dot_loc is last dot in the name */ if ((dot_loc > 0) && (dot_loc < len - 1)) { const char *ext; ext = (const char *)(name + dot_loc + 1); for (i = 0; i < sound_file_extensions_end; i++) if (mus_strcmp(ext, sound_file_extensions[i])) return(true); } return(false); } static bool names_match(const char *filename, const char *pattern) { /* just "*" for wildcards here */ const char *sn, *sp; sn = filename; sp = pattern; if ((!sn) || (!sp)) { if ((sn) || (sp)) return(false); else return(true); } while ((*sn) && (*sp)) { if ((*sp) == '*') { sp++; while ((*sp) == '*') sp++; if (!(*sp)) return(true); while ((*sn) && ((*sn) != (*sp))) sn++; if (!(*sn)) return(false); } else { if ((*sn) != (*sp)) return(false); sn++; sp++; } } return(true); } static dir_info *find_files_from_pattern(dir_info *dp, const char *pattern) { int i; dir_info *ndp; ndp = make_dir_info(dp->dir_name); for (i = 0; i < dp->len; i++) if (names_match(dp->files[i]->filename, pattern)) add_filename_to_dir_info(ndp, dp->files[i]->filename, dp->files[i]->full_filename); return(ndp); } /* -------------------------------- Snd title (lists open sounds) -------------------------------- */ typedef struct { int active_sounds; char **names; int *sounds; } active_sound_list; static void add_sound_to_active_list(snd_info *sp, void *sptr1) { active_sound_list *sptr = (active_sound_list *)sptr1; sptr->names[sptr->active_sounds] = sp->filename; sptr->sounds[sptr->active_sounds] = sp->index; (sptr->active_sounds)++; } void reflect_file_change_in_title(void) { char *title_buffer = NULL; active_sound_list *alist; int i, j, len; alist = (active_sound_list *)calloc(1, sizeof(active_sound_list)); alist->sounds = (int *)calloc(ss->max_sounds, sizeof(int)); alist->names = (char **)calloc(ss->max_sounds, sizeof(char *)); for_each_sound_with_void(add_sound_to_active_list, (void *)alist); len = mus_strlen(ss->startup_title) + 32; if (alist->active_sounds > 0) { if (alist->active_sounds < 4) j = alist->active_sounds; else j = 4; for (i = 0; i < j; i++) len += mus_strlen(filename_without_directory(alist->names[i])); } title_buffer = (char *)calloc(len, sizeof(char)); snprintf(title_buffer, len, "%s%s", ss->startup_title, ((alist->active_sounds > 0) ? ": " : "")); if (alist->active_sounds > 0) { if (alist->active_sounds < 4) j = alist->active_sounds; else j = 4; for (i = 0; i < j; i++) { strcat(title_buffer, filename_without_directory(alist->names[i])); if (i < j - 1) strcat(title_buffer, ", "); } if (alist->active_sounds > 4) strcat(title_buffer, "..."); } set_title(title_buffer); free(title_buffer); free(alist->sounds); free(alist->names); free(alist); } /* -------------------------------- open sound file -------------------------------- */ static int fallback_srate = 0, fallback_chans = 0; static mus_sample_t fallback_sample_type = MUS_UNKNOWN_SAMPLE; static int original_srate = 0, original_chans = 0; static mus_sample_t original_sample_type = MUS_UNKNOWN_SAMPLE; void set_fallback_srate(int sr) {fallback_srate = sr;} void set_fallback_chans(int ch) {fallback_chans = ch;} void set_fallback_sample_type(mus_sample_t fr) {fallback_sample_type = fr;} static file_info *make_file_info_1(const char *fullname) { file_info *hdr; hdr = (file_info *)calloc(1, sizeof(file_info)); hdr->name = mus_strdup(fullname); hdr->type = mus_sound_header_type(fullname); if (hdr->type == MUS_RAW) mus_header_raw_defaults(&(hdr->srate), &(hdr->chans), &(hdr->sample_type)); else { hdr->srate = mus_sound_srate(fullname); original_srate = hdr->srate; hdr->chans = mus_sound_chans(fullname); original_chans = hdr->chans; hdr->sample_type = mus_sound_sample_type(fullname); original_sample_type = hdr->sample_type; } if (!(mus_is_sample_type(hdr->sample_type))) hdr->sample_type = fallback_sample_type; if (hdr->srate <= 0) {if (fallback_srate > 0) hdr->srate = fallback_srate; else hdr->srate = 1;} if (hdr->chans <= 0) {if (fallback_chans > 0) hdr->chans = fallback_chans; else hdr->chans = 1;} hdr->samples = mus_sound_samples(fullname); /* total samples, not per channel */ if ((hdr->samples == 0) && (hdr->chans > 128)) { snd_warning("no samples, but %d chans?", hdr->chans); hdr->chans = 1; } hdr->data_location = mus_sound_data_location(fullname); hdr->comment = mus_sound_comment(fullname); hdr->loops = mus_sound_loop_info(fullname); return(hdr); } file_info *copy_header(const char *fullname, file_info *ohdr) { file_info *hdr; hdr = (file_info *)calloc(1, sizeof(file_info)); hdr->name = mus_strdup(fullname); hdr->comment = NULL; if (ohdr) { hdr->samples = ohdr->samples; hdr->data_location = ohdr->data_location; hdr->srate = ohdr->srate; hdr->chans = ohdr->chans; hdr->sample_type = ohdr->sample_type; hdr->type = ohdr->type; if (ohdr->loops) { int i; hdr->loops = (int *)calloc(MUS_LOOP_INFO_SIZE, sizeof(int)); for (i = 0; i < MUS_LOOP_INFO_SIZE; i++) hdr->loops[i] = ohdr->loops[i]; } } return(hdr); } static file_info *translate_file(const char *filename, mus_header_t type) { file_info *hdr = NULL; char *newname; int *loops = NULL; int err, len, fd; len = strlen(filename); loops = mus_sound_loop_info(filename); /* allocated anew */ newname = (char *)calloc(len + 5, sizeof(char)); snprintf(newname, len + 5, "%s.snd", filename); /* too many special cases to do anything smart here -- I'll just tack on '.snd' */ /* before calling the translator we need to check for write-access to the current directory, * and if none, try to find a temp directory we can write to. * * loop info across translation: 4-Dec-01 */ fd = CREAT(newname, 0666); if (fd == -1) { char *tempname; tempname = snd_tempnam(); fd = CREAT(tempname, 0666); if (fd == -1) { if (loops) free(loops); free(newname); free(tempname); snd_error("can't write translation temp file! (%s)", snd_open_strerror()); return(NULL); } free(newname); newname = mus_strdup(tempname); free(tempname); } snd_close(fd, newname); err = snd_translate(filename, newname, type); if (err == MUS_NO_ERROR) { err = mus_header_read(newname); if (err == MUS_NO_ERROR) { hdr = make_file_info_1(newname); if (hdr->loops == NULL) hdr->loops = loops; else if (loops) free(loops); loops = NULL; ss->translated_filename = mus_strdup(newname); } } else snd_remove(newname, REMOVE_FROM_CACHE); if (newname) free(newname); if (loops) free(loops); return(hdr); } static Xen open_raw_sound_hook; static file_info *open_raw_sound(const char *fullname, read_only_t read_only, bool selected) { Xen res = Xen_false; int res_loc = NOT_A_GC_LOC; int srate, chans; mus_sample_t sample_type; if (ss->reloading_updated_file != 0) { /* choices already made, so just send back a header that reflects those choices */ return(make_file_info_1(fullname)); } if (Xen_hook_has_list(open_raw_sound_hook)) { #if HAVE_SCHEME res = s7_call(s7, open_raw_sound_hook, s7_list(s7, 2, C_string_to_Xen_string(fullname), Xen_false)); /* state = #f? */ #else Xen arg1, procs; procs = Xen_hook_list(open_raw_sound_hook); arg1 = C_string_to_Xen_string(fullname); while (!Xen_is_null(procs)) { res = Xen_call_with_2_args(Xen_car(procs), arg1, res, S_open_raw_sound_hook); if (res_loc != NOT_A_GC_LOC) snd_unprotect_at(res_loc); res_loc = snd_protect(res); procs = Xen_cdr(procs); } #endif } if (Xen_is_list(res)) /* empty list ok here -> accept all current defaults */ { file_info *hdr; mus_long_t data_location, bytes; int len; len = Xen_list_length(res); mus_header_raw_defaults(&srate, &chans, &sample_type); if (len > 0) chans = Xen_integer_to_C_int(Xen_car(res)); if (len > 1) srate = Xen_integer_to_C_int(Xen_cadr(res)); if (len > 2) { Xen df; df = Xen_list_ref(res, 2); sample_type = (mus_sample_t)Xen_integer_to_C_int(df); } if (len > 3) data_location = Xen_llong_to_C_llong(Xen_list_ref(res, 3)); else data_location = 0; if (len > 4) bytes = Xen_llong_to_C_llong(Xen_list_ref(res, 4)); else bytes = mus_sound_length(fullname) - data_location; mus_header_set_raw_defaults(srate, chans, sample_type); mus_sound_override_header(fullname, srate, chans, sample_type, MUS_RAW, data_location, mus_bytes_to_samples(sample_type, bytes)); if (res_loc != NOT_A_GC_LOC) snd_unprotect_at(res_loc); hdr = (file_info *)calloc(1, sizeof(file_info)); hdr->name = mus_strdup(fullname); hdr->type = MUS_RAW; hdr->srate = mus_sound_srate(fullname); hdr->chans = mus_sound_chans(fullname); hdr->sample_type = mus_sound_sample_type(fullname); hdr->samples = mus_sound_samples(fullname); /* total samples, not per channel */ if ((hdr->samples == 0) && (hdr->chans > 8)) { snd_warning("no samples, but %d chans?", hdr->chans); hdr->chans = 1; } hdr->data_location = mus_sound_data_location(fullname); hdr->comment = NULL; return(hdr); } else { bool just_quit = false; if (Xen_is_true(res)) just_quit = true; if (res_loc != NOT_A_GC_LOC) snd_unprotect_at(res_loc); if (just_quit) return(NULL); /* open-sound and view-sound do not fall into the raw data dialog */ if ((ss->open_requestor == FROM_OPEN_SOUND) || (ss->open_requestor == FROM_VIEW_SOUND) || (ss->open_requestor == FROM_NEW_SOUND) || (ss->open_requestor == FROM_NEW_FILE_DIALOG)) return(make_file_info_1(fullname)); #if (!USE_NO_GUI) { char *str; str = (char *)calloc(PRINT_BUFFER_SIZE, sizeof(char)); snprintf(str, PRINT_BUFFER_SIZE, "No header found for %s", filename_without_directory(fullname)); raw_data_dialog_to_file_info(fullname, str, NULL, read_only, selected); /* dialog frees str */ } #else fprintf(stderr, "No header found for %s", filename_without_directory(fullname)); #endif } return(NULL); } #if (!USE_NO_GUI) static char *raw_data_explanation(const char *filename, file_info *hdr, char **info); #endif static Xen bad_header_hook; static file_info *tackle_bad_header(const char *fullname, read_only_t read_only, bool selected) { /* messed up header */ if ((Xen_hook_has_list(bad_header_hook)) && (Xen_is_true(run_or_hook(bad_header_hook, Xen_list_1(C_string_to_Xen_string(fullname)), S_bad_header_hook)))) return(NULL); /* if not from dialog, throw an error ('bad-header) */ if ((ss->open_requestor == FROM_OPEN_SOUND) || (ss->open_requestor == FROM_VIEW_SOUND) || (ss->open_requestor == FROM_NEW_SOUND)) /* this case should not happen! */ { const char *caller; if (ss->open_requestor == FROM_OPEN_SOUND) caller = S_open_sound; else caller = S_view_sound; Xen_error(BAD_HEADER, Xen_list_3(C_string_to_Xen_string("~A: ~S has a bad header?"), C_string_to_Xen_string(caller), C_string_to_Xen_string(fullname))); return(NULL); } #if (!USE_NO_GUI) { mus_header_t type; type = mus_header_type(); if ((type != MUS_MIDI_SAMPLE_DUMP) && (type != MUS_IEEE) && (type != MUS_MUS10) && (type != MUS_HCOM) && (!(header_is_encoded(type)))) { char *info = NULL, *title = NULL; title = raw_data_explanation(fullname, make_file_info_1(fullname), &info); raw_data_dialog_to_file_info(fullname, title, info, read_only, selected); } } #endif return(NULL); } file_info *make_file_info(const char *fullname, read_only_t read_only, bool selected) { file_info *hdr = NULL; if (mus_file_probe(fullname)) { mus_header_t type = MUS_UNKNOWN_HEADER; /* open-raw-sound will force it to viewed as a raw sound */ if (ss->open_requestor == FROM_OPEN_RAW_SOUND) return(make_file_info_1(fullname)); type = mus_sound_header_type(fullname); if (type == MUS_UNKNOWN_HEADER) /* if something went wrong */ type = mus_header_type(); /* try to read it anyway... */ /* handle some files directly through the translator (headers here are not readable) */ if ((type == MUS_MIDI_SAMPLE_DUMP) || (type == MUS_IEEE) || (type == MUS_MUS10) || (type == MUS_HCOM) || (header_is_encoded(type))) { return(translate_file(fullname, type)); } if (mus_is_header_type(type)) { /* at least the header type seems plausible */ /* check header fields */ int sr = 0, ch = 0; sr = mus_sound_srate(fullname); ch = mus_sound_chans(fullname); if ((fallback_srate > 0) && ((sr <= 0) || (sr > 100000000))) sr = fallback_srate; if ((fallback_chans > 0) && ((ch >= 256) || (ch <= 0))) ch = fallback_chans; if ((sr <= 0) || (sr > 100000000) || (ch >= 256) || (ch <= 0)) return(tackle_bad_header(fullname, read_only, selected)); /* header is ok */ if (type == MUS_RAW) return(open_raw_sound(fullname, read_only, selected)); else { mus_sample_t sample_type; sample_type = mus_sound_sample_type(fullname); if (mus_is_sample_type(sample_type)) return(make_file_info_1(fullname)); return(translate_file(fullname, type)); } } else snd_error("%s does not seem to be a sound file?", fullname); /* no known header */ } else snd_error("can't find file %s: %s", fullname, snd_io_strerror()); return(hdr); } file_info *make_temp_header(const char *fullname, int srate, int chans, mus_long_t samples, const char *caller) { file_info *hdr; hdr = (file_info *)calloc(1, sizeof(file_info)); hdr->name = mus_strdup(fullname); hdr->samples = samples; hdr->data_location = 28; hdr->srate = srate; hdr->chans = chans; hdr->sample_type = MUS_OUT_SAMPLE_TYPE; hdr->type = MUS_NEXT; /* want direct read/writes for temp files */ hdr->comment = mus_strdup(caller); return(hdr); } file_info *free_file_info(file_info *hdr) { if (hdr) { if (hdr->name) free(hdr->name); if (hdr->comment) free(hdr->comment); if (hdr->loops) free(hdr->loops); free(hdr); } return(NULL); } static char *opened_sound_file_name(snd_info *sp) { char *newname; int len; len = strlen(sp->filename); newname = (char *)calloc(len + 32, sizeof(char)); snprintf(newname, len + 32, "%s.%s", sp->filename, Xen_file_extension); return(newname); } static char *remembered_sound_file_name(snd_info *sp) { char *newname; int len; len = strlen(sp->filename); newname = (char *)calloc(len + 32, sizeof(char)); snprintf(newname, len + 32, "remembered-%s.%s", sp->short_filename, Xen_file_extension); return(newname); } static void load_sound_file_extras(snd_info *sp) { char *newname; /* possible sound.scm file */ newname = opened_sound_file_name(sp); if (file_write_date(newname) >= sp->write_date) snd_load_file(newname); free(newname); /* remembered-sound.scm -- this is written if remember-sound-state which will also overwrite it */ if (remember_sound_state(ss)) { newname = remembered_sound_file_name(sp); if (file_write_date(newname) >= sp->write_date) snd_load_file(newname); free(newname); } } static void remember_sound_file(snd_info *sp) { char *newname; FILE *fd; newname = remembered_sound_file_name(sp); fd = FOPEN(newname, "w"); if (fd == NULL) { snd_error("remember sound state can't write %s: %s", newname, snd_io_strerror()); return; } sp->remembering = true; save_sound_state(sp, fd); sp->remembering = false; snd_fclose(fd, newname); free(newname); } static Xen snd_opened_sound; static Xen open_hook; static Xen close_hook; static Xen before_close_hook; static Xen during_open_hook; static Xen after_open_hook; void during_open(int fd, const char *file, open_reason_t reason) { if (Xen_hook_has_list(during_open_hook)) run_hook(during_open_hook, Xen_list_3(C_int_to_Xen_integer(fd), C_string_to_Xen_string(file), C_int_to_Xen_integer((int)reason)), S_during_open_hook); } void after_open(snd_info *sp) { /* the sync-style choice used to be handled via after-open-hook in extensions.*, but 15-Feb-11 has * been moved into the main Snd. So here is the code... */ if (sp->nchans > 1) { switch (sync_style(ss)) { case SYNC_NONE: sp->sync = 0; break; case SYNC_ALL: sp->sync = 1; break; case SYNC_BY_SOUND: ss->sound_sync_max++; sp->sync = ss->sound_sync_max; /* if we had used (set! (sync) ...) this would be set (via syncb) to the new max */ break; } } else sp->sync = 0; syncb(sp, sp->sync); if (Xen_hook_has_list(after_open_hook)) run_hook(after_open_hook, Xen_list_1(C_int_to_Xen_sound(sp->index)), S_after_open_hook); if (Xen_hook_has_list(ss->snd_open_file_hook)) run_hook(ss->snd_open_file_hook, Xen_list_1(C_int_to_Xen_integer(FILE_OPENED)), "open-file-hook"); if (Xen_hook_has_list(ss->effects_hook)) run_hook(ss->effects_hook, Xen_empty_list, S_effects_hook); } snd_info *finish_opening_sound(snd_info *sp, bool selected) { if (sp) { #if HAVE_RUBY || HAVE_FORTH Xen_variable_set(S_snd_opened_sound, C_int_to_Xen_sound(sp->index)); #endif #if HAVE_SCHEME Xen_variable_set(snd_opened_sound, C_int_to_Xen_sound(sp->index)); #endif sp->write_date = file_write_date(sp->filename); /* redundant (see snd-xsnd.c) */ sp->need_update = false; ss->active_sounds++; reflect_file_change_in_title(); monitor_sound(sp); } for_each_separate_chan(channel_open_pane); #if USE_MOTIF for_each_separate_chan(channel_unlock_pane); #endif if (sp) { add_srate_to_completion_list(snd_srate(sp)); if ((selected) && (sp->active) && (sp->inuse == SOUND_NORMAL)) select_channel(sp, 0); load_sound_file_extras(sp); if ((sp->channel_style != CHANNELS_SEPARATE) && (sp->nchans > 1)) { channel_style_t val; val = sp->channel_style; sp->channel_style = CHANNELS_SEPARATE; if (val == CHANNELS_COMBINED) combine_sound(sp); else superimpose_sound(sp); } } return(sp); } /* (hook-push open-hook (lambda (f) (display f) #f)) */ snd_info *snd_open_file(const char *filename, read_only_t read_only) { file_info *hdr; snd_info *sp; static char *mcf = NULL; if (mcf) free(mcf); mcf = mus_expand_filename(filename); if (Xen_hook_has_list(open_hook)) { Xen res, fstr; fstr = C_string_to_Xen_string(mcf); res = run_or_hook(open_hook, Xen_list_1(fstr), S_open_hook); if (Xen_is_true(res)) { if (mcf) {free(mcf); mcf = NULL;} return(NULL); } else { if (Xen_is_string(res)) /* added 14-Aug-01 for user-supplied auto-translations */ { if (mcf) free(mcf); mcf = mus_expand_filename(Xen_string_to_C_string(res)); } } } hdr = make_file_info(mcf, read_only, FILE_SELECTED); if (!hdr) { if (mcf) {free(mcf); mcf = NULL;} return(NULL); } sp = add_sound_window(mcf, read_only, hdr); if (mcf) {free(mcf); mcf = NULL;} return(finish_opening_sound(sp, FILE_SELECTED)); } void snd_close_file(snd_info *sp) { int i; Xen res = Xen_false; snd_info *chosen_sp = NULL; /* before-close-hook can cancel the close, whereas close-hook can't */ if (Xen_hook_has_list(before_close_hook)) res = run_or_hook(before_close_hook, Xen_list_1(C_int_to_Xen_sound(sp->index)), S_before_close_hook); if (Xen_is_true(res)) return; #if (!USE_NO_GUI) if ((ask_about_unsaved_edits(ss)) && (has_unsaved_edits(sp))) { save_edits_now(sp); return; } unpost_unsaved_edits_if_any(sp); unpost_file_has_changed_if_any(sp); #endif if (peak_env_dir(ss)) map_over_sound_chans(sp, write_peak_env_info_file); if (Xen_hook_has_list(close_hook)) run_hook(close_hook, Xen_list_1(C_int_to_Xen_sound(sp->index)), S_close_hook); if (remember_sound_state(ss)) remember_sound_file(sp); remember_filename(sp->filename, preloaded_files); /* for open dialog(s) previous files list and File:open recent files menu */ /* an experiment -- event queue seems to be glomming up when lots of fast open/close, * but squelch updates just in case a redisplay event is in the queue. But check_for_event * here is dangerous because a channel might be closed and deallocated already, then * this check lets a mouse event through, cp->axis is NULL, cp->active has been stomped on, * segfault! */ for (i = 0; i < sp->nchans; i++) sp->chans[i]->squelch_update = true; /* check_for_event(); */ sp->file_watcher = unmonitor_file(sp->file_watcher); /* exit does not go through this function to clean up temps -- see snd_exit_cleanly in snd-main.c */ if (selection_creation_in_progress()) finish_selection_creation(); if (ss->deferred_regions > 0) for (i = 0; i < sp->nchans; i++) if (sp->chans[i]) sequester_deferred_regions(sp->chans[i], -1); sp->inuse = SOUND_IDLE; if (sp->playing) stop_playing_sound(sp, PLAY_CLOSE); #if (!USE_NO_GUI) sp->inuse = SOUND_NORMAL; /* needed to make sure the status area is actually cleared in set_status */ set_status(sp, NULL, false); /* false = don't try to update graphs! */ sp->inuse = SOUND_IDLE; #endif if ((sp == selected_sound()) && (!(ss->exiting))) { int i, curmax = -1; /* look for the last selected sound, if any */ for (i = 0; i < ss->max_sounds; i++) { snd_info *nsp; nsp = ss->sounds[i]; if ((nsp) && (nsp->inuse == SOUND_NORMAL) && (nsp != sp) && (nsp->active) && (nsp->selectpos > curmax)) { curmax = nsp->selectpos; chosen_sp = nsp; } } } /* if sequester_deferred_regions is in free_snd_info (moved up to this level 15-12-03) * If the sound is set to SOUND_IDLE, the init function returns 'no-such-sound, and the * subsequent read segfaults. */ free_snd_info(sp); ss->active_sounds--; reflect_file_change_in_title(); enved_reflect_selection(selection_is_active()); reflect_selection_in_save_as_dialog(selection_is_active()); if (Xen_hook_has_list(ss->snd_open_file_hook)) run_hook(ss->snd_open_file_hook, Xen_list_1(C_int_to_Xen_integer(FILE_CLOSED)), "open-file-hook"); if (Xen_hook_has_list(ss->effects_hook)) run_hook(ss->effects_hook, Xen_empty_list, S_effects_hook); if (chosen_sp) select_channel(chosen_sp, 0); else { if (sp == selected_sound()) ss->selected_sound = NO_SELECTION; if ((!(ss->exiting)) && (any_selected_sound() == NULL)) /* I hope this can't be fooled... */ reset_mix_ctr(); } reflect_save_as_sound_selection(NULL); } #define TEMP_SOUND_INDEX 123456 /* just a marker for debugging -- but it actually appears in things like start-playing-hook! */ snd_info *make_sound_readable(const char *filename, bool post_close) { /* conjure up just enough Snd structure to make this sound readable by the edit-tree readers */ snd_info *sp; chan_info *cp; file_info *hdr = NULL; int i; mus_long_t len; /* we've already checked that filename exists */ hdr = make_file_info_1(filename); sp = make_basic_snd_info(hdr->chans); sp->nchans = hdr->chans; sp->hdr = hdr; sp->inuse = SOUND_READER; initialize_control_panel(sp); sp->index = TEMP_SOUND_INDEX; len = (hdr->samples) / (hdr->chans); for (i = 0; i < sp->nchans; i++) { int fd; cp = make_chan_info(NULL, i, sp); cp->editable = false; free(cp->ax); cp->ax = NULL; sp->chans[i] = cp; add_channel_data_1(cp, hdr->srate, len, WITHOUT_GRAPH); fd = snd_open_read(filename); /* sends the error if any */ if (fd != -1) set_up_snd_io(cp, i, fd, filename, hdr, post_close); } sp->active = true; return(sp); } axes_data *free_axes_data(axes_data *sa) { if (sa) { if (sa->axis_data) {free(sa->axis_data); sa->axis_data = NULL;} if (sa->fftp) {free(sa->fftp); sa->fftp = NULL;} if (sa->wavep) {free(sa->wavep); sa->wavep = NULL;} free(sa); } return(NULL); } enum {SA_X0, SA_X1, SA_Y0, SA_Y1, SA_XMIN, SA_XMAX, SA_YMIN, SA_YMAX, SA_ZX, SA_ZY, SA_SX, SA_SY, SA_GSY, SA_GZY}; #define SA_FIELDS 14 axes_data *make_axes_data(snd_info *sp) { axes_data *sa; int i; sa = (axes_data *)calloc(1, sizeof(axes_data)); sa->chans = sp->nchans; sa->fields = SA_FIELDS; sa->axis_data = (double *)calloc(sa->fields * sa->chans, sizeof(double)); sa->fftp = (bool *)calloc(sa->chans, sizeof(bool)); sa->wavep = (bool *)calloc(sa->chans, sizeof(bool)); for (i = 0; i < sa->chans; i++) { chan_info *cp; axis_info *ap; int loc; cp = sp->chans[i]; ap = cp->axis; loc = i * sa->fields; sa->axis_data[loc + SA_X0] = ap->x0; sa->axis_data[loc + SA_X1] = ap->x1; sa->axis_data[loc + SA_Y0] = ap->y0; sa->axis_data[loc + SA_Y1] = ap->y1; sa->axis_data[loc + SA_XMIN] = ap->xmin; sa->axis_data[loc + SA_XMAX] = ap->xmax; sa->axis_data[loc + SA_YMIN] = ap->ymin; sa->axis_data[loc + SA_YMAX] = ap->ymax; sa->axis_data[loc + SA_ZX] = ap->zx; sa->axis_data[loc + SA_SX] = ap->sx; sa->axis_data[loc + SA_ZY] = ap->zy; sa->axis_data[loc + SA_SY] = ap->sy; sa->axis_data[loc + SA_GSY] = cp->gsy; sa->axis_data[loc + SA_GZY] = cp->gzy; sa->wavep[i] = cp->graph_time_on; sa->fftp[i] = cp->graph_transform_on; /* unite and sync buttons are being cleared in snd_info_cleanup and explicitly in snd_update * then probably reset in change_channel_style * meanwhile channel_style is saved in copy_snd_info below * but also restored explicitly in snd_update. * but... if unite was off before the update, it seems that it is set on multi-channel files * (via channel_style(ss) which defaults to channels_combined) */ } return(sa); } void restore_axes_data(snd_info *sp, axes_data *sa, mus_float_t new_duration, bool need_edit_history_update) { int i, j; for (i = 0, j = 0; i < sp->nchans; i++) { chan_info *cp; axis_info *ap; int loc; cp = sp->chans[i]; loc = j * sa->fields; if ((show_full_duration(ss)) && (sa->axis_data[loc + SA_X0] == 0.0) && (sa->axis_data[loc + SA_X1] == sa->axis_data[loc + SA_XMAX])) { /* we were viewing the full duration when the update occurred, and show-full-duration is #t, * so show the full new duration. */ sa->axis_data[loc + SA_X1] = new_duration; /* new x1 */ } else { mus_float_t old_duration; /* old duration is x1 - x0 */ old_duration = sa->axis_data[loc + SA_X1] - sa->axis_data[loc + SA_X0]; if (new_duration < sa->axis_data[loc + SA_X0]) /* new duration < old x0 */ sa->axis_data[loc + SA_X0] = new_duration - old_duration; /* try to maintain old window size */ if (sa->axis_data[loc + SA_X0] < 0.0) sa->axis_data[loc + SA_X0] = 0.0; if (new_duration < sa->axis_data[loc + SA_X1]) sa->axis_data[loc + SA_X1] = new_duration; /* new x1 */ } sa->axis_data[loc + SA_XMAX] = new_duration; /* new xmax */ ap = cp->axis; ap->xmin = sa->axis_data[loc + SA_XMIN]; ap->xmax = sa->axis_data[loc + SA_XMAX]; /* zx and sx are reset by set_axes below? */ ap->zx = sa->axis_data[loc + SA_ZX]; ap->sx = sa->axis_data[loc + SA_SX]; ap->x_ambit = ap->xmax - ap->xmin; if (!show_full_range(ss)) { ap->ymin = sa->axis_data[loc + SA_YMIN]; ap->ymax = sa->axis_data[loc + SA_YMAX]; ap->zy = sa->axis_data[loc + SA_ZY]; ap->sy = sa->axis_data[loc + SA_SY]; ap->y_ambit = ap->ymax - ap->ymin; } else { sa->axis_data[loc + SA_Y0] = ap->y0; sa->axis_data[loc + SA_Y1] = ap->y1; } cp->gzy = sa->axis_data[loc + SA_GZY]; cp->gsy = sa->axis_data[loc + SA_GSY]; set_axes(cp, sa->axis_data[loc + SA_X0], sa->axis_data[loc + SA_X1], sa->axis_data[loc + SA_Y0], sa->axis_data[loc + SA_Y1]); set_z_scrollbars(cp, ap); if ((cp->chan == 0) && (cp->gzy != 1.0)) change_gzy(cp->gzy, cp); /* also fixes gsy slider */ update_graph(cp); /* get normalized state before messing with it */ if (sa->fftp[j]) fftb(cp, true); if (!(sa->wavep[j])) waveb(cp, false); if (need_edit_history_update) reflect_edit_history_change(cp); if (j < (sa->chans - 1)) j++; } } static void copy_chan_info(chan_info *ncp, chan_info *ocp) { ncp->cursor_on = ocp->cursor_on; ncp->cursor_style = ocp->cursor_style; ncp->tracking_cursor_style = ocp->tracking_cursor_style; ncp->cursor_size = ocp->cursor_size; ncp->spectro_x_scale = ocp->spectro_x_scale; ncp->spectro_y_scale = ocp->spectro_y_scale; ncp->spectro_z_scale = ocp->spectro_z_scale; ncp->spectro_z_angle = ocp->spectro_z_angle; ncp->spectro_x_angle = ocp->spectro_x_angle; ncp->spectro_y_angle = ocp->spectro_y_angle; ncp->spectrum_end = ocp->spectrum_end; ncp->spectrum_start = ocp->spectrum_start; ncp->lin_dB = ocp->lin_dB; ncp->min_dB = ocp->min_dB; ncp->fft_window_alpha = ocp->fft_window_alpha; ncp->fft_window_beta = ocp->fft_window_beta; ncp->beats_per_minute = ocp->beats_per_minute; ncp->beats_per_measure = ocp->beats_per_measure; ncp->show_y_zero = ocp->show_y_zero; ncp->show_grid = ocp->show_grid; ncp->grid_density = ocp->grid_density; ncp->show_sonogram_cursor = ocp->show_sonogram_cursor; ncp->show_marks = ocp->show_marks; ncp->wavo_hop = ocp->wavo_hop; ncp->wavo_trace = ocp->wavo_trace; ncp->zero_pad = ocp->zero_pad; ncp->x_axis_style = ocp->x_axis_style; ncp->wavelet_type = ocp->wavelet_type; ncp->with_verbose_cursor = ocp->with_verbose_cursor; ncp->max_transform_peaks = ocp->max_transform_peaks; ncp->show_transform_peaks = ocp->show_transform_peaks; ncp->show_axes = ocp->show_axes; ncp->time_graph_style = ocp->time_graph_style; ncp->lisp_graph_style = ocp->lisp_graph_style; ncp->transform_graph_style = ocp->transform_graph_style; ncp->fft_log_frequency = ocp->fft_log_frequency; ncp->fft_log_magnitude = ocp->fft_log_magnitude; ncp->transform_size = ocp->transform_size; ncp->transform_graph_type = ocp->transform_graph_type; ncp->fft_window = ocp->fft_window; ncp->time_graph_type = ocp->time_graph_type; ncp->dot_size = ocp->dot_size; ncp->transform_normalization = ocp->transform_normalization; ncp->transform_type = ocp->transform_type; ncp->show_mix_waveforms = ocp->show_mix_waveforms; ncp->spectro_hop = ocp->spectro_hop; ncp->graphs_horizontal = ocp->graphs_horizontal; ncp->cursor_proc = ocp->cursor_proc; if (Xen_is_bound(ncp->cursor_proc)) ncp->cursor_proc_loc = snd_protect(ncp->cursor_proc); else ncp->cursor_proc_loc = NOT_A_GC_LOC; } static void copy_snd_info(snd_info *nsp, snd_info *osp) { nsp->speed_control_style = osp->speed_control_style; nsp->speed_control_tones = osp->speed_control_tones; nsp->expand_control_length = osp->expand_control_length; nsp->expand_control_ramp = osp->expand_control_ramp; nsp->expand_control_hop = osp->expand_control_hop; nsp->expand_control_jitter = osp->expand_control_jitter; nsp->contrast_control_amp = osp->contrast_control_amp; nsp->reverb_control_feedback = osp->reverb_control_feedback; nsp->reverb_control_lowpass = osp->reverb_control_lowpass; nsp->reverb_control_decay = osp->reverb_control_decay; nsp->channel_style = osp->channel_style; nsp->sync = osp->sync; } static snd_info *sound_store_chan_info(snd_info *sp) { chan_info **cps; snd_info *nsp; int i; nsp = (snd_info *)calloc(1, sizeof(snd_info)); cps = (chan_info **)calloc(sp->nchans, sizeof(chan_info *)); nsp->chans = cps; nsp->nchans = sp->nchans; copy_snd_info(nsp, sp); for (i = 0; i < sp->nchans; i++) { cps[i] = (chan_info *)calloc(1, sizeof(chan_info)); copy_chan_info(cps[i], sp->chans[i]); } return(nsp); } static void sound_restore_chan_info(snd_info *nsp, snd_info *osp) { int i; chan_info **cps; cps = osp->chans; copy_snd_info(nsp, osp); for (i = 0; i < nsp->nchans; i++) { copy_chan_info(nsp->chans[i], cps[i]); if (Xen_is_bound(cps[i]->cursor_proc)) { snd_unprotect_at(cps[i]->cursor_proc_loc); cps[i]->cursor_proc = Xen_undefined; cps[i]->cursor_proc_loc = NOT_A_GC_LOC; } } } static Xen update_hook; snd_info *snd_update(snd_info *sp) { /* we can't be real smart here because the channel number may have changed and so on */ int i, old_srate, old_chans, sp_chans, old_index, gc_loc = NOT_A_GC_LOC, old_selected_channel = NO_SELECTION; mus_sample_t old_sample_type; channel_style_t old_channel_style; read_only_t read_only; bool old_raw; axes_data *sa; snd_info *nsp = NULL; char *filename; void *ms; snd_info *saved_sp; struct ctrl_state *saved_controls; mus_long_t *old_cursors; void *old_file_watcher; Xen update_hook_result = Xen_false; const char *ur_filename; int app_x, app_y; #if USE_MOTIF int snd_height; snd_height = snd_pane_height(sp); #endif if (sp->edited_region) return(sp); if ((sp->inuse != SOUND_NORMAL) || (!(sp->filename))) return(sp); if (mus_file_probe(sp->filename) == 0) { snd_error("%s no longer exists!", sp->short_filename); return(sp); } app_x = widget_width(MAIN_SHELL(ss)); app_y = widget_height(MAIN_SHELL(ss)); ur_filename = sp->filename; if (peak_env_dir(ss)) for_each_sound_chan(sp, delete_peak_env_info_file); if (with_inset_graph(ss)) for_each_sound_chan(sp, clear_inset_graph); if (Xen_hook_has_list(update_hook)) { /* #t => return without updating (not recommended!!), proc of 1 arg will be evaluated after update is complete */ update_hook_result = run_or_hook(update_hook, Xen_list_1(C_int_to_Xen_sound(sp->index)), S_update_hook); if (Xen_is_true(update_hook_result)) return(sp); if (Xen_is_procedure(update_hook_result)) { if (Xen_is_aritable(update_hook_result, 1)) gc_loc = snd_protect(update_hook_result); else Xen_bad_arity_error(S_update_hook, 0, update_hook_result, S_update_hook " function result should require 1 arg"); } } filename = mus_strdup(ur_filename); read_only = sp->user_read_only; if (sp->nchans > 1) ss->update_sound_channel_style = sp->channel_style; sa = make_axes_data(sp); old_raw = (sp->hdr->type == MUS_RAW); if (old_raw) { mus_header_raw_defaults(&old_srate, &old_chans, &old_sample_type); mus_header_set_raw_defaults(sp->hdr->srate, sp->hdr->chans, sp->hdr->sample_type); } if (sp == selected_sound()) old_selected_channel = sp->selected_channel; sp_chans = sp->nchans; old_index = sp->index; old_channel_style = sp->channel_style; if (sp->channel_style != CHANNELS_SEPARATE) set_sound_channel_style(sp, CHANNELS_SEPARATE); ms = (void *)sound_store_marks(sp); save_controls(sp); saved_controls = sp->saved_controls; sp->saved_controls = NULL; saved_sp = sound_store_chan_info(sp); old_cursors = (mus_long_t *)calloc(sp_chans, sizeof(mus_long_t)); /* peak-env code saves the current peak-envs on exit (snd_close), but in this case, that * data is known to be out-of-date. Since we'll be freeing it eventually anyway, we * do it first here, and the peak-env update-hook clobbers the existing files */ for (i = 0; i < sp_chans; i++) { chan_info *ncp; int k; ncp = sp->chans[i]; old_cursors[i] = cursor_sample(ncp); for (k = 0; k < ncp->edit_size; k++) { ed_list *ed; ed = ncp->edits[k]; if (ed) ed->peak_env = free_peak_env(ncp, k); } } old_file_watcher = sp->file_watcher; /* will be unmonitored in snd_close_file, but we need to know if it is being monitored now */ snd_close_file(sp); /* no mus_sound_forget here because we may be simply re-interpreting the existing data (set! (sample-type) ...) etc */ /* this normalizes the fft/lisp/wave state so we need to reset it after reopen */ #if USE_MOTIF if (!(ss->file_monitor_ok)) alert_new_file(); #endif ss->reloading_updated_file = (old_index + 1); ss->open_requestor = FROM_UPDATE; nsp = snd_open_file(filename, read_only); #if USE_MOTIF XtVaSetValues(w_snd_pane(sp), XmNpaneMinimum, snd_height, XmNpaneMaximum, snd_height, NULL); #endif set_widget_size(MAIN_SHELL(ss), app_x, app_y); /* was at end */ ss->reloading_updated_file = 0; if (old_raw) mus_header_set_raw_defaults(old_srate, old_chans, old_sample_type); if (nsp) { /* if header is bad, nsp can be null awaiting raw data dialog's return */ if ((old_file_watcher) && (!(nsp->file_watcher))) monitor_sound(nsp); /* might be a different sp as well as underlying file */ nsp->saved_controls = saved_controls; if (saved_controls) restore_controls(nsp); if (nsp->nchans == sp_chans) sound_restore_chan_info(nsp, saved_sp); if ((old_selected_channel != NO_SELECTION) && (old_selected_channel < nsp->nchans) && (nsp == selected_sound())) select_channel(nsp, old_selected_channel); restore_axes_data(nsp, sa, mus_sound_duration(filename), false); sound_restore_marks(nsp, ms); for (i = 0; (i < nsp->nchans) && (i < sp_chans); i++) cursor_sample(nsp->chans[i]) = old_cursors[i]; if ((nsp->nchans > 1) && (old_channel_style != CHANNELS_SEPARATE)) /* we set it to separate before the update */ set_sound_channel_style(nsp, old_channel_style); } free(old_cursors); if (Xen_is_procedure(update_hook_result)) { Xen_call_with_1_arg(update_hook_result, (nsp) ? C_int_to_Xen_sound(nsp->index) : Xen_false, "procedure returned by " S_update_hook); if (gc_loc != NOT_A_GC_LOC) snd_unprotect_at(gc_loc); } if (saved_sp) { for (i = 0; i < saved_sp->nchans; i++) if (saved_sp->chans[i]) free(saved_sp->chans[i]); free(saved_sp->chans); free(saved_sp); } free_axes_data((axes_data *)sa); free(filename); #if USE_MOTIF XtVaSetValues(w_snd_pane(sp), XmNpaneMinimum, 1, XmNpaneMaximum, LOTSA_PIXELS, NULL); #endif return(nsp); } static void snd_update_warning_handler(const char *msg, void *data) { set_status((snd_info *)data, msg, false); } static void snd_update_error_handler(const char *msg, void *data) { redirect_snd_error_to(NULL, NULL); redirect_snd_warning_to(NULL, NULL); Xen_error(CANT_UPDATE_FILE, Xen_list_3(C_string_to_Xen_string("~A: ~A"), C_string_to_Xen_string((char *)data), C_string_to_Xen_string(msg))); } snd_info *snd_update_within_xen(snd_info *sp, const char *caller) { snd_info *nsp; redirect_snd_error_to(snd_update_error_handler, (void *)caller); redirect_snd_warning_to(snd_update_warning_handler, (void *)sp); nsp = snd_update(sp); redirect_snd_error_to(NULL, NULL); redirect_snd_warning_to(NULL, NULL); return(nsp); } static Xen after_save_as_hook; void run_after_save_as_hook(snd_info *sp, const char *already_saved_as_name, bool from_save_as_dialog) { /* might be save-selection, as well as save-sound-as */ if (Xen_hook_has_list(after_save_as_hook)) { char *fullname; fullname = mus_expand_filename(already_saved_as_name); run_progn_hook(after_save_as_hook, Xen_list_3((sp) ? C_int_to_Xen_sound(sp->index) : Xen_false, C_string_to_Xen_string(fullname), C_bool_to_Xen_boolean(from_save_as_dialog)), S_after_save_as_hook); free(fullname); } } static Xen before_save_as_hook; static bool before_save_as_hook_active = false; bool run_before_save_as_hook(snd_info *sp, const char *save_as_filename, bool selection, int srate, mus_sample_t smp_type, mus_header_t hd_type, const char *comment) { /* might be save-selection, as well as save-sound-as */ if (before_save_as_hook_active) return(false); if (Xen_hook_has_list(before_save_as_hook)) { Xen result; before_save_as_hook_active = true; result = run_progn_hook(before_save_as_hook, Xen_list_7((sp) ? C_int_to_Xen_sound(sp->index) : Xen_false, C_string_to_Xen_string(save_as_filename), C_bool_to_Xen_boolean(selection), C_int_to_Xen_integer(srate), C_int_to_Xen_integer((int)smp_type), C_int_to_Xen_integer((int)hd_type), (comment) ? C_string_to_Xen_string(comment) : Xen_false), S_before_save_as_hook); before_save_as_hook_active = false; return(Xen_is_true(result)); } return(false); } /* -------- file dialog header/data choices -------- */ enum {H_NEXT, H_AIFC, H_RIFF, H_RF64, H_RAW, H_AIFF, H_IRCAM, H_NIST, H_CAFF, /* the "built-in" choices for output */ H_OGG, H_FLAC, H_SPEEX, H_TTA, H_WAVPACK, /* readable/writable via external programs */ H_MPEG, H_MIDI, /* readable via external programs */ H_SIZE}; static int h_num_sample_types[H_SIZE] = {12 /* next */, 13 /* aifc */, 8 /* riff */, 8 /* rf64 */, 18 /* raw */, 4 /* aiff */, 5 /* ircam */, 7 /* nist */, 13 /* caff */, 1 /* ogg */, 1 /* flac */, 1 /* speex */, 1 /* tta */, 1 /*wavpack */, 1 /* mpeg */, 1 /* midi */}; #define H_DFS_MAX 18 static mus_sample_t h_dfs[H_SIZE][H_DFS_MAX] = { /* next */ {MUS_BFLOAT, MUS_BSHORT, MUS_LSHORT, MUS_LFLOAT, MUS_MULAW, MUS_BYTE, MUS_BINT, MUS_ALAW, MUS_B24INT, MUS_BDOUBLE, MUS_LINT, MUS_LDOUBLE}, /* aifc */ {MUS_BFLOAT, MUS_BSHORT, MUS_MULAW, MUS_BYTE, MUS_BINT, MUS_ALAW, MUS_B24INT, MUS_BDOUBLE, MUS_UBYTE, MUS_LSHORT, MUS_LINT, MUS_L24INT, MUS_UBSHORT}, /* riff */ {MUS_LFLOAT, MUS_LSHORT, MUS_MULAW, MUS_ALAW, MUS_UBYTE, MUS_LINT, MUS_LDOUBLE, MUS_L24INT}, /* rf64 */ {MUS_LFLOAT, MUS_LSHORT, MUS_MULAW, MUS_ALAW, MUS_UBYTE, MUS_LINT, MUS_LDOUBLE, MUS_L24INT}, /* raw */ {MUS_BFLOAT, MUS_LFLOAT, MUS_BSHORT, MUS_MULAW, MUS_BYTE, MUS_BINT, MUS_ALAW, MUS_UBYTE, MUS_B24INT, MUS_BDOUBLE, MUS_LSHORT, MUS_LINT, MUS_LDOUBLE, MUS_UBSHORT, MUS_ULSHORT, MUS_L24INT, MUS_BINTN, MUS_LINTN}, /* aiff */ {MUS_BSHORT, MUS_BINT, MUS_BYTE, MUS_B24INT}, /* ircam */ {MUS_BFLOAT, MUS_BSHORT, MUS_MULAW, MUS_BINT, MUS_ALAW}, /* nist */ {MUS_BSHORT, MUS_LSHORT, MUS_BINT, MUS_LINT, MUS_BYTE, MUS_B24INT, MUS_L24INT}, /* caff */ {MUS_BFLOAT, MUS_BSHORT, MUS_LFLOAT, MUS_LSHORT, MUS_MULAW, MUS_BYTE, MUS_BINTN, MUS_ALAW, MUS_B24INT, MUS_BDOUBLE, MUS_LINTN, MUS_L24INT, MUS_LDOUBLE}, /* ogg */ {MUS_LSHORT}, /* flac */ {MUS_LSHORT}, /* speex */ {MUS_LSHORT}, /* tta */ {MUS_LSHORT}, /* wavpack */ {MUS_LSHORT}, /* readonly */ {MUS_UNKNOWN_SAMPLE}, {MUS_UNKNOWN_SAMPLE} }; static const char *h_df_names[H_SIZE][H_DFS_MAX]; static const char *h_names[H_SIZE] = {"au/next ", "aifc ", "wave ", "rf64 ", "raw ", "aiff ", "ircam ", "nist ", "caff ", "ogg ", "flac ", "speex ", "tta ", "wavpack", "mpeg ", "midi "}; static mus_header_t h_pos_to_type[H_SIZE] = {MUS_NEXT, MUS_AIFC, MUS_RIFF, MUS_RF64, MUS_RAW, MUS_AIFF, MUS_IRCAM, MUS_NIST, MUS_CAFF, MUS_UNKNOWN_HEADER, MUS_UNKNOWN_HEADER, MUS_UNKNOWN_HEADER, MUS_UNKNOWN_HEADER, MUS_UNKNOWN_HEADER, MUS_UNKNOWN_HEADER, MUS_UNKNOWN_HEADER}; static int h_type_to_pos[MUS_NUM_HEADERS]; static int h_type_to_h[MUS_NUM_HEADERS]; static const char *sample_type_name(mus_sample_t sample_type) { switch (sample_type) { case MUS_BSHORT: return("16-bit int (be)"); break; case MUS_MULAW: return("mulaw"); break; case MUS_BYTE: return("8-bit int"); break; case MUS_BFLOAT: return("float (be)"); break; case MUS_BFLOAT_UNSCALED: return("float unscaled (be))"); break; case MUS_BINT: return("32-bit int (be)"); break; case MUS_ALAW: return("alaw"); break; case MUS_UBYTE: return("unsigned byte"); break; case MUS_B24INT: return("24-bit int (be)"); break; case MUS_BDOUBLE: return("double (be)"); break; case MUS_BDOUBLE_UNSCALED: return("double unscaled (be)"); break; case MUS_LSHORT: return("16-bit int (le)"); break; case MUS_LINT: return("32-bit int (le)"); break; case MUS_LFLOAT: return("float (le)"); break; case MUS_LDOUBLE: return("double (le)"); break; case MUS_LFLOAT_UNSCALED: return("float unscaled (le)"); break; case MUS_LDOUBLE_UNSCALED: return("double unscaled (le)"); break; case MUS_UBSHORT: return("unsigned short (be)"); break; case MUS_ULSHORT: return("unsigned short (le)"); break; case MUS_L24INT: return("24-bit int (le)"); break; case MUS_BINTN: return("normalized int (be)"); break; case MUS_LINTN: return("normalized int (le)"); break; default: return("unknown"); break; } } void initialize_sample_type_lists(void) { int i, h; for (h = 0; h < H_SIZE; h++) for (i = 0; i < h_num_sample_types[h]; i++) h_df_names[h][i] = sample_type_name(h_dfs[h][i]); for (i = 0; i < MUS_NUM_HEADERS; i++) { h_type_to_pos[i] = -1; h_type_to_h[i] = -1; } h_type_to_pos[MUS_NEXT] = 0; h_type_to_pos[MUS_AIFC] = 1; h_type_to_pos[MUS_RIFF] = 2; h_type_to_pos[MUS_RF64] = 3; h_type_to_pos[MUS_RAW] = 4; h_type_to_pos[MUS_AIFF] = 5; h_type_to_pos[MUS_IRCAM] = 6; h_type_to_pos[MUS_NIST] = 7; h_type_to_pos[MUS_CAFF] = 8; h_type_to_h[MUS_NEXT] = H_NEXT; h_type_to_h[MUS_AIFC] = H_AIFC; h_type_to_h[MUS_RIFF] = H_RIFF; h_type_to_h[MUS_RF64] = H_RF64; h_type_to_h[MUS_RAW] = H_RAW; h_type_to_h[MUS_AIFF] = H_AIFF; h_type_to_h[MUS_IRCAM] = H_IRCAM; h_type_to_h[MUS_NIST] = H_NIST; h_type_to_h[MUS_CAFF] = H_CAFF; h_type_to_h[MUS_OGG] = H_OGG; h_type_to_h[MUS_FLAC] = H_FLAC; h_type_to_h[MUS_SPEEX] = H_SPEEX; h_type_to_h[MUS_MIDI] = H_MIDI; h_type_to_h[MUS_MPEG] = H_MPEG; h_type_to_h[MUS_TTA] = H_TTA; h_type_to_h[MUS_WAVPACK] = H_WAVPACK; i = 9; /* readable/writable */ #if HAVE_OGG h_type_to_pos[MUS_OGG] = i; h_pos_to_type[i++] = MUS_OGG; #endif #if HAVE_FLAC h_type_to_pos[MUS_FLAC] = i; h_pos_to_type[i++] = MUS_FLAC; #endif #if HAVE_SPEEX h_type_to_pos[MUS_SPEEX] = i; h_pos_to_type[i++] = MUS_SPEEX; #endif #if HAVE_TTA h_type_to_pos[MUS_TTA] = i; h_pos_to_type[i++] = MUS_TTA; #endif #if HAVE_WAVPACK h_type_to_pos[MUS_WAVPACK] = i; h_pos_to_type[i++] = MUS_WAVPACK; #endif /* readable */ #if HAVE_MPEG h_type_to_pos[MUS_MPEG] = i; h_pos_to_type[i++] = MUS_MPEG; #endif #if HAVE_MIDI h_type_to_pos[MUS_MIDI] = i; h_pos_to_type[i++] = MUS_MIDI; #endif } #define NUM_BUILTIN_HEADERS 9 #define NUM_POSSIBLE_HEADERS 16 static const char **writable_headers = NULL; static const char **readable_headers = NULL; static int num_writable_headers = NUM_BUILTIN_HEADERS; static int num_readable_headers = NUM_BUILTIN_HEADERS; const char **short_builtin_headers(int *len) { (*len) = NUM_BUILTIN_HEADERS; return(h_names); } const char **short_writable_headers(int *len) { /* these are headers that we either write ourself, or have external programs to write (oggenc etc) */ if (!writable_headers) { int i; writable_headers = (const char **)calloc(NUM_POSSIBLE_HEADERS, sizeof(char *)); for (i = 0; i < NUM_BUILTIN_HEADERS; i++) writable_headers[i] = h_names[i]; #if HAVE_OGG /* write temp as RIFF 16-bit lshort, then oggenc tempfile.wav -o outoggfile.ogg -q 6 sets to higher quality -- add as arg somehow? so format here is just the ogg output format: nothing settable */ writable_headers[i++] = h_names[H_OGG]; #endif #if HAVE_FLAC /* flac tempfile.wav -o output.flac */ writable_headers[i++] = h_names[H_FLAC]; #endif #if HAVE_SPEEX /* speexenc tempfile.wav output.spx */ writable_headers[i++] = h_names[H_SPEEX]; #endif #if HAVE_TTA /* ttaenc -e in out */ writable_headers[i++] = h_names[H_TTA]; #endif #if HAVE_WAVPACK /* wavpack in -o out */ writable_headers[i++] = h_names[H_WAVPACK]; #endif num_writable_headers = i; } (*len) = num_writable_headers; return(writable_headers); } const char **short_readable_headers(int *len) { if (!readable_headers) { int i; readable_headers = (const char **)calloc(NUM_POSSIBLE_HEADERS, sizeof(char *)); for (i = 0; i < NUM_BUILTIN_HEADERS; i++) readable_headers[i] = h_names[i]; #if HAVE_OGG /* oggdec to tempfile: oggdec infile.ogg -b 16 -o translatedfile.wav defaults for rest are signed little endian wav so sample_types (for output temp) here are not relevant -- no one will want 1 byte */ readable_headers[i++] = h_names[H_OGG]; #endif #if HAVE_FLAC /* flac -d infile.flac -o output.wav * the -d -> decode * no choices */ readable_headers[i++] = h_names[H_FLAC]; #endif #if HAVE_SPEEX /* speexdec infile.spx tempfile.wav no other choices */ readable_headers[i++] = h_names[H_SPEEX]; #endif #if HAVE_MPEG /* mpg321 -q -w output.wav input.mpg this is mpeg->wav only no choices mpg123 is probably the same */ readable_headers[i++] = h_names[H_MPEG]; #endif #if HAVE_TIMIDITY /* timidity input.mid -Ou -o output.snd midi->next/sun there are other choices... */ readable_headers[i++] = h_names[H_MIDI]; #endif #if HAVE_TTA readable_headers[i++] = h_names[H_TTA]; #endif #if HAVE_WAVPACK readable_headers[i++] = h_names[H_WAVPACK]; #endif num_readable_headers = i; } (*len) = num_readable_headers; return(readable_headers); } mus_header_t position_to_header_type(int position) { return(h_pos_to_type[position]); } mus_sample_t position_to_sample_type(mus_header_t header, int position) { return(h_dfs[h_type_to_pos[header]][position]); } static int h_to_sample_type_pos(int h, mus_sample_t samp_type) { int i; for (i = 0; i < h_num_sample_types[h]; i++) if (h_dfs[h][i] == samp_type) return(i); return(0); } const char **header_type_and_sample_type_to_position(file_data *fdat, mus_header_t type, mus_sample_t sample_type) { int h; h = h_type_to_h[type]; fdat->sample_types = h_num_sample_types[h]; fdat->header_type_pos = h_type_to_pos[type]; fdat->sample_type_pos = h_to_sample_type_pos(h, sample_type); return(h_df_names[h]); } void position_to_header_type_and_sample_type(file_data *fdat, int pos) { int h; h = h_type_to_h[h_pos_to_type[pos]]; fdat->header_type_pos = pos; fdat->current_header_type = h_pos_to_type[pos]; fdat->sample_type_pos = h_to_sample_type_pos(h, fdat->current_sample_type); fdat->current_sample_type = h_dfs[h][fdat->sample_type_pos]; } bool header_is_encoded(mus_header_t header_type) { /* going either way here */ return((header_type == MUS_OGG) || (header_type == MUS_FLAC) || (header_type == MUS_SPEEX) || (header_type == MUS_MPEG) || (header_type == MUS_MIDI) || (header_type == MUS_TTA) || (header_type == MUS_WAVPACK) ); } static char *quoted_filename(const char *filename, bool *new_name) { int p, len; p = strcspn(filename, "' *?"); /* also [] but do they actually ever happen? */ len = strlen(filename); if (p < len) { int i, j; char *name; (*new_name) = true; name = (char *)calloc(len * 2, sizeof(char)); for (i = 0, j = 0; i < len; i++) { if ((filename[i] == ' ') || (filename[i] == '\'') || (filename[i] == '*') || (filename[i] == '(') || (filename[i] == ')') || (filename[i] == '?')) name[j++] = '\\'; name[j++] = filename[i]; } return(name); } (*new_name) = false; fprintf(stderr, "not quoted: %s\n", filename); return((char *)filename); } void snd_encode(mus_header_t type, const char *input_filename, const char *output_filename) { /* write lshort wav tmpfile, encode, remove tmpfile */ char *command = NULL, *ofile, *ifile; bool ofile_free = false, ifile_free = false; if (mus_file_probe(output_filename)) snd_remove(output_filename, IGNORE_CACHE); /* these guys balk at overwriting */ /* can't use '%s' here because the filename might also have single-quotes! */ ifile = quoted_filename(input_filename, &ifile_free); ofile = quoted_filename(output_filename, &ofile_free); switch (type) { #if HAVE_OGG case MUS_OGG: command = mus_format("%s %s -o %s", PATH_OGGENC, ifile, ofile); break; #endif #if HAVE_FLAC case MUS_FLAC: command = mus_format("%s %s -o %s", PATH_FLAC, ifile, ofile); break; #endif #if HAVE_SPEEX case MUS_SPEEX: command = mus_format("%s %s %s", PATH_SPEEXENC, ifile, ofile); break; #endif #if HAVE_TTA case MUS_TTA: command = mus_format("%s -e %s -o %s", PATH_TTA, ifile, ofile); break; #endif #if HAVE_WAVPACK case MUS_WAVPACK: command = mus_format("%s %s -o %s", PATH_WAVPACK, ifile, ofile); break; #endif default: break; } if (ofile_free) free(ofile); if (ifile_free) free(ifile); if (command) { int err; err = system(command); free(command); if (err == -1) fprintf(stderr, "%s failed?", command); } } int snd_decode(mus_header_t type, const char *input_filename, const char *output_filename) { int err = 0; char *command = NULL, *ofile, *ifile; bool ofile_free = false, ifile_free = false; if (mus_file_probe(output_filename)) snd_remove(output_filename, IGNORE_CACHE); /* these guys balk at overwriting */ ifile = quoted_filename(input_filename, &ifile_free); ofile = quoted_filename(output_filename, &ofile_free); switch (type) { #if HAVE_OGG case MUS_OGG: command = mus_format("%s %s -b 16 -o %s", PATH_OGGDEC, ifile, ofile); break; #endif #if HAVE_FLAC case MUS_FLAC: command = mus_format("%s -d %s -o %s", PATH_FLAC, ifile, ofile); break; #endif #if HAVE_SPEEX case MUS_SPEEX: command = mus_format("%s %s %s", PATH_SPEEXDEC, ifile, ofile); break; #endif #if HAVE_MPEG case MUS_MPEG: #if HAVE_MPG321 command = mus_format("%s -q -w %s %s", PATH_MPG321, ofile, ifile); #else command = mus_format("%s -q -w %s %s", PATH_MPG123, ofile, ifile); #endif break; #endif #if HAVE_TIMIDITY case MUS_MIDI: command = mus_format("%s %s -Ou -o %s", PATH_TIMIDITY, ifile, ofile); break; #endif #if HAVE_TTA case MUS_TTA: command = mus_format("%s -d %s -o %s", PATH_TTA, ifile, ofile); break; #endif #if HAVE_WAVPACK case MUS_WAVPACK: command = mus_format("%s %s -o %s", PATH_WVUNPACK, ifile, ofile); break; #endif default: err = -1; break; } if (ofile_free) free(ofile); if (ifile_free) free(ifile); if (command) { int err; err = system(command); free(command); if (err == -1) fprintf(stderr, "%s failed?", command); } return(err); } typedef struct { snd_info *parlous_sp, *current_sp; char *filename; } same_name_info; static bool check_for_same_name(snd_info *sp1, same_name_info *info) { if ((sp1) && (sp1 != info->current_sp) && (mus_strcmp(sp1->filename, info->filename))) { if (has_unsaved_edits(sp1)) { info->parlous_sp = sp1; return(true); } } return(false); } static void map_over_sounds_with_collision(bool (*func)(snd_info *, same_name_info *col), same_name_info *collision) { /* true = abort map, skips inactive sounds */ int i; for (i = 0; i < ss->max_sounds; i++) { snd_info *sp; sp = ss->sounds[i]; if ((sp) && (sp->inuse == SOUND_NORMAL)) { bool val; val = (*func)(sp, collision); if (val) return; } } } snd_info *file_is_open_elsewhere_and_has_unsaved_edits(snd_info *sp, const char *fullname) { same_name_info *collision; snd_info *result; collision = (same_name_info *)calloc(1, sizeof(same_name_info)); collision->filename = (char *)fullname; collision->parlous_sp = NULL; collision->current_sp = sp; map_over_sounds_with_collision(check_for_same_name, collision); result = collision->parlous_sp; free(collision); return(result); } bool edit_header_callback(snd_info *sp, file_data *edit_header_data, void (*outer_handler)(const char *error_msg, void *ufd), void (*inner_handler)(const char *error_msg, void *ufd)) { /* this just changes the header -- it does not actually reformat the data or whatever */ mus_long_t loc, samples; char *comment, *original_comment = NULL; file_info *hdr; int chans, srate; mus_sample_t sample_type; mus_header_t header_type; if ((sp->user_read_only == FILE_READ_ONLY) || (sp->file_read_only == FILE_READ_ONLY)) { snd_error("%s is write-protected", sp->filename); return(false); } #ifndef _MSC_VER if (!(ss->file_monitor_ok)) if (access(sp->filename, W_OK) < 0) { snd_error("%s is write-protected", sp->filename); return(false); } #endif hdr = sp->hdr; /* find out which fields changed -- if possible don't touch the sound data */ redirect_snd_error_to(inner_handler, (void *)edit_header_data); comment = get_file_dialog_sound_attributes(edit_header_data, &srate, &chans, &header_type, &sample_type, &loc, &samples, 1); redirect_snd_error_to(outer_handler, (void *)edit_header_data); if (edit_header_data->error_widget != NOT_A_SCANF_WIDGET) /* bad field value, perhaps */ return(false); if (sp->hdr->type != MUS_RAW) { original_comment = mus_sound_comment(sp->filename); if ((hdr->type == MUS_AIFF) || (hdr->type == MUS_AIFC)) mus_header_set_aiff_loop_info(mus_sound_loop_info(sp->filename)); } mus_sound_forget(sp->filename); if (hdr->type != header_type) { sp->writing = true; mus_header_change_type(sp->filename, header_type, sample_type); sp->writing = false; } else { if (hdr->sample_type != sample_type) mus_header_change_sample_type(sp->filename, header_type, sample_type); } if (hdr->chans != chans) mus_header_change_chans(sp->filename, header_type, chans); if (hdr->srate != srate) mus_header_change_srate(sp->filename, header_type, srate); if (hdr->samples != samples) mus_header_change_data_size(sp->filename, header_type, mus_samples_to_bytes(sample_type, samples)); if ((header_type == MUS_NEXT) && (hdr->data_location != loc)) mus_header_change_location(sp->filename, MUS_NEXT, loc); if (!(mus_strcmp(comment, original_comment))) mus_header_change_comment(sp->filename, header_type, comment); if (comment) free(comment); if (original_comment) free(original_comment); snd_update(sp); return(true); } #if (!USE_NO_GUI) /* raw data dialog funcs */ static int swap_int(int n) { int o; unsigned char *inp, *outp; inp = (unsigned char *)&n; outp = (unsigned char *)&o; outp[0] = inp[3]; outp[1] = inp[2]; outp[2] = inp[1]; outp[3] = inp[0]; return(o); } static mus_long_t swap_mus_long_t(mus_long_t n) { mus_long_t o; unsigned char *inp, *outp; inp = (unsigned char *)&n; outp = (unsigned char *)&o; outp[0] = inp[7]; outp[1] = inp[6]; outp[2] = inp[5]; outp[3] = inp[4]; outp[4] = inp[3]; outp[5] = inp[2]; outp[6] = inp[1]; outp[7] = inp[0]; return(o); } static short swap_short(short n) { short o; unsigned char *inp, *outp; inp = (unsigned char *)&n; outp = (unsigned char *)&o; outp[0] = inp[1]; outp[1] = inp[0]; return(o); } static char *raw_data_explanation(const char *filename, file_info *hdr, char **info) { char *reason_str, *tmp_str, *file_string; mus_long_t nsamp; bool ok; int ns, better_srate = 0, better_chans = 0, len; reason_str = (char *)calloc(PRINT_BUFFER_SIZE, sizeof(char)); tmp_str = (char *)calloc(LABEL_BUFFER_SIZE, sizeof(char)); /* try to provide some notion of what might be the intended header (currently limited to byte-order mistakes) */ len = PRINT_BUFFER_SIZE; /* srate */ ok = ((original_srate >= 8000) && (original_srate <= 100000)); snprintf(reason_str, len, "srate%s: %d", (ok) ? "" : " looks wrong", original_srate); if (!ok) { ns = (int)swap_int(original_srate); if ((ns < 4000) || (ns > 100000)) ns = (int)swap_short((short)(original_srate)); if ((ns > 4000) && (ns < 100000)) { better_srate = ns; snprintf(tmp_str, LABEL_BUFFER_SIZE, " (swapped: %d)", ns); reason_str = mus_strcat(reason_str, tmp_str, &len); } } /* chans */ ok = ((original_chans > 0) && (original_chans < 1000)); snprintf(tmp_str, LABEL_BUFFER_SIZE, "\nchans%s: %d", (ok) ? "" : " looks wrong", original_chans); reason_str = mus_strcat(reason_str, tmp_str, &len); if (!ok) { ns = swap_int(original_chans); if ((ns < 0) || (ns > 8)) ns = swap_short((short)(original_chans)); if ((ns > 0) && (ns <= 8)) { better_chans = ns; snprintf(tmp_str, LABEL_BUFFER_SIZE, " (swapped: %d)", ns); reason_str = mus_strcat(reason_str, tmp_str, &len); } } /* header type */ snprintf(tmp_str, LABEL_BUFFER_SIZE, "\ntype: %s", mus_header_type_name(hdr->type)); reason_str = mus_strcat(reason_str, tmp_str, &len); /* sample type */ if (!(mus_is_sample_type(original_sample_type))) { char *format_info; if (original_sample_type != MUS_UNKNOWN_SAMPLE) format_info = (char *)mus_sample_type_name(original_sample_type); else format_info = (char *)mus_header_original_sample_type_name(mus_sound_original_sample_type(filename), hdr->type); snprintf(tmp_str, LABEL_BUFFER_SIZE, "\nformat looks bogus: %s", format_info); } else snprintf(tmp_str, LABEL_BUFFER_SIZE, "\nformat: %s", (char *)mus_sample_type_name(original_sample_type)); reason_str = mus_strcat(reason_str, tmp_str, &len); /* samples */ snprintf(tmp_str, LABEL_BUFFER_SIZE, "\nlength: %.3f (%lld samples, %lld bytes total)", (float)((double)(hdr->samples) / (float)(hdr->chans * hdr->srate)), hdr->samples, mus_sound_length(filename)); reason_str = mus_strcat(reason_str, tmp_str, &len); nsamp = swap_mus_long_t(hdr->samples); if (nsamp < mus_sound_length(filename)) { snprintf(tmp_str, LABEL_BUFFER_SIZE, " (swapped: %lld" , nsamp); reason_str = mus_strcat(reason_str, tmp_str, &len); if ((better_chans) && (better_srate)) { snprintf(tmp_str, LABEL_BUFFER_SIZE, ", swapped length: %.3f / sample-size-in-bytes)", (float)((double)nsamp / (float)(better_chans * better_srate))); reason_str = mus_strcat(reason_str, tmp_str, &len); } else reason_str = mus_strcat(reason_str, ")", &len); } /* data location */ snprintf(tmp_str, LABEL_BUFFER_SIZE, "\ndata location: %lld", hdr->data_location); reason_str = mus_strcat(reason_str, tmp_str, &len); nsamp = swap_mus_long_t(hdr->data_location); if ((nsamp > 0) && (nsamp <= 1024)) { snprintf(tmp_str, LABEL_BUFFER_SIZE, " (swapped: %lld)", nsamp); reason_str = mus_strcat(reason_str, tmp_str, &len); } (*info) = reason_str; file_string = (char *)calloc(PRINT_BUFFER_SIZE, sizeof(char)); snprintf(file_string, PRINT_BUFFER_SIZE, "Bad header found on %s", filename_without_directory(filename)); free(tmp_str); free_file_info(hdr); return(file_string); } #endif char *dialog_get_title(widget_t dialog) { #if USE_MOTIF char *temp, *titlestr = NULL; XmString title; XtVaGetValues(dialog, XmNdialogTitle, &title, NULL); temp = (char *)XmStringUnparse(title, NULL, XmCHARSET_TEXT, XmCHARSET_TEXT, NULL, 0, XmOUTPUT_ALL); if (temp) { titlestr = mus_strdup(temp); XtFree(temp); } return(titlestr); #endif #if USE_GTK return(mus_strdup(gtk_window_get_title(GTK_WINDOW(dialog)))); #endif #if USE_NO_GUI return(NULL); /* make the compiler happy */ #endif } /* -------- info popup -------- */ #if (!USE_NO_GUI) static char *display_file_maxamps(const char *filename, int chans) { char *ampstr = NULL; int i, len; mus_float_t *vals; mus_long_t *times; len = chans * 32; ampstr = (char *)calloc(len, sizeof(char)); vals = (mus_float_t *)calloc(chans, sizeof(mus_float_t)); times = (mus_long_t *)calloc(chans, sizeof(mus_long_t)); snprintf(ampstr, len, "maxamp%s: ", (chans > 1) ? "s" : ""); mus_sound_maxamps(filename, chans, vals, times); for (i = 0; i < chans; i++) { ampstr = mus_strcat(ampstr, prettyf(vals[i], 3), &len); ampstr = mus_strcat(ampstr, " ", &len); } free(vals); free(times); return(ampstr); } static char *display_sound_maxamps(snd_info *sp) { char *ampstr = NULL; int i, len; len = sp->nchans * 32; ampstr = (char *)calloc(len, sizeof(char)); snprintf(ampstr, len, "maxamp%s: ", (sp->nchans > 1) ? "s" : ""); for (i = 0; i < sp->nchans; i++) { ampstr = mus_strcat(ampstr, prettyf(channel_maxamp(sp->chans[i], AT_CURRENT_EDIT_POSITION), 3), &len); ampstr = mus_strcat(ampstr, " ", &len); } return(ampstr); } void display_info(snd_info *sp) { #define INFO_BUFFER_SIZE 1024 if (sp) { file_info *hdr; char *comment = NULL, *ampstr = NULL, *buffer = NULL; hdr = sp->hdr; buffer = (char *)calloc(INFO_BUFFER_SIZE, sizeof(char)); snprintf(buffer, INFO_BUFFER_SIZE, "srate: %d\nchans: %d\nlength: %.3f (%lld %s)\n%s\n", snd_srate(sp), sp->nchans, (double)(current_samples(sp->chans[0])) / (double)snd_srate(sp), current_samples(sp->chans[0]), (sp->nchans == 1) ? "samples" : "framples", ampstr = display_sound_maxamps(sp)); post_it(sp->short_filename, buffer); if (ampstr) free(ampstr); snprintf(buffer, INFO_BUFFER_SIZE, "\n----------------------------------------\n%s:", sp->filename); post_it_append(buffer); snprintf(buffer, INFO_BUFFER_SIZE, "\n type: %s\n format: %s\n written: %s\n", mus_header_type_name(hdr->type), mus_sample_type_name(hdr->sample_type), snd_strftime(STRFTIME_FORMAT, sp->write_date)); post_it_append(buffer); if (hdr->srate != snd_srate(sp)) { snprintf(buffer, INFO_BUFFER_SIZE, " original srate: %d\n", hdr->srate); post_it_append(buffer); } if (hdr->chans != sp->nchans) { snprintf(buffer, INFO_BUFFER_SIZE, " original chans: %d\n", hdr->chans); post_it_append(buffer); } comment = hdr->comment; while ((comment) && (*comment) && (((*comment) == '\n') || ((*comment) == '\t') || ((*comment) == ' ') || ((*comment) == '\xd'))) comment++; if ((comment) && (*comment)) { snprintf(buffer, INFO_BUFFER_SIZE, " comment: \"%s\"\n", comment); post_it_append(buffer); } if (mus_sound_maxamp_exists(sp->filename)) { int i; bool edits = false; for (i = 0; i < sp->nchans; i++) if (sp->chans[i]->edit_ctr > 0) { edits = true; break; } if (edits) { ampstr = display_file_maxamps(sp->filename, sp->nchans); if (ampstr) { snprintf(buffer, INFO_BUFFER_SIZE, " original %s\n", ampstr); post_it_append(buffer); free(ampstr); } } } free(buffer); } } #endif /* -------- extlang connections -------- */ static Xen g_add_sound_file_extension(Xen ext) { #define H_add_sound_file_extension "(" S_add_sound_file_extension " ext): add the file extension 'ext' to the list of sound file extensions" Xen_check_type(Xen_is_string(ext), ext, 1, S_add_sound_file_extension, "a string"); add_sound_file_extension(Xen_string_to_C_string(ext)); return(ext); } static Xen g_sound_file_extensions(void) { #define H_sound_file_extensions "(" S_sound_file_extensions "): list of current sound file extensions (used \ by the just-sounds file filters)" Xen res = Xen_empty_list; int i; for (i = 0; i < sound_file_extensions_end; i++) res = Xen_cons(C_string_to_Xen_string(sound_file_extensions[i]), res); return(res); } static Xen g_set_sound_file_extensions(Xen lst) { int i, len; for (i = 0; i < sound_file_extensions_end; i++) if (sound_file_extensions[i]) { free(sound_file_extensions[i]); sound_file_extensions[i] = NULL; } sound_file_extensions_end = 0; default_sound_file_extensions = 0; len = Xen_list_length(lst); for (i = 0; i < len; i++) if (!(Xen_is_string(Xen_list_ref(lst, i)))) { Xen_check_type(0, Xen_list_ref(lst, i), i, S_set S_sound_file_extensions, "a filename extension (a string like \"snd\")"); return(Xen_false); } for (i = 0; i < len; i++) add_sound_file_extension(Xen_string_to_C_string(Xen_list_ref(lst, i))); return(lst); } static Xen g_file_write_date(Xen file) { #if HAVE_RUBY #define write_date_equivalent "Equivalent to Ruby's File.mtime(file)" #endif #if HAVE_FORTH #define write_date_equivalent "Equivalent to Forth's file-mtime" #endif #if HAVE_SCHEME #define write_date_equivalent "" #endif #define S_file_write_date "file-write-date" #ifndef __GNUC__ #define H_file_write_date "(" S_file_write_date " file): write date of file" #else #define H_file_write_date "(" S_file_write_date " file): write date in the same format as \ current-time:\n(strftime \"%a %d-%b-%Y %H:%M %Z\" (localtime (" S_file_write_date " \"oboe.snd\")))\n" write_date_equivalent #endif time_t date; Xen_check_type(Xen_is_string(file), file, 1, S_file_write_date, "a string"); date = file_write_date(Xen_string_to_C_string(file)); return(C_int_to_Xen_integer(date)); } static Xen g_sound_loop_info(Xen snd) { #define H_sound_loop_info "(" S_sound_loop_info " :optional snd): return the sound's loop points as a \ list: (sustain-start sustain-end release-start release-end baseNote detune)" int *res; snd_info *sp; Snd_assert_sound(S_sound_loop_info, snd, 1); sp = get_sp(snd); if (sp == NULL) return(snd_no_such_sound_error(S_sound_loop_info, snd)); res = sp->hdr->loops; if (res) return(Xen_list_8(C_int_to_Xen_integer(res[0]), C_int_to_Xen_integer(res[1]), C_int_to_Xen_integer(res[2]), C_int_to_Xen_integer(res[3]), C_int_to_Xen_integer(res[4]), C_int_to_Xen_integer(res[5]), C_int_to_Xen_integer(res[6]), C_int_to_Xen_integer(res[7]))); return(Xen_empty_list); } static Xen g_set_sound_loop_info(Xen snd, Xen vals) { snd_info *sp; char *tmp_file; file_info *hdr; mus_header_t type; int len = 0; Xen start0 = Xen_integer_zero, end0 = Xen_integer_zero; Xen start1 = Xen_integer_zero, end1 = Xen_integer_zero; Xen mode0 = Xen_integer_zero, mode1 = Xen_integer_zero; Xen note = Xen_integer_zero, detune = Xen_integer_zero; Xen_check_type((!Xen_is_bound(vals)) || (Xen_is_list(vals)), vals, 2, S_set S_sound_loop_info, "a list"); if (!Xen_is_bound(vals)) { /* what is going on here? -- (set! (sound-loop-info) (list...))? */ Xen_check_type(Xen_is_list(snd), snd, 1, S_set S_sound_loop_info, "a list"); vals = snd; sp = get_sp(Xen_undefined); } else { Snd_assert_sound(S_set S_sound_loop_info, snd, 1); sp = get_sp(snd); } len = Xen_list_length(vals); if (sp == NULL) return(snd_no_such_sound_error(S_set S_sound_loop_info, snd)); if ((sp->user_read_only == FILE_READ_ONLY) || (sp->file_read_only == FILE_READ_ONLY)) Xen_error(CANNOT_SAVE, Xen_list_2(C_string_to_Xen_string(S_set S_sound_loop_info ": ~S is write-protected"), C_string_to_Xen_string(sp->filename))); hdr = sp->hdr; if (len > 0) { start0 = Xen_list_ref(vals, 0); Xen_check_type(Xen_is_integer(start0), start0, 2, S_set S_sound_loop_info, "start0 must be an integer"); if (len > 1) { end0 = Xen_list_ref(vals, 1); Xen_check_type(Xen_is_integer(end0), end0, 2, S_set S_sound_loop_info, "end0 must be an integer"); if (len > 2) { start1 = Xen_list_ref(vals, 2); Xen_check_type(Xen_is_integer(start1), start1, 2, S_set S_sound_loop_info, "start1 must be an integer"); if (len > 3) { end1 = Xen_list_ref(vals, 3); Xen_check_type(Xen_is_integer(end1), end1, 2, S_set S_sound_loop_info, "end1 must be an integer"); if (len > 4) { note = Xen_list_ref(vals, 4); Xen_check_type(Xen_is_integer(note), note, 2, S_set S_sound_loop_info, "note must be an integer"); if (len > 5) { detune = Xen_list_ref(vals, 5); Xen_check_type(Xen_is_integer(detune), detune, 2, S_set S_sound_loop_info, "detune must be an integer"); if (len > 6) { mode0 = Xen_list_ref(vals, 6); Xen_check_type(Xen_is_integer(mode0), mode0, 2, S_set S_sound_loop_info, "mode0 must be an integer"); if (len > 7) { mode1 = Xen_list_ref(vals, 7); Xen_check_type(Xen_is_integer(mode1), mode1, 2, S_set S_sound_loop_info, "mode1 must be an integer"); }}}}}}}} if (hdr->loops == NULL) hdr->loops = (int *)calloc(MUS_LOOP_INFO_SIZE, sizeof(int)); else memset((void *)(hdr->loops), 0, MUS_LOOP_INFO_SIZE * sizeof(int)); hdr->loops[0] = Xen_integer_to_C_int(start0); hdr->loops[1] = Xen_integer_to_C_int(end0); hdr->loops[2] = Xen_integer_to_C_int(start1); hdr->loops[3] = Xen_integer_to_C_int(end1); if (len > 4) { hdr->loops[4] = Xen_integer_to_C_int(note); hdr->loops[5] = Xen_integer_to_C_int(detune); } if (len > 6) { hdr->loops[6] = Xen_integer_to_C_int(mode0); hdr->loops[7] = Xen_integer_to_C_int(mode1); } else { if (!(Xen_is_false(end0))) hdr->loops[6] = 1; if (!(Xen_is_false(end1))) hdr->loops[7] = 1; } mus_sound_set_loop_info(sp->filename, hdr->loops); mus_header_set_aiff_loop_info(hdr->loops); type = hdr->type; if ((type != MUS_AIFF) && (type != MUS_AIFC)) { snd_warning("changing %s's header from %s to aifc to accommodate loop info", sp->short_filename, mus_header_type_name(type)); type = MUS_AIFC; } /* ideally set sound_loop_info would just change the header (keeping all other state intact) * but this aspect of AIFC headers is impossibly complicated (if we could assume our own headers, * it would not be so hard). */ tmp_file = snd_tempnam(); { io_error_t err; err = save_edits_without_display(sp, tmp_file, type, hdr->sample_type, hdr->srate, hdr->comment, AT_CURRENT_EDIT_POSITION); if ((err != IO_NO_ERROR) && (err != IO_SAVE_HOOK_CANCELLATION)) { Xen_error(CANNOT_SAVE, Xen_list_3(C_string_to_Xen_string(S_set S_sound_loop_info ": can't save ~S, ~A"), C_string_to_Xen_string(tmp_file), C_string_to_Xen_string(snd_io_strerror()))); return(Xen_false); /* not executed -- just for emphasis */ } sp->writing = true; if (err == IO_SAVE_HOOK_CANCELLATION) snd_remove(tmp_file, IGNORE_CACHE); else { err = move_file(tmp_file, sp->filename); if (is_serious_io_error(err)) { free(tmp_file); sp->writing = false; Xen_error(CANT_UPDATE_FILE, Xen_list_4(C_string_to_Xen_string(S_set S_sound_loop_info ": can't update ~S: ~A ~A"), C_string_to_Xen_string(sp->filename), C_string_to_Xen_string(io_error_name(err)), C_string_to_Xen_string(snd_io_strerror()))); return(Xen_false); } } sp->writing = false; if (err != IO_SAVE_HOOK_CANCELLATION) snd_update(sp); free(tmp_file); return((err == IO_NO_ERROR) ? Xen_true : C_int_to_Xen_integer((int)err)); } } static Xen g_soundfont_info(Xen snd) { /* return all soundfont descriptors as list of lists: ((name start loopstart loopend)) */ #define H_soundfont_info "(" S_soundfont_info " :optional snd): list of lists describing snd as a soundfont. \ each inner list has the form: (name start loopstart loopend)" Xen outlist = Xen_empty_list; snd_info *sp; Snd_assert_sound(S_soundfont_info, snd, 1); sp = get_sp(snd); if (sp == NULL) return(snd_no_such_sound_error(S_soundfont_info, snd)); mus_header_read(sp->filename); if (mus_header_type() == MUS_SOUNDFONT) { int i, lim; lim = mus_header_sf2_entries(); if (lim > 0) for (i = lim - 1; i >= 0; i--) { Xen inlist; inlist = Xen_list_4(C_string_to_Xen_string(mus_header_sf2_name(i)), C_int_to_Xen_integer(mus_header_sf2_start(i)), C_int_to_Xen_integer(mus_header_sf2_loop_start(i)), C_int_to_Xen_integer(mus_header_sf2_end(i))); outlist = Xen_cons(inlist, outlist); } } return(outlist); } dir_info *find_sound_files_in_dir(const char *name) { return(find_filtered_files_in_dir(name, JUST_SOUNDS_FILTER)); } static Xen g_sound_files_in_directory(Xen dirname) { #define H_sound_files_in_directory "(" S_sound_files_in_directory " :optional (directory \".\")): return a list of the sound files in 'directory'" char *name = NULL; Xen res = Xen_empty_list; Xen_check_type(Xen_is_string_or_unbound(dirname), dirname, 1, S_sound_files_in_directory, "a string"); if (Xen_is_string(dirname)) name = mus_expand_filename(Xen_string_to_C_string(dirname)); else name = mus_expand_filename("."); if (name) { dir_info *dp = NULL; dp = find_sound_files_in_dir(name); if (dp) { int i; for (i = dp->len - 1; i >= 0; i--) res = Xen_cons(C_string_to_Xen_string(dp->files[i]->filename), res); free_dir_info(dp); } free(name); } return(res); } #define S_disk_kspace "disk-kspace" static Xen g_disk_kspace(Xen name) { #define H_disk_kspace "(" S_disk_kspace " filename): kbytes of space available on partition containing 'filename'" Xen_check_type(Xen_is_string(name), name, 1, S_disk_kspace, "a string"); return(C_llong_to_Xen_llong(disk_kspace(Xen_string_to_C_string(name)))); } static Xen g_open_file_dialog(Xen managed) { #define H_open_file_dialog "(" S_open_file_dialog " :optional (managed " PROC_TRUE ")): create the file dialog if needed and display it if 'managed'" Xen_check_type(Xen_is_boolean_or_unbound(managed), managed, 1, S_open_file_dialog, "a boolean"); return(Xen_wrap_widget(make_open_file_dialog(FILE_READ_WRITE, (Xen_is_bound(managed)) ? Xen_boolean_to_C_bool(managed) : true))); } static Xen g_mix_file_dialog(Xen managed) { #define H_mix_file_dialog "(" S_mix_file_dialog " :optional (managed " PROC_TRUE ")): create the mix file dialog if needed and display it if 'managed'" Xen_check_type(Xen_is_boolean_or_unbound(managed), managed, 1, S_mix_file_dialog, "a boolean"); return(Xen_wrap_widget(make_mix_file_dialog((Xen_is_bound(managed)) ? Xen_boolean_to_C_bool(managed) : true))); } static Xen g_insert_file_dialog(Xen managed) { #define H_insert_file_dialog "(" S_insert_file_dialog " :optional (managed " PROC_TRUE ")): create the insert file dialog if needed and display it if 'managed'" Xen_check_type(Xen_is_boolean_or_unbound(managed), managed, 1, S_insert_file_dialog, "a boolean"); return(Xen_wrap_widget(make_insert_file_dialog((Xen_is_bound(managed)) ? Xen_boolean_to_C_bool(managed) : true))); } static Xen g_edit_header_dialog(Xen snd_n) { #define H_edit_header_dialog "(" S_edit_header_dialog " :optional snd): start the Edit Header dialog on sound snd" snd_info *sp; sp = get_sp(snd_n); if ((sp == NULL) || (sp->inuse != SOUND_NORMAL)) return(snd_no_such_sound_error(S_edit_header_dialog, snd_n)); return(Xen_wrap_widget(edit_header(sp))); } static Xen g_save_selection_dialog(Xen managed) { #define H_save_selection_dialog "(" S_save_selection_dialog " :optional managed): start the Selection Save-as dialog" Xen_check_type(Xen_is_boolean_or_unbound(managed), managed, 1, S_save_selection_dialog, "a boolean"); return(Xen_wrap_widget(make_selection_save_as_dialog(Xen_boolean_to_C_bool(managed)))); } static Xen g_save_region_dialog(Xen managed) { #define H_save_region_dialog "(" S_save_region_dialog " :optional managed): start the Region Save-as dialog" Xen_check_type(Xen_is_boolean_or_unbound(managed), managed, 1, S_save_region_dialog, "a boolean"); return(Xen_wrap_widget(make_region_save_as_dialog(Xen_boolean_to_C_bool(managed)))); } static Xen g_save_sound_dialog(Xen managed) { #define H_save_sound_dialog "(" S_save_sound_dialog " :optional managed): start the File Save-as dialog" Xen_check_type(Xen_is_boolean_or_unbound(managed), managed, 1, S_save_sound_dialog, "a boolean"); return(Xen_wrap_widget(make_sound_save_as_dialog(Xen_boolean_to_C_bool(managed)))); } static Xen g_info_dialog(Xen subject, Xen msg) { #define H_info_dialog "(" S_info_dialog " subject message): start the Info window with subject and message" Xen_check_type(Xen_is_string(subject), subject, 1, S_info_dialog, "a string"); Xen_check_type(Xen_is_string(msg), msg, 2, S_info_dialog, "a string"); return(Xen_wrap_widget(post_it(Xen_string_to_C_string(subject), Xen_string_to_C_string(msg)))); } static Xen g_new_sound_dialog(Xen managed) { #define H_new_sound_dialog "(" S_new_sound_dialog " :optional managed): start the File New sound dialog" Xen_check_type(Xen_is_boolean_or_unbound(managed), managed, 1, S_new_sound_dialog, "a boolean"); return(Xen_wrap_widget(make_new_file_dialog(Xen_boolean_to_C_bool(managed)))); } static Xen g_is_sound_file(Xen name) { #define H_is_sound_file "(" S_is_sound_file " name): " PROC_TRUE " if name has a known sound file extension" Xen_check_type(Xen_is_string(name), name, 1, S_is_sound_file, "a filename"); return(C_bool_to_Xen_boolean(is_sound_file(Xen_string_to_C_string(name)))); } static Xen g_snd_tempnam(void) { #define H_snd_tempnam "(" S_snd_tempnam "): return a new temp file name using " S_temp_dir "." char *tmp; Xen res; tmp = snd_tempnam(); res = C_string_to_Xen_string(tmp); free(tmp); return(res); } static Xen g_auto_update(void) {return(C_bool_to_Xen_boolean(auto_update(ss)));} static Xen g_set_auto_update(Xen val) { #define H_auto_update "(" S_auto_update "): " PROC_TRUE " if Snd should automatically update a file if it changes unexpectedly (default: " PROC_FALSE "). \ The number of seconds between update checks is set by " S_auto_update_interval "." Xen_check_type(Xen_is_boolean(val), val, 1, S_set S_auto_update, "a boolean"); set_auto_update(Xen_boolean_to_C_bool(val)); return(C_bool_to_Xen_boolean(auto_update(ss))); } static Xen g_auto_update_interval(void) {return(C_double_to_Xen_real(auto_update_interval(ss)));} static Xen g_set_auto_update_interval(Xen val) { mus_float_t ctime; #define H_auto_update_interval "(" S_auto_update_interval "): time (seconds) between background checks for changed file on disk (default: 60). \ This value only matters if " S_auto_update " is " PROC_TRUE Xen_check_type(Xen_is_number(val), val, 1, S_set S_auto_update_interval, "a number"); ctime = Xen_real_to_C_double(val); if (ctime != auto_update_interval(ss)) { mus_float_t old_time; if ((ctime < 0.0) || (ctime > (24 * 3600))) Xen_out_of_range_error(S_set S_auto_update_interval, 1, val, "invalid time"); old_time = auto_update_interval(ss); set_auto_update_interval(ctime); /* if new value is 0.0, auto_update_check will notice that, and not run or re-start the update check */ /* if new value is not 0.0, and old value was 0.0, we need to restart the timeout proc, unless it's still on the queue */ if ((ctime > 0.0) && (old_time == 0.0)) auto_update_restart(); } return(C_double_to_Xen_real(auto_update_interval(ss))); } static Xen g_default_output_chans(void) {return(C_int_to_Xen_integer(default_output_chans(ss)));} static Xen g_set_default_output_chans(Xen val) { #define MAX_OUTPUT_CHANS 1024 #define H_default_output_chans "(" S_default_output_chans "): default number of channels when a new or temporary file is created (1)" Xen_check_type(Xen_is_integer(val), val, 1, S_set S_default_output_chans, "an integer"); set_default_output_chans(mus_iclamp(1, Xen_integer_to_C_int(val), MAX_OUTPUT_CHANS)); return(C_int_to_Xen_integer(default_output_chans(ss))); } static Xen g_default_output_srate(void) {return(C_int_to_Xen_integer(default_output_srate(ss)));} static Xen g_set_default_output_srate(Xen val) { #define MAX_OUTPUT_SRATE 1000000000 #define H_default_output_srate "(" S_default_output_srate "): default srate when a new or temporary file is created (22050)" Xen_check_type(Xen_is_integer(val), val, 1, S_set S_default_output_srate, "an integer"); set_default_output_srate(mus_iclamp(1, Xen_integer_to_C_int(val), MAX_OUTPUT_SRATE)); return(C_int_to_Xen_integer(default_output_srate(ss))); } static Xen g_default_output_header_type(void) {return(C_int_to_Xen_integer((int)default_output_header_type(ss)));} static Xen g_set_default_output_header_type(Xen val) { mus_header_t typ; #define H_default_output_header_type "(" S_default_output_header_type "): default header type when a new or temporary file is created. \ Normally this is " S_mus_next "; -1 here indicates you want Snd to use the current sound's header type, if possible. \ Other writable headers include " S_mus_aiff ", " S_mus_riff ", " S_mus_ircam ", " S_mus_nist ", " S_mus_aifc ", and " S_mus_raw "." Xen_check_type(Xen_is_integer(val), val, 1, S_set S_default_output_header_type, "an integer"); typ = (mus_header_t)Xen_integer_to_C_int(val); if (mus_header_writable(typ, MUS_IGNORE_SAMPLE)) set_default_output_header_type(typ); else Xen_out_of_range_error(S_set S_default_output_header_type, 1, val, "unwritable header type"); return(C_int_to_Xen_integer((int)default_output_header_type(ss))); } static Xen g_default_output_sample_type(void) {return(C_int_to_Xen_integer(default_output_sample_type(ss)));} static Xen g_set_default_output_sample_type(Xen val) { mus_sample_t samp_type; #define H_default_output_sample_type "(" S_default_output_sample_type "): default sample type when a new or temporary file is created, \ normally " S_mus_ldouble "; mus-unknown-sample here means try to use the current sound's sample type; many other sample types \ are available, but not all are compatible with all header types" Xen_check_type(Xen_is_integer(val), val, 1, S_set S_default_output_sample_type, "an integer"); samp_type = (mus_sample_t)Xen_integer_to_C_int(val); if (mus_is_sample_type(samp_type)) set_default_output_sample_type(samp_type); else Xen_out_of_range_error(S_set S_default_output_sample_type, 1, val, "unknown sample type"); return(C_int_to_Xen_integer((int)default_output_sample_type(ss))); } static Xen g_clipping(void) {return(C_bool_to_Xen_boolean(clipping(ss)));} static Xen g_set_clipping(Xen val) { #define H_clipping "(" S_clipping "): " PROC_TRUE " if Snd should clip output values to the current \ output sample type's maximum. The default (" PROC_FALSE ") allows them to wrap-around which makes a very loud click" Xen_check_type(Xen_is_boolean(val), val, 1, S_set S_clipping, "a boolean"); set_clipping(Xen_boolean_to_C_bool(val)); return(C_bool_to_Xen_boolean(clipping(ss))); } static Xen g_ask_before_overwrite(void) {return(C_bool_to_Xen_boolean(ask_before_overwrite(ss)));} static Xen g_set_ask_before_overwrite(Xen val) { #define H_ask_before_overwrite "(" S_ask_before_overwrite "): " PROC_TRUE " if you want Snd to ask before overwriting a file. \ If " PROC_FALSE ", any existing file of the same name will be overwritten without warning when you save a sound." Xen_check_type(Xen_is_boolean(val), val, 1, S_set S_ask_before_overwrite, "a boolean"); set_ask_before_overwrite(Xen_boolean_to_C_bool(val)); return(C_bool_to_Xen_boolean(ask_before_overwrite(ss))); } static Xen g_with_toolbar(void) {return(C_bool_to_Xen_boolean(with_toolbar(ss)));} void set_with_toolbar_and_display(bool val) { set_with_toolbar(val); #if (!USE_NO_GUI) if (with_toolbar(ss)) show_toolbar(); else hide_toolbar(); #endif } static Xen g_set_with_toolbar(Xen val) { #define H_with_toolbar "(" S_with_toolbar "): " PROC_TRUE " if you want a toolbar" Xen_check_type(Xen_is_boolean(val), val, 1, S_set S_with_toolbar, "a boolean"); set_with_toolbar_and_display(Xen_boolean_to_C_bool(val)); return(C_bool_to_Xen_boolean(with_toolbar(ss))); } static Xen g_with_tooltips(void) {return(C_bool_to_Xen_boolean(with_tooltips(ss)));} void set_with_tooltips(bool val) { in_set_with_tooltips(val); #if USE_GTK #if (!GTK_CHECK_VERSION(3, 16, 0)) /* this can't be combined in the line above */ g_object_set(gtk_settings_get_default(), "gtk-enable-tooltips", val, NULL); #endif #endif } static Xen g_set_with_tooltips(Xen val) { #define H_with_tooltips "(" S_with_tooltips "): " PROC_TRUE " if you want tooltips displayed at all" Xen_check_type(Xen_is_boolean(val), val, 1, S_set S_with_tooltips, "a boolean"); set_with_tooltips(Xen_boolean_to_C_bool(val)); return(C_bool_to_Xen_boolean(with_tooltips(ss))); } void set_with_menu_icons(bool val) { in_set_with_menu_icons(val); #if USE_GTK #if (!GTK_CHECK_VERSION(3, 16, 0)) g_object_set(gtk_settings_get_default(), "gtk-menu-images", with_menu_icons(ss), NULL); g_object_set(gtk_settings_get_default(), "gtk-button-images", with_menu_icons(ss), NULL); #endif #endif } static Xen g_with_menu_icons(void) {return(C_bool_to_Xen_boolean(with_menu_icons(ss)));} static Xen g_set_with_menu_icons(Xen val) { #define H_with_menu_icons "(" S_with_menu_icons "): " PROC_TRUE " if you want icons in the menus (gtk only)" Xen_check_type(Xen_is_boolean(val), val, 1, S_set S_with_menu_icons, "a boolean"); set_with_menu_icons(Xen_boolean_to_C_bool(val)); return(C_bool_to_Xen_boolean(with_menu_icons(ss))); } static void set_save_as_dialog_src(bool val) { in_set_save_as_dialog_src(val); reflect_save_as_src(val); } static Xen g_save_as_dialog_src(void) {return(C_bool_to_Xen_boolean(save_as_dialog_src(ss)));} static Xen g_set_save_as_dialog_src(Xen val) { #define H_save_as_dialog_src "(" S_save_as_dialog_src "): " PROC_TRUE " if you want the 'src' button set by default in the various Save-as dialogs" Xen_check_type(Xen_is_boolean(val), val, 1, S_set S_save_as_dialog_src, "a boolean"); set_save_as_dialog_src(Xen_boolean_to_C_bool(val)); return(C_bool_to_Xen_boolean(save_as_dialog_src(ss))); } static void set_save_as_dialog_auto_comment(bool val) { in_set_save_as_dialog_auto_comment(val); reflect_save_as_auto_comment(val); } static Xen g_save_as_dialog_auto_comment(void) {return(C_bool_to_Xen_boolean(save_as_dialog_auto_comment(ss)));} static Xen g_set_save_as_dialog_auto_comment(Xen val) { #define H_save_as_dialog_auto_comment "(" S_save_as_dialog_auto_comment "): " PROC_TRUE " if you want the 'auto' button set by default in the various Save-as dialogs" Xen_check_type(Xen_is_boolean(val), val, 1, S_set S_save_as_dialog_auto_comment, "a boolean"); set_save_as_dialog_auto_comment(Xen_boolean_to_C_bool(val)); return(C_bool_to_Xen_boolean(save_as_dialog_auto_comment(ss))); } static Xen g_remember_sound_state(void) {return(C_bool_to_Xen_boolean(remember_sound_state(ss)));} static Xen g_set_remember_sound_state(Xen val) { #define H_remember_sound_state "(" S_remember_sound_state "): " PROC_TRUE " if you want a Snd to remember the current \ state of each sound when it is closed, restoring that state when it is opened again later." Xen_check_type(Xen_is_boolean(val), val, 1, S_set S_remember_sound_state, "a boolean"); set_remember_sound_state(Xen_boolean_to_C_bool(val)); return(C_bool_to_Xen_boolean(remember_sound_state(ss))); } static Xen g_ask_about_unsaved_edits(void) {return(C_bool_to_Xen_boolean(ask_about_unsaved_edits(ss)));} static Xen g_set_ask_about_unsaved_edits(Xen val) { #define H_ask_about_unsaved_edits "(" S_ask_about_unsaved_edits "): " PROC_TRUE " if you want Snd to ask whether \ to save unsaved edits when a sound is closed." Xen_check_type(Xen_is_boolean(val), val, 1, S_set S_ask_about_unsaved_edits, "a boolean"); set_ask_about_unsaved_edits(Xen_boolean_to_C_bool(val)); return(C_bool_to_Xen_boolean(ask_about_unsaved_edits(ss))); } static Xen g_show_full_duration(void) {return(C_bool_to_Xen_boolean(show_full_duration(ss)));} static Xen g_set_show_full_duration(Xen val) { int i; #define H_show_full_duration "(" S_show_full_duration "): " PROC_TRUE " if you want the entire sound \ displayed whn it is opened." Xen_check_type(Xen_is_boolean(val), val, 1, S_set S_show_full_duration, "a boolean"); set_show_full_duration(Xen_boolean_to_C_bool(val)); for (i = 0; i < ss->max_sounds; i++) { snd_info *sp; sp = ss->sounds[i]; if ((sp) && (sp->inuse == SOUND_NORMAL)) { int j; for (j = 0; j < sp->nchans; j++) set_x_axis_x0x1(sp->chans[j], 0.0, sp->chans[j]->axis->xmax); } } return(C_bool_to_Xen_boolean(show_full_duration(ss))); } static Xen g_initial_beg(void) {return(C_double_to_Xen_real(initial_beg(ss)));} static Xen g_set_initial_beg(Xen val) { #define H_initial_beg "(" S_initial_beg "): the begin point (in seconds) for the initial graph of a sound." Xen_check_type(Xen_is_number(val), val, 1, S_set S_initial_beg, "a number"); set_initial_beg(Xen_real_to_C_double(val)); return(C_double_to_Xen_real(initial_beg(ss))); } static Xen g_initial_dur(void) {return(C_double_to_Xen_real(initial_dur(ss)));} static Xen g_set_initial_dur(Xen val) { #define H_initial_dur "(" S_initial_dur "): the duration (in seconds) for the initial graph of a sound." Xen_check_type(Xen_is_number(val), val, 1, S_set S_initial_dur, "a number"); set_initial_dur(Xen_real_to_C_double(val)); return(C_double_to_Xen_real(initial_dur(ss))); } static Xen g_show_full_range(void) {return(C_bool_to_Xen_boolean(show_full_range(ss)));} static Xen g_set_show_full_range(Xen val) { int i; #define H_show_full_range "(" S_show_full_range "): " PROC_TRUE " if you want the graph y-bounds to accommodate the sound's \ max and min when it is opened." Xen_check_type(Xen_is_boolean(val), val, 1, S_set S_show_full_range, "a boolean"); set_show_full_range(Xen_boolean_to_C_bool(val)); for (i = 0; i < ss->max_sounds; i++) { snd_info *sp; sp = ss->sounds[i]; if ((sp) && (sp->inuse == SOUND_NORMAL)) { int j; for (j = 0; j < sp->nchans; j++) { chan_info *cp; axis_info *ap; mus_float_t hi; cp = sp->chans[j]; ap = cp->axis; hi = channel_maxamp(cp, AT_CURRENT_EDIT_POSITION); if (hi > ap->ymax) { ap->ymin = -hi; ap->ymax = hi; ap->y_ambit = 2 * hi; ap->y0 = -hi; ap->y1 = hi; ap->zy = 1.0; ap->sy = 0.0; resize_sy_and_zy(cp); apply_y_axis_change(cp); } } } } return(C_bool_to_Xen_boolean(show_full_range(ss))); } Xen_wrap_1_arg(g_add_sound_file_extension_w, g_add_sound_file_extension) Xen_wrap_no_args(g_sound_file_extensions_w, g_sound_file_extensions) Xen_wrap_1_arg(g_set_sound_file_extensions_w, g_set_sound_file_extensions) Xen_wrap_1_arg(g_file_write_date_w, g_file_write_date) Xen_wrap_1_optional_arg(g_soundfont_info_w, g_soundfont_info) Xen_wrap_1_optional_arg(g_sound_files_in_directory_w, g_sound_files_in_directory) Xen_wrap_1_optional_arg(g_sound_loop_info_w, g_sound_loop_info) Xen_wrap_2_optional_args(g_set_sound_loop_info_w, g_set_sound_loop_info) Xen_wrap_1_arg(g_disk_kspace_w, g_disk_kspace) Xen_wrap_1_optional_arg(g_open_file_dialog_w, g_open_file_dialog) Xen_wrap_1_optional_arg(g_mix_file_dialog_w, g_mix_file_dialog) Xen_wrap_1_optional_arg(g_insert_file_dialog_w, g_insert_file_dialog) Xen_wrap_1_optional_arg(g_edit_header_dialog_w, g_edit_header_dialog) Xen_wrap_1_optional_arg(g_save_selection_dialog_w, g_save_selection_dialog) Xen_wrap_1_optional_arg(g_save_region_dialog_w, g_save_region_dialog) Xen_wrap_1_optional_arg(g_save_sound_dialog_w, g_save_sound_dialog) Xen_wrap_1_optional_arg(g_new_sound_dialog_w, g_new_sound_dialog) Xen_wrap_2_args(g_info_dialog_w, g_info_dialog) Xen_wrap_1_arg(g_is_sound_file_w, g_is_sound_file) Xen_wrap_no_args(g_snd_tempnam_w, g_snd_tempnam) Xen_wrap_no_args(g_auto_update_w, g_auto_update) Xen_wrap_1_arg(g_set_auto_update_w, g_set_auto_update) Xen_wrap_no_args(g_auto_update_interval_w, g_auto_update_interval) Xen_wrap_1_arg(g_set_auto_update_interval_w, g_set_auto_update_interval) Xen_wrap_no_args(g_default_output_chans_w, g_default_output_chans) Xen_wrap_1_arg(g_set_default_output_chans_w, g_set_default_output_chans) Xen_wrap_no_args(g_default_output_srate_w, g_default_output_srate) Xen_wrap_1_arg(g_set_default_output_srate_w, g_set_default_output_srate) Xen_wrap_no_args(g_default_output_header_type_w, g_default_output_header_type) Xen_wrap_1_arg(g_set_default_output_header_type_w, g_set_default_output_header_type) Xen_wrap_no_args(g_default_output_sample_type_w, g_default_output_sample_type) Xen_wrap_1_arg(g_set_default_output_sample_type_w, g_set_default_output_sample_type) Xen_wrap_no_args(g_ask_before_overwrite_w, g_ask_before_overwrite) Xen_wrap_1_arg(g_set_ask_before_overwrite_w, g_set_ask_before_overwrite) Xen_wrap_no_args(g_with_toolbar_w, g_with_toolbar) Xen_wrap_1_arg(g_set_with_toolbar_w, g_set_with_toolbar) Xen_wrap_no_args(g_with_tooltips_w, g_with_tooltips) Xen_wrap_1_arg(g_set_with_tooltips_w, g_set_with_tooltips) Xen_wrap_no_args(g_with_menu_icons_w, g_with_menu_icons) Xen_wrap_1_arg(g_set_with_menu_icons_w, g_set_with_menu_icons) Xen_wrap_no_args(g_save_as_dialog_src_w, g_save_as_dialog_src) Xen_wrap_1_arg(g_set_save_as_dialog_src_w, g_set_save_as_dialog_src) Xen_wrap_no_args(g_save_as_dialog_auto_comment_w, g_save_as_dialog_auto_comment) Xen_wrap_1_arg(g_set_save_as_dialog_auto_comment_w, g_set_save_as_dialog_auto_comment) Xen_wrap_no_args(g_remember_sound_state_w, g_remember_sound_state) Xen_wrap_1_arg(g_set_remember_sound_state_w, g_set_remember_sound_state) Xen_wrap_no_args(g_ask_about_unsaved_edits_w, g_ask_about_unsaved_edits) Xen_wrap_1_arg(g_set_ask_about_unsaved_edits_w, g_set_ask_about_unsaved_edits) Xen_wrap_no_args(g_show_full_duration_w, g_show_full_duration) Xen_wrap_1_arg(g_set_show_full_duration_w, g_set_show_full_duration) Xen_wrap_no_args(g_show_full_range_w, g_show_full_range) Xen_wrap_1_arg(g_set_show_full_range_w, g_set_show_full_range) Xen_wrap_no_args(g_initial_beg_w, g_initial_beg) Xen_wrap_1_arg(g_set_initial_beg_w, g_set_initial_beg) Xen_wrap_no_args(g_initial_dur_w, g_initial_dur) Xen_wrap_1_arg(g_set_initial_dur_w, g_set_initial_dur) Xen_wrap_no_args(g_clipping_w, g_clipping) Xen_wrap_1_arg(g_set_clipping_w, g_set_clipping) Xen_wrap_1_arg(g_delete_file_filter_w, g_delete_file_filter) Xen_wrap_2_args(g_add_file_filter_w, g_add_file_filter) #if HAVE_SCHEME static s7_pointer acc_default_output_header_type(s7_scheme *sc, s7_pointer args) {return(g_set_default_output_header_type(s7_cadr(args)));} static s7_pointer acc_default_output_sample_type(s7_scheme *sc, s7_pointer args) {return(g_set_default_output_sample_type(s7_cadr(args)));} static s7_pointer acc_default_output_chans(s7_scheme *sc, s7_pointer args) {return(g_set_default_output_chans(s7_cadr(args)));} static s7_pointer acc_default_output_srate(s7_scheme *sc, s7_pointer args) {return(g_set_default_output_srate(s7_cadr(args)));} static s7_pointer acc_ask_before_overwrite(s7_scheme *sc, s7_pointer args) {return(g_set_ask_before_overwrite(s7_cadr(args)));} static s7_pointer acc_ask_about_unsaved_edits(s7_scheme *sc, s7_pointer args) {return(g_set_ask_about_unsaved_edits(s7_cadr(args)));} static s7_pointer acc_show_full_duration(s7_scheme *sc, s7_pointer args) {return(g_set_show_full_duration(s7_cadr(args)));} static s7_pointer acc_show_full_range(s7_scheme *sc, s7_pointer args) {return(g_set_show_full_range(s7_cadr(args)));} static s7_pointer acc_remember_sound_state(s7_scheme *sc, s7_pointer args) {return(g_set_remember_sound_state(s7_cadr(args)));} static s7_pointer acc_save_as_dialog_src(s7_scheme *sc, s7_pointer args) {return(g_set_save_as_dialog_src(s7_cadr(args)));} static s7_pointer acc_save_as_dialog_auto_comment(s7_scheme *sc, s7_pointer args) {return(g_set_save_as_dialog_auto_comment(s7_cadr(args)));} static s7_pointer acc_with_toolbar(s7_scheme *sc, s7_pointer args) {return(g_set_with_toolbar(s7_cadr(args)));} static s7_pointer acc_with_tooltips(s7_scheme *sc, s7_pointer args) {return(g_set_with_tooltips(s7_cadr(args)));} static s7_pointer acc_with_menu_icons(s7_scheme *sc, s7_pointer args) {return(g_set_with_menu_icons(s7_cadr(args)));} static s7_pointer acc_initial_beg(s7_scheme *sc, s7_pointer args) {return(g_set_initial_beg(s7_cadr(args)));} static s7_pointer acc_initial_dur(s7_scheme *sc, s7_pointer args) {return(g_set_initial_dur(s7_cadr(args)));} static s7_pointer acc_auto_update(s7_scheme *sc, s7_pointer args) {return(g_set_auto_update(s7_cadr(args)));} static s7_pointer acc_auto_update_interval(s7_scheme *sc, s7_pointer args) {return(g_set_auto_update_interval(s7_cadr(args)));} static s7_pointer acc_clipping(s7_scheme *sc, s7_pointer args) {return(g_set_clipping(s7_cadr(args)));} #endif void g_init_file(void) { #if HAVE_SCHEME s7_pointer pl_b, pl_bb, pl_i, pl_ii, pl_s, pl_ss, pl_d, pl_dr, pl_zb, pl_l, pl_ll, pl_bs, pl_is, pl_lt, pl_zt, pl_zss, pl_ltl, pl_ls; { s7_pointer i, b, d, r, s, p, l, t, z; i = s7_make_symbol(s7, "integer?"); b = s7_make_symbol(s7, "boolean?"); d = s7_make_symbol(s7, "float?"); r = s7_make_symbol(s7, "real?"); s = s7_make_symbol(s7, "string?"); p = s7_make_symbol(s7, "pair?"); l = s7_make_symbol(s7, "list"); t = s7_t(s7); z = s7_make_signature(s7, 2, b, p); pl_b = s7_make_signature(s7, 1, b); pl_bb = s7_make_signature(s7, 2, b, b); pl_bs = s7_make_signature(s7, 2, b, s); pl_i = s7_make_signature(s7, 1, i); pl_ii = s7_make_signature(s7, 2, i, i); pl_is = s7_make_signature(s7, 2, i, s); pl_s = s7_make_signature(s7, 1, s); pl_ss = s7_make_signature(s7, 2, s, s); pl_d = s7_make_signature(s7, 1, d); pl_dr = s7_make_signature(s7, 2, d, r); pl_zb = s7_make_signature(s7, 2, z, b); pl_zt = s7_make_signature(s7, 2, z, t); pl_zss = s7_make_signature(s7, 3, z, s, s); pl_l = s7_make_signature(s7, 1, l); pl_ll = s7_make_signature(s7, 2, l, l); pl_lt = s7_make_signature(s7, 2, l, t); pl_ls = s7_make_signature(s7, 2, l, s); pl_ltl = s7_make_signature(s7, 3, l, t, l); } #endif Xen_define_typed_procedure(S_add_sound_file_extension, g_add_sound_file_extension_w, 1, 0, 0, H_add_sound_file_extension, pl_ss); Xen_define_typed_dilambda(S_sound_file_extensions, g_sound_file_extensions_w, H_sound_file_extensions, S_set S_sound_file_extensions, g_set_sound_file_extensions_w, 0, 0, 1, 0, pl_l, pl_ll); Xen_define_typed_procedure(S_is_sound_file, g_is_sound_file_w, 1, 0, 0, H_is_sound_file, pl_bs); Xen_define_typed_procedure(S_file_write_date, g_file_write_date_w, 1, 0, 0, H_file_write_date, pl_is); Xen_define_typed_procedure(S_soundfont_info, g_soundfont_info_w, 0, 1, 0, H_soundfont_info, pl_lt); Xen_define_typed_procedure(S_sound_files_in_directory, g_sound_files_in_directory_w, 0, 1, 0, H_sound_files_in_directory, pl_ls); Xen_define_typed_procedure(S_disk_kspace, g_disk_kspace_w, 1, 0, 0, H_disk_kspace, pl_is); Xen_define_typed_procedure(S_open_file_dialog, g_open_file_dialog_w, 0, 1, 0, H_open_file_dialog, pl_zb); Xen_define_typed_procedure(S_mix_file_dialog, g_mix_file_dialog_w, 0, 1, 0, H_mix_file_dialog, pl_zb); Xen_define_typed_procedure(S_insert_file_dialog, g_insert_file_dialog_w, 0, 1, 0, H_insert_file_dialog, pl_zb); Xen_define_typed_procedure(S_edit_header_dialog, g_edit_header_dialog_w, 0, 1, 0, H_edit_header_dialog, pl_zt); Xen_define_typed_procedure(S_save_selection_dialog, g_save_selection_dialog_w, 0, 1, 0, H_save_selection_dialog, pl_zb); Xen_define_typed_procedure(S_save_region_dialog, g_save_region_dialog_w, 0, 1, 0, H_save_region_dialog, pl_zb); Xen_define_typed_procedure(S_save_sound_dialog, g_save_sound_dialog_w, 0, 1, 0, H_save_sound_dialog, pl_zb); Xen_define_typed_procedure(S_new_sound_dialog, g_new_sound_dialog_w, 0, 1, 0, H_new_sound_dialog, pl_zb); Xen_define_typed_procedure(S_info_dialog, g_info_dialog_w, 2, 0, 0, H_info_dialog, pl_zss); Xen_define_typed_dilambda(S_sound_loop_info, g_sound_loop_info_w, H_sound_loop_info, S_set S_sound_loop_info, g_set_sound_loop_info_w, 0, 1, 1, 1, pl_lt, pl_ltl); Xen_define_variable(S_snd_opened_sound, snd_opened_sound, Xen_false); #define H_open_hook S_open_hook " (name): called each time a file is opened (before the actual open). \ If it returns " PROC_TRUE ", the file is not opened." #define H_before_close_hook S_before_close_hook " (snd): called each time a file is closed (before the close). \ If it returns " PROC_TRUE ", the file is not closed." #define H_close_hook S_close_hook " (snd): called each time a file is closed (before the close)." #define H_bad_header_hook S_bad_header_hook " (name): called if a file has some bogus-looking header. \ Return " PROC_TRUE " to give up on that file." #define H_after_save_as_hook S_after_save_as_hook " (snd name dialog): called \ upon File:Save as or " S_save_sound_as " completion." #define H_before_save_as_hook S_before_save_as_hook " (snd name selection sampling-rate sample-type header-type comment): called \ before File:Save as or " S_save_sound_as ". Provides a way to fixup a sound just before it is saved." #define H_during_open_hook S_during_open_hook " (fd name reason): called after file is opened, but before data has been read." #if HAVE_SCHEME #define H_after_open_hook S_after_open_hook " (snd): called just before the new file's window is displayed. \ This provides a way to set various sound-specific defaults. \n\ (hook-push " S_after_open_hook "\n\ (lambda (snd) \n\ (if (> (" S_channels " snd) 1) \n\ (set! (" S_channel_style " snd) " S_channels_combined "))))" #endif #if HAVE_RUBY #define H_after_open_hook S_after_open_hook " (snd): called just before the new file's window is displayed. \ This provides a way to set various sound-specific defaults. \n\ $after_open_hook.add-hook!(\"set-channels-combined\") do |snd| \n\ if (channels(snd) > 1) \n\ set_channel_style(Channels_combined, snd)\n\ end\n\ end" #endif #if HAVE_FORTH #define H_after_open_hook S_after_open_hook " (snd): called just before the new file's window is displayed. \ This provides a way to set various sound-specific defaults. \n\ " S_after_open_hook " lambda: <{ snd }>\n\ snd " S_channels " 1 > if\n\ " S_channels_combined " snd set-" S_channel_style "\n\ else\n\ #f\n\ then\n\ ; add-hook!" #endif open_hook = Xen_define_hook(S_open_hook, "(make-hook 'name)", 1, H_open_hook); before_close_hook = Xen_define_hook(S_before_close_hook, "(make-hook 'snd)", 1, H_before_close_hook); close_hook = Xen_define_hook(S_close_hook, "(make-hook 'snd)", 1, H_close_hook); bad_header_hook = Xen_define_hook(S_bad_header_hook, "(make-hook 'name)", 1, H_bad_header_hook); after_save_as_hook = Xen_define_hook(S_after_save_as_hook, "(make-hook 'snd 'name 'dialog)", 3, H_after_save_as_hook); before_save_as_hook = Xen_define_hook(S_before_save_as_hook, "(make-hook 'snd 'name 'selection 'sampling-rate 'sample-type 'header-type 'comment)", 7, H_before_save_as_hook); during_open_hook = Xen_define_hook(S_during_open_hook, "(make-hook 'fd 'name 'reason)", 3, H_during_open_hook); after_open_hook = Xen_define_hook(S_after_open_hook, "(make-hook 'snd)", 1, H_after_open_hook); #define H_open_raw_sound_hook S_open_raw_sound_hook " (name state): called when a headerless sound file is opened. \ Its result can be a list describing the raw file's attributes (thereby bypassing the Raw File Dialog and so on). \ The list is interpreted as (list chans srate sample-type data-location data-length) where trailing elements can \ be omitted (location defaults to 0, and length defaults to the file length in bytes)." open_raw_sound_hook = Xen_define_hook(S_open_raw_sound_hook, "(make-hook 'name 'state)", 2, H_open_raw_sound_hook); #define H_update_hook S_update_hook " (snd): called just before " S_update_sound " is called. \ The update process can be triggered by a variety of situations, not just by " S_update_sound ". \ The hook is passed the sound's index. If it returns " PROC_TRUE ", the update is cancelled (this is not \ recommended!); if it returns a procedure of one argument, that procedure is called upon \ completion of the update operation; its argument is the (possibly different) sound index. \ Snd tries to maintain the index across the update, but if you change the number of channels \ the newly updated sound may have a different index." update_hook = Xen_define_hook(S_update_hook, "(make-hook 'snd)", 1, H_update_hook); Xen_define_typed_procedure(S_snd_tempnam, g_snd_tempnam_w, 0, 0, 0, H_snd_tempnam, pl_s); Xen_define_typed_dilambda(S_auto_update, g_auto_update_w, H_auto_update, S_set S_auto_update, g_set_auto_update_w, 0, 0, 1, 0, pl_b, pl_bb); Xen_define_typed_dilambda(S_auto_update_interval, g_auto_update_interval_w, H_auto_update_interval, S_set S_auto_update_interval, g_set_auto_update_interval_w, 0, 0, 1, 0, pl_d, pl_dr); Xen_define_typed_dilambda(S_ask_before_overwrite, g_ask_before_overwrite_w, H_ask_before_overwrite, S_set S_ask_before_overwrite, g_set_ask_before_overwrite_w, 0, 0, 1, 0, pl_b, pl_bb); Xen_define_typed_dilambda(S_with_toolbar, g_with_toolbar_w, H_with_toolbar, S_set S_with_toolbar, g_set_with_toolbar_w, 0, 0, 1, 0, pl_b, pl_bb); Xen_define_typed_dilambda(S_with_tooltips, g_with_tooltips_w, H_with_tooltips, S_set S_with_tooltips, g_set_with_tooltips_w, 0, 0, 1, 0, pl_b, pl_bb); Xen_define_typed_dilambda(S_with_menu_icons, g_with_menu_icons_w, H_with_menu_icons, S_set S_with_menu_icons, g_set_with_menu_icons_w, 0, 0, 1, 0, pl_b, pl_bb); Xen_define_typed_dilambda(S_save_as_dialog_src, g_save_as_dialog_src_w, H_save_as_dialog_src, S_set S_save_as_dialog_src, g_set_save_as_dialog_src_w, 0, 0, 1, 0, pl_b, pl_bb); Xen_define_typed_dilambda(S_save_as_dialog_auto_comment, g_save_as_dialog_auto_comment_w, H_save_as_dialog_auto_comment, S_set S_save_as_dialog_auto_comment, g_set_save_as_dialog_auto_comment_w, 0, 0, 1, 0, pl_b, pl_bb); Xen_define_typed_dilambda(S_remember_sound_state, g_remember_sound_state_w, H_remember_sound_state, S_set S_remember_sound_state, g_set_remember_sound_state_w, 0, 0, 1, 0, pl_b, pl_bb); Xen_define_typed_dilambda(S_ask_about_unsaved_edits, g_ask_about_unsaved_edits_w, H_ask_about_unsaved_edits, S_set S_ask_about_unsaved_edits, g_set_ask_about_unsaved_edits_w, 0, 0, 1, 0, pl_b, pl_bb); Xen_define_typed_dilambda(S_show_full_duration, g_show_full_duration_w, H_show_full_duration, S_set S_show_full_duration, g_set_show_full_duration_w, 0, 0, 1, 0, pl_b, pl_bb); Xen_define_typed_dilambda(S_show_full_range, g_show_full_range_w, H_show_full_range, S_set S_show_full_range, g_set_show_full_range_w, 0, 0, 1, 0, pl_b, pl_bb); Xen_define_typed_dilambda(S_initial_beg, g_initial_beg_w, H_initial_beg, S_set S_initial_beg, g_set_initial_beg_w, 0, 0, 1, 0, pl_d, pl_dr); Xen_define_typed_dilambda(S_initial_dur, g_initial_dur_w, H_initial_dur, S_set S_initial_dur, g_set_initial_dur_w, 0, 0, 1, 0, pl_d, pl_dr); Xen_define_typed_dilambda(S_default_output_chans, g_default_output_chans_w, H_default_output_chans, S_set S_default_output_chans, g_set_default_output_chans_w, 0, 0, 1, 0, pl_i, pl_ii); Xen_define_typed_dilambda(S_default_output_srate, g_default_output_srate_w, H_default_output_srate, S_set S_default_output_srate, g_set_default_output_srate_w, 0, 0, 1, 0, pl_i, pl_ii); Xen_define_typed_dilambda(S_default_output_header_type, g_default_output_header_type_w, H_default_output_header_type, S_set S_default_output_header_type, g_set_default_output_header_type_w, 0, 0, 1, 0, pl_i, pl_ii); Xen_define_typed_dilambda(S_default_output_sample_type, g_default_output_sample_type_w, H_default_output_sample_type, S_set S_default_output_sample_type, g_set_default_output_sample_type_w, 0, 0, 1, 0, pl_i, pl_ii); Xen_define_typed_dilambda(S_clipping, g_clipping_w, H_clipping, S_set S_clipping, g_set_clipping_w, 0, 0, 1, 0, pl_b, pl_bb); Xen_define_safe_procedure(S_add_file_filter, g_add_file_filter_w, 2, 0, 0, H_add_file_filter); Xen_define_safe_procedure(S_delete_file_filter, g_delete_file_filter_w, 1, 0, 0, H_delete_file_filter); ss->file_filters_size = INITIAL_FILE_FILTERS_SIZE; ss->file_filters = Xen_make_vector(ss->file_filters_size, Xen_false); Xen_GC_protect(ss->file_filters); #if HAVE_SCHEME s7_symbol_set_documentation(s7, ss->default_output_header_type_symbol, "*default-output-header-type*: header type when a new file is created (mus-next etc)"); s7_symbol_set_documentation(s7, ss->default_output_sample_type_symbol, "*default-output-sample-type*: sample type when a new file is created (mus-ldouble etc)"); s7_symbol_set_documentation(s7, ss->default_output_chans_symbol, "*default-output-chans*: number of channels when a new file is created (1)"); s7_symbol_set_documentation(s7, ss->default_output_srate_symbol, "*default-output-srate*: sampling rate when a new file is created (44100)"); s7_symbol_set_documentation(s7, ss->ask_before_overwrite_symbol, "*ask-before-overwrite*: #t if you want Snd to ask before overwriting a file."); s7_symbol_set_documentation(s7, ss->ask_about_unsaved_edits_symbol, "*ask-about-unsaved-edits*: #t if you want Snd to ask whether to save unsaved edits when a sound is closed."); s7_symbol_set_documentation(s7, ss->show_full_duration_symbol, "*show-full-duration*: #t if you want the entire sound displayed whn it is opened."); s7_symbol_set_documentation(s7, ss->show_full_range_symbol, "*show-full-range*: #t if you want the graph y-bounds to accommodate the sound's max and min when it is opened."); s7_symbol_set_documentation(s7, ss->remember_sound_state_symbol, "*remember-sound-state*: #t if you want a Snd to remember the current state of each sound when it is closed, restoring that state when it is opened again later."); s7_symbol_set_documentation(s7, ss->save_as_dialog_src_symbol, "*save-as-dialog-src*: #t if you want the 'src' button set by default in the various Save-as dialogs"); s7_symbol_set_documentation(s7, ss->save_as_dialog_auto_comment_symbol, "*save-as-dialog-auto-comment*: #t if you want the 'auto' button set by default in the various Save-as dialogs"); s7_symbol_set_documentation(s7, ss->with_toolbar_symbol, "*with-toolbar*: #t if you want a toolbar"); s7_symbol_set_documentation(s7, ss->with_tooltips_symbol, "*with-tooltips*: #t if you want tooltips"); s7_symbol_set_documentation(s7, ss->with_menu_icons_symbol, "*with-menu-icons*: #t if you want icons in the menus (gtk only)"); s7_symbol_set_documentation(s7, ss->initial_beg_symbol, "*initial-beg*: the begin point (in seconds) for the initial graph of a sound."); s7_symbol_set_documentation(s7, ss->initial_dur_symbol, "*initial-dur*: the duration (in seconds) for the initial graph of a sound."); s7_symbol_set_documentation(s7, ss->auto_update_symbol, "*auto-update*: #t if Snd should automatically update a file if it changes unexpectedly"); s7_symbol_set_documentation(s7, ss->auto_update_interval_symbol, "*auto-update-interval*: time (seconds) between background checks for changed file on disk (60)"); s7_symbol_set_documentation(s7, ss->clipping_symbol, "*clipping*: #t if Snd should clip output values"); s7_symbol_set_access(s7, ss->default_output_header_type_symbol, s7_make_function(s7, "[acc-" S_default_output_header_type "]", acc_default_output_header_type, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->default_output_sample_type_symbol, s7_make_function(s7, "[acc-" S_default_output_sample_type "]", acc_default_output_sample_type, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->default_output_chans_symbol, s7_make_function(s7, "[acc-" S_default_output_chans "]", acc_default_output_chans, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->default_output_srate_symbol, s7_make_function(s7, "[acc-" S_default_output_srate "]", acc_default_output_srate, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->ask_before_overwrite_symbol, s7_make_function(s7, "[acc-" S_ask_before_overwrite "]", acc_ask_before_overwrite, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->ask_about_unsaved_edits_symbol, s7_make_function(s7, "[acc-" S_ask_about_unsaved_edits "]", acc_ask_about_unsaved_edits, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->show_full_duration_symbol, s7_make_function(s7, "[acc-" S_show_full_duration "]", acc_show_full_duration, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->show_full_range_symbol, s7_make_function(s7, "[acc-" S_show_full_range "]", acc_show_full_range, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->remember_sound_state_symbol, s7_make_function(s7, "[acc-" S_remember_sound_state "]", acc_remember_sound_state, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->save_as_dialog_src_symbol, s7_make_function(s7, "[acc-" S_save_as_dialog_src "]", acc_save_as_dialog_src, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->save_as_dialog_auto_comment_symbol, s7_make_function(s7, "[acc-" S_save_as_dialog_auto_comment "]", acc_save_as_dialog_auto_comment, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->with_toolbar_symbol, s7_make_function(s7, "[acc-" S_with_toolbar "]", acc_with_toolbar, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->with_tooltips_symbol, s7_make_function(s7, "[acc-" S_with_tooltips "]", acc_with_tooltips, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->with_menu_icons_symbol, s7_make_function(s7, "[acc-" S_with_menu_icons "]", acc_with_menu_icons, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->initial_beg_symbol, s7_make_function(s7, "[acc-" S_initial_beg "]", acc_initial_beg, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->initial_dur_symbol, s7_make_function(s7, "[acc-" S_initial_dur "]", acc_initial_dur, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->auto_update_symbol, s7_make_function(s7, "[acc-" S_auto_update "]", acc_auto_update, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->auto_update_interval_symbol, s7_make_function(s7, "[acc-" S_auto_update_interval "]", acc_auto_update_interval, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->clipping_symbol, s7_make_function(s7, "[acc-" S_clipping "]", acc_clipping, 2, 0, false, "accessor")); #endif } snd-16.1/fft-menu.scm0000644000076400007640000001545612622705137012600 0ustar bilbil(when (and (provided? 'xm) (not (provided? 'snd-effects-utils.scm))) (load "effects-utils.scm")) (if (and (provided? 'xg) (not (provided? 'snd-gtk-effects-utils.scm))) (load "gtk-effects-utils.scm")) (define *e* (if (provided? 'snd-motif) *motif* *gtk*)) (define update-label (*e* 'update-label)) (define change-label (*e* 'change-label)) (define make-effect-dialog (*e* 'make-effect-dialog)) (define add-sliders (*e* 'add-sliders)) (define activate-dialog (*e* 'activate-dialog)) (define select-file (*e* 'select-file)) (require snd-examp.scm) (provide 'snd-fft-menu.scm) (define fft-list ()) ; menu labels are updated to show current default settings (define fft-menu (add-to-main-menu "FFT Edits" (lambda () (define (update-label fft) (if (pair? fft) (begin ((car fft)) (update-label (cdr fft))))) (update-label fft-list)))) ;;; ------ FFT edit ;;; (define fft-edit-low-frequency 100) (define fft-edit-high-frequency 1000) (define fft-edit-label "FFT notch filter") (define fft-edit-dialog #f) (define fft-edit-menu-label #f) (define (cp-fft-edit) (fft-edit fft-edit-low-frequency fft-edit-high-frequency)) (if (or (provided? 'xg) (provided? 'xm)) (begin (define (post-fft-edit-dialog) (if (not fft-edit-dialog) ;; if fft-edit-dialog doesn't exist, create it (let ((initial-fft-edit-low-frequency 100) (initial-fft-edit-high-frequency 1000) (sliders ())) (set! fft-edit-dialog (make-effect-dialog fft-edit-label (if (provided? 'snd-gtk) (lambda (w context) (cp-fft-edit)) (lambda (w context info) (cp-fft-edit))) (if (provided? 'snd-gtk) (lambda (w context) (help-dialog "FFT notch filter" "A simple example of FFT-based editing. It takes an FFT of the entire sound, \ removes all energy below the low frequency and above the high frequency, then computes the inverse FFT.")) (lambda (w context info) (help-dialog "FFT notch filter" "A simple example of FFT-based editing. It takes an FFT of the entire sound, \ removes all energy below the low frequency and above the high frequency, then computes the inverse FFT."))) (if (provided? 'snd-gtk) (lambda (w data) (set! fft-edit-low-frequency initial-fft-edit-low-frequency) (set! fft-edit-high-frequency initial-fft-edit-high-frequency) ((*gtk* 'gtk_adjustment_set_value) ((*gtk* 'GTK_ADJUSTMENT) (car sliders)) (floor fft-edit-low-frequency)) ((*gtk* 'gtk_adjustment_set_value) ((*gtk* 'GTK_ADJUSTMENT) (cadr sliders)) (floor fft-edit-high-frequency)) ) (lambda (w c i) (set! fft-edit-low-frequency initial-fft-edit-low-frequency) (set! fft-edit-high-frequency initial-fft-edit-high-frequency) ((*motif* 'XtSetValues) (car sliders) (list (*motif* 'XmNvalue) (floor fft-edit-low-frequency))) ((*motif* 'XtSetValues) (cadr sliders) (list (*motif* 'XmNvalue) (floor fft-edit-high-frequency))))))) (set! sliders (add-sliders fft-edit-dialog (list (list "low frequency" 20 initial-fft-edit-low-frequency 22050 (if (provided? 'snd-gtk) (lambda (w data) (set! fft-edit-low-frequency ((*gtk* 'gtk_adjustment_get_value) ((*gtk* 'GTK_ADJUSTMENT) w)))) (lambda (w context info) (set! fft-edit-low-frequency ((*motif* '.value) info)))) 1) (list "high frequency" 20 initial-fft-edit-high-frequency 22050 (if (provided? 'snd-gtk) (lambda (w data) (set! fft-edit-high-frequency ((*gtk* 'gtk_adjustment_get_value) ((*gtk* 'GTK_ADJUSTMENT) w)))) (lambda (w context info) (set! fft-edit-high-frequency ((*motif* '.value) info)))) 1)))))) (activate-dialog fft-edit-dialog)) (set! fft-edit-menu-label (add-to-menu fft-menu "FFT notch filter" post-fft-edit-dialog))) (set! fft-edit-menu-label (add-to-menu fft-menu fft-edit-label cp-fft-edit))) (set! fft-list (cons (lambda () (let ((new-label (format #f "FFT notch filter (~D ~D)" fft-edit-low-frequency fft-edit-high-frequency))) (if fft-edit-menu-label (change-label fft-edit-menu-label new-label)) (set! fft-edit-label new-label))) fft-list)) ;;; ------ FFT squelch ;;; (define fft-squelch-amount 0.0) (define fft-squelch-label "FFT squelch") (define fft-squelch-dialog #f) (define fft-squelch-menu-label #f) (define (cp-fft-squelch) (fft-squelch fft-squelch-amount)) (if (or (provided? 'xg) (provided? 'xm)) (begin (define (post-fft-squelch-dialog) (if (not fft-squelch-dialog) ;; if fft-squelch-dialog doesn't exist, create it (let ((initial-fft-squelch-amount 0.0) (sliders ())) (set! fft-squelch-dialog (make-effect-dialog fft-squelch-label (if (provided? 'snd-gtk) (lambda (w data )(cp-fft-squelch)) (lambda (w context info) (cp-fft-squelch))) (if (provided? 'snd-gtk) (lambda (w data) (help-dialog "FFT squelch" "Removes all energy below the squelch amount. This is sometimes useful for noise-reduction.")) (lambda (w context info) (help-dialog "FFT squelch" "Removes all energy below the squelch amount. This is sometimes useful for noise-reduction."))) (if (provided? 'snd-gtk) (lambda (w data) (set! fft-squelch-amount initial-fft-squelch-amount) ((*gtk* 'gtk_adjustment_set_value) ((*gtk* 'GTK_ADJUSTMENT) (car sliders)) (round (* fft-squelch-amount 100))) ) (lambda (w c i) (set! fft-squelch-amount initial-fft-squelch-amount) ((*motif* 'XtSetValues) (list-ref sliders 0) (list (*motif* 'XmNvalue) (round (* fft-squelch-amount 100)))))))) (set! sliders (add-sliders fft-squelch-dialog (list (list "squelch amount" 0.0 initial-fft-squelch-amount 1.0 (if (provided? 'snd-gtk) (lambda (w data) (set! fft-squelch-amount (/ ((*gtk* 'gtk_adjustment_get_value) ((*gtk* 'GTK_ADJUSTMENT) w)) 100))) (lambda (w context info) (set! fft-squelch-amount (/ ((*motif* '.value) info) 100)))) 100)))))) (activate-dialog fft-squelch-dialog)) (set! fft-squelch-menu-label (add-to-menu fft-menu "FFT squelch" post-fft-squelch-dialog))) (set! fft-squelch-menu-label (add-to-menu fft-menu fft-squelch-label cp-fft-squelch))) (set! fft-list (cons (lambda () (let ((new-label (format #f "FFT squelch (~1,2F)" fft-squelch-amount))) (if fft-squelch-menu-label (change-label fft-squelch-menu-label new-label)) (set! fft-squelch-label new-label))) fft-list)) (add-to-menu fft-menu #f #f) (add-to-menu fft-menu "Squelch vowels" squelch-vowels) snd-16.1/snd-gtk.scm0000644000076400007640000007350312616231602012415 0ustar bilbil;;; translations from snd-motif.scm ;;; ;;; display-scanned-synthesis ;;; zync and unzync ;;; disable control panel ;;; show-disk-space ;;; remove top level menu ;;; keep-file-dialog-open-upon-ok ;;; snd-clock-icon ;;; bring possibly-obscured dialog to top ;;; select-file ;;; add delete and rename options to the file menu ;;; notebook-with-top-tabs ;;; make-font-selector-dialog ;;; add-main-menu-mnemonics (provide 'snd-snd-gtk.scm) (require snd-gtk snd-extensions.scm snd-play.scm) (with-let *gtk* (define load-font pango_font_description_from_string) (define (g-list-foreach glist func) (let ((len (g_list_length glist))) (do ((i 0 (+ i 1))) ((= i len)) (func (g_list_nth_data glist i))))) (define for-each-child (let ((documentation "(for-each-child w func) applies func to w and each of its children")) (lambda (w func) (func w) (g-list-foreach (gtk_container_get_children (GTK_CONTAINER w)) (lambda (w) (func (GTK_WIDGET w))))))) (define host-name ; this is the same as (define (machine-name) (caddr ((*libc* 'uname)))) (let ((documentation "(host-name) -> name of current machine")) (lambda () (let ((val (gdk_property_get (car (main-widgets)) (gdk_atom_intern "WM_CLIENT_MACHINE" #f) GDK_TARGET_STRING 0 1024 0))) ;; val is list: (success atom element-size length unterminated-string) (and (car val) (substring (val 4) 0 (val 3))))))) #| ;;; -------- display-scanned-synthesis -------- ;;; ;;; open a new main pane below the listener, with two sections ;;; on the left various controls, on the right a graph ;;; push 'start' to start the scanned synthesis display ;;; if spring > mass, you'll get overflows ;;; (define scanned-synthesis-pane #f) (define (display-scanned-synthesis) (define compute-uniform-circular-string ;; copied from dsp.scm to simplify life (lambda (size x0 x1 x2 mass xspring damp) (define circle-float-vector-ref (lambda (v i) (if (< i 0) (v (+ size i)) (if (>= i size) (v (- i size)) (v i))))) (let* ((dm (/ damp mass)) (km (/ xspring mass)) (denom (+ 1.0 dm)) (p1 (/ (+ 2.0 (- dm (* 2.0 km))) denom)) (p2 (/ km denom)) (p3 (/ -1.0 denom))) (do ((i 0 (+ i 1))) ((= i size)) (set! (x0 i) (min (+ (* p1 (x1 i)) (* p2 (+ (circle-float-vector-ref x1 (- i 1)) (circle-float-vector-ref x1 (+ i 1)))) (* p3 (x2 i))) 1000.0))) (copy x1 x2) (copy x0 x1)))) (set! *clm-srate* 22050.0) (let* ((mass 1.0) (xspring 0.1) (damp 0.0) (bounds ()) (pts1 #f) (ax0 0) (ax1 0) (ay0 0) (ay1 0) (gc (car (snd-gcs))) ;; now set up a paned window in the main Snd window with controllers on the left and the graph on the right (scan-outer (let ((pane (gtk_box_new GTK_ORIENTATION_HORIZONTAL 0))) (gtk_box_pack_start (GTK_BOX ((main-widgets) 5)) pane #f #f 4) (gtk_widget_show pane) pane)) (scan-row (let ((box (gtk_box_new GTK_ORIENTATION_VERTICAL 0))) (gtk_box_pack_start (GTK_BOX scan-outer) box #f #f 0) (gtk_widget_show box) box)) ;; the graph (scan-pane (let ((grf (gtk_drawing_area_new))) (gtk_widget_set_events grf GDK_ALL_EVENTS_MASK) (gtk_box_pack_start (GTK_BOX scan-outer) grf #t #t 0) (gtk_widget_show grf) grf)) ;; the controllers (scan-start (let ((label (gtk_button_new_with_label "Start"))) (gtk_box_pack_start (GTK_BOX scan-row) label #t #t 0) (gtk_widget_show label) label)) (scan-continue (let ((label (gtk_button_new_with_label "Continue"))) (gtk_box_pack_start (GTK_BOX scan-row) label #t #t 0) (gtk_widget_show label) label)) (scan-stop (let ((label (gtk_button_new_with_label "Stop"))) (gtk_box_pack_start (GTK_BOX scan-row) label #t #t 0) (gtk_widget_show label) label)) (size 128) (tbl (make-table-lookup :size size)) (amplitude 0.02) (gx0 (mus-data tbl)) (gx1 (make-float-vector size)) (gx2 (make-float-vector size)) (vect (make-vector (* 2 size))) (work-proc #f) (play-button #f)) ; fixed up later -- needed in stop-synthesis (define (y->grfy y range) (min ay1 (max ay0 (round (+ ay0 (* range (- 10.0 y))))))) (define (cairo-draw-lines cr data size) (cairo_set_line_width cr 4.0) (cairo_move_to cr (data 0) (data 1)) (do ((i 1 (+ i 1)) (j 2 (+ j 2))) ((= i size)) (cairo_line_to cr (data j) (data (+ j 1)))) (cairo_stroke cr)) (define (draw-graph cr) (if (and (> ax1 ax0) (> ay1 ay0)) (let ((diff (* 0.05 (- ay1 ay0))) ; assuming -10 to 10 (xincr (/ (- ax1 ax0) size)) (bg-color (color->list *basic-color*))) (cairo_set_source_rgb cr (car bg-color) (cadr bg-color) (caddr bg-color)) (if pts1 (cairo-draw-lines cr pts1 size) (begin (cairo_rectangle cr (+ ax0 2) ay0 (- ax1 ax0 2) (- ay1 ay0)) (cairo_fill cr))) (cairo_set_source_rgb cr 0.0 0.0 0.0) (cairo_set_line_width cr 1.0) (let ((x (floor ax0)) (y (y->grfy (gx0 0) diff))) (cairo_move_to cr x y) (set! (vect 0) x) (set! (vect 1) y)) (do ((i 1 (+ i 1)) (j 2 (+ j 2)) (xi (+ ax0 xincr) (+ xi xincr))) ((= i size)) (let ((x (floor xi)) (y (y->grfy (gx0 i) diff))) (set! (vect j) x) (set! (vect (+ j 1)) y) (cairo_line_to cr x y))) (cairo_stroke cr) (set! pts1 vect)))) (define (redraw-graph) (let* ((wn (GDK_WINDOW (gtk_widget_get_window scan-pane))) (cr (gdk_cairo_create wn))) (set! bounds (draw-axes scan-pane gc "scanned synthesis" 0.0 1.0 -10.0 10.0 x-axis-in-seconds show-all-axes cr)) (set! ax0 (+ (car bounds) 4)) (set! ax1 (caddr bounds)) (set! ay1 (cadr bounds)) (set! ay0 (cadddr bounds)) (draw-graph cr) (cairo_destroy cr))) (define (tick-synthesis n) ;; background process (compute-uniform-circular-string size gx0 gx1 gx2 mass xspring damp) (let* ((wn (GDK_WINDOW (gtk_widget_get_window scan-pane))) (cr (gdk_cairo_create wn))) (draw-graph cr) (cairo_destroy cr)) #t) (define (stop-synthesis) (if work-proc (g_source_remove work-proc)) (set! work-proc #f) (gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON play-button) #f)) (define (start-synthesis) (stop-synthesis) (fill! gx0 0.0) (fill! gx1 0.0) (fill! gx2 0.0) (do ((i 0 (+ i 1))) ((= i 12)) (let ((val (sin (/ (* 2 pi i) 12.0)))) (set! (gx1 (+ i (- (/ size 4) 6))) val))) (set! work-proc (g_idle_add tick-synthesis #f))) (define (continue-synthesis) (stop-synthesis) (set! work-proc (g_idle_add tick-synthesis #f))) ;; controller callbacks (for-each (lambda (data) (let* ((title (data 0)) (minval (data 1)) (maxval (data 2)) (curval (data 3)) (decimals (data 4)) (func (data 5)) (adj (gtk_adjustment_new curval minval maxval 1.0 10.0 1.0)) (scale (gtk_scale_new GTK_ORIENTATION_HORIZONTAL (GTK_ADJUSTMENT adj))) (label (gtk_label_new title))) (gtk_scale_set_digits (GTK_SCALE scale) decimals) (gtk_scale_set_value_pos (GTK_SCALE scale) GTK_POS_TOP) (gtk_scale_set_draw_value (GTK_SCALE scale) #t) (gtk_box_pack_start (GTK_BOX scan-row) scale #t #t 0) (gtk_widget_show scale) (gtk_box_pack_start (GTK_BOX scan-row) label #t #t 0) (gtk_widget_show label) (g_signal_connect adj "value_changed" (lambda (w d) (func (gtk_adjustment_get_value (GTK_ADJUSTMENT adj)))) #f))) (list (list "mass" 1 200 100 2 (lambda (val) (set! mass (/ val 100.0)))) (list "spring" 1 100 10 2 (lambda (val) (set! xspring (/ val 100.0)))) (list "damping" 0 100 0 4 (lambda (val) (set! damp (/ val 10000.0)))))) (let ((scan-size (gtk_box_new GTK_ORIENTATION_HORIZONTAL 4))) (gtk_box_pack_start (GTK_BOX scan-row) scan-size #t #t 6) (gtk_widget_show scan-size) (let ((scan-label (gtk_label_new "Size:"))) (gtk_box_pack_start (GTK_BOX scan-size) scan-label #f #f 10) (gtk_widget_show scan-label) (let ((scan-text (gtk_entry_new))) (gtk_box_pack_start (GTK_BOX scan-size) scan-text #t #t 0) (gtk_widget_show scan-text) (gtk_entry_set_text (GTK_ENTRY scan-text) (number->string size)) (g_signal_connect scan-text "activate" (lambda (w d) (stop-synthesis) (set! size (string->number (gtk_entry_get_text (GTK_ENTRY scan-text)))) (set! tbl (make-table-lookup :size size)) (set! gx0 (mus-data tbl)) (set! gx1 (make-float-vector size)) (set! gx2 (make-float-vector size)) (set! vect (make-vector (* size 2)))) #f)))) (set! play-button (gtk_check_button_new_with_label "play")) (gtk_box_pack_start (GTK_BOX scan-row) play-button #f #f 4) (gtk_widget_show play-button) (g_signal_connect play-button "toggled" (lambda (w d) (if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON play-button)) (let* ((audio-info (open-play-output 1 22050 #f 128)) (audio-fd (car audio-info)) ;; (outchans (cadr audio-info)) (len (caddr audio-info)) (data (make-float-vector len)) (sdata (make-shared-vector data (list 1 len)))) (if (not (= audio-fd -1)) (do () ((not (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON play-button))) (mus-audio-close audio-fd)) (tick-synthesis work-proc) (do ((k 0 (+ 1 k))) ((= k len)) (float-vector-set! data k (* amplitude (table-lookup tbl)))) (mus-audio-write audio-fd sdata len)))))) #f) (let* ((freq-adj (gtk_adjustment_new 440.0 20.0 1000.0 1.0 10.0 1.0)) ; step incr, page incr page size (amp-adj (gtk_adjustment_new 0.02 0.0 0.1 .001 .01 .001)) (freq-scale (gtk_scale_new GTK_ORIENTATION_HORIZONTAL (GTK_ADJUSTMENT freq-adj))) (amp-scale (gtk_scale_new GTK_ORIENTATION_HORIZONTAL (GTK_ADJUSTMENT amp-adj))) (freq-label (gtk_label_new "frequency")) (amp-label (gtk_label_new "amplitude"))) (gtk_scale_set_digits (GTK_SCALE freq-scale) 1) (gtk_scale_set_digits (GTK_SCALE amp-scale) 3) (gtk_scale_set_value_pos (GTK_SCALE freq-scale) GTK_POS_TOP) (gtk_scale_set_value_pos (GTK_SCALE amp-scale) GTK_POS_TOP) (gtk_scale_set_draw_value (GTK_SCALE freq-scale) #t) (gtk_scale_set_draw_value (GTK_SCALE amp-scale) #t) (gtk_box_pack_start (GTK_BOX scan-row) freq-scale #t #t 0) (gtk_box_pack_start (GTK_BOX scan-row) freq-label #t #t 0) (gtk_box_pack_start (GTK_BOX scan-row) amp-scale #t #t 0) (gtk_box_pack_start (GTK_BOX scan-row) amp-label #t #t 0) (gtk_widget_show freq-scale) (gtk_widget_show amp-scale) (gtk_widget_show freq-label) (gtk_widget_show amp-label) (g_signal_connect freq-adj "value_changed" (lambda (w d) (set! (mus-frequency tbl) (gtk_adjustment_get_value (GTK_ADJUSTMENT freq-adj)))) #f) (g_signal_connect amp-adj "value_changed" (lambda (w d) (set! amplitude (gtk_adjustment_get_value (GTK_ADJUSTMENT amp-adj)))) #f) ) (g_signal_connect scan-pane "draw" (lambda (w e d) (redraw-graph)) #f) (g_signal_connect scan-pane "configure_event" (lambda (w e d) (redraw-graph)) #f) (g_signal_connect scan-pane "button_press_event" (lambda (w e d) (let ((button (.button (GDK_EVENT_BUTTON e)))) (if (not work-proc) (if (= button 2) (continue-synthesis) (start-synthesis)) (stop-synthesis)))) #f) (g_signal_connect scan-start "clicked" (lambda (w d) (start-synthesis)) #f) (g_signal_connect scan-continue "clicked" (lambda (w d) (continue-synthesis)) #f) (g_signal_connect scan-stop "clicked" (lambda (w d) (stop-synthesis)) #f) #t)) (define (close-scanned-synthesis-pane) (gtk_widget_hide scanned-synthesis-pane)) |# ;;; -------- zync and unzync: start or stop y-zoom slider sync -------- ;;; ;;; (i.e. when one y-zoom-slider changes position, all other channels in the sound change in parallel) ;;; (zync) to start and (unzync) to stop (define (add-dragger hook) (let ((snd (hook 'snd))) (define (dragger-callback adj context) (let ((val (- 1.0 (gtk_adjustment_get_value (GTK_ADJUSTMENT adj)))) (snd (car context)) (chn (cadr context))) (if (sound-property 'dragger snd) (begin (do ((i 0 (+ i 1))) ((= i (channels snd))) (if (not (= i chn)) (begin (set! (y-zoom-slider snd i) (* val val)) (set! (y-position-slider snd i) (y-position-slider snd chn))))) (g_signal_stop_emission (GPOINTER adj) (g_signal_lookup "value_changed" (G_OBJECT_TYPE (G_OBJECT adj))) 0))))) (set! (sound-property 'dragger snd) #t) (set! (sound-property 'save-state-ignore snd) (cons 'dragger (or (sound-property 'save-state-ignore snd) (list 'save-state-ignore)))) (do ((chn 0 (+ 1 chn))) ((= chn (channels snd))) (let ((zy ((channel-widgets snd chn) 14))) (g_signal_connect_closure_by_id (GPOINTER zy) (g_signal_lookup "value_changed" (G_OBJECT_TYPE (G_OBJECT zy))) 0 (g_cclosure_new dragger-callback (list snd chn) (list 'GClosureNotify 0)) #f))))) (define zync (let ((documentation "(zync) ties each sound's y-zoom sliders together so that all change in paralle if one changes")) (lambda () (hook-push after-open-hook add-dragger) (for-each (lambda (n) (if (not (sound-property 'dragger n)) (add-dragger n))) (sounds))))) (define unzync (let ((documentation "(unzync) undoes a previous (zync) -- subsequently each sound's y-zoom sliders are independent")) (lambda () (hook-remove after-open-hook add-dragger) (for-each (lambda (n) (if (sound-property 'dragger n) (set! (sound-property 'dragger n) #f))) (sounds))))) ;;; -------- disable control panel -------- (define (disable-control-panel snd) (gtk_widget_hide (caddr (sound-widgets snd))) (remove-from-menu 2 "Show controls")) ;;; -------- show-disk-space ;;; ;;; adds a label to the status-area area showing the current free space (define show-disk-space (let ((labelled-snds ())) (define (kmg num) (if (<= num 0) "disk full!" (if (> num 1024) (if (> num (* 1024 1024)) (format #f "space: ~6,3FG" (/ num (* 1024.0 1024.0))) (format #f "space: ~6,3FM" (/ num 1024.0))) (format #f "space: ~10DK" num)))) (define (show-label data) (if (sound? (car data)) (let ((space (kmg (disk-kspace (file-name (car data)))))) (gtk_label_set_text (GTK_LABEL (cadr data)) space) (g_timeout_add 10000 show-label data) ; every 10 seconds recheck space 0))) (define (find-if pred l) (cond ((null? l) #f) ((pred (car l)) (car l)) (else (find-if pred (cdr l))))) (lambda (hook) ;; (show-disk-space snd) adds a label to snd's status-area area showing the current free space (for use with after-open-hook) (let* ((snd (hook 'snd)) (previous-label (find-if (lambda (n) (equal? (car n) snd)) labelled-snds))) (if (not previous-label) (if (not snd) (snd-error "no sound found for disk space label") (let* ((name-form ((sound-widgets) 10)) (space (kmg (disk-kspace (file-name snd)))) (new-label (gtk_label_new space))) (gtk_box_pack_start (GTK_BOX name-form) new-label #f #f 6) (gtk_widget_show new-label) (set! previous-label (list snd new-label)) (set! labelled-snds (cons previous-label labelled-snds)) (g_timeout_add 10000 show-label previous-label)))))))) ;;; -------- remove top level menu ;;; ;;; (remove-main-menu 5) removes the Help menu (define remove-main-menu (let ((documentation "(remove-main-menu menu) removes the specified top-level menu: (remove-main-menu 5) removes the Help menu")) (lambda (menu) (gtk_widget_hide ((menu-widgets) menu))))) ;;; -------- keep-file-dialog-open-upon-ok ;;; ;;; this seems to work, but it's a kludge (define (keep-file-dialog-open-upon-ok) (let ((dialog (open-file-dialog #f))) (g_object_set_data (G_OBJECT dialog) "hide-me" (GPOINTER 1)))) ; anything not 0 means don't hide (this is a stupid kludge forced on me by goddamn gtk) ;;; -------- snd-clock-icon -------- ;;; ;;; a clock icon to replace Snd's hourglass ;;; call from a work proc or whatever with hour going from 0 to 12 then #f (define snd-clock-icon (lambda (snd hour) (let* ((window (GDK_WINDOW (gtk_widget_get_window ((sound-widgets snd) 8)))) (cr (gdk_cairo_create window)) (bg (color->list *basic-color*))) (cairo_set_source_rgb cr (car bg) (cadr bg) (caddr bg)) (cairo_rectangle cr 0 0 16 16) ; icon bg (cairo_fill cr) (cairo_set_source_rgb cr 1.0 1.0 1.0) (cairo_arc cr 8 8 7 0 (* 2 pi)) ; clock face (cairo_fill cr) (cairo_set_line_width cr 2.0) (cairo_set_source_rgb cr 0.0 0.0 0.0) (cairo_move_to cr 8 8) ; clock hour hand (cairo_line_to cr (+ 8 (* 7 (sin (* hour (/ 3.1416 6.0))))) (- 8 (* 7 (cos (* hour (/ 3.1416 6.0)))))) (cairo_stroke cr) (cairo_destroy cr)))) #| ;;; this is the happy face progress bar (define (snd-happy-face snd progress) (let* ((window (GDK_WINDOW (gtk_widget_get_window ((sound-widgets snd) 8)))) (cr (gdk_cairo_create window)) (bg (color->list *basic-color*)) (fc (list 1.0 progress 0.0))) ;; overall background (cairo_set_source_rgb cr (car bg) (cadr bg) (caddr bg)) (cairo_rectangle cr 0 0 16 16) (cairo_fill cr) ;; round face (cairo_set_source_rgb cr (car fc) (cadr fc) (caddr fc)) (cairo_arc cr 8 8 8 0.0 (* 2 pi)) (cairo_fill cr) ;; eyes (cairo_set_source_rgb cr 0.0 0.0 0.0) (cairo_arc cr 5 6 1.5 0 (* 2 pi)) (cairo_fill cr) (cairo_arc cr 11 6 1.5 0 (* 2 pi)) (cairo_fill cr) ;; mouth (cairo_set_line_width cr 1.0) (if (< progress 0.4) (cairo_arc cr 8 14 4 (* 17/16 pi) (* -1/16 pi)) (if (< progress 0.7) (begin (cairo_move_to cr 4 12) (cairo_rel_line_to cr 8 0)) (cairo_arc cr 8 8 5 (* 1/16 pi) (* 15/16 pi)))) (cairo_stroke cr) (cairo_destroy cr))) |# ;;; -------- bring possibly-obscured dialog to top (define (raise-dialog w) (gtk_widget_show w) (gtk_window_present (GTK_WINDOW w))) ;;; -------- select-file -------- ;;; ;;; (select-file func title dir filter help) ;;; starts a File Chooser Dialog, runs func if a file is selected ;;; ;;; (add-to-menu 0 "Insert File" ;;; (lambda () ;;; (select-file ;;; (lambda (filename) ;;; (insert-sound filename)) ;;; "Insert File" "." "*" "file will be inserted at cursor"))) (define select-file (let ((file-selector-dialogs ())) ;; (list (list widget inuse func title help) ...) (define (find-free-dialog ds) (and (pair? ds) (if (not (cadr (car ds))) (begin (set! ((car ds) 1) #t) (caar ds)) (find-free-dialog (cdr ds))))) (lambda args ;; (file-select func title dir filter help) (let* ((func (and (> (length args) 0) (args 0))) (title (if (> (length args) 1) (args 1) "select file")) (dir (if (> (length args) 2) (args 2) ".")) (dialog (or (find-free-dialog file-selector-dialogs) (GTK_FILE_CHOOSER_DIALOG (gtk_file_chooser_dialog_new title #f GTK_FILE_CHOOSER_ACTION_OPEN (list "process-stop" GTK_RESPONSE_REJECT "Ok" GTK_RESPONSE_ACCEPT)))))) (gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER dialog) dir) (if (and (= GTK_RESPONSE_ACCEPT (gtk_dialog_run (GTK_DIALOG dialog))) func) (func (gtk_file_chooser_get_filename (GTK_FILE_CHOOSER dialog)))) (gtk_widget_hide (GTK_WIDGET dialog)))))) ;;(select-file (lambda (n) (snd-print n))) #| ;;; -------- with-level-meters, make-level-meter, display-level (define (make-level-meter parent width height) (let ((frame (gtk_frame_new #f))) (gtk_widget_set_size_request frame width height) (gtk_box_pack_start (GTK_BOX parent) frame #t #t 4) (gtk_widget_show frame) (let ((meter (gtk_drawing_area_new))) (gtk_widget_set_events meter (logior GDK_EXPOSURE_MASK GDK_STRUCTURE_MASK)) (gtk_container_add (GTK_CONTAINER frame) meter) (gtk_widget_show meter) (let ((context (list meter 0.0 1.0 0.0 0.0 width height))) (g_signal_connect meter "draw" (lambda (w e d) (display-level d)) context) (g_signal_connect meter "configure_event" (lambda (w e d) (let ((xy (list (gtk_widget_get_allocated_width w) (gtk_widget_get_allocated_height w)))) (set! (d 5) (car xy)) (set! (d 6) (cadr xy)) (display-level d))) context) context)))) (define (display-level meter-data) (let* ((meter (car meter-data)) (level (meter-data 1)) (last-level (meter-data 3)) (red-deg (meter-data 4)) (width (meter-data 5)) (height (meter-data 6)) ;; (size (meter-data 2)) (win (GDK_WINDOW (gtk_widget_get_window meter)))) ;; this is too slow -- can we save the plate? (also if just 1 meter, put pivot higher?) (let ((cr (gdk_cairo_create win))) ;; put our origin at the meter pivot point scaled (as a square so the dial remains circular) to 0..1 (cairo_translate cr (* 0.5 width) (+ (* 0.5 width) (* 0.2 height))) (cairo_scale cr width width) ;; background (let ((pat (cairo_pattern_create_radial 0 0 .1 0 0 0.75))) (cairo_pattern_add_color_stop_rgb pat 0.0 1.0 0.9 0.0) (cairo_pattern_add_color_stop_rgb pat 1.0 1.0 1.0 1.0) (cairo_rectangle cr -1 -1 2 2) (cairo_set_source cr pat) (cairo_fill cr) (cairo_pattern_destroy pat)) ;; dial markings (cairo_set_source_rgb cr 0.0 0.0 0.0) ;; outer arc (cairo_set_line_width cr (/ 2.0 width)) (cairo_arc cr 0 0 0.5 (* -0.75 pi) (* -0.25 pi)) (cairo_stroke cr) ;; inner arc (cairo_set_line_width cr (/ 0.5 width)) (cairo_arc cr 0 0 (- 0.5 (/ 6.0 width)) (* -0.75 pi) (* -0.25 pi)) (cairo_stroke cr) ;; save unrotated coords (cairo_save cr) ;; ticks (cairo_rotate cr (* 5 (/ pi 4))) (do ((i 0 (+ i 1))) ((= i 5)) (cairo_set_line_width cr (/ 1.5 width)) (if (or (= i 0) (= i 4)) (begin (cairo_move_to cr (- 0.5 (/ 6.0 width)) 0.0) (cairo_rel_line_to cr (/ 15.0 width) 0)) (begin (cairo_move_to cr 0.5 0.0) (cairo_rel_line_to cr (/ 9.0 width) 0))) (cairo_stroke cr) (if (< i 4) (begin (cairo_set_line_width cr (/ 0.5 width)) (do ((j 0 (+ 1 j))) ((= j 5)) (cairo_move_to cr 0.5 0.0) (cairo_rel_line_to cr (/ 6.0 width) 0) (cairo_rotate cr (/ pi (* 8 5))) (cairo_stroke cr))))) (cairo_restore cr) ;; needle and bubble (let* ((needle-speed 0.25) (bubble-speed 0.025) (bubble-size (/ pi 12)) (val (+ (* level needle-speed) (* last-level (- 1.0 needle-speed))))) (cairo_save cr) (cairo_set_line_width cr (/ 2.0 width)) (cairo_rotate cr (+ (* 5 (/ pi 4)) (* val pi 0.5))) (cairo_move_to cr 0 0) (cairo_rel_line_to cr 0.55 0.0) (cairo_stroke cr) (cairo_restore cr) (set! (meter-data 3) val) (if (<= val red-deg) (set! val (+ (* val bubble-speed) (* red-deg (- 1.0 bubble-speed))))) (set! (meter-data 4) val) ;; now the red bubble... (if (> val .01) (begin (cairo_set_source_rgb cr 1.0 0.0 0.0) (cairo_set_line_width cr (/ 5.0 width)) (let ((redx (* val 0.5 pi))) (cairo_arc cr 0 0 (- 0.5 (/ 3.0 width)) (+ (* 5 (/ pi 4)) (max 0.0 (- redx bubble-size))) (+ (* 5 (/ pi 4)) redx)) (cairo_stroke cr))))) (cairo_destroy cr)))) (define (with-level-meters n) ;; add n level meters to a pane at the top of the Snd window (let* ((parent ((main-widgets) 5)) (height (if (> n 2) 70 85)) (pw (gtk_widget_get_window parent)) (parent-width (gtk_widget_get_allocated_height pw)) (width (floor (/ parent-width n))) (meters (gtk_box_new GTK_ORIENTATION_HORIZONTAL 4)) (meter-list ())) (gtk_box_pack_start (GTK_BOX parent) meters #f #f 4) (gtk_widget_set_size_request meters width height) (gtk_widget_show meters) (do ((i 0 (+ i 1))) ((= i n)) (set! meter-list (cons (make-level-meter meters width height) meter-list))) (hook-push dac-hook (lambda (hook) (let* ((sdobj (hook 'data)) (maxes (map float-vector-peak sdobj))) (for-each (lambda (meter) (if (null? maxes) (set! (meter 1) 0.0) (begin (set! (meter 1) (car maxes)) (display-level meter) (set! maxes (cdr maxes))))) (reverse meter-list))))) (hook-push stop-dac-hook (lambda (hook) ; drain away the bubble (g_idle_add (let ((ctr 0)) (lambda (ignored) (for-each (lambda (meter) (set! (meter 1) 0.0) (display-level meter)) meter-list) (set! ctr (+ ctr 1)) (< ctr 200))) #f))) meter-list)) |# ;;; -------- state display panel -------- (define variables-dialog #f) (define variables-notebook #f) (define variables-pages ()) (define (make-variables-dialog) (let ((dismiss-button #f)) (set! variables-dialog (gtk_dialog_new)) (gtk_window_set_title (GTK_WINDOW variables-dialog) "Variables") (gtk_container_set_border_width (GTK_CONTAINER variables-dialog) 10) (gtk_window_set_default_size (GTK_WINDOW variables-dialog) -1 -1) (gtk_window_set_resizable (GTK_WINDOW variables-dialog) #t) (gtk_widget_realize variables-dialog) (g_signal_connect variables-dialog "delete_event" (lambda (w ev data) (gtk_widget_hide variables-dialog) #t) #f) (set! dismiss-button (gtk_dialog_add_button (GTK_DIALOG variables-dialog) "Go Away" GTK_RESPONSE_NONE)) (g_signal_connect dismiss-button "clicked" (lambda (w data) (gtk_widget_hide variables-dialog)) #f) (gtk_widget_show dismiss-button) (gtk_widget_set_name dismiss-button "quit_button") (set! variables-notebook (gtk_notebook_new)) (gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG variables-dialog))) variables-notebook #t #t 4) (gtk_notebook_set_tab_pos (GTK_NOTEBOOK variables-notebook) GTK_POS_RIGHT) (gtk_widget_show variables-notebook) (gtk_widget_show variables-dialog) variables-dialog)) (define* (make-variable-display page-name variable-name (type 'text) (range (list 0.0 1.0))) ;; type = 'text, 'meter, 'graph, 'spectrum, 'scale (if (not variables-dialog) (make-variables-dialog)) (let ((page-info (assoc page-name variables-pages))) (if (not page-info) (let ((vbox (gtk_box_new GTK_ORIENTATION_VERTICAL 0)) (tab (gtk_label_new page-name))) (gtk_widget_show tab) (gtk_widget_show vbox) (gtk_notebook_append_page (GTK_NOTEBOOK variables-notebook) vbox tab) (set! page-info (cons page-name vbox)) (set! variables-pages (cons page-info variables-pages)))) (let ((pane (cdr page-info)) (var-label (string-append variable-name ":"))) (case type ((text) ;; add a horizontal pair: label text (let ((label (gtk_label_new var-label)) (hbox (gtk_box_new GTK_ORIENTATION_HORIZONTAL 0)) (text (gtk_label_new ""))) (gtk_box_pack_start (GTK_BOX pane) hbox #f #f 2) (gtk_widget_show hbox) (gtk_box_pack_start (GTK_BOX hbox) label #f #f 6) (gtk_widget_set_halign (GTK_WIDGET label) GTK_ALIGN_START) (gtk_widget_show label) (gtk_box_pack_start (GTK_BOX hbox) text #t #t 6) (gtk_widget_set_halign (GTK_WIDGET text) GTK_ALIGN_START) (gtk_widget_show text) text)) ((scale) (let ((label (gtk_label_new var-label)) (hbox (gtk_box_new GTK_ORIENTATION_HORIZONTAL 0)) (scale (gtk_progress_bar_new))) (gtk_box_pack_start (GTK_BOX pane) hbox #f #f 2) (gtk_widget_show hbox) (gtk_box_pack_start (GTK_BOX hbox) label #f #f 6) (gtk_widget_set_halign (GTK_WIDGET label) GTK_ALIGN_START) (gtk_widget_show label) (gtk_box_pack_start (GTK_BOX hbox) scale #f #f 6) (gtk_widget_show scale) (list scale (car range) (cadr range)))) ((graph) (let ((snd (make-variable-graph pane (string-append variable-name ": time") 2048 *clm-srate*))) (list (sound->integer snd) (channel-data snd 0)))) ((spectrum) (let ((snd (make-variable-graph pane variable-name 2048 *clm-srate*))) (set! (time-graph? snd 0) #f) (set! (transform-graph? snd 0) #t) (set! (x-axis-label snd 0 transform-graph) (string-append variable-name ": frequency")) (list (sound->integer snd) (channel-data snd 0)))) (else #f))))) (define (variable-display var widget) (define (force-update wid) (gdk_window_invalidate_rect (GDK_WINDOW (gtk_widget_get_window (GTK_WIDGET wid))) (list 'GdkRectangle_ 0) #t) (gdk_window_process_updates (GDK_WINDOW (gtk_widget_get_window (GTK_WIDGET wid))) #t)) (define (widget? w) (and (pair? w) (= (length w) 2) (eq? (car w) 'GtkWidget_))) ;; (let ((wid1 (make-variable-display "do-loop" "i*1" 'spectrum))) (variable-display 0.1 wid1)) (if (widget? widget) (if (GTK_IS_LABEL widget) (begin (gtk_label_set_text (GTK_LABEL widget) (object->string var)) (force-update widget))) (if (pair? widget) (if (or (number? (car widget)) (sound? (car widget))) ;; graph/spectrum -- does this need an explicit update? (let* ((snd (car widget)) (data (cadr widget)) (len (length data)) (loc (cursor snd 0))) (set! (data loc) var) (if (time-graph? snd) (update-time-graph snd)) (if (transform-graph? snd) (update-transform-graph snd)) (if (= (+ loc 1) len) (set! (cursor snd 0) 0) (set! (cursor snd 0) (+ loc 1)))) (if (GTK_IS_PROGRESS_BAR (car widget)) ;; "thermometer" (let ((y0 (cadr widget)) (y1 (caddr widget))) ;; (define wid (make-variable-display "do-loop" "i*2" 'scale)) (gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (car widget)) (max 0.0 (min 1.0 (/ (- var y0) (- y1 y0)))))) )))) var) (define (notebook-with-top-tabs) (gtk_notebook_set_tab_pos (GTK_NOTEBOOK ((main-widgets) 5)) GTK_POS_TOP)) ) ; *gtk*snd-16.1/snd-trans.c0000644000076400007640000013553312527220622012422 0ustar bilbil/* translate various special case sound files to something we can edit * (this code is going away...) * * I'm ignoring proprietary or licensed schemes even where the code is publicly available (Rockwell ADPCM, etc) * * currently supported: * IEEE text * Mus10 16-bit SAM (mode 4) * HCOM (from Sox) * shortpack NIST * Dvi-Intel (IMA) ADPCM RIFF (comes in 3 and 4 bit flavors, but just 4-bit here) (MS and Apple are variations of this) * MIDI sample dump * Oki (Dialogic) ADPCM (RIFF) * IBM ADPCM (as per Perry Cook) * Yamaha TX-16 12-bit * * libavcodec has an amazing number of decoders -- are these useful in this context? * also libmpcodecs (available with MPlayer) */ #include "snd.h" #define TRANS_BUF_SIZE 8192 static char write_error_buffer[PRINT_BUFFER_SIZE]; static long long int snd_checked_write(int fd, unsigned char *buf, long long int bytes, const char *filename) { /* io.c checked_write assumes its file descriptors are around */ /* can't call mus_error here because we need to clean up first in case of error */ long long int bytes_written; mus_long_t kfree; kfree = (long long int)disk_kspace(filename); if (kfree < 0) { snprintf(write_error_buffer, PRINT_BUFFER_SIZE, "no space left on device: %s", snd_io_strerror()); return(MUS_ERROR); } if (kfree < (bytes >> 10)) { snprintf(write_error_buffer, PRINT_BUFFER_SIZE, "only %lld bytes left on device (we need %lld bytes)", kfree << 10, bytes); return(MUS_ERROR); } bytes_written = write(fd, buf, bytes); if (bytes_written != bytes) { snprintf(write_error_buffer, PRINT_BUFFER_SIZE, "write error (wrote %lld of requested %lld bytes): %s", bytes_written, bytes, snd_io_strerror()); return(MUS_ERROR); } return(bytes_written); } static int be_snd_checked_write(int fd, unsigned char *buf, int bytes, const char *filename) { /* handle little-endian swap if necessary */ #if MUS_LITTLE_ENDIAN int i; for (i = 0; i < bytes; i += 2) { unsigned char tmp; tmp = buf[i]; buf[i] = buf[i + 1]; buf[i + 1] = tmp; } #endif return(snd_checked_write(fd, buf, bytes, filename)); } #define return_mus_io_error(IO_Func, IO_Name) return(mus_error(MUS_CANT_OPEN_FILE, "translator: %s(%s) %s", IO_Func, IO_Name, snd_io_strerror())) #define return_mus_write_error(OldName, NewName) \ do { \ mus_error(MUS_WRITE_ERROR, "can't translate %s to %s:\n %s", OldName, NewName, write_error_buffer); \ write_error_buffer[0] = '\0'; \ return(MUS_ERROR); \ } \ while (false) #define return_mus_alloc_error(OldName, Bytes, VariableName) \ return(mus_error(MUS_MEMORY_ALLOCATION_FAILED, "translate %s: can't allocate %d bytes for %s", OldName, Bytes, VariableName)) /* I'm using the same variable names in most cases below, so these two macros save lots of repetition */ #define CLEANUP(OldName, NewName) \ do { \ if (fs != -1) snd_close(fs, NewName); \ if (fd != -1) snd_close(fd, OldName); \ if (buf) free(buf); \ } \ while (false) #define STARTUP(OldName, NewName, BufSize, BufType) \ do { \ fs = CREAT(NewName, 0666); \ if (fs == -1) return_mus_io_error("create", NewName); \ fd = OPEN(OldName, O_RDONLY, 0); \ if (fd == -1) \ { \ CLEANUP(OldName, NewName); \ return_mus_io_error("open", OldName); \ } \ buf = (BufType *)calloc(BufSize, sizeof(BufType)); \ if (buf == NULL) \ { \ CLEANUP(OldName, NewName); \ return_mus_alloc_error(OldName, BufSize, "buf"); \ } \ } \ while (false) /* -------------------------------- MIDI sample dump -------------------------------- */ /* F0 7E 01 ss ss ee ff ff ff gg gg gg hh hh hh ii ii ii jj f7 * ss: sample# (LSB MSB), ee: #bits, ff: 1/srate in nsec, gg: samples, hh: loop ii: loop jj: loop * 0000000 f07e 0001 0000 1048 5007 7479 0000 0000 * 0000020 0000 007f f7f0 7e00 0200 4000 003f 7140 */ static int read_midi_sample_dump(const char *oldname, const char *newname, char *hdr) { int fs = -1, fd = -1, err = MUS_NO_ERROR, chans, srate, inp, outp; ssize_t totalin; bool happy; int val = 0, bits, block_count, header_count, state, samples, shift1, shift2, offset; int osp; unsigned char *buf = NULL; chans = 1; STARTUP(oldname, newname, TRANS_BUF_SIZE, unsigned char); totalin = read(fd, buf, TRANS_BUF_SIZE); bits = buf[6]; srate = (int)(1.0e9 / (float)((buf[7] + (buf[8] << 7) + (buf[9] << 14)))); samples = (buf[10] + (buf[11] << 7) + (buf[12] << 14)); mus_bint_to_char((unsigned char *)(hdr + 16), srate); mus_bint_to_char((unsigned char *)(hdr + 20), chans); if (bits == 16) mus_bint_to_char((unsigned char *)(hdr + 8), samples * 2); else mus_bint_to_char((unsigned char *)(hdr + 8), samples); if (snd_checked_write(fs, (unsigned char *)hdr, 28, newname) == MUS_ERROR) { CLEANUP(oldname, newname); return_mus_write_error(oldname, newname); } happy = true; inp = 21; block_count = 120; state = 2; header_count = 5; outp = 0; osp = 0; /* we could be really wacked out and implement any sample width here */ if (bits == 16) { shift1 = 9; shift2 = 5; offset = 32768; } else { shift1 = 1; shift2 = 6; offset = 128; } while (happy) { if (inp >= totalin) { if (totalin < TRANS_BUF_SIZE) happy = false; else { totalin = read(fd, buf, TRANS_BUF_SIZE); inp = 0; } } if (outp >= TRANS_BUF_SIZE) { if (snd_checked_write(fs, (unsigned char *)hdr, TRANS_BUF_SIZE, newname) == MUS_ERROR) { CLEANUP(oldname, newname); return_mus_write_error(oldname, newname); } osp = 0; outp = 0; } if (happy) { if (state != 2) { block_count--; if (block_count == 0) { state = 2; header_count = 7; } } switch (state) { case 0: /* val = buf[inp]; */ /* hmmm... I wonder about this -- the MIDI spec says LSB first, * but the Goldwave midi sample dump output sends MSB first. * I bet this is a bug */ val = buf[inp] << shift1; state = ((bits == 16) ? 1 : 3); break; case 1: /* val |= (buf[inp] << 7); */ val |= (buf[inp] << 2); state = 3; break; case 2: header_count--; if (header_count == 0) { state = 0; block_count = 121; } break; case 3: /* val |= (buf[inp] << shift1); */ val |= (buf[inp] >> shift2); state = 0; mus_bshort_to_char((unsigned char *)(hdr + osp), (short)(val - offset)); osp += 2; outp += 2; break; } inp++; } } if (outp > 0) err = snd_checked_write(fs, (unsigned char *)hdr, outp, newname); CLEANUP(oldname, newname); if (err == MUS_ERROR) return_mus_write_error(oldname, newname); return(MUS_NO_ERROR); } /* -------------------------------- IEEE TEXT -------------------------------- */ static int read_ieee_text(const char *oldname, const char *newname, char *hdr) { /* from untext.c */ /* look for "%sampling rate: nn.nn KHz\n", also get end of to comment (i.e. data location) */ char str[32]; char *buf = NULL; int fd = -1, fs = -1; ssize_t totalin; int inp, outp, op, i, j, s0, srate, err = MUS_NO_ERROR; bool commenting, happy; float fsrate; int osp; STARTUP(oldname, newname, TRANS_BUF_SIZE, char); totalin = read(fd, buf, TRANS_BUF_SIZE); commenting = true; inp = 0; outp = 24; srate = 0; op = 0; while ((commenting) && (inp < totalin)) { if (buf[inp] == '%') {op = inp; inp++;} else { if (buf[inp] == '\n') { if (srate == 0) { for (i = op + 1, j = 0; (i < inp) && (j < 13); i++, j++) str[j] = buf[i]; str[13] = '\0'; if (strcmp(str, "sampling rate") == 0) { for (i = op + 15, j = 0; j < 6; i++, j++) str[j] = buf[i]; str[6] = '\0'; sscanf(str, "%6f", &fsrate); srate = (int)(fsrate * 1000); } else { if (strcmp(str, "Sampling Rate") == 0) { for (i = op + 15, j = 0; j < 6; i++, j++) str[j] = buf[i]; str[6] = '\0'; sscanf(str, "%6d", &srate); } } } inp++; if (buf[inp] != '%') commenting = false; else { hdr[outp] = '\n'; outp++; } } else { hdr[outp] = buf[inp]; outp++; inp++; } } } if (srate == 0) { CLEANUP(oldname, newname); return(MUS_ERROR); } i = (outp % 4); outp += i; mus_bint_to_char((unsigned char *)(hdr + 4), outp); mus_bint_to_char((unsigned char *)(hdr + 16), srate); if (snd_checked_write(fs, (unsigned char *)hdr, outp, newname) == MUS_ERROR) { CLEANUP(oldname, newname); return_mus_write_error(oldname, newname); } happy = true; s0 = 0; outp = 0; osp = 0; while (happy) { if (inp >= totalin) { if (totalin < TRANS_BUF_SIZE) happy = false; else { totalin = read(fd, buf, TRANS_BUF_SIZE); inp = 0; } } if (outp >= TRANS_BUF_SIZE) { if (snd_checked_write(fs, (unsigned char *)hdr, TRANS_BUF_SIZE, newname) == MUS_ERROR) { CLEANUP(oldname, newname); return_mus_write_error(oldname, newname); } osp = 0; outp = 0; } if (happy) { if (buf[inp] == '\n') { str[s0] = '\0'; sscanf(str, "%12d", &j); mus_bshort_to_char((unsigned char *)(hdr + osp), (short)j); osp += 2; outp += 2; inp++; s0 = 0; } else { str[s0] = buf[inp]; s0++; inp++; } } } err = snd_checked_write(fs, (unsigned char *)hdr, outp, newname); /* update size field? */ CLEANUP(oldname, newname); if (err == MUS_ERROR) return_mus_write_error(oldname, newname); return(MUS_NO_ERROR); } /* -------------------------------- Mus10 -------------------------------- */ #define PDP_BUF_SIZE (9*1024) static int read_mus10(const char *oldname, const char *newname, char *hdr) { /* from trans.lisp */ /* nostalgic code -- 36 bit words, two 16-bit samples, right justified */ /* or (even more archaeological) 12 bits packed 3 to a 36-bit word */ unsigned char *buf = NULL; int fd = -1, fs = -1, inp, outp, val, err = MUS_NO_ERROR; ssize_t totalin; bool happy; int osp; float fsrate, fraction; int srateH, srateL, sign, exponent, chans, mode; STARTUP(oldname, newname, PDP_BUF_SIZE, unsigned char); totalin = read(fd, buf, PDP_BUF_SIZE); /* read the PDP-10 float srate, nchans, mode, etc */ /* old header started with 36 bits of 0xaaaaaaaaa */ srateH = (((buf[4] & 0xF) << 14) | (buf[5] << 6) | (buf[6] >> 2)); srateL = (((buf[6] & 0x3) << 16) | (buf[7] << 8) | (buf[8])); /* PDP-10 floating point format was sign in bit 0 , excess 128 exponent in 1-8, fraction in 9-35 */ if (srateH & 0400000) sign = -1; else sign = 1; exponent = ((srateH & 0377000) >> 9) - 128; fraction = (float)(((srateH & 0777) << 18) | srateL) / snd_int_pow2(27); fsrate = sign * snd_int_pow2(exponent) * fraction; if (fsrate > 6400.0) mus_bint_to_char((unsigned char *)(hdr + 16), (int)fsrate); else { /* perhaps old style header? */ if (srateH != 0) mus_bint_to_char((unsigned char *)(hdr + 16), srateH); } mode = ((buf[11] & 0x3F) << 12) | (buf[12] << 4) | (buf[13] >> 4); chans = ((buf[15] & 0x3) << 12) | (buf[16] << 8) | buf[17]; if (chans == 0) chans = 1; mus_bint_to_char((unsigned char *)(hdr + 20), chans); if ((mode != 4) && (mode != 0)) { CLEANUP(oldname, newname); return(mus_error(MUS_UNSUPPORTED_SAMPLE_TYPE, "read_mus10: can't translate Mus10 file %s:\n mode = %d\n", oldname, mode)); } /* 4 = SAM 16-bit packing mode, 0 = 12 bit 3 to a word */ /* now jump to data start */ inp = 576; if (snd_checked_write(fs, (unsigned char *)hdr, 28, newname) == MUS_ERROR) { CLEANUP(oldname, newname); return_mus_write_error(oldname, newname); } happy = true; outp = 0; osp = 0; while (happy) { if (inp >= totalin) { if (totalin < PDP_BUF_SIZE) happy = false; else { totalin = read(fd, buf, PDP_BUF_SIZE); inp = 0; } } if (outp >= TRANS_BUF_SIZE) { if (snd_checked_write(fs, (unsigned char *)hdr, TRANS_BUF_SIZE, newname) == MUS_ERROR) { CLEANUP(oldname, newname); return_mus_write_error(oldname, newname); } osp = 0; outp = 0; } if (happy) { if (mode == 4) { /* packed 4 bits junk | 16 bit | 16 bit per each 36 */ /* so we grab four at a time here to keep the pointers aligned */ /* we've chosen an input buffer size that is a multiple of 9 so that this code need not constantly check bounds */ val = ((buf[inp] & 0xF) << 12) | (buf[inp + 1] << 4) | (buf[inp + 2] >> 4); mus_bshort_to_char((unsigned char *)(hdr + osp), (short)val); osp += 2; val = ((buf[inp + 2] & 0xF) << 12) | (buf[inp + 3] << 4) | (buf[inp + 4] >> 4); mus_bshort_to_char((unsigned char *)(hdr + osp), (short)val); osp += 2; mus_bshort_to_char((unsigned char *)(hdr + osp), (short)((buf[inp + 5] << 8) | buf[inp + 6])); osp += 2; mus_bshort_to_char((unsigned char *)(hdr + osp), (short)((buf[inp + 7] << 8) | buf[inp + 8])); osp += 2; outp += 8; inp += 9; } else { val = (buf[inp] << 8) | (buf[inp + 1] & 0xF0); mus_bshort_to_char((unsigned char *)(hdr + osp), (short)val); osp += 2; val = ((buf[inp + 1] & 0xF) << 12) | (buf[inp + 2] << 4); mus_bshort_to_char((unsigned char *)(hdr + osp), (short)val); osp += 2; outp += 4; inp += 3; } } } err = snd_checked_write(fs, (unsigned char *)hdr, outp, newname); CLEANUP(oldname, newname); if (err == MUS_ERROR) return_mus_write_error(oldname, newname); return(MUS_NO_ERROR); } /* -------------------------------- HCOM (from Sox) -------------------------------- */ static int read_hcom(const char *oldname, const char *newname, char *hdr) { short **d = NULL; int osp, isp; int dc = 0, di, bits, outp; ssize_t totalin; bool happy; unsigned int curval = 0; int i, sample, size = 0, datum, count = 0, err = MUS_NO_ERROR; unsigned char *buf = NULL; int fd = -1, fs = -1; size_t bytes; STARTUP(oldname, newname, TRANS_BUF_SIZE, unsigned char); if (snd_checked_write(fs, (unsigned char *)hdr, 28, newname) == MUS_ERROR) { CLEANUP(oldname, newname); return_mus_write_error(oldname, newname); } lseek(fd, 132, SEEK_SET); bytes = read(fd, buf, 18); /* count sum type div size */ if (bytes != 0) { count = mus_char_to_bint((unsigned char *)buf) - 1; dc = mus_char_to_bint((unsigned char *)(buf + 8)); size = mus_char_to_bshort((unsigned char *)(buf + 16)); d = (short **)calloc(size, sizeof(short *)); bytes = read(fd, buf, size * 4 + 2); /* 2 for pad byte + first sample */ } if (bytes == 0) { if (d) free(d); CLEANUP(oldname, newname); return_mus_write_error(oldname, newname); /* read actually, but it's a generic message */ } osp = 0; for (i = 0; i < size; i++) { d[i] = (short *)calloc(2, sizeof(short)); d[i][0] = mus_char_to_bshort((unsigned char *)(buf + osp)); osp += 2; d[i][1] = mus_char_to_bshort((unsigned char *)(buf + osp)); osp += 2; } sample = mus_char_to_bshort((unsigned char *)(buf + osp)) & 0xff; di = 0; totalin = read(fd, buf, TRANS_BUF_SIZE); osp = 0; isp = 0; happy = true; outp = 2; mus_bshort_to_char((unsigned char *)(hdr + osp), (short)((sample - 128) * 0x100)); osp += 2; bits = 0; while ((happy) && (count > 0)) { if (isp >= totalin) { if (totalin < TRANS_BUF_SIZE) happy = false; else { totalin = read(fd, buf, TRANS_BUF_SIZE); isp = 0; } } if (outp >= TRANS_BUF_SIZE) { if (snd_checked_write(fs, (unsigned char *)hdr, TRANS_BUF_SIZE, newname) == MUS_ERROR) { for (i = 0; i < size; i++) free(d[i]); free(d); CLEANUP(oldname, newname); return_mus_write_error(oldname, newname); } osp = 0; outp = 0; } if (happy) { if (bits == 0) { curval = mus_char_to_bint((unsigned char *)(buf + isp)); isp+=4; bits = 32; } if (curval & 0x80000000) di = d[di][1]; else di = d[di][0]; curval = curval << 1; bits--; if (d[di][0] < 0) { datum = d[di][1]; if (!dc) sample = 0; sample = (sample + datum) & 0xff; count--; if (sample == 0) mus_bshort_to_char((unsigned char *)(hdr + osp), (short)(-127 * 0x100)); else mus_bshort_to_char((unsigned char *)(hdr + osp), (short)((sample - 128) * 0x100)); osp += 2; outp += 2; di = 0; } } } err = snd_checked_write(fs, (unsigned char *)hdr, outp, newname); for (i = 0; i < size; i++) free(d[i]); free(d); CLEANUP(oldname, newname); if (err == MUS_ERROR) return_mus_write_error(oldname, newname); return(MUS_NO_ERROR); } /* -------------------------------- NIST shortpack -------------------------------- */ static unsigned short log2s[] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768}; static int read_nist_shortpack(const char *oldname, const char *newname, char *hdr) { int fs = -1, fd = -1, err = MUS_NO_ERROR, chans, srate, outp, i = 0, k, num, bits = 0, out, els = 0; ssize_t totalin; bool happy; int isp, osp; unsigned short *ptr = NULL, *stop, *start, *kptr; short temp = 0; bool negative; unsigned char *buf = NULL; chans = mus_sound_chans(oldname); srate = mus_sound_srate(oldname); mus_bint_to_char((unsigned char *)(hdr + 16), srate); mus_bint_to_char((unsigned char *)(hdr + 20), chans); STARTUP(oldname, newname, TRANS_BUF_SIZE, unsigned char); if (snd_checked_write(fs, (unsigned char *)hdr, 28, newname) == MUS_ERROR) { CLEANUP(oldname, newname); return_mus_write_error(oldname, newname); } lseek(fd, 1024, SEEK_SET); /* NIST header always 1024 bytes */ totalin = read(fd, buf, TRANS_BUF_SIZE); happy = true; outp = 0; num = 0; osp = 0; /* hdr */ isp = 0; /* buf */ start = &(log2s[15]); stop = log2s; while (happy) { /* now the shortpack algorithm, taken from wavio's shortpack_io.c */ if (num == 0) { num = (int)buf[isp]; bits = (int)buf[isp + 1]; isp += 2; if (isp >= totalin) { totalin = read(fd, buf, TRANS_BUF_SIZE); isp = 0; } temp = mus_char_to_bshort((unsigned char *)(buf + isp)); isp += 2; if (isp >= totalin) { totalin = read(fd, buf, TRANS_BUF_SIZE); isp = 0; } ptr = start; i = 0; els = (int)((num * (bits + 1)) / 16.0); if ((num * (bits + 1)) % 16 != 0) els++; els--; } else { /* get next sample */ out = 0; negative = ((temp & *(ptr--)) != 0); if (ptr < stop) { ptr = start; if (els > 0) { temp = mus_char_to_bshort((unsigned char *)(buf + isp)); isp += 2; if (isp >= totalin) { totalin = read(fd, buf, TRANS_BUF_SIZE); isp = 0; } els--; } } kptr = &(log2s[bits - 1]); for (k = bits + 1; (--k) > 0; ) { if ((temp & *(ptr--)) != 0) out |= *kptr; kptr--; if (ptr < stop) { ptr = start; if (els > 0) { temp = mus_char_to_bshort((unsigned char *)(buf + isp)); isp += 2; if (isp >= totalin) { totalin = read(fd, buf, TRANS_BUF_SIZE); isp = 0; } els--; } } } if (negative) { if (out != 0) mus_bshort_to_char((unsigned char *)(hdr + osp), (short)(-out)); else mus_bshort_to_char((unsigned char *)(hdr + osp), (short)32767); } else mus_bshort_to_char((unsigned char *)(hdr + osp), (short)out); osp += 2; outp += 2; i++; if (i == num) num = 0; } if (isp >= totalin) { if (totalin < TRANS_BUF_SIZE) happy = false; else { totalin = read(fd, buf, TRANS_BUF_SIZE); isp = 0; } } if (outp >= TRANS_BUF_SIZE) { if (snd_checked_write(fs, (unsigned char *)hdr, TRANS_BUF_SIZE, newname) == MUS_ERROR) { CLEANUP(oldname, newname); return_mus_write_error(oldname, newname); } osp = 0; outp = 0; } } err = snd_checked_write(fs, (unsigned char *)hdr, outp, newname); CLEANUP(oldname, newname); if (err == MUS_ERROR) return_mus_write_error(oldname, newname); return(MUS_NO_ERROR); } /* -------------------------------- IBM ADPCM -------------------------------- * * taken from Perry Cook's adpcmdec.c */ static int read_ibm_adpcm(const char *oldname, const char *newname, char *hdr) { short MAX_STEP = 2048, MIN_STEP = 16; int i, j, k, fs = -1, fd = -1; unsigned char *buf = NULL; short *buf1; mus_long_t loc; short XHAT1 = 0, delndec, del1dec = 8, ln1dec, temp; float M[16] = {0.909, 0.909, 0.909, 0.909, 1.21, 1.4641, 1.771561, 2.143589, 0.909, 0.909, 0.909, 0.909, 1.21, 1.4641, 1.771561, 2.143589}; float del_table[16] = {0.0, 0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 0.0, -0.25, -0.5, -0.75, -1.0, -1.25, -1.5, -1.75}; loc = mus_sound_data_location(oldname); mus_bint_to_char((unsigned char *)(hdr + 16), mus_sound_srate(oldname)); mus_bint_to_char((unsigned char *)(hdr + 20), 1); STARTUP(oldname, newname, TRANS_BUF_SIZE, unsigned char); if (snd_checked_write(fs, (unsigned char *)hdr, 28, newname) == MUS_ERROR) { CLEANUP(oldname, newname); return_mus_write_error(oldname, newname); } lseek(fd, loc, SEEK_SET); buf1 = (short *)calloc(TRANS_BUF_SIZE, sizeof(short)); while (true) { ssize_t totalin; totalin = read(fd, buf, TRANS_BUF_SIZE / 4); if (totalin <= 0) break; for (i = 0, j = 0; i < totalin; i += 2, j += 4) { unsigned short data_in; data_in = (*((short *)(buf + i))); for (k = 0; k < 4; k++) { ln1dec = data_in >> 12; data_in = data_in << 4; delndec = (short)(del1dec * M[ln1dec]); temp = delndec - MIN_STEP; if (temp < 0) delndec = MIN_STEP; temp = MAX_STEP - delndec; if (temp < 0) delndec = MAX_STEP; del1dec = delndec; XHAT1 += (short)(delndec * del_table[ln1dec]); if (XHAT1 > 32000 || XHAT1 < -32000) XHAT1 = (short)(XHAT1 * 0.95); buf1[j + k] = XHAT1; } } if (be_snd_checked_write(fs, (unsigned char *)buf1, j * 2, newname) == MUS_ERROR) { free(buf1); CLEANUP(oldname, newname); return_mus_write_error(oldname, newname); } } free(buf1); CLEANUP(oldname, newname); return(MUS_NO_ERROR); } /* -------------------------------- Intel ADPCM -------------------------------- * * described in detail in the Microsoft RIFF docs. This code assumes bits = 4. * in 'wave' file, these are stored as block_align sized blocks, each with a * header storing the current state. These can be multi-channel, but we're handling * only mono until someone complains. See also Apple Tech note 1081 by Mark Cookson. */ static int indexTable[16] = {-1, -1, -1, -1, 2, 4, 6, 8, -1, -1, -1, -1, 2, 4, 6, 8}; static int stepsizeTable[89] = {7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767}; static int adpcm_decoder(unsigned char *indata, short *outdata, int totalbytes, int type) { unsigned int delta, inputbuffer = 0; int valpred, index, i, j; bool happy; bool bufferstep = false; happy = true; if (type == 0) { j = 4; valpred = mus_char_to_lshort(indata); index = indata[2]; } else { j = 2; index = indata[1] & 0x7f; valpred = (indata[0] * 0x100) + (indata[1] & 0xff80); } i = 1; outdata[0] = valpred; while (happy) { int step, vpdiff; if (bufferstep) { delta = inputbuffer & 0xf; if (j == totalbytes) happy = false; } else { inputbuffer = indata[j++]; delta = (inputbuffer >> 4) & 0xf; } bufferstep = !bufferstep; step = stepsizeTable[index]; vpdiff = (step >> 3); if (delta & 1) vpdiff += (step >> 2); if (delta & 2) vpdiff += (step >> 1); if (delta & 4) vpdiff += step; if (delta & 8) valpred -= vpdiff; else valpred += vpdiff; if (valpred > 32767) valpred = 32767; else if (valpred < -32768) valpred = -32768; outdata[i++] = valpred; index += indexTable[delta]; if (index < 0) index = 0; else if (index > 88) index = 88; } return(i); } static int read_dvi_adpcm(const char *oldname, const char *newname, char *hdr, int type) { int fs = -1, fd = -1, chans, srate, blksiz, samps; unsigned char *buf = NULL; mus_long_t loc; loc = mus_sound_data_location(oldname); chans = mus_sound_chans(oldname); blksiz = mus_sound_block_align(oldname); samps = mus_sound_fact_samples(oldname); if ((chans != 1) || (mus_sound_bits_per_sample(oldname) != 4)) return(mus_error(MUS_UNSUPPORTED_SAMPLE_TYPE, "read_dvi_adpcm: can't translate DVI ADPCM file %s: chans: %d and bits: %d\n", oldname, chans, mus_sound_bits_per_sample(oldname))); srate = mus_sound_srate(oldname); mus_bint_to_char((unsigned char *)(hdr + 16), srate); mus_bint_to_char((unsigned char *)(hdr + 20), chans); STARTUP(oldname, newname, blksiz, unsigned char); if (snd_checked_write(fs, (unsigned char *)hdr, 28, newname) == MUS_ERROR) { CLEANUP(oldname, newname); return_mus_write_error(oldname, newname); } lseek(fd, loc, SEEK_SET); while (samps > 0) { int samps_read; ssize_t totalin; totalin = read(fd, buf, blksiz); if (totalin < blksiz) break; samps_read = adpcm_decoder(buf, (short *)hdr, totalin, type); if (be_snd_checked_write(fs, (unsigned char *)hdr, samps_read * 2, newname) == MUS_ERROR) { CLEANUP(oldname, newname); return_mus_write_error(oldname, newname); } samps -= samps_read; } CLEANUP(oldname, newname); return(MUS_NO_ERROR); } /* --------------------------------Oki (Dialogic) ADPCM -------------------------------- * * from vox.tar.gz: * "PC Telephony - The complete guide to designing, building and programming systems * using Dialogic and Related Hardware" by Bob Edgar. pg 272-276. */ struct oki_adpcm_status {short last; short step_index;}; static short oki_step_size[49] = { 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282, 1408, 1552 }; static short oki_adjust[8] = {-1, -1, -1, -1, 2, 4, 6, 8}; static short oki_adpcm_decode(char code, struct oki_adpcm_status *stat) { short diff, E8, SS8, samp; /* SS apparently a predefined macro in Solaris 10.4/opteron */ SS8 = oki_step_size[stat->step_index]; E8 = SS8/8; if (code & 0x01) E8 += SS8 / 4; if (code & 0x02) E8 += SS8 / 2; if (code & 0x04) E8 += SS8; diff = (code & 0x08) ? -E8 : E8; samp = stat->last + diff; if (samp > 2048) samp = 2048; if (samp < -2048) samp = -2048; stat->last = samp; stat->step_index += oki_adjust[code & 0x07]; if (stat->step_index < 0) stat->step_index = 0; if (stat->step_index > 48) stat->step_index = 48; if (samp == 2048) return(32767); return(samp << 4); } static int read_oki_adpcm(const char *oldname, const char *newname, char *hdr) { int fs = -1, fd = -1, i, j, chans, srate, blksiz, samps; unsigned char *buf = NULL; mus_long_t loc; short *buf1; struct oki_adpcm_status stat; chans = mus_sound_chans(oldname); if (chans != 1) return(mus_error(MUS_UNSUPPORTED_SAMPLE_TYPE, "read_oki_adpcm: can't translate Oki ADPCM file %s: chans: %d\n", oldname, chans)); loc = mus_sound_data_location(oldname); blksiz = mus_sound_block_align(oldname); if (blksiz == 0) blksiz = 256; STARTUP(oldname, newname, blksiz, unsigned char); buf1 = (short *)calloc(blksiz * 2, sizeof(short)); samps = mus_sound_fact_samples(oldname); if (samps == 0) samps = (int)mus_sound_framples(oldname); srate = mus_sound_srate(oldname); mus_bint_to_char((unsigned char *)(hdr + 16), srate); mus_bint_to_char((unsigned char *)(hdr + 20), chans); if (snd_checked_write(fs, (unsigned char *)hdr, 28, newname) == MUS_ERROR) { free(buf1); CLEANUP(oldname, newname); return_mus_write_error(oldname, newname); } lseek(fd, loc, SEEK_SET); stat.last = 0; stat.step_index = 0; while (samps > 0) { int samps_read; ssize_t totalin; totalin = read(fd, buf, blksiz); if (totalin <= 0) break; for (i = 0, j = 0; i < totalin; i++) { /* samps_read will be twice totalin because these are 4-bit quantities */ buf1[j++] = oki_adpcm_decode((char)((buf[i] >> 4) & 0x0f), &stat); buf1[j++] = oki_adpcm_decode((char)(buf[i] & 0x0f), &stat); } samps_read = totalin * 2; if (be_snd_checked_write(fs, (unsigned char *)buf1, samps_read * 2, newname) == MUS_ERROR) { free(buf1); CLEANUP(oldname, newname); return_mus_write_error(oldname, newname); } samps -= samps_read; } free(buf1); CLEANUP(oldname, newname); return(MUS_NO_ERROR); } /* -------------------------------- 12 bit cases -------------------------------- */ static int read_12bit(const char *oldname, const char *newname, char *hdr) { int chans, i, j, fs = -1, fd = -1; unsigned char *buf = NULL; short *buf1; mus_long_t loc, samps; loc = mus_sound_data_location(oldname); chans = mus_sound_chans(oldname); samps = mus_sound_samples(oldname); mus_bint_to_char((unsigned char *)(hdr + 16), mus_sound_srate(oldname)); mus_bint_to_char((unsigned char *)(hdr + 20), chans); STARTUP(oldname, newname, ((int)(TRANS_BUF_SIZE * 1.5)), unsigned char); if (snd_checked_write(fs, (unsigned char *)hdr, 28, newname) == MUS_ERROR) { CLEANUP(oldname, newname); return_mus_write_error(oldname, newname); } lseek(fd, loc, SEEK_SET); buf1 = (short *)calloc(TRANS_BUF_SIZE, sizeof(short)); while (samps > 0) { ssize_t totalin; totalin = read(fd, buf, (int)(TRANS_BUF_SIZE * 1.5)); if (totalin <= 0) break; for (i = 0, j = 0; i < totalin; i += 3, j += 2) { buf1[j] = (signed short)((buf[i] << 8) + (buf[i + 1] & 0xf0)); buf1[j + 1] = (signed short)((buf[i + 2] << 8) + ((buf[i + 1] & 0xf) << 4)); } if (be_snd_checked_write(fs, (unsigned char *)buf1, j * 2, newname) == MUS_ERROR) { free(buf1); CLEANUP(oldname, newname); return_mus_write_error(oldname, newname); } samps -= j; } free(buf1); CLEANUP(oldname, newname); return(MUS_NO_ERROR); } #if G7XX /* -------------------------------- G721 and G723 from Sun -------------------------------- * code boiled down considerably here since I have no love of compression schemes. */ struct g72x_state {long yl; short yu; short dms; short dml; short ap; short a[2]; short b[6]; short pk[2]; short dq[6]; short sr[2]; char td;}; static int quan(short val) { #if 0 if (val >= 16384) return(15); if (val >= 8192) return(14); if (val >= 4096) return(13); if (val >= 2048) return(12); if (val >= 1024) return(11); if (val >= 512) return(10); if (val >= 256) return(9); if (val >= 128) return(8); if (val >= 64) return(7); if (val >= 32) return(6); if (val >= 16) return(5); if (val >= 8) return(4); if (val >= 4) return(3); if (val >= 2) return(2); if (val >= 1) return(1); return(0); #else if (val >= 256) { if (val >= 1024) { if (val >= 4096) { if (val >= 16384) return(15); if (val >= 8192) return(14); return(13); } if (val >= 2048) return(12); return(11); } if (val >= 512) return(10); return(9); } if (val >= 8) { if (val >= 64) { if (val >= 128) return(8); return(7); } if (val >= 32) return(6); if (val >= 16) return(5); return(4); } if (val >= 4) return(3); if (val >= 2) return(2); if (val >= 1) return(1); return(0); #endif } static int fmult(int an, int srn) { short anmag, anexp, anmant; short wanexp, wanmant; short retval; anmag = (an > 0) ? an : ((-an) & 0x1FFF); anexp = quan(anmag) - 6; anmant = (anmag == 0) ? 32 : (anexp >= 0) ? anmag >> anexp : anmag << -anexp; wanexp = anexp + ((srn >> 6) & 0xF) - 13; wanmant = (anmant * (srn & 077) + 0x30) >> 4; retval = (wanexp >= 0) ? ((wanmant << wanexp) & 0x7FFF) : (wanmant >> -wanexp); return(((an ^ srn) < 0) ? -retval : retval); } static void g72x_init_state(struct g72x_state *state_ptr) { int cnta; state_ptr->yl = 34816; state_ptr->yu = 544; state_ptr->dms = 0; state_ptr->dml = 0; state_ptr->ap = 0; for (cnta = 0; cnta < 2; cnta++) { state_ptr->a[cnta] = 0; state_ptr->pk[cnta] = 0; state_ptr->sr[cnta] = 32; } for (cnta = 0; cnta < 6; cnta++) { state_ptr->b[cnta] = 0; state_ptr->dq[cnta] = 32; } state_ptr->td = 0; } static int predictor_zero(struct g72x_state *state_ptr) { int i, sezi; sezi = fmult(state_ptr->b[0] >> 2, state_ptr->dq[0]); for (i = 1; i < 6; i++) sezi += fmult(state_ptr->b[i] >> 2, state_ptr->dq[i]); return(sezi); } static int predictor_pole(struct g72x_state *state_ptr) { return(fmult(state_ptr->a[1] >> 2, state_ptr->sr[1]) + fmult(state_ptr->a[0] >> 2, state_ptr->sr[0])); } static int step_size(struct g72x_state *state_ptr) { int y, dif, al; if (state_ptr->ap >= 256) return(state_ptr->yu); else { y = state_ptr->yl >> 6; dif = state_ptr->yu - y; al = state_ptr->ap >> 2; if (dif > 0) y += (dif * al) >> 6; else if (dif < 0) y += (dif * al + 0x3F) >> 6; return(y); } } static int reconstruct(int sign, int dqln, int y) { short dql, dex, dqt, dq; dql = dqln + (y >> 2); if (dql < 0) {return((sign) ? -0x8000 : 0);} else { dex = (dql >> 7) & 15; dqt = 128 + (dql & 127); dq = (dqt << 7) >> (14 - dex); return((sign) ? (dq - 0x8000) : dq); } } static void update(int code_size, int y, int wi, int fi, int dq, int sr, int dqsez, struct g72x_state *state_ptr) { int cnt; short mag, exp, a2p = 0, a1ul, pks1, fa1, ylint, thr2, dqthr, ylfrac, thr1, pk0; char tr; pk0 = (dqsez < 0) ? 1 : 0; mag = dq & 0x7FFF; ylint = state_ptr->yl >> 15; ylfrac = (state_ptr->yl >> 10) & 0x1F; thr1 = (32 + ylfrac) << ylint; thr2 = (ylint > 9) ? 31 << 10 : thr1; dqthr = (thr2 + (thr2 >> 1)) >> 1; if (state_ptr->td == 0) tr = 0; else if (mag <= dqthr) tr = 0; else tr = 1; state_ptr->yu = y + ((wi - y) >> 5); if (state_ptr->yu < 544) state_ptr->yu = 544; else if (state_ptr->yu > 5120) state_ptr->yu = 5120; state_ptr->yl += state_ptr->yu + ((-state_ptr->yl) >> 6); if (tr == 1) { int i; state_ptr->a[0] = 0; state_ptr->a[1] = 0; for (i = 0; i < 6; i++) state_ptr->b[i] = 0; } else { pks1 = pk0 ^ state_ptr->pk[0]; /* UPA2 */ a2p = state_ptr->a[1] - (state_ptr->a[1] >> 7); if (dqsez != 0) { fa1 = (pks1) ? state_ptr->a[0] : -state_ptr->a[0]; if (fa1 < -8191) a2p -= 0x100; else if (fa1 > 8191) a2p += 0xFF; else a2p += fa1 >> 5; if (pk0 ^ state_ptr->pk[1]) {if (a2p <= -12160) a2p = -12288; else {if (a2p >= 12416) a2p = 12288; else a2p -= 0x80;}} else {if (a2p <= -12416) a2p = -12288; else {if (a2p >= 12160) a2p = 12288; else a2p += 0x80;}} } state_ptr->a[1] = a2p; state_ptr->a[0] -= state_ptr->a[0] >> 8; if (dqsez != 0) {if (pks1 == 0) state_ptr->a[0] += 192; else state_ptr->a[0] -= 192;} a1ul = 15360 - a2p; if (state_ptr->a[0] < -a1ul) state_ptr->a[0] = -a1ul; else if (state_ptr->a[0] > a1ul) state_ptr->a[0] = a1ul; for (cnt = 0; cnt < 6; cnt++) { if (code_size == 5) state_ptr->b[cnt] -= state_ptr->b[cnt] >> 9; else state_ptr->b[cnt] -= state_ptr->b[cnt] >> 8; if (dq & 0x7FFF) { if ((dq ^ state_ptr->dq[cnt]) >= 0) state_ptr->b[cnt] += 128; else state_ptr->b[cnt] -= 128; } } } for (cnt = 5; cnt > 0; cnt--) state_ptr->dq[cnt] = state_ptr->dq[cnt-1]; if (mag == 0) { state_ptr->dq[0] = (dq >= 0) ? 0x20 : 0xFC20; } else { exp = quan(mag); state_ptr->dq[0] = (dq >= 0) ? (exp << 6) + ((mag << 6) >> exp) : (exp << 6) + ((mag << 6) >> exp) - 0x400; } state_ptr->sr[1] = state_ptr->sr[0]; if (sr == 0) { state_ptr->sr[0] = 0x20; } else if (sr > 0) { exp = quan(sr); state_ptr->sr[0] = (exp << 6) + ((sr << 6) >> exp); } else if (sr > -32768) { mag = -sr; exp = quan(mag); state_ptr->sr[0] = (exp << 6) + ((mag << 6) >> exp) - 0x400; } else state_ptr->sr[0] = 0xFC20; /* it's declared short?? */ state_ptr->pk[1] = state_ptr->pk[0]; state_ptr->pk[0] = pk0; if (tr == 1) state_ptr->td = 0; else if (a2p < -11776) state_ptr->td = 1; else state_ptr->td = 0; state_ptr->dms += (fi - state_ptr->dms) >> 5; state_ptr->dml += (((fi << 2) - state_ptr->dml) >> 7); if (tr == 1) state_ptr->ap = 256; else if (y < 1536) state_ptr->ap += (0x200 - state_ptr->ap) >> 4; else if (state_ptr->td == 1) state_ptr->ap += (0x200 - state_ptr->ap) >> 4; else if (abs((state_ptr->dms << 2) - state_ptr->dml) >= (state_ptr->dml >> 3)) state_ptr->ap += (0x200 - state_ptr->ap) >> 4; else state_ptr->ap += (-state_ptr->ap) >> 4; } static int g721_decoder(int i, struct g72x_state *state_ptr) { static short dqlntab[16] = {-2048, 4, 135, 213, 273, 323, 373, 425, 425, 373, 323, 273, 213, 135, 4, -2048}; static short witab[16] = {-12, 18, 41, 64, 112, 198, 355, 1122, 1122, 355, 198, 112, 64, 41, 18, -12}; static short fitab[16] = {0, 0, 0, 0x200, 0x200, 0x200, 0x600, 0xE00, 0xE00, 0x600, 0x200, 0x200, 0x200, 0, 0, 0}; short sezi, sei, sez, se, y, sr, dq, dqsez; i &= 0x0f; sezi = predictor_zero(state_ptr); sez = sezi >> 1; sei = sezi + predictor_pole(state_ptr); se = sei >> 1; y = step_size(state_ptr); dq = reconstruct(i & 0x08, dqlntab[i], y); sr = (dq < 0) ? (se - (dq & 0x3FFF)) : se + dq; dqsez = sr - se + sez; update(4, y, witab[i] << 5, fitab[i], dq, sr, dqsez, state_ptr); return(sr << 2); } static int g723_24_decoder(int i, struct g72x_state *state_ptr) { static short dqlntab[8] = {-2048, 135, 273, 373, 373, 273, 135, -2048}; static short witab[8] = {-128, 960, 4384, 18624, 18624, 4384, 960, -128}; static short fitab[8] = {0, 0x200, 0x400, 0xE00, 0xE00, 0x400, 0x200, 0}; short sezi, sei, sez, se, y, sr, dq, dqsez; i &= 0x07; sezi = predictor_zero(state_ptr); sez = sezi >> 1; sei = sezi + predictor_pole(state_ptr); se = sei >> 1; y = step_size(state_ptr); dq = reconstruct(i & 0x04, dqlntab[i], y); sr = (dq < 0) ? (se - (dq & 0x3FFF)) : (se + dq); dqsez = sr - se + sez; update(3, y, witab[i], fitab[i], dq, sr, dqsez, state_ptr); return(sr << 2); } static int g723_40_decoder(int i, struct g72x_state *state_ptr) { static short dqlntab[32] = {-2048, -66, 28, 104, 169, 224, 274, 318, 358, 395, 429, 459, 488, 514, 539, 566, 566, 539, 514, 488, 459, 429, 395, 358, 318, 274, 224, 169, 104, 28, -66, -2048}; static short witab[32] = {448, 448, 768, 1248, 1280, 1312, 1856, 3200, 4512, 5728, 7008, 8960, 11456, 14080, 16928, 22272, 22272, 16928, 14080, 11456, 8960, 7008, 5728, 4512, 3200, 1856, 1312, 1280, 1248, 768, 448, 448}; static short fitab[32] = {0, 0, 0, 0, 0, 0x200, 0x200, 0x200, 0x200, 0x200, 0x400, 0x600, 0x800, 0xA00, 0xC00, 0xC00, 0xC00, 0xC00, 0xA00, 0x800, 0x600, 0x400, 0x200, 0x200, 0x200, 0x200, 0x200, 0, 0, 0, 0, 0}; short sezi, sei, se, sez, y, sr, dq, dqsez; i &= 0x1f; sezi = predictor_zero(state_ptr); sez = sezi >> 1; sei = sezi + predictor_pole(state_ptr); se = sei >> 1; y = step_size(state_ptr); dq = reconstruct(i & 0x10, dqlntab[i], y); sr = (dq < 0) ? (se - (dq & 0x7FFF)) : (se + dq); dqsez = sr - se + sez; update(5, y, witab[i], fitab[i], dq, sr, dqsez, state_ptr); return(sr << 2); } static bool unpack_input(FILE *fin, unsigned char *code, int bits) { static unsigned int in_buffer = 0; static int in_bits = 0; unsigned char in_byte; if (in_bits < bits) { if (fread(&in_byte, sizeof(char), 1, fin) != 1) { *code = 0; return(false); } in_buffer |= (in_byte << in_bits); in_bits += 8; } *code = in_buffer & ((1 << bits) - 1); in_buffer >>= bits; in_bits -= bits; return(true); } static int read_g72x_adpcm(const char *oldname, const char *newname, char *hdr, int which_g) { int fs = -1, j, chans, srate, dec_bits = 0, err = MUS_NO_ERROR; FILE *fd; mus_long_t loc; unsigned char code; short *buf = NULL; size_t bytes; struct g72x_state state; g72x_init_state(&state); chans = mus_sound_chans(oldname); if (chans != 1) return(mus_error(MUS_UNSUPPORTED_SAMPLE_TYPE, "read_g72x_adpcm: can't translate G72x file %s: chans: %d\n", oldname, chans)); fs = CREAT(newname, 0666); if (fs == -1) return_mus_io_error("create", newname); loc = mus_sound_data_location(oldname); srate = mus_sound_srate(oldname); mus_bint_to_char((unsigned char *)(hdr + 16), srate); mus_bint_to_char((unsigned char *)(hdr + 20), chans); fd = FOPEN(oldname, "rb"); if (fd == NULL) { snd_close(fs, newname); return_mus_io_error("fopen", oldname); } if (snd_checked_write(fs, (unsigned char *)hdr, 28, newname) == MUS_ERROR) { snd_close(fs, newname); snd_fclose(fd, oldname); return_mus_write_error(oldname, newname); } buf = (short *)calloc(TRANS_BUF_SIZE, sizeof(short)); if (buf == NULL) { snd_close(fs, newname); snd_fclose(fd, oldname); return_mus_alloc_error(oldname, TRANS_BUF_SIZE, "buf"); } bytes = fread(buf, 1, loc, fd); if (bytes == 0) { snd_close(fs, newname); snd_fclose(fd, oldname); free(buf); return_mus_write_error(oldname, newname); } switch (which_g) { case 0: /* G721 */ dec_bits = 4; break; case 1: /* G723_24 */ dec_bits = 3; break; case 2: /* G723_40 */ dec_bits = 5; break; } j = 0; while (unpack_input(fd, &code, dec_bits)) { switch (which_g) { case 0: buf[j++] = g721_decoder(code, &state); break; case 1: buf[j++] = g723_24_decoder(code, &state); break; case 2: buf[j++] = g723_40_decoder(code, &state); break; } if (j >= TRANS_BUF_SIZE) { if (be_snd_checked_write(fs, (unsigned char *)buf, j * 2, newname) == MUS_ERROR) { snd_close(fs, newname); snd_fclose(fd, oldname); free(buf); return_mus_write_error(oldname, newname); } j = 0; } } if (j > 0) err = be_snd_checked_write(fs, (unsigned char *)buf, j * 2, newname); snd_close(fs, newname); snd_fclose(fd, oldname); free(buf); if (err == MUS_ERROR) return_mus_write_error(oldname, newname); return(MUS_NO_ERROR); } #endif /* -------------------------------- TRANSLATE -------------------------------- */ #define RIFF_Intel_ADPCM 0x11 #define RIFF_Oki_ADPCM 0x10 #define RIFF_MS_ADPCM 2 #define RIFF_IBM_ADPCM 0x103 #if G7XX #define RIFF_G723 0x14 #define RIFF_MS_G723 0x42 #define RIFF_Lucent_G723 0x59 #define RIFF_Vivo_G723 0x111 #define RIFF_G721 0x40 #define NeXT_G721 23 #define NeXT_G723 25 #define NeXT_G723_5 26 #endif static const char *any_samp_type_name(const char *name) { mus_sample_t samp_type; samp_type = mus_sound_sample_type(name); if (samp_type != MUS_UNKNOWN_SAMPLE) return(mus_sample_type_name(samp_type)); else return(mus_header_original_sample_type_name(mus_sound_original_sample_type(name), mus_sound_header_type(name))); } int snd_translate(const char *oldname, const char *newname, mus_header_t type) { /* read oldname, translate to newname as 16-bit linear NeXT file */ /* called from snd-file.c */ int err; char *hdr = NULL; err = MUS_CANT_TRANSLATE; hdr = (char *)calloc(TRANS_BUF_SIZE, sizeof(char)); /* set up default output header */ mus_bint_to_char((unsigned char *)hdr, 0x2e736e64); /* .snd */ mus_bint_to_char((unsigned char *)(hdr + 4), 28); /* data location */ mus_bint_to_char((unsigned char *)(hdr + 8), 0); /* bytes in data portion */ mus_bint_to_char((unsigned char *)(hdr + 12), 3); /* 16-bit linear */ mus_bint_to_char((unsigned char *)(hdr + 16), 22050); mus_bint_to_char((unsigned char *)(hdr + 20), 1); /* chans */ switch (type) { case MUS_MIDI_SAMPLE_DUMP: err = read_midi_sample_dump(oldname, newname, hdr); break; case MUS_IEEE: err = read_ieee_text(oldname, newname, hdr); break; case MUS_MUS10: err = read_mus10(oldname, newname, hdr); break; case MUS_HCOM: err = read_hcom(oldname, newname, hdr); break; case MUS_YAMAHA_TX16W: err = read_12bit(oldname, newname, hdr); break; #if G7XX case MUS_NVF: err = read_g72x_adpcm(oldname, newname, hdr, 0); break; #endif case MUS_RF64: case MUS_RIFF: switch (mus_sound_original_sample_type(oldname)) { case RIFF_MS_ADPCM: case RIFF_Intel_ADPCM: err = read_dvi_adpcm(oldname, newname, hdr, 0); break; case RIFF_IBM_ADPCM: err = read_ibm_adpcm(oldname, newname, hdr); break; case RIFF_Oki_ADPCM: err = read_oki_adpcm(oldname, newname, hdr); break; #if G7XX case RIFF_G721: err = read_g72x_adpcm(oldname, newname, hdr, 0); break; /* untested */ case RIFF_G723: case RIFF_MS_G723: case RIFF_Lucent_G723: case RIFF_Vivo_G723: /* untested */ if (mus_sound_bits_per_sample(oldname) == 3) err = read_g72x_adpcm(oldname, newname, hdr, 1); else if (mus_sound_bits_per_sample(oldname) == 5) err = read_g72x_adpcm(oldname, newname, hdr, 2); break; #endif } break; case MUS_NIST: if (mus_sound_original_sample_type(oldname) == MUS_NIST_SHORTPACK) err = read_nist_shortpack(oldname, newname, hdr); break; #if G7XX case MUS_NEXT: switch (mus_sound_original_sample_type(oldname)) { case NeXT_G721: err = read_g72x_adpcm(oldname, newname, hdr, 0); break; case NeXT_G723: err = read_g72x_adpcm(oldname, newname, hdr, 1); break; case NeXT_G723_5: err = read_g72x_adpcm(oldname, newname, hdr, 2); break; } break; #endif case MUS_AIFC: if (mus_sound_original_sample_type(oldname) == MUS_AIFF_IMA_ADPCM) err = read_dvi_adpcm(oldname, newname, hdr, 1); break; case MUS_OGG: case MUS_SPEEX: case MUS_FLAC: case MUS_MIDI: case MUS_MPEG: case MUS_TTA: case MUS_WAVPACK: default: if (snd_decode(type, oldname, newname) == 0) err = MUS_NO_ERROR; break; } free(hdr); if (err == MUS_CANT_TRANSLATE) return(mus_error(MUS_CANT_TRANSLATE, "can't translate %s\n (%s header: %s (0x%x) sample type)\n", oldname, mus_header_type_name(type), any_samp_type_name(oldname), mus_sound_original_sample_type(oldname))); return(err); } snd-16.1/glistener.c0000644000076400007640000023337712573274335012525 0ustar bilbil#include "glistener.h" /* supplied by caller: help finder, evaluator, symbol table lookup * see s7.html#glistener and glistener.h for examples and documentation. */ #define strcopy(Dest, Src, Len) memcpy((void *)(Dest), (void *)(Src), Len) struct glistener { GtkWidget *text, *scroller, *status; GtkTextBuffer *buffer; bool is_schemish; GtkTextTag *prompt_tag; char *prompt; int prompt_length; char **strings; int strings_size, strings_pos; bool first_time; char *status_message; GtkTextTag *flash_tag; int flashes; int flash_paren_pos; int flash_time; GtkTextTag *highlight_tag; int highlight_start, highlight_end; int insertion_position; GdkCursor *wait_cursor, *arrow_cursor; const char *(*helper)(glistener *g, const char *text); const char *(*checker)(glistener *g, const char *text); void (*evaluator)(glistener *g, const char *text); void (*completer)(glistener *g, bool (*symbol_func)(const char *symbol_name, void *data), void *data); void (*colorizer)(glistener *g, glistener_colorizer_t type, int start, int end); bool (*keyer)(glistener *g, GtkWidget *w, GdkEventKey *e); }; #if ((!GTK_CHECK_VERSION(3, 0, 0))) && (!defined(GDK_KEY_Return)) #define GDK_KEY_BackSpace GDK_BackSpace #define GDK_KEY_Down GDK_Down #define GDK_KEY_Left GDK_Left #define GDK_KEY_Return GDK_Return #define GDK_KEY_Right GDK_Right #define GDK_KEY_Tab GDK_Tab #define GDK_KEY_Up GDK_Up #define GDK_KEY_a GDK_a #define GDK_KEY_b GDK_b #define GDK_KEY_c GDK_c #define GDK_KEY_d GDK_d #define GDK_KEY_e GDK_e #define GDK_KEY_f GDK_f #define GDK_KEY_greater GDK_greater #define GDK_KEY_k GDK_k #define GDK_KEY_l GDK_l #define GDK_KEY_less GDK_less #define GDK_KEY_n GDK_n #define GDK_KEY_p GDK_p #define GDK_KEY_t GDK_t #define GDK_KEY_u GDK_u #define GDK_KEY_v GDK_v #define GDK_KEY_w GDK_w #define GDK_KEY_y GDK_y #endif #define EVENT_KEYVAL(Ev) (Ev)->keyval #if (GTK_CHECK_VERSION(3, 0, 0) && defined(__GNUC__) && (!(defined(__cplusplus)))) #define EVENT_STATE(Ev) ({ GdkModifierType Type; gdk_event_get_state((GdkEvent *)Ev, &Type); Type; }) #else #define EVENT_STATE(Ev) (Ev)->state #endif #define ControlMask GDK_CONTROL_MASK #define MetaMask GDK_MOD1_MASK /* these are the functions we get from the caller: * helper -- provide a brief string describing some entity (NULL = no help) * checker -- check for obvious mistakes in an expression * completer -- provide name completion (NULL = no completion) * evaluator -- evaluate an expression (a C string) and normally print the result in the glistener window */ static const char *default_helper(glistener *g, const char *text) { return(NULL); } void glistener_set_helper(glistener *g, const char *(*help)(glistener *g, const char *text)) { if (help) g->helper = help; else g->helper = default_helper; } static const char *default_checker(glistener *g, const char *text) { return(NULL); } void glistener_set_checker(glistener *g, const char *(*check)(glistener *g, const char *text)) { if (check) g->checker = check; else g->checker = default_checker; } static void default_evaluator(glistener *g, const char *text) { glistener_append_text(g, "\n?"); glistener_append_prompt(g); } void glistener_set_evaluator(glistener *g, void (*eval)(glistener *g, const char *text)) { if (eval) g->evaluator = eval; else g->evaluator = default_evaluator; } static void default_completer(glistener *g, bool (*symbol_func)(const char *symbol_name, void *data), void *data) { } void glistener_set_completer(glistener *g, void (*completer)(glistener *g, bool (*symbol_func)(const char *symbol_name, void *data), void *data)) { if (completer) g->completer = completer; else g->completer = default_completer; } static void default_colorizer(glistener *g, glistener_colorizer_t type, int start, int end) { } void glistener_set_colorizer(glistener *g, void (*colorizer)(glistener *g, glistener_colorizer_t type, int start, int end)) { if (colorizer) g->colorizer = colorizer; else g->colorizer = default_colorizer; } static bool default_keyer(glistener *g, GtkWidget *w, GdkEventKey *e) { return(false); } void glistener_set_keyer(glistener *g, bool (*key)(glistener *g, GtkWidget *w, GdkEventKey *e)) { if (key) g->keyer = key; else g->keyer = default_keyer; /* the keyer can itself block signal emission, so I think all bases are covered * false -> built-in actions * true -> skip built in * block/true -> block, then skip * the caller could simply add his signal to "key-press" in the widget, but then * has less fine-tuned control of the built-in handler. */ } void glistener_is_schemish(glistener *g, bool is_schemish) { g->is_schemish = is_schemish; } static PangoFontDescription *default_font = NULL; /* in case font is set before glistener is created -- this happens in Snd when the * initialization script sets the listener font. At that point in the startup process, * the listener window does not exist. Perhaps it would be safer to copy the value. */ void glistener_set_font(glistener *g, PangoFontDescription *font) { if ((!g) || (!(g->text))) { default_font = font; return; } else default_font = NULL; #if (!GTK_CHECK_VERSION(3, 0, 0)) gtk_widget_modify_font(GTK_WIDGET(g->text), font); #else #if (!GTK_CHECK_VERSION(3, 16, 0)) gtk_widget_override_font(GTK_WIDGET(g->text), font); #endif #endif } #if (!GTK_CHECK_VERSION(3, 0, 0)) static GdkColor *default_text_color = NULL; static GdkColor *default_background_color = NULL; void glistener_set_text_color(glistener *g, GdkColor *p) { if ((g) && (g->text)) { gtk_widget_modify_text(g->text, GTK_STATE_NORMAL, p); default_text_color = NULL; } else default_text_color = p; } void glistener_set_background_color(glistener *g, GdkColor *p) { if ((g) && (g->text)) { gtk_widget_modify_base(g->text, GTK_STATE_NORMAL, p); default_background_color = NULL; } else default_background_color = p; } #else static GdkRGBA *default_text_color = NULL; static GdkRGBA *default_background_color = NULL; void glistener_set_text_color(glistener *g, GdkRGBA *p) { if ((g) && (g->text)) { #if (!GTK_CHECK_VERSION(3, 16, 0)) gtk_widget_override_color(g->text, GTK_STATE_FLAG_NORMAL, p); #endif default_text_color = NULL; } else default_text_color = p; } void glistener_set_background_color(glistener *g, GdkRGBA *p) { if ((g) && (g->text)) { #if (!GTK_CHECK_VERSION(3, 16, 0)) gtk_widget_override_background_color(g->text, GTK_STATE_FLAG_NORMAL, p); #endif default_background_color = NULL; } else default_background_color = p; } #endif void glistener_post_status(glistener *g, const char *msg) { if (g->status) { gtk_statusbar_pop(GTK_STATUSBAR(g->status), 1); gtk_statusbar_push(GTK_STATUSBAR(g->status), 1, msg); } } void glistener_clear_status(glistener *g) { if (g->status) { #if (GTK_CHECK_VERSION(3, 0, 0)) gtk_statusbar_remove_all(GTK_STATUSBAR(g->status), 1); #else gtk_statusbar_pop(GTK_STATUSBAR(g->status), 1); #endif if (g->status_message) { free(g->status_message); g->status_message = NULL; } } } static void glistener_append_status(glistener *g, const char *msg) { if ((g->status) && (msg)) { int len; len = strlen(msg); if (g->status_message) { char *new_msg; len += (strlen(g->status_message) + 3); new_msg = (char *)calloc(len, sizeof(char)); snprintf(new_msg, len, "%s %s", msg, g->status_message); free(g->status_message); g->status_message = new_msg; } else { g->status_message = (char *)calloc(len + 1, sizeof(char)); strcopy(g->status_message, msg, len + 1); } gtk_statusbar_pop(GTK_STATUSBAR(g->status), 1); gtk_statusbar_push(GTK_STATUSBAR(g->status), 1, g->status_message); } } /* ---------------- cursor ---------------- */ void glistener_set_cursor_position(glistener *g, int position) { GtkTextIter pos; /* -1 -> goto to end */ if (position == -1) gtk_text_buffer_get_end_iter(g->buffer, &pos); else gtk_text_buffer_get_iter_at_offset(g->buffer, &pos, position); gtk_text_buffer_place_cursor(g->buffer, &pos); gtk_text_view_scroll_mark_onscreen(GTK_TEXT_VIEW(g->text), gtk_text_buffer_get_insert(g->buffer)); } int glistener_cursor_position(glistener *g) { GtkTextIter pos; gtk_text_buffer_get_iter_at_mark(g->buffer, &pos, gtk_text_buffer_get_insert(g->buffer)); return(gtk_text_iter_get_offset(&pos)); } static int glistener_cursor(glistener *g, GtkTextIter *cursor) { gtk_text_buffer_get_iter_at_mark(g->buffer, cursor, gtk_text_buffer_get_insert(g->buffer)); return(gtk_text_iter_get_offset(cursor)); } void glistener_set_cursor_shape(glistener *g, GdkCursor *cursor_shape) { gdk_window_set_cursor(gtk_text_view_get_window(GTK_TEXT_VIEW(g->text), GTK_TEXT_WINDOW_TEXT), cursor_shape); } /* ---------------- prompt ---------------- */ static void prompt_insert(glistener *g, GtkTextIter *pos, bool at_top) { if (at_top) { if (g->prompt_tag) gtk_text_buffer_insert_with_tags(g->buffer, pos, (char *)(g->prompt + 1), -1, g->prompt_tag, NULL); else gtk_text_buffer_insert(g->buffer, pos, (char *)(g->prompt + 1), -1); } else { if (g->prompt_tag) gtk_text_buffer_insert_with_tags(g->buffer, pos, g->prompt, -1, g->prompt_tag, NULL); else gtk_text_buffer_insert(g->buffer, pos, g->prompt, -1); /* scroll fully to prompt and left so the new prompt is in view */ gtk_text_view_scroll_mark_onscreen(GTK_TEXT_VIEW(g->text), gtk_text_buffer_get_insert(g->buffer)); gtk_adjustment_set_value(GTK_ADJUSTMENT(gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(g->scroller))), 0.0); } } static GtkTextTag *default_prompt_tag = NULL; void glistener_set_prompt_tag(glistener *g, GtkTextTag *m) { if (!g) default_prompt_tag = m; else { g->prompt_tag = m; default_prompt_tag = NULL; } /* should this redisplay all the prompts? */ } static char *default_prompt = NULL; void glistener_set_prompt(glistener *g, const char *str) { /* the internal version includes a preceding , and its length is in unicode terms * also, if we have prompts displayed in the listener, they need to change to match * the new one. * * glistener_set_prompt(g, "s7>") * * from Snd, to get a prompt of lambda: in Greek font: * (set! (listener-prompt) (string (integer->char #xce) (integer->char #xbb) #\:)) * (set! (listener-prompt) (byte-vector #xce #xbb (char->integer #\:))) * currently (see GDK_SUPER_MASK below), to type Greek characters, hold down the windoze-key */ char *old_prompt; int old_prompt_length; if (!str) return; if (!g) { default_prompt = (char *)str; return; } default_prompt = NULL; old_prompt = g->prompt; old_prompt_length = g->prompt_length; g->prompt = (char *)calloc(strlen(str) + 2, sizeof(char)); g->prompt[0] = '\n'; strcat(g->prompt, str); g->prompt_length = g_utf8_strlen(g->prompt, -1); if (!g->text) return; if (old_prompt) { /* nothing will work if the prompt is changed in midcareer unless we remake all the preceding prompts */ GtkTextIter scan, start, end; /* the first prompt does not have a so we handle it directly */ gtk_text_buffer_get_start_iter(g->buffer, &start); gtk_text_buffer_get_iter_at_offset(g->buffer, &end, old_prompt_length - 1); gtk_text_buffer_delete(g->buffer, &start, &end); prompt_insert(g, &start, true); gtk_text_buffer_get_start_iter(g->buffer, &scan); gtk_text_buffer_create_mark(g->buffer, "prompt_pos", &scan, false); /* false -> "right gravity" */ while (gtk_text_iter_forward_search(&scan, old_prompt, (GtkTextSearchFlags)0, &start, &end, NULL)) { gtk_text_buffer_move_mark_by_name(g->buffer, "prompt_pos", &end); gtk_text_buffer_delete(g->buffer, &start, &end); prompt_insert(g, &start, false); gtk_text_buffer_get_iter_at_mark(g->buffer, &scan, gtk_text_buffer_get_mark(g->buffer, "prompt_pos")); } gtk_text_buffer_delete_mark_by_name(g->buffer, "prompt_pos"); free(old_prompt); } } void glistener_append_prompt(glistener *g) { if (g->text) { GtkTextIter end; gtk_text_buffer_get_end_iter(g->buffer, &end); prompt_insert(g, &end, false); gtk_text_buffer_get_end_iter(g->buffer, &end); gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(g->text), &end, 0.0, false, 0.0, 1.0); } } #if (!GTK_CHECK_VERSION(3, 0, 0)) /* backward search is buggy in gtk 2.20 (it's ok in gtk3 I think), and we depend on it! * this code is ridiculous, but it's the least stupid thing I can find that seems to work. */ static gboolean prompt_backward_search(glistener *g, const GtkTextIter *iter, GtkTextIter *start, GtkTextIter *end) { int cur_pos; GtkTextIter scan1, scan2, s1, s2; bool found_it = false; cur_pos = gtk_text_iter_get_offset(iter); gtk_text_buffer_get_start_iter(g->buffer, &scan1); gtk_text_buffer_get_start_iter(g->buffer, &scan2); while (true) { if (!gtk_text_iter_forward_search(&scan1, g->prompt, (GtkTextSearchFlags)0, &s1, &s2, NULL)) return(found_it); if (gtk_text_iter_get_offset(&s2) > cur_pos) return(found_it); found_it = true; gtk_text_iter_forward_search(&scan2, g->prompt, (GtkTextSearchFlags)0, start, end, NULL); scan1 = s2; scan2 = s2; } return(false); } #else static gboolean prompt_backward_search(glistener *g, const GtkTextIter *iter, GtkTextIter *start, GtkTextIter *end) { return(gtk_text_iter_backward_search(iter, g->prompt, (GtkTextSearchFlags)0, start, end, NULL)); } #endif static int find_current_prompt(glistener *g) { GtkTextIter it, start, end; int pos; pos = glistener_cursor_position(g); if (pos < g->prompt_length - 1) return(g->prompt_length - 1); gtk_text_buffer_get_iter_at_offset(g->buffer, &it, pos + g->prompt_length - 1); if (!prompt_backward_search(g, &it, &start, &end)) return(g->prompt_length - 1); return(gtk_text_iter_get_offset(&start) + g->prompt_length); } int glistener_prompt_position(glistener *g) { return(find_current_prompt(g)); } static int find_previous_prompt(glistener *g, int pos) { GtkTextIter it, start, end; int new_pos; if (pos < g->prompt_length - 1) return(g->prompt_length - 1); gtk_text_buffer_get_iter_at_offset(g->buffer, &it, pos); if (!prompt_backward_search(g, &it, &start, &end)) return(g->prompt_length - 1); new_pos = gtk_text_iter_get_offset(&end); if (new_pos < pos) return(new_pos); it = start; gtk_text_iter_backward_char(&it); if (!prompt_backward_search(g, &it, &start, &end)) return(g->prompt_length - 1); return(gtk_text_iter_get_offset(&end)); } static int find_next_prompt(glistener *g) { GtkTextIter it, start, end; glistener_cursor(g, &it); if (!gtk_text_iter_forward_search(&it, g->prompt, (GtkTextSearchFlags)0, &start, &end, NULL)) gtk_text_buffer_get_end_iter(g->buffer, &end); return(gtk_text_iter_get_offset(&end) + 1); } static bool is_prompt_end(glistener *g, int end_pos) { /* the prompt includes the preceding */ GtkTextIter start, end; bool result = false; if (end_pos < g->prompt_length) return(true); gtk_text_buffer_get_iter_at_offset(g->buffer, &end, end_pos); start = end; if (gtk_text_iter_backward_chars(&start, g->prompt_length)) { char *txt; txt = gtk_text_iter_get_text(&start, &end); if (txt) { result = (strcmp(txt, g->prompt) == 0); g_free(txt); } } return(result); } /* ---------------- listener text ---------------- */ static void remember_listener_string(glistener *g, const char *str) { int i, top, len; if (!str) return; if (g->strings_size == 0) { g->strings_size = 8; g->strings = (char **)calloc(g->strings_size, sizeof(char *)); } g->strings_pos = 0; g->first_time = true; /* if str matches current history top entry, ignore it (as in tcsh) */ if ((g->strings[0]) && (strcmp(str, g->strings[0]) == 0)) return; top = g->strings_size - 1; if (g->strings[top]) free(g->strings[top]); for (i = top; i > 0; i--) g->strings[i] = g->strings[i - 1]; len = strlen(str) + 1; g->strings[0] = (char *)calloc(len, sizeof(char)); strcopy(g->strings[0], str, len); } static void restore_listener_string(glistener *g, bool back) { if (g->strings) { char *str; if (!(g->first_time)) { if (back) g->strings_pos++; else g->strings_pos--; } g->first_time = false; if (g->strings_pos < 0) g->strings_pos = 0; if (g->strings_pos > (g->strings_size - 1)) g->strings_pos = g->strings_size - 1; str = g->strings[g->strings_pos]; if (str) glistener_append_text(g, str); } } void glistener_clear(glistener *g) { if (g->text) { GtkTextIter start, end; gtk_text_buffer_get_iter_at_offset(g->buffer, &start, g->prompt_length - 1); gtk_text_buffer_get_end_iter(g->buffer, &end); gtk_text_buffer_delete(g->buffer, &start, &end); } } bool glistener_write(glistener *g, FILE *fp) { char *str = NULL; GtkTextIter start, end; gtk_text_buffer_get_start_iter(g->buffer, &start); gtk_text_buffer_get_end_iter(g->buffer, &end); str = gtk_text_buffer_get_text(g->buffer, &start, &end, true); if (str) { size_t bytes; bytes = strlen(str); if (bytes > 0) { if (fwrite((void *)str, sizeof(char), bytes, fp) != bytes) { g_free(str); return(false); } g_free(str); } } return(true); } void glistener_append_text(glistener *g, const char *msg) { if (g->text) { GtkTextIter end; gtk_text_buffer_get_end_iter(g->buffer, &end); gtk_text_buffer_insert(g->buffer, &end, (char *)msg, -1); gtk_text_view_scroll_mark_onscreen(GTK_TEXT_VIEW(g->text), gtk_text_buffer_get_insert(g->buffer)); } } void glistener_insert_text(glistener *g, const char *text) { if (g->text) { gtk_text_buffer_insert_at_cursor(g->buffer, text, -1); gtk_text_view_scroll_mark_onscreen(GTK_TEXT_VIEW(g->text), gtk_text_buffer_get_insert(g->buffer)); } } char *glistener_text(glistener *g, int start, int end) { GtkTextIter s, e; gtk_text_buffer_get_iter_at_offset(g->buffer, &s, start); gtk_text_buffer_get_iter_at_offset(g->buffer, &e, end); return(gtk_text_buffer_get_text(g->buffer, &s, &e, true)); } void glistener_scroll_to_end(glistener *g) { if (g->text) { GtkTextIter end; gtk_text_buffer_get_end_iter(g->buffer, &end); gtk_text_buffer_place_cursor(g->buffer, &end); gtk_text_view_scroll_mark_onscreen(GTK_TEXT_VIEW(g->text), gtk_text_buffer_get_insert(g->buffer)); gtk_adjustment_set_value(GTK_ADJUSTMENT(gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(g->scroller))), 0.0); } } /* there is apparently no way in gtk to make sure our prompt is still visible after * a paned widget holding this listener changes its layout! */ /* ---------------- paren matching ---------------- */ static gboolean is_gt(gunichar c, gpointer data) { return(c == '>'); } static gboolean is_not_whitespace(gunichar c, gpointer data) { return(!g_unichar_isspace(c)); } static bool find_not_whitespace(glistener *g, int pos, GtkTextIter *limit) { GtkTextIter scan; gtk_text_buffer_get_iter_at_offset(g->buffer, &scan, pos); return(gtk_text_iter_forward_find_char(&scan, is_not_whitespace, NULL, limit)); } static gboolean is_unslashed_double_quote(gunichar c, gpointer data) { int *slashes = (int *)data; if (c == '\\') (*slashes)++; else { if ((c == '\"') && (*slashes & 1) == 0) return(true); *slashes = 0; } return(false); } static bool find_enclosing_string(glistener *g, int pos, int *d1, int *d2, GtkTextIter *start, GtkTextIter *end) { GtkTextIter scan; int p1 = -1, p2 = -1, slashes = 0; gunichar c; bool found_left_quote = false; gtk_text_buffer_get_iter_at_offset(g->buffer, &scan, pos - 1); gtk_text_iter_backward_char(&scan); while (gtk_text_iter_compare(start, &scan) < 0) { c = gtk_text_iter_get_char(&scan); if (c == '\"') { found_left_quote = true; p1 = gtk_text_iter_get_offset(&scan); } else { if (c == '\\') { if (found_left_quote) slashes++; } else { if ((found_left_quote) && ((slashes & 1) == 0)) break; found_left_quote = false; p1 = -1; slashes = 0; } } gtk_text_iter_backward_char(&scan); } if (p1 != -1) gtk_text_buffer_get_iter_at_offset(g->buffer, &scan, p1); slashes = 0; if (gtk_text_iter_forward_find_char(&scan, is_unslashed_double_quote, &slashes, end)) { if (found_left_quote) p2 = gtk_text_iter_get_offset(&scan); else { p1 = gtk_text_iter_get_offset(&scan); if (gtk_text_iter_forward_find_char(&scan, is_unslashed_double_quote, &slashes, end)) p2 = gtk_text_iter_get_offset(&scan); } } if ((p1 == -1) || (p2 == -1)) return(false); *d1 = p1; *d2 = p2 + 1; return(true); } static int find_string_end(glistener *g, int pos, GtkTextIter *limit) { int d1, d2; GtkTextIter e; gtk_text_buffer_get_end_iter(g->buffer, &e); if (find_enclosing_string(g, pos, &d1, &d2, limit, &e)) return(d2 - 1); return(-1); } static gboolean is_block_comment(gunichar c, gpointer data) { int *last_c = (int *)data; if ((c == '#') && (*last_c == '|')) return(true); *last_c = c; return(false); } static int find_open_block_comment(glistener *g, int pos, GtkTextIter *limit) { GtkTextIter scan; int last_cs = 0; gtk_text_buffer_get_iter_at_offset(g->buffer, &scan, pos); gtk_text_iter_backward_find_char(&scan, is_block_comment, &last_cs, limit); return(gtk_text_iter_get_offset(&scan)); } static int find_close_block_comment(glistener *g, int pos, GtkTextIter *limit) { GtkTextIter scan; int last_cs = 0; gtk_text_buffer_get_iter_at_offset(g->buffer, &scan, pos); gtk_text_iter_forward_find_char(&scan, is_block_comment, &last_cs, limit); return(gtk_text_iter_get_offset(&scan)); } static gboolean is_delimiter(gunichar c, gpointer data) { return((g_unichar_isspace(c)) || (c == '(') || (c == ')') || (c == ';') || (c == '\"')); /* in s7, single-quote can appear in a name */ } static void find_surrounding_word(glistener *g, int pos, gboolean (*checker)(gunichar c, gpointer data), int *start_pos, int *end_pos, GtkTextIter *start_limit, GtkTextIter *end_limit) { GtkTextIter start, end; int bpos, epos; *start_pos = pos; bpos = gtk_text_iter_get_offset(start_limit); *end_pos = pos; epos = gtk_text_iter_get_offset(end_limit); gtk_text_buffer_get_iter_at_offset(g->buffer, &start, pos); /* gtk_text_buffer_get_iter_at_offset(g->buffer, &end, pos); */ end = start; if (gtk_text_iter_compare(start_limit, &start) < 0) { if (gtk_text_iter_backward_find_char(&start, checker, NULL, start_limit)) *start_pos = gtk_text_iter_get_offset(&start) + 1; else *start_pos = bpos; } if (gtk_text_iter_compare(&end, end_limit) < 0) { if (!is_delimiter(gtk_text_iter_get_char(&end), NULL)) { if (gtk_text_iter_forward_find_char(&end, checker, NULL, end_limit)) *end_pos = gtk_text_iter_get_offset(&end); else *end_pos = epos; } } } static char *get_preceding_text(glistener *g, int pos, bool *in_string) { GtkTextIter s1, e1, elimit; int start = 0, end = 0; gtk_text_buffer_get_iter_at_offset(g->buffer, &s1, find_current_prompt(g)); gtk_text_buffer_get_iter_at_offset(g->buffer, &e1, pos); gtk_text_buffer_get_end_iter(g->buffer, &elimit); *in_string = false; if (gtk_text_iter_equal(&s1, &elimit)) /* s1 can't be beyond elimit=end iter */ return(NULL); if ((gtk_text_iter_equal(&e1, &elimit)) || (g_unichar_isspace(gtk_text_iter_get_char(&e1)))) { find_surrounding_word(g, pos, is_delimiter, &start, &end, &s1, &e1); gtk_text_buffer_get_iter_at_offset(g->buffer, &elimit, start - 1); *in_string = (gtk_text_iter_get_char(&elimit) == '\"'); gtk_text_buffer_get_iter_at_offset(g->buffer, &s1, start); gtk_text_buffer_get_iter_at_offset(g->buffer, &e1, end); return(gtk_text_buffer_get_text(g->buffer, &s1, &e1, true)); } return(NULL); } static bool at_character_constant(glistener *g, int end_pos) { GtkTextIter start, end; gtk_text_buffer_get_iter_at_offset(g->buffer, &end, end_pos); start = end; if (gtk_text_iter_backward_chars(&start, 2)) { char *txt; bool result = false; txt = gtk_text_iter_get_text(&start, &end); if (txt) { result = (strcmp(txt, "#\\") == 0); g_free(txt); } return(result); } return(false); } static bool find_open_paren(glistener *g, int parens, int pos, int *highlight_pos, GtkTextIter *limit) { GtkTextIter scan; int parens_at_line_end, ppos; bool end_scan = false; gunichar c = 0, last_c; parens_at_line_end = parens; gtk_text_buffer_get_iter_at_offset(g->buffer, &scan, pos); while (gtk_text_iter_compare(limit, &scan) < 0) { last_c = c; c = gtk_text_iter_get_char(&scan); if (!at_character_constant(g, gtk_text_iter_get_offset(&scan))) { if (c == (gunichar)'\"') { int d1, d2, qpos; GtkTextIter e; qpos = gtk_text_iter_get_offset(&scan); gtk_text_buffer_get_end_iter(g->buffer, &e); if (find_enclosing_string(g, qpos, &d1, &d2, limit, &e)) { ppos = d1; } else { return(false); /* no matching double-quote so we're probably in a string */ } gtk_text_buffer_get_iter_at_offset(g->buffer, &scan, ppos); last_c = '\"'; } else { if (c == '\n') { if (end_scan) return(true); parens_at_line_end = parens; } else { if (c == (gunichar)';') { parens = parens_at_line_end; end_scan = false; } else { if ((c == (gunichar)'|') && (last_c == (gunichar)'#')) /* we're looking backwards here, so in the end marker |# we see the # first */ { ppos = find_open_block_comment(g, gtk_text_iter_get_offset(&scan), limit); gtk_text_buffer_get_iter_at_offset(g->buffer, &scan, ppos); last_c = '#'; } else { if (!end_scan) { if (c == ')') parens++; else { if (c == '(') { parens--; if (parens == 0) { (*highlight_pos) = gtk_text_iter_get_offset(&scan); end_scan = true; } } } } } } } } } gtk_text_iter_backward_char(&scan); } return(parens == 0); } static bool find_close_paren(glistener *g, int parens, int pos, int *highlight_pos, GtkTextIter *limit) { GtkTextIter scan; int ppos; gunichar c = 0, prev_c = 0; gtk_text_buffer_get_iter_at_offset(g->buffer, &scan, pos); while (gtk_text_iter_compare(&scan, limit) < 0) { prev_c = c; c = gtk_text_iter_get_char(&scan); if (!at_character_constant(g, gtk_text_iter_get_offset(&scan))) { if (c == (gunichar)'\"') { ppos = find_string_end(g, gtk_text_iter_get_offset(&scan), limit); if (ppos != -1) { gtk_text_buffer_get_iter_at_offset(g->buffer, &scan, ppos); } prev_c = '\"'; } else { if (c == (gunichar)';') gtk_text_iter_forward_to_line_end(&scan); else { if ((c == (gunichar)'|') && (prev_c == (gunichar)'#')) { ppos = find_close_block_comment(g, gtk_text_iter_get_offset(&scan), limit); gtk_text_buffer_get_iter_at_offset(g->buffer, &scan, ppos); } else { if (c == ')') { parens--; if (parens == 0) { (*highlight_pos) = gtk_text_iter_get_offset(&scan); return(true); } } else { if (c == '(') parens++; } } } } } gtk_text_iter_forward_char(&scan); } return(parens == 0); } static void add_inverse(glistener *g, int pos) { GtkTextIter start, end; if (g->flash_paren_pos == -1) g->flash_paren_pos = pos; gtk_text_buffer_get_iter_at_offset(g->buffer, &start, pos); gtk_text_buffer_get_iter_at_offset(g->buffer, &end, pos + 1); if (!g->flash_tag) g->flash_tag = gtk_text_buffer_create_tag(g->buffer, NULL, "background", "red", NULL); gtk_text_buffer_apply_tag(g->buffer, g->flash_tag, &start, &end); } static void remove_inverse(glistener *g, int pos) { GtkTextIter start, end; gtk_text_buffer_get_iter_at_offset(g->buffer, &start, pos); gtk_text_buffer_get_iter_at_offset(g->buffer, &end, pos + 1); if (!g->flash_tag) g->flash_tag = gtk_text_buffer_create_tag(g->buffer, NULL, "background", "red", NULL); gtk_text_buffer_remove_tag(g->buffer, g->flash_tag, &start, &end); } static gint flash_unbalanced_paren(gpointer data) { glistener *g = (glistener *)data; g->flashes--; if (g->flashes & 1) remove_inverse(g, g->flash_paren_pos); else add_inverse(g, g->flash_paren_pos); if (g->flashes > 0) g_timeout_add_full(0, (guint32)g->flash_time, flash_unbalanced_paren, data, NULL); else { remove_inverse(g, g->flash_paren_pos); g->flash_paren_pos = -1; } return(0); } static GtkTextTag *default_highlight_tag = NULL; void glistener_set_highlight_tag(glistener *g, GtkTextTag *m) { if (!g) default_highlight_tag = m; else { g->highlight_tag = m; default_highlight_tag = NULL; } } static void add_highlight(glistener *g, int bpos, int epos) { GtkTextIter start, end; gtk_text_buffer_get_iter_at_offset(g->buffer, &start, bpos); gtk_text_buffer_get_iter_at_offset(g->buffer, &end, epos); if (!g->highlight_tag) g->highlight_tag = gtk_text_buffer_create_tag(g->buffer, NULL, "weight", PANGO_WEIGHT_BOLD, "foreground", "red", NULL); gtk_text_buffer_apply_tag(g->buffer, g->highlight_tag, &start, &end); g->highlight_start = bpos; g->highlight_end = epos; } static void remove_highlight(glistener *g) { if ((g->highlight_tag) && (g->highlight_start != -1)) { GtkTextIter start, end; gtk_text_buffer_get_iter_at_offset(g->buffer, &start, g->highlight_start); gtk_text_buffer_get_iter_at_offset(g->buffer, &end, g->highlight_end); gtk_text_buffer_remove_tag(g->buffer, g->highlight_tag, &start, &end); g->highlight_start = -1; g->highlight_end = -1; } } static void check_for_offscreen_matching_paren(glistener *g, int pos) { GtkTextIter p; GdkRectangle r; /* actually cairo_rectangle_int_t */ int y, height; gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(g->text), &r); gtk_text_buffer_get_iter_at_offset(g->buffer, &p, pos); gtk_text_view_get_line_yrange(GTK_TEXT_VIEW(g->text), (const GtkTextIter *)(&p), &y, &height); if (y < r.y) { GtkTextIter e1; char *text; /* p already points to (, so no need to mess with it */ gtk_text_buffer_get_iter_at_offset(g->buffer, &e1, pos); if (!gtk_text_iter_ends_line(&e1)) gtk_text_iter_forward_to_line_end(&e1); text = gtk_text_buffer_get_text(g->buffer, &p, &e1, false); if (text) { glistener_post_status(g, text); g_free(text); } } } static void check_parens(glistener *g) { int pos; GtkTextIter scan, limit; gunichar c; remove_highlight(g); pos = glistener_cursor_position(g); gtk_text_buffer_get_iter_at_offset(g->buffer, &scan, pos - 1); c = gtk_text_iter_get_char(&scan); if ((c == ')') && (!at_character_constant(g, pos - 1))) { int opos = 0; gtk_text_buffer_get_iter_at_offset(g->buffer, &limit, find_current_prompt(g) - 1); if (find_open_paren(g, 1, pos - 2, &opos, &limit)) { add_highlight(g, opos, opos + 1); check_for_offscreen_matching_paren(g, opos); if (g->checker != default_checker) { char *text; text = glistener_text(g, pos, opos); if (text) { const char *help; help = g->checker(g, (const char *)text); if (help) glistener_post_status(g, help); g_free(text); } } } } else { gtk_text_iter_forward_char(&scan); c = gtk_text_iter_get_char(&scan); if ((c == '(') && (!at_character_constant(g, pos))) { gtk_text_buffer_get_iter_at_offset(g->buffer, &limit, find_next_prompt(g)); if (find_close_paren(g, 1, pos + 1, &pos, &limit)) add_highlight(g, pos, pos + 1); } } } /* ---------------- text editing ---------------- */ static void word_upper(glistener *g, bool capitalize, bool upcase) { int pos; GtkTextIter start, end; char *text = NULL, *up_text = NULL, *down_text = NULL; pos = glistener_cursor_position(g); gtk_text_buffer_get_iter_at_offset(g->buffer, &start, pos); end = start; gtk_text_iter_forward_word_end(&end); if (upcase) { text = gtk_text_buffer_get_text(g->buffer, &start, &end, true); up_text = g_utf8_strup(text, -1); } else { if (!capitalize) { text = gtk_text_buffer_get_text(g->buffer, &start, &end, true); down_text = g_utf8_strdown(text, -1); } else { GtkTextIter pstart; char *text0; gtk_text_buffer_get_iter_at_offset(g->buffer, &pstart, pos); if (g_unichar_isspace(gtk_text_iter_get_char(&pstart))) gtk_text_iter_forward_find_char(&pstart, is_not_whitespace, NULL, &end); gtk_text_iter_forward_char(&pstart); text0 = gtk_text_buffer_get_text(g->buffer, &start, &pstart, true); text = gtk_text_buffer_get_text(g->buffer, &pstart, &end, true); up_text = g_utf8_strup(text0, -1); down_text = g_utf8_strdown(text, -1); g_free(text0); } } gtk_text_buffer_delete(g->buffer, &start, &end); if (up_text) gtk_text_buffer_insert(g->buffer, &start, up_text, -1); if (down_text) gtk_text_buffer_insert(g->buffer, &start, down_text, -1); if (text) g_free(text); if (up_text) g_free(up_text); if (down_text) g_free(down_text); } static void text_transpose(glistener *g) { int curpos; GtkTextIter start, end; curpos = glistener_cursor(g, &end); if (!is_prompt_end(g, curpos)) { char *text, *new_text; start = end; gtk_text_iter_backward_char(&start); gtk_text_iter_forward_char(&end); text = gtk_text_buffer_get_text(g->buffer, &start, &end, false); new_text = g_utf8_strreverse(text, -1); gtk_text_buffer_delete(g->buffer, &start, &end); gtk_text_buffer_insert(g->buffer, &start, new_text, -1); g_free(text); g_free(new_text); } } static void clear_back_to_prompt(glistener *g) { int beg, end; GtkTextIter start, last; end = glistener_cursor_position(g); beg = find_current_prompt(g); if (end <= beg) return; gtk_text_buffer_get_iter_at_offset(g->buffer, &start, beg); gtk_text_buffer_get_iter_at_offset(g->buffer, &last, end); gtk_text_buffer_delete(g->buffer, &start, &last); } /* ---------------- key bindings ---------------- */ void glistener_key_bindings(glistener *g, gpointer cls) { /* emacs key bindings for the most part */ GtkBindingSet *set; set = gtk_binding_set_by_class(cls); /* C-a start of line */ gtk_binding_entry_remove(set, GDK_KEY_a, GDK_CONTROL_MASK); gtk_binding_entry_add_signal(set, GDK_KEY_a, GDK_CONTROL_MASK, "move_cursor", 3, G_TYPE_ENUM, GTK_MOVEMENT_DISPLAY_LINE_ENDS, G_TYPE_INT, -1, G_TYPE_BOOLEAN, false); /* C-b back char */ gtk_binding_entry_remove(set, GDK_KEY_b, GDK_CONTROL_MASK); gtk_binding_entry_add_signal(set, GDK_KEY_b, GDK_CONTROL_MASK, "move_cursor", 3, G_TYPE_ENUM, GTK_MOVEMENT_VISUAL_POSITIONS, G_TYPE_INT, -1, G_TYPE_BOOLEAN, false); /* M-b back word */ gtk_binding_entry_remove(set, GDK_KEY_b, GDK_MOD1_MASK); gtk_binding_entry_add_signal(set, GDK_KEY_b, GDK_MOD1_MASK, "move_cursor", 3, G_TYPE_ENUM, GTK_MOVEMENT_WORDS, G_TYPE_INT, -1, G_TYPE_BOOLEAN, false); /* C-d delete at cursor */ gtk_binding_entry_remove(set, GDK_KEY_d, GDK_CONTROL_MASK); gtk_binding_entry_add_signal(set, GDK_KEY_d, GDK_CONTROL_MASK, "delete_from_cursor", 2, G_TYPE_ENUM, GTK_DELETE_CHARS, G_TYPE_INT, 1); /* -1 = delete to left of cursor */ /* C-e end of line */ gtk_binding_entry_remove(set, GDK_KEY_e, GDK_CONTROL_MASK); gtk_binding_entry_add_signal(set, GDK_KEY_e, GDK_CONTROL_MASK, "move_cursor", 3, /* 3 = n_args */ G_TYPE_ENUM, GTK_MOVEMENT_DISPLAY_LINE_ENDS, G_TYPE_INT, 1, G_TYPE_BOOLEAN, false); /* C-f forward char */ gtk_binding_entry_remove(set, GDK_KEY_f, GDK_CONTROL_MASK); gtk_binding_entry_add_signal(set, GDK_KEY_f, GDK_CONTROL_MASK, "move_cursor", 3, G_TYPE_ENUM, GTK_MOVEMENT_VISUAL_POSITIONS, G_TYPE_INT, 1, G_TYPE_BOOLEAN, false); /* M-f forward word */ gtk_binding_entry_remove(set, GDK_KEY_f, GDK_MOD1_MASK); gtk_binding_entry_add_signal(set, GDK_KEY_f, GDK_MOD1_MASK, "move_cursor", 3, G_TYPE_ENUM, GTK_MOVEMENT_WORDS, G_TYPE_INT, 1, G_TYPE_BOOLEAN, false); /* C-n down line */ gtk_binding_entry_remove(set, GDK_KEY_n, GDK_CONTROL_MASK); gtk_binding_entry_add_signal(set, GDK_KEY_n, GDK_CONTROL_MASK, "move_cursor", 3, G_TYPE_ENUM, GTK_MOVEMENT_DISPLAY_LINES, G_TYPE_INT, 1, G_TYPE_BOOLEAN, false); /* C-p up line */ gtk_binding_entry_remove(set, GDK_KEY_p, GDK_CONTROL_MASK); gtk_binding_entry_add_signal(set, GDK_KEY_p, GDK_CONTROL_MASK, "move_cursor", 3, G_TYPE_ENUM, GTK_MOVEMENT_DISPLAY_LINES, G_TYPE_INT, -1, G_TYPE_BOOLEAN, false); /* C-y yank <- clipboard */ gtk_binding_entry_remove(set, GDK_KEY_y, GDK_CONTROL_MASK); gtk_binding_entry_add_signal(set, GDK_KEY_y, GDK_CONTROL_MASK, "paste_clipboard", 0); /* C-w delete region -> clipboard -- it's possible to clobber a prompt here */ gtk_binding_entry_remove(set, GDK_KEY_w, GDK_CONTROL_MASK); gtk_binding_entry_add_signal(set, GDK_KEY_w, GDK_CONTROL_MASK, "cut_clipboard", 0); /* M-< start of file */ gtk_binding_entry_remove(set, GDK_KEY_less, GDK_MOD1_MASK); gtk_binding_entry_add_signal(set, GDK_KEY_less, GDK_MOD1_MASK, "move_cursor", 3, G_TYPE_ENUM, GTK_MOVEMENT_BUFFER_ENDS, G_TYPE_INT, -1, G_TYPE_BOOLEAN, false); /* M-> end of file */ gtk_binding_entry_remove(set, GDK_KEY_greater, GDK_MOD1_MASK); gtk_binding_entry_add_signal(set, GDK_KEY_greater, GDK_MOD1_MASK, "move_cursor", 3, G_TYPE_ENUM, GTK_MOVEMENT_BUFFER_ENDS, G_TYPE_INT, 1, G_TYPE_BOOLEAN, false); /* down-arrow end of file */ gtk_binding_entry_remove(set, GDK_KEY_Down, (GdkModifierType)0); gtk_binding_entry_add_signal(set, GDK_KEY_Down, (GdkModifierType)0, "move_cursor", 3, G_TYPE_ENUM, GTK_MOVEMENT_BUFFER_ENDS, G_TYPE_INT, 1, G_TYPE_BOOLEAN, false); /* up-arrow start of file */ gtk_binding_entry_remove(set, GDK_KEY_Up, (GdkModifierType)0); gtk_binding_entry_add_signal(set, GDK_KEY_Up, (GdkModifierType)0, "move_cursor", 3, G_TYPE_ENUM, GTK_MOVEMENT_BUFFER_ENDS, G_TYPE_INT, -1, G_TYPE_BOOLEAN, false); /* right-arrow end of line */ gtk_binding_entry_remove(set, GDK_KEY_Right, (GdkModifierType)0); gtk_binding_entry_add_signal(set, GDK_KEY_Right, (GdkModifierType)0, "move_cursor", 3, G_TYPE_ENUM, GTK_MOVEMENT_DISPLAY_LINE_ENDS, G_TYPE_INT, 1, G_TYPE_BOOLEAN, false); /* left-arrow start of line */ gtk_binding_entry_remove(set, GDK_KEY_Left, (GdkModifierType)0); gtk_binding_entry_add_signal(set, GDK_KEY_Left, (GdkModifierType)0, "move_cursor", 3, G_TYPE_ENUM, GTK_MOVEMENT_DISPLAY_LINE_ENDS, G_TYPE_INT, -1, G_TYPE_BOOLEAN, false); /* C-v move down a window */ gtk_binding_entry_remove(set, GDK_KEY_v, GDK_CONTROL_MASK); gtk_binding_entry_add_signal(set, GDK_KEY_v, GDK_CONTROL_MASK, "move_cursor", 3, G_TYPE_ENUM, GTK_MOVEMENT_PAGES, G_TYPE_INT, 1, G_TYPE_BOOLEAN, false); /* M-v for up window */ gtk_binding_entry_remove(set, GDK_KEY_v, GDK_MOD1_MASK); gtk_binding_entry_add_signal(set, GDK_KEY_v, GDK_MOD1_MASK, "move_cursor", 3, G_TYPE_ENUM, GTK_MOVEMENT_PAGES, G_TYPE_INT, -1, G_TYPE_BOOLEAN, false); /* M-d delete word at cursor */ gtk_binding_entry_remove(set, GDK_KEY_d, GDK_MOD1_MASK); gtk_binding_entry_add_signal(set, GDK_KEY_d, GDK_MOD1_MASK, "delete_from_cursor", 2, G_TYPE_ENUM, GTK_DELETE_WORD_ENDS, G_TYPE_INT, 1); } static void glistener_return_callback(glistener *g); static void glistener_completion(glistener *g, int end); static gboolean glistener_key_press(GtkWidget *w, GdkEventKey *event, gpointer data) { glistener *g = (glistener *)data; if ((g->keyer == default_keyer) || (!(g->keyer(g, w, event)))) { guint key; GdkModifierType state; key = EVENT_KEYVAL(event); state = (GdkModifierType)EVENT_STATE(event); /* fprintf(stderr, "key: %d, state: %x\n", key, state); */ #if 1 /* just a fun hack -- need to make a map to do this right * could be 1..3 bytes long * perhaps C->c4, M->c5, []->3, CM->c8? */ if (state & GDK_SUPER_MASK) { char p[3]; p[0] = 0xce; p[1] = key + (0xbb - GDK_KEY_l); /* works for lambda */ p[2] = 0; glistener_insert_text(g, p); g_signal_stop_emission((gpointer)w, g_signal_lookup("key_press_event", G_OBJECT_TYPE((gpointer)w)), 0); return(false); } #endif switch (key) { /* further processing (by gtk) of the keystroke is blocked if we fall through */ case GDK_KEY_a: if (state & MetaMask) glistener_set_cursor_position(g, find_previous_prompt(g, glistener_cursor_position(g))); else return(false); break; case GDK_KEY_c: if (state & MetaMask) word_upper(g, true, false); else return(false); break; case GDK_KEY_d: if (state & ControlMask) { /* need to check for prompt just ahead */ if (!is_prompt_end(g, glistener_cursor_position(g) + g->prompt_length)) return(false); /* else we're sitting at (just in front of) the prompt so drop through and block the signal */ } else { if (state & MetaMask) { GtkTextIter p; int i, pos, new_pos, cur; bool hits_prompt = false; pos = glistener_cursor(g, &p); gtk_text_iter_forward_word_end(&p); new_pos = gtk_text_iter_get_offset(&p); cur = pos + g->prompt_length; /* if there's a prompt somewhere between pos and new_pos, block this deletion */ for (i = 0; i < (new_pos - pos); i++) { hits_prompt = is_prompt_end(g, cur + i); if (hits_prompt) break; } if (!hits_prompt) return(false); } else return(false); } break; case GDK_KEY_e: if (state & MetaMask) glistener_set_cursor_position(g, find_next_prompt(g) - 1); else return(false); break; case GDK_KEY_BackSpace: /* need to check for prompt at cursor */ if (!is_prompt_end(g, glistener_cursor_position(g))) return(false); break; case GDK_KEY_k: if (state & ControlMask) { /* select to line end, copy to clipboard, delete */ GtkTextIter beg, end; gtk_text_buffer_get_iter_at_mark(g->buffer, &beg, gtk_text_buffer_get_mark(g->buffer, "insert")); end = beg; gtk_text_iter_forward_to_line_end(&end); /* was forward_to_end! */ if (!gtk_text_iter_equal(&beg, &end)) { gtk_text_buffer_select_range(g->buffer, &beg, &end); gtk_text_buffer_cut_clipboard(g->buffer, gtk_widget_get_clipboard(w, GDK_SELECTION_CLIPBOARD), true); } } else return(false); break; case GDK_KEY_l: if (state & MetaMask) word_upper(g, false, false); else return(false); break; case GDK_KEY_n: if (state & MetaMask) { clear_back_to_prompt(g); restore_listener_string(g, false); } else return(false); break; case GDK_KEY_p: if (state & MetaMask) { clear_back_to_prompt(g); restore_listener_string(g, true); } else return(false); break; case GDK_KEY_t: if (state & ControlMask) { int pos; pos = glistener_cursor_position(g); if ((!is_prompt_end(g, pos)) && (!is_prompt_end(g, pos + g->prompt_length))) text_transpose(g); else return(false); } else return(false); break; case GDK_KEY_u: if (state & MetaMask) word_upper(g, false, true); else return(false); break; case GDK_KEY_w: if (state & ControlMask) { GtkTextIter start, end; bool has_selection; has_selection = gtk_text_buffer_get_selection_bounds(g->buffer, &start, &end); if (!has_selection) return(false); if (gtk_text_iter_get_offset(&start) >= g->prompt_length) return(false); } else return(false); break; case GDK_KEY_Tab: glistener_completion(g, glistener_cursor_position(g)); return(true); case GDK_KEY_Return: if (state & ControlMask) /* C-return -> insert return no matter what */ glistener_insert_text(g, "\n"); else glistener_return_callback(g); break; default: return(false); } } g_signal_stop_emission((gpointer)w, g_signal_lookup("key_press_event", G_OBJECT_TYPE((gpointer)w)), 0); return(false); } static void post_help(glistener *g, int pos) { GtkTextIter s1, e1; int start = 0, end = 0; char *text; if (g->helper == default_helper) return; gtk_text_buffer_get_iter_at_offset(g->buffer, &s1, find_current_prompt(g)); gtk_text_buffer_get_iter_at_offset(g->buffer, &e1, find_next_prompt(g)); find_surrounding_word(g, pos, is_delimiter, &start, &end, &s1, &e1); gtk_text_buffer_get_iter_at_offset(g->buffer, &s1, start); gtk_text_buffer_get_iter_at_offset(g->buffer, &e1, end); text = gtk_text_buffer_get_text(g->buffer, &s1, &e1, true); if (text) { const char *help; help = g->helper(g, text); if (help) glistener_post_status(g, help); g_free(text); } } static void check_for_open_paren_help(glistener *g) { int pos; GtkTextIter limit; pos = glistener_cursor_position(g); gtk_text_buffer_get_iter_at_offset(g->buffer, &limit, find_current_prompt(g) - 1); if (find_open_paren(g, 1, pos - 2, &pos, &limit)) post_help(g, pos + 1); } static gboolean glistener_key_release(GtkWidget *w, GdkEventKey *event, gpointer data) { glistener *g = (glistener *)data; int cpos; GtkTextIter c; /* before doing anything, make sure we're not in the prompt! */ cpos = glistener_cursor_position(g); if (cpos < g->prompt_length) glistener_set_cursor_position(g, g->prompt_length - 1); else { int bpos; bpos = find_current_prompt(g); if (cpos < bpos) glistener_set_cursor_position(g, bpos); } /* and mark matching paren, if any */ gtk_text_buffer_get_iter_at_offset(g->buffer, &c, glistener_cursor_position(g) - 1); if (gtk_text_iter_get_char(&c) != ')') check_for_open_paren_help(g); else glistener_clear_status(g); check_parens(g); return(false); } static void text_insert(GtkTextBuffer *textbuffer, GtkTextIter *location, gchar *text, gint len, gpointer data) { /* insert-text signal */ glistener *g = (glistener *)data; g->insertion_position = gtk_text_iter_get_offset(location); } static void check_for_empty_listener(GtkTextView *w, gpointer data) { /* cut-clipboard signal */ glistener *g = (glistener *)data; if (gtk_text_buffer_get_char_count(g->buffer) == 0) { /* put a prompt back in! */ GtkTextIter start; gtk_text_buffer_get_start_iter(g->buffer, &start); prompt_insert(g, &start, true); } } static gboolean glistener_button_release(GtkWidget *w, GdkEventButton *ev, gpointer data) { glistener *g = (glistener *)data; if (EVENT_STATE(ev) & GDK_BUTTON2_MASK) glistener_set_cursor_position(g, g->insertion_position); else { int cpos; /* before doing anything, make sure we're not in the prompt! */ cpos = glistener_cursor_position(g); if (cpos < g->prompt_length) glistener_set_cursor_position(g, g->prompt_length - 1); else { int bpos; bpos = find_current_prompt(g); if (cpos < bpos) glistener_set_cursor_position(g, bpos); } } check_parens(g); post_help(g, glistener_cursor_position(g)); return(false); } /* ---------------- evaluation ---------------- */ static void eval_text(glistener *g, GtkTextIter *start, GtkTextIter *end) { char *text; text = gtk_text_buffer_get_text(g->buffer, start, end, false); if (text) { GtkTextIter s, e, cursor_iter; gtk_text_buffer_get_iter_at_mark(g->buffer, &cursor_iter, gtk_text_buffer_get_insert(g->buffer)); if (gtk_text_iter_forward_search(&cursor_iter, g->prompt, (GtkTextSearchFlags)0, &s, &e, NULL)) glistener_append_text(g, text); glistener_set_cursor_shape(g, g->wait_cursor); remember_listener_string(g, text); g->evaluator(g, text); glistener_set_cursor_shape(g, g->arrow_cursor); glistener_set_cursor_position(g, gtk_text_buffer_get_char_count(g->buffer)); g_free(text); } } static int find_expression_limits(glistener *g, int *bpos, int *epos) { GtkTextIter cursor, start, end; int pos; pos = glistener_cursor_position(g); if (pos < g->prompt_length - 1) *bpos = g->prompt_length - 1; else { gtk_text_buffer_get_iter_at_offset(g->buffer, &cursor, pos + g->prompt_length - 1); if (!prompt_backward_search(g, &cursor, &start, &end)) *bpos = g->prompt_length - 1; else *bpos = gtk_text_iter_get_offset(&start) + g->prompt_length; } pos = glistener_cursor(g, &cursor); if (!gtk_text_iter_forward_search(&cursor, g->prompt, (GtkTextSearchFlags)0, &start, &end, NULL)) { gtk_text_buffer_get_end_iter(g->buffer, &end); *epos = gtk_text_iter_get_offset(&end); } else *epos = gtk_text_iter_get_offset(&start); /* now the expression is between bpos and epos */ gtk_text_buffer_get_iter_at_offset(g->buffer, &start, *bpos); gtk_text_buffer_get_iter_at_offset(g->buffer, &end, *epos); if (g_unichar_isspace(gtk_text_iter_get_char(&start))) gtk_text_iter_forward_find_char(&start, is_not_whitespace, NULL, &end); if (gtk_text_iter_compare(&start, &end) >= 0) *bpos = *epos; else { GtkTextIter e1; e1 = end; gtk_text_iter_backward_char(&e1); if (g_unichar_isspace(gtk_text_iter_get_char(&e1))) gtk_text_iter_backward_find_char(&end, is_not_whitespace, NULL, &start); *bpos = gtk_text_iter_get_offset(&start); *epos = gtk_text_iter_get_offset(&end) + 1; } if (gtk_text_iter_compare(&start, &cursor) > 0) { GtkTextIter e1; e1 = cursor; gtk_text_iter_backward_char(&e1); if (g_unichar_isspace(gtk_text_iter_get_char(&e1))) gtk_text_iter_backward_find_char(&cursor, is_not_whitespace, NULL, &start); pos = gtk_text_iter_get_offset(&cursor); } return(pos); } static void glistener_return_callback(glistener *g) { GtkTextIter scan_iter, end_iter, cursor_iter; int cursor_pos, start_pos, end_pos, expr_start = -1, any_start = -1, open_parens = 0, prev_start = -1; glistener_clear_status(g); if (!g->is_schemish) { GtkTextIter a, b; gtk_text_buffer_get_iter_at_offset(g->buffer, &a, find_current_prompt(g)); /* or perhaps line start if not on the prompt line? */ gtk_text_buffer_get_iter_at_offset(g->buffer, &b, glistener_cursor_position(g)); if (!gtk_text_iter_ends_line(&b)) gtk_text_iter_forward_to_line_end(&b); eval_text(g, &a, &b); return; } remove_highlight(g); cursor_pos = find_expression_limits(g, &start_pos, &end_pos); if (start_pos >= end_pos) /* at end? */ { glistener_append_text(g, "\n"); return; } gtk_text_buffer_get_iter_at_offset(g->buffer, &scan_iter, start_pos); gtk_text_buffer_get_iter_at_offset(g->buffer, &end_iter, end_pos); gtk_text_buffer_get_iter_at_offset(g->buffer, &cursor_iter, cursor_pos); while (gtk_text_iter_compare(&scan_iter, &end_iter) < 0) { gunichar c; c = gtk_text_iter_get_char(&scan_iter); /* fprintf(stderr, "%c ", c); */ if (!g_unichar_isspace(c)) { if (any_start == -1) any_start = gtk_text_iter_get_offset(&scan_iter); switch (c) { case '"': { int slashes = 0; GtkTextIter str_iter; str_iter = scan_iter; if (!gtk_text_iter_forward_find_char(&scan_iter, is_unslashed_double_quote, &slashes, &end_iter)) { /* we're in an unclosed string constant */ glistener_insert_text(g, "\n"); return; } gtk_text_iter_forward_char(&scan_iter); /* step over the close double-quote */ if (expr_start == -1) { if (gtk_text_iter_compare(&cursor_iter, &scan_iter) <= 0) { /* we're in a string with no surrounding context */ eval_text(g, &str_iter, &scan_iter); return; } prev_start = gtk_text_iter_get_offset(&str_iter); } } continue; break; case ';': { gtk_text_iter_forward_to_line_end(&scan_iter); if ((expr_start == -1) && (gtk_text_iter_compare(&cursor_iter, &scan_iter) <= 0)) { /* we're in a comment and there's no enclosing context, but there might be a preceding expression */ if (prev_start != -1) { GtkTextIter semi_iter; gtk_text_buffer_get_iter_at_offset(g->buffer, &semi_iter, prev_start); eval_text(g, &semi_iter, &scan_iter); return; } glistener_insert_text(g, "\n"); return; } } break; case '#': { /* the special cases here involve block comments and character constants * there's also #<...> if user types inside the brackets and there's whitespace to confuse it */ GtkTextIter bc_iter, c_iter; gunichar nc; c_iter = scan_iter; bc_iter = scan_iter; gtk_text_iter_forward_char(&bc_iter); nc = gtk_text_iter_get_char(&bc_iter); if (nc == '|') { int last_cs = 0; if (!gtk_text_iter_forward_find_char(&scan_iter, is_block_comment, &last_cs, &end_iter)) { /* we're in a unclosed block comment */ glistener_insert_text(g, "\n"); return; } if ((expr_start == -1) && (gtk_text_iter_compare(&cursor_iter, &scan_iter) <= 0)) { /* we're in a block comment and there's no enclosing context, but there might be a preceding expression */ if (prev_start != -1) { GtkTextIter semi_iter; gtk_text_buffer_get_iter_at_offset(g->buffer, &semi_iter, prev_start); eval_text(g, &semi_iter, &scan_iter); return; } glistener_insert_text(g, "\n"); return; } } else { if (nc == '\\') { gtk_text_iter_forward_chars(&scan_iter, 2); if (gtk_text_iter_get_char(&scan_iter) == 'x') { gtk_text_iter_forward_char(&scan_iter); while (g_unichar_isdigit(gtk_text_iter_get_char(&scan_iter))) gtk_text_iter_forward_char(&scan_iter); } else gtk_text_iter_forward_char(&scan_iter); if (expr_start == -1) { if (gtk_text_iter_compare(&cursor_iter, &scan_iter) <= 0) { /* we're in a character constant with no surrounding context */ eval_text(g, &c_iter, &scan_iter); return; } prev_start = gtk_text_iter_get_offset(&c_iter); } continue; } else { /* a variable name can't start with '#', so I think we can assume #<... must have a closing > ? * other retricted chars: ,:`' */ if (nc == '<') gtk_text_iter_forward_find_char(&scan_iter, is_gt, NULL, &end_iter); } } } break; case '(': if (open_parens == 0) expr_start = gtk_text_iter_get_offset(&scan_iter); open_parens++; break; case ')': open_parens--; if (open_parens == 0) { GtkTextIter c_iter; /* see if the cursor is in the current expression */ if (expr_start == -1) { /* unmatched close-paren */ add_inverse(g, gtk_text_iter_get_offset(&scan_iter)); g->flashes = 4; g_timeout_add_full(0, (guint32)g->flash_time, flash_unbalanced_paren, (gpointer)g, NULL); glistener_post_status(g, "unmatched ')'"); return; } gtk_text_iter_forward_char(&scan_iter); c_iter = scan_iter; while (g_unichar_isspace(gtk_text_iter_get_char(&c_iter))) gtk_text_iter_forward_char(&c_iter); if (gtk_text_iter_compare(&cursor_iter, &c_iter) <= 0) { /* we're in an expression with no surrounding context */ GtkTextIter c_iter; if (any_start != -1) gtk_text_buffer_get_iter_at_offset(g->buffer, &c_iter, any_start); else gtk_text_buffer_get_iter_at_offset(g->buffer, &c_iter, expr_start); eval_text(g, &c_iter, &scan_iter); return; } if (any_start != -1) prev_start = any_start; else prev_start = expr_start; expr_start = -1; any_start = -1; continue; } break; } } else { if (expr_start == -1) { if (any_start != -1) { if (gtk_text_iter_compare(&cursor_iter, &scan_iter) <= 0) { GtkTextIter c_iter; /* an atom with no context */ gtk_text_buffer_get_iter_at_offset(g->buffer, &c_iter, any_start); eval_text(g, &c_iter, &scan_iter); return; } prev_start = any_start; any_start = -1; } } } gtk_text_iter_forward_char(&scan_iter); } /* we fell off the end */ if (open_parens == 0) { GtkTextIter c_iter; /* an atom with no context */ gtk_text_buffer_get_iter_at_offset(g->buffer, &c_iter, any_start); eval_text(g, &c_iter, &end_iter); return; } /* find unmatched open-paren, etc */ if (open_parens > 1) /* if == 1, it's at expr_start */ { GtkTextIter p_iter; gtk_text_buffer_get_iter_at_offset(g->buffer, &p_iter, start_pos); find_open_paren(g, open_parens - 1, end_pos, &expr_start, &p_iter); } add_inverse(g, expr_start); g->flashes = 4; g_timeout_add_full(0, (guint32)g->flash_time, flash_unbalanced_paren, (gpointer)g, NULL); glistener_post_status(g, "unmatched '('"); glistener_insert_text(g, "\n"); } /* ---------------- completion and indentation ---------------- */ /* realpath eqv in glib? -- not available yet (many complaints ...) */ #ifndef _MSC_VER #include #endif static bool is_directory(const char *filename) { #ifndef _MSC_VER #ifdef S_ISDIR struct stat statbuf; return((stat(filename, &statbuf) >= 0) && (S_ISDIR(statbuf.st_mode))); #endif #endif return(false); } static char *filename_completion(glistener *g, const char *partial_name) { char *file_name = NULL, *directory_name = NULL, *temp, *new_name = NULL, *slash, *current_match = NULL, *result = NULL; int len = 0, flen, matches = 0; if (partial_name[0] == '~') { const char *home; home = g_getenv("HOME"); if (home) { new_name = (char *)calloc(strlen(partial_name) + strlen(home) + 1, sizeof(char)); strncpy(new_name, home, strlen(home)); strcat(new_name, (char *)(partial_name + 1)); } } if (!new_name) { int new_len; new_len = strlen(partial_name) + 1; new_name = (char *)calloc(new_len, sizeof(char)); strcopy(new_name, partial_name, new_len); } slash = g_utf8_strrchr(new_name, -1, (gunichar)'/'); if (slash) { len = slash - new_name + 1; temp = (char *)malloc(len * sizeof(char)); file_name = (char *)(new_name + len); strcopy(temp, new_name, len); temp[len - 1] = '\0'; directory_name = realpath(temp, NULL); free(temp); } else { file_name = (char *)partial_name; directory_name = g_get_current_dir(); } if (file_name) flen = strlen(file_name); else return(NULL); glistener_clear_status(g); if ((directory_name) && (file_name)) { GDir *dir; dir = g_dir_open(directory_name, 0, NULL); while (true) { const char *rname; rname = g_dir_read_name(dir); if (!rname) break; if (strncmp(rname, file_name, flen) == 0) { if (strcmp(rname, file_name) != 0) glistener_append_status(g, rname); if (current_match == NULL) { len = strlen(rname); current_match = (char *)calloc(len + 2, sizeof(char)); strcopy(current_match, rname, len + 2); } else { int j; matches++; for (j = 0; j < len; j++) if (current_match[j] != rname[j]) { current_match[j] = '\0'; len = j; if (len <= flen) { /* can't extend current name because of ambiguous matches, so give up */ g_dir_close(dir); if (directory_name) free(directory_name); if (new_name) free(new_name); return(NULL); } break; } } } } if (dir) g_dir_close(dir); } if (len == flen) result = NULL; else { result = current_match; if ((slash) && (current_match)) { /* attach matched portion to user's indication of dir */ result = (char *)calloc(strlen(partial_name) + strlen(current_match) + 3, sizeof(char)); temp = g_utf8_strrchr(partial_name, -1, (gunichar)'/'); strncpy(result, partial_name, temp - partial_name + 1); strcat(result, current_match); free(current_match); } if ((result) && (matches == 0)) { if ((directory_name) && (result[0] == '~')) { char *str; str = (char *)calloc(strlen(directory_name) + strlen(result) + 2, sizeof(char)); strcat(str, directory_name); strcat(str, "/"); strcat(str, (char *)(result + 1)); if (is_directory(str)) strcat(result, "/"); else strcat(result, "\""); free(str); } else { if (is_directory(result)) strcat(result, "/"); else strcat(result, "\""); } } } if (directory_name) free(directory_name); if (new_name) free(new_name); return(result); } typedef struct { const char *text; char *current_match; int len, tlen; glistener *g; } match_info; static bool compare_names(const char *symbol_name, void *data) { match_info *m = (match_info *)data; if (strncmp(m->text, symbol_name, m->tlen) == 0) { if (strcmp(m->text, symbol_name) != 0) glistener_append_status(m->g, symbol_name); if (m->current_match == NULL) { m->len = strlen(symbol_name); m->current_match = (char *)calloc(m->len + 1, sizeof(char)); strcopy(m->current_match, symbol_name, m->len + 1); } else { int j; for (j = 0; j < m->len; j++) if (m->current_match[j] != symbol_name[j]) { m->current_match[j] = '\0'; m->len = j; break; } } } return((m->len > 0) && (m->len <= m->tlen)); } static char *symbol_completion(glistener *g, const char *text) { match_info *m; char *result = NULL; if (g->completer == default_completer) return(NULL); m = (match_info *)calloc(1, sizeof(match_info)); m->text = text; m->tlen = strlen(text); m->len = 0; m->current_match = NULL; m->g = g; glistener_clear_status(g); g->completer(g, compare_names, (void *)m); if (m->len > m->tlen) result = m->current_match; else { if (m->current_match) free(m->current_match); } free(m); return(result); } static void glistener_completion(glistener *g, int pos) { /* -> indent (no-op if on prompt line and at end?) [tmp has old indentation code] * -> try to complete * -> ??? * * in check_parens, if paren found, check expr for * undefined vars, refedined globals, run lint for other errors * * when key release, also perhaps look for possible completions (with list if > 1) */ char *text; bool in_string = false; text = get_preceding_text(g, pos, &in_string); if ((text) && (*text)) { char *new_name; if (!in_string) { if ((g->is_schemish) && (text[0] == '\'')) /* quoted partial symbol name */ { char *unq; unq = symbol_completion(g, (char *)(text + 1)); if (unq) { int len; len = strlen(unq); new_name = (char *)malloc((len + 2) * sizeof(char)); new_name[0] = '\''; memcpy((void *)(new_name + 1), (void *)unq, len); new_name[len + 1] = '\0'; free(unq); } else new_name = NULL; } else new_name = symbol_completion(g, text); } else new_name = filename_completion(g, text); if (new_name) { int old_len, new_len; old_len = strlen(text); new_len = strlen(new_name); gtk_text_buffer_insert_at_cursor(g->buffer, (char *)(new_name + old_len), new_len - old_len); free(new_name); } g_free(text); } else { /* here we're indenting. This code assumes we're using a true fixed width font -- "nimbus mono 10" is not one. */ int pos, bpos, epos, bline, cline, linepos, linecol; GtkTextIter cursor, curline, start_limit, end_limit; pos = find_expression_limits(g, &bpos, &epos); gtk_text_buffer_get_iter_at_offset(g->buffer, &start_limit, bpos - 1); gtk_text_buffer_get_iter_at_offset(g->buffer, &end_limit, epos); gtk_text_buffer_get_iter_at_offset(g->buffer, &cursor, pos); bline = gtk_text_iter_get_line(&start_limit); /* eline = gtk_text_iter_get_line(&end_limit); */ cline = gtk_text_iter_get_line(&cursor); gtk_text_buffer_get_iter_at_line(g->buffer, &curline, cline); linepos = gtk_text_iter_get_offset(&curline); linecol = gtk_text_iter_get_line_offset(&cursor); if ((bline == cline) || (find_not_whitespace(g, linepos, &cursor))) glistener_insert_text(g, " "); else { GtkTextIter paren; int oparen_pos; if (!find_open_paren(g, 1, pos, &oparen_pos, &start_limit)) glistener_insert_text(g, " "); else { int oparen_col; gtk_text_buffer_get_iter_at_offset(g->buffer, &paren, oparen_pos); oparen_col = gtk_text_iter_get_line_offset(&paren); /* we're at linecol, it's at oparen_col */ if (oparen_col > linecol) { int cols; char *spaces; cols = oparen_col - linecol + 2; spaces = (char *)malloc((cols + 1) * sizeof(char)); memset((void *)spaces, 32, cols); spaces[cols] = '\0'; /* now see what follows the unmatched ( */ gtk_text_iter_forward_char(&paren); if (gtk_text_iter_get_char(&paren) == '(') { glistener_insert_text(g, (const char *)(spaces + 1)); free(spaces); } else { GtkTextIter s1, e1; int start = 0, end = 0; char *text; glistener_insert_text(g, (const char *)spaces); /* default indentation */ free(spaces); gtk_text_buffer_get_iter_at_offset(g->buffer, &start_limit, oparen_pos); gtk_text_buffer_get_iter_at_offset(g->buffer, &end_limit, epos); find_surrounding_word(g, oparen_pos + 1, is_delimiter, &start, &end, &start_limit, &end_limit); gtk_text_buffer_get_iter_at_offset(g->buffer, &s1, start); gtk_text_buffer_get_iter_at_offset(g->buffer, &e1, end); text = gtk_text_buffer_get_text(g->buffer, &s1, &e1, true); if (text) { if (strcmp(text, "or") == 0) glistener_insert_text(g, " "); else { if (strcmp(text, "and") == 0) glistener_insert_text(g, " "); else { if (strcmp(text, "cond") == 0) glistener_insert_text(g, " "); else { if (strcmp(text, "if") == 0) { if (cline - bline == 1) glistener_insert_text(g, " "); } } } } g_free(text); } } } } } } } /* ---------------- colorizing ---------------- */ static void glistener_colorizer_callback(glistener *g) { GtkTextIter scan_iter, end_iter; int cur_pos, start_pos, end_pos, expr_start = -1, any_start = -1, open_parens = 0, end_space_pos = 0; bool atom_awaits = false; if ((g->colorizer == default_colorizer) || (!g->is_schemish)) return; find_expression_limits(g, &start_pos, &end_pos); if (start_pos >= end_pos) return; cur_pos = start_pos; end_space_pos = start_pos - 1; gtk_text_buffer_get_iter_at_offset(g->buffer, &scan_iter, start_pos); gtk_text_buffer_get_iter_at_offset(g->buffer, &end_iter, end_pos); gtk_text_buffer_remove_all_tags(g->buffer, &scan_iter, &end_iter); while (gtk_text_iter_compare(&scan_iter, &end_iter) < 0) { gunichar c; c = gtk_text_iter_get_char(&scan_iter); cur_pos = gtk_text_iter_get_offset(&scan_iter); if (!g_unichar_isspace(c)) { if (any_start == -1) any_start = cur_pos; switch (c) { case '"': { int slashes = 0; if (!gtk_text_iter_forward_find_char(&scan_iter, is_unslashed_double_quote, &slashes, &end_iter)) { /* we're in an unclosed string constant */ g->colorizer(g, GLISTENER_STRING, any_start, end_pos); return; } gtk_text_iter_forward_char(&scan_iter); /* step over the close double-quote */ g->colorizer(g, GLISTENER_STRING, cur_pos, gtk_text_iter_get_offset(&scan_iter)); } continue; break; case ';': { gtk_text_iter_forward_to_line_end(&scan_iter); g->colorizer(g, GLISTENER_COMMENT, cur_pos, gtk_text_iter_get_offset(&scan_iter)); } break; case '#': { /* the special cases here involve block comments and character constants * there's also #<...> if user types inside the brackets and there's whitespace to confuse it */ GtkTextIter bc_iter; gunichar nc; bc_iter = scan_iter; gtk_text_iter_forward_char(&bc_iter); nc = gtk_text_iter_get_char(&bc_iter); if (nc == '|') { int last_cs = 0; bool found_end; found_end = gtk_text_iter_forward_find_char(&scan_iter, is_block_comment, &last_cs, &end_iter); g->colorizer(g, GLISTENER_BLOCK_COMMENT, cur_pos, gtk_text_iter_get_offset(&scan_iter) + 1); if ((!found_end) || (expr_start == -1)) /* we're in a unclosed block comment or there's no enclosing context */ return; } else { if (nc == '\\') { gtk_text_iter_forward_chars(&scan_iter, 2); if (gtk_text_iter_get_char(&scan_iter) == 'x') { gtk_text_iter_forward_char(&scan_iter); while (g_unichar_isdigit(gtk_text_iter_get_char(&scan_iter))) gtk_text_iter_forward_char(&scan_iter); } else gtk_text_iter_forward_char(&scan_iter); g->colorizer(g, GLISTENER_CHARACTER, cur_pos, gtk_text_iter_get_offset(&scan_iter)); if (expr_start == -1) /* we're in a character constant with no surrounding context */ return; continue; } else { /* a variable name can't start with '#', so I think we can assume #<... must have a closing > ? * other retricted chars: ,:`' */ if (nc == '<') { gtk_text_iter_forward_find_char(&scan_iter, is_gt, NULL, &end_iter); g->colorizer(g, GLISTENER_BRACKET, cur_pos, gtk_text_iter_get_offset(&scan_iter) + 1); } else atom_awaits = true; /* #t for example */ } } } break; case '(': if (open_parens == 0) expr_start = cur_pos; open_parens++; end_space_pos = cur_pos; break; case ')': if (atom_awaits) { if (cur_pos > end_space_pos + 1) g->colorizer(g, GLISTENER_ATOM, end_space_pos + 1, cur_pos); atom_awaits = false; } end_space_pos = cur_pos; open_parens--; if (open_parens == 0) { /* if this is an unmatched ')' we have already reported that */ if (expr_start == -1) /* unmatched close-paren */ return; gtk_text_iter_forward_char(&scan_iter); g->colorizer(g, GLISTENER_LIST, any_start, cur_pos); expr_start = -1; any_start = -1; continue; } break; default: atom_awaits = true; break; } } else { if (atom_awaits) { g->colorizer(g, GLISTENER_ATOM, end_space_pos + 1, cur_pos); atom_awaits = false; } end_space_pos = cur_pos; if (expr_start == -1) any_start = -1; } gtk_text_iter_forward_char(&scan_iter); } if (atom_awaits) g->colorizer(g, GLISTENER_ATOM, end_space_pos + 1, end_pos); } static void colorize_listener(GtkTextBuffer *buffer, void *data) { glistener_colorizer_callback((glistener *)data); } /* ---------------- testing ---------------- * * these functions are intended for regression test suites. They make it possible to mimic * user and and see the resultant output. */ char *glistener_evaluate(glistener *g) { int start, end; glistener_return_callback(g); start = find_previous_prompt(g, glistener_cursor_position(g)); end = find_current_prompt(g) - g->prompt_length; return(glistener_text(g, start, end)); } char *glistener_complete(glistener *g) { int start, end; glistener_completion(g, glistener_cursor_position(g)); start = find_previous_prompt(g, glistener_cursor_position(g)); end = find_current_prompt(g) - g->prompt_length; return(glistener_text(g, start, end)); } /* ---------------- new listener ---------------- */ #define SIGNAL_CONNECT(Widget, Signal, Function, Data) g_signal_connect(G_OBJECT(Widget), Signal, G_CALLBACK(Function), (gpointer)Data) #define SIGNAL_CONNECT_AFTER(Widget, Signal, Function, Data) g_signal_connect_after(G_OBJECT(Widget), Signal, G_CALLBACK(Function), (gpointer)Data) glistener *glistener_new(GtkWidget *parent, void (*initializations)(glistener *g, GtkWidget *new_listener)) { glistener *g; GtkWidget *vb; /* make a new glistener, set defaults */ g = (glistener *)calloc(1, sizeof(glistener)); g->is_schemish = true; g->helper = default_helper; g->checker = default_checker; g->completer = default_completer; g->evaluator = default_evaluator; g->colorizer = default_colorizer; g->keyer = default_keyer; g->prompt_tag = NULL; g->prompt = NULL; g->prompt_length = 0; g->strings = NULL; g->strings_size = 0; g->strings_pos = 0; g->first_time = true; g->flash_tag = NULL; g->flashes = 0; g->flash_paren_pos = -1; g->flash_time = 150; g->highlight_tag = NULL; g->highlight_start = -1; g->highlight_end = -1; g->insertion_position = 0; g->wait_cursor = NULL; g->arrow_cursor = NULL; g->status_message = NULL; /* make the listener widgets */ g->scroller = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(g->scroller), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); g->text = gtk_text_view_new(); g->buffer = gtk_text_buffer_new(NULL); gtk_text_view_set_buffer(GTK_TEXT_VIEW(g->text), g->buffer); gtk_text_view_set_editable(GTK_TEXT_VIEW(g->text), true); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(g->text), GTK_WRAP_NONE); gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(g->text), true); gtk_text_view_set_left_margin(GTK_TEXT_VIEW(g->text), 4); gtk_container_add(GTK_CONTAINER(g->scroller), g->text); gtk_widget_set_events(g->text, GDK_ALL_EVENTS_MASK); if (default_font) glistener_set_font(g, default_font); else glistener_set_font(g, pango_font_description_from_string("Monospace 11")); glistener_key_bindings(g, GTK_TEXT_VIEW_GET_CLASS(g->text)); if (default_text_color) glistener_set_text_color(g, default_text_color); if (default_background_color) glistener_set_background_color(g, default_background_color); if (initializations) initializations(g, g->text); SIGNAL_CONNECT(g->text, "key_press_event", glistener_key_press, (gpointer)g); SIGNAL_CONNECT(g->text, "key_release_event", glistener_key_release, (gpointer)g); SIGNAL_CONNECT(g->text, "button_release_event", glistener_button_release, (gpointer)g); SIGNAL_CONNECT_AFTER(g->buffer, "insert-text", text_insert, (gpointer)g); SIGNAL_CONNECT_AFTER(g->buffer, "changed", colorize_listener, (gpointer)g); SIGNAL_CONNECT_AFTER(g->text, "cut-clipboard", check_for_empty_listener, (gpointer)g); if (!g->prompt) { if (default_prompt) glistener_set_prompt(g, default_prompt); else { g->prompt = (char *)calloc(3, sizeof(char)); g->prompt[0] = '\n'; g->prompt[1] = '>'; g->prompt_length = g_utf8_strlen(g->prompt, -1); } } if (default_prompt_tag) glistener_set_prompt_tag(g, default_prompt_tag); if (default_highlight_tag) glistener_set_highlight_tag(g, default_highlight_tag); /* put in the first prompt without the preceding */ { GtkTextIter start; gtk_text_buffer_get_start_iter(g->buffer, &start); prompt_insert(g, &start, true); } if (!g->wait_cursor) g->wait_cursor = GDK_CURSOR_NEW(GDK_WATCH); if (!g->arrow_cursor) g->arrow_cursor = GDK_CURSOR_NEW(GDK_LEFT_PTR); #if (!GTK_CHECK_VERSION(3, 0, 0)) vb = gtk_table_new(2, 1, false); if (parent) gtk_container_add(GTK_CONTAINER(parent), vb); gtk_table_attach(GTK_TABLE(vb), g->scroller, 0, 1, 0, 1, /* left right top bottom */ (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)(GTK_FILL | GTK_EXPAND | GTK_SHRINK), 0, 0); g->status = gtk_statusbar_new(); gtk_table_attach(GTK_TABLE(vb), g->status, 0, 1, 1, 2, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)(GTK_FILL), 0, 0); #else vb = gtk_grid_new(); if (parent) gtk_container_add(GTK_CONTAINER(parent), vb); gtk_widget_set_halign(g->scroller, GTK_ALIGN_FILL); gtk_widget_set_valign(g->scroller, GTK_ALIGN_FILL); gtk_widget_set_hexpand(g->scroller, TRUE); gtk_widget_set_vexpand(g->scroller, TRUE); gtk_grid_attach(GTK_GRID(vb), g->scroller, 0, 0, 1, 1); /* left top w h */ g->status = gtk_statusbar_new(); gtk_widget_set_halign(g->status, GTK_ALIGN_FILL); gtk_grid_attach(GTK_GRID(vb), g->status, 0, 1, 1, 1); #endif gtk_widget_show(g->text); gtk_widget_show(g->scroller); gtk_widget_show(g->status); gtk_widget_show(vb); return(g); } /* changes: * 19-Mar-15: changed strcopy macro. * 7-June: added keyer function. * 4-June: added colorizer function. * 28-May: added checker function. */ /* C-s/r could prompt in the status area if it were a text entry, not a label widget -- is that possible? * there's also gtk_overlay (see gtk-demo/overlay.c) in 3.9.8 -- but it says "static position". */ snd-16.1/autosave.scm0000644000076400007640000000530612561523227012677 0ustar bilbil;;; -------- auto-save (provide 'snd-autosave.scm) (define auto-save-interval 60.0) ;seconds between auto-save checks (define auto-saving #f) (define cancel-auto-save (let ((documentation "(cancel-auto-save) turns off the auto-save mechanism")) (lambda () (set! auto-saving #f)))) (define auto-save (let ((documentation "(auto-save) starts watching files, automatically saving backup copies as edits accumulate")) (lambda () (define (auto-save-temp-name snd) (string-append (if (and (string? *temp-dir*) (> (length *temp-dir*) 0)) (string-append *temp-dir* "/") "") "#" (short-file-name snd) "#")) (define (unsaved-edits snd) (or (sound-property 'auto-save snd) 0)) (define (clear-unsaved-edits snd) (set! (sound-property 'auto-save snd) 0)) (define (increment-unsaved-edits snd) (set! (sound-property 'auto-save snd) (+ 1 (sound-property 'auto-save snd)))) (define (upon-edit snd) (lambda () (increment-unsaved-edits snd))) (define (auto-save-open-func snd) (let ((temp-file (auto-save-temp-name snd))) (if (and (file-exists? temp-file) (< (file-write-date (file-name snd)) (file-write-date temp-file))) (snd-warning (format #f "auto-saved version of ~S (~S) is newer" (short-file-name snd) temp-file))) (do ((i 0 (+ 1 i))) ((= i (channels snd))) (if (null? (hook-functions (edit-hook snd i))) (hook-push (edit-hook snd i) (lambda (hook) (upon-edit (hook 'snd)))))) (clear-unsaved-edits snd))) (define (auto-save-done snd) (let ((temp-file (auto-save-temp-name snd))) (if (file-exists? temp-file) (delete-file temp-file)) (clear-unsaved-edits snd))) (define (auto-save-func) (if auto-saving (begin (for-each (lambda (snd) (if (> (unsaved-edits snd) 0) (let ((save-name (auto-save-temp-name snd))) (status-report (string-append "auto-saving as " save-name "...") snd) (in (* 1000 3) (lambda () (status-report "" snd))) (save-sound-as save-name snd) (clear-unsaved-edits snd)))) (sounds)) (in (* 1000 auto-save-interval) auto-save-func)))) (if (not (member auto-save-done (hook-functions close-hook))) (begin (for-each auto-save-open-func (sounds)) (hook-push after-open-hook (lambda (hook) (auto-save-open-func (hook 'snd)))) (hook-push close-hook (lambda (hook) (auto-save-done (hook 'snd)))) (hook-push save-hook (lambda (hook) (auto-save-done (hook 'snd)))) (hook-push exit-hook (lambda (hook) (for-each auto-save-done (sounds)))))) (set! auto-saving #t) (in (floor (* 1000 auto-save-interval)) auto-save-func)))) (auto-save) snd-16.1/bess.scm0000644000076400007640000002436312467370336012016 0ustar bilbil;;; this is obsolete -- it needs some replacement for the mus-audio* functions (if (provided? 'snd-motif) (with-let (sublet *motif*) ;; set up our user-interface (let* ((app (car (main-widgets))) (shell (let* ((xdismiss (XmStringCreate "Go away" XmFONTLIST_DEFAULT_TAG)) (xhelp (XmStringCreate "Help" XmFONTLIST_DEFAULT_TAG)) (titlestr (XmStringCreate "FM Forever!" XmFONTLIST_DEFAULT_TAG)) (dialog (XmCreateTemplateDialog (cadr (main-widgets)) "FM Forever!" (list XmNcancelLabelString xdismiss XmNhelpLabelString xhelp XmNautoUnmanage #f XmNdialogTitle titlestr XmNresizePolicy XmRESIZE_GROW XmNnoResize #f XmNtransient #f)))) (XtAddCallback dialog XmNhelpCallback (lambda (w context info) (snd-print "This dialog lets you experiment with simple FM"))) (XmStringFree xhelp) (XmStringFree xdismiss) (XmStringFree titlestr) dialog)) (dpy (XtDisplay shell)) (screen (DefaultScreenOfDisplay dpy)) ;; (cmap (DefaultColormap dpy (DefaultScreen dpy))) (black (BlackPixelOfScreen screen)) (white (WhitePixelOfScreen screen))) (define (set-flabel label value) (let ((s1 (XmStringCreate (format #f "~,3F" value) XmFONTLIST_DEFAULT_TAG))) (XtVaSetValues label (list XmNlabelString s1)) (XmStringFree s1))) (define (set-ilabel label value) (let ((s1 (XmStringCreate (format #f "~D" value) XmFONTLIST_DEFAULT_TAG))) (XtVaSetValues label (list XmNlabelString s1)) (XmStringFree s1))) (let* ((light-blue *position-color*) (form (XtCreateManagedWidget "form" xmFormWidgetClass shell (list XmNbackground white XmNforeground black XmNresizePolicy XmRESIZE_GROW))) ;; toggle named "play" (play-button (XtCreateManagedWidget "play" xmToggleButtonWidgetClass form (list XmNleftAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_NONE XmNtopAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_NONE XmNbackground white))) ;; carrier freq (carrier (XtCreateManagedWidget "carrier freq:" xmLabelWidgetClass form (list XmNleftAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_NONE XmNtopAttachment XmATTACH_WIDGET XmNtopWidget play-button XmNrightAttachment XmATTACH_NONE XmNrecomputeSize #f XmNbackground white))) (freq-label (XtCreateManagedWidget "label" xmLabelWidgetClass form (list XmNleftAttachment XmATTACH_WIDGET XmNleftWidget carrier XmNbottomAttachment XmATTACH_NONE XmNtopAttachment XmATTACH_OPPOSITE_WIDGET XmNtopWidget carrier XmNrightAttachment XmATTACH_NONE XmNbackground white))) (freq-scale (XtCreateManagedWidget "carrier freq" xmScaleWidgetClass form (list XmNleftAttachment XmATTACH_WIDGET XmNleftWidget freq-label XmNbottomAttachment XmATTACH_NONE XmNtopAttachment XmATTACH_OPPOSITE_WIDGET XmNtopWidget freq-label XmNrightAttachment XmATTACH_FORM XmNshowValue #f XmNorientation XmHORIZONTAL XmNbackground light-blue))) ;; amp (amp (XtCreateManagedWidget "amp:" xmLabelWidgetClass form (list XmNleftAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_NONE XmNtopAttachment XmATTACH_WIDGET XmNtopWidget carrier XmNrightAttachment XmATTACH_NONE XmNrecomputeSize #f XmNbackground white))) (amp-label (XtCreateManagedWidget "label" xmLabelWidgetClass form (list XmNleftAttachment XmATTACH_WIDGET XmNleftWidget amp XmNbottomAttachment XmATTACH_NONE XmNtopAttachment XmATTACH_OPPOSITE_WIDGET XmNtopWidget amp XmNrightAttachment XmATTACH_NONE XmNbackground white))) (amp-scale (XtCreateManagedWidget "amp" xmScaleWidgetClass form (list XmNleftAttachment XmATTACH_WIDGET XmNleftWidget amp-label XmNbottomAttachment XmATTACH_NONE XmNtopAttachment XmATTACH_OPPOSITE_WIDGET XmNtopWidget amp-label XmNrightAttachment XmATTACH_FORM XmNshowValue #f XmNorientation XmHORIZONTAL XmNbackground light-blue))) ;; fm index (fm-index (XtCreateManagedWidget "fm index:" xmLabelWidgetClass form (list XmNleftAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_NONE XmNtopAttachment XmATTACH_WIDGET XmNtopWidget amp-scale XmNrightAttachment XmATTACH_NONE XmNrecomputeSize #f XmNbackground white))) (fm-label (XtCreateManagedWidget "label" xmLabelWidgetClass form (list XmNleftAttachment XmATTACH_WIDGET XmNleftWidget fm-index XmNbottomAttachment XmATTACH_NONE XmNtopAttachment XmATTACH_OPPOSITE_WIDGET XmNtopWidget fm-index XmNrightAttachment XmATTACH_NONE XmNbackground white))) (fm-scale (XtCreateManagedWidget "fm index" xmScaleWidgetClass form (list XmNleftAttachment XmATTACH_WIDGET XmNleftWidget fm-label XmNbottomAttachment XmATTACH_NONE XmNtopAttachment XmATTACH_OPPOSITE_WIDGET XmNtopWidget fm-label XmNrightAttachment XmATTACH_FORM XmNshowValue #f XmNorientation XmHORIZONTAL XmNbackground light-blue))) ;; c/m ratio (cm-ratio (XtCreateManagedWidget "c/m ratio:" xmLabelWidgetClass form (list XmNleftAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_NONE XmNtopAttachment XmATTACH_WIDGET XmNtopWidget fm-scale XmNrightAttachment XmATTACH_NONE XmNrecomputeSize #f XmNbackground white))) (cm-label (XtCreateManagedWidget "label" xmLabelWidgetClass form (list XmNleftAttachment XmATTACH_WIDGET XmNleftWidget cm-ratio XmNbottomAttachment XmATTACH_NONE XmNtopAttachment XmATTACH_OPPOSITE_WIDGET XmNtopWidget cm-ratio XmNrightAttachment XmATTACH_NONE XmNbackground white))) (cm-scale (XtCreateManagedWidget "cm ratio" xmScaleWidgetClass form (list XmNleftAttachment XmATTACH_WIDGET XmNleftWidget cm-label XmNbottomAttachment XmATTACH_NONE XmNtopAttachment XmATTACH_OPPOSITE_WIDGET XmNtopWidget cm-label XmNrightAttachment XmATTACH_FORM XmNshowValue #f XmNorientation XmHORIZONTAL XmNbackground light-blue))) (frequency 220.0) (low-frequency 40.0) (high-frequency 2000.0) (amplitude 0.5) (index 1.0) (high-index 3.0) (ratio 1) (high-ratio 10) (playing 0.0) (carosc (make-oscil 0.0)) (modosc (make-oscil 0.0))) (define (freq-callback w c i) (set! frequency (+ low-frequency (* (.value i) (/ (- high-frequency low-frequency) 100.0)))) (set-flabel freq-label frequency)) (define (amp-callback w c i) (set! amplitude (/ (.value i) 100.0)) (set-flabel amp-label amplitude)) (define (fm-callback w c i) (set! index (* (.value i) (/ high-index 100.0))) (set-flabel fm-label index)) (define (ratio-callback w c i) (set! ratio (floor (* (.value i) (/ high-ratio 100.0)))) (set-ilabel cm-label ratio)) ;; add scale-change (drag and value-changed) callbacks (XtAddCallback freq-scale XmNdragCallback freq-callback) (XtAddCallback freq-scale XmNvalueChangedCallback freq-callback) (XtAddCallback amp-scale XmNdragCallback amp-callback) (XtAddCallback amp-scale XmNvalueChangedCallback amp-callback) (XtAddCallback fm-scale XmNdragCallback fm-callback) (XtAddCallback fm-scale XmNvalueChangedCallback fm-callback) (XtAddCallback cm-scale XmNdragCallback ratio-callback) (XtAddCallback cm-scale XmNvalueChangedCallback ratio-callback) (XtAddCallback play-button XmNvalueChangedCallback (lambda (w c i) (set! playing (if (.set i) 1.0 0.0)))) ;; set initial values (set-flabel freq-label frequency) (set-flabel amp-label amplitude) (set-flabel fm-label index) (set-ilabel cm-label ratio) (XmScaleSetValue freq-scale (floor (* 100 (/ (- frequency low-frequency) (- high-frequency low-frequency))))) (XmScaleSetValue amp-scale (floor (* 100 amplitude))) (XmScaleSetValue fm-scale (floor (* 100 (/ index high-index)))) (XmScaleSetValue cm-scale (floor (* ratio (/ 100 high-ratio)))) (XtManageChild shell) (XtRealizeWidget shell) ;; send fm data to dac (let* ((bufsize 256) (srate 22050) (work-proc #f) ;(data (make-float-vector bufsize 0.0)) (port (mus-audio-open-output mus-audio-default srate 1 mus-lshort (* bufsize 2)))) (if (< port 0) (format #t "can't open DAC!")) (XmAddWMProtocolCallback (cadr (main-widgets)) ; shell (XmInternAtom dpy "WM_DELETE_WINDOW" #f) (lambda (w c i) (XtRemoveWorkProc work-proc) ; odd that there's no XtAppRemoveWorkProc (mus-audio-close port)) #f) (XtAddCallback shell XmNcancelCallback (lambda (w context info) (XtRemoveWorkProc work-proc) (mus-audio-close port) (XtUnmanageChild shell))) (set! work-proc (XtAppAddWorkProc app (lambda (ignored-arg) (let ((data (make-float-vector bufsize 0.0))) (do ((i 0 (+ 1 i))) ((= i bufsize)) (float-vector-set! data i (* amplitude playing (oscil carosc (+ (hz->radians frequency) (* index (oscil modosc (hz->radians (* ratio frequency))))))))) (mus-audio-write port data bufsize) #f)))))))))snd-16.1/enved.scm0000644000076400007640000001754712511331645012157 0ustar bilbil;;; use the lisp graph section of the display as an envelope editor ;;; ;;; (start-enveloping) sets this in progress (for subsequently opened sounds) ;;; (stop-enveloping) turns it off ;;; (channel-envelope snd chn) returns the current envelope associated with snd's channel chn ;;; (set! (channel-envelope snd chn) env) sets it to a new list of breakpoints ;;; ;;; (play-with-envs snd) sets channel amps during playback from the associated enved envelopes ;;; (play-panned snd) pans a mono sound following its enved envelope into a stereo sound (provide 'snd-enved.scm) (define channel-envelope (dilambda (let ((documentation "(channel-envelope snd chn) returns the current enved envelope associated with snd's channel chn")) (lambda (snd chn) (or (channel-property 'enved-envelope snd chn) ()))) (lambda (snd chn new-env) (set! (channel-property 'enved-envelope snd chn) new-env) (graph new-env "" 0.0 1.0 0.0 1.0 snd chn)))) (define (create-initial-envelopes hook) (let ((snd (hook 'snd))) (do ((i 0 (+ i 1))) ((= i (channels snd))) (set! (dot-size snd i) 8) (set! (channel-envelope snd i) (list 0.0 1.0 1.0 1.0))))) ;;; if click on point, delete, ;;; if click/drag on point, move it until release ;;; if click off point, add (and subsequent drag) (define mouse-down 0) (define mouse-up 0) (define click-time 10) ; .1 sec? (define mouse-pos 0) (define mouse-new #f) (define (mouse-press-envelope hook) (let ((snd (hook 'snd)) (chn (hook 'chn)) (ux (hook 'x)) (uy (hook 'y)) (mouse-radius .03)) (define (add-envelope-point x y cur-env) (let ((new-env ())) (define (search-point e) (if (null? e) (append new-env (list x y)) (if (= (car e) x) (append new-env (list x y) (cddr e)) (if (> (car e) x) (append new-env (list x y) e) (begin (set! new-env (append new-env (list (car e) (cadr e)))) (search-point (cddr e))))))) (search-point cur-env))) (define (envelope-position x cur-env) (define (search-point e pos) (if (= (car e) x) pos (search-point (cddr e) (+ pos 2)))) (search-point cur-env 0)) (define (on-dot? x y cur-env pos) (and (pair? cur-env) (or (and (< (abs (- (car cur-env) x)) mouse-radius) (< (abs (- (cadr cur-env) y)) mouse-radius) pos) (on-dot? x y (cddr cur-env) (+ pos 2))))) (let* ((x (max 0.0 (min ux 1.0))) (y (max 0.0 (min uy 1.0))) (cur-env (channel-envelope snd chn)) (pos (on-dot? x y cur-env 0))) (set! mouse-new (not pos)) (set! mouse-down (get-internal-real-time)) (if (not pos) (let ((new-x (max 0.001 (min x .999)))) (set! (channel-envelope snd chn) (add-envelope-point new-x y cur-env)) (set! mouse-pos (envelope-position new-x (channel-envelope snd chn)))) (set! mouse-pos pos))))) (define (mouse-drag-envelope hook) (let ((snd (hook 'snd)) (chn (hook 'chn)) (x (hook 'x)) (y (hook 'y))) ;; point exists, needs to be edited with check for various bounds (define (edit-envelope-point pos x y cur-env) (let ((new-env ())) (define (search-point e npos) (if (= npos pos) (append new-env (list x y) (cddr e)) (begin (set! new-env (append new-env (list (car e) (cadr e)))) (search-point (cddr e) (+ npos 2))))) (search-point cur-env 0))) (let* ((cur-env (channel-envelope snd chn)) (lx (if (= mouse-pos 0) 0.0 (if (>= mouse-pos (- (length cur-env) 2)) 1.0 (max (+ (list-ref cur-env (- mouse-pos 2)) .001) (min x (- (list-ref cur-env (+ mouse-pos 2)) .001)))))) (ly (max 0.0 (min y 1.0)))) (set! (channel-envelope snd chn) (edit-envelope-point mouse-pos lx ly cur-env)) (update-lisp-graph snd chn)))) (define (mouse-release-envelope hook) (let ((snd (hook 'snd)) (chn (hook 'chn)) (axis (hook 'axis))) (define (remove-envelope-point pos cur-env) (let ((new-env ())) (define (search-point e npos) (if (null? e) new-env (if (= pos npos) (append new-env (cddr e)) (begin (set! new-env (append new-env (list (car e) (cadr e)))) (search-point (cddr e) (+ npos 2)))))) (search-point cur-env 0))) (if (= axis lisp-graph) (let ((cur-env (channel-envelope snd chn))) (set! mouse-up (get-internal-real-time)) (if (and (not mouse-new) (<= (- mouse-up mouse-down) click-time) (not (= mouse-pos 0)) (< mouse-pos (- (length cur-env) 2))) (set! (channel-envelope snd chn) (remove-envelope-point mouse-pos cur-env))) (update-lisp-graph snd chn) (set! mouse-new #f) (set! (hook 'result) #t))))) (define (enveloping-key-press hook) (let ((snd (hook 'snd)) (chn (hook 'chn)) (key (hook 'key)) (state (hook 'state))) ;; C-g returns to original env ;; C-. applies current env to amplitude (if (and (= key (char->integer #\.)) (= state 4)) (begin (env-channel (channel-envelope snd chn) 0 (framples snd chn) snd chn) (set! (hook 'result) #t)) (if (and (= key (char->integer #\g)) (= state 4)) (begin (set! (channel-envelope snd chn) '(0.0 1.0 1.0 1.0)) (set! (hook 'result) #t)))))) (define start-enveloping (let ((documentation "(start-enveloping) starts the enved processes, displaying an envelope editor in each channel")) (lambda () (hook-push after-open-hook create-initial-envelopes) (hook-push mouse-press-hook mouse-press-envelope) (hook-push mouse-drag-hook mouse-drag-envelope) (hook-push mouse-click-hook mouse-release-envelope) (hook-push key-press-hook enveloping-key-press)))) (define stop-enveloping (let ((documentation "(stop-enveloping) turns off the enved channel-specific envelope editors")) (lambda () (hook-remove after-open-hook create-initial-envelopes) (hook-remove mouse-press-hook mouse-press-envelope) (hook-remove mouse-drag-hook mouse-drag-envelope) (hook-remove mouse-click-hook mouse-release-envelope) (hook-remove key-press-hook enveloping-key-press)))) ;;; -------------------------------------------------------------------------------- ;;; ;;; some examples of using this envelope editor (define play-with-envs (let ((documentation "(play-with-envs snd) sets channel amps during playback from the associated enved envelopes")) (lambda* (sound) (let ((chans (channels sound))) (do ((chan 0 (+ 1 chan))) ((= chan chans)) (let ((player (make-player sound chan)) (e (make-env (channel-envelope sound chan) :length (floor (/ (framples sound chan) *dac-size*))))) (add-player player 0 -1 -1 (lambda (reason) (set! (hook-functions play-hook) ()))) (hook-push play-hook (lambda (hook) ;; if dac buffer size in framples is not dac-size, we should do something debonair (set! (amp-control player) (env e)))))) (start-playing chans (srate sound)))))) #| (define play-panned (let ((documentation "(play-panned snd) pans a mono sound following its enved envelope into a stereo sound")) (lambda (sound) (let* ((bufsize 256) (data (make-float-vector (list 2 bufsize) 0.0)) (bytes (* bufsize 4)) (audio-fd (mus-audio-open-output mus-audio-default (srate sound) 2 mus-lshort bytes)) (samp 0) (len (framples sound 0))) (snd-print (format #f "audio-fd: ~A " audio-fd)) (if (not (= audio-fd -1)) (let ((e (make-env (channel-envelope sound 0) :length (floor (/ len bufsize))))) (catch #t (lambda () (do ((res #f (let* ((scaler (env e)) (samps0 (channel->float-vector samp bufsize)) (samps1 (copy samps0))) (copy (float-vector-scale! samps0 scaler) (data 0)) (copy (float-vector-scale! samps1 (- 1.0 scaler)) (data 1)) (mus-audio-write audio-fd data bufsize) (set! samp (+ samp bufsize)) (>= samp len)))) (res))) (lambda args (format #t ";play-panned error: ~A" args))) (mus-audio-close audio-fd))))))) |# snd-16.1/nrev.scm0000644000076400007640000000556112616443317012027 0ustar bilbil;;; NREV (the most popular Samson box reverb) (provide 'snd-nrev.scm) (if (provided? 'snd) (require snd-ws.scm) (require sndlib-ws.scm)) (definstrument (nrev (reverb-factor 1.09) (lp-coeff 0.7) (volume 1.0)) ;; reverb-factor controls the length of the decay -- it should not exceed (/ 1.0 .823) ;; lp-coeff controls the strength of the low pass filter inserted in the feedback loop ;; output-scale can be used to boost the reverb output (let ((dly-len (if (= (floor *clm-srate*) 44100) (vector 2467 2753 3217 3533 3877 4127 599 197 67 101 97 73 67 53 37) (and (= (floor *clm-srate*) 22050) (vector 1237 1381 1607 1777 1949 2063 307 97 31 53 47 37 31 29 17)))) (chan2 (> (channels *output*) 1)) (chan4 (= (channels *output*) 4))) (if (not dly-len) (let ((srscale (/ *clm-srate* 25641))) (define (prime? val) (or (= val 2) (and (odd? val) (do ((i 3 (+ i 2)) (lim (sqrt val))) ((or (= 0 (modulo val i)) (> i lim)) (> i lim)))))) (define (next-prime val) (if (prime? val) val (next-prime (+ val 2)))) (set! dly-len (vector 1433 1601 1867 2053 2251 2399 347 113 37 59 53 43 37 29 19)) (do ((i 0 (+ i 1))) ((= i 15)) (let ((val (floor (* srscale (dly-len i))))) (if (even? val) (set! val (+ val 1))) (set! (dly-len i) (next-prime val)))))) (let ((len (+ (floor *clm-srate*) (framples *reverb*))) (comb1 (make-comb (* .822 reverb-factor) (dly-len 0))) (comb2 (make-comb (* .802 reverb-factor) (dly-len 1))) (comb3 (make-comb (* .773 reverb-factor) (dly-len 2))) (comb4 (make-comb (* .753 reverb-factor) (dly-len 3))) (comb5 (make-comb (* .753 reverb-factor) (dly-len 4))) (comb6 (make-comb (* .733 reverb-factor) (dly-len 5))) (low (make-one-pole lp-coeff (- lp-coeff 1.0))) (allpass1 (make-all-pass -0.700 0.700 (dly-len 6))) (allpass2 (make-all-pass -0.700 0.700 (dly-len 7))) (allpass3 (make-all-pass -0.700 0.700 (dly-len 8))) (allpass4 (make-all-pass -0.700 0.700 (dly-len 9))) ; 10 for quad (allpass5 (make-all-pass -0.700 0.700 (dly-len 11))) (allpass6 (and chan2 (make-all-pass -0.700 0.700 (dly-len 12)))) (allpass7 (and chan4 (make-all-pass -0.700 0.700 (dly-len 13)))) (allpass8 (and chan4 (make-all-pass -0.700 0.700 (dly-len 14))))) (let ((filts (if (not chan2) (vector allpass5) (if (not chan4) (vector allpass5 allpass6) (vector allpass5 allpass6 allpass7 allpass8)))) (combs (make-comb-bank (vector comb1 comb2 comb3 comb4 comb5 comb6))) (allpasses (make-all-pass-bank (vector allpass1 allpass2 allpass3)))) (do ((i 0 (+ i 1))) ((= i len)) (out-bank filts i (all-pass allpass4 (one-pole low (all-pass-bank allpasses (comb-bank combs (* volume (ina i *reverb*)))))))))))) ;;; (with-sound (:reverb nrev) (outa 0 .1) (outa 0 .5 *reverb*)) snd-16.1/snd-forth-init.fs0000644000076400007640000002335012434353162013540 0ustar bilbil\ .snd_forth -- start up file for Snd/Forth \ \ @(#)snd-forth-init.fs 1.43 11/11/14 \ \ You can install the *.fs scripts with: \ \ cd ${top_srcdir}/examples/site-lib \ ./install.fth \ \ or even better \ \ cd ${top_builddir} \ make install \ \ If you have installed *.fs scripts with one of the above mentioned \ commands, you don't need to add a path to *load-path*. \ ${prefix}/share/fth/site-fth is already included. Otherwise you can \ add a path with e.g.: \ \ "/home/mike/snd" add-load-path \ A special *SND-HOME* path points to ~/.snd.d: \ \ ~/.snd.d/sound directory for *clm-file-name* \ ~/.snd.d/zap directory for set-temp-dir \ set-save-dir \ ~/.snd.d/peaks directory for set-peak-env-dir \ \ "HOME" getenv constant *home* \ *home* "/.snd.d" $+ constant *snd-home* \ \ Change these paths! \ #t to *fth-verbose* #f to *fth-debug* \ Redirect Fth output (stdout) to the Snd listener (with snd-print). :port-name "sndout" :write-line <'> snd-print make-soft-port set-*stdout* drop \ Now force output to listener: #t set-show-listener drop before-load-hook lambda: <{ fname -- f }> *fth-verbose* if "\\ loading %s\n" #( fname ) fth-print then #t ; add-hook! before-load-hook '( *filename* ) run-hook drop "HOME" getenv constant *home* *home* "/.snd.d" $+ constant *snd-home* hostname constant *hostname* *hostname* "." string-split car constant *short-hostname* *argv* length 0> [if] *argv* car undef file-basename [else] "snd" [then] constant *program-name* \ if configured --with-shared-sndlib 'sndlib provided? [unless] dl-load sndlib Init_sndlib [then] \ Set them before loading clm.fs. 2 set-default-output-chans drop 48000 set-default-output-srate drop mus-bdouble set-default-output-sample-type drop 512 set-dac-size drop mus-clipping set-clipping drop 1024 1024 * set-mus-file-buffer-size drop 48 set-mus-array-print-length drop mus-array-print-length set-print-length drop 128 set-object-print-length require clm require clm-ins \ Environment variable CLM_SEARCH_PATH \ Path variable where sound files reside. \ csh: setenv CLM_SEARCH_PATH /usr/gnu/sound/SFiles:${HOME}/.snd.d/sound \ sh: export CLM_SEARCH_PATH=/usr/gnu/sound/SFiles:${HOME}/.snd.d/sound "CLM_SEARCH_PATH" getenv dup [if] ":" string-split [each] *clm-search-list* swap array-push to *clm-search-list* [end-each] [else] drop *clm-search-list* *snd-home* "/sound" $+ array-push to *clm-search-list* [then] : clm-print-instrument <{ ins beg dur -- }> "%14s: %5.2f %5.2f" '( ins beg dur ) clm-message ; : clm-sox-player <{ output -- }> "sox -qV1 %s -d" #( output ) string-format file-system unless "exit %d\n" #( exit-status ) fth-print then ; 440.0 to *clm-default-frequency* #t to *clm-play* #t to *clm-statistics* #t to *clm-verbose* #f to *clm-debug* *snd-home* "/sound/fth-test.snd" $+ to *clm-file-name* *snd-home* "/sound/fth-test.reverb" $+ to *clm-reverb-file-name* #t to *clm-delete-reverb* <'> clm-print-instrument to *clm-notehook* <'> clm-sox-player to *clm-player* *snd-home* add-load-path "BROWSER" getenv "firefox" || set-html-program drop *snd-home* "/sound" $+ set-open-file-dialog-directory ( dir ) "/saved-snd.fs" $+ set-save-state-file drop *snd-home* "/zap" $+ set-save-dir ( dir ) set-temp-dir drop 0.0 set-auto-update-interval drop #t set-trap-segfault drop #( "rev" "reverb" "wave" ) [each] ( ext ) add-sound-file-extension drop [end-each] \ make-default-comment from clm.fs output-comment-hook lambda: <{ str -- s }> str empty? if make-default-comment else str then ; add-hook! require examp [ifundef] read-eval-loop-prompt "ok " value read-eval-loop-prompt [then] 'snd-nogui provided? [if] \ snd-nogui repl and prompt hooks before-repl-hook reset-hook! \ remove default hook before-repl-hook lambda: <{ -- }> "" #f clm-message "Starting session on %s." #( "%a %b %d %r %Z %Y" current-time strftime ) clm-message "" #f clm-message ; add-hook! \ \ Remove duplicates from history file. \ after-repl-hook lambda: <{ history -- }> history readlines array-reverse! { hary } #() "" "" { nhary hline tline } hary array-length 0 ?do hary i array-ref to hline hary i 1+ array-ref to tline nhary hline array-member? unless nhary hline array-unshift ( nhary ) tline array-unshift drop then 2 +loop history nhary writelines \ Be polite. "" #f clm-message "Thank you for using %s!" #( *program-name* string-upcase ) clm-message "" #f clm-message 1 sleep ; add-hook! \ \ A more elaborated prompt for fth and snd-forth-nogui. \ before-prompt-hook lambda: <{ prompt pos -- new-prompt }> "%I:%M%p" current-time strftime string-downcase! { tm } "%%S[%s %s] (%d)%%s %%Bok%%b " #( *short-hostname* tm pos ) string-format ; add-hook! [else] \ snd-motif|gtk read-hook lambda: <{ text -- flag }> \ Prints "\n" to put output at next line. \ This separates better input from output. cr #f ; add-hook! require snd-xm after-open-hook <'> show-disk-space add-hook! require effects #f to use-combo-box-for-fft-size \ boolean (default #f) 'snd-motif provided? [if] *clm-search-list* [each] ( dir ) undef add-directory-to-view-files-list drop [end-each] \ snd-xm.fs add-mark-pane require popup edhist-save-hook lambda: <{ prc -- }> "%S" #( prc ) clm-message ; add-hook! [then] require extensions with-reopen-menu with-buffers-menu \ examp.fs graph-hook <'> auto-dot add-hook! graph-hook <'> zoom-spectrum add-hook! lisp-graph-hook <'> display-energy add-hook! after-transform-hook <'> fft-peak add-hook! \ graph-hook <'> display-correlate add-hook! \ graph-hook <'> superimpose-ffts add-hook! \ lisp-graph-hook <'> display-db add-hook! require mix mix-click-hook <'> mix-click-sets-amp add-hook! mix-click-hook <'> mix-click-info add-hook! require marks save-mark-properties mark-click-hook <'> mark-click-info add-hook! require dsp require env enved-hook lambda: <{ en pt x y reason -- en'|#f }> reason enved-move-point = if x en 0 array-ref f> x en -2 array-ref f< && if en en pt 2* array-ref x #f #f stretch-envelope ( new-en ) dup pt 2* 1+ y array-set! ( new-en ) else #f then else #f then ; add-hook! \ xm-enved.fs (already loaded by effects.fs) before-enved-hook lambda: <{ gen pos x y reason -- f }> enved-hook hook-empty? if #f else gen xenved-envelope@ { res } enved-hook each { prc } prc #( res pos x y reason ) run-proc to res res false? ?leave end-each res array? if gen res xenved-envelope! then res then ; add-hook! after-open-hook lambda: <{ snd -- }> snd channels 0 ?do snd short-file-name snd i ( chn ) time-graph set-x-axis-label drop \ to force a verbose cursor 0 snd i ( chn ) #f set-cursor drop loop cursor-line snd #t set-cursor-style drop channels-combined snd set-channel-style ; add-hook! require rgb blue set-selected-data-color drop beige set-selected-graph-color drop rainbow-colormap set-colormap drop #t set-enved-wave? drop #t set-just-sounds drop \ defined in examp.fs read-eval-loop-prompt set-listener-prompt drop #t set-show-full-duration drop #t set-show-indices drop #t set-show-transform-peaks drop #t set-show-y-zero drop speed-control-as-ratio set-speed-control-style drop \ graph-once \ graph-as-sonogram \ graph-as-spectrogram graph-once set-transform-graph-type drop #t set-with-inset-graph drop #t set-with-pointer-focus drop #t set-with-smpte-label drop #t set-with-toolbar drop #t set-with-tracking-cursor drop #t set-with-verbose-cursor drop 1200 set-window-width drop 150 set-window-x drop 0 set-window-y drop \ The listener appears in a more convenient size with this trick: 800 set-window-height drop 1000 set-window-height drop \ bind-key ( key modifiers func \ :optional extended=#f origin="" prefs-info="" -- val ) \ \ modifiers: \ 0 normal \ 1 shift \ 4 control \ 8 meta \ \ extended (prefix key): \ #t C-x \ #f none \ \ func ( -- val ) \ \ val should be: \ cursor-in-view \ cursor-on-left \ cursor-on-right \ cursor-in-middle \ keyboard-no-action \ \ C-x C-c terminate Snd c 4 lambda: <{ -- val }> 0 snd-exit drop cursor-in-view ; #t "terminate Snd" "terminate-snd" bind-key drop \ C-x k close selected sound k 0 lambda: <{ -- val }> selected-sound close-sound-extend cursor-in-view ; #t "close sound and jump to next open" "close-current-sound" bind-key drop \ C-x C-k toggle listener k 4 lambda: <{ -- val }> show-listener not set-show-listener drop cursor-in-view ; #t "show listener" "show-listener" bind-key drop \ C-x C-x play x 4 lambda: <{ -- val }> #t play drop cursor-in-view ; #t "play current sound" "play-current-sound" bind-key drop \ C-x C-t play from cursor t 4 lambda: <{ -- val }> selected-sound :start undef undef undef cursor play drop cursor-in-view ; #t "play from cursor" "play-from-cursor" bind-key drop "End" 0 lambda: <{ -- val }> selected-sound { snd } snd #f #f framples { frms } snd srate { sr } '( 0.0 frms sr f/ ) snd #f undef set-x-bounds ( val ) ; #f "view full sound" undef bind-key drop m 0 <'> first-mark-in-window-at-left #f "align window left edge with mark" "first-mark-in-window-at-left" bind-key drop [then] \ snd-nogui \ find-file searchs in *clm-search-list* let: sounds empty? if *clm-file-name* find-file { fname } fname if fname open-sound drop then cr then ;let "%s (Fth %s)" #( snd-version fth-version ) clm-message \ Finally, after loading files with possible error messages, redirect \ Fth error output (stderr) to the Snd listener too. *stdout* set-*stderr* drop \ .snd_forth ends here snd-16.1/sndinfo.c0000644000076400007640000000717612474410636012161 0ustar bilbil/* sndinfo describes sounds */ #include "mus-config.h" #include #include #include #ifndef _MSC_VER #include #endif #include #include #include #include "sndlib.h" static char *display_maxamps(const char *filename, int chans) { char *ampstr; char fstr[16]; int i, len; mus_float_t *vals; mus_long_t *times; len = chans * 32; ampstr = (char *)calloc(len, sizeof(char)); vals = (mus_float_t *)calloc(chans, sizeof(mus_float_t)); times = (mus_long_t *)calloc(chans, sizeof(mus_long_t)); snprintf(ampstr, len, "\n max amp%s: ", (chans > 1) ? "s" : ""); mus_sound_maxamps(filename, chans, vals, times); for (i = 0; i < chans; i++) { snprintf(fstr, 16, "%.3f ", vals[i]); strcat(ampstr, fstr); } free(vals); free(times); return(ampstr); } int main(int argc, char *argv[]) { int chans, srate, ctr; mus_sample_t samp_type; mus_header_t type; mus_long_t samples; float length = 0.0; time_t date; int *loops = NULL; char *comment, *header_name; char *samp_type_info = NULL, *samp_type_name, *ampstr = NULL; char timestr[64]; if (argc == 1) {printf("usage: sndinfo file\n"); exit(0);} mus_sound_initialize(); for (ctr = 1; ctr < argc; ctr++) { if (mus_file_probe(argv[ctr])) /* see if it exists */ { date = mus_sound_write_date(argv[ctr]); srate = mus_sound_srate(argv[ctr]); if (srate == MUS_ERROR) { fprintf(stdout, "%s: not a sound file?\n", argv[ctr]); continue; } chans = mus_sound_chans(argv[ctr]); samples = mus_sound_samples(argv[ctr]); comment = mus_sound_comment(argv[ctr]); if ((chans > 0) && (srate > 0)) length = (float)((double)samples / (double)(chans * srate)); loops = mus_sound_loop_info(argv[ctr]); type = mus_sound_header_type(argv[ctr]); header_name = (char *)mus_header_type_name(type); samp_type = mus_sound_sample_type(argv[ctr]); if (samp_type != MUS_UNKNOWN_SAMPLE) samp_type_info = (char *)mus_sample_type_name(samp_type); else { int orig_type; if (samp_type_info == NULL) samp_type_info = (char *)calloc(64, sizeof(char)); orig_type = mus_sound_original_sample_type(argv[ctr]); samp_type_name = (char *)mus_header_original_sample_type_name(orig_type, type); if (samp_type_name) snprintf(samp_type_info, 64, "%d (%s)", orig_type, samp_type_name); else snprintf(samp_type_info, 64, "%d", orig_type); } fprintf(stdout, "%s:\n srate: %d\n chans: %d\n length: %f", argv[ctr], srate, chans, length); if (length < 10.0) { int samps; samps = mus_sound_framples(argv[ctr]); fprintf(stdout, " (%d sample%s)", samps, (samps != 1) ? "s" : ""); } fprintf(stdout, "\n"); fprintf(stdout, " header type: %s\n sample type: %s\n ", header_name, samp_type_info); strftime(timestr, 64, "%a %d-%b-%Y %H:%M %Z", localtime(&date)); fprintf(stdout, "written: %s", timestr); if ((chans > 0) && (mus_sound_maxamp_exists(argv[ctr]))) { ampstr = display_maxamps(argv[ctr], chans); if (ampstr) fprintf(stdout, "%s", ampstr); } fprintf(stdout, "\n"); if (comment) fprintf(stdout, " comment: %s\n", comment); if (loops) { fprintf(stdout, " loop: %d to %d\n", loops[0], loops[1]); if (loops[2] != 0) fprintf(stdout, " loop: %d to %d\n", loops[2], loops[3]); if (loops[0] != 0) fprintf(stdout, " base: %d, detune: %d\n", loops[4], loops[5]); } } else fprintf(stderr, "%s: %s\n", argv[ctr], strerror(errno)); if (ctr < argc - 1) fprintf(stdout, "\n"); } return(0); } snd-16.1/configure0000755000076400007640000063213612626170325012261 0ustar bilbil#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for snd 16.1. # # Report bugs to . # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 as_fn_exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org and $0: bil@ccrma.stanford.edu about your system, including any $0: error possibly output before this message. Then install $0: a modern shell, or manually run the script under such a $0: shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='snd' PACKAGE_TARNAME='ftp://ccrma-ftp.stanford.edu/pub/Lisp/snd-16.tar.gz' PACKAGE_VERSION='16.1' PACKAGE_STRING='snd 16.1' PACKAGE_BUGREPORT='bil@ccrma.stanford.edu' PACKAGE_URL='' ac_unique_file="snd.c" # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='LTLIBOBJS LIBOBJS MAKE_TARGET ORIGINAL_LDFLAGS INSTALL SO_LD SO_FLAGS LDSO_FLAGS JACK_FLAGS JACK_LIBS AUDIO_LIB PATH_WVUNPACK PATH_WAVPACK PATH_TTA PATH_TIMIDITY PATH_FLAC PATH_SPEEXENC PATH_SPEEXDEC PATH_MPG321 PATH_MPG123 PATH_OGGENC PATH_OGGDEC XEN_CFLAGS XEN_LIBS S7_LIB FTH GL_FLAGS GL_FILES GL_LIBS GTK_LD_LIBS GTK_CFLAGS GTK_LIBS GX_HEADERS GX_FILES XFLAGS XLIBS CAIRO_CFLAGS X_EXTRA_LIBS X_LIBS X_PRE_LIBS X_CFLAGS XMKMF GSL_CFLAGS GSL_LIBS GMP_LIBS FFTW_CFLAGS FFTW_LIBS PKG_CONFIG EGREP GREP CPP INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC host_os host_vendor host_cpu host build_os build_vendor build_cpu build target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking with_gtk with_gui with_gl with_gl2ps with_motif with_editres with_alsa with_oss with_jack with_ladspa with_pulseaudio with_portaudio with_extension_language with_s7 with_forth with_ruby with_gsl with_fftw with_gmp with_audio with_temp_dir with_save_dir with_doc_dir enable_deprecated with_x ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP XMKMF' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures snd 16.1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/ftp://ccrma-ftp.stanford.edu/pub/Lisp/snd-16.tar.gz] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF X features: --x-includes=DIR X include files are in DIR --x-libraries=DIR X library files are in DIR System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of snd 16.1:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --disable-deprecated do not include any deprecated stuff from gtk, s7, motif, clm, snd, or sndlib Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-gtk use Gtk+ to build Snd --with-gui make Snd with graphics support --with-gl include OpenGL support, Motif only --with-gl2ps include gl2ps, Motif only --with-motif use libXm to build Snd --with-editres include editres in xm --with-alsa use ALSA --with-oss use OSS --with-jack use JACK --with-ladspa include support for LADSPA plugins, Linux only --with-pulseaudio use PulseAudio, default=no --with-portaudio use portaudio, default=no --with-extension-language use some extension language, default=yes --with-s7 use S7, default=yes --with-forth use Forth as the extension language --with-ruby use Ruby as the extension language --with-gsl use GSL, default=yes --with-fftw use fftw, default=yes --with-gmp include multiprecision arithmetic via gmp, mpfr, and mpc, default=no --without-audio don't include any audio functionality --with-temp-dir directory to use for temp files --with-save-dir directory to use for saved-state files --with-doc-dir directory to search for documentation --with-x use the X Window System Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor XMKMF Path to xmkmf, Makefile generator for X Window System Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to . _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF snd configure 16.1 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_compute_int LINENO EXPR VAR INCLUDES # -------------------------------------------- # Tries to find the compile-time value of EXPR in a program that includes # INCLUDES, setting VAR accordingly. Returns whether the value could be # computed ac_fn_c_compute_int () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if test "$cross_compiling" = yes; then # Depending upon the size, compute the lo and hi bounds. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) >= 0)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_lo=0 ac_mid=0 while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_hi=$ac_mid; break else as_fn_arith $ac_mid + 1 && ac_lo=$as_val if test $ac_lo -le $ac_mid; then ac_lo= ac_hi= break fi as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) < 0)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_hi=-1 ac_mid=-1 while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) >= $ac_mid)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_lo=$ac_mid; break else as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val if test $ac_mid -le $ac_hi; then ac_lo= ac_hi= break fi as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else ac_lo= ac_hi= fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # Binary search between lo and hi bounds. while test "x$ac_lo" != "x$ac_hi"; do as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_hi=$ac_mid else as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done case $ac_lo in #(( ?*) eval "$3=\$ac_lo"; ac_retval=0 ;; '') ac_retval=1 ;; esac else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 static long int longval () { return $2; } static unsigned long int ulongval () { return $2; } #include #include int main () { FILE *f = fopen ("conftest.val", "w"); if (! f) return 1; if (($2) < 0) { long int i = longval (); if (i != ($2)) return 1; fprintf (f, "%ld", i); } else { unsigned long int i = ulongval (); if (i != ($2)) return 1; fprintf (f, "%lu", i); } /* Do not output a trailing newline, as this causes \r\n confusion on some platforms. */ return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : echo >>conftest.val; read $3 &5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by snd $as_me 16.1, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } if ${ac_cv_build+:} false; then : $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } if ${ac_cv_host+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac # needed by case $host below ac_config_headers="$ac_config_headers mus-config.h" ac_config_files="$ac_config_files makefile" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # AC_HEADER_STDC # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if ${ac_cv_path_install+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in #(( ./ | .// | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' MAKE_TARGET="snd" AUDIO_SYSTEM="None" RANDOM_FEATURES="" OPTIONAL_LIBRARIES="" LOCAL_LANGUAGE="None" GRAPHICS_TOOLKIT="None" PACKAGE=Snd VERSION=16.1 #-------------------------------------------------------------------------------- # configuration options # --with-motif use Motif (the default) # --with-gtk use Gtk+ # --with-alsa use ALSA if possible (the default) # --with-oss use OSS # --with-jack use Jack # --without-audio stub out all audio # --with-gmp include multiprecision arithmetic via gmp, mpfr, and mpc # --disable-deprecated do not include any deprecated stuff (in gtk, motif, s7, sndlib, clm, etc) # --with-ladspa include LADSPA plugin support (Linux) # --with-gui make Snd with(out) any graphics support # --with-forth use Forth as the extension language # --with-ruby use Ruby as the extension language # --with-s7 use S7 as the extension language (default = yes) # --with-extension-language use some extension language (default=yes) # --with-temp-dir directory to use for temp files # --with-save-dir directory to use for saved-state files # --with-doc-dir directory to search for documentation # --with-gl include OpenGL support (default=no, Motif only) # --with-gl2ps include gl2ps (Motif only) # --with-editres include EditRes in xm # --without-gsl omit GSL even if it exists # --without-fftw omit FFTW even if it exists # --with-pulseaudio use PulseAudio # --with-portaudio use portaudio # Check whether --with-gtk was given. if test "${with_gtk+set}" = set; then : withval=$with_gtk; fi # Check whether --with-gui was given. if test "${with_gui+set}" = set; then : withval=$with_gui; fi # Check whether --with-gl was given. if test "${with_gl+set}" = set; then : withval=$with_gl; fi # Check whether --with-gl2ps was given. if test "${with_gl2ps+set}" = set; then : withval=$with_gl2ps; fi # Check whether --with-motif was given. if test "${with_motif+set}" = set; then : withval=$with_motif; fi # Check whether --with-editres was given. if test "${with_editres+set}" = set; then : withval=$with_editres; fi # Check whether --with-alsa was given. if test "${with_alsa+set}" = set; then : withval=$with_alsa; fi # Check whether --with-oss was given. if test "${with_oss+set}" = set; then : withval=$with_oss; fi # Check whether --with-jack was given. if test "${with_jack+set}" = set; then : withval=$with_jack; fi # Check whether --with-ladspa was given. if test "${with_ladspa+set}" = set; then : withval=$with_ladspa; fi # Check whether --with-pulseaudio was given. if test "${with_pulseaudio+set}" = set; then : withval=$with_pulseaudio; fi # Check whether --with-portaudio was given. if test "${with_portaudio+set}" = set; then : withval=$with_portaudio; fi # Check whether --with-extension-language was given. if test "${with_extension_language+set}" = set; then : withval=$with_extension_language; fi # Check whether --with-s7 was given. if test "${with_s7+set}" = set; then : withval=$with_s7; fi # Check whether --with-forth was given. if test "${with_forth+set}" = set; then : withval=$with_forth; fi # Check whether --with-ruby was given. if test "${with_ruby+set}" = set; then : withval=$with_ruby; fi # Check whether --with-gsl was given. if test "${with_gsl+set}" = set; then : withval=$with_gsl; fi # Check whether --with-fftw was given. if test "${with_fftw+set}" = set; then : withval=$with_fftw; fi # Check whether --with-gmp was given. if test "${with_gmp+set}" = set; then : withval=$with_gmp; fi # Check whether --with-audio was given. if test "${with_audio+set}" = set; then : withval=$with_audio; fi # Check whether --with-temp-dir was given. if test "${with_temp_dir+set}" = set; then : withval=$with_temp_dir; cat >>confdefs.h <<_ACEOF #define MUS_DEFAULT_TEMP_DIR "${withval}" _ACEOF fi # Check whether --with-save-dir was given. if test "${with_save_dir+set}" = set; then : withval=$with_save_dir; cat >>confdefs.h <<_ACEOF #define MUS_DEFAULT_SAVE_DIR "${withval}" _ACEOF fi # Check whether --with-doc-dir was given. if test "${with_doc_dir+set}" = set; then : withval=$with_doc_dir; cat >>confdefs.h <<_ACEOF #define MUS_DEFAULT_DOC_DIR "${withval}" _ACEOF fi # Check whether --enable-deprecated was given. if test "${enable_deprecated+set}" = set; then : enableval=$enable_deprecated; fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 $as_echo_n "checking whether byte ordering is bigendian... " >&6; } if ${ac_cv_c_bigendian+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_c_bigendian=unknown # See if we're dealing with a universal compiler. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifndef __APPLE_CC__ not a universal capable compiler #endif typedef int dummy; _ACEOF if ac_fn_c_try_compile "$LINENO"; then : # Check for potential -arch flags. It is not universal unless # there are at least two -arch flags with different values. ac_arch= ac_prev= for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do if test -n "$ac_prev"; then case $ac_word in i?86 | x86_64 | ppc | ppc64) if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then ac_arch=$ac_word else ac_cv_c_bigendian=universal break fi ;; esac ac_prev= elif test "x$ac_word" = "x-arch"; then ac_prev=arch fi done fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_c_bigendian = unknown; then # See if sys/param.h defines the BYTE_ORDER macro. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { #if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ && LITTLE_ENDIAN) bogus endian macros #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : # It does; now see whether it defined to BIG_ENDIAN or not. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { #if BYTE_ORDER != BIG_ENDIAN not big endian #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_bigendian=yes else ac_cv_c_bigendian=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $ac_cv_c_bigendian = unknown; then # See if defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { #if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) bogus endian macros #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : # It does; now see whether it defined to _BIG_ENDIAN or not. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { #ifndef _BIG_ENDIAN not big endian #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_bigendian=yes else ac_cv_c_bigendian=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $ac_cv_c_bigendian = unknown; then # Compile a test program. if test "$cross_compiling" = yes; then : # Try to guess by grepping values from an object file. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ short int ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; short int ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; int use_ascii (int i) { return ascii_mm[i] + ascii_ii[i]; } short int ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; short int ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; int use_ebcdic (int i) { return ebcdic_mm[i] + ebcdic_ii[i]; } extern int foo; int main () { return use_ascii (foo) == use_ebcdic (foo); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then ac_cv_c_bigendian=yes fi if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then if test "$ac_cv_c_bigendian" = unknown; then ac_cv_c_bigendian=no else # finding both strings is unlikely to happen, but who knows? ac_cv_c_bigendian=unknown fi fi fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int main () { /* Are we little or big endian? From Harbison&Steele. */ union { long int l; char c[sizeof (long int)]; } u; u.l = 1; return u.c[sizeof (long int) - 1] == 1; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_c_bigendian=no else ac_cv_c_bigendian=yes fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 $as_echo "$ac_cv_c_bigendian" >&6; } case $ac_cv_c_bigendian in #( yes) $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h ;; #( no) ;; #( universal) $as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h ;; #( *) as_fn_error $? "unknown endianness presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; esac # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of void *" >&5 $as_echo_n "checking size of void *... " >&6; } if ${ac_cv_sizeof_void_p+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (void *))" "ac_cv_sizeof_void_p" "$ac_includes_default"; then : else if test "$ac_cv_type_void_p" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (void *) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_void_p=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_void_p" >&5 $as_echo "$ac_cv_sizeof_void_p" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_VOID_P $ac_cv_sizeof_void_p _ACEOF # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_PKG_CONFIG" && ac_cv_path_PKG_CONFIG="no" ;; esac fi PKG_CONFIG=$ac_cv_path_PKG_CONFIG if test -n "$PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 $as_echo "$PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi #-------------------------------------------------------------------------------- # fftw #-------------------------------------------------------------------------------- FFTW_LIBS="" FFTW_CFLAGS="" if test "$with_fftw" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fftw3" >&5 $as_echo_n "checking for fftw3... " >&6; } if test x$PKG_CONFIG != xno ; then if $PKG_CONFIG fftw3 --exists ; then FFTW_LIBS="`$PKG_CONFIG fftw3 --libs`" FFTW_CFLAGS="`$PKG_CONFIG fftw3 --cflags`" $as_echo "#define HAVE_FFTW3 1" >>confdefs.h OPTIONAL_LIBRARIES="$OPTIONAL_LIBRARIES fftw3" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi #-------------------------------------------------------------------------------- # GMP, MPFR, MPC #-------------------------------------------------------------------------------- # no pc files -- deliberately! We'll just add the libraries and let the chips fall... GMP_LIBS="" if test "$with_gmp" = yes ; then GMP_LIBS="-lgmp -lmpfr -lmpc -lm" $as_echo "#define WITH_GMP 1" >>confdefs.h OPTIONAL_LIBRARIES="$OPTIONAL_LIBRARIES gmp mpfr mpc" fi #-------------------------------------------------------------------------------- # GSL #-------------------------------------------------------------------------------- GSL_LIBS="" GSL_CFLAGS="" if test "$with_gsl" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gsl" >&5 $as_echo_n "checking for gsl... " >&6; } if test x$PKG_CONFIG != xno ; then if $PKG_CONFIG gsl --exists ; then GSL_LIBS="`$PKG_CONFIG gsl --libs`" GSL_CFLAGS="`$PKG_CONFIG gsl --cflags`" $as_echo "#define HAVE_GSL 1" >>confdefs.h OPTIONAL_LIBRARIES="$OPTIONAL_LIBRARIES gsl" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi #-------------------------------------------------------------------------------- # Ladspa #-------------------------------------------------------------------------------- if test "$with_ladspa" = yes ; then $as_echo "#define HAVE_LADSPA 1" >>confdefs.h RANDOM_FEATURES="$RANDOM_FEATURES ladspa" fi #-------------------------------------------------------------------------------- # graphics #-------------------------------------------------------------------------------- # graphics: motif chosen if --with-motif # no gui chosen if --without-gui # gtk chosen if neither of above and we can find gtk-2.0.pc or gtk-3.0.pc # else no gui XLIBS="" XFLAGS="" GX_FILES="" GX_HEADERS="" GTK_FILES="" GTK_HEADERS="" GTK_CFLAGS="" GTK_LIBS="" GTK_LD_LIBS="" ac_snd_gui_choice=none if test "$with_motif" = no && test "$with_gtk" = no ; then with_gui=no fi if test "$with_gui" = no ; then $as_echo "#define USE_NO_GUI 1" >>confdefs.h GX_FILES="NO_GUI_O_FILES" GX_HEADERS="NO_GUI_HEADERS" ac_snd_gui_choice=no fi #-------------------------------------------------------------------------------- # X/Motif #-------------------------------------------------------------------------------- # here as in the gmp case, we simply set up the libs/flags and hope for the best if test "$with_motif" = yes ; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for X" >&5 $as_echo_n "checking for X... " >&6; } # Check whether --with-x was given. if test "${with_x+set}" = set; then : withval=$with_x; fi # $have_x is `yes', `no', `disabled', or empty when we do not yet know. if test "x$with_x" = xno; then # The user explicitly disabled X. have_x=disabled else case $x_includes,$x_libraries in #( *\'*) as_fn_error $? "cannot use X directory names containing '" "$LINENO" 5;; #( *,NONE | NONE,*) if ${ac_cv_have_x+:} false; then : $as_echo_n "(cached) " >&6 else # One or both of the vars are not set, and there is no cached value. ac_x_includes=no ac_x_libraries=no rm -f -r conftest.dir if mkdir conftest.dir; then cd conftest.dir cat >Imakefile <<'_ACEOF' incroot: @echo incroot='${INCROOT}' usrlibdir: @echo usrlibdir='${USRLIBDIR}' libdir: @echo libdir='${LIBDIR}' _ACEOF if (export CC; ${XMKMF-xmkmf}) >/dev/null 2>/dev/null && test -f Makefile; then # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. for ac_var in incroot usrlibdir libdir; do eval "ac_im_$ac_var=\`\${MAKE-make} $ac_var 2>/dev/null | sed -n 's/^$ac_var=//p'\`" done # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR. for ac_extension in a so sl dylib la dll; do if test ! -f "$ac_im_usrlibdir/libX11.$ac_extension" && test -f "$ac_im_libdir/libX11.$ac_extension"; then ac_im_usrlibdir=$ac_im_libdir; break fi done # Screen out bogus values from the imake configuration. They are # bogus both because they are the default anyway, and because # using them would break gcc on systems where it needs fixed includes. case $ac_im_incroot in /usr/include) ac_x_includes= ;; *) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes=$ac_im_incroot;; esac case $ac_im_usrlibdir in /usr/lib | /usr/lib64 | /lib | /lib64) ;; *) test -d "$ac_im_usrlibdir" && ac_x_libraries=$ac_im_usrlibdir ;; esac fi cd .. rm -f -r conftest.dir fi # Standard set of common directories for X headers. # Check X11 before X11Rn because it is often a symlink to the current release. ac_x_header_dirs=' /usr/X11/include /usr/X11R7/include /usr/X11R6/include /usr/X11R5/include /usr/X11R4/include /usr/include/X11 /usr/include/X11R7 /usr/include/X11R6 /usr/include/X11R5 /usr/include/X11R4 /usr/local/X11/include /usr/local/X11R7/include /usr/local/X11R6/include /usr/local/X11R5/include /usr/local/X11R4/include /usr/local/include/X11 /usr/local/include/X11R7 /usr/local/include/X11R6 /usr/local/include/X11R5 /usr/local/include/X11R4 /usr/X386/include /usr/x386/include /usr/XFree86/include/X11 /usr/include /usr/local/include /usr/unsupported/include /usr/athena/include /usr/local/x11r5/include /usr/lpp/Xamples/include /usr/openwin/include /usr/openwin/share/include' if test "$ac_x_includes" = no; then # Guess where to find include files, by looking for Xlib.h. # First, try using that file with no special directory specified. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # We can compile using X headers with no special include directory. ac_x_includes= else for ac_dir in $ac_x_header_dirs; do if test -r "$ac_dir/X11/Xlib.h"; then ac_x_includes=$ac_dir break fi done fi rm -f conftest.err conftest.i conftest.$ac_ext fi # $ac_x_includes = no if test "$ac_x_libraries" = no; then # Check for the libraries. # See if we find them without any special options. # Don't add to $LIBS permanently. ac_save_LIBS=$LIBS LIBS="-lX11 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { XrmInitialize () ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : LIBS=$ac_save_LIBS # We can link X programs with no special library path. ac_x_libraries= else LIBS=$ac_save_LIBS for ac_dir in `$as_echo "$ac_x_includes $ac_x_header_dirs" | sed s/include/lib/g` do # Don't even attempt the hair of trying to link an X program! for ac_extension in a so sl dylib la dll; do if test -r "$ac_dir/libX11.$ac_extension"; then ac_x_libraries=$ac_dir break 2 fi done done fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi # $ac_x_libraries = no case $ac_x_includes,$ac_x_libraries in #( no,* | *,no | *\'*) # Didn't find X, or a directory has "'" in its name. ac_cv_have_x="have_x=no";; #( *) # Record where we found X for the cache. ac_cv_have_x="have_x=yes\ ac_x_includes='$ac_x_includes'\ ac_x_libraries='$ac_x_libraries'" esac fi ;; #( *) have_x=yes;; esac eval "$ac_cv_have_x" fi # $with_x != no if test "$have_x" != yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_x" >&5 $as_echo "$have_x" >&6; } no_x=yes else # If each of the values was on the command line, it overrides each guess. test "x$x_includes" = xNONE && x_includes=$ac_x_includes test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries # Update the cache value to reflect the command line values. ac_cv_have_x="have_x=yes\ ac_x_includes='$x_includes'\ ac_x_libraries='$x_libraries'" { $as_echo "$as_me:${as_lineno-$LINENO}: result: libraries $x_libraries, headers $x_includes" >&5 $as_echo "libraries $x_libraries, headers $x_includes" >&6; } fi if test "$no_x" = yes; then # Not all programs may use this symbol, but it does not hurt to define it. $as_echo "#define X_DISPLAY_MISSING 1" >>confdefs.h X_CFLAGS= X_PRE_LIBS= X_LIBS= X_EXTRA_LIBS= else if test -n "$x_includes"; then X_CFLAGS="$X_CFLAGS -I$x_includes" fi # It would also be nice to do this for all -L options, not just this one. if test -n "$x_libraries"; then X_LIBS="$X_LIBS -L$x_libraries" # For Solaris; some versions of Sun CC require a space after -R and # others require no space. Words are not sufficient . . . . { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -R must be followed by a space" >&5 $as_echo_n "checking whether -R must be followed by a space... " >&6; } ac_xsave_LIBS=$LIBS; LIBS="$LIBS -R$x_libraries" ac_xsave_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } X_LIBS="$X_LIBS -R$x_libraries" else LIBS="$ac_xsave_LIBS -R $x_libraries" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } X_LIBS="$X_LIBS -R $x_libraries" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: neither works" >&5 $as_echo "neither works" >&6; } fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext ac_c_werror_flag=$ac_xsave_c_werror_flag LIBS=$ac_xsave_LIBS fi # Check for system-dependent libraries X programs must link with. # Do this before checking for the system-independent R6 libraries # (-lICE), since we may need -lsocket or whatever for X linking. if test "$ISC" = yes; then X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl_s -linet" else # Martyn Johnson says this is needed for Ultrix, if the X # libraries were built with DECnet support. And Karl Berry says # the Alpha needs dnet_stub (dnet does not exist). ac_xsave_LIBS="$LIBS"; LIBS="$LIBS $X_LIBS -lX11" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char XOpenDisplay (); int main () { return XOpenDisplay (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dnet_ntoa in -ldnet" >&5 $as_echo_n "checking for dnet_ntoa in -ldnet... " >&6; } if ${ac_cv_lib_dnet_dnet_ntoa+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldnet $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dnet_ntoa (); int main () { return dnet_ntoa (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dnet_dnet_ntoa=yes else ac_cv_lib_dnet_dnet_ntoa=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dnet_dnet_ntoa" >&5 $as_echo "$ac_cv_lib_dnet_dnet_ntoa" >&6; } if test "x$ac_cv_lib_dnet_dnet_ntoa" = xyes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet" fi if test $ac_cv_lib_dnet_dnet_ntoa = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dnet_ntoa in -ldnet_stub" >&5 $as_echo_n "checking for dnet_ntoa in -ldnet_stub... " >&6; } if ${ac_cv_lib_dnet_stub_dnet_ntoa+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldnet_stub $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dnet_ntoa (); int main () { return dnet_ntoa (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dnet_stub_dnet_ntoa=yes else ac_cv_lib_dnet_stub_dnet_ntoa=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dnet_stub_dnet_ntoa" >&5 $as_echo "$ac_cv_lib_dnet_stub_dnet_ntoa" >&6; } if test "x$ac_cv_lib_dnet_stub_dnet_ntoa" = xyes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub" fi fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS="$ac_xsave_LIBS" # msh@cis.ufl.edu says -lnsl (and -lsocket) are needed for his 386/AT, # to get the SysV transport functions. # Chad R. Larson says the Pyramis MIS-ES running DC/OSx (SVR4) # needs -lnsl. # The nsl library prevents programs from opening the X display # on Irix 5.2, according to T.E. Dickey. # The functions gethostbyname, getservbyname, and inet_addr are # in -lbsd on LynxOS 3.0.1/i386, according to Lars Hecking. ac_fn_c_check_func "$LINENO" "gethostbyname" "ac_cv_func_gethostbyname" if test "x$ac_cv_func_gethostbyname" = xyes; then : fi if test $ac_cv_func_gethostbyname = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lnsl" >&5 $as_echo_n "checking for gethostbyname in -lnsl... " >&6; } if ${ac_cv_lib_nsl_gethostbyname+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnsl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char gethostbyname (); int main () { return gethostbyname (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_nsl_gethostbyname=yes else ac_cv_lib_nsl_gethostbyname=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_gethostbyname" >&5 $as_echo "$ac_cv_lib_nsl_gethostbyname" >&6; } if test "x$ac_cv_lib_nsl_gethostbyname" = xyes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl" fi if test $ac_cv_lib_nsl_gethostbyname = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lbsd" >&5 $as_echo_n "checking for gethostbyname in -lbsd... " >&6; } if ${ac_cv_lib_bsd_gethostbyname+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lbsd $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char gethostbyname (); int main () { return gethostbyname (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_bsd_gethostbyname=yes else ac_cv_lib_bsd_gethostbyname=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bsd_gethostbyname" >&5 $as_echo "$ac_cv_lib_bsd_gethostbyname" >&6; } if test "x$ac_cv_lib_bsd_gethostbyname" = xyes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -lbsd" fi fi fi # lieder@skyler.mavd.honeywell.com says without -lsocket, # socket/setsockopt and other routines are undefined under SCO ODT # 2.0. But -lsocket is broken on IRIX 5.2 (and is not necessary # on later versions), says Simon Leinen: it contains gethostby* # variants that don't use the name server (or something). -lsocket # must be given before -lnsl if both are needed. We assume that # if connect needs -lnsl, so does gethostbyname. ac_fn_c_check_func "$LINENO" "connect" "ac_cv_func_connect" if test "x$ac_cv_func_connect" = xyes; then : fi if test $ac_cv_func_connect = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for connect in -lsocket" >&5 $as_echo_n "checking for connect in -lsocket... " >&6; } if ${ac_cv_lib_socket_connect+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsocket $X_EXTRA_LIBS $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char connect (); int main () { return connect (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_socket_connect=yes else ac_cv_lib_socket_connect=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_connect" >&5 $as_echo "$ac_cv_lib_socket_connect" >&6; } if test "x$ac_cv_lib_socket_connect" = xyes; then : X_EXTRA_LIBS="-lsocket $X_EXTRA_LIBS" fi fi # Guillermo Gomez says -lposix is necessary on A/UX. ac_fn_c_check_func "$LINENO" "remove" "ac_cv_func_remove" if test "x$ac_cv_func_remove" = xyes; then : fi if test $ac_cv_func_remove = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for remove in -lposix" >&5 $as_echo_n "checking for remove in -lposix... " >&6; } if ${ac_cv_lib_posix_remove+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lposix $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char remove (); int main () { return remove (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_posix_remove=yes else ac_cv_lib_posix_remove=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_posix_remove" >&5 $as_echo "$ac_cv_lib_posix_remove" >&6; } if test "x$ac_cv_lib_posix_remove" = xyes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -lposix" fi fi # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay. ac_fn_c_check_func "$LINENO" "shmat" "ac_cv_func_shmat" if test "x$ac_cv_func_shmat" = xyes; then : fi if test $ac_cv_func_shmat = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shmat in -lipc" >&5 $as_echo_n "checking for shmat in -lipc... " >&6; } if ${ac_cv_lib_ipc_shmat+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lipc $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char shmat (); int main () { return shmat (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_ipc_shmat=yes else ac_cv_lib_ipc_shmat=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ipc_shmat" >&5 $as_echo "$ac_cv_lib_ipc_shmat" >&6; } if test "x$ac_cv_lib_ipc_shmat" = xyes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -lipc" fi fi fi # Check for libraries that X11R6 Xt/Xaw programs need. ac_save_LDFLAGS=$LDFLAGS test -n "$x_libraries" && LDFLAGS="$LDFLAGS -L$x_libraries" # SM needs ICE to (dynamically) link under SunOS 4.x (so we have to # check for ICE first), but we must link in the order -lSM -lICE or # we get undefined symbols. So assume we have SM if we have ICE. # These have to be linked with before -lX11, unlike the other # libraries we check for below, so use a different variable. # John Interrante, Karl Berry { $as_echo "$as_me:${as_lineno-$LINENO}: checking for IceConnectionNumber in -lICE" >&5 $as_echo_n "checking for IceConnectionNumber in -lICE... " >&6; } if ${ac_cv_lib_ICE_IceConnectionNumber+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lICE $X_EXTRA_LIBS $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char IceConnectionNumber (); int main () { return IceConnectionNumber (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_ICE_IceConnectionNumber=yes else ac_cv_lib_ICE_IceConnectionNumber=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ICE_IceConnectionNumber" >&5 $as_echo "$ac_cv_lib_ICE_IceConnectionNumber" >&6; } if test "x$ac_cv_lib_ICE_IceConnectionNumber" = xyes; then : X_PRE_LIBS="$X_PRE_LIBS -lSM -lICE" fi LDFLAGS=$ac_save_LDFLAGS fi GTK_FLAGS="$X_CFLAGS" X_POST_LIBS="-lX11 $X_EXTRA_LIBS -lXext" case "$host" in *-apple-*) X_POST_LIBS="$X_POST_LIBS -lSM -lICE" ;; *-*-linux*) X_POST_LIBS="$X_POST_LIBS -lSM -lICE -lXft" ;; esac X_PRE_LIBS="$X_LIBS $X_PRE_LIBS -lXm -lXt" GX_FILES="MOTIF_O_FILES" GX_HEADERS="SND_X_HEADERS" if test "$with_editres" = yes ; then $as_echo "#define WITH_EDITRES 1" >>confdefs.h OPTIONAL_LIBRARIES="$OPTIONAL_LIBRARIES editres" X_PRE_LIBS="$X_PRE_LIBS -lXmu" fi GTK_LIBS="$X_PRE_LIBS $X_POST_LIBS -lXpm" $as_echo "#define USE_MOTIF 1" >>confdefs.h GRAPHICS_TOOLKIT="Motif" ac_snd_gui_choice=Motif fi #-------------------------------------------------------------------------------- # Gtk #-------------------------------------------------------------------------------- if test "$ac_snd_gui_choice" = none ; then if test x$PKG_CONFIG != xno ; then if $PKG_CONFIG gtk+-3.0 --exists ; then GTK_CFLAGS="`$PKG_CONFIG gtk+-3.0 --cflags`" GTK_LIBS="`$PKG_CONFIG gtk+-3.0 --libs`" GTK_LD_LIBS="`$PKG_CONFIG gtk+-3.0 --libs-only-L` `$PKG_CONFIG gtk+-3.0 --libs-only-l`" ac_snd_gui_choice=gtk else if $PKG_CONFIG gtk+-2.0 --exists ; then GTK_CFLAGS="`$PKG_CONFIG gtk+-2.0 --cflags`" GTK_LIBS="`$PKG_CONFIG gtk+-2.0 --libs`" GTK_LD_LIBS="`$PKG_CONFIG gtk+-2.0 --libs-only-L` `$PKG_CONFIG gtk+-2.0 --libs-only-l`" ac_snd_gui_choice=gtk fi fi fi if test "$ac_snd_gui_choice" = gtk ; then GX_FILES="GTK_O_FILES" GX_HEADERS="SND_G_HEADERS" $as_echo "#define USE_GTK 1" >>confdefs.h GRAPHICS_TOOLKIT="Gtk" if test x$PKG_CONFIG != xno ; then CAIRO_CFLAGS="`$PKG_CONFIG cairo --cflags-only-I`" fi fi fi if test "$ac_snd_gui_choice" = none ; then $as_echo "#define USE_NO_GUI 1" >>confdefs.h GX_FILES="NO_GUI_O_FILES" GX_HEADERS="NO_GUI_HEADERS" fi # fallback on no-gui if test "$with_gui" = no ; then $as_echo "#define USE_NO_GUI 1" >>confdefs.h GX_FILES="NO_GUI_O_FILES" GX_HEADERS="NO_GUI_HEADERS" ac_snd_gui_choice=no fi #-------------------------------------------------------------------------------- # OpenGL #-------------------------------------------------------------------------------- GL_LIBS="" GL_FILES="" GL_FLAGS="" if test "$with_gl" = yes ; then if test x$PKG_CONFIG != xno ; then if $PKG_CONFIG gl --exists ; then GL_CFLAGS="`$PKG_CONFIG gl --cflags`" GL_LIBS="`$PKG_CONFIG gl --libs`" GL_FILES="gl.o" $as_echo "#define HAVE_GL 1" >>confdefs.h OPTIONAL_LIBRARIES="$OPTIONAL_LIBRARIES openGL" if $PKG_CONFIG glu --exists ; then $as_echo "#define HAVE_GLU 1" >>confdefs.h GL_CFLAGS="$GL_CFLAGS `$PKG_CONFIG glu --cflags`" GL_LIBS="$GL_LIBS `$PKG_CONFIG glu --libs`" fi if test "$with_gl2ps" = yes ; then $as_echo "#define WITH_GL2PS 1" >>confdefs.h RANDOM_FEATURES="$RANDOM_FEATURES gl2ps" GL_FILES="$GL_FILES gl2ps.o" fi fi fi fi #-------------------------------------------------------------------------------- # language #-------------------------------------------------------------------------------- # language choice: ruby if --with-ruby and we can find a ruby pc file # forth if --with-forth # none if --without-extension-language # s7 otherwise XEN_LIBS="" XEN_CFLAGS="" ac_snd_extension_language=none if test "$with_extension_language" = no ; then ac_snd_extension_language=no LOCAL_LANGUAGE="None" fi #-------------------------------------------------------------------------------- # Ruby #-------------------------------------------------------------------------------- if test "$with_ruby" = yes ; then if test x$PKG_CONFIG != xno ; then if test "$ac_snd_extension_language" = none ; then if $PKG_CONFIG ruby-2.2 --exists ; then $as_echo "#define HAVE_RUBY 1" >>confdefs.h XEN_CFLAGS="`$PKG_CONFIG ruby-2.2 --cflags`" # this depends on building ruby itself with the --enable-shared flag XEN_LIBS="`$PKG_CONFIG ruby-2.2 --libs`" LOCAL_LANGUAGE="Ruby" ac_snd_extension_language=Ruby fi fi if test "$ac_snd_extension_language" = none ; then if $PKG_CONFIG ruby-2.1 --exists ; then $as_echo "#define HAVE_RUBY 1" >>confdefs.h XEN_CFLAGS="`$PKG_CONFIG ruby-2.1 --cflags`" # this depends on building ruby itself with the --enable-shared flag XEN_LIBS="`$PKG_CONFIG ruby-2.1 --libs`" LOCAL_LANGUAGE="Ruby" ac_snd_extension_language=Ruby fi fi if test "$ac_snd_extension_language" = none ; then if $PKG_CONFIG ruby-2.0 --exists ; then $as_echo "#define HAVE_RUBY 1" >>confdefs.h XEN_CFLAGS="`$PKG_CONFIG ruby-2.0 --cflags`" # this depends on building ruby itself with the --enable-shared flag XEN_LIBS="`$PKG_CONFIG ruby-2.0 --libs`" LOCAL_LANGUAGE="Ruby" ac_snd_extension_language=Ruby fi fi if test "$ac_snd_extension_language" = none ; then if $PKG_CONFIG ruby --exists ; then $as_echo "#define HAVE_RUBY 1" >>confdefs.h XEN_CFLAGS="`$PKG_CONFIG ruby --cflags`" # this depends on building ruby itself with the --enable-shared flag XEN_LIBS="`$PKG_CONFIG ruby --libs`" LOCAL_LANGUAGE="Ruby" ac_snd_extension_language=Ruby fi fi if test "$ac_snd_extension_language" = none ; then if $PKG_CONFIG ruby-1.9.3 --exists ; then $as_echo "#define HAVE_RUBY 1" >>confdefs.h XEN_CFLAGS="`$PKG_CONFIG ruby-1.9.3 --cflags`" # this depends on building ruby itself with the --enable-shared flag XEN_LIBS="`$PKG_CONFIG ruby-1.9.3 --libs`" LOCAL_LANGUAGE="Ruby" ac_snd_extension_language=Ruby fi fi if test "$ac_snd_extension_language" = none ; then if $PKG_CONFIG ruby-1.9 --exists ; then $as_echo "#define HAVE_RUBY 1" >>confdefs.h XEN_CFLAGS="`$PKG_CONFIG ruby-1.9 --cflags`" # this depends on building ruby itself with the --enable-shared flag XEN_LIBS="`$PKG_CONFIG ruby-1.9 --libs`" LOCAL_LANGUAGE="Ruby" ac_snd_extension_language=Ruby fi fi if test "$ac_snd_extension_language" = none ; then if $PKG_CONFIG ruby-1.8 --exists ; then $as_echo "#define HAVE_RUBY 1" >>confdefs.h XEN_CFLAGS="`$PKG_CONFIG ruby-1.8 --cflags`" # this depends on building ruby itself with the --enable-shared flag XEN_LIBS="`$PKG_CONFIG ruby-1.8 --libs`" LOCAL_LANGUAGE="Ruby" ac_snd_extension_language=Ruby fi fi fi fi #-------------------------------------------------------------------------------- # Forth #-------------------------------------------------------------------------------- if test "$with_forth" = yes ; then # Extract the first word of "fth", so it can be a program name with args. set dummy fth; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_FTH+:} false; then : $as_echo_n "(cached) " >&6 else case $FTH in [\\/]* | ?:[\\/]*) ac_cv_path_FTH="$FTH" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_FTH="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_FTH" && ac_cv_path_FTH="no" ;; esac fi FTH=$ac_cv_path_FTH if test -n "$FTH"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $FTH" >&5 $as_echo "$FTH" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Forth" >&5 $as_echo_n "checking for Forth... " >&6; } if test "${FTH}" != no ; then XEN_CFLAGS=`${FTH} --no-init-file --eval .cflags` XEN_LIBS=`${FTH} --no-init-file --eval .libs` { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define HAVE_FORTH 1" >>confdefs.h LOCAL_LANGUAGE="Forth" ac_snd_extension_language=Forth else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi #-------------------------------------------------------------------------------- # s7 (the default) #-------------------------------------------------------------------------------- if test "$with_s7" != no && test "$ac_snd_extension_language" = none ; then $as_echo "#define HAVE_SCHEME 1" >>confdefs.h ac_snd_extension_language=s7 LOCAL_LANGUAGE="s7" S7_LIB="s7.o" fi #-------------------------------------------------------------------------------- # OGG, Flac, Speex, Mpeg, Timidity, TTA, Wavpack # -------------------------------------------------------------------------------- # Extract the first word of "oggdec", so it can be a program name with args. set dummy oggdec; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PATH_OGGDEC+:} false; then : $as_echo_n "(cached) " >&6 else case $PATH_OGGDEC in [\\/]* | ?:[\\/]*) ac_cv_path_PATH_OGGDEC="$PATH_OGGDEC" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PATH_OGGDEC="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_PATH_OGGDEC" && ac_cv_path_PATH_OGGDEC="no" ;; esac fi PATH_OGGDEC=$ac_cv_path_PATH_OGGDEC if test -n "$PATH_OGGDEC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PATH_OGGDEC" >&5 $as_echo "$PATH_OGGDEC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # OGG read # Extract the first word of "oggenc", so it can be a program name with args. set dummy oggenc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PATH_OGGENC+:} false; then : $as_echo_n "(cached) " >&6 else case $PATH_OGGENC in [\\/]* | ?:[\\/]*) ac_cv_path_PATH_OGGENC="$PATH_OGGENC" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PATH_OGGENC="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_PATH_OGGENC" && ac_cv_path_PATH_OGGENC="no" ;; esac fi PATH_OGGENC=$ac_cv_path_PATH_OGGENC if test -n "$PATH_OGGENC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PATH_OGGENC" >&5 $as_echo "$PATH_OGGENC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # OGG write if test "$PATH_OGGDEC" != "no" ; then if test "$PATH_OGGENC" != "no" ; then $as_echo "#define HAVE_OGG 1" >>confdefs.h cat >>confdefs.h <<_ACEOF #define PATH_OGGDEC "${PATH_OGGDEC}" _ACEOF cat >>confdefs.h <<_ACEOF #define PATH_OGGENC "${PATH_OGGENC}" _ACEOF fi fi # Extract the first word of "mpg123", so it can be a program name with args. set dummy mpg123; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PATH_MPG123+:} false; then : $as_echo_n "(cached) " >&6 else case $PATH_MPG123 in [\\/]* | ?:[\\/]*) ac_cv_path_PATH_MPG123="$PATH_MPG123" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PATH_MPG123="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_PATH_MPG123" && ac_cv_path_PATH_MPG123="no" ;; esac fi PATH_MPG123=$ac_cv_path_PATH_MPG123 if test -n "$PATH_MPG123"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PATH_MPG123" >&5 $as_echo "$PATH_MPG123" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # MPEG read/write? if test "$PATH_MPG123" != "no" ; then $as_echo "#define HAVE_MPEG 1" >>confdefs.h cat >>confdefs.h <<_ACEOF #define PATH_MPG123 "${PATH_MPG123}" _ACEOF fi # Extract the first word of "mpg321", so it can be a program name with args. set dummy mpg321; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PATH_MPG321+:} false; then : $as_echo_n "(cached) " >&6 else case $PATH_MPG321 in [\\/]* | ?:[\\/]*) ac_cv_path_PATH_MPG321="$PATH_MPG321" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PATH_MPG321="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_PATH_MPG321" && ac_cv_path_PATH_MPG321="no" ;; esac fi PATH_MPG321=$ac_cv_path_PATH_MPG321 if test -n "$PATH_MPG321"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PATH_MPG321" >&5 $as_echo "$PATH_MPG321" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # MPEG read/write? if test "$PATH_MPG321" != "no" ; then $as_echo "#define HAVE_MPEG 1" >>confdefs.h $as_echo "#define HAVE_MPG321 1" >>confdefs.h cat >>confdefs.h <<_ACEOF #define PATH_MPG321 "${PATH_MPG321}" _ACEOF fi # Extract the first word of "speexdec", so it can be a program name with args. set dummy speexdec; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PATH_SPEEXDEC+:} false; then : $as_echo_n "(cached) " >&6 else case $PATH_SPEEXDEC in [\\/]* | ?:[\\/]*) ac_cv_path_PATH_SPEEXDEC="$PATH_SPEEXDEC" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PATH_SPEEXDEC="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_PATH_SPEEXDEC" && ac_cv_path_PATH_SPEEXDEC="no" ;; esac fi PATH_SPEEXDEC=$ac_cv_path_PATH_SPEEXDEC if test -n "$PATH_SPEEXDEC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PATH_SPEEXDEC" >&5 $as_echo "$PATH_SPEEXDEC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Speex read # Extract the first word of "speexenc", so it can be a program name with args. set dummy speexenc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PATH_SPEEXENC+:} false; then : $as_echo_n "(cached) " >&6 else case $PATH_SPEEXENC in [\\/]* | ?:[\\/]*) ac_cv_path_PATH_SPEEXENC="$PATH_SPEEXENC" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PATH_SPEEXENC="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_PATH_SPEEXENC" && ac_cv_path_PATH_SPEEXENC="no" ;; esac fi PATH_SPEEXENC=$ac_cv_path_PATH_SPEEXENC if test -n "$PATH_SPEEXENC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PATH_SPEEXENC" >&5 $as_echo "$PATH_SPEEXENC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Speex write if test "$PATH_SPEEXDEC" != "no" ; then if test "$PATH_SPEEXENC" != "no" ; then $as_echo "#define HAVE_SPEEX 1" >>confdefs.h cat >>confdefs.h <<_ACEOF #define PATH_SPEEXDEC "${PATH_SPEEXDEC}" _ACEOF cat >>confdefs.h <<_ACEOF #define PATH_SPEEXENC "${PATH_SPEEXENC}" _ACEOF fi fi # Extract the first word of "flac", so it can be a program name with args. set dummy flac; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PATH_FLAC+:} false; then : $as_echo_n "(cached) " >&6 else case $PATH_FLAC in [\\/]* | ?:[\\/]*) ac_cv_path_PATH_FLAC="$PATH_FLAC" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PATH_FLAC="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_PATH_FLAC" && ac_cv_path_PATH_FLAC="no" ;; esac fi PATH_FLAC=$ac_cv_path_PATH_FLAC if test -n "$PATH_FLAC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PATH_FLAC" >&5 $as_echo "$PATH_FLAC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Flac read/write if test "$PATH_FLAC" != "no" ; then $as_echo "#define HAVE_FLAC 1" >>confdefs.h cat >>confdefs.h <<_ACEOF #define PATH_FLAC "${PATH_FLAC}" _ACEOF fi # Extract the first word of "timidity", so it can be a program name with args. set dummy timidity; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PATH_TIMIDITY+:} false; then : $as_echo_n "(cached) " >&6 else case $PATH_TIMIDITY in [\\/]* | ?:[\\/]*) ac_cv_path_PATH_TIMIDITY="$PATH_TIMIDITY" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PATH_TIMIDITY="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_PATH_TIMIDITY" && ac_cv_path_PATH_TIMIDITY="no" ;; esac fi PATH_TIMIDITY=$ac_cv_path_PATH_TIMIDITY if test -n "$PATH_TIMIDITY"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PATH_TIMIDITY" >&5 $as_echo "$PATH_TIMIDITY" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Timidity for .mid -> .wav if test "$PATH_TIMIDITY" != "no" ; then $as_echo "#define HAVE_TIMIDITY 1" >>confdefs.h cat >>confdefs.h <<_ACEOF #define PATH_TIMIDITY "${PATH_TIMIDITY}" _ACEOF fi # Extract the first word of "ttaenc", so it can be a program name with args. set dummy ttaenc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PATH_TTA+:} false; then : $as_echo_n "(cached) " >&6 else case $PATH_TTA in [\\/]* | ?:[\\/]*) ac_cv_path_PATH_TTA="$PATH_TTA" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PATH_TTA="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_PATH_TTA" && ac_cv_path_PATH_TTA="no" ;; esac fi PATH_TTA=$ac_cv_path_PATH_TTA if test -n "$PATH_TTA"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PATH_TTA" >&5 $as_echo "$PATH_TTA" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$PATH_TTA" != "no" ; then $as_echo "#define HAVE_TTA 1" >>confdefs.h cat >>confdefs.h <<_ACEOF #define PATH_TTA "${PATH_TTA}" _ACEOF fi # Extract the first word of "wavpack", so it can be a program name with args. set dummy wavpack; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PATH_WAVPACK+:} false; then : $as_echo_n "(cached) " >&6 else case $PATH_WAVPACK in [\\/]* | ?:[\\/]*) ac_cv_path_PATH_WAVPACK="$PATH_WAVPACK" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PATH_WAVPACK="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_PATH_WAVPACK" && ac_cv_path_PATH_WAVPACK="no" ;; esac fi PATH_WAVPACK=$ac_cv_path_PATH_WAVPACK if test -n "$PATH_WAVPACK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PATH_WAVPACK" >&5 $as_echo "$PATH_WAVPACK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "wvunpack", so it can be a program name with args. set dummy wvunpack; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PATH_WVUNPACK+:} false; then : $as_echo_n "(cached) " >&6 else case $PATH_WVUNPACK in [\\/]* | ?:[\\/]*) ac_cv_path_PATH_WVUNPACK="$PATH_WVUNPACK" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PATH_WVUNPACK="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_PATH_WVUNPACK" && ac_cv_path_PATH_WVUNPACK="no" ;; esac fi PATH_WVUNPACK=$ac_cv_path_PATH_WVUNPACK if test -n "$PATH_WVUNPACK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PATH_WVUNPACK" >&5 $as_echo "$PATH_WVUNPACK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$PATH_WAVPACK" != "no" ; then if test "$PATH_WVUNPACK" != "no" ; then $as_echo "#define HAVE_WAVPACK 1" >>confdefs.h cat >>confdefs.h <<_ACEOF #define PATH_WAVPACK "${PATH_WAVPACK}" _ACEOF cat >>confdefs.h <<_ACEOF #define PATH_WVUNPACK "${PATH_WVUNPACK}" _ACEOF fi fi #-------------------------------------------------------------------------------- # Audio #-------------------------------------------------------------------------------- AUDIO_LIB="" JACK_LIBS="" JACK_FLAGS="" if test "$with_audio" != no ; then if test "$with_pulseaudio" = yes ; then $as_echo "#define MUS_PULSEAUDIO 1" >>confdefs.h AUDIO_LIB="-lpulse-simple" AUDIO_SYSTEM=pulseaudio fi if test "$with_portaudio" = yes ; then $as_echo "#define MUS_PORTAUDIO 1" >>confdefs.h AUDIO_SYSTEM=portaudio AUDIO_LIB="-lportaudio" fi if test "$with_jack" = yes ; then if test "$with_alsa" = yes ; then AUDIO_SYSTEM=ALSA+JACK else AUDIO_SYSTEM=JACK fi $as_echo "#define MUS_JACK 1" >>confdefs.h if test x$PKG_CONFIG != xno ; then if $PKG_CONFIG jack --exists ; then JACK_LIBS="`$PKG_CONFIG jack --libs`" JACK_FLAGS="`$PKG_CONFIG jack --cflags`" if $PKG_CONFIG samplerate --exists ; then JACK_LIBS="$JACK_LIBS `$PKG_CONFIG samplerate --libs`" JACK_FLAGS="$JACK_FLAGS `$PKG_CONFIG samplerate --cflags`" else JACK_LIBS="$JACK_LIBS -lsamplerate" fi else JACK_LIBS="-ljack -lsamplerate" fi else JACK_LIBS="-ljack -lsamplerate" fi JACK_LIBS="$JACK_LIBS -lpthread" fi if test "$with_alsa" = yes ; then $as_echo "#define HAVE_ALSA 1" >>confdefs.h AUDIO_LIB="-lasound" if test "$with_jack" = yes ; then AUDIO_SYSTEM=ALSA+JACK else AUDIO_SYSTEM=ALSA fi fi if test "$with_oss" = yes ; then $as_echo "#define HAVE_OSS 1" >>confdefs.h AUDIO_SYSTEM=OSS fi if test "$AUDIO_SYSTEM" = None ; then case "$host" in *-*-linux*) AUDIO_SYSTEM=ALSA $as_echo "#define HAVE_ALSA 1" >>confdefs.h AUDIO_LIB="-lasound" ;; *-*-sunos4*) AUDIO_SYSTEM=Sun ;; *-*-solaris*) AUDIO_SYSTEM=Sun ;; *-*-hpux*) AUDIO_SYSTEM=Hpux ;; *-*-bsdi*) $as_echo "#define HAVE_OSS 1" >>confdefs.h AUDIO_SYSTEM=OSS ;; *-*-freebsd*) $as_echo "#define HAVE_OSS 1" >>confdefs.h AUDIO_SYSTEM=OSS ;; *-*-openbsd*) AUDIO_SYSTEM=OpenBSD ;; *-*-netbsd*) AUDIO_SYSTEM=NetBSD ;; *-*-cygwin*) if test "$with_jack" != yes ; then AUDIO_SYSTEM=Windows fi ;; *-*-mingw*) audio_system=Windows ;; *-apple-*) if test "$with_jack" != yes ; then AUDIO_SYSTEM=MacOSX AUDIO_LIB="-framework CoreAudio -framework CoreFoundation -framework CoreMIDI" else AUDIO_SYSTEM=JACK JACK_LIBS="-framework CoreAudio -framework CoreServices -framework AudioUnit -L/usr/local/lib -ljack -lsamplerate" JACK_FLAGS="-I/usr/local/include" fi ;; esac fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for audio system" >&5 $as_echo_n "checking for audio system... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AUDIO_SYSTEM" >&5 $as_echo "$AUDIO_SYSTEM" >&6; } if test "$AUDIO_SYSTEM" != None ; then $as_echo "#define WITH_AUDIO 1" >>confdefs.h fi #-------------------------------------------------------------------------------- # compiler/loader flags #-------------------------------------------------------------------------------- LIBS="" LDSO_FLAGS="" SO_FLAGS="" SO_LD="ld" # the SO_* stuff here is for consistency with the sndlib configure script case "$host" in *-*-linux*) LDSO_FLAGS="-shared" LIBS="$LIBS -lm -ldl" if test "$GCC" = yes ; then SO_FLAGS="-fPIC $SO_FLAGS" SO_LD="$CC" fi ;; *-*-sunos4*) LIBS="$LIBS -lm" ;; *-*-solaris*) LIBS="$LIBS -lm" LDSO_FLAGS="-G" ;; *-*-hpux*) LDSO_FLAGS="+z -Ae +DA1.1" if test "$GCC" = yes ; then SO_FLAGS="-fPIC $SO_FLAGS" fi ;; *-*-bsdi*) LIBS="$LIBS -lm" if test "$GCC" = yes ; then SO_FLAGS="-fPIC $SO_FLAGS" fi ;; *-*-freebsd*) LIBS="$LIBS -lm" if test "$GCC" = yes ; then SO_LD="$CC" SO_FLAGS="-fPIC $SO_FLAGS" CFLAGS="-fPIC $CFLAGS" LDSO_FLAGS="-shared" fi ;; *-*-openbsd*) LIBS="$LIBS -lm" if test "$GCC" = yes ; then SO_LD="$CC" SO_FLAGS="-fPIC $SO_FLAGS" CFLAGS="-ftrampolines $CFLAGS" LDSO_FLAGS="-shared" fi ;; *-*-netbsd*) LIBS="$LIBS -lm" if test "$GCC" = yes ; then SO_LD="$CC" SO_FLAGS="-fPIC $SO_FLAGS" LDSO_FLAGS="-shared" fi ;; *-*-mingw*) LIBS="$LIBS -lwinmm -lwsock32" LDFLAGS="$LDFLAGS -mwindows" SO_INSTALL=":" SO_LD=":" ;; *-apple-*) SO_LD="$CC" LDSO_FLAGS="-dynamic -bundle -undefined suppress -flat_namespace" ;; esac #-------------------------------------------------------------------------------- # export-dynamic #-------------------------------------------------------------------------------- CFLAGS="-O2 -I. $CFLAGS" ORIGINAL_LDFLAGS="$LDFLAGS" case "$host" in *-*-linux* | *-*-bsdi* | *-*-freebsd* | *-*-openbsd* | *-*-netbsd*) if test "$CC" = "gcc" || test "$CC" = "g++" || test "$CC" = "cc" ; then LDFLAGS="$LDFLAGS -Wl,-export-dynamic" fi esac #-------------------------------------------------------------------------------- # disable-deprecated #-------------------------------------------------------------------------------- if test "$enable_deprecated" = no ; then CFLAGS="-DGTK_DISABLE_DEPRECATED -DG_DISABLE_DEPRECATED -DGDK_DISABLE_DEPRECATED -DPANGO_DISABLE_DEPRECATED -DCAIRO_DISABLE_DEPRECATED -DGSL_DISABLE_DEPRECATED -Wall $CFLAGS" $as_echo "#define DISABLE_DEPRECATED 1" >>confdefs.h fi #-------------------------------------------------------------------------------- # output #-------------------------------------------------------------------------------- cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by snd $as_me 16.1, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ snd config.status 16.1 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "mus-config.h") CONFIG_HEADERS="$CONFIG_HEADERS mus-config.h" ;; "makefile") CONFIG_FILES="$CONFIG_FILES makefile" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS " shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: Options selected ------------------------- Snd version ...........: $VERSION CFLAGS ................: $CFLAGS LDFLAGS ...............:$LDFLAGS LIBS...................: $LIBS prefix.................: ${prefix} extension language.....: $LOCAL_LANGUAGE audio system...........: $AUDIO_SYSTEM graphics toolkit.......: $GRAPHICS_TOOLKIT optional libraries.....:$OPTIONAL_LIBRARIES random features........:$RANDOM_FEATURES environs...............: $host $CC " >&5 $as_echo " Options selected ------------------------- Snd version ...........: $VERSION CFLAGS ................: $CFLAGS LDFLAGS ...............:$LDFLAGS LIBS...................: $LIBS prefix.................: ${prefix} extension language.....: $LOCAL_LANGUAGE audio system...........: $AUDIO_SYSTEM graphics toolkit.......: $GRAPHICS_TOOLKIT optional libraries.....:$OPTIONAL_LIBRARIES random features........:$RANDOM_FEATURES environs...............: $host $CC " >&6; } snd-16.1/xm-enved.fs0000644000076400007640000004353612306421672012426 0ustar bilbil\ xm-enved.fs -- xm-enved.scm -> xm-enved.fs \ Author: Michael Scholz \ Created: Fri Oct 21 18:22:57 CEST 2005 \ Changed: Sat Dec 1 19:09:08 CET 2012 \ Commentary: \ \ Requires --with-motif|gtk \ \ Tested with Snd 13.x \ Fth 1.3.x \ Motif 2.3.4 X11R6 \ (Glib 2.28.8, Pango 1.28.4, Cairo 1.10.2) \ \ This is an example of an object type written in Forth. \ \ XENVED \ \ before-enved-hook ( xe pos x y reason -- f ) \ xenved? ( obj -- f ) \ make-xenved ( name parent :key envelope axis-bounds args -- xe ) \ \ xenved-length ( xe -- len|-1 ) \ xenved-ref ( xe index -- point ) \ xenved-set! ( xe index point -- ) \ xenved-index ( xe x -- index|-1 ) \ xenved-insert! ( xe index point -- ) \ xenved-delete! ( xe index -- ) \ \ xenved-envelope@ ( xe -- ary ) \ xenved-envelope! ( xe ary -- ) \ xenved-open ( xe -- ) \ xenved-close ( xe -- ) \ \ xe-envelope ( xe -- ary ) \ set-xe-envelope ( xe ary -- ) \ \ xenved-test ( name -- xe ) 'snd-nogui provided? [if] skip-file [then] 'snd-gtk provided? [if] 'gtk3 provided? not [if] .( snd-gtk: gtk3 required -- skipping xm-enved.fs ) cr skip-file [then] [then] require enved require snd-xm \ === XENVED OBJECT TYPE === 5 "( xe pos x y reason -- f ) \ Will be called before changing a breakpoint in XE's envelope. \ This hook runs the global ENVED-HOOK at first, \ subsequent procedures can directly manipulate XE's envelope \ or the returned array of the preceding hook procedure.\n\ This instance hook is like the global ENVED-HOOK; \ POS is ENVELOPE's x-position, X and Y are the new points, \ and REASON is one of the Snd constants ENVED-ADD-POINT, \ ENVED-DELETE-POINT, ENVED-MOVE-POINT. \ If one of the hook procedures in the hook array returns #f, \ xenved changes the breakpoint, \ otherwise the last hook procedure is responsible for manipulating \ XE's envelope itself." create-hook before-enved-hook \ \ Example hook function: \ Applies Snd's enved-hook functions to xenved. \ \ before-enved-hook lambda: <{ xe pos x y reason -- f }> \ enved-hook hook-empty? if \ #f \ else \ xe xenved-envelope@ { res } \ enved-hook each { prc } \ prc #( res pos x y reason ) run-proc to res \ res false? ?leave \ end-each \ res array? if \ xe res xenved-envelope! \ then \ res \ then \ ; add-hook! "xenved" make-object-type constant fth-xenved fth-xenved make-?obj xenved? hide #( "xe-enved" "xe-name" "xe-parent" "xe-args" "xe-drawer" "xe-gcs" "xe-bx0" "xe-bx1" "xe-by0" "xe-by1" "xe-px0" "xe-px1" "xe-py0" "xe-py1" "xe-mouse-up" "xe-mouse-down" "xe-mouse-pos" "xe-mouse-new" "xe-click-time" "xe-dragging" ) create-instance-struct make-xenved-instance : axis-bounds? ( obj -- f ) array-length 4 = ; : xe-length ( self -- len ) xe-enved@ enved-length ; : xe-inspect { self -- str } "#<%s[%d]: axis-bounds: #( %s %s %s %s ), envelope: %s>" #( self object-name self xe-length self xe-bx0@ self xe-bx1@ self xe-by0@ self xe-by1@ self xe-enved@ ) string-format ; : xe->string ( self -- str ) xe-enved@ object->string ; : xe-dump { self -- str } "%S %S :envelope %s :axis-bounds #( %s %s %s %s ) :args %S make-xenved" #( self xe-name@ self xe-parent@ self xe-enved@ self xe-bx0@ self xe-bx1@ self xe-by0@ self xe-by1@ self xe-args@ ) string-format ; : xe->array ( self -- ary ) xe-enved@ object->array ; : xe-ref ( self index -- point ) swap xe-enved@ swap enved-ref ; : xe-set! ( self index point -- ) rot xe-enved@ -rot enved-set! ; : xe-equal? { self obj -- f } self obj = if #t else self xe-enved@ obj xe-enved@ object-equal? then ; \ Init object type Xenved. <'> xe-inspect fth-xenved set-object-inspect \ xe .inspect <'> xe->string fth-xenved set-object->string \ xe object->string <'> xe-dump fth-xenved set-object-dump \ xe object-dump <'> xe->array fth-xenved set-object->array \ xe object->array <'> xe-ref fth-xenved set-object-value-ref \ xe idx object-ref => #( x y ) <'> xe-set! fth-xenved set-object-value-set \ xe idx #( x y ) object-set! <'> xe-equal? fth-xenved set-object-equal-p \ obj1 obj2 object-equal? <'> xe-length fth-xenved set-object-length \ xe object-length => (lstlen/2) <'> xe-ref fth-xenved 1 set-object-apply \ xe idx apply => #( x y ) : run-before-enved-hook { xe point reason -- f } xe xenved? xe 1 "an xenved" assert-type point array-length 2 = point 1 "an array #( x y )" assert-type before-enved-hook hook-empty? if #t else #f ( flag ) before-enved-hook each { prc } prc #( xe xe xe-mouse-pos@ point 0 array-ref point 1 array-ref reason ) run-proc false? if not ( toggle flag ) leave then end-each then ; set-current : xenved-length { xe -- len|-1 } xe xenved? xe 1 "an xenved" assert-type xe xe-length ; : xenved-ref { xe index -- point } xe xenved? xe 1 "an xenved" assert-type xe index xe-ref ; : xenved-set! { xe index point -- } xe xenved? xe 1 "an xenved" assert-type xe index point xe-set! ; : xenved-index { xe x -- index|-1 } xe xenved? xe 1 "an xenved" assert-type xe xe-enved@ x enved-index ; : xenved-insert! { xe index point -- } xe xenved? xe 1 "an xenved" assert-type xe xe-enved@ index point enved-insert! ; : xenved-delete! { xe index -- } xe xenved? xe 1 "an xenved" assert-type xe xe-enved@ index enved-delete! ; previous hide 0.03 constant mouse-radius : grfx { xe x -- n } xe xe-px0@ xe xe-px1@ = if xe xe-px0@ else xe xe-px0@ { px0 } xe xe-px1@ { px1 } xe xe-bx0@ { bx0 } xe xe-bx1@ { bx1 } x bx0 f- bx1 bx0 f- f/ px1 px0 f- f* px0 f+ floor f>s px0 max px1 min then ; : grfy { xe y -- n } xe xe-py0@ xe xe-py1@ = if xe xe-py0@ else xe xe-py0@ { py0 } xe xe-py1@ { py1 } xe xe-by0@ { by0 } xe xe-by1@ { by1 } y by1 f- by0 by1 f- f/ py0 py1 f- f* py1 f+ floor f>s py1 max py0 min then ; : ungrfx { xe x -- r } xe xe-px0@ xe xe-px1@ = if xe xe-bx0@ s>f else xe xe-px0@ { px0 } xe xe-px1@ { px1 } xe xe-bx0@ { bx0 } xe xe-bx1@ { bx1 } x px0 f- px1 px0 f- f/ bx1 bx0 f- f* bx0 f+ bx0 fmax bx1 fmin then ; : ungrfy { xe y -- r } xe xe-py0@ xe xe-py1@ = if xe xe-by1@ s>f else xe xe-py0@ { py0 } xe xe-py1@ { py1 } xe xe-by0@ { by0 } xe xe-by1@ { by1 } py0 y f- py0 py1 f- f/ by1 by0 f- f* by0 f+ by0 fmax by1 fmin then ; 'snd-motif provided? [if] 360 64 * constant 360*64 : xe-redraw { xe -- } xe xe-drawer@ { drawer } drawer is-managed? xe xe-py0@ xe xe-py1@ > && if xe xe-gcs@ { gc } drawer FXtDisplay { dpy } drawer FXtWindow { win } dpy win FXClearWindow drop \ Motif's DRAW-AXES takes 6 optional arguments. \ '( x0 y0 x1 y1 ) = draw-axes(wid gc label \ x0=0.0 x1=1.0 y0=-1.0 y1=1.0 \ style=x-axis-in-seconds \ axes=show-all-axes) \ arity #( 3 6 #f ) drawer gc xe xe-name@ xe xe-bx0@ xe xe-bx1@ xe xe-by0@ xe xe-by1@ x-axis-in-seconds show-all-axes draw-axes drop #f #f { lx ly } 10 { mouse-d } 5 { mouse-r } xe each { point } xe point 0 array-ref grfx { cx } xe point 1 array-ref grfy { cy } dpy win gc cx mouse-r - cy mouse-r - mouse-d mouse-d 0 360*64 FXFillArc drop lx if dpy win gc lx ly cx cy FXDrawLine drop then cx to lx cy to ly end-each then ; [else] : xe-redraw { xe -- } xe xe-drawer@ { drawer } drawer is-managed? xe xe-py0@ xe xe-py1@ > && if xe xe-gcs@ { gc } drawer FGTK_WIDGET widget-size { size } drawer make-cairo { cairo } cairo Fcairo_push_group drop cairo 1.0 1.0 1.0 Fcairo_set_source_rgb drop cairo 0 0 size 0 array-ref size 1 array-ref Fcairo_rectangle drop cairo Fcairo_fill drop \ Gtk's DRAW-AXES takes one more optional argument, \ a cairo object. \ '( x0 y0 x1 y1 ) = draw-axes(wid gc label \ x0=0.0 x1=1.0 y0=-1.0 y1=1.0 \ style=x-axis-in-seconds \ axes=show-all-axes \ cairo) \ arity #( 3 7 #f ) drawer gc xe xe-name@ xe xe-bx0@ xe xe-bx1@ xe xe-by0@ xe xe-by1@ x-axis-in-seconds show-all-axes cairo draw-axes drop cairo 1.0 Fcairo_set_line_width drop cairo 0.0 0.0 0.0 Fcairo_set_source_rgb drop #f #f { lx ly } 5 { mouse-r } xe each { point } xe point 0 array-ref grfx { cx } xe point 1 array-ref grfy { cy } cairo cx cy mouse-r 0.0 two-pi Fcairo_arc drop cairo Fcairo_fill drop lx if cairo lx ly Fcairo_move_to drop cairo cx cy Fcairo_line_to drop cairo Fcairo_stroke drop then cx to lx cy to ly end-each cairo Fcairo_pop_group_to_source drop cairo Fcairo_paint drop cairo free-cairo drop then ; [then] : add-envelope-point { xe x y -- } xe xe-mouse-pos@ { mpos } xe x xenved-index dup 0>= if to mpos else drop xe each 0 array-ref x f> if i to mpos leave then end-each then xe mpos #( x y ) xenved-insert! xe mpos xe-mouse-pos! ; : draw-axes-set-points { lst xe -- } xe lst 0 array-ref xe-px0! xe lst 1 array-ref xe-py0! xe lst 2 array-ref xe-px1! xe lst 3 array-ref xe-py1! xe xe-redraw ; : mouse-press { xe xx yy -- } xe xx ungrfx { x } xe yy ungrfy { y } #f ( flag ) xe each { point } point 0 array-ref x f- fabs mouse-radius f< point 1 array-ref y f- fabs mouse-radius f< && if drop ( flag ) i ( flag is now pos ) leave then end-each { pos } xe pos not xe-mouse-new! xe time xe-mouse-down! pos number? if xe pos xe-mouse-pos! else xe #( x y ) enved-add-point run-before-enved-hook if xe x y add-envelope-point then xe xe-redraw then ; : mouse-release { xe -- } xe xe-mouse-pos@ { mpos } xe time xe-mouse-up! xe xe-mouse-new@ unless xe xe-mouse-up@ xe xe-mouse-down@ f- xe xe-click-time@ f<= if mpos 0<> if mpos xe xenved-length 1- < if xe mpos xenved-ref { point } xe point enved-delete-point run-before-enved-hook if xe mpos xenved-delete! then xe xe-redraw then then then then xe #f xe-mouse-new! ; : mouse-drag { xe xx yy -- } xe xx ungrfx { x } xe yy ungrfy { y } xe xe-mouse-pos@ { mpos } mpos 0= if xe 0 xenved-ref 0 array-ref else mpos xe xenved-length 1- >= if xe -1 xenved-ref 0 array-ref else xe mpos 1- xenved-ref 0 array-ref xe mpos 1+ xenved-ref 0 array-ref x fmin fmax then then to x xe #( x y ) enved-move-point run-before-enved-hook if xe mpos #( x y ) xenved-set! then xe xe-redraw ; 'snd-motif provided? [if] : draw-axes-cb <{ w xe info -- }> xe xe-drawer@ xe xe-gcs@ xe xe-name@ xe xe-bx0@ xe xe-bx1@ xe xe-by0@ x-axis-in-seconds show-all-axes draw-axes xe draw-axes-set-points ; : mouse-press-cb <{ w xe ev f -- }> xe ev Fx ev Fy mouse-press ; : mouse-release-cb <{ w xe ev f -- }> xe mouse-release ; : mouse-drag-cb <{ w xe ev f -- }> xe ev Fx ev Fy mouse-drag ; : define-cursor-cb <{ w xe ev f -- x }> w FXtDisplay w FXtWindow xe FXDefineCursor ; : undefine-cursor-cb <{ w xe ev f -- x }> w FXtDisplay w FXtWindow FXUndefineCursor ; : make-drawer { name parent args -- drawer } args FXmNbackground array-member? unless args FXmNbackground array-push graph-color array-push to args then args FXmNforeground array-member? unless args FXmNforeground array-push data-color array-push to args then name FxmDrawingAreaWidgetClass parent args undef FXtCreateManagedWidget ( drawer ) ; : init-xenved-cbs { xe -- } xe xe-drawer@ { drawer } drawer FXtDisplay FXC_crosshair FXCreateFontCursor { arrow-cursor } drawer FXmNresizeCallback <'> draw-axes-cb xe FXtAddCallback drop drawer FXmNexposeCallback <'> draw-axes-cb xe FXtAddCallback drop drawer FButtonPressMask #f <'> mouse-press-cb xe FXtAddEventHandler drop drawer FButtonReleaseMask #f <'> mouse-release-cb xe FXtAddEventHandler drop drawer FButtonMotionMask #f <'> mouse-drag-cb xe FXtAddEventHandler drop drawer FEnterWindowMask #f <'> define-cursor-cb arrow-cursor FXtAddEventHandler drop drawer FLeaveWindowMask #f <'> undefine-cursor-cb #f FXtAddEventHandler drop ; [else] : draw-axes-cb <{ w ev xe -- f }> xe xe-drawer@ { win } win make-cairo { cairo } win xe xe-gcs@ xe xe-name@ xe xe-bx0@ xe xe-bx1@ xe xe-by0@ xe xe-by1@ x-axis-in-seconds show-all-axes cairo draw-axes xe draw-axes-set-points cairo free-cairo drop #f ; \ '( bool x y ) = \ gdk_event_get_coords(event x-win-return=undef y-win-return=undef) \ arity #( 1 2 #f ) : get-coords ( ev -- x y ) undef undef Fgdk_event_get_coords dup \ coords coords 1 array-ref swap \ x coords 2 array-ref \ x y ; : mouse-press-cb <{ w ev xe -- f }> xe #t xe-dragging! xe ev FGDK_EVENT get-coords mouse-press #f ; : mouse-release-cb <{ w ev xe -- f }> xe #f xe-dragging! xe mouse-release #f ; : mouse-drag-cb <{ w ev xe -- f }> xe xe-dragging@ if xe ev FGDK_EVENT get-coords mouse-drag then #f ; : define-cursor-cb <{ w ev cursor -- f }> w Fgtk_widget_get_window cursor Fgdk_window_set_cursor drop #f ; : make-drawer { name parent args -- drawer } Fgtk_drawing_area_new { drawer } drawer FGDK_ALL_EVENTS_MASK Fgtk_widget_set_events drop parent FGTK_BOX drawer #t #t 10 Fgtk_box_pack_start drop drawer Fgtk_widget_show drop drawer name Fgtk_widget_set_name drop drawer -1 200 Fgtk_widget_set_size_request drop drawer ; : init-xenved-cbs { xe -- } xe xe-drawer@ { drawer } drawer FGPOINTER 'gtk3 provided? if "draw" else "expose_event" then drawer FG_OBJECT FG_OBJECT_TYPE Fg_signal_lookup 0 <'> draw-axes-cb xe #f Fg_cclosure_new #f Fg_signal_connect_closure_by_id drop drawer FGPOINTER "configure_event" drawer FG_OBJECT FG_OBJECT_TYPE Fg_signal_lookup 0 <'> draw-axes-cb xe #f Fg_cclosure_new #f Fg_signal_connect_closure_by_id drop drawer FGPOINTER "button_press_event" drawer FG_OBJECT FG_OBJECT_TYPE Fg_signal_lookup 0 <'> mouse-press-cb xe #f Fg_cclosure_new #f Fg_signal_connect_closure_by_id drop drawer FGPOINTER "button_release_event" drawer FG_OBJECT FG_OBJECT_TYPE Fg_signal_lookup 0 <'> mouse-release-cb xe #f Fg_cclosure_new #f Fg_signal_connect_closure_by_id drop drawer FGPOINTER "motion_notify_event" drawer FG_OBJECT FG_OBJECT_TYPE Fg_signal_lookup 0 <'> mouse-drag-cb xe #f Fg_cclosure_new #f Fg_signal_connect_closure_by_id drop drawer FGPOINTER "enter_notify_event" drawer FG_OBJECT FG_OBJECT_TYPE Fg_signal_lookup 0 <'> define-cursor-cb FGDK_CROSSHAIR Fgdk_cursor_new ( arrow-cursor ) #f Fg_cclosure_new #f Fg_signal_connect_closure_by_id drop drawer FGPOINTER "leave_notify_event" drawer FG_OBJECT FG_OBJECT_TYPE Fg_signal_lookup 0 <'> define-cursor-cb FGDK_LEFT_PTR Fgdk_cursor_new ( old-cursor ) #f Fg_cclosure_new #f Fg_signal_connect_closure_by_id drop ; [then] set-current : make-xenved <{ name parent :key envelope #( 0.0 0.0 1.0 1.0 ) axis-bounds #( 0.0 1.0 0.0 1.0 ) args #() -- xe }> parent widget? parent 2 "a widget" assert-type axis-bounds axis-bounds? axis-bounds 4 "an array of axis bounds" assert-type fth-xenved make-xenved-instance { xe } xe envelope make-enved xe-enved! name string? unless "xe-test" to name then xe name parent args make-drawer xe-drawer! xe name xe-name! xe parent xe-parent! xe args xe-args! xe snd-gcs 0 array-ref xe-gcs! xe axis-bounds 0 array-ref xe-bx0! xe axis-bounds 2 array-ref xe-by0! xe axis-bounds 1 array-ref xe-bx1! xe axis-bounds 3 array-ref xe-by1! xe 0 xe-px0! \ points == ints xe 0 xe-py0! xe 0 xe-px1! xe 0 xe-py1! xe 0.0 xe-mouse-up! xe 0.0 xe-mouse-down! xe 0.5 xe-click-time! xe 0 xe-mouse-pos! xe #f xe-mouse-new! xe #f xe-dragging! xe init-xenved-cbs xe ; : xenved-envelope@ { xe -- ary } xe xenved? xe 1 "an xenved" assert-type xe xe-enved@ enved-envelope@ ; : xenved-envelope! { xe ary -- } xe xenved? xe 1 "an xenved" assert-type ary array? ary 2 "an array" assert-type xe xe-enved@ ary enved-envelope! ; <'> xenved-envelope@ alias xe-envelope : set-xe-envelope { xe ary -- } xe ary xenved-envelope! xe xe-redraw ; \ XXX \ For backwards compatibility. <'> xenved-envelope@ alias xe-envelope@ \ XXX \ For backwards compatibility with arguments swapped. : xe-envelope! { ary xe -- } xe ary xenved-envelope! ; : xenved-open { xe -- } xe xenved? xe 1 "an xenved" assert-type xe xe-drawer@ widget? if xe xe-drawer@ show-widget drop then xe xe-redraw ; : xenved-close { xe -- } xe xenved? xe 1 "an xenved" assert-type xe xe-drawer@ widget? if xe xe-drawer@ hide-widget drop then ; previous #f value test-widget-type #f value test-widget-args #f value test-xenved-args 'snd-motif provided? [if] FxmFormWidgetClass to test-widget-type #( FXmNheight 200 ) to test-widget-args #( FXmNleftAttachment FXmATTACH_WIDGET FXmNtopAttachment FXmATTACH_WIDGET FXmNbottomAttachment FXmATTACH_WIDGET FXmNrightAttachment FXmATTACH_WIDGET ) to test-xenved-args [then] : xenved-test <{ :optional name "xenved" -- xe }> doc" create a drawing test widget\n\ xenved-test value xe\n\ xe => #( 0.0 0.0 1.0 1.0 )\n\ xe xe-envelope => #( 0.0 0.0 1.0 1.0 )\n\ \\ some clicks later\n\ xe xe-envelope => #( 0.0 0.0\n\ 0.190736 0.562264\n\ 0.632152 0.932075\n\ 0.848774 0.316981\n\ 1.0 1.0 )\n\ xe #( 0 1 1 1 ) set-xe-envelope\n\ xe xe-envelope => #( 0 1 1 1 )\n\ xe xe-close." name name test-widget-type test-widget-args add-main-pane :envelope #( 0.0 0.0 1.0 1.0 ) :axis-bounds #( 0.0 1.0 0.0 1.0 ) :args test-xenved-args make-xenved ( xe ) ; \ xm-enved.fs ends here snd-16.1/gtk-effects.scm0000644000076400007640000032123112622705137013250 0ustar bilbil;;; translation of new-effects.scm to gtk/xg (provide 'snd-gtk-effects.scm) (require snd-gtk snd-gtk-effects-utils.scm snd-xm-enved.scm snd-moog.scm snd-rubber.scm snd-dsp.scm) (with-let (sublet *gtk*) (define (plausible-mark-samples) ;; find two marks in the current channel (in or nearest to current window) (let* ((snd (selected-sound)) (chn (selected-channel)) (ms (sort! (map mark-sample (marks snd chn)) <))) (if (< (length ms) 2) (error 'no-such-mark (list "mark-related action requires two marks")) (if (= (length ms) 2) ms (let* ((lw (left-sample snd chn)) (rw (right-sample snd chn)) (cw (cursor snd chn)) (favor (if (>= rw cw lw) cw (* .5 (+ lw rw))))) ;; favor is the point we center the search on (define (centered-points points) (if (= (length points) 2) points (let ((p1 (car points)) (p2 (cadr points)) (p3 (caddr points))) (if (< (abs (- p1 favor)) (abs (- p3 favor))) (list p1 p2) (centered-points (cdr points)))))) (centered-points ms)))))) (define map-chan-over-target-with-sync ;; target: 'marks -> beg=closest marked sample, dur=samples to next mark ;; 'sound -> beg=0, dur=all samples in sound ;; 'selection -> beg=selection-position, dur=selection-framples ;; 'cursor -> beg=cursor, dur=samples to end of sound ;; decay is how long to run the effect past the end of the sound (lambda (func target origin decay) (if (and (eq? target 'selection) (not (selection?))) (snd-print ";no selection") (if (and (eq? target 'sound) (null? (sounds))) (snd-print ";no sound") (if (and (eq? target 'marks) (or (null? (sounds)) (< (length (marks (selected-sound) (selected-channel))) 2))) (snd-print ";no marks") (let* ((snc (sync)) (ms (and (eq? target 'marks) (plausible-mark-samples))) (beg (if (eq? target 'sound) 0 (if (eq? target 'selection) (selection-position) (if (eq? target 'cursor) (cursor (selected-sound) (selected-channel)) (car ms))))) (overlap (if decay (floor (* (srate) decay)) 0))) (apply for-each (lambda (snd chn) (let ((end (if (memq target '(sound cursor)) (- (framples snd chn) 1) (if (eq? target 'selection) (+ (selection-position) (selection-framples)) (cadr ms))))) (if (= (sync snd) snc) (map-channel (func (- end beg)) beg (+ end overlap 1) snd chn #f (format #f "~A ~A ~A" (origin target (- end beg)) (if (eq? target 'sound) 0 beg) (and (not (eq? target 'sound)) (+ 1 (- end beg)))))))) (if (> snc 0) (all-chans) (list (list (selected-sound)) (list (selected-channel))))))))))) (define (add-target mainform target-callback truncate-callback) ;; add a set of 3 radio buttons at the bottom of the main section for choice between sound, selection, between-marks ;; target-callback should take one arg, a symbol: 'sound, 'selection, 'marks, and apply the effect accordingly (upon "DoIt") ;; truncate-callback (if any) takes one arg: boolean representing toggle state (#t = on) (let (;(sep (gtk_separator_new GTK_ORIENTATION_HORIZONTAL)) (rc (gtk_box_new GTK_ORIENTATION_HORIZONTAL 0))) (gtk_box_pack_start (GTK_BOX mainform) rc #f #f 4) ;(gtk_box_pack_start (GTK_BOX rc) sep #t #t 4) ;(gtk_widget_show sep) (gtk_widget_show rc) (let ((group #f)) (for-each (lambda (name type on) (let ((button (gtk_radio_button_new_with_label group name))) (set! group (gtk_radio_button_get_group (GTK_RADIO_BUTTON button))) (gtk_box_pack_start (GTK_BOX rc) button #f #f 4) (gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON button) on) (gtk_widget_show button) (g_signal_connect button "clicked" (lambda (w d) (target-callback type)) #f))) (list "entire sound" "selection" "between marks") (list 'sound 'selection 'marks) (list #t #f #f))) (if truncate-callback (let ((sep (gtk_separator_new GTK_ORIENTATION_HORIZONTAL)) (button (gtk_check_button_new_with_label "truncate at end"))) (gtk_box_pack_start (GTK_BOX rc) sep #t #t 4) (gtk_widget_show sep) (gtk_box_pack_start (GTK_BOX rc) button #t #t 4) (gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON button) #t) (gtk_widget_show button) (g_signal_connect button "clicked" (lambda (w d) (truncate-callback (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON w)))) #f))))) (define (effect-framples target) (if (eq? target 'sound) (- (framples) 1) (if (eq? target 'selection) (selection-framples) (+ 1 (abs (apply - (plausible-mark-samples))))))) ;;; ******************************* ;;; ** ;;; BEGIN PARAMETRIZED EFFECTS ** ;;; ** ;;; ******************************* ;;; AMPLITUDE EFFECTS ;;; (define effects-list ()) ; menu labels are updated to show current settings (define effects-menu (add-to-main-menu "Effects" (lambda () (update-label effects-list)))) (define* (effects-squelch-channel amp gate-size snd chn no-silence) (let ((f0 (make-moving-average gate-size)) (f1 (make-moving-average gate-size :initial-element 1.0))) (if no-silence (map-channel (lambda (y) (let ((val (* y (moving-average f1 (ceiling (- (moving-average f0 (* y y)) amp)))))) (and (not (zero? val)) val))) 0 #f snd chn #f (format #f "effects-squelch-channel ~A ~A" amp gate-size)) (map-channel (lambda (y) (* y (moving-average f1 (ceiling (- (moving-average f0 (* y y)) amp))))) 0 #f snd chn #f (format #f "effects-squelch-channel ~A ~A" amp gate-size))))) (let ((amp-menu-list ()) (amp-menu (gtk_menu_item_new_with_label "Amplitude Effects")) (amp-cascade (gtk_menu_new))) (gtk_menu_shell_append (GTK_MENU_SHELL (gtk_menu_item_get_submenu (GTK_MENU_ITEM (main-menu effects-menu)))) amp-menu) (gtk_widget_show amp-menu) (gtk_menu_item_set_submenu (GTK_MENU_ITEM amp-menu) amp-cascade) (g_signal_connect amp-menu "activate" (lambda (w d) (update-label amp-menu-list)) #f) ;; -------- Gain (gain set by gain-amount) (let ((child (gtk_menu_item_new_with_label "Gain")) (gain-amount 1.0) (gain-dialog #f) (gain-target 'sound) (gain-envelope #f)) (define (scale-envelope e scl) (if (null? e) () (append (list (car e) (* scl (cadr e))) (scale-envelope (cddr e) scl)))) (gtk_menu_shell_append (GTK_MENU_SHELL amp-cascade) child) (gtk_widget_show child) (g_signal_connect child "activate" (lambda (w d) (if (not gain-dialog) (let ((initial-gain-amount 1.0) (sliders ())) (set! gain-dialog (make-effect-dialog "Gain" (lambda (w data) ;; Gain scales amplitude by gain amount. (let ((with-env (and (not (equal? (xe-envelope gain-envelope) (list 0.0 1.0 1.0 1.0))) (scale-envelope (xe-envelope gain-envelope) gain-amount)))) (if (eq? gain-target 'sound) (if with-env (env-sound with-env) (scale-by gain-amount)) (if (eq? gain-target 'selection) (if (selection?) (if with-env (env-selection with-env) (scale-selection-by gain-amount)) (snd-print "no selection")) (let ((pts (plausible-mark-samples))) (if pts (if with-env (env-sound with-env (car pts) (- (cadr pts) (car pts))) (scale-by gain-amount (car pts) (- (cadr pts) (car pts)))))))))) (lambda (w data) (help-dialog "Gain" "Move the slider to change the gain scaling amount.")) (lambda (w data) (set! gain-amount initial-gain-amount) (set! (xe-envelope gain-envelope) (list 0.0 1.0 1.0 1.0)) (gtk_adjustment_set_value (GTK_ADJUSTMENT (car sliders)) gain-amount) ) (lambda () (effect-target-ok gain-target)))) (set! sliders (add-sliders gain-dialog (list (list "gain" 0.0 initial-gain-amount 5.0 (lambda (w data) (set! gain-amount (gtk_adjustment_get_value (GTK_ADJUSTMENT w)))) 100)))) (gtk_widget_show gain-dialog) (set! gain-envelope (xe-create-enved "gain" (gtk_dialog_get_content_area (GTK_DIALOG gain-dialog)) #f '(0.0 1.0 0.0 1.0))) (set! (xe-envelope gain-envelope) (list 0.0 1.0 1.0 1.0)) (add-target (gtk_dialog_get_content_area (GTK_DIALOG gain-dialog)) (lambda (target) (set! gain-target target) (gtk_widget_set_sensitive (GTK_WIDGET (g_object_get_data (G_OBJECT gain-dialog) "ok-button")) (effect-target-ok target))) #f))) (activate-dialog gain-dialog)) #f) (set! amp-menu-list (cons (lambda () (let ((new-label (format #f "Gain (~1,2F)" gain-amount))) (change-label child new-label))) amp-menu-list))) ;; -------- Normalize (let ((child (gtk_menu_item_new_with_label "Normalize")) (normalize-amount 1.0) (normalize-dialog #f) (normalize-target 'sound)) (gtk_menu_shell_append (GTK_MENU_SHELL amp-cascade) child) (gtk_widget_show child) (g_signal_connect child "activate" (lambda (w d) (if (not normalize-dialog) (let ((initial-normalize-amount 1.0) (sliders ())) (set! normalize-dialog (make-effect-dialog "Normalize" (lambda (w data) (if (eq? normalize-target 'sound) (scale-to normalize-amount) (if (eq? normalize-target 'selection) (if (selection?) (scale-selection-to normalize-amount) (snd-print "no selection")) (let ((pts (plausible-mark-samples))) (if pts (scale-to normalize-amount (car pts) (- (cadr pts) (car pts)))))))) (lambda (w data) (help-dialog "Normalize" "Normalize scales amplitude to the normalize amount. Move the slider to change the scaling amount.")) (lambda (w data) (set! normalize-amount initial-normalize-amount) (gtk_adjustment_set_value (GTK_ADJUSTMENT (car sliders)) normalize-amount) ) (lambda () (effect-target-ok normalize-target)))) (set! sliders (add-sliders normalize-dialog (list (list "normalize" 0.0 initial-normalize-amount 1.1 (lambda (w data) (set! normalize-amount (gtk_adjustment_get_value (GTK_ADJUSTMENT w)))) 100)))) (add-target (gtk_dialog_get_content_area (GTK_DIALOG normalize-dialog)) (lambda (target) (set! normalize-target target) (gtk_widget_set_sensitive (GTK_WIDGET (g_object_get_data (G_OBJECT normalize-dialog) "ok-button")) (effect-target-ok target))) #f))) (activate-dialog normalize-dialog)) #f) (set! amp-menu-list (cons (lambda () (let ((new-label (format #f "Normalize (~1,2F)" normalize-amount))) (change-label child new-label))) amp-menu-list))) ;; -------- Gate (gate set by gate-amount) (let ((gate-amount 0.01) (gate-dialog #f) (gate-size 128) (omit-silence #f)) (let ((child (gtk_menu_item_new_with_label "Gate"))) (gtk_menu_shell_append (GTK_MENU_SHELL amp-cascade) child) (gtk_widget_show child) (g_signal_connect child "activate" (lambda (w d) (if (not gate-dialog) ;; if gate-dialog doesn't exist, create it (let ((initial-gate-amount 0.01) (sliders ())) (set! gate-dialog (make-effect-dialog "Gate" (lambda (w data) (let ((snc (sync))) (if (> snc 0) (apply map (lambda (snd chn) (if (= (sync snd) snc) (effects-squelch-channel (* gate-amount gate-amount) gate-size snd chn omit-silence))) (all-chans)) (effects-squelch-channel (* gate-amount gate-amount) gate-size (selected-sound) (selected-channel) omit-silence)))) (lambda (w data) (help-dialog "Gate" "Move the slider to change the gate intensity. Higher values gate more of the sound.")) (lambda (w data) (set! gate-amount initial-gate-amount) (gtk_adjustment_set_value (GTK_ADJUSTMENT (car sliders)) gate-amount) ))) (set! sliders (add-sliders gate-dialog (list (list "gate" 0.0 initial-gate-amount 0.1 (lambda (w data) (set! gate-amount (gtk_adjustment_get_value (GTK_ADJUSTMENT w)))) 1000)))) ;; now add a toggle button setting omit-silence (let ((toggle (gtk_check_button_new_with_label "Omit silence"))) (gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG gate-dialog))) toggle #f #f 4) (gtk_widget_show toggle) (gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON toggle) omit-silence) (g_signal_connect toggle "clicked" (lambda (w d) (set! omit-silence (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON toggle)))) #f)))) (activate-dialog gate-dialog)) #f) (set! amp-menu-list (cons (lambda () (let ((new-label (format #f "Gate (~1,3F)" gate-amount))) (change-label child new-label))) amp-menu-list))))) ;;; DELAY EFFECTS ;;; (define effects-echo (let ((documentation "(effects-echo input-samps-1 delay-time echo-amount beg dur snd chn) is used by the effects dialog to tie into edit-list->function")) (lambda* (input-samps-1 delay-time echo-amount beg dur snd chn) (let* ((del (make-delay (round (* delay-time (srate snd))))) (len (or dur (framples snd chn))) (input-samps (or input-samps-1 len))) (as-one-edit (lambda () (map-channel (lambda (inval) (+ inval (delay del (* echo-amount (+ (tap del) inval))))) beg input-samps snd chn) (if (> len input-samps) (map-channel (lambda (inval) (+ inval (delay del (* echo-amount (tap del))))) (+ beg input-samps) (- dur input-samps) snd chn))) (format #f "effects-echo ~A ~A ~A ~A ~A" input-samps-1 delay-time echo-amount beg dur)))))) (define* (effects-flecho-1 scaler secs input-samps-1 beg dur snd chn) (let ((flt (make-fir-filter :order 4 :xcoeffs (float-vector .125 .25 .25 .125))) (del (make-delay (round (* secs (srate snd)))))) (if (and (not input-samps-1) (not dur)) (map-channel (lambda (inval) (+ inval (delay del (fir-filter flt (* scaler (+ (tap del) inval)))))) beg #f snd chn #f (format #f "effects-flecho-1 ~A ~A ~A ~A ~A" scaler secs input-samps-1 beg #f)) (let* ((cutoff (- (or input-samps-1 dur (framples snd chn)) 1)) (genv (make-env (list 0.0 1.0 cutoff 1.0 (+ cutoff 1) 0.0 (+ cutoff 100) 0.0) :length (+ cutoff 100)))) (map-channel (lambda (inval) (+ inval (delay del (fir-filter flt (* scaler (+ (tap del) (* (env genv) inval))))))) beg dur snd chn #f (format #f "effects-flecho-1 ~A ~A ~A ~A ~A" scaler secs input-samps-1 beg dur)))))) (define* (effects-zecho-1 scaler secs frq amp input-samps-1 beg dur snd chn) (let* ((os (make-oscil frq)) (len (round (* secs (srate snd)))) (del (make-delay len :max-size (round (+ len amp 1)))) (cutoff (- (or input-samps-1 dur (framples snd chn)) 1)) (genv (make-env (list 0.0 1.0 cutoff 1.0 (+ cutoff 1) 0.0 (+ cutoff 100) 0.0) :length (+ cutoff 100)))) (map-channel (lambda (inval) (+ inval (delay del (* scaler (+ (tap del) (* (env genv) inval))) (* amp (oscil os))))) beg dur snd chn #f (format #f "effects-zecho-1 ~A ~A ~A ~A ~A ~A ~A" scaler secs frq amp input-samps-1 beg dur)))) (let ((delay-menu-list ()) (delay-menu (gtk_menu_item_new_with_label "Delay Effects")) (delay-cascade (gtk_menu_new))) (gtk_menu_shell_append (GTK_MENU_SHELL (gtk_menu_item_get_submenu (GTK_MENU_ITEM (main-menu effects-menu)))) delay-menu) (gtk_widget_show delay-menu) (gtk_menu_item_set_submenu (GTK_MENU_ITEM delay-menu) delay-cascade) (g_signal_connect delay-menu "activate" (lambda (w d) (update-label delay-menu-list)) #f) ;; -------- Echo (controlled by delay-time and echo-amount) (let ((child (gtk_menu_item_new_with_label "Echo")) (delay-time .5) ; i.e. delay between echoes (echo-amount .2) (echo-dialog #f) (echo-target 'sound) (echo-truncate #t)) ;; echo-decay? -- using (* 4 delay-time) currently (gtk_menu_shell_append (GTK_MENU_SHELL delay-cascade) child) (gtk_widget_show child) (g_signal_connect child "activate" (lambda (w d) (if (not echo-dialog) (let ((initial-delay-time 0.5) (initial-echo-amount 0.2) (sliders ())) (set! echo-dialog (make-effect-dialog "Echo" (lambda (w data) (map-chan-over-target-with-sync (lambda (cutoff) (let ((del (make-delay (round (* delay-time (srate))))) (genv (make-env (list 0.0 1.0 cutoff 1.0 (+ cutoff 1) 0.0 (+ cutoff 100) 0.0) :length (+ cutoff 100)))) (lambda (inval) (+ inval (delay del (* echo-amount (+ (tap del) (* (env genv) inval)))))))) echo-target (lambda (target input-samps) (format #f "effects-echo ~A ~A ~A" (and (not (eq? target 'sound)) input-samps) delay-time echo-amount)) (and (not echo-truncate) (* 4 delay-time)))) (lambda (w data) (help-dialog "Echo" "The sliders change the delay time and echo amount.")) (lambda (w data) (set! delay-time initial-delay-time) (gtk_adjustment_set_value (GTK_ADJUSTMENT (car sliders)) delay-time) (set! echo-amount initial-echo-amount) (gtk_adjustment_set_value (GTK_ADJUSTMENT (cadr sliders)) echo-amount) ) (lambda () (effect-target-ok echo-target)))) (set! sliders (add-sliders echo-dialog (list (list "delay time" 0.0 initial-delay-time 2.0 (lambda (w data) (set! delay-time (gtk_adjustment_get_value (GTK_ADJUSTMENT (car sliders))))) 100) (list "echo amount" 0.0 initial-echo-amount 1.0 (lambda (w data) (set! echo-amount (gtk_adjustment_get_value (GTK_ADJUSTMENT (cadr sliders))))) 100)))) (add-target (gtk_dialog_get_content_area (GTK_DIALOG echo-dialog)) (lambda (target) (set! echo-target target) (gtk_widget_set_sensitive (GTK_WIDGET (g_object_get_data (G_OBJECT echo-dialog) "ok-button")) (effect-target-ok target))) (lambda (truncate) (set! echo-truncate truncate))))) (activate-dialog echo-dialog)) #f) (set! delay-menu-list (cons (lambda () (let ((new-label (format #f "Echo (~1,2F ~1,2F)" delay-time echo-amount))) (change-label child new-label))) delay-menu-list))) ;; -------- Filtered echo (let ((child (gtk_menu_item_new_with_label "Filtered echo")) (flecho-scaler 0.5) (flecho-delay 0.9) (flecho-dialog #f) (flecho-target 'sound) (flecho-truncate #t)) (define flecho-1 (lambda (scaler secs cutoff) (let ((flt (make-fir-filter :order 4 :xcoeffs (float-vector .125 .25 .25 .125))) (del (make-delay (round (* secs (srate))))) (genv (make-env (list 0.0 1.0 cutoff 1.0 (+ cutoff 1) 0.0 (+ cutoff 100) 0.0) :length (+ cutoff 100)))) (lambda (inval) (+ inval (delay del (fir-filter flt (* scaler (+ (tap del) (* (env genv) inval)))))))))) (gtk_menu_shell_append (GTK_MENU_SHELL delay-cascade) child) (gtk_widget_show child) (g_signal_connect child "activate" (lambda (w d) (if (not flecho-dialog) (let ((initial-flecho-scaler 0.5) (initial-flecho-delay 0.9) (sliders ())) (set! flecho-dialog (make-effect-dialog "Filtered echo" (lambda (w data) (map-chan-over-target-with-sync (lambda (input-samps) (flecho-1 flecho-scaler flecho-delay input-samps)) flecho-target (lambda (target input-samps) (format #f "effects-flecho-1 ~A ~A ~A" flecho-scaler flecho-delay (and (not (eq? target 'sound)) input-samps))) (and (not flecho-truncate) (* 4 flecho-delay)))) (lambda (w data) (help-dialog "Filtered echo" "Move the sliders to set the filter scaler and the delay time in seconds.")) (lambda (w data) (set! flecho-scaler initial-flecho-scaler) (gtk_adjustment_set_value (GTK_ADJUSTMENT (car sliders)) flecho-scaler) (set! flecho-delay initial-flecho-delay) (gtk_adjustment_set_value (GTK_ADJUSTMENT (cadr sliders)) flecho-delay) ) (lambda () (effect-target-ok flecho-target)))) (set! sliders (add-sliders flecho-dialog (list (list "filter scaler" 0.0 initial-flecho-scaler 1.0 (lambda (w data) (set! flecho-scaler (gtk_adjustment_get_value (GTK_ADJUSTMENT (car sliders))))) 100) (list "delay time (secs)" 0.0 initial-flecho-delay 3.0 (lambda (w data) (set! flecho-delay (gtk_adjustment_get_value (GTK_ADJUSTMENT (cadr sliders))))) 100)))) (add-target (gtk_dialog_get_content_area (GTK_DIALOG flecho-dialog)) (lambda (target) (set! flecho-target target) (gtk_widget_set_sensitive (GTK_WIDGET (g_object_get_data (G_OBJECT flecho-dialog) "ok-button")) (effect-target-ok target))) (lambda (truncate) (set! flecho-truncate truncate))))) (activate-dialog flecho-dialog)) #f) (set! delay-menu-list (cons (lambda () (let ((new-label (format #f "Filtered echo (~1,2F ~1,2F)" flecho-scaler flecho-delay))) (change-label child new-label))) delay-menu-list))) ;; -------- Modulated echo (let ((child (gtk_menu_item_new_with_label "Modulated echo")) (zecho-scaler 0.5) (zecho-delay 0.75) (zecho-freq 6) (zecho-amp 10.0) (zecho-dialog #f) (zecho-target 'sound) (zecho-truncate #t)) (define zecho-1 (lambda (scaler secs frq amp cutoff) (let* ((os (make-oscil frq)) (len (round (* secs (srate)))) (del (make-delay len :max-size (round (+ len amp 1)))) (genv (make-env (list 0.0 1.0 cutoff 1.0 (+ cutoff 1) 0.0 (+ cutoff 100) 0.0) :length (+ cutoff 100)))) (lambda (inval) (+ inval (delay del (* scaler (+ (tap del) (* (env genv) inval))) (* amp (oscil os)))))))) (gtk_menu_shell_append (GTK_MENU_SHELL delay-cascade) child) (gtk_widget_show child) (g_signal_connect child "activate" (lambda (w d) (if (not zecho-dialog) (let ((initial-zecho-scaler 0.5) (initial-zecho-delay 0.75) (initial-zecho-freq 6) (initial-zecho-amp 10.0) (sliders ())) (set! zecho-dialog (make-effect-dialog "Modulated echo" (lambda (w data) (map-chan-over-target-with-sync (lambda (input-samps) (zecho-1 zecho-scaler zecho-delay zecho-freq zecho-amp input-samps)) zecho-target (lambda (target input-samps) (format #f "effects-zecho-1 ~A ~A ~A ~A ~A" zecho-scaler zecho-delay zecho-freq zecho-amp (and (not (eq? target 'sound)) input-samps))) (and (not zecho-truncate) (* 4 zecho-delay)))) (lambda (w data) (help-dialog "Modulated echo" "Move the sliders to set the echo scaler, the delay time in seconds, the modulation frequency, and the echo amplitude.")) (lambda (w data) (set! zecho-scaler initial-zecho-scaler) (gtk_adjustment_set_value (GTK_ADJUSTMENT (sliders 0)) zecho-scaler) (set! zecho-delay initial-zecho-delay) (gtk_adjustment_set_value (GTK_ADJUSTMENT (sliders 1)) zecho-delay) (set! zecho-freq initial-zecho-freq) (gtk_adjustment_set_value (GTK_ADJUSTMENT (sliders 2)) zecho-freq) (set! zecho-amp initial-zecho-amp) (gtk_adjustment_set_value (GTK_ADJUSTMENT (sliders 3)) zecho-amp) ) (lambda () (effect-target-ok zecho-target)))) (set! sliders (add-sliders zecho-dialog (list (list "echo scaler" 0.0 initial-zecho-scaler 1.0 (lambda (w data) (set! zecho-scaler (gtk_adjustment_get_value (GTK_ADJUSTMENT (sliders 0))))) 100) (list "delay time (secs)" 0.0 initial-zecho-delay 3.0 (lambda (w data) (set! zecho-delay (gtk_adjustment_get_value (GTK_ADJUSTMENT (sliders 1))))) 100) (list "modulation frequency" 0.0 initial-zecho-freq 100.0 (lambda (w data) (set! zecho-freq (gtk_adjustment_get_value (GTK_ADJUSTMENT (sliders 2))))) 100) (list "modulation amplitude" 0.0 initial-zecho-amp 100.0 (lambda (w data) (set! zecho-amp (gtk_adjustment_get_value (GTK_ADJUSTMENT (sliders 3))))) 100)))) (add-target (gtk_dialog_get_content_area (GTK_DIALOG zecho-dialog)) (lambda (target) (set! zecho-target target) (gtk_widget_set_sensitive (GTK_WIDGET (g_object_get_data (G_OBJECT zecho-dialog) "ok-button")) (effect-target-ok target))) (lambda (truncate) (set! zecho-truncate truncate))))) (activate-dialog zecho-dialog)) #f) (set! delay-menu-list (cons (lambda () (let ((new-label (format #f "Modulated echo (~1,2F ~1,2F ~1,2F ~1,2F)" zecho-scaler zecho-delay zecho-freq zecho-amp))) (change-label child new-label))) delay-menu-list))) ) ;;; FILTERS ;;; (define* (effects-comb-filter scaler size beg dur snd chn) (let ((delay-line (make-float-vector size 0.0)) (delay-loc 0)) (lambda (x) (let ((result (delay-line delay-loc))) (set! (delay-line delay-loc) (+ x (* scaler result))) (set! delay-loc (+ 1 delay-loc)) (if (= delay-loc size) (set! delay-loc 0)) result)))) (define effects-comb-chord (let ((documentation "(effects-comb-chord scaler size amp interval-one interval-two beg dur snd chn) is used by the effects dialog to tie into edit-list->function")) (lambda* (scaler size amp interval-one interval-two beg dur snd chn) (let ((cs (make-comb-bank (vector (make-comb scaler size) (make-comb scaler (* size interval-one)) (make-comb scaler (* size interval-two)))))) (map-channel (lambda (x) (* amp (comb-bank cs x))) beg dur snd chn #f (format #f "effects-comb-chord ~A ~A ~A ~A ~A ~A ~A" scaler size amp interval-one interval-two beg dur)))))) (define* (effects-moog freq Q beg dur snd chn) (let ((gen (make-moog-filter freq Q))) (map-channel (lambda (inval) (moog-filter gen inval)) beg dur snd chn #f (format #f "effects-moog ~A ~A ~A ~A" freq Q beg dur)))) (define* (effects-bbp freq bw beg dur snd chn) (let ((flt (make-butter-band-pass freq bw))) (clm-channel flt beg dur snd chn #f #f (format #f "effects-bbp ~A ~A ~A ~A" freq bw beg dur)))) (define* (effects-bbr freq bw beg dur snd chn) (let ((flt (make-butter-band-reject freq bw))) (clm-channel flt beg dur snd chn #f #f (format #f "effects-bbr ~A ~A ~A ~A" freq bw beg dur)))) (define* (effects-bhp freq beg dur snd chn) (let ((flt (make-butter-high-pass freq))) (clm-channel flt beg dur snd chn #f #f (format #f "effects-bhp ~A ~A ~A" freq beg dur)))) (define* (effects-blp freq beg dur snd chn) (let ((flt (make-butter-low-pass freq))) (clm-channel flt beg dur snd chn #f #f (format #f "effects-blp ~A ~A ~A" freq beg dur)))) (let ((filter-menu-list ()) (filter-menu (gtk_menu_item_new_with_label "Filter Effects")) (filter-cascade (gtk_menu_new))) (gtk_menu_shell_append (GTK_MENU_SHELL (gtk_menu_item_get_submenu (GTK_MENU_ITEM (main-menu effects-menu)))) filter-menu) (gtk_widget_show filter-menu) (gtk_menu_item_set_submenu (GTK_MENU_ITEM filter-menu) filter-cascade) (g_signal_connect filter-menu "activate" (lambda (w d) (update-label filter-menu-list)) #f) ;; -------- Butterworth band-pass filter (let ((child (gtk_menu_item_new_with_label "Band-pass filter")) (band-pass-freq 1000) (band-pass-bw 100) (band-pass-dialog #f) (band-pass-target 'sound)) (gtk_menu_shell_append (GTK_MENU_SHELL filter-cascade) child) (gtk_widget_show child) (g_signal_connect child "activate" (lambda (w d) (if (not band-pass-dialog) (let ((initial-band-pass-freq 1000) (initial-band-pass-bw 100) (sliders ())) (set! band-pass-dialog (make-effect-dialog "Band-pass filter" (lambda (w data) (let ((flt (make-butter-band-pass band-pass-freq band-pass-bw))) (if (eq? band-pass-target 'sound) (filter-sound flt #f #f #f #f (format #f "effects-bbp ~A ~A 0 #f" band-pass-freq band-pass-bw)) (if (eq? band-pass-target 'selection) (filter-selection flt) (let* ((ms (plausible-mark-samples)) (bg (car ms)) (nd (+ 1 (- (cadr ms) (car ms))))) (clm-channel flt bg nd #f #f #f #f (format #f "effects-bbp ~A ~A ~A ~A" band-pass-freq band-pass-bw bg nd))))))) (lambda (w data) (help-dialog "Band-pass filter" "Butterworth band-pass filter. Move the sliders to change the center frequency and bandwidth.")) (lambda (w data) (set! band-pass-freq initial-band-pass-freq) (gtk_adjustment_set_value (GTK_ADJUSTMENT (sliders 0)) (scale-log->linear 20 band-pass-freq 22050)) (set! band-pass-bw initial-band-pass-bw) (gtk_adjustment_set_value (GTK_ADJUSTMENT (sliders 1)) band-pass-bw) ) (lambda () (effect-target-ok band-pass-target)))) (set! sliders (add-sliders band-pass-dialog (list (list "center frequency" 20 initial-band-pass-freq 22050 (lambda (w data) (set! band-pass-freq (scale-linear->log 20 (gtk_adjustment_get_value (GTK_ADJUSTMENT (car sliders))) 22050))) 1 'log) (list "bandwidth" 0 initial-band-pass-bw 1000 (lambda (w data) (set! band-pass-bw (gtk_adjustment_get_value (GTK_ADJUSTMENT (cadr sliders))))) 1)))) (add-target (gtk_dialog_get_content_area (GTK_DIALOG band-pass-dialog)) (lambda (target) (set! band-pass-target target) (gtk_widget_set_sensitive (GTK_WIDGET (g_object_get_data (G_OBJECT band-pass-dialog) "ok-button")) (effect-target-ok target))) #f))) (activate-dialog band-pass-dialog)) #f) (set! filter-menu-list (cons (lambda () (let ((new-label (format #f "Band-pass filter (~,2F ~D)" band-pass-freq band-pass-bw))) (change-label child new-label))) filter-menu-list))) ;; -------- Butterworth band-reject (notch) filter (let ((child (gtk_menu_item_new_with_label "Band-reject filter")) (notch-freq 100) (notch-bw 100) (notch-dialog #f) (notch-target 'sound)) (gtk_menu_shell_append (GTK_MENU_SHELL filter-cascade) child) (gtk_widget_show child) (g_signal_connect child "activate" (lambda (w d) (if (not notch-dialog) (let ((initial-notch-freq 100) (initial-notch-bw 100) (sliders ())) (set! notch-dialog (make-effect-dialog "Band-reject filter" (lambda (w data) (let ((flt (make-butter-band-reject notch-freq notch-bw))) (if (eq? notch-target 'sound) (filter-sound flt #f #f #f #f (format #f "effects-bbr ~A ~A 0 #f" notch-freq notch-bw)) (if (eq? notch-target 'selection) (filter-selection flt) (let* ((ms (plausible-mark-samples)) (bg (car ms)) (nd (+ 1 (- (cadr ms) (car ms))))) (clm-channel flt bg nd #f #f #f #f (format #f "effects-bbr ~A ~A ~A ~A" notch-freq notch-bw bg nd))))))) (lambda (w data) (help-dialog "Band-reject filter" "Butterworth band-reject filter. Move the sliders to change the center frequency and bandwidth.")) (lambda (w data) (set! notch-freq initial-notch-freq) (gtk_adjustment_set_value (GTK_ADJUSTMENT (sliders 0)) (scale-log->linear 20 notch-freq 22050)) (set! notch-bw initial-notch-bw) (gtk_adjustment_set_value (GTK_ADJUSTMENT (sliders 1)) notch-bw) ) (lambda () (effect-target-ok notch-target)))) (set! sliders (add-sliders notch-dialog (list (list "center frequency" 20 initial-notch-freq 22050 (lambda (w data) (set! notch-freq (scale-linear->log 20 (gtk_adjustment_get_value (GTK_ADJUSTMENT (car sliders))) 22050))) 1 'log) (list "bandwidth" 0 initial-notch-bw 1000 (lambda (w data) (set! notch-bw (gtk_adjustment_get_value (GTK_ADJUSTMENT (cadr sliders))))) 1)))) (add-target (gtk_dialog_get_content_area (GTK_DIALOG notch-dialog)) (lambda (target) (set! notch-target target) (gtk_widget_set_sensitive (GTK_WIDGET (g_object_get_data (G_OBJECT notch-dialog) "ok-button")) (effect-target-ok target))) #f))) (activate-dialog notch-dialog)) #f) (set! filter-menu-list (cons (lambda () (let ((new-label (format #f "Band-reject filter (~,2F ~D)" notch-freq notch-bw))) (change-label child new-label))) filter-menu-list))) ;; -------- Butterworth high-pass filter (let ((child (gtk_menu_item_new_with_label "High-pass filter")) (high-pass-freq 100) (high-pass-dialog #f) (high-pass-target 'sound)) (gtk_menu_shell_append (GTK_MENU_SHELL filter-cascade) child) (gtk_widget_show child) (g_signal_connect child "activate" (lambda (w d) (if (not high-pass-dialog) (let ((initial-high-pass-freq 100) (sliders ())) (set! high-pass-dialog (make-effect-dialog "High-pass filter" (lambda (w data) (let ((flt (make-butter-high-pass high-pass-freq))) (if (eq? high-pass-target 'sound) (filter-sound flt #f #f #f #f (format #f "effects-bhp ~A 0 #f" high-pass-freq)) (if (eq? high-pass-target 'selection) (filter-selection flt) (let* ((ms (plausible-mark-samples)) (bg (car ms)) (nd (+ 1 (- (cadr ms) (car ms))))) (clm-channel flt bg nd #f #f #f #f (format #f "effects-bhp ~A ~A ~A" high-pass-freq bg nd))))))) (lambda (w data) (help-dialog "High-pass filter" "Butterworth high-pass filter. Move the slider to change the high-pass cutoff frequency.")) (lambda (w data) (set! high-pass-freq initial-high-pass-freq) (gtk_adjustment_set_value (GTK_ADJUSTMENT (sliders 0)) (scale-log->linear 20 high-pass-freq 22050)) ) (lambda () (effect-target-ok high-pass-target)))) (set! sliders (add-sliders high-pass-dialog (list (list "high-pass cutoff frequency" 20 initial-high-pass-freq 22050 (lambda (w data) (set! high-pass-freq (scale-linear->log 20 (gtk_adjustment_get_value (GTK_ADJUSTMENT (sliders 0))) 22050))) 1 'log)))) (add-target (gtk_dialog_get_content_area (GTK_DIALOG high-pass-dialog)) (lambda (target) (set! high-pass-target target) (gtk_widget_set_sensitive (GTK_WIDGET (g_object_get_data (G_OBJECT high-pass-dialog) "ok-button")) (effect-target-ok target))) #f))) (activate-dialog high-pass-dialog)) #f) (set! filter-menu-list (cons (lambda () (let ((new-label (format #f "High-pass filter (~,2F)" high-pass-freq))) (change-label child new-label))) filter-menu-list))) ;; -------- Butterworth low-pass filter (let ((child (gtk_menu_item_new_with_label "Low-pass filter")) (low-pass-freq 1000) (low-pass-dialog #f) (low-pass-target 'sound)) (gtk_menu_shell_append (GTK_MENU_SHELL filter-cascade) child) (gtk_widget_show child) (g_signal_connect child "activate" (lambda (w d) (if (not low-pass-dialog) (let ((initial-low-pass-freq 1000) (sliders ())) (set! low-pass-dialog (make-effect-dialog "Low-pass filter" (lambda (w data) (let ((flt (make-butter-low-pass low-pass-freq))) (if (eq? low-pass-target 'sound) (filter-sound flt #f #f #f #f (format #f "effects-blp ~A 0 #f" low-pass-freq)) (if (eq? low-pass-target 'selection) (filter-selection flt) (let* ((ms (plausible-mark-samples)) (bg (car ms)) (nd (+ 1 (- (cadr ms) (car ms))))) (clm-channel flt bg nd #f #f #f #f (format #f "effects-blp ~A ~A ~A" low-pass-freq bg nd))))))) (lambda (w data) (help-dialog "Low-pass filter" "Butterworth low-pass filter. Move the slider to change the low-pass cutoff frequency.")) (lambda (w data) (set! low-pass-freq initial-low-pass-freq) (gtk_adjustment_set_value (GTK_ADJUSTMENT (sliders 0)) (scale-log->linear 20 low-pass-freq 22050)) ) (lambda () (effect-target-ok low-pass-target)))) (set! sliders (add-sliders low-pass-dialog (list (list "low-pass cutoff frequency" 20 initial-low-pass-freq 22050 (lambda (w data) (set! low-pass-freq (scale-linear->log 20 (gtk_adjustment_get_value (GTK_ADJUSTMENT (sliders 0))) 22050))) 1 'log)))) (add-target (gtk_dialog_get_content_area (GTK_DIALOG low-pass-dialog)) (lambda (target) (set! low-pass-target target) (gtk_widget_set_sensitive (GTK_WIDGET (g_object_get_data (G_OBJECT low-pass-dialog) "ok-button")) (effect-target-ok target))) #f))) (activate-dialog low-pass-dialog)) #f) (set! filter-menu-list (cons (lambda () (let ((new-label (format #f "Low-pass filter (~,2F)" low-pass-freq))) (change-label child new-label))) filter-menu-list))) ;; -------- Comb filter (let ((child (gtk_menu_item_new_with_label "Comb filter")) (comb-scaler 0.1) (comb-size 50) (comb-dialog #f) (comb-target 'sound)) (gtk_menu_shell_append (GTK_MENU_SHELL filter-cascade) child) (gtk_widget_show child) (g_signal_connect child "activate" (lambda (w d) (if (not comb-dialog) (let ((initial-comb-scaler 0.1) (initial-comb-size 50) (sliders ())) (set! comb-dialog (make-effect-dialog "Comb filter" (lambda (w data) (map-chan-over-target-with-sync (lambda (ignored) (effects-comb-filter comb-scaler comb-size)) comb-target (lambda (target samps) (format #f "effects-comb-filter ~A ~A" comb-scaler comb-size)) #f)) (lambda (w data) (help-dialog "Comb filter" "Move the sliders to change the comb scaler and size.")) (lambda (w data) (set! comb-scaler initial-comb-scaler) (gtk_adjustment_set_value (GTK_ADJUSTMENT (sliders 0)) comb-scaler) (set! comb-size initial-comb-size) (gtk_adjustment_set_value (GTK_ADJUSTMENT (sliders 1)) comb-size) ) (lambda () (effect-target-ok comb-target)))) (set! sliders (add-sliders comb-dialog (list (list "scaler" 0.0 initial-comb-scaler 1.0 (lambda (w data) (set! comb-scaler (gtk_adjustment_get_value (GTK_ADJUSTMENT (sliders 0))))) 100) (list "size" 0 initial-comb-size 100 (lambda (w data) (set! comb-size (gtk_adjustment_get_value (GTK_ADJUSTMENT (sliders 0))))) 1)))) (add-target (gtk_dialog_get_content_area (GTK_DIALOG comb-dialog)) (lambda (target) (set! comb-target target) (gtk_widget_set_sensitive (GTK_WIDGET (g_object_get_data (G_OBJECT comb-dialog) "ok-button")) (effect-target-ok target))) #f))) (activate-dialog comb-dialog)) #f) (set! filter-menu-list (cons (lambda () (let ((new-label (format #f "Comb filter (~1,2F ~D)" comb-scaler comb-size))) (change-label child new-label))) filter-menu-list))) ;; -------- Comb-chord filter (let ((child (gtk_menu_item_new_with_label "Comb chord filter")) (new-comb-chord-scaler 0.95) (new-comb-chord-size 60) (new-comb-chord-amp 0.3) (new-comb-chord-interval-one 0.75) (new-comb-chord-interval-two 1.20) (new-comb-chord-dialog #f) (new-comb-chord-target 'sound)) (define new-comb-chord (lambda (scaler size amp interval-one interval-two) ;; Comb chord filter: create chords by using filters at harmonically related sizes. (let ((cs (make-comb-bank (vector (make-comb scaler size) (make-comb scaler (* size interval-one)) (make-comb scaler (* size interval-two)))))) (lambda (x) (* amp (comb-bank cs x)))))) (gtk_menu_shell_append (GTK_MENU_SHELL filter-cascade) child) (gtk_widget_show child) (g_signal_connect child "activate" (lambda (w d) (if (not new-comb-chord-dialog) (let ((initial-new-comb-chord-scaler 0.95) (initial-new-comb-chord-size 60) (initial-new-comb-chord-amp 0.3) (initial-new-comb-chord-interval-one 0.75) (initial-new-comb-chord-interval-two 1.20) (sliders ())) (set! new-comb-chord-dialog (make-effect-dialog "Comb chord filter" (lambda (w data) (map-chan-over-target-with-sync (lambda (ignored) (new-comb-chord new-comb-chord-scaler new-comb-chord-size new-comb-chord-amp new-comb-chord-interval-one new-comb-chord-interval-two)) new-comb-chord-target (lambda (target samps) (format #f "effects-comb-chord ~A ~A ~A ~A ~A" new-comb-chord-scaler new-comb-chord-size new-comb-chord-amp new-comb-chord-interval-one new-comb-chord-interval-two)) #f)) (lambda (w data) (help-dialog "Comb chord filter" "Creates chords by using filters at harmonically related sizes. Move the sliders to set the comb chord parameters.")) (lambda (w data) (set! new-comb-chord-scaler initial-new-comb-chord-scaler) (gtk_adjustment_set_value (GTK_ADJUSTMENT (sliders 0)) new-comb-chord-scaler) (set! new-comb-chord-size initial-new-comb-chord-size) (gtk_adjustment_set_value (GTK_ADJUSTMENT (sliders 1)) new-comb-chord-size) (set! new-comb-chord-amp initial-new-comb-chord-amp) (gtk_adjustment_set_value (GTK_ADJUSTMENT (sliders 2)) new-comb-chord-amp) (set! new-comb-chord-interval-one initial-new-comb-chord-interval-one) (gtk_adjustment_set_value (GTK_ADJUSTMENT (sliders 3)) new-comb-chord-interval-one) (set! new-comb-chord-interval-two initial-new-comb-chord-interval-two) (gtk_adjustment_set_value (GTK_ADJUSTMENT (sliders 4)) new-comb-chord-interval-two) ) (lambda () (effect-target-ok new-comb-chord-target)))) (set! sliders (add-sliders new-comb-chord-dialog (list (list "chord scaler" 0.0 initial-new-comb-chord-scaler 1.0 (lambda (w data) (set! new-comb-chord-scaler (gtk_adjustment_get_value (GTK_ADJUSTMENT (sliders 0))))) 100) (list "chord size" 0 initial-new-comb-chord-size 100 (lambda (w data) (set! new-comb-chord-size (gtk_adjustment_get_value (GTK_ADJUSTMENT (sliders 1))))) 1) (list "amplitude" 0.0 initial-new-comb-chord-amp 1.0 (lambda (w data) (set! new-comb-chord-amp (gtk_adjustment_get_value (GTK_ADJUSTMENT (sliders 2))))) 100) (list "interval one" 0.0 initial-new-comb-chord-interval-one 2.0 (lambda (w data) (set! new-comb-chord-interval-one (gtk_adjustment_get_value (GTK_ADJUSTMENT (sliders 4))))) 100) (list "interval two" 0.0 initial-new-comb-chord-interval-two 2.0 (lambda (w data) (set! new-comb-chord-interval-two (gtk_adjustment_get_value (GTK_ADJUSTMENT (sliders 4))))) 100)))) (add-target (gtk_dialog_get_content_area (GTK_DIALOG new-comb-chord-dialog)) (lambda (target) (set! new-comb-chord-target target) (gtk_widget_set_sensitive (GTK_WIDGET (g_object_get_data (G_OBJECT new-comb-chord-dialog) "ok-button")) (effect-target-ok target))) #f))) (activate-dialog new-comb-chord-dialog)) #f) (set! filter-menu-list (cons (lambda () (let ((new-label (format #f "Comb chord filter (~1,2F ~D ~1,2F ~1,2F ~1,2F)" new-comb-chord-scaler new-comb-chord-size new-comb-chord-amp new-comb-chord-interval-one new-comb-chord-interval-two))) (change-label child new-label))) filter-menu-list))) ;; -------- Moog filter (let ((child (gtk_menu_item_new_with_label "Moog filter")) (moog-cutoff-frequency 10000) (moog-resonance 0.5) (moog-dialog #f) (moog-target 'sound)) (define (moog freq Q) (let ((gen (make-moog-filter freq Q))) (lambda (inval) (moog-filter gen inval)))) (gtk_menu_shell_append (GTK_MENU_SHELL filter-cascade) child) (gtk_widget_show child) (g_signal_connect child "activate" (lambda (w d) (if (not moog-dialog) (let ((initial-moog-cutoff-frequency 10000) (initial-moog-resonance 0.5) (sliders ())) (set! moog-dialog (make-effect-dialog "Moog filter" (lambda (w data) (map-chan-over-target-with-sync (lambda (ignored) (moog moog-cutoff-frequency moog-resonance)) moog-target (lambda (target samps) (format #f "effects-moog-filter ~A ~A" moog-cutoff-frequency moog-resonance)) #f)) (lambda (w data) (help-dialog "Moog filter" "Moog-style 4-pole lowpass filter with 24db/oct rolloff and variable resonance. Move the sliders to set the filter cutoff frequency and resonance.")) (lambda (w data) (set! moog-cutoff-frequency initial-moog-cutoff-frequency) (gtk_adjustment_set_value (GTK_ADJUSTMENT (car sliders)) (scale-log->linear 20 moog-cutoff-frequency 22050)) (set! moog-resonance initial-moog-resonance) (gtk_adjustment_set_value (GTK_ADJUSTMENT (cadr sliders)) moog-resonance) ) (lambda () (effect-target-ok moog-target)))) (set! sliders (add-sliders moog-dialog (list (list "cutoff frequency" 20 initial-moog-cutoff-frequency 22050 (lambda (w data) (set! moog-cutoff-frequency (scale-linear->log 20 (gtk_adjustment_get_value (GTK_ADJUSTMENT (sliders 0))) 22050))) 1 'log) (list "resonance" 0.0 initial-moog-resonance 1.0 (lambda (w data) (set! moog-resonance (gtk_adjustment_get_value (GTK_ADJUSTMENT (sliders 1))))) 100)))) (add-target (gtk_dialog_get_content_area (GTK_DIALOG moog-dialog)) (lambda (target) (set! moog-target target) (gtk_widget_set_sensitive (GTK_WIDGET (g_object_get_data (G_OBJECT moog-dialog) "ok-button")) (effect-target-ok target))) #f))) (activate-dialog moog-dialog)) #f) (set! filter-menu-list (cons (lambda () (let ((new-label (format #f "Moog filter (~,2F ~1,2F)" moog-cutoff-frequency moog-resonance))) (change-label child new-label))) filter-menu-list))) ) ;;; FREQUENCY EFFECTS (let ((freq-menu-list ()) (freq-menu (gtk_menu_item_new_with_label "Frequency Effects")) (freq-cascade (gtk_menu_new))) (gtk_menu_shell_append (GTK_MENU_SHELL (gtk_menu_item_get_submenu (GTK_MENU_ITEM (main-menu effects-menu)))) freq-menu) (gtk_widget_show freq-menu) (gtk_menu_item_set_submenu (GTK_MENU_ITEM freq-menu) freq-cascade) (g_signal_connect freq-menu "activate" (lambda (w d) (update-label freq-menu-list)) #f) ;; -------- Sample rate conversion (resample) (let ((child (gtk_menu_item_new_with_label "Sample rate conversion")) (src-amount 0.0) (src-dialog #f) (src-target 'sound)) (gtk_menu_shell_append (GTK_MENU_SHELL freq-cascade) child) (gtk_widget_show child) (g_signal_connect child "activate" (lambda (w d) (if (not src-dialog) (let ((initial-src-amount 0.0) (sliders ())) (set! src-dialog (make-effect-dialog "Sample rate conversion" (lambda (w data) (if (eq? src-target 'sound) (src-sound src-amount) (if (eq? src-target 'selection) (if (selection?) (src-selection src-amount) (snd-print "no selection")) (snd-print "can't apply src between marks yet")))) (lambda (w data) (help-dialog "Sample rate conversion" "Move the slider to change the sample rate. Values greater than 1.0 speed up file play, negative values reverse it.")) (lambda (w data) (set! src-amount initial-src-amount) (gtk_adjustment_set_value (GTK_ADJUSTMENT (car sliders)) src-amount) ) (lambda () (effect-target-ok src-target)))) (set! sliders (add-sliders src-dialog (list (list "sample rate" -2.0 initial-src-amount 2.0 (lambda (w data) (set! src-amount (gtk_adjustment_get_value (GTK_ADJUSTMENT (sliders 0))))) 100)))) (add-target (gtk_dialog_get_content_area (GTK_DIALOG src-dialog)) (lambda (target) (set! src-target target) (gtk_widget_set_sensitive (GTK_WIDGET (g_object_get_data (G_OBJECT src-dialog) "ok-button")) (effect-target-ok target))) #f))) (activate-dialog src-dialog)) #f) (set! freq-menu-list (cons (lambda () (let ((new-label (format #f "Sample rate scaling (~1,2F)" src-amount))) (change-label child new-label))) freq-menu-list))) ;; -------- Time and pitch scaling by granular synthesis and sampling rate conversion (let ((child (gtk_menu_item_new_with_label "Time/pitch scaling")) (time-scale 1.0) (hop-size 0.05) (segment-length 0.15) (ramp-scale 0.5) (pitch-scale 1.0) (expsrc-dialog #f) (expsrc-target 'sound)) (gtk_menu_shell_append (GTK_MENU_SHELL freq-cascade) child) (gtk_widget_show child) (g_signal_connect child "activate" (lambda (w d) (if (not expsrc-dialog) (let ((initial-time-scale 1.0) (initial-hop-size 0.05) (initial-segment-length 0.15) (initial-ramp-scale 0.5) (initial-pitch-scale 1.0) (sliders ())) (set! expsrc-dialog (make-effect-dialog "Time/pitch scaling" (lambda (w data) (let ((snd (selected-sound))) (save-controls snd) (reset-controls snd) (set! (speed-control snd) pitch-scale) (let ((new-time (* pitch-scale time-scale))) (if (not (= new-time 1.0)) (begin (set! (expand-control? snd) #t) (set! (expand-control snd) new-time) (set! (expand-control-hop snd) hop-size) (set! (expand-control-length snd) segment-length) (set! (expand-control-ramp snd) ramp-scale)))) (if (eq? expsrc-target 'marks) (let ((ms (plausible-mark-samples))) (apply-controls snd 0 (car ms) (+ 1 (- (cadr ms) (car ms))))) (apply-controls snd (if (eq? expsrc-target 'sound) 0 2))) (restore-controls snd))) (lambda (w data) (help-dialog "Time/pitch scaling" "Move the sliders to change the time/pitch scaling parameters.")) (lambda (w data) (set! time-scale initial-time-scale) (gtk_adjustment_set_value (GTK_ADJUSTMENT (sliders 0)) time-scale) (set! hop-size initial-hop-size) (gtk_adjustment_set_value (GTK_ADJUSTMENT (sliders 1)) hop-size) (set! segment-length initial-segment-length) (gtk_adjustment_set_value (GTK_ADJUSTMENT (sliders 2)) segment-length) (set! ramp-scale initial-ramp-scale) (gtk_adjustment_set_value (GTK_ADJUSTMENT (sliders 3)) ramp-scale) (set! pitch-scale initial-pitch-scale) (gtk_adjustment_set_value (GTK_ADJUSTMENT (sliders 4)) pitch-scale) ) (lambda () (effect-target-ok expsrc-target)))) (set! sliders (add-sliders expsrc-dialog (list (list "time scale" 0.0 initial-time-scale 5.0 (lambda (w data) (set! time-scale (gtk_adjustment_get_value (GTK_ADJUSTMENT (sliders 0))))) 100) (list "hop size" 0.0 initial-hop-size 1.0 (lambda (w data) (set! hop-size (gtk_adjustment_get_value (GTK_ADJUSTMENT (sliders 1))))) 100) (list "segment length" 0.0 initial-segment-length 0.5 (lambda (w data) (set! segment-length (gtk_adjustment_get_value (GTK_ADJUSTMENT (sliders 2))))) 100) (list "ramp scale" 0.0 initial-ramp-scale 0.5 (lambda (w data) (set! ramp-scale (gtk_adjustment_get_value (GTK_ADJUSTMENT (sliders 3))))) 1000) (list "pitch scale" 0.0 initial-pitch-scale 5.0 (lambda (w data) (set! pitch-scale (gtk_adjustment_get_value (GTK_ADJUSTMENT (sliders 4))))) 100)))) (add-target (gtk_dialog_get_content_area (GTK_DIALOG expsrc-dialog)) (lambda (target) (set! expsrc-target target) (gtk_widget_set_sensitive (GTK_WIDGET (g_object_get_data (G_OBJECT expsrc-dialog) "ok-button")) (effect-target-ok target))) #f))) (activate-dialog expsrc-dialog)) #f) (set! freq-menu-list (cons (lambda () (let ((new-label (format #f "Time/pitch scaling (~1,2F ~1,2F)" time-scale pitch-scale))) (change-label child new-label))) freq-menu-list))) ;;; -------- Time-varying sample rate conversion (resample) ;;; (KSM) (let ((child (gtk_menu_item_new_with_label "Src-timevar")) (src-timevar-scale 1.0) (src-timevar-dialog #f) (src-timevar-target 'sound) (src-timevar-envelope #f)) (define (scale-envelope e scl) (if (null? e) () (append (list (car e) (* scl (cadr e))) (scale-envelope (cddr e) scl)))) (gtk_menu_shell_append (GTK_MENU_SHELL freq-cascade) child) (gtk_widget_show child) (g_signal_connect child "activate" (lambda (w d) (if (not src-timevar-dialog) (let ((initial-src-timevar-scale 1.0) (sliders ())) (set! src-timevar-dialog (make-effect-dialog "Src-Timevar" (lambda (w data) (let ((env (scale-envelope (xe-envelope src-timevar-envelope) src-timevar-scale))) (if (eq? src-timevar-target 'sound) (src-sound env) (if (eq? src-timevar-target 'selection) (if (selection-member? (selected-sound)) (src-selection env) (display "no selection")) (let ((pts (plausible-mark-samples))) (if pts (let* ((beg (car pts)) (end (cadr pts)) (len (- end beg))) (src-channel (make-env env :length len) beg len (selected-sound))))))))) (lambda (w data) (help-dialog "Src-Timevar" "Move the slider to change the src-timevar scaling amount.")) (lambda (w data) (set! src-timevar-amount initial-src-timevar-scale) (set! (xe-envelope src-timevar-envelope) (list 0.0 1.0 1.0 1.0)) (gtk_adjustment_set_value (GTK_ADJUSTMENT (car sliders)) src-timevar-scale) ) (lambda () (effect-target-ok src-timevar-target)))) (set! sliders (add-sliders src-timevar-dialog (list (list "Resample factor" 0.0 initial-src-timevar-scale 10.0 (lambda (w data) (set! src-timevar-scale (gtk_adjustment_get_value (GTK_ADJUSTMENT w)))) 100)))) (gtk_widget_show src-timevar-dialog) (set! src-timevar-envelope (xe-create-enved "src-timevar" (gtk_dialog_get_content_area (GTK_DIALOG src-timevar-dialog)) #f '(0.0 1.0 0.0 1.0))) (set! (xe-envelope src-timevar-envelope) (list 0.0 1.0 1.0 1.0)) (add-target (gtk_dialog_get_content_area (GTK_DIALOG src-timevar-dialog)) (lambda (target) (set! src-timevar-target target) (gtk_widget_set_sensitive (GTK_WIDGET (g_object_get_data (G_OBJECT src-timevar-dialog) "ok-button")) (effect-target-ok target))) #f))) (activate-dialog src-timevar-dialog)) #f) (set! freq-menu-list (cons (lambda () (let ((new-label "Src-Timevar")) (change-label child new-label))) freq-menu-list))) ) ;;; MODULATION EFFECTS (define* (effects-am freq en beg dur snd chn) (let ((os (make-oscil freq)) (e (and en (make-env en :length dur)))) (map-channel (if e (lambda (inval) (amplitude-modulate 1.0 inval (* (env e) (oscil os)))) (lambda (inval) (amplitude-modulate 1.0 inval (oscil os)))) beg dur snd chn #f (format #f "effects-am ~A ~A ~A ~A" freq (and en (format #f "'~A" en)) beg dur)))) (define* (effects-rm freq gliss-env beg dur snd chn) (let ((os (make-oscil freq)) (e (and gliss-env (make-env gliss-env :length dur)))) (map-channel (if e (lambda (inval) (* inval (env e) (oscil os))) (lambda (inval) (* inval (oscil os)))) beg dur snd chn #f (format #f "effects-rm ~A ~A ~A ~A" freq (and gliss-env (format #f "'~A" gliss-env)) beg dur)))) (let ((mod-menu-list ()) (mod-menu (gtk_menu_item_new_with_label "Modulation Effects")) (mod-cascade (gtk_menu_new))) (gtk_menu_shell_append (GTK_MENU_SHELL (gtk_menu_item_get_submenu (GTK_MENU_ITEM (main-menu effects-menu)))) mod-menu) (gtk_widget_show mod-menu) (gtk_menu_item_set_submenu (GTK_MENU_ITEM mod-menu) mod-cascade) (g_signal_connect mod-menu "activate" (lambda (w d) (update-label mod-menu-list)) #f) ;; -------- Amplitude modulation (let ((child (gtk_menu_item_new_with_label "Amplitude modulation")) (am-effect-amount 100.0) (am-effect-dialog #f) (am-effect-target 'sound) (am-effect-envelope #f)) (define am-effect (lambda (freq) (let* ((os (make-oscil freq)) (need-env (not (equal? (xe-envelope am-effect-envelope) (list 0.0 1.0 1.0 1.0)))) (e (and need-env (make-env (xe-envelope am-effect-envelope) :length (effect-framples am-effect-target))))) (if need-env (lambda (inval) (amplitude-modulate 1.0 inval (* (env e) (oscil os)))) (lambda (inval) (amplitude-modulate 1.0 inval (oscil os))))))) (gtk_menu_shell_append (GTK_MENU_SHELL mod-cascade) child) (gtk_widget_show child) (g_signal_connect child "activate" (lambda (w d) (if (not am-effect-dialog) (let ((initial-am-effect-amount 100.0) (sliders ())) (set! am-effect-dialog (make-effect-dialog "Amplitude modulation" (lambda (w data) (map-chan-over-target-with-sync (lambda (ignored) (am-effect am-effect-amount)) am-effect-target (lambda (target samps) (format #f "effects-am ~A ~A" am-effect-amount (let* ((need-env (not (equal? (xe-envelope am-effect-envelope) (list 0.0 1.0 1.0 1.0)))) (e (and need-env (xe-envelope am-effect-envelope)))) (and e (format #f "'~A" e))))) #f)) (lambda (w data) (help-dialog "Amplitude modulation" "Move the slider to change the modulation amount.")) (lambda (w data) (set! am-effect-amount initial-am-effect-amount) (set! (xe-envelope am-effect-envelope) (list 0.0 1.0 1.0 1.0)) (gtk_adjustment_set_value (GTK_ADJUSTMENT (car sliders)) am-effect-amount) ) (lambda () (effect-target-ok am-effect-target)))) (set! sliders (add-sliders am-effect-dialog (list (list "amplitude modulation" 0.0 initial-am-effect-amount 1000.0 (lambda (w data) (set! am-effect-amount (gtk_adjustment_get_value (GTK_ADJUSTMENT (sliders 0))))) 1)))) (gtk_widget_show am-effect-dialog) (set! am-effect-envelope (xe-create-enved "am" (gtk_dialog_get_content_area (GTK_DIALOG am-effect-dialog)) #f '(0.0 1.0 0.0 1.0))) (set! (xe-envelope am-effect-envelope) (list 0.0 1.0 1.0 1.0)) (add-target (gtk_dialog_get_content_area (GTK_DIALOG am-effect-dialog)) (lambda (target) (set! am-effect-target target) (gtk_widget_set_sensitive (GTK_WIDGET (g_object_get_data (G_OBJECT am-effect-dialog) "ok-button")) (effect-target-ok target))) #f))) (activate-dialog am-effect-dialog)) #f) (set! mod-menu-list (cons (lambda () (let ((new-label (format #f "Amplitude modulation (~1,2F)" am-effect-amount))) (change-label child new-label))) mod-menu-list))) ;; -------- Ring modulation (let ((child (gtk_menu_item_new_with_label "Ring modulation")) (rm-frequency 100) (rm-radians 100) (rm-dialog #f) (rm-target 'sound) (rm-envelope #f)) (define rm-effect ; avoid collision with examp.scm (lambda (freq gliss-env) (let* ((os (make-oscil freq)) (need-env (and rm-envelope (not (equal? (xe-envelope rm-envelope) (list 0.0 1.0 1.0 1.0))))) (e (and need-env (make-env (xe-envelope rm-envelope) :length (effect-framples rm-target)))) (len (framples)) (genv (make-env :envelope gliss-env :length len))) (if need-env (lambda (inval) (* inval (env e) (oscil os (env genv)))) (lambda (inval) (* inval (oscil os (env genv)))))))) (gtk_menu_shell_append (GTK_MENU_SHELL mod-cascade) child) (gtk_widget_show child) (g_signal_connect child "activate" (lambda (w d) (if (not rm-dialog) (let ((initial-rm-frequency 100) (initial-rm-radians 100) (sliders ())) (set! rm-dialog (make-effect-dialog "Ring modulation" (lambda (w data) (map-chan-over-target-with-sync (lambda (ignored) (rm-effect rm-frequency (list 0 0 1 (hz->radians rm-radians)))) rm-target (lambda (target samps) (format #f "effects-rm ~A ~A" rm-frequency (let* ((need-env (not (equal? (xe-envelope rm-envelope) (list 0.0 1.0 1.0 1.0)))) (e (and need-env (xe-envelope rm-envelope)))) (and e (format #f "'~A" e))))) #f)) (lambda (w data) (help-dialog "Ring modulation" "Move the slider to change the ring modulation parameters.")) (lambda (w data) (set! rm-frequency initial-rm-frequency) (set! (xe-envelope rm-envelope) (list 0.0 1.0 1.0 1.0)) (gtk_adjustment_set_value (GTK_ADJUSTMENT (car sliders)) rm-frequency) (set! rm-radians initial-rm-radians) (gtk_adjustment_set_value (GTK_ADJUSTMENT (cadr sliders)) rm-radians) ) (lambda () (effect-target-ok rm-target)))) (set! sliders (add-sliders rm-dialog (list (list "modulation frequency" 0 initial-rm-frequency 1000 (lambda (w data) (set! rm-frequency (gtk_adjustment_get_value (GTK_ADJUSTMENT (sliders 0))))) 1) (list "modulation radians" 0 initial-rm-radians 360 (lambda (w data) (set! rm-radians (gtk_adjustment_get_value (GTK_ADJUSTMENT (sliders 1))))) 1)))) (gtk_widget_show rm-dialog) (set! rm-envelope (xe-create-enved "rm frequency" (gtk_dialog_get_content_area (GTK_DIALOG rm-dialog)) #f '(0.0 1.0 0.0 1.0))) (set! (xe-envelope rm-envelope) (list 0.0 1.0 1.0 1.0)) (add-target (gtk_dialog_get_content_area (GTK_DIALOG rm-dialog)) (lambda (target) (set! rm-target target) (gtk_widget_set_sensitive (GTK_WIDGET (g_object_get_data (G_OBJECT rm-dialog) "ok-button")) (effect-target-ok target))) #f))) (activate-dialog rm-dialog)) #f) (set! mod-menu-list (cons (lambda () (let ((new-label (format #f "Ring modulation (~D ~D)" rm-frequency rm-radians))) (change-label child new-label))) mod-menu-list))) ) ;;; REVERBS (define* (effects-cnv snd0-1 amp snd chn) (let* ((snd0 (if (sound? snd0-1) snd0-1 (car (sounds)))) (flt-len (framples snd0)) (total-len (+ flt-len (framples snd chn))) (cnv (make-convolve :filter (channel->float-vector 0 flt-len snd0) :input (make-sampler 0 snd chn))) (out-data (make-float-vector total-len))) (do ((i 0 (+ i 1))) ((= i total-len)) (set! (out-data i) (convolve cnv))) (float-vector-scale! out-data amp) (let ((max-samp (float-vector-peak out-data))) (float-vector->channel out-data 0 total-len snd chn #f (format #f "effects-cnv ~A ~A" snd0 amp)) (if (> max-samp 1.0) (set! (y-bounds snd chn) (list (- max-samp) max-samp))) max-samp))) (define (effects-jc-reverb input-samps volume) (let ((allpass1 (make-all-pass -0.700 0.700 1051)) (allpass2 (make-all-pass -0.700 0.700 337)) (allpass3 (make-all-pass -0.700 0.700 113)) (comb1 (make-comb 0.742 4799)) (comb2 (make-comb 0.733 4999)) (comb3 (make-comb 0.715 5399)) (comb4 (make-comb 0.697 5801)) (outdel1 (make-delay (round (* .013 (srate))))) (e (make-env '(0 1 1 0) :scaler volume :base 0.0 :length input-samps))) (let ((combs (make-comb-bank (vector comb1 comb2 comb3 comb4))) (allpasses (make-all-pass-bank (vector allpass1 allpass2 allpass3)))) (lambda (inval) (+ inval (* volume (delay outdel1 (comb-bank combs (all-pass-bank allpasses (* (env e) inval)))))))))) (define* (effects-jc-reverb-1 volume beg dur snd chn) (map-channel (effects-jc-reverb (or dur (framples snd chn)) volume) beg dur snd chn #f (format #f "effects-jc-reverb-1 ~A ~A ~A" volume beg dur))) (let ((reverb-menu-list ()) (reverb-menu (gtk_menu_item_new_with_label "Reverberation")) (reverb-cascade (gtk_menu_new))) (gtk_menu_shell_append (GTK_MENU_SHELL (gtk_menu_item_get_submenu (GTK_MENU_ITEM (main-menu effects-menu)))) reverb-menu) (gtk_widget_show reverb-menu) (gtk_menu_item_set_submenu (GTK_MENU_ITEM reverb-menu) reverb-cascade) (g_signal_connect reverb-menu "activate" (lambda (w d) (update-label reverb-menu-list)) #f) ;; -------- Reverb from Michael McNabb's Nrev (let ((child (gtk_menu_item_new_with_label "McNabb reverb")) (reverb-amount 0.1) (reverb-filter 0.5) (reverb-feedback 1.09) (reverb-dialog #f) (reverb-target 'sound)) (gtk_menu_shell_append (GTK_MENU_SHELL reverb-cascade) child) (gtk_widget_show child) (g_signal_connect child "activate" (lambda (w d) ;; add reverb-control-decay (with ramp?) and reverb-truncate (if (not reverb-dialog) (let ((initial-reverb-amount 0.1) (initial-reverb-filter 0.5) (initial-reverb-feedback 1.09) (sliders ())) (set! reverb-dialog (make-effect-dialog "McNabb reverb" (lambda (w data) (let ((snd (selected-sound))) (save-controls snd) (reset-controls snd) (set! (reverb-control? snd) #t) (set! (reverb-control-scale snd) reverb-amount) (set! (reverb-control-lowpass snd) reverb-filter) (set! (reverb-control-feedback snd) reverb-feedback) (if (eq? reverb-target 'marks) (let ((ms (plausible-mark-samples))) (apply-controls snd 0 (car ms) (+ 1 (- (cadr ms) (car ms))))) (apply-controls snd (if (eq? reverb-target 'sound) 0 2))) (restore-controls snd))) (lambda (w data) (help-dialog "McNabb reverb" "Reverberator from Michael McNabb. Adds reverberation scaled by reverb amount, lowpass filtering, and feedback. Move the sliders to change the reverb parameters.")) (lambda (w data) (set! reverb-amount initial-reverb-amount) (gtk_adjustment_set_value (GTK_ADJUSTMENT (car sliders)) reverb-amount) (set! reverb-filter initial-reverb-filter) (gtk_adjustment_set_value (GTK_ADJUSTMENT (cadr sliders)) reverb-filter) (set! reverb-feedback initial-reverb-feedback) (gtk_adjustment_set_value (GTK_ADJUSTMENT (caddr sliders)) reverb-feedback) ) (lambda () (effect-target-ok reverb-target)))) (set! sliders (add-sliders reverb-dialog (list (list "reverb amount" 0.0 initial-reverb-amount 1.0 (lambda (w data) (set! reverb-amount (gtk_adjustment_get_value (GTK_ADJUSTMENT (sliders 0))))) 100) (list "reverb filter" 0.0 initial-reverb-filter 1.0 (lambda (w data) (set! reverb-filter (gtk_adjustment_get_value (GTK_ADJUSTMENT (sliders 1))))) 100) (list "reverb feedback" 0.0 initial-reverb-feedback 1.25 (lambda (w data) (set! reverb-feedback (gtk_adjustment_get_value (GTK_ADJUSTMENT (sliders 2))))) 100)))) (add-target (gtk_dialog_get_content_area (GTK_DIALOG reverb-dialog)) (lambda (target) (set! reverb-target target) (gtk_widget_set_sensitive (GTK_WIDGET (g_object_get_data (G_OBJECT reverb-dialog) "ok-button")) (effect-target-ok target))) #f))) (activate-dialog reverb-dialog)) #f) (set! reverb-menu-list (cons (lambda () (let ((new-label (format #f "McNabb reverb (~1,2F ~1,2F ~1,2F)" reverb-amount reverb-filter reverb-feedback))) (change-label child new-label))) reverb-menu-list))) ;; -------- Chowning reverb (let ((child (gtk_menu_item_new_with_label "Chowning reverb")) (jc-reverb-decay 2.0) (jc-reverb-volume 0.1) (jc-reverb-dialog #f) (jc-reverb-target 'sound) (jc-reverb-truncate #t)) (gtk_menu_shell_append (GTK_MENU_SHELL reverb-cascade) child) (gtk_widget_show child) (g_signal_connect child "activate" (lambda (w d) (if (not jc-reverb-dialog) (let ((initial-jc-reverb-decay 2.0) (initial-jc-reverb-volume 0.1) (sliders ())) (set! jc-reverb-dialog (make-effect-dialog "Chowning reverb" (lambda (w data) (map-chan-over-target-with-sync (lambda (samps) (effects-jc-reverb samps jc-reverb-volume)) jc-reverb-target (lambda (target samps) (format #f "effects-jc-reverb-1 ~A" jc-reverb-volume)) (and (not jc-reverb-truncate) jc-reverb-decay))) (lambda (w data) (help-dialog "Chowning reverb" "Nice reverb from John Chowning. Move the sliders to set the reverb parameters.")) (lambda (w data) (set! jc-reverb-decay initial-jc-reverb-decay) (gtk_adjustment_set_value (GTK_ADJUSTMENT (sliders 0)) jc-reverb-decay) (set! jc-reverb-volume initial-jc-reverb-volume) (gtk_adjustment_set_value (GTK_ADJUSTMENT (sliders 1)) jc-reverb-volume) ) (lambda () (effect-target-ok jc-reverb-target)))) (set! sliders (add-sliders jc-reverb-dialog (list (list "decay duration" 0.0 initial-jc-reverb-decay 10.0 (lambda (w data) (set! jc-reverb-decay (gtk_adjustment_get_value (GTK_ADJUSTMENT (sliders 0))))) 100) (list "reverb volume" 0.0 initial-jc-reverb-volume 1.0 (lambda (w data) (set! jc-reverb-volume (gtk_adjustment_get_value (GTK_ADJUSTMENT (sliders 1))))) 100)))) (add-target (gtk_dialog_get_content_area (GTK_DIALOG jc-reverb-dialog)) (lambda (target) (set! jc-reverb-target target) (gtk_widget_set_sensitive (GTK_WIDGET (g_object_get_data (G_OBJECT jc-reverb-dialog) "ok-button")) (effect-target-ok target))) (lambda (truncate) (set! jc-reverb-truncate truncate))))) (activate-dialog jc-reverb-dialog)) #f) (set! reverb-menu-list (cons (lambda () (let ((new-label (format #f "Chowning reverb (~1,2F ~1,2F)" jc-reverb-decay jc-reverb-volume))) (change-label child new-label))) reverb-menu-list))) ;; -------- Convolution (let ((child (gtk_menu_item_new_with_label "Convolution")) (convolve-sound-one 0) (convolve-sound-two 1) (convolve-amp 0.01) (convolve-dialog #f)) (gtk_menu_shell_append (GTK_MENU_SHELL reverb-cascade) child) (gtk_widget_show child) (g_signal_connect child "activate" (lambda (w d) (if (not convolve-dialog) (let ((initial-convolve-sound-one 0) (initial-convolve-sound-two 1) (initial-convolve-amp 0.01) (sliders ())) (set! convolve-dialog (make-effect-dialog "Convolution" (lambda (w data) (effects-cnv convolve-sound-one convolve-amp convolve-sound-two)) (lambda (w data) (help-dialog "Convolution" "Very simple convolution. Move the sliders to set the numbers of the soundfiles to be convolved and the amount for the amplitude scaler. Output will be scaled to floating-point values, resulting in very large (but not clipped) amplitudes. Use the Normalize amplitude effect to rescale the output. The convolution data file typically defines a natural reverberation source, and the output from this effect can provide very striking reverb effects. You can find convolution data files on sites listed at http://www.bright.net/~dlphilp/linux_csound.html under Impulse Response Data.")) (lambda (w data) (set! convolve-sound-one initial-convolve-sound-one) (gtk_adjustment_set_value (GTK_ADJUSTMENT (sliders 0)) convolve-sound-one) (set! convolve-sound-two initial-convolve-sound-two) (gtk_adjustment_set_value (GTK_ADJUSTMENT (sliders 1)) convolve-sound-two) (set! convolve-amp initial-convolve-amp) (gtk_adjustment_set_value (GTK_ADJUSTMENT (sliders 2)) convolve-amp) ))) (set! sliders (add-sliders convolve-dialog (list (list "impulse response file" 0 initial-convolve-sound-one 24 (lambda (w data) (set! convolve-sound-one (gtk_adjustment_get_value (GTK_ADJUSTMENT (sliders 0))))) 1) (list "sound file" 0 initial-convolve-sound-two 24 (lambda (w data) (set! convolve-sound-two (gtk_adjustment_get_value (GTK_ADJUSTMENT (sliders 1))))) 1) (list "amplitude" 0.0 initial-convolve-amp 0.10 (lambda (w data) (set! convolve-amp (gtk_adjustment_get_value (GTK_ADJUSTMENT (sliders 2))))) 1000)))))) (activate-dialog convolve-dialog)) #f) (set! reverb-menu-list (cons (lambda () (let ((new-label (format #f "Convolution (~D ~D ~1,2F)" convolve-sound-one convolve-sound-two convolve-amp))) (change-label child new-label))) reverb-menu-list))) ) ;;; VARIOUS AND MISCELLANEOUS (define effects-hello-dentist (let ((documentation "(hello-dentist frq amp snd chn) varies the sampling rate randomly, making a voice sound quavery: (hello-dentist 40.0 .1)")) (lambda* (frq amp beg dur snd chn) (let* ((rn (make-rand-interp :frequency frq :amplitude amp)) (len (or dur (- (framples snd chn) beg))) (sf (make-sampler beg snd chn)) (rd (make-src :srate 1.0 :input (lambda (dir) (read-sample-with-direction sf dir))))) (map-channel (lambda (y) (src rd (rand-interp rn))) beg len snd chn #f (format #f "effects-hello-dentist ~A ~A ~A ~A" frq amp beg (and (not (= len (framples snd chn))) len))))))) (define* (effects-fp sr osamp osfrq beg dur snd chn) (let* ((os (make-oscil osfrq)) (len (framples snd chn)) (sf (make-sampler beg snd chn)) (s (make-src :srate sr :input (lambda (dir) (read-sample-with-direction sf dir))))) (map-channel (lambda (y) (src s (* osamp (oscil os)))) beg len snd chn #f (format #f "effects-fp ~A ~A ~A ~A ~A" sr osamp osfrq beg (and (not (= len (framples snd chn))) len))))) (define* (effects-position-sound mono-snd pos snd chn) (let ((len (framples mono-snd)) (reader1 (make-sampler 0 mono-snd))) (if (number? pos) (map-channel (lambda (y) (+ y (* pos (read-sample reader1)))) 0 len snd chn #f (format #f "effects-position-sound ~A ~A" mono-snd pos)) (let ((e1 (make-env pos :length len))) (if (and (number? chn) (= chn 1)) (map-channel (lambda (y) (+ y (* (env e1) (read-sample reader1)))) 0 len snd chn #f (format #f "effects-position-sound ~A '~A" mono-snd pos)) (map-channel (lambda (y) (+ y (* (- 1.0 (env e1)) (read-sample reader1)))) 0 len snd chn #f (format #f "effects-position-sound ~A '~A" mono-snd pos))))))) (define* (effects-flange amount speed time beg dur snd chn) (let* ((ri (make-rand-interp :frequency speed :amplitude amount)) (len (round (* time (srate snd)))) (del (make-delay len :max-size (round (+ len amount 1))))) (map-channel (lambda (inval) (* .75 (+ inval (delay del inval (rand-interp ri))))) beg dur snd chn #f (format #f "effects-flange ~A ~A ~A ~A ~A" amount speed time beg (and (number? dur) (not (= dur (framples snd chn))) dur))))) (define (effects-cross-synthesis cross-snd amp fftsize r) ;; cross-snd is the index of the other sound (as opposed to the map-channel sound) (let* ((freq-inc (/ fftsize 2)) (fdr #f) (fdi (make-float-vector fftsize)) (spectr (make-float-vector freq-inc)) (inctr 0) (ctr freq-inc) (radius (- 1.0 (/ r fftsize))) (bin (/ (srate) fftsize)) (formants (make-vector freq-inc))) (do ((i 0 (+ 1 i))) ((= i freq-inc)) (set! (formants i) (make-formant (* i bin) radius))) (set! formants (make-formant-bank formants spectr)) (lambda (inval) (if (= ctr freq-inc) (begin (set! fdr (channel->float-vector inctr fftsize cross-snd 0)) (set! inctr (+ inctr freq-inc)) (spectrum fdr fdi #f 2) (float-vector-subtract! fdr spectr) (float-vector-scale! fdr (/ 1.0 freq-inc)) (set! ctr 0))) (set! ctr (+ ctr 1)) (float-vector-add! spectr fdr) (* amp (formant-bank formants inval))))) (define* (effects-cross-synthesis-1 cross-snd amp fftsize r beg dur snd chn) (map-channel (effects-cross-synthesis (if (sound? cross-snd) cross-snd (car (sounds))) amp fftsize r) beg dur snd chn #f (format #f "effects-cross-synthesis-1 ~A ~A ~A ~A ~A ~A" cross-snd amp fftsize r beg dur))) (let ((misc-menu-list ()) (misc-menu (gtk_menu_item_new_with_label "Various")) (misc-cascade (gtk_menu_new))) (gtk_menu_shell_append (GTK_MENU_SHELL (gtk_menu_item_get_submenu (GTK_MENU_ITEM (main-menu effects-menu)))) misc-menu) (gtk_widget_show misc-menu) (gtk_menu_item_set_submenu (GTK_MENU_ITEM misc-menu) misc-cascade) (g_signal_connect misc-menu "activate" (lambda (w d) (update-label misc-menu-list)) #f) ;; -------- Place sound (let ((child (gtk_menu_item_new_with_label "Place sound")) (mono-snd 0) (stereo-snd 1) (pan-pos 45) (place-sound-dialog #f) (place-sound-target 'sound) (place-sound-envelope #f)) (define (place-sound mono-snd stereo-snd pan-env) ;; (place-sound mono-snd stereo-snd pan-env) mixes a mono sound into a stereo sound, splitting ;; it into two copies whose amplitudes depend on the envelope 'pan-env'. If 'pan-env' is ;; a number, the sound is split such that 0 is all in channel 0 and 90 is all in channel 1. (if (number? pan-env) (let ((pos (/ pan-env 90.0))) (effects-position-sound mono-snd pos stereo-snd 1) (effects-position-sound mono-snd (- 1.0 pos) stereo-snd 0)) (begin (effects-position-sound mono-snd pan-env stereo-snd 1) (effects-position-sound mono-snd pan-env stereo-snd 0)))) (gtk_menu_shell_append (GTK_MENU_SHELL misc-cascade) child) (gtk_widget_show child) (g_signal_connect child "activate" (lambda (w d) (if (not place-sound-dialog) (let ((initial-mono-snd 0) (initial-stereo-snd 1) (initial-pan-pos 45) (sliders ())) (set! place-sound-dialog (make-effect-dialog "Place sound" (lambda (w data) (let ((e (xe-envelope place-sound-envelope))) (if (not (equal? e (list 0.0 1.0 1.0 1.0))) (place-sound mono-snd stereo-snd e) (place-sound mono-snd stereo-snd pan-pos)))) (lambda (w data) (help-dialog "Place sound" "Mixes mono sound into stereo sound field.")) (lambda (w data) (set! mono-snd initial-mono-snd) (gtk_adjustment_set_value (GTK_ADJUSTMENT (sliders 0)) mono-snd) (set! stereo-snd initial-stereo-snd) (gtk_adjustment_set_value (GTK_ADJUSTMENT (sliders 1)) stereo-snd) (set! pan-pos initial-pan-pos) (gtk_adjustment_set_value (GTK_ADJUSTMENT (sliders 2)) pan-pos) ) (lambda () (effect-target-ok place-sound-target)))) (set! sliders (add-sliders place-sound-dialog (list (list "mono sound" 0 initial-mono-snd 50 (lambda (w data) (set! mono-snd (gtk_adjustment_get_value (GTK_ADJUSTMENT (sliders 0))))) 1) (list "stereo sound" 0 initial-stereo-snd 50 (lambda (w data) (set! stereo-snd (gtk_adjustment_get_value (GTK_ADJUSTMENT (sliders 1))))) 1) (list "pan position" 0 initial-pan-pos 90 (lambda (w data) (set! pan-pos (gtk_adjustment_get_value (GTK_ADJUSTMENT (sliders 2))))) 1)))) (gtk_widget_show place-sound-dialog) (set! place-sound-envelope (xe-create-enved "panning" (gtk_dialog_get_content_area (GTK_DIALOG place-sound-dialog)) #f '(0.0 1.0 0.0 1.0))) (set! (xe-envelope place-sound-envelope) (list 0.0 1.0 1.0 1.0)))) (activate-dialog place-sound-dialog)) #f) (set! misc-menu-list (cons (lambda () (let ((new-label (format #f "Place sound (~D ~D ~D)" mono-snd stereo-snd pan-pos))) (change-label child new-label))) misc-menu-list))) ;; -------- Insert silence (at cursor, silence-amount in secs) (let ((child (gtk_menu_item_new_with_label "Add silence")) (silence-amount 1.0) (silence-dialog #f)) (gtk_menu_shell_append (GTK_MENU_SHELL misc-cascade) child) (gtk_widget_show child) (g_signal_connect child "activate" (lambda (w d) (if (not silence-dialog) (let ((initial-silence-amount 1.0) (sliders ())) (set! silence-dialog (make-effect-dialog "Add silence" (lambda (w data) (insert-silence (cursor) (floor (* (srate) silence-amount)))) (lambda (w data) (help-dialog "Add silence" "Move the slider to change the number of seconds of silence added at the cursor position.")) (lambda (w data) (set! silence-amount initial-silence-amount) (gtk_adjustment_set_value (GTK_ADJUSTMENT (car sliders)) silence-amount) ))) (set! sliders (add-sliders silence-dialog (list (list "silence" 0.0 initial-silence-amount 5.0 (lambda (w data) (set! silence-amount (gtk_adjustment_get_value (GTK_ADJUSTMENT (sliders 0))))) 100)))))) (activate-dialog silence-dialog)) #f) (set! misc-menu-list (cons (lambda () (let ((new-label (format #f "Add silence (~1,2F)" silence-amount))) (change-label child new-label))) misc-menu-list))) ;;; -------- Contrast (brightness control) ;;; (let ((child (gtk_menu_item_new_with_label "Contrast enhancement")) (contrast-amount 1.0) (contrast-dialog #f) (contrast-target 'sound)) (gtk_menu_shell_append (GTK_MENU_SHELL misc-cascade) child) (gtk_widget_show child) (g_signal_connect child "activate" (lambda (w d) (if (not contrast-dialog) (let ((initial-contrast-amount 1.0) (sliders ())) (set! contrast-dialog (make-effect-dialog "Contrast enhancement" (lambda (w data) (let ((peak (maxamp)) (snd (selected-sound))) (save-controls snd) (reset-controls snd) (set! (contrast-control? snd) #t) (set! (contrast-control snd) contrast-amount) (set! (contrast-control-amp snd) (/ 1.0 peak)) (set! (amp-control snd) peak) (if (eq? contrast-target 'marks) (let ((ms (plausible-mark-samples))) (apply-controls snd 0 (car ms) (+ 1 (- (cadr ms) (car ms))))) (apply-controls snd (if (eq? contrast-target 'sound) 0 2))) (restore-controls snd))) (lambda (w data) (help-dialog "Contrast enhancement" "Move the slider to change the contrast intensity.")) (lambda (w data) (set! contrast-amount initial-contrast-amount) (gtk_adjustment_set_value (GTK_ADJUSTMENT (car sliders)) contrast-amount) ) (lambda () (effect-target-ok contrast-target)))) (set! sliders (add-sliders contrast-dialog (list (list "contrast enhancement" 0.0 initial-contrast-amount 10.0 (lambda (w data) (set! contrast-amount (gtk_adjustment_get_value (GTK_ADJUSTMENT (sliders 0))))) 100)))) (add-target (gtk_dialog_get_content_area (GTK_DIALOG contrast-dialog)) (lambda (target) (set! contrast-target target) (gtk_widget_set_sensitive (GTK_WIDGET (g_object_get_data (G_OBJECT contrast-dialog) "ok-button")) (effect-target-ok target))) #f))) (activate-dialog contrast-dialog)) #f) (set! misc-menu-list (cons (lambda () (let ((new-label (format #f "Contrast enhancement (~1,2F)" contrast-amount))) (change-label child new-label))) misc-menu-list))) ;; -------- Cross synthesis (let ((child (gtk_menu_item_new_with_label "Cross synthesis")) (cross-synth-sound 1) (cross-synth-amp .5) (cross-synth-fft-size 128) (cross-synth-radius 6.0) (cross-synth-dialog #f) (cross-synth-target 'sound)) (gtk_menu_shell_append (GTK_MENU_SHELL misc-cascade) child) (gtk_widget_show child) (g_signal_connect child "activate" (lambda (w d) (if (not cross-synth-dialog) (let ((initial-cross-synth-sound 1) (initial-cross-synth-amp .5) (initial-cross-synth-fft-size 128) (initial-cross-synth-radius 6.0) (sliders ())) (set! cross-synth-dialog (make-effect-dialog "Cross synthesis" (lambda (w data) (map-chan-over-target-with-sync (lambda (ignored) (effects-cross-synthesis cross-synth-sound cross-synth-amp cross-synth-fft-size cross-synth-radius)) cross-synth-target (lambda (target samps) (format #f "effects-cross-synthesis-1 ~A ~A ~A ~A" cross-synth-sound cross-synth-amp cross-synth-fft-size cross-synth-radius)) #f)) (lambda (w data) (help-dialog "Cross synthesis" "The sliders set the number of the soundfile to be cross-synthesized, the synthesis amplitude, the FFT size, and the radius value.")) (lambda (w data) (set! cross-synth-sound initial-cross-synth-sound) (gtk_adjustment_set_value (GTK_ADJUSTMENT (sliders 0)) cross-synth-sound) (set! cross-synth-amp initial-cross-synth-amp) (gtk_adjustment_set_value (GTK_ADJUSTMENT (sliders 1)) cross-synth-amp) (set! cross-synth-fft-size initial-cross-synth-fft-size) (set! cross-synth-radius initial-cross-synth-radius) (gtk_adjustment_set_value (GTK_ADJUSTMENT (sliders 2)) cross-synth-radius) ) (lambda () (effect-target-ok cross-synth-target)))) (set! sliders (add-sliders cross-synth-dialog (list (list "input sound" 0 initial-cross-synth-sound 20 (lambda (w data) (set! cross-synth-sound (gtk_adjustment_get_value (GTK_ADJUSTMENT (sliders 0))))) 1) (list "amplitude" 0.0 initial-cross-synth-amp 1.0 (lambda (w data) (set! cross-synth-amp (gtk_adjustment_get_value (GTK_ADJUSTMENT (sliders 1))))) 100) (list "radius" 0.0 initial-cross-synth-radius 360.0 (lambda (w data) (set! cross-synth-radius (gtk_adjustment_get_value (GTK_ADJUSTMENT (sliders 2))))) 100)))) (add-target (gtk_dialog_get_content_area (GTK_DIALOG cross-synth-dialog)) (lambda (target) (set! cross-synth-target target) (gtk_widget_set_sensitive (GTK_WIDGET (g_object_get_data (G_OBJECT cross-synth-dialog) "ok-button")) (effect-target-ok target))) #f))) (activate-dialog cross-synth-dialog)) #f) (set! misc-menu-list (cons (lambda () (let ((new-label (format #f "Cross synthesis (~D ~1,2F ~D ~1,2F)" cross-synth-sound cross-synth-amp cross-synth-fft-size cross-synth-radius))) (change-label child new-label))) misc-menu-list))) ;; -------- Flange and phasing (let ((child (gtk_menu_item_new_with_label "Flange")) (flange-speed 2.0) (flange-amount 5.0) (flange-time 0.001) (flange-dialog #f) (flange-target 'sound)) (gtk_menu_shell_append (GTK_MENU_SHELL misc-cascade) child) (gtk_widget_show child) (g_signal_connect child "activate" (lambda (w d) (if (not flange-dialog) (let ((initial-flange-speed 2.0) (initial-flange-amount 5.0) (initial-flange-time 0.001) (sliders ())) (set! flange-dialog (make-effect-dialog "Flange" (lambda (w data) (map-chan-over-target-with-sync (lambda (ignored) (let* ((ri (make-rand-interp :frequency flange-speed :amplitude flange-amount)) (len (round (* flange-time (srate)))) (del (make-delay len :max-size (round (+ len flange-amount 1))))) (lambda (inval) (* .75 (+ inval (delay del inval (rand-interp ri))))))) flange-target (lambda (target samps) (format #f "effects-flange ~A ~A ~A" flange-amount flange-speed flange-time)) #f)) (lambda (w data) (help-dialog "Flange" "Move the sliders to change the flange speed, amount, and time")) (lambda (w data) (set! flange-speed initial-flange-speed) (gtk_adjustment_set_value (GTK_ADJUSTMENT (car sliders)) flange-speed) (set! flange-amount initial-flange-amount) (gtk_adjustment_set_value (GTK_ADJUSTMENT (cadr sliders)) flange-amount) (set! flange-time initial-flange-time) (gtk_adjustment_set_value (GTK_ADJUSTMENT (caddr sliders)) flange-time) ) (lambda () (effect-target-ok flange-target)))) (set! sliders (add-sliders flange-dialog (list (list "flange speed" 0.0 initial-flange-speed 100.0 (lambda (w data) (set! flange-speed (gtk_adjustment_get_value (GTK_ADJUSTMENT (sliders 0))))) 10) (list "flange amount" 0.0 initial-flange-amount 100.0 (lambda (w data) (set! flange-amount (gtk_adjustment_get_value (GTK_ADJUSTMENT (sliders 1))))) 10) ;; flange time ought to use a non-linear scale (similar to amp in control panel) (list "flange time" 0.0 initial-flange-time 1.0 (lambda (w data) (set! flange-time (gtk_adjustment_get_value (GTK_ADJUSTMENT (sliders 2))))) 100)))) (add-target (gtk_dialog_get_content_area (GTK_DIALOG flange-dialog)) (lambda (target) (set! flange-target target) (gtk_widget_set_sensitive (GTK_WIDGET (g_object_get_data (G_OBJECT flange-dialog) "ok-button")) (effect-target-ok target))) #f))) (activate-dialog flange-dialog)) #f) (set! misc-menu-list (cons (lambda () (let ((new-label (format #f "Flange (~1,2F ~1,2F ~1,3F)" flange-speed flange-amount flange-time))) (change-label child new-label))) misc-menu-list))) ;; -------- Randomize phase (let ((child (gtk_menu_item_new_with_label "Randomize phase")) (random-phase-amp-scaler 3.14) (random-phase-dialog #f)) (gtk_menu_shell_append (GTK_MENU_SHELL misc-cascade) child) (gtk_widget_show child) (g_signal_connect child "activate" (lambda (w d) (if (not random-phase-dialog) (let ((initial-random-phase-amp-scaler 3.14) (sliders ())) (set! random-phase-dialog (make-effect-dialog "Randomize phase" (lambda (w data) (rotate-phase (lambda (x) (random random-phase-amp-scaler)))) (lambda (w data) (help-dialog "Randomize phase" "Move the slider to change the randomization amplitude scaler.")) (lambda (w data) (set! random-phase-amp-scaler initial-random-phase-amp-scaler) (gtk_adjustment_set_value (GTK_ADJUSTMENT (car sliders)) random-phase-amp-scaler) ))) (set! sliders (add-sliders random-phase-dialog (list (list "amplitude scaler" 0.0 initial-random-phase-amp-scaler 100.0 (lambda (w data) (set! random-phase-amp-scaler (gtk_adjustment_get_value (GTK_ADJUSTMENT (sliders 0))))) 100)))))) (activate-dialog random-phase-dialog)) #f) (set! misc-menu-list (cons (lambda () (let ((new-label (format #f "Randomize phase (~1,2F)" random-phase-amp-scaler))) (change-label child new-label))) misc-menu-list))) ;; -------- Robotize (let ((child (gtk_menu_item_new_with_label "Robotize")) (samp-rate 1.0) (osc-amp 0.3) (osc-freq 20) (robotize-dialog #f) (robotize-target 'sound)) (gtk_menu_shell_append (GTK_MENU_SHELL misc-cascade) child) (gtk_widget_show child) (g_signal_connect child "activate" (lambda (w d) (if (not robotize-dialog) (let ((initial-samp-rate 1.0) (initial-osc-amp 0.3) (initial-osc-freq 20) (sliders ())) (set! robotize-dialog (make-effect-dialog "Robotize" (lambda (w data) (let ((ms (and (eq? robotize-target 'marks) (plausible-mark-samples)))) (effects-fp samp-rate osc-amp osc-freq (if (eq? robotize-target 'sound) 0 (if (eq? robotize-target 'selection) (selection-position) (car ms))) (if (eq? robotize-target 'sound) (framples) (if (eq? robotize-target 'selection) (selection-framples) (- (cadr ms) (car ms))))))) (lambda (w data) (help-dialog "Robotize" "Move the sliders to set the sample rate, oscillator amplitude, and oscillator frequency.")) (lambda (w data) (set! samp-rate initial-samp-rate) (gtk_adjustment_set_value (GTK_ADJUSTMENT (car sliders)) samp-rate) (set! osc-amp initial-osc-amp) (gtk_adjustment_set_value (GTK_ADJUSTMENT (cadr sliders)) osc-amp) (set! osc-freq initial-osc-freq) (gtk_adjustment_set_value (GTK_ADJUSTMENT (caddr sliders)) osc-freq) ) (lambda () (effect-target-ok robotize-target)))) (set! sliders (add-sliders robotize-dialog (list (list "sample rate" 0.0 initial-samp-rate 2.0 (lambda (w data) (set! samp-rate (gtk_adjustment_get_value (GTK_ADJUSTMENT (sliders 0))))) 100) (list "oscillator amplitude" 0.0 initial-osc-amp 1.0 (lambda (w data) (set! osc-amp (gtk_adjustment_get_value (GTK_ADJUSTMENT (sliders 1))))) 100) (list "oscillator frequency" 0.0 initial-osc-freq 60 (lambda (w data) (set! osc-freq (gtk_adjustment_get_value (GTK_ADJUSTMENT (sliders 2))))) 100)))) (add-target (gtk_dialog_get_content_area (GTK_DIALOG robotize-dialog)) (lambda (target) (set! robotize-target target) (gtk_widget_set_sensitive (GTK_WIDGET (g_object_get_data (G_OBJECT robotize-dialog) "ok-button")) (effect-target-ok target))) #f))) (activate-dialog robotize-dialog)) #f) (set! misc-menu-list (cons (lambda () (let ((new-label (format #f "Robotize (~1,2F ~1,2F ~1,2F)" samp-rate osc-amp osc-freq))) (change-label child new-label))) misc-menu-list))) ;; -------- Rubber sound (let ((child (gtk_menu_item_new_with_label "Rubber sound")) (rubber-factor 1.0) (rubber-dialog #f) (rubber-target 'sound)) (gtk_menu_shell_append (GTK_MENU_SHELL misc-cascade) child) (gtk_widget_show child) (g_signal_connect child "activate" (lambda (w d) (if (not rubber-dialog) (let ((initial-rubber-factor 1.0) (sliders ())) (set! rubber-dialog (make-effect-dialog "Rubber sound" (lambda (w data) (rubber-sound rubber-factor)) (lambda (w data) (help-dialog "Rubber sound" "Stretches or contracts the time of a sound. Move the slider to change the stretch factor.")) (lambda (w data) (set! rubber-factor initial-rubber-factor) (gtk_adjustment_set_value (GTK_ADJUSTMENT (car sliders)) rubber-factor) ) (lambda () (effect-target-ok rubber-target)))) (set! sliders (add-sliders rubber-dialog (list (list "stretch factor" 0.0 initial-rubber-factor 5.0 (lambda (w data) (set! rubber-factor (gtk_adjustment_get_value (GTK_ADJUSTMENT (sliders 0))))) 100)))) (add-target (gtk_dialog_get_content_area (GTK_DIALOG rubber-dialog)) (lambda (target) (set! rubber-target target) (gtk_widget_set_sensitive (GTK_WIDGET (g_object_get_data (G_OBJECT rubber-dialog) "ok-button")) (effect-target-ok target))) #f))) (activate-dialog rubber-dialog)) #f) (set! misc-menu-list (cons (lambda () (let ((new-label (format #f "Rubber sound (~1,2F)" rubber-factor))) (change-label child new-label))) misc-menu-list))) ;; -------- Wobble (let ((child (gtk_menu_item_new_with_label "Wobble")) (wobble-frequency 50) (wobble-amplitude 0.5) (wobble-dialog #f) (wobble-target 'sound)) (gtk_menu_shell_append (GTK_MENU_SHELL misc-cascade) child) (gtk_widget_show child) (g_signal_connect child "activate" (lambda (w d) (if (not wobble-dialog) (let ((initial-wobble-frequency 50) (initial-wobble-amplitude 0.5) (sliders ())) (set! wobble-dialog (make-effect-dialog "Wobble" (lambda (w data) (let ((ms (and (eq? wobble-target 'marks) (plausible-mark-samples)))) (effects-hello-dentist wobble-frequency wobble-amplitude (if (eq? wobble-target 'sound) 0 (if (eq? wobble-target 'selection) (selection-position) (car ms))) (if (eq? wobble-target 'sound) (framples) (if (eq? wobble-target 'selection) (selection-framples) (- (cadr ms) (car ms))))))) (lambda (w data) (help-dialog "Wobble" "Move the sliders to set the wobble frequency and amplitude.")) (lambda (w data) (set! wobble-frequency initial-wobble-frequency) (gtk_adjustment_set_value (GTK_ADJUSTMENT (car sliders)) wobble-frequency) (set! wobble-amplitude initial-wobble-amplitude) (gtk_adjustment_set_value (GTK_ADJUSTMENT (cadr sliders)) wobble-amplitude) ) (lambda () (effect-target-ok wobble-target)))) (set! sliders (add-sliders wobble-dialog (list (list "wobble frequency" 0 initial-wobble-frequency 100 (lambda (w data) (set! wobble-frequency (gtk_adjustment_get_value (GTK_ADJUSTMENT (sliders 0))))) 100) (list "wobble amplitude" 0.0 initial-wobble-amplitude 1.0 (lambda (w data) (set! wobble-amplitude (gtk_adjustment_get_value (GTK_ADJUSTMENT (sliders 1))))) 100)))) (add-target (gtk_dialog_get_content_area (GTK_DIALOG wobble-dialog)) (lambda (target) (set! wobble-target target) (gtk_widget_set_sensitive (GTK_WIDGET (g_object_get_data (G_OBJECT wobble-dialog) "ok-button")) (effect-target-ok target))) #f))) (activate-dialog wobble-dialog)) #f) (set! misc-menu-list (cons (lambda () (let ((new-label (format #f "Wobble (~1,2F ~1,2F)" wobble-frequency wobble-amplitude))) (change-label child new-label))) misc-menu-list))) ) ;;; ;;; END PARAMETRIZED EFFECTS ;;; (add-to-menu effects-menu #f #f) (add-to-menu effects-menu "Octave-down" (lambda () (down-oct 2))) (add-to-menu effects-menu "Remove clicks" (lambda () (define (find-click loc) (let ((reader (make-sampler loc)) (mmax (make-moving-max 10)) (samp0 0.0) (samp1 0.0) (samp2 0.0) (len (framples))) (call-with-exit (lambda (return) (do ((ctr loc (+ ctr 1))) ((= ctr len) #f) (set! samp0 samp1) (set! samp1 samp2) (set! samp2 (next-sample reader)) (let ((local-max (max .1 (moving-max mmax samp0)))) (if (and (> (abs (- samp0 samp1)) local-max) (> (abs (- samp1 samp2)) local-max) (< (abs (- samp0 samp2)) (/ local-max 2))) (return (- ctr 1))))))))) (define (remove-click loc) (let ((click (find-click loc))) (if click (begin (smooth-sound (- click 2) 4) (remove-click (+ click 2)))))) (remove-click 0))) (define* (effects-remove-dc snd chn) (let* ((len (framples snd chn)) (data (make-float-vector len)) (reader (make-sampler 0 snd chn))) (let ((lastx 0.0) (lasty 0.0)) (do ((i 0 (+ i 1))) ((= i len)) (let ((inval (next-sample reader))) (set! lasty (+ inval (- (* 0.999 lasty) lastx))) (set! lastx inval) (float-vector-set! data i lasty)))) (float-vector->channel data 0 len snd chn current-edit-position "effects-remove-dc"))) (add-to-menu effects-menu "Remove DC" effects-remove-dc) (add-to-menu effects-menu "Spiker" spike) (define* (effects-compand snd chn) (let ((tbl (float-vector -1.000 -0.960 -0.900 -0.820 -0.720 -0.600 -0.450 -0.250 0.000 0.250 0.450 0.600 0.720 0.820 0.900 0.960 1.000))) (let ((len (framples snd chn))) (let ((reader (make-sampler 0 snd chn)) (data (make-float-vector len))) (do ((i 0 (+ i 1))) ((= i len)) (float-vector-set! data i (array-interp tbl (+ 8.0 (* 8.0 (next-sample reader))) 17))) (float-vector->channel data 0 len snd chn current-edit-position "effects-compand"))))) (add-to-menu effects-menu "Compand" effects-compand) (add-to-menu effects-menu "Invert" (lambda () (scale-by -1))) (add-to-menu effects-menu "Reverse" reverse-sound) (add-to-menu effects-menu "Null phase" zero-phase) ) ; *gtk*snd-16.1/pvoc.rb0000644000076400007640000002223212434353162011633 0ustar bilbil# pvoc.rb -- pvoc.scm -> pvoc.rb # Translator: Michael Scholz # Created: 04/03/27 00:19:51 # Changed: 14/11/14 08:58:16 # versions of the Moore-Klingbeil-Trevisani-Edwards phase-vocoder # # class Pvocoder # initialize(fftsize, overlap, interp, analyze, edit, synthesize) # inspect # pvocoder(input) # # make_pvocoder(fftsize, overlap, interp, analyze, edit, synthesize) # pvocoder(pv, input) # # test_pv_1 # test_pv_2(freq) # test_pv_3(time) # test_pv_4(gate) # # pvoc(*rest) require "ws" class Pvocoder def initialize(fftsize, overlap, interp, analyze, edit, synthesize) @output = interp @interp = interp @hop = overlap @filptr = 0 @N = fftsize @window = make_fft_window(Hamming_window, fftsize) @window.scale!(2.0 / (0.54 * fftsize)) @D = fftsize / overlap @in_data = nil @ampinc = make_vct(fftsize) @freqs = make_vct(fftsize) @amps = make_vct(fftsize / 2) @phaseinc = make_vct(fftsize / 2) @phases = make_vct(fftsize / 2) @lastphase = make_vct(fftsize / 2) @analyze = analyze @edit = edit @synthesize = synthesize end def inspect format("#<%s outctr: %d, interp: %d, \ filptr: %d, N: %d, D: %d, in_data: %p>", self.class, @output, @interp, @filptr, @N, @D, @in_data) end def pvocoder(input) if @output >= @interp if @analyze @analyze.call(self, input) else vct_fill!(@freqs, 0.0) @output = 0 if (not vct?(@in_data)) @in_data = make_vct!(@N) do input.call end else vct_move!(@in_data, 0, @D) ((@N - @D)...@N).each do |i| @in_data[i] = input.call end end buf = @filptr % @N if buf.zero? vct_fill!(@ampinc, 0.0) vct_add!(@ampinc, @in_data) vct_multiply!(@ampinc, @window) else @N.times do |k| @ampinc[buf] = @window[k] * @in_data[k] buf += 1 if buf >= @N buf = 0 end end end @filptr += @D mus_fft(@ampinc, @freqs, @N, 1) rectangular2polar(@ampinc, @freqs) end if @edit @edit.call(self) else pscl = 1.0 / @D kscl = TWO_PI / @N (@N / 2).times do |k| phasediff = @freqs[k] - @lastphase[k] @lastphase[k] = @freqs[k] while phasediff > PI phasediff -= TWO_PI end while phasediff < -TWO_PI phasediff += TWO_PI end @freqs[k] = pscl * phasediff + k * kscl end end scl = 1.0 / @interp vct_subtract!(@ampinc, @amps) vct_subtract!(@freqs, @phaseinc) vct_scale!(@ampinc, scl) vct_scale!(@freqs, scl) end @output += 1 if @synthesize @synthesize.call else vct_add!(@amps, @ampinc) vct_add!(@phaseinc, @freqs) vct_add!(@phases, @phaseinc) sine_bank(@amps, @phases) end end end add_help(:make_pvocoder, "make_pvocoder(fftsize, overlap, interp, analyze=false, \ edit=false, synthesize=false) \ Makes a new (Ruby-based, not CLM) phase-vocoder generator.") def make_pvocoder(fftsize = 512, overlap = 4, interp = 128, analyze = false, edit = false, synthesize = false) Pvocoder.new(fftsize, overlap, interp, analyze, edit, synthesize) end add_help(:pvocoder, "pvocoder(pv, input) \ Is the phase-vocoder generator associated with make_pvocoder.") def pvocoder(pv, input) pv.pvocoder(input) end =begin let(open_sound("oboe.snd"), make_pvocoder(256, 4, 64), make_sampler(0)) do |ind, pv, rd| map_channel(lambda do |y| pvocoder(pv, rd) end) play(ind, :wait, true) save_sound_as("pvoc.snd", ind) revert_sound(ind) close_sound(ind) open_sound("pvoc.snd") end =end def test_pv_1 pv = make_phase_vocoder(false, 512, 4, 128, 1.0, false, false, false) rd = make_sampler(0) map_channel(lambda do |y| phase_vocoder(pv, lambda do |dir| next_sample(rd) end) end) free_sampler(rd) end def test_pv_2(freq) pv = make_phase_vocoder(false, 512, 4, 128, freq, false, false, false) rd = make_sampler(0) map_channel(lambda do |y| phase_vocoder(pv, lambda do |dir| next_sample(rd) end) end) free_sampler(rd) end def test_pv_3(time) pv = make_phase_vocoder(false, 512, 4, (time * 128.0).floor, 1.0, false, false, false) rd = make_sampler(0) len = (time * framples()).floor data = make_vct!(len) do phase_vocoder(pv, lambda do |dir| next_sample(rd) end) end free_sampler(rd) vct2channel(data, 0, len) end def test_pv_4(gate) pv = make_phase_vocoder(false, 512, 4, 128, 1.0, false, lambda do |v| phase_vocoder_amp_increments(v).map! do |val| if val < gate 0.0 else val end true end end, false) rd = make_sampler(0) map_channel(lambda do |y| phase_vocoder(pv, lambda do |dir| next_sample(rd) end) end) free_sampler(rd) end # another version of the phase vocoder add_help(:pvoc, "pvoc(*rest) :fftsize = 512 :overlap = 4 :time = 1.0 :pitch = 1.0 :gate = 0.0 :hoffset = 0.0 :snd = false :chn = false Applies the phase vocoder algorithm to the current sound (i.e. fft analysis, \ oscil bank resynthesis). \ TIME specifies the time dilation ratio, \ PITCH specifies the pitch transposition ratio, \ GATE specifies a resynthesis gate in dB (partials with \ amplitudes lower than the gate value will not be synthesized), \ HOFFSET is a pitch offset in Hz.") def pvoc(*rest) fftsize, overlap, time, pitch, gate, hoffset, snd, chn = nil optkey(rest, binding, [:fftsize, 512], [:overlap, 4], [:time, 1.0], [:pitch, 1.0], [:gate, 0.0], [:hoffset, 0.0], [:snd, false], [:chn, false]) len = framples(snd, chn) filptr = 0 sr = srate(snd) fftsize2 = (fftsize / 2.0).floor d = fftsize / overlap interp = d * time syngate = gate.zero? ? 0.0 : (10 ** (-gate.abs / 20.0)) poffset = hz2radians(hoffset) window = make_fft_window(Hamming_window, fftsize) fdr = make_vct(fftsize) fdi = make_vct(fftsize) lastphase = make_vct(fftsize2) lastamp = make_vct(fftsize2) lastfreq = make_vct(fftsize2) ampinc = make_vct(fftsize2) freqinc = make_vct(fftsize2) fundamental = TWO_PI / fftsize output = interp # resynth_oscils = make_array(fftsize2) do # make_oscil(:frequency, 0) # end outlen = (time * len).floor in_data = channel2vct(0, fftsize * 2, snd, chn) in_data_beg = 0 vct_scale!(window, 2.0 / (0.54 * fftsize)) obank = make_oscil_bank(lastfreq, make_vct(fftsize2, 0.0), lastamp) out_data = make_vct([len, outlen].max) out_data.length.times do |i| if output >= interp output = 0 buffix = filptr % fftsize vct_fill!(lastamp, 0.0) vct_fill!(lastfreq, 0.0) vct_add!(lastamp, fdr) vct_add!(lastfreq, fdi) fftsize.times do |k| fdr[buffix] = window[k] * in_data[filptr - in_data_beg] filptr += 1 buffix += 1 if buffix >= fftsize buffix = 0 end end filptr -= fftsize - d if filptr > in_data_beg + fftsize in_data_beg = filptr in_data = channel2vct(in_data_beg, fftsize * 2, snd, chn) end vct_fill!(fdi, 0.0) mus_fft(fdr, fdi, fftsize, 1) fftsize2.times do |k| a = fdr[k] b = fdi[k] mag = sqrt(a * a + b * b) phase = 0 phasediff = 0 fdr[k] = mag if mag > 0 phase = -atan2(b, a) phasediff = phase - lastphase[k] lastphase[k] = phase while phasediff > PI phasediff -= TWO_PI end while phasediff < -PI phasediff += TWO_PI end end fdi[k] = pitch * ((phasediff * sr) / (d * sr) + k * fundamental + poffset) if fdr[k] < syngate fdr[k] = 0.0 end ampinc[k] = (fdr[k] - lastamp[k]) / interp freqinc[k] = (fdi[k] - lastfreq[k]) / interp end end output += 1 vct_add!(lastamp, ampinc) vct_add!(lastfreq, freqinc) # old_oscil_bank from extensions.rb # out_data[i] = old_oscil_bank(lastamp, resynth_oscils, lastfreq) out_data[i] = oscil_bank(obank) end vct2channel(out_data, 0, out_data.length) end # pvoc.rb ends here snd-16.1/snddiff.scm0000644000076400007640000001331612616231602012457 0ustar bilbil(provide 'snd-snddiff.scm) (define (cross-correlate snd0 chn0 snd1 chn1) (let* ((len0 (framples snd0 chn0)) (len1 (framples snd1 chn1)) (ilen (max len0 len1)) (pow2 (ceiling (log ilen 2))) (fftlen (floor (expt 2 pow2)))) (correlate (channel->float-vector 0 fftlen snd1 chn1) (channel->float-vector 0 fftlen snd0 chn0)))) (define (lag? snd0 chn0 snd1 chn1) ;; returns the probable lagtime between the two sounds (negative means second sound is delayed) (let* ((corr (cross-correlate snd0 chn0 snd1 chn1)) (len (length corr)) (data (float-vector-peak-and-location corr)) (lag (cadr data))) (if (= lag -1) 0 (if (< lag (/ len 2)) lag (- lag len))))) (define* (snddiff-1 v0 v1 (maxdiff 0.0)) (let ((diff (float-vector-subtract! (copy v0) v1))) (if (<= (float-vector-peak diff) maxdiff) 'no-difference (let ((diffs 0) (diff-data ()) (len (min (length v0) (length v1)))) (do ((i 0 (+ i 1))) ((or (> diffs 10) (= i len))) (if (> (abs (diff i)) .00001) (begin (set! diffs (+ diffs 1)) (set! diff-data (cons (list i (v0 i) (v1 i)) diff-data))))) (and (< diffs 10) (list 'differences diff-data)))))) (define (float-vector-size v) (sqrt (dot-product v v))) (define (unconvolve-1 v0 v1 impulse-response) ; assume here that v0 is the original and that we're aligned, and both are trimmed at the front (let ((pos -1) (len (length v0))) (do ((i 0 (+ i 1))) ((or (>= pos 0) (= i len))) (if (not (= (v1 i) 0.0)) (set! pos i))) (if (>= pos 0) ; if still -1, must be all zero (let ((scl (/ (v1 pos) (v0 0))) (size (float-vector-size v1))) (float-vector-subtract! (float-vector-move! v1 0 pos) ; align new copy with original (todo: move doesn't clear trailing entries) (float-vector-scale! (copy v0) scl)) ; subtract original scaled to fit first none zero point (if (< (float-vector-size v1) size) (unconvolve-1 v0 v1 (cons (list scl pos) impulse-response)) impulse-response)) impulse-response))) (define (unconvolve v0 v1) (and (float-vector? v0) (float-vector? v1) (let ((trim -1) (len (min (length v0) (length v1)))) (do ((i 0 (+ i 1))) ((or (> trim -1) (= i len))) (if (or (not (= (v0 i) 0.0)) (not (= (v1 i) 0.0))) (set! trim i))) (if (> trim 0) (begin (float-vector-move! v0 0 trim) (float-vector-move! v1 0 trim))) (let ((result (unconvolve-1 v0 (copy v1) ()))) (and (pair? result) (list 'filter (reverse result))))))) (define (snddiff-2 snd0 chn0 snd1 chn1) ;; this can currently find initial delays, scaling differences, and scattered individual sample differences (let ((len0 (framples snd0 chn0)) (len1 (framples snd1 chn1))) (or (and (= len0 len1) (let ((s0 (channel->float-vector 0 #f snd0 chn0)) (s1 (channel->float-vector 0 #f snd1 chn1))) (or (snddiff-1 s0 s1 0.0) (let* ((pos (maxamp-position snd0 chn0)) (mx0 (sample pos snd0 chn0)) (mx1 (sample pos snd1 chn1)) ; use actual values to keep possible sign difference (scl (/ mx1 mx0)) (diff (snddiff-1 (float-vector-scale! s0 scl) s1))) (if (eq? diff 'no-difference) (list 'scale scl) (and (list? diff) (list 'scale scl 'differences diff))))))) ;; align sounds and zero out any non-overlapping sections, keeping track of whether they are zero beforehand (let ((lag (lag? snd0 chn0 snd1 chn1)) (pre0 #f) (pre1 #f) (post0 #f) (post1 #f)) (if (> lag 0) (begin (pad-channel 0 lag snd1 chn1) (set! pre0 (float-vector-peak (channel->float-vector 0 lag snd0 chn0))) (if (> pre0 0.0) (scale-channel 0.0 0 lag snd0 chn0))) (if (< lag 0) (let ((pad (- lag))) (pad-channel 0 pad snd0 chn0) (set! pre1 (float-vector-peak (channel->float-vector 0 pad snd1 chn1))) (if (> pre1 0.0) (scale-channel 0.0 0 pad snd1 chn1))))) (set! len0 (framples snd0 chn0)) (set! len1 (framples snd1 chn1)) (if (> len0 len1) (let ((dur (- len0 len1))) (set! post0 (float-vector-peak (channel->float-vector len1 dur snd0 chn0))) (scale-channel 0.0 len1 dur snd0 chn0)) (if (> len1 len0) (let ((dur (- len1 len0))) (set! post1 (float-vector-peak (channel->float-vector len0 dur snd1 chn1))) (scale-channel 0.0 len0 dur snd1 chn1)))) (let ((s0 (channel->float-vector 0 #f snd0 chn0)) (s1 (channel->float-vector 0 #f snd1 chn1))) (or (let ((res (snddiff-1 s0 s1 0.0))) (and res (if (> lag 0) (list 'lag lag res pre0 pre1 post0 post1) (list res pre0 pre1 post0 post1)))) (let* ((pos (maxamp-position snd0 chn0)) (mx0 (sample pos snd0 chn0)) (mx1 (sample pos snd1 chn1)) ; use actual values to keep possible sign difference (scl (/ mx1 mx0)) (diff (snddiff-1 (float-vector-scale! s0 scl) s1 0.0001))) (if (eq? diff 'no-difference) (list 'scale scl 'lag lag pre0 pre1 post0 post1) (and (list? diff) (list 'scale scl 'differences diff 'lag lag pre0 pre1 post0 post1))))))) ;; align and zero + scaling didn't find a match ))) (define (snddiff snd0 chn0 snd1 chn1) ;; a wrapper for snddiff to put things back the way they were (let ((edpos0 (edit-position snd0 chn0)) (edpos1 (edit-position snd1 chn1))) (let ((result (snddiff-2 snd0 chn0 snd1 chn1))) (set! (edit-position snd0 chn0) edpos0) (set! (edit-position snd1 chn1) edpos1) (or result (unconvolve (channel->float-vector 0 #f snd0 chn0) (channel->float-vector 0 #f snd1 chn1)))))) ;; for env: slam both to 1 at every peak, check for eq, see if smooth env gives match? ;; or check spectr for eq leaving out low stuff, then try env?snd-16.1/clm.fs0000644000076400007640000012363012476114577011463 0ustar bilbil\ clm.fs -- clm related base words, with-sound and friends \ Author: Michael Scholz \ Created: 04/03/15 19:25:58 \ Changed: 15/02/25 16:05:57 \ \ @(#)clm.fs 1.121 2/25/15 \ clm-print ( fmt :optional args -- ) \ clm-message ( fmt :optional args -- ) \ \ now@ ( -- secs ) \ now! ( secs -- ) \ step ( secs -- ) \ tempo@ ( -- secs ) \ tempo! ( secs -- ) \ interval->hertz ( n -- r ) \ keynum->hertz ( n -- r ) \ hertz->keynum ( r -- n ) \ bpm->seconds ( bpm -- secs ) \ rhythm->seconds ( rhy -- secs ) \ \ tempnam ( -- name ) \ fth-tempnam ( -- name ) \ make-default-comment ( -- str ) \ times->samples ( start dur -- len beg ) \ \ ws-local-variables ( -- ) \ ws-info ( start dur vars -- start dur ) \ run ( start dur -- ) \ run-instrument ( start dur locsig-args -- ) \ end-run ( sample -- ) \ reverb-info ( caller in-chans out-chans -- ) \ instrument: ( "name" -- ) \ ;instrument ( -- ) \ event: ( "name" -- ) \ ;event ( -- ) \ \ find-file ( file -- fname|#f ) \ snd-info ( output :key reverb-file-name scaled? timer -- ) \ \ clm-mix ( ifile keyword-args -- ) \ ws-output ( ws -- fname ) \ with-sound ( body-xt keyword-args -- ws ) \ clm-load ( fname keyword-args -- ws ) \ with-current-sound ( body-xt :key offset scaled-to scaled-by -- ) \ scaled-to ( body-xt scl -- ) \ scaled-by ( body-xt scl -- ) \ with-offset ( body-xt secs -- ) \ with-mix ( body-str|nil args fname start -- ) \ sound-let ( ws-xt-lst body-xt -- ) \ \ play-sound ( :key verbose player :optional input -- ) \ \ example instruments: \ simp ( star dur freq amp -- ) \ src-simp ( start dur amp sr sr-env fname -- ) \ conv-simp ( start dur filt fname amp -- ) \ arpeggio ( start dur freq amp :key ampenv offset -- ) \ \ from generators.scm: \ make-waveshape ( :optional freq parts wave size -- ) \ waveshape ( gen :optional index fm -- val ) \ waveshape? ( obj -- f ) \ partials->waveshape ( part :optional size -- wave ) \ make-sum-of-sines ( :key sines frequency initial-phase -- gen ) \ sum-of-sines ( gen :optional fm -- val ) \ sum-of-sines? ( obj -- f ) \ make-sum-of-cosines ( :key cosines frequency initial-phase -- gen ) \ sum-of-cosines ( gen :optional fm -- val ) \ sum-of-cosines? ( obj -- f ) \ make-sine-summation ( :key frequency initial-phase n a ratio -- gen ) \ sine-summation ( gen :optional fm -- val ) \ sine-summation? ( obj -- f ) [ifundef] flog10 <'> flog alias flog10 <'> fln alias flog <'> flnp1 alias flogp1 [then] \ if configured --with-shared-sndlib 'sndlib provided? [unless] dl-load sndlib Init_sndlib [then] 'snd provided? [unless] <'> noop alias close-sound <'> noop alias find-sound <'> noop alias open-sound <'> noop alias save-sound <'> noop alias scale-channel <'> noop alias sound? <'> noop alias framples \ Some generic words for non-Snd use. : channels <{ :optional obj #f -- n }> obj string? if obj mus-sound-chans else obj mus-generator? if obj mus-channels else obj object-length then then ; : srate <{ :optional obj #f -- n }> obj string? if obj mus-sound-srate else mus-srate f>s then ; : maxamp <{ :optional snd #f chn #f edpos #f -- r }> snd string? if snd mus-sound-maxamp else snd vct? if snd vct-peak else 0.0 then then ; [then] [ifundef] clm-print \ "hello" clm-print \ "file %s, line %d\n" '( "oboe.snd" 123 ) clm-print [ifdef] snd-print : clm-print ( fmt :optional args -- ) string-format snd-print drop ; [else] <'> fth-print alias clm-print ( fmt :optional args -- ) [then] [then] \ Put comment sign before output string and finish with carriage return. : clm-message ( fmt :optional args -- ) string-format { msg } "\\ %s\n" '( msg ) clm-print ; \ === Notelist === hide 0.00 value *clm-current-time* 60.0 value *clm-tempo* 0.25 value *clm-beat* set-current : now@ ( -- secs ) *clm-current-time* ; : now! ( secs -- ) to *clm-current-time* ; : step ( secs -- ) now@ f+ now! ; : tempo@ ( -- secs ) *clm-tempo* ; : tempo! ( secs -- ) to *clm-tempo* ; previous \ --- Pitches --- 6.875 constant lowest-freq : interval->hertz { n -- 5 } 2.0 12.0 n 3.0 f+ f+ 12.0 f/ f** lowest-freq f* ; : keynum->hertz { n -- r } 2.0 n 3.0 f+ 12.0 f/ f** lowest-freq f* ; : hertz->keynum ( r -- n ) lowest-freq f/ 2.0 flogn 12.0 f* 3.0 f- f>s ; hide : pitch ( interval octave "name" --; self -- freq ) { interval octave } 2.0 octave 1.0 f+ 12.0 f* interval 3.0 f+ f+ 12.0 f/ f** lowest-freq f* create , does> ( self -- freq ) @ ; set-current 0 0 pitch |C0 1 0 pitch |Cs0 1 0 pitch |Df0 2 0 pitch |D0 3 0 pitch |Ds0 3 0 pitch |Ef0 4 0 pitch |E0 4 0 pitch |Ff0 5 0 pitch |Es0 5 0 pitch |F0 6 0 pitch |Fs0 6 0 pitch |Gf0 7 0 pitch |G0 8 0 pitch |Gs0 8 0 pitch |Af0 9 0 pitch |A0 10 0 pitch |As0 10 0 pitch |Bf0 11 0 pitch |B0 11 0 pitch |Cf0 12 0 pitch |Bs0 0 1 pitch |C1 1 1 pitch |Cs1 1 1 pitch |Df1 2 1 pitch |D1 3 1 pitch |Ds1 3 1 pitch |Ef1 4 1 pitch |E1 4 1 pitch |Ff1 5 1 pitch |Es1 5 1 pitch |F1 6 1 pitch |Fs1 6 1 pitch |Gf1 7 1 pitch |G1 8 1 pitch |Gs1 8 1 pitch |Af1 9 1 pitch |A1 10 1 pitch |As1 10 1 pitch |Bf1 11 1 pitch |B1 11 1 pitch |Cf1 12 1 pitch |Bs1 0 2 pitch |C2 1 2 pitch |Cs2 1 2 pitch |Df2 2 2 pitch |D2 3 2 pitch |Ds2 3 2 pitch |Ef2 4 2 pitch |E2 4 2 pitch |Ff2 5 2 pitch |Es2 5 2 pitch |F2 6 2 pitch |Fs2 6 2 pitch |Gf2 7 2 pitch |G2 8 2 pitch |Gs2 8 2 pitch |Af2 9 2 pitch |A2 10 2 pitch |As2 10 2 pitch |Bf2 11 2 pitch |B2 11 2 pitch |Cf2 12 2 pitch |Bs2 0 3 pitch |C3 1 3 pitch |Cs3 1 3 pitch |Df3 2 3 pitch |D3 3 3 pitch |Ds3 3 3 pitch |Ef3 4 3 pitch |E3 4 3 pitch |Ff3 5 3 pitch |Es3 5 3 pitch |F3 6 3 pitch |Fs3 6 3 pitch |Gf3 7 3 pitch |G3 8 3 pitch |Gs3 8 3 pitch |Af3 9 3 pitch |A3 10 3 pitch |As3 10 3 pitch |Bf3 11 3 pitch |B3 11 3 pitch |Cf3 12 3 pitch |Bs3 0 4 pitch |C4 1 4 pitch |Cs4 1 4 pitch |Df4 2 4 pitch |D4 3 4 pitch |Ds4 3 4 pitch |Ef4 4 4 pitch |E4 4 4 pitch |Ff4 5 4 pitch |Es4 5 4 pitch |F4 6 4 pitch |Fs4 6 4 pitch |Gf4 7 4 pitch |G4 8 4 pitch |Gs4 8 4 pitch |Af4 9 4 pitch |A4 10 4 pitch |As4 10 4 pitch |Bf4 11 4 pitch |B4 11 4 pitch |Cf4 12 4 pitch |Bs4 0 5 pitch |C5 1 5 pitch |Cs5 1 5 pitch |Df5 2 5 pitch |D5 3 5 pitch |Ds5 3 5 pitch |Ef5 4 5 pitch |E5 4 5 pitch |Ff5 5 5 pitch |Es5 5 5 pitch |F5 6 5 pitch |Fs5 6 5 pitch |Gf5 7 5 pitch |G5 8 5 pitch |Gs5 8 5 pitch |Af5 9 5 pitch |A5 10 5 pitch |As5 10 5 pitch |Bf5 11 5 pitch |B5 11 5 pitch |Cf5 12 5 pitch |Bs5 0 6 pitch |C6 1 6 pitch |Cs6 1 6 pitch |Df6 2 6 pitch |D6 3 6 pitch |Ds6 3 6 pitch |Ef6 4 6 pitch |E6 4 6 pitch |Ff6 5 6 pitch |Es6 5 6 pitch |F6 6 6 pitch |Fs6 6 6 pitch |Gf6 7 6 pitch |G6 8 6 pitch |Gs6 8 6 pitch |Af6 9 6 pitch |A6 10 6 pitch |As6 10 6 pitch |Bf6 11 6 pitch |B6 11 6 pitch |Cf6 12 6 pitch |Bs6 0 7 pitch |C7 1 7 pitch |Cs7 1 7 pitch |Df7 2 7 pitch |D7 3 7 pitch |Ds7 3 7 pitch |Ef7 4 7 pitch |E7 4 7 pitch |Ff7 5 7 pitch |Es7 5 7 pitch |F7 6 7 pitch |Fs7 6 7 pitch |Gf7 7 7 pitch |G7 8 7 pitch |Gs7 8 7 pitch |Af7 9 7 pitch |A7 10 7 pitch |As7 10 7 pitch |Bf7 11 7 pitch |B7 11 7 pitch |Cf7 12 7 pitch |Bs7 0 8 pitch |C8 1 8 pitch |Cs8 1 8 pitch |Df8 2 8 pitch |D8 3 8 pitch |Ds8 3 8 pitch |Ef8 4 8 pitch |E8 4 8 pitch |Ff8 5 8 pitch |Es8 5 8 pitch |F8 6 8 pitch |Fs8 6 8 pitch |Gf8 7 8 pitch |G8 8 8 pitch |Gs8 8 8 pitch |Af8 9 8 pitch |A8 10 8 pitch |As8 10 8 pitch |Bf8 11 8 pitch |B8 11 8 pitch |Cf8 12 8 pitch |Bs8 previous \ --- Note length --- : bpm->seconds ( bpm -- secs ) 60.0 swap f/ ; : rhythm->seconds ( rhy -- secs ) 4.0 tempo@ bpm->seconds f* f* ; hide : notelength ( scale "name" --; self -- r ) create , does> ( self -- r ) @ ( scale ) rhythm->seconds ( secs ) ; set-current 1.0 notelength |W \ whole 2.0 1/f notelength |H \ half 4.0 1/f notelength |Q \ quarter 8.0 1/f notelength |A \ eighth 16.0 1/f notelength |S \ sixteenth 32.0 1/f notelength |T \ thirty-second 1.0 2.0 1/f f+ notelength |W. 2.0 1/f 4.0 1/f f+ notelength |H. 4.0 1/f 8.0 1/f f+ notelength |Q. 8.0 1/f 16.0 1/f f+ notelength |A. 16.0 1/f 32.0 1/f f+ notelength |S. previous \ === Global User Variables (settable in ~/.snd_forth or ~/.fthrc) === "fth 2015/02/25" value *clm-version* #f value *locsig* mus-lshort value *clm-audio-format* #f value *clm-comment* 1.0 value *clm-decay-time* #f value *clm-delete-reverb* "test.snd" value *clm-file-name* #f value *clm-notehook* #f value *clm-play* #f value *clm-player* #f value *clm-reverb* 1 value *clm-reverb-channels* #() value *clm-reverb-data* "test.reverb" value *clm-reverb-file-name* #f value *clm-statistics* #f value *clm-verbose* #f value *clm-debug* "CLM_SEARCH_PATH" getenv "." || ":" string-split value *clm-search-list* <'> *clm-search-list* "List of directories with sound files." help-set! #() value *clm-instruments* <'> *clm-instruments* "List of #( ins-name start dur local-vars ) elements. \ Instruments using RUN or RUN-INSTRUMENT add entries to the list." help-set! 'snd provided? [unless] 1 constant default-output-chans 44100 constant default-output-srate mus-next constant default-output-header-type mus-lfloat constant default-output-sample-type 1024 constant dac-size [then] default-output-chans value *clm-channels* default-output-srate value *clm-srate* locsig-type value *clm-locsig-type* default-output-header-type value *clm-header-type* default-output-sample-type value *clm-sample-type* dac-size value *clm-rt-bufsize* mus-file-buffer-size value *clm-file-buffer-size* mus-clipping value *clm-clipped* mus-array-print-length value *clm-array-print-length* clm-table-size value *clm-table-size* clm-default-frequency value *clm-default-frequency* \ for backward compatibility *clm-sample-type* value *clm-data-format* <'> *clm-data-format* lambda: <{ val -- res }> val to *clm-sample-type* val ; trace-var <'> *clm-default-frequency* lambda: <{ val -- res }> val set-clm-default-frequency ; trace-var <'> *clm-table-size* lambda: <{ val -- res }> val set-clm-table-size ; trace-var \ internal global variables *clm-channels* value *channels* *clm-verbose* value *verbose* *clm-notehook* value *notehook* 'snd provided? [if] <'> snd-tempnam alias fth-tempnam [else] hide user *fth-file-number* set-current : fth-tempnam ( -- name ) doc" Look for environment variables TMP, TEMP, and TMPDIR. \ If none of them is set, use /tmp as temporary path. \ Produces something like:\n\ /tmp/fth-12345-1.snd\n\ /tmp/fth-12345-2.snd\n\ /tmp/fth-12345-3.snd\n\ ..." 1 *fth-file-number* +! environ { env } "%s/fth-%d-%d.snd" env "TMP" array-assoc-ref ?dup-if ( tmp ) else env "TEMP" array-assoc-ref ?dup-if ( temp ) else env "TMPDIR" array-assoc-ref ?dup-if ( tmpdir ) else "/tmp" then then then ( tmp ) getpid *fth-file-number* @ 3 >array string-format ; previous [then] : make-default-comment ( -- str ) "\\ Written %s by %s at %s using clm (%s)" #( "%a %d-%b-%y %H:%M %Z" current-time strftime getlogin gethostname *clm-version* ) string-format ; : times->samples { start dur -- len beg } start seconds->samples { beg } dur seconds->samples { len } beg len d+ beg ; \ === With-Sound Run-Instrument === "with-sound error" create-exception with-sound-error "with-sound interrupt" create-exception with-sound-interrupt #() value *ws-args* \ array for recursive with-sound calls #f value *clm-current-instrument* \ current instrument set in INSTRUMENT: : ws-local-variables ( -- ) nil { vals } *clm-instruments* empty? if "*clm-instruments* is empty" #() clm-message else "" #() clm-message *clm-instruments* each to vals "=== %s [%.3f-%.3f] ===" #( vals 0 array-ref vals 1 array-ref vals 2 array-ref ) clm-message vals 3 array-ref each { var } \ var: '( name . value ) ) "%s = %s" var clm-message end-each "" #() clm-message end-each then ; : ws-info { start dur vars -- start dur } *clm-instruments* #( *clm-current-instrument* start dur vars ) array-push drop *notehook* word? if *notehook* #( *clm-current-instrument* start dur ) run-proc drop then start dur ; hide : (run) ( start dur vars -- limit begin ) ws-info times->samples ; : (run-instrument) { start dur args vars -- limit begin } args hash? unless #{} to args then :degree args :degree hash-ref 0.0 || :distance args :distance hash-ref 1.0 || :reverb args :reverb hash-ref 0.05 || :channels args :channels hash-ref *channels* || :output args :output hash-ref *output* || :revout args :revout hash-ref *reverb* || :type args :type hash-ref locsig-type || make-locsig to *locsig* \ we set channel 3/4 if any to 0.5 * channel 1/2 *output* mus-output? if *output* mus-channels 2 > if *locsig* 2 *locsig* 0 locsig-ref f2/ locsig-set! drop *output* mus-channels 3 > if *locsig* 3 *locsig* 1 locsig-ref f2/ locsig-set! drop then then then *reverb* mus-output? if *reverb* mus-channels 2 > if *locsig* 2 *locsig* 0 locsig-reverb-ref f2/ locsig-reverb-set! drop *reverb* mus-channels 3 > if *locsig* 3 *locsig* 1 locsig-reverb-ref f2/ locsig-reverb-set! drop then then then start dur vars (run) ; : (end-run) { val idx -- } *locsig* idx val locsig drop ; set-current \ RUN/LOOP is only a simple replacement of \ start dur TIMES->SAMPLES ?DO ... LOOP \ \ RUN-INSTRUMENT/END-RUN requires at least an opened *output* \ generator (file->sample), optional an opened *reverb* generator. It \ uses LOCSIG to set samples in output file. At the end of the loop a \ sample value must remain on top of stack! \ \ instrument: foo \ 0 0.1 nil run-instrument 0.2 end-run \ ;instrument \ <'> foo with-sound \ \ fills a sound file of length 0.1 seconds with 2205 samples (srate \ 22050) with 0.2. \ \ 0.0 1.0 RUN ... LOOP \ 0.0 1.0 #{ :degree 45.0 } RUN-INSTRUMENT ... END-RUN : run ( start dur -- ) postpone local-variables postpone (run) postpone ?do ; immediate compile-only : run-instrument ( start dur locsig-args -- ) postpone local-variables postpone (run-instrument) postpone ?do ; immediate compile-only : end-run ( sample -- ) postpone r@ postpone (end-run) postpone loop ; immediate compile-only previous : reverb-info { caller in-chans out-chans -- } "%s on %d in and %d out channels" #( caller in-chans out-chans ) clm-message ; \ === Helper functions for instruments === hide : ins-info ( ins-name -- ) to *clm-current-instrument* ; : event-info { ename -- } *clm-verbose* if ename #() clm-message then ; set-current : instrument: ( "name" -- ) >in @ parse-word $>string { ins-name } >in ! : ins-name postpone literal <'> ins-info compile, ; : event: ( "name" -- ) >in @ parse-word $>string { ev-name } >in ! : ev-name postpone literal <'> event-info compile, ; : ;instrument ( -- ) postpone ; ; immediate <'> ;instrument alias ;event immediate previous \ === Playing and Recording Sound Files === : find-file ( file -- fname|#f ) doc" Return the possible full path name of FILE if FILE exists or \ if FILE was found in *CLM-SEARCH-LIST*, otherwise return #f." { file } file file-exists? if file else #f { fname } file string? *clm-search-list* array? && if *clm-search-list* each ( dir ) "/" $+ file $+ dup file-exists? if to fname leave else drop then end-each then fname then ; hide : .maxamps { fname name sr scl? -- } fname file-exists? if fname mus-sound-maxamp { vals } scl? if " (before scaling)" else "" then { scaled } vals length 0 ?do "%6s %c: %.3f (near %.3f secs)%s" #( name [char] A i 2/ + vals i 1+ array-ref vals i array-ref sr f/ scaled ) clm-message 2 +loop then ; : .timer { obj -- } " real: %.3f (utime %.3f, stime %.3f)" #( obj real-time@ obj user-time@ obj system-time@ ) clm-message ; : .timer-ratio { sr frms obj -- } frms 0> if sr frms f/ { m } " ratio: %.2f (uratio %.2f)" #( obj real-time@ m f* obj user-time@ m f* ) else " ratio: no ratio" #() then clm-message ; set-current : snd-info <{ output :key reverb-file-name #f scaled? #f timer #f -- }> output mus-sound-duration { dur } output mus-sound-framples { frms } output mus-sound-chans { channels } output mus-sound-srate { srate } "filename: %S" #( output ) clm-message " chans: %d, srate: %d" #( channels srate f>s ) clm-message " format: %s [%s]" #( output mus-sound-sample-type mus-sample-type-name output mus-sound-header-type mus-header-type-name ) clm-message " length: %.3f (%d frames)" #( dur frms ) clm-message timer timer? if timer .timer srate frms timer .timer-ratio then output "maxamp" srate scaled? .maxamps reverb-file-name ?dup-if "revamp" srate #f .maxamps then output mus-sound-comment { comm } comm empty? unless " comment: %S" #( comm ) clm-message then ; previous : clm-mix <{ infile :key output #f output-frame 0 frames #f input-frame 0 scaler #f -- }> doc" Mix files in with-sound's *output* generator.\n\ \"oboe.snd\" clm-mix\n\ Mixes oboe.snd in *output* at *output*'s \ location 0 from oboe.snd's location 0 on. \ The whole oboe.snd file will be mixed in because :frames is not specified." 0 { chans } *output* mus-output? { outgen } output unless outgen if *output* mus-channels to chans *output* mus-file-name to output else 'with-sound-error #( "%s: *output* gen or :output required" get-func-name ) fth-throw then then infile find-file to infile infile unless 'file-not-found #( "%s: can't find %S" get-func-name infile ) fth-throw then frames infile mus-sound-framples || dup unless drop undef then to frames outgen if *output* mus-close drop then chans 0> scaler && scaler f0<> && if chans chans * scaler make-vct else #f then { mx } output ( outfile ) infile ( infile ) output-frame ( outloc ) frames ( frames ) input-frame ( inloc ) mx ( matrix ) #f ( envs ) mus-file-mix drop outgen if output continue-sample->file to *output* then ; [ifundef] ws-is-array? #f value ws-is-array? [then] ws-is-array? [if] <'> #() alias #w{} ( -- ws ) <'> array? alias ws? ( obj -- f ) <'> array-assoc-ref alias ws-ref ( ws key -- val ) <'> array-assoc-set! alias ws-set! ( ws key val -- 'ws ) [else] <'> #{} alias #w{} ( -- ws ) <'> hash? alias ws? ( obj -- f ) <'> hash-ref alias ws-ref ( ws key -- val ) : ws-set! ( ws key val -- 'ws ) 3 pick >r hash-set! r> ; [then] hide : ws-get-snd ( ws -- snd ) ( ws ) :output ws-ref find-file { fname } fname 0 find-sound dup sound? if dup save-sound drop close-sound then drop fname open-sound ; : ws-scaled-to { ws -- } ws :scaled-to ws-ref { scale } 'snd provided? if ws ws-get-snd { snd } 0.0 snd #t #f maxamp each fmax end-each { mx } mx f0<> if scale mx f/ to scale snd #f #f framples { len } ws :channels ws-ref 0 ?do scale 0 len snd i ( chn ) #f scale-channel drop loop then snd save-sound drop else ws :output ws-ref mus-sound-maxamp { smax } 0.0 smax length 1 ?do smax i array-ref fabs fmax 2 +loop { mx } mx f0<> if ws :output ws-ref :scaler scale mx f/ clm-mix then then ; : ws-scaled-by { ws -- } ws :scaled-by ws-ref { scale } 'snd provided? if ws ws-get-snd { snd } snd #f #f framples { len } ws :channels ws-ref 0 ?do scale 0 len snd i ( chn ) #f scale-channel drop loop snd save-sound drop else ws :output ws-ref :scaler scale clm-mix then ; : ws-before-output { ws -- } ws :old-table-size clm-table-size ws-set! ( ws ) :old-file-buffer-size mus-file-buffer-size ws-set! ( ws ) :old-array-print-length mus-array-print-length ws-set! ( ws ) :old-clipped mus-clipping ws-set! ( ws ) :old-srate mus-srate ws-set! ( ws ) :old-locsig-type locsig-type ws-set! ( ws ) :old-*output* *output* ws-set! ( ws ) :old-*reverb* *reverb* ws-set! ( ws ) :old-verbose *verbose* ws-set! ( ws ) :old-debug *clm-debug* ws-set! ( ws ) :old-channels *channels* ws-set! ( ws ) :old-notehook *notehook* ws-set! ( ws ) :old-decay-time *clm-decay-time* ws-set! to ws ws :verbose ws-ref to *verbose* ws :debug ws-ref to *clm-debug* ws :channels ws-ref to *channels* ws :notehook ws-ref to *notehook* ws :decay-time ws-ref to *clm-decay-time* *clm-file-buffer-size* set-mus-file-buffer-size drop *clm-array-print-length* set-mus-array-print-length drop ws :scaled-to ws-ref ws :scaled-by ws-ref || if #( mus-bfloat mus-lfloat mus-bdouble mus-ldouble ) ws :sample-type ws-ref array-member? if #f set-mus-clipping else *clm-clipped* set-mus-clipping then else *clm-clipped* set-mus-clipping then drop ws :srate ws-ref set-mus-srate drop ws :locsig-type ws-ref set-locsig-type drop ; : ws-after-output { ws -- ws } ws :old-table-size ws-ref set-clm-table-size drop ws :old-file-buffer-size ws-ref set-mus-file-buffer-size drop ws :old-array-print-length ws-ref set-mus-array-print-length drop ws :old-clipped ws-ref set-mus-clipping drop ws :old-srate ws-ref set-mus-srate drop ws :old-locsig-type ws-ref set-locsig-type drop ws :old-*output* ws-ref to *output* ws :old-*reverb* ws-ref to *reverb* ws :old-verbose ws-ref to *verbose* ws :old-debug ws-ref to *clm-debug* ws :old-channels ws-ref to *channels* ws :old-notehook ws-ref to *notehook* ws :old-decay-time ws-ref to *clm-decay-time* *ws-args* array-pop ; : ws-statistics { ws -- } ws :output ws-ref :reverb-file-name ws :reverb-file-name ws-ref :scaled? ws :scaled-to ws-ref ws :scaled-by ws-ref || :timer ws :timer ws-ref snd-info ; : set-args { key def ws -- } key def get-optkey ws key rot ws-set! to ws ; set-current \ player: xt, proc, string, or #f. \ \ xt: output player execute \ proc: player #( output ) run-proc \ string: "player output" system \ else snd: output :wait #t play \ or clm: output play-sound \ \ A player may look like this: \ \ : play-3-times { output -- } \ 3 0 ?do \ output :wait #t play drop \ loop \ ; \ <'> play-3-times to *clm-player* defer ws-play : ws-play-it { ws -- } ws :output ws-ref { output } ws :player ws-ref { player } player word? if player #( output ) run-proc else player string? if player $space $+ output $+ file-system else 'snd provided? if output find-file :wait #t ws-play else "sndplay " output $+ file-system then then then drop ; : ws-output ( ws -- fname ) :output ws-ref ; : with-sound-default-args ( keyword-args -- ws ) #() to *clm-instruments* #w{} { ws } *ws-args* ws array-push to *ws-args* :channels *clm-channels* ws set-args :clipped *clm-clipped* ws set-args :comment *clm-comment* ws set-args :continue-old-file #f ws set-args :sample-type *clm-sample-type* ws set-args :debug *clm-debug* ws set-args :decay-time *clm-decay-time* ws set-args :delete-reverb *clm-delete-reverb* ws set-args :header-type *clm-header-type* ws set-args :locsig-type *clm-locsig-type* ws set-args :notehook *clm-notehook* ws set-args :output *clm-file-name* ws set-args :play *clm-play* ws set-args :player *clm-player* ws set-args :reverb *clm-reverb* ws set-args :reverb-channels *clm-reverb-channels* ws set-args :reverb-data *clm-reverb-data* ws set-args :reverb-file-name *clm-reverb-file-name* ws set-args :scaled-by #f ws set-args :scaled-to #f ws set-args :srate *clm-srate* ws set-args :statistics *clm-statistics* ws set-args :verbose *clm-verbose* ws set-args \ for backward compatibility :data-format *clm-sample-type* get-optkey ws :sample-type rot ws-set! to ws ws ; : with-sound-args ( keyword-args -- ws ) #w{} { ws } *ws-args* -1 array-ref { ws1 } *ws-args* ws array-push to *ws-args* :play #f ws set-args :player #f ws set-args :statistics #f ws set-args :continue-old-file #f ws set-args :verbose ws1 :verbose ws-ref ws set-args :debug ws1 :debug ws-ref ws set-args :output ws1 :output ws-ref ws set-args :channels ws1 :channels ws-ref ws set-args :srate ws1 :srate ws-ref ws set-args :locsig-type ws1 :locsig-type ws-ref ws set-args :header-type ws1 :header-type ws-ref ws set-args :sample-type ws1 :sample-type ws-ref ws set-args :comment "with-sound level %d" #( *ws-args* length ) string-format ws set-args :notehook ws1 :notehook ws-ref ws set-args :scaled-to ws1 :scaled-to ws-ref ws set-args :scaled-by ws1 :scaled-by ws-ref ws set-args :delete-reverb ws1 :delete-reverb ws-ref ws set-args :reverb ws1 :reverb ws-ref ws set-args :reverb-data ws1 :reverb-data ws-ref ws set-args :reverb-channels ws1 :reverb-channels ws-ref ws set-args :reverb-file-name ws1 :reverb-file-name ws-ref ws set-args :decay-time ws1 :decay-time ws-ref ws set-args \ for backward compatibility :data-format ws1 :sample-type ws-ref get-optkey ws :sample-type rot ws-set! to ws ws ; : with-sound-main { body-xt ws -- ws } body-xt word? body-xt 1 "a proc or xt" assert-type ws ws? ws 2 "a ws object" assert-type ws ws-before-output ws :reverb ws-ref { reverb-xt } reverb-xt if reverb-xt word? reverb-xt 3 "a proc or xt" assert-type #t else #f then { rev? } ws :output ws-ref { output } ws :reverb-file-name ws-ref { revput } ws :continue-old-file ws-ref { cont? } cont? if output continue-sample->file else output file-delete output ws :channels ws-ref ws :sample-type ws-ref ws :header-type ws-ref ws :comment ws-ref dup empty? if drop make-default-comment then make-sample->file then to *output* *output* sample->file? unless 'with-sound-error #( "%s: can't open sample->file" get-func-name ) fth-throw then cont? if output mus-sound-srate set-mus-srate drop 'snd provided? if output 0 find-sound dup sound? if close-sound then drop then then rev? if cont? if revput continue-sample->file else revput file-delete revput ws :reverb-channels ws-ref ws :sample-type ws-ref ws :header-type ws-ref "with-sound temporary reverb file" make-sample->file then to *reverb* *reverb* sample->file? unless 'with-sound-error #( "%s: can't open reverb sample->file" get-func-name ) fth-throw then then ws :timer make-timer ws-set! to ws \ compute ws body body-xt #t nil fth-catch if stack-reset *output* mus-close drop *reverb* if *reverb* mus-close drop then ws ws-after-output ( ws ) "%s: body-xt interrupted; output closed" #( get-func-name ) clm-message \ reraise last exception #f #f #f fth-raise then reverb-xt if *reverb* mus-close drop ws :reverb-file-name ws-ref undef make-file->sample to *reverb* *reverb* file->sample? unless 'with-sound-error #( "%s: can't open file->sample" get-func-name ) fth-throw then \ compute ws reverb \ push reverb arguments on stack ws :reverb-data ws-ref each end-each reverb-xt #t nil fth-catch if stack-reset *output* mus-close drop *reverb* mus-close drop ws ws-after-output ( ws ) "%s: reverb-xt interrupted; output closed" #( get-func-name ) clm-message \ reraise last exception #f #f #f fth-raise then *reverb* mus-close drop then *output* mus-close drop ws :timer ws-ref stop-timer 'snd provided? if ws ws-get-snd drop then ws :statistics ws-ref if ws ws-statistics then reverb-xt if ws :delete-reverb ws-ref if ws :reverb-file-name ws-ref file-delete then then ws :scaled-to ws-ref if ws ws-scaled-to then ws :scaled-by ws-ref if ws ws-scaled-by then ws :play ws-ref if ws ws-play-it then ws ws-after-output ( ws ) ; previous \ Usage: <'> resflt-test with-sound drop \ <'> resflt-test :play #f :channels 2 with-sound .g \ lambda: resflt-test ; :output "resflt.snd" with-sound drop : with-sound ( body-xt keyword-args -- ws ) doc" \\ keywords and default values:\n\ :play *clm-play* (#f)\n\ :statistics *clm-statistics* (#f)\n\ :verbose *clm-verbose* (#f)\n\ :debug *clm-debug* (#f)\n\ :continue-old-file (#f)\n\ :output *clm-file-name* (\"test.snd\")\n\ :channels *clm-channels* (1)\n\ :srate *clm-srate* (44100)\n\ :locsig-type *clm-locsig-type* (mus-interp-linear)\n\ :header-type *clm-header-type* (mus-next)\n\ :sample-type *clm-sample-type* (mus-lfloat)\n\ :clipped *clm-clipped* (#t)\n\ :comment *clm-comment* (#f)\n\ :notehook *clm-notehook* (#f)\n\ :scaled-to (#f)\n\ :scaled-by (#f)\n\ :delete-reverb *clm-delete-reverb* (#f)\n\ :reverb *clm-reverb* (#f)\n\ :reverb-data *clm-reverb-data* (#())\n\ :reverb-channels *clm-reverb-channels* (1)\n\ :reverb-file-name *clm-reverb-file-name* (\"test.reverb\")\n\ :player *clm-player* (#f)\n\ :decay-time *clm-decay-time* (1.0)\n\ Execute BODY-XT, a proc object or an xt, \ and returns a ws-args object with with-sound arguments.\n\ <'> resflt-test with-sound .$ cr\n\ <'> resflt-test :play #t :channels 2 :srate 48000 with-sound drop" *ws-args* empty? if with-sound-default-args else with-sound-args then with-sound-main ( ws ) ; : clm-load ( fname keyword-args -- ws ) doc" Load and eval the CLM instrument file FNAME. \ See with-sound for a full keyword list.\n\ \"test.fsm\" :play #t :player \"sndplay\" clm-load drop" *ws-args* empty? if with-sound-default-args else with-sound-args then { fname ws } fname file-exists? if ws :verbose ws-ref if "loading %S" #( fname ) clm-message then fname <'> file-eval ws with-sound-main ( ws ) else 'no-such-file #( "%s: %S not found" get-func-name fname ) fth-throw then ; : with-current-sound <{ body-xt :key offset 0.0 scaled-to #f scaled-by #f -- }> doc" Must be called within with-sound body. \ Take all arguments from current with-sound except \ :output, :scaled-to, :scaled-by and :comment." *output* mus-output? false? if 'with-sound-error #( "%s can only be called within with-sound" get-func-name ) fth-throw then with-sound-args { ws } fth-tempnam { output } ws :output output ws-set! ( ws ) :scaled-to scaled-to ws-set! ( ws ) :scaled-by scaled-by ws-set! to ws body-xt ws with-sound-main drop output :output-frame offset seconds->samples clm-mix output file-delete ; : scaled-to <{ body-xt scl -- }> doc" Must be called within with-sound body. \ Scale BODY-XT's resulting sound file to SCL.\n\ lambda: ( -- )\n\ 0.0 0.1 660.0 0.5 fm-violin\n\ 0.5 0.1 550.0 0.1 <'> fm-violin 0.8 scaled-to ( scaled to 0.8 )\n\ ; with-sound" body-xt :scaled-to scl with-current-sound ; : scaled-by <{ body-xt scl -- }> doc" Must be called within with-sound body. \ Scale BODY-XT's resulting sound file by SCL.\n\ lambda: ( -- )\n\ 0.0 0.1 660.0 0.5 fm-violin\n\ 0.5 0.1 550.0 0.1 <'> fm-violin 2.0 scaled-by ( scaled to 0.2 )\n\ ; with-sound" body-xt :scaled-by scl with-current-sound ; : with-offset <{ body-xt sec -- }> doc" Must be called within with-sound body. \ Mix BODY-XT's resulting sound file into main sound file at SEC seconds.\n\ lambda: ( -- )\n\ 0.0 0.1 660.0 0.5 fm-violin\n\ 0.5 0.1 550.0 0.1 <'> fm-violin 1.0 \ with-offset ( its actual begin time is 1.5 )\n\ ; with-sound" body-xt :offset sec with-current-sound ; : with-mix <{ body-str args fname start -- }> doc" BODY-STR is a string with with-sound commands or NIL, \ ARGS is an array of with-sound arguments, \ FNAME is the temporary mix file name without extension, \ and START is the begin time for mix in. \ If BODY-STR is NIL a notelist file FNAME.fsm must exist.\n\ lambda: ( -- )\n\ 0.0 0.1 440 0.1 fm-violin\n\ \"\n\ 0.0 0.1 550 0.1 fm-violin\n\ 0.1 0.1 660 0.1 fm-violin\n\ \" #() \"sec1\" 0.5 with-mix\n\ \"\n\ 0.0 0.1 880 0.1 :reverb-amount 0.2 fm-violin\n\ 0.1 0.1 1320 0.1 :reverb-amount 0.2 fm-violin\n\ \" #( :reverb <'> jc-reverb ) \"sec2\" 1.0 with-mix\n\ 2.0 0.1 220 0.1 fm-violin\n\ ; with-sound drop" body-str string? body-str nil? || body-str 1 "a string or nil" assert-type args array? args list? || args 2 "an array or a list" assert-type fname string? fname 3 "a string" assert-type start number? start 4 "a number" assert-type *output* mus-output? false? if 'with-sound-error #( "%s can only be called within with-sound" get-func-name ) fth-throw then fname ".snd" $+ { snd-file } fname ".fsm" $+ { mix-file } fname ".reverb" $+ { rev-file } snd-file file-exists? if snd-file file-mtime else #f then { snd-time } body-str string? if mix-file file-exists? if mix-file readlines "" array-join else "" then ( old-body ) body-str string= if mix-file file-mtime else mix-file #( body-str ) writelines #f then else \ body-str is nil mix-file file-exists? if mix-file file-mtime else 'no-such-file #( "%s: %S not found" get-func-name mix-file ) fth-throw then then { mix-time } snd-time false? mix-time false? || snd-time mix-time d< || if mix-file args each ( put all args on stack ) end-each :output snd-file :reverb-file-name rev-file clm-load drop then snd-file :output-frame start seconds->samples clm-mix ; : sound-let ( ws-xt-lst body-xt -- ) doc" Require array of arrays WS-XT-LST with with-sound args \ and xts, and a BODY-XT. \ The BODY-XT must take WS-XT-LST length arguments which are tempfile names. \ with-sound will be feed with ws-args und ws-xts from WS-XT-LST. \ :output is set to tempnam which will be on stack before executing BODY-XT. \ These temporary files will be deleted after execution of BODY-XT.\n\ #( #( #( :reverb <'> jc-reverb ) 0.0 1 220 0.2 <'> fm-violin )\n\ #( #() 0.5 1 440 0.3 <'> fm-violin ) ) ( the ws-xt-lst )\n\ lambda: { tmp1 tmp2 }\n\ tmp1 :output tmp2 clm-mix\n\ tmp1 clm-mix\n\ ; ( the body-xt ) <'> sound-let with-sound drop" { ws-xt-lst body-xt } ws-xt-lst array? ws-xt-lst 1 "an array" assert-type body-xt word? body-xt 2 "a proc or xt" assert-type *output* mus-output? unless 'with-sound-error #( "%s can only be called within with-sound" get-func-name ) fth-throw then ws-xt-lst map *key* 0 array-ref ( args ) each ( put all args on stack ) end-each with-sound-args ( ws ) :output fth-tempnam ws-set! { ws } *key* 1 array-ref ( xt ) each ( put all xts on stack ) end-each ws with-sound-main :output ws-ref ( outfile ) end-map { outfiles } body-xt xt? if outfiles each end-each body-xt execute else body-xt outfiles run-proc drop then outfiles each ( file ) file-delete end-each ; \ === Playing Sounds === : play-sound <{ :key verbose *clm-verbose* player *clm-player* :optional input *clm-file-name* -- }> doc" Play sound file INPUT.\n\ \"bell.snd\" :verbose #t play-sound" input find-file to input input unless 'no-such-file #( "%s: %s" get-func-name input ) fth-throw then verbose if input snd-info then #w{} :output input ws-set! :player player ws-set! ws-play-it ; 'snd provided? [unless] <'> play-sound alias play [then] <'> play is ws-play \ === Example instruments, more in clm-ins.fs === instrument: simp { start dur freq amp -- } :frequency freq make-oscil { os } :envelope #( 0 0 25 1 75 1 100 0 ) :duration dur :scaler amp make-env { en } start dur run i os 0.0 0.0 oscil en env f* *output* outa drop loop ;instrument : run-test ( -- ) 0.0 1.0 330.0 0.5 simp ; : input-fn { gen -- prc; dir self -- r } 1 proc-create ( prc ) gen , does> { dir self -- r } self @ ( gen ) readin ; instrument: src-simp { start dur amp sr sr-env fname -- } :file fname find-file make-readin { f } :input f input-fn :srate sr make-src { sc } :envelope sr-env :duration dur make-env { en } start dur run i sc en env #f src amp f* *output* outa drop loop f mus-close drop ;instrument instrument: conv-simp { start dur filt fname amp -- } :file fname find-file make-readin { f } filt string? if 8192 0.0 make-vct { v } filt find-file 0 0 v length v file->array else filt then { data } :input f input-fn :filter data make-convolve { cv } start dur run i cv #f convolve amp f* *output* outa drop loop f mus-close drop ;instrument \ <'> src-test with-sound drop event: src-test ( -- ) 0.0 1.0 1.0 0.2 #( 0 0 50 1 100 0 ) "oboe.snd" src-simp ;event \ <'> conv1-test with-sound drop event: conv1-test ( -- ) 0.0 1.0 vct( 0.5 0.2 0.1 0.05 0 0 0 0 ) "fyow.snd" 1.0 conv-simp ;event \ <'> conc2-test with-sound drop event: conv2-test ( -- ) 0.0 1.0 "pistol.snd" "fyow.snd" 0.2 conv-simp ;event \ <'> inst-test with-sound drop event: inst-test ( -- ) 0.0 1.0 1.0 0.2 #( 0 0 50 1 100 0 ) "oboe.snd" src-simp 1.2 1.0 vct( 0.5 0.2 0.1 0.05 0 0 0 0 ) "fyow.snd" 1.0 conv-simp 2.4 1.0 "pistol.snd" "fyow.snd" 0.2 conv-simp ;event \ generators.scm : make-waveshape <{ :optional freq *clm-default-frequency* parts #( 1 1 ) wave #f size *clm-table-size* -- gen }> doc" See make-polyshape." :frequency freq wave if :coeffs wave else :partials parts then make-polyshape ; <'> polyshape alias waveshape ( gen :optional index 1.0 fm 0.0 -- val ) <'> polyshape? alias waveshape? ( obj -- f ) <'> waveshape <'> polyshape help-ref help-set! <'> waveshape? <'> polyshape? help-ref help-set! : partials->waveshape <{ partials :optional size *clm-table-size* -- wave }> doc" See partials->polynomial." partials partials->polynomial ( wave ) ; \ snd10.scm : make-sum-of-sines <{ :key sines 1 frequency 0.0 initial-phase 0.0 -- gen }> doc" See make-nsin." :frequency frequency :n sines make-nsin { gen } gen initial-phase set-mus-phase drop gen ; <'> nsin alias sum-of-sines ( gen :optional fm 0.0 -- val ) <'> nsin? alias sum-of-sines? ( obj -- f ) <'> sum-of-sines <'> nsin help-ref help-set! <'> sum-of-sines? <'> nsin? help-ref help-set! : make-sum-of-cosines <{ :key cosines 1 frequency 0.0 initial-phase 0.0 -- gn }> doc" See make-ncos." :frequency frequency :n cosines make-ncos { gen } gen initial-phase set-mus-phase drop gen ; <'> ncos alias sum-of-cosines ( gen :optional fm 0.0 -- val ) <'> ncos? alias sum-of-cosines? ( obj -- f ) <'> sum-of-cosines <'> ncos help-ref help-set! <'> sum-of-cosines? <'> ncos? help-ref help-set! : make-sine-summation <{ :key frequency 0.0 initial-phase 0.0 n 1 a 0.5 ratio 1.0 -- gen }> doc" See make-nrxysin." :frequency frequency :ratio ratio :n n :r a make-nrxysin { gen } gen initial-phase set-mus-phase drop gen ; <'> nrxysin alias sine-summation ( gen :optional fm 0.0 -- val ) <'> nrxysin? alias sine-summation? ( obj -- f ) <'> sine-summation <'> nrxysin help-ref help-set! <'> sine-summation? <'> nrxysin? help-ref help-set! 'snd provided? [if] instrument: snd-arpeggio <{ start dur freq amp :key ampenv #( 0 0 0.5 1 1 0 ) offset 1.0 -- }> start dur times->samples { end beg } 12 make-array map! :frequency i 6 - 0.03 f* offset f* freq f+ :partials #( 1 1.0 5 0.7 6 0.7 7 0.7 8 0.7 9 0.7 10 0.7 ) make-polyshape end-map { waveshbank } :envelope ampenv :scaler amp 0.1 f* :length end make-env { amp-env } end 0.0 make-vct map! 0.0 ( sum ) waveshbank each ( wv ) 1.0 0.0 polyshape f+ ( sum += ... ) end-each ( sum ) amp-env env f* end-map ( vct-output ) #f channels 0 ?do ( vct-output ) beg end #f i #f undef vct->channel loop ( vct-output ) drop ;instrument event: snd-arpeggio-test ( -- snd ) mus-srate { old-sr } 48000 set-mus-srate drop :file "arpeggio.snd" :header-type mus-next :sample-type mus-bdouble :channels 2 :srate mus-srate f>s :comment make-default-comment new-sound { snd } 0 10 65 0.5 snd-arpeggio snd save-sound drop old-sr set-mus-srate drop snd ;event [then] instrument: arpeggio <{ start dur freq amp :key ampenv #( 0 0 0.5 1 1 0 ) offset 1.0 -- }> start dur times->samples { end beg } 12 make-array map! :frequency i 6 - 0.03 f* offset f* freq f+ :partials #( 1 1.0 5 0.7 6 0.7 7 0.7 8 0.7 9 0.7 10 0.7 ) make-polyshape end-map { waveshbank } :envelope ampenv :scaler amp 0.1 f* :length end make-env { amp-env } start dur #{ :degree 90.0 random } run-instrument 0.0 ( sum ) waveshbank each ( wv ) 1.0 0.0 polyshape f+ ( sum += ... ) end-each ( sum ) amp-env env f* end-run ;instrument \ <'> arpeggio-test :output "arpeggio.snd" with-sound event: arpeggio-test ( -- ) 0 10 65 0.5 arpeggio ;event \ clm.fs ends here snd-16.1/env.fs0000644000076400007640000004212612327441227011466 0ustar bilbil\ env.fs -- env.scm -> env.fs \ Translator/Author: Michael Scholz \ Created: 05/10/27 04:51:42 \ Changed: 14/04/28 03:52:17 \ \ @(#)env.fs 1.25 4/28/14 \ From env.scm|rb with original comments and doc strings from env.scm. \ \ envelope? ( obj -- f ) \ envelope-copy ( env1 -- env2 ) \ \ envelope-interp ( x env :optional base -- r ) \ interp ( x env -- r ) \ window-envelope ( beg end en1 -- en2 ) \ map-envelopes ( env1 env2 xt -- env3 ) \ add-envelopes ( env1 env2 -- env3 ) alias envelopes+ \ multiply-envelopes ( env1 env2 -- env3 ) alias envelopes* \ max-envelope ( env -- r ) \ min-envelope ( env -- r ) \ integrate-envelope ( en -- r ) \ envelope-length ( env -- n ) \ envelope-last-x ( env -- r ) \ stretch-envelope ( env oa na :optional old-decay new-decay -- new-env ) \ scale-envelope ( env1 scl :offset offset -- env2 ) \ reverse-envelope ( env1 -- env2 ) \ envelope-concatenate ( en1 ... enn n -- ne ) \ concatenate-envelopes ( en1 ... enn n -- ne ) \ repeat-envelope ( ur-env reps :optional reflected normalized -- en ) \ \ make-power-env ( envelope :key scaler offset duration -- pe ) \ power-env ( pe -- val ) \ power-env-channel ( pe :optional beg dur snd chn edpos edname -- curb ) \ powenv-channel ( envelope :optional beg dur snd chn edpos -- val ) \ envelope-exp ( en1 :optional power xgrid -- en2 ) \ rms-envelope ( file :key beg dur rfreq db -- en ) \ \ normalize-envelope ( env1 -- env2 ) require clm : envelope? ( obj -- f ) doc" Return #t if OBJ is a vct or an array \ with even length and length >= 2." ( obj ) length dup 2 mod 0= swap 2 >= && ; <'> object-copy alias envelope-copy <'> envelope-copy "( en1 -- en2 ) Copy EN1, which may be a vct or an array." help-set! \ ;;; -------- envelope-interp : envelope-interp <{ x en :optional base 1.0 -- r }> doc" Return value of ENV at X; \ BASE controls connecting segment type; \ ENV may be a vct, or an array:\n\ 0.3 #( 0.0 0.0 0.5 1.0 1.0 0.0 ) 1.0 envelope-interp => 0.6." en empty? if 0.0 else en length { size } x en 0 object-ref f<= size 2 <= || if en 1 object-ref else en 2 object-ref x f> if en 1 object-ref en 3 object-ref f= base f0= || if en 1 object-ref else base 1.0 f= if en 1 object-ref x en 0 object-ref f- en 3 object-ref en 1 object-ref f- en 2 object-ref en 0 object-ref f- f/ f* f+ else en 1 object-ref en 3 object-ref en 1 object-ref f- base 1.0 f- f/ base x en 0 object-ref f- en 2 object-ref en 0 object-ref f- f/ f** 1.0 f- f* f+ then then else x size 2 ?do en i object-ref loop size 2 - >array base recurse ( envelope-interp ) then then then ; : interp ( x env -- r ) doc" 0.3 #( 0.0 0.0 0.5 1.0 1.0 0.0 ) interp => 0.6." 1.0 envelope-interp ; \ ;;; -------- window-envelope (a kinda brute-force translation from the CL version in env.lisp) : window-envelope ( beg end en1 -- en2 ) doc" Return portion of EN1 lying between x axis values BEG and END:\n\ 1.0 3.0 #( 0.0 0.0 5.0 1.0 ) window-envelope => #( 1.0 0.2 3.0 0.6 )." { beg end en1 } #() { en2 } en1 length 1 > if en1 1 array-ref else 0.0 then { lasty } #f { return-early? } en1 length 0 ?do en1 i array-ref { x } en1 i 1+ array-ref { y } y to lasty en2 empty? if x beg f>= if en2 beg array-push beg en1 1.0 envelope-interp array-push to en2 x beg f<> if x end f>= if en2 end array-push end en1 1.0 envelope-interp array-push to en2 #t to return-early? leave else en2 #( x y ) array-push to en2 then then then else x end f<= if en2 x array-push y array-push to en2 x end f= if #t to return-early? leave then else x end f> if en2 end array-push end en1 1.0 envelope-interp array-push to en2 #t to return-early? leave then then then 2 +loop return-early? unless en2 end array-push lasty array-push to en2 then en2 ; \ ;;; -------- map-envelopes like map-across-envelopes in env.lisp hide : fnumb-cmp ( a b -- -1|0|1 ) { a b } a b f< if -1 else a b f= if 0 else 1 then then ; : (at0) ( en xs-array -- en' ) { en xs } en 0 object-ref { diff } en -2 object-ref { lastx } en length 0 ?do en i object-ref diff f- lastx f/ ( x ) xs over array-push drop en i rot object-set! 2 +loop en ; set-current : map-envelopes ( en1 en2 xt -- en3 ) doc" Map XT over the breakpoints in EN1 and EN2 \ returning a new envelope." { en1 en2 xt } #() { xs } #() { en3 } en1 empty? if en2 xs (at0) to en3 else en2 empty? if en1 xs (at0) to en3 else en1 xs (at0) { ee1 } en2 xs (at0) { ee2 } xs array-uniq! <'> fnumb-cmp array-sort! drop xs length 2* :initial-element 0.0 make-array to en3 xs each { x } en3 i 2* x array-set! x ee1 1.0 envelope-interp x ee2 1.0 envelope-interp xt execute en3 i 2* 1+ rot array-set! end-each then then en1 array? if en3 else en1 vct? if en3 vector->vct then then ; previous \ ;;; -------- multiply-envelopes, add-envelopes : add-envelopes ( env1 env2 -- env3 ) doc" Add break-points of ENV1 and ENV2 returning a new envelope." <'> f+ map-envelopes ; : multiply-envelopes ( env1 env2 -- env3 ) doc" Multiply break-points of ENV1 and ENV2 \ returning a new envelope:\n\ #( 0 0 2 0.5 ) #( 0 0 1 2 2 1 ) multiply-envelopes\n\ => #( 0.0 0.0 0.5 0.5 1.0 0.5 )." <'> f* map-envelopes ; <'> add-envelopes alias envelopes+ <'> multiply-envelopes alias envelopes* \ ;;; -------- max-envelope : max-envelope ( en -- r ) doc" Return max y value in EN." { en } en 1 object-ref en length 1 ?do en i object-ref fmax 2 +loop ; \ ;;; -------- min-envelope : min-envelope ( en -- r ) doc" Return min y value in EN." { en } en 1 object-ref en length 1 ?do en i object-ref fmin 2 +loop ; \ ;;; -------- integrate-envelope : integrate-envelope ( en -- r ) doc" Area under env." { en } 0.0 ( sum ) en length 3 - 0 ?do en i 1+ object-ref en i 3 + object-ref f+ 0.5 f* en i 2+ object-ref en i object-ref f- f* f+ ( sum+=... ) 2 +loop ( sum ) ; : envelope-length ( en -- n ) doc" Return number of points in EN." length 2/ ; \ ;;; -------- envelope-last-x : envelope-last-x ( en -- r ) doc" Return max x axis break point position." -2 object-ref ; \ ;;; -------- stretch-envelope : stretch-envelope <{ fn old-attack new-attack :optional old-decay #f new-decay #f -- new-env }> doc" Take ENV and returns a new envelope based on it \ but with the attack and optionally decay portions stretched or squeezed; \ OLD-ATTACK is the original x axis attack end point, \ NEW-ATTACK is where that section should end in the new envelope. \ Similarly for OLD-DECAY and NEW-DECAY. \ This mimics divseg in early versions of CLM \ and its antecedents in Sambox and Mus10 (linen). \ ENV may be a vct, or an array.\n\ #( 0 0 1 1 ) 0.1 0.2 stretch-envelope => #( 0 0 0.2 0.1 1 1 )\n\ #( 0 0 1 1 2 0 ) 0.1 0.2 1.5 1.6 stretch-envelope => #( 0 0 0.2 0.1 1.1 1 1.6 0.5 2 0 )." old-decay new-decay not && if 'argument-error #( "%s: old-decay, %s, but no new-decay, %s?" get-func-name old-decay new-decay ) fth-throw then fn length { len } fn 0 object-ref dup { x0 new-x } fn 1 object-ref { y0 } fn -2 object-ref { last-x } #( x0 y0 ) { new-fn } new-attack x0 f- 0.0001 old-attack x0 f- fmax f/ { scl } old-decay if old-decay old-attack f= if old-decay 0.000001 last-x f* f+ to old-decay then then len 1- 2 ?do fn i object-ref { x1 } fn i 1+ object-ref { y1 } x0 old-attack f< x1 old-attack f>= && if x1 old-attack f= if y1 else y0 y1 y0 f- old-attack x0 f- x1 x0 f- f/ f* f+ then to y0 old-attack to x0 new-attack to new-x new-fn new-x array-push y0 array-push drop old-decay if new-decay new-attack f- old-decay old-attack f- f/ else last-x new-attack f- last-x old-attack f- f/ then to scl then old-decay if x0 old-decay f< x1 old-decay f>= && if x1 old-decay f= if y1 else y0 y1 y0 f- old-decay x0 f- x1 x0 f- f/ f* f+ then to y0 old-decay to x0 new-decay to new-x new-fn new-x array-push y0 array-push drop last-x new-decay f- last-x old-decay f- f/ to scl then then x0 x1 f<> if new-x scl x1 x0 f- f* f+ to new-x new-fn new-x array-push y1 array-push drop x1 to x0 y1 to y0 then 2 +loop fn array? if new-fn else fn vct? if new-fn vector->vct then then ; \ ;;; -------- scale-envelope : scale-envelope <{ en scl :optional offset 0 -- new-en }> doc" Scale y axis values by SCL and optionally adds OFFSET. \ EN may be a list, a vct, or an array." en map *key* i 2 mod if scl f* offset f+ then end-map ( new-en ) ; \ ;;; -------- reverse-envelope : reverse-envelope ( en1 -- en2 ) doc" Reverse the breakpoints in EN1." { en1 } en1 length { size } en1 envelope-copy { en2 } size 2 - { idx } en1 -2 object-ref { xmax } en1 length 1- 0 ?do en2 idx xmax en1 i object-ref f- object-set! en2 idx 1+ en1 i 1+ object-ref object-set! idx 2 - to idx 2 +loop en2 ; \ ;;; -------- envelope-concatenate from clm/env.lisp : envelope-concatenate ( en1 ... enn n -- ne ) doc" Concatenate N envelopes into a new envelope (from clm/env.lisp)." >array { envs } envs object-length 1 = if envs 0 array-ref else 0.0 { xoff } #() { rne } envs each { en } en first-ref { firstx } en object-length 0 ?do en i object-ref { x } en i 1+ object-ref { y } rne x firstx f- xoff f+ array-push y array-push to rne 2 +loop rne -2 array-ref 0.01 f+ to xoff end-each rne then ; \ ;;; -------- concatenate-envelopes from snd/env.scm : concatenate-envelopes ( en1 ... enn n -- ne ) doc" Concatenate N envelopes into a new envelope (from snd/env.scm)." >array { envs } envs object-length 1 = if envs 0 array-ref else 0.0 { xoff } #() { rne } envs each { en } en first-ref { firstx } rne object-length 0> if rne last-ref en second-ref f= if xoff 0.01 f- to xoff 2 else 0 then else 0 then { beg } en object-length beg ?do en i object-ref { x } en i 1+ object-ref { y } rne x firstx f- xoff f+ array-push y array-push to rne 2 +loop rne -2 object-ref 0.01 f+ to xoff end-each rne then ; \ ;;; -------- repeat-envelope : repeat-envelope <{ ur-env repeats :optional reflected #f normalized #f -- en }> doc" Repeat UR-ENV REPEATS times.\n\ #( 0 0 100 1 ) 2 repeat-envelope => #( 0 0 100 1 101 0 201 1 )\n\ If the final y value is different from the first y value, \ a quick ramp is inserted between repeats. \ NORMALIZED causes the new envelope's x axis to have the same extent as the original's. \ REFLECTED causes every other repetition to be in reverse." repeats reflected if f2/ fround->s then { times } reflected if ur-env envelope-last-x { lastx } ur-env array-copy { n-env } ur-env 0 -3 array-subarray array-reverse { r-env } r-env object-length 1- 0 ?do r-env i object-ref { xx } r-env i 1+ object-ref { yy } n-env #( lastx yy f- lastx f+ xx ) array-append to n-env 2 +loop n-env else ur-env then { e } e second-ref { first-y } e envelope-last-x { x-max } e first-ref { x } first-y e last-ref f= { first-y-is-last-y } #( x first-y ) { new-env } times 0 ?do e object-length 1- 2 ?do e i object-ref e i 2- object-ref f- x f+ to x new-env #( x e i 1+ object-ref ) array-append to new-env 2 +loop i times 1- < first-y-is-last-y not && if x-max 100.0 f/ x f+ to x new-env #( x first-y ) array-append to new-env then loop normalized if x-max x f/ { scl } new-env map! *key* i 2 mod 0= if scl f* then end-map ( new-env' ) else new-env then ; \ ;;; -------- power-env : make-power-env <{ envelope :key scaler 1.0 offset 0.0 duration 1.0 -- pe }> envelope -3 object-ref envelope 0 object-ref f- { xext } 0 { jj } envelope length 3.0 f/ fround->s 1- ( len ) make-array map! envelope jj object-ref { x0 } envelope jj 3 + object-ref { x1 } envelope jj 1+ object-ref { y0 } envelope jj 4 + object-ref { y1 } envelope jj 2+ object-ref { base } 3 +to jj :envelope #( 0.0 y0 1.0 y1 ) :base base :scaler scaler :offset offset :duration x1 x0 f- xext f/ duration f* make-env end-map { envs } #{ :envs envs :current-env 0 :current-pass envs 0 array-ref mus-length } ; : power-env ( pe -- val ) { pe } pe :envs hash-ref pe :current-env hash-ref array-ref env ( val ) pe :current-pass hash-ref 1- { pass } pass 0= if pe :current-env pe :current-env hash-ref 1+ hash-set! ( pe ) :envs hash-ref pe :current-env hash-ref array-ref mus-length to pass then pe :current-pass pass hash-set! drop ( val ) ; [defined] env-channel [if] hide : pec-cb { pe beg snd chn edpos -- prc; self -- curbeg } 0 proc-create ( prc ) pe , beg , snd , chn , edpos , does> { self -- curbeg } self @ { pe } self cell+ @ { beg } self 2 cells + @ { snd } self 3 cells + @ { chn } self 4 cells + @ { edpos } pe :envs hash-ref each { e } e mus-length 1+ { len } e beg len snd chn edpos env-channel drop len +to beg end-each beg ; set-current : power-env-channel <{ pe :optional beg 0 dur #f snd #f chn #f edpos #f edname "power-env-channel" -- curbeg }> pe beg snd chn edpos pec-cb edname as-one-edit ; previous [then] \ ;;; here's a simpler version that takes the breakpoint list, rather than the power-env structure: [defined] xramp-channel [if] hide : powc-cb { en beg dur snd chn edpos -- prc; self -- base } dur snd chn #f framples || to dur 0 proc-create ( prc ) en , beg , dur , snd , chn , edpos , does> { self -- base } self @ { en } self cell+ @ { curbeg } self 2 cells + @ { dur } self 3 cells + @ { snd } self 4 cells + @ { chn } self 5 cells + @ { edpos } en 0 array-ref { x1 } en -3 object-ref x1 f- { xrange } en 1 array-ref { y1 } en 2 array-ref { base } 0.0 0.0 { x0 y0 } en length 3 ?do x1 to x0 y1 to y0 en i object-ref to x1 en i 1+ object-ref to y1 x1 x0 f- xrange f/ dur f* fround->s { curdur } y0 y1 base curbeg curdur snd chn edpos xramp-channel drop curdur +to curbeg en i 2+ object-ref to base 3 +loop base ; set-current \ ;; envelope with a separate base for each segment: \ #( 0 0 0.325 1 1 32.0 2 0 32.0 ) powenv-channel : powenv-channel <{ envelope :optional beg 0 dur #f snd #f chn #f edpos #f -- val }> envelope length 3 = if envelope 1 array-ref beg dur snd chn edpos scale-channel else "%s %s %s %s" #( envelope beg dur get-func-name ) string-format { origin } envelope beg dur snd chn edpos powc-cb origin as-one-edit then ; previous [then] \ ;;; by Anders Vinjar: \ ;;; \ ;;; envelope-exp can be used to create exponential segments to include in \ ;;; envelopes. Given 2 or more breakpoints, it approximates the \ ;;; curve between them using 'xgrid linesegments and 'power as the \ ;;; exponent. \ ;;; \ ;;; env is a list of x-y-breakpoint-pairs, \ ;;; power applies to whole envelope, \ ;;; xgrid is how fine a solution to sample our new envelope with. : envelope-exp <{ en1 :optional power 1.0 xgrid 100 -- en2 }> en1 min-envelope { mn } en1 max-envelope mn f- { largest-diff } en1 first-ref { x-min } en1 envelope-last-x { x-max } x-max x-min f- xgrid f/ { x-incr } #() { en2 } x-min { x } 0.0 { y } largest-diff f0= if begin x en1 1.0 envelope-interp to y en2 #( x y ) array-append to en2 x-incr x f+ to x x x-max f>= until else begin x en1 1.0 envelope-interp to y en2 #( x y mn f- largest-diff f/ power f** largest-diff f* mn f+ ) array-append to en2 x-incr x f+ to x x x-max f>= until then en2 ; \ ;;; rms-envelope [defined] make-sampler [if] : rms-envelope <{ file :key beg 0.0 dur #f rfreq 30.0 db #f -- en }> file find-file to file file unless 'no-such-file #( "%s: %S" get-func-name file ) fth-throw then #() { en } rfreq 1/f { incr } file mus-sound-srate { fsr } incr fsr f* fround->s { incrsamps } beg fsr f* fround->s { start } start file 0 1 #f make-sampler { reader } dur if fsr dur f* start f+ fround->s file mus-sound-framples min else file mus-sound-framples then { end } :size incrsamps make-moving-average { rms } end 0 ?do 0.0 { rms-val } incrsamps 0 ?do reader #() apply { val } rms val dup f* moving-average to rms-val loop en i fsr f/ array-push to en rms-val fsqrt to rms-val db if rms-val 0.00001 f< if -100.0 else rms-val flog 10.0 flog f/ 20.0 f* then else rms-val then en swap array-push to en incrsamps +loop en array-reverse ; [then] \ ;;; -------- normalize-envelope : normalize-envelope <{ en1 :optional new-max 1.0 -- en2 }> doc" Scale envelope by NEW-MAX / max-envelope(EN1)." en1 second-ref en1 length 1 ?do en1 i object-ref fabs fmax 2 +loop { peak } en1 new-max peak f/ 0.0 scale-envelope ; \ env.fs ends here snd-16.1/snd-x1.h0000644000076400007640000004211412471670274011632 0ustar bilbil#ifndef SND_X1_H #define SND_X1_H /* -------- snd-xhelp.c -------- */ Widget snd_help(const char *subject, const char *help, with_word_wrap_t with_wrap); Widget snd_help_with_xrefs(const char *subject, const char *helpstr, with_word_wrap_t with_wrap, const char **xrefs, const char **urls); int help_text_width(const char *txt, int start, int end); void snd_help_append(const char *text); void snd_help_back_to_top(void); /* -------- snd-xdraw.c -------- */ void draw_line(graphics_context *ax, int x0, int y0, int x1, int y1); void draw_lines(graphics_context *ax, point_t *points, int num); void draw_points(graphics_context *ax, point_t *points, int num, int size); void fill_rectangle(graphics_context *ax, int x0, int y0, int width, int height); void erase_rectangle(chan_info *cp, graphics_context *ax, int x0, int y0, int width, int height); void fill_polygon(graphics_context *ax, int points, ...); void fill_polygons(graphics_context *ax, point_t *points, int num, int y0); void fill_two_sided_polygons(graphics_context *ax, point_t *points, point_t *points1, int num); void draw_string(graphics_context *ax, int x0, int y0, const char *str, int len); void gtk_style_draw_string(graphics_context *ax, int x0, int y0, const char *str, int len); void draw_dot(graphics_context *ax, int x, int y, int size); void setup_graphics_context(chan_info *cp, graphics_context *ax); void draw_colored_lines(chan_info *cp, graphics_context *ax, point_t *points, int num, int *colors, int axis_y0, color_t default_color); void draw_spectro_line(graphics_context *ax, int color, int x0, int y0, int x1, int y1); void allocate_color_map(int colormap); void check_colormap_sizes(int size); void reflect_color_list(bool setup_time); void allocate_sono_rects(int size); void set_sono_rectangle(int j, int color, int x, int y, int width, int height); void draw_sono_rectangles(graphics_context *ax, int color, int jmax); void set_color_scale(mus_float_t val); void set_color_inverted(bool val); void set_color_cutoff(mus_float_t val); void set_color_map(int val); void set_spectro_hop(int val); void set_spectro_x_angle(mus_float_t val); void set_spectro_y_angle(mus_float_t val); void set_spectro_z_angle(mus_float_t val); void set_spectro_x_scale(mus_float_t val); void set_spectro_y_scale(mus_float_t val); void set_spectro_z_scale(mus_float_t val); bool color_orientation_dialog_is_active(void); Widget make_color_orientation_dialog(bool managed); void reflect_spectro(void); void set_with_gl(bool val, bool with_dialogs); void g_init_gxdraw(void); /* -------- snd-xlistener.c -------- */ void add_completer_to_builtin_textfield(Widget w, int completer); void textfield_focus_callback(Widget w, XtPointer context, XtPointer info); void textfield_unfocus_callback(Widget w, XtPointer context, XtPointer info); void mouse_enter_text_callback(Widget w, XtPointer context, XEvent *event, Boolean *flag); void mouse_leave_text_callback(Widget w, XtPointer context, XEvent *event, Boolean *flag); void listener_delete_text(int new_end); void listener_append_and_prompt(const char *msg); int save_listener_text(FILE *fp); void append_listener_text(int end, const char *msg); void goto_listener(void); void color_listener(Pixel pix); void color_listener_text(Pixel pix); void listener_append(const char *msg); void handle_listener(bool new_state); bool listener_exists(void); int listener_height(void); int listener_width(void); Widget make_togglebutton_widget(const char *name, Widget parent, Arg *args, int n); Widget make_pushbutton_widget(const char *name, Widget parent, Arg *args, int n); Widget make_text_widget(const char *name, Widget parent, Arg *args, int n); Widget make_textfield_widget(const char *name, Widget parent, Arg *args, int n, text_cr_t activatable, int completer); void clear_listener(void); void set_listener_text_font(void); void g_init_gxlistener(void); /* -------- snd-xmenu.c -------- */ Widget add_menu(void); void add_menu_drop(void); Widget menu_widget(int which_menu); void check_menu_labels(int key, int state, bool extended); void reflect_play_selection_stop(void); void g_init_gxmenu(void); void set_button_label(Widget label, const char *str); void add_tooltip(Widget w, const char *tip); void post_basic_popup_menu(void *ev); void post_lisp_popup_menu(void *ev); void post_fft_popup_menu(void *ev); void post_selection_popup_menu(void *ev); widget_t make_file_print_dialog(bool managed, bool direct_to_printer); void save_print_dialog_state(FILE *fd); /* -------- snd-xmain.c -------- */ void snd_doit(int argc, char **argv); color_t get_in_between_color(color_t fg, color_t bg); void auto_update_restart(void); void save_colors(FILE *Fp); /* -------- snd-xfft.c -------- */ void set_fft_window_beta(mus_float_t val); void set_fft_window_alpha(mus_float_t val); void set_transform_size(mus_long_t val); void set_fft_window(mus_fft_window_t val); void set_wavelet_type(int val); Widget make_transform_dialog(bool managed); bool transform_dialog_is_active(void); void set_spectrum_start(mus_float_t val); void set_spectrum_end(mus_float_t val); void set_transform_type(int val); void make_transform_type_list(void); void set_show_transform_peaks(bool val); void set_fft_log_magnitude(bool val); void set_fft_with_phases(bool val); void set_fft_log_frequency(bool val); void set_transform_normalization(fft_normalize_t val); void set_show_selection_transform(bool show); void set_transform_graph_type(graph_type_t val); void reflect_peaks_in_transform_dialog(void); void reflect_log_freq_start_in_transform_dialog(void); void reflect_min_db_in_transform_dialog(void); /* -------- snd-xregion.c -------- */ int update_region_browser(bool grf_too); bool region_browser_is_active(void); void delete_region_and_update_browser(int n); void reflect_play_region_stop(int n); bool region_dialog_is_active(void); void allocate_region_rows(int n); void reflect_regions_in_region_browser(void); void reflect_no_regions_in_region_browser(void); void reflect_region_graph_style(void); void g_init_gxregion(void); /* -------- snd-gxbitmaps.c -------- */ const char **mini_bomb_bits(int n); const char **mini_glass_bits(int n); const char **mini_lock_bits(void); const char **close_icon_bits(void); const char **snd_icon_bits(void); const char **blank_bits(void); void make_icons_transparent(const char *basic_color); const char **stop_sign_bits(void); void make_toolbar_icons(Widget w); enum {SND_XPM_BACK_ARROW, SND_XPM_FORWARD_ARROW, SND_XPM_ZOOM_IN, SND_XPM_ZOOM_OUT, SND_XPM_CUT, SND_XPM_PASTE, SND_XPM_PREFERENCES, SND_XPM_CLOSE, SND_XPM_REDO, SND_XPM_UNDO, SND_XPM_SAVE, SND_XPM_SAVE_AS, SND_XPM_NEW, SND_XPM_OPEN, SND_XPM_NEXT, SND_XPM_BACK, SND_XPM_EXIT, SND_XPM_SEPARATOR, SND_XPM_UP, SND_XPM_STOP, SND_XPM_REVERT, SND_XPM_PLAY, SND_XPM_CURSOR_PLAY, SND_XPM_STOP_PLAY, NUM_TOOLBAR_PIXMAPS}; Pixmap toolbar_icon(int which); void show_toolbar(void); void hide_toolbar(void); /* -------- snd-gxcolormaps.c -------- */ char *colormap_name(int n); bool is_colormap(int n); int num_colormaps(void); void get_current_color(int colormap, int n, rgb_t *r, rgb_t *g, rgb_t *b); #if HAVE_GL rgb_t *color_map_reds(int index); rgb_t *color_map_greens(int index); rgb_t *color_map_blues(int index); #endif void g_init_gxcolormaps(void); /* -------- snd-xfind.c -------- */ void find_dialog(chan_info *cp); void find_dialog_set_label(const char *str); void stop_search_if_error(const char *msg, void *data); void errors_to_find_text(const char *msg, void *data); void find_dialog_stop_label(bool show_stop); bool find_dialog_is_active(void); void save_find_dialog_state(FILE *fd); void g_init_gxfind(void); /* -------- snd-xutils.c -------- */ bool set_tiny_font(const char *font); bool set_listener_font(const char *font); bool set_peaks_font(const char *font); bool set_bold_peaks_font(const char *font); bool set_axis_label_font(const char *font); bool set_axis_numbers_font(const char *font); int label_width(const char *txt, bool use_tiny_font); int number_width(const char *num, bool use_tiny_font); int number_height(XFontStruct *numbers_font); int label_height(bool use_tiny_font); int mark_name_width(const char *txt); void map_over_children_with_color(Widget w, void (*func)(Widget uw, color_t color), color_t color); void clear_window(graphics_context *ax); void set_label(Widget label, const char *str); void set_title(const char *title); void goto_window(Widget text); void check_for_event(void); void color_cursor(Pixel color); void color_marks(Pixel color); void color_selection(Pixel color); void color_data(Pixel color); void color_selected_data(Pixel color); void color_graph(Pixel color); void color_selected_graph(Pixel color); void set_mix_color(Pixel color); void recolor_graph(chan_info *cp, bool selected); void set_sensitive(Widget wid, bool val); void set_toggle_button(Widget wid, bool val, bool passed, void *data); Dimension widget_height(Widget w); Dimension widget_width(Widget w); void set_widget_height(Widget w, Dimension height); void set_widget_width(Widget w, Dimension width); Position widget_x(Widget w); Position widget_y(Widget w); void set_widget_x(Widget w, Position x); void set_widget_y(Widget w, Position y); void set_widget_size(Widget w, Dimension width, Dimension height); void set_widget_position(Widget w, Position x, Position y); idle_t add_work_proc(XtWorkProc func, XtPointer data); void draw_rotated_axis_label(chan_info *cp, graphics_context *ax, const char *text, int x0, int y0); /* -------- snd-xchn.c -------- */ Widget channel_main_pane(chan_info *cp); Widget channel_w(chan_info *cp); Widget channel_f(chan_info *cp); Widget channel_graph(chan_info *cp); bool channel_graph_is_visible(chan_info *cp); void change_gzy(mus_float_t val, chan_info *cp); mus_float_t gsy_value(chan_info *cp); mus_float_t gsy_size(chan_info *cp); void initialize_scrollbars(chan_info *cp); void set_z_scrollbars(chan_info *cp, axis_info *ap); void resize_sx(chan_info *cp); void resize_sy(chan_info *cp); void resize_sy_and_zy(chan_info *cp); void resize_sx_and_zx(chan_info *cp); void channel_open_pane(chan_info *cp); void channel_unlock_pane(chan_info *cp); void reflect_edit_history_change(chan_info *cp); void reflect_edit_counter_change(chan_info *cp); int add_channel_window(snd_info *sound, int channel, int chan_y, int insertion, Widget main, fw_button_t arrows, bool with_events); void set_peak_numbers_font(chan_info *cp, graphics_context *ax); void set_bold_peak_numbers_font(chan_info *cp, graphics_context *ax); void set_tiny_numbers_font(chan_info *cp, graphics_context *ax); color_t get_foreground_color(graphics_context *ax); void set_foreground_color(graphics_context *ax, Pixel color); GC copy_GC(chan_info *cp); GC erase_GC(chan_info *cp); void graph_key_press(Widget w, XtPointer context, XEvent *event, Boolean *cont); void cleanup_cw(chan_info *cp); void free_fft_pix(chan_info *cp); bool restore_fft_pix(chan_info *cp, graphics_context *ax); void save_fft_pix(chan_info *cp, graphics_context *ax, int fwidth, int fheight, int x0, int y1); void change_channel_style(snd_info *sp, channel_style_t new_style); void color_chan_components(color_t color, slider_choice_t which_component); void color_unselected_graphs(color_t color); void g_init_gxchn(void); /* -------- snd-xsnd.c -------- */ int snd_pane_height(snd_info *sp); int control_panel_height(snd_info *sp); Widget w_snd_pane(snd_info *sp); Widget unite_button(snd_info *sp); void set_control_panel_play_button(snd_info *sp); void set_status(snd_info *sp, const char *str, bool update); void snd_info_cleanup(snd_info *sp); void set_amp(snd_info *sp, mus_float_t val); int amp_to_scroll(mus_float_t minval, mus_float_t val, mus_float_t maxval); void set_expand(snd_info *sp, mus_float_t val); void set_contrast(snd_info *sp, mus_float_t val); void set_speed(snd_info *sp, mus_float_t val); void set_revlen(snd_info *sp, mus_float_t val); void set_revscl(snd_info *sp, mus_float_t val); void set_filter_order(snd_info *sp, int val); void set_filter_text(snd_info *sp, const char *str); void display_filter_env(snd_info *sp); void toggle_expand_button(snd_info *sp, bool state); void toggle_contrast_button(snd_info *sp, bool state); void toggle_reverb_button(snd_info *sp, bool state); void toggle_filter_button(snd_info *sp, bool state); void toggle_direction_arrow(snd_info *sp, bool state); void set_filter_in_dB(snd_info *sp, bool val); void set_filter_in_hz(snd_info *sp, bool val); void filter_env_changed(snd_info *sp, env *e); void set_play_button(snd_info *sp, bool val); void play_button_pause(bool pausing); void syncb(snd_info *sp, int on); void show_lock(snd_info *sp); void hide_lock(snd_info *sp); void start_bomb(snd_info *sp); void stop_bomb(snd_info *sp); snd_info *add_sound_window(char *filename, read_only_t read_only, file_info *hdr); void set_sound_pane_file_label(snd_info *sp, const char *str); void color_filter_waveform(Pixel color); void show_controls(snd_info *sp); void hide_controls(snd_info *sp); bool showing_controls(snd_info *sp); void show_all_controls(void); void hide_all_controls(void); void start_progress_report(chan_info *cp); void finish_progress_report(chan_info *cp); void progress_report(chan_info *cp, mus_float_t pct); XmString initial_speed_label(speed_style_t style); void g_init_gxsnd(void); void make_sound_icons_transparent_again(Pixel old_color, Pixel new_color); void reflect_sound_selection(snd_info *sp); void make_controls_dialog(void); void update_sound_label(snd_info *sp); /* -------- snd-xfile.c -------- */ void cleanup_file_monitor(void); void *unmonitor_file(void *watcher); void monitor_sound(snd_info *sp); void save_view_files_dialogs(FILE *fd); widget_t make_view_files_dialog(bool managed, bool make_new); void view_files_unplay(void); void view_files_add_directory(widget_t dialog, const char *dirname); char *view_files_find_any_directory(void); int view_files_dialog_list_length(void); char **view_files_dialog_titles(void); void view_files_start_dialog_with_title(const char *title); char *get_file_dialog_sound_attributes(file_data *fdat, int *srate, int *chans, mus_header_t *header_type, mus_sample_t *sample_type, mus_long_t *location, mus_long_t *samples, int min_chan); void alert_new_file(void); widget_t make_open_file_dialog(read_only_t read_only, bool managed); widget_t make_sound_save_as_dialog(bool managed); void make_channel_extract_dialog(int chan); widget_t make_selection_save_as_dialog(bool managed); widget_t make_region_save_as_dialog(bool managed); widget_t make_new_file_dialog(bool managed); void mouse_enter_label(void *r, int type); void mouse_leave_label(void *r, int type); Widget edit_header(snd_info *sp); void save_edit_header_dialog_state(FILE *fd); void set_open_file_play_button(bool val); widget_t make_mix_file_dialog(bool managed); widget_t make_insert_file_dialog(bool managed); void g_init_gxfile(void); void clear_deleted_snd_info(void *dp); void reflect_just_sounds(void); void save_file_dialog_state(FILE *fd); widget_t post_it(const char *subject, const char *str); void post_it_append(const char *str); void save_post_it_dialog_state(FILE *fd); void reflect_region_in_save_as_dialog(void); void reflect_selection_in_save_as_dialog(bool on); void save_edits_now(snd_info *sp); void changed_file_dialog(snd_info *sp); void unpost_file_has_changed_if_any(snd_info *sp); void unpost_unsaved_edits_if_any(snd_info *sp); void reflect_save_as_src(bool val); void reflect_save_as_auto_comment(bool val); void reflect_save_as_sound_selection(const char *sound_name); void add_drag_and_drop(Widget w, void (*drop_watcher)(Widget w, const char *message, Position x, Position y, void *data), void (*drag_watcher)(Widget w, const char *message, Position x, Position y, drag_style_t dtype, void *data), void *context); /* -------- snd-xenv.c -------- */ axis_info *enved_make_axis(const char *name, graphics_context *ax, int ex0, int ey0, int width, int height, mus_float_t xmin, mus_float_t xmax, mus_float_t ymin, mus_float_t ymax, printing_t printing); void display_enved_env_with_selection(env *e, const char *name, int x0, int y0, int width, int height, bool dots, printing_t printing); void set_enved_redo_sensitive(bool val); void set_enved_revert_sensitive(bool val); void set_enved_undo_sensitive(bool val); void set_enved_save_sensitive(bool val); void set_enved_show_sensitive(bool val); void enved_reflect_selection(bool on); void make_scrolled_env_list(void); void enved_reflect_peak_env_completion(snd_info *sp); void new_active_channel_alert(void); void env_redisplay(void); void env_redisplay_with_print(void); void update_enved_background_waveform(chan_info *cp); Widget create_envelope_editor(void); void set_enved_clipping(bool val); void reflect_enved_style(void); void set_enved_base(mus_float_t val); void set_enved_target(enved_target_t val); void set_enved_with_wave(bool val); void set_enved_in_dB(bool val); bool enved_dialog_is_active(void); void set_enved_filter_order(int order); void color_enved_waveform(Pixel pix); void g_init_gxenv(void); /* -------- snd-xmix.c -------- */ void reflect_mix_change(int mix_id); Widget make_mix_dialog(void); void reflect_mix_play_stop(void); void make_mixer_icons_transparent_again(Pixel old_color, Pixel new_color); int mix_dialog_mix(void); void mix_dialog_set_mix(int id); /* -------- snd-xprefs.c -------- */ widget_t make_preferences_dialog(void); #endif snd-16.1/inf-snd.el0000644000076400007640000015370612444342534012234 0ustar bilbil;;; inf-snd.el -- Inferior Snd Process (Ruby/Scheme/Forth) ;; Copyright (c) 2002--2010 Michael Scholz ;; All rights reserved. ;; ;; Redistribution and use in source and binary forms, with or without ;; modification, are permitted provided that the following conditions ;; are met: ;; 1. Redistributions of source code must retain the above copyright ;; notice, this list of conditions and the following disclaimer. ;; 2. Redistributions in binary form must reproduce the above copyright ;; notice, this list of conditions and the following disclaimer in the ;; documentation and/or other materials provided with the distribution. ;; ;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ;; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE ;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ;; OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ;; HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ;; LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ;; OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ;; SUCH DAMAGE. ;;; Commentary: ;; This file defines a snd-in-a-buffer package built on top of ;; comint-mode. It includes inferior mode for Snd-Ruby ;; (inf-snd-ruby-mode), Snd-Scheme (inf-snd-scheme-mode) and Snd-Forth ;; (inf-snd-forth-mode), furthermore a Snd-Ruby mode (snd-ruby-mode), ;; a Snd-Scheme mode (snd-scheme-mode) and a Snd-Forth mode ;; (snd-forth-mode) for editing source files. It is tested with ;; Snd-Ruby, Snd-Scheme and Snd-Forth 10.3 and GNU Emacs 22.3.1. ;; Since this mode is built on top of the general command-interpreter- ;; in-a-buffer mode (comint-mode), it shares a common base ;; functionality, and a common set of bindings, with all modes derived ;; from comint mode. This makes these modes easier to use. For ;; documentation on the functionality provided by comint-mode, and the ;; hooks available for customizing it, see the file comint.el. ;; A nice feature may be the commands `inf-snd-help' and `snd-help', ;; which shows the description which Snd provides for many functions. ;; With tab-completion in the minibuffer you can scan all functions at ;; a glance. It should be easy to extent this mode with new commands ;; and key bindings; the example below and the code in this file may ;; show the way. ;; There exist six main modes in this file: the three inferior ;; Snd-process-modes (inf-snd-ruby-mode, inf-snd-scheme-mode and ;; inf-snd-forth-mode) and the replacements of ruby-mode ;; (snd-ruby-mode), of scheme-mode (snd-scheme-mode) and of ;; gforth-mode (snd-forth-mode). ;; Variables of the inferior Snd-process-modes ;; inf-snd-ruby|scheme|forth-mode (defaults): ;; ;; inf-snd-scheme-program-name "snd-s7" Snd-Scheme program name ;; inf-snd-ruby-program-name "snd-ruby" Snd-Ruby program name ;; inf-snd-forth-program-name "snd-fth" Snd-Forth program name ;; inf-snd-working-directory "~/" where Ruby, Scheme or Forth scripts reside ;; inf-snd-ruby-mode-hook nil to customize inf-snd-ruby-mode ;; inf-snd-scheme-mode-hook nil to customize inf-snd-scheme-mode ;; inf-snd-forth-mode-hook nil to customize inf-snd-forth-mode ;; inf-snd-ruby-quit-hook nil to reset snd variables before exit ;; inf-snd-scheme-quit-hook nil to reset snd variables before exit ;; inf-snd-forth-quit-hook nil to reset snd variables before exit ;; inf-snd-index-path "~/" path to snd-xref.c ;; inf-snd-prompt ">" listener prompt ;; Variables of the editing modes snd-ruby|scheme|forth-mode ;; (defaults): ;; ;; snd-scheme-mode-hook nil to customize snd-scheme-mode ;; snd-ruby-mode-hook nil to customize snd-ruby-mode ;; snd-forth-mode-hook nil to customize snd-forth-mode ;; You can start inf-snd-ruby-mode interactive either with prefix-key ;; (C-u M-x run-snd-ruby)--you will be ask for program name and ;; optional arguments--or direct (M-x run-snd-ruby). In the latter ;; case, variable inf-snd-ruby-program-name should be set correctly. ;; The same usage goes for inf-snd-scheme-mode and inf-snd-forth-mode. ;; Example for your .emacs file: ;; ;; (autoload 'run-snd-scheme "inf-snd" "Start inferior Snd-Scheme process" t) ;; (autoload 'run-snd-ruby "inf-snd" "Start inferior Snd-Ruby process" t) ;; (autoload 'run-snd-forth "inf-snd" "Start inferior Snd-Forth process" t) ;; (autoload 'snd-scheme-mode "inf-snd" "Load snd-scheme-mode." t) ;; (autoload 'snd-ruby-mode "inf-snd" "Load snd-ruby-mode." t) ;; (autoload 'snd-forth-mode "inf-snd" "Load snd-forth-mode." t) ;; ;; ;; These variables should be set to your needs! ;; (setq inf-snd-scheme-program-name "snd-s7 -notehook") ;; (setq inf-snd-ruby-program-name "snd-ruby -notebook") ;; (setq inf-snd-forth-program-name "snd-forth") ;; (setq inf-snd-working-directory "~/Snd/") ;; (setq inf-snd-index-path "~/Snd/snd/") ;; The hook-variables may be used to set new key bindings and menu ;; entries etc. in your .emacs file, e.g.: ;; ;; (defun snd-sounds () ;; (interactive) ;; (inf-snd-send-string "(sounds)")) ;; ;; (add-hook 'inf-snd-ruby-mode-hook ;; '(lambda () ;; (define-key (current-local-map) [menu-bar inf-snd-ruby-mode foo] ;; '("Sounds" . snd-sounds)) ;; (define-key (current-local-map) "\C-c\C-t" 'snd-sounds))) ;; ;; To edit source code with special key bindings: ;; ;; (add-hook 'snd-ruby-mode-hook ;; '(lambda () ;; (define-key (current-local-map) "\C-co" 'snd-send-buffer) ;; (define-key (current-local-map) "\C-cb" 'snd-send-block) ;; (define-key (current-local-map) "\C-cr" 'snd-send-region) ;; (define-key (current-local-map) "\C-ce" 'snd-send-definition))) ;; ;; (add-hook 'snd-scheme-mode-hook ;; '(lambda () ;; (define-key (current-local-map) "\C-co" 'snd-send-buffer) ;; (define-key (current-local-map) "\C-cr" 'snd-send-region) ;; (define-key (current-local-map) "\C-ce" 'snd-send-definition))) ;; ;; (add-hook 'snd-forth-mode-hook ;; '(lambda () ;; (define-key (current-local-map) "\C-co" 'snd-send-buffer) ;; (define-key (current-local-map) "\C-cr" 'snd-send-region) ;; (define-key (current-local-map) "\C-ce" 'snd-send-definition))) ;; You can change the mode in a source file by M-x snd-ruby-mode (or ;; snd-scheme-mode, snd-forth-mode). To determine automatically which ;; mode to set, you can decide to use special file-extensions. One ;; may use file-extension `.rbs' for Snd-Ruby source files and `.cms' ;; for Snd-Scheme. ;; ;; (set-default 'auto-mode-alist ;; (append '(("\\.rbs$" . snd-ruby-mode) ;; ("\\.cms$" . snd-scheme-mode)) ;; auto-mode-alist)) ;; ;; Or you can use the local mode variable in source files, e.g. by ;; `-*- snd-ruby -*-', `-*- snd-scheme -*-' or `-*- snd-forth -*-' in ;; first line. ;; Key bindings for inf-* and snd-*-modes ;; ;; \e\TAB snd-completion symbol completion at point ;; C-h m describe-mode describe current major mode ;; Key binding of inf-snd-ruby|scheme|forth-mode: ;; ;; C-c C-s inf-snd-run-snd (Snd-Ruby|Scheme|Forth from a dead Snd process buffer) ;; M-C-l inf-snd-load load script in current working directory ;; C-c C-f inf-snd-file open view-files-dialog of Snd ;; M-C-p inf-snd-play play current sound file ;; C-c C-t inf-snd-stop stop playing all sound files ;; C-c C-i inf-snd-help help on Snd-function (snd-help) ;; C-u C-c C-i inf-snd-help-html help on Snd-function (html) ;; C-c C-q inf-snd-quit send exit to Snd process ;; C-c C-k inf-snd-kill kill Snd process and buffer ;; Key bindings of snd-ruby|scheme|forth-mode editing source ;; files: ;; ;; C-c C-s snd-run-snd ;; M-C-x snd-send-definition ;; C-x C-e snd-send-last-sexp ;; C-c M-e snd-send-definition ;; C-c C-e snd-send-definition-and-go ;; C-c M-r snd-send-region ;; C-c C-r snd-send-region-and-go ;; C-c M-o snd-send-buffer ;; C-c C-o snd-send-buffer-and-go ;; C-c M-b snd-send-block (Ruby only) ;; C-c C-b snd-send-block-and-go (Ruby only) ;; C-c C-z snd-switch-to-snd ;; C-c C-l snd-load-file ;; C-u C-c C-l snd-load-file-protected (Ruby only) ;; ;; and in addition: ;; ;; C-c C-f snd-file open view-files-dialog of Snd ;; C-c C-p snd-play play current sound file ;; C-c C-t snd-stop stop playing all sound files ;; C-c C-i snd-help help on Snd-function (snd-help) ;; C-u C-c C-i snd-help-html help on Snd-function (html) ;; C-c C-q snd-quit send exit to Snd process ;; C-c C-k snd-kill kill Snd process and buffer ;;; News: ;; ;; All variables and functions containing the string `guile' are ;; renamed to `scheme'. There are aliases for the following functions ;; and variables: ;; ;; new name alias for backward compatibility ;; ;; run-snd-scheme run-snd-guile ;; snd-scheme-mode-hook snd-guile-mode-hook ;; snd-scheme-mode snd-guile-mode ;; inf-snd-scheme-mode inf-snd-guile-mode ;; inf-snd-scheme-quit-hook inf-snd-guile-quit-hook ;; inf-snd-scheme-program-name inf-snd-guile-program-name ;;; Code: ;;;; The inf-snd-ruby-mode, inf-snd-scheme-mode, and inf-snd-forth-mode. (require 'comint) (require 'scheme) (require 'cmuscheme) ;; (require FEATURE &optional FILENAME NOERROR) (require 'inf-ruby "inf-ruby" t) (require 'ruby-mode "ruby-mode" t) (require 'forth-mode "gforth" t) (defconst inf-snd-version "05-May-2010" "Version date of inf-snd.el.") ;; snd-ruby (defvar inf-snd-ruby-buffer "*Snd-Ruby*" "Inferior Snd-Ruby process buffer.") (defvar inf-snd-ruby-buffer-name "Snd-Ruby" "Inferior Snd-Ruby process buffer name.") (defvar inf-snd-ruby-mode-hook nil "*User hook variable of `inf-snd-ruby-mode'. Will be called after `comint-mode-hook' and before starting inferior Snd-Ruby process.") (defvar inf-snd-ruby-quit-hook nil "*User hook variable of `inf-snd-ruby-mode'. Will be called before finishing inferior Snd-Ruby process.") (defvar inf-snd-ruby-program-name "snd-ruby" "*User variable to set Snd-Ruby-program name and optional arguments.") ;; snd-forth (defvar inf-snd-forth-buffer "*Snd-Forth*" "Inferior Snd-Forth process buffer.") (defvar inf-snd-forth-buffer-name "Snd-Forth" "Inferior Snd-Forth process buffer name.") (defvar inf-snd-forth-mode-hook nil "*User hook variable of `inf-snd-forth-mode'. Will be called after `comint-mode-hook' and before starting inferior Snd-Forth process.") (defvar inf-snd-forth-quit-hook nil "*User hook variable of `inf-snd-forth-mode'. Will be called before finishing inferior Snd-Forth process.") (defvar inf-snd-forth-program-name "snd-forth" "*User variable to set Snd-Forth-program name and optional arguments.") ;; snd-scheme (defvar inf-snd-scheme-buffer "*Snd-Scheme*" "Inferior Snd-Scheme process buffer.") (defvar inf-snd-scheme-buffer-name "Snd-Scheme" "Inferior Snd-Scheme process buffer name.") (defvar inf-snd-scheme-mode-hook nil "*User hook variable of `inf-snd-scheme-mode'. Will be called after `comint-mode-hook' and before starting inferior Snd-Scheme process.") (defvar inf-snd-scheme-quit-hook nil "*User hook variable of `inf-snd-scheme-mode'. Will be called before finishing inferior Snd-Scheme process.") (defvar inf-snd-scheme-program-name "snd-s7" "*User variable to set Snd-Scheme-program name and optional args.") (if (fboundp 'defvaralias) (progn (defvaralias 'inf-snd-guile-mode-hook 'inf-snd-scheme-mode-hook) (defvaralias 'inf-snd-guile-quit-hook 'inf-snd-scheme-quit-hook) (defvaralias 'inf-snd-guile-program-name 'inf-snd-scheme-program-name))) ;; general (defvar snd-completions-buffer "*Completions*" "Snd completions buffer.") (defvar inf-snd-prompt ">" "*User variable to determine Snd's listener prompt. Example: (setq inf-snd-prompt \"snd> \")") (defvar inf-snd-working-directory "~/" "*User variable where Emacs will find the Ruby, Forth, or Scheme scripts.") (defvar inf-snd-kind nil "Options are 'ruby, 'forth, or 'scheme. Needed to determine which extension language to use. This variable is buffer-local.") (defvar inf-snd-comint-line-end "\n" "*User variable for terminating comint-send. Interesting perhaps only for Snd-Forth. The default '\n' should be changed to '\n\n' with snd-forth-xm and snd-forth-xg but not with snd-forth-nogui. A double carriage return forces a prompt while a single carriage return does it not in every case.") (defvar inf-snd-index-path "~/" "*User variable to path where snd-xref.c is located.") (defvar snd-send-eval-file (expand-file-name (concat (user-login-name) "-snd-eval-file.rb") temporary-file-directory) "*User variable of `inf-snd-ruby-mode' and `snd-ruby-mode'. File where the commands will be collected before sending to inferior Snd process.") (defvar inf-snd-to-comment-regexp "^\\(Exception\\|undefined\\|([-A-Za-z]+)\\)" "*User variable of `inf-snd-ruby-mode'. Lines with regexp will be prepended by ruby's comment sign and space '# '.") (defvar inf-snd-ruby-keywords nil "Snd keywords providing online help. \\ Will be used by `inf-snd-help' (\\[inf-snd-help], \\[universal-argument] \\[inf-snd-help]) and `snd-help' (\\[snd-help], \\[universal-argument] \\[snd-help]), taken from snd/snd-xref.c. The user variable `inf-snd-index-path' should point to the correct path where snd-xref.c is located.") (defvar inf-snd-scheme-keywords nil "Snd keywords providing online help. \\ Will be used by `inf-snd-help' (\\[inf-snd-help], \\[universal-argument] \\[inf-snd-help]) and `snd-help' (\\[snd-help], \\[universal-argument] \\[snd-help]), taken from snd/snd-xref.c. The user variable `inf-snd-index-path' should point to the correct path where snd-xref.c is located.") (defvar inf-snd-ruby-keyword-regexp "^ \"\\([A-Za-z0-9$_?!()]+?\\)\"[,}]+?" "*User variable to find Snd-Ruby's keywords in snd-xref.c.") (defvar inf-snd-scheme-keyword-regexp "^ \"\\([-A-Za-z0-9*>?!()]+?\\)\"[,}]+?" "*User variable to find Snd-Scheme's and Snd-Forth's keywords in snd-xref.c.") (defun inf-snd-set-keywords () "Set the keywords for `inf-snd-help'. The user variable `inf-snd-index-path' should point to the correct path of snd-xref.c to create valid keywords." (let ((fbuf (find-file-noselect (concat (expand-file-name inf-snd-index-path) "snd-xref.c"))) (regex (if (eq 'ruby inf-snd-kind) inf-snd-ruby-keyword-regexp inf-snd-scheme-keyword-regexp)) (keys '())) (with-current-buffer fbuf (goto-char (point-min)) (setq case-fold-search nil) (while (re-search-forward regex nil t) (let ((val (match-string 1))) (or (member val keys) (setq keys (cons val keys)))))) (kill-buffer fbuf) keys)) ;;; from share/emacs/22.0.50/lisp/thingatpt.el ;;; lisp-complete-symbol (&optional predicate) (defun snd-completion () "Perform completion on symbols preceding point. Compare that symbol against the known Snd symbols. If no characters can be completed, display a list of possible completions. Repeating the command at that point scrolls the list." (interactive) (let ((window (get-buffer-window snd-completions-buffer))) (if (and (eq last-command this-command) window (window-live-p window) (window-buffer window) (buffer-name (window-buffer window))) ;; If this command was repeated, and ;; there's a fresh completion window with a live buffer, ;; and this command is repeated, scroll that window. (with-current-buffer (window-buffer window) (if (pos-visible-in-window-p (point-max) window) (set-window-start window (point-min)) (save-selected-window (select-window window) (scroll-up)))) ;; Do completion. (let* ((end (point)) (beg (save-excursion (backward-sexp 1) (while (= (char-syntax (following-char)) ?\') (forward-char 1)) (point))) (pattern (buffer-substring-no-properties beg end)) (key-list (if (eq 'ruby inf-snd-kind) inf-snd-ruby-keywords inf-snd-scheme-keywords)) (completion (try-completion pattern key-list))) (cond ((eq completion t)) ((null completion) (message "Can't find completion for \"%s\"" pattern)) ((not (string= pattern completion)) (delete-region beg end) (insert completion)) (t (let ((list (all-completions pattern key-list))) (setq list (sort list 'string<)) (with-output-to-temp-buffer snd-completions-buffer (display-completion-list list))))))))) (defun inf-snd-set-keys (mode name) "Set the key bindings and menu entries for MODE. Menu name is NAME. You can extend the key bindings and menu entries here or via hook variables in .emacs file." ;; key bindings (define-key (current-local-map) "\C-c\C-f" 'inf-snd-file) (define-key (current-local-map) "\M-\C-l" 'inf-snd-load) (define-key (current-local-map) "\M-\C-p" 'inf-snd-play) (define-key (current-local-map) "\C-c\C-s" 'inf-snd-run-snd) (define-key (current-local-map) "\C-c\C-t" 'inf-snd-stop) (define-key (current-local-map) "\C-c\C-i" 'inf-snd-help) (define-key (current-local-map) "\C-c\C-k" 'inf-snd-kill) (define-key (current-local-map) "\C-c\C-q" 'inf-snd-quit) (define-key (current-local-map) "\e\C-i" 'snd-completion) ;; menu entries in reverse order of appearance (define-key (current-local-map) [menu-bar mode] (cons name (make-sparse-keymap name))) (define-key (current-local-map) [menu-bar mode kill] '(menu-item "Kill Snd Process and Buffer" inf-snd-kill :enable (inf-snd-proc-p))) (define-key (current-local-map) [menu-bar mode quit] '(menu-item "Send exit to Snd Process" inf-snd-quit :enable (inf-snd-proc-p))) (define-key (current-local-map) [menu-bar mode start-r] '(menu-item "Start Snd-Ruby Process" inf-snd-run-snd :enable (not (inf-snd-proc-p)) :visible (eq 'ruby inf-snd-kind))) (define-key (current-local-map) [menu-bar mode start-f] '(menu-item "Start Snd-Forth Process" inf-snd-run-snd :enable (not (inf-snd-proc-p)) :visible (eq 'forth inf-snd-kind))) (define-key (current-local-map) [menu-bar mode start-g] '(menu-item "Start Snd-Scheme Process" inf-snd-run-snd :enable (not (inf-snd-proc-p)) :visible (eq 'scheme inf-snd-kind))) (define-key (current-local-map) [menu-bar mode sep-quit] '(menu-item "--")) (define-key (current-local-map) [menu-bar mode desc] '(menu-item "Describe Mode" describe-mode)) (define-key (current-local-map) [menu-bar mode help-html] '(menu-item "Describe Snd Function (html) ..." inf-snd-help-html :enable (inf-snd-proc-p) :visible (not (eq 'ruby inf-snd-kind)))) (define-key (current-local-map) [menu-bar mode help] '(menu-item "Describe Snd Function (snd-help) ..." inf-snd-help :enable (inf-snd-proc-p))) (define-key (current-local-map) [menu-bar mode sep-reset] '(menu-item "--")) (define-key (current-local-map) [menu-bar mode stop] '(menu-item "Stop Playing" inf-snd-stop :enable (inf-snd-proc-p))) (define-key (current-local-map) [menu-bar mode play] '(menu-item "Start Playing" inf-snd-play :enable (inf-snd-proc-p))) (define-key (current-local-map) [menu-bar mode file] '(menu-item "Open Snd-File Dialog" inf-snd-file :enable (inf-snd-proc-p))) (define-key (current-local-map) [menu-bar mode sep-play] '(menu-item "--")) (define-key (current-local-map) [menu-bar mode load-r] '(menu-item "Load Ruby Script ..." inf-snd-load :enable (inf-snd-proc-p) :visible (eq 'ruby inf-snd-kind))) (define-key (current-local-map) [menu-bar mode load-f] '(menu-item "Load Forth Script ..." inf-snd-load :enable (inf-snd-proc-p) :visible (eq 'forth inf-snd-kind))) (define-key (current-local-map) [menu-bar mode load-g] '(menu-item "Load Scheme Script ..." inf-snd-load :enable (inf-snd-proc-p) :visible (eq 'scheme inf-snd-kind)))) (defun inf-snd-send-string (str &optional no-strip-p) "Print STR in buffer and send it to the inferior Snd process. If NO-STRIP-P is nil, the default, all dashes (-) will be translated to underlines (_), if `inf-snd-kind' is 'ruby. If NO-STRIP-P is non-nil, it won't translate. See `inf-snd-load' for the latter case." (interactive) (and (not no-strip-p) (eq 'ruby inf-snd-kind) (while (string-match "-" str) (setq str (replace-match "_" t t str)))) (if (eq 'scheme inf-snd-kind) (setq str (concat "(" str ")"))) (with-current-buffer (inf-snd-proc-buffer) (insert str) (comint-send-input))) (defun inf-snd-run-snd () "Start inferior Snd-Ruby, Snd-Forth, or Snd-Scheme process. Started from dead Snd process buffer." (interactive) (cond ((eq 'ruby inf-snd-kind) (run-snd-ruby inf-snd-ruby-program-name)) ((eq 'forth inf-snd-kind) (run-snd-forth inf-snd-forth-program-name)) (t (run-snd-scheme inf-snd-scheme-program-name)))) (defun inf-snd-file () "Open Snd's view-files-dialog widget." (interactive) (inf-snd-send-string "view-files-dialog")) (defun inf-snd-load (file) "Load the required Ruby, Forth, or Scheme script. Asks for FILE interactively in minibuffer." (interactive "fLoad Snd Script: ") (unless (file-directory-p file) (inf-snd-send-string (if (eq 'forth inf-snd-kind) (format "include %s" (car (file-expand-wildcards file t))) (format "load %S" (car (file-expand-wildcards file t)))) t))) (defun inf-snd-play () "Play current sound." (interactive) (inf-snd-send-string "play")) (defun inf-snd-stop () "Stop playing of all sound files." (interactive) (inf-snd-send-string "stop-playing")) (defun inf-snd-help (&optional html-help) "Receive a string in minibuffer and show corresponding help. \\\\\\ This is done via Snd's function snd_help() or html() if HTML-HELP is non-nil, i.e. it's called by \\[universal-argument] \\[inf-snd-help], putting result at the end of the inferior Snd process buffer. If point is near a function name in inferior Snd process buffer, that function will be used as default value in minibuffer; tab-completion is activated. `inf-snd-ruby-keywords' and `inf-snd-scheme-keywords' hold the help strings, the user variable `inf-snd-index-path' should point to the correct path of snd-xref.c." (interactive "P") (let ((prompt (format "Snd%s Help: " (if html-help " HTML" ""))) (default (thing-at-point 'sexp))) (if default (setq prompt (format "%s(default %s): " prompt default))) (let ((str (completing-read prompt (if (eq 'ruby inf-snd-kind) inf-snd-ruby-keywords inf-snd-scheme-keywords) nil nil nil nil default))) (unless (string= str "") (unless html-help (while (string-match " " str) (setq str (replace-match "" t t str)))) (let ((inf-str (if (and html-help (not (eq 'forth inf-snd-kind))) (format "(html \"%s\")" str) (cond ((eq 'ruby inf-snd-kind) (format "Snd.display(snd_help(\"%s\", true))" str)) ((eq 'forth inf-snd-kind) (format "\"%s\" #t snd-help" str)) (t (format "snd-help \"%s\" #t" str)))))) (with-current-buffer (inf-snd-proc-buffer) (goto-char (point-max)) (if (and (string= (char-to-string (preceding-char)) inf-snd-prompt) (eobp)) (inf-snd-send-string inf-str t) (beginning-of-line) (kill-region (point) (point-max)) (inf-snd-send-string inf-str t) (yank)))))))) (defun inf-snd-help-html () "Start html help." (interactive) (inf-snd-help t)) (defun inf-snd-quit () "Send exit to inferior Snd process." (interactive) (cond ((eq 'ruby inf-snd-kind) (run-hooks 'inf-snd-ruby-quit-hook)) ((eq 'forth inf-snd-kind) (run-hooks 'inf-snd-forth-quit-hook)) (t (run-hooks 'inf-snd-scheme-quit-hook))) (if (bufferp snd-completions-buffer) (kill-buffer snd-completions-buffer)) (get-buffer-process (inf-snd-proc-buffer)) (goto-char (point-max)) (cond ((eq 'ruby inf-snd-kind) (snd-send-invisible "exit(0)")) ((eq 'forth inf-snd-kind) (snd-send-invisible "0 snd-exit drop")) (t (snd-send-invisible "(exit 0)"))) (and (file-exists-p snd-send-eval-file) (delete-file snd-send-eval-file))) (defun inf-snd-kill () "Kill current inferior Snd process and buffer." (interactive) (inf-snd-quit) (delete-process (get-buffer-process (inf-snd-proc-buffer))) (kill-buffer (current-buffer)) (unless (one-window-p) (delete-window (get-buffer-window (inf-snd-proc-buffer))))) (defun inf-snd-proc-buffer () "Return the current process buffer." (cond ((eq 'ruby inf-snd-kind) inf-snd-ruby-buffer) ((eq 'forth inf-snd-kind) inf-snd-forth-buffer) (t inf-snd-scheme-buffer))) (defun inf-snd-proc-p () "Return non-nil if process buffer is available." (save-current-buffer (comint-check-proc (inf-snd-proc-buffer)))) (defun snd-send-invisible (str &optional no-newline) "Send a STR to the process running in the current buffer. Non-nil NO-NEWLINE means string without carriage return append." (let ((proc (get-buffer-process (current-buffer)))) (cond ((not proc) (error "Current buffer has no process")) ((stringp str) (comint-snapshot-last-prompt) (if no-newline (comint-send-string proc str) (comint-simple-send proc str)))))) (defun inf-snd-comint-put-prompt-ruby (string) "Look for `inf-snd-to-comment-regexp' in STRING in the current output. Prepends matching lines with ruby's comment sign and space `# '. Showing a prompt is forced by run_emacs_eval_hook() in snd/examp.rb. This function could be on the so called abnormal hook with one arg `comint-preoutput-filter-functions'." ;; Drop trailing '\n' ("...snd(0)> \n" => "...snd(0)> "). (if (string-match inf-snd-prompt string) (setq string (substring string 0 (match-end 0)))) (while (string-match inf-snd-to-comment-regexp string) (setq string (replace-match "# \\1" t nil string 1))) string) (defun inf-snd-comint-put-prompt-forth (string) "If STRING contains one or more undef strings, replace them with `inf-snd-prompt'. This function could be on the so called abnormal hook with one arg `comint-preoutput-filter-functions'." (if (string-match "\\s-?\\(\\(undef\\s-\\)+\\)$" string) (replace-match inf-snd-prompt t t string 1) string)) (defun inf-snd-comint-put-prompt-scheme (string) "Appends `inf-snd-prompt' to STRING. This function could be on the so called abnormal hook with one arg `comint-preoutput-filter-functions'." (if (string-match "\n" string) (concat string inf-snd-prompt) string)) (defun inf-snd-comint-snd-send (proc line) "Special function for sending input LINE to PROC. Variable `comint-input-sender' is set to this function. Running Snd-Ruby it is necessary to load snd/examp.rb in your ~/.snd file which contains run_emacs_eval_hook(line). inf-snd.el uses this function to evaluate one line or multi-line input (Ruby only)." (if (= (length line) 0) (if (eq 'scheme inf-snd-kind) (setq line "#f") (setq line "nil"))) (comint-send-string proc (if (eq 'ruby inf-snd-kind) (format "run_emacs_eval_hook(%%(%s))\n" line) (concat line inf-snd-comint-line-end)))) (defun inf-snd-get-old-input () "Snarf the whole pointed line." (save-excursion (end-of-line) (let ((end (point))) (beginning-of-line) (buffer-substring-no-properties (point) end)))) (defun inf-snd-args-to-list (string) "Return a list containing the program and optional arguments list. Argument STRING is the Snd command and optional arguments." (let ((where (string-match "[ \t]" string))) (cond ((null where) (list string)) ((not (= where 0)) (cons (substring string 0 where) (inf-snd-args-to-list (substring string (+ 1 where) (length string))))) (t (let ((pos (string-match "[^ \t]" string))) (if (null pos) nil (inf-snd-args-to-list (substring string pos (length string))))))))) (define-derived-mode inf-snd-ruby-mode comint-mode inf-snd-ruby-buffer-name "Inferior mode running Snd-Ruby, derived from `comint-mode'. Snd is a sound editor created by Bill Schottstaedt \(bil@ccrma.Stanford.EDU). You can find it on ftp://ccrma-ftp.stanford.edu/pub/Lisp/snd-7.tar.gz. You can type in Ruby commands in inferior Snd process buffer which will be sent via `comint-send-string' to the inferior Snd process. The return value will be shown in the process buffer, other output goes to the listener of Snd. You should set variable `inf-snd-ruby-program-name' and `inf-snd-working-directory' in your .emacs file to set the appropriate program name and optional arguments and to direct Snd to the Ruby scripts directory, you have. The hook variables `comint-mode-hook' and `inf-snd-ruby-mode-hook' will be called in that special order after calling the inferior Snd process. You can use them e.g. to set additional key bindings. The hook variable `inf-snd-ruby-quit-hook' will be called before finishing the inferior Snd process. You may use it for resetting Snd variables, e.g. the listener prompt. \\ Interactive start is possible either by \\[universal-argument] \\[run-snd-ruby], you will be ask for the Snd program name, or by \\[run-snd-ruby]. Emacs shows an additional menu entry ``Snd-Ruby'' in the menu bar. The following key bindings are defined: \\{inf-snd-ruby-mode-map}" (ruby-mode-variables) (add-hook 'comint-preoutput-filter-functions 'inf-snd-comint-put-prompt-ruby nil t) (add-hook 'comint-input-filter-functions 'ruby-input-filter nil t) (setq comint-get-old-input (function inf-snd-get-old-input)) (setq comint-input-sender (function inf-snd-comint-snd-send)) (setq default-directory inf-snd-working-directory) (make-local-variable 'inf-snd-prompt) (make-local-variable 'inf-snd-kind) (make-local-variable 'inf-snd-comint-line-end) (setq comint-prompt-regexp (concat "^\\(" inf-snd-prompt "\\)+")) (setq inf-snd-kind 'ruby) (setq mode-line-process '(":%s")) (unless inf-snd-ruby-keywords (setq inf-snd-ruby-keywords (inf-snd-set-keywords))) (inf-snd-set-keys 'inf-snd-ruby-mode inf-snd-ruby-buffer-name) (pop-to-buffer inf-snd-ruby-buffer) (goto-char (point-max)) (run-hooks 'inf-snd-ruby-mode-hook)) (define-derived-mode inf-snd-forth-mode comint-mode inf-snd-forth-buffer-name "Inferior mode running Snd-Forth, derived from `comint-mode'. Snd is a sound editor created by Bill Schottstaedt \(bil@ccrma.Stanford.EDU). You can find it on ftp://ccrma-ftp.stanford.edu/pub/Lisp/snd-7.tar.gz. You can type in Forth commands in inferior Snd process buffer which will be sent via `comint-send-string' to the inferior Snd process. The return value will be shown in the process buffer, other output goes to the listener of Snd. You should set variable `inf-snd-forth-program-name' and `inf-snd-working-directory' in your .emacs file to set the appropriate program name and optional arguments and to direct Snd to the Forth scripts directory, you have. The hook variables `comint-mode-hook' and `inf-snd-forth-mode-hook' will be called in that special order after calling the inferior Snd process. You can use them e.g. to set additional key bindings. The hook variable `inf-snd-forth-quit-hook' will be called before finishing the inferior Snd process. You may use it for resetting Snd variables, e.g. the listener prompt. \\ Interactive start is possible either by \\[universal-argument] \\[run-snd-forth], you will be ask for the Snd program name, or by \\[run-snd-forth]. Emacs shows an additional menu entry ``Snd-Forth'' in the menu bar. The following key bindings are defined: \\{inf-snd-forth-mode-map}" (add-hook 'comint-preoutput-filter-functions 'inf-snd-comint-put-prompt-forth nil t) (setq comint-get-old-input (function inf-snd-get-old-input)) (setq comint-input-sender (function inf-snd-comint-snd-send)) (setq default-directory inf-snd-working-directory) (make-local-variable 'inf-snd-prompt) (make-local-variable 'inf-snd-kind) (make-local-variable 'inf-snd-comint-line-end) (setq comint-prompt-regexp (concat "^\\(" inf-snd-prompt "\\)+")) (setq inf-snd-kind 'forth) (setq mode-line-process '(":%s")) (unless inf-snd-scheme-keywords (setq inf-snd-scheme-keywords (inf-snd-set-keywords))) (inf-snd-set-keys 'inf-snd-forth-mode inf-snd-forth-buffer-name) (pop-to-buffer inf-snd-forth-buffer) (goto-char (point-max)) (run-hooks 'inf-snd-forth-mode-hook)) (define-derived-mode inf-snd-scheme-mode comint-mode inf-snd-scheme-buffer-name "Inferior mode running Snd-Scheme, derived from `comint-mode'. Snd is a sound editor created by Bill Schottstaedt \(bil@ccrma.Stanford.EDU). You can find it on ftp://ccrma-ftp.stanford.edu/pub/Lisp/snd-7.tar.gz. You can type in Scheme commands in inferior Snd process buffer which will be sent via `comint-send-string' to the inferior Snd process. The return value will be shown in the process buffer, other output goes to the listener of Snd. You sould set variable `inf-snd-scheme-program-name' and `inf-snd-working-directory' in your .emacs file to set the appropriate program name and optional arguments and to direct Snd to the Scheme scripts directory, you have. The hook variables `comint-mode-hook' and `inf-snd-scheme-mode-hook' will be called in that special order after calling the inferior Snd process. You can use them e.g. to set additional key bindings. The hook variable `inf-snd-scheme-quit-hook' will be called before finishing the inferior Snd process. You may use it for resetting Snd variables, e.g. the listener prompt. \\ Interactive start is possible either by \\[universal-argument] \\[run-snd-scheme], you will be ask for the Snd program name, or by \\[run-snd-scheme]. Emacs shows an additional menu entry ``Snd-Scheme'' in the menu bar. The following key bindings are defined: \\{inf-snd-scheme-mode-map}" (scheme-mode-variables) (add-hook 'comint-preoutput-filter-functions 'inf-snd-comint-put-prompt-scheme nil t) (add-hook 'comint-input-filter-functions 'scheme-input-filter nil t) (setq comint-get-old-input (function scheme-get-old-input)) (setq comint-input-sender (function inf-snd-comint-snd-send)) (setq default-directory inf-snd-working-directory) (make-local-variable 'inf-snd-prompt) (make-local-variable 'inf-snd-kind) (make-local-variable 'inf-snd-comint-line-end) (setq comint-prompt-regexp (concat "^\\(" inf-snd-prompt "\\)+")) (setq inf-snd-kind 'scheme) (setq mode-line-process '(":%s")) (unless inf-snd-scheme-keywords (setq inf-snd-scheme-keywords (inf-snd-set-keywords))) (inf-snd-set-keys 'inf-snd-scheme-mode inf-snd-scheme-buffer-name) (pop-to-buffer inf-snd-scheme-buffer) (goto-char (point-max)) (run-hooks 'inf-snd-scheme-mode-hook)) (defalias 'inf-snd-guile-mode 'inf-snd-scheme-mode) (defun run-snd-ruby (cmd) "Start inferior Snd-Ruby process. CMD is used for determine which program to run. If interactively called, one will be asked for program name to run." (interactive (list (if current-prefix-arg (read-string "Run Snd Ruby: " inf-snd-ruby-program-name) inf-snd-ruby-program-name))) (unless (comint-check-proc inf-snd-ruby-buffer) (let ((cmdlist (inf-snd-args-to-list cmd))) (setq inf-snd-ruby-program-name cmd) (set-buffer (apply 'make-comint inf-snd-ruby-buffer-name (car cmdlist) nil (cdr cmdlist)))) (inf-snd-ruby-mode))) (defun run-snd-forth (cmd) "Start inferior Snd-Forth process. CMD is used for determine which program to run. If interactively called, one will be asked for program name to run." (interactive (list (if current-prefix-arg (read-string "Run Snd Forth: " inf-snd-forth-program-name) inf-snd-forth-program-name))) (unless (comint-check-proc inf-snd-forth-buffer) (let ((cmdlist (inf-snd-args-to-list cmd))) (setq inf-snd-forth-program-name cmd) (set-buffer (apply 'make-comint inf-snd-forth-buffer-name (car cmdlist) nil (cdr cmdlist)))) (inf-snd-forth-mode) (snd-send-invisible "undef"))) ;for inf-snd-comint-put-prompt-forth (defun run-snd-scheme (cmd) "Start inferior Snd-Scheme process. CMD is used for determine which program to run. If interactively called, one will be asked for program name to run." (interactive (list (if current-prefix-arg (read-string "Run Snd Scheme: " inf-snd-scheme-program-name) inf-snd-scheme-program-name))) (unless (comint-check-proc inf-snd-scheme-buffer) (let ((cmdlist (inf-snd-args-to-list cmd))) (setq inf-snd-scheme-program-name cmd) (set-buffer (apply 'make-comint inf-snd-scheme-buffer-name (car cmdlist) nil (cdr cmdlist)))) (inf-snd-scheme-mode) (snd-send-invisible "#f"))) (defalias 'run-snd-guile 'run-snd-scheme) ;;;; The snd-ruby-, snd-scheme-, and snd-forth-mode ;;; Commentary: ;; These three modes are derived from ruby-mode, scheme-mode, and ;; forth-mode. The main changes are the key bindings, which now refer ;; to special Snd-process-buffer-related ones. I took commands from ;; inf-ruby.el, from cmuscheme.el and from gforth.el and changed them ;; appropriately. (defvar snd-ruby-buffer-name "Snd/Ruby" "Buffer name of `snd-ruby-mode'.") (defvar snd-forth-buffer-name "Snd/Forth" "Buffer name of `snd-forth-mode'.") (defvar snd-scheme-buffer-name "Snd/Scheme" "Buffer name of `snd-scheme-mode'.") (defvar snd-ruby-mode-hook nil "User hook variable. Called after `ruby-mode-hook' and before starting inferior Snd process.") (defvar snd-forth-mode-hook nil "*User hook variable. Called after `forth-mode-hook' and before starting inferior Snd process.") (defvar snd-scheme-mode-hook nil "*User hook variable. Called after `scheme-mode-hook' and before starting inferior Snd process.") (defalias 'snd-guile-mode-hook 'snd-scheme-mode-hook) (defvar snd-source-modes '(snd-ruby-mode) "Used to determine if a buffer contains Snd source code. If it's loaded into a buffer that is in one of these major modes, it's considered a Snd source file by `snd-load-file'. Used by this command to determine defaults. This variable is buffer-local in `snd-ruby-mode', `snd-forth-mode' and `snd-scheme-mode'.") (defvar snd-inf-kind 'ruby "Options are 'ruby, 'forth, and 'scheme. Needed to determine which extension language should be used. This variable is buffer-local in `snd-ruby-mode', `snd-forth-mode', and `snd-scheme-mode'.") (defvar snd-prev-l/c-dir/file nil "Cache the (directory . file) pair used in the last `snd-load-file'. Used for determining the default in the next one.") (define-derived-mode snd-ruby-mode ruby-mode snd-ruby-buffer-name "Major mode for editing Snd-Ruby code. Editing commands are similar to those of `ruby-mode'. In addition, you can start an inferior Snd process and some additional commands will be defined for evaluating expressions. A menu ``Snd/Ruby'' appears in the menu bar. Entries in this menu are disabled if no inferior Snd process exist. You can use the hook variables `ruby-mode-hook' and `snd-ruby-mode-hook', which will be called in that order. The current key bindings are: \\{snd-ruby-mode-map}" (make-local-variable 'snd-inf-kind) (make-local-variable 'snd-source-modes) (setq snd-inf-kind 'ruby) (setq snd-source-modes '(snd-ruby-mode)) (unless inf-snd-ruby-keywords (setq inf-snd-ruby-keywords (inf-snd-set-keywords))) (snd-set-keys 'snd-ruby-mode snd-ruby-buffer-name) (run-hooks 'snd-ruby-mode-hook)) (define-derived-mode snd-forth-mode forth-mode snd-forth-buffer-name "Major mode for editing Snd-Forth code. Editing commands are similar to those of `forth-mode'. In addition, you can start an inferior Snd process and some additional commands will be defined for evaluating expressions. A menu ``Snd/Forth'' appears in the menu bar. Entries in this menu are disabled if no inferior Snd process exist. You can use the hook variables `forth-mode-hook' and `snd-forth-mode-hook', which will be called in that order. The current key bindings are: \\{snd-forth-mode-map}" (make-local-variable 'snd-inf-kind) (make-local-variable 'snd-source-modes) (setq snd-inf-kind 'forth) (setq snd-source-modes '(snd-forth-mode)) (unless inf-snd-scheme-keywords (setq inf-snd-scheme-keywords (inf-snd-set-keywords))) (snd-set-keys 'snd-forth-mode snd-forth-buffer-name) (run-hooks 'snd-forth-mode-hook)) (define-derived-mode snd-scheme-mode scheme-mode snd-scheme-buffer-name "Major mode for editing Snd-Scheme code. Editing commands are similar to those of `scheme-mode'. In addition, you can start an inferior Snd process and some additional commands will be defined for evaluating expressions. A menu ``Snd/Scheme'' appears in the menu bar. Entries in this menu are disabled if no inferior Snd process exist. You can use variables `scheme-mode-hook' and `snd-scheme-mode-hook', which will be called in that order. The current key bindings are: \\{snd-scheme-mode-map}" (make-local-variable 'snd-inf-kind) (make-local-variable 'snd-source-modes) (setq snd-inf-kind 'scheme) (setq snd-source-modes '(snd-scheme-mode)) (unless inf-snd-scheme-keywords (setq inf-snd-scheme-keywords (inf-snd-set-keywords))) (snd-set-keys 'snd-scheme-mode snd-scheme-buffer-name) (run-hooks 'snd-scheme-mode-hook)) (defalias 'snd-guile-mode 'snd-scheme-mode) (defun snd-send-region (start end) "Send the current region to the inferior Snd process. START and END define the region." (interactive "r") (if (eq 'ruby snd-inf-kind) (progn (write-region start end snd-send-eval-file nil 0) (comint-send-string (snd-proc) (format "eval(File.open(%S).read, TOPLEVEL_BINDING, \"(emacs-eval-region)\", 1).inspect \ rescue message(\"(emacs-eval-region): %%s (%%s)\\n%%s\", \ $!.message, $!.class, $!.backtrace.join(\"\\n\"))\n" snd-send-eval-file))) (comint-send-region (snd-proc) start end) (comint-send-string (snd-proc) "\n"))) (defun snd-send-region-and-go (start end) "Send the current region to the inferior Snd process. Switch to the process buffer. START and END define the region." (interactive "r") (snd-send-region start end) (snd-switch-to-snd t)) (defun snd-send-definition (&optional cnt) "Send the current or CNT definition to the inferior Snd process." (interactive "p") (save-excursion (if (eq 'ruby snd-inf-kind) (ruby-beginning-of-defun cnt) (beginning-of-defun cnt)) (let ((beg (point))) (if (eq 'ruby snd-inf-kind) (ruby-end-of-defun) (end-of-defun)) (snd-send-region beg (point))))) (defun snd-send-definition-and-go (&optional cnt) "Send the current or CNT definition to the inferior Snd process. Switch to the process buffer." (interactive "p") (snd-send-definition cnt) (snd-switch-to-snd t)) (defun snd-send-last-sexp (&optional cnt) "Send the previous or CNT sexp to the inferior Snd process." (interactive "p") (snd-send-region (save-excursion (if (eq 'ruby snd-inf-kind) (ruby-backward-sexp cnt) (backward-sexp cnt)) (point)) (point))) (defun snd-send-block (&optional cnt) "Send the current or CNT block to the inferior Snd-Ruby process. Works only in `snd-ruby-mode'." (interactive "p") (save-excursion (ruby-beginning-of-block cnt) (let ((beg (point))) (ruby-end-of-block) (end-of-line) (snd-send-region beg (point))))) (defun snd-send-block-and-go (&optional cnt) "Send the current or CNT block to the inferior Snd-Ruby process. Switch to the process buffer. Works only in `snd-ruby-mode'." (interactive "p") (snd-send-block cnt) (snd-switch-to-snd t)) (defun snd-send-buffer () "Send the current buffer to the inferior Snd process." (interactive) (snd-send-region (point-min) (point-max))) (defun snd-send-buffer-and-go () "Send the current buffer to the inferior Snd process. Switch to the process buffer." (interactive) (snd-send-buffer) (snd-switch-to-snd t)) (defun snd-switch-to-snd (&optional eob-p) "If inferior Snd process exists, switch to process buffer, else start Snd. Non-nil EOB-P positions cursor at end of buffer." (interactive "P") (let ((buf (snd-proc-buffer))) (if (get-buffer buf) (pop-to-buffer buf) (snd-run-snd)) (if eob-p (push-mark) (goto-char (point-max))))) (defun snd-run-snd () "If inferior Snd process exists, switch to process buffer, else start Snd. Started from `snd-ruby-mode', `snd-forth-mode' or `snd-scheme-mode'." (interactive) (if (snd-proc-p) (progn (pop-to-buffer (snd-proc-buffer)) (push-mark) (goto-char (point-max))) (cond ((eq 'ruby snd-inf-kind) (run-snd-ruby inf-snd-ruby-program-name)) ((eq 'forth snd-inf-kind) (run-snd-forth inf-snd-forth-program-name)) (t (run-snd-scheme inf-snd-scheme-program-name))))) (defun snd-load-file-protected (filename) "Load a Ruby script FILENAME as an anonymous module into the inferior Snd process." (interactive (comint-get-source "Load Snd script file: " snd-prev-l/c-dir/file snd-source-modes t)) (comint-check-source filename) (setq snd-prev-l/c-dir/file (cons (file-name-directory filename) (file-name-nondirectory filename))) (comint-send-string (snd-proc) (concat "load(\"" filename "\", true)\n"))) (defun snd-load-file (filename) "Load a Snd script FILENAME into the inferior Snd process." (interactive (comint-get-source "Load Snd script file: " snd-prev-l/c-dir/file snd-source-modes t)) (comint-check-source filename) (setq snd-prev-l/c-dir/file (cons (file-name-directory filename) (file-name-nondirectory filename))) (if (eq 'forth snd-inf-kind) (comint-send-string (snd-proc) (concat "include " filename "\n")) (comint-send-string (snd-proc) (concat "(load \"" filename"\"\)\n")))) (defun snd-save-state () "Synchronize the inferior Snd process with the edit buffer." (and (snd-proc) (setq inf-snd-kind snd-inf-kind))) (defun snd-file () "Open Snd's view-files-dialog widget." (interactive) (snd-save-state) (inf-snd-file)) (defun snd-play () "Play current sound." (interactive) (snd-save-state) (inf-snd-play)) (defun snd-stop () "Stop playing of all sounds." (interactive) (snd-save-state) (inf-snd-stop)) (defun snd-help (&optional html-help) "Receive a string in minibuffer and show corresponding help. \\\\\\ This is done via Snd's function snd_help() or html() if HTML-HELP is non-nil, i.e. it's called by \\[universal-argument] \\[snd-help], putting result at the end of the inferior Snd process buffer. If point is near a function name in inferior Snd process buffer, that function will be used as default value in minibuffer; tab-completion is activated. `inf-snd-ruby-keywords' and `inf-snd-scheme-keywords' hold the help strings, the user variable `inf-snd-index-path' should point to the correct path of snd-xref.c." (interactive "P") (snd-save-state) (inf-snd-help html-help)) (defun snd-help-html () "Start html help." (interactive) (snd-help t)) (defun snd-quit () "Send exit to current inferior Snd process." (interactive) (snd-save-state) (save-excursion (snd-switch-to-snd t) (inf-snd-quit))) (defun snd-kill () "Kill current inferior Snd process buffer." (interactive) (snd-save-state) (save-excursion (snd-switch-to-snd t) (inf-snd-kill))) (defun snd-proc-buffer () "Return the current process buffer." (cond ((eq 'ruby snd-inf-kind) inf-snd-ruby-buffer) ((eq 'forth snd-inf-kind) inf-snd-forth-buffer) (t inf-snd-scheme-buffer))) (defun snd-proc () "Return the process buffer." (let* ((buf (snd-proc-buffer)) (proc (get-buffer-process (if (eq major-mode (cond ((eq 'ruby snd-inf-kind) 'inf-snd-ruby-mode) ((eq 'forth snd-inf-kind) 'inf-snd-forth-mode) (' 'inf-snd-scheme-mode))) (current-buffer) buf)))) (or proc (error "No current process. See variable inf-snd-ruby|inf-snd-forth|scheme-buffer")))) (defun snd-proc-p () "Return non-nil if no process buffer available." (save-current-buffer (comint-check-proc (snd-proc-buffer)))) (defun snd-set-keys (mode name) "Set the key bindings and menu entries for MODE. Menu name is NAME. You can extend the key bindings and menu entries here or via hook variables in .emacs file." (define-key (current-local-map) "\M-\C-x" 'snd-send-definition) (define-key (current-local-map) "\C-x\C-e" 'snd-send-last-sexp) (define-key (current-local-map) "\C-c\M-e" 'snd-send-definition) (define-key (current-local-map) "\C-c\C-e" 'snd-send-definition-and-go) (define-key (current-local-map) "\C-c\M-r" 'snd-send-region) (define-key (current-local-map) "\C-c\C-r" 'snd-send-region-and-go) (define-key (current-local-map) "\C-c\M-o" 'snd-send-buffer) (define-key (current-local-map) "\C-c\C-o" 'snd-send-buffer-and-go) (define-key (current-local-map) "\C-c\C-z" 'snd-switch-to-snd) (define-key (current-local-map) "\C-c\C-s" 'snd-run-snd) (define-key (current-local-map) "\C-c\C-l" 'snd-load-file) (define-key (current-local-map) "\C-c\C-f" 'snd-file) (define-key (current-local-map) "\C-c\C-p" 'snd-play) (define-key (current-local-map) "\C-c\C-t" 'snd-stop) (define-key (current-local-map) "\C-c\C-i" 'snd-help) (define-key (current-local-map) "\C-c\C-k" 'snd-kill) (define-key (current-local-map) "\C-c\C-q" 'snd-quit) (define-key (current-local-map) "\e\C-i" 'snd-completion) (if (eq 'ruby snd-inf-kind) (progn (define-key (current-local-map) "\C-c\M-b" 'snd-send-block) (define-key (current-local-map) "\C-c\C-b" 'snd-send-block-and-go) (define-key (current-local-map) "\C-cb" 'undefined) ;overwrite inf-ruby-commands (define-key (current-local-map) "\C-cr" 'undefined) ;C-c + single letter key (define-key (current-local-map) "\C-ce" 'undefined) ;is reserved for user (define-key (current-local-map) "\C-c\C-x" 'undefined) ;key bindings (define-key (current-local-map) "\C-c\M-x" 'undefined)) (define-key (current-local-map) "\C-c\C-c" 'undefined) ;no compile (define-key (current-local-map) "\C-c\M-c" 'undefined)) (define-key (current-local-map) [menu-bar mode] (cons name (make-sparse-keymap name))) (define-key (current-local-map) [menu-bar mode kill] '(menu-item "Kill Snd Process and Buffer" snd-kill :enable (snd-proc-p))) (define-key (current-local-map) [menu-bar mode quit] '(menu-item "Send exit to Snd Process" snd-quit :enable (snd-proc-p))) (define-key (current-local-map) [menu-bar mode sep-quit] '(menu-item "--")) (define-key (current-local-map) [menu-bar mode desc] '(menu-item "Describe Mode" describe-mode)) (define-key (current-local-map) [menu-bar mode help-html] '(menu-item "Describe Snd Function (html) ..." snd-help-html :enable (snd-proc-p))) (define-key (current-local-map) [menu-bar mode help] '(menu-item "Describe Snd Function (snd-help) ..." snd-help :enable (snd-proc-p))) (define-key (current-local-map) [menu-bar mode sep-desc] '(menu-item "--")) (define-key (current-local-map) [menu-bar mode stop] '(menu-item "Stop Playing" snd-stop :enable (snd-proc-p))) (define-key (current-local-map) [menu-bar mode play] '(menu-item "Start Playing" snd-play :enable (snd-proc-p))) (define-key (current-local-map) [menu-bar mode file] '(menu-item "Open Snd-File Dialog" snd-file :enable (snd-proc-p))) (define-key (current-local-map) [menu-bar mode sep-load] '(menu-item "--")) (define-key (current-local-map) [menu-bar mode start-r] '(menu-item "Start Snd-Ruby Process" snd-run-snd :enable (not (snd-proc-p)) :visible (eq 'ruby snd-inf-kind))) (define-key (current-local-map) [menu-bar mode start-f] '(menu-item "Start Snd-Forth Process" snd-run-snd :enable (not (snd-proc-p)) :visible (eq 'forth snd-inf-kind))) (define-key (current-local-map) [menu-bar mode start-g] '(menu-item "Start Snd-Scheme Process" snd-run-snd :enable (not (snd-proc-p)) :visible (eq 'scheme snd-inf-kind))) (define-key (current-local-map) [menu-bar mode switch] '(menu-item "Switch to Snd Process" snd-switch-to-snd :enable (snd-proc-p))) (define-key (current-local-map) [menu-bar mode sep-proc] '(menu-item "--")) (define-key (current-local-map) [menu-bar mode block-go] '(menu-item "Send Block and Go" snd-send-block-and-go :enable (snd-proc-p) :visible (eq 'ruby snd-inf-kind))) (define-key (current-local-map) [menu-bar mode block] '(menu-item "Send Block" snd-send-block :enable (snd-proc-p) :visible (eq 'ruby snd-inf-kind))) (define-key (current-local-map) [menu-bar mode buffer-go] '(menu-item "Send Buffer and Go" snd-send-buffer-and-go :enable (snd-proc-p))) (define-key (current-local-map) [menu-bar mode buffer] '(menu-item "Send Buffer" snd-send-buffer :enable (snd-proc-p))) (define-key (current-local-map) [menu-bar mode region-go] '(menu-item "Send Region and Go" snd-send-region-and-go :enable (and (snd-proc-p) mark-active))) (define-key (current-local-map) [menu-bar mode region] '(menu-item "Send Region" snd-send-region :enable (and (snd-proc-p) mark-active))) (define-key (current-local-map) [menu-bar mode def-go] '(menu-item "Send Definition and Go" snd-send-definition-and-go :enable (snd-proc-p))) (define-key (current-local-map) [menu-bar mode def] '(menu-item "Send Definition" snd-send-definition :enable (snd-proc-p))) (define-key (current-local-map) [menu-bar mode last-sexp] '(menu-item "Send last Sexp" snd-send-last-sexp :enable (snd-proc-p))) (define-key (current-local-map) [menu-bar mode sep-load] '(menu-item "--")) (define-key (current-local-map) [menu-bar mode load-sec] '(menu-item "Load Ruby Script (protected) ..." snd-load-file-protected :enable (snd-proc-p) :visible (eq 'ruby snd-inf-kind))) (define-key (current-local-map) [menu-bar mode load-r] '(menu-item "Load Ruby Script ..." snd-load-file :enable (snd-proc-p) :visible (eq 'ruby snd-inf-kind))) (define-key (current-local-map) [menu-bar mode load-f] '(menu-item "Load Forth Script ..." snd-load-file :enable (snd-proc-p) :visible (eq 'forth snd-inf-kind))) (define-key (current-local-map) [menu-bar mode load-g] '(menu-item "Load Scheme Script ..." snd-load-file :enable (snd-proc-p) :visible (eq 'scheme snd-inf-kind)))) (provide 'inf-snd) ;;; inf-snd.el ends here snd-16.1/snd-x0.h0000644000076400007640000001744012471670274011635 0ustar bilbil#ifndef SND_X0_H #define SND_X0_H #include #include #include #if HAVE_GL #include #include #endif #define XOR(a, b) ((a) ^ (b)) /* can't get used to this operator -- in the good old days, ^ meant exponentiation */ #define xm_font_t XmRenderTable #define XM_FONT_RESOURCE XmNrenderTable #define XM_FONT_FREE XmRenderTableFree #define LOTSA_PIXELS 10000 #define Xen_wrap_widget(Value) ((Value) ? Xen_list_2(C_string_to_Xen_symbol("Widget"), Xen_wrap_C_pointer(Value)) : Xen_false) #define Xen_wrap_window(Value) ((Value) ? Xen_list_2(C_string_to_Xen_symbol("Window"), C_ulong_to_Xen_ulong(Value)) : Xen_false) #define Xen_unwrap_widget(Value) (Xen_is_list(Value) ? Xen_unwrap_C_pointer(Xen_cadr(Value)) : 0) #define Xen_is_widget(Value) (Xen_is_list(Value) && (Xen_list_length(Value) >= 2) && (Xen_is_symbol(Xen_car(Value))) && \ (strcmp("Widget", Xen_symbol_to_C_string(Xen_car(Value))) == 0)) #define Xen_wrap_pixel(Value) Xen_list_2(C_string_to_Xen_symbol("Pixel"), C_int_to_Xen_integer((int)Value)) /* not ulong here! -- messes up the equal? check */ #define Xen_unwrap_pixel(Value) (unsigned long)Xen_integer_to_C_int(Xen_cadr(Value)) #define Xen_is_pixel(Value) (Xen_is_list(Value) && (Xen_list_length(Value) >= 2) && (Xen_is_symbol(Xen_car(Value))) && \ (strcmp("Pixel", Xen_symbol_to_C_string(Xen_car(Value))) == 0)) #define NULL_WIDGET NULL typedef enum {NOT_ACTIVATABLE, ACTIVATABLE, ACTIVATABLE_BUT_NOT_FOCUSED} text_cr_t; #define LINE_MARGIN 4 #define CONTROLS_MARGIN 1 #define SCROLLBAR_MAX 10000 #define BACKGROUND_QUIT 1 #define BACKGROUND_CONTINUE 0 #define BACKGROUND_REMOVE(func) XtRemoveWorkProc(func) /* #define BACKGROUND_ADD(func, data) XtAppAddWorkProc(MAIN_APP(ss), func, (XtPointer)data) */ #define BACKGROUND_ADD(func, data) add_work_proc(func, (XtPointer)data) #define CALL_TIMEOUT(Func, Wait, Data) XtAppAddTimeOut(MAIN_APP(ss), Wait, Func, (XtPointer)Data) #define TIMEOUT_ARGS XtPointer context, XtIntervalId *id #define TIMEOUT_TYPE void #define TIMEOUT_RESULT #define timeout_result_t XtIntervalId #define TIMEOUT_REMOVE(Id) XtRemoveTimeOut(Id) #define widget_t Widget #define widget_is_active(Wid) XtIsManaged(Wid) #define activate_widget(Wid) XtManageChild(Wid) #define deactivate_widget(Wid) XtUnmanageChild(Wid) #define idle_t XtWorkProcId #define idle_func_t Boolean #define any_pointer_t XtPointer /* can't use "pointer_t" -- Mac already defines that type (CoreServices.h) */ #define oclock_t Time #define color_t Pixel #define point_t XPoint #define gc_t GC #define rgb_t unsigned short #define RGB_MAX 65535 #define float_to_rgb(Val) (rgb_t)(RGB_MAX * (Val)) #define rgb_to_float(Val) (float)((float)(Val) / (float)RGB_MAX) typedef struct { GC gc; Display *dp; Drawable wn; Font current_font; } graphics_context; typedef enum {NOT_A_SCANF_WIDGET, SRATE_WIDGET, CHANS_WIDGET, DATA_LOCATION_WIDGET, SAMPLES_WIDGET} scanf_widget_t; typedef struct { Widget header_type_list, sample_type_list, srate_text, chans_text, comment_text, location_text, samples_text, error_text; Widget dialog, src_button, auto_comment_button; mus_header_t current_header_type; mus_sample_t current_sample_type; int sample_types, header_type_pos, sample_type_pos; scanf_widget_t scanf_widget, error_widget; bool src, auto_comment; char *saved_comment; } file_data; typedef enum {WITHOUT_CHANNELS_FIELD, WITH_CHANNELS_FIELD, WITH_EXTRACT_CHANNELS_FIELD} dialog_channels_t; typedef enum {WITHOUT_SAMPLES_FIELD, WITH_SAMPLES_FIELD} dialog_samples_t; typedef enum {WITHOUT_DATA_LOCATION_FIELD, WITH_DATA_LOCATION_FIELD} dialog_data_location_t; typedef enum {WITHOUT_HEADER_TYPE_FIELD, WITH_HEADER_TYPE_FIELD} dialog_header_type_t; typedef enum {WITHOUT_COMMENT_FIELD, WITH_COMMENT_FIELD} dialog_comment_t; #define snd_ShiftMask ShiftMask #define snd_ControlMask ControlMask #if (!HAVE_SUN) #define snd_MetaMask Mod1Mask #else #define snd_MetaMask (Mod1Mask | Mod4Mask) #endif #define MAIN_SHELL(a) (a)->mainshell #define MAIN_PANE(a) (a)->mainpane #define SOUND_PANE(a) (a)->soundpane #define SOUND_PANE_BOX(a) (a)->soundpanebox #define MAIN_APP(a) (a)->mainapp #define MAIN_DISPLAY(a) (a)->mdpy #define PEAKS_FONT(a) (a)->peaks_fontstruct #define BOLD_PEAKS_FONT(a) (a)->bold_peaks_fontstruct #define AXIS_NUMBERS_FONT(a) (a)->axis_numbers_fontstruct #define AXIS_LABEL_FONT(a) (a)->axis_label_fontstruct #define TINY_FONT(a) (a)->tiny_fontstruct #define LISTENER_FONT(a) (a)->listener_fontstruct #define DEFAULT_GRAPH_CURSOR XC_crosshair #define DEFAULT_TINY_FONT "6x12" #define DEFAULT_PEAKS_FONT "-*-times-medium-r-*-*-14-*-*-*-*-*-*-*" #define DEFAULT_BOLD_PEAKS_FONT "-*-times-bold-r-*-*-14-*-*-*-*-*-*-*" #define DEFAULT_AXIS_NUMBERS_FONT "9x15" #define DEFAULT_AXIS_LABEL_FONT "-*-times-medium-r-*-*-18-*-*-*-*-*-*-*" #define KEY_TO_NAME(key) XKeysymToString(key) /* on the Sun, if key is 0, XKeysymToString segfaults! */ /* #define GUI_CURRENT_TIME(ss) XtLastTimestampProcessed(MAIN_DISPLAY(ss)) */ /* now pull in the key names (/usr/include/X11/keysymdef.h) */ #define snd_K_Shift_L XK_Shift_L #define snd_K_space XK_space #define snd_K_openparen XK_parenleft #define snd_K_closeparen XK_parenright #define snd_K_plus XK_plus #define snd_K_minus XK_minus #define snd_K_period XK_period #define snd_K_slash XK_slash #define snd_K_0 XK_0 #define snd_K_1 XK_1 #define snd_K_2 XK_2 #define snd_K_3 XK_3 #define snd_K_4 XK_4 #define snd_K_5 XK_5 #define snd_K_6 XK_6 #define snd_K_7 XK_7 #define snd_K_8 XK_8 #define snd_K_9 XK_9 #define snd_K_less XK_less #define snd_K_greater XK_greater #define snd_K_A XK_A #define snd_K_B XK_B #define snd_K_C XK_C #define snd_K_D XK_D #define snd_K_E XK_E #define snd_K_F XK_F #define snd_K_G XK_G #define snd_K_H XK_H #define snd_K_I XK_I #define snd_K_J XK_J #define snd_K_K XK_K #define snd_K_L XK_L #define snd_K_M XK_M #define snd_K_N XK_N #define snd_K_O XK_O #define snd_K_P XK_P #define snd_K_Q XK_Q #define snd_K_R XK_R #define snd_K_S XK_S #define snd_K_T XK_T #define snd_K_U XK_U #define snd_K_V XK_V #define snd_K_W XK_W #define snd_K_X XK_X #define snd_K_Y XK_Y #define snd_K_Z XK_Z #define snd_K_underscore XK_underscore #define snd_K_a XK_a #define snd_K_b XK_b #define snd_K_c XK_c #define snd_K_d XK_d #define snd_K_e XK_e #define snd_K_f XK_f #define snd_K_g XK_g #define snd_K_h XK_h #define snd_K_i XK_i #define snd_K_j XK_j #define snd_K_k XK_k #define snd_K_l XK_l #define snd_K_m XK_m #define snd_K_n XK_n #define snd_K_o XK_o #define snd_K_p XK_p #define snd_K_q XK_q #define snd_K_r XK_r #define snd_K_s XK_s #define snd_K_t XK_t #define snd_K_u XK_u #define snd_K_v XK_v #define snd_K_w XK_w #define snd_K_x XK_x #define snd_K_y XK_y #define snd_K_z XK_z #define snd_K_Home XK_Home #define snd_K_Left XK_Left #define snd_K_Up XK_Up #define snd_K_Right XK_Right #define snd_K_Down XK_Down #define snd_keypad_Insert XK_KP_Insert #define snd_keypad_Delete XK_KP_Delete #define snd_keypad_Multiply XK_KP_Multiply #define snd_keypad_Add XK_KP_Add #define snd_keypad_Subtract XK_KP_Subtract #define snd_keypad_Divide XK_KP_Divide #define snd_keypad_Decimal XK_KP_Decimal #define snd_keypad_Enter XK_KP_Enter #define snd_keypad_Up XK_KP_Up #define snd_keypad_Down XK_KP_Down #define snd_keypad_Left XK_KP_Left #define snd_keypad_Right XK_KP_Right #define snd_keypad_0 XK_KP_0 #define snd_keypad_1 XK_KP_1 #define snd_keypad_2 XK_KP_2 #define snd_keypad_3 XK_KP_3 #define snd_keypad_4 XK_KP_4 #define snd_keypad_5 XK_KP_5 #define snd_keypad_6 XK_KP_6 #define snd_keypad_7 XK_KP_7 #define snd_keypad_8 XK_KP_8 #define snd_keypad_9 XK_KP_9 #endif snd-16.1/xm-enved.rb0000644000076400007640000007515412434353163012423 0ustar bilbil# xm-enved.rb -- Translation of xm-enved.scm and enved.scm # Translator/Author: Michael Scholz # Created: 03/03/18 00:18:35 # Changed: 14/11/13 04:56:16 # Tested with Snd 15.x # Ruby 2.x.x # Motif 2.3.3 X11R6 # # module Snd_enved # channel_enved(snd, chn) # set_channel_enved(new_env, snd, chn) # channel_envelope(snd, chn) # set_channel_envelope(new_env, snd, chn) # mouse_press_envelope(snd, chn, button, state, x, y) # mouse_drag_envelope(snd, chn, button, state, x, y) # mouse_release_envelope(snd, chn, button, state, x, y, axis) # create_initial_envelopes(snd) # enveloping_key_press(snd, chn, key, state) # start_enveloping # stop_enveloping # play_with_envs(snd = false) # # envelope?(obj) # make_enved(enved) # enved?(obj) # make_graph_enved(enved, snd, chn) # graph_enved?(obj) # make_xenved(name, parent, *rest) # xenved?(obj) # xenved_test(name) # # class Enved # initialize(enved) # inspect # to_s # envelope # envelope=(new_env) # reset # interp(x, base) # stretch(old_att, new_att, old_dec, new_dec) # stretch!(old_att, new_att, old_dec, new_dec) # scale(scale, offset) # scale!(scale, offset) # normalize(new_max) # normalize!(new_max) # reverse # reverse! # point(idx, *args) # min # max # length # first # last # first_x # last_x # first_y # last_y # in_range?(x) # each # each_with_index # map # map! # # class Graph_enved < Enved # initialize(enved, snd, chn) # click_time # click_time=(val) # before_enved_hook # after_enved_hook # inspect # to_s # reset # redraw # mouse_press_cb(x, y) # mouse_drag_cb(x, y) # mouse_release_cb # # class Xenved < Graph_enved # initialize(name, parent, enved, bounds, args, axis_label) # inspect # to_s # clear # envelope=(new_env) # axis_bounds # axis_bounds=(bounds) # point(idx, *args) # create # close require "env" require "hooks" require "extensions" if provided?(:snd_motif) or provided?(:snd_gtk) require "snd-xm" include Snd_XM else $with_motif = false $with_gtk = false end # # defined in snd-xm.rb: # # $with_motif # $with_gtk # $with_gui = ($with_motif or $with_gtk) ? true : false module Snd_enved # returns Graph_enved object or nil def channel_enved(snd = false, chn = false) channel_property(:enved_envelope, snd, chn) end # sets Graph_enved object def set_channel_enved(new_ge, snd = false, chn = false) set_channel_property(:enved_envelope, new_ge, snd, chn) end add_help(:channel_envelope, "channel_envelope(snd=false, chn=false) \ Returns the current enved envelope associated with SND's channel CHN.") def channel_envelope(snd = false, chn = false) if graph_enved?(ge = channel_enved(snd, chn)) ge.envelope elsif envelope?(en = channel_property(:channel_envelope, snd, chn)) set_channel_enved(make_graph_enved(en, snd, chn), snd, chn) en else nil end end def set_channel_envelope(new_env, snd = false, chn = false) set_channel_property(:channel_envelope, new_env, snd, chn) if graph_enved?(ge = channel_enved(snd, chn)) ge.envelope = new_env else ge = make_graph_enved(new_env, snd, chn) set_channel_enved(ge, snd, chn) end ge end # left button: set/delete point # middle button: reset to original env def mouse_press_envelope(snd, chn, button, state, x, y) case button when 1 graph_enved?(ge = channel_enved(snd, chn)) and ge.mouse_press_cb(x, y) when 2 graph_enved?(ge = channel_enved(snd, chn)) and ge.reset end end def mouse_drag_envelope(snd, chn, button, state, x, y) graph_enved?(ge = channel_enved(snd, chn)) and ge.mouse_drag_cb(x, y) end def mouse_release_envelope(snd, chn, button, state, x, y, axis) if axis == Lisp_graph graph_enved?(ge = channel_enved(snd, chn)) and ge.mouse_release_cb true else false end end def create_initial_envelopes(snd) channels(snd).times do |chn| set_dot_size(8, snd, chn) set_channel_envelope([0.0, 1.0, 1.0, 1.0], snd, chn) end end def enveloping_key_press(snd, chn, key, state) # C-g returns to original env # C-. applies current env to amplitude if key == ?. and state == 4 env_channel((channel_envelope(snd, chn) or [0, 1, 1, 1]), 0, framples(snd, chn), snd, chn) true else if key == ?g and state == 4 graph_enved?(ge = channel_enved(snd, chn)) and ge.reset true else false end end end Hook_name = "graph-enved" add_help(:start_enveloping, "start_enveloping() \ Starts the enved processes, displaying an envelope editor in each channel.") def start_enveloping unless $after_open_hook.member?(Hook_name) $after_open_hook.add_hook!(Hook_name) do |snd| create_initial_envelopes(snd) end $mouse_press_hook.add_hook!(Hook_name) do |snd, chn, button, state, x, y| mouse_press_envelope(snd, chn, button, state, x, y) end $mouse_drag_hook.add_hook!(Hook_name) do |snd, chn, button, state, x, y| mouse_drag_envelope(snd, chn, button, state, x, y) end $mouse_click_hook.add_hook!(Hook_name) do |snd, chn, but, st, x, y, axis| mouse_release_envelope(snd, chn, but, st, x, y, axis) end $key_press_hook.add_hook!(Hook_name) do |snd, chn, key, state| enveloping_key_press(snd, chn, key, state) end true else false end end add_help(:stop_enveloping, "stop_enveloping() \ Turns off the enved channel-specific envelope editors.") def stop_enveloping $after_open_hook.remove_hook!(Hook_name) $mouse_press_hook.remove_hook!(Hook_name) $mouse_drag_hook.remove_hook!(Hook_name) $mouse_click_hook.remove_hook!(Hook_name) $key_press_hook.remove_hook!(Hook_name) Snd.catch do set_lisp_graph?(false, Snd.snd, Snd.chn) end nil end # some examples add_help(:play_with_envs, "play_with_envs(snd=false) \ Sets channel amps during playback from the associated enved envelopes.") def play_with_envs(snd = false) channel_envelope(snd, 0) or create_initial_envelopes(snd) channels(snd).times do |chn| player = make_player(snd, chn) e = make_env(:envelope, channel_envelope(snd, chn), :length, (framples(snd, chn).to_f / dac_size).floor) add_player(player, 0, -1, -1, lambda do |reason| $play_hook.reset_hook! end) $play_hook.add_hook!(get_func_name) do |fr| set_amp_control(env(e), player) end end start_playing(channels(snd), srate(snd)) end def envelope?(obj) array?(obj) and obj.length >= 4 and obj.length.even? end def make_enved(enved = [0, 0, 1, 1]) assert_type(envelope?(enved), enved, 0, "an envelope, at least 2 points [x0, y0, x1, y1, ...]") Enved.new(enved) end def enved?(obj) obj.instance_of?(Enved) end def make_graph_enved(enved = [0, 0, 1, 1], snd = Snd.snd, chn = Snd.chn) assert_type(envelope?(enved), enved, 0, "an envelope, at least 2 points [x0, y0, x1, y1, ...]") (ge = Graph_enved.new(enved, snd, chn)).redraw ge end def graph_enved?(obj) obj.instance_of?(Graph_enved) end if $with_gui def make_xenved(name, parent, *rest) envelope, bounds, args, label = optkey(rest, [:envelope, [0, 0, 1, 1]], [:axis_bounds, [0, 1, 0, 1]], [:args, []], :axis_label) unless string?(name) and (not name.empty?) name = "xenved" end assert_type(widget?(parent), parent, 1, "a widget") assert_type((array?(bounds) and bounds.length == 4), bounds, 3, "an array of 4 elements [x0, x1, y0, y1]") unless array?(label) and label.length == 4 label = bounds end Xenved.new(name, parent, envelope, bounds, args, label) end def xenved?(obj) obj.instance_of?(Xenved) end if $with_motif Test_widget_type = RxmFormWidgetClass Test_widget_args = [RXmNheight, 200] Test_xenved_args = [RXmNleftAttachment, RXmATTACH_WIDGET, RXmNtopAttachment, RXmATTACH_WIDGET, RXmNbottomAttachment, RXmATTACH_WIDGET, RXmNrightAttachment, RXmATTACH_WIDGET] else Test_widget_type = false Test_widget_args = false Test_xenved_args = [] end def xenved_test(name = "xenved") make_xenved(name, add_main_pane(name, Test_widget_type, Test_widget_args), :envelope, [0, 0, 1, 1], :axis_bounds, [0, 1, 0, 1], :args, Test_xenved_args) end end end include Snd_enved class Enved include Enumerable include Info def initialize(enved = [0, 0, 1, 1]) (@envelope = enved).map! do |x| x.to_f end @init = @envelope.dup set_enved_help end attr_reader :envelope def inspect format("%s.new(%s)", self.class, @envelope) end def to_s format("#<%s: envelope: %s>", self.class, @envelope.to_string) end def envelope=(enved) assert_type(envelope?(enved), enved, 0, "an envelope, at least 2 points [x0, y0, x1, y1, ...]") @envelope = enved.map do |x| x.to_f end end def reset @envelope = @init.dup end def interp(x, base = 0) envelope_interp(x, @envelope, base) end def stretch(old_att = nil, new_att = nil, old_dec = nil, new_dec = nil) stretch_envelope(@envelope, old_att, new_att, old_dec, new_dec) end def stretch!(old_att = nil, new_att = nil, old_dec = nil, new_dec = nil) self.envelope = self.stretch(old_att, new_att, old_dec, new_dec) end def scale(scale = 1.0, offset = 0.0) scale_envelope(@envelope, scale, offset) end def scale!(scale = 1.0, offset = 0.0) self.envelope = self.scale(scale, offset) end def normalize(new_max = 1.0) self.scale(new_max / self.max) end def normalize!(new_max = 1.0) self.envelope = self.normalize(new_max) end def reverse reverse_envelope(@envelope) end def reverse! self.envelope = self.reverse end def point(idx, *args) x, y = optkey(args, :x, :y) if x @envelope[idx * 2] = x end if y @envelope[idx * 2 + 1] = y end @envelope[idx * 2, 2] end def min min_envelope(@envelope) end def max max_envelope(@envelope) end def length @envelope.length / 2 end def first if @envelope.length > 1 @envelope[0, 2] else [0.0, 0.0] end end def last if @envelope.length > 3 @envelope[-2, 2] else [1.0, 0.0] end end def first_x @envelope[0] end def first_y @envelope[1] end def last_x @envelope[-2] end def last_y @envelope[-1] end def in_range?(x) x > @envelope[0] and x < @envelope[-2] end def each 0.step(@envelope.length - 1, 2) do |i| yield(@envelope[i, 2]) end @envelope end def each_with_index 0.step(@envelope.length - 1, 2) do |i| yield(@envelope[i, 2] + [i]) end @envelope end def map res = make_array(@envelope.length) 0.step(@envelope.length - 1, 2) do |i| res[i, 2] = yield(@envelope[i, 2]) end res end def map! 0.step(@envelope.length - 1, 2) do |i| @envelope[i, 2] = yield(@envelope[i, 2]) end @envelope end private def set_enved_help self.description = "\ # make_enved(env) # # class Enved # initialize(env) # # getter and setter: # envelope=(new_env) # envelope # # methods: # interp(x, base) # stretch(oatt, natt, odec, ndec) stretch!(oatt, natt, odec, ndec) # scale(scale, offset) scale!(scale, offset) # normalize(new_max) normalize!(new_max) # reverse reverse! # max min # first (first [x, y]) last (last [x, y]) # first_x last_x # first_y last_y # map do |x, y| ... end map! do |x, y| ... end # each do |x, y| ... end each_with_index do |x, y, i| ... end # length # point(idx, *args) # point(idx) ==> [x, y] # # point(idx, :x, x_val, :y, y_val) # # sets x, y or both and returns new [x, y] # in_range?(x) (x > first_x and x < last_x) # help (alias info and description) " add_help(:Enved, self.description) end end class Graph_enved < Enved def initialize(enved, snd = false, chn = false) super(enved) @graph_name = short_file_name(snd) @snd = snd @chn = chn @before_enved_hook = Hook.new("@before_enved_hook", 4, "\ lambda do |pos, x, y, reason| ... end: called before changing a \ breakpoint in @envelope. This hook runs the global $enved_hook as \ first hook, subsequent procedures can directly manipulate @envelope. This instance hook is like the global $enved_hook; POS is @envelope's \ x-position, X and Y are the new points, and REASON is one of \ Enved_add_point, Enved_delete_point, Enved_move_point. If the last \ hook procedure in the hook list returns `false', the class changes the \ breakpoint, otherwise the hook procedures are responsible for \ manipulating @envelope itself. From dlocsig.rb: @velocity = make_xenved(\"velocity (v)\", frame, :envelope, [0.0, 0.0, 1.0, 0.0], :axis_bounds, [0.0, 1.0, 0.0, 1.0], :axis_label, [-20.0, 20.0, 0.0, 2.0]) @velocity.before_enved_hook.reset_hook! # to prevent running $enved_hook @velocity.before_enved_hook.add_hook!(\"dlocsig-hook\") do |pos, x, y, reason| if reason == Enved_move_point if @velocity.in_range?(x) old_x = @velocity.point(pos).first @velocity.stretch!(old_x, x) @velocity.point(pos, :y, y) else false end else false end end In contrast the same procedure on the global $enved_hook: $enved_hook.add_hook!(\"snd-init-hook\") do |env, pt, x, y, reason| if reason == Enved_move_point if x > 0.0 and x < env[-2] old_x = env[2 * pt] new_env = stretch_envelope(env, old_x, x) new_env[pt * 2 + 1] = y new_env else # env # first and last points are fixed false # first and last points can be moved end else false end end") hn = "initialize-xm-enved-hook" @before_enved_hook.add_hook!(hn) do |pos, x, y, reason| if $enved_hook.empty? false else e = nil $enved_hook.run_hook do |prc| case e = prc.call(@envelope.dup, pos, x, y, reason) when Array self.envelope = e when Enved, Graph_enved, Xenved self.envelope = e.envelope end end e.class != FalseClass end end @after_enved_hook = Hook.new("@after_enved_hook", 2, "\ lambda do |pos, reason| ... end: called after redrawing new or changed \ breakpoints. POS is @envelope's x-position, and REASON is one of \ Enved_add_point, Enved_delete_point, Enved_move_point.") init set_enved_help end alias help description attr_accessor :click_time attr_reader :before_enved_hook attr_reader :after_enved_hook def inspect format("%s.new(%s, %s, %s)", self.class, @envelope, @snd, @chn) end def to_s format("#<%s: %s[%s:%s]: %s>", self.class, @graph_name, @snd, @chn, @envelope.to_string) end def init @mouse_up = 0.0 @mouse_down = 0.0 @click_time = 0.5 @mouse_pos = 0 @mouse_new = false end def envelope=(new_env) super self.redraw @envelope end def reset super self.redraw init @envelope end def redraw graph(@envelope, @graph_name, 0.0, 1.0, 0.0, 1.0, @snd, @chn) update_lisp_graph(@snd, @chn) end Mouse_radius = 0.03 # To prevent unexpected point movements if position is near first or # last point. Secure_distance = 0.001 def mouse_press_cb(x, y) x = [0.0, [x, 1.0].min].max y = [0.0, [y, 1.0].min].max pos = false self.each_with_index do |x1, y1, i| if (x1 - x).abs < Mouse_radius and (y1 - y).abs < Mouse_radius pos = i break end end @mouse_new = (not pos) @mouse_down = Time.now.to_f if pos @mouse_pos = pos else x = [Secure_distance, [x, 1.0 - Secure_distance].min].max if run_before_enved_hook(x, y, Enved_add_point) add_envelope_point(x, y) end self.redraw @after_enved_hook.call(@mouse_pos / 2, Enved_add_point) end end def mouse_drag_cb(x, y) lx = if @mouse_pos.zero? @envelope[0] elsif @mouse_pos >= (@envelope.length - 2) @envelope[-2] else [@envelope[@mouse_pos - 2] + Secure_distance, [x, @envelope[@mouse_pos + 2] - Secure_distance].min].max end #ly = [0.0, [y, 1.0].min].max ly = y if run_before_enved_hook(lx, ly, Enved_move_point) @envelope[@mouse_pos, 2] = [lx, ly] end self.redraw @after_enved_hook.call(@mouse_pos / 2, Enved_move_point) end def mouse_release_cb @mouse_up = Time.now.to_f if (not @mouse_new) and (@mouse_up - @mouse_down) <= @click_time and @mouse_pos.nonzero? and @mouse_pos < (@envelope.length - 2) if run_before_enved_hook(@envelope[@mouse_pos], @envelope[@mouse_pos + 1], Enved_delete_point) @envelope.slice!(@mouse_pos, 2) end self.redraw @after_enved_hook.call(@mouse_pos / 2, Enved_delete_point) end @mouse_new = false end protected # If the last hook procedure returns false, change the envelope, # otherwise the hook procedure is responsible. def run_before_enved_hook(x, y, reason) if @before_enved_hook.empty? true else e = nil @before_enved_hook.run_hook do |prc| e = prc.call(@mouse_pos / 2, x, y, reason) end e.class == FalseClass end end def add_envelope_point(x, y) idx = @mouse_pos test_env = @envelope.to_pairs if cur_pair = test_env.assoc(x) idx = test_env.index(cur_pair) * 2 @envelope[idx + 1] = y else cur_pair = test_env.detect do |pair| x < pair[0] end if cur_pair idx = test_env.index(cur_pair) * 2 @envelope.insert(idx, x, y) end end @mouse_pos = idx end private def set_enved_help super self.description += "\ # # make_graph_enved(enved, snd, chn) # # class Graph_enved < Enved (see enved.scm) # initialize(enved, snd, chn) # before_enved_hook lambda do |pos, x, y, reason| ... end # after_enved_hook lambda do |pos, reason| ... end # # getter and setter: # click_time=(val) # click_time # # interactive methods: # init # reset # redraw # mouse_press_cb(x, y) # mouse_drag_cb(x, y) # mouse_release_cb # help (alias info and description) # more examples in xm-enved.rb, module Snd_enved ge = make_graph_enved([0, 0, 1, 1], 0, 0) ge.envelope # ==> [0.0, 0.0, 1.0, 1.0] ge.click_time # ==> 0.2 ge.envelope = [0, 1, 1, 1] ge.help # this help " add_help(:Graph_enved, self.description) end end if $with_gui class Xenved < Graph_enved def initialize(name, parent, enved, bounds, args, axis_label) super(enved) @name = name @parent = parent @x0, @x1, @y0, @y1 = bounds.map do |x| x.to_f end @args = args if $with_motif unless @args.member?(RXmNforeground) @args += [RXmNforeground, data_color] end unless @args.member?(RXmNbackground) @args += [RXmNbackground, graph_color] end end @lx0, @lx1, @ly0, @ly1 = if envelope?(axis_label) axis_label.map do |x| x.to_f end else [0.0, 1.0, -1.0, 1.0] end @gc = snd_gcs[0] @drawer = @dpy = @window = nil @px0 = @px1 = @py0 = @py1 = nil @dragging = false set_enved_help create end alias help description def inspect format("%s.new(%p, %s, %s, %s, %s, %s)", self.class, @name, @parent, @envelope, [@x0, @x1, @y0, @y1], @args, [@lx0, @lx1, @ly0, @ly1]) end def to_s format("#<%s: name: %p, envelope: %s>", self.class, @name, @envelope.to_string) end def axis_bounds [@x0, @x1, @y0, @y1] end def axis_bounds=(bounds) assert_type((array?(bounds) and bounds.length == 4), bounds, 0, "an array of 4 elements [x0, x1, y0, y1]") @x0, @x1, @y0, @y1 = bounds.map do |x| x.to_f end self.envelope = @init end def point(idx, *args) if args.length > 0 super redraw end @envelope[idx * 2, 2] end def create if widget?(@drawer) show_widget(@drawer) else create_enved end end alias open create def close hide_widget(@drawer) end protected if $with_motif def redraw if is_managed?(@drawer) and @px0 and @py0 > @py1 RXClearWindow(@dpy, @window) # Motif's DRAW-AXES takes 6 optional arguments. # '( x0 y0 x1 y1 ) = draw-axes(wid gc label # x0=0.0 x1=1.0 y0=-1.0 y1=1.0 # style=x-axis-in-seconds # axes=show-all-axes) # arity #( 3 6 #f ) draw_axes(@drawer, @gc, @name, @lx0, @lx1, @ly0, @ly1) lx = ly = nil @envelope.each_pair do |x, y| cx = grfx(x) cy = grfy(y) RXFillArc(@dpy, @window, @gc, cx - Mouse_r, cy - Mouse_r, Mouse_d, Mouse_d, 0, 360 * 64) if lx RXDrawLine(@dpy, @window, @gc, lx, ly, cx, cy) end lx, ly = cx, cy end end end else def redraw if is_managed?(@drawer) and @px0 and @py0 > @py1 size = widget_size(RGTK_WIDGET(@drawer)) cairo = make_cairo(@drawer) Rcairo_push_group(cairo) Rcairo_set_source_rgb(cairo, 1.0, 1.0, 1.0) Rcairo_rectangle(cairo, 0, 0, size[0], size[1]) Rcairo_fill(cairo) # Gtk's DRAW-AXES takes one more optional argument, a cairo object. # '( x0 y0 x1 y1 ) = draw-axes(wid gc label # x0=0.0 x1=1.0 y0=-1.0 y1=1.0 # style=x-axis-in-seconds # axes=show-all-axes # cairo) # arity #( 3 7 #f ) draw_axes(@drawer, @gc, @name, @lx0, @lx1, @ly0, @ly1, X_axis_in_seconds, Show_all_axes, cairo) Rcairo_set_line_width(cairo, 1.0) Rcairo_set_source_rgb(cairo, 0.0, 0.0, 0.0) lx = ly = nil @envelope.each_pair do |x, y| cx = grfx(x) cy = grfy(y) Rcairo_arc(cairo, cx, cy, Mouse_r, 0.0, TWO_PI) Rcairo_fill(cairo) if lx Rcairo_move_to(cairo, lx, ly) Rcairo_line_to(cairo, cx, cy) Rcairo_stroke(cairo) end lx, ly = cx, cy end Rcairo_pop_group_to_source(cairo) Rcairo_paint(cairo) # Rcairo_destroy(cairo) free_cairo(cairo) end end end private def set_enved_help super self.description += "\ # # make_xenved(name, parent, *rest) # name String # parent Widget # *rest # :envelope, [0, 0, 1, 1] x0, y0, x1, y1, ... # :axis_bounds, [0, 1, 0, 1] x0, x1, y0, y1 # :args, [] Motif properties # :axis_label, nil if axes labels should have # other values than axis_bounds, # (see dlocsig.rb) # # class Xenved < Graph_enved (see xm-enved.scm) # initialize(name, parent, env, axis_bounds, args, axis_label) # # getter and setter: # axis_bounds=(new_bounds) # axis_bounds # # interactive methods: # create (alias open) # close # reset # help (alias info and description) # more examples in effects.rb xe = xenved_test xe.envelope # ==> [0.0, 0.0, 1.0, 1.0] xe.click_time # ==> 0.5 xe.envelope = [0, 1, 1, 1] # some clicks later xe.envelope # ==> [0.0, 0.0, # 0.190735694822888, 0.562264150943396, # 0.632152588555858, 0.932075471698113, # 0.848773841961853, 0.316981132075472, # 1.0, 1.0] xe.help # this help " add_help(:Xenved, self.description) end Mouse_d = 10 Mouse_r = 5 if $with_motif def create_enved @drawer = RXtCreateManagedWidget(@name, RxmDrawingAreaWidgetClass, @parent, @args) @dpy = RXtDisplay(@drawer) @window = RXtWindow(@drawer) RXtAddCallback(@drawer, RXmNresizeCallback, lambda do |w, c, i| draw_axes_cb end) RXtAddCallback(@drawer, RXmNexposeCallback, lambda do |w, c, i| draw_axes_cb end) RXtAddEventHandler(@drawer, RButtonPressMask, false, lambda do |w, c, e, f| mouse_press_cb(ungrfx(Rx(e)), ungrfy(Ry(e))) end) RXtAddEventHandler(@drawer, RButtonReleaseMask, false, lambda do |w, c, e, f| mouse_release_cb end) RXtAddEventHandler(@drawer, RButtonMotionMask, false, lambda do |w, c, e, f| mouse_drag_cb(ungrfx(Rx(e)), ungrfy(Ry(e))) end) RXtAddEventHandler(@drawer, REnterWindowMask, false, lambda do |w, cursor, e, f| RXDefineCursor(@dpy, @window, cursor) end, RXCreateFontCursor(@dpy, RXC_crosshair)) RXtAddEventHandler(@drawer, RLeaveWindowMask, false, lambda do |w, c, e, f| RXUndefineCursor(@dpy, @window) end) end else def create_enved @drawer = Rgtk_drawing_area_new() Rgtk_widget_set_events(@drawer, RGDK_ALL_EVENTS_MASK) Rgtk_box_pack_start(RGTK_BOX(@parent), @drawer, true, true, 10) Rgtk_widget_show(@drawer) Rgtk_widget_set_name(@drawer, @name) Rgtk_widget_set_size_request(@drawer, -1, 200) evname = provided?(:gtk3) ? "draw" : "expose_event" add_event_handler(@drawer, evname) do |w, e, d| draw_axes_cb false end add_event_handler(@drawer, "configure_event") do |w, e, d| draw_axes_cb false end add_event_handler(@drawer, "button_press_event") do |w, e, d| @dragging = true xy = Rgdk_event_get_coords(RGDK_EVENT(e)) mouse_press_cb(ungrfx(xy[1]), ungrfy(xy[2])) false end add_event_handler(@drawer, "button_release_event") do |w, e, d| @dragging = false mouse_release_cb false end add_event_handler(@drawer, "motion_notify_event") do |w, e, d| if @dragging xy = Rgdk_event_get_coords(RGDK_EVENT(e)) mouse_drag_cb(ungrfx(xy[1]), ungrfy(xy[2])) end false end add_event_handler(@drawer, "enter_notify_event", Rgdk_cursor_new(RGDK_CROSSHAIR)) do |w, e, cursor| Rgdk_window_set_cursor(Rgtk_widget_get_window(w), cursor) false end add_event_handler(@drawer, "leave_notify_event", Rgdk_cursor_new(RGDK_LEFT_PTR)) do |w, e, cursor| Rgdk_window_set_cursor(Rgtk_widget_get_window(w), cursor) false end end end if $with_motif # Motif's DRAW_AXES takes 3 required and 6 optional arguments. # draw_axes(wid, gc, label, # x0=0.0, x1=1.0, y0=-1.0, y1=1.0, # style=X_axis_in_seconds, # axes=Show_all_axes) def draw_axes_cb @px0, @py0, @px1, @py1 = draw_axes(@drawer, @gc, @name, @lx0, @lx1, @ly0, @ly1, X_axis_in_seconds, Show_all_axes) redraw end end if $with_gtk # Gtk's DRAW_AXES takes 3 required and 7 optional arguments. # draw_axes(wid, gc, label, # x0=0.0, x1=1.0, y0=-1.0, y1=1.0, # style=X_axis_in_seconds, # axes=Show_all_axes, # cairo) def draw_axes_cb cairo = make_cairo(@drawer) @px0, @py0, @px1, @py1 = draw_axes(@drawer, @gc, @name, @lx0, @lx1, @ly0, @ly1, X_axis_in_seconds, Show_all_axes, cairo) free_cairo(cairo) redraw end end def ungrfx(x) if @px0 == @px1 @x0 else [@x1, [@x0, @x0 + ((@x1 - @x0) * ((x - @px0) / (@px1.to_f - @px0)))].max].min end end def ungrfy(y) if @py0 == @py1 @y1 else [@y1, [@y0, @y0 + ((@y1 - @y0) * ((@py0 - y) / (@py0.to_f - @py1)))].max].min end end def grfx(x) if @px0 == @px1 @px0 else [@px1, [@px0, (@px0 + ((@px1 - @px0) * ((x - @x0) / (@x1.to_f - @x0)))).round].max].min end end def grfy(y) if @py0 == @py1 @py0 else [@py0, [@py1, (@py1 + ((@py0 - @py1) * ((y - @y1) / (@y0.to_f - @y1)))).round].max].min end end end end # xm-enved.rb ends here snd-16.1/libgsl.scm0000644000076400007640000056557612615716254012354 0ustar bilbil;;; libgsl.scm ;;; ;;; tie the gsl library into the *libgsl* environment (require cload.scm) (provide 'libgsl.scm) ;; if loading from a different directory, pass that info to C (let ((current-file (port-filename (current-input-port)))) (let ((directory (and (or (char=? (current-file 0) #\/) (char=? (current-file 0) #\~)) (substring current-file 0 (- (length current-file) 9))))) (when (and directory (not (member directory *load-path*))) (set! *load-path* (cons directory *load-path*))) (with-let (rootlet) (require cload.scm)) (when (and directory (not (string-position directory *cload-cflags*))) (set! *cload-cflags* (string-append "-I" directory " " *cload-cflags*))))) (when (provided? 'pure-s7) (define (make-polar mag ang) (if (and (real? mag) (real? ang)) (complex (* mag (cos ang)) (* mag (sin ang))) (error 'wrong-type-arg "make-polar args should be real")))) ;; since we might be loading this locally, reader-cond (in that case) won't find gsl-version unless... (if (not (defined? '*libgsl*)) (with-let (rootlet) (define gsl-version 0.0) ; define at top-level no matter where we are now (when (and (provided? 'linux) (defined? 'system)) (let ((version (system "pkg-config gsl --modversion" #t))) (if (positive? (length version)) (set! gsl-version (with-input-from-string version read))))))) (if (not (defined? '*libgsl*)) (define *libgsl* (with-let (unlet) (set! *libraries* (cons (cons "libgsl.scm" (curlet)) *libraries*)) (define GSL_REAL real-part) (define GSL_IMAG imag-part) (define GSL_COMPLEX_EQ equal?) (define GSL_COMPLEX_ONE 1.0) (define GSL_COMPLEX_ZERO 0.0) (define GSL_COMPLEX_NEGONE -1.0) (define gsl_complex_polar make-polar) (define gsl_complex_rect complex) (define GSL_IS_ODD odd?) (define GSL_IS_EVEN even?) (define (GSL_IS_REAL n) (and (number? n) (not (nan? n)) (not (infinite? n)))) (define (GSL_SIGN x) (if (negative? x) -1 1)) (define GSL_MAX max) (define GSL_MIN min) (define GSL_MAX_INT max) (define GSL_MIN_INT min) (define GSL_MAX_DBL max) (define GSL_MIN_DBL min) (define gsl_max max) (define gsl_min min) (c-define '((C-macro (double (GSL_CONST_CGS_SPEED_OF_LIGHT GSL_CONST_CGS_GRAVITATIONAL_CONSTANT GSL_CONST_CGS_PLANCKS_CONSTANT_H GSL_CONST_CGS_PLANCKS_CONSTANT_HBAR GSL_CONST_CGS_ASTRONOMICAL_UNIT GSL_CONST_CGS_LIGHT_YEAR GSL_CONST_CGS_PARSEC GSL_CONST_CGS_GRAV_ACCEL GSL_CONST_CGS_ELECTRON_VOLT GSL_CONST_CGS_MASS_ELECTRON GSL_CONST_CGS_MASS_MUON GSL_CONST_CGS_MASS_PROTON GSL_CONST_CGS_MASS_NEUTRON GSL_CONST_CGS_RYDBERG GSL_CONST_CGS_BOLTZMANN GSL_CONST_CGS_MOLAR_GAS GSL_CONST_CGS_STANDARD_GAS_VOLUME GSL_CONST_CGS_MINUTE GSL_CONST_CGS_HOUR GSL_CONST_CGS_DAY GSL_CONST_CGS_WEEK GSL_CONST_CGS_INCH GSL_CONST_CGS_FOOT GSL_CONST_CGS_YARD GSL_CONST_CGS_MILE GSL_CONST_CGS_NAUTICAL_MILE GSL_CONST_CGS_FATHOM GSL_CONST_CGS_MIL GSL_CONST_CGS_POINT GSL_CONST_CGS_TEXPOINT GSL_CONST_CGS_MICRON GSL_CONST_CGS_ANGSTROM GSL_CONST_CGS_HECTARE GSL_CONST_CGS_ACRE GSL_CONST_CGS_BARN GSL_CONST_CGS_LITER GSL_CONST_CGS_US_GALLON GSL_CONST_CGS_QUART GSL_CONST_CGS_PINT GSL_CONST_CGS_CUP GSL_CONST_CGS_FLUID_OUNCE GSL_CONST_CGS_TABLESPOON GSL_CONST_CGS_TEASPOON GSL_CONST_CGS_CANADIAN_GALLON GSL_CONST_CGS_UK_GALLON GSL_CONST_CGS_MILES_PER_HOUR GSL_CONST_CGS_KILOMETERS_PER_HOUR GSL_CONST_CGS_KNOT GSL_CONST_CGS_POUND_MASS GSL_CONST_CGS_OUNCE_MASS GSL_CONST_CGS_TON GSL_CONST_CGS_METRIC_TON GSL_CONST_CGS_UK_TON GSL_CONST_CGS_TROY_OUNCE GSL_CONST_CGS_CARAT GSL_CONST_CGS_UNIFIED_ATOMIC_MASS GSL_CONST_CGS_GRAM_FORCE GSL_CONST_CGS_POUND_FORCE GSL_CONST_CGS_KILOPOUND_FORCE GSL_CONST_CGS_POUNDAL GSL_CONST_CGS_CALORIE GSL_CONST_CGS_BTU GSL_CONST_CGS_THERM GSL_CONST_CGS_HORSEPOWER GSL_CONST_CGS_BAR GSL_CONST_CGS_STD_ATMOSPHERE GSL_CONST_CGS_TORR GSL_CONST_CGS_METER_OF_MERCURY GSL_CONST_CGS_INCH_OF_MERCURY GSL_CONST_CGS_INCH_OF_WATER GSL_CONST_CGS_PSI GSL_CONST_CGS_POISE GSL_CONST_CGS_STOKES GSL_CONST_CGS_STILB GSL_CONST_CGS_LUMEN GSL_CONST_CGS_LUX GSL_CONST_CGS_PHOT GSL_CONST_CGS_FOOTCANDLE GSL_CONST_CGS_LAMBERT GSL_CONST_CGS_FOOTLAMBERT GSL_CONST_CGS_CURIE GSL_CONST_CGS_ROENTGEN GSL_CONST_CGS_RAD GSL_CONST_CGS_SOLAR_MASS GSL_CONST_CGS_BOHR_RADIUS GSL_CONST_CGS_NEWTON GSL_CONST_CGS_DYNE GSL_CONST_CGS_JOULE GSL_CONST_CGS_ERG GSL_CONST_CGS_STEFAN_BOLTZMANN_CONSTANT GSL_CONST_CGS_THOMSON_CROSS_SECTION GSL_CONST_CGSM_SPEED_OF_LIGHT GSL_CONST_CGSM_GRAVITATIONAL_CONSTANT GSL_CONST_CGSM_PLANCKS_CONSTANT_H GSL_CONST_CGSM_PLANCKS_CONSTANT_HBAR GSL_CONST_CGSM_ASTRONOMICAL_UNIT GSL_CONST_CGSM_LIGHT_YEAR GSL_CONST_CGSM_PARSEC GSL_CONST_CGSM_GRAV_ACCEL GSL_CONST_CGSM_ELECTRON_VOLT GSL_CONST_CGSM_MASS_ELECTRON GSL_CONST_CGSM_MASS_MUON GSL_CONST_CGSM_MASS_PROTON GSL_CONST_CGSM_MASS_NEUTRON GSL_CONST_CGSM_RYDBERG GSL_CONST_CGSM_BOLTZMANN GSL_CONST_CGSM_MOLAR_GAS GSL_CONST_CGSM_STANDARD_GAS_VOLUME GSL_CONST_CGSM_MINUTE GSL_CONST_CGSM_HOUR GSL_CONST_CGSM_DAY GSL_CONST_CGSM_WEEK GSL_CONST_CGSM_INCH GSL_CONST_CGSM_FOOT GSL_CONST_CGSM_YARD GSL_CONST_CGSM_MILE GSL_CONST_CGSM_NAUTICAL_MILE GSL_CONST_CGSM_FATHOM GSL_CONST_CGSM_MIL GSL_CONST_CGSM_POINT GSL_CONST_CGSM_TEXPOINT GSL_CONST_CGSM_MICRON GSL_CONST_CGSM_ANGSTROM GSL_CONST_CGSM_HECTARE GSL_CONST_CGSM_ACRE GSL_CONST_CGSM_BARN GSL_CONST_CGSM_LITER GSL_CONST_CGSM_US_GALLON GSL_CONST_CGSM_QUART GSL_CONST_CGSM_PINT GSL_CONST_CGSM_CUP GSL_CONST_CGSM_FLUID_OUNCE GSL_CONST_CGSM_TABLESPOON GSL_CONST_CGSM_TEASPOON GSL_CONST_CGSM_CANADIAN_GALLON GSL_CONST_CGSM_UK_GALLON GSL_CONST_CGSM_MILES_PER_HOUR GSL_CONST_CGSM_KILOMETERS_PER_HOUR GSL_CONST_CGSM_KNOT GSL_CONST_CGSM_POUND_MASS GSL_CONST_CGSM_OUNCE_MASS GSL_CONST_CGSM_TON GSL_CONST_CGSM_METRIC_TON GSL_CONST_CGSM_UK_TON GSL_CONST_CGSM_TROY_OUNCE GSL_CONST_CGSM_CARAT GSL_CONST_CGSM_UNIFIED_ATOMIC_MASS GSL_CONST_CGSM_GRAM_FORCE GSL_CONST_CGSM_POUND_FORCE GSL_CONST_CGSM_KILOPOUND_FORCE GSL_CONST_CGSM_POUNDAL GSL_CONST_CGSM_CALORIE GSL_CONST_CGSM_BTU GSL_CONST_CGSM_THERM GSL_CONST_CGSM_HORSEPOWER GSL_CONST_CGSM_BAR GSL_CONST_CGSM_STD_ATMOSPHERE GSL_CONST_CGSM_TORR GSL_CONST_CGSM_METER_OF_MERCURY GSL_CONST_CGSM_INCH_OF_MERCURY GSL_CONST_CGSM_INCH_OF_WATER GSL_CONST_CGSM_PSI GSL_CONST_CGSM_POISE GSL_CONST_CGSM_STOKES GSL_CONST_CGSM_STILB GSL_CONST_CGSM_LUMEN GSL_CONST_CGSM_LUX GSL_CONST_CGSM_PHOT GSL_CONST_CGSM_FOOTCANDLE GSL_CONST_CGSM_LAMBERT GSL_CONST_CGSM_FOOTLAMBERT GSL_CONST_CGSM_CURIE GSL_CONST_CGSM_ROENTGEN GSL_CONST_CGSM_RAD GSL_CONST_CGSM_SOLAR_MASS GSL_CONST_CGSM_BOHR_RADIUS GSL_CONST_CGSM_NEWTON GSL_CONST_CGSM_DYNE GSL_CONST_CGSM_JOULE GSL_CONST_CGSM_ERG GSL_CONST_CGSM_STEFAN_BOLTZMANN_CONSTANT GSL_CONST_CGSM_THOMSON_CROSS_SECTION GSL_CONST_CGSM_BOHR_MAGNETON GSL_CONST_CGSM_NUCLEAR_MAGNETON GSL_CONST_CGSM_ELECTRON_MAGNETIC_MOMENT GSL_CONST_CGSM_PROTON_MAGNETIC_MOMENT GSL_CONST_CGSM_FARADAY GSL_CONST_CGSM_ELECTRON_CHARGE GSL_CONST_MKS_SPEED_OF_LIGHT GSL_CONST_MKS_GRAVITATIONAL_CONSTANT GSL_CONST_MKS_PLANCKS_CONSTANT_H GSL_CONST_MKS_PLANCKS_CONSTANT_HBAR GSL_CONST_MKS_ASTRONOMICAL_UNIT GSL_CONST_MKS_LIGHT_YEAR GSL_CONST_MKS_PARSEC GSL_CONST_MKS_GRAV_ACCEL GSL_CONST_MKS_ELECTRON_VOLT GSL_CONST_MKS_MASS_ELECTRON GSL_CONST_MKS_MASS_MUON GSL_CONST_MKS_MASS_PROTON GSL_CONST_MKS_MASS_NEUTRON GSL_CONST_MKS_RYDBERG GSL_CONST_MKS_BOLTZMANN GSL_CONST_MKS_MOLAR_GAS GSL_CONST_MKS_STANDARD_GAS_VOLUME GSL_CONST_MKS_MINUTE GSL_CONST_MKS_HOUR GSL_CONST_MKS_DAY GSL_CONST_MKS_WEEK GSL_CONST_MKS_INCH GSL_CONST_MKS_FOOT GSL_CONST_MKS_YARD GSL_CONST_MKS_MILE GSL_CONST_MKS_NAUTICAL_MILE GSL_CONST_MKS_FATHOM GSL_CONST_MKS_MIL GSL_CONST_MKS_POINT GSL_CONST_MKS_TEXPOINT GSL_CONST_MKS_MICRON GSL_CONST_MKS_ANGSTROM GSL_CONST_MKS_HECTARE GSL_CONST_MKS_ACRE GSL_CONST_MKS_BARN GSL_CONST_MKS_LITER GSL_CONST_MKS_US_GALLON GSL_CONST_MKS_QUART GSL_CONST_MKS_PINT GSL_CONST_MKS_CUP GSL_CONST_MKS_FLUID_OUNCE GSL_CONST_MKS_TABLESPOON GSL_CONST_MKS_TEASPOON GSL_CONST_MKS_CANADIAN_GALLON GSL_CONST_MKS_UK_GALLON GSL_CONST_MKS_MILES_PER_HOUR GSL_CONST_MKS_KILOMETERS_PER_HOUR GSL_CONST_MKS_KNOT GSL_CONST_MKS_POUND_MASS GSL_CONST_MKS_OUNCE_MASS GSL_CONST_MKS_TON GSL_CONST_MKS_METRIC_TON GSL_CONST_MKS_UK_TON GSL_CONST_MKS_TROY_OUNCE GSL_CONST_MKS_CARAT GSL_CONST_MKS_UNIFIED_ATOMIC_MASS GSL_CONST_MKS_GRAM_FORCE GSL_CONST_MKS_POUND_FORCE GSL_CONST_MKS_KILOPOUND_FORCE GSL_CONST_MKS_POUNDAL GSL_CONST_MKS_CALORIE GSL_CONST_MKS_BTU GSL_CONST_MKS_THERM GSL_CONST_MKS_HORSEPOWER GSL_CONST_MKS_BAR GSL_CONST_MKS_STD_ATMOSPHERE GSL_CONST_MKS_TORR GSL_CONST_MKS_METER_OF_MERCURY GSL_CONST_MKS_INCH_OF_MERCURY GSL_CONST_MKS_INCH_OF_WATER GSL_CONST_MKS_PSI GSL_CONST_MKS_POISE GSL_CONST_MKS_STOKES GSL_CONST_MKS_STILB GSL_CONST_MKS_LUMEN GSL_CONST_MKS_LUX GSL_CONST_MKS_PHOT GSL_CONST_MKS_FOOTCANDLE GSL_CONST_MKS_LAMBERT GSL_CONST_MKS_FOOTLAMBERT GSL_CONST_MKS_CURIE GSL_CONST_MKS_ROENTGEN GSL_CONST_MKS_RAD GSL_CONST_MKS_SOLAR_MASS GSL_CONST_MKS_BOHR_RADIUS GSL_CONST_MKS_NEWTON GSL_CONST_MKS_DYNE GSL_CONST_MKS_JOULE GSL_CONST_MKS_ERG GSL_CONST_MKS_STEFAN_BOLTZMANN_CONSTANT GSL_CONST_MKS_THOMSON_CROSS_SECTION GSL_CONST_MKS_BOHR_MAGNETON GSL_CONST_MKS_NUCLEAR_MAGNETON GSL_CONST_MKS_ELECTRON_MAGNETIC_MOMENT GSL_CONST_MKS_PROTON_MAGNETIC_MOMENT GSL_CONST_MKS_FARADAY GSL_CONST_MKS_ELECTRON_CHARGE GSL_CONST_MKS_VACUUM_PERMITTIVITY GSL_CONST_MKS_VACUUM_PERMEABILITY GSL_CONST_MKS_DEBYE GSL_CONST_MKS_GAUSS GSL_CONST_MKSA_SPEED_OF_LIGHT GSL_CONST_MKSA_GRAVITATIONAL_CONSTANT GSL_CONST_MKSA_PLANCKS_CONSTANT_H GSL_CONST_MKSA_PLANCKS_CONSTANT_HBAR GSL_CONST_MKSA_ASTRONOMICAL_UNIT GSL_CONST_MKSA_LIGHT_YEAR GSL_CONST_MKSA_PARSEC GSL_CONST_MKSA_GRAV_ACCEL GSL_CONST_MKSA_ELECTRON_VOLT GSL_CONST_MKSA_MASS_ELECTRON GSL_CONST_MKSA_MASS_MUON GSL_CONST_MKSA_MASS_PROTON GSL_CONST_MKSA_MASS_NEUTRON GSL_CONST_MKSA_RYDBERG GSL_CONST_MKSA_BOLTZMANN GSL_CONST_MKSA_MOLAR_GAS GSL_CONST_MKSA_STANDARD_GAS_VOLUME GSL_CONST_MKSA_MINUTE GSL_CONST_MKSA_HOUR GSL_CONST_MKSA_DAY GSL_CONST_MKSA_WEEK GSL_CONST_MKSA_INCH GSL_CONST_MKSA_FOOT GSL_CONST_MKSA_YARD GSL_CONST_MKSA_MILE GSL_CONST_MKSA_NAUTICAL_MILE GSL_CONST_MKSA_FATHOM GSL_CONST_MKSA_MIL GSL_CONST_MKSA_POINT GSL_CONST_MKSA_TEXPOINT GSL_CONST_MKSA_MICRON GSL_CONST_MKSA_ANGSTROM GSL_CONST_MKSA_HECTARE GSL_CONST_MKSA_ACRE GSL_CONST_MKSA_BARN GSL_CONST_MKSA_LITER GSL_CONST_MKSA_US_GALLON GSL_CONST_MKSA_QUART GSL_CONST_MKSA_PINT GSL_CONST_MKSA_CUP GSL_CONST_MKSA_FLUID_OUNCE GSL_CONST_MKSA_TABLESPOON GSL_CONST_MKSA_TEASPOON GSL_CONST_MKSA_CANADIAN_GALLON GSL_CONST_MKSA_UK_GALLON GSL_CONST_MKSA_MILES_PER_HOUR GSL_CONST_MKSA_KILOMETERS_PER_HOUR GSL_CONST_MKSA_KNOT GSL_CONST_MKSA_POUND_MASS GSL_CONST_MKSA_OUNCE_MASS GSL_CONST_MKSA_TON GSL_CONST_MKSA_METRIC_TON GSL_CONST_MKSA_UK_TON GSL_CONST_MKSA_TROY_OUNCE GSL_CONST_MKSA_CARAT GSL_CONST_MKSA_UNIFIED_ATOMIC_MASS GSL_CONST_MKSA_GRAM_FORCE GSL_CONST_MKSA_POUND_FORCE GSL_CONST_MKSA_KILOPOUND_FORCE GSL_CONST_MKSA_POUNDAL GSL_CONST_MKSA_CALORIE GSL_CONST_MKSA_BTU GSL_CONST_MKSA_THERM GSL_CONST_MKSA_HORSEPOWER GSL_CONST_MKSA_BAR GSL_CONST_MKSA_STD_ATMOSPHERE GSL_CONST_MKSA_TORR GSL_CONST_MKSA_METER_OF_MERCURY GSL_CONST_MKSA_INCH_OF_MERCURY GSL_CONST_MKSA_INCH_OF_WATER GSL_CONST_MKSA_PSI GSL_CONST_MKSA_POISE GSL_CONST_MKSA_STOKES GSL_CONST_MKSA_STILB GSL_CONST_MKSA_LUMEN GSL_CONST_MKSA_LUX GSL_CONST_MKSA_PHOT GSL_CONST_MKSA_FOOTCANDLE GSL_CONST_MKSA_LAMBERT GSL_CONST_MKSA_FOOTLAMBERT GSL_CONST_MKSA_CURIE GSL_CONST_MKSA_ROENTGEN GSL_CONST_MKSA_RAD GSL_CONST_MKSA_SOLAR_MASS GSL_CONST_MKSA_BOHR_RADIUS GSL_CONST_MKSA_NEWTON GSL_CONST_MKSA_DYNE GSL_CONST_MKSA_JOULE GSL_CONST_MKSA_ERG GSL_CONST_MKSA_STEFAN_BOLTZMANN_CONSTANT GSL_CONST_MKSA_THOMSON_CROSS_SECTION GSL_CONST_MKSA_BOHR_MAGNETON GSL_CONST_MKSA_NUCLEAR_MAGNETON GSL_CONST_MKSA_ELECTRON_MAGNETIC_MOMENT GSL_CONST_MKSA_PROTON_MAGNETIC_MOMENT GSL_CONST_MKSA_FARADAY GSL_CONST_MKSA_ELECTRON_CHARGE GSL_CONST_MKSA_VACUUM_PERMITTIVITY GSL_CONST_MKSA_VACUUM_PERMEABILITY GSL_CONST_MKSA_DEBYE GSL_CONST_MKSA_GAUSS GSL_CONST_NUM_FINE_STRUCTURE GSL_CONST_NUM_AVOGADRO GSL_CONST_NUM_YOTTA GSL_CONST_NUM_ZETTA GSL_CONST_NUM_EXA GSL_CONST_NUM_PETA GSL_CONST_NUM_TERA GSL_CONST_NUM_GIGA GSL_CONST_NUM_MEGA GSL_CONST_NUM_KILO GSL_CONST_NUM_MILLI GSL_CONST_NUM_MICRO GSL_CONST_NUM_NANO GSL_CONST_NUM_PICO GSL_CONST_NUM_FEMTO GSL_CONST_NUM_ATTO GSL_CONST_NUM_ZEPTO GSL_CONST_NUM_YOCTO GSL_DBL_EPSILON GSL_SQRT_DBL_EPSILON GSL_ROOT3_DBL_EPSILON GSL_ROOT4_DBL_EPSILON GSL_ROOT5_DBL_EPSILON GSL_ROOT6_DBL_EPSILON GSL_LOG_DBL_EPSILON GSL_DBL_MIN GSL_SQRT_DBL_MIN GSL_ROOT3_DBL_MIN GSL_ROOT4_DBL_MIN GSL_ROOT5_DBL_MIN GSL_ROOT6_DBL_MIN GSL_LOG_DBL_MIN GSL_DBL_MAX GSL_SQRT_DBL_MAX GSL_ROOT3_DBL_MAX GSL_ROOT4_DBL_MAX GSL_ROOT5_DBL_MAX GSL_ROOT6_DBL_MAX GSL_LOG_DBL_MAX GSL_FLT_EPSILON GSL_SQRT_FLT_EPSILON GSL_ROOT3_FLT_EPSILON GSL_ROOT4_FLT_EPSILON GSL_ROOT5_FLT_EPSILON GSL_ROOT6_FLT_EPSILON GSL_LOG_FLT_EPSILON GSL_FLT_MIN GSL_SQRT_FLT_MIN GSL_ROOT3_FLT_MIN GSL_ROOT4_FLT_MIN GSL_ROOT5_FLT_MIN GSL_ROOT6_FLT_MIN GSL_LOG_FLT_MIN GSL_FLT_MAX GSL_SQRT_FLT_MAX GSL_ROOT3_FLT_MAX GSL_ROOT4_FLT_MAX GSL_ROOT5_FLT_MAX GSL_ROOT6_FLT_MAX GSL_LOG_FLT_MAX GSL_SFLT_EPSILON GSL_SQRT_SFLT_EPSILON GSL_ROOT3_SFLT_EPSILON GSL_ROOT4_SFLT_EPSILON GSL_ROOT5_SFLT_EPSILON GSL_ROOT6_SFLT_EPSILON GSL_LOG_SFLT_EPSILON GSL_MACH_EPS GSL_SQRT_MACH_EPS GSL_ROOT3_MACH_EPS GSL_ROOT4_MACH_EPS GSL_ROOT5_MACH_EPS GSL_ROOT6_MACH_EPS GSL_LOG_MACH_EPS))) (int (GSL_SUCCESS GSL_FAILURE GSL_CONTINUE GSL_EDOM GSL_ERANGE GSL_EFAULT GSL_EINVAL GSL_EFAILED GSL_EFACTOR GSL_ESANITY GSL_ENOMEM GSL_EBADFUNC GSL_ERUNAWAY GSL_EMAXITER GSL_EZERODIV GSL_EBADTOL GSL_ETOL GSL_EUNDRFLW GSL_EOVRFLW GSL_ELOSS GSL_EROUND GSL_EBADLEN GSL_ENOTSQR GSL_ESING GSL_EDIVERGE GSL_EUNSUP GSL_EUNIMPL GSL_ECACHE GSL_ETABLE GSL_ENOPROG GSL_ENOPROGJ GSL_ETOLF GSL_ETOLX GSL_ETOLG GSL_EOF GSL_IEEE_ROUND_TO_NEAREST GSL_IEEE_ROUND_DOWN GSL_IEEE_ROUND_UP GSL_IEEE_ROUND_TO_ZERO GSL_IEEE_MASK_INVALID GSL_IEEE_MASK_DENORMALIZED GSL_IEEE_MASK_DIVISION_BY_ZERO GSL_IEEE_MASK_OVERFLOW GSL_IEEE_MASK_UNDERFLOW GSL_IEEE_MASK_ALL GSL_IEEE_TRAP_INEXACT GSL_INTEG_GAUSS15 GSL_INTEG_GAUSS21 GSL_INTEG_GAUSS31 GSL_INTEG_GAUSS41 GSL_INTEG_GAUSS51 GSL_INTEG_GAUSS61 GSL_EIGEN_SORT_VAL_ASC GSL_EIGEN_SORT_VAL_DESC GSL_EIGEN_SORT_ABS_ASC GSL_EIGEN_SORT_ABS_DESC gsl_fft_forward gsl_fft_backward GSL_IEEE_TYPE_NAN GSL_IEEE_TYPE_INF GSL_IEEE_TYPE_NORMAL GSL_IEEE_TYPE_DENORMAL GSL_IEEE_TYPE_ZERO GSL_IEEE_SINGLE_PRECISION GSL_IEEE_DOUBLE_PRECISION GSL_IEEE_EXTENDED_PRECISION GSL_LINALG_MOD_NONE GSL_LINALG_MOD_TRANSPOSE GSL_LINALG_MOD_CONJUGATE GSL_MESSAGE_MASK_A GSL_MESSAGE_MASK_B GSL_MESSAGE_MASK_C GSL_MESSAGE_MASK_D GSL_MESSAGE_MASK_E GSL_MESSAGE_MASK_F GSL_MESSAGE_MASK_G GSL_MESSAGE_MASK_H gsl_wavelet_forward gsl_wavelet_backward)) (C-macro (int (GSL_PREC_DOUBLE GSL_PREC_SINGLE GSL_PREC_APPROX GSL_SF_MATHIEU_COEFF GSL_SF_FACT_NMAX GSL_SF_DOUBLEFACT_NMAX GSL_MAJOR_VERSION GSL_MINOR_VERSION GSL_MODE_DEFAULT GSL_INTEG_COSINE GSL_INTEG_SINE))) (C-macro (double (GSL_SF_GAMMA_XMAX GSL_POSINF GSL_NEGINF GSL_NAN GSL_POSZERO GSL_NEGZERO))) (C-macro (char* GSL_VERSION)) (int (CblasRowMajor CblasColMajor CblasNoTrans CblasTrans CblasConjTrans CblasUpper CblasLower CblasNonUnit CblasUnit CblasLeft CblasRight)) ;; redirect GSL errors to s7_error (in-C "static s7_scheme *gsl_error_s7; static void g_gsl_error(const char *reason, const char *file, int line, int gsl_errno) { s7_error(gsl_error_s7, s7_make_symbol(gsl_error_s7, \"gsl-error\"), s7_list(gsl_error_s7, 5, s7_make_string(gsl_error_s7, \"GSL: ~A, ~A in ~A line ~A\"), s7_make_string(gsl_error_s7, gsl_strerror(gsl_errno)), s7_make_string(gsl_error_s7, reason), s7_make_string(gsl_error_s7, file), s7_make_integer(gsl_error_s7, line))); }") (C-init "gsl_error_s7 = sc;") (C-init "gsl_set_error_handler(g_gsl_error);") (C-macro (int (GSL_SF_LEGENDRE_SCHMIDT GSL_SF_LEGENDRE_SPHARM GSL_SF_LEGENDRE_FULL GSL_SF_LEGENDRE_NONE))) ;; special functions ;; ((*libgsl* 'gsl_sf_bessel_J0) 1.0) -> 0.7651976865579666 ;; (let ((sfr ((*libgsl* 'gsl_sf_result.make)))) ((*libgsl* 'gsl_sf_bessel_J0_e) 1.0 sfr) ((*libgsl* 'gsl_sf_result.val) sfr)) (int gsl_sf_airy_Ai_e (double int gsl_sf_result*)) (double gsl_sf_airy_Ai (double int)) (int gsl_sf_airy_Bi_e (double int gsl_sf_result*)) (double gsl_sf_airy_Bi (double int)) (int gsl_sf_airy_Ai_scaled_e (double int gsl_sf_result*)) (double gsl_sf_airy_Ai_scaled (double int)) (int gsl_sf_airy_Bi_scaled_e (double int gsl_sf_result*)) (double gsl_sf_airy_Bi_scaled (double int)) (int gsl_sf_airy_Ai_deriv_e (double int gsl_sf_result*)) (double gsl_sf_airy_Ai_deriv (double int)) (int gsl_sf_airy_Bi_deriv_e (double int gsl_sf_result*)) (double gsl_sf_airy_Bi_deriv (double int)) (int gsl_sf_airy_Ai_deriv_scaled_e (double int gsl_sf_result*)) (double gsl_sf_airy_Ai_deriv_scaled (double int)) (int gsl_sf_airy_Bi_deriv_scaled_e (double int gsl_sf_result*)) (double gsl_sf_airy_Bi_deriv_scaled (double int)) (int gsl_sf_airy_zero_Ai_e (int gsl_sf_result*)) (double gsl_sf_airy_zero_Ai (int)) (int gsl_sf_airy_zero_Bi_e (int gsl_sf_result*)) (double gsl_sf_airy_zero_Bi (int)) (int gsl_sf_airy_zero_Ai_deriv_e (int gsl_sf_result*)) (double gsl_sf_airy_zero_Ai_deriv (int)) (int gsl_sf_airy_zero_Bi_deriv_e (int gsl_sf_result*)) (double gsl_sf_airy_zero_Bi_deriv (int)) (int gsl_sf_bessel_J0_e (double gsl_sf_result*)) (double gsl_sf_bessel_J0 (double)) (int gsl_sf_bessel_J1_e (double gsl_sf_result*)) (double gsl_sf_bessel_J1 (double)) (int gsl_sf_bessel_Jn_e (int double gsl_sf_result*)) (double gsl_sf_bessel_Jn (int double)) (int gsl_sf_bessel_Jn_array (int int double double*)) (int gsl_sf_bessel_Y0_e (double gsl_sf_result*)) (double gsl_sf_bessel_Y0 (double)) (int gsl_sf_bessel_Y1_e (double gsl_sf_result*)) (double gsl_sf_bessel_Y1 (double)) (int gsl_sf_bessel_Yn_e (int double gsl_sf_result*)) (double gsl_sf_bessel_Yn (int double)) (int gsl_sf_bessel_Yn_array (int int double double*)) (int gsl_sf_bessel_I0_e (double gsl_sf_result*)) (double gsl_sf_bessel_I0 (double)) (int gsl_sf_bessel_I1_e (double gsl_sf_result*)) (double gsl_sf_bessel_I1 (double)) (int gsl_sf_bessel_In_e (int double gsl_sf_result*)) (double gsl_sf_bessel_In (int double)) (int gsl_sf_bessel_In_array (int int double double*)) (int gsl_sf_bessel_I0_scaled_e (double gsl_sf_result*)) (double gsl_sf_bessel_I0_scaled (double)) (int gsl_sf_bessel_I1_scaled_e (double gsl_sf_result*)) (double gsl_sf_bessel_I1_scaled (double)) (int gsl_sf_bessel_In_scaled_e (int double gsl_sf_result*)) (double gsl_sf_bessel_In_scaled (int double)) (int gsl_sf_bessel_In_scaled_array (int int double double*)) (int gsl_sf_bessel_K0_e (double gsl_sf_result*)) (double gsl_sf_bessel_K0 (double)) (int gsl_sf_bessel_K1_e (double gsl_sf_result*)) (double gsl_sf_bessel_K1 (double)) (int gsl_sf_bessel_Kn_e (int double gsl_sf_result*)) (double gsl_sf_bessel_Kn (int double)) (int gsl_sf_bessel_Kn_array (int int double double*)) (int gsl_sf_bessel_K0_scaled_e (double gsl_sf_result*)) (double gsl_sf_bessel_K0_scaled (double)) (int gsl_sf_bessel_K1_scaled_e (double gsl_sf_result*) ) (double gsl_sf_bessel_K1_scaled (double)) (int gsl_sf_bessel_Kn_scaled_e (int double gsl_sf_result*)) (double gsl_sf_bessel_Kn_scaled (int double)) (int gsl_sf_bessel_Kn_scaled_array (int int double double*)) (int gsl_sf_bessel_j0_e (double gsl_sf_result*)) (double gsl_sf_bessel_j0 (double)) (int gsl_sf_bessel_j1_e (double gsl_sf_result*)) (double gsl_sf_bessel_j1 (double)) (int gsl_sf_bessel_j2_e (double gsl_sf_result*)) (double gsl_sf_bessel_j2 (double)) (int gsl_sf_bessel_jl_e (int double gsl_sf_result*)) (double gsl_sf_bessel_jl (int double)) (int gsl_sf_bessel_jl_array (int double double*)) (int gsl_sf_bessel_jl_steed_array (int double double*)) (int gsl_sf_bessel_y0_e (double gsl_sf_result*)) (double gsl_sf_bessel_y0 (double)) (int gsl_sf_bessel_y1_e (double gsl_sf_result*)) (double gsl_sf_bessel_y1 (double)) (int gsl_sf_bessel_y2_e (double gsl_sf_result*)) (double gsl_sf_bessel_y2 (double)) (int gsl_sf_bessel_yl_e (int double gsl_sf_result*)) (double gsl_sf_bessel_yl (int double)) (int gsl_sf_bessel_yl_array (int double double*)) (int gsl_sf_bessel_i0_scaled_e (double gsl_sf_result*)) (double gsl_sf_bessel_i0_scaled (double)) (int gsl_sf_bessel_i1_scaled_e (double gsl_sf_result*)) (double gsl_sf_bessel_i1_scaled (double)) (int gsl_sf_bessel_i2_scaled_e (double gsl_sf_result*)) (double gsl_sf_bessel_i2_scaled (double)) (int gsl_sf_bessel_il_scaled_e (int double gsl_sf_result*)) (double gsl_sf_bessel_il_scaled (int double)) (int gsl_sf_bessel_il_scaled_array (int double double*)) (int gsl_sf_bessel_k0_scaled_e (double gsl_sf_result*)) (double gsl_sf_bessel_k0_scaled (double)) (int gsl_sf_bessel_k1_scaled_e (double gsl_sf_result*)) (double gsl_sf_bessel_k1_scaled (double)) (int gsl_sf_bessel_k2_scaled_e (double gsl_sf_result*)) (double gsl_sf_bessel_k2_scaled (double)) (int gsl_sf_bessel_kl_scaled_e (int double gsl_sf_result*)) (double gsl_sf_bessel_kl_scaled (int double)) (int gsl_sf_bessel_kl_scaled_array (int double double*)) (int gsl_sf_bessel_Jnu_e (double double gsl_sf_result*)) (double gsl_sf_bessel_Jnu (double double)) (int gsl_sf_bessel_Ynu_e (double double gsl_sf_result*)) (double gsl_sf_bessel_Ynu (double double)) (int gsl_sf_bessel_sequence_Jnu_e (double int size_t double*)) (int gsl_sf_bessel_Inu_scaled_e (double double gsl_sf_result*)) (double gsl_sf_bessel_Inu_scaled (double double)) (int gsl_sf_bessel_Inu_e (double double gsl_sf_result*)) (double gsl_sf_bessel_Inu (double double)) (int gsl_sf_bessel_Knu_scaled_e (double double gsl_sf_result*)) (double gsl_sf_bessel_Knu_scaled (double double)) (reader-cond ((>= gsl-version 1.15) (int gsl_sf_bessel_Knu_scaled_e10_e (double double gsl_sf_result_e10*)))) (int gsl_sf_bessel_Knu_e (double double gsl_sf_result*)) (double gsl_sf_bessel_Knu (double double)) (int gsl_sf_bessel_lnKnu_e (double double gsl_sf_result*)) (double gsl_sf_bessel_lnKnu (double double)) (int gsl_sf_bessel_zero_J0_e (int gsl_sf_result*)) (double gsl_sf_bessel_zero_J0 (int)) (int gsl_sf_bessel_zero_J1_e (int gsl_sf_result*)) (double gsl_sf_bessel_zero_J1 (int)) (int gsl_sf_bessel_zero_Jnu_e (double int gsl_sf_result*)) (double gsl_sf_bessel_zero_Jnu (double int)) (int gsl_sf_clausen_e (double gsl_sf_result*)) (double gsl_sf_clausen (double)) (int gsl_sf_hydrogenicR_1_e (double double gsl_sf_result*)) (double gsl_sf_hydrogenicR_1 (double double)) (int gsl_sf_hydrogenicR_e (int int double double gsl_sf_result*)) (double gsl_sf_hydrogenicR (int int double double)) (int gsl_sf_coulomb_wave_FG_e (double double double int gsl_sf_result* gsl_sf_result* gsl_sf_result* gsl_sf_result* double* double*)) (int gsl_sf_coulomb_wave_F_array (double int double double double* double*)) (int gsl_sf_coulomb_wave_FG_array (double int double double double* double* double* double*)) (int gsl_sf_coulomb_wave_FGp_array (double int double double double* double* double* double* double* double*)) (int gsl_sf_coulomb_wave_sphF_array (double int double double double* double*)) (int gsl_sf_coulomb_CL_e (double double gsl_sf_result*)) (int gsl_sf_coulomb_CL_array (double int double double*)) (int gsl_sf_coupling_3j_e (int int int int int int gsl_sf_result*)) (double gsl_sf_coupling_3j (int int int int int int)) (int gsl_sf_coupling_6j_e (int int int int int int gsl_sf_result*)) (double gsl_sf_coupling_6j (int int int int int int)) (int gsl_sf_coupling_RacahW_e (int int int int int int gsl_sf_result*)) (double gsl_sf_coupling_RacahW (int int int int int int)) (int gsl_sf_coupling_9j_e (int int int int int int int int int gsl_sf_result*)) (double gsl_sf_coupling_9j (int int int int int int int int int)) (int gsl_sf_dawson_e (double gsl_sf_result*)) (double gsl_sf_dawson (double)) (int gsl_sf_debye_1_e (double gsl_sf_result*)) (double gsl_sf_debye_1 (double)) (int gsl_sf_debye_2_e (double gsl_sf_result*)) (double gsl_sf_debye_2 (double)) (int gsl_sf_debye_3_e (double gsl_sf_result*)) (double gsl_sf_debye_3 (double)) (int gsl_sf_debye_4_e (double gsl_sf_result*)) (double gsl_sf_debye_4 (double)) (int gsl_sf_debye_5_e (double gsl_sf_result*)) (double gsl_sf_debye_5 (double)) (int gsl_sf_debye_6_e (double gsl_sf_result*)) (double gsl_sf_debye_6 (double)) (int gsl_sf_dilog_e (double gsl_sf_result*)) (double gsl_sf_dilog (double)) (int gsl_sf_complex_dilog_xy_e (double double gsl_sf_result* gsl_sf_result*)) (int gsl_sf_complex_dilog_e (double double gsl_sf_result* gsl_sf_result*)) (int gsl_sf_complex_spence_xy_e (double double gsl_sf_result* gsl_sf_result*)) (int gsl_sf_multiply_e (double double gsl_sf_result*)) (double gsl_sf_multiply (double double)) (int gsl_sf_multiply_err_e (double double double double gsl_sf_result*)) (int gsl_sf_ellint_Kcomp_e (double int gsl_sf_result*)) (double gsl_sf_ellint_Kcomp (double int)) (int gsl_sf_ellint_Ecomp_e (double int gsl_sf_result*)) (double gsl_sf_ellint_Ecomp (double int)) (int gsl_sf_ellint_Pcomp_e (double double int gsl_sf_result*)) (double gsl_sf_ellint_Pcomp (double double int)) (int gsl_sf_ellint_Dcomp_e (double int gsl_sf_result*)) (double gsl_sf_ellint_Dcomp (double int)) (int gsl_sf_ellint_F_e (double double int gsl_sf_result*)) (double gsl_sf_ellint_F (double double int)) (int gsl_sf_ellint_E_e (double double int gsl_sf_result*)) (double gsl_sf_ellint_E (double double int)) (int gsl_sf_ellint_P_e (double double double int gsl_sf_result*)) (double gsl_sf_ellint_P (double double double int)) (reader-cond ((< gsl-version 2.0) (int gsl_sf_ellint_D_e (double double double int gsl_sf_result*)) (double gsl_sf_ellint_D (double double double int))) (#t (int gsl_sf_ellint_D_e (double double int gsl_sf_result*)) (double gsl_sf_ellint_D (double double int)))) (int gsl_sf_ellint_RC_e (double double int gsl_sf_result*)) (double gsl_sf_ellint_RC (double double int)) (int gsl_sf_ellint_RD_e (double double double int gsl_sf_result*)) (double gsl_sf_ellint_RD (double double double int)) (int gsl_sf_ellint_RF_e (double double double int gsl_sf_result*)) (double gsl_sf_ellint_RF (double double double int)) (int gsl_sf_ellint_RJ_e (double double double double int gsl_sf_result*)) (double gsl_sf_ellint_RJ (double double double double int)) (int gsl_sf_elljac_e (double double double* double* double*)) ; these are double by reference (int gsl_sf_erfc_e (double gsl_sf_result*)) (double gsl_sf_erfc (double)) (int gsl_sf_log_erfc_e (double gsl_sf_result*)) (double gsl_sf_log_erfc (double)) (int gsl_sf_erf_e (double gsl_sf_result*)) (double gsl_sf_erf (double)) (int gsl_sf_erf_Z_e (double gsl_sf_result*)) (int gsl_sf_erf_Q_e (double gsl_sf_result*)) (double gsl_sf_erf_Z (double)) (double gsl_sf_erf_Q (double)) (int gsl_sf_hazard_e (double gsl_sf_result*)) (double gsl_sf_hazard (double)) (int gsl_sf_exp_e (double gsl_sf_result*)) (double gsl_sf_exp (double)) (int gsl_sf_exp_e10_e (double gsl_sf_result_e10*)) (int gsl_sf_exp_mult_e (double double gsl_sf_result*)) (double gsl_sf_exp_mult (double double)) (int gsl_sf_exp_mult_e10_e (double double gsl_sf_result_e10*)) (int gsl_sf_expm1_e (double gsl_sf_result*)) (double gsl_sf_expm1 (double)) (int gsl_sf_exprel_e (double gsl_sf_result*)) (double gsl_sf_exprel (double)) (int gsl_sf_exprel_2_e (double gsl_sf_result*)) (double gsl_sf_exprel_2 (double)) (int gsl_sf_exprel_n_e (int double gsl_sf_result*)) (double gsl_sf_exprel_n (int double)) (int gsl_sf_exprel_n_CF_e (double double gsl_sf_result*)) (int gsl_sf_exp_err_e (double double gsl_sf_result*)) (int gsl_sf_exp_err_e10_e (double double gsl_sf_result_e10*)) (int gsl_sf_exp_mult_err_e (double double double double gsl_sf_result*)) (int gsl_sf_exp_mult_err_e10_e (double double double double gsl_sf_result_e10*)) (int gsl_sf_expint_E1_e (double gsl_sf_result*)) (double gsl_sf_expint_E1 (double)) (int gsl_sf_expint_E2_e (double gsl_sf_result*)) (double gsl_sf_expint_E2 (double)) (int gsl_sf_expint_En_e (int double gsl_sf_result*)) (double gsl_sf_expint_En (int double)) (int gsl_sf_expint_E1_scaled_e (double gsl_sf_result*)) (double gsl_sf_expint_E1_scaled (double)) (int gsl_sf_expint_E2_scaled_e (double gsl_sf_result*)) (double gsl_sf_expint_E2_scaled (double)) (int gsl_sf_expint_En_scaled_e (int double gsl_sf_result*)) (double gsl_sf_expint_En_scaled (int double)) (int gsl_sf_expint_Ei_e (double gsl_sf_result*)) (double gsl_sf_expint_Ei (double)) (int gsl_sf_expint_Ei_scaled_e (double gsl_sf_result*)) (double gsl_sf_expint_Ei_scaled (double)) (int gsl_sf_Shi_e (double gsl_sf_result*)) (double gsl_sf_Shi (double)) (int gsl_sf_Chi_e (double gsl_sf_result*)) (double gsl_sf_Chi (double)) (int gsl_sf_expint_3_e (double gsl_sf_result*)) (double gsl_sf_expint_3 (double)) (int gsl_sf_Si_e (double gsl_sf_result*)) (double gsl_sf_Si (double)) (int gsl_sf_Ci_e (double gsl_sf_result*)) (double gsl_sf_Ci (double)) (int gsl_sf_atanint_e (double gsl_sf_result*)) (double gsl_sf_atanint (double)) (int gsl_sf_fermi_dirac_m1_e (double gsl_sf_result*)) (double gsl_sf_fermi_dirac_m1 (double)) (int gsl_sf_fermi_dirac_0_e (double gsl_sf_result*)) (double gsl_sf_fermi_dirac_0 (double)) (int gsl_sf_fermi_dirac_1_e (double gsl_sf_result*)) (double gsl_sf_fermi_dirac_1 (double)) (int gsl_sf_fermi_dirac_2_e (double gsl_sf_result*)) (double gsl_sf_fermi_dirac_2 (double)) (int gsl_sf_fermi_dirac_int_e (int double gsl_sf_result*)) (double gsl_sf_fermi_dirac_int (int double)) (int gsl_sf_fermi_dirac_mhalf_e (double gsl_sf_result*)) (double gsl_sf_fermi_dirac_mhalf (double)) (int gsl_sf_fermi_dirac_half_e (double gsl_sf_result*)) (double gsl_sf_fermi_dirac_half (double)) (int gsl_sf_fermi_dirac_3half_e (double gsl_sf_result*)) (double gsl_sf_fermi_dirac_3half (double)) (int gsl_sf_fermi_dirac_inc_0_e (double double gsl_sf_result*)) (double gsl_sf_fermi_dirac_inc_0 (double double)) (int gsl_sf_lngamma_e (double gsl_sf_result*)) (double gsl_sf_lngamma (double)) (int gsl_sf_lngamma_sgn_e (double gsl_sf_result* double*)) (int gsl_sf_gamma_e (double gsl_sf_result*)) (double gsl_sf_gamma (double)) (int gsl_sf_gammastar_e (double gsl_sf_result*)) (double gsl_sf_gammastar (double)) (int gsl_sf_gammainv_e (double gsl_sf_result*)) (double gsl_sf_gammainv (double)) (int gsl_sf_lngamma_complex_e (double double gsl_sf_result* gsl_sf_result*)) (int gsl_sf_taylorcoeff_e (int double gsl_sf_result*)) (double gsl_sf_taylorcoeff (int double)) (int gsl_sf_fact_e (int gsl_sf_result*)) (double gsl_sf_fact (int)) (int gsl_sf_doublefact_e (int gsl_sf_result*)) (double gsl_sf_doublefact (int)) (int gsl_sf_lnfact_e (int gsl_sf_result*)) (double gsl_sf_lnfact (int)) (int gsl_sf_lndoublefact_e (int gsl_sf_result*)) (double gsl_sf_lndoublefact (int)) (int gsl_sf_lnchoose_e (int int gsl_sf_result*)) (double gsl_sf_lnchoose (int int)) (int gsl_sf_choose_e (int int gsl_sf_result*)) (double gsl_sf_choose (int int)) (int gsl_sf_lnpoch_e (double double gsl_sf_result*)) (double gsl_sf_lnpoch (double double)) (int gsl_sf_lnpoch_sgn_e (double double gsl_sf_result* double*)) (int gsl_sf_poch_e (double double gsl_sf_result*)) (double gsl_sf_poch (double double)) (int gsl_sf_pochrel_e (double double gsl_sf_result*)) (double gsl_sf_pochrel (double double)) (int gsl_sf_gamma_inc_Q_e (double double gsl_sf_result*)) (double gsl_sf_gamma_inc_Q (double double)) (int gsl_sf_gamma_inc_P_e (double double gsl_sf_result*)) (double gsl_sf_gamma_inc_P (double double)) (int gsl_sf_gamma_inc_e (double double gsl_sf_result*)) (double gsl_sf_gamma_inc (double double)) (int gsl_sf_lnbeta_e (double double gsl_sf_result*)) (double gsl_sf_lnbeta (double double)) (int gsl_sf_lnbeta_sgn_e (double double gsl_sf_result* double*)) (int gsl_sf_beta_e (double double gsl_sf_result*)) (double gsl_sf_beta (double double)) (int gsl_sf_beta_inc_e (double double double gsl_sf_result*)) (double gsl_sf_beta_inc (double double double)) (int gsl_sf_gegenpoly_1_e (double double gsl_sf_result*)) (int gsl_sf_gegenpoly_2_e (double double gsl_sf_result*)) (int gsl_sf_gegenpoly_3_e (double double gsl_sf_result*)) (double gsl_sf_gegenpoly_1 (double double)) (double gsl_sf_gegenpoly_2 (double double)) (double gsl_sf_gegenpoly_3 (double double)) (int gsl_sf_gegenpoly_n_e (int double double gsl_sf_result*)) (double gsl_sf_gegenpoly_n (int double double)) (int gsl_sf_gegenpoly_array (int double double double*)) (int gsl_sf_hyperg_0F1_e (double double gsl_sf_result*)) (double gsl_sf_hyperg_0F1 (double double)) (int gsl_sf_hyperg_1F1_int_e (int int double gsl_sf_result*)) (double gsl_sf_hyperg_1F1_int (int int double)) (int gsl_sf_hyperg_1F1_e (double double double gsl_sf_result*)) (double gsl_sf_hyperg_1F1 (double double double)) (int gsl_sf_hyperg_U_int_e (int int double gsl_sf_result*)) (double gsl_sf_hyperg_U_int (int int double)) (int gsl_sf_hyperg_U_int_e10_e (int int double gsl_sf_result_e10*)) (int gsl_sf_hyperg_U_e (double double double gsl_sf_result*)) (double gsl_sf_hyperg_U (double double double)) (int gsl_sf_hyperg_U_e10_e (double double double gsl_sf_result_e10*)) (int gsl_sf_hyperg_2F1_e (double double double double gsl_sf_result*)) (double gsl_sf_hyperg_2F1 (double double double double)) (int gsl_sf_hyperg_2F1_conj_e (double double double double gsl_sf_result*)) (double gsl_sf_hyperg_2F1_conj (double double double double)) (int gsl_sf_hyperg_2F1_renorm_e (double double double double gsl_sf_result*)) (double gsl_sf_hyperg_2F1_renorm (double double double double)) (int gsl_sf_hyperg_2F1_conj_renorm_e (double double double double gsl_sf_result*)) (double gsl_sf_hyperg_2F1_conj_renorm (double double double double)) (int gsl_sf_hyperg_2F0_e (double double double gsl_sf_result*)) (double gsl_sf_hyperg_2F0 (double double double)) (int gsl_sf_laguerre_1_e (double double gsl_sf_result*)) (int gsl_sf_laguerre_2_e (double double gsl_sf_result*)) (int gsl_sf_laguerre_3_e (double double gsl_sf_result*)) (double gsl_sf_laguerre_1 (double double)) (double gsl_sf_laguerre_2 (double double)) (double gsl_sf_laguerre_3 (double double)) (int gsl_sf_laguerre_n_e (int double double gsl_sf_result*)) (double gsl_sf_laguerre_n (int double double)) (int gsl_sf_lambert_W0_e (double gsl_sf_result*)) (double gsl_sf_lambert_W0 (double)) (int gsl_sf_lambert_Wm1_e (double gsl_sf_result*)) (double gsl_sf_lambert_Wm1 (double)) (int gsl_sf_legendre_Pl_e (int double gsl_sf_result*)) (double gsl_sf_legendre_Pl (int double)) (int gsl_sf_legendre_Pl_array (int double double*)) (int gsl_sf_legendre_Pl_deriv_array ( int double double* double*)) (int gsl_sf_legendre_P1_e (double gsl_sf_result*)) (int gsl_sf_legendre_P2_e (double gsl_sf_result*)) (int gsl_sf_legendre_P3_e (double gsl_sf_result*)) (double gsl_sf_legendre_P1 (double)) (double gsl_sf_legendre_P2 (double)) (double gsl_sf_legendre_P3 (double)) (int gsl_sf_legendre_Q0_e (double gsl_sf_result*)) (double gsl_sf_legendre_Q0 (double)) (int gsl_sf_legendre_Q1_e (double gsl_sf_result*)) (double gsl_sf_legendre_Q1 (double)) (int gsl_sf_legendre_Ql_e (int double gsl_sf_result*)) (double gsl_sf_legendre_Ql (int double)) (int gsl_sf_legendre_Plm_e (int int double gsl_sf_result*)) (double gsl_sf_legendre_Plm (int int double)) (int gsl_sf_legendre_sphPlm_e (int int double gsl_sf_result*)) (double gsl_sf_legendre_sphPlm (int int double)) (reader-cond ((< gsl-version 2.0) (int gsl_sf_legendre_array_size (int int)) (int gsl_sf_legendre_Plm_array (int int double double*)) (int gsl_sf_legendre_Plm_deriv_array (int int double double* double*)) (int gsl_sf_legendre_sphPlm_array (int int double double*)) (int gsl_sf_legendre_sphPlm_deriv_array (int int double double* double*))) (#t (int gsl_sf_legendre_array (int size_t double double*)) (int gsl_sf_legendre_array_e (int size_t double double double*)) (int gsl_sf_legendre_deriv_array (int size_t double double* double*)) (int gsl_sf_legendre_deriv_array_e (int size_t double double double* double*)) (int gsl_sf_legendre_deriv_alt_array (int size_t double double* double*)) (int gsl_sf_legendre_deriv_alt_array_e (int size_t double double double* double*)) (int gsl_sf_legendre_deriv2_array (int size_t double double* double* double*)) (int gsl_sf_legendre_deriv2_array_e (int size_t double double double* double* double*)) (int gsl_sf_legendre_deriv2_alt_array (int size_t double double* double* double*)) (int gsl_sf_legendre_deriv2_alt_array_e (int size_t double double double* double* double*)) (size_t gsl_sf_legendre_array_n (size_t)) (size_t gsl_sf_legendre_array_index (size_t size_t)) (size_t gsl_sf_legendre_nlm (size_t)))) (int gsl_sf_conicalP_half_e (double double gsl_sf_result*)) (double gsl_sf_conicalP_half (double double)) (int gsl_sf_conicalP_mhalf_e (double double gsl_sf_result*)) (double gsl_sf_conicalP_mhalf (double double)) (int gsl_sf_conicalP_0_e (double double gsl_sf_result*)) (double gsl_sf_conicalP_0 (double double)) (int gsl_sf_conicalP_1_e (double double gsl_sf_result*)) (double gsl_sf_conicalP_1 (double double)) (int gsl_sf_conicalP_sph_reg_e (int double double gsl_sf_result*)) (double gsl_sf_conicalP_sph_reg (int double double)) (int gsl_sf_conicalP_cyl_reg_e (int double double gsl_sf_result*)) (double gsl_sf_conicalP_cyl_reg (int double double)) (int gsl_sf_legendre_H3d_0_e (double double gsl_sf_result*)) (double gsl_sf_legendre_H3d_0 (double double)) (int gsl_sf_legendre_H3d_1_e (double double gsl_sf_result*)) (double gsl_sf_legendre_H3d_1 (double double)) (int gsl_sf_legendre_H3d_e (int double double gsl_sf_result*)) (double gsl_sf_legendre_H3d (int double double)) (int gsl_sf_legendre_H3d_array (int double double double*)) (int gsl_sf_log_e (double gsl_sf_result*)) (double gsl_sf_log (double)) (int gsl_sf_log_abs_e (double gsl_sf_result*)) (double gsl_sf_log_abs (double)) (int gsl_sf_complex_log_e (double double gsl_sf_result* gsl_sf_result*)) (int gsl_sf_log_1plusx_e (double gsl_sf_result*)) (double gsl_sf_log_1plusx (double)) (int gsl_sf_log_1plusx_mx_e (double gsl_sf_result*)) (double gsl_sf_log_1plusx_mx (double)) (int gsl_sf_mathieu_a_array (int int double gsl_sf_mathieu_workspace* double*)) (int gsl_sf_mathieu_b_array (int int double gsl_sf_mathieu_workspace* double*)) (int gsl_sf_mathieu_a_coeff (int double double double*)) (int gsl_sf_mathieu_b_coeff (int double double double*)) (gsl_sf_mathieu_workspace* gsl_sf_mathieu_alloc (size_t double)) (void gsl_sf_mathieu_free (gsl_sf_mathieu_workspace*)) (int gsl_sf_mathieu_ce_array (int int double double gsl_sf_mathieu_workspace* double*)) (int gsl_sf_mathieu_se_array (int int double double gsl_sf_mathieu_workspace* double*)) (reader-cond ((< gsl-version 2.0) (int gsl_sf_mathieu_Mc (int int double double gsl_sf_result*)) (int gsl_sf_mathieu_Ms (int int double double gsl_sf_result*)) (int gsl_sf_mathieu_ce (int double double gsl_sf_result*)) (int gsl_sf_mathieu_se (int double double gsl_sf_result*)) (int gsl_sf_mathieu_a (int double gsl_sf_result*)) (int gsl_sf_mathieu_b (int double gsl_sf_result*))) (#t (int gsl_sf_mathieu_Mc_e (int int double double gsl_sf_result*)) (double gsl_sf_mathieu_Mc (int int double double)) (int gsl_sf_mathieu_Ms_e (int int double double gsl_sf_result*)) (double gsl_sf_mathieu_Ms (int int double double)) (int gsl_sf_mathieu_a_e (int double gsl_sf_result*)) (double gsl_sf_mathieu_a (int double)) (int gsl_sf_mathieu_b_e (int double gsl_sf_result*)) (double gsl_sf_mathieu_b (int double)) (int gsl_sf_mathieu_ce_e (int double double gsl_sf_result*)) (double gsl_sf_mathieu_ce (int double double)) (int gsl_sf_mathieu_se_e (int double double gsl_sf_result*)) (double gsl_sf_mathieu_se (int double double)))) (int gsl_sf_mathieu_Mc_array (int int int double double gsl_sf_mathieu_workspace* double*)) (int gsl_sf_mathieu_Ms_array (int int int double double gsl_sf_mathieu_workspace* double*)) (int gsl_sf_pow_int_e (double int gsl_sf_result*)) (double gsl_sf_pow_int (double int)) (int gsl_sf_psi_int_e (int gsl_sf_result*)) (double gsl_sf_psi_int (int)) (int gsl_sf_psi_e (double gsl_sf_result*)) (double gsl_sf_psi (double)) (int gsl_sf_psi_1piy_e (double gsl_sf_result*)) (double gsl_sf_psi_1piy (double)) (int gsl_sf_complex_psi_e (double double gsl_sf_result* gsl_sf_result*)) (int gsl_sf_psi_1_int_e (int gsl_sf_result*)) (double gsl_sf_psi_1_int (int)) (int gsl_sf_psi_1_e (double gsl_sf_result*)) (double gsl_sf_psi_1 (double)) (int gsl_sf_psi_n_e (int double gsl_sf_result*)) (double gsl_sf_psi_n (int double)) (int gsl_sf_result_smash_e (gsl_sf_result_e10* gsl_sf_result*)) (int gsl_sf_synchrotron_1_e (double gsl_sf_result*)) (double gsl_sf_synchrotron_1 (double)) (int gsl_sf_synchrotron_2_e (double gsl_sf_result*)) (double gsl_sf_synchrotron_2 (double)) (int gsl_sf_transport_2_e (double gsl_sf_result*)) (double gsl_sf_transport_2 (double)) (int gsl_sf_transport_3_e (double gsl_sf_result*)) (double gsl_sf_transport_3 (double)) (int gsl_sf_transport_4_e (double gsl_sf_result*)) (double gsl_sf_transport_4 (double)) (int gsl_sf_transport_5_e (double gsl_sf_result*)) (double gsl_sf_transport_5 (double)) (int gsl_sf_sin_e (double gsl_sf_result*)) (double gsl_sf_sin (double)) (int gsl_sf_cos_e (double gsl_sf_result*)) (double gsl_sf_cos (double)) (int gsl_sf_hypot_e (double double gsl_sf_result*)) (double gsl_sf_hypot (double double)) (int gsl_sf_complex_sin_e (double double gsl_sf_result* gsl_sf_result*)) (int gsl_sf_complex_cos_e (double double gsl_sf_result* gsl_sf_result*)) (int gsl_sf_complex_logsin_e (double double gsl_sf_result* gsl_sf_result*)) (int gsl_sf_sinc_e (double gsl_sf_result*)) (double gsl_sf_sinc (double)) (int gsl_sf_lnsinh_e (double gsl_sf_result*)) (double gsl_sf_lnsinh (double)) (int gsl_sf_lncosh_e (double gsl_sf_result*)) (double gsl_sf_lncosh (double)) (int gsl_sf_polar_to_rect (double double gsl_sf_result* gsl_sf_result*)) (int gsl_sf_rect_to_polar (double double gsl_sf_result* gsl_sf_result*)) (int gsl_sf_sin_err_e (double double gsl_sf_result*)) (int gsl_sf_cos_err_e (double double gsl_sf_result*)) (int gsl_sf_angle_restrict_symm_e (double*)) (double gsl_sf_angle_restrict_symm (double)) (int gsl_sf_angle_restrict_pos_e (double*)) (double gsl_sf_angle_restrict_pos (double)) (int gsl_sf_angle_restrict_symm_err_e (double gsl_sf_result*)) (int gsl_sf_angle_restrict_pos_err_e (double gsl_sf_result*)) (int gsl_sf_zeta_int_e (int gsl_sf_result*)) (double gsl_sf_zeta_int (int)) (int gsl_sf_zeta_e (double gsl_sf_result*)) (double gsl_sf_zeta (double)) (int gsl_sf_zetam1_e (double gsl_sf_result*)) (double gsl_sf_zetam1 (double)) (int gsl_sf_zetam1_int_e (int gsl_sf_result*)) (double gsl_sf_zetam1_int (int)) (int gsl_sf_hzeta_e (double double gsl_sf_result*)) (double gsl_sf_hzeta (double double)) (int gsl_sf_eta_int_e (int gsl_sf_result*)) (double gsl_sf_eta_int (int)) (int gsl_sf_eta_e (double gsl_sf_result*)) (double gsl_sf_eta (double)) (in-C "static s7_pointer g_gsl_sf_result_make(s7_scheme *sc, s7_pointer args) { return(s7_make_c_pointer(sc, (void *)calloc(1, sizeof(gsl_sf_result)))); } static s7_pointer g_gsl_sf_result_val(s7_scheme *sc, s7_pointer args) { return(s7_make_real(sc, ((gsl_sf_result *)s7_c_pointer(s7_car(args)))->val)); } static s7_pointer g_gsl_sf_result_err(s7_scheme *sc, s7_pointer args) { return(s7_make_real(sc, ((gsl_sf_result *)s7_c_pointer(s7_car(args)))->err)); } static s7_pointer g_gsl_sf_result_e10_make(s7_scheme *sc, s7_pointer args) { return(s7_make_c_pointer(sc, (void *)calloc(1, sizeof(gsl_sf_result_e10)))); } static s7_pointer g_to_doubles(s7_scheme *sc, s7_pointer args) { if (s7_is_vector(s7_car(args))) return(s7_make_c_pointer(sc, (void *)s7_float_vector_elements(s7_car(args)))); return(s7_car(args)); } ") (C-function ("gsl_sf_result.make" g_gsl_sf_result_make "" 0)) (C-function ("gsl_sf_result_e10.make" g_gsl_sf_result_e10_make "" 0)) (C-function ("gsl_sf_result.val" g_gsl_sf_result_val "" 1)) (C-function ("gsl_sf_result.err" g_gsl_sf_result_err "" 1)) (C-function ("double*" g_to_doubles "" 1)) (double gsl_log1p (double)) (double gsl_expm1 (double)) (double gsl_hypot (double double)) (double gsl_hypot3 (double double double)) (double gsl_acosh (double)) (double gsl_asinh (double)) (double gsl_atanh (double)) (int gsl_isnan (double)) (int gsl_isinf (double)) (int gsl_finite (double)) (double gsl_nan (void)) (double gsl_posinf (void)) (double gsl_neginf (void)) (double gsl_fdiv (double double)) (double gsl_coerce_double (double)) (double gsl_ldexp (double int)) (in-C "static s7_pointer g_gsl_frexp(s7_scheme *sc, s7_pointer args) { int e = 0; double res; res = gsl_frexp(s7_real(s7_car(args)), &e); return(s7_list(sc, 2, s7_make_real(sc, res), s7_make_integer(sc, e))); } ") (C-function ("gsl_frexp" g_gsl_frexp "" 1)) (int gsl_fcmp (double double double)) (double gsl_pow_2 (double)) (double gsl_pow_3 (double)) (double gsl_pow_4 (double)) (double gsl_pow_5 (double)) (double gsl_pow_6 (double)) (double gsl_pow_7 (double)) (double gsl_pow_8 (double)) (double gsl_pow_9 (double)) (double gsl_pow_int (double int)) ;; gsl_cdf (double gsl_cdf_ugaussian_P (double)) (double gsl_cdf_ugaussian_Q (double)) (double gsl_cdf_ugaussian_Pinv (double)) (double gsl_cdf_ugaussian_Qinv (double)) (double gsl_cdf_gaussian_P (double double)) (double gsl_cdf_gaussian_Q (double double)) (double gsl_cdf_gaussian_Pinv (double double)) (double gsl_cdf_gaussian_Qinv (double double)) (double gsl_cdf_gamma_P (double double double)) (double gsl_cdf_gamma_Q (double double double)) (double gsl_cdf_gamma_Pinv (double double double)) (double gsl_cdf_gamma_Qinv (double double double)) (double gsl_cdf_cauchy_P (double double)) (double gsl_cdf_cauchy_Q (double double)) (double gsl_cdf_cauchy_Pinv (double double)) (double gsl_cdf_cauchy_Qinv (double double)) (double gsl_cdf_laplace_P (double double)) (double gsl_cdf_laplace_Q (double double)) (double gsl_cdf_laplace_Pinv (double double)) (double gsl_cdf_laplace_Qinv (double double)) (double gsl_cdf_rayleigh_P (double double)) (double gsl_cdf_rayleigh_Q (double double)) (double gsl_cdf_rayleigh_Pinv (double double)) (double gsl_cdf_rayleigh_Qinv (double double)) (double gsl_cdf_chisq_P (double double)) (double gsl_cdf_chisq_Q (double double)) (double gsl_cdf_chisq_Pinv (double double)) (double gsl_cdf_chisq_Qinv (double double)) (double gsl_cdf_exponential_P (double double)) (double gsl_cdf_exponential_Q (double double)) (double gsl_cdf_exponential_Pinv (double double)) (double gsl_cdf_exponential_Qinv (double double)) (double gsl_cdf_exppow_P (double double double)) (double gsl_cdf_exppow_Q (double double double)) (double gsl_cdf_tdist_P (double double)) (double gsl_cdf_tdist_Q (double double)) (double gsl_cdf_tdist_Pinv (double double)) (double gsl_cdf_tdist_Qinv (double double)) (double gsl_cdf_fdist_P (double double double)) (double gsl_cdf_fdist_Q (double double double)) (double gsl_cdf_fdist_Pinv (double double double)) (double gsl_cdf_fdist_Qinv (double double double)) (double gsl_cdf_beta_P (double double double)) (double gsl_cdf_beta_Q (double double double)) (double gsl_cdf_beta_Pinv (double double double)) (double gsl_cdf_beta_Qinv (double double double)) (double gsl_cdf_flat_P (double double double)) (double gsl_cdf_flat_Q (double double double)) (double gsl_cdf_flat_Pinv (double double double)) (double gsl_cdf_flat_Qinv (double double double)) (double gsl_cdf_lognormal_P (double double double)) (double gsl_cdf_lognormal_Q (double double double)) (double gsl_cdf_lognormal_Pinv (double double double)) (double gsl_cdf_lognormal_Qinv (double double double)) (double gsl_cdf_gumbel1_P (double double double)) (double gsl_cdf_gumbel1_Q (double double double)) (double gsl_cdf_gumbel1_Pinv (double double double)) (double gsl_cdf_gumbel1_Qinv (double double double)) (double gsl_cdf_gumbel2_P (double double double)) (double gsl_cdf_gumbel2_Q (double double double)) (double gsl_cdf_gumbel2_Pinv (double double double)) (double gsl_cdf_gumbel2_Qinv (double double double)) (double gsl_cdf_weibull_P (double double double)) (double gsl_cdf_weibull_Q (double double double)) (double gsl_cdf_weibull_Pinv (double double double)) (double gsl_cdf_weibull_Qinv (double double double)) (double gsl_cdf_pareto_P (double double double)) (double gsl_cdf_pareto_Q (double double double)) (double gsl_cdf_pareto_Pinv (double double double)) (double gsl_cdf_pareto_Qinv (double double double)) (double gsl_cdf_logistic_P (double double)) (double gsl_cdf_logistic_Q (double double)) (double gsl_cdf_logistic_Pinv (double double)) (double gsl_cdf_logistic_Qinv (double double)) (double gsl_cdf_binomial_P (int double int)) (double gsl_cdf_binomial_Q (int double int)) (double gsl_cdf_poisson_P (int double)) (double gsl_cdf_poisson_Q (int double)) (double gsl_cdf_geometric_P (int double)) (double gsl_cdf_geometric_Q (int double)) (double gsl_cdf_negative_binomial_P (int double double)) (double gsl_cdf_negative_binomial_Q (int double double)) (double gsl_cdf_pascal_P (int double int)) (double gsl_cdf_pascal_Q (int double int)) (double gsl_cdf_hypergeometric_P (int int int int)) (double gsl_cdf_hypergeometric_Q (int int int int)) ;; gsl_dht (gsl_dht* gsl_dht_alloc (size_t)) (gsl_dht* gsl_dht_new (size_t double double)) (int gsl_dht_init (gsl_dht* double double)) (double gsl_dht_x_sample (gsl_dht* int)) (double gsl_dht_k_sample (gsl_dht* int)) (void gsl_dht_free (gsl_dht*)) (int gsl_dht_apply (gsl_dht* double* double*)) ;; gsl_statistics (double gsl_stats_mean (double* size_t size_t)) (double gsl_stats_variance (double* size_t size_t)) (double gsl_stats_sd (double* size_t size_t)) (double gsl_stats_variance_with_fixed_mean (double* size_t size_t double)) (double gsl_stats_sd_with_fixed_mean (double* size_t size_t double)) (double gsl_stats_tss (double* size_t size_t)) (double gsl_stats_tss_m (double* size_t size_t double)) (double gsl_stats_absdev (double* size_t size_t)) (double gsl_stats_skew (double* size_t size_t)) (double gsl_stats_kurtosis (double* size_t size_t)) (double gsl_stats_lag1_autocorrelation (double* size_t size_t)) (double gsl_stats_covariance (double* size_t double* size_t size_t)) (double gsl_stats_correlation (double* size_t double* size_t size_t)) (reader-cond ((>= gsl-version 1.16) (double gsl_stats_spearman (double* size_t double* size_t size_t double*)))) (double gsl_stats_variance_m (double* size_t size_t double)) (double gsl_stats_sd_m (double* size_t size_t double)) (double gsl_stats_absdev_m (double* size_t size_t double)) (double gsl_stats_skew_m_sd (double* size_t size_t double double)) (double gsl_stats_kurtosis_m_sd (double* size_t size_t double double)) (double gsl_stats_lag1_autocorrelation_m (double* size_t size_t double)) (double gsl_stats_covariance_m (double* size_t double* size_t size_t double double)) (double gsl_stats_wmean (double* size_t double* size_t size_t)) (double gsl_stats_wvariance (double* size_t double* size_t size_t)) (double gsl_stats_wsd (double* size_t double* size_t size_t)) (double gsl_stats_wvariance_with_fixed_mean (double* size_t double* size_t size_t double)) (double gsl_stats_wsd_with_fixed_mean (double* size_t double* size_t size_t double)) (double gsl_stats_wtss (double* size_t double* size_t size_t)) (double gsl_stats_wtss_m (double* size_t double* size_t size_t double)) (double gsl_stats_wabsdev (double* size_t double* size_t size_t)) (double gsl_stats_wskew (double* size_t double* size_t size_t)) (double gsl_stats_wkurtosis (double* size_t double* size_t size_t)) (double gsl_stats_wvariance_m (double* size_t double* size_t size_t double)) (double gsl_stats_wsd_m (double* size_t double* size_t size_t double)) (double gsl_stats_wabsdev_m (double* size_t double* size_t size_t double)) (double gsl_stats_wskew_m_sd (double* size_t double* size_t size_t double double)) (double gsl_stats_wkurtosis_m_sd (double* size_t double* size_t size_t double double)) (double gsl_stats_pvariance (double* size_t size_t double* size_t size_t)) (double gsl_stats_ttest (double* size_t size_t double* size_t size_t)) (double gsl_stats_max (double* size_t size_t)) (double gsl_stats_min (double* size_t size_t)) (void gsl_stats_minmax (double* double* double* size_t size_t)) (size_t gsl_stats_max_index (double* size_t size_t)) (size_t gsl_stats_min_index (double* size_t size_t)) (void gsl_stats_minmax_index (size_t* size_t* double* size_t size_t)) (double gsl_stats_median_from_sorted_data (double* size_t size_t)) (double gsl_stats_quantile_from_sorted_data (double* size_t size_t double)) (c-pointer (gsl_interp_linear gsl_interp_polynomial gsl_interp_cspline gsl_interp_cspline_periodic gsl_interp_akima gsl_interp_akima_periodic gsl_min_fminimizer_goldensection gsl_min_fminimizer_brent gsl_min_fminimizer_quad_golden gsl_multimin_fminimizer_nmsimplex gsl_multimin_fminimizer_nmsimplex2 gsl_multimin_fminimizer_nmsimplex2rand gsl_multiroot_fsolver_dnewton gsl_multiroot_fsolver_broyden gsl_multiroot_fsolver_hybrid gsl_multiroot_fsolver_hybrids gsl_prec_eps gsl_prec_sqrt_eps gsl_prec_root3_eps gsl_prec_root4_eps gsl_prec_root5_eps gsl_prec_root6_eps gsl_root_fsolver_bisection gsl_root_fsolver_brent gsl_root_fsolver_falsepos gsl_version gsl_wavelet_daubechies gsl_wavelet_daubechies_centered gsl_wavelet_haar gsl_wavelet_haar_centered gsl_wavelet_bspline gsl_wavelet_bspline_centered)) (reader-cond ((>= gsl-version 1.16) (c-pointer (gsl_multifit_robust_default gsl_multifit_robust_bisquare gsl_multifit_robust_cauchy gsl_multifit_robust_fair gsl_multifit_robust_huber gsl_multifit_robust_ols gsl_multifit_robust_welsch)))) (reader-cond ((>= gsl-version 2.0) (c-pointer gsl_interp_steffen))) (int (gsl_message_mask gsl_check_range)) ;; randist, rng (c-pointer (gsl_qrng_niederreiter_2 gsl_qrng_sobol gsl_qrng_halton gsl_qrng_reversehalton gsl_rng_borosh13 gsl_rng_coveyou gsl_rng_cmrg gsl_rng_fishman18 gsl_rng_fishman20 gsl_rng_fishman2x gsl_rng_gfsr4 gsl_rng_knuthran gsl_rng_knuthran2 gsl_rng_knuthran2002 gsl_rng_lecuyer21 gsl_rng_minstd gsl_rng_mrg gsl_rng_mt19937 gsl_rng_mt19937_1999 gsl_rng_mt19937_1998 gsl_rng_r250 gsl_rng_ran0 gsl_rng_ran1 gsl_rng_ran2 gsl_rng_ran3 gsl_rng_rand gsl_rng_rand48 gsl_rng_random128_bsd gsl_rng_random128_glibc2 gsl_rng_random128_libc5 gsl_rng_random256_bsd gsl_rng_random256_glibc2 gsl_rng_random256_libc5 gsl_rng_random32_bsd gsl_rng_random32_glibc2 gsl_rng_random32_libc5 gsl_rng_random64_bsd gsl_rng_random64_glibc2 gsl_rng_random64_libc5 gsl_rng_random8_bsd gsl_rng_random8_glibc2 gsl_rng_random8_libc5 gsl_rng_random_bsd gsl_rng_random_glibc2 gsl_rng_random_libc5 gsl_rng_randu gsl_rng_ranf gsl_rng_ranlux gsl_rng_ranlux389 gsl_rng_ranlxd1 gsl_rng_ranlxd2 gsl_rng_ranlxs0 gsl_rng_ranlxs1 gsl_rng_ranlxs2 gsl_rng_ranmar gsl_rng_slatec gsl_rng_taus gsl_rng_taus2 gsl_rng_taus113 gsl_rng_transputer gsl_rng_tt800 gsl_rng_uni gsl_rng_uni32 gsl_rng_vax gsl_rng_waterman14 gsl_rng_zuf gsl_rng_default gsl_rng_default_seed)) (gsl_qrng* gsl_qrng_alloc (gsl_qrng_type* int)) (int gsl_qrng_memcpy (gsl_qrng* gsl_qrng*)) (gsl_qrng* gsl_qrng_clone (gsl_qrng*)) (void gsl_qrng_free (gsl_qrng*)) (void gsl_qrng_init (gsl_qrng*)) (char* gsl_qrng_name (gsl_qrng*)) (size_t gsl_qrng_size (gsl_qrng*)) (void* gsl_qrng_state (gsl_qrng*)) (int gsl_qrng_get (gsl_qrng* double*)) (int gsl_ran_bernoulli (gsl_rng* double)) (double gsl_ran_bernoulli_pdf (int double)) (double gsl_ran_beta (gsl_rng* double double)) (double gsl_ran_beta_pdf (double double double)) (int gsl_ran_binomial (gsl_rng* double int)) (int gsl_ran_binomial_knuth (gsl_rng* double int)) (int gsl_ran_binomial_tpe (gsl_rng* double int)) (double gsl_ran_binomial_pdf (int double int)) (double gsl_ran_exponential (gsl_rng* double)) (double gsl_ran_exponential_pdf (double double)) (double gsl_ran_exppow (gsl_rng* double double)) (double gsl_ran_exppow_pdf (double double double)) (double gsl_ran_cauchy (gsl_rng* double)) (double gsl_ran_cauchy_pdf (double double)) (double gsl_ran_chisq (gsl_rng* double)) (double gsl_ran_chisq_pdf (double double)) (void gsl_ran_dirichlet (gsl_rng* size_t double* double*)) (double gsl_ran_dirichlet_pdf (size_t double* double*)) (double gsl_ran_dirichlet_lnpdf (size_t double* double*)) (double gsl_ran_erlang (gsl_rng* double double)) (double gsl_ran_erlang_pdf (double double double)) (double gsl_ran_fdist (gsl_rng* double double)) (double gsl_ran_fdist_pdf (double double double)) (double gsl_ran_flat (gsl_rng* double double)) (double gsl_ran_flat_pdf (double double double)) (double gsl_ran_gamma (gsl_rng* double double)) (double gsl_ran_gamma_int (gsl_rng* int)) (double gsl_ran_gamma_pdf (double double double)) (double gsl_ran_gamma_mt (gsl_rng* double double)) (double gsl_ran_gamma_knuth (gsl_rng* double double)) (double gsl_ran_gaussian (gsl_rng* double)) (double gsl_ran_gaussian_ratio_method (gsl_rng* double)) (double gsl_ran_gaussian_ziggurat (gsl_rng* double)) (double gsl_ran_gaussian_pdf (double double)) (double gsl_ran_ugaussian (gsl_rng*)) (double gsl_ran_ugaussian_ratio_method (gsl_rng*)) (double gsl_ran_ugaussian_pdf (double)) (double gsl_ran_gaussian_tail (gsl_rng* double double)) (double gsl_ran_gaussian_tail_pdf (double double double)) (double gsl_ran_ugaussian_tail (gsl_rng* double)) (double gsl_ran_ugaussian_tail_pdf (double double)) (void gsl_ran_bivariate_gaussian (gsl_rng* double double double double* double*)) (double gsl_ran_bivariate_gaussian_pdf (double double double double double)) (double gsl_ran_landau (gsl_rng*)) (double gsl_ran_landau_pdf (double)) (int gsl_ran_geometric (gsl_rng* double)) (double gsl_ran_geometric_pdf (int double)) (int gsl_ran_hypergeometric (gsl_rng* int int int)) (double gsl_ran_hypergeometric_pdf (int int int int)) (double gsl_ran_gumbel1 (gsl_rng* double double)) (double gsl_ran_gumbel1_pdf (double double double)) (double gsl_ran_gumbel2 (gsl_rng* double double)) (double gsl_ran_gumbel2_pdf (double double double)) (double gsl_ran_logistic (gsl_rng* double)) (double gsl_ran_logistic_pdf (double double)) (double gsl_ran_lognormal (gsl_rng* double double)) (double gsl_ran_lognormal_pdf (double double double)) (int gsl_ran_logarithmic (gsl_rng* double)) (double gsl_ran_logarithmic_pdf (int double)) ;; int* (void gsl_ran_multinomial (gsl_rng* size_t int double* int*)) ; unsigned int* ;; int* (double gsl_ran_multinomial_pdf (size_t double* int*)) ; unsigned int* ;; int* (double gsl_ran_multinomial_lnpdf (size_t double* int*)) ; unsigned int* (int gsl_ran_negative_binomial (gsl_rng* double double)) (double gsl_ran_negative_binomial_pdf (int double double)) (int gsl_ran_pascal (gsl_rng* double int)) (double gsl_ran_pascal_pdf (int double int)) (double gsl_ran_pareto (gsl_rng* double double)) (double gsl_ran_pareto_pdf (double double double)) (int gsl_ran_poisson (gsl_rng* double)) ;; int* (void gsl_ran_poisson_array (gsl_rng* size_t int* double)) ; unsigned int* (double gsl_ran_poisson_pdf (int double)) (double gsl_ran_rayleigh (gsl_rng* double)) (double gsl_ran_rayleigh_pdf (double double)) (double gsl_ran_rayleigh_tail (gsl_rng* double double)) (double gsl_ran_rayleigh_tail_pdf (double double double)) (double gsl_ran_tdist (gsl_rng* double)) (double gsl_ran_tdist_pdf (double double)) (double gsl_ran_laplace (gsl_rng* double)) (double gsl_ran_laplace_pdf (double double)) (double gsl_ran_levy (gsl_rng* double double)) (double gsl_ran_levy_skew (gsl_rng* double double double)) (double gsl_ran_weibull (gsl_rng* double double)) (double gsl_ran_weibull_pdf (double double double)) (void gsl_ran_dir_2d (gsl_rng* double* double*)) (void gsl_ran_dir_2d_trig_method (gsl_rng* double* double*)) (void gsl_ran_dir_3d (gsl_rng* double* double* double*)) (void gsl_ran_dir_nd (gsl_rng* size_t double*)) (void gsl_ran_shuffle (gsl_rng* void* size_t size_t)) (int gsl_ran_choose (gsl_rng* void* size_t void* size_t size_t)) (void gsl_ran_sample (gsl_rng* void* size_t void* size_t size_t)) (gsl_ran_discrete_t* gsl_ran_discrete_preproc (size_t double*)) (void gsl_ran_discrete_free (gsl_ran_discrete_t*)) (size_t gsl_ran_discrete (gsl_rng* gsl_ran_discrete_t*)) (double gsl_ran_discrete_pdf (size_t gsl_ran_discrete_t*)) (gsl_rng_type** gsl_rng_types_setup (void)) (gsl_rng* gsl_rng_alloc (gsl_rng_type*)) (int gsl_rng_memcpy (gsl_rng* gsl_rng*)) (gsl_rng* gsl_rng_clone (gsl_rng*)) (void gsl_rng_free (gsl_rng*)) (void gsl_rng_set (gsl_rng* int)) (int gsl_rng_max (gsl_rng*)) (int gsl_rng_min (gsl_rng*)) (char* gsl_rng_name (gsl_rng*)) (int gsl_rng_fread (FILE* gsl_rng*)) (int gsl_rng_fwrite (FILE* gsl_rng*)) (size_t gsl_rng_size (gsl_rng*)) (void* gsl_rng_state (gsl_rng*)) (void gsl_rng_print_state (gsl_rng*)) (gsl_rng_type* gsl_rng_env_setup (void)) (int gsl_rng_get (gsl_rng*)) (double gsl_rng_uniform (gsl_rng*)) (double gsl_rng_uniform_pos (gsl_rng*)) (int gsl_rng_uniform_int (gsl_rng* int)) ;; gsl_complex (in-C "#define S7_TO_GSL_COMPLEX(sg, g) GSL_SET_COMPLEX(&g, s7_real_part(sg), s7_imag_part(sg)) #define GSL_TO_S7_COMPLEX(sc, g) s7_make_complex(sc, GSL_REAL(g), GSL_IMAG(g)) static s7_pointer s7_gsl_c_c(s7_scheme *sc, s7_pointer arg1, gsl_complex (*callee)(gsl_complex a)) { gsl_complex g, g1; S7_TO_GSL_COMPLEX(arg1, g1); g = callee(g1); return(GSL_TO_S7_COMPLEX(sc, g)); } static s7_pointer s7_gsl_r_c(s7_scheme *sc, s7_pointer arg1, gsl_complex (*callee)(double a)) { gsl_complex g; g = callee(s7_number_to_real(sc, arg1)); return(GSL_TO_S7_COMPLEX(sc, g)); } static s7_pointer s7_gsl_c_r(s7_scheme *sc, s7_pointer arg1, double (*callee)(gsl_complex a)) { gsl_complex g1; S7_TO_GSL_COMPLEX(arg1, g1); return(s7_make_real(sc, callee(g1))); } static s7_pointer s7_gsl_cc_c(s7_scheme *sc, s7_pointer arg1, s7_pointer arg2, gsl_complex (*callee)(gsl_complex a, gsl_complex b)) { gsl_complex g, g1, g2; S7_TO_GSL_COMPLEX(arg1, g1); S7_TO_GSL_COMPLEX(arg2, g2); g = callee(g1, g2); return(GSL_TO_S7_COMPLEX(sc, g)); } static s7_pointer s7_gsl_cr_c(s7_scheme *sc, s7_pointer arg1, s7_pointer arg2, gsl_complex (*callee)(gsl_complex a, double b)) { gsl_complex g, g1; S7_TO_GSL_COMPLEX(arg1, g1); g = callee(g1, s7_number_to_real(sc, arg2)); return(GSL_TO_S7_COMPLEX(sc, g)); } static s7_pointer g_gsl_complex_arg(s7_scheme *sc, s7_pointer args) {return(s7_gsl_c_r(sc, s7_car(args), gsl_complex_arg));} static s7_pointer g_gsl_complex_abs(s7_scheme *sc, s7_pointer args) {return(s7_gsl_c_r(sc, s7_car(args), gsl_complex_abs));} static s7_pointer g_gsl_complex_abs2(s7_scheme *sc, s7_pointer args) {return(s7_gsl_c_r(sc, s7_car(args), gsl_complex_abs2));} static s7_pointer g_gsl_complex_logabs(s7_scheme *sc, s7_pointer args) {return(s7_gsl_c_r(sc, s7_car(args), gsl_complex_logabs));} static s7_pointer g_gsl_complex_conjugate(s7_scheme *sc, s7_pointer args) {return(s7_gsl_c_c(sc, s7_car(args), gsl_complex_conjugate));} static s7_pointer g_gsl_complex_inverse(s7_scheme *sc, s7_pointer args) {return(s7_gsl_c_c(sc, s7_car(args), gsl_complex_inverse));} static s7_pointer g_gsl_complex_negative(s7_scheme *sc, s7_pointer args) {return(s7_gsl_c_c(sc, s7_car(args), gsl_complex_negative));} static s7_pointer g_gsl_complex_sqrt(s7_scheme *sc, s7_pointer args) {return(s7_gsl_c_c(sc, s7_car(args), gsl_complex_sqrt));} static s7_pointer g_gsl_complex_exp(s7_scheme *sc, s7_pointer args) {return(s7_gsl_c_c(sc, s7_car(args), gsl_complex_exp));} static s7_pointer g_gsl_complex_log(s7_scheme *sc, s7_pointer args) {return(s7_gsl_c_c(sc, s7_car(args), gsl_complex_log));} static s7_pointer g_gsl_complex_log10(s7_scheme *sc, s7_pointer args) {return(s7_gsl_c_c(sc, s7_car(args), gsl_complex_log10));} static s7_pointer g_gsl_complex_sin(s7_scheme *sc, s7_pointer args) {return(s7_gsl_c_c(sc, s7_car(args), gsl_complex_sin));} static s7_pointer g_gsl_complex_cos(s7_scheme *sc, s7_pointer args) {return(s7_gsl_c_c(sc, s7_car(args), gsl_complex_cos));} static s7_pointer g_gsl_complex_sec(s7_scheme *sc, s7_pointer args) {return(s7_gsl_c_c(sc, s7_car(args), gsl_complex_sec));} static s7_pointer g_gsl_complex_csc(s7_scheme *sc, s7_pointer args) {return(s7_gsl_c_c(sc, s7_car(args), gsl_complex_csc));} static s7_pointer g_gsl_complex_tan(s7_scheme *sc, s7_pointer args) {return(s7_gsl_c_c(sc, s7_car(args), gsl_complex_tan));} static s7_pointer g_gsl_complex_cot(s7_scheme *sc, s7_pointer args) {return(s7_gsl_c_c(sc, s7_car(args), gsl_complex_cot));} static s7_pointer g_gsl_complex_sinh(s7_scheme *sc, s7_pointer args) {return(s7_gsl_c_c(sc, s7_car(args), gsl_complex_sinh));} static s7_pointer g_gsl_complex_cosh(s7_scheme *sc, s7_pointer args) {return(s7_gsl_c_c(sc, s7_car(args), gsl_complex_cosh));} static s7_pointer g_gsl_complex_sech(s7_scheme *sc, s7_pointer args) {return(s7_gsl_c_c(sc, s7_car(args), gsl_complex_sech));} static s7_pointer g_gsl_complex_csch(s7_scheme *sc, s7_pointer args) {return(s7_gsl_c_c(sc, s7_car(args), gsl_complex_csch));} static s7_pointer g_gsl_complex_tanh(s7_scheme *sc, s7_pointer args) {return(s7_gsl_c_c(sc, s7_car(args), gsl_complex_tanh));} static s7_pointer g_gsl_complex_coth(s7_scheme *sc, s7_pointer args) {return(s7_gsl_c_c(sc, s7_car(args), gsl_complex_coth));} static s7_pointer g_gsl_complex_arctan(s7_scheme *sc, s7_pointer args) {return(s7_gsl_c_c(sc, s7_car(args), gsl_complex_arctan));} static s7_pointer g_gsl_complex_arccot(s7_scheme *sc, s7_pointer args) {return(s7_gsl_c_c(sc, s7_car(args), gsl_complex_arccot));} static s7_pointer g_gsl_complex_arcsinh(s7_scheme *sc, s7_pointer args) {return(s7_gsl_c_c(sc, s7_car(args), gsl_complex_arcsinh));} static s7_pointer g_gsl_complex_arcsech(s7_scheme *sc, s7_pointer args) {return(s7_gsl_c_c(sc, s7_car(args), gsl_complex_arcsech));} static s7_pointer g_gsl_complex_arccsch(s7_scheme *sc, s7_pointer args) {return(s7_gsl_c_c(sc, s7_car(args), gsl_complex_arccsch));} static s7_pointer g_gsl_complex_arccoth(s7_scheme *sc, s7_pointer args) {return(s7_gsl_c_c(sc, s7_car(args), gsl_complex_arccoth));} static s7_pointer g_gsl_complex_arcsin(s7_scheme *sc, s7_pointer args) {return(s7_gsl_c_c(sc, s7_car(args), gsl_complex_arcsin));} static s7_pointer g_gsl_complex_arccos(s7_scheme *sc, s7_pointer args) {return(s7_gsl_c_c(sc, s7_car(args), gsl_complex_arccos));} static s7_pointer g_gsl_complex_arcsec(s7_scheme *sc, s7_pointer args) {return(s7_gsl_c_c(sc, s7_car(args), gsl_complex_arcsec));} static s7_pointer g_gsl_complex_arccsc(s7_scheme *sc, s7_pointer args) {return(s7_gsl_c_c(sc, s7_car(args), gsl_complex_arccsc));} static s7_pointer g_gsl_complex_arccosh(s7_scheme *sc, s7_pointer args) {return(s7_gsl_c_c(sc, s7_car(args), gsl_complex_arccosh));} static s7_pointer g_gsl_complex_arctanh(s7_scheme *sc, s7_pointer args) {return(s7_gsl_c_c(sc, s7_car(args), gsl_complex_arctanh));} static s7_pointer g_gsl_complex_sqrt_real(s7_scheme *sc, s7_pointer args) {return(s7_gsl_r_c(sc, s7_car(args), gsl_complex_sqrt_real));} static s7_pointer g_gsl_complex_arcsin_real(s7_scheme *sc, s7_pointer args) {return(s7_gsl_r_c(sc, s7_car(args), gsl_complex_arcsin_real));} static s7_pointer g_gsl_complex_arccos_real(s7_scheme *sc, s7_pointer args) {return(s7_gsl_r_c(sc, s7_car(args), gsl_complex_arccos_real));} static s7_pointer g_gsl_complex_arcsec_real(s7_scheme *sc, s7_pointer args) {return(s7_gsl_r_c(sc, s7_car(args), gsl_complex_arcsec_real));} static s7_pointer g_gsl_complex_arccsc_real(s7_scheme *sc, s7_pointer args) {return(s7_gsl_r_c(sc, s7_car(args), gsl_complex_arccsc_real));} static s7_pointer g_gsl_complex_arccosh_real(s7_scheme *sc, s7_pointer args) {return(s7_gsl_r_c(sc, s7_car(args), gsl_complex_arccosh_real));} static s7_pointer g_gsl_complex_arctanh_real(s7_scheme *sc, s7_pointer args) {return(s7_gsl_r_c(sc, s7_car(args), gsl_complex_arctanh_real));} static s7_pointer g_gsl_complex_add(s7_scheme *sc, s7_pointer args) {return(s7_gsl_cc_c(sc, s7_car(args), s7_cadr(args), gsl_complex_add));} static s7_pointer g_gsl_complex_sub(s7_scheme *sc, s7_pointer args) {return(s7_gsl_cc_c(sc, s7_car(args), s7_cadr(args), gsl_complex_sub));} static s7_pointer g_gsl_complex_mul(s7_scheme *sc, s7_pointer args) {return(s7_gsl_cc_c(sc, s7_car(args), s7_cadr(args), gsl_complex_mul));} static s7_pointer g_gsl_complex_div(s7_scheme *sc, s7_pointer args) {return(s7_gsl_cc_c(sc, s7_car(args), s7_cadr(args), gsl_complex_div));} static s7_pointer g_gsl_complex_log_b(s7_scheme *sc, s7_pointer args) {return(s7_gsl_cc_c(sc, s7_car(args), s7_cadr(args), gsl_complex_log_b));} static s7_pointer g_gsl_complex_pow(s7_scheme *sc, s7_pointer args) {return(s7_gsl_cc_c(sc, s7_car(args), s7_cadr(args), gsl_complex_pow));} static s7_pointer g_gsl_complex_add_real(s7_scheme *sc, s7_pointer args) {return(s7_gsl_cr_c(sc, s7_car(args), s7_cadr(args), gsl_complex_add_real));} static s7_pointer g_gsl_complex_sub_real(s7_scheme *sc, s7_pointer args) {return(s7_gsl_cr_c(sc, s7_car(args), s7_cadr(args), gsl_complex_sub_real));} static s7_pointer g_gsl_complex_mul_real(s7_scheme *sc, s7_pointer args) {return(s7_gsl_cr_c(sc, s7_car(args), s7_cadr(args), gsl_complex_mul_real));} static s7_pointer g_gsl_complex_div_real(s7_scheme *sc, s7_pointer args) {return(s7_gsl_cr_c(sc, s7_car(args), s7_cadr(args), gsl_complex_div_real));} static s7_pointer g_gsl_complex_add_imag(s7_scheme *sc, s7_pointer args) {return(s7_gsl_cr_c(sc, s7_car(args), s7_cadr(args), gsl_complex_add_imag));} static s7_pointer g_gsl_complex_sub_imag(s7_scheme *sc, s7_pointer args) {return(s7_gsl_cr_c(sc, s7_car(args), s7_cadr(args), gsl_complex_sub_imag));} static s7_pointer g_gsl_complex_mul_imag(s7_scheme *sc, s7_pointer args) {return(s7_gsl_cr_c(sc, s7_car(args), s7_cadr(args), gsl_complex_mul_imag));} static s7_pointer g_gsl_complex_div_imag(s7_scheme *sc, s7_pointer args) {return(s7_gsl_cr_c(sc, s7_car(args), s7_cadr(args), gsl_complex_div_imag));} static s7_pointer g_gsl_complex_pow_real(s7_scheme *sc, s7_pointer args) {return(s7_gsl_cr_c(sc, s7_car(args), s7_cadr(args), gsl_complex_pow_real));} ") (C-function ("gsl_complex_arg" g_gsl_complex_arg "" 1)) (C-function ("gsl_complex_abs" g_gsl_complex_abs "" 1)) (C-function ("gsl_complex_abs2" g_gsl_complex_abs2 "" 1)) (C-function ("gsl_complex_logabs" g_gsl_complex_logabs "" 1)) (C-function ("gsl_complex_conjugate" g_gsl_complex_conjugate "" 1)) (C-function ("gsl_complex_inverse" g_gsl_complex_inverse "" 1)) (C-function ("gsl_complex_negative" g_gsl_complex_negative "" 1)) (C-function ("gsl_complex_sqrt" g_gsl_complex_sqrt "" 1)) (C-function ("gsl_complex_exp" g_gsl_complex_exp "" 1)) (C-function ("gsl_complex_log" g_gsl_complex_log "" 1)) (C-function ("gsl_complex_log10" g_gsl_complex_log10 "" 1)) (C-function ("gsl_complex_sin" g_gsl_complex_sin "" 1)) (C-function ("gsl_complex_cos" g_gsl_complex_cos "" 1)) (C-function ("gsl_complex_sec" g_gsl_complex_sec "" 1)) (C-function ("gsl_complex_csc" g_gsl_complex_csc "" 1)) (C-function ("gsl_complex_tan" g_gsl_complex_tan "" 1)) (C-function ("gsl_complex_cot" g_gsl_complex_cot "" 1)) (C-function ("gsl_complex_sinh" g_gsl_complex_sinh "" 1)) (C-function ("gsl_complex_cosh" g_gsl_complex_cosh "" 1)) (C-function ("gsl_complex_sech" g_gsl_complex_sech "" 1)) (C-function ("gsl_complex_csch" g_gsl_complex_csch "" 1)) (C-function ("gsl_complex_tanh" g_gsl_complex_tanh "" 1)) (C-function ("gsl_complex_coth" g_gsl_complex_coth "" 1)) (C-function ("gsl_complex_arctan" g_gsl_complex_arctan "" 1)) (C-function ("gsl_complex_arccot" g_gsl_complex_arccot "" 1)) (C-function ("gsl_complex_arcsinh" g_gsl_complex_arcsinh "" 1)) (C-function ("gsl_complex_arcsech" g_gsl_complex_arcsech "" 1)) (C-function ("gsl_complex_arccsch" g_gsl_complex_arccsch "" 1)) (C-function ("gsl_complex_arccoth" g_gsl_complex_arccoth "" 1)) (C-function ("gsl_complex_arcsin" g_gsl_complex_arcsin "" 1)) (C-function ("gsl_complex_arccos" g_gsl_complex_arccos "" 1)) (C-function ("gsl_complex_arcsec" g_gsl_complex_arcsec "" 1)) (C-function ("gsl_complex_arccsc" g_gsl_complex_arccsc "" 1)) (C-function ("gsl_complex_arccosh" g_gsl_complex_arccosh "" 1)) (C-function ("gsl_complex_arctanh" g_gsl_complex_arctanh "" 1)) (C-function ("gsl_complex_sqrt_real" g_gsl_complex_sqrt_real "" 1)) (C-function ("gsl_complex_arcsin_real" g_gsl_complex_arcsin_real "" 1)) (C-function ("gsl_complex_arccos_real" g_gsl_complex_arccos_real "" 1)) (C-function ("gsl_complex_arcsec_real" g_gsl_complex_arcsec_real "" 1)) (C-function ("gsl_complex_arccsc_real" g_gsl_complex_arccsc_real "" 1)) (C-function ("gsl_complex_arccosh_real" g_gsl_complex_arccosh_real "" 1)) (C-function ("gsl_complex_arctanh_real" g_gsl_complex_arctanh_real "" 1)) (C-function ("gsl_complex_add" g_gsl_complex_add "" 2)) (C-function ("gsl_complex_sub" g_gsl_complex_sub "" 2)) (C-function ("gsl_complex_mul" g_gsl_complex_mul "" 2)) (C-function ("gsl_complex_div" g_gsl_complex_div "" 2)) (C-function ("gsl_complex_log_b" g_gsl_complex_log_b "" 2)) (C-function ("gsl_complex_pow" g_gsl_complex_pow "" 2)) (C-function ("gsl_complex_add_real" g_gsl_complex_add_real "" 2)) (C-function ("gsl_complex_sub_real" g_gsl_complex_sub_real "" 2)) (C-function ("gsl_complex_mul_real" g_gsl_complex_mul_real "" 2)) (C-function ("gsl_complex_div_real" g_gsl_complex_div_real "" 2)) (C-function ("gsl_complex_add_imag" g_gsl_complex_add_imag "" 2)) (C-function ("gsl_complex_sub_imag" g_gsl_complex_sub_imag "" 2)) (C-function ("gsl_complex_mul_imag" g_gsl_complex_mul_imag "" 2)) (C-function ("gsl_complex_div_imag" g_gsl_complex_div_imag "" 2)) (C-function ("gsl_complex_pow_real" g_gsl_complex_pow_real "" 2)) ;; cheb (gsl_cheb_series* gsl_cheb_alloc (size_t)) (void gsl_cheb_free (gsl_cheb_series*)) (size_t gsl_cheb_order (gsl_cheb_series*)) (size_t gsl_cheb_size (gsl_cheb_series*)) (double* gsl_cheb_coeffs (gsl_cheb_series*)) (double gsl_cheb_eval (gsl_cheb_series* double)) (int gsl_cheb_eval_err (gsl_cheb_series* double double* double*)) (double gsl_cheb_eval_n (gsl_cheb_series* size_t double)) (int gsl_cheb_eval_n_err (gsl_cheb_series* size_t double double* double*)) (double gsl_cheb_eval_mode (gsl_cheb_series* double int)) (int gsl_cheb_eval_mode_e (gsl_cheb_series* double int double* double*)) (int gsl_cheb_calc_deriv (gsl_cheb_series* gsl_cheb_series*)) (int gsl_cheb_calc_integ (gsl_cheb_series* gsl_cheb_series*)) ;; gsl_function is a struct with double function(double void*) and void* params (in-C "static s7_scheme *gsl_f_s7; static gsl_function gsl_f; static double gsl_f_caller(double x, void *p) { return(s7_real(s7_call(gsl_f_s7, (s7_pointer)p, s7_cons(gsl_f_s7, s7_make_real(gsl_f_s7, x), s7_nil(gsl_f_s7))))); } #define make_gsl_function(Args) do {gsl_f.function = gsl_f_caller; gsl_f.params = (void *)Args; gsl_f_s7 = sc;} while (0) static s7_pointer g_gsl_cheb_init(s7_scheme *sc, s7_pointer args) { make_gsl_function(s7_cadr(args)); return(s7_make_integer(sc, gsl_cheb_init((gsl_cheb_series *)s7_c_pointer(s7_car(args)), &gsl_f, s7_real(s7_caddr(args)), s7_real(s7_cadddr(args))))); } ") (C-function ("gsl_cheb_init" g_gsl_cheb_init "" 4)) ;; interp (gsl_interp_accel* gsl_interp_accel_alloc (void)) (int gsl_interp_accel_reset (gsl_interp_accel*)) (void gsl_interp_accel_free (gsl_interp_accel*)) (gsl_interp* gsl_interp_alloc (gsl_interp_type* size_t)) (int gsl_interp_init (gsl_interp* double* double* size_t)) (char* gsl_interp_name (gsl_interp*)) (int gsl_interp_min_size (gsl_interp*)) (reader-cond ((>= gsl-version 1.15) (int gsl_interp_type_min_size (gsl_interp_type*)))) (int gsl_interp_eval_e (gsl_interp* double* double* double gsl_interp_accel* double*)) (double gsl_interp_eval (gsl_interp* double* double* double gsl_interp_accel*)) (int gsl_interp_eval_deriv_e (gsl_interp* double* double* double gsl_interp_accel* double*)) (double gsl_interp_eval_deriv (gsl_interp* double* double* double gsl_interp_accel*)) (int gsl_interp_eval_deriv2_e (gsl_interp* double* double* double gsl_interp_accel* double*)) (double gsl_interp_eval_deriv2 (gsl_interp* double* double* double gsl_interp_accel*)) (int gsl_interp_eval_integ_e (gsl_interp* double* double* double double gsl_interp_accel* double*)) (double gsl_interp_eval_integ (gsl_interp* double* double* double double gsl_interp_accel*)) (void gsl_interp_free (gsl_interp*)) (size_t gsl_interp_bsearch (double* double size_t size_t)) (size_t gsl_interp_accel_find (gsl_interp_accel* double* size_t double)) ;; spline (based on interp above) (gsl_spline* gsl_spline_alloc (gsl_interp_type* size_t)) (int gsl_spline_init (gsl_spline* double* double* size_t)) (char* gsl_spline_name (gsl_spline*)) (int gsl_spline_min_size (gsl_spline*)) (int gsl_spline_eval_e (gsl_spline* double gsl_interp_accel* double*)) (double gsl_spline_eval (gsl_spline* double gsl_interp_accel*)) (int gsl_spline_eval_deriv_e (gsl_spline* double gsl_interp_accel* double*)) (double gsl_spline_eval_deriv (gsl_spline* double gsl_interp_accel*)) (int gsl_spline_eval_deriv2_e (gsl_spline* double gsl_interp_accel* double*)) (double gsl_spline_eval_deriv2 (gsl_spline* double gsl_interp_accel*)) (int gsl_spline_eval_integ_e (gsl_spline* double double gsl_interp_accel* double*)) (double gsl_spline_eval_integ (gsl_spline* double double gsl_interp_accel*)) (void gsl_spline_free (gsl_spline*)) ;; bspline (gsl_bspline_workspace* gsl_bspline_alloc (size_t size_t)) (void gsl_bspline_free (gsl_bspline_workspace*)) (size_t gsl_bspline_ncoeffs (gsl_bspline_workspace*)) (size_t gsl_bspline_order (gsl_bspline_workspace*)) (size_t gsl_bspline_nbreak (gsl_bspline_workspace*)) (double gsl_bspline_breakpoint (size_t gsl_bspline_workspace*)) (reader-cond ((>= gsl-version 1.16) (double gsl_bspline_greville_abscissa (size_t gsl_bspline_workspace*)) (int gsl_bspline_knots_greville (gsl_vector* gsl_bspline_workspace* double*)))) (int gsl_bspline_knots (gsl_vector* gsl_bspline_workspace*)) (int gsl_bspline_knots_uniform (double double gsl_bspline_workspace*)) (int gsl_bspline_eval (double gsl_vector* gsl_bspline_workspace*)) (int gsl_bspline_eval_nonzero (double gsl_vector* size_t* size_t* gsl_bspline_workspace*)) ;;; out 2.0 (gsl_bspline_deriv_workspace* gsl_bspline_deriv_alloc (size_t)) ;;; out 2.0 (void gsl_bspline_deriv_free (gsl_bspline_deriv_workspace*)) (reader-cond ((>= gsl-version 2.0) (int gsl_bspline_deriv_eval (double size_t gsl_matrix* gsl_bspline_workspace*)) (int gsl_bspline_deriv_eval_nonzero (double size_t gsl_matrix* size_t* size_t* gsl_bspline_workspace*)))) ;; sort ;; perhaps size_t* -> int vector? (void gsl_sort (double* size_t size_t)) (reader-cond ((>= gsl-version 1.16) (void gsl_sort2 (double* size_t double* size_t size_t)) (void gsl_sort_vector2 (gsl_vector* gsl_vector*)) (int gsl_poly_dd_hermite_init (double* double* double* double* double* size_t)))) (void gsl_sort_index (size_t* double* size_t size_t)) (int gsl_sort_smallest (double* size_t double* size_t size_t)) (int gsl_sort_smallest_index (size_t* size_t double* size_t size_t)) (int gsl_sort_largest (double* size_t double* size_t size_t)) (int gsl_sort_largest_index (size_t* size_t double* size_t size_t)) (void gsl_sort_vector (gsl_vector*)) (int gsl_sort_vector_index (gsl_permutation* gsl_vector*)) (int gsl_sort_vector_smallest (double* size_t gsl_vector*)) (int gsl_sort_vector_largest (double* size_t gsl_vector*)) (int gsl_sort_vector_smallest_index (size_t* size_t gsl_vector*)) (int gsl_sort_vector_largest_index (size_t* size_t gsl_vector*)) ;; poly (double gsl_poly_eval (double* int double)) (int gsl_poly_eval_derivs (double* size_t double double* size_t)) (int gsl_poly_dd_init (double* double* double* size_t)) (double gsl_poly_dd_eval (double* double* size_t double)) (int gsl_poly_dd_taylor (double* double double* double* size_t double*)) (void gsl_poly_complex_workspace_free (gsl_poly_complex_workspace*)) (gsl_poly_complex_workspace* gsl_poly_complex_workspace_alloc (size_t)) (in-C "static s7_pointer g_gsl_poly_complex_eval(s7_scheme *sc, s7_pointer args) { gsl_complex z, rz; S7_TO_GSL_COMPLEX(s7_caddr(args), z); rz = gsl_poly_complex_eval((double *)s7_c_pointer(s7_car(args)), (int)s7_integer(s7_cadr(args)), z); return(GSL_TO_S7_COMPLEX(sc, rz)); } static s7_pointer g_gsl_complex_poly_complex_eval(s7_scheme *sc, s7_pointer args) { gsl_complex *z; gsl_complex rz, x; int i, n; s7_pointer v; v = s7_car(args); n = s7_integer(s7_cadr(args)); z = (gsl_complex *)calloc(n, sizeof(gsl_complex)); for (i = 0; i < n; i++) S7_TO_GSL_COMPLEX(s7_vector_ref(sc, v, i), z[i]); S7_TO_GSL_COMPLEX(s7_caddr(args), x); rz = gsl_complex_poly_complex_eval(z, n, x); free(z); return(GSL_TO_S7_COMPLEX(sc, rz)); } static s7_pointer g_gsl_poly_complex_solve_quadratic(s7_scheme *sc, s7_pointer args) { gsl_complex z0, z1; int result; s7_pointer res; res = s7_cadddr(args); result = gsl_poly_complex_solve_quadratic(s7_number_to_real(sc, s7_car(args)), s7_number_to_real(sc, s7_cadr(args)), s7_number_to_real(sc, s7_caddr(args)), &z0, &z1); s7_vector_set(sc, res, 0, GSL_TO_S7_COMPLEX(sc, z0)); s7_vector_set(sc, res, 1, GSL_TO_S7_COMPLEX(sc, z1)); return(s7_make_integer(sc, result)); } static s7_pointer g_gsl_poly_complex_solve_cubic(s7_scheme *sc, s7_pointer args) { /* trailing args are by ref, but I think I'll mimic the real solver above */ gsl_complex z0, z1, z2; int result; s7_pointer res; result = gsl_poly_complex_solve_cubic(s7_number_to_real(sc, s7_car(args)), s7_number_to_real(sc, s7_cadr(args)), s7_number_to_real(sc, s7_caddr(args)), &z0, &z1, &z2); res = s7_cadddr(args); s7_vector_set(sc, res, 0, GSL_TO_S7_COMPLEX(sc, z0)); s7_vector_set(sc, res, 1, GSL_TO_S7_COMPLEX(sc, z1)); s7_vector_set(sc, res, 2, GSL_TO_S7_COMPLEX(sc, z2)); return(s7_make_integer(sc, result)); } static s7_pointer g_gsl_poly_complex_solve(s7_scheme *sc, s7_pointer args) { /* trailing args are by ref, but I think I'll mimic the real solver above */ double *z; gsl_poly_complex_workspace *w; int result, i, size; s7_pointer res; size = s7_integer(s7_cadr(args)); res = s7_caddr(args); z = (double *)calloc(size * 2, sizeof(double)); w = gsl_poly_complex_workspace_alloc(size); result = gsl_poly_complex_solve((double *)s7_c_pointer(s7_car(args)), size, w, (gsl_complex_packed_ptr)z); gsl_poly_complex_workspace_free(w); for (i = 0; i < size - 1; i++) s7_vector_set(sc, res, i, s7_make_complex(sc, z[2 * i], z[2 * i + 1])); free(z); return(s7_make_integer(sc, result)); } static s7_pointer g_gsl_poly_solve_quadratic(s7_scheme *sc, s7_pointer args) { double x0, x1; int result; double *res; res = (double *)s7_c_pointer(s7_cadddr(args)); result = gsl_poly_solve_quadratic(s7_number_to_real(sc, s7_car(args)), s7_number_to_real(sc, s7_cadr(args)), s7_number_to_real(sc, s7_caddr(args)), &x0, &x1); res[0] = x0; res[1] = x1; return(s7_make_integer(sc, result)); } static s7_pointer g_gsl_poly_solve_cubic(s7_scheme *sc, s7_pointer args) { double x0, x1, x2; int result; double *res; res = (double *)s7_c_pointer(s7_cadddr(args)); result = gsl_poly_solve_cubic(s7_number_to_real(sc, s7_car(args)), s7_number_to_real(sc, s7_cadr(args)), s7_number_to_real(sc, s7_caddr(args)), &x0, &x1, &x2); res[0] = x0; res[1] = x1; res[2] = x2; return(s7_make_integer(sc, result)); } ") (C-function ("gsl_poly_complex_eval" g_gsl_poly_complex_eval "" 3)) (C-function ("gsl_complex_poly_complex_eval" g_gsl_complex_poly_complex_eval "" 3)) (C-function ("gsl_poly_complex_solve_quadratic" g_gsl_poly_complex_solve_quadratic "" 4)) (C-function ("gsl_poly_complex_solve_cubic" g_gsl_poly_complex_solve_cubic "" 4)) (C-function ("gsl_poly_complex_solve" g_gsl_poly_complex_solve "" 3)) (C-function ("gsl_poly_solve_quadratic" g_gsl_poly_solve_quadratic "" 4)) (C-function ("gsl_poly_solve_cubic" g_gsl_poly_solve_cubic "" 4)) ;; vector (in-C "static s7_pointer g_float_vector_to_gsl_vector(s7_scheme *sc, s7_pointer args) { gsl_vector *g; int size; s7_pointer v; v = s7_car(args); size = s7_vector_length(v); g = (gsl_vector *)s7_c_pointer(s7_cadr(args)); memcpy((void *)(g->data), (void *)s7_float_vector_elements(v), size * sizeof(double)); return(s7_cadr(args)); } static s7_pointer g_gsl_vector_to_float_vector(s7_scheme *sc, s7_pointer args) { gsl_vector *g; int size; s7_pointer v; v = s7_cadr(args); size = s7_vector_length(v); g = (gsl_vector *)s7_c_pointer(s7_car(args)); memcpy((void *)s7_float_vector_elements(v), (void *)(g->data), size * sizeof(double)); return(s7_cadr(args)); } ") (C-function ("float-vector->gsl_vector" g_float_vector_to_gsl_vector "" 2)) (C-function ("gsl_vector->float-vector" g_gsl_vector_to_float_vector "" 2)) (gsl_vector* gsl_vector_alloc (size_t)) (gsl_vector* gsl_vector_calloc (size_t)) (gsl_vector* gsl_vector_alloc_from_vector (gsl_vector* size_t size_t size_t)) (void gsl_vector_free (gsl_vector*)) (void gsl_vector_set_zero (gsl_vector*)) (void gsl_vector_set_all (gsl_vector* double)) (int gsl_vector_set_basis (gsl_vector* size_t)) (int gsl_vector_fread (FILE* gsl_vector*)) (int gsl_vector_fwrite (FILE* gsl_vector*)) (int gsl_vector_fscanf (FILE* gsl_vector*)) (int gsl_vector_fprintf (FILE* gsl_vector* char*)) (int gsl_vector_memcpy (gsl_vector* gsl_vector*)) (int gsl_vector_reverse (gsl_vector*)) (int gsl_vector_swap (gsl_vector* gsl_vector*)) (int gsl_vector_swap_elements (gsl_vector* size_t size_t)) (double gsl_vector_max (gsl_vector*)) (double gsl_vector_min (gsl_vector*)) (size_t gsl_vector_max_index (gsl_vector*)) (size_t gsl_vector_min_index (gsl_vector*)) (int gsl_vector_add (gsl_vector* gsl_vector*)) (int gsl_vector_sub (gsl_vector* gsl_vector*)) (int gsl_vector_mul (gsl_vector* gsl_vector*)) (int gsl_vector_div (gsl_vector* gsl_vector*)) (int gsl_vector_scale (gsl_vector* double)) (int gsl_vector_add_constant (gsl_vector* double)) (reader-cond ((>= gsl-version 1.15) (int gsl_vector_equal (gsl_vector* gsl_vector*)))) (int gsl_vector_isnull (gsl_vector*)) (int gsl_vector_ispos (gsl_vector*)) (int gsl_vector_isneg (gsl_vector*)) (int gsl_vector_isnonneg (gsl_vector*)) (double gsl_vector_get (gsl_vector* size_t)) (void gsl_vector_set (gsl_vector* size_t double)) (double* gsl_vector_ptr (gsl_vector* size_t)) (double* gsl_vector_const_ptr (gsl_vector* size_t)) (void gsl_vector_minmax (gsl_vector* double* double*)) ; by ref (void gsl_vector_minmax_index (gsl_vector* size_t* size_t*)) ; by ref ;; matrix (in-C "static s7_pointer g_float_vector_to_gsl_matrix(s7_scheme *sc, s7_pointer args) { gsl_matrix *g; int size; s7_pointer v; v = s7_car(args); size = s7_vector_length(v); g = (gsl_matrix *)s7_c_pointer(s7_cadr(args)); memcpy((void *)(g->data), (void *)s7_float_vector_elements(v), size * sizeof(double)); return(s7_cadr(args)); } static s7_pointer g_gsl_matrix_to_float_vector(s7_scheme *sc, s7_pointer args) { gsl_matrix *g; int size; s7_pointer v; v = s7_cadr(args); size = s7_vector_length(v); g = (gsl_matrix *)s7_c_pointer(s7_car(args)); memcpy((void *)s7_float_vector_elements(v), (void *)(g->data), size * sizeof(double)); return(s7_cadr(args)); } ") (C-function ("float-vector->gsl_matrix" g_float_vector_to_gsl_matrix "" 2)) (C-function ("gsl_matrix->float-vector" g_gsl_matrix_to_float_vector "" 2)) (gsl_matrix* gsl_matrix_alloc (size_t size_t)) (gsl_matrix* gsl_matrix_calloc (size_t size_t)) (gsl_matrix* gsl_matrix_alloc_from_matrix (gsl_matrix* size_t size_t size_t size_t)) (gsl_vector* gsl_vector_alloc_row_from_matrix (gsl_matrix* size_t)) (gsl_vector* gsl_vector_alloc_col_from_matrix (gsl_matrix* size_t)) (void gsl_matrix_free (gsl_matrix*)) (void gsl_matrix_set_zero (gsl_matrix*)) (void gsl_matrix_set_identity (gsl_matrix*)) (void gsl_matrix_set_all (gsl_matrix* double)) (int gsl_matrix_fread (FILE* gsl_matrix*) ) (int gsl_matrix_fwrite (FILE* gsl_matrix*) ) (int gsl_matrix_fscanf (FILE* gsl_matrix*)) (int gsl_matrix_fprintf (FILE* gsl_matrix* char*)) (int gsl_matrix_memcpy (gsl_matrix* gsl_matrix*)) (int gsl_matrix_swap (gsl_matrix* gsl_matrix*)) (int gsl_matrix_swap_rows (gsl_matrix* size_t size_t)) (int gsl_matrix_swap_columns (gsl_matrix* size_t size_t)) (int gsl_matrix_swap_rowcol (gsl_matrix* size_t size_t)) (int gsl_matrix_transpose (gsl_matrix*)) (int gsl_matrix_transpose_memcpy (gsl_matrix* gsl_matrix*)) (double gsl_matrix_max (gsl_matrix*)) (double gsl_matrix_min (gsl_matrix*)) (void gsl_matrix_minmax (gsl_matrix* double* double*)) (void gsl_matrix_max_index (gsl_matrix* size_t* size_t*)) (void gsl_matrix_min_index (gsl_matrix* size_t* size_t*)) (void gsl_matrix_minmax_index (gsl_matrix* size_t* size_t* size_t* size_t*)) (reader-cond ((>= gsl-version 1.15) (int gsl_matrix_equal (gsl_matrix* gsl_matrix*)))) (int gsl_matrix_isnull (gsl_matrix*)) (int gsl_matrix_ispos (gsl_matrix*)) (int gsl_matrix_isneg (gsl_matrix*)) (int gsl_matrix_isnonneg (gsl_matrix*)) (int gsl_matrix_add (gsl_matrix* gsl_matrix*)) (int gsl_matrix_sub (gsl_matrix* gsl_matrix*)) (int gsl_matrix_mul_elements (gsl_matrix* gsl_matrix*)) (int gsl_matrix_div_elements (gsl_matrix* gsl_matrix*)) (int gsl_matrix_scale (gsl_matrix* double)) (int gsl_matrix_add_constant (gsl_matrix* double)) (int gsl_matrix_add_diagonal (gsl_matrix* double)) (int gsl_matrix_get_row (gsl_vector* gsl_matrix* size_t)) (int gsl_matrix_get_col (gsl_vector* gsl_matrix* size_t)) (int gsl_matrix_set_row (gsl_matrix* size_t gsl_vector*)) (int gsl_matrix_set_col (gsl_matrix* size_t gsl_vector*)) (double gsl_matrix_get (gsl_matrix* size_t size_t)) (void gsl_matrix_set (gsl_matrix* size_t size_t double)) (double* gsl_matrix_ptr (gsl_matrix* size_t size_t)) (double* gsl_matrix_const_ptr (gsl_matrix* size_t size_t)) (in-C "static s7_pointer g_gsl_matrix_size(s7_scheme *sc, s7_pointer args) { gsl_matrix *g; g = (gsl_matrix *)s7_c_pointer(s7_car(args)); return(s7_cons(sc, s7_make_integer(sc, (s7_int)(g->size1)), s7_make_integer(sc, (s7_int)(g->size2)))); }") (C-function ("gsl_matrix_size" g_gsl_matrix_size "" 1)) ;; cblas (int gsl_blas_zdotu (gsl_vector_complex* gsl_vector_complex* gsl_complex*)) (int gsl_blas_zdotc (gsl_vector_complex* gsl_vector_complex* gsl_complex*)) (double gsl_blas_dnrm2 (gsl_vector*)) (double gsl_blas_dasum (gsl_vector*)) (double gsl_blas_dznrm2 (gsl_vector_complex*)) (double gsl_blas_dzasum (gsl_vector_complex*)) (size_t_t gsl_blas_idamax (gsl_vector*)) (size_t_t gsl_blas_izamax (gsl_vector_complex*)) (int gsl_blas_dswap (gsl_vector* gsl_vector*)) (int gsl_blas_dcopy (gsl_vector* gsl_vector*)) (int gsl_blas_daxpy (double gsl_vector* gsl_vector*)) (int gsl_blas_zswap (gsl_vector_complex* gsl_vector_complex*)) (int gsl_blas_zcopy (gsl_vector_complex* gsl_vector_complex*)) (int gsl_blas_drotg (double* double* double* double*)) (int gsl_blas_drotmg (double* double* double* double double*)) (int gsl_blas_drot (gsl_vector* gsl_vector* double double)) (int gsl_blas_drotm (gsl_vector* gsl_vector* double*)) (void gsl_blas_dscal (double gsl_vector*)) (void gsl_blas_zdscal (double gsl_vector_complex*)) (int gsl_blas_dgemv (int double gsl_matrix* gsl_vector* double gsl_vector*)) (int gsl_blas_dtrmv (int int int gsl_matrix* gsl_vector*)) (int gsl_blas_dtrsv (int int int gsl_matrix* gsl_vector*)) (int gsl_blas_ztrmv (int int int gsl_matrix_complex* gsl_vector_complex*)) (int gsl_blas_ztrsv (int int int gsl_matrix_complex* gsl_vector_complex*)) (int gsl_blas_dsymv (int double gsl_matrix* gsl_vector* double gsl_vector*)) (int gsl_blas_dger (double gsl_vector* gsl_vector* gsl_matrix*)) (int gsl_blas_dsyr (int double gsl_vector* gsl_matrix*)) (int gsl_blas_dsyr2 (int double gsl_vector* gsl_vector* gsl_matrix*)) (int gsl_blas_zher (int double gsl_vector_complex* gsl_matrix_complex*)) (int gsl_blas_dgemm (int int double gsl_matrix* gsl_matrix* double gsl_matrix*)) (int gsl_blas_dsymm (int int double gsl_matrix* gsl_matrix* double gsl_matrix*)) (int gsl_blas_dsyrk (int int double gsl_matrix* double gsl_matrix*)) (int gsl_blas_dsyr2k (int int double gsl_matrix* gsl_matrix* double gsl_matrix*)) (int gsl_blas_dtrmm (int int int int double gsl_matrix* gsl_matrix*)) (int gsl_blas_dtrsm (int int int int double gsl_matrix* gsl_matrix*)) (int gsl_blas_zherk (int int double gsl_matrix_complex* double gsl_matrix_complex*)) (double cblas_ddot (int double* int double* int)) (void cblas_zdotu_sub (int double* int double* int double*)) (void cblas_zdotc_sub (int double* int double* int double*)) (double cblas_dnrm2 (int double* int)) (double cblas_dasum (int double* int)) (double cblas_dznrm2 (int void* int)) (double cblas_dzasum (int void* int)) (size_t cblas_idamax (int double* int)) (size_t cblas_icamax (int void* int)) (size_t cblas_izamax (int void* int)) (void cblas_dswap (int double* int double* int)) (void cblas_dcopy (int double* int double* int)) (void cblas_daxpy (int double double* int double* int)) (void cblas_zswap (int double* int double* int)) (void cblas_zcopy (int double* int double* int)) (void cblas_zaxpy (int double* double* int double* int)) (void cblas_drotg (double* double* double* double*)) (void cblas_drotmg (double* double* double* double double*)) (void cblas_drot (int double* int double* int double double)) (void cblas_drotm (int double* int double* int double*)) (void cblas_dscal (int double double* int)) (void cblas_zscal (int double* double* int)) (void cblas_zdscal (int double double* int)) (void cblas_dgemv (int int int int double double* int double* int double double* int)) (void cblas_dgbmv (int int int int int int double double* int double* int double double* int)) (void cblas_dtrmv (int int int int int double* int double* int)) (void cblas_dtbmv (int int int int int int double* int double* int)) (void cblas_dtpmv (int int int int int double* double* int)) (void cblas_dtrsv (int int int int int double* int double* int)) (void cblas_dtbsv (int int int int int int double* int double* int)) (void cblas_dtpsv (int int int int int double* double* int)) (void cblas_zgemv (int int int int double* double* int double* int double* double* int)) (void cblas_zgbmv (int int int int int int double* double* int double* int double* double* int)) (void cblas_ztrmv (int int int int int double* int double* int)) (void cblas_ztbmv (int int int int int int double* int double* int)) (void cblas_ztpmv (int int int int int double* double* int)) (void cblas_ztrsv (int int int int int double* int double* int)) (void cblas_ztbsv (int int int int int int double* int double* int)) (void cblas_ztpsv (int int int int int double* double* int)) (void cblas_dsymv (int int int double double* int double* int double double* int)) (void cblas_dsbmv (int int int int double double* int double* int double double* int)) (void cblas_dspmv (int int int double double* double* int double double* int)) (void cblas_dger (int int int double double* int double* int double* int)) (void cblas_dsyr (int int int double double* int double* int)) (void cblas_dspr (int int int double double* int double*)) (void cblas_dsyr2 (int int int double double* int double* int double* int)) (void cblas_dspr2 (int int int double double* int double* int double*)) (void cblas_zhemv (int int int double* double* int double* int double* double* int)) (void cblas_zhbmv (int int int int double* double* int double* int double* double* int)) (void cblas_zhpmv (int int int double* double* double* int double* double* int)) (void cblas_zgeru (int int int double* double* int double* int double* int)) (void cblas_zgerc (int int int double* double* int double* int double* int)) (void cblas_zher (int int int double double* int double* int)) (void cblas_zhpr (int int int double double* int double*)) (void cblas_zher2 (int int int double* double* int double* int double* int)) (void cblas_zhpr2 (int int int double* double* int double* int double*)) (void cblas_dgemm (int int int int int int double double* int double* int double double* int)) (void cblas_dsymm (int int int int int double double* int double* int double double* int)) (void cblas_dsyrk (int int int int int double double* int double double* int)) (void cblas_dsyr2k (int int int int int double double* int double* int double double* int)) (void cblas_dtrmm (int int int int int int int double double* int double* int)) (void cblas_dtrsm (int int int int int int int double double* int double* int)) (void cblas_zgemm (int int int int int int double* double* int double* int double* double* int)) (void cblas_zsymm (int int int int int double* double* int double* int double* double* int)) (void cblas_zsyrk (int int int int int double* double* int double* double* int)) (void cblas_zsyr2k (int int int int int double* double* int double* int double* double* int)) (void cblas_ztrmm (int int int int int int int double* double* int double* int)) (void cblas_ztrsm (int int int int int int int double* double* int double* int)) (void cblas_zhemm (int int int int int double* double* int double* int double* double* int)) (void cblas_zherk (int int int int int double double* int double double* int)) (void cblas_zher2k (int int int int int double* double* int double* int double double* int)) ;; combination (gsl_combination* gsl_combination_alloc (size_t size_t)) (gsl_combination* gsl_combination_calloc (size_t size_t)) (void gsl_combination_init_first (gsl_combination*)) (void gsl_combination_init_last (gsl_combination*)) (void gsl_combination_free (gsl_combination*)) (int gsl_combination_memcpy (gsl_combination* gsl_combination*) ) (int gsl_combination_fread (FILE* gsl_combination*)) (int gsl_combination_fwrite (FILE* gsl_combination*)) (int gsl_combination_fscanf (FILE* gsl_combination*)) (int gsl_combination_fprintf (FILE* gsl_combination* char*)) (size_t gsl_combination_n (gsl_combination*)) (size_t gsl_combination_k (gsl_combination*)) ;(size_t* gsl_combination_data (gsl_combination*)) (int gsl_combination_valid (gsl_combination*)) (int gsl_combination_next (gsl_combination*)) (int gsl_combination_prev (gsl_combination*)) (size_t gsl_combination_get (gsl_combination* size_t)) (in-C "static s7_pointer g_gsl_combination_to_int_vector(s7_scheme *sc, s7_pointer args) { gsl_combination *g; int i, size; s7_int *el; s7_pointer v; v = s7_cadr(args); size = s7_vector_length(v); g = (gsl_combination *)s7_c_pointer(s7_car(args)); el = s7_int_vector_elements(v); for (i = 0; i < size; i++) el[i] = (s7_int)(g->data[i]); return(s7_cadr(args)); } ") (C-function ("gsl_combination->int-vector" g_gsl_combination_to_int_vector "" 2)) ;; rl+im for complex in most of these cases (int gsl_dft_complex_forward (double* size_t size_t double*)) (int gsl_dft_complex_backward (double* size_t size_t double*)) (int gsl_dft_complex_inverse (double* size_t size_t double*)) (int gsl_dft_complex_transform (double* size_t size_t double* int)) (int gsl_fft_complex_radix2_forward (double* size_t size_t)) (int gsl_fft_complex_radix2_backward (double* size_t size_t)) (int gsl_fft_complex_radix2_inverse (double* size_t size_t)) (int gsl_fft_complex_radix2_transform (double* size_t size_t int)) (int gsl_fft_complex_radix2_dif_forward (double* size_t size_t)) (int gsl_fft_complex_radix2_dif_backward (double* size_t size_t)) (int gsl_fft_complex_radix2_dif_inverse (double* size_t size_t)) (int gsl_fft_complex_radix2_dif_transform (double* size_t size_t int)) (gsl_fft_complex_wavetable* gsl_fft_complex_wavetable_alloc (size_t)) (void gsl_fft_complex_wavetable_free (gsl_fft_complex_wavetable*)) (gsl_fft_complex_workspace* gsl_fft_complex_workspace_alloc (size_t)) (void gsl_fft_complex_workspace_free (gsl_fft_complex_workspace*)) (int gsl_fft_complex_memcpy (gsl_fft_complex_wavetable* gsl_fft_complex_wavetable*)) (int gsl_fft_complex_forward (double* size_t size_t gsl_fft_complex_wavetable* gsl_fft_complex_workspace*)) (int gsl_fft_complex_backward (double* size_t size_t gsl_fft_complex_wavetable* gsl_fft_complex_workspace*)) (int gsl_fft_complex_inverse (double* size_t size_t gsl_fft_complex_wavetable* gsl_fft_complex_workspace*)) (int gsl_fft_complex_transform (double* size_t size_t gsl_fft_complex_wavetable* gsl_fft_complex_workspace* int)) (int gsl_fft_real_radix2_transform (double* size_t size_t) ) (gsl_fft_real_wavetable* gsl_fft_real_wavetable_alloc (size_t)) (void gsl_fft_real_wavetable_free (gsl_fft_real_wavetable*)) (gsl_fft_real_workspace* gsl_fft_real_workspace_alloc (size_t)) (void gsl_fft_real_workspace_free (gsl_fft_real_workspace*)) (int gsl_fft_real_transform (double* size_t size_t gsl_fft_real_wavetable* gsl_fft_real_workspace*)) (int gsl_fft_real_unpack (double* double* size_t size_t)) (gsl_eigen_symm_workspace* gsl_eigen_symm_alloc (size_t)) (void gsl_eigen_symm_free (gsl_eigen_symm_workspace*)) (int gsl_eigen_symm (gsl_matrix* gsl_vector* gsl_eigen_symm_workspace*)) (gsl_eigen_symmv_workspace* gsl_eigen_symmv_alloc (size_t)) (void gsl_eigen_symmv_free (gsl_eigen_symmv_workspace*)) (int gsl_eigen_symmv (gsl_matrix* gsl_vector* gsl_matrix* gsl_eigen_symmv_workspace*)) (gsl_eigen_herm_workspace* gsl_eigen_herm_alloc (size_t)) (void gsl_eigen_herm_free (gsl_eigen_herm_workspace*)) (int gsl_eigen_herm (gsl_matrix_complex* gsl_vector* gsl_eigen_herm_workspace*)) (gsl_eigen_hermv_workspace* gsl_eigen_hermv_alloc (size_t)) (void gsl_eigen_hermv_free (gsl_eigen_hermv_workspace*)) (int gsl_eigen_hermv (gsl_matrix_complex* gsl_vector* gsl_matrix_complex* gsl_eigen_hermv_workspace*)) (gsl_eigen_francis_workspace* gsl_eigen_francis_alloc (void)) (void gsl_eigen_francis_free (gsl_eigen_francis_workspace*)) (void gsl_eigen_francis_T (int gsl_eigen_francis_workspace*)) (int gsl_eigen_francis (gsl_matrix* gsl_vector_complex* gsl_eigen_francis_workspace*)) (int gsl_eigen_francis_Z (gsl_matrix* gsl_vector_complex* gsl_matrix* gsl_eigen_francis_workspace*)) (gsl_eigen_nonsymm_workspace* gsl_eigen_nonsymm_alloc (size_t)) (void gsl_eigen_nonsymm_free (gsl_eigen_nonsymm_workspace*)) (void gsl_eigen_nonsymm_params (int int gsl_eigen_nonsymm_workspace*)) (int gsl_eigen_nonsymm (gsl_matrix* gsl_vector_complex* gsl_eigen_nonsymm_workspace*)) (int gsl_eigen_nonsymm_Z (gsl_matrix* gsl_vector_complex* gsl_matrix* gsl_eigen_nonsymm_workspace*)) (gsl_eigen_nonsymmv_workspace* gsl_eigen_nonsymmv_alloc (size_t)) (void gsl_eigen_nonsymmv_free (gsl_eigen_nonsymmv_workspace*)) (reader-cond ((>= gsl-version 1.15) (void gsl_eigen_nonsymmv_params (int gsl_eigen_nonsymmv_workspace*)))) (int gsl_eigen_nonsymmv (gsl_matrix* gsl_vector_complex* gsl_matrix_complex* gsl_eigen_nonsymmv_workspace*)) (int gsl_eigen_nonsymmv_Z (gsl_matrix* gsl_vector_complex* gsl_matrix_complex* gsl_matrix* gsl_eigen_nonsymmv_workspace*)) (gsl_eigen_gensymm_workspace* gsl_eigen_gensymm_alloc (size_t)) (void gsl_eigen_gensymm_free (gsl_eigen_gensymm_workspace*)) (int gsl_eigen_gensymm (gsl_matrix* gsl_matrix* gsl_vector* gsl_eigen_gensymm_workspace*)) (int gsl_eigen_gensymm_standardize (gsl_matrix* gsl_matrix*)) (gsl_eigen_gensymmv_workspace* gsl_eigen_gensymmv_alloc (size_t)) (void gsl_eigen_gensymmv_free (gsl_eigen_gensymmv_workspace*)) (int gsl_eigen_gensymmv (gsl_matrix* gsl_matrix* gsl_vector* gsl_matrix* gsl_eigen_gensymmv_workspace*)) (gsl_eigen_genherm_workspace* gsl_eigen_genherm_alloc (size_t)) (void gsl_eigen_genherm_free (gsl_eigen_genherm_workspace*)) (int gsl_eigen_genherm (gsl_matrix_complex* gsl_matrix_complex* gsl_vector* gsl_eigen_genherm_workspace*)) (int gsl_eigen_genherm_standardize (gsl_matrix_complex* gsl_matrix_complex*)) (gsl_eigen_genhermv_workspace* gsl_eigen_genhermv_alloc (size_t)) (void gsl_eigen_genhermv_free (gsl_eigen_genhermv_workspace*)) (int gsl_eigen_genhermv (gsl_matrix_complex* gsl_matrix_complex* gsl_vector* gsl_matrix_complex* gsl_eigen_genhermv_workspace*)) (gsl_eigen_gen_workspace* gsl_eigen_gen_alloc (size_t)) (void gsl_eigen_gen_free (gsl_eigen_gen_workspace*)) (void gsl_eigen_gen_params (int int int gsl_eigen_gen_workspace*)) (int gsl_eigen_gen (gsl_matrix* gsl_matrix* gsl_vector_complex* gsl_vector* gsl_eigen_gen_workspace*)) (int gsl_eigen_gen_QZ (gsl_matrix* gsl_matrix* gsl_vector_complex* gsl_vector* gsl_matrix* gsl_matrix* gsl_eigen_gen_workspace*)) (gsl_eigen_genv_workspace* gsl_eigen_genv_alloc (size_t)) (void gsl_eigen_genv_free (gsl_eigen_genv_workspace*)) (int gsl_eigen_genv (gsl_matrix* gsl_matrix* gsl_vector_complex* gsl_vector* gsl_matrix_complex* gsl_eigen_genv_workspace*)) (int gsl_eigen_genv_QZ (gsl_matrix* gsl_matrix* gsl_vector_complex* gsl_vector* gsl_matrix_complex* gsl_matrix* gsl_matrix* gsl_eigen_genv_workspace*)) (int gsl_eigen_symmv_sort (gsl_vector* gsl_matrix* int)) (int gsl_eigen_hermv_sort (gsl_vector* gsl_matrix_complex* int)) (int gsl_eigen_nonsymmv_sort (gsl_vector_complex* gsl_matrix_complex* int)) (int gsl_eigen_gensymmv_sort (gsl_vector* gsl_matrix* int)) (int gsl_eigen_genhermv_sort (gsl_vector* gsl_matrix_complex* int)) (int gsl_eigen_genv_sort (gsl_vector_complex* gsl_vector* gsl_matrix_complex* int)) (int gsl_schur_gen_eigvals (gsl_matrix* gsl_matrix* double* double* double* double* double*)) (int gsl_schur_solve_equation (double gsl_matrix* double double double gsl_vector* gsl_vector* double* double* double)) (int gsl_schur_solve_equation_z (double gsl_matrix* gsl_complex* double double gsl_vector_complex* gsl_vector_complex* double* double* double)) (int gsl_eigen_invert_jacobi (gsl_matrix* gsl_matrix* int)) (in-C "static s7_pointer g_gsl_eigen_jacobi(s7_scheme *sc, s7_pointer args) { unsigned int ref_arg = 0; return(s7_make_integer(sc, (s7_int)gsl_eigen_jacobi((gsl_matrix*)s7_c_pointer(s7_car(args)), (gsl_vector*)s7_c_pointer(s7_cadr(args)), (gsl_matrix*)s7_c_pointer(s7_caddr(args)), (int)s7_integer(s7_cadddr(args)), &ref_arg))); }") (C-function ("gsl_eigen_jacobi" g_gsl_eigen_jacobi "" 4)) (void gsl_error (char* char* int int)) (void gsl_stream_printf (char* char* int char*)) (char* gsl_strerror (int)) (gsl_error_handler_t* gsl_set_error_handler (gsl_error_handler_t*)) (gsl_error_handler_t* gsl_set_error_handler_off (void)) (gsl_stream_handler_t* gsl_set_stream_handler (gsl_stream_handler_t*)) (FILE* gsl_set_stream (FILE*)) (int gsl_fit_linear (double* size_t double* size_t size_t double* double* double* double* double* double*)) (int gsl_fit_wlinear (double* size_t double* size_t double* size_t size_t double* double* double* double* double* double*)) (int gsl_fit_linear_est (double double double double double double double* double*)) (int gsl_fit_mul (double* size_t double* size_t size_t double* double* double*)) (int gsl_fit_wmul (double* size_t double* size_t double* size_t size_t double* double* double*)) (int gsl_fit_mul_est (double double double double* double*)) (gsl_histogram* gsl_histogram_alloc (size_t)) (gsl_histogram* gsl_histogram_calloc (size_t)) (gsl_histogram* gsl_histogram_calloc_uniform (size_t double double)) (void gsl_histogram_free (gsl_histogram*)) (int gsl_histogram_increment (gsl_histogram* double)) (int gsl_histogram_accumulate (gsl_histogram* double double)) (int gsl_histogram_find (gsl_histogram* double size_t*)) (double gsl_histogram_get (gsl_histogram* size_t)) (int gsl_histogram_get_range (gsl_histogram* size_t double* double*)) (double gsl_histogram_max (gsl_histogram*)) (double gsl_histogram_min (gsl_histogram*)) (size_t gsl_histogram_bins (gsl_histogram*)) (void gsl_histogram_reset (gsl_histogram*)) (gsl_histogram* gsl_histogram_calloc_range (size_t double*)) (int gsl_histogram_set_ranges (gsl_histogram* double* size_t)) (int gsl_histogram_set_ranges_uniform (gsl_histogram* double double)) (int gsl_histogram_memcpy (gsl_histogram* gsl_histogram*)) (gsl_histogram* gsl_histogram_clone (gsl_histogram*)) (double gsl_histogram_max_val (gsl_histogram*)) (size_t gsl_histogram_max_bin (gsl_histogram*)) (double gsl_histogram_min_val (gsl_histogram*)) (size_t gsl_histogram_min_bin (gsl_histogram*)) (int gsl_histogram_equal_bins_p (gsl_histogram* gsl_histogram*)) (int gsl_histogram_add (gsl_histogram* gsl_histogram*)) (int gsl_histogram_sub (gsl_histogram* gsl_histogram*)) (int gsl_histogram_mul (gsl_histogram* gsl_histogram*)) (int gsl_histogram_div (gsl_histogram* gsl_histogram*)) (int gsl_histogram_scale (gsl_histogram* double)) (int gsl_histogram_shift (gsl_histogram* double)) (double gsl_histogram_sigma (gsl_histogram*)) (double gsl_histogram_mean (gsl_histogram*)) (double gsl_histogram_sum (gsl_histogram*)) (int gsl_histogram_fwrite (FILE* gsl_histogram*) ) (int gsl_histogram_fread (FILE* gsl_histogram*)) (int gsl_histogram_fprintf (FILE* gsl_histogram* char* char*)) (int gsl_histogram_fscanf (FILE* gsl_histogram*)) (gsl_histogram_pdf* gsl_histogram_pdf_alloc (size_t)) (int gsl_histogram_pdf_init (gsl_histogram_pdf* gsl_histogram*)) (void gsl_histogram_pdf_free (gsl_histogram_pdf*)) (double gsl_histogram_pdf_sample (gsl_histogram_pdf* double)) (gsl_histogram2d* gsl_histogram2d_alloc (size_t size_t)) (gsl_histogram2d* gsl_histogram2d_calloc (size_t size_t)) (gsl_histogram2d* gsl_histogram2d_calloc_uniform (size_t size_t double double double double)) (void gsl_histogram2d_free (gsl_histogram2d*)) (int gsl_histogram2d_increment (gsl_histogram2d* double double)) (int gsl_histogram2d_accumulate (gsl_histogram2d* double double double)) (int gsl_histogram2d_find (gsl_histogram2d* double double size_t* size_t*)) (double gsl_histogram2d_get (gsl_histogram2d* size_t size_t)) (int gsl_histogram2d_get_xrange (gsl_histogram2d* size_t double* double*)) (int gsl_histogram2d_get_yrange (gsl_histogram2d* size_t double* double*)) (double gsl_histogram2d_xmax (gsl_histogram2d*)) (double gsl_histogram2d_xmin (gsl_histogram2d*)) (size_t gsl_histogram2d_nx (gsl_histogram2d*)) (double gsl_histogram2d_ymax (gsl_histogram2d*)) (double gsl_histogram2d_ymin (gsl_histogram2d*)) (size_t gsl_histogram2d_ny (gsl_histogram2d*)) (void gsl_histogram2d_reset (gsl_histogram2d*)) (gsl_histogram2d* gsl_histogram2d_calloc_range (size_t size_t double* double*)) (int gsl_histogram2d_set_ranges_uniform (gsl_histogram2d* double double double double)) (int gsl_histogram2d_memcpy (gsl_histogram2d* gsl_histogram2d*)) (gsl_histogram2d* gsl_histogram2d_clone (gsl_histogram2d*)) (double gsl_histogram2d_max_val (gsl_histogram2d*)) (void gsl_histogram2d_max_bin (gsl_histogram2d* size_t* size_t*)) (double gsl_histogram2d_min_val (gsl_histogram2d*)) (void gsl_histogram2d_min_bin (gsl_histogram2d* size_t* size_t*)) (double gsl_histogram2d_xmean (gsl_histogram2d*)) (double gsl_histogram2d_ymean (gsl_histogram2d*)) (double gsl_histogram2d_xsigma (gsl_histogram2d*)) (double gsl_histogram2d_ysigma (gsl_histogram2d*)) (double gsl_histogram2d_cov (gsl_histogram2d*)) (double gsl_histogram2d_sum (gsl_histogram2d*)) (int gsl_histogram2d_equal_bins_p (gsl_histogram2d* gsl_histogram2d*) ) (int gsl_histogram2d_add (gsl_histogram2d* gsl_histogram2d*)) (int gsl_histogram2d_sub (gsl_histogram2d* gsl_histogram2d*)) (int gsl_histogram2d_mul (gsl_histogram2d* gsl_histogram2d*)) (int gsl_histogram2d_div (gsl_histogram2d* gsl_histogram2d*)) (int gsl_histogram2d_scale (gsl_histogram2d* double)) (int gsl_histogram2d_shift (gsl_histogram2d* double)) (int gsl_histogram2d_fwrite (FILE* gsl_histogram2d*) ) (int gsl_histogram2d_fread (FILE* gsl_histogram2d*)) (int gsl_histogram2d_fprintf (FILE* gsl_histogram2d* char* char*)) (int gsl_histogram2d_fscanf (FILE* gsl_histogram2d*)) (gsl_histogram2d_pdf* gsl_histogram2d_pdf_alloc (size_t size_t)) (int gsl_histogram2d_pdf_init (gsl_histogram2d_pdf* gsl_histogram2d*)) (void gsl_histogram2d_pdf_free (gsl_histogram2d_pdf*)) (int gsl_histogram2d_pdf_sample (gsl_histogram2d_pdf* double double double* double*)) ;(void gsl_ieee_printf_double (double*) ) ; these are ridiculous ;(void gsl_ieee_fprintf_double (FILE* double*) ) ;(void gsl_ieee_double_to_rep (double* gsl_ieee_double_rep*) ) (void gsl_ieee_env_setup (void) ) ; looks for GSL_IEEE_MODE home var ;(int gsl_ieee_read_mode_string (char* int* int* int*) ) ; int by ref (int gsl_ieee_set_mode (int int int) ) (in-C "static s7_pointer g_gsl_deriv_central(s7_scheme *sc, s7_pointer args) { gsl_function gsl_f; make_gsl_function(s7_car(args)); return(s7_make_integer(sc, gsl_deriv_central(&gsl_f, s7_real(s7_cadr(args)), s7_real(s7_caddr(args)), (double *)s7_c_pointer(s7_cadddr(args)), (double *)s7_c_pointer(s7_list_ref(sc, args, 4))))); } static s7_pointer g_gsl_deriv_backward(s7_scheme *sc, s7_pointer args) { gsl_function gsl_f; make_gsl_function(s7_car(args)); return(s7_make_integer(sc, gsl_deriv_backward(&gsl_f, s7_real(s7_cadr(args)), s7_real(s7_caddr(args)), (double *)s7_c_pointer(s7_cadddr(args)), (double *)s7_c_pointer(s7_list_ref(sc, args, 4))))); } static s7_pointer g_gsl_deriv_forward(s7_scheme *sc, s7_pointer args) { gsl_function gsl_f; make_gsl_function(s7_car(args)); return(s7_make_integer(sc, gsl_deriv_forward(&gsl_f, s7_real(s7_cadr(args)), s7_real(s7_caddr(args)), (double *)s7_c_pointer(s7_cadddr(args)), (double *)s7_c_pointer(s7_list_ref(sc, args, 4))))); } ") (C-function ("gsl_deriv_central" g_gsl_deriv_central "" 5)) (C-function ("gsl_deriv_backward" g_gsl_deriv_backward "" 5)) (C-function ("gsl_deriv_forward" g_gsl_deriv_forward "" 5)) (gsl_integration_workspace* gsl_integration_workspace_alloc (size_t)) (void gsl_integration_workspace_free (gsl_integration_workspace*)) (gsl_integration_qaws_table* gsl_integration_qaws_table_alloc (double double int int)) (int gsl_integration_qaws_table_set (gsl_integration_qaws_table* double double int int)) (void gsl_integration_qaws_table_free (gsl_integration_qaws_table*)) (gsl_integration_qawo_table* gsl_integration_qawo_table_alloc (double double int size_t)) (int gsl_integration_qawo_table_set (gsl_integration_qawo_table* double double int)) (int gsl_integration_qawo_table_set_length (gsl_integration_qawo_table* double)) (void gsl_integration_qawo_table_free (gsl_integration_qawo_table*)) (in-C "#define Integration(Name) \ static s7_pointer g_gsl_integration_ ## Name (s7_scheme *sc, s7_pointer args) \ { \ gsl_function gsl_f; \ make_gsl_function(s7_car(args)); \ gsl_integration_ ## Name (&gsl_f, s7_real(s7_cadr(args)), s7_real(s7_caddr(args)), \ (double *)s7_c_pointer(s7_list_ref(sc, args, 3)), (double *)s7_c_pointer(s7_list_ref(sc, args, 4)), \ (double *)s7_c_pointer(s7_list_ref(sc, args, 5)), (double *)s7_c_pointer(s7_list_ref(sc, args, 6))); \ return(s7_car(args)); \ } Integration(qk15) Integration(qk21) Integration(qk31) Integration(qk41) Integration(qk51) Integration(qk61) ") (C-function ("gsl_integration_qk15" g_gsl_integration_qk15 "" 7)) (C-function ("gsl_integration_qk21" g_gsl_integration_qk21 "" 7)) (C-function ("gsl_integration_qk31" g_gsl_integration_qk31 "" 7)) (C-function ("gsl_integration_qk41" g_gsl_integration_qk41 "" 7)) (C-function ("gsl_integration_qk51" g_gsl_integration_qk51 "" 7)) (C-function ("gsl_integration_qk61" g_gsl_integration_qk61 "" 7)) (in-C "static s7_pointer g_gsl_integration_qcheb(s7_scheme *sc, s7_pointer args) { gsl_function gsl_f; make_gsl_function(s7_car(args)); gsl_integration_qcheb(&gsl_f, s7_real(s7_cadr(args)), s7_real(s7_caddr(args)), (double *)s7_c_pointer(s7_cadddr(args)), (double *)s7_c_pointer(s7_list_ref(sc, args, 4))); return(s7_car(args)); } static s7_pointer g_gsl_integration_qng(s7_scheme *sc, s7_pointer args) { size_t ref; gsl_function gsl_f; make_gsl_function(s7_car(args)); return(s7_make_integer(sc, gsl_integration_qng(&gsl_f, s7_real(s7_list_ref(sc, args, 1)), s7_real(s7_list_ref(sc, args, 2)), s7_real(s7_list_ref(sc, args, 3)), s7_real(s7_list_ref(sc, args, 4)), (double *)s7_c_pointer(s7_list_ref(sc, args, 5)), (double *)s7_c_pointer(s7_list_ref(sc, args, 6)), &ref))); } static s7_pointer g_gsl_integration_qag(s7_scheme *sc, s7_pointer args) { gsl_function gsl_f; make_gsl_function(s7_car(args)); return(s7_make_integer(sc, gsl_integration_qag(&gsl_f, s7_real(s7_list_ref(sc, args, 1)), s7_real(s7_list_ref(sc, args, 2)), s7_real(s7_list_ref(sc, args, 3)), s7_real(s7_list_ref(sc, args, 4)), (size_t)s7_integer(s7_list_ref(sc, args, 5)), (int)s7_integer(s7_list_ref(sc, args, 6)), (gsl_integration_workspace *)s7_c_pointer(s7_list_ref(sc, args, 7)), (double *)s7_c_pointer(s7_list_ref(sc, args, 8)), (double *)s7_c_pointer(s7_list_ref(sc, args, 9))))); } static s7_pointer g_gsl_integration_qagi(s7_scheme *sc, s7_pointer args) { gsl_function gsl_f; make_gsl_function(s7_car(args)); return(s7_make_integer(sc, gsl_integration_qagi(&gsl_f, s7_real(s7_list_ref(sc, args, 1)), s7_real(s7_list_ref(sc, args, 2)), (size_t)s7_integer(s7_list_ref(sc, args, 3)), (gsl_integration_workspace *)s7_c_pointer(s7_list_ref(sc, args, 4)), (double *)s7_c_pointer(s7_list_ref(sc, args, 5)), (double *)s7_c_pointer(s7_list_ref(sc, args, 6))))); } static s7_pointer g_gsl_integration_qagiu(s7_scheme *sc, s7_pointer args) { gsl_function gsl_f; make_gsl_function(s7_car(args)); return(s7_make_integer(sc, gsl_integration_qagiu(&gsl_f, s7_real(s7_list_ref(sc, args, 1)), s7_real(s7_list_ref(sc, args, 2)), s7_real(s7_list_ref(sc, args, 3)), (size_t)s7_integer(s7_list_ref(sc, args, 4)), (gsl_integration_workspace *)s7_c_pointer(s7_list_ref(sc, args, 5)), (double *)s7_c_pointer(s7_list_ref(sc, args, 6)), (double *)s7_c_pointer(s7_list_ref(sc, args, 7))))); } static s7_pointer g_gsl_integration_qagil(s7_scheme *sc, s7_pointer args) { gsl_function gsl_f; make_gsl_function(s7_car(args)); return(s7_make_integer(sc, gsl_integration_qagil(&gsl_f, s7_real(s7_list_ref(sc, args, 1)), s7_real(s7_list_ref(sc, args, 2)), s7_real(s7_list_ref(sc, args, 3)), (size_t)s7_integer(s7_list_ref(sc, args, 4)), (gsl_integration_workspace *)s7_c_pointer(s7_list_ref(sc, args, 5)), (double *)s7_c_pointer(s7_list_ref(sc, args, 6)), (double *)s7_c_pointer(s7_list_ref(sc, args, 7))))); } static s7_pointer g_gsl_integration_qags(s7_scheme *sc, s7_pointer args) { gsl_function gsl_f; make_gsl_function(s7_car(args)); return(s7_make_integer(sc, gsl_integration_qags(&gsl_f, s7_real(s7_list_ref(sc, args, 1)), s7_real(s7_list_ref(sc, args, 2)), s7_real(s7_list_ref(sc, args, 3)), s7_real(s7_list_ref(sc, args, 4)), (size_t)s7_integer(s7_list_ref(sc, args, 5)), (gsl_integration_workspace *)s7_c_pointer(s7_list_ref(sc, args, 6)), (double *)s7_c_pointer(s7_list_ref(sc, args, 7)), (double *)s7_c_pointer(s7_list_ref(sc, args, 8))))); } static s7_pointer g_gsl_integration_qagp(s7_scheme *sc, s7_pointer args) { gsl_function gsl_f; make_gsl_function(s7_car(args)); return(s7_make_integer(sc, gsl_integration_qagp(&gsl_f, (double *)s7_c_pointer(s7_list_ref(sc, args, 1)), (size_t)s7_integer(s7_list_ref(sc, args, 2)), s7_real(s7_list_ref(sc, args, 3)), s7_real(s7_list_ref(sc, args, 4)), (size_t)s7_integer(s7_list_ref(sc, args, 5)), (gsl_integration_workspace *)s7_c_pointer(s7_list_ref(sc, args, 6)), (double *)s7_c_pointer(s7_list_ref(sc, args, 7)), (double *)s7_c_pointer(s7_list_ref(sc, args, 8))))); } static s7_pointer g_gsl_integration_qawc(s7_scheme *sc, s7_pointer args) { gsl_function gsl_f; make_gsl_function(s7_car(args)); return(s7_make_integer(sc, gsl_integration_qawc(&gsl_f, s7_real(s7_list_ref(sc, args, 1)), s7_real(s7_list_ref(sc, args, 2)), s7_real(s7_list_ref(sc, args, 3)), s7_real(s7_list_ref(sc, args, 4)), s7_real(s7_list_ref(sc, args, 5)), (size_t)s7_integer(s7_list_ref(sc, args, 6)), (gsl_integration_workspace *)s7_c_pointer(s7_list_ref(sc, args, 7)), (double *)s7_c_pointer(s7_list_ref(sc, args, 8)), (double *)s7_c_pointer(s7_list_ref(sc, args, 9))))); } static s7_pointer g_gsl_integration_qaws(s7_scheme *sc, s7_pointer args) { gsl_function gsl_f; make_gsl_function(s7_car(args)); return(s7_make_integer(sc, gsl_integration_qaws(&gsl_f, s7_real(s7_list_ref(sc, args, 1)), s7_real(s7_list_ref(sc, args, 2)), (gsl_integration_qaws_table *)s7_c_pointer(s7_list_ref(sc, args, 3)), s7_real(s7_list_ref(sc, args, 4)), s7_real(s7_list_ref(sc, args, 5)), (size_t)s7_integer(s7_list_ref(sc, args, 6)), (gsl_integration_workspace *)s7_c_pointer(s7_list_ref(sc, args, 7)), (double *)s7_c_pointer(s7_list_ref(sc, args, 8)), (double *)s7_c_pointer(s7_list_ref(sc, args, 9))))); } static s7_pointer g_gsl_integration_qawo(s7_scheme *sc, s7_pointer args) { gsl_function gsl_f; make_gsl_function(s7_car(args)); return(s7_make_integer(sc, gsl_integration_qawo(&gsl_f, s7_real(s7_list_ref(sc, args, 1)), s7_real(s7_list_ref(sc, args, 2)), s7_real(s7_list_ref(sc, args, 3)), (size_t)s7_integer(s7_list_ref(sc, args, 4)), (gsl_integration_workspace *)s7_c_pointer(s7_list_ref(sc, args, 5)), (gsl_integration_qawo_table *)s7_c_pointer(s7_list_ref(sc, args, 6)), (double *)s7_c_pointer(s7_list_ref(sc, args, 7)), (double *)s7_c_pointer(s7_list_ref(sc, args, 8))))); } static s7_pointer g_gsl_integration_qawf(s7_scheme *sc, s7_pointer args) { gsl_function gsl_f; make_gsl_function(s7_car(args)); return(s7_make_integer(sc, gsl_integration_qawf(&gsl_f, s7_real(s7_list_ref(sc, args, 1)), s7_real(s7_list_ref(sc, args, 2)), (size_t)s7_integer(s7_list_ref(sc, args, 3)), (gsl_integration_workspace *)s7_c_pointer(s7_list_ref(sc, args, 4)), (gsl_integration_workspace *)s7_c_pointer(s7_list_ref(sc, args, 5)), (gsl_integration_qawo_table *)s7_c_pointer(s7_list_ref(sc, args, 6)), (double *)s7_c_pointer(s7_list_ref(sc, args, 7)), (double *)s7_c_pointer(s7_list_ref(sc, args, 8))))); } static s7_pointer g_gsl_integration_glfixed(s7_scheme *sc, s7_pointer args) { gsl_function gsl_f; make_gsl_function(s7_car(args)); return(s7_make_real(sc, gsl_integration_glfixed(&gsl_f, s7_real(s7_list_ref(sc, args, 1)), s7_real(s7_list_ref(sc, args, 2)), (const gsl_integration_glfixed_table *)s7_c_pointer(s7_list_ref(sc, args, 3))))); } static s7_pointer g_gsl_integration_qk(s7_scheme *sc, s7_pointer args) { gsl_function gsl_f; make_gsl_function(s7_list_ref(sc, args, 6)); gsl_integration_qk((int)s7_integer(s7_car(args)), (double *)s7_c_pointer(s7_list_ref(sc, args, 1)), (double *)s7_c_pointer(s7_list_ref(sc, args, 2)), (double *)s7_c_pointer(s7_list_ref(sc, args, 3)), (double *)s7_c_pointer(s7_list_ref(sc, args, 4)), (double *)s7_c_pointer(s7_list_ref(sc, args, 5)), &gsl_f, s7_real(s7_list_ref(sc, args, 7)), s7_real(s7_list_ref(sc, args, 8)), (double *)s7_c_pointer(s7_list_ref(sc, args, 9)), (double *)s7_c_pointer(s7_list_ref(sc, args, 10)), (double *)s7_c_pointer(s7_list_ref(sc, args, 11)), (double *)s7_c_pointer(s7_list_ref(sc, args, 12))); return(s7_car(args)); }") (C-function ("gsl_integration_qcheb" g_gsl_integration_qcheb "" 5)) (C-function ("gsl_integration_qng" g_gsl_integration_qng "" 7)) (C-function ("gsl_integration_qag" g_gsl_integration_qag "" 10)) (C-function ("gsl_integration_qagi" g_gsl_integration_qagi "" 7)) (C-function ("gsl_integration_qagiu" g_gsl_integration_qagiu "" 8)) (C-function ("gsl_integration_qagil" g_gsl_integration_qagil "" 8)) (C-function ("gsl_integration_qags" g_gsl_integration_qags "" 9)) (C-function ("gsl_integration_qagp" g_gsl_integration_qagp "" 9)) (C-function ("gsl_integration_qawc" g_gsl_integration_qawc "" 10)) (C-function ("gsl_integration_qaws" g_gsl_integration_qaws "" 10)) (C-function ("gsl_integration_qawo" g_gsl_integration_qawo "" 9)) (C-function ("gsl_integration_qawf" g_gsl_integration_qawf "" 9)) (C-function ("gsl_integration_qk" g_gsl_integration_qk "" 13)) (C-function ("gsl_integration_glfixed" g_gsl_integration_glfixed "" 4)) (gsl_integration_glfixed_table* gsl_integration_glfixed_table_alloc (size_t)) (void gsl_integration_glfixed_table_free (gsl_integration_glfixed_table*)) (reader-cond ((>= gsl-version 1.15) (int gsl_integration_glfixed_point (double double size_t double* double* gsl_integration_glfixed_table*)) (gsl_integration_cquad_workspace* gsl_integration_cquad_workspace_alloc (size_t)) (void gsl_integration_cquad_workspace_free (gsl_integration_cquad_workspace*)))) (int gsl_linalg_matmult (gsl_matrix* gsl_matrix* gsl_matrix*)) (int gsl_linalg_matmult_mod (gsl_matrix* int gsl_matrix* int gsl_matrix*)) (int gsl_linalg_exponential_ss (gsl_matrix* gsl_matrix* int)) (double gsl_linalg_householder_transform (gsl_vector*)) (int gsl_linalg_householder_hm (double gsl_vector* gsl_matrix*)) (int gsl_linalg_householder_mh (double gsl_vector* gsl_matrix*)) (int gsl_linalg_householder_hv (double gsl_vector* gsl_vector*)) (int gsl_linalg_householder_hm1 (double gsl_matrix*)) (in-C "static s7_pointer g_gsl_linalg_complex_householder_transform(s7_scheme *sc, s7_pointer args) { gsl_complex g; g = gsl_linalg_complex_householder_transform((gsl_vector_complex *)s7_c_pointer(s7_car(args))); return(GSL_TO_S7_COMPLEX(sc, g)); } static s7_pointer g_gsl_linalg_complex_householder_hm(s7_scheme *sc, s7_pointer args) { gsl_complex g; S7_TO_GSL_COMPLEX(s7_car(args), g); return(s7_make_integer(sc, gsl_linalg_complex_householder_hm(g, (gsl_vector_complex *)s7_c_pointer(s7_cadr(args)), (gsl_matrix_complex *)s7_c_pointer(s7_caddr(args))))); } static s7_pointer g_gsl_linalg_complex_householder_mh(s7_scheme *sc, s7_pointer args) { gsl_complex g; S7_TO_GSL_COMPLEX(s7_car(args), g); return(s7_make_integer(sc, gsl_linalg_complex_householder_mh(g, (gsl_vector_complex *)s7_c_pointer(s7_cadr(args)), (gsl_matrix_complex *)s7_c_pointer(s7_caddr(args))))); } static s7_pointer g_gsl_linalg_complex_householder_hv(s7_scheme *sc, s7_pointer args) { gsl_complex g; S7_TO_GSL_COMPLEX(s7_car(args), g); return(s7_make_integer(sc, gsl_linalg_complex_householder_hv(g, (gsl_vector_complex *)s7_c_pointer(s7_cadr(args)), (gsl_vector_complex *)s7_c_pointer(s7_caddr(args))))); } static s7_pointer g_gsl_linalg_complex_LU_det(s7_scheme *sc, s7_pointer args) { gsl_complex g; g = gsl_linalg_complex_LU_det((gsl_matrix_complex *)s7_c_pointer(s7_car(args)), (int)s7_integer(s7_cadr(args))); return(GSL_TO_S7_COMPLEX(sc, g)); } static s7_pointer g_gsl_linalg_complex_LU_sgndet(s7_scheme *sc, s7_pointer args) { gsl_complex g; g = gsl_linalg_complex_LU_sgndet((gsl_matrix_complex *)s7_c_pointer(s7_car(args)), (int)s7_integer(s7_cadr(args))); return(GSL_TO_S7_COMPLEX(sc, g)); } ") (C-function ("gsl_linalg_complex_householder_transform" g_gsl_linalg_complex_householder_transform "" 1)) (C-function ("gsl_linalg_complex_householder_hm" g_gsl_linalg_complex_householder_hm "" 3)) (C-function ("gsl_linalg_complex_householder_mh" g_gsl_linalg_complex_householder_mh "" 3)) (C-function ("gsl_linalg_complex_householder_hv" g_gsl_linalg_complex_householder_hv "" 3)) (C-function ("gsl_linalg_complex_LU_det" g_gsl_linalg_complex_LU_det "" 2)) (C-function ("gsl_linalg_complex_LU_sgndet" g_gsl_linalg_complex_LU_sgndet "" 2)) (int gsl_linalg_hessenberg_decomp (gsl_matrix* gsl_vector*)) (int gsl_linalg_hessenberg_unpack (gsl_matrix* gsl_vector* gsl_matrix*)) (int gsl_linalg_hessenberg_unpack_accum (gsl_matrix* gsl_vector* gsl_matrix*)) (int gsl_linalg_hessenberg_set_zero (gsl_matrix*)) (int gsl_linalg_hessenberg_submatrix (gsl_matrix* gsl_matrix* size_t gsl_vector*)) (int gsl_linalg_hessenberg (gsl_matrix* gsl_vector*)) (int gsl_linalg_hesstri_decomp (gsl_matrix* gsl_matrix* gsl_matrix* gsl_matrix* gsl_vector*)) (int gsl_linalg_SV_decomp (gsl_matrix* gsl_matrix* gsl_vector* gsl_vector*)) (int gsl_linalg_SV_decomp_mod (gsl_matrix* gsl_matrix* gsl_matrix* gsl_vector* gsl_vector*)) (int gsl_linalg_SV_decomp_jacobi (gsl_matrix* gsl_matrix* gsl_vector*)) (int gsl_linalg_SV_solve (gsl_matrix* gsl_matrix* gsl_vector* gsl_vector* gsl_vector*)) (reader-cond ((>= gsl-version 1.16) (int gsl_linalg_SV_leverage (gsl_matrix* gsl_vector*)))) (in-C "static s7_pointer g_gsl_linalg_LU_decomp(s7_scheme *sc, s7_pointer args) { int s = 0; return(s7_make_integer(sc, (s7_int)gsl_linalg_LU_decomp((gsl_matrix *)s7_c_pointer(s7_car(args)), (gsl_permutation *)s7_c_pointer(s7_cadr(args)), &s))); }") (C-function ("gsl_linalg_LU_decomp" g_gsl_linalg_LU_decomp "" 2)) (int gsl_linalg_LU_solve (gsl_matrix* gsl_permutation* gsl_vector* gsl_vector*)) (int gsl_linalg_LU_svx (gsl_matrix* gsl_permutation* gsl_vector*)) (int gsl_linalg_LU_refine (gsl_matrix* gsl_matrix* gsl_permutation* gsl_vector* gsl_vector* gsl_vector*)) (int gsl_linalg_LU_invert (gsl_matrix* gsl_permutation* gsl_matrix*)) (double gsl_linalg_LU_det (gsl_matrix* int)) (double gsl_linalg_LU_lndet (gsl_matrix*)) (int gsl_linalg_LU_sgndet (gsl_matrix* int)) (in-C "static s7_pointer g_gsl_linalg_complex_LU_decomp(s7_scheme *sc, s7_pointer args) { int s = 0; return(s7_make_integer(sc, (s7_int)gsl_linalg_complex_LU_decomp((gsl_matrix_complex *)s7_c_pointer(s7_car(args)), (gsl_permutation *)s7_c_pointer(s7_cadr(args)), &s))); }") (C-function ("gsl_linalg_complex_LU_decomp" g_gsl_linalg_complex_LU_decomp "" 2)) (int gsl_linalg_complex_LU_solve (gsl_matrix_complex* gsl_permutation* gsl_vector_complex* gsl_vector_complex*)) (int gsl_linalg_complex_LU_svx (gsl_matrix_complex* gsl_permutation* gsl_vector_complex*)) (int gsl_linalg_complex_LU_refine (gsl_matrix_complex* gsl_matrix_complex* gsl_permutation* gsl_vector_complex* gsl_vector_complex* gsl_vector_complex*)) (int gsl_linalg_complex_LU_invert (gsl_matrix_complex* gsl_permutation* gsl_matrix_complex*)) (double gsl_linalg_complex_LU_lndet (gsl_matrix_complex*)) (int gsl_linalg_QR_decomp (gsl_matrix* gsl_vector*)) (int gsl_linalg_QR_solve (gsl_matrix* gsl_vector* gsl_vector* gsl_vector*)) (int gsl_linalg_QR_svx (gsl_matrix* gsl_vector* gsl_vector*)) (int gsl_linalg_QR_lssolve (gsl_matrix* gsl_vector* gsl_vector* gsl_vector* gsl_vector*)) (int gsl_linalg_QR_QRsolve (gsl_matrix* gsl_matrix* gsl_vector* gsl_vector*)) (int gsl_linalg_QR_Rsolve (gsl_matrix* gsl_vector* gsl_vector*)) (int gsl_linalg_QR_Rsvx (gsl_matrix* gsl_vector*)) (int gsl_linalg_QR_update (gsl_matrix* gsl_matrix* gsl_vector* gsl_vector*)) (int gsl_linalg_QR_QTvec (gsl_matrix* gsl_vector* gsl_vector*)) (int gsl_linalg_QR_Qvec (gsl_matrix* gsl_vector* gsl_vector*)) (int gsl_linalg_QR_QTmat (gsl_matrix* gsl_vector* gsl_matrix*)) (reader-cond ((>= gsl-version 2.0) (int gsl_linalg_QR_matQ (gsl_matrix* gsl_vector* gsl_matrix*)) (void gsl_linalg_givens (double double double* double*)) (void gsl_linalg_givens_gv (gsl_vector* size_t size_t double double)))) (int gsl_linalg_QR_unpack (gsl_matrix* gsl_vector* gsl_matrix* gsl_matrix*)) (int gsl_linalg_R_solve (gsl_matrix* gsl_vector* gsl_vector*)) (int gsl_linalg_R_svx (gsl_matrix* gsl_vector*)) (in-C "static s7_pointer g_gsl_linalg_QRPT_decomp(s7_scheme *sc, s7_pointer args) { int s = 0; return(s7_make_integer(sc, (s7_int)gsl_linalg_QRPT_decomp((gsl_matrix *)s7_c_pointer(s7_car(args)), (gsl_vector *)s7_c_pointer(s7_cadr(args)), (gsl_permutation *)s7_c_pointer(s7_caddr(args)), &s, (gsl_vector *)s7_c_pointer(s7_cadddr(args))))); }") (C-function ("gsl_linalg_QRPT_decomp" g_gsl_linalg_QRPT_decomp "" 4)) (in-C "static s7_pointer g_gsl_linalg_QRPT_decomp2(s7_scheme *sc, s7_pointer args) { int s = 0; return(s7_make_integer(sc, (s7_int)gsl_linalg_QRPT_decomp2((gsl_matrix *)s7_c_pointer(s7_car(args)), (gsl_matrix *)s7_c_pointer(s7_cadr(args)), (gsl_matrix *)s7_c_pointer(s7_caddr(args)), (gsl_vector *)s7_c_pointer(s7_cadddr(args)), (gsl_permutation *)s7_c_pointer(s7_list_ref(sc, args, 4)), &s, (gsl_vector *)s7_c_pointer(s7_list_ref(sc, args, 5))))); }") (C-function ("gsl_linalg_QRPT_decomp2" g_gsl_linalg_QRPT_decomp2 "" 6)) (int gsl_linalg_QRPT_solve (gsl_matrix* gsl_vector* gsl_permutation* gsl_vector* gsl_vector*)) (int gsl_linalg_QRPT_svx (gsl_matrix* gsl_vector* gsl_permutation* gsl_vector*)) (int gsl_linalg_QRPT_QRsolve (gsl_matrix* gsl_matrix* gsl_permutation* gsl_vector* gsl_vector*)) (int gsl_linalg_QRPT_Rsolve (gsl_matrix* gsl_permutation* gsl_vector* gsl_vector*)) (int gsl_linalg_QRPT_Rsvx (gsl_matrix* gsl_permutation* gsl_vector*)) (int gsl_linalg_QRPT_update (gsl_matrix* gsl_matrix* gsl_permutation* gsl_vector* gsl_vector*)) (int gsl_linalg_LQ_decomp (gsl_matrix* gsl_vector*)) (int gsl_linalg_LQ_solve_T (gsl_matrix* gsl_vector* gsl_vector* gsl_vector*)) (int gsl_linalg_LQ_svx_T (gsl_matrix* gsl_vector* gsl_vector*)) (int gsl_linalg_LQ_lssolve_T (gsl_matrix* gsl_vector* gsl_vector* gsl_vector* gsl_vector*)) (int gsl_linalg_LQ_Lsolve_T (gsl_matrix* gsl_vector* gsl_vector*)) (int gsl_linalg_LQ_Lsvx_T (gsl_matrix* gsl_vector*)) (int gsl_linalg_L_solve_T (gsl_matrix* gsl_vector* gsl_vector*)) (int gsl_linalg_LQ_vecQ (gsl_matrix* gsl_vector* gsl_vector*)) (int gsl_linalg_LQ_vecQT (gsl_matrix* gsl_vector* gsl_vector*)) (int gsl_linalg_LQ_unpack (gsl_matrix* gsl_vector* gsl_matrix* gsl_matrix*)) (int gsl_linalg_LQ_update (gsl_matrix* gsl_matrix* gsl_vector* gsl_vector*)) (int gsl_linalg_LQ_LQsolve (gsl_matrix* gsl_matrix* gsl_vector* gsl_vector*)) (in-C "static s7_pointer g_gsl_linalg_PTLQ_decomp(s7_scheme *sc, s7_pointer args) { int s = 0; return(s7_make_integer(sc, (s7_int)gsl_linalg_PTLQ_decomp((gsl_matrix *)s7_c_pointer(s7_car(args)), (gsl_vector *)s7_c_pointer(s7_cadr(args)), (gsl_permutation *)s7_c_pointer(s7_caddr(args)), &s, (gsl_vector *)s7_c_pointer(s7_cadddr(args))))); }") (C-function ("gsl_linalg_PTLQ_decomp" g_gsl_linalg_PTLQ_decomp "" 4)) (in-C "static s7_pointer g_gsl_linalg_PTLQ_decomp2(s7_scheme *sc, s7_pointer args) { int s = 0; return(s7_make_integer(sc, (s7_int)gsl_linalg_PTLQ_decomp2((gsl_matrix *)s7_c_pointer(s7_car(args)), (gsl_matrix *)s7_c_pointer(s7_cadr(args)), (gsl_matrix *)s7_c_pointer(s7_caddr(args)), (gsl_vector *)s7_c_pointer(s7_cadddr(args)), (gsl_permutation *)s7_c_pointer(s7_list_ref(sc, args, 4)), &s, (gsl_vector *)s7_c_pointer(s7_list_ref(sc, args, 5))))); }") (C-function ("gsl_linalg_PTLQ_decomp2" g_gsl_linalg_PTLQ_decomp2 "" 6)) (int gsl_linalg_PTLQ_solve_T (gsl_matrix* gsl_vector* gsl_permutation* gsl_vector* gsl_vector*)) (int gsl_linalg_PTLQ_svx_T (gsl_matrix* gsl_vector* gsl_permutation* gsl_vector*)) (int gsl_linalg_PTLQ_LQsolve_T (gsl_matrix* gsl_matrix* gsl_permutation* gsl_vector* gsl_vector*)) (int gsl_linalg_PTLQ_Lsolve_T (gsl_matrix* gsl_permutation* gsl_vector* gsl_vector*)) (int gsl_linalg_PTLQ_Lsvx_T (gsl_matrix* gsl_permutation* gsl_vector*)) (int gsl_linalg_PTLQ_update (gsl_matrix* gsl_matrix* gsl_permutation* gsl_vector* gsl_vector*)) (int gsl_linalg_cholesky_decomp (gsl_matrix*)) (int gsl_linalg_cholesky_solve (gsl_matrix* gsl_vector* gsl_vector*)) (int gsl_linalg_cholesky_svx (gsl_matrix* gsl_vector*)) (int gsl_linalg_cholesky_invert (gsl_matrix*)) (int gsl_linalg_cholesky_decomp_unit (gsl_matrix* gsl_vector*)) (int gsl_linalg_complex_cholesky_decomp (gsl_matrix_complex*)) (int gsl_linalg_complex_cholesky_solve (gsl_matrix_complex* gsl_vector_complex* gsl_vector_complex*)) (int gsl_linalg_complex_cholesky_svx (gsl_matrix_complex* gsl_vector_complex*)) (reader-cond ((>= gsl-version 1.15) (int gsl_linalg_complex_cholesky_invert (gsl_matrix_complex*)))) (int gsl_linalg_symmtd_decomp (gsl_matrix* gsl_vector*)) (int gsl_linalg_symmtd_unpack (gsl_matrix* gsl_vector* gsl_matrix* gsl_vector* gsl_vector*)) (int gsl_linalg_symmtd_unpack_T (gsl_matrix* gsl_vector* gsl_vector*)) (int gsl_linalg_hermtd_decomp (gsl_matrix_complex* gsl_vector_complex*)) (int gsl_linalg_hermtd_unpack (gsl_matrix_complex* gsl_vector_complex* gsl_matrix_complex* gsl_vector* gsl_vector*)) (int gsl_linalg_hermtd_unpack_T (gsl_matrix_complex* gsl_vector* gsl_vector*)) (int gsl_linalg_HH_solve (gsl_matrix* gsl_vector* gsl_vector*)) (int gsl_linalg_HH_svx (gsl_matrix* gsl_vector*)) (int gsl_linalg_solve_symm_tridiag (gsl_vector* gsl_vector* gsl_vector* gsl_vector*)) (int gsl_linalg_solve_tridiag (gsl_vector* gsl_vector* gsl_vector* gsl_vector* gsl_vector*)) (int gsl_linalg_solve_symm_cyc_tridiag (gsl_vector* gsl_vector* gsl_vector* gsl_vector*)) (int gsl_linalg_solve_cyc_tridiag (gsl_vector* gsl_vector* gsl_vector* gsl_vector* gsl_vector*)) (int gsl_linalg_bidiag_decomp (gsl_matrix* gsl_vector* gsl_vector*)) (int gsl_linalg_bidiag_unpack (gsl_matrix* gsl_vector* gsl_matrix* gsl_vector* gsl_matrix* gsl_vector* gsl_vector*)) (int gsl_linalg_bidiag_unpack2 (gsl_matrix* gsl_vector* gsl_vector* gsl_matrix*)) (int gsl_linalg_bidiag_unpack_B (gsl_matrix* gsl_vector* gsl_vector*)) (int gsl_linalg_balance_matrix (gsl_matrix* gsl_vector*)) (int gsl_linalg_balance_accum (gsl_matrix* gsl_vector*)) (int gsl_linalg_balance_columns (gsl_matrix* gsl_vector*)) (gsl_matrix_complex* gsl_matrix_complex_alloc (size_t size_t)) (gsl_matrix_complex* gsl_matrix_complex_calloc (size_t size_t)) (gsl_matrix_complex* gsl_matrix_complex_alloc_from_matrix (gsl_matrix_complex* size_t size_t size_t size_t)) (gsl_vector_complex* gsl_vector_complex_alloc_row_from_matrix (gsl_matrix_complex* size_t)) (gsl_vector_complex* gsl_vector_complex_alloc_col_from_matrix (gsl_matrix_complex* size_t)) (gsl_vector_complex* gsl_vector_complex_alloc (size_t)) (void gsl_vector_complex_free (gsl_vector_complex*)) (void gsl_matrix_complex_free (gsl_matrix_complex*)) (void gsl_matrix_complex_set_zero (gsl_matrix_complex*)) (void gsl_matrix_complex_set_identity (gsl_matrix_complex*)) (int gsl_matrix_complex_fread (FILE* gsl_matrix_complex*) ) (int gsl_matrix_complex_fwrite (FILE* gsl_matrix_complex*) ) (int gsl_matrix_complex_fscanf (FILE* gsl_matrix_complex*)) (int gsl_matrix_complex_fprintf (FILE* gsl_matrix_complex* char*)) (int gsl_matrix_complex_memcpy (gsl_matrix_complex* gsl_matrix_complex*)) (int gsl_matrix_complex_swap (gsl_matrix_complex* gsl_matrix_complex*)) (int gsl_matrix_complex_swap_rows (gsl_matrix_complex* size_t size_t)) (int gsl_matrix_complex_swap_columns (gsl_matrix_complex* size_t size_t)) (int gsl_matrix_complex_swap_rowcol (gsl_matrix_complex* size_t size_t)) (int gsl_matrix_complex_transpose (gsl_matrix_complex*)) (int gsl_matrix_complex_transpose_memcpy (gsl_matrix_complex* gsl_matrix_complex*)) (reader-cond ((>= gsl-version 1.15) (int gsl_matrix_complex_equal (gsl_matrix_complex* gsl_matrix_complex*)))) (int gsl_matrix_complex_isnull (gsl_matrix_complex*)) (int gsl_matrix_complex_ispos (gsl_matrix_complex*)) (int gsl_matrix_complex_isneg (gsl_matrix_complex*)) (int gsl_matrix_complex_isnonneg (gsl_matrix_complex*)) (int gsl_matrix_complex_add (gsl_matrix_complex* gsl_matrix_complex*)) (int gsl_matrix_complex_sub (gsl_matrix_complex* gsl_matrix_complex*)) (int gsl_matrix_complex_mul_elements (gsl_matrix_complex* gsl_matrix_complex*)) (int gsl_matrix_complex_div_elements (gsl_matrix_complex* gsl_matrix_complex*)) (in-C "static s7_pointer g_gsl_matrix_complex_set_all(s7_scheme *sc, s7_pointer args) { gsl_complex g; S7_TO_GSL_COMPLEX(s7_cadr(args), g); gsl_matrix_complex_set_all((gsl_matrix_complex *)s7_c_pointer(s7_car(args)), g); return(s7_cadr(args)); } static s7_pointer g_gsl_matrix_complex_set(s7_scheme *sc, s7_pointer args) { gsl_complex g; s7_pointer cg; cg = s7_cadddr(args); S7_TO_GSL_COMPLEX(cg, g); gsl_matrix_complex_set((gsl_matrix_complex *)s7_c_pointer(s7_car(args)), s7_integer(s7_cadr(args)), s7_integer(s7_caddr(args)), g); return(cg); } static s7_pointer g_gsl_matrix_complex_get(s7_scheme *sc, s7_pointer args) { gsl_complex g; g = gsl_matrix_complex_get((gsl_matrix_complex *)s7_c_pointer(s7_car(args)), s7_integer(s7_cadr(args)), s7_integer(s7_caddr(args))); return(GSL_TO_S7_COMPLEX(sc, g)); } static s7_pointer g_gsl_matrix_complex_scale(s7_scheme *sc, s7_pointer args) { gsl_complex g; S7_TO_GSL_COMPLEX(s7_cadr(args), g); return(s7_make_integer(sc, gsl_matrix_complex_scale((gsl_matrix_complex *)s7_c_pointer(s7_car(args)), g))); } static s7_pointer g_gsl_matrix_complex_add_constant(s7_scheme *sc, s7_pointer args) { gsl_complex g; S7_TO_GSL_COMPLEX(s7_cadr(args), g); return(s7_make_integer(sc, gsl_matrix_complex_add_constant((gsl_matrix_complex *)s7_c_pointer(s7_car(args)), g))); } static s7_pointer g_gsl_matrix_complex_add_diagonal(s7_scheme *sc, s7_pointer args) { gsl_complex g; S7_TO_GSL_COMPLEX(s7_cadr(args), g); return(s7_make_integer(sc, gsl_matrix_complex_add_diagonal((gsl_matrix_complex *)s7_c_pointer(s7_car(args)), g))); } static s7_pointer g_gsl_vector_complex_get(s7_scheme *sc, s7_pointer args) { gsl_complex g; g = gsl_vector_complex_get((gsl_vector_complex *)s7_c_pointer(s7_car(args)), s7_integer(s7_cadr(args))); return(GSL_TO_S7_COMPLEX(sc, g)); } ") (C-function ("gsl_matrix_complex_set_all" g_gsl_matrix_complex_set_all "" 2)) (C-function ("gsl_matrix_complex_set" g_gsl_matrix_complex_set "" 4)) (C-function ("gsl_matrix_complex_get" g_gsl_matrix_complex_get "" 3)) (C-function ("gsl_vector_complex_get" g_gsl_vector_complex_get "" 2)) (C-function ("gsl_matrix_complex_scale" g_gsl_matrix_complex_scale "" 2)) (C-function ("gsl_matrix_complex_add_constant" g_gsl_matrix_complex_add_constant "" 2)) (C-function ("gsl_matrix_complex_add_diagonal" g_gsl_matrix_complex_add_diagonal "" 2)) (int gsl_matrix_complex_get_row (gsl_vector_complex* gsl_matrix_complex* size_t)) (int gsl_matrix_complex_get_col (gsl_vector_complex* gsl_matrix_complex* size_t)) (int gsl_matrix_complex_set_row (gsl_matrix_complex* size_t gsl_vector_complex*)) (int gsl_matrix_complex_set_col (gsl_matrix_complex* size_t gsl_vector_complex*)) (gsl_complex* gsl_matrix_complex_ptr (gsl_matrix_complex* size_t size_t)) (gsl_complex* gsl_matrix_complex_const_ptr (gsl_matrix_complex* size_t size_t)) (void gsl_message (char* char* int int)) (gsl_min_fminimizer* gsl_min_fminimizer_alloc (gsl_min_fminimizer_type*) ) (void gsl_min_fminimizer_free (gsl_min_fminimizer*)) (int gsl_min_fminimizer_set (gsl_min_fminimizer* gsl_function* double double double)) (int gsl_min_fminimizer_set_with_values (gsl_min_fminimizer* gsl_function* double double double double double double)) (int gsl_min_fminimizer_iterate (gsl_min_fminimizer*)) (char* gsl_min_fminimizer_name (gsl_min_fminimizer*)) (double gsl_min_fminimizer_x_minimum (gsl_min_fminimizer*)) (double gsl_min_fminimizer_x_lower (gsl_min_fminimizer*)) (double gsl_min_fminimizer_x_upper (gsl_min_fminimizer*)) (double gsl_min_fminimizer_f_minimum (gsl_min_fminimizer*)) (double gsl_min_fminimizer_f_lower (gsl_min_fminimizer*)) (double gsl_min_fminimizer_f_upper (gsl_min_fminimizer*)) (double gsl_min_fminimizer_minimum (gsl_min_fminimizer*)) (int gsl_min_test_interval (double double double double)) (int gsl_min_find_bracket (gsl_function* double* double* double* double* double* double* size_t)) ;; gsl_monte* is not doable -- they chose to pass a bare double* array to the (parameter) gsl_monte_function, ;; and there's nothing I can do with that. To wrap and unwrap it on every call would make it unusable. ;; I could keep wrappers around of all so-far-used sizes, but not until someone actually needs them. ;; the fdf cases [removed in gsl 2.0?] are similar, I think, and the ode functions. GSL also assumes direct access to their ;; structs (as in matrix size1/2) -- not very nice for our style of use. (gsl_multifit_linear_workspace* gsl_multifit_linear_alloc (size_t size_t)) (void gsl_multifit_linear_free (gsl_multifit_linear_workspace*)) (int gsl_multifit_linear (gsl_matrix* gsl_vector* gsl_vector* gsl_matrix* double* gsl_multifit_linear_workspace*)) (int gsl_multifit_wlinear (gsl_matrix* gsl_vector* gsl_vector* gsl_vector* gsl_matrix* double* gsl_multifit_linear_workspace*)) (int gsl_multifit_wlinear_svd (gsl_matrix* gsl_vector* gsl_vector* double size_t* gsl_vector* gsl_matrix* double* gsl_multifit_linear_workspace*)) (int gsl_multifit_wlinear_usvd (gsl_matrix* gsl_vector* gsl_vector* double size_t* gsl_vector* gsl_matrix* double* gsl_multifit_linear_workspace*)) (int gsl_multifit_linear_est (gsl_vector* gsl_vector* gsl_matrix* double* double*)) (int gsl_multifit_linear_residuals (gsl_matrix* gsl_vector* gsl_vector* gsl_vector*)) (reader-cond ((>= gsl-version 1.16) (gsl_multifit_robust_workspace* gsl_multifit_robust_alloc (gsl_multifit_robust_type* size_t size_t)) (void gsl_multifit_robust_free (gsl_multifit_robust_workspace*)) (int gsl_multifit_robust_tune (double gsl_multifit_robust_workspace*)) (char* gsl_multifit_robust_name (gsl_multifit_robust_workspace*)) (gsl_multifit_robust_stats gsl_multifit_robust_statistics (gsl_multifit_robust_workspace*)) (int gsl_multifit_robust (gsl_matrix* gsl_vector* gsl_vector* gsl_matrix* gsl_multifit_robust_workspace*)) (int gsl_multifit_robust_est (gsl_vector* gsl_vector* gsl_matrix* double* double*)) (int gsl_multifit_fsolver_driver (gsl_multifit_fsolver* size_t double double)))) (int gsl_multifit_gradient (gsl_matrix* gsl_vector* gsl_vector*)) (int gsl_multifit_covar (gsl_matrix* double gsl_matrix*)) (gsl_multifit_fsolver* gsl_multifit_fsolver_alloc (gsl_multifit_fsolver_type* size_t size_t)) (void gsl_multifit_fsolver_free (gsl_multifit_fsolver*)) (int gsl_multifit_fsolver_set (gsl_multifit_fsolver* gsl_multifit_function* gsl_vector*)) (int gsl_multifit_fsolver_iterate (gsl_multifit_fsolver*)) (char* gsl_multifit_fsolver_name (gsl_multifit_fsolver*)) (gsl_vector* gsl_multifit_fsolver_position (gsl_multifit_fsolver*)) (int gsl_multifit_test_delta (gsl_vector* gsl_vector* double double)) (int gsl_multifit_test_gradient (gsl_vector* double)) (reader-cond ((< gsl-version 2.0) (int gsl_multifit_linear_svd (gsl_matrix* gsl_vector* double size_t* gsl_vector* gsl_matrix* double* gsl_multifit_linear_workspace*)) (int gsl_multifit_linear_usvd (gsl_matrix* gsl_vector* double size_t* gsl_vector* gsl_matrix* double* gsl_multifit_linear_workspace*))) (#t (int gsl_multifit_linear_svd (gsl_matrix* gsl_multifit_linear_workspace*)) (int gsl_multifit_linear_bsvd (gsl_matrix* gsl_multifit_linear_workspace*)) (int gsl_multifit_linear_solve (double gsl_matrix* gsl_vector* gsl_vector* double* double* gsl_multifit_linear_workspace*)) (int gsl_multifit_linear_applyW (gsl_matrix* gsl_vector* gsl_vector* gsl_matrix* gsl_vector* gsl_multifit_linear_workspace*)) (int gsl_multifit_linear_stdform1 (gsl_vector* gsl_matrix* gsl_vector* gsl_matrix* gsl_vector* gsl_multifit_linear_workspace*)) (int gsl_multifit_linear_wstdform1 (gsl_vector* gsl_matrix* gsl_vector* gsl_vector* gsl_matrix* gsl_vector* gsl_multifit_linear_workspace*)) (int gsl_multifit_linear_stdform2 (gsl_matrix* gsl_matrix* gsl_vector* gsl_matrix* gsl_vector* gsl_matrix* gsl_multifit_linear_workspace*)) (int gsl_multifit_linear_wstdform2 (gsl_matrix* gsl_matrix* gsl_vector* gsl_vector* gsl_matrix* gsl_vector* gsl_matrix* gsl_multifit_linear_workspace*)) (int gsl_multifit_linear_genform1 (gsl_vector* gsl_vector* gsl_vector* gsl_multifit_linear_workspace*)) (int gsl_multifit_linear_genform2 (gsl_matrix* gsl_matrix* gsl_vector* gsl_vector* gsl_matrix* gsl_vector* gsl_multifit_linear_workspace*)) (int gsl_multifit_linear_wgenform2 (gsl_matrix* gsl_matrix* gsl_vector* gsl_vector* gsl_vector* gsl_matrix* gsl_vector* gsl_multifit_linear_workspace*)) (int gsl_multifit_linear_lreg (double double gsl_vector*)) (int gsl_multifit_linear_lcurve (gsl_vector* gsl_vector* gsl_vector* gsl_vector* gsl_multifit_linear_workspace*)) (int gsl_multifit_linear_lcorner (gsl_vector* gsl_vector* size_t*)) (int gsl_multifit_linear_lcorner2 (gsl_vector* gsl_vector* size_t*)) (int gsl_multifit_linear_Lk (size_t size_t gsl_matrix*)) (int gsl_multifit_linear_Lsobolev (size_t size_t gsl_vector* gsl_matrix* gsl_multifit_linear_workspace*)) (int gsl_multifit_robust_maxiter (size_t gsl_multifit_robust_workspace*)) (int gsl_multifit_robust_weights (gsl_vector* gsl_vector* gsl_multifit_robust_workspace*)) (int gsl_multifit_robust_residuals (gsl_matrix* gsl_vector* gsl_vector* gsl_vector* gsl_multifit_robust_workspace*)) (int gsl_multifit_covar_QRPT (gsl_matrix* gsl_permutation* double gsl_matrix*)))) (gsl_multimin_fminimizer* gsl_multimin_fminimizer_alloc (gsl_multimin_fminimizer_type* size_t)) (void gsl_multimin_fminimizer_free (gsl_multimin_fminimizer*)) (char* gsl_multimin_fminimizer_name (gsl_multimin_fminimizer*)) (int gsl_multimin_fminimizer_iterate (gsl_multimin_fminimizer*)) (gsl_vector* gsl_multimin_fminimizer_x (gsl_multimin_fminimizer*)) (double gsl_multimin_fminimizer_minimum (gsl_multimin_fminimizer*)) (double gsl_multimin_fminimizer_size (gsl_multimin_fminimizer*)) (int gsl_multimin_test_gradient (gsl_vector* double)) (int gsl_multimin_test_size (double double)) ;; multimin_function is double f(gsl_vector* void*) -- so we can handle it (but not the fdf brand) (in-C "static s7_scheme *gsl_mmf_s7; static gsl_multimin_function gsl_mmf; static double gsl_mmf_caller(const gsl_vector *x, void *p) { return(s7_real(s7_call(gsl_mmf_s7, (s7_pointer)p, s7_cons(gsl_mmf_s7, s7_make_c_pointer(gsl_mmf_s7, (void *)x), s7_nil(gsl_mmf_s7))))); } #define make_gsl_mm_function(Args, Size) do {gsl_mmf.f = gsl_mmf_caller; gsl_mmf.n = Size; gsl_mmf.params = (void *)Args; gsl_mmf_s7 = sc;} while (0) static s7_pointer g_gsl_multimin_fminimizer_set(s7_scheme *sc, s7_pointer args) { make_gsl_mm_function(s7_cadr(args), ((gsl_vector *)s7_c_pointer(s7_caddr(args)))->size); return(s7_make_integer(sc, gsl_multimin_fminimizer_set((gsl_multimin_fminimizer *)s7_c_pointer(s7_car(args)), &gsl_mmf, (gsl_vector *)s7_c_pointer(s7_caddr(args)), (gsl_vector *)s7_c_pointer(s7_cadddr(args))))); } static s7_pointer g_gsl_multimin_diff(s7_scheme *sc, s7_pointer args) { make_gsl_mm_function(s7_caddr(args), ((gsl_vector *)s7_c_pointer(s7_car(args)))->size); return(s7_make_integer(sc, gsl_multimin_diff(&gsl_mmf, (gsl_vector *)s7_c_pointer(s7_cadr(args)), (gsl_vector *)s7_c_pointer(s7_caddr(args))))); } static s7_pointer g_gsl_multimin_fminimizer_fval(s7_scheme *sc, s7_pointer args) {return(s7_make_real(sc, ((gsl_multimin_fminimizer *)s7_c_pointer(s7_car(args)))->fval));} ") (C-function ("gsl_multimin_fminimizer_set" g_gsl_multimin_fminimizer_set "" 4)) (C-function ("gsl_multimin_diff" g_gsl_multimin_diff "" 3)) (C-function ("gsl_multimin_fminimizer_fval" g_gsl_multimin_fminimizer_fval "" 1)) ;; int f(const gsl_vector* void* gsl_vector*) so the function is doable (in-C "static s7_scheme *gsl_rf_s7; static gsl_multiroot_function gsl_rf; static int gsl_rf_caller(const gsl_vector *x, void *p, gsl_vector *y) { return(s7_integer(s7_call(gsl_rf_s7, (s7_pointer)p, s7_cons(gsl_rf_s7, s7_make_c_pointer(gsl_rf_s7, (void *)x), s7_cons(gsl_rf_s7, s7_make_c_pointer(gsl_rf_s7, (void *)y), s7_nil(gsl_rf_s7)))))); } #define make_gsl_rf_function(Args, Size) do {gsl_rf.f = gsl_rf_caller; gsl_rf.n = Size; gsl_rf.params = (void *)Args; gsl_rf_s7 = sc;} while (0) static s7_pointer g_gsl_multiroot_fsolver_set(s7_scheme *sc, s7_pointer args) { make_gsl_rf_function(s7_cadr(args), ((gsl_vector *)s7_c_pointer(s7_caddr(args)))->size); return(s7_make_integer(sc, gsl_multiroot_fsolver_set((gsl_multiroot_fsolver *)s7_c_pointer(s7_car(args)), &gsl_rf, (const gsl_vector *)s7_c_pointer(s7_caddr(args))))); } static s7_pointer g_gsl_multiroot_fdjacobian(s7_scheme *sc, s7_pointer args) { make_gsl_rf_function(s7_car(args), ((gsl_vector *)s7_c_pointer(s7_cadr(args)))->size); return(s7_make_integer(sc, gsl_multiroot_fdjacobian(&gsl_rf, (gsl_vector *)s7_c_pointer(s7_cadr(args)), (gsl_vector *)s7_c_pointer(s7_caddr(args)), s7_real(s7_cadddr(args)), (gsl_matrix *)s7_list_ref(sc, args, 4)))); }") (C-function ("gsl_multiroot_fsolver_set" g_gsl_multiroot_fsolver_set "" 3)) (C-function ("gsl_multiroot_fdjacobian" g_gsl_multiroot_fdjacobian "" 5)) (gsl_multiroot_fsolver* gsl_multiroot_fsolver_alloc (gsl_multiroot_fsolver_type* size_t) ) (void gsl_multiroot_fsolver_free (gsl_multiroot_fsolver*)) (int gsl_multiroot_fsolver_iterate (gsl_multiroot_fsolver*)) (char* gsl_multiroot_fsolver_name (gsl_multiroot_fsolver*)) (gsl_vector* gsl_multiroot_fsolver_root (gsl_multiroot_fsolver*)) (gsl_vector* gsl_multiroot_fsolver_dx (gsl_multiroot_fsolver*)) (gsl_vector* gsl_multiroot_fsolver_f (gsl_multiroot_fsolver*)) (int gsl_multiroot_test_delta (gsl_vector* gsl_vector* double double)) (int gsl_multiroot_test_residual (gsl_vector* double)) (gsl_multiset* gsl_multiset_alloc (size_t size_t)) (gsl_multiset* gsl_multiset_calloc (size_t size_t)) (void gsl_multiset_init_first (gsl_multiset*)) (void gsl_multiset_init_last (gsl_multiset*)) (void gsl_multiset_free (gsl_multiset*)) (int gsl_multiset_memcpy (gsl_multiset* gsl_multiset*)) (int gsl_multiset_fread (FILE* gsl_multiset*)) (int gsl_multiset_fwrite (FILE* gsl_multiset*)) (int gsl_multiset_fscanf (FILE* gsl_multiset*)) (int gsl_multiset_fprintf (FILE* gsl_multiset* char*)) (size_t gsl_multiset_n (gsl_multiset*)) (size_t gsl_multiset_k (gsl_multiset*)) (size_t* gsl_multiset_data (gsl_multiset*)) (int gsl_multiset_valid (gsl_multiset*)) (int gsl_multiset_next (gsl_multiset*)) (int gsl_multiset_prev (gsl_multiset*)) (size_t gsl_multiset_get (gsl_multiset* size_t)) ;; the ode functions all pass bare double* arrays to the called function. (gsl_permutation* gsl_permutation_alloc (size_t)) (gsl_permutation* gsl_permutation_calloc (size_t)) (void gsl_permutation_init (gsl_permutation*)) (void gsl_permutation_free (gsl_permutation*)) (int gsl_permutation_memcpy (gsl_permutation* gsl_permutation*)) (int gsl_permutation_fread (FILE* gsl_permutation*)) (int gsl_permutation_fwrite (FILE* gsl_permutation*)) (int gsl_permutation_fscanf (FILE* gsl_permutation*)) (int gsl_permutation_fprintf (FILE* gsl_permutation* char*)) (size_t gsl_permutation_size (gsl_permutation*)) (size_t* gsl_permutation_data (gsl_permutation*)) (int gsl_permutation_swap (gsl_permutation* size_t size_t)) (int gsl_permutation_valid (gsl_permutation*)) (void gsl_permutation_reverse (gsl_permutation*)) (int gsl_permutation_inverse (gsl_permutation* gsl_permutation*)) (int gsl_permutation_next (gsl_permutation*)) (int gsl_permutation_prev (gsl_permutation*)) (int gsl_permutation_mul (gsl_permutation* gsl_permutation* gsl_permutation*)) (int gsl_permutation_linear_to_canonical (gsl_permutation* gsl_permutation*)) (int gsl_permutation_canonical_to_linear (gsl_permutation* gsl_permutation*)) (size_t gsl_permutation_inversions (gsl_permutation*)) (size_t gsl_permutation_linear_cycles (gsl_permutation*)) (size_t gsl_permutation_canonical_cycles (gsl_permutation*)) (size_t gsl_permutation_get (gsl_permutation* size_t)) (int gsl_permute_complex (size_t* double* size_t size_t)) (int gsl_permute_complex_inverse (size_t* double* size_t size_t)) (int gsl_permute (size_t* double* size_t size_t)) (int gsl_permute_inverse (size_t* double* size_t size_t)) (int gsl_permute_vector_complex (gsl_permutation* gsl_vector_complex*)) (int gsl_permute_vector_complex_inverse (gsl_permutation* gsl_vector_complex*)) (int gsl_permute_vector (gsl_permutation* gsl_vector*)) (int gsl_permute_vector_inverse (gsl_permutation* gsl_vector*)) (gsl_root_fsolver* gsl_root_fsolver_alloc (gsl_root_fsolver_type*)) (void gsl_root_fsolver_free (gsl_root_fsolver*)) (int gsl_root_fsolver_set (gsl_root_fsolver* gsl_function* double double)) (int gsl_root_fsolver_iterate (gsl_root_fsolver*)) (char* gsl_root_fsolver_name (gsl_root_fsolver*)) (double gsl_root_fsolver_root (gsl_root_fsolver*)) (double gsl_root_fsolver_x_lower (gsl_root_fsolver*)) (double gsl_root_fsolver_x_upper (gsl_root_fsolver*)) (int gsl_root_test_interval (double double double double)) (int gsl_root_test_residual (double double)) (int gsl_root_test_delta (double double double double)) (gsl_sum_levin_u_workspace* gsl_sum_levin_u_alloc (size_t)) (void gsl_sum_levin_u_free (gsl_sum_levin_u_workspace*)) (int gsl_sum_levin_u_accel (double* size_t gsl_sum_levin_u_workspace* double* double*)) (int gsl_sum_levin_u_minmax (double* size_t size_t size_t gsl_sum_levin_u_workspace* double* double*)) (int gsl_sum_levin_u_step (double size_t size_t gsl_sum_levin_u_workspace* double*)) (gsl_sum_levin_utrunc_workspace* gsl_sum_levin_utrunc_alloc (size_t)) (void gsl_sum_levin_utrunc_free (gsl_sum_levin_utrunc_workspace*)) (int gsl_sum_levin_utrunc_accel (double* size_t gsl_sum_levin_utrunc_workspace* double* double*)) (int gsl_sum_levin_utrunc_minmax (double* size_t size_t size_t gsl_sum_levin_utrunc_workspace* double* double*)) (int gsl_sum_levin_utrunc_step (double size_t gsl_sum_levin_utrunc_workspace* double*)) (gsl_wavelet* gsl_wavelet_alloc (gsl_wavelet_type* size_t)) (void gsl_wavelet_free (gsl_wavelet*)) (char* gsl_wavelet_name (gsl_wavelet*)) (gsl_wavelet_workspace* gsl_wavelet_workspace_alloc (size_t)) (void gsl_wavelet_workspace_free (gsl_wavelet_workspace*)) (int gsl_wavelet_transform (gsl_wavelet* double* size_t size_t int gsl_wavelet_workspace*)) (int gsl_wavelet_transform_forward (gsl_wavelet* double* size_t size_t gsl_wavelet_workspace*)) (int gsl_wavelet_transform_inverse (gsl_wavelet* double* size_t size_t gsl_wavelet_workspace*)) (int gsl_wavelet2d_transform (gsl_wavelet* double* size_t size_t size_t int gsl_wavelet_workspace*)) (int gsl_wavelet2d_transform_forward (gsl_wavelet* double* size_t size_t size_t gsl_wavelet_workspace*)) (int gsl_wavelet2d_transform_inverse (gsl_wavelet* double* size_t size_t size_t gsl_wavelet_workspace*)) (int gsl_wavelet2d_nstransform (gsl_wavelet* double* size_t size_t size_t int gsl_wavelet_workspace*)) (int gsl_wavelet2d_nstransform_forward (gsl_wavelet* double* size_t size_t size_t gsl_wavelet_workspace*)) (int gsl_wavelet2d_nstransform_inverse (gsl_wavelet* double* size_t size_t size_t gsl_wavelet_workspace*)) (int gsl_wavelet2d_transform_matrix (gsl_wavelet* gsl_matrix* int gsl_wavelet_workspace*)) (int gsl_wavelet2d_transform_matrix_forward (gsl_wavelet* gsl_matrix* gsl_wavelet_workspace*)) (int gsl_wavelet2d_transform_matrix_inverse (gsl_wavelet* gsl_matrix* gsl_wavelet_workspace*)) (int gsl_wavelet2d_nstransform_matrix (gsl_wavelet* gsl_matrix* int gsl_wavelet_workspace*)) (int gsl_wavelet2d_nstransform_matrix_forward (gsl_wavelet* gsl_matrix* gsl_wavelet_workspace*)) (int gsl_wavelet2d_nstransform_matrix_inverse (gsl_wavelet* gsl_matrix* gsl_wavelet_workspace*)) (reader-cond ((>= gsl-version 2.0) ;; rstat (gsl_rstat_quantile_workspace* gsl_rstat_quantile_alloc (double)) (void gsl_rstat_quantile_free (gsl_rstat_quantile_workspace*)) (int gsl_rstat_quantile_add (double gsl_rstat_quantile_workspace*)) (double gsl_rstat_quantile_get (gsl_rstat_quantile_workspace*)) (gsl_rstat_workspace* gsl_rstat_alloc (void)) (void gsl_rstat_free (gsl_rstat_workspace*)) (size_t gsl_rstat_n (gsl_rstat_workspace*)) (int gsl_rstat_add (double gsl_rstat_workspace*)) (double gsl_rstat_min (gsl_rstat_workspace*)) (double gsl_rstat_max (gsl_rstat_workspace*)) (double gsl_rstat_mean (gsl_rstat_workspace*)) (double gsl_rstat_variance (gsl_rstat_workspace*)) (double gsl_rstat_sd (gsl_rstat_workspace*)) (double gsl_rstat_sd_mean (gsl_rstat_workspace*)) (double gsl_rstat_median (gsl_rstat_workspace*)) (double gsl_rstat_skew (gsl_rstat_workspace*)) (double gsl_rstat_kurtosis (gsl_rstat_workspace*)) (int gsl_rstat_reset (gsl_rstat_workspace*)) ;; spblas (int gsl_spblas_dgemv (int double gsl_spmatrix* gsl_vector* double gsl_vector*)) (int gsl_spblas_dgemm (double gsl_spmatrix* gsl_spmatrix* gsl_spmatrix*)) (size_t gsl_spblas_scatter (gsl_spmatrix* size_t double size_t* double* size_t gsl_spmatrix* size_t)) ;; splinalg (c-pointer gsl_splinalg_itersolve_gmres) (gsl_splinalg_itersolve* gsl_splinalg_itersolve_alloc (gsl_splinalg_itersolve_type* size_t size_t)) (void gsl_splinalg_itersolve_free (gsl_splinalg_itersolve*)) (char* gsl_splinalg_itersolve_name (gsl_splinalg_itersolve*)) (int gsl_splinalg_itersolve_iterate (gsl_spmatrix* gsl_vector* double gsl_vector* gsl_splinalg_itersolve*)) (double gsl_splinalg_itersolve_normr (gsl_splinalg_itersolve*)) ;; spmatrix (C-macro (int (GSL_SPMATRIX_TRIPLET GSL_SPMATRIX_CCS))) ;; #define GSL_SPMATRIX_ISTRIPLET (m) ((m)->sptype == GSL_SPMATRIX_TRIPLET) ;; #define GSL_SPMATRIX_ISCCS (m) ((m)->sptype == GSL_SPMATRIX_CCS) (gsl_spmatrix* gsl_spmatrix_alloc (size_t size_t)) (gsl_spmatrix* gsl_spmatrix_alloc_nzmax (size_t size_t size_t size_t)) (void gsl_spmatrix_free (gsl_spmatrix*)) (int gsl_spmatrix_realloc (size_t gsl_spmatrix*)) (int gsl_spmatrix_set_zero (gsl_spmatrix*)) (size_t gsl_spmatrix_nnz (gsl_spmatrix*)) (int gsl_spmatrix_compare_idx (size_t size_t size_t size_t)) (int gsl_spmatrix_memcpy (gsl_spmatrix* gsl_spmatrix*)) (double gsl_spmatrix_get (gsl_spmatrix* size_t size_t)) (int gsl_spmatrix_set (gsl_spmatrix* size_t size_t double)) (gsl_spmatrix* gsl_spmatrix_compcol (gsl_spmatrix*)) (void gsl_spmatrix_cumsum (size_t size_t*)) (int gsl_spmatrix_scale (gsl_spmatrix* double)) (int gsl_spmatrix_minmax (gsl_spmatrix* double* double*)) (int gsl_spmatrix_add (gsl_spmatrix* gsl_spmatrix* gsl_spmatrix*)) (int gsl_spmatrix_d2sp (gsl_spmatrix* gsl_matrix*)) (int gsl_spmatrix_sp2d (gsl_matrix* gsl_spmatrix*)) (int gsl_spmatrix_equal (gsl_spmatrix* gsl_spmatrix*)) (int gsl_spmatrix_transpose_memcpy (gsl_spmatrix* gsl_spmatrix*)) ;; interp2d (c-pointer (gsl_interp2d_bilinear gsl_interp2d_bicubic)) (gsl_interp2d* gsl_interp2d_alloc (gsl_interp2d_type* size_t size_t)) (char* gsl_interp2d_name (gsl_interp2d*)) (size_t gsl_interp2d_min_size (gsl_interp2d*)) (size_t gsl_interp2d_type_min_size (gsl_interp2d_type*)) (int gsl_interp2d_set (gsl_interp2d* double* size_t size_t double)) (double gsl_interp2d_get (gsl_interp2d* double* size_t size_t)) (size_t gsl_interp2d_idx (gsl_interp2d* size_t size_t)) (int gsl_interp2d_init (gsl_interp2d* double* double* double* size_t size_t)) (void gsl_interp2d_free (gsl_interp2d*)) (double gsl_interp2d_eval (gsl_interp2d* double* double* double* double double gsl_interp_accel* gsl_interp_accel*)) (double gsl_interp2d_eval_extrap (gsl_interp2d* double* double* double* double double gsl_interp_accel* gsl_interp_accel*)) (int gsl_interp2d_eval_e (gsl_interp2d* double* double* double* double double gsl_interp_accel* gsl_interp_accel* double*)) (int gsl_interp2d_eval_e_extrap (gsl_interp2d* double* double* double* double double gsl_interp_accel* gsl_interp_accel* double*)) (double gsl_interp2d_eval_deriv_x (gsl_interp2d* double* double* double* double double gsl_interp_accel* gsl_interp_accel*)) (int gsl_interp2d_eval_deriv_x_e (gsl_interp2d* double* double* double* double double gsl_interp_accel* gsl_interp_accel* double*)) (double gsl_interp2d_eval_deriv_y (gsl_interp2d* double* double* double* double double gsl_interp_accel* gsl_interp_accel*)) (int gsl_interp2d_eval_deriv_y_e (gsl_interp2d* double* double* double* double double gsl_interp_accel* gsl_interp_accel* double*)) (double gsl_interp2d_eval_deriv_xx (gsl_interp2d* double* double* double* double double gsl_interp_accel* gsl_interp_accel*)) (int gsl_interp2d_eval_deriv_xx_e (gsl_interp2d* double* double* double* double double gsl_interp_accel* gsl_interp_accel* double*)) (double gsl_interp2d_eval_deriv_yy (gsl_interp2d* double* double* double* double double gsl_interp_accel* gsl_interp_accel*)) (int gsl_interp2d_eval_deriv_yy_e (gsl_interp2d* double* double* double* double double gsl_interp_accel* gsl_interp_accel* double*)) (double gsl_interp2d_eval_deriv_xy (gsl_interp2d* double* double* double* double double gsl_interp_accel* gsl_interp_accel*)) (int gsl_interp2d_eval_deriv_xy_e (gsl_interp2d* double* double* double* double double gsl_interp_accel* gsl_interp_accel* double*)) ;; spline2n (gsl_spline2d* gsl_spline2d_alloc (gsl_interp2d_type* size_t size_t)) (int gsl_spline2d_init (gsl_spline2d* double* double* double* size_t size_t)) (void gsl_spline2d_free (gsl_spline2d*)) (double gsl_spline2d_eval (gsl_spline2d* double double gsl_interp_accel* gsl_interp_accel*)) (int gsl_spline2d_eval_e (gsl_spline2d* double double gsl_interp_accel* gsl_interp_accel* double*)) (double gsl_spline2d_eval_deriv_x (gsl_spline2d* double double gsl_interp_accel* gsl_interp_accel*)) (int gsl_spline2d_eval_deriv_x_e (gsl_spline2d* double double gsl_interp_accel* gsl_interp_accel* double*)) (double gsl_spline2d_eval_deriv_y (gsl_spline2d* double double gsl_interp_accel* gsl_interp_accel*)) (int gsl_spline2d_eval_deriv_y_e (gsl_spline2d* double double gsl_interp_accel* gsl_interp_accel* double*)) (double gsl_spline2d_eval_deriv_xx (gsl_spline2d* double double gsl_interp_accel* gsl_interp_accel*)) (int gsl_spline2d_eval_deriv_xx_e (gsl_spline2d* double double gsl_interp_accel* gsl_interp_accel* double*)) (double gsl_spline2d_eval_deriv_yy (gsl_spline2d* double double gsl_interp_accel* gsl_interp_accel*)) (int gsl_spline2d_eval_deriv_yy_e (gsl_spline2d* double double gsl_interp_accel* gsl_interp_accel* double*)) (double gsl_spline2d_eval_deriv_xy (gsl_spline2d* double double gsl_interp_accel* gsl_interp_accel*)) (int gsl_spline2d_eval_deriv_xy_e (gsl_spline2d* double double gsl_interp_accel* gsl_interp_accel* double*)) (size_t gsl_spline2d_min_size (gsl_spline2d*)) (char* gsl_spline2d_name (gsl_spline2d*)) (int gsl_spline2d_set (gsl_spline2d* double* size_t size_t double)) (double gsl_spline2d_get (gsl_spline2d* double* size_t size_t)) )) ) "" (list "gsl/gsl_blas.h" "gsl/gsl_blas_types.h" "gsl/gsl_block.h" "gsl/gsl_block_complex_double.h" "gsl/gsl_block_double.h" "gsl/gsl_bspline.h" "gsl/gsl_cblas.h" "gsl/gsl_cdf.h" "gsl/gsl_chebyshev.h" "gsl/gsl_check_range.h" "gsl/gsl_combination.h" "gsl/gsl_complex.h" "gsl/gsl_complex_math.h" "gsl/gsl_const.h" "gsl/gsl_const_cgs.h" "gsl/gsl_const_cgsm.h" "gsl/gsl_const_mks.h" "gsl/gsl_const_mksa.h" "gsl/gsl_const_num.h" "gsl/gsl_deriv.h" "gsl/gsl_dft_complex.h" "gsl/gsl_dht.h" "gsl/gsl_diff.h" "gsl/gsl_eigen.h" "gsl/gsl_errno.h" "gsl/gsl_fft.h" "gsl/gsl_fft_complex.h" "gsl/gsl_fft_real.h" "gsl/gsl_fit.h" "gsl/gsl_heapsort.h" "gsl/gsl_histogram.h" "gsl/gsl_histogram2d.h" "gsl/gsl_ieee_utils.h" "gsl/gsl_inline.h" "gsl/gsl_integration.h" "gsl/gsl_interp.h" (reader-cond ((>= gsl-version 2.0) "gsl/gsl_interp2d.h")) "gsl/gsl_linalg.h" "gsl/gsl_machine.h" "gsl/gsl_math.h" "gsl/gsl_matrix.h" "gsl/gsl_matrix_complex_double.h" "gsl/gsl_matrix_double.h" "gsl/gsl_message.h" "gsl/gsl_min.h" "gsl/gsl_minmax.h" "gsl/gsl_mode.h" "gsl/gsl_multifit.h" "gsl/gsl_multifit_nlin.h" "gsl/gsl_multimin.h" "gsl/gsl_multiroots.h" "gsl/gsl_multiset.h" "gsl/gsl_nan.h" "gsl/gsl_permutation.h" "gsl/gsl_permute.h" "gsl/gsl_permute_complex_double.h" "gsl/gsl_permute_double.h" "gsl/gsl_permute_vector.h" "gsl/gsl_permute_vector_complex_double.h" "gsl/gsl_permute_vector_double.h" "gsl/gsl_poly.h" "gsl/gsl_pow_int.h" "gsl/gsl_precision.h" "gsl/gsl_qrng.h" "gsl/gsl_randist.h" "gsl/gsl_rng.h" "gsl/gsl_roots.h" (reader-cond ((>= gsl-version 2.0) "gsl/gsl_rstat.h")) "gsl/gsl_sf.h" "gsl/gsl_sf_airy.h" "gsl/gsl_sf_bessel.h" "gsl/gsl_sf_clausen.h" "gsl/gsl_sf_coulomb.h" "gsl/gsl_sf_coupling.h" "gsl/gsl_sf_dawson.h" "gsl/gsl_sf_debye.h" "gsl/gsl_sf_dilog.h" "gsl/gsl_sf_elementary.h" "gsl/gsl_sf_ellint.h" "gsl/gsl_sf_elljac.h" "gsl/gsl_sf_erf.h" "gsl/gsl_sf_exp.h" "gsl/gsl_sf_expint.h" "gsl/gsl_sf_fermi_dirac.h" "gsl/gsl_sf_gamma.h" "gsl/gsl_sf_gegenbauer.h" "gsl/gsl_sf_hyperg.h" "gsl/gsl_sf_laguerre.h" "gsl/gsl_sf_lambert.h" "gsl/gsl_sf_legendre.h" "gsl/gsl_sf_log.h" "gsl/gsl_sf_mathieu.h" "gsl/gsl_sf_pow_int.h" "gsl/gsl_sf_psi.h" "gsl/gsl_sf_result.h" (reader-cond ((>= gsl-version 2.0) "gsl/gsl_spblas.h" "gsl/gsl_splinalg.h" "gsl/gsl_spline2d.h" "gsl/gsl_spmatrix.h")) "gsl/gsl_sf_synchrotron.h" "gsl/gsl_sf_transport.h" "gsl/gsl_sf_trig.h" "gsl/gsl_sf_zeta.h" "gsl/gsl_siman.h" "gsl/gsl_sort.h" "gsl/gsl_sort_double.h" "gsl/gsl_sort_vector.h" "gsl/gsl_sort_vector_double.h" "gsl/gsl_specfunc.h" "gsl/gsl_spline.h" "gsl/gsl_statistics.h" "gsl/gsl_statistics_double.h" "gsl/gsl_sum.h" "gsl/gsl_sys.h" "gsl/gsl_vector.h" "gsl/gsl_vector_complex.h" "gsl/gsl_vector_complex_double.h" "gsl/gsl_vector_double.h" "gsl/gsl_version.h" "gsl/gsl_wavelet.h" "gsl/gsl_wavelet2d.h" ) "-I/usr/local/include -g3 -DGSL_DISABLE_DEPRECATED" "-lgsl -lgslcblas" "libgsl_s7") ; GSL_DISABLE_DEPRECATED is needed to avoid a name collision (dating from version 1.7!!) (curlet)))) *libgsl* snd-16.1/snd-find.c0000644000076400007640000001467312555416057012226 0ustar bilbil#include "snd.h" static void clear_search_state(void) { if (Xen_is_procedure(ss->search_proc)) { snd_unprotect_at(ss->search_proc_loc); ss->search_proc_loc = NOT_A_GC_LOC; } ss->search_proc = Xen_undefined; if (ss->search_expr) free(ss->search_expr); ss->search_expr = NULL; } #if (!USE_NO_GUI) static void find_report(chan_info *cp, const char *msg) { if (cp) status_report(cp->sound, "%s", msg); find_dialog_set_label(msg); } static bool search_in_progress = false; static chan_info *previous_channel = NULL; #define MANY_PASSES 100000 static mus_long_t channel_find_forward(chan_info *cp) { mus_long_t i, end, start; end = current_samples(cp); start = cursor_sample(cp) + 1; if (start >= end) start = 0; i = scan_channel(cp, start, end, ss->search_proc); if (i < end) return(i); return(-1); } static mus_long_t channel_find_backward(chan_info *cp) { bool reported = false; mus_long_t i, start, passes; snd_fd *sf = NULL; Xen res = Xen_false; start = cursor_sample(cp) - 1; if (start < 0) start = current_samples(cp) - 1; sf = init_sample_read(start, cp, READ_BACKWARD); if (!sf) return(-1); ss->stopped_explicitly = false; for (i = start, passes = 0; i >= 0; i--, passes++) { res = Xen_call_with_1_arg(ss->search_proc, C_double_to_Xen_real((double)(read_sample(sf))), "search function"); if (!Xen_is_false(res)) break; if (passes >= MANY_PASSES) { passes = 0; check_for_event(); if (!(ss->stopped_explicitly)) { char *msg; msg = mus_format("search at minute %d", (int)floor(i / (snd_srate(cp->sound) * 60))); find_report(cp, msg); free(msg); reported = true; } /* if user types C-s during an active search, we risk stomping on our current pointers */ if (!(cp->sound->active)) break; } if (ss->stopped_explicitly) break; } ss->stopped_explicitly = false; if (reported) find_report(cp, NULL); free_snd_fd(sf); if (i >= 0) return(i); return(-1); } static char *channel_search(chan_info *cp, read_direction_t direction) { mus_long_t samp; char *s1, *s2, *msg; if (direction == READ_FORWARD) samp = channel_find_forward(cp); else samp = channel_find_backward(cp); previous_channel = cp; if (samp == -1) return(NULL); s1 = prettyf(chn_sample(samp, cp, cp->edit_ctr), 2); s2 = x_axis_location_to_string(cp, (double)samp / (double)snd_srate(cp->sound)); msg = mus_format("%s at %s (%lld)", s1, s2, samp); cursor_moveto_without_verbosity(cp, samp); free(s1); free(s2); return(msg); } static char *global_search(read_direction_t direction, bool repeating) { int i, j; if ((repeating) && ((!previous_channel) || (!(previous_channel->sound)) || (!(previous_channel->sound->active)))) repeating = false; for (i = 0; i < ss->max_sounds; i++) { snd_info *sp; sp = ss->sounds[i]; if ((sp) && (sp->inuse == SOUND_NORMAL)) for (j = 0; j < sp->nchans; j++) { chan_info *cp; cp = (chan_info *)(sp->chans[j]); if ((!repeating) || (cp == previous_channel)) { char *msg; repeating = false; /* after we find the channel, look at everything */ msg = channel_search(cp, direction); if (msg) return(msg); } } } return(NULL); } #if HAVE_EXTENSION_LANGUAGE void find_dialog_find(char *str, read_direction_t direction, chan_info *cp) { Xen proc; bool repeating_search = false; if (search_in_progress) { find_report(cp, "search already in progress"); return; } proc = Xen_false; /* str can be null, or equal to the previous call's str -- in this case use * the current search procedure if possible, else complain. * if str not null, make a new (local?) search-procedure */ if ((!str) || (!(*str)) || (mus_strcmp(str, ss->search_expr))) { proc = ss->search_proc; if (!(Xen_is_procedure(proc))) return; repeating_search = true; } else { char *buf = NULL; redirect_errors_to(errors_to_find_text, NULL); proc = snd_catch_any(eval_str_wrapper, str, str); redirect_errors_to(NULL, NULL); if ((!(Xen_is_procedure(proc))) || (!(procedure_arity_ok(proc, 1)))) return; clear_search_state(); /* free previous, if any */ repeating_search = false; ss->search_proc = proc; ss->search_expr = mus_strdup(str); ss->search_proc_loc = snd_protect(proc); buf = (char *)calloc(PRINT_BUFFER_SIZE, sizeof(char)); snprintf(buf, PRINT_BUFFER_SIZE, "%s %s", I_find, str); find_dialog_set_label(buf); free(buf); } /* now we have a search procedure, possibly optimized */ search_in_progress = true; find_dialog_stop_label(true); redirect_xen_error_to(stop_search_if_error, NULL); if (cp) str = channel_search(cp, direction); else str = global_search(direction, repeating_search); redirect_xen_error_to(NULL, NULL); find_dialog_stop_label(false); search_in_progress = false; if ((str) && (*str)) { find_report(cp, str); free(str); } else find_report(cp, "not found"); } #endif #endif /* end no gui */ /* -------------------------------------------------------------------------------- */ static Xen g_search_procedure(void) { #define H_search_procedure "(" S_search_procedure "): the function used by the find dialog or C-s if none is otherwise specified." return(ss->search_proc); } static Xen g_set_search_procedure(Xen proc) { char *error = NULL; /* (set! (search-procedure) (lambda (y) #t)) -> # */ Xen_check_type(Xen_is_procedure(proc) || Xen_is_false(proc), proc, 1, S_set S_search_procedure, "a procedure or " PROC_FALSE); error = procedure_ok(proc, 1, S_search_procedure, "search", 1); if (!error) { clear_search_state(); if (Xen_is_procedure(proc)) { ss->search_proc = proc; ss->search_proc_loc = snd_protect(proc); } } else { Xen errstr; errstr = C_string_to_Xen_string(error); free(error); return(snd_bad_arity_error(S_set S_search_procedure, errstr, proc)); } return(proc); } Xen_wrap_no_args(g_search_procedure_w, g_search_procedure) Xen_wrap_1_arg(g_set_search_procedure_w, g_set_search_procedure) void g_init_find(void) { Xen_define_dilambda(S_search_procedure, g_search_procedure_w, H_search_procedure, S_set S_search_procedure, g_set_search_procedure_w, 0, 0, 1, 0); } snd-16.1/hooks.scm0000644000076400007640000000544712463415455012205 0ustar bilbil;;; hook-related functions (provide 'snd-hooks.scm) ;;; -------- snd-hooks (define snd-hooks (let ((documentation "(snd-hooks) -> list of all global (not channel-specific) hooks")) (lambda () (list after-graph-hook after-lisp-graph-hook lisp-graph-hook before-transform-hook mix-release-hook save-hook mus-error-hook mouse-enter-graph-hook mouse-leave-graph-hook open-raw-sound-hook select-channel-hook after-open-hook close-hook drop-hook update-hook mark-click-hook mark-drag-hook name-click-hook open-hook help-hook before-save-state-hook output-comment-hook play-hook snd-error-hook snd-warning-hook start-playing-hook stop-playing-hook mouse-enter-listener-hook mouse-leave-listener-hook select-sound-hook exit-hook during-open-hook after-transform-hook mouse-enter-label-hook mouse-leave-label-hook initial-graph-hook graph-hook key-press-hook mouse-drag-hook mouse-press-hook enved-hook mouse-click-hook new-widget-hook mark-hook stop-playing-selection-hook after-apply-controls-hook draw-mark-hook bad-header-hook save-state-hook new-sound-hook color-hook orientation-hook listener-click-hook mix-click-hook after-save-state-hook mouse-enter-text-hook mouse-leave-text-hook mix-drag-hook start-playing-selection-hook after-save-as-hook before-save-as-hook draw-mix-hook before-exit-hook before-close-hook clip-hook)))) (define reset-all-hooks (let ((documentation "(reset-all-hooks) removes all Snd hook functions")) (lambda () (for-each (lambda (n) (set! (hook-functions n) ())) (snd-hooks)) (for-each (lambda (snd) (do ((chn 0 (+ chn 1))) ((= chn (channels snd))) (set! (hook-functions (edit-hook snd chn)) ()) (set! (hook-functions (after-edit-hook snd chn)) ()) (set! (hook-functions (undo-hook snd chn)) ()))) (sounds))))) ;;; -------- describe-hook (define describe-hook (let ((documentation "(describe-hook hook) -> description of functions on 'hook'")) (lambda (hook) (for-each (lambda (n) (snd-print (format #f "~%~A" n))) (reverse (hook-functions hook)))))) ;;; -------- local hook (define with-local-hook (let ((documentation "(with-local-hook hook local-hook-procs thunk) evaluates thunk with hook set to local-hook-procs (a list), then restores hook to its previous state")) (lambda (hook local-hook-procs thunk) (let ((old-hook-procs (hook-functions hook))) (set! (hook-functions hook) local-hook-procs) (let ((result (thunk))) (set! (hook-functions hook) old-hook-procs) result))))) ;;; -------- hook-member -------- (define hook-member (let ((documentation "(hook-member value hook) returns non-#f if 'value' is a member of the hook's function list")) (lambda (value hook) (member value (hook-functions hook))))) snd-16.1/misc.scm0000644000076400007640000002327212460216426012003 0ustar bilbil(provide 'snd-misc.scm) (if (not (provided? 'snd-motif)) (snd-error "misc.scm only works in the Motif version of Snd.")) (require snd-snd-motif.scm snd-examp.scm snd-extensions.scm snd-dsp.scm snd-draw.scm snd-env.scm snd-enved.scm) (require snd-hooks.scm snd-marks.scm snd-mix.scm snd-moog.scm snd-play.scm snd-rubber.scm snd-zip.scm snd-edit123.scm) (require snd-new-effects.scm snd-special-menu.scm snd-new-backgrounds.scm snd-marks-menu.scm snd-fft-menu.scm snd-effects-utils.scm) (with-let *motif* (keep-file-dialog-open-upon-ok) (set! *ask-about-unsaved-edits* #t) (if (not (hook-member show-disk-space after-open-hook)) (hook-push after-open-hook show-disk-space)) ;(define wd (make-pixmap (cadr (main-widgets)) rough)) ; this comes from new-backgrounds.scm ;(for-each-child (cadr (main-widgets)) (lambda (w) (XtSetValues w (list XmNbackgroundPixmap wd)))) (define wd (make-pixmap (cadr (main-widgets)) rough)) ;(define (paint-all widget) ; (for-each-child ; widget ; (lambda (w) ; (XtSetValues w (list XmNbackgroundPixmap wd))))) (define (paint-all widget) (for-each-child widget (lambda (w) (if (and (Widget? w) (or (not (XmIsPushButton w)) (string=? (XtName w) "revlen-label") (string=? (XtName w) "revscl-label") (string=? (XtName w) "contrast-label") (string=? (XtName w) "expand-label") (string=? (XtName w) "srate-label") (string=? (XtName w) "amp-label"))) (XtSetValues w (list XmNbackgroundPixmap wd)))))) (paint-all (cadr (main-widgets))) (for-each (lambda (w) (if (and w (Widget? w)) (paint-all w))) (dialog-widgets)) (define (hook-paint-all hook) (paint-all (hook 'widget))) (if (not (hook-member hook-paint-all new-widget-hook)) (hook-push new-widget-hook hook-paint-all)) (set! *mix-waveform-height* 32) ;;; (with-level-meters 2) (add-mark-pane) (add-sound-file-extension "ogg") (add-sound-file-extension "OGG") (add-sound-file-extension "sf") (add-sound-file-extension "SF2") (add-sound-file-extension "mp3") (add-sound-file-extension "MP3") (add-sound-file-extension "W01") (add-sound-file-extension "W02") (add-sound-file-extension "W03") (add-sound-file-extension "W04") (add-sound-file-extension "W05") (add-sound-file-extension "W06") (add-sound-file-extension "W07") (add-sound-file-extension "W08") (add-sound-file-extension "W09") (add-sound-file-extension "W10") (add-sound-file-extension "w01") (add-sound-file-extension "w02") (add-sound-file-extension "w03") (add-sound-file-extension "w04") (add-sound-file-extension "w05") (add-sound-file-extension "w06") (add-sound-file-extension "w07") (add-sound-file-extension "w08") (add-sound-file-extension "w09") (add-sound-file-extension "w10") ;;; ;;; disable original Play radio button ;;; ;(hook-push after-open-hook ; (lambda (hook) ; (XtUnmanageChild (find-child (list-ref (sound-widgets (hook 'snd)) 2) "play")))) ;;; ;;; main menu additions ;;; ;;; -------- add delete and rename options to the file menu (define (add-delete-option) (add-to-menu 0 "Delete" ; add Delete option to File menu (lambda () ;; close current sound and delete it (if (>= (selected-sound) 0) (let ((filename (file-name))) (close-sound) (delete-file filename)))) 8)) ; place after File:New (define (add-rename-option) (let ((rename-dialog #f) (rename-text #f)) (add-to-menu 0 "Rename" (lambda () ;; open dialog to get new name, save-as that name, open (if (not rename-dialog) ;; make a standard dialog (let* ((xdismiss (XmStringCreate "Go Away" XmFONTLIST_DEFAULT_TAG)) (xhelp (XmStringCreate "Help" XmFONTLIST_DEFAULT_TAG)) (xok (XmStringCreate "DoIt" XmFONTLIST_DEFAULT_TAG)) (titlestr (XmStringCreate "Rename" XmFONTLIST_DEFAULT_TAG)) (new-dialog (XmCreateTemplateDialog (cadr (main-widgets)) "Rename" (list XmNcancelLabelString xdismiss XmNhelpLabelString xhelp XmNokLabelString xok XmNautoUnmanage #f XmNdialogTitle titlestr XmNresizePolicy XmRESIZE_GROW XmNnoResize #f XmNbackground *basic-color* XmNtransient #f)))) (for-each (lambda (button color) (XtVaSetValues (XmMessageBoxGetChild new-dialog button) (list XmNarmColor *selection-color* XmNbackground color))) (list XmDIALOG_HELP_BUTTON XmDIALOG_CANCEL_BUTTON XmDIALOG_OK_BUTTON) (list *highlight-color* *highlight-color* *highlight-color*)) (XtAddCallback new-dialog XmNcancelCallback (lambda (w c i) (XtUnmanageChild w))) (XtAddCallback new-dialog XmNhelpCallback (lambda (w c i) (help-dialog "Rename" "Give a new file name to rename the currently selected sound."))) (XtAddCallback new-dialog XmNokCallback (lambda (w c i) (let ((new-name (XmTextFieldGetString rename-text))) (if (and (string? new-name) (> (length new-name) 0) (>= (selected-sound) 0)) (let ();(current-name (file-name))) (save-sound-as new-name) (close-sound) ;(rename-file current-name new-name) ;; (delete-file current-name) perhaps? (open-sound new-name) (XtUnmanageChild w)))))) (XmStringFree xhelp) (XmStringFree xok) (XmStringFree xdismiss) (XmStringFree titlestr) (set! rename-dialog new-dialog) (let* ((mainform (XtCreateManagedWidget "formd" xmRowColumnWidgetClass rename-dialog (list XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_WIDGET XmNbottomWidget (XmMessageBoxGetChild rename-dialog XmDIALOG_SEPARATOR) XmNorientation XmVERTICAL XmNbackground *basic-color*))) (label (XtCreateManagedWidget "new name:" xmLabelWidgetClass mainform (list XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_NONE XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_FORM XmNbackground *basic-color*)))) (set! rename-text (XtCreateManagedWidget "newname" xmTextFieldWidgetClass mainform (list XmNleftAttachment XmATTACH_WIDGET XmNleftWidget label XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_FORM XmNbackground *basic-color*))) (XtAddEventHandler rename-text EnterWindowMask #f (lambda (w context ev flag) (XmProcessTraversal w XmTRAVERSE_CURRENT) (XtSetValues w (list XmNbackground (white-pixel))))) (XtAddEventHandler rename-text LeaveWindowMask #f (lambda (w context ev flag) (XtSetValues w (list XmNbackground *basic-color*))))))) (if (not (XtIsManaged rename-dialog)) (XtManageChild rename-dialog) (raise-dialog rename-dialog))) 8))) (install-searcher-with-colors (lambda (file) #t)) (add-delete-option) (add-rename-option) (add-to-menu 1 #f #f) ; separator ;;; ;;; additions to Edit menu ;;; (define selctr 0) ;;; -------- cut selection -> new file (define (cut-selection->new) (if (selection?) (let ((new-file-name (format #f "sel-~D.snd" selctr))) (set! selctr (+ selctr 1)) (save-selection new-file-name) (delete-selection) (open-sound new-file-name)))) ;;; (add-to-menu 1 "Cut Selection -> New" cut-selection->new) ;;; -------- append selection (define (append-selection) (if (selection?) (insert-selection (framples)))) (add-to-menu 1 "Append Selection" append-selection) ;;; Replace with selection ;;; (define (replace-with-selection) (let ((beg (cursor)) (len (selection-framples))) (delete-samples beg len) (insert-selection beg))) (add-to-menu 1 "Replace with Selection" replace-with-selection) ;;; (add-to-menu 1 #f #f) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; open and convert stereo MP3 files automatically ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (hook-push open-raw-sound-hook (lambda (hook) (set! (hook 'result) (list 2 44100 (if (little-endian?) mus-lshort mus-bshort))))) (hook-push open-hook (lambda (hook) (let ((filename (hook 'name))) (if (= (mus-sound-header-type filename) mus-raw) (let ((rawfile (string-append filename ".raw"))) (system (format #f "mpg123 -s ~A > ~A" filename rawfile)) (set! (hook 'result) rawfile)))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; open and convert stereo OGG files automatically ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (hook-push open-raw-sound-hook (lambda (hook) (set! (hook 'result) (list 2 44100 (if (little-endian?) mus-lshort mus-bshort))))) (hook-push open-hook (lambda (hook) (let ((filename (hook 'name))) (if (= (mus-sound-header-type filename) mus-raw) (let ((rawfile (string-append filename ".raw"))) (system (format #f "ogg123 -d raw -f ~A ~A" rawfile filename)) (set! (hook 'result) rawfile)))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; set up a region play list ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (define (region-play-list data) ;; data is list of lists (list (list time region)...), time in secs (for-each (lambda (tone) (let ((time (* 1000 (car tone))) (region (cadr tone))) (if (region? region) (in time (lambda () (play region)))))) data)) ;;; (region-play-list (list (list 0.0 0) (list 0.5 1) (list 1.0 2) (list 1.0 0))) ;;; Deselect function ;;; (define deselect-all unselect-all) ) snd-16.1/snd-gchn.c0000644000076400007640000012542712603035272012213 0ustar bilbil#include "snd.h" enum { W_main_window, W_graph_window, W_wf_buttons, W_f, W_w, W_zy, W_sy, W_bottom_scrollers, W_sx, W_zx, W_graph, W_gzy, W_gsy, W_up_ev, W_down_ev, NUM_CHAN_WIDGETS }; enum {W_zy_adj, W_zx_adj, W_sy_adj, W_sx_adj, W_gzy_adj, W_gsy_adj, NUM_CHAN_ADJS}; GtkWidget *channel_graph(chan_info *cp) {return(cp->chan_widgets[W_graph]);} static GtkWidget *channel_sx(chan_info *cp) {return(cp->chan_widgets[W_sx]);} static GtkWidget *channel_sy(chan_info *cp) {return(cp->chan_widgets[W_sy]);} static GtkWidget *channel_zx(chan_info *cp) {return(cp->chan_widgets[W_zx]);} static GtkWidget *channel_zy(chan_info *cp) {return(cp->chan_widgets[W_zy]);} static GtkWidget *channel_gsy(chan_info *cp) {return(cp->chan_widgets[W_gsy]);} static GtkWidget *channel_gzy(chan_info *cp) {return(cp->chan_widgets[W_gzy]);} GtkWidget *channel_w(chan_info *cp) {return(cp->chan_widgets[W_w]);} GtkWidget *channel_f(chan_info *cp) {return(cp->chan_widgets[W_f]);} GtkWidget *channel_up_arrow(chan_info *cp) {return(cp->chan_widgets[W_up_ev]);} GtkWidget *channel_down_arrow(chan_info *cp) {return(cp->chan_widgets[W_down_ev]);} #define EDIT_HISTORY_LIST(Cp) (Cp)->edhist_list #if GTK_CHECK_VERSION(3, 0, 0) #define EDIT_HISTORY_CLOSED 2 #else #define EDIT_HISTORY_CLOSED 1 #endif /* in gtk2, 0 is a no-op here, leaving the edit history pane open, * but in gtk 3 if less than about 30, we get * "Gtk-CRITICAL **: gtk_paint_slider: assertion `width >= 0' failed" * (which means the damned thing has to be open always) * or if we hide the scrolled text widget, the pane separator goes away! * So, in gtk3 the scrolled window does not display a horizontal scrollbar */ static GtkWidget *channel_main_pane(chan_info *cp) {return(cp->chan_widgets[W_main_window]);} static GtkAdjustment *gsy_adj(chan_info *cp) {return(cp->chan_adjs[W_gsy_adj]);} static GtkAdjustment *gzy_adj(chan_info *cp) {return(cp->chan_adjs[W_gzy_adj]);} static GtkAdjustment *sy_adj(chan_info *cp) {return(cp->chan_adjs[W_sy_adj]);} static GtkAdjustment *sx_adj(chan_info *cp) {return(cp->chan_adjs[W_sx_adj]);} static GtkAdjustment *zy_adj(chan_info *cp) {return(cp->chan_adjs[W_zy_adj]);} static GtkAdjustment *zx_adj(chan_info *cp) {return(cp->chan_adjs[W_zx_adj]);} static mus_float_t sqr(mus_float_t a) {return(a * a);} static mus_float_t cube(mus_float_t a) {return(a * a * a);} bool channel_graph_is_visible(chan_info *cp) { return((cp) && (cp->chan_widgets) && (channel_graph(cp)) && (widget_is_active(channel_graph(cp))) && (cp->sound) && /* here we may have a sound wrapper for variable display in which case the sound widgets are not implemented */ (((cp->sound->inuse == SOUND_WRAPPER) || (cp->sound->inuse == SOUND_REGION)) || ((cp->sound->inuse == SOUND_NORMAL) && /* other choice: SOUND_IDLE -> no display */ (w_snd_pane(cp->sound)) && (widget_is_active(w_snd_pane(cp->sound)))))); } void channel_open_pane(chan_info *cp) { gtk_widget_show(channel_main_pane(cp)); } static void sy_changed(float value, chan_info *cp) { axis_info *ap; ap = cp->axis; ap->sy = value - ap->zy; if (ap->sy < 0.0) ap->sy = 0.0; apply_y_axis_change(cp); } static void sx_changed(float value, chan_info *cp) { axis_info *ap; ap = cp->axis; ap->sx = value; apply_x_axis_change(cp); } static void zy_changed(float value, chan_info *cp) { axis_info *ap; mus_float_t old_zy; ap = cp->axis; if (value < .01) value = .01; old_zy = ap->zy; ap->zy = sqr(value); if (ap->zy < 1e-5) ap->zy = 1e-5; ap->sy += (.5 * (old_zy - ap->zy)); /* try to keep wave centered */ if (ap->sy < 0) ap->sy = 0; apply_y_axis_change(cp); resize_sy(cp); } #define X_RANGE_CHANGEOVER 20.0 static void zx_changed(float value, chan_info *cp) { axis_info *ap; double old_zx = 0.0; ap = cp->axis; if (ap->xmax == 0.0) return; if (ap->xmax <= ap->xmin) { ap->xmax = ap->xmin + .001; ap->x_ambit = .001; } if (value < .01) value = .01; old_zx = ap->zx; if (ap->x_ambit < X_RANGE_CHANGEOVER) ap->zx = sqr(value); else ap->zx = cube(value); if (fabs(old_zx - ap->zx) > .00001) /* click on zoom is moving the window */ { /* if cursor visible, focus on that, else selection, else mark, else left side */ focus_x_axis_change(cp, zoom_focus_style(ss)); /* focus_x_axis_change has already displayed the new graph, but in gtk the scrollbar setting * in resize_sx will try to display everything again. So try to squelch it... */ if (!(cp->squelch_update)) { cp->squelch_update = true; resize_sx(cp); cp->squelch_update = false; clear_status_area(cp->sound); /* erase the "(update squelched)" message */ } else resize_sx(cp); } } static void set_scrollbar(GtkAdjustment *adj, mus_float_t position, mus_float_t range) /* position and range 0 to 1.0 */ { ADJUSTMENT_SET_PAGE_SIZE(adj, range); ADJUSTMENT_SET_VALUE(adj, position); } /* restore_axes_data (snd-file.c) assumes change_gzy also fixes gsy */ void change_gzy(mus_float_t val, chan_info *cp) { /* from snd_update */ ADJUSTMENT_SET_PAGE_SIZE(gsy_adj(cp), 1.0 - val); ADJUSTMENT_SET_VALUE(gsy_adj(cp), cp->gsy); ADJUSTMENT_SET_VALUE(gzy_adj(cp), val); } mus_float_t gsy_value(chan_info *cp) { return(1.0 - (cp->gsy + ADJUSTMENT_PAGE_SIZE(gsy_adj(cp)))); } mus_float_t gsy_size(chan_info *cp) { return(ADJUSTMENT_PAGE_SIZE(gsy_adj(cp))); } static void set_zx(chan_info *cp, axis_info *ap) { if (ap->x_ambit < X_RANGE_CHANGEOVER) set_scrollbar(zx_adj(cp), sqrt(ap->zx), .1); /* assume size is 10% of scrollbar length */ else set_scrollbar(zx_adj(cp), pow(ap->zx, .333), .1); } void set_z_scrollbars(chan_info *cp, axis_info *ap) { set_zx(cp, ap); set_scrollbar(zy_adj(cp), 1.0 - sqrt(ap->zy), .1); } void initialize_scrollbars(chan_info *cp) { axis_info *ap; snd_info *sp; cp->gzy = 0.0; cp->gsy = 0.0; ap = cp->axis; sp = cp->sound; set_scrollbar(sx_adj(cp), ap->sx, ap->zx); set_scrollbar(sy_adj(cp), 1.0 - ap->sy, ap->zy); set_z_scrollbars(cp, ap); if ((sp->nchans > 1) && (cp->chan == 0) && (gsy_adj(cp))) { set_scrollbar(gsy_adj(cp), 0.0, 1.0); set_scrollbar(gzy_adj(cp), 0.0, 1.0 / (mus_float_t)(sp->nchans)); } } void resize_sy(chan_info *cp) { /* something changed the y axis view, so the scale scroller needs to reflect that change (in size and position) */ axis_info *ap; ap = cp->axis; if (ap->y_ambit != 0.0) { mus_float_t size; size = (ap->y1 - ap->y0) / ap->y_ambit; set_scrollbar(sy_adj(cp), 1.0 - ((ap->y0 - ap->ymin) / ap->y_ambit + size), size); } } void resize_sy_and_zy(chan_info *cp) { resize_sy(cp); set_scrollbar(zy_adj(cp), 1.0 - sqrt(cp->axis->zy), .1); } void resize_sx(chan_info *cp) { axis_info *ap; ap = cp->axis; if (ap->x_ambit != 0.0) set_scrollbar(sx_adj(cp), (ap->x0 - ap->xmin) / ap->x_ambit, (ap->x1 - ap->x0) / ap->x_ambit); } void resize_sx_and_zx(chan_info *cp) { resize_sx(cp); set_zx(cp, cp->axis); } static void sy_valuechanged_callback(GtkAdjustment *adj, gpointer context) { /* see note above -- context may be garbage!! -- this is a huge bug in gtk */ static bool ignore_sy_valuechanged_callback = false; chan_info *cp; cp = (chan_info *)get_user_data(G_OBJECT(adj)); if ((cp->active == CHANNEL_HAS_AXES) && (!ignore_sy_valuechanged_callback)) { ignore_sy_valuechanged_callback = true; sy_changed(1.0 - ADJUSTMENT_VALUE(adj), cp); ignore_sy_valuechanged_callback = false; } } static void sx_valuechanged_callback(GtkAdjustment *adj, gpointer context) { static bool ignore_sx_valuechanged_callback = false; chan_info *cp; cp = (chan_info *)get_user_data(G_OBJECT(adj)); if ((cp->active == CHANNEL_HAS_AXES) && (!ignore_sx_valuechanged_callback)) { ignore_sx_valuechanged_callback = true; sx_changed(ADJUSTMENT_VALUE(adj), cp); ignore_sx_valuechanged_callback = false; } } static void zy_valuechanged_callback(GtkAdjustment *adj, gpointer context) { static bool ignore_zy_valuechanged_callback = false; chan_info *cp; cp = (chan_info *)get_user_data(G_OBJECT(adj)); if ((cp->active == CHANNEL_HAS_AXES) && (!ignore_zy_valuechanged_callback)) { ignore_zy_valuechanged_callback = true; zy_changed(1.0 - ADJUSTMENT_VALUE(adj), cp); ignore_zy_valuechanged_callback = false; } } static void zx_valuechanged_callback(GtkAdjustment *adj, gpointer context) { chan_info *cp; static bool ignore_zx_valuechanged_callback = false; /*see below */ cp = (chan_info *)get_user_data(G_OBJECT(adj)); if ((cp->active == CHANNEL_HAS_AXES) && (!ignore_zx_valuechanged_callback)) { ignore_zx_valuechanged_callback = true; zx_changed(ADJUSTMENT_VALUE(adj), cp); ignore_zx_valuechanged_callback = false; } /* it's easy to get infinite recursion here: * zx_changed -> focus_x_axis_change -> apply_x_axis_change -> update_xs -> reset_x_display -> resize_sx -> set_scrollbar -> * sx_valuechanged_callback -> apply_x_axis_change -> update_xs -> reset_x_display -> resize_sx_and_zx -> resize_sx * and we're looping! This loop happens now because the gtk 3 changes (hiding the adjustment struct) mean that * we're using gtk_adjustment_set_value which triggers the valuechanged callback, whereas earlier we were * simply setting the field, and not triggering the callback. Good Grief! * * I added the guards, but now the sliders seem glitchy -- certainly not smooth! */ } static void gzy_valuechanged_callback(GtkAdjustment *adj, gpointer context) { chan_info *cp; cp = (chan_info *)get_user_data(G_OBJECT(adj)); cp->gzy = ADJUSTMENT_VALUE(adj); if (cp->active == CHANNEL_HAS_AXES) { ADJUSTMENT_SET_PAGE_SIZE(gsy_adj(cp), 1.0 - ADJUSTMENT_VALUE(adj)); if (cp->gsy > cp->gzy) { cp->gsy = ADJUSTMENT_VALUE(adj); ADJUSTMENT_SET_VALUE(gsy_adj(cp), cp->gsy); } #if (!(GTK_CHECK_VERSION(3, 18, 0))) else gtk_adjustment_changed(GTK_ADJUSTMENT(gsy_adj(cp))); #endif for_each_sound_chan(cp->sound, update_graph_or_warn); } } static void gsy_valuechanged_callback(GtkAdjustment *adj, gpointer context) { chan_info *cp; cp = (chan_info *)get_user_data(G_OBJECT(adj)); cp->gsy = ADJUSTMENT_VALUE(adj); if (cp->active == CHANNEL_HAS_AXES) for_each_sound_chan(cp->sound, update_graph_or_warn); } static int last_f_state = 0; static gboolean f_toggle_callback(GtkWidget *w, GdkEventButton *ev, gpointer data) { last_f_state = EVENT_STATE(ev); return(false); } static void f_toggle_click_callback(GtkWidget *w, gpointer data) { f_button_callback((chan_info *)data, TOGGLE_BUTTON_ACTIVE(w), (last_f_state & snd_ControlMask)); } static int last_w_state = 0; static gboolean w_toggle_callback(GtkWidget *w, GdkEventButton *ev, gpointer data) { last_w_state = EVENT_STATE(ev); return(false); } static void w_toggle_click_callback(GtkWidget *w, gpointer data) { w_button_callback((chan_info *)data, TOGGLE_BUTTON_ACTIVE(w), (last_w_state & snd_ControlMask)); } #define MIN_REGRAPH_X 12 #define MIN_REGRAPH_Y 7 static gboolean channel_expose_callback(GtkWidget *w, GdkEventExpose *ev, gpointer data) { chan_info *cp; snd_info *sp; cp = (chan_info *)data; if ((cp == NULL) || (cp->active < CHANNEL_HAS_AXES) || (cp->sound == NULL)) return(false); #if (!GTK_CHECK_VERSION(3, 0, 0)) if ((EVENT_AREA_HEIGHT(ev) < MIN_REGRAPH_Y) || (EVENT_AREA_WIDTH(ev) < MIN_REGRAPH_X)) return(false); /* these are 0 in gtk 3 */ #endif sp = cp->sound; if (sp->channel_style != CHANNELS_SEPARATE) for_each_sound_chan(sp, update_graph_or_warn); else update_graph_or_warn(cp); return(false); } static gboolean channel_resize_callback(GtkWidget *w, GdkEventConfigure *ev, gpointer data) { channel_resize((chan_info *)data); return(false); } static Xen mouse_enter_graph_hook; static Xen mouse_leave_graph_hook; static gboolean graph_mouse_enter(GtkWidget *w, GdkEventCrossing *ev, gpointer data) { /* how many args does this thing take? does it return an int? what does the return value mean? */ if (with_pointer_focus(ss)) goto_window(w); if (Xen_hook_has_list(mouse_enter_graph_hook)) { int pdata; pdata = get_user_int_data(G_OBJECT(w)); run_hook(mouse_enter_graph_hook, Xen_list_2(C_int_to_Xen_sound(unpack_sound(pdata)), C_int_to_Xen_integer(unpack_channel(pdata))), S_mouse_enter_graph_hook); } gdk_window_set_cursor(WIDGET_TO_WINDOW(w), ss->graph_cursor); return(false); } static gboolean graph_mouse_leave(GtkWidget *w, GdkEventCrossing *ev, gpointer data) { if (Xen_hook_has_list(mouse_leave_graph_hook)) { int pdata; pdata = get_user_int_data(G_OBJECT(w)); run_hook(mouse_leave_graph_hook, Xen_list_2(C_int_to_Xen_sound(unpack_sound(pdata)), C_int_to_Xen_integer(unpack_channel(pdata))), S_mouse_leave_graph_hook); } gdk_window_set_cursor(WIDGET_TO_WINDOW(w), ss->arrow_cursor); return(false); } static void hide_gz_scrollbars(snd_info *sp) { chan_info *cp; cp = sp->chans[0]; if (channel_gsy(cp)) { gtk_widget_hide(channel_gsy(cp)); gtk_widget_hide(channel_gzy(cp)); } } static void show_gz_scrollbars(snd_info *sp) { chan_info *cp; cp = sp->chans[0]; if (channel_gsy(cp)) { gtk_widget_show(channel_gsy(cp)); gtk_widget_show(channel_gzy(cp)); } } /* edit history support */ static void history_select_callback(const char *name, int row, void *data) { edit_history_select((chan_info *)data, row); } static void remake_edit_history(chan_info *cp) { snd_info *sp; int i, eds; slist *lst; if ((!cp) || (cp->active < CHANNEL_HAS_AXES)) return; if (cp->squelch_update) return; lst = EDIT_HISTORY_LIST(cp); if (!lst) return; /* if you try to update something in a closed pane, goddamn gtk grinds to a halt */ if (gtk_paned_get_position(GTK_PANED(cp->chan_widgets[W_main_window])) < 10) return; slist_clear(lst); sp = cp->sound; if (sp->channel_style != CHANNELS_SEPARATE) { int k, ed, filelen; char *title; chan_info *ncp; filelen = 16 + strlen(sp->filename); title = (char *)calloc(filelen, sizeof(char)); for (k = 0, ed = 0; k < sp->nchans; k++) { ncp = sp->chans[k]; if ((ncp) && (ncp->sound)) { ncp->edhist_base = ed++; snprintf(title, filelen, "chan %d: %s", k + 1, sp->filename); slist_append(lst, title); eds = ncp->edit_ctr; while ((eds < (ncp->edit_size - 1)) && (ncp->edits[eds + 1])) eds++; for (i = 1; i <= eds; i++, ed++) { char *str; str = edit_to_string(ncp, i); slist_append(lst, str); free(str); } if (k < sp->nchans - 1) { slist_append(lst, "______________________________"); ed++; } } } if (sp->selected_channel == NO_SELECTION) slist_select(lst, cp->edhist_base + cp->edit_ctr); else slist_select(lst, sp->chans[sp->selected_channel]->edhist_base + sp->chans[sp->selected_channel]->edit_ctr); free(title); } else { eds = cp->edit_ctr; while ((eds < (cp->edit_size - 1)) && (cp->edits[eds + 1])) eds++; if (eds >= 0) { slist_append(lst, sp->filename); for (i = 1; i <= eds; i++) { char *str; str = edit_to_string(cp, i); slist_append(lst, str); free(str); } } slist_select(lst, cp->edit_ctr); } goto_graph(cp); } void reflect_edit_history_change(chan_info *cp) { /* new edit so it is added, and any trailing lines removed */ snd_info *sp; if (cp->squelch_update) return; if (cp->in_as_one_edit > 0) return; sp = cp->sound; if ((cp->chan > 0) && (sp->channel_style != CHANNELS_SEPARATE)) { chan_info *ncp; ncp = sp->chans[0]; if ((ncp) && (ncp->sound)) remake_edit_history(ncp); } else remake_edit_history(cp); } void reflect_edit_counter_change(chan_info *cp) { /* undo/redo/revert -- change which line is highlighted */ snd_info *sp; slist *lst; if (cp->squelch_update) return; sp = cp->sound; if ((cp->chan > 0) && (sp->channel_style != CHANNELS_SEPARATE)) { chan_info *ncp; ncp = sp->chans[0]; lst = EDIT_HISTORY_LIST(ncp); if ((!lst) || (!(lst->items))) return; if (gtk_paned_get_position(GTK_PANED(cp->chan_widgets[W_main_window])) < 10) return; slist_select(lst, cp->edit_ctr + cp->edhist_base); } else { lst = EDIT_HISTORY_LIST(cp); if ((!lst) || (!(lst->items))) return; if (widget_width(lst->scroller) < 10) return; slist_select(lst, cp->edit_ctr); slist_moveto(lst, cp->edit_ctr); goto_graph(cp); } } /* for combined cases, the incoming chan_info pointer is always chan[0], * but the actual channel depends on placement if mouse oriented. * virtual_selected_channel(cp) (snd-chn.c) retains the current selected channel */ static gboolean real_graph_key_press(GtkWidget *w, GdkEventKey *ev, gpointer data) { chan_info *cp = (chan_info *)data; int keysym; /* window_get_pointer(ev, &x, &y, &key_state); * the x and y coordinates apparently refer to the mouse, * and are only used to recognize "lisp-graph" oriented keystrokes. * These are then used only if there is also a key_press_hook. */ keysym = EVENT_KEYVAL(ev); #if GTK_CHECK_VERSION(3, 0, 0) key_press_callback(cp, 0, 0, EVENT_STATE(ev), keysym); #else { int x, y; GdkModifierType key_state; window_get_pointer(ev, &x, &y, &key_state); key_press_callback(cp, x, y, EVENT_STATE(ev), keysym); } #endif g_signal_stop_emission((gpointer)w, g_signal_lookup("key_press_event", G_OBJECT_TYPE((gpointer)w)), 0); return(true); } gboolean graph_key_press(GtkWidget *w, GdkEventKey *ev, gpointer data) { chan_info *cp = (chan_info *)data; int keysym; keysym = EVENT_KEYVAL(ev); #if GTK_CHECK_VERSION(3, 0, 0) key_press_callback(cp, 0, 0, EVENT_STATE(ev), keysym); #else { int x, y; GdkModifierType key_state; window_get_pointer(ev, &x, &y, &key_state); key_press_callback(cp, x, y, EVENT_STATE(ev), keysym); } #endif return(true); } static gboolean graph_button_press(GtkWidget *w, GdkEventButton *ev, gpointer data) { chan_info *cp = (chan_info *)data; ss->graph_is_active = true; gtk_widget_grab_focus(w); graph_button_press_callback(cp, (void *)ev, (int)(EVENT_X(ev)), (int)(EVENT_Y(ev)), EVENT_STATE(ev), EVENT_BUTTON(ev), EVENT_TIME(ev)); return(false); } static gboolean graph_button_release(GtkWidget *w, GdkEventButton *ev, gpointer data) { graph_button_release_callback((chan_info *)data, (int)(EVENT_X(ev)), (int)(EVENT_Y(ev)), EVENT_STATE(ev), EVENT_BUTTON(ev)); return(false); } static gboolean graph_button_motion(GtkWidget *w, GdkEventMotion *ev, gpointer data) { int x, y; GdkModifierType state; if (EVENT_IS_HINT(ev)) window_get_pointer(ev, &x, &y, &state); else { x = (int)(EVENT_X(ev)); y = (int)(EVENT_Y(ev)); } if (BUTTON1_PRESSED(EVENT_STATE(ev))) graph_button_motion_callback((chan_info *)data, x, y, EVENT_TIME(ev)); else check_cursor_shape((chan_info *)data, x, y); return(false); } static void channel_drop_watcher(GtkWidget *w, const char *filename, int x, int y, void *data) { drag_and_drop_mix_at_x_y(get_user_int_data(G_OBJECT(w)), filename, x, y); } static void channel_drag_watcher(GtkWidget *w, const char *filename, int x, int y, drag_style_t dtype, void *context) { int snd, chn, data; snd_info *sp; data = get_user_int_data(G_OBJECT(w)); chn = unpack_channel(data); snd = unpack_sound(data); sp = ss->sounds[snd]; if (snd_ok(sp)) { chan_info *cp; float seconds; switch (dtype) { case DRAG_ENTER: case DRAG_MOTION: cp = sp->chans[chn]; if ((sp->nchans > 1) && (sp->channel_style == CHANNELS_COMBINED)) cp = which_channel(sp, y); seconds = (float)(ungrf_x(cp->axis, x)); if (seconds < 0.0) seconds = 0.0; if (sp->nchans > 1) status_report(sp, "drop to mix file in chan %d at %.4f", cp->chan + 1, seconds); else status_report(sp, "drop to mix file at %.4f", seconds); break; case DRAG_LEAVE: set_status(sp, " ", false); /* not clear_status_area here! => segfault */ break; } } } int add_channel_window(snd_info *sp, int channel, int chan_y, int insertion, GtkWidget *main, fw_button_t button_style, bool with_events) { GtkWidget **cw; GtkAdjustment **adjs; chan_info *cp; graphics_context *cax; bool make_widgets, need_extra_scrollbars; make_widgets = ((sp->chans[channel]) == NULL); sp->chans[channel] = make_chan_info(sp->chans[channel], channel, sp); cp = sp->chans[channel]; if (cp->chan_widgets == NULL) { cw = (GtkWidget **)calloc(NUM_CHAN_WIDGETS, sizeof(GtkWidget *)); adjs = (GtkAdjustment **)calloc(NUM_CHAN_ADJS, sizeof(GtkAdjustment *)); cp->chan_widgets = cw; cp->chan_adjs = adjs; } else { cw = cp->chan_widgets; adjs = cp->chan_adjs; } need_extra_scrollbars = ((!main) && (channel == 0)); if (make_widgets) { if (!main) { cw[W_main_window] = gtk_hpaned_new(); add_paned_style(cw[W_main_window]); gtk_container_set_border_width(GTK_CONTAINER(cw[W_main_window]), 2); gtk_box_pack_start(GTK_BOX(w_snd_pane_box(sp)), cw[W_main_window], true, true, 0); cp->edhist_list = slist_new(cw[W_main_window], NULL, 0, PANED_ADD1); #if GTK_CHECK_VERSION(3, 0, 0) gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(cp->edhist_list->scroller), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); #else gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(cp->edhist_list->scroller), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); #endif cp->edhist_list->select_callback = history_select_callback; cp->edhist_list->select_callback_data = (void *)cp; } else cw[W_main_window] = main; cw[W_graph_window] = gtk_table_new(3, 5, false); if ((GTK_IS_VPANED(cw[W_main_window])) || (GTK_IS_HPANED(cw[W_main_window]))) gtk_paned_add2(GTK_PANED(cw[W_main_window]), cw[W_graph_window]); else { if ((GTK_IS_VBOX(cw[W_main_window])) || (GTK_IS_HBOX(cw[W_main_window]))) gtk_box_pack_start(GTK_BOX(cw[W_main_window]), cw[W_graph_window], true, true, 4); else gtk_container_add(GTK_CONTAINER(cw[W_main_window]), cw[W_graph_window]); } gtk_widget_set_size_request(cw[W_graph_window], -1, chan_y); cw[W_graph] = gtk_drawing_area_new(); add_drag_and_drop(cw[W_graph], channel_drop_watcher, channel_drag_watcher, NULL); set_user_int_data(G_OBJECT(cw[W_graph]), pack_sound_and_channel(sp->index, cp->chan)); gtk_widget_set_events(cw[W_graph], GDK_ALL_EVENTS_MASK); SET_CAN_FOCUS(cw[W_graph]); widget_set_hexpand(cw[W_graph], true); widget_set_vexpand(cw[W_graph], true); gtk_table_attach(GTK_TABLE(cw[W_graph_window]), cw[W_graph], 2, 3, 0, 2, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)(GTK_FILL | GTK_EXPAND | GTK_SHRINK), 0, 0); gtk_widget_show(cw[W_graph]); if (with_events) { SG_SIGNAL_CONNECT(cw[W_graph], DRAW_SIGNAL, channel_expose_callback, cp); SG_SIGNAL_CONNECT(cw[W_graph], "configure_event", channel_resize_callback, cp); } SG_SIGNAL_CONNECT(cw[W_graph], "button_press_event", graph_button_press, cp); SG_SIGNAL_CONNECT(cw[W_graph], "button_release_event", graph_button_release, cp); SG_SIGNAL_CONNECT(cw[W_graph], "motion_notify_event", graph_button_motion, cp); if (main == NULL) { SG_SIGNAL_CONNECT(cw[W_graph], "enter_notify_event", graph_mouse_enter, NULL); SG_SIGNAL_CONNECT(cw[W_graph], "leave_notify_event", graph_mouse_leave, NULL); SG_SIGNAL_CONNECT(cw[W_graph], "key_press_event", real_graph_key_press, cp); } cw[W_bottom_scrollers] = gtk_vbox_new(true, 0); gtk_box_set_spacing(GTK_BOX(cw[W_bottom_scrollers]), 0); gtk_table_attach(GTK_TABLE(cw[W_graph_window]), cw[W_bottom_scrollers], 2, 3, 2, 3, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)(GTK_FILL), 0, 0); gtk_widget_show(cw[W_bottom_scrollers]); adjs[W_sx_adj] = (GtkAdjustment *)gtk_adjustment_new(0.0, 0.0, 1.00, 0.001, 0.01, .01); cw[W_sx] = gtk_hscrollbar_new(GTK_ADJUSTMENT(adjs[W_sx_adj])); gtk_box_pack_start(GTK_BOX(cw[W_bottom_scrollers]), cw[W_sx], true, true, 0); set_user_data(G_OBJECT(adjs[W_sx_adj]), (gpointer)cp); SG_SIGNAL_CONNECT(adjs[W_sx_adj], "value_changed", sx_valuechanged_callback, cp); gtk_widget_show(cw[W_sx]); gtk_widget_set_name(cw[W_sx], "sx_slider"); adjs[W_zx_adj] = (GtkAdjustment *)gtk_adjustment_new(0.0, 0.0, 1.1, 0.001, 0.01, .1); cw[W_zx] = gtk_hscrollbar_new(GTK_ADJUSTMENT(adjs[W_zx_adj])); gtk_box_pack_start(GTK_BOX(cw[W_bottom_scrollers]), cw[W_zx], true, true, 0); set_user_data(G_OBJECT(adjs[W_zx_adj]), (gpointer)cp); SG_SIGNAL_CONNECT(adjs[W_zx_adj], "value_changed", zx_valuechanged_callback, cp); gtk_widget_set_name(cw[W_zx], "zx_slider"); gtk_widget_show(cw[W_zx]); cw[W_wf_buttons] = gtk_vbox_new(true, 0); gtk_table_attach(GTK_TABLE(cw[W_graph_window]), cw[W_wf_buttons], 0, 2, 1, 3, GTK_SHRINK, GTK_SHRINK, 0, 0); gtk_widget_show(cw[W_wf_buttons]); if (button_style == WITH_FW_BUTTONS) { cw[W_f] = gtk_check_button_new_with_label("f"); add_tooltip(cw[W_f], "show fft"); gtk_box_pack_start(GTK_BOX(cw[W_wf_buttons]), cw[W_f], true, true, 0); gtk_widget_show(cw[W_f]); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cw[W_f]), false); SG_SIGNAL_CONNECT(cw[W_f], "button_press_event", f_toggle_callback, cp); SG_SIGNAL_CONNECT(cw[W_f], "toggled", f_toggle_click_callback, cp); cw[W_w] = gtk_check_button_new_with_label("w"); add_tooltip(cw[W_f], "show wave"); gtk_box_pack_start(GTK_BOX(cw[W_wf_buttons]), cw[W_w], true, true, 0); gtk_widget_show(cw[W_w]); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cw[W_w]), true); SG_SIGNAL_CONNECT(cw[W_w], "button_press_event", w_toggle_callback, cp); SG_SIGNAL_CONNECT(cw[W_w], "toggled", w_toggle_click_callback, cp); } else { #if GTK_CHECK_VERSION(3, 14, 0) GtkIconTheme *icon_theme; icon_theme = gtk_icon_theme_get_default(); #endif cw[W_up_ev] = gtk_event_box_new(); gtk_box_pack_start(GTK_BOX(cw[W_wf_buttons]), cw[W_up_ev], true, true, 0); gtk_widget_show(cw[W_up_ev]); /* gtk_arrow is deprecated -- docs say: use GtkImage with a suitable icon * but the damned "suitable icon" is specific to some ugly Gnome theme, * so I'll conjure up some "^" and "v" images I guess -- insert flame here. */ #if GTK_CHECK_VERSION(3, 14, 0) cw[W_f] = gtk_image_new_from_pixbuf(gtk_icon_theme_load_icon(icon_theme, "pan-up-symbolic", 16, (GtkIconLookupFlags)0, NULL)); #else cw[W_f] = gtk_arrow_new(GTK_ARROW_UP, GTK_SHADOW_ETCHED_OUT); #endif gtk_container_add(GTK_CONTAINER(cw[W_up_ev]), GTK_WIDGET(cw[W_f])); gtk_widget_show(cw[W_f]); cw[W_down_ev] = gtk_event_box_new(); gtk_box_pack_start(GTK_BOX(cw[W_wf_buttons]), cw[W_down_ev], true, true, 0); gtk_widget_show(cw[W_down_ev]); #if GTK_CHECK_VERSION(3, 14, 0) cw[W_w] = gtk_image_new_from_pixbuf(gtk_icon_theme_load_icon(icon_theme, "pan-down-symbolic", 16, (GtkIconLookupFlags)0, NULL)); #else cw[W_w] = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_ETCHED_OUT); #endif gtk_container_add(GTK_CONTAINER(cw[W_down_ev]), GTK_WIDGET(cw[W_w])); gtk_widget_show(cw[W_w]); } adjs[W_zy_adj] = (GtkAdjustment *)gtk_adjustment_new(0.0, 0.0, 1.1, 0.001, 0.01, .1); /* 0 -> 1 (upside down) */ cw[W_zy] = gtk_vscrollbar_new(GTK_ADJUSTMENT(adjs[W_zy_adj])); widget_set_vexpand(cw[W_zy], true); gtk_table_attach(GTK_TABLE(cw[W_graph_window]), cw[W_zy], 0, 1, 0, 1, (GtkAttachOptions)(GTK_FILL), (GtkAttachOptions)(GTK_EXPAND | GTK_FILL | GTK_SHRINK), 2, 0); set_user_data(G_OBJECT(adjs[W_zy_adj]), (gpointer)cp); SG_SIGNAL_CONNECT(adjs[W_zy_adj], "value_changed", zy_valuechanged_callback, cp); gtk_widget_show(cw[W_zy]); gtk_widget_set_name(cw[W_zy], "zy_slider"); adjs[W_sy_adj] = (GtkAdjustment *)gtk_adjustment_new(0.5, 0.0, 1.01, 0.001, 0.01, .01); cw[W_sy] = gtk_vscrollbar_new(GTK_ADJUSTMENT(adjs[W_sy_adj])); widget_set_vexpand(cw[W_sy], true); gtk_table_attach(GTK_TABLE(cw[W_graph_window]), cw[W_sy], 1, 2, 0, 1, (GtkAttachOptions)(GTK_FILL), (GtkAttachOptions)(GTK_EXPAND | GTK_FILL | GTK_SHRINK), 2, 0); set_user_data(G_OBJECT(adjs[W_sy_adj]), (gpointer)cp); SG_SIGNAL_CONNECT(adjs[W_sy_adj], "value_changed", sy_valuechanged_callback, cp); gtk_widget_show(cw[W_sy]); gtk_widget_set_name(cw[W_sy], "sy_slider"); if (need_extra_scrollbars) { adjs[W_gsy_adj] = (GtkAdjustment *)gtk_adjustment_new(0.0, 0.0, 1.0, 0.001, 0.01, .01); cw[W_gsy] = gtk_vscrollbar_new(GTK_ADJUSTMENT(adjs[W_gsy_adj])); gtk_table_attach(GTK_TABLE(cw[W_graph_window]), cw[W_gsy], 3, 4, 0, 2, (GtkAttachOptions)(GTK_FILL), (GtkAttachOptions)(GTK_EXPAND | GTK_FILL | GTK_SHRINK), 0, 0); set_user_data(G_OBJECT(adjs[W_gsy_adj]), (gpointer)cp); SG_SIGNAL_CONNECT(adjs[W_gsy_adj], "value_changed", gsy_valuechanged_callback, cp); gtk_widget_show(cw[W_gsy]); gtk_widget_set_name(cw[W_gsy], "gsy_slider"); adjs[W_gzy_adj] = (GtkAdjustment *)gtk_adjustment_new(1.0, 0.0, 1.00, 0.001, 0.01, .01); cw[W_gzy] = gtk_vscrollbar_new(GTK_ADJUSTMENT(adjs[W_gzy_adj])); gtk_table_attach(GTK_TABLE(cw[W_graph_window]), cw[W_gzy], 4, 5, 0, 2, (GtkAttachOptions)(GTK_FILL), (GtkAttachOptions)(GTK_EXPAND | GTK_FILL | GTK_SHRINK), 0, 0); set_user_data(G_OBJECT(adjs[W_gzy_adj]), (gpointer)cp); SG_SIGNAL_CONNECT(adjs[W_gzy_adj], "value_changed", gzy_valuechanged_callback, cp); gtk_widget_show(cw[W_gzy]); gtk_widget_set_name(cw[W_gzy], "gzy_slider"); gtk_widget_hide(cw[W_gsy]); gtk_widget_hide(cw[W_gzy]); } else { cw[W_gsy] = NULL; cw[W_gzy] = NULL; } if ((GTK_IS_VPANED(cw[W_main_window])) || (GTK_IS_HPANED(cw[W_main_window]))) gtk_paned_set_position(GTK_PANED(cw[W_main_window]), EDIT_HISTORY_CLOSED); gtk_widget_show(cw[W_graph_window]); } else recolor_graph(cp, false); /* in case selection color left over from previous use */ if ((sp->channel_style != CHANNELS_COMBINED) || (channel == 0)) gtk_widget_show_all(cw[W_main_window]); if ((need_extra_scrollbars) && (sp->channel_style != CHANNELS_COMBINED)) hide_gz_scrollbars(sp); /* default is on in this case */ reflect_edit_history_change(cp); cax = cp->ax; cax->gc = ss->basic_gc; /* cax->wn has to wait until update_graph */ { GtkWidget *w; w = channel_to_widget(cp); cax->wn = WIDGET_TO_WINDOW(w); cax->w = w; } return(0); } static void set_graph_font(chan_info *cp, graphics_context *ax, PangoFontDescription *fnt) { ax->current_font = fnt; } void set_peak_numbers_font(chan_info *cp, graphics_context *ax) {set_graph_font(cp, ax, PEAKS_FONT(ss));} void set_tiny_numbers_font(chan_info *cp, graphics_context *ax) {set_graph_font(cp, ax, TINY_FONT(ss));} void set_bold_peak_numbers_font(chan_info *cp, graphics_context *ax) {set_graph_font(cp, ax, BOLD_PEAKS_FONT(ss));} color_t get_foreground_color(graphics_context *ax) { return(ax->gc->fg_color); } void set_foreground_color(graphics_context *ax, color_info *color) { gc_set_foreground(ax->gc, color); } gc_t *copy_GC(chan_info *cp) { if (cp->selected) return(ss->selected_basic_gc); return(ss->basic_gc); } gc_t *erase_GC(chan_info *cp) { snd_info *sp; sp = cp->sound; if ((cp->selected) || ((sp) && (sp->channel_style == CHANNELS_SUPERIMPOSED) && (sp->index == ss->selected_sound))) return(ss->selected_erase_gc); return(ss->erase_gc); } void cleanup_cw(chan_info *cp) { if (cp) { GtkWidget **cw; cp->progress_pct = -1.0; if (EDIT_HISTORY_LIST(cp)) { slist_clear(EDIT_HISTORY_LIST(cp)); gtk_paned_set_position(GTK_PANED(cp->chan_widgets[W_main_window]), EDIT_HISTORY_CLOSED); } cp->selected = false; cw = cp->chan_widgets; if (cw) { if (cw[W_w]) { set_toggle_button(cw[W_w], true, false, (void *)cp); set_toggle_button(cw[W_f], false, false, (void *)cp); } gtk_widget_hide(channel_main_pane(cp)); } } } void change_channel_style(snd_info *sp, channel_style_t new_style) { if ((sp) && (sp->nchans > 1)) { channel_style_t old_style; chan_info *selected_cp; selected_cp = any_selected_channel(sp); /* chan 0 is none is selected */ old_style = sp->channel_style; sp->channel_style = new_style; if (new_style != old_style) { int i; int height[1]; if ((new_style == CHANNELS_SEPARATE) || (old_style == CHANNELS_SEPARATE)) remake_edit_history(sp->chans[0]); if (old_style == CHANNELS_COMBINED) { hide_gz_scrollbars(sp); for (i = 1; i < sp->nchans; i++) channel_set_mix_tags_erased(sp->chans[i]); } else { if (new_style == CHANNELS_COMBINED) { show_gz_scrollbars(sp); for (i = 1; i < sp->nchans; i++) channel_set_mix_tags_erased(sp->chans[i]); } } if (old_style == CHANNELS_SUPERIMPOSED) { syncb(sp, sp->previous_sync); /* set to blue? */ } else { if (new_style == CHANNELS_SUPERIMPOSED) { sp->previous_sync = sp->sync; if (sp->sync == 0) syncb(sp, 1); apply_y_axis_change(selected_cp); apply_x_axis_change(selected_cp); for (i = 0; i < sp->nchans; i++) { if (i != selected_cp->chan) { chan_info *ncp; ncp = sp->chans[i]; cursor_sample(ncp) = cursor_sample(selected_cp); if (selected_cp->graph_transform_on != ncp->graph_transform_on) { ncp->graph_transform_on = selected_cp->graph_transform_on; set_toggle_button(channel_f(ncp), selected_cp->graph_transform_on, false, (void *)ncp); } if (selected_cp->graph_time_on != ncp->graph_time_on) { ncp->graph_time_on = selected_cp->graph_time_on; set_toggle_button(channel_w(ncp), selected_cp->graph_time_on, false, (void *)ncp); } } } } } height[0] = widget_height(w_snd_pane(sp)) - control_panel_height(sp); if (old_style == CHANNELS_SEPARATE) { axis_info *ap; ap = selected_cp->axis; for (i = 0; i < sp->nchans; i++) { if (i != selected_cp->chan) set_axes(sp->chans[i], ap->x0, ap->x1, ap->y0, ap->y1); if (i > 0) { chan_info *ncp; ncp = sp->chans[i]; cleanup_cw(ncp); ncp->ax->w = channel_to_widget(ncp); ncp->ax->wn = WIDGET_TO_WINDOW(ncp->ax->w); } } channel_open_pane(sp->chans[0]); set_toggle_button(unite_button(sp), true, false, (void *)sp); } else { if (new_style == CHANNELS_SEPARATE) { /* height[0] = total space available */ height[0] /= sp->nchans; for_each_sound_chan(sp, channel_open_pane); /* for (i = 0; i < sp->nchans; i++) reset_mix_graph_parent(sp->chans[i]); */ for (i = 1; i < sp->nchans; i++) { GtkWidget **cw; chan_info *cp; cp = sp->chans[i]; cp->ax->w = channel_to_widget(cp); cp->ax->wn = WIDGET_TO_WINDOW(cp->ax->w); cw = cp->chan_widgets; gtk_widget_show_all(cw[W_main_window]); } set_toggle_button(unite_button(sp), false, false, (void *)sp); if (sp->selected_channel > 0) color_selected_channel(sp); } } if ((new_style == CHANNELS_COMBINED) && (sp->selected_channel > 0)) color_selected_channel(sp); } } } static Xen g_channel_widgets(Xen snd, Xen chn) { #define H_channel_widgets "(" S_channel_widgets " :optional snd chn): a list of widgets: ((0)graph (1)w (2)f (3)sx (4)sy (5)zx (6)zy\ (7)edhist (8)gsy (9)gzy (10)main (11)sx_adj (12)sy_adj (13)zx_adj (14)zy_adj (15)gsy_adj (16)gzy_adj)" #define Xen_wrap_adj(Value) ((Value) ? Xen_list_2(C_string_to_Xen_symbol("GtkAdjustment_"), Xen_wrap_C_pointer(Value)) : Xen_false) chan_info *cp; Snd_assert_channel(S_channel_widgets, snd, chn, 1); cp = get_cp(snd, chn, S_channel_widgets); if (!cp) return(Xen_false); return(Xen_cons(Xen_wrap_widget(channel_graph(cp)), Xen_cons(Xen_wrap_widget(channel_w(cp)), Xen_cons(Xen_wrap_widget(channel_f(cp)), Xen_cons(Xen_wrap_widget(channel_sx(cp)), Xen_cons(Xen_wrap_widget(channel_sy(cp)), Xen_cons(Xen_wrap_widget(channel_zx(cp)), Xen_cons(Xen_wrap_widget(channel_zy(cp)), Xen_cons((EDIT_HISTORY_LIST(cp)) ? Xen_wrap_widget(EDIT_HISTORY_LIST(cp)->topics) : Xen_false, Xen_cons(Xen_wrap_widget(channel_gsy(cp)), Xen_cons(Xen_wrap_widget(channel_gzy(cp)), Xen_cons(Xen_wrap_widget(channel_main_pane(cp)), Xen_cons(Xen_wrap_adj(sx_adj(cp)), Xen_cons(Xen_wrap_adj(sy_adj(cp)), Xen_cons(Xen_wrap_adj(zx_adj(cp)), Xen_cons(Xen_wrap_adj(zy_adj(cp)), Xen_cons(Xen_wrap_adj(gsy_adj(cp)), Xen_cons(Xen_wrap_adj(gzy_adj(cp)), Xen_empty_list)))))))))))))))))); } /* previous snd-gxen.c contents */ static gint timed_eval(gpointer in_code) { #if HAVE_EXTENSION_LANGUAGE /* #if needed on 64-bit machines */ Xen lst = (Xen)in_code; Xen_call_with_no_args(Xen_cadr(lst), "timed callback func"); snd_unprotect_at(Xen_integer_to_C_int(Xen_car(lst))); #endif return(0); } static Xen g_in(Xen ms, Xen code) { #define H_in "(" S_in " msecs thunk): invoke thunk in msecs milliseconds (named call_in in Ruby)" #if HAVE_EXTENSION_LANGUAGE Xen_check_type(Xen_is_number(ms), ms, 1, S_in, "a number"); Xen_check_type(Xen_is_procedure(code), code, 2, S_in, "a procedure"); if (Xen_is_aritable(code, 0)) { int secs; Xen_check_type(Xen_is_integer(ms), ms, 3, S_in, "an integer"); secs = Xen_integer_to_C_int(ms); if (secs < 0) Xen_out_of_range_error(S_in, 1, ms, "a positive integer"); else { Xen lst; lst = Xen_list_2(Xen_false, code); Xen_list_set(lst, 0, C_int_to_Xen_integer(snd_protect(lst))); g_timeout_add_full(0, (guint32)secs, timed_eval, (gpointer)lst, NULL); } } else Xen_bad_arity_error(S_in, 2, code, "should take no args"); #endif return(ms); } void color_unselected_graphs(color_t color) { int i; for (i = 0; i < ss->max_sounds; i++) { snd_info *sp; int j; sp = ss->sounds[i]; if ((sp) && (sp->inuse != SOUND_WRAPPER)) for (j = 0; j < sp->allocated_chans; j++) { chan_info *cp; cp = sp->chans[j]; update_graph(cp); } } } void color_chan_components(color_t color, slider_choice_t which_component) { #if (!GTK_CHECK_VERSION(3, 0, 0)) int i; for (i = 0; i < ss->max_sounds; i++) { int j; snd_info *sp; sp = ss->sounds[i]; if ((sp) && (sp->inuse != SOUND_WRAPPER)) for (j = 0; j < sp->allocated_chans; j++) { chan_info *cp; cp = sp->chans[j]; if (cp) { if (which_component == COLOR_POSITION) { /* in gtk3 this sets the slider color when dragged, and it looks bad * in gtk2 it sets the background (the trough, not the slider) */ widget_modify_bg(channel_sx(cp), GTK_STATE_ACTIVE, color); widget_modify_bg(channel_sy(cp), GTK_STATE_ACTIVE, color); } else { widget_modify_bg(channel_zx(cp), GTK_STATE_ACTIVE, color); widget_modify_bg(channel_zy(cp), GTK_STATE_ACTIVE, color); } } } } #endif } static Xen g_graph_cursor(void) { #define H_graph_cursor "(" S_graph_cursor "): current graph cursor shape" return(C_int_to_Xen_integer(in_graph_cursor(ss))); } static Xen g_set_graph_cursor(Xen curs) { int val; Xen_check_type(Xen_is_integer(curs), curs, 1, S_set S_graph_cursor, "an integer"); val = Xen_integer_to_C_int(curs); if ((val >= 0) && ((val & 1) == 0) && (val <= GDK_XTERM)) /* these are even numbers up to about 152 (gdkcursor.h) */ { ss->Graph_Cursor = val; ss->graph_cursor = GDK_CURSOR_NEW((GdkCursorType)in_graph_cursor(ss)); /* the gtk examples ignore g_object_ref|unref in this regard, so I will also */ } else Xen_out_of_range_error(S_set S_graph_cursor, 1, curs, "invalid cursor"); return(curs); } Xen_wrap_2_args(g_in_w, g_in) Xen_wrap_no_args(g_graph_cursor_w, g_graph_cursor) Xen_wrap_1_arg(g_set_graph_cursor_w, g_set_graph_cursor) Xen_wrap_2_optional_args(g_channel_widgets_w, g_channel_widgets) #if HAVE_SCHEME static s7_pointer acc_graph_cursor(s7_scheme *sc, s7_pointer args) {return(g_set_graph_cursor(s7_cadr(args)));} #endif void g_init_gxchn(void) { Xen_define_procedure(S_in, g_in_w, 2, 0, 0, H_in); Xen_define_dilambda(S_graph_cursor, g_graph_cursor_w, H_graph_cursor, S_set S_graph_cursor, g_set_graph_cursor_w, 0, 0, 1, 0); Xen_define_procedure(S_channel_widgets, g_channel_widgets_w, 0, 2, 0, H_channel_widgets); #if HAVE_SCHEME #define H_mouse_enter_graph_hook S_mouse_enter_graph_hook " (snd chn): called when the mouse \ enters the drawing area (graph pane) of the given channel.\n\ (hook-push " S_mouse_enter_graph_hook "\n\ (lambda (hook)\n\ (" S_focus_widget " (car (" S_channel_widgets " (hook 'snd) (hook 'chn))))))" #define H_mouse_leave_graph_hook S_mouse_leave_graph_hook " (snd chn): called when the mouse \ leaves the drawing area (graph pane) of the given channel." #endif #if HAVE_RUBY #define H_mouse_enter_graph_hook S_mouse_enter_graph_hook " (snd chn): called when the mouse \ enters the drawing area (graph pane) of the given channel.\n\ $mouse_enter_graph_hook.add-hook!(\"focus\") do |snd chn|\n\ focus_widget(channel_widgets(snd, chn)[0])\n\ end" #define H_mouse_leave_graph_hook S_mouse_leave_graph_hook " (snd chn): called when the mouse \ leaves the drawing area (graph pane) of the given channel." #endif #if HAVE_FORTH #define H_mouse_enter_graph_hook S_mouse_enter_graph_hook " (snd chn): called when the mouse \ enters the drawing area (graph pane) of the given channel.\n\ " S_mouse_enter_graph_hook " lambda: <{ snd chn }>\n\ snd chn " S_channel_widgets " car " S_focus_widget "\n\ ; add-hook!" #define H_mouse_leave_graph_hook S_mouse_leave_graph_hook " (snd chn): called when the mouse \ leaves the drawing area (graph pane) of the given channel." #endif mouse_enter_graph_hook = Xen_define_hook(S_mouse_enter_graph_hook, "(make-hook 'snd 'chn)", 2, H_mouse_enter_graph_hook); mouse_leave_graph_hook = Xen_define_hook(S_mouse_leave_graph_hook, "(make-hook 'snd 'chn)", 2, H_mouse_leave_graph_hook); #if HAVE_SCHEME s7_symbol_set_access(s7, ss->graph_cursor_symbol, s7_make_function(s7, "[acc-" S_graph_cursor "]", acc_graph_cursor, 2, 0, false, "accessor")); s7_symbol_set_documentation(s7, ss->graph_cursor_symbol, "*graph-cursor*: current graph cursor shape"); #endif } /* apparently in gtk 3.8.n the sliders are invisible until you try to move them. * I can't find any info about this, and can't find any way to fix it. * Nothing works. */ snd-16.1/snd-draw.c0000644000076400007640000023130612614436174012233 0ustar bilbil#include "snd.h" #if (!USE_NO_GUI) /* our "current path" */ static point_t points[POINT_BUFFER_SIZE]; static point_t points1[POINT_BUFFER_SIZE]; void set_grf_points(int xi, int j, int ymin, int ymax) { points[j].x = xi; points1[j].x = xi; points[j].y = ymax; points1[j].y = ymin; } void set_grf_point(int xi, int j, int yi) { points[j].x = xi; points[j].y = yi; } point_t *get_grf_points(void) {return(points);} point_t *get_grf_points1(void) {return(points1);} void draw_both_grf_points(int dot_size, graphics_context *ax, int j, graph_style_t graph_style) { int i; switch (graph_style) { case GRAPH_LINES: default: draw_lines(ax, points, j); draw_lines(ax, points1, j); break; case GRAPH_DOTS: draw_points(ax, points, j, dot_size); draw_points(ax, points1, j, dot_size); break; case GRAPH_FILLED: fill_two_sided_polygons(ax, points, points1, j); break; case GRAPH_DOTS_AND_LINES: if (dot_size > 1) { draw_points(ax, points, j, dot_size); draw_points(ax, points1, j, dot_size); } draw_lines(ax, points, j); draw_lines(ax, points1, j); break; case GRAPH_LOLLIPOPS: if (dot_size == 1) { for (i = 0; i < j; i++) draw_line(ax, points[i].x, points[i].y, points1[i].x, points1[i].y); } else { int size8, size4; size8 = dot_size / 8; size4 = dot_size / 4; if (size4 < 1) size4 = 1; draw_points(ax, points, j, dot_size); draw_points(ax, points1, j, dot_size); for (i = 0; i < j; i++) fill_rectangle(ax, points[i].x - size8, points[i].y, size4, points1[i].y - points[i].y); } break; } } void draw_grf_points(int dot_size, graphics_context *ax, int j, axis_info *ap, mus_float_t y0, graph_style_t graph_style) { int i, gy0; switch (graph_style) { case GRAPH_LINES: default: draw_lines(ax, points, j); break; case GRAPH_DOTS: draw_points(ax, points, j, dot_size); break; case GRAPH_FILLED: fill_polygons(ax, points, j, grf_y(y0, ap)); break; case GRAPH_DOTS_AND_LINES: if (dot_size > 1) draw_points(ax, points, j, dot_size); draw_lines(ax, points, j); break; case GRAPH_LOLLIPOPS: gy0 = grf_y(y0, ap); if (dot_size == 1) for (i = 0; i < j; i++) draw_line(ax, points[i].x, points[i].y, points[i].x, gy0); else { int size8, size4; size8 = dot_size / 8; size4 = dot_size / 4; if (size4 < 1) size4 = 1; draw_points(ax, points, j, dot_size); for (i = 0; i < j; i++) if (points[i].y > gy0) fill_rectangle(ax, points[i].x - size8, gy0, size4, points[i].y - gy0); else fill_rectangle(ax, points[i].x - size8, points[i].y, size4, gy0 - points[i].y); } break; } } void draw_cursor(chan_info *cp) { cursor_style_t cur; #if USE_GTK color_t old_color; #endif axis_info *ap; graphics_context *ax; if (!(cp->graph_time_on)) return; ap = cp->axis; #if USE_GTK ax = ap->ax; if (!ax) { fprintf(stderr,"axis->ax is null..."); ap->ax = cp->ax; ax = ap->ax; } old_color = get_foreground_color(ax); set_foreground_color(ax, ss->cursor_color); /* if (cp->cx > cp->cursor_size) cx0 = cp->cx - cp->cursor_size; */ /* if (cp->cy > cp->cursor_size) cy0 = cp->cy - cp->cursor_size; */ /* csize = 2 * cp->cursor_size + 1; */ /* what were those lines for? */ #else ax = cursor_context(cp); #endif if ((ss->tracking) && (cp->sound->playing)) cur = cp->tracking_cursor_style; else cur = cp->cursor_style; switch (cur) { case CURSOR_CROSS: draw_line(ax, cp->cx, cp->cy - cp->cursor_size, cp->cx, cp->cy + cp->cursor_size); draw_line(ax, cp->cx - cp->cursor_size, cp->cy, cp->cx + cp->cursor_size, cp->cy); break; case CURSOR_LINE: if ((with_inset_graph(ss)) && (cp->inset_graph)) draw_inset_line_cursor(cp, ax); else draw_line(ax, cp->cx, ap->y_axis_y0 - 1, cp->cx, ap->y_axis_y1); break; case CURSOR_PROC: #if USE_GTK free_cairo(ss->cr); ss->cr = NULL; #endif Xen_call_with_3_args((Xen_is_procedure(cp->cursor_proc)) ? (cp->cursor_proc) : (ss->cursor_proc), C_int_to_Xen_sound(cp->sound->index), C_int_to_Xen_integer(cp->chan), /* this was time-graph, which was useless. It's now #t if we're in tracking-cursor mode */ C_bool_to_Xen_boolean(ss->tracking), S_cursor_style " procedure"); #if USE_GTK ss->cr = make_cairo(ap->ax->wn); copy_context(cp); #endif break; } /* now draw the play triangle below the x axis */ fill_polygon(ax, 4, cp->cx, ap->y_axis_y0, cp->cx + play_arrow_size(ss), ap->y_axis_y0 + play_arrow_size(ss), cp->cx, ap->y_axis_y0 + 2 * play_arrow_size(ss), cp->cx, ap->y_axis_y0); #if USE_GTK set_foreground_color(ax, old_color); #endif } /* -------------------------------------------------------------------------------- */ #define AXIS_CONTEXT_ID_OK(Id) ((Id >= CHAN_GC) && (Id <= CHAN_TMPGC)) #define NO_SUCH_WIDGET Xen_make_error_type("no-such-widget") #if USE_MOTIF static graphics_context *get_ax(chan_info *cp, int ax_id, const char *caller, Xen ignored) { if ((cp) && (AXIS_CONTEXT_ID_OK(ax_id))) return(set_context(cp, (chan_gc_t)ax_id)); Xen_error(Xen_make_error_type("no-such-graphics-context"), Xen_list_6(C_string_to_Xen_string("~A: no such graphics context: ~A, sound index: ~A (~A), chan: ~A"), C_string_to_Xen_string(caller), C_int_to_Xen_integer(ax_id), C_int_to_Xen_sound(cp->sound->index), C_string_to_Xen_string(cp->sound->short_filename), C_int_to_Xen_integer(cp->chan))); return(NULL); } static graphics_context *get_ax_no_cr(chan_info *cp, int ax_id, const char *caller) { return(get_ax(cp,ax_id, caller, Xen_false)); } #endif #if USE_GTK static graphics_context *get_ax(chan_info *cp, int ax_id, const char *caller, Xen xcr) { if ((cp) && (AXIS_CONTEXT_ID_OK(ax_id))) { graphics_context *ax; ax = set_context(cp, (chan_gc_t)ax_id); /* (gdk_cairo_create (GDK_DRAWABLE (gtk_widget_get_window (car (channel-widgets 0 0)))))) -> '(cairo_t_ #) * (eq? (car hi) 'cairo_t_) -> #t */ if ((Xen_is_list(xcr)) && (Xen_list_length(xcr) == 2) && (Xen_is_symbol(Xen_car(xcr))) && (strcmp("cairo_t_", Xen_symbol_to_C_string(Xen_car(xcr))) == 0)) ss->cr = (cairo_t *)Xen_unwrap_C_pointer(Xen_cadr(xcr)); else Xen_error(Xen_make_error_type("not-a-graphics-context"), Xen_list_2(C_string_to_Xen_string("~A: cairo_t argument is not a cairo_t pointer"), C_string_to_Xen_string(caller))); return(ax); } Xen_error(Xen_make_error_type("no-such-graphics-context"), Xen_list_6(C_string_to_Xen_string("~A: no such graphics context: ~A, sound index: ~A (~A), chan: ~A"), C_string_to_Xen_string(caller), C_int_to_Xen_integer(ax_id), C_int_to_Xen_sound(cp->sound->index), C_string_to_Xen_string(cp->sound->short_filename), C_int_to_Xen_integer(cp->chan))); return(NULL); } static graphics_context *get_ax_no_cr(chan_info *cp, int ax_id, const char *caller) { if ((cp) && (AXIS_CONTEXT_ID_OK(ax_id))) { graphics_context *ax; ax = set_context(cp, (chan_gc_t)ax_id); return(ax); } Xen_error(Xen_make_error_type("no-such-graphics-context"), Xen_list_6(C_string_to_Xen_string("~A: no such graphics context: ~A, sound index: ~A (~A), chan: ~A"), C_string_to_Xen_string(caller), C_int_to_Xen_integer(ax_id), C_int_to_Xen_sound(cp->sound->index), C_string_to_Xen_string(cp->sound->short_filename), C_int_to_Xen_integer(cp->chan))); return(NULL); } #endif #define TO_C_AXIS_CONTEXT(Snd, Chn, Ax, Caller, Cr) get_ax(get_cp(Snd, Chn, Caller), (Xen_is_integer(Ax)) ? Xen_integer_to_C_int(Ax) : (int)CHAN_GC, Caller, Cr) #define TO_C_AXIS_CONTEXT_NO_CR(Snd, Chn, Ax, Caller) get_ax_no_cr(get_cp(Snd, Chn, Caller), (Xen_is_integer(Ax)) ? Xen_integer_to_C_int(Ax) : (int)CHAN_GC, Caller) static Xen g_draw_line(Xen x0, Xen y0, Xen x1, Xen y1, Xen snd, Xen chn, Xen ax, Xen xcr) { #define H_draw_line "(" S_draw_line " x0 y0 x1 y1 :optional snd chn (ax " S_time_graph ") cr): draw a line" Snd_assert_channel(S_draw_line, snd, chn, 5); Xen_check_type(Xen_is_integer(x0), x0, 1, S_draw_line, "an integer"); Xen_check_type(Xen_is_integer(y0), y0, 2, S_draw_line, "an integer"); Xen_check_type(Xen_is_integer(x1), x1, 3, S_draw_line, "an integer"); Xen_check_type(Xen_is_integer(y1), y1, 4, S_draw_line, "an integer"); Xen_check_type(Xen_is_integer_or_unbound(ax), ax, 7, S_draw_line, "an integer such as " S_time_graph); draw_line(TO_C_AXIS_CONTEXT(snd, chn, ax, S_draw_line, xcr), Xen_integer_to_C_int(x0), Xen_integer_to_C_int(y0), Xen_integer_to_C_int(x1), Xen_integer_to_C_int(y1)); return(Xen_false); } static Xen g_draw_dot(Xen x0, Xen y0, Xen size, Xen snd, Xen chn, Xen ax, Xen xcr) { #define H_draw_dot "(" S_draw_dot " x0 y0 size :optional snd chn (ax " S_time_graph ") cr): draw a dot" Snd_assert_channel(S_draw_dot, snd, chn, 4); Xen_check_type(Xen_is_integer(x0), x0, 1, S_draw_dot, "an integer"); Xen_check_type(Xen_is_integer(y0), y0, 2, S_draw_dot, "an integer"); Xen_check_type(Xen_is_integer(size), size, 3, S_draw_dot, "an integer"); Xen_check_type(Xen_is_integer_or_unbound(ax), ax, 6, S_draw_dot, "an integer such as " S_time_graph); draw_dot(TO_C_AXIS_CONTEXT(snd, chn, ax, S_draw_dot, xcr), Xen_integer_to_C_int(x0), Xen_integer_to_C_int(y0), Xen_integer_to_C_int(size)); return(Xen_false); } static Xen g_fill_rectangle(Xen x0, Xen y0, Xen width, Xen height, Xen snd, Xen chn, Xen ax, Xen erase, Xen xcr) { #define H_fill_rectangle "(" S_fill_rectangle " x0 y0 width height :optional snd chn (ax " S_time_graph ") erase cr): draw a filled rectangle" Snd_assert_channel(S_fill_rectangle, snd, chn, 5); Xen_check_type(Xen_is_integer(x0), x0, 1, S_fill_rectangle, "an integer"); Xen_check_type(Xen_is_integer(y0), y0, 2, S_fill_rectangle, "an integer"); Xen_check_type(Xen_is_integer(width), width, 3, S_fill_rectangle, "an integer"); Xen_check_type(Xen_is_integer(height), height, 4, S_fill_rectangle, "an integer"); Xen_check_type(Xen_is_integer_or_unbound(ax), ax, 7, S_fill_rectangle, "an integer such as " S_time_graph); Xen_check_type(Xen_is_boolean_or_unbound(erase), erase, 8, S_fill_rectangle, "a boolean"); if ((Xen_is_boolean(erase)) && (Xen_is_true(erase))) erase_rectangle(get_cp(snd, chn, S_fill_rectangle), TO_C_AXIS_CONTEXT(snd, chn, ax, S_fill_rectangle, xcr), Xen_integer_to_C_int(x0), Xen_integer_to_C_int(y0), Xen_integer_to_C_int(width), Xen_integer_to_C_int(height)); else fill_rectangle(TO_C_AXIS_CONTEXT(snd, chn, ax, S_fill_rectangle, xcr), Xen_integer_to_C_int(x0), Xen_integer_to_C_int(y0), Xen_integer_to_C_int(width), Xen_integer_to_C_int(height)); return(Xen_false); } static Xen g_draw_string(Xen text, Xen x0, Xen y0, Xen snd, Xen chn, Xen ax, Xen xcr) { #define H_draw_string "(" S_draw_string " text x0 y0 :optional snd chn (ax " S_time_graph ") cr): draw a string" const char *tmp = NULL; Snd_assert_channel(S_draw_string, snd, chn, 4); Xen_check_type(Xen_is_string(text), text, 1, S_draw_string, "a string"); Xen_check_type(Xen_is_integer(x0), x0, 2, S_draw_string, "an integer"); Xen_check_type(Xen_is_integer(y0), y0, 3, S_draw_string, "an integer"); Xen_check_type(Xen_is_integer_or_unbound(ax), ax, 6, S_draw_string, "an integer such as " S_time_graph); tmp = Xen_string_to_C_string(text); #if USE_MOTIF /* snd-xdraw to make motif draw-string act in the same way (coordinate-wise) as gtk */ /* despite the name, this is not a gtk function */ gtk_style_draw_string(TO_C_AXIS_CONTEXT(snd, chn, ax, S_draw_string, xcr), #else draw_string(TO_C_AXIS_CONTEXT(snd, chn, ax, S_draw_string, xcr), #endif Xen_integer_to_C_int(x0), Xen_integer_to_C_int(y0), tmp, mus_strlen(tmp)); return(text); } static point_t *vector_to_points(Xen pts, const char *caller, int *vector_len) { int i, j, vlen = 0, len = 0; point_t *pack_pts; vlen = Xen_vector_length(pts); if (vlen & 1) Xen_error(Xen_make_error_type("bad-length"), Xen_list_3(C_string_to_Xen_string("~A: length of vector of points (~A) must be even"), C_string_to_Xen_string(caller), C_int_to_Xen_integer(vlen))); if (vlen <= 0) Xen_error(NO_DATA, Xen_list_3(C_string_to_Xen_string("~A: empty points vector? ~A"), C_string_to_Xen_string(caller), pts)); len = vlen / 2; (*vector_len) = len; pack_pts = (point_t *)calloc(len, sizeof(point_t)); for (i = 0, j = 0; i < len; i++, j += 2) { pack_pts[i].x = Xen_integer_to_C_int(Xen_vector_ref(pts, j)); pack_pts[i].y = Xen_integer_to_C_int(Xen_vector_ref(pts, j + 1)); } return(pack_pts); } static Xen g_draw_lines(Xen pts, Xen snd, Xen chn, Xen ax, Xen xcr) { /* pts should be a vector of integers as (x y) pairs */ #define H_draw_lines "(" S_draw_lines " lines :optional snd chn (ax " S_time_graph ") cr): draw a vector of lines" point_t *pack_pts; graphics_context *ax1; int vlen = 0; Snd_assert_channel(S_draw_lines, snd, chn, 2); Xen_check_type(Xen_is_vector(pts), pts, 1, S_draw_lines, "a vector"); Xen_check_type(Xen_is_integer_or_unbound(ax), ax, 4, S_draw_lines, "an integer such as " S_time_graph); ax1 = TO_C_AXIS_CONTEXT(snd, chn, ax, S_draw_lines, xcr); pack_pts = vector_to_points(pts, S_draw_lines, &vlen); draw_lines(ax1, pack_pts, vlen); free(pack_pts); return(pts); } static Xen g_draw_dots(Xen pts, Xen size, Xen snd, Xen chn, Xen ax, Xen xcr) { /* pts should be a vector of integers as (x y) pairs */ #define H_draw_dots "(" S_draw_dots " positions :optional dot-size snd chn (ax " S_time_graph ") cr): draw a vector of dots" point_t *pack_pts; graphics_context *ax1; int vlen = 0; Snd_assert_channel(S_draw_dots, snd, chn, 3); Xen_check_type(Xen_is_vector(pts), pts, 1, S_draw_dots, "a vector"); Xen_check_type(Xen_is_integer_or_unbound(size), size, 2, S_draw_dots, "an integer"); Xen_check_type(Xen_is_integer_or_unbound(ax), ax, 5, S_draw_dots, "an integer such as " S_time_graph); ax1 = TO_C_AXIS_CONTEXT(snd, chn, ax, S_draw_dots, xcr); pack_pts = vector_to_points(pts, S_draw_dots, &vlen); draw_points(ax1, pack_pts, vlen, (Xen_is_integer(size)) ? Xen_integer_to_C_int(size) : 1); free(pack_pts); return(pts); } static Xen g_fill_polygon(Xen pts, Xen snd, Xen chn, Xen ax_id, Xen xcr) { #define H_fill_polygon "(" S_fill_polygon " points :optional snd chn (ax " S_time_graph ") cr): draw a filled polygon" point_t *pack_pts; graphics_context *ax; int vlen = 0; Snd_assert_channel(S_fill_polygon, snd, chn, 2); Xen_check_type(Xen_is_vector(pts), pts, 1, S_fill_polygon, "a vector"); Xen_check_type(Xen_is_integer_or_unbound(ax_id), ax_id, 4, S_fill_polygon, "an integer such as " S_time_graph); ax = TO_C_AXIS_CONTEXT(snd, chn, ax_id, S_fill_polygon, xcr); pack_pts = vector_to_points(pts, S_fill_polygon, &vlen); #if USE_MOTIF XFillPolygon(ax->dp, ax->wn, ax->gc, pack_pts, vlen, Complex, CoordModeOrigin); #else fill_polygon_from_array(ax, pack_pts, vlen); #endif free(pack_pts); return(pts); } static Xen g_make_bezier(Xen args1) { /* used in musglyphs.rb -- not currently used anywhere else */ #define S_make_bezier "make-bezier" #define H_make_bezier "(" S_make_bezier " x0 y0 x1 y1 x2 y2 x3 y3 n): return a vector of points corresponding to the bezier curve \ defined by the 4 controlling points x0..y3; 'n' is how many points to return" /* XDrawBezier from cmn's glfed.c (where it was assuming PostScript coordinates) */ int ax, ay, bx, by, cx, cy, i; float incr, val; int x[4]; int y[4]; int n = 50; Xen pts, args; args = Xen_copy_arg(args1); for (i = 0; i < 4; i++) { x[i] = Xen_integer_to_C_int(Xen_car(args)); y[i] = Xen_integer_to_C_int(Xen_cadr(args)); args = Xen_cddr(args); } if (!Xen_is_null(args)) n = Xen_integer_to_C_int(Xen_car(args)); cx = 3 * (x[1] - x[0]); cy = 3 * (y[1] - y[0]); bx = 3 * (x[2] - x[1]) - cx; by = 3 * (y[2] - y[1]) - cy; ax = x[3] - (x[0] + cx + bx); ay = y[3] - (y[0] + cy + by); incr = 1.0 / (float)n; pts = Xen_make_vector(2 * (n + 1), Xen_integer_zero); Xen_vector_set(pts, 0, C_int_to_Xen_integer(x[0])); Xen_vector_set(pts, 1, C_int_to_Xen_integer(y[0])); for (i = 1, val = incr; i <= n; i++, val += incr) { Xen_vector_set(pts, i * 2, C_int_to_Xen_integer((int)(x[0] + val * (cx + (val * (bx + (val * ax))))))); Xen_vector_set(pts, i * 2 + 1, C_int_to_Xen_integer((int)(y[0] + val * (cy + (val * (by + (val * ay))))))); } return(pts); } static Xen g_foreground_color(Xen snd, Xen chn, Xen xax) { #define H_foreground_color "(" S_foreground_color " :optional snd chn (ax " S_time_graph ")): current drawing color" chan_info *cp; graphics_context *ax; Snd_assert_channel(S_foreground_color, snd, chn, 1); Xen_check_type(Xen_is_integer_or_unbound(xax), xax, 3, S_foreground_color, "an integer"); cp = get_cp(snd, chn, S_foreground_color); if (!cp) return(Xen_false); ax = get_ax_no_cr(cp, (Xen_is_integer(xax)) ? Xen_integer_to_C_int(xax) : (int)CHAN_GC, S_foreground_color); return(Xen_wrap_pixel(get_foreground_color(ax))); } static Xen g_set_foreground_color(Xen color, Xen snd, Xen chn, Xen ax) { chan_info *cp; Snd_assert_channel(S_set S_foreground_color, snd, chn, 2); Xen_check_type(Xen_is_pixel(color), color, 1, S_set S_foreground_color, "a color"); Xen_check_type(Xen_is_integer_or_unbound(ax), ax, 4, S_set S_foreground_color, "an integer"); cp = get_cp(snd, chn, S_set S_foreground_color); if (!cp) return(Xen_false); set_foreground_color(get_ax_no_cr(cp, (Xen_is_integer(ax)) ? Xen_integer_to_C_int(ax) : (int)CHAN_GC, S_set S_foreground_color), Xen_unwrap_pixel(color)); return(color); } with_four_setter_args(g_set_foreground_color_reversed, g_set_foreground_color) #if USE_MOTIF static Xen g_set_current_font(Xen id, Xen snd, Xen chn, Xen ax_id) { graphics_context *ax; Snd_assert_channel(S_set S_current_font, snd, chn, 2); Xen_check_type(Xen_is_integer_or_unbound(ax_id), ax_id, 4, S_set S_current_font, "an integer such as time-graph"); Xen_check_type((Xen_is_list(id)) && (Xen_list_length(id) >= 2) && (Xen_is_symbol(Xen_car(id))) && (strcmp("Font", Xen_symbol_to_C_string(Xen_car(id))) == 0), id, 1, S_set S_current_font, "a Font"); ax = TO_C_AXIS_CONTEXT_NO_CR(snd, chn, ax_id, S_current_font); ax->current_font = (Font)Xen_ulong_to_C_ulong(Xen_cadr(id)); XSetFont(ax->dp, ax->gc, ax->current_font); return(id); } static Xen g_current_font(Xen snd, Xen chn, Xen ax_id) { #define H_current_font "(" S_current_font " :optional snd chn (ax " S_time_graph ")): current font id" graphics_context *ax; chan_info *cp; Snd_assert_channel(S_current_font, snd, chn, 1); Xen_check_type(Xen_is_integer_or_unbound(ax_id), ax_id, 3, S_current_font, "an integer such as time-graph"); cp = get_cp(snd, chn, S_current_font); if (!cp) return(Xen_false); ax = get_ax_no_cr(cp, (Xen_is_integer(ax_id)) ? Xen_integer_to_C_int(ax_id) : (int)CHAN_GC, S_current_font); if (ax->current_font == 0) { if ((cp->axis) && (cp->axis->ax)) return(Xen_list_2(C_string_to_Xen_symbol("Font"), C_ulong_to_Xen_ulong(cp->axis->ax->current_font))); else return(Xen_false); } return(Xen_list_2(C_string_to_Xen_symbol("Font"), C_ulong_to_Xen_ulong(ax->current_font))); } #else static Xen g_set_current_font(Xen id, Xen snd, Xen chn, Xen ax_id) { graphics_context *ax; Snd_assert_channel(S_set S_current_font, snd, chn, 2); Xen_check_type(Xen_is_integer_or_unbound(ax_id), ax_id, 4, S_set S_current_font, "an integer such as time-graph"); ax = TO_C_AXIS_CONTEXT_NO_CR(snd, chn, ax_id, S_set S_current_font); Xen_check_type((Xen_is_wrapped_c_pointer(id)) || (Xen_is_list(id) && (Xen_list_length(id) >= 2) && (Xen_is_symbol(Xen_car(id)))), id, 1, S_set S_current_font, "a wrapped object or a raw pointer"); if (Xen_is_wrapped_c_pointer(id)) ax->current_font = (PangoFontDescription *)Xen_unwrap_C_pointer(id); else ax->current_font = (PangoFontDescription *)Xen_unwrap_C_pointer(Xen_cadr(id)); return(id); } static Xen g_current_font(Xen snd, Xen chn, Xen ax_id) { #define H_current_font "(" S_current_font " :optional snd chn (ax " S_time_graph ")): current font id" graphics_context *ax; Snd_assert_channel(S_current_font, snd, chn, 1); Xen_check_type(Xen_is_integer_or_unbound(ax_id), ax_id, 3, S_current_font, "an integer such as time-graph"); ax = TO_C_AXIS_CONTEXT_NO_CR(snd, chn, ax_id, S_current_font); return(Xen_wrap_C_pointer(ax->current_font)); } #endif with_four_setter_args(g_set_current_font_reversed, g_set_current_font) static Xen g_make_graph_data(Xen snd, Xen chn, Xen edpos, Xen lo, Xen hi) { #define H_make_graph_data "(" S_make_graph_data " :optional snd chn edpos low high): \ return either a " S_vct " (if the graph has one trace), or a list of two " S_vct "s (the two sides of the envelope graph). \ 'edpos' defaults to the " S_current_edit_position ", 'low' defaults to the current window left sample, and \ 'high' defaults to the current rightmost sample. (" S_graph_data " (" S_make_graph_data ")) reimplements the time domain graph." chan_info *cp; Snd_assert_channel(S_make_graph_data, snd, chn, 1); cp = get_cp(snd, chn, S_make_graph_data); if (!cp) return(Xen_false); Xen_check_type(Xen_is_integer_or_unbound(lo), lo, 4, S_make_graph_data, "an integer"); Xen_check_type(Xen_is_integer_or_unbound(hi), hi, 5, S_make_graph_data, "an integer"); return(make_graph_data(cp, to_c_edit_position(cp, edpos, S_make_graph_data, 3), (Xen_is_llong(lo)) ? Xen_llong_to_C_llong(lo) : -1, (Xen_is_llong(hi)) ? Xen_llong_to_C_llong(hi) : -1)); } static Xen g_graph_data(Xen data, Xen snd, Xen chn, Xen ax, Xen lo, Xen hi, Xen style, Xen xcr) { #define H_graph_data "(" S_graph_data " data :optional snd chn (context " S_copy_context ") low high graph-style cr): \ display 'data' in the time domain graph of snd's channel chn using the graphics context context (normally " S_copy_context "), placing the \ data in the recipient's graph between points low and high in the drawing mode graphic-style." chan_info *cp; vct *v0, *v1 = NULL; Snd_assert_channel(S_graph_data, snd, chn, 2); cp = get_cp(snd, chn, S_graph_data); if (!cp) return(Xen_false); if (Xen_is_false(data)) return(Xen_false); Xen_check_type((Xen_is_list(data) && (Xen_list_length(data) == 2) && (mus_is_vct(Xen_car(data))) && (mus_is_vct(Xen_cadr(data)))) || (mus_is_vct(data)), data, 1, S_graph_data, "a list of 2 " S_vct "s or a " S_vct); Xen_check_type(Xen_is_integer_boolean_or_unbound(ax), ax, 4, S_graph_data, "an integer"); Xen_check_type(Xen_is_llong(lo) || Xen_is_false(lo) || !Xen_is_bound(lo), lo, 5, S_graph_data, "a sample number"); Xen_check_type(Xen_is_llong(hi) || Xen_is_false(hi) || !Xen_is_bound(hi), hi, 6, S_graph_data, "a sample number"); Xen_check_type(Xen_is_integer_boolean_or_unbound(style), style, 7, S_graph_data, "an integer"); if (Xen_is_list(data)) { v0 = xen_to_vct(Xen_car(data)); v1 = xen_to_vct(Xen_cadr(data)); } else v0 = xen_to_vct(data); draw_graph_data(cp, (Xen_is_llong(lo)) ? Xen_llong_to_C_llong(lo) : -1, (Xen_is_llong(hi)) ? Xen_llong_to_C_llong(hi) : -1, mus_vct_length(v0), mus_vct_data(v0), (v1) ? (mus_vct_data(v1)) : NULL, get_ax(cp, (Xen_is_integer(ax)) ? Xen_integer_to_C_int(ax) : (int)CHAN_GC, S_graph_data, xcr), (Xen_is_integer(style)) ? (graph_style_t)Xen_integer_to_C_int(style) : cp->time_graph_style); return(data); } static Xen g_main_widgets(void) { #define H_main_widgets "(" S_main_widgets "): top level \ widgets (list (0)main-app (1)main-shell (2)main-pane (3)sound-pane (4)listener-pane (5)notebook-outer-pane)" Xen bad_temp, res; /* needed by old gcc -- gets confused by straight arg list */ int loc; #if USE_MOTIF bad_temp = Xen_list_2(C_string_to_Xen_symbol("XtAppContext"), C_ulong_to_Xen_ulong((unsigned long)MAIN_APP(ss))); #else bad_temp = Xen_wrap_window(MAIN_WINDOW(ss)); #endif loc = snd_protect(bad_temp); res = Xen_cons(bad_temp, Xen_cons(Xen_wrap_widget(MAIN_SHELL(ss)), Xen_cons(Xen_wrap_widget(MAIN_PANE(ss)), Xen_cons(Xen_wrap_widget(SOUND_PANE(ss)), Xen_cons(Xen_wrap_widget(ss->listener_pane), Xen_cons(Xen_wrap_widget(SOUND_PANE_BOX(ss)), Xen_empty_list)))))); snd_unprotect_at(loc); return(res); } static Xen dialog_widgets; static Xen new_widget_hook; /* ideally this would be an "after method" on XtCreateWidget or gtk_new_* */ void run_new_widget_hook(widget_t w) { if (Xen_hook_has_list(new_widget_hook)) run_hook(new_widget_hook, Xen_list_1(Xen_wrap_widget(w)), S_new_widget_hook); } static void check_dialog_widget_table(void) { if (!(Xen_is_vector(dialog_widgets))) { dialog_widgets = Xen_make_vector(NUM_DIALOGS, Xen_false); Xen_GC_protect(dialog_widgets); } } static Xen g_dialog_widgets(void) { #define H_dialog_widgets "(" S_dialog_widgets "): dialog widgets (each " PROC_FALSE " if not yet created): (list \ (0 " S_color_orientation_dialog ") (1 " S_enved_dialog ") (2 " S_transform_dialog ") \ (3 " S_open_file_dialog ") (4 " S_save_sound_dialog ") (5 " S_view_files_dialog ") (6 raw data dialog) (7 new file dialog) \ (8 " S_mix_file_dialog ") (9 " S_edit_header_dialog ") (10 " S_find_dialog ") (11 " S_help_dialog ") \ (12 " S_view_mixes_dialog ") (13 " S_print_dialog ") (14 " S_view_regions_dialog ") \ (15 " S_info_dialog ") (16 extra controls dialog) (17 " S_save_selection_dialog ") (18 " S_insert_file_dialog ") \ (19 " S_save_region_dialog ") (20 " S_preferences_dialog "))" check_dialog_widget_table(); return(Xen_vector_to_Xen_list(dialog_widgets)); } void set_dialog_widget(snd_dialog_t which, widget_t wid) { if (ss->dialogs == NULL) { ss->dialogs_size = 8; ss->num_dialogs = 0; ss->dialogs = (widget_t *)calloc(ss->dialogs_size, sizeof(widget_t)); } else { if (ss->num_dialogs == ss->dialogs_size) { int i; ss->dialogs_size += 8; ss->dialogs = (widget_t *)realloc(ss->dialogs, ss->dialogs_size * sizeof(widget_t)); for (i = ss->num_dialogs; i < ss->dialogs_size; i++) ss->dialogs[i] = NULL; } } ss->dialogs[ss->num_dialogs++] = wid; check_dialog_widget_table(); if (Xen_is_false(Xen_vector_ref(dialog_widgets, (int)which))) Xen_vector_set(dialog_widgets, (int)which, Xen_wrap_widget(wid)); else { if (Xen_is_widget(Xen_vector_ref(dialog_widgets, (int)which))) Xen_vector_set(dialog_widgets, (int)which, Xen_list_2(Xen_wrap_widget(wid), Xen_vector_ref(dialog_widgets, (int)which))); else Xen_vector_set(dialog_widgets, (int)which, Xen_cons(Xen_wrap_widget(wid), Xen_vector_ref(dialog_widgets, (int)which))); } run_new_widget_hook(wid); } static Xen g_widget_position(Xen wid) { #define H_widget_position "(" S_widget_position " wid): widget's position, (list x y), in pixels" widget_t w; Xen_check_type(Xen_is_widget(wid), wid, 1, S_widget_position, "a Widget"); w = (widget_t)(Xen_unwrap_widget(wid)); if (!w) Xen_error(NO_SUCH_WIDGET, Xen_list_2(C_string_to_Xen_string(S_widget_position ": no such widget: ~A"), wid)); return(Xen_list_2(C_int_to_Xen_integer(widget_x(w)), C_int_to_Xen_integer(widget_y(w)))); } static Xen g_set_widget_position(Xen wid, Xen xy) { widget_t w; Xen_check_type(Xen_is_widget(wid), wid, 1, S_set S_widget_position, "a Widget"); Xen_check_type(Xen_is_list(xy) && (Xen_list_length(xy) == 2), xy, 2, S_set S_widget_position, "a list: (x y)"); w = (widget_t)(Xen_unwrap_widget(wid)); if (w) { Xen_check_type(Xen_is_integer(Xen_car(xy)), Xen_car(xy), 0, S_set S_widget_position, "an integer"); Xen_check_type(Xen_is_integer(Xen_cadr(xy)), Xen_cadr(xy), 0, S_set S_widget_position, "an integer"); set_widget_position(w, mus_iclamp(0, Xen_integer_to_C_int(Xen_car(xy)), LOTSA_PIXELS), mus_iclamp(0, Xen_integer_to_C_int(Xen_cadr(xy)), LOTSA_PIXELS)); } else Xen_error(NO_SUCH_WIDGET, Xen_list_2(C_string_to_Xen_string(S_set S_widget_position ": no such widget: ~A"), wid)); return(wid); } static Xen g_widget_size(Xen wid) { #define H_widget_size "(" S_widget_size " wid): widget's size, (list width height), in pixels" widget_t w; Xen_check_type(Xen_is_widget(wid), wid, 1, S_widget_size, "a Widget"); w = (widget_t)(Xen_unwrap_widget(wid)); if (!w) Xen_error(NO_SUCH_WIDGET, Xen_list_2(C_string_to_Xen_string(S_widget_size ": no such widget: ~A"), wid)); return(Xen_list_2(C_int_to_Xen_integer(widget_width(w)), C_int_to_Xen_integer(widget_height(w)))); } static Xen g_set_widget_size(Xen wid, Xen wh) { widget_t w; Xen_check_type(Xen_is_widget(wid), wid, 1, S_set S_widget_size, "a Widget"); Xen_check_type(Xen_is_list(wh) && (Xen_list_length(wh) == 2), wh, 2, S_set S_widget_size, "a list: (width height)"); w = (widget_t)(Xen_unwrap_widget(wid)); if (w) { Xen_check_type(Xen_is_integer(Xen_car(wh)), Xen_car(wh), 0, S_set S_widget_size, "an integer"); Xen_check_type(Xen_is_integer(Xen_cadr(wh)), Xen_cadr(wh), 0, S_set S_widget_size, "an integer"); set_widget_size(w, mus_iclamp(1, Xen_integer_to_C_int(Xen_car(wh)), LOTSA_PIXELS), mus_iclamp(1, Xen_integer_to_C_int(Xen_cadr(wh)), LOTSA_PIXELS)); } else Xen_error(NO_SUCH_WIDGET, Xen_list_2(C_string_to_Xen_string(S_set S_widget_size ": no such widget: ~A"), wid)); return(wid); } static Xen g_widget_text(Xen wid) { #define H_widget_text "(" S_widget_text " wid): widget's text or label" widget_t w; Xen res = Xen_false; Xen_check_type(Xen_is_widget(wid), wid, 1, S_widget_text, "a Widget"); w = (widget_t)(Xen_unwrap_widget(wid)); if (w) { #if USE_MOTIF char *text = NULL; if ((XmIsText(w)) || (XmIsTextField(w))) { text = XmTextGetString(w); res = C_string_to_Xen_string(text); } else { XmString s1 = NULL; XtVaGetValues(w, XmNlabelString, &s1, NULL); if (XmStringEmpty(s1)) return(Xen_false); text = (char *)XmStringUnparse(s1, NULL, XmCHARSET_TEXT, XmCHARSET_TEXT, NULL, 0, XmOUTPUT_ALL); XmStringFree(s1); res = C_string_to_Xen_string(text); } if (text) XtFree(text); return(res); #else if (GTK_IS_ENTRY(w)) return(C_string_to_Xen_string((char *)gtk_entry_get_text(GTK_ENTRY(w)))); else { if ((GTK_IS_BIN(w)) && (GTK_IS_LABEL(BIN_CHILD(w)))) return(C_string_to_Xen_string((char *)gtk_label_get_text(GTK_LABEL(BIN_CHILD(w))))); else { if (GTK_IS_LABEL(w)) return(C_string_to_Xen_string((char *)gtk_label_get_text(GTK_LABEL(w)))); else { if (GTK_IS_TEXT_VIEW(w)) { Xen val = Xen_false; char *text; text = sg_get_text(w, 0, -1); if (text) { val = C_string_to_Xen_string(text); /* this copies, so it should be safe to free the original */ g_free(text); } return(val); } } } } #endif } else Xen_error(NO_SUCH_WIDGET, Xen_list_2(C_string_to_Xen_string(S_widget_text ": no such widget: ~A"), wid)); return(res); } static Xen g_set_widget_text(Xen wid, Xen text) { widget_t w; Xen_check_type(Xen_is_widget(wid), wid, 1, S_set S_widget_text, "a Widget"); Xen_check_type(Xen_is_string(text) || Xen_is_false(text), text, 2, S_set S_widget_text, "a string"); w = (widget_t)(Xen_unwrap_widget(wid)); if (w) { const char *str = NULL; if (Xen_is_string(text)) str = Xen_string_to_C_string(text); #if USE_MOTIF if ((XmIsText(w)) || (XmIsTextField(w))) XmTextSetString(w, (char *)str); else set_button_label(w, str); #else if (GTK_IS_ENTRY(w)) gtk_entry_set_text(GTK_ENTRY(w), str); else set_button_label(w, str); #endif } else Xen_error(NO_SUCH_WIDGET, Xen_list_2(C_string_to_Xen_string(S_set S_widget_text ": no such widget: ~A"), wid)); return(text); } static Xen g_hide_widget(Xen wid) { #define H_hide_widget "(" S_hide_widget " widget): hide or undisplay widget" widget_t w; Xen_check_type(Xen_is_widget(wid), wid, 1, S_hide_widget, "a Widget"); w = (widget_t)(Xen_unwrap_widget(wid)); if (w) { #if USE_MOTIF XtUnmanageChild(w); #else gtk_widget_hide(w); #endif } else Xen_error(NO_SUCH_WIDGET, Xen_list_2(C_string_to_Xen_string(S_hide_widget ": no such widget: ~A"), wid)); return(wid); } static Xen g_show_widget(Xen wid) { #define H_show_widget "(" S_show_widget " widget): show or display widget" widget_t w; Xen_check_type(Xen_is_widget(wid), wid, 1, S_show_widget, "a Widget"); w = (widget_t)(Xen_unwrap_widget(wid)); if (w) { #if USE_MOTIF XtManageChild(w); #else gtk_widget_show(w); #endif } else Xen_error(NO_SUCH_WIDGET, Xen_list_2(C_string_to_Xen_string(S_show_widget ": no such widget: ~A"), wid)); return(wid); } static Xen g_focus_widget(Xen wid) { #define H_focus_widget "(" S_focus_widget " widget): cause widget to receive input focus" widget_t w; Xen_check_type(Xen_is_widget(wid), wid, 1, S_focus_widget, "a Widget"); w = (widget_t)(Xen_unwrap_widget(wid)); if (w) goto_window(w); else Xen_error(NO_SUCH_WIDGET, Xen_list_2(C_string_to_Xen_string(S_focus_widget ": no such widget: ~A"), wid)); return(wid); } static Xen g_snd_gcs(void) { #define H_snd_gcs "(" S_snd_gcs "): a list of Snd graphics contexts (list (0 basic) (1 selected_basic) (2 combined) (3 \ cursor) (4 selected_cursor) (5 selection) (6 selected_selection) (7 erase) (8 selected_erase) (9 mark) (10 selected_mark) (11 mix) (12 \ fltenv_basic) (13 fltenv_data))." #if USE_MOTIF #define Xen_wrap_snd_gc(Value) Xen_list_2(C_string_to_Xen_symbol("GC"), Xen_wrap_C_pointer(Value)) #else #if USE_GTK #define Xen_wrap_snd_gc(Value) Xen_list_2(C_string_to_Xen_symbol("gc_t_"), Xen_wrap_C_pointer(Value)) #else #define Xen_wrap_snd_gc(Value) Xen_false #endif #endif #if (!USE_NO_GUI) return(Xen_cons(Xen_wrap_snd_gc(ss->basic_gc), Xen_cons(Xen_wrap_snd_gc(ss->selected_basic_gc), Xen_cons(Xen_wrap_snd_gc(ss->combined_basic_gc), Xen_cons(Xen_wrap_snd_gc(ss->cursor_gc), Xen_cons(Xen_wrap_snd_gc(ss->selected_cursor_gc), Xen_cons(Xen_wrap_snd_gc(ss->selection_gc), Xen_cons(Xen_wrap_snd_gc(ss->selected_selection_gc), Xen_cons(Xen_wrap_snd_gc(ss->erase_gc), Xen_cons(Xen_wrap_snd_gc(ss->selected_erase_gc), Xen_cons(Xen_wrap_snd_gc(ss->mark_gc), Xen_cons(Xen_wrap_snd_gc(ss->selected_mark_gc), Xen_cons(Xen_wrap_snd_gc(ss->mix_gc), Xen_cons(Xen_wrap_snd_gc(ss->fltenv_basic_gc), Xen_cons(Xen_wrap_snd_gc(ss->fltenv_data_gc), Xen_empty_list))))))))))))))); #else return(Xen_empty_list); #endif } static Xen g_snd_color(Xen choice) { #define H_snd_color "(" S_snd_color " num): color associated with 'num' -- see table of colors in snd-draw.c" color_t col; Xen_check_type(Xen_is_integer(choice), choice, 1, S_snd_color, "an integer"); switch (Xen_integer_to_C_int(choice)) { case 0: col = ss->white; break; case 1: col = ss->black; break; case 2: col = ss->red; break; case 3: col = ss->yellow; break; case 4: col = ss->green; break; case 5: col = ss->light_blue; break; case 6: col = ss->lighter_blue; break; case 7: col = ss->data_color; break; case 8: col = ss->selected_data_color; break; case 9: col = ss->mark_color; break; case 10: col = ss->graph_color; break; case 11: col = ss->selected_graph_color; break; case 12: col = ss->listener_color; break; case 13: col = ss->listener_text_color; break; case 14: col = ss->basic_color; break; case 15: col = ss->selection_color; break; case 16: col = ss->zoom_color; break; case 17: col = ss->position_color; break; case 18: col = ss->highlight_color; break; case 19: col = ss->enved_waveform_color; break; case 20: col = ss->cursor_color; break; case 21: col = ss->text_focus_color; break; case 22: col = ss->filter_control_waveform_color; break; case 23: col = ss->mix_color; break; case 25: col = ss->sash_color; break; case 31: col = ss->grid_color; break; case 32: col = ss->selected_grid_color; break; case 33: if (ss->axis_color_set) col = ss->axis_color; else col = ss->black; break; default: col = ss->black; break; } return(Xen_wrap_pixel(col)); } static Xen g_snd_font(Xen choice) { #if USE_MOTIF #define WRAP_FONT(Value) Xen_list_2(C_string_to_Xen_symbol("Font"), C_ulong_to_Xen_ulong((unsigned long)Value)) #else #define WRAP_FONT(Value) Xen_list_2(C_string_to_Xen_symbol("PangoFontDescription_"), Xen_wrap_C_pointer(Value)) #endif #define H_snd_font "(" S_snd_font " num): font associated with 'num' -- see table of fonts in snd-draw.c" Xen_check_type(Xen_is_integer(choice), choice, 1, S_snd_font, "an integer"); switch (Xen_integer_to_C_int(choice)) { #if USE_MOTIF case 0: return(WRAP_FONT(ss->peaks_fontstruct->fid)); break; case 1: return(WRAP_FONT(ss->bold_peaks_fontstruct->fid)); break; case 2: return(WRAP_FONT(ss->tiny_fontstruct->fid)); break; case 3: return(WRAP_FONT(ss->axis_label_fontstruct->fid)); break; case 4: return(WRAP_FONT(ss->axis_numbers_fontstruct->fid)); break; case 5: return(WRAP_FONT(ss->listener_fontstruct->fid)); break; #endif #if USE_GTK case 0: return(WRAP_FONT(ss->peaks_fnt)); break; case 1: return(WRAP_FONT(ss->bold_peaks_fnt)); break; case 2: return(WRAP_FONT(ss->tiny_fnt)); break; case 3: return(WRAP_FONT(ss->axis_label_fnt)); break; case 4: return(WRAP_FONT(ss->axis_numbers_fnt)); break; case 5: return(WRAP_FONT(ss->listener_fnt)); break; #endif default: return(Xen_false); break; } return(Xen_false); } static Xen g_make_cairo(Xen drawer) { #define H_make_cairo "(" S_make_cairo " widget) in gtk, this returns a new cairo_t to draw on the widget." #if USE_GTK #define C_to_Xen_cairo_t(Value) Xen_list_2(C_string_to_Xen_symbol("cairo_t_"), Xen_wrap_C_pointer(Value)) cairo_t *cr; Xen_check_type(Xen_is_widget(drawer), drawer, 1, S_make_cairo, "a widget"); #if (!GTK_CHECK_VERSION(3, 0, 0)) cr = make_cairo(GDK_DRAWABLE(gtk_widget_get_window(Xen_unwrap_widget(drawer)))); #else cr = make_cairo(GDK_WINDOW(gtk_widget_get_window(Xen_unwrap_widget(drawer)))); #endif return(C_to_Xen_cairo_t(cr)); #endif return(Xen_false); } static Xen g_free_cairo(Xen xcr) { #define H_free_cairo "(" S_free_cairo " cr) in gtk, this frees (destroys) the cairo_t 'cr'." #if USE_GTK if ((Xen_is_list(xcr)) && (Xen_list_length(xcr) == 2) && (Xen_is_symbol(Xen_car(xcr))) && (strcmp("cairo_t_", Xen_symbol_to_C_string(Xen_car(xcr))) == 0)) free_cairo((cairo_t *)Xen_unwrap_C_pointer(Xen_cadr(xcr))); else Xen_error(Xen_make_error_type("not-a-graphics-context"), Xen_list_2(C_string_to_Xen_string(S_free_cairo ": cairo_t argument is not a cairo_t pointer: ~A"), xcr)); #endif return(Xen_false); } #if HAVE_GL static mus_float_t gl_currents[6] = {DEFAULT_SPECTRO_X_ANGLE, DEFAULT_SPECTRO_Y_ANGLE, DEFAULT_SPECTRO_Z_ANGLE, DEFAULT_SPECTRO_X_SCALE, DEFAULT_SPECTRO_Y_SCALE, DEFAULT_SPECTRO_Z_SCALE}; static mus_float_t x_currents[6] = {90.0, 0.0, 358.0, 1.0, 1.0, 0.1}; void sgl_save_currents(void) { mus_float_t *vals; if (with_gl(ss)) vals = gl_currents; else vals = x_currents; vals[0] = spectro_x_angle(ss); vals[1] = spectro_y_angle(ss); vals[2] = spectro_z_angle(ss); vals[3] = spectro_x_scale(ss); vals[4] = spectro_y_scale(ss); vals[5] = spectro_z_scale(ss); } void sgl_set_currents(bool with_dialogs) { mus_float_t *vals; if (with_gl(ss)) vals = gl_currents; else vals = x_currents; in_set_spectro_x_angle(vals[0]); in_set_spectro_y_angle(vals[1]); in_set_spectro_z_angle(vals[2]); in_set_spectro_x_scale(vals[3]); in_set_spectro_y_scale(vals[4]); in_set_spectro_z_scale(vals[5]); if (with_dialogs) reflect_spectro(); chans_field(FCP_X_ANGLE, vals[0]); chans_field(FCP_Y_ANGLE, vals[1]); chans_field(FCP_Z_ANGLE, vals[2]); chans_field(FCP_X_SCALE, vals[3]); chans_field(FCP_Y_SCALE, vals[4]); chans_field(FCP_Z_SCALE, vals[5]); } #endif /* -------- shared color funcs -------- */ static Xen g_is_color(Xen obj) { #define H_is_color "(" S_is_color " obj): " PROC_TRUE " if obj is a color" return(C_bool_to_Xen_boolean(Xen_is_pixel(obj))); } mus_float_t check_color_range(const char *caller, Xen val) { mus_float_t rf; rf = Xen_real_to_C_double(val); if ((rf > 1.0) || (rf < 0.0)) Xen_out_of_range_error(caller, 1, val, "value must be between 0.0 and 1.0"); return(rf); } static Xen g_set_cursor_color(Xen color) { Xen_check_type(Xen_is_pixel(color), color, 1, S_set S_cursor_color, "a color"); color_cursor(Xen_unwrap_pixel(color)); for_each_chan(update_graph); return(color); } static Xen g_cursor_color(void) { #define H_cursor_color "(" S_cursor_color "): cursor color" return(Xen_wrap_pixel(ss->cursor_color)); } #if USE_MOTIF static void highlight_recolor_everything(widget_t w, color_t color) { Pixel curcol; if (XtIsWidget(w)) { XtVaGetValues(w, XmNbackground, &curcol, NULL); if (curcol == color) XmChangeColor(w, ss->highlight_color); } /* to handle the gtk side correctly here, we'd need a list of widgets to modify -- * currently basic-color hits every background, so the whole thing is messed up. */ } #endif void set_highlight_color(color_t color) { #if USE_MOTIF color_t old_color; old_color = ss->highlight_color; #endif ss->highlight_color = color; #if HAVE_SCHEME s7_symbol_set_value(s7, ss->highlight_color_symbol, Xen_wrap_pixel(color)); #endif #if USE_MOTIF map_over_children_with_color(MAIN_SHELL(ss), highlight_recolor_everything, old_color); #endif } static Xen g_set_highlight_color(Xen color) { Xen_check_type(Xen_is_pixel(color), color, 1, S_set S_highlight_color, "a color"); set_highlight_color(Xen_unwrap_pixel(color)); return(color); } static Xen g_highlight_color(void) { #define H_highlight_color "(" S_highlight_color "): color of highlighted text or buttons" return(Xen_wrap_pixel(ss->highlight_color)); } static Xen g_set_mark_color(Xen color) { Xen_check_type(Xen_is_pixel(color), color, 1, S_set S_mark_color, "a color"); color_marks(Xen_unwrap_pixel(color)); for_each_chan(update_graph); return(color); } static Xen g_mark_color(void) { #define H_mark_color "(" S_mark_color "): mark color" return(Xen_wrap_pixel(ss->mark_color)); } void set_zoom_color(color_t color) { ss->zoom_color = color; #if HAVE_SCHEME s7_symbol_set_value(s7, ss->zoom_color_symbol, Xen_wrap_pixel(color)); #endif color_chan_components(ss->zoom_color, COLOR_ZOOM); } static Xen g_set_zoom_color(Xen color) { Xen_check_type(Xen_is_pixel(color), color, 1, S_set S_zoom_color, "a color"); set_zoom_color(Xen_unwrap_pixel(color)); return(color); } static Xen g_zoom_color(void) { #define H_zoom_color "(" S_zoom_color "): color of zoom sliders" return(Xen_wrap_pixel(ss->zoom_color)); } void set_position_color(color_t color) { ss->position_color = color; #if HAVE_SCHEME s7_symbol_set_value(s7, ss->position_color_symbol, Xen_wrap_pixel(color)); #endif color_chan_components(ss->position_color, COLOR_POSITION); } static Xen g_set_position_color(Xen color) { Xen_check_type(Xen_is_pixel(color), color, 1, S_set S_position_color, "a color"); set_position_color(Xen_unwrap_pixel(color)); return(color); } static Xen g_position_color(void) { #define H_position_color "(" S_position_color "): color of position sliders" return(Xen_wrap_pixel(ss->position_color)); } static Xen g_set_listener_color(Xen color) { Xen_check_type(Xen_is_pixel(color), color, 1, S_set S_listener_color, "a color"); color_listener(Xen_unwrap_pixel(color)); return(color); } static Xen g_listener_color(void) { #define H_listener_color "(" S_listener_color "): background color of the lisp listener" return(Xen_wrap_pixel(ss->listener_color)); } static Xen g_set_listener_text_color(Xen color) { Xen_check_type(Xen_is_pixel(color), color, 1, S_set S_listener_text_color, "a color"); color_listener_text(Xen_unwrap_pixel(color)); return(color); } static Xen g_listener_text_color(void) { #define H_listener_text_color "(" S_listener_text_color "): text color in the lisp listener" return(Xen_wrap_pixel(ss->listener_text_color)); } static Xen g_set_enved_waveform_color(Xen color) { Xen_check_type(Xen_is_pixel(color), color, 1, S_set S_enved_waveform_color, "a color"); ss->enved_waveform_color = Xen_unwrap_pixel(color); #if HAVE_SCHEME s7_symbol_set_value(s7, ss->enved_waveform_color_symbol, color); #endif color_enved_waveform(Xen_unwrap_pixel(color)); return(color); } static Xen g_enved_waveform_color(void) { #define H_enved_waveform_color "(" S_enved_waveform_color "): color of the envelope editor wave display" return(Xen_wrap_pixel(ss->enved_waveform_color)); } static Xen g_set_filter_control_waveform_color(Xen color) { Xen_check_type(Xen_is_pixel(color), color, 1, S_set S_filter_control_waveform_color, "a color"); ss->filter_control_waveform_color = Xen_unwrap_pixel(color); #if HAVE_SCHEME s7_symbol_set_value(s7, ss->filter_control_waveform_color_symbol, color); #endif color_filter_waveform(Xen_unwrap_pixel(color)); return(color); } static Xen g_filter_control_waveform_color(void) { #define H_filter_control_waveform_color "(" S_filter_control_waveform_color "): color of the filter waveform" return(Xen_wrap_pixel(ss->filter_control_waveform_color)); } static Xen g_set_selection_color(Xen color) { Xen_check_type(Xen_is_pixel(color), color, 1, S_set S_selection_color, "a color"); color_selection(Xen_unwrap_pixel(color)); for_each_chan(update_graph); return(color); } static Xen g_selection_color(void) { #define H_selection_color "(" S_selection_color "): selection color" return(Xen_wrap_pixel(ss->selection_color)); } static Xen g_set_text_focus_color(Xen color) { Xen_check_type(Xen_is_pixel(color), color, 1, S_set S_text_focus_color, "a color"); ss->text_focus_color = Xen_unwrap_pixel(color); #if HAVE_SCHEME s7_symbol_set_value(s7, ss->text_focus_color_symbol, color); #endif return(color); } static Xen g_text_focus_color(void) { #define H_text_focus_color "(" S_text_focus_color "): color used to show a text field has focus" return(Xen_wrap_pixel(ss->text_focus_color)); } static Xen g_set_sash_color(Xen color) { Xen_check_type(Xen_is_pixel(color), color, 1, S_set S_sash_color, "a color"); ss->sash_color = Xen_unwrap_pixel(color); #if HAVE_SCHEME s7_symbol_set_value(s7, ss->sash_color_symbol, color); #endif return(color); } static Xen g_sash_color(void) { #define H_sash_color "(" S_sash_color "): color used to draw paned window sashes" return(Xen_wrap_pixel(ss->sash_color)); } static Xen g_data_color(void) { #define H_data_color "(" S_data_color "): color used to draw unselected data" return(Xen_wrap_pixel(ss->data_color)); } void set_data_color(color_t color) { ss->data_color = color; #if HAVE_SCHEME s7_symbol_set_value(s7, ss->data_color_symbol, Xen_wrap_pixel(color)); #endif color_data(color); ss->grid_color = get_in_between_color(ss->data_color, ss->graph_color); for_each_chan(update_graph); } static Xen g_set_data_color(Xen color) { Xen_check_type(Xen_is_pixel(color), color, 1, S_set S_data_color, "a color"); set_data_color(Xen_unwrap_pixel(color)); return(color); } void set_selected_data_color(color_t color) { chan_info *cp; ss->selected_data_color = color; #if HAVE_SCHEME s7_symbol_set_value(s7, ss->selected_data_color_symbol, Xen_wrap_pixel(color)); #endif color_selected_data(color); ss->selected_grid_color = get_in_between_color(ss->selected_data_color, ss->selected_graph_color); cp = selected_channel(); if (cp) update_graph(cp); } static Xen g_set_selected_data_color(Xen color) { Xen_check_type(Xen_is_pixel(color), color, 1, S_set S_selected_data_color, "a color"); set_selected_data_color(Xen_unwrap_pixel(color)); return(color); } static Xen g_selected_data_color(void) { #define H_selected_data_color "(" S_selected_data_color "): color used for selected data" return(Xen_wrap_pixel(ss->selected_data_color)); } void set_graph_color(color_t color) { color_graph(color); ss->graph_color = color; #if HAVE_SCHEME s7_symbol_set_value(s7, ss->graph_color_symbol, Xen_wrap_pixel(color)); #endif color_unselected_graphs(color); ss->grid_color = get_in_between_color(ss->data_color, ss->graph_color); } static Xen g_set_graph_color(Xen color) { Xen_check_type(Xen_is_pixel(color), color, 1, S_set S_graph_color, "a color"); set_graph_color(Xen_unwrap_pixel(color)); return(color); } static Xen g_graph_color(void) { #define H_graph_color "(" S_graph_color "): background color used for unselected data" return(Xen_wrap_pixel(ss->graph_color)); } void set_selected_graph_color(color_t color) { chan_info *cp; ss->selected_graph_color = color; #if HAVE_SCHEME s7_symbol_set_value(s7, ss->selected_graph_color_symbol, Xen_wrap_pixel(color)); #endif color_selected_graph(color); ss->selected_grid_color = get_in_between_color(ss->selected_data_color, ss->selected_graph_color); cp = selected_channel(); if (cp) { #if USE_MOTIF XtVaSetValues(channel_graph(cp), XmNbackground, ss->selected_graph_color, NULL); #else widget_modify_bg(channel_graph(cp), GTK_STATE_NORMAL, ss->selected_graph_color); #endif } } static Xen g_set_selected_graph_color(Xen color) { Xen_check_type(Xen_is_pixel(color), color, 1, S_set S_selected_graph_color, "a color"); set_selected_graph_color(Xen_unwrap_pixel(color)); return(color); } static Xen g_selected_graph_color(void) { #define H_selected_graph_color "(" S_selected_graph_color "): background color of selected data" return(Xen_wrap_pixel(ss->selected_graph_color)); } static Xen g_set_axis_color(Xen color) { Xen_check_type(Xen_is_pixel(color), color, 1, S_set S_axis_color, "a color"); ss->axis_color = Xen_unwrap_pixel(color); ss->axis_color_set = true; #if HAVE_SCHEME s7_symbol_set_value(s7, ss->axis_color_symbol, color); #endif for_each_chan(update_graph); return(color); } static Xen g_axis_color(void) { #define H_axis_color "(" S_axis_color "): color of axis (defaults to current data color)" return(Xen_wrap_pixel(ss->axis_color)); } static Xen g_basic_color(void) { #define H_basic_color "(" S_basic_color "): Snd's basic color" return(Xen_wrap_pixel(ss->basic_color)); } #if USE_GTK #if GTK_CHECK_VERSION(3, 0, 0) #if (!GTK_CHECK_VERSION(3, 16, 0)) static bool is_dark(color_info *color) { return(color->red + color->green + color->blue < 0.75); } #endif #endif static void recolor_everything_1(widget_t w, gpointer color) { #if (!GTK_CHECK_VERSION(3, 16, 0)) if ((GTK_IS_WIDGET(w)) && (w != ss->listener_pane)) { #if (!GTK_CHECK_VERSION(3, 0, 0)) /* this is a gigantic memory leak */ #if 0 gtk_widget_modify_bg(w, GTK_STATE_NORMAL, (GdkColor *)color); if (GTK_IS_CONTAINER(w)) gtk_container_foreach(GTK_CONTAINER(w), recolor_everything_1, color); #endif #else gtk_widget_override_background_color(w, GTK_STATE_FLAG_ACTIVE, (GdkRGBA *)color); if (GTK_IS_LABEL(w)) { if (is_dark((color_info *)color)) gtk_widget_override_color(w, GTK_STATE_FLAG_ACTIVE, (GdkRGBA *)(ss->white)); else gtk_widget_override_color(w, GTK_STATE_FLAG_ACTIVE, (GdkRGBA *)(ss->black)); } if (GTK_IS_CONTAINER(w)) gtk_container_foreach(GTK_CONTAINER(w), recolor_everything_1, color); #endif } #endif } void recolor_everything(widget_t w, gpointer color) { #if (!GTK_CHECK_VERSION(3, 0, 0)) GdkColor *nc; nc = rgb_to_gdk_color((color_t)color); #else GdkRGBA *nc; nc = (GdkRGBA *)color; #endif recolor_everything_1(w, (gpointer)nc); } static Xen g_color_to_list(Xen obj) { #define H_color_to_list "(" S_color_to_list " obj): 'obj' rgb values as a list of floats" color_info *v; Xen_check_type(Xen_is_pixel(obj), obj, 1, S_color_to_list, "a color"); v = Xen_unwrap_pixel(obj); if (v) return(Xen_list_4(C_double_to_Xen_real(rgb_to_float(v->red)), C_double_to_Xen_real(rgb_to_float(v->green)), C_double_to_Xen_real(rgb_to_float(v->blue)), C_double_to_Xen_real(v->alpha))); return(Xen_empty_list); } static Xen g_make_color(Xen r, Xen g, Xen b, Xen alpha) { #define H_make_color "(" S_make_color " r g b alpha): return a color object with the indicated rgb values" color_info *ccolor; mus_float_t rf, gf, bf; Xen_check_type(Xen_is_number(r), r, 1, S_make_color, "a number"); /* someday accept a list as r */ Xen_check_type(Xen_is_number(g), g, 2, S_make_color, "a number"); Xen_check_type(Xen_is_number(b), b, 3, S_make_color, "a number"); rf = check_color_range(S_make_color, r); gf = check_color_range(S_make_color, g); bf = check_color_range(S_make_color, b); ccolor = (color_info *)calloc(1, sizeof(color_info)); /* memleak here */ ccolor->red = rf; ccolor->green = gf; ccolor->blue = bf; if (Xen_is_number(alpha)) ccolor->alpha = check_color_range(S_make_color, alpha); else ccolor->alpha = 1.0; return(Xen_wrap_pixel(ccolor)); } #endif #if USE_MOTIF static void recolor_everything(widget_t w, color_t color) { Pixel curcol; if (XtIsWidget(w)) { XtVaGetValues(w, XmNbackground, &curcol, NULL); if (curcol == color) XmChangeColor(w, ss->basic_color); } } static Xen g_color_to_list(Xen obj) { #define H_color_to_list "(" S_color_to_list " obj): 'obj' rgb values as a list of floats" Colormap cmap; XColor tmp_color; Display *dpy; Xen_check_type(Xen_is_pixel(obj), obj, 1, S_color_to_list, "a color"); dpy = XtDisplay(MAIN_SHELL(ss)); cmap = DefaultColormap(dpy, DefaultScreen(dpy)); tmp_color.flags = DoRed | DoGreen | DoBlue; tmp_color.pixel = Xen_unwrap_pixel(obj); XQueryColor(dpy, cmap, &tmp_color); return(Xen_list_3(C_double_to_Xen_real(rgb_to_float(tmp_color.red)), C_double_to_Xen_real(rgb_to_float(tmp_color.green)), C_double_to_Xen_real(rgb_to_float(tmp_color.blue)))); } static Xen g_make_color(Xen r, Xen g, Xen b, Xen alpha) { /* alpha is ignored in Motif */ #define H_make_color "(" S_make_color " r g b alpha): return a color object with the indicated rgb values" Colormap cmap; XColor tmp_color; Display *dpy; mus_float_t rf, gf, bf; Xen_check_type(Xen_is_number(r), r, 1, S_make_color, "a number"); /* someday accept a list as r */ Xen_check_type(Xen_is_number(g), g, 2, S_make_color, "a number"); Xen_check_type(Xen_is_number(b), b, 3, S_make_color, "a number"); rf = check_color_range(S_make_color, r); gf = check_color_range(S_make_color, g); bf = check_color_range(S_make_color, b); dpy = XtDisplay(MAIN_SHELL(ss)); cmap = DefaultColormap(dpy, DefaultScreen(dpy)); tmp_color.flags = DoRed | DoGreen | DoBlue; tmp_color.red = float_to_rgb(rf); tmp_color.green = float_to_rgb(gf); tmp_color.blue = float_to_rgb(bf); if ((XAllocColor(dpy, cmap, &tmp_color)) == 0) Xen_error(Xen_make_error_type("no-such-color"), Xen_list_4(C_string_to_Xen_string(S_make_color ": can't allocate this color! (~A ~A ~A)"), r, g, b)); return(Xen_wrap_pixel(tmp_color.pixel)); } #endif void set_basic_color(color_t color) { #if USE_MOTIF color_t old_color; old_color = ss->basic_color; #endif #if HAVE_SCHEME s7_symbol_set_value(s7, ss->basic_color_symbol, Xen_wrap_pixel(color)); #endif ss->basic_color = color; #if USE_MOTIF map_over_children_with_color(MAIN_SHELL(ss), recolor_everything, old_color); #endif #if USE_GTK recolor_everything(MAIN_SHELL(ss), color); #endif #if USE_MOTIF make_sound_icons_transparent_again(old_color, ss->basic_color); make_mixer_icons_transparent_again(old_color, ss->basic_color); #endif } static Xen g_set_basic_color(Xen color) { Xen_check_type(Xen_is_pixel(color), color, 1, S_set S_basic_color, "a color"); set_basic_color(Xen_unwrap_pixel(color)); return(color); } static Xen g_mix_color(Xen mix_id) { #define H_mix_color "(" S_mix_color " :optional mix-id): color of all mix tags (if mix-id is omitted), or of mix-id's tag" if (xen_is_mix(mix_id)) return(Xen_wrap_pixel(mix_color_from_id(Xen_mix_to_C_int(mix_id)))); return(Xen_wrap_pixel(ss->mix_color)); } static Xen g_set_mix_color(Xen color, Xen mix_id) { Xen_check_type(Xen_is_pixel(color), color, 1, S_set S_mix_color, "a color"); Xen_check_type(xen_is_mix(mix_id) || !Xen_is_bound(mix_id), mix_id, 2, S_set S_mix_color, "a mix"); if (xen_is_mix(mix_id)) mix_set_color_from_id(Xen_mix_to_C_int(mix_id), Xen_unwrap_pixel(color)); else color_mixes(Xen_unwrap_pixel(color)); return(color); } with_two_setter_args(g_set_mix_color_reversed, g_set_mix_color) bool foreground_color_ok(Xen color, graphics_context *ax) { if (Xen_is_pixel(color)) { set_foreground_color(ax, (color_t)Xen_unwrap_pixel(color)); return(true); } return(false); } static Xen g_combined_data_color(Xen snd, Xen chn) { #define H_combined_data_color "(" S_combined_data_color " snd chn): color of this channel's data if graphed with channels-combined" chan_info *cp; Snd_assert_channel(S_combined_data_color, snd, chn, 1); cp = get_cp(snd, chn, S_combined_data_color); if (!cp) return(Xen_false); return(Xen_wrap_pixel(cp->combined_data_color)); } static Xen g_set_combined_data_color(Xen color, Xen snd, Xen chn) { chan_info *cp; Xen_check_type(Xen_is_pixel(color), color, 1, S_set S_combined_data_color, "a color"); Snd_assert_channel(S_combined_data_color, snd, chn, 1); cp = get_cp(snd, chn, S_combined_data_color); if (!cp) return(Xen_false); cp->combined_data_color = Xen_unwrap_pixel(color); update_graph(cp); return(color); } with_three_setter_args(g_set_combined_data_color_reversed, g_set_combined_data_color) Xen_wrap_8_optional_args(g_draw_line_w, g_draw_line) Xen_wrap_7_optional_args(g_draw_dot_w, g_draw_dot) Xen_wrap_5_optional_args(g_draw_lines_w, g_draw_lines) Xen_wrap_6_optional_args(g_draw_dots_w, g_draw_dots) Xen_wrap_7_optional_args(g_draw_string_w, g_draw_string) Xen_wrap_9_optional_args(g_fill_rectangle_w, g_fill_rectangle) Xen_wrap_5_optional_args(g_fill_polygon_w, g_fill_polygon) Xen_wrap_3_optional_args(g_foreground_color_w, g_foreground_color) Xen_wrap_3_optional_args(g_current_font_w, g_current_font) Xen_wrap_no_args(g_main_widgets_w, g_main_widgets) Xen_wrap_no_args(g_dialog_widgets_w, g_dialog_widgets) Xen_wrap_1_arg(g_widget_size_w, g_widget_size) Xen_wrap_2_args(g_set_widget_size_w, g_set_widget_size) Xen_wrap_1_arg(g_widget_position_w, g_widget_position) Xen_wrap_2_args(g_set_widget_position_w, g_set_widget_position) Xen_wrap_1_arg(g_widget_text_w, g_widget_text) Xen_wrap_2_args(g_set_widget_text_w, g_set_widget_text) Xen_wrap_1_arg(g_hide_widget_w, g_hide_widget) Xen_wrap_1_arg(g_show_widget_w, g_show_widget) Xen_wrap_1_arg(g_focus_widget_w, g_focus_widget) Xen_wrap_5_optional_args(g_make_graph_data_w, g_make_graph_data) Xen_wrap_8_optional_args(g_graph_data_w, g_graph_data) Xen_wrap_any_args(g_make_bezier_w, g_make_bezier) Xen_wrap_no_args(g_snd_gcs_w, g_snd_gcs) Xen_wrap_1_arg(g_snd_color_w, g_snd_color) Xen_wrap_1_arg(g_snd_font_w, g_snd_font) Xen_wrap_1_arg(g_make_cairo_w, g_make_cairo) Xen_wrap_1_arg(g_free_cairo_w, g_free_cairo) Xen_wrap_no_args(g_selection_color_w, g_selection_color) Xen_wrap_1_arg(g_set_selection_color_w, g_set_selection_color) Xen_wrap_no_args(g_zoom_color_w, g_zoom_color) Xen_wrap_1_arg(g_set_zoom_color_w, g_set_zoom_color) Xen_wrap_no_args(g_position_color_w, g_position_color) Xen_wrap_1_arg(g_set_position_color_w, g_set_position_color) Xen_wrap_no_args(g_mark_color_w, g_mark_color) Xen_wrap_1_arg(g_set_mark_color_w, g_set_mark_color) Xen_wrap_no_args(g_listener_color_w, g_listener_color) Xen_wrap_1_arg(g_set_listener_color_w, g_set_listener_color) Xen_wrap_no_args(g_listener_text_color_w, g_listener_text_color) Xen_wrap_1_arg(g_set_listener_text_color_w, g_set_listener_text_color) Xen_wrap_no_args(g_enved_waveform_color_w, g_enved_waveform_color) Xen_wrap_1_arg(g_set_enved_waveform_color_w, g_set_enved_waveform_color) Xen_wrap_no_args(g_filter_control_waveform_color_w, g_filter_control_waveform_color) Xen_wrap_1_arg(g_set_filter_control_waveform_color_w, g_set_filter_control_waveform_color) Xen_wrap_no_args(g_highlight_color_w, g_highlight_color) Xen_wrap_1_arg(g_set_highlight_color_w, g_set_highlight_color) Xen_wrap_no_args(g_cursor_color_w, g_cursor_color) Xen_wrap_1_arg(g_set_cursor_color_w, g_set_cursor_color) Xen_wrap_no_args(g_text_focus_color_w, g_text_focus_color) Xen_wrap_1_arg(g_set_text_focus_color_w, g_set_text_focus_color) Xen_wrap_no_args(g_sash_color_w, g_sash_color) Xen_wrap_1_arg(g_set_sash_color_w, g_set_sash_color) Xen_wrap_no_args(g_data_color_w, g_data_color) Xen_wrap_1_arg(g_set_data_color_w, g_set_data_color) Xen_wrap_no_args(g_graph_color_w, g_graph_color) Xen_wrap_1_arg(g_set_graph_color_w, g_set_graph_color) Xen_wrap_no_args(g_selected_graph_color_w, g_selected_graph_color) Xen_wrap_1_arg(g_set_selected_graph_color_w, g_set_selected_graph_color) Xen_wrap_no_args(g_selected_data_color_w, g_selected_data_color) Xen_wrap_1_arg(g_set_selected_data_color_w, g_set_selected_data_color) Xen_wrap_no_args(g_axis_color_w, g_axis_color) Xen_wrap_1_arg(g_set_axis_color_w, g_set_axis_color) Xen_wrap_no_args(g_basic_color_w, g_basic_color) Xen_wrap_1_arg(g_set_basic_color_w, g_set_basic_color) Xen_wrap_1_arg(g_is_color_w, g_is_color) Xen_wrap_4_optional_args(g_make_color_w, g_make_color) Xen_wrap_1_arg(g_color_to_list_w, g_color_to_list) Xen_wrap_1_optional_arg(g_mix_color_w, g_mix_color) Xen_wrap_2_args(g_combined_data_color_w, g_combined_data_color) #if HAVE_SCHEME #define g_set_current_font_w g_set_current_font_reversed #define g_set_foreground_color_w g_set_foreground_color_reversed #define g_set_mix_color_w g_set_mix_color_reversed #define g_set_combined_data_color_w g_set_combined_data_color_reversed static s7_pointer acc_data_color(s7_scheme *sc, s7_pointer args) {return(g_set_data_color(s7_cadr(args)));} static s7_pointer acc_selected_data_color(s7_scheme *sc, s7_pointer args) {return(g_set_selected_data_color(s7_cadr(args)));} static s7_pointer acc_mark_color(s7_scheme *sc, s7_pointer args) {return(g_set_mark_color(s7_cadr(args)));} static s7_pointer acc_graph_color(s7_scheme *sc, s7_pointer args) {return(g_set_graph_color(s7_cadr(args)));} static s7_pointer acc_selected_graph_color(s7_scheme *sc, s7_pointer args) {return(g_set_selected_graph_color(s7_cadr(args)));} static s7_pointer acc_listener_color(s7_scheme *sc, s7_pointer args) {return(g_set_listener_color(s7_cadr(args)));} static s7_pointer acc_listener_text_color(s7_scheme *sc, s7_pointer args) {return(g_set_listener_text_color(s7_cadr(args)));} static s7_pointer acc_basic_color(s7_scheme *sc, s7_pointer args) {return(g_set_basic_color(s7_cadr(args)));} static s7_pointer acc_zoom_color(s7_scheme *sc, s7_pointer args) {return(g_set_zoom_color(s7_cadr(args)));} static s7_pointer acc_selection_color(s7_scheme *sc, s7_pointer args) {return(g_set_selection_color(s7_cadr(args)));} static s7_pointer acc_position_color(s7_scheme *sc, s7_pointer args) {return(g_set_position_color(s7_cadr(args)));} static s7_pointer acc_highlight_color(s7_scheme *sc, s7_pointer args) {return(g_set_highlight_color(s7_cadr(args)));} static s7_pointer acc_enved_waveform_color(s7_scheme *sc, s7_pointer args) {return(g_set_enved_waveform_color(s7_cadr(args)));} static s7_pointer acc_cursor_color(s7_scheme *sc, s7_pointer args) {return(g_set_cursor_color(s7_cadr(args)));} static s7_pointer acc_filter_control_waveform_color(s7_scheme *sc, s7_pointer args) {return(g_set_filter_control_waveform_color(s7_cadr(args)));} static s7_pointer acc_sash_color(s7_scheme *sc, s7_pointer args) {return(g_set_sash_color(s7_cadr(args)));} static s7_pointer acc_axis_color(s7_scheme *sc, s7_pointer args) {return(g_set_axis_color(s7_cadr(args)));} static s7_pointer acc_mix_color(s7_scheme *sc, s7_pointer args) {return(g_set_mix_color(s7_cadr(args), s7_undefined(s7)));} static s7_pointer acc_text_focus_color(s7_scheme *sc, s7_pointer args) {return(g_set_text_focus_color(s7_cadr(args)));} #else Xen_wrap_4_optional_args(g_set_current_font_w, g_set_current_font) Xen_wrap_4_optional_args(g_set_foreground_color_w, g_set_foreground_color) Xen_wrap_2_optional_args(g_set_mix_color_w, g_set_mix_color) Xen_wrap_3_args(g_set_combined_data_color_w, g_set_combined_data_color) #endif void g_init_draw(void) { dialog_widgets = Xen_undefined; Xen_define_constant(S_copy_context, CHAN_GC, "graphics context to draw a line"); Xen_define_constant(S_cursor_context, CHAN_CGC, "graphics context for the cursor"); Xen_define_constant(S_selection_context, CHAN_SELGC, "graphics context to draw in the selection color"); Xen_define_constant(S_mark_context, CHAN_MGC, "graphics context for a mark"); Xen_define_safe_procedure(S_draw_line, g_draw_line_w, 4, 4, 0, H_draw_line); Xen_define_safe_procedure(S_draw_dot, g_draw_dot_w, 2, 5, 0, H_draw_dot); Xen_define_safe_procedure(S_draw_lines, g_draw_lines_w, 1, 4, 0, H_draw_lines); Xen_define_safe_procedure(S_draw_dots, g_draw_dots_w, 1, 5, 0, H_draw_dots); Xen_define_safe_procedure(S_draw_string, g_draw_string_w, 3, 4, 0, H_draw_string); Xen_define_safe_procedure(S_fill_rectangle, g_fill_rectangle_w, 4, 5, 0, H_fill_rectangle); Xen_define_safe_procedure(S_fill_polygon, g_fill_polygon_w, 1, 4, 0, H_fill_polygon); Xen_define_safe_procedure(S_main_widgets, g_main_widgets_w, 0, 0, 0, H_main_widgets); Xen_define_safe_procedure(S_dialog_widgets, g_dialog_widgets_w, 0, 0, 0, H_dialog_widgets); Xen_define_safe_procedure(S_hide_widget, g_hide_widget_w, 1, 0, 0, H_hide_widget); Xen_define_safe_procedure(S_show_widget, g_show_widget_w, 1, 0, 0, H_show_widget); Xen_define_safe_procedure(S_focus_widget, g_focus_widget_w, 1, 0, 0, H_focus_widget); Xen_define_safe_procedure(S_make_graph_data, g_make_graph_data_w, 0, 5, 0, H_make_graph_data); Xen_define_safe_procedure(S_graph_data, g_graph_data_w, 1, 7, 0, H_graph_data); Xen_define_dilambda(S_foreground_color, g_foreground_color_w, H_foreground_color, S_set S_foreground_color, g_set_foreground_color_w, 0, 3, 1, 3); Xen_define_dilambda(S_current_font, g_current_font_w, H_current_font, S_set S_current_font, g_set_current_font_w, 0, 3, 1, 3); Xen_define_dilambda(S_widget_size, g_widget_size_w, H_widget_size, S_set S_widget_size, g_set_widget_size_w, 1, 0, 2, 0); Xen_define_dilambda(S_widget_position, g_widget_position_w, H_widget_position, S_set S_widget_position, g_set_widget_position_w, 1, 0, 2, 0); Xen_define_dilambda(S_widget_text, g_widget_text_w, H_widget_text, S_set S_widget_text, g_set_widget_text_w, 1, 0, 2, 0); Xen_define_dilambda(S_selection_color, g_selection_color_w, H_selection_color, S_set S_selection_color, g_set_selection_color_w, 0, 0, 1, 0); Xen_define_dilambda(S_zoom_color, g_zoom_color_w, H_zoom_color, S_set S_zoom_color, g_set_zoom_color_w, 0, 0, 1, 0); Xen_define_dilambda(S_position_color, g_position_color_w, H_position_color, S_set S_position_color, g_set_position_color_w, 0, 0, 1, 0); Xen_define_dilambda(S_mark_color, g_mark_color_w, H_mark_color, S_set S_mark_color, g_set_mark_color_w, 0, 0, 1, 0); Xen_define_dilambda(S_listener_color, g_listener_color_w, H_listener_color, S_set S_listener_color, g_set_listener_color_w, 0, 0, 1, 0); Xen_define_dilambda(S_listener_text_color, g_listener_text_color_w, H_listener_text_color, S_set S_listener_text_color, g_set_listener_text_color_w, 0, 0, 1, 0); Xen_define_dilambda(S_enved_waveform_color, g_enved_waveform_color_w, H_enved_waveform_color, S_set S_enved_waveform_color, g_set_enved_waveform_color_w, 0, 0, 1, 0); Xen_define_dilambda(S_filter_control_waveform_color, g_filter_control_waveform_color_w, H_filter_control_waveform_color, S_set S_filter_control_waveform_color, g_set_filter_control_waveform_color_w, 0, 0, 1, 0); Xen_define_dilambda(S_highlight_color, g_highlight_color_w, H_highlight_color, S_set S_highlight_color, g_set_highlight_color_w, 0, 0, 1, 0); Xen_define_dilambda(S_cursor_color, g_cursor_color_w, H_cursor_color, S_set S_cursor_color, g_set_cursor_color_w, 0, 0, 1, 0); Xen_define_dilambda(S_text_focus_color, g_text_focus_color_w, H_text_focus_color, S_set S_text_focus_color, g_set_text_focus_color_w, 0, 0, 1, 0); Xen_define_dilambda(S_sash_color, g_sash_color_w, H_sash_color, S_set S_sash_color, g_set_sash_color_w, 0, 0, 1, 0); Xen_define_dilambda(S_data_color, g_data_color_w, H_data_color, S_set S_data_color, g_set_data_color_w, 0, 0, 1, 0); Xen_define_dilambda(S_graph_color, g_graph_color_w, H_graph_color, S_set S_graph_color, g_set_graph_color_w, 0, 0, 1, 0); Xen_define_dilambda(S_selected_graph_color, g_selected_graph_color_w, H_selected_graph_color, S_set S_selected_graph_color, g_set_selected_graph_color_w, 0, 0, 1, 0); Xen_define_dilambda(S_selected_data_color, g_selected_data_color_w, H_selected_data_color, S_set S_selected_data_color, g_set_selected_data_color_w, 0, 0, 1, 0); Xen_define_dilambda(S_axis_color, g_axis_color_w, H_axis_color, S_set S_axis_color, g_set_axis_color_w, 0, 0, 1, 0); Xen_define_dilambda(S_basic_color, g_basic_color_w, H_basic_color, S_set S_basic_color, g_set_basic_color_w, 0, 0, 1, 0); Xen_define_dilambda(S_mix_color, g_mix_color_w, H_mix_color, S_set S_mix_color, g_set_mix_color_w, 0, 1, 1, 1); Xen_define_dilambda(S_combined_data_color, g_combined_data_color_w, H_combined_data_color, S_set S_combined_data_color, g_set_combined_data_color_w, 2, 0, 3, 0); Xen_define_safe_procedure(S_is_color, g_is_color_w, 1, 0, 0, H_is_color); Xen_define_safe_procedure(S_make_color, g_make_color_w, 3, 1, 0, H_make_color); Xen_define_safe_procedure(S_color_to_list, g_color_to_list_w, 1, 0, 0, H_color_to_list); Xen_define_safe_procedure(S_make_bezier, g_make_bezier_w, 0, 0, 1, H_make_bezier); Xen_define_safe_procedure(S_snd_gcs, g_snd_gcs_w, 0, 0, 0, H_snd_gcs); Xen_define_safe_procedure(S_snd_color, g_snd_color_w, 1, 0, 0, H_snd_color); Xen_define_safe_procedure(S_snd_font, g_snd_font_w, 1, 0, 0, H_snd_font); Xen_define_safe_procedure(S_make_cairo, g_make_cairo_w, 1, 0, 0, H_make_cairo); Xen_define_safe_procedure(S_free_cairo, g_free_cairo_w, 1, 0, 0, H_free_cairo); #define H_new_widget_hook S_new_widget_hook " (widget): called each time a dialog or \ a new set of channel or sound widgets is created." new_widget_hook = Xen_define_hook(S_new_widget_hook, "(make-hook 'widget)", 1, H_new_widget_hook); #if HAVE_SCHEME s7_symbol_set_access(s7, ss->data_color_symbol, s7_make_function(s7, "[acc-" S_data_color "]", acc_data_color, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->highlight_color_symbol, s7_make_function(s7, "[acc-" S_highlight_color "]", acc_highlight_color, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->axis_color_symbol, s7_make_function(s7, "[acc-" S_axis_color "]", acc_axis_color, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->sash_color_symbol, s7_make_function(s7, "[acc-" S_sash_color "]", acc_sash_color, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->filter_control_waveform_color_symbol, s7_make_function(s7, "[acc-" S_filter_control_waveform_color "]", acc_filter_control_waveform_color, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->mix_color_symbol, s7_make_function(s7, "[acc-" S_mix_color "]", acc_mix_color, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->selected_data_color_symbol, s7_make_function(s7, "[acc-" S_selected_data_color "]", acc_selected_data_color, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->mark_color_symbol, s7_make_function(s7, "[acc-" S_mark_color "]", acc_mark_color, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->graph_color_symbol, s7_make_function(s7, "[acc-" S_graph_color "]", acc_graph_color, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->selected_graph_color_symbol, s7_make_function(s7, "[acc-" S_selected_graph_color "]", acc_selected_graph_color, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->listener_color_symbol, s7_make_function(s7, "[acc-" S_listener_color "]", acc_listener_color, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->listener_text_color_symbol, s7_make_function(s7, "[acc-" S_listener_text_color "]", acc_listener_text_color, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->basic_color_symbol, s7_make_function(s7, "[acc-" S_basic_color "]", acc_basic_color, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->selection_color_symbol, s7_make_function(s7, "[acc-" S_selection_color "]", acc_selection_color, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->zoom_color_symbol, s7_make_function(s7, "[acc-" S_zoom_color "]", acc_zoom_color, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->position_color_symbol, s7_make_function(s7, "[acc-" S_position_color "]", acc_position_color, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->enved_waveform_color_symbol, s7_make_function(s7, "[acc-" S_enved_waveform_color "]", acc_enved_waveform_color, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->cursor_color_symbol, s7_make_function(s7, "[acc-" S_cursor_color "]", acc_cursor_color, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->text_focus_color_symbol, s7_make_function(s7, "[acc-" S_text_focus_color "]", acc_text_focus_color, 2, 0, false, "accessor")); s7_symbol_set_documentation(s7, ss->axis_color_symbol, "*axis-color*: color of axis (defaults to current data color)"); s7_symbol_set_documentation(s7, ss->basic_color_symbol, "*basic-color*: Snd's basic color"); s7_symbol_set_documentation(s7, ss->cursor_color_symbol, "*cursor-color*: cursor color"); s7_symbol_set_documentation(s7, ss->data_color_symbol, "*data-color*: color used to draw unselected data"); s7_symbol_set_documentation(s7, ss->enved_waveform_color_symbol, "*enved-waveform-color*: color of the envelope editor wave display"); s7_symbol_set_documentation(s7, ss->filter_control_waveform_color_symbol, "*filter-control-waveform-color*: color of the filter waveform"); s7_symbol_set_documentation(s7, ss->graph_color_symbol, "*graph-color*: background color used for unselected data"); s7_symbol_set_documentation(s7, ss->highlight_color_symbol, "*highlight-color*: color of highlighted text or buttons"); s7_symbol_set_documentation(s7, ss->listener_color_symbol, "*listener-color*: background color of the lisp listener"); s7_symbol_set_documentation(s7, ss->listener_text_color_symbol, "*listener-text-color*: text color in the lisp listener"); s7_symbol_set_documentation(s7, ss->mark_color_symbol, "*mark-color*: mark color"); s7_symbol_set_documentation(s7, ss->mix_color_symbol, "*mix-color*: color of mix tags"); s7_symbol_set_documentation(s7, ss->position_color_symbol, "*position-color*: color of position sliders"); s7_symbol_set_documentation(s7, ss->sash_color_symbol, "*sash-color*: color used to draw paned window sashes"); s7_symbol_set_documentation(s7, ss->selected_data_color_symbol, "*selected-data-color*: color used for selected data"); s7_symbol_set_documentation(s7, ss->selected_graph_color_symbol, "*selected-graph-color*: background color of selected data"); s7_symbol_set_documentation(s7, ss->selection_color_symbol, "*selection-color*: selection color"); s7_symbol_set_documentation(s7, ss->text_focus_color_symbol, "*text-focus-color*: color used to show a text field has focus"); s7_symbol_set_documentation(s7, ss->zoom_color_symbol, "*zoom-color*: color of zoom sliders"); #endif } #else /* no gui -- extension lang tie-ins are in snd-nogui.c */ void set_grf_points(int xi, int j, int ymin, int ymax) {} void set_grf_point(int xi, int j, int yi) {} void draw_grf_points(int dot_size, graphics_context *ax, int j, axis_info *ap, mus_float_t y0, graph_style_t graph_style) {} void draw_both_grf_points(int dot_size, graphics_context *ax, int j, graph_style_t graph_style) {} void draw_cursor(chan_info *cp) {} point_t *get_grf_points(void) {return(NULL);} point_t *get_grf_points1(void) {return(NULL);} bool foreground_color_ok(Xen color, graphics_context *ax) {return(true);} #endif snd-16.1/mockery.scm0000644000076400007640000013702612615151307012522 0ustar bilbil(provide 'mockery.scm) (define (outlet-member obj e) (or (eq? obj e) (and (not (eq? obj (rootlet))) (outlet-member (outlet obj) e)))) (define (make-method f accessor) (lambda args (if (let? (car args)) (apply f (accessor (car args)) (cdr args)) (apply f (car args) (accessor (cadr args)) (cddr args))))) (define (make-object . args) (openlet (apply inlet args))) (define (mock->string obj . args) (dynamic-wind (lambda () (coverlet obj)) (lambda () (apply #_object->string (obj 'value) args)) (lambda () (openlet obj)))) ;;; -------------------------------------------------------------------------------- (define *mock-vector* (let ((mock-vector? #f)) (let ((mock-vector-class (openlet (inlet 'morally-equal? (make-method #_morally-equal? (lambda (obj) (obj 'value))) ; see comment below 'local-set! (lambda (obj i val) ; reactive-vector uses this as a hook into vector-set! (if (vector? (obj 'value)) (#_vector-set! (obj 'value) i val) (error 'wrong-type-arg "vector-set! ~S ~S ~S" obj i val))) ; the wrong arg here is 'i 'vector-set! (lambda (obj i val) ((obj 'local-set!) obj i val) val) 'let-set! (lambda (obj i val) ((obj 'local-set!) obj i val) val) 'vector-ref (lambda (obj i) (if (mock-vector? obj) (#_vector-ref (obj 'value) i) (error 'wrong-type-arg "vector-ref ~S ~S" obj i))) 'let-ref (lambda (obj i) (#_vector-ref (obj 'value) i)) ; the implicit case, so 'i can't be the culprit 'vector-length (lambda (obj) (#_length (obj 'value))) (reader-cond ((not (provided? 'pure-s7)) 'vector-append (make-method #_vector-append (lambda (obj) (obj 'value))))) 'reverse (lambda (obj) (#_reverse (obj 'value))) 'sort! (lambda (obj f) (#_sort! (obj 'value) f)) 'make-iterator (lambda (obj) (#_make-iterator (obj 'value))) 'arity (lambda (obj) (#_arity (obj 'value))) 'object->string (lambda* (obj (w #t)) (if (eq? w :readable) "*mock-vector*" "#")) 'vector-dimensions (lambda (obj) (#_vector-dimensions (obj 'value))) 'fill! (lambda (obj val) (#_fill! (obj 'value) val)) 'vector->list (lambda (obj . args) (if (mock-vector? obj) (map values (obj 'value)) (error 'wrong-type-arg "vector->list ~S ~S" obj args))) 'make-shared-vector (lambda* (obj dim (off 0)) (if (mock-vector? obj) (#_make-shared-vector (obj 'value) dim off) (error 'wrong-type-arg "make-shared-vector ~S ~S ~S" obj dim off))) 'vector-fill! (lambda (obj . args) (if (mock-vector? obj) (apply #_fill! (obj 'value) args) (error 'wrong-type-arg "vector-fill! ~S ~S ~S ~S" obj val start end))) 'copy (lambda* (source dest . args) ;; copy by itself does not make a new vector, but if no dest we ;; need a copy of source, so use coverlet/openlet to make sure ;; we aren't caught in an infinite recursion. (if (mock-vector? source) (if (and dest (not (let? dest))) (apply copy (source 'value) dest args) (let ((nobj (or dest (dynamic-wind (lambda () (coverlet source)) (lambda () (openlet (copy source))) (lambda () (openlet source)))))) (if dest (apply copy (source 'value) (nobj 'value) args) (set! (nobj 'value) (copy (source 'value)))) nobj)) (error 'wrong-type-arg "copy ~S ~S ~S" source dest args))) 'vector? (lambda (obj) #t) 'values (lambda (obj . args) (obj 'value)) 'length (lambda (obj) (#_length (obj 'value))) 'append (make-method #_append (lambda (obj) (obj 'value))) 'class-name 'mock-vector)))) (define* (make-mock-vector len (init #)) (openlet (sublet mock-vector-class 'value (#_make-vector len init) 'object->string mock->string))) (define (mock-vector . args) (let ((v (make-mock-vector 0))) (set! (v 'value) (apply #_vector args)) v)) (set! mock-vector? (lambda (obj) (and (openlet? obj) (outlet-member obj mock-vector-class)))) (curlet)))) #| ;;; the morally-equal? method should track circles (via cyclic-sequences?) ;;; as it is now, this code cores up indefinitely: (let ((v1 ((*mock-vector* 'mock-vector) 1 2 3 4)) (v2 ((*mock-vector* 'mock-vector) 2 3 4)) (v3 #(1 2 3 4)) (v4 #(2 3 4))) (vector-set! v2 0 v1) (vector-set! v1 0 v2) (vector-set! v4 0 v3) (vector-set! v3 0 v4) (morally-equal? v1 v3)) ;;; but how to make this cooperate with the built-in method -- we should call cyclic-sequences just once |# #| ;; vector that grows to accommodate vector-set! (define stretchable-vector-class (let ((local-ref (lambda (obj index) (if (>= index (length (obj 'value))) (obj 'initial-element) (#_vector-ref (obj 'value) index)))) (local-set! (lambda (obj index val) (if (>= index (length (obj 'value))) (set! (obj 'value) (copy (obj 'value) (make-vector (+ index 8) (obj 'initial-element))))) (#_vector-set! (obj 'value) index val)))) (openlet (sublet (*mock-vector* 'mock-vector-class) 'value (vector) 'object->string mock->string 'initial-element #f 'vector-ref local-ref 'let-ref local-ref 'vector-set! local-set! 'let-set! local-set!)))) |# ;;; -------------------------------------------------------------------------------- (define *mock-hash-table* (let ((mock-hash-table? #f)) (let ((mock-hash-table-class (openlet (inlet 'morally-equal? (lambda (x y) (#_morally-equal? (x 'mock-hash-table-table) y)) 'hash-table-ref (lambda (obj key) (#_hash-table-ref (obj 'mock-hash-table-table) key)) 'hash-table-set! (lambda (obj key val) (#_hash-table-set! (obj 'mock-hash-table-table) key val)) 'hash-table-entries (lambda (obj) (#_hash-table-entries (obj 'mock-hash-table-table))) 'make-iterator (lambda (obj) (#_make-iterator (obj 'mock-hash-table-table))) 'let-ref-fallback (lambda (obj key) (if (defined? 'mock-hash-table-table obj) (#_hash-table-ref (obj 'mock-hash-table-table) key))) 'let-set!-fallback (lambda (obj key val) (if (defined? 'mock-hash-table-table obj) (#_hash-table-set! (obj 'mock-hash-table-table) key val))) ;; the fallbacks are needed because hash-tables and lets use exactly the same syntax in implicit indexing: ;; (x 'y) but s7 can't tell that in this one case, we actually want the 'y to be a key not a field. ;; So, to avoid infinite recursion in let-ref (implicit index), if let-ref can't find the let field, ;; and the let has 'let-ref|set!-fallback, let-ref|set! passes the argument to that function rather than ;; return #. ;; ;; (round (openlet (inlet 'round (lambda (obj) (#_round (obj 'value))) 'let-ref-fallback (lambda args 3)))) -> 3 'fill! (lambda (obj val) (#_fill! (obj 'mock-hash-table-table) val)) 'reverse (lambda (obj) (#_reverse (obj 'mock-hash-table-table))) 'object->string (lambda* (obj (w #t)) (if (eq? w :readable) "*mock-hash-table*" "#")) 'arity (lambda (obj) (#_arity (obj 'mock-hash-table-table))) 'copy (lambda* (source dest . args) (if (mock-hash-table? source) (if (and dest (not (let? dest))) (apply copy (obj 'mock-hash-table-table) dest args) (let ((nobj (or dest (openlet (copy (coverlet source)))))) (openlet source) (set! (nobj 'mock-hash-table-table) (copy (source 'mock-hash-table-table))) nobj)) (error 'wrong-type-arg "copy ~S ~S ~S" source dest args))) 'hash-table? (lambda (obj) #t) 'values (lambda (obj . args) (obj 'mock-hash-table-table)) 'length (lambda (obj) (#_length (obj 'mock-hash-table-table))) 'append (make-method #_append (lambda (obj) (obj 'value))) 'class-name 'mock-hash-table)))) (define* (make-mock-hash-table (len 511)) (openlet (sublet mock-hash-table-class 'mock-hash-table-table (#_make-hash-table len) ;; object->string here is a problem -- don't set any value to the object itself! 'object->string (lambda (obj . args) ; can't use mock->string because the value is not in the 'value field (dynamic-wind (lambda () (coverlet obj)) (lambda () (apply #_object->string (obj 'mock-hash-table-table) args)) (lambda () (openlet obj))))))) (define (mock-hash-table . args) (let ((v (make-mock-hash-table))) (set! (v 'mock-hash-table-table) (apply #_hash-table args)) v)) (define (mock-hash-table* . args) (let ((v (make-mock-hash-table))) (set! (v 'mock-hash-table-table) (apply #_hash-table* args)) v)) (set! mock-hash-table? (lambda (obj) (and (openlet? obj) (outlet-member obj mock-hash-table-class)))) (curlet)))) #| ;; hash-table that returns a special identifier when key is not in the table (define gloomy-hash-table (openlet (sublet (*mock-hash-table* 'mock-hash-table-class) ; ideally this would be a separate (not copied) gloomy-hash-table-class 'mock-hash-table-table #f 'false (gensym) 'not-a-key #f 'hash-table-ref (lambda (obj key) (let ((val (#_hash-table-ref (obj 'mock-hash-table-table) key))) (if (eq? val (obj 'false)) #f (or val (obj 'not-a-key))))) 'hash-table-key? (lambda (obj key) (#_hash-table-ref (obj 'mock-hash-table-table) key))))) (define (hash-table-key? obj key) ((obj 'hash-table-key?) obj key)) (define* (make-gloomy-hash-table (len 511) not-a-key) (let ((ht (copy gloomy-hash-table))) (set! (ht 'mock-hash-table-table) (make-hash-table len)) (set! (ht 'not-a-key) not-a-key) ht)) |# ;;; -------------------------------------------------------------------------------- (define *mock-string* (let ((mock-string? #f)) (let ((mock-string-class (openlet (inlet 'morally-equal? (lambda (x y) (#_morally-equal? (x 'value) y)) 'reverse (lambda (obj) (#_reverse (obj 'value))) 'object->string (lambda* (obj (w #t)) (if (eq? w :readable) "*mock-string*" "#")) 'arity (lambda (obj) (#_arity (obj 'value))) 'make-iterator (lambda (obj) (#_make-iterator (obj 'value))) 'let-ref (lambda (obj i) (#_string-ref (obj 'value) i)) ; these are the implicit cases 'let-set! (lambda (obj i val) (string-set! (obj 'value) i val)) 'string-length (lambda (obj) (#_length (obj 'value))) 'string-append (make-method #_string-append (lambda (obj) (obj 'value))) 'string-copy (lambda (obj) (#_copy (obj 'value))) 'string=? (make-method #_string=? (lambda (obj) (obj 'value))) 'string? (make-method #_string>? (lambda (obj) (obj 'value))) 'string<=? (make-method #_string<=? (lambda (obj) (obj 'value))) 'string>=? (make-method #_string>=? (lambda (obj) (obj 'value))) 'string-downcase (lambda (obj) (#_string-downcase (obj 'value))) 'string-upcase (lambda (obj) (#_string-upcase (obj 'value))) 'string->symbol (lambda (obj) (#_string->symbol (obj 'value))) 'symbol (lambda (obj) (#_symbol (obj 'value))) 'gensym (lambda (obj) (#_gensym (obj 'value))) 'make-keyword (lambda (obj) (#_make-keyword (obj 'value))) 'open-input-string (lambda (obj) (#_open-input-string (obj 'value))) 'call-with-input-string (lambda (obj f) (#_call-with-input-string (obj 'value) f)) 'with-input-from-string (lambda (obj f) (#_with-input-from-string (obj 'value) f)) 'directory? (lambda (obj) (#_directory? (obj 'value))) 'file-exists? (lambda (obj) (#_file-exists? (obj 'value))) 'getenv (lambda (obj) (#_getenv (obj 'value))) 'delete-file (lambda (obj) (#_delete-file (obj 'value))) 'system (lambda* (obj cap) (#_system (obj 'value) cap)) '->byte-vector (lambda (obj) (#_->byte-vector (obj 'value))) ; this is in-place! 'load (lambda* (obj (e (curlet))) (#_load (obj 'value) e)) 'eval-string (lambda* (obj (e (curlet))) (#_eval-string (obj 'value) e)) 'char-position (make-method #_char-position (lambda (obj) (obj 'value))) 'format (make-method #_format (lambda (obj) (obj 'value))) 'string-fill! (lambda* (obj val (start 0) end) (if (mock-string? obj) (#_string-fill! (obj 'value) val start (or end (#_string-length (obj 'value)))) (error 'wrong-type-arg "string-fill! ~S ~S ~S ~S" obj val start end))) 'fill! (lambda (obj val) (if (mock-string? obj) (#_fill! (obj 'value) val) (error 'wrong-type-arg "fill! ~S ~S" obj val))) 'copy (lambda* (obj . args) (if (mock-string? obj) (apply #_copy (obj 'value) args) (error 'wrong-type-arg "copy ~S ~S" obj args))) 'substring (lambda (obj . args) (if (mock-string? obj) (apply #_substring (obj 'value) args) (error 'wrong-type-arg "substring ~S ~S" obj args))) 'string->number (lambda* (obj (r 10)) (if (mock-string? obj) (#_string->number (obj 'value) r) (error 'wrong-type-arg "string->number ~S ~S" obj r))) 'write-string (lambda (obj . args) (if (mock-string? obj) (apply #_write-string (obj 'value) args) (error 'wrong-type-arg "write-string ~S ~S" obj args))) 'string-position (lambda* (s1 s2 (start 0)) (if (mock-string? s1) (#_string-position (s1 'value) s2 start) (if (mock-string? s2) (#_string-position s1 (s2 'value) start) (error 'wrong-type-arg "write-string ~S ~S ~S" s1 s2 start)))) 'string-ref (lambda (obj i) (if (mock-string? obj) (#_string-ref (obj 'value) i) (error 'wrong-type-arg "string-ref ~S ~S" obj i))) 'string-set! (lambda (obj i val) (if (mock-string? obj) (#_string-set! (obj 'value) i val) (error 'wrong-type-arg "string-set! ~S ~S ~S" obj i val))) (reader-cond ((not (provided? 'pure-s7)) 'string->list (make-method #_string->list (lambda (obj) (obj 'value))) 'string-ci=? (make-method #_string-ci=? (lambda (obj) (obj 'value))) 'string-ci? (make-method #_string-ci>? (lambda (obj) (obj 'value))) 'string-ci<=? (make-method #_string-ci<=? (lambda (obj) (obj 'value))) 'string-ci>=? (make-method #_string-ci>=? (lambda (obj) (obj 'value))))) 'string? (lambda (obj) #t) 'values (lambda (obj . args) (obj 'value)) 'length (lambda (obj) (#_string-length (obj 'value))) 'append (make-method #_append (lambda (obj) (obj 'value))) 'class-name 'mock-string)))) (define* (make-mock-string len (init #\null)) (openlet (sublet mock-string-class 'value (#_make-string len init) 'object->string mock->string))) (define (mock-string . args) (let ((v (make-mock-string 0))) (set! (v 'value) (if (string? (car args)) (car args) (apply #_string args))) v)) (set! mock-string? (lambda (obj) (and (openlet? obj) (outlet-member obj mock-string-class)))) (curlet)))) #| ;; string that is always the current time of day (require libc.scm) (define time-string (let ((daytime (lambda args (with-let (sublet *libc*) (let ((timestr (make-string 64))) (let ((len (strftime timestr 64 "%a %d-%b-%Y %H:%M %Z" (localtime (time.make (time (c-pointer 0))))))) (substring timestr 0 len))))))) (openlet (sublet (*mock-string* 'mock-string-class) ; the mock-string isn't really needed here 'let-ref-fallback daytime 'object->string daytime)))) ;; similarly ("JIT data"): (define ? (openlet (inlet 'object->string (lambda (obj . args) (apply #_object->string (owlet) args))))) |# ;;; -------------------------------------------------------------------------------- (define *mock-char* (let ((mock-char? #f)) (let ((mock-char-class (openlet (inlet 'morally-equal? (lambda (x y) (#_morally-equal? (x 'value) y)) 'char-upcase (lambda (obj) (#_char-upcase (obj 'value))) 'char-downcase (lambda (obj) (#_char-downcase (obj 'value))) 'char->integer (lambda (obj) (#_char->integer (obj 'value))) 'char-upper-case? (lambda (obj) (#_char-upper-case? (obj 'value))) 'char-lower-case? (lambda (obj) (#_char-lower-case? (obj 'value))) 'char-alphabetic? (lambda (obj) (#_char-alphabetic? (obj 'value))) 'char-numeric? (lambda (obj) (#_char-numeric? (obj 'value))) 'char-whitespace? (lambda (obj) (#_char-whitespace? (obj 'value))) 'char=? (make-method #_char=? (lambda (obj) (obj 'value))) 'char? (make-method #_char>? (lambda (obj) (obj 'value))) 'char<=? (make-method #_char<=? (lambda (obj) (obj 'value))) 'char>=? (make-method #_char>=? (lambda (obj) (obj 'value))) 'char-ci=? (make-method #_char-ci=? (lambda (obj) (obj 'value))) 'char-ci? (make-method #_char-ci>? (lambda (obj) (obj 'value))) 'char-ci<=? (make-method #_char-ci<=? (lambda (obj) (obj 'value))) 'char-ci>=? (make-method #_char-ci>=? (lambda (obj) (obj 'value))) 'string (make-method #_string (lambda (obj) (obj 'value))) 'object->string (lambda* (obj (w #t)) (if (eq? w :readable) "*mock-char*" "#")) 'arity (lambda (obj) (#_arity (obj 'value))) 'format (make-method #_format (lambda (obj) (obj 'value))) 'make-string (make-method #_make-string (lambda (obj) (obj 'value))) 'char-position (make-method #_char-position (lambda (obj) (obj 'value))) 'write-char (lambda (obj . args) (if (mock-char? obj) (apply #_write-char (obj 'value) args) (error 'wrong-type-arg "write-char: ~S ~S" obj args))) 'string-set! (lambda (obj ind val) (if (and (string? obj) (integer? ind)) (#_string-set! obj ind (val 'value)) (error 'wrong-type-arg "string-set! ~S ~S ~S" obj ind val))) 'copy (lambda (obj . args) (if (mock-char? obj) (obj 'value) (error 'wrong-type-arg "copy: ~S ~S" obj args))) 'char? (lambda (obj) #t) 'class-name 'mock-char 'length (lambda (obj) #f) 'values (lambda (obj . args) (obj 'value)))))) (define (mock-char c) (if (and (char? c) (not (let? c))) (openlet (sublet (*mock-char* 'mock-char-class) 'value c 'object->string mock->string)) (error 'wrong-type-arg "mock-char ~S is not a char" c))) (set! mock-char? (lambda (obj) (and (openlet? obj) (outlet-member obj mock-char-class)))) (curlet)))) #| ;;; eventually I'll conjure up unichars like (define lambda (byte-vector #xce #xbb)) via mock-char, ;;; then combine those into unistring via mock-string ;;; ;;; (string-length obj)->g_utf8_strlen etc ;;; (g_unichar_isalpha (g_utf8_get_char (byte-vector #xce #xbb))) -> #t ;;; (g_utf8_strlen (byte-vector #xce #xbb #xce #xba) 10) -> 2 ;;; (g_utf8_normalize (byte-vector #xce #xbb #xce #xba) 4 G_NORMALIZE_DEFAULT) ;;; but the ones that return gunichar (toupper) currently don't return a byte-vector or a string ;;; maybe gunichar->byte-vector? ;;; need glib.scm, or unicode.scm to load the stuff |# ;;; -------------------------------------------------------------------------------- (define *mock-number* (let ((mock-number? #f)) (define* (range-method-1 func arg start end) (if (not end) (func arg (start 'value)) (if (not (let? start)) (func arg start (end 'value)) (apply func arg (start 'value) end ())))) (define* (range-method-2 func arg1 arg2 start end) (if (not end) (func arg1 arg2 (start 'value)) (if (not (let? start)) (func arg1 arg2 start (end 'value)) (apply func arg1 arg2 (start 'value) end ())))) (let ((mock-number-class (openlet (inlet 'morally-equal? (lambda (x y) (#_morally-equal? (x 'value) y)) 'object->string (lambda* (obj (w #t)) (if (eq? w :readable) "*mock-number*" "#")) 'arity (lambda (obj) (#_arity (obj 'value))) 'real-part (lambda (obj) (#_real-part (obj 'value))) 'imag-part (lambda (obj) (#_imag-part (obj 'value))) 'numerator (lambda (obj) (#_numerator (obj 'value))) 'denominator (lambda (obj) (#_denominator (obj 'value))) 'even? (lambda (obj) (#_even? (obj 'value))) 'odd? (lambda (obj) (#_odd? (obj 'value))) 'zero? (lambda (obj) (#_zero? (obj 'value))) 'positive? (lambda (obj) (#_positive? (obj 'value))) 'negative? (lambda (obj) (#_negative? (obj 'value))) 'infinite? (lambda (obj) (#_infinite? (obj 'value))) 'nan? (lambda (obj) (#_nan? (obj 'value))) (reader-cond ((not (provided? 'pure-s7)) 'make-polar (make-method #_make-polar (lambda (obj) (obj 'value))) 'make-rectangular (make-method #_complex (lambda (obj) (obj 'value))))) 'complex (make-method #_complex (lambda (obj) (obj 'value))) 'random-state (make-method #_random-state (lambda (obj) (obj 'value))) 'magnitude (lambda (obj) (#_magnitude (obj 'value))) 'angle (lambda (obj) (#_angle (obj 'value))) 'rationalize (make-method #_rationalize (lambda (obj) (obj 'value))) 'abs (lambda (obj) (#_abs (obj 'value))) 'exp (lambda (obj) (#_exp (obj 'value))) 'log (make-method #_log (lambda (obj) (obj 'value))) 'sin (lambda (obj) (#_sin (obj 'value))) 'cos (lambda (obj) (#_cos (obj 'value))) 'tan (lambda (obj) (#_tan (obj 'value))) 'asin (lambda (obj) (#_asin (obj 'value))) 'acos (lambda (obj) (#_acos (obj 'value))) 'atan (make-method #_atan (lambda (obj) (obj 'value))) 'sinh (lambda (obj) (#_sinh (obj 'value))) 'cosh (lambda (obj) (#_cosh (obj 'value))) 'tanh (lambda (obj) (#_tanh (obj 'value))) 'asinh (lambda (obj) (#_asinh (obj 'value))) 'acosh (lambda (obj) (#_acosh (obj 'value))) 'atanh (lambda (obj) (#_atanh (obj 'value))) 'sqrt (lambda (obj) (#_sqrt (obj 'value))) 'expt (make-method #_expt (lambda (obj) (obj 'value))) 'floor (lambda (obj) (#_floor (obj 'value))) 'ceiling (lambda (obj) (#_ceiling (obj 'value))) 'truncate (lambda (obj) (#_truncate (obj 'value))) 'round (lambda (obj) (#_round (obj 'value))) 'integer->char (lambda (obj) (#_integer->char (obj 'value))) 'inexact->exact (lambda (obj) (#_inexact->exact (obj 'value))) 'exact->inexact (lambda (obj) (#_exact->inexact (obj 'value))) 'integer-length (lambda (obj) (#_integer-length (obj 'value))) 'integer-decode-float (lambda (obj) (#_integer-decode-float (obj 'value))) 'number? (lambda (obj) (#_number? (obj 'value))) ; why not #t? currently (mock-number (mock-number ...)) is an error 'integer? (lambda (obj) (#_integer? (obj 'value))) 'real? (lambda (obj) (#_real? (obj 'value))) 'complex? (lambda (obj) (#_complex? (obj 'value))) 'rational? (lambda (obj) (#_rational? (obj 'value))) 'exact? (lambda (obj) (#_exact? (obj 'value))) 'inexact? (lambda (obj) (#_inexact? (obj 'value))) 'ash (make-method #_ash (lambda (obj) (obj 'value))) 'logbit? (make-method #_logbit? (lambda (obj) (obj 'value))) 'number->string (make-method #_number->string (lambda (obj) (obj 'value))) 'random (make-method #_random (lambda (obj) (obj 'value))) 'quotient (make-method #_quotient (lambda (obj) (obj 'value))) 'remainder (make-method #_remainder (lambda (obj) (obj 'value))) 'modulo (make-method #_modulo (lambda (obj) (obj 'value))) 'lognot (lambda (obj) (#_lognot (obj 'value))) 'logior (make-method #_logior (lambda (obj) (obj 'value))) 'logxor (make-method #_logxor (lambda (obj) (obj 'value))) 'logand (make-method #_logand (lambda (obj) (obj 'value))) ;; any object that has lcm or gcd also needs rational? 'lcm (make-method #_lcm (lambda (obj) (obj 'value))) 'gcd (make-method #_gcd (lambda (obj) (obj 'value))) '+ (make-method #_+ (lambda (obj) (obj 'value))) '- (make-method #_- (lambda (obj) (obj 'value))) '* (make-method #_* (lambda (obj) (obj 'value))) '/ (make-method #_/ (lambda (obj) (obj 'value))) ;; any object that has min or max also needs real? 'max (make-method #_max (lambda (obj) (obj 'value))) 'min (make-method #_min (lambda (obj) (obj 'value))) '= (make-method #_= (lambda (obj) (obj 'value))) '< (make-method #_< (lambda (obj) (obj 'value))) '> (make-method #_> (lambda (obj) (obj 'value))) '<= (make-method #_<= (lambda (obj) (obj 'value))) '>= (make-method #_>= (lambda (obj) (obj 'value))) 'write-byte (lambda (byte . port) (apply #_write-byte (byte 'value) port)) 'make-list (lambda (ind . args) (apply #_make-list (ind 'value) args)) 'make-vector (make-method #_make-vector (lambda (obj) (obj 'value))) 'make-float-vector(make-method #_make-float-vector (lambda (obj) (obj 'value))) 'make-hash-table (lambda (ind . args) (apply #_make-hash-table (ind 'value) args)) 'make-byte-vector (make-method #_make-byte-vector (lambda (obj) (obj 'value))) 'byte-vector (make-method #_byte-vector (lambda (obj) (obj 'value))) 'format (make-method #_format (lambda (obj) (obj 'value))) 'make-string (lambda (ind . args) (if (mock-number? ind) (apply #_make-string (ind 'value) args) (error 'wrong-type-arg "make-string ~S ~S" ind args))) 'string-ref (lambda (str ind) (if (string? str) (#_string-ref str (ind 'value)) (error 'wrong-type-arg "make-string ~S ~S" str ind))) 'string-set! (lambda (str ind val) (if (string? str) (#_string-set! str (ind 'value) val) (error 'wrong-type-arg "string-set! ~S ~S ~S" str ind val))) 'string->number (lambda (str radix) (if (string? str) (#_string->number str (radix 'value)) (error 'wrong-type-arg "string->number ~S ~S" str radix))) 'list-ref (lambda (lst ind) (if (pair? lst) (#_list-ref lst (ind 'value)) (error 'wrong-type-arg "list-ref ~S ~S" lst ind))) 'list-set! (lambda (lst ind val) (if (pair? lst) (#_list-set! lst (ind 'value) val) (error 'wrong-type-arg "list-set! ~S ~S ~S" lst ind val))) 'list-tail (lambda (lst ind) (if (pair? lst) (#_list-tail lst (ind 'value)) (error 'wrong-type-arg "list-tail ~S ~S" ind args))) 'vector-ref (lambda (vec ind) (if (vector? vec) (#_vector-ref vec (ind 'value)) (error 'wrong-type-arg "vector-ref ~S ~S" vec ind))) 'vector-set! (lambda (vec ind val) (if (vector? vec) (#_vector-set! vec (ind 'value) val) (error 'wrong-type-arg "vector-set! ~S ~S ~S" vec ind val))) 'make-shared-vector (lambda (obj dims offset) (if (and (vector? obj) (pair? dims)) (#_make-shared-vector obj dims (offset 'value)) (error 'wrong-type-arg "make-shared-vector ~S ~S ~S" obj dims offset))) 'vector->list (lambda* (vec start end) (if (vector? vec) ;; when there are two args, either might have triggered this method call, ;; if (not (let? end)) or (let? start), start must be a mock-number ;; and if (not (let? start)), end must be a mock-number, but ;; if (let? start) and (let? end), end might be anything (range-method-1 #_vector->list vec start end) (error 'wrong-type-arg "vector->list ~S ~S ~S" vec start end))) 'vector-fill! (lambda* (vec c start end) (if (vector? vec) (range-method-2 #_vector-fill! vec c start end) (error 'wrong-type-arg "vector-fill! ~S ~S ~S ~S" vec c start end))) 'substring (lambda* (str start end) (if (string? str) (range-method-1 #_substring start end) (error 'wrong-type-arg "substring ~S ~S ~S" str start end))) 'string-fill! (lambda* (str c start end) (if (and (string? str) (char? c)) (range-method-2 #_string-fill! str c start end) (error 'wrong-type-arg "string-fill! ~S ~S ~S ~S" str c start end))) 'string->list (lambda* (str start end) (if (string? str) (range-method-1 #_string->list str start end) (error 'wrong-type-arg "string->list ~S ~S ~S" str start end))) 'write-string (lambda* (str port start end) (if (and (string? str) (output-port? port)) (range-method-2 #_write-string str port start end) (error 'wrong-type-arg "write-string ~S ~S ~S ~S" str port start end))) 'read-string (lambda* (k (port (current-input-port))) (#_read-string (k 'value) port)) 'copy (lambda* (obj dest start end) (if (mock-number? obj) (obj 'value) (if (or (mock-number? start) (mock-number? end)) (range-method-2 #_copy obj dest start end) (error 'wrong-type-arg "copy ~S ~S ~S ~S" obj dest start end)))) 'length (lambda (obj) #f) 'number? (lambda (obj) #t) 'values (lambda (obj . args) (obj 'value)) 'class-name 'mock-number)))) (define (mock-number x) (if (and (number? x) (not (let? x))) (openlet (sublet (*mock-number* 'mock-number-class) 'value x 'object->string mock->string)) (error 'wrong-type-arg "mock-number ~S is not a number" x))) (set! mock-number? (lambda (obj) (and (openlet? obj) (outlet-member obj mock-number-class)))) (curlet)))) #| ;;; fuzzy number (define fuzzy-number (let ((fuzz (lambda (fx) (#_* fx (#_- 1.05 (#_random .1)))))) (lambda (fx) (openlet (sublet (*mock-number* 'mock-number-class) 'let-ref-fallback (lambda (obj sym) (fuzz fx)) 'object->string (lambda (obj . args) (#_number->string (fuzz fx)))))))) ;;; interval arithmetic ;;; ;;; from Wikipedia: ;;; x + y = [a+c, b+d] ;;; x - y = [a-d, b-c] ;;; x × y = [min(ac, ad, bc, bd), max(ac, ad, bc, bd)] ;;; x / y = [min(a/c, a/d, b/c, b/d), max(a/c, a/d, b/c, b/d)] (define *interval* (let* ((make-interval #f) (low (lambda (z) (z 'low))) (high (lambda (z) (z 'high))) (interval-class (openlet (sublet (*mock-number* 'mock-number-class) '+ (lambda args (let ((lo 0) (hi 0)) (for-each (lambda (z) (if (let? z) (begin (set! lo (+ lo (low z))) (set! hi (+ hi (high z)))) (begin (set! lo (+ lo z)) (set! hi (+ hi z))))) args) (make-interval lo hi))) '* (lambda args (let ((lo 1) (hi 1)) (for-each (lambda (z) (let ((zlo (if (let? z) (low z) z)) (zhi (if (let? z) (high z) z))) (let ((ac (* lo zlo)) (ad (* lo zhi)) (bc (* hi zlo)) (bd (* hi zhi))) (set! lo (min ac ad bc bd)) (set! hi (max ac ad bc bd))))) args) (make-interval lo hi))) '- (lambda args (let ((z (car args))) (if (null? (cdr args)) ; negate (must be let? else how did we get here?) (make-interval (- (high z)) (- (low z))) (let ((lo (low z)) (hi (high z))) (for-each (lambda (z) (if (let? z) (begin (set! lo (- lo (high z))) (set! hi (- hi (low z)))) (begin (set! lo (- lo z)) (set! hi (- hi z))))) (cdr args)) (make-interval lo hi))))) '/ (lambda args (let ((z (car args))) (if (null? (cdr args)) ; invert (make-interval (/ (high z)) (/ (low z))) (let ((lo (low z)) (hi (high z))) (for-each (lambda (z) (let ((zlo (if (let? z) (low z) z)) (zhi (if (let? z) (high z) z))) (let ((ac (/ lo zlo)) (ad (/ lo zhi)) (bc (/ hi zlo)) (bd (/ hi zhi))) (set! lo (min ac ad bc bd)) (set! hi (max ac ad bc bd))))) (cdr args)) (make-interval lo hi))))) 'abs (lambda (z) (if (positive? (low z)) (make-interval (low z) (high z)) (if (negative? (high z)) (make-interval (abs (high z)) (abs (low z))) (make-interval 0 (max (abs (low z)) (abs (high z))))))) 'object->string (lambda (obj . args) (format #f "#" (low obj) (high obj))) )))) (set! make-interval (lambda (low high) (if (> low high) (format *stderr* "~A ~A~%" low high)) (openlet (sublet interval-class 'low low 'high high)))) (curlet))) (define x ((*interval* 'make-interval) 3.0 4.0)) |# ;;; -------------------------------------------------------------------------------- (define *mock-pair* (let ((mock-pair? #f)) (let ((mock-pair-class (openlet (inlet 'morally-equal? (lambda (x y) (#_morally-equal? (x 'value) y)) 'pair-line-number (lambda (obj) (#_pair-line-number (obj 'value))) 'list->string (lambda (obj) (#_list->string (obj 'value))) 'object->string (lambda* (obj (w #t)) (if (eq? w :readable) "*mock-pair*" "#")) 'list? (lambda (obj) (#_list? (obj 'value))) 'car (lambda (obj) (#_car (obj 'value))) 'cdr (lambda (obj) (#_cdr (obj 'value))) 'set-car! (lambda (obj val) (#_set-car! (obj 'value) val)) 'set-cdr! (lambda (obj val) (#_set-cdr! (obj 'value) val)) 'caar (lambda (obj) (#_caar (obj 'value))) 'cadr (lambda (obj) (#_cadr (obj 'value))) 'cdar (lambda (obj) (#_cdar (obj 'value))) 'cddr (lambda (obj) (#_cddr (obj 'value))) 'caaar (lambda (obj) (#_caaar (obj 'value))) 'caadr (lambda (obj) (#_caadr (obj 'value))) 'cadar (lambda (obj) (#_cadar (obj 'value))) 'cdaar (lambda (obj) (#_cdaar (obj 'value))) 'caddr (lambda (obj) (#_caddr (obj 'value))) 'cdddr (lambda (obj) (#_cdddr (obj 'value))) 'cdadr (lambda (obj) (#_cdadr (obj 'value))) 'cddar (lambda (obj) (#_cddar (obj 'value))) 'caaaar (lambda (obj) (#_caaaar (obj 'value))) 'caaadr (lambda (obj) (#_caaadr (obj 'value))) 'caadar (lambda (obj) (#_caadar (obj 'value))) 'cadaar (lambda (obj) (#_cadaar (obj 'value))) 'caaddr (lambda (obj) (#_caaddr (obj 'value))) 'cadddr (lambda (obj) (#_cadddr (obj 'value))) 'cadadr (lambda (obj) (#_cadadr (obj 'value))) 'caddar (lambda (obj) (#_caddar (obj 'value))) 'cdaaar (lambda (obj) (#_cdaaar (obj 'value))) 'cdaadr (lambda (obj) (#_cdaadr (obj 'value))) 'cdadar (lambda (obj) (#_cdadar (obj 'value))) 'cddaar (lambda (obj) (#_cddaar (obj 'value))) 'cdaddr (lambda (obj) (#_cdaddr (obj 'value))) 'cddddr (lambda (obj) (#_cddddr (obj 'value))) 'cddadr (lambda (obj) (#_cddadr (obj 'value))) 'cdddar (lambda (obj) (#_cdddar (obj 'value))) 'assoc (lambda (val obj . args) (apply #_assoc val (obj 'value) args)) (reader-cond ((not (provided? 'pure-s7)) 'assq (lambda (val obj) (#_assq val (obj 'value))) 'assv (lambda (val obj) (#_assv val (obj 'value))) 'memq (lambda (val obj) (#_memq val (obj 'value))) 'memv (lambda (val obj) (#_memv val (obj 'value))))) 'member (lambda (val obj . args) (apply #_member val (obj 'value) args)) 'let-ref (lambda (obj ind) (coverlet obj) (let ((val (#_list-ref (obj 'value) ind))) (openlet obj) val)) 'let-set! (lambda (obj ind val) (coverlet obj) (#_list-set! (obj 'value) ind val) (openlet obj) val) 'arity (lambda (obj) (#_arity (obj 'value))) 'fill! (lambda (obj val) (#_fill! (obj 'value) val)) 'reverse (lambda (obj) (#_reverse (obj 'value))) 'reverse! (lambda (obj) (set! (obj 'value) (#_reverse (obj 'value)))) 'sort! (lambda (obj f) (#_sort! (obj 'value) f)) 'make-iterator (lambda (obj) (#_make-iterator (obj 'value))) 'eval (lambda (f obj) (#_eval (obj 'value))) 'list->vector (lambda (obj) (#_list->vector (obj 'value))) 'list-tail (lambda (obj . args) (if (mock-pair? obj) (apply #_list-tail (obj 'value) args) (error 'wrong-type-arg "list-tail ~S ~S" obj args))) 'copy (lambda (obj . args) (if (mock-pair? obj) (apply #_copy (obj 'value) args) (error 'wrong-type-arg "copy ~S ~S" obj args))) 'make-shared-vector (lambda (obj dims . args) (if (mock-pair? dims) (apply #_make-shared-vector obj (dims 'value) args) (error 'wrong-type-arg "make-shared-vector ~S ~S ~S" obj dims args))) 'make-vector (lambda (obj dims . args) (if (mock-pair? dims) (apply #_make-vector obj (dims 'value) args) (error 'wrong-type-arg "make-vector ~S ~S ~S" obj dims args))) 'append (make-method #_append (lambda (obj) (obj 'value))) 'list-ref (lambda (obj ind) (if (mock-pair? obj) (#_list-ref (obj 'value) ind) (error 'wrong-type-arg "list-ref ~S ~S" obj ind))) 'list-set! (lambda (obj ind val) (if (mock-pair? obj) (#_list-set! (obj 'value) ind val) (error 'wrong-type-arg "list-set! ~S ~S ~S" obj ind val))) 'pair? (lambda (obj) #t) 'length (lambda (obj) (#_length (obj 'value))) 'values (lambda (obj . args) (obj 'value)) 'append (make-method #_append (lambda (obj) (obj 'value))) 'class-name 'mock-pair)))) (define (mock-pair . args) (openlet (sublet (*mock-pair* 'mock-pair-class) 'value (copy args) 'object->string mock->string))) (set! mock-pair? (lambda (obj) (and (openlet? obj) (outlet-member obj mock-pair-class)))) (curlet)))) #| (let ((immutable-list-class (sublet (*mock-pair* 'mock-pair-class) 'object->string mock->string 'let-set! (lambda (obj i val) (set! (obj 'value) (append (copy (obj 'value) (make-list (+ i 1))) (list-tail (obj 'value) (+ i 1)))) (list-set! (obj 'value) i val)) 'list-set! (lambda (obj i val) (set! (obj 'value) (append (copy (obj 'value) (make-list (+ i 1))) (list-tail (obj 'value) (+ i 1)))) (list-set! (obj 'value) i val)) 'set-car! (lambda (obj val) (set! (obj 'value) (cons val (cdr (obj 'value))))) 'set-cdr! (lambda (obj val) (set! (obj 'value) (cons (car (obj 'value)) val))) 'fill! (lambda (obj val) (set! (obj 'value) (fill! (copy (obj 'value)) val))) 'reverse! (lambda (obj) (set! (obj 'value) (reverse (obj 'value)))) 'sort! (lambda (obj func) (set! (obj 'value) (sort! (copy (obj 'value)) func)))))) (define (immutable-list lst) (openlet (sublet immutable-list-class 'value lst)))) |# ;;; since a mock-pair prints itself as if a list, you can get some strange printout results: ;;; (cons 'a ((*mock-pair* 'mock-pair) 'b 'c)) -> '(a . (b c)) ;;; -------------------------------------------------------------------------------- (define *mock-symbol* (let ((mock-symbol-class (openlet (inlet 'object->string (lambda* (obj (w #t)) (if (eq? w :readable) "*mock-symbol*" "#")) 'morally-equal? (lambda (x y) (#_morally-equal? (x 'value) y)) 'gensym? (lambda (obj) (#_gensym? (obj 'value))) 'symbol->string (lambda (obj) (#_symbol->string (obj 'value))) 'symbol->value (lambda (obj . args) (apply #_symbol->value (obj 'value) args)) 'symbol->dynamic-value (lambda (obj) (#_symbol->dynamic-value (obj 'value))) 'symbol-access (lambda (obj . args) (apply #_symbol-access (obj 'value) args)) 'provided? (lambda (obj) (#_provided? (obj 'value))) 'provide (lambda (obj) (#_provide (obj 'value))) 'defined? (lambda (obj) (#_defined? (obj 'value))) 'symbol->keyword (lambda (obj) (#_symbol->keyword (obj 'value))) 'keyword? (lambda (obj) (#_keyword? (obj 'value))) 'keyword->symbol (lambda (obj) (#_keyword->symbol (obj 'value))) 'format (lambda (str s . args) (#_symbol->string s)) 'symbol? (lambda (obj) #t) 'class-name 'mock-symbol 'values (lambda (obj . args) (obj 'value)) )))) (define (mock-symbol s) (if (and (symbol? s) (not (let? s))) (openlet (sublet (*mock-symbol* 'mock-symbol-class) 'value s 'object->string mock->string)) (error 'wrong-type-arg "mock-symbol ~S is not a symbol" s))) (define (mock-symbol? obj) (and (openlet? obj) (outlet-member obj mock-symbol-class))) (curlet))) ;;; -------------------------------------------------------------------------------- (define *mock-port* (let ((mock-port? #f)) (let ((mock-port-class (openlet (inlet 'port? (lambda (obj) #t) 'morally-equal? (lambda (x y) (#_morally-equal? (x 'value) y)) 'close-input-port (lambda (obj) (#_close-input-port (obj 'value))) 'close-output-port (lambda (obj) (#_close-output-port (obj 'value))) 'flush-output-port (lambda (obj) (#_flush-output-port (obj 'value))) 'get-output-string (lambda (obj) (#_get-output-string (obj 'value))) 'newline (lambda (obj) (#_newline (obj 'value))) 'write (lambda (x obj) (#_write x (obj 'value))) 'display (lambda (x obj) (#_display x (obj 'value))) 'read-char (lambda (obj) (#_read-char (obj 'value))) 'peek-char (lambda (obj) (#_peek-char (obj 'value))) 'read-byte (lambda (obj) (#_read-byte (obj 'value))) 'read-line (lambda (obj . args) (apply #_read-line (obj 'value) args)) 'read (lambda (obj) (#_read (obj 'value))) 'input-port? (lambda (obj) (#_input-port? (obj 'value))) 'output-port? (lambda (obj) (#_output-port? (obj 'value))) 'port-closed? (lambda (obj) (#_port-closed? (obj 'value))) 'char-ready? (lambda (obj) (#_char-ready? (obj 'value))) 'port-line-number (lambda (obj) (#_port-line-number (obj 'value))) 'port-filename (lambda (obj) (#_port-filename (obj 'value))) 'object->string (lambda* (obj (w #t)) (if (eq? w :readable) "*mock-port*" "#")) 'format (make-method #_format (lambda (obj) (obj 'value))) 'set-current-output-port (lambda (obj) (#_set-current-output-port (obj 'value))) 'set-current-input-port (lambda (obj) (#_set-current-input-port (obj 'value))) 'set-current-error-port (lambda (obj) (#_set-current-error-port (obj 'value))) 'write-char (lambda (c obj) (if (mock-port? obj) (#_write-char c (obj 'value)) (error 'wrong-type-arg "write-char ~S ~S" c obj))) 'write-string (lambda (s obj . args) (if (mock-port? obj) (apply #_write-string s (obj 'value) args) (error 'wrong-type-arg "write-string ~S ~S ~S" s obj args))) 'write-byte (lambda (b obj) (if (mock-port? obj) (#_write-byte b (obj 'value)) (error 'wrong-type-arg "write-byte ~S ~S" b obj))) 'read-string (lambda (k obj) (if (mock-port? obj) (#_read-string k (obj 'value)) (error 'wrong-type-arg "read-string ~S ~S" k obj))) 'values (lambda (obj . args) (obj 'value)) 'class-name 'mock-port )))) (define (mock-port port) (if (and (or (input-port? port) (output-port? port)) (not (let? port))) (openlet (sublet (*mock-port* 'mock-port-class) 'value port 'object->string mock->string)) (error 'wrong-type-arg "mock-port ~S is not a port" port))) (set! mock-port? (lambda (obj) (and (openlet? obj) (outlet-member obj mock-port-class)))) (curlet)))) ;;; sublet of any of these needs to include the value field or a let-ref-fallback #| (require libc.scm) (define *input-file* (let ((file-write-date (lambda (file) (with-let (sublet *libc* :file file) (let ((buf (stat.make))) (stat file buf) (let ((date (stat.st_mtime buf))) (free buf) date))))) (file-size (lambda (file) (with-let (sublet *libc* :file file) (let ((buf (stat.make))) (stat file buf) (let ((size (stat.st_size buf))) (free buf) size))))) (file-owner (lambda (file) (with-let (sublet *libc* :file file) (let ((buf (stat.make))) (stat file buf) (let ((uid (stat.st_uid buf))) (free buf) (let ((pwd (getpwuid uid))) (passwd.pw_name pwd)))))))) (openlet (sublet (*mock-port* 'mock-port-class) 'value #f 'length (lambda (obj) (file-size (obj 'file-name))) 'owner (lambda (obj) (file-owner (obj 'file-name))) 'write-date (lambda (obj) (file-write-date (obj 'file-name))))))) (define (open-a-file file) (let ((p (openlet (sublet *input-file* 'file-name file)))) (set! (p 'value) (open-input-file "oboe.snd")) p)) (define p (open-a-file "oboe.snd")) (length p) -> 101684 ((p 'owner) p) -> "bil" |# snd-16.1/edit-menu.scm0000644000076400007640000001255212616231601012731 0ustar bilbil;;; add some useful options to the Edit menu ;;; ;;; these used to be in the effects menu (provide 'snd-edit-menu.scm) (define edit-menu 1) ;;; -------- selection -> new file (define selection->new (let ((documentation "(selection-new" selection->new 8) ;pos=8 puts this in the selection section in the Edit menu ;;; -------- cut selection -> new file (define cut-selection->new (let ((documentation "(cut-selection->new) saves the selection, deletes it, then opens the saved file")) (lambda () (and (selection?) (let ((new-file-name (snd-tempnam))) (save-selection new-file-name) (delete-selection) (open-sound new-file-name)))))) (add-to-menu edit-menu "Cut selection->new" cut-selection->new 9) ;;; -------- append selection (define append-selection (let ((documentation "(append-selection) appends the current selection")) (lambda () (if (selection?) (insert-selection (framples)))))) (add-to-menu edit-menu "Append selection" append-selection 10) ;;; -------- make-stereofile (define (make-stereofile) (let* ((ofile-name (file-name)) (old-sound (selected-sound)) (nsnd (new-sound (string-append ofile-name ".stereo") 2 (srate) (sample-type) (header-type)))) (if (not nsnd) (begin (display "Could not make new sound.")(newline)) (begin (insert-sound ofile-name 0 0 nsnd 0) (insert-sound ofile-name 0 (if (> 0 (channels old-sound)) 1 0) nsnd 1))))) (add-to-menu edit-menu "Make Stereofile" make-stereofile) ;;; -------- (add-to-menu edit-menu #f #f) ;;; -------- trim front and back (goes by first or last mark) (define trim-front (let ((documentation "(trim-front) finds the first mark in each of the syncd channels and removes all samples before it")) (lambda () (let ((snc (sync))) (define (trim-front-one-channel snd chn) (if (< (length (marks snd chn)) 1) (status-report "trim-front needs a mark" snd) (delete-samples 0 (mark-sample (car (marks snd chn))) snd chn))) (if (> snc 0) (apply map (lambda (snd chn) (if (= (sync snd) snc) (trim-front-one-channel snd chn))) (all-chans)) (trim-front-one-channel (or (selected-sound) (car (sounds))) (or (selected-channel) 0))))))) (add-to-menu edit-menu "Trim front" trim-front) (define trim-back (let ((documentation "(trim-back) finds the last mark in each of the syncd channels and removes all samples after it")) (lambda () (let ((snc (sync))) (define (trim-back-one-channel snd chn) (if (< (length (marks snd chn)) 1) (status-report "trim-back needs a mark" snd) (let ((endpt (mark-sample (car (reverse (marks snd chn)))))) (delete-samples (+ endpt 1) (- (framples snd chn) endpt))))) (if (> snc 0) (apply map (lambda (snd chn) (if (= (sync snd) snc) (trim-back-one-channel snd chn))) (all-chans)) (trim-back-one-channel (or (selected-sound) (car (sounds))) (or (selected-channel) 0))))))) (add-to-menu edit-menu "Trim back" trim-back) ;;; -------- crop (trims front and back) (define* (crop-one-channel snd chn) (if (< (length (marks snd chn)) 2) (status-report "crop needs start and end marks" snd) (as-one-edit (lambda () (delete-samples 0 (mark-sample (car (marks snd chn))) snd chn) (let ((endpt (mark-sample (car (reverse (marks snd chn)))))) (delete-samples (+ endpt 1) (- (framples snd chn) endpt)))) "crop-one-channel"))) (define crop (let ((documentation "(crop) finds the first and last marks in each of the syncd channels and removes all samples outside them")) (lambda () (let ((snc (sync))) (if (> snc 0) (apply map (lambda (snd chn) (if (= (sync snd) snc) (crop-one-channel snd chn))) (all-chans)) (crop-one-channel (or (selected-sound) (car (sounds))) (or (selected-channel) 0))))))) (add-to-menu edit-menu "Crop" crop) ;;; -------- add these to the Edit menu, if possible (if (and (not (provided? 'snd-gtk)) (provided? 'xm)) (with-let (sublet *motif*) (let* ((edit-cascade (list-ref (menu-widgets) 2)) (edit-menu (cadr (XtGetValues edit-cascade (list XmNsubMenuId 0))))) (define (for-each-child w func) ;; (for-each-child w func) applies func to w and its descendents (func w) (if (XtIsComposite w) (for-each (lambda (n) (for-each-child n func)) (cadr (XtGetValues w (list XmNchildren 0) 1))))) (XtAddCallback edit-cascade XmNcascadingCallback (lambda (w c i) (for-each-child edit-menu (lambda (child) (if (or (string=? (XtName child) "Selection->new") (string=? (XtName child) "Cut selection->new") (string=? (XtName child) "Append selection")) (XtSetSensitive child (selection?)) (if (string=? (XtName child) "Crop") (XtSetSensitive child (and (selected-sound) (> (length (marks (selected-sound) (selected-channel))) 1))) (if (or (string=? (XtName child) "Trim front") (string=? (XtName child) "Trim back")) (XtSetSensitive child (and (selected-sound) (>= (length (marks (selected-sound) (selected-channel))) 1)))))))))))) ) snd-16.1/edit123.scm0000644000076400007640000003413312622705137012223 0ustar bilbil;;; easy edit ;;; ;;;version 0.8 ;;;keybindings and functions to make sound editing as easy and convenient ;;;as pressing 1 2 3 ;;;1 set mark ;;;2 move mark backward ;;;3 move mark backward by a fraction ;;;C-2 move mark forward ;;;C-3 move mark forward by a fraction ;;;p set mark fixed and play (important: you have to use this key to finalize the setting of the start mark ) ;;;f fade ;;;c crop delete the part before and after the marks ;;;C-1 toggles start and end status ;;; keys have multiple actions assigned depending on the status of the editing process ;;; p is a customized playfunction ;;; P (thats Shift P) plays the end of the track and sets the system for setting an end mark ;;; after having set the start mark pressing P (Shift-P) and then M-2 and M-3 is a good approach to quickly get to the desired area. ;;; there are some more keybindings, that i commented out. ;;; you can suit them to your taste. ;;; for a more in depth description have a look at ;;; http://www.users.startplus.de/rawdlite/sound/HOWTO_record_from_radio_to_mp3.html ;;; enjoy ;;; tom@tomroth.de (provide 'snd-edit123.scm) (require snd-selection.scm) (define status 0) (define curpos 0) (define is-playing 0) (define open-next-file-in-directory (let ((last-file-opened #f) (current-directory #f) (current-sorted-files #f)) (define (file-from-path curfile) (let ((last-slash 0)) (do ((i 0 (+ 1 i))) ((= i (length curfile))) (if (char=? (curfile i) #\/) (set! last-slash i))) (substring curfile (+ 1 last-slash)))) (define (directory-from-path curfile) (let ((last-slash 0)) (do ((i 0 (+ 1 i))) ((= i (length curfile))) (if (char=? (curfile i) #\/) (set! last-slash i))) (substring curfile 0 last-slash))) (define (find-next-file) ;; find the next file in the sorted list, with wrap-around (let ((choose-next (not (string? last-file-opened))) (just-filename (file-from-path last-file-opened))) (call-with-exit (lambda (return) (for-each (lambda (file) (if choose-next (return file) (if (string=? file just-filename) (set! choose-next #t)))) current-sorted-files) ;; if we get here we wrapped around (car current-sorted-files))))) (define (get-current-files dir) (set! current-directory dir) (set! current-sorted-files (sort! (sound-files-in-directory dir) string (cursor) (+ (selection-position) (selection-framples)))) (begin (make-selection (cursor) (+ (cursor) (selection-framples))) (stop-playing) (eos))) (if (and (>= (cursor) (selection-position)) (<= (cursor) (+ (selection-position) (selection-framples)))) (begin (stop-playing) (eos) (make-selection (cursor) (+ (cursor) (selection-framples))))) (play (selection))) (define (backward-selection) (if (not (selection?)) (make-selection (- (cursor) 20000) (cursor))) (if (< (selection-framples) 2000) (make-selection (- (cursor) 2000) (cursor))) (if (or (< (cursor) (selection-position)) (> (cursor) (+ (selection-position) (selection-framples)))) (begin (make-selection (cursor) (- (cursor) (selection-framples))) (stop-playing) (set! (cursor) (selection-position)))) (if (and (>= (cursor) (selection-position)) (<= (cursor) (+ (selection-position) (selection-framples)))) (begin (stop-playing) (set! (cursor) (selection-position)))) (make-selection (- (cursor) (selection-framples)) (cursor) ) (play (selection))) (define (mark-start length) (select-channel 0) (if (find-mark "start") (delete-named-mark "start") ) (mark-named "start") (stop-playing) (goto-named-mark "start") (set! status 1) (make-selection (cursor) (+ (cursor) length)) (stop-playing) (key (char->integer #\t) 4) (play (selection))) (define (mark-end length) (select-channel 0) (if (find-mark "end") (delete-named-mark "end") ) (mark-named "end") (stop-playing) (goto-named-mark "end") (set! status 3) (make-selection (- (cursor) length) (cursor) ) (key (char->integer #\t) 4) (play (selection))) (define (stop-song) (set! curpos (cursor)) (stop-playing) (set! (cursor) curpos)) (define (play-song) (stop-playing) (select-channel 0) ;(if (eq? status 1)(set! status 2)) ;(if (eq? status 3)(set! status 0)) (let ((old-tracking (with-tracking-cursor))) (set! (with-tracking-cursor) #t) (hook-push stop-playing-hook (lambda (hook) (set! (with-tracking-cursor) old-tracking) (set! (channel-style (hook 'snd)) channels-superimposed)))) (play (selected-sound) :start (cursor))) (define (play-end) (key (char->integer #\>) 1) (stop-playing) (key (char->integer #\t) 4) (set! status 2) (set! (cursor) (- (cursor) 100000)) (play (selected-sound) :start (cursor)) ) (define (toggle-play) (lambda () (case is-playing ((1) (stop-playing)) ((0) (play)) ))) ;double-selection (define (double-selection) (set! (cursor) (selection-position)) (make-selection (selection-position) (+ (selection-position)(* (selection-framples) 2))) ) ;half-selection (define (half-selection) (set! (cursor) (selection-position)) (make-selection (selection-position) (+ (selection-position)(/ (selection-framples) 2))) ) ;play-selection ; to lazy to code ;-) (define (my_crop) (select-channel 0) (if (find-mark "start") (begin (key (char->integer #\<) 4) (key (char->integer #\ ) 4) (key (char->integer #\j) 4) (key (char->integer #\d) 0) )) (if (find-mark "end") (begin (key (char->integer #\j) 4) (key (char->integer #\ ) 4) (key (char->integer #\>) 5) (key (char->integer #\d) 0) )) (key (char->integer #\<) 0) ) (define (my_save) (save-sound ) (open-next-file-in-directory) ) (bind-key (char->integer #\d) 0 delete-selection) (bind-key (char->integer #\s) 0 my_save) (bind-key (char->integer #\c) 0 my_crop) (bind-key (char->integer #\n) 0 open-next-file-in-directory) (bind-key (char->integer #\ ) 8 stop-song) (bind-key (char->integer #\c) 0 my_crop) (bind-key (char->integer #\x) 0 half-selection) (bind-key (char->integer #\X) 1 double-selection) (bind-key (char->integer #\y) 0 double-selection);german version (bind-key (char->integer #\z) 0 double-selection);english version (bind-key (char->integer #\^) 0 (lambda () (my-play-selection-forw 50000 50000))) (bind-key (char->integer #\^) 4 (lambda () (my-play-selection-backw 50000 50000))) (bind-key (char->integer #\t) 8 (lambda () (play (selection)))) (bind-key (char->integer #\p) 0 play-song) (bind-key (char->integer #\P) 1 play-end) (bind-key (char->integer #\p) 8 toggle-play) (bind-key (char->integer #\3) 8 forward-selection) (bind-key (char->integer #\2) 8 backward-selection) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; status ;;;; 0 = new ;;; 1 = start is set ;;; 2 = playing ;;; 3 = end is set ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (bind-key #xFFBE 0 (lambda () (case status ((0 1) (mark-start 50000)) ((2) (mark-end 50000)) ((3) (mark-end 40000)) (else (set! status 0)) ))) (bind-key (char->integer #\1) 0 (lambda () (case status ((0 1) (mark-start 50000)) ((2) (mark-end 50000)) ((3) (mark-end 40000)) (else (set! status 0)) ))) (bind-key (char->integer #\1) 4 (lambda () (case status ((0) (mark-end 50000)) ((1) (set! status 3)) ((2) (mark-start 50000)) ((3) (set! status 1)) (else (set! status 0)) ))) (bind-key (char->integer #\1) 8 (lambda () (case status ((0) (set! status 2)) ((1) (set! status 3)) ((3) (set! status 1)) (else (set! status 0)) ))) (bind-key (char->integer #\2) 4 (lambda () (case status ((0) (mark-start 30000)) ((1) (move-start 2000 50000)) ((2) (mark-end 50000)) ((3) (move-end 2000 50000)) (else (set! status 0)) ))) (bind-key (char->integer #\2) 0 (lambda ()(case status ((0) (mark-start 30000)) ((1) (move-start -2000 50000)) ((2) (mark-end 50000)) ((3) (move-end -2000 50000)) (else (set! status 0)) ))) (bind-key (char->integer #\3) 4 (lambda () (case status ((0) (mark-start 20000)) ((1) (move-start 300 20000)) ((2) (mark-end 20000)) ((3) (move-end 300 20000)) (else (set! status 0)) ))) (bind-key (char->integer #\3) 0 (lambda () (case status ((0) (mark-start 20000)) ((1) (move-start -300 20000)) ((2) (mark-end 20000)) ((3) (move-end -300 20000)) (else (set! status 0)) ))) (bind-key (char->integer #\p) 4 toggle-play) (bind-key (char->integer #\p) 0 play-song) (bind-key (char->integer #\P) 1 play-end) ; f fade in or out selection (bind-key (char->integer #\f) 0 (lambda() (case status ((0) (mark-start 50000)) ((1) (env-selection '(0 0 2 1))) ((2) (mark-end 50000)) ((3) (env-selection '(0 1 2 0))) (else (set! status 0)) ))) (bind-key (char->integer #\t) 0 (lambda () (case status ((1) (goto-named-mark "start") (my-play-selection (cursor) (+ (cursor) 100000))) ((3) (goto-named-mark "end") (my-play-selection (- (cursor) 100000) (cursor))) ; (else (status-report "status:" (status) ) ) ) ) ) ; change status ; + zoom in (bind-key (char->integer #\+) 0 (lambda () (set! (x-bounds) (list (/ (selection-position) (srate)) (/ (+ (selection-position) (selection-framples)) (srate)))) (cursor-on-left) ) ) ; - zoom out (bind-key (char->integer #\-) 0 (lambda () (let ((curs (cursor))) (set! (x-bounds) (list 0 5)) (set! (cursor) curs)) ) ) snd-16.1/gl.c0000644000076400007640000104273012626046435011120 0ustar bilbil/* gl.c: s7, Ruby, and Forth bindings for GL, GLU * generated automatically from makegl.scm and gldata.scm * needs xen.h * * reference args are ignored if passed, resultant values are returned in a list. * the various "v" forms are omitted for now -- are they needed in this context? * 'gl is added to *features* * * HISTORY: * * 16-Apr-14: changed max-args to 8. * -------- * 16-Dec-09: removed Guile support. * -------- * 17-Oct-08: removed gtkglext bindings. * -------- * 30-Mar-06: check for glu.h, omit GLU_* if necessary. Add Forth support. * -------- * 13-Jun-05: merged gl-ruby.c into gl.c. * -------- * 10-Mar: Gl_Version. * 1-Feb-03: glGet* funcs now try to handle multiple return values correctly. * -------- * 18-Nov: added more GtkGlext bindings. * 1-Aug: removed all 'EXT' junk. * 24-July: changed Guile prefix (R5RS reserves vertical-bar). * 18-June: GL 1.1 stubs. * 4-June: GtkGLext support. * 20-May-02: initial version. */ #include "mus-config.h" #if HAVE_EXTENSION_LANGUAGE #include #if HAVE_GLU #include #endif #if USE_MOTIF #include #endif #include #if USE_SND /* USE_SND causes xm to use Snd's error handlers which are much smarter than xen's fallback versions */ #include "snd.h" #else #include "xen.h" #endif #ifndef unsigned_long /* for FreeBSD (thanks to Michael Scholz) (can't use ulong here due to collisions elsewhere) */ typedef unsigned long unsigned_long; #endif /* prefix for all names */ #if HAVE_SCHEME #define XL_PRE "" #define XL_POST "" #endif #if HAVE_RUBY /* for Ruby, XG PRE needs to be uppercase */ #define XL_PRE "R" #define XL_POST "" #endif #if HAVE_FORTH #define XL_PRE "F" #define XL_POST "" #endif #define wrap_for_Xen(Name, Value) Xen_list_2(C_string_to_Xen_symbol(Name), Xen_wrap_C_pointer(Value)) #define is_wrapped(Name, Value) (Xen_is_list(Value) && \ (Xen_list_length(Value) >= 2) && \ (Xen_is_symbol(Xen_car(Value))) && \ (strcmp(Name, Xen_symbol_to_C_string(Xen_car(Value))) == 0)) #define XL_TYPE(Name, XType) \ static Xen C_to_Xen_ ## Name (XType val) {return(Xen_list_2(C_string_to_Xen_symbol(#Name), C_ulong_to_Xen_ulong(val)));} \ static XType Xen_to_C_ ## Name (Xen val) {return((XType)Xen_ulong_to_C_ulong(Xen_cadr(val)));} \ static bool Xen_is_ ## Name (Xen val) {return(is_wrapped(#Name, val));} #define XL_TYPE_1(Name, XType) \ static XType Xen_to_C_ ## Name (Xen val) {return((XType)Xen_ulong_to_C_ulong(Xen_cadr(val)));} \ static bool Xen_is_ ## Name (Xen val) {return(is_wrapped(#Name, val));} #define XL_TYPE_PTR(Name, XType) \ static Xen C_to_Xen_ ## Name (XType val) {if (val) return(wrap_for_Xen(#Name, val)); return(Xen_false);} \ static XType Xen_to_C_ ## Name (Xen val) {if (Xen_is_false(val)) return(NULL); return((XType)Xen_unwrap_C_pointer(Xen_cadr(val)));} \ static bool Xen_is_ ## Name (Xen val) {return(is_wrapped(#Name, val));} /* if NULL ok, should be explicit */ #define XL_TYPE_PTR_1(Name, XType) \ static XType Xen_to_C_ ## Name (Xen val) {if (Xen_is_false(val)) return(NULL); return((XType)Xen_unwrap_C_pointer(Xen_cadr(val)));} \ static bool Xen_is_ ## Name (Xen val) {return(is_wrapped(#Name, val));} /* if NULL ok, should be explicit */ /* ---------------------------------------- types ---------------------------------------- */ #if USE_MOTIF XL_TYPE_PTR(XVisualInfo, XVisualInfo*) XL_TYPE_PTR(Display, Display*) #define C_to_Xen_int(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_int(Arg) (int)(Xen_integer_to_C_int(Arg)) #define Xen_is_int(Arg) Xen_is_integer(Arg) XL_TYPE_PTR_1(int_, int*) XL_TYPE_PTR(GLXContext, GLXContext) #define Xen_to_C_unsigned_long(Arg) (unsigned_long)(Xen_ulong_to_C_ulong(Arg)) #define Xen_is_unsigned_long(Arg) Xen_is_ulong(Arg) #define C_to_Xen_Bool(Arg) C_bool_to_Xen_boolean(Arg) #define Xen_to_C_Bool(Arg) (Bool)(Xen_boolean_to_C_bool(Arg)) #define Xen_is_Bool(Arg) Xen_is_boolean(Arg) XL_TYPE(GLXPixmap, GLXPixmap) XL_TYPE_1(Pixmap, Pixmap) XL_TYPE(Window, Window) XL_TYPE_1(Font, Font) #define C_to_Xen_char_(Arg) C_string_to_Xen_string(Arg) #define Xen_to_C_char_(Arg) (char*)(Xen_string_to_C_string(Arg)) #define Xen_is_char_(Arg) Xen_is_string(Arg) #endif #define C_to_Xen_GLfloat(Arg) C_double_to_Xen_real(Arg) #define Xen_to_C_GLfloat(Arg) (GLfloat)(Xen_real_to_C_double(Arg)) #define Xen_is_GLfloat(Arg) Xen_is_number(Arg) #define Xen_to_C_GLclampf(Arg) (GLclampf)(Xen_real_to_C_double(Arg)) #define Xen_is_GLclampf(Arg) Xen_is_number(Arg) #define Xen_to_C_GLbitfield(Arg) (GLbitfield)(Xen_ulong_to_C_ulong(Arg)) #define Xen_is_GLbitfield(Arg) Xen_is_ulong(Arg) #define C_to_Xen_GLuint(Arg) C_ulong_to_Xen_ulong(Arg) #define Xen_to_C_GLuint(Arg) (GLuint)(Xen_ulong_to_C_ulong(Arg)) #define Xen_is_GLuint(Arg) Xen_is_ulong(Arg) #define C_to_Xen_GLboolean(Arg) C_bool_to_Xen_boolean(Arg) #define Xen_to_C_GLboolean(Arg) (GLboolean)(Xen_boolean_to_C_bool(Arg)) #define Xen_is_GLboolean(Arg) Xen_is_boolean(Arg) #define C_to_Xen_GLenum(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GLenum(Arg) (GLenum)(Xen_integer_to_C_int(Arg)) #define Xen_is_GLenum(Arg) Xen_is_integer(Arg) #define C_to_Xen_GLint(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GLint(Arg) (GLint)(Xen_integer_to_C_int(Arg)) #define Xen_is_GLint(Arg) Xen_is_integer(Arg) #define C_to_Xen_GLushort(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GLushort(Arg) (GLushort)(Xen_integer_to_C_int(Arg)) #define Xen_is_GLushort(Arg) Xen_is_integer(Arg) XL_TYPE_PTR_1(GLubyte_, GLubyte*) #define Xen_to_C_GLsizei(Arg) (GLsizei)(Xen_integer_to_C_int(Arg)) #define Xen_is_GLsizei(Arg) Xen_is_integer(Arg) XL_TYPE_PTR_1(GLdouble_, GLdouble*) #define C_to_Xen_GLdouble(Arg) C_double_to_Xen_real(Arg) #define Xen_to_C_GLdouble(Arg) (GLdouble)(Xen_real_to_C_double(Arg)) #define Xen_is_GLdouble(Arg) Xen_is_number(Arg) #define C_to_Xen_constchar_(Arg) C_string_to_Xen_string((char *)(Arg)) #define Xen_to_C_GLclampd(Arg) (GLclampd)(Xen_real_to_C_double(Arg)) #define Xen_is_GLclampd(Arg) Xen_is_number(Arg) XL_TYPE_PTR_1(GLfloat_, GLfloat*) XL_TYPE_PTR_1(GLvoid_, GLvoid*) #define Xen_to_C_GLshort(Arg) (GLshort)(Xen_integer_to_C_int(Arg)) #define Xen_is_GLshort(Arg) Xen_is_integer(Arg) #define Xen_to_C_GLbyte(Arg) (GLbyte)(Xen_integer_to_C_int(Arg)) #define Xen_is_GLbyte(Arg) Xen_is_integer(Arg) #define C_to_Xen_GLubyte(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GLubyte(Arg) (GLubyte)(Xen_integer_to_C_int(Arg)) #define Xen_is_GLubyte(Arg) Xen_is_integer(Arg) XL_TYPE_PTR(void_, void*) XL_TYPE_PTR_1(GLuint_, GLuint*) XL_TYPE_PTR_1(GLboolean_, GLboolean*) #if HAVE_GLU XL_TYPE_PTR(GLUnurbs_, GLUnurbs*) #endif #ifdef GLU_VERSION_1_2 XL_TYPE_PTR(GLUtesselator_, GLUtesselator*) #endif #if HAVE_GLU XL_TYPE_PTR(GLUquadric_, GLUquadric*) #endif XL_TYPE_PTR_1(GLint_, GLint*) #if HAVE_GLU XL_TYPE(_GLUfuncptr, _GLUfuncptr) #endif /* ---------------------------------------- state readback confusion ---------------------------------------- */ static int how_many_vals(GLenum gl) { switch (gl) { case GL_CURRENT_COLOR: case GL_CURRENT_TEXTURE_COORDS: case GL_CURRENT_RASTER_POSITION: case GL_CURRENT_RASTER_COLOR: case GL_CURRENT_RASTER_TEXTURE_COORDS: case GL_VIEWPORT: case GL_FOG_COLOR: case GL_AMBIENT: case GL_DIFFUSE: case GL_SPECULAR: case GL_EMISSION: case GL_LIGHT_MODEL_AMBIENT: case GL_SCISSOR_BOX: case GL_COLOR_WRITEMASK: case GL_COLOR_CLEAR_VALUE: return(4); break; case GL_MODELVIEW_MATRIX: case GL_PROJECTION_MATRIX: case GL_TEXTURE_MATRIX: return(16); break; case GL_CURRENT_NORMAL: case GL_SPOT_DIRECTION: return(3); break; case GL_DEPTH_RANGE: case GL_LINE_WIDTH_RANGE: return(2); break; default: return(1); break; /* try to squelch c++ babbling */ } return(1); } /* ---------------------------------------- functions ---------------------------------------- */ #if USE_MOTIF static Xen gxg_glXChooseVisual(Xen dpy, Xen screen, Xen attribList) { #define H_glXChooseVisual "XVisualInfo* glXChooseVisual(Display* dpy, int screen, int* attribList)" Xen_check_type(Xen_is_Display(dpy), dpy, 1, "glXChooseVisual", "Display*"); Xen_check_type(Xen_is_int(screen), screen, 2, "glXChooseVisual", "int"); Xen_check_type(Xen_is_int_(attribList), attribList, 3, "glXChooseVisual", "int*"); return(C_to_Xen_XVisualInfo(glXChooseVisual(Xen_to_C_Display(dpy), Xen_to_C_int(screen), Xen_to_C_int_(attribList)))); } static Xen gxg_glXCopyContext(Xen dpy, Xen src, Xen dst, Xen mask) { #define H_glXCopyContext "void glXCopyContext(Display* dpy, GLXContext src, GLXContext dst, unsigned_long mask)" Xen_check_type(Xen_is_Display(dpy), dpy, 1, "glXCopyContext", "Display*"); Xen_check_type(Xen_is_GLXContext(src), src, 2, "glXCopyContext", "GLXContext"); Xen_check_type(Xen_is_GLXContext(dst), dst, 3, "glXCopyContext", "GLXContext"); Xen_check_type(Xen_is_unsigned_long(mask), mask, 4, "glXCopyContext", "unsigned_long"); glXCopyContext(Xen_to_C_Display(dpy), Xen_to_C_GLXContext(src), Xen_to_C_GLXContext(dst), Xen_to_C_unsigned_long(mask)); return(Xen_false); } static Xen gxg_glXCreateContext(Xen dpy, Xen vis, Xen shareList, Xen direct) { #define H_glXCreateContext "GLXContext glXCreateContext(Display* dpy, XVisualInfo* vis, GLXContext shareList, \ Bool direct)" Xen_check_type(Xen_is_Display(dpy), dpy, 1, "glXCreateContext", "Display*"); Xen_check_type(Xen_is_XVisualInfo(vis), vis, 2, "glXCreateContext", "XVisualInfo*"); Xen_check_type(Xen_is_GLXContext(shareList), shareList, 3, "glXCreateContext", "GLXContext"); Xen_check_type(Xen_is_Bool(direct), direct, 4, "glXCreateContext", "Bool"); return(C_to_Xen_GLXContext(glXCreateContext(Xen_to_C_Display(dpy), Xen_to_C_XVisualInfo(vis), Xen_to_C_GLXContext(shareList), Xen_to_C_Bool(direct)))); } static Xen gxg_glXCreateGLXPixmap(Xen dpy, Xen vis, Xen pixmap) { #define H_glXCreateGLXPixmap "GLXPixmap glXCreateGLXPixmap(Display* dpy, XVisualInfo* vis, Pixmap pixmap)" Xen_check_type(Xen_is_Display(dpy), dpy, 1, "glXCreateGLXPixmap", "Display*"); Xen_check_type(Xen_is_XVisualInfo(vis), vis, 2, "glXCreateGLXPixmap", "XVisualInfo*"); Xen_check_type(Xen_is_Pixmap(pixmap), pixmap, 3, "glXCreateGLXPixmap", "Pixmap"); return(C_to_Xen_GLXPixmap(glXCreateGLXPixmap(Xen_to_C_Display(dpy), Xen_to_C_XVisualInfo(vis), Xen_to_C_Pixmap(pixmap)))); } static Xen gxg_glXDestroyContext(Xen dpy, Xen ctx) { #define H_glXDestroyContext "void glXDestroyContext(Display* dpy, GLXContext ctx)" Xen_check_type(Xen_is_Display(dpy), dpy, 1, "glXDestroyContext", "Display*"); Xen_check_type(Xen_is_GLXContext(ctx), ctx, 2, "glXDestroyContext", "GLXContext"); glXDestroyContext(Xen_to_C_Display(dpy), Xen_to_C_GLXContext(ctx)); return(Xen_false); } static Xen gxg_glXDestroyGLXPixmap(Xen dpy, Xen pix) { #define H_glXDestroyGLXPixmap "void glXDestroyGLXPixmap(Display* dpy, GLXPixmap pix)" Xen_check_type(Xen_is_Display(dpy), dpy, 1, "glXDestroyGLXPixmap", "Display*"); Xen_check_type(Xen_is_GLXPixmap(pix), pix, 2, "glXDestroyGLXPixmap", "GLXPixmap"); glXDestroyGLXPixmap(Xen_to_C_Display(dpy), Xen_to_C_GLXPixmap(pix)); return(Xen_false); } static Xen gxg_glXGetConfig(Xen dpy, Xen vis, Xen attrib, Xen value) { #define H_glXGetConfig "int glXGetConfig(Display* dpy, XVisualInfo* vis, int attrib, int* [value])" int ref_value[1]; Xen_check_type(Xen_is_Display(dpy), dpy, 1, "glXGetConfig", "Display*"); Xen_check_type(Xen_is_XVisualInfo(vis), vis, 2, "glXGetConfig", "XVisualInfo*"); Xen_check_type(Xen_is_int(attrib), attrib, 3, "glXGetConfig", "int"); { Xen result; result = C_to_Xen_int(glXGetConfig(Xen_to_C_Display(dpy), Xen_to_C_XVisualInfo(vis), Xen_to_C_int(attrib), ref_value)); return(Xen_list_2(result, C_to_Xen_int(ref_value[0]))); } } static Xen gxg_glXGetCurrentContext(void) { #define H_glXGetCurrentContext "GLXContext glXGetCurrentContext( void)" return(C_to_Xen_GLXContext(glXGetCurrentContext())); } static Xen gxg_glXGetCurrentDrawable(void) { #define H_glXGetCurrentDrawable "Window glXGetCurrentDrawable( void)" return(C_to_Xen_Window(glXGetCurrentDrawable())); } static Xen gxg_glXIsDirect(Xen dpy, Xen ctx) { #define H_glXIsDirect "Bool glXIsDirect(Display* dpy, GLXContext ctx)" Xen_check_type(Xen_is_Display(dpy), dpy, 1, "glXIsDirect", "Display*"); Xen_check_type(Xen_is_GLXContext(ctx), ctx, 2, "glXIsDirect", "GLXContext"); return(C_to_Xen_Bool(glXIsDirect(Xen_to_C_Display(dpy), Xen_to_C_GLXContext(ctx)))); } static Xen gxg_glXMakeCurrent(Xen dpy, Xen drawable, Xen ctx) { #define H_glXMakeCurrent "Bool glXMakeCurrent(Display* dpy, Window drawable, GLXContext ctx)" Xen_check_type(Xen_is_Display(dpy), dpy, 1, "glXMakeCurrent", "Display*"); Xen_check_type(Xen_is_Window(drawable), drawable, 2, "glXMakeCurrent", "Window"); Xen_check_type(Xen_is_GLXContext(ctx), ctx, 3, "glXMakeCurrent", "GLXContext"); return(C_to_Xen_Bool(glXMakeCurrent(Xen_to_C_Display(dpy), Xen_to_C_Window(drawable), Xen_to_C_GLXContext(ctx)))); } static Xen gxg_glXQueryExtension(Xen dpy, Xen errorBase, Xen eventBase) { #define H_glXQueryExtension "Bool glXQueryExtension(Display* dpy, int* [errorBase], int* [eventBase])" int ref_errorBase[1]; int ref_eventBase[1]; Xen_check_type(Xen_is_Display(dpy), dpy, 1, "glXQueryExtension", "Display*"); { Xen result; result = C_to_Xen_Bool(glXQueryExtension(Xen_to_C_Display(dpy), ref_errorBase, ref_eventBase)); return(Xen_list_3(result, C_to_Xen_int(ref_errorBase[0]), C_to_Xen_int(ref_eventBase[0]))); } } static Xen gxg_glXQueryVersion(Xen dpy, Xen major, Xen minor) { #define H_glXQueryVersion "Bool glXQueryVersion(Display* dpy, int* [major], int* [minor])" int ref_major[1]; int ref_minor[1]; Xen_check_type(Xen_is_Display(dpy), dpy, 1, "glXQueryVersion", "Display*"); { Xen result; result = C_to_Xen_Bool(glXQueryVersion(Xen_to_C_Display(dpy), ref_major, ref_minor)); return(Xen_list_3(result, C_to_Xen_int(ref_major[0]), C_to_Xen_int(ref_minor[0]))); } } static Xen gxg_glXSwapBuffers(Xen dpy, Xen drawable) { #define H_glXSwapBuffers "void glXSwapBuffers(Display* dpy, Window drawable)" Xen_check_type(Xen_is_Display(dpy), dpy, 1, "glXSwapBuffers", "Display*"); Xen_check_type(Xen_is_Window(drawable), drawable, 2, "glXSwapBuffers", "Window"); glXSwapBuffers(Xen_to_C_Display(dpy), Xen_to_C_Window(drawable)); return(Xen_false); } static Xen gxg_glXUseXFont(Xen font, Xen first, Xen count, Xen listBase) { #define H_glXUseXFont "void glXUseXFont(Font font, int first, int count, int listBase)" Xen_check_type(Xen_is_Font(font), font, 1, "glXUseXFont", "Font"); Xen_check_type(Xen_is_int(first), first, 2, "glXUseXFont", "int"); Xen_check_type(Xen_is_int(count), count, 3, "glXUseXFont", "int"); Xen_check_type(Xen_is_int(listBase), listBase, 4, "glXUseXFont", "int"); glXUseXFont(Xen_to_C_Font(font), Xen_to_C_int(first), Xen_to_C_int(count), Xen_to_C_int(listBase)); return(Xen_false); } static Xen gxg_glXWaitGL(void) { #define H_glXWaitGL "void glXWaitGL( void)" glXWaitGL(); return(Xen_false); } static Xen gxg_glXWaitX(void) { #define H_glXWaitX "void glXWaitX( void)" glXWaitX(); return(Xen_false); } static Xen gxg_glXGetClientString(Xen dpy, Xen name) { #define H_glXGetClientString "char* glXGetClientString(Display* dpy, int name)" Xen_check_type(Xen_is_Display(dpy), dpy, 1, "glXGetClientString", "Display*"); Xen_check_type(Xen_is_int(name), name, 2, "glXGetClientString", "int"); return(C_to_Xen_char_(glXGetClientString(Xen_to_C_Display(dpy), Xen_to_C_int(name)))); } static Xen gxg_glXQueryServerString(Xen dpy, Xen screen, Xen name) { #define H_glXQueryServerString "char* glXQueryServerString(Display* dpy, int screen, int name)" Xen_check_type(Xen_is_Display(dpy), dpy, 1, "glXQueryServerString", "Display*"); Xen_check_type(Xen_is_int(screen), screen, 2, "glXQueryServerString", "int"); Xen_check_type(Xen_is_int(name), name, 3, "glXQueryServerString", "int"); return(C_to_Xen_char_(glXQueryServerString(Xen_to_C_Display(dpy), Xen_to_C_int(screen), Xen_to_C_int(name)))); } static Xen gxg_glXQueryExtensionsString(Xen dpy, Xen screen) { #define H_glXQueryExtensionsString "char* glXQueryExtensionsString(Display* dpy, int screen)" Xen_check_type(Xen_is_Display(dpy), dpy, 1, "glXQueryExtensionsString", "Display*"); Xen_check_type(Xen_is_int(screen), screen, 2, "glXQueryExtensionsString", "int"); return(C_to_Xen_char_(glXQueryExtensionsString(Xen_to_C_Display(dpy), Xen_to_C_int(screen)))); } #endif static Xen gxg_glClearIndex(Xen c) { #define H_glClearIndex "void glClearIndex(GLfloat c)" Xen_check_type(Xen_is_GLfloat(c), c, 1, "glClearIndex", "GLfloat"); glClearIndex(Xen_to_C_GLfloat(c)); return(Xen_false); } static Xen gxg_glClearColor(Xen red, Xen green, Xen blue, Xen alpha) { #define H_glClearColor "void glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)" Xen_check_type(Xen_is_GLclampf(red), red, 1, "glClearColor", "GLclampf"); Xen_check_type(Xen_is_GLclampf(green), green, 2, "glClearColor", "GLclampf"); Xen_check_type(Xen_is_GLclampf(blue), blue, 3, "glClearColor", "GLclampf"); Xen_check_type(Xen_is_GLclampf(alpha), alpha, 4, "glClearColor", "GLclampf"); glClearColor(Xen_to_C_GLclampf(red), Xen_to_C_GLclampf(green), Xen_to_C_GLclampf(blue), Xen_to_C_GLclampf(alpha)); return(Xen_false); } static Xen gxg_glClear(Xen mask) { #define H_glClear "void glClear(GLbitfield mask)" Xen_check_type(Xen_is_GLbitfield(mask), mask, 1, "glClear", "GLbitfield"); glClear(Xen_to_C_GLbitfield(mask)); return(Xen_false); } static Xen gxg_glIndexMask(Xen mask) { #define H_glIndexMask "void glIndexMask(GLuint mask)" Xen_check_type(Xen_is_GLuint(mask), mask, 1, "glIndexMask", "GLuint"); glIndexMask(Xen_to_C_GLuint(mask)); return(Xen_false); } static Xen gxg_glColorMask(Xen red, Xen green, Xen blue, Xen alpha) { #define H_glColorMask "void glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)" Xen_check_type(Xen_is_GLboolean(red), red, 1, "glColorMask", "GLboolean"); Xen_check_type(Xen_is_GLboolean(green), green, 2, "glColorMask", "GLboolean"); Xen_check_type(Xen_is_GLboolean(blue), blue, 3, "glColorMask", "GLboolean"); Xen_check_type(Xen_is_GLboolean(alpha), alpha, 4, "glColorMask", "GLboolean"); glColorMask(Xen_to_C_GLboolean(red), Xen_to_C_GLboolean(green), Xen_to_C_GLboolean(blue), Xen_to_C_GLboolean(alpha)); return(Xen_false); } static Xen gxg_glAlphaFunc(Xen func, Xen ref) { #define H_glAlphaFunc "void glAlphaFunc(GLenum func, GLclampf ref)" Xen_check_type(Xen_is_GLenum(func), func, 1, "glAlphaFunc", "GLenum"); Xen_check_type(Xen_is_GLclampf(ref), ref, 2, "glAlphaFunc", "GLclampf"); glAlphaFunc(Xen_to_C_GLenum(func), Xen_to_C_GLclampf(ref)); return(Xen_false); } static Xen gxg_glBlendFunc(Xen sfactor, Xen dfactor) { #define H_glBlendFunc "void glBlendFunc(GLenum sfactor, GLenum dfactor)" Xen_check_type(Xen_is_GLenum(sfactor), sfactor, 1, "glBlendFunc", "GLenum"); Xen_check_type(Xen_is_GLenum(dfactor), dfactor, 2, "glBlendFunc", "GLenum"); glBlendFunc(Xen_to_C_GLenum(sfactor), Xen_to_C_GLenum(dfactor)); return(Xen_false); } static Xen gxg_glLogicOp(Xen opcode) { #define H_glLogicOp "void glLogicOp(GLenum opcode)" Xen_check_type(Xen_is_GLenum(opcode), opcode, 1, "glLogicOp", "GLenum"); glLogicOp(Xen_to_C_GLenum(opcode)); return(Xen_false); } static Xen gxg_glCullFace(Xen mode) { #define H_glCullFace "void glCullFace(GLenum mode)" Xen_check_type(Xen_is_GLenum(mode), mode, 1, "glCullFace", "GLenum"); glCullFace(Xen_to_C_GLenum(mode)); return(Xen_false); } static Xen gxg_glFrontFace(Xen mode) { #define H_glFrontFace "void glFrontFace(GLenum mode)" Xen_check_type(Xen_is_GLenum(mode), mode, 1, "glFrontFace", "GLenum"); glFrontFace(Xen_to_C_GLenum(mode)); return(Xen_false); } static Xen gxg_glPointSize(Xen size) { #define H_glPointSize "void glPointSize(GLfloat size)" Xen_check_type(Xen_is_GLfloat(size), size, 1, "glPointSize", "GLfloat"); glPointSize(Xen_to_C_GLfloat(size)); return(Xen_false); } static Xen gxg_glLineWidth(Xen width) { #define H_glLineWidth "void glLineWidth(GLfloat width)" Xen_check_type(Xen_is_GLfloat(width), width, 1, "glLineWidth", "GLfloat"); glLineWidth(Xen_to_C_GLfloat(width)); return(Xen_false); } static Xen gxg_glLineStipple(Xen factor, Xen pattern) { #define H_glLineStipple "void glLineStipple(GLint factor, GLushort pattern)" Xen_check_type(Xen_is_GLint(factor), factor, 1, "glLineStipple", "GLint"); Xen_check_type(Xen_is_GLushort(pattern), pattern, 2, "glLineStipple", "GLushort"); glLineStipple(Xen_to_C_GLint(factor), Xen_to_C_GLushort(pattern)); return(Xen_false); } static Xen gxg_glPolygonMode(Xen face, Xen mode) { #define H_glPolygonMode "void glPolygonMode(GLenum face, GLenum mode)" Xen_check_type(Xen_is_GLenum(face), face, 1, "glPolygonMode", "GLenum"); Xen_check_type(Xen_is_GLenum(mode), mode, 2, "glPolygonMode", "GLenum"); glPolygonMode(Xen_to_C_GLenum(face), Xen_to_C_GLenum(mode)); return(Xen_false); } static Xen gxg_glPolygonOffset(Xen factor, Xen units) { #define H_glPolygonOffset "void glPolygonOffset(GLfloat factor, GLfloat units)" Xen_check_type(Xen_is_GLfloat(factor), factor, 1, "glPolygonOffset", "GLfloat"); Xen_check_type(Xen_is_GLfloat(units), units, 2, "glPolygonOffset", "GLfloat"); glPolygonOffset(Xen_to_C_GLfloat(factor), Xen_to_C_GLfloat(units)); return(Xen_false); } static Xen gxg_glPolygonStipple(Xen mask) { #define H_glPolygonStipple "void glPolygonStipple(GLubyte* mask)" Xen_check_type(Xen_is_GLubyte_(mask), mask, 1, "glPolygonStipple", "GLubyte*"); glPolygonStipple(Xen_to_C_GLubyte_(mask)); return(Xen_false); } static Xen gxg_glEdgeFlag(Xen flag) { #define H_glEdgeFlag "void glEdgeFlag(GLboolean flag)" Xen_check_type(Xen_is_GLboolean(flag), flag, 1, "glEdgeFlag", "GLboolean"); glEdgeFlag(Xen_to_C_GLboolean(flag)); return(Xen_false); } static Xen gxg_glScissor(Xen x, Xen y, Xen width, Xen height) { #define H_glScissor "void glScissor(GLint x, GLint y, GLsizei width, GLsizei height)" Xen_check_type(Xen_is_GLint(x), x, 1, "glScissor", "GLint"); Xen_check_type(Xen_is_GLint(y), y, 2, "glScissor", "GLint"); Xen_check_type(Xen_is_GLsizei(width), width, 3, "glScissor", "GLsizei"); Xen_check_type(Xen_is_GLsizei(height), height, 4, "glScissor", "GLsizei"); glScissor(Xen_to_C_GLint(x), Xen_to_C_GLint(y), Xen_to_C_GLsizei(width), Xen_to_C_GLsizei(height)); return(Xen_false); } static Xen gxg_glClipPlane(Xen plane, Xen equation) { #define H_glClipPlane "void glClipPlane(GLenum plane, GLdouble* equation)" Xen_check_type(Xen_is_GLenum(plane), plane, 1, "glClipPlane", "GLenum"); Xen_check_type(Xen_is_GLdouble_(equation), equation, 2, "glClipPlane", "GLdouble*"); glClipPlane(Xen_to_C_GLenum(plane), Xen_to_C_GLdouble_(equation)); return(Xen_false); } static Xen gxg_glGetClipPlane(Xen plane, Xen equation) { #define H_glGetClipPlane "void glGetClipPlane(GLenum plane, GLdouble* [equation])" GLdouble ref_equation[1]; Xen_check_type(Xen_is_GLenum(plane), plane, 1, "glGetClipPlane", "GLenum"); glGetClipPlane(Xen_to_C_GLenum(plane), ref_equation); return(Xen_list_1(C_to_Xen_GLdouble(ref_equation[0]))); } static Xen gxg_glDrawBuffer(Xen mode) { #define H_glDrawBuffer "void glDrawBuffer(GLenum mode)" Xen_check_type(Xen_is_GLenum(mode), mode, 1, "glDrawBuffer", "GLenum"); glDrawBuffer(Xen_to_C_GLenum(mode)); return(Xen_false); } static Xen gxg_glReadBuffer(Xen mode) { #define H_glReadBuffer "void glReadBuffer(GLenum mode)" Xen_check_type(Xen_is_GLenum(mode), mode, 1, "glReadBuffer", "GLenum"); glReadBuffer(Xen_to_C_GLenum(mode)); return(Xen_false); } static Xen gxg_glEnable(Xen cap) { #define H_glEnable "void glEnable(GLenum cap)" Xen_check_type(Xen_is_GLenum(cap), cap, 1, "glEnable", "GLenum"); glEnable(Xen_to_C_GLenum(cap)); return(Xen_false); } static Xen gxg_glDisable(Xen cap) { #define H_glDisable "void glDisable(GLenum cap)" Xen_check_type(Xen_is_GLenum(cap), cap, 1, "glDisable", "GLenum"); glDisable(Xen_to_C_GLenum(cap)); return(Xen_false); } static Xen gxg_glIsEnabled(Xen cap) { #define H_glIsEnabled "GLboolean glIsEnabled(GLenum cap)" Xen_check_type(Xen_is_GLenum(cap), cap, 1, "glIsEnabled", "GLenum"); return(C_to_Xen_GLboolean(glIsEnabled(Xen_to_C_GLenum(cap)))); } static Xen gxg_glEnableClientState(Xen cap) { #define H_glEnableClientState "void glEnableClientState(GLenum cap)" Xen_check_type(Xen_is_GLenum(cap), cap, 1, "glEnableClientState", "GLenum"); glEnableClientState(Xen_to_C_GLenum(cap)); return(Xen_false); } static Xen gxg_glDisableClientState(Xen cap) { #define H_glDisableClientState "void glDisableClientState(GLenum cap)" Xen_check_type(Xen_is_GLenum(cap), cap, 1, "glDisableClientState", "GLenum"); glDisableClientState(Xen_to_C_GLenum(cap)); return(Xen_false); } static Xen gxg_glGetBooleanv(Xen pname, Xen params) { #define H_glGetBooleanv "void glGetBooleanv(GLenum pname, GLboolean* [params])" GLboolean ref_params[16]; Xen_check_type(Xen_is_GLenum(pname), pname, 1, "glGetBooleanv", "GLenum"); glGetBooleanv(Xen_to_C_GLenum(pname), ref_params); { Xen result; int i, vals; vals = how_many_vals(Xen_to_C_GLenum(pname)); result = Xen_empty_list; for (i = 0; i < vals; i++) result = Xen_cons(C_to_Xen_GLboolean(ref_params[i]), result); return(result); } } static Xen gxg_glGetDoublev(Xen pname, Xen params) { #define H_glGetDoublev "void glGetDoublev(GLenum pname, GLdouble* [params])" GLdouble ref_params[1]; Xen_check_type(Xen_is_GLenum(pname), pname, 1, "glGetDoublev", "GLenum"); glGetDoublev(Xen_to_C_GLenum(pname), ref_params); return(Xen_list_1(C_to_Xen_GLdouble(ref_params[0]))); } static Xen gxg_glGetFloatv(Xen pname, Xen params) { #define H_glGetFloatv "void glGetFloatv(GLenum pname, GLfloat* [params])" GLfloat ref_params[16]; Xen_check_type(Xen_is_GLenum(pname), pname, 1, "glGetFloatv", "GLenum"); glGetFloatv(Xen_to_C_GLenum(pname), ref_params); { Xen result; int i, vals; vals = how_many_vals(Xen_to_C_GLenum(pname)); result = Xen_empty_list; for (i = 0; i < vals; i++) result = Xen_cons(C_to_Xen_GLfloat(ref_params[i]), result); return(result); } } static Xen gxg_glGetIntegerv(Xen pname, Xen params) { #define H_glGetIntegerv "void glGetIntegerv(GLenum pname, GLint* [params])" GLint ref_params[16]; Xen_check_type(Xen_is_GLenum(pname), pname, 1, "glGetIntegerv", "GLenum"); glGetIntegerv(Xen_to_C_GLenum(pname), ref_params); { Xen result; int i, vals; vals = how_many_vals(Xen_to_C_GLenum(pname)); result = Xen_empty_list; for (i = 0; i < vals; i++) result = Xen_cons(C_to_Xen_GLint(ref_params[i]), result); return(result); } } static Xen gxg_glPushAttrib(Xen mask) { #define H_glPushAttrib "void glPushAttrib(GLbitfield mask)" Xen_check_type(Xen_is_GLbitfield(mask), mask, 1, "glPushAttrib", "GLbitfield"); glPushAttrib(Xen_to_C_GLbitfield(mask)); return(Xen_false); } static Xen gxg_glPopAttrib(void) { #define H_glPopAttrib "void glPopAttrib( void)" glPopAttrib(); return(Xen_false); } static Xen gxg_glPushClientAttrib(Xen mask) { #define H_glPushClientAttrib "void glPushClientAttrib(GLbitfield mask)" Xen_check_type(Xen_is_GLbitfield(mask), mask, 1, "glPushClientAttrib", "GLbitfield"); glPushClientAttrib(Xen_to_C_GLbitfield(mask)); return(Xen_false); } static Xen gxg_glPopClientAttrib(void) { #define H_glPopClientAttrib "void glPopClientAttrib( void)" glPopClientAttrib(); return(Xen_false); } static Xen gxg_glRenderMode(Xen mode) { #define H_glRenderMode "GLint glRenderMode(GLenum mode)" Xen_check_type(Xen_is_GLenum(mode), mode, 1, "glRenderMode", "GLenum"); return(C_to_Xen_GLint(glRenderMode(Xen_to_C_GLenum(mode)))); } static Xen gxg_glGetError(void) { #define H_glGetError "GLenum glGetError( void)" return(C_to_Xen_GLenum(glGetError())); } static Xen gxg_glGetString(Xen name) { #define H_glGetString "constchar* glGetString(GLenum name)" Xen_check_type(Xen_is_GLenum(name), name, 1, "glGetString", "GLenum"); return(C_to_Xen_constchar_(glGetString(Xen_to_C_GLenum(name)))); } static Xen gxg_glFinish(void) { #define H_glFinish "void glFinish( void)" glFinish(); return(Xen_false); } static Xen gxg_glFlush(void) { #define H_glFlush "void glFlush( void)" glFlush(); return(Xen_false); } static Xen gxg_glHint(Xen target, Xen mode) { #define H_glHint "void glHint(GLenum target, GLenum mode)" Xen_check_type(Xen_is_GLenum(target), target, 1, "glHint", "GLenum"); Xen_check_type(Xen_is_GLenum(mode), mode, 2, "glHint", "GLenum"); glHint(Xen_to_C_GLenum(target), Xen_to_C_GLenum(mode)); return(Xen_false); } static Xen gxg_glClearDepth(Xen depth) { #define H_glClearDepth "void glClearDepth(GLclampd depth)" Xen_check_type(Xen_is_GLclampd(depth), depth, 1, "glClearDepth", "GLclampd"); glClearDepth(Xen_to_C_GLclampd(depth)); return(Xen_false); } static Xen gxg_glDepthFunc(Xen func) { #define H_glDepthFunc "void glDepthFunc(GLenum func)" Xen_check_type(Xen_is_GLenum(func), func, 1, "glDepthFunc", "GLenum"); glDepthFunc(Xen_to_C_GLenum(func)); return(Xen_false); } static Xen gxg_glDepthMask(Xen flag) { #define H_glDepthMask "void glDepthMask(GLboolean flag)" Xen_check_type(Xen_is_GLboolean(flag), flag, 1, "glDepthMask", "GLboolean"); glDepthMask(Xen_to_C_GLboolean(flag)); return(Xen_false); } static Xen gxg_glDepthRange(Xen near_val, Xen far_val) { #define H_glDepthRange "void glDepthRange(GLclampd near_val, GLclampd far_val)" Xen_check_type(Xen_is_GLclampd(near_val), near_val, 1, "glDepthRange", "GLclampd"); Xen_check_type(Xen_is_GLclampd(far_val), far_val, 2, "glDepthRange", "GLclampd"); glDepthRange(Xen_to_C_GLclampd(near_val), Xen_to_C_GLclampd(far_val)); return(Xen_false); } static Xen gxg_glClearAccum(Xen red, Xen green, Xen blue, Xen alpha) { #define H_glClearAccum "void glClearAccum(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)" Xen_check_type(Xen_is_GLfloat(red), red, 1, "glClearAccum", "GLfloat"); Xen_check_type(Xen_is_GLfloat(green), green, 2, "glClearAccum", "GLfloat"); Xen_check_type(Xen_is_GLfloat(blue), blue, 3, "glClearAccum", "GLfloat"); Xen_check_type(Xen_is_GLfloat(alpha), alpha, 4, "glClearAccum", "GLfloat"); glClearAccum(Xen_to_C_GLfloat(red), Xen_to_C_GLfloat(green), Xen_to_C_GLfloat(blue), Xen_to_C_GLfloat(alpha)); return(Xen_false); } static Xen gxg_glAccum(Xen op, Xen value) { #define H_glAccum "void glAccum(GLenum op, GLfloat value)" Xen_check_type(Xen_is_GLenum(op), op, 1, "glAccum", "GLenum"); Xen_check_type(Xen_is_GLfloat(value), value, 2, "glAccum", "GLfloat"); glAccum(Xen_to_C_GLenum(op), Xen_to_C_GLfloat(value)); return(Xen_false); } static Xen gxg_glMatrixMode(Xen mode) { #define H_glMatrixMode "void glMatrixMode(GLenum mode)" Xen_check_type(Xen_is_GLenum(mode), mode, 1, "glMatrixMode", "GLenum"); glMatrixMode(Xen_to_C_GLenum(mode)); return(Xen_false); } static Xen gxg_glOrtho(Xen left, Xen right, Xen bottom, Xen top, Xen near_val, Xen far_val) { #define H_glOrtho "void glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, \ GLdouble far_val)" Xen_check_type(Xen_is_GLdouble(left), left, 1, "glOrtho", "GLdouble"); Xen_check_type(Xen_is_GLdouble(right), right, 2, "glOrtho", "GLdouble"); Xen_check_type(Xen_is_GLdouble(bottom), bottom, 3, "glOrtho", "GLdouble"); Xen_check_type(Xen_is_GLdouble(top), top, 4, "glOrtho", "GLdouble"); Xen_check_type(Xen_is_GLdouble(near_val), near_val, 5, "glOrtho", "GLdouble"); Xen_check_type(Xen_is_GLdouble(far_val), far_val, 6, "glOrtho", "GLdouble"); glOrtho(Xen_to_C_GLdouble(left), Xen_to_C_GLdouble(right), Xen_to_C_GLdouble(bottom), Xen_to_C_GLdouble(top), Xen_to_C_GLdouble(near_val), Xen_to_C_GLdouble(far_val)); return(Xen_false); } static Xen gxg_glFrustum(Xen left, Xen right, Xen bottom, Xen top, Xen near_val, Xen far_val) { #define H_glFrustum "void glFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, \ GLdouble far_val)" Xen_check_type(Xen_is_GLdouble(left), left, 1, "glFrustum", "GLdouble"); Xen_check_type(Xen_is_GLdouble(right), right, 2, "glFrustum", "GLdouble"); Xen_check_type(Xen_is_GLdouble(bottom), bottom, 3, "glFrustum", "GLdouble"); Xen_check_type(Xen_is_GLdouble(top), top, 4, "glFrustum", "GLdouble"); Xen_check_type(Xen_is_GLdouble(near_val), near_val, 5, "glFrustum", "GLdouble"); Xen_check_type(Xen_is_GLdouble(far_val), far_val, 6, "glFrustum", "GLdouble"); glFrustum(Xen_to_C_GLdouble(left), Xen_to_C_GLdouble(right), Xen_to_C_GLdouble(bottom), Xen_to_C_GLdouble(top), Xen_to_C_GLdouble(near_val), Xen_to_C_GLdouble(far_val)); return(Xen_false); } static Xen gxg_glViewport(Xen x, Xen y, Xen width, Xen height) { #define H_glViewport "void glViewport(GLint x, GLint y, GLsizei width, GLsizei height)" Xen_check_type(Xen_is_GLint(x), x, 1, "glViewport", "GLint"); Xen_check_type(Xen_is_GLint(y), y, 2, "glViewport", "GLint"); Xen_check_type(Xen_is_GLsizei(width), width, 3, "glViewport", "GLsizei"); Xen_check_type(Xen_is_GLsizei(height), height, 4, "glViewport", "GLsizei"); glViewport(Xen_to_C_GLint(x), Xen_to_C_GLint(y), Xen_to_C_GLsizei(width), Xen_to_C_GLsizei(height)); return(Xen_false); } static Xen gxg_glPushMatrix(void) { #define H_glPushMatrix "void glPushMatrix( void)" glPushMatrix(); return(Xen_false); } static Xen gxg_glPopMatrix(void) { #define H_glPopMatrix "void glPopMatrix( void)" glPopMatrix(); return(Xen_false); } static Xen gxg_glLoadIdentity(void) { #define H_glLoadIdentity "void glLoadIdentity( void)" glLoadIdentity(); return(Xen_false); } static Xen gxg_glLoadMatrixd(Xen m) { #define H_glLoadMatrixd "void glLoadMatrixd(GLdouble* m)" Xen_check_type(Xen_is_GLdouble_(m), m, 1, "glLoadMatrixd", "GLdouble*"); glLoadMatrixd(Xen_to_C_GLdouble_(m)); return(Xen_false); } static Xen gxg_glLoadMatrixf(Xen m) { #define H_glLoadMatrixf "void glLoadMatrixf(GLfloat* m)" Xen_check_type(Xen_is_GLfloat_(m), m, 1, "glLoadMatrixf", "GLfloat*"); glLoadMatrixf(Xen_to_C_GLfloat_(m)); return(Xen_false); } static Xen gxg_glMultMatrixd(Xen m) { #define H_glMultMatrixd "void glMultMatrixd(GLdouble* m)" Xen_check_type(Xen_is_GLdouble_(m), m, 1, "glMultMatrixd", "GLdouble*"); glMultMatrixd(Xen_to_C_GLdouble_(m)); return(Xen_false); } static Xen gxg_glMultMatrixf(Xen m) { #define H_glMultMatrixf "void glMultMatrixf(GLfloat* m)" Xen_check_type(Xen_is_GLfloat_(m), m, 1, "glMultMatrixf", "GLfloat*"); glMultMatrixf(Xen_to_C_GLfloat_(m)); return(Xen_false); } static Xen gxg_glRotated(Xen angle, Xen x, Xen y, Xen z) { #define H_glRotated "void glRotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z)" Xen_check_type(Xen_is_GLdouble(angle), angle, 1, "glRotated", "GLdouble"); Xen_check_type(Xen_is_GLdouble(x), x, 2, "glRotated", "GLdouble"); Xen_check_type(Xen_is_GLdouble(y), y, 3, "glRotated", "GLdouble"); Xen_check_type(Xen_is_GLdouble(z), z, 4, "glRotated", "GLdouble"); glRotated(Xen_to_C_GLdouble(angle), Xen_to_C_GLdouble(x), Xen_to_C_GLdouble(y), Xen_to_C_GLdouble(z)); return(Xen_false); } static Xen gxg_glRotatef(Xen angle, Xen x, Xen y, Xen z) { #define H_glRotatef "void glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)" Xen_check_type(Xen_is_GLfloat(angle), angle, 1, "glRotatef", "GLfloat"); Xen_check_type(Xen_is_GLfloat(x), x, 2, "glRotatef", "GLfloat"); Xen_check_type(Xen_is_GLfloat(y), y, 3, "glRotatef", "GLfloat"); Xen_check_type(Xen_is_GLfloat(z), z, 4, "glRotatef", "GLfloat"); glRotatef(Xen_to_C_GLfloat(angle), Xen_to_C_GLfloat(x), Xen_to_C_GLfloat(y), Xen_to_C_GLfloat(z)); return(Xen_false); } static Xen gxg_glScaled(Xen x, Xen y, Xen z) { #define H_glScaled "void glScaled(GLdouble x, GLdouble y, GLdouble z)" Xen_check_type(Xen_is_GLdouble(x), x, 1, "glScaled", "GLdouble"); Xen_check_type(Xen_is_GLdouble(y), y, 2, "glScaled", "GLdouble"); Xen_check_type(Xen_is_GLdouble(z), z, 3, "glScaled", "GLdouble"); glScaled(Xen_to_C_GLdouble(x), Xen_to_C_GLdouble(y), Xen_to_C_GLdouble(z)); return(Xen_false); } static Xen gxg_glScalef(Xen x, Xen y, Xen z) { #define H_glScalef "void glScalef(GLfloat x, GLfloat y, GLfloat z)" Xen_check_type(Xen_is_GLfloat(x), x, 1, "glScalef", "GLfloat"); Xen_check_type(Xen_is_GLfloat(y), y, 2, "glScalef", "GLfloat"); Xen_check_type(Xen_is_GLfloat(z), z, 3, "glScalef", "GLfloat"); glScalef(Xen_to_C_GLfloat(x), Xen_to_C_GLfloat(y), Xen_to_C_GLfloat(z)); return(Xen_false); } static Xen gxg_glTranslated(Xen x, Xen y, Xen z) { #define H_glTranslated "void glTranslated(GLdouble x, GLdouble y, GLdouble z)" Xen_check_type(Xen_is_GLdouble(x), x, 1, "glTranslated", "GLdouble"); Xen_check_type(Xen_is_GLdouble(y), y, 2, "glTranslated", "GLdouble"); Xen_check_type(Xen_is_GLdouble(z), z, 3, "glTranslated", "GLdouble"); glTranslated(Xen_to_C_GLdouble(x), Xen_to_C_GLdouble(y), Xen_to_C_GLdouble(z)); return(Xen_false); } static Xen gxg_glTranslatef(Xen x, Xen y, Xen z) { #define H_glTranslatef "void glTranslatef(GLfloat x, GLfloat y, GLfloat z)" Xen_check_type(Xen_is_GLfloat(x), x, 1, "glTranslatef", "GLfloat"); Xen_check_type(Xen_is_GLfloat(y), y, 2, "glTranslatef", "GLfloat"); Xen_check_type(Xen_is_GLfloat(z), z, 3, "glTranslatef", "GLfloat"); glTranslatef(Xen_to_C_GLfloat(x), Xen_to_C_GLfloat(y), Xen_to_C_GLfloat(z)); return(Xen_false); } static Xen gxg_glIsList(Xen list) { #define H_glIsList "GLboolean glIsList(GLuint list)" Xen_check_type(Xen_is_GLuint(list), list, 1, "glIsList", "GLuint"); return(C_to_Xen_GLboolean(glIsList(Xen_to_C_GLuint(list)))); } static Xen gxg_glDeleteLists(Xen list, Xen range) { #define H_glDeleteLists "void glDeleteLists(GLuint list, GLsizei range)" Xen_check_type(Xen_is_GLuint(list), list, 1, "glDeleteLists", "GLuint"); Xen_check_type(Xen_is_GLsizei(range), range, 2, "glDeleteLists", "GLsizei"); glDeleteLists(Xen_to_C_GLuint(list), Xen_to_C_GLsizei(range)); return(Xen_false); } static Xen gxg_glGenLists(Xen range) { #define H_glGenLists "GLuint glGenLists(GLsizei range)" Xen_check_type(Xen_is_GLsizei(range), range, 1, "glGenLists", "GLsizei"); return(C_to_Xen_GLuint(glGenLists(Xen_to_C_GLsizei(range)))); } static Xen gxg_glNewList(Xen list, Xen mode) { #define H_glNewList "void glNewList(GLuint list, GLenum mode)" Xen_check_type(Xen_is_GLuint(list), list, 1, "glNewList", "GLuint"); Xen_check_type(Xen_is_GLenum(mode), mode, 2, "glNewList", "GLenum"); glNewList(Xen_to_C_GLuint(list), Xen_to_C_GLenum(mode)); return(Xen_false); } static Xen gxg_glEndList(void) { #define H_glEndList "void glEndList( void)" glEndList(); return(Xen_false); } static Xen gxg_glCallList(Xen list) { #define H_glCallList "void glCallList(GLuint list)" Xen_check_type(Xen_is_GLuint(list), list, 1, "glCallList", "GLuint"); glCallList(Xen_to_C_GLuint(list)); return(Xen_false); } static Xen gxg_glCallLists(Xen n, Xen type, Xen lists) { #define H_glCallLists "void glCallLists(GLsizei n, GLenum type, GLvoid* lists)" Xen_check_type(Xen_is_GLsizei(n), n, 1, "glCallLists", "GLsizei"); Xen_check_type(Xen_is_GLenum(type), type, 2, "glCallLists", "GLenum"); Xen_check_type(Xen_is_GLvoid_(lists), lists, 3, "glCallLists", "GLvoid*"); glCallLists(Xen_to_C_GLsizei(n), Xen_to_C_GLenum(type), Xen_to_C_GLvoid_(lists)); return(Xen_false); } static Xen gxg_glListBase(Xen base) { #define H_glListBase "void glListBase(GLuint base)" Xen_check_type(Xen_is_GLuint(base), base, 1, "glListBase", "GLuint"); glListBase(Xen_to_C_GLuint(base)); return(Xen_false); } static Xen gxg_glBegin(Xen mode) { #define H_glBegin "void glBegin(GLenum mode)" Xen_check_type(Xen_is_GLenum(mode), mode, 1, "glBegin", "GLenum"); glBegin(Xen_to_C_GLenum(mode)); return(Xen_false); } static Xen gxg_glEnd(void) { #define H_glEnd "void glEnd( void)" glEnd(); return(Xen_false); } static Xen gxg_glVertex2d(Xen x, Xen y) { #define H_glVertex2d "void glVertex2d(GLdouble x, GLdouble y)" Xen_check_type(Xen_is_GLdouble(x), x, 1, "glVertex2d", "GLdouble"); Xen_check_type(Xen_is_GLdouble(y), y, 2, "glVertex2d", "GLdouble"); glVertex2d(Xen_to_C_GLdouble(x), Xen_to_C_GLdouble(y)); return(Xen_false); } static Xen gxg_glVertex2f(Xen x, Xen y) { #define H_glVertex2f "void glVertex2f(GLfloat x, GLfloat y)" Xen_check_type(Xen_is_GLfloat(x), x, 1, "glVertex2f", "GLfloat"); Xen_check_type(Xen_is_GLfloat(y), y, 2, "glVertex2f", "GLfloat"); glVertex2f(Xen_to_C_GLfloat(x), Xen_to_C_GLfloat(y)); return(Xen_false); } static Xen gxg_glVertex2i(Xen x, Xen y) { #define H_glVertex2i "void glVertex2i(GLint x, GLint y)" Xen_check_type(Xen_is_GLint(x), x, 1, "glVertex2i", "GLint"); Xen_check_type(Xen_is_GLint(y), y, 2, "glVertex2i", "GLint"); glVertex2i(Xen_to_C_GLint(x), Xen_to_C_GLint(y)); return(Xen_false); } static Xen gxg_glVertex2s(Xen x, Xen y) { #define H_glVertex2s "void glVertex2s(GLshort x, GLshort y)" Xen_check_type(Xen_is_GLshort(x), x, 1, "glVertex2s", "GLshort"); Xen_check_type(Xen_is_GLshort(y), y, 2, "glVertex2s", "GLshort"); glVertex2s(Xen_to_C_GLshort(x), Xen_to_C_GLshort(y)); return(Xen_false); } static Xen gxg_glVertex3d(Xen x, Xen y, Xen z) { #define H_glVertex3d "void glVertex3d(GLdouble x, GLdouble y, GLdouble z)" Xen_check_type(Xen_is_GLdouble(x), x, 1, "glVertex3d", "GLdouble"); Xen_check_type(Xen_is_GLdouble(y), y, 2, "glVertex3d", "GLdouble"); Xen_check_type(Xen_is_GLdouble(z), z, 3, "glVertex3d", "GLdouble"); glVertex3d(Xen_to_C_GLdouble(x), Xen_to_C_GLdouble(y), Xen_to_C_GLdouble(z)); return(Xen_false); } static Xen gxg_glVertex3f(Xen x, Xen y, Xen z) { #define H_glVertex3f "void glVertex3f(GLfloat x, GLfloat y, GLfloat z)" Xen_check_type(Xen_is_GLfloat(x), x, 1, "glVertex3f", "GLfloat"); Xen_check_type(Xen_is_GLfloat(y), y, 2, "glVertex3f", "GLfloat"); Xen_check_type(Xen_is_GLfloat(z), z, 3, "glVertex3f", "GLfloat"); glVertex3f(Xen_to_C_GLfloat(x), Xen_to_C_GLfloat(y), Xen_to_C_GLfloat(z)); return(Xen_false); } static Xen gxg_glVertex3i(Xen x, Xen y, Xen z) { #define H_glVertex3i "void glVertex3i(GLint x, GLint y, GLint z)" Xen_check_type(Xen_is_GLint(x), x, 1, "glVertex3i", "GLint"); Xen_check_type(Xen_is_GLint(y), y, 2, "glVertex3i", "GLint"); Xen_check_type(Xen_is_GLint(z), z, 3, "glVertex3i", "GLint"); glVertex3i(Xen_to_C_GLint(x), Xen_to_C_GLint(y), Xen_to_C_GLint(z)); return(Xen_false); } static Xen gxg_glVertex3s(Xen x, Xen y, Xen z) { #define H_glVertex3s "void glVertex3s(GLshort x, GLshort y, GLshort z)" Xen_check_type(Xen_is_GLshort(x), x, 1, "glVertex3s", "GLshort"); Xen_check_type(Xen_is_GLshort(y), y, 2, "glVertex3s", "GLshort"); Xen_check_type(Xen_is_GLshort(z), z, 3, "glVertex3s", "GLshort"); glVertex3s(Xen_to_C_GLshort(x), Xen_to_C_GLshort(y), Xen_to_C_GLshort(z)); return(Xen_false); } static Xen gxg_glVertex4d(Xen x, Xen y, Xen z, Xen w) { #define H_glVertex4d "void glVertex4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w)" Xen_check_type(Xen_is_GLdouble(x), x, 1, "glVertex4d", "GLdouble"); Xen_check_type(Xen_is_GLdouble(y), y, 2, "glVertex4d", "GLdouble"); Xen_check_type(Xen_is_GLdouble(z), z, 3, "glVertex4d", "GLdouble"); Xen_check_type(Xen_is_GLdouble(w), w, 4, "glVertex4d", "GLdouble"); glVertex4d(Xen_to_C_GLdouble(x), Xen_to_C_GLdouble(y), Xen_to_C_GLdouble(z), Xen_to_C_GLdouble(w)); return(Xen_false); } static Xen gxg_glVertex4f(Xen x, Xen y, Xen z, Xen w) { #define H_glVertex4f "void glVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)" Xen_check_type(Xen_is_GLfloat(x), x, 1, "glVertex4f", "GLfloat"); Xen_check_type(Xen_is_GLfloat(y), y, 2, "glVertex4f", "GLfloat"); Xen_check_type(Xen_is_GLfloat(z), z, 3, "glVertex4f", "GLfloat"); Xen_check_type(Xen_is_GLfloat(w), w, 4, "glVertex4f", "GLfloat"); glVertex4f(Xen_to_C_GLfloat(x), Xen_to_C_GLfloat(y), Xen_to_C_GLfloat(z), Xen_to_C_GLfloat(w)); return(Xen_false); } static Xen gxg_glVertex4i(Xen x, Xen y, Xen z, Xen w) { #define H_glVertex4i "void glVertex4i(GLint x, GLint y, GLint z, GLint w)" Xen_check_type(Xen_is_GLint(x), x, 1, "glVertex4i", "GLint"); Xen_check_type(Xen_is_GLint(y), y, 2, "glVertex4i", "GLint"); Xen_check_type(Xen_is_GLint(z), z, 3, "glVertex4i", "GLint"); Xen_check_type(Xen_is_GLint(w), w, 4, "glVertex4i", "GLint"); glVertex4i(Xen_to_C_GLint(x), Xen_to_C_GLint(y), Xen_to_C_GLint(z), Xen_to_C_GLint(w)); return(Xen_false); } static Xen gxg_glVertex4s(Xen x, Xen y, Xen z, Xen w) { #define H_glVertex4s "void glVertex4s(GLshort x, GLshort y, GLshort z, GLshort w)" Xen_check_type(Xen_is_GLshort(x), x, 1, "glVertex4s", "GLshort"); Xen_check_type(Xen_is_GLshort(y), y, 2, "glVertex4s", "GLshort"); Xen_check_type(Xen_is_GLshort(z), z, 3, "glVertex4s", "GLshort"); Xen_check_type(Xen_is_GLshort(w), w, 4, "glVertex4s", "GLshort"); glVertex4s(Xen_to_C_GLshort(x), Xen_to_C_GLshort(y), Xen_to_C_GLshort(z), Xen_to_C_GLshort(w)); return(Xen_false); } static Xen gxg_glNormal3b(Xen nx, Xen ny, Xen nz) { #define H_glNormal3b "void glNormal3b(GLbyte nx, GLbyte ny, GLbyte nz)" Xen_check_type(Xen_is_GLbyte(nx), nx, 1, "glNormal3b", "GLbyte"); Xen_check_type(Xen_is_GLbyte(ny), ny, 2, "glNormal3b", "GLbyte"); Xen_check_type(Xen_is_GLbyte(nz), nz, 3, "glNormal3b", "GLbyte"); glNormal3b(Xen_to_C_GLbyte(nx), Xen_to_C_GLbyte(ny), Xen_to_C_GLbyte(nz)); return(Xen_false); } static Xen gxg_glNormal3d(Xen nx, Xen ny, Xen nz) { #define H_glNormal3d "void glNormal3d(GLdouble nx, GLdouble ny, GLdouble nz)" Xen_check_type(Xen_is_GLdouble(nx), nx, 1, "glNormal3d", "GLdouble"); Xen_check_type(Xen_is_GLdouble(ny), ny, 2, "glNormal3d", "GLdouble"); Xen_check_type(Xen_is_GLdouble(nz), nz, 3, "glNormal3d", "GLdouble"); glNormal3d(Xen_to_C_GLdouble(nx), Xen_to_C_GLdouble(ny), Xen_to_C_GLdouble(nz)); return(Xen_false); } static Xen gxg_glNormal3f(Xen nx, Xen ny, Xen nz) { #define H_glNormal3f "void glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz)" Xen_check_type(Xen_is_GLfloat(nx), nx, 1, "glNormal3f", "GLfloat"); Xen_check_type(Xen_is_GLfloat(ny), ny, 2, "glNormal3f", "GLfloat"); Xen_check_type(Xen_is_GLfloat(nz), nz, 3, "glNormal3f", "GLfloat"); glNormal3f(Xen_to_C_GLfloat(nx), Xen_to_C_GLfloat(ny), Xen_to_C_GLfloat(nz)); return(Xen_false); } static Xen gxg_glNormal3i(Xen nx, Xen ny, Xen nz) { #define H_glNormal3i "void glNormal3i(GLint nx, GLint ny, GLint nz)" Xen_check_type(Xen_is_GLint(nx), nx, 1, "glNormal3i", "GLint"); Xen_check_type(Xen_is_GLint(ny), ny, 2, "glNormal3i", "GLint"); Xen_check_type(Xen_is_GLint(nz), nz, 3, "glNormal3i", "GLint"); glNormal3i(Xen_to_C_GLint(nx), Xen_to_C_GLint(ny), Xen_to_C_GLint(nz)); return(Xen_false); } static Xen gxg_glNormal3s(Xen nx, Xen ny, Xen nz) { #define H_glNormal3s "void glNormal3s(GLshort nx, GLshort ny, GLshort nz)" Xen_check_type(Xen_is_GLshort(nx), nx, 1, "glNormal3s", "GLshort"); Xen_check_type(Xen_is_GLshort(ny), ny, 2, "glNormal3s", "GLshort"); Xen_check_type(Xen_is_GLshort(nz), nz, 3, "glNormal3s", "GLshort"); glNormal3s(Xen_to_C_GLshort(nx), Xen_to_C_GLshort(ny), Xen_to_C_GLshort(nz)); return(Xen_false); } static Xen gxg_glIndexd(Xen c) { #define H_glIndexd "void glIndexd(GLdouble c)" Xen_check_type(Xen_is_GLdouble(c), c, 1, "glIndexd", "GLdouble"); glIndexd(Xen_to_C_GLdouble(c)); return(Xen_false); } static Xen gxg_glIndexf(Xen c) { #define H_glIndexf "void glIndexf(GLfloat c)" Xen_check_type(Xen_is_GLfloat(c), c, 1, "glIndexf", "GLfloat"); glIndexf(Xen_to_C_GLfloat(c)); return(Xen_false); } static Xen gxg_glIndexi(Xen c) { #define H_glIndexi "void glIndexi(GLint c)" Xen_check_type(Xen_is_GLint(c), c, 1, "glIndexi", "GLint"); glIndexi(Xen_to_C_GLint(c)); return(Xen_false); } static Xen gxg_glIndexs(Xen c) { #define H_glIndexs "void glIndexs(GLshort c)" Xen_check_type(Xen_is_GLshort(c), c, 1, "glIndexs", "GLshort"); glIndexs(Xen_to_C_GLshort(c)); return(Xen_false); } static Xen gxg_glIndexub(Xen c) { #define H_glIndexub "void glIndexub(GLubyte c)" Xen_check_type(Xen_is_GLubyte(c), c, 1, "glIndexub", "GLubyte"); glIndexub(Xen_to_C_GLubyte(c)); return(Xen_false); } static Xen gxg_glColor3b(Xen red, Xen green, Xen blue) { #define H_glColor3b "void glColor3b(GLbyte red, GLbyte green, GLbyte blue)" Xen_check_type(Xen_is_GLbyte(red), red, 1, "glColor3b", "GLbyte"); Xen_check_type(Xen_is_GLbyte(green), green, 2, "glColor3b", "GLbyte"); Xen_check_type(Xen_is_GLbyte(blue), blue, 3, "glColor3b", "GLbyte"); glColor3b(Xen_to_C_GLbyte(red), Xen_to_C_GLbyte(green), Xen_to_C_GLbyte(blue)); return(Xen_false); } static Xen gxg_glColor3d(Xen red, Xen green, Xen blue) { #define H_glColor3d "void glColor3d(GLdouble red, GLdouble green, GLdouble blue)" Xen_check_type(Xen_is_GLdouble(red), red, 1, "glColor3d", "GLdouble"); Xen_check_type(Xen_is_GLdouble(green), green, 2, "glColor3d", "GLdouble"); Xen_check_type(Xen_is_GLdouble(blue), blue, 3, "glColor3d", "GLdouble"); glColor3d(Xen_to_C_GLdouble(red), Xen_to_C_GLdouble(green), Xen_to_C_GLdouble(blue)); return(Xen_false); } static Xen gxg_glColor3f(Xen red, Xen green, Xen blue) { #define H_glColor3f "void glColor3f(GLfloat red, GLfloat green, GLfloat blue)" Xen_check_type(Xen_is_GLfloat(red), red, 1, "glColor3f", "GLfloat"); Xen_check_type(Xen_is_GLfloat(green), green, 2, "glColor3f", "GLfloat"); Xen_check_type(Xen_is_GLfloat(blue), blue, 3, "glColor3f", "GLfloat"); glColor3f(Xen_to_C_GLfloat(red), Xen_to_C_GLfloat(green), Xen_to_C_GLfloat(blue)); return(Xen_false); } static Xen gxg_glColor3i(Xen red, Xen green, Xen blue) { #define H_glColor3i "void glColor3i(GLint red, GLint green, GLint blue)" Xen_check_type(Xen_is_GLint(red), red, 1, "glColor3i", "GLint"); Xen_check_type(Xen_is_GLint(green), green, 2, "glColor3i", "GLint"); Xen_check_type(Xen_is_GLint(blue), blue, 3, "glColor3i", "GLint"); glColor3i(Xen_to_C_GLint(red), Xen_to_C_GLint(green), Xen_to_C_GLint(blue)); return(Xen_false); } static Xen gxg_glColor3s(Xen red, Xen green, Xen blue) { #define H_glColor3s "void glColor3s(GLshort red, GLshort green, GLshort blue)" Xen_check_type(Xen_is_GLshort(red), red, 1, "glColor3s", "GLshort"); Xen_check_type(Xen_is_GLshort(green), green, 2, "glColor3s", "GLshort"); Xen_check_type(Xen_is_GLshort(blue), blue, 3, "glColor3s", "GLshort"); glColor3s(Xen_to_C_GLshort(red), Xen_to_C_GLshort(green), Xen_to_C_GLshort(blue)); return(Xen_false); } static Xen gxg_glColor3ub(Xen red, Xen green, Xen blue) { #define H_glColor3ub "void glColor3ub(GLubyte red, GLubyte green, GLubyte blue)" Xen_check_type(Xen_is_GLubyte(red), red, 1, "glColor3ub", "GLubyte"); Xen_check_type(Xen_is_GLubyte(green), green, 2, "glColor3ub", "GLubyte"); Xen_check_type(Xen_is_GLubyte(blue), blue, 3, "glColor3ub", "GLubyte"); glColor3ub(Xen_to_C_GLubyte(red), Xen_to_C_GLubyte(green), Xen_to_C_GLubyte(blue)); return(Xen_false); } static Xen gxg_glColor3ui(Xen red, Xen green, Xen blue) { #define H_glColor3ui "void glColor3ui(GLuint red, GLuint green, GLuint blue)" Xen_check_type(Xen_is_GLuint(red), red, 1, "glColor3ui", "GLuint"); Xen_check_type(Xen_is_GLuint(green), green, 2, "glColor3ui", "GLuint"); Xen_check_type(Xen_is_GLuint(blue), blue, 3, "glColor3ui", "GLuint"); glColor3ui(Xen_to_C_GLuint(red), Xen_to_C_GLuint(green), Xen_to_C_GLuint(blue)); return(Xen_false); } static Xen gxg_glColor3us(Xen red, Xen green, Xen blue) { #define H_glColor3us "void glColor3us(GLushort red, GLushort green, GLushort blue)" Xen_check_type(Xen_is_GLushort(red), red, 1, "glColor3us", "GLushort"); Xen_check_type(Xen_is_GLushort(green), green, 2, "glColor3us", "GLushort"); Xen_check_type(Xen_is_GLushort(blue), blue, 3, "glColor3us", "GLushort"); glColor3us(Xen_to_C_GLushort(red), Xen_to_C_GLushort(green), Xen_to_C_GLushort(blue)); return(Xen_false); } static Xen gxg_glColor4b(Xen red, Xen green, Xen blue, Xen alpha) { #define H_glColor4b "void glColor4b(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha)" Xen_check_type(Xen_is_GLbyte(red), red, 1, "glColor4b", "GLbyte"); Xen_check_type(Xen_is_GLbyte(green), green, 2, "glColor4b", "GLbyte"); Xen_check_type(Xen_is_GLbyte(blue), blue, 3, "glColor4b", "GLbyte"); Xen_check_type(Xen_is_GLbyte(alpha), alpha, 4, "glColor4b", "GLbyte"); glColor4b(Xen_to_C_GLbyte(red), Xen_to_C_GLbyte(green), Xen_to_C_GLbyte(blue), Xen_to_C_GLbyte(alpha)); return(Xen_false); } static Xen gxg_glColor4d(Xen red, Xen green, Xen blue, Xen alpha) { #define H_glColor4d "void glColor4d(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha)" Xen_check_type(Xen_is_GLdouble(red), red, 1, "glColor4d", "GLdouble"); Xen_check_type(Xen_is_GLdouble(green), green, 2, "glColor4d", "GLdouble"); Xen_check_type(Xen_is_GLdouble(blue), blue, 3, "glColor4d", "GLdouble"); Xen_check_type(Xen_is_GLdouble(alpha), alpha, 4, "glColor4d", "GLdouble"); glColor4d(Xen_to_C_GLdouble(red), Xen_to_C_GLdouble(green), Xen_to_C_GLdouble(blue), Xen_to_C_GLdouble(alpha)); return(Xen_false); } static Xen gxg_glColor4f(Xen red, Xen green, Xen blue, Xen alpha) { #define H_glColor4f "void glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)" Xen_check_type(Xen_is_GLfloat(red), red, 1, "glColor4f", "GLfloat"); Xen_check_type(Xen_is_GLfloat(green), green, 2, "glColor4f", "GLfloat"); Xen_check_type(Xen_is_GLfloat(blue), blue, 3, "glColor4f", "GLfloat"); Xen_check_type(Xen_is_GLfloat(alpha), alpha, 4, "glColor4f", "GLfloat"); glColor4f(Xen_to_C_GLfloat(red), Xen_to_C_GLfloat(green), Xen_to_C_GLfloat(blue), Xen_to_C_GLfloat(alpha)); return(Xen_false); } static Xen gxg_glColor4i(Xen red, Xen green, Xen blue, Xen alpha) { #define H_glColor4i "void glColor4i(GLint red, GLint green, GLint blue, GLint alpha)" Xen_check_type(Xen_is_GLint(red), red, 1, "glColor4i", "GLint"); Xen_check_type(Xen_is_GLint(green), green, 2, "glColor4i", "GLint"); Xen_check_type(Xen_is_GLint(blue), blue, 3, "glColor4i", "GLint"); Xen_check_type(Xen_is_GLint(alpha), alpha, 4, "glColor4i", "GLint"); glColor4i(Xen_to_C_GLint(red), Xen_to_C_GLint(green), Xen_to_C_GLint(blue), Xen_to_C_GLint(alpha)); return(Xen_false); } static Xen gxg_glColor4s(Xen red, Xen green, Xen blue, Xen alpha) { #define H_glColor4s "void glColor4s(GLshort red, GLshort green, GLshort blue, GLshort alpha)" Xen_check_type(Xen_is_GLshort(red), red, 1, "glColor4s", "GLshort"); Xen_check_type(Xen_is_GLshort(green), green, 2, "glColor4s", "GLshort"); Xen_check_type(Xen_is_GLshort(blue), blue, 3, "glColor4s", "GLshort"); Xen_check_type(Xen_is_GLshort(alpha), alpha, 4, "glColor4s", "GLshort"); glColor4s(Xen_to_C_GLshort(red), Xen_to_C_GLshort(green), Xen_to_C_GLshort(blue), Xen_to_C_GLshort(alpha)); return(Xen_false); } static Xen gxg_glColor4ub(Xen red, Xen green, Xen blue, Xen alpha) { #define H_glColor4ub "void glColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)" Xen_check_type(Xen_is_GLubyte(red), red, 1, "glColor4ub", "GLubyte"); Xen_check_type(Xen_is_GLubyte(green), green, 2, "glColor4ub", "GLubyte"); Xen_check_type(Xen_is_GLubyte(blue), blue, 3, "glColor4ub", "GLubyte"); Xen_check_type(Xen_is_GLubyte(alpha), alpha, 4, "glColor4ub", "GLubyte"); glColor4ub(Xen_to_C_GLubyte(red), Xen_to_C_GLubyte(green), Xen_to_C_GLubyte(blue), Xen_to_C_GLubyte(alpha)); return(Xen_false); } static Xen gxg_glColor4ui(Xen red, Xen green, Xen blue, Xen alpha) { #define H_glColor4ui "void glColor4ui(GLuint red, GLuint green, GLuint blue, GLuint alpha)" Xen_check_type(Xen_is_GLuint(red), red, 1, "glColor4ui", "GLuint"); Xen_check_type(Xen_is_GLuint(green), green, 2, "glColor4ui", "GLuint"); Xen_check_type(Xen_is_GLuint(blue), blue, 3, "glColor4ui", "GLuint"); Xen_check_type(Xen_is_GLuint(alpha), alpha, 4, "glColor4ui", "GLuint"); glColor4ui(Xen_to_C_GLuint(red), Xen_to_C_GLuint(green), Xen_to_C_GLuint(blue), Xen_to_C_GLuint(alpha)); return(Xen_false); } static Xen gxg_glColor4us(Xen red, Xen green, Xen blue, Xen alpha) { #define H_glColor4us "void glColor4us(GLushort red, GLushort green, GLushort blue, GLushort alpha)" Xen_check_type(Xen_is_GLushort(red), red, 1, "glColor4us", "GLushort"); Xen_check_type(Xen_is_GLushort(green), green, 2, "glColor4us", "GLushort"); Xen_check_type(Xen_is_GLushort(blue), blue, 3, "glColor4us", "GLushort"); Xen_check_type(Xen_is_GLushort(alpha), alpha, 4, "glColor4us", "GLushort"); glColor4us(Xen_to_C_GLushort(red), Xen_to_C_GLushort(green), Xen_to_C_GLushort(blue), Xen_to_C_GLushort(alpha)); return(Xen_false); } static Xen gxg_glTexCoord1d(Xen s) { #define H_glTexCoord1d "void glTexCoord1d(GLdouble s)" Xen_check_type(Xen_is_GLdouble(s), s, 1, "glTexCoord1d", "GLdouble"); glTexCoord1d(Xen_to_C_GLdouble(s)); return(Xen_false); } static Xen gxg_glTexCoord1f(Xen s) { #define H_glTexCoord1f "void glTexCoord1f(GLfloat s)" Xen_check_type(Xen_is_GLfloat(s), s, 1, "glTexCoord1f", "GLfloat"); glTexCoord1f(Xen_to_C_GLfloat(s)); return(Xen_false); } static Xen gxg_glTexCoord1i(Xen s) { #define H_glTexCoord1i "void glTexCoord1i(GLint s)" Xen_check_type(Xen_is_GLint(s), s, 1, "glTexCoord1i", "GLint"); glTexCoord1i(Xen_to_C_GLint(s)); return(Xen_false); } static Xen gxg_glTexCoord1s(Xen s) { #define H_glTexCoord1s "void glTexCoord1s(GLshort s)" Xen_check_type(Xen_is_GLshort(s), s, 1, "glTexCoord1s", "GLshort"); glTexCoord1s(Xen_to_C_GLshort(s)); return(Xen_false); } static Xen gxg_glTexCoord2d(Xen s, Xen t) { #define H_glTexCoord2d "void glTexCoord2d(GLdouble s, GLdouble t)" Xen_check_type(Xen_is_GLdouble(s), s, 1, "glTexCoord2d", "GLdouble"); Xen_check_type(Xen_is_GLdouble(t), t, 2, "glTexCoord2d", "GLdouble"); glTexCoord2d(Xen_to_C_GLdouble(s), Xen_to_C_GLdouble(t)); return(Xen_false); } static Xen gxg_glTexCoord2f(Xen s, Xen t) { #define H_glTexCoord2f "void glTexCoord2f(GLfloat s, GLfloat t)" Xen_check_type(Xen_is_GLfloat(s), s, 1, "glTexCoord2f", "GLfloat"); Xen_check_type(Xen_is_GLfloat(t), t, 2, "glTexCoord2f", "GLfloat"); glTexCoord2f(Xen_to_C_GLfloat(s), Xen_to_C_GLfloat(t)); return(Xen_false); } static Xen gxg_glTexCoord2i(Xen s, Xen t) { #define H_glTexCoord2i "void glTexCoord2i(GLint s, GLint t)" Xen_check_type(Xen_is_GLint(s), s, 1, "glTexCoord2i", "GLint"); Xen_check_type(Xen_is_GLint(t), t, 2, "glTexCoord2i", "GLint"); glTexCoord2i(Xen_to_C_GLint(s), Xen_to_C_GLint(t)); return(Xen_false); } static Xen gxg_glTexCoord2s(Xen s, Xen t) { #define H_glTexCoord2s "void glTexCoord2s(GLshort s, GLshort t)" Xen_check_type(Xen_is_GLshort(s), s, 1, "glTexCoord2s", "GLshort"); Xen_check_type(Xen_is_GLshort(t), t, 2, "glTexCoord2s", "GLshort"); glTexCoord2s(Xen_to_C_GLshort(s), Xen_to_C_GLshort(t)); return(Xen_false); } static Xen gxg_glTexCoord3d(Xen s, Xen t, Xen r) { #define H_glTexCoord3d "void glTexCoord3d(GLdouble s, GLdouble t, GLdouble r)" Xen_check_type(Xen_is_GLdouble(s), s, 1, "glTexCoord3d", "GLdouble"); Xen_check_type(Xen_is_GLdouble(t), t, 2, "glTexCoord3d", "GLdouble"); Xen_check_type(Xen_is_GLdouble(r), r, 3, "glTexCoord3d", "GLdouble"); glTexCoord3d(Xen_to_C_GLdouble(s), Xen_to_C_GLdouble(t), Xen_to_C_GLdouble(r)); return(Xen_false); } static Xen gxg_glTexCoord3f(Xen s, Xen t, Xen r) { #define H_glTexCoord3f "void glTexCoord3f(GLfloat s, GLfloat t, GLfloat r)" Xen_check_type(Xen_is_GLfloat(s), s, 1, "glTexCoord3f", "GLfloat"); Xen_check_type(Xen_is_GLfloat(t), t, 2, "glTexCoord3f", "GLfloat"); Xen_check_type(Xen_is_GLfloat(r), r, 3, "glTexCoord3f", "GLfloat"); glTexCoord3f(Xen_to_C_GLfloat(s), Xen_to_C_GLfloat(t), Xen_to_C_GLfloat(r)); return(Xen_false); } static Xen gxg_glTexCoord3i(Xen s, Xen t, Xen r) { #define H_glTexCoord3i "void glTexCoord3i(GLint s, GLint t, GLint r)" Xen_check_type(Xen_is_GLint(s), s, 1, "glTexCoord3i", "GLint"); Xen_check_type(Xen_is_GLint(t), t, 2, "glTexCoord3i", "GLint"); Xen_check_type(Xen_is_GLint(r), r, 3, "glTexCoord3i", "GLint"); glTexCoord3i(Xen_to_C_GLint(s), Xen_to_C_GLint(t), Xen_to_C_GLint(r)); return(Xen_false); } static Xen gxg_glTexCoord3s(Xen s, Xen t, Xen r) { #define H_glTexCoord3s "void glTexCoord3s(GLshort s, GLshort t, GLshort r)" Xen_check_type(Xen_is_GLshort(s), s, 1, "glTexCoord3s", "GLshort"); Xen_check_type(Xen_is_GLshort(t), t, 2, "glTexCoord3s", "GLshort"); Xen_check_type(Xen_is_GLshort(r), r, 3, "glTexCoord3s", "GLshort"); glTexCoord3s(Xen_to_C_GLshort(s), Xen_to_C_GLshort(t), Xen_to_C_GLshort(r)); return(Xen_false); } static Xen gxg_glTexCoord4d(Xen s, Xen t, Xen r, Xen q) { #define H_glTexCoord4d "void glTexCoord4d(GLdouble s, GLdouble t, GLdouble r, GLdouble q)" Xen_check_type(Xen_is_GLdouble(s), s, 1, "glTexCoord4d", "GLdouble"); Xen_check_type(Xen_is_GLdouble(t), t, 2, "glTexCoord4d", "GLdouble"); Xen_check_type(Xen_is_GLdouble(r), r, 3, "glTexCoord4d", "GLdouble"); Xen_check_type(Xen_is_GLdouble(q), q, 4, "glTexCoord4d", "GLdouble"); glTexCoord4d(Xen_to_C_GLdouble(s), Xen_to_C_GLdouble(t), Xen_to_C_GLdouble(r), Xen_to_C_GLdouble(q)); return(Xen_false); } static Xen gxg_glTexCoord4f(Xen s, Xen t, Xen r, Xen q) { #define H_glTexCoord4f "void glTexCoord4f(GLfloat s, GLfloat t, GLfloat r, GLfloat q)" Xen_check_type(Xen_is_GLfloat(s), s, 1, "glTexCoord4f", "GLfloat"); Xen_check_type(Xen_is_GLfloat(t), t, 2, "glTexCoord4f", "GLfloat"); Xen_check_type(Xen_is_GLfloat(r), r, 3, "glTexCoord4f", "GLfloat"); Xen_check_type(Xen_is_GLfloat(q), q, 4, "glTexCoord4f", "GLfloat"); glTexCoord4f(Xen_to_C_GLfloat(s), Xen_to_C_GLfloat(t), Xen_to_C_GLfloat(r), Xen_to_C_GLfloat(q)); return(Xen_false); } static Xen gxg_glTexCoord4i(Xen s, Xen t, Xen r, Xen q) { #define H_glTexCoord4i "void glTexCoord4i(GLint s, GLint t, GLint r, GLint q)" Xen_check_type(Xen_is_GLint(s), s, 1, "glTexCoord4i", "GLint"); Xen_check_type(Xen_is_GLint(t), t, 2, "glTexCoord4i", "GLint"); Xen_check_type(Xen_is_GLint(r), r, 3, "glTexCoord4i", "GLint"); Xen_check_type(Xen_is_GLint(q), q, 4, "glTexCoord4i", "GLint"); glTexCoord4i(Xen_to_C_GLint(s), Xen_to_C_GLint(t), Xen_to_C_GLint(r), Xen_to_C_GLint(q)); return(Xen_false); } static Xen gxg_glTexCoord4s(Xen s, Xen t, Xen r, Xen q) { #define H_glTexCoord4s "void glTexCoord4s(GLshort s, GLshort t, GLshort r, GLshort q)" Xen_check_type(Xen_is_GLshort(s), s, 1, "glTexCoord4s", "GLshort"); Xen_check_type(Xen_is_GLshort(t), t, 2, "glTexCoord4s", "GLshort"); Xen_check_type(Xen_is_GLshort(r), r, 3, "glTexCoord4s", "GLshort"); Xen_check_type(Xen_is_GLshort(q), q, 4, "glTexCoord4s", "GLshort"); glTexCoord4s(Xen_to_C_GLshort(s), Xen_to_C_GLshort(t), Xen_to_C_GLshort(r), Xen_to_C_GLshort(q)); return(Xen_false); } static Xen gxg_glRasterPos2d(Xen x, Xen y) { #define H_glRasterPos2d "void glRasterPos2d(GLdouble x, GLdouble y)" Xen_check_type(Xen_is_GLdouble(x), x, 1, "glRasterPos2d", "GLdouble"); Xen_check_type(Xen_is_GLdouble(y), y, 2, "glRasterPos2d", "GLdouble"); glRasterPos2d(Xen_to_C_GLdouble(x), Xen_to_C_GLdouble(y)); return(Xen_false); } static Xen gxg_glRasterPos2f(Xen x, Xen y) { #define H_glRasterPos2f "void glRasterPos2f(GLfloat x, GLfloat y)" Xen_check_type(Xen_is_GLfloat(x), x, 1, "glRasterPos2f", "GLfloat"); Xen_check_type(Xen_is_GLfloat(y), y, 2, "glRasterPos2f", "GLfloat"); glRasterPos2f(Xen_to_C_GLfloat(x), Xen_to_C_GLfloat(y)); return(Xen_false); } static Xen gxg_glRasterPos2i(Xen x, Xen y) { #define H_glRasterPos2i "void glRasterPos2i(GLint x, GLint y)" Xen_check_type(Xen_is_GLint(x), x, 1, "glRasterPos2i", "GLint"); Xen_check_type(Xen_is_GLint(y), y, 2, "glRasterPos2i", "GLint"); glRasterPos2i(Xen_to_C_GLint(x), Xen_to_C_GLint(y)); return(Xen_false); } static Xen gxg_glRasterPos2s(Xen x, Xen y) { #define H_glRasterPos2s "void glRasterPos2s(GLshort x, GLshort y)" Xen_check_type(Xen_is_GLshort(x), x, 1, "glRasterPos2s", "GLshort"); Xen_check_type(Xen_is_GLshort(y), y, 2, "glRasterPos2s", "GLshort"); glRasterPos2s(Xen_to_C_GLshort(x), Xen_to_C_GLshort(y)); return(Xen_false); } static Xen gxg_glRasterPos3d(Xen x, Xen y, Xen z) { #define H_glRasterPos3d "void glRasterPos3d(GLdouble x, GLdouble y, GLdouble z)" Xen_check_type(Xen_is_GLdouble(x), x, 1, "glRasterPos3d", "GLdouble"); Xen_check_type(Xen_is_GLdouble(y), y, 2, "glRasterPos3d", "GLdouble"); Xen_check_type(Xen_is_GLdouble(z), z, 3, "glRasterPos3d", "GLdouble"); glRasterPos3d(Xen_to_C_GLdouble(x), Xen_to_C_GLdouble(y), Xen_to_C_GLdouble(z)); return(Xen_false); } static Xen gxg_glRasterPos3f(Xen x, Xen y, Xen z) { #define H_glRasterPos3f "void glRasterPos3f(GLfloat x, GLfloat y, GLfloat z)" Xen_check_type(Xen_is_GLfloat(x), x, 1, "glRasterPos3f", "GLfloat"); Xen_check_type(Xen_is_GLfloat(y), y, 2, "glRasterPos3f", "GLfloat"); Xen_check_type(Xen_is_GLfloat(z), z, 3, "glRasterPos3f", "GLfloat"); glRasterPos3f(Xen_to_C_GLfloat(x), Xen_to_C_GLfloat(y), Xen_to_C_GLfloat(z)); return(Xen_false); } static Xen gxg_glRasterPos3i(Xen x, Xen y, Xen z) { #define H_glRasterPos3i "void glRasterPos3i(GLint x, GLint y, GLint z)" Xen_check_type(Xen_is_GLint(x), x, 1, "glRasterPos3i", "GLint"); Xen_check_type(Xen_is_GLint(y), y, 2, "glRasterPos3i", "GLint"); Xen_check_type(Xen_is_GLint(z), z, 3, "glRasterPos3i", "GLint"); glRasterPos3i(Xen_to_C_GLint(x), Xen_to_C_GLint(y), Xen_to_C_GLint(z)); return(Xen_false); } static Xen gxg_glRasterPos3s(Xen x, Xen y, Xen z) { #define H_glRasterPos3s "void glRasterPos3s(GLshort x, GLshort y, GLshort z)" Xen_check_type(Xen_is_GLshort(x), x, 1, "glRasterPos3s", "GLshort"); Xen_check_type(Xen_is_GLshort(y), y, 2, "glRasterPos3s", "GLshort"); Xen_check_type(Xen_is_GLshort(z), z, 3, "glRasterPos3s", "GLshort"); glRasterPos3s(Xen_to_C_GLshort(x), Xen_to_C_GLshort(y), Xen_to_C_GLshort(z)); return(Xen_false); } static Xen gxg_glRasterPos4d(Xen x, Xen y, Xen z, Xen w) { #define H_glRasterPos4d "void glRasterPos4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w)" Xen_check_type(Xen_is_GLdouble(x), x, 1, "glRasterPos4d", "GLdouble"); Xen_check_type(Xen_is_GLdouble(y), y, 2, "glRasterPos4d", "GLdouble"); Xen_check_type(Xen_is_GLdouble(z), z, 3, "glRasterPos4d", "GLdouble"); Xen_check_type(Xen_is_GLdouble(w), w, 4, "glRasterPos4d", "GLdouble"); glRasterPos4d(Xen_to_C_GLdouble(x), Xen_to_C_GLdouble(y), Xen_to_C_GLdouble(z), Xen_to_C_GLdouble(w)); return(Xen_false); } static Xen gxg_glRasterPos4f(Xen x, Xen y, Xen z, Xen w) { #define H_glRasterPos4f "void glRasterPos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)" Xen_check_type(Xen_is_GLfloat(x), x, 1, "glRasterPos4f", "GLfloat"); Xen_check_type(Xen_is_GLfloat(y), y, 2, "glRasterPos4f", "GLfloat"); Xen_check_type(Xen_is_GLfloat(z), z, 3, "glRasterPos4f", "GLfloat"); Xen_check_type(Xen_is_GLfloat(w), w, 4, "glRasterPos4f", "GLfloat"); glRasterPos4f(Xen_to_C_GLfloat(x), Xen_to_C_GLfloat(y), Xen_to_C_GLfloat(z), Xen_to_C_GLfloat(w)); return(Xen_false); } static Xen gxg_glRasterPos4i(Xen x, Xen y, Xen z, Xen w) { #define H_glRasterPos4i "void glRasterPos4i(GLint x, GLint y, GLint z, GLint w)" Xen_check_type(Xen_is_GLint(x), x, 1, "glRasterPos4i", "GLint"); Xen_check_type(Xen_is_GLint(y), y, 2, "glRasterPos4i", "GLint"); Xen_check_type(Xen_is_GLint(z), z, 3, "glRasterPos4i", "GLint"); Xen_check_type(Xen_is_GLint(w), w, 4, "glRasterPos4i", "GLint"); glRasterPos4i(Xen_to_C_GLint(x), Xen_to_C_GLint(y), Xen_to_C_GLint(z), Xen_to_C_GLint(w)); return(Xen_false); } static Xen gxg_glRasterPos4s(Xen x, Xen y, Xen z, Xen w) { #define H_glRasterPos4s "void glRasterPos4s(GLshort x, GLshort y, GLshort z, GLshort w)" Xen_check_type(Xen_is_GLshort(x), x, 1, "glRasterPos4s", "GLshort"); Xen_check_type(Xen_is_GLshort(y), y, 2, "glRasterPos4s", "GLshort"); Xen_check_type(Xen_is_GLshort(z), z, 3, "glRasterPos4s", "GLshort"); Xen_check_type(Xen_is_GLshort(w), w, 4, "glRasterPos4s", "GLshort"); glRasterPos4s(Xen_to_C_GLshort(x), Xen_to_C_GLshort(y), Xen_to_C_GLshort(z), Xen_to_C_GLshort(w)); return(Xen_false); } static Xen gxg_glRectd(Xen x1, Xen y1, Xen x2, Xen y2) { #define H_glRectd "void glRectd(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2)" Xen_check_type(Xen_is_GLdouble(x1), x1, 1, "glRectd", "GLdouble"); Xen_check_type(Xen_is_GLdouble(y1), y1, 2, "glRectd", "GLdouble"); Xen_check_type(Xen_is_GLdouble(x2), x2, 3, "glRectd", "GLdouble"); Xen_check_type(Xen_is_GLdouble(y2), y2, 4, "glRectd", "GLdouble"); glRectd(Xen_to_C_GLdouble(x1), Xen_to_C_GLdouble(y1), Xen_to_C_GLdouble(x2), Xen_to_C_GLdouble(y2)); return(Xen_false); } static Xen gxg_glRectf(Xen x1, Xen y1, Xen x2, Xen y2) { #define H_glRectf "void glRectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)" Xen_check_type(Xen_is_GLfloat(x1), x1, 1, "glRectf", "GLfloat"); Xen_check_type(Xen_is_GLfloat(y1), y1, 2, "glRectf", "GLfloat"); Xen_check_type(Xen_is_GLfloat(x2), x2, 3, "glRectf", "GLfloat"); Xen_check_type(Xen_is_GLfloat(y2), y2, 4, "glRectf", "GLfloat"); glRectf(Xen_to_C_GLfloat(x1), Xen_to_C_GLfloat(y1), Xen_to_C_GLfloat(x2), Xen_to_C_GLfloat(y2)); return(Xen_false); } static Xen gxg_glRecti(Xen x1, Xen y1, Xen x2, Xen y2) { #define H_glRecti "void glRecti(GLint x1, GLint y1, GLint x2, GLint y2)" Xen_check_type(Xen_is_GLint(x1), x1, 1, "glRecti", "GLint"); Xen_check_type(Xen_is_GLint(y1), y1, 2, "glRecti", "GLint"); Xen_check_type(Xen_is_GLint(x2), x2, 3, "glRecti", "GLint"); Xen_check_type(Xen_is_GLint(y2), y2, 4, "glRecti", "GLint"); glRecti(Xen_to_C_GLint(x1), Xen_to_C_GLint(y1), Xen_to_C_GLint(x2), Xen_to_C_GLint(y2)); return(Xen_false); } static Xen gxg_glRects(Xen x1, Xen y1, Xen x2, Xen y2) { #define H_glRects "void glRects(GLshort x1, GLshort y1, GLshort x2, GLshort y2)" Xen_check_type(Xen_is_GLshort(x1), x1, 1, "glRects", "GLshort"); Xen_check_type(Xen_is_GLshort(y1), y1, 2, "glRects", "GLshort"); Xen_check_type(Xen_is_GLshort(x2), x2, 3, "glRects", "GLshort"); Xen_check_type(Xen_is_GLshort(y2), y2, 4, "glRects", "GLshort"); glRects(Xen_to_C_GLshort(x1), Xen_to_C_GLshort(y1), Xen_to_C_GLshort(x2), Xen_to_C_GLshort(y2)); return(Xen_false); } static Xen gxg_glVertexPointer(Xen size, Xen type, Xen stride, Xen ptr) { #define H_glVertexPointer "void glVertexPointer(GLint size, GLenum type, GLsizei stride, GLvoid* ptr)" Xen_check_type(Xen_is_GLint(size), size, 1, "glVertexPointer", "GLint"); Xen_check_type(Xen_is_GLenum(type), type, 2, "glVertexPointer", "GLenum"); Xen_check_type(Xen_is_GLsizei(stride), stride, 3, "glVertexPointer", "GLsizei"); Xen_check_type(Xen_is_GLvoid_(ptr), ptr, 4, "glVertexPointer", "GLvoid*"); glVertexPointer(Xen_to_C_GLint(size), Xen_to_C_GLenum(type), Xen_to_C_GLsizei(stride), Xen_to_C_GLvoid_(ptr)); return(Xen_false); } static Xen gxg_glNormalPointer(Xen type, Xen stride, Xen ptr) { #define H_glNormalPointer "void glNormalPointer(GLenum type, GLsizei stride, GLvoid* ptr)" Xen_check_type(Xen_is_GLenum(type), type, 1, "glNormalPointer", "GLenum"); Xen_check_type(Xen_is_GLsizei(stride), stride, 2, "glNormalPointer", "GLsizei"); Xen_check_type(Xen_is_GLvoid_(ptr), ptr, 3, "glNormalPointer", "GLvoid*"); glNormalPointer(Xen_to_C_GLenum(type), Xen_to_C_GLsizei(stride), Xen_to_C_GLvoid_(ptr)); return(Xen_false); } static Xen gxg_glColorPointer(Xen size, Xen type, Xen stride, Xen ptr) { #define H_glColorPointer "void glColorPointer(GLint size, GLenum type, GLsizei stride, GLvoid* ptr)" Xen_check_type(Xen_is_GLint(size), size, 1, "glColorPointer", "GLint"); Xen_check_type(Xen_is_GLenum(type), type, 2, "glColorPointer", "GLenum"); Xen_check_type(Xen_is_GLsizei(stride), stride, 3, "glColorPointer", "GLsizei"); Xen_check_type(Xen_is_GLvoid_(ptr), ptr, 4, "glColorPointer", "GLvoid*"); glColorPointer(Xen_to_C_GLint(size), Xen_to_C_GLenum(type), Xen_to_C_GLsizei(stride), Xen_to_C_GLvoid_(ptr)); return(Xen_false); } static Xen gxg_glIndexPointer(Xen type, Xen stride, Xen ptr) { #define H_glIndexPointer "void glIndexPointer(GLenum type, GLsizei stride, GLvoid* ptr)" Xen_check_type(Xen_is_GLenum(type), type, 1, "glIndexPointer", "GLenum"); Xen_check_type(Xen_is_GLsizei(stride), stride, 2, "glIndexPointer", "GLsizei"); Xen_check_type(Xen_is_GLvoid_(ptr), ptr, 3, "glIndexPointer", "GLvoid*"); glIndexPointer(Xen_to_C_GLenum(type), Xen_to_C_GLsizei(stride), Xen_to_C_GLvoid_(ptr)); return(Xen_false); } static Xen gxg_glTexCoordPointer(Xen size, Xen type, Xen stride, Xen ptr) { #define H_glTexCoordPointer "void glTexCoordPointer(GLint size, GLenum type, GLsizei stride, GLvoid* ptr)" Xen_check_type(Xen_is_GLint(size), size, 1, "glTexCoordPointer", "GLint"); Xen_check_type(Xen_is_GLenum(type), type, 2, "glTexCoordPointer", "GLenum"); Xen_check_type(Xen_is_GLsizei(stride), stride, 3, "glTexCoordPointer", "GLsizei"); Xen_check_type(Xen_is_GLvoid_(ptr), ptr, 4, "glTexCoordPointer", "GLvoid*"); glTexCoordPointer(Xen_to_C_GLint(size), Xen_to_C_GLenum(type), Xen_to_C_GLsizei(stride), Xen_to_C_GLvoid_(ptr)); return(Xen_false); } static Xen gxg_glEdgeFlagPointer(Xen stride, Xen ptr) { #define H_glEdgeFlagPointer "void glEdgeFlagPointer(GLsizei stride, GLvoid* ptr)" Xen_check_type(Xen_is_GLsizei(stride), stride, 1, "glEdgeFlagPointer", "GLsizei"); Xen_check_type(Xen_is_GLvoid_(ptr), ptr, 2, "glEdgeFlagPointer", "GLvoid*"); glEdgeFlagPointer(Xen_to_C_GLsizei(stride), Xen_to_C_GLvoid_(ptr)); return(Xen_false); } static Xen gxg_glGetPointerv(Xen pname, Xen params) { #define H_glGetPointerv "void glGetPointerv(GLenum pname, void** [params])" void* ref_params[1]; Xen_check_type(Xen_is_GLenum(pname), pname, 1, "glGetPointerv", "GLenum"); glGetPointerv(Xen_to_C_GLenum(pname), ref_params); return(Xen_list_1(C_to_Xen_void_(ref_params[0]))); } static Xen gxg_glArrayElement(Xen i) { #define H_glArrayElement "void glArrayElement(GLint i)" Xen_check_type(Xen_is_GLint(i), i, 1, "glArrayElement", "GLint"); glArrayElement(Xen_to_C_GLint(i)); return(Xen_false); } static Xen gxg_glDrawArrays(Xen mode, Xen first, Xen count) { #define H_glDrawArrays "void glDrawArrays(GLenum mode, GLint first, GLsizei count)" Xen_check_type(Xen_is_GLenum(mode), mode, 1, "glDrawArrays", "GLenum"); Xen_check_type(Xen_is_GLint(first), first, 2, "glDrawArrays", "GLint"); Xen_check_type(Xen_is_GLsizei(count), count, 3, "glDrawArrays", "GLsizei"); glDrawArrays(Xen_to_C_GLenum(mode), Xen_to_C_GLint(first), Xen_to_C_GLsizei(count)); return(Xen_false); } static Xen gxg_glDrawElements(Xen mode, Xen count, Xen type, Xen indices) { #define H_glDrawElements "void glDrawElements(GLenum mode, GLsizei count, GLenum type, GLvoid* indices)" Xen_check_type(Xen_is_GLenum(mode), mode, 1, "glDrawElements", "GLenum"); Xen_check_type(Xen_is_GLsizei(count), count, 2, "glDrawElements", "GLsizei"); Xen_check_type(Xen_is_GLenum(type), type, 3, "glDrawElements", "GLenum"); Xen_check_type(Xen_is_GLvoid_(indices), indices, 4, "glDrawElements", "GLvoid*"); glDrawElements(Xen_to_C_GLenum(mode), Xen_to_C_GLsizei(count), Xen_to_C_GLenum(type), Xen_to_C_GLvoid_(indices)); return(Xen_false); } static Xen gxg_glInterleavedArrays(Xen format, Xen stride, Xen pointer) { #define H_glInterleavedArrays "void glInterleavedArrays(GLenum format, GLsizei stride, GLvoid* pointer)" Xen_check_type(Xen_is_GLenum(format), format, 1, "glInterleavedArrays", "GLenum"); Xen_check_type(Xen_is_GLsizei(stride), stride, 2, "glInterleavedArrays", "GLsizei"); Xen_check_type(Xen_is_GLvoid_(pointer), pointer, 3, "glInterleavedArrays", "GLvoid*"); glInterleavedArrays(Xen_to_C_GLenum(format), Xen_to_C_GLsizei(stride), Xen_to_C_GLvoid_(pointer)); return(Xen_false); } static Xen gxg_glShadeModel(Xen mode) { #define H_glShadeModel "void glShadeModel(GLenum mode)" Xen_check_type(Xen_is_GLenum(mode), mode, 1, "glShadeModel", "GLenum"); glShadeModel(Xen_to_C_GLenum(mode)); return(Xen_false); } static Xen gxg_glLightf(Xen light, Xen pname, Xen param) { #define H_glLightf "void glLightf(GLenum light, GLenum pname, GLfloat param)" Xen_check_type(Xen_is_GLenum(light), light, 1, "glLightf", "GLenum"); Xen_check_type(Xen_is_GLenum(pname), pname, 2, "glLightf", "GLenum"); Xen_check_type(Xen_is_GLfloat(param), param, 3, "glLightf", "GLfloat"); glLightf(Xen_to_C_GLenum(light), Xen_to_C_GLenum(pname), Xen_to_C_GLfloat(param)); return(Xen_false); } static Xen gxg_glLighti(Xen light, Xen pname, Xen param) { #define H_glLighti "void glLighti(GLenum light, GLenum pname, GLint param)" Xen_check_type(Xen_is_GLenum(light), light, 1, "glLighti", "GLenum"); Xen_check_type(Xen_is_GLenum(pname), pname, 2, "glLighti", "GLenum"); Xen_check_type(Xen_is_GLint(param), param, 3, "glLighti", "GLint"); glLighti(Xen_to_C_GLenum(light), Xen_to_C_GLenum(pname), Xen_to_C_GLint(param)); return(Xen_false); } static Xen gxg_glGetLightfv(Xen light, Xen pname, Xen params) { #define H_glGetLightfv "void glGetLightfv(GLenum light, GLenum pname, GLfloat* [params])" GLfloat ref_params[16]; Xen_check_type(Xen_is_GLenum(light), light, 1, "glGetLightfv", "GLenum"); Xen_check_type(Xen_is_GLenum(pname), pname, 2, "glGetLightfv", "GLenum"); glGetLightfv(Xen_to_C_GLenum(light), Xen_to_C_GLenum(pname), ref_params); { Xen result; int i, vals; vals = how_many_vals(Xen_to_C_GLenum(pname)); result = Xen_empty_list; for (i = 0; i < vals; i++) result = Xen_cons(C_to_Xen_GLfloat(ref_params[i]), result); return(result); } } static Xen gxg_glGetLightiv(Xen light, Xen pname, Xen params) { #define H_glGetLightiv "void glGetLightiv(GLenum light, GLenum pname, GLint* [params])" GLint ref_params[1]; Xen_check_type(Xen_is_GLenum(light), light, 1, "glGetLightiv", "GLenum"); Xen_check_type(Xen_is_GLenum(pname), pname, 2, "glGetLightiv", "GLenum"); glGetLightiv(Xen_to_C_GLenum(light), Xen_to_C_GLenum(pname), ref_params); return(Xen_list_1(C_to_Xen_GLint(ref_params[0]))); } static Xen gxg_glLightModelf(Xen pname, Xen param) { #define H_glLightModelf "void glLightModelf(GLenum pname, GLfloat param)" Xen_check_type(Xen_is_GLenum(pname), pname, 1, "glLightModelf", "GLenum"); Xen_check_type(Xen_is_GLfloat(param), param, 2, "glLightModelf", "GLfloat"); glLightModelf(Xen_to_C_GLenum(pname), Xen_to_C_GLfloat(param)); return(Xen_false); } static Xen gxg_glLightModeli(Xen pname, Xen param) { #define H_glLightModeli "void glLightModeli(GLenum pname, GLint param)" Xen_check_type(Xen_is_GLenum(pname), pname, 1, "glLightModeli", "GLenum"); Xen_check_type(Xen_is_GLint(param), param, 2, "glLightModeli", "GLint"); glLightModeli(Xen_to_C_GLenum(pname), Xen_to_C_GLint(param)); return(Xen_false); } static Xen gxg_glMaterialf(Xen face, Xen pname, Xen param) { #define H_glMaterialf "void glMaterialf(GLenum face, GLenum pname, GLfloat param)" Xen_check_type(Xen_is_GLenum(face), face, 1, "glMaterialf", "GLenum"); Xen_check_type(Xen_is_GLenum(pname), pname, 2, "glMaterialf", "GLenum"); Xen_check_type(Xen_is_GLfloat(param), param, 3, "glMaterialf", "GLfloat"); glMaterialf(Xen_to_C_GLenum(face), Xen_to_C_GLenum(pname), Xen_to_C_GLfloat(param)); return(Xen_false); } static Xen gxg_glMateriali(Xen face, Xen pname, Xen param) { #define H_glMateriali "void glMateriali(GLenum face, GLenum pname, GLint param)" Xen_check_type(Xen_is_GLenum(face), face, 1, "glMateriali", "GLenum"); Xen_check_type(Xen_is_GLenum(pname), pname, 2, "glMateriali", "GLenum"); Xen_check_type(Xen_is_GLint(param), param, 3, "glMateriali", "GLint"); glMateriali(Xen_to_C_GLenum(face), Xen_to_C_GLenum(pname), Xen_to_C_GLint(param)); return(Xen_false); } static Xen gxg_glGetMaterialfv(Xen face, Xen pname, Xen params) { #define H_glGetMaterialfv "void glGetMaterialfv(GLenum face, GLenum pname, GLfloat* [params])" GLfloat ref_params[16]; Xen_check_type(Xen_is_GLenum(face), face, 1, "glGetMaterialfv", "GLenum"); Xen_check_type(Xen_is_GLenum(pname), pname, 2, "glGetMaterialfv", "GLenum"); glGetMaterialfv(Xen_to_C_GLenum(face), Xen_to_C_GLenum(pname), ref_params); { Xen result; int i, vals; vals = how_many_vals(Xen_to_C_GLenum(pname)); result = Xen_empty_list; for (i = 0; i < vals; i++) result = Xen_cons(C_to_Xen_GLfloat(ref_params[i]), result); return(result); } } static Xen gxg_glGetMaterialiv(Xen face, Xen pname, Xen params) { #define H_glGetMaterialiv "void glGetMaterialiv(GLenum face, GLenum pname, GLint* [params])" GLint ref_params[1]; Xen_check_type(Xen_is_GLenum(face), face, 1, "glGetMaterialiv", "GLenum"); Xen_check_type(Xen_is_GLenum(pname), pname, 2, "glGetMaterialiv", "GLenum"); glGetMaterialiv(Xen_to_C_GLenum(face), Xen_to_C_GLenum(pname), ref_params); return(Xen_list_1(C_to_Xen_GLint(ref_params[0]))); } static Xen gxg_glColorMaterial(Xen face, Xen mode) { #define H_glColorMaterial "void glColorMaterial(GLenum face, GLenum mode)" Xen_check_type(Xen_is_GLenum(face), face, 1, "glColorMaterial", "GLenum"); Xen_check_type(Xen_is_GLenum(mode), mode, 2, "glColorMaterial", "GLenum"); glColorMaterial(Xen_to_C_GLenum(face), Xen_to_C_GLenum(mode)); return(Xen_false); } static Xen gxg_glPixelZoom(Xen xfactor, Xen yfactor) { #define H_glPixelZoom "void glPixelZoom(GLfloat xfactor, GLfloat yfactor)" Xen_check_type(Xen_is_GLfloat(xfactor), xfactor, 1, "glPixelZoom", "GLfloat"); Xen_check_type(Xen_is_GLfloat(yfactor), yfactor, 2, "glPixelZoom", "GLfloat"); glPixelZoom(Xen_to_C_GLfloat(xfactor), Xen_to_C_GLfloat(yfactor)); return(Xen_false); } static Xen gxg_glPixelStoref(Xen pname, Xen param) { #define H_glPixelStoref "void glPixelStoref(GLenum pname, GLfloat param)" Xen_check_type(Xen_is_GLenum(pname), pname, 1, "glPixelStoref", "GLenum"); Xen_check_type(Xen_is_GLfloat(param), param, 2, "glPixelStoref", "GLfloat"); glPixelStoref(Xen_to_C_GLenum(pname), Xen_to_C_GLfloat(param)); return(Xen_false); } static Xen gxg_glPixelStorei(Xen pname, Xen param) { #define H_glPixelStorei "void glPixelStorei(GLenum pname, GLint param)" Xen_check_type(Xen_is_GLenum(pname), pname, 1, "glPixelStorei", "GLenum"); Xen_check_type(Xen_is_GLint(param), param, 2, "glPixelStorei", "GLint"); glPixelStorei(Xen_to_C_GLenum(pname), Xen_to_C_GLint(param)); return(Xen_false); } static Xen gxg_glPixelTransferf(Xen pname, Xen param) { #define H_glPixelTransferf "void glPixelTransferf(GLenum pname, GLfloat param)" Xen_check_type(Xen_is_GLenum(pname), pname, 1, "glPixelTransferf", "GLenum"); Xen_check_type(Xen_is_GLfloat(param), param, 2, "glPixelTransferf", "GLfloat"); glPixelTransferf(Xen_to_C_GLenum(pname), Xen_to_C_GLfloat(param)); return(Xen_false); } static Xen gxg_glPixelTransferi(Xen pname, Xen param) { #define H_glPixelTransferi "void glPixelTransferi(GLenum pname, GLint param)" Xen_check_type(Xen_is_GLenum(pname), pname, 1, "glPixelTransferi", "GLenum"); Xen_check_type(Xen_is_GLint(param), param, 2, "glPixelTransferi", "GLint"); glPixelTransferi(Xen_to_C_GLenum(pname), Xen_to_C_GLint(param)); return(Xen_false); } static Xen gxg_glGetPixelMapfv(Xen map, Xen values) { #define H_glGetPixelMapfv "void glGetPixelMapfv(GLenum map, GLfloat* [values])" GLfloat ref_values[1]; Xen_check_type(Xen_is_GLenum(map), map, 1, "glGetPixelMapfv", "GLenum"); glGetPixelMapfv(Xen_to_C_GLenum(map), ref_values); return(Xen_list_1(C_to_Xen_GLfloat(ref_values[0]))); } static Xen gxg_glGetPixelMapuiv(Xen map, Xen values) { #define H_glGetPixelMapuiv "void glGetPixelMapuiv(GLenum map, GLuint* [values])" GLuint ref_values[1]; Xen_check_type(Xen_is_GLenum(map), map, 1, "glGetPixelMapuiv", "GLenum"); glGetPixelMapuiv(Xen_to_C_GLenum(map), ref_values); return(Xen_list_1(C_to_Xen_GLuint(ref_values[0]))); } static Xen gxg_glGetPixelMapusv(Xen map, Xen values) { #define H_glGetPixelMapusv "void glGetPixelMapusv(GLenum map, GLushort* [values])" GLushort ref_values[1]; Xen_check_type(Xen_is_GLenum(map), map, 1, "glGetPixelMapusv", "GLenum"); glGetPixelMapusv(Xen_to_C_GLenum(map), ref_values); return(Xen_list_1(C_to_Xen_GLushort(ref_values[0]))); } static Xen gxg_glBitmap(Xen width, Xen height, Xen xorig, Xen yorig, Xen xmove, Xen ymove, Xen bitmap) { #define H_glBitmap "void glBitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, \ GLfloat ymove, GLubyte* bitmap)" Xen_check_type(Xen_is_GLsizei(width), width, 1, "glBitmap", "GLsizei"); Xen_check_type(Xen_is_GLsizei(height), height, 2, "glBitmap", "GLsizei"); Xen_check_type(Xen_is_GLfloat(xorig), xorig, 3, "glBitmap", "GLfloat"); Xen_check_type(Xen_is_GLfloat(yorig), yorig, 4, "glBitmap", "GLfloat"); Xen_check_type(Xen_is_GLfloat(xmove), xmove, 5, "glBitmap", "GLfloat"); Xen_check_type(Xen_is_GLfloat(ymove), ymove, 6, "glBitmap", "GLfloat"); Xen_check_type(Xen_is_GLubyte_(bitmap), bitmap, 7, "glBitmap", "GLubyte*"); glBitmap(Xen_to_C_GLsizei(width), Xen_to_C_GLsizei(height), Xen_to_C_GLfloat(xorig), Xen_to_C_GLfloat(yorig), Xen_to_C_GLfloat(xmove), Xen_to_C_GLfloat(ymove), Xen_to_C_GLubyte_(bitmap)); return(Xen_false); } static Xen gxg_glReadPixels(Xen x, Xen y, Xen width, Xen height, Xen format, Xen type, Xen pixels) { #define H_glReadPixels "void glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, \ GLenum type, GLvoid* pixels)" Xen_check_type(Xen_is_GLint(x), x, 1, "glReadPixels", "GLint"); Xen_check_type(Xen_is_GLint(y), y, 2, "glReadPixels", "GLint"); Xen_check_type(Xen_is_GLsizei(width), width, 3, "glReadPixels", "GLsizei"); Xen_check_type(Xen_is_GLsizei(height), height, 4, "glReadPixels", "GLsizei"); Xen_check_type(Xen_is_GLenum(format), format, 5, "glReadPixels", "GLenum"); Xen_check_type(Xen_is_GLenum(type), type, 6, "glReadPixels", "GLenum"); Xen_check_type(Xen_is_GLvoid_(pixels), pixels, 7, "glReadPixels", "GLvoid*"); glReadPixels(Xen_to_C_GLint(x), Xen_to_C_GLint(y), Xen_to_C_GLsizei(width), Xen_to_C_GLsizei(height), Xen_to_C_GLenum(format), Xen_to_C_GLenum(type), Xen_to_C_GLvoid_(pixels)); return(Xen_false); } static Xen gxg_glDrawPixels(Xen width, Xen height, Xen format, Xen type, Xen pixels) { #define H_glDrawPixels "void glDrawPixels(GLsizei width, GLsizei height, GLenum format, GLenum type, \ GLvoid* pixels)" Xen_check_type(Xen_is_GLsizei(width), width, 1, "glDrawPixels", "GLsizei"); Xen_check_type(Xen_is_GLsizei(height), height, 2, "glDrawPixels", "GLsizei"); Xen_check_type(Xen_is_GLenum(format), format, 3, "glDrawPixels", "GLenum"); Xen_check_type(Xen_is_GLenum(type), type, 4, "glDrawPixels", "GLenum"); Xen_check_type(Xen_is_GLvoid_(pixels), pixels, 5, "glDrawPixels", "GLvoid*"); glDrawPixels(Xen_to_C_GLsizei(width), Xen_to_C_GLsizei(height), Xen_to_C_GLenum(format), Xen_to_C_GLenum(type), Xen_to_C_GLvoid_(pixels)); return(Xen_false); } static Xen gxg_glCopyPixels(Xen x, Xen y, Xen width, Xen height, Xen type) { #define H_glCopyPixels "void glCopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type)" Xen_check_type(Xen_is_GLint(x), x, 1, "glCopyPixels", "GLint"); Xen_check_type(Xen_is_GLint(y), y, 2, "glCopyPixels", "GLint"); Xen_check_type(Xen_is_GLsizei(width), width, 3, "glCopyPixels", "GLsizei"); Xen_check_type(Xen_is_GLsizei(height), height, 4, "glCopyPixels", "GLsizei"); Xen_check_type(Xen_is_GLenum(type), type, 5, "glCopyPixels", "GLenum"); glCopyPixels(Xen_to_C_GLint(x), Xen_to_C_GLint(y), Xen_to_C_GLsizei(width), Xen_to_C_GLsizei(height), Xen_to_C_GLenum(type)); return(Xen_false); } static Xen gxg_glStencilFunc(Xen func, Xen ref, Xen mask) { #define H_glStencilFunc "void glStencilFunc(GLenum func, GLint ref, GLuint mask)" Xen_check_type(Xen_is_GLenum(func), func, 1, "glStencilFunc", "GLenum"); Xen_check_type(Xen_is_GLint(ref), ref, 2, "glStencilFunc", "GLint"); Xen_check_type(Xen_is_GLuint(mask), mask, 3, "glStencilFunc", "GLuint"); glStencilFunc(Xen_to_C_GLenum(func), Xen_to_C_GLint(ref), Xen_to_C_GLuint(mask)); return(Xen_false); } static Xen gxg_glStencilMask(Xen mask) { #define H_glStencilMask "void glStencilMask(GLuint mask)" Xen_check_type(Xen_is_GLuint(mask), mask, 1, "glStencilMask", "GLuint"); glStencilMask(Xen_to_C_GLuint(mask)); return(Xen_false); } static Xen gxg_glStencilOp(Xen fail, Xen zfail, Xen zpass) { #define H_glStencilOp "void glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)" Xen_check_type(Xen_is_GLenum(fail), fail, 1, "glStencilOp", "GLenum"); Xen_check_type(Xen_is_GLenum(zfail), zfail, 2, "glStencilOp", "GLenum"); Xen_check_type(Xen_is_GLenum(zpass), zpass, 3, "glStencilOp", "GLenum"); glStencilOp(Xen_to_C_GLenum(fail), Xen_to_C_GLenum(zfail), Xen_to_C_GLenum(zpass)); return(Xen_false); } static Xen gxg_glClearStencil(Xen s) { #define H_glClearStencil "void glClearStencil(GLint s)" Xen_check_type(Xen_is_GLint(s), s, 1, "glClearStencil", "GLint"); glClearStencil(Xen_to_C_GLint(s)); return(Xen_false); } static Xen gxg_glTexGend(Xen coord, Xen pname, Xen param) { #define H_glTexGend "void glTexGend(GLenum coord, GLenum pname, GLdouble param)" Xen_check_type(Xen_is_GLenum(coord), coord, 1, "glTexGend", "GLenum"); Xen_check_type(Xen_is_GLenum(pname), pname, 2, "glTexGend", "GLenum"); Xen_check_type(Xen_is_GLdouble(param), param, 3, "glTexGend", "GLdouble"); glTexGend(Xen_to_C_GLenum(coord), Xen_to_C_GLenum(pname), Xen_to_C_GLdouble(param)); return(Xen_false); } static Xen gxg_glTexGenf(Xen coord, Xen pname, Xen param) { #define H_glTexGenf "void glTexGenf(GLenum coord, GLenum pname, GLfloat param)" Xen_check_type(Xen_is_GLenum(coord), coord, 1, "glTexGenf", "GLenum"); Xen_check_type(Xen_is_GLenum(pname), pname, 2, "glTexGenf", "GLenum"); Xen_check_type(Xen_is_GLfloat(param), param, 3, "glTexGenf", "GLfloat"); glTexGenf(Xen_to_C_GLenum(coord), Xen_to_C_GLenum(pname), Xen_to_C_GLfloat(param)); return(Xen_false); } static Xen gxg_glTexGeni(Xen coord, Xen pname, Xen param) { #define H_glTexGeni "void glTexGeni(GLenum coord, GLenum pname, GLint param)" Xen_check_type(Xen_is_GLenum(coord), coord, 1, "glTexGeni", "GLenum"); Xen_check_type(Xen_is_GLenum(pname), pname, 2, "glTexGeni", "GLenum"); Xen_check_type(Xen_is_GLint(param), param, 3, "glTexGeni", "GLint"); glTexGeni(Xen_to_C_GLenum(coord), Xen_to_C_GLenum(pname), Xen_to_C_GLint(param)); return(Xen_false); } static Xen gxg_glGetTexGendv(Xen coord, Xen pname, Xen params) { #define H_glGetTexGendv "void glGetTexGendv(GLenum coord, GLenum pname, GLdouble* [params])" GLdouble ref_params[1]; Xen_check_type(Xen_is_GLenum(coord), coord, 1, "glGetTexGendv", "GLenum"); Xen_check_type(Xen_is_GLenum(pname), pname, 2, "glGetTexGendv", "GLenum"); glGetTexGendv(Xen_to_C_GLenum(coord), Xen_to_C_GLenum(pname), ref_params); return(Xen_list_1(C_to_Xen_GLdouble(ref_params[0]))); } static Xen gxg_glGetTexGenfv(Xen coord, Xen pname, Xen params) { #define H_glGetTexGenfv "void glGetTexGenfv(GLenum coord, GLenum pname, GLfloat* [params])" GLfloat ref_params[1]; Xen_check_type(Xen_is_GLenum(coord), coord, 1, "glGetTexGenfv", "GLenum"); Xen_check_type(Xen_is_GLenum(pname), pname, 2, "glGetTexGenfv", "GLenum"); glGetTexGenfv(Xen_to_C_GLenum(coord), Xen_to_C_GLenum(pname), ref_params); return(Xen_list_1(C_to_Xen_GLfloat(ref_params[0]))); } static Xen gxg_glGetTexGeniv(Xen coord, Xen pname, Xen params) { #define H_glGetTexGeniv "void glGetTexGeniv(GLenum coord, GLenum pname, GLint* [params])" GLint ref_params[1]; Xen_check_type(Xen_is_GLenum(coord), coord, 1, "glGetTexGeniv", "GLenum"); Xen_check_type(Xen_is_GLenum(pname), pname, 2, "glGetTexGeniv", "GLenum"); glGetTexGeniv(Xen_to_C_GLenum(coord), Xen_to_C_GLenum(pname), ref_params); return(Xen_list_1(C_to_Xen_GLint(ref_params[0]))); } static Xen gxg_glTexEnvf(Xen target, Xen pname, Xen param) { #define H_glTexEnvf "void glTexEnvf(GLenum target, GLenum pname, GLfloat param)" Xen_check_type(Xen_is_GLenum(target), target, 1, "glTexEnvf", "GLenum"); Xen_check_type(Xen_is_GLenum(pname), pname, 2, "glTexEnvf", "GLenum"); Xen_check_type(Xen_is_GLfloat(param), param, 3, "glTexEnvf", "GLfloat"); glTexEnvf(Xen_to_C_GLenum(target), Xen_to_C_GLenum(pname), Xen_to_C_GLfloat(param)); return(Xen_false); } static Xen gxg_glTexEnvi(Xen target, Xen pname, Xen param) { #define H_glTexEnvi "void glTexEnvi(GLenum target, GLenum pname, GLint param)" Xen_check_type(Xen_is_GLenum(target), target, 1, "glTexEnvi", "GLenum"); Xen_check_type(Xen_is_GLenum(pname), pname, 2, "glTexEnvi", "GLenum"); Xen_check_type(Xen_is_GLint(param), param, 3, "glTexEnvi", "GLint"); glTexEnvi(Xen_to_C_GLenum(target), Xen_to_C_GLenum(pname), Xen_to_C_GLint(param)); return(Xen_false); } static Xen gxg_glGetTexEnvfv(Xen target, Xen pname, Xen params) { #define H_glGetTexEnvfv "void glGetTexEnvfv(GLenum target, GLenum pname, GLfloat* [params])" GLfloat ref_params[1]; Xen_check_type(Xen_is_GLenum(target), target, 1, "glGetTexEnvfv", "GLenum"); Xen_check_type(Xen_is_GLenum(pname), pname, 2, "glGetTexEnvfv", "GLenum"); glGetTexEnvfv(Xen_to_C_GLenum(target), Xen_to_C_GLenum(pname), ref_params); return(Xen_list_1(C_to_Xen_GLfloat(ref_params[0]))); } static Xen gxg_glGetTexEnviv(Xen target, Xen pname, Xen params) { #define H_glGetTexEnviv "void glGetTexEnviv(GLenum target, GLenum pname, GLint* [params])" GLint ref_params[1]; Xen_check_type(Xen_is_GLenum(target), target, 1, "glGetTexEnviv", "GLenum"); Xen_check_type(Xen_is_GLenum(pname), pname, 2, "glGetTexEnviv", "GLenum"); glGetTexEnviv(Xen_to_C_GLenum(target), Xen_to_C_GLenum(pname), ref_params); return(Xen_list_1(C_to_Xen_GLint(ref_params[0]))); } static Xen gxg_glTexParameterf(Xen target, Xen pname, Xen param) { #define H_glTexParameterf "void glTexParameterf(GLenum target, GLenum pname, GLfloat param)" Xen_check_type(Xen_is_GLenum(target), target, 1, "glTexParameterf", "GLenum"); Xen_check_type(Xen_is_GLenum(pname), pname, 2, "glTexParameterf", "GLenum"); Xen_check_type(Xen_is_GLfloat(param), param, 3, "glTexParameterf", "GLfloat"); glTexParameterf(Xen_to_C_GLenum(target), Xen_to_C_GLenum(pname), Xen_to_C_GLfloat(param)); return(Xen_false); } static Xen gxg_glTexParameteri(Xen target, Xen pname, Xen param) { #define H_glTexParameteri "void glTexParameteri(GLenum target, GLenum pname, GLint param)" Xen_check_type(Xen_is_GLenum(target), target, 1, "glTexParameteri", "GLenum"); Xen_check_type(Xen_is_GLenum(pname), pname, 2, "glTexParameteri", "GLenum"); Xen_check_type(Xen_is_GLint(param), param, 3, "glTexParameteri", "GLint"); glTexParameteri(Xen_to_C_GLenum(target), Xen_to_C_GLenum(pname), Xen_to_C_GLint(param)); return(Xen_false); } static Xen gxg_glGetTexParameterfv(Xen target, Xen pname, Xen params) { #define H_glGetTexParameterfv "void glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* [params])" GLfloat ref_params[1]; Xen_check_type(Xen_is_GLenum(target), target, 1, "glGetTexParameterfv", "GLenum"); Xen_check_type(Xen_is_GLenum(pname), pname, 2, "glGetTexParameterfv", "GLenum"); glGetTexParameterfv(Xen_to_C_GLenum(target), Xen_to_C_GLenum(pname), ref_params); return(Xen_list_1(C_to_Xen_GLfloat(ref_params[0]))); } static Xen gxg_glGetTexParameteriv(Xen target, Xen pname, Xen params) { #define H_glGetTexParameteriv "void glGetTexParameteriv(GLenum target, GLenum pname, GLint* [params])" GLint ref_params[1]; Xen_check_type(Xen_is_GLenum(target), target, 1, "glGetTexParameteriv", "GLenum"); Xen_check_type(Xen_is_GLenum(pname), pname, 2, "glGetTexParameteriv", "GLenum"); glGetTexParameteriv(Xen_to_C_GLenum(target), Xen_to_C_GLenum(pname), ref_params); return(Xen_list_1(C_to_Xen_GLint(ref_params[0]))); } static Xen gxg_glGetTexLevelParameterfv(Xen target, Xen level, Xen pname, Xen params) { #define H_glGetTexLevelParameterfv "void glGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, \ GLfloat* [params])" GLfloat ref_params[1]; Xen_check_type(Xen_is_GLenum(target), target, 1, "glGetTexLevelParameterfv", "GLenum"); Xen_check_type(Xen_is_GLint(level), level, 2, "glGetTexLevelParameterfv", "GLint"); Xen_check_type(Xen_is_GLenum(pname), pname, 3, "glGetTexLevelParameterfv", "GLenum"); glGetTexLevelParameterfv(Xen_to_C_GLenum(target), Xen_to_C_GLint(level), Xen_to_C_GLenum(pname), ref_params); return(Xen_list_1(C_to_Xen_GLfloat(ref_params[0]))); } static Xen gxg_glGetTexLevelParameteriv(Xen target, Xen level, Xen pname, Xen params) { #define H_glGetTexLevelParameteriv "void glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, \ GLint* [params])" GLint ref_params[1]; Xen_check_type(Xen_is_GLenum(target), target, 1, "glGetTexLevelParameteriv", "GLenum"); Xen_check_type(Xen_is_GLint(level), level, 2, "glGetTexLevelParameteriv", "GLint"); Xen_check_type(Xen_is_GLenum(pname), pname, 3, "glGetTexLevelParameteriv", "GLenum"); glGetTexLevelParameteriv(Xen_to_C_GLenum(target), Xen_to_C_GLint(level), Xen_to_C_GLenum(pname), ref_params); return(Xen_list_1(C_to_Xen_GLint(ref_params[0]))); } static Xen gxg_glTexImage1D(Xen arglist) { #define H_glTexImage1D "void glTexImage1D(GLenum target, GLint level, GLint internalFormat, GLsizei width, \ GLint border, GLenum format, GLenum type, GLvoid* pixels)" Xen target, level, internalFormat, width, border, format, type, pixels; target = Xen_list_ref(arglist, 0); level = Xen_list_ref(arglist, 1); internalFormat = Xen_list_ref(arglist, 2); width = Xen_list_ref(arglist, 3); border = Xen_list_ref(arglist, 4); format = Xen_list_ref(arglist, 5); type = Xen_list_ref(arglist, 6); pixels = Xen_list_ref(arglist, 7); Xen_check_type(Xen_is_GLenum(target), target, 1, "glTexImage1D", "GLenum"); Xen_check_type(Xen_is_GLint(level), level, 2, "glTexImage1D", "GLint"); Xen_check_type(Xen_is_GLint(internalFormat), internalFormat, 3, "glTexImage1D", "GLint"); Xen_check_type(Xen_is_GLsizei(width), width, 4, "glTexImage1D", "GLsizei"); Xen_check_type(Xen_is_GLint(border), border, 5, "glTexImage1D", "GLint"); Xen_check_type(Xen_is_GLenum(format), format, 6, "glTexImage1D", "GLenum"); Xen_check_type(Xen_is_GLenum(type), type, 7, "glTexImage1D", "GLenum"); Xen_check_type(Xen_is_GLvoid_(pixels), pixels, 8, "glTexImage1D", "GLvoid*"); glTexImage1D(Xen_to_C_GLenum(target), Xen_to_C_GLint(level), Xen_to_C_GLint(internalFormat), Xen_to_C_GLsizei(width), Xen_to_C_GLint(border), Xen_to_C_GLenum(format), Xen_to_C_GLenum(type), Xen_to_C_GLvoid_(pixels)); return(Xen_false); } static Xen gxg_glTexImage2D(Xen arglist) { #define H_glTexImage2D "void glTexImage2D(GLenum target, GLint level, GLint internalFormat, GLsizei width, \ GLsizei height, GLint border, GLenum format, GLenum type, GLvoid* pixels)" Xen target, level, internalFormat, width, height, border, format, type, pixels; target = Xen_list_ref(arglist, 0); level = Xen_list_ref(arglist, 1); internalFormat = Xen_list_ref(arglist, 2); width = Xen_list_ref(arglist, 3); height = Xen_list_ref(arglist, 4); border = Xen_list_ref(arglist, 5); format = Xen_list_ref(arglist, 6); type = Xen_list_ref(arglist, 7); pixels = Xen_list_ref(arglist, 8); Xen_check_type(Xen_is_GLenum(target), target, 1, "glTexImage2D", "GLenum"); Xen_check_type(Xen_is_GLint(level), level, 2, "glTexImage2D", "GLint"); Xen_check_type(Xen_is_GLint(internalFormat), internalFormat, 3, "glTexImage2D", "GLint"); Xen_check_type(Xen_is_GLsizei(width), width, 4, "glTexImage2D", "GLsizei"); Xen_check_type(Xen_is_GLsizei(height), height, 5, "glTexImage2D", "GLsizei"); Xen_check_type(Xen_is_GLint(border), border, 6, "glTexImage2D", "GLint"); Xen_check_type(Xen_is_GLenum(format), format, 7, "glTexImage2D", "GLenum"); Xen_check_type(Xen_is_GLenum(type), type, 8, "glTexImage2D", "GLenum"); Xen_check_type(Xen_is_GLvoid_(pixels), pixels, 9, "glTexImage2D", "GLvoid*"); glTexImage2D(Xen_to_C_GLenum(target), Xen_to_C_GLint(level), Xen_to_C_GLint(internalFormat), Xen_to_C_GLsizei(width), Xen_to_C_GLsizei(height), Xen_to_C_GLint(border), Xen_to_C_GLenum(format), Xen_to_C_GLenum(type), Xen_to_C_GLvoid_(pixels)); return(Xen_false); } static Xen gxg_glGenTextures(Xen n, Xen textures) { #define H_glGenTextures "void glGenTextures(GLsizei n, GLuint* textures)" Xen_check_type(Xen_is_GLsizei(n), n, 1, "glGenTextures", "GLsizei"); Xen_check_type(Xen_is_GLuint_(textures), textures, 2, "glGenTextures", "GLuint*"); glGenTextures(Xen_to_C_GLsizei(n), Xen_to_C_GLuint_(textures)); return(Xen_false); } static Xen gxg_glDeleteTextures(Xen n, Xen textures) { #define H_glDeleteTextures "void glDeleteTextures(GLsizei n, GLuint* textures)" Xen_check_type(Xen_is_GLsizei(n), n, 1, "glDeleteTextures", "GLsizei"); Xen_check_type(Xen_is_GLuint_(textures), textures, 2, "glDeleteTextures", "GLuint*"); glDeleteTextures(Xen_to_C_GLsizei(n), Xen_to_C_GLuint_(textures)); return(Xen_false); } static Xen gxg_glBindTexture(Xen target, Xen texture) { #define H_glBindTexture "void glBindTexture(GLenum target, GLuint texture)" Xen_check_type(Xen_is_GLenum(target), target, 1, "glBindTexture", "GLenum"); Xen_check_type(Xen_is_GLuint(texture), texture, 2, "glBindTexture", "GLuint"); glBindTexture(Xen_to_C_GLenum(target), Xen_to_C_GLuint(texture)); return(Xen_false); } static Xen gxg_glAreTexturesResident(Xen n, Xen textures, Xen residences) { #define H_glAreTexturesResident "GLboolean glAreTexturesResident(GLsizei n, GLuint* textures, GLboolean* residences)" Xen_check_type(Xen_is_GLsizei(n), n, 1, "glAreTexturesResident", "GLsizei"); Xen_check_type(Xen_is_GLuint_(textures), textures, 2, "glAreTexturesResident", "GLuint*"); Xen_check_type(Xen_is_GLboolean_(residences), residences, 3, "glAreTexturesResident", "GLboolean*"); return(C_to_Xen_GLboolean(glAreTexturesResident(Xen_to_C_GLsizei(n), Xen_to_C_GLuint_(textures), Xen_to_C_GLboolean_(residences)))); } static Xen gxg_glIsTexture(Xen texture) { #define H_glIsTexture "GLboolean glIsTexture(GLuint texture)" Xen_check_type(Xen_is_GLuint(texture), texture, 1, "glIsTexture", "GLuint"); return(C_to_Xen_GLboolean(glIsTexture(Xen_to_C_GLuint(texture)))); } static Xen gxg_glTexSubImage1D(Xen target, Xen level, Xen xoffset, Xen width, Xen format, Xen type, Xen pixels) { #define H_glTexSubImage1D "void glTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, \ GLenum format, GLenum type, GLvoid* pixels)" Xen_check_type(Xen_is_GLenum(target), target, 1, "glTexSubImage1D", "GLenum"); Xen_check_type(Xen_is_GLint(level), level, 2, "glTexSubImage1D", "GLint"); Xen_check_type(Xen_is_GLint(xoffset), xoffset, 3, "glTexSubImage1D", "GLint"); Xen_check_type(Xen_is_GLsizei(width), width, 4, "glTexSubImage1D", "GLsizei"); Xen_check_type(Xen_is_GLenum(format), format, 5, "glTexSubImage1D", "GLenum"); Xen_check_type(Xen_is_GLenum(type), type, 6, "glTexSubImage1D", "GLenum"); Xen_check_type(Xen_is_GLvoid_(pixels), pixels, 7, "glTexSubImage1D", "GLvoid*"); glTexSubImage1D(Xen_to_C_GLenum(target), Xen_to_C_GLint(level), Xen_to_C_GLint(xoffset), Xen_to_C_GLsizei(width), Xen_to_C_GLenum(format), Xen_to_C_GLenum(type), Xen_to_C_GLvoid_(pixels)); return(Xen_false); } static Xen gxg_glTexSubImage2D(Xen arglist) { #define H_glTexSubImage2D "void glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, \ GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)" Xen target, level, xoffset, yoffset, width, height, format, type, pixels; target = Xen_list_ref(arglist, 0); level = Xen_list_ref(arglist, 1); xoffset = Xen_list_ref(arglist, 2); yoffset = Xen_list_ref(arglist, 3); width = Xen_list_ref(arglist, 4); height = Xen_list_ref(arglist, 5); format = Xen_list_ref(arglist, 6); type = Xen_list_ref(arglist, 7); pixels = Xen_list_ref(arglist, 8); Xen_check_type(Xen_is_GLenum(target), target, 1, "glTexSubImage2D", "GLenum"); Xen_check_type(Xen_is_GLint(level), level, 2, "glTexSubImage2D", "GLint"); Xen_check_type(Xen_is_GLint(xoffset), xoffset, 3, "glTexSubImage2D", "GLint"); Xen_check_type(Xen_is_GLint(yoffset), yoffset, 4, "glTexSubImage2D", "GLint"); Xen_check_type(Xen_is_GLsizei(width), width, 5, "glTexSubImage2D", "GLsizei"); Xen_check_type(Xen_is_GLsizei(height), height, 6, "glTexSubImage2D", "GLsizei"); Xen_check_type(Xen_is_GLenum(format), format, 7, "glTexSubImage2D", "GLenum"); Xen_check_type(Xen_is_GLenum(type), type, 8, "glTexSubImage2D", "GLenum"); Xen_check_type(Xen_is_GLvoid_(pixels), pixels, 9, "glTexSubImage2D", "GLvoid*"); glTexSubImage2D(Xen_to_C_GLenum(target), Xen_to_C_GLint(level), Xen_to_C_GLint(xoffset), Xen_to_C_GLint(yoffset), Xen_to_C_GLsizei(width), Xen_to_C_GLsizei(height), Xen_to_C_GLenum(format), Xen_to_C_GLenum(type), Xen_to_C_GLvoid_(pixels)); return(Xen_false); } static Xen gxg_glCopyTexImage1D(Xen target, Xen level, Xen internalformat, Xen x, Xen y, Xen width, Xen border) { #define H_glCopyTexImage1D "void glCopyTexImage1D(GLenum target, GLint level, GLenum internalformat, \ GLint x, GLint y, GLsizei width, GLint border)" Xen_check_type(Xen_is_GLenum(target), target, 1, "glCopyTexImage1D", "GLenum"); Xen_check_type(Xen_is_GLint(level), level, 2, "glCopyTexImage1D", "GLint"); Xen_check_type(Xen_is_GLenum(internalformat), internalformat, 3, "glCopyTexImage1D", "GLenum"); Xen_check_type(Xen_is_GLint(x), x, 4, "glCopyTexImage1D", "GLint"); Xen_check_type(Xen_is_GLint(y), y, 5, "glCopyTexImage1D", "GLint"); Xen_check_type(Xen_is_GLsizei(width), width, 6, "glCopyTexImage1D", "GLsizei"); Xen_check_type(Xen_is_GLint(border), border, 7, "glCopyTexImage1D", "GLint"); glCopyTexImage1D(Xen_to_C_GLenum(target), Xen_to_C_GLint(level), Xen_to_C_GLenum(internalformat), Xen_to_C_GLint(x), Xen_to_C_GLint(y), Xen_to_C_GLsizei(width), Xen_to_C_GLint(border)); return(Xen_false); } static Xen gxg_glCopyTexImage2D(Xen arglist) { #define H_glCopyTexImage2D "void glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, \ GLint x, GLint y, GLsizei width, GLsizei height, GLint border)" Xen target, level, internalformat, x, y, width, height, border; target = Xen_list_ref(arglist, 0); level = Xen_list_ref(arglist, 1); internalformat = Xen_list_ref(arglist, 2); x = Xen_list_ref(arglist, 3); y = Xen_list_ref(arglist, 4); width = Xen_list_ref(arglist, 5); height = Xen_list_ref(arglist, 6); border = Xen_list_ref(arglist, 7); Xen_check_type(Xen_is_GLenum(target), target, 1, "glCopyTexImage2D", "GLenum"); Xen_check_type(Xen_is_GLint(level), level, 2, "glCopyTexImage2D", "GLint"); Xen_check_type(Xen_is_GLenum(internalformat), internalformat, 3, "glCopyTexImage2D", "GLenum"); Xen_check_type(Xen_is_GLint(x), x, 4, "glCopyTexImage2D", "GLint"); Xen_check_type(Xen_is_GLint(y), y, 5, "glCopyTexImage2D", "GLint"); Xen_check_type(Xen_is_GLsizei(width), width, 6, "glCopyTexImage2D", "GLsizei"); Xen_check_type(Xen_is_GLsizei(height), height, 7, "glCopyTexImage2D", "GLsizei"); Xen_check_type(Xen_is_GLint(border), border, 8, "glCopyTexImage2D", "GLint"); glCopyTexImage2D(Xen_to_C_GLenum(target), Xen_to_C_GLint(level), Xen_to_C_GLenum(internalformat), Xen_to_C_GLint(x), Xen_to_C_GLint(y), Xen_to_C_GLsizei(width), Xen_to_C_GLsizei(height), Xen_to_C_GLint(border)); return(Xen_false); } static Xen gxg_glCopyTexSubImage1D(Xen target, Xen level, Xen xoffset, Xen x, Xen y, Xen width) { #define H_glCopyTexSubImage1D "void glCopyTexSubImage1D(GLenum target, GLint level, GLint xoffset, \ GLint x, GLint y, GLsizei width)" Xen_check_type(Xen_is_GLenum(target), target, 1, "glCopyTexSubImage1D", "GLenum"); Xen_check_type(Xen_is_GLint(level), level, 2, "glCopyTexSubImage1D", "GLint"); Xen_check_type(Xen_is_GLint(xoffset), xoffset, 3, "glCopyTexSubImage1D", "GLint"); Xen_check_type(Xen_is_GLint(x), x, 4, "glCopyTexSubImage1D", "GLint"); Xen_check_type(Xen_is_GLint(y), y, 5, "glCopyTexSubImage1D", "GLint"); Xen_check_type(Xen_is_GLsizei(width), width, 6, "glCopyTexSubImage1D", "GLsizei"); glCopyTexSubImage1D(Xen_to_C_GLenum(target), Xen_to_C_GLint(level), Xen_to_C_GLint(xoffset), Xen_to_C_GLint(x), Xen_to_C_GLint(y), Xen_to_C_GLsizei(width)); return(Xen_false); } static Xen gxg_glCopyTexSubImage2D(Xen arglist) { #define H_glCopyTexSubImage2D "void glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, \ GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)" Xen target, level, xoffset, yoffset, x, y, width, height; target = Xen_list_ref(arglist, 0); level = Xen_list_ref(arglist, 1); xoffset = Xen_list_ref(arglist, 2); yoffset = Xen_list_ref(arglist, 3); x = Xen_list_ref(arglist, 4); y = Xen_list_ref(arglist, 5); width = Xen_list_ref(arglist, 6); height = Xen_list_ref(arglist, 7); Xen_check_type(Xen_is_GLenum(target), target, 1, "glCopyTexSubImage2D", "GLenum"); Xen_check_type(Xen_is_GLint(level), level, 2, "glCopyTexSubImage2D", "GLint"); Xen_check_type(Xen_is_GLint(xoffset), xoffset, 3, "glCopyTexSubImage2D", "GLint"); Xen_check_type(Xen_is_GLint(yoffset), yoffset, 4, "glCopyTexSubImage2D", "GLint"); Xen_check_type(Xen_is_GLint(x), x, 5, "glCopyTexSubImage2D", "GLint"); Xen_check_type(Xen_is_GLint(y), y, 6, "glCopyTexSubImage2D", "GLint"); Xen_check_type(Xen_is_GLsizei(width), width, 7, "glCopyTexSubImage2D", "GLsizei"); Xen_check_type(Xen_is_GLsizei(height), height, 8, "glCopyTexSubImage2D", "GLsizei"); glCopyTexSubImage2D(Xen_to_C_GLenum(target), Xen_to_C_GLint(level), Xen_to_C_GLint(xoffset), Xen_to_C_GLint(yoffset), Xen_to_C_GLint(x), Xen_to_C_GLint(y), Xen_to_C_GLsizei(width), Xen_to_C_GLsizei(height)); return(Xen_false); } static Xen gxg_glMap1d(Xen target, Xen u1, Xen u2, Xen stride, Xen order, Xen points) { #define H_glMap1d "void glMap1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, \ GLdouble* points)" Xen_check_type(Xen_is_GLenum(target), target, 1, "glMap1d", "GLenum"); Xen_check_type(Xen_is_GLdouble(u1), u1, 2, "glMap1d", "GLdouble"); Xen_check_type(Xen_is_GLdouble(u2), u2, 3, "glMap1d", "GLdouble"); Xen_check_type(Xen_is_GLint(stride), stride, 4, "glMap1d", "GLint"); Xen_check_type(Xen_is_GLint(order), order, 5, "glMap1d", "GLint"); Xen_check_type(Xen_is_GLdouble_(points), points, 6, "glMap1d", "GLdouble*"); glMap1d(Xen_to_C_GLenum(target), Xen_to_C_GLdouble(u1), Xen_to_C_GLdouble(u2), Xen_to_C_GLint(stride), Xen_to_C_GLint(order), Xen_to_C_GLdouble_(points)); return(Xen_false); } static Xen gxg_glMap1f(Xen target, Xen u1, Xen u2, Xen stride, Xen order, Xen points) { #define H_glMap1f "void glMap1f(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, GLfloat* points)" Xen_check_type(Xen_is_GLenum(target), target, 1, "glMap1f", "GLenum"); Xen_check_type(Xen_is_GLfloat(u1), u1, 2, "glMap1f", "GLfloat"); Xen_check_type(Xen_is_GLfloat(u2), u2, 3, "glMap1f", "GLfloat"); Xen_check_type(Xen_is_GLint(stride), stride, 4, "glMap1f", "GLint"); Xen_check_type(Xen_is_GLint(order), order, 5, "glMap1f", "GLint"); Xen_check_type(Xen_is_GLfloat_(points), points, 6, "glMap1f", "GLfloat*"); glMap1f(Xen_to_C_GLenum(target), Xen_to_C_GLfloat(u1), Xen_to_C_GLfloat(u2), Xen_to_C_GLint(stride), Xen_to_C_GLint(order), Xen_to_C_GLfloat_(points)); return(Xen_false); } static Xen gxg_glMap2d(Xen arglist) { #define H_glMap2d "void glMap2d(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, \ GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, GLdouble* points)" Xen target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points; target = Xen_list_ref(arglist, 0); u1 = Xen_list_ref(arglist, 1); u2 = Xen_list_ref(arglist, 2); ustride = Xen_list_ref(arglist, 3); uorder = Xen_list_ref(arglist, 4); v1 = Xen_list_ref(arglist, 5); v2 = Xen_list_ref(arglist, 6); vstride = Xen_list_ref(arglist, 7); vorder = Xen_list_ref(arglist, 8); points = Xen_list_ref(arglist, 9); Xen_check_type(Xen_is_GLenum(target), target, 1, "glMap2d", "GLenum"); Xen_check_type(Xen_is_GLdouble(u1), u1, 2, "glMap2d", "GLdouble"); Xen_check_type(Xen_is_GLdouble(u2), u2, 3, "glMap2d", "GLdouble"); Xen_check_type(Xen_is_GLint(ustride), ustride, 4, "glMap2d", "GLint"); Xen_check_type(Xen_is_GLint(uorder), uorder, 5, "glMap2d", "GLint"); Xen_check_type(Xen_is_GLdouble(v1), v1, 6, "glMap2d", "GLdouble"); Xen_check_type(Xen_is_GLdouble(v2), v2, 7, "glMap2d", "GLdouble"); Xen_check_type(Xen_is_GLint(vstride), vstride, 8, "glMap2d", "GLint"); Xen_check_type(Xen_is_GLint(vorder), vorder, 9, "glMap2d", "GLint"); Xen_check_type(Xen_is_GLdouble_(points), points, 10, "glMap2d", "GLdouble*"); glMap2d(Xen_to_C_GLenum(target), Xen_to_C_GLdouble(u1), Xen_to_C_GLdouble(u2), Xen_to_C_GLint(ustride), Xen_to_C_GLint(uorder), Xen_to_C_GLdouble(v1), Xen_to_C_GLdouble(v2), Xen_to_C_GLint(vstride), Xen_to_C_GLint(vorder), Xen_to_C_GLdouble_(points)); return(Xen_false); } static Xen gxg_glMap2f(Xen arglist) { #define H_glMap2f "void glMap2f(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, \ GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, GLfloat* points)" Xen target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points; target = Xen_list_ref(arglist, 0); u1 = Xen_list_ref(arglist, 1); u2 = Xen_list_ref(arglist, 2); ustride = Xen_list_ref(arglist, 3); uorder = Xen_list_ref(arglist, 4); v1 = Xen_list_ref(arglist, 5); v2 = Xen_list_ref(arglist, 6); vstride = Xen_list_ref(arglist, 7); vorder = Xen_list_ref(arglist, 8); points = Xen_list_ref(arglist, 9); Xen_check_type(Xen_is_GLenum(target), target, 1, "glMap2f", "GLenum"); Xen_check_type(Xen_is_GLfloat(u1), u1, 2, "glMap2f", "GLfloat"); Xen_check_type(Xen_is_GLfloat(u2), u2, 3, "glMap2f", "GLfloat"); Xen_check_type(Xen_is_GLint(ustride), ustride, 4, "glMap2f", "GLint"); Xen_check_type(Xen_is_GLint(uorder), uorder, 5, "glMap2f", "GLint"); Xen_check_type(Xen_is_GLfloat(v1), v1, 6, "glMap2f", "GLfloat"); Xen_check_type(Xen_is_GLfloat(v2), v2, 7, "glMap2f", "GLfloat"); Xen_check_type(Xen_is_GLint(vstride), vstride, 8, "glMap2f", "GLint"); Xen_check_type(Xen_is_GLint(vorder), vorder, 9, "glMap2f", "GLint"); Xen_check_type(Xen_is_GLfloat_(points), points, 10, "glMap2f", "GLfloat*"); glMap2f(Xen_to_C_GLenum(target), Xen_to_C_GLfloat(u1), Xen_to_C_GLfloat(u2), Xen_to_C_GLint(ustride), Xen_to_C_GLint(uorder), Xen_to_C_GLfloat(v1), Xen_to_C_GLfloat(v2), Xen_to_C_GLint(vstride), Xen_to_C_GLint(vorder), Xen_to_C_GLfloat_(points)); return(Xen_false); } static Xen gxg_glGetMapdv(Xen target, Xen query, Xen v) { #define H_glGetMapdv "void glGetMapdv(GLenum target, GLenum query, GLdouble* [v])" GLdouble ref_v[1]; Xen_check_type(Xen_is_GLenum(target), target, 1, "glGetMapdv", "GLenum"); Xen_check_type(Xen_is_GLenum(query), query, 2, "glGetMapdv", "GLenum"); glGetMapdv(Xen_to_C_GLenum(target), Xen_to_C_GLenum(query), ref_v); return(Xen_list_1(C_to_Xen_GLdouble(ref_v[0]))); } static Xen gxg_glGetMapfv(Xen target, Xen query, Xen v) { #define H_glGetMapfv "void glGetMapfv(GLenum target, GLenum query, GLfloat* [v])" GLfloat ref_v[1]; Xen_check_type(Xen_is_GLenum(target), target, 1, "glGetMapfv", "GLenum"); Xen_check_type(Xen_is_GLenum(query), query, 2, "glGetMapfv", "GLenum"); glGetMapfv(Xen_to_C_GLenum(target), Xen_to_C_GLenum(query), ref_v); return(Xen_list_1(C_to_Xen_GLfloat(ref_v[0]))); } static Xen gxg_glGetMapiv(Xen target, Xen query, Xen v) { #define H_glGetMapiv "void glGetMapiv(GLenum target, GLenum query, GLint* [v])" GLint ref_v[1]; Xen_check_type(Xen_is_GLenum(target), target, 1, "glGetMapiv", "GLenum"); Xen_check_type(Xen_is_GLenum(query), query, 2, "glGetMapiv", "GLenum"); glGetMapiv(Xen_to_C_GLenum(target), Xen_to_C_GLenum(query), ref_v); return(Xen_list_1(C_to_Xen_GLint(ref_v[0]))); } static Xen gxg_glEvalCoord1d(Xen u) { #define H_glEvalCoord1d "void glEvalCoord1d(GLdouble u)" Xen_check_type(Xen_is_GLdouble(u), u, 1, "glEvalCoord1d", "GLdouble"); glEvalCoord1d(Xen_to_C_GLdouble(u)); return(Xen_false); } static Xen gxg_glEvalCoord1f(Xen u) { #define H_glEvalCoord1f "void glEvalCoord1f(GLfloat u)" Xen_check_type(Xen_is_GLfloat(u), u, 1, "glEvalCoord1f", "GLfloat"); glEvalCoord1f(Xen_to_C_GLfloat(u)); return(Xen_false); } static Xen gxg_glEvalCoord2d(Xen u, Xen v) { #define H_glEvalCoord2d "void glEvalCoord2d(GLdouble u, GLdouble v)" Xen_check_type(Xen_is_GLdouble(u), u, 1, "glEvalCoord2d", "GLdouble"); Xen_check_type(Xen_is_GLdouble(v), v, 2, "glEvalCoord2d", "GLdouble"); glEvalCoord2d(Xen_to_C_GLdouble(u), Xen_to_C_GLdouble(v)); return(Xen_false); } static Xen gxg_glEvalCoord2f(Xen u, Xen v) { #define H_glEvalCoord2f "void glEvalCoord2f(GLfloat u, GLfloat v)" Xen_check_type(Xen_is_GLfloat(u), u, 1, "glEvalCoord2f", "GLfloat"); Xen_check_type(Xen_is_GLfloat(v), v, 2, "glEvalCoord2f", "GLfloat"); glEvalCoord2f(Xen_to_C_GLfloat(u), Xen_to_C_GLfloat(v)); return(Xen_false); } static Xen gxg_glMapGrid1d(Xen un, Xen u1, Xen u2) { #define H_glMapGrid1d "void glMapGrid1d(GLint un, GLdouble u1, GLdouble u2)" Xen_check_type(Xen_is_GLint(un), un, 1, "glMapGrid1d", "GLint"); Xen_check_type(Xen_is_GLdouble(u1), u1, 2, "glMapGrid1d", "GLdouble"); Xen_check_type(Xen_is_GLdouble(u2), u2, 3, "glMapGrid1d", "GLdouble"); glMapGrid1d(Xen_to_C_GLint(un), Xen_to_C_GLdouble(u1), Xen_to_C_GLdouble(u2)); return(Xen_false); } static Xen gxg_glMapGrid1f(Xen un, Xen u1, Xen u2) { #define H_glMapGrid1f "void glMapGrid1f(GLint un, GLfloat u1, GLfloat u2)" Xen_check_type(Xen_is_GLint(un), un, 1, "glMapGrid1f", "GLint"); Xen_check_type(Xen_is_GLfloat(u1), u1, 2, "glMapGrid1f", "GLfloat"); Xen_check_type(Xen_is_GLfloat(u2), u2, 3, "glMapGrid1f", "GLfloat"); glMapGrid1f(Xen_to_C_GLint(un), Xen_to_C_GLfloat(u1), Xen_to_C_GLfloat(u2)); return(Xen_false); } static Xen gxg_glMapGrid2d(Xen un, Xen u1, Xen u2, Xen vn, Xen v1, Xen v2) { #define H_glMapGrid2d "void glMapGrid2d(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, \ GLdouble v2)" Xen_check_type(Xen_is_GLint(un), un, 1, "glMapGrid2d", "GLint"); Xen_check_type(Xen_is_GLdouble(u1), u1, 2, "glMapGrid2d", "GLdouble"); Xen_check_type(Xen_is_GLdouble(u2), u2, 3, "glMapGrid2d", "GLdouble"); Xen_check_type(Xen_is_GLint(vn), vn, 4, "glMapGrid2d", "GLint"); Xen_check_type(Xen_is_GLdouble(v1), v1, 5, "glMapGrid2d", "GLdouble"); Xen_check_type(Xen_is_GLdouble(v2), v2, 6, "glMapGrid2d", "GLdouble"); glMapGrid2d(Xen_to_C_GLint(un), Xen_to_C_GLdouble(u1), Xen_to_C_GLdouble(u2), Xen_to_C_GLint(vn), Xen_to_C_GLdouble(v1), Xen_to_C_GLdouble(v2)); return(Xen_false); } static Xen gxg_glMapGrid2f(Xen un, Xen u1, Xen u2, Xen vn, Xen v1, Xen v2) { #define H_glMapGrid2f "void glMapGrid2f(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2)" Xen_check_type(Xen_is_GLint(un), un, 1, "glMapGrid2f", "GLint"); Xen_check_type(Xen_is_GLfloat(u1), u1, 2, "glMapGrid2f", "GLfloat"); Xen_check_type(Xen_is_GLfloat(u2), u2, 3, "glMapGrid2f", "GLfloat"); Xen_check_type(Xen_is_GLint(vn), vn, 4, "glMapGrid2f", "GLint"); Xen_check_type(Xen_is_GLfloat(v1), v1, 5, "glMapGrid2f", "GLfloat"); Xen_check_type(Xen_is_GLfloat(v2), v2, 6, "glMapGrid2f", "GLfloat"); glMapGrid2f(Xen_to_C_GLint(un), Xen_to_C_GLfloat(u1), Xen_to_C_GLfloat(u2), Xen_to_C_GLint(vn), Xen_to_C_GLfloat(v1), Xen_to_C_GLfloat(v2)); return(Xen_false); } static Xen gxg_glEvalPoint1(Xen i) { #define H_glEvalPoint1 "void glEvalPoint1(GLint i)" Xen_check_type(Xen_is_GLint(i), i, 1, "glEvalPoint1", "GLint"); glEvalPoint1(Xen_to_C_GLint(i)); return(Xen_false); } static Xen gxg_glEvalPoint2(Xen i, Xen j) { #define H_glEvalPoint2 "void glEvalPoint2(GLint i, GLint j)" Xen_check_type(Xen_is_GLint(i), i, 1, "glEvalPoint2", "GLint"); Xen_check_type(Xen_is_GLint(j), j, 2, "glEvalPoint2", "GLint"); glEvalPoint2(Xen_to_C_GLint(i), Xen_to_C_GLint(j)); return(Xen_false); } static Xen gxg_glEvalMesh1(Xen mode, Xen i1, Xen i2) { #define H_glEvalMesh1 "void glEvalMesh1(GLenum mode, GLint i1, GLint i2)" Xen_check_type(Xen_is_GLenum(mode), mode, 1, "glEvalMesh1", "GLenum"); Xen_check_type(Xen_is_GLint(i1), i1, 2, "glEvalMesh1", "GLint"); Xen_check_type(Xen_is_GLint(i2), i2, 3, "glEvalMesh1", "GLint"); glEvalMesh1(Xen_to_C_GLenum(mode), Xen_to_C_GLint(i1), Xen_to_C_GLint(i2)); return(Xen_false); } static Xen gxg_glEvalMesh2(Xen mode, Xen i1, Xen i2, Xen j1, Xen j2) { #define H_glEvalMesh2 "void glEvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2)" Xen_check_type(Xen_is_GLenum(mode), mode, 1, "glEvalMesh2", "GLenum"); Xen_check_type(Xen_is_GLint(i1), i1, 2, "glEvalMesh2", "GLint"); Xen_check_type(Xen_is_GLint(i2), i2, 3, "glEvalMesh2", "GLint"); Xen_check_type(Xen_is_GLint(j1), j1, 4, "glEvalMesh2", "GLint"); Xen_check_type(Xen_is_GLint(j2), j2, 5, "glEvalMesh2", "GLint"); glEvalMesh2(Xen_to_C_GLenum(mode), Xen_to_C_GLint(i1), Xen_to_C_GLint(i2), Xen_to_C_GLint(j1), Xen_to_C_GLint(j2)); return(Xen_false); } static Xen gxg_glFogf(Xen pname, Xen param) { #define H_glFogf "void glFogf(GLenum pname, GLfloat param)" Xen_check_type(Xen_is_GLenum(pname), pname, 1, "glFogf", "GLenum"); Xen_check_type(Xen_is_GLfloat(param), param, 2, "glFogf", "GLfloat"); glFogf(Xen_to_C_GLenum(pname), Xen_to_C_GLfloat(param)); return(Xen_false); } static Xen gxg_glFogi(Xen pname, Xen param) { #define H_glFogi "void glFogi(GLenum pname, GLint param)" Xen_check_type(Xen_is_GLenum(pname), pname, 1, "glFogi", "GLenum"); Xen_check_type(Xen_is_GLint(param), param, 2, "glFogi", "GLint"); glFogi(Xen_to_C_GLenum(pname), Xen_to_C_GLint(param)); return(Xen_false); } static Xen gxg_glFeedbackBuffer(Xen size, Xen type, Xen buffer) { #define H_glFeedbackBuffer "void glFeedbackBuffer(GLsizei size, GLenum type, GLfloat* buffer)" Xen_check_type(Xen_is_GLsizei(size), size, 1, "glFeedbackBuffer", "GLsizei"); Xen_check_type(Xen_is_GLenum(type), type, 2, "glFeedbackBuffer", "GLenum"); Xen_check_type(Xen_is_GLfloat_(buffer), buffer, 3, "glFeedbackBuffer", "GLfloat*"); glFeedbackBuffer(Xen_to_C_GLsizei(size), Xen_to_C_GLenum(type), Xen_to_C_GLfloat_(buffer)); return(Xen_false); } static Xen gxg_glPassThrough(Xen token) { #define H_glPassThrough "void glPassThrough(GLfloat token)" Xen_check_type(Xen_is_GLfloat(token), token, 1, "glPassThrough", "GLfloat"); glPassThrough(Xen_to_C_GLfloat(token)); return(Xen_false); } static Xen gxg_glSelectBuffer(Xen size, Xen buffer) { #define H_glSelectBuffer "void glSelectBuffer(GLsizei size, GLuint* buffer)" Xen_check_type(Xen_is_GLsizei(size), size, 1, "glSelectBuffer", "GLsizei"); Xen_check_type(Xen_is_GLuint_(buffer), buffer, 2, "glSelectBuffer", "GLuint*"); glSelectBuffer(Xen_to_C_GLsizei(size), Xen_to_C_GLuint_(buffer)); return(Xen_false); } static Xen gxg_glInitNames(void) { #define H_glInitNames "void glInitNames( void)" glInitNames(); return(Xen_false); } static Xen gxg_glLoadName(Xen name) { #define H_glLoadName "void glLoadName(GLuint name)" Xen_check_type(Xen_is_GLuint(name), name, 1, "glLoadName", "GLuint"); glLoadName(Xen_to_C_GLuint(name)); return(Xen_false); } static Xen gxg_glPushName(Xen name) { #define H_glPushName "void glPushName(GLuint name)" Xen_check_type(Xen_is_GLuint(name), name, 1, "glPushName", "GLuint"); glPushName(Xen_to_C_GLuint(name)); return(Xen_false); } static Xen gxg_glPopName(void) { #define H_glPopName "void glPopName( void)" glPopName(); return(Xen_false); } static Xen gxg_glDrawRangeElements(Xen mode, Xen start, Xen end, Xen count, Xen type, Xen indices) { #define H_glDrawRangeElements "void glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, \ GLenum type, GLvoid* indices)" Xen_check_type(Xen_is_GLenum(mode), mode, 1, "glDrawRangeElements", "GLenum"); Xen_check_type(Xen_is_GLuint(start), start, 2, "glDrawRangeElements", "GLuint"); Xen_check_type(Xen_is_GLuint(end), end, 3, "glDrawRangeElements", "GLuint"); Xen_check_type(Xen_is_GLsizei(count), count, 4, "glDrawRangeElements", "GLsizei"); Xen_check_type(Xen_is_GLenum(type), type, 5, "glDrawRangeElements", "GLenum"); Xen_check_type(Xen_is_GLvoid_(indices), indices, 6, "glDrawRangeElements", "GLvoid*"); glDrawRangeElements(Xen_to_C_GLenum(mode), Xen_to_C_GLuint(start), Xen_to_C_GLuint(end), Xen_to_C_GLsizei(count), Xen_to_C_GLenum(type), Xen_to_C_GLvoid_(indices)); return(Xen_false); } static Xen gxg_glTexImage3D(Xen arglist) { #define H_glTexImage3D "void glTexImage3D(GLenum target, GLint level, GLint internalFormat, GLsizei width, \ GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, GLvoid* pixels)" Xen target, level, internalFormat, width, height, depth, border, format, type, pixels; target = Xen_list_ref(arglist, 0); level = Xen_list_ref(arglist, 1); internalFormat = Xen_list_ref(arglist, 2); width = Xen_list_ref(arglist, 3); height = Xen_list_ref(arglist, 4); depth = Xen_list_ref(arglist, 5); border = Xen_list_ref(arglist, 6); format = Xen_list_ref(arglist, 7); type = Xen_list_ref(arglist, 8); pixels = Xen_list_ref(arglist, 9); Xen_check_type(Xen_is_GLenum(target), target, 1, "glTexImage3D", "GLenum"); Xen_check_type(Xen_is_GLint(level), level, 2, "glTexImage3D", "GLint"); Xen_check_type(Xen_is_GLint(internalFormat), internalFormat, 3, "glTexImage3D", "GLint"); Xen_check_type(Xen_is_GLsizei(width), width, 4, "glTexImage3D", "GLsizei"); Xen_check_type(Xen_is_GLsizei(height), height, 5, "glTexImage3D", "GLsizei"); Xen_check_type(Xen_is_GLsizei(depth), depth, 6, "glTexImage3D", "GLsizei"); Xen_check_type(Xen_is_GLint(border), border, 7, "glTexImage3D", "GLint"); Xen_check_type(Xen_is_GLenum(format), format, 8, "glTexImage3D", "GLenum"); Xen_check_type(Xen_is_GLenum(type), type, 9, "glTexImage3D", "GLenum"); Xen_check_type(Xen_is_GLvoid_(pixels), pixels, 10, "glTexImage3D", "GLvoid*"); glTexImage3D(Xen_to_C_GLenum(target), Xen_to_C_GLint(level), Xen_to_C_GLint(internalFormat), Xen_to_C_GLsizei(width), Xen_to_C_GLsizei(height), Xen_to_C_GLsizei(depth), Xen_to_C_GLint(border), Xen_to_C_GLenum(format), Xen_to_C_GLenum(type), Xen_to_C_GLvoid_(pixels)); return(Xen_false); } static Xen gxg_glTexSubImage3D(Xen arglist) { #define H_glTexSubImage3D "void glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, \ GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLvoid* pixels)" Xen target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels; target = Xen_list_ref(arglist, 0); level = Xen_list_ref(arglist, 1); xoffset = Xen_list_ref(arglist, 2); yoffset = Xen_list_ref(arglist, 3); zoffset = Xen_list_ref(arglist, 4); width = Xen_list_ref(arglist, 5); height = Xen_list_ref(arglist, 6); depth = Xen_list_ref(arglist, 7); format = Xen_list_ref(arglist, 8); type = Xen_list_ref(arglist, 9); pixels = Xen_list_ref(arglist, 10); Xen_check_type(Xen_is_GLenum(target), target, 1, "glTexSubImage3D", "GLenum"); Xen_check_type(Xen_is_GLint(level), level, 2, "glTexSubImage3D", "GLint"); Xen_check_type(Xen_is_GLint(xoffset), xoffset, 3, "glTexSubImage3D", "GLint"); Xen_check_type(Xen_is_GLint(yoffset), yoffset, 4, "glTexSubImage3D", "GLint"); Xen_check_type(Xen_is_GLint(zoffset), zoffset, 5, "glTexSubImage3D", "GLint"); Xen_check_type(Xen_is_GLsizei(width), width, 6, "glTexSubImage3D", "GLsizei"); Xen_check_type(Xen_is_GLsizei(height), height, 7, "glTexSubImage3D", "GLsizei"); Xen_check_type(Xen_is_GLsizei(depth), depth, 8, "glTexSubImage3D", "GLsizei"); Xen_check_type(Xen_is_GLenum(format), format, 9, "glTexSubImage3D", "GLenum"); Xen_check_type(Xen_is_GLenum(type), type, 10, "glTexSubImage3D", "GLenum"); Xen_check_type(Xen_is_GLvoid_(pixels), pixels, 11, "glTexSubImage3D", "GLvoid*"); glTexSubImage3D(Xen_to_C_GLenum(target), Xen_to_C_GLint(level), Xen_to_C_GLint(xoffset), Xen_to_C_GLint(yoffset), Xen_to_C_GLint(zoffset), Xen_to_C_GLsizei(width), Xen_to_C_GLsizei(height), Xen_to_C_GLsizei(depth), Xen_to_C_GLenum(format), Xen_to_C_GLenum(type), Xen_to_C_GLvoid_(pixels)); return(Xen_false); } static Xen gxg_glCopyTexSubImage3D(Xen arglist) { #define H_glCopyTexSubImage3D "void glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, \ GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)" Xen target, level, xoffset, yoffset, zoffset, x, y, width, height; target = Xen_list_ref(arglist, 0); level = Xen_list_ref(arglist, 1); xoffset = Xen_list_ref(arglist, 2); yoffset = Xen_list_ref(arglist, 3); zoffset = Xen_list_ref(arglist, 4); x = Xen_list_ref(arglist, 5); y = Xen_list_ref(arglist, 6); width = Xen_list_ref(arglist, 7); height = Xen_list_ref(arglist, 8); Xen_check_type(Xen_is_GLenum(target), target, 1, "glCopyTexSubImage3D", "GLenum"); Xen_check_type(Xen_is_GLint(level), level, 2, "glCopyTexSubImage3D", "GLint"); Xen_check_type(Xen_is_GLint(xoffset), xoffset, 3, "glCopyTexSubImage3D", "GLint"); Xen_check_type(Xen_is_GLint(yoffset), yoffset, 4, "glCopyTexSubImage3D", "GLint"); Xen_check_type(Xen_is_GLint(zoffset), zoffset, 5, "glCopyTexSubImage3D", "GLint"); Xen_check_type(Xen_is_GLint(x), x, 6, "glCopyTexSubImage3D", "GLint"); Xen_check_type(Xen_is_GLint(y), y, 7, "glCopyTexSubImage3D", "GLint"); Xen_check_type(Xen_is_GLsizei(width), width, 8, "glCopyTexSubImage3D", "GLsizei"); Xen_check_type(Xen_is_GLsizei(height), height, 9, "glCopyTexSubImage3D", "GLsizei"); glCopyTexSubImage3D(Xen_to_C_GLenum(target), Xen_to_C_GLint(level), Xen_to_C_GLint(xoffset), Xen_to_C_GLint(yoffset), Xen_to_C_GLint(zoffset), Xen_to_C_GLint(x), Xen_to_C_GLint(y), Xen_to_C_GLsizei(width), Xen_to_C_GLsizei(height)); return(Xen_false); } static Xen gxg_glColorTable(Xen target, Xen internalformat, Xen width, Xen format, Xen type, Xen table) { #define H_glColorTable "void glColorTable(GLenum target, GLenum internalformat, GLsizei width, GLenum format, \ GLenum type, GLvoid* table)" Xen_check_type(Xen_is_GLenum(target), target, 1, "glColorTable", "GLenum"); Xen_check_type(Xen_is_GLenum(internalformat), internalformat, 2, "glColorTable", "GLenum"); Xen_check_type(Xen_is_GLsizei(width), width, 3, "glColorTable", "GLsizei"); Xen_check_type(Xen_is_GLenum(format), format, 4, "glColorTable", "GLenum"); Xen_check_type(Xen_is_GLenum(type), type, 5, "glColorTable", "GLenum"); Xen_check_type(Xen_is_GLvoid_(table), table, 6, "glColorTable", "GLvoid*"); glColorTable(Xen_to_C_GLenum(target), Xen_to_C_GLenum(internalformat), Xen_to_C_GLsizei(width), Xen_to_C_GLenum(format), Xen_to_C_GLenum(type), Xen_to_C_GLvoid_(table)); return(Xen_false); } static Xen gxg_glColorSubTable(Xen target, Xen start, Xen count, Xen format, Xen type, Xen data) { #define H_glColorSubTable "void glColorSubTable(GLenum target, GLsizei start, GLsizei count, GLenum format, \ GLenum type, GLvoid* data)" Xen_check_type(Xen_is_GLenum(target), target, 1, "glColorSubTable", "GLenum"); Xen_check_type(Xen_is_GLsizei(start), start, 2, "glColorSubTable", "GLsizei"); Xen_check_type(Xen_is_GLsizei(count), count, 3, "glColorSubTable", "GLsizei"); Xen_check_type(Xen_is_GLenum(format), format, 4, "glColorSubTable", "GLenum"); Xen_check_type(Xen_is_GLenum(type), type, 5, "glColorSubTable", "GLenum"); Xen_check_type(Xen_is_GLvoid_(data), data, 6, "glColorSubTable", "GLvoid*"); glColorSubTable(Xen_to_C_GLenum(target), Xen_to_C_GLsizei(start), Xen_to_C_GLsizei(count), Xen_to_C_GLenum(format), Xen_to_C_GLenum(type), Xen_to_C_GLvoid_(data)); return(Xen_false); } static Xen gxg_glCopyColorSubTable(Xen target, Xen start, Xen x, Xen y, Xen width) { #define H_glCopyColorSubTable "void glCopyColorSubTable(GLenum target, GLsizei start, GLint x, GLint y, \ GLsizei width)" Xen_check_type(Xen_is_GLenum(target), target, 1, "glCopyColorSubTable", "GLenum"); Xen_check_type(Xen_is_GLsizei(start), start, 2, "glCopyColorSubTable", "GLsizei"); Xen_check_type(Xen_is_GLint(x), x, 3, "glCopyColorSubTable", "GLint"); Xen_check_type(Xen_is_GLint(y), y, 4, "glCopyColorSubTable", "GLint"); Xen_check_type(Xen_is_GLsizei(width), width, 5, "glCopyColorSubTable", "GLsizei"); glCopyColorSubTable(Xen_to_C_GLenum(target), Xen_to_C_GLsizei(start), Xen_to_C_GLint(x), Xen_to_C_GLint(y), Xen_to_C_GLsizei(width)); return(Xen_false); } static Xen gxg_glCopyColorTable(Xen target, Xen internalformat, Xen x, Xen y, Xen width) { #define H_glCopyColorTable "void glCopyColorTable(GLenum target, GLenum internalformat, GLint x, GLint y, \ GLsizei width)" Xen_check_type(Xen_is_GLenum(target), target, 1, "glCopyColorTable", "GLenum"); Xen_check_type(Xen_is_GLenum(internalformat), internalformat, 2, "glCopyColorTable", "GLenum"); Xen_check_type(Xen_is_GLint(x), x, 3, "glCopyColorTable", "GLint"); Xen_check_type(Xen_is_GLint(y), y, 4, "glCopyColorTable", "GLint"); Xen_check_type(Xen_is_GLsizei(width), width, 5, "glCopyColorTable", "GLsizei"); glCopyColorTable(Xen_to_C_GLenum(target), Xen_to_C_GLenum(internalformat), Xen_to_C_GLint(x), Xen_to_C_GLint(y), Xen_to_C_GLsizei(width)); return(Xen_false); } static Xen gxg_glGetColorTableParameterfv(Xen target, Xen pname, Xen params) { #define H_glGetColorTableParameterfv "void glGetColorTableParameterfv(GLenum target, GLenum pname, \ GLfloat* [params])" GLfloat ref_params[1]; Xen_check_type(Xen_is_GLenum(target), target, 1, "glGetColorTableParameterfv", "GLenum"); Xen_check_type(Xen_is_GLenum(pname), pname, 2, "glGetColorTableParameterfv", "GLenum"); glGetColorTableParameterfv(Xen_to_C_GLenum(target), Xen_to_C_GLenum(pname), ref_params); return(Xen_list_1(C_to_Xen_GLfloat(ref_params[0]))); } static Xen gxg_glGetColorTableParameteriv(Xen target, Xen pname, Xen params) { #define H_glGetColorTableParameteriv "void glGetColorTableParameteriv(GLenum target, GLenum pname, \ GLint* [params])" GLint ref_params[1]; Xen_check_type(Xen_is_GLenum(target), target, 1, "glGetColorTableParameteriv", "GLenum"); Xen_check_type(Xen_is_GLenum(pname), pname, 2, "glGetColorTableParameteriv", "GLenum"); glGetColorTableParameteriv(Xen_to_C_GLenum(target), Xen_to_C_GLenum(pname), ref_params); return(Xen_list_1(C_to_Xen_GLint(ref_params[0]))); } static Xen gxg_glBlendEquation(Xen mode) { #define H_glBlendEquation "void glBlendEquation(GLenum mode)" Xen_check_type(Xen_is_GLenum(mode), mode, 1, "glBlendEquation", "GLenum"); glBlendEquation(Xen_to_C_GLenum(mode)); return(Xen_false); } static Xen gxg_glBlendColor(Xen red, Xen green, Xen blue, Xen alpha) { #define H_glBlendColor "void glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)" Xen_check_type(Xen_is_GLclampf(red), red, 1, "glBlendColor", "GLclampf"); Xen_check_type(Xen_is_GLclampf(green), green, 2, "glBlendColor", "GLclampf"); Xen_check_type(Xen_is_GLclampf(blue), blue, 3, "glBlendColor", "GLclampf"); Xen_check_type(Xen_is_GLclampf(alpha), alpha, 4, "glBlendColor", "GLclampf"); glBlendColor(Xen_to_C_GLclampf(red), Xen_to_C_GLclampf(green), Xen_to_C_GLclampf(blue), Xen_to_C_GLclampf(alpha)); return(Xen_false); } static Xen gxg_glHistogram(Xen target, Xen width, Xen internalformat, Xen sink) { #define H_glHistogram "void glHistogram(GLenum target, GLsizei width, GLenum internalformat, GLboolean sink)" Xen_check_type(Xen_is_GLenum(target), target, 1, "glHistogram", "GLenum"); Xen_check_type(Xen_is_GLsizei(width), width, 2, "glHistogram", "GLsizei"); Xen_check_type(Xen_is_GLenum(internalformat), internalformat, 3, "glHistogram", "GLenum"); Xen_check_type(Xen_is_GLboolean(sink), sink, 4, "glHistogram", "GLboolean"); glHistogram(Xen_to_C_GLenum(target), Xen_to_C_GLsizei(width), Xen_to_C_GLenum(internalformat), Xen_to_C_GLboolean(sink)); return(Xen_false); } static Xen gxg_glResetHistogram(Xen target) { #define H_glResetHistogram "void glResetHistogram(GLenum target)" Xen_check_type(Xen_is_GLenum(target), target, 1, "glResetHistogram", "GLenum"); glResetHistogram(Xen_to_C_GLenum(target)); return(Xen_false); } static Xen gxg_glGetHistogram(Xen target, Xen reset, Xen format, Xen type, Xen values) { #define H_glGetHistogram "void glGetHistogram(GLenum target, GLboolean reset, GLenum format, GLenum type, \ GLvoid* values)" Xen_check_type(Xen_is_GLenum(target), target, 1, "glGetHistogram", "GLenum"); Xen_check_type(Xen_is_GLboolean(reset), reset, 2, "glGetHistogram", "GLboolean"); Xen_check_type(Xen_is_GLenum(format), format, 3, "glGetHistogram", "GLenum"); Xen_check_type(Xen_is_GLenum(type), type, 4, "glGetHistogram", "GLenum"); Xen_check_type(Xen_is_GLvoid_(values), values, 5, "glGetHistogram", "GLvoid*"); glGetHistogram(Xen_to_C_GLenum(target), Xen_to_C_GLboolean(reset), Xen_to_C_GLenum(format), Xen_to_C_GLenum(type), Xen_to_C_GLvoid_(values)); return(Xen_false); } static Xen gxg_glGetHistogramParameterfv(Xen target, Xen pname, Xen params) { #define H_glGetHistogramParameterfv "void glGetHistogramParameterfv(GLenum target, GLenum pname, GLfloat* [params])" GLfloat ref_params[1]; Xen_check_type(Xen_is_GLenum(target), target, 1, "glGetHistogramParameterfv", "GLenum"); Xen_check_type(Xen_is_GLenum(pname), pname, 2, "glGetHistogramParameterfv", "GLenum"); glGetHistogramParameterfv(Xen_to_C_GLenum(target), Xen_to_C_GLenum(pname), ref_params); return(Xen_list_1(C_to_Xen_GLfloat(ref_params[0]))); } static Xen gxg_glGetHistogramParameteriv(Xen target, Xen pname, Xen params) { #define H_glGetHistogramParameteriv "void glGetHistogramParameteriv(GLenum target, GLenum pname, GLint* [params])" GLint ref_params[1]; Xen_check_type(Xen_is_GLenum(target), target, 1, "glGetHistogramParameteriv", "GLenum"); Xen_check_type(Xen_is_GLenum(pname), pname, 2, "glGetHistogramParameteriv", "GLenum"); glGetHistogramParameteriv(Xen_to_C_GLenum(target), Xen_to_C_GLenum(pname), ref_params); return(Xen_list_1(C_to_Xen_GLint(ref_params[0]))); } static Xen gxg_glMinmax(Xen target, Xen internalformat, Xen sink) { #define H_glMinmax "void glMinmax(GLenum target, GLenum internalformat, GLboolean sink)" Xen_check_type(Xen_is_GLenum(target), target, 1, "glMinmax", "GLenum"); Xen_check_type(Xen_is_GLenum(internalformat), internalformat, 2, "glMinmax", "GLenum"); Xen_check_type(Xen_is_GLboolean(sink), sink, 3, "glMinmax", "GLboolean"); glMinmax(Xen_to_C_GLenum(target), Xen_to_C_GLenum(internalformat), Xen_to_C_GLboolean(sink)); return(Xen_false); } static Xen gxg_glResetMinmax(Xen target) { #define H_glResetMinmax "void glResetMinmax(GLenum target)" Xen_check_type(Xen_is_GLenum(target), target, 1, "glResetMinmax", "GLenum"); glResetMinmax(Xen_to_C_GLenum(target)); return(Xen_false); } static Xen gxg_glGetMinmax(Xen target, Xen reset, Xen format, Xen types, Xen values) { #define H_glGetMinmax "void glGetMinmax(GLenum target, GLboolean reset, GLenum format, GLenum types, \ GLvoid* values)" Xen_check_type(Xen_is_GLenum(target), target, 1, "glGetMinmax", "GLenum"); Xen_check_type(Xen_is_GLboolean(reset), reset, 2, "glGetMinmax", "GLboolean"); Xen_check_type(Xen_is_GLenum(format), format, 3, "glGetMinmax", "GLenum"); Xen_check_type(Xen_is_GLenum(types), types, 4, "glGetMinmax", "GLenum"); Xen_check_type(Xen_is_GLvoid_(values), values, 5, "glGetMinmax", "GLvoid*"); glGetMinmax(Xen_to_C_GLenum(target), Xen_to_C_GLboolean(reset), Xen_to_C_GLenum(format), Xen_to_C_GLenum(types), Xen_to_C_GLvoid_(values)); return(Xen_false); } static Xen gxg_glGetMinmaxParameterfv(Xen target, Xen pname, Xen params) { #define H_glGetMinmaxParameterfv "void glGetMinmaxParameterfv(GLenum target, GLenum pname, GLfloat* [params])" GLfloat ref_params[1]; Xen_check_type(Xen_is_GLenum(target), target, 1, "glGetMinmaxParameterfv", "GLenum"); Xen_check_type(Xen_is_GLenum(pname), pname, 2, "glGetMinmaxParameterfv", "GLenum"); glGetMinmaxParameterfv(Xen_to_C_GLenum(target), Xen_to_C_GLenum(pname), ref_params); return(Xen_list_1(C_to_Xen_GLfloat(ref_params[0]))); } static Xen gxg_glGetMinmaxParameteriv(Xen target, Xen pname, Xen params) { #define H_glGetMinmaxParameteriv "void glGetMinmaxParameteriv(GLenum target, GLenum pname, GLint* [params])" GLint ref_params[1]; Xen_check_type(Xen_is_GLenum(target), target, 1, "glGetMinmaxParameteriv", "GLenum"); Xen_check_type(Xen_is_GLenum(pname), pname, 2, "glGetMinmaxParameteriv", "GLenum"); glGetMinmaxParameteriv(Xen_to_C_GLenum(target), Xen_to_C_GLenum(pname), ref_params); return(Xen_list_1(C_to_Xen_GLint(ref_params[0]))); } static Xen gxg_glConvolutionFilter1D(Xen target, Xen internalformat, Xen width, Xen format, Xen type, Xen image) { #define H_glConvolutionFilter1D "void glConvolutionFilter1D(GLenum target, GLenum internalformat, GLsizei width, \ GLenum format, GLenum type, GLvoid* image)" Xen_check_type(Xen_is_GLenum(target), target, 1, "glConvolutionFilter1D", "GLenum"); Xen_check_type(Xen_is_GLenum(internalformat), internalformat, 2, "glConvolutionFilter1D", "GLenum"); Xen_check_type(Xen_is_GLsizei(width), width, 3, "glConvolutionFilter1D", "GLsizei"); Xen_check_type(Xen_is_GLenum(format), format, 4, "glConvolutionFilter1D", "GLenum"); Xen_check_type(Xen_is_GLenum(type), type, 5, "glConvolutionFilter1D", "GLenum"); Xen_check_type(Xen_is_GLvoid_(image), image, 6, "glConvolutionFilter1D", "GLvoid*"); glConvolutionFilter1D(Xen_to_C_GLenum(target), Xen_to_C_GLenum(internalformat), Xen_to_C_GLsizei(width), Xen_to_C_GLenum(format), Xen_to_C_GLenum(type), Xen_to_C_GLvoid_(image)); return(Xen_false); } static Xen gxg_glConvolutionFilter2D(Xen target, Xen internalformat, Xen width, Xen height, Xen format, Xen type, Xen image) { #define H_glConvolutionFilter2D "void glConvolutionFilter2D(GLenum target, GLenum internalformat, GLsizei width, \ GLsizei height, GLenum format, GLenum type, GLvoid* image)" Xen_check_type(Xen_is_GLenum(target), target, 1, "glConvolutionFilter2D", "GLenum"); Xen_check_type(Xen_is_GLenum(internalformat), internalformat, 2, "glConvolutionFilter2D", "GLenum"); Xen_check_type(Xen_is_GLsizei(width), width, 3, "glConvolutionFilter2D", "GLsizei"); Xen_check_type(Xen_is_GLsizei(height), height, 4, "glConvolutionFilter2D", "GLsizei"); Xen_check_type(Xen_is_GLenum(format), format, 5, "glConvolutionFilter2D", "GLenum"); Xen_check_type(Xen_is_GLenum(type), type, 6, "glConvolutionFilter2D", "GLenum"); Xen_check_type(Xen_is_GLvoid_(image), image, 7, "glConvolutionFilter2D", "GLvoid*"); glConvolutionFilter2D(Xen_to_C_GLenum(target), Xen_to_C_GLenum(internalformat), Xen_to_C_GLsizei(width), Xen_to_C_GLsizei(height), Xen_to_C_GLenum(format), Xen_to_C_GLenum(type), Xen_to_C_GLvoid_(image)); return(Xen_false); } static Xen gxg_glConvolutionParameterf(Xen target, Xen pname, Xen params) { #define H_glConvolutionParameterf "void glConvolutionParameterf(GLenum target, GLenum pname, GLfloat params)" Xen_check_type(Xen_is_GLenum(target), target, 1, "glConvolutionParameterf", "GLenum"); Xen_check_type(Xen_is_GLenum(pname), pname, 2, "glConvolutionParameterf", "GLenum"); Xen_check_type(Xen_is_GLfloat(params), params, 3, "glConvolutionParameterf", "GLfloat"); glConvolutionParameterf(Xen_to_C_GLenum(target), Xen_to_C_GLenum(pname), Xen_to_C_GLfloat(params)); return(Xen_false); } static Xen gxg_glConvolutionParameteri(Xen target, Xen pname, Xen params) { #define H_glConvolutionParameteri "void glConvolutionParameteri(GLenum target, GLenum pname, GLint params)" Xen_check_type(Xen_is_GLenum(target), target, 1, "glConvolutionParameteri", "GLenum"); Xen_check_type(Xen_is_GLenum(pname), pname, 2, "glConvolutionParameteri", "GLenum"); Xen_check_type(Xen_is_GLint(params), params, 3, "glConvolutionParameteri", "GLint"); glConvolutionParameteri(Xen_to_C_GLenum(target), Xen_to_C_GLenum(pname), Xen_to_C_GLint(params)); return(Xen_false); } static Xen gxg_glCopyConvolutionFilter1D(Xen target, Xen internalformat, Xen x, Xen y, Xen width) { #define H_glCopyConvolutionFilter1D "void glCopyConvolutionFilter1D(GLenum target, GLenum internalformat, \ GLint x, GLint y, GLsizei width)" Xen_check_type(Xen_is_GLenum(target), target, 1, "glCopyConvolutionFilter1D", "GLenum"); Xen_check_type(Xen_is_GLenum(internalformat), internalformat, 2, "glCopyConvolutionFilter1D", "GLenum"); Xen_check_type(Xen_is_GLint(x), x, 3, "glCopyConvolutionFilter1D", "GLint"); Xen_check_type(Xen_is_GLint(y), y, 4, "glCopyConvolutionFilter1D", "GLint"); Xen_check_type(Xen_is_GLsizei(width), width, 5, "glCopyConvolutionFilter1D", "GLsizei"); glCopyConvolutionFilter1D(Xen_to_C_GLenum(target), Xen_to_C_GLenum(internalformat), Xen_to_C_GLint(x), Xen_to_C_GLint(y), Xen_to_C_GLsizei(width)); return(Xen_false); } static Xen gxg_glCopyConvolutionFilter2D(Xen target, Xen internalformat, Xen x, Xen y, Xen width, Xen height) { #define H_glCopyConvolutionFilter2D "void glCopyConvolutionFilter2D(GLenum target, GLenum internalformat, \ GLint x, GLint y, GLsizei width, GLsizei height)" Xen_check_type(Xen_is_GLenum(target), target, 1, "glCopyConvolutionFilter2D", "GLenum"); Xen_check_type(Xen_is_GLenum(internalformat), internalformat, 2, "glCopyConvolutionFilter2D", "GLenum"); Xen_check_type(Xen_is_GLint(x), x, 3, "glCopyConvolutionFilter2D", "GLint"); Xen_check_type(Xen_is_GLint(y), y, 4, "glCopyConvolutionFilter2D", "GLint"); Xen_check_type(Xen_is_GLsizei(width), width, 5, "glCopyConvolutionFilter2D", "GLsizei"); Xen_check_type(Xen_is_GLsizei(height), height, 6, "glCopyConvolutionFilter2D", "GLsizei"); glCopyConvolutionFilter2D(Xen_to_C_GLenum(target), Xen_to_C_GLenum(internalformat), Xen_to_C_GLint(x), Xen_to_C_GLint(y), Xen_to_C_GLsizei(width), Xen_to_C_GLsizei(height)); return(Xen_false); } static Xen gxg_glSeparableFilter2D(Xen arglist) { #define H_glSeparableFilter2D "void glSeparableFilter2D(GLenum target, GLenum internalformat, GLsizei width, \ GLsizei height, GLenum format, GLenum type, GLvoid* row, GLvoid* column)" Xen target, internalformat, width, height, format, type, row, column; target = Xen_list_ref(arglist, 0); internalformat = Xen_list_ref(arglist, 1); width = Xen_list_ref(arglist, 2); height = Xen_list_ref(arglist, 3); format = Xen_list_ref(arglist, 4); type = Xen_list_ref(arglist, 5); row = Xen_list_ref(arglist, 6); column = Xen_list_ref(arglist, 7); Xen_check_type(Xen_is_GLenum(target), target, 1, "glSeparableFilter2D", "GLenum"); Xen_check_type(Xen_is_GLenum(internalformat), internalformat, 2, "glSeparableFilter2D", "GLenum"); Xen_check_type(Xen_is_GLsizei(width), width, 3, "glSeparableFilter2D", "GLsizei"); Xen_check_type(Xen_is_GLsizei(height), height, 4, "glSeparableFilter2D", "GLsizei"); Xen_check_type(Xen_is_GLenum(format), format, 5, "glSeparableFilter2D", "GLenum"); Xen_check_type(Xen_is_GLenum(type), type, 6, "glSeparableFilter2D", "GLenum"); Xen_check_type(Xen_is_GLvoid_(row), row, 7, "glSeparableFilter2D", "GLvoid*"); Xen_check_type(Xen_is_GLvoid_(column), column, 8, "glSeparableFilter2D", "GLvoid*"); glSeparableFilter2D(Xen_to_C_GLenum(target), Xen_to_C_GLenum(internalformat), Xen_to_C_GLsizei(width), Xen_to_C_GLsizei(height), Xen_to_C_GLenum(format), Xen_to_C_GLenum(type), Xen_to_C_GLvoid_(row), Xen_to_C_GLvoid_(column)); return(Xen_false); } #if HAVE_GLU static Xen gxg_gluBeginCurve(Xen nurb) { #define H_gluBeginCurve "void gluBeginCurve(GLUnurbs* nurb)" Xen_check_type(Xen_is_GLUnurbs_(nurb), nurb, 1, "gluBeginCurve", "GLUnurbs*"); gluBeginCurve(Xen_to_C_GLUnurbs_(nurb)); return(Xen_false); } #ifdef GLU_VERSION_1_2 static Xen gxg_gluBeginPolygon(Xen tess) { #define H_gluBeginPolygon "void gluBeginPolygon(GLUtesselator* tess)" Xen_check_type(Xen_is_GLUtesselator_(tess), tess, 1, "gluBeginPolygon", "GLUtesselator*"); gluBeginPolygon(Xen_to_C_GLUtesselator_(tess)); return(Xen_false); } #endif static Xen gxg_gluBeginSurface(Xen nurb) { #define H_gluBeginSurface "void gluBeginSurface(GLUnurbs* nurb)" Xen_check_type(Xen_is_GLUnurbs_(nurb), nurb, 1, "gluBeginSurface", "GLUnurbs*"); gluBeginSurface(Xen_to_C_GLUnurbs_(nurb)); return(Xen_false); } static Xen gxg_gluBeginTrim(Xen nurb) { #define H_gluBeginTrim "void gluBeginTrim(GLUnurbs* nurb)" Xen_check_type(Xen_is_GLUnurbs_(nurb), nurb, 1, "gluBeginTrim", "GLUnurbs*"); gluBeginTrim(Xen_to_C_GLUnurbs_(nurb)); return(Xen_false); } static Xen gxg_gluBuild1DMipmapLevels(Xen arglist) { #define H_gluBuild1DMipmapLevels "GLint gluBuild1DMipmapLevels(GLenum target, GLint internalFormat, \ GLsizei width, GLenum format, GLenum type, GLint level, GLint base, GLint max, void* data)" Xen target, internalFormat, width, format, type, level, base, max, data; target = Xen_list_ref(arglist, 0); internalFormat = Xen_list_ref(arglist, 1); width = Xen_list_ref(arglist, 2); format = Xen_list_ref(arglist, 3); type = Xen_list_ref(arglist, 4); level = Xen_list_ref(arglist, 5); base = Xen_list_ref(arglist, 6); max = Xen_list_ref(arglist, 7); data = Xen_list_ref(arglist, 8); Xen_check_type(Xen_is_GLenum(target), target, 1, "gluBuild1DMipmapLevels", "GLenum"); Xen_check_type(Xen_is_GLint(internalFormat), internalFormat, 2, "gluBuild1DMipmapLevels", "GLint"); Xen_check_type(Xen_is_GLsizei(width), width, 3, "gluBuild1DMipmapLevels", "GLsizei"); Xen_check_type(Xen_is_GLenum(format), format, 4, "gluBuild1DMipmapLevels", "GLenum"); Xen_check_type(Xen_is_GLenum(type), type, 5, "gluBuild1DMipmapLevels", "GLenum"); Xen_check_type(Xen_is_GLint(level), level, 6, "gluBuild1DMipmapLevels", "GLint"); Xen_check_type(Xen_is_GLint(base), base, 7, "gluBuild1DMipmapLevels", "GLint"); Xen_check_type(Xen_is_GLint(max), max, 8, "gluBuild1DMipmapLevels", "GLint"); Xen_check_type(Xen_is_void_(data), data, 9, "gluBuild1DMipmapLevels", "void*"); return(C_to_Xen_GLint(gluBuild1DMipmapLevels(Xen_to_C_GLenum(target), Xen_to_C_GLint(internalFormat), Xen_to_C_GLsizei(width), Xen_to_C_GLenum(format), Xen_to_C_GLenum(type), Xen_to_C_GLint(level), Xen_to_C_GLint(base), Xen_to_C_GLint(max), Xen_to_C_void_(data)))); } static Xen gxg_gluBuild1DMipmaps(Xen target, Xen internalFormat, Xen width, Xen format, Xen type, Xen data) { #define H_gluBuild1DMipmaps "GLint gluBuild1DMipmaps(GLenum target, GLint internalFormat, GLsizei width, \ GLenum format, GLenum type, void* data)" Xen_check_type(Xen_is_GLenum(target), target, 1, "gluBuild1DMipmaps", "GLenum"); Xen_check_type(Xen_is_GLint(internalFormat), internalFormat, 2, "gluBuild1DMipmaps", "GLint"); Xen_check_type(Xen_is_GLsizei(width), width, 3, "gluBuild1DMipmaps", "GLsizei"); Xen_check_type(Xen_is_GLenum(format), format, 4, "gluBuild1DMipmaps", "GLenum"); Xen_check_type(Xen_is_GLenum(type), type, 5, "gluBuild1DMipmaps", "GLenum"); Xen_check_type(Xen_is_void_(data), data, 6, "gluBuild1DMipmaps", "void*"); return(C_to_Xen_GLint(gluBuild1DMipmaps(Xen_to_C_GLenum(target), Xen_to_C_GLint(internalFormat), Xen_to_C_GLsizei(width), Xen_to_C_GLenum(format), Xen_to_C_GLenum(type), Xen_to_C_void_(data)))); } static Xen gxg_gluBuild2DMipmapLevels(Xen arglist) { #define H_gluBuild2DMipmapLevels "GLint gluBuild2DMipmapLevels(GLenum target, GLint internalFormat, \ GLsizei width, GLsizei height, GLenum format, GLenum type, GLint level, GLint base, GLint max, void* data)" Xen target, internalFormat, width, height, format, type, level, base, max, data; target = Xen_list_ref(arglist, 0); internalFormat = Xen_list_ref(arglist, 1); width = Xen_list_ref(arglist, 2); height = Xen_list_ref(arglist, 3); format = Xen_list_ref(arglist, 4); type = Xen_list_ref(arglist, 5); level = Xen_list_ref(arglist, 6); base = Xen_list_ref(arglist, 7); max = Xen_list_ref(arglist, 8); data = Xen_list_ref(arglist, 9); Xen_check_type(Xen_is_GLenum(target), target, 1, "gluBuild2DMipmapLevels", "GLenum"); Xen_check_type(Xen_is_GLint(internalFormat), internalFormat, 2, "gluBuild2DMipmapLevels", "GLint"); Xen_check_type(Xen_is_GLsizei(width), width, 3, "gluBuild2DMipmapLevels", "GLsizei"); Xen_check_type(Xen_is_GLsizei(height), height, 4, "gluBuild2DMipmapLevels", "GLsizei"); Xen_check_type(Xen_is_GLenum(format), format, 5, "gluBuild2DMipmapLevels", "GLenum"); Xen_check_type(Xen_is_GLenum(type), type, 6, "gluBuild2DMipmapLevels", "GLenum"); Xen_check_type(Xen_is_GLint(level), level, 7, "gluBuild2DMipmapLevels", "GLint"); Xen_check_type(Xen_is_GLint(base), base, 8, "gluBuild2DMipmapLevels", "GLint"); Xen_check_type(Xen_is_GLint(max), max, 9, "gluBuild2DMipmapLevels", "GLint"); Xen_check_type(Xen_is_void_(data), data, 10, "gluBuild2DMipmapLevels", "void*"); return(C_to_Xen_GLint(gluBuild2DMipmapLevels(Xen_to_C_GLenum(target), Xen_to_C_GLint(internalFormat), Xen_to_C_GLsizei(width), Xen_to_C_GLsizei(height), Xen_to_C_GLenum(format), Xen_to_C_GLenum(type), Xen_to_C_GLint(level), Xen_to_C_GLint(base), Xen_to_C_GLint(max), Xen_to_C_void_(data)))); } static Xen gxg_gluBuild2DMipmaps(Xen target, Xen internalFormat, Xen width, Xen height, Xen format, Xen type, Xen data) { #define H_gluBuild2DMipmaps "GLint gluBuild2DMipmaps(GLenum target, GLint internalFormat, GLsizei width, \ GLsizei height, GLenum format, GLenum type, void* data)" Xen_check_type(Xen_is_GLenum(target), target, 1, "gluBuild2DMipmaps", "GLenum"); Xen_check_type(Xen_is_GLint(internalFormat), internalFormat, 2, "gluBuild2DMipmaps", "GLint"); Xen_check_type(Xen_is_GLsizei(width), width, 3, "gluBuild2DMipmaps", "GLsizei"); Xen_check_type(Xen_is_GLsizei(height), height, 4, "gluBuild2DMipmaps", "GLsizei"); Xen_check_type(Xen_is_GLenum(format), format, 5, "gluBuild2DMipmaps", "GLenum"); Xen_check_type(Xen_is_GLenum(type), type, 6, "gluBuild2DMipmaps", "GLenum"); Xen_check_type(Xen_is_void_(data), data, 7, "gluBuild2DMipmaps", "void*"); return(C_to_Xen_GLint(gluBuild2DMipmaps(Xen_to_C_GLenum(target), Xen_to_C_GLint(internalFormat), Xen_to_C_GLsizei(width), Xen_to_C_GLsizei(height), Xen_to_C_GLenum(format), Xen_to_C_GLenum(type), Xen_to_C_void_(data)))); } static Xen gxg_gluBuild3DMipmapLevels(Xen arglist) { #define H_gluBuild3DMipmapLevels "GLint gluBuild3DMipmapLevels(GLenum target, GLint internalFormat, \ GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLint level, GLint base, GLint max, \ void* data)" Xen target, internalFormat, width, height, depth, format, type, level, base, max, data; target = Xen_list_ref(arglist, 0); internalFormat = Xen_list_ref(arglist, 1); width = Xen_list_ref(arglist, 2); height = Xen_list_ref(arglist, 3); depth = Xen_list_ref(arglist, 4); format = Xen_list_ref(arglist, 5); type = Xen_list_ref(arglist, 6); level = Xen_list_ref(arglist, 7); base = Xen_list_ref(arglist, 8); max = Xen_list_ref(arglist, 9); data = Xen_list_ref(arglist, 10); Xen_check_type(Xen_is_GLenum(target), target, 1, "gluBuild3DMipmapLevels", "GLenum"); Xen_check_type(Xen_is_GLint(internalFormat), internalFormat, 2, "gluBuild3DMipmapLevels", "GLint"); Xen_check_type(Xen_is_GLsizei(width), width, 3, "gluBuild3DMipmapLevels", "GLsizei"); Xen_check_type(Xen_is_GLsizei(height), height, 4, "gluBuild3DMipmapLevels", "GLsizei"); Xen_check_type(Xen_is_GLsizei(depth), depth, 5, "gluBuild3DMipmapLevels", "GLsizei"); Xen_check_type(Xen_is_GLenum(format), format, 6, "gluBuild3DMipmapLevels", "GLenum"); Xen_check_type(Xen_is_GLenum(type), type, 7, "gluBuild3DMipmapLevels", "GLenum"); Xen_check_type(Xen_is_GLint(level), level, 8, "gluBuild3DMipmapLevels", "GLint"); Xen_check_type(Xen_is_GLint(base), base, 9, "gluBuild3DMipmapLevels", "GLint"); Xen_check_type(Xen_is_GLint(max), max, 10, "gluBuild3DMipmapLevels", "GLint"); Xen_check_type(Xen_is_void_(data), data, 11, "gluBuild3DMipmapLevels", "void*"); return(C_to_Xen_GLint(gluBuild3DMipmapLevels(Xen_to_C_GLenum(target), Xen_to_C_GLint(internalFormat), Xen_to_C_GLsizei(width), Xen_to_C_GLsizei(height), Xen_to_C_GLsizei(depth), Xen_to_C_GLenum(format), Xen_to_C_GLenum(type), Xen_to_C_GLint(level), Xen_to_C_GLint(base), Xen_to_C_GLint(max), Xen_to_C_void_(data)))); } static Xen gxg_gluBuild3DMipmaps(Xen arglist) { #define H_gluBuild3DMipmaps "GLint gluBuild3DMipmaps(GLenum target, GLint internalFormat, GLsizei width, \ GLsizei height, GLsizei depth, GLenum format, GLenum type, void* data)" Xen target, internalFormat, width, height, depth, format, type, data; target = Xen_list_ref(arglist, 0); internalFormat = Xen_list_ref(arglist, 1); width = Xen_list_ref(arglist, 2); height = Xen_list_ref(arglist, 3); depth = Xen_list_ref(arglist, 4); format = Xen_list_ref(arglist, 5); type = Xen_list_ref(arglist, 6); data = Xen_list_ref(arglist, 7); Xen_check_type(Xen_is_GLenum(target), target, 1, "gluBuild3DMipmaps", "GLenum"); Xen_check_type(Xen_is_GLint(internalFormat), internalFormat, 2, "gluBuild3DMipmaps", "GLint"); Xen_check_type(Xen_is_GLsizei(width), width, 3, "gluBuild3DMipmaps", "GLsizei"); Xen_check_type(Xen_is_GLsizei(height), height, 4, "gluBuild3DMipmaps", "GLsizei"); Xen_check_type(Xen_is_GLsizei(depth), depth, 5, "gluBuild3DMipmaps", "GLsizei"); Xen_check_type(Xen_is_GLenum(format), format, 6, "gluBuild3DMipmaps", "GLenum"); Xen_check_type(Xen_is_GLenum(type), type, 7, "gluBuild3DMipmaps", "GLenum"); Xen_check_type(Xen_is_void_(data), data, 8, "gluBuild3DMipmaps", "void*"); return(C_to_Xen_GLint(gluBuild3DMipmaps(Xen_to_C_GLenum(target), Xen_to_C_GLint(internalFormat), Xen_to_C_GLsizei(width), Xen_to_C_GLsizei(height), Xen_to_C_GLsizei(depth), Xen_to_C_GLenum(format), Xen_to_C_GLenum(type), Xen_to_C_void_(data)))); } static Xen gxg_gluCheckExtension(Xen extName, Xen extString) { #define H_gluCheckExtension "GLboolean gluCheckExtension(GLubyte* extName, GLubyte* extString)" Xen_check_type(Xen_is_GLubyte_(extName), extName, 1, "gluCheckExtension", "GLubyte*"); Xen_check_type(Xen_is_GLubyte_(extString), extString, 2, "gluCheckExtension", "GLubyte*"); return(C_to_Xen_GLboolean(gluCheckExtension(Xen_to_C_GLubyte_(extName), Xen_to_C_GLubyte_(extString)))); } static Xen gxg_gluCylinder(Xen quad, Xen base, Xen top, Xen height, Xen slices, Xen stacks) { #define H_gluCylinder "void gluCylinder(GLUquadric* quad, GLdouble base, GLdouble top, GLdouble height, \ GLint slices, GLint stacks)" Xen_check_type(Xen_is_GLUquadric_(quad), quad, 1, "gluCylinder", "GLUquadric*"); Xen_check_type(Xen_is_GLdouble(base), base, 2, "gluCylinder", "GLdouble"); Xen_check_type(Xen_is_GLdouble(top), top, 3, "gluCylinder", "GLdouble"); Xen_check_type(Xen_is_GLdouble(height), height, 4, "gluCylinder", "GLdouble"); Xen_check_type(Xen_is_GLint(slices), slices, 5, "gluCylinder", "GLint"); Xen_check_type(Xen_is_GLint(stacks), stacks, 6, "gluCylinder", "GLint"); gluCylinder(Xen_to_C_GLUquadric_(quad), Xen_to_C_GLdouble(base), Xen_to_C_GLdouble(top), Xen_to_C_GLdouble(height), Xen_to_C_GLint(slices), Xen_to_C_GLint(stacks)); return(Xen_false); } static Xen gxg_gluDeleteNurbsRenderer(Xen nurb) { #define H_gluDeleteNurbsRenderer "void gluDeleteNurbsRenderer(GLUnurbs* nurb)" Xen_check_type(Xen_is_GLUnurbs_(nurb), nurb, 1, "gluDeleteNurbsRenderer", "GLUnurbs*"); gluDeleteNurbsRenderer(Xen_to_C_GLUnurbs_(nurb)); return(Xen_false); } static Xen gxg_gluDeleteQuadric(Xen quad) { #define H_gluDeleteQuadric "void gluDeleteQuadric(GLUquadric* quad)" Xen_check_type(Xen_is_GLUquadric_(quad), quad, 1, "gluDeleteQuadric", "GLUquadric*"); gluDeleteQuadric(Xen_to_C_GLUquadric_(quad)); return(Xen_false); } #ifdef GLU_VERSION_1_2 static Xen gxg_gluDeleteTess(Xen tess) { #define H_gluDeleteTess "void gluDeleteTess(GLUtesselator* tess)" Xen_check_type(Xen_is_GLUtesselator_(tess), tess, 1, "gluDeleteTess", "GLUtesselator*"); gluDeleteTess(Xen_to_C_GLUtesselator_(tess)); return(Xen_false); } #endif static Xen gxg_gluDisk(Xen quad, Xen inner, Xen outer, Xen slices, Xen loops) { #define H_gluDisk "void gluDisk(GLUquadric* quad, GLdouble inner, GLdouble outer, GLint slices, GLint loops)" Xen_check_type(Xen_is_GLUquadric_(quad), quad, 1, "gluDisk", "GLUquadric*"); Xen_check_type(Xen_is_GLdouble(inner), inner, 2, "gluDisk", "GLdouble"); Xen_check_type(Xen_is_GLdouble(outer), outer, 3, "gluDisk", "GLdouble"); Xen_check_type(Xen_is_GLint(slices), slices, 4, "gluDisk", "GLint"); Xen_check_type(Xen_is_GLint(loops), loops, 5, "gluDisk", "GLint"); gluDisk(Xen_to_C_GLUquadric_(quad), Xen_to_C_GLdouble(inner), Xen_to_C_GLdouble(outer), Xen_to_C_GLint(slices), Xen_to_C_GLint(loops)); return(Xen_false); } static Xen gxg_gluEndCurve(Xen nurb) { #define H_gluEndCurve "void gluEndCurve(GLUnurbs* nurb)" Xen_check_type(Xen_is_GLUnurbs_(nurb), nurb, 1, "gluEndCurve", "GLUnurbs*"); gluEndCurve(Xen_to_C_GLUnurbs_(nurb)); return(Xen_false); } #ifdef GLU_VERSION_1_2 static Xen gxg_gluEndPolygon(Xen tess) { #define H_gluEndPolygon "void gluEndPolygon(GLUtesselator* tess)" Xen_check_type(Xen_is_GLUtesselator_(tess), tess, 1, "gluEndPolygon", "GLUtesselator*"); gluEndPolygon(Xen_to_C_GLUtesselator_(tess)); return(Xen_false); } #endif static Xen gxg_gluEndSurface(Xen nurb) { #define H_gluEndSurface "void gluEndSurface(GLUnurbs* nurb)" Xen_check_type(Xen_is_GLUnurbs_(nurb), nurb, 1, "gluEndSurface", "GLUnurbs*"); gluEndSurface(Xen_to_C_GLUnurbs_(nurb)); return(Xen_false); } static Xen gxg_gluEndTrim(Xen nurb) { #define H_gluEndTrim "void gluEndTrim(GLUnurbs* nurb)" Xen_check_type(Xen_is_GLUnurbs_(nurb), nurb, 1, "gluEndTrim", "GLUnurbs*"); gluEndTrim(Xen_to_C_GLUnurbs_(nurb)); return(Xen_false); } static Xen gxg_gluErrorString(Xen error) { #define H_gluErrorString "constchar* gluErrorString(GLenum error)" Xen_check_type(Xen_is_GLenum(error), error, 1, "gluErrorString", "GLenum"); return(C_to_Xen_constchar_(gluErrorString(Xen_to_C_GLenum(error)))); } static Xen gxg_gluGetNurbsProperty(Xen nurb, Xen property, Xen data) { #define H_gluGetNurbsProperty "void gluGetNurbsProperty(GLUnurbs* nurb, GLenum property, GLfloat* data)" Xen_check_type(Xen_is_GLUnurbs_(nurb), nurb, 1, "gluGetNurbsProperty", "GLUnurbs*"); Xen_check_type(Xen_is_GLenum(property), property, 2, "gluGetNurbsProperty", "GLenum"); Xen_check_type(Xen_is_GLfloat_(data), data, 3, "gluGetNurbsProperty", "GLfloat*"); gluGetNurbsProperty(Xen_to_C_GLUnurbs_(nurb), Xen_to_C_GLenum(property), Xen_to_C_GLfloat_(data)); return(Xen_false); } static Xen gxg_gluGetString(Xen name) { #define H_gluGetString "constchar* gluGetString(GLenum name)" Xen_check_type(Xen_is_GLenum(name), name, 1, "gluGetString", "GLenum"); return(C_to_Xen_constchar_(gluGetString(Xen_to_C_GLenum(name)))); } #ifdef GLU_VERSION_1_2 static Xen gxg_gluGetTessProperty(Xen tess, Xen which, Xen data) { #define H_gluGetTessProperty "void gluGetTessProperty(GLUtesselator* tess, GLenum which, GLdouble* data)" Xen_check_type(Xen_is_GLUtesselator_(tess), tess, 1, "gluGetTessProperty", "GLUtesselator*"); Xen_check_type(Xen_is_GLenum(which), which, 2, "gluGetTessProperty", "GLenum"); Xen_check_type(Xen_is_GLdouble_(data), data, 3, "gluGetTessProperty", "GLdouble*"); gluGetTessProperty(Xen_to_C_GLUtesselator_(tess), Xen_to_C_GLenum(which), Xen_to_C_GLdouble_(data)); return(Xen_false); } #endif static Xen gxg_gluLoadSamplingMatrices(Xen nurb, Xen model, Xen perspective, Xen view) { #define H_gluLoadSamplingMatrices "void gluLoadSamplingMatrices(GLUnurbs* nurb, GLfloat* model, GLfloat* perspective, \ GLint* view)" Xen_check_type(Xen_is_GLUnurbs_(nurb), nurb, 1, "gluLoadSamplingMatrices", "GLUnurbs*"); Xen_check_type(Xen_is_GLfloat_(model), model, 2, "gluLoadSamplingMatrices", "GLfloat*"); Xen_check_type(Xen_is_GLfloat_(perspective), perspective, 3, "gluLoadSamplingMatrices", "GLfloat*"); Xen_check_type(Xen_is_GLint_(view), view, 4, "gluLoadSamplingMatrices", "GLint*"); gluLoadSamplingMatrices(Xen_to_C_GLUnurbs_(nurb), Xen_to_C_GLfloat_(model), Xen_to_C_GLfloat_(perspective), Xen_to_C_GLint_(view)); return(Xen_false); } static Xen gxg_gluLookAt(Xen arglist) { #define H_gluLookAt "void gluLookAt(GLdouble eyeX, GLdouble eyeY, GLdouble eyeZ, GLdouble centerX, \ GLdouble centerY, GLdouble centerZ, GLdouble upX, GLdouble upY, GLdouble upZ)" Xen eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ; eyeX = Xen_list_ref(arglist, 0); eyeY = Xen_list_ref(arglist, 1); eyeZ = Xen_list_ref(arglist, 2); centerX = Xen_list_ref(arglist, 3); centerY = Xen_list_ref(arglist, 4); centerZ = Xen_list_ref(arglist, 5); upX = Xen_list_ref(arglist, 6); upY = Xen_list_ref(arglist, 7); upZ = Xen_list_ref(arglist, 8); Xen_check_type(Xen_is_GLdouble(eyeX), eyeX, 1, "gluLookAt", "GLdouble"); Xen_check_type(Xen_is_GLdouble(eyeY), eyeY, 2, "gluLookAt", "GLdouble"); Xen_check_type(Xen_is_GLdouble(eyeZ), eyeZ, 3, "gluLookAt", "GLdouble"); Xen_check_type(Xen_is_GLdouble(centerX), centerX, 4, "gluLookAt", "GLdouble"); Xen_check_type(Xen_is_GLdouble(centerY), centerY, 5, "gluLookAt", "GLdouble"); Xen_check_type(Xen_is_GLdouble(centerZ), centerZ, 6, "gluLookAt", "GLdouble"); Xen_check_type(Xen_is_GLdouble(upX), upX, 7, "gluLookAt", "GLdouble"); Xen_check_type(Xen_is_GLdouble(upY), upY, 8, "gluLookAt", "GLdouble"); Xen_check_type(Xen_is_GLdouble(upZ), upZ, 9, "gluLookAt", "GLdouble"); gluLookAt(Xen_to_C_GLdouble(eyeX), Xen_to_C_GLdouble(eyeY), Xen_to_C_GLdouble(eyeZ), Xen_to_C_GLdouble(centerX), Xen_to_C_GLdouble(centerY), Xen_to_C_GLdouble(centerZ), Xen_to_C_GLdouble(upX), Xen_to_C_GLdouble(upY), Xen_to_C_GLdouble(upZ)); return(Xen_false); } static Xen gxg_gluNewNurbsRenderer(void) { #define H_gluNewNurbsRenderer "GLUnurbs* gluNewNurbsRenderer( void)" return(C_to_Xen_GLUnurbs_(gluNewNurbsRenderer())); } static Xen gxg_gluNewQuadric(void) { #define H_gluNewQuadric "GLUquadric* gluNewQuadric( void)" return(C_to_Xen_GLUquadric_(gluNewQuadric())); } #ifdef GLU_VERSION_1_2 static Xen gxg_gluNewTess(void) { #define H_gluNewTess "GLUtesselator* gluNewTess( void)" return(C_to_Xen_GLUtesselator_(gluNewTess())); } #endif #ifdef GLU_VERSION_1_2 static Xen gxg_gluNextContour(Xen tess, Xen type) { #define H_gluNextContour "void gluNextContour(GLUtesselator* tess, GLenum type)" Xen_check_type(Xen_is_GLUtesselator_(tess), tess, 1, "gluNextContour", "GLUtesselator*"); Xen_check_type(Xen_is_GLenum(type), type, 2, "gluNextContour", "GLenum"); gluNextContour(Xen_to_C_GLUtesselator_(tess), Xen_to_C_GLenum(type)); return(Xen_false); } #endif static Xen gxg_gluNurbsCallback(Xen nurb, Xen which, Xen CallBackFunc) { #define H_gluNurbsCallback "void gluNurbsCallback(GLUnurbs* nurb, GLenum which, _GLUfuncptr CallBackFunc)" Xen_check_type(Xen_is_GLUnurbs_(nurb), nurb, 1, "gluNurbsCallback", "GLUnurbs*"); Xen_check_type(Xen_is_GLenum(which), which, 2, "gluNurbsCallback", "GLenum"); Xen_check_type(Xen_is__GLUfuncptr(CallBackFunc), CallBackFunc, 3, "gluNurbsCallback", "_GLUfuncptr"); gluNurbsCallback(Xen_to_C_GLUnurbs_(nurb), Xen_to_C_GLenum(which), Xen_to_C__GLUfuncptr(CallBackFunc)); return(Xen_false); } static Xen gxg_gluNurbsCallbackData(Xen nurb, Xen userData) { #define H_gluNurbsCallbackData "void gluNurbsCallbackData(GLUnurbs* nurb, GLvoid* userData)" Xen_check_type(Xen_is_GLUnurbs_(nurb), nurb, 1, "gluNurbsCallbackData", "GLUnurbs*"); Xen_check_type(Xen_is_GLvoid_(userData), userData, 2, "gluNurbsCallbackData", "GLvoid*"); gluNurbsCallbackData(Xen_to_C_GLUnurbs_(nurb), Xen_to_C_GLvoid_(userData)); return(Xen_false); } static Xen gxg_gluNurbsCurve(Xen nurb, Xen knotCount, Xen knots, Xen stride, Xen control, Xen order, Xen type) { #define H_gluNurbsCurve "void gluNurbsCurve(GLUnurbs* nurb, GLint knotCount, GLfloat* knots, GLint stride, \ GLfloat* control, GLint order, GLenum type)" Xen_check_type(Xen_is_GLUnurbs_(nurb), nurb, 1, "gluNurbsCurve", "GLUnurbs*"); Xen_check_type(Xen_is_GLint(knotCount), knotCount, 2, "gluNurbsCurve", "GLint"); Xen_check_type(Xen_is_GLfloat_(knots), knots, 3, "gluNurbsCurve", "GLfloat*"); Xen_check_type(Xen_is_GLint(stride), stride, 4, "gluNurbsCurve", "GLint"); Xen_check_type(Xen_is_GLfloat_(control), control, 5, "gluNurbsCurve", "GLfloat*"); Xen_check_type(Xen_is_GLint(order), order, 6, "gluNurbsCurve", "GLint"); Xen_check_type(Xen_is_GLenum(type), type, 7, "gluNurbsCurve", "GLenum"); gluNurbsCurve(Xen_to_C_GLUnurbs_(nurb), Xen_to_C_GLint(knotCount), Xen_to_C_GLfloat_(knots), Xen_to_C_GLint(stride), Xen_to_C_GLfloat_(control), Xen_to_C_GLint(order), Xen_to_C_GLenum(type)); return(Xen_false); } static Xen gxg_gluNurbsProperty(Xen nurb, Xen property, Xen value) { #define H_gluNurbsProperty "void gluNurbsProperty(GLUnurbs* nurb, GLenum property, GLfloat value)" Xen_check_type(Xen_is_GLUnurbs_(nurb), nurb, 1, "gluNurbsProperty", "GLUnurbs*"); Xen_check_type(Xen_is_GLenum(property), property, 2, "gluNurbsProperty", "GLenum"); Xen_check_type(Xen_is_GLfloat(value), value, 3, "gluNurbsProperty", "GLfloat"); gluNurbsProperty(Xen_to_C_GLUnurbs_(nurb), Xen_to_C_GLenum(property), Xen_to_C_GLfloat(value)); return(Xen_false); } static Xen gxg_gluNurbsSurface(Xen arglist) { #define H_gluNurbsSurface "void gluNurbsSurface(GLUnurbs* nurb, GLint sKnotCount, GLfloat* sKnots, \ GLint tKnotCount, GLfloat* tKnots, GLint sStride, GLint tStride, GLfloat* control, GLint sOrder, GLint tOrder, \ GLenum type)" Xen nurb, sKnotCount, sKnots, tKnotCount, tKnots, sStride, tStride, control, sOrder, tOrder, type; nurb = Xen_list_ref(arglist, 0); sKnotCount = Xen_list_ref(arglist, 1); sKnots = Xen_list_ref(arglist, 2); tKnotCount = Xen_list_ref(arglist, 3); tKnots = Xen_list_ref(arglist, 4); sStride = Xen_list_ref(arglist, 5); tStride = Xen_list_ref(arglist, 6); control = Xen_list_ref(arglist, 7); sOrder = Xen_list_ref(arglist, 8); tOrder = Xen_list_ref(arglist, 9); type = Xen_list_ref(arglist, 10); Xen_check_type(Xen_is_GLUnurbs_(nurb), nurb, 1, "gluNurbsSurface", "GLUnurbs*"); Xen_check_type(Xen_is_GLint(sKnotCount), sKnotCount, 2, "gluNurbsSurface", "GLint"); Xen_check_type(Xen_is_GLfloat_(sKnots), sKnots, 3, "gluNurbsSurface", "GLfloat*"); Xen_check_type(Xen_is_GLint(tKnotCount), tKnotCount, 4, "gluNurbsSurface", "GLint"); Xen_check_type(Xen_is_GLfloat_(tKnots), tKnots, 5, "gluNurbsSurface", "GLfloat*"); Xen_check_type(Xen_is_GLint(sStride), sStride, 6, "gluNurbsSurface", "GLint"); Xen_check_type(Xen_is_GLint(tStride), tStride, 7, "gluNurbsSurface", "GLint"); Xen_check_type(Xen_is_GLfloat_(control), control, 8, "gluNurbsSurface", "GLfloat*"); Xen_check_type(Xen_is_GLint(sOrder), sOrder, 9, "gluNurbsSurface", "GLint"); Xen_check_type(Xen_is_GLint(tOrder), tOrder, 10, "gluNurbsSurface", "GLint"); Xen_check_type(Xen_is_GLenum(type), type, 11, "gluNurbsSurface", "GLenum"); gluNurbsSurface(Xen_to_C_GLUnurbs_(nurb), Xen_to_C_GLint(sKnotCount), Xen_to_C_GLfloat_(sKnots), Xen_to_C_GLint(tKnotCount), Xen_to_C_GLfloat_(tKnots), Xen_to_C_GLint(sStride), Xen_to_C_GLint(tStride), Xen_to_C_GLfloat_(control), Xen_to_C_GLint(sOrder), Xen_to_C_GLint(tOrder), Xen_to_C_GLenum(type)); return(Xen_false); } static Xen gxg_gluOrtho2D(Xen left, Xen right, Xen bottom, Xen top) { #define H_gluOrtho2D "void gluOrtho2D(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top)" Xen_check_type(Xen_is_GLdouble(left), left, 1, "gluOrtho2D", "GLdouble"); Xen_check_type(Xen_is_GLdouble(right), right, 2, "gluOrtho2D", "GLdouble"); Xen_check_type(Xen_is_GLdouble(bottom), bottom, 3, "gluOrtho2D", "GLdouble"); Xen_check_type(Xen_is_GLdouble(top), top, 4, "gluOrtho2D", "GLdouble"); gluOrtho2D(Xen_to_C_GLdouble(left), Xen_to_C_GLdouble(right), Xen_to_C_GLdouble(bottom), Xen_to_C_GLdouble(top)); return(Xen_false); } static Xen gxg_gluPartialDisk(Xen quad, Xen inner, Xen outer, Xen slices, Xen loops, Xen start, Xen sweep) { #define H_gluPartialDisk "void gluPartialDisk(GLUquadric* quad, GLdouble inner, GLdouble outer, GLint slices, \ GLint loops, GLdouble start, GLdouble sweep)" Xen_check_type(Xen_is_GLUquadric_(quad), quad, 1, "gluPartialDisk", "GLUquadric*"); Xen_check_type(Xen_is_GLdouble(inner), inner, 2, "gluPartialDisk", "GLdouble"); Xen_check_type(Xen_is_GLdouble(outer), outer, 3, "gluPartialDisk", "GLdouble"); Xen_check_type(Xen_is_GLint(slices), slices, 4, "gluPartialDisk", "GLint"); Xen_check_type(Xen_is_GLint(loops), loops, 5, "gluPartialDisk", "GLint"); Xen_check_type(Xen_is_GLdouble(start), start, 6, "gluPartialDisk", "GLdouble"); Xen_check_type(Xen_is_GLdouble(sweep), sweep, 7, "gluPartialDisk", "GLdouble"); gluPartialDisk(Xen_to_C_GLUquadric_(quad), Xen_to_C_GLdouble(inner), Xen_to_C_GLdouble(outer), Xen_to_C_GLint(slices), Xen_to_C_GLint(loops), Xen_to_C_GLdouble(start), Xen_to_C_GLdouble(sweep)); return(Xen_false); } static Xen gxg_gluPerspective(Xen fovy, Xen aspect, Xen zNear, Xen zFar) { #define H_gluPerspective "void gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar)" Xen_check_type(Xen_is_GLdouble(fovy), fovy, 1, "gluPerspective", "GLdouble"); Xen_check_type(Xen_is_GLdouble(aspect), aspect, 2, "gluPerspective", "GLdouble"); Xen_check_type(Xen_is_GLdouble(zNear), zNear, 3, "gluPerspective", "GLdouble"); Xen_check_type(Xen_is_GLdouble(zFar), zFar, 4, "gluPerspective", "GLdouble"); gluPerspective(Xen_to_C_GLdouble(fovy), Xen_to_C_GLdouble(aspect), Xen_to_C_GLdouble(zNear), Xen_to_C_GLdouble(zFar)); return(Xen_false); } static Xen gxg_gluPickMatrix(Xen x, Xen y, Xen delX, Xen delY, Xen viewport) { #define H_gluPickMatrix "void gluPickMatrix(GLdouble x, GLdouble y, GLdouble delX, GLdouble delY, GLint* viewport)" Xen_check_type(Xen_is_GLdouble(x), x, 1, "gluPickMatrix", "GLdouble"); Xen_check_type(Xen_is_GLdouble(y), y, 2, "gluPickMatrix", "GLdouble"); Xen_check_type(Xen_is_GLdouble(delX), delX, 3, "gluPickMatrix", "GLdouble"); Xen_check_type(Xen_is_GLdouble(delY), delY, 4, "gluPickMatrix", "GLdouble"); Xen_check_type(Xen_is_GLint_(viewport), viewport, 5, "gluPickMatrix", "GLint*"); gluPickMatrix(Xen_to_C_GLdouble(x), Xen_to_C_GLdouble(y), Xen_to_C_GLdouble(delX), Xen_to_C_GLdouble(delY), Xen_to_C_GLint_(viewport)); return(Xen_false); } static Xen gxg_gluProject(Xen arglist) { #define H_gluProject "GLint gluProject(GLdouble objX, GLdouble objY, GLdouble objZ, GLdouble* model, \ GLdouble* proj, GLint* view, GLdouble* [winX], GLdouble* [winY], GLdouble* [winZ])" GLdouble ref_winX[1]; GLdouble ref_winY[1]; GLdouble ref_winZ[1]; Xen objX, objY, objZ, model, proj, view; objX = Xen_list_ref(arglist, 0); objY = Xen_list_ref(arglist, 1); objZ = Xen_list_ref(arglist, 2); model = Xen_list_ref(arglist, 3); proj = Xen_list_ref(arglist, 4); view = Xen_list_ref(arglist, 5); Xen_check_type(Xen_is_GLdouble(objX), objX, 1, "gluProject", "GLdouble"); Xen_check_type(Xen_is_GLdouble(objY), objY, 2, "gluProject", "GLdouble"); Xen_check_type(Xen_is_GLdouble(objZ), objZ, 3, "gluProject", "GLdouble"); Xen_check_type(Xen_is_GLdouble_(model), model, 4, "gluProject", "GLdouble*"); Xen_check_type(Xen_is_GLdouble_(proj), proj, 5, "gluProject", "GLdouble*"); Xen_check_type(Xen_is_GLint_(view), view, 6, "gluProject", "GLint*"); { Xen result; result = C_to_Xen_GLint(gluProject(Xen_to_C_GLdouble(objX), Xen_to_C_GLdouble(objY), Xen_to_C_GLdouble(objZ), Xen_to_C_GLdouble_(model), Xen_to_C_GLdouble_(proj), Xen_to_C_GLint_(view), ref_winX, ref_winY, ref_winZ)); return(Xen_list_4(result, C_to_Xen_GLdouble(ref_winX[0]), C_to_Xen_GLdouble(ref_winY[0]), C_to_Xen_GLdouble(ref_winZ[0]))); } } static Xen gxg_gluPwlCurve(Xen nurb, Xen count, Xen data, Xen stride, Xen type) { #define H_gluPwlCurve "void gluPwlCurve(GLUnurbs* nurb, GLint count, GLfloat* data, GLint stride, GLenum type)" Xen_check_type(Xen_is_GLUnurbs_(nurb), nurb, 1, "gluPwlCurve", "GLUnurbs*"); Xen_check_type(Xen_is_GLint(count), count, 2, "gluPwlCurve", "GLint"); Xen_check_type(Xen_is_GLfloat_(data), data, 3, "gluPwlCurve", "GLfloat*"); Xen_check_type(Xen_is_GLint(stride), stride, 4, "gluPwlCurve", "GLint"); Xen_check_type(Xen_is_GLenum(type), type, 5, "gluPwlCurve", "GLenum"); gluPwlCurve(Xen_to_C_GLUnurbs_(nurb), Xen_to_C_GLint(count), Xen_to_C_GLfloat_(data), Xen_to_C_GLint(stride), Xen_to_C_GLenum(type)); return(Xen_false); } static Xen gxg_gluQuadricCallback(Xen quad, Xen which, Xen CallBackFunc) { #define H_gluQuadricCallback "void gluQuadricCallback(GLUquadric* quad, GLenum which, _GLUfuncptr CallBackFunc)" Xen_check_type(Xen_is_GLUquadric_(quad), quad, 1, "gluQuadricCallback", "GLUquadric*"); Xen_check_type(Xen_is_GLenum(which), which, 2, "gluQuadricCallback", "GLenum"); Xen_check_type(Xen_is__GLUfuncptr(CallBackFunc), CallBackFunc, 3, "gluQuadricCallback", "_GLUfuncptr"); gluQuadricCallback(Xen_to_C_GLUquadric_(quad), Xen_to_C_GLenum(which), Xen_to_C__GLUfuncptr(CallBackFunc)); return(Xen_false); } static Xen gxg_gluQuadricDrawStyle(Xen quad, Xen draw) { #define H_gluQuadricDrawStyle "void gluQuadricDrawStyle(GLUquadric* quad, GLenum draw)" Xen_check_type(Xen_is_GLUquadric_(quad), quad, 1, "gluQuadricDrawStyle", "GLUquadric*"); Xen_check_type(Xen_is_GLenum(draw), draw, 2, "gluQuadricDrawStyle", "GLenum"); gluQuadricDrawStyle(Xen_to_C_GLUquadric_(quad), Xen_to_C_GLenum(draw)); return(Xen_false); } static Xen gxg_gluQuadricNormals(Xen quad, Xen normal) { #define H_gluQuadricNormals "void gluQuadricNormals(GLUquadric* quad, GLenum normal)" Xen_check_type(Xen_is_GLUquadric_(quad), quad, 1, "gluQuadricNormals", "GLUquadric*"); Xen_check_type(Xen_is_GLenum(normal), normal, 2, "gluQuadricNormals", "GLenum"); gluQuadricNormals(Xen_to_C_GLUquadric_(quad), Xen_to_C_GLenum(normal)); return(Xen_false); } static Xen gxg_gluQuadricOrientation(Xen quad, Xen orientation) { #define H_gluQuadricOrientation "void gluQuadricOrientation(GLUquadric* quad, GLenum orientation)" Xen_check_type(Xen_is_GLUquadric_(quad), quad, 1, "gluQuadricOrientation", "GLUquadric*"); Xen_check_type(Xen_is_GLenum(orientation), orientation, 2, "gluQuadricOrientation", "GLenum"); gluQuadricOrientation(Xen_to_C_GLUquadric_(quad), Xen_to_C_GLenum(orientation)); return(Xen_false); } static Xen gxg_gluQuadricTexture(Xen quad, Xen texture) { #define H_gluQuadricTexture "void gluQuadricTexture(GLUquadric* quad, GLboolean texture)" Xen_check_type(Xen_is_GLUquadric_(quad), quad, 1, "gluQuadricTexture", "GLUquadric*"); Xen_check_type(Xen_is_GLboolean(texture), texture, 2, "gluQuadricTexture", "GLboolean"); gluQuadricTexture(Xen_to_C_GLUquadric_(quad), Xen_to_C_GLboolean(texture)); return(Xen_false); } static Xen gxg_gluScaleImage(Xen arglist) { #define H_gluScaleImage "GLint gluScaleImage(GLenum format, GLsizei wIn, GLsizei hIn, GLenum typeIn, \ void* dataIn, GLsizei wOut, GLsizei hOut, GLenum typeOut, GLvoid* dataOut)" Xen format, wIn, hIn, typeIn, dataIn, wOut, hOut, typeOut, dataOut; format = Xen_list_ref(arglist, 0); wIn = Xen_list_ref(arglist, 1); hIn = Xen_list_ref(arglist, 2); typeIn = Xen_list_ref(arglist, 3); dataIn = Xen_list_ref(arglist, 4); wOut = Xen_list_ref(arglist, 5); hOut = Xen_list_ref(arglist, 6); typeOut = Xen_list_ref(arglist, 7); dataOut = Xen_list_ref(arglist, 8); Xen_check_type(Xen_is_GLenum(format), format, 1, "gluScaleImage", "GLenum"); Xen_check_type(Xen_is_GLsizei(wIn), wIn, 2, "gluScaleImage", "GLsizei"); Xen_check_type(Xen_is_GLsizei(hIn), hIn, 3, "gluScaleImage", "GLsizei"); Xen_check_type(Xen_is_GLenum(typeIn), typeIn, 4, "gluScaleImage", "GLenum"); Xen_check_type(Xen_is_void_(dataIn), dataIn, 5, "gluScaleImage", "void*"); Xen_check_type(Xen_is_GLsizei(wOut), wOut, 6, "gluScaleImage", "GLsizei"); Xen_check_type(Xen_is_GLsizei(hOut), hOut, 7, "gluScaleImage", "GLsizei"); Xen_check_type(Xen_is_GLenum(typeOut), typeOut, 8, "gluScaleImage", "GLenum"); Xen_check_type(Xen_is_GLvoid_(dataOut), dataOut, 9, "gluScaleImage", "GLvoid*"); return(C_to_Xen_GLint(gluScaleImage(Xen_to_C_GLenum(format), Xen_to_C_GLsizei(wIn), Xen_to_C_GLsizei(hIn), Xen_to_C_GLenum(typeIn), Xen_to_C_void_(dataIn), Xen_to_C_GLsizei(wOut), Xen_to_C_GLsizei(hOut), Xen_to_C_GLenum(typeOut), Xen_to_C_GLvoid_(dataOut)))); } static Xen gxg_gluSphere(Xen quad, Xen radius, Xen slices, Xen stacks) { #define H_gluSphere "void gluSphere(GLUquadric* quad, GLdouble radius, GLint slices, GLint stacks)" Xen_check_type(Xen_is_GLUquadric_(quad), quad, 1, "gluSphere", "GLUquadric*"); Xen_check_type(Xen_is_GLdouble(radius), radius, 2, "gluSphere", "GLdouble"); Xen_check_type(Xen_is_GLint(slices), slices, 3, "gluSphere", "GLint"); Xen_check_type(Xen_is_GLint(stacks), stacks, 4, "gluSphere", "GLint"); gluSphere(Xen_to_C_GLUquadric_(quad), Xen_to_C_GLdouble(radius), Xen_to_C_GLint(slices), Xen_to_C_GLint(stacks)); return(Xen_false); } #ifdef GLU_VERSION_1_2 static Xen gxg_gluTessBeginContour(Xen tess) { #define H_gluTessBeginContour "void gluTessBeginContour(GLUtesselator* tess)" Xen_check_type(Xen_is_GLUtesselator_(tess), tess, 1, "gluTessBeginContour", "GLUtesselator*"); gluTessBeginContour(Xen_to_C_GLUtesselator_(tess)); return(Xen_false); } #endif #ifdef GLU_VERSION_1_2 static Xen gxg_gluTessBeginPolygon(Xen tess, Xen data) { #define H_gluTessBeginPolygon "void gluTessBeginPolygon(GLUtesselator* tess, GLvoid* data)" Xen_check_type(Xen_is_GLUtesselator_(tess), tess, 1, "gluTessBeginPolygon", "GLUtesselator*"); Xen_check_type(Xen_is_GLvoid_(data), data, 2, "gluTessBeginPolygon", "GLvoid*"); gluTessBeginPolygon(Xen_to_C_GLUtesselator_(tess), Xen_to_C_GLvoid_(data)); return(Xen_false); } #endif static Xen gxg_gluTessCallback(Xen tess, Xen which, Xen CallBackFunc) { #define H_gluTessCallback "void gluTessCallback(GLUtesselator* tess, GLenum which, _GLUfuncptr CallBackFunc)" Xen_check_type(Xen_is_GLUtesselator_(tess), tess, 1, "gluTessCallback", "GLUtesselator*"); Xen_check_type(Xen_is_GLenum(which), which, 2, "gluTessCallback", "GLenum"); Xen_check_type(Xen_is__GLUfuncptr(CallBackFunc), CallBackFunc, 3, "gluTessCallback", "_GLUfuncptr"); gluTessCallback(Xen_to_C_GLUtesselator_(tess), Xen_to_C_GLenum(which), Xen_to_C__GLUfuncptr(CallBackFunc)); return(Xen_false); } #ifdef GLU_VERSION_1_2 static Xen gxg_gluTessEndContour(Xen tess) { #define H_gluTessEndContour "void gluTessEndContour(GLUtesselator* tess)" Xen_check_type(Xen_is_GLUtesselator_(tess), tess, 1, "gluTessEndContour", "GLUtesselator*"); gluTessEndContour(Xen_to_C_GLUtesselator_(tess)); return(Xen_false); } #endif #ifdef GLU_VERSION_1_2 static Xen gxg_gluTessEndPolygon(Xen tess) { #define H_gluTessEndPolygon "void gluTessEndPolygon(GLUtesselator* tess)" Xen_check_type(Xen_is_GLUtesselator_(tess), tess, 1, "gluTessEndPolygon", "GLUtesselator*"); gluTessEndPolygon(Xen_to_C_GLUtesselator_(tess)); return(Xen_false); } #endif #ifdef GLU_VERSION_1_2 static Xen gxg_gluTessNormal(Xen tess, Xen valueX, Xen valueY, Xen valueZ) { #define H_gluTessNormal "void gluTessNormal(GLUtesselator* tess, GLdouble valueX, GLdouble valueY, \ GLdouble valueZ)" Xen_check_type(Xen_is_GLUtesselator_(tess), tess, 1, "gluTessNormal", "GLUtesselator*"); Xen_check_type(Xen_is_GLdouble(valueX), valueX, 2, "gluTessNormal", "GLdouble"); Xen_check_type(Xen_is_GLdouble(valueY), valueY, 3, "gluTessNormal", "GLdouble"); Xen_check_type(Xen_is_GLdouble(valueZ), valueZ, 4, "gluTessNormal", "GLdouble"); gluTessNormal(Xen_to_C_GLUtesselator_(tess), Xen_to_C_GLdouble(valueX), Xen_to_C_GLdouble(valueY), Xen_to_C_GLdouble(valueZ)); return(Xen_false); } #endif #ifdef GLU_VERSION_1_2 static Xen gxg_gluTessProperty(Xen tess, Xen which, Xen data) { #define H_gluTessProperty "void gluTessProperty(GLUtesselator* tess, GLenum which, GLdouble data)" Xen_check_type(Xen_is_GLUtesselator_(tess), tess, 1, "gluTessProperty", "GLUtesselator*"); Xen_check_type(Xen_is_GLenum(which), which, 2, "gluTessProperty", "GLenum"); Xen_check_type(Xen_is_GLdouble(data), data, 3, "gluTessProperty", "GLdouble"); gluTessProperty(Xen_to_C_GLUtesselator_(tess), Xen_to_C_GLenum(which), Xen_to_C_GLdouble(data)); return(Xen_false); } #endif #ifdef GLU_VERSION_1_2 static Xen gxg_gluTessVertex(Xen tess, Xen location, Xen data) { #define H_gluTessVertex "void gluTessVertex(GLUtesselator* tess, GLdouble* location, GLvoid* data)" Xen_check_type(Xen_is_GLUtesselator_(tess), tess, 1, "gluTessVertex", "GLUtesselator*"); Xen_check_type(Xen_is_GLdouble_(location), location, 2, "gluTessVertex", "GLdouble*"); Xen_check_type(Xen_is_GLvoid_(data), data, 3, "gluTessVertex", "GLvoid*"); gluTessVertex(Xen_to_C_GLUtesselator_(tess), Xen_to_C_GLdouble_(location), Xen_to_C_GLvoid_(data)); return(Xen_false); } #endif static Xen gxg_gluUnProject(Xen arglist) { #define H_gluUnProject "GLint gluUnProject(GLdouble winX, GLdouble winY, GLdouble winZ, GLdouble* model, \ GLdouble* proj, GLint* view, GLdouble* [objX], GLdouble* [objY], GLdouble* [objZ])" GLdouble ref_objX[1]; GLdouble ref_objY[1]; GLdouble ref_objZ[1]; Xen winX, winY, winZ, model, proj, view; winX = Xen_list_ref(arglist, 0); winY = Xen_list_ref(arglist, 1); winZ = Xen_list_ref(arglist, 2); model = Xen_list_ref(arglist, 3); proj = Xen_list_ref(arglist, 4); view = Xen_list_ref(arglist, 5); Xen_check_type(Xen_is_GLdouble(winX), winX, 1, "gluUnProject", "GLdouble"); Xen_check_type(Xen_is_GLdouble(winY), winY, 2, "gluUnProject", "GLdouble"); Xen_check_type(Xen_is_GLdouble(winZ), winZ, 3, "gluUnProject", "GLdouble"); Xen_check_type(Xen_is_GLdouble_(model), model, 4, "gluUnProject", "GLdouble*"); Xen_check_type(Xen_is_GLdouble_(proj), proj, 5, "gluUnProject", "GLdouble*"); Xen_check_type(Xen_is_GLint_(view), view, 6, "gluUnProject", "GLint*"); { Xen result; result = C_to_Xen_GLint(gluUnProject(Xen_to_C_GLdouble(winX), Xen_to_C_GLdouble(winY), Xen_to_C_GLdouble(winZ), Xen_to_C_GLdouble_(model), Xen_to_C_GLdouble_(proj), Xen_to_C_GLint_(view), ref_objX, ref_objY, ref_objZ)); return(Xen_list_4(result, C_to_Xen_GLdouble(ref_objX[0]), C_to_Xen_GLdouble(ref_objY[0]), C_to_Xen_GLdouble(ref_objZ[0]))); } } static Xen gxg_gluUnProject4(Xen arglist) { #define H_gluUnProject4 "GLint gluUnProject4(GLdouble winX, GLdouble winY, GLdouble winZ, GLdouble clipW, \ GLdouble* model, GLdouble* proj, GLint* view, GLdouble near, GLdouble far, GLdouble* [objX], GLdouble* [objY], \ GLdouble* [objZ], GLdouble* [objW])" GLdouble ref_objX[1]; GLdouble ref_objY[1]; GLdouble ref_objZ[1]; GLdouble ref_objW[1]; Xen winX, winY, winZ, clipW, model, proj, view, near, far; winX = Xen_list_ref(arglist, 0); winY = Xen_list_ref(arglist, 1); winZ = Xen_list_ref(arglist, 2); clipW = Xen_list_ref(arglist, 3); model = Xen_list_ref(arglist, 4); proj = Xen_list_ref(arglist, 5); view = Xen_list_ref(arglist, 6); near = Xen_list_ref(arglist, 7); far = Xen_list_ref(arglist, 8); Xen_check_type(Xen_is_GLdouble(winX), winX, 1, "gluUnProject4", "GLdouble"); Xen_check_type(Xen_is_GLdouble(winY), winY, 2, "gluUnProject4", "GLdouble"); Xen_check_type(Xen_is_GLdouble(winZ), winZ, 3, "gluUnProject4", "GLdouble"); Xen_check_type(Xen_is_GLdouble(clipW), clipW, 4, "gluUnProject4", "GLdouble"); Xen_check_type(Xen_is_GLdouble_(model), model, 5, "gluUnProject4", "GLdouble*"); Xen_check_type(Xen_is_GLdouble_(proj), proj, 6, "gluUnProject4", "GLdouble*"); Xen_check_type(Xen_is_GLint_(view), view, 7, "gluUnProject4", "GLint*"); Xen_check_type(Xen_is_GLdouble(near), near, 8, "gluUnProject4", "GLdouble"); Xen_check_type(Xen_is_GLdouble(far), far, 9, "gluUnProject4", "GLdouble"); { Xen result; result = C_to_Xen_GLint(gluUnProject4(Xen_to_C_GLdouble(winX), Xen_to_C_GLdouble(winY), Xen_to_C_GLdouble(winZ), Xen_to_C_GLdouble(clipW), Xen_to_C_GLdouble_(model), Xen_to_C_GLdouble_(proj), Xen_to_C_GLint_(view), Xen_to_C_GLdouble(near), Xen_to_C_GLdouble(far), ref_objX, ref_objY, ref_objZ, ref_objW)); return(Xen_list_5(result, C_to_Xen_GLdouble(ref_objX[0]), C_to_Xen_GLdouble(ref_objY[0]), C_to_Xen_GLdouble(ref_objZ[0]), C_to_Xen_GLdouble(ref_objW[0]))); } } #endif #if USE_MOTIF Xen_wrap_3_args(gxg_glXChooseVisual_w, gxg_glXChooseVisual) Xen_wrap_4_args(gxg_glXCopyContext_w, gxg_glXCopyContext) Xen_wrap_4_args(gxg_glXCreateContext_w, gxg_glXCreateContext) Xen_wrap_3_args(gxg_glXCreateGLXPixmap_w, gxg_glXCreateGLXPixmap) Xen_wrap_2_args(gxg_glXDestroyContext_w, gxg_glXDestroyContext) Xen_wrap_2_args(gxg_glXDestroyGLXPixmap_w, gxg_glXDestroyGLXPixmap) Xen_wrap_4_optional_args(gxg_glXGetConfig_w, gxg_glXGetConfig) Xen_wrap_no_args(gxg_glXGetCurrentContext_w, gxg_glXGetCurrentContext) Xen_wrap_no_args(gxg_glXGetCurrentDrawable_w, gxg_glXGetCurrentDrawable) Xen_wrap_2_args(gxg_glXIsDirect_w, gxg_glXIsDirect) Xen_wrap_3_args(gxg_glXMakeCurrent_w, gxg_glXMakeCurrent) Xen_wrap_3_optional_args(gxg_glXQueryExtension_w, gxg_glXQueryExtension) Xen_wrap_3_optional_args(gxg_glXQueryVersion_w, gxg_glXQueryVersion) Xen_wrap_2_args(gxg_glXSwapBuffers_w, gxg_glXSwapBuffers) Xen_wrap_4_args(gxg_glXUseXFont_w, gxg_glXUseXFont) Xen_wrap_no_args(gxg_glXWaitGL_w, gxg_glXWaitGL) Xen_wrap_no_args(gxg_glXWaitX_w, gxg_glXWaitX) Xen_wrap_2_args(gxg_glXGetClientString_w, gxg_glXGetClientString) Xen_wrap_3_args(gxg_glXQueryServerString_w, gxg_glXQueryServerString) Xen_wrap_2_args(gxg_glXQueryExtensionsString_w, gxg_glXQueryExtensionsString) #endif Xen_wrap_1_arg(gxg_glClearIndex_w, gxg_glClearIndex) Xen_wrap_4_args(gxg_glClearColor_w, gxg_glClearColor) Xen_wrap_1_arg(gxg_glClear_w, gxg_glClear) Xen_wrap_1_arg(gxg_glIndexMask_w, gxg_glIndexMask) Xen_wrap_4_args(gxg_glColorMask_w, gxg_glColorMask) Xen_wrap_2_args(gxg_glAlphaFunc_w, gxg_glAlphaFunc) Xen_wrap_2_args(gxg_glBlendFunc_w, gxg_glBlendFunc) Xen_wrap_1_arg(gxg_glLogicOp_w, gxg_glLogicOp) Xen_wrap_1_arg(gxg_glCullFace_w, gxg_glCullFace) Xen_wrap_1_arg(gxg_glFrontFace_w, gxg_glFrontFace) Xen_wrap_1_arg(gxg_glPointSize_w, gxg_glPointSize) Xen_wrap_1_arg(gxg_glLineWidth_w, gxg_glLineWidth) Xen_wrap_2_args(gxg_glLineStipple_w, gxg_glLineStipple) Xen_wrap_2_args(gxg_glPolygonMode_w, gxg_glPolygonMode) Xen_wrap_2_args(gxg_glPolygonOffset_w, gxg_glPolygonOffset) Xen_wrap_1_arg(gxg_glPolygonStipple_w, gxg_glPolygonStipple) Xen_wrap_1_arg(gxg_glEdgeFlag_w, gxg_glEdgeFlag) Xen_wrap_4_args(gxg_glScissor_w, gxg_glScissor) Xen_wrap_2_args(gxg_glClipPlane_w, gxg_glClipPlane) Xen_wrap_2_optional_args(gxg_glGetClipPlane_w, gxg_glGetClipPlane) Xen_wrap_1_arg(gxg_glDrawBuffer_w, gxg_glDrawBuffer) Xen_wrap_1_arg(gxg_glReadBuffer_w, gxg_glReadBuffer) Xen_wrap_1_arg(gxg_glEnable_w, gxg_glEnable) Xen_wrap_1_arg(gxg_glDisable_w, gxg_glDisable) Xen_wrap_1_arg(gxg_glIsEnabled_w, gxg_glIsEnabled) Xen_wrap_1_arg(gxg_glEnableClientState_w, gxg_glEnableClientState) Xen_wrap_1_arg(gxg_glDisableClientState_w, gxg_glDisableClientState) Xen_wrap_2_optional_args(gxg_glGetBooleanv_w, gxg_glGetBooleanv) Xen_wrap_2_optional_args(gxg_glGetDoublev_w, gxg_glGetDoublev) Xen_wrap_2_optional_args(gxg_glGetFloatv_w, gxg_glGetFloatv) Xen_wrap_2_optional_args(gxg_glGetIntegerv_w, gxg_glGetIntegerv) Xen_wrap_1_arg(gxg_glPushAttrib_w, gxg_glPushAttrib) Xen_wrap_no_args(gxg_glPopAttrib_w, gxg_glPopAttrib) Xen_wrap_1_arg(gxg_glPushClientAttrib_w, gxg_glPushClientAttrib) Xen_wrap_no_args(gxg_glPopClientAttrib_w, gxg_glPopClientAttrib) Xen_wrap_1_arg(gxg_glRenderMode_w, gxg_glRenderMode) Xen_wrap_no_args(gxg_glGetError_w, gxg_glGetError) Xen_wrap_1_arg(gxg_glGetString_w, gxg_glGetString) Xen_wrap_no_args(gxg_glFinish_w, gxg_glFinish) Xen_wrap_no_args(gxg_glFlush_w, gxg_glFlush) Xen_wrap_2_args(gxg_glHint_w, gxg_glHint) Xen_wrap_1_arg(gxg_glClearDepth_w, gxg_glClearDepth) Xen_wrap_1_arg(gxg_glDepthFunc_w, gxg_glDepthFunc) Xen_wrap_1_arg(gxg_glDepthMask_w, gxg_glDepthMask) Xen_wrap_2_args(gxg_glDepthRange_w, gxg_glDepthRange) Xen_wrap_4_args(gxg_glClearAccum_w, gxg_glClearAccum) Xen_wrap_2_args(gxg_glAccum_w, gxg_glAccum) Xen_wrap_1_arg(gxg_glMatrixMode_w, gxg_glMatrixMode) Xen_wrap_6_args(gxg_glOrtho_w, gxg_glOrtho) Xen_wrap_6_args(gxg_glFrustum_w, gxg_glFrustum) Xen_wrap_4_args(gxg_glViewport_w, gxg_glViewport) Xen_wrap_no_args(gxg_glPushMatrix_w, gxg_glPushMatrix) Xen_wrap_no_args(gxg_glPopMatrix_w, gxg_glPopMatrix) Xen_wrap_no_args(gxg_glLoadIdentity_w, gxg_glLoadIdentity) Xen_wrap_1_arg(gxg_glLoadMatrixd_w, gxg_glLoadMatrixd) Xen_wrap_1_arg(gxg_glLoadMatrixf_w, gxg_glLoadMatrixf) Xen_wrap_1_arg(gxg_glMultMatrixd_w, gxg_glMultMatrixd) Xen_wrap_1_arg(gxg_glMultMatrixf_w, gxg_glMultMatrixf) Xen_wrap_4_args(gxg_glRotated_w, gxg_glRotated) Xen_wrap_4_args(gxg_glRotatef_w, gxg_glRotatef) Xen_wrap_3_args(gxg_glScaled_w, gxg_glScaled) Xen_wrap_3_args(gxg_glScalef_w, gxg_glScalef) Xen_wrap_3_args(gxg_glTranslated_w, gxg_glTranslated) Xen_wrap_3_args(gxg_glTranslatef_w, gxg_glTranslatef) Xen_wrap_1_arg(gxg_glIsList_w, gxg_glIsList) Xen_wrap_2_args(gxg_glDeleteLists_w, gxg_glDeleteLists) Xen_wrap_1_arg(gxg_glGenLists_w, gxg_glGenLists) Xen_wrap_2_args(gxg_glNewList_w, gxg_glNewList) Xen_wrap_no_args(gxg_glEndList_w, gxg_glEndList) Xen_wrap_1_arg(gxg_glCallList_w, gxg_glCallList) Xen_wrap_3_args(gxg_glCallLists_w, gxg_glCallLists) Xen_wrap_1_arg(gxg_glListBase_w, gxg_glListBase) Xen_wrap_1_arg(gxg_glBegin_w, gxg_glBegin) Xen_wrap_no_args(gxg_glEnd_w, gxg_glEnd) Xen_wrap_2_args(gxg_glVertex2d_w, gxg_glVertex2d) Xen_wrap_2_args(gxg_glVertex2f_w, gxg_glVertex2f) Xen_wrap_2_args(gxg_glVertex2i_w, gxg_glVertex2i) Xen_wrap_2_args(gxg_glVertex2s_w, gxg_glVertex2s) Xen_wrap_3_args(gxg_glVertex3d_w, gxg_glVertex3d) Xen_wrap_3_args(gxg_glVertex3f_w, gxg_glVertex3f) Xen_wrap_3_args(gxg_glVertex3i_w, gxg_glVertex3i) Xen_wrap_3_args(gxg_glVertex3s_w, gxg_glVertex3s) Xen_wrap_4_args(gxg_glVertex4d_w, gxg_glVertex4d) Xen_wrap_4_args(gxg_glVertex4f_w, gxg_glVertex4f) Xen_wrap_4_args(gxg_glVertex4i_w, gxg_glVertex4i) Xen_wrap_4_args(gxg_glVertex4s_w, gxg_glVertex4s) Xen_wrap_3_args(gxg_glNormal3b_w, gxg_glNormal3b) Xen_wrap_3_args(gxg_glNormal3d_w, gxg_glNormal3d) Xen_wrap_3_args(gxg_glNormal3f_w, gxg_glNormal3f) Xen_wrap_3_args(gxg_glNormal3i_w, gxg_glNormal3i) Xen_wrap_3_args(gxg_glNormal3s_w, gxg_glNormal3s) Xen_wrap_1_arg(gxg_glIndexd_w, gxg_glIndexd) Xen_wrap_1_arg(gxg_glIndexf_w, gxg_glIndexf) Xen_wrap_1_arg(gxg_glIndexi_w, gxg_glIndexi) Xen_wrap_1_arg(gxg_glIndexs_w, gxg_glIndexs) Xen_wrap_1_arg(gxg_glIndexub_w, gxg_glIndexub) Xen_wrap_3_args(gxg_glColor3b_w, gxg_glColor3b) Xen_wrap_3_args(gxg_glColor3d_w, gxg_glColor3d) Xen_wrap_3_args(gxg_glColor3f_w, gxg_glColor3f) Xen_wrap_3_args(gxg_glColor3i_w, gxg_glColor3i) Xen_wrap_3_args(gxg_glColor3s_w, gxg_glColor3s) Xen_wrap_3_args(gxg_glColor3ub_w, gxg_glColor3ub) Xen_wrap_3_args(gxg_glColor3ui_w, gxg_glColor3ui) Xen_wrap_3_args(gxg_glColor3us_w, gxg_glColor3us) Xen_wrap_4_args(gxg_glColor4b_w, gxg_glColor4b) Xen_wrap_4_args(gxg_glColor4d_w, gxg_glColor4d) Xen_wrap_4_args(gxg_glColor4f_w, gxg_glColor4f) Xen_wrap_4_args(gxg_glColor4i_w, gxg_glColor4i) Xen_wrap_4_args(gxg_glColor4s_w, gxg_glColor4s) Xen_wrap_4_args(gxg_glColor4ub_w, gxg_glColor4ub) Xen_wrap_4_args(gxg_glColor4ui_w, gxg_glColor4ui) Xen_wrap_4_args(gxg_glColor4us_w, gxg_glColor4us) Xen_wrap_1_arg(gxg_glTexCoord1d_w, gxg_glTexCoord1d) Xen_wrap_1_arg(gxg_glTexCoord1f_w, gxg_glTexCoord1f) Xen_wrap_1_arg(gxg_glTexCoord1i_w, gxg_glTexCoord1i) Xen_wrap_1_arg(gxg_glTexCoord1s_w, gxg_glTexCoord1s) Xen_wrap_2_args(gxg_glTexCoord2d_w, gxg_glTexCoord2d) Xen_wrap_2_args(gxg_glTexCoord2f_w, gxg_glTexCoord2f) Xen_wrap_2_args(gxg_glTexCoord2i_w, gxg_glTexCoord2i) Xen_wrap_2_args(gxg_glTexCoord2s_w, gxg_glTexCoord2s) Xen_wrap_3_args(gxg_glTexCoord3d_w, gxg_glTexCoord3d) Xen_wrap_3_args(gxg_glTexCoord3f_w, gxg_glTexCoord3f) Xen_wrap_3_args(gxg_glTexCoord3i_w, gxg_glTexCoord3i) Xen_wrap_3_args(gxg_glTexCoord3s_w, gxg_glTexCoord3s) Xen_wrap_4_args(gxg_glTexCoord4d_w, gxg_glTexCoord4d) Xen_wrap_4_args(gxg_glTexCoord4f_w, gxg_glTexCoord4f) Xen_wrap_4_args(gxg_glTexCoord4i_w, gxg_glTexCoord4i) Xen_wrap_4_args(gxg_glTexCoord4s_w, gxg_glTexCoord4s) Xen_wrap_2_args(gxg_glRasterPos2d_w, gxg_glRasterPos2d) Xen_wrap_2_args(gxg_glRasterPos2f_w, gxg_glRasterPos2f) Xen_wrap_2_args(gxg_glRasterPos2i_w, gxg_glRasterPos2i) Xen_wrap_2_args(gxg_glRasterPos2s_w, gxg_glRasterPos2s) Xen_wrap_3_args(gxg_glRasterPos3d_w, gxg_glRasterPos3d) Xen_wrap_3_args(gxg_glRasterPos3f_w, gxg_glRasterPos3f) Xen_wrap_3_args(gxg_glRasterPos3i_w, gxg_glRasterPos3i) Xen_wrap_3_args(gxg_glRasterPos3s_w, gxg_glRasterPos3s) Xen_wrap_4_args(gxg_glRasterPos4d_w, gxg_glRasterPos4d) Xen_wrap_4_args(gxg_glRasterPos4f_w, gxg_glRasterPos4f) Xen_wrap_4_args(gxg_glRasterPos4i_w, gxg_glRasterPos4i) Xen_wrap_4_args(gxg_glRasterPos4s_w, gxg_glRasterPos4s) Xen_wrap_4_args(gxg_glRectd_w, gxg_glRectd) Xen_wrap_4_args(gxg_glRectf_w, gxg_glRectf) Xen_wrap_4_args(gxg_glRecti_w, gxg_glRecti) Xen_wrap_4_args(gxg_glRects_w, gxg_glRects) Xen_wrap_4_args(gxg_glVertexPointer_w, gxg_glVertexPointer) Xen_wrap_3_args(gxg_glNormalPointer_w, gxg_glNormalPointer) Xen_wrap_4_args(gxg_glColorPointer_w, gxg_glColorPointer) Xen_wrap_3_args(gxg_glIndexPointer_w, gxg_glIndexPointer) Xen_wrap_4_args(gxg_glTexCoordPointer_w, gxg_glTexCoordPointer) Xen_wrap_2_args(gxg_glEdgeFlagPointer_w, gxg_glEdgeFlagPointer) Xen_wrap_2_optional_args(gxg_glGetPointerv_w, gxg_glGetPointerv) Xen_wrap_1_arg(gxg_glArrayElement_w, gxg_glArrayElement) Xen_wrap_3_args(gxg_glDrawArrays_w, gxg_glDrawArrays) Xen_wrap_4_args(gxg_glDrawElements_w, gxg_glDrawElements) Xen_wrap_3_args(gxg_glInterleavedArrays_w, gxg_glInterleavedArrays) Xen_wrap_1_arg(gxg_glShadeModel_w, gxg_glShadeModel) Xen_wrap_3_args(gxg_glLightf_w, gxg_glLightf) Xen_wrap_3_args(gxg_glLighti_w, gxg_glLighti) Xen_wrap_3_optional_args(gxg_glGetLightfv_w, gxg_glGetLightfv) Xen_wrap_3_optional_args(gxg_glGetLightiv_w, gxg_glGetLightiv) Xen_wrap_2_args(gxg_glLightModelf_w, gxg_glLightModelf) Xen_wrap_2_args(gxg_glLightModeli_w, gxg_glLightModeli) Xen_wrap_3_args(gxg_glMaterialf_w, gxg_glMaterialf) Xen_wrap_3_args(gxg_glMateriali_w, gxg_glMateriali) Xen_wrap_3_optional_args(gxg_glGetMaterialfv_w, gxg_glGetMaterialfv) Xen_wrap_3_optional_args(gxg_glGetMaterialiv_w, gxg_glGetMaterialiv) Xen_wrap_2_args(gxg_glColorMaterial_w, gxg_glColorMaterial) Xen_wrap_2_args(gxg_glPixelZoom_w, gxg_glPixelZoom) Xen_wrap_2_args(gxg_glPixelStoref_w, gxg_glPixelStoref) Xen_wrap_2_args(gxg_glPixelStorei_w, gxg_glPixelStorei) Xen_wrap_2_args(gxg_glPixelTransferf_w, gxg_glPixelTransferf) Xen_wrap_2_args(gxg_glPixelTransferi_w, gxg_glPixelTransferi) Xen_wrap_2_optional_args(gxg_glGetPixelMapfv_w, gxg_glGetPixelMapfv) Xen_wrap_2_optional_args(gxg_glGetPixelMapuiv_w, gxg_glGetPixelMapuiv) Xen_wrap_2_optional_args(gxg_glGetPixelMapusv_w, gxg_glGetPixelMapusv) Xen_wrap_7_args(gxg_glBitmap_w, gxg_glBitmap) Xen_wrap_7_args(gxg_glReadPixels_w, gxg_glReadPixels) Xen_wrap_5_args(gxg_glDrawPixels_w, gxg_glDrawPixels) Xen_wrap_5_args(gxg_glCopyPixels_w, gxg_glCopyPixels) Xen_wrap_3_args(gxg_glStencilFunc_w, gxg_glStencilFunc) Xen_wrap_1_arg(gxg_glStencilMask_w, gxg_glStencilMask) Xen_wrap_3_args(gxg_glStencilOp_w, gxg_glStencilOp) Xen_wrap_1_arg(gxg_glClearStencil_w, gxg_glClearStencil) Xen_wrap_3_args(gxg_glTexGend_w, gxg_glTexGend) Xen_wrap_3_args(gxg_glTexGenf_w, gxg_glTexGenf) Xen_wrap_3_args(gxg_glTexGeni_w, gxg_glTexGeni) Xen_wrap_3_optional_args(gxg_glGetTexGendv_w, gxg_glGetTexGendv) Xen_wrap_3_optional_args(gxg_glGetTexGenfv_w, gxg_glGetTexGenfv) Xen_wrap_3_optional_args(gxg_glGetTexGeniv_w, gxg_glGetTexGeniv) Xen_wrap_3_args(gxg_glTexEnvf_w, gxg_glTexEnvf) Xen_wrap_3_args(gxg_glTexEnvi_w, gxg_glTexEnvi) Xen_wrap_3_optional_args(gxg_glGetTexEnvfv_w, gxg_glGetTexEnvfv) Xen_wrap_3_optional_args(gxg_glGetTexEnviv_w, gxg_glGetTexEnviv) Xen_wrap_3_args(gxg_glTexParameterf_w, gxg_glTexParameterf) Xen_wrap_3_args(gxg_glTexParameteri_w, gxg_glTexParameteri) Xen_wrap_3_optional_args(gxg_glGetTexParameterfv_w, gxg_glGetTexParameterfv) Xen_wrap_3_optional_args(gxg_glGetTexParameteriv_w, gxg_glGetTexParameteriv) Xen_wrap_4_optional_args(gxg_glGetTexLevelParameterfv_w, gxg_glGetTexLevelParameterfv) Xen_wrap_4_optional_args(gxg_glGetTexLevelParameteriv_w, gxg_glGetTexLevelParameteriv) Xen_wrap_any_args(gxg_glTexImage1D_w, gxg_glTexImage1D) Xen_wrap_any_args(gxg_glTexImage2D_w, gxg_glTexImage2D) Xen_wrap_2_args(gxg_glGenTextures_w, gxg_glGenTextures) Xen_wrap_2_args(gxg_glDeleteTextures_w, gxg_glDeleteTextures) Xen_wrap_2_args(gxg_glBindTexture_w, gxg_glBindTexture) Xen_wrap_3_args(gxg_glAreTexturesResident_w, gxg_glAreTexturesResident) Xen_wrap_1_arg(gxg_glIsTexture_w, gxg_glIsTexture) Xen_wrap_7_args(gxg_glTexSubImage1D_w, gxg_glTexSubImage1D) Xen_wrap_any_args(gxg_glTexSubImage2D_w, gxg_glTexSubImage2D) Xen_wrap_7_args(gxg_glCopyTexImage1D_w, gxg_glCopyTexImage1D) Xen_wrap_any_args(gxg_glCopyTexImage2D_w, gxg_glCopyTexImage2D) Xen_wrap_6_args(gxg_glCopyTexSubImage1D_w, gxg_glCopyTexSubImage1D) Xen_wrap_any_args(gxg_glCopyTexSubImage2D_w, gxg_glCopyTexSubImage2D) Xen_wrap_6_args(gxg_glMap1d_w, gxg_glMap1d) Xen_wrap_6_args(gxg_glMap1f_w, gxg_glMap1f) Xen_wrap_any_args(gxg_glMap2d_w, gxg_glMap2d) Xen_wrap_any_args(gxg_glMap2f_w, gxg_glMap2f) Xen_wrap_3_optional_args(gxg_glGetMapdv_w, gxg_glGetMapdv) Xen_wrap_3_optional_args(gxg_glGetMapfv_w, gxg_glGetMapfv) Xen_wrap_3_optional_args(gxg_glGetMapiv_w, gxg_glGetMapiv) Xen_wrap_1_arg(gxg_glEvalCoord1d_w, gxg_glEvalCoord1d) Xen_wrap_1_arg(gxg_glEvalCoord1f_w, gxg_glEvalCoord1f) Xen_wrap_2_args(gxg_glEvalCoord2d_w, gxg_glEvalCoord2d) Xen_wrap_2_args(gxg_glEvalCoord2f_w, gxg_glEvalCoord2f) Xen_wrap_3_args(gxg_glMapGrid1d_w, gxg_glMapGrid1d) Xen_wrap_3_args(gxg_glMapGrid1f_w, gxg_glMapGrid1f) Xen_wrap_6_args(gxg_glMapGrid2d_w, gxg_glMapGrid2d) Xen_wrap_6_args(gxg_glMapGrid2f_w, gxg_glMapGrid2f) Xen_wrap_1_arg(gxg_glEvalPoint1_w, gxg_glEvalPoint1) Xen_wrap_2_args(gxg_glEvalPoint2_w, gxg_glEvalPoint2) Xen_wrap_3_args(gxg_glEvalMesh1_w, gxg_glEvalMesh1) Xen_wrap_5_args(gxg_glEvalMesh2_w, gxg_glEvalMesh2) Xen_wrap_2_args(gxg_glFogf_w, gxg_glFogf) Xen_wrap_2_args(gxg_glFogi_w, gxg_glFogi) Xen_wrap_3_args(gxg_glFeedbackBuffer_w, gxg_glFeedbackBuffer) Xen_wrap_1_arg(gxg_glPassThrough_w, gxg_glPassThrough) Xen_wrap_2_args(gxg_glSelectBuffer_w, gxg_glSelectBuffer) Xen_wrap_no_args(gxg_glInitNames_w, gxg_glInitNames) Xen_wrap_1_arg(gxg_glLoadName_w, gxg_glLoadName) Xen_wrap_1_arg(gxg_glPushName_w, gxg_glPushName) Xen_wrap_no_args(gxg_glPopName_w, gxg_glPopName) Xen_wrap_6_args(gxg_glDrawRangeElements_w, gxg_glDrawRangeElements) Xen_wrap_any_args(gxg_glTexImage3D_w, gxg_glTexImage3D) Xen_wrap_any_args(gxg_glTexSubImage3D_w, gxg_glTexSubImage3D) Xen_wrap_any_args(gxg_glCopyTexSubImage3D_w, gxg_glCopyTexSubImage3D) Xen_wrap_6_args(gxg_glColorTable_w, gxg_glColorTable) Xen_wrap_6_args(gxg_glColorSubTable_w, gxg_glColorSubTable) Xen_wrap_5_args(gxg_glCopyColorSubTable_w, gxg_glCopyColorSubTable) Xen_wrap_5_args(gxg_glCopyColorTable_w, gxg_glCopyColorTable) Xen_wrap_3_optional_args(gxg_glGetColorTableParameterfv_w, gxg_glGetColorTableParameterfv) Xen_wrap_3_optional_args(gxg_glGetColorTableParameteriv_w, gxg_glGetColorTableParameteriv) Xen_wrap_1_arg(gxg_glBlendEquation_w, gxg_glBlendEquation) Xen_wrap_4_args(gxg_glBlendColor_w, gxg_glBlendColor) Xen_wrap_4_args(gxg_glHistogram_w, gxg_glHistogram) Xen_wrap_1_arg(gxg_glResetHistogram_w, gxg_glResetHistogram) Xen_wrap_5_args(gxg_glGetHistogram_w, gxg_glGetHistogram) Xen_wrap_3_optional_args(gxg_glGetHistogramParameterfv_w, gxg_glGetHistogramParameterfv) Xen_wrap_3_optional_args(gxg_glGetHistogramParameteriv_w, gxg_glGetHistogramParameteriv) Xen_wrap_3_args(gxg_glMinmax_w, gxg_glMinmax) Xen_wrap_1_arg(gxg_glResetMinmax_w, gxg_glResetMinmax) Xen_wrap_5_args(gxg_glGetMinmax_w, gxg_glGetMinmax) Xen_wrap_3_optional_args(gxg_glGetMinmaxParameterfv_w, gxg_glGetMinmaxParameterfv) Xen_wrap_3_optional_args(gxg_glGetMinmaxParameteriv_w, gxg_glGetMinmaxParameteriv) Xen_wrap_6_args(gxg_glConvolutionFilter1D_w, gxg_glConvolutionFilter1D) Xen_wrap_7_args(gxg_glConvolutionFilter2D_w, gxg_glConvolutionFilter2D) Xen_wrap_3_args(gxg_glConvolutionParameterf_w, gxg_glConvolutionParameterf) Xen_wrap_3_args(gxg_glConvolutionParameteri_w, gxg_glConvolutionParameteri) Xen_wrap_5_args(gxg_glCopyConvolutionFilter1D_w, gxg_glCopyConvolutionFilter1D) Xen_wrap_6_args(gxg_glCopyConvolutionFilter2D_w, gxg_glCopyConvolutionFilter2D) Xen_wrap_any_args(gxg_glSeparableFilter2D_w, gxg_glSeparableFilter2D) #if HAVE_GLU Xen_wrap_1_arg(gxg_gluBeginCurve_w, gxg_gluBeginCurve) #ifdef GLU_VERSION_1_2 Xen_wrap_1_arg(gxg_gluBeginPolygon_w, gxg_gluBeginPolygon) #endif Xen_wrap_1_arg(gxg_gluBeginSurface_w, gxg_gluBeginSurface) Xen_wrap_1_arg(gxg_gluBeginTrim_w, gxg_gluBeginTrim) Xen_wrap_any_args(gxg_gluBuild1DMipmapLevels_w, gxg_gluBuild1DMipmapLevels) Xen_wrap_6_args(gxg_gluBuild1DMipmaps_w, gxg_gluBuild1DMipmaps) Xen_wrap_any_args(gxg_gluBuild2DMipmapLevels_w, gxg_gluBuild2DMipmapLevels) Xen_wrap_7_args(gxg_gluBuild2DMipmaps_w, gxg_gluBuild2DMipmaps) Xen_wrap_any_args(gxg_gluBuild3DMipmapLevels_w, gxg_gluBuild3DMipmapLevels) Xen_wrap_any_args(gxg_gluBuild3DMipmaps_w, gxg_gluBuild3DMipmaps) Xen_wrap_2_args(gxg_gluCheckExtension_w, gxg_gluCheckExtension) Xen_wrap_6_args(gxg_gluCylinder_w, gxg_gluCylinder) Xen_wrap_1_arg(gxg_gluDeleteNurbsRenderer_w, gxg_gluDeleteNurbsRenderer) Xen_wrap_1_arg(gxg_gluDeleteQuadric_w, gxg_gluDeleteQuadric) #ifdef GLU_VERSION_1_2 Xen_wrap_1_arg(gxg_gluDeleteTess_w, gxg_gluDeleteTess) #endif Xen_wrap_5_args(gxg_gluDisk_w, gxg_gluDisk) Xen_wrap_1_arg(gxg_gluEndCurve_w, gxg_gluEndCurve) #ifdef GLU_VERSION_1_2 Xen_wrap_1_arg(gxg_gluEndPolygon_w, gxg_gluEndPolygon) #endif Xen_wrap_1_arg(gxg_gluEndSurface_w, gxg_gluEndSurface) Xen_wrap_1_arg(gxg_gluEndTrim_w, gxg_gluEndTrim) Xen_wrap_1_arg(gxg_gluErrorString_w, gxg_gluErrorString) Xen_wrap_3_args(gxg_gluGetNurbsProperty_w, gxg_gluGetNurbsProperty) Xen_wrap_1_arg(gxg_gluGetString_w, gxg_gluGetString) #ifdef GLU_VERSION_1_2 Xen_wrap_3_args(gxg_gluGetTessProperty_w, gxg_gluGetTessProperty) #endif Xen_wrap_4_args(gxg_gluLoadSamplingMatrices_w, gxg_gluLoadSamplingMatrices) Xen_wrap_any_args(gxg_gluLookAt_w, gxg_gluLookAt) Xen_wrap_no_args(gxg_gluNewNurbsRenderer_w, gxg_gluNewNurbsRenderer) Xen_wrap_no_args(gxg_gluNewQuadric_w, gxg_gluNewQuadric) #ifdef GLU_VERSION_1_2 Xen_wrap_no_args(gxg_gluNewTess_w, gxg_gluNewTess) #endif #ifdef GLU_VERSION_1_2 Xen_wrap_2_args(gxg_gluNextContour_w, gxg_gluNextContour) #endif Xen_wrap_3_args(gxg_gluNurbsCallback_w, gxg_gluNurbsCallback) Xen_wrap_2_args(gxg_gluNurbsCallbackData_w, gxg_gluNurbsCallbackData) Xen_wrap_7_args(gxg_gluNurbsCurve_w, gxg_gluNurbsCurve) Xen_wrap_3_args(gxg_gluNurbsProperty_w, gxg_gluNurbsProperty) Xen_wrap_any_args(gxg_gluNurbsSurface_w, gxg_gluNurbsSurface) Xen_wrap_4_args(gxg_gluOrtho2D_w, gxg_gluOrtho2D) Xen_wrap_7_args(gxg_gluPartialDisk_w, gxg_gluPartialDisk) Xen_wrap_4_args(gxg_gluPerspective_w, gxg_gluPerspective) Xen_wrap_5_args(gxg_gluPickMatrix_w, gxg_gluPickMatrix) Xen_wrap_any_args(gxg_gluProject_w, gxg_gluProject) Xen_wrap_5_args(gxg_gluPwlCurve_w, gxg_gluPwlCurve) Xen_wrap_3_args(gxg_gluQuadricCallback_w, gxg_gluQuadricCallback) Xen_wrap_2_args(gxg_gluQuadricDrawStyle_w, gxg_gluQuadricDrawStyle) Xen_wrap_2_args(gxg_gluQuadricNormals_w, gxg_gluQuadricNormals) Xen_wrap_2_args(gxg_gluQuadricOrientation_w, gxg_gluQuadricOrientation) Xen_wrap_2_args(gxg_gluQuadricTexture_w, gxg_gluQuadricTexture) Xen_wrap_any_args(gxg_gluScaleImage_w, gxg_gluScaleImage) Xen_wrap_4_args(gxg_gluSphere_w, gxg_gluSphere) #ifdef GLU_VERSION_1_2 Xen_wrap_1_arg(gxg_gluTessBeginContour_w, gxg_gluTessBeginContour) #endif #ifdef GLU_VERSION_1_2 Xen_wrap_2_args(gxg_gluTessBeginPolygon_w, gxg_gluTessBeginPolygon) #endif Xen_wrap_3_args(gxg_gluTessCallback_w, gxg_gluTessCallback) #ifdef GLU_VERSION_1_2 Xen_wrap_1_arg(gxg_gluTessEndContour_w, gxg_gluTessEndContour) #endif #ifdef GLU_VERSION_1_2 Xen_wrap_1_arg(gxg_gluTessEndPolygon_w, gxg_gluTessEndPolygon) #endif #ifdef GLU_VERSION_1_2 Xen_wrap_4_args(gxg_gluTessNormal_w, gxg_gluTessNormal) #endif #ifdef GLU_VERSION_1_2 Xen_wrap_3_args(gxg_gluTessProperty_w, gxg_gluTessProperty) #endif #ifdef GLU_VERSION_1_2 Xen_wrap_3_args(gxg_gluTessVertex_w, gxg_gluTessVertex) #endif Xen_wrap_any_args(gxg_gluUnProject_w, gxg_gluUnProject) Xen_wrap_any_args(gxg_gluUnProject4_w, gxg_gluUnProject4) #endif static void define_functions(void) { #if HAVE_SCHEME static s7_pointer s_boolean, s_integer, s_real, s_any; static s7_pointer pl_tb, pl_t, pl_bt, pl_tttti, pl_ttttb, pl_ttri, pl_ttit, pl_ttr, pl_ttir, pl_ttb, pl_tti, pl_ttiti, pl_ttrriir, pl_ttititiiti, pl_ttititi, pl_ttrri, pl_ttrrri, pl_iiiiitiiit, pl_iiiiiiiit, pl_iiiiiiiiiiit, pl_iiiiiiit, pl_iiiiiiiiiit, pl_iiiiiit, pl_iiiiiiiiit, pl_irrrt, pl_irrrrtttrrt, pl_i, pl_bit, pl_bi, pl_ittit, pl_tiirrrrt, pl_tiiiit, pl_tiiit, pl_tiiiiiiit, pl_tiiiiiiiit, pl_tirriit, pl_tirriirriit, pl_tirrir, pl_tir, pl_tit, pl_tiiiiiiiiit, pl_tiiiiiiiiiit, pl_tiiib, pl_ti, pl_tiiiiiit, pl_tiir, pl_tiiiiit, pl_tiit, pl_tibiit, pl_tiib, pl_trrrrt, pl_tr, pl_unused; s_boolean = s7_make_symbol(s7, "boolean?"); s_integer = s7_make_symbol(s7, "integer?"); s_real = s7_make_symbol(s7, "real?"); s_any = s7_t(s7); pl_tb = s7_make_circular_signature(s7, 1, 2, s_any, s_boolean); pl_t = s7_make_circular_signature(s7, 0, 1, s_any); pl_bt = s7_make_circular_signature(s7, 1, 2, s_boolean, s_any); pl_tttti = s7_make_circular_signature(s7, 4, 5, s_any, s_any, s_any, s_any, s_integer); pl_ttttb = s7_make_circular_signature(s7, 4, 5, s_any, s_any, s_any, s_any, s_boolean); pl_ttri = s7_make_circular_signature(s7, 3, 4, s_any, s_any, s_real, s_integer); pl_ttit = s7_make_circular_signature(s7, 3, 4, s_any, s_any, s_integer, s_any); pl_ttr = s7_make_circular_signature(s7, 2, 3, s_any, s_any, s_real); pl_ttir = s7_make_circular_signature(s7, 3, 4, s_any, s_any, s_integer, s_real); pl_ttb = s7_make_circular_signature(s7, 2, 3, s_any, s_any, s_boolean); pl_tti = s7_make_circular_signature(s7, 2, 3, s_any, s_any, s_integer); pl_ttiti = s7_make_circular_signature(s7, 4, 5, s_any, s_any, s_integer, s_any, s_integer); pl_ttrriir = s7_make_circular_signature(s7, 6, 7, s_any, s_any, s_real, s_real, s_integer, s_integer, s_real); pl_ttititiiti = s7_make_circular_signature(s7, 9, 10, s_any, s_any, s_integer, s_any, s_integer, s_any, s_integer, s_integer, s_any, s_integer); pl_ttititi = s7_make_circular_signature(s7, 6, 7, s_any, s_any, s_integer, s_any, s_integer, s_any, s_integer); pl_ttrri = s7_make_circular_signature(s7, 4, 5, s_any, s_any, s_real, s_real, s_integer); pl_ttrrri = s7_make_circular_signature(s7, 5, 6, s_any, s_any, s_real, s_real, s_real, s_integer); pl_iiiiitiiit = s7_make_circular_signature(s7, 9, 10, s_integer, s_integer, s_integer, s_integer, s_integer, s_any, s_integer, s_integer, s_integer, s_any); pl_iiiiiiiit = s7_make_circular_signature(s7, 8, 9, s_integer, s_integer, s_integer, s_integer, s_integer, s_integer, s_integer, s_integer, s_any); pl_iiiiiiiiiiit = s7_make_circular_signature(s7, 11, 12, s_integer, s_integer, s_integer, s_integer, s_integer, s_integer, s_integer, s_integer, s_integer, s_integer, s_integer, s_any); pl_iiiiiiit = s7_make_circular_signature(s7, 7, 8, s_integer, s_integer, s_integer, s_integer, s_integer, s_integer, s_integer, s_any); pl_iiiiiiiiiit = s7_make_circular_signature(s7, 10, 11, s_integer, s_integer, s_integer, s_integer, s_integer, s_integer, s_integer, s_integer, s_integer, s_integer, s_any); pl_iiiiiit = s7_make_circular_signature(s7, 6, 7, s_integer, s_integer, s_integer, s_integer, s_integer, s_integer, s_any); pl_iiiiiiiiit = s7_make_circular_signature(s7, 9, 10, s_integer, s_integer, s_integer, s_integer, s_integer, s_integer, s_integer, s_integer, s_integer, s_any); pl_irrrt = s7_make_circular_signature(s7, 4, 5, s_integer, s_real, s_real, s_real, s_any); pl_irrrrtttrrt = s7_make_circular_signature(s7, 10, 11, s_integer, s_real, s_real, s_real, s_real, s_any, s_any, s_any, s_real, s_real, s_any); pl_i = s7_make_circular_signature(s7, 0, 1, s_integer); pl_bit = s7_make_circular_signature(s7, 2, 3, s_boolean, s_integer, s_any); pl_bi = s7_make_circular_signature(s7, 1, 2, s_boolean, s_integer); pl_ittit = s7_make_circular_signature(s7, 4, 5, s_integer, s_any, s_any, s_integer, s_any); pl_tiirrrrt = s7_make_circular_signature(s7, 7, 8, s_any, s_integer, s_integer, s_real, s_real, s_real, s_real, s_any); pl_tiiiit = s7_make_circular_signature(s7, 5, 6, s_any, s_integer, s_integer, s_integer, s_integer, s_any); pl_tiiit = s7_make_circular_signature(s7, 4, 5, s_any, s_integer, s_integer, s_integer, s_any); pl_tiiiiiiit = s7_make_circular_signature(s7, 8, 9, s_any, s_integer, s_integer, s_integer, s_integer, s_integer, s_integer, s_integer, s_any); pl_tiiiiiiiit = s7_make_circular_signature(s7, 9, 10, s_any, s_integer, s_integer, s_integer, s_integer, s_integer, s_integer, s_integer, s_integer, s_any); pl_tirriit = s7_make_circular_signature(s7, 6, 7, s_any, s_integer, s_real, s_real, s_integer, s_integer, s_any); pl_tirriirriit = s7_make_circular_signature(s7, 10, 11, s_any, s_integer, s_real, s_real, s_integer, s_integer, s_real, s_real, s_integer, s_integer, s_any); pl_tirrir = s7_make_circular_signature(s7, 5, 6, s_any, s_integer, s_real, s_real, s_integer, s_real); pl_tir = s7_make_circular_signature(s7, 2, 3, s_any, s_integer, s_real); pl_tit = s7_make_circular_signature(s7, 2, 3, s_any, s_integer, s_any); pl_tiiiiiiiiit = s7_make_circular_signature(s7, 10, 11, s_any, s_integer, s_integer, s_integer, s_integer, s_integer, s_integer, s_integer, s_integer, s_integer, s_any); pl_tiiiiiiiiiit = s7_make_circular_signature(s7, 11, 12, s_any, s_integer, s_integer, s_integer, s_integer, s_integer, s_integer, s_integer, s_integer, s_integer, s_integer, s_any); pl_tiiib = s7_make_circular_signature(s7, 4, 5, s_any, s_integer, s_integer, s_integer, s_boolean); pl_ti = s7_make_circular_signature(s7, 1, 2, s_any, s_integer); pl_tiiiiiit = s7_make_circular_signature(s7, 7, 8, s_any, s_integer, s_integer, s_integer, s_integer, s_integer, s_integer, s_any); pl_tiir = s7_make_circular_signature(s7, 3, 4, s_any, s_integer, s_integer, s_real); pl_tiiiiit = s7_make_circular_signature(s7, 6, 7, s_any, s_integer, s_integer, s_integer, s_integer, s_integer, s_any); pl_tiit = s7_make_circular_signature(s7, 3, 4, s_any, s_integer, s_integer, s_any); pl_tibiit = s7_make_circular_signature(s7, 5, 6, s_any, s_integer, s_boolean, s_integer, s_integer, s_any); pl_tiib = s7_make_circular_signature(s7, 3, 4, s_any, s_integer, s_integer, s_boolean); pl_trrrrt = s7_make_circular_signature(s7, 5, 6, s_any, s_real, s_real, s_real, s_real, s_any); pl_tr = s7_make_circular_signature(s7, 1, 2, s_any, s_real); pl_unused = NULL; #endif #if HAVE_SCHEME #define gl_define_procedure(Name, Value, A1, A2, A3, Help, Sig) s7_define_typed_function(s7, XL_PRE #Name XL_POST, Value, A1, A2, A3, Help, Sig) #else #define gl_define_procedure(Name, Value, A1, A2, A3, Help, Sig) Xen_define_safe_procedure(XL_PRE #Name XL_POST, Value, A1, A2, A3, Help) #endif #if USE_MOTIF gl_define_procedure(glXChooseVisual, gxg_glXChooseVisual_w, 3, 0, 0, H_glXChooseVisual, pl_ttit); gl_define_procedure(glXCopyContext, gxg_glXCopyContext_w, 4, 0, 0, H_glXCopyContext, pl_tttti); gl_define_procedure(glXCreateContext, gxg_glXCreateContext_w, 4, 0, 0, H_glXCreateContext, pl_ttttb); gl_define_procedure(glXCreateGLXPixmap, gxg_glXCreateGLXPixmap_w, 3, 0, 0, H_glXCreateGLXPixmap, pl_t); gl_define_procedure(glXDestroyContext, gxg_glXDestroyContext_w, 2, 0, 0, H_glXDestroyContext, pl_t); gl_define_procedure(glXDestroyGLXPixmap, gxg_glXDestroyGLXPixmap_w, 2, 0, 0, H_glXDestroyGLXPixmap, pl_t); gl_define_procedure(glXGetConfig, gxg_glXGetConfig_w, 3, 1, 0, H_glXGetConfig, pl_ittit); gl_define_procedure(glXGetCurrentContext, gxg_glXGetCurrentContext_w, 0, 0, 0, H_glXGetCurrentContext, pl_t); gl_define_procedure(glXGetCurrentDrawable, gxg_glXGetCurrentDrawable_w, 0, 0, 0, H_glXGetCurrentDrawable, pl_t); gl_define_procedure(glXIsDirect, gxg_glXIsDirect_w, 2, 0, 0, H_glXIsDirect, pl_bt); gl_define_procedure(glXMakeCurrent, gxg_glXMakeCurrent_w, 3, 0, 0, H_glXMakeCurrent, pl_bt); gl_define_procedure(glXQueryExtension, gxg_glXQueryExtension_w, 1, 2, 0, H_glXQueryExtension, pl_bt); gl_define_procedure(glXQueryVersion, gxg_glXQueryVersion_w, 1, 2, 0, H_glXQueryVersion, pl_bt); gl_define_procedure(glXSwapBuffers, gxg_glXSwapBuffers_w, 2, 0, 0, H_glXSwapBuffers, pl_t); gl_define_procedure(glXUseXFont, gxg_glXUseXFont_w, 4, 0, 0, H_glXUseXFont, pl_tti); gl_define_procedure(glXWaitGL, gxg_glXWaitGL_w, 0, 0, 0, H_glXWaitGL, pl_t); gl_define_procedure(glXWaitX, gxg_glXWaitX_w, 0, 0, 0, H_glXWaitX, pl_t); gl_define_procedure(glXGetClientString, gxg_glXGetClientString_w, 2, 0, 0, H_glXGetClientString, pl_tti); gl_define_procedure(glXQueryServerString, gxg_glXQueryServerString_w, 3, 0, 0, H_glXQueryServerString, pl_tti); gl_define_procedure(glXQueryExtensionsString, gxg_glXQueryExtensionsString_w, 2, 0, 0, H_glXQueryExtensionsString, pl_tti); #endif gl_define_procedure(glClearIndex, gxg_glClearIndex_w, 1, 0, 0, H_glClearIndex, pl_tr); gl_define_procedure(glClearColor, gxg_glClearColor_w, 4, 0, 0, H_glClearColor, pl_tr); gl_define_procedure(glClear, gxg_glClear_w, 1, 0, 0, H_glClear, pl_ti); gl_define_procedure(glIndexMask, gxg_glIndexMask_w, 1, 0, 0, H_glIndexMask, pl_ti); gl_define_procedure(glColorMask, gxg_glColorMask_w, 4, 0, 0, H_glColorMask, pl_tb); gl_define_procedure(glAlphaFunc, gxg_glAlphaFunc_w, 2, 0, 0, H_glAlphaFunc, pl_tir); gl_define_procedure(glBlendFunc, gxg_glBlendFunc_w, 2, 0, 0, H_glBlendFunc, pl_ti); gl_define_procedure(glLogicOp, gxg_glLogicOp_w, 1, 0, 0, H_glLogicOp, pl_ti); gl_define_procedure(glCullFace, gxg_glCullFace_w, 1, 0, 0, H_glCullFace, pl_ti); gl_define_procedure(glFrontFace, gxg_glFrontFace_w, 1, 0, 0, H_glFrontFace, pl_ti); gl_define_procedure(glPointSize, gxg_glPointSize_w, 1, 0, 0, H_glPointSize, pl_tr); gl_define_procedure(glLineWidth, gxg_glLineWidth_w, 1, 0, 0, H_glLineWidth, pl_tr); gl_define_procedure(glLineStipple, gxg_glLineStipple_w, 2, 0, 0, H_glLineStipple, pl_ti); gl_define_procedure(glPolygonMode, gxg_glPolygonMode_w, 2, 0, 0, H_glPolygonMode, pl_ti); gl_define_procedure(glPolygonOffset, gxg_glPolygonOffset_w, 2, 0, 0, H_glPolygonOffset, pl_tr); gl_define_procedure(glPolygonStipple, gxg_glPolygonStipple_w, 1, 0, 0, H_glPolygonStipple, pl_t); gl_define_procedure(glEdgeFlag, gxg_glEdgeFlag_w, 1, 0, 0, H_glEdgeFlag, pl_tb); gl_define_procedure(glScissor, gxg_glScissor_w, 4, 0, 0, H_glScissor, pl_ti); gl_define_procedure(glClipPlane, gxg_glClipPlane_w, 2, 0, 0, H_glClipPlane, pl_tit); gl_define_procedure(glGetClipPlane, gxg_glGetClipPlane_w, 1, 1, 0, H_glGetClipPlane, pl_tit); gl_define_procedure(glDrawBuffer, gxg_glDrawBuffer_w, 1, 0, 0, H_glDrawBuffer, pl_ti); gl_define_procedure(glReadBuffer, gxg_glReadBuffer_w, 1, 0, 0, H_glReadBuffer, pl_ti); gl_define_procedure(glEnable, gxg_glEnable_w, 1, 0, 0, H_glEnable, pl_ti); gl_define_procedure(glDisable, gxg_glDisable_w, 1, 0, 0, H_glDisable, pl_ti); gl_define_procedure(glIsEnabled, gxg_glIsEnabled_w, 1, 0, 0, H_glIsEnabled, pl_bi); gl_define_procedure(glEnableClientState, gxg_glEnableClientState_w, 1, 0, 0, H_glEnableClientState, pl_ti); gl_define_procedure(glDisableClientState, gxg_glDisableClientState_w, 1, 0, 0, H_glDisableClientState, pl_ti); gl_define_procedure(glGetBooleanv, gxg_glGetBooleanv_w, 1, 1, 0, H_glGetBooleanv, pl_tit); gl_define_procedure(glGetDoublev, gxg_glGetDoublev_w, 1, 1, 0, H_glGetDoublev, pl_tit); gl_define_procedure(glGetFloatv, gxg_glGetFloatv_w, 1, 1, 0, H_glGetFloatv, pl_tit); gl_define_procedure(glGetIntegerv, gxg_glGetIntegerv_w, 1, 1, 0, H_glGetIntegerv, pl_tit); gl_define_procedure(glPushAttrib, gxg_glPushAttrib_w, 1, 0, 0, H_glPushAttrib, pl_ti); gl_define_procedure(glPopAttrib, gxg_glPopAttrib_w, 0, 0, 0, H_glPopAttrib, pl_t); gl_define_procedure(glPushClientAttrib, gxg_glPushClientAttrib_w, 1, 0, 0, H_glPushClientAttrib, pl_ti); gl_define_procedure(glPopClientAttrib, gxg_glPopClientAttrib_w, 0, 0, 0, H_glPopClientAttrib, pl_t); gl_define_procedure(glRenderMode, gxg_glRenderMode_w, 1, 0, 0, H_glRenderMode, pl_i); gl_define_procedure(glGetError, gxg_glGetError_w, 0, 0, 0, H_glGetError, pl_i); gl_define_procedure(glGetString, gxg_glGetString_w, 1, 0, 0, H_glGetString, pl_ti); gl_define_procedure(glFinish, gxg_glFinish_w, 0, 0, 0, H_glFinish, pl_t); gl_define_procedure(glFlush, gxg_glFlush_w, 0, 0, 0, H_glFlush, pl_t); gl_define_procedure(glHint, gxg_glHint_w, 2, 0, 0, H_glHint, pl_ti); gl_define_procedure(glClearDepth, gxg_glClearDepth_w, 1, 0, 0, H_glClearDepth, pl_tr); gl_define_procedure(glDepthFunc, gxg_glDepthFunc_w, 1, 0, 0, H_glDepthFunc, pl_ti); gl_define_procedure(glDepthMask, gxg_glDepthMask_w, 1, 0, 0, H_glDepthMask, pl_tb); gl_define_procedure(glDepthRange, gxg_glDepthRange_w, 2, 0, 0, H_glDepthRange, pl_tr); gl_define_procedure(glClearAccum, gxg_glClearAccum_w, 4, 0, 0, H_glClearAccum, pl_tr); gl_define_procedure(glAccum, gxg_glAccum_w, 2, 0, 0, H_glAccum, pl_tir); gl_define_procedure(glMatrixMode, gxg_glMatrixMode_w, 1, 0, 0, H_glMatrixMode, pl_ti); gl_define_procedure(glOrtho, gxg_glOrtho_w, 6, 0, 0, H_glOrtho, pl_tr); gl_define_procedure(glFrustum, gxg_glFrustum_w, 6, 0, 0, H_glFrustum, pl_tr); gl_define_procedure(glViewport, gxg_glViewport_w, 4, 0, 0, H_glViewport, pl_ti); gl_define_procedure(glPushMatrix, gxg_glPushMatrix_w, 0, 0, 0, H_glPushMatrix, pl_t); gl_define_procedure(glPopMatrix, gxg_glPopMatrix_w, 0, 0, 0, H_glPopMatrix, pl_t); gl_define_procedure(glLoadIdentity, gxg_glLoadIdentity_w, 0, 0, 0, H_glLoadIdentity, pl_t); gl_define_procedure(glLoadMatrixd, gxg_glLoadMatrixd_w, 1, 0, 0, H_glLoadMatrixd, pl_t); gl_define_procedure(glLoadMatrixf, gxg_glLoadMatrixf_w, 1, 0, 0, H_glLoadMatrixf, pl_t); gl_define_procedure(glMultMatrixd, gxg_glMultMatrixd_w, 1, 0, 0, H_glMultMatrixd, pl_t); gl_define_procedure(glMultMatrixf, gxg_glMultMatrixf_w, 1, 0, 0, H_glMultMatrixf, pl_t); gl_define_procedure(glRotated, gxg_glRotated_w, 4, 0, 0, H_glRotated, pl_tr); gl_define_procedure(glRotatef, gxg_glRotatef_w, 4, 0, 0, H_glRotatef, pl_tr); gl_define_procedure(glScaled, gxg_glScaled_w, 3, 0, 0, H_glScaled, pl_tr); gl_define_procedure(glScalef, gxg_glScalef_w, 3, 0, 0, H_glScalef, pl_tr); gl_define_procedure(glTranslated, gxg_glTranslated_w, 3, 0, 0, H_glTranslated, pl_tr); gl_define_procedure(glTranslatef, gxg_glTranslatef_w, 3, 0, 0, H_glTranslatef, pl_tr); gl_define_procedure(glIsList, gxg_glIsList_w, 1, 0, 0, H_glIsList, pl_bi); gl_define_procedure(glDeleteLists, gxg_glDeleteLists_w, 2, 0, 0, H_glDeleteLists, pl_ti); gl_define_procedure(glGenLists, gxg_glGenLists_w, 1, 0, 0, H_glGenLists, pl_i); gl_define_procedure(glNewList, gxg_glNewList_w, 2, 0, 0, H_glNewList, pl_ti); gl_define_procedure(glEndList, gxg_glEndList_w, 0, 0, 0, H_glEndList, pl_t); gl_define_procedure(glCallList, gxg_glCallList_w, 1, 0, 0, H_glCallList, pl_ti); gl_define_procedure(glCallLists, gxg_glCallLists_w, 3, 0, 0, H_glCallLists, pl_tiit); gl_define_procedure(glListBase, gxg_glListBase_w, 1, 0, 0, H_glListBase, pl_ti); gl_define_procedure(glBegin, gxg_glBegin_w, 1, 0, 0, H_glBegin, pl_ti); gl_define_procedure(glEnd, gxg_glEnd_w, 0, 0, 0, H_glEnd, pl_t); gl_define_procedure(glVertex2d, gxg_glVertex2d_w, 2, 0, 0, H_glVertex2d, pl_tr); gl_define_procedure(glVertex2f, gxg_glVertex2f_w, 2, 0, 0, H_glVertex2f, pl_tr); gl_define_procedure(glVertex2i, gxg_glVertex2i_w, 2, 0, 0, H_glVertex2i, pl_ti); gl_define_procedure(glVertex2s, gxg_glVertex2s_w, 2, 0, 0, H_glVertex2s, pl_ti); gl_define_procedure(glVertex3d, gxg_glVertex3d_w, 3, 0, 0, H_glVertex3d, pl_tr); gl_define_procedure(glVertex3f, gxg_glVertex3f_w, 3, 0, 0, H_glVertex3f, pl_tr); gl_define_procedure(glVertex3i, gxg_glVertex3i_w, 3, 0, 0, H_glVertex3i, pl_ti); gl_define_procedure(glVertex3s, gxg_glVertex3s_w, 3, 0, 0, H_glVertex3s, pl_ti); gl_define_procedure(glVertex4d, gxg_glVertex4d_w, 4, 0, 0, H_glVertex4d, pl_tr); gl_define_procedure(glVertex4f, gxg_glVertex4f_w, 4, 0, 0, H_glVertex4f, pl_tr); gl_define_procedure(glVertex4i, gxg_glVertex4i_w, 4, 0, 0, H_glVertex4i, pl_ti); gl_define_procedure(glVertex4s, gxg_glVertex4s_w, 4, 0, 0, H_glVertex4s, pl_ti); gl_define_procedure(glNormal3b, gxg_glNormal3b_w, 3, 0, 0, H_glNormal3b, pl_ti); gl_define_procedure(glNormal3d, gxg_glNormal3d_w, 3, 0, 0, H_glNormal3d, pl_tr); gl_define_procedure(glNormal3f, gxg_glNormal3f_w, 3, 0, 0, H_glNormal3f, pl_tr); gl_define_procedure(glNormal3i, gxg_glNormal3i_w, 3, 0, 0, H_glNormal3i, pl_ti); gl_define_procedure(glNormal3s, gxg_glNormal3s_w, 3, 0, 0, H_glNormal3s, pl_ti); gl_define_procedure(glIndexd, gxg_glIndexd_w, 1, 0, 0, H_glIndexd, pl_tr); gl_define_procedure(glIndexf, gxg_glIndexf_w, 1, 0, 0, H_glIndexf, pl_tr); gl_define_procedure(glIndexi, gxg_glIndexi_w, 1, 0, 0, H_glIndexi, pl_ti); gl_define_procedure(glIndexs, gxg_glIndexs_w, 1, 0, 0, H_glIndexs, pl_ti); gl_define_procedure(glIndexub, gxg_glIndexub_w, 1, 0, 0, H_glIndexub, pl_ti); gl_define_procedure(glColor3b, gxg_glColor3b_w, 3, 0, 0, H_glColor3b, pl_ti); gl_define_procedure(glColor3d, gxg_glColor3d_w, 3, 0, 0, H_glColor3d, pl_tr); gl_define_procedure(glColor3f, gxg_glColor3f_w, 3, 0, 0, H_glColor3f, pl_tr); gl_define_procedure(glColor3i, gxg_glColor3i_w, 3, 0, 0, H_glColor3i, pl_ti); gl_define_procedure(glColor3s, gxg_glColor3s_w, 3, 0, 0, H_glColor3s, pl_ti); gl_define_procedure(glColor3ub, gxg_glColor3ub_w, 3, 0, 0, H_glColor3ub, pl_ti); gl_define_procedure(glColor3ui, gxg_glColor3ui_w, 3, 0, 0, H_glColor3ui, pl_ti); gl_define_procedure(glColor3us, gxg_glColor3us_w, 3, 0, 0, H_glColor3us, pl_ti); gl_define_procedure(glColor4b, gxg_glColor4b_w, 4, 0, 0, H_glColor4b, pl_ti); gl_define_procedure(glColor4d, gxg_glColor4d_w, 4, 0, 0, H_glColor4d, pl_tr); gl_define_procedure(glColor4f, gxg_glColor4f_w, 4, 0, 0, H_glColor4f, pl_tr); gl_define_procedure(glColor4i, gxg_glColor4i_w, 4, 0, 0, H_glColor4i, pl_ti); gl_define_procedure(glColor4s, gxg_glColor4s_w, 4, 0, 0, H_glColor4s, pl_ti); gl_define_procedure(glColor4ub, gxg_glColor4ub_w, 4, 0, 0, H_glColor4ub, pl_ti); gl_define_procedure(glColor4ui, gxg_glColor4ui_w, 4, 0, 0, H_glColor4ui, pl_ti); gl_define_procedure(glColor4us, gxg_glColor4us_w, 4, 0, 0, H_glColor4us, pl_ti); gl_define_procedure(glTexCoord1d, gxg_glTexCoord1d_w, 1, 0, 0, H_glTexCoord1d, pl_tr); gl_define_procedure(glTexCoord1f, gxg_glTexCoord1f_w, 1, 0, 0, H_glTexCoord1f, pl_tr); gl_define_procedure(glTexCoord1i, gxg_glTexCoord1i_w, 1, 0, 0, H_glTexCoord1i, pl_ti); gl_define_procedure(glTexCoord1s, gxg_glTexCoord1s_w, 1, 0, 0, H_glTexCoord1s, pl_ti); gl_define_procedure(glTexCoord2d, gxg_glTexCoord2d_w, 2, 0, 0, H_glTexCoord2d, pl_tr); gl_define_procedure(glTexCoord2f, gxg_glTexCoord2f_w, 2, 0, 0, H_glTexCoord2f, pl_tr); gl_define_procedure(glTexCoord2i, gxg_glTexCoord2i_w, 2, 0, 0, H_glTexCoord2i, pl_ti); gl_define_procedure(glTexCoord2s, gxg_glTexCoord2s_w, 2, 0, 0, H_glTexCoord2s, pl_ti); gl_define_procedure(glTexCoord3d, gxg_glTexCoord3d_w, 3, 0, 0, H_glTexCoord3d, pl_tr); gl_define_procedure(glTexCoord3f, gxg_glTexCoord3f_w, 3, 0, 0, H_glTexCoord3f, pl_tr); gl_define_procedure(glTexCoord3i, gxg_glTexCoord3i_w, 3, 0, 0, H_glTexCoord3i, pl_ti); gl_define_procedure(glTexCoord3s, gxg_glTexCoord3s_w, 3, 0, 0, H_glTexCoord3s, pl_ti); gl_define_procedure(glTexCoord4d, gxg_glTexCoord4d_w, 4, 0, 0, H_glTexCoord4d, pl_tr); gl_define_procedure(glTexCoord4f, gxg_glTexCoord4f_w, 4, 0, 0, H_glTexCoord4f, pl_tr); gl_define_procedure(glTexCoord4i, gxg_glTexCoord4i_w, 4, 0, 0, H_glTexCoord4i, pl_ti); gl_define_procedure(glTexCoord4s, gxg_glTexCoord4s_w, 4, 0, 0, H_glTexCoord4s, pl_ti); gl_define_procedure(glRasterPos2d, gxg_glRasterPos2d_w, 2, 0, 0, H_glRasterPos2d, pl_tr); gl_define_procedure(glRasterPos2f, gxg_glRasterPos2f_w, 2, 0, 0, H_glRasterPos2f, pl_tr); gl_define_procedure(glRasterPos2i, gxg_glRasterPos2i_w, 2, 0, 0, H_glRasterPos2i, pl_ti); gl_define_procedure(glRasterPos2s, gxg_glRasterPos2s_w, 2, 0, 0, H_glRasterPos2s, pl_ti); gl_define_procedure(glRasterPos3d, gxg_glRasterPos3d_w, 3, 0, 0, H_glRasterPos3d, pl_tr); gl_define_procedure(glRasterPos3f, gxg_glRasterPos3f_w, 3, 0, 0, H_glRasterPos3f, pl_tr); gl_define_procedure(glRasterPos3i, gxg_glRasterPos3i_w, 3, 0, 0, H_glRasterPos3i, pl_ti); gl_define_procedure(glRasterPos3s, gxg_glRasterPos3s_w, 3, 0, 0, H_glRasterPos3s, pl_ti); gl_define_procedure(glRasterPos4d, gxg_glRasterPos4d_w, 4, 0, 0, H_glRasterPos4d, pl_tr); gl_define_procedure(glRasterPos4f, gxg_glRasterPos4f_w, 4, 0, 0, H_glRasterPos4f, pl_tr); gl_define_procedure(glRasterPos4i, gxg_glRasterPos4i_w, 4, 0, 0, H_glRasterPos4i, pl_ti); gl_define_procedure(glRasterPos4s, gxg_glRasterPos4s_w, 4, 0, 0, H_glRasterPos4s, pl_ti); gl_define_procedure(glRectd, gxg_glRectd_w, 4, 0, 0, H_glRectd, pl_tr); gl_define_procedure(glRectf, gxg_glRectf_w, 4, 0, 0, H_glRectf, pl_tr); gl_define_procedure(glRecti, gxg_glRecti_w, 4, 0, 0, H_glRecti, pl_ti); gl_define_procedure(glRects, gxg_glRects_w, 4, 0, 0, H_glRects, pl_ti); gl_define_procedure(glVertexPointer, gxg_glVertexPointer_w, 4, 0, 0, H_glVertexPointer, pl_tiiit); gl_define_procedure(glNormalPointer, gxg_glNormalPointer_w, 3, 0, 0, H_glNormalPointer, pl_tiit); gl_define_procedure(glColorPointer, gxg_glColorPointer_w, 4, 0, 0, H_glColorPointer, pl_tiiit); gl_define_procedure(glIndexPointer, gxg_glIndexPointer_w, 3, 0, 0, H_glIndexPointer, pl_tiit); gl_define_procedure(glTexCoordPointer, gxg_glTexCoordPointer_w, 4, 0, 0, H_glTexCoordPointer, pl_tiiit); gl_define_procedure(glEdgeFlagPointer, gxg_glEdgeFlagPointer_w, 2, 0, 0, H_glEdgeFlagPointer, pl_tit); gl_define_procedure(glGetPointerv, gxg_glGetPointerv_w, 1, 1, 0, H_glGetPointerv, pl_tit); gl_define_procedure(glArrayElement, gxg_glArrayElement_w, 1, 0, 0, H_glArrayElement, pl_ti); gl_define_procedure(glDrawArrays, gxg_glDrawArrays_w, 3, 0, 0, H_glDrawArrays, pl_ti); gl_define_procedure(glDrawElements, gxg_glDrawElements_w, 4, 0, 0, H_glDrawElements, pl_tiiit); gl_define_procedure(glInterleavedArrays, gxg_glInterleavedArrays_w, 3, 0, 0, H_glInterleavedArrays, pl_tiit); gl_define_procedure(glShadeModel, gxg_glShadeModel_w, 1, 0, 0, H_glShadeModel, pl_ti); gl_define_procedure(glLightf, gxg_glLightf_w, 3, 0, 0, H_glLightf, pl_tiir); gl_define_procedure(glLighti, gxg_glLighti_w, 3, 0, 0, H_glLighti, pl_ti); gl_define_procedure(glGetLightfv, gxg_glGetLightfv_w, 2, 1, 0, H_glGetLightfv, pl_tiit); gl_define_procedure(glGetLightiv, gxg_glGetLightiv_w, 2, 1, 0, H_glGetLightiv, pl_tiit); gl_define_procedure(glLightModelf, gxg_glLightModelf_w, 2, 0, 0, H_glLightModelf, pl_tir); gl_define_procedure(glLightModeli, gxg_glLightModeli_w, 2, 0, 0, H_glLightModeli, pl_ti); gl_define_procedure(glMaterialf, gxg_glMaterialf_w, 3, 0, 0, H_glMaterialf, pl_tiir); gl_define_procedure(glMateriali, gxg_glMateriali_w, 3, 0, 0, H_glMateriali, pl_ti); gl_define_procedure(glGetMaterialfv, gxg_glGetMaterialfv_w, 2, 1, 0, H_glGetMaterialfv, pl_tiit); gl_define_procedure(glGetMaterialiv, gxg_glGetMaterialiv_w, 2, 1, 0, H_glGetMaterialiv, pl_tiit); gl_define_procedure(glColorMaterial, gxg_glColorMaterial_w, 2, 0, 0, H_glColorMaterial, pl_ti); gl_define_procedure(glPixelZoom, gxg_glPixelZoom_w, 2, 0, 0, H_glPixelZoom, pl_tr); gl_define_procedure(glPixelStoref, gxg_glPixelStoref_w, 2, 0, 0, H_glPixelStoref, pl_tir); gl_define_procedure(glPixelStorei, gxg_glPixelStorei_w, 2, 0, 0, H_glPixelStorei, pl_ti); gl_define_procedure(glPixelTransferf, gxg_glPixelTransferf_w, 2, 0, 0, H_glPixelTransferf, pl_tir); gl_define_procedure(glPixelTransferi, gxg_glPixelTransferi_w, 2, 0, 0, H_glPixelTransferi, pl_ti); gl_define_procedure(glGetPixelMapfv, gxg_glGetPixelMapfv_w, 1, 1, 0, H_glGetPixelMapfv, pl_tit); gl_define_procedure(glGetPixelMapuiv, gxg_glGetPixelMapuiv_w, 1, 1, 0, H_glGetPixelMapuiv, pl_tit); gl_define_procedure(glGetPixelMapusv, gxg_glGetPixelMapusv_w, 1, 1, 0, H_glGetPixelMapusv, pl_tit); gl_define_procedure(glBitmap, gxg_glBitmap_w, 7, 0, 0, H_glBitmap, pl_tiirrrrt); gl_define_procedure(glReadPixels, gxg_glReadPixels_w, 7, 0, 0, H_glReadPixels, pl_tiiiiiit); gl_define_procedure(glDrawPixels, gxg_glDrawPixels_w, 5, 0, 0, H_glDrawPixels, pl_tiiiit); gl_define_procedure(glCopyPixels, gxg_glCopyPixels_w, 5, 0, 0, H_glCopyPixels, pl_ti); gl_define_procedure(glStencilFunc, gxg_glStencilFunc_w, 3, 0, 0, H_glStencilFunc, pl_ti); gl_define_procedure(glStencilMask, gxg_glStencilMask_w, 1, 0, 0, H_glStencilMask, pl_ti); gl_define_procedure(glStencilOp, gxg_glStencilOp_w, 3, 0, 0, H_glStencilOp, pl_ti); gl_define_procedure(glClearStencil, gxg_glClearStencil_w, 1, 0, 0, H_glClearStencil, pl_ti); gl_define_procedure(glTexGend, gxg_glTexGend_w, 3, 0, 0, H_glTexGend, pl_tiir); gl_define_procedure(glTexGenf, gxg_glTexGenf_w, 3, 0, 0, H_glTexGenf, pl_tiir); gl_define_procedure(glTexGeni, gxg_glTexGeni_w, 3, 0, 0, H_glTexGeni, pl_ti); gl_define_procedure(glGetTexGendv, gxg_glGetTexGendv_w, 2, 1, 0, H_glGetTexGendv, pl_tiit); gl_define_procedure(glGetTexGenfv, gxg_glGetTexGenfv_w, 2, 1, 0, H_glGetTexGenfv, pl_tiit); gl_define_procedure(glGetTexGeniv, gxg_glGetTexGeniv_w, 2, 1, 0, H_glGetTexGeniv, pl_tiit); gl_define_procedure(glTexEnvf, gxg_glTexEnvf_w, 3, 0, 0, H_glTexEnvf, pl_tiir); gl_define_procedure(glTexEnvi, gxg_glTexEnvi_w, 3, 0, 0, H_glTexEnvi, pl_ti); gl_define_procedure(glGetTexEnvfv, gxg_glGetTexEnvfv_w, 2, 1, 0, H_glGetTexEnvfv, pl_tiit); gl_define_procedure(glGetTexEnviv, gxg_glGetTexEnviv_w, 2, 1, 0, H_glGetTexEnviv, pl_tiit); gl_define_procedure(glTexParameterf, gxg_glTexParameterf_w, 3, 0, 0, H_glTexParameterf, pl_tiir); gl_define_procedure(glTexParameteri, gxg_glTexParameteri_w, 3, 0, 0, H_glTexParameteri, pl_ti); gl_define_procedure(glGetTexParameterfv, gxg_glGetTexParameterfv_w, 2, 1, 0, H_glGetTexParameterfv, pl_tiit); gl_define_procedure(glGetTexParameteriv, gxg_glGetTexParameteriv_w, 2, 1, 0, H_glGetTexParameteriv, pl_tiit); gl_define_procedure(glGetTexLevelParameterfv, gxg_glGetTexLevelParameterfv_w, 3, 1, 0, H_glGetTexLevelParameterfv, pl_tiiit); gl_define_procedure(glGetTexLevelParameteriv, gxg_glGetTexLevelParameteriv_w, 3, 1, 0, H_glGetTexLevelParameteriv, pl_tiiit); gl_define_procedure(glTexImage1D, gxg_glTexImage1D_w, 0, 0, 1, H_glTexImage1D, pl_tiiiiiiit); gl_define_procedure(glTexImage2D, gxg_glTexImage2D_w, 0, 0, 1, H_glTexImage2D, pl_tiiiiiiiit); gl_define_procedure(glGenTextures, gxg_glGenTextures_w, 2, 0, 0, H_glGenTextures, pl_tit); gl_define_procedure(glDeleteTextures, gxg_glDeleteTextures_w, 2, 0, 0, H_glDeleteTextures, pl_tit); gl_define_procedure(glBindTexture, gxg_glBindTexture_w, 2, 0, 0, H_glBindTexture, pl_ti); gl_define_procedure(glAreTexturesResident, gxg_glAreTexturesResident_w, 3, 0, 0, H_glAreTexturesResident, pl_bit); gl_define_procedure(glIsTexture, gxg_glIsTexture_w, 1, 0, 0, H_glIsTexture, pl_bi); gl_define_procedure(glTexSubImage1D, gxg_glTexSubImage1D_w, 7, 0, 0, H_glTexSubImage1D, pl_tiiiiiit); gl_define_procedure(glTexSubImage2D, gxg_glTexSubImage2D_w, 0, 0, 1, H_glTexSubImage2D, pl_tiiiiiiiit); gl_define_procedure(glCopyTexImage1D, gxg_glCopyTexImage1D_w, 7, 0, 0, H_glCopyTexImage1D, pl_ti); gl_define_procedure(glCopyTexImage2D, gxg_glCopyTexImage2D_w, 0, 0, 1, H_glCopyTexImage2D, pl_ti); gl_define_procedure(glCopyTexSubImage1D, gxg_glCopyTexSubImage1D_w, 6, 0, 0, H_glCopyTexSubImage1D, pl_ti); gl_define_procedure(glCopyTexSubImage2D, gxg_glCopyTexSubImage2D_w, 0, 0, 1, H_glCopyTexSubImage2D, pl_ti); gl_define_procedure(glMap1d, gxg_glMap1d_w, 6, 0, 0, H_glMap1d, pl_tirriit); gl_define_procedure(glMap1f, gxg_glMap1f_w, 6, 0, 0, H_glMap1f, pl_tirriit); gl_define_procedure(glMap2d, gxg_glMap2d_w, 0, 0, 1, H_glMap2d, pl_tirriirriit); gl_define_procedure(glMap2f, gxg_glMap2f_w, 0, 0, 1, H_glMap2f, pl_tirriirriit); gl_define_procedure(glGetMapdv, gxg_glGetMapdv_w, 2, 1, 0, H_glGetMapdv, pl_tiit); gl_define_procedure(glGetMapfv, gxg_glGetMapfv_w, 2, 1, 0, H_glGetMapfv, pl_tiit); gl_define_procedure(glGetMapiv, gxg_glGetMapiv_w, 2, 1, 0, H_glGetMapiv, pl_tiit); gl_define_procedure(glEvalCoord1d, gxg_glEvalCoord1d_w, 1, 0, 0, H_glEvalCoord1d, pl_tr); gl_define_procedure(glEvalCoord1f, gxg_glEvalCoord1f_w, 1, 0, 0, H_glEvalCoord1f, pl_tr); gl_define_procedure(glEvalCoord2d, gxg_glEvalCoord2d_w, 2, 0, 0, H_glEvalCoord2d, pl_tr); gl_define_procedure(glEvalCoord2f, gxg_glEvalCoord2f_w, 2, 0, 0, H_glEvalCoord2f, pl_tr); gl_define_procedure(glMapGrid1d, gxg_glMapGrid1d_w, 3, 0, 0, H_glMapGrid1d, pl_tir); gl_define_procedure(glMapGrid1f, gxg_glMapGrid1f_w, 3, 0, 0, H_glMapGrid1f, pl_tir); gl_define_procedure(glMapGrid2d, gxg_glMapGrid2d_w, 6, 0, 0, H_glMapGrid2d, pl_tirrir); gl_define_procedure(glMapGrid2f, gxg_glMapGrid2f_w, 6, 0, 0, H_glMapGrid2f, pl_tirrir); gl_define_procedure(glEvalPoint1, gxg_glEvalPoint1_w, 1, 0, 0, H_glEvalPoint1, pl_ti); gl_define_procedure(glEvalPoint2, gxg_glEvalPoint2_w, 2, 0, 0, H_glEvalPoint2, pl_ti); gl_define_procedure(glEvalMesh1, gxg_glEvalMesh1_w, 3, 0, 0, H_glEvalMesh1, pl_ti); gl_define_procedure(glEvalMesh2, gxg_glEvalMesh2_w, 5, 0, 0, H_glEvalMesh2, pl_ti); gl_define_procedure(glFogf, gxg_glFogf_w, 2, 0, 0, H_glFogf, pl_tir); gl_define_procedure(glFogi, gxg_glFogi_w, 2, 0, 0, H_glFogi, pl_ti); gl_define_procedure(glFeedbackBuffer, gxg_glFeedbackBuffer_w, 3, 0, 0, H_glFeedbackBuffer, pl_tiit); gl_define_procedure(glPassThrough, gxg_glPassThrough_w, 1, 0, 0, H_glPassThrough, pl_tr); gl_define_procedure(glSelectBuffer, gxg_glSelectBuffer_w, 2, 0, 0, H_glSelectBuffer, pl_tit); gl_define_procedure(glInitNames, gxg_glInitNames_w, 0, 0, 0, H_glInitNames, pl_t); gl_define_procedure(glLoadName, gxg_glLoadName_w, 1, 0, 0, H_glLoadName, pl_ti); gl_define_procedure(glPushName, gxg_glPushName_w, 1, 0, 0, H_glPushName, pl_ti); gl_define_procedure(glPopName, gxg_glPopName_w, 0, 0, 0, H_glPopName, pl_t); gl_define_procedure(glDrawRangeElements, gxg_glDrawRangeElements_w, 6, 0, 0, H_glDrawRangeElements, pl_tiiiiit); gl_define_procedure(glTexImage3D, gxg_glTexImage3D_w, 0, 0, 1, H_glTexImage3D, pl_tiiiiiiiiit); gl_define_procedure(glTexSubImage3D, gxg_glTexSubImage3D_w, 0, 0, 1, H_glTexSubImage3D, pl_tiiiiiiiiiit); gl_define_procedure(glCopyTexSubImage3D, gxg_glCopyTexSubImage3D_w, 0, 0, 1, H_glCopyTexSubImage3D, pl_ti); gl_define_procedure(glColorTable, gxg_glColorTable_w, 6, 0, 0, H_glColorTable, pl_tiiiiit); gl_define_procedure(glColorSubTable, gxg_glColorSubTable_w, 6, 0, 0, H_glColorSubTable, pl_tiiiiit); gl_define_procedure(glCopyColorSubTable, gxg_glCopyColorSubTable_w, 5, 0, 0, H_glCopyColorSubTable, pl_ti); gl_define_procedure(glCopyColorTable, gxg_glCopyColorTable_w, 5, 0, 0, H_glCopyColorTable, pl_ti); gl_define_procedure(glGetColorTableParameterfv, gxg_glGetColorTableParameterfv_w, 2, 1, 0, H_glGetColorTableParameterfv, pl_tiit); gl_define_procedure(glGetColorTableParameteriv, gxg_glGetColorTableParameteriv_w, 2, 1, 0, H_glGetColorTableParameteriv, pl_tiit); gl_define_procedure(glBlendEquation, gxg_glBlendEquation_w, 1, 0, 0, H_glBlendEquation, pl_ti); gl_define_procedure(glBlendColor, gxg_glBlendColor_w, 4, 0, 0, H_glBlendColor, pl_tr); gl_define_procedure(glHistogram, gxg_glHistogram_w, 4, 0, 0, H_glHistogram, pl_tiiib); gl_define_procedure(glResetHistogram, gxg_glResetHistogram_w, 1, 0, 0, H_glResetHistogram, pl_ti); gl_define_procedure(glGetHistogram, gxg_glGetHistogram_w, 5, 0, 0, H_glGetHistogram, pl_tibiit); gl_define_procedure(glGetHistogramParameterfv, gxg_glGetHistogramParameterfv_w, 2, 1, 0, H_glGetHistogramParameterfv, pl_tiit); gl_define_procedure(glGetHistogramParameteriv, gxg_glGetHistogramParameteriv_w, 2, 1, 0, H_glGetHistogramParameteriv, pl_tiit); gl_define_procedure(glMinmax, gxg_glMinmax_w, 3, 0, 0, H_glMinmax, pl_tiib); gl_define_procedure(glResetMinmax, gxg_glResetMinmax_w, 1, 0, 0, H_glResetMinmax, pl_ti); gl_define_procedure(glGetMinmax, gxg_glGetMinmax_w, 5, 0, 0, H_glGetMinmax, pl_tibiit); gl_define_procedure(glGetMinmaxParameterfv, gxg_glGetMinmaxParameterfv_w, 2, 1, 0, H_glGetMinmaxParameterfv, pl_tiit); gl_define_procedure(glGetMinmaxParameteriv, gxg_glGetMinmaxParameteriv_w, 2, 1, 0, H_glGetMinmaxParameteriv, pl_tiit); gl_define_procedure(glConvolutionFilter1D, gxg_glConvolutionFilter1D_w, 6, 0, 0, H_glConvolutionFilter1D, pl_tiiiiit); gl_define_procedure(glConvolutionFilter2D, gxg_glConvolutionFilter2D_w, 7, 0, 0, H_glConvolutionFilter2D, pl_tiiiiiit); gl_define_procedure(glConvolutionParameterf, gxg_glConvolutionParameterf_w, 3, 0, 0, H_glConvolutionParameterf, pl_tiir); gl_define_procedure(glConvolutionParameteri, gxg_glConvolutionParameteri_w, 3, 0, 0, H_glConvolutionParameteri, pl_ti); gl_define_procedure(glCopyConvolutionFilter1D, gxg_glCopyConvolutionFilter1D_w, 5, 0, 0, H_glCopyConvolutionFilter1D, pl_ti); gl_define_procedure(glCopyConvolutionFilter2D, gxg_glCopyConvolutionFilter2D_w, 6, 0, 0, H_glCopyConvolutionFilter2D, pl_ti); gl_define_procedure(glSeparableFilter2D, gxg_glSeparableFilter2D_w, 0, 0, 1, H_glSeparableFilter2D, pl_tiiiiiit); #if HAVE_GLU gl_define_procedure(gluBeginCurve, gxg_gluBeginCurve_w, 1, 0, 0, H_gluBeginCurve, pl_t); #ifdef GLU_VERSION_1_2 gl_define_procedure(gluBeginPolygon, gxg_gluBeginPolygon_w, 1, 0, 0, H_gluBeginPolygon, pl_t); #endif gl_define_procedure(gluBeginSurface, gxg_gluBeginSurface_w, 1, 0, 0, H_gluBeginSurface, pl_t); gl_define_procedure(gluBeginTrim, gxg_gluBeginTrim_w, 1, 0, 0, H_gluBeginTrim, pl_t); gl_define_procedure(gluBuild1DMipmapLevels, gxg_gluBuild1DMipmapLevels_w, 0, 0, 1, H_gluBuild1DMipmapLevels, pl_iiiiiiiiit); gl_define_procedure(gluBuild1DMipmaps, gxg_gluBuild1DMipmaps_w, 6, 0, 0, H_gluBuild1DMipmaps, pl_iiiiiit); gl_define_procedure(gluBuild2DMipmapLevels, gxg_gluBuild2DMipmapLevels_w, 0, 0, 1, H_gluBuild2DMipmapLevels, pl_iiiiiiiiiit); gl_define_procedure(gluBuild2DMipmaps, gxg_gluBuild2DMipmaps_w, 7, 0, 0, H_gluBuild2DMipmaps, pl_iiiiiiit); gl_define_procedure(gluBuild3DMipmapLevels, gxg_gluBuild3DMipmapLevels_w, 0, 0, 1, H_gluBuild3DMipmapLevels, pl_iiiiiiiiiiit); gl_define_procedure(gluBuild3DMipmaps, gxg_gluBuild3DMipmaps_w, 0, 0, 1, H_gluBuild3DMipmaps, pl_iiiiiiiit); gl_define_procedure(gluCheckExtension, gxg_gluCheckExtension_w, 2, 0, 0, H_gluCheckExtension, pl_bt); gl_define_procedure(gluCylinder, gxg_gluCylinder_w, 6, 0, 0, H_gluCylinder, pl_ttrrri); gl_define_procedure(gluDeleteNurbsRenderer, gxg_gluDeleteNurbsRenderer_w, 1, 0, 0, H_gluDeleteNurbsRenderer, pl_t); gl_define_procedure(gluDeleteQuadric, gxg_gluDeleteQuadric_w, 1, 0, 0, H_gluDeleteQuadric, pl_t); #ifdef GLU_VERSION_1_2 gl_define_procedure(gluDeleteTess, gxg_gluDeleteTess_w, 1, 0, 0, H_gluDeleteTess, pl_t); #endif gl_define_procedure(gluDisk, gxg_gluDisk_w, 5, 0, 0, H_gluDisk, pl_ttrri); gl_define_procedure(gluEndCurve, gxg_gluEndCurve_w, 1, 0, 0, H_gluEndCurve, pl_t); #ifdef GLU_VERSION_1_2 gl_define_procedure(gluEndPolygon, gxg_gluEndPolygon_w, 1, 0, 0, H_gluEndPolygon, pl_t); #endif gl_define_procedure(gluEndSurface, gxg_gluEndSurface_w, 1, 0, 0, H_gluEndSurface, pl_t); gl_define_procedure(gluEndTrim, gxg_gluEndTrim_w, 1, 0, 0, H_gluEndTrim, pl_t); gl_define_procedure(gluErrorString, gxg_gluErrorString_w, 1, 0, 0, H_gluErrorString, pl_ti); gl_define_procedure(gluGetNurbsProperty, gxg_gluGetNurbsProperty_w, 3, 0, 0, H_gluGetNurbsProperty, pl_ttit); gl_define_procedure(gluGetString, gxg_gluGetString_w, 1, 0, 0, H_gluGetString, pl_ti); #ifdef GLU_VERSION_1_2 gl_define_procedure(gluGetTessProperty, gxg_gluGetTessProperty_w, 3, 0, 0, H_gluGetTessProperty, pl_ttit); #endif gl_define_procedure(gluLoadSamplingMatrices, gxg_gluLoadSamplingMatrices_w, 4, 0, 0, H_gluLoadSamplingMatrices, pl_t); gl_define_procedure(gluLookAt, gxg_gluLookAt_w, 0, 0, 1, H_gluLookAt, pl_tr); gl_define_procedure(gluNewNurbsRenderer, gxg_gluNewNurbsRenderer_w, 0, 0, 0, H_gluNewNurbsRenderer, pl_t); gl_define_procedure(gluNewQuadric, gxg_gluNewQuadric_w, 0, 0, 0, H_gluNewQuadric, pl_t); #ifdef GLU_VERSION_1_2 gl_define_procedure(gluNewTess, gxg_gluNewTess_w, 0, 0, 0, H_gluNewTess, pl_t); #endif #ifdef GLU_VERSION_1_2 gl_define_procedure(gluNextContour, gxg_gluNextContour_w, 2, 0, 0, H_gluNextContour, pl_tti); #endif gl_define_procedure(gluNurbsCallback, gxg_gluNurbsCallback_w, 3, 0, 0, H_gluNurbsCallback, pl_ttit); gl_define_procedure(gluNurbsCallbackData, gxg_gluNurbsCallbackData_w, 2, 0, 0, H_gluNurbsCallbackData, pl_t); gl_define_procedure(gluNurbsCurve, gxg_gluNurbsCurve_w, 7, 0, 0, H_gluNurbsCurve, pl_ttititi); gl_define_procedure(gluNurbsProperty, gxg_gluNurbsProperty_w, 3, 0, 0, H_gluNurbsProperty, pl_ttir); gl_define_procedure(gluNurbsSurface, gxg_gluNurbsSurface_w, 0, 0, 1, H_gluNurbsSurface, pl_ttititiiti); gl_define_procedure(gluOrtho2D, gxg_gluOrtho2D_w, 4, 0, 0, H_gluOrtho2D, pl_tr); gl_define_procedure(gluPartialDisk, gxg_gluPartialDisk_w, 7, 0, 0, H_gluPartialDisk, pl_ttrriir); gl_define_procedure(gluPerspective, gxg_gluPerspective_w, 4, 0, 0, H_gluPerspective, pl_tr); gl_define_procedure(gluPickMatrix, gxg_gluPickMatrix_w, 5, 0, 0, H_gluPickMatrix, pl_trrrrt); gl_define_procedure(gluProject, gxg_gluProject_w, 0, 0, 1, H_gluProject, pl_irrrt); gl_define_procedure(gluPwlCurve, gxg_gluPwlCurve_w, 5, 0, 0, H_gluPwlCurve, pl_ttiti); gl_define_procedure(gluQuadricCallback, gxg_gluQuadricCallback_w, 3, 0, 0, H_gluQuadricCallback, pl_ttit); gl_define_procedure(gluQuadricDrawStyle, gxg_gluQuadricDrawStyle_w, 2, 0, 0, H_gluQuadricDrawStyle, pl_tti); gl_define_procedure(gluQuadricNormals, gxg_gluQuadricNormals_w, 2, 0, 0, H_gluQuadricNormals, pl_tti); gl_define_procedure(gluQuadricOrientation, gxg_gluQuadricOrientation_w, 2, 0, 0, H_gluQuadricOrientation, pl_tti); gl_define_procedure(gluQuadricTexture, gxg_gluQuadricTexture_w, 2, 0, 0, H_gluQuadricTexture, pl_ttb); gl_define_procedure(gluScaleImage, gxg_gluScaleImage_w, 0, 0, 1, H_gluScaleImage, pl_iiiiitiiit); gl_define_procedure(gluSphere, gxg_gluSphere_w, 4, 0, 0, H_gluSphere, pl_ttri); #ifdef GLU_VERSION_1_2 gl_define_procedure(gluTessBeginContour, gxg_gluTessBeginContour_w, 1, 0, 0, H_gluTessBeginContour, pl_t); #endif #ifdef GLU_VERSION_1_2 gl_define_procedure(gluTessBeginPolygon, gxg_gluTessBeginPolygon_w, 2, 0, 0, H_gluTessBeginPolygon, pl_t); #endif gl_define_procedure(gluTessCallback, gxg_gluTessCallback_w, 3, 0, 0, H_gluTessCallback, pl_ttit); #ifdef GLU_VERSION_1_2 gl_define_procedure(gluTessEndContour, gxg_gluTessEndContour_w, 1, 0, 0, H_gluTessEndContour, pl_t); #endif #ifdef GLU_VERSION_1_2 gl_define_procedure(gluTessEndPolygon, gxg_gluTessEndPolygon_w, 1, 0, 0, H_gluTessEndPolygon, pl_t); #endif #ifdef GLU_VERSION_1_2 gl_define_procedure(gluTessNormal, gxg_gluTessNormal_w, 4, 0, 0, H_gluTessNormal, pl_ttr); #endif #ifdef GLU_VERSION_1_2 gl_define_procedure(gluTessProperty, gxg_gluTessProperty_w, 3, 0, 0, H_gluTessProperty, pl_ttir); #endif #ifdef GLU_VERSION_1_2 gl_define_procedure(gluTessVertex, gxg_gluTessVertex_w, 3, 0, 0, H_gluTessVertex, pl_t); #endif gl_define_procedure(gluUnProject, gxg_gluUnProject_w, 0, 0, 1, H_gluUnProject, pl_irrrt); gl_define_procedure(gluUnProject4, gxg_gluUnProject4_w, 0, 0, 1, H_gluUnProject4, pl_irrrrtttrrt); #endif } /* ---------------------------------------- constants ---------------------------------------- */ static void define_integers(void) { #define DEFINE_INTEGER(Name) Xen_define(XL_PRE #Name XL_POST, C_int_to_Xen_integer(Name)) #if USE_MOTIF DEFINE_INTEGER(GLX_USE_GL); DEFINE_INTEGER(GLX_BUFFER_SIZE); DEFINE_INTEGER(GLX_LEVEL); DEFINE_INTEGER(GLX_RGBA); DEFINE_INTEGER(GLX_DOUBLEBUFFER); DEFINE_INTEGER(GLX_STEREO); DEFINE_INTEGER(GLX_AUX_BUFFERS); DEFINE_INTEGER(GLX_RED_SIZE); DEFINE_INTEGER(GLX_GREEN_SIZE); DEFINE_INTEGER(GLX_BLUE_SIZE); DEFINE_INTEGER(GLX_ALPHA_SIZE); DEFINE_INTEGER(GLX_DEPTH_SIZE); DEFINE_INTEGER(GLX_STENCIL_SIZE); DEFINE_INTEGER(GLX_ACCUM_RED_SIZE); DEFINE_INTEGER(GLX_ACCUM_GREEN_SIZE); DEFINE_INTEGER(GLX_ACCUM_BLUE_SIZE); DEFINE_INTEGER(GLX_ACCUM_ALPHA_SIZE); DEFINE_INTEGER(GLX_BAD_SCREEN); DEFINE_INTEGER(GLX_BAD_ATTRIBUTE); DEFINE_INTEGER(GLX_NO_EXTENSION); DEFINE_INTEGER(GLX_BAD_VISUAL); DEFINE_INTEGER(GLX_BAD_CONTEXT); DEFINE_INTEGER(GLX_BAD_VALUE); DEFINE_INTEGER(GLX_BAD_ENUM); DEFINE_INTEGER(GLX_VENDOR); DEFINE_INTEGER(GLX_VERSION); DEFINE_INTEGER(GLX_EXTENSIONS); #endif DEFINE_INTEGER(GL_FALSE); DEFINE_INTEGER(GL_TRUE); DEFINE_INTEGER(GL_BYTE); DEFINE_INTEGER(GL_UNSIGNED_BYTE); DEFINE_INTEGER(GL_SHORT); DEFINE_INTEGER(GL_UNSIGNED_SHORT); DEFINE_INTEGER(GL_INT); DEFINE_INTEGER(GL_UNSIGNED_INT); DEFINE_INTEGER(GL_FLOAT); DEFINE_INTEGER(GL_DOUBLE); DEFINE_INTEGER(GL_2_BYTES); DEFINE_INTEGER(GL_3_BYTES); DEFINE_INTEGER(GL_4_BYTES); DEFINE_INTEGER(GL_POINTS); DEFINE_INTEGER(GL_LINES); DEFINE_INTEGER(GL_LINE_LOOP); DEFINE_INTEGER(GL_LINE_STRIP); DEFINE_INTEGER(GL_TRIANGLES); DEFINE_INTEGER(GL_TRIANGLE_STRIP); DEFINE_INTEGER(GL_TRIANGLE_FAN); DEFINE_INTEGER(GL_QUADS); DEFINE_INTEGER(GL_QUAD_STRIP); DEFINE_INTEGER(GL_POLYGON); DEFINE_INTEGER(GL_VERTEX_ARRAY); DEFINE_INTEGER(GL_NORMAL_ARRAY); DEFINE_INTEGER(GL_COLOR_ARRAY); DEFINE_INTEGER(GL_INDEX_ARRAY); DEFINE_INTEGER(GL_TEXTURE_COORD_ARRAY); DEFINE_INTEGER(GL_EDGE_FLAG_ARRAY); DEFINE_INTEGER(GL_VERTEX_ARRAY_SIZE); DEFINE_INTEGER(GL_VERTEX_ARRAY_TYPE); DEFINE_INTEGER(GL_VERTEX_ARRAY_STRIDE); DEFINE_INTEGER(GL_NORMAL_ARRAY_TYPE); DEFINE_INTEGER(GL_NORMAL_ARRAY_STRIDE); DEFINE_INTEGER(GL_COLOR_ARRAY_SIZE); DEFINE_INTEGER(GL_COLOR_ARRAY_TYPE); DEFINE_INTEGER(GL_COLOR_ARRAY_STRIDE); DEFINE_INTEGER(GL_INDEX_ARRAY_TYPE); DEFINE_INTEGER(GL_INDEX_ARRAY_STRIDE); DEFINE_INTEGER(GL_TEXTURE_COORD_ARRAY_SIZE); DEFINE_INTEGER(GL_TEXTURE_COORD_ARRAY_TYPE); DEFINE_INTEGER(GL_TEXTURE_COORD_ARRAY_STRIDE); DEFINE_INTEGER(GL_EDGE_FLAG_ARRAY_STRIDE); DEFINE_INTEGER(GL_VERTEX_ARRAY_POINTER); DEFINE_INTEGER(GL_NORMAL_ARRAY_POINTER); DEFINE_INTEGER(GL_COLOR_ARRAY_POINTER); DEFINE_INTEGER(GL_INDEX_ARRAY_POINTER); DEFINE_INTEGER(GL_TEXTURE_COORD_ARRAY_POINTER); DEFINE_INTEGER(GL_EDGE_FLAG_ARRAY_POINTER); DEFINE_INTEGER(GL_V2F); DEFINE_INTEGER(GL_V3F); DEFINE_INTEGER(GL_C4UB_V2F); DEFINE_INTEGER(GL_C4UB_V3F); DEFINE_INTEGER(GL_C3F_V3F); DEFINE_INTEGER(GL_N3F_V3F); DEFINE_INTEGER(GL_C4F_N3F_V3F); DEFINE_INTEGER(GL_T2F_V3F); DEFINE_INTEGER(GL_T4F_V4F); DEFINE_INTEGER(GL_T2F_C4UB_V3F); DEFINE_INTEGER(GL_T2F_C3F_V3F); DEFINE_INTEGER(GL_T2F_N3F_V3F); DEFINE_INTEGER(GL_T2F_C4F_N3F_V3F); DEFINE_INTEGER(GL_T4F_C4F_N3F_V4F); DEFINE_INTEGER(GL_MATRIX_MODE); DEFINE_INTEGER(GL_MODELVIEW); DEFINE_INTEGER(GL_PROJECTION); DEFINE_INTEGER(GL_TEXTURE); DEFINE_INTEGER(GL_POINT_SMOOTH); DEFINE_INTEGER(GL_POINT_SIZE); DEFINE_INTEGER(GL_POINT_SIZE_GRANULARITY); DEFINE_INTEGER(GL_POINT_SIZE_RANGE); DEFINE_INTEGER(GL_LINE_SMOOTH); DEFINE_INTEGER(GL_LINE_STIPPLE); DEFINE_INTEGER(GL_LINE_STIPPLE_PATTERN); DEFINE_INTEGER(GL_LINE_STIPPLE_REPEAT); DEFINE_INTEGER(GL_LINE_WIDTH); DEFINE_INTEGER(GL_LINE_WIDTH_GRANULARITY); DEFINE_INTEGER(GL_LINE_WIDTH_RANGE); DEFINE_INTEGER(GL_POINT); DEFINE_INTEGER(GL_LINE); DEFINE_INTEGER(GL_FILL); DEFINE_INTEGER(GL_CW); DEFINE_INTEGER(GL_CCW); DEFINE_INTEGER(GL_FRONT); DEFINE_INTEGER(GL_BACK); DEFINE_INTEGER(GL_POLYGON_MODE); DEFINE_INTEGER(GL_POLYGON_SMOOTH); DEFINE_INTEGER(GL_POLYGON_STIPPLE); DEFINE_INTEGER(GL_EDGE_FLAG); DEFINE_INTEGER(GL_CULL_FACE); DEFINE_INTEGER(GL_CULL_FACE_MODE); DEFINE_INTEGER(GL_FRONT_FACE); DEFINE_INTEGER(GL_POLYGON_OFFSET_FACTOR); DEFINE_INTEGER(GL_POLYGON_OFFSET_UNITS); DEFINE_INTEGER(GL_POLYGON_OFFSET_POINT); DEFINE_INTEGER(GL_POLYGON_OFFSET_LINE); DEFINE_INTEGER(GL_POLYGON_OFFSET_FILL); DEFINE_INTEGER(GL_COMPILE); DEFINE_INTEGER(GL_COMPILE_AND_EXECUTE); DEFINE_INTEGER(GL_LIST_BASE); DEFINE_INTEGER(GL_LIST_INDEX); DEFINE_INTEGER(GL_LIST_MODE); DEFINE_INTEGER(GL_NEVER); DEFINE_INTEGER(GL_LESS); DEFINE_INTEGER(GL_EQUAL); DEFINE_INTEGER(GL_LEQUAL); DEFINE_INTEGER(GL_GREATER); DEFINE_INTEGER(GL_NOTEQUAL); DEFINE_INTEGER(GL_GEQUAL); DEFINE_INTEGER(GL_ALWAYS); DEFINE_INTEGER(GL_DEPTH_TEST); DEFINE_INTEGER(GL_DEPTH_BITS); DEFINE_INTEGER(GL_DEPTH_CLEAR_VALUE); DEFINE_INTEGER(GL_DEPTH_FUNC); DEFINE_INTEGER(GL_DEPTH_RANGE); DEFINE_INTEGER(GL_DEPTH_WRITEMASK); DEFINE_INTEGER(GL_DEPTH_COMPONENT); DEFINE_INTEGER(GL_LIGHTING); DEFINE_INTEGER(GL_LIGHT0); DEFINE_INTEGER(GL_LIGHT1); DEFINE_INTEGER(GL_LIGHT2); DEFINE_INTEGER(GL_LIGHT3); DEFINE_INTEGER(GL_LIGHT4); DEFINE_INTEGER(GL_LIGHT5); DEFINE_INTEGER(GL_LIGHT6); DEFINE_INTEGER(GL_LIGHT7); DEFINE_INTEGER(GL_SPOT_EXPONENT); DEFINE_INTEGER(GL_SPOT_CUTOFF); DEFINE_INTEGER(GL_CONSTANT_ATTENUATION); DEFINE_INTEGER(GL_LINEAR_ATTENUATION); DEFINE_INTEGER(GL_QUADRATIC_ATTENUATION); DEFINE_INTEGER(GL_AMBIENT); DEFINE_INTEGER(GL_DIFFUSE); DEFINE_INTEGER(GL_SPECULAR); DEFINE_INTEGER(GL_SHININESS); DEFINE_INTEGER(GL_EMISSION); DEFINE_INTEGER(GL_POSITION); DEFINE_INTEGER(GL_SPOT_DIRECTION); DEFINE_INTEGER(GL_AMBIENT_AND_DIFFUSE); DEFINE_INTEGER(GL_COLOR_INDEXES); DEFINE_INTEGER(GL_LIGHT_MODEL_TWO_SIDE); DEFINE_INTEGER(GL_LIGHT_MODEL_LOCAL_VIEWER); DEFINE_INTEGER(GL_LIGHT_MODEL_AMBIENT); DEFINE_INTEGER(GL_FRONT_AND_BACK); DEFINE_INTEGER(GL_SHADE_MODEL); DEFINE_INTEGER(GL_FLAT); DEFINE_INTEGER(GL_SMOOTH); DEFINE_INTEGER(GL_COLOR_MATERIAL); DEFINE_INTEGER(GL_COLOR_MATERIAL_FACE); DEFINE_INTEGER(GL_COLOR_MATERIAL_PARAMETER); DEFINE_INTEGER(GL_NORMALIZE); DEFINE_INTEGER(GL_CLIP_PLANE0); DEFINE_INTEGER(GL_CLIP_PLANE1); DEFINE_INTEGER(GL_CLIP_PLANE2); DEFINE_INTEGER(GL_CLIP_PLANE3); DEFINE_INTEGER(GL_CLIP_PLANE4); DEFINE_INTEGER(GL_CLIP_PLANE5); DEFINE_INTEGER(GL_ACCUM_RED_BITS); DEFINE_INTEGER(GL_ACCUM_GREEN_BITS); DEFINE_INTEGER(GL_ACCUM_BLUE_BITS); DEFINE_INTEGER(GL_ACCUM_ALPHA_BITS); DEFINE_INTEGER(GL_ACCUM_CLEAR_VALUE); DEFINE_INTEGER(GL_ACCUM); DEFINE_INTEGER(GL_ADD); DEFINE_INTEGER(GL_LOAD); DEFINE_INTEGER(GL_MULT); DEFINE_INTEGER(GL_RETURN); DEFINE_INTEGER(GL_ALPHA_TEST); DEFINE_INTEGER(GL_ALPHA_TEST_REF); DEFINE_INTEGER(GL_ALPHA_TEST_FUNC); DEFINE_INTEGER(GL_BLEND); DEFINE_INTEGER(GL_BLEND_SRC); DEFINE_INTEGER(GL_BLEND_DST); DEFINE_INTEGER(GL_ZERO); DEFINE_INTEGER(GL_ONE); DEFINE_INTEGER(GL_SRC_COLOR); DEFINE_INTEGER(GL_ONE_MINUS_SRC_COLOR); DEFINE_INTEGER(GL_DST_COLOR); DEFINE_INTEGER(GL_ONE_MINUS_DST_COLOR); DEFINE_INTEGER(GL_SRC_ALPHA); DEFINE_INTEGER(GL_ONE_MINUS_SRC_ALPHA); DEFINE_INTEGER(GL_DST_ALPHA); DEFINE_INTEGER(GL_ONE_MINUS_DST_ALPHA); DEFINE_INTEGER(GL_SRC_ALPHA_SATURATE); DEFINE_INTEGER(GL_CONSTANT_COLOR); DEFINE_INTEGER(GL_ONE_MINUS_CONSTANT_COLOR); DEFINE_INTEGER(GL_CONSTANT_ALPHA); DEFINE_INTEGER(GL_ONE_MINUS_CONSTANT_ALPHA); DEFINE_INTEGER(GL_FEEDBACK); DEFINE_INTEGER(GL_RENDER); DEFINE_INTEGER(GL_SELECT); DEFINE_INTEGER(GL_2D); DEFINE_INTEGER(GL_3D); DEFINE_INTEGER(GL_3D_COLOR); DEFINE_INTEGER(GL_3D_COLOR_TEXTURE); DEFINE_INTEGER(GL_4D_COLOR_TEXTURE); DEFINE_INTEGER(GL_POINT_TOKEN); DEFINE_INTEGER(GL_LINE_TOKEN); DEFINE_INTEGER(GL_LINE_RESET_TOKEN); DEFINE_INTEGER(GL_POLYGON_TOKEN); DEFINE_INTEGER(GL_BITMAP_TOKEN); DEFINE_INTEGER(GL_DRAW_PIXEL_TOKEN); DEFINE_INTEGER(GL_COPY_PIXEL_TOKEN); DEFINE_INTEGER(GL_PASS_THROUGH_TOKEN); DEFINE_INTEGER(GL_FEEDBACK_BUFFER_POINTER); DEFINE_INTEGER(GL_FEEDBACK_BUFFER_SIZE); DEFINE_INTEGER(GL_FEEDBACK_BUFFER_TYPE); DEFINE_INTEGER(GL_SELECTION_BUFFER_POINTER); DEFINE_INTEGER(GL_SELECTION_BUFFER_SIZE); DEFINE_INTEGER(GL_FOG); DEFINE_INTEGER(GL_FOG_MODE); DEFINE_INTEGER(GL_FOG_DENSITY); DEFINE_INTEGER(GL_FOG_COLOR); DEFINE_INTEGER(GL_FOG_INDEX); DEFINE_INTEGER(GL_FOG_START); DEFINE_INTEGER(GL_FOG_END); DEFINE_INTEGER(GL_LINEAR); DEFINE_INTEGER(GL_EXP); DEFINE_INTEGER(GL_EXP2); DEFINE_INTEGER(GL_LOGIC_OP); DEFINE_INTEGER(GL_INDEX_LOGIC_OP); DEFINE_INTEGER(GL_COLOR_LOGIC_OP); DEFINE_INTEGER(GL_LOGIC_OP_MODE); DEFINE_INTEGER(GL_CLEAR); DEFINE_INTEGER(GL_SET); DEFINE_INTEGER(GL_COPY); DEFINE_INTEGER(GL_COPY_INVERTED); DEFINE_INTEGER(GL_NOOP); DEFINE_INTEGER(GL_INVERT); DEFINE_INTEGER(GL_AND); DEFINE_INTEGER(GL_NAND); DEFINE_INTEGER(GL_OR); DEFINE_INTEGER(GL_NOR); DEFINE_INTEGER(GL_XOR); DEFINE_INTEGER(GL_EQUIV); DEFINE_INTEGER(GL_AND_REVERSE); DEFINE_INTEGER(GL_AND_INVERTED); DEFINE_INTEGER(GL_OR_REVERSE); DEFINE_INTEGER(GL_OR_INVERTED); DEFINE_INTEGER(GL_STENCIL_TEST); DEFINE_INTEGER(GL_STENCIL_WRITEMASK); DEFINE_INTEGER(GL_STENCIL_BITS); DEFINE_INTEGER(GL_STENCIL_FUNC); DEFINE_INTEGER(GL_STENCIL_VALUE_MASK); DEFINE_INTEGER(GL_STENCIL_REF); DEFINE_INTEGER(GL_STENCIL_FAIL); DEFINE_INTEGER(GL_STENCIL_PASS_DEPTH_PASS); DEFINE_INTEGER(GL_STENCIL_PASS_DEPTH_FAIL); DEFINE_INTEGER(GL_STENCIL_CLEAR_VALUE); DEFINE_INTEGER(GL_STENCIL_INDEX); DEFINE_INTEGER(GL_KEEP); DEFINE_INTEGER(GL_REPLACE); DEFINE_INTEGER(GL_INCR); DEFINE_INTEGER(GL_DECR); DEFINE_INTEGER(GL_NONE); DEFINE_INTEGER(GL_LEFT); DEFINE_INTEGER(GL_RIGHT); DEFINE_INTEGER(GL_FRONT_LEFT); DEFINE_INTEGER(GL_FRONT_RIGHT); DEFINE_INTEGER(GL_BACK_LEFT); DEFINE_INTEGER(GL_BACK_RIGHT); DEFINE_INTEGER(GL_AUX0); DEFINE_INTEGER(GL_AUX1); DEFINE_INTEGER(GL_AUX2); DEFINE_INTEGER(GL_AUX3); DEFINE_INTEGER(GL_COLOR_INDEX); DEFINE_INTEGER(GL_RED); DEFINE_INTEGER(GL_GREEN); DEFINE_INTEGER(GL_BLUE); DEFINE_INTEGER(GL_ALPHA); DEFINE_INTEGER(GL_LUMINANCE); DEFINE_INTEGER(GL_LUMINANCE_ALPHA); DEFINE_INTEGER(GL_ALPHA_BITS); DEFINE_INTEGER(GL_RED_BITS); DEFINE_INTEGER(GL_GREEN_BITS); DEFINE_INTEGER(GL_BLUE_BITS); DEFINE_INTEGER(GL_INDEX_BITS); DEFINE_INTEGER(GL_SUBPIXEL_BITS); DEFINE_INTEGER(GL_AUX_BUFFERS); DEFINE_INTEGER(GL_READ_BUFFER); DEFINE_INTEGER(GL_DRAW_BUFFER); DEFINE_INTEGER(GL_DOUBLEBUFFER); DEFINE_INTEGER(GL_STEREO); DEFINE_INTEGER(GL_BITMAP); DEFINE_INTEGER(GL_COLOR); DEFINE_INTEGER(GL_DEPTH); DEFINE_INTEGER(GL_STENCIL); DEFINE_INTEGER(GL_DITHER); DEFINE_INTEGER(GL_RGB); DEFINE_INTEGER(GL_RGBA); DEFINE_INTEGER(GL_MAX_LIST_NESTING); DEFINE_INTEGER(GL_MAX_ATTRIB_STACK_DEPTH); DEFINE_INTEGER(GL_MAX_MODELVIEW_STACK_DEPTH); DEFINE_INTEGER(GL_MAX_NAME_STACK_DEPTH); DEFINE_INTEGER(GL_MAX_PROJECTION_STACK_DEPTH); DEFINE_INTEGER(GL_MAX_TEXTURE_STACK_DEPTH); DEFINE_INTEGER(GL_MAX_EVAL_ORDER); DEFINE_INTEGER(GL_MAX_LIGHTS); DEFINE_INTEGER(GL_MAX_CLIP_PLANES); DEFINE_INTEGER(GL_MAX_TEXTURE_SIZE); DEFINE_INTEGER(GL_MAX_PIXEL_MAP_TABLE); DEFINE_INTEGER(GL_MAX_VIEWPORT_DIMS); DEFINE_INTEGER(GL_MAX_CLIENT_ATTRIB_STACK_DEPTH); DEFINE_INTEGER(GL_ATTRIB_STACK_DEPTH); DEFINE_INTEGER(GL_CLIENT_ATTRIB_STACK_DEPTH); DEFINE_INTEGER(GL_COLOR_CLEAR_VALUE); DEFINE_INTEGER(GL_COLOR_WRITEMASK); DEFINE_INTEGER(GL_CURRENT_INDEX); DEFINE_INTEGER(GL_CURRENT_COLOR); DEFINE_INTEGER(GL_CURRENT_NORMAL); DEFINE_INTEGER(GL_CURRENT_RASTER_COLOR); DEFINE_INTEGER(GL_CURRENT_RASTER_DISTANCE); DEFINE_INTEGER(GL_CURRENT_RASTER_INDEX); DEFINE_INTEGER(GL_CURRENT_RASTER_POSITION); DEFINE_INTEGER(GL_CURRENT_RASTER_TEXTURE_COORDS); DEFINE_INTEGER(GL_CURRENT_RASTER_POSITION_VALID); DEFINE_INTEGER(GL_CURRENT_TEXTURE_COORDS); DEFINE_INTEGER(GL_INDEX_CLEAR_VALUE); DEFINE_INTEGER(GL_INDEX_MODE); DEFINE_INTEGER(GL_INDEX_WRITEMASK); DEFINE_INTEGER(GL_MODELVIEW_MATRIX); DEFINE_INTEGER(GL_MODELVIEW_STACK_DEPTH); DEFINE_INTEGER(GL_NAME_STACK_DEPTH); DEFINE_INTEGER(GL_PROJECTION_MATRIX); DEFINE_INTEGER(GL_PROJECTION_STACK_DEPTH); DEFINE_INTEGER(GL_RENDER_MODE); DEFINE_INTEGER(GL_RGBA_MODE); DEFINE_INTEGER(GL_TEXTURE_MATRIX); DEFINE_INTEGER(GL_TEXTURE_STACK_DEPTH); DEFINE_INTEGER(GL_VIEWPORT); DEFINE_INTEGER(GL_AUTO_NORMAL); DEFINE_INTEGER(GL_MAP1_COLOR_4); DEFINE_INTEGER(GL_MAP1_GRID_DOMAIN); DEFINE_INTEGER(GL_MAP1_GRID_SEGMENTS); DEFINE_INTEGER(GL_MAP1_INDEX); DEFINE_INTEGER(GL_MAP1_NORMAL); DEFINE_INTEGER(GL_MAP1_TEXTURE_COORD_1); DEFINE_INTEGER(GL_MAP1_TEXTURE_COORD_2); DEFINE_INTEGER(GL_MAP1_TEXTURE_COORD_3); DEFINE_INTEGER(GL_MAP1_TEXTURE_COORD_4); DEFINE_INTEGER(GL_MAP1_VERTEX_3); DEFINE_INTEGER(GL_MAP1_VERTEX_4); DEFINE_INTEGER(GL_MAP2_COLOR_4); DEFINE_INTEGER(GL_MAP2_GRID_DOMAIN); DEFINE_INTEGER(GL_MAP2_GRID_SEGMENTS); DEFINE_INTEGER(GL_MAP2_INDEX); DEFINE_INTEGER(GL_MAP2_NORMAL); DEFINE_INTEGER(GL_MAP2_TEXTURE_COORD_1); DEFINE_INTEGER(GL_MAP2_TEXTURE_COORD_2); DEFINE_INTEGER(GL_MAP2_TEXTURE_COORD_3); DEFINE_INTEGER(GL_MAP2_TEXTURE_COORD_4); DEFINE_INTEGER(GL_MAP2_VERTEX_3); DEFINE_INTEGER(GL_MAP2_VERTEX_4); DEFINE_INTEGER(GL_COEFF); DEFINE_INTEGER(GL_DOMAIN); DEFINE_INTEGER(GL_ORDER); DEFINE_INTEGER(GL_FOG_HINT); DEFINE_INTEGER(GL_LINE_SMOOTH_HINT); DEFINE_INTEGER(GL_PERSPECTIVE_CORRECTION_HINT); DEFINE_INTEGER(GL_POINT_SMOOTH_HINT); DEFINE_INTEGER(GL_POLYGON_SMOOTH_HINT); DEFINE_INTEGER(GL_DONT_CARE); DEFINE_INTEGER(GL_FASTEST); DEFINE_INTEGER(GL_NICEST); DEFINE_INTEGER(GL_SCISSOR_TEST); DEFINE_INTEGER(GL_SCISSOR_BOX); DEFINE_INTEGER(GL_MAP_COLOR); DEFINE_INTEGER(GL_MAP_STENCIL); DEFINE_INTEGER(GL_INDEX_SHIFT); DEFINE_INTEGER(GL_INDEX_OFFSET); DEFINE_INTEGER(GL_RED_SCALE); DEFINE_INTEGER(GL_RED_BIAS); DEFINE_INTEGER(GL_GREEN_SCALE); DEFINE_INTEGER(GL_GREEN_BIAS); DEFINE_INTEGER(GL_BLUE_SCALE); DEFINE_INTEGER(GL_BLUE_BIAS); DEFINE_INTEGER(GL_ALPHA_SCALE); DEFINE_INTEGER(GL_ALPHA_BIAS); DEFINE_INTEGER(GL_DEPTH_SCALE); DEFINE_INTEGER(GL_DEPTH_BIAS); DEFINE_INTEGER(GL_PIXEL_MAP_S_TO_S_SIZE); DEFINE_INTEGER(GL_PIXEL_MAP_I_TO_I_SIZE); DEFINE_INTEGER(GL_PIXEL_MAP_I_TO_R_SIZE); DEFINE_INTEGER(GL_PIXEL_MAP_I_TO_G_SIZE); DEFINE_INTEGER(GL_PIXEL_MAP_I_TO_B_SIZE); DEFINE_INTEGER(GL_PIXEL_MAP_I_TO_A_SIZE); DEFINE_INTEGER(GL_PIXEL_MAP_R_TO_R_SIZE); DEFINE_INTEGER(GL_PIXEL_MAP_G_TO_G_SIZE); DEFINE_INTEGER(GL_PIXEL_MAP_B_TO_B_SIZE); DEFINE_INTEGER(GL_PIXEL_MAP_A_TO_A_SIZE); DEFINE_INTEGER(GL_PIXEL_MAP_S_TO_S); DEFINE_INTEGER(GL_PIXEL_MAP_I_TO_I); DEFINE_INTEGER(GL_PIXEL_MAP_I_TO_R); DEFINE_INTEGER(GL_PIXEL_MAP_I_TO_G); DEFINE_INTEGER(GL_PIXEL_MAP_I_TO_B); DEFINE_INTEGER(GL_PIXEL_MAP_I_TO_A); DEFINE_INTEGER(GL_PIXEL_MAP_R_TO_R); DEFINE_INTEGER(GL_PIXEL_MAP_G_TO_G); DEFINE_INTEGER(GL_PIXEL_MAP_B_TO_B); DEFINE_INTEGER(GL_PIXEL_MAP_A_TO_A); DEFINE_INTEGER(GL_PACK_ALIGNMENT); DEFINE_INTEGER(GL_PACK_LSB_FIRST); DEFINE_INTEGER(GL_PACK_ROW_LENGTH); DEFINE_INTEGER(GL_PACK_SKIP_PIXELS); DEFINE_INTEGER(GL_PACK_SKIP_ROWS); DEFINE_INTEGER(GL_PACK_SWAP_BYTES); DEFINE_INTEGER(GL_UNPACK_ALIGNMENT); DEFINE_INTEGER(GL_UNPACK_LSB_FIRST); DEFINE_INTEGER(GL_UNPACK_ROW_LENGTH); DEFINE_INTEGER(GL_UNPACK_SKIP_PIXELS); DEFINE_INTEGER(GL_UNPACK_SKIP_ROWS); DEFINE_INTEGER(GL_UNPACK_SWAP_BYTES); DEFINE_INTEGER(GL_ZOOM_X); DEFINE_INTEGER(GL_ZOOM_Y); DEFINE_INTEGER(GL_TEXTURE_ENV); DEFINE_INTEGER(GL_TEXTURE_ENV_MODE); DEFINE_INTEGER(GL_TEXTURE_1D); DEFINE_INTEGER(GL_TEXTURE_2D); DEFINE_INTEGER(GL_TEXTURE_WRAP_S); DEFINE_INTEGER(GL_TEXTURE_WRAP_T); DEFINE_INTEGER(GL_TEXTURE_MAG_FILTER); DEFINE_INTEGER(GL_TEXTURE_MIN_FILTER); DEFINE_INTEGER(GL_TEXTURE_ENV_COLOR); DEFINE_INTEGER(GL_TEXTURE_GEN_S); DEFINE_INTEGER(GL_TEXTURE_GEN_T); DEFINE_INTEGER(GL_TEXTURE_GEN_MODE); DEFINE_INTEGER(GL_TEXTURE_BORDER_COLOR); DEFINE_INTEGER(GL_TEXTURE_WIDTH); DEFINE_INTEGER(GL_TEXTURE_HEIGHT); DEFINE_INTEGER(GL_TEXTURE_BORDER); DEFINE_INTEGER(GL_TEXTURE_COMPONENTS); DEFINE_INTEGER(GL_TEXTURE_RED_SIZE); DEFINE_INTEGER(GL_TEXTURE_GREEN_SIZE); DEFINE_INTEGER(GL_TEXTURE_BLUE_SIZE); DEFINE_INTEGER(GL_TEXTURE_ALPHA_SIZE); DEFINE_INTEGER(GL_TEXTURE_LUMINANCE_SIZE); DEFINE_INTEGER(GL_TEXTURE_INTENSITY_SIZE); DEFINE_INTEGER(GL_NEAREST_MIPMAP_NEAREST); DEFINE_INTEGER(GL_NEAREST_MIPMAP_LINEAR); DEFINE_INTEGER(GL_LINEAR_MIPMAP_NEAREST); DEFINE_INTEGER(GL_LINEAR_MIPMAP_LINEAR); DEFINE_INTEGER(GL_OBJECT_LINEAR); DEFINE_INTEGER(GL_OBJECT_PLANE); DEFINE_INTEGER(GL_EYE_LINEAR); DEFINE_INTEGER(GL_EYE_PLANE); DEFINE_INTEGER(GL_SPHERE_MAP); DEFINE_INTEGER(GL_DECAL); DEFINE_INTEGER(GL_MODULATE); DEFINE_INTEGER(GL_NEAREST); DEFINE_INTEGER(GL_REPEAT); DEFINE_INTEGER(GL_CLAMP); DEFINE_INTEGER(GL_S); DEFINE_INTEGER(GL_T); DEFINE_INTEGER(GL_R); DEFINE_INTEGER(GL_Q); DEFINE_INTEGER(GL_TEXTURE_GEN_R); DEFINE_INTEGER(GL_TEXTURE_GEN_Q); DEFINE_INTEGER(GL_PROXY_TEXTURE_1D); DEFINE_INTEGER(GL_PROXY_TEXTURE_2D); DEFINE_INTEGER(GL_TEXTURE_PRIORITY); DEFINE_INTEGER(GL_TEXTURE_RESIDENT); DEFINE_INTEGER(GL_TEXTURE_BINDING_1D); DEFINE_INTEGER(GL_TEXTURE_BINDING_2D); DEFINE_INTEGER(GL_TEXTURE_INTERNAL_FORMAT); DEFINE_INTEGER(GL_PACK_SKIP_IMAGES); DEFINE_INTEGER(GL_PACK_IMAGE_HEIGHT); DEFINE_INTEGER(GL_UNPACK_SKIP_IMAGES); DEFINE_INTEGER(GL_UNPACK_IMAGE_HEIGHT); DEFINE_INTEGER(GL_TEXTURE_3D); DEFINE_INTEGER(GL_PROXY_TEXTURE_3D); DEFINE_INTEGER(GL_TEXTURE_DEPTH); DEFINE_INTEGER(GL_TEXTURE_WRAP_R); DEFINE_INTEGER(GL_MAX_3D_TEXTURE_SIZE); DEFINE_INTEGER(GL_TEXTURE_BINDING_3D); DEFINE_INTEGER(GL_ALPHA4); DEFINE_INTEGER(GL_ALPHA8); DEFINE_INTEGER(GL_ALPHA12); DEFINE_INTEGER(GL_ALPHA16); DEFINE_INTEGER(GL_LUMINANCE4); DEFINE_INTEGER(GL_LUMINANCE8); DEFINE_INTEGER(GL_LUMINANCE12); DEFINE_INTEGER(GL_LUMINANCE16); DEFINE_INTEGER(GL_LUMINANCE4_ALPHA4); DEFINE_INTEGER(GL_LUMINANCE6_ALPHA2); DEFINE_INTEGER(GL_LUMINANCE8_ALPHA8); DEFINE_INTEGER(GL_LUMINANCE12_ALPHA4); DEFINE_INTEGER(GL_LUMINANCE12_ALPHA12); DEFINE_INTEGER(GL_LUMINANCE16_ALPHA16); DEFINE_INTEGER(GL_INTENSITY); DEFINE_INTEGER(GL_INTENSITY4); DEFINE_INTEGER(GL_INTENSITY8); DEFINE_INTEGER(GL_INTENSITY12); DEFINE_INTEGER(GL_INTENSITY16); DEFINE_INTEGER(GL_R3_G3_B2); DEFINE_INTEGER(GL_RGB4); DEFINE_INTEGER(GL_RGB5); DEFINE_INTEGER(GL_RGB8); DEFINE_INTEGER(GL_RGB10); DEFINE_INTEGER(GL_RGB12); DEFINE_INTEGER(GL_RGB16); DEFINE_INTEGER(GL_RGBA2); DEFINE_INTEGER(GL_RGBA4); DEFINE_INTEGER(GL_RGB5_A1); DEFINE_INTEGER(GL_RGBA8); DEFINE_INTEGER(GL_RGB10_A2); DEFINE_INTEGER(GL_RGBA12); DEFINE_INTEGER(GL_RGBA16); DEFINE_INTEGER(GL_VENDOR); DEFINE_INTEGER(GL_RENDERER); DEFINE_INTEGER(GL_VERSION); DEFINE_INTEGER(GL_EXTENSIONS); DEFINE_INTEGER(GL_NO_ERROR); DEFINE_INTEGER(GL_INVALID_VALUE); DEFINE_INTEGER(GL_INVALID_ENUM); DEFINE_INTEGER(GL_INVALID_OPERATION); DEFINE_INTEGER(GL_STACK_OVERFLOW); DEFINE_INTEGER(GL_STACK_UNDERFLOW); DEFINE_INTEGER(GL_OUT_OF_MEMORY); DEFINE_INTEGER(GL_RESCALE_NORMAL); DEFINE_INTEGER(GL_CLAMP_TO_EDGE); DEFINE_INTEGER(GL_MAX_ELEMENTS_VERTICES); DEFINE_INTEGER(GL_MAX_ELEMENTS_INDICES); DEFINE_INTEGER(GL_BGR); DEFINE_INTEGER(GL_BGRA); DEFINE_INTEGER(GL_UNSIGNED_BYTE_3_3_2); DEFINE_INTEGER(GL_UNSIGNED_BYTE_2_3_3_REV); DEFINE_INTEGER(GL_UNSIGNED_SHORT_5_6_5); DEFINE_INTEGER(GL_UNSIGNED_SHORT_5_6_5_REV); DEFINE_INTEGER(GL_UNSIGNED_SHORT_4_4_4_4); DEFINE_INTEGER(GL_UNSIGNED_SHORT_4_4_4_4_REV); DEFINE_INTEGER(GL_UNSIGNED_SHORT_5_5_5_1); DEFINE_INTEGER(GL_UNSIGNED_SHORT_1_5_5_5_REV); DEFINE_INTEGER(GL_UNSIGNED_INT_8_8_8_8); DEFINE_INTEGER(GL_UNSIGNED_INT_8_8_8_8_REV); DEFINE_INTEGER(GL_UNSIGNED_INT_10_10_10_2); DEFINE_INTEGER(GL_UNSIGNED_INT_2_10_10_10_REV); DEFINE_INTEGER(GL_LIGHT_MODEL_COLOR_CONTROL); DEFINE_INTEGER(GL_SINGLE_COLOR); DEFINE_INTEGER(GL_SEPARATE_SPECULAR_COLOR); DEFINE_INTEGER(GL_TEXTURE_MIN_LOD); DEFINE_INTEGER(GL_TEXTURE_MAX_LOD); DEFINE_INTEGER(GL_TEXTURE_BASE_LEVEL); DEFINE_INTEGER(GL_TEXTURE_MAX_LEVEL); DEFINE_INTEGER(GL_COLOR_TABLE); DEFINE_INTEGER(GL_POST_CONVOLUTION_COLOR_TABLE); DEFINE_INTEGER(GL_POST_COLOR_MATRIX_COLOR_TABLE); DEFINE_INTEGER(GL_PROXY_COLOR_TABLE); DEFINE_INTEGER(GL_PROXY_POST_CONVOLUTION_COLOR_TABLE); DEFINE_INTEGER(GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE); DEFINE_INTEGER(GL_COLOR_TABLE_SCALE); DEFINE_INTEGER(GL_COLOR_TABLE_BIAS); DEFINE_INTEGER(GL_COLOR_TABLE_FORMAT); DEFINE_INTEGER(GL_COLOR_TABLE_WIDTH); DEFINE_INTEGER(GL_COLOR_TABLE_RED_SIZE); DEFINE_INTEGER(GL_COLOR_TABLE_GREEN_SIZE); DEFINE_INTEGER(GL_COLOR_TABLE_BLUE_SIZE); DEFINE_INTEGER(GL_COLOR_TABLE_ALPHA_SIZE); DEFINE_INTEGER(GL_COLOR_TABLE_LUMINANCE_SIZE); DEFINE_INTEGER(GL_COLOR_TABLE_INTENSITY_SIZE); DEFINE_INTEGER(GL_CONVOLUTION_1D); DEFINE_INTEGER(GL_CONVOLUTION_2D); DEFINE_INTEGER(GL_SEPARABLE_2D); DEFINE_INTEGER(GL_CONVOLUTION_BORDER_MODE); DEFINE_INTEGER(GL_CONVOLUTION_FILTER_SCALE); DEFINE_INTEGER(GL_CONVOLUTION_FILTER_BIAS); DEFINE_INTEGER(GL_REDUCE); DEFINE_INTEGER(GL_CONVOLUTION_FORMAT); DEFINE_INTEGER(GL_CONVOLUTION_WIDTH); DEFINE_INTEGER(GL_CONVOLUTION_HEIGHT); DEFINE_INTEGER(GL_MAX_CONVOLUTION_WIDTH); DEFINE_INTEGER(GL_MAX_CONVOLUTION_HEIGHT); DEFINE_INTEGER(GL_POST_CONVOLUTION_RED_SCALE); DEFINE_INTEGER(GL_POST_CONVOLUTION_GREEN_SCALE); DEFINE_INTEGER(GL_POST_CONVOLUTION_BLUE_SCALE); DEFINE_INTEGER(GL_POST_CONVOLUTION_ALPHA_SCALE); DEFINE_INTEGER(GL_POST_CONVOLUTION_RED_BIAS); DEFINE_INTEGER(GL_POST_CONVOLUTION_GREEN_BIAS); DEFINE_INTEGER(GL_POST_CONVOLUTION_BLUE_BIAS); DEFINE_INTEGER(GL_POST_CONVOLUTION_ALPHA_BIAS); DEFINE_INTEGER(GL_CONSTANT_BORDER); DEFINE_INTEGER(GL_REPLICATE_BORDER); DEFINE_INTEGER(GL_CONVOLUTION_BORDER_COLOR); DEFINE_INTEGER(GL_COLOR_MATRIX); DEFINE_INTEGER(GL_COLOR_MATRIX_STACK_DEPTH); DEFINE_INTEGER(GL_MAX_COLOR_MATRIX_STACK_DEPTH); DEFINE_INTEGER(GL_POST_COLOR_MATRIX_RED_SCALE); DEFINE_INTEGER(GL_POST_COLOR_MATRIX_GREEN_SCALE); DEFINE_INTEGER(GL_POST_COLOR_MATRIX_BLUE_SCALE); DEFINE_INTEGER(GL_POST_COLOR_MATRIX_ALPHA_SCALE); DEFINE_INTEGER(GL_POST_COLOR_MATRIX_RED_BIAS); DEFINE_INTEGER(GL_POST_COLOR_MATRIX_GREEN_BIAS); DEFINE_INTEGER(GL_POST_COLOR_MATRIX_BLUE_BIAS); DEFINE_INTEGER(GL_POST_COLOR_MATRIX_ALPHA_BIAS); DEFINE_INTEGER(GL_HISTOGRAM); DEFINE_INTEGER(GL_PROXY_HISTOGRAM); DEFINE_INTEGER(GL_HISTOGRAM_WIDTH); DEFINE_INTEGER(GL_HISTOGRAM_FORMAT); DEFINE_INTEGER(GL_HISTOGRAM_RED_SIZE); DEFINE_INTEGER(GL_HISTOGRAM_GREEN_SIZE); DEFINE_INTEGER(GL_HISTOGRAM_BLUE_SIZE); DEFINE_INTEGER(GL_HISTOGRAM_ALPHA_SIZE); DEFINE_INTEGER(GL_HISTOGRAM_LUMINANCE_SIZE); DEFINE_INTEGER(GL_HISTOGRAM_SINK); DEFINE_INTEGER(GL_MINMAX); DEFINE_INTEGER(GL_MINMAX_FORMAT); DEFINE_INTEGER(GL_MINMAX_SINK); DEFINE_INTEGER(GL_TABLE_TOO_LARGE); DEFINE_INTEGER(GL_BLEND_EQUATION); DEFINE_INTEGER(GL_MIN); DEFINE_INTEGER(GL_MAX); DEFINE_INTEGER(GL_FUNC_ADD); DEFINE_INTEGER(GL_FUNC_SUBTRACT); DEFINE_INTEGER(GL_FUNC_REVERSE_SUBTRACT); DEFINE_INTEGER(GL_BLEND_COLOR); DEFINE_INTEGER(GL_CURRENT_BIT); DEFINE_INTEGER(GL_POINT_BIT); DEFINE_INTEGER(GL_LINE_BIT); DEFINE_INTEGER(GL_POLYGON_BIT); DEFINE_INTEGER(GL_POLYGON_STIPPLE_BIT); DEFINE_INTEGER(GL_PIXEL_MODE_BIT); DEFINE_INTEGER(GL_LIGHTING_BIT); DEFINE_INTEGER(GL_FOG_BIT); DEFINE_INTEGER(GL_DEPTH_BUFFER_BIT); DEFINE_INTEGER(GL_ACCUM_BUFFER_BIT); DEFINE_INTEGER(GL_STENCIL_BUFFER_BIT); DEFINE_INTEGER(GL_VIEWPORT_BIT); DEFINE_INTEGER(GL_TRANSFORM_BIT); DEFINE_INTEGER(GL_ENABLE_BIT); DEFINE_INTEGER(GL_COLOR_BUFFER_BIT); DEFINE_INTEGER(GL_HINT_BIT); DEFINE_INTEGER(GL_EVAL_BIT); DEFINE_INTEGER(GL_LIST_BIT); DEFINE_INTEGER(GL_TEXTURE_BIT); DEFINE_INTEGER(GL_SCISSOR_BIT); DEFINE_INTEGER(GL_ALL_ATTRIB_BITS); DEFINE_INTEGER(GL_CLIENT_PIXEL_STORE_BIT); DEFINE_INTEGER(GL_CLIENT_VERTEX_ARRAY_BIT); #if HAVE_GLU DEFINE_INTEGER(GLU_FALSE); DEFINE_INTEGER(GLU_TRUE); DEFINE_INTEGER(GLU_VERSION); DEFINE_INTEGER(GLU_EXTENSIONS); DEFINE_INTEGER(GLU_INVALID_ENUM); DEFINE_INTEGER(GLU_INVALID_VALUE); DEFINE_INTEGER(GLU_OUT_OF_MEMORY); DEFINE_INTEGER(GLU_INVALID_OPERATION); DEFINE_INTEGER(GLU_OUTLINE_POLYGON); DEFINE_INTEGER(GLU_OUTLINE_PATCH); DEFINE_INTEGER(GLU_NURBS_ERROR); DEFINE_INTEGER(GLU_ERROR); DEFINE_INTEGER(GLU_NURBS_BEGIN); DEFINE_INTEGER(GLU_NURBS_VERTEX); DEFINE_INTEGER(GLU_NURBS_NORMAL); DEFINE_INTEGER(GLU_NURBS_COLOR); DEFINE_INTEGER(GLU_NURBS_TEXTURE_COORD); DEFINE_INTEGER(GLU_NURBS_END); DEFINE_INTEGER(GLU_NURBS_BEGIN_DATA); DEFINE_INTEGER(GLU_NURBS_VERTEX_DATA); DEFINE_INTEGER(GLU_NURBS_NORMAL_DATA); DEFINE_INTEGER(GLU_NURBS_COLOR_DATA); DEFINE_INTEGER(GLU_NURBS_TEXTURE_COORD_DATA); DEFINE_INTEGER(GLU_NURBS_END_DATA); DEFINE_INTEGER(GLU_NURBS_ERROR1); DEFINE_INTEGER(GLU_NURBS_ERROR2); DEFINE_INTEGER(GLU_NURBS_ERROR3); DEFINE_INTEGER(GLU_NURBS_ERROR4); DEFINE_INTEGER(GLU_NURBS_ERROR5); DEFINE_INTEGER(GLU_NURBS_ERROR6); DEFINE_INTEGER(GLU_NURBS_ERROR7); DEFINE_INTEGER(GLU_NURBS_ERROR8); DEFINE_INTEGER(GLU_NURBS_ERROR9); DEFINE_INTEGER(GLU_NURBS_ERROR10); DEFINE_INTEGER(GLU_NURBS_ERROR11); DEFINE_INTEGER(GLU_NURBS_ERROR12); DEFINE_INTEGER(GLU_NURBS_ERROR13); DEFINE_INTEGER(GLU_NURBS_ERROR14); DEFINE_INTEGER(GLU_NURBS_ERROR15); DEFINE_INTEGER(GLU_NURBS_ERROR16); DEFINE_INTEGER(GLU_NURBS_ERROR17); DEFINE_INTEGER(GLU_NURBS_ERROR18); DEFINE_INTEGER(GLU_NURBS_ERROR19); DEFINE_INTEGER(GLU_NURBS_ERROR20); DEFINE_INTEGER(GLU_NURBS_ERROR21); DEFINE_INTEGER(GLU_NURBS_ERROR22); DEFINE_INTEGER(GLU_NURBS_ERROR23); DEFINE_INTEGER(GLU_NURBS_ERROR24); DEFINE_INTEGER(GLU_NURBS_ERROR25); DEFINE_INTEGER(GLU_NURBS_ERROR26); DEFINE_INTEGER(GLU_NURBS_ERROR27); DEFINE_INTEGER(GLU_NURBS_ERROR28); DEFINE_INTEGER(GLU_NURBS_ERROR29); DEFINE_INTEGER(GLU_NURBS_ERROR30); DEFINE_INTEGER(GLU_NURBS_ERROR31); DEFINE_INTEGER(GLU_NURBS_ERROR32); DEFINE_INTEGER(GLU_NURBS_ERROR33); DEFINE_INTEGER(GLU_NURBS_ERROR34); DEFINE_INTEGER(GLU_NURBS_ERROR35); DEFINE_INTEGER(GLU_NURBS_ERROR36); DEFINE_INTEGER(GLU_NURBS_ERROR37); DEFINE_INTEGER(GLU_AUTO_LOAD_MATRIX); DEFINE_INTEGER(GLU_CULLING); DEFINE_INTEGER(GLU_SAMPLING_TOLERANCE); DEFINE_INTEGER(GLU_DISPLAY_MODE); DEFINE_INTEGER(GLU_PARAMETRIC_TOLERANCE); DEFINE_INTEGER(GLU_SAMPLING_METHOD); DEFINE_INTEGER(GLU_U_STEP); DEFINE_INTEGER(GLU_V_STEP); DEFINE_INTEGER(GLU_NURBS_MODE); DEFINE_INTEGER(GLU_NURBS_TESSELLATOR); DEFINE_INTEGER(GLU_NURBS_RENDERER); DEFINE_INTEGER(GLU_OBJECT_PARAMETRIC_ERROR); DEFINE_INTEGER(GLU_OBJECT_PATH_LENGTH); DEFINE_INTEGER(GLU_PATH_LENGTH); DEFINE_INTEGER(GLU_PARAMETRIC_ERROR); DEFINE_INTEGER(GLU_DOMAIN_DISTANCE); DEFINE_INTEGER(GLU_MAP1_TRIM_2); DEFINE_INTEGER(GLU_MAP1_TRIM_3); DEFINE_INTEGER(GLU_POINT); DEFINE_INTEGER(GLU_LINE); DEFINE_INTEGER(GLU_FILL); DEFINE_INTEGER(GLU_SILHOUETTE); DEFINE_INTEGER(GLU_SMOOTH); DEFINE_INTEGER(GLU_FLAT); DEFINE_INTEGER(GLU_NONE); DEFINE_INTEGER(GLU_OUTSIDE); DEFINE_INTEGER(GLU_INSIDE); DEFINE_INTEGER(GLU_TESS_BEGIN); DEFINE_INTEGER(GLU_BEGIN); DEFINE_INTEGER(GLU_TESS_VERTEX); DEFINE_INTEGER(GLU_VERTEX); DEFINE_INTEGER(GLU_TESS_END); DEFINE_INTEGER(GLU_END); DEFINE_INTEGER(GLU_TESS_ERROR); DEFINE_INTEGER(GLU_TESS_EDGE_FLAG); DEFINE_INTEGER(GLU_EDGE_FLAG); DEFINE_INTEGER(GLU_TESS_COMBINE); DEFINE_INTEGER(GLU_TESS_BEGIN_DATA); DEFINE_INTEGER(GLU_TESS_VERTEX_DATA); DEFINE_INTEGER(GLU_TESS_END_DATA); DEFINE_INTEGER(GLU_TESS_ERROR_DATA); DEFINE_INTEGER(GLU_TESS_EDGE_FLAG_DATA); DEFINE_INTEGER(GLU_TESS_COMBINE_DATA); DEFINE_INTEGER(GLU_CW); DEFINE_INTEGER(GLU_CCW); DEFINE_INTEGER(GLU_INTERIOR); DEFINE_INTEGER(GLU_EXTERIOR); DEFINE_INTEGER(GLU_UNKNOWN); DEFINE_INTEGER(GLU_TESS_WINDING_RULE); DEFINE_INTEGER(GLU_TESS_BOUNDARY_ONLY); DEFINE_INTEGER(GLU_TESS_TOLERANCE); DEFINE_INTEGER(GLU_TESS_ERROR1); DEFINE_INTEGER(GLU_TESS_ERROR2); DEFINE_INTEGER(GLU_TESS_ERROR3); DEFINE_INTEGER(GLU_TESS_ERROR4); DEFINE_INTEGER(GLU_TESS_ERROR5); DEFINE_INTEGER(GLU_TESS_ERROR6); DEFINE_INTEGER(GLU_TESS_ERROR7); DEFINE_INTEGER(GLU_TESS_ERROR8); DEFINE_INTEGER(GLU_TESS_MISSING_BEGIN_POLYGON); DEFINE_INTEGER(GLU_TESS_MISSING_BEGIN_CONTOUR); DEFINE_INTEGER(GLU_TESS_MISSING_END_POLYGON); DEFINE_INTEGER(GLU_TESS_MISSING_END_CONTOUR); DEFINE_INTEGER(GLU_TESS_COORD_TOO_LARGE); DEFINE_INTEGER(GLU_TESS_NEED_COMBINE_CALLBACK); DEFINE_INTEGER(GLU_TESS_WINDING_ODD); DEFINE_INTEGER(GLU_TESS_WINDING_NONZERO); DEFINE_INTEGER(GLU_TESS_WINDING_POSITIVE); DEFINE_INTEGER(GLU_TESS_WINDING_NEGATIVE); DEFINE_INTEGER(GLU_TESS_WINDING_ABS_GEQ_TWO); #endif } /* -------------------------------- initialization -------------------------------- */ static bool gl_already_inited = false; void Init_libgl(void); void Init_libgl(void) { if (!gl_already_inited) { define_integers(); define_functions(); Xen_provide_feature("gl"); Xen_define("gl-version", C_string_to_Xen_string("26-Nov-15")); gl_already_inited = true; } } #else void Init_libgl(void); void Init_libgl(void) { } #endif snd-16.1/extensions.rb0000644000076400007640000016510112462257647013102 0ustar bilbil# extensions.rb -- various generally useful Snd extensions (see extensions.scm) # Translator/Author: Michael Scholz # Created: 04/01/03 17:30:23 # Changed: 14/12/03 17:13:44 # module Compatibility # scan_sound_chans(beg, end, snd, edpos) do |y| ... end # map_sound_chans(beg, end, edname, snd, edpos) do |y| ... end # scan_all_chans(beg, end, edpos) do |y| ... end # map_all_chans(beg, end, edname, edpos) do |y| ... end # scan_chans(beg, end, edpos) do |y| ... end # map_chans(beg, end, edname, edpos) do |y| ... end # scan_across_all_chans(beg, end, snd, edpos) do |data, chns| ... end # map_across_all_chans(beg, end, edname, snd, edpos) do |data, chns| ... end # selection_to_temp(type = Mus_next, format = Mus_out_format) # syncd_sounds(val) # sound_to_temp(type = Mus_next, format = Mus_out_format, edpos = false) # selection_to_temps(type = Mus_next, format = Mus_out_format) # sound_to_temps(type = Mus_next, format = Mus_out_format, edpos = false) # temp_to_sound(data, filename, origin = false) # temps_to_sound(data, filenames, origin = false) # temp_to_selection(data, filename, origin = false) # temps_to_selection(data, filenames, origin = false) # # forward_sample(count, snd, chn) # backward_sample(count, snd, chn) # # back_or_forth_graph(count) # forward_graph(count) # backward_graph(count) # back_or_forth_mix(count) # forward_mix(count = 1, snd = false, chn = false) # backward_mix(count = 1, snd = false, chn = false) # back_or_forth_mark(count) # forward_mark(count = 1, snd = false, chn = false) # backward_mark(count = 1, snd = false, chn = false) # vct_convolve!(r1, r2) # old_map_channel(beg, dur, snd, chn, edpos, edname, &func) # mus_bank(gens, amps, in1, in2) # old_oscil_bank(amps, gens, in1, in2) # old_formant_bank(amps, gens, in1) # vct2samples(samp, samps, data, snd, chn) # samples2vct(samp, samps, snd, chn, nv, epos) # scale_sound_by(scl, beg, dur, snd, chn, edpos) # scale_sound_to(norm, beg, dur, snd, chn) # emacs_style_save_as # set_emacs_style_save_as(val) # make_iir_low_pass_1(fc) # make_iir_high_pass_1(fc) # sine_bank(amps, phases, size) # # module Extensions # remove_channel_property(key, snd, chn) # remove_sound_property(key, snd) # # channel_sync(snd, chn) # set_channel_sync(val, snd, chn) # # set_sound_property_save_state_ignore(key, snd) # set_channel_property_save_state_ignore(key, snd, chn) # show_sound_properties(snd) # show_channel_properties(snd, chn) # # properties2string(snd) # save_properties(fname) # # remember_all_sound_properties(database, tmp_snd_p) # remember_properties # class Remember_sound_properties # initialize(database) # inspect # with_db do |db| ... end # load(snd) # save(snd) # each do |k, v| ... end # delete_if do |k, v| ... end # contents # help # # add_comment(samp, comm, snd, chn) # remove_comment(comm, snd, chn) # show_comments(snd, chn) # # marks?(more_than_one) # all_chans # all_chans_zipped # normalized_mix(fname, beg, in_chan, snd, chn) # enveloped_mix(fname, beg, env, del_tmp) # # map_sound_files(*args) do |f| ... end # for_each_sound_file(*args) do |f| ... end alias each_sound_file # match_sound_files(*args) do |f| ... end # # selection_members # clear_selection # make_selection(beg, len, snd, chn) # delete_selection_and_smooth() # # mix_channel(fdata, beg, dur, snd, chn, edpos) # insert_channel(fdata, beg, dur, snd, chn, edpos) # redo_channel(edits, snd, chn) # undo_channel(edits, snd, chn) # # any_env_channel(en, b, d, s, c, ep, ori) do |r0, r1, b, d, s, c, e| ... end # sine_ramp(rmp0, rmp1, beg, dur, snd, chn, edpos) # sine_env_channel(env, beg, dur, snd, chn, edpos) # blackman4_ramp(rmp0, rmp1, beg, dur, snd, chn, edpos) # blackman4_env_channel(env, beg, dur, snd, chn, edpos) # ramp_squared(rmp0, rmp1, symmetric, beg, dur, snd, chn, edpos) # env_squared_channel(env, symmetric, beg, dur, snd, chn, edpos) # ramp_expt(rmp0, rmp1, exponent, symmetric, beg, dur, snd, chn, edpos) # env_expt_channel(env, exponent, symmetric, beg, dur, snd, chn, edpos) # offset_channel(amount, beg, dur, snd, chn, edpos) # offset_sound(amount, beg, dur, snd) # pad_sound(beg, dur, snd) # dither_channel(amnt, beg, dur, snd, chn, edpos) # dither_sound(amnt, beg, dur, snd) # contrast_channel(index, beg, dur, snd, chn, edpos) # contrast_sound(index, beg, dur, snd) # channels_eql?(snd1, chn1, snd2, chn2, allowable_difference) # channels_equal?(snd1, chn1, snd2, chn2, allowable_difference) # mono2stereo(new_name, snd1, chn1, snd2, chn2) # mono_files2stereo(new_name, chan1_name, chan2_name) # stereo2mono(orig_snd, chan1_name, chan2_name) # # with_reopen_menu # with_buffers_menu # Comments are mostly taken from extensions.scm. require "hooks" include Math module Compatibility # # Snd-4 compatibility stuff # add_help(:scan_sound_chans, "scan_sound_chans(beg=0, end=flase, snd=false, edpos=false, &proc) \ Applies scan_chan with PROC to each channel in a sound.") def scan_sound_chans(beg = 0, fin = false, snd = false, edpos = false, &body) # Proc#arity returns -1 instead of 1 on older versions if body and body.arity.abs == 1 val = nil c = (0...chans(snd)).detect do |chn| val = scan_chan(body, beg, fin, snd, chn, edpos) end if c val += [Snd.snd(snd), c] else nil end else Snd.raise(:bad_arity, "scan_sound_chans(beg, end, snd, edpos) do |y| ... end") end end add_help(:map_sound_chans, "map_sound_chans(beg=0, end=flase, snd=false, edpos=false, &proc) \ Applies map_chan with PROC to each channel in a sound.") def map_sound_chans(beg = 0, fin = false, edname = false, snd = false, edpos = false, &body) if body and body.arity.abs == 1 channels(snd).times do |chn| map_chan(body, beg, fin, edname, snd, chn, edpos) end else Snd.raise(:bad_arity, "map_sound_chans(beg, end, ename, snd, edpos) do |y| ... end") end end add_help(:scan_all_chans, "scan_all_chans(beg=0, end=flase, edpos=false, &proc) \ Applies scan_chan with PROC to all channels (all sounds).") def scan_all_chans(beg = 0, fin = false, edpos = false, &body) if body and body.arity.abs == 1 catch(:done) do Snd.sounds.each do |snd| channels(snd).times do |chn| if res = scan_chan(body, beg, fin, snd, chn, edpos) throw(:done, res += [snd, chn]) end end end false end else Snd.raise(:bad_arity, "scan_all_chans(beg, end, edpos) do |y| ... end") end end add_help(:map_all_chans, "map_all_chans(beg=0, end=flase, edpos=false, &proc) \ Applies map_chan with proc to all channels (all sounds).") def map_all_chans(beg = 0, fin = false, edname = false, edpos = false, &body) if body and body.arity.abs == 1 Snd.sounds.each do |snd| channels(snd).times do |chn| map_chan(body, beg, fin, edname, snd, chn, edpos) end end else Snd.raise(:bad_arity, "map_all_chans(beg, end, ename, edpos) do |y| ... end") end end add_help(:scan_chan, "scan_chans(beg=0, end=flase, edpos=false, &proc) \ Applies scan_chan with PROC to all channels sharing current sound's sync.") def scan_chans(beg = 0, fin = false, edpos = false, &body) if body and body.arity.abs == 1 current_sync = sync(selected_sound) catch(:done) do Snd.sounds.each do |snd| if sync(snd) == current_sync channels(snd).times do |chn| if res = scan_chan(body, beg, fin, snd, chn, edpos) throw(:done, res += [snd, chn]) end end end end false end else Snd.raise(:bad_arity, "scan_chans(beg, end, edpos) do |y| ... end") end end add_help(:map_chan, "map_chans(beg=0, end=false, edpos=false, &proc) \ Applies map_chan with PROC to all channels sharing current sound's sync.") def map_chans(beg = 0, fin = false, edname = false, edpos = false, &body) if body and body.arity.abs == 1 current_sync = sync(selected_sound) Snd.sounds.each do |snd| if sync(snd) == current_sync channels(snd).times do |chn| map_chan(body, beg, fin, edname, snd, chn, edpos) end end end else Snd.raise(:bad_arity, "map_chans(beg, end, ename, edpos) do |y| ... end") end end add_help(:scan_across_all_chans, "scan_across_all_chans(beg=0, end=flase, \ snd=false, edpos=false, &proc) \ Applies map_chan with PROC to all channels in parallel.") # body.call(data, chan_num) def scan_across_all_chans(beg = 0, fin = false, snd = false, edpos = false, &body) chans = all_chans chan_num = chans.first.length maxlen = 0 Snd.sounds.each do |s| channels(s).times do |chn| maxlen = [maxlen, framples(s, chn)].max end end len = integer?(fin) ? ([fin, maxlen].min - beg) : (maxlen - beg) data = make_array(chan_num, 0.0) fds = make_array(chan_num) do |chn| make_sampler(beg, chans[0].shift, chans[1].shift, 1, edpos) end catch(:done) do len.times do |i| data.map_with_index! do |d, chn| next_sample(fds[chn]) end if newdata = body.call(data, chan_num) throw(:done, [newdata, i + beg]) end end end end add_help(:map_across_all_chans, "map_across_all_chans(beg=0, end=flase, edname=false, \ snd=false, edpos=false, &proc) \ Applies map_chan with PROC to all channels in parallel.") def map_across_all_chans(beg = 0, fin = false, edname = false, snd = false, edpos = false, &body) snds, chans = all_chans chan_num = snds.length maxlen = 0 Snd.sounds.each do |sd| channels(sd).times do |chn| maxlen = [maxlen, framples(sd, chn)].max end end len = integer?(fin) ? ([fin, maxlen].min - beg) : (maxlen - beg) data = make_array(chan_num) fds = make_array(chan_num) do |chn| make_sampler(beg, snds[chn], chans[chn], 1, edpos) end filenames = make_array(chan_num) do |chn| snd_tempnam end outgs = make_array(chan_num) do |chn| make_sample2file(filenames[chn], 1, Mus_out_format, Mus_next) end outsamp = 0 len.times do |i| data.map_with_index! do |d, chn| next_sample(fds[chn]) end if (newdata = body.call(data, chan_num)) newdata.each_with_index do |dat, chn| out_any(outsamp, dat, 0, outgs[chn]) end outsamp += 1 end end filenames.each_with_index do |file, chn| mus_close(outgs[chn]) free_sampler(fds[chn]) if outsamp > 0 delete_samples(beg, len, snds[chn], chans[chn]) if outsamp != len set_samples(beg, outsamp, file, snds[chn], chans[chn], true, edname) delete_file(file) end end end # # Snd-4 external program support stuff # add_help(:selection_to_temp, "selection_to_temp(type=Mus_next, format=Mus_out_format) \ Writes selection data as (multichannel) file (for external program).") def selection_to_temp(type = Mus_next, format = Mus_out_format) data = [snd_tempnam] save_selection(data.first, 44100, format, type) data end def syncd_sounds(val) ctr = 0 Snd.sounds.each do |snd| if sync(snd) == val ctr += 1 end end ctr end add_help(:sound_to_temp, "sound_to_temp(type=Mus_next, format=Mus_out_format, edpos=false) \ Writes sound data as (multichannel) file (for external program).") def sound_to_temp(type = Mus_next, format = Mus_out_format, edpos = false) cursnd = selected_sound cursync = sync(cursnd) if cursync.zero? or syncd_sounds(cursync) == 1 data = [snd_tempnam] save_sound_as(data.first, selected_sound, :header_type, type, :sample_type, format, :edit_position, edpos) data else Snd.raise(:snd_error, "re-implemented sound-to-temp doesn't \ handle sync bit correctly yet.") end end add_help(:selection_to_temps, "selection_to_temps(type=Mus_next, format=Mus_out_format) \ Writes selection data as mono files (for external program).") def selection_to_temps(type = Mus_next, format = Mus_out_format) data = make_array(selection_chans) do |chn| outname = snd_tempnam save_selection(outname, 44100, format, type, :channel, chn) outname end data end add_help(:sound_to_temps, "sound_to_temps(type=Mus_next, format=Mus_out_format, edpos=false) \ Writes sound data as mono files (for external program).") def sound_to_temps(type = Mus_next, format = Mus_out_format, edpos = false) cursnd = selected_sound cursync = sync(cursnd) if cursync.zero? or syncd_sounds(cursync) == 1 make_array(channels(cursnd)) do |chn| outname = snd_tempnam save_sound_as(outname, selected_sound, :header_type, type, :sample_type, format, :channel, chn, :edit_position, edpos) outname end else Snd.raise(:snd_error, "re-implemented sound-to-temps doesn't \ handle sync bit correctly yet.") end end # filenames: String or Array of Strings def delete_temp_data_files(data, filenames) case filenames when String (data or []).each do |temp_file| if File.exist?(temp_file) and temp_file != filenames File.unlink(temp_file) end end when Array (data or []).each_with_index do |temp_file, i| if File.exist?(temp_file) and temp_file != filenames[i] File.unlink(temp_file) end end end end add_help(:temp_to_sound, "temp_to_sound(data, filename, origin=false) \ Reads (multichannel) file as new sound data (from external program).") def temp_to_sound(data, filename, origin = false) cursnd = selected_sound delete_temp_data_files(data, filename) channels(cursnd).times do |chn| set_samples(0, mus_sound_framples(filename), filename, cursnd, chn, true, origin, chn) end end add_help(:temps_to_sound, "temps_to_sound(data, filenames, origin=false) \ Reads mono files as new sound data (from external program).") def temps_to_sound(data, filenames, origin = false) cursnd = selected_sound delete_temp_data_files(data, filenames) channels(cursnd).times do |chn| len = mus_sound_framples(filenames[chn]) set_samples(0, len, filenames[chn], cursnd, chn, true, origin, chn) end end add_help(:temp_to_selection, "temp_to_selection(data, filename, origin=false) \ Sets selection from (multichannel) file (from external program).") def temp_to_selection(data, filename, origin = false) delete_temp_data_files(data, filename) chan = 0 len = mus_sound_framples(filename) Snd.sounds.each do |snd| channels(snd).times do |chn| if selection_member?(snd, chn) set_samples(selection_position(snd, chn), len, filename, snd, chn, true, origin, chan) chan += 1 end end end end add_help(:temps_to_selection, "temps_to_selection(data, filenames, origin=false) \ Sets selection from mono files (from external program).") def temps_to_selection(data, filenames, origin = false) delete_temp_data_files(data, filenames) chan = 0 Snd.sounds.each do |snd| channels(snd).times do |chn| if selection_member?(snd, chn) len = mus_sound_framples(filenames[chan]) set_samples(selection_position(snd, chn), len, filenames[chan], snd, chn, true, origin) chan += 1 end end end end # # Snd-5 compatibility stuff # def forward_sample(count = 1, snd = false, chn = false) set_cursor(cursor(snd, chn) + count, snd, chn) end def backward_sample(count = 1, snd = false, chn = false) set_cursor(cursor(snd, chn) - count, snd, chn) end # # Snd-7 compatibility stuff # def back_or_forth_graph(count) if sounds cursnd = selected_sound or Snd.sounds.first curchn = selected_channel or 0 curpos = 0 pos = 0 sndlst = [] chnlst = [] Snd.sounds.each do |snd| channels(snd).times do |chn| if cursnd.eql?(snd) and curchn == chn curpos = pos end pos += 1 sndlst.push(snd) chnlst.push(chn) end end newpos = (curpos + count) % sndlst.length set_selected_sound(sndlst[newpos]) set_selected_channel(chnlst[newpos]) [selected_sound, selected_channel] end end def forward_graph(count = 1) back_or_forth_graph(count) end def backward_graph(count = 1) back_or_forth_graph(-count) end def back_or_forth_mix(count, snd, chn) if count.nonzero? and (mx = mixes(snd, chn)) if mx.length == 1 set_cursor(mix_position(mx.first), snd, chn) mx.first else sorted_mx = mx.sort do |a, b| mix_position(a) <=> mix_position(b) end pos = cursor(snd, chn) curpos = count > 0 ? -1 : 0 if pos >= mix_position(sorted_mx.first) sorted_mx.each do |m| if (count > 0 and pos < mix_position(m)) or (count < 0 and pos <= mix_position(m)) break else curpos += 1 end end end curmx = sorted_mx[(curpos + count) % mx.length] set_cursor(mix_position(curmx), snd, chn) curmx end else false end end def forward_mix(count = 1, snd = false, chn = false) back_or_forth_mix(count, Snd.snd(snd), Snd.chn(chn)) end def backward_mix(count = 1, snd = false, chn = false) back_or_forth_mix(-count, Snd.snd(snd), Snd.chn(chn)) end def back_or_forth_mark(count, snd, chn) mk = Snd.marks(snd, chn) if count.nonzero? and (not mk.empty?) if mk.length == 1 set_cursor(mark_sample(mk.first), snd, chn) mk.first else sorted_mk = mk.sort do |a, b| mark_sample(a) <=> mark_sample(b) end pos = cursor(snd, chn) curpos = count > 0 ? -1 : 0 if pos >= mark_sample(sorted_mk.first) sorted_mk.each do |m| if (count > 0 and pos < mark_sample(m)) or (count < 0 and pos <= mark_sample(m)) break else curpos += 1 end end end curmk = sorted_mk[(curpos + count) % mk.length] set_cursor(mark_sample(curmk), snd, chn) curmk end else false end end def forward_mark(count = 1, snd = false, chn = false) back_or_forth_mark(count, Snd.snd(snd), Snd.chn(chn)) end def backward_mark(count = 1, snd = false, chn = false) back_or_forth_mark(-count, Snd.snd(snd), Snd.chn(chn)) end def vct_convolve!(r1, r2) convolution(r1, r2, r1.length) end def old_map_channel(beg = 0, dur = false, snd = false, chn = false, edpos = false, edname = false, &func) map_channel(lambda do |y| if array?(val = func.call(y)) vector2vct(val) else val end end, beg, dur, snd, chn, edpos, edname) end def mus_bank(gens, amps, in1 = false, in2 = false) amps = case amps when Array amps.to_vct when Vct amps else Vct.new(gens.length, 1.0) end inp1 = case in1 when Array in1.to_vct when Vct in1 else Vct.new(gens.length, 0.0) end inp2 = case in2 when Array in2.to_vct when Vct in2 else Vct.new(gens.length, 0.0) end sum = 0.0 gens.each_with_index do |gen, i| sum = sum + amps[i] * mus_run(gen, inp1[i], inp2[i]) end sum end def old_oscil_bank(amps, gens, in1 = false, in2 = false) amps = case amps when Array amps.to_vct when Vct amps else Vct.new(gens.length, 1.0) end inp1 = case in1 when Array in1.to_vct when Vct in1 else Vct.new(gens.length, 0.0) end inp2 = case in2 when Array in2.to_vct when Vct in2 else Vct.new(gens.length, 0.0) end sum = 0.0 gens.each_with_index do |gen, i| sum = sum + amps[i] * oscil(gen, inp1[i], inp2[i]) end sum end def old_formant_bank(amps, gens, in1 = 0.0) formant_bank(array?(amps) ? amps.to_vct : amps, gens, in1) end def vct2samples(samp, samps, data, snd = false, chn = false) vct2channel(data, samp, samps, snd, chn) end def samples2vct(samp, samps, snd = false, chn = false, nv = false, epos = false) if nv vct_subseq(channel2vct(samp, samps, snd, chn, epos), 0, samps, nv) else channel2vct(samp, samps, snd, chn, epos) end end def scale_sound_by(scl, beg = false, dur = false, snd = false, chn = false, edpos = false) if integer?(chn) scale_channel(scl, beg, dur, snd, chn, edpos) else channels(snd).times do |c| scale_channel(scl, beg, dur, snd, c) end end end def scale_sound_to(norm, beg = false, dur = false, snd = false, chn = false) if integer?(chn) mx = maxamp(snd, chn) if mx.nonzero? and mx != norm scale_channel(norm / mx, beg, dur, snd, chn) end else mx = maxamp(snd, true).max if mx.nonzero? and mx != norm channels(snd).times do |c| scale_channel(norm / mx, beg, dur, snd, c) end end end end Emacs_hookname = "after-save-as-hook-replace-sound" def emacs_style_save_as $after_save_as_hook.member?(Emacs_hookname) end def set_emacs_style_save_as(val = true) if val and (not emacs_style_save_as()) $after_save_as_hook.add_hook!(Emacs_hookname) do |snd, fname, from_dialog| if from_dialog revert_sound(snd) close_sound(snd) open_sound(fname) end end else $after_save_as_hook.remove_hook!(Emacs_hookname) end end alias mus_error_to_string mus_error_type2string def make_iir_low_pass_1(fc) fc = fc.to_f theta = (2 * PI * fc) / mus_srate() gamma = cos(theta) / (1.0 + sin(theta)) xc = (1.0 - gamma) / 2.0 make_filter(2, vct(xc, xc), vct(0.0, -gamma)) end def make_iir_high_pass_1(fc) fc = fc.to_f theta = (2 * PI * fc) / mus_srate() gamma = cos(theta) / (1.0 + sin(theta)) xc = (1.0 + gamma) / 2.0 make_filter(2, vct(xc, -xc), vct(0.0, -gamma)) end # # Snd-9 compatibility stuff # def sine_bank(amps, phases, size = nil) len = (size or amps.length) sum = 0.0 len.times do |i| sum = sum + amps[i] * sin(phases[i]) end sum end end include Compatibility module Extensions add_help(:remove_channel_property, "remove_channel_property(key, snd) \ Deletes key-value pair.") def remove_channel_property(key, snd = false, chn = false) array?(props = channel_properties(snd, chn)) and array?(item = props.assoc(key)) and props.delete(item) end add_help(:remove_sound_property, "remove_sound_property(key, snd) \ Deletes key-value pair.") def remove_sound_property(key, snd = false) array?(props = sound_properties(snd)) and array?(item = props.assoc(key)) and props.delete(item) end def channel_sync(snd = false, chn = false) channel_property(:sync, snd, chn) end def set_channel_sync(val, snd = false, chn = false) set_channel_property(:sync, val, snd, chn) end def set_sound_property_save_state_ignore(key, snd = false) set_sound_property(:save_state_ignore, (sound_property(:save_state_ignore, snd) or [:save_state_ignore]) + [key], snd) end def set_channel_property_save_state_ignore(key, snd = false, chn = false) set_channel_property(:save_state_ignore, (channel_property(:save_state_ignore, snd, chn) or [:save_state_ignore]) + [key], snd, chn) end def show_sound_properties(snd = false) if props = sound_properties(snd) Snd.display("sound-properties of %s", file_name(snd).inspect) props.each do |k, v| Snd.display("%s --> %s", k, v.inspect) end else Snd.display("%s has no sound-properties", file_name(snd).inspect) end nil end def show_channel_properties(snd = false, chn = false) Snd.display("channel-properties of %s", file_name(snd).inspect) if integer?(chn) if props = channel_properties(snd, chn) Snd.display("==> channel %d <==", chn) props.each do |k, v| Snd.display("%s --> %s", k, v.inspect) end else Snd.display("==> channel %d has no channel-properties <==", chn) end else channels(snd).times do |cn| if props = channel_properties(snd, cn) Snd.display("==> channel %d <==", cn) props.each do |k, v| Snd.display("%s --> %s", k, v.inspect) end else Snd.display("==> channel %d has no channel-properties <==", cn) end end end nil end # Used in remember_all_sound_properties and remember_sound_state $sound_funcs = [:sync, :with_tracking_cursor, :selected_channel, :show_controls, :read_only, :contrast_control?, :expand_control?, :reverb_control?, :filter_control?, :amp_control, :amp_control_bounds, :contrast_control, :contrast_control_amp, :contrast_control_bounds, :expand_control, :expand_control_bounds, :expand_control_hop, :expand_control_jitter, :expand_control_length, :expand_control_ramp, :filter_control_envelope, :filter_control_in_dB, :filter_control_in_hz, :filter_control_order, :reverb_control_decay, :reverb_control_feedback, :reverb_control_length, :reverb_control_length_bounds, :reverb_control_lowpass, :reverb_control_scale, :reverb_control_scale_bounds, :speed_control, :speed_control_bounds, :speed_control_style, :speed_control_tones] # transform_type: # transform2integer --> # save/load --> integer2transform $channel_funcs = [:time_graph?, :transform_graph?, :lisp_graph?, :x_bounds, :y_bounds, :cursor, :cursor_size, :cursor_style, :show_marks, :show_y_zero, :show_grid, :wavo_hop, :wavo_trace, :max_transform_peaks, :show_transform_peaks, :fft_log_frequency, :fft_log_magnitude, :with_verbose_cursor, :zero_pad, :wavelet_type, :min_dB, :transform_size, :transform_graph_type, :time_graph_type, :fft_window, :transform_type, :transform_normalization, :time_graph_style, :show_mix_waveforms, :dot_size, :x_axis_style, :show_axes, :graphs_horizontal, :lisp_graph_style, :transform_graph_style, :grid_density, :tracking_cursor_style] # [ms] Based on the idea of remember_sound_state() below, here is # another approach, using a database file. # # remember_all_sound_properties() in ~/.snd-ruby.rb installs the hooks # default database is ~/.snd-properties.db # default tmp_snd_p is false # (discarding `.*0000_00.snd' and `.*.rev.*' filenames) def remember_all_sound_properties(database = ENV['HOME'] + "/.snd-properties", tmp_snd_p = false) rsp = Remember_sound_properties.new(database) unless $after_open_hook.member?("save-property-hook") $after_open_hook.add_hook!("save-property-hook") do |snd| rsp.load(snd) end $close_hook.add_hook!("save-property-hook") do |snd| if tmp_snd_p or (not file_name(snd) =~ /(.+\d+_\d+\.snd$)|(.*\.rev.*$)/) rsp.save(snd) end end end set_property(:remember_properties, :object, rsp) rsp end # Returns the local object created by remember_all_sound_properties # to manipulate the database with methods mentioned below; it saves # a global variable. def remember_properties property(:remember_properties, :object) end class Remember_sound_properties add_help(:remember_sound_properties, "\ # class Remember_sound_properties # initialize(database) # # getter: # database # # methods: # inspect # with_db do ... end # load(snd) # save(snd) # each do |file, value| ... end # delete_if do |file, value| ... end # contents # help (alias info and description) # # Usage: # # rsp = Remember_sound_properties.new(database) # unless $after_open_hook.member?(\"save-property-hook\") # $after_open_hook.add_hook!(\"save-property-hook\") do |snd| # rsp.load(snd) # end # $close_hook.add_hook!(\"save-property-hook\") do |snd| # # discarding `.*0000_00.snd' and `.*.rev.*' filenames # if tmp_snd_p or # (not file_name(snd) =~ /(.+\\d+_\\d+\\.snd$)|(.*\\.rev.*$)/) # rsp.save(snd) # end # end # end # # rsp.delete_if do |file, value| # file =~ /test/ # end # deletes all files containing the string \"test\" # rsp.contents # prints all filenames in database # rsp.each do |file, value| # Snd.display(file) # end # the same as rsp.contents") include Enumerable include Info with_silence do unless defined? DBM.open require "dbm" end end def initialize(database) @database = database @sound_funcs = $sound_funcs @channel_funcs = $channel_funcs set_help end attr_reader :database alias help description def inspect format("#<%s: database: %s>", self.class, @database.inspect) end def with_db db = DBM.open(@database) ret = yield(db) db.close ret end def load(snd) snd_name = file_name(snd) with_db do |db| Snd.catch do eval((db[snd_name] or "")) end end if file_write_date(snd_name) == sound_property(:current_file_time, snd) @sound_funcs.each do |prop| if (val = sound_property(prop, snd)) if prop == :selected_channel # arguments swapped! Kernel.set_snd_func(prop, snd, val) else Kernel.set_snd_func(prop, val, snd) end end end channels(snd).times do |chn| set_squelch_update(true, snd, chn) @channel_funcs.each do |prop| if (val = channel_property(prop, snd, chn)) if prop == :transform_type Kernel.set_snd_func(prop, integer2transform(val), snd, chn) else Kernel.set_snd_func(prop, val, snd, chn) end end end set_squelch_update(false, snd, chn) end end end # the resulting string looks like # let(find_sound("snd_name")) do |snd| # set_sound_properties([...], snd) # if channels(snd) > 0 # set_channel_properties([...], snd, 0) # end # if channels(snd) > 1 # set_channel_properties([...], snd, 1) # end # ... # end # self.load evals this string def save(snd) snd_name = file_name(snd) set_sound_property(:current_file_time, file_write_date(snd_name), snd) @sound_funcs.each do |prop| set_sound_property(prop, snd_func(prop, snd), snd) end props = (sound_properties(snd) or []) if reject = sound_property(:save_state_ignore, snd) props.reject! do |k, v| reject.member?(k) end end res = format("let(find_sound(%s)) do |snd_s|\n", snd_name.inspect) res += format(" set_sound_properties(%s, snd_s)\n", props.inspect) channels(snd).times do |chn| @channel_funcs.each do |prop| if prop == :transform_type set_channel_property(prop, transform2integer(snd_func(prop, snd, chn)), snd, chn) else set_channel_property(prop, snd_func(prop, snd, chn), snd, chn) end end props = (channel_properties(snd, chn) or []) if reject = channel_property(:save_state_ignore, snd, chn) props.reject! do |k, v| reject.member?(k) end end res += format(" if channels(snd_s) > %d\n", chn) res += format(" set_channel_properties(%s, snd_s, %d)\n", props.inspect, chn) res += " end\n" end res += "end\n" res += marks2string(snd) with_db do |db| db[snd_name] = res end end def each with_db do |db| db.each do |key, value| yield(key, value) end end end def delete_if(&body) with_db do |db| db.delete_if(&body) end end def contents Snd.display("contents of %s", @database.inspect) with_db do |db| db.each do |file, value| Snd.display(file) end end nil end private def set_help self.description = get_help(:remember_sound_properties) end end # add channel comments (see extsnd.html->Graphics->draw-string) def add_comment(samp, comm, snd = selected_sound(), chn = selected_channel()) if array?(comments = channel_property(:comments, snd, chn)) comments.push([samp, comm]) else set_channel_property(:comments, [[samp, comm]], snd, chn) end end def remove_comment(comm, snd = selected_sound(), chn = selected_channel()) (channel_property(:comments, snd, chn) or []).delete_if do |samp, text| text == comm end end def show_comments(snd, chn) (channel_property(:comments, snd, chn) or []).each do |samp, text| width = 6 * text.length if samp.between?(left_sample(snd, chn), right_sample(snd, chn)) xpos = x2position(samp / srate(snd).to_f, snd, chn) ypos = y2position(sample(samp), snd, chn) cr = make_cairo(channel_widgets(snd, chn)[0]) draw_line(xpos, 35, xpos, ypos - 4, snd, chn, Copy_context, cr) draw_string(text, xpos - width / 2, 18, snd, chn, Copy_context, cr) free_cairo(cr) end end end # $after_graph_hook.add_hook!("show-comments") do |snd, chn| # show_comments(snd, chn) # end # Have we marks? Similar to selections?(). def marks?(more_than_one = true) if (m = marks(selected_sound(), selected_channel())).nil? false else if more_than_one m.length > 1 else true end end end add_help(:all_chans, "all_chans() \ Returns two parallel lists, the first snd indices, \ the second channel numbers. \ If we have two sounds open (indices 0 and 1 for example), \ and the second has two channels, \ all_chans returns [[0, 1, 1], [0, 0, 1]].") def all_chans sndlist = [] chnlist = [] Snd.sounds.each do |snd| channels(snd).times do |chn| sndlist << snd chnlist << chn end end [sndlist, chnlist] end # all_chans: [[0, 1, 1], [0, 0, 1]] # all_chans_zipped: [[0, 0], [1, 0], [1, 1]] # fits with each or map # all_chans_zipped.each do |snd, chn| ... end def all_chans_zipped new_list = [] Snd.sounds.each do |snd| channels(snd).times do |chn| new_list.push([snd, chn]) end end new_list end add_help(:normalized_mix, "normalized_mix(filename, beg, in_chan, snd, chn) \ Is like mix but the mix result has same peak amp \ as unmixed snd/chn (returns scaler).") def normalized_mix(fname, beg = 0, in_chan = 0, snd = false, chn = false) orig_maxamp = maxamp(snd, chn) mix(fname, beg, in_chan, snd, chn) new_maxamp = maxamp(snd, chn) if orig_maxamp == new_maxamp 1.0 else scl = orig_maxamp / new_maxamp old_sync = sync(snd) set_sync(false, snd) scale_by(scl, snd, chn) set_sync(old_sync, snd) scl end end add_help(:enveloped_mix, "enveloped_mix(filename, beg, env) \ Mixes FILENAME starting at BEG with amplitude envelope ENV: \ enveloped_mix(\"pistol.snd\", 0, [0, 0, 1, 1, 2, 0])") def enveloped_mix(fname, beg, env, del_tmp = true) len = framples(fname) amp_env = make_env(env, :length, len) rd = make_readin(fname) map_channel(lambda do |y| y + env(amp_env) * readin(rd) end, beg, len) end # enveloped_mix("pistol.snd", 0, [0, 0, 1, 1, 2, 0]) add_help(:for_each_sound_file, "for_each_sound_file(*dir_args) do |file| ... end \ Applies body to each sound file in dir.") add_help(:map_sound_files, "map_sound_files(*dir_array) do |file| ... end \ Applies body to each sound file in dir.") add_help(:each_sound_file, "each_sound_file(*dir_args) do |file| ... end \ Applies body to each sound file in dir.") def each_sound_file(*args, &func) if args.empty? args.push(Dir.pwd) end args.map do |dir| if File.exist?(dir) sound_files_in_directory(dir).each do |f| func.call(dir + "/" + f) end end end end alias for_each_sound_file each_sound_file alias map_sound_files each_sound_file # each_sound_file(".", "/usr/opt/sound/SFiles") do |f| # play(f, :wait, true) # end add_help(:match_sound_files, "match_sound_files(*dir_args) do |file| ... end \ Applies func to each sound file in dir and returns a list of files \ for which body does not return false.") def match_sound_files(*args, &func) res = [] each_sound_file(*args) do |f| func.call(f) and res.push(f) end res end # match_sound_files() do |f| f =~ /\.(wav|snd)$/ end add_help(:selection_members, "selection_members() \ Returns list of lists of [snd, chn] indicating the channels \ participating in the current selection.") def selection_members sndlist = [] if selection? Snd.sounds.each do |snd| channels(snd).times do |chn| sndlist.push([snd, chn]) if selection_member?(snd, chn) end end end sndlist end add_help(:clear_selection, "clear_selection() \ Unselects any currently selected samples.") def clear_selection() if selection? Snd.sounds.each do |snd| channels(snd).times do |chn| need_update = selection_member?(snd, chn) set_selection_member?(false, snd, chn) if need_update update_time_graph(snd, chn) end end end end end add_help(:make_selection, "make_selection(beg=0, end=false, snd=false, chn=false) \ Makes a selection like make-region but without creating a region. \ make_selection follows SND's sync field, \ and applies to all SND's channels if CHN is not specified. \ END defaults to end of channel, BEG defaults to 0, \ SND defaults to the currently selected sound.") def make_selection(beg = 0, len = false, snd = false, chn = false) add_chan_to_selection = lambda do |s0, s1, s, c| unless s0 s0 = 0 end set_selection_member?(true, s, c) set_selection_position(s0, s, c) val = if number?(s1) s1 + 1 else framples(s, c) end set_selection_framples(val - s0, s, c) end current_sound = (snd or selected_sound() or Snd.sounds[0]) unless sound?(current_sound) Snd.raise(:no_such_sound, beg, len, snd, chn) end current_sync = sync(current_sound) clear_selection() if number?(chn) add_chan_to_selection.call(beg, len, snd, chn) else Snd.sounds.each do |s| if snd == true or s.eql?(current_sound) or (current_sync.nonzero? and current_sync == sync(s)) channels(s).times do |i| add_chan_to_selection.call(beg, len, s, i) end end end end end add_help(:mix_channel, "mix_channel(file, beg=0, dur=false, \ snd=false, chn=false, edpos=false) \ Mixes in FILE. \ FILE can be the file name or a list [file_name, beg = 0, chn = 0].") def mix_channel(fdata, beg = 0, dur = false, snd = false, chn = false, edpos = false) assert_type((string?(fdata) or array?(fdata)), fdata, 0, "a string or an array") unless number?(beg) beg = 0 end fname = string?(fdata) ? fdata : fdata.first fbeg = if string?(fdata) or fdata.length < 2 0 else fdata[1] end fchan = if string?(fdata) or fdata.length < 3 0 else fdata[2] end len = (dur or (mus_sound_framples(fname) - fbeg)) Snd.raise(:no_such_sample) if beg < 0 if len > 0 reader = make_sampler(fbeg, fname, fchan) map_channel(lambda do |val| val + next_sample(reader) end, beg, len, snd, chn, edpos, format("%s(%p, %s, %s", get_func_name, fdata, beg, dur)) end end add_help(:insert_channel, "insert_channel(file, beg=0, dur=false, \ snd=false, chn=false, edpos=false) \ Inserts the FILE. \ FILE can be the file name or a list [file_name, beg = 0, chn = 0].") def insert_channel(fdata, beg = 0, dur = false, snd = false, chn = false, edpos = false) assert_type((string?(fdata) or array?(fdata)), fdata, 0, "a string or an array") unless number?(beg) beg = 0 end fname = string?(fdata) ? fdata : fdata.first fbeg = if string?(fdata) or fdata.length < 2 0 else fdata[1] end fchan = if string?(fdata) or fdata.length < 3 0 else fdata[2] end len = (dur or (mus_sound_framples(fname) - fbeg)) Snd.raise(:no_such_sample) if beg < 0 if len > 0 reader = make_sampler(fbeg, fname, fchan) insert_samples(beg, len, Vct.new(len) do |i| next_sample(reader) end, snd, chn, edpos, false, format("%s(%p, %s, %s", get_func_name, fdata, beg, dur)) end end add_help(:redo_channel, "redo_channel(edits=1, snd=false, chn=false) \ Is the regularized version of redo.") def redo_channel(edits = 1, snd = false, chn = false) if snd and sync(snd).nonzero? and chn set_edit_position(edit_position(snd, chn) + edits, snd, chn) else redo_edit(edits, snd) end end add_help(:undo_channel, "undo_channel(edits=1, snd=false, chn=false) \ Is the regularized version of undo.") def undo_channel(edits = 1, snd = false, chn = false) if snd and sync(snd).nonzero? and chn set_edit_position([edit_position(snd, chn) - edits, 0].max, snd, chn) else undo_edit(edits, snd) end end # Take breakpoints in ENV, connect with FUNC, apply as envelope to # channel handled as a sequence of funcs and scales. def any_env_channel(env, beg = 0, dur = false, snd = false, chn = false, edpos = false, origin = false, &func) if array?(env) and (not env.empty?) pts = env.length / 2 if pts == 1 scale_channel(env[0], beg, dur, snd, chn, edpos) else x0 = y0 = 0 x1, y1 = env[0], env[1] xrange = (env[-2] - env[0]).to_f ramp_beg = beg unless number?(dur) dur = framples(snd, chn) end as_one_edit_rb(origin) do | | 2.step(env.length - 1, 2) do |i| x0, y0, x1, y1 = x1, y1, env[i], env[i + 1] ramp_dur = (dur * ((x1 - x0) / xrange)).round if y0 == y1 scale_channel(y0, ramp_beg, ramp_dur, snd, chn, edpos) else func.call(y0, y1, ramp_beg, ramp_dur, snd, chn, edpos) end ramp_beg += ramp_dur end end end end end add_help(:sine_ramp, "sine_ramp(rmp0, rmp1, beg=0, dur=false, \ snd=false, chn=false, edpos=false) \ Produces a sinsusoidal connection from RMP0 to RMP1.") def sine_ramp(rmp0, rmp1, beg = 0, dur = false, snd = false, chn = false, edpos = false) angle = -PI len = if number?(dur) dur else framples(snd, chn) - beg end incr = PI / len map_channel(lambda do |y| result = y * (rmp0 + (rmp1 - rmp0) * (0.5 + 0.5 * cos(angle))) angle += incr result end, beg, dur, snd, chn, edpos, format("%s(%s, %s, %s, %s", get_func_name, rmp0, rmp1, beg, dur)) end add_help(:sine_env_channel, "sine_env_channel(env, beg=0, dur=false, \ snd=false, chn=false, edpos=false) \ Connects ENV's dots with sinusoids.") def sine_env_channel(env, beg = 0, dur = false, snd = false, chn = false, edpos = false) any_env_channel(env, beg, dur, snd, chn, edpos, format("%s(%p, %s, %s", get_func_name, env, beg, dur)) do |r0, r1, b, d, s, c, e| sine_ramp(r0, r1, b, d, s, c, e) end end # sine_env_channel([0, 0, 1, 1, 2, -0.5, 3, 1]) # An obvious extension of this idea is to use the blackman fft window # formulas to get sharper sinusoids (i.e. use the sum of n cosines, # rather than just 1). def blackman4_ramp(rmp0, rmp1, beg = 0, dur = false, snd = false, chn = false, edpos = false) angle = 0.0 len = if number?(dur) dur else framples(snd, chn) - beg end incr = PI / len map_channel(lambda do |y| cx = cos(angle) result = y * (rmp0 + (rmp1 - rmp0) * (0.084037 + cx * (-0.29145 + cx * (0.375696 + cx * (-0.20762 + cx * 0.041194))))) angle += incr result end, beg, dur, snd, chn, edpos, format("%s(%s, %s, %s, %s", get_func_name, rmp0, rmp1, beg, dur)) end def blackman4_env_channel(env, beg = 0, dur = false, snd = false, chn = false, edpos = false) any_env_channel(env, beg, dur, snd, chn, edpos, format("%s(%p, %s, %s", get_func_name, env, beg, dur)) do |r0, r1, b, d, s, c, e| blackman4_ramp(r0, r1, b, d, s, c, e) end end add_help(:ramp_squared, "ramp_squared(rmp0, rmp1, symmetric=true, beg=0, dur=false, \ snd=false, chn=false, edpos=false) \ Connects RMP0 and RMP1 with an x^2 curve.") def ramp_squared(rmp0, rmp1, symmetric = true, beg = 0, dur = false, snd = false, chn = false, edpos = false) angle = 0.0 len = if number?(dur) dur else framples(snd, chn) - beg end incr = 1.0 / len map_channel(lambda do |y| result = y * (rmp0 + angle * angle * (rmp1 - rmp0)) angle += incr result end, beg, dur, snd, chn, edpos, format("%s(%s, %s, %s, %s, %s", get_func_name, rmp0, rmp1, symmetric, beg, dur)) end add_help(:env_squared_channel, "env_squared_channel(env, symmetric=true, beg=0, dur=false, \ snd=false, chn=false, edpos=false) \ Connects ENV's dots with x^2 curves.") def env_squared_channel(env, symmetric = true, beg = 0, dur = false, snd = false, chn = false, edpos = false) any_env_channel(env, beg, dur, snd, chn, edpos, format("%s(%p, %s, %s, %s", get_func_name, env, symmetric, beg, dur)) do |r0, r1, b, d, s, c, e| ramp_squared(r0, r1, symmetric, b, d, s, c, e) end end # env_squared_channel([0, 0, 1, 1, 2, -0.5, 3, 1]) add_help(:ramp_expt, "ramp_expt(rmp0, rmp1, exponent, symmetric=true, beg=0, dur=false, \ snd=false, chn=false, edpos=false) \ Connects RMP0 and RMP1 with an x^exponent curve.") def ramp_expt(rmp0, rmp1, exponent, symmetric = true, beg = 0, dur = false, snd = false, chn = false, edpos = false) angle = 0.0 len = if number?(dur) dur else framples(snd, chn) - beg end incr = 1.0 / len map_channel(lambda do |y| begin result = y * (rmp0 + exp(log(angle) * exponent) * (rmp1 - rmp0)) rescue result = 0.0 end angle += incr result end, beg, dur, snd, chn, edpos, format("%s(%s, %s, %s, %s, %s, %s", get_func_name, rmp0, rmp1, exponent, symmetric, beg, dur)) end add_help(:env_expt_channel, "env_expt_channel(env, exponent, symmetric=true, beg=0, dur=false, \ snd=false, chn=false, edpos=false) \ Connects ENV's dots with x^exponent curves.") def env_expt_channel(env, exponent, symmetric = true, beg = 0, dur = false, snd = false, chn = false, edpos = false) if exponent == 1.0 env_channel(env, beg, dur, snd, chn, edpos) else any_env_channel(env, beg, dur, snd, chn, edpos, format("%s(%p, %s, %s, %s, %s", get_func_name, env, exponent, symmetric, beg, dur)) do |r0, r1, b, d, s, c, e| ramp_expt(r0, r1, exponent, symmetric, b, d, s, c, e) end end end add_help(:offset_channel, "offset_channel(amount, beg=0, dur=false, \ snd=false, chn=false, edpos=false) \ Adds AMOUNT to each sample.") def offset_channel(amount, beg = 0, dur = false, snd = false, chn = false, edpos = false) map_channel(lambda do |y| y + amount end, beg, dur, snd, chn, edpos, format("%s(%s, %s, %s", get_func_name, amount, beg, dur)) end add_help(:offset_sound, "offset_sound(off, beg=0, dur=false, snd=false) \ Adds OFF to every sample in SND.") def offset_sound(off, beg = 0, dur = false, snd = false) snd = Snd.snd(snd) if sound?(snd) channels(snd).times do |chn| offset_channel(off, beg, dur, snd, chn) end else Snd.raise(:no_such_sound, snd) end end add_help(:pad_sound, "pad_sound(beg, dur, snd=false) \ Places a block of DUR zeros in every channel of SND starting at BEG.") def pad_sound(beg, dur, snd = false) snd = Snd.snd(snd) if sound?(snd) channels(snd).times do |chn| pad_channel(beg, dur, snd, chn) end else Snd.raise(:no_such_sound, snd) end end add_help(:dither_channel, "dither_channel(amount=0.00006, beg=0, dur=false, \ snd=false, chn=false, edpos=false) \ Adds AMOUNT dither to each sample.") def dither_channel(amnt = 0.00006, beg = 0, dur = false, snd = false, chn = false, edpos = false) dither = 0.5 * amnt map_channel(lambda do |y| mus_random(dither) + mus_random(dither) + y end, beg, dur, snd, chn, edpos, format("%s(%s, %s, %s", get_func_name, amnt, beg, dur)) end add_help(:dither_sound, "dither_sound(amount=0.00006, beg=0, dur=false, snd=false) \ Adds dithering to every channel of SND.") def dither_sound(amnt = 0.00006, beg = 0, dur = false, snd = false) snd = Snd.snd(snd) if sound?(snd) channels(snd).times do |chn| dither_channel(amnt, beg, dur, snd, chn) end else Snd.raise(:no_such_sound, snd) end end add_help(:contrast_channel, "contrast_channel(index, beg=0, dur=false, \ snd=false, chn=false, edpos=false) \ Applies contrast-enhancement to the sound.") def contrast_channel(index, beg = 0, dur = false, snd = false, chn = false, edpos = false) map_channel(lambda do |y| sin(y * HALF_PI + index * sin(y * TWO_PI)) end, beg, dur, snd, chn, edpos, format("%s(%s, %s, %s", get_func_name, index, beg, dur)) end add_help(:contrast_sound, "contrast_sound(index, beg=0, dur=false, snd=false) \ Applies contrast-enhancement to every channel of SND.") def contrast_sound(index, beg = 0, dur = false, snd = false) snd = Snd.snd(snd) if sound?(snd) channels(snd).times do |chn| contrast_channel(index, beg, dur, snd, chn) end else Snd.raise(:no_such_sound, snd) end end # channels-equal add_help(:channels_eql?, "channels_eql?(s1, c1, s2, c2, diff=0.0) \ Returns true if the two channels \ are the same (within diff) modulo trailing 0's.") def channels_eql?(snd1, chn1, snd2, chn2, allowable_difference = 0.0) if snd1.eql?(snd2) and chn1 == chn2 true else mx1 = maxamp(snd1, chn1) mx2 = maxamp(snd2, chn2) if (mx1 - mx2).abs > allowable_difference false else len1 = framples(snd1, chn1) len2 = framples(snd2, chn2) first_longer = (len1 >= len2) len = first_longer ? len1 : len2 s1 = first_longer ? snd1 : snd2 s2 = first_longer ? snd2 : snd1 c1 = first_longer ? chn1 : chn2 c2 = first_longer ? chn2 : chn1 read2 = make_sampler(0, s2, c2) (not scan_channel(lambda do |y| val = read_sample(read2) (val - y).abs > allowable_difference end, 0, len, s1, c1)) end end end add_help(:channels_equal?, "channels_equal?(s1, c1, s2, c2, diff=0.0) \ Returns true if the two channels are the same (within diff).") def channels_equal?(snd1, chn1, snd2, chn2, allowable_difference = 0.0) len1 = framples(snd1, chn1) len2 = framples(snd2, chn2) if len1 == len2 channels_eql?(snd1, chn1, snd2, chn2, allowable_difference) else false end end # mono->stereo, mono-files->stereo def mono2stereo(new_name, snd1, chn1, snd2, chn2) old_ed1 = edit_position(snd1, chn1) old_ed2 = edit_position(snd2, chn2) ind = new_sound(new_name, :channels, 2, :srate, srate(snd1)) swap_channels(ind, 0, snd1, chn1) swap_channels(ind, 1, snd2, chn2) set_edit_position(old_ed1, snd1, chn1) set_edit_position(old_ed2, snd2, chn2) ind end # mono2stereo("test.snd", 0, 0, 1, 0) def mono_files2stereo(new_name, chan1_name, chan2_name) ind1 = open_sound(chan1_name) ind2 = open_sound(chan2_name) ind3 = mono2stereo(new_name, ind1, 0, ind2, 0) close_sound(ind1) close_sound(ind2) ind3 end # mono_files2stereo("test.snd", "oboe.snd", "pistol.snd") def stereo2mono(orig_snd, chan1_name, chan2_name) old_ed0 = edit_position(orig_snd, 0) old_ed1 = edit_position(orig_snd, 1) chan1 = new_sound(chan1_name, :srate, srate(orig_snd)) chan2 = new_sound(chan2_name, :srate, srate(orig_snd)) swap_channels(orig_snd, 0, chan1, 0) swap_channels(orig_snd, 1, chan2, 0) set_edit_position(old_ed0, orig_snd, 0) set_edit_position(old_ed1, orig_snd, 1) [chan1, chan2] end # stereo2mono(0, "hi1.snd", "hi2.snd") # # === PREFERENCES-DIALOG === # # reopen menu $including_reopen_menu = false # for prefs def with_reopen_menu unless $including_reopen_menu menu = Reopen_menu.new("Reopen") $including_reopen_menu = true $close_hook.add_hook!("prefs-add-to-reopen-menu") do |snd| menu.add_to_reopen_menu(snd) end $open_hook.add_hook!("prefs-check-reopen-menu") do |file| menu.check_reopen_menu(file) end end end class Reopen_menu def initialize(name) @menu_name = name @reopen_menu = add_to_main_menu(name, lambda do | | end) @reopen_names = [] @reopen_max_length = 16 @reopen_empty = "empty" end def add_to_reopen_menu(snd) brief_name = short_file_name(snd) long_name = file_name(snd) unless(@reopen_names.member?(brief_name)) if @reopen_names.member?(@reopen_empty) remove_from_menu(@reopen_menu, @reopen_empty) @reopen_names = [] end add_to_menu(@reopen_menu, brief_name, lambda do | | remove_from_menu(@reopen_menu, brief_name) if File.exist?(long_name) open_sound(long_name) end end, 0) @reopen_names.push(brief_name) if @reopen_names.length > @reopen_max_length remove_from_menu(@reopen_menu, @reopen_names.shift) end end false end def check_reopen_menu(file) brief_name = File.basename(file) if @reopen_names.member?(brief_name) remove_from_menu(@reopen_menu, brief_name) @reopen_names.delete(brief_name) end if @reopen_names.empty? add_to_menu(@reopen_menu, @reopen_empty, lambda do | | end, 0) @reopen_names.push(@reopen_empty) end end end # buffers menu $include_buffers_menu = false # for prefs def with_buffers_menu unless $include_buffers_menu menu = Buffers_menu.new("Buffers") $include_buffers_menu = true $open_hook.add_hook!("prefs-open-buffer") do |file| menu.open_buffer(file) end $close_hook.add_hook!("prefs-close-buffer") do |file| menu.close_buffer(file) end end end class Buffers_menu def initialize(name) @menu_name = name @buffer_menu = add_to_main_menu(name, lambda do | | end) @buffer_names = [] @buffer_empty = "empty" end def open_buffer(file) if @buffer_names.member?(@buffer_empty) remove_from_menu(@buffer_menu, @buffer_empty) @buffer_names = [] end add_to_menu(@buffer_menu, file, lambda do | | if sound?(ind = find_sound(file)) select_sound(ind) end end, -1) @buffer_names.push(file) end def close_buffer(snd) remove_from_menu(@buffer_menu, file_name(snd)) @buffer_names.delete(file_name(snd)) if @buffer_names.empty? add_to_menu(@buffer_menu, @buffer_empty, lambda do | | end, 0) @buffer_names.push(@buffer_empty) end false end end end include Extensions # extensions.rb ends here snd-16.1/libdl.scm0000644000076400007640000000230212502665142012125 0ustar bilbil;;; libdl.scm ;;; ;;; tie the dynamic loader library into the *libdl* environment (require cload.scm) (provide 'libdl.scm) ;; if loading from a different directory, pass that info to C (let ((current-file (port-filename (current-input-port)))) (let ((directory (and (or (char=? (current-file 0) #\/) (char=? (current-file 0) #\~)) (substring current-file 0 (- (length current-file) 9))))) (when (and directory (not (member directory *load-path*))) (set! *load-path* (cons directory *load-path*))) (with-let (rootlet) (require cload.scm)) (when (and directory (not (string-position directory *cload-cflags*))) (set! *cload-cflags* (string-append "-I" directory " " *cload-cflags*))))) (if (not (defined? '*libdl*)) (define *libdl* (with-let (unlet) (set! *libraries* (cons (cons "libdl.scm" (curlet)) *libraries*)) (c-define '((void* dlopen (char* int)) (int dlclose (void*)) (void* dlsym (void* char*)) (char* dlerror (void)) (C-macro (int (RTLD_LAZY RTLD_NOW RTLD_BINDING_MASK RTLD_NOLOAD RTLD_DEEPBIND RTLD_GLOBAL RTLD_LOCAL RTLD_NODELETE)))) "" "dlfcn.h" "" "" "libdl_s7") (curlet)))) *libdl* ;; the loader will return *libdl* snd-16.1/snd-env.c0000644000076400007640000015714212603035272012063 0ustar bilbil#include "snd.h" #if USE_MOTIF #define BIG_DOT_SIZE 10 #define MEDIUM_DOT_SIZE 7 #define LITTLE_DOT_SIZE 4 #else #define BIG_DOT_SIZE 5 #define MEDIUM_DOT_SIZE 3 #define LITTLE_DOT_SIZE 2 #endif static int current_dot_size = BIG_DOT_SIZE; #define MAX_PIXEL 10000 env *free_env(env *e) { if (e) { if (e->data) {free(e->data); e->data = NULL;} free(e); } return(NULL); } env *copy_env(env *e) { if (e) { env *ne; ne = (env *)calloc(1, sizeof(env)); ne->pts = e->pts; ne->data_size = e->pts * 2; ne->data = (mus_float_t *)malloc(ne->data_size * sizeof(mus_float_t)); memcpy((void *)(ne->data), (void *)(e->data), ne->data_size * sizeof(mus_float_t)); ne->base = e->base; return(ne); } return(NULL); } bool envs_equal(env *e1, env *e2) { /* snd-mix.c check for set mix amp env no-op */ int i; if (!e1) return(!e2); if (!e2) return(false); if (e1->pts != e2->pts) return(false); for (i = 0; i < e1->pts * 2; i++) if (e1->data[i] != e2->data[i]) return(false); if (e1->base != e2->base) return(false); /* 1 and 0 are possibilities here */ return(true); } char *env_to_string(env *e) { char *news = NULL; if (e) { int i, j, len; bool first = true; char *expr_buf; len = 4 + (e->pts * 2 * 16); news = (char *)calloc(len, sizeof(char)); #if HAVE_RUBY news[0] = '['; #endif #if HAVE_SCHEME news[0] = '\''; news[1] = '('; #endif #if HAVE_FORTH news[0] = '\''; news[1] = '('; news[2] = ' '; #endif expr_buf = (char *)calloc(PRINT_BUFFER_SIZE, sizeof(char)); for (i = 0, j = 0; i < e->pts; i++, j += 2) { if (fabs(e->data[j + 1]) < .0000001) e->data[j + 1] = 0.0; /* try to get rid of -0.000 */ #if HAVE_RUBY snprintf(expr_buf, PRINT_BUFFER_SIZE, "%s%.3f, %.3f", (first) ? "" : ", ", e->data[j], e->data[j + 1]); #endif #if HAVE_SCHEME || HAVE_FORTH snprintf(expr_buf, PRINT_BUFFER_SIZE, "%s%.3f %.3f", (first) ? "" : " ", e->data[j], e->data[j + 1]); #endif news = mus_strcat(news, expr_buf, &len); first = false; } free(expr_buf); #if HAVE_RUBY news = mus_strcat(news, "]", &len); #endif #if HAVE_SCHEME news = mus_strcat(news, ")", &len); #endif #if HAVE_FORTH news = mus_strcat(news, " )", &len); #endif } else news = mus_strdup(PROC_FALSE); return(news); } env *make_envelope_with_offset_and_scaler(mus_float_t *env_buffer, int len, mus_float_t offset, mus_float_t scaler) { env *e; int i, flen; if (len < 4) flen = 4; else flen = len; if (flen & 1) flen++; e = (env *)calloc(1, sizeof(env)); e->data = (mus_float_t *)calloc(flen, sizeof(mus_float_t)); e->data_size = flen; e->pts = flen / 2; for (i = 0; i < len; i += 2) { e->data[i] = env_buffer[i]; e->data[i + 1] = offset + scaler * env_buffer[i + 1]; } if ((flen == 4) && (len == 2)) /* fixup degenerate envelope */ { e->data[2] = e->data[0] + 1.0; e->data[3] = e->data[1]; } e->base = 1.0; return(e); } static env *make_envelope(mus_float_t *env_buffer, int len) { return(make_envelope_with_offset_and_scaler(env_buffer, len, 0.0, 1.0)); } static void add_point(env *e, int pos, mus_float_t x, mus_float_t y) { int i, j; if (e->pts * 2 == e->data_size) { e->data_size += 16; e->data = (mus_float_t *)realloc(e->data, (e->data_size) * sizeof(mus_float_t)); } for (i = e->pts - 1, j = (e->pts - 1) * 2; i >= pos; i--, j -= 2) { e->data[j + 2] = e->data[j]; e->data[j + 3] = e->data[j + 1]; } e->data[pos * 2] = x; e->data[pos * 2 + 1] = y; e->pts++; } static void move_point(env *e, int pos, mus_float_t x, mus_float_t y) { e->data[pos * 2] = x; e->data[pos * 2 + 1] = y; } static void delete_point(env *e, int pos) { int i, j; for (i = pos, j = pos * 2; i < e->pts - 1; i++, j += 2) { e->data[j] = e->data[j + 2]; e->data[j + 1] = e->data[j + 3]; } e->pts--; } static int place_point(int *cxs, int points, int x, env *e, mus_float_t bx) { int i; for (i = 0; i < points; i++) { if (x == cxs[i]) { /* use true values to disambiguate */ if (e->data[i * 2] > bx) return(i - 1); else return(i); } else { if (x < cxs[i]) return(i - 1); } } return(points); } static int hit_point(int *cxs, int *cys, int points, int x, int y) { /* enved dot size (10) is big enough that we need to search for the closest dot * but I think we can assume that the x's are in order */ int i, cur_i = -1, cur_min_x = MAX_PIXEL, cur_min_y = MAX_PIXEL, lim_x; lim_x = x + current_dot_size; for (i = 0; (i < points) && (cxs[i] <= lim_x); i++) if (((x > (cxs[i] - current_dot_size)) && (x < (cxs[i] + current_dot_size))) && ((y > (cys[i] - current_dot_size)) && (y < (cys[i] + current_dot_size)))) { if (abs(x - cxs[i]) <= cur_min_x) { if (abs(y - cys[i]) < cur_min_y) { cur_i = i; cur_min_x = abs(x - cxs[i]); cur_min_y = abs(y - cys[i]); } } } return(cur_i); } env *default_env(mus_float_t x1, mus_float_t y) { env *e; e = (env *)calloc(1, sizeof(env)); e->data = (mus_float_t *)calloc(4, sizeof(mus_float_t)); e->data_size = 4; e->pts = 2; e->data[0] = 0.0; e->data[1] = y; e->data[2] = x1; e->data[3] = y; e->base = 1.0; return(e); } bool is_default_env(env *e) { if (e == NULL) return(true); if (e->pts != 2) return(false); return((snd_feq(e->data[0], 0.0)) && (snd_feq(e->data[1], 1.0)) && (snd_feq(e->data[2], 1.0)) && (snd_feq(e->data[3], 1.0))); } env_editor *new_env_editor(void) { env_editor *edp; edp = (env_editor *)calloc(1, sizeof(env_editor)); edp->current_xs = (int *)calloc(8, sizeof(int)); edp->current_ys = (int *)calloc(8, sizeof(int)); edp->axis = (axis_info *)calloc(1, sizeof(axis_info)); edp->current_size = 8; edp->env_dragged = false; edp->env_pos = 0; edp->click_to_delete = false; edp->edited = false; edp->clipping = true; edp->in_dB = false; return(edp); } static void env_editor_set_current_point(env_editor *edp, int pos, int x, int y) { if (pos == edp->current_size) { edp->current_size += 8; edp->current_xs = (int *)realloc(edp->current_xs, edp->current_size * sizeof(int)); edp->current_ys = (int *)realloc(edp->current_ys, edp->current_size * sizeof(int)); } edp->current_xs[pos] = x; edp->current_ys[pos] = y; } static short env_editor_grf_y_dB(env_editor *edp, mus_float_t val) { if (edp->in_dB) return(grf_y(in_dB(min_dB(ss), ss->lin_dB, val), edp->axis)); else return(grf_y(val, edp->axis)); } static mus_float_t un_dB(mus_float_t py) { return((py <= min_dB(ss)) ? 0.0 : pow(10.0, py * .05)); } double env_editor_ungrf_y_dB(env_editor *edp, int y) { if (edp->in_dB) return(un_dB(ungrf_y(edp->axis, y))); else return(ungrf_y(edp->axis, y)); } #define EXP_SEGLEN 4 typedef enum {ENVED_ADD_POINT, ENVED_DELETE_POINT, ENVED_MOVE_POINT} enved_point_t; static bool check_enved_hook(env *e, int pos, mus_float_t x, mus_float_t y, enved_point_t reason); /* enved display can call mus_make_env which can throw 'mus-error, so we need local protection */ static mus_error_handler_t *old_error_handler; static void local_mus_error(int type, char *msg) { snd_error_without_format(msg); } void env_editor_display_env(env_editor *edp, env *e, graphics_context *ax, const char *name, int x0, int y0, int width, int height, printing_t printing) { int i; mus_float_t ex0, ey0, ex1, ey1; axis_info *ap; if (e) { ex0 = e->data[0]; ey0 = e->data[1]; ex1 = e->data[(e->pts * 2) - 2]; ey1 = ey0; for (i = 3; i < e->pts * 2; i += 2) { mus_float_t val; val = e->data[i]; if (ey0 > val) ey0 = val; if (ey1 < val) ey1 = val; } if (ey0 > 0.0) ey0 = 0.0; if ((ey0 == ey1) && (ey1 == 0.0)) ey1 = 1.0; /* fixup degenerate case */ if ((edp->with_dots) && (ey1 < 1.0)) ey1 = 1.0; } else { if (edp != ss->enved) return; ex0 = 0.0; ex1 = 1.0; ey0 = 0.0; ey1 = 1.0; } if (edp->in_dB) { ey0 = min_dB(ss); ey1 = 0.0; } if (edp == ss->enved) { /* don't free edp->axis! */ ap = enved_make_axis(name, ax, x0, y0, width, height, ex0, ex1, ey0, ey1, printing); /* ax used only for GC here */ edp->axis = ap; } else { ap = edp->axis; ap->ax = ax; if (edp->with_dots) init_env_axes(ap, name, x0, y0, width, height, ex0, ex1, ey0, ey1, NOT_PRINTING); } if (!(ax->wn)) return; if (e) { int j, dur; mus_float_t curx, xincr; int ix0, ix1, iy0, iy1; ix1 = grf_x(e->data[0], ap); iy1 = env_editor_grf_y_dB(edp, e->data[1]); if (edp->with_dots) { if (e->pts < 50) current_dot_size = BIG_DOT_SIZE; else { if (e->pts < 100) current_dot_size = MEDIUM_DOT_SIZE; else current_dot_size = LITTLE_DOT_SIZE; } env_editor_set_current_point(edp, 0, ix1, iy1); draw_dot(ax, ix1, iy1, current_dot_size); } if (e->base == 1.0) { if (edp->in_dB) { for (j = 1, i = 2; i < e->pts * 2; i += 2, j++) { ix0 = ix1; iy0 = iy1; ix1 = grf_x(e->data[i], ap); iy1 = env_editor_grf_y_dB(edp, e->data[i + 1]); if (edp->with_dots) { env_editor_set_current_point(edp, j, ix1, iy1); draw_dot(ax, ix1, iy1, current_dot_size); } /* now try to fill in from the last point to this one */ if ((ix1 - ix0) < (2 * EXP_SEGLEN)) { /* points are too close to be worth interpolating */ draw_line(ax, ix0, iy0, ix1, iy1); } else { /* interpolate so the display looks closer to dB */ mus_float_t yval, yincr; int lx1, ly1, k; dur = (ix1 - ix0) / EXP_SEGLEN; xincr = (e->data[i] - e->data[i - 2]) / (mus_float_t)dur; curx = e->data[i - 2] + xincr; lx1 = ix0; ly1 = iy0; yval = e->data[i - 1]; yincr = (e->data[i + 1] - yval) / (mus_float_t)dur; yval += yincr; for (k = 1; k < dur; k++, curx += xincr, yval += yincr) { int lx0, ly0; lx0 = lx1; ly0 = ly1; lx1 = grf_x(curx, ap); ly1 = grf_y(in_dB(min_dB(ss), ss->lin_dB, yval), ap); draw_line(ax, lx0, ly0, lx1, ly1); } draw_line(ax, lx1, ly1, ix1, iy1); } } } else { for (j = 1, i = 2; i < e->pts * 2; i += 2, j++) { ix0 = ix1; iy0 = iy1; ix1 = grf_x(e->data[i], ap); iy1 = grf_y(e->data[i + 1], ap); if (edp->with_dots) { env_editor_set_current_point(edp, j, ix1, iy1); draw_dot(ax, ix1, iy1, current_dot_size); } draw_line(ax, ix0, iy0, ix1, iy1); if (printing) ps_draw_line(ap, ix0, iy0, ix1, iy1); } } } else { if (e->base <= 0.0) { for (j = 1, i = 2; i < e->pts * 2; i += 2, j++) { ix0 = ix1; iy0 = iy1; ix1 = grf_x(e->data[i], ap); iy1 = env_editor_grf_y_dB(edp, e->data[i + 1]); if (edp->with_dots) { env_editor_set_current_point(edp, j, ix1, iy1); draw_dot(ax, ix1, iy1, current_dot_size); } draw_line(ax, ix0, iy0, ix1, iy0); draw_line(ax, ix1, iy0, ix1, iy1); if (printing) { ps_draw_line(ap, ix0, iy0, ix1, iy0); ps_draw_line(ap, ix1, iy0, ix1, iy1); } } } else { int index = 0; mus_float_t env_val; mus_any *ce; if (edp->with_dots) for (j = 1, i = 2; i < e->pts * 2; i += 2, j++) env_editor_set_current_point(edp, j, grf_x(e->data[i], ap), grf_y(e->data[i + 1], ap)); /* exponential case */ dur = width / EXP_SEGLEN; old_error_handler = mus_error_set_handler(local_mus_error); ce = mus_make_env(e->data, e->pts, 1.0, 0.0, e->base, 0.0, dur - 1, NULL); mus_error_set_handler(old_error_handler); if (ce == NULL) return; if (dur < e->pts) dur = e->pts; env_val = mus_env(ce); ix1 = grf_x(0.0, ap); iy1 = env_editor_grf_y_dB(edp, env_val); xincr = (ex1 - ex0) / (mus_float_t)dur; for (i = 1, curx = ex0 + xincr; i < dur; i++, curx += xincr) { iy0 = iy1; ix0 = ix1; env_val = mus_env(ce); ix1 = grf_x(curx, ap); iy1 = env_editor_grf_y_dB(edp, env_val); draw_line(ax, ix0, iy0, ix1, iy1); if (printing) ps_draw_line(ap, ix0, iy0, ix1, iy1); if ((edp->with_dots) && (index != mus_position(ce))) { index = mus_position(ce); if (index < (e->pts - 1)) draw_dot(ax, ix1, iy1, current_dot_size); } } if (curx < ex1) { iy0 = iy1; ix0 = ix1; ix1 = grf_x(ex1, ap); iy1 = env_editor_grf_y_dB(edp, e->data[e->pts * 2 - 1]); draw_line(ax, ix0, iy0, ix1, iy1); if (printing) ps_draw_line(ap, ix0, iy0, ix1, iy1); } if (edp->with_dots) draw_dot(ax, ix1, iy1, current_dot_size); mus_free(ce); } } } } void env_editor_button_motion_with_xy(env_editor *edp, int evx, int evy, oclock_t motion_time, env *e, mus_float_t *new_x, mus_float_t *new_y) { axis_info *ap; mus_float_t x0, x1, x, y; if ((e == NULL) || (edp == NULL)) return; if ((motion_time - edp->down_time) < ss->click_time) return; edp->env_dragged = true; edp->click_to_delete = false; ap = edp->axis; x = ungrf_x(ap, evx); if (edp->env_pos > 0) x0 = e->data[edp->env_pos * 2 - 2]; else x0 = e->data[0]; if (edp->env_pos < (e->pts - 1)) x1 = e->data[edp->env_pos * 2 + 2]; /* looking for next point on right to avoid crossing it */ else x1 = e->data[e->pts * 2 - 2]; { mus_float_t dist = 0.0001; if ((x1 - x0) <= dist) dist = (x1 - x0) / 2.0; if (x <= x0) x = x0 + dist; if (x >= x1) x = x1 - dist; } if (edp->env_pos == 0) x = e->data[0]; if (edp->env_pos == (e->pts - 1)) x = e->data[(e->pts - 1) * 2]; y = ungrf_y(ap, evy); if ((edp->clipping) || (edp->in_dB)) { if (y < ap->y0) y = ap->y0; if (y > ap->y1) y = ap->y1; } if (edp->in_dB) y = un_dB(y); if ((edp != ss->enved) || (check_enved_hook(e, edp->env_pos, x, y, ENVED_MOVE_POINT) == 0)) move_point(e, edp->env_pos, x, y); edp->edited = true; if (new_x) (*new_x) = x; if (new_y) (*new_y) = y; } void env_editor_button_motion(env_editor *edp, int evx, int evy, oclock_t motion_time, env *e) { env_editor_button_motion_with_xy(edp, evx, evy, motion_time, e, NULL, NULL); } bool env_editor_button_press(env_editor *edp, int evx, int evy, oclock_t time, env *e) { int pos; mus_float_t x, y; axis_info *ap; ap = edp->axis; edp->down_time = time; edp->env_dragged = false; pos = hit_point(edp->current_xs, edp->current_ys, e->pts, evx, evy); x = ungrf_x(ap, evx); y = env_editor_ungrf_y_dB(edp, evy); if (edp->clipping) { if (y < ap->y0) y = ap->y0; if (y > ap->y1) y = ap->y1; } if (pos == -1) { if (x <= ap->x0) { pos = 0; x = ap->x0; } else { if (x >= ap->x1) { pos = e->pts - 1; x = ap->x1; } } } edp->env_pos = pos; /* if not -1, then user clicked existing point -- wait for drag/release to decide what to do */ if (pos == -1) { pos = place_point(edp->current_xs, e->pts, evx, e, x); /* place returns left point index of current segment or pts if off left end */ /* in this case, user clicked in middle of segment, so add point there */ if ((edp != ss->enved) || (check_enved_hook(e, pos, x, y, ENVED_ADD_POINT) == 0)) add_point(e, pos + 1, x, y); edp->env_pos = pos + 1; edp->click_to_delete = false; } else edp->click_to_delete = true; edp->edited = true; return(pos == -1); } void env_editor_button_release(env_editor *edp, env *e) { if ((edp->click_to_delete) && (!(edp->env_dragged)) && (edp->env_pos > 0) && (edp->env_pos < (e->pts - 1)) && ((edp != ss->enved) || (check_enved_hook(e, edp->env_pos, 0, 0, ENVED_DELETE_POINT) == 0))) delete_point(e, edp->env_pos); prepare_enved_edit(e); edp->env_pos = 0; edp->env_dragged = false; edp->click_to_delete = false; } /* -------- (main) ENVELOPE EDITOR FUNCTIONS -------- */ static int env_list_size = 0; /* current size of env edits list */ static int env_list_top = 0; /* one past current active position in list */ static env **env_list = NULL; /* env edits list (for local undo/redo/revert) */ static env **all_envs = NULL; /* all envs, either loaded or created in editor */ static char **all_names = NULL; /* parallel names */ static int all_envs_size = 0; /* size of this array */ static int all_envs_top = 0; /* one past pointer to last entry in this array */ void init_env_axes(axis_info *ap, const char *name, int x_offset, int ey0, int width, int height, mus_float_t xmin, mus_float_t xmax, mus_float_t ymin, mus_float_t ymax, printing_t printing) { if (ap->xlabel) free(ap->xlabel); ap->xmin = xmin; ap->xmax = xmax; ap->ymin = ymin; ap->ymax = ymax; ap->y_ambit = ap->ymax - ap->ymin; ap->x_ambit = ap->xmax - ap->xmin; ap->xlabel = mus_strdup(name); ap->x0 = xmin; ap->x1 = xmax; ap->y0 = ymin; ap->y1 = ymax; ap->width = width; ap->window_width = width; ap->y_offset = ey0; ap->height = height; ap->graph_x0 = x_offset; make_axes_1(ap, X_AXIS_IN_SECONDS, 1, SHOW_ALL_AXES, printing, WITH_X_AXIS, NO_GRID, WITH_LINEAR_AXES, grid_density(ss)); /* if this is too small for an axis, it still sets up the fields needed for grf_x|y, so tiny envelope graphs will work */ } void view_envs(int env_window_width, int env_window_height, printing_t printing) { /* divide space available into a grid (if needed) that shows all currently defined envelopes */ /* I suppose if there were several hundred envelopes, we'd need a scrollable viewer... */ int cols, rows, i, j, width, height, x, y, k; if (all_envs_top > 1) { cols = snd_round(sqrt((mus_float_t)(all_envs_top * env_window_width) / (mus_float_t)env_window_height)); rows = snd_round((mus_float_t)all_envs_top / (mus_float_t)cols); if ((rows * cols) < all_envs_top) rows++; } else { cols = 1; rows = 1; } width = (int)((mus_float_t)env_window_width / (mus_float_t)cols); height = (int)((mus_float_t)env_window_height / (mus_float_t)rows); k = 0; for (i = 0, x = 0; i < cols; i++, x += width) for (j = 0, y = 0; j < rows; j++, y += height) { display_enved_env_with_selection(all_envs[k], all_names[k], x, y, width, height, 0, printing); k++; if (k == all_envs_top) return; } } int hit_env(int xe, int ye, int env_window_width, int env_window_height) { if (all_envs_top == 0) return(-1); else { if (all_envs_top == 1) return(0); else { int cols, rows, i, j, width, height, x, y, k; cols = snd_round(sqrt((mus_float_t)(all_envs_top * env_window_width) / (mus_float_t)env_window_height)); rows = snd_round((mus_float_t)all_envs_top / (mus_float_t)cols); if ((rows * cols) < all_envs_top) rows++; width = (int)((mus_float_t)env_window_width / (mus_float_t)cols); height = (int)((mus_float_t)env_window_height / (mus_float_t)rows); k = 0; for (i = 0, x = width; i < cols; i++, x += width) if (x > xe) for (j = 0, y = height; j < rows; j++, y += height) { if (y > ye) return(k); k++; } else k += rows; } } return(0); } void prepare_enved_edit(env *new_env) { int i; if (env_list_top == env_list_size) { env_list_size += 16; if (env_list) { env_list = (env **)realloc(env_list, env_list_size * sizeof(env *)); for (i = env_list_top; i < env_list_size; i++) env_list[i] = NULL; } else env_list = (env **)calloc(env_list_size, sizeof(env *)); } /* clear out current edit list above this edit */ for (i = env_list_top; i < env_list_size; i++) env_list[i] = free_env(env_list[i]); env_list[env_list_top] = copy_env(new_env); env_list_top++; } void redo_env_edit(void) { if (env_list) { if ((env_list_top < env_list_size) && (env_list[env_list_top])) { env_list_top++; set_enved_undo_sensitive(true); set_enved_revert_sensitive(true); } if ((env_list_top == env_list_size) || (env_list[env_list_top] == NULL)) set_enved_redo_sensitive(false); set_enved_save_sensitive(true); } } void undo_env_edit(void) { if (env_list) { if (env_list_top > 0) { env_list_top--; set_enved_redo_sensitive(true); } if (env_list_top == 0) { set_enved_undo_sensitive(false); /* set_enved_revert_sensitive(false); */ } set_enved_save_sensitive(true); } } void revert_env_edit(void) { if (env_list) { if (env_list_top > 0) set_enved_redo_sensitive(true); if (env_list_top > 1) env_list_top = 1; else { env_list_top = 0; set_enved_undo_sensitive(false); set_enved_revert_sensitive(false); set_enved_save_sensitive(false); } } } static int find_env(const char *name) { /* -1 upon failure */ int i; if ((all_envs) && (name)) for (i = 0; i < all_envs_top; i++) if (mus_strcmp(name, all_names[i])) return(i); return(-1); } int enved_all_envs_top(void) {return(all_envs_top);} char *enved_all_names(int n) {return(all_names[n]);} void set_enved_env_list_top(int n) {env_list_top = n;} /* env *enved_all_envs(int pos) {return(all_envs[pos]);} */ static void add_envelope(const char *name, env *val) { if (all_envs_top == all_envs_size) { all_envs_size += 16; if (all_envs) { int i; all_envs = (env **)realloc(all_envs, all_envs_size * sizeof(env *)); all_names = (char **)realloc(all_names, all_envs_size * sizeof(char *)); for (i = all_envs_size - 16; i < all_envs_size; i++) {all_names[i] = NULL; all_envs[i] = NULL;} } else { all_envs = (env **)calloc(all_envs_size, sizeof(env *)); all_names = (char **)calloc(all_envs_size, sizeof(char *)); } } all_envs[all_envs_top] = val; if (all_names[all_envs_top]) free(all_names[all_envs_top]); all_names[all_envs_top] = mus_strdup(name); all_envs_top++; if (enved_dialog_is_active()) { set_enved_show_sensitive(true); make_scrolled_env_list(); } } #if 0 void delete_envelope(const char *name) { int pos; pos = find_env(name); if (pos != -1) { int i; if (all_names[pos]) free(all_names[pos]); for (i = pos; i < all_envs_size - 1; i++) { all_envs[i] = all_envs[i + 1]; all_envs[i + 1] = NULL; all_names[i] = all_names[i + 1]; all_names[i + 1] = NULL; } all_envs_top--; if (enved_dialog_is_active()) { if (all_envs_top > 0) set_enved_show_sensitive(true); make_scrolled_env_list(); } } } #endif void alert_envelope_editor(const char *name, env *val) { /* whenever an envelope is defined, we get notification through this function */ int i; if (val == NULL) return; i = find_env(name); if (i != -1) { free_env(all_envs[i]); all_envs[i] = val; } else add_envelope(name, val); } struct enved_fft { mus_long_t size; mus_float_t *data; mus_float_t scale; }; enved_fft *free_enved_fft(enved_fft *ef) { if (ef) { if (ef->data) free(ef->data); ef->data = NULL; free(ef); } return(NULL); } void reflect_enved_fft_change(chan_info *cp) { if ((enved_dialog_is_active()) && (enved_target(ss) == ENVED_SPECTRUM) && (cp == current_channel())) env_redisplay(); } #define DEFAULT_ENVED_MAX_FFT_SIZE 1048576 static mus_long_t enved_max_fft_size = DEFAULT_ENVED_MAX_FFT_SIZE; static enved_fft *make_enved_spectrum(chan_info *cp) { enved_fft *ef; if (cp->edits[cp->edit_ctr]->fft == NULL) cp->edits[cp->edit_ctr]->fft = (enved_fft *)calloc(1, sizeof(enved_fft)); ef = cp->edits[cp->edit_ctr]->fft; if ((ef) && (ef->size == 0)) /* otherwise it is presumably already available */ { mus_long_t i, data_len; mus_float_t data_max = 0.0; snd_fd *sf; data_len = cp->axis->hisamp - cp->axis->losamp; if (data_len > enved_max_fft_size) data_len = enved_max_fft_size; if (data_len == 0) return(NULL); sf = init_sample_read(cp->axis->losamp, cp, READ_FORWARD); if (sf == NULL) return(NULL); ef->size = snd_to_int_pow2(data_len); ef->data = (mus_float_t *)malloc(ef->size * sizeof(mus_float_t)); if (ef->data == NULL) return(NULL); fourier_spectrum(sf, ef->data, ef->size, data_len, NULL, NULL); free_snd_fd(sf); for (i = 0; i < ef->size; i++) if (ef->data[i] > data_max) data_max = ef->data[i]; if (data_max > 0.0) ef->scale = data_max; } return(ef); } static void display_enved_spectrum(chan_info *cp, enved_fft *ef, axis_info *ap) { if (ef) { mus_float_t incr, x = 0.0; int i = 0; mus_long_t hisamp; mus_float_t samples_per_pixel; ap->losamp = 0; ap->hisamp = ef->size - 1; ap->y0 = 0.0; ap->y1 = ef->scale; ap->x0 = 0.0; ap->x1 = snd_srate(cp->sound) / 2; init_axis_scales(ap); hisamp = ef->size / 2; incr = (mus_float_t)snd_srate(cp->sound) / (mus_float_t)(ef->size); samples_per_pixel = (mus_float_t)((double)hisamp / (mus_float_t)(ap->x_axis_x1 - ap->x_axis_x0)); if ((samples_per_pixel < 4.0) && (hisamp < POINT_BUFFER_SIZE)) { for (i = 0, x = 0.0; i < hisamp; i++, x += incr) set_grf_point(grf_x(x, ap), i, grf_y(ef->data[i], ap)); draw_grf_points(1, ap->ax, i, ap, 0.0, GRAPH_LINES); } else { int j = 0; mus_float_t xf = 0.0, ymax; ymax = -1.0; while (i < hisamp) { mus_float_t ina; ina = ef->data[i++]; if (ina > ymax) ymax = ina; xf += 1.0; if (xf > samples_per_pixel) { set_grf_point(grf_x(x, ap), j++, grf_y(ymax, ap)); x += (incr * samples_per_pixel); xf -= samples_per_pixel; ymax = -1.0; } } draw_grf_points(1, ap->ax, j, ap, 0.0, GRAPH_LINES); } } } void enved_show_background_waveform(axis_info *ap, axis_info *gray_ap, bool apply_to_selection, bool show_fft, printing_t printing) { printing_t old_printing; bool two_sided = false; axis_info *active_ap = NULL; chan_info *active_channel = NULL; if (!(any_selected_sound())) return; if ((!gray_ap) || (!ap)) return; gray_ap->x_axis_x0 = ap->x_axis_x0; gray_ap->x_axis_x1 = ap->x_axis_x1; gray_ap->y_axis_y0 = ap->y_axis_y0; gray_ap->y_axis_y1 = ap->y_axis_y1; active_channel = current_channel(); if ((!active_channel) || (active_channel->active < CHANNEL_HAS_AXES) || (active_channel->edits == NULL)) return; old_printing = active_channel->printing; active_channel->printing = printing; if (show_fft) { if (enved_max_fft_size < transform_size(ss)) enved_max_fft_size = transform_size(ss); if (enved_max_fft_size < active_channel->transform_size) enved_max_fft_size = active_channel->transform_size; #if USE_MOTIF /* uses fft_pix etc in chan_info */ if ((active_channel->transform_graph_type == GRAPH_AS_SONOGRAM) && (active_channel->graph_transform_on)) { /* if the sonogram isn't ready, try to get it * this is for frequency envelopes as in animals.scm */ if ((!(active_channel->fft_pix)) || (!(active_channel->fft_pix_ready))) display_channel_fft_data(active_channel); } if ((active_channel->fft_pix) && (active_channel->fft_pix_ready) && (active_channel->transform_graph_type == GRAPH_AS_SONOGRAM) && (active_channel->graph_transform_on)) { int old_x0, old_y0; old_x0 = active_channel->fft_pix_x0; old_y0 = active_channel->fft_pix_y0; /* this actually aligns with the top of the enved window */ active_channel->fft_pix_x0 = ap->x_axis_x0; active_channel->fft_pix_y0 = ap->y_axis_y1; restore_fft_pix(active_channel, gray_ap->ax); active_channel->fft_pix_x0 = old_x0; active_channel->fft_pix_y0 = old_y0; } else display_enved_spectrum(active_channel, make_enved_spectrum(active_channel), gray_ap); #else /* for gtk, we need to redisplay the sonogram? */ #if CAIRO_HAS_RECORDING_SURFACE && (0) /* fprintf(stderr, "%p %d %d %d\n", (active_channel->fft_pix), (active_channel->fft_pix_ready), (active_channel->transform_graph_type == GRAPH_AS_SONOGRAM), (active_channel->graph_transform_on)); */ if ((active_channel->fft_pix) && (active_channel->fft_pix_ready) && (active_channel->transform_graph_type == GRAPH_AS_SONOGRAM) && (active_channel->graph_transform_on)) { cairo_t *lcr, *old_cr; old_cr = ss->cr; lcr = gdk_cairo_create(gray_ap->ax->wn); ss->cr = lcr; cairo_set_source_surface(lcr, active_channel->fft_pix, 0.0, 0.0); cairo_paint(lcr); cairo_destroy(lcr); ss->cr = old_cr; } else #else /* this is not so slow as to be an annoyance, so maybe it's ok */ if ((active_channel->transform_graph_type == GRAPH_AS_SONOGRAM) && (active_channel->graph_transform_on)) { axis_info *old_ap; int x0, x1, y0, y1; old_ap = active_channel->axis; x0 = old_ap->x_axis_x0; x1 = old_ap->x_axis_x1; y0 = old_ap->y_axis_y0; y1 = old_ap->y_axis_y1; active_channel->axis = gray_ap; active_channel->fft->axis->x_axis_x0 = gray_ap->x_axis_x0; active_channel->fft->axis->x_axis_x1 = gray_ap->x_axis_x1; active_channel->fft->axis->y_axis_y0 = gray_ap->y_axis_y0; active_channel->fft->axis->y_axis_y1 = gray_ap->y_axis_y1; make_sonogram(active_channel); active_channel->axis = old_ap; old_ap->x_axis_x0 = x0; old_ap->x_axis_x1 = x1; old_ap->y_axis_y0 = y0; old_ap->y_axis_y1 = y1; } else #endif display_enved_spectrum(active_channel, make_enved_spectrum(active_channel), gray_ap); #endif } else { mus_long_t samps; graph_type_t old_time_graph_type = GRAPH_ONCE; int srate, pts = 0; active_ap = active_channel->axis; if (apply_to_selection) { if (!(selection_is_active())) return; samps = selection_len(); srate = selection_srate(); gray_ap->losamp = selection_beg(NULL); gray_ap->hisamp = gray_ap->losamp + samps - 1; gray_ap->x0 = (double)(gray_ap->losamp) / (double)srate; gray_ap->x1 = (double)(gray_ap->hisamp) / (double)srate; gray_ap->y0 = active_ap->y0; gray_ap->y1 = active_ap->y1; } else { /* show current channel overall view in gray scale */ samps = current_samples(active_channel); srate = snd_srate(active_channel->sound); gray_ap->losamp = 0; gray_ap->hisamp = samps - 1; if (active_channel->time_graph_type == GRAPH_AS_WAVOGRAM) { gray_ap->y0 = -1.0; gray_ap->y1 = 1.0; } else { gray_ap->y0 = active_ap->y0; gray_ap->y1 = active_ap->y1; } gray_ap->x0 = 0.0; gray_ap->x1 = (double)samps / (double)srate; } init_axis_scales(gray_ap); active_channel->axis = gray_ap; old_time_graph_type = active_channel->time_graph_type; active_channel->time_graph_type = GRAPH_ONCE; pts = make_background_graph(active_channel, srate, &two_sided); active_channel->time_graph_type = old_time_graph_type; active_channel->axis = active_ap; if (pts > 0) { if (two_sided) draw_both_grf_points(1, gray_ap->ax, pts, GRAPH_LINES); else draw_grf_points(1, gray_ap->ax, pts, gray_ap, 0.0, GRAPH_LINES); } } active_channel->printing = old_printing; } env *enved_next_env(void) { if (env_list_top > 0) return(copy_env(env_list[env_list_top - 1])); else return(NULL); } char *env_name_completer(widget_t w, const char *text, void *data) { int matches = 0; char *current_match = NULL; if ((all_envs) && (text) && (*text)) { int i, j, len, curlen; len = strlen(text); for (i = 0; i < all_envs_top; i++) if (strncmp(text, all_names[i], len) == 0) { matches++; add_possible_completion(all_names[i]); if (current_match == NULL) current_match = mus_strdup(all_names[i]); else { curlen = strlen(current_match); for (j = 0; j < curlen; j++) if (current_match[j] != all_names[i][j]) { current_match[j] = '\0'; break; } } } } set_completion_matches(matches); if ((current_match) && (*current_match)) return(current_match); return(mus_strdup(text)); } void save_envelope_editor_state(FILE *fd) { int i; for (i = 0; i < all_envs_top; i++) { char *estr; estr = env_to_string(all_envs[i]); if (estr) { #if HAVE_SCHEME fprintf(fd, "(%s %s %s %.4f)\n", S_define_envelope, all_names[i], estr, all_envs[i]->base); #endif #if HAVE_RUBY { char *name; name = xen_scheme_procedure_to_ruby(S_define_envelope); fprintf(fd, "%s(\"%s\", %s, %.4f)\n", name, all_names[i], estr, all_envs[i]->base); free(name); } #endif #if HAVE_FORTH fprintf(fd, "\"%s\" %s %.4f %s drop\n", all_names[i], estr, all_envs[i]->base, S_define_envelope); #endif free(estr); } } } env *xen_to_env(Xen res) { env *rtn = NULL; if (Xen_is_list(res)) { int len = 0; len = Xen_list_length(res); if (len > 0) { int i; mus_float_t *data = NULL; Xen lst; if (Xen_is_number(Xen_car(res))) { data = (mus_float_t *)calloc(len, sizeof(mus_float_t)); for (i = 0, lst = Xen_copy_arg(res); i < len; i++, lst = Xen_cdr(lst)) { Xen el; el = Xen_car(lst); data[i] = Xen_real_to_C_double(el); } } else { /* embedded lists '((0 0) (100 1)) */ if (Xen_is_list(Xen_car(res))) { len *= 2; data = (mus_float_t *)calloc(len, sizeof(mus_float_t)); for (i = 0, lst = Xen_copy_arg(res); i < len; i += 2, lst = Xen_cdr(lst)) { Xen el; el = Xen_car(lst); if ((!(Xen_is_number(Xen_car(el)))) || (!(Xen_is_number(Xen_cadr(el))))) { free(data); return(NULL); } data[i] = Xen_real_to_C_double(Xen_car(el)); data[i + 1] = Xen_real_to_C_double(Xen_cadr(el)); } } else { /* something is screwed up */ return(NULL); } } if (data) { if (len > 1) rtn = make_envelope(data, len); free(data); } } } return(rtn); } static bool x_increases(Xen res) { int i, len; Xen lst; mus_float_t x; len = Xen_list_length(res); x = Xen_real_to_C_double(Xen_car(res)); for (i = 2, lst = Xen_cddr(Xen_copy_arg(res)); i < len; i += 2, lst = Xen_cddr(lst)) { mus_float_t nx; nx = Xen_real_to_C_double(Xen_car(lst)); if (x >= nx) return(false); x = nx; } return(true); } #if (!HAVE_EXTENSION_LANGUAGE) #define ENV_BUFFER_SIZE 128 static int env_buffer_size = 0; static mus_float_t *env_buffer = NULL; static char env_white_space[5] = {' ', '(', ')', '\t', '\''}; #endif env *string_to_env(const char *str) { #if HAVE_EXTENSION_LANGUAGE Xen res; res = snd_catch_any(eval_str_wrapper, (void *)str, "string->env"); if (Xen_is_list(res)) { int len; len = Xen_list_length(res); if ((len % 2) == 0) { if (x_increases(res)) return(xen_to_env(res)); else snd_error("x axis points not increasing: %s", str); } else snd_error("odd length envelope? %s", str); } else snd_error("%s is not a list", str); return(NULL); #else char *tok, *tmp; int i; float f; if ((str) && (*str)) { char *old_tmp; tmp = mus_strdup(str); old_tmp = tmp; i = 0; if (env_buffer_size == 0) { env_buffer_size = ENV_BUFFER_SIZE; env_buffer = (mus_float_t *)calloc(ENV_BUFFER_SIZE, sizeof(mus_float_t)); } if ((*tmp) == '\'') tmp++; if ((*tmp) == '(') tmp++; tok = strtok(tmp, env_white_space); while (tok) { if (!(sscanf(tok, "%f", &f))) { snd_error("%s in env list is not a number", tok); return(NULL); } env_buffer[i] = (mus_float_t)f; i++; if (i == env_buffer_size) { env_buffer_size *= 2; env_buffer = (mus_float_t *)realloc(env_buffer, env_buffer_size * sizeof(mus_float_t)); } tok = strtok(NULL, env_white_space); } if ((i == 0) || (i & 1)) snd_error("odd length envelope? %s", str); free(old_tmp); return(make_envelope(env_buffer, i)); } return(NULL); #endif } env *position_to_env(int pos) { if (pos < 0) return(NULL); return(copy_env(all_envs[pos])); } env *name_to_env(const char *str) { env *e; int pos; if ((!str) || (!(*str))) return(NULL); pos = find_env(str); if (pos >= 0) return(copy_env(all_envs[pos])); #if HAVE_SCHEME || HAVE_FORTH e = xen_to_env(C_string_to_Xen_value(str)); #else e = xen_to_env(Xen_eval_C_string((char *)str)); #endif return(e); } #if HAVE_RUBY #define SND_ENV_MAX_VARS 100 static Xen snd_env_array[SND_ENV_MAX_VARS]; static int env_index = -1; #endif static Xen g_define_envelope(Xen name, Xen data, Xen base) { env *e; const char *ename; #define H_define_envelope "(" S_define_envelope " name data :optional base): load 'name' with associated 'data', a list of breakpoints \ into the envelope editor." Xen_check_type(Xen_is_string(name) || Xen_is_symbol(name), name, 1, S_define_envelope, "a string or symbol"); Xen_check_type(Xen_is_list(data), data, 2, S_define_envelope, "a list of breakpoints"); Xen_check_type(Xen_is_number_or_unbound(base) || Xen_is_false(base), base, 3, S_define_envelope, "a float or " PROC_FALSE); if (Xen_is_string(name)) ename = Xen_string_to_C_string(name); else ename = Xen_symbol_to_C_string(name); e = xen_to_env(data); if (!e) return(Xen_false); if (Xen_is_number(base)) e->base = Xen_real_to_C_double(base); #if HAVE_RUBY { char *name; alert_envelope_editor(name = xen_scheme_global_variable_to_ruby(ename), e); if (env_index >= SND_ENV_MAX_VARS) env_index = 0; else env_index++; Xen_define_variable(ename, snd_env_array[env_index], data); /* need global C variable */ free(name); return(snd_env_array[env_index]); } #endif #if HAVE_SCHEME || HAVE_FORTH { Xen temp; alert_envelope_editor(ename, e); Xen_define_variable(ename, temp, data); /* already gc protected */ return(temp); } #endif #if (!HAVE_EXTENSION_LANGUAGE) return(0); #endif } Xen env_to_xen(env *e) { if (e) return(mus_array_to_list(e->data, 0, e->pts * 2)); return(Xen_empty_list); } void add_or_edit_symbol(const char *name, env *val) { /* called from envelope editor -- pass new definition into scheme */ #if HAVE_RUBY char *buf, *tmpstr = NULL; int len; if (!val) return; tmpstr = env_to_string(val); len = mus_strlen(tmpstr) + mus_strlen(name) + 32; buf = (char *)calloc(len, sizeof(char)); snprintf(buf, len, "%s = %s", name, tmpstr); if (tmpstr) free(tmpstr); snd_catch_any(eval_str_wrapper, buf, buf); free(buf); #endif #if HAVE_SCHEME Xen e; if (!val) return; if (Xen_is_defined(name)) { e = s7_make_symbol(s7, name); Xen_variable_set(e, env_to_xen(val)); } else Xen_define_variable(name, e, env_to_xen(val)); #endif #if HAVE_FORTH if (!val) return; if (Xen_is_defined(name)) Xen_variable_set(name, env_to_xen(val)); else fth_define_variable(name, env_to_xen(val), NULL); #endif } env *get_env(Xen e, const char *origin) /* list in e */ { int i, len = 0; env *new_env; Xen_check_type(Xen_is_list(e), e, 1, origin, "a list"); len = Xen_list_length(e); if (len == 0) Xen_error(NO_DATA, Xen_list_3(C_string_to_Xen_string("~A: null env, ~A"), C_string_to_Xen_string(origin), e)); new_env = xen_to_env(e); if (!new_env) Xen_error(Xen_make_error_type("env-error"), Xen_list_2(C_string_to_Xen_string("envelope break point list is screwed up: ~A"), e)); for (i = 2; i < new_env->pts * 2; i += 2) if (new_env->data[i - 2] > new_env->data[i]) { Xen msg; char *buf; buf = (char *)calloc(1024, sizeof(char)); snprintf(buf, 1024, "%s: env at breakpoint %d: x axis value %f > %f", origin, i / 2, new_env->data[i - 2], new_env->data[i]); msg = C_string_to_Xen_string(buf); free(buf); free_env(new_env); Xen_error(Xen_make_error_type("env-error"), Xen_list_3(C_string_to_Xen_string("~A, ~A"), msg, e)); } return(new_env); } static Xen g_save_envelopes(Xen filename) { #define H_save_envelopes "(" S_save_envelopes " :optional filename): save the envelopes known to the envelope editor in filename" char *name = NULL; Xen_check_type((Xen_is_string(filename) || (Xen_is_false(filename)) || (!Xen_is_bound(filename))), filename, 1, S_save_envelopes, "a string or " PROC_FALSE); if (Xen_is_string(filename)) name = mus_expand_filename(Xen_string_to_C_string(filename)); else name = mus_strdup("envs.save"); if (name) { FILE *fd; fd = FOPEN(name, "w"); if (fd) { save_envelope_editor_state(fd); snd_fclose(fd, name); } free(name); if (!fd) { Xen_error(CANNOT_SAVE, Xen_list_3(C_string_to_Xen_string(S_save_envelopes ": can't save ~S, ~A"), filename, C_string_to_Xen_string(snd_open_strerror()))); } } return(filename); } static Xen enved_hook; static bool check_enved_hook(env *e, int pos, mus_float_t x, mus_float_t y, enved_point_t reason) { if (Xen_hook_has_list(enved_hook)) { Xen result = Xen_false; /* if hook procedure returns a list, that is the new contents of the * envelope -- if its length doesn't match current, we need to remake * current. Otherwise return 0, and assume the caller will handle default */ #if HAVE_SCHEME result = s7_call(s7, enved_hook, Xen_list_5(env_to_xen(e), C_int_to_Xen_integer(pos), C_double_to_Xen_real(x), C_double_to_Xen_real(y), C_int_to_Xen_integer((int)reason))); #else { Xen procs, env_list; env_list = env_to_xen(e); procs = Xen_hook_list(enved_hook); while (!Xen_is_null(procs)) { Xen temp; temp = Xen_apply(Xen_car(procs), Xen_list_5(env_list, C_int_to_Xen_integer(pos), C_double_to_Xen_real(x), C_double_to_Xen_real(y), C_int_to_Xen_integer((int)reason)), S_enved_hook); if (!Xen_is_false(temp)) { result = temp; env_list = temp; } procs = Xen_cdr(procs); } } #endif if (Xen_is_list(result)) { int i, len; Xen lst; len = Xen_list_length(result); if (len > e->data_size) { free(e->data); e->data = (mus_float_t *)calloc(len, sizeof(mus_float_t)); e->data_size = len; } e->pts = len / 2; for (i = 0, lst = Xen_copy_arg(result); i < len; i++, lst = Xen_cdr(lst)) e->data[i] = Xen_real_to_C_double(Xen_car(lst)); return(true); } } return(false); } static Xen g_enved_base(void) {return(C_double_to_Xen_real(enved_base(ss)));} static Xen g_set_enved_base(Xen val) { #define H_enved_base "(" S_enved_base "): envelope editor exponential base value (1.0)" Xen_check_type(Xen_is_number(val), val, 1, S_set S_enved_base, "a number"); set_enved_base(mus_fclamp(0.0, Xen_real_to_C_double(val), 300000.0)); return(C_double_to_Xen_real(enved_base(ss))); } static Xen g_enved_power(void) {return(C_double_to_Xen_real(enved_power(ss)));} static Xen g_set_enved_power(Xen val) { #define H_enved_power "(" S_enved_power "): envelope editor base scale range (9.0^power)" Xen_check_type(Xen_is_number(val), val, 1, S_set S_enved_power, "a number"); set_enved_power(mus_fclamp(0.0, Xen_real_to_C_double(val), 10.0)); return(C_double_to_Xen_real(enved_power(ss))); } static Xen g_enved_clipping(void) {return(C_bool_to_Xen_boolean(enved_clipping(ss)));} static Xen g_set_enved_clipping(Xen on) { #define H_enved_clipping "(" S_enved_clipping "): envelope editor clip button setting; \ if clipping, the motion of the mouse is restricted to the current graph bounds." Xen_check_type(Xen_is_boolean(on), on, 1, S_set S_enved_clipping, "a boolean"); set_enved_clipping(Xen_boolean_to_C_bool(on)); return(C_bool_to_Xen_boolean(enved_clipping(ss))); } static Xen g_enved_style(void) {return(C_int_to_Xen_integer(enved_style(ss)));} static Xen g_set_enved_style(Xen val) { #define H_enved_style "(" S_enved_style "): envelope editor breakpoint connection choice: can \ be " S_envelope_linear ", or " S_envelope_exponential int choice; Xen_check_type(Xen_is_integer(val), val, 1, S_set S_enved_style, S_envelope_linear ", or " S_envelope_exponential); choice = Xen_integer_to_C_int(val); if ((choice == ENVELOPE_LINEAR) || (choice == ENVELOPE_EXPONENTIAL)) { set_enved_style((env_type_t)choice); reflect_enved_style(); } else Xen_out_of_range_error(S_enved_style, 1, val, S_enved_style " should be " S_envelope_linear ", or " S_envelope_exponential); return(val); } static Xen g_enved_target(void) {return(C_int_to_Xen_integer((int)enved_target(ss)));} static Xen g_set_enved_target(Xen val) { int in_n; #define H_enved_target "(" S_enved_target "): determines how the envelope edit envelope is applied; \ choices are " S_enved_amplitude ", " S_enved_srate "(apply to speed), and " S_enved_spectrum "(apply as a filter)." Xen_check_type(Xen_is_integer(val), val, 1, S_set S_enved_target, "an integer"); in_n = Xen_integer_to_C_int(val); if ((in_n < 0) || (in_n > (int)ENVED_SRATE)) Xen_out_of_range_error(S_set S_enved_target, 1, val, S_enved_target " should be " S_enved_amplitude ", " S_enved_srate ", or " S_enved_spectrum); else { enved_target_t n; n = (enved_target_t)in_n; /* there is a huge bug in some versions of g++ that make it necessary to: */ if (in_n < 0) n = ENVED_AMPLITUDE; if (in_n > 2) n = ENVED_SRATE; set_enved_target(n); } return(C_int_to_Xen_integer((int)enved_target(ss))); } static Xen g_enved_with_wave(void) {return(C_bool_to_Xen_boolean(enved_with_wave(ss)));} static Xen g_set_enved_with_wave(Xen val) { #define H_enved_with_wave "(" S_enved_with_wave "): " PROC_TRUE " if the envelope editor is displaying the waveform to be edited" Xen_check_type(Xen_is_boolean(val), val, 1, S_set S_enved_with_wave, "a boolean"); set_enved_with_wave(Xen_boolean_to_C_bool(val)); return(C_bool_to_Xen_boolean(enved_with_wave(ss))); } static Xen g_enved_in_dB(void) {return(C_bool_to_Xen_boolean(enved_in_dB(ss)));} static Xen g_set_enved_in_dB(Xen val) { #define H_enved_in_dB "(" S_enved_in_dB "): " PROC_TRUE " if the envelope editor is using dB" Xen_check_type(Xen_is_boolean(val), val, 1, S_set S_enved_in_dB, "a boolean"); set_enved_in_dB(Xen_boolean_to_C_bool(val)); return(C_bool_to_Xen_boolean(enved_in_dB(ss))); } static Xen g_enved_filter_order(void) {return(C_int_to_Xen_integer(enved_filter_order(ss)));} static Xen g_set_enved_filter_order(Xen val) { #define H_enved_filter_order "(" S_enved_filter_order "): envelope editor's FIR filter order (40)" Xen_check_type(Xen_is_integer(val), val, 1, S_set S_enved_filter_order, "an integer"); set_enved_filter_order(Xen_integer_to_C_int(val)); return(C_int_to_Xen_integer(enved_filter_order(ss))); } static Xen g_enved_dialog(void) { #define H_enved_dialog "(" S_enved_dialog "): start the Envelope Editor" return(Xen_wrap_widget(create_envelope_editor())); } Xen_wrap_no_args(g_enved_base_w, g_enved_base) Xen_wrap_1_arg(g_set_enved_base_w, g_set_enved_base) Xen_wrap_no_args(g_enved_power_w, g_enved_power) Xen_wrap_1_arg(g_set_enved_power_w, g_set_enved_power) Xen_wrap_no_args(g_enved_clipping_w, g_enved_clipping) Xen_wrap_1_arg(g_set_enved_clipping_w, g_set_enved_clipping) Xen_wrap_no_args(g_enved_style_w, g_enved_style) Xen_wrap_1_arg(g_set_enved_style_w, g_set_enved_style) Xen_wrap_no_args(g_enved_target_w, g_enved_target) Xen_wrap_1_arg(g_set_enved_target_w, g_set_enved_target) Xen_wrap_no_args(g_enved_with_wave_w, g_enved_with_wave) Xen_wrap_1_arg(g_set_enved_with_wave_w, g_set_enved_with_wave) Xen_wrap_no_args(g_enved_in_dB_w, g_enved_in_dB) Xen_wrap_1_arg(g_set_enved_in_dB_w, g_set_enved_in_dB) Xen_wrap_no_args(g_enved_filter_order_w, g_enved_filter_order) Xen_wrap_1_arg(g_set_enved_filter_order_w, g_set_enved_filter_order) Xen_wrap_no_args(g_enved_dialog_w, g_enved_dialog) Xen_wrap_1_optional_arg(g_save_envelopes_w, g_save_envelopes) Xen_wrap_3_optional_args(g_define_envelope_w, g_define_envelope) #if HAVE_SCHEME static s7_pointer acc_enved_base(s7_scheme *sc, s7_pointer args) {return(g_set_enved_base(s7_cadr(args)));} static s7_pointer acc_enved_filter_order(s7_scheme *sc, s7_pointer args) {return(g_set_enved_filter_order(s7_cadr(args)));} static s7_pointer acc_enved_power(s7_scheme *sc, s7_pointer args) {return(g_set_enved_power(s7_cadr(args)));} static s7_pointer acc_enved_style(s7_scheme *sc, s7_pointer args) {return(g_set_enved_style(s7_cadr(args)));} static s7_pointer acc_enved_target(s7_scheme *sc, s7_pointer args) {return(g_set_enved_target(s7_cadr(args)));} static s7_pointer acc_enved_with_wave(s7_scheme *sc, s7_pointer args) {return(g_set_enved_with_wave(s7_cadr(args)));} #endif void g_init_env(void) { #define H_enved_amplitude "The value for " S_enved_target " that sets the envelope editor 'amp' button." #define H_enved_spectrum "The value for " S_enved_target " that sets the envelope editor 'flt' button." #define H_enved_srate "The value for " S_enved_target " that sets the envelope editor 'src' button." Xen_define_constant(S_enved_amplitude, ENVED_AMPLITUDE, H_enved_amplitude); Xen_define_constant(S_enved_spectrum, ENVED_SPECTRUM, H_enved_spectrum); Xen_define_constant(S_enved_srate, ENVED_SRATE, H_enved_srate); Xen_define_constant(S_envelope_linear, ENVELOPE_LINEAR, S_enved_style " choice: linear connections between breakpoints"); Xen_define_constant(S_envelope_exponential, ENVELOPE_EXPONENTIAL, S_enved_style " choice: exponential connections between breakpoints"); Xen_define_dilambda(S_enved_base, g_enved_base_w, H_enved_base, S_set S_enved_base, g_set_enved_base_w, 0, 0, 1, 0); Xen_define_dilambda(S_enved_power, g_enved_power_w, H_enved_power, S_set S_enved_power, g_set_enved_power_w, 0, 0, 1, 0); Xen_define_dilambda(S_enved_clipping, g_enved_clipping_w, H_enved_clipping, S_set S_enved_clipping, g_set_enved_clipping_w, 0, 0, 1, 0); Xen_define_dilambda(S_enved_style, g_enved_style_w, H_enved_style, S_set S_enved_style, g_set_enved_style_w, 0, 0, 1, 0); Xen_define_dilambda(S_enved_target, g_enved_target_w, H_enved_target, S_set S_enved_target, g_set_enved_target_w, 0, 0, 1, 0); Xen_define_dilambda(S_enved_with_wave, g_enved_with_wave_w, H_enved_with_wave, S_set S_enved_with_wave, g_set_enved_with_wave_w, 0, 0, 1, 0); Xen_define_dilambda(S_enved_in_dB, g_enved_in_dB_w, H_enved_in_dB, S_set S_enved_in_dB, g_set_enved_in_dB_w, 0, 0, 1, 0); Xen_define_dilambda(S_enved_filter_order, g_enved_filter_order_w, H_enved_filter_order, S_set S_enved_filter_order, g_set_enved_filter_order_w, 0, 0, 1, 0); Xen_define_safe_procedure(S_enved_dialog, g_enved_dialog_w, 0, 0, 0, H_enved_dialog); Xen_define_safe_procedure(S_save_envelopes, g_save_envelopes_w, 0, 1, 0, H_save_envelopes); #if HAVE_SCHEME Xen_define_safe_procedure(S_define_envelope "-1", g_define_envelope_w, 2, 1, 0, H_define_envelope); Xen_eval_C_string("(define-macro (define-envelope a . b) `(define-envelope-1 ',a ,@b))"); #else Xen_define_procedure(S_define_envelope, g_define_envelope_w, 2, 1, 0, H_define_envelope); #endif Xen_define_constant(S_enved_add_point, ENVED_ADD_POINT, S_enved_hook " 'reason' arg when point is added"); Xen_define_constant(S_enved_delete_point, ENVED_DELETE_POINT, S_enved_hook " 'reason' arg when point is deleted"); Xen_define_constant(S_enved_move_point, ENVED_MOVE_POINT, S_enved_hook " 'reason' arg when point is moved"); #if HAVE_SCHEME #define H_enved_hook S_enved_hook " (envelope point x y reason): \ called each time a breakpoint is changed in the envelope editor; \ if it returns a list, that list defines the new envelope, \ otherwise the breakpoint is moved (but not beyond the neighboring \ breakpoint), leaving other points untouched. The kind of change that triggered the hook \ is 'reason' which can be " S_enved_move_point ", " S_enved_delete_point ", \ or " S_enved_add_point ". This hook makes it possible to define attack \ and decay portions in the envelope editor, or use functions such as \ stretch-envelope from env.scm: \n\ (hook-push " S_enved_hook "\n\ (lambda (hook) \n\ ((lambda (env pt x y reason)\n\ (if (= reason " S_enved_move_point ")\n\ (let* ((old-x (list-ref env (* pt 2)))\n\ (new-env (stretch-envelope env old-x x)))\n\ (list-set! new-env (+ (* pt 2) 1) y)\n\ (set! (hook 'result) new-env))))) \n\ (hook 'envelope) (hook 'point) (hook 'x) (hook 'y) (hook 'reason))))" #endif #if HAVE_RUBY #define H_enved_hook S_enved_hook " (env pt new-x new-y reason): \ called each time a breakpoint is changed in the envelope editor; \ if it returns a list, that list defines the new envelope, \ otherwise the breakpoint is moved (but not beyond the neighboring \ breakpoint), leaving other points untouched. The kind of change that triggered the hook \ is 'reason' which can be " S_enved_move_point ", " S_enved_delete_point ", \ or " S_enved_add_point ". This hook makes it possible to define attack \ and decay portions in the envelope editor." #endif #if HAVE_FORTH #define H_enved_hook S_enved_hook " (env pt new-x new-y reason): \ called each time a breakpoint is changed in the envelope editor; \ if it returns a list, that list defines the new envelope, \ otherwise the breakpoint is moved (but not beyond the neighboring \ breakpoint), leaving other points untouched. The kind of change that triggered the hook \ is 'reason' which can be " S_enved_move_point ", " S_enved_delete_point ", \ or " S_enved_add_point ". This hook makes it possible to define attack \ and decay portions in the envelope editor, or use functions such as \ stretch-envelope from env.fth: \n\ " S_enved_hook " lambda: <{ en pt x y reason }>\n\ reason " S_enved_move_point " = if\n\ en old-x en pt 2* list@ x stretch-envelope pt 2* 1+ y list!\n\ else\n\ #f\n\ then\n\ ; add-hook!" #endif enved_hook = Xen_define_hook(S_enved_hook, "(make-hook 'envelope 'point 'x 'y 'reason)", 5, H_enved_hook); /* not 'env as hook arg name! that can confuse clm2xen's optimizer */ ss->enved = new_env_editor(); free(ss->enved->axis); ss->enved->axis = NULL; ss->enved->in_dB = DEFAULT_ENVED_IN_DB; ss->enved->clipping = DEFAULT_ENVED_CLIPPING; #if HAVE_SCHEME s7_symbol_set_access(s7, ss->enved_base_symbol, s7_make_function(s7, "[acc-" S_enved_base "]", acc_enved_base, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->enved_filter_order_symbol, s7_make_function(s7, "[acc-" S_enved_filter_order "]", acc_enved_filter_order, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->enved_power_symbol, s7_make_function(s7, "[acc-" S_enved_power "]", acc_enved_power, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->enved_style_symbol, s7_make_function(s7, "[acc-" S_enved_style "]", acc_enved_style, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->enved_target_symbol, s7_make_function(s7, "[acc-" S_enved_target "]", acc_enved_target, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->enved_with_wave_symbol, s7_make_function(s7, "[acc-" S_enved_with_wave "]", acc_enved_with_wave, 2, 0, false, "accessor")); s7_symbol_set_documentation(s7, ss->enved_base_symbol, "*enved-base*: envelope editor exponential base value (1.0)"); s7_symbol_set_documentation(s7, ss->enved_filter_order_symbol, "*enved-filter-order*: envelope editor's FIR filter order (40)"); s7_symbol_set_documentation(s7, ss->enved_power_symbol, "*enved-power*: envelope editor base scale range (9.0^power)"); s7_symbol_set_documentation(s7, ss->enved_style_symbol, "*enved-style*: envelope editor breakpoint connection choice: envelope-linear or envelope-exponential"); s7_symbol_set_documentation(s7, ss->enved_target_symbol, "*enved-target*: determines how the envelope edit envelope is applied; enved-amplitude etc"); s7_symbol_set_documentation(s7, ss->enved_with_wave_symbol, "*enved-wave?*: #t if the envelope editor is displaying the waveform to be edited"); #endif } snd-16.1/marks.rb0000644000076400007640000004022112434353162011777 0ustar bilbil# marks.rb -- marks.scm --> marks.rb # Translator: Michael Scholz # Created: 05/03/23 02:08:47 # Changed: 14/11/14 07:02:23 # examples of mark-related functions # # module Mark # mark_name2id(name) # move_syncd_marks(sync, diff) # describe_mark(id) # # class Mark_sync # initialize # start_sync # stop_sync # click_to_sync(id) # # syncup(ids) # fit_selection_between_marks(m1, m2) # pad_marks(ids, secs) # play_syncd_marks(sync) # play_between_marks(mark1 = false, mark2 = false) # # class Mark_report # initialize(snd) # report_mark_names_play_hook(size) # report_mark_names_stop_playing_hook(snd) # # report_mark_names # eval_between_marks(&func) # snap_marks # define_selection_via_marks(m1, m2) # snap_mark_to_beat # mark_explode(htype = Mus_next, dformat = Mus_bfloat) # save_mark_properties # mark_click_info(id) # eval_header(sndf) # marks2string(sndf) require "hooks" module Mark # mark_name2id is a global version of find-mark add_help(:mark_name2id, "mark_name2id(name) \ Is like find-mark but searches all currently accessible channels.") def mark_name2id(name) Snd.sounds.each do |snd| channels(snd).times do |chn| if mark?(m = find_mark(name, snd, chn)) return m end end end :no_such_mark end # move_syncd_marks moves all syncd marks together add_help(:move_syncd_marks, "move_syncd_marks(sync, diff) \ Moves all marks sharing sync by diff samples.") def move_syncd_marks(sync, diff) (syncd_marks(sync) or []).each do |m| set_mark_sample(m, mark_sample(m) + diff) end end # describe_mark shows mark history add_help(:describe_mark, "describe_mark(id) \ Returns a description of the movements of mark ID over \ the channel's edit history.") def describe_mark(id) mark_setting = Snd.catch do mark_home(id) end.first if mark_setting == :no_such_mark Snd.sounds.each do |snd| break if array?(mark_setting) channels(snd).times do |chn| break if array?(mark_setting) max_edits = 0 edits(snd, chn).each do |n| max_edits += n end 0.upto(max_edits) do |ed| if (m = marks(snd, chn, ed)) and m.member?(id) mark_setting = [snd, chn] break end end end end end if array?(mark_setting) snd, chn = mark_setting max_edits = 0 edits(snd, chn).each do |n| max_edits += n end descr = [[:mark, id, :sound, snd, short_file_name(snd), :channel, chn]] 0.upto(max_edits) do |ed| if marks(snd, chn, ed).member?(id) descr.push(mark_sample(id, ed)) else descr.push(false) end end descr else Snd.raise(:no_such_mark, id) end end # click marks between start-sync and stop-sync to sync them together # (easier than calling mark-sync over and over by hand) class Mark_sync def initialize @mark_sync_number = 0 end def start_sync @mark_sync_number += 1 end def stop_sync @mark_sync_number = 0 end def click_to_sync(id) mark_sync(id, @mark_sync_number) false end end # ms = Mark_sync.new # $mark_click_hook.add_hook!("marks") do |id| ms.click_to_sync(id) end # syncronize sounds at a given mark add_help(:syncup, "syncup(*ids) \ Pads the channels with zeros so that all the marks in IDS list \ occur at the same time.") def syncup(*args_ids) ids = args_ids.flatten samps = ids.map do |id| mark?(id) and mark_sample(id) end max_samp = samps.max ids.zip(samps) do |id, samp| if samp < max_samp nsamps = max_samp - samp snd, chn = mark_home(id) insert_samples(0, nsamps, Vct.new(nsamps), snd, chn) end end end # fit selection between marks, expanding via granulate (this # needs some tweaking...) add_help(:fit_selection_between_marks, "fit_selection_between_marks(m1, m2) \ Fits (and mixes) the current selection (via granulate) \ between the given marks.") def fit_selection_between_marks(m1, m2) m1_samp = mark_sample(m1) m2_samp = mark_sample(m2) m1_home = mark_home(m1) m2_home = mark_home(m2) if m1_home != m2_home Snd.display("mark %s is in %s[%s] but mark %s is in %s[%s]?", m1, m1_home[0], m1_home[1], m2, m2_home[0], m2_home[1]) else mark_samps = m2_samp - m1_samp selection_samps = selection_framples() reg_data = region2vct reader = make_sampler(m1_samp) gr = make_granulate(:expansion, mark_samps / selection_samps.to_f) inctr = 0 new_data = Vct.new(mark_samps) do next_sample(reader) + granulate(gr, lambda do |dir| if inctr >= selection_samps 0.0 else val = reg_data[inctr] inctr += dir val end end) end free_sampler(reader) vct2channel(new_data, m1_samp, mark_samps, m1_home[0], m1_home[1]) end end # pad_marks inserts silence before each in a list of marks add_help(:pad_marks, "pad_marks(ids, secs) \ Inserts SECS seconds of silence before each mark in IDS.") def pad_marks(ids, secs) silence_length = (secs * srate()).floor silence_samps = Vct.new(silence_length) as_one_edit_rb(get_func_name) do (ids or []).each do |id| samp = [0, mark_sample(id) - 1].max snd, chn = mark_home(id) insert_samples(samp, silence_length, silence_samps, snd, chn) end end end # play_syncd_marks add_help(:play_syncd_marks, "play_syncd_marks(sync) \ Starts playing from all marks sharing SYNC.") def play_syncd_marks(sync) chans = 1 rate = 22050 (syncd_marks(sync) or []).each do |m| snd, chn = mark_home(m) new_player = make_player(snd, chn) add_player(new_player, mark_sample(m)) chans = [chans, chn + 1].max rate = [rate, srate(snd)].max end start_playing(chans, rate) end add_help(:play_between_marks, "play_between_marks(mark1=false, mark2=false) \ Plays the portion between the marks (searching for plausible default marks).") def play_between_marks(mark1 = false, mark2 = false) snd = Snd.snd chn = Snd.chn m1 = if mark1 mark1 else if ms = marks(snd, chn) ret = false ms.each do |m| if mark_sample(m) >= left_sample(snd, chn) ret = m break end end ret else Snd.display("no marks in current window?") false end end m2 = if mark?(m1) if mark2 mark2 else if ms = marks(snd, chn) ret = false ms.each do |m| if mark_sample(m) > mark_sample(m1) ret = m break end end ret else Snd.display("no second mark?") false end end else false end if mark?(m1) and mark?(m2) pos1 = mark_sample(m1) pos2 = mark_sample(m2) beg = [pos1, pos2].min len = [pos1, pos2].max play(mark_home(m1).car, :channel, mark_home(m1).cadr, :start, beg, :end, len) end end class Mark_report def initialize(snd) @snd = snd @marklist = marks(@snd, 0) @samplist = (@marklist or []).map do |m| mark_sample(m) end @samp = 0 end def report_mark_names_play_hook(size) @samp += size if array?(@samplist) and @samp >= @samplist.first snd_print(mark_sample(@marklist.first), @snd) @marklist.unshift @samplist.unshift end end def report_mark_names_stop_playing_hook(snd) snd_print("", snd) $play_hook.remove_hook("report-mark-names-play") $stop_playing_hook.remove_hook("report-mark-names-stop-playing") end end # report_mark_names causes mark names to be posted in the minibuffer as a sound is played add_help(:report_mark_names, "report_mark_names() \ Causes mark names to be printed as they are passed while playing.") def report_mark_names $start_playing_hook.add_hook!("marks.rb") do |snd| rp = Mark_report.new(snd) $stop_playing_hook.add_hook!("report-mark-names-stop-playing") do |s| rp.report_mark_names_stop_playing_hook(s) end $play_hook.add_hook!("report-mark-names-play") do |samps| rp.report_mark_names_play_hook(samps) end end end # eval_between_marks add_help(:eval_between_marks, "eval_between_marks(&func) \ Evaluates FUNC between the leftmost marks; \ FUNC takes one arg, the original sample.") def eval_between_marks(func1 = nil, &func2) func = if block_given? func2 else func1 end if proc?(func) snd = Snd.snd chn = Snd.chn if chn < 0 chn = 0 end if array?(mlist = marks(snd, chn)) and mlist.length > 1 left_samp = left_sample(snd, chn) winl = false mlist.each_with_index do |n, i| if mark_sample(n) > left_samp winl = mlist[i..-1] break end end if array?(winl) and winl.length > 1 beg = mark_sample(winl[0]) len = mark_sample(winl[1]) - beg old_data = channel2vct(beg, len, snd, chn) new_data = Vct.new(len) do |i| func.call(old_data[i]) end vct2channel(new_data, beg, len, snd, chn) end else snd_print("need 2 marks") end end end # bind_key(?m, 0, # lambda do | | # prompt_in_minibuffer("mark eval:", eval_between_marks) # end) # snap_marks add_help(:snap_marks, "snap_marks() \ Places marks at current selection boundaries.") def snap_marks if selection? selection_members.each do |snd, chn| pos = selection_position(snd, chn) len = selection_framples(snd, chn) add_mark(pos, snd, chn) add_mark(pos + len, snd, chn) end end end # define_selection_via_marks add_help(:define_selection_via_marks, "define_selection_via_marks(m1, m2) \ Defines the current selection to lie between the marks given.") def define_selection_via_marks(m1, m2) m1sc = mark_home(m1) m2sc = mark_home(m2) if m1sc.eql?(m2sc) beg = [mark_sample(m1), mark_sample(m2)].min fin = [mark_sample(m1), mark_sample(m2)].max snd, chn = m1sc if selection? set_selection_member?(false, true) end set_selection_member?(true, snd, chn) set_selection_position(beg, snd, chn) set_selection_framples(fin - beg + 1, snd, chn) else Snd.raise(:snd_error, "define_selection_via_marks assumes the marks are \ in the same channel") end end # snap_mark_to_beat add_help(:snap_mark_to_beat, "snap_mark_to_beat() \ Ensures that when a mark is dragged, \ its released position is always on a beat.") def snap_mark_to_beat mark_release = 4 $mark_hook.add_hook!(get_func_name) do |m, snd, chn, reason| if reason == mark_release samp = mark_sample(m) bps = beats_per_minute(snd, chn) / 60.0 sr = srate(snd) beat = ((samp * bps) / sr).floor.to_f lower = ((beat * sr) / bps).floor higher = (((beat + 1.0) * sr) / bps).floor set_mark_sample(m, if (samp - lower) < (higher - samp) lower else higher end) end end end # mark_explode # write out each section of a file between marks as a separate file add_help(:mark_explode, "mark_explode(header_type=Mus_next, data_format=Mus_bfloat) \ Splits a sound into a bunch of sounds based on mark placements.") def mark_explode(htype = Mus_next, dformat = Mus_bfloat) start = 0 file_ctr = 0 snd = Snd.snd if marks(snd) marks(snd).first.each do |m| last = mark_sample(m) if last > start filename = format("mark-%d.snd", file_ctr) file_ctr += 1 channels(snd).times do |chn| set_selection_member?(true, snd, chn) set_selection_position(start, snd, chn) set_selection_framples(last - start, snd, chn) end save_selection(filename, :header_type, htype, :sample_type, dformat, :srate, srate(snd)) channels(snd).times do |chn| set_selection_member?(false, snd, chn) end end start = last end end update_time_graph(snd) end # # === Mark Properties === # add_help(:save_mark_properties, "save_mark_properties() \ Sets up an $after_save_state_hook function to save any mark-properties.") def save_mark_properties $after_save_state_hook.add_hook!(get_func_name) do |fname| File.open(File.expand_path(fname), "a+") do |f| f.printf("\n# from %s in %s\n", get_func_name, __FILE__) f.printf("require \"marks.rb\"\n") (marks or []).each do |snds| (snds or []).each do |chns| (chns or []).each do |m| if mp = mark_properties(m) snd, chn = mark_home(m) msamp = mark_sample(m) f.printf("if sound?(snd = find_sound(%s))\n", file_name(snd).inspect) f.printf(" if mark?(m = find_mark(%d, snd, %d))\n", msamp, chn) f.printf(" set_mark_properties(m, %p)\n", mp) f.printf(" end\n") f.printf("end\n") end end end end end end end # # === Mark Click Info === # add_help(:mark_click_info, "mark_click_info(n) \ Is a $mark_click_hook function that describes a mark and its properties.") def mark_click_info(id) Snd.raise(:no_such_mark, id) unless mark?(id) mname = mark_name(id) mnamestr = "" if mname mnamestr = format("\n mark name: %p", mname) end msamp = mark_sample(id) msync = mark_sync(id) msyncstr = "" if msync.nonzero? msyncstr = format("\n sync: %d", msync) end props = mark_properties(id) propstr = "" if props propstr = format("\n properties: %p", props) end info_dialog("Mark info", format("\ mark id: %s%s sample: %d (%1.3f secs)%s%s", id, mnamestr, msamp, msamp / srate(mark_home(id)[0]).to_f, msyncstr, propstr)) true end # this code saves mark info in the sound file header, and reads it # back in when the sound is later reopened def marks2string(sndf) str = "require \"marks\"\n" (marks(sndf) or []).each_with_index do |chan_marks, chn| (chan_marks or []).each do |m| str += format("m = add_mark(%s, false, %d, %s, %d)\n", mark_sample(m), chn, mark_name(m).null? ? false : mark_name(m).inspect, mark_sync(m)) if props = mark_properties(m) str += format("set_mark_properties(m, %s)\n", props.inspect) end end end str end # $output_comment_hook.add_hook!("marks2string") do |str| # marks2string(selected_sound()) # end # $after_open_hook.add_hook!("marks2string") do |snd| # if string?(str = comment(snd)) # Snd.catch do eval(str, TOPLEVEL_BINDING, "(eval-header)", 1) end.first # end # end end include Mark # marks.rb ends here snd-16.1/fmviolin.clm0000644000076400007640000037165012306421670012670 0ustar bilbil;; translated from sambox form 12-June-06 (with-sound (:reverb jc-reverb :channels 2) (fm-violin 0.0 1.6 164.5868 0.02 :fm-index 2.1087 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 6.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 2.9945374e-4 4 164.5868 0.0325 :fm-index 1.5488 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 6.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 4.9972534e-4 1.2 125.9513 0.0325 :fm-index 2.2999 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 6.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 4.9972534e-4 2.8 125.9513 0.02 :fm-index 1.6818 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 6.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 0.0013008118 4 24.4994 0.0375 :fm-index 2.4557 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 6.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 0.0032997131 3 24.4994 0.0375 :fm-index 1.9387 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 6.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 0.0034999847 2.8 24.4994 0.0325 :fm-index 2.3828 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 6.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 0.00399971 0.8 24.4994 0.02 :fm-index 1.7348 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 6.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 0.004299164 4 24.4994 0.0375 :fm-index 2.0886 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 6.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 6.0002995 1.2 88.8854 0.02 :fm-index 2.0711 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 6.0002995 4 88.8854 0.0325 :fm-index 2.0225 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 6.0004997 1.2 102.7186 0.0325 :fm-index 1.93 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 6.0009995 1.2 32.7025 0.045 :fm-index 1.9269 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 6.001499 2.8 32.7025 0.0325 :fm-index 2.2153 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 6.0023003 2 32.7025 0.0325 :fm-index 2.1968 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 6.0023003 4 32.7025 0.045 :fm-index 1.6091 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 6.0025005 2 32.7025 0.0325 :fm-index 2.1766 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 6.0035 1.2 32.7025 0.02 :fm-index 1.5157 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 6.0039997 0.8 32.7025 0.02 :fm-index 1.8092 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 6.004299 2 32.7025 0.0325 :fm-index 1.6198 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 12.000301 1.2 177.7708 0.0375 :fm-index 1.9631 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.2) (fm-violin 12.000301 4 177.7708 0.0375 :fm-index 1.9647 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.2) (fm-violin 12.0005 2.8 336.2471 0.02 :fm-index 2.3977 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.2) (fm-violin 12.000801 1.2 336.2471 0.03125 :fm-index 2.4103 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.2) (fm-violin 12.000999 2 65.405 0.0375 :fm-index 1.8419 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.2) (fm-violin 12.0033 2 65.405 0.0375 :fm-index 2.454 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.2) (fm-violin 12.004299 4 65.405 0.02 :fm-index 2.2909 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.2) (fm-violin 18.000301 1.2 11.1107 0.0375 :fm-index 1.8715 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 18.000301 4 11.1107 0.0375 :fm-index 2.459 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 18.0005 2.8 21.0154 0.02 :fm-index 2.3802 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 18.000801 1.2 21.0154 0.03125 :fm-index 1.7564 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 18.001 2 4.0878 0.0375 :fm-index 2.2529 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 18.0033 2 4.0878 0.0375 :fm-index 1.9693 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 18.0043 4 4.0878 0.02 :fm-index 2.2534 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 24.0 5.4 116.54 0.03125 :fm-index 2.2822 :amp-env '(0 0 0.0556 1 4.0937 0.6 9.1414 0.3 24.2845 0.1 100.0 0) :noise-amount 0.1 :reverb-amount 0.028) (fm-violin 24.009998 5.4 43.6538 0.03125 :fm-index 2.0867 :amp-env '(0 0 0.0556 1 4.0937 0.6 9.1414 0.3 24.2845 0.1 100.0 0) :noise-amount 0.1 :reverb-amount 0.0202) (fm-violin 24.02 5.4 130.81 0.03125 :fm-index 1.9652 :amp-env '(0 0 0.0556 1 4.0937 0.6 9.1414 0.3 24.2845 0.1 100.0 0) :noise-amount 0.1 :reverb-amount 0.027) (fm-violin 24.025002 5.4 87.3075 0.03125 :fm-index 2.1524 :amp-env '(0 0 0.0556 1 4.0937 0.6 9.1414 0.3 24.2845 0.1 100.0 0) :noise-amount 0.1 :reverb-amount 0.026) (fm-violin 24.029999 4.5 261.62 0.01875 :fm-index 2.1384 :amp-env '(0 0 0.0667 1 4.1044 0.6 9.1515 0.3 24.2929 0.1 100 0) :noise-amount 0.1 :reverb-amount 0.0242) (fm-violin 24.029999 4.5 174.615 0.01875 :fm-index 2.1425 :amp-env '(0 0 0.0667 1 4.1044 0.6 9.1515 0.3 24.2929 0.1 100 0) :noise-amount 0.1 :reverb-amount 0.0265) (fm-violin 24.029999 4.5 130.81 0.01875 :fm-index 1.9805 :amp-env '(0 0 0.0667 1 4.1044 0.6 9.1515 0.3 24.2929 0.1 100 0) :noise-amount 0.1 :reverb-amount 0.0201) (fm-violin 24.035 4.5 43.6538 0.01875 :fm-index 2.4876 :amp-env '(0 0 0.0667 1 4.1044 0.6 9.1515 0.3 24.2929 0.1 100 0) :noise-amount 0.1 :reverb-amount 0.0329) (fm-violin 24.04 3.6 220 0.01875 :fm-index 1.8282 :amp-env '(0 0 0.0833 1 4.1204 0.6 9.1667 0.3 24.3056 0.1 100.0 0) :noise-amount 0.15 :reverb-amount 0.0244) (fm-violin 24.04 3.6 174.615 0.01875 :fm-index 2.3479 :amp-env '(0 0 0.0833 1 4.1204 0.6 9.1667 0.3 24.3056 0.1 100.0 0) :noise-amount 0.15 :reverb-amount 0.02) (fm-violin 24.04 3.6 523.24 0.01875 :fm-index 1.6424 :amp-env '(0 0 0.0833 1 4.1204 0.6 9.1667 0.3 24.3056 0.1 100.0 0) :noise-amount 0.15 :reverb-amount 0.0286) (fm-violin 24.044998 3.6 349.23 0.01875 :fm-index 1.6449 :amp-env '(0 0 0.0833 1 4.1204 0.6 9.1667 0.3 24.3056 0.1 100.0 0) :noise-amount 0.15 :reverb-amount 0.0333) (fm-violin 24.05 6 699.46 0.01875 :fm-index 1.557 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.1 :reverb-amount 0.13) (fm-violin 24.05 6 1397.92 0.01875 :fm-index 1.5131 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.1 :reverb-amount 0.13) (fm-violin 24.05 6 783.98 0.01875 :fm-index 2.2031 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.1 :reverb-amount 0.13) (fm-violin 24.05 6 1046.48 0.01875 :fm-index 2.2724 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.1 :reverb-amount 0.13) (fm-violin 24.060001 9 21.8269 0.01875 :fm-index 2.1048 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.1 :reverb-amount 0.1) (fm-violin 24.060001 8 87.3075 0.01875 :fm-index 1.8854 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.1 :reverb-amount 0.1) (fm-violin 24.060001 7 65.405 0.01875 :fm-index 1.6781 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.1 :reverb-amount 0.1) (fm-violin 24.060001 8 43.6538 0.01875 :fm-index 1.7862 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.1 :reverb-amount 0.1) (fm-violin 24.07 6 175.615 0.01875 :fm-index 2.2656 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.1 :reverb-amount 0.1) (fm-violin 24.07 6 350.23 0.01875 :fm-index 2.4241 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.1 :reverb-amount 0.1) (fm-violin 24.07 6 131.81 0.01875 :fm-index 2.4294 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.1 :reverb-amount 0.1) (fm-violin 24.07 6 32.7025 0.01875 :fm-index 1.5779 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.1 :reverb-amount 0.1) (fm-violin 24.080002 6 196.995 0.01875 :fm-index 1.8511 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.1 :reverb-amount 0.1) (fm-violin 24.080002 6 1047.48 0.01875 :fm-index 2.2148 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.1 :reverb-amount 0.1) (fm-violin 24.080002 6 831.62 0.01875 :fm-index 1.9913 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.1 :reverb-amount 0.1) (fm-violin 24.080002 6 2793.84 0.01875 :fm-index 2.2607 :fm2-rat 1.0 :fm3-rat 1.0 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.1 :reverb-amount 0.1) (fm-violin 24.27 6 784.98 0.02 :fm-index 2.0693 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.1 :reverb-amount 0.1) (fm-violin 24.27 6 64.405 0.02 :fm-index 1.692 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.1 :reverb-amount 0.1) (fm-violin 24.27 6 208.655 0.02 :fm-index 2.2597 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.1 :reverb-amount 0.1) (fm-violin 24.27 6 43.6538 0.02 :fm-index 2.2522 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.1 :reverb-amount 0.1) (fm-violin 36.0 1.8 349.23 0.02 :fm-index 2.1541 :amp-env '(0 0 0.1667 1 4.2003 0.6 9.2424 0.3 24.3687 0.1 100 0) :noise-amount 0.05 :reverb-amount 0.0225) (fm-violin 36.01 2.7 146.83 0.02 :fm-index 2.3335 :amp-env '(0 0 0.1111 1 4.147 0.6 9.1919 0.3 24.3266 0.1 100.0 0) :noise-amount 0.05 :reverb-amount 0.0274) (fm-violin 36.02 1.8 880 0.02 :fm-index 2.191 :amp-env '(0 0 0.1667 1 4.2003 0.6 9.2424 0.3 24.3687 0.1 100 0) :noise-amount 0.05 :reverb-amount 0.0279) (fm-violin 36.025 3.6 73.415 0.02 :fm-index 2.141 :amp-env '(0 0 0.0833 1 4.1204 0.6 9.1667 0.3 24.3056 0.1 100.0 0) :noise-amount 0.05 :reverb-amount 0.0223) (fm-violin 36.03 2.7 87.3075 0.02 :fm-index 1.8491 :amp-env '(0 0 0.1111 1 4.147 0.6 9.1919 0.3 24.3266 0.1 100.0 0) :noise-amount 0.001 :reverb-amount 0.0217) (fm-violin 36.03 2.7 75.5662 0.02 :fm-index 1.9191 :amp-env '(0 0 0.1111 1 4.147 0.6 9.1919 0.3 24.3266 0.1 100.0 0) :noise-amount 0.001 :reverb-amount 0.0204) (fm-violin 36.04 3.6 52.3432 0.02 :fm-index 1.609 :amp-env '(0 0 0.0833 1 4.1204 0.6 9.1667 0.3 24.3056 0.1 100.0 0) :noise-amount 0.001 :reverb-amount 0.0296) (fm-violin 36.045 1.8 73.415 0.02 :fm-index 2.2201 :amp-env '(0 0 0.1667 1 4.2003 0.6 9.2424 0.3 24.3687 0.1 100 0) :noise-amount 0.001 :reverb-amount 0.0221) (fm-violin 36.05 4 116.54 0.0075 :fm-index 2.023 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.001 :reverb-amount 0.1) (fm-violin 36.05 4 97.9975 0.0075 :fm-index 1.7284 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.001 :reverb-amount 0.1) (fm-violin 36.06 4 36.7075 0.0075 :fm-index 1.6845 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.001 :reverb-amount 0.1) (fm-violin 36.065 4 97.9975 0.0075 :fm-index 2.4616 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.001 :reverb-amount 0.1) (fm-violin 43.0 1.8 261.62 0.02 :fm-index 2.2576 :amp-env '(0 0 0.1667 1 4.2003 0.6 9.2424 0.3 24.3687 0.1 100 0) :noise-amount 0.01 :reverb-amount 0.0286) (fm-violin 43.010002 2.7 130.81 0.02 :fm-index 2.153 :amp-env '(0 0 0.1111 1 4.147 0.6 9.1919 0.3 24.3266 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.033) (fm-violin 43.019997 1.8 523.24 0.02 :fm-index 2.0608 :amp-env '(0 0 0.1667 1 4.2003 0.6 9.2424 0.3 24.3687 0.1 100 0) :noise-amount 0.01 :reverb-amount 0.0235) (fm-violin 43.025 3.6 65.405 0.02 :fm-index 2.2203 :amp-env '(0 0 0.0833 1 4.1204 0.6 9.1667 0.3 24.3056 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0234) (fm-violin 43.03 2.7 65.405 0.02 :fm-index 1.7089 :amp-env '(0 0 0.1111 1 4.147 0.6 9.1919 0.3 24.3266 0.1 100.0 0) :noise-amount 0.001 :reverb-amount 0.0208) (fm-violin 43.03 2.7 130.81 0.02 :fm-index 2.2948 :amp-env '(0 0 0.1111 1 4.147 0.6 9.1919 0.3 24.3266 0.1 100.0 0) :noise-amount 0.001 :reverb-amount 0.0269) (fm-violin 43.04 3.6 32.7025 0.02 :fm-index 1.7677 :amp-env '(0 0 0.0833 1 4.1204 0.6 9.1667 0.3 24.3056 0.1 100.0 0) :noise-amount 0.001 :reverb-amount 0.0288) (fm-violin 43.045 1.8 32.7025 0.02 :fm-index 1.903 :amp-env '(0 0 0.1667 1 4.2003 0.6 9.2424 0.3 24.3687 0.1 100 0) :noise-amount 0.001 :reverb-amount 0.0209) (fm-violin 43.050003 4 65.405 0.0075 :fm-index 2.2757 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.001 :reverb-amount 0.1) (fm-violin 43.050003 4 65.405 0.0075 :fm-index 2.2435 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.001 :reverb-amount 0.1) (fm-violin 43.059998 4 32.7025 0.0075 :fm-index 1.9619 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.001 :reverb-amount 0.1) (fm-violin 43.065002 4 65.405 0.0075 :fm-index 2.0207 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.001 :reverb-amount 0.1) (fm-violin 49.010002 0.9 3135.92 0.02 :fm-index 2.1204 :fm2-rat 1.0 :fm3-rat 1.0 :amp-env '(0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.495 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0024) (fm-violin 49.010002 0.45 1567.96 0.02 :fm-index 2.0691 :amp-env '(0 0 0.6667 1 4.6801 0.6 9.697 0.3 24.7475 0.1 100 0) :noise-amount 0.01 :reverb-amount 0.0025) (fm-violin 49.019997 0.9 6271.84 0.02 :fm-index 2.2081 :fm2-rat 1.0 :fm3-rat 1.0 :amp-env '(0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.495 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0022) (fm-violin 49.025 0.9 783.98 0.02 :fm-index 1.8719 :amp-env '(0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.495 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0022) (fm-violin 49.03 0.27 783.98 0.02 :fm-index 1.9705 :amp-env '(0 0 1.1111 1 5.1066 0.6 10.101 0.3 25.0842 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.002) (fm-violin 49.03 0.63 1567.96 0.02 :fm-index 1.6778 :amp-env '(0 0 0.4762 1 4.4974 0.6 9.5238 0.3 24.6032 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0021) (fm-violin 49.04 0.9 391.99 0.02 :fm-index 1.9558 :amp-env '(0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.495 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0023) (fm-violin 49.045 0.45 195.995 0.02 :fm-index 2.1344 :amp-env '(0 0 0.6667 1 4.6801 0.6 9.697 0.3 24.7475 0.1 100 0) :noise-amount 0.01 :reverb-amount 0.0027) (fm-violin 49.050003 2 783.98 0.02 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.009) (fm-violin 49.050003 1 1567.96 0.02 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.009) (fm-violin 49.059998 2 391.99 0.02 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.009) (fm-violin 49.065002 1 783.98 0.02 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.009) (fm-violin 49.07 2 195.995 0.02 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.004) (fm-violin 49.07 1 1567.96 0.02 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.004) (fm-violin 49.08 1 784.98 0.02 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.004) (fm-violin 49.085 2 391.99 0.02 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.004) (fm-violin 55.010002 0.9 97.9975 0.0125 :fm-index 2.0885 :amp-env '(0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.495 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0031) (fm-violin 55.010002 1.8 48.9988 0.0125 :fm-index 2.2269 :amp-env '(0 0 0.1667 1 4.2003 0.6 9.2424 0.3 24.3687 0.1 100 0) :noise-amount 0.01 :reverb-amount 0.0026) (fm-violin 55.019997 0.9 195.995 0.0125 :fm-index 2.0305 :amp-env '(0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.495 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0032) (fm-violin 55.025 0.9 24.4994 0.0125 :fm-index 2.4934 :amp-env '(0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.495 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0025) (fm-violin 55.03 1.8 97.9975 0.0125 :fm-index 2.4039 :amp-env '(0 0 0.1667 1 4.2003 0.6 9.2424 0.3 24.3687 0.1 100 0) :noise-amount 0.04 :reverb-amount 0.0023) (fm-violin 55.03 0.9 195.995 0.0125 :fm-index 1.5159 :amp-env '(0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.495 0.1 100.0 0) :noise-amount 0.04 :reverb-amount 0.0021) (fm-violin 55.03 0.9 392.99 0.0125 :fm-index 2.2122 :amp-env '(0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.495 0.1 100.0 0) :noise-amount 0.04 :reverb-amount 0.0028) (fm-violin 55.03 1.8 784.98 0.0125 :fm-index 2.1574 :amp-env '(0 0 0.1667 1 4.2003 0.6 9.2424 0.3 24.3687 0.1 100 0) :noise-amount 0.04 :reverb-amount 0.002) (fm-violin 55.03 2.7 24.4994 0.0125 :fm-index 2.1963 :amp-env '(0 0 0.1111 1 4.147 0.6 9.1919 0.3 24.3266 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0031) (fm-violin 55.03 1.8 48.9988 0.0125 :fm-index 1.9761 :amp-env '(0 0 0.1667 1 4.2003 0.6 9.2424 0.3 24.3687 0.1 100 0) :noise-amount 0.01 :reverb-amount 0.0032) (fm-violin 55.04 2.7 12.2497 0.0125 :fm-index 1.5088 :amp-env '(0 0 0.1111 1 4.147 0.6 9.1919 0.3 24.3266 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0021) (fm-violin 55.045 1.8 6.1248 0.0125 :fm-index 1.7384 :amp-env '(0 0 0.1667 1 4.2003 0.6 9.2424 0.3 24.3687 0.1 100 0) :noise-amount 0.01 :reverb-amount 0.0021) (fm-violin 55.050003 2 24.4994 0.0125 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.004 :reverb-amount 0.1) (fm-violin 55.050003 1 48.9988 0.0125 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.004 :reverb-amount 0.1) (fm-violin 55.059998 2 12.2497 0.0125 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.004 :reverb-amount 0.1) (fm-violin 55.065002 1 24.4994 0.0125 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.004 :reverb-amount 0.1) (fm-violin 55.07 2 6.1248 0.0125 :fm-index 1.2474 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.004 :reverb-amount 0.1) (fm-violin 55.07 1 48.9988 0.0125 :fm-index 0.7526 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.004 :reverb-amount 0.1) (fm-violin 55.08 1 25.4994 0.0125 :fm-index 1.108 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.004 :reverb-amount 0.1) (fm-violin 55.085 2 12.2497 0.0125 :fm-index 1.0859 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.004 :reverb-amount 0.1) (fm-violin 55.089996 4 97.9975 0.0125 :fm-index 2.4788 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.004 :reverb-amount 0.1) (fm-violin 55.089996 3 48.9988 0.0125 :fm-index 1.898 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.004 :reverb-amount 0.1) (fm-violin 55.089996 3 25.4994 0.0125 :fm-index 2.1151 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.004 :reverb-amount 0.1) (fm-violin 55.095 5 12.2497 0.0125 :fm-index 2.3224 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.004 :reverb-amount 0.1) (fm-violin 61.21 0.9 123.4725 0.0125 :amp-env '(0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.495 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0031) (fm-violin 61.21 1.8 61.7363 0.0125 :amp-env '(0 0 0.1667 1 4.2003 0.6 9.2424 0.3 24.3687 0.1 100 0) :noise-amount 0.01 :reverb-amount 0.0023) (fm-violin 61.22 0.9 246.945 0.0125 :amp-env '(0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.495 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0023) (fm-violin 61.225 0.9 30.8681 0.0125 :amp-env '(0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.495 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0026) (fm-violin 61.230003 1.8 123.4725 0.0125 :amp-env '(0 0 0.1667 1 4.2003 0.6 9.2424 0.3 24.3687 0.1 100 0) :noise-amount 0.04 :reverb-amount 0.0027) (fm-violin 61.230003 0.9 246.945 0.0125 :amp-env '(0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.495 0.1 100.0 0) :noise-amount 0.04 :reverb-amount 0.0026) (fm-violin 61.230003 0.9 494.89 0.0125 :amp-env '(0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.495 0.1 100.0 0) :noise-amount 0.04 :reverb-amount 0.002) (fm-violin 61.230003 1.8 988.78 0.0125 :amp-env '(0 0 0.1667 1 4.2003 0.6 9.2424 0.3 24.3687 0.1 100 0) :noise-amount 0.04 :reverb-amount 0.0025) (fm-violin 61.230003 2.7 30.8681 0.0125 :amp-env '(0 0 0.1111 1 4.147 0.6 9.1919 0.3 24.3266 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0028) (fm-violin 61.230003 1.8 61.7363 0.0125 :amp-env '(0 0 0.1667 1 4.2003 0.6 9.2424 0.3 24.3687 0.1 100 0) :noise-amount 0.01 :reverb-amount 0.0023) (fm-violin 61.239998 2.7 15.4341 0.0125 :amp-env '(0 0 0.1111 1 4.147 0.6 9.1919 0.3 24.3266 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.003) (fm-violin 61.245003 1.8 20.5788 0.0125 :amp-env '(0 0 0.1667 1 4.2003 0.6 9.2424 0.3 24.3687 0.1 100 0) :noise-amount 0.01 :reverb-amount 0.0023) (fm-violin 61.25 2 30.8681 0.0125 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.009 :reverb-amount 0.1) (fm-violin 61.25 1 61.7363 0.0125 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.009 :reverb-amount 0.1) (fm-violin 61.260002 2 15.4341 0.0125 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.009 :reverb-amount 0.1) (fm-violin 61.265 1 30.8681 0.0125 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.009 :reverb-amount 0.1) (fm-violin 61.271004 2 30.8681 0.0125 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.004 :reverb-amount 0.1) (fm-violin 61.271004 1 61.7363 0.0125 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.004 :reverb-amount 0.1) (fm-violin 61.281 1 31.8681 0.0125 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.004 :reverb-amount 0.1) (fm-violin 61.286003 2 15.4341 0.0125 :amp-env '(0 0 1 1 99 1 100 0) :noise-amount 0.004 :reverb-amount 0.1) (fm-violin 69.01 0.9 3135.92 0.02 :fm-index 1.7299 :fm2-rat 1.0 :fm3-rat 1.0 :amp-env '(0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.495 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0026) (fm-violin 69.01 0.45 1464.6987 0.02 :fm-index 1.9173 :amp-env '(0 0 0.6667 1 4.6801 0.6 9.697 0.3 24.7475 0.1 100 0) :noise-amount 0.01 :reverb-amount 0.0027) (fm-violin 69.02 0.9 6714.005 0.02 :fm-index 2.4604 :fm2-rat 1.0 :fm3-rat 1.0 :amp-env '(0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.495 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0032) (fm-violin 69.025 0.9 684.119 0.02 :fm-index 1.9969 :amp-env '(0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.495 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0021) (fm-violin 69.03 0.27 684.119 0.02 :fm-index 2.0022 :amp-env '(0 0 1.1111 1 5.1066 0.6 10.101 0.3 25.0842 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0026) (fm-violin 69.03 0.63 1464.6987 0.02 :fm-index 2.1058 :amp-env '(0 0 0.4762 1 4.4974 0.6 9.5238 0.3 24.6032 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0027) (fm-violin 69.04 0.9 319.5325 0.02 :fm-index 2.2293 :amp-env '(0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.495 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0029) (fm-violin 69.045 0.45 149.2445 0.02 :fm-index 1.578 :amp-env '(0 0 0.6667 1 4.6801 0.6 9.697 0.3 24.7475 0.1 100 0) :noise-amount 0.01 :reverb-amount 0.0025) (fm-violin 69.05 1 684.119 0.02 :amp-env '(0 0 1 1 100 0) :noise-amount 0.009) (fm-violin 69.05 1 1464.6987 0.02 :amp-env '(0 0 1 1 100 0) :noise-amount 0.009) (fm-violin 69.06 1 319.5325 0.02 :amp-env '(0 0 1 1 100 0) :noise-amount 0.009) (fm-violin 69.065 1 684.119 0.02 :amp-env '(0 0 1 1 100 0) :noise-amount 0.009) (fm-violin 69.07 1 149.2445 0.02 :amp-env '(0 0 1 1 100 0) :noise-amount 0.004) (fm-violin 69.07 1 1464.6987 0.02 :amp-env '(0 0 1 1 100 0) :noise-amount 0.004) (fm-violin 69.08 1 561.6022 0.02 :amp-env '(0 0 1 1 100 0) :noise-amount 0.004) (fm-violin 69.085 1 319.5325 0.02 :amp-env '(0 0 1 1 100 0) :noise-amount 0.004) (fm-violin 72.01 0.9 3135.92 0.02 :fm-index 1.6329 :fm2-rat 1.0 :fm3-rat 1.0 :amp-env '(0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.495 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0031) (fm-violin 72.01 0.45 1810.5774 0.02 :fm-index 1.8298 :amp-env '(0 0 0.6667 1 4.6801 0.6 9.697 0.3 24.7475 0.1 100 0) :noise-amount 0.01 :reverb-amount 0.0031) (fm-violin 72.02 0.9 5431.4136 0.02 :fm-index 2.164 :fm2-rat 1.0 :fm3-rat 1.0 :amp-env '(0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.495 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0022) (fm-violin 72.025 0.9 1045.368 0.02 :fm-index 1.6971 :amp-env '(0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.495 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0032) (fm-violin 72.03 0.27 1045.368 0.02 :fm-index 2.4855 :amp-env '(0 0 1.1111 1 5.1066 0.6 10.101 0.3 25.0842 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0028) (fm-violin 72.03 0.63 1810.5774 0.02 :fm-index 2.1604 :amp-env '(0 0 0.4762 1 4.4974 0.6 9.5238 0.3 24.6032 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.002) (fm-violin 72.04 0.9 603.5612 0.02 :fm-index 2.4204 :amp-env '(0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.495 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0031) (fm-violin 72.045 0.45 348.4765 0.02 :fm-index 2.3918 :amp-env '(0 0 0.6667 1 4.6801 0.6 9.697 0.3 24.7475 0.1 100 0) :noise-amount 0.01 :reverb-amount 0.0026) (fm-violin 72.046 0.9 201.1989 0.02 :fm-index 1.5205 :amp-env '(0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.495 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0024) (fm-violin 72.046 0.9 116.1656 0.02 :fm-index 2.3049 :amp-env '(0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.495 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0028) (fm-violin 72.05 0.9 3135.92 0.02 :fm-index 2.4363 :fm2-rat 1.0 :fm3-rat 1.0 :amp-env '(0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.495 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0021) (fm-violin 72.05 0.45 1464.6987 0.02 :fm-index 2.3865 :amp-env '(0 0 0.6667 1 4.6801 0.6 9.697 0.3 24.7475 0.1 100 0) :noise-amount 0.01 :reverb-amount 0.0027) (fm-violin 72.06 0.9 6714.005 0.02 :fm-index 1.7354 :fm2-rat 1.0 :fm3-rat 1.0 :amp-env '(0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.495 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0021) (fm-violin 72.065 0.9 684.119 0.02 :fm-index 1.8282 :amp-env '(0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.495 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0025) (fm-violin 72.07 0.27 684.119 0.02 :fm-index 2.3923 :amp-env '(0 0 1.1111 1 5.1066 0.6 10.101 0.3 25.0842 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0025) (fm-violin 72.07 0.63 1464.6987 0.02 :fm-index 2.2789 :amp-env '(0 0 0.4762 1 4.4974 0.6 9.5238 0.3 24.6032 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0028) (fm-violin 72.08 0.9 319.5325 0.02 :fm-index 1.5438 :amp-env '(0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.495 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0027) (fm-violin 72.085 0.45 149.2445 0.02 :fm-index 2.421 :amp-env '(0 0 0.6667 1 4.6801 0.6 9.697 0.3 24.7475 0.1 100 0) :noise-amount 0.01 :reverb-amount 0.0028) (fm-violin 72.086 0.9 69.7078 0.02 :fm-index 2.0288 :amp-env '(0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.495 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0029) (fm-violin 72.086 0.9 32.5585 0.02 :fm-index 1.8254 :amp-env '(0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.495 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0028) (fm-violin 75.05 0.9 3135.92 0.02 :fm-index 1.7334 :fm2-rat 1.0 :fm3-rat 1.0 :amp-env '(0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.495 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0) (fm-violin 75.05 0.45 1810.5774 0.02 :fm-index 2.3629 :amp-env '(0 0 0.6667 1 4.6801 0.6 9.697 0.3 24.7475 0.1 100 0) :noise-amount 0.01 :reverb-amount 0.0) (fm-violin 75.06 0.9 5431.4136 0.02 :fm-index 2.2744 :fm2-rat 1.0 :fm3-rat 1.0 :amp-env '(0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.495 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0) (fm-violin 75.065 0.9 1045.368 0.02 :fm-index 1.8722 :amp-env '(0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.495 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0) (fm-violin 75.11 0.27 1045.368 0.02 :fm-index 2.3139 :amp-env '(0 0 1.1111 1 5.1066 0.6 10.101 0.3 25.0842 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0) (fm-violin 75.11 0.63 1810.5774 0.02 :fm-index 1.6216 :amp-env '(0 0 0.4762 1 4.4974 0.6 9.5238 0.3 24.6032 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0) (fm-violin 75.12 0.9 603.5612 0.02 :fm-index 1.5308 :amp-env '(0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.495 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0) (fm-violin 75.165 0.45 348.4765 0.02 :fm-index 2.0346 :amp-env '(0 0 0.6667 1 4.6801 0.6 9.697 0.3 24.7475 0.1 100 0) :noise-amount 0.01 :reverb-amount 0.0) (fm-violin 75.166 0.9 201.1989 0.02 :fm-index 1.8176 :amp-env '(0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.495 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0) (fm-violin 75.166 0.9 116.1656 0.02 :fm-index 1.7145 :amp-env '(0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.495 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0) (fm-violin 75.17 0.9 3135.92 0.02 :fm-index 2.4459 :fm2-rat 1.0 :fm3-rat 1.0 :amp-env '(0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.495 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0) (fm-violin 75.17 0.45 1464.6987 0.02 :fm-index 2.4644 :amp-env '(0 0 0.6667 1 4.6801 0.6 9.697 0.3 24.7475 0.1 100 0) :noise-amount 0.01 :reverb-amount 0.0) (fm-violin 75.18 0.9 6714.005 0.02 :fm-index 1.9985 :fm2-rat 1.0 :fm3-rat 1.0 :amp-env '(0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.495 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0) (fm-violin 75.185 0.9 684.119 0.02 :fm-index 2.4542 :amp-env '(0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.495 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0) (fm-violin 75.29 0.27 684.119 0.02 :fm-index 2.3391 :amp-env '(0 0 1.1111 1 5.1066 0.6 10.101 0.3 25.0842 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0) (fm-violin 75.29 0.63 1464.6987 0.02 :fm-index 1.5138 :amp-env '(0 0 0.4762 1 4.4974 0.6 9.5238 0.3 24.6032 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0) (fm-violin 75.3 0.9 319.5325 0.02 :fm-index 1.544 :amp-env '(0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.495 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0) (fm-violin 75.305 0.45 149.2445 0.02 :fm-index 2.2283 :amp-env '(0 0 0.6667 1 4.6801 0.6 9.697 0.3 24.7475 0.1 100 0) :noise-amount 0.01 :reverb-amount 0.0) (fm-violin 75.306 0.9 69.7078 0.02 :fm-index 1.9498 :amp-env '(0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.495 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0) (fm-violin 75.306 0.9 32.5585 0.02 :fm-index 2.2943 :amp-env '(0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.495 0.1 100.0 0) :noise-amount 0.01 :reverb-amount 0.0) (fm-violin 78.26 1.2 355.5416 0.02 :fm-index 2.0375 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141) (fm-violin 78.26 1.5 354.8319 0.02 :fm-index 1.8744 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141) (fm-violin 78.2603 0.9 356.2527 0.02 :fm-index 1.8743 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141) (fm-violin 78.2605 0.9 409.2356 0.02 :fm-index 2.0808 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141) (fm-violin 78.2605 2.1 410.0541 0.02 :fm-index 1.9219 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141) (fm-violin 78.2608 1.2 130.81 0.02 :fm-index 1.5746 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141) (fm-violin 78.2613 3 130.2883 0.02 :fm-index 2.3771 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141) (fm-violin 78.2615 0.9 130.2883 0.02 :fm-index 1.7765 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141) (fm-violin 78.2615 2.1 130.5489 0.0325 :fm-index 1.6485 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141) (fm-violin 78.2625 2 130.81 0.02 :fm-index 2.1416 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141) (fm-violin 78.2633 2 130.5488 0.02 :fm-index 2.0883 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141) (fm-violin 82.2605 0.8 523.24 0.02 :fm-index 2.3056 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 1.e-4 :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141) (fm-violin 82.2605 1 247.1611 0.02 :fm-index 1.6308 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 1.e-4 :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141) (fm-violin 82.261 0.6 1107.6991 0.02 :fm-index 1.9364 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 1.e-4 :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141) (fm-violin 82.2613 2 116.7506 0.02 :fm-index 2.374 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 1.e-4 :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141) (fm-violin 82.2615 0.6 116.7506 0.02 :fm-index 1.8374 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 1.e-4 :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141) (fm-violin 82.2615 1.4 247.1611 0.02 :fm-index 1.725 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 1.e-4 :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141) (fm-violin 82.262 0.6 55.1491 0.02 :fm-index 1.5495 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 1.e-4 :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141) (fm-violin 82.2623 1 26.0506 0.02 :fm-index 1.7235 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 1.e-4 :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141) (fm-violin 82.2623 2 12.3054 0.02 :fm-index 1.8818 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 1.e-4 :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141) (fm-violin 82.2623 2 5.8127 0.02 :fm-index 1.9537 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 1.e-4 :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141) (fm-violin 82.2625 2 523.24 0.02 :fm-index 2.1593 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 1.e-4 :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141) (fm-violin 82.2625 1 256.239 0.02 :fm-index 1.9851 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 1.e-4 :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141) (fm-violin 82.263 2 1068.456 0.02 :fm-index 1.8015 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 1.e-4 :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141) (fm-violin 82.2633 2 125.4843 0.02 :fm-index 1.6161 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 1.e-4 :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141) (fm-violin 82.2635 0.6 125.4843 0.02 :fm-index 2.2767 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 1.e-4 :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141) (fm-violin 82.2635 1.4 256.239 0.02 :fm-index 2.0835 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 1.e-4 :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141) (fm-violin 82.264 0.4 61.4517 0.02 :fm-index 1.531 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 1.e-4 :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141) (fm-violin 82.2643 1 30.0939 0.02 :fm-index 1.5803 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 1.e-4 :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141) (fm-violin 82.2643 2 14.7374 0.02 :fm-index 1.9586 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 1.e-4 :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141) (fm-violin 82.2643 2 7.2172 0.02 :fm-index 1.727 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 1.e-4 :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141) (fm-violin 82.2645 6 28.471 0.02 :fm-index 1.5983 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 1.e-4 :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141) (fm-violin 82.2648 10 25.6239 0.02 :fm-index 1.7285 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 1.e-4 :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141) (fm-violin 82.2648 8 21.3532 0.02 :fm-index 1.7955 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 1.e-4 :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141) (fm-violin 82.2648 8 17.0826 0.02 :fm-index 2.0866 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 1.e-4 :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141) (fm-violin 86.26 1.6 1643.4968 0.02 :fm-index 2.1104 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.141 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 86.26 2 1643.4968 0.02 :fm-index 1.5191 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.141 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 86.2603 1.2 1643.4968 0.02 :fm-index 2.0478 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.141 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 86.2603 4 1643.4968 0.02 :fm-index 2.0473 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.141 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 86.2605 1.2 1422.1663 0.02 :fm-index 1.9845 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.141 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 86.2605 2.8 1422.1663 0.02 :fm-index 2.0429 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.141 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 86.2605 1.2 1422.1663 0.02 :fm-index 1.6184 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.141 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 86.2608 1.6 523.24 0.02 :fm-index 2.3908 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.141 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 86.2608 2 523.24 0.02 :fm-index 1.6733 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.141 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 86.261 1.2 523.24 0.02 :fm-index 2.0431 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.141 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 86.261 4 523.24 0.02 :fm-index 1.743 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.141 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 86.2613 1.2 523.24 0.02 :fm-index 2.203 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.141 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 86.2613 2.8 523.24 0.02 :fm-index 2.0149 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.141 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 86.2615 1.2 523.24 0.02 :fm-index 2.231 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.141 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 86.2615 2 523.24 0.02 :fm-index 2.1625 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.141 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 86.2618 4 523.24 0.02 :fm-index 2.0 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.141 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 86.2618 4 523.24 0.02 :fm-index 2.2034 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.141 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 86.262 3 523.24 0.02 :fm-index 2.0186 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.141 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 86.262 1.5 523.24 0.02 :fm-index 2.1373 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.141 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 86.2623 3 523.24 0.02 :fm-index 1.9046 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.141 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 86.2623 3 523.24 0.02 :fm-index 2.1834 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.141 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 86.2625 1.2 523.24 0.02 :fm-index 1.8266 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.141 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 86.2625 2.8 523.24 0.02 :fm-index 1.5937 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.141 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 86.2628 0.8 523.24 0.02 :fm-index 1.9762 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.141 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 86.2628 2 523.24 0.02 :fm-index 1.8954 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.141 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 86.263 4 523.24 0.02 :fm-index 2.3302 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.141 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 86.263 4 523.24 0.02 :fm-index 2.4949 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.141 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 90.26 1.6 821.7484 0.02 :fm-index 2.4793 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 90.26 2 821.7484 0.02 :fm-index 2.4789 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 90.2603 1.2 821.7484 0.02 :fm-index 2.0827 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 90.2603 4 821.7484 0.02 :fm-index 2.4769 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 90.2605 1.2 711.0832 0.02 :fm-index 2.4094 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 90.2605 2.8 711.0832 0.02 :fm-index 2.4031 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 90.2605 1.2 711.0832 0.02 :fm-index 2.1428 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 90.2608 1.6 261.62 0.02 :fm-index 2.3129 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 90.2608 2 261.62 0.02 :fm-index 2.3488 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 90.261 1.2 261.62 0.02 :fm-index 2.1466 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 90.261 4 261.62 0.02 :fm-index 1.6938 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 90.2613 1.2 261.62 0.02 :fm-index 2.1287 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 90.2613 2.8 261.62 0.02 :fm-index 2.1917 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 90.2615 1.2 261.62 0.02 :fm-index 2.3583 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 90.2615 2 261.62 0.02 :fm-index 1.8368 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 90.2618 4 261.62 0.02 :fm-index 1.5107 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 90.2618 4 261.62 0.02 :fm-index 1.6218 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 90.262 3 261.62 0.02 :fm-index 1.9041 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 90.262 1.5 261.62 0.02 :fm-index 1.5748 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 90.2623 3 261.62 0.02 :fm-index 1.9339 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 90.2623 3 261.62 0.02 :fm-index 2.0489 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 90.2625 1.2 261.62 0.02 :fm-index 2.0888 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 90.2625 2.8 261.62 0.02 :fm-index 1.7306 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 90.2628 0.8 261.62 0.02 :fm-index 2.3257 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 90.2628 2 261.62 0.02 :fm-index 2.4755 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 90.263 4 261.62 0.02 :fm-index 1.9459 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 90.263 4 261.62 0.02 :fm-index 1.5782 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 94.26 1.6 3286.9937 0.02 :fm-index 1.6655 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 1.414 :fm2-rat 1.414 :fm3-rat 1.718 :reverb-amount 0.001) (fm-violin 94.26 2 3286.9937 0.02 :fm-index 1.9356 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 1.414 :fm2-rat 1.414 :fm3-rat 1.718 :reverb-amount 0.001) (fm-violin 94.2603 1.2 3286.9937 0.02 :fm-index 1.5665 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 1.414 :fm2-rat 1.414 :fm3-rat 1.718 :reverb-amount 0.001) (fm-violin 94.2603 4 3286.9937 0.02 :fm-index 1.6701 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 1.414 :fm2-rat 1.414 :fm3-rat 1.718 :reverb-amount 0.001) (fm-violin 94.2605 1.2 2844.3325 0.02 :fm-index 2.3273 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 1.414 :fm2-rat 1.414 :fm3-rat 1.718 :reverb-amount 0.001) (fm-violin 94.2605 2.8 2844.3325 0.02 :fm-index 1.552 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 1.414 :fm2-rat 1.414 :fm3-rat 1.718 :reverb-amount 0.001) (fm-violin 94.2605 1.2 2844.3325 0.02 :fm-index 2.4104 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 1.414 :fm2-rat 1.414 :fm3-rat 1.718 :reverb-amount 0.001) (fm-violin 94.2608 1.6 1046.48 0.02 :fm-index 2.1075 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 94.2608 2 1046.48 0.02 :fm-index 1.7004 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 94.261 1.2 1046.48 0.02 :fm-index 1.6502 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 94.261 4 1046.48 0.02 :fm-index 2.4591 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 94.2613 1.2 1046.48 0.02 :fm-index 2.1491 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 94.2613 2.8 1046.48 0.02 :fm-index 2.1594 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 94.2615 1.2 1046.48 0.02 :fm-index 2.4783 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 94.2615 2 1046.48 0.02 :fm-index 2.208 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 94.2618 4 1046.48 0.02 :fm-index 1.5844 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 94.2618 4 1046.48 0.02 :fm-index 1.544 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 94.262 3 1046.48 0.02 :fm-index 1.9857 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 94.262 1.5 1046.48 0.02 :fm-index 1.5165 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 94.2623 3 1046.48 0.02 :fm-index 1.8309 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 94.2623 3 1046.48 0.02 :fm-index 2.1236 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 94.2625 1.2 1046.48 0.0125 :fm-index 2.4074 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 94.2625 2.8 1046.48 0.0125 :fm-index 1.6315 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 94.2628 0.8 1046.48 0.0125 :fm-index 1.8061 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 94.2628 2 1046.48 0.0125 :fm-index 2.3664 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 94.263 4 1046.48 0.0125 :fm-index 2.249 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 94.263 4 1046.48 0.0125 :fm-index 2.4081 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718 :reverb-amount 0.001) (fm-violin 98.26 1.6 1643.4968 0.02 :fm-index 1.9284 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718) (fm-violin 98.26 2 1643.4968 0.02 :fm-index 2.2171 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718) (fm-violin 98.2603 1.2 1643.4968 0.02 :fm-index 2.2272 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718) (fm-violin 98.2603 4 1643.4968 0.02 :fm-index 1.5677 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718) (fm-violin 98.2605 1.2 1422.1663 0.02 :fm-index 2.0476 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718) (fm-violin 98.2605 2.8 1422.1663 0.02 :fm-index 2.3289 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718) (fm-violin 98.2605 1.2 1422.1663 0.02 :fm-index 2.0269 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718) (fm-violin 98.2608 1.6 523.24 0.02 :fm-index 1.7767 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718) (fm-violin 98.2608 2 523.24 0.02 :fm-index 1.8117 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718) (fm-violin 98.261 1.2 523.24 0.02 :fm-index 1.5694 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718) (fm-violin 98.261 4 523.24 0.02 :fm-index 1.6869 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718) (fm-violin 98.2613 1.2 523.24 0.02 :fm-index 1.934 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718) (fm-violin 98.2613 2.8 523.24 0.02 :fm-index 2.3986 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718) (fm-violin 98.2615 1.2 523.24 0.02 :fm-index 2.4593 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718) (fm-violin 98.2615 2 523.24 0.02 :fm-index 2.343 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718) (fm-violin 98.2618 4 523.24 0.02 :fm-index 2.265 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718) (fm-violin 98.2618 4 523.24 0.02 :fm-index 2.3015 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718) (fm-violin 98.262 3 523.24 0.02 :fm-index 1.9909 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718) (fm-violin 98.262 1.5 523.24 0.02 :fm-index 2.3916 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718) (fm-violin 98.2623 3 523.24 0.02 :fm-index 2.0401 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718) (fm-violin 98.2623 3 523.24 0.02 :fm-index 1.8484 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718) (fm-violin 98.2625 1.2 523.24 0.02 :fm-index 2.3138 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718) (fm-violin 98.2625 2.8 523.24 0.02 :fm-index 1.6295 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718) (fm-violin 98.2628 0.8 523.24 0.02 :fm-index 2.2344 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718) (fm-violin 98.2628 2 523.24 0.02 :fm-index 1.8423 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718) (fm-violin 98.263 4 523.24 0.02 :fm-index 2.2086 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718) (fm-violin 98.263 4 523.24 0.02 :fm-index 2.313 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 3.414 :fm2-rat 1.414 :fm3-rat 2.718) (fm-violin 102.2605 0.8 523.24 0.02 :fm-index 2.0123 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 1.e-4 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 102.2605 1 493.8728 0.02 :fm-index 2.1176 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 1.e-4 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 102.261 0.6 554.3535 0.02 :fm-index 1.9163 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 1.e-4 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 102.2613 2 466.1539 0.02 :fm-index 1.5048 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 1.e-4 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 102.2615 0.6 466.1539 0.02 :fm-index 1.5242 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 1.e-4 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 102.2615 1.4 493.8728 0.02 :fm-index 1.9509 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 1.e-4 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 102.262 0.6 439.9907 0.02 :fm-index 2.2131 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 1.e-4 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 102.2623 1 415.2959 0.02 :fm-index 1.7326 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 1.e-4 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 102.2623 2 391.9871 0.02 :fm-index 1.9936 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 1.e-4 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 102.2623 2 369.9866 0.02 :fm-index 2.1103 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 1.e-4 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 102.2625 2 523.24 0.02 :fm-index 1.6206 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 1.e-4 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 102.2625 1 522.7173 0.02 :fm-index 1.8598 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 1.e-4 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 102.263 2 523.7632 0.02 :fm-index 1.8015 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 1.e-4 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 102.2633 2 522.1951 0.02 :fm-index 2.3575 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 1.e-4 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 102.2635 0.6 522.1951 0.02 :fm-index 1.501 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 1.e-4 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 102.2635 1.4 522.7173 0.02 :fm-index 2.4075 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 1.e-4 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 102.264 0.4 521.6734 0.02 :fm-index 2.0721 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 1.e-4 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 102.2643 1 521.1523 0.02 :fm-index 2.0433 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 1.e-4 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 102.2643 2 520.6316 0.02 :fm-index 1.9788 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 1.e-4 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 102.2643 2 520.1115 0.02 :fm-index 1.677 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 1.e-4 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 110.259995 0.8 1046.48 0.02 :fm-index 1.561 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 110.259995 1 1044.3912 0.02 :fm-index 2.3514 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 110.2603 0.6 1048.573 0.02 :fm-index 1.9958 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 110.2603 2 1042.3066 0.02 :fm-index 1.9654 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 110.2605 0.6 1042.3066 0.02 :fm-index 1.5285 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 110.2605 1.4 1044.3912 0.02 :fm-index 1.8881 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 110.2608 0.6 1040.2262 0.02 :fm-index 1.8682 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 110.2608 0.8 523.24 0.02 :fm-index 1.8296 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 110.261 1 522.1956 0.02 :fm-index 2.1899 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 110.261 0.6 524.2865 0.02 :fm-index 1.9614 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 110.26131 2 521.1533 0.02 :fm-index 1.7483 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 110.261505 0.6 521.1533 0.02 :fm-index 1.8717 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 110.261505 1.4 522.1956 0.02 :fm-index 1.5619 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 110.26199 0.6 520.1131 0.02 :fm-index 2.4331 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 110.2623 1 519.0749 0.02 :fm-index 2.4153 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 110.2623 2 518.0388 0.02 :fm-index 1.5477 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 110.2623 2 517.0048 0.02 :fm-index 1.9956 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 110.2625 2 523.24 0.02 :fm-index 1.8111 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 110.2625 1 522.7173 0.02 :fm-index 2.482 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 110.263 2 523.7632 0.02 :fm-index 1.5744 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 110.263306 2 522.1951 0.02 :fm-index 1.995 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 110.263504 0.6 522.1951 0.02 :fm-index 1.9792 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 110.263504 1.4 522.7173 0.02 :fm-index 1.7415 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 110.26401 0.4 521.6734 0.02 :fm-index 2.0884 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 110.2643 1 521.1523 0.02 :fm-index 2.3605 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 110.2643 2 520.6316 0.02 :fm-index 1.7817 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 110.2643 2 520.1115 0.02 :fm-index 2.0283 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 114.259995 1.6 177.7708 0.02 :fm-index 1.6447 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 114.259995 2 177.7708 0.02 :fm-index 2.4875 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 114.2603 1.2 177.7708 0.02 :fm-index 1.6126 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 114.2603 4 177.7708 0.02 :fm-index 2.3122 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 114.2605 1.2 205.4371 0.02 :fm-index 2.4116 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 114.2605 2.8 205.4371 0.02 :fm-index 1.5337 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 114.2608 1.2 205.4371 0.02 :fm-index 2.0307 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 114.2608 1.6 65.405 0.02 :fm-index 2.2341 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 114.261 2 65.405 0.02 :fm-index 2.4683 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 114.261 1.2 65.405 0.02 :fm-index 2.0643 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 114.26131 4 65.405 0.02 :fm-index 2.1925 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 114.261505 1.2 65.405 0.02 :fm-index 2.1325 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 114.261505 2.8 65.405 0.02 :fm-index 1.5847 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 114.26199 1.2 65.405 0.02 :fm-index 1.8781 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 114.2623 2 65.405 0.02 :fm-index 2.0283 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 114.2623 4 65.405 0.02 :fm-index 2.4739 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 114.2623 4 65.405 0.02 :fm-index 2.2333 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 114.2625 2 65.405 0.02 :fm-index 2.2194 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 114.2625 1 65.405 0.02 :fm-index 2.4491 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 114.263 2 65.405 0.02 :fm-index 1.5672 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 114.263306 2 65.405 0.02 :fm-index 2.3254 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 114.263504 1.2 65.405 0.02 :fm-index 1.8302 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 114.263504 2.8 65.405 0.02 :fm-index 1.9201 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 114.26401 0.8 65.405 0.02 :fm-index 1.9164 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 114.2643 2 65.405 0.02 :fm-index 1.9483 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 114.2643 4 65.405 0.02 :fm-index 2.4247 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 114.2643 4 65.405 0.02 :fm-index 2.0419 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 1.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 118.259995 1.6 88.8854 0.02 :fm-index 2.2832 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 118.259995 2 88.8854 0.02 :fm-index 1.6588 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 118.2603 1.2 88.8854 0.02 :fm-index 2.2392 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 118.2603 4 88.8854 0.02 :fm-index 1.7354 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 118.2605 1.2 102.7186 0.02 :fm-index 1.6692 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 118.2605 2.8 102.7186 0.02 :fm-index 2.1518 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 118.2608 1.2 102.7186 0.02 :fm-index 2.2439 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 118.2608 1.6 32.7025 0.02 :fm-index 2.1665 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 118.261 2 32.7025 0.02 :fm-index 1.7947 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 118.261 1.2 32.7025 0.02 :fm-index 2.074 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 118.26131 4 32.7025 0.02 :fm-index 1.9705 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 118.261505 1.2 32.7025 0.02 :fm-index 1.9447 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 118.261505 2.8 32.7025 0.02 :fm-index 2.4918 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 118.26199 1.2 32.7025 0.02 :fm-index 1.6275 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 118.2623 2 32.7025 0.02 :fm-index 2.2355 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 118.2623 4 32.7025 0.02 :fm-index 2.0084 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 118.2623 4 32.7025 0.02 :fm-index 1.8964 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 118.2625 2 32.7025 0.02 :fm-index 2.3937 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 118.2625 1 32.7025 0.02 :fm-index 1.8634 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 118.263 2 32.7025 0.02 :fm-index 1.5217 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 118.263306 2 32.7025 0.02 :fm-index 1.9275 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 118.263504 1.2 32.7025 0.02 :fm-index 2.4413 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 118.263504 2.8 32.7025 0.02 :fm-index 2.3242 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 118.26401 0.8 32.7025 0.02 :fm-index 2.3267 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 118.2643 2 32.7025 0.02 :fm-index 1.7004 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 118.2643 4 32.7025 0.02 :fm-index 1.8785 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 118.2643 4 32.7025 0.02 :fm-index 2.4573 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 3.141 :reverb-amount 0.1) (fm-violin 122.259995 1.6 22.2213 0.02 :fm-index 1.6232 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 122.259995 2 22.2213 0.02 :fm-index 1.5982 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 122.2603 1.2 22.2213 0.02 :fm-index 2.1585 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 122.2603 4 22.2213 0.02 :fm-index 2.2207 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 122.2605 1.2 42.0309 0.02 :fm-index 1.5294 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 122.2605 2.8 42.0309 0.02 :fm-index 1.9544 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 122.2608 1.2 42.0309 0.02 :fm-index 2.4016 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 122.2608 1.6 8.1756 0.02 :fm-index 1.5267 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 122.261 2 8.1756 0.02 :fm-index 2.419 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 122.261 1.2 8.1756 0.02 :fm-index 2.2757 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 122.26131 4 8.1756 0.02 :fm-index 2.3607 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 122.261505 1.2 8.1756 0.02 :fm-index 1.8698 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 122.261505 2.8 8.1756 0.02 :fm-index 2.3753 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 122.26199 1.2 8.1756 0.02 :fm-index 2.3392 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 122.2623 2 8.1756 0.02 :fm-index 1.5088 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 122.2623 4 8.1756 0.02 :fm-index 2.2084 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 122.2623 4 8.1756 0.02 :fm-index 1.9512 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 122.2625 2 8.1756 0.02 :fm-index 2.0399 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 122.2625 1 8.1756 0.02 :fm-index 1.7053 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 122.263 2 8.1756 0.02 :fm-index 2.3204 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 122.263306 2 8.1756 0.02 :fm-index 1.6336 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 122.263504 1.2 8.1756 0.02 :fm-index 1.9483 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 122.263504 2.8 8.1756 0.02 :fm-index 2.3255 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 122.26401 0.8 8.1756 0.02 :fm-index 1.7331 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 122.2643 2 8.1756 0.02 :fm-index 1.9318 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 122.2643 4 8.1756 0.02 :fm-index 1.6908 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 122.2643 4 8.1756 0.02 :fm-index 2.4103 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 126.259995 1.6 11.1107 0.02 :fm-index 1.6371 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 126.259995 2 11.1107 0.02 :fm-index 1.8971 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 126.2603 1.2 11.1107 0.02 :fm-index 1.9065 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 126.2603 4 11.1107 0.02 :fm-index 2.2143 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 126.2605 1.2 21.0154 0.02 :fm-index 1.8011 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 126.2605 2.8 21.0154 0.02 :fm-index 2.195 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 126.2608 1.2 21.0154 0.02 :fm-index 2.3563 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 126.2608 1.6 4.0878 0.02 :fm-index 2.3181 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 126.261 2 4.0878 0.02 :fm-index 2.0776 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 126.261 1.2 4.0878 0.02 :fm-index 1.8336 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 126.26131 4 4.0878 0.02 :fm-index 1.5019 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 126.261505 1.2 4.0878 0.02 :fm-index 2.2368 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 126.261505 2.8 4.0878 0.02 :fm-index 1.7462 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 126.26199 1.2 4.0878 0.02 :fm-index 1.9604 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 126.2623 2 4.0878 0.02 :fm-index 2.2361 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 126.2623 4 4.0878 0.02 :fm-index 1.9972 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 126.2623 4 4.0878 0.02 :fm-index 2.487 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 126.2625 2 4.0878 0.02 :fm-index 2.0762 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 126.2625 1 4.0878 0.02 :fm-index 2.2973 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 126.263 2 4.0878 0.02 :fm-index 2.235 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 126.263306 2 4.0878 0.02 :fm-index 2.1613 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 126.263504 1.2 4.0878 0.02 :fm-index 2.064 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 126.263504 2.8 4.0878 0.02 :fm-index 2.1738 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 126.26401 0.8 4.0878 0.02 :fm-index 1.5188 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 126.2643 2 4.0878 0.02 :fm-index 1.8766 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 126.2643 4 4.0878 0.02 :fm-index 2.3083 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 126.2643 4 4.0878 0.02 :fm-index 2.2215 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 130.26 1.6 66.5893 0.02 :fm-index 1.7041 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 130.26 2 66.4564 0.02 :fm-index 2.0296 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 130.2603 1.2 66.7225 0.02 :fm-index 1.8321 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 130.2603 4 66.3237 0.02 :fm-index 2.155 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 130.2605 1.2 125.449 0.02 :fm-index 2.1806 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 130.2605 2.8 125.6999 0.02 :fm-index 2.357 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 130.2608 1.2 125.1986 0.02 :fm-index 1.9861 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 130.2608 1.6 24.4994 0.02 :fm-index 1.6412 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 130.261 2 24.4505 0.02 :fm-index 1.977 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 130.261 1.2 24.5484 0.02 :fm-index 2.0103 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 130.2613 4 24.4017 0.02 :fm-index 2.0663 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 130.2615 1.2 24.4017 0.02 :fm-index 2.1521 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 130.2615 2.8 24.4505 0.02 :fm-index 2.4453 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 130.262 1.2 24.353 0.02 :fm-index 2.093 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 130.2623 2 24.696 0.02 :fm-index 2.3423 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 130.2623 4 24.7454 0.02 :fm-index 2.0856 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 130.2623 4 24.7948 0.02 :fm-index 1.957 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 130.2625 2 24.4994 0.02 :fm-index 2.4642 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 130.2625 1 24.4749 0.02 :fm-index 1.9901 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 130.263 2 24.5239 0.02 :fm-index 1.9972 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 130.2633 2 24.4505 0.02 :fm-index 1.9148 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 130.2635 1.2 24.4505 0.02 :fm-index 1.9017 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 130.2635 2.8 24.4749 0.02 :fm-index 2.4958 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 130.264 0.8 24.426 0.02 :fm-index 2.2518 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 130.2643 2 24.5975 0.02 :fm-index 2.112 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 130.2643 4 24.6221 0.02 :fm-index 2.3154 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 130.2643 4 24.6467 0.02 :fm-index 1.924 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 134.26 1.6 164.5868 0.02 :fm-index 1.9587 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 6.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 134.26 2 164.5868 0.02 :fm-index 1.5071 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 6.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 134.2603 1.2 164.5868 0.02 :fm-index 1.769 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 6.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 134.2603 4 164.5868 0.02 :fm-index 1.7686 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 6.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 134.2605 1.2 125.9513 0.02 :fm-index 1.5702 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 6.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 134.2605 2.8 125.9513 0.02 :fm-index 2.1962 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 6.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 134.2608 1.2 125.9513 0.02 :fm-index 1.7701 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 6.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 134.2608 1.6 24.4994 0.02 :fm-index 2.1665 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 6.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 134.261 2 24.4994 0.02 :fm-index 1.9345 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 6.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 134.261 1.2 24.4994 0.02 :fm-index 2.2037 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 6.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 134.2613 4 24.4994 0.02 :fm-index 1.6826 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 6.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 134.2615 1.2 24.4994 0.02 :fm-index 1.541 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 6.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 134.2615 2.8 24.4994 0.02 :fm-index 1.8293 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 6.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 134.262 1.2 24.4994 0.02 :fm-index 2.1468 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 6.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 134.2623 2 24.4994 0.02 :fm-index 2.0758 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 6.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 134.2623 4 24.4994 0.02 :fm-index 2.4138 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 6.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 134.2623 4 24.4994 0.02 :fm-index 1.8479 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 6.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 134.2625 3 24.4994 0.02 :fm-index 2.4639 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 6.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 134.2625 1.5 24.4994 0.02 :fm-index 2.3995 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 6.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 134.263 3 24.4994 0.02 :fm-index 1.8609 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 6.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 134.2633 3 24.4994 0.02 :fm-index 2.4506 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 6.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 134.2635 1.2 24.4994 0.02 :fm-index 2.1577 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 6.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 134.2635 2.8 24.4994 0.02 :fm-index 1.6663 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 6.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 134.264 0.8 24.4994 0.02 :fm-index 2.1166 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 6.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 134.2643 2 24.4994 0.02 :fm-index 1.9362 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 6.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 134.2643 4 24.4994 0.02 :fm-index 2.2052 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 6.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 134.2643 4 24.4994 0.02 :fm-index 2.0102 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :noise-amount 0.004 :fm1-rat 6.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 138.26 0.4 1046.48 0.02 :fm-index 2.387 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :gliss-env '(0 0 75 0.1 90 0.3 97 0.6 100 1) :glissando-amount 0.8 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 138.26 0.5 1044.3912 0.02 :fm-index 2.4309 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :gliss-env '(0 0 75 0.1 90 0.3 97 0.6 100 1) :glissando-amount 0.8 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 138.2603 0.3 1048.573 0.02 :fm-index 2.15 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :gliss-env '(0 0 75 0.1 90 0.3 97 0.6 100 1) :glissando-amount 0.8 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 138.2603 0.5 1042.3066 0.02 :fm-index 1.7211 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :gliss-env '(0 0 75 0.1 90 0.3 97 0.6 100 1) :glissando-amount 0.8 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 138.261 0.3 524.2865 0.02 :fm-index 2.1751 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :gliss-env '(0 0 75 0.1 90 0.3 97 0.6 100 1) :glissando-amount 0.8 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 138.262 0.3 520.1131 0.02 :fm-index 1.5433 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :gliss-env '(0 0 75 0.1 90 0.3 97 0.6 100 1) :glissando-amount 0.8 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 138.2623 0.4 517.0048 0.02 :fm-index 2.4335 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :gliss-env '(0 0 75 0.1 90 0.3 97 0.6 100 1) :glissando-amount 0.8 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 138.2625 0.4 523.24 0.02 :fm-index 2.2778 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :gliss-env '(0 0 75 0.1 90 0.3 97 0.6 100 1) :glissando-amount 0.8 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 138.2635 0.3 522.1951 0.02 :fm-index 1.9441 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :gliss-env '(0 0 75 0.1 90 0.3 97 0.6 100 1) :glissando-amount 0.8 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 138.2643 0.4 520.6316 0.02 :fm-index 2.4656 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :gliss-env '(0 0 75 0.1 90 0.3 97 0.6 100 1) :glissando-amount 0.8 :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141) (fm-violin 142.12 0.4 2092.96 0.02 :fm-index 3 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141 :reverb-amount 0) (fm-violin 142.12 0.5 2088.782 0.02 :fm-index 3 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141 :reverb-amount 0) (fm-violin 142.12 0.3 2097.146 0.02 :fm-index 3 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141 :reverb-amount 0) (fm-violin 142.12 0.5 2084.613 0.02 :fm-index 3 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141 :reverb-amount 0) (fm-violin 142.121 0.3 1048.573 0.02 :fm-index 3 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141 :reverb-amount 0) (fm-violin 142.122 0.3 1040.226 0.02 :fm-index 3 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141 :reverb-amount 0) (fm-violin 142.122 0.5 1034.01 0.02 :fm-index 3 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141 :reverb-amount 0) (fm-violin 142.123 0.5 1046.48 0.02 :fm-index 3 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141 :reverb-amount 0) (fm-violin 142.124 0.3 1044.39 0.02 :fm-index 3 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141 :reverb-amount 0) (fm-violin 142.124 0.5 1041.263 0.02 :fm-index 3 :amp-env '(0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0) :fm1-rat 2.718 :fm2-rat 1.141 :fm3-rat 3.141 :reverb-amount 0) (fm-violin 144.488 1.177 416.6072 0.001375 :fm-index 1.114 :amp-env '(0 0 20 0.5 40 0.1 60 0.2 80 1 100 0) :noise-amount 0.005 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 144.505 2.49 859.5863 0.0010375 :fm-index 0.589 :amp-env '(0 0 20 1 60 0.1 75 0.3 100 0) :noise-amount 0.005 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 145.059 1.055 1758.0815 6.625e-4 :fm-index 1.864 :amp-env '(0 0 20 1 60 0.1 75 0.3 100 0) :noise-amount 0.005 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 145.093 1.858 229.0566 0.001375 :fm-index 1.969 :amp-env '(0 0 20 1 60 0.1 75 0.3 100 0) :noise-amount 0.005 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 145.349 3.368 479.1994 0.0010375 :fm-index 1.997 :amp-env '(0 0 20 0.5 40 0.1 60 0.2 80 1 100 0) :noise-amount 0.005 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 145.501 3.068 411.8241 0.001375 :fm-index 1.539 :amp-env '(0 0 20 1 60 0.1 75 0.3 100 0) :noise-amount 0.005 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 145.52 2.829 984.8456 6.625e-4 :fm-index 0.056 :amp-env '(0 0 20 0.5 40 0.1 60 0.2 80 1 100 0) :noise-amount 0.005 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 145.61 0.704 1767.7444 6.625e-4 :fm-index 1.262 :amp-env '(0 0 20 1 60 0.1 75 0.3 100 0) :noise-amount 0.005 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 145.848 3.051 859.7203 0.0010375 :fm-index 1.608 :amp-env '(0 0 20 1 60 0.1 75 0.3 100 0) :noise-amount 0.005 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 146.488 3.235 231.9431 0.001375 :fm-index 0.969 :amp-env '(0 0 20 0.5 40 0.1 60 0.2 80 1 100 0) :noise-amount 0.005 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 146.561 3.281 475.2009 0.0010375 :fm-index 0.374 :amp-env '(0 0 20 1 60 0.1 75 0.3 100 0) :noise-amount 0.005 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 146.797 2.84 988.8375 6.625e-4 :fm-index 0.42 :amp-env '(0 0 20 1 60 0.1 75 0.3 100 0) :noise-amount 0.005 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 147.062 1.021 411.7247 0.001375 :fm-index 0.137 :amp-env '(0 0 20 1 60 0.1 75 0.3 100 0) :noise-amount 0.005 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 147.213 1.161 848.5959 0.0010375 :fm-index 1.312 :amp-env '(0 0 20 1 60 0.1 75 0.3 100 0) :noise-amount 0.005 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 147.441 2.616 390.06 0.001375 :fm-index 1.903 :amp-env '(0 0 20 0.5 40 0.1 60 0.2 80 1 100 0) :noise-amount 0.005 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 147.449 0.7 802.3538 0.0010375 :fm-index 1.594 :amp-env '(0 0 20 1 60 0.1 75 0.3 100 0) :noise-amount 0.005 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 147.527 2.508 1773.9366 6.625e-4 :fm-index 1.803 :amp-env '(0 0 20 0.5 40 0.1 60 0.2 80 1 100 0) :noise-amount 0.005 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 147.782 2.799 232.4344 0.001375 :fm-index 0.059 :amp-env '(0 0 20 1 60 0.1 75 0.3 100 0) :noise-amount 0.005 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 147.783 2.766 1650.1434 6.625e-4 :fm-index 0.44 :amp-env '(0 0 20 1 60 0.1 75 0.3 100 0) :noise-amount 0.005 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 147.789 3.156 475.7231 0.0010375 :fm-index 0.737 :amp-env '(0 0 20 1 60 0.1 75 0.3 100 0) :noise-amount 0.005 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 148.154 2.129 976.0237 6.625e-4 :fm-index 1.269 :amp-env '(0 0 20 1 60 0.1 75 0.3 100 0) :noise-amount 0.005 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 148.489 3.365 390.0525 0.001375 :fm-index 1.458 :amp-env '(0 0 20 1 60 0.1 75 0.3 100 0) :noise-amount 0.005 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 148.745 1.507 1665.9722 6.625e-4 :fm-index 1.933 :amp-env '(0 0 20 1 60 0.1 75 0.3 100 0) :noise-amount 0.005 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 148.832 1.443 798.1238 0.0010375 :fm-index 0.856 :amp-env '(0 0 20 0.5 40 0.1 60 0.2 80 1 100 0) :noise-amount 0.005 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 148.944 3.156 229.0528 0.001375 :fm-index 1.83 :amp-env '(0 0 20 1 60 0.1 75 0.3 100 0) :noise-amount 0.005 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 149.393 1.11 473.7225 0.0010375 :fm-index 1.626 :amp-env '(0 0 20 0.5 40 0.1 60 0.2 80 1 100 0) :noise-amount 0.005 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 149.697 1.617 988.7953 6.625e-4 :fm-index 0.423 :amp-env '(0 0 20 1 60 0.1 75 0.3 100 0) :noise-amount 0.005 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 150.062 1.319 390.9769 0.001375 :fm-index 0.41 :amp-env '(0 0 20 1 60 0.1 75 0.3 100 0) :noise-amount 0.005 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 150.084 3.366 804.6413 0.0010375 :fm-index 1.876 :amp-env '(0 0 20 1 60 0.1 75 0.3 100 0) :noise-amount 0.005 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 150.174 2.721 418.6819 0.001375 :fm-index 0.091 :amp-env '(0 0 20 1 60 0.1 75 0.3 100 0) :noise-amount 0.005 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 150.57 3.446 845.4019 9.625e-4 :fm-index 0.766 :amp-env '(0 0 20 1 60 0.1 75 0.3 100 0) :noise-amount 0.005 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 150.644 1.179 1656.5756 6.125e-4 :fm-index 0.296 :amp-env '(0 0 20 0.5 40 0.1 60 0.2 80 1 100 0) :noise-amount 0.005 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 150.66 2.852 1758.9788 6.125e-4 :fm-index 0.452 :amp-env '(0 0 20 1 60 0.1 75 0.3 100 0) :noise-amount 0.005 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 150.827 1.884 387.0009 0.0012375 :fm-index 1.301 :amp-env '(0 0 20 0.5 40 0.1 60 0.2 80 1 100 0) :noise-amount 0.005 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 150.887 3.404 796.7213 9.625e-4 :fm-index 1.182 :amp-env '(0 0 20 1 60 0.1 75 0.3 100 0) :noise-amount 0.005 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 150.964 3.323 416.3916 0.0012375 :fm-index 0.629 :amp-env '(0 0 20 1 60 0.1 75 0.3 100 0) :noise-amount 0.005 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 151.132 1.705 1637.2303 6.125e-4 :fm-index 1.057 :amp-env '(0 0 20 0.5 40 0.1 60 0.2 80 1 100 0) :noise-amount 0.005 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 151.15 3.125 1762.4906 6.125e-4 :fm-index 1.317 :amp-env '(0 0 20 1 60 0.1 75 0.3 100 0) :noise-amount 0.005 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 151.386 2.967 852.0487 9.625e-4 :fm-index 1.479 :amp-env '(0 0 20 0.5 40 0.1 60 0.2 80 1 100 0) :noise-amount 0.005 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 151.667 0.678 413.7094 0.0012375 :fm-index 0.947 :amp-env '(0 0 20 1 60 0.1 75 0.3 100 0) :noise-amount 0.005 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 151.878 2.749 1749.7509 6.125e-4 :fm-index 0.504 :amp-env '(0 0 20 0.5 40 0.1 60 0.2 80 1 100 0) :noise-amount 0.005 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 151.973 0.599 848.1253 9.625e-4 :fm-index 1.938 :amp-env '(0 0 20 0.5 40 0.1 60 0.2 80 1 100 0) :noise-amount 0.005 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 152.088 3.336 229.9144 0.0012375 :fm-index 1.393 :amp-env '(0 0 20 1 60 0.1 75 0.3 100 0) :noise-amount 0.005 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 152.117 1.13 984.0816 6.125e-4 :fm-index 0.356 :amp-env '(0 0 20 1 60 0.1 75 0.3 100 0) :noise-amount 0.005 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 152.464 1.733 478.7184 9.625e-4 :fm-index 0.284 :amp-env '(0 0 20 1 60 0.1 75 0.3 100 0) :noise-amount 0.005 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 152.576 0.568 413.4253 0.0012375 :fm-index 1.502 :amp-env '(0 0 20 1 60 0.1 75 0.3 100 0) :noise-amount 0.005 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 152.82 1.215 230.9588 0.0012375 :fm-index 1.099 :amp-env '(0 0 20 0.5 40 0.1 60 0.2 80 1 100 0) :noise-amount 0.005 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 152.832 3.459 473.8903 9.625e-4 :fm-index 0.768 :amp-env '(0 0 20 1 60 0.1 75 0.3 100 0) :noise-amount 0.005 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 152.832 0.726 857.2875 9.625e-4 :fm-index 0.752 :amp-env '(0 0 20 1 60 0.1 75 0.3 100 0) :noise-amount 0.005 :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.1) (fm-violin 156.26 0.05 80 0.1 :fm-index 5 :amp-env '(0 0 1 1 3 1 10 0.5 30 0.2 60 0.05 100 0) :fm1-env '(0 1 90 1 100 0) :reverb-amount 0) (fm-violin 157.261 0.2 80 0.1 :fm-index 4 :amp-env '(0 1 6 1 10 0.5 20 0.363 30 0.27 40 0.2 50 0.12 60 0.08 70 0.04 100 0) :fm1-env '(0 1 20 0 100 0) :fm2-rat 0.6875 :reverb-amount 0) (fm-violin 158.26 0.05 80 0.1 :fm-index 5 :amp-env '(0 0 1 1 3 1 10 0.5 30 0.2 60 0.05 100 0) :fm1-env '(0 1 90 1 100 0) :reverb-amount 0) (fm-violin 158.262 0.2 80 0.1 :fm-index 5 :amp-env '(0 1 6 1 10 0.5 20 0.363 30 0.27 40 0.2 50 0.12 60 0.08 70 0.04 100 0) :fm1-env '(0 1 20 0 100 0) :fm2-rat 0.6875 :reverb-amount 0) (fm-violin 159.26 0.05 80 0.1 :fm-index 6 :amp-env '(0 0 1 1 3 1 10 0.5 30 0.2 60 0.05 100 0) :fm1-env '(0 1 90 1 100 0) :reverb-amount 0) (fm-violin 159.263 0.2 80 0.1 :fm-index 6 :amp-env '(0 1 6 1 10 0.5 20 0.363 30 0.27 40 0.2 50 0.12 60 0.08 70 0.04 100 0) :fm1-env '(0 1 20 0 100 0) :fm2-rat 0.6875 :reverb-amount 0) (fm-violin 160.26 0.05 80 0.0375 :fm-index 4 :amp-env '(0 0 1 1 3 1 10 0.5 30 0.2 60 0.05 100 0) :fm1-env '(0 1 90 1 100 0) :reverb-amount 0) (fm-violin 160.262 0.1 160 0.0375 :fm-index 4 :amp-env '(0 1 6 1 10 0.5 20 0.363 30 0.27 40 0.2 50 0.12 60 0.08 70 0.04 100 0) :fm1-env '(0 1 20 0 100 0) :fm2-rat 0.6875 :reverb-amount 0) (fm-violin 160.262 0.25 80 0.1 :fm-index 4 :amp-env '(0 1 6 1 10 0.5 20 0.363 30 0.27 40 0.2 50 0.12 60 0.08 70 0.04 100 0) :fm1-env '(0 1 20 0 100 0) :fm2-rat 0.6875 :reverb-amount 0) (fm-violin 161.26 0.05 80 0.0625 :fm-index 4 :amp-env '(0 0 1 1 3 1 10 0.5 30 0.2 60 0.05 100 0) :fm1-env '(0 1 90 1 100 0) :reverb-amount 0) (fm-violin 161.261 0.1 210 0.0375 :fm-index 4 :amp-env '(0 1 6 1 10 0.5 20 0.363 30 0.27 40 0.2 50 0.12 60 0.08 70 0.04 100 0) :fm1-env '(0 1 20 0 100 0) :fm2-rat 0.6875 :reverb-amount 0) (fm-violin 161.262 0.2 80 0.0125 :fm-index 4 :amp-env '(0 1 6 1 10 0.5 20 0.363 30 0.27 40 0.2 50 0.12 60 0.08 70 0.04 100 0) :fm1-env '(0 1 20 0 100 0) :fm2-rat 0.6875 :reverb-amount 0) (fm-violin 161.263 0.25 320 0.0125 :fm-index 2 :amp-env '(0 1 6 1 10 0.5 20 0.363 30 0.27 40 0.2 50 0.12 60 0.08 70 0.04 100 0) :fm1-env '(0 1 20 0 100 0) :fm2-rat 0.6875 :reverb-amount 0) (fm-violin 162.26 0.05 80 0.1 :fm-index 4 :amp-env '(0 0 1 1 3 1 10 0.5 30 0.2 60 0.05 100 0) :fm1-env '(0 1 90 1 100 0) :reverb-amount 0) (fm-violin 162.261 0.1 210 0.0125 :fm-index 2 :amp-env '(0 1 6 1 10 0.5 20 0.363 30 0.27 40 0.2 50 0.12 60 0.08 70 0.04 100 0) :fm1-env '(0 1 20 0 100 0) :fm2-rat 0.6875 :reverb-amount 0) (fm-violin 162.262 0.2 80 0.025 :fm-index 4 :amp-env '(0 1 6 1 10 0.5 20 0.363 30 0.27 40 0.2 50 0.12 60 0.08 70 0.04 100 0) :fm1-env '(0 1 20 0 100 0) :fm2-rat 0.6875 :reverb-amount 0) (fm-violin 162.263 0.25 320 0.0375 :amp-env '(0 1 6 1 10 0.5 20 0.363 30 0.27 40 0.2 50 0.12 60 0.08 70 0.04 100 0) :fm1-env '(0 1 20 0 100 0) :fm2-rat 0.6875 :reverb-amount 0) (fm-violin 163.26 0.05 80 0.1 :fm-index 2 :amp-env '(0 0 1 1 3 1 10 0.5 30 0.2 60 0.05 100 0) :fm1-env '(0 1 90 1 100 0) :reverb-amount 0) (fm-violin 163.261 0.1 210 0.0125 :fm-index 2 :amp-env '(0 1 6 1 10 0.5 20 0.363 30 0.27 40 0.2 50 0.12 60 0.08 70 0.04 100 0) :fm1-env '(0 1 20 0 100 0) :fm2-rat 0.6875 :reverb-amount 0) (fm-violin 163.262 0.2 80 0.025 :fm-index 2 :amp-env '(0 1 6 1 10 0.5 20 0.363 30 0.27 40 0.2 50 0.12 60 0.08 70 0.04 100 0) :fm1-env '(0 1 20 0 100 0) :fm2-rat 0.6875 :reverb-amount 0) (fm-violin 163.263 0.25 320 0.0375 :amp-env '(0 1 6 1 10 0.5 20 0.363 30 0.27 40 0.2 50 0.12 60 0.08 70 0.04 100 0) :fm1-env '(0 1 20 0 100 0) :fm2-rat 0.6875 :reverb-amount 0) (fm-violin 164.26 4 3286.9937 0.02 :fm-index 2.2165 :amp-env '(0 0 65 1 100 0) :noise-amount 0.004 :fm1-env '(0 0 65 1 100 0) :fm1-rat 1.141 :fm2-rat 1.414 :fm3-rat 1.718) (fm-violin 164.2603 4 1046.48 0.02 :fm-index 2.3234 :amp-env '(0 0 65 1 100 0) :noise-amount 0.004 :fm1-env '(0 0 65 1 100 0) :fm1-rat 3.141 :fm2-rat 2.414 :fm3-rat 2.718) (fm-violin 164.2605 4 2844.3325 0.02 :fm-index 2.479 :amp-env '(0 0 65 1 100 0) :noise-amount 0.004 :fm1-env '(0 0 65 1 100 0) :fm1-rat 1.141 :fm2-rat 1.414 :fm3-rat 1.718 :reverb-amount 0.1) (fm-violin 164.2608 4 821.7484 0.0125 :fm-index 1.8667 :amp-env '(0 0 65 1 100 0) :noise-amount 0.004 :fm1-env '(0 0 65 1 100 0) :fm1-rat 3.141 :fm2-rat 4.414 :fm3-rat 2.718) (fm-violin 164.261 4 261.62 0.0125 :fm-index 1.8523 :amp-env '(0 0 65 1 100 0) :noise-amount 0.004 :fm1-env '(0 0 65 1 100 0) :fm1-rat 3.141 :fm2-rat 4.414 :fm3-rat 2.718) (fm-violin 164.2613 4 711.0832 0.0125 :fm-index 2.23 :amp-env '(0 0 65 1 100 0) :noise-amount 0.004 :fm1-env '(0 0 65 1 100 0) :fm1-rat 3.141 :fm2-rat 4.414 :fm3-rat 2.718 :reverb-amount 0.1) (fm-violin 164.2615 4 205.4371 0.0075 :fm-index 1.5187 :amp-env '(0 0 65 1 100 0) :noise-amount 0.004 :fm1-env '(0 0 65 1 100 0) :fm1-rat 3.141 :fm2-rat 4.414 :fm3-rat 2.718) (fm-violin 164.2618 4 65.405 0.0075 :fm-index 2.4074 :amp-env '(0 0 65 1 100 0) :noise-amount 0.004 :fm1-env '(0 0 65 1 100 0) :fm1-rat 3.141 :fm2-rat 4.414 :fm3-rat 2.718) (fm-violin 164.262 4 177.7708 0.0075 :fm-index 2.4481 :amp-env '(0 0 65 1 100 0) :noise-amount 0.004 :fm1-env '(0 0 65 1 100 0) :fm1-rat 3.141 :fm2-rat 4.414 :fm3-rat 2.718 :reverb-amount 0.1) (fm-violin 164.2623 4 51.3593 0.00125 :fm-index 2.3069 :amp-env '(0 0 65 1 100 0) :noise-amount 0.004 :fm1-env '(0 0 65 1 100 0) :fm1-rat 3.141 :fm2-rat 4.414 :fm3-rat 2.718) (fm-violin 164.2625 4 16.3513 0.00125 :fm-index 2.1008 :amp-env '(0 0 65 1 100 0) :noise-amount 0.004 :fm1-env '(0 0 65 1 100 0) :fm1-rat 3.141 :fm2-rat 4.414 :fm3-rat 2.718) (fm-violin 164.2628 4 44.4427 0.00125 :fm-index 2.486 :amp-env '(0 0 65 1 100 0) :noise-amount 0.004 :fm1-env '(0 0 65 1 100 0) :fm1-rat 3.141 :fm2-rat 4.414 :fm3-rat 2.718 :reverb-amount 0.1) (fm-violin 172.2603 1.2 88.8854 0.0125 :fm-index 2.3144 :amp-env '(0 0 50 1 100 0) :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.2) (fm-violin 172.2603 4 88.8854 0.0125 :fm-index 2.169 :amp-env '(0 0 50 1 100 0) :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.2) (fm-violin 172.2605 2.8 168.1236 0.00625 :fm-index 2.185 :amp-env '(0 0 50 1 100 0) :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.2) (fm-violin 172.2608 1.2 168.1236 0.01 :fm-index 1.7743 :amp-env '(0 0 50 1 100 0) :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.2) (fm-violin 172.261 2 32.7025 0.0125 :fm-index 2.4925 :amp-env '(0 0 50 1 100 0) :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.2) (fm-violin 172.2633 2 32.7025 0.0125 :fm-index 2.1325 :amp-env '(0 0 50 1 100 0) :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.2) (fm-violin 172.2643 4 32.7025 0.00625 :fm-index 1.7578 :amp-env '(0 0 50 1 100 0) :fm1-rat 2.718 :fm2-rat 4.414 :fm3-rat 5.141 :reverb-amount 0.2) (fm-violin 180.26 6.683 244.816 7.5e-4 :fm-index 2 :noise-amount 0.004 :reverb-amount 0.2) (fm-violin 180.26 5.517 495.404 7.5e-4 :fm-index 2 :noise-amount 0.004 :reverb-amount 0.2) (fm-violin 180.26 7.535 980.619 2.5e-4 :fm-index 2 :noise-amount 0.004 :reverb-amount 0.2) (fm-violin 180.26 7.199 1965.429 2.5e-4 :fm-index 0.8 :fm2-rat 1.0 :fm3-rat 1.0 :noise-amount 0.004 :reverb-amount 0.2) (fm-violin 180.26 4.079 3835.317 2.5e-4 :fm-index 0.8 :fm2-rat 1.0 :fm3-rat 1.0 :noise-amount 0.004 :reverb-amount 0.2) (fm-violin 180.517 4.74 1320.967 2.5e-4 :fm-index 0.8 :fm2-rat 1.0 :fm3-rat 1.0 :noise-amount 0.004 :reverb-amount 0.2) (fm-violin 180.704 7.208 655.567 5.e-4 :fm-index 2 :noise-amount 0.004 :reverb-amount 0.2) (fm-violin 181.049 6.653 169.423 5.e-4 :fm-index 2 :noise-amount 0.004 :reverb-amount 0.2) (fm-violin 189.545 6.465 366.333 0.004 :fm-index 1.048 :amp-env '(0 0 1.5468 1 2.0882 0.7 2.3202 1 98.4532 0.75 100.0 0) :base 0.03125 :reverb-amount 0.9) (fm-violin 189.595 8.434 1172.583 0.00225 :fm-index 1.135 :amp-env '(0 0 1.1857 1.0 1.6007 0.7 1.7785 1 98.8143 0.5556 100.0 0) :base 0.03125 :reverb-amount 0.9) (fm-violin 189.765 1.621 369.994 0.002125 :fm-index 0.096 :amp-env '(0 0 6.169 1.0 8.3282 0.7 9.2535 1.0 93.831 0.5294 100.0 0) :base 0.03125 :reverb-amount 0.9) (fm-violin 189.882 3.064 246.942 0.002125 :fm-index 0.002 :amp-env '(0 0 3.2637 1 4.406 0.7 4.8956 1.0 96.7363 0.5294 100.0 0) :base 0.03125 :reverb-amount 0.9) (fm-violin 189.925 3.117 123.471 0.00475 :fm-index 0.233 :amp-env '(0 0 3.2082 1 4.3311 0.7 4.8123 1 96.7918 0.7895 100.0 0) :base 0.03125 :reverb-amount 0.9) (fm-violin 189.981 3.567 123.471 0.00525 :fm-index 0.233 :amp-env '(0 0 2.8035 1 3.7847 0.7 4.2052 1.0 97.1965 0.8095 100.0 0) :base 0.03125 :reverb-amount 0.9) (fm-violin 190.128 1.045 246.942 0.002125 :fm-index 1.205 :amp-env '(0 0 9.5694 1 12.9187 0.7 14.3541 1 90.4306 0.5294 100.0 0) :base 0.03125 :reverb-amount 0.9) (fm-violin 190.255 3.387 374.137 0.002125 :fm-index 0.18 :amp-env '(0 0 2.9525 1.0 3.9858 0.7 4.4287 1.0 97.0475 0.5294 100.0 0) :base 0.03125 :reverb-amount 0.9) (fm-violin 190.299 8.305 1576.912 0.0025 :fm-index 0.299 :amp-env '(0 0 1.2041 1 1.6255 0.7 1.8061 1 98.7959 0.6 100.0 0) :base 0.03125 :reverb-amount 0.9) (fm-violin 190.33 4.463 246.942 0.002125 :fm-index 0.002 :amp-env '(0 0 2.2406 1 3.0249 0.7 3.361 1.0 97.7594 0.5294 100.0 0) :base 0.03125 :reverb-amount 0.9) (fm-violin 190.66 8.994 1576.912 0.0025 :fm-index 0.299 :fm2-rat 1.0 :fm3-rat 1.0 :amp-env '(0 0 1.1119 1 1.501 0.7 1.6678 1 98.8881 0.6 100.0 0) :base 0.03125 :reverb-amount 0.9) (fm-violin 190.906 8.836 1172.583 0.00225 :fm-index 1.135 :amp-env '(0 0 1.1317 1 1.5278 0.7 1.6976 1 98.8683 0.5556 100.0 0) :base 0.03125 :reverb-amount 0.9) (fm-violin 191.151 4.932 374.137 0.002125 :fm-index 0.18 :amp-env '(0 0 2.0276 1 2.7372 0.7 3.0414 1 97.9724 0.5294 100.0 0) :base 0.03125 :reverb-amount 0.9) (fm-violin 191.272 2.325 369.994 0.002125 :fm-index 1.103 :amp-env '(0 0 4.3011 1 5.8065 0.7 6.4516 1 95.6989 0.5294 100.0 0) :base 0.03125 :reverb-amount 0.9) (fm-violin 192.696 3.554 366.333 0.003875 :fm-index 1.048 :amp-env '(0 0 2.8137 1 3.7985 0.7 4.2206 1 97.1863 0.7419 100.0 0) :base 0.03125 :reverb-amount 0.9) (fm-violin 193.724 0.604 246.942 0.002125 :fm-index 1.205 :amp-env '(0 0 16.5563 1 22.351 0.7 24.8344 1 83.4437 0.5294 100 0) :base 0.03125 :reverb-amount 0.9) (fm-violin 193.942 2.501 123.471 0.004125 :fm-index 0.233 :amp-env '(0 0 3.9984 1 5.3978 0.7 5.9976 1 96.0016 0.7576 100.0 0) :base 0.03125 :reverb-amount 0.9) (fm-violin 194.034 2.386 246.942 0.002125 :fm-index 0.002 :amp-env '(0 0 4.1911 1 5.658 0.7 6.2867 1 95.8089 0.5294 100.0 0) :base 0.03125 :reverb-amount 0.9) (fm-violin 194.385 1.451 369.994 0.002125 :fm-index 1.103 :amp-env '(0 0 6.8918 1 9.3039 0.7 10.3377 1 93.1082 0.5294 100.0 0) :base 0.03125 :reverb-amount 0.9) (fm-violin 194.567 2.655 374.137 0.002125 :fm-index 0.18 :amp-env '(0 0 3.7665 1 5.0847 0.7 5.6497 1 96.2335 0.5294 100.0 0) :base 0.03125 :reverb-amount 0.9) (fm-violin 194.983 2.986 123.471 0.00475 :fm-index 0.233 :amp-env '(0 0 3.349 1 4.5211 0.7 5.0234 1 96.651 0.7895 100.0 0) :base 0.03125 :reverb-amount 0.9) (fm-violin 195.491 0.611 123.977 0.002125 :fm-index 0.755 :amp-env '(0 0 16.3666 1 22.0949 0.7 24.5499 1 83.6334 0.5294 100.0 0) :base 0.03125 :reverb-amount 0.9) (fm-violin 195.757 1.444 123.471 0.002125 :fm-index 0.002 :amp-env '(0 0 6.9252 1 9.349 0.7 10.3878 1 93.0748 0.5294 100.0 0) :base 0.03125 :reverb-amount 0.9) (fm-violin 195.775 0.537 92.4435 0.004125 :fm-index 0.92 :amp-env '(0 0 18.622 1 25.1397 0.7 27.933 1 81.378 0.7576 100.0 0) :base 0.03125 :reverb-amount 0.9) (fm-violin 195.775 10.537 92.4435 0.001625 :fm-index 0.92 :amp-env '(0 0 0.949 1 1.2812 0.7 1.4236 1 99.051 0.3846 100.0 0) :base 0.03125 :reverb-amount 0.9) (fm-violin 195.938 0.652 122.2995 0.002125 :fm-index 1.838 :amp-env '(0 0 15.3374 1 20.7055 0.7 23.0061 1 84.6626 0.5294 100.0 0) :base 0.03125 :reverb-amount 0.9) (fm-violin 196.235 3.725 586.2915 0.00225 :fm-index 1.135 :amp-env '(0 0 2.6846 1 3.6242 0.7 4.0268 1 97.3154 0.5556 100.0 0) :base 0.03125 :reverb-amount 0.9) (fm-violin 196.256 2.89 183.1665 0.00325 :fm-index 1.048 :amp-env '(0 0 3.4602 1 4.6713 0.7 5.1903 1 96.5398 0.6923 100.0 0) :base 0.03125 :reverb-amount 0.9) (fm-violin 196.271 1.621 187.0685 0.002125 :fm-index 0.18 :amp-env '(0 0 6.169 1.0 8.3282 0.7 9.2535 1.0 93.831 0.5294 100.0 0) :base 0.03125 :reverb-amount 0.9) (fm-violin 196.292 2.016 183.1665 0.003625 :fm-index 1.048 :amp-env '(0 0 4.9603 1 6.6964 0.7 7.4405 1 95.0397 0.7241 100.0 0) :base 0.03125 :reverb-amount 0.9) (fm-violin 196.292 12.016 183.1665 0.003625 :fm-index 1.048 :amp-env '(0 0 0.8322 1 1.1235 0.7 1.2483 1.0 99.1678 0.7241 100.0 0) :base 0.03125 :reverb-amount 0.9) (fm-violin 196.33 0.73 184.997 0.002125 :fm-index 0.096 :amp-env '(0 0 13.6986 1 18.4932 0.7 20.5479 1.0 86.3014 0.5294 100 0) :base 0.03125 :reverb-amount 0.9) (fm-violin 196.357 1.96 183.1665 0.0035 :fm-index 1.048 :amp-env '(0 0 5.102 1.0 6.8878 0.7 7.6531 1.0 94.898 0.7143 100.0 0) :base 0.03125 :reverb-amount 0.9) (fm-violin 196.382 2.245 61.7355 0.004125 :fm-index 0.233 :amp-env '(0 0 4.4543 1 6.0134 0.7 6.6815 1 95.5457 0.7576 100.0 0) :base 0.03125 :reverb-amount 0.9) (fm-violin 196.382 12.245 61.7355 0.004125 :fm-index 0.233 :amp-env '(0 0 0.8167 1 1.1025 0.7 1.225 1 99.1833 0.7576 100.0 0) :base 0.03125 :reverb-amount 0.9) (fm-violin 196.541 3.013 246.505 0.0045 :fm-index 1.135 :amp-env '(0 0 3.319 1.0 4.4806 0.7 4.9784 1.0 96.681 0.7778 100.0 0) :base 0.03125 :reverb-amount 0.9) (fm-violin 196.557 2.322 1251.596 0.005 :fm-index 0.299 :amp-env '(0 0 4.3066 1 5.814 0.7 6.4599 1 95.6934 0.8 100.0 0) :base 0.03125 :reverb-amount 0.9) (fm-violin 196.557 18.322 1251.596 0.0025 :fm-index 0.299 :amp-env '(0 0 0.5458 1.0 0.7368 0.7 0.8187 1 99.4542 0.6 100.0 0) :base 0.03125 :reverb-amount 0.9) (fm-violin 196.56 13.877 3951.12 7.5e-4 :fm-index 0.5 :fm2-rat 1.0 :fm3-rat 1.0 :amp-env '(0 0 15 1 100 0) :reverb-amount 0.9) (fm-violin 196.76 17.877 493.89 0.002125 :fm-index 0.528 :amp-env '(0 0 15 1 100 0) :reverb-amount 0.9) (fm-violin 197.106 1.99 183.1665 0.002875 :fm-index 1.048 :amp-env '(0 0 5.0251 1.0 6.7839 0.7 7.5377 1 94.9749 0.6522 100.0 0) :base 0.03125 :reverb-amount 0.9) (fm-violin 197.16 13.877 1975.56 0.001375 :fm-index 1.2 :amp-env '(0 0 15 1 100 0) :reverb-amount 0.9) (fm-violin 197.257 1.918 61.7355 0.004125 :fm-index 0.233 :amp-env '(0 0 5.2138 1 7.0386 0.7 7.8206 1 94.7862 0.7576 100.0 0) :base 0.03125 :reverb-amount 0.9) (fm-violin 197.26 15.877 246.945 0.002125 :fm-index 0.528 :amp-env '(0 0 15 1 100 0) :reverb-amount 0.9) (fm-violin 197.637 1.309 183.1665 0.003875 :fm-index 1.048 :amp-env '(0 0 7.6394 1 10.3132 0.7 11.4591 1 92.3606 0.7419 100.0 0) :base 0.03125 :reverb-amount 0.9) (fm-violin 197.86 16.877 987.78 0.001625 :fm-index 1.5 :amp-env '(0 0 15 1 100 0) :reverb-amount 0.9) (fm-violin 198.033 1.159 183.1665 0.003125 :fm-index 1.048 :amp-env '(0 0 8.6281 1 11.648 0.7 12.9422 1.0 91.3719 0.68 100.0 0) :base 0.03125 :reverb-amount 0.9) (fm-violin 198.06 13.877 3951.12 0.001125 :fm2-rat 1.0 :fm3-rat 1.0 :amp-env '(0 0 15 1 100 0) :reverb-amount 0.9) (fm-violin 198.098 1.24 30.8675 0.004125 :fm-index 0.233 :amp-env '(0 0 8.0645 1 10.8871 0.7 12.0968 1 91.9355 0.7576 100.0 0) :base 0.03125 :reverb-amount 0.9) (fm-violin 198.098 11.24 30.8675 0.001625 :fm-index 0.233 :amp-env '(0 0 0.8897 1 1.2011 0.7 1.3345 1 99.1103 0.3846 100.0 0) :base 0.03125 :reverb-amount 0.9) (fm-violin 198.126 0.26 123.471 0.002125 :fm-index 1.205 :amp-env '(0 0 38.4615 1 51.9231 0.7 57.6923 1 61.5385 0.5294 100.0 0) :base 0.03125 :reverb-amount 0.9) (fm-violin 198.126 10.26 123.471 0.002125 :fm-index 1.205 :amp-env '(0 0 0.9747 1 1.3158 0.7 1.462 1 99.0253 0.5294 100.0 0) :base 0.03125 :reverb-amount 0.9) (fm-violin 198.26 14.877 123.4725 0.002125 :fm-index 1.5 :amp-env '(0 0 15 1 100 0) :reverb-amount 0.9) (fm-violin 198.26 13.877 61.7363 0.002125 :fm-index 1.5 :amp-env '(0 0 15 1 100 0) :reverb-amount 0.9) (fm-violin 198.26 12.877 30.8681 0.002125 :fm-index 1.5 :amp-env '(0 0 15 1 100 0) :reverb-amount 0.9) (fm-violin 198.26 11.877 15.4341 0.002125 :fm-index 1.5 :amp-env '(0 0 15 1 100 0) :reverb-amount 0.9) (fm-violin 217.262 0.3906 440 0.05625 :fm-index 1.2 :amp-env '(0 0 0.768 1 4.7774 0.6 9.7891 0.3 24.8243 0.1 100 0) :reverb-amount 0.0013) (fm-violin 217.264 0.522 220 0.05625 :fm-index 1.2 :amp-env '(0 0 0.5747 1.0 4.5919 0.6 9.6134 0.3 24.6778 0.1 100 0) :reverb-amount 0.0012) (fm-violin 217.266 1.566 880 0.05625 :fm-index 1.2 :amp-env '(0 0 0.1916 1.0 4.2242 0.6 9.2651 0.3 24.3876 0.1 100.0 0) :reverb-amount 0.0014) (fm-violin 217.268 1.566 110 0.05625 :fm-index 1.2 :amp-env '(0 0 0.1916 1.0 4.2242 0.6 9.2651 0.3 24.3876 0.1 100.0 0) :reverb-amount 0.0013) (fm-violin 220.86 0.9 733.333 0.0234375 :fm-index 0.2 :amp-env '(0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.495 0.1 100.0 0) :reverb-amount 0.0012) (fm-violin 220.86 0.225 550 0.0234375 :fm-index 0.2 :amp-env '(0 0 1.3333 1 5.3199 0.6 10.303 0.3 25.2525 0.1 100 0) :reverb-amount 0.0015) (fm-violin 220.86 0.45 586.667 0.046875 :fm-index 0.2 :amp-env '(0 0 0.6667 1 4.6801 0.6 9.697 0.3 24.7475 0.1 100 0) :reverb-amount 0.0013) (fm-violin 220.902 0.9 733.333 0.0234375 :fm-index 0.4 :amp-env '(0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.495 0.1 100.0 0) :reverb-amount 0.0013) (fm-violin 220.902 0.225 550 0.0234375 :fm-index 0.4 :amp-env '(0 0 1.3333 1 5.3199 0.6 10.303 0.3 25.2525 0.1 100 0) :reverb-amount 0.001) (fm-violin 220.902 0.45 586.667 0.046875 :fm-index 0.4 :amp-env '(0 0 0.6667 1 4.6801 0.6 9.697 0.3 24.7475 0.1 100 0) :reverb-amount 0.0015) (fm-violin 220.943 0.9 366.667 0.0234375 :fm-index 0.6 :amp-env '(0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.495 0.1 100.0 0) :reverb-amount 0.0016) (fm-violin 220.943 0.225 275 0.0234375 :fm-index 0.6 :amp-env '(0 0 1.3333 1 5.3199 0.6 10.303 0.3 25.2525 0.1 100 0) :reverb-amount 0.0015) (fm-violin 220.943 0.45 293.334 0.046875 :fm-index 0.6 :amp-env '(0 0 0.6667 1 4.6801 0.6 9.697 0.3 24.7475 0.1 100 0) :reverb-amount 0.0015) (fm-violin 220.985 0.9 733.333 0.0234375 :fm-index 0.8 :amp-env '(0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.495 0.1 100.0 0) :reverb-amount 0.001) (fm-violin 220.985 0.225 550 0.0234375 :fm-index 0.8 :amp-env '(0 0 1.3333 1 5.3199 0.6 10.303 0.3 25.2525 0.1 100 0) :reverb-amount 0.0013) ) snd-16.1/snd-glistener.c0000644000076400007640000006306312614436174013275 0ustar bilbil#include "snd.h" #include "snd-menu.h" static GtkWidget *listener_text = NULL; static GtkTextBuffer *listener_buffer = NULL; void listener_append(const char *msg) { if (ss->listener) glistener_append_text(ss->listener, msg); if (listener_text) ss->graph_is_active = false; } void listener_append_and_prompt(const char *msg) { if (msg) { glistener_append_text(ss->listener, msg); glistener_append_prompt(ss->listener); } else { if (ss->listener) glistener_append_text(ss->listener, "\n"); } } static Xen listener_click_hook; static Xen mouse_enter_listener_hook; static Xen mouse_leave_listener_hook; static gboolean listener_focus_callback(GtkWidget *w, GdkEventCrossing *ev, gpointer unknown) { if (with_pointer_focus(ss)) goto_window(listener_text); if (Xen_hook_has_list(mouse_enter_listener_hook)) run_hook(mouse_enter_listener_hook, Xen_list_1(Xen_wrap_widget(listener_text)), S_mouse_enter_listener_hook); cursor_set_blinks(w, true); return(false); } static gboolean listener_unfocus_callback(GtkWidget *w, GdkEventCrossing *ev, gpointer unknown) { if (Xen_hook_has_list(mouse_leave_listener_hook)) run_hook(mouse_leave_listener_hook, Xen_list_1(Xen_wrap_widget(listener_text)), S_mouse_leave_listener_hook); cursor_set_blinks(w, false); return(false); } static gboolean listener_button_press(GtkWidget *w, GdkEventButton *ev, gpointer data) { ss->graph_is_active = false; return(false); } static gboolean listener_key_press(GtkWidget *w, GdkEventKey *event, gpointer data) { guint key; GdkModifierType state; /* clear possible warning */ /* glistener_clear_status(ss->listener); */ key = EVENT_KEYVAL(event); state = (GdkModifierType)EVENT_STATE(event); if ((state & snd_ControlMask) && ((key == snd_K_g) || (key == snd_K_G))) ss->C_g_typed = true; if (ss->graph_is_active) { chan_info *cp; cp = current_channel(); if (!cp) ss->graph_is_active = false; else { graph_key_press(channel_graph(cp), event, (gpointer)cp); return(true); /* don't repeat the keystroke?? */ } } return(false); } #if HAVE_SCHEME static s7_pointer g_listener_load_hook(s7_scheme *sc, s7_pointer args) { /* arg is the hook, (hook 'name) is the file */ s7_pointer hook, file; if (!(ss->listener)) return(args); char msg[128]; hook = s7_car(args); file = s7_let_ref(s7, hook, s7_make_symbol(s7, "name")); if (!s7_is_string(file)) s7_wrong_type_arg_error(sc, "glistener *load-hook*", 1, file, "a hook with a 'name field, the file being loaded"); snprintf(msg, 128, "loading %s", s7_string(file)); glistener_post_status(ss->listener, msg); return(args); } #endif static void listener_init(glistener *g, GtkWidget *w) { listener_text = w; listener_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(w)); set_listener_text_font(); add_listener_style(w); SG_SIGNAL_CONNECT(w, "key_press_event", listener_key_press, NULL); /* Snd's should run first */ SG_SIGNAL_CONNECT(w, "button_press_event", listener_button_press, NULL); SG_SIGNAL_CONNECT(w, "enter_notify_event", listener_focus_callback, NULL); SG_SIGNAL_CONNECT(w, "leave_notify_event", listener_unfocus_callback, NULL); glistener_set_prompt_tag(ss->listener, gtk_text_buffer_create_tag(listener_buffer, "glistener_prompt_tag", "weight", PANGO_WEIGHT_BOLD, /* "foreground", "red", */ NULL)); ss->listener_pane = w; } #if HAVE_SCHEME static const char *helper(glistener *g, const char *text) { s7_pointer sym; if (!text) return(NULL); sym = s7_symbol_table_find_name(s7, text); if (sym) return(s7_help(s7, sym)); glistener_clear_status(g); return(NULL); } #if HAVE_CHECKER static const char *checker(glistener *g, const char *text) { int gc_loc, err_loc; s7_pointer port, err_port, result; const char *errmsg; bool err = false; result = s7_f(s7); if (s7_begin_hook(s7) != NULL) return(NULL); err_port = s7_set_current_error_port(s7, s7_open_output_string(s7)); err_loc = s7_gc_protect(s7, err_port); port = s7_open_input_string(s7, text); gc_loc = s7_gc_protect(s7, port); result = s7_read(s7, port); errmsg = s7_get_output_string(s7, err_port); if (errmsg) {err = true; glistener_post_status(g, errmsg);} s7_close_input_port(s7, port); s7_gc_unprotect_at(s7, gc_loc); s7_close_output_port(s7, s7_current_error_port(s7)); s7_set_current_error_port(s7, err_port); s7_gc_unprotect_at(s7, err_loc); if ((!err) && (s7_is_pair(result))) { s7_pointer sym; sym = s7_car(result); if (s7_is_symbol(sym)) { s7_pointer val; val = s7_symbol_value(s7, sym); if ((val != s7_undefined(s7)) && (!s7_is_aritable(s7, val, s7_list_length(s7, result) - 1))) { glistener_post_status(g, "wrong number of args"); } } } return(NULL); } #endif static GtkTextTag *string_tag = NULL, *comment_tag = NULL, *comment3_tag = NULL, *block_comment_tag = NULL; static GtkTextTag *syntax_tag = NULL, *macro_tag = NULL, *procedure_tag = NULL, *constant_tag = NULL; static GtkTextTag *undefined_tag = NULL; /* also bracket and character */ static s7_pointer g_colorizer_colors(s7_scheme *sc, s7_pointer args) { #define H_colorizer_colors "(colorizer-colors comment comment3 block-comment string constant syntax macro procedure undefined)" /* set the tag colors from scheme -- tags are owned by the buffer, so I assume we don't free the old ones * * default: (colorizer-colors "red" "brown" "orangered" "gray40" "gray20" "blue" "seagreen" "steelblue4" "black") */ int i; s7_pointer p; for (p = args, i = 1; s7_is_pair(p); p = s7_cdr(p), i++) { if (!s7_is_string(s7_car(p))) s7_wrong_type_arg_error(sc, "colorizer-colors", i, s7_car(p), "a color name (a string)"); } p = args; if (s7_is_pair(p)) {comment_tag = gtk_text_buffer_create_tag(listener_buffer, NULL, "foreground", s7_string(s7_car(p)), NULL); p = s7_cdr(p);} if (s7_is_pair(p)) {comment3_tag = gtk_text_buffer_create_tag(listener_buffer, NULL, "foreground", s7_string(s7_car(p)), NULL); p = s7_cdr(p);} if (s7_is_pair(p)) {block_comment_tag = gtk_text_buffer_create_tag(listener_buffer, NULL, "foreground", s7_string(s7_car(p)), NULL); p = s7_cdr(p);} if (s7_is_pair(p)) {string_tag = gtk_text_buffer_create_tag(listener_buffer, NULL, "foreground", s7_string(s7_car(p)), NULL); p = s7_cdr(p);} if (s7_is_pair(p)) {constant_tag = gtk_text_buffer_create_tag(listener_buffer, NULL, "foreground", s7_string(s7_car(p)), NULL); p = s7_cdr(p);} if (s7_is_pair(p)) {syntax_tag = gtk_text_buffer_create_tag(listener_buffer, NULL, "foreground", s7_string(s7_car(p)), NULL); p = s7_cdr(p);} if (s7_is_pair(p)) {macro_tag = gtk_text_buffer_create_tag(listener_buffer, NULL, "foreground", s7_string(s7_car(p)), NULL); p = s7_cdr(p);} if (s7_is_pair(p)) {procedure_tag = gtk_text_buffer_create_tag(listener_buffer, NULL, "foreground", s7_string(s7_car(p)), NULL); p = s7_cdr(p);} if (s7_is_pair(p)) {undefined_tag = gtk_text_buffer_create_tag(listener_buffer, NULL, "foreground", s7_string(s7_car(p)), NULL); p = s7_cdr(p);} return(s7_t(sc)); } static void colorizer(glistener *g, glistener_colorizer_t type, int start, int end) { GtkTextIter s1, s2; GtkTextTag *tag; if (!comment_tag) { comment_tag = gtk_text_buffer_create_tag(listener_buffer, NULL, "foreground", "red", NULL); comment3_tag = gtk_text_buffer_create_tag(listener_buffer, NULL, "foreground", "brown", NULL); block_comment_tag = gtk_text_buffer_create_tag(listener_buffer, NULL, "foreground", "orangered", NULL); string_tag = gtk_text_buffer_create_tag(listener_buffer, NULL, "foreground", "gray40", NULL); constant_tag = gtk_text_buffer_create_tag(listener_buffer, NULL, "foreground", "gray20", NULL); syntax_tag = gtk_text_buffer_create_tag(listener_buffer, NULL, "foreground", "blue", NULL); macro_tag = gtk_text_buffer_create_tag(listener_buffer, NULL, "foreground", "seagreen", NULL); procedure_tag = gtk_text_buffer_create_tag(listener_buffer, NULL, "foreground", "steelblue4", NULL); undefined_tag = gtk_text_buffer_create_tag(listener_buffer, NULL, "foreground", "black", NULL); } tag = NULL; switch (type) { case GLISTENER_COMMENT: tag = comment_tag; if (comment3_tag) { /* presumably ;;; ... is handled differently in this case */ GtkTextIter iter; gtk_text_buffer_get_iter_at_offset(listener_buffer, &iter, start); /* is start the start of a line, and are the first 3 chars semicolons */ if ((gtk_text_iter_starts_line(&iter)) && ((end - start) > 2)) { char *text; text = glistener_text(ss->listener, start, start + 3); if (text) { if (strcmp(text, ";;;") == 0) tag = comment3_tag; free(text); } } } break; case GLISTENER_BLOCK_COMMENT: tag = block_comment_tag; break; case GLISTENER_STRING: tag = string_tag; break; case GLISTENER_ATOM: { char *text; tag = NULL; text = glistener_text(ss->listener, start, end); if (text[0] == '#') { tag = constant_tag; } else { s7_pointer sym; sym = s7_symbol_table_find_name(s7, text); if (sym) { if (s7_is_syntax(s7_symbol_value(s7, sym))) tag = syntax_tag; else { if (s7_is_procedure(s7_symbol_value(s7, sym))) tag = procedure_tag; else { if (s7_is_macro(s7, sym)) tag = macro_tag; else { if (!s7_is_defined(s7, text)) { tag = undefined_tag; } } } } } else { } } if (text) free(text); } break; case GLISTENER_LIST: case GLISTENER_BRACKET: case GLISTENER_CHARACTER: break; } if (!tag) return; gtk_text_buffer_get_iter_at_offset(listener_buffer, &s1, start); gtk_text_buffer_get_iter_at_offset(listener_buffer, &s2, end); gtk_text_buffer_apply_tag(listener_buffer, tag, &s1, &s2); } static void completer(glistener *g, bool (*symbol_func)(const char *symbol_name, void *data), void *data) { s7_for_each_symbol_name(s7, symbol_func, data); } static s7_pointer top_level_let = NULL; static s7_pointer g_top_level_let(s7_scheme *sc, s7_pointer args) { return(top_level_let); } static s7_pointer g_set_top_level_let(s7_scheme *sc, s7_pointer args) { top_level_let = s7_car(args); return(top_level_let); } static void evaluator(glistener *g, const char *text) { int gc_loc; s7_pointer old_port, result; char *errmsg = NULL; if (s7_begin_hook(s7) != NULL) return; /* s7 is already running (user typed during computation) */ old_port = s7_set_current_error_port(s7, s7_open_output_string(s7)); gc_loc = s7_gc_protect(s7, old_port); if (with_interrupts(ss)) s7_set_begin_hook(s7, listener_begin_hook); result = s7_eval_c_string_with_environment(s7, text, top_level_let); s7_set_begin_hook(s7, NULL); errmsg = mus_strdup(s7_get_output_string(s7, s7_current_error_port(s7))); s7_close_output_port(s7, s7_current_error_port(s7)); s7_set_current_error_port(s7, old_port); s7_gc_unprotect_at(s7, gc_loc); if (errmsg) { if (*errmsg) snd_display_result(errmsg, NULL); free(errmsg); } else snd_report_listener_result(result); } static s7_pointer wrap_glistener(glistener *g) { return(s7_make_c_pointer(s7, (void *)g)); } static glistener *unwrap_glistener(s7_scheme *sc, const char *caller, s7_pointer p) { glistener *g; if (!s7_is_c_pointer(p)) s7_wrong_type_arg_error(sc, caller, 1, p, "a c-pointer"); g = (glistener *)s7_c_pointer(p); if (!g) s7_wrong_type_arg_error(sc, caller, 1, p, "a non-null c-pointer"); return(g); } static s7_pointer g_evaluate(s7_scheme *sc, s7_pointer args) { char *str; s7_pointer result; str = glistener_evaluate(unwrap_glistener(sc, "listener eval", s7_car(args))); result = s7_make_string(s7, str); if (str) g_free(str); return(result); } static s7_pointer g_complete(s7_scheme *sc, s7_pointer args) { char *str; s7_pointer result; str = glistener_complete(unwrap_glistener(sc, "listener completion", s7_car(args))); result = s7_make_string(s7, str); if (str) g_free(str); return(result); } static s7_pointer g_append_text(s7_scheme *sc, s7_pointer args) { if (s7_is_string(s7_cadr(args))) glistener_append_text(unwrap_glistener(sc, "listener append_text", s7_car(args)), s7_string(s7_cadr(args))); return(s7_cadr(args)); } static s7_pointer g_insert_text(s7_scheme *sc, s7_pointer args) { if (s7_is_string(s7_cadr(args))) glistener_insert_text(unwrap_glistener(sc, "listener insert_text", s7_car(args)), s7_string(s7_cadr(args))); return(s7_cadr(args)); } static s7_pointer g_scroll_to_end(s7_scheme *sc, s7_pointer args) { glistener_scroll_to_end(unwrap_glistener(sc, "listener scroll_to_end", s7_car(args))); return(s7_car(args)); } static s7_pointer g_append_prompt(s7_scheme *sc, s7_pointer args) { glistener_append_prompt(unwrap_glistener(sc, "listener append prompt", s7_car(args))); return(s7_car(args)); } static s7_pointer g_prompt_position(s7_scheme *sc, s7_pointer args) { return(s7_make_integer(s7, glistener_prompt_position(unwrap_glistener(sc, "listener prompt position", s7_car(args))))); } static s7_pointer g_cursor_position(s7_scheme *sc, s7_pointer args) { return(s7_make_integer(s7, glistener_cursor_position(unwrap_glistener(sc, "listener cursor position", s7_car(args))))); } static s7_pointer g_set_cursor_position(s7_scheme *sc, s7_pointer args) { if (s7_is_integer(s7_cadr(args))) glistener_set_cursor_position(unwrap_glistener(sc, "set listener cursor-position", s7_car(args)), s7_integer(s7_cadr(args))); return(s7_cadr(args)); } static s7_pointer g_text(s7_scheme *sc, s7_pointer args) { if ((s7_is_integer(s7_cadr(args))) && (s7_is_integer(s7_caddr(args)))) { char *str; s7_pointer result; str = glistener_text(unwrap_glistener(sc, "listener text", s7_car(args)), s7_integer(s7_cadr(args)), s7_integer(s7_caddr(args))); result = s7_make_string(s7, str); if (str) g_free(str); return(result); } return(s7_f(sc)); } static s7_pointer g_clear(s7_scheme *sc, s7_pointer args) { glistener_clear(unwrap_glistener(sc, "listener clear", s7_car(args))); return(s7_car(args)); } static s7_pointer g_text_widget(s7_scheme *sc, s7_pointer args) { return(s7_list(sc, 2, s7_make_symbol(sc, "GtkTextView*"), s7_make_c_pointer(sc, (void *)listener_text))); } static s7_pointer g_set_prompt(s7_scheme *sc, s7_pointer args) { if (s7_is_string(s7_cadr(args))) glistener_set_prompt(unwrap_glistener(sc, "set listener prompt", s7_car(args)), s7_string(s7_cadr(args))); return(s7_cadr(args)); } static s7_pointer g_set_prompt_tag(s7_scheme *sc, s7_pointer args) { /* args: (# (GtkTextTag_ #)) */ GtkTextTag *new_tag = NULL; if (s7_is_pair(s7_cadr(args))) new_tag = (GtkTextTag *)(s7_c_pointer(s7_cadr(s7_cadr(args)))); glistener_set_prompt_tag(unwrap_glistener(sc, "set listener prompt tag", s7_car(args)), new_tag); return(s7_cadr(args)); } /* (listener-set-prompt-tag *listener* (gtk_text_buffer_create_tag (GTK_TEXT_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (listener-text-widget *listener*)))) #f (list "weight" PANGO_WEIGHT_BOLD "foreground" "red"))) */ static void glistener_init(glistener *g1) { s7_define_function(s7, "listener-append-text", g_append_text, 2, 0, false, "(listener-append-text g txt)"); s7_define_function(s7, "listener-insert-text", g_insert_text, 2, 0, false, "(listener-insert-text g txt)"); s7_define_function(s7, "listener-cursor-position", g_cursor_position, 1, 0, false, "(listener-cursor-position g)"); s7_define_function(s7, "listener-set-cursor-position", g_set_cursor_position, 2, 0, false, "(listener-set-cursor-position g pos)"); s7_define_function(s7, "listener-text", g_text, 3, 0, false, "(listener-text g start end)"); s7_define_function(s7, "listener-append-prompt", g_append_prompt, 1, 0, false, "(listener-append-prompt g)"); s7_define_function(s7, "listener-prompt-position", g_prompt_position, 1, 0, false, "(listener-prompt-position g)"); s7_define_function(s7, "listener-set-prompt", g_set_prompt, 2, 0, false, "(listener-set-prompt g str)"); s7_define_function(s7, "listener-set-prompt-tag", g_set_prompt_tag, 2, 0, false, "(listener-set-prompt-tag g tag)"); s7_define_function(s7, "listener-evaluate", g_evaluate, 1, 0, false, "(listener-evaluate g)"); s7_define_function(s7, "listener-complete", g_complete, 1, 0, false, "(listener-complete g)"); s7_define_function(s7, "listener-scroll", g_scroll_to_end, 1, 0, false, "(listener-scroll g)"); s7_define_function(s7, "listener-clear", g_clear, 1, 0, false, "(listener-clear g)"); s7_define_function(s7, "listener-text-widget", g_text_widget, 1, 0, false, "(listener-text-widget g)"); s7_define_variable(s7, "*listener*", wrap_glistener(g1)); } #endif static bool listener_colorizing = false; bool listener_colorized(void) {return(listener_colorizing);} bool listener_set_colorized(bool val) { #if HAVE_SCHEME listener_colorizing = val; s7_symbol_set_value(s7, ss->listener_colorized_symbol, s7_make_boolean(s7, val)); if (ss->listener) { if (val) glistener_set_colorizer(ss->listener, colorizer); else glistener_set_colorizer(ss->listener, NULL); } #endif return(val); } #if HAVE_FORTH || HAVE_RUBY static void evaluator(glistener *g, const char *text) { call_read_hook_or_eval(text); /* snd-listener.c */ } #endif static bool keyer(glistener *g, GtkWidget *w, GdkEventKey *e) { /* add C-g handling */ guint key; GdkModifierType state; key = EVENT_KEYVAL(e); state = (GdkModifierType)EVENT_STATE(e); if (((key == snd_K_g) || (key == snd_K_G)) && (state & snd_ControlMask)) { ss->C_g_typed = true; control_g(any_selected_sound()); } return(false); } static void make_listener_widget(int height) { #if HAVE_EXTENSION_LANGUAGE if (!listener_text) { GtkWidget *frame; frame = gtk_frame_new(NULL); gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN); gtk_widget_show(frame); if (sound_style(ss) != SOUNDS_IN_SEPARATE_WINDOWS) gtk_paned_pack2(GTK_PANED(SOUND_PANE(ss)), frame, false, true); /* add2 but resize=false */ else gtk_container_add(GTK_CONTAINER(MAIN_PANE(ss)), frame); ss->listener = glistener_new(frame, listener_init); glistener_set_evaluator(ss->listener, evaluator); glistener_set_keyer(ss->listener, keyer); #if HAVE_SCHEME glistener_set_helper(ss->listener, helper); #if HAVE_CHECKER glistener_set_checker(ss->listener, checker); #endif glistener_set_completer(ss->listener, completer); if (listener_colorizing) glistener_set_colorizer(ss->listener, colorizer); glistener_init(ss->listener); #endif #if HAVE_FORTH || HAVE_RUBY glistener_is_schemish(ss->listener, false); #endif } #endif } void goto_listener(void) { goto_window(listener_text); } void color_listener(color_info *pix) { ss->listener_color = pix; #if HAVE_SCHEME s7_symbol_set_value(s7, ss->listener_color_symbol, Xen_wrap_pixel(pix)); #endif #if (!GTK_CHECK_VERSION(3, 0, 0)) glistener_set_background_color(ss->listener, rgb_to_gdk_color(ss->listener_color)); #else glistener_set_background_color(ss->listener, (GdkRGBA *)(ss->listener_color)); #endif } void color_listener_text(color_info *pix) { ss->listener_text_color = pix; #if HAVE_SCHEME s7_symbol_set_value(s7, ss->listener_text_color_symbol, Xen_wrap_pixel(pix)); #endif #if (!GTK_CHECK_VERSION(3, 0, 0)) glistener_set_text_color(ss->listener, rgb_to_gdk_color(ss->listener_text_color)); #else glistener_set_text_color(ss->listener, (GdkRGBA *)(ss->listener_text_color)); #endif } void handle_listener(bool open) { if (!open) return; if (!listener_text) { make_listener_widget(100); color_listener(ss->listener_color); color_listener_text(ss->listener_text_color); gtk_widget_hide(view_listener_menu); } if ((SOUND_PANE(ss)) && /* might be run -separate with no sound open */ (sound_style(ss) != SOUNDS_IN_SEPARATE_WINDOWS)) { int hgt; hgt = widget_height(SOUND_PANE(ss)); if (hgt > 100) /* we can get here before the sound window has opened, but with one pending. * the position is in terms of current size, which is useless in this case. */ gtk_paned_set_position(GTK_PANED(SOUND_PANE(ss)), (gint)(hgt * .75)); } } bool listener_exists(void) { return((bool)listener_text); } int listener_height(void) { if (!listener_text) return(0); return(100); } int listener_width(void) { if (!listener_text) return(0); return(500); } static Xen g_listener_selection(void) { #define H_listener_selection "(" S_listener_selection "): currently selected text in listener or " PROC_FALSE Xen res = Xen_false; if (listener_text) { GtkTextIter start, end; if (gtk_text_buffer_get_selection_bounds(listener_buffer, &start, &end)) { char *txt; txt = gtk_text_buffer_get_text(listener_buffer, &start, &end, true); if (txt) { res = C_string_to_Xen_string(txt); g_free(txt); } } } return(res); } void set_listener_text_font(void) { /* (set! (listener-font) "Monospace 12") */ glistener_set_font(ss->listener, LISTENER_FONT(ss)); } static Xen g_reset_listener_cursor(void) { #define H_reset_listener_cursor "(" S_reset_listener_cursor "): reset listener cursor to the default pointer" if (listener_text) glistener_set_cursor_shape(ss->listener, ss->arrow_cursor); return(Xen_false); } void clear_listener(void) { if (ss->listener) glistener_clear(ss->listener); } void append_listener_text(int end, const char *msg) { /* "end" arg needed in Motif */ if (ss->listener) glistener_append_text(ss->listener, msg); } int save_listener_text(FILE *fp) { if (ss->listener) { if ((!listener_text) || (glistener_write(ss->listener, fp))) return(0); } return(-1); } static Xen g_goto_listener_end(void) { #define H_goto_listener_end "(" S_goto_listener_end "): move cursor and scroll to bottom of listener pane" if (ss->listener) glistener_scroll_to_end(ss->listener); return(Xen_false); } Xen_wrap_no_args(g_listener_selection_w, g_listener_selection) Xen_wrap_no_args(g_reset_listener_cursor_w, g_reset_listener_cursor) Xen_wrap_no_args(g_goto_listener_end_w, g_goto_listener_end) void g_init_gxlistener(void) { #if HAVE_SCHEME #define H_mouse_enter_listener_hook S_mouse_enter_listener_hook " (widget): called when the mouse \ enters the lisp listener pane:\n\ (hook-push " S_mouse_enter_listener_hook "\n\ (lambda (hook)\n\ (" S_focus_widget " (hook 'widget))))" #endif #if HAVE_RUBY #define H_mouse_enter_listener_hook S_mouse_enter_listener_hook " (listener): called when the mouse \ enters the lisp listener pane:\n\ $mouse_enter_listener_hook.add-hook!(\"enter\") do |widget|\n\ focus_widget(widget)\n\ end" #endif #if HAVE_FORTH #define H_mouse_enter_listener_hook S_mouse_enter_listener_hook " (listener): called when the mouse \ enters the lisp listener pane:\n\ " S_mouse_enter_listener_hook " lambda: <{ wid }> wid " S_focus_widget " ; add-hook!" #endif #define H_mouse_leave_listener_hook S_mouse_leave_listener_hook " (widget): called when the mouse \ leaves the lisp listener pane" mouse_enter_listener_hook = Xen_define_hook(S_mouse_enter_listener_hook, "(make-hook 'widget)", 1, H_mouse_enter_listener_hook); mouse_leave_listener_hook = Xen_define_hook(S_mouse_leave_listener_hook, "(make-hook 'widget)", 1, H_mouse_leave_listener_hook); Xen_define_procedure(S_listener_selection, g_listener_selection_w, 0, 0, 0, H_listener_selection); Xen_define_procedure(S_reset_listener_cursor, g_reset_listener_cursor_w, 0, 0, 0, H_reset_listener_cursor); Xen_define_procedure(S_goto_listener_end, g_goto_listener_end_w, 0, 0, 0, H_goto_listener_end); #define H_listener_click_hook S_listener_click_hook " (position): called when listener clicked; position is text pos of click in listener" listener_click_hook = Xen_define_hook(S_listener_click_hook, "(make-hook 'position)", 1, H_listener_click_hook); #if HAVE_SCHEME top_level_let = s7_nil(s7); s7_define_variable(s7, "top-level-let", s7_dilambda(s7, "top-level-let", g_top_level_let, 0, 0, g_set_top_level_let, 1, 0, "listener environment")); s7_define_function(s7, "colorizer-colors", g_colorizer_colors, 0, 0, true, H_colorizer_colors); s7_hook_set_functions(s7, s7_name_to_value(s7, "*load-hook*"), s7_cons(s7, s7_make_function(s7, "listener-load-hook", g_listener_load_hook, 1, 0, false, "listener *load-hook* function"), s7_hook_functions(s7, s7_name_to_value(s7, "*load-hook*")))); #endif } /* to get rid of * Fontconfig error: Cannot load default config file * and the consequent ridiculous fonts, since I think I built fontconfig from scratch, * copy (as root) /etc/fonts/fonts.conf to /usr/local/etc/fonts/fonts.conf * * to disable the goddamn beep put * gtk-error-bell = 0 * in /etc/gtk-2.0/gtkrc * * to build fontconfig, use --disable-docs (there's no way to make the docbook chain happy) * atk-bridge-2.0 needed, glib needs automake 1.13.1, at-spi2-atk needs at-spi2-code which * is incompatible with glib 2.37.0, my FC18 machine is dead, so I'm stuck. Wait for FC19... * * to implement stuff like find, the prompt might be in the status area? */ snd-16.1/snd-xen.c0000644000076400007640000024752412622711070012067 0ustar bilbil#if (defined(__GNUC__)) #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #include #endif #include "snd.h" #include "clm2xen.h" #define HAVE_SPECIAL_FUNCTIONS (!_MSC_VER) /* Snd defines its own exit and delay * * In Ruby, rand is kernel_rand. * * In Forth, Snd's exit is named snd-exit. */ /* error handlers */ static const char *io_error_names[IO_ERROR_NUM] = {"no error", "save-hook cancellation", "bad channel", "can't reopen file", "too many open files", "unknown sndlib error", "no memory", "can't open", "no filename", "bad sample type", "bad header type", "sndlib uninitialized", "not a sound file", "file closed", "write error", "interrupted", "can't close", "bad header", "disk full", "write protected", "can't read selection file", "need write confirmation", "no changes", "io edit-hook cancellation", "can't create file" }; const char *io_error_name(io_error_t err) { if (err < IO_ERROR_NUM) return(io_error_names[(int)err]); return(mus_format("unknown io_error: %d", err)); } /* this is needed as a C int below */ #ifndef USE_NO_GUI #define USE_NO_GUI 0 #endif static bool run_snd_error_hook(const char *msg) { return((Xen_hook_has_list(ss->snd_error_hook)) && (Xen_is_true(run_or_hook(ss->snd_error_hook, Xen_list_1(C_string_to_Xen_string(msg)), S_snd_error_hook)))); } void redirect_snd_warning_to(void (*handler)(const char *warning_msg, void *ufd), void *data) { ss->snd_warning_handler = handler; ss->snd_warning_data = data; } void redirect_snd_error_to(void (*handler)(const char *error_msg, void *ufd), void *data) { ss->snd_error_handler = handler; ss->snd_error_data = data; } static void snd_error_1(const char *msg, bool with_redirection_and_hook) { if (with_redirection_and_hook) { if (ss->snd_error_handler) { /* make sure it doesn't call itself recursively */ void (*old_snd_error_handler)(const char *error_msg, void *data); void *old_snd_error_data; old_snd_error_handler = ss->snd_error_handler; old_snd_error_data = ss->snd_error_data; ss->snd_error_handler = NULL; ss->snd_error_data = NULL; (*(old_snd_error_handler))(msg, old_snd_error_data); ss->snd_error_handler = old_snd_error_handler; ss->snd_error_data = old_snd_error_data; return; } if (run_snd_error_hook(msg)) return; } #if (USE_NO_GUI) fprintf(stderr, "%s", msg); #else if (ss) { if (ss->batch_mode) fprintf(stderr, "%s", msg); #if ((!HAVE_EXTENSION_LANGUAGE) && (!USE_NO_GUI)) { snd_info *sp; sp = any_selected_sound(); if ((sp) && (sp->active)) status_report(sp, "%s", msg); else post_it("Error", msg); } #endif } else { fprintf(stderr, "%s", msg); fputc('\n', stderr); } #endif /* end USE_NO_GUI */ } static void snd_warning_1(const char *msg) { if (ss->snd_warning_handler) { /* make sure it doesn't call itself recursively */ void (*old_snd_warning_handler)(const char *msg, void *data); void *old_snd_warning_data; old_snd_warning_handler = ss->snd_warning_handler; old_snd_warning_data = ss->snd_warning_data; ss->snd_warning_handler = NULL; ss->snd_warning_data = NULL; (*(old_snd_warning_handler))(msg, old_snd_warning_data); ss->snd_warning_handler = old_snd_warning_handler; ss->snd_warning_data = old_snd_warning_data; return; } if ((Xen_hook_has_list(ss->snd_warning_hook)) && (Xen_is_true(run_or_hook(ss->snd_warning_hook, Xen_list_1(C_string_to_Xen_string(msg)), S_snd_warning_hook)))) return; if ((ss) && (!(ss->batch_mode)) && (ss->max_sounds > 0)) { snd_info *sp; sp = any_selected_sound(); if ((sp) && (sp->active)) status_report(sp, "%s", msg); /* make the Mac C compiler happy */ else { listener_append(msg); fprintf(stderr, "%s", msg); } } else fprintf(stderr, "%s", msg); } static int snd_error_buffer_size = 1024; static char *snd_error_buffer = NULL; void snd_warning(const char *format, ...) { int bytes_needed = 0; va_list ap; if (snd_error_buffer == NULL) snd_error_buffer = (char *)calloc(snd_error_buffer_size, sizeof(char)); va_start(ap, format); /* can't use vasprintf here -- we may jump anywhere leaving unclaimed memory behind */ bytes_needed = vsnprintf(snd_error_buffer, snd_error_buffer_size, format, ap); va_end(ap); if (bytes_needed >= snd_error_buffer_size) { snd_error_buffer_size = bytes_needed * 2; free(snd_error_buffer); snd_error_buffer = (char *)calloc(snd_error_buffer_size, sizeof(char)); va_start(ap, format); vsnprintf(snd_error_buffer, snd_error_buffer_size, format, ap); va_end(ap); } snd_warning_1(snd_error_buffer); } void snd_warning_without_format(const char *msg) { snd_warning_1(msg); } void snd_error(const char *format, ...) { int bytes_needed = 0; va_list ap; if (snd_error_buffer == NULL) snd_error_buffer = (char *)calloc(snd_error_buffer_size, sizeof(char)); va_start(ap, format); bytes_needed = vsnprintf(snd_error_buffer, snd_error_buffer_size, format, ap); va_end(ap); if (bytes_needed > snd_error_buffer_size) { snd_error_buffer_size = bytes_needed * 2; free(snd_error_buffer); snd_error_buffer = (char *)calloc(snd_error_buffer_size, sizeof(char)); va_start(ap, format); vsnprintf(snd_error_buffer, snd_error_buffer_size, format, ap); va_end(ap); } snd_error_1(snd_error_buffer, true); } void snd_error_without_format(const char *msg) { snd_error_1(msg, true); } static Xen g_snd_error(Xen msg) { /* this throws a 'snd-error error; it does not call snd_error_1 or friends above */ #define H_snd_error "(" S_snd_error " str): throws a 'snd-error error" Xen_check_type(Xen_is_string(msg), msg, 1, S_snd_error, "a string"); if (!(run_snd_error_hook(Xen_string_to_C_string(msg)))) /* have to call this before the throw, else we end up at top level */ Xen_error(Xen_make_error_type("snd-error"), Xen_list_2(C_string_to_Xen_string(S_snd_error ": ~A"), msg)); return(msg); } static Xen g_snd_warning(Xen msg) { #define H_snd_warning "(" S_snd_warning " str): reports warning message str (normally in the status area)" Xen_check_type(Xen_is_string(msg), msg, 1, S_snd_warning, "a string"); snd_warning("%s", Xen_string_to_C_string(msg)); return(msg); } static Xen clip_hook; static mus_float_t run_clip_hook(mus_float_t val) { if (Xen_hook_has_list(clip_hook)) { Xen result; result = run_progn_hook(clip_hook, Xen_list_1(C_double_to_Xen_real(val)), S_clip_hook); if (Xen_is_number(result)) return(Xen_real_to_C_double(result)); } /* otherwise mimic the built-in default in io.c */ if (val >= 0.99999) return(0.99999); return(-1.0); } static bool clip_hook_checker(void) { bool result; result = Xen_hook_has_list(clip_hook); if (result) mus_clip_set_handler(run_clip_hook); else mus_clip_set_handler(NULL); return(result); } /* -------- protect Xen vars from GC -------- */ #if HAVE_SCHEME int snd_protect(Xen obj) {return(s7_gc_protect(s7, obj));} void snd_unprotect_at(int loc) {s7_gc_unprotect_at(s7, loc);} #else static Xen gc_protection; static int gc_protection_size = 0; #define DEFAULT_GC_VALUE Xen_undefined static int gc_last_cleared = NOT_A_GC_LOC; static int gc_last_set = NOT_A_GC_LOC; int snd_protect(Xen obj) { int i, old_size; Xen tmp; if (gc_protection_size == 0) { gc_protection_size = 512; gc_protection = Xen_make_vector(gc_protection_size, DEFAULT_GC_VALUE); Xen_GC_protect(gc_protection); Xen_vector_set(gc_protection, 0, obj); gc_last_set = 0; } else { if ((gc_last_cleared >= 0) && Xen_is_eq(Xen_vector_ref(gc_protection, gc_last_cleared), DEFAULT_GC_VALUE)) { /* we hit this branch about 2/3 of the time */ Xen_vector_set(gc_protection, gc_last_cleared, obj); gc_last_set = gc_last_cleared; gc_last_cleared = NOT_A_GC_LOC; return(gc_last_set); } for (i = gc_last_set; i < gc_protection_size; i++) if (Xen_is_eq(Xen_vector_ref(gc_protection, i), DEFAULT_GC_VALUE)) { Xen_vector_set(gc_protection, i, obj); gc_last_set = i; return(gc_last_set); } for (i = 0; i < gc_last_set; i++) if (Xen_is_eq(Xen_vector_ref(gc_protection, i), DEFAULT_GC_VALUE)) { /* here we average 3 checks before a hit, so this isn't as bad as it looks */ Xen_vector_set(gc_protection, i, obj); gc_last_set = i; return(gc_last_set); } tmp = gc_protection; old_size = gc_protection_size; gc_protection_size *= 2; gc_protection = Xen_make_vector(gc_protection_size, DEFAULT_GC_VALUE); Xen_GC_protect(gc_protection); for (i = 0; i < old_size; i++) { Xen_vector_set(gc_protection, i, Xen_vector_ref(tmp, i)); Xen_vector_set(tmp, i, DEFAULT_GC_VALUE); } Xen_vector_set(gc_protection, old_size, obj); /* in Ruby, I think we can unprotect it */ #if HAVE_RUBY || HAVE_FORTH Xen_GC_unprotect(tmp); #endif gc_last_set = old_size; } return(gc_last_set); } void snd_unprotect_at(int loc) { if (loc >= 0) { Xen_vector_set(gc_protection, loc, DEFAULT_GC_VALUE); gc_last_cleared = loc; } } #endif /* -------- error handling -------- */ static char *last_file_loaded = NULL; #if HAVE_SCHEME static Xen g_snd_s7_error_handler(Xen args) { s7_pointer msg; msg = s7_car(args); Xen_check_type(Xen_is_string(msg), msg, 1, "_snd_s7_error_handler_", "a string"); if (ss->xen_error_handler) (*(ss->xen_error_handler))(s7_string(msg), (void *)any_selected_sound()); /* not NULL! */ return(s7_f(s7)); } #endif void redirect_xen_error_to(void (*handler)(const char *msg, void *ufd), void *data) { ss->xen_error_handler = handler; ss->xen_error_data = data; #if HAVE_SCHEME if (handler == NULL) s7_eval_c_string(s7, "(set! (hook-functions *error-hook*) ())"); else s7_eval_c_string(s7, "(set! (hook-functions *error-hook*) (list \n\ (lambda (hook) \n\ (let ((args (hook 'data))) \n\ (_snd_s7_error_handler_ \n\ (string-append \n\ (if (string? args) \n\ args \n\ (if (pair? args) \n\ (apply format #f args) \n\ \"\")) \n\ (with-let (owlet) \n\ (if (and error-code \n\ (string? error-file) \n\ (number? error-line)) \n\ (format #f \"~%~S[~D]: ~A~%\" error-file error-line error-code) \n\ \"\"))))))))"); #endif } static void redirect_snd_print_to(void (*handler)(const char *msg, void *ufd), void *data) { ss->snd_print_handler = handler; ss->snd_print_data = data; } void redirect_everything_to(void (*handler)(const char *msg, void *ufd), void *data) { redirect_snd_error_to(handler, data); redirect_xen_error_to(handler, data); redirect_snd_warning_to(handler, data); redirect_snd_print_to(handler, data); } void redirect_errors_to(void (*handler)(const char *msg, void *ufd), void *data) { redirect_snd_error_to(handler, data); redirect_xen_error_to(handler, data); redirect_snd_warning_to(handler, data); } static char *gl_print(Xen result); /* ---------------- RUBY error handler ---------------- */ #if HAVE_RUBY static Xen snd_format_if_needed(Xen args) { /* if car has formatting info, use next arg as arg list for it */ Xen format_args = Xen_empty_list, cur_arg, result; int i, start = 0, num_args, format_info_len, err_size = 8192; bool got_tilde = false, was_formatted = false; char *format_info = NULL, *errmsg = NULL; num_args = Xen_list_length(args); if (num_args == 1) return(Xen_car(args)); format_info = mus_strdup(Xen_string_to_C_string(Xen_car(args))); format_info_len = mus_strlen(format_info); if (Xen_is_cons(Xen_cadr(args))) format_args = Xen_copy_arg(Xen_cadr(args)); /* protect Ruby case */ else format_args = Xen_cdr(args); errmsg = (char *)calloc(err_size, sizeof(char)); for (i = 0; i < format_info_len; i++) { if (format_info[i] == '~') { strncat(errmsg, (char *)(format_info + start), i - start); start = i + 2; got_tilde = true; } else { if (got_tilde) { was_formatted = true; got_tilde = false; switch (format_info[i]) { case '~': errmsg = mus_strcat(errmsg, "~", &err_size); break; case '%': errmsg = mus_strcat(errmsg, "\n", &err_size); break; case 'S': case 'A': if (!Xen_is_null(format_args)) { cur_arg = Xen_car(format_args); format_args = Xen_cdr(format_args); if (Xen_is_vector(cur_arg)) { char *vstr; vstr = gl_print(cur_arg); errmsg = mus_strcat(errmsg, vstr, &err_size); free(vstr); } else { char *temp = NULL; errmsg = mus_strcat(errmsg, temp = (char *)Xen_object_to_C_string(cur_arg), &err_size); } } /* else ignore it */ break; default: start = i - 1; break; } } } } if (i > start) strncat(errmsg, (char *)(format_info + start), i - start); if (format_info) free(format_info); if (!was_formatted) { char *temp = NULL; errmsg = mus_strcat(errmsg, " ", &err_size); errmsg = mus_strcat(errmsg, temp = (char *)Xen_object_to_C_string(Xen_cadr(args)), &err_size); if (num_args > 2) { if (!Xen_is_false(Xen_caddr(args))) start = 2; else start = 3; for (i = start; i < num_args; i++) { char *temp = NULL; errmsg = mus_strcat(errmsg, " ", &err_size); errmsg = mus_strcat(errmsg, temp = (char *)Xen_object_to_C_string(Xen_list_ref(args, i)), &err_size); } } } result = C_string_to_Xen_string(errmsg); free(errmsg); return(result); } void snd_rb_raise(Xen tag, Xen throw_args) { static char *msg = NULL; Xen err = rb_eStandardError, bt; int size = 2048; char *idname; if (msg) free(msg); msg = (char *)calloc(size, sizeof(char)); idname = (char *)rb_id2name(tag); if (strcmp(idname, "Out_of_range") == 0) err = rb_eRangeError; else if (strcmp(idname, "Wrong_type_arg") == 0) err = rb_eTypeError; msg = mus_strcat(msg, idname, &size); if (strcmp(idname, "Mus_error") == 0) msg = mus_strcat(msg, ": ", &size); else msg = mus_strcat(msg, " in ", &size); msg = mus_strcat(msg, Xen_string_to_C_string(snd_format_if_needed(throw_args)), &size); bt = rb_funcall(err, rb_intern("caller"), 0); if (Xen_vector_length(bt) > 0) { int i; msg = mus_strcat(msg, "\n", &size); for (i = 0; i < Xen_vector_length(bt); i++) { msg = mus_strcat(msg, Xen_string_to_C_string(Xen_vector_ref(bt, i)), &size); msg = mus_strcat(msg, "\n", &size); } } if (strcmp(idname, "Snd_error") != 0) { if (!(run_snd_error_hook(msg))) { if (ss->xen_error_handler) { /* make sure it doesn't call itself recursively */ void (*old_xen_error_handler)(const char *msg, void *data); void *old_xen_error_data; old_xen_error_handler = ss->xen_error_handler; old_xen_error_data = ss->xen_error_data; ss->xen_error_handler = NULL; ss->xen_error_data = NULL; (*(old_xen_error_handler))(msg, old_xen_error_data); ss->xen_error_handler = old_xen_error_handler; ss->xen_error_data = old_xen_error_data; } } } rb_raise(err, "%s", msg); } #endif /* end HAVE_RUBY */ #if HAVE_EXTENSION_LANGUAGE Xen snd_catch_any(Xen_catch_t body, void *body_data, const char *caller) { return((*body)(body_data)); } #else /* no extension language but user managed to try to evaluate something * can this happen? */ Xen snd_catch_any(Xen_catch_t body, void *body_data, const char *caller) { snd_error("This version of Snd has no extension language, so there's no way for %s to evaluate anything", caller); return(Xen_false); } #endif bool procedure_arity_ok(Xen proc, int args) { #if HAVE_SCHEME return(s7_is_aritable(s7, proc, args)); #else Xen arity; int rargs; arity = Xen_arity(proc); rargs = Xen_integer_to_C_int(arity); #if HAVE_RUBY return(xen_rb_arity_ok(rargs, args)); #endif #if HAVE_FORTH return(rargs == args); #endif #endif return(true); } char *procedure_ok(Xen proc, int args, const char *caller, const char *arg_name, int argn) { int rargs; /* if string returned, needs to be freed */ /* 0 args is special => "thunk" meaning in this case that optional args are not ok (applies to as-one-edit and two menu callbacks) */ if (!(Xen_is_procedure(proc))) { if (!Xen_is_false(proc)) /* #f as explicit arg to clear */ return(mus_format(" %s is not a procedure!", (arg_name) ? arg_name : caller)); } else { Xen arity; arity = Xen_arity(proc); #if HAVE_RUBY rargs = Xen_integer_to_C_int(arity); if (!xen_rb_arity_ok(rargs, args)) return(mus_format(" %s function should take %d args, not %d", (arg_name) ? arg_name : caller, args, (rargs < 0) ? (-rargs) : rargs)); #endif #if HAVE_SCHEME { int oargs, loc; loc = snd_protect(arity); rargs = Xen_integer_to_C_int(Xen_car(arity)); oargs = Xen_integer_to_C_int(Xen_cdr(arity)); snd_unprotect_at(loc); if (rargs > args) return(mus_format(" %s function should take %d argument%s, but instead requires %d", (arg_name) ? arg_name : caller, args, (args != 1) ? "s" : "", rargs)); if ((rargs + oargs) < args) return(mus_format(" %s function should accept at least %d argument%s, but instead accepts only %d", (arg_name) ? arg_name : caller, args, (args != 1) ? "s" : "", rargs + oargs)); } #endif #if HAVE_FORTH rargs = Xen_integer_to_C_int(arity); if (rargs != args) return(mus_format(" %s function should take %d args, not %d", (arg_name) ? arg_name : caller, args, rargs)); #endif } return(NULL); } Xen snd_no_such_file_error(const char *caller, Xen filename) { Xen_error(NO_SUCH_FILE, Xen_list_4(C_string_to_Xen_string("no-such-file: ~A ~S: ~A"), C_string_to_Xen_string(caller), filename, C_string_to_Xen_string(snd_open_strerror()))); return(Xen_false); } Xen snd_no_such_channel_error(const char *caller, Xen snd, Xen chn) { int index = NOT_A_SOUND; if (Xen_is_integer(snd)) index = Xen_integer_to_C_int(snd); else { if (xen_is_sound(snd)) index = Xen_sound_to_C_int(snd); } if ((index >= 0) && (index < ss->max_sounds) && (snd_ok(ss->sounds[index]))) /* good grief... */ { snd_info *sp; sp = ss->sounds[index]; Xen_error(NO_SUCH_CHANNEL, Xen_list_6(C_string_to_Xen_string("no-such-channel: (~A: sound: ~A, chan: ~A) (~S, chans: ~A))"), C_string_to_Xen_string(caller), snd, chn, C_string_to_Xen_string(sp->short_filename), C_int_to_Xen_integer(sp->nchans))); } Xen_error(NO_SUCH_CHANNEL, Xen_list_4(C_string_to_Xen_string("no-such-channel: (~A: sound: ~A, chan: ~A)"), C_string_to_Xen_string(caller), snd, chn)); return(Xen_false); } Xen snd_no_active_selection_error(const char *caller) { Xen_error(Xen_make_error_type("no-active-selection"), Xen_list_2(C_string_to_Xen_string("~A: no active selection"), C_string_to_Xen_string(caller))); return(Xen_false); } Xen snd_bad_arity_error(const char *caller, Xen errstr, Xen proc) { Xen_error(Xen_make_error_type("bad-arity"), Xen_list_3(C_string_to_Xen_string("~A,~A"), C_string_to_Xen_string(caller), errstr)); return(Xen_false); } /* -------- various evaluators (within our error handler) -------- */ Xen eval_str_wrapper(void *data) { return(Xen_eval_C_string((char *)data)); } static Xen eval_file_wrapper(void *data) { Xen error; last_file_loaded = (char *)data; error = Xen_load((char *)data); /* error only meaningful in Ruby */ last_file_loaded = NULL; return(error); } static char *g_print_1(Xen obj) /* free return val */ { #if HAVE_SCHEME return(Xen_object_to_C_string(obj)); #endif #if HAVE_FORTH || HAVE_RUBY return(mus_strdup(Xen_object_to_C_string(obj))); #endif #if (!HAVE_EXTENSION_LANGUAGE) return(NULL); #endif } static char *gl_print(Xen result) { char *newbuf = NULL, *str = NULL; int i, ilen, savelen; #if HAVE_SCHEME /* expand \t first (neither gtk nor motif handles this automatically) * but... "#\\t" is the character t not a tab indication! * (object->string #\t) or worse #\tab */ #define TAB_SPACES 4 int tabs = 0, len, j = 0; newbuf = g_print_1(result); len = mus_strlen(newbuf); for (i = 0; i < len - 1; i++) if (((i == 0) || ((newbuf[i - 1] != '\\') && (newbuf[i - 1] != '#'))) && (newbuf[i] == '\\') && (newbuf[i + 1] == 't')) tabs++; if (tabs == 0) return(newbuf); ilen = len + tabs * TAB_SPACES; str = (char *)calloc(ilen, sizeof(char)); for (i = 0; i < len - 1; i++) { if (((i == 0) || (newbuf[i - 1] != '\\')) && (newbuf[i] == '\\') && (newbuf[i + 1] == 't')) { int k; for (k = 0; k < TAB_SPACES; k++) str[j + k] = ' '; j += TAB_SPACES; i++; } else str[j++] = newbuf[i]; } str[j] = newbuf[len - 1]; free(newbuf); return(str); #endif /* specialize vectors which can be enormous in this context */ if ((!(Xen_is_vector(result))) || ((int)(Xen_vector_length(result)) <= print_length(ss))) return(g_print_1(result)); ilen = print_length(ss); newbuf = (char *)calloc(128, sizeof(char)); savelen = 128; #if HAVE_FORTH snprintf(newbuf, 128, "#("); #endif #if HAVE_RUBY snprintf(newbuf, 128, "["); #endif for (i = 0; i < ilen; i++) { str = g_print_1(Xen_vector_ref(result, i)); if ((str) && (*str)) { if (i != 0) { #if HAVE_RUBY newbuf = mus_strcat(newbuf, ",", &savelen); #endif newbuf = mus_strcat(newbuf, " ", &savelen); } newbuf = mus_strcat(newbuf, str, &savelen); free(str); } } #if HAVE_FORTH newbuf = mus_strcat(newbuf, " ...)", &savelen); #endif #if HAVE_RUBY newbuf = mus_strcat(newbuf, " ...]", &savelen); #endif return(newbuf); } void snd_display_result(const char *str, const char *endstr) { if (ss->snd_print_handler) { /* make sure it doesn't call itself recursively */ void (*old_snd_print_handler)(const char *msg, void *data); void *old_snd_print_data; old_snd_print_handler = ss->snd_print_handler; old_snd_print_data = ss->snd_print_data; ss->snd_print_handler = NULL; ss->snd_print_data = NULL; (*(old_snd_print_handler))(str, old_snd_print_data); ss->snd_print_handler = old_snd_print_handler; ss->snd_print_data = old_snd_print_data; } else { if (endstr) listener_append(endstr); listener_append_and_prompt(str); } } void snd_report_result(Xen result, const char *buf) { char *str = NULL; str = gl_print(result); snd_display_result(str, buf); if (str) free(str); } void snd_report_listener_result(Xen form) { snd_report_result(form, "\n"); } static char *stdin_str = NULL; void clear_stdin(void) { if (stdin_str) free(stdin_str); stdin_str = NULL; } #if HAVE_SCHEME static int check_balance(const char *expr, int start, int end) { int i; bool not_whitespace = false; int paren_count = 0; bool prev_separator = true; bool quote_wait = false; i = start; while (i < end) { switch (expr[i]) { case ';' : /* skip till newline. */ do { i++; } while ((i < end) && (expr[i] != '\n')); break; case ' ': case '\n': case '\t': case '\r': if ((not_whitespace) && (paren_count == 0) && (!quote_wait)) return(i); else { prev_separator = true; i++; } break; case '\"' : if ((not_whitespace) && (paren_count == 0) && (!quote_wait)) return(i); else { /* skip past ", ignoring \", some cases: * "\"\"" '("\"\"") "\\" "#\\(" "'(\"#\\\")" */ while (i < end) { i++; if (expr[i] == '\\') i++; else { if (expr[i] == '\"') break; } } i++; if (paren_count == 0) { if (i < end) return(i); else return(0); } else { prev_separator = true; not_whitespace = true; quote_wait = false; } } break; case '#': if ((i < end - 1) && (expr[i + 1] == '|')) { /* (+ #| a comment |# 2 1) */ i++; do { i++; } while (((expr[i] != '|') || (expr[i + 1] != '#')) && (i < end)); i++; break; } else { /* (set! *#readers* (cons (cons #\c (lambda (str) (apply make-rectangular (read)))) *#readers*)) */ if ((not_whitespace) && (paren_count == 0) && (!quote_wait)) return(i); else { bool found_it = false; if (prev_separator) { int k, incr = 0; for (k = i + 1; k < end; k++) { if (expr[k] == '(') { /* should we look at the readers here? I want to support #c(1 2) for example */ not_whitespace = false; prev_separator = false; incr = k - i; break; } else { if ((!isdigit((int)expr[k])) && /* #2d(...)? */ (!isalpha((int)expr[k])) && /* #c(1 2)? */ (expr[k] != 'D') && (expr[k] != 'd') && (expr[k] != '=') && /* what is this for? */ (expr[k] != '#')) /* perhaps #1d(#(1 2) 3) ? */ break; } } if (incr > 0) { i += incr; found_it = true; } } if (!found_it) { if ((i + 2 < end) && (expr[i + 1] == '\\') && ((expr[i + 2] == ')') || (expr[i + 2] == ';') || (expr[i + 2] == '\"') || (expr[i + 2] == '('))) i += 3; else { prev_separator = false; quote_wait = false; not_whitespace = true; i++; } } } } break; case '(' : if ((not_whitespace) && (paren_count == 0) && (!quote_wait)) return(i - 1); /* 'a(...) -- ignore the (...) */ else { i++; paren_count++; not_whitespace = true; prev_separator = true; quote_wait = false; } break; case ')' : paren_count--; if ((not_whitespace) && (paren_count == 0)) return(i + 1); else { i++; not_whitespace = true; prev_separator = true; quote_wait = false; } break; case '\'' : case '`' : /* `(1 2) */ if (prev_separator) quote_wait = true; not_whitespace = true; i++; break; case ',': /* `,(+ 1 2) */ case '@': /* `,@(list 1 2) */ prev_separator = false; not_whitespace = true; i++; break; default: prev_separator = false; quote_wait = false; not_whitespace = true; i++; break; } } return(0); } #endif char *stdin_check_for_full_expression(const char *newstr) { #if HAVE_SCHEME int end_of_text; #endif if (stdin_str) { char *str; str = stdin_str; stdin_str = (char *)calloc(mus_strlen(str) + mus_strlen(newstr) + 2, sizeof(char)); strcat(stdin_str, str); strcat(stdin_str, newstr); free(str); } else stdin_str = mus_strdup(newstr); #if HAVE_SCHEME end_of_text = check_balance(stdin_str, 0, mus_strlen(stdin_str)); if (end_of_text > 0) { if (end_of_text + 1 < mus_strlen(stdin_str)) stdin_str[end_of_text + 1] = 0; return(stdin_str); } return(NULL); #endif return(stdin_str); } void stdin_free_str(void) { if (stdin_str) free(stdin_str); stdin_str = NULL; } static void string_to_stdout(const char *msg, void *ignored) { fprintf(stdout, "%s\n", msg); } void snd_eval_stdin_str(const char *buf) { /* we may get incomplete expressions here */ /* (Ilisp always sends a complete expression, but it may be broken into two or more pieces from read's point of view) */ char *str = NULL; if (mus_strlen(buf) == 0) return; str = stdin_check_for_full_expression(buf); if (str) { Xen result; int loc; redirect_everything_to(string_to_stdout, NULL); result = snd_catch_any(eval_str_wrapper, (void *)str, str); redirect_everything_to(NULL, NULL); loc = snd_protect(result); stdin_free_str(); str = gl_print(result); string_to_stdout(str, NULL); if (str) free(str); snd_unprotect_at(loc); } } static void string_to_stderr_and_listener(const char *msg, void *ignore) { fprintf(stderr, "%s\n", msg); if (listener_exists()) /* the idea here is to save startup errors until we can post them */ { listener_append((char *)msg); listener_append("\n"); } else { if (ss->startup_errors) { char *temp; temp = ss->startup_errors; ss->startup_errors = mus_format("%s\n%s %s\n", ss->startup_errors, listener_prompt(ss), msg); free(temp); } else ss->startup_errors = mus_strdup(msg); /* initial prompt is already there */ } } static bool snd_load_init_file_1(const char *filename) { char *fullname; bool happy = false; fullname = mus_expand_filename(filename); if (mus_file_probe(fullname)) { char *expr; happy = true; #if HAVE_SCHEME expr = mus_format("(load %s)", fullname); #endif #if HAVE_RUBY || HAVE_FORTH expr = mus_format("load(%s)", fullname); #endif snd_catch_any(eval_file_wrapper, (void *)fullname, expr); free(expr); } if (fullname) free(fullname); return(happy); } void snd_load_init_file(bool no_global, bool no_init) { /* look for ".snd" on the home directory; return true if an error occurred (to try to get that info to the user's attention) */ /* called only in snd-g|xmain.c at initialization time */ /* changed Oct-05 because the Scheme/Ruby/Forth choices are becoming a hassle -- * now save-options has its own file ~/.snd_prefs_ruby|forth|s7 which is loaded first, if present * then ~/.snd_ruby|forth|s7, if present * then ~/.snd for backwards compatibility * snd_options does not write ~/.snd anymore, but overwrites the .snd_prefs_* file * use set init files only change the ~/.snd choice * * there are parallel choices for the global configuration file: /etc/snd_ruby|forth|s7.conf */ #if HAVE_EXTENSION_LANGUAGE #if HAVE_RUBY #define SND_EXT_CONF "/etc/snd_ruby.conf" #define SND_PREFS "~/.snd_prefs_ruby" #define SND_INIT "~/.snd_ruby" #endif #if HAVE_FORTH #define SND_EXT_CONF "/etc/snd_forth.conf" #define SND_PREFS "~/.snd_prefs_forth" #define SND_INIT "~/.snd_forth" #endif #if HAVE_SCHEME #define SND_EXT_CONF "/etc/snd_s7.conf" #define SND_PREFS "~/.snd_prefs_s7" #define SND_INIT "~/.snd_s7" #endif #define SND_INIT_FILE_ENVIRONMENT_NAME "SND_INIT_FILE" #if (defined(_MSC_VER) || __CYGWIN__) #define INIT_FILE_NAME "snd-init" #else #define INIT_FILE_NAME "~/.snd" #endif #define SND_CONF "/etc/snd.conf" redirect_snd_print_to(string_to_stdout, NULL); redirect_errors_to(string_to_stderr_and_listener, NULL); /* check for global configuration files (/etc/snd*) */ if (!no_global) { snd_load_init_file_1(SND_EXT_CONF); snd_load_init_file_1(SND_CONF); } /* now load local init file(s) */ if (!no_init) { char *temp; snd_load_init_file_1(SND_PREFS); /* check for possible prefs dialog output */ snd_load_init_file_1(SND_INIT); temp = getenv(SND_INIT_FILE_ENVIRONMENT_NAME); if (temp) snd_load_init_file_1(temp); else snd_load_init_file_1(INIT_FILE_NAME); } redirect_everything_to(NULL, NULL); #endif } static char *find_source_file(const char *orig); void snd_load_file(const char *filename) { char *str = NULL, *str2 = NULL; str = mus_expand_filename(filename); if (!(mus_file_probe(str))) { char *temp; temp = find_source_file(str); free(str); str = temp; } if (!str) { snd_error("can't load %s: %s", filename, snd_open_strerror()); return; } str2 = mus_format("(load \"%s\")", filename); /* currently unused in Forth and Ruby */ snd_catch_any(eval_file_wrapper, (void *)str, str2); if (str) free(str); if (str2) free(str2); } static Xen g_snd_print(Xen msg) { #define H_snd_print "(" S_snd_print " str): display str in the listener window" char *str = NULL; if (Xen_is_string(msg)) str = mus_strdup(Xen_string_to_C_string(msg)); else { if (Xen_is_char(msg)) { str = (char *)calloc(2, sizeof(char)); str[0] = Xen_char_to_C_char(msg); } else str = gl_print(msg); } if (str) { #if USE_GTK if (ss->listener) #endif listener_append(str); free(str); } /* used to check for event in Motif case, but that is very dangerous -- check for infinite loop C-c needs to be somewhere else */ return(msg); } void check_features_list(const char *features) { /* check for list of features, report any missing, exit (for compsnd) */ /* this can't be in snd.c because we haven't fully initialized the extension language and so on at that point */ if (!features) return; #if HAVE_SCHEME Xen_eval_C_string(mus_format("(for-each \ (lambda (f) \ (if (not (provided? f)) \ (display (format #f \"~%%no ~A!~%%~%%\" f)))) \ (list %s))", features)); #endif #if HAVE_RUBY /* provided? is defined in examp.rb */ Xen_eval_C_string(mus_format("[%s].each do |f|\n\ unless $LOADED_FEATURES.map do |ff| File.basename(ff) end.member?(f.to_s.tr(\"_\", \"-\"))\n\ $stderr.printf(\"~\\nno %%s!\\n\\n\", f.id2name)\n\ end\n\ end\n", features)); #endif #if HAVE_FORTH Xen_eval_C_string(mus_format("'( %s ) [each] dup \ provided? [if] \ drop \ [else] \ 1 >list \"\\nno %%s!\\n\\n\" swap format .stderr \ [then] \ [end-each]\n", features)); #endif snd_exit(0); } mus_float_t string_to_mus_float_t(const char *str, mus_float_t lo, const char *field_name) { #if HAVE_EXTENSION_LANGUAGE Xen res; res = snd_catch_any(eval_str_wrapper, (void *)str, "string->float"); if (Xen_is_number(res)) { mus_float_t f; f = Xen_real_to_C_double(res); if (f < lo) snd_error("%s: %.3f is invalid", field_name, f); else return(f); } else snd_error("%s is not a number", str); return(0.0); #else float res = 0.0; if (str) { if (!(sscanf(str, "%f", &res))) snd_error("%s is not a number", str); else { if (res < lo) snd_error("%s: %.3f is invalid", field_name, res); } } return((mus_float_t)res); #endif } int string_to_int(const char *str, int lo, const char *field_name) { #if HAVE_EXTENSION_LANGUAGE Xen res; res = snd_catch_any(eval_str_wrapper, (void *)str, "string->int"); if (Xen_is_number(res)) { int val; val = Xen_integer_to_C_int(res); if (val < lo) snd_error("%s: %d is invalid", field_name, val); else return(val); } else snd_error("%s: %s is not a number", field_name, str); return(0); #else int res = 0; if (str) { if (!(sscanf(str, "%12d", &res))) snd_error("%s: %s is not a number", field_name, str); else { if (res < lo) snd_error("%s: %d is invalid", field_name, res); } } return(res); #endif } mus_long_t string_to_mus_long_t(const char *str, mus_long_t lo, const char *field_name) { #if HAVE_EXTENSION_LANGUAGE Xen res; res = snd_catch_any(eval_str_wrapper, (void *)str, "string->mus_long_t"); if (Xen_is_number(res)) { mus_long_t val; val = Xen_llong_to_C_llong(res); if (val < lo) snd_error("%s: %lld is invalid", field_name, val); else return(val); } else snd_error("%s: %s is not a number", field_name, str); return(0); #else mus_long_t res = 0; if (str) { if (!(sscanf(str, "%lld" , &res))) snd_error("%s: %s is not a number", field_name, str); else { if (res < lo) snd_error("%s: %lld is invalid", field_name, res); } } return(res); #endif } Xen run_progn_hook(Xen hook, Xen args, const char *caller) { #if HAVE_SCHEME return(s7_call(s7, hook, args)); #else Xen result = Xen_false; Xen procs = Xen_hook_list(hook); while (!Xen_is_null(procs)) { result = Xen_apply(Xen_car(procs), args, caller); procs = Xen_cdr(procs); } return(result); #endif } Xen run_hook(Xen hook, Xen args, const char *caller) { #if HAVE_SCHEME return(s7_call(s7, hook, args)); #else Xen procs = Xen_hook_list(hook); while (!Xen_is_null(procs)) { if (!(Xen_is_eq(args, Xen_empty_list))) Xen_apply(Xen_car(procs), args, caller); else Xen_call_with_no_args(Xen_car(procs), caller); procs = Xen_cdr(procs); } return(Xen_false); #endif } Xen run_or_hook(Xen hook, Xen args, const char *caller) { #if HAVE_SCHEME return(s7_call(s7, hook, args)); #else Xen result = Xen_false; /* (or): #f */ Xen hook_result = Xen_false; Xen procs = Xen_hook_list(hook); while (!Xen_is_null(procs)) { if (!(Xen_is_eq(args, Xen_empty_list))) result = Xen_apply(Xen_car(procs), args, caller); else result = Xen_call_with_no_args(Xen_car(procs), caller); if (!Xen_is_false(result)) hook_result = result; procs = Xen_cdr(procs); } return(hook_result); #endif } #if HAVE_SCHEME && (!_MSC_VER) #include /* these are included because libtool's dlopen is incredibly stupid */ /* apparently netBSD does not have dlerror? #ifdef __NetBSD__ #define dlerror() g_strerror(errno) #endif to get symbols from current program: handle = dlopen(NULL, RTLD_GLOBAL | RTLD_LAZY); */ static Xen g_dlopen(Xen name, Xen flags) { #define H_dlopen "(dlopen lib (flags RTLD_LAZY)) loads the dynamic library 'lib' and returns a handle for it (for dlinit and dlclose)" void *handle; const char *cname; Xen_check_type(Xen_is_string(name), name, 1, "dlopen", "a string (filename)"); cname = Xen_string_to_C_string(name); if (cname) { handle = dlopen(cname, RTLD_LAZY); if (handle == NULL) { char *longname; longname = mus_expand_filename(cname); if (Xen_is_integer(flags)) handle = dlopen(longname, Xen_integer_to_C_int(flags)); else handle = dlopen(longname, RTLD_LAZY); free(longname); if (handle == NULL) { char *err; err = (char *)dlerror(); if ((err) && (*err)) return(C_string_to_Xen_string(err)); return(Xen_false); } } return(Xen_wrap_C_pointer(handle)); } return(Xen_false); } static Xen g_dlclose(Xen handle) { #define H_dlclose "(dlclose handle) may close the library referred to by 'handle'." Xen_check_type(Xen_is_wrapped_c_pointer(handle), handle, 1, "dlclose", "a library handle"); return(C_int_to_Xen_integer(dlclose((void *)(Xen_unwrap_C_pointer(handle))))); } static Xen g_dlerror(void) { #define H_dlerror "(dlerror) returns a string describing the last dlopen/dlinit/dlclose error" return(C_string_to_Xen_string(dlerror())); } static Xen g_dlsym(Xen handle, Xen func) { #define H_dlsym "(dlsym library function-name) returns a pointer to function in library, or #f." void *proc; Xen_check_type(Xen_is_wrapped_c_pointer(handle), handle, 1, "dlsym", "a library handle"); Xen_check_type(Xen_is_string(func), func, 2, "dlsym", "a string (function name)"); proc = dlsym((void *)(Xen_unwrap_C_pointer(handle)), Xen_string_to_C_string(func)); if (proc == NULL) return(Xen_false); return(Xen_wrap_C_pointer(func)); } static Xen g_dlinit(Xen handle, Xen func) { #define H_dlinit "(dlinit handle func) calls 'func' from the library referred to by 'handle'." typedef void *(*snd_dl_func)(void); void *proc; Xen_check_type(Xen_is_wrapped_c_pointer(handle), handle, 1, "dlinit", "a library handle"); Xen_check_type(Xen_is_string(func), func, 2, "dlinit", "a string (init func name)"); proc = dlsym((void *)(Xen_unwrap_C_pointer(handle)), Xen_string_to_C_string(func)); if (proc == NULL) return(C_string_to_Xen_string(dlerror())); ((snd_dl_func)proc)(); return(Xen_true); } #endif #if HAVE_SCHEME static s7_pointer g_line_reader(s7_scheme *sc, s7_pointer args) { const char *str; Xen_check_type(Xen_is_string(s7_car(args)), s7_car(args), 1, "#__line__", "a string"); str = s7_string(s7_car(args)); if ((str) && (strcmp(str, "__line__") == 0)) return(s7_make_integer(sc, s7_port_line_number(s7_current_input_port(sc)))); return(Xen_false); } #endif static Xen g_little_endian(void) { #if MUS_LITTLE_ENDIAN return(Xen_true); #else return(Xen_false); #endif } static Xen g_snd_global_state(void) { return(Xen_wrap_C_pointer(ss)); } #if (!HAVE_SCHEME) /* fmod is the same as modulo in s7: (do ((i 0 (+ i 1))) ((= i 100)) (let ((val1 (- (random 1.0) 2.0)) (val2 (- (random 1.0) 2.0))) (let ((f (fmod val1 val2)) (m (modulo val1 val2))) (if (> (abs (- f m)) 1e-9) (format *stderr* "~A ~A -> ~A ~A~%" val1 val2 f m))))) */ static Xen g_fmod(Xen a, Xen b) { double val, x, y; Xen_check_type(Xen_is_number(a), a, 1, "fmod", " a number"); Xen_check_type(Xen_is_number(b), b, 2, "fmod", " a number"); x = Xen_real_to_C_double(a); y = Xen_real_to_C_double(b); val = fmod(x, y); if (((y > 0.0) && (val < 0.0)) || ((y < 0.0) && (val > 0.0))) return(C_double_to_Xen_real(val + y)); return(C_double_to_Xen_real(val)); } #endif #if HAVE_SPECIAL_FUNCTIONS || HAVE_GSL #define S_bes_j0 "bes-j0" #define S_bes_j1 "bes-j1" #define S_bes_jn "bes-jn" #define S_bes_y0 "bes-y0" #define S_bes_y1 "bes-y1" #define S_bes_yn "bes-yn" #endif #if HAVE_SCHEME && WITH_GMP && HAVE_SPECIAL_FUNCTIONS #include #include #include static Xen big_math_1(Xen x, int (*mpfr_math)(mpfr_ptr, mpfr_srcptr, mpfr_rnd_t)) { s7_pointer val; mpfr_t y; mpfr_init_set(y, *s7_big_real(x), GMP_RNDN); mpfr_math(y, y, GMP_RNDN); val = s7_make_big_real(s7, &y); mpfr_clear(y); return(val); } static Xen big_j0(Xen x) {return(big_math_1(x, mpfr_j0));} static Xen big_j1(Xen x) {return(big_math_1(x, mpfr_j1));} static Xen big_y0(Xen x) {return(big_math_1(x, mpfr_y0));} static Xen big_y1(Xen x) {return(big_math_1(x, mpfr_y1));} static Xen big_erf(Xen x) {return(big_math_1(x, mpfr_erf));} static Xen big_erfc(Xen x) {return(big_math_1(x, mpfr_erfc));} static Xen big_math_2(Xen n, Xen x, int (*mpfr_math)(mpfr_ptr, long, mpfr_srcptr, mpfr_rnd_t)) { s7_pointer val; mpfr_t y; mpfr_init_set(y, *s7_big_real(x), GMP_RNDN); mpfr_math(y, Xen_integer_to_C_int(n), y, GMP_RNDN); val = s7_make_big_real(s7, &y); mpfr_clear(y); return(val); } static Xen big_jn(Xen n, Xen x) {return(big_math_2(n, x, mpfr_jn));} static Xen big_yn(Xen n, Xen x) {return(big_math_2(n, x, mpfr_yn));} /* bes-i0 from G&R 8.447, 8.451, A&S 9.6.12, 9.7.1, arprec bessel.cpp */ static Xen big_i0(Xen ux) { int k; mpfr_t sum, x, x1, x2, eps; mpfr_init_set_ui(sum, 0, GMP_RNDN); mpfr_init_set(x, *s7_big_real(ux), GMP_RNDN); mpfr_init_set_ui(sum, 1, GMP_RNDN); mpfr_init_set_ui(x1, 1, GMP_RNDN); mpfr_init_set_ui(eps, 2, GMP_RNDN); mpfr_pow_si(eps, eps, -mpfr_get_default_prec(), GMP_RNDN); mpfr_init_set_ui(x2, mpfr_get_default_prec(), GMP_RNDN); mpfr_div_ui(x2, x2, 2, GMP_RNDN); if (mpfr_cmpabs(x, x2) < 0) { mpfr_mul(x, x, x, GMP_RNDN); /* x = ux^2 */ for (k = 1; k < 10000; k++) { mpfr_set_ui(x2, k, GMP_RNDN); /* x2 = k */ mpfr_mul(x2, x2, x2, GMP_RNDN); /* x2 = k^2 */ mpfr_div(x1, x1, x2, GMP_RNDN); /* x1 = x1/x2 */ mpfr_mul(x1, x1, x, GMP_RNDN); /* x1 = x1*x */ mpfr_div_ui(x1, x1, 4, GMP_RNDN); /* x1 = x1/4 */ if (mpfr_cmp(x1, eps) < 0) break; mpfr_add(sum, sum, x1, GMP_RNDN); /* sum += x1 */ } /* takes usually ca 10 to 40 iterations */ } else { mpfr_t den, num; mpfr_init(den); mpfr_init(num); mpfr_abs(x, x, GMP_RNDN); for (k = 1; k < 10000; k++) { mpfr_set(x2, x1, GMP_RNDN); mpfr_set_ui(den, k, GMP_RNDN); mpfr_mul_ui(den, den, 8, GMP_RNDN); mpfr_mul(den, den, x, GMP_RNDN); mpfr_set_ui(num, k, GMP_RNDN); mpfr_mul_ui(num, num, 2, GMP_RNDN); mpfr_sub_ui(num, num, 1, GMP_RNDN); mpfr_mul(num, num, num, GMP_RNDN); mpfr_div(num, num, den, GMP_RNDN); mpfr_mul(x1, x1, num, GMP_RNDN); mpfr_add(sum, sum, x1, GMP_RNDN); if (mpfr_cmp(x1, eps) < 0) { mpfr_const_pi(x2, GMP_RNDN); mpfr_mul_ui(x2, x2, 2, GMP_RNDN); mpfr_mul(x2, x2, x, GMP_RNDN); mpfr_sqrt(x2, x2, GMP_RNDN); /* sqrt(2*pi*x) */ mpfr_div(sum, sum, x2, GMP_RNDN); mpfr_exp(x1, x, GMP_RNDN); mpfr_mul(sum, sum, x1, GMP_RNDN); /* sum * e^x / sqrt(2*pi*x) */ break; } if (mpfr_cmp(x1, x2) > 0) { fprintf(stderr, "bes-i0 has screwed up"); break; } } mpfr_clear(den); mpfr_clear(num); } mpfr_clear(x1); mpfr_clear(x2); mpfr_clear(x); mpfr_clear(eps); return(s7_make_big_real(s7, &sum)); } /* fft * (define hi (make-vector 8)) * (define ho (make-vector 8)) * (do ((i 0 (+ i 1))) ((= i 8)) (vector-set! hi i (bignum "0.0")) (vector-set! ho i (bignum "0.0"))) * (vector-set! ho 1 (bignum "-1.0")) * (vector-set! ho 1 (bignum "-1.0")) * (bignum-fft hi ho 8) * * this is tricky -- perhaps a bad idea. vector elements are changed in place which means * they better be unique! and there are no checks that each element actually is a bignum * which means we'll segfault if a normal real leaks through. * * bignum_fft is say 200 times slower than the same size fftw call, and takes more space than * I can account for: 2^20 29 secs ~.5 Gb, 2^24 11 mins ~5Gb. I think there should be * the vector element (8), the mpfr_t space (16 or 32), the s7_cell (28 or 32), and the value pointer (8), * and the heap pointer loc (8) so 2^24 should be (* 2 (expt 2 24) (+ 8 8 8 8 32 32)) = 3 Gb, not 5. 2^25 25 min 10.6? * I think the extra is in the free space in the heap -- it can be adding 1/4 of the total. */ static s7_pointer bignum_fft(s7_scheme *sc, s7_pointer args) { #define H_bignum_fft "(bignum-fft rl im n (sign 1)) performs a multiprecision fft on the vectors of bigfloats rl and im" int n, sign = 1; s7_pointer *rl, *im; int m, j, mh, ldm, lg, i, i2, j2, imh; mpfr_t ur, ui, u, vr, vi, angle, c, s, temp; #define big_rl(n) (*(s7_big_real(rl[n]))) #define big_im(n) (*(s7_big_real(im[n]))) n = s7_integer(s7_list_ref(sc, args, 2)); if (s7_list_length(sc, args) > 3) sign = s7_integer(s7_list_ref(sc, args, 3)); rl = s7_vector_elements(s7_list_ref(sc, args, 0)); im = s7_vector_elements(s7_list_ref(sc, args, 1)); /* scramble(rl, im, n); */ { int i, m, j; s7_pointer vr, vi; j = 0; for (i = 0; i < n; i++) { if (j > i) { vr = rl[j]; vi = im[j]; rl[j] = rl[i]; im[j] = im[i]; rl[i] = vr; im[i] = vi; } m = n >> 1; while ((m >= 2) && (j >= m)) { j -= m; m = m >> 1; } j += m; } } imh = (int)(log(n + 1) / log(2.0)); m = 2; ldm = 1; mh = n >> 1; mpfr_init(angle); /* angle = (M_PI * sign) */ mpfr_const_pi(angle, GMP_RNDN); if (sign == -1) mpfr_neg(angle, angle, GMP_RNDN); mpfr_init(c); mpfr_init(s); mpfr_init(ur); mpfr_init(ui); mpfr_init(u); mpfr_init(vr); mpfr_init(vi); mpfr_init(temp); for (lg = 0; lg < imh; lg++) { mpfr_cos(c, angle, GMP_RNDN); /* c = cos(angle) */ mpfr_sin(s, angle, GMP_RNDN); /* s = sin(angle) */ mpfr_set_ui(ur, 1, GMP_RNDN); /* ur = 1.0 */ mpfr_set_ui(ui, 0, GMP_RNDN); /* ui = 0.0 */ for (i2 = 0; i2 < ldm; i2++) { i = i2; j = i2 + ldm; for (j2 = 0; j2 < mh; j2++) { mpfr_set(temp, big_im(j), GMP_RNDN); /* vr = ur * rl[j] - ui * im[j] */ mpfr_mul(temp, temp, ui, GMP_RNDN); mpfr_set(vr, big_rl(j), GMP_RNDN); mpfr_mul(vr, vr, ur, GMP_RNDN); mpfr_sub(vr, vr, temp, GMP_RNDN); mpfr_set(temp, big_rl(j), GMP_RNDN); /* vi = ur * im[j] + ui * rl[j] */ mpfr_mul(temp, temp, ui, GMP_RNDN); mpfr_set(vi, big_im(j), GMP_RNDN); mpfr_mul(vi, vi, ur, GMP_RNDN); mpfr_add(vi, vi, temp, GMP_RNDN); mpfr_set(big_rl(j), big_rl(i), GMP_RNDN); /* rl[j] = rl[i] - vr */ mpfr_sub(big_rl(j), big_rl(j), vr, GMP_RNDN); mpfr_set(big_im(j), big_im(i), GMP_RNDN); /* im[j] = im[i] - vi */ mpfr_sub(big_im(j), big_im(j), vi, GMP_RNDN); mpfr_add(big_rl(i), big_rl(i), vr, GMP_RNDN); /* rl[i] += vr */ mpfr_add(big_im(i), big_im(i), vi, GMP_RNDN); /* im[i] += vi */ i += m; j += m; } mpfr_set(u, ur, GMP_RNDN); /* u = ur */ mpfr_set(temp, ui, GMP_RNDN); /* ur = (ur * c) - (ui * s) */ mpfr_mul(temp, temp, s, GMP_RNDN); mpfr_mul(ur, ur, c, GMP_RNDN); mpfr_sub(ur, ur, temp, GMP_RNDN); mpfr_set(temp, u, GMP_RNDN); /* ui = (ui * c) + (u * s) */ mpfr_mul(temp, temp, s, GMP_RNDN); mpfr_mul(ui, ui, c, GMP_RNDN); mpfr_add(ui, ui, temp, GMP_RNDN); } mh >>= 1; ldm = m; mpfr_div_ui(angle, angle, 2, GMP_RNDN); /* angle *= 0.5 */ m <<= 1; } return(s7_f(sc)); } #endif #if HAVE_SPECIAL_FUNCTIONS && (!HAVE_GSL) static Xen g_j0(Xen x) { #define H_j0 "(" S_bes_j0 " x): returns the regular cylindrical bessel function value J0(x)" #if (!HAVE_SCHEME) Xen_check_type(Xen_is_number(x), x, 1, S_bes_j0, " a number"); #endif #if HAVE_SCHEME && WITH_GMP if ((s7_is_bignum(x)) && (s7_is_real(x)) && (!(s7_is_rational(x)))) return(big_j0(x)); #endif return(C_double_to_Xen_real(j0(Xen_real_to_C_double(x)))); } static Xen g_j1(Xen x) { #define H_j1 "(" S_bes_j1 " x): returns the regular cylindrical bessel function value J1(x)" #if (!HAVE_SCHEME) Xen_check_type(Xen_is_number(x), x, 1, S_bes_j1, " a number"); #endif #if HAVE_SCHEME && WITH_GMP if ((s7_is_bignum(x)) && (s7_is_real(x)) && (!(s7_is_rational(x)))) return(big_j1(x)); #endif return(C_double_to_Xen_real(j1(Xen_real_to_C_double(x)))); } static Xen g_jn(Xen order, Xen x) { #define H_jn "(" S_bes_jn " n x): returns the regular cylindrical bessel function value Jn(x)" Xen_check_type(Xen_is_integer(order), x, 1, S_bes_jn, " an int"); #if (!HAVE_SCHEME) Xen_check_type(Xen_is_number(x), x, 2, S_bes_jn, " a number"); #endif #if HAVE_SCHEME && WITH_GMP if ((s7_is_bignum(x)) && (s7_is_real(x)) && (!(s7_is_rational(x)))) return(big_jn(order, x)); #endif return(C_double_to_Xen_real(jn(Xen_integer_to_C_int(order), Xen_real_to_C_double(x)))); } static Xen g_y0(Xen x) { #define H_y0 "(" S_bes_y0 " x): returns the irregular cylindrical bessel function value Y0(x)" Xen_check_type(Xen_is_number(x), x, 1, S_bes_y0, " a number"); #if HAVE_SCHEME && WITH_GMP if ((s7_is_bignum(x)) && (s7_is_real(x)) && (!(s7_is_rational(x)))) return(big_y0(x)); #endif return(C_double_to_Xen_real(y0(Xen_real_to_C_double(x)))); } static Xen g_y1(Xen x) { #define H_y1 "(" S_bes_y1 " x): returns the irregular cylindrical bessel function value Y1(x)" Xen_check_type(Xen_is_number(x), x, 1, S_bes_y1, " a number"); #if HAVE_SCHEME && WITH_GMP if ((s7_is_bignum(x)) && (s7_is_real(x)) && (!(s7_is_rational(x)))) return(big_y1(x)); #endif return(C_double_to_Xen_real(y1(Xen_real_to_C_double(x)))); } static Xen g_yn(Xen order, Xen x) { #define H_yn "(" S_bes_yn " n x): returns the irregular cylindrical bessel function value Yn(x)" Xen_check_type(Xen_is_integer(order), x, 1, S_bes_yn, " an int"); Xen_check_type(Xen_is_number(x), x, 2, S_bes_yn, " a number"); #if HAVE_SCHEME && WITH_GMP if ((s7_is_bignum(x)) && (s7_is_real(x)) && (!(s7_is_rational(x)))) return(big_yn(order, x)); #endif return(C_double_to_Xen_real(yn(Xen_integer_to_C_int(order), Xen_real_to_C_double(x)))); } static Xen g_erf(Xen x) { #define H_erf "(erf x): returns the error function erf(x)" Xen_check_type(Xen_is_number(x), x, 1, "erf", " a number"); #if HAVE_SCHEME && WITH_GMP if ((s7_is_bignum(x)) && (s7_is_real(x)) && (!(s7_is_rational(x)))) return(big_erf(x)); #endif return(C_double_to_Xen_real(erf(Xen_real_to_C_double(x)))); } static Xen g_erfc(Xen x) { #define H_erfc "(erfc x): returns the complementary error function erfc(x)" Xen_check_type(Xen_is_number(x), x, 1, "erfc", " a number"); #if HAVE_SCHEME && WITH_GMP if ((s7_is_bignum(x)) && (s7_is_real(x)) && (!(s7_is_rational(x)))) return(big_erfc(x)); #endif return(C_double_to_Xen_real(erfc(Xen_real_to_C_double(x)))); } static Xen g_lgamma(Xen x) { #define H_lgamma "(lgamma x): returns the log of the gamma function at x" Xen_check_type(Xen_is_number(x), x, 1, "lgamma", " a number"); return(C_double_to_Xen_real(lgamma(Xen_real_to_C_double(x)))); } #endif #define S_bes_i0 "bes-i0" static Xen g_i0(Xen x) { #define H_i0 "(" S_bes_i0 " x): returns the modified cylindrical bessel function value I0(x)" Xen_check_type(Xen_is_number(x), x, 1, S_bes_i0, " a number"); #if HAVE_SCHEME && WITH_GMP if ((s7_is_bignum(x)) && (s7_is_real(x)) && (!(s7_is_rational(x)))) return(big_i0(x)); #endif return(C_double_to_Xen_real(mus_bessi0(Xen_real_to_C_double(x)))); /* uses GSL if possible */ } /* ---------------------------------------- use GSL ---------------------------------------- */ #if HAVE_GSL /* include all the bessel functions, etc */ #include static Xen g_j0(Xen x) { #define H_j0 "(" S_bes_j0 " x): returns the regular cylindrical bessel function value J0(x)" Xen_check_type(Xen_is_number(x), x, 1, S_bes_j0, " a number"); #if HAVE_SCHEME && WITH_GMP if ((s7_is_bignum(x)) && (s7_is_real(x)) && (!(s7_is_rational(x)))) return(big_j0(x)); #endif return(C_double_to_Xen_real(gsl_sf_bessel_J0(Xen_real_to_C_double(x)))); } static Xen g_j1(Xen x) { #define H_j1 "(" S_bes_j1 " x): returns the regular cylindrical bessel function value J1(x)" Xen_check_type(Xen_is_number(x), x, 1, S_bes_j1, " a number"); #if HAVE_SCHEME && WITH_GMP if ((s7_is_bignum(x)) && (s7_is_real(x)) && (!(s7_is_rational(x)))) return(big_j1(x)); #endif return(C_double_to_Xen_real(gsl_sf_bessel_J1(Xen_real_to_C_double(x)))); } static Xen g_jn(Xen order, Xen x) { #define H_jn "(" S_bes_jn " n x): returns the regular cylindrical bessel function value Jn(x)" Xen_check_type(Xen_is_integer(order), x, 1, S_bes_jn, " an int"); Xen_check_type(Xen_is_number(x), x, 2, S_bes_jn, " a number"); #if HAVE_SCHEME && WITH_GMP if ((s7_is_bignum(x)) && (s7_is_real(x)) && (!(s7_is_rational(x)))) return(big_jn(order, x)); #endif return(C_double_to_Xen_real(gsl_sf_bessel_Jn(Xen_integer_to_C_int(order), Xen_real_to_C_double(x)))); } static Xen g_y0(Xen x) { #define H_y0 "(" S_bes_y0 " x): returns the irregular cylindrical bessel function value Y0(x)" Xen_check_type(Xen_is_number(x), x, 1, S_bes_y0, " a number"); #if HAVE_SCHEME && WITH_GMP if ((s7_is_bignum(x)) && (s7_is_real(x)) && (!(s7_is_rational(x)))) return(big_y0(x)); #endif return(C_double_to_Xen_real(gsl_sf_bessel_Y0(Xen_real_to_C_double(x)))); } static Xen g_y1(Xen x) { #define H_y1 "(" S_bes_y1 " x): returns the irregular cylindrical bessel function value Y1(x)" Xen_check_type(Xen_is_number(x), x, 1, S_bes_y1, " a number"); #if HAVE_SCHEME && WITH_GMP if ((s7_is_bignum(x)) && (s7_is_real(x)) && (!(s7_is_rational(x)))) return(big_y1(x)); #endif return(C_double_to_Xen_real(gsl_sf_bessel_Y1(Xen_real_to_C_double(x)))); } static Xen g_yn(Xen order, Xen x) { #define H_yn "(" S_bes_yn " n x): returns the irregular cylindrical bessel function value Yn(x)" Xen_check_type(Xen_is_integer(order), x, 1, S_bes_yn, " an int"); Xen_check_type(Xen_is_number(x), x, 2, S_bes_yn, " a number"); #if HAVE_SCHEME && WITH_GMP if ((s7_is_bignum(x)) && (s7_is_real(x)) && (!(s7_is_rational(x)))) return(big_yn(order, x)); #endif return(C_double_to_Xen_real(gsl_sf_bessel_Yn(Xen_integer_to_C_int(order), Xen_real_to_C_double(x)))); } #define S_bes_i1 "bes-i1" #define S_bes_in "bes-in" #define S_bes_k0 "bes-k0" #define S_bes_k1 "bes-k1" #define S_bes_kn "bes-kn" static Xen g_i1(Xen x) { #define H_i1 "(" S_bes_i1 " x): returns the regular cylindrical bessel function value I1(x)" Xen_check_type(Xen_is_number(x), x, 1, S_bes_i1, " a number"); return(C_double_to_Xen_real(gsl_sf_bessel_I1(Xen_real_to_C_double(x)))); } static Xen g_in(Xen order, Xen x) { #define H_in "(" S_bes_in " n x): returns the regular cylindrical bessel function value In(x)" Xen_check_type(Xen_is_integer(order), x, 1, S_bes_in, " an int"); Xen_check_type(Xen_is_number(x), x, 2, S_bes_in, " a number"); return(C_double_to_Xen_real(gsl_sf_bessel_In(Xen_integer_to_C_int(order), Xen_real_to_C_double(x)))); } static Xen g_k0(Xen x) { #define H_k0 "(" S_bes_k0 " x): returns the irregular cylindrical bessel function value K0(x)" Xen_check_type(Xen_is_number(x), x, 1, S_bes_k0, " a number"); return(C_double_to_Xen_real(gsl_sf_bessel_K0(Xen_real_to_C_double(x)))); } static Xen g_k1(Xen x) { #define H_k1 "(" S_bes_k1 " x): returns the irregular cylindrical bessel function value K1(x)" Xen_check_type(Xen_is_number(x), x, 1, S_bes_k1, " a number"); return(C_double_to_Xen_real(gsl_sf_bessel_K1(Xen_real_to_C_double(x)))); } static Xen g_kn(Xen order, Xen x) { #define H_kn "(" S_bes_kn " n x): returns the irregular cylindrical bessel function value Kn(x)" Xen_check_type(Xen_is_integer(order), x, 1, S_bes_kn, " an int"); Xen_check_type(Xen_is_number(x), x, 2, S_bes_kn, " a number"); return(C_double_to_Xen_real(gsl_sf_bessel_Kn(Xen_integer_to_C_int(order), Xen_real_to_C_double(x)))); } #include static Xen g_erf(Xen x) { #define H_erf "(erf x): returns the error function erf(x)" Xen_check_type(Xen_is_number(x), x, 1, "erf", " a number"); #if HAVE_SCHEME && WITH_GMP if ((s7_is_bignum(x)) && (s7_is_real(x)) && (!(s7_is_rational(x)))) return(big_erf(x)); #endif return(C_double_to_Xen_real(gsl_sf_erf(Xen_real_to_C_double(x)))); } static Xen g_erfc(Xen x) { #define H_erfc "(erfc x): returns the complementary error function value erfc(x)" Xen_check_type(Xen_is_number(x), x, 1, "erfc", " a number"); #if HAVE_SCHEME && WITH_GMP if ((s7_is_bignum(x)) && (s7_is_real(x)) && (!(s7_is_rational(x)))) return(big_erfc(x)); #endif return(C_double_to_Xen_real(gsl_sf_erfc(Xen_real_to_C_double(x)))); } #include static Xen g_lgamma(Xen x) { #define H_lgamma "(lgamma x): returns the log of the gamma function at x" Xen_check_type(Xen_is_number(x), x, 1, "lgamma", " a number"); return(C_double_to_Xen_real(gsl_sf_lngamma(Xen_real_to_C_double(x)))); } #include static Xen g_gsl_ellipk(Xen k) { double f; #define H_gsl_ellipk "(gsl-ellipk k): returns the complete elliptic integral k" Xen_check_type(Xen_is_number(k), k, 1, "gsl-ellipk", "a number"); f = Xen_real_to_C_double(k); Xen_check_type(f >= 0.0, k, 1, "gsl-ellipk", "a non-negative number"); return(C_double_to_Xen_real(gsl_sf_ellint_Kcomp(sqrt(Xen_real_to_C_double(k)), GSL_PREC_APPROX))); } #include static Xen g_gsl_ellipj(Xen u, Xen m) { #define H_gsl_ellipj "(gsl-ellipj u m): returns the Jacobian elliptic functions sn, cn, and dn of u and m" double sn = 0.0, cn = 0.0, dn = 0.0; Xen_check_type(Xen_is_number(u), u, 1, "gsl-ellipj", "a number"); Xen_check_type(Xen_is_number(m), m, 2, "gsl-ellipj", "a number"); gsl_sf_elljac_e(Xen_real_to_C_double(u), Xen_real_to_C_double(m), &sn, &cn, &dn); return(Xen_list_3(C_double_to_Xen_real(sn), C_double_to_Xen_real(cn), C_double_to_Xen_real(dn))); } #include #if ((GSL_MAJOR_VERSION >= 1) && (GSL_MINOR_VERSION >= 9)) #define HAVE_GSL_EIGEN_NONSYMMV_WORKSPACE 1 #endif #if HAVE_GSL_EIGEN_NONSYMMV_WORKSPACE /* eignevector/values, from gsl/doc/examples/eigen_nonsymm.c */ #include #include static Xen g_gsl_eigenvectors(Xen matrix) { double *data; int i, j, len; Xen values = Xen_false, vectors = Xen_false; #if HAVE_SCHEME Xen_check_type(s7_is_float_vector(matrix), matrix, 1, "gsl-eigenvectors", "a float vector"); len = (int)sqrt(s7_vector_length(matrix)); data = (double *)s7_float_vector_elements(matrix); #else vct *v; Xen_check_type(mus_is_vct(matrix), matrix, 1, "gsl-eigenvectors", "a vct"); v = Xen_to_vct(matrix); len = (int)sqrt(mus_vct_length(v)); data = mus_vct_data(v); #endif { gsl_matrix_view m = gsl_matrix_view_array(data, len, len); gsl_vector_complex *eval = gsl_vector_complex_alloc(len); gsl_matrix_complex *evec = gsl_matrix_complex_alloc(len, len); gsl_eigen_nonsymmv_workspace *w = gsl_eigen_nonsymmv_alloc(len); gsl_eigen_nonsymmv(&m.matrix, eval, evec, w); gsl_eigen_nonsymmv_free(w); gsl_eigen_nonsymmv_sort(eval, evec, GSL_EIGEN_SORT_ABS_DESC); { int values_loc, vectors_loc; values = Xen_make_vector(len, Xen_integer_zero); values_loc = snd_protect(values); vectors = Xen_make_vector(len, Xen_false); vectors_loc = snd_protect(vectors); for (i = 0; i < len; i++) { Xen vect; #if HAVE_SCHEME s7_double *fv_data; #endif gsl_complex eval_i = gsl_vector_complex_get(eval, i); gsl_vector_complex_view evec_i = gsl_matrix_complex_column(evec, i); Xen_vector_set(values, i, C_double_to_Xen_real(GSL_REAL(eval_i))); #if HAVE_SCHEME vect = s7_make_float_vector(s7, len, 1, NULL); fv_data = s7_float_vector_elements(vect); #else vect = Xen_make_vector(len, Xen_integer_zero); #endif Xen_vector_set(vectors, i, vect); for (j = 0; j < len; j++) { gsl_complex z = gsl_vector_complex_get(&evec_i.vector, j); #if HAVE_SCHEME fv_data[j] = GSL_REAL(z); #else Xen_vector_set(vect, j, C_double_to_Xen_real(GSL_REAL(z))); #endif } } snd_unprotect_at(values_loc); snd_unprotect_at(vectors_loc); } gsl_vector_complex_free(eval); gsl_matrix_complex_free(evec); } #if (!HAVE_SCHEME) free(data); #endif return(Xen_list_2(values, vectors)); } #endif #if HAVE_COMPLEX_TRIG && HAVE_COMPLEX_NUMBERS #include #include static Xen g_gsl_roots(Xen poly) { #define H_gsl_roots "(gsl-roots poly): roots of poly" int i, n, loc; double *p; double complex *z; gsl_poly_complex_workspace *w; Xen result; /* gsl_roots: balance_companion_matrix gets hung if the vector is multidimensional */ Xen_check_type((Xen_is_vector(poly)) && (Xen_vector_rank(poly) == 1), poly, 1, "gsl-roots", "a vector"); n = Xen_vector_length(poly); w = gsl_poly_complex_workspace_alloc(n); z = (double complex *)calloc(n, sizeof(double complex)); p = (double *)calloc(n, sizeof(double)); #if HAVE_SCHEME if (s7_is_float_vector(poly)) { s7_double *e; e = s7_float_vector_elements(poly); for (i = 0; i < n; i++) p[i] = e[i]; } else { for (i = 0; i < n; i++) p[i] = Xen_real_to_C_double(Xen_vector_ref(poly, i)); } #else for (i = 0; i < n; i++) p[i] = Xen_real_to_C_double(Xen_vector_ref(poly, i)); #endif gsl_poly_complex_solve(p, n, w, (gsl_complex_packed_ptr)z); gsl_poly_complex_workspace_free (w); result = Xen_make_vector(n - 1, Xen_integer_zero); loc = snd_protect(result); for (i = 0; i < n - 1; i++) if (__imag__(z[i]) != 0.0) Xen_vector_set(result, i, C_complex_to_Xen_complex(z[i])); else Xen_vector_set(result, i, C_double_to_Xen_real(__real__(z[i]))); free(z); free(p); snd_unprotect_at(loc); return(result); } #endif #endif /* -------- source file extensions list -------- */ static char **source_file_extensions = NULL; static int source_file_extensions_size = 0; static int source_file_extensions_end = 0; static int default_source_file_extensions = 0; static void add_source_file_extension(const char *ext) { int i; for (i = 0; i < source_file_extensions_end; i++) if (mus_strcmp(ext, source_file_extensions[i])) return; if (source_file_extensions_end == source_file_extensions_size) { source_file_extensions_size += 8; if (source_file_extensions == NULL) source_file_extensions = (char **)calloc(source_file_extensions_size, sizeof(char *)); else source_file_extensions = (char **)realloc(source_file_extensions, source_file_extensions_size * sizeof(char *)); } source_file_extensions[source_file_extensions_end] = mus_strdup(ext); source_file_extensions_end++; } bool is_source_file(const char *name) { if (!name) return(false); if (source_file_extensions) { int i, dot_loc = -1, len; len = strlen(name); for (i = 0; i < len; i++) if (name[i] == '.') dot_loc = i; /* dot_loc is last dot in the name */ if ((dot_loc > 0) && (dot_loc < len - 1)) { const char *ext; ext = (const char *)(name + dot_loc + 1); for (i = 0; i < source_file_extensions_end; i++) if (mus_strcmp(ext, source_file_extensions[i])) return(true); } } return(false); } void save_added_source_file_extensions(FILE *fd) { if (source_file_extensions_end > default_source_file_extensions) { int i; for (i = default_source_file_extensions; i < source_file_extensions_end; i++) { #if HAVE_SCHEME fprintf(fd, "(%s \"%s\")\n", S_add_source_file_extension, source_file_extensions[i]); #endif #if HAVE_RUBY fprintf(fd, "%s(\"%s\")\n", to_proc_name(S_add_source_file_extension), source_file_extensions[i]); #endif #if HAVE_FORTH fprintf(fd, "\"%s\" %s drop\n", source_file_extensions[i], S_add_source_file_extension); #endif } } } static Xen g_add_source_file_extension(Xen ext) { #define H_add_source_file_extension "(" S_add_source_file_extension " ext): add the file extension 'ext' to the list of source file extensions" Xen_check_type(Xen_is_string(ext), ext, 1, S_add_source_file_extension, "a string"); add_source_file_extension(Xen_string_to_C_string(ext)); return(ext); } static char *find_source_file(const char *orig) { int i; for (i = 0; i < source_file_extensions_end; i++) { char *str; str = mus_format("%s.%s", orig, source_file_extensions[i]); if (mus_file_probe(str)) return(str); free(str); } return(NULL); } /* list-in-vector|list, vector-in-list|vector, cobj-in-vector|list obj-in-cobj * string-ci-in-vector? hash-table cases? * most of this could be done via for-each */ #if HAVE_SCHEME && (!_MSC_VER) Xen_wrap_2_optional_args(g_dlopen_w, g_dlopen) Xen_wrap_1_arg(g_dlclose_w, g_dlclose) Xen_wrap_no_args(g_dlerror_w, g_dlerror) Xen_wrap_2_args(g_dlinit_w, g_dlinit) Xen_wrap_2_args(g_dlsym_w, g_dlsym) #endif #if HAVE_SCHEME Xen_wrap_any_args(g_snd_s7_error_handler_w, g_snd_s7_error_handler); #endif Xen_wrap_1_arg(g_snd_print_w, g_snd_print) Xen_wrap_no_args(g_little_endian_w, g_little_endian) Xen_wrap_no_args(g_snd_global_state_w, g_snd_global_state) Xen_wrap_1_arg(g_add_source_file_extension_w, g_add_source_file_extension) #if (!HAVE_SCHEME) Xen_wrap_2_args(g_fmod_w, g_fmod) #endif #if HAVE_SPECIAL_FUNCTIONS || HAVE_GSL Xen_wrap_1_arg(g_j0_w, g_j0) Xen_wrap_1_arg(g_j1_w, g_j1) Xen_wrap_2_args(g_jn_w, g_jn) Xen_wrap_1_arg(g_y0_w, g_y0) Xen_wrap_1_arg(g_y1_w, g_y1) Xen_wrap_2_args(g_yn_w, g_yn) Xen_wrap_1_arg(g_erf_w, g_erf) Xen_wrap_1_arg(g_erfc_w, g_erfc) Xen_wrap_1_arg(g_lgamma_w, g_lgamma) #endif Xen_wrap_1_arg(g_i0_w, g_i0) #if HAVE_GSL Xen_wrap_1_arg(g_i1_w, g_i1) Xen_wrap_2_args(g_in_w, g_in) Xen_wrap_1_arg(g_k0_w, g_k0) Xen_wrap_1_arg(g_k1_w, g_k1) Xen_wrap_2_args(g_kn_w, g_kn) Xen_wrap_1_arg(g_gsl_ellipk_w, g_gsl_ellipk) Xen_wrap_2_args(g_gsl_ellipj_w, g_gsl_ellipj) #if HAVE_GSL_EIGEN_NONSYMMV_WORKSPACE Xen_wrap_1_arg(g_gsl_eigenvectors_w, g_gsl_eigenvectors) #endif #if HAVE_COMPLEX_TRIG && HAVE_COMPLEX_NUMBERS Xen_wrap_1_arg(g_gsl_roots_w, g_gsl_roots) #endif #endif #if USE_MOTIF void Init_libxm(void); #else void Init_libxg(void); #endif #if HAVE_GL void Init_libgl(void); #endif static char *legalize_path(const char *in_str) { int inlen; char *out_str; int inpos, outpos = 0; inlen = mus_strlen(in_str); out_str = (char *)calloc(inlen * 2, sizeof(char)); for (inpos = 0; inpos < inlen; inpos++) { if (in_str[inpos] == '\\') out_str[outpos++] = '\\'; out_str[outpos++] = in_str[inpos]; } return(out_str); } #if HAVE_GL static Xen g_snd_gl_context(void) { #if USE_GTK /* return(Xen_list_2(C_string_to_Xen_symbol("GLContext"), Xen_wrap_C_pointer(ss->cx))); */ #else #if USE_MOTIF return(Xen_list_2(C_string_to_Xen_symbol("GLXContext"), Xen_wrap_C_pointer(ss->cx))); #else return(XEN_FALSE); #endif #endif } Xen_wrap_no_args(g_snd_gl_context_w, g_snd_gl_context) #endif /* -------------------------------------------------------------------------------- */ Xen_wrap_1_arg(g_snd_error_w, g_snd_error) Xen_wrap_1_arg(g_snd_warning_w, g_snd_warning) void g_xen_initialize(void) { #if HAVE_SCHEME s7_pointer pl_dr, pl_dir, pl_ss, pl_b; #if HAVE_GSL_EIGEN_NONSYMMV_WORKSPACE s7_pointer pl_pf; #endif #endif #if HAVE_RUBY rb_gc_disable(); #endif Xen_define_procedure(S_snd_error, g_snd_error_w, 1, 0, 0, H_snd_error); Xen_define_procedure(S_snd_warning, g_snd_warning_w, 1, 0, 0, H_snd_warning); #if HAVE_SCHEME #define H_snd_error_hook S_snd_error_hook " (message): called upon snd_error. \ If it returns " PROC_TRUE ", Snd flushes the error (it assumes you've reported it via the hook):\n\ (hook-push " S_snd_error_hook "\n\ (lambda (hook) (" S_play " \"bong.snd\")))" #define H_snd_warning_hook S_snd_warning_hook " (message): called upon snd_warning. \ If it returns " PROC_TRUE ", Snd flushes the warning (it assumes you've reported it via the hook):\n\ (define without-warnings\n\ (lambda (thunk)\n\ (define no-warning (lambda (hook) (set! (hook 'result) #t)))\n\ (hook-push snd-warning-hook no-warning) \n\ (thunk)\n\ (hook-remove snd-warning-hook no-warning)))" #endif #if HAVE_RUBY #define H_snd_error_hook S_snd_error_hook " (error-message): called upon snd_error. \ If it returns true, Snd flushes the error (it assumes you've reported it via the hook):\n\ $snd_error_hook.add-hook!(\"error\") do |msg|\n\ play(\"bong.snd\")\n\ false\n\ end" #define H_snd_warning_hook S_snd_warning_hook " (warning-message): called upon snd_warning. \ If it returns true, Snd flushes the warning (it assumes you've reported it via the hook)\n\ def without_warning(&body)\n\ $snd_warning_hook.add_hook!(\"no_warning\") do |msg| true end\n\ ret = body.call\n\ $snd_warning_hook.remove_hook!(\"no_warning\")\n\ ret\n\ end\n\ # without_warning do " S_snd_warning "(\"not shown\") end" #endif #if HAVE_FORTH #define H_snd_error_hook S_snd_error_hook " (error-message): called upon snd_error. \ If it returns " PROC_TRUE ", Snd flushes the error (it assumes you've reported it via the hook):\n\ " S_snd_error_hook " lambda: <{ msg }>\n\ \"bong.snd\" " S_play " drop\n\ #f\n\ ; add-hook!" #define H_snd_warning_hook S_snd_warning_hook " (warning-message): called upon snd_warning. \ If it returns " PROC_TRUE ", Snd flushes the warning (it assumes you've reported it via the hook)\n\ : no-warning <{ msg -- f }> #t ;\n\ : without-warnings <{ xt -- }>\n\ " S_snd_warning_hook " <'> no-warning add-hook!\n\ xt execute\n\ " S_snd_warning_hook " <'> no-warning remove-hook! drop\n\ ;\n\ \\ lambda: ( -- ) \"not shown\" " S_snd_warning " ; without-warning\n\ " #endif ss->snd_error_hook = Xen_define_hook(S_snd_error_hook, "(make-hook 'message)", 1, H_snd_error_hook); ss->snd_warning_hook = Xen_define_hook(S_snd_warning_hook, "(make-hook 'message)", 1, H_snd_warning_hook); #define H_clip_hook S_clip_hook " (val) is called each time a sample is about to \ be clipped upon being written to a sound file. The hook function can return the new value to \ be written, or rely on the default (-1.0 or 1.0 depending on the sign of 'val')." clip_hook = Xen_define_hook(S_clip_hook, "(make-hook 'val)", 1, H_clip_hook); mus_clip_set_handler_and_checker(NULL, clip_hook_checker); add_source_file_extension(Xen_file_extension); #if HAVE_SCHEME add_source_file_extension("cl"); add_source_file_extension("lisp"); add_source_file_extension("init"); /* for slib */ #endif #if HAVE_FORTH add_source_file_extension("fth"); add_source_file_extension("fsm"); #endif add_source_file_extension("marks"); /* from save-marks */ default_source_file_extensions = source_file_extensions_end; Xen_define_procedure("snd-global-state", g_snd_global_state_w, 0, 0, 0, "internal testing function"); Xen_define_procedure(S_add_source_file_extension, g_add_source_file_extension_w, 1, 0, 0, H_add_source_file_extension); ss->snd_open_file_hook = Xen_define_simple_hook("(make-hook 'reason)", 1); Xen_GC_protect(ss->snd_open_file_hook); ss->effects_hook = Xen_define_hook(S_effects_hook, "(make-hook)", 0, "called when something changes that the effects dialogs care about"); Init_sndlib(); #if HAVE_FORTH fth_add_loaded_files("sndlib.so"); #endif #if (!HAVE_SCHEME) gc_protection = Xen_false; #endif #if HAVE_SCHEME { s7_pointer s, i, b, r, d; s = s7_make_symbol(s7, "string?"); i = s7_make_symbol(s7, "integer?"); b = s7_make_symbol(s7, "boolean?"); r = s7_make_symbol(s7, "real?"); d = s7_make_symbol(s7, "float?"); pl_ss = s7_make_signature(s7, 2, s, s); pl_dr = s7_make_circular_signature(s7, 1, 2, d, r); pl_dir = s7_make_signature(s7, 3, d, i, r); pl_b = s7_make_signature(s7, 1, b); #if HAVE_GSL_EIGEN_NONSYMMV_WORKSPACE pl_pf = s7_make_signature(s7, 2, s7_make_symbol(s7, "pair?"), s7_make_symbol(s7, "float-vector?")); #endif } #endif Xen_define_typed_procedure(S_snd_print, g_snd_print_w, 1, 0, 0, H_snd_print, pl_ss); Xen_define_typed_procedure("little-endian?", g_little_endian_w, 0, 0, 0, "return " PROC_TRUE " if host is little endian", pl_b); #if HAVE_SCHEME Xen_eval_C_string("(define fmod modulo)"); #else Xen_define_procedure("fmod", g_fmod_w, 2, 0, 0, "C's fmod"); #endif #if HAVE_SPECIAL_FUNCTIONS || HAVE_GSL Xen_define_typed_procedure(S_bes_j0, g_j0_w, 1, 0, 0, H_j0, pl_dr); Xen_define_typed_procedure(S_bes_j1, g_j1_w, 1, 0, 0, H_j1, pl_dr); Xen_define_typed_procedure(S_bes_jn, g_jn_w, 2, 0, 0, H_jn, pl_dir); Xen_define_typed_procedure(S_bes_y0, g_y0_w, 1, 0, 0, H_y0, pl_dr); Xen_define_typed_procedure(S_bes_y1, g_y1_w, 1, 0, 0, H_y1, pl_dr); Xen_define_typed_procedure(S_bes_yn, g_yn_w, 2, 0, 0, H_yn, pl_dir); Xen_define_typed_procedure("erf", g_erf_w, 1, 0, 0, H_erf, pl_dr); Xen_define_typed_procedure("erfc", g_erfc_w, 1, 0, 0, H_erfc, pl_dr); Xen_define_typed_procedure("lgamma", g_lgamma_w, 1, 0, 0, H_lgamma, pl_dr); #endif Xen_define_safe_procedure(S_bes_i0, g_i0_w, 1, 0, 0, H_i0); #if HAVE_GSL Xen_define_typed_procedure(S_bes_i1, g_i1_w, 1, 0, 0, H_i1, pl_dr); Xen_define_typed_procedure(S_bes_in, g_in_w, 2, 0, 0, H_in, pl_dir); Xen_define_typed_procedure(S_bes_k0, g_k0_w, 1, 0, 0, H_k0, pl_dr); Xen_define_typed_procedure(S_bes_k1, g_k1_w, 1, 0, 0, H_k1, pl_dr); Xen_define_typed_procedure(S_bes_kn, g_kn_w, 2, 0, 0, H_kn, pl_dir); Xen_define_typed_procedure("gsl-ellipk", g_gsl_ellipk_w, 1, 0, 0, H_gsl_ellipk, pl_dr); Xen_define_typed_procedure("gsl-ellipj", g_gsl_ellipj_w, 2, 0, 0, H_gsl_ellipj, pl_dr); #if HAVE_GSL_EIGEN_NONSYMMV_WORKSPACE Xen_define_typed_procedure("gsl-eigenvectors", g_gsl_eigenvectors_w, 1, 0, 0, "returns eigenvalues and eigenvectors", pl_pf); #endif #if HAVE_COMPLEX_TRIG && HAVE_COMPLEX_NUMBERS Xen_define_typed_procedure("gsl-roots", g_gsl_roots_w, 1, 0, 0, H_gsl_roots, NULL); #endif #endif #if HAVE_SCHEME && WITH_GMP s7_define_function(s7, "bignum-fft", bignum_fft, 3, 1, false, H_bignum_fft); #endif g_init_base(); g_init_utils(); g_init_marks(); g_init_regions(); g_init_selection(); g_init_mix(); g_init_fft(); /* needs to precede snd-chn init */ g_init_chn(); g_init_kbd(); g_init_sig(); g_init_print(); g_init_edits(); g_init_listener(); g_init_help(); g_init_menu(); g_init_main(); g_init_snd(); g_init_dac(); /* needs to follow snd and mix */ g_init_file(); g_init_data(); g_init_env(); g_init_find(); #if (!USE_NO_GUI) g_init_gxcolormaps(); g_init_gxfile(); g_init_gxdraw(); g_init_gxenv(); g_init_gxmenu(); g_init_axis(); g_init_gxlistener(); g_init_gxchn(); g_init_draw(); g_init_gxregion(); g_init_gxsnd(); g_init_gxfind(); #endif #if HAVE_SCHEME && (!_MSC_VER) Xen_define_procedure("dlopen", g_dlopen_w, 1, 1 ,0, H_dlopen); Xen_define_procedure("dlclose", g_dlclose_w, 1, 0 ,0, H_dlclose); Xen_define_procedure("dlerror", g_dlerror_w, 0, 0 ,0, H_dlerror); Xen_define_procedure("dlinit", g_dlinit_w, 2, 0 ,0, H_dlinit); Xen_define_procedure("dlsym", g_dlsym_w, 2, 0 ,0, H_dlsym); Xen_define_constant("RTLD_LAZY", RTLD_LAZY, "dlopen flag"); Xen_define_constant("RTLD_NOW", RTLD_NOW, "dlopen flag"); Xen_define_constant("RTLD_GLOBAL", RTLD_GLOBAL, "dlopen flag"); #endif #if HAVE_LADSPA && HAVE_EXTENSION_LANGUAGE g_ladspa_to_snd(); #endif #ifdef SCRIPTS_DIR Xen_add_to_load_path((char *)SCRIPTS_DIR); #endif { char *pwd, *legal_pwd; pwd = mus_getcwd(); legal_pwd = legalize_path(pwd); Xen_add_to_load_path(legal_pwd); free(legal_pwd); } #if HAVE_SCHEME Xen_define_procedure("_snd_s7_error_handler_", g_snd_s7_error_handler_w, 0, 0, 1, "internal error redirection for snd/s7"); s7_define_safe_function(s7, "_snd-line-reader_", g_line_reader, 1, 0, false, "port-line-number reader"); Xen_eval_C_string("(define redo-edit redo)"); /* consistency with Ruby */ Xen_eval_C_string("(define undo-edit undo)"); /* Xen_eval_C_string("(define (procedure-name proc) (if (procedure? proc) (format #f \"~A\" proc) #f))"); */ /* needed in snd-test.scm and hooks.scm */ Xen_eval_C_string("\ (define* (apropos name (port #f) (e (rootlet))) \ \"(apropos name (port *stdout*) (env (rootlet))) looks for 'name' as a part of any symbol name, and sends matches to 'port'\" \ (let ((ap-name (if (string? name) \ name \ (if (symbol? name) \ (symbol->string name) \ (error 'wrong-type-arg \"apropos argument 1 should be a string or a symbol\")))) \ (ap-env (if (let? e) \ e \ (error 'wrong-type-arg \"apropos argument 3 should be an environment\"))) \ (ap-port (if (or (not port) (output-port? port)) \ port \ (error 'wrong-type-arg \"apropos argument 2 should be an output port\")))) \ (for-each \ (lambda (binding) \ (if (and (pair? binding) \ (string-position ap-name (symbol->string (car binding)))) \ (snd-print \ (format ap-port \"~%~A: ~A\" \ (car binding) \ (if (procedure? (cdr binding)) \ (procedure-documentation (cdr binding)) \ (cdr binding)))))) \ ap-env) \ #f))"); Xen_eval_C_string("\ (define break-ok #f)\ (define break-exit #f) ; a kludge to get 2 funcs to share a local variable\n\ (define break-enter #f)\ \ (let ((saved-listener-prompt (listener-prompt)))\ (set! break-exit (lambda ()\ (hook-clear read-hook)\ (set! (listener-prompt) saved-listener-prompt)\ #f))\ (set! break-enter (lambda ()\ (set! saved-listener-prompt (listener-prompt)))))\ \ (define-macro (break)\ `(let ((__break__ (curlet)))\ (break-enter)\ (set! (listener-prompt) (format #f \"~A>\" (if (defined? __func__) __func__ 'break)))\ (call/cc\ (lambda (return)\ (set! break-ok return) ; save current program loc so (break-ok) continues from the break\n\ (hook-push read-hook ; anything typed in the listener is evaluated in the environment of the break call\n\ (lambda (str)\ (eval-string str __break__)))\ (error 'snd-top-level))) ; jump back to the top level\n\ (break-exit))) ; we get here if break-ok is called\n\ "); #endif #if HAVE_FORTH Xen_eval_C_string("<'> redo alias redo-edit"); /* consistency with Ruby */ Xen_eval_C_string("<'> undo alias undo-edit"); Xen_eval_C_string(": clm-print ( fmt :optional args -- ) fth-format snd-print drop ;"); #endif #if HAVE_RUBY Xen_eval_C_string("def clm_print(str, *args)\n\ snd_print format(str, *args)\n\ end"); #endif #if HAVE_GL Xen_define_procedure("snd-gl-context", g_snd_gl_context_w, 0, 0, 0, "GL Context"); #endif #if USE_MOTIF #if HAVE_SCHEME { s7_pointer motif, old_shadow; s7_define_constant(s7, "*motif*", motif = s7_inlet(s7, s7_nil(s7))); old_shadow = s7_shadow_rootlet(s7); s7_set_shadow_rootlet(s7, motif); Init_libxm(); s7_set_shadow_rootlet(s7, old_shadow); } #else Init_libxm(); #endif #if HAVE_FORTH fth_add_loaded_files("libxm.so"); #endif #endif #if USE_GTK #if HAVE_SCHEME { s7_pointer gtk, old_shadow; s7_define_constant(s7, "*gtk*", gtk = s7_inlet(s7, s7_nil(s7))); old_shadow = s7_shadow_rootlet(s7); s7_set_shadow_rootlet(s7, gtk); Init_libxg(); s7_set_shadow_rootlet(s7, old_shadow); } #else Init_libxg(); #endif #if HAVE_FORTH fth_add_loaded_files("libxg.so"); #endif #endif #if HAVE_GL #if HAVE_SCHEME { s7_pointer gl, old_shadow; s7_define_constant(s7, "*gl*", gl = s7_inlet(s7, s7_nil(s7))); old_shadow = s7_shadow_rootlet(s7); s7_set_shadow_rootlet(s7, gl); Init_libgl(); s7_set_shadow_rootlet(s7, old_shadow); } #else Init_libgl(); #endif #endif #if HAVE_ALSA Xen_provide_feature("alsa"); #endif #if HAVE_OSS Xen_provide_feature("oss"); #endif #if MUS_PULSEAUDIO Xen_provide_feature("pulse-audio"); #endif #if MUS_JACK Xen_provide_feature("jack"); #endif #if HAVE_GSL Xen_provide_feature("gsl"); #endif #if USE_MOTIF Xen_provide_feature("snd-motif"); #endif #if USE_GTK Xen_provide_feature("snd-gtk"); #if GTK_CHECK_VERSION(3, 0, 0) Xen_provide_feature("gtk3"); #else Xen_provide_feature("gtk2"); #endif #endif #if USE_NO_GUI Xen_provide_feature("snd-nogui"); #endif #if HAVE_FORTH Xen_provide_feature("snd-forth"); #endif #if HAVE_SCHEME Xen_provide_feature("snd-s7"); #endif #if WITH_AUDIO Xen_provide_feature("audio"); #endif #if HAVE_RUBY Xen_provide_feature("snd-ruby"); /* we need to set up the search path so that load and require will work as in the program irb */ { Xen paths; int i, len; paths = rb_gv_get("$:"); /* this is printed as * ["/home/bil/ruby-snd", "/usr/local/share/snd", "/usr/local/lib/ruby/site_ruby/2.0.0", ...] */ len = Xen_vector_length(paths); for (i = 0; i < len; i++) Xen_add_to_load_path(Xen_string_to_C_string(Xen_vector_ref(paths, i))); } #endif Xen_provide_feature("snd"); Xen_provide_feature("snd" SND_MAJOR_VERSION); Xen_provide_feature("snd-" SND_MAJOR_VERSION "." SND_MINOR_VERSION); #if HAVE_RUBY rb_gc_enable(); #endif } snd-16.1/numerics.scm0000644000076400007640000006366212615151310012674 0ustar bilbil(provide 'snd-numerics.scm) (when (provided? 'pure-s7) (define (make-polar mag ang) (if (and (real? mag) (real? ang)) (complex (* mag (cos ang)) (* mag (sin ang))) (error 'wrong-type-arg "make-polar args should be real")))) ;;; random stuff I needed at one time or another while goofing around... ;;; there are a lot more in snd-test.scm (define factorial (let* ((num-factorials 128) (factorials (let ((temp (make-vector num-factorials 0))) (set! (temp 0) 1) ; is this correct? (set! (temp 1) 1) temp))) (lambda (n) (if (> n num-factorials) (let ((old-num num-factorials) (old-facts factorials)) (set! num-factorials n) (set! factorials (make-vector num-factorials 0)) (do ((i 0 (+ i 1))) ((= i old-num)) (set! (factorials i) (old-facts i))))) (if (zero? (factorials n)) (set! (factorials n) (* n (factorial (- n 1))))) (factorials n)))) #| ;;; maxima uses this: ;; From Richard Fateman's paper, "Comments on Factorial Programs", ;; http://www.cs.berkeley.edu/~fateman/papers/factorial.pdf ;; ;; k(n,m) = n*(n-m)*(n-2*m)*... ;; ;; (k n 1) is n! ;; ;; This is much faster (3-4 times) than the original factorial ;; function. (define (factorial n) (define (k n m) (if (<= n m) n (* (k n (* 2 m)) (k (- n m) (* 2 m))))) (if (zero? n) 1 (k n 1))) |# (define (binomial-direct n m) (/ (factorial n) (* (factorial m) (factorial (- n m))))) (define n-choose-k (let ((documentation "(n-choose-k n k) computes the binomial coefficient C(N,K)")) (lambda (n k) (let ((mn (min k (- n k)))) (if (< mn 0) 0 (if (= mn 0) 1 (let* ((mx (max k (- n k))) (cnk (+ 1 mx))) (do ((i 2 (+ i 1))) ((> i mn) cnk) (set! cnk (/ (* cnk (+ mx i)) i)))))))))) ;;; -------------------------------------------------------------------------------- ;;; from Numerical Recipes (define (plgndr l m x) ;Legendre polynomial P m/l (x), m and l integer ;0 <= m <= l and -1<= x <= 1 (x real) (if (or (< m 0) (> m l) (> (abs x) 1.0)) (snd-error "invalid arguments to plgndr") (let ((pmm 1.0) (fact 0.0) (somx2 0.0)) (if (> m 0) (begin (set! somx2 (sqrt (* (- 1.0 x) (+ 1.0 x)))) (set! fact 1.0) (do ((i 1 (+ i 1))) ((> i m)) (set! pmm (* (- pmm) fact somx2)) (set! fact (+ fact 2.0))))) (if (= l m) pmm (let ((pmmp1 (* x pmm (+ (* 2 m) 1)))) (if (= l (+ m 1)) pmmp1 (let ((pk 0.0)) ; NR used "ll" which is unreadable (do ((k (+ m 2) (+ k 1))) ((> k l)) (set! pk (/ (- (* x (- (* 2 k) 1) pmmp1) (* (+ k m -1) pmm)) (- k m))) (set! pmm pmmp1) (set! pmmp1 pk)) pk))))))) ;;; A&S (bessel.lisp) (define (legendre-polynomial a x) ; sum of weighted polynomials (m=0) (let ((n (- (length a) 1))) (if (= n 0) (a 0) (let ((r x) (s 1.0) (h 0.0) (sum (a 0))) (do ((k 1 (+ k 1))) ((= k n)) (set! h r) (set! sum (+ sum (* r (a k)))) (set! r (/ (- (* r x (+ (* 2 k) 1)) (* s k)) (+ k 1))) (set! s h)) (+ sum (* r (a n))))))) (define (legendre n x) (legendre-polynomial (let ((v (make-vector (+ 1 n) 0.0))) (set! (v n) 1.0) v) x)) ;;; (with-sound (:scaled-to 0.5) (do ((i 0 (+ i 1)) (x 0.0 (+ x .1))) ((= i 10000)) (outa i (legendre 20 (cos x))))) #| ;; if l odd, there seems to be sign confusion: (with-sound (:channels 2 :scaled-to 1.0) (do ((i 0 (+ i 1)) (theta 0.0 (+ theta 0.01))) ((= i 10000)) (outa i (plgndr 1 1 (cos theta))) (let ((x (sin theta))) (outb i (- x))))) ;; this works: (with-sound (:channels 2 :scaled-to 1.0) (do ((i 0 (+ i 1)) (theta 0.0 (+ theta 0.01))) ((= i 10000)) (let ((x (cos theta))) (outa i (plgndr 3 0 x)) (outb i (* 0.5 x (- (* 5 x x) 3)))))) |# (define* (gegenbauer n x (alpha 0.0)) (if (< alpha -0.5) (set! alpha -0.5)) (if (= n 0) 1.0 (if (= alpha 0.0) ; maxima and A&S 22.3.14 (gsl has bogus values here) (* (/ 2.0 n) (cos (* n x))) (if (= n 1) ; gsl splits out special cases (* 2 alpha x) ; G&R 8.93(2) (if (= n 2) (- (* 2 alpha (+ alpha 1) x x) alpha) ; G&R 8.93(3) (let ((fn1 (* 2 x alpha)) (fn 0.0) (fn2 1.0)) (if (= n 1) fn1 (do ((k 2 (+ k 1)) (k0 2.0 (+ k0 1.0))) ((> k n) fn) (set! fn (/ (- (* 2 x fn1 (+ k alpha -1.0)) (* fn2 (+ k (* 2 alpha) -2.0))) k0)) (set! fn2 fn1) (set! fn1 fn))))))))) ;;; (with-sound (:scaled-to 0.5) (do ((i 0 (+ i 1)) (x 0.0 (+ x .1))) ((= i 10000)) (outa i (gegenbauer 15 (cos x) 1.0)))) #| (with-sound (:scaled-to 0.5) (do ((i 0 (+ i 1)) (theta 0.0 (+ theta 0.05))) ((= i 10000)) (let ((x (cos theta))) (outa i (gegenbauer 20 x))))) |# (define* (chebyshev-polynomial a x (kind 1)) (let ((n (- (length a) 1))) (if (= n 0) (a 0) (let ((r (* kind x)) (s 1.0) (h 0.0) (sum (a 0))) (do ((k 1 (+ k 1))) ((= k n)) (set! h r) (set! sum (+ sum (* r (a k)))) (set! r (- (* 2 r x) s)) (set! s h)) (+ sum (* r (a n))))))) (define* (chebyshev n x (kind 1)) (let ((a (make-vector (+ 1 n) 0.0))) (set! (a n) 1.0) (chebyshev-polynomial a x kind))) (define (hermite-polynomial a x) (let ((n (- (length a) 1))) (if (= n 0) (a 0) (let ((r (* 2 x)) (s 1.0) (h 0.0) (sum (a 0))) (do ((k 1 (+ k 1)) (k2 2 (+ k2 2))) ((= k n)) (set! h r) (set! sum (+ sum (* r (a k)))) (set! r (- (* 2 r x) (* k2 s))) (set! s h)) (+ sum (* r (a n))))))) (define* (hermite n x) (let ((a (make-vector (+ 1 n) 0.0))) (set! (a n) 1.0) (hermite-polynomial a x))) (define* (laguerre-polynomial a x (alpha 0.0)) (let ((n (- (length a) 1))) (if (= n 0) (a 0) (let ((r (- (+ alpha 1.0) x)) (s 1.0) (h 0.0) (sum (a 0))) (do ((k 1 (+ k 1))) ((= k n)) (set! h r) (set! sum (+ sum (* r (a k)))) (set! r (/ (- (* r (- (+ (* 2 k) 1 alpha) x)) (* s (+ k alpha))) (+ k 1))) (set! s h)) (+ sum (* r (a n))))))) (define* (laguerre n x (alpha 0.0)) (let ((a (make-vector (+ 1 n) 0.0))) (set! (a n) 1.0) (laguerre-polynomial a x alpha))) #| ;;; -------------------------------------------------------------------------------- ;;; ;;; just for my amusement -- apply a linear-fractional or Mobius transformation to the fft data (treated as complex) ;;; ;;; (automorph 1 0 0 1) is the identity ;;; (automorph 2 0 0 1) scales by 2 ;;; (automorph 0.0+1.0i 0 0 1) rotates 90 degrees (so 4 times = identity) ;;; most cases won't work right because we're assuming real output and so on (define* (automorph a b c d snd chn) (let* ((len (framples snd chn)) (pow2 (ceiling (log len 2))) (fftlen (floor (expt 2 pow2))) (fftlen2 (/ fftlen 2)) (fftscale (/ 1.0 fftlen)) (rl (channel->float-vector 0 fftlen snd chn)) (im (make-float-vector fftlen))) (fft rl im 1) (float-vector-scale! rl fftscale) (float-vector-scale! im fftscale) ;; handle 0 case by itself (let* ((c1 (complex (rl 0) (im 0))) (val (/ (+ (* a c1) b) (+ (* c c1) d))) (rval (real-part val)) (ival (imag-part val))) (set! (rl 0) rval) (set! (im 0) ival)) (do ((i 1 (+ i 1)) (k (- fftlen 1) (- k 1))) ((= i fftlen2)) (let* ((c1 (complex (rl i) (im i))) (val (/ (+ (* a c1) b) ; (az + b) / (cz + d) (+ (* c c1) d))) (rval (real-part val)) (ival (imag-part val))) (set! (rl i) rval) (set! (im i) ival) (set! (rl k) rval) (set! (im k) (- ival)))) (fft rl im -1) (float-vector->channel rl 0 len snd chn #f (format #f "automorph ~A ~A ~A ~A" a b c d)))) |# #| ;;; -------------------------------------------------------------------------------- ;;; these are in snd-xen.c?? (define (bes-i1 x) ;I1(x) (if (< (abs x) 3.75) (let ((y (expt (/ x 3.75) 2))) (* x (+ 0.5 (* y (+ 0.87890594 (* y (+ 0.51498869 (* y (+ 0.15084934 (* y (+ 0.2658733e-1 (* y (+ 0.301532e-2 (* y 0.32411e-3)))))))))))))) (let* ((ax (abs x)) (y (/ 3.75 ax)) (ans1 (+ 0.2282967e-1 (* y (+ -0.2895312e-1 (* y (+ 0.1787654e-1 (* y -0.420059e-2))))))) (ans2 (+ 0.39894228 (* y (+ -0.3988024e-1 (* y (+ -0.362018e-2 (* y (+ 0.163801e-2 (* y (+ -0.1031555e-1 (* y ans1))))))))))) (sign (if (< x 0.0) -1.0 1.0))) (* (/ (exp ax) (sqrt ax)) ans2 sign)))) (define (bes-in n x) ;return In(x) for any integer n, real x (if (= n 0) (bes-i0 x) (if (= n 1) (bes-i1 x) (if (= x 0.0) 0.0 (let* ((iacc 40) (bigno 1.0e10) (bigni 1.0e-10) (ans 0.0) (tox (/ 2.0 (abs x))) (bip 0.0) (bi 1.0) (m (* 2 (+ n (truncate (sqrt (* iacc n)))))) (bim 0.0)) (do ((j m (- j 1))) ((= j 0)) (set! bim (+ bip (* j tox bi))) (set! bip bi) (set! bi bim) (if (> (abs bi) bigno) (begin (set! ans (* ans bigni)) (set! bi (* bi bigni)) (set! bip (* bip bigni)))) (if (= j n) (set! ans bip))) (if (and (< x 0.0) (odd? n)) (set! ans (- ans))) (* ans (/ (bes-i0 x) bi))))))) |# ;;; -------------------------------------------------------------------------------- (define (aux-f x) ;1<=x= x 1.0) (- (/ pi 2) (* (cos x) (aux-f x)) (* (sin x) (aux-g x))) (let ((sum x) (fact 2.0) (one -1.0) (xs x) (x2 (* x x)) (err .000001) (unhappy #t)) (do ((i 3.0 (+ i 2.0))) ((not unhappy)) (set! xs (/ (* one x2 xs) (* i fact))) (set! one (- one)) (set! fact (+ 1 fact)) (set! xs (/ xs fact)) (set! unhappy (> (abs xs) err)) (set! sum (+ sum xs))) sum))) (define (Ci x) (if (>= x 1.0) (- (* (sin x) (aux-f x)) (* (cos x) (aux-g x))) (let ((g .5772156649) (sum 0.0) (fact 1.0) (one -1.0) (xs 1.0) (x2 (* x x)) (err .000001) (unhappy #t)) (do ((i 2.0 (+ i 2.0))) ((not unhappy)) (set! xs (/ (* one x2 xs) (* i fact))) (set! one (- one)) (set! fact (+ 1 fact)) (set! xs (/ xs fact)) (set! unhappy (> (abs xs) err)) (set! sum (+ sum xs))) (+ g (log x) sum)))) ;;; -------------------------------------------------------------------------------- (define bernoulli3 (let ((saved-values (let ((v (make-vector 100 #f)) (vals (vector 1 -1/2 1/6 0 -1/30 0 1/42 0 -1/30 0 5/66 0 -691/2730 0 7/6 0 -3617/510 0 43867/798 0 -174611/330 0 854513/138 0 -236364091/2730 0 8553103/6 0 -23749461029/870 0 8615841276005/14322 0))) (do ((i 0 (+ i 1))) ((= i 30)) (set! (v i) (vals i))) v))) (lambda (n) (if (number? (saved-values n)) (saved-values n) (let ((value (if (odd? n) 0.0 (let ((sum2 0.0) (itmax 1000) (tol 5.0e-7) (close-enough #f)) (do ((i 1 (+ i 1))) ((or close-enough (> i itmax))) (let ((term (/ 1.0 (expt i n)))) (set! sum2 (+ sum2 term)) (set! close-enough (or (< (abs term) tol) (< (abs term) (* tol (abs sum2))))))) (/ (* 2.0 sum2 (factorial n) (if (= (modulo n 4) 0) -1 1)) (expt (* 2.0 pi) n)))))) (set! (saved-values n) value)))))) (define (bernoulli-poly n x) (let ((fact 1.0) (value (bernoulli3 0))) (do ((i 1 (+ i 1))) ((> i n) value) (set! fact (* fact (/ (- (+ n 1) i) i))) (set! value (+ (* value x) (* fact (bernoulli3 i))))))) #| (with-sound (:clipped #f :channels 2) (let ((x 0.0) (incr (hz->radians 100.0)) (N 2)) (do ((i 0 (+ i 1))) ((= i 44100)) (outa i (* (expt -1 (- N 1)) (/ 0.5 (factorial N)) (expt (* 2 pi) (+ (* 2 N) 1)) (bernoulli-poly (+ (* 2 N) 1) (/ x (* 2 pi))))) (outb i (* (expt -1 (- N 1)) (/ 0.5 (factorial N)) (expt (* 2 pi) (+ (* 2 N) 1)) (bernoulli-poly (+ (* 2 N) 0) (/ x (* 2 pi))))) (set! x (+ x incr)) (if (> x (* 2 pi)) (set! x (- x (* 2 pi))))))) |# ;;; -------------------------------------------------------------------------------- (define (sin-m*pi/n m1 n1) ;; this returns an expression giving the exact value of sin(m*pi/n), m and n integer ;; if we can handle n -- currently it can be anything of the form 2^a 3^b 5^c 7^d 11^h 13^e 17^f 257^g ;; so (sin-m*pi/n 1 60) returns an exact expression for sin(pi/60). (let ((m (numerator (/ m1 n1))) (n (denominator (/ m1 n1)))) (set! m (modulo m (* 2 n))) ;; now it's in lowest terms without extra factors of 2*pi (cond ((zero? m) 0) ((zero? n) (error "divide by zero (sin-m*pi/n n = 0)")) ((= n 1) 0) ((negative? n) (let ((val (sin-m*pi/n m (- n)))) (and val `(- ,val)))) ((> m n) (let ((val (sin-m*pi/n (- m n) n))) (and val `(- ,val)))) ((= n 2) (if (= m 0) 0 1)) ((= n 3) `(sqrt 3/4)) ((> m 1) (let ((m1 (sin-m*pi/n (- m 1) n)) (n1 (sin-m*pi/n 1 n)) (m2 (sin-m*pi/n (- m 2) n))) (and m1 m2 n1 `(- (* 2 ,m1 (sqrt (- 1 (* ,n1 ,n1)))) ,m2)))) ((= n 5) `(/ (sqrt (- 10 (* 2 (sqrt 5)))) 4)) ((= n 7) `(let ((A1 (expt (+ -7/3456 (sqrt -49/442368)) 1/3)) (A2 (expt (- -7/3456 (sqrt -49/442368)) 1/3))) (sqrt (+ 7/12 (* -1/2 (+ A1 A2)) (* 1/2 0+i (sqrt 3) (- A1 A2)))))) ((= n 17) `(let* ((A1 (sqrt (- 17 (sqrt 17)))) (A2 (sqrt (+ 17 (sqrt 17)))) (A3 (sqrt (+ 34 (* 6 (sqrt 17)) (* (sqrt 2) (- (sqrt 17) 1) A1) (* -8 (sqrt 2) A2))))) (* 1/8 (sqrt 2) (sqrt (- 17 (sqrt 17) (* (sqrt 2) (+ A1 A3))))))) ((= n 11) `(let* ((SQRT5 (* 1/2 (- (sqrt 5) 1))) (B5 (sqrt (+ 2 (* 1/2 (+ (sqrt 5) 1))))) (B6 (+ SQRT5 (* 0+i B5))) (B6_2 (* B6 B6)) (B6_3 (* B6 B6 B6)) (B6_4 (* B6 B6 B6 B6)) (D1 (+ 6 (* 3/2 B6) (* 3/4 B6_2))) (D2 (+ SQRT5 (* 0+i B5) (* 1/4 B6_2))) (D3 (* 1/2 (- (+ 1 (* 0+i (sqrt 11)))))) (D4 (* 1/2 (- (* 0+i (sqrt 11)) 1))) (D6 (+ 1 (* 1/4 B6_2) (* 1/8 B6_3))) (D7 (+ (* 1/2 B6) (* 1/16 B6_4))) (D8 (+ 2 (* 1/2 B6))) (D9 (+ 13 (* 21 B6) (* 67/4 B6_2) (* 21/4 B6_3) (* 2 B6_4))) (D11 (+ 129 (* 109/2 B6) (* 59/4 B6_2) (* 9/8 B6_3) (* 9/16 B6_4))) (D13 (+ (* 3 B6) B6_2)) (D14 (+ (* 3 B6) (* 3/4 B6_2) (* 3/8 B6_3))) (D15 (+ 79 (* 27 B6) (* 39/4 B6_2) (* 37/4 B6_3) (* 21/4 B6_4))) (D16 (+ D11 (* D3 D9) (* D4 D15))) (D17 (+ D11 (* D4 D9) (* D3 D15))) (D30 (/ (* B6_2 (+ (* D3 D6) (* D4 D7))) (* 4 (expt D17 1/5)))) (D32 (* 1/2 (+ 1 (* 0+i (sqrt 11))))) (D33 (/ (* B6_3 (+ (* D4 D6) (* D3 D7))) (* 8 (expt D16 1/5)))) (D34 (* 1/4 B6_2 (expt D16 1/5))) (D35 (+ 2 (* 1/8 B6_4) (* 1/2 B6 D8) (* 1/8 B6_3 D2))) (D36 (+ SQRT5 (* 0+i B5) (* 1/2 B6_2) (* 1/4 B6_3) (* 1/2 B6 D2) (* 1/4 B6_2 (+ (* 1/4 B6_3) (* 1/16 B6_4))))) (D38 (* 1/2 (+ -1 (* 0+i (sqrt 11))))) (D39 (* 1/8 B6_3 (expt D17 1/5))) (D40 (+ 3 (* 3/2 B6) (* 9/4 B6_2) (* 7/8 B6_3) (* 3/16 B6_4) (* 1/2 B6 (+ 6 (* 2 B6))) (* 1/16 B6_4 D1) (* 1/4 B6_2 D13) (* 1/8 B6_3 (+ 3 (* 3/4 B6_3) (* 3/16 B6_4))))) (D41 (+ (* 1/4 B6_2 D1) (* 1/8 B6_3 D13) (* 1/16 B6_4 D14) (* 1/2 B6 (+ 4 (* 3/8 B6_4))))) (D42 (+ 3 (* 3/4 B6_3) (* 3/16 B6_4) (* 1/8 B6_3 D1) (* 1/4 B6_2 D14) (* 1/2 B6 (+ (* 3/2 B6_2) (* 3/8 B6_3) (* 3/16 B6_4))) (* 1/16 B6_4 (+ 3 (* 3/2 B6) (* 3/8 B6_4))))) (D43 (+ (* 1/4 B6_3) (* 1/16 B6_4) (* 1/8 B6_3 D8) (* 1/4 B6_2 D2) (* 1/2 B6 (+ (* 1/2 B6_2) (* 1/8 B6_3))) (* 1/16 B6_4 (+ 1 (* 1/8 B6_4))))) (D44 (/ (* B6_4 (+ D42 (* D4 D40) (* D3 D41))) (* 16 (expt D16 3/5)))) (D45 (/ (* B6 (+ D42 (* D3 D40) (* D4 D41))) (* 2 (expt D17 3/5)))) (D48 (/ (* B6 (+ D43 (* D3 D35) (* D4 D36))) (* 2 (expt D16 2/5)))) (D49 (/ (* B6_4 (+ D43 (* D4 D35) (* D3 D36))) (* 16 (expt D17 2/5))))) (* -1/2 0+i (+ (* 1/5 (- D32 D33 D34 D48 D44)) (* 1/5 (+ D38 D30 D39 D49 D45)))))) ((= n 13) `(let* ((A1 (/ (- -1 (sqrt 13)) 2)) (A2 (/ (+ -1 (sqrt 13)) 2)) (A3 (/ (+ -1 (* 0+i (sqrt 3))) 2)) (A4 (+ -1 (* 0+i (sqrt 3)))) (A5 (* 0+i (sqrt (+ 7 (sqrt 13) A2)))) (A6 (* 0+i (sqrt (+ 7 (- (sqrt 13)) A1)))) (A8 (* 1/2 (- A2 A6))) (A9 (* 1/2 (+ A1 A5))) (A11 (* 1/2 (+ A2 A6))) (A12 (* 1/2 (- A1 A5))) (A13 (* 3/2 A4 A8)) (A14 (* 3/2 A4 A11)) (A15 (* 3/4 A4 A4 A11)) (A16 (* 3/4 A4 A4 A8)) (A17 (+ A3 (* 1/4 A4 A4)))) (* -1/6 0+i (+ (- A9 A12) (* A4 (+ (/ (+ A8 (* A17 A12)) (* 2 (expt (+ 6 A13 A15 A9) 1/3))) (/ (+ A11 (* A17 A9)) (* -2 (expt (+ 6 A16 A14 A12) 1/3))) (* 1/4 A4 (- (expt (+ 6 A13 A15 A9) 1/3) (expt (+ 6 A16 A14 A12) 1/3))))))))) ((= n 257) `(let* ((A1 (sqrt (- 514 (* 2 (sqrt 257))))) (A2 (- 257 (* 15 (sqrt 257)))) (A3 (+ 257 (* 15 (sqrt 257)))) (A4 (- 257 (sqrt 257))) (A5 (+ (sqrt 257) 257)) (A7 (+ 257 (* 9 (sqrt 257)))) (A8 (- 514 (* 18 (sqrt 257)))) (AA (sqrt (* 2 A5))) (A9 (sqrt (+ A2 (* 8 A1) (* -7 AA)))) (A10 (sqrt (+ A2 (* -8 A1) (* 7 AA)))) (A11 (sqrt (+ A3 (* 7 A1) (* 8 AA)))) (A12 (sqrt (+ A3 (* -7 A1) (* -8 AA)))) (A13 (sqrt (+ A8 (* 6 A1) (* 8 A9) (* -24 A10) (* 12 A11)))) (A14 (* 4 (sqrt (+ A8 (* 6 A1) (* -8 A9) (* 24 A10) (* -12 A11))))) (A15 (* 4 (sqrt (+ A8 (* -6 A1) (* -12 A12) (* 24 A9) (* 8 A10))))) (A16 (* 4 (sqrt (* 2 (+ (- 257 (* 9 (sqrt 257))) (* -3 A1) (* 6 A12) (* -12 A9) (* -4 A10)))))) (A17 (sqrt (* 2 (+ A7 (* -3 AA) (* -4 A12) (* 6 A9) (* 12 A11))))) (A18 (sqrt (* 2 (+ A7 (* 3 AA) (* 12 A12) (* -6 A10) (* 4 A11))))) (A19 (* 4 (sqrt (* 2 (+ A7 (* 3 AA) (* -12 A12) (* 6 A10) (* -4 A11)))))) (A20 (* 4 (sqrt (* 2 (+ A7 (* -3 AA) (* 4 A12) (* -6 A9) (* -12 A11)))))) (A22 (+ A4 (* 3 A1) (* -4 AA) (* -4 A12) (* 4 A9) (* -4 A10) (* 2 A11))) (A23 (+ A5 (* -4 A1) (* -3 AA) (* -4 A12) (* 2 A9) (* 4 A10) (* 4 A11))) (A24 (+ A5 (* 4 A1) (* 3 AA) (* 4 A12) (* 4 A9) (* -2 A10) (* 4 A11))) (A26 (sqrt (+ A22 (+ (- A16) (- A19) (* 4 A17) (* -6 A13))))) (A27 (sqrt (+ A22 (+ A16 A19 (* -4 A17) (* 6 A13))))) (A28 (+ 257 (* 7 (sqrt 257)) (* 3 A1) (* -4 A9) (* 4 A10) (* 6 A11))) (A29 (* 8 (sqrt (+ A24 A15 (- A20) (* -6 A18) (* -4 A13))))) (A30 (+ A28 (* -4 A18) (* -4 A17) (* -2 A13))) (A31 (+ (* 8 (sqrt (+ A23 A15 A14 (* 4 A18) (* -6 A17)))) (* 4 A26) A29 (* -8 A27)))) (* 1/16 (sqrt (* 1/2 (+ A4 (- A1) (* -2 A11) (* -2 A13) (* -4 A26) (* -4 (sqrt (* 2 (+ A30 (- A31))))) (* -8 (sqrt (+ A4 (- A1) (* -2 A11) (* 6 A13) (* -4 A26) (* -8 A27) (* 4 (sqrt (* 2 (+ A30 A31)))) (* -8 (sqrt (* 2 (+ A28 (* 4 A18) (* 4 A17) (* 2 A13) (* -8 A26) (* -4 A27) (* -8 (sqrt (+ A23 (- A15) (- A14) (* -4 A18) (* 6 A17)))) (* -8 (sqrt (+ A24 (- A15) A20 (* 6 A18) (* 4 A13))))))))))))))))) ((or (= (modulo n 2) 0) (= (modulo n 3) 0) (= (modulo n 5) 0) (= (modulo n 7) 0) (= (modulo n 17) 0) (= (modulo n 13) 0) (= (modulo n 257) 0) (= (modulo n 11) 0)) (let ((divisor (if (= (modulo n 2) 0) 2 (if (= (modulo n 3) 0) 3 (if (= (modulo n 5) 0) 5 (if (= (modulo n 7) 0) 7 (if (= (modulo n 17) 0) 17 (if (= (modulo n 13) 0) 13 (if (= (modulo n 11) 0) 11 257))))))))) (let ((val (sin-m*pi/n 1 (/ n divisor)))) (and val `(let ((ex ,val)) (/ (- (expt (+ (sqrt (- 1 (* ex ex))) (* 0+i ex)) (/ 1 ,divisor)) (expt (- (sqrt (- 1 (* ex ex))) (* 0+i ex)) (/ 1 ,divisor))) 0+2i)))))) (else #f)))) #| (let ((maxerr 0.0) (max-case #f) (cases 0)) (do ((n 1 (+ n 1))) ((= n 10000)) (do ((m 1 (+ m 1))) ((= m 4)) (let ((val (sin (/ (* m pi) n))) (expr (sin-m*pi/n m n))) (if expr (let ((err (magnitude (- val (eval expr))))) (set! cases (+ cases 1)) (if (> err maxerr) (begin (set! maxerr err) (set! max-case (/ m n))))))))) (format #t "sin-m*pi/n (~A cases) max err ~A at ~A~%" cases maxerr max-case)) :(sin (/ pi (* 257 17))) 0.00071906440440859 :(eval (sin-m*pi/n 1 (* 17 257))) 0.00071906440440875 |# ;;; -------------------------------------------------------------------------------- (define (show-digits-of-pi-starting-at-digit id) ;; piqpr8.c ;; ;; This program implements the BBP algorithm to generate a few hexadecimal ;; digits beginning immediately after a given position id, or in other words ;; beginning at position id + 1. On most systems using IEEE 64-bit floating- ;; point arithmetic, this code works correctly so long as d is less than ;; approximately 1.18 x 10^7. If 80-bit arithmetic can be employed, this limit ;; is significantly higher. Whatever arithmetic is used, results for a given ;; position id can be checked by repeating with id-1 or id+1, and verifying ;; that the hex digits perfectly overlap with an offset of one, except possibly ;; for a few trailing digits. The resulting fractions are typically accurate ;; to at least 11 decimal digits, and to at least 9 hex digits. ;; ;; David H. Bailey 2006-09-08 ;; ;; translated to Scheme 29-Dec-08 (define (ihex x nhx chx) ;; This returns, in chx, the first nhx hex digits of the fraction of x. (let ((y (abs x)) (hx "0123456789ABCDEF")) (do ((i 0 (+ i 1))) ((= i nhx)) (set! y (* 16.0 (- y (floor y)))) (set! (chx i) (hx (floor y)))) chx)) (define expm (let* ((ntp 25) (tp1 0) (tp (make-vector ntp))) (lambda (p ak) ;; expm = 16^p mod ak. This routine uses the left-to-right binary exponentiation scheme. ;; If this is the first call to expm, fill the power of two table tp. (if (= tp1 0) (begin (set! tp1 1) (set! (tp 0) 1.0) (do ((i 1 (+ i 1))) ((= i ntp)) (set! (tp i) (* 2.0 (tp (- i 1))))))) (if (= ak 1.0) 0.0 (let ((pl -1)) ;; Find the greatest power of two less than or equal to p. (do ((i 0 (+ i 1))) ((or (not (= pl -1)) (= i ntp))) (if (> (tp i) p) (set! pl i))) (if (= pl -1) (set! pl ntp)) (let ((pt (tp (- pl 1))) (p1 p) (r 1.0)) ;; Perform binary exponentiation algorithm modulo ak. (do ((j 1 (+ j 1))) ((> j pl) r) (if (>= p1 pt) (begin (set! r (* 16.0 r)) (set! r (- r (* ak (floor (/ r ak))))) (set! p1 (- p1 pt)))) (set! pt (* 0.5 pt)) (if (>= pt 1.0) (begin (set! r (* r r)) (set! r (- r (* ak (floor (/ r ak)))))))))))))) (define (series m id) ;; This routine evaluates the series sum_k 16^(id-k)/(8*k+m) using the modular exponentiation technique. (let ((eps 1e-17) (s 0.0)) (do ((k 0 (+ k 1))) ((= k id)) (let* ((ak (+ (* 8 k) m)) (p (- id k)) (t (expm p ak))) (set! s (+ s (/ t ak))) (set! s (- s (floor s))))) ;; Compute a few terms where k >= id. (let ((happy #f)) (do ((k id (+ k 1))) ((or (> k (+ id 100)) happy) s) (let* ((ak (+ (* 8 k) m)) (t (/ (expt 16.0 (- id k)) ak))) (set! happy (< t eps)) (set! s (+ s t)) (set! s (- s (floor s)))))))) ;; id is the digit position. Digits generated follow immediately after id. (let* ((chx (make-string 17)) (s1 (series 1 id)) (s2 (series 4 id)) (s3 (series 5 id)) (s4 (series 6 id)) (pid (+ (* 4.0 s1) (* -2.0 s2) (- s3) (- s4)))) (set! pid (+ 1.0 (- pid (floor pid)))) (ihex pid 10 chx) (format #t " position = ~D~% fraction = ~,15F~% hex digits = ~S~%" id pid chx))) #| ;;; from the CL bboard, perhaps written by Justin Grant ;;; requires gmp (bignums) (define (machin-pi digits) (define (arccot-minus xsq n xpower) (let ((term (floor (/ xpower n)))) (if (= term 0) 0 (- (arccot-plus xsq (+ n 2) (floor (/ xpower xsq))) term)))) (define (arccot-plus xsq n xpower) (let ((term (floor (/ xpower n)))) (if (= term 0) 0 (+ (arccot-minus xsq (+ n 2) (floor (/ xpower xsq))) term)))) (define (arccot x unity) (let ((xpower (floor (/ unity x)))) (arccot-plus (* x x) 1 xpower))) (let* ((unity (expt 10 (+ digits 10))) (thispi (* 4 (- (* 4 (arccot 5 unity)) (arccot 239 unity))))) (floor (/ thispi (expt 10 10))))) |# ;;; -------------------------------------------------------------------------------- (define* (sin-nx-peak n (err 1e-12)) ;; return the min peak amp and its location for sin(x)+sin(nx+a) (let* ((size (* n 100)) (incr (/ (* 2 pi) size)) (peak 0.0) (location 0.0) (offset (if (= (modulo n 4) 3) 0 pi))) (do ((i 0 (+ i 1)) (x 0.0 (+ x incr))) ((= i size)) (let ((val (abs (+ (sin x) (sin (+ offset (* n x))))))) (if (> val peak) (begin (set! peak val) (set! location x))))) ;; now narrow it by zigzagging around the peak (let ((x location)) (do ((zig-size (* incr 2) (/ zig-size 2))) ((< zig-size err)) (let ((cur (abs (+ (sin x) (sin (+ offset (* n x)))))) (left (abs (+ (sin (- x zig-size)) (sin (+ (* n (- x zig-size)) offset)))))) (if (< left cur) (let ((right (abs (+ (sin (+ x zig-size)) (sin (+ (* n (+ x zig-size)) offset)))))) (if (> right cur) (set! x (+ x zig-size)))) (set! x (- x zig-size))))) (list (abs (+ (sin x) (sin (+ (* n x) offset)))) x)))) ;;; -------------------------------------------------------------------------------- (define (exptmod a b n) ; from the net somewhere: (modulo (expt a b) n) (cond ((zero? b) 1) ((even? b) (exptmod (modulo (* a a) n) (quotient b 2) n)) (else (modulo (* a (exptmod (modulo (* a a) n) (quotient b 2) n)) n)))) snd-16.1/stuff.scm0000644000076400007640000020744112625163702012202 0ustar bilbil;; some useful (or at least amusing) functions and macros (provide 'stuff.scm) (when (provided? 'pure-s7) (define (let->list e) (reverse! (map values e))) (define (memq a b) (member a b eq?)) (define (assq a b) (assoc a b eq?))) ;;; ---------------- (define empty? (let ((documentation "(empty? obj) returns #t if obj is an empty sequence")) (lambda (obj) (if (hash-table? obj) (zero? (hash-table-entries obj)) ; length here is table size (eqv? (length obj) 0))))) (define applicable? arity) ;(define sequence? length) -- now built-in for procedure-signatures (define indexable? (let ((documentation "(indexable? obj) returns #t if obj can be applied to an index: (obj 0)")) (lambda (obj) (and (sequence? obj) (applicable? obj))))) (define (ow!) (call-with-output-string (lambda (p) (do ((e (outlet (owlet)) (outlet e))) ((eq? e (rootlet))) (format p "~{~A ~}~%" e))))) #| (set! (hook-functions *error-hook*) (list (lambda (hook) (apply format *stderr* (hook 'data)) (newline *stderr*) (when ((owlet) 'error-line) (format *stderr* "~S line ~A~%" ((owlet) 'error-file) ((owlet) 'error-line))) (do ((e (outlet (owlet)) (outlet e))) ((eq? e (rootlet))) (format *stderr* "~{ ~A~%~}~%" e)) (format *stderr* "~%~A~%" (stacktrace))))) |# ;;; ---------------- (define (first obj) (if (sequence? obj) (obj 0) (error "first argument, ~S, is not a sequence" obj))) (define (second obj) (if (sequence? obj) (obj 1) (error "second argument, ~S, is not a sequence" obj))) (define (third obj) (if (sequence? obj) (obj 2) (error "third argument, ~S, is not a sequence" obj))) (define (fourth obj) (if (sequence? obj) (obj 3) (error "fourth argument, ~S, is not a sequence" obj))) (define (fifth obj) (if (sequence? obj) (obj 4) (error "fifth argument, ~S, is not a sequence" obj))) (define (sixth obj) (if (sequence? obj) (obj 5) (error "sixth argument, ~S, is not a sequence" obj))) (define (seventh obj)(if (sequence? obj) (obj 6) (error "seventh argument, ~S, is not a sequence" obj))) (define (eighth obj) (if (sequence? obj) (obj 7) (error "eighthment, ~S, is not a sequence" obj))) (define (ninth obj) (if (sequence? obj) (obj 8) (error "ninth argument, ~S, is not a sequence" obj))) (define (tenth obj) (if (sequence? obj) (obj 9) (error "tenth argument, ~S, is not a sequence" obj))) (define iota (let ((documentation "(iota n (start 0) (incr 1)) returns a list counting from start for n:\n\ (iota 3) -> '(0 1 2)")) (lambda* (n (start 0) (incr 1)) (if (or (not (integer? n)) (< n 0)) (error 'wrong-type-arg "iota length ~A should be a non-negative integer" n)) (let ((lst (make-list n))) (do ((p lst (cdr p)) (i start (+ i incr))) ((null? p) lst) (set! (car p) i)))))) (define (cdr* lst n) (do ((i n (- i 1)) (result lst (cdr result))) ((or (null? result) (zero? i)) result))) (define make-circular-list (let ((documentation "(make-circular-list n init) returns a circular list with n entries initialized to init:\n\ (make-circular-list 3 #f) -> #1=(#f #f #f . #1#)")) (lambda* (n init) (let ((l (make-list n init))) (set-cdr! (list-tail l (- n 1)) l))))) (define circular-list (let ((documentation "(circular-list . objs) returns a circular list with objs:\n\ (circular-list 1 2) -> #1=(1 2 . #1#)")) (lambda objs (let ((lst (copy objs))) (set-cdr! (list-tail lst (- (length lst) 1)) lst))))) (define circular-list? (let ((documentation "(circular-list? obj) returns #t if obj is a circular list")) (lambda (obj) (catch #t (lambda () (infinite? (length obj))) (lambda args #f))))) (define linearize (let ((documentation " (linearize lst) turns a circular list into normal list:\n\ (linearize (circular-list 1 2)) -> '(1 2)")) (lambda (lst) (define (lin-1 lst result sofar) (if (or (not (pair? lst)) (memq lst sofar)) (reverse! result) (lin-1 (cdr lst) (cons (car lst) result) (cons lst sofar)))) (lin-1 lst () ())))) (define cyclic? (let ((documentation "(cyclic obj) returns #t if the sequence obj contains any cycles")) (lambda (obj) (pair? (cyclic-sequences obj))))) (define copy-tree (let ((documentation "(copy-tree lst) returns a full copy of lst")) (lambda (lis) (if (pair? lis) (cons (copy-tree (car lis)) (copy-tree (cdr lis))) lis)))) (define tree-member (let ((documentation "(tree-member sym tree) returns #t if sym is found anywhere in tree:\n\ (tree-member 'a '(1 (2 a))) -> #t")) (lambda (sym tree) (and (pair? tree) (or (eq? (car tree) sym) (and (pair? (car tree)) (tree-member sym (car tree))) (tree-member sym (cdr tree))))))) (define adjoin (let ((documentation "(adjoin obj lst) adds obj to lst if it is not already in lst, returning the new list")) (lambda (obj lst) (if (member obj lst) lst (cons obj lst))))) (define (cdr-assoc obj lst) (cond ((assoc obj lst) => cdr) (else #f))) ;;; ---------------- (define-macro (fully-macroexpand form) (define (expand form) (if (pair? form) (if (and (symbol? (car form)) (macro? (symbol->value (car form)))) (expand (apply macroexpand (list form))) (if (and (eq? (car form) 'set!) ; look for (set! (mac ...) ...) and use mac's procedure-setter (pair? (cdr form)) (pair? (cadr form)) (macro? (symbol->value (caadr form)))) (expand (apply (eval (procedure-source (procedure-setter (symbol->value (caadr form))))) (append (cdadr form) (cddr form)))) (cons (expand (car form)) (expand (cdr form))))) form)) (list 'quote (expand form))) (define-macro (define-with-macros name&args . body) `(apply define ',name&args (list (fully-macroexpand `(begin ,,@body))))) (define setf (let ((args (gensym)) (name (gensym))) (apply define-bacro `((,name . ,args) (unless (null? ,args) (apply set! (car ,args) (cadr ,args) ()) (apply setf (cddr ,args))))))) (define-macro* (incf sym (inc 1)) `(set! ,sym (+ ,sym ,inc))) ; or ({list} set! sym ({list} + sym inc)) ;; (define-bacro* (incf-1 sym (inc 1)) (apply set! sym (list + sym inc) ())) (define-macro* (decf sym (dec 1)) `(set! ,sym (- ,sym ,dec))) (define-macro (shiftf . places) (let ((tmp (gensym))) `(let ((,tmp ,(car places))) ,@(map (lambda (a b) `(set! ,a ,b)) places (cdr places)) ,tmp))) (define-macro (rotatef . places) (let ((tmp (gensym)) (last (car (list-tail places (- (length places) 1))))) `(let ((,tmp ,(car places))) ,@(map (lambda (a b) `(set! ,a ,b)) places (cdr places)) (set! ,last ,tmp)))) (define-macro (progv vars vals . body) `(apply (apply lambda ,vars ',body) ,vals)) (define-macro (symbol-set! var val) ; like CL's set `(apply set! ,var ',val ())) (define-macro (value->symbol expr) `(let ((val ,expr) (e1 (curlet))) (call-with-exit (lambda (return) (do ((e e1 (outlet e))) () (for-each (lambda (slot) (if (equal? val (cdr slot)) (return (car slot)))) e) (if (eq? e (rootlet)) (return #f))))))) (define-macro (enum . args) `(for-each define ',args (iota (length ',args)))) (define-macro (destructuring-bind lst expr . body) ; if only there were some use for this! `(let ,(letrec ((flatten (lambda (lst1 lst2 args) (cond ((null? lst1) args) ((not (pair? lst1)) (cons (list lst1 lst2) args)) (#t (flatten (car lst1) (car lst2) (flatten (cdr lst1) (cdr lst2) args))))))) (flatten lst (eval expr) ())) ,@body)) (define-macro (and-let* vars . body) `(let () ; bind vars, if any is #f stop, else evaluate body with those bindings (and ,@(map (lambda (var) `(begin (apply define ',var) ,(car var))) vars) (begin ,@body)))) (define-macro (while test . body) ; while loop with predefined break and continue `(call-with-exit (lambda (break) (letrec ((continue (lambda () (if (let () ,test) (begin (let () ,@body) (continue)) (break))))) (continue))))) (define-macro (do* spec end . body) `(let* (,@(map (lambda (var) (list (car var) (cadr var))) spec)) (do () ,end ,@body ,@(map (lambda (var) (if (pair? (cddr var)) `(set! ,(car var) ,(caddr var)) (values))) spec)))) (define-macro (string-case selector . clauses) `(case (symbol ,selector) ; case with string constant keys ,@(map (lambda (clause) (if (pair? (car clause)) `(,(map symbol (car clause)) ,@(cdr clause)) clause)) clauses))) (define-macro (eval-case key . clauses) ; case with evaluated key-lists (let ((select (gensym))) `(let ((,select ,key)) (cond ,@(map (lambda (lst) (if (pair? (car lst)) (cons `(member ,select (list ,@(car lst))) (cdr lst)) lst)) clauses))))) ;;; ---------------- (define hash-table->alist (let ((documentation "(hash-table->alist table) returns the contents of table as an association list:\n\ (hash-table->alist (hash-table '(a . 1))) -> '((a . 1))")) (lambda (table) (if (hash-table? table) (map values table) (error "hash-table->alist argument, ~A, is not a hash-table" table))))) (define merge-hash-tables (let ((documentation "(merge-hash-tables . tables) returns a new hash-table with the contents of all the tables")) (lambda tables (apply hash-table (apply append (map hash-table->alist tables)))))) ;;; ---------------- (define-macro (c?r path) (define (X-marks-the-spot accessor tree) (if (pair? tree) (or (X-marks-the-spot (cons 'car accessor) (car tree)) (X-marks-the-spot (cons 'cdr accessor) (cdr tree))) (and (eq? tree 'X) accessor))) (let ((body 'lst)) (for-each (lambda (f) (set! body (list f body))) (reverse (X-marks-the-spot () path))) `(dilambda (lambda (lst) ,body) (lambda (lst val) (set! ,body val))))) ;;; ---------------- (define find-if (let ((documentation "(find-if func sequence) applies func to each member of sequence.\n\ If func approves of one, find-if returns that member of the sequence")) (lambda (f sequence) (call-with-exit (lambda (return) (for-each (lambda (arg) (if (f arg) (return arg))) sequence) #f))))) (define member? (let ((documentation "(member? obj sequence) returns #t if obj is an element of sequence")) (lambda (obj sequence) (find-if (lambda (x) (equal? x obj)) sequence)))) (define index-if (let ((documentation "(index-if func sequence) applies func to each member of sequence.\n\ If func approves of one, index-if returns the index that gives that element's position.\n\ (index-if (lambda (x) (= x 32)) #(0 1 32 4)) -> 2\n\ (index-if (lambda (x) (= (cdr x) 32)) (hash-table '(a . 1) '(b . 32))) -> 'b")) (lambda (f sequence) (call-with-exit (lambda (return) (if (or (hash-table? sequence) (let? sequence)) (for-each (lambda (arg) (if (f arg) (return (car arg)))) sequence) (let ((position 0)) (for-each (lambda (arg) (if (f arg) (return position)) (set! position (+ position 1))) sequence))) #f))))) (define count-if (let ((documentation "(count-if func sequence) applies func to each member of sequence, returning the number of times func approves.")) (lambda (f sequence) (let ((count 0)) (for-each (lambda (arg) (if (f arg) (set! count (+ count 1)))) sequence) count)))) (define every? (let ((documentation "(every? func sequence) returns #t if func approves of every member of sequence")) (lambda (f sequence) (not (member #f sequence (lambda (a b) (not (f b)))))))) (define any? (let ((documentation "(any? func sequence) returns #t if func approves of any member of sequence")) (lambda (f sequence) (member #f sequence (lambda (a b) (f b)))))) (define collect-if (let ((documentation "(collect-if type func sequence) gathers the elements of sequence that satisfy func, and returns them via type:\n\ (collect-if list integer? #(1.4 2/3 1 1+i 2)) -> '(1 2)")) (lambda (type f sequence) (apply type (map (lambda (arg) (if (f arg) arg (values))) sequence))))) ;;; if type=list, this is slightly wasteful because list currently copies its args, so: ;;; ((if (eq? type list) values (values apply type)) ...) would work ;;; ;;; to return (f arg) rather than arg, (apply type (map f sequence)) (define remove-if (let ((documentation "(remove-if type f sequence) returns via type the elements of sequence that do not satisfy func:\n\ (remove-if list integer? #(1.4 2/3 1 1+i 2)) -> '(1.4 2/3 1+1i)")) (lambda (type f sequence) (collect-if type (lambda (obj) (not (f obj))) sequence)))) (define nonce (let ((documentation "(nonce type sequence) returns via type the elements of sequence that occur only once")) (lambda (type sequence) (collect-if type (lambda (obj) (= (count-if (lambda (x) (equal? x obj)) sequence) 1)) sequence)))) (define full-find-if (let ((documentation "(full-find-if func sequence) searches sequence, and recursively any sequences it contains, for an element that satisfies func")) (lambda (f sequence) (if (and (procedure? f) (aritable? f 1)) (if (sequence? sequence) (call-with-exit (lambda (return) (letrec ((full-find-if-1 (lambda (seq) (for-each (lambda (x) (if (f x) (return x) (if (sequence? x) (full-find-if-1 x)))) seq)))) (full-find-if-1 sequence)) #f)) (error "full-find-if second argument, ~A, is not a sequence" sequence)) (error "full-find-if first argument, ~A, is not a procedure of one argument" f))))) (define full-count-if (let ((documentation "(full-count-if func sequence) searches sequence, and recursively any sequences it contains, returning the number of elements that satisfy func")) (lambda (f sequence) (let ((count 0)) (full-find-if (lambda (x) (if (f x) (set! count (+ count 1))) #f) sequence) count)))) (define full-index-if (let ((documentation "(full-index-if func sequence) searches sequence, and recursively any sequences it contains, returning the indices of the first element that satisfies func:\n\ (full-index-if (lambda (x) (and (integer? x) (= x 3))) '(1 (2 3))) -> '(1 1)")) (lambda (f sequence) (call-with-exit (lambda (return) (letrec ((full-index-if-1 (lambda (f seq path) (if (or (hash-table? seq) (let? seq)) (for-each (lambda (arg) (if (f arg) (return (reverse (cons (car arg) path))) (if (indexable? (cdr arg)) (full-index-if-1 f (cdr arg) (cons (car arg) path))))) seq) (let ((position 0)) (for-each (lambda (arg) (if (f arg) (return (reverse (cons position path))) (if (indexable? arg) (full-index-if-1 f arg (cons position path)))) (set! position (+ position 1))) seq)))))) (full-index-if-1 f sequence ()) #f)))))) (define (make-complete-iterator obj) (make-iterator (let ((iters ()) (cycles (cyclic-sequences obj)) (seen-cycles ())) (define (iter-memq p q) (and (pair? q) (or (eq? p (iterator-sequence (car q))) (iter-memq p (cdr q))))) (define (make-careful-iterator p) (if (not (pair? p)) (make-iterator p) (let ((len (length p))) (if (infinite? len) ; circular list (make-iterator (let ((cur p) (iterator? #t)) (lambda () (if (memq cur seen-cycles) # (let ((result (car cur))) (if (memq cur cycles) (set! seen-cycles (cons cur seen-cycles))) (set! cur (cdr cur)) result))))) (if (positive? len) ; normal list (make-iterator p) (make-iterator ; dotted list (let ((cur p) (iterator? #t)) (lambda () (if (pair? cur) (let ((result (car cur))) (set! cur (cdr cur)) result) (let ((result cur)) (set! cur #) result)))))))))) (let ((iter (make-careful-iterator obj))) (let ((iterator? #t)) (define (iterloop) ; define returns the new value (let ((result (iter))) (if (length result) (if (or (memq result seen-cycles) ; we've dealt with it already, so skip it (eq? result (iterator-sequence iter)) (iter-memq result iters)) ; we're dealing with it the right now (iterloop) ; this means the outermost sequence is ignored if encountered during the traversal (begin (set! iters (cons iter iters)) (set! iter (make-careful-iterator result)) result)) (if (eq? result #) (if (null? iters) # (begin (set! seen-cycles (cons (iterator-sequence iter) seen-cycles)) (set! iter (car iters)) (set! iters (cdr iters)) (iterloop))) result))))))))) (define safe-find-if (let ((documentation "(safe-find-if func sequence) searches sequence, and recursively any sequences it contains, for an element that satisfies func.\ Unlike full-find-if, safe-find-if can handle any circularity in the sequences.")) (lambda (f sequence) (let ((iter (make-complete-iterator sequence))) (let loop ((x (iter))) (if (f x) x (if (and (eq? x #) (iterator-at-end? iter)) #f (loop (iter))))))))) (define (safe-count-if f sequence) ;; currently the complete-iterator above skips repetitions, including the outer sequence, ;; so this count will be off if there are repeated cycles? ;; Perhaps make an iterator that returns everything. (if (sequence? sequence) (if (procedure? f) (let ((count 0)) (safe-find-if (lambda (x) (if (f x) (set! count (+ count 1))) #f) sequence) count) (error "safe-count-if first argument, ~A, should be a function" f)) (error "safe-count-if second argument, ~A, should be a sequence" sequence))) ;;; ---------------- (define sequences->list (let ((documentation "(sequences->list . sequences) returns a list of elements of all the sequences:\n\ (sequences->list \"hi\" #(0 1) (hash-table '(a . 2))) -> '(#\\h #\\i 0 1 (a . 2))")) (lambda sequences (apply append (map (lambda (sequence) (map values sequence)) sequences))))) (define concatenate (let ((documentation "(concatenate type . sequences) concatenates sequences returning an object of type:\n\ (concatenate vector '(1 2) #(3 4)) -> #(1 2 3 4)")) (lambda (type . sequences) (apply type (apply sequences->list sequences))))) (define intersection (let ((documentation "(intersection type . sequences) returns via type the intersection of the sequences:\n\ (intersection vector '(1 2 3) #(2 3 4)) -> #(2 3)")) (lambda (type . sequences) (if (every? sequence? sequences) (apply type (let ((lst ())) (if (pair? sequences) (for-each (lambda (obj) (if (every? (lambda (seq) (find-if (lambda (x) (equal? x obj)) seq)) (cdr sequences)) (set! lst (cons obj lst)))) (car sequences))) (reverse lst))) (error "intersection arguments should be sequences: ~A" sequences))))) (define union (let ((documentation "(union type . sequences) returns via type the union of the sequences:\n\ (union vector '(1 2 3) #(2 3 4)) -> #(1 2 3 4)")) (lambda (type . sequences) (apply type (let ((lst ())) (for-each (lambda (obj) (if (not (member obj lst)) (set! lst (cons obj lst)))) (apply sequences->list sequences)) (reverse lst)))))) (define asymmetric-difference (let ((documentation "(asymmetric-difference type . sequences) returns the elements in the rest of the sequences that are not in the first:\n\ (asymmetric-difference vector '(1 2 3) #(2 3 4) '(1 5)) -> #(4 5)")) (lambda (type . sequences) ; complement, elements in B's not in A (if (and (pair? sequences) (pair? (cdr sequences))) (collect-if type (lambda (obj) (not (member obj (car sequences)))) (apply union list (cdr sequences))) (apply type ()))))) (define cl-set-difference (let ((documentation "(cl-set-difference type .sequences) returns the elements in the first sequence that are not in the rest of the sequences:\n\ (cl-set-difference vector '(1 2 3) #(2 3 4) '(1 5)) -> #()")) (lambda (type . sequences) ; CL: elements in A not in B's (if (and (pair? sequences) (pair? (cdr sequences))) (let ((others (apply union list (cdr sequences)))) (collect-if type (lambda (obj) (not (member obj others))) (car sequences))) (apply type ()))))) (define symmetric-difference (let ((documentation "(symmetric-difference type .sequences) returns the elements that are in an odd number of the sequences:\n\ (symmetric-difference vector '(1 2 3) #(2 3 4) '(5)) -> #(1 4 5)")) (lambda (type . sequences) ; xor, elements in an odd number of sequences (logxor A B...) (let ((all (apply sequences->list sequences))) (collect-if type (lambda (obj) (odd? (count-if (lambda (x) (equal? x obj)) all))) (apply union list sequences)))))) (define power-set (let ((documentation "(power-set type . sequences) returns the power set of the union of the elements in the sequences.")) (lambda (type . sequences) ; ignoring repeats (letrec ((pset (lambda (set) (if (null? set) '(()) (let ((rest (pset (cdr set)))) (append rest (map (lambda (subset) (cons (car set) subset)) rest))))))) (apply type (pset (apply union list sequences))))))) ;;; ---------------- (define ->predicate (let ((predicates (list integer? rational? real? complex? number? byte-vector? string? float-vector? int-vector? vector? null? proper-list? pair? list? keyword? gensym? symbol? char? string? hash-table? iterator? continuation? input-port? output-port? let? dilambda? procedure? macro? boolean? random-state? eof-object? c-object? c-pointer? (lambda (obj) (eq? obj #)) (lambda (obj) (eq? obj #)) (lambda (obj) (memq obj (list quote if when unless begin set! let let* letrec letrec* cond and or case do lambda lambda* define define* define-macro define-macro* define-bacro define-bacro* define-constant with-baffle macroexpand with-let))))) (documentation "(->predicate obj) returns the type predicate function for obj: (->predicate 31) -> integer?")) (lambda (obj) (find-if (lambda (pred) (pred obj)) predicates)))) (define add-predicate (let ((documentation "(add-predicate p) adds p (a boolean function of one argument) to the list of predicates used by ->predicate")) (lambda (p) (if (and (procedure? p) (aritable? p 1)) (let ((e (funclet ->predicate))) (set! (e 'predicates) (cons p (e 'predicates)))) (error "add-predicate argument, ~A, is not a procedure of one argument" p))))) (define typeq? (let ((documentation "(typeq? . objs) returns #t if all objs have the same type (as determined by ->predicate)")) (lambda objs (or (null? objs) (every? (->predicate (car objs)) (cdr objs)))))) (define-macro (typecase expr . clauses) ; actually type=any boolean func (let ((obj (gensym))) `(begin ; normally this would be (let ((,obj ,expr)) ...) (define ,obj ,expr) ; but use begin so that internal defines are not blocked (cond ,@(map (lambda (clause) (if (memq (car clause) '(#t else)) clause (if (= (length (car clause)) 1) `((,(caar clause) ,obj) ,@(cdr clause)) `((or ,@(map (lambda (type) `(,type ,obj)) (car clause))) ,@(cdr clause))))) clauses))))) ;;; ---------------- (define 2^n? (let ((documentation "(2^n? x) returns #t if x is a power of 2")) (lambda (x) (and (integer> x) (not (zero? x)) (zero? (logand x (- x 1))))))) (define (2^n-1? x) (and (integer? x) (zero? (logand x (+ x 1))))) (define (lognand . ints) (lognot (apply logand ints))) (define (lognor . ints) (lognot (apply logior ints))) (define (logeqv . ints) (if (odd? (length ints)) (lognot (apply logxor -1 ints)) ; Clisp does it this way (lognot (apply logxor ints)))) (define (log-none-of . ints) ; bits on in none of ints (lognot (apply logior ints))) (define (log-all-of . ints) ; bits on in all of ints (apply logand ints)) (define (log-any-of . ints) ; bits on in at least 1 of ints (apply logior ints)) (define (log-n-of n . ints) ; return the bits on in exactly n of ints (if (integer? n) (if (every? integer? ints) (let ((len (length ints))) (cond ((= len 0) (if (= n 0) -1 0)) ((= n 0) (lognot (apply logior ints))) ((= n len) (apply logand ints)) ((> n len) 0) (#t (do ((1s 0) (prev ints) (i 0 (+ i 1))) ((= i len) 1s) (let ((cur (ints i))) (if (= i 0) (set! 1s (logior 1s (logand cur (apply log-n-of (- n 1) (cdr ints))))) (let* ((mid (cdr prev)) (nxt (if (= i (- len 1)) () (cdr mid)))) (set! (cdr prev) nxt) (set! 1s (logior 1s (logand cur (apply log-n-of (- n 1) ints)))) (set! (cdr prev) mid) (set! prev mid)))))))) (error "log-n-of ints arguments, ~A, should all be integers" ints)) (error "log-n-of first argument, ~A, should be an integer" n))) ;; from Rick (define (byte siz pos) ;; -> cache size, position and mask. (list siz pos (ash (- (ash 1 siz) 1) pos))) (define byte-size car) (define byte-position cadr) (define byte-mask caddr) (define (ldb bytespec integer) (ash (logand integer (byte-mask bytespec)) (- (byte-position bytespec)))) (define (dpb integer bytespec into) (logior (ash (logand integer (- (ash 1 (byte-size bytespec)) 1)) (byte-position bytespec)) (logand into (lognot (byte-mask bytespec))))) ;;; ---------------- (define-macro* (define-class class-name inherited-classes (slots ()) (methods ())) `(let ((outer-env (outlet (curlet))) (new-methods ()) (new-slots ())) (for-each (lambda (class) ;; each class is a set of nested environments, the innermost (first in the list) ;; holds the local slots which are copied each time an instance is created, ;; the next holds the class slots (global to all instances, not copied); ;; these hold the class name and other such info. The remaining environments ;; hold the methods, with the localmost method first. So in this loop, we ;; are gathering the local slots and all the methods of the inherited ;; classes, and will splice them together below as a new class. (set! new-slots (append (let->list class) new-slots)) (do ((e (outlet (outlet class)) (outlet e))) ((or (not (let? e)) (eq? e (rootlet)))) (set! new-methods (append (let->list e) new-methods)))) ,inherited-classes) (let ((remove-duplicates (lambda (lst) ; if multiple local slots with same name, take the localmost (letrec ((rem-dup (lambda (lst nlst) (cond ((null? lst) nlst) ((assq (caar lst) nlst) (rem-dup (cdr lst) nlst)) (else (rem-dup (cdr lst) (cons (car lst) nlst))))))) (reverse (rem-dup lst ())))))) (set! new-slots (remove-duplicates (append (map (lambda (slot) (if (pair? slot) (cons (car slot) (cadr slot)) (cons slot #f))) ,slots) ; the incoming new slots, #f is the default value new-slots)))) ; the inherited slots (set! new-methods (append (map (lambda (method) (if (pair? method) (cons (car method) (cadr method)) (cons method #f))) ,methods) ; the incoming new methods ;; add an object->string method for this class (this is already a generic function). (list (cons 'object->string (lambda* (obj (use-write #t)) (if (eq? use-write :readable) ; write readably (format #f "(make-~A~{ :~A ~W~^~})" ',class-name (map (lambda (slot) (values (car slot) (cdr slot))) obj)) (format #f "#<~A: ~{~A~^ ~}>" ',class-name (map (lambda (slot) (list (car slot) (cdr slot))) obj)))))) (reverse! new-methods))) ; the inherited methods, shadowed automatically (let ((new-class (openlet (apply sublet ; the local slots (sublet ; the global slots (apply inlet ; the methods (reverse new-methods)) 'class-name ',class-name ; class-name slot 'inherited ,inherited-classes 'inheritors ()) ; classes that inherit from this class new-slots)))) (varlet outer-env ',class-name new-class ; define the class as class-name in the calling environment ;; define class-name? type check (string->symbol (string-append (symbol->string ',class-name) "?")) (lambda (obj) (and (let? obj) (eq? (obj 'class-name) ',class-name)))) (varlet outer-env ;; define the make-instance function for this class. ;; Each slot is a keyword argument to the make function. (string->symbol (string-append "make-" (symbol->string ',class-name))) (apply lambda* (map (lambda (slot) (if (pair? slot) (list (car slot) (cdr slot)) (list slot #f))) new-slots) `((let ((new-obj (copy ,,class-name))) ,@(map (lambda (slot) `(set! (new-obj ',(car slot)) ,(car slot))) new-slots) new-obj)))) ;; save inheritance info for this class for subsequent define-method (letrec ((add-inheritor (lambda (class) (for-each add-inheritor (class 'inherited)) (if (not (memq new-class (class 'inheritors))) (set! (class 'inheritors) (cons new-class (class 'inheritors))))))) (for-each add-inheritor ,inherited-classes)) ',class-name))) (define-macro (define-generic name) ; (define (genfun any) ((any 'genfun) any)) `(define ,name (lambda args (let ((gf ((car args) ',name))) ; get local definition (if (not (eq? gf ,name)) ; avoid infinite recursion (apply gf args) (error "attempt to call generic function wrapper recursively")))))) (define-macro (define-slot-accessor name slot) `(define ,name (dilambda (lambda (obj) (obj ',slot)) (lambda (obj val) (set! (obj ',slot) val))))) (define-macro (define-method name-and-args . body) `(let* ((outer-env (outlet (curlet))) (method-name (car ',name-and-args)) (method-args (cdr ',name-and-args)) (object (caar method-args)) (class (symbol->value (cadar method-args))) (old-method (class method-name)) (method (apply lambda* method-args ',body))) ;; define the method as a normal-looking function ;; s7test.scm has define-method-with-next-method that implements call-next-method here ;; it also has make-instance (varlet outer-env method-name (apply lambda* method-args `(((,object ',method-name) ,@(map (lambda (arg) (if (pair? arg) (car arg) arg)) method-args))))) ;; add the method to the class (varlet (outlet (outlet class)) method-name method) ;; if there are inheritors, add it to them as well, but not if they have a shadowing version (for-each (lambda (inheritor) (if (not (eq? (inheritor method-name) #)) ; defined? goes to the global env (if (eq? (inheritor method-name) old-method) (set! (inheritor method-name) method)) (varlet (outlet (outlet inheritor)) method-name method))) (class 'inheritors)) method-name)) (define (all-methods obj method) ;; for arbitrary method combinations: this returns a list of all the methods of a given name ;; in obj's class and the classes it inherits from (see example below) (if (symbol? method) (let* ((base-method (obj method)) (methods (if (procedure? base-method) (list base-method) ()))) (for-each (lambda (ancestor) (let ((next-method (ancestor method))) (if (and (procedure? next-method) (not (memq next-method methods))) (set! methods (cons next-method methods))))) (obj 'inherited)) (reverse methods)) (error "all-methods 'method argument should be a symbol: ~A" method))) ;;; ---------------- (define for-each-subset (let ((documentation "(for-each-subset func args) forms each subset of args, then applies func to the subsets that fit its arity")) (lambda (func args) (define (subset source dest len) (if (null? source) (if (aritable? func len) ; does this subset fit? (apply func dest)) (begin (subset (cdr source) (cons (car source) dest) (+ len 1)) (subset (cdr source) dest len)))) (subset args () 0)))) (define for-each-permutation (let ((documentation "(for-each-permutation func vals) applies func to every permutation of vals:\n\ (for-each-permutation (lambda args (format #t \"~{~A~^ ~}~%\" args)) '(1 2 3))")) (lambda (func vals) (define (pinner cur nvals len) (if (= len 1) (apply func (cons (car nvals) cur)) (do ((i 0 (+ i 1))) ; I suppose a named let would be more Schemish ((= i len)) (let ((start nvals)) (set! nvals (cdr nvals)) (let ((cur1 (cons (car nvals) cur))) ; add (car nvals) to our arg list (set! (cdr start) (cdr nvals)) ; splice out that element and (pinner cur1 (cdr start) (- len 1)) ; pass a smaller circle on down, "wheels within wheels" (set! (cdr start) nvals)))))) ; restore original circle (let ((len (length vals))) (set-cdr! (list-tail vals (- len 1)) vals) ; make vals into a circle (pinner () vals len) (set-cdr! (list-tail vals (- len 1)) ()))))) ; restore its original shape ;;; ---------------- (define (clamp minimum x maximum) (min maximum (max x minimum))) (define (1- x) (- x 1)) (define (1+ x) (+ x 1)) (define n-choose-k (let ((documentation "(n-choose-k n k) returns the binomial coefficient C(N,K)")) (lambda (n k) (if (integer? n) (if (integer? k) (let ((mn (min k (- n k)))) (if (or (negative? mn) (negative? n)) 0 (if (= mn 0) 1 (let* ((mx (max k (- n k))) (cnk (+ 1 mx))) (do ((i 2 (+ i 1))) ((> i mn) cnk) (set! cnk (/ (* cnk (+ mx i)) i))))))) (error "n-choose-k 'k argument, ~A, should be an integer" k)) (error "n-choose-k 'n argument, ~A, should be an integer" n))))) ;;; ---------------- (define continuable-error (let ((documentation "(continuable-error . args) is (apply error args) wrapped in a continuation named 'continue.")) (lambda args (call/cc (lambda (continue) (apply error args)))))) (define continue-from-error ; maybe arg for value to pass back (let ((documentation "(continue-from-error) tries to continue from the point of the earlier continuable-error")) (lambda () (if (continuation? ((owlet) 'continue)) (((owlet) 'continue)))))) (define (call-with-input-vector v proc) (if (vector? v) (let ((i -1)) (proc (openlet (inlet 'read (lambda (p) (v (set! i (+ i 1)))))))) (error "call-with-input-vector first argument, ~A, should be a vector" v))) (define (call-with-output-vector proc) (let* ((size 1) (v (make-vector size #f)) (i 0) (write-to-vector (lambda (obj p) (when (= i size) ; make the vector bigger to accommodate the output (set! v (copy v (make-vector (set! size (* size 2)) #f)))) (set! (v i) obj) (set! i (+ i 1)) #))) ; that's what write/display return! (proc (openlet (inlet 'write (lambda* (obj p) ((if (not (let? p)) write write-to-vector) obj p)) 'display (lambda* (obj p) ((if (not (let? p)) display write-to-vector) obj p)) 'format (lambda (p . args) (if (not (let? p)) (apply format p args) (write (apply format #f args) p)))))) (make-shared-vector v (list i)))) ; ignore extra trailing elements ;;; ---------------- (define* (flatten-let e (n -1)) (if (let? e) (let ((slots ())) (do ((pe e (outlet pe)) (i 0 (+ i 1))) ((or (eq? pe (rootlet)) (= i n)) (apply inlet slots)) (for-each (lambda (slot) (if (and (not (assq (car slot) slots)) (not (constant? (car slot)))) ; immutable symbol (set! slots (cons slot slots)))) pe))) (error "flatten-let argument, ~A, is not a let" e))) (define* (owlets (ows 1)) (flatten-let (owlet) ows)) ;;; ---------------- (define-macro (reflective-let vars . body) `(let ,vars ,@(map (lambda (vr) `(set! (symbol-access ',(car vr)) (lambda (s v) (format *stderr* "~S -> ~S~%" s v) v))) vars) ,@body)) #| (define-bacro (reflective-probe) (with-let (inlet 'e (outlet (curlet))) (for-each (lambda (var) (format *stderr* "~S: ~S~%" (car var) (cdr var))) e))) |# ;; ideally this would simply vanish, and make no change in the run-time state, but (values) here returns # ;; (let ((a 1) (b 2)) (list (set! a 3) (reflective-probe) b)) -> '(3 2) not '(3 # 2) ;; I was too timid when I started s7 and thought (then) that (abs -1 (values)) should be an error ;; perhaps if we want it to disappear: (define-bacro (reflective-probe . body) (with-let (inlet :e (outlet (curlet)) :body body) (for-each (lambda (var) (format *stderr* "~S: ~S~%" (car var) (cdr var))) e) `(begin ,@body))) ;; now (let ((a 1) (b 2)) (list (set! a 3) (reflective-probe b))) -> '(3 2) ;; and (let ((a 1) (b 2)) (list (set! a 3) (reflective-probe) b)) -> '(3 () 2) ;; or use it to print function args: (define (f a b) (reflective-probe) (+ a b)) ;; could this use reactive-lambda* to show changes as well? ;;; ---------------- (define (gather-symbols expr ce lst ignore) (define (symbol->let sym ce) (if (defined? sym ce #t) ce (and (not (eq? ce (rootlet))) (symbol->let sym (outlet ce))))) (if (symbol? expr) (if (and (not (memq expr lst)) (not (memq expr ignore)) (not (procedure? (symbol->value expr ce))) (not (eq? (symbol->let expr ce) (rootlet)))) (cons expr lst) lst) (if (pair? expr) (if (and (pair? (cdr expr)) (pair? (cddr expr))) (if (pair? (cadr expr)) (if (memq (car expr) '(let let* letrec letrec* do)) (gather-symbols (cddr expr) ce lst (append ignore (map car (cadr expr)))) (if (eq? (car expr) 'lambda) (gather-symbols (cddr expr) ce lst (append ignore (cadr expr))) (if (eq? (car expr) 'lambda*) (gather-symbols (cddr expr) ce lst (append ignore (map (lambda (a) (if (pair? a) (car a) a)) (cadr expr)))) (gather-symbols (cdr expr) ce (gather-symbols (car expr) ce lst ignore) ignore)))) (if (and (eq? (car expr) 'lambda) (symbol? (cadr expr))) (gather-symbols (cddr expr) ce lst (append ignore (list (cadr expr)))) (gather-symbols (cdr expr) ce (gather-symbols (car expr) ce lst ignore) ignore))) (if (eq? (car expr) '_) (cons expr lst) (gather-symbols (cdr expr) ce (gather-symbols (car expr) ce lst ignore) ignore))) lst))) (define-bacro (reactive-set! place value) (with-let (inlet 'place place ; with-let here gives us control over the names 'value value 'e (outlet (curlet))) ; the run-time (calling) environment (let ((nv (gensym)) (ne (gensym))) `(begin (define ,ne ,e) ,@(map (lambda (sym) (if (symbol? sym) `(set! (symbol-access ',sym) (lambda (s v) (let ((,nv ,(if (with-let (sublet e 'sym sym) (symbol-access sym)) `(begin (,(procedure-source (with-let (sublet e 'sym sym) (symbol-access sym))) s v)) 'v))) (with-let (sublet ,ne ',sym ,nv) (set! ,place ,value)) ,nv))) (if (or (not (eq? (car sym) '_)) (not (pair? (cdr sym))) (not (integer? (cadr sym))) (not (null? (cddr sym)))) (error 'wrong-type-arg "reactive-vector can't handle: ~S~%" sym) (let ((index (cadr sym))) `(set! (_ 'local-set!) (apply lambda '(obj i val) (append (cddr (procedure-source (_ 'local-set!))) `((if (= i ,,index) (set! ,',place ,',value)))))))))) (gather-symbols value e () ())) (set! ,place ,value))))) #| (let ((a 1) (b 2) (c 3)) (reactive-set! b (+ c 4)) ; order matters! (reactive-set! a (+ b c)) (set! c 5) a) (let ((a 1) (v (vector 1 2 3))) (reactive-set! (v 1) (* a 3)) (set! a 4) v) |# ;; just a first stab at this: (define reactive-vector (let () (require mockery.scm) (define make-mock-vector (*mock-vector* 'make-mock-vector)) (define (reactive-vector-1 e . args) ;; set up accessors for any element that has an expression as its initial value ;; if any element depends on some other element, return a mock-vector with setter fixed up (let ((code `(let ((_ (,(if (any? (lambda (a) (tree-member '_ a)) args) '((funclet reactive-vector) 'make-mock-vector) 'make-vector) ,(length args))))))) (let ((ctr 0)) (for-each (lambda (arg) (set! code (append code `((reactive-set! (_ ,ctr) ,arg)))) (set! ctr (+ ctr 1))) args)) (append code `(_)))) (define-bacro (reactive-vector . args) (apply ((funclet reactive-vector) 'reactive-vector-1) (outlet (curlet)) args)))) #| (let ((a 1)) (let ((v (reactive-vector a (+ a 1) 2))) (set! a 4) v)) -> #(4 5 2) (let* ((a 1) (v (reactive-vector a (+ a 1) 2))) (set! a 4) v) -> #(4 5 2) (let* ((a 1) (v (reactive-vector a (+ a 1) (* 2 (_ 0))))) (set! a 4) v) -> #(4 5 8) ;;; mock-vector could also be used for constant or reflective vectors, etc -- just like symbol-access but element-wise |# ;; another experiment: (define-bacro (reactive-format port ctrl . args) (with-let (inlet 'e (outlet (curlet)) 'args args 'port port 'ctrl ctrl) (let* ((syms (gather-symbols args e () ())) (sa's (map symbol-access syms))) `(begin ,@(map (lambda (sym sa) `(set! (symbol-access ',sym) (lambda (s v) (let ((result (if ,sa (apply ,sa s v ()) v))) (with-let (sublet ,e ',sym result) (format ,port ,ctrl ,@args)) ; is this equivalent to an exported closure in the GC? result)))) syms sa's) (format ,port ,ctrl ,@args))))) ;;; this is not pretty ;;; part of the complexity comes from the hope to be tail-callable, but even a version ;;; using dynamic-wind is complicated because of shadowing ;;; what I think we want here is a globally accessible way to see set! that does not ;;; require non-local state (not a hook with its list of functions, or symbol-access) ;;; and that doesn't bring s7 to a halt. Perhaps a symbol-access function that ;;; traverses the let-chain (like *features*) looking for something?? But the relevant ;;; chain is on the stack (is it?), so it won't be quick. And weak refs are asking for trouble. ;;; (let ((a 1)) (define (set-a x) (set! a x)) (let ((b 2)) (reactive-set! b (+ a 1)) (set-a 3) b)) ;;; Perhaps a way to share the original's slot? No slow down, transparent, local setter can ;;; run its own accessor, set -> shared slot so all sharers see the new value, ;;; but how to trigger all accessors? ;;; (set! (symbol-slot 'a e1) (symbol-slot 'a e2)) ;;; this isn't currently doable -- object.slt.val is a pointer, not a pointer to a pointer ;;; there is the symbol's extra slot, but it is global. I wonder how much slower s7 would be ;;; with a pointer to a pointer here -- are there any other places this would be useful? ;;; even with this, the entire accessor chain is not triggered. ;;; so, use with-accessors and reactive-set! for complex cases (define unique-reactive-let-name ; the alternative is (apply define-bacro ...) with a top-level gensym (let ((name #f)) (lambda () (if (gensym? name) name (set! name (gensym "v")))))) (define-bacro (reactive-let vars . body) (with-let (inlet 'vars vars 'body body 'e (outlet (curlet))) (let ((bindings ()) (accessors ()) (setters ()) (gs (gensym)) (v (unique-reactive-let-name))) (define (rlet-symbol sym) (string->symbol (string-append "{" (symbol->string sym) "}-rlet"))) (for-each (lambda (bd) (let ((syms (gather-symbols (cadr bd) e () ()))) (for-each (lambda (sym) (let ((fname (gensym (symbol->string sym)))) (set! bindings (cons `(,fname (lambda (,sym) ,(copy (cadr bd)))) bindings)) (if (not (memq sym setters)) (set! setters (cons sym setters))) (let ((prev (assq sym accessors))) (if (not prev) (set! accessors (cons (cons sym `((set! ,(car bd) (,fname ,v)))) accessors)) (set-cdr! prev (append `((set! ,(car bd) (,fname ,v))) (cdr prev))))))) syms) (set! bindings (cons bd bindings)))) vars) (let ((bsyms (gather-symbols body e () ())) (nsyms ())) (for-each (lambda (s) (if (and (with-let (sublet e (quote gs) s) (symbol-access gs)) (not (assq s bindings))) (if (not (memq s setters)) (begin (set! setters (cons s setters)) (set! nsyms (cons (cons s (cdr (procedure-source (with-let (sublet e (quote gs) s) (symbol-access gs))))) nsyms))) (let ((prev (assq s accessors))) (if prev ; merge the two functions (set-cdr! prev (append (cdddr (procedure-source (with-let (sublet e (quote gs) s) (symbol-access gs)))) (cdr prev)))))))) bsyms) `(let ,(map (lambda (sym) (values `(,(rlet-symbol sym) (lambda (,v) (set! ,sym ,v))) `(,sym ,sym))) setters) (let ,(reverse bindings) ,@(map (lambda (sa) (if (not (assq (car sa) bindings)) `(set! (symbol-access ',(car sa)) (lambda (,(gensym) ,v) (,(rlet-symbol (car sa)) ,v) ,@(cdr sa) ,v)) (values))) accessors) ,@(map (lambda (ns) `(set! (symbol-access ',(car ns)) (apply lambda ',(cdr ns)))) nsyms) ,@body)))))) (define-macro (reactive-let* vars . body) (define (add-let v) (if (pair? v) `(reactive-let ((,(caar v) ,(cadar v))) ,(add-let (cdr v))) `(begin ,@body))) (add-let vars)) ;; reactive-letrec is not useful: lambdas already react and anything else is an error (use of #) (define-macro (reactive-lambda* args . body) `(let ((f (lambda* ,args ,@body)) (e (curlet))) (unless (eq? e (rootlet)) (define (one-access s1 v) (let* ((syms (map car e)) (sa's (map (lambda (s) (symbol-access s e)) syms))) (dynamic-wind (lambda () (for-each (lambda (s) (if (not (eq? s s1)) (set! (symbol-access s e) #f))) syms)) (lambda () (f s1 v)) (lambda () (for-each (lambda (s a) (set! (symbol-access s e) a)) syms sa's))))) (for-each (lambda (s) (set! (symbol-access s e) one-access)) (map car e))) f)) (define-macro (with-accessors vars . body) `(let ((accessors ())) (dynamic-wind (lambda () (set! accessors (map symbol-access ',vars))) (lambda () ,@body) (lambda () (for-each (lambda (var accessor) (set! (symbol-access var) accessor)) ',vars accessors))))) ;; (let ((a 1) (b 2)) (with-accessors (a b) (let ((c 3)) (reactive-set! c (+ (* 2 a) (* 3 b))) (set! a 4) c))) #| (let ((x 0.0)) (reactive-let ((y (sin x))) (set! x 1.0) y)) -- so "lifting" comes for free? (map (lambda (s) (symbol-access (car s) e)) e) (let ((a 1)) (reactive-let ((b (+ a 1)) (c (* a 2))) (set! a 3) (+ c b))) (let ((a 1) (d 2)) (reactive-let ((b (+ a d)) (c (* a d)) (d 0)) (set! a 3) (+ b c))) (let ((a 1)) (reactive-let* ((b (+ a 1)) (c (* b 2))) (set! a 3) (+ c b))) (let ((a 1)) (reactive-let* ((b (+ a 1))) (set! a 3) b)) (define rl (let ((a 1) (b 2) (c 3)) (reactive-lambda* (s v) (format *stderr* "~S changed: ~S~%" s v)))) ;; constant env: ;; (define e (let ((a 1) (b 2)) (reactive-lambda* (s v) ((curlet) s)) (curlet))) |# ;;; what about (reactive-vector (v 0)) -- can we watch some other vector's contents? ;;; if v were a mock-vector, we could use the same vector-set! stuff as now but with any name (how to distinguish?) ;;; we can distinguish because this is happening at run-time where (v 0) has an ascertainable meaning ;;; how would reactive-hash-table work? (hash 'a (+ b 1)) and update 'a's value whenever b changes? ;;; reactive-string? (reactive-string #\a c (integer->char a) (str 0) (_ 0)) ;;; reactive-eval reactive-if(expr changes)--reactive-assert for example #| ;; this tests a bacro for independence of any runtime names ;; (bacro-shaker reactive-set! '(let ((a 21) (b 1)) (reactive-set! a (* b 2)) (set! b 3) a)) (define (bacro-shaker bac example) (define (swap-symbols old-code syms) (if (null? old-code) () (if (symbol? old-code) (let ((x (assq old-code syms))) (if x (cdr x) (copy old-code))) (if (pair? old-code) (cons (swap-symbols (car old-code) syms) (swap-symbols (cdr old-code) syms)) (copy old-code))))) (let ((e (outlet (curlet))) (source (cddr (cadr (caddr (procedure-source bac)))))) (let ((symbols (gather-symbols source (rootlet) () ())) (exsyms (gather-symbols (cadr example) (rootlet) () ()))) ;; now try each symbol at each position in exsyms, in all combinations (let ((syms ())) (for-each (lambda (s) (set! syms (cons (cons s s) syms))) exsyms) (let ((result (eval example e))) (define (g . new-args) (for-each (lambda (a b) (set-cdr! a b)) syms new-args) (let ((code (swap-symbols example syms))) (let ((new-result (catch #t (lambda () (eval code e)) (lambda args args)))) (if (not (equal? result new-result)) (format *stderr* "~A -> ~A~%~A -> ~A~%" example result code new-result))))) (define (f . args) (for-each-permutation g args)) (let ((subsets ()) (func f) (num-args (length exsyms)) (args symbols)) (define (subset source dest len) (if (null? source) (begin (set! subsets (cons dest subsets)) (if (= len num-args) (apply func dest))) (begin (subset (cdr source) (cons (car source) dest) (+ len 1)) (subset (cdr source) dest len)))) (subset args () 0))))))) |# ;;; ---------------- (define-macro (catch* clauses . error) (define (builder lst) (if (null? lst) (apply values error) `(catch #t (lambda () ,(car lst)) (lambda args ,(builder (cdr lst)))))) (builder clauses)) (define* (subsequence obj (start 0) end) (let* ((len (length obj)) (new-len (- (min len (or end len)) start))) (if (negative? new-len) (error 'out-of-range "end: ~A should be greater than start: ~A" end start)) (cond ((vector? obj) (make-shared-vector obj (list new-len) start)) ((string? obj) (if end (substring obj start end) (substring obj start))) ((pair? obj) (if (not end) (cdr* obj start) (let ((lst (make-list new-len #f))) (do ((i 0 (+ i 1))) ((= i new-len) lst) (set! (lst i) (obj (+ i start))))))) (else ; (subsequence (inlet 'subsequence (lambda* (obj start end) "subseq"))) (catch* (((obj 'subsequence) obj start end) (subsequence (obj 'value) start end)) #f))))) (define (sequence->string val) (if (or (not (sequence? val)) (empty? val)) (format #f "~S" val) (cond ((vector? val) (format #f "#(~{~A~| ~})" val)) ((let? val) (format #f "(inlet ~{'~A~| ~})" val)) ((hash-table? val) (format #f "(hash-table ~{'~A~| ~})" val)) ((string? val) (format #f (if (byte-vector? val) "#u8(~{~D~| ~})" "\"~{~A~|~}\"") val)) (else (format #f "(~{~A~| ~})" val))))) ;;; ---------------- (define-macro (elambda args . body) ; lambda but pass extra arg "*env*" = run-time env `(define-bacro (,(gensym) ,@args) `((lambda* ,(append ',args `((*env* (curlet)))) ,'(begin ,@body)) ,,@args))) (define-macro* (rlambda args . body) ; lambda* but eval arg defaults in run-time env (let ((arg-names (map (lambda (arg) (if (pair? arg) (car arg) arg)) args)) (arg-defaults (map (lambda (arg) (if (pair? arg) `(,(car arg) (eval ,(cadr arg))) arg)) args))) `(define-bacro* (,(gensym) ,@arg-defaults) `((lambda ,',arg-names ,'(begin ,@body)) ,,@arg-names)))) ;;; ---------------- (if (and (not (defined? 'apropos)) (not (provided? 'snd))) (define* (apropos name (port *stdout*) (e (rootlet))) (let ((ap-name (if (string? name) name (if (symbol? name) (symbol->string name) (error 'wrong-type-arg "apropos argument 1 should be a string or a symbol")))) (ap-env (if (let? e) e (error 'wrong-type-arg "apropos argument 3 should be an environment"))) (ap-port (if (output-port? port) port (error 'wrong-type-arg "apropos argument 2 should be an output port")))) (for-each (lambda (binding) (if (and (pair? binding) (string-position ap-name (symbol->string (car binding)))) (format ap-port "~A: ~A~%" (car binding) (if (procedure? (cdr binding)) (procedure-documentation (cdr binding)) (cdr binding))))) ap-env)))) ;;; ---------------- ;; these need to be globally accessible since they're inserted in arbitrary source (define Display #f) (define Display-port #f) (let ((spaces 0) (*display-spacing* 2) ; (set! ((funclet Display) '*display-spacing*) 1) etc (*display-print-length* 6) (*display* *stderr*) ; exported via Display-port (e (gensym)) (result (gensym)) (vlp (gensym))) ;; local symbol access -- this does not affect any other uses of these symbols (set! (symbol-access '*display-spacing* (curlet)) (lambda (s v) (if (and (integer? v) (not (negative? v))) v *display-spacing*))) (set! (symbol-access '*display-print-length* (curlet)) (lambda (s v) (if (and (integer? v) (not (negative? v))) v *display-print-length*))) ;; export *display* -- just a convenience (set! Display-port (dilambda (lambda () *display*) (lambda (val) (set! *display* val)))) (define (prepend-spaces) (format *display* (format #f "~~~DC" spaces) #\space)) (define (display-format str . args) `(let ((,vlp (*s7* 'print-length))) (with-let (funclet Display) (set! (*s7* 'print-length) *display-print-length*) (prepend-spaces)) (format (Display-port) ,str ,@args) (set! (*s7* 'print-length) ,vlp))) (define (display-let le e) (let ((vlp (*s7* 'print-length))) (for-each (lambda (slot) (unless (or (gensym? (car slot)) (eq? (cdr slot) e)) (set! (*s7* 'print-length) *display-print-length*) (let ((str (sequence->string (cdr slot)))) (set! (*s7* 'print-length) 30) (format (Display-port) " :~A ~{~A~|~}" (car slot) str)))) le) (set! (*s7* 'print-length) vlp))) (define (last lst) (let ((len (length lst))) (let ((end (list-tail lst (if (negative? len) (abs len) (- len 1))))) (if (pair? end) (car end) end)))) (define* (butlast lst (result ())) (if (or (not (pair? lst)) (null? (cdr lst))) (reverse result) (butlast (cdr lst) (cons (car lst) result)))) (define* (remove-keys args (lst ())) (if (pair? args) (remove-keys (cdr args) (if (or (not (keyword? (car args))) (eq? (car args) :rest)) (cons (car args) lst) lst)) (if (null? args) (reverse lst) (append (reverse lst) args)))) (define (walk-let-body source) (let ((previous (butlast source)) (end (last source))) `(begin ,@previous (let ((,result ,end)) (with-let (funclet Display) (prepend-spaces)) (format (Display-port) " ~A~A) -> ~A~%" ,(if (pair? previous) " ... " "") ',end ,result) ,result)))) (define (proc-walk source) (if (pair? source) (case (car source) ((let let* letrec letrec*) ;; show local variables, (let vars . body) -> (let vars print-vars . body) (if (symbol? (cadr source)) ; named let? (append (list (car source) ; let (cadr source) ; name (caddr source) ; vars (display-format "(let ~A (~{~A~| ~})~%" (cadr source) '(outlet (curlet)))) (walk-let-body (cdddr source))) ; body (append (list (car source) ; let (cadr source) ; vars (display-format "(~A (~{~A~| ~})~%" (car source) '(outlet (curlet)))) (walk-let-body (cddr source))))) ; body ((or and) ;; report form that short-circuits the evaluation (append (list (car source)) (let ((ctr -1) (len (- (length (cdr source)) 1)) (eob (if (eq? (car source) 'or) 'when 'unless))) (map (lambda (expr) (set! ctr (+ ctr 1)) `(let ((,result ,expr)) (,eob ,result (format (Display-port) " (~A ~A~A~A) -> ~A~%" ',(car source) ,(if (> ctr 0) " ... " "") ',expr ,(if (< ctr len) " ... " "") ,result)) ,result)) (cdr source))))) ((begin with-let with-baffle) ;; report last form (let ((previous (butlast (cdr source))) (end (last source))) `(,(car source) ,@previous (let ((,result ,end)) (format (Display-port) "(~A ~A~A) -> ~A~%" ',(car source) ,(if (pair? previous) " ... " "") ',end ,result) ,result)))) ((when unless) ;; report expr if body not walked, else report last form of body (let ((previous (butlast (cddr source))) (end (last (cddr source)))) `(,(car source) (let ((,result ,(cadr source))) (,(car source) (not ,result) (format (Display-port) "(~A ~A -> ~A ...)~%" ',(car source) ',(cadr source) ,result)) ,result) ,@previous (let ((,result ,end)) (format (Display-port) "(~A ... ~A) -> ~A~%" ',(car source) ',end ,result) ,result)))) ((quote) source) ((cond) ;; report form that satisifies cond (let ((ctr -1) (len (- (length (cdr source)) 1))) `(cond ,@(map (lambda (clause) (let ((test (car clause)) (body (cdr clause))) (set! ctr (+ ctr 1)) (if (eq? (car body) '=>) `(,test => (lambda (,result) (let ((,result (,@(cdr body) ,result))) (format (Display-port) " (cond ~A~A~A) -> ~A~%" ,(if (> ctr 0) " ... " "") ',clause ,(if (< ctr len) " ... " "") ,result) ,result))) `(,test (let ((,result (begin ,@body))) (format (Display-port) " (cond ~A~A~A) -> ~A~%" ,(if (> ctr 0) " ... " "") ',clause ,(if (< ctr len) " ... " "") ,result) ,result))))) (cdr source))))) ((case) ;; as in cond but include selector value in [] and report fall throughs (let ((ctr -1) (len (- (length (cddr source)) 1)) (default (member '(else #t) (cddr source) (lambda (a b) (memq (car b) a))))) `(case ,(cadr source) ,@(append (map (lambda (clause) (let ((test (car clause)) (body (cdr clause))) (set! ctr (+ ctr 1)) (if (eq? (car body) '=>) `(,test => (lambda (,result) (let ((,result (,@(cdr body) ,result))) (format (Display-port) " (case [~A] ~A~A~A) -> ~A~%" ,(cadr source) ,(if (> ctr 0) " ... " "") ',clause ,(if (< ctr len) " ... " "") ,result) ,result))) `(,test (let ((,result (begin ,@body))) (format (Display-port) " (case [~A] ~A~A~A) -> ~A~%" ,(cadr source) ,(if (> ctr 0) " ... " "") ',clause ,(if (< ctr len) " ... " "") ,result) ,result))))) (cddr source)) (if (not default) `((else (format (Display-port) " (case [~A] falls through~%" ,(cadr source)) #)) ()))))) ((dynamic-wind) ;; here we want to ignore the first and last clauses, and report the last of the second (let ((l2 (caddr source))) (let* ((body (and (eq? (car l2) 'lambda) (cddr l2))) (previous (and body (butlast body))) (end (and body (last body)))) (if (not body) source `(dynamic-wind ,(cadr source) (lambda () ,@previous (let ((,result ,end)) (format (Display-port) "(dynamic-wind ... ~A) -> ~A~%" ',end ,result) ,result)) ,(cadddr source)))))) (else (cons (proc-walk (car source)) (proc-walk (cdr source))))) source)) (define-macro (Display-1 definition) (if (and (pair? definition) (memq (car definition) '(define define*)) (pair? (cdr definition)) (pair? (cadr definition))) ;; (Display (define (f ...) ...) (let ((func (caadr definition)) (args (cdadr definition)) (body `(begin ,@(proc-walk (cddr definition))))) ;(format *stderr* "~A ~A ~A~%" func args body) (let* ((no-noise-args (remove-keys args)) ; omit noise words like :optional (arg-names (if (null? args) () (if (proper-list? args) ; handle (f x ...), (f (x 1) ...), (f . x), and (f x . z) (map (lambda (a) (if (symbol? a) a (car a))) ; omit the default values no-noise-args) (if (pair? args) (append (butlast no-noise-args) (list :rest (last args))) (list :rest args))))) (call-args (if (null? args) () (if (proper-list? args) (if (memq :rest args) (append (butlast (butlast no-noise-args)) ; also omit the :rest (list (list '{apply_values} (last args)))) arg-names) ; (... y x) (if (pair? args) (append (butlast no-noise-args) ; (... y ({apply_values} x)) (list (list '{apply_values} (last args)))) (list (list '{apply_values} args))))))) ; (... ({apply_values} x)) `(define ,func (define-macro* ,(cons (gensym) args) ; args might be a symbol etc `((lambda* ,(cons ',e ',arg-names) ; prepend added env arg because there might be a rest arg (let ((,',result '?)) (dynamic-wind (lambda () ; when function called, show args and caller (with-let (funclet Display) ; indent (prepend-spaces) (set! spaces (+ spaces *display-spacing*))) (format (Display-port) "(~A" ',',func) ; show args, ruthlessly abbreviated (((funclet Display) 'display-let) (outlet (outlet (curlet))) ,',e) (format (Display-port) ")") (let ((caller (eval '__func__ ,',e))) ; show caller (if (not (eq? caller #)) (format (Display-port) " ;called from ~A" caller))) (newline (Display-port))) (lambda () ; the original function body (set! ,',result ,',body)) ; but annotated by proc-walk (lambda () ; at the end, show the result (with-let (funclet Display) (set! spaces (- spaces *display-spacing*)) ; unindent (prepend-spaces)) (format (Display-port) " -> ~S~%" ,',result))))) (curlet) ,,@call-args))))) ; pass in the original args and the curlet ;; (Display ) (proc-walk definition))) ; (Display (+ x 1)) etc (set! Display Display-1)) ; make Display-1 globally accessible ;;; -------------------------------------------------------------------------------- (define (*s7*->list) (list :print-length (*s7* 'print-length) :safety (*s7* 'safety) :cpu-time (*s7* 'cpu-time) :heap-size (*s7* 'heap-size) :free-heap-size (*s7* 'free-heap-size) :gc-freed (*s7* 'gc-freed) :gc-protected-objects (*s7* 'gc-protected-objects) :gc-stats (*s7* 'gc-stats) :max-string-length (*s7* 'max-string-length) :max-list-length (*s7* 'max-list-length) :max-vector-length (*s7* 'max-vector-length) :max-vector-dimensions (*s7* 'max-vector-dimensions) :default-hash-table-length (*s7* 'default-hash-table-length) :initial-string-port-length (*s7* 'initial-string-port-length) :default-rationalize-error (*s7* 'default-rationalize-error) :default-random-state (*s7* 'default-random-state) :morally-equal-float-epsilon (*s7* 'morally-equal-float-epsilon) :hash-table-float-epsilon (*s7* 'hash-table-float-epsilon) :float-format-precision (*s7* 'float-format-precision) :bignum-precision (*s7* 'bignum-precision) :file-names (*s7* 'file-names) :rootlet-size (*s7* 'rootlet-size) :c-types (*s7* 'c-types) :stack-top (*s7* 'stack-top) :stack-size (*s7* 'stack-size) :stacktrace-defaults (*s7* 'stacktrace-defaults) :max-stack-size (*s7* 'max-stack-size) :symbol-table-locked? (*s7* 'symbol-table-locked?) :undefined-identifier-warnings (*s7* 'undefined-identifier-warnings) :catches (*s7* 'catches) :exits (*s7* 'exits))) ;;; -------------------------------------------------------------------------------- (define* (make-directory-iterator name (recursive #t)) (if (not (string? name)) (error "directory name should be a string: ~S" name) (make-iterator (with-let (sublet *libc* :name name :recursive recursive) (let ((dir (opendir name))) (if (equal? dir NULL) (error "can't open ~S: ~S" name (strerror (errno))) (let ((iterator? #t) (dirs ()) (dir-names ()) (dir-name name)) (define* (reader quit) ; returned from with-let (if (eq? quit #) ; caller requests cleanup and early exit (begin ; via ((iterator-sequence iter) #) (closedir dir) (for-each closedir dirs) (set! dirs ()) quit) (let ((file (read_dir dir))) (if (zero? (length file)) ; null filename => all done (begin (closedir dir) (if (null? dirs) # (begin ; else pop back to outer dir (set! dir (car dirs)) (set! dirs (cdr dirs)) (set! dir-name (car dir-names)) (set! dir-names (cdr dir-names)) (reader)))) (if (not (member file '("." "..") string=?)) (let ((full-dir-name (string-append dir-name "/" file))) (if (and recursive (reader-cond ((defined? 'directory?) (directory? full-dir-name)) (#t (let ((buf (stat.make))) (let ((result (and (stat full-dir-name buf) (S_ISDIR (stat.st_mode buf))))) (free buf) result))))) (let ((new-dir (opendir full-dir-name))) (if (equal? new-dir NULL) ; inner directory is unreadable? (begin (format *stderr* "can't read ~S: ~S" file (strerror (errno))) (reader)) (begin (set! dirs (cons dir dirs)) (set! dir new-dir) (set! dir-names (cons dir-name dir-names)) (set! dir-name full-dir-name) (reader)))) (string-append dir-name "/" file))) (reader)))))))))))))snd-16.1/snd-test.rb0000644000076400007640000500031212476114577012440 0ustar bilbil# snd-test.rb -- Snd Ruby code and tests # Translator/Author: Michael Scholz # Created: 05/02/18 10:18:34 # Changed: 15/03/05 13:28:53 # Tags: FIXME - something is wrong # XXX - info marker # # Tested with: # Snd 15.x # Ruby 2.x.x # # Reads init file ./.sndtest.rb or ~/.sndtest.rb for global variables, # hooks, etc. # # Example: # =begin % cat ./.sndtest.rb # $VERBOSE = true # $DEBUG = true $original_save_dir = set_save_dir(ENV["TMPDIR"]) $original_temp_dir = set_temp_dir(save_dir) $info_array_print_length = 4 $sf_dir = "/usr/opt/sound/sf1/" $bigger_snd = "/usr/opt/sound/SFiles/bigger.snd" $with_big_file = true # $all_args = true # $bigtest_08 = true # $tests = 2 alias bye exit =end # # Start tests: # # snd -noinit -load snd-test.rb # all tests # snd -noinit -load snd-test.rb 3 7 20 # only tests 3, 7, 20 # snd -noinit -load snd-test.rb -23 # all tests except 23 # # test 00: constants # test 01: defaults # test 02: headers # test 03: variables # test 04: sndlib # test 05: simple overall checks # test 06: vcts # test 07: colors # test 08: clm # test 09: mix # test 10: marks # test 11: dialogs # test 12: extensions # test 13: menus, edit lists, hooks, etc # test 14: all together now # test 15: chan-local vars # test 16: regularized funcs # test 17: dialogs and graphics # test 18: enved # test 19: save and restore # test 20: transforms # test 21: new stuff # test 23: with-sound # test 28: errors # test all done $VERBOSE = false $DEBUG = false $my_snd_error_hook = false $my_mus_error_hook = false # run snd-test.rb $tests times $tests = 1 $HOME = ENV["HOME"] $original_save_dir = (save_dir or $HOME + "/zap/snd") $original_temp_dir = (temp_dir or $HOME + "/zap/tmp") $original_sound_file_extensions = sound_file_extensions $original_prompt = listener_prompt $default_file_buffer_size = mus_file_buffer_size() $info_array_print_length = 24 $sf_dir = "/home/bil/sf1/" $bigger_snd = "/home/bil/zap/sounds/bigger.snd" $with_big_file = false # $bigtest_08 not included in $all_args $all_args = false $bigtest_08 = false # Global variables may be overridden in `pwd`/.sndtest.rb or ~/.sndtest.rb. lambda do |file| if File.file?(file) load(file) elsif File.file?(f = $HOME + "/" + file) load(f) end end.call(".sndtest.rb") unless $my_snd_error_hook $my_snd_error_hook = Proc.new do |msg| true end end require "clm" # default 1, can be reset in .sndtest.rb $tests = ((integer?($tests) and $tests > 0) ? $tests : 1) $clmtest = 0 $with_test_nogui = provided?("snd-nogui") $with_test_gui = (not $with_test_nogui) $with_test_motif = provided?("snd-motif") $with_test_gtk = provided?("snd-gtk") $with_test_gtk3 = provided?("gtk3") $with_test_ladspa = provided?("snd-ladspa") $with_test_gl = provided?("gl") $with_test_gl2ps = provided?("gl2ps") $with_test_gsl = provided?("gsl") $with_test_alsa = provided?("alsa") if $with_test_nogui def noop(*args, &body) false end undef x_bounds undef set_x_bounds undef y_bounds undef set_y_bounds undef enved_filter undef graph_cursor undef set_graph_cursor undef enved_envelope undef set_enved_envelope undef colormap undef set_colormap # XXX: snd-nogui.c defines "in" alias call_in in alias integer2colormap noop alias colormap2integer noop alias axis_color noop alias highlight_color noop x_bounds_value = [0.0, 0.1] make_proc_with_setter(:x_bounds, Proc.new do |*args| x_bounds_value end, Proc.new do |bounds, *args| x_bounds_value = bounds end) y_bounds_value = [-1.0, 1.0] make_proc_with_setter(:y_bounds, Proc.new do |*args| y_bounds_value end, Proc.new do |bounds, *args| y_bounds_value = bounds end) # XXX: For ruby18 it's important to define Procs with arity 0 in this way: # # Proc.new do | | enved_filter_value end # or Proc.new do enved_filter_value end # or lambda do enved_filter_value end # # but not # # lambda do | | enved_filter_value end # # Otherwise we can't correctly determine the arity in test 28. enved_filter_value = true make_proc_with_setter(:enved_filter, Proc.new do | | enved_filter_value end, Proc.new do |val| enved_filter_value = val end) graph_cursor_value = 34 make_proc_with_setter(:graph_cursor, Proc.new do | | graph_cursor_value end, Proc.new do |val| graph_cursor_value = val end) enved_envelope_value = nil make_proc_with_setter(:enved_envelope, Proc.new do | | enved_envelope_value end, Proc.new do |val| enved_envelope_value = val end) colormap_value = $hot_colormap make_proc_with_setter(:colormap, Proc.new do | | colormap_value end, Proc.new do |val| if val.kind_of?(Numeric) and val.between?(0, 20) colormap_value = val end end) $mouse_enter_graph_hook = Hook.new("$mouse_enter_graph_hook", 2) $mouse_enter_label_hook = Hook.new("$mouse_enter_label_hook", 3) $mouse_enter_listener_hook = Hook.new("$mouse_enter_listener_hook", 1) $mouse_enter_text_hook = Hook.new("$mouse_enter_text_hook", 1) $mouse_leave_graph_hook = Hook.new("$mouse_leave_graph_hook", 2) $mouse_leave_label_hook = Hook.new("$mouse_leave_label_hook", 3) $mouse_leave_listener_hook = Hook.new("$mouse_leave_listener_hook", 1) $mouse_leave_text_hook = Hook.new("$mouse_leave_text_hook", 1) end require "examp" require "ws" require "hooks" require "mix" require "marks" require "pvoc" require "bird" require "v" require "poly" require "dsp" require "analog-filter" require "rgb" require "effects" require "draw" require "musglyphs" if $with_test_motif RXSetErrorHandler(lambda do |dpy, e| val, err = RXGetErrorText(dpy, Rerror_code(e), nil, 1024) $stderr.printf("Xlib error_code[%s]: %s\n", val, err) val, err = RXGetErrorText(dpy, Rrequest_code(e), nil, 1024) $stderr.printf("Xlib request_code[%s]: %s\n", val, err) val, err = RXGetErrorText(dpy, Rminor_code(e), nil, 1024) $stderr.printf("Xlib minor_code[%s]: %s\n", val, err) $stderr.printf("Ruby $!: %s\n", $!.inspect) $stderr.printf("Ruby $@: %s\n", $@.inspect) end) RXSetIOErrorHandler(lambda do |dpy| $stderr.printf("Xlib IO Error dpy: %s", dpy.inspect) $stderr.printf("Ruby $!: %s\n", $!.inspect) $stderr.printf("Ruby $@: %s\n", $@.inspect) end) end # Returns Ascii value of KEY as a Fixnum. # # Since Ruby 1.9.0 (July/August 2006) ?x returns string "x" instead of # fixnum 120, so we need a new function. # # key_to_int(?x) => 120 if ?x.kind_of?(String) def key_to_int(key) key.sum end else def key_to_int(key) key end end if $with_test_nogui set_with_mix_tags(true) end unbind_key(key_to_int(?c), 4, true) # C-c for interrupt key trap("SIGINT") do |sig| puts snd_info("Interrupt received. Finish snd-test.rb.") snd_info("") $timings.last.last.stop finish_snd_test clear_test_files exit(2) end # let procs $snd|mus_error_hook("sndtestrc") untouched def reset_almost_all_hooks reset_all_hooks if proc?($my_snd_error_hook) $snd_error_hook.add_hook!("sndtest", &$my_snd_error_hook) end if proc?($my_mus_error_hook) $mus_error_hook.add_hook!("sndtest", &$my_mus_error_hook) end end reset_almost_all_hooks $test_functions = Array.new def main_test start_snd_test() if false # XXX: Instead of rand() one can use different command lines: # snd -noinit snd-test.rb 3 2 1 # snd -noinit snd-test.rb 1 3 2 # etc. $test_functions.rand! end $test_functions.each do |func| before_test(func) snd_func(func) after_test(func) end finish_snd_test() clear_test_files exit(0) end if $with_test_nogui def snd_info(fmt, *args) clm_print("# %s\n", format(fmt, *args)) nil end else def snd_info(fmt, *args) str = format(fmt, *args) clm_print("\n# %s", str) $stderr.printf("# %s\n", str) nil end end if RUBY_VERSION >= "1.9" def snd_display_prev_caller(fmt, *args) if line = caller(2)[0].scan(/:(.*):in /).first snd_info("[%s] %s", line.first, format(fmt, *args)) else snd_info(fmt, *args) end end else def snd_display_prev_caller(fmt, *args) # Because ruby < 1.9 has a line number bug we use function name. if line = caller(2)[0].scan(/^.*:in `(.*)'/).first snd_info("[%s] %s", line.first, format(fmt, *args)) else snd_info(fmt, *args) end end end def snd_display(*args) if args.empty? snd_display_prev_caller("") else fmt = args.shift snd_display_prev_caller(fmt, *args) end end def snd_debug(*args) if args.empty? snd_display_prev_caller("#") else fmt = args.shift snd_display_prev_caller("#", format(fmt, *args)) end end def snd_test_format(sndfmt, res, req, fmt = "", *args) str = format(sndfmt, res, req) unless fmt.empty? str = format(fmt, *args) + ": " + str end str end def snd_format(res, req, op = "!=", fmt = "", *args) case req when Float snd_test_format("res %1.4f #{op} req %1.4f?", res, req, fmt, *args) when Vct, Array, Vec, Poly old_alen = mus_array_print_length() old_vlen = print_length() set_mus_array_print_length($info_array_print_length) set_print_length($info_array_print_length) if res.nil? res = "nil" end str = snd_test_format("res #{op} req?\n# => res %s\n# => req %s", res, req, fmt, *args) set_mus_array_print_length(old_alen) set_print_length(old_vlen) str else snd_test_format("res %s #{op} req %s?", res.inspect, req.inspect, fmt, *args) end end def snd_format_neq(res, req, fmt = "", *args) snd_format(res, req, "!=", fmt, *args) end def snd_format_eq(res, req, fmt = "", *args) snd_format(res, req, "==", fmt, *args) end def snd_test_equal?(res, req) case req when Float res.kind_of?(Numeric) and fequal?(res, req) when Vct, Vec, Poly vequal?(res, req) else res == req end end def snd_test_neq(res, req, fmt = "", *args) if snd_test_equal?(res, req) false else snd_display_prev_caller(snd_format(res, req, "!=", fmt, *args)) true end end def snd_test_eq(res, req, fmt = "", *args) if snd_test_equal?(res, req) snd_display_prev_caller(snd_format(res, req, "==", fmt, *args)) true else false end end # snd_test_any_neq(res, req, :ffequal?, "more info") def snd_test_any_neq(res, req, func, fmt = "", *args) if method(func).call(res, req) false else snd_display_prev_caller(snd_format(res, req, "!=", fmt, *args)) true end end # snd_test_any_eq(res, req, :ffequal?, "more info") def snd_test_any_eq(res, req, func, fmt = "", *args) if method(func).call(res, req) snd_display_prev_caller(snd_format(res, req, "==", fmt, *args)) true else false end end def snd_test_lt(res, req, fmt = "", *args) if res < req snd_display_prev_caller(snd_format(res, req, "<", fmt, *args)) true else false end end def snd_test_gt(res, req, fmt = "", *args) if res > req snd_display_prev_caller(snd_format(res, req, ">", fmt, *args)) true else false end end # command line args: last arg(s) may be zero or many test numbers # snd -noinit -load snd-test.rb 3 7 20 # only tests 3, 7, 20 # snd -noinit -load snd-test.rb -23 # all tests except 23 lambda do # non existent tests, non wanted tests (negative arguments like -23) # added here nargs = [22, 24, 25, 26, 27, 29] targs = [] if script_arg.positive? script_args[script_arg..-1].each do |arg| n = Snd.catch(:all, nil) do Integer(arg) end.first if integer?(n) if n < 0 nargs << n.abs elsif n <= 30 # test_30 for short tests targs << n end end end end if targs.empty? 29.times do |n| targs << n end end (targs - nargs).each do |n| $test_functions << format("test_%02d", n).intern end end.call def fneq_err(f1, f2, err = 0.001) (f1 - f2).abs > err end def fneq(a, b) fneq_err(a, b, 0.001) end def ffneq(a, b) fneq_err(a, b, 0.01) end def fffneq(a, b) fneq_err(a, b, 0.1) end def fequal_err(f1, f2, err = 0.001) (f1 - f2).abs <= err end def fequal?(a, b) fequal_err(a, b, 0.001) end def ffequal?(a, b) fequal_err(a, b, 0.01) end def fffequal?(a, b) fequal_err(a, b, 0.1) end # returns a vct or false # obj: Vct, Array, Vec, Poly def any2vct(obj) obj.respond_to?(:to_vct) and obj.to_vct end # compares Arrays and Vcts def vequal_err(val0, val1, err = 0.001) (v0 = any2vct(val0)) and (v1 = any2vct(val1)) and (v0.subtract(v1).peak <= err) end def vequal?(v0, v1) vequal_err(v0, v1, 0.001) end def vvequal?(v0, v1) vequal_err(v0, v1, 0.00002) end def vfequal?(v0, v1) vequal_err(v0, v1, 0.01) end def vffequal?(v0, v1) vequal_err(v0, v1, 0.1) end def vfffequal?(v0, v1) vequal_err(v0, v1, 0.5) end alias vequal vequal? alias vvequal vvequal? alias vfequal vfequal? alias vffequal vffequal? alias vfffequal vfffequal? def cneq(a, b) if number?(a) and number?(b) fneq(a.real, b.real) or fneq(a.imag, b.imag) else true end end def vcneql(a, b) if a.length != b.length true else a.each_with_index do |x, i| if cneq(x, b[i]) return true end end false end end def cequal?(a, b) if number?(a) and number?(b) fequal?(a.real, b.real) and fequal?(a.imag, b.imag) else false end end def vcequal?(a, b) if a.length != b.length false else a.each_with_index do |x, i| if cneq(x, b[i]) return false end end true end end alias cequal cequal? alias vcequal vcequal? def vmaxdiff(v0, v1) v0.dup.subtract(v1).peak end def list_p(obj) array?(obj) and (not obj.empty?) end def any_arity(obj) case obj when Proc, Method obj.arity when String, Symbol method(obj).arity else 0 end end def arity_ok(func, args) rargs = Snd.catch do any_arity(func) end.first if integer?(rargs) if rargs >= 0 args == rargs else args >= (rargs.abs - 1) # We have no idea how much optional args. end else false end end def set_arity_ok(func, args) arity_ok("set_#{func}", args) end if $with_test_nogui def dismiss_all_dialogs end else def dismiss_all_dialogs dialog_widgets.each do |dialog| if array?(dialog) if symbol?(dialog.car) if is_managed?(dialog) hide_widget(dialog) end else dialog.each do |d| if symbol?(d.car) if is_managed?(dialog) hide_widget(dialog) end end end end end end end end def safe_display_edits(snd = false, chn = false, edpos = false, with_src = true) Snd.catch(:all, lambda do |*args| snd_display_prev_caller("display_edits: %s", args) end) do display_edits(snd, chn, edpos, with_src) end.first end def safe_divide(a, b) b.zero? ? a : (a / b) end set_with_background_processes(false) def make_color_with_catch(c1, c2, c3) make_color(c1, c2, c3) rescue make_color(1, 0, 0) end def file_copy(f1, f2) if File.exist?(f1) fin = File.open(f1, "r") fout = File.open(f2, "w") fout.write(fin.read) until fin.eof? fin.close fout.close end end def delete_file(file) File.owned?(file) and File.unlink(file) end def delete_files(*files) files.each do |f| delete_file(f) end end def with_file(file, verbose = $DEBUG, &body) if File.exist?(full_name = $sf_dir + file) body.call(full_name) else if verbose snd_display_prev_caller("%s missing?", full_name) end end end def with_gc_disabled GC.disable ret = yield GC.enable GC.start ret end Snd_error_tags.each do |tag| res = Snd.catch(tag) do Snd.throw(tag, "snd-test") end if res.first != tag snd_display("Snd.catch (throwing 1): %s -> %s", tag.inspect, res.inspect) end res = Snd.catch(:all) do Snd.raise(tag, "snd-test") end if res.first != tag snd_display("Snd.catch (raising 1): %s -> %s", tag.inspect, res.inspect) end res = Snd.catch(tag, :okay) do Snd.throw(tag, "snd-test") end if res.first != :okay snd_display("Snd.catch (throwing 2): %s -> %s", tag.inspect, res.inspect) end res = Snd.catch(:all, :okay) do Snd.raise(tag, "snd-test") end if res.first != :okay snd_display("Snd.catch (raising 2): %s -> %s", tag.inspect, res.inspect) end end def cwd Dir.pwd + "/" end class Snd_test_time def initialize @real_time = Time.now @process_time = process_times @real = @utime = @stime = 0.0 end attr_reader :real, :utime, :stime def to_s format("real: %1.3f, user: %1.3f, system: %1.3f", @real, @utime, @stime) end def inspect format("#<%s: %s>", self.class, self.to_s) end def start @real_time = Time.now @process_time = process_times end def stop @real = Time.now - @real_time cur_time = process_times @utime = cur_time.utime - @process_time.utime @stime = cur_time.stime - @process_time.stime end end def with_time(msg = nil, &body) stt = Snd_test_time.new stt.start body.call stt.stop if msg and $VERBOSE snd_info("%s (%s)", stt.to_s, msg) end [stt.real, stt.utime, stt.stime] end def start_snd_test() # map_chan* procedure $init_channel = lambda do |y| 1.0 end $default_srate = 22050.0 $timings = Array.new(0) set_show_listener(true) set_window_x(600) set_window_y(10) kind = if $with_test_motif "motif" elsif $with_test_gtk "gtk" elsif $with_test_nogui "nogui" else "unknown" end snd_info("=== Snd version: %s (snd_%s)", snd_version, kind) snd_info("=== Ruby version: %s (%s) [%s]", RUBY_VERSION, RUBY_RELEASE_DATE, RUBY_PLATFORM) snd_info("") snd_info("%s", Time.now.localtime.strftime("%a %d-%b-%Y %I:%M %p")) snd_info("") $overall_start_time = Snd_test_time.new end def finish_snd_test() $overall_start_time.stop Snd.regions.apply(:forget_region) stop_playing reset_almost_all_hooks set_ask_about_unsaved_edits(false) set_remember_sound_state(false) snd_info("all done!") snd_info("") unless $timings.empty? $timings.each do |tst| snd_info("%s %s", tst.first, tst.last.inspect) end end snd_info("total %s\n", $overall_start_time.inspect) set_show_listener(true) save_listener("test-ruby.output") clear_listener set_show_listener(true) set_listener_prompt($original_prompt) end def clear_test_files fs = 0 [$original_save_dir, $original_temp_dir, "/tmp"].each do |path| if File.exist?(path) fs += Dir[path + "/snd_*"].length Dir[path + "/snd_*"].each do |f| delete_file(f) end end end snd_info("%s temporary file%s deleted", fs.zero? ? "no" : fs, fs.between?(0, 1) ? "" : "s") mus_sound_prune $snd_opened_sound = false ["1", "aaa.eps", "accelmap", "envs.save", "fmv.snd", "fmv.wav", "fmv0.snd", "fmv1.snd", "fmv2.snd", "fmv3.snd", "fmv4.reverb", "fmv4.snd", "gtk-errors", "hiho.marks", "hiho.rb", "hiho.snd", "hiho.snd", "hiho.tmp", "hiho.wave", "ho", "new.snd", "oboe.marks", "obtest.snd.stereo", "remembered-oboe.snd.rb", "saved-snd.rb", "snd.eps", "test-1.snd", "test-2.snd", "test-macros.scm", "test.aifc", "test.aiff", "test.data", "test.rev", "test.reverb", "test.rf64", "test.snd", "test.snd.snd", "test.wav", "test.wave", "test.xpm", "test1.snd", "test1.reverb", "test2.snd", "test3.snd", "tmp.snd", "with-mix.rbm", "with-mix.snd"].each do |file| delete_file(file) end ["bad_sample_type.snd.snd", "ce-c3.w02.snd", "hcom-16.snd.snd", "ieee-text-16.snd.snd", "mus10.snd.snd", "nasahal.avi.snd", "nist-shortpack.wav.snd", "o2_dvi.wave.snd", "oki.wav.snd", "trumps22.adp.snd", "wood.sds.snd"].each do |file| with_file(file, false) do delete_file(file) end end end def before_test(func) set_sync_style(Sync_none) set_mus_srate($clm_srate = $default_srate.to_i) set_clipping(false) set_mus_clipping(false) $timings.push([func, Snd_test_time.new]) snd_info("%s", func) end def after_test(func) $timings.last.last.stop if sounds snd_info("%s: open sounds: %s", func, short_file_name(true)) Snd.sounds.apply(:close_sound) end Snd.regions.apply(:forget_region) set_ask_about_unsaved_edits(false) set_remember_sound_state(false) dismiss_all_dialogs if $VERBOSE snd_info("%s done (%s)\n#", func, $timings.last.last) else snd_info("%s done\n#", func) end end # returns body's return value or error symbol (eg. :no_such_sound) def without_errors(&body) Snd.catch(:all) do body.call end.first end if $with_test_motif module Test_event # see event.scm def key_event(widget, key, state) e = RXEvent(RKeyPress) dpy = RXtDisplay(widget) window = RXtWindow(widget) Rset_type(e, RKeyPress) Rset_window(e, window) Rset_display(e, dpy) Rset_root(e, RRootWindow(dpy, RDefaultScreen(dpy))) Rset_x(e, 0) Rset_y(e, 0) Rset_x_root(e, 0) Rset_y_root(e, 0) Rset_keycode(e, RXKeysymToKeycode(dpy, [:KeySym, key_to_int(key)])) Rset_state(e, state) Rset_time(e, [:Time, RCurrentTime]) Rset_same_screen(e, true) Rset_subwindow(e, [:Window, RNone]) err = RXSendEvent(dpy, window, false, RKeyPressMask, e) if err.nonzero? Rset_type(e, RKeyRelease) Rset_time(e, [:Time, RCurrentTime]) err = RXSendEvent(dpy, window, false, RKeyReleaseMask, e) end if err.zero? snd_display("[key-event error] ", err) end err end def key_event_with_mouse(widget, key, state, x, y) e = RXEvent(RKeyPress) dpy = RXtDisplay(widget) window = RXtWindow(widget) Rset_type(e, RKeyPress) Rset_window(e, window) Rset_display(e, dpy) Rset_root(e, RRootWindow(dpy, RDefaultScreen(dpy))) Rset_x(e, x) Rset_y(e, y) Rset_x_root(e, x) Rset_y_root(e, y) Rset_keycode(e, RXKeysymToKeycode(dpy, [:KeySym, key_to_int(key)])) Rset_state(e, state) Rset_time(e, [:Time, RCurrentTime]) Rset_same_screen(e, true) Rset_subwindow(e, [:Window, RNone]) err = RXSendEvent(dpy, window, false, RKeyPressMask, e) if err.nonzero? Rset_type(e, RKeyRelease) Rset_time(e, [:Time, RCurrentTime]) err = RXSendEvent(dpy, window, false, RKeyReleaseMask, e) end if err.zero? snd_display("[key-event error] ", err) end err end def resize_event(widget, width, height) e = RXEvent(RResizeRequest) dpy = RXtDisplay(widget) window = RXtWindow(widget) Rset_window(e, window) Rset_display(e, dpy) Rset_width(e, width) Rset_height(e, height) RXSendEvent(dpy, window, false, RResizeRedirectMask, e) end def enter_event(widget) e = RXEvent(REnterNotify) dpy = RXtDisplay(widget) window = RXtWindow(widget) Rset_window(e, window) Rset_display(e, dpy) RXSendEvent(dpy, window, false, REnterWindowMask, e) end def leave_event(widget) e = RXEvent(RLeaveNotify) dpy = RXtDisplay(widget) window = RXtWindow(widget) Rset_window(e, window) Rset_display(e, dpy) RXSendEvent(dpy, window, false, RLeaveWindowMask, e) end def expose_event(widget, x, y, width, height) e = RXEvent(RExpose) dpy = RXtDisplay(widget) window = RXtWindow(widget) Rset_window(e, window) Rset_display(e, dpy) Rset_x(e, x) Rset_y(e, y) Rset_width(e, width) Rset_height(e, height) Rset_count(e, 0) RXSendEvent(dpy, window, false, RExposureMask, e) end def click_event(widget, button, state, x, y) e = RXEvent(RButtonPress) dpy = RXtDisplay(widget) window = RXtWindow(widget) Rset_type(e, RButtonPress) Rset_window(e, window) Rset_display(e, dpy) Rset_root(e, RRootWindow(dpy, RDefaultScreen(dpy))) Rset_x(e, x) Rset_y(e, y) Rset_x_root(e, 0) Rset_y_root(e, 0) Rset_state(e, state) Rset_button(e, button) Rset_time(e, [:Time, RCurrentTime]) Rset_same_screen(e, true) Rset_subwindow(e, [:Window, RNone]) err = RXSendEvent(dpy, window, false, RButtonPressMask, e) if err.nonzero? Rset_type(e, RButtonRelease) Rset_time(e, [:Time, RCurrentTime]) err = RXSendEvent(dpy, window, false, RButtonReleaseMask, e) end if err.zero? snd_display("[click-event error] ", err) end err end def drag_event(widget, button, state, x0, y0, x1, y1) e = RXEvent(RButtonPress) e1 = RXEvent(RMotionNotify) dpy = RXtDisplay(widget) window = RXtWindow(widget) Rset_type(e, RButtonPress) Rset_window(e, window) Rset_display(e, dpy) Rset_root(e, RRootWindow(dpy, RDefaultScreen(dpy))) Rset_x(e, x0) Rset_y(e, y0) Rset_x_root(e, 0) Rset_y_root(e, 0) Rset_state(e, state) Rset_button(e, button) Rset_time(e, [:Time, RCurrentTime]) Rset_same_screen(e, true) Rset_subwindow(e, [:Window, RNone]) err = RXSendEvent(dpy, window, false, RButtonPressMask, e) if err.nonzero? Rset_window(e1, window) Rset_display(e1, dpy) Rset_root(e1, RRootWindow(dpy, RDefaultScreen(dpy))) # Rset_x(e1, x1) # Rset_y(e1, y1) Rset_x_root(e1, x0) Rset_y_root(e1, y0) Rset_state(e1, state) Rset_time(e1, [:Time, RCurrentTime + 300]) Rset_same_screen(e1, true) Rset_subwindow(e1, [:Window, RNone]) Rset_is_hint(e1, RNotifyNormal) den = if (x1 - x0).abs > 10 or (y1 - y0).abs > 10 10 else 2 end xdiff = ((x1 - x0) / den.to_f).floor ydiff = ((y1 - y0) / den.to_f).floor xn = x0 + xdiff yn = y0 + ydiff den.times do Rset_x(e1, xn) Rset_y(e1, yn) RXSendEvent(dpy, window, false, RButtonMotionMask, e1) xn += xdiff yn += ydiff end Rset_type(e, RButtonRelease) Rset_time(e, [:Time, RCurrentTime + 500]) Rset_x(e, x1) Rset_y(e, y1) RXSendEvent(dpy, window, false, RButtonReleaseMask, e) end end def select_item(wid, pos) if RXmIsList(wid) RXmListSelectPos(wid, pos + 1, true) else snd_display("is not a list!", RXtName(wid)) end end def click_button(button, value = false, bits = false) if RWidget?(button) if RXtIsSensitive(button) if RXmIsPushButton(button) or RXmIsPushButtonGadget(button) if RXtHasCallbacks(button, RXmNactivateCallback) == RXtCallbackHasSome but = RXmPushButtonCallbackStruct() Rset_click_count(but, 0) e = RXEvent(RButtonPress) Rset_state(e, (bits or 0)) Rset_event(but, e) RXtCallCallbacks(button, RXmNactivateCallback, but) else snd_display("pushbutton %s has no active callbacks", RXtName(button)) end else if RXmIsToggleButton(button) or RXmIsToggleButtonGadget(button) if RXtHasCallbacks(button, RXmNvalueChangedCallback) == RXtCallbackHasSome tgl = RXmToggleButtonCallbackStruct() Rset_set(tgl, value) e = RXEvent(RButtonPress) Rset_state(e, (bits or 0)) Rset_event(tgl, e) RXtCallCallbacks(button, RXmNvalueChangedCallback, tgl) else snd_display("togglebutton %s has no valueChanged callbacks", RXtName(button)) end else if RXmIsArrowButton(button) if RXtHasCallbacks(button, RXmNactivateCallback) == RXtCallbackHasSome arr = RXmArrowButtonCallbackStruct() Rset_click_count(arr, 0) e = RXEvent(RButtonPress) Rset_state(e, (bits or 0)) Rset_event(arr, e) RXtCallCallbacks(button, RXmNactivateCallback, arr) else snd_display("arrowbutton %s has no active callbacks", RXtName(button)) end else snd_display("%s (%s) is not a push or toggle button", RXtName(button), RXtName(RXtParent(button))) end end end else snd_display("%s is not sensitive", RXtName(button)) end else snd_display("%s is not a widget", button) end end def resize_pane(wid, height) RXtUnmanageChild(wid) RXtVaSetValues(wid, [RXmNpaneMinimum, (height > 5 ? (height - 5) : 0), RXmNpaneMaximum, height + 5]) RXtManageChild(wid) RXtVaSetValues(wid, [RXmNpaneMinimum, 5, RXmNpaneMaximum, 1000]) end def force_event app = main_widgets.car msk = RXtIMXEvent | RXtIMAlternateInput until (RXtAppPending(app) & msk).zero? RXtDispatchEvent(RXtAppNextEvent(app)) end end def take_keyboard_focus(wid) if RXmIsTraversable(wid) and (RXmGetVisibility(wid) != RXmVISIBILITY_FULLY_OBSCURED) RXmProcessTraversal(wid, RXmTRAVERSE_CURRENT) end end def move_scale(scl, val) RXmScaleSetValue(scl, val) cb = RXmScaleCallbackStruct() Rset_value(cb, val) Rset_event(cb, RXEvent()) RXtCallCallbacks(scl, RXmNvalueChangedCallback, cb) end def change_prop(winat, name, command) find_window = lambda do |dpy, top, natom| res = RXGetWindowProperty(dpy, top, natom, 0, 1024, false, RXA_STRING) if res[0] == RSuccess and res[1] != [:Atom, RNone] top else vals = RXQueryTree(dpy, top) if vals[0].zero? false else vals[3].each do |win| if RWindow?(val = find_window.call(dpy, win, natom)) return val end end false end end end dpy = RXtDisplay(main_widgets[1]) natom = RXInternAtom(dpy, winat, false) window = find_window.call(dpy, RDefaultRootWindow(dpy), natom) if RWindow?(window) RXChangeProperty(dpy, window, RXInternAtom(dpy, name, false), RXA_STRING, 8, RPropModeReplace, command) RXFlush(dpy) command else false end end make_proc_with_setter(:beep_state, # return amp pitch duration lambda do vals = RXGetKeyboardControl(RXtDisplay(main_widgets.cadr))[1, 3] end, # amp pitch dur # set_beep_state([100, 200, 100]) lambda do |lst| RXChangeKeyboardControl(RXtDisplay(main_widgets.cadr), RKBBellPercent | RKBBellPitch | RKBBellDuration, [0] + lst) end) def beep RXBell(RXtDisplay(main_widgets.cadr), 100) end end include Test_event end # snd-test.scm translations # ---------------- test 00: constants ---------------- Tiny_font_string = $with_test_motif ? "6x12" : $with_test_gtk ? "Sans 8" : "9x15" Tiny_font_set_string = $with_test_motif ? "9x15" : $with_test_gtk ? "Monospace 10" : "6x12" # XXX: temp_dir save_dir ladspa_dir peak_env_dir # # These variables default to NULL (snd.c/snd-0.h). # snd-test.scm checks for #f # snd-test.rb checks for "" def test_00 if sounds or mixes or marks or regions snd_display("start up sounds: %s, mixes: %s, marks: %s, regions: %s", sounds.inspect, mixes.inspect, marks.inspect, regions.inspect) end [[:Enved_amplitude, 0], [:Bartlett_window, 4], [:Bartlett_hann_window, 21], [:Blackman2_window, 6], [:Blackman3_window, 7], [:Blackman4_window, 8], [:Blackman5_window, 24], [:Blackman6_window, 25], [:Blackman7_window, 26], [:Blackman8_window, 27], [:Blackman9_window, 28], [:Blackman10_window, 29], [:Bohman_window, 22], [:Cauchy_window, 12], [:Mlt_sine_window, 33], [:Papoulis_window, 34], [:Dpss_window, 35], [:Sinc_window, 36], [:Channels_combined, 1], [:Channels_separate, 0], [:Channels_superimposed, 2], [:Connes_window, 18], [:Cursor_in_middle, 3], [:Cursor_in_view, 0], [:Cursor_on_left, 1], [:Cursor_on_right, 2], [:Exponential_window, 9], [:Flat_top_window, 23], [:Sync_none, 0], [:Sync_all, 1], [:Sync_by_sound, 2], [:Zoom_focus_active, 2], [:Zoom_focus_left, 0], [:Zoom_focus_middle, 3], [:Zoom_focus_right, 1], [:Gaussian_window, 14], [:Graph_dots, 1], [:Graph_dots_and_lines, 3], [:Graph_filled, 2], [:Graph_lines, 0], [:Graph_lollipops, 4], [:Hamming_window, 5], [:Hann_window, 1], [:Hann_poisson_window, 17], [:Kaiser_window, 11], [:Keyboard_no_action, 4], [:Parzen_window, 3], [:Poisson_window, 13], [:Rectangular_window, 0], [:Riemann_window, 10], [:Rv2_window, 30], [:Rv3_window, 31], [:Rv4_window, 32], [:Graph_as_sonogram, 1], [:Graph_as_spectrogram, 2], [:Graph_once, 0], [:Graph_as_wavogram, 3], [:Enved_spectrum, 1], [:Speed_control_as_float, 0], [:Speed_control_as_ratio, 1], [:Speed_control_as_semitone, 2], [:Enved_srate, 2], [:Tukey_window, 15], [:Welch_window, 2], [:Cursor_cross, 0], [:Cursor_line, 1], [:Dont_normalize, 0], [:Envelope_linear, 0], [:Envelope_exponential, 1], [:Normalize_by_channel, 1], [:Normalize_by_sound, 2], [:Normalize_globally, 3], [:X_axis_in_samples, 1], [:X_axis_in_beats, 3], [:X_axis_in_measures, 4], [:X_axis_in_seconds, 0], [:X_axis_as_clock, 5], [:X_axis_as_percentage, 2], [:Enved_add_point, 0], [:Enved_delete_point, 1], [:Enved_move_point, 2], [:Time_graph, 0], [:Transform_graph, 1], [:Lisp_graph, 2], [:Copy_context, 0], [:Cursor_context, 3], [:Selection_context, 2], [:Mark_context, 4], [:Show_no_axes, 0], [:Show_all_axes, 1], [:Show_x_axis, 2], [:Show_all_axes_unlabelled, 3], [:Show_x_axis_unlabelled, 4], [:Show_bare_x_axis, 5], # sndlib constants [:Mus_unknown_header, 0], [:Mus_next, 1], [:Mus_aifc, 2], [:Mus_riff, 3], [:Mus_nist, 6], [:Mus_raw, 12], [:Mus_ircam, 15], [:Mus_aiff, 49], [:Mus_bicsf, 5], [:Mus_voc, 10], [:Mus_svx, 9], [:Mus_soundfont, 26], [:Mus_rf64, 4], [:Mus_caff, 60], # [:Mus_interp_none, 0], [:Mus_interp_linear, 1], [:Mus_interp_sinusoidal, 2], [:Mus_interp_all_pass, 3], [:Mus_interp_lagrange, 4], [:Mus_interp_bezier, 5], [:Mus_interp_hermite, 6], # [:Mus_chebyshev_first_kind, 1], [:Mus_chebyshev_second_kind, 2], # [:Mus_unknown_sample, 0], [:Mus_bshort, 1], [:Mus_lshort, 10], [:Mus_mulaw, 2], [:Mus_alaw, 6], [:Mus_byte, 3], [:Mus_ubyte, 7], [:Mus_bfloat, 4], [:Mus_lfloat, 12], [:Mus_bint, 5], [:Mus_lint, 11], [:Mus_bintn, 17], [:Mus_lintn, 18], [:Mus_b24int, 8], [:Mus_l24int, 16], [:Mus_bdouble, 9], [:Mus_ldouble, 13], [:Mus_ubshort, 14], [:Mus_ulshort, 15], [:Mus_bfloat_unscaled, 19], [:Mus_lfloat_unscaled, 20], [:Mus_bdouble_unscaled, 21], [:Mus_ldouble_unscaled, 22]].each do |sym, req| snd_test_neq(Module.const_get(sym), req, "%s", sym) end if $with_test_gsl [[:Dolph_chebyshev_window, 16], [:Samaraki_window, 19], [:Ultraspherical_window, 20]].each do |sym, req| snd_test_neq(Module.const_get(sym), req, "%s", sym) end end # old_dir = temp_dir set_temp_dir(false) [[:region_graph_style, Graph_lines], [:ask_about_unsaved_edits, false], [:show_full_duration, false], [:show_full_range, false], [:initial_beg, 0.0], [:initial_dur, 0.1], [:ask_before_overwrite, false], [:auto_resize, true], [:auto_update, false], [:channel_style, 1], [:color_cutoff, 0.003], [:color_inverted, true], [:color_scale, 1.0], [:auto_update_interval, 60.0], [:cursor_update_interval, 0.05], [:cursor_location_offset, 0], [:dac_combines_channels, true], [:dac_size, 256], [:clipping, false], [:default_output_chans, 1], [:default_output_sample_type, Mus_lfloat], [:default_output_srate, 44100], [:default_output_header_type, Mus_next], [:dot_size, 1], [:cursor_size, 15], [:cursor_style, Cursor_cross], [:tracking_cursor_style, Cursor_line], [:enved_base, 1.0], [:enved_clip?, true], [:enved_filter, true], [:enved_filter_order, 40], [:enved_in_dB, false], [:enved_style, Envelope_linear], [:enved_power, 3.0], [:enved_target, 0], [:enved_wave?, false], [:enved_envelope, nil], [:eps_file, "snd.eps"], [:eps_bottom_margin, 0.0], [:eps_left_margin, 0.0], [:eps_size, 1.0], [:fft_window_alpha, 0.0], [:fft_window_beta, 0.0], [:fft_log_frequency, false], [:fft_log_magnitude, false], [:fft_with_phases, false], [:transform_size, 512], [:transform_graph_type, Graph_once], [:fft_window, 6], [:graph_cursor, 34], [:graph_style, Graph_lines], [:graphs_horizontal, true], [:html_dir, "."], [:html_program, "firefox"], [:just_sounds, true], [:listener_prompt, ">"], [:max_transform_peaks, 100], [:max_regions, 16], [:min_dB, -60.0], [:log_freq_start, 32.0], [:selection_creates_region, true], [:transform_normalization, Normalize_by_channel], [:print_length, 12], [:play_arrow_size, 10], [:save_state_file, "saved-snd.rb"], [:show_axes, 1], [:show_transform_peaks, false], [:show_indices, false], [:show_marks, true], [:show_mix_waveforms, true], [:show_selection_transform, false], [:show_y_zero, false], [:show_grid, false], [:grid_density, 1.0], [:show_sonogram_cursor, false], [:sinc_width, 10], [:spectrum_end, 1.0], [:spectro_hop, 4], [:spectrum_start, 0.0], [:spectro_x_angle, ($with_test_gl ? 300.0 : 90.0)], [:spectro_x_scale, ($with_test_gl ? 1.5 : 1.0)], [:spectro_y_angle, ($with_test_gl ? 320.0 : 0.0)], [:spectro_y_scale, 1.0], [:spectro_z_angle, ($with_test_gl ? 0.0 : 358.0)], [:spectro_z_scale, ($with_test_gl ? 1.0 : 0.1)], [:temp_dir, ""], [:ladspa_dir, ""], [:peak_env_dir, ""], [:tiny_font, Tiny_font_string], [:transform_type, $fourier_transform], [:with_file_monitor, true], [:clm_table_size, 512], [:clm_default_frequency, 0.0], [:with_verbose_cursor, false], [:with_inset_graph, false], [:with_interrupts, true], [:remember_sound_state, false], [:with_smpte_label, false], [:with_toolbar, ($with_test_gtk ? true : false)], [:with_tooltips, true], [:with_menu_icons, false], [:save_as_dialog_src, false], [:save_as_dialog_auto_comment, false], [:with_pointer_focus, false], [:wavelet_type, 0], [:time_graph_type, Graph_once], [:wavo_hop, 3], [:wavo_trace, 64], [:x_axis_style, 0], [:beats_per_minute, 60.0], [:beats_per_measure, 4], [:zero_pad, 0], [:zoom_focus_style, 2], [:sync_style, Sync_by_sound], [:mix_waveform_height, 20], [:mix_tag_width, 6], [:mix_tag_height, 14], [:mark_tag_width, 10], [:mark_tag_height, 4]].each do |sym, req| snd_test_neq(set_snd_func(sym, snd_func(sym)), req, "set_%s", sym) end set_temp_dir(old_dir) # set_max_transform_peaks(-123) set_zero_pad(-123) [[:max_transform_peaks, 100], [:zero_pad, 0]].each do |sym, req| snd_test_neq(set_snd_func(sym, snd_func(sym)), req, "set_%s", sym) end snd_test_neq(zero_pad(true, true), nil, "zero_pad(true, true)") if $with_test_motif [:axis_label_font, :axis_numbers_font, :tiny_font, :peaks_font, :bold_peaks_font].each do |sym| req = snd_func(sym) snd_test_neq(set_snd_func(sym, "8x123"), req, "set_%s to bogus value", sym) end end set_ask_about_unsaved_edits(false) set_remember_sound_state(false) end # ---------------- test 01: defaults ---------------- $good_colormap = $hot_colormap $better_colormap = $black_and_white_colormap def test_01 if $with_test_gui unless colormap?($good_colormap) $good_colormap = false (1..20).each do |i| col = integer2colormap(i) if colormap?(col) $good_colormap = col break end end end unless colormap?($better_colormap) $better_colormap = false (colormap2integer($good_colormap)..20).each do |i| col = integer2colormap(i) if colormap?(col) $better_colormap = col break end end end end # old_dir = temp_dir set_temp_dir(false) [["amp_control", without_errors do amp_control() end, :no_such_sound], ["amp_control_bounds", amp_control_bounds()[1], 8.0], ["ask_about_unsaved_edits", ask_about_unsaved_edits(), false], ["ask_before_overwrite", ask_before_overwrite(), false], ["auto_resize", auto_resize(), true], ["auto_update", auto_update(), false], ["auto_update_interval", auto_update_interval(), 60.0], ["beats_per_measure", beats_per_measure(), 4], ["beats_per_minute", beats_per_minute(), 60.0], ["channel_style", channel_style(), 1], ["clipping", clipping(), false], ["clm_table_size", clm_table_size(), 512], ["clm_default_frequency", clm_default_frequency(), 0.0], ["color_cutoff", color_cutoff(), 0.003], ["color_inverted", color_inverted(), true], ["color_scale", color_scale(), 1.0], ["colormap", colormap(), $good_colormap], ["contrast_control", without_errors do contrast_control() end, :no_such_sound], ["contrast_control_amp", contrast_control_amp(), 1.0], ["contrast_control_bounds", contrast_control_bounds()[1], 10.0], ["contrast_control?", without_errors do contrast_control?() end, :no_such_sound], ["with_tracking_cursor", with_tracking_cursor(), false], ["cursor_location_offset", cursor_location_offset(), 0], ["cursor_size", cursor_size(), 15], ["cursor_style", cursor_style(), Cursor_cross], ["cursor_update_interval", cursor_update_interval(), 0.05], ["dac_combines_channels", dac_combines_channels(), true], ["dac_size", dac_size(), 256], ["default_output_chans", default_output_chans(), 1], ["default_output_sample_type", default_output_sample_type(), Mus_lfloat], ["default_output_header_type", default_output_header_type(), Mus_next], ["default_output_srate", default_output_srate(), 44100], ["dot_size", dot_size(), 1], ["enved_base", enved_base(), 1.0], ["enved_clip?", enved_clip?(), true], ["enved_envelope", enved_envelope(), nil], ["enved_filter", enved_filter(), true], ["enved_filter_order", enved_filter_order(), 40], ["enved_in_dB", enved_in_dB(), false], ["enved_power", enved_power(), 3.0], ["enved_style", enved_style(), Envelope_linear], ["enved_target", enved_target(), 0], ["enved_wave?", enved_wave?(), false], ["eps_bottom_margin", eps_bottom_margin(), 0.0], ["eps_file", eps_file(), "snd.eps"], ["eps_left_margin", eps_left_margin(), 0.0], ["eps_size", eps_size(), 1.0], ["expand_control", without_errors do expand_control() end, :no_such_sound], ["expand_control_bounds", expand_control_bounds()[1], 20.0], ["expand_control_hop", expand_control_hop(), 0.05], ["expand_control_jitter", expand_control_jitter(), 0.1], ["expand_control_length", expand_control_length(), 0.15], ["expand_control_ramp", expand_control_ramp(), 0.4], ["expand_control?", without_errors do expand_control?() end, :no_such_sound], ["fft_log_frequency", fft_log_frequency(), false], ["fft_log_magnitude", fft_log_magnitude(), false], ["fft_with_phases", fft_with_phases(), false], ["fft_window", fft_window(), 6], ["fft_window_alpha", fft_window_alpha(), 0.0], ["fft_window_beta", fft_window_beta(), 0.0], ["filter_control_coeffs", without_errors do filter_control_coeffs() end, :no_such_sound], ["filter_control_envelope", without_errors do filter_control_envelope() end, :no_such_sound], ["filter_control_in_dB", filter_control_in_dB(), false], ["filter_control_in_hz", filter_control_in_hz(), false], ["filter_control_order", filter_control_order(), 20], ["filter_control?", without_errors do filter_control?() end, :no_such_sound], ["graph_cursor", graph_cursor(), 34], ["graph_style", graph_style(), Graph_lines], ["graphs_horizontal", graphs_horizontal(), true], ["grid_density", grid_density(), 1.0], ["html_dir", html_dir(), "."], ["html_program", html_program(), "firefox"], ["initial_beg", initial_beg(), 0.0], ["initial_dur", initial_dur(), 0.1], ["just_sounds", just_sounds(), true], ["ladspa_dir", ladspa_dir(), ""], ["peak_env_dir", peak_env_dir(), ""], ["lisp_graph?", without_errors do lisp_graph?() end, :no_such_sound], ["listener_prompt", listener_prompt(), ">"], ["log_freq_start", log_freq_start(), 32.0], ["mark_tag_height", mark_tag_height(), 4], ["mark_tag_width", mark_tag_width(), 10], ["max_regions", max_regions(), 16], ["max_transform_peaks", max_transform_peaks(), 100], ["min_dB", min_dB(), -60.0], ["mix_tag_height", mix_tag_height(), 14], ["mix_tag_width", mix_tag_width(), 6], ["mix_waveform_height", mix_waveform_height(), 20], ["mus_array_print_length", mus_array_print_length(), 8], ["mus_clipping", mus_clipping(), false], ["mus_float_equal_fudge_factor", mus_float_equal_fudge_factor(), 0.0000001], ["play_arrow_size", play_arrow_size(), 10], ["print_length", print_length(), 12], ["read_only", without_errors do read_only() end, :no_such_sound], ["region_graph_style", region_graph_style(), Graph_lines], ["remember_sound_state", remember_sound_state(), false], ["reverb_control_feedback", reverb_control_feedback(), 1.09], ["reverb_control_length", without_errors do reverb_control_length() end, :no_such_sound], ["reverb_control_length_bounds", reverb_control_length_bounds()[1], 5.0], ["reverb_control_lowpass", reverb_control_lowpass(), 0.7], ["reverb_control_scale", without_errors do reverb_control_scale() end, :no_such_sound], ["reverb_control_scale_bounds", reverb_control_scale_bounds()[1], 4.0], ["reverb_control?", without_errors do reverb_control?() end, :no_such_sound], ["save_as_dialog_auto_comment", save_as_dialog_auto_comment, false], ["save_as_dialog_src", save_as_dialog_src, false], ["save_state_file", save_state_file(), "saved-snd.rb"], ["selection_creates_region", selection_creates_region(), true], ["show_axes", show_axes(), 1], ["show_controls", show_controls(), false], ["show_full_duration", show_full_duration(), false], ["show_full_range", show_full_range(), false], ["show_grid", show_grid(), false], ["show_indices", show_indices(), false], ["show_marks", show_marks(), true], ["show_mix_waveforms", show_mix_waveforms(), true], ["show_selection_transform", show_selection_transform(), false], ["show_sonogram_cursor", show_sonogram_cursor(), false], ["show_transform_peaks", show_transform_peaks(), false], ["show_y_zero", show_y_zero(), false], ["sinc_width", sinc_width(), 10], ["spectrum_end", spectrum_end(), 1.0], ["spectro_hop", spectro_hop(), 4], ["spectrum_start", spectrum_start(), 0.0], ["spectro_x_angle", spectro_x_angle(), ($with_test_gl ? 300.0 : 90.0)], ["spectro_x_scale", spectro_x_scale(), ($with_test_gl ? 1.5 : 1.0)], ["spectro_y_angle", spectro_y_angle(), ($with_test_gl ? 320.0 : 0.0)], ["spectro_y_scale", spectro_y_scale(), 1.0], ["spectro_z_angle", spectro_z_angle(), ($with_test_gl ? 0.0 : 358.0)], ["spectro_z_scale", spectro_z_scale(), ($with_test_gl ? 1.0 : 0.1)], ["speed_control", without_errors do speed_control() end, :no_such_sound], ["speed_control_bounds", speed_control_bounds()[1], 20.0], ["sync", without_errors do sync() end, :no_such_sound], ["sync_style", sync_style(), Sync_by_sound], ["temp_dir", temp_dir(), ""], ["time_graph_type", time_graph_type(), Graph_once], ["time_graph?", without_errors do time_graph?() end, :no_such_sound], ["tiny_font", tiny_font(), Tiny_font_string], ["tracking_cursor_style", tracking_cursor_style(), Cursor_line], ["transform_graph_type", transform_graph_type(), Graph_once], ["transform_graph?", without_errors do transform_graph?() end, :no_such_sound], ["transform_normalization", transform_normalization(), Normalize_by_channel], ["transform_size", transform_size(), 512], ["transform_type", transform_type(), $fourier_transform], ["wavelet_type", wavelet_type(), 0], ["wavo_hop", wavo_hop(), 3], ["wavo_trace", wavo_trace(), 64], ["with_mix_tags", with_mix_tags(), true], ["with_relative_panes", with_relative_panes(), true], ["with_tracking_cursor", with_tracking_cursor(), false], ["with_verbose_cursor", with_verbose_cursor(), false], ["with_inset_graph", with_inset_graph(), false], ["with_interrupts", with_interrupts(), true], ["with_smpte_label", with_smpte_label, false], ["with_toolbar", with_toolbar, ($with_test_gtk ? true : false)], ["with_tooltips", with_tooltips, true], ["with_menu_icons", with_menu_icons, false], ["with_pointer_focus", with_pointer_focus(), false], ["x_axis_style", x_axis_style(), 0], ["zero_pad", zero_pad(), 0], ["zoom_focus_style", zoom_focus_style(), 2]].each do |name, res, req| snd_test_neq(res, req, name) end set_temp_dir(old_dir) snd_test_neq($snd_opened_sound, false, "$snd_opened_sound") set_ask_about_unsaved_edits(false) set_remember_sound_state(false) end # ---------------- test 02: headers ---------------- def test_headers(name, chns, sr, dur, typ, frm, loop_start = false, loop_end = false) if File.exist?(name) file = name else file = $sf_dir + name end if File.exist?(file) fchns = mus_sound_chans(file) fsr = mus_sound_srate(file) fdur = mus_sound_duration(file) if fchns != chns snd_display_prev_caller(snd_format_neq(fchns, chns, "%s chans", name)) end if fsr != sr snd_display_prev_caller(snd_format_neq(fsr, sr, "%s srate", name)) end if fneq(fdur, dur) snd_display_prev_caller(snd_format_neq(fdur, dur, "%s duration", name)) end ffrm = mus_sound_sample_type(file) ftyp = mus_sound_header_type(file) req = mus_sound_length(file) res = mus_sound_datum_size(file) * fdur * fsr * fchns if (ffrm != Mus_unknown_sample) and (ftyp != 27) and (req + 1) < res snd_display_prev_caller(snd_format_neq(res, req, "%s length", name)) end fframples = mus_sound_framples(file) res = fframples.to_f / fsr if fneq(res, fdur) snd_display_prev_caller(snd_format_neq(res, fdur, "%s framples", name)) end fsamps = mus_sound_samples(file) res = fframples - fsamps / fchns if res.abs > 1 snd_display_prev_caller(snd_format_neq(res, fsamps, "%s samples", name)) end res = mus_header_type_name(ftyp) if res != typ snd_display_prev_caller(snd_format_neq(res, typ, "%s type", name)) end res = mus_sample_type_name(ffrm) if res != frm snd_display_prev_caller(snd_format_neq(res, frm, "%s format", name)) end lst = mus_sound_loop_info(file) if loop_start and loop_end if (not lst.nil?) and lst.length > 1 if lst[0] != loop_start snd_display_prev_caller(snd_format_neq(lst[0], loop_start, "%s loop start", name)) end if lst[1] != loop_end snd_display_prev_caller(snd_format_neq(lst[1], loop_end, "%s loop end", name)) end else snd_display_prev_caller("%s loop info empty: %s?", name, lst.inspect) end else unless lst.nil? snd_display_prev_caller("%s thinks it has loop info: %s?", name, lst) end end mus_sound_forget(file) else if $DEBUG snd_display_prev_caller("%s missing?", file) end end end def test_02 test_headers("5_secs.aiff", 1, 44100, 5.303107, "AIFF", "big endian short (16 bits)") test_headers("8svx-8.snd", 1, 22050, 1.88766443729401, "SVX8", "signed byte (8 bits)") test_headers("Fnonull.aif", 1, 8000, 0.00112499995157123, "AIFC", "mulaw (8 bits)") test_headers("Pmiscck.aif", 1, 8000, 0.00112499995157123, "AIFC", "mulaw (8 bits)") test_headers("Pmiscck.wav", 1, 8000, 0.00112499995157123, "RIFF", "mulaw (8 bits)") test_headers("Poffset.aif", 1, 8000, 0.00112499995157123, "AIFC", "mulaw (8 bits)") test_headers("Porder.aif", 1, 8000, 0.00112499995157123, "AIFC", "mulaw (8 bits)") test_headers("Ptjunk.aif", 1, 8000, 0.00112499995157123, "AIFC", "mulaw (8 bits)") test_headers("Ptjunk.wav", 1, 8000, 0.00112499995157123, "RIFF", "mulaw (8 bits)") test_headers("SINE24-S.WAV", 2, 44100, 2.0, "RIFF", "little endian int (24 bits)") test_headers("a1.asf", 1, 16000, 3.736562, "asf", "unknown") test_headers("a2.asf", 1, 8000, 4.630625, "asf", "unknown") test_headers("addf8.afsp", 1, 8000, 2.9760000705719, "Sun/Next", "big endian short (16 bits)") test_headers("addf8.d", 1, 8000, 2.9760000705719, "SPPACK", "big endian short (16 bits)") test_headers("addf8.dwd", 1, 8000, 2.976000071, "DiamondWare", "little endian short (16 bits)") test_headers("addf8.nh", 2, 44100, 0.269931972, "raw (no header)", "big endian short (16 bits)") test_headers("addf8.sd", 1, 8000, 2.9760000705719, "ESPS", "big endian short (16 bits)") test_headers("addf8.sf_mipseb", 1, 8000, 2.9760000705719, "IRCAM", "big endian short (16 bits)") test_headers("addf8.sf_sun", 1, 8000, 2.9760000705719, "IRCAM", "big endian short (16 bits)") test_headers("addf8.sf_vax_b", 1, 8000, 2.9760000705719, "IRCAM", "big endian short (16 bits)") test_headers("addf8.wav", 1, 8000, 2.9760000705719, "RIFF", "little endian short (16 bits)") test_headers("aebass.krz", 1, 44100, 3.0, "Kurzweil 2000", "big endian short (16 bits)") test_headers("aiff-16.snd", 2, 44100, 0.746666669845581, "AIFF", "big endian short (16 bits)") test_headers("aiff-8.snd", 2, 44100, 0.746666669845581, "AIFF", "signed byte (8 bits)") test_headers("alaw.aifc", 1, 44100, 0.0367800444364548, "AIFC", "alaw (8 bits)") test_headers("alaw.wav", 1, 11025, 8.70666694641113, "RIFF", "alaw (8 bits)") test_headers("astor_basia.mp2", 2, 44100, 1.022,"raw (no header)", "big endian short (16 bits)") test_headers("c.asf", 1, 8000, 21.368126, "asf", "unknown") test_headers("ce-c3.w02", 1, 33000, 3.88848495483398, "TX-16W", "unknown") test_headers("ce-c4.w03", 1, 33000, 2.91618180274963, "TX-16W", "unknown") test_headers("ce-d2.w01", 1, 33000, 3.46439385414124, "TX-16W", "unknown") test_headers("clbonef.wav", 1, 22050, 2.57832193374634, "RIFF", "little endian float (32 bits)") test_headers("cranker.krz", 1, 44100, 3.48267579, "Kurzweil 2000", "big endian short (16 bits)") test_headers("d40130.aif", 1, 10000, 0.100000001490116, "AIFF", "big endian short (16 bits)") test_headers("d40130.au", 1, 10000, 0.100000001490116, "Sun/Next", "big endian short (16 bits)") test_headers("d40130.dsf", 1, 8000, 0.125, "Delusion", "little endian short (16 bits)") test_headers("d40130.fsm", 1, 8000, 0.12524999678, "Farandole", "little endian short (16 bits)") test_headers("d40130.iff", 1, 10000, 0.100000001490116, "SVX8", "signed byte (8 bits)") test_headers("d40130.pat", 1, 10000, 0.100000001490116, "Gravis Ultrasound patch", "little endian short (16 bits)") test_headers("d40130.sds", 1, 10000, 0.100000001490116, "MIDI sample dump", "unknown") test_headers("d40130.sdx", 1, 10000, 0.100000001490116, "Sample dump", "unsigned little endian short (16 bits)") test_headers("d40130.sf", 1, 10000, 0.100000001490116, "IRCAM", "little endian short (16 bits)") test_headers("d40130.smp", 1, 8000, 0.125, "SMP", "little endian short (16 bits)") test_headers("d40130.sou", 1, 8000, 0.125, "SBStudioII", "little endian short (16 bits)") test_headers("d40130.st3", 1, 8000, 0.125, "Digiplayer ST3", "unsigned little endian short (16 bits)") test_headers("d40130.uwf", 1, 8000, 0.1252499, "Ultratracker", "little endian short (16 bits)") test_headers("d40130.voc", 1, 10000, 0.100100003182888, "VOC", "unsigned byte (8 bits)") test_headers("d40130.w00", 1, 16000, 0.0625, "TX-16W", "unknown") test_headers("d40130.wav", 1, 10000, 0.100000001490116, "RIFF", "little endian short (16 bits)") test_headers("d43.wav", 1, 10000, 0.100000001490116, "RIFF", "little endian short (16 bits)") test_headers("digit0v0.aiff", 1, 8000, 0.560000002384186, "AIFC", "big endian short (16 bits)") test_headers("esps-16.snd", 1, 8000, 3.09737491607666, "ESPS", "big endian short (16 bits)") test_headers("forest.aiff", 2, 44100, 3.907143, "AIFF", "big endian short (16 bits)", 24981, 144332) test_headers("g721.au", 1, 11025, 4.35328817367554, "Sun/Next", "unknown") test_headers("g722.aifc", 1, 44100, 0.0184353739023209, "AIFC", "unknown") test_headers("gong.wve", 1, 8000, 3.96799993515015, "PSION", "alaw (8 bits)") test_headers("gsm610.wav", 1, 11025, 1.7687075138092, "RIFF", "unknown") test_headers("inrs-16.snd", 1, 8000, 2.46399998664856, "INRS", "little endian short (16 bits)") test_headers("kirk.wve", 1, 8000, 1.40799999237061, "PSION", "alaw (8 bits)") test_headers("loop.aiff", 1, 44100, 0.0367120169103146, "AIFC", "big endian short (16 bits)", 12, 23) test_headers("m.asf", 1, 8000, 64.964622, "asf", "unknown") test_headers("mary-sun4.sig", 1, 8000, 4.47612476348877, "Comdisco SPW signal", "big endian double (64 bits)") test_headers("mocksong.wav", 1, 11025, 7.869569301605, "RIFF", "little endian short (16 bits)") test_headers("mono24.wav", 1, 22050, 1.98997735977173, "RIFF", "little endian int (24 bits)") test_headers("msadpcm.wav", 1, 11025, 4.43501138687134, "RIFF", "unknown") test_headers("n8.snd", 1, 44100, 0.0367800444364548, "Sun/Next", "signed byte (8 bits)") test_headers("nasahal.aif", 1, 11025, 9.89841270446777, "AIFF", "signed byte (8 bits)") test_headers("nasahal.avi", 1, 11025, 10.432744, "AVI", "little endian short (16 bits)") test_headers("nasahal.dig", 1, 11025, 9.8984, "Sound Designer 1", "big endian short (16 bits)") test_headers("nasahal.ivc", 2, 44100, 0.449, "raw (no header)", "big endian short (16 bits)") test_headers("nasahal.pat", 1, 11025, 3.95410442352295, "Gravis Ultrasound patch", "unsigned byte (8 bits)") test_headers("nasahal.snd", 1, 11025, 9.89841270446777, "SNDT", "unsigned byte (8 bits)") test_headers("nasahal.svx", 1, 11025, 9.89841270446777, "SVX8", "signed byte (8 bits)") test_headers("nasahal.v8", 1, 8000, 13.6412496566772, "Covox V8", "unsigned byte (8 bits)") test_headers("nasahal.voc", 1, 11025, 9.89941024780273, "VOC", "unsigned byte (8 bits)") test_headers("nasahal.vox", 2, 44100, 0.22444, "raw (no header)", "big endian short (16 bits)") test_headers("nasahal8.wav", 1, 11025, 9.89841270446777, "RIFF", "unsigned byte (8 bits)") test_headers("nasahalad.smp", 1, 11025, 4.94920635223389, "Goldwave sample", "little endian short (16 bits)") test_headers("next-16.snd", 1, 22050, 1.00004529953003, "Sun/Next", "big endian short (16 bits)") test_headers("next-8.snd", 1, 22050, 0.226757362484932, "Sun/Next", "signed byte (8 bits)") test_headers("next-dbl.snd", 1, 22050, 0.226757362484932, "Sun/Next", "big endian double (64 bits)") test_headers("oboe.ldbl", 1, 22050, 2.30512475967407, "RIFF", "little endian double (64 bits)") test_headers("next-flt.snd", 1, 22050, 0.226757362484932, "Sun/Next", "big endian float (32 bits)") test_headers("aifc-float.snd", 1, 22050, 0.2267573624849, "AIFC", "big endian float (32 bits)") test_headers("next-mulaw.snd", 1, 8012, 2.03295063972473, "Sun/Next", "mulaw (8 bits)") test_headers("next24.snd", 1, 44100, 0.0367800444364548, "Sun/Next", "big endian int (24 bits)") test_headers("nist-01.wav", 1, 16000, 2.26912498474121, "NIST", "little endian short (16 bits)") test_headers("nist-10.wav", 1, 16000, 2.26912498474121, "NIST", "big endian short (16 bits)") test_headers("nist-16.snd", 1, 16000, 1.02400004863739, "NIST", "big endian short (16 bits)") test_headers("nist-shortpack.wav", 1, 16000, 4.53824996948242, "NIST", "unknown") test_headers("none.aifc", 1, 44100, 0.0367800444364548, "AIFC", "big endian short (16 bits)") test_headers("nylon2.wav", 2, 22050, 1.14376413822174, "RIFF", "unknown") test_headers("o2.adf", 1, 44100, 0.036780, "CSRE adf", "little endian short (16 bits)") test_headers("o2.avr", 1, 44100, 0.0183900222182274, "AVR", "big endian short (16 bits)") test_headers("o2.bicsf", 1, 44100, 0.0367800444364548, "IRCAM", "big endian short (16 bits)") test_headers("o2.mpeg1", 2, 44100, 0.0070975, "raw (no header)", "big endian short (16 bits)") test_headers("o2.sd2", 2, 44100, 0.0183900222, "raw (no header)", "big endian short (16 bits)") test_headers("o2.sf2", 1, 44100, 0.036780044436, "SoundFont", "little endian short (16 bits)") test_headers("o2.smp", 1, 8000, 0.202749997377396, "SMP", "little endian short (16 bits)") test_headers("o2.voc", 1, 44100, 0.0368934236466885, "VOC", "little endian short (16 bits)") test_headers("o2.wave", 1, 44100, 0.0367800444364548, "RIFF", "little endian short (16 bits)") test_headers("o2_12bit.aiff", 1, 44100, 0.036780044436, "AIFF", "big endian short (16 bits)") test_headers("o2_18bit.aiff", 1, 44100, 0.0367800444364548, "AIFF", "big endian int (24 bits)") test_headers("o2_711u.wave", 1, 44100, 0.0367800444364548, "RIFF", "mulaw (8 bits)") test_headers("o2_722.snd", 1, 44100, 0.0183900222182274, "Sun/Next", "unknown") test_headers("o2_726.aiff", 1, 8000, 0.0367499999701977, "AIFC", "unknown") test_headers("o2_726.snd", 1, 44100, 0.0230158735066652, "Sun/Next", "unknown") test_headers("o2_728.aiff", 1, 8000, 0.0367499999701977, "AIFC", "unknown") test_headers("o2_8.iff", 1, 44100, 0.0367800444364548, "SVX8", "signed byte (8 bits)") test_headers("o2_8.voc", 1, 44100, 0.0370294786989689, "VOC", "unsigned byte (8 bits)") test_headers("o2_dvi.wave", 1, 44100, 0.0232199542224407, "RIFF", "unknown") test_headers("o2_float.bicsf", 1, 44100, 0.0367800444, "IRCAM", "big endian float (32 bits)") test_headers("o2_gsm.aiff", 1, 8000, 0.0367499999701977, "AIFC", "unknown") test_headers("o2_u8.avr", 1, 44100, 0.0367800444364548, "AVR", "unsigned byte (8 bits)") test_headers("o2_u8.wave", 1, 44100, 0.0367800444364548, "RIFF", "unsigned byte (8 bits)") test_headers("o28.mpc", 1, 44100, 0.036780, "AKAI 4", "little endian short (16 bits)") test_headers("oboe.kts", 1, 22050, 2.305125, "Korg", "big endian short (16 bits)") test_headers("oboe.its", 1, 22050, 2.305125, "Impulse Tracker", "little endian short (16 bits)") test_headers("oboe.sf2", 1, 22050, 2.305124759674, "SoundFont", "little endian short (16 bits)") test_headers("oboe.paf", 1, 22050, 2.305125, "Ensoniq Paris", "big endian short (16 bits)") test_headers("oboe.pf1", 1, 22050, 2.305125, "Ensoniq Paris", "little endian short (16 bits)") test_headers("oboe.smp", 1, 22050, 2.305125, "snack SMP", "little endian short (16 bits)") test_headers("oboe.rf64", 1, 22050, 2.305125, "rf64", "little endian short (16 bits)") test_headers("oboe-be32.caf", 1, 22050, 2.305125, "caff", "normalized big endian int (32 bits)") test_headers("oboe-bf64.caf", 1, 22050, 2.305125, "caff", "big endian double (64 bits)") test_headers("oboe-lf32.caf", 1, 22050, 2.305125, "caff", "little endian float (32 bits)") test_headers("oboe-ulaw.caf", 1, 22050, 2.305125, "caff", "mulaw (8 bits)") test_headers("oboe.nsp", 1, 22050, 2.305125, "CSL", "little endian short (16 bits)") test_headers("oboe-ulaw.voc", 1, 22050, 2.305669, "VOC", "mulaw (8 bits)") test_headers("oboe-lf32.sf", 1, 22050, 2.305669, "IRCAM", "little endian float (32 bits)") test_headers("oboe.wfp", 1, 22050, 2.305125, "Turtle Beach", "little endian short (16 bits)") test_headers("oboe.sox", 1, 22050, 2.305125, "Sox", "normalized little endian int (32 bits)") test_headers("oki.snd", 2, 44100, 0.004195011, "raw (no header)", "big endian short (16 bits)") test_headers("oki.wav", 1, 44100, 0.016780, "RIFF", "unknown") test_headers("orv-dvi-adpcm.wav", 1, 44100, 1.92725622653961, "RIFF", "unknown") test_headers("riff-16.snd", 1, 22050, 1.88766443729401, "RIFF", "little endian short (16 bits)") test_headers("riff-8-u.snd", 1, 11025, 0.506848096847534, "RIFF", "unsigned byte (8 bits)") test_headers("rooster.wve", 1, 8000, 2.04800009727478, "PSION", "alaw (8 bits)") test_headers("sd1-16.snd", 1, 44100, 0.40054, "Sound Designer 1", "big endian short (16 bits)") test_headers("sf-16.snd", 1, 22050, 1.88766443729401, "IRCAM", "big endian short (16 bits)") test_headers("si654.adc", 1, 16000, 6.71362495422363, "ADC/OGI", "big endian short (16 bits)") test_headers("smp-16.snd", 1, 8000, 5.2028751373291, "SMP", "little endian short (16 bits)") test_headers("sound.pat", 1, 8000, 1.95050001144409, "Gravis Ultrasound patch", "unsigned little endian short (16 bits)") test_headers("sound.sap", 1, 8000, 1.95050001144409, "Goldwave sample", "little endian short (16 bits)") test_headers("sound.sds", 1, 8000, 1.95050001144409, "MIDI sample dump", "unknown") test_headers("sound.sfr", 1, 8000, 1.95050001144409, "SRFS", "little endian short (16 bits)") test_headers("sound.v8", 1, 8000, 1.95050001144409, "Covox V8", "unsigned byte (8 bits)") test_headers("sound.vox", 2, 44100, 0.0442177, "raw (no header)", "big endian short (16 bits)") test_headers("step.omf", 1, 11025, 8.70666694641113, "OMF", "signed byte (8 bits)") test_headers("step.qt", 1, 11025, 8.70630359649658, "Quicktime", "unsigned byte (8 bits)") test_headers("sun-16-afsp.snd", 1, 8000, 2.9760000705719, "Sun/Next", "big endian short (16 bits)") test_headers("sun-mulaw.snd", 1, 8000, 4.61950016021729, "Sun/Next", "mulaw (8 bits)") test_headers("sw1038t_short.wav", 2, 8000, 6.0, "NIST", "mulaw (8 bits)") test_headers("swirl.pat", 1, 22050, 1.0619500875473, "Gravis Ultrasound patch", "unsigned little endian short (16 bits)") test_headers("sy85.snd", 1, 8000, 5.05600023269653, "Sy-85", "big endian short (16 bits)") test_headers("sy99.snd", 1, 8000, 4.54400014877319, "Sy-99", "big endian short (16 bits)") test_headers("telephone.wav", 1, 16000, 2.2788124084, "NIST", "little endian short (16 bits)") test_headers("trumps22.adp", 1, 22050, 3.092880, "RIFF", "unknown") test_headers("truspech.wav", 1, 8000, 1.1599999666214, "RIFF", "unknown") test_headers("ulaw.aifc", 1, 44100, 0.0367800444364548, "AIFC", "mulaw (8 bits)") test_headers("voc-8-u.snd", 1, 8000, 1.49937498569489, "VOC", "unsigned byte (8 bits)") test_headers("o28.voc", 1, 44100, 0.036893, "VOC", "little endian short (16 bits)") test_headers("voxware.wav", 1, 8000, 0.324000000953674, "RIFF", "unknown") test_headers("wd.w00", 1, 8000, 0.202749997377396, "Sy-99", "big endian short (16 bits)") test_headers("wd1.smp", 1, 8000, 0.202749997377396, "SMP", "little endian short (16 bits)") test_headers("wd1.wav", 1, 44100, 0.0367800444364548, "RIFF", "little endian short (16 bits)") test_headers("wheel.mat", 2, 44100, 0.14564626, "raw (no header)", "big endian short (16 bits)") test_headers("b8.pvf", 1, 44100, 0.036803, "Portable Voice Format", "signed byte (8 bits)") test_headers("b16.pvf", 1, 44100, 0.0368, "Portable Voice Format", "big endian short (16 bits)") test_headers("b32.pvf", 1, 44100, 0.036803, "Portable Voice Format", "big endian int (32 bits)") test_headers("water.voc", 2, 32000, 42.3463897705078, "VOC", "little endian short (16 bits)") test_headers("wood.dsf", 1, 8000, 0.202749997377, "Delusion", "little endian short (16 bits)") test_headers("wood.dvi", 1, 22100, 0.0278733037412167, "RIFF", "unknown") test_headers("wood.dwd", 1, 22100, 0.0733936652541161, "DiamondWare", "signed byte (8 bits)") test_headers("wood.fsm", 1, 8000, 0.2029999942, "Farandole", "little endian short (16 bits)") test_headers("wood.mad", 1, 22100, 0.0372398197650909, "RIFF", "unknown") test_headers("wood.maud", 1, 44100, 0.0183900222182274, "MAUD", "big endian short (16 bits)") test_headers("wood.pat", 1, 22100, 0.0733936652541161, "Gravis Ultrasound patch", "little endian short (16 bits)") test_headers("wood.riff", 1, 44100, 0.0367800444364548, "RIFF", "little endian short (16 bits)") test_headers("wood.rifx", 1, 44100, 0.0367800444364548, "RIFF", "big endian short (16 bits)") test_headers("wood.sds", 1, 22100, 0.0733936652541161, "MIDI sample dump", "unknown") test_headers("wood.sdx", 1, 22100, 0.0733936652541161, "Sample dump", "unsigned little endian short (16 bits)") test_headers("wood.sf", 1, 44100, 0.0367800444364548, "IRCAM", "big endian short (16 bits)") test_headers("wood.sndr", 2, 44100, 0.009229, "raw (no header)", "big endian short (16 bits)") test_headers("wood.sndt", 1, 44100, 0.0367800444364548, "SNDT", "unsigned byte (8 bits)") test_headers("wood.st3", 1, 8000, 0.202749997377396, "Digiplayer ST3", "unsigned little endian short (16 bits)") test_headers("wood.uwf", 1, 8000, 0.202999994, "Ultratracker", "little endian short (16 bits)") test_headers("wood.w00", 1, 16000, 0.101374998688698, "TX-16W", "unknown") test_headers("wood12.aiff", 1, 44100, 0.0367800444364548, "AIFF", "big endian short (16 bits)") test_headers("wood16.dwd", 2, 44100, 0.03678004, "DiamondWare", "little endian short (16 bits)") test_headers("wood16.wav", 2, 44100, 0.03678004, "RIFF", "little endian short (16 bits)") test_headers("wood16.nsp", 2, 44100, 0.03678004, "CSL", "little endian short (16 bits)") test_headers("wood16.smp", 2, 44100, 0.03678004, "snack SMP", "little endian short (16 bits)") test_headers("wood24.aiff", 1, 44100, 0.0367800444364548, "AIFF", "big endian int (24 bits)") test_headers("woodblock.aiff", 1, 44100, 0.03678, "AIFF", "big endian short (16 bits)") test_headers("woodflt.snd", 1, 44100, 0.0367800444364548, "Sun/Next", "big endian float (32 bits)") test_headers("RealDrums.sf2", 1, 44100, 6.397256, "SoundFont", "little endian short (16 bits)") test_headers("32bit.sf", 1, 44100, 4.6, "IRCAM", "little endian float (32 bits, unscaled)") test_headers("PCM_48_8bit_m.w64", 1, 48000, 0.375, "SoundForge", "unsigned byte (8 bits)") test_headers("oboe.sf6", 1, 22050, 2.305125, "SoundForge", "little endian short (16 bits)") test_headers("addf8.24we", 1, 8000, 2.976000, "RIFF", "little endian int (24 bits)") test_headers("hybrid.snd", 1, 44100, 4.600000, "BICSF", "big endian float (32 bits)") test_headers("litmanna.sf", 1, 44100, 0.533, "IRCAM", "little endian short (16 bits)") test_headers("M1F1-float64C-AFsp.aif", 2, 8000, 2.9366, "AIFC", "big endian double (64 bits)") test_headers("MacBoing.wav", 1, 11127, 0.696, "RIFF", "unsigned byte (8 bits)") test_headers("t15.aiff", 2, 44100, 135.00, "AIFC", "little endian short (16 bits)") test_headers("tomf8.aud", 1, 8000, 2.016000, "INRS", "little endian short (16 bits)") test_headers("Xhs001x.nsp", 1, 10000, 6.017400, "CSL", "little endian short (16 bits)") test_headers("zulu_a4.w11", 1, 33000, 1.21987879276276, "TX-16W", "unknown", 23342, 40042) # name = "forest.aiff" with_file(name) do |file| snd_test_neq(mus_sound_mark_info(file), [[4, 0], [3, 0], [2, 144332], [1, 24981]], "mus_sound_mark_info %s", name) end name = "traffic.aiff" with_file(name) do |file| snd_test_neq(mus_sound_mark_info(file), [[4, 1], [3, 0], [2, 171931], [1, 99461]], "mus_sound_mark_info %s", name) end end # ---------------- test 03: variables ---------------- def test_03 ind = open_sound("oboe.snd") test_dir = $HOME + "/test" if File.exist?(test_dir) old_val = temp_dir snd_test_neq(set_temp_dir(test_dir), test_dir, "set_temp_dir") set_temp_dir(old_val) end snd_test_neq(sample(1000), 0.0328, "sample 1000") # $snd_error_hook.reset_hook! $mus_error_hook.reset_hook! [$output_comment_hook, $help_hook, $mark_drag_hook, $mix_drag_hook, $mouse_drag_hook, $mouse_click_hook, $mouse_press_hook, $start_playing_hook, $start_playing_selection_hook, $stop_playing_hook, $key_press_hook, $snd_error_hook, $snd_warning_hook, $name_click_hook, $after_apply_controls_hook, $enved_hook, $mouse_enter_label_hook, $mouse_enter_graph_hook, $mouse_enter_listener_hook, $mouse_leave_label_hook, $mouse_leave_graph_hook, $mouse_leave_listener_hook, $initial_graph_hook, $after_graph_hook, $graph_hook].each_with_index do |h, i| if (not hook?(h)) or (not h.empty?) snd_display("hook[%d]: %p?", i, h) end end reset_almost_all_hooks # if $with_test_gui old_ctrl = show_controls set_show_controls(true) req = enved_dialog snd_test_neq(dialog_widgets[1], req, "enved_dialog") req = [0.0, 0.0, 1.0, 1.0, 2.0, 0.0] set_enved_envelope(req) snd_test_neq(enved_envelope, req, "set_enved_envelope") set_enved_envelope(enved_envelope()) snd_test_neq(enved_envelope, req, "set_enved_envelope to self") set_show_controls(old_ctrl) end # gui_lst = [[:color_cutoff, 0.003, 0.01], [:color_inverted, true, false], [:color_scale, 1.0, 0.5], [:contrast_control?, false, true], [:enved_base, 1.0, 1.5], [:enved_in_dB, false, true], [:enved_target, 0, 1], [:enved_wave?, false, true], [:expand_control?, false, true], [:fft_log_frequency, false, true], [:fft_log_magnitude, false, true], [:fft_with_phases, false, true], [:enved_filter_order, 40, 20], [:filter_control?, false, true], [:transform_normalization, Normalize_by_channel, Dont_normalize], [:reverb_control?, false, true], [:show_transform_peaks, false, true], [:show_selection_transform, false, true], [:spectrum_end, 1.0, 0.7], [:spectro_hop, 4, 10], [:spectrum_start, 0.0, 0.1], [:spectro_x_angle, ($with_test_gl ? 300.0 : 90.0), 60.0], [:spectro_x_scale, ($with_test_gl ? 1.5 : 1.0), 2.0], [:spectro_y_angle, ($with_test_gl ? 320.0 : 0.0), 60.0], [:spectro_y_scale, 1.0, 2.0], [:spectro_z_angle, ($with_test_gl ? 0.0 : 358.0), 60.0], [:spectro_z_scale, ($with_test_gl ? 1.0 : 0.1), 0.2]] lst = [[:amp_control, 1.0, 0.5], [:amp_control_bounds, [0.0, 8.0], [1.0, 5.0]], [:ask_about_unsaved_edits, false, true], [:ask_before_overwrite, false, true], [:auto_resize, true, false], [:auto_update, false, true], [:channel_style, 0, 1], [:colormap, $good_colormap, $better_colormap], [:contrast_control, 0.0, 0.5], [:contrast_control_bounds, [0.0, 10.0], [1.0, 5.0]], [:contrast_control_amp, 1.0, 0.5], [:auto_update_interval, 60.0, 120.0], [:cursor_update_interval, 0.05, 0.1], [:cursor_location_offset, 0, 32768], [:with_tracking_cursor, false, true], [:cursor_size, 15, 30], [:cursor_style, Cursor_cross, Cursor_line], [:tracking_cursor_style, Cursor_line, Cursor_cross], [:dac_combines_channels, true, false], [:dac_size, 256, 512], [:clipping, false, true], [:default_output_chans, 1, 2], [:default_output_sample_type, Mus_lfloat, Mus_bshort], [:default_output_srate, 22050, 44100], [:default_output_header_type, Mus_next, Mus_aifc], [:dot_size, 1, 4], [:enved_clip?, false, true], [:enved_style, Envelope_linear, Envelope_exponential], [:enved_power, 3.0, 3.5], [:eps_file, "snd.eps", "snd-1.eps"], [:eps_left_margin, 0.0, 72.0], [:eps_size, 1.0, 2.0], [:eps_bottom_margin, 0.0, 36.0], [:expand_control, 1.0, 2.0], [:expand_control_bounds, [0.001, 20.0], [1.0, 2.0]], [:expand_control_hop, 0.05, 0.1], [:expand_control_jitter, 0.1, 0.2], [:expand_control_length, 0.15, 0.2], [:expand_control_ramp, 0.4, 0.2], [:fft_window_alpha, 0.0, 1.0], [:fft_window_beta, 0.0, 0.5], [:transform_size, 512, 1024], [:transform_graph_type, Graph_once, Graph_as_sonogram], [:fft_window, 6, 5], [:transform_graph?, false, true], [:filter_control_in_dB, false, true], [:filter_control_envelope, [0.0, 1.0, 1.0, 1.0], [0.0, 1.0, 1.0, 0.0]], [:enved_filter, true, false], [:filter_control_in_hz, false, true], [:filter_control_order, 20, 40], [:graph_cursor, 34, 32], [:graph_style, 0, 1], [:initial_beg, 0.0, 1.0], [:initial_dur, 0.1, 1.0], [:just_sounds, false, true], [:listener_prompt, ">", ":"], [:max_transform_peaks, 100, 10], [:max_regions, 16, 6], [:min_dB, -60.0, -90.0], [:log_freq_start, 32.0, 10.0], [:mix_waveform_height, 20, 40], [:mix_tag_height, 14, 20], [:mix_tag_width, 6, 20], [:mark_tag_height, 4, 20], [:mark_tag_width, 10, 20], [:mus_clipping, false, true], [:selection_creates_region, true, false], [:play_arrow_size, 10, 16], [:print_length, 12, 16], [:region_graph_style, Graph_lines, Graph_lollipops], [:reverb_control_decay, 1.0, 2.0], [:reverb_control_feedback, 1.09, 1.6], [:reverb_control_length, 1.0, 2.0], [:reverb_control_length_bounds, [0.0, 0.5], [1.0, 2.0]], [:reverb_control_lowpass, 0.7, 0.9], [:reverb_control_scale, 0.0, 0.2], [:reverb_control_scale_bounds, [0.0, 4.0], [0.0, 0.2]], [:show_axes, 1, 0], [:show_full_duration, false, true], [:show_full_range, false, true], [:show_indices, false, true], [:show_marks, true, false], [:show_mix_waveforms, true, false], [:show_y_zero, false, true], [:show_grid, false, true], [:grid_density, 1.0, 0.5], [:show_sonogram_cursor, false, true], [:sinc_width, 10, 40], [:speed_control, 1.0, 0.5], [:speed_control_bounds, [0.05, 20.0], [1.0, 5.0]], [:speed_control_style, 0, 1], [:speed_control_tones, 12, 18], [:sync, 0, 1], [:sync_style, Sync_by_sound, Sync_all], [:tiny_font, Tiny_font_string, Tiny_font_set_string], [:transform_type, $fourier_transform, $autocorrelation], [:with_verbose_cursor, false, true], [:wavelet_type, 0, 1], [:time_graph?, false, true], [:time_graph_type, Graph_once, Graph_as_wavogram], [:wavo_hop, 3, 6], [:wavo_trace, 64, 128], [:with_mix_tags, true, false], [:with_relative_panes, true, false], [:with_gl, $with_test_gl, false], [:x_axis_style, 0, 1], [:beats_per_minute, 30.0, 120.0], [:beats_per_measure, 1, 120], [:zero_pad, 0, 1], [:zoom_focus_style, 2, 1]] if $with_test_gui lst += gui_lst end lst.each do |sym, initval, newval| next unless symbol?(sym) 2.times do |i| set_snd_func(sym, newval) snd_test_neq(snd_func(sym), newval, "set_%s[%d]", sym, i) set_snd_func(sym, initval) end end # [if $with_test_gui [:amp_control, 1.0, [-1.0, 123.123]] end, [:amp_control_bounds, [0.0, 8.0], [false, [0.0], [1.0, 0.0], 2.0]], [:channel_style, 0, [32, -1, 1.0]], [:colormap, $good_colormap, [321, -123]], [:color_cutoff, 0.003, [-1.0, 123.123]], [:color_scale, 1.0, [-32.0, 2000.0]], if $with_test_gui [:contrast_control, 0.0, [-123.123, 123.123]] end, [:contrast_control_bounds, [0.0, 10.0], [false, [0.0], [1.0, 0.0], 2.0]], [:cursor_size, 15, [1.123, -2.5]], [:dac_size, 256, [-1, 0, -123]], [:dot_size, 1, [0, -1, -123]], [:enved_target, 0, [123, -321]], [:expand_control, 1.0, [-1.0, 0.0]], [:expand_control_bounds, [0.001, 20.0], [false, [0.0], [1.0, 0.0], 2.0]], [:expand_control_hop, 0.05, [-1.0]], [:expand_control_length, 0.15, [-1.0, 0.0]], [:expand_control_ramp, 0.4, [-1.0, 1.0, 123.123]], [:fft_window_alpha, 0.0, [-1.0, 123.123]], [:fft_window_beta, 0.0, [-1.0, 123.123]], [:transform_size, 512, [-1, 0]], [:zero_pad, 0, [-1, -123]], [:cursor_style, Cursor_cross, [-1]], [:cursor_style, Cursor_line, [2, 123]], [:tracking_cursor_style, Cursor_line, [-1]], [:tracking_cursor_style, Cursor_line, [2, 123]], [:transform_graph_type, Graph_once, [-1, 123]], [:fft_window, 6, [-1, 123]], [:enved_filter_order, 40, [-1, 0]], [:filter_control_order, 20, [-10, -1, 0]], [:max_transform_peaks, 100, [-1]], [:max_regions, 16, [-1, -123]], [:reverb_control_length, 1.0, [-1.0]], [:show_axes, 1, [-1, 123]], [:sinc_width, 10, [-10]], [:spectrum_end, 1.0, [-1.0]], [:spectro_hop, 4, [-10, -1, 0]], [:spectrum_start, 0.0, [-1.0]], [:speed_control, 1.0, [0.0]], [:speed_control_bounds, [0.05, 20.0], [false, [0.0], [1.0, 0.0], 2.0]], [:speed_control_style, 0, [-1, 10]], [:sync_style, Sync_by_sound, [-1, 123]], [:transform_type, $fourier_transform, [integer2transform(-1), integer2transform(123)]], [:wavelet_type, 0, [-1, 123]], [:wavo_hop, 1, [0, -123]], [:wavo_trace, 1, [0, -123]], [:x_axis_style, 0, [-1, 123]], [:zoom_focus_style, 2, [-1, 123]]].each do |sym, initval, newvals| next unless symbol?(sym) newvals.each do |newval| Snd.catch do set_snd_func(sym, newval) end snd_test_eq(snd_func(sym), newval, "set_%s (bad set)", sym) set_snd_func(sym, initval) end end # if $with_test_gui set_sync_style(Sync_none) set_window_width(300) set_window_height(300) snd_test_neq(window_width, 300, "window width") snd_test_neq(window_height, 300, "window height") old_val = color_scale set_color_scale(100.0) snd_test_neq(color_scale, 100.0, "color_scale") set_color_scale(old_val) end # if proc?(search_procedure) snd_display("global search procedure: %s?", search_procedure.inspect) end set_search_procedure(lambda do |y| y > 0.1 end) unless proc?(search_procedure) snd_display("set global search procedure: %s?", search_procedure.inspect) end unless search_procedure.call(0.2) snd_display("search 0.1 > 0.2?") end if search_procedure.call(0.02) snd_display("search 0.1 > 0.02?") end set_search_procedure(lambda do |y| y < 0.0 end) if search_procedure.call(0.02) snd_display("search 0.0 < 0.02?") end set_search_procedure(false) if proc?(search_procedure) snd_display("global search procedure after reset: %s?", search_procedure.inspect) end set_search_procedure(lambda do |y| y > 0.1 end) unless proc?(search_procedure) snd_display("set global search procedure: %s?", search_procedure.inspect) end set_search_procedure(false) # if $with_test_gui old_val = enved_filter_order set_enved_filter_order(5) snd_test_neq(enved_filter_order, 6, "set_enved_filter_order 5") set_enved_filter_order(old_val) # zero_to_one = [0, 0.0, 50, 0.5, 100, 1.0] mod_down = [0, 1.0, 50, 0.5, 100, 0.0] set_enved_envelope(:zero_to_one) snd_test_neq(enved_envelope, zero_to_one, "set_enved_envelope (Symbol)") set_enved_envelope("mod_down") snd_test_neq(enved_envelope, mod_down, "set_enved_envelope (String)") end close_sound(ind) dismiss_all_dialogs undefined = [] kernel_global_variables = Kernel.global_variables # XXX: from original snd-test.scm list removed or changed: # # :file2string (Scheme specific in snd-utils.c) # :redo (Ruby statement) # # :in replaced by :call_in [:snd_opened_sound, :abort, :add_colormap, :add_mark, :add_player, :add_sound_file_extension, :add_source_file_extension, :add_to_main_menu, :add_to_menu, :add_transform, :after_apply_controls_hook, :after_edit_hook, :after_graph_hook, :after_lisp_graph_hook, :after_open_hook, :after_save_as_hook, :after_save_state_hook, :after_transform_hook, :all_pass, :all_pass?, :amp_control, :amp_control_bounds, :amplitude_modulate, :analyse_ladspa, :apply_controls, :apply_ladspa, :array2file, :array_interp, :as_one_edit, :ask_about_unsaved_edits, :ask_before_overwrite, :asymmetric_fm, :asymmetric_fm?, :auto_resize, :auto_update, :auto_update_interval, :autocorrelate, :autocorrelation, :axis_color, :axis_info, :axis_label_font, :axis_numbers_font, :bad_header_hook, :bartlett_window, :bartlett_hann_window, :basic_color, :beats_per_measure, :beats_per_minute, :before_close_hook, :before_exit_hook, :before_save_as_hook, :before_save_state_hook, :before_transform_hook, :bind_key, :blackman2_window, :blackman3_window, :blackman4_window, :blackman5_window, :blackman6_window, :blackman7_window, :blackman8_window, :blackman9_window, :blackman10_window, :bohman_window, :bold_peaks_font, :call_in, :cauchy_window, :mlt_sine_window, :cepstrum, :change_samples_with_origin, :channel2vct, :channel_amp_envs, :channel_data, :channel_properties, :channel_property, :channel_style, :channel_widgets, :channels, :channels_combined, :channels_separate, :channels_superimposed, :chans, :clear_listener, :clip_hook, :clipping, :clm_channel, :clm_table_size, :clm_default_frequency, :close_hook, :close_sound, :color_cutoff, :color_orientation_dialog, :color_hook, :color_inverted, :color_scale, :color?, :colormap, :colormap_name, :colormap_ref, :colormap_size, :colormap?, :comb, :comb?, :combined_data_color, :comment, :connes_window, :continue_frample2file, :continue_sample2file, :contrast_control, :contrast_control_amp, :contrast_control_bounds, :contrast_control?, :contrast_enhancement, :controls2channel, :convolution, :convolve, :convolve_files, :convolve_selection_with, :convolve_with, :convolve?, :copy_context, :copy_sampler, :current_edit_position, :current_font, :cursor, :cursor_color, :cursor_context, :cursor_cross, :cursor_in_middle, :cursor_in_view, :cursor_line, :cursor_location_offset, :cursor_on_left, :cursor_on_right, :cursor_position, :cursor_size, :cursor_style, :cursor_update_interval, :dac_combines_channels, :dac_size, :data_color, :sample_type, :data_location, :data_size, :db2linear, :default_output_chans, :default_output_sample_type, :default_output_header_type, :default_output_srate, :define_envelope, :degrees2radians, :delay, :delay_tick, :delay?, :delete_colormap, :delete_mark, :delete_marks, :delete_sample, :delete_samples, :delete_samples_and_smooth, :delete_selection, :delete_selection_and_smooth, :delete_transform, :dialog_widgets, :disk_kspace, :display_edits, :dolph_chebyshev_window, :dont_normalize, :dot_product, :dot_size, :draw_axes, :draw_dot, :draw_dots, :draw_line, :draw_lines, :draw_mark_hook, :draw_mix_hook, :draw_string, :drop_hook, :during_open_hook, :edit_fragment, :edit_header_dialog, :edit_hook, :edit_list2function, :edit_position, :edit_tree, :edits, :edot_product, :env, :env_channel, :env_channel_with_base, :env_interp, :env_selection, :env_sound, :env?, :enved_add_point, :enved_amplitude, :enved_base, :enved_clip?, :enved_delete_point, :enved_dialog, :enved_envelope, :enved_filter, :enved_filter_order, :enved_hook, :enved_in_dB, :enved_move_point, :enved_power, :enved_spectrum, :enved_srate, :enved_style, :enved_target, :enved_wave?, :enved_waveform_color, :envelope_exponential, :envelope_linear, :eps_bottom_margin, :eps_file, :eps_left_margin, :eps_size, :exit, :exit_hook, :expand_control, :expand_control_bounds, :expand_control_hop, :expand_control_jitter, :expand_control_length, :expand_control_ramp, :expand_control?, :exponential_window, :fft, :fft_log_frequency, :fft_log_magnitude, :fft_window, :fft_window_alpha, :fft_window_beta, :fft_with_phases, :file2array, :file2frample, :file2frample?, :file2sample, :file2sample?, :file_name, :file_write_date, :fill_polygon, :fill_rectangle, :filter, :filtered_comb, :filtered_comb?, :filter_channel, :filter_control_coeffs, :filter_control_envelope, :filter_control_in_dB, :filter_control_in_hz, :filter_control_order, :filter_control_waveform_color, :filter_control?, :filter_selection, :filter_sound, :filter?, :find_dialog, :find_mark, :find_sound, :finish_progress_report, :fir_filter, :fir_filter?, :flat_top_window, :focus_widget, :foreground_color, :forget_region, :formant, :formant_bank, :formant_bank?, :formant?, :firmant, :firmant?, :comb_bank, :comb_bank?, :all_pass_bank, :all_pass_bank?, :filtered_comb_bank, :filtered_comb_bank?, :make_comb_bank, :make_all_pass_bank, :make_filtered_comb_bank, :fourier_transform, :frample2file, :frample2file?, :frample2frample, :framples, :free_player, :free_sampler, :gaussian_window, :gc_off, :gc_on, :gl_graph2ps, :glSpectrogram, :goto_listener_end, :granulate, :granulate?, :graph, :graph2ps, :graph_as_sonogram, :graph_as_spectrogram, :graph_as_wavogram, :graph_color, :graph_cursor, :graph_data, :graph_dots, :graph_dots_and_lines, :graph_filled, :graph_hook, :graph_lines, :graph_lollipops, :graph_once, :graph_style, :graphs_horizontal, :grid_density, :haar_transform, :hamming_window, :hann_poisson_window, :hann_window, :header_type, :help_dialog, :help_hook, :hide_widget, :highlight_color, :html_dir, :html_program, :hz2radians, :iir_filter, :iir_filter?, :in_any, :ina, :inb, :info_dialog, :init_ladspa, :initial_graph_hook, :insert_file_dialog, :insert_region, :insert_sample, :insert_samples, :insert_samples_with_origin, :insert_selection, :insert_silence, :insert_sound, :just_sounds, :kaiser_window, :key, :key_binding, :key_press_hook, :keyboard_no_action, :ladspa_activate, :ladspa_cleanup, :ladspa_connect_port, :ladspa_deactivate, :ladspa_descriptor, :ladspa_dir, :peak_env_dir, :ladspa_instantiate, :ladspa_run, :ladspa_run_adding, :ladspa_set_run_adding_gain, :left_sample, :linear2db, :lisp_graph, :lisp_graph_hook, :lisp_graph_style, :lisp_graph?, :list2vct, :list_ladspa, :listener_click_hook, :listener_color, :listener_font, :listener_prompt, :listener_selection, :listener_text_color, :little_endian?, :locsig, :locsig_ref, :locsig_reverb_ref, :locsig_reverb_set!, :locsig_set!, :locsig_type, :locsig?, :log_freq_start, :main_menu, :main_widgets, :make_all_pass, :make_asymmetric_fm, :make_moving_average, :make_moving_max, :make_bezier, :make_color, :make_comb, :make_filtered_comb, :make_convolve, :make_delay, :make_env, :make_fft_window, :make_file2frample, :make_file2sample, :make_filter, :make_fir_coeffs, :make_fir_filter, :make_formant, :make_firmant, :make_formant_bank, :make_frample2file, :make_granulate, :make_graph_data, :make_iir_filter, :make_locsig, :make_mix_sampler, :make_move_sound, :make_notch, :make_one_pole, :make_one_pole_all_pass, :make_one_zero, :make_oscil, :make_phase_vocoder, :make_player, :make_polyshape, :make_polywave, :make_pulse_train, :make_rand, :make_rand_interp, :make_readin, :make_region, :make_region_sampler, :make_sample2file, :make_sampler, :make_sawtooth_wave, :make_nrxysin, :make_nrxycos, "make_rxyk!cos".intern, "make_rxyk!sin".intern, :make_snd2sample, :make_square_wave, :make_src, :make_ssb_am, :make_ncos, :make_nsin, :make_table_lookup, :make_triangle_wave, :make_two_pole, :make_two_zero, :make_variable_graph, :make_vct, :make_wave_train, :map_chan, :map_channel, :mark_click_hook, :mark_color, :mark_context, :mark_drag_hook, :mark_home, :mark_hook, :mark_name, :mark_properties, :mark_property, :mark_sample, :mark_sync, :mark_sync_max, :mark_tag_height, :mark_tag_width, :mark?, :marks, :max_regions, :max_transform_peaks, :maxamp, :maxamp_position, :menu_widgets, :min_dB, :mix, :mix_amp, :mix_amp_env, :mix_click_hook, :mix_color, :mix_dialog_mix, :mix_drag_hook, :mix_file_dialog, :mix_length, :mix_home, :mix_name, :mix_position, :mix_properties, :mix_property, :mix_region, :mix_release_hook, :mix_sync, :mix_sync_max, :mix_sampler?, :mix_selection, :mix_speed, :mix_tag_height, :mix_tag_width, :mix_tag_y, :mix_vct, :mix_waveform_height, :mix?, :mixes, :mouse_click_hook, :mouse_drag_hook, :mouse_enter_graph_hook, :mouse_enter_label_hook, :mouse_enter_listener_hook, :mouse_enter_text_hook, :mouse_leave_graph_hook, :mouse_leave_label_hook, :mouse_leave_listener_hook, :mouse_leave_text_hook, :mouse_press_hook, :move_locsig, :move_sound, :move_sound?, :moving_average, :moving_average?, :moving_max, :moving_max?, :mus_aifc, :mus_aiff, :mus_alaw, :mus_alsa_buffer_size, :mus_alsa_buffers, :mus_alsa_capture_device, :mus_alsa_device, :mus_alsa_playback_device, :mus_alsa_squelch_warning, :mus_apply, :mus_array_print_length, :mus_float_equal_fudge_factor, :mus_b24int, :mus_bdouble, :mus_bdouble_unscaled, :mus_bfloat, :mus_bfloat_unscaled, :mus_bicsf, :mus_bint, :mus_bintn, :mus_bshort, :mus_byte, :mus_bytes_per_sample, :mus_caff, :mus_channel, :mus_channels, :mus_chebyshev_first_kind, :mus_chebyshev_second_kind,:mus_clipping, :mus_close, :mus_data, :mus_sample_type2string, :mus_sample_type_name, :mus_describe, :mus_error_hook, :mus_error_type2string, :mus_expand_filename, :mus_feedback, :mus_feedforward, :mus_fft, :mus_file_buffer_size, :mus_file_clipping, :mus_file_name, :mus_frequency, :mus_generator?, :mus_header_raw_defaults, :mus_header_type2string, :mus_header_type_name, :mus_hop, :mus_increment, :mus_input?, :mus_interp_all_pass, :mus_interp_bezier, :mus_interp_hermite, :mus_interp_lagrange, :mus_interp_linear, :mus_interp_none, :mus_interp_sinusoidal, :mus_interp_type, :mus_interpolate, :mus_ircam, :mus_l24int, :mus_ldouble, :mus_ldouble_unscaled, :mus_length, :mus_lfloat, :mus_lfloat_unscaled, :mus_lint, :mus_lintn, :mus_location, :mus_lshort, :mus_max_malloc, :mus_max_table_size, :mus_mulaw, :mus_name, :mus_next, :mus_nist, :mus_offset, :mus_order, :mus_oss_set_buffers, :mus_out_format, :mus_output?, :mus_phase, :mus_ramp, :mus_rand_seed, :mus_random, :mus_raw, :mus_reset, :mus_riff, :mus_run, :mus_scaler, :mus_set_formant_radius_and_frequency, :mus_sound_chans, :mus_sound_comment, :mus_sound_sample_type, :mus_sound_data_location, :mus_sound_datum_size, :mus_sound_duration, :mus_sound_forget, :mus_sound_framples, :mus_sound_header_type, :mus_sound_length, :mus_sound_loop_info, :mus_sound_mark_info, :mus_sound_maxamp, :mus_sound_maxamp_exists?, :mus_sound_prune, :mus_sound_report_cache, :mus_sound_samples, :mus_sound_srate, :mus_sound_type_specifier, :mus_sound_write_date, :mus_soundfont, :mus_srate, :mus_svx, :mus_ubshort, :mus_ubyte, :mus_ulshort, :mus_unknown_sample, :mus_unknown_header, :mus_voc, :mus_width, :mus_xcoeff, :mus_xcoeffs, :mus_ycoeff, :mus_ycoeffs, :name_click_hook, :new_sound, :new_sound_dialog, :new_sound_hook, :new_widget_hook, :next_sample, :normalize_by_channel, :normalize_by_sound, :normalize_channel, :normalize_globally, :notch, :notch?, :one_pole, :one_pole?, :one_pole_all_pass, :one_pole_all_pass?, :one_zero, :one_zero?, :open_file_dialog, :open_file_dialog_directory, :open_hook, :open_raw_sound, :open_raw_sound_hook, :open_sound, :orientation_hook, :oscil, :oscil?, :out_any, :outa, :outb, :outc, :outd, :output_comment_hook, :override_samples_with_origin, :pad_channel, :partials2polynomial, :partials2wave, :parzen_window, :pausing, :peaks, :peaks_font, :phase_partials2wave, :phase_vocoder, :phase_vocoder_amp_increments, :phase_vocoder_amps, :phase_vocoder_freqs, :phase_vocoder_phase_increments, :phase_vocoder_phases, :phase_vocoder?, :play, :play_arrow_size, :play_hook, :player_home, :player?, :players, :playing, :poisson_window, :polar2rectangular, :polynomial, :polyshape, :polywave, :polyshape?, :polywave?, :position2x, :position2y, :position_color, :preferences_dialog, :previous_sample, :print_dialog, :print_length, :progress_report, :pulse_train, :pulse_train?, :radians2degrees, :radians2hz, :ramp_channel, :rand, :rand_interp, :rand_interp?, :rand?, :read_mix_sample, :read_only, :read_region_sample, :read_sample, :readin, :readin?, :rectangular2magnitudes, :rectangular2polar, :rectangular_window, :redo_edit, :region2vct, :region_chans, :region_home, :region_framples, :region_graph_style, :region_maxamp, :region_maxamp_position, :region_position, :region_sample, :region_sampler?, :region_srate, :region?, :regions, :remember_sound_state, :remove_from_menu, :reset_controls, :reset_listener_cursor, :restore_controls, :restore_region, :reverb_control_decay, :reverb_control_feedback, :reverb_control_length, :reverb_control_length_bounds, :reverb_control_lowpass, :reverb_control_scale, :reverb_control_scale_bounds, :reverb_control?, :reverse_channel, :reverse_selection, :reverse_sound, :revert_sound, :riemann_window, :right_sample, :ring_modulate, :rv2_window, :rv3_window, :rv4_window, :samaraki_window, :sample, :sample2file, :sample2file?, :sampler_at_end?, :sampler_home, :sampler_position, :sampler?, :samples, :samples2seconds, :sash_color, :save_controls, :save_dir, :save_edit_history, :save_envelopes, :save_hook, :save_listener, :save_marks, :save_region, :save_region_dialog, :save_selection, :save_selection_dialog, :save_sound, :save_sound_as, :save_sound_dialog, :save_state, :save_state_file, :save_state_hook, :sawtooth_wave, :sawtooth_wave?, :scale_by, :scale_channel, :scale_selection_by, :scale_selection_to, :scale_to, :scan_channel, :script_arg, :script_args, :search_procedure, :seconds2samples, :select_all, :select_channel, :select_channel_hook, :select_sound, :select_sound_hook, :selected_channel, :selected_data_color, :selected_graph_color, :selected_sound, :selection_chans, :selection_color, :selection_context, :selection_creates_region, :selection_framples, :selection_maxamp, :selection_maxamp_position, :selection_member?, :selection_position, :selection_srate, :selection?, :short_file_name, :show_all_axes, :show_all_axes_unlabelled, :show_bare_x_axis, :show_axes, :show_controls, :show_grid, :show_indices, :show_full_duration, :show_full_range, :initial_beg, :initial_dur, :show_listener, :show_marks, :show_mix_waveforms, :show_no_axes, :show_selection, :show_selection_transform, :show_sonogram_cursor, :show_transform_peaks, :show_widget, :show_x_axis, :show_x_axis_unlabelled, :show_y_zero, :sinc_width, :nrxysin, :nrxysin?, :nrxycos, :nrxycos?, "rxyk!cos".intern, "rxyk!cos?".intern, "rxyk!sin".intern, "rxyk!sin?".intern, :smooth_channel, :smooth_selection, :smooth_sound, :snd2sample, :snd2sample?, :snd_error, :snd_error_hook, :snd_gcs, :snd_help, :snd_font, :snd_color, :snd_print, :snd_spectrum, :snd_tempnam, :snd_url, :snd_urls, :snd_version, :snd_warning, :snd_warning_hook, :sound_file_extensions, :sound_file?, :sound_files_in_directory, :sound_loop_info, :sound_properties, :sound_property, :sound_widgets, :sound?, :soundfont_info, :sounds, :spectrum_end, :spectro_hop, :spectrum_start, :spectro_x_angle, :spectro_x_scale, :spectro_y_angle, :spectro_y_scale, :spectro_z_angle, :spectro_z_scale, :spectrum, :speed_control, :speed_control_as_float, :speed_control_as_ratio, :speed_control_as_semitone, :speed_control_bounds, :speed_control_style, :speed_control_tones, :square_wave, :square_wave?, :squelch_update, :srate, :src, :src_channel, :src_selection, :src_sound, :src?, :ssb_am, :ssb_am?, :start_playing, :start_playing_hook, :start_playing_selection_hook, :start_progress_report, :status_report, :stop_player, :stop_playing, :stop_playing_hook, :stop_playing_selection_hook, :ncos, :ncos?, :nsin, :nsin?, :swap_channels, :sync, :sync_style, :sync_none, :sync_all, :sync_by_sound, :sync_max, :syncd_marks, :table_lookup, :table_lookup?, :tap, :tap?, :temp_dir, :text_focus_color, :time_graph, :time_graph_style, :time_graph_type, :time_graph?, :tiny_font, :tracking_cursor_style, :transform2vct, :transform_dialog, :transform_framples, :transform_graph, :transform_graph_style, :transform_graph_type, :transform_graph?, :transform_normalization, :transform_sample, :transform_size, :transform_type, :transform?, :triangle_wave, :triangle_wave?, :tukey_window, :two_pole, :two_pole?, :two_zero, :two_zero?, :ultraspherical_window, :unbind_key, :undo, :undo_edit, :undo_hook, :unselect_all, :update_hook, :update_lisp_graph, :update_sound, :update_time_graph, :update_transform_graph, :variable_graph?, :vct, :vct_multiply, :vct_add, :vct2channel, :vct2list, :vct2string, :vct2vector, :vct_add!, :vct_length, :vct_max, :vct_min, :vct_move!, :vct_multiply!, :vct_offset!, :vct_peak, :vct_ref, :vct_reverse!, :vct_scale!, :vct_set!, :vct_subseq, :vct_subtract!, :vct?, :vector2vct, :view_sound, :walsh_transform, :wave_train, :wave_train?, :wavelet_transform, :wavelet_type, :wavo_hop, :wavo_trace, :welch_window, :widget_position, :widget_size, :widget_text, :window_height, :window_width, :window_x, :window_y, :with_background_processes, :with_file_monitor, :with_gl, :with_mix_tags, :with_relative_panes, :with_tracking_cursor, :with_verbose_cursor, :with_inset_graph, :with_interrupts, :with_pointer_focus, :with_smpte_label, :with_toolbar, :with_tooltips, :with_menu_icons, :save_as_dialog_src, :save_as_dialog_auto_comment, :x2position, :x_axis_as_clock, :x_axis_as_percentage, :x_axis_in_beats, :x_axis_in_measures, :x_axis_in_samples, :x_axis_in_seconds, :x_axis_label, :x_axis_style, :x_bounds, :x_position_slider, :x_zoom_slider, :xramp_channel, :y2position, :y_axis_label, :y_bounds, :y_position_slider, :y_zoom_slider, :zero_pad, :zoom_color, :zoom_focus_active, :zoom_focus_left, :zoom_focus_middle, :zoom_focus_right, :zoom_focus_style].each do |n| next if Module.function?(n) str = n.to_s next if Object.const_defined?("#{str.capitalize}".intern) str = "$" + str # XXX: ruby18 likes a String next if kernel_global_variables.member?(str) # XXX: ruby19+ likes a Symbol next if kernel_global_variables.member?(str.intern) undefined << n end unless $with_test_ladspa undefined.delete_if do |s| s.to_s =~ /ladspa/ end end unless $with_test_gl undefined.delete_if do |s| s == :glSpectrogram end end unless $with_test_gl2ps undefined.delete_if do |s| s == :gl_graph2ps end end unless undefined.empty? snd_display("undefined[%d]: %s", undefined.length, undefined) end end # ---------------- test 04: sndlib ---------------- def frame2byte(file, frame) mus_sound_data_location(file) + mus_sound_chans(file) * mus_sound_datum_size(file) * frame end def test_04_00 oboe_snd = "oboe.snd" chns = mus_sound_chans(oboe_snd) dl = mus_sound_data_location(oboe_snd) fr = mus_sound_framples(oboe_snd) smps = mus_sound_samples(oboe_snd) len = mus_sound_length(oboe_snd) size = mus_sound_datum_size(oboe_snd) com = mus_sound_comment(oboe_snd) sr = mus_sound_srate(oboe_snd) m1 = mus_sound_maxamp_exists?(oboe_snd) mal = mus_sound_maxamp(oboe_snd) mz = mus_sound_maxamp "z.snd" bytes = mus_bytes_per_sample(mus_sound_sample_type(oboe_snd)) snd_test_neq(mz[0], 0, "mus_sound_maxamp z.snd") snd_test_neq(mz[1], 0.0, "mus_sound_maxamp z.snd") [[Mus_bshort, 2], [Mus_lshort, 2], [Mus_mulaw, 1], [Mus_alaw, 1], [Mus_byte, 1], [Mus_ubyte, 1], [Mus_bfloat, 4], [Mus_lfloat, 4], [Mus_bint, 4], [Mus_lint, 4], [Mus_bintn, 4], [Mus_lintn, 4], [Mus_b24int, 3], [Mus_l24int, 3], [Mus_bdouble, 8], [Mus_ldouble, 8], [Mus_ubshort, 2], [Mus_ulshort, 2], [Mus_bdouble_unscaled, 8], [Mus_ldouble_unscaled, 8], [Mus_bfloat_unscaled, 4], [Mus_lfloat_unscaled, 4]].each do |frm, siz| snd_test_neq(mus_bytes_per_sample(frm), siz, "mus_bytes_per_sample") end snd_test_neq(mus_sample_type2string(Mus_bshort), "Mus_bshort", "mus_sample_type2string") snd_test_neq(mus_header_type2string(Mus_aifc), "Mus_aifc", "mus_header_type2string") hiho = "hiho.tmp" mus_sound_report_cache(hiho) fp = File.open(hiho) snd_test_neq(fp.readline.chomp, "sound table:", "print-cache 1") fp.close delete_file(hiho) req = 10 snd_test_neq(chns, 1, "oboe: mus_sound_chans") snd_test_neq(dl, 28, "oboe: mus_sound_data_location") snd_test_neq(fr, 50828, "oboe: mus_sound_framples") snd_test_neq(smps, 50828, "oboe: mus_sound_samples") snd_test_neq(len, 50828 * 2 + 28, "oboe: mus_sound_length") snd_test_neq(size, 2, "oboe: mus_sound_datum_size") snd_test_neq(bytes, 2, "oboe: mus_sound_bytes") snd_test_neq(sr, 22050, "oboe: mus_sound_srate") if m1 and $clmtest.zero? snd_display("oboe: mus_sound_maxamp_exists? before maxamp: %s?", m1) end unless res = mus_sound_maxamp_exists?(oboe_snd) snd_display("oboe: mus_sound_maxamp_exists? after maxamp: %s?", res) end # if $clmtest.zero? res = mus_header_raw_defaults if (not array?(res)) or res.length != 3 snd_display("mus_header_raw_defaults: %s?", res) end sr, chns, frm = res snd_test_neq(sr, 44100, "mus_header_raw_defaults srate") snd_test_neq(chns, 2, "mus_header_raw_defaults chns") snd_test_neq(frm, Mus_bshort, "mus_header_raw_defaults format") end old_val = mus_header_raw_defaults set_mus_header_raw_defaults([12345, 3, Mus_bdouble_unscaled]) res = mus_header_raw_defaults if (not array?(res)) or res.length != 3 snd_display("mus_header_raw_defaults: %s?", res) end sr, chns, frm = res snd_test_neq(sr, 12345, "mus_header_raw_defaults srate") snd_test_neq(chns, 3, "mus_header_raw_defaults chns") snd_test_neq(frm, Mus_bdouble_unscaled, "mus_header_raw_defaults format") set_mus_header_raw_defaults(old_val) # tm = mus_sound_write_date(oboe_snd) snd_test_neq(Time.at(tm).localtime.strftime("%d-%b %H:%M"), "15-Oct 04:34", "mus_sound_write_date oboe.snd") tm = mus_sound_write_date("pistol.snd") snd_test_neq(Time.at(tm).localtime.strftime("%d-%b %H:%M"), "01-Jul 22:06", "mus_sound_write_date pistol.snd") # ind = open_sound(oboe_snd) lfname = "test" + "-test" * 10 + ".snd" if variable_graph?(ind) snd_display("variable_graph thinks anything is a graph...") end if player?(ind) snd_display("player? thinks anything is a player...") end unless sound?(ind) snd_display("%s is not a sound?", ind) end if (sound?(false)) snd_display("sound? false -> true?") end if (sound?(true)) snd_display("sound? true -> true?") end save_sound_as(lfname, ind) close_sound(ind) # ind = open_sound(lfname) unless sound?(ind) snd_display("cannot find test...snd") end req = lfname.length snd_test_lt(file_name(ind).length, req, "file_name length") snd_test_neq(short_file_name(ind).length, req, "short_file_name length") close_sound(ind) mus_sound_forget(lfname) delete_file(lfname) # with_file("forest.aiff") do |fsnd| file_copy("fsnd", "fmv.snd") ind = open_sound("fmv.snd") snd_test_neq(sound_loop_info(ind), mus_sound_loop_info(fsnd), "loop_info") set_sound_loop_info(ind, [12000, 14000, 1, 2, 3, 4]) snd_test_neq(sound_loop_info(ind), [12000, 14000, 1, 2, 3, 4, 1, 1], "set_loop_info") save_sound_as("fmv1.snd", ind, :header_type, Mus_aifc) close_sound(ind) snd_test_neq(mus_sound_loop_info("fmv1.snd"), [12000, 14000, 1, 2, 3, 4, 1, 1], "saved loop_info") end # ind = open_sound(oboe_snd) save_sound_as("fmv.snd", ind, :header_type, Mus_aifc) close_sound(ind) ind = open_sound("fmv.snd") snd_test_neq(sound_loop_info(ind), nil, "null loop_info") set_sound_loop_info(ind, [1200, 1400, 4, 3, 2, 1]) snd_test_neq(sound_loop_info(ind), [1200, 1400, 4, 3, 2, 1, 1, 1], "set null loop_info") save_sound_as("fmv1.snd", :sound, ind, :header_type, Mus_aifc) close_sound(ind) snd_test_neq(mus_sound_loop_info("fmv1.snd"), [1200, 1400, 4, 3, 2, 1, 1, 1], "saved null loop_info") ind = open_sound("fmv.snd") set_sound_loop_info(ind, [1200, 1400, 4, 3, 2, 1, 1, 0]) snd_test_neq(sound_loop_info(ind), [1200, 1400, 0, 0, 2, 1, 1, 0], "set null loop_info (no mode1)") save_sound_as("fmv1.snd", ind, :header_type, Mus_aifc) close_sound(ind) snd_test_neq(mus_sound_loop_info("fmv1.snd"), [1200, 1400, 0, 0, 2, 1, 1, 0], "saved null loop_info (no mode1)") # unless com.empty? snd_display("oboe: mus_sound_comment: %s", com.inspect) end [["nasahal8.wav", "ICRD: 1997-02-22\nIENG: Paul R. Roger\nISFT: Sound Forge 4.0\n"], ["8svx-8.snd", "File created by Sound Exchange "], ["sun-16-afsp.snd", "AFspdate:1981/02/11 23:03:34 UTC"], ["smp-16.snd", "Converted using Sox. "], ["d40130.au", "1994 Jesus Villena"], ["wood.maud", "file written by SOX MAUD-export "], ["addf8.sf_mipseb", "date=\"Feb 11 18:03:34 1981\" info=\"Original recorded at 20 kHz, 15-bit D/A, digitally filtered and resampled\" speaker=\"AMK female\" text=\"Add the sum to the product of these three.\" "], ["mary-sun4.sig", "MARY HAD A LITTLE LAMB\n"], ["nasahal.pat", "This patch saved with Sound Forge 3.0."], ["next-16.snd", ";Written on Mon 1-Jul-91 at 12:10 PDT at localhost (NeXT) using Allegro CL and clm of 25-June-91"], ["wood16.nsp", "Created by Snack "], ["wood.sdx", "1994 Jesus Villena"], ["clmcom.aif", "this is a comment"], ["anno.aif", "1994 Jesus Villena\n"], ["telephone.wav", "sample_byte_format -s2 01\nchannel_count -i 1\nsample_count -i 36461\nsample_rate -i 16000\nsample_n_bytes -i 2\nsample_sig_bits -i 16\n"] ].each do |f, req| with_file(f) do |fsnd| snd_test_neq(mus_sound_comment(fsnd), req, "mus_sound_comment %s", fsnd) end end with_file("traffic.aiff") do |fsnd| res = mus_sound_comment(fsnd) unless string?(res) snd_display("mus_sound_comment traffic: %s", res.inspect) end end if $clmtest.zero? snd_test_neq(mal[1], 0.14724, "oboe: mus_sound_maxamp") snd_test_neq(mal[0], 24971, "oboe: mus_sound_maxamp at %d", mal[0]) end res = mus_sound_type_specifier(oboe_snd) if res != 0x646e732e and # little endian reader res != 0x2e736e64 # big endian reader snd_display("oboe: mus_sound_type_specifier: 0x%x?", res) end # tm = file_write_date(oboe_snd) snd_test_neq(Time.at(tm).localtime.strftime("%d-%b-%Y %H:%M"), "15-Oct-2006 04:34", "file_write_date oboe.snd") # lasth = 1 until mus_header_type_name(lasth) == "unknown" lasth += 1 end if lasth < 50 snd_display("header_type[%d] == %s?", lasth, mus_header_type_name(lasth)) end lasth = 1 until mus_sample_type_name(lasth) == "unknown" lasth += 1 end if lasth < 10 snd_display("sample_type[%d] == %s?", lasth, mus_sample_type_name(lasth)) end [:Dont_normalize, :Normalize_globally, :Normalize_by_channel].each do |val_sym| req = Module.const_get(val_sym) set_transform_normalization(req) snd_test_neq(transform_normalization, req, "set_transform_normalization(%s)", val_sym) end # ind = new_sound("fmv.snd", 1, 22050, Mus_bshort, Mus_next, "set_samples test", 100) set_samples(10, 3, Vct.new(3, 0.1)) snd_test_neq(channel2vct(0, 20, ind, 0), vct(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.1, 0.1, 0.1, 0, 0, 0, 0, 0, 0, 0), "1 set samples 0 for 0.1") set_samples(20, 3, Vct.new(3, 0.1), ind, 0) snd_test_neq(channel2vct(10, 20, ind, 0), vct(0.1, 0.1, 0.1, 0, 0, 0, 0, 0, 0, 0, 0.1, 0.1, 0.1, 0, 0, 0, 0, 0, 0, 0), "2 set samples 10 for 0.1") set_samples(30, 3, Vct.new(3, 0.1), ind, 0, false, "a name") snd_test_neq(channel2vct(20, 20, ind, 0), vct(0.1, 0.1, 0.1, 0, 0, 0, 0, 0, 0, 0, 0.1, 0.1, 0.1, 0, 0, 0, 0, 0, 0, 0), "3 set samples 20 for 0.1") set_samples(0, 3, Vct.new(3, 0.2), ind, 0, false, "a name", 0, 1) snd_test_neq(channel2vct(0, 20, ind, 0), vct(0.2, 0.2, 0.2, 0, 0, 0, 0, 0, 0, 0, 0.1, 0.1, 0.1, 0, 0, 0, 0, 0, 0, 0), "4 set samples 0 at 1 for 0.1") snd_test_neq(channel2vct(20, 20, ind, 0), Vct.new(20, 0.0), "5 set samples 20 at 1 for 0.1") nd = new_sound("fmv1.snd", :channels, 2) vct2channel(Vct.new(10, 0.5), 0, 10, nd, 0) vct2channel(Vct.new(10, 0.3), 0, 10, nd, 1) save_sound_as("fmv1.snd", nd) close_sound(nd) unless File.exist?("fmv1.snd") snd_display("fmv1.snd not saved?") end set_samples(0, 10, "fmv1.snd", ind, 0, false, "another name", 1) snd_test_neq(channel2vct(0, 20, ind, 0), vct(0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.1, 0.1, 0.1, 0, 0, 0, 0, 0, 0, 0), "6 set samples 0 at 1 for 0.1") set_samples(5, 6, "fmv1.snd", ind, 0, false, "another name 7", 0) snd_test_neq(channel2vct(0, 20, ind, 0), vct(0.3, 0.3, 0.3, 0.3, 0.3, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.1, 0.1, 0, 0, 0, 0, 0, 0, 0), "7 set samples 0 at 1 for 0.1") revert_sound(ind) set_samples(0, 10, "fmv1.snd", ind, 0, false, "another name 8", 1, 0, false) snd_test_neq(channel2vct(0, 20, ind, 0), vct(0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), "8 set samples 0 at 1 for 0.1") set_samples(10, 10, "fmv1.snd", ind, 0, false, "another name 9", 0, 0) snd_test_neq(channel2vct(0, 20, ind, 0), vct(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5), "9 set samples 0 at 1 for 0.1") set_samples(20, 10, "fmv1.snd") snd_test_neq(channel2vct(10, 20, ind, 0), Vct.new(20, 0.5), "10 set samples 0 at 1 for 0.1") revert_sound(ind) set_samples(0, 10, "fmv1.snd", ind, 0, true, "another name", 1, 0, false) snd_test_neq(framples(ind, 0), 10, "11 set samples truncate") revert_sound(ind) delete_file("fmv1.snd") # res = Snd.catch do set_samples(0, 10, "fmv1.snd", ind, 0) end if res.first != :no_such_file snd_display("set samples, no such file: %s", res.inspect) end nd = new_sound("fmv1.snd", :channels, 1) vct2channel(Vct.new(10, 0.5), 0, 10, nd, 0) save_sound_as("fmv1.snd", nd) close_sound(nd) if (res = Snd.catch do set_samples(0, 10, "fmv1.snd", ind, 0, false, "another name", 1) end).first != :no_such_channel snd_display("set samples no such channel: %s", res.inspect) end if (res = Snd.catch do set_samples(0, 10, "fmv1.snd", ind, 0, false, "another name", -1) end).first != :no_such_channel snd_display("set samples no such channel (-1): %s", res.inspect) end res = Snd.catch do set_samples(0, -10, "fmv1.snd") end if res.first != :wrong_type_arg snd_display("set samples (-10): %s", res.inspect) end res = Snd.catch do set_samples(-10, 10, "fmv1.snd") end if res.first != :no_such_sample snd_display("set samples (beg -10): %s", res.inspect) end close_sound(ind) # len = 100 [[Mus_bshort, 2 ** -15], [Mus_lshort, 2 ** -15], [Mus_mulaw, 0.02], [Mus_alaw, 0.02], [Mus_byte, 2 ** -7], [Mus_lfloat, 2 ** -23], [Mus_bint, 2 ** -23], [Mus_lint, 2 ** -23], [Mus_b24int, 2 ** -23], [Mus_l24int, 2 ** -23], [Mus_ubshort, 2 ** -15], [Mus_ulshort, 2 ** -15], [Mus_ubyte, 2 ** -7], [Mus_bfloat, 2 ** -23], [Mus_bdouble, 2 ** -23], [Mus_ldouble, 2 ** -23]].each do |type, allowed_diff| ind = new_sound("test.snd", 1, 22050, Mus_bfloat, Mus_next) v = make_vct(len) maxdiff = 0.0 maxpos = false v[0] = 0.999 v[1] = -1.000 v[2] = 0.100 v[3] = -0.100 v[4] = 0.010 v[5] = -0.010 v[6] = 0.001 v[7] = -0.001 v[8] = 0.000 9.upto(len - 1) do |i| val = random(1.9999) if val > 2.0 or val < 0.0 snd_display("random 2.0: %1.4f?", val) end v[i] = 1.0 - val end vct2channel(v, 0, len, ind, 0) save_sound_as("test1.snd", ind, :header_type, Mus_next, :sample_type, type) close_sound(ind) ind = open_sound("test1.snd") v1 = channel2vct(0, len, ind, 0) len.times do |i| diff = (v[i] - v1[i]).abs if diff > maxdiff maxdiff = diff maxpos = i end end if maxdiff > allowed_diff snd_display(snd_format_neq(v1[maxpos], v[maxpos], "type %s: maxdiff %1.4f, maxpos %d", mus_sample_type_name(type), maxdiff, maxpos)) end close_sound(ind) end # ob = view_sound(oboe_snd) samp = sample(1000, ob) old_comment = mus_sound_comment(oboe_snd) str = format("written %s", Time.now.localtime.strftime("%a %d-%b-%Y %H:%M")) set_comment(ob, str) # check_it = lambda do |snd, type, fmt| snd_test_neq(header_type(snd), type, "save_as %s", mus_header_type_name(type)) ntyp = mus_sound_header_type("test.snd") snd_test_neq(ntyp, type, "saved_as %s -> %s", mus_header_type_name(type), mus_header_type_name(ntyp)) snd_test_neq(sample_type(snd), fmt, "save_as %s", mus_sample_type_name(fmt)) nfmt = mus_sound_sample_type("test.snd") snd_test_neq(nfmt, fmt, "saved_as %s -> %s", mus_sample_type_name(fmt), mus_sample_type_name(nfmt)) snd_test_neq(sample(1000, snd), samp, "%s[1000]", mus_header_type_name(type)) end # tag = Snd.catch do save_sound_as("test.snd", ob, :header_type, Mus_aifc, :sample_type, Mus_bdouble) end if tag.first == :cannot_save snd_display("save_sound_as test.snd write trouble: %s", tag) end # set_filter_control_in_hz(true) ab = open_sound("test.snd") check_it.call(ab, Mus_aifc, Mus_bdouble) snd_test_neq(mus_sound_comment("test.snd"), str, "output_comment") snd_test_neq(comment(ab), str, "output_comment (comment)") close_sound(ab) snd_test_neq(mus_sound_comment(oboe_snd), old_comment, "set_comment overwrote current") set_filter_control_in_hz(false) # save_sound_as("test.snd", ob, :header_type, Mus_raw) ab = open_raw_sound("test.snd", 1, 22050, Mus_bshort) check_it.call(ab, Mus_raw, Mus_bshort) close_sound(ab) # save_sound_as("test.snd", ob, :header_type, Mus_nist, :sample_type, Mus_bint) ab = open_sound("test.snd") check_it.call(ab, Mus_nist, Mus_bint) close_sound(ab) # $output_comment_hook.reset_hook! $output_comment_hook.add_hook!("snd-test-4") do |string| string + " [written by me]" end save_sound_as(:file, "test.snd", :sound, ob, :header_type, Mus_riff, :sample_type, Mus_lfloat) $output_comment_hook.reset_hook! ab = open_sound("test.snd") check_it.call(ab, Mus_riff, Mus_lfloat) snd_test_neq(comment(ab), str + " [written by me]", "output_comment_hook") close_sound(ab) [[Mus_aiff, Mus_b24int], [Mus_ircam, Mus_mulaw], [Mus_next, Mus_alaw], [Mus_next, Mus_ldouble]].each do |type, fmt| save_sound_as("test.snd", ob, :header_type, type, :sample_type, fmt) ab = open_sound("test.snd") check_it.call(ab, type, fmt) close_sound(ab) end save_sound_as("test.snd", ob, :header_type, Mus_next, :sample_type, Mus_bshort) ab = open_sound("test.snd") check_it.call(ab, Mus_next, Mus_bshort) $update_hook.reset_hook! set_y_bounds([-3.0, 3.0], ab, 0) set_sample_type(ab, Mus_lshort) # ; these set!'s can change the index via update-sound if find_sound("test.snd") != ab ab = find_sound("test.snd") end frm = sample_type(ab) snd_test_neq(frm, Mus_lshort, "set_sample_type %s", mus_sample_type_name(frm)) snd_test_neq(y_bounds(ab, 0), [-3.0, 3.0], "set data format y_bounds") set_y_bounds([2.0], ab, 0) snd_test_neq(y_bounds(ab, 0), [-2.0, 2.0], "set data format y_bounds 1") set_y_bounds([-2.0], ab, 0) snd_test_neq(y_bounds(ab, 0), [-2.0, 2.0], "set data format y_bounds -2") set_header_type(ab, Mus_aifc) if find_sound("test.snd") != ab ab = find_sound("test.snd") end type = header_type(ab) snd_test_neq(type, Mus_aifc, "set_header_type %s", mus_header_type_name(type)) set_channels(ab, 3) if find_sound("test.snd") != ab ab = find_sound("test.snd") end snd_test_neq(channels(ab), 3, "set_channels") set_data_location(ab, 1234) if find_sound("test.snd") != ab ab = find_sound("test.snd") end snd_test_neq(data_location(ab), 1234, "set_data_location") old_size = data_size(ab) set_data_size(ab, 1234) if find_sound("test.snd") != ab ab = find_sound("test.snd") end snd_test_neq(data_size(ab), 1234, "set_data_size") set_data_size(ab, old_size) set_srate(ab, 12345) if find_sound("test.snd") != ab ab = find_sound("test.snd") end snd_test_neq(srate(ab), 12345, "set_srate") close_sound(ab) # save_sound_as("test.snd", ob, :header_type, Mus_next, :sample_type, Mus_bfloat) ab = open_sound("test.snd") check_it.call(ab, Mus_next, Mus_bfloat) close_sound(ab) # save_sound_as("test.snd", ob, :header_type, Mus_next, :sample_type, Mus_bshort) close_sound(ob) ab = open_sound("test.snd") set_sample_type(Mus_lshort) if find_sound("test.snd") != ab ab = find_sound("test.snd") end frm = sample_type(ab) snd_test_neq(frm, Mus_lshort, "set_sample_type %s", mus_sample_type_name(frm)) set_header_type(Mus_aifc) if find_sound("test.snd") != ab ab = find_sound("test.snd") end type = header_type(ab) snd_test_neq(type, Mus_aifc, "set_header_type %s", mus_header_type_name(type)) set_channels(3) if find_sound("test.snd") != ab ab = find_sound("test.snd") end snd_test_neq(channels(), 3, "set_channels") set_data_location(1234) if find_sound("test.snd") != ab ab = find_sound("test.snd") end snd_test_neq(data_location(), 1234, "set_data_location") set_srate(12345) if find_sound("test.snd") != ab ab = find_sound("test.snd") end snd_test_neq(srate(), 12345, "set_srate") close_sound(ab) # ind = open_sound("2a.snd") [[lambda do save_sound_as("test.snd", :header_type, Mus_riff, :sample_type, Mus_l24int, :channel, 0) end, Mus_riff, Mus_l24int, srate(ind)], [lambda do save_sound_as("test.snd", :header_type, Mus_aifc, :sample_type, Mus_bfloat, :channel, 1, :srate, 12345) end, Mus_aifc, Mus_bfloat, 12345], [lambda do save_sound_as("test.snd", :channel, 1, :comment, "this is a test") end, header_type(ind), sample_type(ind), srate(ind)]].each_with_index do |args, i| prc, type, fmt, sr = args prc.call snd = open_sound("test.snd") info = format("save_sound_as :channel %d", i) snd_test_neq(channels(snd), 1, "%s channels", info) snd_test_neq(header_type(snd), type, "%s header_type", info) snd_test_neq(sample_type(snd), fmt, "%s sample_type", info) snd_test_neq(srate(snd), sr, "%s srate", info) snd_test_neq(framples(snd), framples(ind, 0), "%s framples", info) snd_test_neq(maxamp(snd, 0), maxamp(ind, 0), "%s maxamp", info) close_sound(snd) end close_sound(ind) # [["t15.aiff", [[132300, 0.148], [132300, 0.126]]], ["M1F1-float64C-AFsp.aif", [[8000, -0.024], [8000, 0.021]]]].each do |f, vals| with_file(f) do |fsnd| ind = open_sound(fsnd) chn = -1 if vals.detect do |val| chn += 1 fneq(sample(val[0], ind, chn), val[1]) end snd_display("%s trouble[%s]: %s", fsnd, chn, vals.map_with_index do |val, i| sample(val[0], ind, i) end) end close_sound(ind) end end # [["bad_chans.snd", [0, 22050, 0]], ["bad_srate.snd", [1, 0, 0]], ["bad_sample_type.snd", [1, 22050, 4411]], ["bad_chans.aifc", [0, 22050, 0]], ["bad_srate.aifc", [1, 0, 0]], ["bad_length.aifc", [1, 22050, -10]], ["bad_chans.riff", [0, 22050, 0]], ["bad_srate.riff", [1, 0, 0]], ["bad_chans.nist", [0, 22050, 0]], ["bad_srate.nist", [1, 0, 0]], ["bad_length.nist", [1, 22050, -10]]].each do |f, vals| with_file(f) do |fsnd| res = Snd.catch do [mus_sound_chans(fsnd), mus_sound_srate(fsnd), mus_sound_framples(fsnd)] end.first if res != vals and res != :mus_error snd_display(snd_format_neq(res, vals, fsnd)) end end end # ind = open_sound("/usr/include/sys/" + Dir.pwd + "/oboe.snd") if (not sound?(ind)) or (short_file_name(ind) != "oboe.snd") snd_display("open_sound with slashes: %s", ind) end $bad_header_hook.reset_hook! $bad_header_hook.add_hook!("snd-test-4") do |n| true end ["bad_chans.snd", "bad_srate.snd", "bad_chans.aifc", "bad_srate.aifc", "bad_length.aifc", "bad_chans.riff", "bad_srate.riff", "bad_chans.nist", "bad_location.nist", "bad_field.nist", "bad_srate.nist", "bad_length.nist"].each do |f| with_file(f) do |fsnd| Snd.catch do insert_sound(fsnd) end Snd.catch do convolve_with(fsnd) end Snd.catch do mix(fsnd) end Snd.catch do snd = open_sound(fsnd) sound?(snd) and close_sound(snd) end end end close_sound(ind) Snd.sounds.apply(:close_sound) # if selected_sound snd_display("selected_sound %s %s?", selected_sound, sounds.inspect) end # with_file("a.sf2") do |fsnd| fil = open_sound(fsnd) loops = soundfont_info(fil) if loops.nil? or loops[0][2] != 65390 or loops[1][1] != 65490 snd_display("soundfont_info: %s", loops.inspect) end close_sound(fil) end end def test_04_01 ["trunc.snd", "trunc.aiff", "trunc.wav", "trunc.sf", "trunc.voc", "trunc.nist", "bad.wav", "trunc1.aiff", "badform.aiff"].each do |file| with_file(file) do |fsnd| res = Snd.catch do open_sound(fsnd) end snd_test_neq(res.first, :mus_error, "open_sound %s", file) end end $open_raw_sound_hook.add_hook!("snd-test-044") do |file, choice| [1, 22050, Mus_bshort] end with_file("empty.snd") do |fsnd| ind = open_sound(fsnd) if sample_type(ind) != Mus_bshort or channels(ind) != 1 or srate(ind) != 22050 or data_location(ind) != 0 or framples(ind) != 0 snd_display("open raw: %s %s %s %s %s?", sample_type(ind), channels(ind), srate(ind), data_location(ind), framples(ind)) end close_sound(ind) end $open_raw_sound_hook.reset_hook! end def test_04_03 # # check clipping choices # ind = view_sound("oboe.snd") set_clipping(false) scale_channel(10.0) save_sound_as("test.snd", ind, :header_type, Mus_next, :sample_type, Mus_bfloat) undo_edit(1, ind, 0) ind1 = open_sound("test.snd") snd_test_neq(maxamp(ind1, 0), 10.0 * maxamp(ind, 0), "clipping 0") close_sound(ind1) delete_file("test.snd") # set_clipping(true) map_channel(lambda do |y| y * 10.0 end, 0, framples(), ind, 0) save_sound_as("test.snd", ind, :header_type, Mus_next, :sample_type, Mus_bfloat) undo_edit(1, ind, 0) ind1 = open_sound("test.snd") snd_test_neq(maxamp(ind1, 0), 1.0, "clipping 1") close_sound(ind1) delete_file("test.snd") # set_clipping(false) mx = maxamp(ind) map_channel(lambda do |y| y + (1.001 - mx) end, 0, framples(), ind, 0) save_sound_as("test.snd", ind, :header_type, Mus_next, :sample_type, Mus_bfloat) ind1 = open_sound("test.snd") if res = scan_channel(lambda do |y| y < 0.0 end) snd_display("clipping 2: %s?", res) end close_sound(ind1) delete_file("test.snd") # set_clipping(true) save_sound_as("test.snd", ind, :header_type, Mus_next, :sample_type, Mus_bshort) ind1 = open_sound("test.snd") if res = scan_channel(lambda do |y| y < 0.0 end) snd_display("clipping 3: %s?", res) end close_sound(ind1) delete_file("test.snd") # set_clipping(false) close_sound(ind) # set_clipping(false) snd = new_sound("test.snd", :sample_type, Mus_lshort) pad_channel(0, 10) set_sample(1, 1.0) set_sample(2, -1.0) set_sample(3, 0.9999) set_sample(4, 2.0) set_sample(5, -2.0) set_sample(6, 1.3) set_sample(7, -1.3) set_sample(8, 1.8) set_sample(9, -1.8) save_sound(snd) close_sound(snd) snd = open_sound("test.snd") snd_test_neq(channel2vct(0, 10), vct(0.0, 1.0, -1.0, 1.0, 0.0, 0.0, -0.7, 0.7, -0.2, 0.2), "unclipped 1") close_sound(snd) mus_sound_forget("test.snd") # set_clipping(true) snd = new_sound("test.snd", :sample_type, Mus_lshort) pad_channel(0, 10) set_sample(1, 1.0) set_sample(2, -1.0) set_sample(3, 0.9999) set_sample(4, 2.0) set_sample(5, -2.0) set_sample(6, 1.3) set_sample(7, -1.3) set_sample(8, 1.8) set_sample(9, -1.8) save_sound(snd) close_sound(snd) snd = open_sound("test.snd") snd_test_neq(channel2vct(0, 10), vct(0.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0), "clipped") close_sound(snd) # with_file("32bit.sf") do |fsnd| ind = open_sound(fsnd) snd_test_neq(maxamp(ind, 0), 0.228, "32bit max") close_sound(ind) end [["next-dbl.snd", 10, 10, vct(0.475, 0.491, 0.499, 0.499, 0.492, 0.476, 0.453, 0.423, 0.387, 0.344)], ["oboe.ldbl", 1000, 10, vct(0.033, 0.035, 0.034, 0.031, 0.026, 0.020, 0.013, 0.009, 0.005, 0.004)], ["next-flt.snd", 10, 10, vct(0.475, 0.491, 0.499, 0.499, 0.492, 0.476, 0.453, 0.423, 0.387, 0.344)], ["clbonef.wav", 1000, 10, vct(0.111, 0.101, 0.070, 0.032, -0.014, -0.060, -0.085, -0.108, -0.129, -0.152)], ["next-8.snd", 10, 10, vct(0.898, 0.945, 0.977, 0.992, 0.992, 0.977, 0.945, 0.906, 0.844, 0.773)], ["o2_u8.wave", 1000, 10, vct(-0.164, -0.219, -0.258, -0.242, -0.180, -0.102, -0.047, 0.000, 0.039, 0.055)], ["next-16.snd", 1000, 10, vct(-0.026, -0.022, -0.024, -0.030, -0.041, -0.048, -0.050, -0.055, -0.048, -0.033)], ["o2.wave", 1000, 10, vct(-0.160, -0.216, -0.254, -0.239, -0.175, -0.102, -0.042, 0.005, 0.041, 0.059)], ["o2_18bit.aiff", 1000, 10, vct(-0.160, -0.216, -0.254, -0.239, -0.175, -0.102, -0.042, 0.005, 0.041, 0.059)], ["o2_12bit.aiff", 1000, 10, vct(-0.160, -0.216, -0.254, -0.239, -0.175, -0.102, -0.042, 0.005, 0.041, 0.059)], ["next24.snd", 1000, 10, vct(-0.160, -0.216, -0.254, -0.239, -0.175, -0.102, -0.042, 0.005, 0.041, 0.059)], ["mono24.wav", 1000, 10, vct(0.005, 0.010, 0.016, 0.008, -0.007, -0.018, -0.025, -0.021, -0.005, 0.001)], ["o2_711u.wave", 1000, 10, vct(-0.164, -0.219, -0.254, -0.242, -0.172, -0.103, -0.042, 0.005, 0.042, 0.060)], ["alaw.wav", 1000, 10, vct(-0.024, -0.048, -0.024, 0.000, 0.008, 0.008, 0.000, -0.040, -0.064, -0.024)], ["b32.pvf", 1000, 10, vct(-0.160, -0.216, -0.254, -0.239, -0.175, -0.102, -0.042, 0.005, 0.041, 0.059)], ["b32.wave", 1000, 10, vct(-0.160, -0.216, -0.254, -0.239, -0.175, -0.102, -0.042, 0.005, 0.041, 0.059)], ["b32.snd", 1000, 10, vct(-0.160, -0.216, -0.254, -0.239, -0.175, -0.102, -0.042, 0.005, 0.041, 0.059)], ["32bit.sf", 1000, 10, vct(0.016, 0.014, 0.013, 0.011, 0.010, 0.010, 0.010, 0.010, 0.012, 0.014)], ["nist-shortpack.wav", 10000, 10, vct(0.021, 0.018, 0.014, 0.009, 0.004, -0.001, -0.004, -0.006, -0.007, -0.008)], ["wood.sds", 1000, 10, vct(-0.160, -0.216, -0.254, -0.239, -0.175, -0.102, -0.042, 0.005, 0.041, 0.059)], ["mus10.snd", 10000, 10, vct(0.004, 0.001, 0.005, 0.009, 0.017, 0.015, 0.008, 0.011, 0.009, 0.012)], ["ieee-text-16.snd", 1000, 10, vct(-0.052, -0.056, -0.069, -0.077, -0.065, -0.049, -0.054, -0.062, -0.066, -0.074)], ["hcom-16.snd", 10000, 10, vct(0.000, 0.000, 0.000, 0.008, 0.000, -0.016, -0.016, -0.016, -0.008, 0.000)], ["ce-c3.w02", 1000, 10, vct(0.581, 0.598, 0.596, 0.577, 0.552, 0.530, 0.508, 0.479, 0.449, 0.425)], ["nasahal.avi", 20000, 10, vct(0.390, 0.120, -0.399, -0.131, 0.464, 0.189, -0.458, -0.150, 0.593, 0.439)], ["oki.wav", 100, 10, vct(0.396, 0.564, 0.677, 0.779, 0.761, 0.540, 0.209, -0.100, -0.301, -0.265)], ["trumps22.adp", 5000, 10, vct(0.267, 0.278, 0.309, 0.360, 0.383, 0.414, 0.464, 0.475, 0.486, 0.495)] ].each do |file, beg, dur, data| with_file(file) do |fsnd| Snd.catch do ind = open_sound(fsnd) snd_test_neq(channel2vct(beg, dur, ind, 0), data, "%s", file) close_sound(ind) end end end end def test_04_04 ["no error", "no frequency method", "no phase method", "null gen arg to method", "no length method", "no describe method", "no data method", "no scaler method", "memory allocation failed", "can't open file", "no sample input", "no sample output", "no such channel", "no file name provided", "no location method", "no channel method", "no such fft window", "unknown sample type", "header read failed", "unknown header type", "file descriptors not initialized", "not a sound file", "file closed", "write error", "header write failed", "can't open temp file", "interrupted", "bad envelope", "audio channels not available", "audio srate not available", "audio sample type not available", "no audio input available", "audio configuration not available", "audio write error", "audio size not available", "audio device not available", "can't close audio", "can't open audio", "audio read error", "can't write audio", "can't read audio", "no audio read permission", "can't close file", "arg out of range", "no channels method", "no hop method", "no width method", "no file-name method", "no ramp method", "no run method", "no increment method", "no offset method", "no xcoeff method", "no ycoeff method", "no xcoeffs method", "no ycoeffs method", "no reset", "bad size", "can't convert", "read error", "no feedforward method", "no feedback method", "no interp-type method", "no position method", "no order method", "no copy method", "can't translate"].each_with_index do |err, i| snd_test_neq(err, mus_error_type2string(i), "mus_error_type2string %d", i) end oboe_snd = "oboe.snd" cur_srate = mus_sound_srate(oboe_snd) cur_chans = mus_sound_chans(oboe_snd) cur_format = mus_sound_sample_type(oboe_snd) cur_type = mus_sound_header_type(oboe_snd) cur_loc = mus_sound_data_location(oboe_snd) cur_samps = mus_sound_samples(oboe_snd) set_mus_sound_srate(oboe_snd, cur_srate * 2) snd_test_neq(mus_sound_srate(oboe_snd), cur_srate * 2, "set_mus_sound_srate") set_mus_sound_samples(oboe_snd, cur_samps * 2) snd_test_neq(mus_sound_samples(oboe_snd), cur_samps * 2, "set_mus_sound_samples") set_mus_sound_chans(oboe_snd, cur_chans * 2) snd_test_neq(mus_sound_chans(oboe_snd), cur_chans * 2, "set_mus_sound_chans") set_mus_sound_data_location(oboe_snd, cur_loc * 2) snd_test_neq(mus_sound_data_location(oboe_snd), cur_loc * 2, "set_mus_sound_data_location") set_mus_sound_header_type(oboe_snd, Mus_nist) snd_test_neq(mus_sound_header_type(oboe_snd), Mus_nist, "set_mus_sound_header_type") set_mus_sound_sample_type(oboe_snd, Mus_lintn) snd_test_neq(mus_sound_sample_type(oboe_snd), Mus_lintn, "set_mus_sound_sample_type") set_mus_sound_srate(oboe_snd, cur_srate) set_mus_sound_samples(oboe_snd, cur_samps) set_mus_sound_chans(oboe_snd, cur_chans) set_mus_sound_data_location(oboe_snd, cur_loc) set_mus_sound_header_type(oboe_snd, cur_type) set_mus_sound_sample_type(oboe_snd, cur_format) # ind = open_sound("oboe.snd") save_sound_as("test.wave", ind, :header_type, Mus_riff) save_sound_as("test.rf64", ind, :header_type, Mus_rf64) save_sound_as("test.aifc", ind, :header_type, Mus_aifc) close_sound(ind) ["test.wave", "test.rf64", "test.aifc"].each do |file| cur_srate = mus_sound_srate(file) cur_chans = mus_sound_chans(file) cur_format = mus_sound_sample_type(file) cur_type = mus_sound_header_type(file) cur_loc = mus_sound_data_location(file) cur_samps = mus_sound_samples(file) set_mus_sound_srate(file, cur_srate * 2) snd_test_neq(mus_sound_srate(file), cur_srate * 2, "%s set_mus_sound_srate", file) set_mus_sound_samples(file, cur_samps * 2) snd_test_neq(mus_sound_samples(file), cur_samps * 2, "%s set_mus_sound_samples", file) set_mus_sound_chans(file, cur_chans * 2) snd_test_neq(mus_sound_chans(file), cur_chans * 2, "%s set_mus_sound_chans", file) set_mus_sound_data_location(file, cur_loc * 2) snd_test_neq(mus_sound_data_location(file), cur_loc * 2, "%s set_mus_sound_data_location", file) set_mus_sound_header_type(file, Mus_nist) snd_test_neq(mus_sound_header_type(file), Mus_nist, "%s set_mus_sound_header_type", file) set_mus_sound_sample_type(file, Mus_lintn) snd_test_neq(mus_sound_sample_type(file), Mus_lintn, "%s set_mus_sound_sample_type", file) set_mus_sound_srate(file, cur_srate) set_mus_sound_samples(file, cur_samps) set_mus_sound_chans(file, cur_chans) set_mus_sound_data_location(file, cur_loc) set_mus_sound_header_type(file, cur_type) set_mus_sound_sample_type(file, cur_format) end ["test.wave", "test.rf64", "test.aifc"].each do |file| ind = open_sound(file) cur_srate = srate(ind) cur_chans = chans(ind) cur_format = sample_type(ind) cur_type = header_type(ind) cur_loc = data_location(ind) cur_samps = framples(ind) set_srate(ind, cur_srate * 2) snd_test_neq(srate(ind), cur_srate * 2, "%s set_srate", file) set_framples(cur_samps * 2, ind) snd_test_neq(framples(ind), cur_samps * 2, "%s set_framples", file) set_chans(ind, cur_chans * 2) # this can change the index xind = find_sound(file) if ind != xind ind = xind end snd_test_neq(chans(ind), cur_chans * 2, "%s set_chans", file) set_data_location(ind, cur_loc * 2) snd_test_neq(data_location(ind), cur_loc * 2, "%s set_location", file) set_header_type(ind, Mus_nist) snd_test_neq(header_type(ind), Mus_nist, "%s set_header_type", file) set_sample_type(ind, Mus_lintn) snd_test_neq(sample_type(ind), Mus_lintn, "%s set_sample_type", file) set_srate(ind, cur_srate) set_framples(cur_samps, ind) set_channels(ind, cur_chans) set_data_location(ind, cur_loc) set_header_type(ind, cur_type) set_sample_type(ind, cur_format) close_sound(ind) delete_file(file) end unless $with_test_motif end # XXX: with big file # # with_sound(:output, $bigger_snd, :srate, 44100, :play, false) do # 72000.times do |i| # fm_violin_1(i, 0.1, 440, i / 72000.0 * 0.9 + 0.01) # end # end $big_file_framples = 0 def test_04_05 if File.exist?($bigger_snd) # ; silence as last .9 secs, so it probably wasn't written probable_framples = (44100 * 71999.1).floor snd_test_neq(mus_sound_samples($bigger_snd), 3175160310, "bigger samples") snd_test_neq(mus_sound_framples($bigger_snd), 3175160310, "bigger framples") snd_test_neq(mus_sound_framples($bigger_snd), probable_framples, "bigger framples (probable)") snd_test_neq(mus_sound_length($bigger_snd), 6350320648, "bigger length") snd_test_neq(mus_sound_duration($bigger_snd), 71999.1015, "bigger dur") ind = open_sound($bigger_snd) snd_test_neq(framples(ind), 3175160310, "bigger framples") $big_file_framples = framples(ind) snd_test_neq(framples(ind), probable_framples, "bigger framples (probable)") snd_test_neq(framples(ind, 0, 0), $big_file_framples, "bigger edpos-framples") m1 = add_mark(44100 * 50000, ind) snd_test_neq(mark_sample(m1), 44100 * 50000, "bigger mark at") set_mark_sample(m1, 44100 * 66000) snd_test_neq(mark_sample(m1), 44100 * 66000, "bigger mark to") if mix?(mx = mix_sound("oboe.snd", 44100 * 60000).car) snd_test_neq(mix_position(mx), 44100 * 60000, "bigger mix at") set_mix_position(mx, 44100 * 61000) snd_test_neq(mix_position(mx), 44100 * 61000, "bigger mix to") undo_edit(2) else snd_display("no mix tag from mix_sound: %s?", mx) end res = find_channel(lambda do |y| y != 0.0 end) if res.kind_of?(FalseClass) or res > 100 snd_display("bigger find not 0.0: %s", res) end old_select = selection_creates_region set_selection_creates_region(false) select_all(ind) snd_test_neq(selection_framples(), framples(ind), "bigger select all") set_selection_position(44100 * 50000) snd_test_neq(selection_position(), 44100 * 50000, "bigger select pos") set_selection_position(0) set_selection_framples(44100 * 65000) snd_test_neq(selection_framples(), 44100 * 65000, "bigger select len") set_selection_creates_region(old_select) set_cursor(44100 * 50000, ind) snd_test_neq(cursor(ind), 44100 * 50000, "bigger cursor") m1 = add_mark(44123 * 51234, ind) snd_test_neq(mark_sample(m1), 44123 * 51234, "bigger mark at") mid = find_mark(44123 * 51234) snd_test_neq(mid, m1, "bigger find_mark") mx = mix_sound("oboe.snd", 44123 * 51234).car mxd = find_mix(44123 * 51234) snd_test_neq(mxd, mx, "bigger find_mix") set_cursor(44123 * 51234, ind) snd_test_neq(cursor(ind), 44123 * 51234, "bigger cursor 123") close_sound(ind) end end def test_04_06 ind = new_sound("tmp.snd", 1, 22050, Mus_l24int, Mus_riff, :size, 100000) old_selection_creates_region = selection_creates_region() set_selection_creates_region(true) x = -0.5 incr = 1.0 / framples() map_channel(lambda do |n| val = x x += incr val end) save_sound(ind) close_sound(ind) ind = open_sound("tmp.snd") reg = select_all [[:Mus_next, :Mus_l24int], [:Mus_aifc, :Mus_l24int]].each do |ht, df| save_selection("tmp1.snd", 44100, Module.const_get(df), Module.const_get(ht)) ind1 = open_sound("tmp1.snd") x = -0.5 incr = 1.0 / framples() err = scan_channel(lambda do |n| val = x x += incr fneq(val, n) end, 0, 100000, ind1) if err snd_display("%s (%s) selection not saved correctly? %s", df, ht, err) end close_sound(ind1) end save_region(reg, "tmp1.snd", Mus_l24int, Mus_next) ind1 = open_sound("tmp1.snd") x = -0.5 incr = 1.0 / framples() err = scan_channel(lambda do |n| val = x x += incr fneq(val, n) end, 0, 100000, ind1) if err snd_display("Mus_l24int (Mus_next) region not saved correctly? %s", err) end close_sound(ind1) delete_file("tmp1.snd") close_sound(ind) delete_file("tmp.snd") set_selection_creates_region(old_selection_creates_region) # ind = new_sound("tmp.snd", 1, 22050, Mus_bfloat, Mus_next, :size, 10, :comment, false) map_channel($init_channel) env_channel([0.0, 0.0, 0.1, 0.1, 0.2, 0.2, 0.3, 0.3, 0.4, 0.4, 0.5, 0.5, 0.6, 0.6, 0.7, 0.7, 0.8, 0.8, 0.9, 0.9]) snd_test_neq(channel2vct(), vct(0.000, 0.100, 0.200, 0.300, 0.400, 0.500, 0.600, 0.700, 0.800, 0.900), "ramp env by 0.1") close_sound(ind) end def test_04_07 $open_raw_sound_hook.reset_hook! $open_raw_sound_hook.add_hook!(get_func_name) do |a, b| true end $bad_header_hook.reset_hook! $bad_header_hook.add_hook!(get_func_name) do |n| true end if $open_raw_sound_hook.empty? snd_display("$open_raw_sound_hook.add_hook! failed??") end if $bad_header_hook.empty? snd_display("$bad_header_hook.add_hook! failed??") end magic_words = [".snd", "FORM", "AIFF", "AIFC", "COMM", "COMT", "INFO", "INST", "inst", "MARK", "SSND", "FVER", "NONE", "ULAW", "ulaw", "ima4", "raw ", "sowt", "in32", "in24", "ni23", "fl32", "FL32", "fl64", "twos", "ALAW", "alaw", "APPL", "CLM ", "RIFF", "RIFX", "WAVE", "fmt ", "data", "fact", "clm ", "NIST", "8SVX", "16SV", "Crea", "tive", "SOUN", "D SA", "MPLE", "BODY", "VHDR", "CHAN", "ANNO", "NAME", "2BIT", "HCOM", "FSSD", "%//\n", "%---", "ALaw", "Soun", "MAUD", "MHDR", "MDAT", "mdat", "MThd", "sfbk", "sdta", "shdr", "pdta", "LIST", "GF1P", "ATCH", "$SIG", "NAL_", "GOLD", " SAM", "SRFS", "Diam", "ondW", "CSRE", "SND ", "SNIN", "SNDT", "DDSF", "FSMu", "UWFD", "LM89", "SY80", "SY85", "SCRS", "DSPL", "AVI ", "strf", "movi", "PRAM", " paf", "fap ", "DS16", "HEDR", "HDR8", "SDA_", "SDAB", "SD_B", "NOTE", "file", "=sam", "SU7M", "SU7R", "PVF1", "PVF2", "AUTH", "riff", "TWIN", "IMPS", "SMP1", "Maui", "SDIF", "NVF "] len = magic_words.length magic_words.each_with_index do |magic, ctr| if $open_raw_sound_hook.empty? snd_display("$open_raw_sound_hook.add_hook! cleared??") end if $bad_header_hook.empty? snd_display("$bad_header_hook.add_hook! cleared??") end delete_file("test.snd") mus_sound_forget("test.snd") File.open("test.snd", "w") do |fp| fp.write(magic) 128.times do fp.write(mus_random(1.0)) end end res = Snd.catch do open_sound("test.snd") end.first if number?(res) and sound?(res) snd_display("open_sound garbage %s: %s?", magic, res) if sound?(res) close_sound(res) end end delete_file("test.snd") mus_sound_forget("test.snd") File.open("test.snd", "w") do |fp| fp.write(magic) 128.times do fp.write(mus_random(128)) end end res = Snd.catch do open_sound("test.snd") end.first if number?(res) and sound?(res) snd_display("open_sound plausible garbage %s: %s?", magic, res) if sound?(res) close_sound(res) end end delete_file("test.snd") mus_sound_forget("test.snd") File.open("test.snd", "w") do |fp| fp.write(magic) (1...12).each do |i| if (ctr + i) < len fp.write(magic_words[ctr + i]) else fp.write(magic_words[i]) end end end res = Snd.catch do open_sound("test.snd") end.first if number?(res) and sound?(res) snd_display("open_sound very plausible garbage %s: %s?", magic, res) if sound?(res) close_sound(res) end end end delete_file("test.snd") mus_sound_forget("test.snd") end def make_aifc_file(framples, auth_lo, bits) File.open("test.aif", "w") do |fp| fp.write "FORM" fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0146); # len fp.write "AIFCFVER" fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0004); # version chunk size fp.putc(0242); fp.putc(0200); fp.putc(0121); fp.putc(0100); # version fp.write "COMM" fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0046); # COMM chunk size fp.putc(0000); fp.putc(0001); # 1 chan fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(framples); # framples fp.putc(0000); fp.putc(bits); # bits fp.putc(0100); fp.putc(0016); fp.putc(0254); fp.putc(0104); fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); # srate as 80-bit float (sheesh) fp.write "NONE" # compression fp.putc(0016); # pascal string len fp.write "not compressed" fp.putc(0000); fp.write "AUTH" fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(auth_lo); # AUTH chunk size fp.write "bil" fp.putc(0000); fp.write "SSND" fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0014); # SSND chunk size fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); # SSND data loc fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); # block size? fp.putc(0000); fp.putc(0101); fp.putc(0000); fp.putc(0100); # two samples end end undef read_ascii def read_ascii(in_filename, out_filename = "test.snd", out_type = Mus_next, out_format = Mus_bshort, out_srate = 44100) in_buffer = IO.readlines(in_filename) # array of strings out_snd = new_sound(out_filename, 1, out_srate, out_format, out_type, format("created by %s: %s", get_func_name, in_filename)) bufsize = 512 data = make_vct(bufsize) loc = 0 frame = 0 short2float = 1.0 / 32768.0 as_one_edit_rb do | | in_buffer.each do |line| line.split.each do |str_val| val = eval(str_val) data[loc] = val * short2float loc += 1 if loc == bufsize vct2channel(data, frame, bufsize, out_snd, 0) frame += bufsize loc = 0 end end end if loc > 0 vct2channel(data, frame, loc, out_snd, 0) end end out_snd end def test_04_08 File.open("test.snd", "w") do |fp| fp.write ".snd" fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0034); # location fp.putc(0000); fp.putc(0001); fp.putc(0215); fp.putc(0030); # nominal size fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0022); # format fp.putc(0000); fp.putc(0000); fp.putc(0126); fp.putc(0042); # srate fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0001); # chans fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); # comment fp.putc(0000); fp.putc(0001); # samp 1 end snd_test_neq(mus_sound_sample_type("test.snd"), Mus_bshort, "next 18") delete_file("test.snd") mus_sound_forget("test.snd") File.open("test.snd", "w") do |fp| fp.write ".snd" fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0004); # location fp.putc(0000); fp.putc(0001); fp.putc(0215); fp.putc(0030); # nominal size fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0022); # format fp.putc(0000); fp.putc(0000); fp.putc(0126); fp.putc(0042); # srate fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0001); # chans fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); # comment fp.putc(0000); fp.putc(0001); # samp 1 end res = Snd.catch do open_sound("test.snd") end.first if number?(res) and sound?(res) snd_display("open_sound next bad location %s: %s?", data_location(res), res) close_sound(res) end delete_file("test.snd") mus_sound_forget("test.snd") File.open("test.snd", "w") do |fp| fp.write ".snd" fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0034); # location fp.putc(0000); fp.putc(0001); fp.putc(0215); fp.putc(0030); # nominal size fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0122); # format fp.putc(0000); fp.putc(0000); fp.putc(0126); fp.putc(0042); # srate fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0001); # chans fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); # comment fp.putc(0000); fp.putc(0001); # samp 1 end res = Snd.catch do open_sound("test.snd") end.first if number?(res) and sound?(res) snd_display("open_sound next bad format %s: %s?", sample_type(res), res) close_sound(res) end delete_file("test.snd") mus_sound_forget("test.snd") delete_file("test.aif") mus_sound_forget("test.aif") # # ;;correct (make-aifc-file #o002 #o004 #o020) # make_aifc_file(0102, 004, 020) Snd.catch do ind = open_sound("test.aif") snd_test_neq(framples(ind), 2, "bad framples in header") close_sound(ind) end delete_file("test.aif") mus_sound_forget("test.aif") make_aifc_file(002, 150, 020) res = Snd.catch do open_sound("test.aif") end.first if number?(res) and sound?(res) snd_display("open_sound aifc no ssnd chunk %s: %s?", data_location(res), res) close_sound(res) end delete_file("test.aif") mus_sound_forget("test.aif") make_aifc_file(002, 000, 020) res = Snd.catch do open_sound("test.aif") end.first if number?(res) and sound?(res) snd_display("open_sound aifc 0-len auth chunk %s: %s?", data_location(res), res) close_sound(res) end delete_file("test.aif") mus_sound_forget("test.aif") make_aifc_file(002, 150, 120) res = Snd.catch do open_sound("test.aif") end.first if number?(res) and sound?(res) snd_display("open_sound aifc bits 80 %s: %s?", sample_type(res), res) close_sound(res) end delete_file("test.aif") mus_sound_forget("test.aif") File.open("test.aif", "w") do |fp| fp.write "FORM" fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0176); # len fp.write "AIFCFVER" fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0004); # version chunk size fp.putc(0242); fp.putc(0200); fp.putc(0121); fp.putc(0100); # version fp.write "COMM" fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0046); # COMM chunk size fp.putc(0000); fp.putc(0001); # 1 chan fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0002); # framples fp.putc(0000); fp.putc(0020); # bits fp.putc(0100); fp.putc(0016); fp.putc(0254); fp.putc(0104); fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); # srate as 80-bit float (sheesh) fp.write "NONE" # compression fp.putc(0016); # pascal string len fp.write "not compressed" fp.putc(0000); fp.write "AUTH" fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0004); # AUTH chunk size fp.write "bil" fp.putc(0000); fp.write "ANNO" fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0004); # AUTH chunk size fp.write "cat" fp.putc(0000); fp.write "NAME" fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0004); # AUTH chunk size fp.write "dog" fp.putc(0000); fp.write "SSND" fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0004); # AUTH chunk size fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0014); # SSND chunk size fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); # SSND data loc fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); # block size? fp.putc(0000); fp.putc(0101); fp.putc(0000); fp.putc(0100); # two samples end Snd.catch do snd_test_neq(mus_sound_comment("test.aif").length, 15, "aifc 3 aux comments") end delete_file("test.aif") mus_sound_forget("test.aif") File.open("test.aif", "w") do |fp| fp.write "FORM" fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0142); # len fp.write "AIFC" fp.write "SSND" fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0014); # SSND chunk size fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); # SSND data location fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); # block size? fp.putc(0000); fp.putc(0101); fp.putc(0000); fp.putc(0100); # two samples fp.write "COMM" fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0046); # COMM chunk size fp.putc(0000); fp.putc(0001); # 1 chan fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0002); # framples fp.putc(0000); fp.putc(0020); # bits fp.putc(0100); fp.putc(0016); fp.putc(0254); fp.putc(0104); fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); # srate as 80-bit float (sheesh) fp.write "NONE" # compression fp.putc(0016); # pascal string len fp.write "not compressed" fp.putc(0000); fp.write "COMT" fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0014); fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.write "bil" fp.putc(0000); end Snd.catch do snd_test_neq(mus_sound_comment("test.aif")[0..2], "bil", "aifc trailing comt comments") end snd_test_neq(mus_sound_framples("test.aif"), 2, "aifc trailing comt framples") Snd.catch do ind = open_sound("test.aif") if fneq(sample(0), 0.00198) or fneq(sample(1), 0.00195) or fneq(sample(2), 0.0) or fneq(sample(3), 0.0) snd_display("aifc trailing comt samps: %s %s %s %s", sample(0), sample(1), sample(2), sample(3)) end close_sound(ind) end delete_file("test.aif") mus_sound_forget("test.aif") File.open("test.aif", "w") do |fp| fp.write "FORM" fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0142); # len fp.write "AIFC" fp.write "SSND" fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0014); # SSND chunk size fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); # SSND data location fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); # block size? fp.putc(0000); fp.putc(0101); fp.putc(0000); fp.putc(0100); # two samples fp.write "COMM" fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0046); # COMM chunk size fp.putc(0000); fp.putc(0001); # 1 chan fp.putc(0000); fp.putc(0000); fp.putc(0100); fp.putc(0102); # framples fp.putc(0000); fp.putc(0020); # bits fp.putc(0100); fp.putc(0016); fp.putc(0254); fp.putc(0104); fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); # srate as 80-bit float (sheesh) fp.write "NONE" # compression fp.putc(0016); # pascal string len fp.write "not compressed" fp.putc(0000); fp.write "COMT" fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0014); fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0101); fp.putc(0000); fp.putc(0000); fp.write "bil" fp.putc(0000); end snd_test_neq(mus_sound_comment("test.aif")[0..2], "bil", "aifc trailing comt comment") snd_test_neq(mus_sound_framples("test.aif"), 2, "aifc trailing comt (bogus) framples") Snd.catch do ind = open_sound("test.aif") if fneq(sample(0), 0.00198) or fneq(sample(1), 0.00195) or fneq(sample(2), 0.0) or fneq(sample(3), 0.0) snd_display("aifc trailing comt samps (bogus frame setting): %s %s %s %s", sample(0), sample(1), sample(2), sample(3)) end close_sound(ind) end delete_file("test.aif") mus_sound_forget("test.aif") File.open("test.aif", "w") do |fp| fp.write "FORM" fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0142); # len fp.write "AIFC" fp.write "SSND" fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0014); # SSND chunk size fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); # SSND data location fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); # block size? fp.putc(0000); fp.putc(0101); fp.putc(0000); fp.putc(0100); # two samples fp.write "COMM" fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0046); # COMM chunk size fp.putc(0000); fp.putc(0001); # 1 chan fp.putc(0000); fp.putc(0000); fp.putc(0100); fp.putc(0102); # framples fp.putc(0000); fp.putc(0020); # bits fp.putc(0100); fp.putc(0016); fp.putc(0254); fp.putc(0104); fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); # srate as 80-bit float (sheesh) fp.write "NONE" # compression fp.putc(0016); # pascal string len fp.write "not compressed" fp.putc(0000); fp.write "SSND" fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0014); fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0101); fp.putc(0000); fp.putc(0100); end res = Snd.catch do open_sound("test.aif") end.first if number?(res) and sound?(res) snd_display("open_sound aifc 2 ssnd chunks %s: %s?", data_location(res), res) close_sound(res) end delete_file("test.aif") mus_sound_forget("test.aif") File.open("test.aif", "w") do |fp| fp.write "FORM" fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0040); # len fp.write "AIFC" fp.write "SSND" fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0014); # SSND chunk size fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); # SSND data location fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); # block size? fp.putc(0000); fp.putc(0101); fp.putc(0000); fp.putc(0100); # two samples end res = Snd.catch do open_sound("test.aif") end.first if res != :mus_error snd_display("open_sound aifc no comm chunk: %s?", res) if number?(res) and sound?(res) close_sound(res) end end delete_file("test.aif") mus_sound_forget("test.aif") # File.open("test.aif", "w") do |fp| # write AIFC with trailing chunks to try to confuse file->sample fp.write "FORM" fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0176); # len fp.write "AIFCFVER" fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0004); # version chunk size fp.putc(0242); fp.putc(0200); fp.putc(0121); fp.putc(0100); # version fp.write "COMM" fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0046); # COMM chunk size fp.putc(0000); fp.putc(0001); # 1 chan fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0002); # framples fp.putc(0000); fp.putc(0020); # bits fp.putc(0100); fp.putc(0016); fp.putc(0254); fp.putc(0104); fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); # srate as 80-bit float (sheesh) fp.write "NONE" # compression fp.putc(0016); # pascal string len fp.write "not compressed" fp.putc(0000); fp.write "SSND" fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0014); fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0170); fp.putc(0101); fp.putc(0100); fp.putc(0100); # two samples fp.write "AUTH" fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0004); # AUTH chunk size fp.write "bil" fp.putc(0000); fp.write "ANNO" fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0004); fp.write "cat" fp.putc(0000); fp.write "NAME" fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0004); fp.write "dog" fp.putc(0000); end Snd.catch do gen = make_file2sample("test.aif") snd_test_neq(gen.call(0), 0.93948, "file2sample chunked 0") snd_test_neq(gen.call(1), 0.50195, "file2sample chunked 1") snd_test_neq(gen.call(2), 0.00000, "file2sample chunked eof") snd_test_neq(gen.call(3), 0.00000, "file2sample chunked eof+1") res = open_sound("test.aif") snd_test_neq(framples(res), 2, "chunked framples") snd_test_neq(sample(0), 0.93948, "file chunked 0") snd_test_neq(sample(1), 0.50195, "file chunked 1") snd_test_neq(sample(2), 0.00000, "file chunked eof") snd_test_neq(sample(3), 0.00000, "file chunked eof+1") close_sound(res) end Snd.catch do snd_test_neq(mus_sound_framples("test.aif"), 2, "chunked mus_sound_framples") end delete_file("test.aif") mus_sound_forget("test.aif") # File.open("test.aif", "w") do |fp| # write AIFC with trailing chunks to try to confuse file->sample fp.write "FORM" fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0176); # len fp.write "AIFCFVER" fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0004); # version chunk size fp.putc(0242); fp.putc(0200); fp.putc(0121); fp.putc(0100); # version fp.write "SSND" fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0014); # SSND chunk size fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); # SSND data location fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); # block size? fp.putc(0170); fp.putc(0101); fp.putc(0100); fp.putc(0100); # two samples fp.write "COMM" fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0046); # COMM chunk size fp.putc(0000); fp.putc(0001); # 1 chan fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0002); # framples fp.putc(0000); fp.putc(0020); # bits fp.putc(0100); fp.putc(0016); fp.putc(0254); fp.putc(0104); fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); # srate as 80-bit float (sheesh) fp.write "NONE" # compression fp.putc(0016); # pascal string len fp.write "not compressed" fp.putc(0000); fp.write "APPL" fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(key_to_int(?h)); fp.write "CLM ;Written Mon 02-Nov-98 01:44 CST by root at ockeghem (Linux/X86) using Allegro CL, clm of 20-Oct-98" fp.putc(0000); end Snd.catch do gen = make_file2sample("test.aif") snd_test_neq(gen.call(0), 0.93948, "file2sample chunked 0") snd_test_neq(gen.call(1), 0.50195, "file2sample chunked 1") snd_test_neq(gen.call(2), 0.00000, "file2sample chunked eof") snd_test_neq(gen.call(3), 0.00000, "file2sample chunked eof+1") res = open_sound("test.aif") snd_test_neq(framples(res), 2, "chunked framples") snd_test_neq(sample(0), 0.93948, "file chunked 0") snd_test_neq(sample(1), 0.50195, "file chunked 1") snd_test_neq(sample(2), 0.00000, "file chunked eof") snd_test_neq(sample(3), 0.00000, "file chunked eof+1") snd_test_neq(comment(), ";Written Mon 02-Nov-98 01:44 CST by root at ockeghem (Linux/X86) using Allegro CL, clm of 20-Oct-98", "chunked appl comment") close_sound(res) end delete_file("test.aif") mus_sound_forget("test.aif") # File.open("test.aif", "w") do |fp| # write AIFC with trailing chunks to try to confuse file->sample fp.write "FORM" fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0176); # len fp.write "AIFCFVER" fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0004); # version chunk size fp.putc(0242); fp.putc(0200); fp.putc(0121); fp.putc(0100); # version fp.write "SSND" fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0014); # SSND chunk size fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); # SSND data location fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); # block size? fp.putc(0170); fp.putc(0101); fp.putc(0100); fp.putc(0100); # two samples (onr frame) fp.write "COMM" fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0046); # COMM chunk size fp.putc(0000); fp.putc(0002); # 2 chan fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0001); # frame fp.putc(0000); fp.putc(0020); # bits fp.putc(0100); fp.putc(0016); fp.putc(0254); fp.putc(0104); fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(0000); # srate as 80-bit float (sheesh) fp.write "NONE" # compression fp.putc(0016); # pascal string len fp.write "not compressed" fp.putc(0000); fp.write "APPL" fp.putc(0000); fp.putc(0000); fp.putc(0000); fp.putc(key_to_int(?h)); fp.write "CLM ;Written Mon 02-Nov-98 01:44 CST by root at ockeghem (Linux/X86) using Allegro CL, clm of 20-Oct-98" fp.putc(0000); end Snd.catch do gen = make_file2sample("test.aif") snd_test_neq(gen.call(0, 0), 0.93948, "file2sample chunked 0 0") snd_test_neq(gen.call(0, 1), 0.50195, "file2sample chunked 0 1") snd_test_neq(gen.call(1, 0), 0.00000, "file2sample chunked eof (stereo)") snd_test_neq(gen.call(1, 1), 0.00000, "file2sample chunked eof+1 (stereo)") res = open_sound("test.aif") snd_test_neq(framples(res), 1, "chunked framples (1)") snd_test_neq(sample(0, res, 0), 0.93948, "file chunked 0 0") snd_test_neq(sample(0, res, 1), 0.50195, "file chunked 0 1") snd_test_neq(sample(1, res, 0), 0.00000, "file chunked eof (stereo)") snd_test_neq(sample(1, res, 1), 0.00000, "file chunked eof+1 (stereo)") snd_test_neq(comment(), ";Written Mon 02-Nov-98 01:44 CST by root at ockeghem (Linux/X86) using Allegro CL, clm of 20-Oct-98", "chunked appl comment (stereo)") close_sound(res) end delete_file("test.aif") mus_sound_forget("test.aif") # files = sound_files_in_directory(Dir.pwd) if files.empty? snd_display("no sound files in %s?", Dir.pwd) end files1 = sound_files_in_directory() snd_test_neq(files1, files, "different sound files in %s and default?", Dir.pwd) files2 = sound_files_in_directory(".") if files1 != files2 or files != files2 snd_display("sound_files_in_directory dot: %s but %s?:", files2, files) end $open_raw_sound_hook.reset_hook! $bad_header_hook.reset_hook! Snd.sounds.apply(:close_sound) # ind = new_sound(:size, 0) snd_test_neq(framples(ind), 0, "new_sound :size 0") snd_test_neq(sample(0), 0.0, "new_sound :size 0 sample 0") new_file_name = file_name(ind) close_sound(ind) delete_file(new_file_name) ind = new_sound(:size, 1) snd_test_neq(framples(ind), 1, "new_sound :size 1") snd_test_neq(sample(0), 0.0, "new_sound :size 1 sample 0") new_file_name = file_name(ind) close_sound(ind) delete_file(new_file_name) if (res = Snd.catch do new_sound(:size, -1) end).first != :out_of_range snd_display("new_sound :size -1: %s", res.inspect) end # with_file("caruso.asc") do |file| ind = read_ascii(file) unless sound?(ind) snd_display("read_ascii cannot find %s (%s)?", file, ind.inspect) end snd_test_neq(maxamp(ind, 0), 0.723, "read_ascii maxamp") snd_test_neq(framples(ind, 0), 50000, "read_ascii framples") snd_test_neq(srate(ind), 44100, "read_ascii srate") set_srate(ind, 8000) snd_test_neq(framples(ind, 0), 50000, "set srate clobbered new sound framples") snd_test_neq(maxamp(ind, 0), 0.723, "set srate clobbered new sound maxamp") close_sound(ind) end # ind = open_sound("oboe.snd") save_sound_as("test space.snd") close_sound(ind) ind = open_sound("test space.snd") snd_test_neq(short_file_name(ind), "test space.snd", "file name with space") snd_test_neq(mus_sound_framples("test space.snd"), framples(ind), "spaced filename framples") add_mark(1234, ind, 0) save_marks(ind) close_sound(ind) ind = open_sound("test space.snd") load("test space.marks") unless find_mark(1234, ind) snd_display("space file name save marks: %s", marks(ind).inspect) end rd = make_readin(:file, "test space.snd") snd_test_neq(mus_file_name(rd), "test space.snd", "file name with space readin") close_sound(ind) delete_files("test space.snd", "test space.marks") end def test_04 $tests.times do |i| $clmtest = i if $VERBOSE and $tests > 1 snd_info("clmtest %d of %d", $clmtest + 1, $tests) end clear_listener() test_04_00 test_04_01 test_04_03 test_04_04 test_04_05 if $with_big_file test_04_06 end test_04_07 test_04_08 end # ---------------- test 05: simple overall checks ---------------- def test_edpos(ind1, func_sym, func_body = nil, &change_thunk) unless func_body func_body = lambda do |snd, chn, val| snd_func(func_sym, snd, chn, val) end end fr1 = func_body.call(ind1, 0, false) fr2 = func_body.call(ind1, 0, 0) fr3 = func_body.call(ind1, 0, Current_edit_position) if fr1 != fr2 or fr1 != fr3 snd_display_prev_caller("initial %s: %s %s %s?", func_sym, fr1, fr2, fr3) end change_thunk.call fr5 = func_body.call(ind1, 0, false) fr6 = func_body.call(ind1, 0, 1) fr7 = func_body.call(ind1, 0, Current_edit_position) if fr5 != fr6 or fr5 != fr7 snd_display_prev_caller("%s (edpos 1): %s %s %s?", func_sym, fr5, fr6, fr7) end revert_sound(ind1) end def test_edpos_1(func_sym, ind1, &body) v0 = channel2vct(12000, 10, ind1, 0) body.call(ind1, 0) v1 = channel2vct(12000, 10, ind1, 0) if vequal(v0, v1) s = snd_format(v1, v0, "==", "%s (0) no change!", func_sym) snd_display_prev_caller(s) end body.call(ind1, 0) v2 = channel2vct(12000, 10, ind1, 0) unless vequal(v1, v2) snd_display_prev_caller(snd_format(v2, v1, "!=", "%s (1)", func_sym)) end revert_sound(ind1) end def test_orig(func0, func1, name, ind1) v0 = channel2vct(12000, 10, ind1, 0) func0.call(ind1) v1 = channel2vct(12000, 10, ind1, 0) if vfequal(v0, v1) snd_display_prev_caller(snd_format(v1, v0, "==", "%s (orig 0) no change!", name)) end func1.call(ind1) v2 = channel2vct(12000, 10, ind1, 0) unless vfequal(v0, v2) snd_display_prev_caller(snd_format(v2, v0, "!=", "%s (orig 1)", name)) end revert_sound(ind1) end def make_bandpass_2(flo1, fhi1, flo2, fhi2, len = 30) f1 = make_bandpass(flo1, fhi1, len) f2 = make_bandpass(flo2, fhi2, len) vct_add!(mus_xcoeffs(f1), mus_xcoeffs(f2)) f1 end def bandpass_2(f, input) fir_filter(f, input) end def check_maxamp(ind, val, name) if fneq(maxamp(ind, 0), val) snd_display_prev_caller("maxamp amp_env %s: %s should be %s", name, maxamp(ind), val) end pos = find_channel(lambda do |y| y.abs >= (val - 0.0001) end) unless pos snd_display_prev_caller("actual maxamp %s vals not right", name) end maxpos = maxamp_position(ind, 0) if maxpos != pos snd_display_prev_caller("%s: \ find and maxamp_position disagree: %s (%s) %s (%s)?", name, pos, sample(pos, ind, 0), maxpos, sample(maxpos, ind, 0)) end reader = make_sampler(0, ind, 0) data = Vct.new(framples(ind, 0)) do |i| next_sample(reader) end mx, mpos = vct_peak_and_location(data) if mpos != maxpos snd_display_prev_caller("%s: scan and maxamp_position disagree: %s %s?", name, mpos, maxpos) end if fneq(mx, val) snd_display_prev_caller("actual %s max: %s (correct: %s)", name, mx, val) end end def check_env_vals(name, gen) reader = make_sampler() framples().times do |i| val = env(gen) y = next_sample(reader) if fneq(val, y) snd_display_prev_caller(snd_format_neq(val, y, "%s %s at %d", get_func_name, name, i)) return end end end def our_x2position(ind, x) ax = axis_info(ind, 0) [ax[10].to_f + ((x - ax[2]) * (ax[12].to_f - ax[10])) / (ax[4] - ax[2]), x2position(x, ind)] end def region2vct_1(reg, chn, len) region2vct(reg, 0, len, chn) end def region_to_vct(reg, chn, len) rs = make_region_sampler(reg, 0, chn) make_vct!(len) do next_sample(rs) end end # basic edit tree cases def test_05_00 if playing snd_display("dac is running?") end ind = open_sound("oboe.snd") set_transform_graph?(true, ind, 0) set_transform_graph_type(Graph_as_sonogram, ind, 0) set_y_axis_label("hiho", ind, 0) set_fft_log_frequency(true, ind, 0) update_transform_graph(ind, 0) close_sound(ind) # ind = new_sound("test.snd") if redo_edit.nonzero? snd_display("redo_edit with no ops: %s?", redo_edit) end if undo_edit.nonzero? snd_display("undo_edit with no ops: %s?", undo_edit) end str = format(" EDITS: 0 (begin) [0:2]: (at 0, cp->sounds[0][0:0, 0.000]) [file: %s/test.snd[0]] (at 1, end_mark) ", Dir.pwd) if (res = safe_display_edits) != str snd_display("new 0: %s %s?", str, res) end insert_samples(10, 10, make_vct(10)) str = format(" EDITS: 1 (begin) [0:2]: (at 0, cp->sounds[0][0:0, 0.000]) [file: %s/test.snd[0]] (at 1, end_mark) (insert 1 20) ; insert_samples [1:4]: (at 0, cp->sounds[0][0:0, 0.000]) [file: %s/test.snd[0]] (at 1, cp->sounds[-1][0:8, 0.000]) (at 10, cp->sounds[1][0:9, 1.000]) [buf: 10] (at 20, end_mark) ", Dir.pwd, Dir.pwd) if (res = safe_display_edits) != str snd_display("new 1: %s %s?", str, res) end undo_edit insert_samples(0, 10, make_vct(10)) str = format(" EDITS: 1 (begin) [0:2]: (at 0, cp->sounds[0][0:0, 0.000]) [file: %s/test.snd[0]] (at 1, end_mark) (insert 0 10) ; insert_samples [1:3]: (at 0, cp->sounds[1][0:9, 1.000]) [buf: 10] (at 10, cp->sounds[0][0:0, 0.000]) [file: %s/test.snd[0]] (at 11, end_mark) ", Dir.pwd, Dir.pwd) if (res = safe_display_edits) != str snd_display("new 2: %s %s?", str, res) end undo_edit(2) insert_samples(0, 10, make_vct(10)) str = format(" EDITS: 1 (begin) [0:2]: (at 0, cp->sounds[0][0:0, 0.000]) [file: %s/test.snd[0]] (at 1, end_mark) (insert 0 10) ; insert_samples [1:3]: (at 0, cp->sounds[1][0:9, 1.000]) [buf: 10] (at 10, cp->sounds[0][0:0, 0.000]) [file: %s/test.snd[0]] (at 11, end_mark) ", Dir.pwd, Dir.pwd) if (res = safe_display_edits) != str snd_display("new 3: %s %s?", str, res) end undo_edit set_sample(0, 0.5) str = format(" EDITS: 1 (begin) [0:2]: (at 0, cp->sounds[0][0:0, 0.000]) [file: %s/test.snd[0]] (at 1, end_mark) (set 0 1) ; set_sample(0, 0.5000 [1:2]: (at 0, cp->sounds[1][0:0, 1.000]) [buf: 1] (at 1, end_mark) ", Dir.pwd) if (res = safe_display_edits) != str snd_display("new 4: %s %s?", str, res) end undo_edit set_samples(0, 10, make_vct(10)) str = format(" EDITS: 1 (begin) [0:2]: (at 0, cp->sounds[0][0:0, 0.000]) [file: %s/test.snd[0]] (at 1, end_mark) (set 0 10) ; set-samples [1:2]: (at 0, cp->sounds[1][0:9, 1.000]) [buf: 10] (at 10, end_mark) ", Dir.pwd) if (res = safe_display_edits) != str snd_display("new 5: %s %s?", str, res) end idx = 1 test_idx = 5 test_output = lambda do |str| idx += 1 test_idx += 1 if (res = safe_display_edits(ind, 0, idx)) != str snd_display("new %s: %s %s?", test_idx, str, res) end end delete_samples(3, 4) test_output.call(" (delete 3 4) ; delete_samples(3, 4 [2:3]: (at 0, cp->sounds[1][0:2, 1.000]) [buf: 10] (at 3, cp->sounds[1][7:9, 1.000]) [buf: 10] (at 6, end_mark) ") set_samples(1, 4, make_vct(4)) test_output.call(" (set 1 4) ; set-samples [3:4]: (at 0, cp->sounds[1][0:0, 1.000]) [buf: 10] (at 1, cp->sounds[2][0:3, 1.000]) [buf: 4] (at 5, cp->sounds[1][9:9, 1.000]) [buf: 10] (at 6, end_mark) ") undo_edit(2) insert_samples(2, 3, make_vct(3)) insert_samples(2, 1, make_vct(1)) insert_samples(4, 1, make_vct(1)) insert_samples(15, 1, make_vct(1)) str = format(" EDITS: 5 (begin) [0:2]: (at 0, cp->sounds[0][0:0, 0.000]) [file: %s/test.snd[0]] (at 1, end_mark) (set 0 10) ; set-samples [1:2]: (at 0, cp->sounds[1][0:9, 1.000]) [buf: 10] (at 10, end_mark) (insert 2 3) ; insert_samples [2:4]: (at 0, cp->sounds[1][0:1, 1.000]) [buf: 10] (at 2, cp->sounds[2][0:2, 1.000]) [buf: 3] (at 5, cp->sounds[1][2:9, 1.000]) [buf: 10] (at 13, end_mark) (insert 2 1) ; insert_samples [3:5]: (at 0, cp->sounds[1][0:1, 1.000]) [buf: 10] (at 2, cp->sounds[3][0:0, 1.000]) [buf: 1] (at 3, cp->sounds[2][0:2, 1.000]) [buf: 3] (at 6, cp->sounds[1][2:9, 1.000]) [buf: 10] (at 14, end_mark) (insert 4 1) ; insert_samples [4:7]: (at 0, cp->sounds[1][0:1, 1.000]) [buf: 10] (at 2, cp->sounds[3][0:0, 1.000]) [buf: 1] (at 3, cp->sounds[2][0:0, 1.000]) [buf: 3] (at 4, cp->sounds[4][0:0, 1.000]) [buf: 1] (at 5, cp->sounds[2][1:2, 1.000]) [buf: 3] (at 7, cp->sounds[1][2:9, 1.000]) [buf: 10] (at 15, end_mark) (insert 15 1) ; insert_samples [5:8]: (at 0, cp->sounds[1][0:1, 1.000]) [buf: 10] (at 2, cp->sounds[3][0:0, 1.000]) [buf: 1] (at 3, cp->sounds[2][0:0, 1.000]) [buf: 3] (at 4, cp->sounds[4][0:0, 1.000]) [buf: 1] (at 5, cp->sounds[2][1:2, 1.000]) [buf: 3] (at 7, cp->sounds[1][2:9, 1.000]) [buf: 10] (at 15, cp->sounds[5][0:0, 1.000]) [buf: 1] (at 16, end_mark) ", Dir.pwd) test_idx += 1 idx += 2 if (res = safe_display_edits) != str snd_display("new 8: %s?", res) end delete_samples(2, 1) test_output.call(" (delete 2 1) ; delete_samples(2, 1 [6:7]: (at 0, cp->sounds[1][0:1, 1.000]) [buf: 10] (at 2, cp->sounds[2][0:0, 1.000]) [buf: 3] (at 3, cp->sounds[4][0:0, 1.000]) [buf: 1] (at 4, cp->sounds[2][1:2, 1.000]) [buf: 3] (at 6, cp->sounds[1][2:9, 1.000]) [buf: 10] (at 14, cp->sounds[5][0:0, 1.000]) [buf: 1] (at 15, end_mark) ") delete_samples(0, 5) test_output.call(" (delete 0 5) ; delete_samples(0, 5 [7:4]: (at 0, cp->sounds[2][2:2, 1.000]) [buf: 3] (at 1, cp->sounds[1][2:9, 1.000]) [buf: 10] (at 9, cp->sounds[5][0:0, 1.000]) [buf: 1] (at 10, end_mark) ") delete_samples(6, 4) test_output.call(" (delete 6 4) ; delete_samples(6, 4 [8:3]: (at 0, cp->sounds[2][2:2, 1.000]) [buf: 3] (at 1, cp->sounds[1][2:6, 1.000]) [buf: 10] (at 6, end_mark) ") delete_samples(0, 1) test_output.call(" (delete 0 1) ; delete_samples(0, 1 [9:2]: (at 0, cp->sounds[1][2:6, 1.000]) [buf: 10] (at 5, end_mark) ") delete_samples(0, 5) test_output.call(" (delete 0 5) ; delete_samples(0, 5 [10:1]: (at 0, end_mark) ") delete_samples(0, 10) unless edit_position == 10 snd_display("no-op delete deleted something! %s", safe_display_edits) end insert_samples(0, 3, make_vct(3)) test_output.call(" (insert 0 3) ; insert_samples [11:2]: (at 0, cp->sounds[6][0:2, 1.000]) [buf: 3] (at 3, end_mark) ") delete_samples(2, 1) test_output.call(" (delete 2 1) ; delete_samples(2, 1 [12:2]: (at 0, cp->sounds[6][0:1, 1.000]) [buf: 3] (at 2, end_mark) ") set_sample(0, 0.5) test_output.call(" (set 0 1) ; set_sample(0, 0.5000 [13:3]: (at 0, cp->sounds[7][0:0, 1.000]) [buf: 1] (at 1, cp->sounds[6][1:1, 1.000]) [buf: 3] (at 2, end_mark) ") set_sample(1, 0.5) test_output.call(" (set 1 1) ; set_sample(1, 0.5000 [14:3]: (at 0, cp->sounds[7][0:0, 1.000]) [buf: 1] (at 1, cp->sounds[8][0:0, 1.000]) [buf: 1] (at 2, end_mark) ") map_channel($init_channel, 0, 10) test_output.call(" (set 0 10) ; map-channel [15:2]: (at 0, cp->sounds[9][0:9, 1.000]) [buf: 10] (at 10, end_mark) ") insert_samples(0, 10, make_vct(10)) test_output.call(" (insert 0 10) ; insert_samples [16:3]: (at 0, cp->sounds[10][0:9, 1.000]) [buf: 10] (at 10, cp->sounds[9][0:9, 1.000]) [buf: 10] (at 20, end_mark) ") set_samples(2, 3, make_vct(3)) test_output.call(" (set 2 3) ; set-samples [17:5]: (at 0, cp->sounds[10][0:1, 1.000]) [buf: 10] (at 2, cp->sounds[11][0:2, 1.000]) [buf: 3] (at 5, cp->sounds[10][5:9, 1.000]) [buf: 10] (at 10, cp->sounds[9][0:9, 1.000]) [buf: 10] (at 20, end_mark) ") set_samples(0, 12, make_vct(12)) test_output.call(" (set 0 12) ; set-samples [18:3]: (at 0, cp->sounds[12][0:11, 1.000]) [buf: 12] (at 12, cp->sounds[9][2:9, 1.000]) [buf: 10] (at 20, end_mark) ") set_samples(30, 10, make_vct(10)) test_output.call(" (set 20 21) ; set-samples [19:5]: (at 0, cp->sounds[12][0:11, 1.000]) [buf: 12] (at 12, cp->sounds[9][2:9, 1.000]) [buf: 10] (at 20, cp->sounds[-1][0:9, 0.000]) (at 30, cp->sounds[13][0:9, 1.000]) [buf: 10] (at 40, end_mark) ") close_sound(ind) end # scale/ramp def test_05_01 ind = new_sound("test.snd") idx = -1 test_name = "scl" test_output = lambda do |ed, str| idx += 1 if (res = safe_display_edits(ind, 0, ed)) != str snd_display("%s %s: %s %s?", test_name, idx, str, res) end end map_channel($init_channel, 0, 10) scale_channel(0.5) test_output.call(2, " (scale 0 10) ; scale_channel(0.500, 0, false [2:2]: (at 0, cp->sounds[1][0:9, 0.500]) [buf: 10] (at 10, end_mark) ") undo_edit scale_channel(0.5, 0, 3) test_output.call(2, " (scale 0 3) ; scale_channel(0.500, 0, 3 [2:3]: (at 0, cp->sounds[1][0:2, 0.500]) [buf: 10] (at 3, cp->sounds[1][3:9, 1.000]) [buf: 10] (at 10, end_mark) ") undo_edit scale_channel(0.5, 5, 5) test_output.call(2, " (scale 5 5) ; scale_channel(0.500, 5, 5 [2:3]: (at 0, cp->sounds[1][0:4, 1.000]) [buf: 10] (at 5, cp->sounds[1][5:9, 0.500]) [buf: 10] (at 10, end_mark) ") undo_edit scale_channel(0.5, 2, 4) test_output.call(2, " (scale 2 4) ; scale_channel(0.500, 2, 4 [2:4]: (at 0, cp->sounds[1][0:1, 1.000]) [buf: 10] (at 2, cp->sounds[1][2:5, 0.500]) [buf: 10] (at 6, cp->sounds[1][6:9, 1.000]) [buf: 10] (at 10, end_mark) ") undo_edit scale_channel(0.5, 10, 10) unless edit_position == 1 snd_display("scale beyond end edited? %s", safe_display_edits) end scale_channel(0.5, 100, 10) unless edit_position == 1 snd_display("scale way beyond end edited? %s", safe_display_edits) end scale_channel(0.5, 5, 10) test_output.call(2, " (scale 5 5) ; scale_channel(0.500, 5, 5 [2:3]: (at 0, cp->sounds[1][0:4, 1.000]) [buf: 10] (at 5, cp->sounds[1][5:9, 0.500]) [buf: 10] (at 10, end_mark) ") undo_edit set_sample(4, 0.5) test_output.call(2, " (set 4 1) ; set_sample(4, 0.5000 [2:4]: (at 0, cp->sounds[1][0:3, 1.000]) [buf: 10] (at 4, cp->sounds[2][0:0, 1.000]) [buf: 1] (at 5, cp->sounds[1][5:9, 1.000]) [buf: 10] (at 10, end_mark) ") scale_channel(0.5, 0, 4) test_output.call(3, " (scale 0 4) ; scale_channel(0.500, 0, 4 [3:4]: (at 0, cp->sounds[1][0:3, 0.500]) [buf: 10] (at 4, cp->sounds[2][0:0, 1.000]) [buf: 1] (at 5, cp->sounds[1][5:9, 1.000]) [buf: 10] (at 10, end_mark) ") scale_channel(0.5, 4, 1) test_output.call(4, " (scale 4 1) ; scale_channel(0.500, 4, 1 [4:4]: (at 0, cp->sounds[1][0:3, 0.500]) [buf: 10] (at 4, cp->sounds[2][0:0, 0.500]) [buf: 1] (at 5, cp->sounds[1][5:9, 1.000]) [buf: 10] (at 10, end_mark) ") scale_channel(0.5, 0, 7) test_output.call(5, " (scale 0 7) ; scale_channel(0.500, 0, 7 [5:5]: (at 0, cp->sounds[1][0:3, 0.250]) [buf: 10] (at 4, cp->sounds[2][0:0, 0.250]) [buf: 1] (at 5, cp->sounds[1][5:6, 0.500]) [buf: 10] (at 7, cp->sounds[1][7:9, 1.000]) [buf: 10] (at 10, end_mark) ") scale_channel(0.5, 1, 4) test_output.call(6, " (scale 1 4) ; scale_channel(0.500, 1, 4 [6:6]: (at 0, cp->sounds[1][0:0, 0.250]) [buf: 10] (at 1, cp->sounds[1][1:3, 0.125]) [buf: 10] (at 4, cp->sounds[2][0:0, 0.125]) [buf: 1] (at 5, cp->sounds[1][5:6, 0.500]) [buf: 10] (at 7, cp->sounds[1][7:9, 1.000]) [buf: 10] (at 10, end_mark) ") undo_edit(4) scale_channel(0.5, 1, 8) test_output.call(3, " (scale 1 8) ; scale_channel(0.500, 1, 8 [3:6]: (at 0, cp->sounds[1][0:0, 1.000]) [buf: 10] (at 1, cp->sounds[1][1:3, 0.500]) [buf: 10] (at 4, cp->sounds[2][0:0, 0.500]) [buf: 1] (at 5, cp->sounds[1][5:8, 0.500]) [buf: 10] (at 9, cp->sounds[1][9:9, 1.000]) [buf: 10] (at 10, end_mark) ") undo_edit(2) idx = -1 test_name = "ramp" ramp_channel(0.0, 1.0) test_output.call(2, " (ramp 0 10) ; ramp_channel(0.000, 1.000, 0, false [2:2]: (at 0, cp->sounds[1][0:9, 1.000, [1]0.000 -> 1.000]) [buf: 10] (at 10, end_mark) ") scale_channel(0.5) test_output.call(3, " (scale 0 10) ; scale_channel(0.500, 0, false [3:2]: (at 0, cp->sounds[1][0:9, 0.500, [1]0.000 -> 1.000]) [buf: 10] (at 10, end_mark) ") undo_edit scale_channel(0.5, 0, 5) test_output.call(3, " (scale 0 5) ; scale_channel(0.500, 0, 5 [3:3]: (at 0, cp->sounds[1][0:4, 0.500, [1]0.000 -> 0.444]) [buf: 10] (at 5, cp->sounds[1][5:9, 1.000, [1]0.556 -> 1.000]) [buf: 10] (at 10, end_mark) ") undo_edit scale_channel(0.5, 2, 4) test_output.call(3, " (scale 2 4) ; scale_channel(0.500, 2, 4 [3:4]: (at 0, cp->sounds[1][0:1, 1.000, [1]0.000 -> 0.111]) [buf: 10] (at 2, cp->sounds[1][2:5, 0.500, [1]0.222 -> 0.556]) [buf: 10] (at 6, cp->sounds[1][6:9, 1.000, [1]0.667 -> 1.000]) [buf: 10] (at 10, end_mark) ") undo_edit scale_channel(0.5, 5, 5) test_output.call(3, " (scale 5 5) ; scale_channel(0.500, 5, 5 [3:3]: (at 0, cp->sounds[1][0:4, 1.000, [1]0.000 -> 0.444]) [buf: 10] (at 5, cp->sounds[1][5:9, 0.500, [1]0.556 -> 1.000]) [buf: 10] (at 10, end_mark) ") undo_edit(2) ramp_channel(0.2, 0.6, 2, 6) test_output.call(2, " (ramp 2 6) ; ramp_channel(0.200, 0.600, 2, 6 [2:4]: (at 0, cp->sounds[1][0:1, 1.000]) [buf: 10] (at 2, cp->sounds[1][2:7, 1.000, [1]0.200 -> 0.600]) [buf: 10] (at 8, cp->sounds[1][8:9, 1.000]) [buf: 10] (at 10, end_mark) ") scale_channel(0.5, 0, 5) test_output.call(3, " (scale 0 5) ; scale_channel(0.500, 0, 5 [3:5]: (at 0, cp->sounds[1][0:1, 0.500]) [buf: 10] (at 2, cp->sounds[1][2:4, 0.500, [1]0.200 -> 0.360]) [buf: 10] (at 5, cp->sounds[1][5:7, 1.000, [1]0.440 -> 0.600]) [buf: 10] (at 8, cp->sounds[1][8:9, 1.000]) [buf: 10] (at 10, end_mark) ") undo_edit scale_channel(0.5, 2, 6) test_output.call(3, " (scale 2 6) ; scale_channel(0.500, 2, 6 [3:4]: (at 0, cp->sounds[1][0:1, 1.000]) [buf: 10] (at 2, cp->sounds[1][2:7, 0.500, [1]0.200 -> 0.600]) [buf: 10] (at 8, cp->sounds[1][8:9, 1.000]) [buf: 10] (at 10, end_mark) ") undo_edit scale_channel(0.5, 5, 4) test_output.call(3, " (scale 5 4) ; scale_channel(0.500, 5, 4 [3:6]: (at 0, cp->sounds[1][0:1, 1.000]) [buf: 10] (at 2, cp->sounds[1][2:4, 1.000, [1]0.200 -> 0.360]) [buf: 10] (at 5, cp->sounds[1][5:7, 0.500, [1]0.440 -> 0.600]) [buf: 10] (at 8, cp->sounds[1][8:8, 0.500]) [buf: 10] (at 9, cp->sounds[1][9:9, 1.000]) [buf: 10] (at 10, end_mark) ") undo_edit set_sample(4, 0.5) test_output.call(3, " (set 4 1) ; set_sample(4, 0.5000 [3:6]: (at 0, cp->sounds[1][0:1, 1.000]) [buf: 10] (at 2, cp->sounds[1][2:3, 1.000, [1]0.200 -> 0.280]) [buf: 10] (at 4, cp->sounds[2][0:0, 1.000]) [buf: 1] (at 5, cp->sounds[1][5:7, 1.000, [1]0.440 -> 0.600]) [buf: 10] (at 8, cp->sounds[1][8:9, 1.000]) [buf: 10] (at 10, end_mark) ") undo_edit scale_channel(0.5, 4, 1) test_output.call(3, " (scale 4 1) ; scale_channel(0.500, 4, 1 [3:6]: (at 0, cp->sounds[1][0:1, 1.000]) [buf: 10] (at 2, cp->sounds[1][2:3, 1.000, [1]0.200 -> 0.280]) [buf: 10] (at 4, cp->sounds[1][4:4, 0.500, [1]0.360 -> 0.360]) [buf: 10] (at 5, cp->sounds[1][5:7, 1.000, [1]0.440 -> 0.600]) [buf: 10] (at 8, cp->sounds[1][8:9, 1.000]) [buf: 10] (at 10, end_mark) ") undo_edit delete_sample(4) test_output.call(3, " (delete 4 1) ; delete_samples(4, 1 [3:5]: (at 0, cp->sounds[1][0:1, 1.000]) [buf: 10] (at 2, cp->sounds[1][2:3, 1.000, [1]0.200 -> 0.280]) [buf: 10] (at 4, cp->sounds[1][5:7, 1.000, [1]0.440 -> 0.600]) [buf: 10] (at 7, cp->sounds[1][8:9, 1.000]) [buf: 10] (at 9, end_mark) ") undo_edit delete_samples(4, 2) test_output.call(3, " (delete 4 2) ; delete_samples(4, 2 [3:5]: (at 0, cp->sounds[1][0:1, 1.000]) [buf: 10] (at 2, cp->sounds[1][2:3, 1.000, [1]0.200 -> 0.280]) [buf: 10] (at 4, cp->sounds[1][6:7, 1.000, [1]0.520 -> 0.600]) [buf: 10] (at 6, cp->sounds[1][8:9, 1.000]) [buf: 10] (at 8, end_mark) ") undo_edit delete_samples(4, 3) test_output.call(3, " (delete 4 3) ; delete_samples(4, 3 [3:5]: (at 0, cp->sounds[1][0:1, 1.000]) [buf: 10] (at 2, cp->sounds[1][2:3, 1.000, [1]0.200 -> 0.280]) [buf: 10] (at 4, cp->sounds[1][7:7, 1.000, [1]0.600 -> 0.600]) [buf: 10] (at 5, cp->sounds[1][8:9, 1.000]) [buf: 10] (at 7, end_mark) ") undo_edit delete_samples(4, 4) test_output.call(3, " (delete 4 4) ; delete_samples(4, 4 [3:4]: (at 0, cp->sounds[1][0:1, 1.000]) [buf: 10] (at 2, cp->sounds[1][2:3, 1.000, [1]0.200 -> 0.280]) [buf: 10] (at 4, cp->sounds[1][8:9, 1.000]) [buf: 10] (at 6, end_mark) ") undo_edit delete_samples(4, 5) test_output.call(3, " (delete 4 5) ; delete_samples(4, 5 [3:4]: (at 0, cp->sounds[1][0:1, 1.000]) [buf: 10] (at 2, cp->sounds[1][2:3, 1.000, [1]0.200 -> 0.280]) [buf: 10] (at 4, cp->sounds[1][9:9, 1.000]) [buf: 10] (at 5, end_mark) ") undo_edit scale_channel(0.5, 4, 2) test_output.call(3, " (scale 4 2) ; scale_channel(0.500, 4, 2 [3:6]: (at 0, cp->sounds[1][0:1, 1.000]) [buf: 10] (at 2, cp->sounds[1][2:3, 1.000, [1]0.200 -> 0.280]) [buf: 10] (at 4, cp->sounds[1][4:5, 0.500, [1]0.360 -> 0.440]) [buf: 10] (at 6, cp->sounds[1][6:7, 1.000, [1]0.520 -> 0.600]) [buf: 10] (at 8, cp->sounds[1][8:9, 1.000]) [buf: 10] (at 10, end_mark) ") undo_edit pad_channel(4, 1) test_output.call(3, " (silence 4 1) ; pad-channel [3:6]: (at 0, cp->sounds[1][0:1, 1.000]) [buf: 10] (at 2, cp->sounds[1][2:3, 1.000, [1]0.200 -> 0.280]) [buf: 10] (at 4, cp->sounds[-1][0:0, 0.000]) (at 5, cp->sounds[1][4:7, 1.000, [1]0.360 -> 0.600]) [buf: 10] (at 9, cp->sounds[1][8:9, 1.000]) [buf: 10] (at 11, end_mark) ") close_sound(ind) end # xramp def test_05_02 ind = new_sound("test.snd") idx = -1 test_name = "xramp" test_output = lambda do |ed, str| idx += 1 if (res = safe_display_edits(ind, 0, ed)) != str snd_display("%s %s: %s %s?", test_name, idx, str, res) end end map_channel($init_channel, 0, 10) xramp_channel(0.0, 1.0, 32.0) test_output.call(2, " (ramp 0 10) ; xramp_channel(0.000, 1.000, 32.000, 0, false [2:2]: (at 0, cp->sounds[1][0:9, 1.000, [1]0.000 -> 1.000, off: -0.032, scl: 0.032]) [buf: 10] (at 10, end_mark) ") undo_edit xramp_channel(0.0, 1.0, 0.325) test_output.call(2, " (ramp 0 10) ; xramp_channel(0.000, 1.000, 0.325, 0, false [2:2]: (at 0, cp->sounds[1][0:9, 1.000, [1]0.000 -> 1.000, off: 1.481, scl: -1.481]) [buf: 10] (at 10, end_mark) ") undo_edit xramp_channel(0.0, 1.0, 0.0) test_output.call(2, format(" (scale 0 10) ; scale_channel(0.000, 0, false [2:2]: (at 0, cp->sounds[0][0:9, 0.000]) [file: %s/test.snd[0]] (at 10, end_mark) ", Dir.pwd)) undo_edit xramp_channel(0.0, 1.0, 1.0) test_output.call(2, " (ramp 0 10) ; ramp_channel(0.000, 1.000, 0, false [2:2]: (at 0, cp->sounds[1][0:9, 1.000, [1]0.000 -> 1.000]) [buf: 10] (at 10, end_mark) ") undo_edit xramp_channel(0.5, 1.5, 32.0) test_output.call(2, " (ramp 0 10) ; xramp_channel(0.500, 1.500, 32.000, 0, false [2:2]: (at 0, cp->sounds[1][0:9, 1.000, [1]0.500 -> 1.500, off: 0.468, scl: 0.032]) [buf: 10] (at 10, end_mark) ") if fneq(maxamp, 1.5) or fneq(sample(0), 0.5) snd_display("xramp 5 vals: %s %s", maxamp, sample(0)) end undo_edit xramp_channel(-0.5, 1.5, 32.0) test_output.call(2, " (ramp 0 10) ; xramp_channel(-0.500, 1.500, 32.000, 0, false [2:2]: (at 0, cp->sounds[1][0:9, 1.000, [1]-0.500 -> 1.500, off: -0.565, scl: 0.065]) [buf: 10] (at 10, end_mark) ") if fneq(maxamp, 1.5) or fneq(sample(0), -0.5) snd_display("xramp 6 vals: %s %s", maxamp, sample(0)) end undo_edit xramp_channel(0.0, 1.0, 32.0) vals = channel2vct scale_channel(0.5) test_output.call(3, " (scale 0 10) ; scale_channel(0.500, 0, false [3:2]: (at 0, cp->sounds[1][0:9, 0.500, [1]0.000 -> 1.000, off: -0.032, scl: 0.032]) [buf: 10] (at 10, end_mark) ") ctr = 0 if res = scan_channel(lambda do |y| if fneq(y, 0.5 * vals[ctr]) true else ctr += 1 false end end) snd_display("trouble in xramp 7: %s", res) end undo_edit delete_sample(0) test_output.call(3, " (delete 0 1) ; delete_samples(0, 1 [3:2]: (at 0, cp->sounds[1][1:9, 1.000, [1]0.015 -> 1.000, off: -0.032, scl: 0.032]) [buf: 10] (at 9, end_mark) ") ctr = 1 if res = scan_channel(lambda do |y| if fneq(y, vals[ctr]) true else ctr += 1 false end end) snd_display("trouble in xramp 8: %s", res) end undo_edit delete_samples(0, 2) test_output.call(3, " (delete 0 2) ; delete_samples(0, 2 [3:2]: (at 0, cp->sounds[1][2:9, 1.000, [1]0.037 -> 1.000, off: -0.032, scl: 0.032]) [buf: 10] (at 8, end_mark) ") ctr = 2 if res = scan_channel(lambda do |y| if fneq(y, vals[ctr]) true else ctr += 1 false end end) snd_display("trouble in xramp 9: %s", res) end undo_edit delete_sample(0) delete_sample(0) test_output.call(4, " (delete 0 1) ; delete_samples(0, 1 [4:2]: (at 0, cp->sounds[1][2:9, 1.000, [1]0.037 -> 1.000, off: -0.032, scl: 0.032]) [buf: 10] (at 8, end_mark) ") undo_edit(2) delete_sample(4) test_output.call(3, " (delete 4 1) ; delete_samples(4, 1 [3:3]: (at 0, cp->sounds[1][0:3, 1.000, [1]0.000 -> 0.070, off: -0.032, scl: 0.032]) [buf: 10] (at 4, cp->sounds[1][5:9, 1.000, [1]0.189 -> 1.000, off: -0.032, scl: 0.032]) [buf: 10] (at 9, end_mark) ") undo_edit delete_samples(4, 2) test_output.call(3, " (delete 4 2) ; delete_samples(4, 2 [3:3]: (at 0, cp->sounds[1][0:3, 1.000, [1]0.000 -> 0.070, off: -0.032, scl: 0.032]) [buf: 10] (at 4, cp->sounds[1][6:9, 1.000, [1]0.293 -> 1.000, off: -0.032, scl: 0.032]) [buf: 10] (at 8, end_mark) ") undo_edit scale_channel(0.5, 4, 2) test_output.call(3, " (scale 4 2) ; scale_channel(0.500, 4, 2 [3:4]: (at 0, cp->sounds[1][0:3, 1.000, [1]0.000 -> 0.070, off: -0.032, scl: 0.032]) [buf: 10] (at 4, cp->sounds[1][4:5, 0.500, [1]0.118 -> 0.189, off: -0.032, scl: 0.032]) [buf: 10] (at 6, cp->sounds[1][6:9, 1.000, [1]0.293 -> 1.000, off: -0.032, scl: 0.032]) [buf: 10] (at 10, end_mark) ") ctr = 0 if res = scan_channel(lambda do |y| if (ctr > 5 and fneq(y, vals[ctr])) or (ctr < 4 and fneq(y, vals[ctr])) or ((ctr == 4 or ctr == 5) and fneq(y, 0.5 * vals[ctr])) true else ctr += 1 false end end) snd_display("trouble in xramp 13: %s", res) end undo_edit scale_channel(0.5, 0, 2) test_output.call(3, " (scale 0 2) ; scale_channel(0.500, 0, 2 [3:3]: (at 0, cp->sounds[1][0:1, 0.500, [1]0.000 -> 0.015, off: -0.032, scl: 0.032]) [buf: 10] (at 2, cp->sounds[1][2:9, 1.000, [1]0.037 -> 1.000, off: -0.032, scl: 0.032]) [buf: 10] (at 10, end_mark) ") undo_edit pad_channel(4, 2) test_output.call(3, " (silence 4 2) ; pad-channel [3:4]: (at 0, cp->sounds[1][0:3, 1.000, [1]0.000 -> 0.070, off: -0.032, scl: 0.032]) [buf: 10] (at 4, cp->sounds[-1][0:1, 0.000]) (at 6, cp->sounds[1][4:9, 1.000, [1]0.118 -> 1.000, off: -0.032, scl: 0.032]) [buf: 10] (at 12, end_mark) ") undo_edit set_sample(4, 1.0) test_output.call(3, " (set 4 1) ; set_sample(4, 1.0000 [3:4]: (at 0, cp->sounds[1][0:3, 1.000, [1]0.000 -> 0.070, off: -0.032, scl: 0.032]) [buf: 10] (at 4, cp->sounds[2][0:0, 1.000]) [buf: 1] (at 5, cp->sounds[1][5:9, 1.000, [1]0.189 -> 1.000, off: -0.032, scl: 0.032]) [buf: 10] (at 10, end_mark) ") undo_edit set_samples(4, 2, make_vct(2)) test_output.call(3, " (set 4 2) ; set-samples [3:4]: (at 0, cp->sounds[1][0:3, 1.000, [1]0.000 -> 0.070, off: -0.032, scl: 0.032]) [buf: 10] (at 4, cp->sounds[2][0:1, 1.000]) [buf: 2] (at 6, cp->sounds[1][6:9, 1.000, [1]0.293 -> 1.000, off: -0.032, scl: 0.032]) [buf: 10] (at 10, end_mark) ") undo_edit scale_channel(0.5) set_samples(4, 2, make_vct(2)) test_output.call(4, " (set 4 2) ; set-samples [4:4]: (at 0, cp->sounds[1][0:3, 0.500, [1]0.000 -> 0.070, off: -0.032, scl: 0.032]) [buf: 10] (at 4, cp->sounds[2][0:1, 1.000]) [buf: 2] (at 6, cp->sounds[1][6:9, 0.500, [1]0.293 -> 1.000, off: -0.032, scl: 0.032]) [buf: 10] (at 10, end_mark) ") close_sound(ind) ind = new_sound("test.snd") test_name = "multi-ramp" idx = 0 map_channel($init_channel, 0, 100) 10.times do |i| scale_channel(0.5, i * 10, 10) end ramp_channel(0.0, 1.0) test_output.call(12, " (ramp 0 100) ; ramp_channel(0.000, 1.000, 0, false [12:11]: (at 0, cp->sounds[1][0:9, 0.500, [1]0.000 -> 0.091]) [buf: 100] (at 10, cp->sounds[1][10:19, 0.500, [1]0.101 -> 0.192]) [buf: 100] (at 20, cp->sounds[1][20:29, 0.500, [1]0.202 -> 0.293]) [buf: 100] (at 30, cp->sounds[1][30:39, 0.500, [1]0.303 -> 0.394]) [buf: 100] (at 40, cp->sounds[1][40:49, 0.500, [1]0.404 -> 0.495]) [buf: 100] (at 50, cp->sounds[1][50:59, 0.500, [1]0.505 -> 0.596]) [buf: 100] (at 60, cp->sounds[1][60:69, 0.500, [1]0.606 -> 0.697]) [buf: 100] (at 70, cp->sounds[1][70:79, 0.500, [1]0.707 -> 0.798]) [buf: 100] (at 80, cp->sounds[1][80:89, 0.500, [1]0.808 -> 0.899]) [buf: 100] (at 90, cp->sounds[1][90:99, 0.500, [1]0.909 -> 1.000]) [buf: 100] (at 100, end_mark) ") if fneq(maxamp, 0.5) snd_display("multi-ramp 1 maxamp: %s", maxamp) end undo_edit ramp_channel(0.1, 1.0, 10, 90) test_output.call(12, " (ramp 10 90) ; ramp_channel(0.100, 1.000, 10, 90 [12:11]: (at 0, cp->sounds[1][0:9, 0.500]) [buf: 100] (at 10, cp->sounds[1][10:19, 0.500, [1]0.100 -> 0.191]) [buf: 100] (at 20, cp->sounds[1][20:29, 0.500, [1]0.201 -> 0.292]) [buf: 100] (at 30, cp->sounds[1][30:39, 0.500, [1]0.302 -> 0.393]) [buf: 100] (at 40, cp->sounds[1][40:49, 0.500, [1]0.403 -> 0.494]) [buf: 100] (at 50, cp->sounds[1][50:59, 0.500, [1]0.504 -> 0.596]) [buf: 100] (at 60, cp->sounds[1][60:69, 0.500, [1]0.606 -> 0.697]) [buf: 100] (at 70, cp->sounds[1][70:79, 0.500, [1]0.707 -> 0.798]) [buf: 100] (at 80, cp->sounds[1][80:89, 0.500, [1]0.808 -> 0.899]) [buf: 100] (at 90, cp->sounds[1][90:99, 0.500, [1]0.909 -> 1.000]) [buf: 100] (at 100, end_mark) ") if fneq(maxamp, 0.5) snd_display("multi-ramp 2 maxamp: %s", maxamp) end undo_edit ramp_channel(0.0, 0.9, 0, 90) test_output.call(12, " (ramp 0 90) ; ramp_channel(0.000, 0.900, 0, 90 [12:11]: (at 0, cp->sounds[1][0:9, 0.500, [1]0.000 -> 0.091]) [buf: 100] (at 10, cp->sounds[1][10:19, 0.500, [1]0.101 -> 0.192]) [buf: 100] (at 20, cp->sounds[1][20:29, 0.500, [1]0.202 -> 0.293]) [buf: 100] (at 30, cp->sounds[1][30:39, 0.500, [1]0.303 -> 0.394]) [buf: 100] (at 40, cp->sounds[1][40:49, 0.500, [1]0.404 -> 0.496]) [buf: 100] (at 50, cp->sounds[1][50:59, 0.500, [1]0.506 -> 0.597]) [buf: 100] (at 60, cp->sounds[1][60:69, 0.500, [1]0.607 -> 0.698]) [buf: 100] (at 70, cp->sounds[1][70:79, 0.500, [1]0.708 -> 0.799]) [buf: 100] (at 80, cp->sounds[1][80:89, 0.500, [1]0.809 -> 0.900]) [buf: 100] (at 90, cp->sounds[1][90:99, 0.500]) [buf: 100] (at 100, end_mark) ") if fneq(maxamp, 0.5) snd_display("multi-ramp 3 maxamp: %s", maxamp) end if fneq(sample(89), 0.45) snd_display("multi-ramp 3 sample 89: %s", sample(89)) end if fneq(sample(90), 0.5) snd_display("multi-ramp 3 sample 90: %s", sample(90)) end undo_edit ramp_channel(0.1, 0.9, 10, 80) test_output.call(12, " (ramp 10 80) ; ramp_channel(0.100, 0.900, 10, 80 [12:11]: (at 0, cp->sounds[1][0:9, 0.500]) [buf: 100] (at 10, cp->sounds[1][10:19, 0.500, [1]0.100 -> 0.191]) [buf: 100] (at 20, cp->sounds[1][20:29, 0.500, [1]0.201 -> 0.292]) [buf: 100] (at 30, cp->sounds[1][30:39, 0.500, [1]0.303 -> 0.394]) [buf: 100] (at 40, cp->sounds[1][40:49, 0.500, [1]0.404 -> 0.495]) [buf: 100] (at 50, cp->sounds[1][50:59, 0.500, [1]0.505 -> 0.596]) [buf: 100] (at 60, cp->sounds[1][60:69, 0.500, [1]0.606 -> 0.697]) [buf: 100] (at 70, cp->sounds[1][70:79, 0.500, [1]0.708 -> 0.799]) [buf: 100] (at 80, cp->sounds[1][80:89, 0.500, [1]0.809 -> 0.900]) [buf: 100] (at 90, cp->sounds[1][90:99, 0.500]) [buf: 100] (at 100, end_mark) ") revert_sound map_channel($init_channel, 0, 100) ramp_channel(0.0, 1.0) 10.times do |i| scale_channel(0.5, i * 10, 10) end test_output.call(12, " (scale 90 10) ; scale_channel(0.500, 90, 10 [12:11]: (at 0, cp->sounds[1][0:9, 0.500, [1]0.000 -> 0.091]) [buf: 100] (at 10, cp->sounds[1][10:19, 0.500, [1]0.101 -> 0.192]) [buf: 100] (at 20, cp->sounds[1][20:29, 0.500, [1]0.202 -> 0.293]) [buf: 100] (at 30, cp->sounds[1][30:39, 0.500, [1]0.303 -> 0.394]) [buf: 100] (at 40, cp->sounds[1][40:49, 0.500, [1]0.404 -> 0.495]) [buf: 100] (at 50, cp->sounds[1][50:59, 0.500, [1]0.505 -> 0.596]) [buf: 100] (at 60, cp->sounds[1][60:69, 0.500, [1]0.606 -> 0.697]) [buf: 100] (at 70, cp->sounds[1][70:79, 0.500, [1]0.707 -> 0.798]) [buf: 100] (at 80, cp->sounds[1][80:89, 0.500, [1]0.808 -> 0.899]) [buf: 100] (at 90, cp->sounds[1][90:99, 0.500, [1]0.909 -> 1.000]) [buf: 100] (at 100, end_mark) ") close_sound(ind) end # ramp2 def test_05_03 ind = new_sound("test.snd") idx = -1 test_name = "ramp2" test_output = lambda do |ed, str| idx += 1 if (res = safe_display_edits(ind, 0, ed)) != str snd_display("%s %s: %s %s?", test_name, idx, str, res) end end map_chan($init_channel, 0, 10) ramp_channel(0.0, 1.0) ramp_channel(0.0, 1.0) test_output.call(3, " (ramp 0 11) ; ramp_channel(0.000, 1.000, 0, false [3:2]: (at 0, cp->sounds[1][0:10, 1.000, [1]0.000 -> 1.000, [2]0.000 -> 1.000]) [buf: 11] (at 11, end_mark) ") unless vequal(res = channel2vct, vct(0.000, 0.010, 0.040, 0.090, 0.160, 0.250, 0.360, 0.490, 0.640, 0.810, 1.000)) snd_display("ramp2 (0): %s", res) end scale_channel(0.5) test_output.call(4, " (scale 0 11) ; scale_channel(0.500, 0, false [4:2]: (at 0, cp->sounds[1][0:10, 0.500, [1]0.000 -> 1.000, [2]0.000 -> 1.000]) [buf: 11] (at 11, end_mark) ") undo_edit scale_channel(0.5, 0, 5) test_output.call(4, " (scale 0 5) ; scale_channel(0.500, 0, 5 [4:3]: (at 0, cp->sounds[1][0:4, 0.500, [1]0.000 -> 0.400, [2]0.000 -> 0.400]) [buf: 11] (at 5, cp->sounds[1][5:10, 1.000, [1]0.500 -> 1.000, [2]0.500 -> 1.000]) [buf: 11] (at 11, end_mark) ") unless vequal(res = channel2vct, vct(0.000, 0.005, 0.020, 0.045, 0.080, 0.250, 0.360, 0.490, 0.640, 0.810, 1.000)) snd_display("ramp2 (2): %s", res) end undo_edit scale_channel(0.5, 2, 4) test_output.call(4, " (scale 2 4) ; scale_channel(0.500, 2, 4 [4:4]: (at 0, cp->sounds[1][0:1, 1.000, [1]0.000 -> 0.100, [2]0.000 -> 0.100]) [buf: 11] (at 2, cp->sounds[1][2:5, 0.500, [1]0.200 -> 0.500, [2]0.200 -> 0.500]) [buf: 11] (at 6, cp->sounds[1][6:10, 1.000, [1]0.600 -> 1.000, [2]0.600 -> 1.000]) [buf: 11] (at 11, end_mark) ") undo_edit(2) ramp_channel(0.75, 0.25) test_output.call(3, " (ramp 0 11) ; ramp_channel(0.750, 0.250, 0, false [3:2]: (at 0, cp->sounds[1][0:10, 1.000, [1]0.000 -> 1.000, [2]0.750 -> 0.250]) [buf: 11] (at 11, end_mark) ") undo_edit ramp_channel(0.2, 0.6, 2, 6) test_output.call(3, " (ramp 2 6) ; ramp_channel(0.200, 0.600, 2, 6 [3:4]: (at 0, cp->sounds[1][0:1, 1.000, [1]0.000 -> 0.100]) [buf: 11] (at 2, cp->sounds[1][2:7, 1.000, [1]0.200 -> 0.700, [2]0.200 -> 0.600]) [buf: 11] (at 8, cp->sounds[1][8:10, 1.000, [1]0.800 -> 1.000]) [buf: 11] (at 11, end_mark) ") scale_channel(0.5, 0, 5) test_output.call(4, " (scale 0 5) ; scale_channel(0.500, 0, 5 [4:5]: (at 0, cp->sounds[1][0:1, 0.500, [1]0.000 -> 0.100]) [buf: 11] (at 2, cp->sounds[1][2:4, 0.500, [1]0.200 -> 0.400, [2]0.200 -> 0.360]) [buf: 11] (at 5, cp->sounds[1][5:7, 1.000, [1]0.500 -> 0.700, [2]0.440 -> 0.600]) [buf: 11] (at 8, cp->sounds[1][8:10, 1.000, [1]0.800 -> 1.000]) [buf: 11] (at 11, end_mark) ") undo_edit set_sample(4, 0.5) test_output.call(4, " (set 4 1) ; set_sample(4, 0.5000 [4:6]: (at 0, cp->sounds[1][0:1, 1.000, [1]0.000 -> 0.100]) [buf: 11] (at 2, cp->sounds[1][2:3, 1.000, [1]0.200 -> 0.300, [2]0.200 -> 0.280]) [buf: 11] (at 4, cp->sounds[2][0:0, 1.000]) [buf: 1] (at 5, cp->sounds[1][5:7, 1.000, [1]0.500 -> 0.700, [2]0.440 -> 0.600]) [buf: 11] (at 8, cp->sounds[1][8:10, 1.000, [1]0.800 -> 1.000]) [buf: 11] (at 11, end_mark) ") undo_edit(3) close_sound(ind) ind = new_sound("test.snd") map_channel($init_channel, 0, 100) test_name = "multi-ramp2" 10.times do |i| scale_channel(0.5, i * 10, 10) end ramp_channel(0.0, 1.0) ramp_channel(1.0, 0.0) test_output.call(13, " (ramp 0 100) ; ramp_channel(1.000, 0.000, 0, false [13:11]: (at 0, cp->sounds[1][0:9, 0.500, [1]0.000 -> 0.091, [2]1.000 -> 0.909]) [buf: 100] (at 10, cp->sounds[1][10:19, 0.500, [1]0.101 -> 0.192, [2]0.899 -> 0.808]) [buf: 100] (at 20, cp->sounds[1][20:29, 0.500, [1]0.202 -> 0.293, [2]0.798 -> 0.707]) [buf: 100] (at 30, cp->sounds[1][30:39, 0.500, [1]0.303 -> 0.394, [2]0.697 -> 0.606]) [buf: 100] (at 40, cp->sounds[1][40:49, 0.500, [1]0.404 -> 0.495, [2]0.596 -> 0.505]) [buf: 100] (at 50, cp->sounds[1][50:59, 0.500, [1]0.505 -> 0.596, [2]0.495 -> 0.404]) [buf: 100] (at 60, cp->sounds[1][60:69, 0.500, [1]0.606 -> 0.697, [2]0.394 -> 0.303]) [buf: 100] (at 70, cp->sounds[1][70:79, 0.500, [1]0.707 -> 0.798, [2]0.293 -> 0.202]) [buf: 100] (at 80, cp->sounds[1][80:89, 0.500, [1]0.808 -> 0.899, [2]0.192 -> 0.101]) [buf: 100] (at 90, cp->sounds[1][90:99, 0.500, [1]0.909 -> 1.000, [2]0.091 -> 0.000]) [buf: 100] (at 100, end_mark) ") undo_edit(12) ramp_channel(0.0, 1.0, 10, 20) ramp_channel(0.0, 1.0, 50, 10) ramp_channel(0.0, 1.0, 25, 10) test_output.call(4, " (ramp 25 10) ; ramp_channel(0.000, 1.000, 25, 10 [4:8]: (at 0, cp->sounds[1][0:9, 1.000]) [buf: 100] (at 10, cp->sounds[1][10:24, 1.000, [1]0.000 -> 0.737]) [buf: 100] (at 25, cp->sounds[1][25:29, 1.000, [1]0.789 -> 1.000, [2]0.000 -> 0.444]) [buf: 100] (at 30, cp->sounds[1][30:34, 1.000, [1]0.556 -> 1.000]) [buf: 100] (at 35, cp->sounds[1][35:49, 1.000]) [buf: 100] (at 50, cp->sounds[1][50:59, 1.000, [1]0.000 -> 1.000]) [buf: 100] (at 60, cp->sounds[1][60:99, 1.000]) [buf: 100] (at 100, end_mark) ") close_sound(ind) end # ramp-xramp, xramp-ramp def test_05_04 ind = new_sound("test.snd") idx = -1 test_name = "ramp-xramp" test_output = lambda do |ed, str| idx += 1 if (res = safe_display_edits(ind, 0, ed)) != str snd_display("%s %s: %s %s?", test_name, idx, str, res) end end map_chan($init_channel, 0, 10) ramp_channel(0.0, 1.0) xramp_channel(0.0, 1.0, 32.0) test_output.call(3, " (ramp 0 11) ; xramp_channel(0.000, 1.000, 32.000, 0, false [3:2]: (at 0, cp->sounds[1][0:10, 1.000, [1]0.000 -> 1.000, [2]0.000 -> 1.000, off: -0.032, scl: 0.032]) [buf: 11] (at 11, end_mark) ") unless vequal(case1 = channel2vct, vct(0.000, 0.001, 0.006, 0.018, 0.039, 0.075, 0.135, 0.233, 0.387, 0.628, 1.000)) snd_display("ramp-xramp (1): %s", case1) end scale_channel(0.5) test_output.call(4, " (scale 0 11) ; scale_channel(0.500, 0, false [4:2]: (at 0, cp->sounds[1][0:10, 0.500, [1]0.000 -> 1.000, [2]0.000 -> 1.000, off: -0.032, scl: 0.032]) [buf: 11] (at 11, end_mark) ") undo_edit scale_channel(0.5, 0, 5) test_output.call(4, " (scale 0 5) ; scale_channel(0.500, 0, 5 [4:3]: (at 0, cp->sounds[1][0:4, 0.500, [1]0.000 -> 0.400, [2]0.000 -> 0.097, off: -0.032, scl: 0.032]) [buf: 11] (at 5, cp->sounds[1][5:10, 1.000, [1]0.500 -> 1.000, [2]0.150 -> 1.000, off: -0.032, scl: 0.032]) [buf: 11] (at 11, end_mark) ") unless vequal(case2 = channel2vct, vct(0.000, 0.001, 0.003, 0.009, 0.019, 0.075, 0.135, 0.233, 0.387, 0.628, 1.000)) snd_display("ramp-xramp (2): %s", case2) end undo_edit scale_channel(0.5, 2, 4) test_output.call(4, " (scale 2 4) ; scale_channel(0.500, 2, 4 [4:4]: (at 0, cp->sounds[1][0:1, 1.000, [1]0.000 -> 0.100, [2]0.000 -> 0.013, off: -0.032, scl: 0.032]) [buf: 11] (at 2, cp->sounds[1][2:5, 0.500, [1]0.200 -> 0.500, [2]0.032 -> 0.150, off: -0.032, scl: 0.032]) [buf: 11] (at 6, cp->sounds[1][6:10, 1.000, [1]0.600 -> 1.000, [2]0.226 -> 1.000, off: -0.032, scl: 0.032]) [buf: 11] (at 11, end_mark) ") undo_edit(2) xramp_channel(0.75, 0.25, 32.0) test_output.call(3, " (ramp 0 11) ; xramp_channel(0.750, 0.250, 32.000, 0, false [3:2]: (at 0, cp->sounds[1][0:10, 1.000, [1]0.000 -> 1.000, [2]0.750 -> 0.250, off: 0.234, scl: 0.016]) [buf: 11] (at 11, end_mark) ") undo_edit xramp_channel(0.2, 0.6, 3.0, 2, 6) test_output.call(3, " (ramp 2 6) ; xramp_channel(0.200, 0.600, 3.000, 2, 6 [3:4]: (at 0, cp->sounds[1][0:1, 1.000, [1]0.000 -> 0.100]) [buf: 11] (at 2, cp->sounds[1][2:7, 1.000, [1]0.200 -> 0.700, [2]0.200 -> 0.600, off: 0.000, scl: 0.200]) [buf: 11] (at 8, cp->sounds[1][8:10, 1.000, [1]0.800 -> 1.000]) [buf: 11] (at 11, end_mark) ") scale_channel(0.5, 0, 5) test_output.call(4, " (scale 0 5) ; scale_channel(0.500, 0, 5 [4:5]: (at 0, cp->sounds[1][0:1, 0.500, [1]0.000 -> 0.100]) [buf: 11] (at 2, cp->sounds[1][2:4, 0.500, [1]0.200 -> 0.400, [2]0.200 -> 0.310, off: 0.000, scl: 0.200]) [buf: 11] (at 5, cp->sounds[1][5:7, 1.000, [1]0.500 -> 0.700, [2]0.387 -> 0.600, off: 0.000, scl: 0.200]) [buf: 11] (at 8, cp->sounds[1][8:10, 1.000, [1]0.800 -> 1.000]) [buf: 11] (at 11, end_mark) ") undo_edit set_sample(4, 0.5) test_output.call(4, " (set 4 1) ; set_sample(4, 0.5000 [4:6]: (at 0, cp->sounds[1][0:1, 1.000, [1]0.000 -> 0.100]) [buf: 11] (at 2, cp->sounds[1][2:3, 1.000, [1]0.200 -> 0.300, [2]0.200 -> 0.249, off: 0.000, scl: 0.200]) [buf: 11] (at 4, cp->sounds[2][0:0, 1.000]) [buf: 1] (at 5, cp->sounds[1][5:7, 1.000, [1]0.500 -> 0.700, [2]0.387 -> 0.600, off: 0.000, scl: 0.200]) [buf: 11] (at 8, cp->sounds[1][8:10, 1.000, [1]0.800 -> 1.000]) [buf: 11] (at 11, end_mark) ") revert_sound test_name = "xramp-ramp" map_chan($init_channel, 0, 10) xramp_channel(0.0, 1.0, 32.0) ramp_channel(0.0, 1.0) test_output.call(3, " (ramp 0 11) ; ramp_channel(0.000, 1.000, 0, false [3:2]: (at 0, cp->sounds[1][0:10, 1.000, [1]0.000 -> 1.000, [2]0.000 -> 1.000, off: -0.032, scl: 0.032]) [buf: 11] (at 11, end_mark) ") unless vequal(case1, (res = channel2vct)) snd_display("xramp-ramp (1): %s", res) end scale_channel(0.5) test_output.call(4, " (scale 0 11) ; scale_channel(0.500, 0, false [4:2]: (at 0, cp->sounds[1][0:10, 0.500, [1]0.000 -> 1.000, [2]0.000 -> 1.000, off: -0.032, scl: 0.032]) [buf: 11] (at 11, end_mark) ") undo_edit scale_channel(0.5, 0, 5) test_output.call(4, " (scale 0 5) ; scale_channel(0.500, 0, 5 [4:3]: (at 0, cp->sounds[1][0:4, 0.500, [1]0.000 -> 0.400, [2]0.000 -> 0.097, off: -0.032, scl: 0.032]) [buf: 11] (at 5, cp->sounds[1][5:10, 1.000, [1]0.500 -> 1.000, [2]0.150 -> 1.000, off: -0.032, scl: 0.032]) [buf: 11] (at 11, end_mark) ") unless vequal(case2, (res = channel2vct)) snd_display("xramp-ramp (2): %s", res) end undo_edit scale_channel(0.5, 2, 4) test_output.call(4, " (scale 2 4) ; scale_channel(0.500, 2, 4 [4:4]: (at 0, cp->sounds[1][0:1, 1.000, [1]0.000 -> 0.100, [2]0.000 -> 0.013, off: -0.032, scl: 0.032]) [buf: 11] (at 2, cp->sounds[1][2:5, 0.500, [1]0.200 -> 0.500, [2]0.032 -> 0.150, off: -0.032, scl: 0.032]) [buf: 11] (at 6, cp->sounds[1][6:10, 1.000, [1]0.600 -> 1.000, [2]0.226 -> 1.000, off: -0.032, scl: 0.032]) [buf: 11] (at 11, end_mark) ") undo_edit(2) ramp_channel(0.75, 0.25) test_output.call(3, " (ramp 0 11) ; ramp_channel(0.750, 0.250, 0, false [3:2]: (at 0, cp->sounds[1][0:10, 1.000, [1]0.750 -> 0.250, [2]0.000 -> 1.000, off: -0.032, scl: 0.032]) [buf: 11] (at 11, end_mark) ") undo_edit ramp_channel(0.2, 0.6, 2, 6) test_output.call(3, " (ramp 2 6) ; ramp_channel(0.200, 0.600, 2, 6 [3:4]: (at 0, cp->sounds[1][0:1, 1.000, [1]0.000 -> 0.013, off: -0.032, scl: 0.032]) [buf: 11] (at 2, cp->sounds[1][2:7, 1.000, [1]0.200 -> 0.600, [2]0.032 -> 0.333, off: -0.032, scl: 0.032]) [buf: 11] (at 8, cp->sounds[1][8:10, 1.000, [1]0.484 -> 1.000, off: -0.032, scl: 0.032]) [buf: 11] (at 11, end_mark) ") scale_channel(0.5, 0, 5) test_output.call(4, " (scale 0 5) ; scale_channel(0.500, 0, 5 [4:5]: (at 0, cp->sounds[1][0:1, 0.500, [1]0.000 -> 0.013, off: -0.032, scl: 0.032]) [buf: 11] (at 2, cp->sounds[1][2:4, 0.500, [1]0.200 -> 0.360, [2]0.032 -> 0.097, off: -0.032, scl: 0.032]) [buf: 11] (at 5, cp->sounds[1][5:7, 1.000, [1]0.440 -> 0.600, [2]0.150 -> 0.333, off: -0.032, scl: 0.032]) [buf: 11] (at 8, cp->sounds[1][8:10, 1.000, [1]0.484 -> 1.000, off: -0.032, scl: 0.032]) [buf: 11] (at 11, end_mark) ") undo_edit set_sample(4, 0.5) test_output.call(4, " (set 4 1) ; set_sample(4, 0.5000 [4:6]: (at 0, cp->sounds[1][0:1, 1.000, [1]0.000 -> 0.013, off: -0.032, scl: 0.032]) [buf: 11] (at 2, cp->sounds[1][2:3, 1.000, [1]0.200 -> 0.280, [2]0.032 -> 0.059, off: -0.032, scl: 0.032]) [buf: 11] (at 4, cp->sounds[2][0:0, 1.000]) [buf: 1] (at 5, cp->sounds[1][5:7, 1.000, [1]0.440 -> 0.600, [2]0.150 -> 0.333, off: -0.032, scl: 0.032]) [buf: 11] (at 8, cp->sounds[1][8:10, 1.000, [1]0.484 -> 1.000, off: -0.032, scl: 0.032]) [buf: 11] (at 11, end_mark) ") close_sound(ind) end # ramp2+xramp def test_05_05 ind = new_sound("test.snd") idx = -1 test_name = "ramp2+xramp" test_output = lambda do |ed, str| idx += 1 if (res = safe_display_edits(ind, 0, ed)) != str snd_display("%s %s: %s %s?", test_name, idx, str, res) end end map_chan($init_channel, 0, 10) xramp_channel(0.0, 1.0, 32.0) ramp_channel(0.0, 1.0) ramp_channel(0.0, 1.0) test_output.call(4, " (ramp 0 11) ; ramp_channel(0.000, 1.000, 0, false [4:2]: (at 0, cp->sounds[1][0:10, 1.000, [1]0.000 -> 1.000, [2]0.000 -> 1.000, [3]0.000 -> 1.000, off: -0.032, scl: 0.032]) [buf: 11] (at 11, end_mark) ") unless vequal(case1 = channel2vct, vct(0.000, 0.000, 0.001, 0.005, 0.015, 0.038, 0.081, 0.163, 0.310, 0.565, 1.000)) snd_display("ramp2+xramp (1): %s", case1) end scale_channel(0.5) test_output.call(5, " (scale 0 11) ; scale_channel(0.500, 0, false [5:2]: (at 0, cp->sounds[1][0:10, 0.500, [1]0.000 -> 1.000, [2]0.000 -> 1.000, [3]0.000 -> 1.000, off: -0.032, scl: 0.032]) [buf: 11] (at 11, end_mark) ") undo_edit scale_channel(0.5, 0, 5) test_output.call(5, " (scale 0 5) ; scale_channel(0.500, 0, 5 [5:3]: (at 0, cp->sounds[1][0:4, 0.500, [1]0.000 -> 0.400, [2]0.000 -> 0.400, [3]0.000 -> 0.097, off: -0.032, scl: 0.032]) [buf: 11] (at 5, cp->sounds[1][5:10, 1.000, [1]0.500 -> 1.000, [2]0.500 -> 1.000, [3]0.150 -> 1.000, off: -0.032, scl: 0.032]) [buf: 11] (at 11, end_mark) ") unless vequal(case2 = channel2vct, vct(0.000, 0.000, 0.001, 0.003, 0.008, 0.038, 0.081, 0.163, 0.310, 0.565, 1.000)) snd_display("ramp2+xramp (2): %s", case2) end undo_edit scale_channel(0.5, 2, 4) test_output.call(5, " (scale 2 4) ; scale_channel(0.500, 2, 4 [5:4]: (at 0, cp->sounds[1][0:1, 1.000, [1]0.000 -> 0.100, [2]0.000 -> 0.100, [3]0.000 -> 0.013, off: -0.032, scl: 0.032]) [buf: 11] (at 2, cp->sounds[1][2:5, 0.500, [1]0.200 -> 0.500, [2]0.200 -> 0.500, [3]0.032 -> 0.150, off: -0.032, scl: 0.032]) [buf: 11] (at 6, cp->sounds[1][6:10, 1.000, [1]0.600 -> 1.000, [2]0.600 -> 1.000, [3]0.226 -> 1.000, off: -0.032, scl: 0.032]) [buf: 11] (at 11, end_mark) ") undo_edit(2) ramp_channel(0.75, 0.25) test_output.call(4, " (ramp 0 11) ; ramp_channel(0.750, 0.250, 0, false [4:2]: (at 0, cp->sounds[1][0:10, 1.000, [1]0.000 -> 1.000, [2]0.750 -> 0.250, [3]0.000 -> 1.000, off: -0.032, scl: 0.032]) [buf: 11] (at 11, end_mark) ") undo_edit ramp_channel(0.2, 0.6, 2, 6) test_output.call(4, " (ramp 2 6) ; ramp_channel(0.200, 0.600, 2, 6 [4:4]: (at 0, cp->sounds[1][0:1, 1.000, [1]0.000 -> 0.100, [2]0.000 -> 0.013, off: -0.032, scl: 0.032]) [buf: 11] (at 2, cp->sounds[1][2:7, 1.000, [1]0.200 -> 0.700, [2]0.200 -> 0.600, [3]0.032 -> 0.333, off: -0.032, scl: 0.032]) [buf: 11] (at 8, cp->sounds[1][8:10, 1.000, [1]0.800 -> 1.000, [2]0.484 -> 1.000, off: -0.032, scl: 0.032]) [buf: 11] (at 11, end_mark) ") scale_channel(0.5, 0, 5) test_output.call(5, " (scale 0 5) ; scale_channel(0.500, 0, 5 [5:5]: (at 0, cp->sounds[1][0:1, 0.500, [1]0.000 -> 0.100, [2]0.000 -> 0.013, off: -0.032, scl: 0.032]) [buf: 11] (at 2, cp->sounds[1][2:4, 0.500, [1]0.200 -> 0.400, [2]0.200 -> 0.360, [3]0.032 -> 0.097, off: -0.032, scl: 0.032]) [buf: 11] (at 5, cp->sounds[1][5:7, 1.000, [1]0.500 -> 0.700, [2]0.440 -> 0.600, [3]0.150 -> 0.333, off: -0.032, scl: 0.032]) [buf: 11] (at 8, cp->sounds[1][8:10, 1.000, [1]0.800 -> 1.000, [2]0.484 -> 1.000, off: -0.032, scl: 0.032]) [buf: 11] (at 11, end_mark) ") undo_edit set_sample(4, 0.5) test_output.call(5, " (set 4 1) ; set_sample(4, 0.5000 [5:6]: (at 0, cp->sounds[1][0:1, 1.000, [1]0.000 -> 0.100, [2]0.000 -> 0.013, off: -0.032, scl: 0.032]) [buf: 11] (at 2, cp->sounds[1][2:3, 1.000, [1]0.200 -> 0.300, [2]0.200 -> 0.280, [3]0.032 -> 0.059, off: -0.032, scl: 0.032]) [buf: 11] (at 4, cp->sounds[2][0:0, 1.000]) [buf: 1] (at 5, cp->sounds[1][5:7, 1.000, [1]0.500 -> 0.700, [2]0.440 -> 0.600, [3]0.150 -> 0.333, off: -0.032, scl: 0.032]) [buf: 11] (at 8, cp->sounds[1][8:10, 1.000, [1]0.800 -> 1.000, [2]0.484 -> 1.000, off: -0.032, scl: 0.032]) [buf: 11] (at 11, end_mark) ") revert_sound idx = -1 test_name = "xramp+ramp2" map_chan($init_channel, 0, 10) ramp_channel(0.0, 1.0) ramp_channel(0.0, 1.0) xramp_channel(0.0, 1.0, 32.0) test_output.call(4, " (ramp 0 11) ; xramp_channel(0.000, 1.000, 32.000, 0, false [4:2]: (at 0, cp->sounds[1][0:10, 1.000, [1]0.000 -> 1.000, [2]0.000 -> 1.000, [3]0.000 -> 1.000, off: -0.032, scl: 0.032]) [buf: 11] (at 11, end_mark) ") unless vequal(case1, (res = channel2vct)) snd_display("xramp+ramp2 (1): %s", res) end revert_sound(ind) close_sound(ind) end # multi-ramp2+xramp # multi-ramp-xramp # xramp2 # multi-xramp2 def test_05_06 ind = new_sound("test.snd") idx = -1 test_name = "multi-ramp2+xramp" test_output = lambda do |ed, str| idx += 1 if (res = safe_display_edits(ind, 0, ed)) != str snd_display("%s %s: %s %s?", test_name, idx, str, res) end end map_channel($init_channel, 0, 100) scale_channel(0.5) xramp_channel(1.0, 0.0, 32.0) ramp_channel(0.0, 1.0) ramp_channel(0.0, 1.0) case3 = channel2vct undo_edit(4) 10.times do |i| scale_channel(0.5, i * 10, 10) end xramp_channel(1.0, 0.0, 32.0) ramp_channel(0.0, 1.0) ramp_channel(0.0, 1.0) test_output.call(14, " (ramp 0 100) ; ramp_channel(0.000, 1.000, 0, false [14:11]: (at 0, cp->sounds[1][0:9, 0.500, [1]0.000 -> 0.091, [2]0.000 -> 0.091, [3]1.000 -> 0.721, off: -0.032, scl: 0.032]) [buf: 100] (at 10, cp->sounds[1][10:19, 0.500, [1]0.101 -> 0.192, [2]0.101 -> 0.192, [3]0.695 -> 0.499, off: -0.032, scl: 0.032]) [buf: 100] (at 20, cp->sounds[1][20:29, 0.500, [1]0.202 -> 0.293, [2]0.202 -> 0.293, [3]0.480 -> 0.342, off: -0.032, scl: 0.032]) [buf: 100] (at 30, cp->sounds[1][30:39, 0.500, [1]0.303 -> 0.394, [2]0.303 -> 0.394, [3]0.329 -> 0.231, off: -0.032, scl: 0.032]) [buf: 100] (at 40, cp->sounds[1][40:49, 0.500, [1]0.404 -> 0.495, [2]0.404 -> 0.495, [3]0.222 -> 0.153, off: -0.032, scl: 0.032]) [buf: 100] (at 50, cp->sounds[1][50:59, 0.500, [1]0.505 -> 0.596, [2]0.505 -> 0.596, [3]0.147 -> 0.099, off: -0.032, scl: 0.032]) [buf: 100] (at 60, cp->sounds[1][60:69, 0.500, [1]0.606 -> 0.697, [2]0.606 -> 0.697, [3]0.094 -> 0.060, off: -0.032, scl: 0.032]) [buf: 100] (at 70, cp->sounds[1][70:79, 0.500, [1]0.707 -> 0.798, [2]0.707 -> 0.798, [3]0.057 -> 0.033, off: -0.032, scl: 0.032]) [buf: 100] (at 80, cp->sounds[1][80:89, 0.500, [1]0.808 -> 0.899, [2]0.808 -> 0.899, [3]0.030 -> 0.014, off: -0.032, scl: 0.032]) [buf: 100] (at 90, cp->sounds[1][90:99, 0.500, [1]0.909 -> 1.000, [2]0.909 -> 1.000, [3]0.012 -> -0.000, off: -0.032, scl: 0.032]) [buf: 100] (at 100, end_mark) ") unless vequal(case3, res = channel2vct) snd_display("multi-ramp2+xramp: %s", res) end revert_sound map_channel($init_channel, 0, 100) xramp_channel(1.0, 0.0, 32.0) ramp_channel(0.0, 1.0, 10, 20) ramp_channel(0.0, 1.0, 50, 10) ramp_channel(0.0, 1.0, 25, 10) test_output.call(5, " (ramp 25 10) ; ramp_channel(0.000, 1.000, 25, 10 [5:8]: (at 0, cp->sounds[1][0:9, 1.000, [1]1.000 -> 0.721, off: -0.032, scl: 0.032]) [buf: 100] (at 10, cp->sounds[1][10:24, 1.000, [1]0.000 -> 0.737, [2]0.695 -> 0.413, off: -0.032, scl: 0.032]) [buf: 100] (at 25, cp->sounds[1][25:29, 1.000, [1]0.789 -> 1.000, [2]0.000 -> 0.444, [3]0.398 -> 0.342, off: -0.032, scl: 0.032]) [buf: 100] (at 30, cp->sounds[1][30:34, 1.000, [1]0.556 -> 1.000, [2]0.329 -> 0.282, off: -0.032, scl: 0.032]) [buf: 100] (at 35, cp->sounds[1][35:49, 1.000, [1]0.271 -> 0.153, off: -0.032, scl: 0.032]) [buf: 100] (at 50, cp->sounds[1][50:59, 1.000, [1]0.000 -> 1.000, [2]0.147 -> 0.099, off: -0.032, scl: 0.032]) [buf: 100] (at 60, cp->sounds[1][60:99, 1.000, [1]0.094 -> -0.000, off: -0.032, scl: 0.032]) [buf: 100] (at 100, end_mark) ") close_sound(ind) ind = new_sound("test.snd") idx = -1 test_name = "multi-ramp-xramp" map_channel($init_channel, 0, 100) scale_channel(0.5) ramp_channel(0.0, 1.0) xramp_channel(1.0, 0.0, 32.0) case3 = channel2vct undo_edit(3) 10.times do |i| scale_channel(0.5, i * 10, 10) end ramp_channel(0.0, 1.0) xramp_channel(1.0, 0.0, 32.0) test_output.call(13, " (ramp 0 100) ; xramp_channel(1.000, 0.000, 32.000, 0, false [13:11]: (at 0, cp->sounds[1][0:9, 0.500, [1]0.000 -> 0.091, [2]1.000 -> 0.721, off: -0.032, scl: 0.032]) [buf: 100] (at 10, cp->sounds[1][10:19, 0.500, [1]0.101 -> 0.192, [2]0.695 -> 0.499, off: -0.032, scl: 0.032]) [buf: 100] (at 20, cp->sounds[1][20:29, 0.500, [1]0.202 -> 0.293, [2]0.480 -> 0.342, off: -0.032, scl: 0.032]) [buf: 100] (at 30, cp->sounds[1][30:39, 0.500, [1]0.303 -> 0.394, [2]0.329 -> 0.231, off: -0.032, scl: 0.032]) [buf: 100] (at 40, cp->sounds[1][40:49, 0.500, [1]0.404 -> 0.495, [2]0.222 -> 0.153, off: -0.032, scl: 0.032]) [buf: 100] (at 50, cp->sounds[1][50:59, 0.500, [1]0.505 -> 0.596, [2]0.147 -> 0.099, off: -0.032, scl: 0.032]) [buf: 100] (at 60, cp->sounds[1][60:69, 0.500, [1]0.606 -> 0.697, [2]0.094 -> 0.060, off: -0.032, scl: 0.032]) [buf: 100] (at 70, cp->sounds[1][70:79, 0.500, [1]0.707 -> 0.798, [2]0.057 -> 0.033, off: -0.032, scl: 0.032]) [buf: 100] (at 80, cp->sounds[1][80:89, 0.500, [1]0.808 -> 0.899, [2]0.030 -> 0.014, off: -0.032, scl: 0.032]) [buf: 100] (at 90, cp->sounds[1][90:99, 0.500, [1]0.909 -> 1.000, [2]0.012 -> -0.000, off: -0.032, scl: 0.032]) [buf: 100] (at 100, end_mark) ") unless vequal(case3, res = channel2vct) snd_display("multi-ramp-xramp: %s", res) end undo_edit(12) xramp_channel(0.0, 1.0, 3.0, 10, 20) xramp_channel(0.0, 1.0, 3.0, 50, 10) xramp_channel(0.0, 1.0, 3.0, 25, 10) test_output.call(4, " (ramp 25 10) ; xramp_channel(0.000, 1.000, 3.000, 25, 10 [4:8]: (at 0, cp->sounds[1][0:9, 1.000]) [buf: 100] (at 10, cp->sounds[1][10:24, 1.000, [1]0.000 -> 0.623, off: -0.500, scl: 0.500]) [buf: 100] (at 25, cp->sounds[1][25:29, 1.000, [1]0.690 -> 1.000, off: -0.500, scl: 0.500, [2]0.000 -> 0.315, off: -0.500, scl: 0.500]) [buf: 100] (at 30, cp->sounds[1][30:34, 1.000, [1]0.421 -> 1.000, off: -0.500, scl: 0.500]) [buf: 100] (at 35, cp->sounds[1][35:49, 1.000]) [buf: 100] (at 50, cp->sounds[1][50:59, 1.000, [1]0.000 -> 1.000, off: -0.500, scl: 0.500]) [buf: 100] (at 60, cp->sounds[1][60:99, 1.000]) [buf: 100] (at 100, end_mark) ") revert_sound test_name = "multi-xramp-ramp 3" map_channel($init_channel, 0, 100) 10.times do |i| scale_channel(0.5, i * 10, 10) end xramp_channel(1.0, 0.0, 32.0) ramp_channel(0.0, 1.0) test_output.call(13, " (ramp 0 100) ; ramp_channel(0.000, 1.000, 0, false [13:11]: (at 0, cp->sounds[1][0:9, 0.500, [1]0.000 -> 0.091, [2]1.000 -> 0.721, off: -0.032, scl: 0.032]) [buf: 100] (at 10, cp->sounds[1][10:19, 0.500, [1]0.101 -> 0.192, [2]0.695 -> 0.499, off: -0.032, scl: 0.032]) [buf: 100] (at 20, cp->sounds[1][20:29, 0.500, [1]0.202 -> 0.293, [2]0.480 -> 0.342, off: -0.032, scl: 0.032]) [buf: 100] (at 30, cp->sounds[1][30:39, 0.500, [1]0.303 -> 0.394, [2]0.329 -> 0.231, off: -0.032, scl: 0.032]) [buf: 100] (at 40, cp->sounds[1][40:49, 0.500, [1]0.404 -> 0.495, [2]0.222 -> 0.153, off: -0.032, scl: 0.032]) [buf: 100] (at 50, cp->sounds[1][50:59, 0.500, [1]0.505 -> 0.596, [2]0.147 -> 0.099, off: -0.032, scl: 0.032]) [buf: 100] (at 60, cp->sounds[1][60:69, 0.500, [1]0.606 -> 0.697, [2]0.094 -> 0.060, off: -0.032, scl: 0.032]) [buf: 100] (at 70, cp->sounds[1][70:79, 0.500, [1]0.707 -> 0.798, [2]0.057 -> 0.033, off: -0.032, scl: 0.032]) [buf: 100] (at 80, cp->sounds[1][80:89, 0.500, [1]0.808 -> 0.899, [2]0.030 -> 0.014, off: -0.032, scl: 0.032]) [buf: 100] (at 90, cp->sounds[1][90:99, 0.500, [1]0.909 -> 1.000, [2]0.012 -> -0.000, off: -0.032, scl: 0.032]) [buf: 100] (at 100, end_mark) ") undo_edit(12) ramp_channel(0.0, 1.0, 10, 20) ramp_channel(0.0, 1.0, 50, 10) ramp_channel(0.0, 1.0, 25, 10) test_output.call(4, " (ramp 25 10) ; ramp_channel(0.000, 1.000, 25, 10 [4:8]: (at 0, cp->sounds[1][0:9, 1.000]) [buf: 100] (at 10, cp->sounds[1][10:24, 1.000, [1]0.000 -> 0.737]) [buf: 100] (at 25, cp->sounds[1][25:29, 1.000, [1]0.789 -> 1.000, [2]0.000 -> 0.444]) [buf: 100] (at 30, cp->sounds[1][30:34, 1.000, [1]0.556 -> 1.000]) [buf: 100] (at 35, cp->sounds[1][35:49, 1.000]) [buf: 100] (at 50, cp->sounds[1][50:59, 1.000, [1]0.000 -> 1.000]) [buf: 100] (at 60, cp->sounds[1][60:99, 1.000]) [buf: 100] (at 100, end_mark) ") close_sound(ind) ind = new_sound("test.snd") idx = -1 test_name = "xramp2" map_chan($init_channel, 0, 10) xramp_channel(0.0, 1.0, 2.0) xramp_channel(0.0, 1.0, 2.0) test_output.call(3, " (ramp 0 11) ; xramp_channel(0.000, 1.000, 2.000, 0, false [3:2]: (at 0, cp->sounds[1][0:10, 1.000, [1]0.000 -> 1.000, off: -1.000, scl: 1.000, [2]0.000 -> 1.000, off: -1.000, scl: 1.000]) [buf: 11] (at 11, end_mark) ") unless vequal(res = channel2vct, vct(0.000, 0.005, 0.022, 0.053, 0.102, 0.172, 0.266, 0.390, 0.549, 0.750, 1.000)) snd_display("xramp2 (1): %s", res) end scale_channel(0.5) test_output.call(4, " (scale 0 11) ; scale_channel(0.500, 0, false [4:2]: (at 0, cp->sounds[1][0:10, 0.500, [1]0.000 -> 1.000, off: -1.000, scl: 1.000, [2]0.000 -> 1.000, off: -1.000, scl: 1.000]) [buf: 11] (at 11, end_mark) ") undo_edit scale_channel(0.5, 0, 5) test_output.call(4, " (scale 0 5) ; scale_channel(0.500, 0, 5 [4:3]: (at 0, cp->sounds[1][0:4, 0.500, [1]0.000 -> 0.320, off: -1.000, scl: 1.000, [2]0.000 -> 0.320, off: -1.000, scl: 1.000]) [buf: 11] (at 5, cp->sounds[1][5:10, 1.000, [1]0.414 -> 1.000, off: -1.000, scl: 1.000, [2]0.414 -> 1.000, off: -1.000, scl: 1.000]) [buf: 11] (at 11, end_mark) ") unless vequal(res = channel2vct, vct(0.000, 0.003, 0.011, 0.027, 0.051, 0.172, 0.266, 0.390, 0.549, 0.750, 1.000)) snd_display("xramp2 (2): %s", res) end undo_edit scale_channel(0.5, 2, 4) test_output.call(4, " (scale 2 4) ; scale_channel(0.500, 2, 4 [4:4]: (at 0, cp->sounds[1][0:1, 1.000, [1]0.000 -> 0.072, off: -1.000, scl: 1.000, [2]0.000 -> 0.072, off: -1.000, scl: 1.000]) [buf: 11] (at 2, cp->sounds[1][2:5, 0.500, [1]0.149 -> 0.414, off: -1.000, scl: 1.000, [2]0.149 -> 0.414, off: -1.000, scl: 1.000]) [buf: 11] (at 6, cp->sounds[1][6:10, 1.000, [1]0.516 -> 1.000, off: -1.000, scl: 1.000, [2]0.516 -> 1.000, off: -1.000, scl: 1.000]) [buf: 11] (at 11, end_mark) ") undo_edit(2) xramp_channel(0.75, 0.25, 0.3) test_output.call(3, " (ramp 0 11) ; xramp_channel(0.750, 0.250, 0.300, 0, false [3:2]: (at 0, cp->sounds[1][0:10, 1.000, [1]0.000 -> 1.000, off: -1.000, scl: 1.000, [2]0.750 -> 0.250, off: 0.964, scl: -0.714]) [buf: 11] (at 11, end_mark) ") undo_edit xramp_channel(0.2, 0.6, 32.0, 2, 6) test_output.call(3, " (ramp 2 6) ; xramp_channel(0.200, 0.600, 32.000, 2, 6 [3:4]: (at 0, cp->sounds[1][0:1, 1.000, [1]0.000 -> 0.072, off: -1.000, scl: 1.000]) [buf: 11] (at 2, cp->sounds[1][2:7, 1.000, [1]0.149 -> 0.625, off: -1.000, scl: 1.000, [2]0.200 -> 0.600, off: 0.187, scl: 0.013]) [buf: 11] (at 8, cp->sounds[1][8:10, 1.000, [1]0.741 -> 1.000, off: -1.000, scl: 1.000]) [buf: 11] (at 11, end_mark) ") scale_channel(0.5, 0, 5) test_output.call(4, " (scale 0 5) ; scale_channel(0.500, 0, 5 [4:5]: (at 0, cp->sounds[1][0:1, 0.500, [1]0.000 -> 0.072, off: -1.000, scl: 1.000]) [buf: 11] (at 2, cp->sounds[1][2:4, 0.500, [1]0.149 -> 0.320, off: -1.000, scl: 1.000, [2]0.200 -> 0.239, off: 0.187, scl: 0.013]) [buf: 11] (at 5, cp->sounds[1][5:7, 1.000, [1]0.414 -> 0.625, off: -1.000, scl: 1.000, [2]0.290 -> 0.600, off: 0.187, scl: 0.013]) [buf: 11] (at 8, cp->sounds[1][8:10, 1.000, [1]0.741 -> 1.000, off: -1.000, scl: 1.000]) [buf: 11] (at 11, end_mark) ") undo_edit set_sample(4, 0.5) test_output.call(4, " (set 4 1) ; set_sample(4, 0.5000 [4:6]: (at 0, cp->sounds[1][0:1, 1.000, [1]0.000 -> 0.072, off: -1.000, scl: 1.000]) [buf: 11] (at 2, cp->sounds[1][2:3, 1.000, [1]0.149 -> 0.231, off: -1.000, scl: 1.000, [2]0.200 -> 0.213, off: 0.187, scl: 0.013]) [buf: 11] (at 4, cp->sounds[2][0:0, 1.000]) [buf: 1] (at 5, cp->sounds[1][5:7, 1.000, [1]0.414 -> 0.625, off: -1.000, scl: 1.000, [2]0.290 -> 0.600, off: 0.187, scl: 0.013]) [buf: 11] (at 8, cp->sounds[1][8:10, 1.000, [1]0.741 -> 1.000, off: -1.000, scl: 1.000]) [buf: 11] (at 11, end_mark) ") undo_edit(3) close_sound(ind) ind = new_sound("test.snd") idx = -1 test_name = "multi-xramp2" map_channel($init_channel, 0, 100) 10.times do |i| scale_channel(0.5, i * 10, 10) end xramp_channel(0.0, 1.0, 3.0) xramp_channel(1.0, 0.0, 0.3) test_output.call(13, " (ramp 0 100) ; xramp_channel(1.000, 0.000, 0.300, 0, false [13:11]: (at 0, cp->sounds[1][0:9, 0.500, [1]0.000 -> 0.053, off: -0.500, scl: 0.500, [2]1.000 -> 0.950, off: 1.429, scl: -1.429]) [buf: 100] (at 10, cp->sounds[1][10:19, 0.500, [1]0.059 -> 0.117, off: -0.500, scl: 0.500, [2]0.945 -> 0.889, off: 1.429, scl: -1.429]) [buf: 100] (at 20, cp->sounds[1][20:29, 0.500, [1]0.124 -> 0.190, off: -0.500, scl: 0.500, [2]0.882 -> 0.819, off: 1.429, scl: -1.429]) [buf: 100] (at 30, cp->sounds[1][30:39, 0.500, [1]0.198 -> 0.271, off: -0.500, scl: 0.500, [2]0.811 -> 0.740, off: 1.429, scl: -1.429]) [buf: 100] (at 40, cp->sounds[1][40:49, 0.500, [1]0.279 -> 0.361, off: -0.500, scl: 0.500, [2]0.731 -> 0.651, off: 1.429, scl: -1.429]) [buf: 100] (at 50, cp->sounds[1][50:59, 0.500, [1]0.371 -> 0.462, off: -0.500, scl: 0.500, [2]0.641 -> 0.550, off: 1.429, scl: -1.429]) [buf: 100] (at 60, cp->sounds[1][60:69, 0.500, [1]0.473 -> 0.575, off: -0.500, scl: 0.500, [2]0.540 -> 0.437, off: 1.429, scl: -1.429]) [buf: 100] (at 70, cp->sounds[1][70:79, 0.500, [1]0.587 -> 0.701, off: -0.500, scl: 0.500, [2]0.425 -> 0.308, off: 1.429, scl: -1.429]) [buf: 100] (at 80, cp->sounds[1][80:89, 0.500, [1]0.715 -> 0.842, off: -0.500, scl: 0.500, [2]0.295 -> 0.164, off: 1.429, scl: -1.429]) [buf: 100] (at 90, cp->sounds[1][90:99, 0.500, [1]0.857 -> 1.000, off: -0.500, scl: 0.500, [2]0.148 -> 0.000, off: 1.429, scl: -1.429]) [buf: 100] (at 100, end_mark) ") close_sound(ind) end # ramp3 # multi-ramp3 def test_05_07 ind = new_sound("test.snd") idx = -1 test_name = "ramp3" test_output = lambda do |ed, str| idx += 1 if (res = safe_display_edits(ind, 0, ed)) != str snd_display("%s %s: %s %s?", test_name, idx, str, res) end end map_chan($init_channel, 0, 10) ramp_channel(0.0, 1.0) ramp_channel(0.0, 1.0) ramp_channel(0.0, 1.0) test_output.call(4, " (ramp 0 11) ; ramp_channel(0.000, 1.000, 0, false [4:2]: (at 0, cp->sounds[1][0:10, 1.000, [1]0.000 -> 1.000, [2]0.000 -> 1.000, [3]0.000 -> 1.000]) [buf: 11] (at 11, end_mark) ") unless vequal(res = channel2vct, vct(0.000, 0.001, 0.008, 0.027, 0.064, 0.125, 0.216, 0.343, 0.512, 0.729, 1.000)) snd_display("ramp3 (1): %s", res) end scale_channel(0.5) test_output.call(5, " (scale 0 11) ; scale_channel(0.500, 0, false [5:2]: (at 0, cp->sounds[1][0:10, 0.500, [1]0.000 -> 1.000, [2]0.000 -> 1.000, [3]0.000 -> 1.000]) [buf: 11] (at 11, end_mark) ") undo_edit scale_channel(0.5, 0, 5) test_output.call(5, " (scale 0 5) ; scale_channel(0.500, 0, 5 [5:3]: (at 0, cp->sounds[1][0:4, 0.500, [1]0.000 -> 0.400, [2]0.000 -> 0.400, [3]0.000 -> 0.400]) [buf: 11] (at 5, cp->sounds[1][5:10, 1.000, [1]0.500 -> 1.000, [2]0.500 -> 1.000, [3]0.500 -> 1.000]) [buf: 11] (at 11, end_mark) ") undo_edit scale_channel(0.5, 2, 4) test_output.call(5, " (scale 2 4) ; scale_channel(0.500, 2, 4 [5:4]: (at 0, cp->sounds[1][0:1, 1.000, [1]0.000 -> 0.100, [2]0.000 -> 0.100, [3]0.000 -> 0.100]) [buf: 11] (at 2, cp->sounds[1][2:5, 0.500, [1]0.200 -> 0.500, [2]0.200 -> 0.500, [3]0.200 -> 0.500]) [buf: 11] (at 6, cp->sounds[1][6:10, 1.000, [1]0.600 -> 1.000, [2]0.600 -> 1.000, [3]0.600 -> 1.000]) [buf: 11] (at 11, end_mark) ") undo_edit(2) ramp_channel(0.75, 0.25) test_output.call(4, " (ramp 0 11) ; ramp_channel(0.750, 0.250, 0, false [4:2]: (at 0, cp->sounds[1][0:10, 1.000, [1]0.000 -> 1.000, [2]0.000 -> 1.000, [3]0.750 -> 0.250]) [buf: 11] (at 11, end_mark) ") undo_edit ramp_channel(0.2, 0.6, 2, 6) test_output.call(4, " (ramp 2 6) ; ramp_channel(0.200, 0.600, 2, 6 [4:4]: (at 0, cp->sounds[1][0:1, 1.000, [1]0.000 -> 0.100, [2]0.000 -> 0.100]) [buf: 11] (at 2, cp->sounds[1][2:7, 1.000, [1]0.200 -> 0.700, [2]0.200 -> 0.700, [3]0.200 -> 0.600]) [buf: 11] (at 8, cp->sounds[1][8:10, 1.000, [1]0.800 -> 1.000, [2]0.800 -> 1.000]) [buf: 11] (at 11, end_mark) ") scale_channel(0.5, 0, 5) test_output.call(5, " (scale 0 5) ; scale_channel(0.500, 0, 5 [5:5]: (at 0, cp->sounds[1][0:1, 0.500, [1]0.000 -> 0.100, [2]0.000 -> 0.100]) [buf: 11] (at 2, cp->sounds[1][2:4, 0.500, [1]0.200 -> 0.400, [2]0.200 -> 0.400, [3]0.200 -> 0.360]) [buf: 11] (at 5, cp->sounds[1][5:7, 1.000, [1]0.500 -> 0.700, [2]0.500 -> 0.700, [3]0.440 -> 0.600]) [buf: 11] (at 8, cp->sounds[1][8:10, 1.000, [1]0.800 -> 1.000, [2]0.800 -> 1.000]) [buf: 11] (at 11, end_mark) ") undo_edit set_sample(4, 0.5) test_output.call(5, " (set 4 1) ; set_sample(4, 0.5000 [5:6]: (at 0, cp->sounds[1][0:1, 1.000, [1]0.000 -> 0.100, [2]0.000 -> 0.100]) [buf: 11] (at 2, cp->sounds[1][2:3, 1.000, [1]0.200 -> 0.300, [2]0.200 -> 0.300, [3]0.200 -> 0.280]) [buf: 11] (at 4, cp->sounds[2][0:0, 1.000]) [buf: 1] (at 5, cp->sounds[1][5:7, 1.000, [1]0.500 -> 0.700, [2]0.500 -> 0.700, [3]0.440 -> 0.600]) [buf: 11] (at 8, cp->sounds[1][8:10, 1.000, [1]0.800 -> 1.000, [2]0.800 -> 1.000]) [buf: 11] (at 11, end_mark) ") undo_edit(3) close_sound(ind) ind = new_sound("test.snd") idx = -1 test_name = "multi-ramp3" map_channel($init_channel, 0, 100) test_name = "" 10.times do |i| scale_channel(0.5, i * 10, 10) end ramp_channel(0.0, 1.0) ramp_channel(1.0, -0.5) ramp_channel(-0.5, 1.5) test_output.call(14, " (ramp 0 100) ; ramp_channel(-0.500, 1.500, 0, false [14:11]: (at 0, cp->sounds[1][0:9, 0.500, [1]0.000 -> 0.091, [2]1.000 -> 0.864, [3]-0.500 -> -0.318]) [buf: 100] (at 10, cp->sounds[1][10:19, 0.500, [1]0.101 -> 0.192, [2]0.848 -> 0.712, [3]-0.298 -> -0.116]) [buf: 100] (at 20, cp->sounds[1][20:29, 0.500, [1]0.202 -> 0.293, [2]0.697 -> 0.561, [3]-0.096 -> 0.086]) [buf: 100] (at 30, cp->sounds[1][30:39, 0.500, [1]0.303 -> 0.394, [2]0.545 -> 0.409, [3]0.106 -> 0.288]) [buf: 100] (at 40, cp->sounds[1][40:49, 0.500, [1]0.404 -> 0.495, [2]0.394 -> 0.258, [3]0.308 -> 0.490]) [buf: 100] (at 50, cp->sounds[1][50:59, 0.500, [1]0.505 -> 0.596, [2]0.242 -> 0.106, [3]0.510 -> 0.692]) [buf: 100] (at 60, cp->sounds[1][60:69, 0.500, [1]0.606 -> 0.697, [2]0.091 -> -0.045, [3]0.712 -> 0.894]) [buf: 100] (at 70, cp->sounds[1][70:79, 0.500, [1]0.707 -> 0.798, [2]-0.061 -> -0.197, [3]0.914 -> 1.096]) [buf: 100] (at 80, cp->sounds[1][80:89, 0.500, [1]0.808 -> 0.899, [2]-0.212 -> -0.348, [3]1.116 -> 1.298]) [buf: 100] (at 90, cp->sounds[1][90:99, 0.500, [1]0.909 -> 1.000, [2]-0.364 -> -0.500, [3]1.318 -> 1.500]) [buf: 100] (at 100, end_mark) ") undo_edit(13) ramp_channel(0.0, 1.0, 10, 30) ramp_channel(0.0, 1.0, 50, 20) ramp_channel(0.0, 1.0, 20, 15) ramp_channel(0.0, 1.0, 30, 30) test_output.call(5, " (ramp 30 30) ; ramp_channel(0.000, 1.000, 30, 30 [5:10]: (at 0, cp->sounds[1][0:9, 1.000]) [buf: 100] (at 10, cp->sounds[1][10:19, 1.000, [1]0.000 -> 0.310]) [buf: 100] (at 20, cp->sounds[1][20:29, 1.000, [1]0.345 -> 0.655, [2]0.000 -> 0.643]) [buf: 100] (at 30, cp->sounds[1][30:34, 1.000, [1]0.690 -> 0.828, [2]0.714 -> 1.000, [3]0.000 -> 0.138]) [buf: 100] (at 35, cp->sounds[1][35:39, 1.000, [1]0.862 -> 1.000, [2]0.172 -> 0.310]) [buf: 100] (at 40, cp->sounds[1][40:49, 1.000, [1]0.345 -> 0.655]) [buf: 100] (at 50, cp->sounds[1][50:59, 1.000, [1]0.000 -> 0.474, [2]0.690 -> 1.000]) [buf: 100] (at 60, cp->sounds[1][60:69, 1.000, [1]0.526 -> 1.000]) [buf: 100] (at 70, cp->sounds[1][70:99, 1.000]) [buf: 100] (at 100, end_mark) ") close_sound(ind) ind = new_sound("test.snd") map_chan($init_channel, 0, 10) idx = -1 test_name = "ramp+xramp" ramp_channel(0.0, 1.0) xramp_channel(0.0, 1.0, 32.0) test_output.call(3, " (ramp 0 11) ; xramp_channel(0.000, 1.000, 32.000, 0, false [3:2]: (at 0, cp->sounds[1][0:10, 1.000, [1]0.000 -> 1.000, [2]0.000 -> 1.000, off: -0.032, scl: 0.032]) [buf: 11] (at 11, end_mark) ") idx = -1 test_name = "xramp+xramp" undo_edit(2) xramp_channel(0.0, 1.0, 0.32) xramp_channel(0.0, 1.0, 32.0) test_output.call(3, " (ramp 0 11) ; xramp_channel(0.000, 1.000, 32.000, 0, false [3:2]: (at 0, cp->sounds[1][0:10, 1.000, [1]0.000 -> 1.000, off: 1.471, scl: -1.471, [2]0.000 -> 1.000, off: -0.032, scl: 0.032]) [buf: 11] (at 11, end_mark) ") idx = -1 test_name = "xramp+xramp+xramp" undo_edit(2) xramp_channel(0.0, 1.0, 0.32) xramp_channel(0.0, 1.0, 32.0) xramp_channel(0.0, 1.0, 32.0) test_output.call(4, " (ramp 0 11) ; xramp_channel(0.000, 1.000, 32.000, 0, false [4:2]: (at 0, cp->sounds[1][0:10, 1.000, [1]0.000 -> 1.000, off: 1.471, scl: -1.471, [2]0.000 -> 1.000, off: -0.032, scl: 0.032, [3]0.000 -> 1.000, off: -0.032, scl: 0.032]) [buf: 11] (at 11, end_mark) ") idx = -1 test_name = "xramp+xramp+ramp" undo_edit(3) xramp_channel(0.0, 1.0, 0.32) xramp_channel(0.0, 1.0, 32.0) ramp_channel(0.0, 1.0) test_output.call(4, " (ramp 0 11) ; ramp_channel(0.000, 1.000, 0, false [4:2]: (at 0, cp->sounds[1][0:10, 1.000, [1]0.000 -> 1.000, [2]0.000 -> 1.000, off: 1.471, scl: -1.471, [3]0.000 -> 1.000, off: -0.032, scl: 0.032]) [buf: 11] (at 11, end_mark) ") idx = -1 test_name = "xramp+ramp" undo_edit(3) xramp_channel(0.0, 1.0, 32.0) ramp_channel(0.0, 1.0) test_output.call(3, " (ramp 0 11) ; ramp_channel(0.000, 1.000, 0, false [3:2]: (at 0, cp->sounds[1][0:10, 1.000, [1]0.000 -> 1.000, [2]0.000 -> 1.000, off: -0.032, scl: 0.032]) [buf: 11] (at 11, end_mark) ") idx = -1 test_name = "ramp+ramp+xramp" undo_edit(2) ramp_channel(0.0, 1.0) ramp_channel(0.0, 1.0) xramp_channel(0.0, 1.0, 32.0) test_output.call(4, " (ramp 0 11) ; xramp_channel(0.000, 1.000, 32.000, 0, false [4:2]: (at 0, cp->sounds[1][0:10, 1.000, [1]0.000 -> 1.000, [2]0.000 -> 1.000, [3]0.000 -> 1.000, off: -0.032, scl: 0.032]) [buf: 11] (at 11, end_mark) ") idx = -1 test_name = "ramp+ramp+ramp+ramp" undo_edit(3) ramp_channel(0.0, 1.0) ramp_channel(0.0, 1.0) ramp_channel(0.0, 1.0) ramp_channel(0.0, 1.0) test_output.call(5, " (ramp 0 11) ; ramp_channel(0.000, 1.000, 0, false [5:2]: (at 0, cp->sounds[1][0:10, 1.000, [1]0.000 -> 1.000, [2]0.000 -> 1.000, [3]0.000 -> 1.000, [4]0.000 -> 1.000]) [buf: 11] (at 11, end_mark) ") idx = -1 test_name = "ramp+ramp+ramp+xramp" undo_edit(4) ramp_channel(0.0, 1.0) ramp_channel(0.0, 1.0) ramp_channel(0.0, 1.0) xramp_channel(0.0, 1.0, 32.0) test_output.call(5, " (ramp 0 11) ; xramp_channel(0.000, 1.000, 32.000, 0, false [5:2]: (at 0, cp->sounds[1][0:10, 1.000, [1]0.000 -> 1.000, [2]0.000 -> 1.000, [3]0.000 -> 1.000, [4]0.000 -> 1.000, off: -0.032, scl: 0.032]) [buf: 11] (at 11, end_mark) ") close_sound(ind) end def test_05_08 data = make_vct(101, 1.0) rto1_data = make_vct(101) xto1_data = make_vct(101) cos_data = make_vct(101) xe = make_env(:envelope, [0, 0, 1, 1], :length, 101, :base, 32.0) incr = PI / 101.0 ang = -0.5 * PI 101.times do |i| rto1_data[i] = i * 0.01 xto1_data[i] = env(xe) cos_data[i] = cos(ang) ang += incr end ind = new_sound("test.snd") set_to_1 = lambda do map_chan($init_channel, 0, 100) end cset_to_1 = lambda do |dat| 101.times do |i| dat[i] = 1.0 end end ramp_to_1 = lambda do ramp_channel(0.0, 1.0) end cramp_to_1 = lambda do |dat| vct_multiply!(dat, rto1_data) end scale_by_half = lambda do scale_channel(0.5) end cscale_by_half = lambda do |dat| vct_scale!(dat, 0.5) end scale_by_two = lambda do scale_channel(2.0, 30, 40) end cscale_by_two = lambda do |dat| (30...70).each do |i| dat[i] *= 2.0 end end xramp_to_1 = lambda do xramp_channel(0.0, 1.0, 32.0) end cxramp_to_1 = lambda do |dat| vct_multiply!(dat, xto1_data) end scale_mid = lambda do scale_channel(0.125, 30, 30) end cscale_mid = lambda do |dat| (30...60).each do |i| dat[i] *= 0.125 end end on_air = lambda do scale_channel(0.0, 10, 30) end con_air = lambda do |dat| (10...40).each do |i| dat[i] = 0.0 end end rev_channel2vct = lambda do len = data.length rd = make_sampler(len - 1, ind, 0, -1) dat = make_vct(len) (len - 1).downto(0) do |i| dat[i] = rd.call end free_sampler(rd) dat end if $with_test_motif edhist = channel_widgets(ind, 0)[7] edp = RXtParent(edhist) pmax = RXtVaGetValues(edp, [RXmNpaneMaximum, 0]).cadr RXtUnmanageChild(edp) RXtVaSetValues(edp, [RXmNpaneMinimum, 100]) RXtManageChild(edp) end set_squelch_update(true, ind) # 0 case set_to_1.call snd_test_neq(channel2vct, data, "0 case") snd_test_neq(rev_channel2vct.call, data, "0 rev case") # 1 case [[scale_by_two, cscale_by_two, :scale_by_two], [ramp_to_1, cramp_to_1, :ramp_to_1], [xramp_to_1, cxramp_to_1, :xramp_to_1], [scale_by_half, cscale_by_half, :scale_by_half], [scale_mid, cscale_mid, :scale_mid], [on_air, con_air, :on_air]].each do |func, check, name| revert_sound set_to_1.call cset_to_1.call(data) func.call check.call(data) snd_test_neq(channel2vct, data, "1 case %s", name) snd_test_neq(rev_channel2vct.call, data, "1 rev case %s", name) end # 2 case [[scale_by_two, cscale_by_two, :scale_by_two], [ramp_to_1, cramp_to_1, :ramp_to_1], [xramp_to_1, cxramp_to_1, :xramp_to_1], [scale_by_half, cscale_by_half, :scale_by_half], [scale_mid, cscale_mid, :scale_mid], [on_air, con_air, :on_air]].each do |func, check, name| [[scale_by_two, cscale_by_two, :scale_by_two], [ramp_to_1, cramp_to_1, :ramp_to_1], [xramp_to_1, cxramp_to_1, :xramp_to_1], [scale_by_half, cscale_by_half, :scale_by_half], [scale_mid, cscale_mid, :scale_mid], [on_air, con_air, :on_air]].each do |func1, check1, name1| revert_sound set_to_1.call cset_to_1.call(data) func.call check.call(data) func1.call check1.call(data) snd_test_neq(channel2vct, data, "2 case %s (%s)", name1, name) snd_test_neq(rev_channel2vct.call, data, "2 rev case %s (%s)", name1, name) end end # 3 case [[scale_by_two, cscale_by_two, :scale_by_two], [ramp_to_1, cramp_to_1, :ramp_to_1], [xramp_to_1, cxramp_to_1, :xramp_to_1], [scale_by_half, cscale_by_half, :scale_by_half], [scale_mid, cscale_mid, :scale_mid], [on_air, con_air, :on_air]].each do |func, check, name| [[scale_by_two, cscale_by_two, :scale_by_two], [ramp_to_1, cramp_to_1, :ramp_to_1], [xramp_to_1, cxramp_to_1, :xramp_to_1], [scale_by_half, cscale_by_half, :scale_by_half], [scale_mid, cscale_mid, :scale_mid], [on_air, con_air, :on_air]].each do |func1, check1, name1| [[scale_by_two, cscale_by_two, :scale_by_two], [ramp_to_1, cramp_to_1, :ramp_to_1], [xramp_to_1, cxramp_to_1, :xramp_to_1], [scale_by_half, cscale_by_half, :scale_by_half], [scale_mid, cscale_mid, :scale_mid], [on_air, con_air, :on_air]].each do |func2, check2, name2| revert_sound set_to_1.call cset_to_1.call(data) func.call check.call(data) func1.call check1.call(data) func2.call check2.call(data) snd_test_neq(channel2vct, data, "3 case %s (%s (%s))", name2, name1, name) snd_test_neq(rev_channel2vct.call, data, "3 rev case %s (%s (%s))", name2, name1, name) end end end if $all_args # 4 case [[scale_by_two, cscale_by_two, :scale_by_two], [ramp_to_1, cramp_to_1, :ramp_to_1], [xramp_to_1, cxramp_to_1, :xramp_to_1], [scale_by_half, cscale_by_half, :scale_by_half], [scale_mid, cscale_mid, :scale_mid], [on_air, con_air, :on_air]].each do |func, check, name| [[scale_by_two, cscale_by_two, :scale_by_two], [ramp_to_1, cramp_to_1, :ramp_to_1], [xramp_to_1, cxramp_to_1, :xramp_to_1], [scale_by_half, cscale_by_half, :scale_by_half], [scale_mid, cscale_mid, :scale_mid], [on_air, con_air, :on_air]].each do |func1, check1, name1| [[scale_by_two, cscale_by_two, :scale_by_two], [ramp_to_1, cramp_to_1, :ramp_to_1], [xramp_to_1, cxramp_to_1, :xramp_to_1], [scale_by_half, cscale_by_half, :scale_by_half], [scale_mid, cscale_mid, :scale_mid], [on_air, con_air, :on_air]].each do |func2, check2, name2| [[scale_by_two, cscale_by_two, :scale_by_two], [ramp_to_1, cramp_to_1, :ramp_to_1], [xramp_to_1, cxramp_to_1, :xramp_to_1], [scale_by_half, cscale_by_half, :scale_by_half], [scale_mid, cscale_mid, :scale_mid], [on_air, con_air, :on_air]].each do |func3, check3, name3| revert_sound set_to_1.call cset_to_1.call(data) func.call check.call(data) func1.call check1.call(data) func2.call check2.call(data) func3.call check3.call(data) snd_test_neq(channel2vct, data, "4 case %s (%s (%s (%s)))", name3, name2, name1, name) snd_test_neq(rev_channel2vct.call, data, "4 rev case %s (%s (%s (%s)))", name3, name2, name1, name) end end end end # 5 case [[scale_by_two, cscale_by_two, :scale_by_two], [ramp_to_1, cramp_to_1, :ramp_to_1], [xramp_to_1, cxramp_to_1, :xramp_to_1], [scale_by_half, cscale_by_half, :scale_by_half], [scale_mid, cscale_mid, :scale_mid], [on_air, con_air, :on_air]].each do |func, check, name| [[scale_by_two, cscale_by_two, :scale_by_two], [ramp_to_1, cramp_to_1, :ramp_to_1], [xramp_to_1, cxramp_to_1, :xramp_to_1], [scale_by_half, cscale_by_half, :scale_by_half], [scale_mid, cscale_mid, :scale_mid], [on_air, con_air, :on_air]].each do |func1, check1, name1| [[scale_by_two, cscale_by_two, :scale_by_two], [ramp_to_1, cramp_to_1, :ramp_to_1], [xramp_to_1, cxramp_to_1, :xramp_to_1], [scale_by_half, cscale_by_half, :scale_by_half], [scale_mid, cscale_mid, :scale_mid], [on_air, con_air, :on_air]].each do |func2, check2, name2| [[scale_by_two, cscale_by_two, :scale_by_two], [ramp_to_1, cramp_to_1, :ramp_to_1], [xramp_to_1, cxramp_to_1, :xramp_to_1], [scale_by_half, cscale_by_half, :scale_by_half], [scale_mid, cscale_mid, :scale_mid], [on_air, con_air, :on_air]].each do |func3, check3, name3| [[scale_by_two, cscale_by_two, :scale_by_two], [ramp_to_1, cramp_to_1, :ramp_to_1], [xramp_to_1, cxramp_to_1, :xramp_to_1], [scale_by_half, cscale_by_half, :scale_by_half], [scale_mid, cscale_mid, :scale_mid], [on_air, con_air, :on_air]].each do |func4, check4, name4| revert_sound set_to_1.call cset_to_1.call(data) func.call check.call(data) func1.call check1.call(data) func2.call check2.call(data) func3.call check3.call(data) func4.call check4.call(data) snd_test_neq(channel2vct, data, "5 case %s (%s (%s (%s (%s))))", name4, name3, name2, name1, name) snd_test_neq(rev_channel2vct.call, data, "5 rev case %s (%s (%s (%s (%s))))", name4, name3, name2, name1, name) end end end end end # 6 case [[scale_by_two, cscale_by_two, :scale_by_two], [ramp_to_1, cramp_to_1, :ramp_to_1], [xramp_to_1, cxramp_to_1, :xramp_to_1], [scale_by_half, cscale_by_half, :scale_by_half], [scale_mid, cscale_mid, :scale_mid], [on_air, con_air, :on_air]].each do |func, check, name| [[scale_by_two, cscale_by_two, :scale_by_two], [ramp_to_1, cramp_to_1, :ramp_to_1], [xramp_to_1, cxramp_to_1, :xramp_to_1], [scale_by_half, cscale_by_half, :scale_by_half], [scale_mid, cscale_mid, :scale_mid], [on_air, con_air, :on_air]].each do |func1, check1, name1| [[scale_by_two, cscale_by_two, :scale_by_two], [ramp_to_1, cramp_to_1, :ramp_to_1], [xramp_to_1, cxramp_to_1, :xramp_to_1], [scale_by_half, cscale_by_half, :scale_by_half], [scale_mid, cscale_mid, :scale_mid], [on_air, con_air, :on_air]].each do |func2, check2, name2| [[scale_by_two, cscale_by_two, :scale_by_two], [ramp_to_1, cramp_to_1, :ramp_to_1], [xramp_to_1, cxramp_to_1, :xramp_to_1], [scale_by_half, cscale_by_half, :scale_by_half], [scale_mid, cscale_mid, :scale_mid], [on_air, con_air, :on_air]].each do |func3, check3, name3| [[scale_by_two, cscale_by_two, :scale_by_two], [ramp_to_1, cramp_to_1, :ramp_to_1], [xramp_to_1, cxramp_to_1, :xramp_to_1], [scale_by_half, cscale_by_half, :scale_by_half], [scale_mid, cscale_mid, :scale_mid], [on_air, con_air, :on_air]].each do |func4, check4, name4| [[scale_by_two, cscale_by_two, :scale_by_two], [ramp_to_1, cramp_to_1, :ramp_to_1], [xramp_to_1, cxramp_to_1, :xramp_to_1], [scale_by_half, cscale_by_half, :scale_by_half], [scale_mid, cscale_mid, :scale_mid], [on_air, con_air, :on_air]].each do |func5, check5, name5| revert_sound set_to_1.call cset_to_1.call(data) func.call check.call(data) func1.call check1.call(data) func2.call check2.call(data) func3.call check3.call(data) func4.call check4.call(data) func5.call check5.call(data) snd_test_neq(channel2vct, data, "6 case %s (%s (%s (%s (%s (%s)))))", name5, name4, name3, name2, name1, name) snd_test_neq(rev_channel2vct.call, data, "6 rev case %s (%s (%s (%s (%s (%s)))))", name5, name4, name3, name2, name1, name) end end end end end end end close_sound(ind) end def test_05_09 ind = open_sound("oboe.snd") snd_test_neq(redo_edit(1, ind, 0), 0, "open redo_edit with no ops") snd_test_neq(undo_edit(1, ind, 0), 0, "open undo_edit with no ops") set_cursor(1000) delete_sample(321) snd_test_neq(cursor(), 999, "delete_sample before cursor") snd_test_neq(cursor(ind, 0, 0), 1000, "delete_sample before cursor (0)") undo_edit snd_test_neq(cursor(), 1000, "delete_sample after cursor undo") undo_edit(-1) snd_test_neq(cursor(), 999, "delete_sample before cursor redo") redo_edit(-1) delete_sample(1321) snd_test_neq(cursor(), 1000, "delete_sample after cursor") undo_edit delete_samples(0, 100) snd_test_neq(cursor(), 900, "delete_samples before cursor") undo_edit delete_samples(1100, 100) snd_test_neq(cursor(), 1000, "delete_samples after cursor") undo_edit insert_samples(100, 100, make_vct(100)) snd_test_neq(cursor(), 1100, "insert_samples before cursor") undo_edit insert_samples(1100, 100, make_vct(100)) snd_test_neq(cursor(), 1000, "insert_samples after cursor") undo_edit set_samples(0, 100, make_vct(100)) snd_test_neq(cursor(), 1000, "set_samples cursor") set_show_axes(Show_x_axis_unlabelled, ind, 0) update_time_graph set_show_axes(Show_all_axes_unlabelled, ind, 0) update_time_graph close_sound(ind) # ind = new_sound("test.snd", :size, 100) vct2channel(Vct.new(3, 1.0), 10, 8) snd_test_neq(maxamp(ind, 0), 1.0, "vct2channel size mismatch maxamp") snd_test_neq(channel2vct(0, 20, ind, 0), vct(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), "vct2channel size mismatch") revert_sound(ind) set_samples(10, 5, Vct.new(3, 1.0)) snd_test_neq(maxamp(ind, 0), 1.0, "set_samples size mismatch maxamp") snd_test_neq(channel2vct(0, 20, ind, 0), vct(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), "set_samples size mismatch") revert_sound(ind) insert_samples(10, 8, Vct.new(3, 1.0), ind, 0) snd_test_neq(maxamp(ind, 0), 1.0, "insert samples size mismatch maxamp") snd_test_neq(channel2vct(0, 20, ind, 0), vct(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), "insert samples size mismatch") close_sound(ind) end def test_05_10 ind = open_sound("oboe.snd") bnds = x_bounds(ind) xp = x_position_slider yp = y_position_slider xz = x_zoom_slider yz = y_zoom_slider snd_test_neq(snd_completion(" open-so"), " open-sound", "completion (1)") # XXX: Zoom_focus_right (constant) replaced with zoom_focus_style snd_test_neq(snd_completion(" zoom_focus_s"), " zoom_focus_style", "completion (2)") play("oboe.snd", :wait, true) play("oboe.snd", :start, 12000, :wait, true) play("oboe.snd", :start, 12000, :end, 15000, :wait, true) play(ind, :edit_position, edit_position - 1, :wait, true) old_speed = speed_control(ind) old_style = speed_control_style old_open = show_controls(ind) set_show_controls(true, ind) set_speed_control(-2.0, ind) play(ind, :start, 12345, :wait, true) set_speed_control_style(Speed_control_as_semitone) set_speed_control(0.5, ind) set_speed_control_style(Speed_control_as_ratio) set_speed_control(0.25, ind) set_speed_control(old_speed, ind) set_speed_control_style(old_style) set_show_controls(old_open, ind) k = disk_kspace("oboe.snd") if (not number?(k)) or k <= 0 snd_display("disk_kspace = %s", k) end k = disk_kspace("/baddy/hiho") snd_test_neq(k, -1, "disk_kspace of bogus file") snd_test_neq(transform_framples, 0, "transform_framples") set_transform_size(512) set_transform_graph?(true) set_time_graph?(true) # Snd.catch(:all, lambda do |*args| snd_display("axis label error: %s", args) end) do snd_test_neq(x_axis_label(), "time", "def time x_axis_label") set_x_axis_label("no time", ind, 0, Time_graph) snd_test_neq(x_axis_label(), "no time", "set time x_axis_label") update_transform_graph snd_test_neq(x_axis_label(ind, 0, Transform_graph), "frequency", "get fft x_axis_label") set_x_axis_label("hiho", ind, 0, Transform_graph) update_transform_graph snd_test_neq(x_axis_label(ind, 0, Transform_graph), "hiho", "set fft x_axis_label") set_x_axis_label("frequency", ind, 0, Transform_graph) # for later test # graph([0, 0, 1, 1, 2, 0], "lisp") update_lisp_graph snd_test_neq(x_axis_label(ind, 0, Lisp_graph), "lisp", "def lisp x_axis_label") set_x_axis_label("no lisp", ind, 0, Lisp_graph) snd_test_neq(x_axis_label(ind, 0, Lisp_graph), "no lisp", "lisp x_axis_label") # set_y_axis_label("no amp", ind, 0, Time_graph) snd_test_neq(y_axis_label(), "no amp", "time y_axis_label") set_y_axis_label("no lamp", ind, 0, Lisp_graph) snd_test_neq(y_axis_label(ind, 0, Lisp_graph), "no lamp", "lisp y_axis_label") set_y_axis_label(false) set_y_axis_label("no amp", ind, 0) snd_test_neq(y_axis_label(), "no amp", "time y_axis_label") set_y_axis_label(false, ind) end # cr = make_cairo(channel_widgets(ind, 0)[0]) graph_data(make_vct(4), ind, 0, Copy_context, false, false, Graph_lines, cr) free_cairo(cr) update_lisp_graph graph(vct(0, 0, 1, 1, 2, 0)) 32.times do graph(vct(0, 1, 2)) graph([vct(0, 1, 2), vct(3, 2, 1), vct(1, 2, 3)]) graph([vct(0, 1, 2), vct(3, 2, 1)]) end set_x_bounds([0.0, 0.01]) data = make_graph_data if vct?(data) snd_test_neq(right_sample - left_sample + 1, data.length, "make_graph_data bounds: %d %d", left_sample, right_sample) mid = (0.5 * data.length).round snd_test_neq(sample(left_sample + mid), data[mid], "make_graph_data[%d]", mid) end data = make_graph_data(ind, 0, 0, 100, 199) if vct?(data) snd_test_neq(data.length, 100, "make_graph_data 100:199") snd_test_neq(sample(50), data[50], "make_graph_data 50") end set_x_bounds([0.0, 0.1]) update_transform_graph Snd.catch(:no_such_axis, lambda do |*args| snd_display("transform axis not displayed?") end) do snd_test_neq(x_axis_label(ind, 0, Transform_graph), "frequency", "def fft x_axis_label") set_x_axis_label("fourier", ind, 0, Transform_graph) snd_test_neq(x_axis_label(ind, 0, Transform_graph), "fourier", "fft x_axis_label") set_x_axis_label("hiho") # set_y_axis_label("spectra", ind, 0, Transform_graph) snd_test_neq(y_axis_label(ind, 0, Transform_graph), "spectra", "fft y_axis_label") set_y_axis_label("hiho") end # if number?(transform_framples) and transform_framples.zero? snd_display("transform_graph? transform-framples: %s?", trandform_framples) end update_transform_graph if (tag = Snd.catch do peaks("/baddy/hiho") end).first != :cant_open_file snd_display("peaks bad file: %s", tag.inspect) end peaks("tmp.peaks") pks_data = IO.readlines("tmp.peaks") if /Snd: fft peaks/ !~ pks_data[0] snd_display("peaks 1: %s", pks_data[0].inspect) end if /fft 512 points beginning at sample 0/ !~ pks_data[2] snd_display("peaks 2: %s", pks_data[2].inspect) end delete_file("tmp.peaks") peaks() if $with_test_motif if (not dialog_widgets[15]) or (not RXtIsManaged(dialog_widgets[15])) snd_display("peaks but no help?") end end dismiss_all_dialogs num_transforms = 6 num_transform_graph_types = 3 set_transform_graph?(true, ind, 0) set_transform_size(64, ind, 0) num_transforms.times do |i| set_transform_type(integer2transform(i)) unless transform?(integer2transform(i)) snd_display("transform? %d?", i) end num_transform_graph_types.times do |j| set_transform_graph_type(j, ind, 0) update_transform_graph(ind, 0) end end set_transform_type($fourier_transform) unless (res = transform?(transform_type)) snd_display("transform? %s %s?", res, $fourier_transform) end unless transform?($autocorrelation) snd_display("transform? $autocorrelation") end if read_only(ind) snd_display("read_only open_sound: %s?", read_only(ind)) end set_read_only(true, ind) unless read_only(ind) snd_display("set_read_only: %s?", read_only(ind)) end a_ctr = 0 bind_key(key_to_int(?a), 0, lambda do a_ctr = 3 end) key(key_to_int(?a), 0) snd_test_neq(a_ctr, 3, "bind_key") unbind_key(key_to_int(?a), 0) a_ctr = 0 key(key_to_int(?a), 0) old_gstyle = graph_style 5.times do |i| psf = eps_file if string?(psf) delete_file(psf) set_graph_style(i) graph2ps unless File.exist?(psf) snd_display("graph2ps: %s?", psf) end delete_file(psf) end end set_graph_style(old_gstyle) err = Snd.catch(:cannot_print, 12345) do graph2ps("/bad/bad.eps") end if err.first != 12345 snd_display("graph2ps err: %s?", err.inspect) end n2 = open_sound("2.snd") or open_sound("4.aiff") set_transform_graph?(true, n2) [Channels_superimposed, Channels_combined, Channels_separate].each do |style| set_channel_style(style, n2) snd_test_neq(channel_style(n2), style, "channel_style") graph2ps("aaa.eps") end close_sound(n2) if channels(ind) == 1 set_channel_style(Channels_superimposed, ind) snd_test_neq(channel_style(ind), Channels_separate, "channel_style[0]") end set_sync(32, ind) snd_test_neq(sync(ind), 32, "sunc->32") if (res = sync_max()) < 32 snd_display("sync_max 32: %s?", res) end set_sync(0, ind) set_channel_sync(12, ind, 0) snd_test_neq(channel_sync(ind, 0), 12, "channel_sunc->12") set_channel_sync(0, ind, 0) snd_test_neq(a_ctr, 0, "unbind_key") snd_test_neq(xp, 0.0, "x_position_slider") snd_test_neq(yp, 0.0, "y_position_slider") if fneq(xz, 0.04338) and fneq(xz, 1.0) snd_display("x_zoom_slider: %s?", xz) end snd_test_neq(yz, 1.0, "y_zoom_slider") if (fneq(bnds[0], 0.0) or fneq(bnds[1], 0.1)) and (fneq(bnds[0], 0.0) or fneq(bnds[1], 2.305)) snd_display("x_bounds: %s?", bnds) end snd_test_neq(find_sound("oboe.snd"), ind, "oboe: index") [[:sound?, true], [:chans, 1], [:channels, 1], [:framples, 50828], [:srate, 22050], [:data_location, 28], [:data_size, 50828 * 2], [:sample_type, Mus_bshort], [:maxamp, 0.14724], [:maxamp_position, 24971], [:comment, ""]].each do |func, val| snd_test_neq(snd_func(func, ind), val, "oboe") end snd_test_neq(short_file_name(ind), "oboe.snd", "oboe: short name") snd_test_neq(count_matches(lambda do |y| y > 0.125 end), 1314, "oboe: count_matches") snd_test_neq(count_matches(lambda do |y| y > 0.1 end), 2852, "oboe: unopt count_matches") spot = find_channel(lambda do |y| y > 0.13 end) if spot.kind_of?(FalseClass) or spot != 8862 snd_display("find: %s?", spot) end set_right_sample(3000) if ((res = right_sample) - 3000).abs > 1 snd_display("right_sample: %s?", res) end set_left_sample(1000) if ((res = left_sample) - 1000).abs > 1 snd_display("left_sample: %s?", res) end eds = edits if eds[0].nonzero? or eds[1].nonzero? snd_display("edits: %s?", eds) end if edit_position != eds[0] snd_display("edit_position: %s %s?", edit_position, eds) end play(ind, :channel, 0, :wait, true) select_all(ind, 0) r0 = regions.first unless selection? snd_display("selection?") end unless region?(r0) snd_display("region?") end snd_test_neq(selection_chans, 1, "selection_chans (1)") snd_test_neq(selection_srate, srate(ind), "selection_srate") snd_test_neq(region_maxamp(r0), maxamp(ind), "region_maxamp (1)") snd_test_neq(region_maxamp_position(r0), maxamp_position(ind), "region_maxamp_position (1)") snd_test_neq(selection_maxamp(ind, 0), maxamp(ind), "selection_maxamp (1)") snd_test_neq(selection_maxamp_position(ind, 0), maxamp_position(ind), "selection_maxamp_position (1)") save_region(r0, "temp.dat") if File.exist?("temp.dat") File.unlink("temp.dat") else snd_display("save_region file disappeared?") end play(r0, :wait, true) # needs to be true here or it never gets run if Snd.regions.length != 1 snd_display("regions: %s", regions) end unless (res = selection_member?(ind)) snd_display("selection_member?: %s?", res) end [[:region_srate, 22050], [:region_chans, 1], [:region_framples, 50828], [:region_home, ["oboe.snd", 0, 50827]]].each do |func, req| snd_test_neq(snd_func(func, r0), req, "%s", func) end snd_test_neq(selection_framples, 50828, "selection_framples") snd_test_neq(selection_position, 0, "selection_position") snd_test_neq(region_position(r0, 0), 0, "region_position") snd_test_neq(region_maxamp(r0), maxamp(ind), "region_maxamp (2)") snd_test_neq(selection_maxamp(ind, 0), maxamp(ind), "selection_maxamp (2)") [[:region_srate, 22050], [:region_chans, 1], [:region_framples, 50828], [:region_maxamp, maxamp(ind)]].each do |func, req| snd_test_neq(snd_func(func, r0), req, "%s", func) end samps1 = channel2vct(0, 50827, ind, 0) samps2 = region2vct(r0, 0, 50828, 0) rd = make_sampler(0, ind, 0, 1) unless sampler?(rd) snd_display("%s not sampler?", rd) end snd_test_neq(sampler_position(rd), 0, "initial sampler_position") snd_test_neq(sampler_home(rd), [ind, 0], "sampler_home") if sampler_at_end?(rd) snd_display("%s init at end?", rd) end if (res = Snd.catch do region2vct(r0, -1, 1233) end).first != :no_such_sample snd_display("region2vct -1: %s", res.inspect) end if res = Snd.catch do region2vct(r0, 12345678, 1) end.first snd_display("region2vct 12345678: %s", res.inspect) end snd_test_neq(rd.to_s, "#", "sampler actually got %s", rd.to_s) erd = rd snd_test_neq(erd, rd, "sampler equal?") 50827.times do |i| val = (i % 2).nonzero? ? next_sample(rd) : read_sample(rd) if val != samps1[i] or val != samps2[i] snd_display("readers disagree at %s (%s %s %s)", i, val, samps1[i], samps2[i]) break end end free_sampler(rd) if (res = Snd.catch do make_sampler(0, ind, -1) end).first != :no_such_channel snd_display("make_sampler bad chan -1: %s?", res.inspect) end if (res = Snd.catch do make_sampler(0, ind, 1) end).first != :no_such_channel snd_display("make_sampler bad chan 1: %s?", res.inspect) end fd = make_sampler(0) if mix_sampler?(fd) snd_display("sampler: mix %s?", fd) end if region_sampler?(fd) snd_display("sampler: region %s?", fd) end unless sampler?(fd) snd_display("sampler: normal %s?", fd) end snd_test_neq(sampler_position(fd), 0, "sampler: position") free_sampler(fd) snd_test_neq(fd.to_s[-16, 16], "at eof or freed>", "freed sampler") reg = regions.first chns = region_chans(reg) if (res = Snd.catch do make_region_sampler(reg, 0, chans + 1) end).first != :no_such_channel snd_display("make_region_sampler bad chan (2): %s %s", res.inspect, regions) end if (res = Snd.catch do make_region_sampler(reg, 0, 0, -2) end).first != :no_such_direction snd_display("make_region_sampler bad dir (-2): %s", res.inspect) end revert_sound(ind) insert_sample(100, 0.5, ind) res = Snd.catch do insert_sound("oboe.snd", 0, 1) end if res.first != :no_such_channel snd_display("insert_sound bad chan (1): %s", res.inspect) end if (res = Snd.catch do insert_sample(-12, 1.0) end).first != :no_such_sample snd_display("insert_sample bad pos: %s", res.inspect) end set_show_axes(Show_no_axes, ind, 0) update_transform_graph(ind) update_time_graph(ind) snd_test_neq(sample(100), 0.5, "insert_sample (100)") snd_test_neq(framples(ind), 50829, "insert_sample (framples)") v0 = Array.new(3, 0.25) v1 = make_vct(3, 0.75) insert_samples(200, 3, v0, ind) insert_samples(300, 3, v1, ind) snd_test_neq(sample(201), 0.25, "insert_samples (201)") snd_test_neq(sample(301), 0.75, "insert_samples (301)") snd_test_neq(framples(ind), 50835, "insert_samples (framples)") save_sound_as("hiho.snd", ind, 22050, Mus_bshort, Mus_next) nind = view_sound("hiho.snd") snd_test_neq(sample(101, nind), sample(101, ind), "save_sound_as") unless read_only(nind) snd_display("read_only view_sound: %s?", read_only(nind)) end set_speed_control_style(Speed_control_as_semitone, nind) snd_test_neq(speed_control_style(nind), Speed_control_as_semitone, "speed_control_style set semi") set_speed_control_tones(-8, nind) snd_test_neq(speed_control_tones(nind), 12, "speed_control_tones -8") set_speed_control_tones(18, nind) snd_test_neq(speed_control_tones(nind), 18, "speed_control_tones 18") graph2ps("aaa.eps") close_sound(nind) revert_sound(ind) # set_sample(50, 0.5, ind) snd_test_neq(sample(50), 0.5, "set_sample") set_samples(60, 3, Array.new(3, 0.25), ind) snd_test_neq(sample(60), 0.25, "set_samples (60)") snd_test_neq(sample(61), 0.25, "set_samples (61)") set_samples(10, 3, [0.1, 0.2, 0.3], ind) snd_test_neq(channel2vct(10, 3, ind), vct(0.1, 0.2, 0.3), "set_samples via list") revert_sound(ind) save_sound_as("temporary.snd", ind) set_samples(100000, 20000, "temporary.snd", ind) snd_test_neq(channel2vct(110000, 10), channel2vct(10000, 10), "set_samples to self") revert_sound(ind) delete_file("temporary.snd") delete_sample(100, ind) snd_test_neq(framples(ind), 50827, "delete_sample") delete_samples(0, 100, ind) snd_test_neq(framples(ind), 50727, "delete_samples") revert_sound(ind) maxa = maxamp(ind) scale_to(0.5, ind) newmaxa = maxamp(ind) snd_test_neq(newmaxa, 0.5, "scale_to") undo_edit(1, ind) scale_by(2.0, ind) newmaxa = maxamp(ind) snd_test_neq(newmaxa, 2.0 * maxa, "scale_by") revert_sound(ind) scale_by(-1, ind) mix("oboe.snd") snd_test_neq(maxamp(ind, 0), 0.0, "invert+mix") revert_sound(ind) select_all(ind) if regions.length != 2 snd_display("regions (2): %s", regions) end scale_selection_to(0.5) newmaxa = maxamp(ind) snd_test_neq(newmaxa, 0.5, "scale_selection_to") revert_sound(ind) select_all(ind) scale_selection_by(2.0) newmaxa = maxamp(ind) snd_test_neq(newmaxa, 2.0 * maxa, "scale_selection_by") revert_sound(ind) select_all(ind) rread = make_region_sampler(regions.first, 0) sread = make_sampler(0, ind) rvect = region2vct(regions.first, 0, 100) svect = samples(0, 100, ind) snd_test_neq(region_sample(regions.first, 1), rvect[1], "region_sample") 100.times do |i| rval = next_sample(rread) sval = next_sample(sread) snd_test_neq(rval, sval, "sample_read") snd_test_neq(rval, rvect[i], "region_samples") snd_test_neq(sval, svect[i], "samples") end free_sampler(rread) val0 = next_sample(sread) if sampler_at_end?(sread) snd_display("premature end?") end previous_sample(sread) val1 = previous_sample(sread) snd_test_neq(val0, val1, "previous_sample") free_sampler(rread) revert_sound(ind) s100 = sample(100) s40 = sample(40) len = framples addlen = mus_sound_framples("fyow.snd") old_csize = cursor_size old_cstyle = cursor_style set_cursor_style(Cursor_line) set_cursor_size(25) set_cursor(50, ind) snd_test_neq(cursor_style, Cursor_line, "cursor_style") snd_test_neq(cursor_size, 25, "cursor_size") set_cursor_style(Cursor_cross) set_cursor_size(15) set_cursor(30, ind, 0) set_cursor_style(Cursor_line) set_cursor_size(20) set_cursor(20, ind, 0) if $with_test_gui set_cursor_style(lambda do |snd, chn, ax| x, y = cursor_position size = (cursor_size / 2.0).round cr = make_cairo(channel_widgets(snd, chn)[0]) draw_line(x - size, y - size, x + size, y + size, snd, chn, Cursor_context, cr) draw_line(x - size, y + size, x + size, y - size, snd, chn, Cursor_context, cr) free_cairo(cr) end, ind, 0) unless proc?(res = cursor_style(ind, 0)) snd_display("set_cursor_style to Proc: %s", res) end end set_cursor_size(old_csize) set_cursor_style(old_cstyle) set_cursor(50, ind) insert_sound("fyow.snd", cursor, 0, ind, 0) ss100 = sample(100) snd_test_neq(sample(40), s40, "insert_sound s40") snd_test_eq(ss100, s100, "insert_sound s100") snd_test_neq(ss100, 0.001831, "insert_sound") snd_test_neq(framples, addlen + len, "insert_sound len") save_sound_as("not-temporary.snd") insert_samples(0, 100, "not-temporary.snd") set_cursor(framples(ind, 0, 0) - 2, ind, 0, 0) revert_sound snd_test_neq(cursor(ind, 0), framples(ind, 0, 0) - 2, "set edpos cursor %s", cursor) delete_file("not-temporary.snd") id = make_region(0, 99) insert_region(id, 60, ind) snd_test_neq(framples, len + 100, "insert_region len") snd_test_neq(sample(100), s40, "insert_region") if (res = Snd.catch do regmax = if regions regions.map do |r| region2integer(r) end.max + 1000 else 1000 end insert_region(integer2region(regmax), 0) end).first != :no_such_region snd_display("insert_region bad id: %s", res.inspect) end save_region(id, "fmv.snd") region_srate(id) region_chans(id) region_framples(id) [[:mus_sound_header_type, Mus_next], [:mus_sound_sample_type, Mus_out_format], [:mus_sound_srate, region_srate(id)], [:mus_sound_chans, region_chans(id)], [:mus_sound_framples, region_framples(id)]].each do |func, req| snd_test_neq(snd_func(func, "fmv.snd"), req, "save_region (1) %s", func) end if region_position(id, 0).nonzero? snd_display("save_region position: %s", region_position(id, 0)) end delete_file("fmv.snd") save_region(id, "fmv.snd", Mus_lshort, Mus_riff, "this is a comment") [[:mus_sound_header_type, Mus_riff], [:mus_sound_sample_type, Mus_lshort], [:mus_sound_comment, "this is a comment"], [:mus_sound_framples, region_framples(id)]].each do |func, req| snd_test_neq(snd_func(func, "fmv.snd"), req, "save_region (2) %s", func) end delete_file("fmv.snd") save_region(id, :file, "fmv.snd", :header_type, Mus_riff, :sample_type, Mus_lshort, :comment, "this is a comment") [[:mus_sound_header_type, Mus_riff], [:mus_sound_sample_type, Mus_lshort], [:mus_sound_comment, "this is a comment"], [:mus_sound_framples, region_framples(id)]].each do |func, req| snd_test_neq(snd_func(func, "fmv.snd"), req, "save_region opt (3) %s", func) end delete_file("fmv.snd") save_region(id, :comment, "this is a comment", :file, "fmv.snd", :sample_type, Mus_lshort, :header_type, Mus_riff) [[:mus_sound_header_type, Mus_riff], [:mus_sound_sample_type, Mus_lshort], [:mus_sound_comment, "this is a comment"], [:mus_sound_framples, region_framples(id)]].each do |func, req| snd_test_neq(snd_func(func, "fmv.snd"), req, "save_region opt1 (4) %s", func) end delete_file("fmv.snd") save_region(id, "fmv.snd", :sample_type, Mus_bshort) [[:mus_sound_header_type, Mus_next], [:mus_sound_sample_type, Mus_bshort], [:mus_sound_framples, region_framples(id)]].each do |func, req| snd_test_neq(snd_func(func, "fmv.snd"), req, "save_region opt2 (5) %s", func) end delete_files("fmv.snd", "aaa.eps") close_sound(ind) end def test_05_11 res = Snd.catch do new_sound("hi.snd", :channels, 0) end if res.first != :out_of_range snd_display("new_sound bad chan: %s?", res) end # ind = new_sound("fmv.snd", 2, 22050, Mus_ldouble, Mus_next, "unequal lens") insert_silence(0, 1000, ind, 1) res1 = framples(ind, 0) res2 = framples(ind, 1) if res1 != 1 or res2 != 1001 snd_test_neq(res1, 1, "silence 1") snd_test_neq(res2, 1001, "silence 1 (1001") end save_sound(ind) if (res1 = framples(ind, 0)) != 1001 or (res2 = framples(ind, 1)) != 1001 snd_display("saved silence 1: %s %s?", res1, res2) end if (res = mus_sound_framples("fmv.snd")) != 1001 snd_display("saved framples silence 1: %s?", res) end v0 = channel2vct(0, 1000, ind, 0) v1 = channel2vct(0, 1000, ind, 1) if fneq(vct_peak(v0), 0.0) snd_display("auto-pad 0: %s?", vct_peak(v0)) end if fneq(vct_peak(v1), 0.0) snd_display("silence 0: %s?", vct_peak(v1)) end close_sound(ind) delete_file("fmv.snd") # ind = new_sound("fmv.snd", 2, 22050, Mus_bshort, Mus_next, "unequal lens") pad_channel(0, 1000, ind, 1) if (res1 = framples(ind, 0)) != 1 or (res2 = framples(ind, 1)) != 1001 snd_display("silence: %s %s?", res1, res2) end v0 = channel2vct(0, 1000, ind, 0) v1 = channel2vct(0, 1000, ind, 1) if fneq(vct_peak(v0), 0.0) snd_display("pad 0: %s?", vct_peak(v0)) end if fneq(vct_peak(v1), 0.0) snd_display("pad 1: %s?", vct_peak(v1)) end map_channel($init_channel, 0, 2, ind, 0) map_channel($init_channel, 0, 1002, ind, 1) pad_channel(0, 1000, ind, 0, 1) if (res = framples(ind, 1)) != 1002 snd_display("pad_channel ed 1: %s?", res) end close_sound(ind) delete_file("fmv.snd") # ind = new_sound("fmv.snd", 1, 22050, Mus_bshort, Mus_ircam, "this is a comment") v0 = make_vct(128) v0[64] = 0.5 v0[127] = 0.5 vct2samples(0, 128, v0, ind, 0) make_selection(0, 126) smooth_selection v0 = channel2vct(0, 128, ind, 0) if fneq(sample(127), 0.5) or fneq(sample(120), 0.4962) or fneq(sample(32), 0.07431) or fneq(sample(64), 0.25308) snd_display("smooth_selection: %s?", v0) end revert_sound(ind) vct_fill!(v0, 0.0) v0[10] = 0.5 vct2channel(v0) select_all old_sw = sinc_width set_sinc_width(40) src_selection(0.5) v0 = channel2vct(0, 128, ind, 0) if fneq(sample(20), 0.5) or fneq(sample(30), 0.0) or fneq(sample(17), -0.1057) snd_display("src_selection: %s?", v0) end unselect_all if selection_member? snd_display("unselect_all but still a selection?") end unselect_all revert_sound(ind) set_sinc_width(old_sw) vct_fill!(v0, 0.0) v0[10] = 0.5 vct2channel(v0, 0) select_all filter_selection([0, 0, 0.1, 1, 1, 0], 40) v0 = channel2vct(0, 128, ind, 0) if fneq(sample(29), 0.1945) or fneq(sample(39), -0.0137) or fneq(sample(24), -0.01986) snd_display("filter_selection: %s?", v0) end revert_sound(ind) vct_fill!(v0, 1.0) vct2channel(v0) select_all filter_selection(make_one_zero(:a0, 0.5, :a1, 0.0)) v0 = channel2vct(0, 128, ind, 0) if fneq(sample(29), 0.5) or fneq(sample(39), 0.5) or fneq(sample(24), 0.5) snd_display("filter_selection one_zero: %s?", v0) end revert_sound(ind) vct_fill!(v0, 1.0) vct2channel(v0) delete_file("fmv5.snd") select_all env_selection([0, 0, 1, 1, 2, 0], 1.0) v0 = channel2vct(0, 128, ind, 0) if fneq(sample(64), 1.0) or fneq(sample(20), 0.3125) or fneq(sample(119), 0.127) snd_display("env_selection: %s?", v0) end save_selection("fmv5.snd", 22050, Mus_bint, Mus_next, "") revert_sound(ind) # res = Snd.catch do file2array("/baddy/hiho", 0, 0, 128, v0) end if res.first != :no_such_file snd_display("file2array w/o file: %s", res.inspect) end res = Snd.catch do file2array("fmv5.snd", 123, 0, 128, v0) end if res.first != :no_such_channel snd_display("file2array w/o channel: %s", res.inspect) end file2array("fmv5.snd", 0, 0, 128, v0) if fneq(v0[64], 1.0) or fneq(v0[20], 0.3125) or fneq(v0[119], 0.127) snd_display("save_selection: %s %s %s %s?", v0[64], v0[20], v0[119], v0) end if (res = mus_sound_sample_type("fmv5.snd")) != Mus_bint snd_display("save_selection type: %s?", mus_sample_type_name(res)) end if (res = mus_sound_header_type("fmv5.snd")) != Mus_next snd_display("save_selection format: %s?", mus_header_type_name(res)) end if (res = mus_sound_srate("fmv5.snd")) != 22050 snd_display("save_selection srate: %s?", res) end vct_fill!(v0, 0.0) v0[100] = 0.5 v0[2] = -0.5 vct2channel(v0) select_all Snd.catch do reverse_selection end save_selection("fmv4.snd", 44100, Mus_lfloat, Mus_riff, "this is a comment") v0 = channel2vct(0, 128, ind, 0) if fneq(sample(27), 0.5) or fneq(sample(125), -0.5) snd_display("reverse_selection: %s?", v0) end file2array("fmv4.snd", 0, 0, 128, v0) if fneq(sample(27), 0.5) or fneq(sample(125), -0.5) snd_display("save reverse_selection: %s?", v0) end if (res = mus_sound_header_type("fmv4.snd")) != Mus_riff snd_display("save_selection type 1: %s", mus_header_type_name(res)) end if (res = mus_sound_sample_type("fmv4.snd")) != Mus_lfloat snd_display("save_selection format 1: %s", mus_sample_type_name(res)) end if (res = mus_sound_srate("fmv4.snd")) != 44100 snd_display("save_selection srate 1: %s", res) end if (res = mus_sound_comment("fmv4.snd")) != "this is a comment" snd_display("save_selection comment: %s", res) end delete_file("fmv4.snd") # save_selection(:file, "fmv4.snd", :header_type, Mus_riff, :sample_type, Mus_lfloat, :srate, 44100, :comment, "this is a comment") if (res = mus_sound_header_type("fmv4.snd")) != Mus_riff snd_display("save_selection opt type 1: %s", mus_header_type_name(res)) end if (res = mus_sound_sample_type("fmv4.snd")) != Mus_lfloat snd_display("save_selection opt format 1: %s", mus_sample_type_name(res)) end if (res = mus_sound_srate("fmv4.snd")) != 44100 snd_display("save_selection opt srate 1: %s", res) end if (res = mus_sound_comment("fmv4.snd")) != "this is a comment" snd_display("save_selection opt comment: %s", res) end delete_file("fmv4.snd") # save_selection(:file, "fmv4.snd", :sample_type, Mus_bfloat, :channel, 0) res = mus_sound_header_type("fmv4.snd") if res != Mus_next and res != Mus_ircam snd_display("save_selection opt1 type 1: %s", mus_header_type_name(res)) end if (res = mus_sound_sample_type("fmv4.snd")) != Mus_bfloat snd_display("save_selection opt1 format 1: %s", mus_sample_type_name(res)) end if (res = mus_sound_chans("fmv4.snd")) != 1 snd_display("save_selection opt1 chans: %s", res) end delete_file("fmv4.snd") revert_sound(ind) vct_fill!(v0, 0.0) v0[2] = 1.0 v1 = make_vct(256) 128.times do |i| v1[i] = v0[i] end vct2channel(v1) select_all if mus_clipping set_mus_clipping(false) end if clipping set_clipping(false) end convolve_selection_with("fmv5.snd", 0.5) v0 = channel2vct(0, 128, ind, 0) if fneq(sample(66), -0.5) snd_display("convolve_selection_with: %s %s %s?", v0[66], sample(66), v0) end close_sound(ind) delete_file("fmv.snd") end def test_05_12 obind = open_sound("oboe.snd") vol = maxamp(obind) dur = framples set_amp_control(2.0, obind) snd_test_neq(amp_control(obind), 2.0, "set_amp_control") reset_controls(obind) snd_test_neq(amp_control(obind), 1.0, "set_amp_control") set_amp_control_bounds([0.0, 4.0], obind) snd_test_neq(amp_control_bounds(obind), [0.0, 4.0], "amp_control_bounds") set_amp_control(2.0, obind) if (res = Snd.catch do apply_controls(obind) end).first == :no_such_sound snd_display("apply_controls: cannot find oboe.snd? %s", res.inspect) end newamp = maxamp(obind) if fneq_err(2.0 * vol, newamp, 0.05) snd_display("apply amp: %s -> %s?", vol, newamp) end set_amp_control_bounds([0.0, 8.0], obind) set_speed_control_bounds([1.0, 5.0], obind) snd_test_neq(speed_control_bounds(obind), [1.0, 5.0], "speed_control_bounds") set_speed_control(0.5, obind) set_speed_control_bounds([0.05, 20.0], obind) add_mark(1234) apply_controls(obind) newdur = framples(obind) set_speed_control(1.0, obind) unless newdur - 2.0 * dur < 256 snd_display("apply speed: %s -> %s?", dur, newdur) end set_contrast_control?(true, obind) set_contrast_control_bounds([0.5, 2.5], obind) snd_test_neq(contrast_control_bounds(obind), [0.5, 2.5], "contrast_control_bounds") set_contrast_control(1.0, obind) apply_controls(obind) set_contrast_control_bounds([0.0, 10.0], obind) snd_test_neq(contrast_control_bounds(obind), [0.0, 10.0], "contrast_control_bounds (2)") secamp = maxamp(obind) secdur = framples(obind) snd_test_neq(secamp, 0.989, "apply contrast") snd_test_neq(secdur, newdur, "apply contrast length") undo_edit(3, obind) set_reverb_control?(true, obind) set_reverb_control_scale_bounds([0.0, 1.0], obind) snd_test_neq(reverb_control_scale_bounds(obind), [0.0, 1.0], "reverb_control_scale_bounds") set_reverb_control_length_bounds([0.0, 2.0], obind) snd_test_neq(reverb_control_length_bounds(obind), [0.0, 2.0], "reverb_control_length_bounds") set_reverb_control_scale(0.2, obind) apply_controls(obind) revamp = maxamp(obind) revdur = framples(obind) snd_test_any_neq(revamp, 0.214, :ffequal?, "apply reverb scale") unless revdur - ((reverb_control_decay * 22050.0).round + 50828) < 256 snd_display("apply reverb length: %s?", revdur) end undo_edit(1, obind) set_expand_control?(true, obind) set_expand_control_bounds([1.0, 3.0], obind) snd_test_neq(expand_control_bounds(obind), [1.0, 3.0], "expand_control_bounds") set_expand_control(1.5, obind) apply_controls(obind) expamp = maxamp(obind) expdur = framples(obind) if fneq_err(expamp, 0.152, 0.05) snd_display("apply expand_control scale: %s?", expamp) end if expdur <= 1.25 * 50828 snd_display("apply expand_control length: %s?", expdur) end set_expand_control_bounds([0.001, 20.0], obind) undo_edit(1, obind) set_filter_control?(true, obind) set_filter_control_order(40, obind) set_filter_control_envelope([0.0, 0.0, 1.0, 0.5, 2.0, 0.0], obind) apply_controls(obind) fltamp = maxamp(obind) fltdur = framples(obind) snd_test_gt((fltamp - 0.02).abs, 0.005, "apply filter scale") snd_test_gt(fltdur - (40 + 50828), 256, "apply filter length") undo_edit(1, obind) # revert_sound(obind) make_selection(1000, 1000) scale_selection_to(0.1) scale_selection_by(2.0) make_selection(2000, 2001) scale_selection_by(2.0) scale_selection_to(0.5) make_selection(1000, 2001) scale_selection_to(0.5) scale_selection_by(0.5) make_selection(2000, 2000) scale_selection_by(2.0) scale_selection_to(0.5) make_selection(1000, 1001) scale_selection_to(0.1) scale_selection_by(2.0) make_selection(999, 2002) scale_selection_to(1.0) scale_selection_by(0.5) tree = edit_tree tr_tree = [[0, 0, 0, 998, 1.0, 0.0, 0.0, 0], [999, 0, 999, 999, 0.999969720840454, 0.0, 0.0, 0], [1000, 0, 1000, 1000, 6.09052181243896, 0.0, 0.0, 0], [1001, 0, 1001, 1001, 0.999969720840454, 0.0, 0.0, 0], [1002, 0, 1002, 1999, 0.499984979629517, 0.0, 0.0, 0], [2000, 0, 2000, 2000, 7.54652404785156, 0.0, 0.0, 0], [2001, 0, 2001, 2001, 3.7732629776001, 0.0, 0.0, 0], [2002, 0, 2002, 2002, 0.999969720840454, 0.0, 0.0, 0], [2003, 0, 2003, 50827, 1.0, 0.0, 0.0, 0], [50828, -2, 0, 0, 0.0, 0.0, 0.0, 0]] unless snd_test_neq(tree.length, tr_tree.length, "edit trees are not same length") tree.each_with_index do |branch, i| tr_branch = tr_tree[i] 5.times do |j| snd_test_neq(branch[j], tr_branch[j], "edit trees disagree at [%d][%d]", i, j) end end end insert_silence(1001, 8) insert_silence(900, 50) insert_silence(2005, 1) insert_silence(999, 2) tree = edit_tree tr_tree = [[0, 0, 0, 899, 1.0, 0.0, 0.0, 0], [900, -1, 0, 49, 0.0, 0.0, 0.0, 0], [950, 0, 900, 948, 1.0, 0.0, 0.0, 0], [999, -1, 0, 1, 0.0, 0.0, 0.0, 0], [1001, 0, 949, 998, 1.0, 0.0, 0.0, 0], [1051, 0, 999, 999, 0.999969720840454, 0.0, 0.0, 0], [1052, 0, 1000, 1000, 6.09052181243896, 0.0, 0.0, 0], [1053, -1, 0, 7, 0.0, 0.0, 0.0, 0], [1061, 0, 1001, 1001, 0.999969720840454, 0.0, 0.0, 0], [1062, 0, 1002, 1946, 0.499984979629517, 0.0, 0.0, 0], [2007, -1, 0, 0, 0.0, 0.0, 0.0, 0], [2008, 0, 1947, 1999, 0.499984979629517, 0.0, 0.0, 0], [2061, 0, 2000, 2000, 7.54652404785156, 0.0, 0.0, 0], [2062, 0, 2001, 2001, 3.7732629776001, 0.0, 0.0, 0], [2063, 0, 2002, 2002, 0.999969720840454, 0.0, 0.0, 0], [2064, 0, 2003, 50827, 1.0, 0.0, 0.0, 0], [50889, -2, 0, 0, 0.0, 0.0, 0.0, 0]] unless snd_test_neq(tree.length, tr_tree.length, "silenced edit trees are not same length") tree.each_with_index do |branch, i| tr_branch = tr_tree[i] 5.times do |j| snd_test_neq(branch[j], tr_branch[j], "silenced edit trees disagree at [%d][%d]", i, j) end end end snd_test_neq(vct(sample(998), sample(999), sample(1000), sample(1001)), vct(-0.03, 0.0, 0.0, -0.03), "insert_silence [999 for 2]") snd_test_neq(vct(sample(2006), sample(2007), sample(2008)), vct(-0.033, 0.0, -0.033), "insert_silence [2007 for 1]") revert_sound(obind) add_mark(1200, obind, 0) mark_num = marks(obind, 0).length scale_by(2.0, obind, 0) mark_now = marks(obind, 0).length snd_test_neq(mark_num, mark_now, "mark lost after scaling") set_selection_position(0) set_selection_framples(100) scale_selection_to(0.5) mark_now = marks(obind, 0).length snd_test_neq(mark_num, mark_now, "mark lost after scaling scaling") m1 = add_mark(1000) set_cursor(100, obind, 0) key(key_to_int(?u), 4, obind) key(key_to_int(?1), 0, obind) key(key_to_int(?0), 0, obind) key(key_to_int(?0), 0, obind) key(key_to_int(?o), 4, obind) snd_test_neq(mark_sample(m1), 1100, "mark after zeros") set_cursor(0, obind) key(key_to_int(?j), 4, obind) snd_test_neq(cursor(obind), 1100, "C-j") add_mark(100) set_cursor(0, obind) key(key_to_int(?u), 4, obind) key(key_to_int(?2), 0, obind) key(key_to_int(?j), 4, obind) snd_test_neq(cursor(obind), 1100, "C-u 2 C-j") key(key_to_int(?-), 4, obind) key(key_to_int(?j), 4, obind) snd_test_neq(cursor(obind), 100, "C-- C-j") revert_sound(obind) frs = framples(obind) make_region(0, 999, obind, 0) unless selection? snd_display("make_region but no selection? %s", selection?) end delete_selection snd_test_neq(framples(obind), frs - 1000, "delete_selection") val = sample(0, obind, 0) undo_edit snd_test_neq(sample(1000), val, "delete_selection val") insert_selection res = Snd.catch do insert_selection(0, obind, 123) end if res.first != :no_such_channel snd_display("insert_selection bad chan: %s?", res.inspect) end res = Snd.catch do mix_selection(0, obind, 123) end if res.first != :no_such_channel snd_display("mix_selection bad chan: %s?", res.inspect) end snd_test_neq(framples(obind), frs + 1000, "insert_selection") snd_test_neq(sample(2000), val, "insert_selection val") val = sample(900) mix_selection snd_test_neq(sample(900), val * 2.0, "mix_selection val") snd_test_neq(framples(obind), frs + 1000, "mix_selection len") close_sound(obind) end Apply_to_sound, Apply_to_channel, Apply_to_selection = [0, 1, 2] def test_05_13 ind = open_sound("2.snd") len = framples(ind) len2 = len * 2 len4 = len * 4 set_sync(1, ind) set_speed_control(0.5, ind) apply_controls(ind, Apply_to_sound) # temp 1 snd_test_gt((framples() - len2).abs, 256, "apply srate 0.5") make_selection(0, framples()) set_speed_control(0.5, ind) apply_controls(ind, Apply_to_selection) # temp 2 snd_test_gt((framples() - len4).abs, 256, "apply srate 0.5 to selection") env_sound([0, 0, 1, 1], 0, framples(), 32.0) # temp 3 reg = select_all() # make multi_channel region insert_region(reg, 0) # temp 4 insert_selection(0) # temp 5 revert_sound(ind) # set_speed_control(0.5) set_sync(0, ind) set_selected_channel(ind, 1) apply_controls(ind, Apply_to_channel) snd_test_gt((framples(ind, 1) - len2).abs, 256, "apply srate 0.5 to chan 1") snd_test_neq(framples(ind, 0), len, "apply srate 0.5 but chan 0") set_speed_control(0.5, ind) apply_controls(ind, Apply_to_sound, 1000) make_selection(2000, 4000) set_speed_control(0.5, ind) apply_controls(ind, Apply_to_selection) set_selected_channel(ind, false) snd_test_neq(selected_channel(ind), false, "selected_channel false") close_sound(ind) # ind1 = open_sound("oboe.snd") mx1 = maxamp(ind1, 0) ind2 = open_sound("2.snd") mx20 = maxamp(ind2, 0) mx21 = maxamp(ind2, 1) select_sound(ind1) scale_sound_by(2.0) snd_test_neq(maxamp(ind1, 0), 2.0 * mx1, "scale_sound_by 2.0") res = edit_fragment(1, ind1, 0) req = ["scale_channel(2.000, 0, false", "scale", 0, 50828] snd_test_neq(res, req, "scale_sound_by") scale_sound_to(0.5) snd_test_neq(maxamp(ind1, 0), 0.5, "scale_sound_to 0.5") res = edit_fragment(2, ind1, 0) req = ["scale_channel(1.698, 0, false", "scale", 0, 50828] snd_test_neq(res, req, "scale_sound_to") scale_sound_by(0.0, 0, 1000, ind1, 0) snd_test_neq(maxamp(ind1, 0), 0.5, "scale_sound_by 0.0") res = edit_fragment(3, ind1, 0) req = ["scale_channel(0.000, 0, 1000", "scale", 0, 1000] snd_test_neq(res, req, "scale_sound_by 0.0") res = channel2vct(0, 1000, ind1, 0).peak snd_test_neq(res, 0.0, "0:0 scale_sound_by 0.0 [0:1000]") revert_sound(ind1) oldv = channel2vct(12000, 10, ind1, 0) scale_sound_by(2.0, 12000, 10, ind1, 0) newv = channel2vct(12000, 10, ind1, 0) 10.times do |i| snd_test_neq(oldv[i] * 2.0, newv[i], "scale %d", i) end res = edit_fragment(1, ind1, 0) req = ["scale_channel(2.000, 12000, 10", "scale", 12000, 10] snd_test_neq(res, req, "scale_sound_by 2.0 [12000:10]") revert_sound(ind1) # select_sound(ind2) scale_sound_by(2.0) snd_test_neq(maxamp(ind2, 0), 2.0 * mx20, "2:0 scale_sound_by 2.0") snd_test_neq(maxamp(ind2, 1), 2.0 * mx21, "2:1 scale_sound_by 2.0") scale_sound_to(0.5) res = [maxamp(ind2, 0), maxamp(ind2, 1)].max snd_test_neq(res, 0.5, "2 scale_sound_to 0.5") scale_sound_by(0.0, 0, 1000, ind2, 1) res = edit_fragment(3, ind2, 1) req = ["scale_channel(0.000, 0, 1000", "scale", 0, 1000] snd_test_neq(res, req, "2:1 scale_sound_by 0.0") res = channel2vct(0, 1000, ind2, 1).peak snd_test_neq(res, 0.0, "2:1 scale_sound_by 0.0 [0:1000]") revert_sound(ind2) oldv = channel2vct(12000, 10, ind2, 0) scale_sound_by(2.0, 12000, 10, ind2, 0) newv = channel2vct(12000, 10, ind2, 0) 10.times do |i| snd_test_neq(oldv[i] * 2.0, newv[i], "2 scale %d", i) end revert_sound(ind2) # set_sync(3, ind2) set_sync(3, ind1) scale_sound_by(2.0) snd_test_neq(maxamp(ind1, 0), mx1, "sync scale_sound_by 2.0") snd_test_neq(maxamp(ind2, 0), 2.0 * mx20, "2:0 sync scale_sound_by 2.0") snd_test_neq(maxamp(ind2, 1), 2.0 * mx21, "2:1 sync scale_sound_by 2.0") scale_sound_to(1.0, 20000, 40000, ind2, 1) snd_test_neq(maxamp(ind1, 0), mx1, "sync scale_sound_to 1.0") snd_test_neq(maxamp(ind2, 0), 2.0 * mx20, "2:0 sync scale_sound_to 1.0") snd_test_neq(maxamp(ind2, 1), 1.0, "2:1 sync scale_sound_to 1.0") close_sound(ind1) close_sound(ind2) end def test_05_14 ind = open_sound("now.snd") unless $snd_opened_sound.eql?(ind) snd_display("$snd_opened_sound: %s %s?", $snd_opened_sound, ind) end set_amp_control(0.5, ind) if fneq(res = amp_control(ind), 0.5) snd_display("amp_control (0.5): %s?", res) end set_amp_control(0.25, ind, 0) if fneq(res = amp_control(ind), 0.5) snd_display("amp_control after local set (0.5): %s?", res) end if fneq(res = amp_control(ind, 0), 0.25) snd_display("amp_control 0 (0.25): %s?", res) end set_amp_control(1.0, ind) if fneq(res = amp_control(ind), 1.0) snd_display("amp_control after local set (1.0): %s?", res) end if fneq(res = amp_control(ind, 0), 0.25) snd_display("amp_control 0 after set (0.25): %s?", res) end # set_transform_graph?(true, ind, 0) set_transform_graph_type(Graph_as_sonogram, ind, 0) update_transform_graph(ind, 0) res = transform_framples(ind, 0) if (not list?(res)) or fneq(res.car, 1.0) or res.caddr != 256 snd_display("transform_framples: %s (%s)?", res.inspect, transform_size(ind, 0)) end close_sound(ind) # ind = open_sound("4.aiff") if fneq(res = amp_control(ind), 1.0) snd_display("amp_control upon open (1.0): %s?", res) end if fneq(res = amp_control(ind, 2), 1.0) snd_display("amp_control 2 upon open (1.0): %s?", res) end set_amp_control(0.5, ind) if fneq(res = amp_control(ind, 2), 0.5) snd_display("amp_control 2 after global set (0.5): %s?", res) end set_amp_control(0.25, ind, 2) if fneq(res = amp_control(ind, 2), 0.25) snd_display("amp_control 2 (0.25): %s?", res) end after_ran = false $after_apply_controls_hook.reset_hook! $after_apply_controls_hook.add_hook!("snd-test") do |snd| after_ran = snd end apply_controls(ind) unless ind.eql?(after_ran) snd_display("$after_apply_controls_hook: %s?", after_ran) end $after_apply_controls_hook.reset_hook! revert_sound(ind) set_sync(1, ind) scale_to(vct(0.1, 0.2)) mx = maxamp(ind, true) if fneq(mx[0], 0.1) or fneq(mx[1], 0.2) or fneq(mx[2], 0.2) or fneq(mx[3], 0.2) snd_display("scale_to with vector: %s?", mx) end set_filter_control_envelope([0, 0, 1, 1], ind) if [0.0, 0.0, 1.0, 1.0] != filter_control_envelope(ind) snd_display("set_filter_control_envelope: %s?", filter_control_envelope(ind)) end set_filter_control_order(20, ind) unless vequal(res = filter_control_coeffs(ind), vct(-0.007, 0.010, -0.025, 0.029, -0.050, 0.055, -0.096, 0.109, -0.268, 0.241, 0.241, -0.268, 0.109, -0.096, 0.055, -0.050, 0.029, -0.025, 0.010, -0.007)) snd_display("highpass coeffs: %s?", res) end set_filter_control_envelope(filter_control_envelope(ind), ind) if [0.0, 0.0, 1.0, 1.0] != filter_control_envelope(ind) snd_display("set_filter_control_envelope to self: %s?", filter_control_envelope(ind)) end set_filter_control_envelope([0, 1, 1, 0], ind) unless vequal(res = filter_control_coeffs(ind), vct(0.003, 0.002, 0.004, 0.002, 0.007, 0.003, 0.014, 0.012, 0.059, 0.394, 0.394, 0.059, 0.012, 0.014, 0.003, 0.007, 0.002, 0.004, 0.002, 0.003)) snd_display("lowpass coeffs: %s?", res) end close_sound(ind) end def test_05_15 obind = open_sound("4.aiff") amps = maxamp(obind, true) snd_test_neq(maxamp_position(obind, true), [810071, 810071, 810071, 810071], "4.aiff times") if window_width < 600 set_window_width(600) end if window_height < 600 set_window_height(600) end set_x_bounds([0.0, 0.1], obind, 0) set_show_axes(Show_x_axis, obind, 0) update_time_graph set_amp_control(0.1, obind) select_channel(2) res = Snd.catch do apply_controls(obind, 1) end if res.first == :no_such_sound snd_display("apply_controls cannot find 4.aiff: %s?", res.inspect) end newamps = maxamp(obind, true) if fneq(amps[0], newamps[0]) or fneq(amps[1], newamps[1]) or fneq_err(0.1 * amps[2], newamps[2], 0.05) or fneq(amps[3], newamps[3]) snd_display(snd_format_neq(newamps, amps, "apply amps")) end undo_edit(1, obind, 2) set_amp_control(0.1, obind) make_region(0, framples(obind), obind, 1) Snd.catch do apply_controls(obind, 2) end newamps = maxamp(obind, true) if fneq(amps[0], newamps[0]) or fneq_err(0.1 * amps[1], newamps[1], 0.05) or fneq(amps[2], newamps[2]) or fneq(amps[3], newamps[3]) snd_display(snd_format_neq(newamps, amps, "apply selection amps")) end # if $with_test_gui axinfo = axis_info(obind, 0, Time_graph) losamp, hisamp, x0, y0, x1, y1 = axinfo[0, 6] xpos = x0 + 0.5 * (x1 - x0.to_f) ypos = y0 + 0.75 * (y1 - y0.to_f) select_channel(0) set_cursor(100, obind) xy = cursor_position(obind) snd_test_neq(position2x(xy[0]), cursor(obind).to_f / srate(obind), "cursor_position %s", xy[0]) snd_test_neq(position2x(x2position(xpos)), xpos, "x<->position") if ((res = position2y(y2position(ypos))) - ypos).abs > 0.5 snd_display(snd_format(res, ypos, "y<->position")) end snd_test_neq(left_sample(obind, 0), losamp, "axis_info[0 losamp]") snd_test_neq(right_sample(obind, 0), hisamp, "axis_info[1 hisamp]") snd_test_neq(axinfo[6], 0.0, "axis_info[6 xmin]") snd_test_neq(axinfo[7], -1.0, "axis_info[7 ymin]") snd_test_neq(axinfo[9], 1.0, "axis_info[9 ymax]") res = our_x2position(obind, x0) if (res[0] - res[1]).abs > 1 snd_display(snd_format_neq(res[0], res[1], "x0->position")) end res = our_x2position(obind, x1) if (res[0] - res[1]).abs > 1 snd_display(snd_format_neq(res[0], res[1], "x1->position")) end res = our_x2position(obind, 0.5 * (x0 + x1)) if (res[0] - res[1]).abs > 1 snd_display(snd_format_neq(res[0], res[1], "xmid->position")) end if $clmtest.zero? cp_x = lambda do |x| (axinfo[10] + ((x - x0.to_f) * ((axinfo[12] - axinfo[10].to_f) / (x1 - x0.to_f)))).floor end cp_y = lambda do |y| (axinfo[13] + ((y1.to_f - y) * ((axinfo[11] - axinfo[13].to_f) / (y1 - y0.to_f)))).floor end if ((res1 = x2position(xpos)) - (res2 = cp_x.call(xpos))).abs > 1 snd_display(snd_format_neq(res2, res1, "cp_x 0.5")) end if ((res1 = y2position(ypos)) - (res2 = cp_y.call(ypos))).abs > 1 snd_display(snd_format_neq(res2, res1, "cp_y 0.75")) end 10.times do |i| xxpos = x0 + random(x1 - x0) yypos = y0 + random(y1 - y0) if ((res1 = x2position(xxpos)) - (res2 = cp_x.call(xxpos))).abs > 1 snd_display(snd_format_neq(res2, res1, "cp_x[%d] %1.4f", i, xxpos)) end if ((res1 = y2position(yypos)) - (res2 = cp_y.call(yypos))).abs > 1 snd_display(snd_format_neq(res2, res1, "cp_y[%d] %1.4f", i, yypos)) end snd_test_neq(position2x(cp_x.call(xxpos)), xxpos, "x2position cp_x[%d]", i) snd_test_any_neq(position2y(cp_y.call(yypos)), yypos, :fffequal?, "y2position cp_y[%d]", i) end end old_samp = left_sample(obind, 0) set_left_sample(1234, obind, 0) snd_test_neq(axis_info(obind, 0)[0], 1234, "axis_info[0 losamp at 1234]") set_left_sample(old_samp, obind, 0) axinfo = axis_info(obind, 0) x0 = axinfo[2] x1 = axinfo[4] res = our_x2position(obind, x0) if (res[0] - res[1]).abs > 1 snd_display("x0a->position: %s?", res) end res = our_x2position(obind, x1) if (res[0] - res[1]).abs > 1 snd_display("x1a->position: %s?", res) end res = our_x2position(obind, 0.5 * (x0 + x1)) if (res[0] - res[1]).abs > 1 snd_display("xmida->position: %s?", res) end set_y_bounds([-2.0, 3.0], obind, 0) snd_test_neq(axis_info(obind, 0)[7], -2.0, "axis_info[7 ymin]") snd_test_neq(axis_info(obind, 0)[9], 3.0, "axis_info[9 ymax]") end # close_sound(obind) end def test_05_16 ind1 = open_sound("oboe.snd") test_orig(lambda { |snd| src_sound(2.0, 1.0, snd) }, lambda { |snd| src_sound(0.5, 1.0, snd) }, "src_sound(2.0, 1.0, snd)", ind1) test_orig(lambda { |snd| src_channel(2.0) }, lambda { |snd| src_channel(0.5) }, "src_channel(2.5)", ind1) test_orig(lambda { |snd| scale_by(2.0, snd) }, lambda { |snd| scale_by(0.5, snd) }, "scale_by(2.0, snd)", ind1) test_orig(lambda { |snd| scale_channel(2.0) }, lambda { |snd| scale_channel(0.5) }, "scale_channel(2.0)", ind1) test_orig(lambda { |snd| reverse_sound(snd) }, lambda { |snd| reverse_sound(snd) }, "reverse_sound(snd)", ind1) test_orig(lambda { |snd| reverse_channel() }, lambda { |snd| reverse_channel() }, "reverse_channel()", ind1) test_orig(lambda { |snd| env_sound([0, 1.0, 1, 2.0]) }, lambda { |snd| env_sound([0, 1.0, 1, 0.5]) }, "env_sound([0, 1.0, 1, 2.0])", ind1) test_orig(lambda { |snd| env_sound([0, 1.0, 1, 2.0, 2, 1.0]) }, lambda { |snd| env_sound([0, 1.0, 1, 0.5, 2, 1.0]) }, "env_sound([0, 1.0, 1, 2.0, 2, 1.0])", ind1) test_orig(lambda { |snd| env_channel(make_env([0, 1.0, 1, 2.0], :length, framples(snd))) }, lambda { |snd| env_channel(make_env([[0, 1.0], [1, 0.5]], :length, framples(snd))) }, "env_channel(make_env([0, 1.0, 1, 2.0]))", ind1) test_orig(lambda { |snd| env_channel([0, 1.0, 1, 2.0]) }, lambda { |snd| env_channel([0, 1.0, 1, 0.5]) }, "env_channel([0, 1.0, 1, 2.0])", ind1) test_orig(lambda { |snd| env_channel(make_env([0, 2, 1, 2, 2, 0.5, 3, 0.5], :base, 0, :length, framples(snd))) }, lambda { |snd| env_channel(make_env([0, 0.5, 1, 0.5, 2, 2, 3, 2], :base, 0, :length, framples(snd))) }, "env_channel(make_env([0, 2, 1, 2, 2, 0.5, 3, 0.5]))", ind1) test_orig(lambda { |snd| map_channel(lambda { |y| y * 2.0 }) }, lambda { |snd| map_channel(lambda { |y| y * 0.5 }) }, "map_channel(lambda { |y| y * 2.0 })", ind1) test_orig(lambda { |snd| map_channel(lambda { |y| y * 2.0 }, 1234) }, lambda { |snd| map_channel(lambda { |y| y * 0.5 }, 1234) }, "map_channel(lambda { |y| y * 2.0 }, 1234)", ind1) test_orig(lambda { |snd| map_channel(lambda { |y| y * 2.0 }, 12005, 10) }, lambda { |snd| map_channel(lambda { |y| y * 0.5 }, 12005, 10) }, "map_channel(lambda { |y| y * 2.0 }, 12005, 10)", ind1) outp = false test_orig(lambda { |snd| map_channel(lambda { |y| vct(y * 2.0, y * 2.0) }) }, lambda { |snd| map_channel(lambda { |y| outp = (outp ? false : y * 0.5) }) }, "map_channel(lambda { |y| vct(y * 2.0, y * 2.0) })", ind1) test_orig(lambda { |snd| map_chan(lambda { |y| y * 2.0 }) }, lambda { |snd| map_chan(lambda { |y| y * 0.5 }) }, "map_chan(lambda { |y| y * 2.0 })", ind1) test_orig(lambda { |snd| pad_channel(1000, 2000, snd) }, lambda { |snd| delete_samples(1000, 2000, snd) }, "pad_channel(1000, 2000, snd)", ind1) test_orig(lambda { |snd| clm_channel(make_one_zero(:a0, 2.0, :a1, 0.0)) }, lambda { |snd| clm_channel(make_one_zero(:a0, 0.5, :a1, 0.0)) }, "clm_channel(make_one_zero)", ind1) test_orig(lambda { |snd| clm_channel(make_one_pole(:a0, 2.0, :b1, 0.0)) }, lambda { |snd| clm_channel(make_one_pole(:a0, 0.5, :b1, 0.0)) }, "clm_channel(make_one_pole)", ind1) test_orig(lambda { |snd| filter_sound(make_one_zero(:a0, 2.0, :a1, 0.0), 2, snd, 0) }, lambda { |snd| filter_sound(make_one_zero(:a0, 0.5, :a1, 0.0), 2, snd, 0) }, "filter_sound(make_one_zero)", ind1) if (res = Snd.catch do src_sound([0, 0, 1, 1]) end).first != :out_of_range snd_display("src_sound env at 0: %s", res.inspect) end if (res = Snd.catch do src_sound([0, 1, 1, -1]) end).first != :out_of_range snd_display("src_sound env through 0: %s", res.inspect) end # scale_to(1.0, ind1) v0 = make_vct(10) v1 = channel2vct(12000, 10, ind1, 0) v0[0] = 1.0 array2file("fmv3.snd", v0, 10, 22050, 1) file_copy("oboe.snd", "fmv4.snd") convolve_with("fmv3.snd", 1.0, ind1) convolve_files("fmv4.snd", "fmv3.snd", 1.0, "fmv5.snd") v2 = channel2vct(12000, 10, ind1, 0) snd_test_any_neq(v2, v1, :vfequal?, "convolve_with (orig 0)") file2array("fmv5.snd", 0, 12000, 10, v2) snd_test_any_neq(v2, v1, :vfequal?, "convolve_files (orig 0)") delete_files("fmv3.snd", "fmv5.snd") convolve_files("2.snd", "oboe.snd", 0.5, "fmv5.snd") res = mus_sound_maxamp("fmv5.snd") snd_test_neq(res[1], 0.25, "convolve_files stereo (1)") snd_test_neq(res[3], 0.50, "convolve_files stereo (2)") delete_file("fmv5.snd") scale_to(0.25, ind1) set_y_bounds([], ind1) if $with_test_gui snd_test_neq(y_bounds(ind1), [-0.25, 0.25], "y_bounds []") end revert_sound(ind1) # scale_to(1.0, ind1) v0 = make_vct(10) v1 = channel2vct(12000, 10, ind1, 0) v0[5] = 1.0 array2file("fmv3.snd", v0, 10, 22050, 1) convolve_with("fmv3.snd", 1.0, ind1) convolve_files("fmv4.snd", "fmv3.snd", 1.0, "fmv5.snd") v2 = channel2vct(12005, 10, ind1, 0) snd_test_any_neq(v2, v1, :vfequal?, "convolve_with (orig 2)") file2array("fmv5.snd", 0, 12005, 10, v2) snd_test_any_neq(v2, v1, :vfequal?, "convolve_files (orig 2)") delete_files("fmv3.snd", "fmv4.snd", "fmv5.snd") revert_sound(ind1) # old_val = selection_creates_region old_regions = regions set_selection_creates_region(false) select_all(ind1) set_selection_creates_region(old_val) unless old_regions.eql?(regions) snd_display("selection_creates_region: %s -> %s", old_regions, regions) end convolve_selection_with("pistol.snd", maxamp) data = channel2vct(12000, 10, ind1, 0) convolve_with("pistol.snd", maxamp(ind1, 0, 0), ind1, 0, 0) new_data = channel2vct(12000, 10, ind1, 0) snd_test_any_neq(new_data, data, :vfequal?, "convolve_selection_with") revert_sound(ind1) # make_selection(1000, 2000, ind1) ma = maxamp(ind1) convolve_selection_with("pistol.snd", ma) if fneq(maxamp(ind1), ma) snd_display("convolve_selection_with 1000: %s %s?", ma, maxamp(ind1)) end make_selection(1000, 2000, ind1) id = make_region unless region?(id) snd_display("make_region argless: %s?", id) end if (res1 = region_framples(id, 0)) != (res2 = selection_framples) snd_display("region/selection_framples: %s %s (%s)?", res1, res2, region_framples(id)) end if (res1 = region_sample(id, 0)) != (res2 = sample(1000, ind1)) snd_display("region_sample from make_region: %s %s?", res1, res2) end close_sound(ind1) end def test_05_17 ind = open_sound("2.snd") reg = make_region(0, 100, ind, true) if (res = region_home(reg)) != ["2.snd", 0, 100] snd_display("make + region_home: %s?", res) end if (res = region_chans(reg)) != 2 snd_display("make_region chan true: %s", res) end close_sound(ind) # ind = open_sound("2.snd") v0 = channel2vct(12000, 10, ind, 0) v1 = channel2vct(12000, 10, ind, 1) swap_channels(ind) v2 = channel2vct(12000, 10, ind, 0) v3 = channel2vct(12000, 10, ind, 1) if vequal(v0, v2) or vequal(v1, v3) snd_display("swap_channels 0: no change!\n# %s\n# %s\n# %s\n# %s", v0, v2, v1, v3) end swap_channels(ind) v2 = channel2vct(12000, 10, ind, 0) v3 = channel2vct(12000, 10, ind, 1) unless vequal(v0, v2) or vequal(v1, v3) snd_display("swap_channels 1: \n# %s\n# %s\n# %s\n# %s", v0, v2, v1, v3) end set_cursor(100, ind, 0) set_cursor(200, ind, 1) if (res0 = cursor(ind, 0)) != 100 or (res1 = cursor(ind, 1)) != 200 snd_display("cursor: %s %s?", res0, res1) end set_sync(1, ind) scale_by([0.5, 0.25], ind) scale_by(vct(2.0, 4.0), ind) revert_sound(ind) amps = maxamp(ind, true) swap_channels(ind, 0, ind) newamps = maxamp(ind, true) if fneq(amps[0], newamps[1]) or fneq(amps[1], newamps[0]) snd_display("swap_channels with cp def: %s %s?", amps, newamps) end swap_channels(ind, 1) newamps = maxamp(ind, true) if fneq(amps[0], newamps[0]) or fneq(amps[1], newamps[1]) snd_display("swap_channels with cp def 0: %s %s?", amps, newamps) end close_sound(ind) end def test_05_18 ind1 = open_sound("oboe.snd") ind2 = open_sound("2.snd") ups1 = count_matches(lambda do |n| n > 0.1 end, 0, ind1, 0) count = 0 reader = make_sampler(0, ind1) framples(ind1).times do |i| if next_sample(reader) > 0.1 count += 1 end end ups2 = count if ups1 != ups2 snd_display("scan_chan: %s %s?", ups1, ups2) end ups1 = count_matches(lambda do |n| n > 0.03 end, 0, ind2, 0) ups2 = count_matches(lambda do |n| n > 0.03 end, 0, ind2, 1) count = 0 reader = make_sampler(0, ind2, 0) framples(ind2).times do |i| if next_sample(reader) > 0.03 count += 1 end end ups3 = count count = 0 reader = make_sampler(0, ind2, 1) framples(ind2).times do |i| if next_sample(reader) > 0.03 count += 1 end end ups4 = count if ups1 != ups3 snd_display("2[0] scan_chan: %s %s?", ups1, ups3) end if ups2 != ups4 snd_display("2[1] scan_chan: %s %s?", ups2, ups4) end set_sync(true, ind2) count = 0 scan_chans do |n| if n > 0.03 count += 1 end false end total = count if total != ups1 + ups2 snd_display("scan_chans: %s %s?", total, ups1 + ups2) end set_sync(false, ind2) count = 0 scan_sound_chans(0, framples(ind2), ind2) do |n| if n > 0.03 count += 1 end false end total = count if total != ups1 + ups2 snd_display("scan_sound_chans: %s %s?", total, ups1 + ups2) end count = 0 scan_across_all_chans do |data, len| data.each do |val| if val > 0.03 count += 1 end end false end total = count ups3 = count_matches(lambda do |n| n > 0.03 end, 0, ind1, 0) if total != ups1 + ups2 + ups3 snd_display("scan_across_all_chans: %s %s?", total, ups1 + ups2 + ups3) end count = 0 scan_all_chans do |n| if n > 0.03 count += 1 end false end total = count ups3 = count_matches(lambda do |n| n > 0.03 end, 0, ind1, 0) if total != ups1 + ups2 + ups3 snd_display("scan_all_chans: %s %s?", total, ups1 + ups2 + ups3) end close_sound(ind1) close_sound(ind2) end def get_test_args(args, snd, chn, edpos) [(args[0] or snd), (args[1] or chn), (args[2] or edpos)] end def test_05_20 ind1 = open_sound("oboe.snd") len = framples(ind1) ctr = 0 map_chan(lambda do |n| ctr = (ctr == 1) ? 0 : 1 ctr.zero? ? n * 2.0 : false end, 0, framples(ind1), "ignore: cut 2", ind1, 0) if framples(ind1) > (len * 2 + 1) snd_display("map_chan cut: %s %s?", len, framples(ind1)) end revert_sound(ind1) ctr = 0 map_chan(lambda do |n| ctr += 1 ctr > 3 ? true : n end, 0, framples(ind1), "ignore: cut none", ind1, 0) if ctr > 4 snd_display("map_chan no-edit count: %s?", ctr) end revert_sound(ind1) v1 = make_vct(2) map_chan(lambda do |n| v1[0] = n v1[1] = n * 3.0 v1 end, 0, framples(ind1), "ignore: cut 2", ind1, 0) if (framples(ind1) - len * 2).abs > 3 snd_display("map_chan double: %s %s?", len, framples(ind1)) end revert_sound(ind1) otime = maxamp_position(ind1) set_sample(1234, 0.9) ntime = maxamp_position(ind1) nval = maxamp(ind1) npos = edit_position(ind1, 0) if ntime != 1234 snd_display("maxamp_position 1234: %s?", ntime) end ootime = maxamp_position(ind1, 0, 0) if ootime != otime snd_display("maxamp_position edpos 0: %s %s?", otime, ootime) end nntime = maxamp_position(ind1, 0, npos) if nntime != ntime snd_display("maxamp_position edpos %s: %s %s?", npos, ntime, nntime) end if fneq(nval, 0.9) snd_display("maxamp 0.9: %s?", nval) end set_sample(1234, 0.0) env_channel([0, 0, 1, 1]) snd_test_neq(maxamp_position(), 35062, "env_channel maxamp_position") ootime = maxamp_position(ind1, 0, 0) snd_test_neq(ootime, otime, "maxamp_position edpos 0 (1)") nntime = maxamp_position(ind1, 0, 1) snd_test_neq(nntime, 1234, "maxamp_position edpos 1 (1)") nntime = maxamp_position(ind1, 0, Current_edit_position) snd_test_neq(nntime, 35062, "maxamp_position edpos current") revert_sound(ind1) make_selection(24000, 25000) snd_test_neq(selection_maxamp_position(), 971, "selection_maxamp_position") make_region(24000, 25000) res = region_maxamp_position(regions.first) snd_test_neq(res, 971, "region_maxamp_position") close_sound(ind1) ind1 = open_sound("oboe.snd") test_edpos(ind1, :maxamp) do | | scale_by(2.0, ind1, 0) end test_edpos(ind1, :framples) do | | src_sound(2.0, 1.0, ind1, 0) end test_edpos(ind1, :count_matches, lambda do |*args| snd, chn, edpos = get_test_args(args, 0, 0, Current_edit_position) count_matches(lambda do |n1| n1 > 0.1 end, 0, snd, chn, edpos) end) do | | scale_by(2.0, ind1, 0) end test_edpos(ind1, :find, lambda do |*args| snd, chn, edpos = get_test_args(args, 0, 0, Current_edit_position) find_channel(lambda do |n2| n2 > 0.1 end, 0, snd, chn, edpos) end) do | | delete_samples(0, 100, ind1, 0) end test_edpos(ind1, :scan_channel, lambda do |*args| snd, chn, edpos = get_test_args(args, 0, 0, Current_edit_position) samp = 0 scan_channel(lambda do |n3| if n3 > 0.1 samp else samp += 1 false end end, 0, framples(snd, chn), snd, chn, edpos) samp end) do | | delete_samples(0, 100, ind1, 0) end # delete_samples(0, 10000, ind1, 0) save_sound_as("fmv.snd", ind1, :edit_position, 0) save_sound_as("fmv1.snd", ind1, :edit_position, 1) if (res = Snd.catch do save_sound_as("fmv2.snd", ind1, :channel, 1234) end).first != :no_such_channel snd_display("save_sound_as bad chan: %s", res) end if (res0 = mus_sound_framples("fmv.snd")) != (res1 = framples(ind1, 0, 0)) snd_display("save_sound_as (edpos): %s %s?", res0, res1) end if (res0 = mus_sound_framples("fmv1.snd")) != (res1 = framples(ind1, 0, 1)) snd_display("save_sound_as (edpos 1): %s %s?", res0, res1) end if (res0 = mus_sound_framples("fmv.snd")) == (res1 = framples(ind1, 0, 1)) snd_display("save_sound_as (edpos 1)(2): %s %s?", res0, res1) end ind2 = open_sound("fmv.snd") ind3 = open_sound("fmv1.snd") unless vequal(res0 = channel2vct(12000, 10, ind1, 0, 0), res1 = channel2vct(12000, 10, ind2, 0)) snd_display("save_sound_as (edpos 3): %s %s?", res0, res1) end unless vequal(res0 = channel2vct(12000, 10, ind1, 0, 1), res1 = channel2vct(12000, 10, ind3, 0)) snd_display("save_sound_as (edpos 4): %s %s?", res0, res1) end if vequal(res0 = channel2vct(12000, 10, ind2), res1 = channel2vct(12000, 10, ind3, 0)) snd_display("save_sound_as (edpos 5): %s %s?", res0, res1) end select_sound(ind3) set_comment("hiho") if comment != "hiho" snd_display("set_comment no index: %s?", comment) end close_sound(ind2) close_sound(ind3) delete_files("fmv.snd", "fmv1.snd") # test_edpos_1(:reverse_sound, ind1) do |snd, pos| reverse_sound(snd, 0, pos) end test_edpos_1(:env_sound, ind1) do |snd, pos| env_sound([0, 0, 1, 1, 2, 0], 0, 20000, 1.0, snd, 0, pos) end test_edpos_1(:src_sound, ind1) do |snd, pos| src_sound(0.5, 1.0, snd, 0, pos) end test_edpos_1(:filter_sound, ind1) do |snd, pos| filter_sound(make_fir_filter(6, vct(0.1, 0.2, 0.3, 0.3, 0.2, 0.1)), 6, snd, 0, pos) end test_edpos_1(:convolve_with, ind1) do |snd, pos| convolve_with("pistol.snd", 0.5, snd, 0, pos) end # ind = new_sound("fmv.snd") e = make_env([0.0, 0.0, 1.0, 2000 * 0.2 * PI], :length, 2001) v = make_vct!(2000) do |i| sin(env(e)) end vct2channel(v, 0, 2000, ind, 0) filter_sound([0, 0, 0.09, 0, 0.1, 1, 0.11, 0, 1, 0], 1024) if maxamp > 0.025 snd_display("filter_sound maxamp 1: %s?", maxamp) end undo_edit filter_sound([0, 0, 0.19, 0, 0.2, 1, 0.21, 0, 1, 0], 1024) if maxamp < 0.9 snd_display("filter_sound maxamp 2: %s?", maxamp) end undo_edit filter_sound([0, 0, 0.29, 0, 0.3, 1, 0.31, 0, 1, 0], 1024) if maxamp > 0.02 snd_display("filter_sound maxamp 3: %s?", maxamp) end old_ssc = show_sonogram_cursor old_tgt = transform_graph_type set_show_sonogram_cursor(true) set_with_tracking_cursor(true) snd_test_neq(with_tracking_cursor(), true, "with_tracking_cursor set to true") set_transform_graph_type(Graph_as_sonogram) play(selected_sound, :wait, true) set_transform_graph?(true) set_transform_graph_type(old_tgt) set_show_sonogram_cursor(old_ssc) close_sound(ind) close_sound(ind1) end def peak_env_equal?(name, index, e, diff) rd = make_sampler(0, index, 0) e_size = e.first.length samps_per_bin = (framples(index) / e_size.to_f).ceil mins, maxs = e[0, 2] max_diff = 0.0 e_bin = 0 samp = 0 mx = -10.0 mn = 10.0 until e_bin == e_size if samp >= samps_per_bin mxdiff = (mx - maxs[e_bin]).abs mndiff = (mn - mins[e_bin]).abs if mxdiff > max_diff max_diff = mxdiff end if mndiff > max_diff max_diff = mndiff end if mxdiff > diff or mndiff > diff snd_display("%s: peak_env_equal? [bin %s of %s]: %s %s %s?", name, e_bin, e_size, mn, mx, [mxdiff, mndiff].max) return false end samp = 0 mx = -10.0 mn = 10.0 e_bin += 1 end val = next_sample(rd) if val < mn mn = val end if val > mx mx = val end samp += 1 end true end def test_05_22 ind = open_sound("oboe.snd") mx = maxamp(ind, 0) if (e0 = channel_amp_envs(ind, 0)).nil? snd_display("no amp env data") else mx1 = vct_peak(e0[0]) mx2 = vct_peak(e0[1]) if fneq(mx, [mx1, mx2].max) snd_display("amp env max: %s %s %s?", mx, mx1, mx2) end peak_env_equal?("straight peak", ind, e0, 0.0001) # scale_by(3.0) e1 = channel_amp_envs(ind, 0, 1) mx3 = vct_peak(e1[0]) mx4 = vct_peak(e1[1]) if fneq(3.0 * mx1, mx3) or fneq(3.0 * mx2, mx4) snd_display("3.0 amp env max: %s %s %s %s?", mx1, mx2, mx3, mx4) end peak_env_equal?("scaled peak", ind, e1, 0.0001) if fneq(maxamp(ind, 0), 3.0 * mx) snd_display("maxamp after scale: %s %s?", mx, maxamp(ind, 0)) end undo_edit # set_selection_member?(false, true) set_selection_member?(true, ind, 0) set_selection_position(20000, ind, 0) set_selection_framples(12000, ind, 0) scale_selection_by(3.0) e1 = channel_amp_envs(ind, 0, 1) mx3 = vct_peak(e1[0]) mx4 = vct_peak(e1[1]) if fneq(3.0 * mx1, mx3) or fneq(3.0 * mx2, mx4) snd_display("selection 3.0 amp env max: %s %s %s %s?", mx1, mx2, mx3, mx4) end if fneq(maxamp(ind, 0), 3.0 * mx) snd_display("maxamp after selection scale: %s %s?", mx, maxamp(ind, 0)) end peak_env_equal?("selection peak", ind, e1, 0.0001) # map_chan(lambda do |n| n.abs end, 0, false, "test", ind, 0) e1 = channel_amp_envs(ind, 0, 2) mx3 = vct_peak(e1[0]) mx4 = vct_peak(e1[1]) if fneq(3.0 * mx2, mx4) snd_display("abs selection 3.0 amp env max: %s %s %s %s?", mx1, mx2, mx3, mx4) end if fneq(maxamp(ind, 0), 3.0 * mx) snd_display("maxamp after abs selection scale: %s %s?", mx, maxamp(ind, 0)) end peak_env_equal?("map_chan peak", ind, e1, 0.0001) # delete_samples(10000, 5000) e1 = channel_amp_envs(ind, 0) mx3 = vct_peak(e1[0]) mx4 = vct_peak(e1[1]) if fneq(3.0 * mx2, mx4) snd_display("abs selection 3.0 amp env max: %s %s %s %s?", mx1, mx2, mx3, mx4) end if fneq(maxamp(ind, 0), 3.0 * mx) snd_display("maxamp after abs selection scale: %s %s?", mx, maxamp(ind, 0)) end peak_env_equal?("delete peak", ind, e1, 0.0001) # scale_selection_by -0.333 e1 = channel_amp_envs(ind, 0, 4) mx3 = vct_peak(e1[0]) if fneq(maxamp(ind, 0), mx) snd_display("maxamp after minus selection scale: %s %s?", mx, maxamp(ind, 0)) end if fneq(maxamp(ind, 0), mx3) snd_display("mx3 maxamp after minus abs selection scale: %s %s?", mx, mx3) end peak_env_equal?("scale_selection peak", ind, e1, 0.0001) end revert_sound(ind) ramp_channel(0.0, 1.0) peak_env_equal?("ramp_channel peak", ind, channel_amp_envs(ind, 0, 1), 0.001) undo_edit env_channel([0, 0, 1, 1, 2, 0]) peak_env_equal?("env_channel peak", ind, channel_amp_envs(ind, 0, 1), 0.002) undo_edit env_channel(make_env([0, 0, 1, 1, 2, 0], :scaler, 0.5, :length, framples)) peak_env_equal?("scaled env_channel peak", ind, channel_amp_envs(ind, 0, 1), 0.002) undo_edit env_channel(make_env([0, 0, 1, 1, 2, 0], 0.5, :length, framples)) peak_env_equal?("scaled nokey env_channel peak", ind, channel_amp_envs(ind, 0, 1), 0.001) undo_edit env_channel(make_env([0, 0, 1, 1, 2, 0], :scaler, 0.5, :offset, 0.5, :length, framples)) peak_env_equal?("scaled and offset env_channel peak", ind, channel_amp_envs(ind, 0, 1), 0.001) undo_edit env_channel(make_env([0, 0, 1, 1, 2, 0.5, 3, 0], :base, 0.0, :length, framples)) peak_env_equal?("env_channel base 0.0 peak", ind, channel_amp_envs(ind, 0, 1), 0.001) undo_edit xramp_channel(0.0, 1.0, 32.0) peak_env_equal?("xramp_channel 32.0 peak", ind, channel_amp_envs(ind, 0, 1), 0.008) undo_edit xramp_channel(0.0, 1.0, 0.032) peak_env_equal?("xramp_channel 0.032 peak", ind, channel_amp_envs(ind, 0, 1), 0.004) undo_edit env_channel(make_env([0, 0, 1, 1, 2, 0.5, 3, 0], :base, 10.0, :length, framples)) peak_env_equal?("env_channel base 10.0 peak", ind, channel_amp_envs(ind, 0, 1), 0.01) undo_edit env_channel(make_env([0, 0, 1, 1, 2, 0], :base, 0.1, :length, framples)) peak_env_equal?("env_channel base 0.1 peak", ind, channel_amp_envs(ind, 0, 1), 0.003) undo_edit insert_samples(1000, 5000, make_vct(5000, 0.5)) peak_env_equal?("insert_samples peak", ind, channel_amp_envs(ind, 0, 1), 0.0001) undo_edit set_samples(500, 100, make_vct(100, 0.1)) peak_env_equal?("set_samples peak", ind, channel_amp_envs(ind, 0, 1), 0.0001) undo_edit # revert_sound(ind) ramp_channel(0.0, 1.0) ramp_channel(1.0, 0.0) peak_env_equal?("2 ramp_channel peak", ind, channel_amp_envs(ind, 0, 2), 0.002) # revert_sound(ind) env_channel([0, 0, 1, 1]) env_channel([0, 0, 1, 1, 2, 0]) peak_env_equal?("2 env_channel peak", ind, channel_amp_envs(ind, 0, 2), 0.002) revert_sound(ind) ramp_channel(0.0, 1.0, 12000, 5000) peak_env_equal?("ramp_channel peak", ind, channel_amp_envs(ind, 0, 1), 0.002) undo_edit env_channel([0, 0, 1, 1, 2, 0], 12000, 5000) peak_env_equal?("env_channel peak", ind, channel_amp_envs(ind, 0, 1), 0.003) undo_edit env_channel(make_env([0, 0, 1, 1, 2, 0], :scaler, 0.5, :length, 5000), 12000, 5000) peak_env_equal?("scaled env_channel peak", ind, channel_amp_envs(ind, 0, 1), 0.004) undo_edit env_channel(make_env([0, 0, 1, 1, 2, 0], 0.5, :length, 5000), 12000, 5000) peak_env_equal?("scaled nokey env_channel peak", ind, channel_amp_envs(ind, 0, 1), 0.004) undo_edit env_channel(make_env([0, 0, 1, 1, 2, 0], :scaler, 0.5, :offset, 0.5, :length, 5000), 12000, 5000) peak_env_equal?("scaled and offset env_channel peak", ind, channel_amp_envs(ind, 0, 1), 0.002) undo_edit xramp_channel(0.0, 1.0, 32.0, 2000, 1000) peak_env_equal?("xramp_channel 32.0 peak (1)", ind, channel_amp_envs(ind, 0, 1), 0.009) undo_edit xramp_channel(0.0, 1.0, 0.032, 2000, 1000) peak_env_equal?("xramp_channel 0.032 peak (1)", ind, channel_amp_envs(ind, 0, 1), 0.01) undo_edit env_channel(make_env([0, 0, 1, 1, 2, 0.5, 3, 0], :base, 10.0, :length, 5000), 12000, 5000) peak_env_equal?("env_channel base 10.0 peak", ind, channel_amp_envs(ind, 0, 1), 0.1) undo_edit # revert_sound(ind) ramp_channel(0.0, 1.0) ramp_channel(1.0, 0.0, 2000, 1000) peak_env_equal?("2 ramp_channel peak", ind, channel_amp_envs(ind, 0, 2), 0.002) # revert_sound(ind) env_channel([0, 0, 1, 1]) env_channel([0, 0, 1, 1, 2, 0], 2000, 1000) peak_env_equal?("2 env_channel peak", ind, channel_amp_envs(ind, 0, 2), 0.002) # revert_sound(ind) env_channel([0, 0, 1, 1]) env_channel([0, 0, 1, 1, 2, 0]) env_channel([0, 0, 1, 1], 12000, 5000) peak_env_equal?("3 env_channel peak", ind, channel_amp_envs(ind, 0, 3), 0.01) revert_sound(ind) close_sound(ind) # ind = new_sound("test.snd") map_chan(lambda do |y| 1.0 end, 0, 50000) ramp_channel(0.5, 1.0, 1000, 4000) mn, mx = channel_amp_envs(ind, 0)[0, 2] (mn.length - 4).times do |i| if mn[i] < 0.5 snd_display("peak min: %s %s?", mn[i], i) break end if mx[i] < 0.5 snd_display("peak max: %s %s?", mx[i], i) break end end undo_edit map_chan(lambda do |y| -1.0 end, 0, 50000) ramp_channel(0.5, 1.0, 1000, 4000) mn, mx = channel_amp_envs(ind, 0)[0, 2] (mn.length - 4).times do |i| if mn[i] > -0.5 snd_display("1 peak min: %s %s?", mn[i], i) break end if mx[i] > -0.5 snd_display("1 peak max: %s %s?", mx[i], i) break end end close_sound(ind) end $g_init_val = 0 def test_channel_func(name, index, init_val, func, &val_func) len = framples(index) chns = chans(index) $g_init_val = init_val 2.times do |k| val = val_func.call(len) set_sync(k, index) chns.times do |i| map_channel(lambda do |n| 0.0 end, 0, len, index, i) res = scan_channel(lambda do |n| n.abs > 0.001 end, 0, len, index, i) if res snd_display("%s init scan: %s?", name, res) end end chns.times do |i| map_channel(lambda do |n| $g_init_val end, 0, len, index, i) func.call(0, len, index, i, false) chns.times do |j| vi = channel2vct(0, len, index, j) if j == i unless vequal(vi, val) snd_display("%s chan func: %s %s?", name, vi, val) end else res = scan_channel(lambda do |n| n.abs > 0.001 end, 0, len, index, j) if res snd_display("%s chan func leaks? %s %s: %s", name, i, j, res) end end end map_channel(lambda do |n| 0.0 end, 0, len, index, i) end chns.times do |i| map_channel(lambda do |n| $g_init_val end, 0, len, index, i) ed = edit_position(index, i) map_channel(lambda do |n| $g_init_val + 1.0 end, 0, len, index, i) func.call(0, len, index, i, ed) chns.times do |j| vi = channel2vct(0, len, index, j) if j == i unless vequal(vi, val) snd_display("%s ed chan func: %s %s?", name, vi, val) end else res = scan_channel(lambda do |n| n.abs > 0.001 end, 0, len, index, j) if res snd_display("%s ed chan func leaks? %s %s %s: %s", name, i, j, ed, res) end end end map_channel(lambda do |n| 0.0 end, 0, len, index, i) end beg = dur = (len / 3.0).floor nv = val_func.call(dur) vct_fill!(val, 0.0) i = beg dur.times do |j| val[i] = nv[j] i += 1 end chns.times do |i| map_channel(lambda do |n| $g_init_val end, beg, dur, index, i) func.call(beg, dur, index, i, false) add_mark(beg, index, i) chns.times do |j| vi = channel2vct(0, len, index, j) if j == i unless vequal(vi, val) snd_display("%s chan func n: %s %s?", name, vi, val) end else res = scan_channel(lambda do |n| n.abs > 0.001 end, 0, len, index, j) if res snd_display("%s dur chan func leaks? %s %s: %s", name, i, j, res) end end end map_channel(lambda do |n| 0.0 end, 0, len, index, i) end end end def test_05_23 index = new_sound("fmv.snd", 2, 22050, Mus_bshort, Mus_next, "channel tests") insert_silence(0, 10, index, 0) insert_silence(0, 10, index, 1) test_channel_func(:env, index, 0.0, lambda do |beg, dur, index, chan, edpos| clm_channel(make_env(:envelope, [0, 0, 1, 1], :length, dur), beg, dur, index, chan, edpos) end) do |dur| e = make_env(:envelope, [0, 0, 1, 1], :length, dur) make_vct!(dur) do env(e) end end test_channel_func(:oscil, index, 0.0, lambda do |beg, dur, index, chan, edpos| clm_channel(make_oscil(:frequency, 0.0, :initial_phase, PI / 2.0), beg, dur, index, chan, edpos) end) do |dur| make_vct!(dur) do 1.0 end end test_channel_func(:scale_channel, index, 1.0, lambda do |beg, dur, index, chan, edpos| scale_channel(0.5, beg, dur, index, chan, edpos) end) do |dur| make_vct!(dur) do 0.5 end end test_channel_func(:env_channel, index, 1.0, lambda do |beg, dur, index, chan, edpos| env_channel(make_env(:envelope, [0, 0, 1, 1], :length, dur), beg, dur, index, chan, edpos) end) do |dur| e = make_env(:envelope, [0, 0, 1, 1], :length, dur) make_vct!(dur) do env(e) end end test_channel_func(:env_channel, index, 1.0, lambda do |beg, dur, index, chan, edpos| env_channel([0, 0, 1, 1], beg, dur, index, chan, edpos) end) do |dur| e = make_env(:envelope, [0, 0, 1, 1], :length, dur) make_vct!(dur) do env(e) end end test_channel_func(:vct2channel, index, 1.0, lambda do |beg, dur, index, chan, edpos| vct2channel(make_vct!(dur) do -1.0 end, beg, dur, index, chan) end) do |dur| make_vct!(dur) do -1.0 end end test_channel_func(:pad_channel, index, 1.0, lambda do |beg, dur, index, chan, edpos| delete_samples(beg, dur, index, chan, edpos) pad_channel(beg, dur, index, chan, edpos) end) do |dur| make_vct(dur) end test_channel_func(:insert_samples, index, 1.0, lambda do |beg, dur, index, chan, edpos| delete_samples(beg, dur, index, chan, edpos) insert_samples(beg, dur, make_vct!(dur) do -1.0 end, index, chan, edpos) end) do |dur| make_vct!(dur) do -1.0 end end test_channel_func(:set_samples, index, 1.0, lambda do |beg, dur, index, chan, edpos| set_samples(beg, dur, make_vct!(dur) do -1.0 end, index, chan, false, "test_channel", edpos) end) do |dur| make_vct!(dur) do -1.0 end end test_channel_func(:reverse_channel, index, 1.0, lambda do |beg, dur, index, chan, edpos| env_channel(make_env(:envelope, [0, 0, 1, 1], :length, dur), beg, dur, index, chan, edpos) reverse_channel(beg, dur, index, chan) end) do |dur| e = make_env(:envelope, [0, 1, 1, 0], :length, dur) make_vct!(dur) do env(e) end end test_channel_func(:smooth_channel, index, 1.0, lambda do |beg, dur, index, chan, edpos| env_channel(make_env(:envelope, [0, 0, 1, 1], :length, dur), beg, dur, index, chan, edpos) set_sample(beg + dur, 1.0, index, chan) smooth_channel(beg, dur, index, chan) if beg.nonzero? set_sample(beg + dur, 0.0, index, chan) end end) do |dur| make_vct!(dur) do |i| 0.5 + 0.5 * cos(PI + (PI * i) / dur) end end # old_max = maxamp(index, true) regdata = Snd.regions.map do |n| region2vct(n, 0, 10) end old_reglen = Snd.regions.map do |n| region_framples(n) end s61_files = [] $save_state_hook.add_hook!("snd-test") do |file| s61_files.push(file) false end delete_file("s61.rb") save_state("s61.rb") close_sound(index) Snd.regions.apply(:forget_region) load("s61.rb") if (res = Snd.regions.map do |n| region_framples(n) end) != old_reglen snd_display("region_framples after save: %s %s?", old_reglen, res) end Snd.catch(:all, lambda do |*args| snd_display("region2vct: %s", args.inspect) end) do Snd.regions.zip(regdata) do |n, data| unless vequal(res = region2vct(n, 0, 10), data) snd_display("region after save %s: %s %s?", n, data, res) end end end index = find_sound("fmv.snd") if (res = maxamp(index, true)) != old_max snd_display("maxes: %s %s?", res, old_max) end if edits(index) != [275, 0] snd_display("saved channel edits: %s?", edits(index)) end 10.times do |i| pos = random(edits(index).first) scale_channel(random(2.0), random(5), random(5), index, 0, pos) set_edit_position((edits(index).first * 0.7).floor, index) end close_sound(index) Snd.regions.apply(:forget_region) s61_files.each do |file| delete_file(file) end delete_file("s61.rb") $save_state_hook.reset_hook! end def test_05_24 index = new_sound("fmv.snd", 2, 22050, Mus_bshort, Mus_next, "channel tests") sw = sinc_width set_sinc_width(10) v0 = make_vct(10) v0[0] = 1.0 vct2channel(v0, 0, 10, index, 0) src_channel(0.5, 0, 10, index, 0) idx = -1 s = make_src(:srate, 0.5, :input, lambda do |dir| idx += 1 idx.zero? ? 1.0 : 0.0 end) v = make_vct!(10) do src(s) end unless vequal(res = channel2vct(0, 10, index, 0), v) snd_display("src_channel: %s %s?", v, res) end unless vequal(res = channel2vct(0, 10, index, 1), make_vct(10)) snd_display("src_channel leaks: %s?", res) end res = Snd.catch do src_channel(120000.0) end if res.first != :mus_error snd_display("src_channel crazy srate: %s?", res.inspect) end res = Snd.catch do filter_sound(make_snd2sample()) end if res.first != :mus_error # not relevant in Ruby? snd_display("filter_sound + un-run gen: %s?", res.inspect) end revert_sound(index) vct2channel(v0, 0, 10, index, 1) vct2channel(v0, 10, 10, index, 1) src_channel(make_env(:envelope, [1, 1, 2, 2], :length, 21), 0, 20, index, 1) unless vequal(res = channel2vct(0, 10, index, 1), vct(1.000, 0.000, -0.048, 0.068, -0.059, 0.022, 0.030, -0.100, 0.273, 0.606)) snd_display("src_channel env: %s?", res) end unless vequal(res = channel2vct(0, 10, index, 0), make_vct(10)) snd_display("src_channel env leaks: %s?", res) end # revert_sound(index) vct2channel(v0, 0, 10, index, 1) vct2channel(v0, 10, 10, index, 1) src_channel(make_env(:envelope, [1, 1, 2, 2], :length, 21), 0, 20, index, 1) unless vequal(res = channel2vct(0, 10, index, 1), vct(1.000, 0.000, -0.048, 0.068, -0.059, 0.022, 0.030, -0.100, 0.273, 0.606)) snd_display("src_channel env: %s?", res) end unless vequal(res = channel2vct(0, 10, index, 0), make_vct(10)) snd_display("src_channel env leaks: %s?", res) end # revert_sound(index) vct2channel(v0, 0, 10, index, 1) vct2channel(v0, 10, 10, index, 1) src_channel([1, 1, 2, 2], 0, 20, index, 1) unless vequal(res = channel2vct(0, 10, index, 1), vct(1.000, 0.000, -0.051, 0.069, -0.056, 0.015, 0.042, -0.117, 0.320, 0.568)) snd_display("src_channel lst: %s?", res) end unless vequal(res = channel2vct(0, 10, index, 0), make_vct(10)) snd_display("src_channel lst leaks: %s?", res) end set_sinc_width(sw) close_sound(index) end def test_05_25 ind = open_sound("oboe.snd") rid0 = make_region(2000, 2020, ind, 0) rid0_data = region2vct_1(rid0, 0, 20) scale_sound_by(2.0) play(rid0, :wait, true) unless vequal(res = region2vct_1(rid0, 0, 20), rid0_data) snd_display("deferred region after scaling:\n# %s\n# %s", rid0_data, res) end unless vequal(res = region_to_vct(rid0, 0, 20), rid0_data) snd_display("deferred region after scaling (rs):\n# %s\n# %s", rid0_data, res) end undo_edit scale_by(4.0) play(rid0, :wait, true) unless vequal(res = region2vct_1(rid0, 0, 20), rid0_data) snd_display("file region after scaling:\n# %s\n# %s", rid0_data, res) end unless vequal(res = region_to_vct(rid0, 0, 20), rid0_data) snd_display("file region after scaling (rs):\n# %s\n# %s", rid0_data, res) end rid1 = make_region(2000, 2020, ind, 0) rid1_data = region2vct_1(rid1, 0, 20) scale_to(0.5) unless vequal(res = region2vct_1(rid1, 0, 20), rid1_data) snd_display("deferred region after scale_to:\n# %s\n# %s", rid1_data, res) end close_sound(ind) play(rid0, :wait, true) play(rid1, :wait, true) unless vequal(res = region2vct_1(rid1, 0, 20), rid1_data) snd_display("deferred region after close:\n# %s\n# %s", rid1_data, res) end unless vequal(res = region2vct_1(rid0, 0, 20), rid0_data) snd_display("file region after close:\n# %s\n# %s", rid0_data, res) end [[2000, 20, 2000, 20], [2000, 10, 2000, 20], [2000, 20, 2000, 10], [0, 20, 2000, 20], [2000, 20, 0, 20], [0, 10, 2000, 20], [2000, 20, 0, 10]].each do |s1, l1, s2, l2| ind = open_sound("2.snd") set_selection_member?(false, true) set_selection_member?(true, ind, 0) set_selection_position(s1, ind, 0) set_selection_framples(l1, ind, 0) set_selection_member?(true, ind, 1) set_selection_position(s2, ind, 1) set_selection_framples(l2, ind, 1) rid2 = make_region rid20_data = region2vct_1(rid2, 0, l1) rid21_data = region2vct_1(rid2, 1, l2) if (res = region_chans(rid2)) != 2 snd_display("region_chans of synced sound: %s?", res) end swap_channels(ind, 0, ind, 1) unless vequal(res = region2vct_1(rid2, 0, l1), rid20_data) snd_display("deferred region after scaling (20):\n# %s\n# %s", rid20_data, res) end unless vequal(res = region_to_vct(rid2, 0, l1), rid20_data) snd_display("deferred region after scaling (20 rs):\n# %s\n# %s", rid20_data, res) end unless vequal(res = region2vct_1(rid2, 1, l2), rid21_data) snd_display("deferred region after scaling (21):\n# %s\n# %s", rid21_data, res) end unless vequal(res = region_to_vct(rid2, 1, l2), rid21_data) snd_display("deferred region after scaling (21 rs):\n# %s\n# %s", rid21_data, res) end close_sound(ind) unless vequal(res = region2vct_1(rid2, 0, l1), rid20_data) snd_display("deferred region after scaling (20):\n# %s\n# %s", rid20_data, res) end unless vequal(res = region_to_vct(rid2, 0, l1), rid20_data) snd_display("deferred region after scaling (20 rs):\n# %s\n# %s", rid20_data, res) end unless vequal(res = region2vct_1(rid2, 1, l2), rid21_data) snd_display("deferred region after scaling (21):\n# %s\n# %s", rid21_data, res) end unless vequal(res = region_to_vct(rid2, 1, l2), rid21_data) snd_display("deferred region after scaling (21 rs):\n# %s\n# %s", rid21_data, res) end end ind = open_sound("obtest.snd") set_read_only(true, ind) delete_samples(0, 1000, ind, 0) res = Snd.catch do save_sound(ind) end if sound?(res.first) snd_display("save_sound read_only: %s", res) end snd_test_neq(edits(ind), [1, 0], "read_only ignored") set_read_only(false, ind) revert_sound(ind) res = Snd.catch do save_sound(ind) end unless sound?(res.first) snd_display("save_sound read_write: %s", res) end key(key_to_int(?j), 4) key(key_to_int(?-), 4) key(key_to_int(?j), 4) key(key_to_int(?j), 4) key(key_to_int(?x), 4) key(key_to_int(?c), 0) Snd.catch do add_mark(123) end key(key_to_int(?u), 4) key(key_to_int(?6), 4) key(key_to_int(?j), 4) key(key_to_int(?u), 4) key(key_to_int(?6), 4) key(key_to_int(?x), 4) key(key_to_int(?c), 0) close_sound(ind) # ns = new_sound v = make_vct(1000) unselect_all 1000.times do |i| v[i] = 0.001 * i end vct2channel(v, 0, 1000, ns, 0) set_selection_member?(true, ns, 0) set_selection_position(200, ns, 0) set_selection_framples(300, ns, 0) delete_selection_and_smooth snd_test_neq(framples(ns, 0), 700, "delete_selection_and_smooth framples") snd_test_neq(sample(167, ns, 0), 0.167, "delete_selection_and_smooth 167") snd_test_neq(sample(234, ns, 0), 0.534, "delete_selection_and_smooth 234") snd_test_neq(sample(210, ns, 0), 0.406, "delete_selection_and_smooth 210") v1 = channel2vct maxdiff = 0.0 mindiff = 10.0 ls = v1[0] (1...700).each do |i| diff = v1[i] - ls ls = v1[i] if diff > maxdiff maxdiff = diff end if diff < mindiff mindiff = diff end end snd_test_lt(mindiff, 0.0009, "delete_selection_and_smooth min diff") snd_test_gt(maxdiff, 0.007, "delete_selection_and_smooth max diff") close_sound(ns) # ns = new_sound v = make_vct(1000) unselect_all 1000.times do |i| v[i] = 0.001 * i end vct2channel(v, 0, 1000, ns, 0) delete_samples_and_smooth(200, 300, ns, 0) snd_test_neq(framples(ns, 0), 700, "delete_samples_and_smooth framples") snd_test_neq(sample(167, ns, 0), 0.167, "delete_samples_and_smooth 167") snd_test_neq(sample(234, ns, 0), 0.534, "delete_samples_and_smooth 234") snd_test_neq(sample(210, ns, 0), 0.406, "delete_samples_and_smooth 210") v1 = channel2vct maxdiff = 0.0 mindiff = 10.0 ls = v1[0] (1...700).each do |i| diff = v1[i] - ls ls = v1[i] if diff > maxdiff maxdiff = diff end if diff < mindiff mindiff = diff end end snd_test_lt(mindiff, 0.0009, "delete_samples_and_smooth min diff") snd_test_gt(maxdiff, 0.007, "delete_samples_and_smooth max diff") close_sound(ns) # old_beg = initial_beg old_dur = initial_dur old_show = show_full_duration $initial_graph_hook.reset_hook! # set_show_full_range(true) ns = open_sound("1a.snd") snd_test_neq(y_bounds(ns, 0), [-1.0, 1.0], "show_full_range 1.0 test") close_sound(ns) with_sound(:output, "test.snd", :clipped, false) do fm_violin(0, 1, 440, 3.5) end ns = open_sound("test.snd") snd_test_neq(y_bounds(ns, 0), [-3.5, 3.5], "show_full_range 3.5 test") with_sound(:output, "test.snd", :clipped, false) do fm_violin(0, 1, 440, 1.5) end update_sound(ns = find_sound("test.snd")) snd_test_neq(y_bounds(ns, 0), [-1.5, 1.5], "show_full_range 1.5 test") close_sound(ns) set_show_full_range(false) # set_show_full_duration(true) ns = open_sound("1.snd") ls = left_sample(ns, 0) rs = right_sample(ns, 0) fr = framples(ns, 0) snd_test_neq([fr, ls, rs], [220501, 0, 220501], "show_full_duration 1") close_sound(ns) set_show_full_duration(true) set_initial_beg(0.0) set_initial_dur(0.2) ns = open_sound("1.snd") ls = left_sample(ns, 0) rs = right_sample(ns, 0) fr = framples(ns, 0) snd_test_neq([fr, ls, rs], [220501, 0, 220501], "show_full_duration 2") close_sound(ns) set_show_full_duration(false) set_initial_beg(0.0) set_initial_dur(0.2) ns = open_sound("1.snd") ls = left_sample(ns, 0) rs = right_sample(ns, 0) fr = framples(ns, 0) snd_test_neq([fr, ls, rs], [220501, 0, 4410], "show_full_duration 3") close_sound(ns) set_initial_beg(2.0) set_initial_dur(1.0) ns = open_sound("1.snd") ls = left_sample(ns, 0) rs = right_sample(ns, 0) fr = framples(ns, 0) snd_test_neq([fr, ls, rs], [220501, 44100, 66150], "show_full_duration 4") close_sound(ns) set_initial_beg(old_beg) set_initial_dur(old_dur) set_show_full_duration(old_show) old_sync = sync_style set_sync_style(Sync_none) ns = open_sound("2.snd") snd_test_neq(sync(ns), 0, "Sync_none open") set_sync(1, ns) set_sync_style(Sync_by_sound) ns1 = open_sound("1a.snd") snd_test_eq(sync(ns1), 1, "Sync_by_sound open") snd_test_neq(sync(ns), 1, "Sync_by_sound open") close_sound(ns1) close_sound(ns) set_sync_style(old_sync) # ind = view_sound("obtest.snd") delete_samples(0, 1000, ind, 0) res = Snd.catch do save_sound(ind) end if sound?(res.first) snd_display("save_viewed_sound: %s", res) end snd_test_neq(edits(ind), [1, 0], "view read_only ignored") close_sound(ind) # ind = new_sound("test.snd", 1, 22050, Mus_bfloat, Mus_next) insert_silence(0, 150000) map_channel(lambda do |y| 0.5 end) env_sound([0, 0, 1, 1, 2, 0]) fp(1.0, 0.3, 20) old_cursor = with_tracking_cursor set_with_tracking_cursor(true) play(selected_sound, :wait, true) set_with_tracking_cursor(old_cursor) close_sound(ind) # ind = new_sound("test.snd", 1, 22050, Mus_bfloat, Mus_next) [150, 1500, 150000].each do |dur| insert_silence(0, dur) map_channel($init_channel) env_sound([0, 0, 1, 1, 2, 0]) rd = make_sampler(framples - 1, ind, 0, -1) if (res = sampler_position(rd)) != (framples - 1) snd_display("sampler_position: %s?", res) end map_channel(lambda do |y| rd.call end) pos = 0 e = make_env([0, 0, 1, 1, 2, 0], :length, dur + 1) scan_channel(lambda do |y| if fneq(val = env(e), y) snd_display("trouble in reverse read at %s %s %s", pos, val, y) true else pos += 1 false end end) revert_sound end close_sound(ind) # ind = new_sound("test.snd", 1, 22050, Mus_bfloat, Mus_next) insert_silence(0, 1000) map_channel($init_channel) env_sound([0, 0, 1, 1, 2, 0]) scale_channel(0.0, 100, 200) rd = make_sampler(framples - 1, ind, 0, -1) map_channel(lambda do |y| rd.call end) pos = 0 e = make_env([0, 0, 1, 1, 2, 0], :length, 1001) scan_channel(lambda do |y| val = env(e) if ((pos > 900 or pos <= 700) and fneq(val, y)) or (pos > 700 and pos <= 900 and fneq(y, 0.0)) snd_display("trouble in reverse read 2 at %s %s %s", pos, val, y) true else pos += 1 false end end) close_sound(ind) # ind = new_sound("test.snd", 1, 22050, Mus_bfloat, Mus_next) insert_silence(0, 150000) map_channel($init_channel) edpos = edit_position 7.times do |i| if i == 5 scale_channel(0.5, 1000, 12345) end env_sound([0, 0, 1, 1, 2.5, 0, 3, 1, 4, 0]) case i when 1 delete_samples(50, 100) when 2 insert_samples(300, 100, make_vct!(100) do 0.5 end) when 3 scale_channel(0.0, 1000, 1000) when 4 vct2channel(make_vct!(100) do 0.5 end, 500, 100) when 6 env_sound([0, 1, 1, 0], 10000, 2000) end rd = make_sampler(framples - 1, ind, 0, -1) map_channel(lambda do |y| rd.call end) rd = make_sampler(framples - 1, ind, 0, -1) map_channel(lambda do |y| rd.call end) old_rd = make_sampler(0, ind, 0, 1, edit_position(ind, 0) - 2) pos = 0 scan_channel(lambda do |y| if fneq(val = old_rd.call, y) snd_display("trouble in reverse (%s) read at %s %s %s", i, pos, val, y) true else pos += 1 false end end) end set_edit_position(edpos, ind, 0) close_sound(ind) # reader = false last_proc = false scan_again = lambda do result = false until sampler_at_end?(reader) if val = last_proc.call(reader.call) result = [val, sampler_position(reader) - 1] break end end result end my_scan_chan = lambda do |proc| if proc last_proc = proc reader = make_sampler(0) end scan_again.call end ind = open_sound("oboe.snd") set_cursor(1000, ind, 0) if fneq(res = sample(1000), sample()) snd_display("sample no args: %s %s", sample(), res) end req = [true, 4423] res = my_scan_chan.call(lambda do |y| y > 0.1 end) if res != req snd_display("my_scan_chan: res %s != req %s?", res, req) end req = [true, 4463] res = scan_again.call if res != req snd_display("scan_again: res %s != req %s?", res, req) end set_cursor(1000) # XXX: set_sample(0.5) isn't possible # Wrong_type_arg in set_sample: argument 1, 0.5, should be an integer set_sample(:undefined, 0.5) if fneq(res = sample(1000), 0.5) snd_display("set sample no arg: %s %s?", res, sample(0)) end close_sound(ind) end def test_05_26 ind = new_sound("test.snd") map_chan(lambda do |y| 1.0 end, 0, 1000) env_channel(make_env([0, 1, 1, 1], :scaler, 0.5, :length, 1001)) check_maxamp(ind, 0.5, "simple scaler") check_env_vals("simple scaler", make_env([0, 1, 1, 1], :scaler, 0.5, :length, 1001)) if edit_position == 2 undo_edit else snd_display("env+scl was no-op") end env_channel(make_env([0, 1, 1, 1], :offset, 0.5, :length, 1001)) check_maxamp(ind, 1.5, "simple offset") check_env_vals("simple offset", make_env([0, 1, 1, 1], :offset, 0.5, :length, 1001)) if edit_position == 2 undo_edit else snd_display("env+offset was no-op") end env_channel(make_env([0, 0, 1, 1, 2, 0], :offset, 0.5, :scaler, 2.0, :length, 1001)) check_maxamp(ind, 2.5, "off+scl") check_env_vals("off+scl", make_env([0, 0, 1, 1, 2, 0], :offset, 0.5, :scaler, 2.0, :length, 1001)) undo_edit env_channel(make_env([0, -0.5, 1, 0, 2, -1], :offset, 0.5, :scaler, 2.0, :length, 1001)) check_maxamp(ind, 1.5, "off+scl #2") mx = -12.0 scan_channel(lambda do |y| if y > mx mx = y end false end) snd_test_neq(mx, 0.5, "non abs max (correct 0.5)") check_env_vals("off+scl #2", make_env([0, -0.5, 1, 0, 2, -1], :offset, 0.5, :scaler, 2.0, :length, 1001)) undo_edit env_sound([0, 0.5, 1, 0.75, 2, 0.25], 0, framples(), 32.0) check_maxamp(ind, 0.75, "xramp") check_env_vals("xramp", make_env([0, 0.5, 1, 0.75, 2, 0.25], :base, 32.0, :length, 1001)) undo_edit env_channel_with_base([0, 0.5, 1, 0.75, 2, 0.25], 32.0) check_maxamp(ind, 0.75, "xramp1") check_env_vals("xramp1", make_env([0, 0.5, 1, 0.75, 2, 0.25], :base, 32.0, :length, 1001)) close_sound(ind) # hlb = make_hilbert_transform(8) snd_test_neq(make_vct!(20) do |i| hilbert_transform(hlb, (i == 0 ? 1.0 : 0.0)) end, vct(0, -0.01, 0, -0.046, 0, -0.152, 0, -0.614, 0, 0.614, 0, 0.152, 0, 0.046, 0, 0.01, 0, 0, 0, 0), "hilbert_transform 8 impulse response") hlb = make_hilbert_transform(7) snd_test_neq(make_vct!(20) do |i| hilbert_transform(hlb, (i == 0 ? 1.0 : 0.0)) end, vct(-0.007, 0.0, -0.032, 0.0, -0.136, 0.0, -0.608, 0.0, 0.608, 0.0, 0.136, 0.0, 0.032, 0.0, 0.007, 0.0, 0.0, 0.0, 0.0, 0.0), "hilbert_transform 7 impulse response") ind = new_sound("test.snd") pad_channel(0, 1000) set_sample(100, 1.0) h = make_hilbert_transform(100) 4.times do map_channel(lambda do |y| hilbert_transform(h, y) end) end snd_test_gt((sample(500) - 0.98).abs, 0.01, "hilbert impulse") set_sample(500, 0.0) snd_test_gt(maxamp(ind, 0), 0.02, "hilbert sidelobes") scale_channel(0.0) set_sample(100, 1.0) h = make_hilbert_transform(101) 4.times do map_channel(lambda do |y| hilbert_transform(h, y) end) end snd_test_gt((sample(504) - 0.98).abs, 0.01, "hilbert 101 impulse") set_sample(504, 0.0) snd_test_gt(maxamp(ind, 0), 0.02, "hilbert 101 sidelobes") revert_sound pad_channel(0, 1000) set_sample(100, 1.0) lo = make_lowpass(PI * 0.1, 20) hi = make_highpass(PI * 0.1, 20) map_channel(lambda do |y| lowpass(lo, y) + highpass(hi, y) end) snd_test_neq(sample(120), 1.0, "lowpass+highpass impulse") set_sample(120, 0.0) snd_test_neq(maxamp(ind, 0), 0.0, "lowpass+highpass sidelobes") undo_edit(2) lo = make_bandpass(PI * 0.1, PI * 0.2, 20) hi = make_bandstop(PI * 0.1, PI * 0.2, 20) map_channel(lambda do |y| bandpass(lo, y) + bandpass(hi, y) end) snd_test_neq(sample(120), 1.0, "bandpass+bandstop impulse") set_sample(120, 0.0) snd_test_neq(maxamp(ind, 0), 0.0, "bandpass+bandstop sidelobes") close_sound(ind) # ind = new_sound("test.snd") map_channel(lambda do |y| mus_random(1.0) end, 0, 10000) f2 = make_bandpass_2(0.12 * PI, 0.15 * PI, 0.22 * PI, 0.25 * PI, 100) map_channel(lambda do |y| bandpass_2(f2, y) end) data = channel2vct undo_edit f1 = make_bandpass(0.12 * PI, 0.15 * PI, 100) f2 = make_bandpass(0.22 * PI, 0.25 * PI, 100) map_channel(lambda do |y| bandpass(f1, y) + bandpass(f2, y) end) data1 = channel2vct vct_subtract!(data, data1) res = vct_peak(data) if res > 0.00001 snd_display(snd_format(res, 0.00001, "fir_filter 2")) end undo_edit close_sound(ind) # ind = new_sound("test.snd", 1, 22050, Mus_bfloat, Mus_next, "ramp re-order tests", 100) map_channel(lambda do |y| 1.0 end) [["ramp-xramp", true, lambda do env_sound([0, 0, 1, 1, 2, 0]) env_sound([0, 0, 1, 1], 0, 100, 2.0) end, lambda do env_sound([0, 0, 1, 1], 0, 100, 2.0) env_sound([0, 0, 1, 1, 2, 0]) end], ["ramp2-xramp (1)", true, lambda do env_sound([0, 0, 1, 1, 2, 0]) env_sound([0, 0, 1, 1, 3, 0]) env_sound([0, 0, 1, 1], 0, 100, 2.0) end, lambda do env_sound([0, 0, 1, 1, 2, 0]) env_sound([0, 0, 1, 1], 0, 100, 2.0) env_sound([0, 0, 1, 1, 3, 0]) end], ["ramp2-xramp (2)", true, lambda do env_sound([0, 0, 1, 1, 2, 0]) env_sound([0, 0, 1, 1]) env_sound([0, 0, 1, 1, 3, 0], 0, 100, 2.0) end, lambda do env_sound([0, 0, 1, 1, 3, 0], 0, 100, 2.0) env_sound([0, 0, 1, 1, 2, 0]) env_sound([0, 0, 1, 1]) end], ["xramp2-ramp (1)", true, lambda do env_sound([0, 0, 1, 1, 2, 0], 0, 100, 2.0) env_sound([0, 0, 1, 1]) env_sound([0, 0, 1, 1, 3, 0], 0, 100, 3.0) end, lambda do env_sound([0, 0, 1, 1, 2, 0], 0, 100, 2.0) env_sound([0, 0, 1, 1, 3, 0], 0, 100, 3.0) env_sound([0, 0, 1, 1]) end], ["xramp2-ramp (2)", true, lambda do env_sound([0, 0, 1, 1, 2, 0], 0, 100, 2.0) env_sound([0, 0, 1, 1, 3, 0]) env_sound([0, 0, 1, 1], 0, 100, 3.0) end, lambda do env_sound([0, 0, 1, 1, 3, 0]) env_sound([0, 0, 1, 1, 2, 0], 0, 100, 2.0) env_sound([0, 0, 1, 1], 0, 100, 3.0) end], ["ramp4", true, lambda do env_sound([0, 0, 1, 1]) env_sound([0, 0, 1, 1, 2, 0]) env_sound([0, 0, 1, 1, 3, 0]) env_sound([0, 0, 1, 1, 4, 0]) end, lambda do env_sound([0, 0, 1, 1, 4, 0]) env_sound([0, 0, 1, 1, 2, 0]) env_sound([0, 0, 1, 1, 3, 0]) env_sound([0, 0, 1, 1]) end]].each do |name, try_scale, f1, f2| edpos = edit_position(ind, 0) f1.call v1 = channel2vct(0, 100, ind, 0) set_edit_position(edpos, ind, 0) f2.call v2 = channel2vct(0, 100, ind, 0) snd_test_neq(v1, v2, "env reordering test %s", name) set_edit_position(edpos, ind, 0) if try_scale scale_by(2.0) f1.call v1 = channel2vct(0, 100, ind, 0) set_edit_position(edpos, ind, 0) f2.call scale_by(2.0) v2 = channel2vct(0, 100, ind, 0) snd_test_neq(v1, v2, "scaled (2) env reordering test %s", name) set_edit_position(edpos, ind, 0) f1.call scale_by(0.5) v1 = channel2vct(0, 100, ind, 0) set_edit_position(edpos, ind, 0) scale_by(0.5) f2.call v2 = channel2vct(0, 100, ind, 0) snd_test_neq(v1, v2, "scaled (0.5) env reordering test %s", name) set_edit_position(edpos, ind, 0) end end close_sound(ind) # offset channel ind = new_sound("test.snd", 1, 22050, Mus_bfloat, Mus_next, "offset tests", 10) offset_channel(0.1) snd_test_neq(channel2vct(0, 10), Vct.new(10, 0.1), "offset_channel (0.1)") offset_channel(-0.2, 5, 5) snd_test_neq(channel2vct(0, 10), vct(0.1, 0.1, 0.1, 0.1, 0.1, -0.1, -0.1, -0.1, -0.1, -0.1), "offset_channel (-0.1)") undo_edit offset_channel(0.9, 0, 10, ind, 0) snd_test_neq(channel2vct(0, 10), Vct.new(10, 1.0), "offset_channel (1.0)") revert_sound(ind) # sine_env and sine_ramp... map_channel($init_channel) sine_ramp(0.0, 1.0) snd_test_neq(channel2vct, vct(0.000, 0.024, 0.095, 0.206, 0.345, 0.500, 0.655, 0.794, 0.905, 0.976), "sine_ramp 0 1") revert_sound(ind) offset_channel(1.0) sine_ramp(1.0, 0.0) snd_test_neq(channel2vct, vct(1.000, 0.976, 0.905, 0.794, 0.655, 0.500, 0.345, 0.206, 0.095, 0.024), "sine_ramp 1 0") close_sound(ind) # ind = new_sound("test.snd", 1, 22050, Mus_bfloat, Mus_next, "sine_env tests", 100) # map_channel($init_channel) map_channel(lambda do |y| 1.0 end) sine_env_channel([0, 0, 1, 1, 2, -0.5, 3, 1]) snd_test_neq(channel2vct(20, 10), vct(0.664, 0.708, 0.750, 0.790, 0.827, 0.862, 0.893, 0.921, 0.944, 0.964), "sine_env_channel 0a") snd_test_neq(channel2vct(60, 10), vct(-0.381, -0.417, -0.446, -0.47, -0.486, -0.497, -0.5, -0.497, -0.486, -0.47), "sine_env_channel 0b") snd_test_neq(edit_position(ind, 0), 2, "as_one_edit sine_env_channel") revert_sound(ind) offset_channel(-1.0) sine_env_channel([0, 0, 1, 1, 2, 1, 3, 0], 40, 20) snd_test_neq(channel2vct(40, 20), vct(0, -0.05, -0.188, -0.389, -0.611, -0.812, -0.95, -1, -1, -1, -1, -1, -1, -1, -1, -0.95, -0.812, -0.611, -0.389, -0.188), "off+sine_env a") snd_test_neq(channel2vct(30, 10), make_vct(10, -1.0), "off+sine_env b") revert_sound(ind) scale_by(0.0) dither_channel mx = maxamp if mx < 0.00003 or mx > 0.0001 snd_display("dithering: %s", mx) end revert_sound(ind) map_channel(ring_mod(10, [0, 0, 1, hz2radians(100)])) osc_formants(0.99, vct(400, 800, 1200), vct(400, 800, 1200), vct(4, 2, 3)) map_channel(zecho(0.5, 0.75, 6, 10.0)) map_channel(flecho(0.5, 0.9)) filtered_env([0, 0, 1, 1, 2, 0]) map_channel(formant_filter(0.99, 2400)) map_channel(comb_filter(0.8, 32)) map_channel(zcomb(0.8, 32, [0, 0, 1, 10])) map_channel(notch_filter(0.8, 32)) ind1 = open_sound("now.snd") select_sound(ind1) snd_test_neq(maxamp, 0.309, "squelch_vowels init") squelch_vowels snd_test_neq(maxamp, 0.047, "squelch_vowels maxamp") select_sound(ind) map_channel(cross_synthesis(ind1, 0.5, 128, 6.0)) revert_sound(ind1) fft_edit(40, 8000) fft_squelch(0.1) close_sound(ind) revert_sound(ind1) scramble_channel(0.01) revert_sound(ind1) close_sound(ind1) end def test_05_27 ind = new_sound("test.snd", 1, 22050, Mus_bfloat, Mus_next, "special env tests", 100) map_channel($init_channel) blackman4_ramp(0.0, 1.0) vals = channel2vct undo_edit blackman4_env_channel([0, 0, 1, 1]) unless vequal(res = channel2vct, vals) snd_display("blackman4_env_channel/ramp:\n# %s\n# %s", vals, res) end undo_edit blackman4_ramp(0.0, 1.0, 0, 50) vals = channel2vct undo_edit blackman4_env_channel([0, 0, 1, 1, 2, 1]) unless vequal(res = channel2vct, vals) snd_display("blackman4_env_channel/ramp 1:\n# %s\n# %s", vals, res) end undo_edit blackman4_env_channel([0, 0, 1, 1, 2, -0.5, 3, 0]) unless vequal(res = channel2vct(60, 10), vct(-0.109, -0.217, -0.313, -0.392, -0.451, -0.488, -0.499, -0.499, -0.499, -0.499)) snd_display("blackman4_env_channel to -0.5: %s", res) end undo_edit # ramp_squared(0.0, 1.0) vals = channel2vct() undo_edit env_squared_channel([0, 0, 1, 1]) snd_test_neq(channel2vct(), vals, "env_squared/ramp") undo_edit ramp_squared(0.0, 1.0, true, 0, 50) vals = channel2vct undo_edit env_squared_channel([0, 0, 1, 1, 2, 1]) snd_test_neq(channel2vct(), vals, "env_squared/ramp 1") undo_edit env_squared_channel([0, 0, 1, 1, 2, -0.5, 3, 0]) req = vct(-0.450, -0.466, -0.478, -0.488, -0.494, -0.499, -0.500, -0.500, -0.498, -0.496) snd_test_neq(channel2vct(60, 10), req, "env_squared to -0.5") undo_edit env_squared_channel([0, 0, 1, 1, 2, -0.5, 3, 0], false) req = vct(-0.004, -0.080, -0.158, -0.240, -0.324, -0.410, -0.500, -0.500, -0.498, -0.496) snd_test_neq(channel2vct(60, 10), req, "env_squared unsymmetric to -0.5") undo_edit # ramp_squared(0.0, 1.0) vals = channel2vct undo_edit env_expt_channel([0, 0, 1, 1], 2) unless vequal(res = channel2vct, vals) snd_display("env_expt2/ramp:\n# %s\n# %s", vals, res) end undo_edit env_squared_channel([0, 0, 1, 1, 2, -0.5, 3, 0]) vals = channel2vct undo_edit env_expt_channel([0, 0, 1, 1, 2, -0.5, 3, 0], 2.0) unless vequal(res = channel2vct, vals) snd_display("env_expt2/env_squared:\n# %s\n# %s", vals, res) end undo_edit env_squared_channel([0, 0, 1, 1, 2, -0.5, 3, 0], false) vals = channel2vct undo_edit env_expt_channel([0, 0, 1, 1, 2, -0.5, 3, 0], 2.0, false) unless vequal(res = channel2vct, vals) snd_display("env_expt2/env_squared unsymmetric:\n# %s\n# %s", vals, res) end undo_edit # ramp_expt(0.0, 1.0, 32.0) vals = channel2vct() undo_edit env_expt_channel([0, 0, 1, 1], 32.0) snd_test_neq(channel2vct(), vals, "env_expt/ramp 32") undo_edit ramp_expt(0.0, 1.0, 32.0, false, 0, 50) vals = channel2vct() undo_edit env_expt_channel([0, 0, 1, 1, 2, 1], 32.0) snd_test_neq(channel2vct(), vals, "env_expt/ramp 1 32") undo_edit ramp_expt(0.0, 1.0, 0.1) vals = channel2vct() undo_edit env_expt_channel([0, 0, 1, 1], 0.1) snd_test_neq(channel2vct(), vals, "env_expt/ramp 0.1") undo_edit env_expt_channel([0, 0, 1, 1, 2, -0.5, 3, 0], 12.0) req = vct(0.319, 0.472, 0.691, 1.000, 0.537, 0.208, -0.022, -0.182, -0.291, -0.365) snd_test_neq(channel2vct(30, 10), req, "env_expt to -0.5 12.0") undo_edit env_expt_channel([0, 0, 1, 1, 2, -0.5, 3, 0], 12.0, false) req = vct(0.319, 0.472, 0.691, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000) snd_test_neq(channel2vct(30, 10), req, "env_expt ot -0.5 12.0 unsymmetric") undo_edit close_sound(ind) # ind0 = open_sound("oboe.snd") ind1 = open_sound("pistol.snd") if res = channel_clipped?(ind0, 0) snd_display("channel_clipped? oboe.snd: %s?", res) end scale_to(1.5, ind0, 0) req = 4503 res = channel_clipped?(ind0, 0) if res != req snd_display("channel_clipped? after scale: res %s != req %s?", res, req) end revert_sound(ind0) 4.times do ramp_channel(0.0, 1.0, 0, false, ind1, 0) end make_selection(1000, 2000, ind1, 0) set_sync(1, ind0) set_selected_sound(ind0) env_selection([0, 0, 1, 1]) if (res0 = edit_position(ind0, 0)) != 0 or (res1 = edit_position(ind1)) != 5 snd_display("selection override of sync field: %s %s?", res0, res1) end env_sound([0, 0, 1, 1, 2, 0]) if (res0 = edit_position(ind0, 0)) != 1 or (res1 = edit_position(ind1)) != 5 snd_display("sync field over selection: %s %s?", res0, res1) end close_sound(ind0) close_sound(ind1) end def test_05 $clmtest = 0 test_05_00 if $with_test_gui # no set_x_axis_label test_05_01 test_05_02 test_05_03 test_05_04 test_05_05 test_05_06 test_05_07 test_05_08 test_05_09 test_05_10 if $with_test_gui test_05_11 test_05_12 if $with_test_gui test_05_13 test_05_14 if $with_test_gui test_05_15 test_05_16 test_05_17 test_05_18 test_05_20 test_05_22 test_05_23 if $with_test_gui # load("s61.rb") -> set_transform_size(0) test_05_24 test_05_25 test_05_26 test_05_27 end # ---------------- test 06: vcts ---------------- def test_06 # setting print_length (12) and vct_print_length (10) to the same size set_print_length(print_length) # v0 = make_vct(10) v1 = Vct.new(10) vlst = make_vct(3) snd_test_neq(vct?(v0), true, "v0 is not a vct?") snd_test_neq(v0.kind_of?(Vct), true, "v0 is not kind_of? Vct?") snd_test_eq(v0, 10, "v0 is 10") snd_test_neq(vct?(10), false, "10 is a vct?") snd_test_neq(v0.length, 10, "Vct#length") vct_fill!(v0, 1.0) v1.fill(0.5) if v0.eql?(v1) snd_format_eq(v0, v1, "Vct#eql?") end if v0 == v1 snd_format_eq(v0, v1, "Vct#==") end v2 = v1 v3 = Vct.new(10) v4 = make_vct(3) unless v1.eql?(v2) snd_format_neq(v1, v2, "not Vct#eql? (1)") end vct_fill!(v3, 0.5) unless v2.eql?(v1) snd_format_neq(v2, v1, "not Vct#eql? (2)") end if v4.eql?(v1) snd_format_eq(v4, v1, "len diff Vct#eql?") end vct_set!(v3, 0, 1.0) snd_test_neq(vct_ref(v3, 0), 1.0, "vct_set!") v3[0] = 1.0 snd_test_neq(v3[0], 1.0, "Vct#[]=") vlst[1] = 0.1 snd_test_neq(vct2list(vlst), [0.0, 0.1, 0.0], "vct2list") vect = [0.0, 1.0, 2.0, 3.0] v123 = vct(0.0, 1.0, 2.0, 3.0) v2 = vect.to_vct v3 = v2 str = format("%s", v2.to_s) str1 = format("%s", make_vct(32).to_s) snd_test_neq(vct?(vector2vct(make_array(0))), true, "vector2vct empty vect") snd_test_neq(vct?(make_array(0).to_vct), true, "make_array(0).to_vct empty vect") snd_test_neq(str, "#", "Vct#to_s") snd_test_neq(v123, v2, "vector2vct") snd_test_neq(vct2vector(v123), vect, "vct2vector") snd_test_neq(v123.to_a, vect, "Vct#to_a") unless v3.eql?(v2) snd_format_neq(v3, v2, "Vct#eql?") end snd_test_neq(v2.length, 4, "vector2vct#length") snd_test_neq(v2[2], 2.0, "vector2vct[2]") vct_move!(v2, 0, 2) snd_test_neq(v2[0], 2.0, "vct_move!") v2 = Vct.new(4) do |i| i end v2.move!(3, 2, true) snd_test_neq(v2[2], 1.0, "Vct#move! back (1)") snd_test_neq(v2[3], 2.0, "Vct#move! back (2)") snd_test_neq(vct(3, 2, 1), vct_reverse!(vct(1, 2, 3)), "vct_reverse!") snd_test_neq(vct(3, 2, 1), vct(1, 2, 3).reverse, "Vct#reverse") snd_test_neq(vct(2, 1), vct_reverse!(vct(1, 2)), "vct_reverse!") snd_test_neq(vct(1), vct(1).reverse, "vct(1)#reverse") snd_test_neq(vct(4, 3, 2, 1), vct(1, 2, 3, 4).reverse(4), "Vct#reverse(4)") snd_test_neq(vct(3, 2, 1), vct_reverse!(vct(1, 2, 3), 3), "vct_reverse(3)") snd_test_neq(vct(2, 1), vct(1, 2).reverse(2), "Vct#reverse(2)") snd_test_neq(vct(1), vct_reverse!(vct(1), 1), "vct_reverse!(1)") # vv0 = Vct.new(3) snd_test_neq(Snd.catch do vct_ref(vv0, 10) end.first, :out_of_range, "vct_ref high index") snd_test_neq(Snd.catch do vv0[-4] end.first, :out_of_range, "Vct#[] low index") snd_test_neq(Snd.catch do vct_set!(vv0, 10, 1.0) end.first, :out_of_range, "vct_set! high index") snd_test_neq(Snd.catch do vv0[-1] = 1.0 end.first, :out_of_range, "Vct#[]= low index") snd_test_neq(Snd.catch do vct_move!(vv0, 10, 0, true) end.first, :out_of_range, "vct_move! high index") snd_test_neq(Snd.catch do vv0.move(0, 10, true) end.first, :out_of_range, "Vct#move high 2 index") snd_test_neq(Snd.catch do vct_move!(vv0, -10, 0, false) end.first, :out_of_range, "vct_move! back high index") snd_test_neq(Snd.catch do vv0.move!(0, -10, false) end.first, :out_of_range, "Vct#move! back high 2 index") 10.times do |i| snd_test_neq(v0[i], 1.0, "fill v0[%d]", i) snd_test_neq(v1[i], 0.5, "preset v1[%d]", i) end # add v0.add(v1).each_with_index do |x, i| snd_test_neq(x, 1.5, "Vct#add[%d]", i) end (v0 + v1).each_with_index do |x, i| snd_test_neq(x, 1.5, "Vct#+[%d]", i) end vct_add!(v0, v1) v0.each_with_index do |x, i| snd_test_neq(x, 1.5, "vct_add![%d]", i) end # subtract v0.subtract(v1).each_with_index do |x, i| snd_test_neq(x, 1.0, "Vct#subtract[%d]", i) end (v0 - v1).each_with_index do |x, i| snd_test_neq(x, 1.0, "Vct#-[%d]", i) end vct_subtract!(v0, v1) v0.each_with_index do |x, i| snd_test_neq(x, 1.0, "vct_subtract![%d]", i) end # dup, vct_copy v0.dup.each_with_index do |x, i| snd_test_neq(x, 1.0, "Vct#dup[%d]", i) end v2 = vct_copy(v0) v2.each_with_index do |x, i| snd_test_neq(x, 1.0, "vct_copy[%d]", i) end # scale v2.scale(5.0).each_with_index do |x, i| snd_test_neq(x, 5.0, "Vct#scale[%d]", i) end (v2 * 5.0).each_with_index do |x, i| snd_test_neq(x, 5.0, "Vct#*[%d]", i) end vct_scale!(v2, 5.0) v2.each_with_index do |x, i| snd_test_neq(x, 5.0, "vct_scale![%d]", i) end # offset v0.offset(-1.0).each_with_index do |x, i| snd_test_neq(x, 0.0, "Vct#offset[%d]", i) end (v0 + -1.0).each_with_index do |x, i| snd_test_neq(x, 0.0, "Vct#+[%d]", i) end vct_offset!(v0, -1.0) v0.each_with_index do |x, i| snd_test_neq(x, 0.0, "vct_offset![%d]", i) end # multiply v2.multiply(v1).each_with_index do |x, i| snd_test_neq(x, 2.5, "Vct#multiply[%d]", i) end (v2 * v1).each_with_index do |x, i| snd_test_neq(x, 2.5, "Vct#*[%d]", i) end vct_multiply!(v2, v1) v2.each_with_index do |x, i| snd_test_neq(x, 2.5, "vct_multiply![%d]", i) end # snd_test_neq(vct_peak(v2), 2.5, "vct_peak (1)") snd_test_neq(v2.peak, 2.5, "Vct#peak (1)") v2[5] = 123.0 snd_test_neq(vct_peak(v2), 123.0, "vct_peak (2)") snd_test_neq(v2.peak, 123.0, "Vct#peak (2)") vn = Vct.new(32) do |i| i end vb = make_vct(64) vs = make_vct(3) vss = Vct.new(1) vnew = vct_subseq(vn, 3) snd_test_neq(vnew[0], 3.0, "vct_subseq[3:]") snd_test_neq(vnew.length, 29, "vct_subseq[3:] length") vnew = vn.subseq(3, 8) snd_test_neq(vnew[0], 3.0, "Vct#subseq[3:8]") snd_test_neq(vnew.length, 6, "Vct#subseq[3:8] length") vct_subseq(vn, 3, 3, vs) snd_test_neq(vs[0], 3.0, "vct_subseq[3:3->vs] (1)") snd_test_neq(vs[1], 0.0, "vct_subseq[3:3->vs] (2)") snd_test_neq(vs[2], 0.0, "vct_subseq[3:3->vs] (3)") vn.subseq(0, 32, vs) snd_test_neq(vs.length, 3, "Vct#subseq[:32->vs] length") vn.subseq(2, 3, vss) snd_test_neq(vss[0], 2.0, "Vct#subseq[2:3->vss]") vb[8] = 123.0 vct_subseq(vn, 1, 8, vb) snd_test_neq(vb[0], 1.0, "vct_subseq[1:8->vb][0]") snd_test_neq(vb[8], 123.0, "vct_subseq[1:8->vb][8]") # vct_add, vct_multiply (vct+, vct*) v1 = Vct.new(3, 0.1) v2 = make_vct(4, 0.2) snd_test_neq(vct_add(v1.dup, v2), vct(0.3, 0.3, 0.3), "vct_add 0.1 0.2") snd_test_neq(v1 + v2, vct(0.3, 0.3, 0.3), "Vct#+ 0.1 0.2") v1[1] = 0.3 snd_test_neq(vct_add(v1.dup, v2), vct(0.3, 0.5, 0.3), "vct_add 0.1 0.2 (1)") snd_test_neq(v1 + v2, vct(0.3, 0.5, 0.3), "Vct#+ 0.1 0.2 (1)") snd_test_neq(vct_add(v1.dup, 2.0), vct(2.1, 2.3, 2.1), "vct_add 0.1 2.0") snd_test_neq(v1 + 2.0, vct(2.1, 2.3, 2.1), "Vct#+ 0.1 2.0") snd_test_neq(vct_add(2.0, v1.dup), vct(2.1, 2.3, 2.1), "vct_add 0.1 2.0 (1)") snd_test_neq(2.0 + v1, vct(2.1, 2.3, 2.1), "2.0#+(v1) 0.1 2.0 (1)") snd_test_neq(vct_multiply(2.0, v1.dup), vct(0.2, 0.6, 0.2), "vct_multiply 2") snd_test_neq(2.0 * v1, vct(0.2, 0.6, 0.2), "2.0#*(v1)") snd_test_neq(vct_multiply(v1.dup, 2.0), vct(0.2, 0.6, 0.2), "vct_multiply 2 (1)") snd_test_neq(v1 * 2.0, vct(0.2, 0.6, 0.2), "Vct#* 2 (1)") snd_test_neq(vct_multiply(v1.dup, v2), vct(0.02, 0.06, 0.02), "vct_multiply v1 v2") snd_test_neq(v1 * v2, vct(0.02, 0.06, 0.02), "Vct#*(v2)") # v0.map do |val| PI end.each_with_index do |x, i| snd_test_neq(x, PI, "Vct#map[%d]", i) end v0.map! do |x| 1.0 end v0.each_with_index do |x, i| snd_test_neq(x, 1.0, "Vct#map[%d] 1.0", i) end # snd_test_neq(vct(1.0, 2.0, 3.0)[1], 2.0, "vct(...)[1]") v1 = [1, 2, 3, 4].to_vct snd_test_neq(v1[1], 2.0, "Vct#[1]") # ind = open_sound("oboe.snd") set_speed_control(0.5, ind) play(selected_sound, :wait, true) apply_controls revert_sound reset_controls(ind) # # try some special cases # apply_controls snd_test_neq(edit_position(ind), 0, "apply_controls with no change") set_speed_control(-1.0, ind) apply_controls if $with_test_gui snd_test_neq(edit_position(ind), 1, "apply_controls with srate -1.0") end if ((res0 = framples(ind, 0)) - (res1 = framples(ind, 0, 0))).abs > 2 snd_display("apply_controls srate -1.0 lengths: %s %s", res0, res1) end res1 = sample(9327) if fneq(res0 = maxamp, 0.147) or res1.abs < 0.01 snd_display("apply_controls srate -1.0 samples: %s %s?", res0, res1) end snd_test_neq(speed_control(ind), 1.0, "apply_controls -1.0") set_speed_control(1.5) apply_controls revert_sound set_speed_control(1.5) $after_apply_controls_hook.add_hook!("snd-test") do |s| snd_test_neq(Snd.catch do apply_controls() end.first, :cannot_apply_controls, "after_apply_controls_hook: recursive attempt apply_controls") end apply_controls $after_apply_controls_hook.reset_hook! revert_sound close_sound(ind) # # Vct.new.map twice, and Vct.new twice # v1 = Vct.new(32) v1.map! do v2 = Vct.new(3) v2.map! do 0.1 end v2.first end snd_test_neq(v1[12], 0.1, "v.map! twice") Vct.new(32) do Vct.new(3) do 0.1 end.first end snd_test_neq(v1[12], 0.1, "v.new twice") hi = make_vct(3) snd_test_neq(Snd.catch do vct_subseq(hi, 1, 0) end.first, :out_of_range, "vct_subseq 1 0") snd_test_neq(vct?(vct()), true, "vct() not a vct") snd_test_neq(vct?(make_vct(0)), true, "make_vct(0) not a vct") v0 = make_vct(5, 0.1) v1 = make_vct(6, 0.2) v0.add!(v1, 2) snd_test_neq(v0, [0.1, 0.1, 0.3, 0.3, 0.3].to_vct, "v.add! + offset") # # vct methods # snd_test_neq(Vct.new(10), make_vct(10), "Vct#new 0.000") snd_test_neq(Vct.new(10, 3.14), make_vct(10, 3.14), "Vct#new 3.140") v1 = Vct.new(10) do |i| i * 0.01 end v2 = make_vct(10) ctr = -1 v2.map! do |x| (ctr += 1) * 0.01 end snd_test_neq(v1, v2, "Vct#new 0.000 0.010 0.020...") snd_test_neq(vct_ref(v1, 8), v2[8], "Vct#[] (1)") snd_test_neq(v2[8], 0.08, "Vct#[] (2)") vct_set!(v1, 8, 0.5) v2[8] = 0.5 snd_test_neq(vct_ref(v1, 8), v2[8], "Vct#[]= (1)") snd_test_neq(v2[8], 0.5, "Vct#[]= (2)") snd_test_neq(v1.length, vct_length(v2), "Vct#length (1)") snd_test_neq(v2.length, vct_length(v1), "Vct#length (2)") snd_test_neq(v2.length, 10, "Vct#length (3)") v1.each_with_index do |val, i| snd_test_neq(val, v2[i], "Vct#each (%d)", i) end snd_test_neq(v1 <=> v2, 0, "Vct#<=> (0)") snd_test_neq(Vct.new(10) do |i| i * 0.001 end <=> v1, -1, "Vct#<=> (-1)") snd_test_neq(v2 <=> Vct.new(10) do |i| i * 0.001 end, 1, "Vct#<=> (1)") v2.map! do |val| val + 0.5 end v3 = v1.map do |val| val + 0.5 end snd_test_neq(v2, v3, "Vct#map(!)") v2 = v1.dup snd_test_neq(v1 <=> v2, 0, "Vct#dup") vec1 = make_array(10) do |i| i * 0.01 end vec1[8] = 0.5 vec2 = v2.to_a snd_test_neq(vec1, vec2, "Vct#to_a") snd_test_neq(vec1.to_vct, v1, "Array#to_vct") snd_test_neq(vct2string(v1), v2.to_str, "Vct#to_str") snd_test_neq(v2.to_str, "\ vct(0.000, 0.010, 0.020, 0.030, 0.040, 0.050, 0.060, 0.070, 0.500, 0.090)", "Vct#to_str") snd_test_neq(v1.peak, vct_peak(v2), "Vct#peak") v3 = v1.dup v3.add!(v2) v4 = v1.add(v2) snd_test_neq(v3, v4, "Vct#add(!)") v3 = v1.dup v3.subtract!(v2) v4 = v1.subtract(v2) snd_test_neq(v3, v4, "Vct#subtract(!)") v3 = v1.dup v3.multiply!(v2) v4 = v1.multiply(v2) snd_test_neq(v3, v4, "Vct#multiply(!)") v3 = v1.dup v3.offset!(0.5) v4 = v1.offset(0.5) snd_test_neq(v3, v4, "Vct#offset(!)") v3 = v1.dup v3.scale!(2.0) v4 = v1.scale(2.0) snd_test_neq(v3, v4, "Vct#scale(!)") v3 = Vct.new(10) v4 = Vct.new(10) v3.fill(0.5) vct_fill!(v4, 0.5) snd_test_neq(v3, v4, "Vct#fill(!)") snd_test_neq(v1.first, vct_ref(v2, 0), "Vct#first") snd_test_neq(v1.last, vct_ref(v2, vct_length(v2) - 1), "Vct#last") v1.first = 0.2 vct_set!(v2, 0, 0.2) snd_test_neq(v1.first, vct_ref(v2, 0), "Vct#first (2)") snd_test_neq(v1.first, 0.2, "Vct#first (3)") v1.last = 0.3 vct_set!(v2, vct_length(v2) - 1, 0.3) snd_test_neq(v1.last, vct_ref(v2, vct_length(v2) - 1), "Vct#last (2)") snd_test_neq(v1.last, 0.3, "Vct#last (3)") end # ---------------- test 07: colors ---------------- def test_07_00 c1 = Snd.catch(:no_such_color, false) do make_color(0, 0, 1) end.first c2 = c1 c3 = Snd.catch(:no_such_color, false) do make_color(0, 0, 1) end.first unless c1.equal?(c2) snd_display("color equal? %s %s", c1, c2) end unless c1.eql?(c2) snd_display("color eql? %s %s", c1, c2) end unless c1 == c2 snd_display("color == %s %s", c1, c2) end if (res = color2list(c1)) != [0.0, 0.0, 1.0] snd_display("color2list: %s %s?", c1, res) end true_color_list = [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 1.0, 1.0], [0.0, 0.0, 7.01915007248035e-4], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.49999], [1.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 0.0, 1.0], [1.0, 0.0, 1.0], [0.0, 0.500007629510948, 0.4], [1.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 0.0, 1.0]] 15.times do |i| cm = integer2colormap(i) if colormap?(cm) res0 = colormap_ref(cm, 0) res1 = true_color_list[i] unless vequal(res0, res1) snd_display("colormap_ref[%s]: %s (%s)", cm, res0, res1) end end end Snd.catch do [[:basic_color, Ivory2], [:cursor_color, Red], [:data_color, Black], [:enved_waveform_color, Blue], [:filter_control_waveform_color, Blue], [:graph_color, White], [:highlight_color, Ivory1], [:listener_color, Alice_blue], [:listener_text_color, Black], [:mark_color, Red], [:mix_color, Dark_gray], [:position_color, Ivory3], [:sash_color, Light_green], [:selected_data_color, Black], [:selected_graph_color, White], [:selection_color, Lightsteelblue1], [:text_focus_color, White], [:zoom_color, Ivory4]].each do |getfnc, initval| unless color?(initval) snd_display("%s not color?", initval) end set_snd_func(getfnc, Beige) if (res = snd_func(getfnc)) != Beige snd_display("set_%s != Beige (%s)?", getfnc, res) end set_snd_func(getfnc, initval) end ind = open_sound("oboe.snd") set_selected_data_color(Light_green) set_data_color(Blue) set_selected_graph_color(Light_green) if $with_test_motif red = make_color_with_catch(1.0, 0.0, 0.0) set_foreground_color(red, ind, 0, Cursor_context) if (res = foreground_color(ind, 0, Cursor_context)) != red snd_display("set_foreground_color cursor: %s %s?", res, red) end set_foreground_color(Blue) if (res = foreground_color) != Blue snd_display("set_foreground_color: %s %s?", res, Blue) end set_foreground_color(Red, ind) if (res = foreground_color(ind)) != Red snd_display("set_foreground_color with ind (Red): %s %s?", res, Red) end set_foreground_color(Black, ind) if (res = foreground_color(ind)) != Black snd_display("set_foreground_color with ind (Black): %s %s?", res, Black) end end set_selected_graph_color(make_color_with_catch(0.96, 0.96, 0.86)) set_data_color(Black) set_selected_data_color(Blue) set_data_color(White) close_sound(ind) end end def check_colormap(name, colmap, x, r, g, b, n, err) r1, g1, b1 = colormap_ref(colmap, x) if x < (1.0 - (1.0 / n)) and (fneq_err(r, r1, err) or fneq_err(g, g1, err) or fneq_err(b, b1, err)) snd_display_prev_caller("%s %1.4f (%1.4f): %s %s", name, x, [(r - r1).abs, (g - g1).abs, (b - b1).abs].max, [r, g, b], [r1, g1, b1]) end end def test_07_01 [[512, 0.005], [64, 0.04]].each do |n, err| set_colormap_size(n) 10.times do |i| x = random(1.0) r = (x < (3.0 / 4)) ? ((7.0 / 8) * x) : ((11.0 / 8) * x - 3.0 / 8) g = (x < (3.0 / 8)) ? ((7.0 / 8) * x) : ((x < (3.0 / 4)) ? ((29.0 / 24) * x - 1.0 / 8) : ((7.0 / 8) * x + 1.0 / 8)) b = (x < (3.0 / 8)) ? ((29.0 / 24) * x) : ((7.0 / 8) * x + 1.0 / 8) check_colormap("bone", $bone_colormap, x, r, g, b, n, err) end 10.times do |i| x = random(1.0) r = (x < (4.0 / 5)) ? ((5.0 / 4) * x) : 1.0 g = (4.0 / 5) * x b = (1.0 / 2) * x check_colormap("copper", $copper_colormap, x, r, g, b, n, err) end 10.times do |i| x = random(1.0) r = 0.0 g = x b = 1.0 - g / 2.0 check_colormap("winter", $winter_colormap, x, r, g, b, n, err) end 10.times do |i| x = random(1.0) r = 1.0 g = x b = 0.0 check_colormap("autumn", $autumn_colormap, x, r, g, b, n, err) end 10.times do |i| x = random(1.0) r = x g = 1.0 - r b = 1.0 check_colormap("cool", $cool_colormap, x, r, g, b, n, err) end 10.times do |i| x = random(1.0) r = (x < (3.0 / 8)) ? ((8.0 / 3) * x) : 1.0 g = (x < (3.0 / 8)) ? 0.0 : ((x < (3.0 / 4)) ? ((8.0 / 3) * x - 1.0) : 1.0) b = (x < (3.0 / 4)) ? 0.0 : (4.0 * x - 3) check_colormap("hot", $hot_colormap, x, r, g, b, n, err) end 10.times do |i| x = random(1.0) r = (x < (3.0 / 8)) ? 0.0 : ((x < (5.0 / 8)) ? (4.0 * x - 3.0 / 2) : ((x < (7.0 / 8)) ? 1.0 : (-4.0 * x + 9.0 / 2))) g = (x < (1.0 / 8)) ? 0.0 : ((x < (3.0 / 8)) ? (4.0 * x - 0.5) : (((x < (5.0 / 8)) ? 1.0 : ((x < (7.0 / 8)) ? (-4.0 * x + 7.0 / 2) : 0.0)))) b = (x < (1.0 / 8)) ? (4.0 * x + 0.5) : ((x < (3.0 / 8)) ? 1.0 : ((x < (5.0 / 8)) ? (-4.0 * x + 5.0 / 2) : 0.0)) check_colormap("jet", $jet_colormap, x, r, g, b, n, err) end 10.times do |i| x = random(1.0) r = (x < (3.0 / 8)) ? ((14.0 / 9) * x) : ((2.0 / 3) * x + 1.0 / 3) g = (x < (3.0 / 8)) ? ((2.0 / 3) * x) : ((x < (3.0 / 4)) ? ((14.0 / 9) * x - 1.0 / 3) : ((2.0 / 3) * x + 1.0 / 3)) b = (x < (3.0 / 4)) ? ((2.0 / 3) * x) : (2.0 * x - 1.0) check_colormap("pink", $pink_colormap, x, r, g, b, n, err) end 10.times do |i| x = random(1.0) r = 1.0 g = x b = 1.0 - g check_colormap("spring", $spring_colormap, x, r, g, b, n, err) end 10.times do |i| x = random(1.0) r = x g = x b = x check_colormap("gray", $gray_colormap, x, r, g, b, n, err) end 10.times do |i| x = random(1.0) r = 0.0 g = 0.0 b = 0.0 check_colormap("black_and_white", $black_and_white_colormap, x, r, g, b, n, err) end 10.times do |i| x = random(1.0) r = x g = 0.5 + r / 2.0 b = 0.4 check_colormap("summer", $summer_colormap, x, r, g, b, n, err) end 10.times do |i| x = random(1.0) r = (x < (2.0 / 5)) ? 1.0 : ((x < (3.0 / 5)) ? (-5.0 * x + 3) : ((x < (4.0 / 5)) ? 0.0 : (10.0 / 3 * x - 8.0 / 3))) g = (x < (2.0 / 5)) ? ((5.0 / 2) * x) : ((x < (3.0 / 5)) ? 1.0 : ((x < (4.0 / 5)) ? (-5.0 * x + 4) : 0.0)) b = (x < (3.0 / 5)) ? 0.0 : ((x < (4.0 / 5)) ? (5.0 * x - 3) : 1.0) check_colormap("rainbow", $rainbow_colormap, x, r, g, b, n, err) end 10.times do |i| x = random(1.0) rgb = colormap_ref($prism_colormap, x) if x < 1.0 - 1.0 / n and (not vequal(rgb, [1.0, 0.0, 0.0])) and (not vequal(rgb, [1.0, 0.5, 0.0])) and (not vequal(rgb, [1.0, 1.0, 0.0])) and (not vequal(rgb, [0.0, 1.0, 0.0])) and (not vequal(rgb, [0.0, 0.0, 1.0])) and (not vequal(rgb, [0.6667, 0.0, 1.0])) snd_display("prism %s", rgb) end end 10.times do |i| x = random(1.0) rgb = colormap_ref($flag_colormap, x) if x < 1.0 - 1.0 / n and (not vequal(rgb, [1.0, 0.0, 0.0])) and (not vequal(rgb, [1.0, 1.0, 1.0])) and (not vequal(rgb, [0.0, 0.0, 1.0])) and (not vequal(rgb, [0.0, 0.0, 0.0])) snd_display("flag %s", rgb) end end end end def test_07_02(old_colormap_size) ind = add_colormap("white", lambda do |size| [make_vct(size, 1.0), make_vct(size, 1.0), make_vct(size, 1.0)] end) unless res = colormap?(ind) snd_display("add_colormap %s: %s?", ind, res) end unless vequal(res = colormap_ref(ind, 0.5), [1.0, 1.0, 1.0]) snd_display("white colormap: %s?", res) end if (res = Snd.catch do set_colormap(ind) end).first == :no_such_colormap or colormap != ind snd_display("colormap white: %s %s %s", res, ind, colormap) end if (res = colormap_name(ind)) != "white" snd_display("white colormap name: %s?", res) end if (res = Snd.catch do delete_colormap(integer2colormap(1234)) end).first != :no_such_colormap snd_display("delete_colormap 1234: %s?", res) end if (res = Snd.catch do colormap_ref(integer2colormap(1234), 0.5) end).first != :no_such_colormap snd_display("colormap_ref 1234: %s?", res) end res = Snd.catch do colormap_ref(integer2colormap(-1), 0.5) end if res.first != :no_such_colormap and res.first != :wrong_type_arg snd_display("colormap_ref -1: %s?", res) end if (res = Snd.catch do set_colormap(integer2colormap(1234)) end).first != :no_such_colormap snd_display("set_colormap 1234: %s?", res) end res = Snd.catch do set_colormap(integer2colormap(-1)) end if res.first != :no_such_colormap and res.first != :wrong_type_arg snd_display("set_colormap -1: %s?", res) end if (res = Snd.catch do colormap_ref($copper_colormap, 2.0) end).first != :out_of_range snd_display("colormap_ref 2.0: %s?", res) end # set_colormap_size(old_colormap_size) if (res = colormap_size) != old_colormap_size snd_display("set_colormap_size: %s %s?", res, old_colormap_size) end if (res = colormap_name($black_and_white_colormap)) != "black-and-white" snd_display("black-and-white: %s?", res) end if (res = colormap_name($gray_colormap)) != "gray" snd_display("gray: %s?", res) end if (res = colormap_name($rainbow_colormap)) != "rainbow" snd_display("rainbow: %s?", res) end add_colormap("purple", lambda do |size| r = make_vct(size) g = make_vct(size) b = make_vct(size) er = [0, 60, 60, 116, 128, 252, 192, 252, 256, 60] eg = [0, 0, 64, 0, 128, 252, 192, 252, 256, 0] eb = [0, 80, 128, 252, 192, 0, 256, 80] incr = 256.0 / size x = 0.0 size.times do |i| r[i] = envelope_interp(x, er) / 256.0 g[i] = envelope_interp(x, eg) / 256.0 b[i] = envelope_interp(x, eb) / 256.0 x += incr end [r, g, b] end) add_colormap("sin", lambda do |size| r = make_vct(size) g = make_vct(size) b = make_vct(size) incr = (2.0 * PI) / size x = 0.0 size.times do |i| r[i] = sin(1.5 * x).abs g[i] = sin(3.5 * x).abs b[i] = sin(2.5 * x).abs x += incr end [r, g, b] end) add_colormap("another-sin", lambda do |size| r = make_vct(size) g = make_vct(size) b = make_vct(size) incr = (2.0 * PI) / size x = 0.0 size.times do |i| r[i] = sin(2.5 * x).abs g[i] = sin(3.5 * x).abs b[i] = sin(4.5 * x).abs x += incr end [r, g, b] end) [1024, 256, 2, 512].each do |n| set_colormap_size(n) 10.times do |i| x = random(1.0) r = (x < 4.0 / 5) ? ((5.0 / 4) * x) : 1.0 g = (4.0 / 5) * x b = 0.5 * x rgb = colormap_ref($copper_colormap, x) r1, g1, b1 = rgb err = 0.01 if n > 2 and x < (1.0 - (1.0 / n)) and (fneq_err(r, r1, err) or fneq_err(g, g1, err) or fneq_err(b, b1, err)) snd_display("copper size reset %s: %1.4f (%1.4f): %s %s", n, x, [(r - r1).abs, (g - g1).abs, (b - b1).abs].max, [r, g, b], [r1, g1, b1]) end end end set_colormap_size(old_colormap_size) end def test_07 if $with_test_gui old_colormap_size = colormap_size old_colormap = colormap test_07_00 test_07_01 test_07_02(old_colormap_size) set_colormap(old_colormap) end end # ---------------- test 08: clm ---------------- def sweep2bins(flt, bins) ind = open_sound("sweep.snd") if mus_generator?(flt) clm_channel(flt) else map_channel(flt) end mx = maxamp() size = (22050 / bins).round resp = Vct.new(bins) do |i| channel2vct(i * size, size).peak end close_sound(ind) [mx, resp] end def filter_response_max(f1) mx = f1.run(1.0).abs 1000.times do |i| mx = [mx, f1.run(0.0).abs].max end mx end def filter_equal?(f1, f2) f1.order == f2.order and vequal(f1.xcoeffs, f2.xcoeffs) and vequal(f1.ycoeffs, f2.ycoeffs) end def f05equal?(f1, f2) fequal_err(f1, f2, 0.05) end def analog_filter_tests # # Butterworth # poles = [vct(1, 1.414, 1), vct(1, 1.848, 1, 1, 0.765, 1), vct(1, 1.932, 1, 1, 1.414, 1, 1, 0.518, 1), vct(1, 1.962, 1, 1, 1.663, 1, 1, 1.111, 1, 1, 0.390, 1), vct(1, 1.975, 1, 1, 1.782, 1, 1, 1.414, 1, 1, 0.908, 1, 1, 0.313, 1)] k = 0 2.step(11, 2) do |i| vals = butterworth_prototype(i) snd_test_neq(vals[1], poles[k], "butterworth_prototype poles %d", i) len = (k + 1) * 3 zeros = Vct.new(len) 2.step(len, 3) do |j| zeros[j] = 1.0 break if j >= (k + 1) * 3 end snd_test_neq(vals[0], zeros, "butterworth_prototype zeros %d", i) k += 1 end cutoff = 0.1 3.times do |m| k = 1 2.step(16, 2) do |i| local = make_butterworth_lowpass(i, cutoff) dsp = make_butter_lp(k, mus_srate * cutoff) snd_test_any_neq(local, dsp, :filter_equal?, "butterworth lowpass %1.4f", cutoff) local = make_butterworth_highpass(i, cutoff) dsp = make_butter_hp(k, mus_srate * cutoff) snd_test_any_neq(local, dsp, :filter_equal?, "butterworth highpass %1.4f", cutoff) k += 1 end cutoff += 0.1 end # ind = open_sound("oboe.snd") hummer = make_eliminate_hum(550) map_channel(lambda do |x| eliminate_hum(hummer, x) end) peaker = make_peaking_2(500, 1000, 1.0) map_channel(peaker) map_channel(chordalize()) close_sound(ind) # ind = new_sound("sweep.snd", 1, 22050, Mus_bfloat, Mus_next, false, 22050) phase = 0.0 freq = 0.0 incr = PI / 22050.0 map_channel(lambda do |y| val = sin(phase) phase += freq freq += incr val * 0.5 end) save_sound(ind) close_sound(ind) f1 = make_butterworth_lowpass(8, 0.1) vals = sweep2bins(f1, 10) snd_test_neq(vals[0], 0.5, "butterworth lp 8 max") v1 = vct(0.500, 0.500, 0.359, 0.014, 0.001, 0.000, 0.000, 0.000, 0.000, 0.000) snd_test_neq(vals[1], v1, "butterworth lp 8 0.1 spect") f1 = make_butterworth_lowpass(12, 0.25) vals = sweep2bins(f1, 10) snd_test_neq(vals[0], 0.5, "butterworth lp 12 max") v1 = vct(0.500, 0.500, 0.500, 0.500, 0.499, 0.358, 0.010, 0.000, 0.000, 0.000) snd_test_neq(vals[1], v1, "butterworth lp 12 0.25 spect") f1 = make_butterworth_lowpass(10, 0.4) vals = sweep2bins(f1, 10) snd_test_neq(vals[0], 0.5, "butterworth lp 10 max") v0 = vals[1] v1 = vct(0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.499, 0.361, 0.001) v2 = vct(0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.499, 0.360, 0.002) if (not vequal(v0, v1)) and (not vequal(v0, v2)) snd_test_neq(v0, v1, "butterworth lp 10 0.4 spect (v1)") snd_test_neq(v0, v2, "butterworth lp 10 0.4 spect (v2)") end 2.step(12, 2) do |i| 0.1.step(0.35, 0.1) do |j| f1 = make_butterworth_lowpass(i, j) snd_test_gt(filter_response_max(f1), 1.0, "butter low max %d %d", i, j) end end # f1 = make_butterworth_highpass(8, 0.1) vals = sweep2bins(f1, 10) snd_test_neq(vals[0], 0.5, "butterworth hp 8 max") v1 = vct(0.001, 0.348, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500) snd_test_neq(vals[1], v1, "butterworth hp 8 0.1 spect") f1 = make_butterworth_highpass(12, 0.25) vals = sweep2bins(f1, 10) snd_test_neq(vals[0], 0.5, "butterworth hp 12 max") v1 = vct(0.000, 0.000, 0.000, 0.011, 0.348, 0.500, 0.500, 0.500, 0.500, 0.500) snd_test_neq(vals[1], v1, "butterworth hp 12 0.25 spect") f1 = make_butterworth_highpass(10, 0.4) vals = sweep2bins(f1, 10) snd_test_neq(vals[0], 0.5, "butterworth hp 10 max") v1 = vct(0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.005, 0.343, 0.501, 0.501) snd_test_neq(vals[1], v1, "butterworth hp 10 0.4 spect") 2.step(12, 2) do |i| 0.1.step(0.35, 0.1) do |j| f1 = make_butterworth_highpass(i, j) snd_test_gt(filter_response_max(f1), 1.0, "butter high max %d %d", i, j) end end # f1 = make_butterworth_bandpass(4, 0.1, 0.2) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.5, :f05equal?, "butterworth bp 4 max") v1 = vct(0.028, 0.350, 0.481, 0.479, 0.346, 0.132, 0.038, 0.009, 0.002, 0.000) snd_test_neq(vals[1], v1, "butterworth bp 4 0.1 0.2 spect") f1 = make_butterworth_bandpass(12, 0.1, 0.2) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.5, :f05equal?, "butterworth bp 12 max") v1 = vct(0.000, 0.323, 0.501, 0.500, 0.358, 0.009, 0.000, 0.000, 0.000, 0.000) snd_test_neq(vals[1], v1, "butterworth bp 12 0.1 0.2 spect") f1 = make_butterworth_bandpass(8, 0.3, 0.4) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.5, :f05equal?, "butterworth bp 8 max") v1 = vct(0.000, 0.000, 0.000, 0.003, 0.034, 0.344, 0.499, 0.499, 0.353, 0.002) snd_test_neq(vals[1], v1, "butterworth bp 8 0.3 0.4 spect") # f1 = make_butterworth_bandstop(4, 0.1, 0.2) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.5, :f05equal?, "butterworth bs 4 max") v1 = vct(0.500, 0.500, 0.347, 0.339, 0.481, 0.499, 0.500, 0.500, 0.500, 0.500) snd_test_neq(vals[1], v1, "butterworth bs 4 0.1 0.2 spect") f1 = make_butterworth_bandstop(12, 0.1, 0.2) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.5, :f05equal?, "butterworth bs 12 max") v1 = vct(0.500, 0.500, 0.365, 0.334, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500) snd_test_neq(vals[1], v1, "butterworth bs 12 0.1 0.2 spect") f1 = make_butterworth_bandstop(8, 0.3, 0.4) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.5, :f05equal?, "butterworth bs 8 max") v1 = vct(0.500, 0.500, 0.500, 0.500, 0.500, 0.498, 0.354, 0.332, 0.500, 0.500) snd_test_neq(vals[1], v1, "butterworth bs 8 0.3 0.4 spect") # # Chebyshev # # ripple 0.01 0.1 1 for 2..10 even poles_01 = [vct(1, 4.456, 10.426), vct(1, 0.822, 2.006, 1, 1.984, 1.299), vct(1, 0.343, 1.372, 1, 0.937, 0.939, 1, 1.280, 0.506), vct(1, 0.189, 1.196, 1, 0.537, 0.925, 1, 0.804, 0.542, 1, 0.948, 0.272), vct(1, 0.119, 1.121, 1, 0.347, 0.940, 1, 0.540, 0.646, 1, 0.680, 0.352, 1, 0.754, 0.170)] zeros = [vct(0, 0, 1), vct(0, 0, 0.250, 0, 0, 1), vct(0, 0, 0.062, 0, 0, 1, 0, 0, 1), vct(0, 0, 0.016, 0, 0, 1, 0, 0, 1, 0, 0, 1), vct(0, 0, 0.004, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1)] poles_1 = [vct(1, 2.372, 3.314), vct(1, 0.528, 1.330, 1, 1.275, 0.623), vct(1, 0.229, 1.129, 1, 0.627, 0.696, 1, 0.856, 0.263), vct(1, 0.128, 1.069, 1, 0.364, 0.799, 1, 0.545, 0.416, 1, 0.643, 0.146), vct(1, 0.082, 1.044, 1, 0.237, 0.862, 1, 0.369, 0.568, 1, 0.465, 0.274, 1, 0.515, 0.092)] poles_10 = [vct(1, 1.098, 1.103), vct(1, 0.279, 0.987, 1, 0.674, 0.279), vct(1, 0.124, 0.991, 1, 0.340, 0.558, 1, 0.464, 0.125), vct(1, 0.070, 0.994, 1, 0.199, 0.724, 1, 0.298, 0.341, 1, 0.352, 0.070), vct(1, 0.045, 0.996, 1, 0.130, 0.814, 1, 0.203, 0.521, 1, 0.255, 0.227, 1, 0.283, 0.045)] k = 0 2.step(11, 2) do |i| vals = chebyshev_prototype(i, 0.01) snd_test_neq(vals[1], poles_01[k], "chebyshev_prototype 0.01 poles %d", i) vals = chebyshev_prototype(i, 0.1) snd_test_neq(vals[1], poles_1[k], "chebyshev_prototype 0.1 poles %d", i) vals = chebyshev_prototype(i) snd_test_neq(vals[1], poles_10[k], "chebyshev_prototype 1 poles %d", i) snd_test_neq(vals[0], zeros[k], "chebyshev_prototype 0.01 zeros %d", i) k += 1 end # f1 = make_chebyshev_lowpass(8, 0.1) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.51, :ffequal?, "chebyshev lp 8 max") v0 = vals[1] v1 = vct(0.508, 0.512, 0.468, 0.001, 0, 0, 0, 0, 0, 0) v2 = vct(0.507, 0.512, 0.467, 0.001, 0, 0, 0, 0, 0, 0) v3 = vct(0.508, 0.513, 0.469, 0.001, 0, 0, 0, 0, 0, 0) v4 = vct(0.509, 0.508, 0.465, 0.001, 0, 0, 0, 0, 0, 0) if (not vequal(v0, v1)) and (not vequal(v0, v2)) and (not vequal(v0, v3)) and (not vequal(v0, v4)) snd_test_neq(v0, v1, "chebyshev lp 8 0.1 spect (v1)") snd_test_neq(v0, v2, "chebyshev lp 8 0.1 spect (v2)") snd_test_neq(v0, v3, "chebyshev lp 8 0.1 spect (v3)") snd_test_neq(v0, v4, "chebyshev lp 8 0.1 spect (v4)") end f1 = make_chebyshev_lowpass(12, 0.25) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.51, :ffequal?, "chebyshev lp 12 max") v1 = vct(0.509, 0.500, 0.508, 0.508, 0.507, 0.413, 0, 0, 0, 0) snd_test_neq(vals[1], v1, "chebyshev lp 12 0.25 spect") f1 = make_chebyshev_lowpass(10, 0.4) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.51, :ffequal?, "chebyshev lp 10 max") v1 = vct(0.465, 0.493, 0.509, 0.508, 0.477, 0.507, 0.508, 0.507, 0.431, 0) snd_test_neq(vals[1], v1, "chebyshev lp 10 0.4 spect") f1 = make_chebyshev_lowpass(8, 0.1, 0.01) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.49, :ffequal?, "chebyshev lp 8 0.1 0.01 max") v1 = vct(0.492, 0.491, 0.483, 0.006, 0, 0, 0, 0, 0, 0) snd_test_neq(vals[1], v1, "chebyshev lp 8 0.1 0.01 spect") f1 = make_chebyshev_lowpass(12, 0.25, 0.1) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.49, :ffequal?, "chebyshev lp 12 0.1 max") v1 = vct(0.488, 0.488, 0.488, 0.488, 0.487, 0.403, 0, 0, 0, 0) snd_test_neq(vals[1], v1, "chebyshev lp 12 0.25 0.1 spect") f1 = make_chebyshev_lowpass(10, 0.4, 0.001) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.49, :ffequal?, "chebyshev lp 10 0.001 max") v1 = vct(0.497, 0.497, 0.497, 0.497, 0.497, 0.497, 0.497, 0.497, 0.488, 0) snd_test_neq(vals[1], v1, "chebyshev lp 10 0.4 0.001 spect") 2.step(10, 2) do |i| 0.1.step(0.35, 0.1) do |j| f1 = make_chebyshev_lowpass(i, j) snd_test_gt(filter_response_max(f1), 1.0, "cheby low max %d %d", i, j) end end # f1 = make_chebyshev_highpass(8, 0.1) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.55, :ffequal?, "chebyshev hp 8 max") v1 = vct(0, 0.341, 0.551, 0.509, 0.466, 0.501, 0.509, 0.505, 0.481, 0.461) snd_test_neq(vals[1], v1, "chebyshev hp 8 0.1 spect") f1 = make_chebyshev_highpass(12, 0.25) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.55, :ffequal?, "chebyshev hp 12 max") v1 = vct(0, 0, 0, 0, 0.299, 0.554, 0.509, 0.509, 0.500, 0.509) snd_test_neq(vals[1], v1, "chebyshev hp 12 0.25 spect") f1 = make_chebyshev_highpass(10, 0.4) vals = sweep2bins(f1, 10) v0 = vals[1] v1 = vct(0, 0, 0, 0, 0, 0, 0, 0.297, 0.786, 0.677) v2 = vct(0, 0, 0, 0, 0, 0, 0, 0.301, 0.788, 0.660) v3 = vct(0, 0, 0, 0, 0, 0, 0, 0.322, 0.861, 0.724) v4 = vct(0, 0, 0, 0, 0, 0, 0, 0.262, 0.571, 0.509) if (not vequal(v0, v1)) and (not vequal(v0, v2)) and (not vequal(v0, v3)) and (not vequal(v0, v4)) snd_test_neq(v0, v1, "chebyshev hp 10 0.4 spect (v1)") snd_test_neq(v0, v2, "chebyshev hp 10 0.4 spect (v2)") snd_test_neq(v0, v3, "chebyshev hp 10 0.4 spect (v3)") snd_test_neq(v0, v4, "chebyshev hp 10 0.4 spect (v4)") end f1 = make_chebyshev_highpass(8, 0.1, 0.01) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.49, :ffequal?, "chebyshev hp 8 0.1 0.01 max") v1 = vct(0, 0.498, 0.498, 0.492, 0.491, 0.492, 0.492, 0.492, 0.491, 0.491) snd_test_neq(vals[1], v1, "chebyshev hp 8 0.1 0.01 spect") f1 = make_chebyshev_highpass(12, 0.25, 0.1) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.51, :ffequal?, "chebyshev hp 12 0.1 max") v1 = vct(0, 0, 0, 0, 0.453, 0.516, 0.489, 0.489, 0.488, 0.488) snd_test_neq(vals[1], v1, "chebyshev hp 12 0.25 0.1 spect") f1 = make_chebyshev_highpass(10, 0.4, 0.001) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.5, :ffequal?, "chebyshev 10 0.001 max") v0 = vals[1] v1 = vct(0, 0, 0, 0, 0, 0, 0.002, 0.501, 0.504, 0.504) v2 = vct(0, 0, 0, 0, 0, 0, 0.002, 0.503, 0.505, 0.504) v3 = vct(0, 0, 0, 0, 0, 0, 0.002, 0.503, 0.501, 0.497) if (not vequal(v0, v1)) and (not vequal(v0, v2)) and (not vequal(v0, v3)) snd_test_neq(v0, v1, "chebyshev hp 10 0.4 0.001 spect (v1)") snd_test_neq(v0, v2, "chebyshev hp 10 0.4 0.001 spect (v2)") snd_test_neq(v0, v3, "chebyshev hp 10 0.4 0.001 spect (v3)") end 2.step(10, 2) do |i| 0.1.step(0.35, 0.1) do |j| f1 = make_chebyshev_highpass(i, j) snd_test_gt(filter_response_max(f1), 1.0, "cheby high max %d %d", i, j) end end # f1 = make_chebyshev_bandpass(4, 0.1, 0.2) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.5, :f05equal?, "chebyshev bp 4 max") v1 = vct(0.009, 0.449, 0.509, 0.505, 0.442, 0.065, 0.013, 0.003, 0, 0) snd_test_neq(vals[1], v1, "chebyshev bp 4 0.1 0.2 spect") f1 = make_chebyshev_bandpass(6, 0.1, 0.2) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.5, :f05equal?, "chebyshev bp 6 max") v1 = vct(0.001, 0.376, 0.505, 0.498, 0.412, 0.011, 0.001, 0, 0, 0) snd_test_neq(vals[1], v1, "chebyshev bp 6 0.1 0.2 spect") f1 = make_chebyshev_bandpass(8, 0.3, 0.4) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.5, :f05equal?, "chebyshev bp 8 max") v1 = vct(0, 0, 0, 0, 0.002, 0.363, 0.517, 0.513, 0.433, 0) snd_test_neq(vals[1], v1, "chebyshev bp 8 0.3 0.4 spect") f1 = make_chebyshev_bandpass(8, 0.2, 0.2, 0.01) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.5, :f05equal?, "chebyshev bp 10 0.2 max") v1 = vct(0, 0, 0.015, 0.483, 0.482, 0.021, 0.001, 0, 0, 0) snd_test_neq(vals[1], v1, "chebyshev bp 10 0.2 spect") # f1 = make_chebyshev_bandstop(4, 0.1, 0.4) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.5, :f05equal?, "chebyshev bs 4 max") v1 = vct(0.509, 0.505, 0.447, 0.033, 0.006, 0.006, 0.033, 0.445, 0.512, 0.509) snd_test_neq(vals[1], v1, "chebyshev bs 4 0.1 0.4 spect") f1 = make_chebyshev_bandstop(8, 0.1, 0.4) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.51, :f05equal?, "chebyshev bs 8 max") v0 = vals[1] v1 = vct(0.508, 0.512, 0.468, 0.001, 0, 0, 0.001, 0.345, 0.551, 0.507) v2 = vct(0.507, 0.512, 0.467, 0.001, 0, 0, 0.001, 0.344, 0.590, 0.508) v3 = vct(0.508, 0.513, 0.469, 0.001, 0, 0, 0.001, 0.345, 0.552, 0.508) v4 = vct(0.509, 0.508, 0.465, 0.001, 0, 0, 0.001, 0.343, 0.548, 0.508) if (not vequal(v0, v1)) and (not vequal(v0, v2)) and (not vequal(v0, v3)) and (not vequal(v0, v4)) snd_test_neq(v0, v1, "chebyshev bs 8 0.1 0.4 spect (v1)") snd_test_neq(v0, v2, "chebyshev bs 8 0.1 0.4 spect (v2)") snd_test_neq(v0, v3, "chebyshev bs 8 0.1 0.4 spect (v3)") snd_test_neq(v0, v4, "chebyshev bs 8 0.1 0.4 spect (v4)") end f1 = make_chebyshev_bandstop(8, 0.1, 0.4, 0.01) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.5, :f05equal?, "chebyshev bs 8 0.01 max") v1 = vct(0.492, 0.491, 0.483, 0.006, 0, 0, 0.006, 0.494, 0.495, 0.492) snd_test_neq(vals[1], v1, "chebyshev bs 8 0.1 0.4 0.01 spect") # # inverse-chebyshev # f1 = make_inverse_chebyshev_lowpass(8, 0.1) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.51, :ffequal?, "inverse_chebyshev lp 8 max") v0 = vals[1] v1 = vct(0.501, 0.496, 0.001, 0, 0.001, 0, 0, 0, 0, 0.001) v2 = vct(0.500, 0.498, 0.001, 0, 0.001, 0, 0, 0, 0, 0.001) if (not vequal(v0, v1)) and (not vequal(v0, v2)) snd_test_neq(v0, v1, "inverse_chebyshev lp 8 0.1 spect (v1)") snd_test_neq(v0, v2, "inverse_chebyshev lp 8 0.1 spect (v2)") end f1 = make_inverse_chebyshev_lowpass(12, 0.25) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.51, :ffequal?, "inverse_chebyshev lp 12 max") v1 = vct(0.500, 0.500, 0.500, 0.500, 0.496, 0.001, 0.001, 0.001, 0.001, 0.001) snd_test_neq(vals[1], v1, "inverse_chebyshev lp 12 0.25 spect") f1 = make_inverse_chebyshev_lowpass(10, 0.4) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.51, :ffequal?, "inverse_chebyshev lp 10 max") v0 = vals[1] v1 = vct(0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.497, 0.001, 0.001) v2 = vct(0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.497, 0.002, 0.002) if (not vequal(v0, v1)) and (not vequal(v0, v2)) snd_test_neq(v0, v1, "inverse_chebyshev lp 10 0.4 spect (v1)") snd_test_neq(v0, v2, "inverse_chebyshev lp 10 0.4 spect (v2)") end f1 = make_inverse_chebyshev_lowpass(10, 0.4, 120) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.51, :ffequal?, "inverse_chebyshev lp 10 max") v1 = vct(0.501, 0.501, 0.501, 0.501, 0.501, 0.500, 0.345, 0.007, 0, 0) snd_test_neq(vals[1], v1, "inverse_chebyshev lp 10 0.4 120 spect") # 2.step(10, 2) do |i| 0.1.step(0.35, 0.1) do |j| f1 = make_inverse_chebyshev_lowpass(i, j) snd_test_gt(filter_response_max(f1), 1.0, "inv cheby low max %d %d", i, j) end end # f1 = make_inverse_chebyshev_highpass(8, 0.1) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.51, :ffequal?, "inverse_chebyshev hp 8 max") v1 = vct(0.001, 0.001, 0.440, 0.505, 0.505, 0.503, 0.502, 0.501, 0.501, 0.501) snd_test_neq(vals[1], v1, "inverse_chebyshev hp 8 0.1 spect") f1 = make_inverse_chebyshev_highpass(12, 0.25) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.51, :ffequal?, "inverse_chebyshev hp 12 max") v1 = vct(0.001, 0.001, 0.001, 0.001, 0.001, 0.505, 0.506, 0.503, 0.501, 0.501) snd_test_neq(vals[1], v1, "inverse_chebyshev hp 12 0.25 spect") f1 = make_inverse_chebyshev_highpass(10, 0.4) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.51, :ffequal?, "inverse_chebyshev hp 10 max") v0 = vals[1] v1 = vct(0, 0, 0, 0.001, 0.001, 0.001, 0.001, 0.001, 0.503, 0.503) v2 = vct(0, 0, 0, 0.001, 0.001, 0.001, 0.001, 0.001, 0.505, 0.503) v3 = vct(0, 0, 0, 0.001, 0.001, 0.001, 0.001, 0.001, 0.509, 0.504) if (not vequal(v0, v1)) and (not vequal(v0, v2)) and (not vequal(v0, v3)) snd_test_neq(v0, v1, "inverse_chebyshev hp 10 0.4 spect (v1)") snd_test_neq(v0, v2, "inverse_chebyshev hp 10 0.4 spect (v2)") snd_test_neq(v0, v3, "inverse_chebyshev hp 10 0.4 spect (v3)") end f1 = make_inverse_chebyshev_highpass(10, 0.1, 120) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.51, :ffequal?, "inverse_chebyshev hp 10 0.1 120 max") v1 = vct(0, 0, 0.007, 0.328, 0.502, 0.502, 0.502, 0.501, 0.501, 0.501) snd_test_neq(vals[1], v1, "inverse_chebyshev hp 10 0.1 120 spect") # 2.step(10, 2) do |i| 0.1.step(0.35, 0.1) do |j| f1 = make_inverse_chebyshev_highpass(i, j) snd_test_gt(filter_response_max(f1), 1.0, "inv cheby high max %d %d", i, j) end end # f1 = make_inverse_chebyshev_bandpass(10, 0.1, 0.2) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.5, :f05equal?, "inverse_chebyshev bp 10 max") v1 = vct(0.001, 0.001, 0.498, 0.485, 0.001, 0.001, 0, 0.001, 0, 0.001) snd_test_neq(vals[1], v1, "inverse_chebyshev bp 10 0.1 0.2 spect") f1 = make_inverse_chebyshev_bandpass(10, 0.1, 0.2, 30) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.5, :f05equal?, "inverse_chebyshev bp 10 30 max") v0 = vals[1] v1 = vct(0.026, 0.025, 0.509, 0.505, 0.02, 0.016, 0.012, 0.016, 0.011, 0.016) v2 = vct(0.030, 0.042, 0.511, 0.505, 0.02, 0.016, 0.012, 0.016, 0.011, 0.016) v3 = vct(0.022, 0.017, 0.511, 0.505, 0.02, 0.016, 0.012, 0.016, 0.011, 0.016) if (not vequal(v0, v1)) and (not vequal(v0, v2)) and (not vequal(v0, v3)) snd_test_neq(v0, v1, "inverse_chebyshev bp 10 0.1 0.2 30 spect (v1)") snd_test_neq(v0, v2, "inverse_chebyshev bp 10 0.1 0.2 30 spect (v2)") snd_test_neq(v0, v3, "inverse_chebyshev bp 10 0.1 0.2 30 spect (v3)") end f1 = make_inverse_chebyshev_bandpass(8, 0.1, 0.4) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.5, :f05equal?, "inverse_chebyshev bp 8 max") v1 = vct(0.001, 0.001, 0.440, 0.506, 0.505, 0.503, 0.502, 0.434, 0.001, 0.001) snd_test_neq(vals[1], v1, "inverse_chebyshev bp 8 0.1 0.4 spect") f1 = make_inverse_chebyshev_bandpass(8, 0.3, 0.4, 40) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.5, :f05equal?, "inverse_chebyshev bp 8 40 max") v1 = vct(0.002, 0.005, 0.007, 0.007, 0.005, 0.005, 0.503, 0.505, 0.006, 0.005) snd_test_neq(vals[1], v1, "inverse_chebyshev bp 8 0.3 0.4 40 spect") # f1 = make_inverse_chebyshev_bandstop(4, 0.1, 0.4) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.5, :f05equal?, "inverse_chebyshev bs 4 max") v1 = vct(0.500, 0.054, 0.001, 0.001, 0, 0, 0, 0.001, 0.055, 0.503) snd_test_neq(vals[1], v1, "inverse_chebyshev bs 4 0.1 0.4 spect") f1 = make_inverse_chebyshev_bandstop(8, 0.1, 0.4) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.51, :f05equal?, "inverse_chebyshev bs 8 max") v0 = vals[1] v1 = vct(0.501, 0.496, 0.001, 0.001, 0, 0, 0, 0.001, 0.507, 0.506) v2 = vct(0.506, 0.328, 0.001, 0.001, 0, 0, 0, 0.000, 0.268, 0.511) v3 = vct(0.500, 0.498, 0.001, 0.001, 0, 0, 0, 0.001, 0.507, 0.506) if (not vequal(v0, v1)) and (not vequal(v0, v2)) and (not vequal(v0, v3)) snd_test_neq(v0, v1, "inverse_chebyshev bs 8 0.1 0.4 spect (v1)") snd_test_neq(v0, v2, "inverse_chebyshev bs 8 0.1 0.4 spect (v2)") snd_test_neq(v0, v3, "inverse_chebyshev bs 8 0.1 0.4 spect (v3)") end f1 = make_inverse_chebyshev_bandstop(8, 0.1, 0.4, 90) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.5, :f05equal?, "inverse_chebyshev bs 8 90 max") v0 = vals[1] v1 = vct(0.505, 0.325, 0, 0, 0, 0, 0, 0, 0.270, 0.506) v2 = vct(0.506, 0.328, 0, 0, 0, 0, 0, 0, 0.269, 0.509) v3 = vct(0.501, 0.327, 0, 0, 0, 0, 0, 0, 0.268, 0.506) if (not vequal(v0, v1)) and (not vequal(v0, v2)) and (not vequal(v0, v3)) snd_test_neq(v0, v1, "inverse_chebyshev bs 8 0.1 0.4 90 spect (v1)") snd_test_neq(v0, v2, "inverse_chebyshev bs 8 0.1 0.4 90 spect (v2)") snd_test_neq(v0, v3, "inverse_chebyshev bs 8 0.1 0.4 90 spect (v3)") end if $with_test_gsl if defined? gsl_roots # gsl_roots isn't defined for ruby in snd-xen.c # # bessel # f1 = make_bessel_lowpass(4, 0.1) vals = sweep2bins(f1, 10) snd_test_neq(vals[0], 0.5, "bessel lp 4 0.1 max") snd_test_neq(vals[1], vct(0.500, 0.417, 0.209, 0.062, 0.018, 0.005, 0.001, 0, 0, 0), "bessel lp 4 0.1 spect") f1 = make_bessel_lowpass(8, 0.1) vals = sweep2bins(f1, 10) snd_test_neq(vals[0], 0.5, "bessel lp 8 max") snd_test_neq(vals[1], vct(0.499, 0.365, 0.116, 0.010, 0.001, 0, 0, 0, 0, 0), "bessel lp 8 0.1 spect") f1 = make_bessel_lowpass(12, 0.25) vals = sweep2bins(f1, 10) snd_test_neq(vals[0], 0.5, "bessel lp 12 max") snd_test_neq(vals[1], vct(0.500, 0.477, 0.410, 0.309, 0.185, 0.063, 0.006, 0, 0, 0), "bessel lp 12 0.25 spect") f1 = make_bessel_lowpass(10, 0.4) vals = sweep2bins(f1, 10) snd_test_neq(vals[0], 0.5, "bessel lp 10 max") if (not vequal(vals[1], vct(0.5, 0.498, 0.491, 0.479, 0.458, 0.423, 0.364, 0.259, 0.086, 0.001))) and (not vequal(vals[1], vct(0.5, 0.498, 0.491, 0.479, 0.458, 0.423, 0.364, 0.259, 0.086, 0.002))) snd_display(snd_format_neq(vals[1], vct(0.5, 0.498, 0.491, 0.479, 0.458, 0.423, 0.364, 0.259, 0.086, 0.001), "bessel lp 10 0.4 spect")) end 2.step(11, 2) do |i| 0.1.step(0.44, 0.1) do |j| f1 = make_bessel_lowpass(i, j) snd_test_gt(filter_response_max(f1), 1.0, "bess low max %d %d", i, j) end end # f1 = make_bessel_highpass(8, 0.1) vals = sweep2bins(f1, 10) snd_test_neq(vals[0], 0.5, "bessel hp 8 max") snd_test_neq(vals[1], vct(0.001, 0.115, 0.29, 0.386, 0.435, 0.465, 0.483, 0.493, 0.498, 0.5), "bessel hp 8 0.1 spect") f1 = make_bessel_highpass(12, 0.25) vals = sweep2bins(f1, 10) snd_test_neq(vals[0], 0.5, "bessel hp 12 max") snd_test_neq(vals[1], vct(0, 0, 0, 0.006, 0.063, 0.181, 0.309,0.410, 0.477, 0.5), "bessel hp 12 0.25 spect") f1 = make_bessel_highpass(10, 0.4) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.5, :ffequal?, "bessel hp 10 max") snd_test_neq(vals[1], vct(0, 0, 0, 0, 0, 0, 0.004, 0.084, 0.343, 0.499), "bessel hp 12 0.25 0.01 90 spect") # f1 = make_bessel_bandpass(4, 0.1, 0.2) vals = sweep2bins(f1, 10) snd_test_neq(vals[0], 0.5, "bessel bp 4 max") snd_test_neq(vals[1], vct(0.023, 0.176, 0.245, 0.244, 0.179, 0.085, 0.031, 0.008, 0.001, 0), "bessel bp 4 0.1 0.2 spect") # f1 = make_bessel_bandstop(12, 0.1, 0.2) vals = sweep2bins(f1, 10) snd_test_neq(vals[0], 0.5, "bessel bs 12 max") snd_test_neq(vals[1], vct(0.498, 0.325, 0.065, 0.066, 0.177, 0.297, 0.389, 0.452, 0.488, 0.5), "bessel bs 12 0.1 0.2 spect") end # # elliptic # f1 = make_elliptic_lowpass(8, 0.1) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.5, :fffequal?, "elliptic lp 8 max") if (not vequal(vals[1], vct(0.500, 0.515, 0.379, 0, 0, 0, 0, 0, 0, 0))) and (not vequal(vals[1], vct(0.500, 0.509, 0.385, 0, 0, 0, 0, 0, 0, 0))) and (not vequal(vals[1], vct(0.499, 0.498, 0.373, 0, 0, 0, 0, 0, 0, 0))) snd_display(snd_format_neq(vals[1], vct(0.500, 0.515, 0.379, 0, 0, 0, 0, 0, 0, 0), "elliptic lp 8 0.1 spect")) end f1 = make_elliptic_lowpass(12, 0.25) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.5, :fffequal?, "elliptic lp 12 max") if (not vequal(vals[1], vct(0.476, 0.500, 0.491, 0.499, 0.494, 0.412, 0.003, 0.001, 0, 0))) and (not vequal(vals[1], vct(0.476, 0.500, 0.491, 0.499, 0.494, 0.561, 0.004, 0, 0, 0))) and (not vequal(vals[1], vct(0.476, 0.500, 0.491, 0.499, 0.493, 0.299, 0.006, 0.001, 0, 0))) snd_display(snd_format_neq(vals[1], vct(0.476, 0.500, 0.491, 0.499, 0.494, 0.412, 0.003, 0.001, 0, 0), "elliptic lp 12 0.25 spect")) end f1 = make_elliptic_lowpass(4, 0.4) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.5, :fffequal?, "elliptic lp 4 max") snd_test_neq(vals[1], vct(0.447, 0.453, 0.462, 0.477, 0.494, 0.500, 0.497, 0.496, 0.445, 0.003), "elliptic lp 4 0.4 spect") f1 = make_elliptic_lowpass(8, 0.1, 0.1) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.5, :fffequal?, "elliptic lp 8 0.1 max") snd_test_neq(vals[1], vct(0.500, 0.499, 0.475, 0, 0, 0, 0, 0, 0, 0), "elliptic lp 8 0.1 0.1 spect") f1 = make_elliptic_lowpass(8, 0.1, 0.1, 90) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.5, :fffequal?, "elliptic lp 8 0.1 90 max") snd_test_neq(vals[1], vct(0.500, 0.499, 0.475, 0, 0, 0, 0, 0, 0, 0), "elliptic lp 8 0.1 0.1 90 spect") f1 = make_elliptic_lowpass(8, 0.25, 0.01, 90) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.5, :fffequal?, "elliptic lp 8 0.25 90 max") snd_test_neq(vals[1], vct(0.500, 0.500, 0.500, 0.500, 0.499, 0.495, 0.001, 0, 0, 0), "elliptic lp 8 0.25 0.01 90 spect") # f1 = make_elliptic_highpass(4, 0.1) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.5, :fffequal?, "elliptic hp 4 max") snd_test_neq(vals[1], vct(0.004, 0.438, 0.516, 0.499, 0.502, 0.495, 0.478, 0.463, 0.453, 0.447), "elliptic hp 4 0.1 spect") f1 = make_elliptic_highpass(12, 0.25) vals = sweep2bins(f1, 10) # snd_test_any_neq(vals[0], 0.5, :fffequal?, "elliptic hp 12 max") if (not vequal(vals[1], vct(0, 0.001, 0.001, 0.001, 0.026, 0.934, 0.518, 0.495, 0.503, 0.477))) and (not vequal(vals[1], vct(0, 0.001, 0.001, 0.001, 0.033, 1.185, 0.519, 0.495, 0.503, 0.477))) and (not vequal(vals[1], vct(0, 0.001, 0.001, 0.001, 0.018, 0.788, 0.520, 0.495, 0.503, 0.477))) snd_display(snd_format_neq(vals[1], vct(0, 0.001, 0.001, 0.001, 0.026, 0.934, 0.518, 0.495, 0.503, 0.477), "elliptic hp 12 0.25 spect: %s?")) end f1 = make_elliptic_highpass(12, 0.25, 0.01, 90) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.5, :fffequal?, "elliptic hp 12 90 max") snd_test_neq(vals[1], vct(0, 0, 0, 0, 0.499, 0.517, 0.503, 0.501, 0.500, 0.500), "elliptic hp 12 0.25 0.01 90 spect") f1 = make_elliptic_highpass(4, 0.4) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.5, :fffequal?, "elliptic hp 4 0.4 max") snd_test_neq(vals[1], vct(0, 0, 0, 0.001, 0.001, 0.002, 0.023, 0.447, 0.515, 0.502), "elliptic hp 4 0.4 spect") f1 = make_elliptic_highpass(8, 0.1, 0.1) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.5, :fffequal?, "elliptic hp 8 0.1 max") snd_test_neq(vals[1], vct(0, 0.478, 0.553, 0.506, 0.499, 0.501, 0.501, 0.499, 0.497, 0.495), "elliptic hp 8 0.1 0.1 spect") f1 = make_elliptic_highpass(8, 0.1, 0.1, 90) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.5, :fffequal?, "elliptic hp 8 0.1 90 max") snd_test_neq(vals[1], vct(0, 0.478, 0.554, 0.506, 0.499, 0.501, 0.501, 0.499, 0.497, 0.495), "elliptic hp 8 0.1 0.1 90 spect") f1 = make_elliptic_highpass(8, 0.25, 0.01, 90) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.5, :fffequal?, "elliptic hp 8 0.25 90 max") snd_test_neq(vals[1], vct(0, 0, 0, 0.001, 0.516, 0.517, 0.507, 0.503, 0.501, 0.500), "elliptic hp 8 0.25 0.01 90 spect") # f1 = make_elliptic_bandpass(4, 0.1, 0.2, 0.1) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.5, :fffequal?, "elliptic bp 4 max") snd_test_neq(vals[1], vct(0.036, 0.546, 0.55, 0.51, 0.501, 0.032, 0.024, 0.009, 0.021, 0.024), "elliptic bp 4 0.1 0.2 0.1 spect") f1 = make_elliptic_bandpass(6, 0.1, 0.2, 0.1, 90) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.5, :fffequal?, "elliptic bp 6 max") snd_test_neq(vals[1], vct(0.002, 0.511, 0.532, 0.503, 0.492, 0.003, 0.001, 0.001, 0.001, 0.001), "elliptic bp 6 0.1 0.2 0.1 90 spect") # f1 = make_elliptic_bandstop(4, 0.1, 0.3, 0.1) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.5, :fffequal?, "elliptic bs 4 max") snd_test_neq(vals[1], vct(0.499, 0.502, 0.498, 0.037, 0.05, 0.54, 0.544, 0.527, 0.526, 0.521), "elliptic bs 4 0.1 0.3 0.1 spect") f1 = make_elliptic_bandstop(8, 0.1, 0.3, 0.1, 120) vals = sweep2bins(f1, 10) snd_test_any_neq(vals[0], 0.5, :fffequal?, "elliptic bs 8 max") if (not vequal(vals[1], vct(0.500, 0.499, 0.476, 0, 0, 0.495, 0.526, 0.505, 0.501, 0.501))) and (not vequal(vals[1], vct(0.500, 0.499, 0.475, 0, 0, 0.495, 0.526, 0.505, 0.501, 0.501))) snd_display(snd_format_neq(vals[1], vct(0.500, 0.499, 0.476, 0, 0, 0.495, 0.526, 0.505, 0.501, 0.501), "elliptic bs 8 0.1 0.3 0.1 120 spect")) end end # $with_test_gsl end def poly_roots_tests # degree=0 res = poly(0.0).roots req = poly() snd_test_neq(res, req, "poly_roots 0.0") res = poly(12.3).roots req = poly() snd_test_neq(res, req, "poly_roots 12.3") # degree 0 + x=0 res = poly(0.0, 1.0).roots req = [0.0] snd_test_neq(res, req, "poly_roots 0.0 1.0") res = poly(0.0, 0.0, 0.0, 121.0).roots req = [0.0, 0.0, 0.0] snd_test_neq(res, req, "poly_roots 0.0 0.0 0.0 121.0") # degree=1 res = poly(-1.0, 1.0).roots req = [1.0] snd_test_neq(res, req, "poly_roots -1.0 1.0") res = poly(-2.0, 4.0).roots req = [0.5] snd_test_neq(res, req, "poly_roots -2.0 4.0") res = poly(Complex(0.0, -1.0), 1).roots req = [Complex(0.0, 1.0)] snd_test_neq(res, req, "poly_roots -i 1") # linear x^n res = poly(-1.0, 0.0, 0.0, 0.0, 1.0).roots req1 = [Complex(0.0, -1.0), -1.0, Complex(0.0, 1.0), 1.0] req2 = [1.0, -1.0, Complex(0.0, 1.0), Complex(-0.0, -1.0)] if vcneql(res, req1) and vcneql(res, req2) snd_format_neq(res, req1, "poly_roots -1 0 0 0 1 (a)") snd_format_neq(res, req2, "poly_roots -1 0 0 0 1 (b)") end res = poly(-16, 0, 0, 0, 1).roots req1 = [Complex(0.0, -2.0), -2.0, Complex(0.0, 2.0), 2.0] req2 = [2.0, -2.0, Complex(0.0, 2.0), Complex(-0.0, -2.0)] if vcneql(res, req1) and vcneql(res, req2) snd_format_neq(res, req1, "poly_roots -16 0 0 0 1 (a)") snd_format_neq(res, req2, "poly_roots -16 0 0 0 1 (b)") end res = poly(-32, 0, 0, 0, 0, 0, 0.5).roots req = [Complex(1.0, -1.7320), Complex(-1.0, -1.7320), -2.0, Complex(-1.0, 1.7320), Complex(1.0, 1.7320), 2.0] snd_test_any_neq(res, req, :vcequal?, "poly_roots -32 0 0 0 0 0 0.5") # linear + x=0 res = poly(0, -2, 4).roots req = [0.0, 0.5] snd_test_neq(res, req, "poly_roots 0 -2 4") # degree=2 res = poly(-1, 0, 1).roots req = [1.0, -1.0] snd_test_neq(res, req, "poly_roots -1 0 1") res = poly(15, -8, 1).roots req = [5.0, 3.0] snd_test_neq(res, req, "poly_roots 15 -8 1") res = poly(1, -2, 1).roots req = [1.0, 1.0] snd_test_neq(res, req, "poly_roots 1 -2 1") res = poly(-1, Complex(0.0, 2.0), 1).roots req = [Complex(0.0, -1.0), Complex(0.0, -1.0)] snd_test_neq(res, req, "poly_roots -1 2i 1") res = poly(1, 1, 5).roots req = [Complex(-0.1, 0.43589), Complex(-0.1, -0.43589)] snd_test_any_neq(res, req, :vcequal?, "poly_roots 1 1 5") # 2 + x=0 res = poly(0, 0, -1, 0, 1).roots req = [0.0, 0.0, 1.0, -1.0] snd_test_neq(res, req, "poly_roots 0 0 -1 0 1") # quadratic in x^(n/2) res = poly(1, 0, -2, 0, 1).roots req1 = [-1.0, 1.0, -1.0, 1.0] req2 = [1.0, 1.0, -1.0, -1.0] if res != req1 and res != req2 snd_format_neq(res, req1, "poly_roots 1 0 -2 0 1 (a)") snd_format_neq(res, req2, "poly_roots 1 0 -2 0 1 (b)") end res = poly(64, 0, 0, -16, 0, 0, 1).roots req = [Complex(-1.0, -1.73205), Complex(-1.0, 1.73205), 2.0, Complex(-1.0, -1.73205), Complex(-1.0, 1.73205), 2.0] snd_test_any_neq(res, req, :vcequal?, "poly_roots 64 0 0 -16 0 0 1") # degree=3 res = poly(-15, 23, -9, 1).roots req = [5.0, 1.0, 3.0] snd_test_any_neq(res, req, :vequal?, "poly_roots -15 23 -9 1") res = poly(-126, -15, 0, 1).roots req = [6.0, Complex(-3.0, 3.46410), Complex(-3.0, -3.46410)] snd_test_any_neq(res, req, :vcequal?, "poly_roots -126 -15 0 1") res = poly(-1, 3, -3, 1).roots req = [1.0, 1.0, 1.0] snd_test_neq(res, req, "poly_roots -1 3 -3 1") res = poly(1, -1, -1, 1).roots req = [1.0, -1.0, 1.0] snd_test_any_neq(res, req, :vequal?, "poly_roots 1 -1 -1 1") res = poly(2, -2, -2, 2).roots req = [1.0, -1.0, 1.0] snd_test_any_neq(res, req, :vequal?, "poly_roots 2 -2 -2 2") # degree=4 res = poly(-15, 8, 14, -8, 1).roots req = [5.0, 3.0, 1.0, -1.0] snd_test_neq(res, req, "poly_roots -15 8 14 -8 1: [5.0, 3.0, 1.0, -1.0]") res = (poly(2, 1) * poly(-3, 1) * poly(8, 1) * poly(-9, 1)).reduce.roots req = [9, 3, -2, -8] snd_test_neq(res, req, "poly_roots 4(1)") res = (poly(0.2, 1) * poly(-3, 1) * poly(0.8, 1) * poly(-9, 1)).reduce.roots req = [9, 3, -0.2, -0.8] snd_test_any_neq(res, req, :vequal?, "poly_roots 4(2)") res = (poly(0.02, 1) * poly(-32, 1) * poly(0.8, 1) * poly(-9, 1)).reduce.roots req = [32, 9, -0.02, -0.8] snd_test_any_neq(res, req, :vequal?, "poly_roots 4(3)") # degree>4 res = poly(1, 1) * poly(2, 1) * poly(-3, 1) * poly(-1, 1) * poly(-2, 1) res = res.reduce.roots req = [3, 2, -1, -2, 1] snd_test_any_neq(res, req, :vequal?, "poly_roots n(1)") res = poly(1, 1) * poly(2, 1) * poly(-3, 1) * poly(8, 1) * poly(-9, 1) res = res.reduce.roots req = [9, 3, -2, -8, -1] snd_test_any_neq(res, req, :vequal?, "poly_roots n(2)") res = poly(-1, 0, 1) * poly(9, 1) * poly(-3, 1) * poly(-10, 1) * poly(-2, 1) res = res.reduce.roots req = [10, 3, -1, -9, 2, 1] snd_test_any_neq(res, req, :vequal?, "poly_roots n(3)") res = poly(-1, 0, 1) * poly(-4, 0, 1) * poly(-3, 1) * poly(-10, 1) * poly(-9, 0, 1) res = res.reduce.roots req = [10, 3, -2, -3, -1, 3, 2, 1] snd_test_any_neq(res, req, :vequal?, "poly_roots n(4)") res = poly(-1, 0, 1) * poly(-4, 0, 1) * poly(-16, 0, 1) * poly(-25, 0, 1) * poly(-9, 0, 1) res = res.reduce.roots req = [5, -3, -4, -5, 4, -2, 3, -1, 2, 1] snd_test_any_neq(res, req, :vequal?, "poly_roots n(5)") res = poly(1, 1) * poly(2, 1) * poly(-3, 1) * poly(1, 1) * poly(-2, 1) res = res.reduce.roots req = [3, -1, -1, -2, 2] snd_test_any_neq(res, req, :vequal?, "poly_roots n(6)") res = poly(-64, 0, 0, 0, 0, 0, 1).roots req = [Complex(0.999, -1.732), Complex(-1.0, -1.732), -2.0, Complex(-1.0, 1.732), Complex(1.0, 1.732), 2.0] snd_test_any_neq(res, req, :vcequal?, "poly_roots 64 6") res = poly(64, 0, 0, -16, 0, 0, 1).roots req = [Complex(-1.0, -1.732), Complex(-1.0, 1.732), 2.0, Complex(-1.0, -1.732), Complex(-1.0, 1.732), 2.0] snd_test_any_neq(res, req, :vcequal?, "poly_roots 64 16 6") 10.times do poly(random(1.0), random(1.0), random(1.0)).roots end 10.times do poly(mus_random(1.0), mus_random(1.0), mus_random(1.0)).roots end res = convolution(vct(1, 2, 3, 0, 0, 0, 0, 0), vct(1, 2, 3, 0, 0, 0, 0, 0), 8) req = poly(1, 2, 3, 0) * poly(1, 2, 3, 0) snd_test_any_neq(res, req, :vequal?, "poly_multiply convolve") 10.times do poly(make_rectangular(mus_random(1.0), mus_random(1.0)), make_rectangular(mus_random(1.0), mus_random(1.0))).roots end 10.times do poly(make_rectangular(mus_random(1.0), mus_random(1.0)), make_rectangular(mus_random(1.0), mus_random(1.0)), make_rectangular(mus_random(1.0), mus_random(1.0))).roots end 10.times do poly(mus_random(1.0), mus_random(1.0), mus_random(1.0), mus_random(1.0)).roots end 10.times do poly(make_rectangular(mus_random(1.0), mus_random(1.0)), make_rectangular(mus_random(1.0), mus_random(1.0)), make_rectangular(mus_random(1.0), mus_random(1.0)), make_rectangular(mus_random(1.0), mus_random(1.0))).roots end 10.times do poly(mus_random(1.0), mus_random(1.0), mus_random(1.0), mus_random(1.0), mus_random(1.0)).roots end 10.times do poly(make_rectangular(mus_random(1.0), mus_random(1.0)), make_rectangular(mus_random(1.0), mus_random(1.0)), make_rectangular(mus_random(1.0), mus_random(1.0)), make_rectangular(mus_random(1.0), mus_random(1.0)), make_rectangular(mus_random(1.0), mus_random(1.0))).roots end 3.upto(20) do |i| v = Vct.new(i) v[0] = mus_random(1.0) v[i - 1] = 1.0 poly_roots(v) end 3.step(21, 2) do |i| v = Vct.new(i) v[0] = mus_random(1.0) v[i - 1] = 1.0 v[(i - 1) / 2] = 1.0 v.to_poly.roots end res = poly(1, -1, -1, 1).roots req = [1.0, -1.0, 1.0] snd_test_any_neq(res, req, :vequal?, "poly_roots 1 -1 -1 1") res = poly_roots(vct(2, -1, -2, 1)) req = [2.0, -1.0, 1.0] snd_test_any_neq(res, req, :vequal?, "poly_roots 2 -1 -2 1") res = poly(-1, 1, 1, 1).roots req = [0.544, Complex(-0.772, 1.115), Complex(-0.772, -1.115)] snd_test_any_neq(res, req, :vcequal?, "poly_roots -1 1 1 1") res = poly_roots(vct(-1, 3, -3, 1)) req = [1.0, 1.0, 1.0] snd_test_neq(res, req, "poly_roots -1 3 -3 1") res = poly_roots(vct(1, -4, 6, -4, 1)) req = [1.0, 1.0, 1.0, 1.0] snd_test_neq(res, req, "poly_roots 1 -4 6 -4 1") res = poly_roots(vct(0.5, 0, 0, 1)) req1 = [Complex(0.397, -0.687), -0.794, Complex(0.397, 0.687)] req2 = [Complex(0.397, 0.687), Complex(0.397, -0.687), -0.794] if vcneql(res, req1) and vcneql(res, req2) snd_format_neq(res, req1, "poly_roots 0.5 0 0 1 (a)") snd_format_neq(res, req2, "poly_roots 0.5 0 0 1 (b)") end # FIXME: reduce added (poly) # without reduce: # 3.0 -1.0 -2.0 -3.0 2.0-1.1555579666323415e-33i 1.0+2.9582283945787943e-31i res = poly(-1, 1) * poly(1, 1) * poly(-2, 1) * poly(2, 1) * poly(-3, 1) * poly(3, 1) res = res.reduce.roots req = [-3.0, 3.0, -1.0, 1.0, -2.0, 2.0] snd_test_any_neq(res, req, :vequal?, "cube in 2") end def jc_reverb_1(decay_dur, low_pass, volume, amp_env) allpass1 = make_all_pass(-0.7, 0.7, 1051) allpass2 = make_all_pass(-0.7, 0.7, 337) allpass3 = make_all_pass(-0.7, 0.7, 113) comb1 = make_comb(0.742, 4799) comb2 = make_comb(0.733, 4999) comb3 = make_comb(0.715, 5399) comb4 = make_comb(0.697, 5801) outdel = make_delay((0.013 * srate).round) dur = decay_dur + framples / srate envA = (amp_env ? make_env(:envelope, amp_env, :scaler, volume, :duration, dur) : false) comb_sum_1 = comb_sum_2 = comb_sum = all_sums = delA = delB = 0.0 map_chan(lambda do |inval| allpass_sum = all_pass(allpass3, all_pass(allpass2, all_pass(allpass1, inval))) comb_sum_2, comb_sum_1 = comb_sum_1, comb_sum comb_sum = (comb(comb1, allpass_sum) + comb(comb2, allpass_sum) + comb(comb3, allpass_sum) + comb(comb4, allpass_sum)) all_sums = if low_pass 0.25 * (comb_sum + comb_sum_2) + 0.5 * comb_sum_1 else comb_sum end inval + if envA env(envA) * delay(outdel, all_sums) else volume * delay(outdel, all_sums) end end, 0, (dur * srate).to_i) end # fm_violin def fm_violin_1(start, dur, freq, amp, *args) fm_index, amp_env, periodic_vibrato_rate, random_vibrato_rate = nil periodic_vibrato_amp, random_vibrato_amp, noise_amount, noise_freq = nil ind_noise_freq, ind_noise_amount, amp_noise_freq, amp_noise_amount = nil gliss_env, gliss_amount, fm1_env, fm2_env, fm3_env, fm1_rat, fm2_rat, fm3_rat = nil fm1_index, fm2_index, fm3_index, base, index_type, reverb_amount, degree, distance = nil optkey(args, binding, [:fm_index, 1.0], [:amp_env, [0, 0, 25, 1, 75, 1, 100, 0]], [:periodic_vibrato_rate, 5.0], [:random_vibrato_rate, 16.0], [:periodic_vibrato_amp, 0.0025], [:random_vibrato_amp, 0.005], [:noise_amount, 0.0], [:noise_freq, 1000.0], [:ind_noise_freq, 10.0], [:ind_noise_amount, 0.0], [:amp_noise_freq, 20.0], [:amp_noise_amount, 0.0], [:gliss_env, [0, 0, 100, 0]], [:gliss_amount, 0.0], [:fm1_env, [0, 1, 25, 0.4, 75, 0.6, 100, 0]], [:fm2_env, [0, 1, 25, 0.4, 75, 0.6, 100, 0]], [:fm3_env, [0, 1, 25, 0.4, 75, 0.6, 100, 0]], [:fm1_rat, 1.0], [:fm2_rat, 3.0], [:fm3_rat, 4.0], [:fm1_index, false], [:fm2_index, false], [:fm3_index, false], [:base, 1.0], [:reverb_amount, 0.01], [:degree, random(90)], [:distance, 1.0]) frq_scl = hz2radians(freq) modulate = fm_index.nonzero? maxdev = frq_scl * fm_index logfreq = log(freq) sqrtfreq = sqrt(freq) index1 = (fm1_index or [PI, maxdev * 5.0 / logfreq].min) index2 = (fm2_index or [PI, maxdev * 3.0 * (8.5 - logfreq) / (3.0 + freq * 0.001)].min) index3 = (fm3_index or [PI, maxdev * 4.0 / sqrtfreq].min) easy_case = (noise_amount.zero? and fm1_env == fm2_env and fm1_env == fm3_env and fm1_rat == fm1_rat.floor and fm2_rat == fm2_rat.floor and fm3_rat == fm3_rat.floor) norm = ((easy_case and modulate and 1.0) or index1) carrier = make_oscil(:frequency, freq) fmosc1 = if modulate if easy_case make_polyshape(:frequency, fm1_rat * freq, :coeffs, partials2polynomial([fm1_rat.to_i, index1, (fm2_rat / fm1_rat).floor, index2, (fm3_rat / fm1_rat).floor, index3])) else make_oscil(:frequency, fm1_rat * freq) end else false end fmosc2 = (modulate and (easy_case or make_oscil(:frequency, fm2_rat * freq))) fmosc3 = (modulate and (easy_case or make_oscil(:frequency, fm3_rat * freq))) ampf = make_env(:envelope, amp_env, :scaler, amp, :duration, dur, :base, base) indf1 = (modulate and make_env(:envelope, fm1_env, :scaler, norm, :duration, dur)) indf2 = (modulate and (easy_case or make_env(:envelope, fm2_env, :scaler, index2, :duration, dur))) indf3 = (modulate and (easy_case or make_env(:envelope, fm3_env, :scaler, index3, :duration, dur))) frqf = make_env(:envelope, gliss_env, :scaler, gliss_amount * frq_scl, :duration, dur) pervib = make_triangle_wave(periodic_vibrato_rate, periodic_vibrato_amp * frq_scl) ranvib = make_rand_interp(random_vibrato_rate, random_vibrato_amp * frq_scl) fm_noi = (noise_amount.nonzero? and make_rand(noise_freq, PI * noise_amount)) ind_noi = ((ind_noise_amount.nonzero? and ind_noise_freq.nonzero?) and make_rand_interp(ind_noise_freq, ind_noise_amount)) amp_noi = ((amp_noise_amount.nonzero? and amp_noise_freq.nonzero?) and make_rand_interp(amp_noise_freq, amp_noise_amount)) fuzz = modulation = 0.0 ind_fuzz = amp_fuzz = 1.0 out_data = make_vct!(seconds2samples(dur)) do if noise_amount.nonzero? fuzz = rand(fm_noi) end vib = env(frqf) + triangle_wave(pervib) + rand_interp(ranvib) if ind_noi ind_fuzz = 1.0 + rand_interp(ind_noi) end if amp_noi amp_fuzz = 1.0 + rand_interp(amp_noi) end if modulate modulation = if easy_case env(indf1) * polyshape(fmosc1, 1.0, vib) else (env(indf1) * oscil(fmosc1, fm1_rat * vib + fuzz) + env(indf2) * oscil(fmosc2, fm2_rat * vib + fuzz) + env(indf3) * oscil(fmosc3, fm3_rat * vib + fuzz)) end end env(ampf) * amp_fuzz * oscil(carrier, vib + ind_fuzz * modulation) end beg = seconds2samples(start) loc = make_locsig(:channels, channels(false), :degree, degree, :reverb, reverb_amount, :distance, distance) channels(false).times do |chn| mix_vct(vct_scale!(vct_copy(out_data), locsig_ref(loc, chn)), beg, false, chn, false) end end def fltit coeffs = vct(0.1, 0.2, 0.3, 0.4, 0.4, 0.3, 0.2, 0.1) flt = make_fir_filter(8, coeffs) xcof = flt.xcoeffs es = make_array(8) do |i| if i == 5 make_env(:envelope, [0, 0.4, 1, 1], :duration, 1.0) else make_env(:envelope, [0, coeffs[i], 1, 0], :duration, 0.5) end end lambda do |x| es.each_with_index do |en, i| xcof[i] = env(en) end fir_filter(flt, x) end end def freq_sweep(dur) phase = 0.0 freq = 0.0 incr = PI / (dur * 1.05 * mus_srate) len = framples() data = Vct.new(len) do |i| val = sin(phase) phase += freq freq += incr val end.scale!(0.5) vct2channel(data) end def make_ssb_am_1(freq, order = 40) if order.even? order += 1 end freq = freq.to_f carrier_freq = freq.abs cos_carrier = make_oscil(freq, HALF_PI) sin_carrier = make_oscil(freq) dly = make_delay(order) hlb = make_hilbert_transform(order) lambda do |y, fm| ccos = oscil(cos_carrier, fm) csin = oscil(sin_carrier, fm) yh = hilbert_transform(hlb, y) yd = delay(dly, y) if carrier_freq > 0.0 ccos * yd - csin * yh # shift up else ccos * yd + csin * yh # shift down end end end def ssb_am_1(gen, y, fm = 0.0) gen.call(y, fm) end def rough_spectrum(ind) rd = make_sampler(0, ind, 0) spect = Vct.new(10) do sum = 0.0 1000.times do val = rd.call sum = sum + val * val end sum end spect.scale!(1.0 / spect.peak) end def print_and_check(gen, name, desc, desc1 = "", desc2 = "") if gen.name != name snd_display_prev_caller("mus_name %s: %s?", name, gen.name) end if gen.name != "xen->sample" if gen.to_s != desc and gen.to_s != desc1 and gen.to_s != desc2 snd_display_prev_caller("mus_describe %s: %s?", gen.name, gen) end end egen = gen unless egen.eql?(gen) snd_display_prev_caller("eql? %s: %s?", gen, egen) end end def test_gen_equal(g0, g1, g2) # g0 = g1 at start != g2 g3 = g0 gad = make_vct(2) unless g0.eql?(g3) snd_display_prev_caller("let %s %s.eql? %s?", g0.name, g0, g3) end unless g0.eql?(g1) snd_display_prev_caller("arg %s %s.eql? %s?", g0.name, g0, g1) end if g0 == g1 snd_display_prev_caller("%s %s == %s?", g0.name, g0, g1) end if g0 == g2 snd_display_prev_caller("%s %s == %s?", g0.name, g0, g2) end if g0 == gad snd_display_prev_caller("%s == frame %s %s?", g0.name, g0, gad) end g0.run g3.run g3.run unless g0.eql?(g3) snd_display_prev_caller("run let %s %s.eql? %s?", g0.name, g0, g3) end if g0.eql?(g1) snd_display_prev_caller("arg %s %s.eql? %s?", g0.name, g0, g1) end if g0 == g1 snd_display_prev_caller("run %s %s == %s?", g0.name, g0, g1) end if g0 == g2 snd_display_prev_caller("run %s %s != %s?", g0.name, g0, g2) end end def fm_test(gen) if mus_generator?(gen) gen.frequency = 0.0 gen.phase = 0.0 gen.run(0.0) if fneq(res = gen.phase, 0.0) snd_display_prev_caller("%s phase(0): %s?", gen, res) end gen.run(1.0) if fneq(res = gen.phase, 1.0) snd_display_prev_caller("%s phase(1): %s?", gen, res) end gen.run(0.0) if fneq(res = gen.phase, 1.0) snd_display_prev_caller("%s phase(1, 0): %s?", gen, res) end gen.frequency = radians2hz(2.0) if fneq(res = gen.increment, 2.0) snd_display_prev_caller("%s increment: %s", gen, res) end gen.increment = 2.0 if fneq(res = gen.frequency, radians2hz(2.0)) snd_display_prev_caller("%s set increment: %s %s", gen, gen.increment, hz2radians(res)) end gen.run(0.0) if fneq(res = gen.phase, 3.0) snd_display_prev_caller("%s phase(1, 2): %s %s?", gen, res, gen.frequency) end gen.run(1.0) if fneq(res = gen.phase, 6.0) snd_display_prev_caller("%s phase(3, 2, 1): %s %s?", gen, res, gen.frequency) end 10.times do gen.run(10.0) end if fneq(res = gen.phase, 26 + 100 - TWO_PI * 20) snd_display_prev_caller("%s phase (over): %s %s?", gen, res, gen.frequency) end gen.frequency = 0.0 gen.phase = 0.0 gen.run(1234567812345678) gen.run(-1234567812345678) gen.frequency = 0.0 gen.phase = 0.0 gen.run(-2.0) if fneq(res = gen.phase, -2.0) and fneq(res, TWO_PI - 2) snd_display_prev_caller("phase %s freq: %s?", res, gen.frequency) end else snd_display_prev_caller("%s not a gen?", gen.inspect) end end def test_08_00 set_mus_srate(22050) samps = seconds2samples(1.0) secs = samples2seconds(22050) if samps != 22050 snd_display("seconds2samples: %s?", samps) end if fneq(secs, 1.0) snd_display("samples2seconds: %s?", secs) end set_mus_file_buffer_size($default_file_buffer_size) if (res = Snd.catch do set_mus_file_buffer_size(false) end).first != :wrong_type_arg snd_display("mus_file_buffer_size bad size: %s?", res) end set_mus_file_buffer_size(128) if (res = mus_file_buffer_size) != 128 snd_display("set_mus_file_buffer_size: %s?", res) end set_mus_file_buffer_size($default_file_buffer_size) if (res = mus_array_print_length) != 8 snd_display("mus_array_print_length: %s?", res) end set_mus_array_print_length(12) if (res = mus_array_print_length) != 12 snd_display("mus_array_print_length: %s?", res) end set_mus_array_print_length(32) if (res = mus_array_print_length) != 32 snd_display("set_mus_array_print_length: %s?", res) end set_mus_array_print_length(8) fudge = mus_float_equal_fudge_factor if (mus_float_equal_fudge_factor - 0.0000001).abs > 0.00000001 snd_display("mus_float_equal_fudge_factor: %s?", mus_float_equal_fudge_factor) end set_mus_float_equal_fudge_factor(0.1) if fneq(mus_float_equal_fudge_factor, 0.1) snd_display("set_mus_float_equal_fudge_factor: %s?", mus_float_equal_fudge_factor) end set_mus_float_equal_fudge_factor(fudge) if fneq(mus_srate, 22050.0) snd_display("mus_srate: %s?", mus_srate) end if fneq(res = hz2radians(1.0), 2.84951704088598e-4) snd_display("hz2radians: %s?", res) end if fneq(res = radians2hz(2.84951704088598e-4), 1.0) snd_display("radians2hz: %s?", res) end if fneq(res = radians2degrees(1.0), 57.2957801818848) snd_display("radians2degrees: %s?", res) end if fneq(res = degrees2radians(57.2957801818848), 1.0) snd_display("degrees2radians: %s?", res) end if fneq(res = linear2db(0.25), -12.0411996841431) snd_display("linear2db: %s?", res) end if fneq(res = db2linear(-12.0411996841431), 0.25) snd_display("db2linear: %s?", res) end if fneq(res = ring_modulate(0.4, 0.5), 0.2) snd_display("ring_modulate: %s?", res) end if fneq(res = amplitude_modulate(1.0, 0.5, 0.4), 0.7) snd_display("amplitude_modulate: %s?", res) end if fneq(res = contrast_enhancement(0.1, 0.75), sin(0.1 * (PI / 2) + 0.75 * sin(0.1 * 2.0 * PI))) snd_display("contrast_enhancement: %s (0.562925306221587)", res) end if fneq(res = contrast_enhancement(1.0), 1.0) snd_display("contrast_enhancement: %s (1.0)", res) end # [[partials2polynomial([1, 1, 2, 1], Mus_chebyshev_first_kind), vct(-1.0, 1.0, 2.0)], [partials2polynomial([1, 1, 2, 1], Mus_chebyshev_second_kind), vct(1.0, 2.0, 0.0)], [partials2polynomial([1, 1, 2, 1, 3, 1, 5, 1], Mus_chebyshev_first_kind), vct(-1.0, 3.0, 2.0, -16.0, 0.0, 16.0)], [partials2polynomial([1, 1, 2, 1, 3, 1, 5, 1], Mus_chebyshev_second_kind), vct(1.0, 2.0, -8.0, 0.0, 16.0, 0.0)], [partials2polynomial([1, 1, 2, 0.5, 3, 0.1, 6, 0.01], Mus_chebyshev_first_kind), vct(-0.51, 0.7, 1.18, 0.4, -0.48, 0.0, 0.32)], [partials2polynomial([1, 1, 2, 0.5, 3, 0.1, 6, 0.01], Mus_chebyshev_second_kind), vct(0.9, 1.06, 0.4, -0.32, 0.0, 0.32, 0.0)], [partials2polynomial([1, 9, 2, 3, 3, 5, 4, 7, 5, 1]), vct(4.0, -1.0, -50.0, 0.0, 56.0, 16.0)], [partials2polynomial([7, 1]), vct(0.0, -7.0, 0.0, 56.0, 0.0, -112.0, 0.0, 64.0)], [partials2polynomial([7, 1], Mus_chebyshev_first_kind), vct(0.0, -7.0, 0.0, 56.0, 0.0, -112.0, 0.0, 64.0)], [partials2polynomial([7, 1], Mus_chebyshev_second_kind), vct(-1.0, 0.0, 24.0, 0.0, -80.0, 0.0, 64.0, 0.0)]].each_with_index do |args, i| vals, orig = args unless vequal(vals, orig) snd_display("partials2polynomial[%s]: %s?", i + 1, vals) end end # if defined? cosh lv7 = partials2polynomial([7, 1]) lv8 = partials2polynomial([7, 1], Mus_chebyshev_second_kind) # if fneq(res1 = polynomial(lv7, 1.0), res2 = cosh(7.0 * acosh(1.0))) snd_display("ccosh cheb 7 1.0: %s %s?", res1, res2) end if fneq(res1 = polynomial(lv7, 1.0), res2 = cos(7.0 * acos(1.0))) snd_display("cos cheb 7 1.0: %s %s?", res1, res2) end if fneq(res1 = polynomial(lv8, 1.0), res2 = sin(7.0 * acos(1.0)) / sin(acos(1.0))) snd_display("acos cheb 7 1.0: %s %s?", res1, res2) end 10.times do val = mus_random(1.0) res = polynomial(lv7, val) req = cosh(7.0 * acosh(val)).to_f snd_test_neq(res, req, "ccosh cheb 7 %s", val) res = polynomial(lv7, val) req = cos(7.0 * acos(val)) snd_test_neq(res, req, "cos cheb 7 %s", val) res = polynomial(lv8, val) req = sin(7.0 * acos(val)) / sin(acos(val)) snd_test_neq(res, req, "acos cheb 7 %s", val) end end # # check phase-quadrature cancellations # cos_coeffs = partials2polynomial([1, 1, 2, 1], Mus_chebyshev_first_kind) sin_coeffs = partials2polynomial([1, 1, 2, 1], Mus_chebyshev_second_kind) incr = (2 * PI * 440.0) / 22050.0 a = 0.0 1100.times do x = cos(a) y = sin(a) cax = polynomial(cos_coeffs, x) sax = polynomial(sin_coeffs, x) upper = cos(2 * a) * cax - sin(2 * a) * y * sax lower = cos(2 * a) * cax + sin(2 * a) * y * sax upper2 = cos(a * 3) + cos(a * 4) lower2 = 1.0 + cos(a) if fneq(upper, upper2) or fneq(lower, lower2) snd_display("%s %s, %s %s?", upper, upper2, lower, lower2) end a += incr end # if (res = Snd.catch do harmonicizer(550.0, [0.5, 0.3, 0.2], 10) end).first != :no_data snd_display("odd length arg to partials2polynomial: %s", res.inspect) end rdat = make_vct(16) idat = make_vct(16) vdat = make_vct(16) rdat[0] = 1.0 vdat[0] = 1.0 v0 = spectrum(rdat, idat, make_fft_window(Rectangular_window, 16), 1) v1 = snd_spectrum(vdat, Rectangular_window, 16, true) 8.times do |i| if fneq(v0[i], v1[i]) snd_display("spectra not equal 1: %s %s?", v0, v1) end end idat.scale!(0.0) rdat.scale!(0.0) rdat[0] = 1.0 v0 = spectrum(rdat, idat, make_fft_window(Rectangular_window, 17), 1) v1 = snd_spectrum(vdat, Rectangular_window, 16, true) 8.times do |i| if fneq(v0[i], v1[i]) snd_display("spectra not equal 0: %s %s?", v0, v1) end end if (res = Snd.catch do spectrum(rdat, idat, false, -1) end).first != :out_of_range snd_display("spectrum bad type: %s", res.inspect) end # rdat = make_vct(16) idat = make_vct(16) xdat = make_vct(16) ydat = make_vct(16) rdat[3] = 1.0 xdat[3] = 1.0 fft(rdat, idat, 1) mus_fft(xdat, ydat, 16, 1) if fneq(rdat[0], xdat[0]) snd_display("ffts: %s %s", rdat, xdat) end fft(rdat, idat, -1) mus_fft(xdat, ydat, 17, -1) 16.times do |i| if (i == 3 and (fneq(rdat[i], 16.0) or fneq(xdat[i], 16.0))) or (i != 3 and (fneq(rdat[i], 0.0) or fneq(xdat[i], 0.0))) snd_display("fft real[%s]: %s %s?", i, rdat[i], xdat[i]) end if fneq(idat[i], 0.0) or fneq(ydat[i], 0.0) snd_display("fft imag[%s]: %s %s?", i, idat[i], ydat[i]) end end if (res = Snd.catch do mus_fft(xdat, ydat, -1, 0) end).first != :out_of_range snd_display("mus_fft bad len: %s", res.inspect) end # rdat = make_vct(20) idat = make_vct(19) rdat[3] = 1.0 mus_fft(rdat, idat) convolution(rdat, idat) spectrum(rdat, idat, false) # v0 = make_vct(10) v1 = make_vct(10) vct_fill!(v0, 1.0) vct_fill!(v1, 0.5) v0.map_with_index! do |x, i| x * v1[i] end if fneq(res = dot_product(v0, v1), 2.5) snd_display("dot_product: %s?", res) end if fneq(res = dot_product(v0, v1, 10), 2.5) snd_display("dot_product (10): %s?", res) end if fneq(res = dot_product(v0, v1, 3), 0.75) snd_display("dot_product (3): %s?", res) end v0.map! do |x| 0.0 end if fneq(v0[3], 0.0) snd_display("clear v0: %s?", v0) end vct_fill!(v0, 1.0) vct_fill!(v1, 0.5) if fneq((res = rectangular2polar(v0, v1))[0], 1.118) snd_display("rectangular2polar: %s?", res) end vct_fill!(v0, 1.0) vct_fill!(v1, 1.0) rectangular2polar(v0, v1) if fneq(v0[0], sqrt(2.0)) or fneq(v1[0], -atan2(1.0, 1.0)) snd_display("rectangular2polar (%s %s): %s %s?", sqrt(2.0), -atan2(1.0, 1.0), v0[0], v1[0]) end polar2rectangular(v0, v1) if fneq(v0[0], 1.0) or fneq(v1[0], 1.0) snd_display("polar2rectangular (1 1): %s %s?", v0[0], v1[0]) end # ind = open_sound("oboe.snd") rl = channel2vct(1200, 512) im = make_vct(512) fft(rl, im, 512) rl_copy = vct_copy(rl) im_copy = vct_copy(im) rectangular2polar(rl, im) polar2rectangular(rl, im) 512.times do |i| if fneq(rl[i], rl_copy[i]) or fneq(im[i], im_copy[i]) snd_display("polar2rectangular[%s]: %s %s %s %s?", i, rl[i], rl_copy[i], im[i], im_copy[i]) end end close_sound(ind) # if defined? edot_product # edot_product in dsp.rb vals = make_vct(1, 1.0) if fneq(res = edot_product(0.0, vals), 1.0) snd_display("edot 1.0: %s?", res) end vals[0] = 0.0 if fneq(res = edot_product(0.0, vals), 0.0) snd_display("edot 0.0: %s?", res) end vals = make_array(1, 1.0) if fneq(res = edot_product(0.0, vals), 1.0) snd_display("edot 1.0: %s?", res) end vals[0] = Complex(0.0) if cneq(res = edot_product(0.0, vals), Complex(0.0)) snd_display("edot i: %s?", res) end vals = make_vct(4, 1.0) v1 = edot_product(0.25 * TWO_PI, vals) v2 = exp(0.00 * TWO_PI) + exp(0.25 * TWO_PI) + exp(0.50 * TWO_PI) + exp(0.75 * TWO_PI) if fneq(v1, v2) snd_display("edot 4 i: %s %s?", v1, v2) end vals = make_array(4) do |i| i + 1.0 end v1 = edot_product(0.25 * TWO_PI * Complex(0.0), vals) v2 = 1 * exp(0.00 * TWO_PI * Complex(0.0)) + 2 * exp(0.25 * TWO_PI * Complex(0.0)) + 3 * exp(0.50 * TWO_PI * Complex(0.0)) + 4 * exp(0.75 * TWO_PI * Complex(0.0)) if cneq(v1, v2) snd_display("edot 4 -i: %s %s?", v1, v2) end vals.map! do |i| i + Complex(1.0) end v1 = edot_product(0.25 * TWO_PI * Complex(0.0, -1), vals) v2 = Complex(1.0) * exp(0.00 * TWO_PI * Complex(0.0, -1)) + Complex(2.0) * exp(0.25 * TWO_PI * Complex(0.0, -1)) + Complex(3.0) * exp(0.50 * TWO_PI * Complex(0.0, -1)) + Complex(4.0) * exp(0.75 * TWO_PI * Complex(0.0, -1)) if cneq(v1, v2) snd_display("edot 4 -i * i: %s %s?", v1, v2) end end # v0 = vct(1.0, 0.5, 0.1) if fneq(res0 = polynomial(v0, 0.0), 1.0) or fneq(res1 = polynomial(v0, 1.0), 1.6) or fneq(res2 = polynomial(v0, 2.0), 2.4) snd_display("polynomial: %s %s %s?", res0, res1, res2) end if fneq(res = polynomial(vct(0.0, 2.0), 0.5), 1.0) snd_display("polynomial 2.0 * 0.5: %s?", res) end if (res = Snd.catch do polynomial(false, 1.0) end).first != :wrong_type_arg snd_display("polynomial empty coeffs: %s", res.inspect) end # coeffs = vct(1.0, 0.0, -0.4999999963, 0.0, 0.0416666418, 0.0, -0.0013888397, 0.0, 0.0000247609, 0.0, -0.0000002605) new_cos = lambda do |x| if (x = x.abs) <= HALF_PI polynomial(coeffs, x) elsif (nx = fmod(x, TWO_PI)) <= HALF_PI polynomial(coeffs, nx) elsif nx <= PI -polynomial(coeffs, PI - nx) elsif nx < 1.5 * PI -polynomial(coeffs, nx - PI) else polynomial(coeffs, TWO_PI - nx) end end err = 0.0 x = -10.0 2000.times do |i| diff = (cos(x) - new_cos.call(x)).abs if diff > err err = diff end x += 0.01 end if err > 1.1e-7 snd_display("new_cos poly err: %s?", err) end # # POLY # res = poly(0.1, 0.2, 0.3) + vct(0, 1, 2, 3, 4) req = vct(0.1, 1.2, 2.3, 3, 4) snd_test_neq(res, req, "poly_add 1") res = poly(0.1, 0.2, 0.3) + 0.5 req = vct(0.6, 0.2, 0.3) snd_test_neq(res, req, "poly_add 2") res = 0.5 + poly(0.1, 0.2, 0.3) req = vct(0.6, 0.2, 0.3) snd_test_neq(res, req, "poly_add 3") # res = poly(1, 1) * vct(-1, 1) req = vct(-1, 0, 1, 0) snd_test_neq(res, req, "poly_multiply 1") res = poly(-5, 1) * vct(3, 7, 2) req = vct(-15, -32, -3, 2, 0) snd_test_neq(res, req, "poly_multiply 2") res = poly(-30, -4, 2) * vct(0.5, 1) req = vct(-15, -32, -3, 2, 0) snd_test_neq(res, req, "poly_multiply 3") res = poly(-30, -4, 2) * 0.5 req = vct(-15, -2, 1) snd_test_neq(res, req, "poly_multiply 4") res = 2.0 * poly(-30, -4, 2) req = vct(-60, -8, 4) snd_test_neq(res, req, "poly_multiply 5") # res = poly(-1, 0, 1) / vct(1, 1) req1 = vct(-1, 1, 0) req2 = vct(0, 0, 0) unless vequal(res[0], req1) or vequal(res[1], req2) snd_format_neq(res[0], req1, "poly_div 1a") snd_format_neq(res[1], req2, "poly_div 1b") end res = poly(-15, -32, -3, 2) / vct(-5, 1) req1 = vct(3, 7, 2, 0) req2 = vct(0, 0, 0, 0) unless vequal(res[0], req1) or vequal(res[1], req2) snd_format_neq(res[0], req1, "poly_div 2a") snd_format_neq(res[1], req2, "poly_div 2b") end res = poly(-15, -32, -3, 2) / vct(3, 1) req1 = vct(-5, -9, 2, 0) req2 = vct(0, 0, 0, 0) unless vequal(res[0], req1) or vequal(res[1], req2) snd_format_neq(res[0], req1, "poly_div 3a") snd_format_neq(res[1], req2, "poly_div 3b") end res = poly(-15, -32, -3, 2) / vct(0.5, 1) req1 = vct(-30, -4, 2, 0) req2 = vct(0, 0, 0, 0) unless vequal(res[0], req1) or vequal(res[1], req2) snd_format_neq(res[0], req1, "poly_div 4a") snd_format_neq(res[1], req2, "poly_div 4b") end res = poly(-15, -32, -3, 2) / vct(3, 7, 2) req1 = vct(-5, 1, 0, 0) req2 = vct(0, 0, 0, 0) unless vequal(res[0], req1) or vequal(res[1], req2) snd_format_neq(res[0], req1, "poly_div 5a") snd_format_neq(res[1], req2, "poly_div 5b") end res = poly(-15, -32, -3, 2) / 2.0 req = vct(-7.5, -16, -1.5, 1) snd_test_neq(res[0], req, "poly_div 6") res = poly(-1, 0, 0, 0, 1) / vct(1, 0, 1) req1 = vct(-1, 0, 1, 0, 0) req2 = vct(0, 0, 0, 0, 0) unless vequal(res[0], req1) or vequal(res[1], req2) snd_format_neq(res[0], req1, "poly_div 7a") snd_format_neq(res[1], req2, "poly_div 7b") end res = poly(-1, 0, 0, 0, 0, 0, 0, 0, 1) / vct(1, 0, 0, 0, 1) req1 = vct(-1, 0, 0, 0, 1, 0, 0, 0, 0) req2 = vct(0, 0, 0, 0, 0, 0, 0, 0, 0) unless vequal(res[0], req1) or vequal(res[1], req2) snd_format_neq(res[0], req1, "poly_div 8a") snd_format_neq(res[1], req2, "poly_div 8b") end res = poly(-1, 0, 1) / vct(-1, 0, 1) req1 = vct(1, 0, 0) req2 = vct(0, 0, 0) snd_format_neq(res[0], req1, "poly_div 9a") snd_format_neq(res[1], req2, "poly_div 9b") res = poly(-1, 0, 1) / vct(2, 1) req1 = vct(-2, 1, 0) req2 = vct(3, 0, 0) unless vequal(res[0], req1) or vequal(res[1], req2) snd_format_neq(res[0], req1, "poly_div 10a") snd_format_neq(res[1], req2, "poly_div 10b") end res = poly(2, 1) / vct(-1, 0, 1) req1 = vct(0) req2 = vct(-1, 0, 1) unless vequal(res[0], req1) or vequal(res[1], req2) snd_format_neq(res[0], req1, "poly_div 11a") snd_format_neq(res[1], req2, "poly_div 11b") end res = poly(1, 2, 3, 0, 1) / vct(0, 0, 0, 1) req1 = vct(0, 1, 0, 0, 0) req2 = vct(1, 2, 3, 0, 0) unless vequal(res[0], req1) or vequal(res[1], req2) snd_format_neq(res[0], req1, "poly_div 12a") snd_format_neq(res[1], req2, "poly_div 12b") end # ind = open_sound("1a.snd") v1 = channel2vct(0, 100, ind, 0) v2 = channel2vct(0, 100, ind, 0) res = poly_div(v1, v2)[0] req = make_vct(100) req[0] = 1.0 snd_test_neq(res, req, "poly1 1a") close_sound(ind) # res = poly(0.5, 1, 2, 4).derivative req = vct(1, 4, 12) snd_test_neq(res, req, "poly_derivative") # res = poly(1, 2, 3).reduce req = vct(1, 2, 3) snd_test_neq(res, req, "reduce 1") res = poly(1, 2, 3, 0, 0, 0).reduce req = vct(1, 2, 3) snd_test_neq(res, req, "reduce 2") res = poly(0, 0, 0, 0, 1, 0).reduce req = vct(0, 0, 0, 0, 1) snd_test_neq(res, req, "reduce 3") # res = (poly(2, 1) * vct(-3, 1)).reduce.gcd(vct(2, 1)) req = vct(2, 1) snd_test_neq(res, req, "poly_gcd 1") res = (poly(2, 1) * vct(-3, 1)).reduce.gcd(vct(3, 1)) req = vct(0) snd_test_neq(res, req, "poly_gcd 2") res = (poly(2, 1) * vct(-3, 1)).reduce.gcd(vct(-3, 1)) req = vct(-3, 1) snd_test_neq(res, req, "poly_gcd 3") res = (poly(8, 1) * poly(2, 1) * poly(-3, 1)).reduce.gcd(vct(-3, 1)) req = vct(-3, 1) snd_test_neq(res, req, "poly_gcd 4") res = poly(8, 1) * poly(2, 1) * [-3, 1] res = res.reduce.gcd((poly(8, 1) * [-3, 1]).reduce) req = vct(-24, 5, 1) snd_test_neq(res, req, "poly_gcd 5") res = poly(-1, 0, 1).gcd([2, -2, -1, 1]) req = [0] snd_test_neq(res, req, "poly_gcd 6") res = poly(2, -2, -1, 1).gcd([-1, 0, 1]) req = [1, -1] snd_test_neq(res, req, "poly_gcd 7") res = poly(2, -2, -1, 1).gcd([-2.5, 1]) req = [0] snd_test_neq(res, req, "poly_gcd 8") # poly_roots_tests() # res = poly(-1, 0, 1).resultant([1, -2, 1]) req = 0.0 snd_test_neq(res, req, "poly_resultant 0") res = poly(-1, 0, 2).resultant([1, -2, 1]) req = 1.0 snd_test_neq(res, req, "poly_resultant 1") res = poly(-1, 0, 1).resultant([1, 1]) req = 0.0 snd_test_neq(res, req, "poly_resultant 2") res = poly(-1, 0, 1).resultant([2, 1]) req = 3.0 snd_test_neq(res, req, "poly_resultant 3") # res = poly(-1, 0, 1).discriminant req = -4.0 snd_test_neq(res, req, "poly_discriminant 0") res = poly(1, -2, 1).discriminant req = 0.0 snd_test_neq(res, req, "poly_discriminant 1") res = (poly(-1, 1) * poly(-1, 1) * poly(3, 1)).reduce.discriminant req = 0.0 snd_test_neq(res, req, "poly_discriminant 2") res = (poly(-1, 1) * poly(-1, 1) * poly(3, 1) * poly(2, 1)).reduce.discriminant req = 0.0 snd_test_neq(res, req, "poly_discriminant 3") res = (poly(1, 1) * poly(-1, 1) * poly(3, 1) * poly(2, 1)).reduce.discriminant req = 2304.0 snd_test_neq(res, req, "poly_discriminant 4") res = (poly(1, 1) * poly(-1, 1) * poly(3, 1) * poly(3, 1)).reduce.discriminant req = 0.0 snd_test_neq(res, req, "poly_discriminant 5") # v0 = make_vct!(10) do |i| i end if fneq(res = array_interp(v0, 3.5), 3.5) snd_display("array_interp: %s?", res) end if fneq(res = array_interp(v0, 13.5), 3.5) snd_display("array_interp (13.5): %s?", res) end if fneq(res = array_interp(v0, -6.5), 3.5) snd_display("array_interp (-6.5): %s?", res) end if fneq(res = array_interp(v0, 103.6), 3.6) snd_display("array_interp (103.6): %s?", res) end if fneq(res = array_interp(v0, -106.6), 3.4) snd_display("array_interp (-106.6): %s?", res) end if fneq(res = array_interp(v0, -0.5), 4.5) snd_display("array_interp (-0.5): %s?", res) end if fneq(res = array_interp(v0, -0.9), 8.1) snd_display("array_interp (-0.9): %s?", res) end if fneq(res = array_interp(v0, -0.1), 0.9) snd_display("array_interp (-0.1): %s?", res) end if fneq(res = array_interp(v0, 9.1), 8.1) snd_display("array_interp (9.1): %s?", res) end if fneq(res = array_interp(v0, 9.9), 0.9) snd_display("array_interp (9.9): %s?", res) end if fneq(res = array_interp(v0, 10.1), 0.1) snd_display("array_interp (10.1): %s?", res) end if (res = Snd.catch do array_interp(v0, 1, -10) end).first != :out_of_range snd_display("array_interp bad index: %s", res.inspect) end # v0 = make_vct!(10) do |i| i end if fneq(res = mus_interpolate(Mus_interp_linear, 1.5, v0), 1.5) snd_display("mus_interpolate linear: %s?", res) end if fneq(res = mus_interpolate(Mus_interp_all_pass, 1.5, v0), 1.5) snd_display("mus_interpolate all-pass: %s?", res) end if fneq(res = mus_interpolate(Mus_interp_none, 1.5, v0), 1.0) snd_display("mus_interpolate none: %s?", res) end if fneq(res = mus_interpolate(Mus_interp_hermite, 1.5, v0), 1.5) snd_display("mus_interpolate hermite: %s?", res) end if fneq(res = mus_interpolate(Mus_interp_bezier, 1.5, v0), 1.5) snd_display("mus_interpolate bezier: %s?", res) end if fneq(res = mus_interpolate(Mus_interp_lagrange, 1.5, v0), 1.5) snd_display("mus_interpolate lagrange: %s?", res) end v0.map_with_index! do |val, i| sin(PI * (i / 5.0)) end if fneq(res = mus_interpolate(Mus_interp_linear, 1.5, v0), 0.7694) snd_display("mus_interpolate linear sin: %s?", res) end if fneq(res = mus_interpolate(Mus_interp_all_pass, 1.5, v0), 0.7694) snd_display("mus_interpolate all-pass sin: %s?", res) end if fneq(res = mus_interpolate(Mus_interp_none, 1.5, v0), 0.5877) snd_display("mus_interpolate none sin: %s?", res) end if fneq(res = mus_interpolate(Mus_interp_hermite, 1.5, v0), 0.8061) snd_display("mus_interpolate hermite sin: %s?", res) end if fneq(res = mus_interpolate(Mus_interp_bezier, 1.5, v0), 0.6959) snd_display("mus_interpolate bezier sin: %s?", res) end if fneq(res = mus_interpolate(Mus_interp_lagrange, 1.5, v0), 0.7975) snd_display("mus_interpolate lagrange sin: %s?", res) end if (res = Snd.catch do mus_interpolate(1234, 1.0, make_vct(3)) end).first != :out_of_range snd_display("mus_interpolate 1234: %s", res.inspect) end if (res = Snd.catch do mus_interpolate(Mus_interp_linear, 1.0, make_vct(3), -1) end).first != :out_of_range snd_display("mus_interpolate size -1: %s", res.inspect) end end def test_08_01 gen = make_delay(3) gen2 = make_delay(3) gen1 = make_delay(4, :initial_contents, [1.0, 0.5, 0.25, 0.0]) gen3 = make_delay(4, :initial_contents, vct(1.0, 0.5, 0.25, 0.0)) print_and_check(gen, "delay", "delay line[3, step]: [0 0 0]") v0 = make_vct!(10) do |i| delay(gen, i) end v1 = make_vct!(10) do |i| delay?(gen2) ? delay(gen2, i) : -1.0 end unless vequal(v1, v0) snd_display("map delay: %s %s?", v0, v1) end unless delay?(gen) snd_display("%s not a delay?", gen) end if gen.length != 3 snd_display("delay length: %s?", gen.length) end if fneq(v0[1], 0.0) or fneq(v0[4], 1.0) or fneq(v0[8], 5.0) snd_display("delay output: %s?", v0) end if fneq(delay(gen1), 1.0) or fneq(delay(gen1), 0.5) or fneq(delay(gen1), 0.25) or fneq(delay(gen1), 0.0) or fneq(delay(gen1), 0.0) snd_display("delay with list initial-contents confused") end if fneq(delay(gen3), 1.0) or fneq(delay(gen3), 0.5) or fneq(delay(gen3), 0.25) or fneq(delay(gen3), 0.0) or fneq(delay(gen3), 0.0) snd_display("delay with vct initial-contents confused") end if (res = Snd.catch do make_delay(:size, false) end).first != :wrong_type_arg snd_display("make_delay bad size false: %s", res.inspect) end if (res = Snd.catch do make_delay(3, :initial_element, make_oscil) end).first != :wrong_type_arg snd_display("make_delay bad initial element: %s", res.inspect) end if (res = Snd.catch do make_delay(-3) end).first != :out_of_range snd_display("make_delay bad size: %s", res.inspect) end d1 = make_delay(3) d2 = make_delay(3) d3 = make_delay(4) delay(d1, 1.0) delay(d2, 1.0) delay(d3, 1.0) test_gen_equal(d1, d2, d3) test_gen_equal(make_delay(3, :initial_element, 1.0), make_delay(3, :initial_element, 1.0), make_delay(3, :initial_element, 0.5)) test_gen_equal(make_delay(3, :initial_contents, [1.0, 0.0, 0.0]), make_delay(3, :initial_contents, [1.0, 0.0, 0.0]), make_delay(3, :initial_contents, [1.0, 1.0, 1.0])) gen = make_delay(5) delay(gen, 1.0) delay(gen, 0.0) delay(gen, 0.5) data = vct_copy(gen.data) gen.data[0] = 0.3 if fneq(gen.data[0], 0.3) snd_display("delay data 0: %s?", gen.data[0]) end data[0] = 0.75 gen.data = data if fneq(gen.data[0], 0.75) snd_display("delay set data 0: %s?", gen.data[0]) end delay(gen, 0.0) delay(gen, 0.0) if fneq(res = delay(gen, 0.0), 0.75) snd_display("set delay data: %s %s?", res, gen.data) end if res = make_oscil.data snd_display("mus_data osc: %s?", res) end # del = make_delay(5, :max_size, 8) delay(del, 1.0) 4.times do delay(del, 0.0) end v0 = make_vct!(5) do delay(del, 0.0, 0.4) end unless vequal(v0, vct(0.6, 0.4, 0.0, 0.0, 0.0)) snd_display("zdelay: %s?", v0) end delay(del, 1.0) delay(del, 0.0, 0.4) if (res = del.to_s) != "delay line[5,8, linear]: [0 0 1 0 0]" snd_display("describe zdelay: %s", res) end if (res = Snd.catch do tap(make_oscil) end).first != :wrong_type_arg snd_display("tap of oscil: %s?", res.inspect) end # dly = make_delay(3) flt = make_one_zero(0.5, 0.4) v = make_vct(20) inval = 1.0 v.map! do |x| res = delay(dly, inval + one_zero(flt, tap(dly)) * 0.6) inval = 0.0 res end unless vequal(v, vct(0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.3, 0.24, 0.0, 0.09, 0.144, 0.058, 0.027, 0.065, 0.052, 0.022, 0.026, 0.031, 0.019, 0.013)) snd_display("tap with low pass: %s?", v) end # dly = make_delay(3) v = make_vct(20) inval = 1.0 v.map! do |x| res = delay(dly, inval + tap(dly)) inval = 0.0 res end unless vequal(v, vct(0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0)) snd_display("simple tap: %s?", v) end dly = make_delay(6) v = make_vct(20) inval = 1.0 snd_test_neq(tap?(dly), true, "tap?") v.map! do |x| res = delay(dly, inval + tap(dly, -2.0)) inval = 0.0 res end unless vequal(v, vct(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0)) snd_display("tap back 2: %s?", v) end # dly = make_delay(3, :initial_element, 32.0) unless vct?(dly.data) snd_display("delay data not vct?") else if dly.data.length != 3 snd_display("delay data len not 3: %s (%s)?", dly.data.length, dly.data) else if fneq(res = dly.data[1], 32.0) snd_display("delay [1] 32: %s?", res) end end end if (res = Snd.catch do dly.length = -1 end).first != :out_of_range snd_display("len to -1 -> %s?", res.inspect) end if (res = Snd.catch do dly.length = 0 end).first != :out_of_range snd_display("len to 0 -> %s?", res.inspect) end if (res = Snd.catch do dly.length = 100 end).first != :out_of_range snd_display("len to 100 -> %s?", res.inspect) end if (res = Snd.catch do dly.data[100] = 0.1 end).first != :out_of_range snd_display("data 100 to 0.1 -> %s?", res.inspect) end data = make_vct(32, 1.0) dly.data = data unless vct?(dly.data) snd_display("set delay data not vct?") end if fneq(dly.data[1], 1.0) snd_display("set delay [1] 1: %s?", dly.data[1]) end if dly.data.length != 32 snd_display("set delay data len(32): %s?", dly.data.length) end if (res = Snd.catch do dly.length = 100 end).first != :out_of_range snd_display("set len to 100 -> %s", res.inspect) end if (res = Snd.catch do dly.data[100] = 0.1 end).first != :out_of_range snd_display("set data 100 to 0.1 -> %s", res.inspect) end # d1 = make_delay(4) d2 = make_delay(4, :max_size, 5, :type, Mus_interp_linear) d3 = make_delay(4, :max_size, 5, :type, Mus_interp_all_pass) d4 = make_delay(4, :max_size, 5, :type, Mus_interp_none) d5 = make_delay(4, :max_size, 4, :type, Mus_interp_lagrange) d6 = make_delay(4, :max_size, 4, :type, Mus_interp_hermite) d7 = make_delay(4, :max_size, 4, :type, Mus_interp_linear) v1 = make_vct(20) v2 = make_vct(20) v3 = make_vct(20) v4 = make_vct(20) v5 = make_vct(20) v6 = make_vct(20) v7 = make_vct(20) [[d1, Mus_interp_none], [d2, Mus_interp_linear], [d3, Mus_interp_all_pass], [d4, Mus_interp_none], [d5, Mus_interp_lagrange], [d6, Mus_interp_hermite], [d7, Mus_interp_linear]].each_with_index do |args, i| dly, type = args if dly.interp_type != type snd_display("d%s interp type: %s?", i + 1, dly.interp_type) end end [[v1, d1], [v2, d2], [v3, d3], [v4, d4], [v5, d5], [v6, d6], [v7, d7]].each do |v, d| v[0] = delay(d, 1.0) delay_tick(d, 0.0) end j = -0.2 (1...20).each do |i| [[v1, d1], [v2, d2], [v3, d3], [v4, d4], [v5, d5], [v6, d6], [v7, d7]].each do |v, d| v[i] = tap(d, j) end j -= 0.2 end if (not vequal(v1, vct(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0))) and (not vequal(v1, vct(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0))) snd_display("delay interp none (1): %s?", v1) end unless vequal(v2, vct(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 0.8, 0.6, 0.4, 0.2, 0.0, 0.0, 0.0, 0.0, 0.0)) snd_display("delay interp linear (2): %s?", v2) end unless vequal(v3, vct(0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.6, 0.16, 0.168, -0.168, 0.334, 0.199, 0.52, 0.696, -0.696, 0.557, -0.334, 0.134, -0.027)) snd_display("delay interp all-pass (3): %s?", v3) end if (not vequal(v4, vct(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0))) and (not vequal(v4, vct(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0))) snd_display("delay interp none (4): %s?", v4) end unless vequal(v5, vct(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.12, 0.28, 0.48, 0.72, 1.0, 0.96, 0.84, 0.64, 0.36, 0.0, -0.08, -0.12, -0.12, -0.08)) snd_display("delay interp lagrange (5): %s?", v5) end unless vequal(v6, vct(0.0, -0.016, -0.048, -0.072, -0.064, 0.0, 0.168, 0.424, 0.696, 0.912, 1.0, 0.912, 0.696, 0.424, 0.168, 0.0, -0.064, -0.072, -0.048, -0.016)) snd_display("delay interp hermite (6): %s?", v6) end unless vequal(v7, vct(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 0.8, 0.6, 0.4, 0.2, 0.0, 0.0, 0.0, 0.0, 0.0)) snd_display("delay interp linear (7): %s?", v7) end # dly = make_delay(:size, 2, :max_size, 3) impulse = 1.0 data = make_vct!(5) do val = delay(dly, impulse, 0.4) impulse = 0.0 val end unless vequal(data, vct(0.0, 0.0, 0.6, 0.4, 0.0)) snd_display("delay size 2, max 3, off 0.4: %s", data) end dly = make_delay(:size, 2, :max_size, 3) impulse = 1.0 data = make_vct!(5) do val = delay(dly, impulse, -0.4) impulse = 0.0 val end unless vequal(data, vct(0.0, 0.4, 0.6, 0.0, 0.0)) snd_display("delay size 2, max 3, off -0.4: %s", data) end # dly = make_delay(:size, 1, :max_size, 2) impulse = 1.0 data = make_vct!(5) do val = delay(dly, impulse, 0.4) impulse = 0.0 val end unless vequal(data, vct(0.0, 0.6, 0.4, 0.0, 0.0)) snd_display("delay size 1, max 2, off 0.4: %s", data) end # dly = make_delay(:size, 0, :max_size, 1) impulse = 1.0 data = make_vct!(5) do val = delay(dly, impulse, 0.4) impulse = 0.0 val end unless vequal(data, vct(0.6, 0.4, 0.0, 0.0, 0.0)) snd_display("delay size 0, max 1, off 0.4: %s", data) end dly = make_delay(:size, 0, :max_size, 1) if fneq(res = delay(dly, 0.0), 0.0) snd_display("initial delay 0 size val: %s?", res) end dly = make_delay(:size, 0, :max_size, 1) impulse = 1.0 data = make_vct!(5) do val = delay(dly, impulse, -0.4) impulse = 0.0 val end unless vequal(data, vct(1.4, -0.4, 0.0, 0.0, 0.0)) snd_display("delay size 0, max 1, off -0.4: %s", data) end dly = make_delay(:size, 0, :max_size, 100) v = make_vct!(10) do |i| delay(dly, 0.5, i) end unless vequal(v, vct(0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)) snd_display("delay 0 -> 100: %s", v) end 9.downto(0) do |i| v[i] = delay(dly, 0.5, i) end unless vequal(v, vct(0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5)) snd_display("delay 100 -> 0: %s", v) end dly.reset unless vequal(dly.data, Vct.new(100, 0.0)) snd_display("after reset mus-data delay peak: %s?", dly.data.peak) end 10.times do |i| v[i] = delay(dly, (i.odd? ? 1.0 : 0.0), i * 0.1) end unless vequal(v, vct(0.0, 0.9, 0.0, 0.7, 0.0, 0.5, 0.0, 0.3, 0.0, 0.1)) snd_display("delay 0 -> 100 0.1: %s", v) end dly.reset 10.times do |i| v[i] = delay(dly, (i.odd? ? 1.0 : 0.0), 1.0 + i * 0.1) end unless vequal(v, vct(0.0, 0.0, 0.8, 0.3, 0.6, 0.5, 0.4, 0.7, 0.2, 0.9)) snd_display("delay 0 -> 100 1.1: %s", v) end end def test_08_02 gen = make_all_pass(0.4, 0.6, 3) gen1 = make_all_pass(0.4, 0.6, 3) print_and_check(gen, "all-pass", "all-pass feedback: 0.400, feedforward: 0.600, line[3, step]:[0 0 0]") v0 = make_vct!(10) do all_pass(gen, 1.0) end v1 = make_vct(10) v1.map! do |x| all_pass?(gen1) ? all_pass(gen1, 1.0) : -1.0 end unless vequal(v0, v1) snd_display("map all-pass: %s %s?", v0, v1) end unless all_pass?(gen) snd_display("%s not all-pass?", gen) end if gen.length != 3 snd_display("all-pass length: %s?", gen.length) end if gen.order != 3 snd_display("all-pass order: %s?", gen.order) end if fneq(gen.feedback, 0.4) snd_display("all-pass feedback: %s?", gen.feedback) end if fneq(gen.feedforward, 0.6) snd_display("all-pass feedforward: %s?", gen.feedforward) end if fneq(v0[1], 0.6) or fneq(v0[4], 1.84) or fneq(v0[8], 2.336) snd_display("all-pass output: %s?", v0) end gen.feedback = 0.5 if fneq(gen.feedback, 0.5) snd_display("all-pass set_feedback: %s?", gen.feedback) end gen.feedforward = 0.5 if fneq(gen.feedforward, 0.5) snd_display("all-pass set_feedforward: %s?", gen.feedforward) end d1 = make_all_pass(0.7, 0.5, 3) d2 = make_all_pass(0.7, 0.5, 3) d3 = make_all_pass(0.7, 0.5, 4) all_pass(d1, 1.0) all_pass(d2, 1.0) all_pass(d3, 1.0) test_gen_equal(d1, d2, d3) test_gen_equal(make_all_pass(0.7, 0.5, 3, :initial_element, 1.0), make_all_pass(0.7, 0.5, 3, :initial_element, 1.0), make_all_pass(0.7, 0.5, 3, :initial_element, 0.5)) test_gen_equal(make_all_pass(0.7, 0.5, 3, :initial_element, 1.0), make_all_pass(0.7, 0.5, 3, :initial_element, 1.0), make_all_pass(0.5, 0.5, 3, :initial_element, 1.0)) test_gen_equal(make_all_pass(0.7, 0.5, 3, :initial_contents, [1.0, 0.0, 0.0]), make_all_pass(0.7, 0.5, 3, :initial_contents, [1.0, 0.0, 0.0]), make_all_pass(0.7, 0.5, 3, :initial_contents, [1.0, 1.0, 1.0])) err = Snd.catch do make_all_pass(:feedback, 0.2, :feedforward, 0.1, :size, -1) end if err.first != :out_of_range or err[1] != "make_all_pass" or err[2] != "size _1 < 0?" or snd_display("make_all_pass bad size error message: %s", err.inspect) end # gen = make_moving_average(4) gen1 = make_moving_average(4) print_and_check(gen, "moving-average", "moving-average 0.000, line[4]:[0 0 0 0]") v0 = make_vct!(10) do moving_average(gen, 1.0) end v1 = make_vct(10) v1.map! do |x| moving_average?(gen1) ? moving_average(gen1, 1.0) : -1.0 end unless vequal(v0, v1) snd_display("map moving_average: %s %s?", v0, v1) end unless moving_average?(gen) snd_display("%s not moving_average?", gen) end if gen.length != 4 snd_display("moving-average length: %s?", gen.length) end if gen.order != 4 snd_display("moving-average order: %s?", gen.order) end if fneq(v0[1], 0.5) or fneq(v0[4], 1.0) or fneq(v0[8], 1.0) snd_display("moving-average output: %s?", v0) end gen = make_moving_average(8) if fneq(val = moving_average(gen), 0.0) snd_display("empty moving_average: %s?", val) end if fneq(val = moving_average(gen, 1.0), 0.125) snd_display("moving-average 1: %s?", val) end if fneq(val = moving_average(gen, 1.0), 0.25) snd_display("moving-average 2: %s?", val) end if fneq(val = moving_average(gen, 0.5), 0.3125) snd_display("moving-average 2: %s?", val) end 4.times do moving_average(gen, 0.0) end if fneq(val = moving_average(gen, 0.0), 0.3125) snd_display("moving-average 6: %s?", val) end if fneq(val = moving_average(gen, 0.0), 0.1875) snd_display("moving-average 7: %s?", val) end if fneq(val = moving_average(gen, 0.0), 0.0625) snd_display("moving-average 8: %s?", val) end if fneq(val = moving_average(gen, 0.0), 0.0) snd_display("moving-average 9: %s?", val) end gen = make_moving_average(10, :initial_element, 0.5) if fneq(val = moving_average(gen, 0.5), 0.5) snd_display("moving-average initial_element: %s?", val) end gen = make_moving_average(3, :initial_contents, [1.0, 1.0, 1.0]) if fneq(val = moving_average(gen, 1.0), 1.0) snd_display("moving-average initial_contents: %s?", val) end d1 = make_moving_average(3, :initial_contents, [0.7, 0.5, 3]) d2 = make_moving_average(3, :initial_contents, vct(0.7, 0.5, 3)) d3 = make_moving_average(4, :initial_contents, [0.7, 0.5, 0.1, 4]) moving_average(d1, 1.0) moving_average(d2, 1.0) moving_average(d3, 1.0) test_gen_equal(d1, d2, d3) test_gen_equal(make_moving_average(3, :initial_element, 1.0), make_moving_average(3, :initial_element, 1.0), make_moving_average(3, :initial_element, 0.5)) test_gen_equal(make_moving_average(3, :initial_element, 1.0), make_moving_average(3, :initial_element, 1.0), make_moving_average(4, :initial_element, 1.0)) test_gen_equal(make_moving_average(3, :initial_contents, [1.0, 0.0, 0.0]), make_moving_average(3, :initial_contents, [1.0, 0.0, 0.0]), make_moving_average(3, :initial_contents, [1.0, 1.0, 1.0])) err = Snd.catch do make_moving_average(:size, -1) end if err.first != :out_of_range or err[1] != "make_moving_average" or err[2] != "size -1 < 0?" or snd_display("make_moving_average bad size error message: %s", err.inspect) end # gen = make_comb(0.4, 3) gen1 = make_comb(0.4, 3) print_and_check(gen, "comb", "comb scaler: 0.400, line[3, step]: [0 0 0]") v0 = make_vct!(10) do comb(gen, 1.0) end v1 = make_vct(10) v1.map! do |x| comb?(gen1) ? comb(gen1, 1.0) : -1.0 end unless vequal(v0, v1) snd_display("map comb: %s %s?", v0, v1) end unless comb?(gen) snd_display("%s not comb?", gen) end if gen.length != 3 snd_display("comb length: %s?", gen.length) end if gen.order != 3 snd_display("comb order: %s?", gen.order) end if fneq(gen.feedback, 0.4) snd_display("comb feedback: %s?", gen.feedback) end if fneq(v0[1], 0.0) or fneq(v0[4], 1.0) or fneq(v0[8], 1.4) snd_display("comb output: %s?", v0) end d1 = make_comb(0.7, 3) d2 = make_comb(0.7, 3) d3 = make_comb(0.7, 4) comb(d1, 1.0) comb(d2, 1.0) comb(d3, 1.0) test_gen_equal(d1, d2, d3) test_gen_equal(make_comb(0.7, 3, :initial_element, 1.0), make_comb(0.7, 3, :initial_element, 1.0), make_comb(0.7, 3, :initial_element, 0.5)) test_gen_equal(make_comb(0.7, 3, :initial_element, 1.0), make_comb(0.7, 3, :initial_element, 1.0), make_comb(0.5, 3, :initial_element, 1.0)) test_gen_equal(make_comb(0.7, 3, :initial_contents, [1.0, 0.0, 0.0]), make_comb(0.7, 3, :initial_contents, [1.0, 0.0, 0.0]), make_comb(0.7, 3, :initial_contents, [1.0, 1.0, 1.0])) del = make_comb(0.0, 5, :max_size, 8) comb(del, 1.0) 4.times do comb(del, 0.0) end v0 = make_vct!(5) do comb(del, 0.0, 0.4) end unless vequal(v0, vct(0.600, 0.400, 0.000, 0.000, 0.000)) snd_display("zcomb: %s", v0) end comb(del, 1.0) comb(del, 0.0, 0.4) if (res = del.to_s) != "comb scaler: 0.000, line[5,8, linear]: [0 0 1 0 0]" snd_display("describe zcomb: %s", res) end del.feedback = 1.0 if fneq(del.feedback, 1.0) snd_display("comb feedback set: %s?", del.feedback) end # gen = make_filtered_comb(0.4, 5, :filter, make_one_zero(0.3, 0.7)) print_and_check(gen, "filtered-comb", "filtered-comb scaler: 0.400, line[5, step]: [0 0 0 0 0], filter: [one-zero a0: 0.300, a1: 0.700, x1: 0.000]") v0 = make_vct!(20) do |i| filtered_comb(gen, (i.zero? ? 1.0 : 0.0)) end v1 = vct(0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0.12, 0.28, 0, 0, 0, 0.014, 0.067, 0.078, 0, 0) snd_test_neq(v0, v1, "filtered_comb") unless filtered_comb?(gen) snd_display("%s not filtered_comb?", gen) end if gen.length != 5 snd_display("filtered_comb length: %s?", gen.length) end if gen.order != 5 snd_display("filtered_comb order: %s?", gen.order) end if fneq(gen.feedback, 0.4) snd_display("filtered_comb feedback: %s?", gen.feedback) end gen = make_filtered_comb(0.9, 5, :filter, make_one_zero(0.5, 0.5)) print_and_check(gen, "filtered-comb", "filtered-comb scaler: 0.900, line[5, step]: [0 0 0 0 0], filter: [one-zero a0: 0.500, a1: 0.500, x1: 0.000]") v0 = make_vct!(20) do |i| filtered_comb(gen, (i.zero? ? 1.0 : 0.0)) end v1 = vct(0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0.45, 0.45, 0, 0, 0, 0.202, 0.405, 0.202, 0, 0) snd_test_neq(v0, v1, "filtered_comb: 0.5 0.5") gen = make_filtered_comb(0.9, 5, :filter, make_fir_filter(5, vct(0.1, 0.2, 0.3, 0.2, 0.1))) print_and_check(gen, "filtered-comb", "filtered-comb scaler: 0.900, line[5, step]: [0 0 0 0 0], filter: [fir-filter order: 5, xs: [0.1 0.2 0.3 0.2 0.1]]") v0 = make_vct!(20) do |i| filtered_comb(gen, (i.zero? ? 1.0 : 0.0)) end v1 = vct(0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0.09, 0.18, 0.27, 0.18, 0.09, 0.008, 0.032, 0.081, 0.13, 0.154) snd_test_neq(v0, v1, "filtered_comb (fir)") d1 = make_filtered_comb(0.7, 3, :filter, make_one_pole(0.3, 0.7)) d2 = make_filtered_comb(0.7, 3, :filter, make_one_pole(0.3, 0.7)) d3 = make_filtered_comb(0.7, 4, :filter, make_one_pole(0.3, 0.7)) filtered_comb(d1, 1.0) filtered_comb(d2, 1.0) filtered_comb(d3, 1.0) test_gen_equal(d1, d2, d3) test_gen_equal(make_filtered_comb(0.7, 3, :initial_element, 1.0, :filter, make_one_zero(0.5, 0.5)), make_filtered_comb(0.7, 3, :initial_element, 1.0, :filter, make_one_zero(0.5, 0.5)), make_filtered_comb(0.7, 3, :initial_element, 0.5, :filter, make_one_zero(0.5, 0.5))) test_gen_equal(make_filtered_comb(0.7, 3, :initial_element, 1.0, :filter, make_one_zero(0.5, 0.5)), make_filtered_comb(0.7, 3, :initial_element, 1.0, :filter, make_one_zero(0.5, 0.5)), make_filtered_comb(0.7, 3, :initial_element, 1.0, :filter, make_one_zero(0.25, 0.25))) test_gen_equal(make_filtered_comb(0.7, 3, :initial_contents, [1.0, 0.0, 0.0], :filter, make_one_zero(0.5, 0.5)), make_filtered_comb(0.7, 3, :initial_contents, [1.0, 0.0, 0.0], :filter, make_one_zero(0.5, 0.5)), make_filtered_comb(0.7, 3, :initial_contents, [1.0, 1.0, 1.0], :filter, make_one_zero(0.5, 0.5))) del = make_filtered_comb(0.0, 5, :max_size, 8, :filter, make_one_zero(0.5, 0.5)) filtered_comb(del, 1.0) 4.times do filtered_comb(del, 0.0) end v0 = make_vct!(5) do filtered_comb(del, 0.0, 0.4) end snd_test_neq(v0, vct(0.6, 0.4, 0, 0, 0), "zfiltered_comb") filtered_comb(del, 1.0) filtered_comb(del, 0.0, 0.4) snd_test_neq(mus_describe(del), "filtered-comb scaler: 0.000, line[5,8, linear]: [0 0 1 0 0], filter: [one-zero a0: 0.500, a1: 0.500, x1: 0.000]", "describe zfiltered_comb") del.feedback = 1.0 snd_test_neq(del.feedback, 1.0, "filtered_echo feedback set") # gen = make_notch(0.4, 3) gen1 = make_notch(0.4, 3) print_and_check(gen, "notch", "notch scaler: 0.400, line[3, step]: [0 0 0]") v0 = make_vct!(10) do notch(gen, 1.0) end v1 = Vct.new(10) do |x| notch?(gen1) ? notch(gen1, 1.0) : -1.0 end unless vequal(v0, v1) snd_display("map notch: %s %s?", v0, v1) end unless notch?(gen) snd_display("%s not notch?", gen) end if gen.length != 3 snd_display("notch length: %s?", gen.length) end if gen.order != 3 snd_display("notch order: %s?", gen.order) end if fneq(gen.feedforward, 0.4) snd_display("notch feedforward: %s?", gen.feedforward) end if fneq(v0[1], 0.4) or fneq(v0[4], 1.4) or fneq(v0[8], 1.4) snd_display("notch output: %s?", v0) end d1 = make_notch(0.7, 3) d2 = make_notch(0.7, 3) d3 = make_notch(0.7, 4) notch(d1, 1.0) notch(d2, 1.0) notch(d3, 1.0) test_gen_equal(d1, d2, d3) test_gen_equal(make_notch(0.7, 3, :initial_element, 1.0), make_notch(0.7, 3, :initial_element, 1.0), make_notch(0.7, 3, :initial_element, 0.5)) test_gen_equal(make_notch(0.7, 3, :initial_element, 1.0), make_notch(0.7, 3, :initial_element, 1.0), make_notch(0.5, 3, :initial_element, 1.0)) test_gen_equal(make_notch(0.7, 3, :initial_contents, [1.0, 0.0, 0.0]), make_notch(0.7, 3, :initial_contents, [1.0, 0.0, 0.0]), make_notch(0.7, 3, :initial_contents, [1.0, 1.0, 1.0])) # make sure all-pass is the same as comb/notch given the appropriate # feedback/forward settings [[make_comb(0.5, 5), vct(0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.5)], [make_all_pass(0.5, 0.0, 5), vct(0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.5)], [make_notch(0.5, 5), vct(0.5, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0)], [make_all_pass(0.0, 0.5, 5), vct(0.5, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0)]].each do |gen, v1| v0 = Vct.new(11) do |i| gen.run(i.zero? ? 1.0 : 0.0) end snd_test_neq(v0, v1, "0 %s (0.5, 0.0, 5)", gen.name) end # make sure all-pass is the same as zcomb/znotch given the # appropriate feedback/forward and "pm" settings [[make_comb(0.5, 5, :max_size, 20), vct(0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.5)], [make_all_pass(0.5, 0.0, 5, :max_size, 20), vct(0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.5)], [make_notch(0.5, 5, :max_size, 20), vct(0.5, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0)], [make_all_pass(0.0, 0.5, 5, :max_size, 20), vct(0.5, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0)]].each do |gen, v1| v0 = Vct.new(11) do |i| gen.run(i.zero? ? 1.0 : 0.0) end snd_test_neq(v0, v1, "1 %s (0.5, 0.0, 5)", gen.name) end # now actually use the size difference [[make_comb(0.5, 5, :max_size, 20), vct(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.8, 0.4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.16, 0.36, 0.2, 0.04, 0.0, 0.0, 0.0)], [make_all_pass(0.5, 0.0, 5, :max_size, 20), vct(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.8, 0.4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.16, 0.36, 0.2, 0.04, 0.0, 0.0, 0.0)], [make_notch(0.5, 5, :max_size, 20), vct(0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.8, 0.4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)], [make_all_pass(0.0, 0.5, 5, :max_size, 20), vct(0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.8, 0.4, 0.0, 0.0, 0.0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)]].each do |gen, v1| angle = -0.2 v0 = Vct.new(20) do |i| gen.run((i.zero? ? 1.0 : 0.0), angle += 0.2) end snd_test_neq(v0, v1, "2 %s (0.5, 0.0, 5)", gen.name) end [[make_comb(0.5, 5, :max_size, 20), vct(0.0, 0.0, 0.0, 0.0, 0.8, 0.0, 0.0, 0.16, 0.16, 0.0, 0.08, 0.064, 0.016, 0.035, 0.013, 0.018, 0.007, 0.007, 0.003, 0.002)], [make_all_pass(0.5, 0.0, 5, :max_size, 20), vct(0.0, 0.0, 0.0, 0.0, 0.8, 0.0, 0.0, 0.16, 0.16, 0.0, 0.08, 0.064, 0.016, 0.035, 0.013, 0.018, 0.007, 0.007, 0.003, 0.002)], [make_notch(0.5, 5, :max_size, 20), vct(0.5, 0.0, 0.0, 0.0, 0.8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)], [make_all_pass(0.0, 0.5, 5, :max_size, 20), vct(0.5, 0.0, 0.0, 0.0, 0.8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)]].each do |gen, v1| angle = 0.2 v0 = Vct.new(20) do |i| gen.run((i.zero? ? 1.0 : 0.0), angle -= 0.2) end snd_test_neq(v0, v1, "3 %s (0.5, 0.0, 5)", gen.name) end [[make_comb(0.5, 5, :max_size, 20), vct(0.0, 0.0, 0.0, 0.0, 0.0, 0.95, 0.06, 0.0, 0.0, 0.0, 0.428, 0.079, 0.004, 0.0, 0.0, 0.182, 0.067, 0.008, 0.0, 0.0)], [make_all_pass(0.5, 0.0, 5, :max_size, 20), vct(0.0, 0.0, 0.0, 0.0, 0.0, 0.95, 0.06, 0.0, 0.0, 0.0, 0.428, 0.079, 0.004, 0.0, 0.0, 0.182, 0.067, 0.008, 0.0, 0.0)], [make_notch(0.5, 5, :max_size, 20), vct(0.5, 0.0, 0.0, 0.0, 0.0, 0.95, 0.06, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)], [make_all_pass(0.0, 0.5, 5, :max_size, 20), vct(0.5, 0, 0, 0, 0, 0.95, 0.06, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)]].each do |gen, v1| angle = -0.01 v0 = Vct.new(20) do |i| gen.run((i.zero? ? 1.0 : 0.0), angle += 0.01) end snd_test_neq(v0, v1, "4 %s (0.5, 0.0, 5)", gen.name) end # now run off either end of the delay line "by accident" [[make_comb(0.5, 5, :max_size, 10), vct(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 1.0, 0.25, 0.125, 0.094, 0.062, 0.055, 0.047, 0.039, 0.031, 0.029)], [make_all_pass(0.5, 0.0, 5, :max_size, 10), vct(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 1.0, 0.25, 0.125, 0.094, 0.062, 0.055, 0.047, 0.039, 0.031, 0.029)], [make_notch(0.5, 5, :max_size, 10), vct(0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)], [make_all_pass(0.0, 0.5, 5, :max_size, 10), vct(0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 1.0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)]].each do |gen, v1| angle = -0.5 v0 = Vct.new(20) do |i| gen.run((i.zero? ? 1.0 : 0.0), angle += 0.5) end snd_test_neq(v0, v1, "5 %s (0.5, 0.0, 5)", gen.name) end [[make_comb(0.5, 5, :max_size, 10), vct(0.0, 0.0, 0.0, 0.5, 0.0, 0.125, 0.0, 0.031, 0.016, 0.004, 1.0, 0.0, 0.25, 0.031, 0.0, 0.012, 0.002, 0.250, 0.125, 0.008)], [make_all_pass(0.5, 0.0, 5, :max_size, 10), vct(0.0, 0.0, 0.0, 0.5, 0.0, 0.125, 0.0, 0.031, 0.016, 0.004, 1.0, 0.0, 0.25, 0.031, 0.0, 0.012, 0.002, 0.250, 0.125, 0.008)], [make_notch(0.5, 5, :max_size, 10), vct(0.5, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)], [make_all_pass(0.0, 0.5, 5, :max_size, 10), vct(0.5, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)]].each do |gen, v1| angle = 0.5 v0 = Vct.new(20) do |i| gen.run((i.zero? ? 1.0 : 0.0), angle -= 0.5) end snd_test_neq(v0, v1, "6 %s (0.0, 0.5, 5)", gen.name) end # gen = make_filtered_comb(0.5, 5, :filter, make_one_zero(0.5, 0.5)) v0 = Vct.new(21) do |i| filtered_comb(gen, i.zero? ? 1.0 : 0.0) end v1 = vct(0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0.25, 0.25, 0, 0, 0, 0.062, 0.125, 0.062, 0, 0, 0.016) snd_test_neq(v0, v1, "0 filtered_comb (0.5, 5)") # gen = make_filtered_comb(0.5, 5, :filter, make_one_zero(0.25, 0.75)) v0 = Vct.new(21) do |i| filtered_comb(gen, i.zero? ? 1.0 : 0.0) end v1 = vct(0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0.125, 0.375, 0, 0, 0, 0.016, 0.094, 0.141, 0, 0, 0.002) snd_test_neq(v0, v1, "1 filtered_comb (0.5, 5)") # gen = make_filtered_comb(0.5, 5, :max_size, 20, :filter, make_one_zero(0.5, 0.5)) angle = -0.2 v0 = Vct.new(20) do |i| filtered_comb(gen, i.zero? ? 1.0 : 0.0, angle += 0.2) end v1 = vct(0, 0, 0, 0, 0, 0, 0.8, 0.4, 0, 0, 0, 0, 0, 0.08, 0.22, 0.3, 0.140, 0.04, 0, 0) snd_test_neq(v0, v1, "2 filtered_comb (0.5, 5)") # gen = make_filtered_comb(0.5, 5, :max_size, 20, :filter, make_one_zero(0.5, 0.5)) angle = 0.2 v0 = Vct.new(20) do |i| filtered_comb(gen, i.zero? ? 1.0 : 0.0, angle -= 0.2) end v1 = vct(0, 0, 0, 0, 0.8, 0, 0, 0.08, 0.2, 0.04, 0.02, 0.068, 0.042, 0.019, 0.026, 0.015, 0.011, 0.009, 0.006, 0.004) snd_test_neq(v0, v1, "3 filtered_comb (0.5, 5)") # gen = make_filtered_comb(0.5, 5, :max_size, 20, :filter, make_one_zero(0.5, 0.5)) angle = -0.01 v0 = Vct.new(20) do |i| filtered_comb(gen, i.zero? ? 1.0 : 0.0, angle += 0.01) end v1 = vct(0, 0, 0, 0, 0, 0.95, 0.06, 0, 0, 0, 0.214, 0.251, 0.043, 0.002, 0, 0.045, 0.106, 0.081, 0.023, 0.003) snd_test_neq(v0, v1, "4 filtered_comb (0.5, 5)") end def test_08_03 gen = make_one_pole(0.4, 0.7) gen1 = make_one_pole(0.4, 0.7) print_and_check(gen, "one-pole", "one-pole a0: 0.400, b1: 0.700, y1: 0.000") v0 = make_vct!(10) do one_pole(gen, 1.0) end v1 = Vct.new(10) do |x| one_pole?(gen1) ? one_pole(gen1, 1.0) : -1.0 end unless vequal(v0, v1) snd_display("map one_pole: %s %s?", v0, v1) end unless one_pole?(gen) snd_display("%s not one_pole?", gen) end if gen.order != 1 snd_display("one_pole order: %s?", gen.order) end if fneq(gen.a0, 0.4) snd_display("one_pole a0: %s?", gen.a0) end if fneq(gen.b1, 0.7) snd_display("one_pole b1: %s?", gen.b1) end if fneq(v0[1], 0.12) or fneq(v0[4], 0.275) or fneq(v0[8], 0.245) snd_display("one_pole output: %s?", v0) end if fneq(gen.ycoeff(1), 0.7) snd_display("1p ycoeff 1 0.7: %s?", gen) end gen.ycoeff = 1, 0.1 if fneq(gen.ycoeff(1), 0.1) snd_display("1p set_ycoeff 1 0.1: %s?", gen) end if fneq(gen.xcoeff(0), 0.4) snd_display("1p xcoeff 0 0.4: %s?", gen) end gen.xcoeff = 0, 0.3 if fneq(gen.xcoeff(0), 0.3) snd_display("1p set_xcoeff 0 0.3: %s?", gen) end # gen = make_one_zero(0.4, 0.7) gen1 = make_one_zero(0.4, 0.7) print_and_check(gen, "one-zero", "one-zero a0: 0.400, a1: 0.700, x1: 0.000") v0 = make_vct!(10) do one_zero(gen, 1.0) end v1 = Vct.new(10) do |x| one_zero?(gen1) ? one_zero(gen1, 1.0) : -1.0 end unless vequal(v0, v1) snd_display("map one_zero: %s %s?", v0, v1) end unless one_zero?(gen) snd_display("%s not one_zero?", gen) end if gen.order != 1 snd_display("one_zero order: %s?", gen.order) end if fneq(gen.a0, 0.4) snd_display("one_zero a0: %s?", gen.a0) end if fneq(gen.a1, 0.7) snd_display("one_zero a1: %s?", gen.a1) end if fneq(v0[1], 1.1) snd_display("one_zero output: %s?", v0) end if fneq(gen.xcoeff(0), 0.4) snd_display("1z xcoeff 0 0.4: %s?", gen) end gen.xcoeff = 0, 0.1 if fneq(gen.xcoeff(0), 0.1) snd_display("1z set_xcoeff 0 0.1: %s?", gen) end # gen = make_two_zero(0.4, 0.7, 0.3) gen1 = make_two_zero(0.4, 0.7, 0.3) print_and_check(gen, "two-zero", "two-zero a0: 0.400, a1: 0.700, a2: 0.300, x1: 0.000, x2: 0.000") v0 = make_vct!(10) do two_zero(gen, 1.0) end v1 = Vct.new(10) do |x| two_zero?(gen1) ? two_zero(gen1, 1.0) : -1.0 end unless vequal(v0, v1) snd_display("map two_zero: %s %s?", v0, v1) end unless two_zero?(gen) snd_display("%s not two_zero?", gen) end if gen.order != 2 snd_display("two_zero order: %s?", gen.order) end if fneq(gen.a0, 0.4) snd_display("two_zero a0: %s?", gen.a0) end if fneq(gen.a1, 0.7) snd_display("two_zero a1: %s?", gen.a1) end if fneq(gen.a2, 0.3) snd_display("two_zero a2: %s?", gen.a2) end if fneq(v0[1], 1.1) or fneq(v0[8], 1.4) snd_display("two_zero output: %s?", v0) end if fneq(gen.xcoeff(0), 0.4) snd_display("2z xcoeff 0 0.4: %s?", gen) end gen.xcoeff = 0, 0.1 if fneq(gen.xcoeff(0), 0.1) snd_display("2z set_xcoeff 0 0.1: %s?", gen) end gen.xcoeff = 0, 1.0 r = gen.scaler gen.frequency = 500.0 if fneq(gen.frequency, 500.0) snd_display("set_mus_frequency two_zero: %s?", gen.frequency) end if fneq(gen.scaler, r) snd_display("set_mus_frequency two_zero hit r: %s?", gen.scaler) end gen.scaler = 0.99 if fneq(gen.scaler, 0.99) snd_display("set_mus_scaler two_zero: %s?", gen.scaler) end if fneq(gen.frequency, 500.0) snd_display("set_mus_scaler hit freq two_zero: %s?", gen.frequency) end g3 = make_two_zero(:radius, 0.99, :frequency, 500.0) if fneq(gen.a0, g3.a0) or fneq(gen.a1, g3.a1) or fneq(gen.a2, g3.a2) snd_display("two_zero setters: %s %s", gen, g3) end gen = make_two_zero(0.4, 0.7, 0.3) if fneq(val = gen.call(1.0, 0.0), 0.4) snd_display("2zero->0.4: %s?", val) end if fneq(val = gen.call(0.5, 0.0), 0.9) snd_display("2zero->0.9: %s?", val) end if fneq(val = gen.call(1.0, 0.0), 1.05) snd_display("2zero->1.05: %s?", val) end # gen = make_two_pole(0.4, 0.7, 0.3) gen1 = make_two_pole(0.4, 0.7, 0.3) print_and_check(gen, "two-pole", "two-pole a0: 0.400, b1: 0.700, b2: 0.300, y1: 0.000, y2: 0.000") v0 = make_vct!(10) do two_pole(gen, 1.0) end v1 = Vct.new(10) do |x| two_pole?(gen1) ? two_pole(gen1, 1.0) : -1.0 end unless vequal(v0, v1) snd_display("map two_pole: %s %s?", v0, v1) end unless two_pole?(gen) snd_display("%s not two_pole?", gen) end if gen.order != 2 snd_display("two_pole order: %s?", gen.order) end if fneq(gen.a0, 0.4) snd_display("two_pole a0: %s?", gen.a0) end if fneq(gen.b1, 0.7) snd_display("two_pole b1: %s?", gen.b1) end if fneq(gen.b2, 0.3) snd_display("two_pole b2: %s?", gen.b2) end if fneq(v0[1], 0.12) or fneq(v0[8], 0.201) snd_display("two_pole output: %s?", v0) end if fneq(gen.ycoeff(1), 0.7) snd_display("2p ycoeff 1 0.7: %s?", gen) end gen.ycoeff = 1, 0.1 if fneq(gen.ycoeff(1), 0.1) snd_display("2p set_ycoeff 1 0.1: %s?", gen) end if fneq(gen.xcoeff(0), 0.4) snd_display("2p xcoeff 0 0.4: %s?", gen) end gen.xcoeff = 0, 0.3 if fneq(gen.xcoeff(0), 0.3) snd_display("2p set_xcoeff 0 0.3: %s?", gen) end gen.xcoeff = 0, 1.0 r = gen.scaler gen.frequency = 500.0 if fneq(gen.frequency, 500.0) snd_display("set_mus_frequency two_pole: %s?", gen.frequency) end if fneq(gen.scaler, r) snd_display("set_mus_frequency two_pole hit r: %s?", gen.scaler) end gen.scaler = 0.99 if fneq(gen.scaler, 0.99) snd_display("set_mus_scaler two_pole: %s?", gen.scaler) end if fneq(gen.frequency, 500.0) snd_display("set_mus_scaler hit freq two_pole: %s?", gen.frequency) end g3 = make_two_pole(:radius, 0.99, :frequency, 500.0) if fneq(gen.a0, g3.a0) or fneq(gen.a1, g3.a1) or fneq(gen.a2, g3.a2) snd_display("two_pole setters: %s %s", gen, g3) end gen = make_two_pole(0.4, 0.7, 0.3) if fneq(val = gen.call(1.0, 0.0), 0.4) snd_display("a0->out 2pole: %s?", val) end if fneq(val = gen.call(0.5, 0.0), -0.08) snd_display("a0->out 2pole (-0.08): %s?", val) end if fneq(val = gen.call(1.0, 0.0), 0.336) snd_display("a0->out 2pole (0.336): %s?", val) end # gen = make_oscil(440.0) gen1 = make_oscil(440.0) gen2 = make_oscil(440.0) print_and_check(gen, "oscil", "oscil freq: 440.000Hz, phase: 0.000") v0 = make_vct!(10) do oscil(gen, 0.0) end v1 = make_vct!(10) do mus_apply(gen1, 0.0, 0.0) end v2 = Vct.new(10) do |x| oscil?(gen2) ? oscil(gen2, 0.0) : -1.0 end unless vequal(v0, v2) snd_display("map oscil: %s %s?", v0, v2) end unless oscil?(gen) snd_display("%s not oscil?", gen) end if fneq(gen.phase, 1.253787) snd_display("oscil phase: %s?", gen.phase) end if fneq(gen.frequency, 440.0) snd_display("oscil frequency: %s?", gen.frequency) end if fneq(gen.length, 1) snd_display("oscil cosines: %s?", gen.length) end if fneq(v0[1], 0.125) or fneq(v0[8], 0.843) snd_display("oscil output: %s?", v0) end gen.phase = 0.0 if fneq(gen.phase, 0.0) snd_display("oscil set_phase: %s?", gen.phase) end gen.frequency = 100.0 if fneq(gen.frequency, 100.0) snd_display("oscil set_frequency: %s?", gen.frequency) end # v0.each_with_index do |val, i| if fneq(val, v1[i]) snd_display("mus_apply oscil at %s: %s %s?", i, val, v1[i]) end end if fneq(mus_apply, 0.0) snd_display("mus_apply: %s?", mus_apply) end gen1 = make_oscil(100.0) gen2 = make_oscil(-100.0) mx = 0.0 100.times do mx = [mx, (gen1.run + gen2.run).abs].max end if fneq(mx, 0.0) snd_display("1 oscil +-: %s?", mx) end gen1 = make_oscil(100.0, PI * 0.5) gen2 = make_oscil(-100.0, PI * 0.5) mx = 0.0 100.times do mx = [mx, (gen1.run - gen2.run).abs].max end if fneq(mx, 0.0) snd_display("2 oscil +-: %s?", mx) end fm_test(make_oscil) fm_test(make_square_wave) fm_test(make_triangle_wave) fm_test(make_ncos) fm_test(make_nsin) fm_test(make_sawtooth_wave) fm_test(make_rand) fm_test(make_rand_interp) fm_test(make_pulse_train) # gen = make_oscil(440.0) gen1 = make_oscil(440.0) 10.times do if fneq(oval = oscil(gen, 0.1), mval = mus_run(gen1, 0.1)) snd_display("mus_run %s but oscil %s?", oval, mval) end end gen = make_oscil(440.0) gen1 = make_oscil(440.0) gen2 = make_oscil(440.0) gen3 = make_oscil(440.0) fm_index = hz2radians(440.0) v0 = make_vct(10) v1 = make_vct(10) 10.times do |i| v0[i] = oscil(gen, fm_index * oscil(gen1, 0.0)) v1[i] = mus_apply(gen2, fm_index * mus_apply(gen3, 0.0, 0.0), 0.0) end if fneq(v0[1], 0.125) or fneq(v0[6], 0.83) or fneq(v0[8], 0.987) snd_display("oscil fm output: %s?", v0) end v0.each_with_index do |val, i| if fneq(val, v1[i]) snd_display("mus_apply fm oscil at %s: %s %s?", i, val, v1[i]) end end test_gen_equal(make_oscil(440.0), make_oscil(440.0), make_oscil(100.0)) test_gen_equal(make_oscil(440.0), make_oscil(440.0), make_oscil(440.0, 1.0)) gen = make_oscil(440.0) gen1 = make_oscil(440.0) pm_index = 2.0 v0 = make_vct!(10) do gen.call(0.0, pm_index * gen1.call(0.0, 0.0)) end if fneq(v0[1], 0.367) or fneq(v0[6], 0.854) or fneq(v0[8], 0.437) snd_display("oscil pm output: %s?", v0) end gen = make_oscil(440.0) 1100.times do |i| if fneq(val1 = sin(gen.phase), val2 = gen.call(0.0, 0.0)) snd_display("oscil (sin): %s: %s %s?", i, val1, val2) end end gen = make_oscil(440.0, :initial_phase, PI * 0.5) a = 0.0 900.times do |i| if fneq(val1 = cos(a), val2 = gen.call(0.0, 0.0)) snd_display("oscil (cos): %s: %s %s?", i, val1, val2) end a = a + (2 * PI * 440) / 22050 end gen = make_oscil(0.0) gen1 = make_oscil(40.0) a = 0.0 1100.times do |i| if fneq(val1 = sin(sin(a)), val2 = oscil(gen, 0.0, oscil(gen1, 0.0))) snd_display("oscil pm: %s: %s %s?", i, val1, val2) end a = a + (2 * PI * 40) / 22050 end gen = make_oscil(0.0) gen1 = make_oscil(40.0) a = 0.0 a1 = 0.0 1100.times do |i| fm = sin(a) if fneq(val1 = sin(a1), val2 = oscil(gen, oscil(gen1, 0.0))) snd_display("oscil fm: %s: %s %s?", i, val1, val2) end a = a + (2 * PI * 40) / 22050 a1 += fm end # if (res = Snd.catch do mus_location(make_oscil) end).first != :mus_error snd_display("mus_location bad gen: %s", res.inspect) end if (res = Snd.catch do set_mus_location(make_oscil, 0) end).first != :mus_error snd_display("set_mus_location bad gen: %s", res.inspect) end if (res = Snd.catch do set_mus_scaler(make_oscil, 0) end).first != :mus_error snd_display("set_mus_scaler bad gen: %s", res.inspect) end if (res = Snd.catch do mus_frequency(make_one_pole) end).first != :mus_error snd_display("mus_frequency bad gen: %s", res.inspect) end if (res = Snd.catch do set_mus_frequency(make_one_pole, 0) end).first != :mus_error snd_display("set_mus_frequency bad gen: %s", res.inspect) end if (res = Snd.catch do make_delay(1024 * 1024 * 40) end).first != :out_of_range snd_display("make_delay huge line 1: %s", res.inspect) end if (res = Snd.catch do make_delay(32, :max_size, 1024 * 1024 * 40) end).first != :out_of_range snd_display("make_delay huge line 2: %s", res.inspect) end end def test_08_04 gen = make_asymmetric_fm(440.0) gen1 = make_asymmetric_fm(440.0) print_and_check(gen, "asymmetric-fm", "asymmetric-fm freq: 440.000Hz, phase: 0.000, ratio: 1.000, r: 1.000") v0 = make_vct!(10) do asymmetric_fm(gen, 0.0) end v1 = Vct.new(10) do |x| asymmetric_fm?(gen1) ? asymmetric_fm(gen1, 0.0) : -1.0 end unless vequal(v0, v1) snd_display("map asymmetric_fm: %s %s?", v0, v1) end unless asymmetric_fm?(gen) snd_display("%s not asymmetric_fm?", gen) end if fneq(gen.phase, 1.253787) snd_display("asymmetric_fm phase: %s?", gen.phase) end gen.phase = 1.0 if fneq(gen.phase, 1.0) snd_display("asymmetric_fm set_phase: %s?", gen.phase) end if fneq(gen.frequency, 440.0) snd_display("asymmetric_fm frequency: %s?", gen.frequency) end gen.frequency = 100.0 if fneq(gen.frequency, 100.0) snd_display("asymmetric_fm set_frequency: %s?", gen.frequency) end if fneq(v0[2], 0.969) or fneq(v0[8], 0.538) snd_display("asymmetric_fm output: %s?", v0) end if fneq(gen.scaler, 1.0) snd_display("asymmetric_fm set_scaler: %s?", gen.scaler) end gen.scaler = 0.5 if fneq(gen.scaler, 0.5) snd_display("asymmetric_fm set_scaler: %s?", gen.scaler) end if fneq(gen.offset, 1.0) snd_display("asymmetric_fm offset: %s?", gen.offset) end test_gen_equal(make_asymmetric_fm(440), make_asymmetric_fm(440), make_asymmetric_fm(100)) test_gen_equal(make_asymmetric_fm(440), make_asymmetric_fm(440), make_asymmetric_fm(440, 1)) test_gen_equal(make_asymmetric_fm(440), make_asymmetric_fm(440), make_asymmetric_fm(440, 0.0, 3)) gen1 = make_asymmetric_fm(1000, 0, 1, 0.1) gen2 = make_oscil(1000, :initial_phase, HALF_PI) 100.times do |i| ss = asymmetric_fm(gen1, 0.0, 0.0) os = oscil(gen2, 0.0) if fneq(ss, os) snd_display("asymmetric_fm 1: %s: os: %s ss: %s?", i, os, ss) break end end gen3 = make_asymmetric_fm(1000, 0, 1.0, 0.2) gen4 = make_oscil(1000, :initial_phase, HALF_PI) gen5 = make_oscil(200) fm1 = hz2radians(0.2 * 1000) vct0 = make_vct(2048) vct1 = make_vct!(2048) do |i| vct0[i] = asymmetric_fm(gen3, 1.0, 0.0) oscil(gen4, fm1 * oscil(gen5)) end spectr1 = snd_spectrum(vct0, Rectangular_window, 2048, true) spectr2 = snd_spectrum(vct1, Rectangular_window, 2048, true) (1...512).each do |i| if fneq_err(spectr1[i], spectr2[i], 0.02) snd_display("asymmetric_fm 2: %s: %s %s?", i, spectr1[i], spectr2[i]) break end end gen = make_asymmetric_fm(40.0, 0.0, 1.0, 0.1) gen1 = make_asyfm(:frequency, 40.0, :ratio, 0.1, :index, 2.0) a = 0.0 1100.times do |i| val1 = asymmetric_fm(gen, 2.0) val3 = asyfm_J(gen1, 0.0) r = 1.0 ratio = 0.1 index = 2.0 cr = 0.5 * (r - (1.0 / r)) sr = 0.5 * (r + (1.0 / r)) th = a mth = ratio * th val2 = exp(index * cr * (1.0 + cos(mth))) * cos(th + (index * sr * sin(mth))) if fneq(val1, val2) or fneq(val1, val3) snd_display("asyfm by hand: %s: 1 %s 2 %s 3 %s?", i, val1, val2, val3) end a = a + ((TWO_PI * 40.0) / mus_srate()) end gen3 = make_asymmetric_fm(1000, 0, 2.0, 0.1) gen4 = make_asymmetric_fm(1000, 0, 0.5, 0.1) vct0 = make_vct(2048) vct1 = make_vct!(2048) do |i| vct0[i] = asymmetric_fm(gen3, 2.0, 0.0) asymmetric_fm(gen4, 2.0, 0.0) end spectr1 = snd_spectrum(vct0, Rectangular_window, 2048, true) spectr2 = snd_spectrum(vct1, Rectangular_window, 2048, true) s1_loc = 0 s2_loc = 0 (1...256).each do |i| if (1.0 - spectr1[i]).abs < 0.01 s1_loc = i end if (1.0 - spectr2[i]).abs < 0.01 s2_loc = i end end if s2_loc > s1_loc snd_display("asymmetric_fm peaks: %s %s?", s1_loc, s2_loc) end center = ((22050 / 2048.0) * 0.5 * (s1_loc + s2_loc)).round if (1000 - center).abs > 60 snd_display("asymmetric_fm center: %s?", center) end gen3.scaler = 0.5 2048.times do |i| vct0[i] = asymmetric_fm(gen3, 2.0, 0.0) end spectr1 = snd_spectrum(vct0, Rectangular_window, 2048, true) (1...256).each do |i| s1_loc = i if (1.0 - spectr1[i]).abs < 0.01 end if s2_loc != s1_loc snd_display("asymmetric_fm set r peaks: %s %s?", s1_loc, s2_loc) end 2048.times do |i| vct0[i] = asymmetric_fm(gen3, 2.0, 0.0) end snd_spectrum(vct0, Rectangular_window, 2048, true, 0.0, true) (1...256).each do |i| if (1.0 - spectr1[i]).abs < 0.01 s1_loc = i end end if s2_loc != s1_loc snd_display("asymmetric_fm set r in place peaks: %s %s?", s1_loc, s2_loc) end # gen = make_asyfm(:frequency, 2000, :ratio, 0.1) asyfm_I(gen, 0.0) end class F_filter def initialize(coeffs) @coeffs = coeffs @xs = Vct.new(coeffs.length) end def f_filter(x) xlen = @xs.length @xs.move!(xlen - 1, xlen - 2, true) @xs.first = x dot_product(@coeffs, @xs, xlen) end end def make_f_filter(coeffs) F_filter.new(coeffs) end def f_filter(flt, x) flt.f_filter(x) end def test_08_05 gen = make_fir_filter(3, vct(0.5, 0.25, 0.125)) gen1 = make_fir_filter(3, vct(0.5, 0.25, 0.125)) print_and_check(gen, "fir-filter", "fir-filter order: 3, xs: [0.5 0.25 0.125]") v0 = make_vct!(10) do |i| fir_filter(gen, i.zero? ? 1.0 : 0.0) end v1 = make_vct(10) inp = -1 v1.map! do |x| inp += 1 fir_filter?(gen1) ? fir_filter(gen1, inp.zero? ? 1.0 : 0.0) : -1.0 end unless vequal(v0, v1) snd_display("map fir_filter: %s %s?", v0, v1) end unless fir_filter?(gen) snd_display("%s not fir_filter?", gen) end if gen.length != 3 snd_display("fir_filter length: %s?", gen.length) end if fneq(v0[1], 0.25) or fneq(v0[2], 0.125) snd_display("fir_filter output: %s?", v0) end data = gen.xcoeffs if fneq(data[1], 0.25) snd_display("fir_filter xcoeffs: %s?", data) end if (res = Snd.catch do mus_xcoeff(gen, 123) end).first != :mus_error snd_display("xcoeff 123: %s", res.inspect) end if (res = Snd.catch do mus_ycoeff(gen, 123) end).first != :mus_error snd_display("fir ycoeff 123: %s", res.inspect) end f1 = make_fir_filter(3, vct(0.5, 0.25, 0.125)) f2 = make_fir_filter(3, vct(0.5, 0.25, 0.125)) f3 = make_fir_filter(3, vct(0.75, 0.25, 0.125)) fir_filter(f1, 1.0) fir_filter(f2, 1.0) fir_filter(f3, 1.0) test_gen_equal(f1, f2, f3) f1 = make_fir_filter(3, vct(0.5, 0.25, 0.125)) f2 = make_fir_filter(3, vct(0.5, 0.25, 0.125)) f3 = make_fir_filter(2, vct(0.5, 0.25)) fir_filter(f1, 1.0) fir_filter(f2, 1.0) fir_filter(f3, 1.0) test_gen_equal(f1, f2, f3) coeffs = vct(0.1, 0.2, 0.3, 0.4, 0.4, 0.3, 0.2, 0.1) flt = make_fir_filter(8, coeffs) xcof = flt.xcoeffs es = make_array(8) do |i| make_env([0, coeffs[i], 1, 0], :length, 102) end es[5] = make_env([0, 0.4, 1, 1], :length, 102) data = make_vct!(100) do |i| val = fir_filter(flt, (i % 12).zero? ? 1.0 : 0.0) es.each_with_index do |en, j| xcof[j] = env(en) end val end if fneq(data[1], 0.2) or fneq(data[10], 0.0) or fneq(data[18], 0.166) or fneq(data[89], 0.923) snd_display("filter xcoeffs: %s?", data) end # fir1 = make_fir_filter(3, [1, 0.4, 0.1].to_vct) fir2 = make_f_filter([1, 0.4, 0.1].to_vct) 10.times do |i| val1 = fir_filter(fir1, i.zero? ? 1.0 : 0.0) val2 = f_filter(fir2, i.zero? ? 1.0 : 0.0) if fneq(val1, val2) snd_display("f_filter %s -> %s %s?", i, val1, val2) break end end # gen = make_iir_filter(3, vct(0.5, 0.25, 0.125)) gen1 = make_iir_filter(3, vct(0.5, 0.25, 0.125)) print_and_check(gen, "iir-filter", "iir-filter order: 3, ys: [0.5 0.25 0.125]") v0 = make_vct!(10) do |i| iir_filter(gen, i.zero? ? 1.0 : 0.0) end v1 = make_vct(10) inp = -1 v1.map! do |x| inp += 1 iir_filter?(gen1) ? iir_filter(gen1, inp.zero? ? 1.0 : 0.0) : -1.0 end unless vequal(v0, v1) snd_display("map iir_filter: %s %s?", v0, v1) end unless iir_filter?(gen) snd_display("%s not iir_filter?", gen) end if gen.length != 3 snd_display("iir_filter length: %s?", gen.length) end if fneq(v0[1], -0.25) or fneq(v0[2], -0.062) snd_display("iir_filter output: %s?", v0) end data = gen.ycoeffs if fneq(data[1], 0.25) snd_display("iir_filter ycoeffs: %s?", data) end if (res = Snd.catch do mus_ycoeff(gen, 123) end).first != :mus_error snd_display("ycoeff 123: %s", res.inspect) end if (res = Snd.catch do mus_xcoeff(gen, 123) end).first != :mus_error snd_display("iir xcoeff 123: %s", res.inspect) end f1 = make_iir_filter(3, vct(0.5, 0.25, 0.125)) f2 = make_iir_filter(3, vct(0.5, 0.25, 0.125)) f3 = make_iir_filter(3, vct(0.75, 0.25, 0.125)) iir_filter(f1, 1.0) iir_filter(f2, 1.0) iir_filter(f3, 1.0) test_gen_equal(f1, f2, f3) f1 = make_iir_filter(3, vct(0.5, 0.25, 0.125)) f2 = make_iir_filter(3, vct(0.5, 0.25, 0.125)) f3 = make_iir_filter(2, vct(0.5, 0.25)) iir_filter(f1, 1.0) iir_filter(f2, 1.0) iir_filter(f3, 1.0) test_gen_equal(f1, f2, f3) # gen = make_filter(3, vct(0.5, 0.25, 0.125), vct(0.5, 0.25, 0.125)) gen1 = make_filter(3, vct(0.5, 0.25, 0.125), vct(0.5, 0.25, 0.125)) print_and_check(gen, "filter", "filter order: 3, xs: [0.5 0.25 0.125], ys: [0.5 0.25 0.125]") v0 = make_vct!(10) do |i| filter(gen, i.zero? ? 1.0 : 0.0) end v1 = make_vct(10) inp = -1 v1.map! do |x| inp += 1 filter?(gen1) ? filter(gen1, inp.zero? ? 1.0 : 0.0) : -1.0 end unless vequal(v0, v1) snd_display("map filter: %s %s?", v0, v1) end unless filter?(gen) snd_display("%s not filter?", gen) end if gen.length != 3 snd_display("filter length: %s?", gen.length) end if fneq(v0[1], 0.125) or fneq(v0[2], 0.031) snd_display("filter output: %s?", v0) end gen2 = make_biquad(0.1, 0.2, 0.3, 0.4, 0.5) unless filter?(gen2) snd_display("make_biquad: %s?", gen2) end xs = gen.xcoeffs ys = gen.ycoeffs if xs != vct(0.5, 0.25, 0.125) or xs != ys snd_display("mus_xcoeffs: %s %s?", xs, ys) end if (res = Snd.catch do make_filter(:order, 2, :xcoeffs, vct(1.0, 0.5), :ycoeffs, vct(2.0, 1.0, 0.5)) end).first != :mus_error snd_display("make_filter bad coeffs: %s", res.inspect) end if (res = Snd.catch do make_filter(:order, 0, :xcoeffs, vct(1.0, 0.5)) end).first != :out_of_range snd_display("make_filter bad order: %s", res.inspect) end if (res = Snd.catch do make_fir_filter(:order, 22, :xcoeffs, vct(1.0, 0.5)) end).first != :mus_error snd_display("make_fir_filter bad coeffs: %s", res.inspect) end if (res = Snd.catch do make_iir_filter(:order, 22, :ycoeffs, vct(1.0, 0.5)) end).first != :mus_error snd_display("make_iir_filter bad coeffs: %s", res.inspect) end if (res = Snd.catch do make_fir_filter(-1) end).first != :out_of_range snd_display("make_fir_filter bad order: %s", res.inspect) end unless iir_filter?(res = make_filter(:order, 2, :ycoeffs, vct(1.0, 0.5))) snd_display("make_filter with only y: %s", res) end f1 = make_filter(3, vct(0.5, 0.25, 0.125), vct(0.5, 0.25, 0.125)) f2 = make_filter(3, vct(0.5, 0.25, 0.125), vct(0.5, 0.25, 0.125)) f3 = make_filter(3, vct(0.5, 0.25, 0.125), vct(0.5, 0.5, 0.5)) filter(f1, 1.0) filter(f2, 1.0) filter(f3, 1.0) test_gen_equal(f1, f2, f3) f1 = make_filter(3, vct(0.5, 0.25, 0.125), vct(0.5, 0.25, 0.125)) f2 = make_filter(3, vct(0.5, 0.25, 0.125), vct(0.5, 0.25, 0.125)) f3 = make_filter(3, vct(0.5, 0.5, 0.125), vct(0.5, 0.25, 0.0625)) filter(f1, 1.0) filter(f2, 1.0) filter(f3, 1.0) test_gen_equal(f1, f2, f3) fr = make_fir_filter(6, vct(0, 1, 2, 3, 4, 5)) if fr.length != 6 snd_display("filter_length: %s?", fr.length) end # unless vequal(res = cascade2canonical([vct(1, 0, 0), vct(1, 0.5, 0.25)]), vct(1.000, 0.500, 0.250, 0.000, 0.000)) snd_display("cascade2canonical 0: %s?", res) end unless vequal(res = cascade2canonical([vct(1, 1, 0), vct(1, 0.5, 0.25)]), vct(1.000, 1.500, 0.750, 0.250, 0.000)) snd_display("cascade2canonical 1: %s?", res) end unless vequal(res = cascade2canonical([vct(1, 0.8, 0), vct(1, 1.4, 0.65), vct(1, 0, 0)]), vct(1.000, 2.200, 1.770, 0.520, 0.000, 0.000, 0.000)) snd_display("cascade2canonical 2: %s?", res) end unless vequal(res = cascade2canonical([vct(1, -0.9, 0), vct(1, 1, 0.74), vct(1, -1.6, 0.8)]), vct(1.000, -1.500, 0.480, -0.330, 0.938, -0.533, 0.000)) snd_display("cascade2canonical 3: %s?", res) end # ind = new_sound("test.snd", 1, 22050, Mus_bfloat, Mus_next) pad_channel(0, 10000) freq_sweep(0.45) sp = rough_spectrum(ind) if (not vequal(sp, vct(0.962, 0.998, 0.998, 0.998, 0.998, 0.999, 0.999, 0.998, 0.997, 1))) and (not vequal(sp, vct(0.963, 0.999, 0.999, 0.999, 0.999, 0.999, 1, 1, 0.998, 0.997))) snd_display("initial rough spectrum: %s?", sp) end b = make_butter_high_pass(440.0) v = make_vct!(10) do |i| butter(b, i.zero? ? 1.0 : 0.0) end unless vequal(v, vct(0.915, -0.162, -0.146, -0.131, -0.117, -0.103, -0.09, -0.078, -0.066, -0.056)) snd_display("butter high: %s?", v) end b = make_butter_high_pass(1000.0) map_channel(lambda do |y| butter(b, y) end) sp = rough_spectrum(ind) if (not vequal(sp, vct(0.150, 0.833, 0.980, 0.994, 0.997, 0.998, 0.999, 0.998, 0.997, 1))) and (not vequal(sp, vct(0.150, 0.833, 0.981, 0.995, 0.998, 0.999, 1, 1, 0.998, 0.997))) snd_display("hp rough spectrum: %s?", sp) end undo_edit # b = make_butter_low_pass(440.0) v.map_with_index! do |val, i| butter(b, i.zero? ? 1.0 : 0.0) end unless vequal(v, vct(0.004, 0.014, 0.026, 0.035, 0.043, 0.049, 0.053, 0.055, 0.057, 0.057)) snd_display("butter low: %s?", v) end b = make_butter_low_pass(1000.0) map_channel(lambda do |y| butter(b, y) end) sp = rough_spectrum(ind) unless vequal(sp, vct(1, 0.212, 0.024, 0.005, 0.001, 0.000, 0.000, 0.000, 0.000, 0.000)) snd_display("lp rough spectrum: %s?", sp) end undo_edit # b = make_butter_band_pass(440.0, 50.0) v.map_with_index! do |val, i| butter(b, i.zero? ? 1.0 : 0.0) end unless vequal(v, vct(0.007, 0.014, 0.013, 0.013, 0.012, 0.011, 0.009, 0.008, 0.007, 0.005)) snd_display("butter bandpass: %s?", v) end b = make_butter_band_pass(1000.0, 500.0) map_channel(lambda do |y| butter(b, y) end) sp = rough_spectrum(ind) unless vequal(sp, vct(0.888, 1, 0.144, 0.056, 0.027, 0.014, 0.008, 0.004, 0.002, 0)) snd_display("bp rough spectrum: %s?", sp) end undo_edit # b = make_butter_band_reject(440.0, 50.0) v.map_with_index! do |val, i| butter(b, i.zero? ? 1.0 : 0.0) end unless vequal(v, vct(0.993, -0.014, -0.013, -0.013, -0.012, -0.011, -0.009, -0.008, -0.007, -0.005)) snd_display("butter bandstop: %s?", v) end b = make_butter_band_reject(1000.0, 500.0) map_channel(lambda do |y| butter(b, y) end) sp = rough_spectrum(ind) if (not vequal(sp, vct(0.662, 0.687, 0.953, 0.980, 0.989, 0.994, 0.997, 0.997, 0.997, 1))) and (not vequal(sp, vct(0.664, 0.689, 0.955, 0.982, 0.992, 0.996, 0.999, 1, 0.999, 0.998))) snd_display("bs rough spectrum: %s?", sp) end undo_edit # analog_filter_tests # v = spectrum2coeffs(10, vct(0, 1.0, 0, 0, 0, 0, 0, 0, 1.0, 0)) v1 = make_fir_coeffs(10, vct(0, 1.0, 0, 0, 0, 0, 0, 0, 1.0, 0)) unless vequal(v, vct(-0.190, -0.118, 0.000, 0.118, 0.190, 0.190, 0.118, 0.000, -0.118, -0.190)) snd_display("spectrum2coeffs: %s?", v) end unless vequal(v, v1) snd_display("spectrum2coeffs v make_fir_coeffs: %s %s?", v, v1) end notched_spectr = make_vct(20) notched_spectr[2] = 1.0 v = spectrum2coeffs(20, notched_spectr) v1 = make_fir_coeffs(20, notched_spectr) unless vequal(v, vct(0.095, 0.059, 0.000, -0.059, -0.095, -0.095, -0.059, 0.000, 0.059, 0.095, 0.095, 0.059, 0.000, -0.059, -0.095, -0.095, -0.059, 0.000, 0.059, 0.095)) snd_display("spectrum2coeffs (notch): %s?", v) end unless vequal(v, v1) snd_display("spectrum2coeffs v(2) make_fir_coeffs: %s %s?", v, v1) end flt = make_fir_filter(20, v) map_channel(lambda do |y| fir_filter(flt, y) end) sp = rough_spectrum(ind) unless vequal(sp, vct(0.007, 0.493, 1.000, 0.068, 0.030, 0.019, 0.014, 0.011, 0.009, 0.009)) snd_display("sp->coeff rough spectrum: %s?", sp) end undo_edit # rspect = make_vct!(20) do random(1.0) end v = spectrum2coeffs(20, rspect) v1 = make_fir_coeffs(20, rspect) unless vequal(v, v1) snd_display("spectrum2coeffs v(3) make_fir_coeffs:\n# %s\n# %s", v, v1) end b = make_highpass(hz2radians(1000.0), 10) v = make_vct!(20) do |i| highpass(b, i.zero? ? 1.0 : 0.0) end unless vequal(v, vct(-0.001, -0.002, -0.005, -0.011, -0.021, -0.034, -0.049, -0.065, -0.078, -0.087, 0.909, -0.087, -0.078, -0.065, -0.049, -0.034, -0.021, -0.011, -0.005, -0.002)) snd_display("dsp.rb high: %p?", v) end b = make_highpass(hz2radians(1000.0), 20) map_channel(lambda do |y| highpass(b, y) end) sp = rough_spectrum(ind) if (not vequal(sp, vct(0.053, 0.774, 0.998, 0.997, 0.997, 0.996, 0.996, 0.996, 0.997, 1))) and (not vequal(sp, vct(0.053, 0.776, 1.000, 0.998, 0.998, 0.998, 0.998, 0.998, 0.998, 1))) snd_display("dsp hp rough spectrum: %s?", sp) end undo_edit # b = make_lowpass(hz2radians(1000.0), 10) v = make_vct!(20) do |i| lowpass(b, i.zero? ? 1.0 : 0.0) end unless vequal(v, vct(0.001, 0.002, 0.005, 0.011, 0.021, 0.034, 0.049, 0.065, 0.078, 0.087, 0.091, 0.087, 0.078, 0.065, 0.049, 0.034, 0.021, 0.011, 0.005, 0.002)) snd_display("dsp.rb low: %s?", v) end b = make_lowpass(hz2radians(1000.0), 20) map_channel(lambda do |y| lowpass(b, y) end) sp = rough_spectrum(ind) unless vequal(sp, vct(1, 0.054, 0, 0, 0, 0, 0, 0, 0, 0)) snd_display("dsp lp rough spectrum: %s?", sp) end undo_edit # b = make_bandpass(hz2radians(1500.0), hz2radians(2000.0), 10) v = make_vct!(20) do |i| bandpass(b, i.zero? ? 1.0 : 0.0) end unless vequal(v, vct(0.001, -0.001, -0.005, -0.011, -0.017, -0.019, -0.013, 0.003, 0.022, 0.039, 0.045, 0.039, 0.022, 0.003, -0.013, -0.019, -0.017, -0.011, -0.005, -0.001)) snd_display("dsp.rb bp: %s?", v) end b = make_bandpass(hz2radians(1500.0), hz2radians(2000.0), 20) map_channel(lambda do |y| bandpass(b, y) end) sp = rough_spectrum(ind) unless vequal(sp, vct(0.010, 1, 0.154, 0, 0, 0, 0, 0, 0, 0)) snd_display("dsp bp rough spectrum: %s?", sp) end undo_edit # b = make_bandstop(hz2radians(1500.0), hz2radians(2000.0), 10) v = make_vct!(20) do |i| bandstop(b, i.zero? ? 1.0 : 0.0) end unless vequal(v, vct(-0.001, 0.001, 0.005, 0.011, 0.017, 0.019, 0.013, -0.003, -0.022, -0.039, 0.955, -0.039, -0.022, -0.003, 0.013, 0.019, 0.017, 0.011, 0.005, 0.001)) snd_display("dsp.rb bs: %s?", v) end b = make_bandstop(hz2radians(1500.0), hz2radians(2000.0), 20) map_channel(lambda do |y| bandstop(b, y) end) sp = rough_spectrum(ind) if (not vequal(sp, vct(0.904, 0.425, 0.821, 0.998, 0.997, 0.996, 0.996, 0.996, 0.997, 1))) and (not vequal(sp, vct(0.906, 0.425, 0.822, 1.000, 0.999, 0.998, 0.998, 0.998, 0.998, 1))) snd_display("dsp bp rough spectrum: %s?", sp) end undo_edit # b = make_differentiator(10) v = make_vct!(20) do |i| differentiator(b, i.zero? ? 1.0 : 0.0) end unless vequal(v, vct(-0.008, 0.011, -0.021, 0.039, -0.066, 0.108, -0.171, 0.270, -0.456, 0.977, 0.000, -0.977, 0.456, -0.270, 0.171, -0.108, 0.066, -0.039, 0.021, -0.011)) snd_display("dsp.rb df: %s?", v) end b = make_differentiator(20) map_channel(lambda do |y| differentiator(b, y) end) sp = rough_spectrum(ind) unless vequal(sp, vct(0.004, 0.027, 0.075, 0.147, 0.242, 0.362, 0.506, 0.674, 0.864, 1)) snd_display("dsp df rough spectrum: %s?", sp) end undo_edit # b = make_iir_high_pass_2(440.0) v = make_vct!(10) do |i| butter(b, i.zero? ? 1.0 : 0.0) end unless vequal(v, vct(0.915, -0.162, -0.146, -0.131, -0.117, -0.103, -0.09, -0.078, -0.066, -0.056)) snd_display("iir-2 high: %s?", v) end b = make_iir_high_pass_2(1000.0) map_channel(lambda do |y| butter(b, y) end) sp = rough_spectrum(ind) if (not vequal(sp, vct(0.150, 0.833, 0.980, 0.994, 0.997, 0.998, 0.999, 0.998, 0.997, 1))) and (not vequal(sp, vct(0.150, 0.833, 0.981, 0.995, 0.998, 0.999, 1, 1, 0.998, 0.997))) snd_display("iir-2 hp rough spectrum: %s?", sp) end undo_edit # b = make_iir_low_pass_2(440.0) v = make_vct!(10) do |i| butter(b, i.zero? ? 1.0 : 0.0) end unless vequal(v, vct(0.004, 0.014, 0.026, 0.035, 0.043, 0.049, 0.053, 0.055, 0.057, 0.057)) snd_display("iir-2 low: %s?", v) end b = make_iir_low_pass_2(1000.0) map_channel(lambda do |y| butter(b, y) end) sp = rough_spectrum(ind) unless vequal(sp, vct(1, 0.212, 0.024, 0.005, 0.001, 0, 0, 0, 0, 0)) snd_display("iir-2 lp rough spectrum: %s?", sp) end undo_edit # b = make_iir_band_pass_2(440.0, 490.0) v = make_vct!(10) do |i| butter(b, i.zero? ? 1.0 : 0.0) end unless vequal(v, vct(0.007, 0.014, 0.013, 0.013, 0.012, 0.010, 0.009, 0.008, 0.006, 0.004)) snd_display("iir bp-2 bandpass: %s?", v) end b = make_iir_band_pass_2(1000.0, 1500.0) map_channel(lambda do |y| butter(b, y) end) sp = rough_spectrum(ind) unless vequal(sp, vct(0.239, 1, 0.117, 0.041, 0.019, 0.010, 0.005, 0.003, 0.001, 0)) snd_display("iir bp-2 rough spectrum: %s?", sp) end undo_edit # b = make_iir_band_stop_2(440.0, 500.0) v = make_vct!(10) do |i| butter(b, i.zero? ? 1.0 : 0.0) end v1 = vct(0.992, -0.017, -0.016, -0.015, -0.014, -0.012, -0.011, -0.009, -0.007, -0.005) snd_test_neq(v, v1, "iir bp-2 bandstop: %s?") b = make_iir_band_stop_2(1000.0, 1500.0) map_channel(lambda do |y| butter(b, y) end) sp = rough_spectrum(ind) if (not vequal(sp, vct(0.836, 0.525, 0.943, 0.979, 0.989, 0.994, 0.997, 0.997, 0.997, 1))) and (not vequal(sp, vct(0.838, 0.527, 0.945, 0.981, 0.991, 0.996, 0.999, 1, 0.999, 0.998))) snd_display("iir bs-2 rough spectrum: %s?", sp) end undo_edit # b = make_butter_hp(4, 440.0) v = make_vct!(10) do |i| butter(b, i.zero? ? 1.0 : 0.0) end v1 = vct(0.725, -0.466, -0.315, -0.196, -0.104, -0.036, 0.014, 0.047, 0.0685, 0.0775) v2 = vct(0.725, -0.466, -0.315, -0.196, -0.104, -0.035, 0.015, 0.049, 0.070, 0.081) v3 = vct(0.725, -0.466, -0.315, -0.196, -0.104, -0.035, 0.014, 0.049, 0.069, 0.079) if (not vequal(v, v1)) and (not vequal(v, v2)) and (not vequal(v, v3)) snd_test_neq(v, v1, "butter hp (1)") snd_test_neq(v, v2, "butter hp (2)") snd_test_neq(v, v3, "butter hp (3)") end b = make_butter_hp(4, 1000.0) map_channel(lambda do |y| butter(b, y) end) sp = rough_spectrum(ind) if (not vequal(sp, vct(0.0505, 0.982, 1.0, 1.0, 0.998, 0.998, 0.999, 0.998, 0.996, 0.999))) and (not vequal(sp, vct(0.051, 0.982, 1.0, 1.0, 0.998, 0.998, 0.998, 0.999, 0.997, 0.995))) and (not vequal(sp, vct(0.051, 0.991, 1.0, 1.0, 0.998, 0.998, 0.999, 0.999, 0.997, 0.995))) and (not vequal(sp, vct(0.045, 0.970, 1.0, 1.0, 0.998, 0.998, 0.999, 0.999, 0.997, 0.995))) and (not vequal(sp, vct(0.052, 0.971, 1.0, 1.0, 0.998, 0.998, 0.999, 0.999, 0.997, 0.995))) snd_display("butter hp rough spectrum: %s?", sp) end undo_edit # b = make_butter_lp(4, 440.0) v = make_vct!(10) do |i| butter(b, i.zero? ? 1.0 : 0.0) end unless vequal(v, make_vct(10)) snd_display("butter lp: %s?", v) end b = make_butter_lp(4, 1000.0) map_channel(lambda do |y| butter(b, y) end) sp = rough_spectrum(ind) if (not vequal(sp, vct(1, 0.035, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000))) and (not vequal(sp, vct(1, 0.038, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000))) snd_display("butter lp rough spectrum: %s?", sp) end undo_edit # b = make_butter_bp(4, 440.0, 500.0) v = make_vct!(10) do |i| butter(b, i.zero? ? 1.0 : 0.0) end unless vequal(v, make_vct(10)) snd_display("butter bp: %s?", v) end b = make_butter_bp(4, 1000.0, 1500.0) map_channel(lambda do |y| butter(b, y) end) undo_edit # b = make_butter_bs(4, 440.0, 500.0) v = make_vct!(10) do |i| butter(b, i.zero? ? 1.0 : 0.0) end if (not vequal(v, vct(0.978, -0.043, -0.041, -0.038, -0.035, -0.031, -0.026, -0.0225, -0.015, -0.0085))) and (not vequal(v, vct(0.978, -0.043, -0.041, -0.038, -0.035, -0.031, -0.027, -0.022, -0.017, -0.011))) and (not vequal(v, vct(0.978, -0.043, -0.041, -0.038, -0.035, -0.031, -0.027, -0.021, -0.014, -0.011))) snd_display("butter bs: %s?", v) end b = make_butter_bs(4, 1000.0, 1500.0) map_channel(lambda do |y| butter(b, y) end) undo_edit # revert_sound test_scanned_synthesis(0.1, 10000, 1.0, 0.1, 0.0) close_sound(ind) end def test_08_06 gen = make_sawtooth_wave(440.0) gen1 = make_sawtooth_wave(440.0) print_and_check(gen, "sawtooth-wave", "sawtooth-wave freq: 440.000Hz, phase: 3.142, amp: 1.000") v0 = Vct.new(10) do sawtooth_wave(gen, 0.0) end v1 = make_vct(10) v1.map! do |x| sawtooth_wave?(gen1) ? sawtooth_wave(gen1, 0.0) : -1.0 end unless vequal(v0, v1) snd_display("map sawtooth_wave: %s %s?", v0, v1) end unless sawtooth_wave?(gen) snd_display("%s not sawtooth_wave?", gen) end if fneq(gen.phase, 4.39538) snd_display("sawtooth_wave phase: %s?", gen.phase) end if fneq(gen.frequency, 440.0) snd_display("sawtooth_wave frequency: %s?", gen.frequency) end gen.frequency = 100.0 if fneq(gen.frequency, 100.0) snd_display("sawtooth_wave set_frequency: %s?", gen.frequency) end if fneq(gen.scaler, 1.0) snd_display("sawtooth_wave scaler: %s?", gen.scaler) end gen.scaler = 0.5 if fneq(gen.scaler, 0.5) snd_display("sawtooth_wave set_scaler: %s?", gen.scaler) end if fneq(v0[1], 0.04) or fneq(v0[8], 0.319) snd_display("sawtooth_wave output: %s?", v0) end test_gen_equal(make_sawtooth_wave(440.0), make_sawtooth_wave(440.0), make_sawtooth_wave(120.0)) test_gen_equal(make_sawtooth_wave(440.0), make_sawtooth_wave(440.0), make_sawtooth_wave(440.0, 1.0, 1.0)) test_gen_equal(make_sawtooth_wave(440.0), make_sawtooth_wave(440.0), make_sawtooth_wave(440.0, 0.5)) gen1 = make_sawtooth_wave(100.0) gen2 = make_sawtooth_wave(-100.0) mx = 0.0 100.times do mx = [mx, (gen1.run + gen2.run).abs].max end if fneq(mx, 0.0) snd_display("sawtooth_wave +-: %s?", mx) end # gen = make_square_wave(440.0) gen1 = make_square_wave(440.0) print_and_check(gen, "square-wave", "square-wave freq: 440.000Hz, phase: 0.000, amp: 1.000") v0 = make_vct!(10) do |i| square_wave(gen, 0.0) end v1 = make_vct(10) w = 1.0 v1.map! do |x| w = gen1.width square_wave?(gen1) ? square_wave(gen1, 0.0) : -1.0 end if fneq(w, 0.5) snd_display("mus_width opt: %s?", w) end unless vequal(v0, v1) snd_display("map square_wave: %s %s?", v0, v1) end unless square_wave?(gen) snd_display("%s not square_wave?", gen) end if fneq(gen.phase, 1.253787) snd_display("square_wave phase: %s?", gen.phase) end if fneq(gen.frequency, 440.0) snd_display("square_wave frequency: %s?", gen.frequency) end if fneq(gen.scaler, 1.0) snd_display("square_wave scaler: %s?", gen.scaler) end gen.scaler = 0.5 if fneq(gen.scaler, 0.5) snd_display("square_wave set_scaler: %s?", gen.scaler) end if fneq(gen.width, 0.5) snd_display("square_wave width: %s?", gen.width) end gen.width = 0.75 if fneq(gen.width, 0.75) snd_display("square_wave set_width: %s?", gen.width) end if fneq(v0[1], 1.0) or fneq(v0[8], 1.0) snd_display("square_wave output: %s?", v0) end test_gen_equal(make_square_wave(440.0), make_square_wave(440.0), make_square_wave(120.0)) test_gen_equal(make_square_wave(440.0), make_square_wave(440.0), make_square_wave(440.0, 1.0, 1.0)) test_gen_equal(make_square_wave(440.0), make_square_wave(440.0), make_square_wave(440.0, 0.5)) old_srate = mus_srate set_mus_srate(500.0) gen = make_square_wave(100.0, -0.5, HALF_PI) v0 = make_vct!(20) do |i| gen.run end unless vequal(v0, vct(-0.5, -0.5, 0.0, 0.0, -0.5, -0.5, -0.5, 0.0, 0.0, -0.5, -0.5, -0.5, 0.0, 0.0, -0.5, -0.5, -0.5, 0.0, 0.0, -0.5)) snd_display("square_wave -0.5: %s?", v0) end set_mus_srate(old_srate) # gen = make_triangle_wave(440.0) gen1 = make_triangle_wave(440.0, 1.0, PI) gen2 = make_triangle_wave(440.0) print_and_check(gen, "triangle-wave", "triangle-wave freq: 440.000Hz, phase: 0.000, amp: 1.000") v0 = make_vct!(10) do |i| triangle_wave(gen, 0.0) end v1 = make_vct(10) v1.map! do |x| triangle_wave?(gen2) ? triangle_wave(gen2, 0.0) : -1.0 end unless vequal(v0, v1) snd_display("map triangle_wave: %s %s?", v0, v1) end unless triangle_wave?(gen) snd_display("%s not triangle_wave?", gen) end if fneq(gen.phase, 1.253787) snd_display("triangle_wave phase: %s?", gen.phase) end if fneq(gen1.phase, PI) snd_display("init triangle_wave phase: %s?", gen1.phase) end if fneq(gen.frequency, 440.0) snd_display("triangle_wave frequency: %s?", gen.frequency) end if fneq(gen.scaler, 1.0) snd_display("triangle_wave scaler: %s?", gen.scaler) end gen.scaler = 0.5 if fneq(gen.scaler, 0.5) snd_display("triangle_wave set_scaler: %s?", gen.scaler) end if fneq(v0[1], 0.08) or fneq(v0[8], 0.639) snd_display("triangle_wave output: %s?", v0) end test_gen_equal(make_triangle_wave(440.0), make_triangle_wave(440.0), make_triangle_wave(120.0)) test_gen_equal(make_triangle_wave(440.0), make_triangle_wave(440.0), make_triangle_wave(440.0, 1.0, 1.0)) test_gen_equal(make_triangle_wave(440.0), make_triangle_wave(440.0), make_triangle_wave(440.0, 0.5)) gen1 = make_triangle_wave(100.0) gen2 = make_triangle_wave(-100.0) mx = 0.0 100.times do mx = [mx, (gen1.run + gen2.run).abs].max end if fneq(mx, 0.0) snd_display("triangle_wave +-: %s?", mx) end # gen = make_pulse_train(440.0) gen1 = make_pulse_train(440.0) print_and_check(gen, "pulse-train", "pulse-train freq: 440.000Hz, phase: 0.000, amp: 1.000") v0 = make_vct!(10) do |i| pulse_train(gen, 0.0) end v1 = make_vct(10) v1.map! do |x| pulse_train?(gen1) ? pulse_train(gen1, 0.0) : -1.0 end unless vequal(v0, v1) snd_display("map pulse_train: %s %s?", v0, v1) end unless pulse_train?(gen) snd_display("%s not pulse_train?", gen) end if fneq(gen.phase, 1.253787) snd_display("pulse_train phase: %s?", gen.phase) end if fneq(gen.frequency, 440.0) snd_display("pulse_train frequency: %s?", gen.frequency) end if fneq(gen.scaler, 1.0) snd_display("pulse_train scaler: %s?", gen.scaler) end gen.scaler = 0.5 if fneq(gen.scaler, 0.5) snd_display("pulse_train set_scaler: %s?", gen.scaler) end if fneq(v0[0], 1.0) or fneq(v0[8], 0.0) snd_display("pulse_train output: %s?", v0) end test_gen_equal(make_pulse_train(440.0), make_pulse_train(440.0), make_pulse_train(120.0)) test_gen_equal(make_pulse_train(440.0), make_pulse_train(440.0), make_pulse_train(440.0, 1.0, 1.0)) test_gen_equal(make_pulse_train(440.0), make_pulse_train(440.0), make_pulse_train(440.0, 0.5)) old_srate = mus_srate set_mus_srate(500.0) gen = make_pulse_train(100.0, -0.5, HALF_PI) v0 = make_vct!(20) do |i| gen.run end unless vequal(v0, vct(0.0, 0.0, 0.0, 0.0, -0.5, 0.0, 0.0, 0.0, 0.0, -0.5, 0.0, 0.0, 0.0, 0.0, -0.5, 0.0, 0.0, 0.0, 0.0, -0.5)) snd_display("pulse_train -0.5: %s?", v0) end set_mus_srate(old_srate) # gen = make_two_pole(1200.0, 0.1) unless two_pole?(gen) snd_display("%s not 2-polar?", gen) end if gen.order != 2 snd_display("2-polar order: %s?", gen.order) end if fneq(gen.a0, 1.0) snd_display("2-polar a0: %s?", gen.a0) end if fneq(gen.b1, -0.188) snd_display("2-polar b1: %s?", gen.b1) end if fneq(gen.b2, 0.01) snd_display("2-polar b2: %s?", gen.b2) end if fneq(gen.frequency, 1200.0) snd_display("2-polar freq: %s?", gen.frequency) end if fneq(gen.scaler, 0.1) snd_display("2-polar scaler: %s?", gen.scaler) end # gen = make_two_pole(:frequency, 1200.0, :radius, 0.1) unless two_pole?(gen) snd_display("%s not f2-polar?", gen) end if gen.order != 2 snd_display("f2-polar order: %s?", gen.order) end if fneq(gen.a0, 1.0) snd_display("f2-polar a0: %s?", gen.a0) end if fneq(gen.b1, -0.188) snd_display("f2-polar b1: %s?", gen.b1) end if fneq(gen.b2, 0.01) snd_display("f2-polar b2: %s?", gen.b2) end if fneq(gen.frequency, 1200.0) snd_display("f2-polar freq: %s?", gen.frequency) end if fneq(gen.scaler, 0.1) snd_display("f2-polar scaler: %s?", gen.scaler) end # gen = make_two_zero(1200.0, 0.1) unless two_zero?(gen) snd_display("%s not 2-zp?", gen) end if gen.order != 2 snd_display("2-zp order: %s?", gen.order) end if fneq(gen.a0, 1.0) snd_display("2-zp a0: %s?", gen.a0) end if fneq(gen.a1, -0.188) snd_display("2-zp a1: %s?", gen.a1) end if fneq(gen.a2, 0.01) snd_display("2-zp a2: %s?", gen.a2) end if fneq(gen.frequency, 1200.0) snd_display("2-zp freq: %s?", gen.frequency) end if fneq(gen.scaler, 0.1) snd_display("2-zp scaler: %s?", gen.scaler) end # gen = make_two_zero(:frequency, 1200.0, :radius, 0.1) unless two_zero?(gen) snd_display("%s not f2-zp?", gen) end if gen.order != 2 snd_display("f2-zp order: %s?", gen.order) end if fneq(gen.a0, 1.0) snd_display("f2-zp a0: %s?", gen.a0) end if fneq(gen.a1, -0.188) snd_display("f2-zp a1: %s?", gen.a1) end if fneq(gen.a2, 0.01) snd_display("f2-zp a2: %s?", gen.a2) end if fneq(gen.frequency, 1200.0) snd_display("f2-zp freq: %s?", gen.frequency) end if fneq(gen.scaler, 0.1) snd_display("f2-zp scaler: %s?", gen.scaler) end # gen = make_formant(1200.0, 0.9) gen1 = make_formant(1200.0, 0.9) print_and_check(gen, "formant", "formant frequency: 1200.000, radius: 0.900") v0 = make_vct!(10) do |i| formant(gen, i.zero? ? 1.0 : 0.0) end v1 = make_vct(10) inp = -1 v1.map! do |x| inp += 1 formant?(gen1) ? formant(gen1, inp.zero? ? 1.0 : 0.0) : -1.0 end unless vequal(v0, v1) snd_display("map formant: %s %s?", v0, v1) end unless formant?(gen) snd_display("%s not formant?", gen) end if gen.order != 2 snd_display("formant order: %s?", gen.order) end if fneq(gen.frequency, 1200.0) snd_display("formant frequency: %s?", gen.frequency) end if fneq(v0[0], 0.095) or fneq(v0[1], 0.161) snd_display("formant output: %s?", v0) end if fneq(gen.scaler, 0.9) snd_display("formant gain: %s?", gen.scaler) end gen.scaler = 2.0 if fneq(gen.scaler, 2.0) snd_display("formant set_gain: %s?", gen.scaler) end f1 = make_formant(1200.0, 0.9) f2 = make_formant(1200.0, 0.9) f3 = make_formant(600.0, 0.9) formant(f1, 1.0) formant(f2, 1.0) formant(f3, 1.0) test_gen_equal(f1, f2, f3) f1 = make_formant(1200.0, 0.9) f2 = make_formant(1200.0, 0.9) f3 = make_formant(1200.0, 0.99) formant(f1, 1.0) formant(f2, 1.0) formant(f3, 1.0) test_gen_equal(f1, f2, f3) # amps = vct(0.5, 0.25) ff = [make_formant(1000.0, 0.1), make_formant(100.0, 0.2)] fs = make_formant_bank(ff, amps) f0 = make_formant(1000.0, 0.1) f1 = make_formant(100.0, 0.2) v0 = make_vct!(10) do |i| val = i.zero? ? 1.0 : 0.0 (0.5 * formant(f0, val)) + (0.25 * formant(f1, val)) end v1 = make_vct!(10) do |i| val = i.zero? ? 1.0 : 0.0 formant_bank(fs, val) end unless vequal(v0, v1) snd_display("formant_bank 1: %s %s?", v0, v1) end # amps = vct(0.5, 0.25) ff = [make_formant(1000.0, 0.1), make_formant(100.0, 0.2)] fs = make_formant_bank(ff, amps) v = make_vct!(5) do |i| val = i.zero? ? 1.0 : 0.0 formant_bank(fs, val) end unless vequal(v, vct(0.368, 0.095, -0.346, -0.091, -0.020)) snd_display("run formant_bank: %s?", v) end # ob = open_sound("oboe.snd") poltergeist = lambda do |frek, amp, r, gain, frek_env, r_env| # test courtesy of Anders Vinjar filt = make_formant(frek, r) fe = make_env(:envelope, frek_env, :length, framples, :offset, frek) re = make_env(:envelope, r_env, :length, framples, :offset, r) lambda do |y| outval = gain * formant(filt, amp * y) mus_set_formant_radius_and_frequency(filt, env(re), env(fe)) outval end end map_chan(poltergeist.call(300, 0.1, 0.0, 30.0, [0, 100, 1, 4000], [0, 0.99, 1, 0.9])) play(ob, :wait, true) close_sound(ob) end def test_08_08 [[:Hamming_window, 0.0, vct(0.080, 0.115, 0.215, 0.364, 0.540, 0.716, 0.865, 1.000, 1.000, 0.865, 0.716, 0.540, 0.364, 0.215, 0.115, 0.080)], [:Rectangular_window, 0.0, vct(1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000)], [:Hann_window, 0.0, vct(0.000, 0.038, 0.146, 0.309, 0.500, 0.691, 0.854, 1.000, 1.000, 0.854, 0.691, 0.500, 0.309, 0.146, 0.038, 0.000)], [:Welch_window, 0.0, vct(0.000, 0.234, 0.438, 0.609, 0.750, 0.859, 0.938, 1.000, 1.000, 0.938, 0.859, 0.750, 0.609, 0.438, 0.234, 0.000)], [:Connes_window, 0.0, vct(0.000, 0.055, 0.191, 0.371, 0.562, 0.739, 0.879, 1.000, 1.000, 0.879, 0.739, 0.562, 0.371, 0.191, 0.055, 0.000)], [:Parzen_window, 0.0, vct(0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 1.000, 1.000, 0.750, 0.625, 0.500, 0.375, 0.250, 0.125, 0.000)], [:Bartlett_window, 0.0, vct(0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 1.000, 1.000, 0.750, 0.625, 0.500, 0.375, 0.250, 0.125, 0.000)], [:Blackman2_window, 0.0, vct(0.005, 0.020, 0.071, 0.177, 0.344, 0.558, 0.775, 1.000, 1.000, 0.775, 0.558, 0.344, 0.177, 0.071, 0.020, 0.005)], [:Blackman3_window, 0.0, vct(0.000, 0.003, 0.022, 0.083, 0.217, 0.435, 0.696, 1.000, 1.000, 0.696, 0.435, 0.217, 0.083, 0.022, 0.003, 0.000)], [:Blackman4_window, 0.0, vct(0.002, 0.002, 0.003, 0.017, 0.084, 0.263, 0.562, 1.000, 1.000, 0.562, 0.263, 0.084, 0.017, 0.003, 0.002, 0.002)], [:Blackman5_window, 0.0, vct(0.000, 0.000, 0.003, 0.022, 0.097, 0.280, 0.574, 1.000, 1.000, 0.574, 0.280, 0.097, 0.022, 0.003, 0.000, 0.000)], [:Blackman6_window, 0.0, vct(0.000, 0.000, 0.001, 0.011, 0.064, 0.223, 0.520, 1.000, 1.000, 0.520, 0.223, 0.064, 0.011, 0.001, 0.000, 0.000)], [:Blackman7_window, 0.0, vct(0.000, 0.000, 0.000, 0.006, 0.042, 0.177, 0.471, 1.000, 1.000, 0.471, 0.177, 0.042, 0.006, 0.000, 0.000, 0.000)], [:Blackman8_window, 0.0, vct(0.000, 0.000, 0.000, 0.003, 0.028, 0.141, 0.426, 1.000, 1.000, 0.426, 0.141, 0.028, 0.003, 0.000, 0.000, 0.000)], [:Blackman9_window, 0.0, vct(0.000, 0.000, 0.000, 0.001, 0.018, 0.112, 0.385, 1.000, 1.000, 0.385, 0.112, 0.018, 0.001, 0.000, 0.000, 0.000)], [:Blackman10_window, 0.0, vct(0.000, 0.000, 0.000, 0.001, 0.012, 0.089, 0.349, 1.000, 1.000, 0.349, 0.089, 0.012, 0.001, 0.000, 0.000, 0.000)], [:Rv2_window, 0.0, vct(0.000, 0.001, 0.021, 0.095, 0.250, 0.478, 0.729, 1.000, 1.000, 0.729, 0.478, 0.250, 0.095, 0.021, 0.001, 0.000)], [:Rv3_window, 0.0, vct(0.000, 0.000, 0.003, 0.029, 0.125, 0.330, 0.622, 1.000, 1.000, 0.622, 0.330, 0.125, 0.029, 0.003, 0.000, 0.000)], [:Rv4_window, 0.0, vct(0.000, 0.000, 0.000, 0.009, 0.062, 0.228, 0.531, 1.000, 1.000, 0.531, 0.228, 0.062, 0.009, 0.000, 0.000, 0.000)], [:Exponential_window, 0.0, vct(0.000, 0.087, 0.181, 0.283, 0.394, 0.515, 0.646, 0.944, 0.944, 0.646, 0.515, 0.394, 0.283, 0.181, 0.087, 0.000)], [:Riemann_window, 0.0, vct(0.000, 0.139, 0.300, 0.471, 0.637, 0.784, 0.900, 1.000, 1.000, 0.900, 0.784, 0.637, 0.471, 0.300, 0.139, 0.000)], [:Kaiser_window, 2.5, vct(0.304, 0.426, 0.550, 0.670, 0.779, 0.871, 0.941, 1.000, 1.000, 0.941, 0.871, 0.779, 0.670, 0.550, 0.426, 0.304)], [:Cauchy_window, 2.5, vct(0.138, 0.173, 0.221, 0.291, 0.390, 0.532, 0.719, 1.000, 1.000, 0.719, 0.532, 0.390, 0.291, 0.221, 0.173, 0.138)], [:Poisson_window, 2.5, vct(0.082, 0.112, 0.153, 0.210, 0.287, 0.392, 0.535, 1.000, 1.000, 0.535, 0.392, 0.287, 0.210, 0.153, 0.112, 0.082)], [:Gaussian_window, 1.0, vct(0.607, 0.682, 0.755, 0.823, 0.882, 0.932, 0.969, 1.000, 1.000, 0.969, 0.932, 0.882, 0.823, 0.755, 0.682, 0.607)], [:Tukey_window, 0.0, vct(0.000, 0.038, 0.146, 0.309, 0.500, 0.691, 0.854, 1.000, 1.000, 0.854, 0.691, 0.500, 0.309, 0.146, 0.038, 0.000)], [:Hann_poisson_window, 0.0, vct(0.000, 0.038, 0.146, 0.309, 0.500, 0.691, 0.854, 1.000, 1.000, 0.854, 0.691, 0.500, 0.309, 0.146, 0.038, 0.000)], ].each do |win, beta, vals| Snd.catch do res = make_fft_window(Module.const_get(win), 16, beta) unless vequal(res, vals) snd_display("%s: %s?", win, res) end end end if $with_test_gsl [[:Samaraki_window, 0.0, vct(1.000, 0.531, 0.559, 0.583, 0.604, 0.620, 0.631, 0.638, 0.640, 0.638, 0.631, 0.620, 0.604, 0.583, 0.559, 0.531)], [:Ultraspherical_window, 0.0, vct(1.000, 0.033, 0.034, 0.035, 0.036, 0.036, 0.037, 0.037, 0.037, 0.037, 0.037, 0.036, 0.036, 0.035, 0.034, 0.033)], [:Dolph_chebyshev_window, 0.0, vct(1.000, 0.033, 0.034, 0.035, 0.036, 0.036, 0.037, 0.037, 0.037, 0.037, 0.037, 0.036, 0.036, 0.035, 0.034, 0.033)], [:Dolph_chebyshev_window, 1.0, vct(1.000, 0.274, 0.334, 0.393, 0.446, 0.491, 0.525, 0.546, 0.553, 0.546, 0.525, 0.491, 0.446, 0.393, 0.334, 0.274)] ].each do |win, beta, vals| Snd.catch do res = make_fft_window(Module.const_get(win), 16, beta) unless vequal(res, vals) snd_display("%s: %s?", win, res) end end end [[:Ultraspherical_window, 0.0, 0.0, :Dolph_chebyshev_window, 0.0, 0.0], [:Ultraspherical_window, 0.0, 1.0, :Samaraki_window, 0.0, 0.0], [:Ultraspherical_window, 0.5, 0.0, :Dolph_chebyshev_window, 0.5, 0.0], [:Ultraspherical_window, 0.5, 1.0, :Samaraki_window, 0.5, 0.0] ].each do |win1, beta1, alpha1, win2, beta2, alpha2| Snd.catch do val1 = make_fft_window(Module.const_get(win1), 16, beta1, alpha1) val2 = make_fft_window(Module.const_get(win2), 16, beta2, alpha2) unless vequal(val1, vals2) snd_display("%s/%s %s: %s %s?", win1, win2, beta1, val1, val2) end end end val1 = dolph(16, 1.0) val2 = make_fft_window(Dolph_chebyshev_window, 16, 1.0) unless vequal(val1, val2) snd_display("dolph/dolph 1: %s %s?", val1, val2) end val1 = dolph_1(16, 1.0).to_vct val2 = make_fft_window(Dolph_chebyshev_window, 16, 1.0) unless vequal(val1, val2) snd_display("dolph_1/dolph 1: %s %s?", val1, val2) end end # $with_test_gsl # gen = make_env(:envelope, [0, 0, 1, 1, 2, 0], :scaler, 0.5, :length, 11) gen1 = make_env(:envelope, [0, 0, 1, 1, 2, 0], :scaler, 0.5, :length, 11) print_and_check(gen, "env", "env linear, pass: 0 (dur: 11), index: 0, scaler: 0.5000, offset: 0.0000, data: [0 0 1 1 2 0]") unless env?(gen) snd_display("%s not env?", gen) end if fneq(gen.scaler, 0.5) snd_display("env scaler: %s?", gen.scaler) end if fneq(gen.increment, 1.0) snd_display("env base (1.0): %s?", gen.increment) end if gen.length != 11 snd_display("env length: %s?", gen.length) end v0 = make_vct!(10) do env(gen) end v1 = make_vct(10) off = 123.0 v1.map! do |x| off = gen1.offset env?(gen1) ? env(gen1) : -1.0 end if fneq(off, 0.0) snd_display("mus_offset opt: %s?", off) end unless vequal(v0, v1) snd_display("map env: %s %s?", v0, v1) end if fneq(v0[0], 0.0) or fneq(v0[1], 0.1) or fneq(v0[6], 0.4) snd_display("env output: %s?", v0) end if fneq(res = env_interp(1.6, gen), 0.2) snd_display("env_interp %s at 1.6: %s?", gen, res) end gen = make_env(:envelope, [0, 1, 1, 0], :base, 32.0, :length, 11) if fneq(gen.increment, 32.0) snd_display("env base (32.0): %s?", gen.increment) end v0.map! do |val| env(gen) end if fneq(v0[0], 1.0) or fneq(v0[1], 0.698) or fneq(v0[8], 0.032) snd_display("%s output: %s?", gen, v0) end gen = make_env(:envelope, [0, 1, 1, 0], :base, 0.0325, :length, 11) if fneq(gen.increment, 0.0325) snd_display("env base (0.0325): %s?", gen.increment) end v0.map! do |val| env(gen) end if fneq(v0[0], 1.0) or fneq(v0[1], 0.986) or fneq(v0[8], 0.513) snd_display("%s output: %s?", gen, v0) end gen = make_env(:envelope, [0, 1, 1, 0.5, 2, 0], :base, 0.0, :length, 11, :offset, 1.0) if fneq(gen.offset, 1.0) snd_display("mus_offset: %s?", gen.offset) end if fneq(gen.increment, 0.0) snd_display("env base (0.0): %s?", gen.increment) end v0.map_with_index! do |val, i| if i == 3 if gen.location != 3 snd_display("env location: %s?", gen.location) end end env(gen) end if fneq(v0[0], 2.0) or fneq(v0[6], 1.5) or fneq(v0[8], 1.5) snd_display("%s output: %s?", gen, v0) end if fneq(res = env_interp(1.5, gen), 1.5) snd_display("env_interp %s at 1.5: %s?", gen, res) end gen.location = 6 if gen.location != 6 snd_display("set_mus_location (6): %s?", gen.location) end if fneq(val = env(gen), 1.5) snd_display("set_mus_location 6 -> %s (1.5)?", val) end gen.location = 0 if fneq(val = env(gen), 2.0) snd_display("set_mus_location 0 -> %s (2.0)?", val) end gen = make_env([0, 0, 1, -1, 2, 0], :length, 11) 5.times do |i| if fneq(val = env(gen), i / -5.0) snd_display("neg env: %s %s?", i, val) end end 5.times do |i| if fneq(val = env(gen), -1.0 + i / 5.0) snd_display("neg env: %s %s?", i, val) end end gen = make_env([0, 0, 1, -1, 2, 0], :length, 11, :base, 0.5) vct(0.0, -0.14869, -0.31950, -0.51571, -0.74110, -1.0, -0.74110, -0.51571, -0.31950, -0.14869).each_with_index do |val, i| if fneq(res = env(gen), val) snd_display("neg exp env: %s %s?", i, res) end end mus_apply(gen) e = make_env([0, 0, 1, 1], :length, 10) if fneq(res = env_interp(1.0, e), 1.0) snd_display("env_interp 0011 at 1: %s?", res) end if fneq(res = env_interp(2.0, e), 1.0) snd_display("env_interp 0011 at 2: %s?", res) end if fneq(res = env_interp(0.0, e), 0.0) snd_display("env_interp 0011 at 0: %s?", res) end if fneq(res = env_interp(0.444, e), 0.444) snd_display("env_interp 0011 at 0.444: %s?", res) end e.reset 10.times do |i| if fneq(val = env(e), i * 0.111111) snd_display("ramp env over 10: %s at %s?", val, i) end end e = make_env([0, 0, 0.5, 0.5, 1, 1], :base, 32, :length, 10) x = 0.0 vct(0, 0.0243, 0.0667, 0.1412, 0.2716, 0.5, 0.5958, 0.709, 0.8425, 1).each_with_index do |val, i| if fneq(res = env_interp(x, e), val) snd_display("[0, 0.5, 1] env_interp over 10: %s at %s (%s)", res, i, val) end x += 0.111111 end e = make_env([0, -1.0, 1, 1], :base, 32, :length, 10) x = 0.0 vct(-1.0, -0.9697, -0.9252, -0.8597, -0.7635, -0.6221, -0.4142, -0.1088, 0.34017, 1.0).each_with_index do |val, i| if fneq(res = env_interp(x, e), val) snd_display("[-1, 1] env_interp over 10: %s at %s (%s)", res, i, val) end x += 0.111111 end e = make_env([0, -1.0, 0.5, 0.5, 1, 0], :base, 32, :length, 10) x = 0.0 vct(-1.0, -0.952, -0.855, -0.661, -0.274, 0.5, 0.356, 0.226, 0.107, 0.0).each_with_index do |val, i| if fneq(res = env_interp(x, e), val) snd_display("[-1, 0.5, 0] env_interp over 10: %s at %s (%s)", res, i, val) end x += 0.111111 end e = make_env([0, 0.0, 0.5, 0.5, 1, -1.0], :base, 32, :length, 10) x = 0.0 vct(0, 0.085, 0.177, 0.276, 0.384, 0.5, -0.397, -0.775, -0.933, -1).each_with_index do |val, i| if fneq(res = env_interp(x, e), val) snd_display("[0, 0.5, -1] env_interp over 10: %s at %s (%s)", res, i, val) end x += 0.111111 end # e = make_env([0, 0, 1, 1], :length, 10, :base, 4) if fneq(res = env_interp(1.0, e), 1.0) snd_display("env_interp 0011 4 at 1: %s?", res) end if fneq(res = env_interp(0.0, e), 0.0) snd_display("env_interp 0011 4 at 0: %s?", res) end if fneq(res = env_interp(0.45, e), 0.2839) snd_display("env_interp 0011 4 at 0.45: %s?", res) end e = make_env([0, 0, 1, 1], :length, 10, :base, 0.2) if fneq(res = env_interp(1.0, e), 1.0) snd_display("env_interp 0011 2 at 1: %s?", res) end if fneq(res = env_interp(0.0, e), 0.0) snd_display("env_interp 0011 2 at 0: %s?", res) end if fneq(res = env_interp(0.45, e), 0.6387) snd_display("env_interp 0011 2 at 0.45: %s?", res) end e = make_env([0, 0, 1, 1], :length, 10, :offset, 2.0) e.offset = 3.0 if fneq(e.offset, 3.0) snd_display("set_mus_offset env: %s?", e.offset) end # e1 = make_env([0, 0, 1, 1], :base, 32.0, :length, 11) vct(0, 0.013, 0.032, 0.059, 0.097, 0.150, 0.226, 0.333, 0.484, 0.698, 1).each do |val| if fneq(res = env(e1), val) snd_display("exp env direct (32.0): %s %s", res, val) end end e1 = make_env([0, 1, 1, 2], :base, 32.0, :length, 11) vct(1, 1.013, 1.032, 1.059, 1.097, 1.15, 1.226, 1.333, 1.484, 1.698, 2).each do |val| if fneq(res = env(e1), val) snd_display("exp env direct (32.0) offset: %s %s", res, val) end end e1 = make_env([0, 1, 1, 2], :base, 32.0, :length, 11) vct(1, 1.013, 1.032, 1.059, 1.097, 1.15, 1.226, 1.333, 1.484, 1.698, 2).each do |val| if fneq(res = env(e1), val) snd_display("exp env direct (32.0) offset (and dur): %s %s", res, val) end end e1 = make_env([0, 0, 1, 1], :base, 0.032, :length, 11) vct(0.000, 0.301, 0.514, 0.665, 0.772, 0.848, 0.902, 0.940, 0.967, 0.986, 1.0).each do |val| if fneq(res = env(e1), val) snd_display("exp env direct (0.032): %s %s", res, val) end end # e1 = make_env([0, 0, 1, 1], :base, 0.03125, :length, 11) e2 = make_env([0, 0, 1, 1, 2, 0], :base, 32.0, :length, 11) e3 = make_env([0, 0, 0.1, 1, 2, 0], :base, 1.1, :length, 101) 10.times do |i| lv1 = env_interp(i * 0.1, e1) lv2 = env(e1) lv3 = env_interp(i * 0.2, e2) lv4 = env(e2) if fneq(lv1, lv2) snd_display("env_interp[rmp %s]: %s (%s)?", i * 0.1, lv1, lv2) end if fneq(lv3, lv4) snd_display("env_interp[pyr %s]: %s (%s)?", i * 0.2, lv3, lv4) end end 100.times do |i| lv5 = env_interp(i * 0.02, e3) lv6 = env(e3) if fneq(lv5, lv6) snd_display("env_interp[tri %s]: %s (%s)?", i * 0.02, lv5, lv6) end end # e1 = make_env([0, 0, 1, 1, 2, 0], :length, 10) lv1 = make_vct!(11) do env(e1) end lv2 = make_vct!(11) do env(e1) end e1.reset lv3 = make_vct!(11) do env(e1) end unless vequal(lv1, lv3) snd_display("mus_reset: %s %s?", lv1, lv3) end unless vequal(lv2, make_vct(11)) snd_display("mus_reset 1: %s?", lv2) end # gen = make_env([0, 0, 1, 1, 2, 0], :length, 11) 4.times do env(gen) end if fneq(res = env(gen), 0.8) snd_display("env(5): %s?", res) end gen.reset 4.times do env(gen) end if fneq(res = env(gen), 0.8) snd_display("mus_reset (via reset): %s?", res) end gen.location = 6 if fneq(res = env(gen), 0.8) snd_display("set_mus_location 6 -> %s (0.8)?", res) end gen = make_env([0, 0, 1, 1], :base, 0.032, :length, 12) gen.location = 5 if fneq(res = env(gen), 0.817) snd_display("set env location with base: %s %s?", res, gen) end gen = make_env([0, 0, 1, 1], :base, 0.032, :length, 12) gen.location = 5 if fneq(res = env(gen), 0.817) snd_display("set env location with base and dur: %s %s?", res, gen) end # test_gen_equal(make_env([0, 0, 1, 1, 2, 0], :scaler, 0.50, :length, 10), make_env([0, 0, 1, 1, 2, 0], :scaler, 0.50, :length, 10), make_env([0, 0, 1, 1, 2, 0], :scaler, 0.25, :length, 10)) test_gen_equal(make_env([0, 0, 1, 1, 2, 0], :scaler, 0.50, :length, 10), make_env([0, 0, 1, 1, 2, 0], :scaler, 0.50, :length, 10), make_env([0, 0, 1, 1, 2, 0], :scaler, 0.50, :length, 11)) test_gen_equal(make_env([0, 0, 1, 1, 2, 0], :scaler, 0.50, :length, 10), make_env([0, 0, 1, 1, 2, 0], :scaler, 0.50, :length, 10), make_env([0, 0, 1, 1, 3, 0], :scaler, 0.50, :length, 10)) # if (res = Snd.catch do make_env(:envelope, []) end).first != :no_data snd_display("make_env null env: %s", res.inspect) end if (res = Snd.catch do make_env(:length, 0) end).first != :no_data snd_display("make_env no env: %s", res.inspect) end if (res = Snd.catch do make_env(:envelope, [0, 0], :length, -1) end).first != :out_of_range snd_display("make_env bad end: %s", res.inspect) end if (res = Snd.catch do make_env(:envelope, [0, 0], :length, -1) end).first != :out_of_range snd_display("make_env bad dur: %s", res.inspect) end if (res = Snd.catch do make_env(:envelope, [0, 0], :duration, -1.0) end).first != :out_of_range snd_display("make_env bad duration: %s", res.inspect) end if (res = Snd.catch do make_env(:envelope, [0, 0], :base, -1.0) end).first != :out_of_range snd_display("make_env bad base: %s", res.inspect) end if (res = Snd.catch do make_env(:envelope, [1, 1, 0, 0], :length, 11) end).first != :mus_error snd_display("make_env bad env 1 1 0 0: %s", res.inspect) end if (res = Snd.catch do make_env(:envelope, [0, 1, -1, 0], :length, 11) end).first != :mus_error snd_display("make_env bad env 0 1 -1 0: %s", res.inspect) end if (res = Snd.catch do make_env(:envelope, [0, 1, 1, 0], :length, 11, :length, 10) end).first != :mus_error snd_display("make_env bad end/dur: %s", res.inspect) end end def test_08_09 gen = make_table_lookup(440.0, :wave, partials2wave([1, 1, 2, 1])) gen1 = make_table_lookup(440.0, :wave, partials2wave([1, 1, 2, 1], make_vct(512))) gen3 = make_table_lookup gen4 = make_table_lookup(440.0, :wave, partials2wave([1, 1, 2, 1])) print_and_check(gen, "table-lookup", "table-lookup freq: 440.000Hz, phase: 0.000, length: 512, interp: linear") if gen.length != 512 snd_display("table_lookup length: %s?", gen.length) end if gen3.length != 512 snd_display("default table_lookup length: %s?", gen3.length) end v0 = make_vct!(10) do table_lookup(gen, 0.0) end v1 = make_vct!(10) do mus_apply(gen1, 0.0) end v2 = make_vct(10) v2.map! do |x| table_lookup?(gen4) ? table_lookup(gen4) : -1.0 end unless vequal(v0, v2) snd_display("map table_lookup: %s %s?", v0, v2) end gen4 = make_table_lookup(440.0, :wave, partials2wave([1, 1, 2, 1])) v2.map! do |x| table_lookup(gen4) end unless vequal(v0, v2) snd_display("map table_lookup (no fm): %s %s?", v0, v2) end unless table_lookup?(gen) snd_display("%s not table_lookup?", gen) end unless vct?(gen.data) snd_display("mus_data table_lookup: %s?", gen.data) end if fneq(gen.phase, 1.253787) snd_display("table_lookup phase: %s?", gen.phase) end gen.phase = 1.0 if fneq(gen.phase, 1.0) snd_display("table_lookup set_phase: %s?", gen.phase) end if fneq(gen.frequency, 440.0) snd_display("table_lookup frequency: %s?", gen.frequency) end gen.frequency = 100.0 if fneq(gen.frequency, 100.0) snd_display("table_lookup set_frequency: %s?", gen.frequency) end if fneq(v0[1], 0.373) or fneq(v0[8], 1.75) snd_display("table_lookup output: %s?", v0) end unless vequal(v0, v1) snd_display("mus_apply table_lookup: %s %s?", v0, v1) end gen = make_table_lookup(440.0, :wave, phase_partials2wave([1, 1, 0, 2, 1, HALF_PI])) v0.map! do |val| table_lookup(gen, 0.0) end if fneq(v0[1], 1.094) or fneq(v0[8], 0.421) snd_display("table_lookup phase output: %s?", v0) end if fneq(vct_peak(partials2wave([1, 1, 2, 1])), 1.76035475730896) or fneq(vct_peak(partials2wave([1, 1, 2, 1], false, true)), 1.0) or fneq(vct_peak(partials2wave([1, 1, 2, 1, 3, 1, 4, 1], false, true)), 1.0) snd_display("normalized partials?") end gen.data = phase_partials2wave([1, 1, 0, 2, 1, HALF_PI], false, true) # if (res = Snd.catch do phase_partials2wave([1, 0.3, 2, 0.2]) end).first != :wrong_type_arg snd_display("bad length arg to phase_partials2wave: %s", res.inspect) end if (res = Snd.catch do phase_partials2wave(["hiho", 0.3, 2, 0.2]) end).first != :wrong_type_arg snd_display("bad harmonic arg to phase_partials2wave: %s", res.inspect) end if (res = Snd.catch do phase_partials2wave([]) end).first != :no_data snd_display("nil list to phase_partials2wave: %s", res.inspect) end phase_partials2wave([1, 1, 0], make_vct(16), false).each_with_index do |val, i| if fneq(val, res = sin((TWO_PI * i) / 16.0)) snd_display("phase_partials2wave 1 1 0 at %s: %s %s?", i, val, res) end end phase_partials2wave([1, 1, 0.25 * PI], make_vct(16), false).each_with_index do |val, i| if fneq(val, res = sin(0.25 * PI + ((TWO_PI * i) / 16.0))) snd_display("phase_partials2wave 1 1 0.25 at %s: %s %s?", i, val, res) end end phase_partials2wave([1, 1, 0, 2, 1, 0], make_vct(16), false).each_with_index do |val, i| if fneq(val, res = sin((TWO_PI * i) / 16.0) + sin((2.0 * TWO_PI * i) / 16.0)) snd_display("phase_partials2wave 1 1 0 2 1 0 at %s: %s %s?", i, val, res) end end phase_partials2wave([1, 1, 0, 2, 1, HALF_PI], make_vct(16), false).each_with_index do |val, i| if fneq(val, res = sin((TWO_PI * i) / 16.0) + sin(HALF_PI + ((2.0 * TWO_PI * i) / 16.0))) snd_display("phase_partials2wave 1 1 0 2 1 0.5 at %s: %s %s?", i, val, res) end end # test_gen_equal(make_table_lookup(440.0, :wave, partials2wave([1, 1, 2, 1])), make_table_lookup(440.0, :wave, partials2wave([1, 1, 2, 1])), make_table_lookup(100.0, :wave, partials2wave([1, 1, 2, 1]))) test_gen_equal(make_table_lookup(440.0, :wave, partials2wave([1, 1, 2, 1])), make_table_lookup(440.0, :wave, partials2wave([1, 1, 2, 1])), make_table_lookup(440.0, :wave, partials2wave([1, 1, 2, 0.5]))) # if (res = Snd.catch do partials2wave([0.5, 0.3, 0.2]) end).first != :bad_type snd_display("odd length arg to partials2wave: %s", res.inspect) end # hi = make_table_lookup(:size, 256) if hi.length != 256 snd_display("table_lookup set length: %s?", hi.length) end if (res = Snd.catch do make_table_lookup(:size, 0) end).first != :out_of_range snd_display("table_lookup size 0: %s", res.inspect) end gen = make_table_lookup(440.0, :wave, partials2wave([1, 1])) a = 0.0 ainc = (TWO_PI * 440.0) / 22050.0 1100.times do |i| if fneq(val1 = sin(a), val2 = gen.run(0.0)) snd_display("table_lookup [1, 1]: %s: %s %s?", i, val1, val2) end a += ainc end gen = make_table_lookup(4.0, :wave, partials2wave([1, 1])) a = 0.0 ainc = (TWO_PI * 4.0) / 22050.0 1100.times do |i| if fneq(val1 = sin(a), val2 = gen.run(0.0)) snd_display("table_lookup [1, 1] 4: %s: %s %s?", i, val1, val2) end a += ainc end gen = make_table_lookup(440.0, :wave, partials2wave([1, 0.75, 3, 0.25])) a = 0.0 ainc = (TWO_PI * 440.0) / 22050.0 1100.times do |i| val1 = 0.75 * sin(a) + 0.25 * sin(3.0 * a) if fneq(val1, val2 = gen.run(0.0)) snd_display("table_lookup [1, 0.75, 3, 0.25]: %s: %s %s?", i, val1, val2) end a += ainc end gen = make_table_lookup(0.0, :wave, partials2wave([1, 1])) gen1 = make_table_lookup(40.0, :wave, partials2wave([1, 1])) a = 0.0 a1 = 0.0 ainc = (TWO_PI * 40.0) / 22050.0 100.times do |i| if fneq(val1 = sin(a1), val2 = gen.run(gen1.run(0.0))) snd_display("table_lookup/table_lookup fm: %s: %s %s?", i, val1, val2) end a1 += sin(a) a += ainc end [[:Mus_interp_none, vct(0, 0.000, 0.000, 0.000, 0.000, 1.000, 1.000, 1.000, 1.000, 1.000)], [:Mus_interp_linear, vct(0, 0.200, 0.400, 0.600, 0.800, 1.000, 0.800, 0.600, 0.400, 0.200)], [:Mus_interp_lagrange, vct(0, 0.120, 0.280, 0.480, 0.720, 1.000, 0.960, 0.840, 0.640, 0.360)], [:Mus_interp_all_pass, vct(1, 0.000, 0.429, 0.143, 0.095, 0.905, 0.397, 0.830, 0.793, 0.912)], [:Mus_interp_hermite, vct(0, 0.168, 0.424, 0.696, 0.912, 1.000, 0.912, 0.696, 0.424, 0.168)] ].each do |type_sym, vals| type = Module.const_get(type_sym) tbl = make_table_lookup(:frequency, 0.0, :size, 4, :type, type) tbl.data[1] = 1.0 fm = (TWO_PI * 0.2) / 4.0 v = make_vct!(10) do table_lookup(tbl, fm) end if (not vequal(v, vals)) and (type_sym != :Mus_interp_all_pass) and (type_sym != :Mus_interp_none or (not vequal(v, vct(0, 0, 0, 0, 0, 0, 1, 1, 1, 1)))) snd_display("tbl interp %s: %s?", type_sym, v) end if tbl.interp_type != type snd_display("tbl interp_type (%s) %s?", type_sym, tbl.interp_type) end end # gen0 = make_polyshape(440.0, :coeffs, partials2polynomial([1, 1])) gen = make_polyshape(440.0, :partials, [1, 1], :kind, Mus_chebyshev_first_kind) gen1 = make_polyshape(440.0) print_and_check(gen, "polyshape", "polyshape freq: 440.000Hz, phase: 0.000, coeffs[2]: [0 1]") if gen.length != 2 snd_display("polyshape length: %s?", gen.length) end v0 = make_vct!(10) do if fneq(val0 = polyshape(gen0, 1.0, 0.0), val = mus_apply(gen, 1.0, 0.0)) snd_display("polyshape: %s != %s?", val, val0) end val end v1 = make_vct(10) v1.map! do |x| polyshape?(gen1) ? polyshape(gen1, 1.0, 0.0) : -1.0 end unless vequal(v0, v1) snd_display("map polyshape: %s %s?", v0, v1) end gen1 = make_polyshape(440.0, :coeffs, partials2polynomial([1, 1])) v1.map! do |x| polyshape(gen1, 1.0) end unless vequal(v0, v1) snd_display("map polyshape (no fm): %s %s?", v0, v1) end unless polyshape?(gen) snd_display("%s not polyshape?", gen) end if fneq(gen.phase, 1.253787) snd_display("polyshape phase: %s?", gen.phase) end gen.phase = 1.0 if fneq(gen.phase, 1.0) snd_display("polyshape set_phase: %s?", gen.phase) end if fneq(gen.frequency, 440.0) snd_display("polyshape frequency: %s?", gen.frequency) end gen.frequency = 100.0 if fneq(gen.frequency, 100.0) snd_display("polyshape set_frequency: %s?", gen.frequency) end unless vct?(gen.data) snd_display("mus_data polyshape: %s?", gen.data) end if fneq(v0[1], 0.992) or fneq(v0[8], 0.538) snd_display("polyshape output: %s?", v0) end gen0.data = make_vct(32) gen0.length = 32 if gen0.length != 32 snd_display("set_mus_length polyshape: %s?", gen0.length) end # test_gen_equal(make_polyshape(440.0, :partials, [1, 1]), make_polyshape(440.0), make_polyshape(100.0, :partials, [1, 1])) test_gen_equal(make_polyshape(440.0, :partials, [1, 1]), make_polyshape(440.0), make_polyshape(4400.0, :partials, [1, 1, 2, 0.5])) # gen = make_polyshape(440.0, :partials, [1, 1]) 1100.times do |i| a = gen.phase if fneq(val1 = cos(a), val2 = gen.run(1.0, 0.0)) snd_display("polyshaper [1, 1] %s: %s %s?", i, val1, val2) break end end gen = make_polyshape(440.0) # check default for partials: [1, 1]) 1100.times do |i| a = gen.phase val1 = cos(a) if fneq(val1, val2 = gen.run(1.0, 0.0)) snd_display("polyshaper [1, 1, 2, 0.5] %s: %s %s?", i, val1, val2) break end end gen = make_polyshape(440.0, :partials, [1, 1]) 1100.times do |i| a = gen.phase if fneq(val1 = 0.5 * cos(a), val2 = gen.run(0.5, 0.0)) snd_display("polyshaper default [1, 1] 0.5 %s: %s %s?", i, val1, val2) break end end # if (res = Snd.catch do make_polyshape(440.0, :coeffs, 3.14) end).first != :wrong_type_arg snd_display("make_polyshape bad coeffs: %s", res.inspect) end gen = make_polyshape(0.0, :coeffs, partials2polynomial([1, 1])) gen1 = make_polyshape(40.0, :coeffs, partials2polynomial([1, 1])) a1 = 0.0 a = 0.0 400.times do |i| if ((val1 = cos(a1)) - (val2 = polyshape(gen, 1.0, polyshape(gen1, 1.0)))).abs > 0.002 snd_display("polyshape fm: %s: %s %s?", i, val1, val2) break end a1 += cos(a) a = a + (TWO_PI * 40.0) / 22050.0 end end def test_08_10 gen = make_wave_train(440.0, 0.0, make_vct(20)) gen1 = make_wave_train(440.0, 0.0, make_vct(20)) print_and_check(gen, "wave-train", "wave-train freq: 440.000Hz, phase: 0.000, size: 20, interp: linear") 20.times do |i| gen.data[i] = i * 0.5 gen1.data[i] = gen.data[i] end if gen.length != 20 snd_display("wave_train length: %s?", gen.length) end v0 = make_vct!(10) do wave_train(gen, 0.0) end v1 = make_vct(10) v1.map! do |x| wave_train?(gen1) ? wave_train(gen1) : -1.0 end unless vequal(v0, v1) snd_display("map wave_train: %s %s?", v0, v1) end unless wave_train?(gen) snd_display("%s not wave_train?", gen) end if fneq(gen.phase, 0.0) snd_display("wave_train phase: %s?", gen.phase) end gen.phase = 1.0 if fneq(gen.phase, 1.0) snd_display("wave_train set_phase: %s?", gen.phase) end if fneq(gen.frequency, 440.0) snd_display("wave_train frequency: %s?", gen.frequency) end gen.frequency = 100.0 if fneq(gen.frequency, 100.0) snd_display("wave_train set_frequency: %s?", gen.frequency) end if fneq(v0[1], 0.5) or fneq(v0[8], 4.0) snd_display("wave_train output: %s?", v0) end gen.reset if fneq(gen.phase, 0.0) snd_display("wave_train reset phase: %s?", gen.phase) end if fneq(res = wave_train(gen, 0.0), 0.0) snd_display("wave_train data: %s?", res) end unless vct?(gen.data) snd_display("mus_data wave_train: %s?", gen.data) end gen.data = make_vct(3) # test_gen_equal(make_wave_train(440.0, 0.0, make_vct(20)), make_wave_train(440.0, 0.0, make_vct(20)), make_wave_train(100.0, 0.0, make_vct(20))) test_gen_equal(make_wave_train(440.0, 0.0, make_vct(20)), make_wave_train(440.0, 0.0, make_vct(20)), make_wave_train(440.0, 1.0, make_vct(20))) # hi = make_wave_train(:size, 256) if hi.length != 256 snd_display("wave_train set_length: %s?", hi.length) end hi.length = 128 if hi.length != 128 snd_display("wave_train set_length: %s?", hi.length) end [[:Mus_interp_none, vct(0.000, 1.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 1.000)], [:Mus_interp_linear, vct(0.200, 0.800, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.200, 0.800)], [:Mus_interp_lagrange, vct(0.120, 0.960, -0.080, 0.000, 0.0, 0.0, 0.0, 0.0, 0.120, 0.960)], [:Mus_interp_hermite, vct(0.168, 0.912, -0.064, -0.016, 0.0, 0.0, 0.0, 0.000, 0.168, 0.912)] ].each do |type_sym, vals| type = Module.const_get(type_sym) fm = (TWO_PI * 0.2) / 4.0 tbl = make_wave_train(:frequency, 3000.0, :initial_phase, fm, :size, 4, :type, type) tbl.data[1] = 1.0 v = make_vct!(10) do wave_train(tbl, 0.0) end unless vequal(v, vals) snd_display("wt tbl interp %s: %s?", type_sym, v) end if tbl.interp_type != type snd_display("wt tbl interp_type (%s) %s?", type_sym, tbl.interp_type) end end if (res = Snd.catch do make_wave_train(:size, 0) end).first != :out_of_range snd_display("wave_train size 0: %s", res.inspect) end # ind = new_sound(:size, 10) if framples != 10 snd_display("new_sound size 10: %s?", framples) end map_channel($init_channel, 7, 8) if framples != 15 snd_display("map_channel 7 8: %s?", framples) end map_channel($init_channel) if framples != 15 snd_display("map_channel (no dur): %s?", framples) end revert_sound(ind) map_channel($init_channel, 9, 10) if framples != 19 snd_display("map_channel 9 10: %s?", framples) end if (res = edit_position(ind, 0)) > 2 snd_display("map_channel pad edits (1): %s?", res) end revert_sound(ind) map_channel($init_channel, 10, 10) if framples != 20 snd_display("map_channel 10 10: %s?", framples) end if (res = edit_position(ind, 0)) > 2 snd_display("map_channel pad edits (2): %s?", res) end revert_sound(ind) map_channel($init_channel, 20, 10) if framples != 30 snd_display("map_channel 20 10: %s?", framples) end if (res = edit_position(ind, 0)) > 2 snd_display("map_channel pad edits (3): %s?", res) end revert_sound(ind) if scan_channel(lambda do |y| false end, 30, 10) snd_display("scan_channel past end?") end close_sound(ind) # ind = new_sound(:size, 1000) table = vct(0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6) gen = make_wave_train(1000.0, :wave, table) map_channel(lambda do |y| wave_train(gen) end) if fneq(res = maxamp, 0.6) snd_display("wave_train 0 max: %s?", res) end unless vequal(res = channel2vct(0, 30), vct(0.000, 0.100, 0.200, 0.300, 0.400, 0.500, 0.600, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.100, 0.200, 0.300, 0.400, 0.500, 0.600)) snd_display("wave_train 0 data: %s?", res) end unless vequal(res = channel2vct(85, 30), vct(0.000, 0.000, 0.000, 0.000, 0.000, 0.100, 0.200, 0.300, 0.400, 0.500, 0.600, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.100, 0.200, 0.300)) snd_display("wave_train 0 data 85: %s?", res) end undo_edit # table = make_vct(10, 0.1) gen = make_wave_train(1000.0, :initial_phase, PI, :wave, table) map_channel(lambda do |y| wave_train(gen) end) if fneq(res = maxamp, 0.1) snd_display("wave_train 1 max: %s?", res) end unless vequal(res = channel2vct(0, 30), vct(0.100, 0.100, 0.100, 0.100, 0.100, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.000, 0.000)) snd_display("wave_train 1 data: %s?", res) end undo_edit # table = make_vct(10, 0.1) gen = make_wave_train(2000.0, :wave, table) map_channel(lambda do |y| wave_train(gen) end) if fneq(res = maxamp, 0.1) snd_display("wave_train 2 max: %s?", res) end unless vequal(res = channel2vct(0, 30), vct(0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.000, 0.000, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.000, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100)) snd_display("wave_train 2 data: %s?", res) end if (not vequal(res = channel2vct(440, 30), vct(0.000, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.000, 0.000, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.000, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100))) and (not vequal(res = channel2vct(440, 30), vct(0.000, 0.000, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.000, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.000, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100))) snd_display("wave_train 2 data 440: %s?", res) end undo_edit # table = make_vct(10, 0.1) gen = make_wave_train(3000.0, :wave, table) map_channel(lambda do |y| wave_train(gen) end) if fneq(res = maxamp, 0.2) snd_display("wave_train 3 max: %s?", res) end unless vequal(res = channel2vct(0, 30), vct(0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.200, 0.200, 0.100, 0.100, 0.100, 0.100, 0.100, 0.200, 0.200, 0.200, 0.100, 0.100, 0.100, 0.100, 0.100, 0.200, 0.200, 0.100, 0.100, 0.100, 0.100, 0.100)) snd_display("wave_train 3 data: %s?", res) end unless vequal(res = channel2vct(440, 30), vct(0.100, 0.200, 0.200, 0.200, 0.100, 0.100, 0.100, 0.100, 0.100, 0.200, 0.200, 0.100, 0.100, 0.100, 0.100, 0.100, 0.200, 0.200, 0.200, 0.100, 0.100, 0.100, 0.100, 0.100, 0.200, 0.200, 0.100, 0.100, 0.100, 0.100)) snd_display("wave_train 3 data 440: %s?", res) end undo_edit # table = make_vct(10, 0.1) gen = make_wave_train(5000.0, :wave, table) map_channel(lambda do |y| wave_train(gen) end) if fneq(res = maxamp, 0.3) snd_display("wave_train 4 max: %s?", res) end unless vequal(res = channel2vct(0, 30), vct(0.100, 0.100, 0.100, 0.100, 0.100, 0.200, 0.200, 0.200, 0.200, 0.300, 0.200, 0.200, 0.200, 0.200, 0.300, 0.200, 0.200, 0.200, 0.300, 0.200, 0.200, 0.200, 0.200, 0.300, 0.200, 0.200, 0.200, 0.300, 0.200, 0.200)) snd_display("wave_train 4 data: %s?", res) end unless vequal(res = channel2vct(440, 30), vct(0.200, 0.200, 0.300, 0.200, 0.200, 0.200, 0.300, 0.200, 0.200, 0.200, 0.300, 0.300, 0.200, 0.200, 0.200, 0.300, 0.200, 0.200, 0.200, 0.300, 0.200, 0.200, 0.200, 0.200, 0.300, 0.200, 0.200, 0.200, 0.300, 0.200)) snd_display("wave_train 4 data 440: %s?", res) end undo_edit # table = make_vct(10, 0.1) gen = make_wave_train(1000.0, :wave, table) e = make_env([0, 1, 1, 2], :length, 1001) base_freq = mus_frequency(gen) map_channel(lambda do |y| res = wave_train(gen) set_mus_frequency(gen, env(e) * base_freq) res end) if fneq(res = maxamp, 0.1) snd_display("wave_train 5 max: %s?", res) end unless vequal(res = channel2vct(0, 30), vct(0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100)) snd_display("wave_train 5 data: %s?", res) end unless vequal(res = channel2vct(440, 30), vct(0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.000, 0.000, 0.000, 0.000, 0.000, 0.100)) snd_display("wave_train 5 data 440: %s?", res) end unless vequal(res = channel2vct(900, 30), vct(0.100, 0.000, 0.000, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.000, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.000, 0.000, 0.100, 0.100, 0.100, 0.100)) snd_display("wave_train 5 data 900: %s?", res) end undo_edit # table = make_vct(10, 0.1) gen = make_wave_train(500.0, :wave, table) ctr = 0 map_channel(lambda do |y| res = wave_train(gen) if ctr > 22 ctr = 0 vct_scale!(mus_data(gen), 1.05) else ctr += 1 end res end) if fneq(res = maxamp, 0.704) snd_display("wave_train 6 max: %s?", res) end unless vequal(res = channel2vct(0, 30), vct(0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000)) snd_display("wave_train 6 data: %s?", res) end if (not vequal(res = channel2vct(440, 30), vct(0.000, 0.241, 0.241, 0.241, 0.241, 0.241, 0.241, 0.241, 0.241, 0.241, 0.241, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000))) and (not vequal(res = channel2vct(440, 30), vct(0.000, 0.000, 0.241, 0.241, 0.241, 0.241, 0.241, 0.241, 0.241, 0.241, 0.241, 0.241, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000))) snd_display("wave_train 6 data 440: %s?", res) end unless vequal(res = channel2vct(900, 30), vct(0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.639, 0.639, 0.639)) snd_display("wave_train 6 data 900: %s?", res) end undo_edit fname = file_name(ind) close_sound(ind) delete_file(fname) # gen = make_readin("oboe.snd", 0, 1490) gen1 = make_readin("oboe.snd", 0, 1490) print_and_check(gen, "readin", "readin oboe.snd[chan 0], loc: 1490, dir: 1") v0 = make_vct!(10) do readin(gen) end v1 = make_vct(10) v1.map! do |x| if readin?(gen1) if gen1.channel.zero? readin(gen1) else 1.0 end else if gen1.file_name == "oboe.snd" -1.0 else -1.0 end end end unless vequal(v0, v1) snd_display("map readin: %s %s?", v0, v1) end unless readin?(gen) snd_display("%s not readin?", gen) end unless mus_input?(gen) snd_display("%s not input?", gen) end if gen.length != 50828 snd_display("readin length: %s?", gen.length) end if gen.channel.nonzero? snd_display("readin chan: %s?", gen.channel) end if gen.file_name != "oboe.snd" snd_display("readin mus_file_name: %s?", gen.file_name) end if fneq(v0[1], -0.009) or fneq(v0[7], 0.029) snd_display("readin output: %s?", v0) end set_mus_location(gen, 1000) if mus_location(gen) != 1000 snd_display("readin set_mus_location: %s?", mus_location(gen)) end if fneq(res = readin(gen), 0.033) snd_display("readin set_mus_location data: %s?", res) end set_mus_increment(gen, -1) if fneq(mus_increment(gen), -1.0) snd_display("readin set_mus_increment: %s?", mus_increment(gen)) end if (res = Snd.catch do make_readin("/baddy/hiho", 0, 124) end).first != :no_such_file snd_display("make_readin w/o file: %s", res.inspect) end if (res = Snd.catch do make_readin("oboe.snd", 123, 124) end).first != :out_of_range snd_display("make_readin with bad chan: %s", res.inspect) end # test_gen_equal(make_readin("oboe.snd", 0), make_readin("oboe.snd", 0), make_readin("oboe.snd", 0, 1230)) test_gen_equal(make_readin("oboe.snd", 0, :size, 512), make_readin("oboe.snd", 0, :size, 512), make_readin("pistol.snd", 0, :size, 512)) test_gen_equal(make_readin("2.snd", 1), make_readin("2.snd", 1), make_readin("2.snd", 0)) # gen = make_readin("2.snd", 1, :size, 1024) print_and_check(gen, "readin", "readin 2.snd[chan 1], loc: 0, dir: 1") v0.map! do readin(gen) end if gen.channel != 1 snd_display("readin chan 1: %s?", gen.channel) end if fneq(v0[1], 0.01) or fneq(v0[7], -0.006) snd_display("readin 1 output: %s?", v0) end print_and_check(gen, "readin", "readin 2.snd[chan 1], loc: 10, dir: 1") # gen = make_file2sample("oboe.snd") print_and_check(gen, "file->sample", "file->sample oboe.snd") unless file2sample?(gen) snd_display("%s not file2sample?", gen) end unless mus_input?(gen) snd_display("%s not input?", gen) end if gen.length != 50828 snd_display("file2sample length: %s?", gen.length) end if gen.file_name != "oboe.snd" snd_display("file2sample mus_file_name: %s?", gen.file_name) end v0 = make_vct!(10) do |i| file2sample(gen, 1490 + i) end if fneq(v0[1], -0.009) or fneq(v0[7], 0.029) snd_display("file2sample output: %s?", v0) end if fneq(mus_increment(gen), 0.0) snd_display("file2sample increment: %s?", mus_increment(gen)) end set_mus_increment(gen, 1) if fneq(mus_increment(gen), 1.0) snd_display("file2sample set_increment: %s?", mus_increment(gen)) end mus_reset(gen) # ind = open_sound("oboe.snd") gen = make_snd2sample(ind) gen1 = make_snd2sample(ind) print_and_check(gen, "snd->sample", "snd->sample reading oboe.snd (1 chan) at 0:[no readers]") unless gen.eql?(gen) snd_display("snd2sample not eql? itself?") end if gen.eql?(gen1) snd_display("snd2sample eql? not itself?") end unless snd2sample?(gen) snd_display("%s not snd2sample?", gen) end unless mus_input?(gen) snd_display("%s not input?", gen) end if gen.length != framples(ind) snd_display("snd2sample length: %s?", gen.length) end if gen.file_name != (Dir.pwd + "/oboe.snd") snd_display("snd2sample mus_file_name: %s?", gen.file_name) end v0 = make_vct!(10) do |i| snd2sample(gen, 1490 + i) end if fneq(v0[1], -0.009) or fneq(v0[7], 0.029) snd_display("snd2sample output: %s?", v0) end if mus_channels(gen) != 1 snd_display("snd2sample channels: %s?", mus_channels(gen)) end if mus_location(gen) != 1499 snd_display("snd2sample location: %s?", mus_location(gen)) end v0.map_with_index! do |val, i| ina(1490 + i, gen) end if fneq(v0[1], -0.009) or fneq(v0[7], 0.029) snd_display("snd2sample output ina: %s?", v0) end close_sound(ind) # ind = open_sound("2.snd") gen = make_snd2sample(ind) v0 = make_vct!(10) do |i| snd2sample(gen, 1490 + i, 0) snd2sample(gen, 1490 + i, 1) end print_and_check(gen, "snd->sample", "snd->sample reading 2.snd (2 chans) at 1499:[#, #]") unless snd2sample?(gen) snd_display("%s not snd2sample?", gen) end unless mus_input?(gen) snd_display("%s not input?", gen) end if gen.length != framples(ind) snd_display("snd2sample length: %s?", gen.length) end if gen.file_name != (Dir.pwd + "/2.snd") snd_display("snd2sample mus_file_name: %s?", gen.file_name) end if mus_channels(gen) != 2 snd_display("snd2sample channels (2): %s?", mus_channels(gen)) end if mus_location(gen) != 1499 snd_display("snd2sample location (2): %s?", mus_location(gen)) end close_sound(ind) end def test_08_11 gen = make_file2frample("oboe.snd") print_and_check(gen, "file->frample", "file->frample oboe.snd") unless file2frample?(gen) snd_display("%s not file2frample?", gen) end unless mus_input?(gen) snd_display("%s not input?", gen) end if gen.length != 50828 snd_display("file2frample length: %s?", gen.length) end g1 = make_vct(gen.channels) v0 = make_vct!(10) do |i| file2frample(gen, 1490 + i, g1)[0] end unless file2frample?(gen) snd_display("%s not file2frample?", gen) end if gen.file_name != "oboe.snd" snd_display("file2frample mus_file_name: %s?", gen.file_name) end if fneq(v0[1], -0.009) or fneq(v0[7], 0.029) snd_display("file2frample output: %s?", v0) end # delete_files("fmv.snd", "fmv1.snd", "fmv2.snd", "fmv3.snd") gen = make_sample2file("fmv.snd", 2, Mus_lshort, Mus_riff) print_and_check(gen, "sample->file", "sample->file fmv.snd") unless sample2file?(gen) snd_display("%s not sample2file?", gen) end unless mus_output?(gen) snd_display("%s not output?", gen) end if gen.length != mus_file_buffer_size snd_display("sample2file length: %s?", gen.length) end genx = gen unless gen.eql?(genx) snd_display("sample2file eql? %s %s", genx, gen) end if gen.file_name != "fmv.snd" snd_display("sample2file mus_file_name: %s?", gen.file_name) end 100.times do |i| sample2file(gen, i, 0, i * 0.001) sample2file(gen, i, 1, i * 0.010) end outa(50, 0.015, gen) outb(50, 0.150, gen) out_any(60, 0.015, 0, gen) out_any(60, 0.150, 1, gen) mus_close(gen) gen = make_file2sample("fmv.snd") print_and_check(gen, "file->sample", "file->sample fmv.snd") val0 = in_any(20, 0, gen) val1 = in_any(20, 1, gen) val2 = ina(30, gen) val3 = inb(30, gen) val4 = file2sample(gen, 40, 0) val5 = file2sample(gen, 40, 1) val6 = in_any(50, 0, gen) val7 = in_any(50, 1, gen) val8 = in_any(60, 0, gen) val9 = in_any(60, 1, gen) if mus_channels(gen) != 2 snd_display("sample2file channels: %s?", mus_channels(gen)) end unless mus_input?(gen) snd_display("%s not input?", gen) end if fneq(val0, 0.02) or fneq(val1, 0.2) snd_display("in_any: %s %s?", val0, val1) end if fneq(val2, 0.03) or fneq(val3, 0.3) snd_display("ina|b: %s %s?", val2, val3) end if fneq(val4, 0.04) or fneq(val5, 0.4) snd_display("sample2file: %s %s?", val4, val5) end if fneq(val6, 0.065) or fneq(val7, 0.65) snd_display("outa|b: %s %s?", val6, val7) end if fneq(val8, 0.075) or fneq(val9, 0.75) snd_display("out_any: %s %s?", val8, val9) end # gen = Vct.new(10) let(-0.1) do |x| gen.length.times do |i| outa(i, x += 0.1, gen) end end unless vequal(gen, vct(0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9)) snd_display("outa->vct ramp: %s?", gen) end let(-0.1) do |x| gen.length.times do |i| outa(i, x += 0.1, gen) end end unless vequal(gen, vct(0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9).scale!(2.0)) snd_display("outa->vct ramp 2: %s?", gen) end if (res = mus_channels(gen)) != 1 snd_display("mus_channels vct: %s?", res) end # gen = make_oscil(440.0) res = Snd.catch do outa(0, 0.1, gen) end if res.first != :wrong_type_arg and res.first != :mus_error snd_display("outa -> oscil: %s", res.inspect) end # gen = make_sample2file("fmv.snd", 4, Mus_lshort, Mus_riff) print_and_check(gen, "sample->file", "sample->file fmv.snd") 10.times do |i| outa(i, 0.1, gen) outb(i, 0.2, gen) outc(i, 0.3, gen) outd(i, 0.4, gen) end 10.times do |i| outa(i, 0.01, gen) outb(i, 0.02, gen) outc(i, 0.03, gen) outd(i, 0.04, gen) end mus_close(gen) gen = make_file2sample("fmv.snd") print_and_check(gen, "file->sample", "file->sample fmv.snd") 10.times do |i| if fneq(res1 = ina(i, gen), 0.11) or fneq(res2 = inb(i, gen), 0.22) or fneq(res3 = in_any(i, 2, gen), 0.33) or fneq(res4 = in_any(i, 3, gen), 0.44) snd_display("4-chan out/in[%s]: %s %s %s %s?", i, res1, res2, res3, res4) end end if (res = Snd.catch do make_sample2file("fmv.snd", -1, Mus_lshort, Mus_next) end).first != :out_of_range snd_display("make_sample2file bad chans: %s", res.inspect) end if (res = Snd.catch do mus_location(make_oscil) end).first != :mus_error snd_display("set_mus_location(make_oscil): %s", res.inspect) end if (res = Snd.catch do make_sample2file("fmv.snd", 1, -1, Mus_next) end).first != :out_of_range snd_display("make_sample2file bad format: %s", res.inspect) end if (res = Snd.catch do make_sample2file("fmv.snd", 1, Mus_lshort, -1) end).first != :out_of_range snd_display("make_sample2file bad type: %s", res.inspect) end # gen = make_frample2file("fmv1.snd", 2, Mus_bshort, Mus_next) print_and_check(gen, "frample->file", "frample->file fmv1.snd") unless frample2file?(gen) snd_display("%s not frample2file?", gen) end unless mus_output?(gen) snd_display("%s not output?", gen) end if gen.length != mus_file_buffer_size snd_display("frample2file length: %s?", gen.length) end if gen.file_name != "fmv1.snd" snd_display("frample2file mus_file_name: %s?", gen.file_name) end gen.length = 4096 if gen.length != 4096 snd_display("frample2file length: %s?", gen.length) end gen.length = 8192 fr0 = make_vct(2, 0.0) 100.times do |i| vct_set!(fr0, 0, i * 0.001) vct_set!(fr0, 1, i * 0.010) frample2file(gen, i, fr0) end mus_close(gen) gen = make_file2frample("fmv1.snd", 1024) fr0 = make_vct(gen.channels) val4 = file2frample(gen, 40, fr0) frout = make_vct(2) if fneq(vct_ref(val4, 0), 0.04) or fneq(vct_ref(val4, 1), 0.4) snd_display("frample2file output: %s?", val4) end file2frample(gen, 40, frout) unless frout.eql?(val4) snd_display("frample2file output via frame: %s %s?", frout, val4) end # gen = make_sample2file("fmv2.snd", 4, Mus_bshort, Mus_aifc) print_and_check(gen, "sample->file", "sample->file fmv2.snd") unless sample2file?(gen) snd_display("%s not sample2file?", gen) end unless mus_output?(gen) snd_display("%s not output?", gen) end 100.times do |i| sample2file(gen, i, 0, i * 0.001) sample2file(gen, i, 1, i * 0.010) sample2file(gen, i, 2, i * 0.002) sample2file(gen, i, 3, i * 0.003) end outa(50, 0.015, gen) outb(50, 0.150, gen) outc(50, 0.020, gen) outd(50, 0.030, gen) out_any(60, 0.015, 0, gen) out_any(60, 0.150, 1, gen) out_any(60, 0.020, 2, gen) out_any(60, 0.030, 3, gen) mus_close(gen) gen = make_file2sample("fmv2.snd") val0 = in_any(20, 2, gen) val1 = in_any(20, 3, gen) val2 = file2sample(gen, 50, 2) val3 = file2sample(gen, 50, 3) val4 = file2sample(gen, 60, 2) val5 = file2sample(gen, 60, 3) if mus_channels(gen) != 4 snd_display("file2sample channels (4): %s?", mus_channels(gen)) end if fneq(mus_increment(gen), 0.0) snd_display("file2sample increment: %s?", mus_increment(gen)) end if fneq(val0, 0.04) or fneq(val1, 0.06) snd_display("in_any(0, 4): %s %s?", val0, val1) end if fneq(val2, 0.12) or fneq(val3, 0.18) snd_display("file2sample(4): %s %s?", val2, val3) end if fneq(val4, 0.14) or fneq(val5, 0.21) snd_display("in_any(4, 4): %s %s?", val4, val5) end # delete_file("fmv.snd") mus_sound_forget("fmv.snd") sf = make_sample2file("fmv.snd", 2, Mus_bshort, Mus_next, "this is a comment") 10.times do |i| sample2file(sf, i, 0, i * 0.10) sample2file(sf, i, 1, i * 0.01) end mus_close(sf) if (res = mus_sound_chans("fmv.snd")) != 2 snd_display("sample2file chans: %s?", res) end if (res = mus_sound_framples("fmv.snd")) != 10 snd_display("sample2file framples: %s?", res) end if (res = mus_sound_samples("fmv.snd")) != 20 snd_display("sample2file samples: %s?", res) end if (res = mus_sound_header_type("fmv.snd")) != Mus_next snd_display("sample2file type: %s?", res) end if (res = mus_sound_sample_type("fmv.snd")) != Mus_bshort snd_display("sample2file format: %s?", res) end if (res = mus_sound_comment("fmv.snd")) != "this is a comment" snd_display("sample2file comment: %s?", res) end rd = make_file2sample("fmv.snd") 10.times do |i| if fneq(c0 = file2sample(rd, i, 0), i * 0.10) or fneq(c1 = file2sample(rd, i, 1), i * 0.01) snd_display("sample2file2sample at %s: %s %s?", i, c0, c1) break end end mus_close(rd) sf = continue_sample2file("fmv.snd") 10.times do |i| sample2file(sf, i + 5, 0, i * -0.02) sample2file(sf, i + 5, 1, i * -0.01) end mus_close(sf) mus_sound_forget("fmv.snd") if (res = mus_sound_chans("fmv.snd")) != 2 snd_display("continue_sample2file chans: %s?", res) end if (res = mus_sound_framples("fmv.snd")) != 15 snd_display("continue_sample2file framples: %s?", res) end if (res = mus_sound_samples("fmv.snd")) != 30 snd_display("continue_sample2file samples: %s?", res) end if (res = mus_sound_header_type("fmv.snd")) != Mus_next snd_display("continue_sample2file type: %s?", res) end if (res = mus_sound_sample_type("fmv.snd")) != Mus_bshort snd_display("continue_sample2file format: %s?", res) end if (res = mus_sound_comment("fmv.snd")) != "this is a comment" snd_display("continue_sample2file comment: %s?", res) end ind = open_sound("fmv.snd") unless vequal(c0 = channel2vct(0, 15, ind, 0), vct(0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.58, 0.66, 0.74, 0.82, -0.1, -0.12, -0.14, -0.16, -0.18)) snd_display("continue_sample2file (0): %s", c0) end unless vequal(c0 = channel2vct(0, 15, ind, 1), vct(0.0, 0.01, 0.02, 0.03, 0.04, 0.05, 0.05, 0.05, 0.05, 0.05, -0.05, -0.06, -0.07, -0.08, -0.09)) snd_display("continue_sample2file (1): %s", c0) end close_sound(ind) # delete_file("fmv.snd") mus_sound_forget("fmv.snd") msg = "this is a comment" sf = make_frample2file("fmv.snd", 2, Mus_lfloat, Mus_riff, msg) 10.times do |i| frample2file(sf, i, vct(i * 0.10, i * 0.01)) end mus_close(sf) if (res = mus_sound_chans("fmv.snd")) != 2 snd_display("frample2file chans: %s?", res) end if (res = mus_sound_framples("fmv.snd")) != 10 snd_display("frample2file framples: %s?", res) end if (res = mus_sound_samples("fmv.snd")) != 20 snd_display("frample2file samples: %s?", res) end if (res = mus_sound_header_type("fmv.snd")) != Mus_riff snd_display("frample2file type: %s?", res) end if (res = mus_sound_sample_type("fmv.snd")) != Mus_lfloat snd_display("frample2file format: %s?", res) end if (res = mus_sound_comment("fmv.snd")) != msg snd_display("frample2file comment: %s?", res) end rd = make_file2frample("fmv.snd") f0 = vct(0, 0) rd.length.times do |i| file2frample(rd, i, f0) snd_test_neq(f0.length, 2, "frample2file2frample at %d: f0.len %s", i, f0) snd_test_neq(f0[0], i * 0.10, "frample2file2frample at %d: f0[0] %s", i, f0) snd_test_neq(f0[1], i * 0.01, "frample2file2frample at %d: f0[1] %s", i, f0) end mus_close(rd) sf = continue_frample2file("fmv.snd") 10.times do |i| frample2file(sf, i + 5, vct(i * -0.02, i * -0.01)) end mus_close(sf) mus_sound_forget("fmv.snd") if (res = mus_sound_chans("fmv.snd")) != 2 snd_display("continue_frample2file chans: %s?", res) end if (res = mus_sound_framples("fmv.snd")) != 15 snd_display("continue_frample2file framples: %s?", res) end if (res = mus_sound_samples("fmv.snd")) != 30 snd_display("continue_frample2file samples: %s?", res) end if (res = mus_sound_header_type("fmv.snd")) != Mus_riff snd_display("continue_frample2file type: %s?", res) end if (res = mus_sound_sample_type("fmv.snd")) != Mus_lfloat snd_display("continue_frample2file format: %s?", res) end if (res = mus_sound_comment("fmv.snd")) != "this is a comment" snd_display("continue_frample2file comment: %s?", res) end ind = open_sound("fmv.snd") c0 = channel2vct(0, 15, ind, 0) c1 = channel2vct(0, 15, ind, 1) v0 = vct(0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.58, 0.66, 0.74, 0.82, -0.1, -0.12, -0.14, -0.16, -0.18) v1 = vct(0.0, 0.01, 0.02, 0.03, 0.04, 0.05, 0.05, 0.05, 0.05, 0.05, -0.05, -0.06, -0.07, -0.08, -0.09) snd_test_neq(c0, v0, "continue_frample2file (0)") snd_test_neq(c1, v1, "continue_frample2file (1)") close_sound(ind) delete_file("fmv.snd") mus_sound_forget("fmv.snd") # os = make_oscil(440.0) v0 = make_vct!(1000) do 0.1 * oscil(os) end array2file("fmv3.snd", v0, 10000, 22050, 1) # 10000 deliberate v1 = make_vct(1000) file2array("fmv3.snd", 0, 0, 1000, v1) vct2vector(v0).zip(vct2vector(v1)) do |val1, val2| if fneq(val1, val2) snd_display("array2file2array: %s %s?", val1, val2) end end # if (res = Snd.catch do array2file("fmv3.snd", v0, -1, 1000, 1) end).first != :out_of_range snd_display("array2file bad samps: %s", res.inspect) end if (res = Snd.catch do array2file("/bad/baddy/fmv3.snd", v0, 1, 1000, 1) end).first != :mus_error snd_display("array2file bad file: %s", res.inspect) end if (res = Snd.catch do file2array("fmv3.snd", -1, 0, -1, v0) end).first != :out_of_range snd_display("file2array bad samps: %s", res.inspect) end end def test_08_12 gen = make_rand(10000.0) print_and_check(gen, "rand", "rand freq: 10000.000Hz, phase: 0.000, amp: 1.000") v0 = make_vct!(10) do rand(gen, 0.0) end unless rand?(gen) snd_display("%s not rand?", gen) end if fneq(gen.phase, 3.3624296) snd_display("rand phase: %s?", gen.phase) end if fneq(gen.frequency, 10000.0) snd_display("rand frequency %s?", gen.frequency) end gen.scaler = 0.5 if fneq(gen.scaler, 0.5) snd_display("rand set_scaler: %s?", gen.scaler) end if v0[1] == v0[8] snd_display("rand output: %s", v0) end # gen = make_rand(10000.0, :envelope, [0, 0, 1, 1]) print_and_check(gen, "rand", "rand freq: 10000.000Hz, phase: 0.000, amp: 1.000, with distribution envelope") v0 = make_vct!(10) do rand(gen, 0.0) end unless rand?(gen) snd_display("(dist) %s not rand?", gen) end if fneq(gen.frequency, 10000.0) snd_display("(dist) rand frequency %s?", gen.frequency) end if v0[1] == v0[8] snd_display("(dist) rand output: %s", v0) end if (not vct?(gen.data)) or gen.length != gen.data.length or gen.length != 512 snd_display("(dist) rand data: %s %s?", gen.length, gen.data) end # gen1 = make_rand(10000.0, :envelope, [0, 0, 1, 1]) gen2 = make_rand(10000.0, :envelope, [0, 1, 1, 0]) up1 = 0 down1 = 0 bad1 = 0 up2 = 0 down2 = 0 bad2 = 0 1000.times do |i| val1 = rand(gen1) val2 = rand(gen2) if val1 >= 0.5 up1 += 1 else if val1 >= 0.0 down1 += 1 else bad1 += 1 end end if val2 >= 0.5 up2 += 1 else if val2 >= 0.0 down2 += 1 else bad2 += 1 end end end snd_test_neq(bad1, 0, "rand dist: down/up 1 %d/%d", down1, up1) snd_test_neq(bad2, 0, "rand dist: down/up 2 %d/%d", down2, up2) snd_test_gt(2.5 * down1, up1, "rand dist: down/up/bad 1 %d/%d/%d", down1, up1, bad1) snd_test_gt(2.5 * up2, down2, "rand dist: down/up/bad 2 %d/%d/%d", down2, up2, bad2) # gen = make_rand_interp(4000.0) print_and_check(gen, "rand-interp", gen.to_s) v0 = make_vct!(10) do rand_interp(gen, 0.0) end unless rand_interp?(gen) snd_display("%s not rand_interp?", gen) end if fneq(gen.phase, 5.114882) snd_display("rand_interp phase: %s?", gen.phase) end if fneq(gen.frequency, 4000.0) snd_display("rand_interp frequency %s?", gen.frequency) end gen.scaler = 0.5 if fneq(gen.scaler, 0.5) snd_display("rand_interp set_scaler: %s?", gen.scaler) end if v0[1] == v0[8] snd_display("rand_interp output: %s", v0) end # gen = make_rand_interp(4000.0, :envelope, [-1, 1, 0, 0, 1, 1]) print_and_check(gen, "rand-interp", gen.to_s) v0 = make_vct!(10) do rand_interp(gen, 0.0) end unless rand_interp?(gen) snd_display("(dist) %s not rand_interp?", gen) end if v0[1] == v0[8] snd_display("(dist) rand_interp output: %s", v0) end if (not vct?(gen.data)) or gen.length != gen.data.length or gen.length != 512 snd_display("(dist) rand_interp data: %s %s?", gen.length, gen.data) end # gen = make_rand(10000.0, 1.0) gen1 = make_rand_interp(10000.0, 1.0) 1000.times do val1 = gen.run(0.0) val2 = gen1.run(0.0) if val1 > 1.0 or val1 < -1.0 snd_display(",rand: %s %s?", val1, gen) end if val2 > 1.0 or val2 < -1.0 snd_display(",rand_interp: %s %s?", val2, gen1) end end gen = make_rand(10000.0, :distribution, inverse_integrate([0, 0, 1, 1])) print_and_check(gen, "rand", "rand freq: 10000.000Hz, phase: 0.000, amp: 1.000, with distribution envelope") v0.map! do rand(gen, 0.0) end unless rand?(gen) snd_display("(dist 2) %s not rand?", gen) end if fneq(gen.frequency, 10000.0) snd_display("(dist 2) rand frequency %s?", gen.frequency) end if v0[1] == v0[8] snd_display("(dist 2) rand output: %s", v0) end if (not vct?(gen.data)) or gen.length != gen.data.length or gen.length != 512 snd_display("(dist 2) rand data: %s %s?", gen.length, gen.data) end # gen1 = make_rand(10000.0, :distribution, inverse_integrate([0, 0, 1, 1])) gen2 = make_rand(10000.0, :distribution, inverse_integrate([0, 1, 1, 0])) up1 = 0 down1 = 0 bad1 = 0 up2 = 0 down2 = 0 bad2 = 0 1000.times do |i| val1 = rand(gen1) val2 = rand(gen2) if val1 >= 0.5 up1 += 1 else if val1 >= 0.0 down1 += 1 else bad1 += 1 end end if val2 >= 0.5 up2 += 1 else if val2 >= 0.0 down2 += 1 else bad2 += 1 end end end if bad1.nonzero? or bad2.nonzero? or 2.5 * down1 > up1 or 2.0 * up2 > down2 snd_display("rand dist 2: %s %s %s, %s %s %s", down1, up1, bad1, down2, up2, bad2) end # v1 = inverse_integrate([-1, 1, 1, 1]) if fneq(v1[4], -0.984) snd_display("inverse_integrate -1 to 1 uniform: %s?", v1) end v1 = inverse_integrate([0, 1, 1, 1]) if fneq(v1[4], 0.008) snd_display("inverse_integrate 0 to 1 uniform: %s?", v1) end v1 = inverse_integrate([0, 1, 1, 0]) if fneq(v1[4], 0.004) snd_display("inverse_integrate 0 to 1 1 to 0: %s?", v1) end v1 = inverse_integrate([0, 0, 0.5, 1, 1, 0]) if fneq(v1[4], 0.073) snd_display("inverse_integrate triangle: %s?", v1) end v1 = inverse_integrate(gaussian_envelope(1.0)) if fneq(v1[4], -0.593) snd_display("inverse_integrate gaussian: %s?", v1) end end def test_08_13 minp = 1.0 maxp = -1.0 1100.times do val1 = mus_random(1.0) if val1 < minp minp = val1 end if val1 > maxp maxp = val1 end if val1 > 1.0 or val1 < -1.0 snd_display("mus_random: %s?", val1) end end if maxp < 0.9 or minp > -0.9 snd_display("mus_random: %s %s", minp, maxp) end minp = 12.0 maxp = -12.0 1100.times do val1 = mus_random(12.0) if val1 < minp minp = val1 end if val1 > maxp maxp = val1 end if val1 > 12.0 or val1 < -12.0 snd_display("mus_random (12): %s?", val1) end end if maxp < 11.0 or minp > -11.0 snd_display("mus_random (12): %s %s", minp, maxp) end res = lambda do |n| hits = make_array(10, 0) n.times do |i| hits[(5 + mus_random(5.0)).floor] += 1 end sum = 0.0 pp = n / 10.0 hits.each do |val| sum = sum + (((val - pp) * (val - pp)) / pp) end sum end.call(10000) if res < 3.0 snd_display("mus_random not so random (chi)? %s", res) end res = lambda do |n| hits = make_array(10, 0) gen = make_rand(22050.0, 5) n.times do |i| hits[(5 + rand(gen, 0.0)).floor] += 1 end sum = 0.0 pp = n / 10.0 hits.each do |val| sum = sum + (((val - pp) * (val - pp)) / pp) end sum end.call(10000) if res < 3.5 snd_display("rand not so random (chi)? %s", res) end # data = make_vct!(65536) do mus_random(1.0) end ndat = snd_spectrum(data, Rectangular_window, 65536, true, 0.0, false, false) peak = vct_peak(ndat) sum = 0.0 if peak > 1000.0 snd_display("mus_random spectral peak: %s?", peak) end 32768.times do |i| sum += ndat[i] end if (res = sum / 32768.0) > 200.0 snd_display("random average: %s %s?", res, ndat[0]) end data.map! do mus_random(1.0) end autocorrelate(data) data[0] = 0.0 pk = vct_peak(data) if pk > 1000 snd_display("random autocorrelate peak: %s?", pk) end sum = 0.0 32768.times do |i| sum += ndat[i].abs end if (res = sum / 32768.0) > 200.0 snd_display("random autocorrelate average: %s?", res) end end def test_08_14 set_locsig_type(Mus_interp_linear) gen = make_locsig(30.0, :channels, 2) gen1 = make_locsig(60.0, :channels, 2) gen2 = make_locsig(60.0, :channels, 4) gen200 = make_locsig(200.0, :channels, 4) gen3 = gen1 locsig(gen, 0, 1.0) print_and_check(gen, "locsig", "locsig chans 2, outn: [0.667 0.333], interp: linear") unless locsig?(gen) snd_display("%s not locsig?", gen) end unless gen1.eql?(gen3) snd_display("locsig %s.eql?(%s)?", gen1, gen3) end unless gen1 == gen3 snd_display("locsig %s == %s?", gen1, gen3) end if gen1.eql?(gen2) snd_display("locsig 1 %s.eql?(%s)?", gen1, gen2) end if gen == gen1 snd_display("locsig 2 %s == %s?", gen, gen1) end if gen == gen2 snd_display("locsig 3 %s == %s?", gen, gen2) end if fneq(res1 = locsig_ref(gen, 0), 0.667) or fneq(res2 = locsig_ref(gen, 1), 0.333) snd_display("locsig ref: %s %s?", res1, res2) end unless vequal(mus_data(gen), vct(0.667, 0.333)) snd_display("locsig gen outn: %s?", mus_data(gen)) end unless vequal(mus_data(gen1), vct(0.333, 0.667)) snd_display("locsig gen1 outn: %s?", mus_data(gen1)) end unless vequal(mus_data(gen2), vct(0.333, 0.667, 0.000, 0.000)) snd_display("locsig gen2 outn: %s?", mus_data(gen2)) end unless vequal(mus_data(gen200), vct(0.000, 0.000, 0.778, 0.222)) snd_display("locsig gen200 outn: %s?", mus_data(gen200)) end locsig_set!(gen, 0, 0.25) unless vequal(mus_data(gen), vct(0.250, 0.333)) snd_display("locsig gen 0.25 outn: %s?", mus_data(gen)) end locsig(gen, 0, 1.0) locsig_set!(gen, 0, 0.5) unless vequal(mus_data(gen), vct(0.500, 0.333)) snd_display("locsig gen 0.5 outn: %s?", mus_data(gen)) end locsig(gen, 0, 1.0) gen = make_locsig(300.0, 2.0, 0.1, :channels, 4) unless vequal(mus_data(gen), vct(0.167, 0.000, 0.000, 0.333)) snd_display("locsig gen 300 outn: %s?", mus_data(gen)) end locsig(gen, 0, 1.0) move_locsig(gen1, 90.0, 1.0) unless vequal(mus_data(gen1), vct(0.000, 1.000)) snd_display("locsig gen1 90 outn: %s?", mus_data(gen1)) end move_locsig(gen1, 0.0, 1.0) unless vequal(mus_data(gen1), vct(1.000, 0.000)) snd_display("locsig gen1 0 outn: %s?", mus_data(gen1)) end move_locsig(gen1, 45.0, 1.0) unless vequal(mus_data(gen1), vct(0.500, 0.500)) snd_display("locsig gen1 45 outn: %s?", mus_data(gen1)) end move_locsig(gen1, 135.0, 2.0) unless vequal(mus_data(gen1), vct(0.000, 0.500)) snd_display("locsig gen1 135 outn: %s?", mus_data(gen1)) end move_locsig(gen1, -270.0, 3.0) unless vequal(mus_data(gen1), vct(0.333, 0.000)) snd_display("locsig gen1 -270 outn: %s?", mus_data(gen1)) end [1, 2, 4, 8].each do |chans| m1 = make_locsig(:channels, chans) if m1.channels != chans or m1.length != chans snd_display("locsig %s chans but: %s %s?", chans, m1.channels, m1.length) end chans.times do |i| locsig_set!(m1, i, i * 0.1) end chans.times do |i| if fneq(locsig_ref(m1, i), i * 0.1) snd_display("locsig[%s] = %s (%s)?", i, locsig_ref(m1, i), i * 0.1) end end end # if (res = Snd.catch do make_locsig(:channels, 0) end).first != :mus_error snd_display("make_locsig bad (0) chans: %s", res.inspect) end if (res = Snd.catch do make_locsig(:channels, -2) end).first != :out_of_range snd_display("make_locsig bad (-2) chans: %s", res.inspect) end if (res = Snd.catch do make_locsig(:output, 1) end).first != :wrong_type_arg snd_display("make_locsig bad output: %s", res.inspect) end res = Snd.catch do locsig_ref(make_locsig, 1) end if res != [0.0] and res.car != :mus_error snd_display("locsig_ref bad chan (0): %s", res.inspect) end res = Snd.catch do locs = make_locsig(200, :channels, 2) locsig_ref(locs, -1) end if res != [0.0] and res.car != :mus_error snd_display("locsig_ref bad chan (1): %s", res.inspect) end res = Snd.catch do locs = make_locsig locsig_set!(locs, 2, 0.1) end if res != [0.1] and res.car != :mus_error snd_display("locsig_set! bad chan (2): %s", res.inspect) end res = Snd.catch do locs = make_locsig(:reverb, 0.1) locsig_reverb_ref(locs, 2) end if res != [0.0] and res.car != :mus_error snd_display("locsig_reverb_ref bad reverb chan (2): %s", res.inspect) end res = Snd.catch do locs = make_locsig(:reverb, 0.1) locsig_reverb_set!(locs, 2, 0.1) end if res != [0.1] and res.car != :mus_error snd_display("locsig_reverb_set! bad reverb chan (2): %s", res.inspect) end # locs = make_locsig(:channels, 8, :degree, 0) move_locsig(locs, 180.0, 1.0) if fneq(locsig_ref(locs, 0), 0.0) snd_display("move_locsig by jump: %s?", locs.data) end unless vequal(locs.data, vct(0.000, 0.000, 0.000, 0.000, 1.000, 0.000, 0.000, 0.000)) snd_display("move_locsig by jump data: %s?", locs.data) end move_locsig(locs, 120.0, 1.0) unless vequal(locs.data, vct(0.000, 0.000, 0.333, 0.667, 0.000, 0.000, 0.000, 0.000)) snd_display("move_locsig by jump 120 data: %s?", locs.data) end move_locsig(locs, -20.0, 1.0) unless vequal(locs.data, vct(0.556, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.444)) snd_display("move_locsig by jump -20 data: %s?", locs.data) end # sf = make_sample2file("fmv4.snd", 8, Mus_bshort, Mus_next, "this is a comment") sfrev = make_sample2file("fmv4.reverb", 8, Mus_bshort, Mus_next, "this is a comment") locs = make_locsig(:channels, 8, :degree, 0, :distance, 1.0, :reverb, 0.1, :output, sf, :revout, sfrev, :type, Mus_interp_linear) unless vequal(locs.data, vct(1.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000)) snd_display("ws not move_locsig by jump data: %s?", locs.data) end unless vequal(locs.xcoeffs, vct(0.100, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000)) snd_display("ws not move_locsig by jump rev data: %s?", locs.xcoeffs) end move_locsig(locs, 180.0, 2.0) if fneq(locsig_ref(locs, 0), 0.0) snd_display("ws move_locsig by jump: %s?", locs.data) end unless vequal(locs.data, vct(0.000, 0.000, 0.000, 0.000, 0.500, 0.000, 0.000, 0.000)) snd_display("ws move_locsig by jump data: %s?", locs.data) end unless vequal(locs.xcoeffs, vct(0.000, 0.000, 0.000, 0.000, 0.071, 0.000, 0.000, 0.000)) snd_display("ws move_locsig by jump rev data: %s?", locs.xcoeffs) end move_locsig(locs, 120.0, 3.0) unless vequal(locs.data, vct(0.000, 0.000, 0.111, 0.222, 0.000, 0.000, 0.000, 0.000)) snd_display("ws move_locsig by jump 120 data: %s?", locs.data) end unless vequal(locs.xcoeffs, vct(0.000, 0.000, 0.019, 0.038, 0.000, 0.000, 0.000, 0.000)) snd_display("ws move_locsig by jump 120 rev data: %s?", locs.xcoeffs) end move_locsig(locs, -20.0, 4.0) unless vequal(locs.data, vct(0.139, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.111)) snd_display("ws move_locsig by jump -20 data: %s?", locs.data) end unless vequal(locs.xcoeffs, vct(0.028, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.022)) snd_display("ws move_locsig by jump -20 rev data: %s?", locs.xcoeffs) end mus_close(sf) mus_close(sfrev) delete_files("fmv4.snd", "fmv4.reverb") mus_sound_prune # [Mus_caff, Mus_aifc, Mus_next, Mus_riff, Mus_rf64].each do |ht| ind = find_sound(with_sound(:channels, 8) do 8.times do |i| locsig(make_locsig(:degree, i * 45, :output, $output), i, 0.5) end end.output) 8.times do |chn| samps = channel2vct(0, 8, ind, chn) 8.times do |k| if k == chn and fneq(samps[k], 0.5) snd_display("8 out %s chan %s samp %s (0.5): %s?", mus_header_type2string(ht), chn, k, samps[k]) end if k != chn and fneq(samps[k], 0.0) snd_display("8 out %s chan %s samp %s (0.0): %s?", mus_header_type2string(ht), chn, k, samps[k]) end end end close_sound(ind) end # gen = make_frample2file("fmv4.snd", 2, Mus_bshort, Mus_next) rev = make_frample2file("fmv4.reverb", 1, Mus_bshort, Mus_next) lc = make_locsig(60.0, :reverb, 0.1, :channels, 2, :output, gen, :revout, rev) 100.times do |i| locsig(lc, i, 1.0) end if fneq(res = locsig_reverb_ref(lc, 0), 0.1) snd_display("locsig_reverb_ref: %s?", res) end locsig_reverb_set!(lc, 0, 0.3) if fneq(res = locsig_reverb_ref(lc, 0), 0.3) snd_display("locsig_reverb_set!: %s?", res) end locsig_reverb_set!(lc, 0, 0.2) if fneq(res = locsig_reverb_ref(lc, 0), 0.2) snd_display("locsig_reverb_set!: %s?", res) end mus_close(gen) mus_close(rev) v0 = make_vct(100) v1 = make_vct(100) v2 = make_vct(100) file2array("fmv4.snd", 0, 0, 100, v0) file2array("fmv4.snd", 1, 0, 100, v1) file2array("fmv4.reverb", 0, 0, 100, v2) if fneq(v2[0], 0.1) snd_display("locsig reverb: %s?", v2) end if fneq(2 * v0[0], v1[0]) snd_display("locsig direct: %s %s?", v0[0], v1[0]) end # gen = make_frample2file("fmv4.snd", 4, Mus_bshort, Mus_next) rev = make_frample2file("fmv4.reverb", 4, Mus_bshort, Mus_next) lc = make_locsig(60.0, :reverb, 0.1, :channels, 4, :distance, 4.0, :output, gen, :revout, rev) print_and_check(lc, "locsig", "locsig chans 4, outn: [0.083 0.167 0.000 0.000], revn: [0.017 0.033 0.000 0.000], interp: linear") 100.times do |i| locsig(lc, i, 1.0) end 4.times do |i| locsig_reverb_set!(lc, i, i * 0.1) if fneq(res = locsig_reverb_ref(lc, i), i * 0.1) snd_display("locsig_reverb_set![%s]: %s?", i, res) end end print_and_check(lc, "locsig", "locsig chans 4, outn: [0.083 0.167 0.000 0.000], revn: [0.000 0.100 0.200 0.300], interp: linear") unless vct?(lc.data) snd_display("out data locsig: %s?", lc.data) end unless vct?(lc.xcoeffs) snd_display("rev data locsig: %s?", lc.xcoeffs) end xcs = lc.xcoeffs if fneq(res = mus_xcoeff(lc, 0), xcs[0]) snd_display("locsig xcoeff: %s %s?", res, xcs[0]) end if fneq(res = mus_xcoeff(lc, 1), 0.1) snd_display("locsig xcoeff 1: %s %s?", res, xcs[0]) end mus_close(gen) mus_close(rev) # print_and_check(make_locsig(160, :channels, 4), "locsig", "locsig chans 4, outn: [0.000 0.222 0.778 0.000], interp: linear") print_and_check(make_locsig(-200, :channels, 4), "locsig", "locsig chans 4, outn: [0.000 0.222 0.778 0.000], interp: linear") print_and_check(make_locsig(160, :channels, 4, :distance, 0.5), "locsig", "locsig chans 4, outn: [0.000 0.222 0.778 0.000], interp: linear") print_and_check(make_locsig(320, :channels, 4), "locsig", "locsig chans 4, outn: [0.556 0.000 0.000 0.444], interp: linear") print_and_check(make_locsig(-40, :channels, 4), "locsig", "locsig chans 4, outn: [0.556 0.000 0.000 0.444], interp: linear") print_and_check(make_locsig(320, :channels, 2), "locsig", "locsig chans 2, outn: [0.000 1.000], interp: linear") print_and_check(make_locsig(-40, :channels, 2), "locsig", "locsig chans 2, outn: [1.000 0.000], interp: linear") print_and_check(make_locsig(0, :channels, 1, :output, Vct.new(10)), "locsig", "locsig chans 1, outn: [1.000], interp: linear") # locsig_data = lambda do |g| make_vct!(g.channels) do |i| locsig_ref(g, i) end end gen = make_locsig(-0.1, :channels, 8) unless vequal(locsig_data.call(gen), vct(0.998, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.002)) snd_display("locsig -0.1(8): %s?", locsig_data.call(gen)) end gen = make_locsig(-359.9, :channels, 8) unless vequal(locsig_data.call(gen), vct(0.998, 0.002, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000)) snd_display("locsig -359.9(8): %s?", locsig_data.call(gen)) end gen = make_locsig(-359.9, :channels, 4) unless vequal(locsig_data.call(gen), vct(0.999, 0.001, 0.000, 0.000)) snd_display("locsig -359.9(4): %s?", locsig_data.call(gen)) end gen = make_locsig(-360.1, :channels, 8) unless vequal(locsig_data.call(gen), vct(0.998, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.002)) snd_display("locsig -360.1(8): %s?", locsig_data.call(gen)) end gen = make_locsig(-700, :channels, 8) unless vequal(locsig_data.call(gen), vct(0.556, 0.444, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000)) snd_display("locsig -700(8): %s?", locsig_data.call(gen)) end gen = make_locsig(-700, :channels, 2) unless vequal(locsig_data.call(gen), vct(1.000, 0.000)) snd_display("locsig -700(2): %s?", locsig_data.call(gen)) end gen = make_locsig(20, :channels, 2) unless vequal(locsig_data.call(gen), vct(0.778, 0.222)) snd_display("locsig 20(2): %s?", locsig_data.call(gen)) end gen = make_locsig(123456.0, :channels, 8) unless vequal(locsig_data.call(gen), vct(0.467, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.533)) snd_display("locsig 123456(8): %s?", locsig_data.call(gen)) end gen = make_locsig(336.0, :channels, 8) unless vequal(locsig_data.call(gen), vct(0.467, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.533)) snd_display("locsig 336(8): %s?", locsig_data.call(gen)) end gen = make_locsig(-123456.0, :channels, 8) unless vequal(locsig_data.call(gen), vct(0.467, 0.533, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000)) snd_display("locsig -123456(8): %s?", locsig_data.call(gen)) end gen = make_locsig(24.0, :channels, 8) unless vequal(locsig_data.call(gen), vct(0.467, 0.533, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000)) snd_display("locsig 24(8): %s?", locsig_data.call(gen)) end # locsig_scalers = lambda do |chans, degree, type| if chans == 1 vct(1.0) else deg = chans == 2 ? [0.0, [90.0, degree].min].max : degree.divmod(360.0)[1] degs_per_chan = chans == 2 ? 90.0 : (360.0 / chans) pos = deg / degs_per_chan left = pos.floor right = (left + 1) % chans frac = pos - left v = make_vct(chans) if type == Mus_interp_linear v[left] = 1.0 - frac v[right] = frac else ldeg = HALF_PI * (0.5 - frac) norm = sqrt(2.0) * 0.5 c = cos(ldeg) s = sin(ldeg) v[left] = norm * (c + s) v[right] = norm * (c - s) end v end end [0, 1, 2, 4].each do |rev_chans| delete_file("test.reverb") revfile = if rev_chans > 0 make_frample2file("test.reverb", rev_chans, Mus_bshort, Mus_next) else false end [Mus_interp_linear, Mus_interp_sinusoidal].each do |type| set_locsig_type(type) if locsig_type != type snd_display("locsig_type: %s %s?", type, locsig_type) end [0.0, 45.0, 90.0, 1234.0].each do |deg| gen = make_locsig(deg, :channels, 1, :revout, revfile, :reverb, 0.1, :distance, 2.0) revs = revfile ? locsig_scalers.call(rev_chans, deg, type) : [] if gen.channels != 1 snd_display("locsig %s: %s?", deg, gen) end if fneq(locsig_ref(gen, 0), 0.5) snd_display("locsig scaler[%s] %s: %s?", type, deg, locsig_ref(gen, 0)) end revs.each_with_index do |val, i| if fneq(res1 = locsig_reverb_ref(gen, i), res2 = ((0.1 / sqrt(2.0)) * val)) snd_display("mono locrev[%s] %s at %s: %s %s?", type, gen, deg, res1, res2) break end end end [Mus_interp_linear, Mus_interp_sinusoidal].each do |ltype| [0.0, 45.0, 90.0, 1234.0].each do |deg| gen = make_locsig(deg, :channels, 1, :type, ltype) if gen.channels != 1 snd_display("locsig %s: %s?", deg, gen) end if fneq(res = locsig_ref(gen, 0), 1.0) snd_display("locsig[%s] scaler %s: %s?", ltype, deg, res) end end end [2, 3, 4, 5, 8, 12, 16, 24].each do |chans| [0.0, 45.0, 90.0, 120.0, 180.0, 275.0, 315.0, 300.0, 15.0, 1234.0].each do |deg| gen = make_locsig(deg, :channels, chans, :revout, revfile, :reverb, 0.1) if gen.channels != chans snd_display("multi locsig %s: %s?", deg, gen) break end locsig_scalers.call(chans, deg, type).each_with_index do |val, i| if fneq(res = locsig_ref(gen, i), val) snd_display("locrev[%s] %s at %s: %s %s?", type, gen, deg, res, val) break end end (revfile ? locsig_scalers.call(rev_chans, deg, type) : []).each_with_index do |val, i| if fneq(res1 = locsig_reverb_ref(gen, i), res2 = 0.1 * val) snd_display("locrev[%s] %s at %s: %s %s?", type, gen, deg, res1, res2) break end end end end [2, 3, 4, 5, 8, 12, 16, 24].each do |chans| [Mus_interp_linear, Mus_interp_sinusoidal].each do |ltype| [0.0, 45.0, 90.0, 120.0, 180.0, 275.0, 315.0, 300.0, 15.0, 1234.0].each do |deg| gen = make_locsig(deg, :channels, chans, :type, ltype, :revout, revfile, :reverb, 0.1) if gen.channels != chans snd_display("stereo locsig %s: %s?", deg, gen) break end locsig_scalers.call(chans, deg, ltype).each_with_index do |val, i| if fneq(res = locsig_ref(gen, i), val) snd_display("locrev[%s] %s at %s: %s %s?", ltype, gen, deg, res, val) break end end (revfile ? locsig_scalers.call(rev_chans,deg,ltype): []).each_with_index do |val, i| if fneq(res1 = locsig_reverb_ref(gen, i), res2 = 0.1 * val) snd_display("locrev[%s] %s at %s: %s %s?", ltype, gen, deg, res1, res2) break end end end end end end revfile and mus_close(revfile) end # set_locsig_type(Mus_interp_linear) outp = Vct.new(10) gen = make_locsig(0.0, :output, outp) if (res = mus_channels(gen)) != 1 snd_display("make_locsig->vct chans (1)", res) end 10.times do |i| locsig(gen, i, 1.0) end unless vequal(outp, Vct.new(10, 1.0)) snd_display("locsig->vct chan 0: %s?", outp) end 10.times do |i| locsig(gen, i, 0.5) end unless vequal(outp, Vct.new(10, 1.5)) snd_display("locsig->vct chan 0: %s?", outp) end outp = Vct.new(10) gen = make_locsig(45.0, :channels, 2, :output, outp) if (res = mus_channels(gen)) != 2 snd_display("make_locsig->vct chans (2)", res) end 10.times do |i| locsig(gen, i, 1.0) end unless vequal(outp, Vct.new(10, 0.5)) snd_display("locsig(2)->vct chan 0: %s?", outp) end 10.times do |i| locsig(gen, i, 0.5) end unless vequal(outp, Vct.new(10, 0.75)) snd_display("locsig(2)->vct chan 0: %s?", outp) end # set_mus_array_print_length(8) outf1 = make_frample2file("fmv.snd", 1, Mus_bshort, Mus_next) outf4 = make_frample2file("fmv1.snd", 4, Mus_bshort, Mus_next) revf = make_frample2file("fmv2.snd", 1, Mus_bshort, Mus_next) start = 0 len = 1000 dur = 1.0 gen1 = make_move_sound([start, len, 1, 0, make_delay(32), make_env([0, 0, 1, 1], :length, 1001), make_env([0, 0, 1, 1], :length, 1001), [make_delay(32)], [make_env([0, 0, 1, 1], :length, 1001)], false, [0, 1]], outf1) gen2 = make_move_sound([start, len, 4, 0, make_delay(12), make_env([0, 0, 10, 1], :duration, dur), false, Array.new(4, false), [make_env([0, 0, 1, 1, 2, 0, 3, 0, 4, 0], :duration, dur), make_env([0, 0, 1, 0, 2, 1, 3, 0, 4, 0], :duration, dur), make_env([0, 0, 1, 0, 2, 0, 3, 1, 4, 0], :duration, dur), make_env([0, 0, 1, 0, 2, 0, 3, 0, 4, 1], :duration, dur)], false, [0, 1, 2, 3]], outf4) gen3 = make_move_sound([start, len, 1, 1, make_delay(32), make_env([0, 0, 1, 1], :length, 1001), make_env([0, 0, 1, 1], :length, 1001), [make_delay(32)], [make_env([0, 0, 1, 1], :length, 1001)], [make_env([0, 1, 1, 1], :length, 1001)], [0, 1]], outf1, revf) print_and_check(gen1, "move-sound", "move-sound start: 0, end: 1000, out chans 1, rev chans: 0 doppler delay line[32, step]: [0 0 0 0 0 0 0 0...(0: 0, 0: 0)] doppler env linear, pass: 0 (dur: 1001), index: 0, scaler: 1.0000, offset: 0.0000, data: [0 0 1 1] global reverb env linear, pass: 0 (dur: 1001), index: 0, scaler: 1.0000, offset: 0.0000, data: [0 0 1 1] out_delays[1]: [0]: delay line[32, step]: [0 0 0 0 0 0 0 0...(0: 0, 0: 0)] out_envs[1]: [0]: env linear, pass: 0 (dur: 1001), index: 0, scaler: 1.0000, offset: 0.0000, data: [0 0 1 1] rev_envs: nil out_map[1]: (0) free: arrays: true, gens: false ") print_and_check(gen2, "move-sound", "move-sound start: 0, end: 1000, out chans 4, rev chans: 0 doppler delay line[12, step]: [0 0 0 0 0 0 0 0...(0: 0, 0: 0)] doppler env linear, pass: 0 (dur: 22050), index: 0, scaler: 1.0000, offset: 0.0000, data: [0 0 10 1] global reverb null out_delays[4]: [0]: nil [1]: nil [2]: nil [3]: nil out_envs[4]: [0]: env linear, pass: 0 (dur: 22050), index: 0, scaler: 1.0000, offset: 0.0000, data: [0 0 1 1 2 0 3 0...(0: 0, 8: 4)] [1]: env linear, pass: 0 (dur: 22050), index: 0, scaler: 1.0000, offset: 0.0000, data: [0 0 1 0 2 1 3 0...(0: 0, 8: 4)] [2]: env linear, pass: 0 (dur: 22050), index: 0, scaler: 1.0000, offset: 0.0000, data: [0 0 1 0 2 0 3 1...(0: 0, 8: 4)] [3]: env linear, pass: 0 (dur: 22050), index: 0, scaler: 1.0000, offset: 0.0000, data: [0 0 1 0 2 0 3 0...(0: 0, 8: 4)] rev_envs: nil out_map[4]: (0 1 2 3) free: arrays: true, gens: false ") print_and_check(gen3, "move-sound", "move-sound start: 0, end: 1000, out chans 1, rev chans: 1 doppler delay line[32, step]: [0 0 0 0 0 0 0 0...(0: 0, 0: 0)] doppler env linear, pass: 0 (dur: 1001), index: 0, scaler: 1.0000, offset: 0.0000, data: [0 0 1 1] global reverb env linear, pass: 0 (dur: 1001), index: 0, scaler: 1.0000, offset: 0.0000, data: [0 0 1 1] out_delays[1]: [0]: delay line[32, step]: [0 0 0 0 0 0 0 0...(0: 0, 0: 0)] out_envs[1]: [0]: env linear, pass: 0 (dur: 1001), index: 0, scaler: 1.0000, offset: 0.0000, data: [0 0 1 1] rev_envs[1]: [0]: env linear, pass: 0 (dur: 1001), index: 0, scaler: 1.0000, offset: 0.0000, data: [0 1 1 1] out_map[1]: (0) free: arrays: true, gens: false ") # unless move_sound?(gen1) snd_display("not move_sound: %s?", gen1) end if gen1 == gen2 snd_display("move_sounds are equal: %s == %s?", gen1, gen2) end if gen1.channels != 1 snd_display("mus_channels move_sound (1): %s?", gen1.channels) end if gen2.channels != 4 snd_display("mus_channels move_sound (4): %s?", gen2.channels) end gen1.reset # no-op # v = Vct.new(10) do |i| move_sound(gen1, i, 0.5) + gen2.run(i, 0.25) + move_sound(gen3, i, 0.125) end unless vequal(v, Vct.new(10, 0.875)) snd_display("move_sound output: %s?", v) end if (res = Snd.catch do make_move_sound([0, 1000, 1, 0, make_oscil(32), make_env([0, 0, 1, 1], :length, 1001), make_env([0, 0, 1, 1], :length, 1001), [make_delay(32)], [make_env([0, 0, 1, 1], :length, 1001)], false, [0, 1]], outf1) end).first != :wrong_type_arg snd_display("make_move_sound bad doppler delay: %s", res.inspect) end if (res = Snd.catch do make_move_sound([0, 1000, 1, 0, make_oscil(32), make_env([0, 0, 1, 1], :length, 1001), make_env([0, 0, 1, 1], :length, 1001), [make_delay(32)]], outf1) end).first != :wrong_type_arg snd_display("make_move_sound truncated list: %s", res.inspect) end if (res = Snd.catch do make_move_sound([0, 1000, 1, 0, make_delay(32), make_env([0, 0, 1, 1], :length, 1001), false, [false], [make_env([0, 0, 1, 1], :length, 1001)], false, false], outf1) end).first != :wrong_type_arg snd_display("make_move_sound no out map: %s", res.inspect) end mus_close(outf1) mus_close(outf4) mus_close(revf) delete_file("fmv.snd") delete_file("fmv1.snd") delete_file("fmv2.snd") mus_sound_prune end def test_08_15 if (res = Snd.catch do make_src(:width, -1) end).first != :out_of_range snd_display("make_src bad width: %s", res.inspect) end # s1 = make_src(lambda do |y| 1.0 end, 2.0) src(s1, 25.0) src(s1, 25.0) src(s1, 125.0) src(s1, -25.0) src(s1, -125.0) 10.times do |i| make_src(lambda do |y| 1.0 end, 1.5, :width, 5 + i * 10) end # ctr = 0.0 gen = make_src(:srate, 2.0, :input, lambda do |dir| val = ctr ctr += 1.0 val end) v0 = make_vct!(10) do src(gen, 0.0) end ctr = 0.0 gen.reset v0.each_with_index do |old_val, i| snd_test_neq(old_val, src(gen, 0.0), "reset src %d", i) end # so1 = lambda do |ss, pp| src(ss, env(pp)) end s1 = make_src(:srate, 2.0, :input, make_readin("oboe.snd", 0, 10000)) s2 = make_src(:srate, 2.0, :input, make_readin("oboe.snd", 0, 10000)) s3 = make_src(:srate, 2.0, :input, make_readin("oboe.snd", 0, 10000)) e1 = make_env([0, 1, 2, 0.5], :duration, 1000) e2 = make_env([0, 1, 2, 0.5], :duration, 1000) e3 = make_env([0, 1, 2, 0.5], :duration, 1000) 100.times do |i| x1 = src(s1, env(e1)) ex2 = env(e2) x2 = src(s2, ex2) x3 = so1.call(s3, e3) snd_test_neq(x1, x2, "%d", i) snd_test_neq(x1, x3, "%d", i) end # gen = make_granulate(:expansion, 2.0, :input, make_readin("oboe.snd", 0, 4000, 1, 2048)) gen1 = make_granulate(:expansion, 2.0) rd1 = make_readin(:file, "oboe.snd", :channel, 0, :start, 4000, :direction, 1, :size, mus_file_buffer_size) print_and_check(gen, "granulate", "granulate expansion: 2.000 (551/1102), scaler: 0.600, length: 0.150 secs (3308 samps), ramp: 0.060") v0 = make_vct!(1000) do granulate(gen) end v1 = make_vct(1000) v1.map! do |x| granulate?(gen1) ? granulate(gen1, lambda do |dir| readin(rd1) end) : -1.0 end if (worst = (vct_peak(v0) - vct_peak(v1)).abs) > 0.01 snd_display("run granulate: %s?", worst) end genx = gen1 unless genx.eql?(gen1) snd_display("granulate eql? %s %s %s", genx, gen1, genx.eql?(gen1)) end if gen.eql? gen1 snd_display("granulate eql? %s %s?", gen, gen1) end if vct_peak(v0).zero? snd_display("granulate output peak: %s?", vct_peak(v0)) end unless granulate?(gen) snd_display("%s not granulate?", gen) end if fneq(gen.increment, 2.0) snd_display("granulate increment: %s?", gen.increment) end if fneq(gen.scaler, 0.6) snd_display("granulate scaler: %s?", gen.scaler) end if ffneq(gen.frequency, 0.05) snd_display("granulate frequency: %s?", gen.frequency) end if gen.ramp != 1323 snd_display("granulate ramp: %s?", gen.ramp) end if gen.length != 3308 snd_display("granulate length: %s?", gen.length) end if gen.hop != 1102 snd_display("granulate hop: %s?", gen.hop) end gen.hop = 1000 if gen.hop != 1000 snd_display("granulate set_hop: %s?", gen.hop) end gen.ramp = 1000 if gen.ramp != 1000 snd_display("granulate set_ramp: %s?", gen.ramp) end gen.length = 3000 if gen.length != 3000 snd_display("granulate set_length: %s?", gen.length) end gen.increment = 3.0 if ffneq(gen.increment, 3.0) snd_display("granulate set_increment: %s?", gen.increment) end gen.location = 1 if gen.location != 1 snd_display("granulate set_location: %s?", gen.location) end gen.frequency = 0.1 if fneq(gen.frequency, 0.1) snd_display("granulate set_frequency: %s?", gen.frequency) end # if (res = Snd.catch do make_granulate(:hop, 35.0, :length, 35.0) end).first != :out_of_range snd_display("make_granulate bad sizes: %s", res.inspect) end # ind = open_sound("oboe.snd") mx = maxamp(ind, 0) rd = make_sampler(0) grn = make_granulate(:expansion, 2.0, :input, lambda do |dir| rd.call end, :edit, lambda do |g| g.data.scale!(2.0) 0 end) map_channel(lambda do |y| granulate(grn) end) if (maxamp() / mx) < 1.4 or (mx / maxamp()) > 2.5 snd_display("gran edit 2* (0): %s %s?", mx, maxamp()) end undo_edit rd = make_sampler(0) grn = make_granulate(:expansion, 2.0, :input, lambda do |dir| read_sample(rd) end, :edit, lambda do |g| g.data.scale!(4.0) 0 end) map_channel(lambda do |y| granulate(grn) end) if (maxamp() / mx) < 3.0 or (mx / maxamp()) > 6.0 snd_display("gran edit 4* (0): %s %s?", mx, maxamp()) end revert_sound(ind) rd = make_sampler(0) grn = make_granulate(:expansion, 2.0, :input, lambda do |dir| read_sample(rd) end, :edit, lambda do |g| g.data.scale!(2.0) 0 end) map_channel(lambda do |y| granulate(grn) end) if (maxamp() / mx) < 1.4 or (mx / maxamp()) > 2.5 snd_display("gran edit 2* (1): %s %s?", mx, maxamp()) end undo_edit rd = make_sampler(0) grn = make_granulate(:expansion, 2.0, :input, lambda do |dir| read_sample(rd) end, :edit, lambda do |g| g.data.scale!(4.0) 0 end) map_channel(lambda do |y| granulate(grn) end) if (maxamp() / mx) < 2.9 or (mx / maxamp()) > 6.0 snd_display("gran edit 4* (1): %s %s?", mx, maxamp()) end revert_sound(ind) # XXX: grn = make_granulate(:expansion, 2.0, :input, make_sampler(0)) # Doesn't work with Ruby; make_sampler is not a procedure. rd = make_sampler(0) input_fnc = lambda do |dir| rd.call end edit_fnc = lambda do |g| g.data.scale!(2.0) 0 end grn = make_granulate(:expansion, 2.0, :input, input_fnc, :edit, edit_fnc) map_channel(lambda do |y| granulate(grn) end) if (maxamp() / mx) < 1.4 or (mx / maxamp()) > 2.5 snd_display("gran edit 2* (2): %s %s?", mx, maxamp()) end undo_edit rd = make_sampler(0) grn = make_granulate(:expansion, 2.0) map_channel(lambda do |y| granulate(grn, lambda do |dir| rd.call end, lambda do |g| g.data.scale!(4.0) 0 end) end) if (maxamp() / mx) < 3.0 or (mx / maxamp()) > 6.0 snd_display("gran edit 4* (2): %s %s?", mx, maxamp()) end close_sound(ind) ind = open_sound("oboe.snd") rd = make_sampler(0) grn = make_granulate(:expansion, 2.0, :length, 0.01, :hop, 0.05, :input, lambda do |dir| next_sample(rd) end) map_channel(lambda do |y| granulate(grn) end) if (res = maxamp) > 0.2 snd_display("trouble in granulate len 0.01 hop 0.05: %s?", res) end undo_edit rd = make_sampler(0) grn = make_granulate(:expansion, 2.0, :length, 0.04, :hop, 0.05, :input, lambda do |dir| next_sample(rd) end) map_channel(lambda do |y| granulate(grn) end) if (res = maxamp) > 0.2 snd_display("trouble in granulate len 0.04 hop 0.05: %s?", res) end undo_edit rd = make_sampler(0) grn = make_granulate(:expansion, 2.0, :length, 0.01, :hop, 0.25, :input, lambda do |dir| next_sample(rd) end) map_channel(lambda do |y| granulate(grn) end) if (res = maxamp) > 0.2 snd_display("trouble in granulate len 0.01 hop 0.25: %s?", res) end undo_edit rd = make_sampler(0) grn = make_granulate(:expansion, 2.0, :length, 0.4, :hop, 0.5, :input, lambda do |dir| next_sample(rd) end) map_channel(lambda do |y| granulate(grn) end) if (res = maxamp) > 0.2 snd_display("trouble in granulate len 0.4 hop 0.5: %s?", res) end undo_edit close_sound(ind) end def test_08_16 ind = new_sound(:size, 1000) gen = make_granulate(:jitter, 0.0, :hop, 0.004, :length, 0.001, :input, lambda do |dir| 0.1 end) map_channel(lambda do |y| granulate(gen) end) if fneq(res = maxamp, 0.06) snd_display("gran 0 max: %s?", res) end unless vequal(res = channel2vct(0, 30), vct(0.000, 0.007, 0.013, 0.020, 0.027, 0.033, 0.040, 0.047, 0.053, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.053, 0.047, 0.040, 0.033, 0.027, 0.020, 0.013, 0.007, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000)) snd_display("gran 0 data: %s?", res) end unless vequal(res = channel2vct(85, 30), vct(0.000, 0.000, 0.000, 0.000, 0.007, 0.013, 0.020, 0.027, 0.033, 0.040, 0.047, 0.053, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.053, 0.047, 0.040, 0.033, 0.027, 0.020, 0.013, 0.007, 0.000, 0.000, 0.000, 0.000)) snd_display("gran 0 data 85: %s?", res) end undo_edit gen = make_granulate(:jitter, 0.0, :hop, 0.002, :length, 0.001, :input, lambda do |dir| 0.1 end) map_channel(lambda do |y| granulate(gen) end) if fneq(res = maxamp, 0.06) snd_display("gran 1 max: %s?", res) end unless vequal(res = channel2vct(0, 30), vct(0.000, 0.007, 0.013, 0.020, 0.027, 0.033, 0.040, 0.047, 0.053, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.053, 0.047, 0.040, 0.033, 0.027, 0.020, 0.013, 0.007, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000)) snd_display("gran 1 data: %s?", res) end unless vequal(res = channel2vct(40, 30), vct(0.000, 0.000, 0.000, 0.000, 0.000, 0.007, 0.013, 0.020, 0.027, 0.033, 0.040, 0.047, 0.053, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.053, 0.047, 0.040, 0.033, 0.027, 0.020, 0.013, 0.007, 0.000, 0.000, 0.000)) snd_display("gran 1 data 40: %s?", res) end undo_edit gen = make_granulate(:jitter, 0.0, :hop, 0.002, :length, 0.001, :ramp, 0.1, :input, lambda do |dir| 0.1 end) map_channel(lambda do |y| granulate(gen) end) if fneq(res = maxamp, 0.06) snd_display("gran 2 max: %s?", res) end unless vequal(res = channel2vct(0, 30), vct(0.000, 0.030, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.030, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000)) snd_display("gran 2 data: %s?", res) end unless vequal(res = channel2vct(40, 30), vct(0.000, 0.000, 0.000, 0.000, 0.000, 0.030, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.030, 0.000, 0.000, 0.000)) snd_display("gran 2 data 40: %s?", res) end undo_edit gen = make_granulate(:jitter, 0.0, :hop, 0.002, :length, 0.001, :ramp, 0.5, :input, lambda do |dir| 0.1 end) map_channel(lambda do |y| granulate(gen) end) if fneq(res = maxamp, 0.06) snd_display("gran 3 max: %s?", res) end unless vequal(res = channel2vct(0, 30), vct(0.000, 0.005, 0.011, 0.016, 0.022, 0.027, 0.033, 0.038, 0.044, 0.049, 0.055, 0.060, 0.060, 0.055, 0.049, 0.044, 0.038, 0.033, 0.027, 0.022, 0.016, 0.011, 0.005, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000)) snd_display("gran 3 data: %s?", res) end unless vequal(res = channel2vct(85, 30), vct(0.000, 0.000, 0.000, 0.000, 0.005, 0.011, 0.016, 0.022, 0.027, 0.033, 0.038, 0.044, 0.049, 0.055, 0.060, 0.060, 0.055, 0.049, 0.044, 0.038, 0.033, 0.027, 0.022, 0.016, 0.011, 0.005, 0.000, 0.000, 0.000, 0.000)) snd_display("gran 3 data 85: %s?", res) end undo_edit gen = make_granulate(:jitter, 0.0, :hop, 0.001, :length, 0.001, :ramp, 0.5, :input, lambda do |dir| 0.1 end) map_channel(lambda do |y| granulate(gen) end) if fneq(res = maxamp, 0.06) snd_display("gran 4 max: %s?", res) end unless vequal(res = channel2vct(0, 30), vct(0.000, 0.005, 0.011, 0.016, 0.022, 0.027, 0.033, 0.038, 0.044, 0.049, 0.055, 0.060, 0.060, 0.055, 0.049, 0.044, 0.038, 0.033, 0.027, 0.022, 0.016, 0.011, 0.005, 0.005, 0.011, 0.016, 0.022, 0.027, 0.033, 0.038)) snd_display("gran 4 data: %s?", res) end unless vequal(res = channel2vct(85, 30), vct(0.022, 0.016, 0.011, 0.005, 0.005, 0.011, 0.016, 0.022, 0.027, 0.033, 0.038, 0.044, 0.049, 0.055, 0.060, 0.060, 0.055, 0.049, 0.044, 0.038, 0.033, 0.027, 0.022, 0.016, 0.011, 0.005, 0.005, 0.011, 0.016, 0.022)) snd_display("gran 4 data 85: %s?", res) end undo_edit gen = make_granulate(:jitter, 0.0, :hop, 0.001, :length, 0.001, :ramp, 0.25, :scaler, 1.0, :input, lambda do |dir| 0.1 end) map_channel(lambda do |y| granulate(gen) end) if fneq(res = maxamp, 0.1) snd_display("gran 5 max: %s?", res) end unless vequal(res = channel2vct(0, 30), vct(0.000, 0.020, 0.040, 0.060, 0.080, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.080, 0.060, 0.040, 0.020, 0.020, 0.040, 0.060, 0.080, 0.100, 0.100, 0.100)) snd_display("gran 5 data: %s?", res) end unless vequal(res = channel2vct(85, 30), vct(0.080, 0.060, 0.040, 0.020, 0.020, 0.040, 0.060, 0.080, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.080, 0.060, 0.040, 0.020, 0.020, 0.040, 0.060, 0.080)) snd_display("gran 5 data 85: %s?", res) end undo_edit gen = make_granulate(:jitter, 0.0, :hop, 0.001, :length, 0.002, :ramp, 0.5, :scaler, 1.0, :input, lambda do |dir| 0.1 end) map_channel(lambda do |y| granulate(gen) end) if fneq(res = maxamp, 0.105) snd_display("gran 6 max: %s?", res) end unless vequal(res = channel2vct(0, 30), vct(0.000, 0.005, 0.009, 0.014, 0.018, 0.023, 0.027, 0.032, 0.036, 0.041, 0.045, 0.050, 0.055, 0.059, 0.064, 0.068, 0.073, 0.077, 0.082, 0.086, 0.091, 0.095, 0.100, 0.105, 0.105, 0.105, 0.105, 0.105, 0.105, 0.105)) snd_display("gran 6 data: %s?", res) end unless vequal(res = channel2vct(85, 30), vct(0.105, 0.105, 0.105, 0.105, 0.105, 0.105, 0.105, 0.105, 0.105, 0.105, 0.105, 0.105, 0.105, 0.105, 0.105, 0.105, 0.105, 0.105, 0.105, 0.105, 0.105, 0.105, 0.105, 0.105, 0.105, 0.105, 0.105, 0.105, 0.105, 0.105)) snd_display("gran 6 data 85: %s?", res) end undo_edit gen = make_granulate(:jitter, 0.0, :hop, 0.001, :length, 0.005, :ramp, 0.5, :scaler, 1.0, :input, lambda do |dir| 0.1 end) map_channel(lambda do |y| granulate(gen) end) if fneq(res = maxamp, 0.264) snd_display("gran 7 max: %s?", res) end unless vequal(res = channel2vct(0, 30), vct(0.000, 0.002, 0.004, 0.005, 0.007, 0.009, 0.011, 0.013, 0.015, 0.016, 0.018, 0.020, 0.022, 0.024, 0.025, 0.027, 0.029, 0.031, 0.033, 0.035, 0.036, 0.038, 0.040, 0.044, 0.047, 0.051, 0.055, 0.058, 0.062, 0.065)) snd_display("gran 7 data: %s?", res) end unless vequal(res = channel2vct(85, 30), vct(0.244, 0.244, 0.244, 0.244, 0.245, 0.247, 0.249, 0.251, 0.253, 0.255, 0.256, 0.258, 0.260, 0.262, 0.264, 0.264, 0.262, 0.260, 0.258, 0.256, 0.255, 0.253, 0.251, 0.249, 0.247, 0.245, 0.245, 0.247, 0.249, 0.251)) snd_display("gran 7 data 85: %s?", res) end undo_edit gen = make_granulate(:jitter, 0.0, :hop, 0.01, :length, 0.001, :ramp, 0.5, :scaler, 1.0, :expansion, 2.0, :input, lambda do |dir| 0.1 end) map_channel(lambda do |y| granulate(gen) end) if fneq(res = maxamp, 0.1) snd_display("gran 8 max: %s?", res) end unless vequal(res = channel2vct(0, 30), vct(0.000, 0.009, 0.018, 0.027, 0.036, 0.045, 0.055, 0.064, 0.073, 0.082, 0.091, 0.100, 0.100, 0.091, 0.082, 0.073, 0.064, 0.055, 0.045, 0.036, 0.027, 0.018, 0.009, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000)) snd_display("gran 8 data: %s?", res) end unless vequal(res = channel2vct(220, 30), vct(0.000, 0.009, 0.018, 0.027, 0.036, 0.045, 0.055, 0.064, 0.073, 0.082, 0.091, 0.100, 0.100, 0.091, 0.082, 0.073, 0.064, 0.055, 0.045, 0.036, 0.027, 0.018, 0.009, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000)) snd_display("gran 8 data 220: %s?", res) end undo_edit gen = make_granulate(:jitter, 0.0, :hop, 0.01, :length, 0.001, :ramp, 0.5, :scaler, 1.0, :expansion, 0.5, :input, lambda do |dir| 0.1 end) map_channel(lambda do |y| granulate(gen) end) if fneq(res = maxamp, 0.1) snd_display("gran 9 max: %s?", res) end unless vequal(res = channel2vct(0, 30), vct(0.000, 0.009, 0.018, 0.027, 0.036, 0.045, 0.055, 0.064, 0.073, 0.082, 0.091, 0.100, 0.100, 0.091, 0.082, 0.073, 0.064, 0.055, 0.045, 0.036, 0.027, 0.018, 0.009, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000)) snd_display("gran 9 data: %s?", res) end unless vequal(res = channel2vct(220, 30), vct(0.000, 0.009, 0.018, 0.027, 0.036, 0.045, 0.055, 0.064, 0.073, 0.082, 0.091, 0.100, 0.100, 0.091, 0.082, 0.073, 0.064, 0.055, 0.045, 0.036, 0.027, 0.018, 0.009, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000)) snd_display("gran 9 data 220: %s?", res) end undo_edit gen = make_granulate(:jitter, 0.0, :hop, 0.001, :length, 0.005, :ramp, 0.5, :scaler, 1.0) map_channel(lambda do |y| granulate(gen, lambda do |dir| 0.1 end, lambda do |g| g.data.scale!(2.0) 0 end) end) if fneq(res = maxamp, 2 * 0.264) snd_display("gran 10 max: %s?", res) end unless vequal(vct_scale!(res = channel2vct(0, 30), 0.5), vct(0.000, 0.002, 0.004, 0.005, 0.007, 0.009, 0.011, 0.013, 0.015, 0.016, 0.018, 0.020, 0.022, 0.024, 0.025, 0.027, 0.029, 0.031, 0.033, 0.035, 0.036, 0.038, 0.040, 0.044, 0.047, 0.051, 0.055, 0.058, 0.062, 0.065)) snd_display("gran 10 data: %s?", res) end unless vequal(vct_scale!(res = channel2vct(85, 30), 0.5), vct(0.244, 0.244, 0.244, 0.244, 0.245, 0.247, 0.249, 0.251, 0.253, 0.255, 0.256, 0.258, 0.260, 0.262, 0.264, 0.264, 0.262, 0.260, 0.258, 0.256, 0.255, 0.253, 0.251, 0.249, 0.247, 0.245, 0.245, 0.247, 0.249, 0.251)) snd_display("gran 10 data 85: %s?", res) end undo_edit gen = make_granulate(:jitter, 0.0, :hop, 0.005, :length, 0.002, :ramp, 0.0, :scaler, 1.0) forward = true ctr = -0.5 incr = 0.001 map_channel(lambda do |y| granulate(gen, lambda do |dir| ctr += incr ctr end, lambda do |g| len = g.length if forward forward = false else forward = true vct_reverse!(g.data, len) end len end) end) if (res = maxamp) > 0.6 snd_display("gran 11 max: %s?", res) end unless vequal(res = channel2vct(0, 30), vct(-0.499, -0.498, -0.497, -0.496, -0.495, -0.494, -0.493, -0.492, -0.491, -0.490, -0.489, -0.488, -0.487, -0.486, -0.485, -0.484, -0.483, -0.482, -0.481, -0.480, -0.479, -0.478, -0.477, -0.476, -0.475, -0.474, -0.473, -0.472, -0.471, -0.470)) snd_display("gran 11 data: %s?", res) end unless vequal(res = channel2vct(100, 30), vct(0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, -0.345, -0.346, -0.347, -0.348, -0.349, -0.350, -0.351, -0.352, -0.353, -0.354, -0.355, -0.356, -0.357, -0.358, -0.359, -0.360, -0.361, -0.362, -0.363, -0.364)) snd_display("gran 11 data 100: %s?", res) end undo_edit ctr = -0.5 incr = 0.001 gen = make_granulate(:jitter, 0.0, :hop, 0.005, :length, 0.002, :ramp, 0.0, :scaler, 1.0, :input, lambda do |dir| ctr += incr end) map_channel(lambda do |y| granulate(gen) end) if (res = maxamp) > 0.6 snd_display("gran 12 max: %s?", res) end unless vequal(res = channel2vct(0, 30), vct(-0.499, -0.498, -0.497, -0.496, -0.495, -0.494, -0.493, -0.492, -0.491, -0.490, -0.489, -0.488, -0.487, -0.486, -0.485, -0.484, -0.483, -0.482, -0.481, -0.480, -0.479, -0.478, -0.477, -0.476, -0.475, -0.474, -0.473, -0.472, -0.471, -0.470)) snd_display("gran 12 data: %s?", res) end unless vequal(res = channel2vct(100, 30), vct(0.0, 0.0, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.0, 0.0, -0.389, -0.388, -0.387, -0.386, -0.385, -0.384, -0.383, -0.382, -0.381, -0.38, -0.379, -0.378, -0.377, -0.376, -0.375, -0.374, -0.373, -0.372, -0.371, -0.370)) snd_display("gran 12 data 100: %s?", res) end undo_edit gen = make_granulate(:jitter, 0.0, :hop, 0.001, :length, 0.005, :ramp, 0.5, :scaler, 1.0, :input, lambda do |dir| 0.1 end, :edit, lambda do |g| g.data.scale!(2.0) 0 end) map_channel(lambda do |y| granulate(gen) end) if (res = maxamp) > 0.6 snd_display("gran 13 max: %s?", res) end unless vequal(vct_scale!(res = channel2vct(0, 30), 0.5), vct(0.000, 0.002, 0.004, 0.005, 0.007, 0.009, 0.011, 0.013, 0.015, 0.016, 0.018, 0.020, 0.022, 0.024, 0.025, 0.027, 0.029, 0.031, 0.033, 0.035, 0.036, 0.038, 0.040, 0.044, 0.047, 0.051, 0.055, 0.058, 0.062, 0.065)) snd_display("gran 13 data: %s?", res) end unless vequal(vct_scale!(res = channel2vct(85, 30), 0.5), vct(0.244, 0.244, 0.244, 0.244, 0.245, 0.247, 0.249, 0.251, 0.253, 0.255, 0.256, 0.258, 0.260, 0.262, 0.264, 0.264, 0.262, 0.260, 0.258, 0.256, 0.255, 0.253, 0.251, 0.249, 0.247, 0.245, 0.245, 0.247, 0.249, 0.251)) snd_display("gran 13 data 85: %s?", res) end undo_edit forward = true ctr = -0.5 incr = 0.001 gen = make_granulate(:jitter, 0.0, :hop, 0.005, :length, 0.002, :ramp, 0.0, :scaler, 1.0, :input, lambda do |dir| ctr += incr ctr end, :edit, lambda do |g| len = mus_length(g) if forward forward = false else forward = true vct_reverse!(mus_data(g), len) end len end) map_channel(lambda do |y| granulate(gen) end) if (res = maxamp) > 0.6 snd_display("gran 14 max: %s?", res) end unless vequal(res = channel2vct(0, 30), vct(-0.499, -0.498, -0.497, -0.496, -0.495, -0.494, -0.493, -0.492, -0.491, -0.490, -0.489, -0.488, -0.487, -0.486, -0.485, -0.484, -0.483, -0.482, -0.481, -0.480, -0.479, -0.478, -0.477, -0.476, -0.475, -0.474, -0.473, -0.472, -0.471, -0.470)) snd_display("gran 14 data: %s?", res) end unless vequal(res = channel2vct(100, 30), vct(0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, -0.345, -0.346, -0.347, -0.348, -0.349, -0.350, -0.351, -0.352, -0.353, -0.354, -0.355, -0.356, -0.357, -0.358, -0.359, -0.360, -0.361, -0.362, -0.363, -0.364)) snd_display("gran 14 data 100: %s?", res) end undo_edit # gen = make_granulate(:jitter, 0.0, :hop, 0.004, :length, 0.001, :ramp, 0.0, :input, lambda do |dir| 0.1 end) e = make_env(:envelope, [0, 0, 1, 0.5], :length, 1001) base_ramp_len = mus_length(gen) map_channel(lambda do |y| result = granulate(gen) set_mus_ramp(gen, (base_ramp_len * env(e)).round) result end) if fneq(res = maxamp, 0.06) snd_display("granf 0 max: %s?", res) end if (mus_ramp(gen) - 0.5 * mus_length(gen)).abs > 1 snd_display("granf 0 ramp: %s %s?", gen.ramp, gen.length) end unless vequal(res = channel2vct(0, 30), vct(0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000)) snd_display("granf 0 data: %s?", res) end unless vequal(res = channel2vct(440, 30), vct(0.000, 0.012, 0.024, 0.036, 0.048, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.048, 0.036, 0.024, 0.012, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000)) snd_display("granf 0 data 440: %s?", res) end unless vequal(res = channel2vct(880, 30), vct(0.000, 0.006, 0.012, 0.018, 0.024, 0.030, 0.036, 0.042, 0.048, 0.054, 0.060, 0.060, 0.060, 0.060, 0.054, 0.048, 0.042, 0.036, 0.030, 0.024, 0.018, 0.012, 0.006, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000)) snd_display("granf 0 data 880: %s?", res) end undo_edit gen = make_granulate(:jitter, 0.0, :hop, 0.004, :length, 0.001, :ramp, 0.0, :input, lambda do |dir| 0.1 end) e = make_env(:envelope, [0, 1, 1, 0.25], :length, 1001) base_hop_len = mus_hop(gen) map_channel(lambda do |y| result = granulate(gen) set_mus_hop(gen, (base_hop_len * env(e)).round) result end) if fneq(res = maxamp, 0.06) snd_display("granf 1 max: %s?", res) end if (mus_hop(gen) - 0.001 * mus_srate).abs > 1 snd_display("granf 1 hop: %s?", gen.hop) end unless vequal(res = channel2vct(0, 30), vct(0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000)) snd_display("granf 1 data: %s?", res) end unless vequal(res = channel2vct(900, 30), vct(0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060)) snd_display("granf 1 data 900: %s?", res) end undo_edit gen = make_granulate(:jitter, 0.0, :hop, 0.004, :length, 0.001, :ramp, 0.0, :input, lambda do |dir| 0.1 end) e = make_env(:envelope, [0, 1, 1, 0.25], :length, 1001) base_freq = mus_frequency(gen) map_channel(lambda do |y| result = granulate(gen) set_mus_frequency(gen, base_freq * env(e)) result end) if fneq(res = maxamp, 0.06) snd_display("granf 2 max: %s?", res) end if (mus_hop(gen) - 0.001 * mus_srate).abs > 1 snd_display("granf 2 hop: %s?", gen.hop) end unless vequal(res = channel2vct(0, 30), vct(0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000)) snd_display("granf 2 data: %s?", res) end unless vequal(res = channel2vct(900, 30), vct(0.060, 0.060, 0.060, 0.060, 0.060, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060)) snd_display("granf 2 data 900: %s?", res) end undo_edit gen = make_granulate(:jitter, 0.0, :hop, 0.002, :length, 0.001, :ramp, 0.0, :scaler, 1.0, :input, lambda do |dir| 0.1 end) base_freq = mus_frequency(gen) map_channel(lambda do |y| granulate(gen) end) if fneq(res = maxamp, 0.1) snd_display("granf 3 max: %s?", res) end unless vequal(res = channel2vct(0, 30), vct(0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000)) snd_display("granf 3 data: %s?", res) end undo_edit gen = make_granulate(:jitter, 0.0, :hop, 0.004, :length, 0.001, :ramp, 0.0, :scaler, 1.0, :input, lambda do |dir| 0.1 end) e = make_env(:envelope, [0, 1, 1, 0], :length, 1001) base_freq = mus_frequency(gen) map_channel(lambda do |y| result = granulate(gen) set_mus_scaler(gen, env(e)) result end) if fneq(res = maxamp, 0.1) snd_display("granf 4 max: %s?", res) end unless vequal(res = channel2vct(0, 30), vct(0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000)) snd_display("granf 4 data: %s?", res) end unless vequal(res = channel2vct(440, 30), vct(0.056, 0.056, 0.056, 0.056, 0.056, 0.056, 0.056, 0.056, 0.056, 0.056, 0.056, 0.056, 0.056, 0.056, 0.056, 0.056, 0.056, 0.056, 0.056, 0.056, 0.056, 0.056, 0.056, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000)) snd_display("granf 4 data 440: %s?", res) end unless vequal(res = channel2vct(900, 30), vct(0.012, 0.012, 0.012, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000)) snd_display("granf 4 data 900: %s?", res) end undo_edit gen = make_granulate(:jitter, 0.0, :hop, 0.006, :length, 0.001, :ramp, 0.0, :max_size, 2200, :input, lambda do |dir| 0.1 end) e = make_env(:envelope, [0, 1, 1, 5], :length, 1001) base_len = mus_length(gen) map_channel(lambda do |y| result = granulate(gen) set_mus_length(gen, (base_len * env(e)).round) result end) if fneq(res = maxamp, 0.06) snd_display("granf 5 max: %s?", res) end if (gen.length - 5 * base_len).abs > 10 snd_display("granf 5 length: %s %s?", mus_length(gen), 5 * base_len) end unless vequal(res = channel2vct(0, 30), vct(0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000)) snd_display("granf 5 data: %s?", res) end unless vequal(res = channel2vct(440, 30), vct(0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000)) snd_display("granf 5 data 440: %s?", res) end unless vequal(res = channel2vct(800, 30), vct(0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060)) snd_display("granf 5 data 800: %s?", res) end undo_edit gen = make_granulate(:jitter, 0.0, :hop, 0.006, :length, 0.005, :ramp, 0.0, :max_size, 2200, :input, lambda do |dir| 0.1 end) e = make_env(:envelope, [0, 1, 1, 0.2], :length, 1001) base_len = mus_length(gen) map_channel(lambda do |y| result = granulate(gen) set_mus_length(gen, (base_len * env(e)).round) result end) if fneq(res = maxamp, 0.06) snd_display("granf 6 max: %s?", res) end if (gen.length - 0.2 * base_len).abs > 4 snd_display("granf 6 length: %s %s?", mus_length(gen), 0.2 * base_len) end unless vequal(res = channel2vct(0, 30), vct(0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060)) snd_display("granf 6 data: %s?", res) end unless vequal(res = channel2vct(820, 30), vct(0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.060, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000)) snd_display("granf 6 data 820: %s?", res) end undo_edit max_list = lambda do pts = [] samp = 0 lasty = 0.0 scan_channel(lambda do |y| if lasty < 0.1 and y >= 0.1 pts << samp end lasty = y samp += 1 false end) pts end gen = make_granulate(:jitter, 0.0, :hop, 0.01, :length, 0.001, :ramp, 0.5, :scaler, 1.0, :expansion, 0.5, :input, lambda do |dir| 0.1 end) map_channel(lambda do |y| granulate(gen) end) if [11, 231, 451, 671, 891] != (res = max_list.call) snd_display("grn jitter 0 max: %s?", res) end undo_edit gen = make_granulate(:jitter, 0.3, :hop, 0.01, :length, 0.001, :ramp, 0.5, :scaler, 1.0, :expansion, 0.5, :input, lambda do |dir| 0.1 end) map_channel(lambda do |y| granulate(gen) end) if [11, 231, 451, 671, 891] == (res = max_list.call) snd_display("grn jitter 0.3 max: %s?", res) end old_vals = res undo_edit gen = make_granulate(:jitter, 0.3, :hop, 0.01, :length, 0.001, :ramp, 0.5, :scaler, 1.0, :expansion, 0.5, :input, lambda do |dir| 0.1 end) map_channel(lambda do |y| granulate(gen) end) if (res = max_list.call) == old_vals snd_display("grn jitter 0.3 max: %s %s?", res, old_vals) end undo_edit old_vals = false gen = make_granulate(:jitter, 1.0, :hop, 0.01, :length, 0.001, :ramp, 0.5, :scaler, 1.0, :expansion, 0.5, :input, lambda do |dir| 0.1 end) seed = gen.location map_channel(lambda do |y| granulate(gen) end) old_vals = max_list.call undo_edit gen = make_granulate(:jitter, 1.0, :hop, 0.01, :length, 0.001, :ramp, 0.5, :scaler, 1.0, :expansion, 0.5, :input, lambda do |dir| 0.1 end) gen.location = seed map_channel(lambda do |y| granulate(gen) end) if (res = max_list.call) != old_vals snd_display("grn jitter 1.0 max with seed: %s %s?", res, old_vals) end undo_edit fname = file_name(ind) close_sound(ind) delete_file(fname) end def test_08_17 ind = new_sound("tmp.snd", 1, 22050, Mus_bfloat, Mus_next, :size, 10000) gen = make_granulate(:expansion, 20.0, :input, lambda do |dir| 0.01 end, :length, 0.00995, :hop, 0.01, :ramp, 0.0, :scaler, 1.0, :jitter, 0.0) clm_channel(gen) # 0.01 max stable if fneq(maxamp, 0.01) snd_display("granulate stable 1: %s?", maxamp) end if minval = scan_channel(lambda do |y| y < 0.0099 end) snd_display("granulate stable 1 min: %s?", minval) end undo_edit gen = make_granulate(:expansion, 20.0, :input, lambda do |dir| 0.1 end, :length, 0.00995, :hop, 0.01, :ramp, 0.0, :scaler, 0.5, :jitter, 0.0) clm_channel(gen) # 0.05 max stable if fneq(maxamp, 0.05) snd_display("granulate stable 2: %s?", maxamp) end if minval = scan_channel(lambda do |y| y < 0.0499 end) snd_display("granulate stable 2 min: %s?", minval) end undo_edit gen = make_granulate(:expansion, 20.0, :input, lambda do |dir| 0.05 end, :length, 0.099975, :hop, 0.1, :ramp, 0.0, :scaler, 1.0, :jitter, 0.0) clm_channel(gen) # 0.05 max stable if fneq(maxamp, 0.05) snd_display("granulate stable 3: %s?", maxamp) end if minval = scan_channel(lambda do |y| y < 0.0499 end) snd_display("granulate stable 3 min: %s %s?", minval, sample(minval[1])) end undo_edit ctr = 0 gen = make_granulate(:expansion, 2.0, :input, lambda do |dir| val = ctr * 0.0001 ctr += 1 val end, :length, 0.01, :hop, 0.1, :ramp, 0.0, :scaler, 1.0, :jitter, 0.0) clm_channel(gen) if fneq(maxamp, 0.462) snd_display("granulate ramped 4: %s?", maxamp) end vals = count_matches(lambda do |y| y != 0.0 end) if (vals - 1104).abs > 10 snd_display("granulate ramped 4 not 0.0: %s?", vals) end if (not vequal(res1 = channel2vct(2203, 10), vct(0.000, 0.000, 0.110, 0.110, 0.110, 0.111, 0.111, 0.111, 0.111, 0.111))) or (not vequal(res2 = channel2vct(4523, 10), vct(0.232, 0.232, 0.232, 0.232, 0.232, 0.232, 0.232, 0.232, 0.233, 0.233))) or (not vequal(res3 = channel2vct(8928, 10), vct(0.452, 0.452, 0.452, 0.452, 0.452, 0.452, 0.452, 0.452, 0.452, 0.452))) snd_display("granulate ramped 4 data off: %s %s %s?", res1, res2, res3) end undo_edit e = make_env([0, 0, 1, 1], :length, 10000) gen = make_granulate(:expansion, 2.0, :input, lambda do |dir| env(e) end, :length, 0.00995, :hop, 0.01, :ramp, 0.0, :scaler, 1.0, :jitter, 0.0) clm_channel(gen) if fneq(maxamp, 0.505) snd_display("granulate ramped 5: %s?", maxamp) end vals = count_matches(lambda do |y| y != 0.0 end) mxoff = 0.0 mx = maxamp len = framples cur = 0.0 incr = mx / len scan_channel(lambda do |y| diff = (cur - y).abs if diff > mxoff mxoff = diff end cur += incr false end) if mxoff > 0.02 snd_display("granulate ramped 5 mxoff: %s?", mxoff) end undo_edit e = make_env([0, 0, 1, 1], :length, 10000) gen = make_granulate(:expansion, 2.0, :input, lambda do |dir| env(e) end, :length, 0.00995, :hop, 0.01, :ramp, 0.5, :scaler, 1.0, :jitter, 0.0) clm_channel(gen) if fneq(maxamp, 0.495) snd_display("granulate ramped 6: %s?", maxamp) end if (not vequal(res1 = channel2vct(2000, 10), vct(0.018, 0.019, 0.020, 0.021, 0.022, 0.023, 0.024, 0.025, 0.026, 0.027))) or (not vequal(res2 = channel2vct(8000, 10), vct(0.294, 0.298, 0.301, 0.305, 0.309, 0.313, 0.316, 0.320, 0.324, 0.328))) snd_display("granulate ramped 6 data: %s %s?", res1, res2) end undo_edit e = make_env([0, 0, 1, 1], :length, 10000) gen = make_granulate(:expansion, 2.0, :input, lambda do |dir| env(e) end, :length, 0.00995, :hop, 0.01, :ramp, 0.25, :scaler, 1.0, :jitter, 0.0) clm_channel(gen) if fneq(maxamp, 0.505) snd_display("granulate ramped 7: %s?", maxamp) end if (not vequal(res1 = channel2vct(2000, 10), vct(0.037, 0.039, 0.040, 0.042, 0.044, 0.046, 0.048, 0.050, 0.052, 0.054))) or (not vequal(res2 = channel2vct(8000, 10), vct(0.404, 0.404, 0.404, 0.404, 0.404, 0.405, 0.405, 0.405, 0.405, 0.405))) snd_display("granulate ramped 7 data: %s %s?", res1, res2) end undo_edit e = make_env([0, 0, 1, 1], :length, 10000) gen = make_granulate(:expansion, 2.0, :input, lambda do |dir| env(e) end, :length, 0.05, :hop, 0.01, :ramp, 0.25, :scaler, 0.1, :jitter, 0.0) clm_channel(gen) if fneq(maxamp, 0.201) snd_display("granulate ramped 7: %s?", maxamp) end mxoff = 0.0 mx = maxamp len = framples cur = 0.0 incr = mx / len scan_channel(lambda do |y| diff = (cur - y).abs if diff > mxoff mxoff = diff end cur += incr false end) if mxoff > 0.01 snd_display("granulate ramped 7 mxoff: %s?", mxoff) end undo_edit e = make_env([0, 0, 1, 1], :length, 10000) gen = make_granulate(:expansion, 2.0, :input, lambda do |dir| env(e) end, :length, 0.1, :hop, 0.01, :ramp, 0.1, :scaler, 0.1, :jitter, 0.0) clm_channel(gen) if fneq(maxamp, 0.501) snd_display("granulate ramped 8: %s?", maxamp) end mxoff = 0.0 mx = maxamp len = framples - 2000 cur = sample(2000) incr = (mx - cur) / len scan_channel(lambda do |y| diff = (cur - y).abs if diff > mxoff mxoff = diff end cur += incr false end, 2000) if mxoff > 0.001 snd_display("granulate ramped 8 mxoff: %s?", mxoff) end undo_edit e = make_env([0, 0, 1, 1], :length, 10000) gen = make_granulate(:expansion, 2.0, :input, lambda do |dir| env(e) end, :length, 0.4, :hop, 0.01, :ramp, 0.4, :scaler, 0.025, :jitter, 0.0) clm_channel(gen) if fneq(maxamp, 0.433) snd_display("granulate ramped 9: %s?", maxamp) end undo_edit close_sound(ind) end def test_08_18 v0 = make_vct(32) v1 = make_vct(256) v2 = make_vct(256) v01 = make_vct(32) v11 = make_vct(256) v21 = make_vct(256) 1.upto(15) do |i| v0[i] = v01[i] = 1.0 / i end v1[0] = v11[0] = 1.0 gen = make_convolve(:filter, v0) gen1 = make_convolve(:filter, v01) n = n1 = -1 print_and_check(gen, "convolve", "convolve size: 64") unless convolve?(gen) snd_display("%s not convolve?", gen) end genx = gen1 unless genx.eql?(gen1) snd_display("convolve %s.eql?(%s)", genx, gen1) end if gen.eql?(gen1) snd_display("convolve %s.eql?(%s)", gen, gen1) end if mus_length(gen) != 64 snd_display("convolve fft len: %s?", mus_length(gen)) end 128.times do |i| v2[i] = convolve(gen, lambda do |dir| n += 1 v1[n] end) end v21.map! do |x| if convolve?(gen1) convolve(gen1, lambda do |dir| n1 += 1 v11[n1] end) else -1.0 end end unless vequal(v2, v21) snd_display("run gran: %s %s?", v2, v21) end if fneq(v2[0], 0.0) or fneq(v2[1], 1.0) or fneq(v2[4], 0.25) or fneq(v2[7], 0.143) snd_display("convolve output: %s?", v2) end convolve_files("oboe.snd", "fyow.snd", 0.5, "fmv.snd") if fneq(res = mus_sound_maxamp("fmv.snd")[1], 0.5) snd_display("convolve_files: %s != 0.5?", res) end # ind = new_sound("fmv.snd") set_sample(1, 0.1) save_sound(ind) if edits(ind, 0) != [0, 0] snd_display("weird: edits not cleared after save_sound: %s?", edits(ind, 0)) end close_sound(ind) ind = open_sound("fmv.snd") if framples(ind, 0) != 2 snd_display("save_sound 2 samps: %s?", framples(ind, 0)) end if fneq(sample(0), 0.0) or fneq(sample(1), 0.1) snd_display("save_sound: %s %s?", sample(0), sample(1)) end 3.upto(5) do |i| set_sample(i, i * 0.1) save_sound(ind) if edits(ind, 0) != [0, 0] snd_display("weird: edits not cleared after save_sound %s: %s?", i, edits(ind, 0)) end close_sound(ind) ind = open_sound("fmv.snd") if framples(ind, 0) != i + 1 snd_display("save_sound %s samps: %s?", i + 1, framples(ind, 0)) end if fneq(sample(0), 0.0) or fneq(sample(1), 0.1) or fneq(sample(i), i * 0.1) snd_display("save_sound %s: %s %s %s?", i, sample(0), sample(1), sample(i)) end end close_sound(ind) # ind = new_sound("test.snd", :srate, 22050, :channels, 1, :size, 1000) gen = make_ssb_am(100.0) map_channel(lambda do |y| ssb_am(gen, 0.0) end) if fneq(maxamp, 0.0) snd_display("ssb_am 0.0: %s?", maxamp) end gen1 = make_oscil(220.0) map_channel(lambda do |y| 0.5 * oscil(gen1) end) gen = make_ssb_am(100.0, 100) map_channel(lambda do |y| ssb_am(gen, y) end) delete_samples(0, 200) gen1 = make_oscil(320.0, :initial_phase, asin(2.0 * sample(0))) map_channel(lambda do |y| y - 0.5 * oscil(gen1) end) if maxamp > 0.004 snd_display("ssb_am cancelled: %s?", maxamp) end undo_edit(3) gen = make_ssb_am(100.0, 100) map_channel(lambda do |y| ssb_am(gen, y, hz2radians(50.0)) end) delete_samples(0, 180) if defined? asin gen1 = make_oscil(370.0, :initial_phase, asin(2.0 * sample(0))) map_channel(lambda do |y| y - 0.5 * oscil(gen1) end) if maxamp > 0.004 snd_display("ssb_am fm cancelled: %s?", maxamp) end end close_sound(ind) # ind = new_sound("test.snd", :srate, 22050, :channels, 1, :size, 1000) ctr = 0 map_channel(lambda do |y| val = sin((TWO_PI * ctr) / 50) ctr += 1 val end) ssb_bank(441, 882, 1, 100) delete_samples(0, 217) if defined? asin gen1 = make_oscil(882.0, :initial_phase, asin(sample(0))) map_channel(lambda do |y| y - oscil(gen1) end) if maxamp > 0.04 snd_display("ssb_bank cancelled: %s?", maxamp) end end close_sound(ind) # nind = new_sound("fmv.snd", 1, 22050, Mus_bshort, Mus_aifc, "this is a comment") with_time("fm_violin_1(0, 1, 440, 0.1)") do fm_violin_1(0, 1, 440, 0.1) end play(nind, :wait, true) save_sound(nind) unless sound?(nind) snd_display("save_sound clobbered %s?", nind) end oboe_index = (find_sound("oboe.snd") or open_sound("oboe.snd")) if oboe_index == nind snd_display("find_sound found bogus case: %s (%s)?", oboe_index, nind) end cnvtest(oboe_index, nind, 0.1) select_sound(nind) select_channel(0) if selected_sound != nind snd_display("selected_sound: %s (%s)?", selected_sound, nind) end if selected_channel != 0 snd_display("selected_channel: %s?", selected_channel) end jc_reverb_1(1.0, false, 0.1, false) play(nind, :wait, true) voiced2unvoiced(1.0, 256, 2.0, 2.0) pulse_voice(80, 20.0, 1.0, 1024, 0.01) map_chan(fltit) close_sound(oboe_index) unless sound?(nind) snd_display("close_sound clobbered %s?", nind) end fr = framples(nind, 0) 10.times do delete_samples(10, 100, nind, 0) save_sound(nind) end if framples(nind, 0) != fr - 1000 snd_display("delete_samples: %s %s?", fr, framples(nind, 0)) end revert_sound(nind) close_sound(nind) delete_file("fmv.snd") nind = new_sound("fmv.snd") if (res1 = header_type(nind)) != (res2 = default_output_header_type) snd_display("new_sound default header_type: %s %s?", mus_header_type_name(res1), mus_header_type_name(res2)) end if (res1 = sample_type(nind)) != (res2 = default_output_sample_type) snd_display("new_sound default sample_type: %s %s?", mus_sample_type_name(res1), mus_sample_type_name(res2)) end if (res1 = channels(nind)) != (res2 = default_output_chans) snd_display("new_sound default chans: %s %s?", res1, res2) end if (res1 = srate(nind)) != (res2 = default_output_srate) snd_display("new_sound default srate: %s %s?", res1, res2) end close_sound(nind) delete_file("fmv.snd") end def test_08_19 nind = new_sound("fmv.snd", 1, 22050, Mus_bshort, Mus_nist, "this is a comment") set_sample(0, 1.0, nind) start_progress_report(nind) convolve_with("oboe.snd") progress_report(0.1, nind) if fneq(sample(1000), 0.223) snd_display("convolve_with: %s?", sample(1000)) end progress_report(0.3, nind) revert_sound(nind) progress_report(0.5, nind) set_sample(200, 0.0001) set_sample(100, 1.0) progress_report(0.8, nind) smooth_sound(0, 100) finish_progress_report(nind) if fneq(sample(50), 0.5) or fneq(sample(30), 0.20608) or fneq(sample(90), 0.9755) snd_display("smooth: %s %s %s?", sample(50), sample(30), sample(90)) end undo_edit old_sw = sinc_width set_sinc_width(40) set_sample(100, 0.5) if fneq(sample(100), 0.5) snd_display("set_sample(100): %s?", sample(100)) end src_sound(0.1) if fneq(sample(1000), 0.5) or fneq(sample(1024), 0.0625) or fneq(sample(1010), 0.0) snd_display("src_sound: %s %s %s?", sample(100), sample(1024), sample(1010)) end set_sinc_width(old_sw) revert_sound(nind) close_sound(nind) # nind = new_sound("fmv.snd", 1, 22050, Mus_lshort, Mus_riff, "this is a comment", 22050) if framples(nind) != 22050 snd_display("new_sound initial_length: %s?", framples(nind)) end mix("pistol.snd") map_chan(expsrc(2.0, nind)) undo_edit eds = edits if eds[0] != 1 or eds[1] != 1 snd_display("undo edits: %s?", eds) end if edit_position != eds[0] snd_display("undo edit_position: %s %s?", edit_position, eds) end expsnd([0, 1, 2, 0.4]) map_chan(comb_chord(0.95, 100, 0.3)) map_chan(formants(0.99, 900, 0.02, 1800, 0.01, 2700)) map_chan(moving_formant(0.99, [0, 1200, 1, 2400])) scale_to(0.3) eds = edits if eds[0] != 6 or eds[1] != 0 snd_display("edits(6): %s?", eds) end if edit_position != eds[0] snd_display("edit_position(6): %s %s?", edit_position, eds) end set_edit_position(1) if edit_position != 1 snd_display("set_edit_position(1): %s?", edit_position) end set_edit_position(4) if edit_position != 4 snd_display("set_edit_position(4): %s?", edit_position) end revert_sound(nind) mix("pistol.snd") map_chan(zecho(0.5, 0.75, 6, 10.0), 0, 65000) map_chan(am(440)) add_mark(1200) add_mark(2300) key(key_to_int(?x), 4) key(key_to_int(?c), 0) # trigger mark_define_region reverse_sound(nind) revert_sound(nind) mid = mix_sound("pistol.snd", 0).car if mix?(mid) and mix_home(mid) != [selected_sound, 0, false, 0] snd_display("mix_sound mix_home: %s (%s or %s 0)?", mix_home(mid), selected_sound, nind) end hello_dentist(40.0, 0.1) fp(1.0, 0.3, 20) revert_sound(nind) enveloped_mix("oboe.snd", 0, [0, 0, 1, 1, 2, 0]) pvoc(:pitch, 0.5, :time, 1.0, :snd, nind) revert_sound(nind) close_sound(nind) end def test_08_20 make_mix_output = lambda do |name, i| if i == 0 or i == 1 name else continue_sample2file(name) end end make_mix_input = lambda do |name, i| if i == 0 or i == 2 name else make_file2frample(name) end end end def test_08_21 Snd.sounds.apply(:close_sound) gen = make_phase_vocoder(false, 512, 4, 256, 1.0, false, false, false) if fneq((res = Snd.catch do phase_vocoder(gen) end).first, 0.0) snd_display("simple no-in pv call: %s", res.inspect) end if (res = Snd.catch do gen = make_phase_vocoder(:fft_size, 1234) end).first != :out_of_range snd_display("pv bad fft: %s?", res.inspect) end ind = open_sound("oboe.snd") rd = make_sampler(0) pv = make_phase_vocoder(lambda do |dir| next_sample(rd) end, 512, 4, 128, 1.0, false, false, false) unless phase_vocoder?(pv) snd_display("%s not phase_vocoder?", pv) end print_and_check(pv, "phase-vocoder", "phase-vocoder outctr: 128, interp: 128, filptr: 0, N: 512, D: 128, in_data: nil") pv = make_phase_vocoder set_mus_location(pv, 120) if (res = mus_location(pv)) != 120 snd_display("pv set outctr: %s?", res) end select_sound(ind) map_chan(lambda do |val| phase_vocoder(pv) end) phase_vocoder_amp_increments(pv)[0] = 0.1 if fneq(res = phase_vocoder_amp_increments(pv)[0], 0.1) snd_display("set_phase_vocoder_amp_increments: %s?", res) end phase_vocoder_amps(pv)[0] = 0.1 if fneq(res = phase_vocoder_amps(pv)[0], 0.1) snd_display("set_phase_vocoder_amps: %s?", res) end phase_vocoder_phases(pv)[0] = 0.1 if fneq(res = phase_vocoder_phases(pv)[0], 0.1) snd_display("set_phase_vocoder_phases: %s?", res) end phase_vocoder_phase_increments(pv)[0] = 0.1 if fneq(res = phase_vocoder_phase_increments(pv)[0], 0.1) snd_display("set_phase_vocoder_phase_increments: %s?", res) end phase_vocoder_freqs(pv)[0] = 0.1 if fneq(res = phase_vocoder_freqs(pv)[0], 0.1) snd_display("set_phase_vocoder_freqs: %s?", res) end undo_edit(1) free_sampler(rd) # lastphases = make_vct(512) rd = make_sampler(0) pv = make_phase_vocoder(lambda do |dir| next_sample(rd) end, 512, 4, 128, 1.0, false, lambda do |v| n = mus_length(v) d = mus_hop(v) freqs = phase_vocoder_freqs(v) pscl = 1.0 / d kscl = TWO_PI / n (n / 2).times do |k| phasediff = freqs[k] - lastphases[k] lastphases[k] = freqs[k] if phasediff > PI phasediff -= TWO_PI else if phasediff < -PI phasediff += TWO_PI end end freqs[k] = 0.5 * (pscl * phasediff + k * kscl) end false end, false) map_chan(lambda do |val| phase_vocoder(pv) end) undo_edit(1) free_sampler(rd) # rd = make_sampler(0) pv = make_phase_vocoder(lambda do |dir| next_sample(rd) end, 512, 4, 128 * 2, 1.0, false, false, false) len = 1000 data = make_vct!(len) do phase_vocoder(pv) end set_samples(0, len, data) undo_edit(1) free_sampler(rd) # incalls = outcalls = 0 rd = make_sampler(0) pv = make_phase_vocoder(lambda do |dir| next_sample(rd) end, 512, 4, (128 * 2.0).to_i, 1.0, lambda do |v, infunc| incalls += 1 true end, false, lambda do |v| outcalls += 1 0.0 end) len = 1000 data = make_vct!(len) do phase_vocoder(pv) end set_samples(0, len, data) undo_edit(1) free_sampler(rd) if incalls.zero? or outcalls.zero? snd_display("phase_vocoder incalls: %s, outcalls: %s?", incalls, outcalls) end set_mus_location(pv, mus_location(pv)) if (res = Snd.catch do make_phase_vocoder(false, 512, 4, 256, 1.0, lambda do |a, b, c| false end, false, false) end).first != :bad_arity snd_display("make_phase_vocoder bad analyze func: %s", res.inspect) end if (res = Snd.catch do make_phase_vocoder(false, 512, 4, 256, 1.0, lambda do |a, b| 0.0 end, lambda do |a, b, c| false end, false) end).first != :bad_arity snd_display("make_phase_vocoder bad edit func: %s", res.inspect) end if (res = Snd.catch do make_phase_vocoder(false, 512, 4, 256, 1.0, lambda do |a, b| 0.0 end, lambda do |a| false end, lambda do |a, b| 0 end) end).first != :bad_arity snd_display("make_phase_vocoder bad synthesize func: %s", res.inspect) end geno = make_phase_vocoder(lambda do |dir| 0.0 end) genx = make_phase_vocoder(:input, lambda do |dir| 0.0 end) if geno.eql?(genx) snd_display("phase_vocoder %s.eql?(%s)?", geno, genx) end if fneq(genx.frequency, 1.0) snd_display("mus_frequency phase_vocoder: %s?", genx.frequency) end set_mus_frequency(genx, 2.0) if fneq(genx.frequency, 2.0) snd_display("set_mus_frequency phase_vocoder: %s?", genx.frequency) end if genx.increment != 128 snd_display("mus_increment phase_vocoder: %s?", genx.increment) end set_mus_increment(genx, 256) if genx.increment != 256 snd_display("set_mus_increment phase_vocoder: %s?", genx.increment) end if genx.hop != 128 snd_display("mus_hop phase_vocoder: %s?", genx.hop) end set_mus_hop(genx, 64) if genx.hop != 64 snd_display("set_mus_hop phase_vocoder: %s?", genx.hop) end if genx.length != 512 snd_display("mus_length phase_vocoder: %s?", genx.length) end genxx = genx unless genx.eql?(genxx) snd_display("phase_vocoder %s.eql?(%s)?", genxx, genx) end close_sound(ind) end def test_08_22 ind = open_sound("oboe.snd") gen = make_moog_filter(500.0, 0.1) if fneq(gen.frequency, 500.0) snd_display("moog freq: %s?", gen.frequency) end if fneq(gen.Q, 0.1) snd_display("moog Q: %s?", gen.Q) end unless vct?(gen.state) snd_display("moog state: %s?", gen.state) end if fneq(gen.A, 0.0) snd_display("moog A: %s?", gen.A) end if fneq(gen.freqtable, -0.861) snd_display("moog freqtable: %s?", gen.freqtable) end vals = make_vct!(20) do |i| moog_filter(gen, i.zero? ? 1.0 : 0.0) end unless vequal(vals, vct(0.0, 0.0, 0.0025, 0.0062, 0.0120, 0.0198, 0.0292, 0.0398, 0.0510, 0.0625, 0.0739, 0.0847, 0.0946, 0.1036, 0.1113, 0.1177, 0.1228, 0.1266, 0.1290, 0.1301)) snd_display("moog output: %s?", vals) end close_sound(ind) # gen = make_ssb_am(440.0) gen1 = make_ssb_am(440.0) print_and_check(gen, "ssb-am", "ssb-am shift: up, sin/cos: 439.999975 Hz (0.000000 radians), order: 41", "ssb-am shift: up, sin/cos: 440.000000 Hz (0.000000 radians), order: 41", "ssb-am shift: up, sin/cos: 439.999969 Hz (0.000000 radians), order: 41") v0 = make_vct!(10) do ssb_am(gen, 0.0) end v1 = make_vct(10) v1.map! do |x| ssb_am?(gen1) ? ssb_am(gen1, 0.0) : -1.0 end unless vequal(v0, v1) snd_display("map ssb_am: %s %s?", v0, v1) end unless ssb_am?(gen) snd_display("%s not ssb_am?", gen) end if fneq(gen.phase, 1.253787) snd_display("ssb_am phase: %s?", gen.phase) end if fneq(gen.frequency, 440.0) snd_display("ssb_am frequency: %s?", gen.frequency) end if gen.order != 41 snd_display("ssb_am order: %s?", gen.order) end if gen.length != 41 snd_display("ssb_am length: %s?", gen.length) end if gen.interp_type != Mus_interp_none snd_display("ssb_am interp_type: %s?", gen.interp_type) end if fneq(gen.xcoeff(0), -0.00124) snd_display("ssb_am xcoeff 0: %s?", gen.xcoeff(0)) end if fneq(gen.xcoeff(1), 0.0) snd_display("ssb_am xcoeff 1: %s?", gen.xcoeff(1)) end # test_gen_equal(make_ssb_am(440.0), make_ssb_am(440.0), make_ssb_am(500.0)) # o1 = make_ssb_am(400.0) o2 = make_ssb_am_1(400.0) 100.times do |i| inval = sin(0.1 * i) req = ssb_am(o1, inval) res = ssb_am_1(o2, inval) if snd_test_neq(res, req, "ssb_am (up) at %d", i) break end end # o1 = make_ssb_am(400.0) o2 = make_ssb_am_1(400.0) 100.times do |i| inval = sin(0.1 * i) fmval = sin(0.2 * i) req = ssb_am(o1, inval, fmval) res = ssb_am_1(o2, inval, fmval) if snd_test_neq(res, req, "ssb_am + fm (up) at %d", i) break end end # o1 = make_ssb_am(-100.0) o2 = make_ssb_am_1(-100.0) 100.times do |i| inval = random(1.0) req = ssb_am(o1, inval) res = ssb_am_1(o2, inval) if snd_test_neq(res, req, "ssb_am (down) at %d", i) break end end # o1 = make_ssb_am(1000.0, 100) o2 = make_ssb_am_1(1000.0, 100) 100.times do |i| inval = random(1.0) req = ssb_am(o1, inval) res = ssb_am_1(o2, inval) if snd_test_neq(res, req, "ssb_am (down) at %d", i) break end end # index = open_sound("pistol.snd") data = channel2vct(0, 100) convolve_with("oboe.snd", false) scl = maxamp convolve_with("oboe.snd", scl, index, 0, 0) snd_test_any_neq(maxamp, scl, :ffequal?, "convolve_with amps") close_sound(index) reader = make_sampler(0, "pistol.snd") 10.times do |i| snd_test_neq(data[i], next_sample(reader), "external reader trouble") end free_sampler(reader) # gen = make_moving_max(4) iv = vct(0.1, 0.05, -0.2, 0.15, -1.5, 0.1, 0.01, 0.001, 0.0, 0.0) tv = vct(0.1, 0.1, 0.2, 0.2, 1.5, 1.5, 1.5, 1.5, 0.1, 0.01) ov = Vct.new(10) do |i| moving_max(gen, iv[i]) end snd_test_neq(ov, tv, "moving_max") g1 = make_moving_max(10) 1000.times do |i| snd_test_neq(moving_max(g1, random(1.0)), g1.data.peak, "moving_max[%d]", i) end # data = vct(1, 0, -1.1, 1.1001, 0.1, -1.1, 1, 1, 0.5, -0.01, 0.02, 0, 0, 0, 0) g = make_moving_max(3) odata = Vct.new(15) do |i| moving_max(g, data[i]) end req = vct(1, 1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1, 1, 0.5, 0.02, 0.02, 0, 0) snd_test_neq(odata, req, "moving_max") if odata[4] == odata[7] snd_test_eq(odata[4], odata[7], "moving_max 0.0001 offset") end # data = vct(0.1, -0.2, 0.3, 0.4, -0.5, 0.6, 0.7, 0.8, -0.9, 1.0, 0.0, 0.0) g = make_moving_sum(3) odata = Vct.new(15, 0.0) data.each_with_index do |x, i| odata[i] = moving_sum(g, x) end req = vct(0.1, 0.3, 0.6, 0.9, 1.2, 1.5, 1.8, 2.1, 2.4, 2.7, 1.9, 1, 0, 0, 0) snd_test_neq(odata, req, "moving_sum") # g = make_moving_rms(4) odata = Vct.new(15, 0.0) data.each_with_index do |x, i| odata[i] = moving_rms(g, x) end req = vct(0.05, 0.112, 0.187, 0.274, 0.367, 0.464, 0.561, 0.66, 0.758, 0.857, 0.783, 0.673, 0, 0, 0) snd_test_neq(odata, req, "moving_rms") # g = make_moving_length(4) odata = Vct.new(15, 0.0) data.each_with_index do |x, i| odata[i] = moving_length(g, x) end req = vct(0.1, 0.224, 0.374, 0.548, 0.735, 0.927, 1.122, 1.319, 1.517, 1.715, 1.565, 1.345, 0, 0, 0) snd_test_neq(odata, req, "moving_length") # 10.times do |i| data[i] = mus_random(0.5) end g = make_moving_length(4) data.each_with_index do |x, i| odata[i] = moving_length(g, x) end k = 0 (-3..8).each do |i| sum = 0.0 4.times do |j| if i + j >= 0 sum += data[i + j] * data[i + j] end end snd_test_neq(odata[k], sqrt(sum), "moving_length ran") k += 1 end # 10.times do |i| data[i] = mus_random(0.5) end g = make_moving_sum(4) data.each_with_index do |x, i| odata[i] = moving_sum(g, x) end k = 0 (-3..8).each do |i| sum = 0.0 4.times do |j| if i + j >= 0 sum += data[i + j].abs end end snd_test_neq(odata[k], sum, "moving_sum ran") k += 1 end # 10.times do |i| data[i] = mus_random(0.5) end g = make_moving_rms(4) data.each_with_index do |x, i| odata[i] = moving_rms(g, x) end k = 0 (-3..8).each do |i| sum = 0.0 4.times do |j| if i + j >= 0 sum = sum + data[i + j] * data[i + j] end end snd_test_neq(odata[k], sqrt(sum / 4.0), "moving_rms ran") k += 1 end # ind = open_sound("oboe.snd") harmonicizer(550.0, [1, 0.5, 2, 0.3, 3, 0.2], 10) close_sound(ind) # argslist = make_array(16) do [:frequency, 440.0] end.flatten [:make_wave_train, :make_polyshape, :make_delay, :make_moving_average, :make_comb, :make_filtered_comb, :make_notch, :make_rand, :make_rand_interp, :make_table_lookup, :make_env, :make_readin, :make_locsig, :make_granulate, :make_convolve, :make_phase_vocoder].each do |make| res = Snd.catch do argslist.apply(:snd_func, make) end if res.first != :mus_error snd_display("long arglist to %s: %s", make, res.inspect) end end # [[:table_lookup, [:wave]], [:wave_train, [:wave]], [:polyshape, [:coeffs]], [:delay, [:initial_contents]], [:filtered_comb, [:scaler, 0.5, :filter, make_one_zero(0.1, 0.2), :initial_contents]], [:rand, [:distribution]], [:fir_filter, [:xcoeffs]], [:iir_filter, [:ycoeffs]]].each do |name, args| v1 = Vct.new(10, 0.1) g1 = snd_func("make_" + name.to_s, *args + [v1]) case name when :fir_filter if g1.xcoeffs != v1 snd_display("%s data !=: %s %s?", name, g1.xcoeffs, v1) end v1[1] = 0.3 if fneq(g1.xcoeffs[1], 0.3) snd_display("%s vct_set!: %s %s?", name, v1[1], g1.xcoeffs[1]) end g1.xcoeffs[1] = 0.5 if fneq(v1[1], 0.5) snd_display("%s set_data: %s %s?", name, v1[1], g1.xcoeffs[1]) end when :iir_filter if g1.ycoeffs != v1 snd_display("%s data !=: %s %s?", name, g1.ycoeffs, v1) end v1[1] = 0.3 if fneq(g1.ycoeffs[1], 0.3) snd_display("%s vct_set!: %s %s?", name, v1[1], g1.ycoeffs[1]) end g1.ycoeffs[1] = 0.5 if fneq(v1[1], 0.5) snd_display("%s set_data: %s %s?", name, v1[1], g1.ycoeffs[1]) end else if g1.data != v1 snd_display("%s data !=: %s %s?", name, g1.data, v1) end v1[1] = 0.3 if fneq(g1.data[1], 0.3) snd_display("%s vct_set!: %s %s?", name, v1[1], g1.data[1]) end g1.data[1] = 0.5 if fneq(v1[1], 0.5) snd_display("%s set_data: %s %s?", name, v1[1], g1.data[1]) end end end end def test_08_23 [[:all_pass, false, 0.0, false], [:asymmetric_fm, false, 0.0, false], [:moving_average, false, 1.0, false], [:comb, false, 0.0, false], [:convolve, [:filter, vct(0, 1, 2)], lambda { |dir| 0.0 }, false], [:delay, false, 0.0, false], [:env, [:length, 11, :envelope, [0, 1, 1, 0]], false, false], [:filter, [:xcoeffs, vct(0, 1, 2)], 0.0, false], [:filter, [:ycoeffs, vct(0, 1, 2)], 0.0, false], [:filter, [:xcoeffs, vct(1, 2, 3), :ycoeffs, vct(0, 1, 2)], 0.0, false], [:fir_filter, [:xcoeffs, vct(0, 1, 2)], 0.0, false], [:formant, false, 0.0, false], [:granulate, false, lambda { |dir| 0.0 }, false], [:iir_filter, [:ycoeffs, vct(0, 1, 2)], 0.0, false], [:locsig, false, 0.0, lambda { |gen, a| locsig(gen, 0, a) }], [:notch, false, 0.0, false], [:one_pole, false, 0.0, false], [:one_zero, false, 0.0, false], [:oscil, false, 0.0, false], [:pulse_train, false, 0.0, false], [:rand, false, 0.0, false], [:rand_interp, false, 0.0, false], [:sawtooth_wave, false, 0.0, false], [:square_wave, false, 0.0, false], [:src, false, lambda { |dir| 0.0 }, lambda { |gen, a| src(gen, 0.0, a) }], [:table_lookup, false, 0.0, false], [:triangle_wave, false, 0.0, false], [:two_pole, false, 0.0, false], [:two_zero, false, 0.0, false], [:wave_train, false, 0.0, false], [:polyshape, false, 0.0, false], [:phase_vocoder, false, lambda { |dir| 0.0 }, false], [:ssb_am, false, 0.0, false]].each do |name_sym, make_args, arg, run_func| gen = if make_args snd_func(format("make_%s", name_sym), *make_args) else snd_func(format("make_%s", name_sym)) end unless snd_func(format("%s%c", name_sym, ??), gen) snd_display("%s: %s?", name_sym, gen) end tag = if proc?(run_func) Snd.catch do arg ? run_func.call(gen, arg) : run_func.call(gen) end.first else Snd.catch do arg ? snd_func(name_sym, gen, arg) : snd_func(name_sym, gen) end.first end if (not number?(tag)) and (not frame?(tag)) snd_display("%s (make_gen, gen, gen? test): %s %s?", name_sym, arg, tag) end [:mus_channel, :mus_channels, :mus_data, :mus_feedback, :mus_feedforward, :mus_frequency, :mus_hop, :mus_increment, :mus_length, :mus_location, :mus_order, :mus_phase, :mus_ramp, :mus_random, :mus_run, :mus_scaler, :mus_xcoeffs, :mus_ycoeffs].each do |func_sym| if (res = Snd.catch do snd_func(func_sym, false) end).first != :wrong_type_arg snd_display("generic function with false: %s.%s(false) -> %s", name_sym, func_sym, res.inspect) end g1 = make_oscil g2 = make_one_pole(0.1, 0.9) res = Snd.catch do snd_func(func_sym, g1) end if symbol?(res) and res != :wrong_type_arg and res != :mus_error snd_display("generic %s of oscil: %s", name_sym, res.inspect) end res = Snd.catch do snd_func(func_sym, g2) end if symbol?(res) and res != :wrong_type_arg and res != :mus_error snd_display("generic %s of delay: %s", name_sym, res.inspect) end tag = Snd.catch do snd_func(func_sym, gen) end.first if (not symbol?(tag)) and tag != :mus_error and tag != :out_of_range and tag != :wrong_type_arg and (func_sym != :mus_data or vct?(tag)) set_tag = Snd.catch do set_snd_func(func_sym, gen, tag) end.first if symbol?(set_tag) and set_tag != :mus_error and set_tag != :out_of_range and set_tag != :wrong_type_arg and set_tag != :no_method_error snd_display("%s.%s= tag: %s set_tag: %s?", name_sym, func_sym.to_s[4..-1], tag.inspect, set_tag.inspect) end end end end # functions = [ [:all_pass, false, false], [:asymmetric_fm, false, false], [:moving_average, false, false], [:comb, false, false], [:filtered_comb, [:filter, make_one_zero(0.5, 0.5)], false], [:convolve, [:filter, vct(0, 1, 2), :input, lambda { |dir| 1.0 }], false], [:delay, false, false], [:env, [:envelope, [0, 1, 1, 0], :length, 11], lambda { |gen, ignored| env(gen) }], [:filter, [:xcoeffs, vct(0, 1, 2)], false], [:filter, [:ycoeffs, vct(0, 1, 2)], false], [:filter, [:xcoeffs, vct(1, 2, 3), :ycoeffs, vct(0, 1, 2)], false], [:fir_filter, [:xcoeffs, vct(0, 1, 2)], false], [:formant, [:radius, 0.1, :frequency, 440.0], false], [:granulate, [:input, lambda { |dir| 1.0 }], false], [:iir_filter, [:xcoeffs, vct(0, 1, 2)], false], [:locsig, false, lambda { |gen, a| locsig(gen, 0, 1.0) }], [:notch, false, false], [:one_pole, [0.3, 0.7], false], [:one_zero, [0.5, 0.5], false], [:oscil, false, false], [:pulse_train, false, false], [:sawtooth_wave, false, false], [:square_wave, false, false], [:table_lookup, [:wave, make_vct(128, 0.1)], false], [:triangle_wave, false, false], [:two_pole, [0.1, 0.3, 0.6], false], [:two_zero, [0.1, 0.3, 0.5], false], [:polyshape, [:frequency, 440.0, :partials, [1, 1]], false], [:phase_vocoder, [lambda { |dir| 1.0 }], false], [:ssb_am, false, false]] functions.each do |name_sym, make_args, run_func| gen = if make_args snd_func(format("make_%s", name_sym), *make_args) else snd_func(format("make_%s", name_sym)) end data = make_vct!(10) do |i| if proc?(run_func) run_func.call(gen, i.zero? ? 1.0 : 0.0) else snd_func(name_sym, gen, i.zero? ? 1.0 : 0.0) end end 2.times do |k| mus_reset(gen) unless proc?(run_func) not_zero = false first_val = k.zero? ? snd_func(name_sym, gen, 1.0) : mus_apply(gen, 1.0, 0.0) if data[0] != 0.0 not_zero = true end if fneq(data[0], first_val) snd_display("[%s] %s: 0 %s %s?", k.zero? ? :run : :apply, name_sym, data[0], first_val) end (1...10).each do |i| old_val = data[i] new_val = k.zero? ? snd_func(name_sym, gen, 0.0) : mus_apply(gen, 0.0, 0.0) if old_val != 0.0 not_zero = true end if fneq(old_val, new_val) snd_display("[%s] %s: %s %s %s?", k.zero? ? :run : :apply, name_sym, i, old_val, new_val) end end unless not_zero case name_sym when :polyshape, :ssb_am next else snd_display("%s not much of a reset test!", name_sym) end end end end end random_args = [1.5, "/hiho", [0, 1], 1234, make_vct(3), make_color_with_catch(0.95, 0.95, 0.95), :mus_error, sqrt(-1.0), make_delay(32), lambda do || true end, 0, 1, -1, make_hook("snd_test"), false, true, 0.0, 1.0, -1.0, [], 3, 4, 2, 8, 16, 32, 64, 2.0 ** 21.5, 2.0 ** -18.0] functions.each do |name_sym, make_args, run_func| gen = if make_args snd_func(format("make_%s", name_sym), *make_args) else snd_func(format("make_%s", name_sym)) end random_args.each do |arg1| Snd.catch do if proc?(run_func) run_func.call(gen, arg1) else snd_func(name_sym, gen, arg1) end end random_args.each do |arg2| Snd.catch do mus_run(gen, arg1, arg2) end end end end end def test_08_24 random_args = [ 2.0 ** 21.5, 2.0 ** -18.0, 1.5, "/hiho", [0, 1], 1234, make_vct(3), make_color_with_catch(0.1, 0.2, 0.3), [0, 1], Rational(3, 4), Complex(0, 1), #sqrt(-1.0), make_delay(32), lambda do || 0.0 end, lambda do |dir| 1.0 end, lambda do |a, b, c| 1.0 end, 0, 1, -1, false, true, key_to_int(?c), 0.0, 1.0, -1.0, [], 32, [1, 2]] random_gen = lambda do |*args| [:make_all_pass, :make_asymmetric_fm, :make_moving_average, :make_moving_max, :make_moving_norm, :make_table_lookup, :make_triangle_wave, :make_comb, :make_delay, :make_env, :make_fft_window, :make_filter, :make_filtered_comb, :make_fir_filter, :make_formant, :make_iir_filter, :make_locsig, :make_notch, :make_one_pole, :make_one_pole_all_pass, :make_one_zero, :make_oscil, :make_pulse_train, :make_rand, :make_rand_interp, :make_sawtooth_wave, :make_polyshape, :make_polywave, :make_square_wave, :make_two_pole, :make_two_zero, :make_wave_train, :make_ssb_am].each do |make_func| gen = Snd.catch do snd_func(make_func, *args) end.first if mus_generator?(gen) random_args.each do |arg| Snd.catch do gen.call(arg) end end end end end random_gen.call() random_args.each do |arg1| random_gen.call(arg1) random_args.each do |arg2| random_gen.call(arg1, arg2) if $all_args or $bigtest_08 random_args.each do |arg3| random_gen.call(arg1, arg2, arg3) if $bigtest_08 random_args.each do |arg4| random_gen.call(arg1, arg2, arg3, arg4) end end end end end end end def test_08 test_08_00 test_08_01 test_08_02 test_08_03 test_08_04 test_08_05 test_08_06 test_08_08 test_08_09 test_08_10 test_08_11 test_08_12 test_08_13 test_08_14 test_08_15 test_08_16 test_08_17 test_08_18 test_08_19 test_08_20 test_08_21 test_08_22 test_08_23 test_08_24 end # ---------------- test 09: mix ---------------- def test_09_00 new_index = new_sound("hiho.wave", 1, 22050, Mus_bshort, Mus_next) select_sound(new_index) if res = find_mix(0, new_index, 0) snd_display("found non-existent mix: %s?", res) end unless mix?(mix_id = mix("pistol.snd", 100).car) snd_display("%s not mix?", mix_id) end view_mixes_dialog pos = mix_position(mix_id) len = mix_length(mix_id) spd = mix_speed(mix_id) snd, chn = mix_home(mix_id)[0, 2] nam = mix_name(mix_id) amp = mix_amp(mix_id) mr = make_mix_sampler(mix_id) unless mix_sampler?(mr) snd_display("%s not mix_sampler?", mr) end if region_sampler?(mr) snd_display("mix_sampler: region %s?", mr) end if (res = sampler_position(mr)).nonzero? snd_display("mix_sampler_position: %s?", res) end if sampler_at_end?(mr) snd_display("mix_sampler at end? %s", mr) end unless (res = sampler_home(mr)).eql?(mix_id) snd_display("%s home: %s?", sampler_home(mr), res) end if mr.to_s[0, 16] != "#1: %s %s?", samps, v) end unless mix?(tag) snd_display("mix 1->1 tag: %s?", tag) end undo_edit tag = mix("test.snd", 5).car samps = channel2vct(0, 20) v = make_vct(20) v[7] = 0.5 v[10] = 0.25 unless vequal(samps, v) snd_display("mix 1->1 at 5: %s %s?", samps, v) end unless mix?(tag) snd_display("mix 1->1 at 5 tag: %s?", tag) end undo_edit tag = mix("test.snd", 0, 0, ind, 0, false) samps = channel2vct(0, 20) v = make_vct(20) v[2] = 0.5 v[5] = 0.25 unless vequal(samps, v) snd_display("mix 1->1 at 0: %s %s?", samps, v) end if mix?(tag) snd_display("mix 1->1 at 0 tag: %s?", tag) end undo_edit indout = new_sound("test.snd", 2, 22050, Mus_bshort, Mus_next, "mix tests") insert_silence(0, 10, indout, 0) insert_silence(0, 10, indout, 1) set_sample(2, 0.5, indout, 0) set_sample(5, 0.25, indout, 0) set_sample(2, 0.95, indout, 1) set_sample(5, 0.125, indout, 1) save_sound(indout) close_sound(indout) tag = mix("test.snd", 0, 1).car samps = channel2vct(0, 20) v = make_vct(20) v[2] = 0.95 v[5] = 0.125 unless vequal(samps, v) snd_display("mix 2->1: %s %s?", samps, v) end unless mix?(tag) snd_display("mix 2->1 tag: %s?", tag) end undo_edit tag = mix("test.snd", 5, 1).car samps = channel2vct(0, 20) v = make_vct(20) v[7] = 0.95 v[10] = 0.125 unless vequal(samps, v) snd_display("mix 2->1 at 5: %s %s?", samps, v) end unless mix?(tag) snd_display("mix 2->1 at 5 tag: %s?", tag) end undo_edit close_sound(ind) # ind = new_sound("fmv.snd", 2, 22050, Mus_bshort, Mus_next, "mix tests") insert_silence(0, 20, ind, 0) insert_silence(0, 20, ind, 1) tag = mix("test.snd", 0, true).car samps0 = channel2vct(0, 20, ind, 0) samps1 = channel2vct(0, 20, ind, 1) v = make_vct(20) v[2] = 0.5 v[5] = 0.25 unless vequal(samps0, v) snd_display("mix 1->1 (2): %s %s?", samps0, v) end v[2] = 0.95 v[5] = 0.125 unless vequal(samps1, v) snd_display("mix 1->1 (3): %s %s?", samps1, v) end unless mix?(tag) snd_display("mix 1->1 tag: %s?", tag) end undo_edit(1, ind, 0) undo_edit(1, ind, 1) tag = mix("test.snd", 0, 1, ind, 1, false) samps0 = channel2vct(0, 20, ind, 0) samps1 = channel2vct(0, 20, ind, 1) v = make_vct(20) unless vequal(samps0, v) snd_display("mix 1->1 (4): %s %s?", samps0, v) end v[2] = 0.95 v[5] = 0.125 unless vequal(samps1, v) snd_display("mix 1->1 (5): %s %s?", samps1, v) end if mix?(tag) snd_display("mix 1->1 tag: %s?", tag) end undo_edit(1, ind, 1) set_sync(1, ind) mix("test.snd", 0, true).car samps0 = channel2vct(0, 20, ind, 0) samps1 = channel2vct(0, 20, ind, 1) v = make_vct(20) v[2] = 0.5 v[5] = 0.25 unless vequal(samps0, v) snd_display("mix 1->1 (6): %s %s?", samps0, v) end v[2] = 0.95 v[5] = 0.125 unless vequal(samps1, v) snd_display("mix 1->1 (7): %s %s?", samps1, v) end undo_edit close_sound(ind) delete_files("test.snd", "fmv.snd") # # check ripple_mixes # ind = open_sound("oboe.snd") data = channel2vct(100, 100) m1 = mix_vct(data, 321, ind, 0, true) m2 = mix_vct(data, 123, ind, 0, true) set_mix_position(m1, 500) if (res = mix_position(m1)) != 500 snd_display("mix_position m1[0]: %s?", res) end if (res = mix_position(m2)) != 123 snd_display("mix_position m2[0]: %s?", res) end undo_edit set_mix_position(m2, 500) if (res = mix_position(m2)) != 500 snd_display("mix_position m2[1]: %s?", res) end if (res = mix_position(m1)) != 321 snd_display("mix_position m1[1]: %s?", res) end undo_edit insert_silence(0, 100) if (res = mix_position(m1)) != 321 + 100 snd_display("mix_position m1[2]: %s?", res) end if (res = mix_position(m2)) != 123 + 100 snd_display("mix_position m2[2]: %s?", res) end delete_samples(0, 50) if (res = mix_position(m1)) != 321 + 50 snd_display("mix_position m1[3]: %s?", res) end if (res = mix_position(m2)) != 123 + 50 snd_display("mix_position m2[3]: %s?", res) end undo_edit(2) set_mix_position(m2, 500) undo_edit scale_channel(0.5, 1000, 100) if (res = mix_position(m2)) != 123 snd_display("mix_position m2[5]: %s?", res) end if (res = mix_position(m1)) != 321 snd_display("mix_position m1[5]: %s?", res) end undo_edit set_mix_position(m2, 500) undo_edit set_mix_position(m2, 500) undo_edit ramp_channel(0.0, 1.0, 3000, 100) if (res = Snd.catch do if (res = mix_position(m2)) != 123 snd_display("mix_position m2[7]: %s?", res) end if (res = mix_position(m1)) != 321 snd_display("mix_position m1[7]: %s?", res) end end).first snd_display("mix_position trouble: %s", res.inspect) end close_sound(ind) # # check that current console is correct # ind = open_sound("storm.snd") set_x_bounds([0, 80]) make_selection(1000000, 1050000) m1 = mix_selection(900000).car m2 = mix_selection(400000).car as_one_edit(lambda do | | set_mix_position(m1, 0) set_mix_position(m2, 1) end) if ((res1 = mix_position(m1)) != 0) or ((res2 = mix_position(m2)) != 1) snd_display("as_one_edit positions: %s %s?", res1, res2) end undo_channel if ((res1 = mix_position(m1)) != 900000) or ((res2 = mix_position(m2)) != 400000) snd_display("as_one_edit positions after undo: (%s): %s (%s): %s?", m1, res1, m2, res2) end redo_channel if (res1 = mix_position(m1)) != 0 or (res2 = mix_position(m2)) != 1 snd_display("as_one_edit positions after redo: %s %s?", res1, res2) end close_sound(ind) # ind = open_sound("2.snd") make_selection(0, 10000, ind) if (res = selection_chans) != 2 snd_display("stereo selection: %s?", res) end set_sync(true, ind) md = mix_selection(500, ind).car unless mix?(integer2mix(mix2integer(md) + 1)) snd_display("where is 2nd mix? %s %s?", md, mixes) end if (res = edit_position(ind, 0)) != 1 snd_display("edit_position 0 after stereo mix selection: %s?", res) end if (res = edit_position(ind, 1)) != 1 snd_display("edit_position 1 after stereo mix selection: %s?", res) end close_sound(ind) end def test_mix_disconnect(name, id0, chn0, id1, chn1) amp0 = mix_amp(id0) amp1 = mix_amp(id1) env0 = mix_amp_env(id0) env1 = mix_amp_env(id1) set_mix_amp(id0, mix_amp(id0) * 0.5) if fneq(mix_amp(id0), 0.5 * amp0) or fneq(mix_amp(id1), amp1) snd_display("pan_mix disconnect amp %s: %s (%s) %s (%s)?", name, mix_amp(id0), amp0, mix_amp(id1), amp1) end set_mix_amp_env(id1, [0.0, random(1.0), 1.0, random(1.0)]) if mix_amp_env(id0) != env0 or (not vequal(mix_amp_env(id1), (env1 or []))) snd_display("pan_mix disconnect amp_env %s: %s (%s) %s (%s)?", name, mix_amp_env(id0), env0, mix_amp_env(id1), env1) end if id0 != id1 pos0 = mix_position(id0) pos1 = mix_position(id1) spd0 = mix_speed(id0) spd1 = mix_speed(id1) set_mix_position(id0, pos0 + 12) if mix_position(id0) == pos0 or mix_position(id1) != pos1 snd_display("pan_mix disconnect position %s: %s (%s) %s (%s)?", name, mix_position(id0), pos0, mix_position(id1), pos1) end set_mix_speed(id1, mix_speed(id1) * 1.5) if fneq(mix_speed(id1), 1.5 * spd1) or fneq(mix_speed(id0), spd0) snd_display("pan_mix disconnect speed %s: %s (%s) %s (%s)?", name, mix_speed(id0), spd0, mix_speed(id1), spd1) end end end def test_09_03 ind = new_sound("test.snd") v = Vct.new(20) do |i| i * 0.01 end vct2channel(v) v.map! do |val| -val end mx = mix_vct(v, 10) hi = make_mix_sampler(mx, 0) ho = make_mix_sampler(mx, 5) 10.times do |i| ho_val = ho.call hi_val = hi.call if fneq(hi_val, i * -0.01) snd_display("mix_reader at %s from 0: %s?", i, hi_val) break end if fneq(ho_val, (i + 5)* -0.01) snd_display("mix_reader at %s from 5: %s?", i, ho_val) break end end revert_sound(ind) v = Vct.new(21) v.fill(0.5) vct2channel(v) mx = mix_vct(v, 10) set_mix_amp_env(mx, [0, 0, 1, 1]) hi = make_mix_sampler(mx, 0) ho = make_mix_sampler(mx, 10) 10.times do |i| ho_val = ho.call hi_val = hi.call if fneq(hi_val, i * 0.025) snd_display("mix_reader enved at %s from 0: %s?", i, hi_val) break end if fneq(ho_val, (i + 10)* 0.025) snd_display("mix_reader enved at %s from 5: %s?", i, ho_val) break end end close_sound(ind) # ind = open_sound("oboe.snd") id = mix_vct(Vct.new(10, 0.1)) set_mix_position(id, 100) if (res1 = mix_position(id)) != 100 or (res2 = edit_position(ind, 0)) != 2 snd_display("mix_position init: %s %s?", res1, res2) end set_mix_position(id, 100) if (res1 = mix_position(id)) != mix_position(id) or (res2 = edit_position(ind, 0)) != 2 snd_display("mix_position 2 (no-op): %s %s?", res1, res2) end set_mix_amp(id, 1.0) if fneq(res1 = mix_amp(id), 1.0) or (res2 = edit_position(ind, 0)) != 2 snd_display("mix_amp no-op: %s %s?", res1, res2) end set_mix_amp(id, 0.5) if fneq(res1 = mix_amp(id), 0.5) or (res2 = edit_position(ind, 0)) != 3 snd_display("mix_amp 0.5: %s %s?", res1, res2) end set_mix_amp(id, mix_amp(id)) if fneq(res1 = mix_amp(id), 0.5) or (res2 = edit_position(ind, 0)) != 3 snd_display("mix_amp no-op: %s %s?", res1, res2) end set_mix_speed(id, 1.0) if fneq(res1 = mix_speed(id), 1.0) or (res2 = edit_position(ind, 0)) != 3 snd_display("mix_speed no-op: %s %s?", res1, res2) end set_mix_speed(id, 0.5) if fneq(res1 = mix_speed(id), 0.5) or (res2 = edit_position(ind, 0)) != 4 snd_display("mix_speed 0.5: %s %s?", res1, res2) end set_mix_speed(id, mix_speed(id)) if fneq(res1 = mix_speed(id), 0.5) or (res2 = edit_position(ind, 0)) != 4 snd_display("mix_speed 2 no-op: %s %s?", res1, res2) end set_mix_amp_env(id, [0, 0, 1, 1]) if (res = edit_position(ind, 0)) != 5 snd_display("mix_amp init: %s %s?", mix_amp_env(id), res) end set_mix_amp_env(id, [0, 0, 1, 1]) if (res = edit_position(ind, 0)) != 5 snd_display("mix_amp no-op: %s %s?", mix_amp_env(id), res) end close_sound(ind) # ind = new_sound("test.snd", 1, 22050, Mus_bfloat, Mus_next, "lock mix tests", 300) mix1 = mix_vct(Vct.new(10, 0.5), 10) set_mix_amp(mix1, 0.0) if fneq(res = maxamp(ind, 0), 0.0) snd_display("delete mix maxamp: %s?", res) end undo_channel(1, ind, 0) if fneq(res = maxamp(ind, 0), 0.5) snd_display("undelete mix maxamp: %s?", res) end redo_channel(1, ind, 0) if fneq(res = maxamp(ind, 0), 0.0) snd_display("redelete mix maxamp: %s?", res) end undo_edit(2) if number?(mix?(mix1)) snd_display("undo 2 kept mix?") end if fneq(res = maxamp(ind, 0), 0.0) snd_display("no delete_mix maxamp: %s?", res) end redo_edit if fneq(res = maxamp(ind, 0), 0.5) snd_display("reundelete mix maxamp: %s?", res) end close_sound(ind) end def test_09_04 # set_with_mix_tags(true) ind = open_sound("oboe.snd") mx = mix_vct(Vct.new(100, 0.1), 1000) fr = mus_sound_framples("1a.snd") [[lambda do pad_channel(0, 100) end, 1100, false, :pad0], [lambda do pad_channel(0, 2000) end, 3000, false, :pad20], [lambda do pad_channel(800, 100) end, 1100, false, :pad800], [lambda do pad_channel(850, 100) end, 1100, false, :pad800], [lambda do pad_channel(990, 100) end, 1100, false, :pad990], [lambda do pad_channel(1010, 100) end, 1000, true, :pad1010], [lambda do pad_channel(1050, 10) end, 1000, true, :pad1050], [lambda do pad_channel(1110, 100) end, 1000, false, :pad1110], [lambda do pad_channel(2000, 100) end, 1000, false, :pad2000], [lambda do insert_samples(0, 100, Vct.new(100, 0.2)) end, 1100, false, :insert0], [lambda do insert_samples(800, 100, Vct.new(100, 0.2)) end, 1100, false, :insert800], [lambda do insert_samples(990, 100, Vct.new(100, 0.2)) end, 1100, false, :insert990], [lambda do insert_samples(1010, 100, Vct.new(100, 0.2)) end, 1000, true, :insert1010], [lambda do insert_samples(1050, 10, Vct.new(100, 0.2)) end, 1000, true, :insert1050], [lambda do insert_samples(1110, 100, Vct.new(100, 0.2)) end, 1000, false, :insert1110], [lambda do insert_samples(2000, 100, Vct.new(100, 0.2)) end, 1000, false, :insert2000], [lambda do insert_sound("1a.snd", 0) end, fr + 1000, false, :inserts0], [lambda do insert_sound("1a.snd", 800) end, fr + 1000, false, :inserts800], [lambda do insert_sound("1a.snd", 990) end, fr + 1000, false, :inserts990], [lambda do insert_sound("1a.snd", 1010) end, 1000, true, :inserts1010], [lambda do insert_sound("1a.snd", 1050) end, 1000, true, :inserts1050], [lambda do insert_sound("1a.snd", 1110) end, 1000, false, :inserts1110], [lambda do insert_sound("1a.snd", 2000) end, 1000, false, :inserts2000], [lambda do delete_samples(0, 100) end, 900, false, :delete0], [lambda do delete_samples(0, 2000) end, 1000, true, :delete20], [lambda do delete_samples(800, 100) end, 900, false, :delete800], [lambda do delete_samples(850, 100) end, 900, false, :delete850], [lambda do delete_samples(950, 40) end, 960, false, :delete950], [lambda do delete_samples(990, 100) end, 1000, true, :delete990], [lambda do delete_samples(1010, 100) end, 1000, true, :delete1010], [lambda do delete_samples(1050, 10) end, 1000, true, :delete1050], [lambda do delete_samples(1110, 100) end, 1000, false, :delete1110], [lambda do delete_samples(2000, 100) end, 1000, false, :delete2000], [lambda do set_samples(0, 100, Vct.new(100, 0.2)) end, 1000, false, :set0], [lambda do set_samples(0, 2000, Vct.new(2000, 0.2)) end, 1000, true, :set0], [lambda do set_samples(800, 100, Vct.new(100, 0.2)) end, 1000, false, :set800], [lambda do set_samples(990, 100, Vct.new(100, 0.2)) end, 1000, true, :set990], [lambda do set_samples(1010, 100, Vct.new(100, 0.2)) end, 1000, true, :set1010], [lambda do set_samples(1050, 10, Vct.new(100, 0.2)) end, 1000, true, :set1050], [lambda do set_samples(1110, 100, Vct.new(100, 0.2)) end, 1000, false, :set1110], [lambda do set_samples(2000, 100, Vct.new(100, 0.2)) end, 1000, false, :set2000], [lambda do scale_channel(2.0, 0, 100) end, 1000, false, :scale0], [lambda do scale_channel(2.0, 0, 2000) end, 1000, true, :scale20], [lambda do scale_channel(2.0, 800, 100) end, 1000, false, :scale800], [lambda do scale_channel(2.0, 850, 100) end, 1000, false, :scale850], [lambda do scale_channel(2.0, 950, 40) end, 1000, false, :scale950], [lambda do scale_channel(2.0, 990, 100) end, 1000, true, :scale990], [lambda do scale_channel(2.0, 1010, 100) end, 1000, true, :scale1010], [lambda do scale_channel(2.0, 1050, 10) end, 1000, true, :scale1050], [lambda do scale_channel(2.0, 1110, 100) end, 1000, false, :scale1110], [lambda do scale_channel(2.0, 2000, 100) end, 1000, false, :scale2000], [lambda do env_channel([0, 0, 1, 1], 0, 100) end, 1000, false, :env0], [lambda do env_channel([0, 0, 1, 1], 0, 2000) end, 1000, true, :env20], [lambda do env_channel([0, 0, 1, 1], 800, 100) end, 1000, false, :env800], [lambda do env_channel([0, 0, 1, 1], 850, 100) end, 1000, false, :env850], [lambda do env_channel([0, 0, 1, 1], 950, 40) end, 1000, false, :env950], [lambda do env_channel([0, 0, 1, 1], 990, 100) end, 1000, true, :env990], [lambda do env_channel([0, 0, 1, 1], 1010, 100) end, 1000, true, :env1010], [lambda do env_channel([0, 0, 1, 1], 1050, 10) end, 1000, true, :env1050], [lambda do env_channel([0, 0, 1, 1], 1110, 100) end, 1000, false, :env1110], [lambda do env_channel([0, 0, 1, 1], 2000, 100) end, 1000, false, :env2000] ].each do |func, beg, lock, name| edpos = edit_position(ind, 0) func.call set_edit_position(edpos, ind, 0) end close_sound(ind) # ind = open_sound("4.aiff") selind = open_sound("oboe.snd") make_selection(100, 500, selind, 0) mix_selection(500, ind, 2) if (res = edit_position(ind, 0)) != 0 snd_display("mix_selection 0->2 0: %s?", res) end if (res = edit_position(ind, 1)) != 0 snd_display("mix_selection 0->2 1: %s?", res) end if (res = edit_position(ind, 2)) != 1 snd_display("mix_selection 0->2 2: %s?", res) end if (res = edit_position(ind, 3)) != 0 snd_display("mix_selection 0->2 3: %s?", res) end revert_sound(ind) set_sync(1234, ind) mix_selection(500, ind, 1) if (res = edit_position(ind, 0)) != 0 snd_display("mix_selection 1->2 0: %s?", res) end if (res = edit_position(ind, 1)) != 1 snd_display("mix_selection 1->2 1: %s?", res) end if (res = edit_position(ind, 2)) != 0 snd_display("mix_selection 1->2 2: %s?", res) end if (res = edit_position(ind, 3)) != 0 snd_display("mix_selection 1->2 3: %s?", res) end revert_sound(ind) set_sync(0, ind) insert_selection(500, ind, 2) if (res = edit_position(ind, 0)) != 0 snd_display("insert_selection 0->2 0: %s?", res) end if (res = edit_position(ind, 1)) != 0 snd_display("insert_selection 0->2 1: %s?", res) end if (res = edit_position(ind, 2)) != 1 snd_display("insert_selection 0->2 2: %s?", res) end if (res = edit_position(ind, 3)) != 0 snd_display("insert_selection 0->2 3: %s?", res) end revert_sound(ind) set_sync(1234, ind) insert_selection(500, ind, 1) if (res = edit_position(ind, 0)) != 0 snd_display("insert_selection 1->2 0: %s?", res) end if (res = edit_position(ind, 1)) != 1 snd_display("insert_selection 1->2 1: %s?", res) end if (res = edit_position(ind, 2)) != 0 snd_display("insert_selection 1->2 2: %s?", res) end if (res = edit_position(ind, 3)) != 0 snd_display("insert_selection 1->2 3: %s?", res) end revert_sound(ind) set_sync(0, ind) close_sound(ind) close_sound(selind) end def test_09 if $with_test_gui test_09_00 test_09_02 test_09_03 test_09_04 end end # ---------------- test 10: marks ---------------- def data_max(beg, fin) maxval = 0.0 Snd.sounds.each do |snd| channels(snd).times do |chn| scan_channel(lambda do |data| maxval = [maxval, data.abs].max false end, 0, false, snd, chn) end end maxval end def data_max2(beg, fin, snd) maxval = 0.0 channels(snd).times do |chn| scan_channel(lambda do |data| maxval = [maxval, data.abs].max false end, 0, false, snd, chn) end maxval end def data_max1(beg, fin, snd, chn) maxval = 0.0 scan_channel(lambda do |data| maxval = [maxval, data.abs].max false end, beg, fin, snd, chn) maxval end def test_10_00 ind0 = new_sound("fmv.snd", 2, 22050, Mus_bshort, Mus_aifc, "this is a comment") ind1 = new_sound("fmv1.snd", 1, 22050, Mus_bshort, Mus_aifc, "this is a comment") v0 = make_array(10, 1.0) set_sync(123, ind0) set_sync(123, ind1) insert_samples(0, 10, v0, ind0, 0) insert_samples(0, 10, v0, ind0, 1) insert_samples(0, 10, v0, ind1, 0) env_sound([0, 0, 1, 1], 0, 10, 1.0, ind0) 10.times do |i| if fneq(res = sample(i, ind0, 0), i * 0.1111) snd_display("ind0:0 1 env_sound[%s]: %s?", i, res) end if fneq(res = sample(i, ind0, 1), i * 0.1111) snd_display("ind0:1 1 env_sound[%s]: %s?", i, res) end if fneq(res = sample(i, ind0, 0), i * 0.1111) snd_display("ind1:0 1 env_sound[%s]: %s?", i, res) end end undo_edit env_sound(make_env(:envelope, [0, 0, 1, 1], :length, 10), 0, 10, 1.0, ind0) 10.times do |i| if fneq(res = sample(i, ind0, 0), i * 0.1111) snd_display("ind0:0 2 env_sound[%s]: %s?", i, res) end if fneq(res = sample(i, ind0, 1), i * 0.1111) snd_display("ind0:1 2 env_sound[%s]: %s?", i, res) end if fneq(res = sample(i, ind0, 0), i * 0.1111) snd_display("ind1:0 2 env_sound[%s]: %s?", i, res) end end undo_edit env_sound([0, 0, 0.5, 1, 1, 1], 0, 10, 0.0, ind0) if fneq(res1 = sample(3, ind0, 0), 0.0) or fneq(res2 = sample(8, ind0, 0), 1.0) snd_display("ind0:0 env_sound stepped: %s %s?", res1, res2) end if fneq(res1 = sample(3, ind0, 0), 0.0) or fneq(res2 = sample(8, ind0, 0), 1.0) snd_display("ind0:1 env_sound stepped: %s %s?", res1, res2) end if fneq(res1 = sample(3, ind0, 0), 0.0) or fneq(res2 = sample(8, ind0, 0), 1.0) snd_display("ind1:0 env_sound stepped: %s %s?", res1, res2) end undo_edit revert_sound(ind0) revert_sound(ind1) insert_samples(0, 10, v0, ind0, 0) insert_samples(0, 10, v0, ind0, 1) insert_samples(0, 10, v0, ind1, 0) filter_sound(make_one_zero(:a0, 0.5, :a1, 0.0), 0, ind0) 10.times do |i| if fneq(res = sample(i, ind0, 0), 0.5) snd_display("ind0:0 1 filter_sound[%s]: %s?", i, res) end if fneq(res = sample(i, ind0, 1), 0.5) snd_display("ind0:1 1 filter_sound[%s]: %s?", i, res) end if fneq(res = sample(i, ind0, 0), 0.5) snd_display("ind1:0 1 filter_sound[%s]: %s?", i, res) end end close_sound(ind0) close_sound(ind1) # ind0 = new_sound("fmv.snd", 1, 22050, Mus_bshort, Mus_aifc, "this is a comment") v0 = Vct.new(10, 0.1) old5 = sample(5, ind0) insert_samples(10, 10, v0, ind0) env_sound([0, 0, 1, 2], 10, 10, 1.0, ind0) 10.times do |i| if fneq(res = sample(i + 10, ind0), i * 0.0222) snd_display("env_sound[%s]: %s?", i + 10, res) end end if fneq(res = sample(5, ind0), old5) snd_display("env_sound[5]: %s %s?", old5, res) end undo_edit env_sound([0, 0, 1, 2], 10, 10, 4.0, ind0) v0 = channel2vct(10, 10) if fneq(v0[3], 0.039) or fneq(v0[8], 0.162) snd_display("env_sound 4.0: %s?", v0) end undo_edit env_sound([0, 0, 1, 2], 10, 10, 0.05, ind0) v0 = channel2vct(10, 10) if fneq(v0[3], 0.133) or fneq(v0[8], 0.196) snd_display("env_sound 0.05: %s?", v0) end close_sound(ind0) # ind0 = new_sound("fmv.snd", 2, 22050, Mus_bshort, Mus_aifc, "this is a comment") ind1 = new_sound("fmv1.snd", 1, 22050, Mus_bshort, Mus_next, "this is a comment") insert_samples(0, 10, make_array(10, 1.00), ind0, 0) insert_samples(0, 10, make_array(10, 0.10), ind0, 1) insert_samples(0, 10, make_array(10, 0.01), ind1, 0) if fneq(res = data_max1(0, 9, ind0, 0), 1.00) snd_display("scan_chan[0,0]: %s?", res) end if fneq(res = data_max1(0, 9, ind0, 1), 0.10) snd_display("scan_chan[0,1]: %s?", res) end if fneq(res = data_max1(0, 9, ind1, 0), 0.01) snd_display("scan_chan[1,0]: %s?", res) end if fneq(res = data_max1(0, 9, false, false), 0.01) snd_display("scan_chans: %s?", res) end if fneq(res = data_max(0, 9), 1.00) snd_display("scan_all_chans: %s?", res) end if fneq(res = data_max2(0, 9, ind0), 1.00) snd_display("scan_across_all_chans: %s?", res) end close_sound(ind0) close_sound(ind1) end def test_10_01 ind0 = new_sound("fmv.snd", 2, 22050, Mus_bshort, Mus_aifc, "this is a comment") mix("oboe.snd") m1 = add_mark(100) delete_sample(10) m2 = add_mark(200) delete_sample(10) m3 = add_mark(300) undo_edit save_sound if marks(ind0, 0).length != 2 snd_display("marks after save: %s?", marks(ind0, 0)) end if (not mark?(m1)) or mark_sample(m1) != 99 snd_display("save_sound mark1: %s?", mark_sample(m1)) end if (not mark?(m2)) or mark_sample(m2) != 200 snd_display("save_sound mark2: %s?", mark_sample(m1)) end if mark?(m3) snd_display("save_sound mark3: %s?", m3) end close_sound(ind0) # fd = open_sound("oboe.snd") m1 = add_mark(123) sync_val = mark_sync_max + 1 unless mark?(m1) snd_display("mark?") end if mark_sample(m1) != 123 snd_display("add_mark: %s?", mark_sample(m1)) end set_mark_property(:hiho, m1, 123) if (res = mark_property(:hiho, m1)) != 123 snd_display("mark_property: %s?", res) end if (res = mark_property(:not_there, m1)) snd_display("mark_not_property: %s?", res) end if (res = Snd.catch do mark_sample(integer2mark(12345678)) end).first != :no_such_mark snd_display("mark_sample err: %s", res.inspect) end if (res = Snd.catch do add_mark(123, 123) end).first != :no_such_sound snd_display("add_mark err: %s", res.inspect) end m2 = add_mark(12345, fd, 0) unless mark?(m2) snd_display("add_mark failed?: %s", m2) end if mark_sample(m2) != 12345 snd_display("add_mark 0 0: %s?", mark_sample(m2)) end if mark_sync(m2) != 0 snd_display("init mark_sync: %s?", mark_sync(m2)) end set_mark_sync(m2, sync_val) if (res = mark_sync(m2)) != sync_val snd_display("set_mark_sync (%s): %s?", sync_val, res) end syncs = syncd_marks(sync_val) chans = marks(fd, 0) samps = chans.map do |chn| mark_sample(chn) end if syncs != [m2] snd_display("syncd_marks: %s?", syncs) end if chans != [m1, m2] snd_display("marks: %s?", chans) end if samps != [mark_sample(m1), mark_sample(m2)] snd_display("map samps: %s?", samps) end delete_samples(200, 100, fd, 0) chans = marks(fd) samps = chans.first.map do |chn| mark_sample(chn) end if samps != [mark_sample(m1, 0), mark_sample(m2, 0) - 100] snd_display("map samps: %s?", samps) end unless (res = describe_mark(m2)) == [[:mark, m2, :sound, fd, "oboe.snd", :channel, 0], 12345, 12245] snd_display("describe_mark: %s?", res) end set_mark_sync(m1, mark_sync(m2)) move_syncd_marks(sync_val, 100) chans = marks(fd) samps = chans.first.map do |chn| mark_sample(chn) end if samps != [mark_sample(m1, 0) + 100, mark_sample(m2, 0)] snd_display("syncd move samps: %s?", samps) end set_cursor(500) set_mark_sync(m1, true) if mark_sync(m1) != 1 snd_display("mark_sync via bool: %s?", mark_sync(m1)) end delete_mark(m1) chans = marks(fd, 0) if chans != [m2] snd_display("delete_mark: %s?", chans) end undo_edit chans = marks(fd, 0) if chans != [m1, m2] snd_display("delete_mark then undo: %s?", chans) end redo_edit if mark_name(m2) != "" snd_display("init mark_name: %s?", mark_name(m2)) end set_mark_name(m2, "hiho!") if mark_name(m2) != "hiho!" snd_display("set_mark_name: %s?", mark_name(m2)) end undo_edit if mark_name(m2) != "" snd_display("undo mark_name: %s?", mark_name(m2)) end redo_edit if mark_name(m2) != "hiho!" snd_display("redo mark_name: %s?", mark_name(m2)) end # m3 = find_mark("hiho!") m4 = find_mark(mark_sample(m2)) m5 = find_mark("not-a-mark") m6 = find_mark(123456787) m7 = mark_name2id("hiho!") if (not m2 == m3) or (not m4 == m7) or (not m2 == m4) snd_display("find_mark: %s %s %s %s?", m2, m3, m4, m7) end if (not m5 == m6) or m5 != false snd_display("find-not-a-mark: %s %s?", m5, m6) end set_mark_sample(m2, 2000) m1 = add_mark(1000) m3 = add_mark(3000) m4 = add_mark(4000) insert_samples(2500, 500, Vct.new(500), fd, 0) samps = (marks(fd, 0) or []).map do |m| mark_sample(m) end if samps != [1000, 2000, 3500, 4500] snd_display("insert ripple: %s?", samps) end set_mark_sample(m3, 300) set_cursor(500) sd = open_sound("4.aiff") m3 = add_mark(1000, sd, 2) m4 = add_mark(1000, sd, 3) unless mark_home(m3) == [sd, 2] snd_display("mark->sound 4: %s?", mark_home(m3)) end close_sound(sd) file = save_marks(fd) if file != Dir.pwd + "/oboe.marks" snd_display("save_marks: %s?", file) end file = save_marks(fd, "hiho.marks") if file != "hiho.marks" snd_display("save_marks with arg: %s?", file) end unless shell("diff hiho.marks %s/oboe.marks", Dir.pwd) snd_display("save marks differs") end close_sound(fd) # s1 = open_sound("oboe.snd") s2 = open_sound("oboe.snd") add_mark(123, s1, 0) add_mark(321, s2, 0) set_with_verbose_cursor(true) delete_file("s61.rb") Snd.catch do save_state("s61.rb") end set_with_verbose_cursor(false) close_sound(s1) close_sound(s2) load("s61.rb") unless with_verbose_cursor snd_display("save_state with_verbose_cursor?") end s1 = find_sound("oboe.snd", 0) s2 = find_sound("oboe.snd", 1) if (not sound?(s1)) or (not sound?(s2)) snd_display("cannot re-open sounds: %s %s?", s1, s2) else m1 = marks(s1) m2 = marks(s2) if m1.length != 1 or m2.length != 1 or m1.first.length != 1 or m2.first.length != 1 snd_display("save_marks via save_state to: %s %s?", m1, m2) end samp1 = mark_sample(m1[0][0]) samp2 = mark_sample(m2[0][0]) if samp1 != 123 or samp2 != 321 snd_display("save_marks via save_state positions: %s %s?", samp1, samp2) end end sound?(s1) and close_sound(s1) sound?(s2) and close_sound(s2) fd = open_sound("pistol.snd") if file = save_marks snd_display("save_marks no marks: %s?", file) end close_sound(fd) fd = open_sound("oboe.snd") load("oboe.marks") mlst = marks(fd, 0) if mlst.length != 4 snd_display("restore oboe.marks: %s?", mlst.inspect) end close_sound(fd) fd = open_sound("oboe.snd") add_mark(1000) add_mark(2500) add_mark(framples - 4000) marks(fd, 0) src_sound(-0.5) unless (res1 = marks(fd, 0)) == (res2 = marks(fd, 0, 0).reverse) snd_display("src rev marks: %s %s?", res1.inspect, res2.inspect) end unless (res = (marks(fd, 0) or []).map do |m| mark_sample(m) end) == [7998, 96654, 99654] snd_display("src rev mark locs: %s?", res) end close_sound(fd) fd = open_sound("4.aiff") add_mark(1000, fd, 0) add_mark(2000, fd, 1) add_mark(3000, fd, 2) add_mark(4000, fd, 3) if marks.length.zero? snd_display("marks (no args): %s?", marks) end save_marks(fd) close_sound(fd) fd = open_sound("4.aiff") load("4.marks") delete_file("4.marks") (marks(fd) or []).each_with_index do |mlst, i| if mlst.length != 1 snd_display("save_marks[%s]: %s?", i, mlst) end if (res = mark_sample(mlst.first)) != (i + 1) * 1000 snd_display("save_marks[%s] at %s?", i, res) end end close_sound(fd) end def test_10_02 ind = open_sound("pistol.snd") samp1 = 1834 samp2 = 8345 m1 = add_mark(samp1, ind, 0) m2 = add_mark(samp2) set_mark_sync(m1, 123) set_mark_sync(m2, 100) if (res = mark_sync_max()) != 123 snd_display("mark_sync_max: %s?", res) end src_sound(-1.0) if mark_sample(m1) != 39788 snd_display("src -1 m1: %s?", mark_sample(m1)) end if mark_sample(m2) != 33277 snd_display("src -1 m2: %s?", mark_sample(m2)) end undo_edit src_sound(0.5) if mark_sample(m1) != 2 * samp1 snd_display("src 0.5 m1: %s?", mark_sample(m1)) end if mark_sample(m2) != 2 * samp2 snd_display("src 0.5 m2: %s?", mark_sample(m2)) end undo_edit delete_samples(1000, 100) if mark_sample(m1) != samp1 - 100 snd_display("delete_samples 100 m1: %s?", mark_sample(m1)) end insert_silence(1000, 100) if mark_sample(m1) != samp1 snd_display("insert_silence 100 m1: %s?", mark_sample(m1)) end revert_sound(ind) delete_samples(2000, 100) if mark_sample(m1) != samp1 snd_display("delete_samples (2) 100 m1: %s?", mark_sample(m1)) end if mark_sample(m2) != samp2 - 100 snd_display("delete_samples (2) 100 m2: %s?", mark_sample(m2)) end insert_silence(2000, 100) if mark_sample(m1) != samp1 snd_display("insert_silence (2) 100 m1: %s?", mark_sample(m1)) end if mark_sample(m2) != samp2 snd_display("insert_silence (2) 100 m2: %s?", mark_sample(m2)) end revert_sound(ind) delete_samples(10000, 100) if mark_sample(m1) != samp1 snd_display("delete_samples (3) 100 m1: %s?", mark_sample(m1)) end if mark_sample(m2) != samp2 snd_display("delete_samples (3) 100 m2: %s?", mark_sample(m2)) end insert_silence(10000, 100) if mark_sample(m1) != samp1 snd_display("insert_silence (3) 100 m1: %s?", mark_sample(m1)) end if mark_sample(m2) != samp2 snd_display("insert_silence (3) 100 m2: %s?", mark_sample(m2)) end src_sound([0, 0.5, 1, 0.5, 2, 1]) if mark_sample(m1) != 2 * samp1 snd_display("src env 0.5 m1: %s?", mark_sample(m1)) end if mark_sample(m2) != 2 * samp2 snd_display("src env 0.5 m2: %s?", mark_sample(m2)) end undo_edit reverse_sound if mark_sample(m1) != 39788 snd_display("reverse_sound m1: %s?", mark_sample(m1)) end if mark_sample(m2) != 33277 snd_display("reverse_sound m2: %s?", mark_sample(m2)) end undo_edit src_sound([0, -0.5, 1, -0.5, 2, -1]) if mark_sample(m1) != 68598 snd_display("src -env m1: %s?", mark_sample(m1)) end if mark_sample(m2) != 61160 snd_display("src -env m2: %s?", mark_sample(m2)) end revert_sound(ind) # src_channel(make_env(:envelope, [0, 0.5, 1, 1], :length, 8001), 2000, 10000) if mark_sample(m1) != samp1 snd_display("src_channel (1) m1: %s?", mark_sample(m1)) end if mark_sample(m2) != 11345 snd_display("src_channel (1) m2: %s?", mark_sample(m2)) end undo_edit src_channel(make_env(:envelope, [0, 0.5, 1, 1], :length, 8001), 0, 8000) if mark_sample(m1) != 3303 snd_display("src_channel (2) m1: %s?", mark_sample(m1)) end if mark_sample(m2) != samp2 snd_display("src_channel (2) m2: %s?", mark_sample(m2)) end undo_edit src_channel(make_env(:envelope, [0, 0.5, 1, 1], :length, 8001), 10000, 8000) if mark_sample(m1) != samp1 snd_display("src_channel (3) m1: %s?", mark_sample(m1)) end if mark_sample(m2) != samp2 snd_display("src_channel (3) m2: %s?", mark_sample(m2)) end close_sound(ind) # ind = open_sound("2.snd") set_sync(true, ind) m3 = add_mark(1000, ind, 0) m4 = add_mark(8000, ind, 1) swap_channels if (not (res1 = mark_home(m3)) == [ind, 1]) or (not (res2 = mark_home(m4)) == [ind, 0]) snd_display("swapped mark homes: %s %s?", res1, res2) end if (res1 = mark_sample(m3)) != 1000 or (res2 = mark_sample(m4)) != 8000 snd_display("swapped mark samples: %s %s?", res1, res2) end close_sound(ind) # ind = open_sound("2.snd") set_sync(true, ind) m3 = add_mark(1000, ind, 0) delete_samples(1000, 10, ind, 1) swap_channels unless (res = mark_home(m3)) == [ind, 1] snd_display("edited swapped mark home: %s?", res) end if (res = mark_sample(m3)) != 1000 snd_display("edited swapped mark sample: %s?", res) end delete_marks close_sound(ind) # ind = open_sound("oboe.snd") m1 = add_mark(123, ind, 0) m2 = add_mark(234, ind, 0) define_selection_via_marks(m1, m2) if (not selection?) snd_display("define_selection_via_marks failed?") else mc = selection_members unless mc == [[ind, 0]] snd_display("selection_members after mark def: %s [[%s, 0]]", mc, ind) end if selection_position != 123 snd_display("selection_position 123: %s?", selection_position) end if selection_framples != 112 snd_display("selection_framples 112: %s?", selection_framples) end end m1 = add_mark(1000, ind, 0) m2 = add_mark(2000, ind, 0) define_selection_via_marks(m1, m2) if (not selection?) snd_display("define_selection_via_marks repeat failed?") else mc = selection_members unless mc == [[ind, 0]] snd_display("selection_members after 2nd mark def: %s [[%s, 0]]", mc, ind) end if selection_position != 1000 snd_display("selection_position 1000: %s?", selection_position) end if selection_framples != 1001 snd_display("selection_framples 1001: %s?", selection_framples) end end set_selection_member?(false, true) if selection? snd_display("cannot clear selection via selection_members?") end set_selection_member?(true, ind, 0) set_selection_position(2000, ind, 0) set_selection_framples(1234, ind, 0) snap_marks unless mark?(m1 = find_mark(2000, ind, 0)) snd_display("snap_marks start: %s?", Snd.marks(ind, 0).map do |m| mark_sample(m) end) end unless mark?(m2 = find_mark(2000 + 1234, ind, 0)) snd_display("snap_marks end: %s?", Snd.marks(ind, 0).map do |m| mark_sample(m) end) end set_selection_position(framples(ind, 0) + 1234, ind, 0) if (res = selection_position(ind, 0)) != framples(ind) - 1 snd_display("selection_position past eof: %s %s?", res, framples(ind) - 1) end revert_sound(ind) src_sound([0, 0.5, 1, 1.75665]) # trying to hit previous dur on the nose "by accident..." # try to hit mark_size segfault as_one_edit(lambda do | | add_mark(10) mix("oboe.snd") 20.times do |i| scale_channel(1.2) add_mark(i * 2) end end) scale_channel(0.5) close_sound(ind) # ind = open_sound("oboe.snd") 100.times do |i| current_marks = Snd.marks(ind, 0) current_samples = [] if current_marks and (not current_marks.empty?) current_samples = current_marks.map do |m| mark_sample(m) end id = current_marks[random(current_marks.length - 1)] unless find_mark(mark_sample(id)).eql?(id) snd_display("two marks at %s: %s?", mark_sample(id), current_marks.map do |m| mark_sample(m) end) end if res = find_mark("not-a-mark") snd_display("find-bogus-mark: %s?", res) end end case random(15) when 0 beg = random(framples) dur = [1, random(100)].max insert_silence(beg, dur) if current_marks and (not current_marks.empty?) current_marks.zip(current_samples) do |id, old_loc| if old_loc > beg if mark?(id) if (res = mark_sample(id)) != old_loc + dur snd_display("insert, mark %s %s -> %s (%s)?", id, old_loc, res, dur) end else snd_display("insert clobbered mark: %s?", id) end end end end when 1 if edits(ind, 0)[0] > 0 undo_edit end when 2 if edits(ind, 0)[1] > 0 redo_edit end when 3 scale_channel((maxamp(ind, 0) > 0.1) ? 0.5 : 2.0) unless (res = Snd.marks(ind, 0)) == current_marks snd_display("scaling changed marks: %s %s?", res, current_marks) end unless (res = Snd.marks(ind, 0).map do |m| mark_sample(m) end) == current_samples snd_display("scaling changed mark locations: %s %s?", res, current_samples) end when 4 set_sample(random(framples - 1), 0.5) unless (res = Snd.marks(ind, 0)) == current_marks snd_display("set_sample changed marks: %s %s?", res, current_marks) end unless (res = Snd.marks(ind, 0).map do |m| mark_sample(m) end) == current_samples snd_display("set_sample changed mark location: %s %s?", res, current_samples) end when 5 beg = random(framples) dur = [1, random(100)].max len = beg + dur delete_samples(beg, dur) if current_marks and (not current_marks.empty?) current_marks.zip(current_samples) do |id, old_loc| if old_loc > beg and old_loc < len and mark?(id) snd_display("delete did not clobber mark: %s %s [%s, %s]?", id, old_loc, beg, dur) else if old_loc > len and (res = mark_sample(id)) != old_loc - dur snd_display("delete ripple mark, mark %s %s -> %s (%s)?", id, old_loc, res, dur) else if old_loc < beg and (res = mark_sample(id)) != old_loc snd_display("delete but mark before: %s %s %s %s?", id, old_loc, res, dur) end end end end end when 6 revert_sound when 7 if current_marks and current_marks.length > 1 id = current_marks[random(current_marks.length - 1)] delete_mark(id) if mark?(id) snd_display("delete_mark failed: %s?", id) end if (res = marks(ind, 0)).length != current_marks.length - 1 snd_display("delete_mark list trouble: %s %s %s?", id, current_marks, res) end end when 8 rate = (framples > 200000) ? 2.0 : 0.5 src_channel(rate) if current_marks and (not current_marks.empty?) current_marks.zip(current_samples) do |id, old_loc| unless mark?(id) snd_display("src_channel clobbered mark: %s?", id) else if ((old_loc / rate) - (res = mark_sample(id))).abs > 2 snd_display("src_channel moved mark: %s?", id) end end end end when 9 reverse_channel if current_marks and (not current_marks.empty?) current_marks.zip(current_samples) do |id, old_loc| unless mark?(id) snd_display("reverse_channel clobbered mark: %s?", id) else if ((framples - old_loc) - (res = mark_sample(id))).abs > 2 snd_display("reverse_channel moved mark: %s %s %s (%s)?", id, old_loc, framples - old_loc, res) end end end end else add_mark(random(framples - 1)) end end close_sound(ind) # defined?(mark_sync_color) and $with_test_motif and mark_sync_color("blue") ind = open_sound("oboe.snd") m0 = add_mark(4321) delete_sample(100) m1 = add_mark(1234) val0 = describe_mark(m0) val1 = describe_mark(m1) if mark2integer(val0[0][1]) != mark2integer(m0) or val0[0][3] != ind or val0[0][6] != 0 or val0[1] != 4321 or val0[2] != 4320 snd_display("describe_mark m0: %s?", val0) end if mark2integer(val1[0][1]) != mark2integer(m1) or val1[0][3] != ind or val1[0][6] != 0 or val1[1] != false or val1[2] != 1234 snd_display("describe_mark m1: %s?", val1) end delete_mark(m0) delete_sample(5000) val0 = describe_mark(m0) val1 = describe_mark(m1) if mark2integer(val0[0][1]) != mark2integer(m0) or val0[0][3] != ind or val0[0][6] != 0 or val0[1] != 4321 or val0[2] != false or val0[3] != false snd_display("describe_mark m0 (1): %s?", val0) end if mark2integer(val1[0][1]) != mark2integer(m1) or val1[0][3] != ind or val1[0][6] != 0 or val1[1] != false or val1[2] != 1234 or val1[3] != 1234 snd_display("describe_mark m1 (1): %s?", val1) end revert_sound(ind) $draw_mark_hook.add_hook!("snd-test") do |id| true end m0 = add_mark(4321) m1 = add_mark(1234) dur = framples(ind) / srate(ind).to_f pad_marks([m0, m1], 0.01) if fneq(res = framples(ind) / srate(ind).to_f, dur + 0.02) snd_display("pad_marks: %s %s?", dur, res) end if mark_sample(m0) != 4763 and mark_sample(m0) != 4761 snd_display("pad_marks m0 pos: %s", mark_sample(m0)) end if fneq(res = sample(1235), 0.0) snd_display("pad_marks 1235: %s?", res) end close_sound(ind) $draw_mark_hook.reset_hook! # ind = open_sound("oboe.snd") if res = find_mark(12345) snd_display("find_mark when no marks: %s?", res) end add_mark(123, ind, 0) delete_sample(0) m1 = add_mark(23, ind, 0) set_mark_name(m1, "23") delete_sample(0) unless find_mark(123, ind, 0, 0) snd_display("cannot find 00th mark") end unless find_mark("23") snd_display("cannot find 01th mark") end unless find_mark(121) snd_display("cannot find 02th mark") end delete_mark(find_mark("23")) scale_by(2.0) m1 = add_mark(1234) set_mark_name(m1, "23") if (m10 = find_mark("23")) if (res = mark_sample(m10)) != 1234 snd_display("mark 10th: %s?", res) end else snd_display("cannot find 10th mark?") end if (m11 = find_mark("23", ind, 0, 1)) if (res = mark_sample(m11, 1)) != 23 snd_display("mark 11th: %s?", res) end else snd_display("cannot find 11th mark?") end if (m12 = find_mark("23", ind, 0, 2)) snd_display("found 12th mark: %s %s %s?", m12, mark_sample(m12, 2), mark_name(m12)) end set_mark_name(m1, false) close_sound(ind) # ind = open_sound("oboe.snd") add_mark(123) add_mark(234, ind, 0, "hiho", 1) add_mark(345, ind, 0, false, 1) add_mark(456, ind, 0, "a mark", 2) add_mark(567, ind, 0, false, 1) save_marks(ind, "oboe.marks") close_sound(ind) ind = open_sound("oboe.snd") add_mark(1, ind, 0, "new mark", 1) load("oboe.marks") if mark?(m = find_mark(123, ind, 0)) if mark_name(m).length.nonzero? snd_display("saved mark 123 name: %s?", mark_name(m)) end if mark_sync(m).nonzero? snd_display("saved mark 123 sync: %s?", mark_sync(m)) end else snd_display("saved marks missed 123: %s?", m.inspect) end m1_sync = 0 if mark?(m = find_mark(234, ind, 0)) if mark_name(m) != "hiho" snd_display("saved mark 234 name: %?", mark_name(m)) end if mark_sync(m) == 0 or mark_sync(m) == 1 snd_display("saved mark 234 sync: %s?", mark_sync(m)) end m1_sync = mark_sync(m) else snd_display("saved marks missed 234: %s?", m.inspect) end if mark?(m = find_mark(345, ind, 0)) if mark_name(m).length.nonzero? snd_display("saved mark 345 name: %?", mark_name(m)) end if mark_sync(m) != m1_sync snd_display("saved mark 345 sync: %s %s?", mark_sync(m), m1_sync) end else snd_display("saved marks missed 345: %s?", m.inspect) end if mark?(m = find_mark(456, ind, 0)) if mark_name(m) != "a mark" snd_display("saved mark 456 name: %?", mark_name(m)) end if mark_sync(m) == m1_sync or mark_sync(m) == 0 or mark_sync(m) == 1 snd_display("saved mark 456 sync: %s %s?", mark_sync(m), m1_sync) end else snd_display("saved marks missed 456: %s?", m.inspect) end if mark?(m = find_mark(567, ind, 0)) if mark_name(m).length.nonzero? snd_display("saved mark 567 name: %?", mark_name(m)) end if mark_sync(m) != m1_sync snd_display("saved mark 567 sync: %s %s?", mark_sync(m), m1_sync) end else snd_display("saved marks missed 567: %s?", m.inspect) end delete_file("oboe.marks") # ind1 = open_sound("2a.snd") add_mark(1, ind1, 0) add_mark(2, ind1, 1) add_mark(3, ind1, 0, "hi3") add_mark(6, ind1, 1, "hi6") add_mark(4, ind1, 0, false, 4) add_mark(8, ind1, 1, false, 5) add_mark(5, ind1, 0, false, 9) add_mark(10, ind1, 1, false, 9) add_mark(20, ind1, 0, false, 12) add_mark(40, ind1, 1, false, 12) add_mark(60, ind1, 1, false, 12) save_marks(ind1, "test.marks") close_sound(ind) close_sound(ind1) # ind = open_sound("2a.snd") load("test.marks") m1 = find_mark(1, ind, 0) m2 = find_mark(2, ind, 1) if mark?(m1) and mark?(m2) if mark_sync(m1).nonzero? or mark_sync(m2).nonzero? snd_display("save_marks 2a 1, 2 syncs: %s %s?", mark_sync(m1), mark_sync(m2)) end else snd_display("save_marks 2a 1, 2: %s %s?", m1.inspect, m2.inspect) end m1 = find_mark(5, ind, 0) m2 = find_mark(10, ind, 1) if mark?(m1) and mark?(m2) if mark_sync(m1).zero? or mark_sync(m1) != mark_sync(m2) snd_display("save_marks 2a 5, 10 syncs: %s %s?", mark_sync(m1), mark_sync(m2)) end else snd_display("save_marks 2a 5, 10: %s %s?", m1.inspect, m2.inspect) end m1 = find_mark(4, ind, 0) m2 = find_mark(8, ind, 1) m3 = find_mark(5, ind, 0) if mark?(m1) and mark?(m2) if mark_sync(m1).zero? or mark_sync(m2).zero? or mark_sync(m1) == mark_sync(m2) or mark_sync(m1) == mark_sync(m3) snd_display("save_marks 2a 4, 8 syncs: %s %s?", mark_sync(m1), mark_sync(m2), mark_sync(m3)) end else snd_display("save_marks 2a 4, 8: %s %s?", m1.inspect, m2.inspect) end m1 = find_mark(3, ind, 0) m2 = find_mark(6, ind, 1) if mark?(m1) and mark?(m2) if mark_sync(m1).nonzero? or mark_sync(m2).nonzero? snd_display("save_marks 2a 3, 6 syncs: %s %s?", mark_sync(m1), mark_sync(m2)) end if mark_name(m1) != "hi3" snd_display("save_marks 2a 3 name: %s?", mark_name(m1)) end if mark_name(m2) != "hi6" snd_display("save_marks 2a 6 name: %s?", mark_name(m1)) end else snd_display("save_marks 2a 3, 6: %s %s?", m1.inspect, m2.inspect) end m1 = find_mark(4, ind, 0) m2 = find_mark(5, ind, 0) m3 = find_mark(20, ind, 0) m4 = find_mark(40, ind, 1) m5 = find_mark(60, ind, 1) if mark?(m3) and mark?(m4) and mark?(m5) if mark_sync(m3).zero? or (m1 and mark_sync(m1) == mark_sync(m3)) or (m2 and mark_sync(m2) == mark_sync(m3)) or mark_sync(m3) != mark_sync(m4) or mark_sync(m3) != mark_sync(m5) snd_display("save_marks 2a 20... syncs: %s %s %s?", mark_sync(m3),mark_sync(m4), mark_sync(m5)) end else snd_display("save_marks 2a 20...: %s %s %s?", m3.inspect, m4.inspect, m5.inspect) end delete_file("test.marks") close_sound(ind) # ind = new_sound(:size, 1000) add_mark(123) add_mark(234, ind, 0, "hiho", 1) add_mark(345, ind, 0, false, 1) add_mark(456, ind, 0, "a mark", 2) add_mark(567, ind, 0, false, 1) $output_comment_hook.add_hook!("mark2string") do |str| marks2string(selected_sound) end save_sound_as("tst.snd") new_file_name = file_name(ind) close_sound(ind) delete_file(new_file_name) ind = open_sound("tst.snd") $output_comment_hook.reset_hook! if string?(str = comment(ind)) Snd.catch do eval(str, TOPLEVEL_BINDING, "(eval-header)", 1) end end if (ms = marks(ind, 0)).nil? ms = [] end if ms.length != 5 snd_display("eval_header + marks2string: %s?", ms.inspect) end samps = ms.apply(:mark_sample) if (not samps.member?(123)) or (not samps.member?(567)) snd_display("eval marked header samps: %s?", samps.inspect) end unless find_mark(234) snd_display("eval mark header no mark at 234?") end if mr = find_mark(456) if (res = mark_sync(mr)) != 2 snd_display("eval mark header sync: %s?", res) end else snd_display("saved marks missed 456: %s?", mr) end close_sound(ind) mus_sound_forget("tst.snd") delete_file("tst.snd") # mark_explode ind = new_sound(:size, 31) ctr = -1 map_channel(lambda do |y| ctr += 1 if ctr < 10 0.1 elsif ctr < 20 0.4 else 0.8 end end) add_mark(10) add_mark(20) add_mark(30) mark_explode if File.exist?("mark-0.snd") ind1 = open_sound("mark-0.snd") if framples(ind1, 0) != 10 snd_display("mark-0 framples: %s?", framples(ind1, 0)) end unless vequal(res = channel2vct, Vct.new(10, 0.1)) snd_display("mark-0 vals: %s?", res) end close_sound(ind1) delete_file("mark-0.snd") else snd_display("mark_explode did not write mark-0.snd?") end if File.exist?("mark-1.snd") ind1 = open_sound("mark-1.snd") if framples(ind1, 0) != 10 snd_display("mark-1 framples: %s?", framples(ind1, 0)) end unless vequal(res = channel2vct, Vct.new(10, 0.4)) snd_display("mark-1 vals: %s?", res) end close_sound(ind1) delete_file("mark-1.snd") else snd_display("mark_explode did not write mark-1.snd?") end if File.exist?("mark-2.snd") ind1 = open_sound("mark-2.snd") if framples(ind1, 0) != 10 snd_display("mark-2 framples: %s?", framples(ind1, 0)) end unless vequal(res = channel2vct, Vct.new(10, 0.8)) snd_display("mark-2 vals: %s?", res) end close_sound(ind1) delete_file("mark-2.snd") else snd_display("mark_explode did not write mark-2.snd?") end if File.exist?("mark-3.snd") snd_display("mark_explode wrote too many files?") delete_file("mark-3.snd") end name = file_name(ind) close_sound(ind) delete_file(name) end def test_10 test_10_00 test_10_01 if $with_test_gui # load("s61.rb") -> set_transform_size(0) test_10_02 end # ---------------- test 11: dialogs ---------------- def string_equal_ignore_white_space(s1, s2) s1 == s2 or s1.delete(":()-_, \n") == s2.delete(":()-_, \n") end define_envelope("env4", [0, 1, 1, 0]) # defines $env4 def test_11 if $with_test_gui Snd.catch do peaks() end enved_dialog color_orientation_dialog transform_dialog view_regions_dialog Snd.catch do edit_header_dialog() end open_file_dialog(false) mix_file_dialog(false) insert_file_dialog(false) help_dialog("Test", "snd-test here") save_envelopes("hiho.env") load("hiho.env") if $env4 != [0.0, 1.0, 1.0, 0.0] snd_display("save_envelopes: %s?", $env4) end delete_file("hiho.env") help_dialog("test2", "this is the next test", ["string 1{open-sound}", "{env-sound}string2", "string{close-sound}3"], ["extsnd.html#sndopen", "extsnd.html#sndenv", "extsnd.html#sndclose"]) dismiss_all_dialogs # ind = open_sound("oboe.snd") edit_header_dialog(ind) dismiss_all_dialogs close_sound(ind) # if (res = snd_url(:open_sound)) != "extsnd.html#opensound" snd_display("snd_url :open_sound: %s?", res.inspect) end if (res = snd_url("open_sound")) != "extsnd.html#opensound" snd_display("snd_url \"open_sound\": %s?", res.inspect) end unless array?(res = snd_urls) snd_display("snd_urls: %s?", res.inspect) end # XXX: snd_help(:open_sound) => "keyword" # str2 = snd_help(:open_sound) => "keyword" str2 = snd_help(:open_sound.to_s) str3 = snd_help("open_sound") unless string_equal_ignore_white_space(str2, str3) snd_display("snd_help open_sound: expected %s, got %s?", str2, str3) end str1 = "(enved-base): envelope editor exponential base value (1.0)" str2 = snd_help(:enved_base.to_s) str3 = snd_help("enved_base") unless string_equal_ignore_white_space(str1, str2) snd_display("snd_help :enved_base: expected %s, got %s", str1, str2) end unless string_equal_ignore_white_space(str1, str3) snd_display("snd_help \"enved_base\": expected %s, got %s", str1, str3) end old_val = Hamming_window str1 = snd_help(:Hamming_window.to_s) str2 = snd_help("Hamming_window") if (not string_equal_ignore_white_space(str1, str2)) or (not string_equal_ignore_white_space(str1, "A raised cosine")) snd_display("snd_help Hamming_window: expected %s, got %s?", str1, str2) end if (not number?(Hamming_window)) or Hamming_window != old_val snd_display("snd_help clobbered out-of-module variable: %s %s?", old_val, Hamming_window) end # urls = snd_urls[0...25] urls.each do |fnc, url| if function?(fnc) snd_help(fnc, false) end end urls.each do |fnc, url| if function?(fnc) help_dialog(fnc, snd_help(fnc, false)) end end set_show_indices(false) # define_envelope("test_ramp", [0, 0, 1, 1]) if $test_ramp != [0, 0, 1, 1] snd_display("define_envelope $test_ramp: %s?", $test_ramp) end define_envelope("test_ramp", [0, 1, 1, 0]) if $test_ramp != [0, 1, 1, 0] snd_display("re-define-envelope $test_ramp: %s?", $test_ramp) end end end # ---------------- test 12: extensions ---------------- def spectral_difference(snd1, snd2) size = [framples(snd1), framples(snd2)].max pow2 = (log(size) / log(2)).ceil fftlen = (2 ** pow2).to_i fdr1 = channel2vct(0, fftlen, snd1, 0) fdr2 = channel2vct(0, fftlen, snd2, 0) spectr1 = snd_spectrum(fdr1, Blackman2_window, fftlen, true) spectr2 = snd_spectrum(fdr2, Blackman2_window, fftlen, true) diff = 0.0 diffs = spectr1.subtract(spectr2) diffs.each do |d| diff += d.abs end diff end def test_spectral_difference(snd1, snd2, maxok) s1 = open_sound(snd1) s2 = open_sound(snd2) if (not sound?(s1)) or (not sound?(s2)) snd_display_prev_caller("open_sound %s or %s failed?", snd1, snd2) end diff = spectral_difference(s1, s2) close_sound(s1) close_sound(s2) if diff > maxok snd_display_prev_caller("translate spectral difference %s %s: %s > %s?", snd1, snd2, diff, maxok) end end def test_12 if $with_test_gui sf_dir_files = [] if string?($sf_dir) sound_files_in_directory($sf_dir).each do |file| dir = $sf_dir + file #Snd.catch(:mus_error) do Snd.catch do mus_sound_chans(dir).between?(1, 255) and mus_sound_sample_type(dir) >= 0 and mus_sound_srate(dir) > 0 and mus_sound_framples(dir) >= 0 and sf_dir_files.push(dir) end end end if sound_file_extensions.null? set_sound_file_extensions($original_sound_file_extensions) end open_files = [] open_ctr = 0 add_sound_file_extension("wave") unless (exts = sound_file_extensions).member?("wave") snd_display("sound_file_extensions: %s?", exts) end set_sound_file_extensions([]) unless (res = sound_file_extensions).nil? snd_display("sound_file_extensions set []: %s?", res) end set_sound_file_extensions(exts) unless (res = sound_file_extensions).member?("wave") snd_display("sound_file_extensions reset: %s?", res) end until open_ctr == 32 len = open_files.length open_chance = (8 - len) * 0.125 close_chance = len * 0.125 if len.zero? or random(1.0) > 0.5 name = sf_dir_files[random(sf_dir_files.length).floor] ht = Snd.catch(:all, 0) do mus_sound_header_type(name) end.first df = Snd.catch(:all, 0) do mus_sound_sample_type(name) end.first fd = if ht == Mus_raw or ht == Mus_unknown_header or df == Mus_unknown_sample -1 else Snd.catch(:all, -1) do view_sound(name) end.first or -1 end if fd != -1 open_ctr += 1 open_files.push(fd) end else if len > 0 and random(1.0) > 0.3 if sound?(fd = open_files.delete_at(random(open_files.length))) close_sound(fd) end end end end open_files.apply(:close_sound) open_files = [] if Snd.sounds.length != 0 snd_display("active_sounds: %s %s?", sounds.inspect, Snd.sounds.map do |s| short_file_name(s) end) end fd = open_raw_sound(:file, $sf_dir + "addf8.nh", :channels, 1, :srate, 8012, :sample_type, Mus_mulaw) if sample_type(fd) != Mus_mulaw snd_display("open_raw_sound: %s?", mus_sample_type_name(sample_type(fd))) end close_sound(fd) # $bad_header_hook.reset_hook! test_spectral_difference($sf_dir + "o2.wave", $sf_dir + "o2_dvi.wave", 10.0) test_spectral_difference($sf_dir + "wood.riff", $sf_dir + "wood.sds", 4.0) test_spectral_difference($sf_dir + "nist-10.wav", $sf_dir + "nist-shortpack.wav", 1.0) $bad_header_hook.add_hook!("snd-test") do |n| true end # # dangling readers (overall) # ind = open_sound("oboe.snd") hi = make_sampler(0, ind, 0) close_sound(ind) unless sampler?(hi) snd_display("dangling reader: %s?", hi) end unless string?(hi.to_s) snd_display("dangling reader format: %s?", hi) end val = hi.call val1 = next_sample(hi) val2 = previous_sample(hi) val3 = read_sample(hi) if fneq(val, 0.0) or fneq(val1, 0.0) or fneq(val2, 0.0) or fneq(val3, 0.0) snd_display("dangling read: %s %s %s %s?", val, val1, val2, val3) end if res = sampler_home(hi) snd_display("dangling reader home: %s?", res) end if (res = sampler_position(hi)).nonzero? snd_display("dangling sampler_position: %s?", res) end unless (res = sampler_at_end?(hi)) snd_display("dangling reader eof: %s?", res) end free_sampler(hi) # # same (pruned edit) # ind = open_sound("oboe.snd") delete_samples(100, 100) hi = make_sampler(0, ind, 0) revert_sound delete_samples(100, 100) unless sampler?(hi) snd_display("pruned dangling reader: %s?", hi) end unless string?(hi.to_s) snd_display("pruned dangling reader format: %s?", hi) end val = hi.call val1 = next_sample(hi) val2 = previous_sample(hi) val3 = read_sample(hi) if fneq(val, 0.0) or fneq(val1, 0.0) or fneq(val2, 0.0) or fneq(val3, 0.0) snd_display("pruned dangling read: %s %s %s %s?", val, val1, val2, val3) end if (res = sampler_home(hi)) != [ind, 0] snd_display("pruned dangling reader home: %s?", res) end unless (res = sampler_at_end?(hi)) snd_display("pruned dangling reader eof: %s?", res) end free_sampler(hi) close_sound(ind) # # region reader # ind = open_sound("oboe.snd") reg = make_region(1000, 2000, ind, 0) rd = make_region_sampler(reg, 0) if mix_sampler?(rd) snd_display("region_sampler mix: %s?", rd) end unless region_sampler?(rd) snd_display("region_sampler region: %s?", rd) end if sampler?(rd) snd_display("region_sampler normal: %s?", rd) end if (res = sampler_position(rd)).nonzero? snd_display("region_sampler position: %s?", res) end if (res = sampler_home(rd)) != [reg, 0] snd_display("region_sampler home: %s?", res) end if (res = sampler_at_end?(rd)) snd_display("region_sampler_at_end?: %s?", res) end val = rd.call if fneq(val, 0.0328) snd_display("region_sampler at start: %s?", val) end unless string?(res = rd.to_s) snd_display("region_sampler: %s?", res) end close_sound(ind) forget_region(reg) val = read_sample(rd) if fneq(val, 0.0) snd_display("region_sampler at end: %s?", val) end unless sampler_at_end?(rd) snd_display("region_sampler after deletion?") end free_sampler(rd) # # mix reader # save_md = 0 $mix_click_hook.add_hook!("mix-click-sets-amp") do |id| mix_click_sets_amp(id) end ind = open_sound("oboe.snd") reg = make_region(1000, 2000, ind, 0) md = mix_region(reg, 0, ind, 0, 0).car rd = make_mix_sampler(md) set_mix_property(:hi, md, "hi") save_md = md if (res = mix_property(:hi, md)) != "hi" snd_display("mix_property (hi): %s?", res) end val = rd.call if fneq(val, 0.0328) snd_display("mix_sampler at start: %s?", val) end unless string?(res = rd.to_s) snd_display("mix_sampler: %s?", res) end close_sound(ind) if (res = Snd.catch do mix_property(:hi, md) end).first != :no_such_mix snd_display("mix_property bad mix: %s", res.inspect) end if (res = rd.to_s) != "#" snd_display("mix_sampler released: %s?", res) end free_sampler(rd) $mix_click_hook.reset_hook! $close_hook.reset_hook! # sfiles = [] ffiles = [] old_dir = Dir.pwd Dir.chdir($sf_dir) each_sound_file do |file| Snd.catch do if mus_sound_chans(file) > 16 ffiles.push(file) end end end map_sound_files do |file| Snd.catch do if mus_sound_chans(file) > 16 sfiles.push(file) end end end if File.exist?("s24.snd") and (ffiles != [$sf_dir + "s24.snd"] or sfiles != [$sf_dir + "s24.snd"]) snd_display("map|for_each_sound_file(s): %s %s?", ffiles, sfiles) end Dir.chdir(old_dir) end sf_dir_files.each do |n| mus_sound_forget($sf_dir + n) end end # ---------------- test 13: menus, edit lists, hooks, etc ---------------- def loop_through_files(description, select, &make_cmd) data = if select selection_to_temps(Mus_next, Mus_out_format) else sound_to_temps(Mus_next, Mus_out_format) end cont = true output_names = make_array(data.length) do |i| break unless cont outname = format("/tmp/snd_test_%s.snd", random(1.0).object_id) cont = shell(make_cmd.call(data[i], outname)) outname end if select temps_to_selection(data, output_names, description) else temps_to_sound(data, output_names, description) end end def copyfile(select) loop_through_files("(cp)", select) do |input, output| format("cp %s %s", input, output) end end def carg0(hook) hook.call end def carg1(hook) hook.call(1) end def carg2(hook) hook.call(1, 2) end def carg3(hook) hook.call(1, 2, 3) end def carg4(hook) hook.call(1, 2, 3, 4) end def carg5(hook) hook.call(1, 2, 3, 4, 5) end def carg6(hook) hook.call(1, 2, 3, 4, 5, 6) end def carg7(hook) hook.call(1, 2, 3, 4, 5, 6, 7) end def harg0 32 end def harg1(a) a + 32 end def harg2(a, b) a + b + 32 end def harg3(a, b, c) a + b + c + 32 end def harg4(a, b, c, d) a + b + c + d + 32 end def harg5(a, b, c, d, e) a + b + c + d + e + 32 end def harg6(a, b, c, d, e, f) a + b + c + d + e + f + 32 end def harg7(a, b, c, d, e, f, g) a + b + c + d + e + f + g + 32 end def test_hooks funcs = [[:harg0, :carg0, 32], [:harg1, :carg1, 33], [:harg2, :carg2, 35], [:harg3, :carg3, 38], [:harg4, :carg4, 42], [:harg5, :carg5, 47], [:harg6, :carg6, 53], [:harg7, :carg7, 60]] Snd_hooks.each do |hook| if hook? hook if hook.arity.between?(0, 7) vals = funcs[hook.arity] hook.add_hook!(get_func_name, &method(vals[0])) if (res = snd_func(vals[1], hook)) != vals[2] snd_display("hook.call: %s (%s) %s?", res.inspect, vals[2], hook.inspect) end else snd_display("hook arity: %s %s?", hook.arity, hook.inspect) end end end reset_almost_all_hooks Snd_hooks.each do |hook| if hook?(hook) next if hook.name == "$snd_error_hook" next if hook.name == "$mus_error_hook" unless hook.empty? snd_display("%s not empty?", hook.inspect) end end end end def mdt_test(a, b, c, d) false end def test_13_00 fd = view_sound("oboe.snd") mb = add_to_main_menu("clm") if (res = Snd.catch do add_to_menu(-1, "fm-violin", lambda do | | false end) end).first != :no_such_menu snd_display("add_to_menu bad menu: %s", res.inspect) end if (res = Snd.catch do add_to_main_menu("oops", make_delay(11)) end).first != :bad_arity snd_display("add_to_main_menu non-thunk: %s", res.inspect) end if (res = Snd.catch do add_to_menu(3, "oops", lambda do |a, b| make_delay(12) end) end).first != :bad_arity snd_display("add_to_menu non-thunk: %s", res.inspect) end set_cursor(2000, fd) set_transform_graph_type(Graph_once) set_transform_graph?(true, fd) if $with_test_gui add_to_menu(mb, "not here", lambda do | | snd_display("oops") end) remove_from_menu(mb,"not here") end $help_hook.reset_hook! hi = snd_help(:cursor_position) $help_hook.add_hook!("snd-test") do |a, b| if a != "cursor_position" snd_display("in $help_hook subject: %s?", a) end if b != "(cursor-position :optional snd chn): current cursor position (x y in pixels) in snd's channel chn" snd_display("in $help_hook text: %s?", b) end "hiho:" + b end ho = snd_help(:cursor_position) if ho.length != hi.length snd_display("length $help_hook\n\t<[%s]%s>\n\t<[%s]%s>?", hi.length, hi, ho.length, ho) end $help_hook.reset_hook! $help_hook.add_hook!("snd-test") do |a, b| false end ho = snd_help(:cursor_position) if hi != ho snd_display("$help_hook false: %s %s?", hi, ho) end $help_hook.reset_hook! # fr = framples(fd) chn = chans(fd) sr = srate(fd) mx = maxamp(fd) copyfile(false) if (res = edit_fragment) != ["(cp)", "set", 0, 50828] snd_display("copyfile: %s?", res) end if fr != framples(fd) or chn != chans(fd) or fneq(mx, maxamp(fd)) or fneq(sr, srate(fd)) snd_display("copyfile (1): %s %s %s %s?", framples(fd), chans(fd), srate(fd), maxamp(fd)) end eds = edits select_all copyfile(true) if (res = edit_fragment) != ["(cp)", "set", 0, 50828] snd_display("copyfile (select): %s?", res) end if (res = edits) != [eds[0] + 1, eds[1]] snd_display("copyfile (select eds): %s %s?", eds, res) end if fr != framples(fd) or chn != chans(fd) or fneq(mx, maxamp(fd)) or fneq(sr, srate(fd)) snd_display("copyfile (2): %s %s %s %s?", framples(fd), chans(fd), srate(fd), maxamp(fd)) end # set_transform_size(256, fd, 0) dpys = [Graph_once, Graph_as_sonogram, Graph_as_spectrogram] * 2 ffts = [transform2integer($fourier_transform)] * 3 + [transform2integer($autocorrelation)] * 3 dpys.zip(ffts) do |dpy_type, fft_type| set_transform_graph_type(dpy_type, fd, 0) set_transform_type(integer2transform(fft_type), fd, 0) update_transform_graph(fd, 0) vals = transform2vct(fd, 0) if vals if fneq(res = transform_sample(0, 0, fd, 0), vals[0]) snd_display("transform_sample %s %s -> %s %s?", dpy_type, fft_type, vals[0], res) end if vals.length < 256 snd_display("transform2vct size: %s?", vals.length) end else snd_display("transform %s %s -> %s?", dpy_type, fft_type, vals) end end if (res = Snd.catch do transform_sample(5000, 0, fd, 0) end).first != :no_such_sample snd_display("access invalid (bin) transform sample: %s", res.inspect) end if (res = Snd.catch do transform_sample(0, 5000, fd, 0) end).first != :no_such_sample snd_display("access invalid (slice) transform sample: %s", res.inspect) end close_sound(fd) set_transform_type($fourier_transform) $after_open_hook.add_hook!("snd-test") do |snd| set_x_axis_style(X_axis_in_samples, snd, true) end fd = open_sound("2.snd") close_sound(fd) $after_open_hook.reset_hook! $after_open_hook.add_hook!("snd-test") do |snd| set_x_axis_style(X_axis_in_percentage, snd, true) end $initial_graph_hook.add_hook!("snd-test") do |snd, chn, dur| if mus_sound_maxamp_exists?(file_name(snd)) amp_vals = mus_sound_maxamp(file_name(snd)) max_val = amp_vals[chn * 2 + 1] [0.0, dur, -max_val, max_val] else [0.0, dur, -1.0, 1.0] end end $after_open_hook.reset_hook! $initial_graph_hook.reset_hook! $initial_graph_hook.add_hook!("snd-test") do |snd, chn, dur| [0.0, dur, -1.0, 1.0, "a label", -4.0, 4.0] end fd = open_sound("2.snd") if defined? axis_info # snd-nogui hasn't axis_info ax = axis_info if array?(ax) and (fneq(ax[2], 0.0) or fneq(ax[3], -1.0) or fneq(ax[4], mus_sound_duration("2.snd")) or fneq(ax[5], 1.0) or fneq(ax[6], 0.0) or fneq(ax[7], -4.0) or fneq(ax[8], mus_sound_duration("2.snd")) or fneq(ax[9], 4.0)) snd_display("$initial_graph_hook with ymin/max: %s?", ax) end end $initial_graph_hook.reset_hook! set_selection_position(1000, fd, 1) set_selection_framples(10, fd, 1) set_selection_member?(true, fd, 1) if selection_member?(fd, 0) snd_display("chan 0 is selection_member?") end 2.times do |chn| set_selection_position(1000, fd, chn) set_selection_framples(10, fd, chn) set_selection_member?(true, fd, chn) end scale_selection_to([0.5, 0.25].to_vct) if fneq(maxamp(fd, 0), 0.5) or fneq(maxamp(fd, 1), 0.25) snd_display("scale_selection_to with vector: %s?", maxamp(fd, true)) end close_sound(fd) # fd = open_sound("obtest.snd") Snd.sounds.apply(:close_sound) test_hooks $bad_header_hook.add_hook!("snd-hook") do |n| true end ind = open_sound("oboe.snd") set_cursor(2000) key(key_to_int(?u), 4, ind) key(key_to_int(?1), 0, ind) key(key_to_int(?0), 0, ind) key(key_to_int(?0), 0, ind) key(key_to_int(?x), 4, ind) key(key_to_int(?z), 4, ind) if (res = edit_fragment) != ["smooth_channel(2000, 100", "set", 2000, 100] snd_display("C-x C-z fragment: %s?", res) end set_cursor(0) select_all key(key_to_int(?x), 4, ind) key(key_to_int(?o), 0, ind) key(key_to_int(?-), 4, ind) key(key_to_int(?x), 4, ind) key(key_to_int(?o), 0, ind) key(key_to_int(?x), 4, ind) key(key_to_int(?o), 0, ind) key(key_to_int(?x), 4, ind) key(key_to_int(?p), 0, ind) set_selection_member?(false, true) revert_sound(ind) close_sound(ind) end def test_13_01 with_file("addf8.nh") do |file| unless $open_raw_sound_hook.empty? $open_raw_sound_hook.reset_hook! end $open_raw_sound_hook.add_hook!("snd-hook") do |file, choice| [1, 22050, Mus_bshort] end ind = open_sound(file) play(ind, :wait, true) $open_raw_sound_hook.remove_hook!("snd-hook") if (res = [chans(ind), srate(ind), sample_type(ind), framples(ind)]) != [1, 22050, Mus_bshort, 23808] snd_display("open_raw: %s?", res) end set_search_procedure(lambda do |n| n > 0.2 end) close_sound(ind) end save_as_dialog = true save_as_name = "hiho" save_as_index = false $after_save_as_hook.reset_hook! $after_save_as_hook.add_hook!("snd-test") do |ind, name, dial| save_as_index = ind save_as_name = name save_as_dialog = dial end ind = open_sound("oboe.snd") save_sound_as("test.snd", ind, :header_type, Mus_raw) close_sound(ind) $open_raw_sound_hook.reset_hook! $after_save_as_hook.reset_hook! if save_as_dialog snd_display("$after_save_as_hook dialog: %s?", save_as_dialog) end if save_as_index != ind snd_display("$after_save_as_hook index: %s (%s)?", save_as_index, ind) end if Dir.pwd + "/test.snd" != save_as_name snd_display("$after_save_as_hook name: %s (%s)?", save_as_name, Dir.pwd + "/test.snd") end $open_raw_sound_hook.add_hook!("snd-hook-1") do |file, choice| if File.basename(file) != "test.snd" snd_display("$open_raw_sound_hook file: %s?", file) end unless choice == false snd_display("$open_raw_sound_hook choice 1: %s?", choice) end [2, 44100, Mus_mulaw] end ind = open_sound("test.snd") if (res = [header_type(ind), sample_type(ind), chans(ind), srate(ind), framples(ind)]) \ != [Mus_raw, Mus_mulaw, 2, 44100, 50828] snd_display("$open_raw_sound_hook 1: %s?", res) end close_sound(ind) $open_raw_sound_hook.add_hook!("snd-hook-2") do |file, choice| if choice != [2, 44100, Mus_mulaw] snd_display("$open_raw_sound_hook choice 2: %s?", choice) end [1, 22050, Mus_lint] end ind = open_sound("test.snd") if (res = [header_type(ind), sample_type(ind), chans(ind), srate(ind), framples(ind)]) \ != [Mus_raw, Mus_lint, 1, 22050, 50828 / 2] snd_display("$open_raw_sound_hook 2: %s?", res) end close_sound(ind) $open_raw_sound_hook.reset_hook! $open_raw_sound_hook.add_hook!("snd-hook-3") do |file, choice| [2] end ind = open_sound("test.snd") if (res = [header_type(ind), sample_type(ind), chans(ind), srate(ind)]) \ != [Mus_raw, Mus_lint, 2, 22050] snd_display("$open_raw_sound_hook 3: %s?", res) end close_sound(ind) $open_raw_sound_hook.reset_hook! $open_raw_sound_hook.add_hook!("snd-hook-4") do |file, choice| [1, 22050, Mus_bshort, 120, 320] end ind = open_sound("test.snd") if (res = [header_type(ind), sample_type(ind), chans(ind), srate(ind), data_location(ind), data_size(ind), framples(ind)]) \ != [Mus_raw, Mus_bshort, 1, 22050, 120, 320, 160] snd_display("$open_raw_sound_hook 4: %s?", res) end close_sound(ind) $open_raw_sound_hook.reset_hook! $during_open_hook.reset_hook! # ind = op = sl = aop = dop = cl = ig = scl = other = false $open_hook.add_hook!("snd-test") do |filename| if filename != mus_expand_filename("oboe.snd") snd_display("$open_hook: %s?", filename) end op = true false end $after_open_hook.add_hook!("snd-test") do |snd| aop = snd end $during_open_hook.add_hook!("snd-test") do |fd, filename, reason| if filename != mus_expand_filename("oboe.snd") snd_display("$during_open_hook filename: %s?", filename) end if reason != 1 snd_display("$during_open_hook reason: %s?", reason) end dop = true end $initial_graph_hook.add_hook!("snd-test") do |snd, chn, dur| if chn.nonzero? snd_display("$initial_graph_hook (channel): %s not 0?", chn) end ig = true false end ind = open_sound("oboe.snd") unless op snd_display("$open_hook not called?") end unless dop snd_display("$during_open_hook not called?") end unless ig snd_display("$initial_graph_hook not called?") end unless sound?(aop) snd_display("$after_open_hook not called?") end if aop != ind snd_display("$after_open_hook %s but ind: %s?", aop, ind) end select_all $open_hook.reset_hook! $during_open_hook.reset_hook! $after_open_hook.reset_hook! $initial_graph_hook.reset_hook! $open_hook.add_hook!("snd-test") do |filename| true end unless (res = open_sound("pistol.snd")) == false snd_display("$open_hook true, but open_sound -> %s?", res) if sound?(res) close_sound(res) end end $open_hook.reset_hook! # gr = agr = gbf = abf = false $before_transform_hook.reset_hook! $after_transform_hook.reset_hook! $after_graph_hook.reset_hook! $graph_hook.reset_hook! $graph_hook.add_hook!("snd-test") do |snd, chn, y0, y1| unless snd.eql?(ind) snd_display("$graph_hook: %s not %s?", snd, ind) end if chn.nonzero? snd_display("$graph_hook: (channel): %s not 0?", chn) end gr = true false end $after_graph_hook.add_hook!("snd-test") do |snd, chn| unless snd.eql?(ind) snd_display("$after_graph_hook: %s not %s?", snd, ind) end if chn.nonzero? snd_display("$after_graph_hook: (channel): %s not 0?", chn) end agr = true end $before_transform_hook.add_hook!("snd-test") do |snd, chn| gbf = true cursor end $after_transform_hook.add_hook!("snd-test") do |snd, chn, scale| abf = true if transform_graph?(snd, chn) and transform_graph_type(snd, chn) == Graph_once num = (2.0 * transform2vct(snd, chn).peak / transform_size(snd, chn)).to_s status_report(num, snd) end false end set_transform_graph?(true, ind, 0) set_time_graph?(true, ind, 0) update_transform_graph(ind, 0) if $with_test_motif unless gr app = main_widgets.car 1000.times do msg = RXtAppPending(app) if (msg & (RXtIMXEvent | RXtIMAlternateInput)).zero? break else RXtDispatchEvent(RXtAppNextEvent(app)) end end end end unless gr snd_display("$graph_hook not called? %s %s %s %s?", time_graph?(ind), short_file_name(ind), ind, sounds) end unless agr snd_display("$after_graph_hook not called?") end unless gbf snd_display("$before_transform_hook not called?") end unless abf snd_display("$after_transform_hook not called?") end $before_transform_hook.reset_hook! set_transform_graph?(false, ind, 0) $graph_hook.reset_hook! $after_graph_hook.reset_hook! # other = open_sound("pistol.snd") $select_sound_hook.add_hook!("snd-test") do |snd| unless snd.eql?(ind) snd_display("$select_sound_hook: %s not %s?", snd, ind) end sl = true end $select_channel_hook.add_hook!("snd-test") do |snd, chn| unless snd.eql?(ind) snd_display("$select_channel_hook: %s not %s?", snd, ind) end if chn.nonzero? snd_display("$select_channel_hook: (channel): %s not 0?", chn) end scl = true end select_sound(ind) unless sl snd_display("$select_sound_hook not called?") end unless scl snd_display("$select_channel_hook not called?") end $select_sound_hook.reset_hook! $select_channel_hook.reset_hook! # spl = stl = ph = ph1 = false $start_playing_hook.add_hook!("snd-test") do |snd| spl = true unless snd.eql?(ind) snd_display("$start_playing_hook: %s not %s?", snd, ind) end false end $stop_playing_hook.add_hook!("snd-test") do |snd| unless snd.eql?(ind) snd_display("$stop_playing_hook: %s not %s?", snd, ind) end stl = true false end $play_hook.add_hook!("snd-test") do |n| if n < 128 snd_display("$play_hook samps: %s?", n) end set_expand_control_hop(expand_control_hop) set_expand_control_length(expand_control_length) set_expand_control_ramp(expand_control_ramp) set_contrast_control_amp(contrast_control_amp) set_reverb_control_lowpass(reverb_control_lowpass) set_reverb_control_feedback(reverb_control_feedback) ph = true end set_expand_control?(true, ind) set_reverb_control?(true, ind) play(ind, :wait, true) set_expand_control?(false, ind) set_reverb_control?(false, ind) unless spl snd_display("$start_playing_hook not called?") end unless stl snd_display("$stop_playing_hook not called?") end unless ph snd_display("$play_hook not called?") end $start_playing_hook.reset_hook! $start_playing_selection_hook.reset_hook! $stop_playing_hook.reset_hook! $play_hook.reset_hook! $play_hook.add_hook!("snd-test") do |n| set_expand_control_hop(0.02) set_expand_control_length(0.02) set_expand_control_ramp(0.2) set_contrast_control_amp(0.5) set_reverb_control_lowpass(0.02) set_reverb_control_feedback(0.02) end # play(ind, :wait, true) $play_hook.reset_hook! $start_playing_hook.add_hook!("snd-test") do |snd| true end play("4.aiff") $start_playing_hook.reset_hook! # ss = false old_reg = selection_creates_region set_selection_creates_region(true) $stop_playing_selection_hook.add_hook!("snd-test") do | | ss = true end reg = select_all play(selection, :wait, true) play(reg, :wait, true) unless ss snd_display("$stop_playing_selection_hook not called?") end $stop_playing_selection_hook.reset_hook! set_selection_creates_region(old_reg) play(ind, :wait, true) # e0 = e1 = u0 = u1 = a0 = a1 = false edit_hook(ind, 0).add_hook!("snd-test-1") do | | e0 = true end edit_hook(other, 0).add_hook!("snd-test-2") do | | e1 = true; false end undo_hook(ind, 0).add_hook!("snd-test-1") do | | u0 = true end undo_hook(other, 0).add_hook!("snd-test-2") do | | u1 = true end after_edit_hook(ind, 0).add_hook!("snd-test-1") do | | a0 = true end after_edit_hook(other, 0).add_hook!("snd-test-2") do | | a1 = true end # delete_sample(0, ind, 0) if edit_position(ind, 0) != 0 snd_display("edit_hook true did not disallow edit!") end unless e0 snd_display("edit_hook true not called?") end if a0 snd_display("after_edit_hook 0 called?") end undo_edit(1, ind, 0) if u0 snd_display("undo_hook called?") end # delete_sample(0, other, 0) if edit_position(other, 0) != 1 snd_display("edit_hook false did not allow edit!") end unless e1 snd_display("edit_hook false not called?") end unless a1 snd_display("after_edit_hook 1 not called?") end undo_edit(1, other, 0) unless u1 snd_display("undo_hook not called?") end # edit_hook(ind, 0).reset_hook! edit_hook(other, 0).reset_hook! undo_hook(ind, 0).reset_hook! undo_hook(other, 0).reset_hook! after_edit_hook(ind, 0).reset_hook! after_edit_hook(other, 0).reset_hook! # $snd_error_hook.reset_hook! $snd_warning_hook.reset_hook! $mus_error_hook.reset_hook! se = false sw = false me = false se_msg = "se_msg" sw_msg = "sw_msg" me_msg = "me_msg" $snd_error_hook.add_hook!("snd-test") do |msg| se_msg = msg se = true end $snd_warning_hook.add_hook!("snd-test") do |msg| sw_msg = msg sw = true end $mus_error_hook.add_hook!("snd-test") do |type, msg| me_msg = msg me = true end snd_error("uhoh") snd_warning("hiho") mus_sound_samples("/bad/baddy") unless se snd_display("$snd_error_hook not called (%s != uhoh)?", se_msg) end unless sw snd_display("$snd_warning_hook not called (%s != hiho)?", sw_msg) end unless me snd_display("$mus_error_hook not called (%s)?", me_msg) end $snd_error_hook.reset_hook! $snd_warning_hook.reset_hook! $mus_error_hook.reset_hook! $snd_error_hook.add_hook!("snd-test") do |msg| se = msg true end snd_error("not an error") if se != "not an error" snd_display("$snd_error_hook saw: %s?", se) end # $before_exit_hook.add_hook!("snd-test-1") do | | false end $before_exit_hook.add_hook!("snd-test-2") do | | true end $exit_hook.add_hook!("snd-test-3") do | | false end exit $exit_hook.reset_hook! $before_exit_hook.reset_hook! # sh = false delete_file("baddy.snd") $save_hook.add_hook!("snd-test") do |snd, filename| if (not string?(filename)) or filename != mus_expand_filename("baddy.snd") snd_display("$save_hook filename: %s?", filename) end unless snd.eql?(ind) snd_display("$save_hook: %s not %s?", snd, ind) end sh = true end save_sound_as("baddy.snd", ind) unless sh snd_display("$save_hook not called?") end if File.exist?("baddy.snd") snd_display("$save_hook did not cancel save?") delete_file("baddy.snd") end $save_hook.reset_hook! $close_hook.add_hook!("snd-test") do |snd| unless snd.eql?(ind) snd_display("$close_hook: %s not %s?", snd, ind) end cl = true end close_sound(ind) unless cl snd_display("$close_hook not called?") end $close_hook.reset_hook! close_sound(other) end def test_13_02 unless $with_test_alsa in1 = open_sound("oboe.snd") in2 = open_sound("2.snd") set_sync(1, in1) set_sync(1, in2) play(selected_sound, :wait, true) close_sound(in1) close_sound(in2) end # ind = open_sound("oboe.snd") if $with_test_motif edhist = channel_widgets(ind, 0)[7] edp = RXtParent(edhist) pmax = RXtVaGetValues(edp, [RXmNpaneMaximum, 0]).cadr RXtUnmanageChild(edp) RXtVaSetValues(edp, [RXmNpaneMinimum, 100]) RXtManageChild(edp) end edit_hook_ctr = 0 after_edit_hook_ctr = 0 edit_hook(ind, 0).add_hook!("snd-test") do | | edit_hook_ctr += 1 true end after_edit_hook(ind, 0).add_hook!("snd-test") do | | after_edit_hook_ctr += 1 true end all_tests = [[:apply_controls, lambda { | | set_amp_control(0.5, ind, 0) apply_controls(ind) set_amp_control(1.0, ind, 0) }], [:clm_channel, lambda { | | clm_channel(make_two_zero(1, -1)) }], [:convolve_selection_with, lambda { | | reg = select_all(ind, 0) convolve_selection_with("1a.snd", 0.5) region?(reg) and forget_region(reg) }], [:convolve_with, lambda { | | convolve_with("1a.snd", 0.5, ind, 0)}], [:delete_sample, lambda { | | delete_sample(123, ind, 0) }], [:delete_samples, lambda { | | delete_samples(123, 123, ind, 0) }], [:delete_selection, lambda { | | reg = select_all(ind, 0) delete_selection region?(reg) and forget_region(reg) }], [:env_channel, lambda { | | env_channel([0, 0, 1, 1]) }], [:env_selection, lambda { | | reg = select_all(ind, 0) env_selection([0, 0, 1, 1], 1.0) region?(reg) and forget_region(reg) }], [:env_sound, lambda { | | env_sound([0, 0, 1, 1]) }], [:filter_sound, lambda { | | filter_sound([0, 1, 1, 0], 1024) }], [:filter_selection, lambda { | | reg = select_all(ind, 0) filter_selection([0, 0, 1, 1], 6) region?(reg) and forget_region(reg) }], [:insert_region, lambda { | | reg = make_region(0, 100, ind, 0) insert_region(reg, 123, ind, 0) region?(reg) and forget_region(reg) }], [:insert_sample, lambda { | | insert_sample(123, 0.5, ind, 0) }], [:insert_samples, lambda { | | insert_samples(123, 3, make_vct(3, 1.0), ind, 0) }], [:insert_selection, lambda { | | reg = select_all(ind, 0) insert_selection(120, ind, 0) region?(reg) and forget_region(reg) }], [:insert_silence, lambda { | | insert_silence(123, 456, ind, 0) }], [:insert_sound, lambda { | | insert_sound("1a.snd", 123) }], [:map_chan, lambda { | | map_chan(lambda { |y| y + 0.2 }) }], [:map_channel, lambda { | | map_channel(lambda { |y| y + 0.2 }) }], [:mix, lambda { | | mix("1a.snd", 123) }], [:mix_amp, lambda { | | mx = mix_vct(make_vct(3, 1.0), 123) mix?(mx) and set_mix_amp(mx, 0.123) }], [:mix_amp_env, lambda { | | mx = mix_vct(make_vct(3, 1.0), 123) mix?(mx) and set_mix_amp_env(mx, [0, 0, 1, 1]) }], [:mix_position, lambda { | | mx = mix_vct(make_vct(3, 1.0), 123) mix?(mx) and set_mix_position(mx, 123) }], [:mix_speed, lambda { | | mx = mix_vct(make_vct(3, 1.0), 123) mix?(mx) and set_mix_speed(mx, 0.123) }], [:mix_region, lambda { | | reg = make_region(0, 100, ind, 0) mix_region(reg, 123, ind, 0) region?(reg) and forget_region(reg) }], [:mix_selection, lambda { | | reg = select_all(ind, 0) mix_selection(1234, ind, 0) region?(reg) and forget_region(reg) }], [:mix_vct, lambda { | | mix_vct(make_vct(10, 0.3), 123) }], [:pad_channel, lambda { | | pad_channel(123, 456, ind, 0) }], [:ramp_channel, lambda { | | ramp_channel(0.0, 0.5, 123, 456) }], [:reverse_channel, lambda { | | reverse_channel(123, 456, ind, 0) }], [:reverse_sound, lambda { | | reverse_sound(ind, 0) }], [:reverse_selection, lambda { | | reg = select_all(ind, 0) reverse_selection region?(reg) and forget_region(reg) }], [:scale_by, lambda { | | scale_by(2.0) }], [:scale_channel, lambda { | | scale_channel(0.5, 123, 456, ind, 0) }], [:scale_selection_by, lambda { | | reg = select_all(ind, 0) scale_selection_by(2.0) region?(reg) and forget_region(reg) }], [:scale_selection_to, lambda { | | reg = select_all(ind, 0) scale_selection_to(0.5) region?(reg) and forget_region(reg) }], [:scale_to, lambda { | | scale_to(0.4) }], [:scale_sound_to, lambda { | | scale_sound_to(0.5) }], [:smooth_channel, lambda { | | smooth_channel(123, 456, ind, 0) }], [:smooth_sound, lambda { | | smooth_sound(123, 456, ind, 0) }], [:smooth_selection, lambda { | | reg = select_all(ind, 0) smooth_selection region?(reg) and forget_region(reg) }], [:src_channel, lambda { | | src_channel(0.5, 123, 456, ind, 0) }], [:src_sound, lambda { | | src_sound([0, 0.5, 1, 1]) }], [:src_selection, lambda { | | reg = select_all(ind, 0) src_selection(0.5) region?(reg) and forget_region(reg) }], [:swap_channels, lambda { | | ind1 = open_sound("1a.snd") swap_channels(ind, 0, ind1, 0) close_sound(ind1) }], [:vct2channel, lambda { | | vct2channel(make_vct(3), 123, 3, ind, 0) }], [:xramp_channel, lambda { | | xramp_channel(0.5, 1.0, 32.0, 123, 456, ind, 0) }]] # all_tests.each do |name, func| Snd.catch do func.call end if (res = edit_position(ind, 0)) != 0 snd_display("%s: blocked edit: %s?", name, res) end if edit_hook_ctr != 1 snd_display("%s: edit_hook calls: %s?", name, edit_hook_ctr) end if after_edit_hook_ctr != 0 snd_display("%s: after_edit_hook calls: %s?", name, after_edit_hook_ctr) end edit_hook_ctr = 0 if (res = mixes(ind, 0)) != nil snd_display("%s: mixes: %s?", name, res) end end # edit_hook_ctr = 0 after_edit_hook_ctr = 0 edit_hook(ind, 0).reset_hook! after_edit_hook(ind, 0).reset_hook! edit_hook(ind, 0).add_hook!("snd-test") do | | edit_hook_ctr += 1 false end after_edit_hook(ind, 0).add_hook!("snd-test") do | | after_edit_hook_ctr += 1 true end # all_tests.each do |name, func| func.call unless (res = edit_position(ind, 0)) > 0 snd_display("%s: unblocked edit: %s?", name, res) end unless edit_hook_ctr > 0 snd_display("%s: unblocked edit_hook calls: %s?", name, edit_hook_ctr) end unless after_edit_hook_ctr > 0 snd_display("%s: unblocked after_edit_hook calls: %s?", name, after_edit_hook_ctr) end edit_hook_ctr = 0 after_edit_hook_ctr = 0 revert_sound(ind) end if $with_test_motif edhist = channel_widgets(ind, 0)[7] edp = RXtParent(edhist) pmax = RXtVaGetValues(edp, [RXmNpaneMaximum, 0]).cadr RXtUnmanageChild(edp) RXtVaSetValues(edp, [RXmNpaneMinimum, 100]) RXtManageChild(edp) end close_sound(ind) # # before|after-save-as-hook # hook_called = false $before_save_as_hook.add_hook!("snd-test") do |snd, fname, sel, sr, type, fmt, com| if sr != srate(snd) channels(snd).times do |chn| src_channel(srate(snd).to_f / sr, 0, false, snd, chn) end save_sound_as(fname, snd, :header_type, type, :sample_type, fmt, :srate, sr, :comment, com) channels(snd).times do |chn| undo_edit(1, snd, chn) end hook_called = true true else false end end ind = open_sound("2.snd") save_sound_as("test.snd", :srate, 44100) if (res = edit_position(ind, 0)).nonzero? snd_display("$before_save_as_hook undo_edit: %s?", res) end unless hook_called snd_display("$before_save_as_hook not called?") end close_sound(ind) ind = open_sound("test.snd") if (res = srate(ind)) != 44100 snd_display("$before_save_as_hook src: %s?", res) end close_sound(ind) $before_save_as_hook.remove_hook!("snd-test") # need_save_as_undo = false $before_save_as_hook.add_hook!("snd-test") do |snd, fname, sel, sr, type, fmt, com| need_save_as_undo = false if sr != srate(snd) src_sound(srate(snd).to_f / sr, 1.0, snd) need_save_as_undo = true end false end $after_save_as_hook.add_hook!("snd-test") do |snd, fname, dialog| if need_save_as_undo undo_edit end end ind = open_sound("oboe.snd") save_sound_as("test.snd", :srate, 44100) if (res = edit_position(ind, 0)).nonzero? snd_display("$after_save_as_hook undo_edit: %s?", res) end close_sound(ind) ind = open_sound("test.snd") if (res = srate(ind)) != 44100 snd_display("$before|after_save_as_hook src: %s?", res) end close_sound(ind) $before_save_as_hook.reset_hook! $after_save_as_hook.reset_hook! # old_clip = clipping old_mus_clip = mus_clipping set_clipping(true) set_mus_clipping(true) $clip_hook.reset_hook! index = new_sound("test.snd", 1, 22050, Mus_bshort, Mus_next, "clip-hook test", 10) map_channel(lambda do |y| mus_random(0.999) end) set_sample(2, 1.0001) set_sample(4, -1.0) set_sample(6, 1.5) set_sample(8, -1.5) hook_called = 0 vals = channel2vct(0, 10, index) $clip_hook.add_hook!("test-13-clip") do |val| if fneq(val, 1.0) and fneq(val, 1.5) and fneq(val, -1.5) snd_display("$clip_hook called upon: %s?", val) end hook_called += 1 0.0 end save_sound(index) $clip_hook.reset_hook! if hook_called != 3 snd_display("$clip_hook called %s times?", hook_called) end close_sound(index) index = open_sound("test.snd") new_vals = channel2vct(0, 10, index) fixed_vals = vct_copy(vals) fixed_vals[2] = 0.0 fixed_vals[6] = 0.0 fixed_vals[8] = 0.0 unless vequal(fixed_vals, new_vals) snd_display("$clip_hook results:\n%s\n%s\n%s?", new_vals, fixed_vals, vals) end close_sound(index) set_clipping(old_clip) set_mus_clipping(old_mus_clip) end def test_13 if $with_test_gui reset_almost_all_hooks test_13_00 test_13_01 test_13_02 end end # ---------------- test 14: all together now ---------------- def test_panel(func) val = snd_func(func, true) val1 = Snd.sounds.apply(:snd_func, func) val2 = Snd.sounds.reverse.apply(:snd_func, func) if (not vequal(val, val1)) and (not vequal(val, val2)) snd_display_prev_caller("%s %s:\n\t%s\n\t%s\n\t%s?", get_func_name, func, val, val1, val2) end end def all_chans_zipped_reverse new_list = [] Snd.sounds.reverse.each do |snd| channels(snd).times do |chn| new_list.push([snd, chn]) end end new_list end def test_channel(func) val = snd_func(func, true, true).flatten val1 = all_chans_zipped.map do |snd, chn| snd_func(func, snd, chn) end.flatten val2 = all_chans_zipped_reverse.map do |snd, chn| snd_func(func, snd, chn) end.flatten if (not val.eql?(val1)) and (not val.eql?(val2)) snd_display_prev_caller("%s %s:\n\t%s\n\t%s\n\t%s?", get_func_name, func, val, val1, val2) end end def duration(snd) framples(snd) / srate(snd).to_f end def safe_make_selection(beg, fin, snd) len = framples(snd) old_choice = selection_creates_region() set_selection_creates_region(true) if len > 1 if fin < len make_selection(beg, fin, snd) else if beg < len make_selection(beg, len - 1, snd) else make_selection(0, len - 1, snd) end end end set_selection_creates_region(old_choice) end def clone_sound_as(new_name, snd = false) string?(save_dir) or set_save_dir("/tmp") old_snd = Snd.snd(snd) fdir, fbase = File.split(snd_tempnam) rb = fdir + "/" + File.basename(fbase, ".snd") + ".rb" save_edit_history(rb, old_snd) file_copy(file_name(old_snd), new_name) sfile = open_sound(new_name) eval(File.open(rb).read) delete_file(rb) sfile end def test_14 if $with_test_gui cur_dir_files = [] sound_files_in_directory(".").each do |f| if Snd.catch(:all, 0) do mus_sound_framples(f) end.first > 0 cur_dir_files.push(f) end end $after_open_hook.add_hook!("make_player") do |snd| make_player(snd, 0) end open_ctr = 0 stereo_files = [] quad_files = [] mono_files = [] octo_files = [] open_files = [] cur_dir_files.each do |name| ht = mus_sound_header_type(name) df = mus_sound_sample_type(name) len = mus_sound_framples(name) if ht != Mus_raw and len.nonzero? and df != -1 case mus_sound_chans(name) when 1 mono_files.push(name) when 2 stereo_files.push(name) when 4 quad_files.push(name) when 8 octo_files.push(name) end end end with_buffers_menu Snd.sounds.each do |snd| mxpos = 0 channels(snd).times do |chn| mxpos += edit_position(snd, chn) end if mxpos > 100 or channels(snd) > 4 snd_display("revert %s at %s?", file_name(snd), mxpos) revert_sound(snd) end end files = Snd.sounds.length delete_file("s61.rb") Snd.sounds.each do |s| if channels(s) > 4 open_files.delete_if do |f| f == s end close_sound(s) end end save_state("s61.rb") Snd.sounds.apply(:close_sound) Snd.regions.apply(:forget_region) load("s61.rb") if Snd.sounds.length != files snd_display("save_state restart from %s to %s sounds?", files, Snd.sounds.length) end open_files = Snd.sounds len = open_files.length open_chance = [0.0, (8.0 - len) * 0.125].max close_chance = len * 0.125 if len.zero? name = cur_dir_files[random(cur_dir_files.length)] ht = mus_sound_header_type(name) df = mus_sound_sample_type(name) fd = (ht == Mus_raw or df == -1) ? -1 : view_sound(name) if number?(fd) and fd != -1 open_files.push(fd) else close_sound(fd) end end if len > 0 fd = open_files[random(open_files.length)] close_sound(fd) open_files.delete_if do |f| f == fd end end open_ctr = open_files.length if open_ctr.zero? fd = view_sound("oboe.snd") open_ctr = 1 open_files.push(fd) end choose_fd = lambda do Snd.sounds[random(Snd.sounds.length)] end curfd = choose_fd.call curloc = [0, [1200, framples(curfd, 0)].min].max old_marks = Snd.marks(curfd, 0).length if (dur = duration(curfd)) > 0.0 set_x_bounds([0.0, [dur, 1.0].min], curfd) xb = x_bounds(curfd) if fneq(xb[0], 0.0) or fneq(xb[1], [dur, 1.0].min) snd_display("x_bounds: %s?", xb) end end set_y_bounds([-0.5, 0.5], curfd) yb = y_bounds(curfd) if fneq(yb[0], -0.5) or fneq(yb[1], 0.5) snd_display("y_bounds: %s?", yb) end set_cursor(curloc, curfd, 0) cl = cursor(curfd, 0) if cl != curloc and (res = framples(curfd, 0)) > curloc snd_display("cursor %s != %s (framples: %s)?", cl, curloc, res) curloc = cursor(curfd, 0) end if curloc >= framples(curfd, 0) curloc = 0 end id = Snd.catch(:all, -1) do add_mark(curloc, curfd) end.car if number?(id) and id != -1 cl = mark_sample(id) new_marks = Snd.marks(curfd, 0).length if cl != curloc snd_display("mark %s != %s?", cl, curloc) end if new_marks != (old_marks + 1) snd_display("marks %s %s?", new_marks, old_marks) end new_id = find_mark(curloc, curfd) if (not mark?(new_id)) or id != new_id snd_display("find_mark (by sample): %s %s (%s for %s %s)?", id, new_id, curloc, mark_sample(id), mark_sample(new_id)) end set_mark_name(id, "hiho") new_id = find_mark("hiho", curfd) if (not mark?(new_id)) or id != new_id snd_display("find_mark (by name): %s %s (%s for %s %s)?", id, new_id) end if (res = mark_name(id)) != "hiho" snd_display("mark_name: %s?", res) end set_mark_sample(id, [0, curloc - 100].max) cl = mark_sample(id) if cl != [0, curloc - 100].max snd_display("set_mark_sample %s != %s?", cl, curloc) end delete_mark(id) end if duration(curfd) > 1.2 set_x_bounds([1.0, 1.1], curfd) end if framples(curfd) > 25 add_mark(10, curfd) add_mark(20, curfd) key(key_to_int(?m), 0, curfd) set_cursor(0, curfd) new_marks = Snd.marks(curfd, 0).length delete_marks(curfd) if duration(curfd) > 0.0 set_x_bounds([0.0, [duration(curfd), 0.1].min], curfd) end set_y_bounds([-1.0, 1.0], curfd) if Snd.marks(curfd, 0).length > 0 or new_marks != (old_marks + 3) snd_display("delete marks: %s %s?", new_marks, old_marks) end end revert_sound old_settings = selection_creates_region() set_selection_creates_region(true) reg = select_all() Snd.catch do if region?(reg) and selection?() r1 = region_rms(regions.first) r2 = selection_rms snd_test_neq(r1, r2, "region_rms") set_selection_creates_region(old_settings) end end Snd.catch do if region?(regions[2]) play(regions[2], :wait, true) end end Snd.catch do mix_region(regions[2]) end framples < 100000 and play(selected_sound, :wait, true) scale_to(0.1, choose_fd.call) scale_by(2.0, choose_fd.call) save_controls set_amp_control(0.5) test_panel(:amp_control) restore_controls Snd.catch do cfd = choose_fd.call safe_make_selection(1000, 2000, cfd) src_selection(0.5) undo_edit(1, cfd) cfd = choose_fd.call safe_make_selection(1000, 2000, cfd) src_selection(-1.5) undo_edit(1, cfd) cfd = choose_fd.call safe_make_selection(1000, 2000, cfd) scale_selection_by(0.5) undo_edit(1, cfd) cfd = choose_fd.call safe_make_selection(1000, 2000, cfd) env_selection([0, 0, 1, 1, 2, 0]) undo_edit(1, cfd) cfd = choose_fd.call safe_make_selection(1000, 2000, cfd) scale_selection_to(0.5) reverse_selection undo_edit(2, cfd) Snd.regions.length > 2 and forget_region(regions[2]) end open_files.apply(:revert_sound) Snd.catch do cfd = open_files.first set_sync(1, cfd) open_files.length > 1 and set_sync(1, open_files[1]) safe_make_selection(1000, 2000, cfd) src_selection(0.5) undo_edit(1, cfd) safe_make_selection(1000, 2000, cfd) src_selection(-1.5) undo_edit(1, cfd) safe_make_selection(1000, 2000, cfd) env_selection([0, 0, 1, 1, 2, 0]) undo_edit(1, cfd) safe_make_selection(1000, 2000, cfd) reverse_selection undo_edit(1, cfd) safe_make_selection(1000, 2000, cfd) filter_selection([0, 0, 0.1, 1, 1, 0], 40) undo_edit(1, cfd) safe_make_selection(1000, 2000, cfd) convolve_selection_with("oboe.snd") undo_edit(1, cfd) safe_make_selection(1000, 2000, cfd) smooth_selection undo_edit(1, cfd) safe_make_selection(1000, 2000, cfd) scale_selection_by(0.5) undo_edit(1, cfd) scale_selection_to(0.5) reverse_selection undo_edit(2, cfd) src_selection([0, 0.5, 1, 1]) undo_edit revert_sound(cfd) open_files.length > 1 and revert_sound(open_files[1]) end # frms = framples() if frms > 1 and frms < 10000 make_region(0, frms) convolve_selection_with("fyow.snd", 0.5) play(selected_sound, :wait, true) end if frms > 1 and frms < 10000 convolve_with("fyow.snd", 0.25) end insert_sound("oboe.snd") $graph_hook.reset_hook! $after_transform_hook.reset_hook! open_files.apply(:revert_sound) # ind = choose_fd.call select_sound(ind) [[lambda { |beg| insert_sound("2a.snd", beg) }, lambda { |beg| insert_sound("4a.snd", beg) }], [lambda { |beg| reverse_sound }, lambda { |beg| reverse_sound }], [lambda { |beg| if framples(ind) < 10000 convolve_with("2a.snd", 0.5) else scale_by(2.0) end }, lambda { |beg| src_sound(2.0) }], [lambda { |beg| env_sound([0, 0, 1, 1, 2, 0]) }, lambda { |beg| env_sound([0, 0, 1, 1]) }], [lambda { |beg| smooth_sound }, lambda { |beg| insert_silence(beg, 100) }] ].each do |func, func1| pad_channel(0, 100, ind, 0) func.call(0) pad_channel(0, 100, ind, 0) func1.call(0) revert_sound(ind) if channels(ind) > 1 pad_channel(0, 100, ind, 1) func.call(0) pad_channel(0, 100, ind, 1) func1.call(0) revert_sound(ind) end delete_samples(0, 1000, ind, 0) func.call(2 * framples(ind, 0)) delete_samples(0, 1000, ind, 0) func1.call(2 * framples(ind, 0)) revert_sound(ind) if channels(ind) > 1 delete_samples(0, 1000, ind, 1) func.call(2 * framples(ind, 1)) delete_samples(0, 1000, ind, 1) func1.call(2 * framples(ind, 1)) revert_sound(ind) end end # ind = open_sound("z.snd") restore_controls if framples(ind).nonzero? snd_display("framples z.snd: %s?", framples(ind)) end if samples != false snd_display("samples of empty file (z): %s?", samples) end if channel2vct != false snd_display("channel2vct of empty file (z): %s?", channel2vct) end if fneq(maxamp(ind), 0.0) snd_display("maxamp z.snd: %s?", maxamp(ind)) end if fneq(sample(100, ind), 0.0) snd_display("sample 100 z.snd: %s?", sample(100, ind)) end scale_by(2.0) if (res = edit_position(ind, 0)).nonzero? snd_display("scale z: %s?", res) end env_sound([0, 0, 1, 1]) if (res = edit_position(ind, 0)).nonzero? snd_display("env_sound z: %s?", res) end smooth_sound if (res = edit_position(ind, 0)).nonzero? snd_display("smooth_sound z: %s?", res) end reverse_sound if (res = edit_position(ind, 0)).nonzero? snd_display("reverse_sound z: %s?", res) end src_sound(2.0) if (res = edit_position(ind, 0)).nonzero? snd_display("src_sound z: %s?", res) end insert_sound("z.snd") if (res = edit_position(ind, 0)).nonzero? snd_display("insert_sound z: %s?", res) end mix("z.snd") if (res = edit_position(ind, 0)).nonzero? snd_display("mix z: %s?", res) end filter_sound(make_one_zero(:a0, 2.0, :a1, 0.0)) if (res = edit_position(ind, 0)).nonzero? snd_display("filter_sound z: %s?", res) end if fneq(res = mus_sound_duration("z.snd"), 0.0) snd_display("mus_sound_duration z.snd: %s?", res) end Snd.catch(:io_error) do convolve_with("z.snd", 1.0) end if (res = edit_position(ind, 0)).nonzero? snd_display("convolve_with z: %s?", res) end if (res = Snd.catch do find_channel(lambda do |y| y > 0.1 end) end).first != :no_such_sample snd_display("find z: %s", res.inspect) end if (res = Snd.catch do count_matches(lambda do |y| y > 0.1 end) end).first != :no_such_sample snd_display("count_matches z: %s", res.inspect) end reader = make_sampler(0) val = next_sample(reader) if fneq(val, 0.0) snd_display("sampler z.snd: %s?", val) end unless string?(reader.to_s) snd_display("z.snd reader: %s?", reader.to_s) end if (res = cursor_position) != [0, 0] snd_display("cursor_position z: %s?", res) end if (res = cursor).nonzero? snd_display("cursor z: %ws?", res) end outer = make_player(ind, 0) pl = make_player(ind, 0) add_player(pl) start_playing(1, 22050, false) revert_sound(ind) set_transform_graph?(true, ind, 0) $lisp_graph_hook.add_hook!("display_energy") do |snd, chn| display_energy(snd, chn) end set_x_bounds([0.0, 0.01]) set_sample(0, 0.5) set_x_bounds([0.0, 0.001]) close_sound(ind) if (res = Snd.catch do add_player(outer) end).first != :no_such_player snd_display("dangling player: %s", res.inspect) end if res = channel_amp_envs("z.snd", 0, 100) snd_display("channel_amp_envs of empty file: %s?", res) end # zz = view_sound("z.snd") select_sound(zz) mix("4.aiff").car add_mark(0) add_mark(1200) delete_marks revert_sound(zz) editctr = edit_position(zz) if (res = edit_position(zz)).nonzero? snd_display("revert_sound edit_position: %s?", res) end s8_snd = (File.exist?("s8.snd") ? "s8.snd" : "oboe.snd") as_one_edit_rb do mix(s8_snd, 24000) reg = select_all if selection? filter_selection([0, 0, 0.2, 1, 0.5, 0, 1, 0], 40) delete_selection mix_region(reg) end end if (res = edit_position(zz)) != 1 snd_display("as_one_edit mix zz: %s -> %s?", editctr, res) end close_sound(zz) s8 = view_sound(s8_snd) select_sound(s8) if channels(s8) == 8 select_channel(5) if (not number?(selected_channel)) or selected_channel != 5 snd_display("select_channel: %s?", select_channel) end end editctr = edit_position as_one_edit_rb do reg = select_all delete_selection mix("4.aiff") set_sync(1) mix("oboe.snd", 60000) scale_by(0.1) set_sync(1) if channels(s8) > 3 select_channel(3) end if region?(reg) insert_region(reg, 80000) end end snd_test_neq(edit_position(), editctr + 1, "as_one_edit s8") revert_sound(s8) close_sound(s8) # cfd = choose_fd.call if channels(cfd) > 1 uval = random(3) set_channel_style(uval, cfd) snd_test_neq(channel_style(cfd), uval, "channel_style") end if framples(cfd) < 200000 src_sound(2.5, 1.0, cfd) src_sound(-2.5, 1.0, cfd) src_sound(0.5, 1.0, cfd) revert_sound(cfd) src_sound(-0.5, 1.0, cfd) src_sound([0, 0.5, 1, 1.5], 1.0, cfd) if framples(cfd) > 0 src_sound(make_env([0, 0.5, 1, 1.5], :length, framples(cfd)), 1.0, cfd) end revert_sound(cfd) filter_sound([0, 1, 0.2, 0, 0.5, 1, 1, 0], 20, cfd) filter_sound([0, 0, 0.1, 0, 0.11, 1, 0.12, 0, 1, 0], 2048, cfd) env_sound([0, 0, 0.5, 1, 1, 0], 0, framples(cfd), 1.0, cfd) insert_sample(1200, 0.1, cfd) snd_test_neq(sample(1200, cfd), 0.1, "insert_sample(looped)") end revert_sound(cfd) # cfd = open_sound("obtest.snd") select_sound(cfd) cfd2 = open_sound("pistol.snd") select_sound(cfd2) set_amp_control(0.5) set_speed_control(2.0) test_panel(:speed_control) apply_controls framples < 100000 and play(selected_sound, :wait, true) if fneq(res1 = reverb_control_decay(cfd), res2 = reverb_control_decay) snd_display("reverb_control_decay local: %s, global: %s?", res1, res2) end set_reverb_control?(true) set_reverb_control_scale(0.2) test_panel(:reverb_control_scale) test_panel(:reverb_control_length) test_panel(:reverb_control_lowpass) test_panel(:reverb_control_feedback) apply_controls framples < 100000 and play(selected_sound, :wait, true) set_contrast_control?(true) set_contrast_control(0.5) test_panel(:contrast_control) test_panel(:contrast_control_amp) apply_controls framples < 100000 and play(selected_sound, :wait, true) set_expand_control?(true) set_expand_control(2.5) test_panel(:expand_control) test_panel(:expand_control_length) test_panel(:expand_control_hop) test_panel(:expand_control_ramp) apply_controls framples < 100000 and play(selected_sound, :wait, true) set_filter_control?(true) set_filter_control_order(40) test_panel(:filter_control_order) set_filter_control_envelope([0, 0, 0.1, 1, 0.2, 0, 1, 0]) filter_control_envelope apply_controls framples < 100000 and play(selected_sound, :wait, true) set_amp_control(1.5) test_panel(:amp_control) apply_controls framples < 100000 and play(selected_sound, :wait, true) swap_channels(cfd, 0, cfd2, 0) set_amp_control(0.75, true) test_panel(:amp_control) if (res = amp_control(cfd2) - 0.75).abs > 0.05 snd_display("set_amp_control 0.75, true: %s?", res) end set_contrast_control_amp(0.75, true) if fneq(res = contrast_control_amp(cfd2), 0.75) snd_display("set_contrast_control_amp 0.75, true: %s?", res) end set_contrast_control_bounds([2.0, 3.0], cfd2) unless vequal(res = contrast_control_bounds(cfd2), [2.0, 3.0]) snd_display("set_contrast_control_bound (cfd2): %s?", res) end set_expand_control_length(0.025, true) if fneq(res = expand_control_length(cfd2), 0.025) snd_display("set_expand_control_length 0.025, true: %s?", res) end set_expand_control_hop(0.025, true) if fneq(res = expand_control_hop(cfd2), 0.025) snd_display("set_expand_control_hop 0.025, true: %s?", res) end set_expand_control_jitter(0.025, true) if fneq(res = expand_control_jitter(cfd2), 0.025) snd_display("set_expand_control_jitter 0.025, true: %s?", res) end set_expand_control_ramp(0.025, true) if fneq(res = expand_control_ramp(cfd2), 0.025) snd_display("set_expand_control_ramp 0.025, true: %s?", res) end clone = clone_sound_as("/tmp/cloned.snd", cfd2) if framples(cfd2) != framples(clone) snd_display("clone framples: %s %s?", framples(cfd2), framples(clone)) end close_sound(clone) delete_file("/tmp/cloned.snd") mus_sound_forget("/tmp/cloned.snd") close_sound(cfd2) close_sound(cfd) edit_hook.add_hook!("snd-test") do | | false end editctr = edit_position as_one_edit_rb do set_sample(200, 0.2) set_sample(300, 0.3) end if (res = edit_position) != editctr + 1 snd_display("as_one_edit: %s -> %s?", editctr, res) end as_one_edit_rb do false end if (res = edit_position) != editctr + 1 snd_display("as_one_edit nil: %s -> %s?", editctr, res) end delete_sample(250) undo_hook.add_hook!("snd-test") do | | false end undo_edit delete_sample(250) undo_edit as_one_edit_rb do set_sample(20, 0.2) set_sample(30, 0.3) end undo_edit(1) as_one_edit_rb do set_sample(2, 0.2) as_one_edit_rb do set_sample(3, 0.3) end end undo_edit(2) undo_hook.reset_hook! edit_hook.reset_hook! sw_msg = "sw_msg" $snd_warning_hook.add_hook!("snd-test") do |msg| sw_msg = msg if msg != "hiho" snd_display("$snd_warning_hook: %s?", msg) end true end snd_warning("hiho") if sw_msg != "hiho" snd_display("$snd_warning_hook not called (%s != hiho)?", sw_msg) end $snd_error_hook.reset_hook! $snd_warning_hook.reset_hook! if proc? $my_snd_error_hook $snd_error_hook.add_hook!("sndtestrc", &$my_snd_error_hook) end if proc? $my_mus_error_hook $mus_error_hook.add_hook!("sndtestrc", &$my_mus_error_hook) end $name_click_hook.add_hook!("snd-test") do |n| true end redo_edit(1) $name_click_hook.reset_hook! set_transform_graph?(true) test_channel(:transform_graph?) test_channel(:time_graph?) test_channel(:lisp_graph?) test_channel(:framples) test_channel(:cursor) test_channel(:cursor_size) test_channel(:cursor_style) test_channel(:tracking_cursor_style) test_channel(:left_sample) test_channel(:right_sample) test_channel(:squelch_update) test_channel(:x_zoom_slider) test_channel(:y_zoom_slider) test_channel(:x_position_slider) test_channel(:y_position_slider) test_channel(:edit_position) test_channel(:maxamp) test_channel(:edit_hook) test_channel(:after_edit_hook) test_channel(:undo_hook) func = lambda do |len, fd| steps = len / 16 step = 1.0 / len v = Vct.new(len, 0.0) v.length.times do |i| val = next_sample(fd).abs bin = (val * 16.0).round if bin < steps steps.times do |j| v[j + bin] += step end end end v end set_transform_type(add_transform("histogram", "bins", 0.0, 1.0, func)) set_x_bounds([0.1, 0.2]) set_transform_type($fourier_transform) set_x_bounds([0.1, 0.2]) $lisp_graph_hook.add_hook!("display_energy") do |snd, chn| display_energy(snd, chn) end $graph_hook.reset_hook! if channels() == 2 $graph_hook.add_hook!("correlate") do |snd, chn, y0, y1| display_correlate(snd, chn, y0, y1) end set_x_bounds([0.1, 0.12]) set_x_bounds([0.1, 0.2]) $graph_hook.remove_hook!("correlate") end set_lisp_graph?(false) sum_of_squares = 0.0 buffer = Vct.new(128) position = 0 current_sample = 0 chan_samples = framples map_chan_rb do |y| old_y = buffer[position] sum_of_squares = (sum_of_squares + y * y) - old_y * old_y buffer[position] = y position += 1 if position == 128 position = 0 end current_sample += 1 if sum_of_squares > 0.01 if current_sample == chan_samples Vct.new(128) do |i| final_y = buffer[position] val = sum_of_squares > 0.01 ? final_y : 0.0 sum_of_squares = sum_of_squares - final_y * final_y position += 1 if position == 128 position = 0 end val end else old_y end else false end end # maxval1 = maxamp + 0.01 unless every_sample? do |y| y < maxval1 end res = scan_channel(lambda do |y| y >= maxval1 end) snd_display("%s, every_sample?: %s %s [%s: %s]?", short_file_name, maxval1, res, cursor, sample(cursor)) edit_position.times do |i| snd_display("%s: %s %s", i, maxamp(false, 0, i), edit_fragment(i)) end end map_chan(echo(0.5, 0.75), 0, 60000) $after_transform_hook.reset_hook! $lisp_graph_hook.reset_hook! $lisp_graph_hook.add_hook!("snd-test") do |snd, chn| graph(vct(0, 1, 2)) end Snd.sounds.each do |snd| set_sync((random(3)), snd) end $graph_hook.add_hook!("superimpose_ffts") do |snd, chn, y0, y1| superimpose_ffts(snd, chn, y0, y1) end 10.times do |i| Snd.sounds.each do |snd| if framples(snd) > 0 dur = (framples(snd) / srate(snd).to_f).floor.to_f start = [0.0, [dur - 0.1, random(dur)].min].max if dur > 0.0 set_x_bounds([start, [start + 0.1, dur].min], snd, 0) end end end end $graph_hook.reset_hook! $lisp_graph_hook.reset_hook! # # new variable settings # [[:amp_control, true, 0.1, 1.0], [:auto_update, false, false, true], [:channel_style, false, 0, 2], [:color_cutoff, false, 0.0,0.2], [:color_inverted, false, false, true], [:color_scale, false, 0.1, 1000.0], [:contrast_control, true, 0.0, 1.0], [:contrast_control_amp, true, 0.0, 1.0], [:contrast_control?, true, false, true], [:auto_update_interval, false, 60.0, 120.0], [:cursor_update_interval, false, 0.05, 0.1], [:cursor_location_offset, false, 0, 1024], [:with_tracking_cursor, false, false, true], [:cursor_size, false, 15, 25], [:cursor_style, false, Cursor_cross, Cursor_line], [:tracking_cursor_style, false, Cursor_line, Cursor_cross], [:clipping, false, false, true], [:dot_size, false, 1, 10], [:enved_base, false, 0.01, 100.0], [:enved_clip?, false, false, true], [:enved_in_dB, false, false, true], [:enved_style, false, Envelope_linear, Envelope_exponential], [:enved_power, false, 3.0, 3.5], [:enved_target, false, 0, 2], [:enved_wave?, false, false, true], [:expand_control, true, 0.1, 5.0], [:expand_control_hop, true, 0.01, 0.5], [:expand_control_jitter, true, 0.01, 0.5], [:expand_control_length, true, 0.1, 0.25], [:expand_control_ramp, true, 0.1, 0.4], [:expand_control?, true, false, true], [:fft_window_alpha, false, 0.0, 1.0], [:fft_window_beta, false, 0.0, 1.0], [:fft_log_frequency, false, false, true], [:fft_log_magnitude, false, false, true], [:fft_with_phases, false, false, true], [:transform_size, false, 16, 128], [:transform_graph_type, false, Graph_once, Graph_as_spectrogram], [:transform_graph?, true, false, true], [:filter_control_in_dB, true, false, true], [:filter_control_in_hz, true, false, true], [:filter_control_order, true, 2, 400], [:filter_control?, true, false, true], # [:graph_cursor, false, 0, 35], [:time_graph_style, false, 0, 4], [:lisp_graph_style, false, 0, 4], [:transform_graph_style, false, 0, 4], [:graphs_horizontal, false, false, true], [:max_transform_peaks, false, 1, 100], [:max_regions, false, 1, 32], [:min_dB, false, -120.0, -30.0], [:log_freq_start, false, 50.0, 5.0], [:selection_creates_region, false, false, true], [:transform_normalization, false, Dont_normalize, Normalize_globally], [:play_arrow_size, false, 2, 32], [:print_length, false, 2, 32], [:region_graph_style, false, Graph_lines, Graph_lollipops], [:reverb_control_decay, false, 0.0, 2.0], [:reverb_control_feedback, true, 1.0, 1.1], [:reverb_control_length, true, 1.0, 2.0], [:reverb_control_lowpass, true, 0.2, 0.99], [:reverb_control_scale, true, 0.0, 0.2], [:reverb_control?, true, false, true], [:show_axes, false, 0, 2], [:show_transform_peaks, false, false, true], [:show_indices, false, false, true], [:show_marks, false, false, true], [:show_mix_waveforms, true, false, true], [:show_selection_transform, false, false, true], [:show_y_zero, false, false, true], [:show_grid, false, false, true], [:grid_density, true, 0.1, 4.0], [:show_sonogram_cursor, false, false, true], [:sinc_width, false, 4, 100], [:spectrum_end, false, 0.5, 0.8], [:spectro_hop, false, 2, 20], [:spectrum_start, false, 0.0, 0.1], [:spectro_x_angle, false, 0.0, 90.0], [:spectro_x_scale, false, 0.1, 2.0], [:spectro_y_angle, false, 0.0, 90.0], [:spectro_y_scale, false, 0.1, 2.0], [:spectro_z_angle, false, 0.0, 359.0], [:spectro_z_scale, false, 0.1, 0.2], [:speed_control, true, 0.1, 5.0], [:speed_control_style, false, 0, 2], [:speed_control_tones, false, 2, 100], [:sync, true, 0, 5], [:sync_style, false, 0, 3], [:with_verbose_cursor, false, false, true], [:wavelet_type, false, 0, 10], [:time_graph?, true, false, true], [:x_axis_style, false, 0, 2], [:beats_per_minute, false, 60.0, 120.0], [:beats_per_measure, false, 4, 120], [:zero_pad, false, 0, 2], [:zoom_focus_style, false, 0, 3]].each do |func, index_p, minval, maxval| index = index_p ? choose_fd.call : false if index if minval == false set_snd_func(func, true, index) else val = minval + (maxval - minval) * random(1.0) set_snd_func(func, (integer?(minval) and val.floor or val), index) end else if minval == false set_snd_func(func, true) else val = minval + (maxval - minval) * random(1.0) set_snd_func(func, (integer?(minval) and val.floor or val)) end end end if transform_type != $fourier_transform set_transform_graph?(false, true, true) set_transform_size([transform_size, 128].min) end open_files.apply(:close_sound) set_sync_style(Sync_none) set_mus_rand_seed(1234) if mus_rand_seed != 1234 snd_display("mus_rand_seed: %s (1234)?", mus_rand_seed) end val = mus_random(1.0) val1 = mus_random(1.0) if fneq(val, -0.7828) or fneq(val1, -0.8804) snd_display("mus_random: %s %s?", val, val1) end if mus_rand_seed == 1234 snd_display("mus_rand_seed: %s?", mus_rand_seed) end set_mus_rand_seed(1234) val = mus_random(1.0) val1 = mus_random(1.0) if fneq(val, -0.7828) or fneq(val1, -0.8804) snd_display("mus_random repeated: %s %s?", val, val1) end $after_open_hook.reset_hook! $close_hook.reset_hook! $open_hook.reset_hook! end end # ---------------- test 15: chan-local vars ---------------- def prefix_it(n, id) key(key_to_int(?u), 0, id) n.to_s.each_byte do |c| key(c, 0, id) end end def prefix_uit(n, id) n.to_s.each_byte do |c| key(c, 0, id) end end def test_history_channel(func, new_val, snd1, snd2, snd3) test_equal = lambda do |nv, new_val| if float?(nv) (not fneq(nv, new_val)) else nv == new_val end end chan_equal_p = lambda do |vals, new_val| if vals.null? true elsif list_p(vals) (not vals.detect do |val| val != new_val end) else test_equal.call(vals, new_val) end end test_channel(func) old_value = snd_func(func) old_chan_value = snd_func(func, snd1, 0) set_snd_func(func, new_val, snd1, 0) unless test_equal.call(nv = snd_func(func, snd1, 0), new_val) snd_display_prev_caller("%s: set_%s[1]: %s %s?", get_func_name, func, new_val, nv) end set_snd_func(func, new_val, snd3, 2) unless test_equal.call(nv = snd_func(func, snd3, 2), new_val) snd_display_prev_caller("%s: set_%s[2]: %s %s?", get_func_name, func, new_val, nv) end unless test_equal.call(old_value, new_val) if test_equal.call(nv = snd_func(func, snd3, 1), new_val) snd_display_prev_caller("%s: set_%s[3]: %s %s?", get_func_name, func, new_val, nv) end end set_snd_func(func, new_val, snd2, true) unless test_equal.call(nv = snd_func(func, snd2, 1), new_val) snd_display_prev_caller("%s: set_%s[4]: %s %s?", get_func_name, func, new_val, nv) end set_snd_func(func, new_val) unless chan_equal_p.call(nv = snd_func(func, true, true).flatten, new_val) snd_display_prev_caller("%s: set_%s[5]: %s %s?", get_func_name, func, new_val, nv) end set_snd_func(func, old_value) end def freq_peak(beg, ind, size) interpolated_peak_offset = lambda do |la, ca, ra| pk = 0.001 + [la, ca, ra].max logla = log([la, 0.0000001].max / pk) / log(10) logca = log([ca, 0.0000001].max / pk) / log(10) logra = log([ra, 0.0000001].max / pk) / log(10) 0.5 * (logla - logra) / ((logla + logra) - 2 * logca) end data = channel2vct(beg, size, ind, 0) spectr = snd_spectrum(data, Blackman2_window, size) peak0 = 0.0 pk0loc = 0 (size / 2).times do |i| if spectr[i] > peak0 peak0 = spectr[i] pk0loc = i end end [((pk0loc + (pk0loc > 0 ? interpolated_peak_offset.call(spectr[pk0loc - 1], spectr[pk0loc], spectr[pk0loc + 1]) : 0.0)) * srate) / size, peak0] end def smoother(y0, y1, num) angle = y1 > y0 ? PI : 0.0 off = 0.5 * (y0 + y1) incr = PI / num scale = 0.5 * (y1 - y0).abs Vct.new(num + 1) do |i| off + scale * cos(angle + i * incr) end end def test_selection(ind, beg, len, scaler) set_selection_member?(true, ind, 0) set_selection_position(beg) set_selection_framples(len) scale_selection_by(scaler) diff = 0.0 pos = edit_position(ind, 0) old_reader = make_sampler(beg, ind, 0, 1, pos - 1) new_reader = make_sampler(beg, ind, 0, 1, pos) len.times do |i| ov = scaler * old_reader.call nv = next_sample(new_reader) val = (ov - nv).abs diff += val end if diff > 0.0 snd_display_prev_caller("diff (%s %s): %s?", beg, len, diff) end diff = 0.0 100.times do |i| ov = next_sample(old_reader) nv = next_sample(new_reader) val = (ov - nv).abs diff += val end if diff > 0.0 snd_display_prev_caller("zdiff (%s %s): %s?", beg, len, diff) end free_sampler(old_reader) free_sampler(new_reader) end def test_selection_to(ind, beg, len, maxval) set_selection_member?(true, ind, 0) set_selection_position(beg) set_selection_framples(len) scale_selection_to(maxval) newmax = 0.0 new_reader = make_sampler(beg, ind, 0) len.times do nv = next_sample(new_reader).abs if nv > newmax newmax = nv end end if fneq(newmax, maxval) snd_display_prev_caller("%s (%s %s) %s: %s?", get_func_name, beg, len, maxval, newmax) end free_sampler(new_reader) end def play_with_amps_1(snd, *amps) channels(snd).times do |chn| player = make_player(snd, chn) unless player?(player) snd_display("player? %s -> false?", player) end unless players.member?(player) snd_display("player: %s, but players: %s?", player, players) end if (res = player_home(player)) != [snd, chn] snd_display("player_home %s %s?", res, [snd, chn]) end set_amp_control(amps[chn], player) set_speed_control(0.5, player) set_expand_control?(true, player) set_expand_control(2.0, player) set_contrast_control?(true, player) set_contrast_control(1.0, player) set_reverb_control?(true, player) set_reverb_control_scale(0.02, player) end start_playing(channels(snd), srate(snd), false) end def test_15_00 snds = match_sound_files do |file| File.exist?(file) and # for $tests > 1 mus_sound_header_type(file) != Mus_raw and mus_sound_chans(file) == 1 end if snds.length > 0 obi = open_sound(snds.first) if all_chans != [[obi], [0]] snd_display("all_chans (1): %s?", all_chans) end snds1 = match_sound_files do |file| File.exist?(file) and # for $tests > 1 mus_sound_chans(file) == 2 end if snds1.length > 0 s2i = open_sound(snds1.first) res = all_chans req1 = [[obi, s2i, s2i], [0, 0, 1]] req2 = [[s2i, s2i, obi], [0, 1, 0]] if res != req1 and res != req2 snd_test_neq(res, req1, "all_chans (2a)") snd_test_neq(res, req2, "all_chans (2b)") end res = finfo("oboe.snd") req = "oboe.snd: chans: 1, srate: 22050, Sun/Next, big endian short (16 bits), len: 2.305" snd_test_neq(res, req, "finfo") close_sound(s2i) else snd_display("No sound file found for s2i: %s", snds1) end close_sound(obi) else snd_display("No sound file found obi: %p", snds) end res = all_chans req = [[], []] snd_test_neq(res, req, "all_chans(0) (3)") obi = open_sound("oboe.snd") set_cursor(1000, obi) snd_test_neq(locate_zero(0.001), 1050, "locate_zero") $graph_hook.add_hook!("auto_dot") do |snd, chn, y0, y1| auto_dot(snd, chn, y0, y1) end $graph_hook.add_hook!("superimpose_ffts") do |snd, chn, y0, y1| superimpose_ffts(snd, chn, y0, y1) end set_transform_graph?(true, obi, 0) update_graphs # snds = match_sound_files do |file| File.exist?(file) and # for $tests > 1 mus_sound_chans(file) == 2 end if snds.length > 0 s2i = open_sound(snds.first) snd_test_neq(channels(s2i), 2, "match 2 got %s", short_file_name(s2i)) update_graphs $graph_hook.remove_hook!("auto_dot") $graph_hook.remove_hook!("superimpose_ffts") set_transform_graph?(false, obi, 0) select_sound(obi) m1 = add_mark(100, obi, 0) first_mark_in_window_at_left res = left_sample(obi, 0) - 100 snd_test_gt(res, 1, "first_mark_in_window_at_left %s", mark_sample(m1)) delete_mark(m1) close_sound(s2i) else $graph_hook.remove_hook!("auto_dot") $graph_hook.remove_hook!("superimpose_ffts") snd_display("No sound file found: %p", snds) end safe_make_selection(1000, 2000, obi) delete_selection_and_smooth res = edit_fragment(0, obi, 0) req = ["", "init", 0, 50828] snd_test_neq(res, req, "edit_fragment (0)") res = edit_fragment(1, obi, 0) req = ["delete_samples(1000, 1001", "delete", 1000, 1001] snd_test_neq(res, req, "edit_fragment (1)") res = edit_fragment(2, obi, 0) req = ["delete-selection-and-smooth", "set", 968, 64] snd_test_neq(res, req, "edit_fragment (2)") # maxa = maxamp(obi) normalized_mix("pistol.snd", 1000, 0, obi, 0) nmaxa = maxamp(obi) snd_test_neq(nmaxa, maxa, "normalized_mix") revert_sound(obi) snds = match_sound_files do |file| File.exist?(file) and # for $tests > 1 mus_sound_chans(file) == 2 and mus_sound_framples(file) > 1000 end if snds.length > 0 s2i = open_sound(snds.first) res = channels(s2i) snd_test_neq(res, 2, "match_sound_files: 2+1000 got %s with", short_file_name(s2i)) o1 = sample(1000, obi, 0) s1 = sample(1000, s2i, 0) s2 = sample(1000, s2i, 1) do_all_chans("double all samples") do |val| (val ? (2.0 * val) : false) end o11 = sample(1000, obi, 0) s11 = sample(1000, s2i, 0) s21 = sample(1000, s2i, 1) reso1 = 2.0 * o1 ress1 = 2.0 * s1 ress2 = 2.0 * s2 if fneq(reso1, o11) or fneq(ress1, s11) or fneq(ress2, s21) snd_test_neq(reso1, o11, "do_all_chans (a)") snd_test_neq(ress1, s11, "do_all_chans (b)") snd_test_neq(ress2, s21, "do_all_chans (c)") end update_graphs m1 = maxamp(obi, 0) m2 = maxamp(s2i, 0) m3 = maxamp(s2i, 1) mc = [[obi, 0], [s2i, 0], [s2i, 1]].map do |snd, chn| maxamp(snd, chn) end if fneq(m1, mc[0]) or fneq(m2, mc[1]) or fneq(m3, mc[2]) snd_test_neq(m1, mc[0], "map maxamp (a)") snd_test_neq(m2, mc[1], "map maxamp (b)") snd_test_neq(m3, mc[2], "map maxamp (c)") end set_sync(1, obi) set_sync(1, s2i) do_chans("*2") do |val| (val ? (2.0 * val) : false) end mc1 = [[obi, 0], [s2i, 0], [s2i, 1]].map do |snd, chn| maxamp(snd, chn) end resm1 = 2.0 * m1 resm2 = 2.0 * m2 resm3 = 2.0 * m3 if fneq(resm1, mc1[0]) or fneq(resm2, mc1[1]) or fneq(resm3, mc1[2]) snd_test_neq(resm1, mc1[0], "do_chans (a)") snd_test_neq(resm2, mc1[1], "do_chans (b)") snd_test_neq(resm3, mc1[2], "do_chans (c)") end set_sync(0, obi) set_sync(0, s2i) select_sound(s2i) do_sound_chans("/2") do |val| (val ? (0.5 * val) : false) end mc2 = [[obi, 0], [s2i, 0], [s2i, 1]].map do |snd, chn| maxamp(snd, chn) end m1 *= 2.0 if fneq(m1, mc2[0]) or fneq(m2, mc2[1]) or fneq(m3, mc2[2]) snd_test_neq(m1, mc2[0], "do_sound_chans (a)") snd_test_neq(m2, mc2[1], "do_sound_chans (b)") snd_test_neq(m3, mc2[2], "do_sound_chans (c)") end if every_sample? do |val| val > 0.5 end snd_display("every_sample? (0)?") end unless every_sample? do |val| val < 5.0 end snd_display("every_sample? (1)?") end select_sound(obi) res = sort_samples(32)[1] snd_test_neq(res, 4504, "sort_samples") revert_sound(s2i) revert_sound(obi) set_sync(3, obi) set_sync(3, s2i) half_way = (0.5 * framples(obi)).floor o1 = sample(half_way, obi, 0) s1 = sample(half_way, s2i, 0) s2 = sample(half_way, s2i, 1) place_sound(obi, s2i, [0, 0.5, 1, 0.5]) s21 = sample(half_way, s2i, 0) s22 = sample(half_way, s2i, 1) revert_sound(s2i) place_sound(obi, s2i, 45.0) s31 = sample(half_way, s2i, 0) s32 = sample(half_way, s2i, 1) res1 = s1 + 0.5 * o1 res2 = s2 + 0.5 * o1 if fneq(res1, s21) or fneq(res2, s22) or fneq(s21, s31) or fneq(s22, s32) snd_test_neq(res1, s21, "place_sound (a)") snd_test_neq(res2, s22, "place_sound (b)") snd_test_neq(s21, s31, "place_sound (c)") snd_test_neq(s22, s32, "place_sound (d)") end revert_sound(s2i) revert_sound(obi) set_sync(0, obi) set_sync(0, s2i) res1 = compand.call(0.0) res2 = compand.call(1.0) res3 = compand.call(0.1) res4 = compand.call(0.99) res5 = compand.call(0.95) if fneq(res1, 0.0) or fneq(res2, 1.0) or fneq(res3, 0.2) or fneq(res4, 0.997) or fneq(res5, 0.984) snd_test_neq(res1, 0.0, "compand (a)") snd_test_neq(res2, 1.0, "compand (b)") snd_test_neq(res3, 0.2, "compand (c)") snd_test_neq(res4, 0.997, "compand (d)") snd_test_neq(res5, 0.984, "compand (e)") end close_sound(obi) revert_sound(s2i) # s1 = sample(1000, s2i, 0) s2 = sample(1000, s2i, 1) set_sync(4, s2i) select_all if selection_chans != 2 snd_display("selection_chans (2): %s?", selection_chans) Snd.sounds.each do |snd| channels(snd).times do |chn| if selection_member?(snd, chn) snd_display("%s[%s] at %s?", short_file_name(snd), chn, selection_position(snd, chn)) end end end end res = selection_srate req = srate(s2i) snd_test_neq(res, req, "selection_srate") if selection_chans == 2 swap_selection_channels res1 = sample(1000, s2i, 1) res2 = sample(1000, s2i, 0) if fneq(res1, s1) or fneq(res2, s2) snd_test_neq(res1, s1, "swap_selection_channels (a)") snd_test_neq(res2, s2, "swap_selection_channels (b)") end end revert_sound(s2i) close_sound(s2i) else snd_display("No sound file found s2i: %p", snds) end # obi = open_sound("oboe.snd") if $with_test_gui select_all Snd.regions.apply(:forget_region) if regions != nil snd_display("no regions: %s?", regions.inspect) end id = make_region(100, 200, obi, 0) if (!(regions.eql?([id]))) snd_display("make_region regions: %s?", regions.inspect) end revert_sound(obi) oldlen = framples(obi) env_sound_interp([0, 0, 1, 1, 2, 0], 2.0, obi, 0) newlen = framples(obi) if (2 * oldlen - newlen).abs > 3 snd_display("env_sound_interp: %s %s?", oldlen, newlen) end end # revert_sound(obi) granulated_sound_interp([0, 0, 1, 0.1, 2, 1], 1.0, 0.2, [0, 0, 1, 1, 2, 0]) snd_test_neq(edit_position(obi, 0), 1, "granulated_sound_interp no-op 1") snd_test_lt(maxamp(obi, 0), 0.15, "granulated_sound_interp 1 maxamp") res = (framples(obi, 0) - 50828).abs snd_test_gt(res, 1000, "granulated_sound_interp 1 framples") revert_sound(obi) granulated_sound_interp([0, 0, 1, 1], 2.0) snd_test_neq(edit_position(obi, 0), 1, "granulated_sound_interp no-op 2") snd_test_lt(maxamp(obi, 0), 0.145, "granulated_sound_interp 2 maxamp") res = (framples(obi, 0) - 101656).abs snd_test_gt(res, 1000, "granulated_sound_interp 2 framples") revert_sound(obi) granulated_sound_interp([0, 0, 1, 0.1, 2, 1], 1.0, 0.2, [0, 0, 1, 1, 2, 0], 0.02) snd_test_neq(edit_position(obi, 0), 1, "granulated_sound_interp no-op 3") snd_test_lt(maxamp(obi, 0), 0.2, "granulated_sound_interp 3 maxamp") res = (framples(obi, 0) - 50828).abs snd_test_gt(res, 1000, "granulated_sound_interp 3 framples") close_sound(obi) end def test_15_01 ind = new_sound("test.snd", :size, 20) offset_channel(1.0) env_sound([0, 0, 1, 1]) osc = make_oscil(:frequency, 1000.0, :initial_phase, PI + HALF_PI) reader = make_sound_interp(0, ind, 0) len = framples(ind, 0) - 1 map_channel_rb do |val| sound_interp(reader, len * (0.5 + 0.5 * oscil(osc))) end snd_test_neq(channel2vct(), vct(0.000, 0.020, 0.079, 0.172, 0.291, 0.427, 0.569, 0.706, 0.825, 0.919, 0.979, 1.000, 0.981, 0.923, 0.831, 0.712, 0.576, 0.434, 0.298, 0.177), "sound_interp") undo_edit osc = make_oscil(:frequency, 0.5, :initial_phase, PI + HALF_PI) reader = make_sound_interp(0, ind, 0) len = framples(ind, 0) - 1 map_channel(lambda do |val| sound_interp(reader, len * (0.5 + 0.5 * oscil(osc))) end) undo_edit env_sound_interp([0, 0, 1, 1]) snd_test_neq(channel2vct(), vct(0.000, 0.053, 0.105, 0.158, 0.211, 0.263, 0.316, 0.368, 0.421, 0.474, 0.526, 0.579, 0.632, 0.684, 0.737, 0.789, 0.842, 0.895, 0.947, 1.000), "env_sound_interp no change") undo_edit env_sound_interp([0, 0, 1, 0.95, 2, 0], 2.0) snd_test_neq(channel2vct(), vct(0.000, 0.050, 0.100, 0.150, 0.200, 0.250, 0.300, 0.350, 0.400, 0.450, 0.500, 0.550, 0.600, 0.650, 0.700, 0.750, 0.800, 0.850, 0.900, 0.950, 1.000, 0.950, 0.900, 0.850, 0.800, 0.750, 0.700, 0.650, 0.600, 0.550, 0.500, 0.450, 0.400, 0.350, 0.300, 0.250, 0.200, 0.150, 0.100, 0.050), "env_sound_interp twice len and back") revert_sound(ind) set_sample(10, 0.5) remove_clicks snd_test_neq(sample(10), 0.0, "remove_clicks") undo_edit val = scan_channel(search_for_click) snd_test_neq(val, 11, "search_for_click") close_sound(ind) # id = open_sound("oboe.snd") fr = framples(id, 0) mx = maxamp(id, 0) set_framples(25000, id, 0) if (res = framples(id, 0)) != 25000 snd_display("set_framples 25000: %s?", res) end if (res = edit_position(id, 0)) != 1 snd_display("set_framples 25000 edit: %s?", res) end set_framples(75000, id, 0) if (res = framples(id, 0)) != 75000 snd_display("set_framples 75000: %s?", res) end if (res = edit_position(id, 0)) != 2 snd_display("set_framples 75000 edit: %s?", res) end if fneq(res = sample(30000, id, 0), 0.0) snd_display("set_framples 75000 zeros: %s?", res) end set_framples(0, id, 0) if (res = framples(id, 0)) != 0 snd_display("set_framples 0: %s?", res) end set_framples(100, id, 0) if (res = framples(id, 0)) != 100 snd_display("set_framples 100: %s?", res) end revert_sound if fneq(res = sample(30000, id, 0), -0.0844) snd_display("revert from set_framples: %s?", res) end if (res = framples(id, 0)) != fr snd_display("revert set_framples: %s != %s?", res, fr) end set_maxamp(0.5, id, 0) if fneq(res = maxamp(id, 0), 0.5) snd_display("set_maxamp: %s?", res) end if (res = edit_position(id, 0)) != 1 snd_display("set_maxamp edit: %s?", res) end set_maxamp(0.1, id, 0) if fneq(res = maxamp(id, 0), 0.1) snd_display("set_maxamp 0.1: %s?", res) end if (res = edit_position(id, 0)) != 2 snd_display("set_maxamp 0.1 edit: %s?", res) end revert_sound if fneq(res = maxamp(id, 0), mx) snd_display("maxamp after set: %s %s?", res, mx) end set_x_position_slider(0.1, id, 0) if fneq(res = x_position_slider(id, 0), 0.1) snd_display("set_x_position_slider 0.1: %s?", res) end set_x_zoom_slider(0.5, id, 0) if fneq(res = x_zoom_slider(id, 0), 0.5) snd_display("set_x_zoom_slider 0.5: %s?", res) end if (res1 = (fr - 2 * ((res2 = right_sample(id, 0)) - (res3 = left_sample(id, 0)))).abs) > 10 snd_display("set_x_zoom_slider: %s %s --> %s?", res2, res3, res1) end set_y_position_slider(0.1, id, 0) if $with_test_motif and fneq(res = y_position_slider(id, 0), 0.1) snd_display("set_y_position_slider 0.1: %s?", res) end set_y_zoom_slider(0.5, id, 0) if fneq(res = y_zoom_slider(id, 0), 0.5) snd_display("set_y_zoom_slider 0.5: %s?", res) end # len = (channel_properties(id, 0) or []).length if res = channel_property(:hiho, id, 0) snd_display("channel_property :hiho: %s?", res) end set_channel_property(:hiho, 123, id, 0) if (res = channel_property(:hiho, id, 0)) != 123 snd_display("channel_property :hiho (123): %s?", res) end if res = channel_property(:hi, id, 0) snd_display("channel_property :hi: %s?", res) end set_channel_property(:hi, PI, id, 0) if (res = channel_property(:hi, id, 0)) != PI snd_display("channel_property :hi (PI): %s?", res) end if (res = channel_property(:hiho, id, 0)) != 123 snd_display("channel_property 2nd :hiho (123): %s?", res) end if (res = (channel_properties or []).length) != len + 2 snd_display("channel_properties: %s?", res) end # len = (sound_properties(id) or []).length if res = sound_property(:hiho, id) snd_display("sound_property :hiho: %s?", res) end set_sound_property(:hiho, 123, id) if (res = sound_property(:hiho, id)) != 123 snd_display("sound_property :hiho (123): %s?", res) end if res = sound_property(:hi, id) snd_display("sound_property :hi: %s?", res) end set_sound_property(:hi, PI, id) if (res = sound_property(:hi, id)) != PI snd_display("sound_property :hi (PI): %s?", res) end if (res = sound_property(:hiho, id)) != 123 snd_display("sound_property 2nd :hiho (123): %s?", res) end if (res = (sound_properties(id) or []).length) != len + 2 snd_display("sound_properties: %s?", res) end # XXX: S7 has here :wrong_type_arg # XXX: Ruby has still :bad_type res = Snd.catch do map_channel(lambda do |y| "hiho" end) end snd_test_neq(res.first, :bad_type, "map_channel bad val") close_sound(id) # id = open_sound("oboe.snd") prefix_it(1000, id) key(key_to_int(?x), 4, id) key(key_to_int(?b), 4, id) if (left = left_sample(id)) != 1000 snd_display("u1000: %s?", left) end prefix_it(0, id) key(key_to_int(?x), 4, id) key(key_to_int(?b), 4, id) if (left = left_sample(id)) != 0 snd_display("u0: %s?", left) end set_cursor(1234, id) prefix_it(0, id) key(key_to_int(?f), 4, id) if (cr = cursor(id)) != 1234 snd_display("0f: %s?", cr) end prefix_it(100, id) key(key_to_int(?f), 4, id) if (cr = cursor(id)) != 1334 snd_display("100f: %s?", cr) end prefix_it(-100, id) key(key_to_int(?f), 4, id) if (cr = cursor(id)) != 1234 snd_display("-100f: %s?", cr) end prefix_it(1, id) key(key_to_int(?f), 4, id) if (cr = cursor(id)) != 1235 snd_display("1f: %s?", cr) end prefix_it(1000, id) key(key_to_int(?x), 4, id) key(key_to_int(?p), 4, id) if ((right = right_sample(id)) - (left = left_sample(id)) - 1000).abs > 2 snd_display("1000xp: %s %s?", left, right) end prefix_it(1, id) key(key_to_int(?.), 0, id) key(key_to_int(?2), 0, id) key(key_to_int(?x), 4, id) key(key_to_int(?p), 4, id) if ((right = right_sample(id)) - (left = left_sample(id)) - (22050 * 1.2)).abs > 2 snd_display("1.2xp: %s %s?", left, right) end # prefix_uit(1000, id) key(key_to_int(?x), 4, id) key(key_to_int(?b), 4, id) if (left = left_sample(id)) != 1000 and left != 1001 snd_display("uu1000: %s?", left) end prefix_uit(0, id) key(key_to_int(?x), 4, id) key(key_to_int(?b), 4, id) if (left = left_sample(id)) != 0 snd_display("uu0: %s?", left) end set_cursor(1234, id) prefix_uit(0, id) key(key_to_int(?f), 4, id) if (cr = cursor(id)) != 1234 snd_display("u0f: %s?", cr) end prefix_uit(100, id) key(key_to_int(?f), 4, id) if (cr = cursor(id)) != 1334 snd_display("u100f: %s?", cr) end prefix_uit(-100, id) key(key_to_int(?f), 4, id) if (cr = cursor(id)) != 1234 snd_display("u-100f: %s?", cr) end prefix_uit(1, id) key(key_to_int(?f), 4, id) if (cr = cursor(id)) != 1235 snd_display("u1f: %s?", cr) end prefix_uit(1000, id) key(key_to_int(?x), 4, id) key(key_to_int(?p), 4, id) if ((right = right_sample(id)) - (left = left_sample(id)) - 1000).abs > 2 snd_display("u1000xp: %s %s?", left, right) end prefix_uit(1, id) key(key_to_int(?.), 0, id) key(key_to_int(?2), 0, id) key(key_to_int(?x), 4, id) key(key_to_int(?p), 4, id) if ((right = right_sample(id)) - (left = left_sample(id)) - (22050 * 1.2)).abs > 2 snd_display("u1.2xp: %s %s?", left, right) end close_sound(id) # snds = match_sound_files do |file| File.exist?(file) and # for $tests > 1 mus_sound_chans(file) >= 2 and mus_sound_framples(file) > 1000 end if snds.length > 0 id = open_sound(snds.first) set_sync(1, id) select_sound(id) make_region(200, 500, id) select_channel(1) key(key_to_int(?x), 4, id) key(key_to_int(?v), 0, id) if $with_test_gui x0 = x_bounds(id, 0) x1 = x_bounds(id, 1) if fneq(x0[0], x1[0]) or fneq(x0[1], x1[1]) snd_display("C-x v: %s %s?", x0, x1) end key(key_to_int(?u), 4, id) key(key_to_int(?1), 0, id) key(key_to_int(?x), 4, id) key(key_to_int(?q), 0, id) end close_sound(id) else snd_display("No sound file found id: %s", snds) end end def f3neq(a, b) fneq_err(a, b, 10) end def f4neq(a, b) fneq_err(a, b, 1) end def f5neq(a, b) fneq_err(a, b, 0.05 * [a, b].max) end def test_15_02 snd1 = open_sound("oboe.snd") snd2 = open_sound("2.snd") snd3 = open_sound("4.aiff") [[:time_graph_type, Graph_as_wavogram], [:wavo_hop, 12], [:wavo_trace, 512], [:max_transform_peaks, 3], [:show_transform_peaks, true], [:zero_pad, 32], [:transform_graph_type, Graph_as_sonogram], [:fft_window, Cauchy_window], [:with_verbose_cursor, true], [:fft_log_frequency, true], [:fft_log_magnitude, true], [:fft_with_phases, true], [:min_dB, -120.0], [:wavelet_type, 3], [:transform_size, 32], [:fft_window_alpha, 0.5], [:fft_window_beta, 0.5], [:transform_type, $autocorrelation], [:transform_normalization, 0], [:show_mix_waveforms, true], [:graph_style, Graph_lollipops], [:dot_size, 8], [:show_axes, Show_no_axes], [:show_y_zero, true], [:show_grid, true], [:show_marks, false], [:grid_density, 1.0], [:spectro_x_angle, 32.0], [:spectro_x_scale, 0.5], [:spectro_y_angle, 32.0], [:spectro_y_scale, 0.5], [:spectro_z_angle, 32.0], [:spectro_z_scale, 0.5], [:spectro_hop, 14], [:spectrum_end, 0.3], [:spectrum_start, 0.1], [:graphs_horizontal, false], [:x_axis_style, X_axis_in_samples], [:beats_per_minute, 120.0], [:beats_per_measure, 3], [:cursor_size, 15], [:cursor_style, Cursor_cross], [:tracking_cursor_style, Cursor_cross], [:show_sonogram_cursor, true]].each do |func, nv| test_history_channel(func, nv, snd1, snd2, snd3) end [snd1, snd2].apply(:close_sound) # set_time_graph_style(Graph_filled, snd3, true) 4.times do |chn| if (res = time_graph_style(snd3, chn)) != Graph_filled snd_display("set_time_graph_style %s %s (filled): %s?", snd3, chn, res) end end set_time_graph_style(Graph_lines, snd3, 2) 4.times do |chn| if chn == 2 if (res = time_graph_style(snd3, chn)) != Graph_lines snd_display("set_time_graph_style %s %s (lines): %s?", snd3, chn, res) end else if (res = time_graph_style(snd3, chn)) != Graph_filled snd_display("set_time_graph_style %s %s (filled): %s?", snd3, chn, res) end end end set_time_graph_style(Graph_dots, snd3, true) 4.times do |chn| if (res = time_graph_style(snd3, chn)) != Graph_dots snd_display("set_time_graph_style %s %s (dots): %s?", snd3, chn, res) end end set_graph_style(Graph_dots_and_lines) 4.times do |chn| if (res = time_graph_style(snd3, chn)) != Graph_dots_and_lines snd_display("set_time_graph_style %s %s (dots and lines): %s?", snd3, chn, res) end end set_lisp_graph_style(Graph_filled, snd3, true) 4.times do |chn| if (res = lisp_graph_style(snd3, chn)) != Graph_filled snd_display("set_lisp_graph_style %s %s (filled): %s?", snd3, chn, res) end end set_lisp_graph_style(Graph_lines, snd3, 2) 4.times do |chn| if chn == 2 if (res = lisp_graph_style(snd3, chn)) != Graph_lines snd_display("set_lisp_graph_style %s %s (lines): %s?", snd3, chn, res) end else if (res = lisp_graph_style(snd3, chn)) != Graph_filled snd_display("set_lisp_graph_style %s %s (filled): %s?", snd3, chn, res) end end end set_lisp_graph_style(Graph_lines, snd3, true) 4.times do |chn| if (res = lisp_graph_style(snd3, chn)) != Graph_lines snd_display("set_lisp_graph_style %s %s (lines): %s?", snd3, chn, res) end end set_transform_graph_style(Graph_filled, snd3, true) 4.times do |chn| if (res = transform_graph_style(snd3, chn)) != Graph_filled snd_display("set_transform_graph_style %s %s (filled): %s?", snd3, chn, res) end end set_transform_graph_style(Graph_lines, snd3, 2) 4.times do |chn| if chn == 2 if (res = transform_graph_style(snd3, chn)) != Graph_lines snd_display("set_transform_graph_style %s %s (lines): %s?", snd3, chn, res) end else if (res = transform_graph_style(snd3, chn)) != Graph_filled snd_display("set_transform_graph_style %s %s (filled): %s?", snd3, chn, res) end end end 4.times do |chn| if (res = time_graph_style(snd3, chn)) != Graph_dots_and_lines snd_display("set fft and lisp -> time_graph_style: %s?", snd3, chn, res) end end 4.times do |chn| if (res = lisp_graph_style(snd3, chn)) != Graph_lines snd_display("set fft and lisp -> lisp_graph_style: %s?", snd3, chn, res) end end close_sound(snd3) snd2 = open_sound("2.snd") sound?(snd2) and play_with_amps_1(snd2, 0.2, 0.1) close_sound(snd2) # old_bp = with_background_processes set_with_background_processes(false) ind = open_sound("1a.snd") player = make_player(ind, 0) len = framples(ind, 0) incr = dac_size e = make_env(:envelope, [0, 0, 1, 1], :length, (len.to_f / incr).floor + 1) samp = 0 add_player(player, 0, -1, -1, lambda do |reason| $play_hook.reset_hook! close_sound(ind) end) $play_hook.add_hook!("snd-test") do |fr| set_amp_control(env(e), player) if fneq(res = amp_control(ind), 1.0) snd_display("amp_control snd: %s?", res) end if ((res1 = amp_control(player)) - (res2 = samp / len.to_f)).abs > 1.0 snd_display("amp_control player: %s %s?", res1, res2) end samp += incr end start_playing(1, srate(ind)) if find_sound("1a.snd") snd_display("stop proc did not close?") Snd.catch do close_sound(ind) end end set_with_background_processes(old_bp) # ind = open_sound("pistol.snd") if res = selection_member?(ind, 0) snd_display("initial selection_member?: %s %s?", res, selection?) end set_selection_member?(true, ind, 0) if (not (res1 = selection_member?(ind, 0))) or (not (res2 = selection_member?(ind))) snd_display("selection_member? %s %s %s?", res1, res2, selection?) end if (res = selection_framples) != 1 snd_display("initial selection_framples: %s?", res) end set_selection_framples(1200) if (res = selection_framples) != 1200 snd_display("selection_framples 1200: %s?", res) end delete_selection if selection? snd_display("selection active after cut?") end undo_edit unless selection? snd_display("selection inactive after undo?") end if (not (res1 = selection_member?(ind, 0))) or (not (res2 = selection_member?(ind))) snd_display("selection_member? after undo %s %s %s?", res1, res2, selection?) end if (res1 = selection_framples) != 1200 or (res2 = selection_position) != 0 snd_display("selection after undo: [0, 1200] [%s, %s]?", res2, res1) end set_selection_position(1000) if (res1 = selection_framples) != 200 or (res2 = selection_position) != 1000 snd_display("selection after undo: [1000, 200] [%s, %s]?", res2, res1) end reverse_selection if (res1 = selection_framples) != 200 or (res2 = selection_position) != 1000 snd_display("selection after reverse: [1000, 200] [%s, %s]?", res2, res1) end old_framples = framples(ind) src_selection(0.5) if (framples(ind) - (200 + old_framples)).abs > 5 or ((res = selection_framples) - 400).abs > 5 snd_display("selection after src 0.5: [1000, 400] [%s, %s]?", res, selection_position) end undo_edit redo_edit if (framples(ind) - (200 + old_framples)).abs > 5 or ((res = selection_framples) - 400).abs > 5 snd_display("selection after src 0.5 with undo/redo: [1000, 400] [%s, %s]?", res, selection_position) end undo_edit(3) close_sound(ind) # # src-duration tests # ind = new_sound("test.snd", 1, 22050, Mus_bfloat, Mus_next, "src-* tests", 10000) osc = make_oscil(:frequency, 500) if fneq(res1 = src_duration([0, 1, 1, 2]), 0.693147180559945) or fneq(res2 = src_duration([0, 2, 1, 1]), src_duration([0, 1, 1, 2])) or fneq(res3 = src_duration([0, 1, 0.5, 2]), src_duration([0, 1, 1, 2])) or fneq(res4 = src_duration([0.5, 1, 0.75, 2]), src_duration([0, 1, 1, 2])) snd_display("src_duration test1: %s %s %s %s?", res1, res2, res3, res4) end if fneq(res1 = src_duration([0, 1, 1, 0.5]), 1.38629436111989) or fneq(res2 = src_duration([0, 0.5, 1, 1]), src_duration([0, 1, 1, 0.5])) or fneq(res3 = src_duration([0, 1, 0.5, 0.5]), src_duration([0, 1, 1, 0.5])) or fneq(res4 = src_duration([0.5, 1, 0.75, 0.5]), src_duration([0, 1, 1, 0.5])) snd_display("src_duration test2: %s %s %s %s?", res1, res2, res3, res4) end if fneq(res1 = src_duration([0, 1, 1, 1]), 1.0) or fneq(res2 = src_duration([0, 2, 1, 2]), 0.5) snd_display("src_duration test3: %s %s?", res1, res2) end if fneq(res = src_duration([0, 0.5, 0.5, 3, 0.6, 1, 0.7, 0.1, 0.8, 1.5, 1, 1]), 1.02474349685432) snd_display("src_duration test4: %s?", res) end if fneq(res = src_duration([0, 1, 1, 2, 2, 1]), 0.693147180559945) snd_display("src_duration test5: %s?", res) end map_channel_rb do |y| 0.5 * oscil(osc) end vals = freq_peak(0, ind, 8192) if f4neq(vals[0], 500.0) or fneq(vals[1], 1.0) snd_display("src no-test: %s?", vals) end # src_lists1 = [[2.0, 0.5], [0.5, 2.0], [5.0, 0.2], [0.2, 5.0]] src_lists2 = [[[0, 1, 1, 2], 500.0, 1000.0], [[0, 2, 1, 1], 1000.0, 500.0], [[0, 1, 1, 2, 2, 1], 500.0, 500.0], [[0, 0.5, 1, 1], 250.0, 500.0], [[0, 0.5, 1, 2], 250.0, 1000.0]] src_lists3 = [[0, 1, 1, 2], [0, 2, 1, 1], [0, 1, 1, 2, 2, 1], [0, 0.5, 1, 1], [0, 0.5, 1, 2]] # src_sound src_lists1.each do |sr, dur| src_sound(sr, 1.0, ind, 0) if fneq(res = framples(ind, 0) / 10000.0, dur) snd_display("src_sound %s: %s (%s)?", sr, res, dur) end vals = freq_peak(0, ind, 8192) if f4neq(vals[0], 500 * sr) or fneq(vals[1], 1.0) snd_display("src_sound %s freq: %s?", sr, vals) end undo_edit end src_lists2.each do |e, f0, f1| src_sound(e, 1.0, ind, 0) if fneq(res1 = framples(ind, 0) / 10000.0, res2 = src_duration(e)) snd_display("src_sound (env) %s: %s (%s)?", e, res1, res2) end vals = freq_peak(0, ind, 256) if f5neq(vals[0], f0) snd_display("src_sound (env) 0 %s freq: %s?", f0, vals) end vals = freq_peak((src_duration(e) * 10000.0).floor - 256, ind, 256) if f5neq(vals[0], f1) snd_display("src_sound (env) 1 %s freq: %s?", f1, vals) end undo_edit end src_lists2.each do |e, f0, f1| src_sound(make_env(:envelope, e, :length, framples), 1.0, ind, 0) if fneq(res1 = framples(ind, 0) / 10000.0, res2 = src_duration(e)) snd_display("src_sound (make_env) %s: %s (%s)?", e, res1, res2) end vals = freq_peak(0, ind, 256) if f5neq(vals[0], f0) snd_display("src_sound (make_env) 0 %s freq: %s?", f0, vals) end vals = freq_peak((src_duration(e) * 10000.0).floor - 256, ind, 256) if f5neq(vals[0], f1) snd_display("src_sound (make_env) 1 %s freq: %s?", f1, vals) end undo_edit end # src_channel src_lists1.each do |sr, dur| src_channel(sr) if fneq(res = framples(ind, 0) / 10000.0, dur) snd_display("src_channel %s: %s (%s)?", sr, res, dur) end vals = freq_peak(0, ind, 8192) if f4neq(vals[0], 500 * sr) or fneq(vals[1], 1.0) snd_display("src_channel %s freq: %s?", sr, vals) end undo_edit end src_lists2.each do |e, f0, f1| src_channel(e) if fneq(res1 = framples(ind, 0) / 10000.0, res2 = src_duration(e)) snd_display("src_channel (env) %s: %s (%s)?", e, res1, res2) end vals = freq_peak(0, ind, 256) if f5neq(vals[0], f0) snd_display("src_channel (env f0) %s freq: %s?", f0, vals) end vals = freq_peak((src_duration(e) * 10000.0).floor - 256, ind, 256) if f5neq(vals[0], f1) snd_display("src_channel (env f1) %s freq: %s?", f1, vals) end undo_edit end src_lists1.each do |sr, dur| src_channel(sr, 1000, 2500) if f4neq(res1 = framples(ind, 0), (res2 = 7500 + dur * 2500)) snd_display("src_channel section: %s %s?", res1, res) end vals = freq_peak(0, ind, 512) if f5neq(vals[0], 500.0) snd_display("src_channel section 0 %s freq: %s?", sr, vals) end vals = freq_peak(((dur * 2500.0).floor + 7500) - 512, ind, 512) if f5neq(vals[0], 500.0) snd_display("src_channel section 8000 %s freq: %s?", sr, vals) end vals = freq_peak(1000, ind, 512) if f5neq(vals[0], 500.0 * sr) snd_display("src_channel section %s freq: %s?", sr, vals) end undo_edit end src_lists3.each do |e| src_channel(make_env(:envelope, e, :length, 2501), 1000, 2500) if f3neq(res1 = framples(ind, 0), (res2 = 7500 + src_duration(e) * 2500)) snd_display("src_channel section (make_env duration) %s: %s (%s %s)?", e, src_duration(e), res1, res2) end vals = freq_peak(0, ind, 256) if f5neq(vals[0], 500.0) snd_display("src_channel section (make_env 0): %s?", vals) end vals = freq_peak(((src_duration(e) * 2500).floor + 7500) - 256, ind, 256) if f5neq(vals[0], 500.0) snd_display("src_channel section (make_env 1): %s?", vals) end undo_edit end # src_selection make_selection(1000, 3500, ind, 0) src_lists1.each do |sr, dur| src_selection(sr) if f3neq(res1 = framples(ind, 0), (res2 = 7500 + dur * 2500)) snd_display("src_selection section: %s %s?", res1, res) end vals = freq_peak(0, ind, 512) if f5neq(vals[0], 500.0) snd_display("src_selection section 0 %s freq: %s?", sr, vals) end vals = freq_peak(((dur * 2500.0).floor + 7500) - 512, ind, 512) if f5neq(vals[0], 500.0) snd_display("src_selection section 8000 %s freq: %s?", sr, vals) end vals = freq_peak(1000, ind, 512) if f5neq(vals[0], 500.0 * sr) snd_display("src_selection section %s freq: %s?", sr, vals) end undo_edit end src_lists3.each do |e| src_selection(make_env(:envelope, e, :length, 2501)) if f3neq(res1 = framples(ind, 0), (res2 = 7500 + src_duration(e) * 2500)) snd_display("src_selection section (make_env duration) %s: %s (%s %s)?", e, src_duration(e), res1, res2) end vals = freq_peak(0, ind, 256) if f5neq(vals[0], 500.0) snd_display("src_selection section (make_env 0): %s?", vals) end vals = freq_peak(((src_duration(e) * 2500).floor + 7500) - 256, ind, 256) if f5neq(vals[0], 500.0) snd_display("src_selection section (make_env 1): %s?", vals) end undo_edit end src_lists3.each do |e| src_selection(e) if f3neq(res1 = framples(ind, 0), (res2 = 7500 + src_duration(e) * 2500)) snd_display("src_selection section (env duration) %s: %s (%s %s)?", e, src_duration(e), res1, res2) end vals = freq_peak(0, ind, 256) if f5neq(vals[0], 500.0) snd_display("src_selection section (env 0): %s?", vals) end vals = freq_peak(((src_duration(e) * 2500).floor + 7500) - 256, ind, 256) if f5neq(vals[0], 500.0) snd_display("src_selection section (env 1): %s?", vals) end undo_edit end close_sound(ind) end def test_15_03 ind = new_sound("hi.snd") 10.times do |i| set_sample(i, i * 0.1, ind) end select_all(ind) set_sample(10, 1.0, ind) smooth_selection unless vequal(channel2vct(0, 11, ind).subseq(0, 9), smoother(0.0, 1.0, 10).subseq(0, 9)) snd_display("smooth_selection: %s %s?", channel2vct(0, 11, ind), smoother(0.0, 1.0, 10)) end revert_sound 10.times do |i| set_sample(i, 1.0 - i * 0.1, ind) end select_all(ind) set_sample(10, 0.0, ind) smooth_selection unless vequal(channel2vct(0, 11, ind).subseq(0, 9), smoother(1.0, 0.0, 10).subseq(0, 9)) snd_display("smooth_selection back: %s %s?", channel2vct(0, 11, ind), smoother(1.0, 0.0, 10)) end close_sound(ind) # ind = new_sound("hi.snd") 10.times do |i| set_sample(i, i * 0.1, ind) end set_sample(10, 1.0, ind) smooth_sound(0, 10, ind) unless vequal(channel2vct(0, 11, ind).subseq(0, 9), smoother(0.0, 1.0, 10).subseq(0, 9)) snd_display("smooth_sound: %s %s?", channel2vct(0, 11, ind), smoother(0.0, 1.0, 10)) end revert_sound 10.times do |i| set_sample(i, 1.0 - i * 0.1, ind) end set_sample(10, 0.0, ind) smooth_sound(0, 10, ind) unless vequal(channel2vct(0, 11, ind).subseq(0, 9), smoother(1.0, 0.0, 10).subseq(0, 9)) snd_display("smooth_sound back: %s %s?", channel2vct(0, 11, ind), smoother(1.0, 0.0, 10)) end close_sound(ind) delete_file("hi.snd") # ind = open_sound("oboe.snd") len = framples(ind) set_cursor(1200, ind) key(key_to_int(?u), 4, ind) key(key_to_int(?1), 0, ind) key(key_to_int(?0), 0, ind) key(key_to_int(?0), 0, ind) key(key_to_int(?o), 4, ind) snd_test_neq(framples(ind), 100 + len, "C-o len") data = channel2vct(1200, 100, ind) snd_test_neq(vct_peak(data), 0.0, "C-o") revert_sound(ind) set_cursor(1200, ind) key(key_to_int(?u), 4, ind) key(key_to_int(?1), 0, ind) key(key_to_int(?0), 0, ind) key(key_to_int(?0), 0, ind) key(key_to_int(?z), 4, ind) snd_test_neq(framples(ind), len, "C-z len") data = channel2vct(1200, 100, ind) snd_test_neq(vct_peak(data), 0.0, "C-z") set_cursor(0, ind) key(key_to_int(?u), 4, ind) key(key_to_int(?3), 0, ind) key(key_to_int(?.), 0, ind) key(key_to_int(?0), 0, ind) key(key_to_int(?z), 4, ind) if fneq(maxamp(ind, 0), 0.0) snd_display("C-z full: %s?", maxamp) end revert_sound(ind) set_cursor(1200, ind) key(key_to_int(?u), 4, ind) key(key_to_int(?1), 0, ind) key(key_to_int(?.), 0, ind) key(key_to_int(?0), 0, ind) key(key_to_int(?o), 4, ind) snd_test_neq(framples(ind), len + srate(ind), "C-o 1.0 len") data = channel2vct(1200, 100, ind) snd_test_neq(vct_peak(data), 0.0, "C-o 1.0") revert_sound(ind) set_cursor(1200, ind) key(key_to_int(?u), 4, ind) key(key_to_int(?1), 0, ind) key(key_to_int(?.), 0, ind) key(key_to_int(?0), 0, ind) key(key_to_int(?z), 4, ind) snd_test_neq(framples(ind), len, "C-z 1.0 len") data = channel2vct(1200, srate(ind), ind) snd_test_neq(vct_peak(data), 0.0, "C-z 1.0") close_sound(ind) # ind = open_sound("2.snd") set_sync(1, ind) key(key_to_int(?>), 4) key(key_to_int(?\s), 4) key(key_to_int(?<), 4) if (not (res1 = selection_member?(ind, 0))) or (not (res2 = selection_member?(ind, 1))) or (res3 = selection_position(ind, 0)) != 0 or (res4 = selection_position(ind, 1)) != 0 or (res5 = selection_framples(ind, 0)) != framples(ind, 0) or (res6 = selection_framples(ind, 1)) != framples(ind, 1) snd_display("sync selection via <-: %s %s %s %s %s %s?", res1, res2, res3, res4, res5, res6) end key(key_to_int(?\s), 4) key(key_to_int(?>), 4) if (not (res1 = selection_member?(ind, 0))) or (not (res2 = selection_member?(ind, 1))) or (res3 = selection_position(ind, 0)) != 0 or (res4 = selection_position(ind, 1)) != 0 or (res5 = selection_framples(ind, 0)) != framples(ind, 0) or (res6 = selection_framples(ind, 1)) != framples(ind, 1) snd_display("sync selection via ->: %s %s %s %s %s %s?", res1, res2, res3, res4, res5, res6) end set_cursor(0, ind, 1) set_cursor(1000, ind, 0) if (res = cursor(ind, 1)) != 1000 snd_display("syncd cursors: %s %s?", cursor(ind, 0), res) end close_sound(ind) # ind = open_sound("oboe.snd") test_selection(ind, 1200, 100, 2.0) test_selection(ind, 600, 1200, 2.0) test_selection(ind, 0, 100, 2.0) test_selection(ind, 22500, 50827 - 22500, 0.5) test_selection(ind, 0, 50828, 0.5) # test_selection_to(ind, 1200, 100, 1.0) test_selection_to(ind, 600, 1200, 0.1) test_selection_to(ind, 0, 100, 0.5) test_selection_to(ind, 22500, 50827 - 22500, 2.0) test_selection_to(ind, 0, 50828, 0.5) # revert_sound(ind) make_selection(1200, 1200) unless selection? snd_display("no selection from 1 samp region?") end if (res = selection_framples) != 1 snd_display("1 samp selection: %s samps?", res) end scale_selection_to(1.0) if fneq(res = sample(1200, ind, 0).abs, 1.0) snd_display("scale 1 samp selection: %s?", res) end revert_sound(ind) id = make_region(500, 1000) src_selection(0.5) if ((res = region_framples(id)) - 500).abs > 1 snd_display("region_framples after src_selection: %s?", res) end reg_mix_id = mix_region(id, 1500, ind, 0).car if (res1 = mix_length(reg_mix_id)) != (res2 = region_framples(id)) snd_display("mix_region: %s != %s?", res1, res2) end if (res = mix_home(reg_mix_id)) != [ind, 0, false, 0] snd_display("mix_region mix_home %s [%s, 0, false, 0]?", res, ind) end sel_mix_id = mix_selection(2500, ind, 0).car if (res1 = mix_length(sel_mix_id)) != (res2 = selection_framples) snd_display("mix_selection framples: %s != %s?", res1, res2) end if ((res1 = mix_length(reg_mix_id)) * 2 - (res2 = mix_length(sel_mix_id))).abs > 3 snd_display("mix selection and region: %s %s %s %s?", res1, res2, region_framples(id), selection_framples) end if (res = mix_home(reg_mix_id)) != [ind, 0, false, 0] snd_display("mix_selection mix_home %s [%s, 0, false, 0]?", res, ind) end insert_selection(3000, ind, 0) insert_selection(3000, ind) mix_selection(3000, ind) delete_selection revert_sound(ind) close_sound(ind) # if File.exist?("storm.snd") ind = open_sound("storm.snd") set_sinc_width(10) with_time("src_sound(1.3)") do src_sound(1.3) end with_time("env_sound([0, 0, 1, 1, 2, 0])") do env_sound([0, 0, 1, 1, 2, 0]) end with_time("filter_sound, FIR direct form") do filter_sound([0, 1, 0.2, 0, 0.5, 1, 1, 0], 20) end with_time("filter_sound, convolution") do filter_sound([0, 0, 0.1, 0, 0.11, 1, 0.12, 0, 1, 0], 2048) end revert_sound(ind) reg = make_region(0, 123000, ind, 0) region2vct(reg, 0, 10, 0, Vct.new(10)) ramp_channel(0.0, 1.0) ramp_channel(0.0, 1.0) ramp_channel(0.0, 1.0) ramp_channel(0.0, 1.0) close_sound(ind) end if File.exist?("1a.snd") and $all_args ind = open_sound("1a.snd") with_time("rubber_sound(1.25)") do rubber_sound(1.25) end close_sound(ind) end oboe = open_sound("oboe.snd") a4 = open_sound("4.aiff") sr = srate(oboe) save_sound_as("test.aif", oboe, :header_type, Mus_aifc) oboe_aif = open_sound("test.aif") if (res = header_type(oboe_aif)) != Mus_aifc snd_display("oboe_aif header: %s?", mus_header_type_name(res)) end set_srate(oboe_aif, sr * 2) if fneq(res = srate(oboe_aif), sr * 2) snd_display("set_srate: %s %s?", sr * 2, res) end set_header_type(oboe_aif, Mus_next) if (res = header_type(oboe_aif)) != Mus_next snd_display("set_header: %s?", mus_header_type_name(res)) end set_data_location(oboe_aif, 28) if (res = data_location(oboe_aif)) != 28 snd_display("set_data_location: %s?", res) end set_sample_type(oboe_aif, Mus_mulaw) if (res = sample_type(oboe_aif)) != Mus_mulaw snd_display("set_sample_type: %s?", mus_sample_type_name(res)) end save_sound_as("test.aif", oboe_aif, 22050, Mus_bshort, Mus_aifc, 0) close_sound(oboe_aif) delete_file("test.aif") set_selected_sound(a4) if selected_sound != a4 snd_display("set_selected_sound: %s %s?", selected_sound, a4) end set_selected_channel(a4, 2) if selected_channel != 2 snd_display("set_selected_channel a4: %s?", selected_channel(a4)) end set_selected_channel(a4, 3) if selected_channel(a4) != 3 snd_display("set_selected_channel a4: %s?", selected_channel(a4)) end close_sound(a4) close_sound(oboe) end def test_15_04 if fneq(res = envelope_interp(0.1, [0, 0, 1, 1]), 0.1) snd_display("envelope_interp 0.1: %s?", res) end if fneq(res = envelope_interp(0.1, [0, 0, 1, 1], 32.0), 0.01336172) snd_display("envelope_interp 0.013: %s?", res) end if fneq(res = envelope_interp(0.1, [0, 0, 1, 1], 0.012), 0.36177473) snd_display("envelope_interp 0.361: %s?", res) end if fneq(res = envelope_interp(0.3, [0, 0, 0.5, 1, 1, 0]), 0.6) snd_display("envelope_interp 0.3 [0, 0, 0.5, 1, 1, 0]: %s?", res) end unless vequal(res = window_envelope(1.0, 3.0, [0, 0, 5, 1]), [1, 0.2, 3, 0.6]) snd_display("window_envelope: %s?", res) end unless vequal(res = multiply_envelopes([0, 0, 1, 1], [0, 0, 1, 1, 2, 0]), [0, 0, 0.5, 0.5, 1, 0]) snd_display("multiply_envelopes: %s?", res) end if fneq(res = max_envelope([0, 0, 1, 1, 2, 3, 4, 0]), 3.0) snd_display("0 max_envelope: %s?", res) end if fneq(res = max_envelope([0, 1]), 1.0) snd_display("1 max_envelope: %s?", res) end if fneq(res = max_envelope([0, 1, 1, 1, 2, 2]), 2.0) snd_display("2 max_envelope: %s?", res) end if fneq(res = max_envelope([0, -1, 1, -2]), -1.0) snd_display("3 max_envelope: %s?", res) end if fneq(res = max_envelope([0, -2, 1, -1]), -1.0) snd_display("4 max_envelope: %s?", res) end if fneq(res = min_envelope([0, 0, 1, 1, 2, 3, 4, 0]), 0.0) snd_display("0 min_envelope: %s?", res) end if fneq(res = min_envelope([0, 1]), 1.0) snd_display("1 min_envelope: %s?", res) end if fneq(res = min_envelope([0, 1, 1, 1, 2, 2]), 1.0) snd_display("2 min_envelope: %s?", res) end if fneq(res = min_envelope([0, -1, 1, -2]), -2.0) snd_display("3 min_envelope: %s?", res) end if fneq(res = min_envelope([0, -2, 1, -1]), -2.0) snd_display("4 min_envelope: %s?", res) end if fneq(res = integrate_envelope([0, 0, 1, 1]), 0.5) snd_display("0 integrate_envelope: %s?", res) end if fneq(res = integrate_envelope([0, 1, 1, 1]), 1.0) snd_display("1 integrate_envelope: %s?", res) end if fneq(res = integrate_envelope([0, 0, 1, 1, 2, 0.5]), 1.25) snd_display("2 integrate_envelope: %s?", res) end unless vequal(res = stretch_envelope([0, 0, 1, 1], 0.1, 0.2), [0, 0, 0.2, 0.1, 1, 1]) snd_display("stretch_envelope att: %s?", res) end unless vequal(res = stretch_envelope([0, 0, 1, 1, 2, 0], 0.1, 0.2, 1.5, 1.6), [0, 0, 0.2, 0.1, 1.1, 1, 1.6, 0.5, 2, 0]) snd_display("stretch_envelope dec: %s?", res) end unless vequal(res = add_envelopes([0, 0, 1, 1, 2, 0], [0, 0, 1, 1]), [0, 0, 0.5, 1.5, 1, 1]) snd_display("add_envelopes: %s?", res) end unless vequal(res = scale_envelope([0, 0, 1, 1], 2.0), [0, 0, 1, 2]) snd_display("scale_envelope: %s?", res) end unless vequal(res = scale_envelope([0, 0, 1, 1], 2.0, 1.0), [0, 1, 1, 3]) snd_display("scale_envelope offset: %s?", res) end unless vequal(res = reverse_envelope([0, 0, 1, 1]), [0, 1, 1, 0]) snd_display("0 reverse_envelope ramp: %s?", res) end unless vequal(res = reverse_envelope([0, 0, 0.5, 1, 2, 0]), [0, 0, 1.5, 1, 2, 0]) snd_display("1 reverse_envelope ramp 2: %s?", res) end unless vequal(res = reverse_envelope([0, 0, 0.5, 1, 2, 1]), [0, 1, 1.5, 1, 2, 0]) snd_display("2 reverse_envelope ramp 2: %s?", res) end unless vequal(res = concatenate_envelopes([0, 0, 1, 1], [0, 1, 1, 0]), [0, 0, 1, 1, 2, 0]) snd_display("0 concatenate_envelopes: %s?", res) end unless vequal(res = concatenate_envelopes([0, 0, 1, 1.5], [0, 1, 1, 0]), [0, 0, 1, 1.5, 1.01, 1, 2.01, 0]) snd_display("1 concatenate_envelopes: %s?", res) end unless vequal(res = repeat_envelope([0, 0, 1, 100], 2), [0, 0, 1, 100, 1.01, 0, 2.01, 100]) snd_display("0 repeat_envelope: %s?", res) end unless vequal(res = repeat_envelope([0, 0, 1.5, 1, 2, 0], 2), [0, 0, 1.5, 1, 2, 0, 3.5, 1, 4, 0]) snd_display("1 repeat_envelope: %s?", res) end unless vequal(res = repeat_envelope([0, 0, 1.5, 1, 2, 0], 2, false, true), [0, 0, 0.75, 1, 1, 0, 1.75, 1, 2, 0]) snd_display("2 repeat_envelope: %s?", res) end unless vequal(res = repeat_envelope([0, 0, 1.5, 1, 2, 0], 2, true), [0, 0, 1.5, 1, 2, 0, 2.5, 1, 4, 0]) snd_display("3 repeat_envelope: %s?", res) end unless vequal(res = repeat_envelope([0, 0, 1.5, 1, 2, 0], 3), [0, 0, 1.5, 1, 2, 0, 3.5, 1, 4, 0, 5.5, 1, 6, 0]) snd_display("4 repeat_envelope: %s?", res) end unless vequal(res = normalize_envelope([0, 0, 1, 1.5, 2, 1.0]), [0, 0.0, 1, 1.0, 2, 0.667]) snd_display("0 normalize_envelope: %s?", res) end unless vequal(res = normalize_envelope([0, 0, 1, 0.5, 2, -0.8]), [0, 0.0, 1, 0.625, 2, -1.0]) snd_display("1 normalize_envelope: %s?", res) end unless vequal(res = envelope_exp([0, 0, 1, 1], 2.0, 10), [0.000, 0.000, 0.100, 0.010, 0.200, 0.040, 0.300, 0.090, 0.400, 0.160, 0.500, 0.250, 0.600, 0.360, 0.700, 0.490, 0.800, 0.640, 0.900, 0.810, 1.000, 1.000]) snd_display("0 envelope_exp: %s?", res) end unless vequal(res = envelope_exp([0, 0, 1, 1, 2, 0], 1.0, 10), [0.000, 0.000, 0.200, 0.200, 0.400, 0.400, 0.600, 0.600, 0.800, 0.800, 1.000, 1.000, 1.200, 0.800, 1.400, 0.600, 1.600, 0.400, 1.800, 0.200, 2.000, 0.000]) snd_display("1 envelope_exp: %s?", res) end # ind = new_sound("fmv.snd") vct2channel(Vct.new(20, 1.0)) if selection? set_selection_member?(false, true) end make_selection(5, 9, ind, 0) scale_selection_to(0.5) insert_selection(15, ind) if (res = framples(ind)) != 25 snd_display("insert_selection 5: %s?", res) end unless vequal(res = channel2vct(0, 25), vct(1.0, 1.0, 1.0, 1.0, 1.0, 0.5, 0.5, 0.5, 0.5, 0.5, 1.0, 1.0, 1.0, 1.0, 1.0, 0.5, 0.5, 0.5, 0.5, 0.5, 1.0, 1.0, 1.0, 1.0, 1.0)) snd_display("insert_selection: %s?", res) end mix_selection(1, ind, 0) unless vequal(res = channel2vct(0, 10, ind, 0), vct(1.0, 1.5, 1.5, 1.5, 1.5, 1.0, 0.5, 0.5, 0.5, 0.5)) snd_display("mix_selection vals: %s?", res) end close_sound(ind) # ind = new_sound("fmv.snd") old_size = transform_size.zero? ? 128 : transform_size old_type = transform_type old_norm = transform_normalization old_grf = transform_graph_type e = make_env([0, 0, 1, 2000 * 0.2 * PI], :length, 2001) v = Vct.new(2000) do |i| sin(env(e)) end vct2channel(v, 0, 2000, ind, 0) set_transform_size(256, ind) set_transform_type($fourier_transform) set_transform_normalization(Normalize_by_channel) set_transform_graph_style(Graph_once) set_zero_pad(0) set_transform_graph?(true) make_selection(0, 200) set_show_selection_transform(true) set_selection_framples(300) update_transform_graph if vct?(data = transform2vct) pk = data.peak if pk.zero? snd_display("transform selection peak: %s?", pk) end if fneq(res = transform_sample(0), data[0]) snd_display("transform_sample: %s, data: %s?", res, data[0]) end else snd_display("transform2vct -> %s?", data) end set_zero_pad(100000) if zero_pad > 1000 snd_display("zero_pad: %s?", zero_pad) end set_zero_pad(0) set_transform_size(old_size) set_transform_type(old_type) set_transform_normalization(old_norm) set_transform_graph_style(old_grf) close_sound(ind) end def test_15 set_transform_type($fourier_transform) test_15_00 if $with_test_gui test_15_01 test_15_02 # set_transform_size(0) in test_history_channel test_15_03 test_15_04 end end # ---------------- test 16: regularized funcs ---------------- def undo_env(snd, chn) if (len = (edits(snd, chn) or []).first) > 0 1.upto(len) do |i| if (ed = edit_fragment(i, snd, chn)) and ed[1] == "env" set_edit_position(i - 1, snd, chn) return true end end false else false end end def opt_test(choice) cursnd = Snd.sounds.pick curchn = random(channels(cursnd)) cur_maxamps = [] cur_edits = [] cur_framples = [] all_chans_zipped.each do |s, c| cur_maxamps << maxamp(s, c) cur_edits << edit_position(s, c) cur_framples << framples(s, c) end cur_amp = maxamp(cursnd, curchn) cur_edit = edit_position(cursnd, curchn) cur_frame = framples(cursnd, curchn) snd_lst, chn_lst = all_chans case choice when 0 # scale_channel scaler = (cur_amp < 1.0) ? (random(1.0) + 1.0) : (random(0.5) + 0.5) cur_loc = random(cur_frame) cur_samp = sample(cur_loc, cursnd, curchn) scale_channel(scaler, 0, cur_frame, cursnd, curchn) if (res = edit_position(cursnd, curchn)) != cur_edit + 1 and res != cur_edit snd_display("scale_channel %s[%s] edit pos: %s %s?", short_file_name(cursnd), curchn, res, cur_edit) end if (res = framples(cursnd, curchn)) != cur_frame snd_display("scale_channel %s[%s] framples: %s %s?", short_file_name(cursnd), curchn, res, cur_frame) end if fneq(res1 = maxamp(cursnd, curchn), res2 = scaler * cur_amp) snd_display("scale_channel %s[%s] maxamp: %s %s (%s, scaler: %s)?", short_file_name(cursnd), curchn, res1, res2, (res1 - res2).abs, scaler) end if fneq(res1 = sample(cur_loc, cursnd, curchn), res2 = scaler * cur_samp) snd_display("scale_channel %s[%s] cur_samp: %s %s?", short_file_name(cursnd), curchn, res1, res2) end snd_lst.zip(chn_lst, cur_maxamps, cur_edits, cur_framples) do |s, c, amp, ed, fr| if (not s == cursnd and c == curchn) if (res = edit_position(s, c)) != ed snd_display("scale_channel %s[%s] wrong edit pos: %s %s?", short_file_name(s), c, res, ed) end if (res = framples(s, c)) != fr snd_display("scale_channel %s[%s] wrong framples: %s %s?", short_file_name(s), c, res, fr) end if fneq(res = maxamp(s, c), amp) snd_display("scale_channel %s[%s] wrong maxamp: %s %s?", short_file_name(s), c, res, amp) end end end when 1 # scale_by maxscl = cur_maxamps.max scaler = (maxscl < 1.0) ? (random(1.0) + 1.0) : (random(0.5) + 0.5) scale_by(scaler, cursnd, curchn) snd_lst.zip(chn_lst, cur_maxamps, cur_edits, cur_framples) do |s, c, amp, ed, fr| if (sync(cursnd) == 0 and (s != cursnd or c != curchn)) or (sync(s) != sync(cursnd)) if (res = edit_position(s, c)) != ed snd_display("scale_by %s[%s] wrong edit pos: %s %s?", short_file_name(s), c, res, ed) end if (res = framples(s, c)) != fr snd_display("scale_by %s[%s] wrong framples: %s %s?", short_file_name(s), c, res, fr) end if fneq(res = maxamp(s, c), amp) snd_display("scale_by %s[%s] wrong maxamp: %s %s?", short_file_name(s), c, res, amp) end else if (res = edit_position(s, c)) != ed + 1 and res != ed snd_display("scale_by %s[%s] wrong edit pos: %s %s?", short_file_name(s), c, res, ed + 1) end if (res = framples(s, c)) != fr snd_display("scale_by %s[%s] wrong framples: %s %s?", short_file_name(s), c, res, fr) end if fneq(res1 = maxamp(s, c), res2 = amp * scaler) snd_display("scale_by %s[%s] wrong maxamp: %s %s?", short_file_name(s), c, res1, res2) end end end when 2 # env_channel pts = random(6) + 1 maxpt = 0.0 x = y = 0.0 e = make_array(pts) 0.step(pts - 1, 2) do |i| e[i] = x if random(3) > 0 y = mus_random(1.0) end e[i + 1] = y if y.abs > maxpt maxpt = y.abs end x += 0.01 + random(1.0) end if undo_env(cursnd, curchn) cur_maxamps = [] cur_edits = [] cur_framples = [] all_chans_zipped.each do |s, c| cur_maxamps << maxamp(s, c) cur_edits << edit_position(s, c) cur_framples << framples(s, c) cur_amp = maxamp(cursnd, curchn) cur_edit = edit_position(cursnd, curchn) cur_frame = framples(cursnd, curchn) end end env_channel(e, 0, cur_frame, cursnd, curchn) if (res = edit_position(cursnd, curchn)) != cur_edit + 1 and res != cur_edit snd_display("env_channel %s[%s] edit pos: %s %s?", short_file_name(cursnd), curchn, res, cur_edit + 1) end if (res = framples(cursnd, curchn)) != cur_frame snd_display("env_channel %s[%s] framples: %s %s?", short_file_name(cursnd), curchn, res, cur_frame) end if (res1 = maxamp(cursnd, curchn)) - 0.01 > (res2 = maxpt * cur_amp) snd_display("env_channel %s[%s] maxamp: %s %s from %s?", short_file_name(cursnd), curchn, res1, res2, e) Snd.throw(:mus_error, "env_channel maxamp", short_file_name(cursnd)) end snd_lst.zip(chn_lst, cur_maxamps, cur_edits, cur_framples) do |s, c, amp, ed, fr| unless s == cursnd and c == curchn if (res = edit_position(s, c)) != ed snd_display("env_channel %s[%s] wrong edit pos: %s %s?", short_file_name(s), c, res, ed) end if (res = framples(s, c)) != fr snd_display("env_channel %s[%s] wrong framples: %s %s?", short_file_name(s), c, res, fr) end if fneq(res = maxamp(s, c), amp) snd_display("env_channel %s[%s] wrong maxamp: %s %s?", short_file_name(s), c, res, amp) end end end when 3 # env_sound pts = random(6) + 1 maxpt = 0.0 x = y = 0.0 e = make_array(pts) 0.step(pts - 1, 2) do |i| e[i] = x if random(3) > 0 y = mus_random(1.0) end e[i + 1] = y if y.abs > maxpt maxpt = y.abs end x += 0.01 + random(1.0) end recalc = false minfr = cur_framples.min beg = random((minfr / 2.0).floor) all_chans_zipped.each do |s, c| unless (sync(cursnd) == 0 and (s != cursnd or c != curchn)) or sync(s) != sync(cursnd) recalc = (recalc or undo_env(s, c)) end end if recalc cur_maxamps = [] cur_edits = [] cur_framples = [] all_chans_zipped.each do |s, c| cur_maxamps << maxamp(s, c) cur_edits << edit_position(s, c) cur_framples << framples(s, c) end cur_amp = maxamp(cursnd, curchn) cur_edit = edit_position(cursnd, curchn) cur_frame = framples(cursnd, curchn) end env_sound(e, beg, [pts, minfr - beg].max, 1.0, cursnd, curchn) snd_lst.zip(chn_lst, cur_maxamps, cur_edits, cur_framples) do |s, c, amp, ed, fr| if (sync(cursnd) == 0 and (s != cursnd or c != curchn)) or sync(s) != sync(cursnd) if (res = edit_position(s, c)) != ed snd_display("env_sound %s[%s] wrong edit pos: %s %s?", short_file_name(s), c, res, ed) end if (res = framples(s, c)) != fr snd_display("env_sound %s[%s] wrong framples: %s %s?", short_file_name(s), c, res, fr) end if fneq(res = maxamp(s, c), amp) snd_display("env_sound %s[%s] wrong maxamp: %s %s?", short_file_name(s), c, res, amp) end else if (res = edit_position(s, c)) != ed + 1 and res != ed snd_display("env_sound %s[%s] edit pos: %s %s?", short_file_name(s), c, res, ed + 1) end if (res = framples(s, c)) != fr snd_display("env_sound %s[%s] framples: fr %s orig_fr %s?", short_file_name(s), c, res, fr) end end end when 4 # scale_sound_by maxscl = cur_maxamps.max scaler = (maxscl < 1.0) ? (random(1.0) + 1.0) : (random(0.5) + 0.5) scale_sound_by(scaler, 1000, 1000, cursnd) snd_lst.zip(chn_lst, cur_maxamps, cur_edits, cur_framples) do |s, c, amp, ed, fr| if s != cursnd if (res = edit_position(s, c)) != ed snd_display("scale_sound_by %s[%s] wrong edit pos: %s %s?", short_file_name(s), c, res, ed) end if (res = framples(s, c)) != fr snd_display("scale_sound_by %s[%s] wrong framples: %s %s?", short_file_name(s), c, res, fr) end if fneq(res = maxamp(s, c), amp) snd_display("scale_sound_by %s[%s] wrong maxamp: %s %s?", short_file_name(s), c, res, amp) end else if (res = edit_position(s, c)) != ed + 1 and res != ed snd_display("scale_sound_by %s[%s] wrong edit pos: %s %s?", short_file_name(s), c, res, ed + 1) end if (res = framples(s, c)) != fr snd_display("scale_sound_by %s[%s] wrong framples: %s %s?", short_file_name(s), c, res, fr) end end end when 5 if (pos = edit_position(cursnd, curchn)) > 0 undo_edit(random(pos), cursnd, curchn) end when 6 if (len = framples(cursnd, curchn)) > 10000 delete_samples(random((len / 2).floor), random(100) + 10, cursnd, curchn) end when 7 set_samples(random(framples(cursnd, curchn) + 100), random(100) + 10, Vct.new(10, 1.0), cursnd, curchn) when 8 insert_samples(random(framples(cursnd, curchn) + 100), random(100) + 10, Vct.new(10, 1.0), cursnd, curchn) when 9 add_mark(random(framples(cursnd, curchn)), cursnd, curchn) when 10 mix_vct(Vct.new(random(100) + 10, random(1.0)), random(framples(cursnd, curchn) + 100), cursnd, curchn) when 11 pad_channel(random(framples(cursnd, curchn) + 100), random(100) + 10, cursnd, curchn) when 12 pts = random(8) + 1 maxpt = 0.0 x = y = 0.0 e = make_array(pts) 0.step(pts - 1, 2) do |i| e[i] = x if random(3) > 0 y = mus_random(1.0) end e[i + 1] = y if y.abs > maxpt maxpt = y.abs end x += 0.01 + random(1.0) end beg = random(framples(cursnd, curchn) - 300) dur = random(200) + 80 reader0 = make_sampler(beg, cursnd, curchn) env_channel(e, beg, dur, cursnd, curchn) reader1 = make_sampler(beg, cursnd, curchn) en = make_env(:envelope, e, :length, dur) dur.times do |i| e0 = env(en) val00 = reader0.call val0 = e0 * val00 val1 = reader1.call if (val0 - val1).abs > 0.005 delete_file("baddy.rb") save_state("baddy.rb") snd_display("read env off by %s:\n# (%s) at %s: %s %s (%s %s) [%s %s]\n# %s", (val0 - val1).abs, e, i, val0, val1, reader0, reader1, e0, val00, safe_display_edits(cursnd, curchn)) Snd_throw(:mus_error, "read env off at", i) end end when 13 scale_channel(0.5, random(framples(cursnd, curchn) - 100), random(100) + 10, cursnd, curchn) when 14 beg = random(framples(cursnd, curchn) - 200) scale_channel(0.5, beg, random(100) + 10, cursnd, curchn) scale_channel(0.5, beg + 10, random(100) + 10, cursnd, curchn) when 15 beg = random(framples(cursnd, curchn) - 200) scale_channel(0.5, beg, random(100) + 10, cursnd, curchn) scale_channel(2.0, beg, random(100) + 10, cursnd, curchn) when 16 beg = random(framples(cursnd, curchn) - 200) pad_channel(beg, random(100) + 10, cursnd, curchn) pad_channel(beg + 10, random(100) + 10, cursnd, curchn) when 17 beg = random(framples(cursnd, curchn) - 200) pad_channel(beg, random(100) + 10, cursnd, curchn) pad_channel(beg, random(100) + 10, cursnd, curchn) when 18 beg = random(framples(cursnd, curchn) - 200) delete_sample(beg, cursnd, curchn) delete_sample(beg + random(100), cursnd, curchn) when 19 beg = random(framples(cursnd, curchn) + 200) set_sample(beg, 0.1, cursnd, curchn) set_sample(beg + random(100), 0.2, cursnd, curchn) when 20 beg = random(framples(cursnd, curchn) - 200) ramp_channel(random(2.0) - 1.0, random(2.0) - 1.0, beg, random(100) + 10, cursnd, curchn) end end def amp_envs_equal?(snd, chn, pos0, pos1, df) env0 = channel_amp_envs(snd, chn, pos0) env1 = channel_amp_envs(snd, chn, pos1) len0 = (env0 and list_p(env0) and env0.length == 2 and env0[1].length) len1 = (env1 and list_p(env1) and env1.length == 2 and env1[1].length) if len0 and len1 minlen = [len0, len1].min inc0 = len0 / minlen inc1 = len1 / minlen e0 = env0[1] e1 = env1[1] if integer?(inc0) and integer?(inc1) minlen.times do |i| max0 = -1.0 max1 = -1.0 if inc0 == 1 max0 = e0[i] else inc0.times do |j| nmx = e0[j + inc0 * i] if nmx > max0 max0 = nmx end end end if inc1 == 1 max1 = e1[i] else inc1.times do |j| nmx = e1[j + inc1 * i] if nmx > max1 max1 = nmx end end end if (max0 - max1).abs > df snd_display_prev_caller(snd_format_neq(max0, max1, "amp_env[%d of %d], df %1.4f", i, minlen, df)) end end else snd_display_prev_caller("lens: %s %s?", len0, len1) end end true end def vequal_at(v0, v1) v0.each_with_index do |val, i| if fneq_err(val, v1[i], 0.001) return [i, val, v1[i]] end end false end def edits_not_equal?(tl0, tl1) tl0.each_with_index do |t0, i| t1 = tl1[i] if t0[0] != t1[0] or t0[1] != t1[1] or t0[2] != t1[2] or t0[3] != t1[3] or fneq(t0[4], t1[4]) or fneq(t0[5], t1[5]) or fneq(t0[6], t1[6]) return [i, t0, t1] end end false end def check_edit_tree(expected_tree, expected_vals, name) current_vals = channel2vct len = current_vals.length if expected_vals and len != expected_vals.length snd_display_prev_caller("%s: lengths differ: %s %s?", name, len, expected_vals.length) else if expected_vals and (not vequal(current_vals, expected_vals)) snd_display_prev_caller("checking %s, vals disagree (loc, dur, expect):\n# %s?", name, vequal_at(current_vals, expected_vals)) else tree = edit_tree if bad_data = edits_not_equal?(tree, expected_tree) snd_display_prev_caller("checking %s, trees disagree (loc, cur, expect):\n# %s\n# in %s?", name, bad_data, tree) end if len > 5 split_loc = 2 + random(len - 3) fread = make_sampler(split_loc) bread = make_sampler(split_loc - 1, false, false, -1) split_vals = Vct.new(len) split_loc.upto(len - 1) do |i| split_vals[i] = fread.call end (split_loc - 1).downto(0) do |i| split_vals[i] = bread.call end if expected_vals and (not vequal(split_vals, expected_vals)) snd_display_prev_caller("checking %s, split vals disagree (loc, cur, expect):\n# %s?", name, vequal_at(split_vals, expected_vals)) end end end end end def reversed_read(snd, chn) len = framples(snd, chn) sf = make_sampler(len - 1, snd, chn, -1) Vct.new(len) do read_sample(sf) end.reverse end def init_sound(val, dur, chns) ind = new_sound("test.snd", chns, 22050, Mus_bshort, Mus_next) chns.times do |chn| insert_silence(0, dur, ind, chn) map_channel(lambda do |y| val end, 0, framples, ind, chn) end ind end def check_back_and_forth(ind, name, v) happy = true unless vequal(res = channel2vct(0, framples, ind, 0), v) happy = false snd_display_prev_caller("%s forth: %s %s?", name, res, v) end unless vequal(res = reversed_read(ind, 0), v) happy = false snd_display_prev_caller("%s back: %s %s?", name, res, v) end happy end def check_both_chans(ind, name, f0, f1) if (c0 = scan_channel(f0, 0, framples, ind, 0)) snd_display_prev_caller("%s swap c0: %s?", name, c0) end if (c1 = scan_channel(f1, 0, framples, ind, 1)) snd_display_prev_caller("%s swap c1: %s?", name, c1) end end def test_16_00 oboe = open_sound("oboe.snd") [[lambda do scale_channel(2.0, 0, 0, oboe) end, :scale_channel], [lambda do env_channel(make_env([0, 0, 1, 1], :length, 123), 0, 0, oboe) end, :env_channel], [lambda do clm_channel(make_oscil, 0, 0, oboe) end, :clm_channel], [lambda do vct2channel(make_vct(3), 0, 0, oboe) end, :vct2channel], [lambda do smooth_channel(0, 0, oboe) end, :smooth_channel], [lambda do pad_channel(0, 0, oboe) end, :pad_channel], [lambda do src_channel(2.0, 0, 0, oboe) end, :src_channel], [lambda do mix_channel("pistol.snd", 0, 0, oboe) end, :mix_channel], [lambda do insert_channel("pistol.snd", 0, 0, oboe) end, :insert_channel], [lambda do reverse_channel(0, 0, oboe) end, :reverse_channel], [lambda do scale_sound_by(2.0, 0, 0, oboe) end, :scale_sound_by], [lambda do env_sound([0, 0, 1, 1], 0, 0, oboe) end, :env_sound], [lambda do set_samples(0, 0, Vct.new(3), oboe) end, :set_samples], [lambda do smooth_sound(0, 0, oboe) end, :smooth_soundxs], [lambda do insert_silence(0, 0, oboe) end, :insert_silence]].each do |func, name| func.call if (res = edit_position(oboe)) != 0 snd_display("dur: 0 %s: %s %s?", name, res, edit_fragment) end end [[lambda do scale_channel(2.0, -1, 123, oboe) end, :scale_channel], [lambda do env_channel(make_env([0, 0, 1, 1], :length, 123), -1, 123, oboe) end, :env_channel], [lambda do clm_channel(make_oscil, -1, 123, oboe) end, :clm_channel], [lambda do vct2channel(make_vct(3), -1, 123, oboe) end, :vct2channel], [lambda do smooth_channel(-1, 123, oboe) end, :smooth_channel], [lambda do pad_channel(-1, 123, oboe) end, :pad_channel], [lambda do src_channel(2.0, -1, 123, oboe) end, :src_channel], [lambda do mix_channel("pistol.snd", -1, 123, oboe) end, :mix_channel], [lambda do insert_channel("pistol.snd", -1, 123, oboe) end, :insert_channel], [lambda do reverse_channel(-1, 123, oboe) end, :reverse_channel], [lambda do scale_sound_by(2.0, -1, 123, oboe) end, :scale_sound_by], [lambda do env_sound([0, 0, 1, 1], -1, 123, oboe) end, :env_sound], [lambda do set_samples(-1, 123, Vct.new(3), oboe) end, :set_samples], [lambda do smooth_sound(-1, 123, oboe) end, :smooth_soundxs], [lambda do insert_silence(-1, 123, oboe) end, :insert_silence]].each do |func, name| if (res = Snd.catch do func.call end).first != :no_such_sample snd_display("%s beg -1 -> %s", name, res.inspect) end if (res = edit_position(oboe)) != 0 snd_display("beg: -1 %s: %s %s?", name, res, edit_fragment) end end [[lambda do scale_channel(2.0, 12345678, 123, oboe) end, :scale_channel], [lambda do env_channel(make_env([0, 0, 1, 1], :length, 123), 12345678, 123, oboe) end, :env_channel], [lambda do smooth_channel(12345678, 123, oboe) end, :smooth_channel], [lambda do src_channel(2.0, 12345678, 123, oboe) end, :src_channel], [lambda do reverse_channel(12345678, 123, oboe) end, :reverse_channel]].each do |func, name| func.call if (res = edit_position(oboe)) != 0 snd_display("beg: 12345678 %s: %s %s?", name, res, edit_fragment) end end pos = 0 [[lambda do scale_channel(2.0, 0, 123, oboe, 0) end, :scale_channel], [lambda do env_channel(make_env([0, 0, 1, 1], :length, 123), 0, 123, oboe, 0) end, :env_channel], [lambda do clm_channel(make_oscil, 0, 123, oboe, 0) end, :clm_channel], [lambda do vct2channel(make_vct(3), 0, 123, oboe, 0) end, :vct2channel], [lambda do smooth_channel(0, 123, oboe, 0) end, :smooth_channel], [lambda do pad_channel(0, 123, oboe, 0) end, :pad_channel], [lambda do src_channel(2.0, 0, 123, oboe, 0) end, :src_channel], [lambda do mix_channel("pistol.snd", 0, 123, oboe, 0) end, :mix_channel], [lambda do insert_channel("pistol.snd", 0, 123, oboe, 0) end, :insert_channel], [lambda do reverse_channel(0, 123, oboe, 0) end, :reverse_channel], [let(rd = make_sampler(0), make_src(:srate, 2.0, :input, lambda do |dir| rd.call end)) do |rd, sr| lambda do clm_channel(sr, 0, 12345, oboe, 0) end end, "clm_channel src"], [let(rd = make_sampler(0), make_granulate(:expansion, 2.0, :input, lambda do |dir| rd.call end)) do |rd, gr| lambda do clm_channel(gr, 0, 12345, oboe, 0) end end, "clm_channel granulate"], [let(rd = make_sampler(0), make_convolve(:input, lambda do |dir| rd.call end, :filter, vct(1, 0, 0))) do |rd, cv| lambda do clm_channel(cv, 0, 12345, oboe, 0) end end, "clm_channel convolve"], [let(rd = make_sampler(0), make_phase_vocoder(:input, lambda do |dir| rd.call end)) do |rd, pv| lambda do clm_channel(pv, 0, 12345, oboe, 0) end end, "clm_channel phase_vocoder"]].each do |func, name| func.call if (res = edit_position(oboe)) != pos += 1 snd_display("%s[%s]: %s %s?", name, pos, res, edit_fragment) end end # revert_sound(oboe) [[lambda do scale_channel(2.0, 0, 123, oboe, 0, 123) end, :scale_channel], [lambda do env_channel(make_env([0, 0, 1, 1], :length, 123), 0, 123, oboe, 0, 123) end, :env_channel], [lambda do clm_channel(make_oscil, 0, 123, oboe, 0, 123) end, :clm_channel], [lambda do vct2channel(make_vct(3), 0, 123, oboe, 0, 123) end, :vct2channel], [lambda do smooth_channel(0, 123, oboe, 0, 123) end, :smooth_channel], [lambda do pad_channel(0, 123, oboe, 0, 123) end, :pad_channel], [lambda do src_channel(2.0, 0, 123, oboe, 0, 123) end, :src_channel], [lambda do mix_channel("pistol.snd", 0, 123, oboe, 0, 123) end, :mix_channel], [lambda do insert_channel("pistol.snd", 0, 123, oboe, 0, 123) end, :insert_channel], [lambda do reverse_channel(0, 123, oboe, 0, 123) end, :reverse_channel]].each do |func, name| if (res = Snd.catch do func.call end).first != :no_such_edit snd_display("bad edpos %s: %s", name, res.inspect) end if (res = edit_position(oboe)) != 0 snd_display("edpos: 123 %s: %s %s?", name, res, edit_fragment) end end revert_sound(oboe) oldv = channel2vct(1000, 10, oboe) mix_channel("oboe.snd", 0) oldv.scale!(2.0) unless vequal(res = channel2vct(1000, 10, oboe), oldv) snd_display("mix_channel at 0: %s %s?", oldv, res) end revert_sound(oboe) oldv.scale!(0.5) insert_channel("oboe.snd", 0) unless vequal(res = channel2vct(1000, 10, oboe), oldv) snd_display("insert_channel at 0: %s %s?", oldv, res) end if (res1 = framples(oboe, 0)) != (res2 = framples(oboe, 0, 0)) * 2 snd_display("insert_channel framples: %s %s?", res1, res2) end revert_sound(oboe) close_sound(oboe) end def funcs_equal?(name, func0, func1, oboe0, oboe1) func0.call(false, false, oboe0) func1.call(false, false, oboe1) res1 = channel2vct(1000, 100, oboe0) res2 = channel2vct(1000, 100, oboe1) snd_test_neq(channel2vct(1000, 100, oboe0), channel2vct(1000, 100, oboe1), "%s via false", name) revert_sound(oboe0) revert_sound(oboe1) select_sound(oboe0) func0.call select_sound(oboe1) func1.call snd_test_neq(channel2vct(1000, 100, oboe0), channel2vct(1000, 100, oboe1), "%s via none", name) revert_sound(oboe0) revert_sound(oboe1) func0.call(0, framples(oboe0), oboe0) func1.call(0, framples(oboe1), oboe1) snd_test_neq(channel2vct(1000, 100, oboe0), channel2vct(1000, 100, oboe1), "%s via 0 framples", name) revert_sound(oboe0) revert_sound(oboe1) end def test_16_01 if default_output_chans != 1 set_default_output_chans(1) end ind = new_sound("fmv.snd") v0 = Vct.new(20, 1.0) vct2channel(v0) if framples != 20 snd_display("vct2channel new 20: %s?", framples) end if fneq(maxamp, 1.0) snd_display("vct 1->new: %s?", maxamp) end env_channel(make_env(:envelope, [0, 0, 1, 1, 2, 1], :base, 0, :length, 20)) if (res = channel2vct) != vct(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) snd_display("env_channel step 1: %s?", res) end undo_edit env_channel(make_env(:envelope, [0, 0, 1, 1, 2, 1], :base, 0, :length, 20), 8) if (res = channel2vct) != vct(1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1) snd_display("env_channel step 1 at 8: %s?", res) end undo_edit env_channel(make_env(:envelope, [0, 0, 1, 1, 2, 1], :base, 0, :length, 12)) if (res = channel2vct) != vct(0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) snd_display("env_channel step 1 at 0: %s?", res) end undo_edit env_channel(make_env(:envelope, [0, 0, 1, 1, 2, 1], :base, 0, :length, 12), 4) if (res = channel2vct) != vct(1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) snd_display("env_channel step 1 at 4: %s?", res) end undo_edit env_channel(make_env(:envelope, [0, 0, 1, 1, 2, 1], :base, 0, :length, 12), 4, 3) if (res = channel2vct) != vct(1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) snd_display("env_channel step 1 at 4 by 3: %s?", res) end undo_edit env_channel(make_env(:envelope, [0, 1, 1, 0, 2, 0], :base, 0, :length, 8), 0, 12) if (res = channel2vct) != vct(1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1) snd_display("env_channel step 1 at 0 for 7: %s?", res) end undo_edit env_channel(make_env(:envelope, [0, 0, 1, 1, 2, 1, 3, 0, 4, 0], :base, 0, :length, 20)) if (res = channel2vct) != vct(0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0) snd_display("env_channel step 1: %s?", res) end undo_edit env_channel(make_env(:envelope, [0, 0, 1, 0.5, 2, 0.25, 3, 0, 4, 0], :base, 0, :length, 21)) if (res = channel2vct) != vct(0, 0, 0, 0, 0, 0, 0.5, 0.5, 0.5, 0.5, 0.5, 0.25, 0.25, 0.25, 0.25, 0.25, 0, 0, 0, 0) snd_display("env_channel step 1 (0.5): %s?", res) end close_sound(ind) # set_x_axis_style(X_axis_as_percentage) ind = open_sound("2.snd") fr = framples m0 = maxamp(ind, 0) m1 = maxamp(ind, 1) set_sync(64, ind) insert_sound("2.snd") insert_sound("2.snd") if framples != fr * 3 snd_display("2.snd 3x = %s %s?", fr, framples) end if (res1 = framples(ind, 0)) != (res2 = framples(ind, 1)) snd_display("insert synced: %s %s?", res1, res2) end swap_channels if fneq(res1 = maxamp(ind, 1), m0) or fneq(res2 = maxamp(ind, 0), m1) snd_display("swapped: %s %s -> %s %s?", m0, m1, res1, res2) end close_sound(ind) set_x_axis_style(X_axis_in_seconds) new_snd = mono_files2stereo("test.snd", "oboe.snd", "pistol.snd") if channels(new_snd) != 2 snd_display("mono_files2stereo not stereo: %s?", channels(new_snd)) end if (res = short_file_name(new_snd)) != "test.snd" snd_display("mono_files2stereo filename: %s?", res) end if (res = framples(new_snd)) != 50828 snd_display("mono_files2stereo framples: %s?", res) end close_sound(new_snd) # oboe0 = open_sound("oboe.snd") oboe1 = open_sound("oboe.snd") funcs_equal?(:scale_sound_by, lambda { |*args| scale_sound_by(2.0, *args)}, lambda { |*args| scale_channel(2.0, *args)}, oboe0, oboe1) funcs_equal?(:scale_and_ramp_0, lambda { |*args| scale_sound_by(0.0, *args)}, lambda { |*args| ramp_channel(0.0, 0.0, *args)}, oboe0, oboe1) funcs_equal?(:scale_and_ramp_2, lambda { |*args| scale_sound_by(2.0, *args)}, lambda { |*args| ramp_channel(2.0, 2.0, *args)}, oboe0, oboe1) funcs_equal?(:smooth_sound, lambda { |*args| smooth_sound(*args)}, lambda { |*args| smooth_channel(*args)}, oboe0, oboe1) funcs_equal?(:env_sound, lambda { |*args| beg = (args[0] or 0) len = (args[1] and number?(args[1])) ? (args[1] - 1) : false snd = (args[2] or selected_sound) env_sound([0, 0, 1, 1], beg, len, 1.0, snd) }, lambda { |*args| snd = (args[2] or selected_sound) len = (args[1] and number?(args[1])) ? args[1] : (framples(snd) - 1) env_channel(make_env(:envelope, [0, 0, 1, 1], :length, len), *args) }, oboe0, oboe1) funcs_equal?(:map_chan, lambda { |*args| beg = (args[0] or 0) len = (args[1] and number?(args[1])) ? (args[1] - 1) : false snd = (args[2] or selected_sound) map_chan(lambda { |n| n * 2 }, beg, len, "testing...", snd) }, lambda { |*args| beg = (args[0] or 0) len = (args[1] and number?(args[1])) ? (args[1] - 1) : false snd = (args[2] or selected_sound) map_channel(lambda { |n| n * 2 }, beg, len, snd) }, oboe0, oboe1) funcs_equal?(:src_sound, lambda { |*args| src_sound(2.0, 1.0, (args[2] or false)) }, lambda { |*args| src_channel(2.0, *args) }, oboe0, oboe1) funcs_equal?(:reverse_sound, lambda { |*args| reverse_sound((args[2] or false)) }, lambda { |*args| reverse_channel(*args) }, oboe0, oboe1) funcs_equal?(:mix, lambda { |*args| mix("pistol.snd", 0, 0, (args[2] or false)) }, lambda { |*args| mix_channel("pistol.snd", *args) }, oboe0, oboe1) funcs_equal?(:insert_sound, lambda { |*args| insert_sound("pistol.snd", 0, 0, (args[2] or false)) }, lambda { |*args| insert_channel("pistol.snd", *args) }, oboe0, oboe1) close_sound(oboe0) close_sound(oboe1) # ind = open_sound("oboe.snd") scale_by(0.5) scale_by(0.25) undo_edit [[lambda { |n| scale_channel(0.5, 0, false, n, 0, 2) }, :scale_channel], [lambda { |n| env_channel([0, 0, 1, 1, 2, 0], 0, false, n, 0, 2) }, :env_channel], [lambda { |n| pad_channel(0, 100, n, 0, 2) }, :pad_channel_0], [lambda { |n| pad_channel(100, 100, n, 0, 2) }, :pad_channel_100], [lambda { |n| delete_sample(100, n, 0, 2) }, :delete_sample], [lambda { |n| set_sample(100, 0.52, n, 0, 2) }, :set_sample]].each do |func, name| if (res = Snd.catch do func.call(ind) end).first != :no_such_edit snd_display("%s upon about-to-be-clobbered data: %s", name, res.inspect) end end close_sound(ind) # ind = open_sound("oboe.snd") ind1 = new_sound("test.snd") old_save_dir = save_dir set_save_dir(false) map_channel(lambda do |y| 0.5 end, 0, 100, ind1, 0) save_sound(ind1) close_sound(ind1) insert_sound("test.snd", 12345) delete_file("hiho.rb") vals = channel2vct(12345 - 50, 200, ind, 0) save_state("hiho.rb") close_sound(ind) Snd.regions.apply(:forget_region) load("hiho.rb") ind = find_sound("oboe.snd") if sound?(ind) unless vequal(res = channel2vct(12345 - 50, 200, ind, 0), vals) snd_display("save_state hiho vals:\n# %s\n# %s?", vals, res) end else snd_display("save hiho failed?") end close_sound(ind) set_save_dir(old_save_dir) # set_x_axis_style(X_axis_in_beats) ind = open_sound("storm.snd") reverse_channel(500000, 1000000) set_sample(0, 0.1, ind, 0, Current_edit_position) if fneq(res = sample(0, ind, 0, Current_edit_position), 0.1) snd_display("set_sample + edpos: %s?", res) end close_sound(ind) set_x_axis_style(X_axis_in_seconds) # [1, 2, 4].each do |out_chans| ind = new_sound("new.snd", out_chans, 22050, Mus_bfloat, Mus_next, "edpos testing") mx = Snd.sounds.map do |s| sync(s) end.max set_sync(mx + 1, ind) ["2a.snd", "1a.snd", "4a.snd"].each do |in_snd| [lambda do |posfunc| chn = [random(out_chans + 1), out_chans - 1].min res = channel2vct(0, framples(ind, chn), ind, chn, 0) unless vequal(res, vct(0.0)) snd_display("start bad: %s?", res) end set_sample(0, 0.1, ind, chn) res = channel2vct(0, framples(ind, chn), ind, chn) unless vequal(res, vct(0.1)) snd_display("set bad: %s?", res) end pad_channel(0, 1, ind, chn, posfunc.call) if proc?(pos = posfunc.call) pos = pos.call(ind, chn) end data = channel2vct(0, framples(ind, chn), ind, chn) if (pos.zero? and (not vequal(data, vct(0.0, 0.0)))) or ((pos == Current_edit_position or pos == edit_position(ind, chn)) and (not vequal(data, vct(0.0, 0.1)))) or (pos == edit_position(ind, chn) - 1 and (not vequal(data, vct(0.0, 0.0)))) snd_display("pos[%s]: edpos %s of %s, pad result[%s, %s]: %s?", chn, pos, edit_position(ind, chn), framples(ind, chn, pos), framples(ind, chn), data) end if channels(ind) > 1 channels(ind).times do |i| next if chn == i res = channel2vct(0, framples(ind, i), ind, i) unless vequal(res, vct(0.0)) snd_display("pad[%s / %s] empty: %s?", i, chn, data) end end end end, lambda do |posfunc| chn = [random(out_chans + 1), out_chans - 1].min set_sample(0, 0.1, ind, chn) set_sample(0, sample(0, ind, chn, posfunc.call()) * 2.0, ind, chn, posfunc.call()) if proc?(pos = posfunc.call) pos = pos.call(ind, chn) end data = channel2vct(0, framples(ind, chn), ind, chn) if (pos.zero? and (not vequal(data, vct(0.0)))) or ((pos == Current_edit_position or pos == edit_position(ind, chn)) and (not vequal(data, vct(0.2)))) or (pos == edit_position(ind, chn) - 1 and (not vequal(data, vct(0.0)))) snd_display("pos[%s]: edpos %s of %s, set *2 result[%s, %s]: %s?", chn, pos, edit_position(ind, chn), framples(ind, chn, pos), framples(ind, chn), data) end if channels(ind) > 1 channels(ind).times do |i| next if chn == i res = channel2vct(0, framples(ind, i), ind, i) unless vequal(res, vct(0.0)) snd_display("scale[%s / %s] empty: %s?", i, chn, data) end end end end].each do |func| [lambda do Current_edit_position end, lambda do 0 end, lambda do edit_position(ind, 0) - 1 end, lambda do edit_position(ind, 0) end].each do |edpos| func.call(edpos) revert_sound(ind) end end end close_sound(ind) end # ind = open_sound("oboe.snd") map_channel(lambda do |y| false end) if framples(ind) != 0 snd_display("map_channel false framples: %s?", framples(ind)) end if edits(ind) == [0, 0] snd_display("map_channel false edits backed up") end undo_edit(1, ind) if framples(ind) == 0 snd_display("map_channel false framples after undo: %s?", framples(ind)) end if (res = Snd.catch do map_channel(lambda do |y| "hiho" end) end).first != :bad_type snd_display("map_channel bad_type: %s", res.inspect) end ctr = 0 if (res = Snd.catch do scan_channel(lambda do |y| ctr += 1 asdf end) end).first != :name_error snd_display("scan_channel unbound: %s", res.inspect) end if ctr != 1 snd_display("scan_channel error exit: %s?", ctr) end if res = scan_channel(lambda do |y| false end) snd_display("scan_channel func false: %s?", res) end if res = scan_channel(lambda do |y| false end, 1234) snd_display("scan_channel func false with beg: %s?", res) end if res = scan_channel(lambda do |y| false end, 1234, 4321) snd_display("scan_channel func false with beg+dur: %s?", res) end revert_sound(ind) del = make_delay(1000) len = framples clm_channel(del, 0, len, ind, 0, 0, 2000) if framples(ind) != len + 2000 snd_display("clm_channel overlap length: %s %s?", len, framples) end if edit_tree != [[0, 1, 0, 52827, 1.0, 0.0, 0.0, 0], [52828, -2, 0, 0, 0.0, 0.0, 0.0, 0]] snd_display("clm_channel overlaps: %s?", edit_tree) end reader = make_sampler(0) preader = make_sampler(0, ind, 0, 1, 0) 1000.times do |i| if fneq(res = reader.call, 0.0) snd_display("clm_channel overlap delayed[%s]: %s?", i, res) break end end len.times do |i| if fneq(res1 = reader.call, res2 = preader.call) snd_display("clm_channel overlap main[%s]: %s %s?", i + 1000, res1, res2) break end end 1000.times do |i| if fneq(res = reader.call, 0.0) snd_display("clm_channel overlap trailing garbage[%s]: %s?", i, res) break end end close_sound(ind) # ind = open_sound("oboe.snd") oldamp = 0.0 oldloc = 0 ctr = 0 scan_channel(lambda { |y| if y.abs >= oldamp oldloc = ctr oldamp = y.abs end ctr += 1 false }) scale_by(10.0) scale_by(0.1) reverse_channel(0, false, ind, 0, 1) amp = 0.0 loc = 0 ctr = framples - 1 scan_channel(lambda { |y| if y.abs > amp amp = y.abs loc = ctr end ctr -= 1 false }) if fneq(oldamp, amp * 0.1) or loc != oldloc snd_display("reverse edpos screwup: %s at %s, %s at %s?", oldamp, oldloc, amp, loc) end reverse_channel(0, false, ind, 0, 2) amp = 0.0 loc = 0 ctr = framples - 1 scan_channel(lambda { |y| if y.abs > amp amp = y.abs loc = ctr end ctr -= 1 false }) if fneq(oldamp, amp) or loc != oldloc snd_display("reverse unscaled edpos screwup: %s at %s, %s at %s?", oldamp, oldloc, amp, loc) end close_sound(ind) end class Mus alias old_call call alias call run end def check_env(name, r, e, dur) dur.times do |i| if fneq(rv = r.call, ev = e.call) snd_display("%s env check [%s]: %s %s?", name, i, rv, ev) return end end end def test_16_02 mus_clipping and set_mus_clipping(false) clipping and set_clipping(false) ind = new_sound("fmv.snd", 1, 22050, Mus_bfloat, Mus_next, "edit trees") select_sound(ind) select_channel(0) check_edit_tree([[0, 0, 0, 0, 0.0, 0.0, 0.0, 1], [1, -2, 0, 0, 0.0, 0.0, 0.0, 0]], Vct.new(1), "initial new_sound") vals = Vct.new(100, 1.0) set_samples(0, 100, vals) check_edit_tree([[0, 1, 0, 99, 1.0, 0.0, 0.0, 1], [100, -2, 0, 0, 0.0, 0.0, 0.0, 0]], vals, "set first samps to one") scale_channel(0.5, 10, 20) 10.upto(29) do |i| vals[i] = 0.5 end check_edit_tree([[0, 1, 0, 9, 1.0, 0.0, 0.0, 1], [10, 1, 10, 29, 0.5, 0.0, 0.0, 0], [30, 1, 30, 99, 1.0, 0.0, 0.0, 0], [100, -2, 0, 0, 0.0, 0.0, 0.0, 0]], vals, "scale_channel(0.5, 10, 20)") env_channel(make_env(:envelope, [0, 0, 1, 1], :length, 11), 15, 10) e = make_env(:envelope, [0, 0, 1, 1], :length, 11) 15.upto(24) do |i| vals[i] *= env(e) end check_edit_tree([[0, 1, 0, 9, 1.0, 0.0, 0.0, 0], [10, 1, 10, 14, 0.5, 0.0, 0.0, 0], [15, 1, 15, 24, 0.5, 0.0, 0.1, 1], [25, 1, 25, 29, 0.5, 0.0, 0.0, 0], [30, 1, 30, 99, 1.0, 0.0, 0.0, 0], [100, -2, 0, 0, 0.0, 0.0, 0.0, 0]], vals, "env_channel(15, 10)") normalize_channel(1.0) check_edit_tree([[0, 1, 0, 9, 1.0, 0.0, 0.0, 0], [10, 1, 10, 14, 0.5, 0.0, 0.0, 0], [15, 1, 15, 24, 0.5, 0.0, 0.1, 1], [25, 1, 25, 29, 0.5, 0.0, 0.0, 0], [30, 1, 30, 99, 1.0, 0.0, 0.0, 0], [100, -2, 0, 0, 0.0, 0.0, 0.0, 0]], vals, "env_channel(15, 10) a") select_all if fneq(res = selection_maxamp, 1.0) snd_display("selection_maxamp in checker: %s?", res) end scale_selection_to(1.0) check_edit_tree([[0, 1, 0, 9, 1.0, 0.0, 0.0, 0], [10, 1, 10, 14, 0.5, 0.0, 0.0, 0], [15, 1, 15, 24, 0.5, 0.0, 0.1, 1], [25, 1, 25, 29, 0.5, 0.0, 0.0, 0], [30, 1, 30, 99, 1.0, 0.0, 0.0, 0], [100, -2, 0, 0, 0.0, 0.0, 0.0, 0]], vals, "env_channel(15, 10) b") set_selection_position(5) set_selection_framples(10) scale_selection_to(0.5) 5.upto(14) do |i| vals[i] *= 0.5 end check_edit_tree([[0, 1, 0, 4, 1.0, 0.0, 0.0, 0], [5, 1, 5, 9, 0.5, 0.0, 0.0, 0], [10, 1, 10, 14, 0.25, 0.0, 0.0, 0], [15, 1, 15, 24, 0.5, 0.0, 0.1, 1], [25, 1, 25, 29, 0.5, 0.0, 0.0, 0], [30, 1, 30, 99, 1.0, 0.0, 0.0, 0], [100, -2, 0, 0, 0.0, 0.0, 0.0, 0]], vals, "scale_selection_to(0.5)") set_sample(20, 0.1) vals[20] = 0.1 check_edit_tree([[0, 1, 0, 4, 1.0, 0.0, 0.0, 0], [5, 1, 5, 9, 0.5, 0.0, 0.0, 0], [10, 1, 10, 14, 0.25, 0.0, 0.0, 0], [15, 1, 15, 19, 0.5, 0.0, 0.1, 1], [20, 2, 0, 0, 1.0, 0.0, 0.0, 0], [21, 1, 21, 24, 0.5, 0.6, 0.1, 4], [25, 1, 25, 29, 0.5, 0.0, 0.0, 0], [30, 1, 30, 99, 1.0, 0.0, 0.0, 0], [100, -2, 0, 0, 0.0, 0.0, 0.0, 0]], vals, "set_sample(20, 0.1)") reverse_channel(5, 10) j = 14 5.upto(9) do |i| vals[i], vals[j] = vals[j], vals[i] j -= 1 end check_edit_tree([[0, 1, 0, 4, 1.0, 0.0, 0.0, 0], [5, 3, 0, 9, 1.0, 0.0, 0.0, 0], [15, 1, 15, 19, 0.5, 0.0, 0.1, 1], [20, 2, 0, 0, 1.0, 0.0, 0.0, 0], [21, 1, 21, 24, 0.5, 0.6, 0.1, 4], [25, 1, 25, 29, 0.5, 0.0, 0.0, 0], [30, 1, 30, 99, 1.0, 0.0, 0.0, 0], [100, -2, 0, 0, 0.0, 0.0, 0.0, 0]], vals, "reverse_channel(5, 10)") if fneq(res = selection_maxamp, 0.5) snd_display("selection_maxamp before: %s?", res) end mixvals = Vct.new(10, 0.1) old_sample4 = sample(4) old_sample5 = sample(5) id = mix_vct(mixvals, 4) 4.upto(13) do |i| vals[i] += mixvals[i - 4] end check_edit_tree([[0, 1, 0, 3, 1.0, 0.0, 0.0, 0], [4, 1, 4, 4, 1.0, 0.0, 0.0, 1], [5, 3, 0, 8, 1.0, 0.0, 0.0, 1], [14, 3, 9, 9, 1.0, 0.0, 0.0, 0], [15, 1, 15, 19, 0.5, 0.0, 0.1, 4], [20, 2, 0, 0, 1.0, 0.0, 0.0, 0], [21, 1, 21, 24, 0.5, 0.6, 0.1, 4], [25, 1, 25, 29, 0.5, 0.0, 0.0, 0], [30, 1, 30, 99, 1.0, 0.0, 0.0, 0], [100, -2, 0, 0, 0.0, 0.0, 0.0, 0]], vals, format("mix_vct(id: %s (%s) [%s, %s] + 0.1 -> [%s, %s] [%s, %s]) 4 (0.1)", id, ind, old_sample4, old_sample5, sample(4), sample(5), vals[4], vals[5])) delete_samples(28, 12) insert_silence(28, 12) 28.upto(39) do |i| vals[i] = 0.0 end old_vals = vals.dup check_edit_tree([[0, 1, 0, 3, 1.0, 0.0, 0.0, 0], [4, 1, 4, 4, 1.0, 0.0, 0.0, 1], [5, 3, 0, 8, 1.0, 0.0, 0.0, 1], [14, 3, 9, 9, 1.0, 0.0, 0.0, 0], [15, 1, 15, 19, 0.5, 0.0, 0.1, 4], [20, 2, 0, 0, 1.0, 0.0, 0.0, 0], [21, 1, 21, 24, 0.5, 0.6, 0.1, 4], [25, 1, 25, 27, 0.5, 0.0, 0.0, 0], [28, -1, 0, 11, 0.0, 0.0, 0.0, 0], [40, 1, 40, 99, 1.0, 0.0, 0.0, 0], [100, -2, 0, 0, 0.0, 0.0, 0.0, 0]], vals, "delete_samples(28, 12); insert_silence(28, 12)") if fneq(res = selection_maxamp, 0.6) snd_display("selection_maxamp after: %s?", res) end set_selection_position(50) set_selection_framples(10) scale_selection_by(0.1) if fneq(res = selection_maxamp, 0.1) snd_display("re-selection_maxamp: %s?", res) end 50.upto(59) do |i| vals[i] = 0.1 end check_edit_tree([[0, 1, 0, 3, 1.0, 0.0, 0.0, 0], [4, 1, 4, 4, 1.0, 0.0, 0.0, 1], [5, 3, 0, 8, 1.0, 0.0, 0.0, 1], [14, 3, 9, 9, 1.0, 0.0, 0.0, 0], [15, 1, 15, 19, 0.5, 0.0, 0.1, 1], [20, 2, 0, 0, 1.0, 0.0, 0.0, 0], [21, 1, 21, 24, 0.5, 0.6, 0.1, 4], [25, 1, 25, 27, 0.5, 0.0, 0.0, 0], [28, -1, 0, 11, 0.0, 0.0, 0.0, 0], [40, 1, 40, 49, 1.0, 0.0, 0.0, 0], [50, 1, 50, 59, 0.1, 0.0, 0.0, 0], [60, 1, 60, 99, 1.0, 0.0, 0.0, 0], [100, -2, 0, 0, 0.0, 0.0, 0.0, 0]], vals, "scale_selection_by(0.1)") env_channel(make_env(:envelope, [0, 0, 1, 1, 2, 0, 3, 0], :length, 31, :base, 0), 50, 30) e = make_env(:envelope, [0, 0, 1, 1, 2, 0, 3, 0], :length, 31, :base, 0) 50.upto(79) do |i| vals[i] *= env(e) end check_edit_tree([[0, 1, 0, 3, 1.0, 0.0, 0.0, 0], [4, 1, 4, 4, 1.0, 0.0, 0.0, 1], [5, 3, 0, 8, 1.0, 0.0, 0.0, 1], [14, 3, 9, 9, 1.0, 0.0, 0.0, 0], [15, 1, 15, 19, 0.5, 0.0, 0.1, 4], [20, 2, 0, 0, 1.0, 0.0, 0.0, 0], [21, 1, 21, 24, 0.5, 0.6, 0.1, 4], [25, 1, 25, 27, 0.5, 0.0, 0.0, 0], [28, -1, 0, 11, 0.0, 0.0, 0.0, 0], [40, 1, 40, 49, 1.0, 0.0, 0.0, 0], [50, 1, 50, 59, 0.0, 0.0, 0.0, 0], [60, 1, 60, 60, 0.0, 0.0, 0.0, 0], [61, 1, 61, 70, 1.0, 0.0, 0.0, 0], [71, 1, 71, 79, 0.0, 0.0, 0.0, 0], [80, 1, 80, 99, 1.0, 0.0, 0.0, 0], [100, -2, 0, 0, 0.0, 0.0, 0.0, 0]], vals, "step env 30") undo_channel(2) check_edit_tree([[0, 1, 0, 3, 1.0, 0.0, 0.0, 0], [4, 1, 4, 4, 1.0, 0.0, 0.0, 1], [5, 3, 0, 8, 1.0, 0.0, 0.0, 1], [14, 3, 9, 9, 1.0, 0.0, 0.0, 0], [15, 1, 15, 19, 0.5, 0.0, 0.1, 4], [20, 2, 0, 0, 1.0, 0.0, 0.0, 0], [21, 1, 21, 24, 0.5, 0.6, 0.1, 4], [25, 1, 25, 27, 0.5, 0.0, 0.0, 0], [28, -1, 0, 11, 0.0, 0.0, 0.0, 0], [40, 1, 40, 99, 1.0, 0.0, 0.0, 0], [100, -2, 0, 0, 0.0, 0.0, 0.0, 0]], old_vals, "undo to delete/insert (over step env)") redo_channel(2) check_edit_tree([[0, 1, 0, 3, 1.0, 0.0, 0.0, 0], [4, 1, 4, 4, 1.0, 0.0, 0.0, 1], [5, 3, 0, 8, 1.0, 0.0, 0.0, 1], [14, 3, 9, 9, 1.0, 0.0, 0.0, 0], [15, 1, 15, 19, 0.5, 0.0, 0.1, 4], [20, 2, 0, 0, 1.0, 0.0, 0.0, 0], [21, 1, 21, 24, 0.5, 0.6, 0.1, 4], [25, 1, 25, 27, 0.5, 0.0, 0.0, 0], [28, -1, 0, 11, 0.0, 0.0, 0.0, 0], [40, 1, 40, 49, 1.0, 0.0, 0.0, 0], [50, 1, 50, 59, 0.0, 0.0, 0.0, 0], [60, 1, 60, 60, 0.0, 0.0, 0.0, 0], [61, 1, 61, 70, 1.0, 0.0, 0.0, 0], [71, 1, 71, 79, 0.0, 0.0, 0.0, 0], [80, 1, 80, 99, 1.0, 0.0, 0.0, 0], [100, -2, 0, 0, 0.0, 0.0, 0.0, 0]], vals, "redo past step env 30") set_sample(75, -0.5) vals[75] = -0.5 flt = make_one_zero(0.5, 0.5) flt1 = make_one_zero(0.5, 0.5) clm_channel(flt, 75, 10) 75.upto(84) do |i| vals[i] = one_zero(flt1, vals[i]) end check_edit_tree([[0, 1, 0, 3, 1.0, 0.0, 0.0, 0], [4, 1, 4, 4, 1.0, 0.0, 0.0, 1], [5, 3, 0, 8, 1.0, 0.0, 0.0, 1], [14, 3, 9, 9, 1.0, 0.0, 0.0, 0], [15, 1, 15, 19, 0.5, 0.0, 0.1, 4], [20, 2, 0, 0, 1.0, 0.0, 0.0, 0], [21, 1, 21, 24, 0.5, 0.6, 0.1, 4], [25, 1, 25, 27, 0.5, 0.0, 0.0, 0], [28, -1, 0, 11, 0.0, 0.0, 0.0, 0], [40, 1, 40, 49, 1.0, 0.0, 0.0, 0], [50, 1, 50, 59, 0.0, 0.0, 0.0, 0], [60, 1, 60, 60, 0.0, 0.0, 0.0, 0], [61, 1, 61, 70, 1.0, 0.0, 0.0, 0], [71, 1, 71, 74, 0.0, 0.0, 0.0, 0], [75, 6, 0, 9, 1.0, 0.0, 0.0, 0], [85, 1, 85, 99, 1.0, 0.0, 0.0, 0], [100, -2, 0, 0, 0.0, 0.0, 0.0, 0]], vals, "clm_channel(flt, 75, 10)") map_channel(lambda do |y| y * 0.5 end, 3, 11) 3.upto(13) do |i| vals[i] *= 0.5 end check_edit_tree([[0, 1, 0, 2, 1.0, 0.0, 0.0, 0], [3, 8, 0, 10, 1.0, 0.0, 0.0, 0], [14, 7, 10, 11, 1.0, 0.0, 0.0, 0], [16, 1, 16, 19, 0.5, 0.1, 0.1, 4], [20, 2, 0, 0, 1.0, 0.0, 0.0, 0], [21, 1, 21, 24, 0.5, 0.6, 0.1, 4], [25, 1, 25, 27, 0.5, 0.0, 0.0, 0], [28, -1, 0, 11, 0.0, 0.0, 0.0, 2], [40, 1, 40, 49, 1.0, 0.0, 0.0, 0], [50, 1, 50, 59, 0.0, 0.0, 0.0, 0], [60, 1, 60, 60, 0.0, 0.0, 0.0, 0], [61, 1, 61, 70, 1.0, 0.0, 0.0, 0], [71, 1, 71, 74, 0.0, 0.0, 0.0, 0], [75, 6, 0, 9, 1.0, 0.0, 0.0, 0], [85, 1, 85, 99, 1.0, 0.0, 0.0, 0], [100, -2, 0, 0, 0.0, 0.0, 0.0, 0]], vals, "map_channel 3 14") reader = make_sampler(50) map_channel(lambda do |y| y - reader.call end, 0, 25) 25.times do |i| vals[i] -= vals[i + 50] end check_edit_tree([[0, 9, 0, 24, 1.0, 0.0, 0.0, 0], [25, 1, 25, 27, 0.5, 0.0, 0.0, 0], [28, -1, 0, 11, 0.0, 0.0, 0.0, 2], [40, 1, 40, 49, 1.0, 0.0, 0.0, 0], [50, 1, 50, 59, 0.0, 0.0, 0.0, 2], [60, 1, 60, 60, 0.0, 0.0, 0.0, 2], [61, 1, 61, 70, 1.0, 0.0, 0.0, 0], [71, 1, 71, 74, 0.0, 0.0, 0.0, 2], [75, 6, 0, 9, 1.0, 0.0, 0.0, 0], [85, 1, 85, 99, 1.0, 0.0, 0.0, 0], [100, -2, 0, 0, 0.0, 0.0, 0.0, 0]], vals, "back set via map_channel") set_selection_position(20) set_selection_framples(70) env_selection([0, 0, 1, 1]) if fneq(res = selection_maxamp(ind, 0), 1.0) snd_display("selection_maxamp after env_selection: %s?", res) end x = 0.0 incr = 1.0 / 69.0 20.upto(89) do |i| vals[i] *= x x += incr end check_edit_tree([[0, 9, 0, 19, 1.0, 0.0, 0.0, 0], [20, 9, 20, 24, 1.0, 0.0, 0.0145, 4], [25, 1, 25, 27, 0.5, 0.072, 0.0145, 4], [28, -1, 0, 11, 0.0, 0.0, 0.0, 2], [40, 1, 40, 49, 1.0, 0.2898, 0.0145, 4], [50, 1, 50, 59, 0.0, 0.0, 0.0, 2], [60, 1, 60, 60, 0.0, 0.0, 0.0, 2], [61, 1, 61, 70, 1.0, 0.5942, 0.0145, 4], [71, 1, 71, 74, 0.0, 0.0, 0.0, 2], [75, 6, 0, 9, 1.0, 0.7971, 0.0145, 4], [85, 1, 85, 89, 1.0, 0.942, 0.0145, 4], [90, 1, 90, 99, 1.0, 0.0, 0.0, 0], [100, -2, 0, 0, 0.0, 0.0, 0.0, 0]], vals, "env_selection([0, 0, 1, 1])") normalize_channel(0.5) vals.scale!(0.5) check_edit_tree([[0, 9, 0, 19, 0.5, 0.0, 0.0, 0], [20, 9, 20, 24, 0.5, 0.0, 0.0145, 4], [25, 1, 25, 27, 0.25, 0.0725, 0.0145, 4], [28, -1, 0, 11, 0.0, 0.0, 0.0, 2], [40, 1, 40, 49, 0.5, 0.2898, 0.0145, 4], [50, 1, 50, 59, 0.0, 0.0, 0.0, 2], [60, 1, 60, 60, 0.0, 0.0, 0.0, 2], [61, 1, 61, 70, 0.5, 0.5942, 0.0145, 4], [71, 1, 71, 74, 0.0, 0.0, 0.0, 2], [75, 6, 0, 9, 0.5, 0.7971, 0.0145, 4], [85, 1, 85, 89, 0.5, 0.942, 0.0145, 4], [90, 1, 90, 99, 0.5, 0.0, 0.0, 0], [100, -2, 0, 0, 0.0, 0.0, 0.0, 0]], vals, "normalize_channel(0.5)") if fneq(res = selection_maxamp, 0.5) snd_display("selection_maxamp after scl: %s?", res) end delete_samples(0, 100) insert_silence(0, 100) vals.fill(0.0) check_edit_tree([[0, -1, 0, 99, 0.0, 0.0, 0.0, 0], [100, -2, 0, 0, 0.0, 0.0, 0.0, 0]], vals, "second set...") set_sample(50, 0.5) vals[50] = 0.5 check_edit_tree([[0, -1, 0, 49, 0.0, 0.0, 0.0, 2], [50, 10, 0, 0, 1.0, 0.0, 0.0, 0], [51, -1, 51, 99, 0.0, 0.0, 0.0, 2], [100, -2, 0, 0, 0.0, 0.0, 0.0, 0]], vals, "split silence") map_channel($init_channel, 0, 25) 25.times do |i| vals[i] = 1.0 end check_edit_tree([[0, 11, 0, 24, 1.0, 0.0, 0.0, 0], [25, -1, 25, 49, 0.0, 0.0, 0.0, 2], [50, 10, 0, 0, 1.0, 0.0, 0.0, 0], [51, -1, 51, 99, 0.0, 0.0, 0.0, 2], [100, -2, 0, 0, 0.0, 0.0, 0.0, 0]], vals, "clobber silence start") map_channel($init_channel, 75, 25) 75.upto(99) do |i| vals[i] = 1.0 end check_edit_tree([[0, 11, 0, 24, 1.0, 0.0, 0.0, 0], [25, -1, 25, 49, 0.0, 0.0, 0.0, 2], [50, 10, 0, 0, 1.0, 0.0, 0.0, 0], [51, -1, 51, 74, 0.0, 0.0, 0.0, 2], [75, 12, 0, 24, 1.0, 0.0, 0.0, 0], [100, -2, 0, 0, 0.0, 0.0, 0.0, 0]], vals, "clobber silence end") scale_channel(0.0, 0, 100) vals.fill(0.0) check_edit_tree([[0, 0, 0, 99, 0.0, 0.0, 0.0, 1], [100, -2, 0, 0, 0.0, 0.0, 0.0, 0]], vals, "scale_channel(0.0, 0, 100)") e = make_env(:envelope, [0, 0, 1, 1], :length, 101) e1 = make_env(:envelope, [0, 0, 1, 1], :length, 101) map_channel(lambda do |y| env(e) end) vals.map! do |val| env(e1) end check_edit_tree([[0, 13, 0, 99, 1.0, 0.0, 0.0, 0], [100, -2, 0, 0, 0.0, 0.0, 0.0, 0]], vals, "env start") set_sample(50, -0.5) vals[50] = -0.5 check_edit_tree([[0, 13, 0, 49, 1.0, 0.0, 0.0, 0], [50, 14, 0, 0, 1.0, 0.0, 0.0, 0], [51, 13, 51, 99, 1.0, 0.0, 0.0, 0], [100, -2, 0, 0, 0.0, 0.0, 0.0, 0]], vals, "split env segment") map_channel($init_channel, 0, 25) 25.times do |i| vals[i] = 1.0 end check_edit_tree([[0, 15, 0, 24, 1.0, 0.0, 0.0, 0], [25, 13, 25, 49, 1.0, 0.0, 0.0, 0], [50, 14, 0, 0, 1.0, 0.0, 0.0, 0], [51, 13, 51, 99, 1.0, 0.0, 0.0, 0], [100, -2, 0, 0, 0.0, 0.0, 0.0, 0]], vals, "clobber env start") map_channel($init_channel, 75, 25) 75.upto(99) do |i| vals[i] = 1.0 end check_edit_tree([[0, 15, 0, 24, 1.0, 0.0, 0.0, 0], [25, 13, 25, 49, 1.0, 0.0, 0.0, 0], [50, 14, 0, 0, 1.0, 0.0, 0.0, 0], [51, 13, 51, 74, 1.0, 0.0, 0.0, 0], [75, 16, 0, 24, 1.0, 0.0, 0.0, 0], [100, -2, 0, 0, 0.0, 0.0, 0.0, 0]], vals, "clobber env end") env_channel(make_env(:envelope, [0, 1, 1, 0, 2, 1], :length, 20), 50, 20) e = make_env(:envelope, [0, 1, 1, 0, 2, 1], :length, 20) 50.upto(69) do |i| vals[i] *= env(e) end check_edit_tree([[0, 15, 0, 24, 1.0, 0.0, 0.0, 0], [25, 13, 25, 49, 1.0, 0.0, 0.0, 0], [50, 14, 0, 0, 1.0, 1.0, -0.1, 4], [51, 13, 51, 59, 1.0, 0.8999, -0.1, 4], [60, 13, 60, 69, 1.0, 0.0, 0.1111, 4], [70, 13, 70, 74, 1.0, 0.0, 0.0, 0], [75, 16, 0, 24, 1.0, 0.0, 0.0, 0], [100, -2, 0, 0, 0.0, 0.0, 0.0, 0]], vals, "env on env") env_channel(make_env(:envelope, [0, 1, 1, 0, 2, 1], :length, 80), 10, 80) e = make_env(:envelope, [0, 1, 1, 0, 2, 1], :length, 80) 10.upto(89) do |i| vals[i] *= env(e) end check_edit_tree([[0, 15, 0, 9, 1.0, 0.0, 0.0, 0], [10, 15, 10, 24, 1.0, 1.0, -0.025, 4], [25, 13, 25, 49, 1.0, 0.625, -0.025, 4], [50, 14, 0, 0, 1.0, 1.0, -0.1, 6], [51, 13, 51, 59, 1.0, 0.8999, -0.1, 6], [60, 13, 60, 69, 1.0, 0.0, 0.1111, 6], [70, 13, 70, 74, 1.0, 0.5128, 0.025, 4], [75, 16, 0, 14, 1.0, 0.641, 0.026, 4], [90, 16, 15, 24, 1.0, 0.0, 0.0, 0], [100, -2, 0, 0, 0.0, 0.0, 0.0, 0]], vals, "env on env 2") env_channel(make_env(:envelope, [0, 1, 1, 0, 2, 1], :length, 20), 50, 20) e = make_env(:envelope, [0, 1, 1, 0, 2, 1], :length, 20) 50.upto(69) do |i| vals[i] *= env(e) end check_edit_tree([[0, 15, 0, 9, 1.0, 0.0, 0.0, 0], [10, 15, 10, 24, 1.0, 1.0, -0.025, 4], [25, 13, 25, 49, 1.0, 0.625, -0.025, 4], [50, 14, 0, 0, 1.0, 1.0, -0.1, 10], [51, 13, 51, 59, 1.0, 0.8999, -0.1, 10], [60, 13, 60, 69, 1.0, 0.0, 0.1111, 10], [70, 13, 70, 74, 1.0, 0.5128, 0.0256, 4], [75, 16, 0, 14, 1.0, 0.641, 0.0256, 4], [90, 16, 15, 24, 1.0, 0.0, 0.0, 0], [100, -2, 0, 0, 0.0, 0.0, 0.0, 0]], vals, "env on env 3") delete_samples(10, 20) insert_silence(10, 20) 10.upto(29) do |i| vals[i] = 0.0 end check_edit_tree([[0, 15, 0, 9, 1.0, 0.0, 0.0, 0], [10, -1, 0, 19, 0.0, 0.0, 0.0, 2], [30, 13, 30, 49, 1.0, 0.5, -0.025, 4], [50, 14, 0, 0, 1.0, 1.0, -0.1, 10], [51, 13, 51, 59, 1.0, 0.8999, -0.1, 10], [60, 13, 60, 69, 1.0, 0.0, 0.1111, 10], [70, 13, 70, 74, 1.0, 0.5128, 0.026, 4], [75, 16, 0, 14, 1.0, 0.641, 0.026, 4], [90, 16, 15, 24, 1.0, 0.0, 0.0, 0], [100, -2, 0, 0, 0.0, 0.0, 0.0, 0]], vals, "env preclobbered") close_sound(ind) # [10, 10000].each do |dur| i1 = new_sound vct2channel(Vct.new(dur, 1.0)) env_sound([0, 0, 1, 1]) check_env(:ramp, make_sampler(0), make_env([0, 0, 1, 1], :length, dur), dur) reverse_channel check_env(:rev_ramp, make_sampler(0), make_env([0, 1, 1, 0], :length, dur), dur) undo_edit(2) env_sound([0, 0, 1, 1, 2, 0]) check_env(:ramp, make_sampler(0), make_env([0, 0, 1, 1, 2, 0], :length, dur), dur) cur_read = make_sampler(0) reverse_channel check_env(:rev_pyr_1, cur_read, make_sampler(dur - 1, i1, 0, -1), dur) undo_edit(2) env_sound([0, 0, 1, 1, 2, 0, 3, 1]) check_env(:ramp_3, make_sampler(0), make_env([0, 0, 1, 1, 2, 0, 3, 1],:length, dur), dur) cur_read = make_sampler(0) reverse_channel check_env(:rev_pyr_2, cur_read, make_sampler(dur - 1, i1, 0, -1), dur) undo_edit(2) env_sound([0, 0, 1, 1, 2, 1, 3, 0]) check_env(:sqoff, make_sampler(0), make_env([0, 0, 1, 1, 2, 1, 3, 0], :length, dur), dur) undo_edit(1) env_sound([0, 0, 1, 0.5, 2, 0.5, 3, 0]) check_env(:sqoff_5, make_sampler(0), make_env([0, 0, 1, 0.5, 2, 0.5, 3, 0], :length, dur), dur) undo_edit(1) scale_channel(0.5) env_sound([0, 0, 1, 1]) check_env(:scl_ramp, make_sampler(0), make_env([0, 0, 1, 1], :length, dur, :scaler, 0.5), dur) reverse_channel check_env(:scl_rev_ramp, make_sampler(0), make_env([0, 1, 1, 0], :length, dur, :scaler, 0.5), dur) undo_edit(2) env_sound([0, 0, 1, 1, 2, 0]) check_env(:scl_ramp_3, make_sampler(0), make_env([0, 0, 1, 1, 2, 0], :length, dur, :scaler, 0.5), dur) cur_read = make_sampler(0) reverse_channel check_env(:scl_rev_pyr, cur_read, make_sampler(dur - 1, i1, 0, -1), dur) undo_edit(3) # if dur == 10000 [[ 0, 1000], [ 0, 6000], [1000, 1000], [1000, 4000], [4000, 2000], [5000, 1000], [6000, 1000], [5000, 5000]].each do |beg, local_dur| env_sound([0, 0, 1, 1, 2, 0]) scale_channel(0.5, beg, local_dur) e = make_env([0, 0, 1, 1, 2, 0], :length, dur) ctr = 0 check_env(:env_and_scl, make_sampler(0), lambda { val = env(e) ctr += 1 if ctr.between?(beg + 1, beg + local_dur) val * 0.5 else val end }, dur) undo_edit(2) end [[ 0, 1000, 500, 200], [ 0, 6000, 0, 10000], [1000, 1000, 0, 1500], [1000, 4000, 2000, 1000], [4000, 2000, 5000, 500], [5000, 1000, 4000, 2000], [6000, 1000, 0, 2000], [5000, 5000, 8000, 2000]].each do |env_beg, env_dur, scl_beg, scl_dur| env_channel([0, 0, 1, 1, 2, 1, 3, 0], env_beg, env_dur) scale_channel(0.5, scl_beg, scl_dur) e = make_env([0, 0, 1, 1, 2, 1, 3, 0], :length, env_dur) ctr = 0 check_env(:env_scl_partial, make_sampler(0), lambda { val = 1.0 ctr += 1 if ctr.between?(env_beg + 1, env_beg + env_dur) val *= env(e) end if ctr.between?(scl_beg + 1, scl_beg + scl_dur) val *= 0.5 end val }, dur) undo_edit(2) end end env_sound([0, 0, 1, 1]) env_sound([0, 0, 1, 1]) e = make_env([0, 0, 1, 1], :length, dur) check_env(:unenv_ramp, make_sampler(0), lambda { val = env(e) val * val }, dur) undo_edit(2) env_sound([0, 0, 1, 1]) vct2channel(Vct.new(3, 1.0), 3, 3) unless vequal(res = channel2vct(0, 10), vct(0, 1.111 / dur, 2.222 / dur, 1, 1, 1, 6.66 / dur, 7.77 / dur, 8.88 / dur, 10.0 / dur)) snd_display("1 vals: %s?", res) end undo_edit(2) env_sound([0, 0, 1, 1]) delete_samples(3, 3) insert_samples(3, 3, Vct.new(3, 1.0)) unless vequal(res = channel2vct(0, 10), vct(0, 1.111 / dur, 2.222 / dur, 1, 1, 1, 6.66 / dur, 7.77 / dur, 8.88 / dur, 10.0 / dur)) snd_display("2 vals: %s?", res) end undo_edit(3) env_sound([0, 0, 1, 1]) insert_samples(3, 3, Vct.new(3, 1.0)) delete_samples(3, 3) check_env(:ramp_5, make_sampler(0), make_env([0, 0, 1, 1], :length, dur), dur) undo_edit(3) env_sound([0, 0, 1, 1, 2, 0]) if dur == 10 vct2channel(Vct.new(3, 1.0), 3, 3) unless vequal(res = channel2vct(0, 10), vct(0, 0.2, 0.4, 1, 1, 1, 0.75, 0.5, 0.25, 0)) snd_display("4 vals (%s): %s?", dur, res) end else vct2channel(Vct.new(3, 0.0), 4998, 3) unless vequal(res = channel2vct(4995, 10), vct(0.999, 0.999, 1, 0, 0, 0, 1, 0.999, 0.999, 0.999)) snd_display("4 vals (%s): %s?", dur, res) end end undo_edit(2) if dur == 10 env_sound([0, 0, 1, 1, 2, 0]) delete_samples(3, 3) insert_samples(3, 3, Vct.new(3, 1.0)) unless vequal(res = channel2vct(0, 10), vct(0, 0.2, 0.4, 1, 1, 1, 0.75, 0.5, 0.25, 0)) snd_display("2 vals: %s?", res) end undo_edit(3) env_sound([0, 0, 1, 1, 2, 0]) vct2channel(Vct.new(3, 1.0), 0, 3) unless vequal(res = channel2vct(0, 10), vct(1, 1, 1, 0.6, 0.8, 1, 0.75, 0.5, 0.25, 0)) snd_display("4 vals: %s?", res) end undo_edit(2) env_sound([0, 0, 1, 1, 2, 0]) vct2channel(Vct.new(3, 1.0), 7, 3) unless vequal(res = channel2vct(0, 10), vct(0, 0.2, 0.4, 0.6, 0.8, 1, 0.75, 1, 1, 1)) snd_display("5 vals: %s?", res) end undo_edit(2) end file = file_name(i1) close_sound(i1) delete_file(file) end if $initial_graph_hook.empty? $update_hook.reset_hook! $close_hook.reset_hook! $exit_hook.reset_hook! require "env" end end def test_16_03 ind = new_sound("fmv.snd", 1, 22050, Mus_bfloat, Mus_next, "envd edit trees") vals = Vct.new(10000, 1.0) select_sound(ind) select_channel(0) check_edit_tree([[0, 0, 0, 0, 0.0, 0.0, 0.0, 1], [1, -2, 0, 0, 0.0, 0.0, 0.0, 0]], Vct.new(1), "initial new_sound") set_samples(0, 10000, vals) check_edit_tree([[0, 1, 0, 9999, 1.0, 0.0, 0.0, 0], [10000, -2, 0, 0, 0.0, 0.0, 0.0, 0]], vals, "envd set first samps to one") env_sound([0, 0, 1, 1]) e = make_env(:envelope, [0, 0, 1, 1], :length, 10000) vals.map! do |val| e.run end check_edit_tree([[0, 1, 0, 9999, 1.0, 0.0, 1.0e-4, 4], [10000, -2, 0, 0, 0.0, 0.0, 0.0, 0]], vals, "env frag [0, 0, 1, 1]") delete_samples(1000, 1000) v1 = Vct.new(9000) 1000.times do |i| v1[i] = vals[i] end 1000.upto(8999) do |i| v1[i] = vals[i + 1000] end check_edit_tree([[0, 1, 0, 999, 1.0, 0.0, 1.0e-4, 4], [1000, 1, 2000, 9999, 1.0, 0.2, 1.0e-4, 4], [9000, -2, 0, 0, 0.0, 0.0, 0.0, 0]], v1, "env frag del") undo_edit(1) delete_samples(9000, 1000) insert_samples(3000, 1000, Vct.new(1000)) 9999.downto(4000) do |i| vals[i] = vals[i - 1000] end 3000.upto(3999) do |i| vals[i] = 0.0 end check_edit_tree([[0, 1, 0, 2999, 1.0, 0.0, 1.0e-4, 4], [3000, 2, 0, 999, 1.0, 0.0, 0.0, 0], [4000, 1, 3000, 8999, 1.0, 0.3, 1.0e-4, 4], [10000, -2, 0, 0, 0.0, 0.0, 0.0, 0]], vals, "envd ins/del") delete_samples(0, 1000) insert_samples(0, 1000, Vct.new(1000)) 0.upto(999) do |i| vals[i] = 0.0 end check_edit_tree([[0, 3, 0, 999, 1.0, 0.0, 0.0, 0], [1000, 1, 1000, 2999, 1.0, 0.1, 1.0e-4, 4], [3000, 2, 0, 999, 1.0, 0.0, 0.0, 0], [4000, 1, 3000, 8999, 1.0, 0.3, 1.0e-4, 4], [10000, -2, 0, 0, 0.0, 0.0, 0.0, 0]], vals, "envd predel") scale_by(0.5) vals.scale!(0.5) check_edit_tree([[0, 3, 0, 999, 0.5, 0.0, 0.0, 0], [1000, 1, 1000, 2999, 0.5, 0.1, 1.0e-4, 4], [3000, 2, 0, 999, 0.5, 0.0, 0.0, 0], [4000, 1, 3000, 8999, 0.5, 0.3, 1.0e-4, 4], [10000, -2, 0, 0, 0.0, 0.0, 0.0, 0]], vals, "envd scl") reverse_channel j = 9999 5000.times do |i| vals[i], vals[j] = vals[j], vals[i] j -= 1 end check_edit_tree([[0, 4, 0, 9999, 1.0, 0.0, 0.0, 0], [10000, -2, 0, 0, 0.0, 0.0, 0.0, 0]], vals, "envd rev") revert_sound(ind) vals = Vct.new(100000, 1.0) vct2channel(vals, 0, 100000) env_channel(make_env(:envelope, [0, 0, 1, 1, 2, 0], :length, 10000), 30000, 10000) e = make_env(:envelope, [0, 0, 1, 1, 2, 0], :length, 10000) 30000.upto(39999) do |i| vals[i] = e.run end check_edit_tree([[0, 1, 0, 29999, 1.0, 0.0, 0.0, 0], [30000, 1, 30000, 34999, 1.0, 0.0, 1.9e-4, 4], [35000, 1, 35000, 39999, 1.0, 1.0, -2.0e-4, 4], [40000, 1, 40000, 99999, 1.0, 0.0, 0.0, 0], [100000, -2, 0, 0, 0.0, 0.0, 0.0, 0]], vals, "partial env") scale_channel(0.5, 10000, 10000) env_channel(make_env(:envelope, [0, 0, 1, 1, 2, 0], :length, 10000), 30000, 10000) e = make_env(:envelope, [0, 0, 1, 1, 2, 0], :length, 10000) 30000.upto(39999) do |i| vals[i] *= e.run end 10000.upto(19999) do |i| vals[i] *= 0.5 end check_edit_tree([[0, 1, 0, 9999, 1.0, 0.0, 0.0, 0], [10000, 1, 10000, 19999, 0.5, 0.0, 0.0, 0], [20000, 1, 20000, 29999, 1.0, 0.0, 0.0, 0], [30000, 1, 30000, 34999, 1.0, 0.0, 1.9e-4, 6], [35000, 1, 35000, 39999, 1.0, 1.0, -2.0e-4, 6], [40000, 1, 40000, 99999, 1.0, 0.0, 0.0, 0], [100000, -2, 0, 0, 0.0, 0.0, 0.0, 0]], vals, "env over env") env_channel(make_env(:envelope, [0, 0, 1, 1, 2, 0], :length, 10000), 5000, 10000) e = make_env(:envelope, [0, 0, 1, 1, 2, 0], :length, 10000) 5000.upto(14999) do |i| vals[i] *= e.run end check_edit_tree([[0, 1, 0, 4999, 1.0, 0.0, 0.0, 0], [5000, 1, 5000, 9999, 1.0, 0.0, 1.9e-4, 4], [10000, 1, 10000, 14999, 0.5, 1.0, -2.0e-4, 4], [15000, 1, 15000, 19999, 0.5, 0.0, 0.0, 0], [20000, 1, 20000, 29999, 1.0, 0.0, 0.0, 0], [30000, 1, 30000, 34999, 1.0, 0.0, 1.9e-4, 6], [35000, 1, 35000, 39999, 1.0, 1.0, -2.0e-4, 6], [40000, 1, 40000, 99999, 1.0, 0.0, 0.0, 0], [100000, -2, 0, 0, 0.0, 0.0, 0.0, 0]], vals, "env over scl") ramp_channel(0.5, -0.5, 25000, 1000) e = make_env(:envelope, [0, 0.5, 1, -0.5], :length, 1000) 25000.upto(25999) do |i| vals[i] *= e.run end check_edit_tree([[0, 1, 0, 4999, 1.0, 0.0, 0.0, 0], [5000, 1, 5000, 9999, 1.0, 0.0, 1.9e-4, 4], [10000, 1, 10000, 14999, 0.5, 1.0, -2.0e-4, 4], [15000, 1, 15000, 19999, 0.5, 0.0, 0.0, 0], [20000, 1, 20000, 24999, 1.0, 0.0, 0.0, 0], [25000, 1, 25000, 25999, 1.0, 0.5, -0.001, 4], [26000, 1, 26000, 29999, 1.0, 0.0, 0.0, 0], [30000, 1, 30000, 34999, 1.0, 0.0, 1.9e-4, 6], [35000, 1, 35000, 39999, 1.0, 1.0, -2.0e-4, 6], [40000, 1, 40000, 99999, 1.0, 0.0, 0.0, 0], [100000, -2, 0, 0, 0.0, 0.0, 0.0, 0]], vals, "ramp") scale_by(-1.0) vals.scale!(-1.0) check_edit_tree([[0, 1, 0, 4999, -1.0, 0.0, 0.0, 0], [5000, 1, 5000, 9999, -1.0, 0.0, 1.9e-4, 4], [10000, 1, 10000, 14999, -0.5, 1.0, -2.0e-4, 4], [15000, 1, 15000, 19999, -0.5, 0.0, 0.0, 0], [20000, 1, 20000, 24999, -1.0, 0.0, 0.0, 0], [25000, 1, 25000, 25999, -1.0, 0.5, -0.001, 4], [26000, 1, 26000, 29999, -1.0, 0.0, 0.0, 0], [30000, 1, 30000, 34999, -1.0, 0.0, 1.9e-4, 6], [35000, 1, 35000, 39999, -1.0, 1.0, -2.0e-4, 6], [40000, 1, 40000, 99999, -1.0, 0.0, 0.0, 0], [100000, -2, 0, 0, 0.0, 0.0, 0.0, 0]], vals, "invert") reader = make_sampler(0, ind, 0, 1, edit_position - 1) map_channel(lambda { |y| y + reader.call }) check_edit_tree([[0, 2, 0, 99999, 1.0, 0.0, 0.0, 0], [100000, -2, 0, 0, 0.0, 0.0, 0.0, 0]], Vct.new(100000), "invert and add") if fneq(maxamp, 0.0) snd_display("invert-and-add maxamp: %s?", maxamp) end undo_edit ramp_channel(-1.0, 1.0, 50000, 30000) e = make_env(:envelope, [0, -1, 1, 1], :length, 30000) 50000.upto(79999) do |i| vals[i] *= e.run end check_edit_tree([[0, 1, 0, 4999, -1.0, 0.0, 0.0, 0], [5000, 1, 5000, 9999, -1.0, 0.0, 1.9e-4, 4], [10000, 1, 10000, 14999, -0.5, 1.0, -2.0e-4, 4], [15000, 1, 15000, 19999, -0.5, 0.0, 0.0, 0], [20000, 1, 20000, 24999, -1.0, 0.0, 0.0, 0], [25000, 1, 25000, 25999, -1.0, 0.5, -0.001, 4], [26000, 1, 26000, 29999, -1.0, 0.0, 0.0, 0], [30000, 1, 30000, 34999, -1.0, 0.0, 1.9e-4, 6], [35000, 1, 35000, 39999, -1.0, 1.0, -2.0e-4, 6], [40000, 1, 40000, 49999, -1.0, 0.0, 0.0, 0], [50000, 1, 50000, 79999, -1.0, -1.0, 6.6e-5, 4], [80000, 1, 80000, 99999, -1.0, 0.0, 0.0, 0], [100000, -2, 0, 0, 0.0, 0.0, 0.0, 0]], vals, "ramp") env_sound([0, 0, 1, 1]) reverse_channel delete_samples(1, 99999) if fneq(sample(0), -1.0) snd_display("sample at end: %s?", sample(0)) end if framples != 1 snd_display("length at end: %s?", framples) end check_edit_tree([[0, 2, 0, 0, 1.0, 0.0, 0.0, 0], [1, -2, 0, 0, 0.0, 0.0, 0.0, 0]], Vct.new(1, -1.0), "at end") close_sound(ind) # ind = open_sound("oboe.snd") env_channel([0.0, 0.984011617147162, 0.644050741979388, 0.110976689002195, 1.17272046995914, 0.384709990674106, 1.25650287720397, 0.551452668245628, 1.4389507801877, 0.843827758574229, 2.16614272265275, 0.226832341237953]) if (not number?(val = sample(50827))) or fneq(val, 0.0) snd_display("round-off env: %s?", val) end check_edit_tree([[0, 0, 0, 15111, 1.0, 0.984, -5.77e-5, 4], [15112, 0, 15112, 27516, 1.0, 0.111, 2.2e-5, 4], [27517, 0, 27517, 29482, 1.0, 0.3848, 8.48e-5, 4], [29483, 0, 29483, 33763, 1.0, 0.5515, 6.83e-5, 4], [33764, 0, 33764, 50827, 1.0, 0.8438, -3.62e-5, 4], [50828, -2, 0, 0, 0.0, 0.0, 0.0, 0]], false, "round-off test") revert_sound(ind) map_channel($init_channel) env_channel([0, 0, 1, 1, 2, 0]) scale_channel(0.5, 1000, 1000) if fneq(val = sample(800), 0.0314) snd_display("scl on env trouble: %s?", val) end check_edit_tree([[0, 1, 0, 999, 1.0, 0.0, 3.93e-5, 4], [1000, 1, 1000, 1999, 0.5, 0.0393, 3.93e-5, 4], [2000, 1, 2000, 25413, 1.0, 0.0786, 3.93e-5, 4], [25414, 1, 25414, 50827, 1.0, 1.0, -3.93e-5, 4], [50828, -2, 0, 0, 0.0, 0.0, 0.0, 0]], false, "scl on env") revert_sound(ind) map_channel($init_channel) ramp_channel(0.0, 1.0) ramp_channel(0.0, 1.0) ramp_channel(0.0, 1.0) if fneq(val = sample(20000), (20000.0 / 50828) ** 3) snd_display("ramp_channels piled up: %s?", val) end check_edit_tree([[0, 1, 0, 50827, 1.0, 0.0, 1.9e-5, 10], [50828, -2, 0, 0, 0.0, 0.0, 0.0, 0]], false, "ramp upon ramp") revert_sound(ind) map_channel($init_channel) ramp_channel(0.5, 1.0) # val = 0.5 + (20000/50828)*0.5 ramp_channel(0.0, 0.5) # val * (20000/50828)*0.5 ramp_channel(0.1, 0.4) # val * (0.1 + (20000/50828)*0.3) val = sample(20000) ratio = 20000.0 / 50828 val1 = 0.5 + 0.5 * ratio val2 = val1 * 0.5 * ratio val3 = val2 * (0.1 + ratio * 0.3) if fneq(val, val3) snd_display("ramp-channels piled up (2): %s %s?", val, val3) end revert_sound(ind) env_channel([0, 0, 1, 1, 2, 0]) check_edit_tree([[0, 0, 0, 25413, 1.0, 0.0, 3.9e-5, 4], [25414, 0, 25414, 50827, 1.0, 1.0, -3.93e-5, 4], [50828, -2, 0, 0, 0.0, 0.0, 0.0, 0]], false, "env+scl 0") scale_channel(0.5, 0, 1000) check_edit_tree([[0, 0, 0, 999, 0.5, 0.0, 3.93e-5, 4], [1000, 0, 1000, 25413, 1.0, 0.0393, 3.93e-5, 4], [25414, 0, 25414, 50827, 1.0, 1.0, -3.93e-5, 4], [50828, -2, 0, 0, 0.0, 0.0, 0.0, 0]], false, "env+scl 1") undo_edit scale_channel(0.5, 1000, 1000) check_edit_tree([[0, 0, 0, 999, 1.0, 0.0, 3.93e-5, 4], [1000, 0, 1000, 1999, 0.5, 0.0393, 3.93e-5, 4], [2000, 0, 2000, 25413, 1.0, 0.0786, 3.93e-5, 4], [25414, 0, 25414, 50827, 1.0, 1.0, -3.93e-5, 4], [50828, -2, 0, 0, 0.0, 0.0, 0.0, 0]], false, "env+scl 2") undo_edit scale_channel(0.5, 0, 25415) check_edit_tree([[0, 0, 0, 25413, 0.5, 0.0, 3.93e-5, 4], [25414, 0, 25414, 25414, 0.5, 1.0, -3.93e-5, 4], [25415, 0, 25415, 50827, 1.0, 0.999, -3.93e-5, 4], [50828, -2, 0, 0, 0.0, 0.0, 0.0, 0]], false, "env+scl 3") undo_edit scale_channel(0.5, 20000, 10000) check_edit_tree([[0, 0, 0, 19999, 1.0, 0.0, 3.93e-5, 4], [20000, 0, 20000, 25413, 0.5, 0.7869, 3.93e-5, 4], [25414, 0, 25414, 29999, 0.5, 1.0, -3.93e-5, 4], [30000, 0, 30000, 50827, 1.0, 0.8195, -3.93e-5, 4], [50828, -2, 0, 0, 0.0, 0.0, 0.0, 0]], false, "env+scl 4") undo_edit scale_channel(0.5, 30000, 1000) check_edit_tree([[0, 0, 0, 25413, 1.0, 0.0, 3.93e-5, 4], [25414, 0, 25414, 29999, 1.0, 1.0, -3.93e-5, 4], [30000, 0, 30000, 30999, 0.5, 0.8195, -3.93e-5, 4], [31000, 0, 31000, 50827, 1.0, 0.7802, -3.93e-5, 4], [50828, -2, 0, 0, 0.0, 0.0, 0.0, 0]], false, "env+scl 5") undo_edit scale_channel(0.5, 25415, 1000) check_edit_tree([[0, 0, 0, 25413, 1.0, 0.0, 3.935e-5, 4], [25414, 0, 25414, 25414, 1.0, 1.0, -3.935e-5, 4], [25415, 0, 25415, 26414, 0.5, 0.9999, -3.935e-5, 4], [26415, 0, 26415, 50827, 1.0, 0.96, -3.93e-5, 4], [50828, -2, 0, 0, 0.0, 0.0, 0.0, 0]], false, "env+scl 6") undo_edit scale_channel(0.5, 40000, 10828) check_edit_tree([[0, 0, 0, 25413, 1.0, 0.0, 3.935e-5, 4], [25414, 0, 25414, 39999, 1.0, 1.0, -3.935e-5, 4], [40000, 0, 40000, 50827, 0.5, 0.426, -3.935e-5, 4], [50828, -2, 0, 0, 0.0, 0.0, 0.0, 0]], false, "env+scl 7") undo_edit close_sound(ind) end def check_envs(name, r_maker, e_maker, dur, i1, i2) check_env(format("%s-i1-0", name), r_maker.call(i1, 0), e_maker.call(i1, 0), dur) check_env(format("%s-i2-0", name), r_maker.call(i2, 0), e_maker.call(i2, 0), dur) check_env(format("%s-i2-1", name), r_maker.call(i2, 1), e_maker.call(i2, 1), dur) end def test_16_04 [10, 10000].each do |dur| i1 = new_sound i2 = new_sound("fmv1.snd", 2, 44100, Mus_bfloat, Mus_next) v = Vct.new(dur, 1.0) vct2channel(v, 0, dur, i1) vct2channel(v, 0, dur, i2, 0) vct2channel(v, 0, dur, i2, 1) set_sync(1, i1) set_sync(1, i2) env_sound([0, 0, 1, 1]) check_envs(:ramps, lambda do |s, c| make_sampler(0, s, c) end, lambda do |s, c| make_env(:envelope, [0, 0, 1, 1], :length, dur) end, dur, i1, i2) reverse_sound check_envs(:rev_ramps, lambda { |s, c| make_sampler(0, s, c) }, lambda { |s, c| make_env(:envelope, [0, 1, 1, 0], :length, dur) }, dur, i1, i2) undo_edit(2) env_sound([0, 0, 1, 1, 2, 0]) check_envs(:ramps_2, lambda { |s, c| make_sampler(0, s, c) }, lambda { |s, c| make_env(:envelope, [0, 0, 1, 1, 2, 0], :length, dur) }, dur, i1, i2) undo_edit(1) scale_by(0.5) env_sound([0, 0, 1, 1]) check_envs(:scl_ramps, lambda { |s, c| make_sampler(0, s, c) }, lambda { |s, c| make_env(:envelope, [0, 0, 1, 1], :length, dur, :scaler, 0.5) }, dur, i1, i2) reverse_sound check_envs(:scl_rev_ramps, lambda { |s, c| make_sampler(0, s, c) }, lambda { |s, c| make_env(:envelope, [0, 1, 1, 0], :length, dur, :scaler, 0.5) }, dur, i1, i2) undo_edit(3) env_sound([0, 0, 1, 1]) env_sound([0, 0, 1, 1]) check_envs(:unenv_ramps, lambda { |s, c| make_sampler(0, s, c) }, lambda { |s, c| e = make_env(:envelope, [0, 0, 1, 1], :length, dur) lambda { val = env(e) val * val } }, dur, i1, i2) undo_edit(2) env_sound([0, 0, 1, 1]) v1 = Vct.new(3, 1.0) vct2channel(v1, 3, 3, i1) vct2channel(v1, 3, 3, i2, 0) vct2channel(v1, 3, 3, i2, 1) unless vequal(res = channel2vct(0, 10, i1, 0), vct(0, 1.111 / dur, 2.222 / dur, 1, 1, 1, 6.66 / dur, 7.77 / dur, 8.88 / dur, 10.0 / dur)) snd_display("1 0 vals: %s?", res) end unless vequal(res = channel2vct(0, 10, i2, 0), vct(0, 1.111 / dur, 2.222 / dur, 1, 1, 1, 6.66 / dur, 7.77 / dur, 8.88 / dur, 10.0 / dur)) snd_display("2 0 vals: %s?", res) end unless vequal(res = channel2vct(0, 10, i2, 1), vct(0, 1.111 / dur, 2.222 / dur, 1, 1, 1, 6.66 / dur, 7.77 / dur, 8.88 / dur, 10.0 / dur)) snd_display("2 1 vals: %s?", res) end file = file_name(i1) close_sound(i1) delete_file(file) file = file_name(i2) close_sound(i2) delete_file(file) end # data = ["1a.snd", "oboe.snd", "storm.snd"].map do |sound| if File.exist?(sound) ind = view_sound(sound) set_squelch_update(true, ind) tms = [lambda { scale_channel(2.0) }, lambda { reverse_channel }, lambda { env_channel([0, 0, 1, 1]) }, lambda { map_channel(lambda { |y| y * 2 }) }, lambda { scan_channel(lambda { |y| y > 1.0 }) }, lambda { pad_channel(0, 2000) }, lambda { vct2channel(Vct.new(1000, 0.1), 0, 1000) }, lambda { clm_channel(make_two_zero(0.5, 0.5)) }, lambda { mix("pistol.snd", 12345) }, lambda { src_channel(2.0) }, lambda { delete_samples(10, 200) }].map do |func| with_time(&func).first end close_sound(ind) tms end end if $VERBOSE snd_info(" scl rev env map scn pad wrt clm mix src") str = "" data[0].each do |x| str << "%6.2f" % x end snd_info(" 1a: %s", str) str = "" data[1].each do |x| str << "%6.2f" % x end snd_info(" oboe: %s", str) str = "" data[2].each do |x| str << "%6.2f" % x end snd_info(" storm: %s", str) end # ind = new_sound("fmv.snd", :header_type, Mus_next, :sample_type, Mus_bfloat) set_sinc_width(10) pad_channel(0, 1000, ind) set_sample(100, 0.5) if fneq(res = sample(100, ind, 0, 2), 0.5) snd_display("sample(100 (2): %s?", res) end if fneq(res = sample(100, ind, 0, 1), 0.0) snd_display("sample(100 (1): %s?", res) end src_channel(0.5) if fneq(res = maxamp(ind, 0), 0.5) snd_display("src_channel max 0.5: %s?", res) end if fneq(res = sample(200), 0.5) snd_display("src_channel 0.5 200: %s?", res) end unless vequal(res = channel2vct(180, 40, ind, 0), vct(0.000, -0.000, 0.000, 0.001, -0.000, -0.003, 0.000, 0.007, -0.000, -0.012, 0.000, 0.020, -0.000, -0.033, 0.000, 0.054, -0.000, -0.100, -0.000, 0.316, 0.500, 0.316, -0.000, -0.100, -0.000, 0.054, 0.000, -0.033, -0.000, 0.020, 0.000, -0.012, -0.000, 0.007, 0.000, -0.003, -0.000, 0.001, 0.000, -0.000)) snd_display("src_channel 0.5: %s?", res) end undo_edit(1, ind, 0) src_channel(0.25) if fneq(res = maxamp(ind, 0), 0.5) snd_display("src_channel max 0.25: res %1.4f != req 0.500?", res) end if fneq(res = sample(400), 0.5) snd_display("src_channel 0.25 400: res %1.4f != req 0.500?", res) end unless vequal(res = channel2vct(360, 80, ind, 0), vct(0.000, -0.000, -0.000, -0.000, 0.000, 0.000, 0.001, 0.001, -0.000, -0.002, -0.003, -0.003, 0.000, 0.004, 0.007, 0.006, -0.000, -0.008, -0.012, -0.010, 0.000, 0.013, 0.020, 0.016, -0.000, -0.021, -0.033, -0.026, 0.000, 0.034, 0.054, 0.044, -0.000, -0.060, -0.100, -0.087, -0.000, 0.148, 0.316, 0.449, 0.500, 0.449, 0.316, 0.148, -0.000, -0.087, -0.100, -0.060, -0.000, 0.044, 0.054, 0.034, 0.000, -0.026, -0.033, -0.021, -0.000, 0.016, 0.020, 0.013, 0.000, -0.010, -0.012, -0.008, -0.000, 0.006, 0.007, 0.004, 0.000, -0.003, -0.003, -0.002, -0.000, 0.001, 0.001, 0.000, 0.000, -0.000, -0.000, -0.000)) snd_display("src_channel 0.25: %s?", res) end undo_edit(2, ind, 0) i = 0 pi_div_100 = PI / 100.0 map_channel_rb do |y| val = sin(i * pi_div_100) i += 1 val * 0.5 end [[2.00, 0.008], [1.50, 0.010], [3.00, 0.015], [3.14, 0.025]].each do |sr, df| src_channel(sr) if ((res = maxamp(ind, 0)) - 0.5).abs > df snd_display("src_channel sine %s: %s?", sr, res) end if integer?(sr) r0 = make_sampler(0) r1 = make_sampler(0, ind, 0, 1, edit_position - 1) 500.times do |i| diff = (r0.call - r1.call).abs if diff > df snd_display("src_channel %s diff %s: %s?", sr, i, diff) end 1.upto(sr - 1) do r1.call end end end 50.times do |i| s1 = sample(i, ind, 0, edit_position) s2 = sample((sr * i).round, ind, 0, edit_position - 1) s3 = sample(i, ind, 0, 1) if (s1 - s2).abs > df snd_display("sample %s src(%s): %s %s?", i, sr, s1, s2) end if fneq(s3, 0.0) snd_display("sample %s (1): %s?", i, s3) end end undo_edit(1, ind, 0) end close_sound(ind) # ind = open_sound("oboe.snd") orig_max = maxamp(ind, 0) [[2.00, 0.008], [1.50, 0.010], [3.00, 0.015], [3.14, 0.025]].each do |sr, df| src_channel(sr) if ((res = maxamp(ind, 0)) - orig_max).abs > df snd_display(snd_format_neq(res, orig_max, "src_channel oboe (1) sr %1.4f, df %1.4f", sr, df)) end undo_edit(1, ind, 0) end # [[0.50, 0.001], [0.25, 0.001], [0.90, 0.001], [0.10, 0.001]].each do |sr, df| src_channel(sr) if ((res = maxamp(ind, 0)) - orig_max).abs > df snd_display(snd_format_neq(res, orig_max, "src_channel oboe (2) sr %1.4f, df %1.4f", sr, df)) end 50.times do |i| samp = i * 100 s1 = sample(samp, ind, 0, edit_position) s2 = sample((sr * samp).floor, ind, 0, edit_position - 1) if (s1 - s2).abs > df snd_display(snd_format_neq(s1, s2, "sample %d oboe (2) sr %1.4f, df %1.4f", i, sr, df)) end end undo_edit(1, ind, 0) amp_envs_equal?(ind, 0, edit_position, edit_position + 1, 0.01) end # revert_sound(ind) scale_by(2.0) scale_by(0.5) amp_envs_equal?(ind, 0, edit_position, edit_position - 2, 0.001) revert_sound(ind) close_sound(ind) # ind = open_sound("oboe.snd") [[lambda { |beg, dur| env_channel([0, 0, 1, 1], beg, dur) }, 0, 1000, 50828], [lambda { |beg, dur| map_channel(lambda { |y| y * 0.5 }, beg, dur) }, 0, 1000, 50828], [lambda { |beg, dur| reverse_channel(beg, dur) }, 0, 1000, 50828], [lambda { |beg, dur| scale_channel(2.0, beg, dur) }, 0, 1000, 50828], [lambda { |beg, dur| vct2channel(Vct.new(dur), beg, dur) }, 0, 1000, 50828], [lambda { |beg, dur| smooth_channel(beg, dur) }, 0, 1000, 50828], [lambda { |beg, dur| pad_channel(beg, dur) }, 0, 1000, 51828], [lambda { |beg, dur| src_channel(0.5, beg, dur) }, 0, 1000, 52829], [lambda { |beg, dur| insert_silence(beg, dur) }, 0, 1000, 53829] ].each do |func, beg, dur, len| old_len = framples(ind) func.call(beg, dur) if (res = framples(ind)) != len snd_display("(%s %s %s) with %s: %s (%s)?", func, beg, dur, old_len, res, len) end end revert_sound(ind) [[ 1000, 1000, 51828], [60000, 1000, 61000], [ 0, 1000, 62000], [62000, 1, 62001], [62000, 2, 62003], [62004, 1, 62005]].each do |beg, dur, len| old_len = framples(ind) pad_channel(beg, dur) if (res = framples(ind)) != len snd_display("(pad_channel %s %s) with %s: %s (%s)?", beg, dur, old_len, res, len) end end revert_sound(ind) [[lambda { |beg, dur| env_channel([0, 0, 1, 1], beg, dur) }, 1000, 50828], [lambda { |beg, dur| reverse_channel(beg, dur) }, 1000, 50828], [lambda { |beg, dur| scale_channel(2.0, beg, dur) }, 1000, 50828], [lambda { |beg, dur| scale_sound_by(2.0, beg, dur) }, 1000, 50828], [lambda { |beg, dur| vct2channel(Vct.new(dur), beg, dur) }, 1000, 51928], [lambda { |beg, dur| smooth_channel(beg, dur) }, 1000, 51928], [lambda { |beg, dur| pad_channel(beg, dur) }, 1000, 53028], [lambda { |beg, dur| src_channel(0.5, beg, dur) }, 1000, 53028], [lambda { |beg, dur| insert_silence(beg, dur) }, 1000, 54028], [lambda { |beg, dur| env_sound([0, 0, 1, 1], beg, dur) }, 1000, 54028] ].each do |func, dur, len| old_len = framples(ind) func.call(old_len + 100, dur) if (res = framples(ind)) != len snd_display("(%s %s) with %s: %s (%s)?", func, dur, old_len, res, len) end end revert_sound(ind) len = (1.25 * framples()).floor 100.times do case random(10) when 0 pad_channel(random(len), random(1000)) when 1 env_channel([0, 0, 1, 1, 2, 0], random(len), random(1000)) when 2 env_sound([0, 0, 1, 1, 2, 0], random(len), random(1000)) when 3 scale_channel(random(1.0), random(len), random(1000)) when 4 scale_sound_by(random(1.0), random(len), random(1000)) when 5 src_channel(random(0.2) + 0.9, random(len), random(1000)) when 6 ramp_channel(random(1.0), random(1.0), random(len), random(1000)) when 7 reverse_channel(random(len), random(1000)) when 8 dur = [2, random(100)].max vct2channel(Vct.new(dur), random(len), dur) when 9 map_channel(lambda { |y| y * 2 }, random((0.5 * framples()).floor), random(1000)) end end close_sound(ind) end def test_16_05 ind0 = open_sound("oboe.snd") ind1 = open_sound("2.snd") ind2 = open_sound("4.aiff") set_squelch_update(true, ind0, true) set_squelch_update(true, ind1, true) set_squelch_update(true, ind2, true) Snd.catch(:mus_error, lambda do |*args| snd_display("caught error: %s", args) end) do 500.times do set_sync(random(3), ind0) set_sync(random(3), ind1) set_sync(random(3), ind2) opt_test(random(22)) end end set_squelch_update(false, ind0, true) set_squelch_update(false, ind1, true) set_squelch_update(false, ind2, true) close_sound(ind0) close_sound(ind1) close_sound(ind2) # ind = init_sound(0.5, 10, 2) save_sound(ind) scale_channel(2.0, 0, framples, ind, 1) swap_channels check_both_chans(ind, "1", lambda { |y| fneq(y, 1.0) }, lambda { |y| fneq(y, 0.5) }) undo_edit(1, ind, 0) undo_edit(2, ind, 1) scale_channel(0.5, 0, framples, ind, 0) scale_channel(2.0, 0, framples, ind, 1) swap_channels check_both_chans(ind, "2", lambda { |y| fneq(y, 1.0) }, lambda { |y| fneq(y, 0.25) }) undo_edit(2, ind, 0) undo_edit(2, ind, 1) delete_samples(2, 3, ind, 0) env_channel([0, 0, 1, 1, 2, 0], 0, framples(ind, 1), ind, 1) swap_channels undo_edit(2, ind, 0) undo_edit(2, ind, 1) delete_samples(2, 7, ind, 0) swap_channels(ind, 0, ind, 1, 5, 4) revert_sound(ind) m0 = add_mark(3, ind, 0) m1 = add_mark(4, ind, 1) m2 = add_mark(5, ind, 1) scale_channel(0.5) swap_channels if (res = mark_sample(m0)) != 3 snd_display("swapped m0: %s?", res) end if (res = mark_sample(m1)) != 4 snd_display("swapped m1: %s?", res) end if (res = mark_sample(m2)) != 5 snd_display("swapped m2: %s?", res) end if (res = mark_home(m0)) != [ind, 1] snd_display("mark_home m0: %s?", res) end if (res = mark_home(m1)) != [ind, 0] snd_display("mark_home m1: %s?", res) end if (res = mark_home(m2)) != [ind, 0] snd_display("mark_home m2: %s?", res) end undo_edit(1, ind, 0) undo_edit(1, ind, 1) if (res = mark_sample(m0)) != 3 snd_display("swapped m0 (2): %s?", res) end if (res = mark_sample(m1)) != 4 snd_display("swapped m1 (2): %s?", res) end if (res = mark_sample(m2)) != 5 snd_display("swapped m2 (2): %s?", res) end if (res = mark_home(m0)) != [ind, 0] snd_display("mark_home m0 (2): %s?", res) end if (res = mark_home(m1)) != [ind, 1] snd_display("mark_home m1 (2): %s?", res) end if (res = mark_home(m2)) != [ind, 1] snd_display("mark_home m2 (2): %s?", res) end close_sound(ind) delete_file("test.snd") # ind = init_sound(0.5, 10, 4) scale_channel(0.5, 0, framples, ind, 1) scale_channel(0.25, 0, framples, ind, 2) scale_channel(0.125, 0, framples, ind, 3) swap_channels(ind, 1, ind, 2) maxs = maxamp(ind, true) if fneq(maxs[0], 0.5) or fneq(maxs[1], 0.125) or fneq(maxs[2], 0.25) or fneq(maxs[3], 0.0625) snd_display("swap midchans: %s?", maxs) end close_sound(ind) # ind0 = open_sound("oboe.snd") ind1 = open_sound("pistol.snd") mx0 = maxamp(ind0, 0) mx1 = maxamp(ind1, 0) swap_channels(ind0, 0, ind1, 0) if fneq(res = maxamp(ind0, 0), mx1) snd_display("maxamp cross swap 0: %s?", res) end if fneq(res = maxamp(ind1, 0), mx0) snd_display("maxamp cross swap 1: %s?", res) end close_sound(ind0) close_sound(ind1) # ind = init_sound(1.0, 10, 1) # # ramp+ramp # ramp_channel(0.0, 1.0) check_back_and_forth(ind, "ramp 1", vct(0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1)) ramp_channel(0.0, 1.0) check_back_and_forth(ind, "ramp 2", vct(0, 0.01, 0.04, 0.09, 0.16, 0.25, 0.36, 0.49, 0.64, 0.81, 1)) undo_edit ramp_channel(1.0, 0.0) check_back_and_forth(ind, "ramp 3", vct(0, 0.09, 0.16, 0.21, 0.24, 0.25, 0.24, 0.21, 0.16, 0.09, 0)) undo_edit env_channel([0, 0, 1, 1, 2, 0]) check_back_and_forth(ind, "ramp 4", vct(0, 0.020, 0.080, 0.180, 0.320, 0.500, 0.480, 0.420, 0.320, 0.180, 0)) undo_edit(2) env_channel([0, 0, 1, 1, 2, 0]) check_back_and_forth(ind, "ramp 5", vct(0, 0.200, 0.400, 0.600, 0.800, 1.000, 0.800, 0.600, 0.400, 0.200, 0)) ramp_channel(0.0, 1.0) check_back_and_forth(ind, "ramp 6", vct(0, 0.020, 0.080, 0.180, 0.320, 0.500, 0.480, 0.420, 0.320, 0.180, 0)) scale_channel(0.5) check_back_and_forth(ind, "ramp 7", vct(0, 0.010, 0.040, 0.090, 0.160, 0.250, 0.240, 0.210, 0.160, 0.090, 0)) undo_edit(3) scale_channel(0.5) env_channel([0, 0, 1, 1, 2, 0]) check_back_and_forth(ind, "ramp 8", vct(0, 0.100, 0.200, 0.300, 0.400, 0.500, 0.400, 0.300, 0.200, 0.100, 0)) ramp_channel(0.0, 1.0) check_back_and_forth(ind, "ramp 9", vct(0, 0.010, 0.040, 0.090, 0.160, 0.250, 0.240, 0.210, 0.160, 0.090, 0)) undo_edit(3) ramp_channel(0.0, 1.0) ramp_channel(0.0, 1.0) ramp_channel(0.0, 1.0) check_back_and_forth(ind, "ramp 10", vct(0, 0.001, 0.008, 0.027, 0.064, 0.125, 0.216, 0.343, 0.512, 0.729, 1)) undo_edit(3) # # ramp+scl (checking split loc) # ramp_channel(0.0, 1.0, 0, 5) scale_channel(0.5, 3, 3) check_back_and_forth(ind, "ramp+scl 1", vct(0, 0.250, 0.500, 0.375, 0.500, 0.500, 1, 1, 1, 1, 1)) undo_edit(2) ramp_channel(1.0, 0.0, 5, 5) scale_channel(0.5, 4, 3) check_back_and_forth(ind, "ramp+scl 2", vct(1, 1, 1, 1, 0.500, 0.500, 0.375, 0.500, 0.250, 0, 1)) undo_edit(2) close_sound(ind) # if $all_args [[:scale_channel, lambda do |snd, i| scale_channel(i * 0.01) end], [:set_sample, lambda do |snd, i| set_sample(i, 0.5) end], [:env_channel, lambda do |snd, i| env_channel([0, 0, 1, 1]) end], [:env_channel_with_base, lambda do |snd, i| env_channel_with_base([0, 0, 1, 1], 32.0) end], [:env_channel_with_base, lambda do |snd, i| env_channel_with_base([0, 0, 1, 1], 0.0) end], [:delete_sample, lambda do |snd, i| delete_sample(i * 10) end], [:insert_sample, lambda do |snd, i| insert_sample(i * 10, 0.5) end], [:pad_channel, lambda do |snd, i| pad_channel(i * 10, i * 10) end], [:mix_no_tag, lambda do |snd, i| mix("pistol.snd", 10 * i, 0, snd, 0, false) end], [:mix_tag, lambda do |snd, i| mix("pistol.snd", 10 * i, 0, snd, 0, true) end], [:mix_scale_to, lambda do |snd, i| set_mix_amp(mix("pistol.snd", 100 * i).car, 0.01) end], [:mix_amp, lambda do |snd, i| mix("pistol.snd", 100 * i); scale_to(0.5) end], [:src_sound_1, lambda do |snd, i| src_sound(2.0); undo_edit end], [:src_sound_2, lambda do |snd, i| src_sound(2.01); undo_edit end], [:filter_channel_1, lambda do |snd, i| filter_channel(vct(0.25, 0.5, 0.25, 0.1), 4) end], [:filter_channel_2, lambda do |snd, i| filter_channel(vct(0.25, 0.5, 0.5, 0.25), 4) end], [:filter_channel_3, lambda do |snd, i| filter_channel(vct(0.1, 0.2, 0.1, 0.1, 0.1, 0.1, 0.1, 0.2, 0.1, 0.1), 10) end], [:filter_channel_4, lambda do |snd, i| filter_channel(vct(0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1), 10) end], [:clm_channel, lambda do |snd, i| clm_channel(make_two_zero(0.5, 0.5)) end], [:reverse_channel, lambda do |snd, i| reverse_channel(i * 10, i * 100) end]].each do |name, func| ["1.snd", "oboe.snd", "1a.snd"].each do |sound| ind = open_sound(sound) with_time do set_squelch_update(true, ind, 0) with_time(format("%s() [%s]", name, sound)) do 256.times do |i| revert_sound(ind) if (i % 10).zero? func.call(ind, i) end end revert_sound(ind) set_squelch_update(false, ind, 0) close_sound(ind) end end end end end def test_16 test_16_00 test_16_01 if $with_test_gui # load("hiho.rb") -> set_transform_size(0) test_16_02 test_16_03 test_16_04 test_16_05 end # ---------------- test 17: dialogs and graphics ---------------- add_help(:arrow2right, "arrow2right(x, y, size, snd, chn, cr) \ draw an arrow pointing (from the left) at the point [x, y]") def arrow2right(x, y, size, snd, chn, cr) size2 = size * 2 fill_polygon([x, y, x - size2, y - size, x - size2, y + size, x, y], snd, chn, Time_graph, cr) fill_rectangle(x - 4 * size, (y - 0.4 * size).floor, size2, (0.8 * size).floor, snd, chn, Time_graph, false, cr) end def test_17 if $with_test_gui $after_graph_hook.add_hook!(get_func_name, &method(:display_previous_edits).to_proc) $lisp_graph_hook.add_hook!(get_func_name) do |snd, chn| lambda do | | cr = make_cairo(channel_widgets(snd, chn)[0]) draw_string("hi", x2position(0.5, snd, chn, Lisp_graph), y2position(0.5, snd, chn, Lisp_graph), snd, chn, Lisp_graph, cr) free_cairo(cr) end end ind = open_sound("oboe.snd") wids = channel_widgets wids1 = channel_widgets(selected_sound) wids2 = channel_widgets(selected_sound, selected_channel) 1.upto(3) do |i| scale_by(0.5) set_x_bounds([0, i * 0.3]) end revert_sound(ind) draw_bass_clef(100, 100, 100, 0, ind, 0) update_time_graph(ind, 0) draw_fermata(200, 100, 60, 0, ind, 0) cr = make_cairo(channel_widgets(ind, 0)[0]) draw_line(100, 100, 200, 200, ind, 0, Time_graph, cr) draw_dot(300, 300, 10, ind, 0, Time_graph, cr) draw_string("hiho", 20, 20, ind, 0, Time_graph, cr) draw_dots([25, 25, 50, 50, 100, 100], 10, ind, 0, Time_graph, cr) arrow2right(100, 50, 10, ind, 0, cr) fill_rectangle(20, 20, 100, 100, ind, 0, Time_graph, false, cr) free_cairo(cr) make_bezier(0, 0, 20, 20, 40, 30, 60, 10, 10) update_time_graph(ind, 0) $after_graph_hook.reset_hook! $lisp_graph_hook.reset_hook! # ind = open_sound("oboe.snd") set_time_graph?(false, ind, 0) graph([vct(0, 1, 2), vct(3, 2, 1), vct(1, 2, 3), vct(1, 1, 1), vct(0, 1, 0), vct(3, 1, 2)]) update_lisp_graph $lisp_graph_hook.add_hook!("snd-test") do |snd, chn| [basic_color, zoom_color, data_color, selected_data_color, mix_color] end graph([vct(0, 1, 2), vct(3, 2, 1), vct(1, 2, 3), vct(1, 1, 1), vct(0, 1, 0), vct(3, 1, 2)]) update_lisp_graph $lisp_graph_hook.reset_hook! close_sound(ind) # ind1 = open_sound("2.snd") wids3 = channel_widgets(ind1, 0) wids4 = channel_widgets(ind1, 1) if (not list_p(wids)) or (not list_p(wids3)) or ($with_test_motif and (wids1.length != 11 or wids2.length != 11)) snd_display("channel_widgets confused: %s %s %s %s %s?", wids, wids1, wids2, wids3, wids4) end hide_widget(channel_widgets.first) show_widget(channel_widgets.first) close_sound(true) end end # ---------------- test 18: enved ---------------- def test_18 if $with_test_gui start_enveloping ind = open_sound("oboe.snd") if (res = channel_envelope(ind, 0)) != [0.0, 1.0, 1.0, 1.0] snd_display("channel_envelope: %s?", res) end set_channel_envelope([0, 0, 1, 1, 2, 0], ind, 0) if (res = channel_envelope(ind, 0)) != [0, 0, 1, 1, 2, 0] snd_display("set_channel_envelope: %s?", res) end close_sound(ind) stop_enveloping end end # ---------------- test 19: save and restore ---------------- def local_neq?(a, b) if float?(a) or float?(b) fneq(a, b) else a != b end end def insert_vct(v, beg = 0, dur = false, snd = false, chn = false) insert_samples(beg, dur, v, snd, chn, false, false, format("%s(%s, %s, %s", get_func_name, v.to_str, beg, dur)) end def clm_channel_test(snd = false, chn = false) clm_channel(make_two_zero(1, -1), 0, false, snd, chn, false, false, "clm_channel_test(") end def make_v_mix(snd = false, chn = false) mix_vct([0.1, 0.2, 0.3].to_vct, 100, snd, chn, true, "mix_vct(vct(0.1, 0.2, 0.3)") end def test_19_00 nind = open_sound("oboe.snd") add_mark(123) delete_sample(12) set_x_bounds([0.2, 0.4]) old_bounds = x_bounds set_show_axes(Show_all_axes) set_transform_graph_type(Graph_as_sonogram) set_speed_control_style(Speed_control_as_ratio) set_channel_style(Channels_superimposed) set_enved_target(Enved_srate) set_sound_property(:hi, "hi", nind) set_sound_property("ho", 1234, nind) set_channel_property(:ha, 3.14, nind, 0) $before_save_state_hook.reset_hook! $before_save_state_hook.add_hook!("snd-test") do |fname| File.open(File.expand_path(fname), "w") do |f| f.printf("# this comment will be at the top of the saved state file.\n") end true end delete_file(save_state_file) save_state(save_state_file) # save_options("test.temp") close_sound(nind) Snd.regions.apply(:forget_region) load(save_state_file) ind = find_sound("oboe.snd") if fneq_err(old_bounds[0], x_bounds(ind, 0)[0], 0.05) or fneq_err(old_bounds[1], x_bounds(ind, 0)[1], 0.05) snd_display("save bounds: %s?", x_bounds(ind, 0)) end if marks(ind, 0).length != 1 snd_display("save marks: %s?", marks(ind, 0)) end if (res = mark_sample(marks(ind, 0)[0])) != 122 snd_display("save mark: %s?", res) end if (res = edit_position(ind, 0)) != 1 snd_display("save edit_position: %s?", res) end if (res = edit_fragment(1, ind, 0)) != ["delete_samples(12, 1", "delete", 12, 1] snd_display("save edits: %s?", res) end if (res = edit_tree(ind, 0)) != [[0, 0, 0, 11, 1.0, 0.0, 0.0, 0], [12, 0, 13, 50827, 1.0, 0.0, 0.0, 0], [50827, -2, 0, 0, 0.0, 0.0, 0.0, 0]] snd_display("save edit_tree: %s?", res) end if (res = sound_property("ho", ind)) != 1234 snd_display("sound_property saved: 1234 -> %s?", res.inspect) end if (res = sound_property(:hi, ind)) != "hi" snd_display("sound_property saved: hi -> %s?", res.inspect) end if (res = channel_property(:ha, ind, 0)) != 3.14 snd_display("channel_property saved: 3.14 -> %s?", res.inspect) end close_sound(ind) $before_save_state_hook.reset_hook! $after_save_state_hook.reset_hook! if (res = Snd.catch(:cannot_save, 12345) do save_state("/bad/bad.save") end).first != 12345 snd_display("save_state err: %s", res.inspect) end if (res = Snd.catch(:cannot_save, 12345) do save_listener("/bad/bad.save") end).first != 12345 snd_display("save_listener err: %s", res.inspect) end # nind = open_sound("oboe.snd") set_sample(1, 0.5) delete_sample(100) insert_sample(10, 0.5) scale_channel(2.0) insert_silence(100, 20) save_edit_history("hiho.rb") revert_sound(nind) sfile = nind eval(File.open("hiho.rb").read) if (res = edit_fragment(1)) != ["set_sample(1, 0.5000", "set", 1, 1] snd_display("save_edit_history 1: %s?", res) end if (res = edit_fragment(2)) != ["delete_samples(100, 1", "delete", 100, 1] snd_display("save_edit_history 2: %s?", res) end if (res = edit_fragment(3)) != ["insert_sample(10, 0.5000", "insert", 10, 1] snd_display("save_edit_history 3: %s?", res) end if (res = edit_fragment(4)) != ["scale_channel(2.000, 0, false", "scale", 0, 50828] snd_display("save_edit_history 4: %s?", res) end if (res = edit_fragment(5)) != ["pad-channel", "zero", 100, 20] snd_display("save_edit_history 5: %s?", res) end save_edit_history("hiho.rb", nind, 0) scale_sound_to(1.0, 0, framples(nind, 0), nind, 0) eds = edit_position(nind, 0) val = insert_sound("zero.snd") if val.nonzero? or eds != edit_position(nind, 0) snd_display("insert_sound zero.snd, was an edit? %s %s %s", val, eds, edit_position(nind, 0)) end revert_sound(nind) scale_sound_to(0.5, 0, framples(nind, 0), nind, 0) if fneq(res = maxamp(nind, 0), 0.5) snd_display("scale_sound_to(0.5): %s?", res) end close_sound(nind) # nind = open_sound("oboe.snd") ramp_channel(0.0, 1.0) xramp_channel(0.0, 1.0, 32.0) save_edit_history("hiho.rb") revert_sound(nind) sfile = nind eval(File.open("hiho.rb").read) if (res = edit_fragment(1)) != ["ramp_channel(0.000, 1.000, 0, false", "env", 0, 50828] snd_display("save_edit_history ramp 1: %s?", res) end if (res = edit_fragment(2)) != ["xramp_channel(0.000, 1.000, 32.000, 0, false", "env", 0, 50828] snd_display("save_edit_history xramp 2: %s?", res) end revert_sound(nind) if (res = IO.readlines("hiho.rb")) != [" ramp_channel(0.000, 1.000, 0, false, sfile, 0, false)\n", " xramp_channel(0.000, 1.000, 32.000, 0, false, sfile, 0, false)\n"] snd_display("IO.readlines (file2string): %s?", res) end close_sound(nind) # add_sound_file_extension("ogg") add_sound_file_extension("OGG") add_sound_file_extension("sf") add_sound_file_extension("SF2") add_sound_file_extension("mp3") add_sound_file_extension("MP3") add_sound_file_extension("W01") add_sound_file_extension("W02") add_sound_file_extension("W03") add_sound_file_extension("W04") add_sound_file_extension("W05") add_sound_file_extension("W06") add_sound_file_extension("W07") add_sound_file_extension("W08") add_sound_file_extension("W09") add_sound_file_extension("W10") add_sound_file_extension("w01") add_sound_file_extension("w02") add_sound_file_extension("w03") add_sound_file_extension("w04") add_sound_file_extension("w05") add_source_file_extension("gad") # ind = new_sound("fmv.snd") set_sample(10, 0.1) save_sound(ind) set_sample(1, 0.1) eds = safe_display_edits(ind) delete_file("t1.rb") save_state("t1.rb") close_sound(ind) # If savehook.snd doesn't exist, an IO-error will be raised. Snd.regions.each do |r| Snd.catch(:io_error) do forget_region(r) end end load("t1.rb") ind = find_sound("fmv.snd") unless sound?(ind) snd_display("save_state restored but no sound?") end 3.upto(5) do |i| set_sample(i, i * 0.1) eds = safe_display_edits(ind) delete_file("t1.rb") save_state("t1.rb") close_sound(ind) Snd.regions.apply(:forget_region) load("t1.rb") ind = find_sound("fmv.snd") unless sound?(ind) snd_display("save_state %s restored but no sound?", i) end end close_sound(ind) delete_file("t1.rb") # ind = new_sound("fmv.snd", 8, 22050, Mus_bshort, Mus_next, "this is an 8-channel save-state test") ind1 = new_sound("fmv1.snd", 2, 22050, Mus_bshort, Mus_next, "this is an 2-channel save-state test") set_sample(10, 0.1, ind, 0) set_sample(10, 0.2, ind, 1) set_sample(10, 0.3, ind, 2) set_sample(10, 0.4, ind, 3) set_sample(10, -0.1, ind1, 0) set_sample(10, -0.2, ind1, 1) save_sound(ind) save_sound(ind1) set_sample(1, 0.1, ind, 0) set_sample(1, 0.2, ind, 1) set_sample(1, 0.3, ind, 2) set_sample(1, 0.4, ind, 3) set_sample(1, -0.1, ind1, 0) set_sample(1, -0.2, ind1, 1) eds = safe_display_edits(ind) eds1 = safe_display_edits(ind1) delete_file("t1.rb") save_state("t1.rb") close_sound(ind) close_sound(ind1) Snd.regions.apply(:forget_region) load("t1.rb") ind = find_sound("fmv.snd") ind1 = find_sound("fmv1.snd") if (not sound?(ind)) or (not sound?(ind1)) snd_display("save_state (2) restored but no sound? %s %s", ind, ind1) end close_sound(ind) close_sound(ind1) delete_file("t1.rb") # ind = open_sound("oboe.snd") old_save_dir = save_dir old_eps_file = eps_file set_save_dir(false) set_samples(100, 32, Vct.new(32, 1.0)) map_channel(lambda do |y| y + 0.1 end, 1000, 10000) set_show_axes(Show_no_axes, ind, 0) set_zoom_focus_style(Zoom_focus_middle) set_transform_normalization(Dont_normalize, ind, 0) set_graph_style(Graph_filled, ind, 0) set_transform_graph_type(Graph_as_spectrogram, ind, 0) set_time_graph_type(Graph_as_wavogram, ind, 0) set_x_axis_style(X_axis_as_percentage, ind, 0) set_speed_control_style(Speed_control_as_semitone, ind, 0) set_cursor(1234, ind, 0) set_eps_file("hiho.eps") set_amp_control_bounds([0.0, 2.5], ind) set_speed_control_bounds([1.0, 2.5], ind) set_reverb_control_scale_bounds([0.0, 2.5], ind) set_reverb_control_length_bounds([0.0, 2.5], ind) set_contrast_control_bounds([0.0, 2.5], ind) set_x_axis_label("time-x", ind, 0, Time_graph) set_y_axis_label("amp-y", ind, 0, Time_graph) old_srate = mus_srate old_file_buffer_size = mus_file_buffer_size old_array_print_length = mus_array_print_length old_clm_table_size = clm_table_size set_mus_srate(48000) set_mus_array_print_length(24) set_mus_file_buffer_size(4096) set_clm_table_size(256) delete_file("s61.rb") save_state("s61.rb") close_sound(ind) Snd.regions.apply(:forget_region) load("s61.rb") if fneq(res = mus_srate, 48000.0) snd_display("save/restore mus_srate: %s", res) end if (res = mus_file_buffer_size) != 4096 snd_display("save/restore mus_file_buffer_size: %s", res) end if (res = mus_array_print_length) != 24 snd_display("save/restore mus_array_print_length: %s", res) end if (res = clm_table_size) != 256 snd_display("save/restore clm_table_size: %s", res) end set_mus_srate(old_srate) set_mus_array_print_length(old_array_print_length) set_mus_file_buffer_size(old_file_buffer_size) set_clm_table_size(old_clm_table_size) set_save_dir(old_save_dir) ind = find_sound("oboe.snd") if (res = show_axes(ind, 0)) != Show_no_axes snd_display("save Show_no_axes: %s?", res.inspect) end if (res = zoom_focus_style) != Zoom_focus_middle snd_display("save Zoom_focus_middle: %s?", res.inspect) end if (res = transform_normalization(ind, 0)) != Dont_normalize snd_display("save Dont_normalize: %s?", res.inspect) end if (res = graph_style(ind, 0)) != Graph_filled snd_display("save Graph_filled: %s?", res.inspect) end if (res = transform_graph_type(ind, 0)) != Graph_as_spectrogram snd_display("save Graph_as_spectrogram: %s?", res.inspect) end if (res = time_graph_type(ind, 0)) != Graph_as_wavogram snd_display("save Graph_as_wavogram: %s?", res.inspect) end if (res = x_axis_style(ind, 0)) != X_axis_as_percentage snd_display("save X_axis_as_percentage: %s?", res.inspect) end if (res = speed_control_style(ind)) != Speed_control_as_semitone snd_display("save Speed_control_as_semitone: %s?", res.inspect) end if (res = cursor(ind, 0)) != 1234 snd_display("save cursor 1234: %s?", res.inspect) end if (res = eps_file) != "hiho.eps" snd_display("save eps_file: %s?", res.inspect) end if defined? set_x_axis_label if (res = x_axis_label(ind, 0, Time_graph)) != "time-x" snd_display("save x_axis_label: %s?", res.inspect) end if (res = y_axis_label(ind, 0, Time_graph)) != "amp-y" snd_display("save y_axis_label: %s?", res.inspect) end end if amp_control_bounds(ind) != [0.0, 2.5] snd_display("save amp_control_bounds: %s?", res.inspect) end if speed_control_bounds(ind) != [1.0, 2.5] snd_display("save speed_control_bounds: %s?", res.inspect) end if contrast_control_bounds(ind) != [0.0, 2.5] snd_display("save contrast_control_bounds: %s?", res.inspect) end if reverb_control_scale_bounds(ind) != [0.0, 2.5] snd_display("save reverb_control_scale_bounds: %s?", res.inspect) end if reverb_control_length_bounds(ind) != [0.0, 2.5] snd_display("save reverb_control_length_bounds: %s?", res.inspect) end set_eps_file(old_eps_file) delete_file("s61.rb") close_sound(ind) # ind = open_sound("oboe.snd") old_tiny_font = tiny_font old_peaks_font = peaks_font old_bold_peaks_font = bold_peaks_font old_amp = amp_control_bounds old_speed = speed_control_bounds old_contrast = contrast_control_bounds old_revlen = reverb_control_length_bounds old_revscl = reverb_control_scale_bounds set_tiny_font("8x13") set_peaks_font("8x13") set_bold_peaks_font("8x13") set_amp_control_bounds([0.0, 2.5]) set_speed_control_bounds([1.0, 2.5]) set_reverb_control_scale_bounds([0.0, 2.5]) set_reverb_control_length_bounds([0.0, 2.5]) set_contrast_control_bounds([0.0, 2.5]) save_state("s61.rb") close_sound(ind) Snd.regions.apply(:forget_region) load("s61.rb") ind = find_sound("oboe.snd") if (res = tiny_font) != "8x13" snd_display("save tiny_font: %s?", res) end if (res = peaks_font) != "8x13" snd_display("save peaks_font: %s?", res) end if (res = bold_peaks_font) != "8x13" snd_display("save bold_peaks_font: %s?", res) end if amp_control_bounds() != [0.0, 2.5] snd_display("save amp_control_bounds: %s?", res) end if speed_control_bounds() != [1.0, 2.5] snd_display("save speed_control_bounds: %s?", res) end if contrast_control_bounds() != [0.0, 2.5] snd_display("save contrast_control_bounds: %s?", res) end if reverb_control_scale_bounds() != [0.0, 2.5] snd_display("save reverb_control_scale_bounds: %s?", res) end if reverb_control_length_bounds() != [0.0, 2.5] snd_display("save reverb_control_length_bounds: %s?", res) end set_tiny_font(old_tiny_font) set_peaks_font(old_peaks_font) set_bold_peaks_font(old_bold_peaks_font) set_amp_control_bounds(old_amp) set_speed_control_bounds(old_speed) set_contrast_control_bounds(old_contrast) set_reverb_control_length_bounds(old_revlen) set_reverb_control_scale_bounds(old_revscl) delete_file("s61.rb") close_sound(ind) end def test_19_01 # new_globals new_locals funcs = [[:transform_graph_type, Graph_as_sonogram, Graph_once], [:time_graph_type, Graph_as_wavogram, Graph_once], [:show_axes, Show_all_axes, Show_x_axis], [:transform_normalization, Normalize_by_sound, Normalize_by_channel], [:graph_style, Graph_dots, Graph_lines], [:x_axis_style, X_axis_in_samples, X_axis_in_seconds], [:spectro_x_scale, 0.1, 1.0], [:transform_size, 32, 256], [:fft_window, Bartlett_window, Blackman2_window], [:dot_size, 4, 1], [:max_transform_peaks, 10, 100], [:with_verbose_cursor, true, false], [:zero_pad, 1, 0], [:min_dB, -90, -60], [:spectro_hop, 12, 4], [:spectrum_end, 0.1, 1.0], [:cursor_size, 15, 25], [:cursor_style, Cursor_cross, Cursor_line]] old_globals = funcs.map do |func, global, local| snd_func(func) end ind = open_sound("oboe.snd") funcs.each do |func, global, local| set_snd_func(func, global) set_snd_func(func, local, ind, 0) end set_zoom_focus_style(Zoom_focus_right) set_channel_style(Channels_combined) set_channel_style(Channels_separate, ind) delete_file("s61.rb") save_state("s61.rb") close_sound(ind) Snd.regions.apply(:forget_region) load("s61.rb") ind = find_sound("oboe.snd") funcs.each do |func, global, local| if $with_test_nogui next if func == :transform_normalization next if func == :spectro_x_scale next if func == :spectro_hop next if func == :spectrum_end end if local_neq?(res1 = snd_func(func), global) or local_neq?(res2 = snd_func(func, ind, 0), local) snd_display("save %s reversed: %s [%s] %s [%s]?", func, res1, global, res2, local) end end if (res = channel_style(ind)) != Channels_separate snd_display("save channel_style reversed: %s %s?", channel_style, res) end funcs.zip(old_globals) do |args, old_global| set_snd_func(args.first, old_global) end close_sound(ind) set_zoom_focus_style(Zoom_focus_active) set_channel_style(Channels_separate) delete_file("s61.rb") # ind0 = open_sound("oboe.snd") ind1 = open_sound("oboe.snd") if (res = find_sound("oboe.snd", 0)) != ind0 snd_display("find_sound 0: ind0 %s res %s?", ind0, res) end if (res = find_sound("oboe.snd", 1)) != ind1 snd_display("find_sound 1: ind1 %s res %s?", ind1, res) end add_mark(123, ind0) add_mark(321, ind1) delete_file("s61.rb") save_state("s61.rb") close_sound(ind0) close_sound(ind1) load("s61.rb") ind0 = find_sound("oboe.snd", 0) ind1 = find_sound("oboe.snd", 1) if (not ind0) or (not ind1) snd_display("saved 2oboes, found: %s", Snd.sounds.map do |s| short_file_name(s) end) end unless find_mark(123, ind0) snd_display("saved 2oboes mark 0?") end if find_mark(123, ind1) snd_display("saved 2oboes mark 1->0?") end unless find_mark(321, ind1) snd_display("saved 2oboes mark 1?") end if find_mark(321, ind0) snd_display("saved 2oboes mark 0->1?") end close_sound(ind0) close_sound(ind1) # basic choices [[lambda { |ind| insert_sample(10, 0.5, ind, 0) }, lambda { |ind| if fneq(sample(10), 0.5) snd_display("insert_sample save_state: %s?", channel2vct(5, 10, ind, 0)) end if (res = framples(ind, 0)) != 101 snd_display("insert_sample save_state len: %s?", res) end }], [lambda { |ind| delete_sample(10, ind, 0) }, lambda { |ind| if fneq(sample(10), 0.0) snd_display("delete_sample save_state: %s?", channel2vct(5, 10, ind, 0)) end if (res = framples(ind, 0)) != 99 snd_display("delete_sample save_state len: %s?", res) end }], [lambda { |ind| set_sample(10, 0.5, ind, 0) }, lambda { |ind| if fneq(sample(10), 0.5) snd_display("set_sample save_state: %s?", channel2vct(5, 10, ind, 0)) end if (res = framples(ind, 0)) != 100 snd_display("set_sample save_state len: %s?", res) end }], [lambda { |ind| set_sample(10, 0.5, ind, 0); scale_channel(0.5) }, lambda { |ind| if fneq(sample(10), 0.25) snd_display("scl sample save_state: %s?", channel2vct(5, 10, ind, 0)) end if (res = framples(ind, 0)) != 100 snd_display("scl sample save_state len: %s?", res) end if (res = edit_position(ind, 0)) != 2 snd_display("scl sample save_state edpos: %s?", res) end }], [lambda { |ind| vct2channel(Vct.new(10, 0.5), 10, 5, ind, 0); pad_channel(12, 5, ind, 0) }, lambda { |ind| if (res = framples(ind, 0)) != 105 snd_display("pad sample save_state len: %s?", res) end if (res = edit_position(ind, 0)) != 2 snd_display("pad sample save_state edpos: %s?", res) end unless vequal(res = channel2vct(10, 10, ind, 0), vct(0.5, 0.5, 0, 0, 0, 0, 0, 0.5, 0.5, 0.5)) snd_display("pad sample save_state: %s?", res) end }], [lambda { |ind| map_channel(lambda { |y| 1.0 }); env_channel([0, 0, 1, 1], 0, 11, ind, 0) }, lambda { |ind| if (res = framples(ind, 0)) != 100 snd_display("env sample save_state len: %s?", res) end if (res = edit_position(ind, 0)) != 2 snd_display("env sample save_state edpos: %s?", res) end unless vequal(res = channel2vct(0, 15, ind, 0), vct(0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1, 1, 1, 1, 1)) snd_display("env sample save_state: %s?", res) end }], # map_channel as backup [lambda { |ind| ctr = 0 map_channel(lambda { |y| ctr += 1 ctr.even? ? 0.1 : false }) }, lambda { |ind| if (res = framples(ind, 0)) != 50 snd_display("map false save_state len: %s?", res) end if (res = edit_position(ind, 0)) != 1 snd_display("map false save_state edpos: %s?", res) end if fneq(res = maxamp(ind, 0), 0.1) snd_display("map false save_state max: %s?", res) end unless vequal(res = channel2vct(0, 10, ind, 0), Vct.new(10, 0.1)) snd_display("map false save_state: %s?", res) end }], # as_one_edit [lambda { |ind| as_one_edit(lambda { | | vct2channel(Vct.new(10) { |i| (i + 1) * 0.1 }, 0, 10, ind, 0) vct2channel(Vct.new(10) { |i| (i + 1) * 0.1 }, 20, 10, ind, 0) }) }, lambda { |ind| if (res = edit_position(ind, 0)) != 1 snd_display("save_state backup 2 vcts edpos: %s?", res) end unless vequal(res = channel2vct( 0, 10, ind, 0), Vct.new(10) { |i| (i + 1) * 0.1 }) snd_display("as_one_edit save_state 1: %s?", res.to_str) end unless vequal(res = channel2vct(20, 10, ind, 0), Vct.new(10) { |i| (i + 1) * 0.1 }) snd_display("as_one_edit save_state 2: %s?", res.to_str) end }], [lambda { |ind| as_one_edit(lambda { | | vct2channel(Vct.new(10) { |i| (i + 1) * 0.1 }, 0, 10, ind, 0) scale_by(0.5) }) }, lambda { |ind| if (res = edit_position(ind, 0)) != 1 snd_display("save_state backup vct+scl edpos: %s?", res) end unless vequal(res = channel2vct(0, 10, ind, 0), Vct.new(10) { |i| (i + 1) * 0.1 }.scale(0.5)) snd_display("as_one_edit save_state 3: %s?", res) end }], [lambda { |ind| as_one_edit(lambda { | | vct2channel(Vct.new(10) { |i| (i + 1) * 0.1 }, 0, 10, ind, 0) delete_samples(5, 5) }) }, lambda { |ind| if (res = edit_position(ind, 0)) != 1 snd_display("save_state backup vct+del edpos: %s?", res) end unless vequal(res = channel2vct(0, 10, ind, 0), Vct.new(10) { |i| if i < 5 (i + 1) * 0.1 else 0.0 end }) snd_display("as_one_edit save_state 4: %s?", res) end }], [lambda { |ind| as_one_edit(lambda { | | delete_samples(5, 5) insert_samples(5, 2, vct(0.1, 0.2)) }) }, lambda { |ind| if (res = edit_position(ind, 0)) != 1 snd_display("save_state backup del+insert edpos: %s?", res) end unless vequal(res = channel2vct(0, 10, ind, 0), Vct.new(10) { |i| case i when 5 0.1 when 6 0.2 else 0.0 end }) snd_display("as_one_edit save_state 5: %s?", res) end if (res = framples(ind, 0)) != 97 snd_display("save_state backup del+insert len: %s?", res) end }], # 2 embedded as_one_edits [lambda { |ind| map_channel(lambda { |y| -1.0 }) as_one_edit(lambda { | | delete_samples(5, 5) insert_samples(5, 2, vct(0.1, 0.2)) }) scale_channel(2.0) as_one_edit(lambda { | | vct2channel(Vct.new(10) { |i| (i + 1) * 0.1 }, 10, 10, ind, 0) vct2channel(Vct.new(10) { |i| (i + 1) * 0.1 }, 20, 10, ind, 0) }) delete_samples(15, 10) }, lambda { |ind| if (res = edit_position(ind, 0)) != 5 snd_display("embed save_state edpos: %s?", res) end if (res = framples(ind, 0)) != 87 snd_display("embed save_state len: %s?", res) end unless vequal(res = channel2vct(0, 25, ind, 0), vct(-2, -2, -2, -2, -2, 0.2, 0.4, -2, -2, -2, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, -2, -2, -2, -2, -2)) snd_display("embed save_state 9: %s?", res.to_str) end }]].each_with_index do |args, i| func = args[0] test = args[1] ind = new_sound("test.snd", 1, 22050, Mus_bfloat, Mus_next, "mono save-state tests", 100) func.call(ind) delete_file("s61.rb") save_state("s61.rb") close_sound(ind) load("s61.rb") if sound?(ind = find_sound("test.snd")) test.call(ind) close_sound(ind) else snd_display("save_state test %s no test.snd?", i) end end end def test_19_02 # # edit_list2function # ind = open_sound("oboe.snd") mx0 = maxamp frs = framples # simple scale scale_channel(2.0) if fneq(res = maxamp, 2 * mx0) snd_display("edit_list2function off to a bad start: %s?", res) end unless proc?(func = edit_list2function) snd_display("edit_list2function 1: %s", func) end if (res = func.source) != "Proc.new {|snd, chn| scale_channel(2.000, 0, false, snd, chn) }" snd_display("edit_list2function 1: %s", res) end func.call(ind, 0) if fneq(res = maxamp, 4 * mx0) snd_display("edit_list2function called (1): %s %s?", res, mx0) end revert_sound(ind) scale_by(2.0) unless proc?(func = edit_list2function) snd_display("edit_list2function 1a: %s", func) end if (res = func.source) != "Proc.new {|snd, chn| scale_channel(2.000, 0, false, snd, chn) }" snd_display("edit_list2function 1a: %s", res) end revert_sound(ind) normalize_channel(1.001) # normalize_channel(1.0) seems to do nothing unless proc?(func = edit_list2function) snd_display("edit_list2function 1c: %s", func) end if (res = func.source) != "Proc.new {|snd, chn| normalize_channel(1.001, 0, false, snd, chn) }" snd_display("edit_list2function 1c: %s", res) end revert_sound(ind) # simple delete delete_samples(10, 100) if (res = framples) != frs - 100 snd_display("edit_list2function delete: %s %s?", frs, res) end unless proc?(func = edit_list2function) snd_display("edit_list2function 2: %s", func) end if (res = func.source) != "Proc.new {|snd, chn| delete_samples(10, 100, snd, chn) }" snd_display("edit_list2function 2: %s", res) end func.call(ind, 0) if (res = framples) != frs - 200 snd_display("edit_list2function called (2): %s %s?", frs, res) end revert_sound(ind) delete_sample(100) if (res = framples) != frs - 1 snd_display("edit_list2function delete (2a): %s %s?", frs, res) end unless proc?(func = edit_list2function) snd_display("edit_list2function 2a: %s", func) end if (res = func.source) != "Proc.new {|snd, chn| delete_samples(100, 1, snd, chn) }" snd_display("edit_list2function 2a: %s", res) end func.call(ind, 0) if (res = framples) != frs - 2 snd_display("edit_list2function called (2a): %s %s?", frs, res) end revert_sound(ind) # simple zero pad pad_channel(10, 100) if (res = framples) != frs + 100 snd_display("edit_list2function pad: %s %s?", frs, res) end unless proc?(func = edit_list2function) snd_display("edit_list2function 3: %s", func) end if (res = func.source) != "Proc.new {|snd, chn| pad_channel(10, 100, snd, chn) }" snd_display("edit_list2function 3: %s", res) end func.call(ind, 0) if (res = framples) != frs + 200 snd_display("edit_list2function called (3): %s %s?", frs, res) end revert_sound(ind) insert_silence(10, 100) if (res = framples) != frs + 100 snd_display("edit_list2function pad (3a): %s %s?", frs, res) end unless proc?(func = edit_list2function) snd_display("edit_list2function 3a: %s", func) end if (res = func.source) != "Proc.new {|snd, chn| pad_channel(10, 100, snd, chn) }" snd_display("edit_list2function 3a: %s", res) end func.call(ind, 0) if (res = framples) != frs + 200 snd_display("edit_list2function called (3a): %s %s?", frs, res) end revert_sound(ind) # simple ramp ramp_channel(0.2, 0.9) snd_test_neq(maxamp(), 0.0899, "edit_list2function ramp") unless proc?(func = edit_list2function) snd_display("edit_list2function 4: %s", func) end if (res = func.source) != "Proc.new {|snd, chn| ramp_channel(0.200, 0.900, 0, false, snd, chn) }" snd_display("edit_list2function 4: %s", res) end func.call(ind, 0) snd_test_neq(maxamp(), 0.061, "edit_list2function called (4)") revert_sound(ind) # simple xramp xramp_channel(0.2, 0.9, 32.0) snd_test_neq(maxamp(), 0.055, "edit_list2function xramp") unless proc?(func = edit_list2function) snd_display("edit_list2function 5: %s", func) end if (res = func.source) != "Proc.new {|snd, chn| xramp_channel(0.200, 0.900, 32.000, 0, false, snd, chn) }" snd_display("edit_list2function 5: %s", res) end func.call(ind, 0) if fneq(res = maxamp, 0.0266) snd_display("edit_list2function called (5): %s?", res) end revert_sound(ind) # simple env env_sound([0, 0, 1, 1]) snd_test_neq(maxamp(), 0.0906, "edit_list2function env") unless proc?(func = edit_list2function) snd_display("edit_list2function 6: %s", func) end if (res = func.source) != "Proc.new {|snd, chn| env_channel([0.000, 0.000, 1.000, 1.000], 0, false, snd, chn) }" snd_display("edit_list2function 6: %s", res) end func.call(ind, 0) snd_test_neq(maxamp(), 0.0634, "edit_list2function called (6)") revert_sound(ind) # less simple env env_sound([0, 0, 1, 0.3, 2, 0.8, 3, 0]) snd_test_neq(maxamp(), 0.107, "edit_list2function env (7)") unless proc?(func = edit_list2function) snd_display("edit_list2function 7: %s", func) end if (res = func.source) != "Proc.new {|snd, chn| env_channel([0.000, 0.000, 1.000, 0.300, 2.000, 0.800, 3.000, 0.000], 0, false, snd, chn) }" snd_display("edit_list2function 7: %s", res) end func.call(ind, 0) if fneq(res = maxamp, 0.0857) snd_display("edit_list2function called (7): %s?", res) end revert_sound(ind) env_sound([0, 0, 1, 0.3, 2, 0.8, 3, 0]) unless proc?(func = edit_list2function) snd_display("edit_list2function 7a: %s", func) end if (res = func.source) != "Proc.new {|snd, chn| env_channel([0.000, 0.000, 1.000, 0.300, 2.000, 0.800, 3.000, 0.000], 0, false, snd, chn) }" snd_display("edit_list2function 7a: %s", res) end revert_sound(ind) env_sound([0, 0, 1, 0.3, 2, 0.8, 3, 0], 1000, 2000) unless proc?(func = edit_list2function) snd_display("edit_list2function 7b: %s", func) end if (res = func.source) != "Proc.new {|snd, chn| env_channel(make_env([0.000, 0.000, 1.000, 0.300, 2.000, 0.800, 3.000, 0.000], :base, 1.0000, :end, 1999), 1000, 2000, snd, chn) }" snd_display("edit_list2function 7b: %s", res) end revert_sound(ind) env_sound(make_env(:envelope, [0, 0, 1, 0.3, 2, 0.8, 3, 0], :base, 32.0, :length, 2000), 1000, 2000) mxenv0 = maxamp unless proc?(func = edit_list2function) snd_display("edit_list2function 7c: %s", func) end if (res = func.source) != "Proc.new {|snd, chn| env_channel(make_env([0.000, 0.000, 1.000, 0.300, 2.000, 0.800, 3.000, 0.000], :base, 32.0000, :end, 1999), 1000, 2000, snd, chn) }" snd_display("edit_list2function 7c: %s", res) end revert_sound(ind) env_sound(make_env(:envelope, [0, 0, 1, 0.3, 2, 0.8, 3, 0], :offset, 2.0, :scaler, 3.0, :length, 2000), 1000, 2000) mxenv1 = maxamp unless proc?(func = edit_list2function) snd_display("edit_list2function 7d: %s", func) end if (res = func.source) != "Proc.new {|snd, chn| env_channel(make_env([0.000, 2.000, 1.000, 2.900, 2.000, 4.400, 3.000, 2.000], :base, 1.0000, :end, 1999), 1000, 2000, snd, chn) }" snd_display("edit_list2function 7d: %s", res) end revert_sound(ind) func.call(ind, 0) if fneq(res = maxamp, mxenv1) snd_display("edit_list2function 7d max: %s %s %s?", res, mxenv1, mxenv0) end revert_sound(ind) 5.times do |i| env_channel([0, 0, 1, 1, 2, 0]) end unless proc?(func = edit_list2function) snd_display("edit_list2function 7e: %s", func) end if (res = func.source) != "Proc.new {|snd, chn| env_channel([0.000, 0.000, 1.000, 1.000, 2.000, 0.000], 0, false, snd, chn); env_channel([0.000, 0.000, 1.000, 1.000, 2.000, 0.000], 0, false, snd, chn); env_channel([0.000, 0.000, 1.000, 1.000, 2.000, 0.000], 0, false, snd, chn); env_channel([0.000, 0.000, 1.000, 1.000, 2.000, 0.000], 0, false, snd, chn); env_channel([0.000, 0.000, 1.000, 1.000, 2.000, 0.000], 0, false, snd, chn) }" snd_display("edit_list2function 7e: %s", res) end revert_sound(ind) func.call(ind, 0) snd_test_neq(maxamp(), 0.146, "edit_list2function 7e max") if (res = edit_position) != 5 snd_display("edit_list2function 7e edpos: %s?", res) end revert_sound(ind) env_sound([0, 0, 1, 1, 2, 0], 0, framples, 32.0) snd_test_neq(maxamp(), 0.146, "edit_list2function 7f max") unless proc?(func = edit_list2function) snd_display("edit_list2function 7f: %s", func) end if (res = func.source) != "Proc.new {|snd, chn| env_channel_with_base([0.000, 0.000, 1.000, 1.000, 2.000, 0.000], 32.0000, 0, false, snd, chn) }" snd_display("edit_list2function 7f: %s", res) end revert_sound(ind) func.call(ind, 0) snd_test_neq(maxamp(), 0.146, "edit_list2function called (7f)") revert_sound(ind) env_sound([0, 0, 1, 1, 2, 1, 3, 0], 0, framples, 0.0) if fneq(res = sample(4000), 0.0) snd_display("edit_list2function env 7g: %s?", res) end unless proc?(func = edit_list2function) snd_display("edit_list2function 7g: %s", func) end if (res = func.source) != "Proc.new {|snd, chn| env_channel_with_base([0.000, 0.000, 1.000, 1.000, 2.000, 1.000, 3.000, 0.000], 0.0000, 0, false, snd, chn) }" snd_display("edit_list2function 7g: %s", res) end revert_sound(ind) func.call(ind, 0) if fneq(res = sample(4000), 0.0) snd_display("edit_list2function called (7g): %s?", res) end revert_sound(ind) # simple 1 sample insert insert_sample(100, 0.1) if (res = framples) != frs + 1 snd_display("edit_list2function insert_sample: %s %s?", frs, res) end unless proc?(func = edit_list2function) snd_display("edit_list2function 9: %s", func) end if (res = func.source) != "Proc.new {|snd, chn| insert_sample(100, 0.1000, snd, chn) }" snd_display("edit_list2function 9: %s", res) end func.call(ind, 0) unless vequal(res = channel2vct(99, 4), vct(0.0, 0.1, 0.1, 0.0)) snd_display("edit_list2function func 9: %s?", res) end if (res = framples) != frs + 2 snd_display("edit_list2function called (9): %s %s?", frs, res) end revert_sound(ind) # insert_samples with data insert_samples(0, 100, Vct.new(100, 0.1)) if (res = framples) != frs + 100 snd_display("edit_list2function insert_samples (100): %s %s?", frs, res) end unless proc?(func = edit_list2function) snd_display("edit_list2function 9a: %s", func) end func.call(ind, 0) if (res = framples) != frs + 200 snd_display("edit_list2function insert_samples (200): %s %s?", frs, res) end unless vequal(res = channel2vct(0, 5), vct(0.1, 0.1, 0.1, 0.1, 0.1)) snd_display("edit_list2function func 9a: %s?", res) end revert_sound(ind) # set_samples with data set_samples(0, 100, Vct.new(100, 0.1)) if (res = framples) != frs snd_display("edit_list2function set_samples (1): %s %s?", frs, res) end unless proc?(func = edit_list2function) snd_display("edit_list2function 9b: %s", func) end func.call(ind, 0) if (res = framples) != frs snd_display("edit_list2function set_samples (2): %s %s?", frs, res) end unless vequal(res = channel2vct(0, 5), vct(0.1, 0.1, 0.1, 0.1, 0.1)) snd_display("edit_list2function func 9b: %s?", res) end revert_sound(ind) # simple 1 sample set val = sample(100) set_sample(100, 0.1) if (res = framples) != frs snd_display("edit_list2function set_sample framples: %s %s?", frs, res) end if fneq(res = sample(100), 0.1) snd_display("edit_list2function set_sample val: %s %s?", val, res) end func = edit_list2function revert_sound(ind) if fneq(res = sample(100), val) snd_display("edit_list2function unset_sample val: %s %s?", val, res) end unless proc?(func) snd_display("edit_list2function 10: %s", func) end if (res = func.source) != "Proc.new {|snd, chn| set_sample(100, 0.1000, snd, chn) }" snd_display("edit_list2function 10: %s", res) end func.call(ind, 0) unless vequal(res = channel2vct(99, 4), vct(0.0, 0.1, 0.0, 0.0)) snd_display("edit_list2function func 10: %s?", res) end revert_sound(ind) pfrs = mus_sound_framples("pistol.snd") insert_sound("pistol.snd", 1000) if (res = framples) != frs + pfrs snd_display("edit_list2function insert_sound framples: %s %s?", frs, res) end unless proc?(func = edit_list2function) snd_display("edit_list2function 10a: %s", func) end if (res = func.source) != format("Proc.new {|snd, chn| insert_sound(%s, 1000, 0, snd, chn) }", File.expand_path("pistol.snd").inspect) snd_display("edit_list2function 10a: %s", res) end revert_sound(ind) func.call(ind, 0) if (res = framples) != frs + pfrs snd_display("edit_list2function called (10a): %s %s?", frs, res) end revert_sound(ind) pfrs = mus_sound_framples("pistol.snd") insert_samples(1000, pfrs, "pistol.snd") if (res = framples) != frs + pfrs snd_display("edit_list2function insert_samples framples: %s %s?", frs, res) end unless proc?(func = edit_list2function) snd_display("edit_list2function 11: %s", func) end if (res = func.source) != format("Proc.new {|snd, chn| insert_samples(1000, %s, %s, snd, chn) }", mus_sound_samples("pistol.snd"), File.expand_path("pistol.snd").inspect) snd_display("edit_list2function 11: %s", res) end revert_sound(ind) func.call(ind, 0) if (res = framples) != frs + pfrs snd_display("edit_list2function called (11): %s %s?", frs, res) end revert_sound(ind) smooth_channel(1000, 100) val = sample(1050) unless proc?(func = edit_list2function) snd_display("edit_list2function 12: %s", func) end if (res = func.source) != "Proc.new {|snd, chn| smooth_channel(1000, 100, snd, chn) }" snd_display("edit_list2function 12: %s", res) end revert_sound(ind) func.call(ind, 0) if fneq(res = sample(1050), val) snd_display("edit_list2function called (12): %s %s?", res, val) end revert_sound(ind) smooth_channel(1000, 100) unless proc?(func = edit_list2function) snd_display("edit_list2function 12a: %s", func) end if (res = func.source) != "Proc.new {|snd, chn| smooth_channel(1000, 100, snd, chn) }" snd_display("edit_list2function 12a: %s", res) end revert_sound(ind) # selection stuff make_selection(1000, 11000) scale_selection_by(2.0) unless proc?(func = edit_list2function) snd_display("edit_list2function 13: %s", func) end if (res = func.source) != "Proc.new {|snd, chn| scale_channel(2.000, 1000, 10001, snd, chn) }" snd_display("edit_list2function 13: %s", res) end revert_sound(ind) func.call(ind, 0) snd_test_neq(maxamp(), 0.269, "edit_list2function called (13)") revert_sound(ind) scale_selection_to(1.0) unless proc?(func = edit_list2function) snd_display("edit_list2function 13:a %s", func) end if (res = func.source) != "Proc.new {|snd, chn| normalize_channel(1.000, 1000, 10001, snd, chn) }" snd_display("edit_list2function 13a: %s", res) end revert_sound(ind) env_selection([0, 0, 1, 1, 2, 0]) snd_test_neq(sample(4000), 0.0173, "edit_list2function 14 samp") unless proc?(func = edit_list2function) snd_display("edit_list2function 14: %s", func) end if (res = func.source) != "Proc.new {|snd, chn| env_channel(make_env([0.000, 0.000, 1.000, 1.000, 2.000, 0.000], :base, 1.0000, :end, 10000), 1000, 10001, snd, chn) }" snd_display("edit_list2function 14: %s", res) end revert_sound(ind) func.call(ind, 0) snd_test_neq(sample(4000), 0.0173, "edit_list2function called (14)") revert_sound(ind) make_selection(1000, 1100) smooth_selection val = sample(1050) unless proc?(func = edit_list2function) snd_display("edit_list2function 14a: %s", func) end if (res = func.source) != "Proc.new {|snd, chn| smooth_channel(1000, 101, snd, chn) }" snd_display("edit_list2function 14a: %s", res) end revert_sound(ind) func.call(ind, 0) if fneq(res = sample(1050), val) snd_display("edit_list2function called (14a): %s?", res) end revert_sound(ind) reverse_selection unless proc?(func = edit_list2function) snd_display("edit_list2function 14b: %s", func) end if (res = func.source) != "Proc.new {|snd, chn| reverse_channel(1000, 101, snd, chn) }" snd_display("edit_list2function 14b: %s", res) end revert_sound(ind) func.call(ind, 0) revert_sound(ind) delete_selection unless proc?(func = edit_list2function) snd_display("edit_list2function 14c: %s", func) end if (res = func.source) != "Proc.new {|snd, chn| delete_samples(1000, 101, snd, chn) }" snd_display("edit_list2function 14c: %s", res) end revert_sound(ind) func.call(ind, 0) revert_sound(ind) # simple reapply env_channel([0, 0, 1, 1, 2, 0]) func = edit_list2function close_sound(ind) ind = new_sound("tmp.snd", 1, 22050, Mus_bfloat, Mus_next, :size, 20, :comment, false) map_channel(lambda do |y| 1.0 end) func.call(ind, 0) unless vequal(res = channel2vct, vct(0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 0.889, 0.778, 0.667, 0.556, 0.444, 0.333, 0.222, 0.111, 0.0)) snd_display("edit_list2function env reapply: %s?", res) end close_sound(ind) ind = open_sound("oboe.snd") # insert-region reg = make_region(1000, 1100) insert_region(reg, 2000) val = sample(2050) unless proc?(func = edit_list2function) snd_display("edit_list2function 16: %s", func) end if (res = func.source) != format("Proc.new {|snd, chn| insert_region(integer2region(%s), 2000, snd, chn) }", region2integer(reg)) snd_display("edit_list2function 16: %s", res) end revert_sound(ind) func.call(ind, 0) if fneq(res = sample(2050), val) snd_display("edit_list2function called (16): %s?", res) end revert_sound(ind) # reverse reverse_channel val = sample(2000) unless proc?(func = edit_list2function) snd_display("edit_list2function 17: %s", func) end if (res = func.source) != "Proc.new {|snd, chn| reverse_channel(0, false, snd, chn) }" snd_display("edit_list2function 17: %s", res) end if fneq(val, -0.002) snd_display("edit_list2function 17 val: %s?", val) end revert_sound(ind) func.call(ind, 0) if fneq(val, -0.002) snd_display("edit_list2function 17 re-val: %s?", val) end revert_sound(ind) reverse_channel val = sample(2000) unless proc?(func = edit_list2function) snd_display("edit_list2function 17a: %s", func) end if (res = func.source) != "Proc.new {|snd, chn| reverse_channel(0, false, snd, chn) }" snd_display("edit_list2function 17a: %s", res) end if fneq(val, -0.002) snd_display("edit_list2function 17a val: %s?", val) end revert_sound(ind) reverse_channel(1000, 500) unless proc?(func = edit_list2function) snd_display("edit_list2function 17b: %s", func) end if (res = func.source) != "Proc.new {|snd, chn| reverse_channel(1000, 500, snd, chn) }" snd_display("edit_list2function 17b: %s", res) end revert_sound(ind) # src src_sound(2.0) if (framples - 25415).abs > 2 snd_display("edit_list2function 18 len: %s?", framples) end unless proc?(func = edit_list2function) snd_display("edit_list2function 18: %s", func) end if (res = func.source) != "Proc.new {|snd, chn| src_channel(2.0000, 0, false, snd, chn) }" snd_display("edit_list2function 18: %s", res) end revert_sound(ind) func.call(ind, 0) if (framples - 25415).abs > 2 snd_display("edit_list2function 18 re-len: %s?", framples) end revert_sound(ind) src_channel(2.0, 1000, 500) frs = framples unless proc?(func = edit_list2function) snd_display("edit_list2function 18a: %s", func) end if (res = func.source) != "Proc.new {|snd, chn| src_channel(2.0000, 1000, 500, snd, chn) }" snd_display("edit_list2function 18a: %s", res) end revert_sound(ind) func.call(ind, 0) if framples != frs snd_display("edit_list2function 18a re-len: %s?", framples) end revert_sound(ind) src_sound([0, 1, 1, 2, 2, 1]) frs = framples unless proc?(func = edit_list2function) snd_display("edit_list2function 18b: %s", func) end if (res = func.source) != "Proc.new {|snd, chn| src_channel([0.000, 1.000, 1.000, 2.000, 2.000, 1.000], 0, false, snd, chn) }" snd_display("edit_list2function 18b: %s", res) end revert_sound(ind) func.call(ind, 0) if framples != frs snd_display("edit_list2function 18b re-len: %s?", framples) end revert_sound(ind) src_channel([0, 1, 1, 2], 1000, 500) frs = framples unless proc?(func = edit_list2function) snd_display("edit_list2function 18c: %s", func) end if (res = func.source) != "Proc.new {|snd, chn| src_channel([0.000, 1.000, 1.000, 2.000], 1000, 500, snd, chn) }" snd_display("edit_list2function 18c: %s", res) end revert_sound(ind) func.call(ind, 0) if framples != frs snd_display("edit_list2function 18c re-len: %s?", framples) end revert_sound(ind) # filter-channel filter_channel([0, 1, 1, 0], 10) mx = maxamp unless proc?(func = edit_list2function) snd_display("edit_list2function 19: %s", func) end if (res = func.source) != "Proc.new {|snd, chn| filter_channel([0.000, 1.000, 1.000, 0.000], 10, 0, false, snd, chn) }" snd_display("edit_list2function 19: %s", res) end revert_sound(ind) func.call(ind, 0) if fneq(res = maxamp, mx) snd_display("edit_list2function 19 re-filter: %s %s?", mx, res) end revert_sound(ind) [[lambda { insert_vct(vct(1.0, 0.5), 0, 2) }, "Proc.new {|snd, chn| insert_vct(vct(1.000, 0.500), 0, 2, snd, chn) }"], [lambda { clm_channel_test }, "Proc.new {|snd, chn| clm_channel_test(snd, chn) }"], # examp.rb [lambda { fft_edit(1000, 3000) }, "Proc.new {|snd, chn| fft_edit(1000, 3000, snd, chn) }"], [lambda { fft_squelch(0.01) }, "Proc.new {|snd, chn| fft_squelch(0.01, snd, chn) }"], [lambda { fft_cancel(1000, 3000) }, "Proc.new {|snd, chn| fft_cancel(1000, 3000, snd, chn) }"], [lambda { squelch_vowels }, "Proc.new {|snd, chn| squelch_vowels(snd, chn) }"], [lambda { fft_env_edit([0, 0, 1, 1, 2, 0]) }, "Proc.new {|snd, chn| fft_env_edit([0, 0, 1, 1, 2, 0], snd, chn) }"], [lambda { fft_env_interp([0, 0, 1, 1, 2, 0], [0, 1, 1, 0, 2, 0], [0, 0, 1, 1]) }, "Proc.new {|snd, chn| fft_env_interp([0, 0, 1, 1, 2, 0], [0, 1, 1, 0, 2, 0], [0, 0, 1, 1], snd, chn) }"], [lambda { hello_dentist(10.0, 0.1) }, "Proc.new {|snd, chn| hello_dentist(10.0, 0.1, snd, chn) }"], [lambda { fp(1.0, 0.3, 20.0) }, "Proc.new {|snd, chn| fp(1.0, 0.3, 20.0, snd, chn) }"], [lambda { expsnd([0, 1, 1, 2]) }, "Proc.new {|snd, chn| expsnd([0, 1, 1, 2], snd, chn) }"], [lambda { voiced2unvoiced(1.0, 256, 2.0, 2.0) }, "Proc.new {|snd, chn| voiced2unvoiced(1.0, 256, 2.0, 2.0, snd, chn) }"], [lambda { env_sound_interp([0, 0, 1, 1, 2, 0], 2.0) }, "Proc.new {|snd, chn| env_sound_interp([0, 0, 1, 1, 2, 0], 2.0, snd, chn) }"], [lambda { add_notes([["1a.snd"], ["pistol.snd", 1.0, 2.0]]) }, "Proc.new {|snd, chn| add_notes([[\"1a.snd\"], [\"pistol.snd\", 1.0, 2.0]], snd, chn) }"], [lambda { filtered_env([0, 0, 1, 1, 2, 0]) }, "Proc.new {|snd, chn| filtered_env([0, 0, 1, 1, 2, 0], snd, chn) }"], [lambda { reverse_by_blocks(0.1) }, "Proc.new {|snd, chn| reverse_by_blocks(0.1, snd, chn) }"], [lambda { reverse_within_blocks(0.1) }, "Proc.new {|snd, chn| reverse_within_blocks(0.1, snd, chn) }"], # extensions.rb [lambda { mix_channel("1a.snd", 1200) }, "Proc.new {|snd, chn| mix_channel(\"1a.snd\", 1200, false, snd, chn) }"], [lambda { insert_channel("1a.snd", 1200) }, "Proc.new {|snd, chn| insert_channel(\"1a.snd\", 1200, false, snd, chn) }"], [lambda { sine_ramp(0.5, 0.9) }, "Proc.new {|snd, chn| sine_ramp(0.5, 0.9, 0, false, snd, chn) }"], [lambda { sine_env_channel([0, 0, 1, 1, 2, -0.5, 3, 1]) }, "Proc.new {|snd, chn| sine_env_channel([0, 0, 1, 1, 2, -0.5, 3, 1], 0, false, snd, chn) }"], [lambda { blackman4_ramp(0.0, 1.0) }, "Proc.new {|snd, chn| blackman4_ramp(0.0, 1.0, 0, false, snd, chn) }"], [lambda { blackman4_env_channel([0, 0, 1, 1, 2, -0.5, 3, 1]) }, "Proc.new {|snd, chn| blackman4_env_channel([0, 0, 1, 1, 2, -0.5, 3, 1], 0, false, snd, chn) }"], [lambda { ramp_squared(0.2, 0.8, true) }, "Proc.new {|snd, chn| ramp_squared(0.2, 0.8, true, 0, false, snd, chn) }"], [lambda { env_squared_channel([0, 0, 1, 1], true) }, "Proc.new {|snd, chn| env_squared_channel([0, 0, 1, 1], true, 0, false, snd, chn) }"], [lambda { ramp_expt(0.2, 0.8, 32.0, true) }, "Proc.new {|snd, chn| ramp_expt(0.2, 0.8, 32.0, true, 0, false, snd, chn) }"], [lambda { env_expt_channel([0, 0, 1, 1], 32.0, true) }, "Proc.new {|snd, chn| env_expt_channel([0, 0, 1, 1], 32.0, true, 0, false, snd, chn) }"], [lambda { offset_channel(0.1) }, "Proc.new {|snd, chn| offset_channel(0.1, 0, false, snd, chn) }"], [lambda { dither_channel(0.1) }, "Proc.new {|snd, chn| dither_channel(0.1, 0, false, snd, chn) }"], [lambda { contrast_channel(0.1) }, "Proc.new {|snd, chn| contrast_channel(0.1, 0, false, snd, chn) }"], # dsp.rb [lambda { ssb_bank(550, 600, 10) }, "Proc.new {|snd, chn| ssb_bank(550, 600, 10, 40, 50.0, 0, false, snd, chn) }"], [lambda { ssb_bank_env(550, 660, [0, 1, 1, 2], 10) }, "Proc.new {|snd, chn| ssb_bank_env(550, 660, [0, 1, 1, 2], 10, 40, 50.0, 0, false, snd, chn) }"], [lambda { down_oct(1) }, "Proc.new {|snd, chn| down_oct(1, snd, chn) }"], [lambda { freqdiv(8) }, "Proc.new {|snd, chn| freqdiv(8, snd, chn) }"], [lambda { adsat(8) }, "Proc.new {|snd, chn| adsat(8, false, false, snd, chn) }"], [lambda { spike }, "Proc.new {|snd, chn| spike(snd, chn) }"], [lambda { zero_phase }, "Proc.new {|snd, chn| zero_phase(snd, chn) }"], [lambda { rotate_phase(lambda { |x| random(PI) }) }, format("Proc.new {|snd, chn| rotate_phase(Proc.new {|val_r| rotate_phase_%s(val_r) }, snd, chn) }", edit_list_proc_counter + 1)], [lambda { brighten_slightly(0.5) }, "Proc.new {|snd, chn| brighten_slightly(0.5, snd, chn) }"], [lambda { shift_channel_pitch(100) }, "Proc.new {|snd, chn| shift_channel_pitch(100, 40, 0, false, snd, chn) }"], [lambda { channel_polynomial(vct(0, 0.5)) }, "Proc.new {|snd, chn| channel_polynomial(vct(0.000, 0.500), snd, chn) }"], [lambda { spectral_polynomial(vct(0, 0.5)) }, "Proc.new {|snd, chn| spectral_polynomial(vct(0.000, 0.500), snd, chn) }"], [lambda { notch_channel([60.0, 120.0, 240.0], false, false, false) }, "Proc.new {|snd, chn| notch_channel([60.0, 120.0, 240.0], false, false, false, snd, chn) }"], # effects.rb [lambda { effects_squelch_channel(0.1, 128) }, "Proc.new {|snd, chn| effects_squelch_channel(0.1, 128, snd, chn) }"], [lambda { effects_echo(false, 0.5, 0.1, 0, false) }, "Proc.new {|snd, chn| effects_echo(false, 0.5, 0.1, 0, false, snd, chn) }"], [lambda { effects_flecho_1(0.5, 0.1, false, 0, false) }, "Proc.new {|snd, chn| effects_flecho_1(0.5, 0.1, false, 0, false, snd, chn) }"], [lambda { effects_zecho_1(0.75, 0.75, 6.0, 10.0, false, 0, false) }, "Proc.new {|snd, chn| effects_zecho_1(0.75, 0.75, 6.0, 10.0, false, 0, false, snd, chn) }"], #[lambda { effects_comb_filter(0.1, 50, 0, false) }, #"Proc.new {|snd, chn| effects_comb_filter(0.1, 50, 0, false, snd, chn) }"], [lambda { effects_moog(10000, 0.5, 0, false) }, "Proc.new {|snd, chn| effects_moog(10000, 0.5, 0, false, snd, chn) }"], [lambda { effects_remove_dc }, "Proc.new {|snd, chn| effects_remove_dc(snd, chn) }"], [lambda { effects_compand }, "Proc.new {|snd, chn| effects_compand(snd, chn) }"], [lambda { effects_am(100.0, false) }, "Proc.new {|snd, chn| effects_am(100.0, false, 0, false, snd, chn) }"], [lambda { effects_rm(100.0, false) }, "Proc.new {|snd, chn| effects_rm(100.0, false, 0, false, snd, chn) }"], [lambda { effects_bbp(1000.0, 100.0, 0, false) }, "Proc.new {|snd, chn| effects_bbp(1000.0, 100.0, 0, false, snd, chn) }"], [lambda { effects_bbr(1000.0, 100.0, 0, false) }, "Proc.new {|snd, chn| effects_bbr(1000.0, 100.0, 0, false, snd, chn) }"], [lambda { effects_bhp(1000.0, 0, false) }, "Proc.new {|snd, chn| effects_bhp(1000.0, 0, false, snd, chn) }"], [lambda { effects_blp(1000.0, 0, false) }, "Proc.new {|snd, chn| effects_blp(1000.0, 0, false, snd, chn) }"], [lambda { effects_hello_dentist(50.0, 0.5, 0, false) }, "Proc.new {|snd, chn| effects_hello_dentist(50.0, 0.5, 0, false, snd, chn) }"], [lambda { effects_fp(1.0, 0.3, 20.0, 0, false) }, "Proc.new {|snd, chn| effects_fp(1.0, 0.3, 20.0, 0, false, snd, chn) }"], [lambda { effects_flange(5.0, 2.0, 0.001, 0, false) }, "Proc.new {|snd, chn| effects_flange(5.0, 2.0, 0.001, 0, false, snd, chn) }"], [lambda { effects_jc_reverb_1(0.1, 0, false) }, "Proc.new {|snd, chn| effects_jc_reverb_1(0.1, 0, false, snd, chn) }"] ].each_with_index do |args, i| func, descr = args func.call unless proc?(func = edit_list2function) snd_display("edit_list2function proc 20[%s]: %s", i, func.inspect) end if func.source != descr snd_display("edit_list2function source 20[%s]: %s", i, func.source) end revert_sound(ind) func.call(ind, 0) revert_sound(ind) end close_sound(ind) end def test_19_03 # # apply controls edit lists # ind = open_sound("oboe.snd") original_maxamp = maxamp reset_controls controls2channel([2.0]) if fneq(res = amp_control(ind), 1.0) snd_display("controls2channel amp: %s?", res) end if fneq(res = maxamp, 2 * original_maxamp) snd_display("controls2channel maxamp: %s?", res) end func = edit_list2function if (res = func.source) != "Proc.new {|snd, chn| scale_channel(2.000, 0, false, snd, chn) }" snd_display("edit_list2function controls2channel 1: %s", res) end func.call(ind, 0) revert_sound(ind) # controls2channel([false, 2.0]) if fneq(res = channel2vct(22000, 22100).peak, 0.0479) snd_display("dp->end screwed up again!?!: %s?", res) end func = edit_list2function if (res = func.source) != "Proc.new {|snd, chn| controls2channel([false, 2.0], 0, false, snd, chn) }" snd_display("edit_list2function controls2channel 2: %s", res) end revert_sound(ind) func.call(ind, 0) revert_sound(ind) snd_test_neq(speed_control(ind), 1.0, "controls2channel speed") # controls2channel([false, false, [0.5]]) func = edit_list2function if (res = func.source) != "Proc.new {|snd, chn| controls2channel([false, false, [0.5]], 0, false, snd, chn) }" snd_display("edit_list2function controls2channel 3: %s", res) end revert_sound(ind) func.call(ind, 0) revert_sound(ind) if fneq(res = contrast_control(ind), 0.0) snd_display("controls2channel contrast: %s?", res) end # controls2channel([false, false, [0.5, 2.0]]) func = edit_list2function if (res = func.source) != "Proc.new {|snd, chn| controls2channel([false, false, [0.5, 2.0]], 0, false, snd, chn) }" snd_display("edit_list2function controls2channel 3a: %s", res) end revert_sound(ind) func.call(ind, 0) revert_sound(ind) if fneq(res = contrast_control(ind), 0.0) snd_display("controls2channel contrast 3a: %s?", res) end # controls2channel([false, false, false, [0.5]]) func = edit_list2function if (res = func.source) != "Proc.new {|snd, chn| controls2channel([false, false, false, [0.5]], 0, false, snd, chn) }" snd_display("edit_list2function controls2channel 4: %s", res) end revert_sound(ind) func.call(ind, 0) revert_sound(ind) if fneq(res = expand_control(ind), 1.0) snd_display("controls2channel expand: %s?", res) end # controls2channel([false, false, false, [0.5, 0.1, 0.2, 0.06, 0.0]]) func = edit_list2function if (res = func.source) != "Proc.new {|snd, chn| controls2channel([false, false, false, [0.5, 0.1, 0.2, 0.06, 0.0]], 0, false, snd, chn) }" snd_display("edit_list2function controls2channel 4a: %s", res) end revert_sound(ind) func.call(ind, 0) revert_sound(ind) if fneq(res = expand_control(ind), 1.0) snd_display("controls2channel expand 4a: %s?", res) end # controls2channel([false, false, false, false, [0.1]]) func = edit_list2function if (res = func.source) != "Proc.new {|snd, chn| controls2channel([false, false, false, false, [0.1]], 0, false, snd, chn) }" snd_display("edit_list2function controls2channel 5: %s", res) end revert_sound(ind) func.call(ind, 0) revert_sound(ind) if fneq(res = reverb_control_scale(ind), 0.0) snd_display("controls2channel reverb: %s?", res) end # controls2channel([false, false, false, false, [0.1, 1.2, 0.9, 0.9, 2.0]]) func = edit_list2function if (res = func.source) != "Proc.new {|snd, chn| controls2channel([false, false, false, false, [0.1, 1.2, 0.9, 0.9, 2.0]], 0, false, snd, chn) }" snd_display("edit_list2function controls2channel 5a: %s", res) end revert_sound(ind) func.call(ind, 0) revert_sound(ind) if fneq(res = reverb_control_scale(ind), 0.0) snd_display("controls2channel reverb 5a: %s?", res) end # order = filter_control_order(ind) controls2channel([false, false, false, false, false, [10, [0, 0, 1, 1]]]) func = edit_list2function if (res = func.source) != "Proc.new {|snd, chn| controls2channel([false, false, false, false, false, [10, [0, 0, 1, 1]]], 0, false, snd, chn) }" snd_display("edit_list2function controls2channel 6: %s", res) end revert_sound(ind) func.call(ind, 0) revert_sound(ind) if (res = filter_control_order(ind)) != order snd_display("controls2channel filter: %s?", res) end # # mix stuff # id = make_v_mix(ind, 0) # mix-position set_mix_position(id, 200) if (res = mix_position(id)) != 200 snd_display("edit_list2function mix off to a bad start: %s?", res) end unless proc?(func = edit_list2function) snd_display("edit_list2function mix 1: %s?", func) end if (res = func.source) != format("Proc.new {|snd, chn| _mix_%s = false; _mix_%s = mix_vct(vct(0.1, 0.2, 0.3), 100, snd, chn); set_mix_position(_mix_%s, 200) }", mix2integer(id), mix2integer(id), mix2integer(id)) snd_display("edit_list2function mix 1: %s", res) end revert_sound(ind) func.call(ind, 0) res1 = mixes(ind, 0) res2 = if res1.nil? false else res1.detect do |m| mix?(m) and mix_position(m) == 200 end end unless mix?(res2) snd_display("edit_list2function mix 1 repos: %s %s?", res1, res2) end revert_sound(ind) # mix-amp id = make_v_mix(ind, 0) set_mix_amp(id, 0.5) unless proc?(func = edit_list2function) snd_display("edit_list2function mix 4: %s?", func) end if (res = func.source) != format("Proc.new {|snd, chn| _mix_%s = false; _mix_%s = mix_vct(vct(0.1, 0.2, 0.3), 100, snd, chn); set_mix_amp(_mix_%s, 0.5000) }", mix2integer(id), mix2integer(id), mix2integer(id)) snd_display("edit_list2function mix 4: %s", res) end revert_sound(ind) func.call(ind, 0) revert_sound(ind) # mix-speed id = make_v_mix(ind, 0) set_mix_speed(id, 0.5) unless proc?(func = edit_list2function) snd_display("edit_list2function mix 5: %s?", func) end if (res = func.source) != format("Proc.new {|snd, chn| _mix_%s = false; _mix_%s = mix_vct(vct(0.1, 0.2, 0.3), 100, snd, chn); set_mix_speed(_mix_%s, 0.5000) }", mix2integer(id), mix2integer(id), mix2integer(id)) snd_display("edit_list2function mix 5: %s", res) end revert_sound(ind) func.call(ind, 0) revert_sound(ind) close_sound(ind) # ind = open_sound("2.snd") src_sound(3.0, 1.0, ind) save_sound_as("test.snd") close_sound(ind) ind = open_sound("test.snd") if (res = chans(ind)) != 2 snd_display("src_sound/save_sound_as: %s chans?", res) end close_sound(ind) # ind = open_sound("oboe.snd") if (res = Snd.catch do save_sound_as("test.snd", :edit_position, 1) end).first != :no_such_edit snd_display("save_sound_as bad edpos: %s", res.inspect) end if (res = Snd.catch do save_sound_as("test.snd", :channel, 1, :edit_position, 1) end).first != :no_such_channel snd_display("save_sound_as bad chan: %s", res.inspect) end save_sound_as("test.snd", :comment, "this is a comment") close_sound(ind) ind = open_sound("test.snd") if (res = comment(ind)) != "this is a comment" snd_display("save_sound_as with comment: %s?", res) end close_sound(true) end def test_19 if $with_test_gui # load(save_state_file) -> set_transform_size(0) test_19_00 test_19_01 end test_19_02 test_19_03 mus_sound_prune end # ---------------- test 20: transforms ---------------- def bes_test(func_sym) [0.0, 0.5, 1.0, 2.0, 20.0].each do |x| snd_test_neq(snd_func(func_sym, x), snd_func("#{func_sym.to_s}_1", x), "%s(%1.1f)", func_sym, x) end 10.times do x = random(100.0) snd_test_neq(snd_func(func_sym, x), snd_func("#{func_sym.to_s}_1", x), "%s(%1.1f)", func_sym, x) end end def bes_j0_1(x) if x.abs < 8.0 y = x * x ans1 = 57568490574.0 + y * (-13362590354.0 + \ y * (651619640.7 + \ y * (-11214424.18 + \ y * (77392.33017 + \ y * -184.9052456)))) ans2 = 57568490411.0 + y * (1029532985.0 + \ y * (9494680.718 + \ y * (59272.64853 + \ y * (267.8532712 + y)))) ans1 / ans2 else ax = x.abs z = 8.0 / ax y = z * z xx = ax - 0.785398164 ans1 = 1.0 + y * (-0.1098628627e-2 + \ y * (0.2734510407e-4 + \ y * (-0.2073370639e-5 + \ y * 0.2093887211e-6))) ans2 = -0.1562499995e-1 + y * (0.1430488765e-3 + \ y * (-0.6911147651e-5 + \ y * (0.7621095161e-6 + \ y * -0.934945152e-7))) sqrt(0.636619772 / ax) * (cos(xx) * ans1 - sin(xx) * z * ans2) end end def bes_j1_1(x) if x.abs < 8.0 y = x * x ans1 = x * (72362614232.0 + \ y * (-7895059235.0 + \ y * (242396853.1 + \ y * (-2972611.439 + \ y * (15704.48260 + \ y * -30.16036606))))) ans2 = 144725228442.0 + y * (2300535178.0 + \ y * (18583304.74 + \ y * (99447.43394 + \ y * (376.9991397 + y)))) ans1 / ans2 else ax = x.abs z = 8.0 / ax y = z * z xx = ax - 2.356194491 ans1 = 1.0 + y * (0.183105e-2 + \ y * (-0.3516396496e-4 + \ y * (0.2457520174e-5 + \ y * -0.240337019e-6))) ans2 = 0.04687499995 + y * (-0.2002690873e-3 + \ y * (0.8449199096e-5 + \ y * (-0.88228987e-6 + \ y * 0.105787412e-6))) sqrt(0.636619772 / ax) * (cos(xx) * ans1 - sin(xx) * z * ans2) * (x.zero? ? 0 : (x < 0 ? -1 : 1)) end end def bes_jn_1(nn, x) n = nn.abs besn = if n.zero? bes_j0_1(x) elsif n == 1 bes_j1_1(x) elsif x.zero? 0.0 else iacc = 40.0 ans = 0.0 bigno = 1.0e10 bigni = 1.0e-10 tox = 2.0 / x.abs if x.abs > n bjm = bes_j0_1(x.abs) bj = bes_j1_1(x.abs) bjp = 0.0 (1...n).each do |i| bjp = i * tox * bj - bjm bjm, bj = bj, bjp end ans = bj else m = 2 * ((sqrt(iacc * n) + n) / 2.0).floor jsum = 0 bjm = 0.0 sum = 0.0 bjp = 0.0 bj = 1.0 m.downto(1) do |i| bjm = i * tox * bj - bjp bjp, bj = bj, bjm if bj.abs > bigno bj *= bigni bjp *= bigni ans *= bigni sum *= bigni end if jsum.nonzero? sum += bj end jsum = 1 - jsum if i == n ans = bjp end end sum = 2.0 * sum - bj ans = ans / sum end if x < 0 and n.odd? -ans else ans end end if nn < 0 and nn.odd? -besn else besn end end def bes_test_jn 10.times do |k| 10.times do |i| x = random(100.0) snd_test_neq(bes_jn(k, x), bes_jn_1(k, x), "bes_jn(%k, %1.1f)", k, x) end end end def bes_y0_1(x) if x < 8.0 y = x * x ans1 = -2957821389.0 + y * (7062834065.0 + \ y * (-512359803.6 + \ y * (10879881.29 + \ y * (-86327.92757 + \ y * 228.4622733)))) ans2 = 40076544269.0 + y * (745249964.8 + \ y * (7189466.438 + \ y * (47447.26470 + \ y * (226.1030244 + y)))) ans1 / ans2 + 0.636619772 * bes_j0(x) * log(x) else z = 8.0 / x y = z * z xx = x - 0.785398164 ans1 = 1.0 + y * (-0.1098628627e-2 + \ y * (0.2734510407e-4 + \ y * (-0.2073370639e-5 + \ y * 0.2093887211e-6))) ans2 = -0.1562499995e-1 + y * (0.1430488765e-3 + \ y * (-0.6911147651e-5 + \ y * (0.7621095161e-6 + \ y * -0.934945152e-7))) sqrt(0.636619772 / x) * (sin(xx) * ans1 + cos(xx) * z * ans2) end end def bes_y1_1(x) if x < 8.0 y = x * x ans1 = x * (-0.4900604943e13 + \ y * (0.1275274390e13 + \ y * (-0.5153438139e11 + \ y * (0.7349264551e9 + \ y * (-0.4237922726e7 + \ y * 0.8511937935e4))))) ans2 = 0.2499580570e14 + y * (0.4244419664e12 + \ y * (0.3733650367e10 + \ y * (0.2245904002e8 + \ y * (0.1020426050e6 + \ y * (0.3549632885e3 + y))))) ans1 / ans2 + 0.636619772 * (bes_j1(x) * log(x) - 1.0 / x) else z = 8.0 / x y = z * z xx = x - 2.356194491 ans1 = 1.0 + y * (0.183105e-2 + \ y * (-0.3516396496e-4 + \ y * (0.2457520174e-5 + \ y * -0.240337019e-6))) ans2 = 0.04687499995 + y * (-0.2002690873e-3 + \ y * (0.8449199096e-5 + \ y * (-0.88228987e-6 + \ y * 0.105787412e-6))) sqrt(0.636619772 / x) * (sin(xx) * ans1 + cos(xx) * z * ans2) end end def bes_test_y(func_sym) [0.5, 1.0, 2.0, 20.0].each do |x| snd_test_neq(snd_func(func_sym, x), snd_func("#{func_sym.to_s}_1", x), "%s(%1.1f)", func_sym, x) end 10.times do x = random(100.0) snd_test_neq(snd_func(func_sym, x), snd_func("#{func_sym.to_s}_1", x), "%s(%1.1f)", func_sym, x) end end def bes_yn_1(n, x) if n.zero? bes_y0_1(x) elsif n == 1 bes_y1_1(x) else tox = 2.0 / x byp = 0.0 by = bes_y1_1(x) bym = bes_y0_1(x) (1...n).each do |i| byp = i * tox * by - bym bym, by = by, byp end by end end def bes_test_yn 10.times do |k| 10.times do |i| x = random(100.0) snd_test_neq(bes_yn(k, x) / bes_yn_1(k, x), 1.0, "bes_yn(%d, %1.1f)", k, x) end end end def bes_i0_1(x) if x.abs < 3.75 y = (x / 3.75) ** 2 1.0 + y * (3.5156229 + \ y * (3.0899424 + \ y * (1.2067492 + \ y * (0.2659732 + \ y * (0.360768e-1 + \ y * 0.45813e-2))))) else ax = x.abs y = 3.75 / ax (exp(ax) / sqrt(ax)) * (0.39894228 + \ y * (0.1328592e-1 + \ y * (0.225319e-2 + \ y * (-0.157565e-2 + \ y * (0.916281e-2 + \ y * (-0.2057706e-1 + \ y * (0.2635537e-1 + \ y * (-0.1647633e-1 + \ y * 0.392377e-2)))))))) end end def bes_test_i0 [0.0, 0.5, 1.0, 2.0, 0.01].each do |x| snd_test_neq(bes_i0(x), bes_i0_1(x), "bes_i0(%1.1f)", x) end 10.times do x = random(1.0) snd_test_neq(bes_i0(x), bes_i0_1(x), "bes_i0(%1.1f)", x) end end def bes_i1(x) if x.abs < 3.75 y = (x / 3.75) ** 2 x * (0.5 + \ y * (0.87890594 + \ y * (0.51498869 + \ y * (0.15084934 + \ y * (0.2658733e-1 + \ y * (0.301532e-2 + \ y * 0.32411e-3)))))) else ax = x.abs y = 3.75 / ax ans1 = 0.2282967e-1 + y * (-0.2895312e-1 + \ y * (0.1787654e-1 + \ y * -0.420059e-2)) ans2 = 0.39894228 + y * (-0.3988024e-1 + \ y * (-0.362018e-2 + \ y * (0.163801e-2 + \ y * (-0.1031555e-1 + y * ans1)))) exp(ax) / sqrt(ax) * ans2 * (x < 0 ? -1 : 1) end end def bes_test_i1 [[ 1.0, 0.565159], [ 2.0, 1.59063685], [ 5.0, 24.33564], [10.0, 2670.9883]].each do |n, x| snd_test_neq(bes_i1(n), x, "bes_i1 %1.1f", n) end end def bes_in(n, x) if n.zero? bes_i0(x) elsif n == 1 bes_i1(x) elsif x.zero? 0.0 else iacc = 40.0 ans = 0.0 bigno = 1.0e10 bigni = 1.0e-10 tox = 2.0 / x.abs bip = 0.0 bi = 1.0 bim = 0.0 m = 2 * (n + sqrt(iacc * n).floor) m.downto(1) do |i| bim = bip + i * tox * bi bip, bi = bi, bim if bi.abs > bigno ans *= bigni bi *= bigni bip *= bigni end if i == n ans = bip end end if x < 0 and n.odd? ans = -ans end ans * (bes_i0(x) / bi) end end def bes_test_in [[ 1, 0.565159, 1.5906368, 24.33564], [ 2, 0.13574767, 0.6889484, 17.505615], [ 3, 0.02216842, 0.21273995, 10.331150], [ 5, 2.71463e-4, 0.009825679, 2.157974], [10, 2.752948e-10, 3.016963e-7, 0.004580044]].each do |n, x1, x2, x5| snd_test_neq(bes_in(n, 1.0), x1, "bes_in %d 1.0", n) snd_test_neq(bes_in(n, 2.0), x2, "bes_in %d 2.0", n) snd_test_neq(bes_in(n, 5.0), x5, "bes_in %d 5.0", n) end end def bes_k0(x) if x <= 2.0 y = x * (x / 4.0) -log(x / 2.0) * bes_i0(x) + -0.57721566 + y * (0.42278420 + \ y * (0.23069756 + \ y * (0.3488590e-1 + \ y * (0.262698e-2 + \ y * (0.10750e-3 + \ y * 0.74e-5))))) else y = 2.0 / x (exp(-x) / sqrt(x)) * \ (1.25331414 + \ y * (-0.7832358e-1 + \ y * (0.2189568e-1 + \ y * (-0.1062446e-1 + \ y * (0.587872e-2 + \ y * (-0.251540e-2 + \ y * -0.53208e-3)))))) end end def bes_test_k0 [[ 1.0, 0.4210244], [ 2.0, 0.1138938], [10.0, 1.7780e-5]].each do |n, x| snd_test_neq(bes_k0(n), x, "bes_k0 %1.1f", n) end end def bes_k1(x) if x <= 2.0 y = x * (x / 4.0) log(x / 2.0) * bes_i1(x) + 1.0 / x * (1.0 + \ y * (0.15443144 + \ y * (-0.67278579 + \ y * (-0.18156897 + \ y * (-0.1919402e-1 + \ y * (-0.110404e-2 + \ y * -0.4686e-4)))))) else y = 2.0 / x (exp(-x) / sqrt(x)) * \ (1.25331414 + \ y * (0.23498619 + \ y * (-0.3655620e-1 + \ y * (0.1504268e-1 + \ y * (0.780353e-2 + \ y * (0.325614e-2 + \ y * -0.68245e-3)))))) end end def bes_test_k1 [[ 1.0, 0.60190723], [ 2.0, 0.1398658], [10.0, 1.86487e-5]].each do |n, x| snd_test_neq(bes_k1(n), x, "bes_k1 %1.1f", n) end end def bes_kn(n, x) if n.zero? bes_k0(x) elsif n == 1 bes_k1(x) else tox = 2.0 / x bkp = 0.0 bk = bes_k1(x) bkm = bes_k0(x) (1...n).each do |i| bkp = i * tox * bk + bkm bkm, bk = bk, bkp end bk end end def bes_test_kn [[1, 0.6019072, 0.139865, 0.00404461], [2, 1.6248389, 0.2537597, 0.0053089], [3, 7.1012629, 0.6473854, 0.0082917], [5, 360.96059, 9.431049, 0.0327062]].each do |n, x1, x2, x5| snd_test_neq(bes_kn(n, 1.0), x1, "bes_kn %d 1.0", n) snd_test_neq(bes_kn(n, 2.0), x2, "bes_kn %d 2.0", n) snd_test_neq(bes_kn(n, 5.0), x5, "bes_kn %d 5.0", n) end end def gammln(x) stp = 2.5066282746310005 tmp = x + 5.5 tmp1 = tmp - ((x + 0.5) * log(tmp)) ser = 1.000000000190015 + 76.18009172947146 / (x + 1.0) + -86.50532032941677 / (x + 2.0) + 24.01409824083091 / (x + 3.0) + -1.231739572450155 / (x + 4.0) + 0.1208650973866179e-2 / (x + 5.0) + -0.5395239384953e-5 / (x + 6.0) log((stp * ser) / x) - tmp1 end def test_lgamma 10.times do x = random(100.0) res1 = lgamma(x) res2 = gammln(x) if array?(res1) # XXX: Ruby 1.9+ returns an array res1 = res1[0] end snd_test_neq(res1, res2, "lgamma(%1.1f)", x) end end def test_erf [[0.0, 0.0], [0.5, 0.5204998], [1.0, 0.8427007]].each do |n, x| snd_test_neq(erf(n), x, "erf(%1.1f)", n) end 10.times do val = random(2.0) res1 = erf(val) res2 = erfc(val) snd_test_neq(res1 + res2, 1.0, "erf+erfc erf %1.4f erfc %1.4f)", res1, res2) end end def inverse_haar(f) n = f.length g = Vct.new(n) s2 = sqrt(2.0) v = 1.0 / sqrt(n) f[0] *= v m = 2 until m > n mh = m / 2 k = 0 0.step(m - 1, 2) do |j| x = f[k] y = f[mh + k] * v g[j] = x + y g[j + 1] = x - y k += 1 end (m - 1).downto(0) do |i| f[i] = g[i] end v *= s2 m *= 2 end f end def wavelet(data, n, isign, wf, cc) cc_size = cc.length sig = -1.0 j = cc_size - 1 ccr = Vct.new(cc_size) cc.each do |val| ccr[j] = val * sig j -= 1 sig = -sig end if n >= 4 if isign >= 0 nn = n until nn < 4 snd_func(wf, data, nn, isign, cc, ccr) nn /= 2 end else nn = 4 until nn > n snd_func(wf, data, nn, isign, cc, ccr) nn *= 2 end end end end def pwt(data, n, isign, cc, cr) data1 = Vct.new(n) n1 = n - 1 ncof = cc.length nmod = ncof * n nh = (n / 2.0).floor ioff = joff = -(ncof / 2.0).floor ii = 0 if isign >= 0 1.step(n, 2) do |i| ni = i + nmod + ioff nj = i + nmod + joff 1.upto(ncof) do |k| jf = n1 & (ni + k) jr = n1 & (nj + k) data1[ii] = data1[ii] + cc[k - 1] * data[jf] data1[ii + nh] = data1[ii + nh] + cr[k - 1] * data[jr] end ii += 1 end else 1.step(n, 2) do |i| ai = data[ii] ai1 = data[ii + nh] ni = i + nmod + ioff nj = i + nmod + joff 1.upto(ncof) do |k| jf = n1 & (ni + k) jr = n1 & (nj + k) data1[jf] = data1[jf] + cc[k - 1] * ai data1[jr] = data1[jr] + cr[k - 1] * ai1 end ii += 1 end end data1.map_with_index do |val, i| data[i] = val end end def corr(x, y, n, m) r = Vct.new(m + 1) (m + 1).times do |i| r[i] = 0.0 (n - i).times do |j| r[i] = r[i] + x[j + i] * y[j] end end r end def cross_correlate_3(rl1, rl2, fftlen) fftscale = 1.0 / fftlen im1 = Vct.new(fftlen) im2 = Vct.new(fftlen) fft(rl1, im1, 1) fft(rl2, im2, 1) tmprl = rl1.dup tmpim = im1.dup tmprl *= rl2 tmpim *= im2 im2 *= rl1 rl2 *= im1 tmprl += tmpim im2 -= rl2 fft(tmprl, im2, -1).scale(fftscale) end def automorph(a, b, c, d, snd = false, chn = false) len = framples(snd, chn) pow2 = (log(len) / log(2)).ceil.to_i fftlen = (2 ** pow2).round fftscale = 1.0 / fftlen rl = channel2vct(0, fftlen, snd, chn) im = Vct.new(fftlen) fft(rl, im, 1) rl.scale!(fftscale) im.scale!(fftscale) c1 = Complex(rl[0], im[0]) val = (a * c1 + b) / (c * c1 + d) rval = val.real ival = val.imag rl[0] = rval im[0] = ival k = fftlen - 1 (1..(fftlen / 2)).each do |i| c1 = Complex(rl[i], im[i]) val = (a * c1 + b) / (c * c1 + d) rval = val.real ival = val.imag rl[i] = rval im[i] = ival rl[k] = rval im[k] = -ival k -= 1 end fft(rl, im, -1) vct2channel(rl, 0, len, snd, chn, false, format("%s(%s, %s, %s, %s", get_func_name, a, b, c, d)) end sqrt2 = 1.41421356237309504880168872420969808 sqrt15 = 3.87298334620741688517927 $wts = {[:daub4, 0] => vct(0.4829629131445341, 0.8365163037378079, 0.2241438680420134, -0.1294095225512604), [:daub6, 1] => vct(0.332670552950, 0.806891509311, 0.459877502118, -0.135011020010, -0.085441273882, 0.035226291886), [:daub8, 2] => vct(0.230377813309, 0.714846570553, 0.630880767930, -0.027983769417, -0.187034811719, 0.030841381836, 0.032883011667, -0.010597401785), [:daub10, 3] => vct(0.160102397974, 0.603829269797, 0.724308528438, 0.138428145901, -0.242294887066, -0.032244869585, 0.077571493840, -0.006241490213, -0.012580751999, 0.003335725285), [:daub12, 4] => vct(0.111540743350, 0.494623890398, 0.751133908021, 0.315250351709, -0.226264693965, -0.129766867567, 0.097501605587, 0.027522865530, -0.031582039317, 0.000553842201, 0.004777257511, -0.001077301085), [:daub14, 5] => vct(0.077852054085, 0.396539319482, 0.729132090846, 0.469782287405, -0.143906003929, -0.224036184994, 0.071309219267, 0.080612609151, -0.038029936935, -0.016574541631, 0.012550998556, 0.000429577973, -0.001801640704, 0.000353713800), [:daub16, 6] => vct(0.054415842243, 0.312871590914, 0.675630736297, 0.585354683654, -0.015829105256, -0.284015542962, 0.000472484574, 0.128747426620, -0.017369301002, -0.044088253931, 0.013981027917, 0.008746094047, -0.004870352993, -0.000391740373, 0.000675449406, -0.000117476784), [:daub18, 7] => vct(0.038077947364, 0.243834674613, 0.604823123690, 0.657288078051, 0.133197385825, -0.293273783279, -0.096840783223, 0.148540749338, 0.030725681479, -0.067632829061, 0.000250947115, 0.022361662124, -0.004723204758, -0.004281503682, 0.001847646883, 0.000230385764, -0.000251963189, 0.000039347320), [:daub20, 8] => vct(0.026670057901, 0.188176800077, 0.527201188931, 0.688459039453, 0.281172343661, -0.249846424327, -0.195946274377, 0.127369340336, 0.093057364604, -0.071394147166, -0.029457536822, 0.033212674059, 0.003606553567, -0.010733175483, 0.001395351747, 0.001992405295, -0.000685856695, -0.000116466855, 0.000093588670, -0.000013264203), [:battle_lemarie, 9] => vct(sqrt2 * -0.002, sqrt2 * -0.003, sqrt2 * 0.006, sqrt2 * 0.006, sqrt2 * -0.013, sqrt2 * -0.012, sqrt2 * 0.030, sqrt2 * 0.023, sqrt2 * -0.078, sqrt2 * -0.035, sqrt2 * 0.307, sqrt2 * 0.542, sqrt2 * 0.307, sqrt2 * -0.035, sqrt2 * -0.078, sqrt2 * 0.023, sqrt2 * 0.030, sqrt2 * -0.012, sqrt2 * -0.013, sqrt2 * 0.006, sqrt2 * 0.006, sqrt2 * -0.003, sqrt2 * -0.002, 0.0), [:burt_adelson, 10] => vct(sqrt2 * (-1.0 / 20.0), sqrt2 * (5.0 / 20.0), sqrt2 * (12.0 / 20.0), sqrt2 * (5.0 / 20.0), sqrt2 * (-1.0 / 20.0), 0.0), [:beylkin, 11] => vct(0.099305765374353, 0.424215360812961, 0.699825214056600, 0.449718251149468, -0.110927598348234, -0.264497231446384, 0.026900308803690, 0.155538731877093, -0.017520746266529, -0.088543630622924, 0.019679866044322, 0.042916387274192, -0.017460408696028, -0.014365807968852, 0.010040411844631, 0.0014842347824723, -0.002736031626258, 0.0006404853285212), [:coif2, 12] => vct((sqrt2 * (sqrt15 - 3)) / 32.0, (sqrt2 * (1 - sqrt15)) / 32.0, (sqrt2 * (6 - 2 * sqrt15)) / 32.0, (sqrt2 * (2 * sqrt15 + 6)) / 32.0, (sqrt2 * (sqrt15 + 13)) / 32.0, (sqrt2 * (9 - sqrt15)) / 32.0), [:coif4, 13] => vct(0.0011945726958388, -0.01284557955324, 0.024804330519353, 0.050023519962135, -0.15535722285996, -0.071638282295294, 0.57046500145033, 0.75033630585287, 0.28061165190244, -0.0074103835186718, -0.014611552521451, -0.0013587990591632), [:coif6, 14] => vct(-0.0016918510194918, -0.00348787621998426, 0.019191160680044, 0.021671094636352, -0.098507213321468, -0.056997424478478, 0.45678712217269, 0.78931940900416, 0.38055713085151, -0.070438748794943, -0.056514193868065, 0.036409962612716, 0.0087601307091635, -0.011194759273835, -0.0019213354141368, 0.0020413809772660, 0.00044583039753204, -0.00021625727664696), [:sym2, 15] => vct(sqrt2 * -0.125, sqrt2 * 0.25, sqrt2 * 0.75, sqrt2 * 0.25, sqrt2 * -0.125), [:sym3, 16] => vct(sqrt2 / 8.0, (sqrt2 * 3.0) / 8.0, (sqrt2 * 3.0) / 8.0, sqrt2 / 8.0), [:sym4, 17] => vct((sqrt2 * 3.0) / 128.0, (sqrt2 * -6.0) / 128.0, (sqrt2 * -16.0) / 128.0, (sqrt2 * 38.0) / 128.0, (sqrt2 * 90.0) / 128.0, (sqrt2 * 38.0) / 128.0, (sqrt2 * -16.0) / 128.0, (sqrt2 * -6.0) / 128.0, (sqrt2 * 3.0) / 128.0, 0.0), [:sym5, 18] => vct((sqrt2 * 3.0) / 64.0, (sqrt2 * -9.0) / 64.0, (sqrt2 * -7.0) / 64.0, (sqrt2 * 45.0) / 64.0, (sqrt2 * 45.0) / 64.0, (sqrt2 * -7.0) / 64.0, (sqrt2 * -9.0) / 64.0, (sqrt2 * 3.0) / 64.0), [:sym6, 19] => vct((sqrt2 * -35.0) / 16384.0, (sqrt2 * -105.0) / 16384.0, (sqrt2 * -195.0) / 16384.0, (sqrt2 * 865.0) / 16384.0, (sqrt2 * 363.0) / 16384.0, (sqrt2 * -3489.0) / 16384.0, (sqrt2 * -307.0) / 16384.0, (sqrt2 * 11025.0) / 16384.0, (sqrt2 * 11025.0) / 16384.0, (sqrt2 * -307.0) / 16384.0, (sqrt2 * -3489.0) / 16384.0, (sqrt2 * 363.0) / 16384.0, (sqrt2 * 865.0) / 16384.0, (sqrt2 * -195.0) / 16384.0, (sqrt2 * -105.0) / 16384.0, (sqrt2 * -35.0) / 16384.0)} def test_20_00 # check small transform cases index = open_sound("oboe.snd") set_transform_graph?(true) [$fourier_transform, $wavelet_transform, $autocorrelation, $walsh_transform, $cepstrum, $haar_transform].each do |transform| set_transform_type(transform) [8, 7, -7, 4, 3, 2, 1, 0].each do |size| Snd.catch do set_transform_size(size) update_transform_graph end end end close_sound(index) # # fft # d0 = Vct.new(16) d0[0] = 1.0 snd_transform($fourier_transform, d0, 0) d0.each_with_index do |val, i| if fneq(val, 1.0) snd_display("fourier (1.0) [%s]: %s?", i, val) end end d0 = Vct.new(16) d0[0] = 1.0 snd_transform($fourier_transform, d0, 0) d0.each_with_index do |val, i| if fneq(val, 1.0) snd_display("fourier (1.0) [%s]: %s?", i, val) end end snd_transform($fourier_transform, d0, 0) d0.each_with_index do |val, i| if i.zero? if fneq(val, 256.0) and fneq(val, 361.0) snd_display("fourier (256.0) [%s]: %s?", i, val) end else if fneq(val, 0.0) snd_display("fourier (0.0) [%s]: %s?", i, val) end end end # r0 = Vct.new(8) i0 = Vct.new(8) r1 = Vct.new(8) i1 = Vct.new(8) r2 = Vct.new(8) i2 = Vct.new(8) r0[1] = 0.5 r1[3] = 0.75 r2[1] = 0.25 r2[3] = 0.25 mus_fft(r0, i0) mus_fft(r1, i1) mus_fft(r2, i2) r0.scale!(0.5) i0.scale!(0.5) r1.scale!(0.3333) i1.scale!(0.3333) r0.add!(r1) i0.add!(i1) if (not vequal(r0, r2)) or (not vequal(i0, i2)) snd_display("fft additions/scaling: %s %s: %s %s?", r2, i2, r0, i0) end # d0 = Vct.new(8) d1 = Vct.new(8) d0[2] = 1.0 mus_fft(d0, d1, 8, 1) if (not vequal(d0, vct(1.000, 0.000, -1.000, -0.000, 1.000, 0.000, -1.000, -0.000))) or (not vequal(d1, vct(0.000, 1.000, 0.000, -1.000, 0.000, 1.000, 0.000, -1.000))) snd_display("mus_fft 1: %s %s?", d0, d1) end mus_fft(d0, d1, 8, -1) if (not vequal(d0, vct(0.000, 0.000, 8.000, 0.000, 0.000, 0.000, 0.000, 0.000))) or (not vequal(d1, vct(0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000))) snd_display("mus_fft -1: %s %s?", d0, d1) end d0.fill(1.0) d1.fill(0.0) mus_fft(d0, d1, 8) if (not vequal(d0, vct(8.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000))) or (not vequal(d1, vct(0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000))) snd_display("mus_fft 2: %s %s?", d0, d1) end mus_fft(d0, d1, 8, -1) if (not vequal(d0, vct(8.000, 8.000, 8.000, 8.000, 8.000, 8.000, 8.000, 8.000))) or (not vequal(d1, vct(0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000))) snd_display("mus_fft -2: %s %s?", d0, d1) end d1.fill 0.0 d0.map! do |val| random(1.0) end fn = d0.dup mus_fft(d0, d1, 8) mus_fft(d0, d1, 8, -1) d0.scale! 1.0 / 8.0 unless vequal(d0, fn) snd_display("mus_fft 3: %s %s?", d0, fn) end d0 = Vct.new(8) do 1.0 - random(2.0) end d1 = Vct.new(8) do 1.0 - random(2.0) end save_d0 = d0.dup save_d1 = d1.dup reversed_d0 = Vct.new(8) do |i| d0[7 - i] end reversed_d1 = Vct.new(8) do |i| d1[7 - i] end mus_fft(d0, d1, 8) mus_fft(d0, d1, 8) d0.scale!(0.125) d1.scale!(0.125) 7.times do |i| if fneq(d0[i + 1], reversed_d0[i]) snd_display("mus_fft d0 reversed: %s %s?", d0, reversed_d0) end if fneq(d1[i + 1], reversed_d1[i]) snd_display("mus_fft d1 reversed: %s %s?", d1, reversed_d1) end end mus_fft(d0, d1, 8) mus_fft(d0, d1, 8) d0.scale!(0.125) d1.scale!(0.125) unless vequal(d0, save_d0) snd_display("mus_fft d0 saved: %s %s?", d0, saved_d0) end unless vequal(d1, save_d1) snd_display("mus_fft d1 saved: %s %s?", d1, saved_d1) end catch(:done) do [8, 16].each do |size| d0 = Vct.new(size) d0[0] = 1.0 dcopy = d0.dup d1 = snd_spectrum(d0, Rectangular_window, size) unless vequal(d0, dcopy) snd_display("snd_specrum not in-place?: %s %s?", d0, dcopy) end (size / 2).times do |i| if fneq(d1[i], 1.0) snd_display("snd_spectrum (1.0) [%s: %s]: %s?", i, size, d1[i]) end end d0 = Vct.new(size, 1.0) d1 = snd_spectrum(d0, Rectangular_window) if fneq(d1[0], 1.0) snd_display("snd_spectrum back (1.0 %s): %s?", size, d1[0]) end (1...(size / 2)).each do |i| if fneq(d1[i], 0.0) snd_display("snd_spectrum (0.0) [%s: %s]: %s?", i, size, d1[i]) throw(:done) end end d0 = Vct.new(size) d0[0] = 1.0 d1 = snd_spectrum(d0, Rectangular_window, size, false) # dB (0.0 = max) (size / 2).times do |i| if fneq(d1[i], 0.0) snd_display("snd_spectrum dB (0.0) [%s: %s]: %s?", i, size, d1[i]) throw(:done) end end d0 = Vct.new(size, 1.0) d1 = snd_spectrum(d0, Rectangular_window, size, false) if fneq(d1[0], 0.0) snd_display("snd_spectrum dB back (0.0 %s): %s?", size, d1[0]) end (1...(size / 2)).each do |i| if fneq(d1[i], -90.0) # currently ignores min-dB (snd-sig.c 5023) snd_display("snd_spectrum dB (1.0) [%s: %s]): %s?", i, size, d1[i]) throw(:done) end end d0 = Vct.new(size) d0[0] = 1.0 dcopy = d0.dup d1 = snd_spectrum(d0, Rectangular_window, size, true, 1.0, true) # in-place if vequal(d0, dcopy) snd_display("snd_spectrum in-place: %s %s?", d0, dcopy) end unless vequal(d0, d1) snd_display("snd_spectrum returns in-place: %s %s?", d0, d1) end (size / 2).times do |i| if fneq(d1[i], 1.0) snd_display("snd_spectrum dB (1.0 true) [%s: %s]: %s?", i, size, d1[i]) throw(:done) end end d0 = Vct.new(size) d0[0] = 1.0 dcopy = d0.dup d1 = snd_spectrum(d0, Rectangular_window, size, false, 1.0, true) # in-place dB if vequal(d0, dcopy) snd_display("snd_spectrum dB in-place: %s %s?", d0, dcopy) end unless vequal(d0, d1) snd_display("snd_spectrum returns dB in-place: %s %s?", d0, d1) end (size / 2).times do |i| if fneq(d1[i], 0.0) snd_display("snd_spectrum dB (1.0 true) [%s: %s]: %s?", i, size, d1[i]) throw(:done) end end d0 = Vct.new(size, 1.0) d1 = snd_spectrum(d0, Rectangular_window, size, true, 0.0, false, false) # linear (in-place) if fneq(d1[0], size.to_f) snd_display("snd_spectrum no more 0: %s?", d1) end (1...(size / 2)).each do |i| if fneq(d1[i], 0.0) snd_display("snd_spectrum no more (0.0) [%s: %s]: %s?", i, size, d1[i]) throw(:done) end end d0 = Vct.new(size, 1.0) d1 = snd_spectrum(d0, Blackman2_window, size) if (not vequal(d1, vct(1.000, 0.721, 0.293, 0.091))) and (not vequal(d1, vct(1.000, 0.647, 0.173, 0.037, 0.024, 0.016, 0.011, 0.005))) snd_display("blackman2 snd_spectrum: %s?", d1) end d0 = Vct.new(size, 1.0) d1 = snd_spectrum(d0, Gaussian_window, size, true, 0.5) if (not vequal(d1, vct(1.000, 0.900, 0.646, 0.328))) and (not vequal(d1, vct(1.000, 0.870, 0.585, 0.329, 0.177, 0.101, 0.059, 0.028))) snd_display("gaussian 0.5 snd_spectrum: %s?", d1) end d0 = Vct.new(size, 1.0) d1 = snd_spectrum(d0, Gaussian_window, size, true, 0.85) if (not vequal(d1, vct(1.000, 0.924, 0.707, 0.383))) and (not vequal(d1, vct(1.000, 0.964, 0.865, 0.725, 0.566, 0.409, 0.263, 0.128))) snd_display("gaussian 0.85 snd_spectrum: %s?", d1) end end end # catch(:done) do [16, 128, 512, 1024].each do |len| rl = Vct.new(len, 1.0) xrl = Vct.new(len, 1.0) len2 = len / 2 snd_transform($fourier_transform, rl) snd_transform($fourier_transform, xrl, true) len2.times do |i| if fneq(rl[i], xrl[i]) snd_display("flat fft: %s at %s: %s %s?", len, i, rl[i], xrl[i]) throw(:done) end end if fneq(rl[0], len * len.to_f) snd_display("%s at 0: %s?", len, rl[0]) end rl[0] = 0.0 if rl.peak > 0.001 snd_display("%s impulse: %s?", len, rl.peak) end end end catch(:done) do [16, 128, 512, 1024].each do |len| rl = Vct.new(len) xrl = Vct.new(len) len2 = len / 2 rl[len2] = 1.0 xrl[len2] = 1.0 snd_transform($fourier_transform, rl) snd_transform($fourier_transform, xrl, true) len2.times do |i| if fneq(rl[i], xrl[i]) snd_display("impulse fft: %s at %s: %s %s?", len, i, rl[i], xrl[i]) throw(:done) end end if fneq(rl[0], 1.0) snd_display("flat %s at 0: %s?", len, rl[0]) end end end catch(:done) do [16, 128, 512, 1024, 4096].each do |len| rl = Vct.new(len) xrl = Vct.new(len) do |i| rl[i] = random(1.0) end len2 = len / 2 rl[len2] = 1.0 xrl[len2] = 1.0 snd_transform($fourier_transform, rl) rl.scale!(1.0 / len) snd_transform($fourier_transform, xrl, true) xrl.scale!(1.0 / len) len2.times do |i| if fneq(rl[i], xrl[i]) snd_display("random fft: %s at %s: %s %s?", len, i, rl[i], xrl[i]) throw(:done) end end end end catch(:done) do [16, 128, 512, 1024, 4096].each do |len| rl = Vct.new(len) xrl = Vct.new(len) do |i| rl[i] = sin((TWO_PI * 10.0 * i) / len) end len2 = len / 2 rl[len2] = 1.0 xrl[len2] = 1.0 snd_transform($fourier_transform, rl) rl.scale!(1.0 / len) snd_transform($fourier_transform, xrl, true) xrl.scale!(1.0 / len) len2.times do |i| if fneq(rl[i], xrl[i]) snd_display("sin fft: %s at %s: %s %s?", len, i, rl[i], xrl[i]) throw(:done) end end end end # # autocorrelation # rl = Vct.new(16) rl[0] = 1.0 autocorrelate(rl) unless vequal(rl, vct(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) snd_display("autocorrelate 1: %s?", rl) end rl = Vct.new(16) rl[0] = 1.0 rl[1] = -1.0 autocorrelate(rl) unless vequal(rl, vct(2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) snd_display("autocorrelate 1 -1: %s?", rl) end rl = Vct.new(16) rl[0] = 1.0 rl[4] = -1.0 autocorrelate(rl) unless vequal(rl, vct(2, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) snd_display("autocorrelate 1 0 0 0 -1: %s?", rl) end rl = Vct.new(16) rl1 = Vct.new(16) 8.times do |i| rl[i] = rl1[i] = 8.0 - 1 end nr = vct_subseq(corr(rl, rl, 16, 16), 0, 15) autocorrelate(rl1) unless vequal(rl1, nr) snd_display("autocorrelate/corr (ramp): %s?", rl1, nr) end rl = Vct.new(16) rl1 = Vct.new(16) 8.times do |i| rl[i] = rl1[i] = 1.0 - random(2.0) end nr = vct_subseq(corr(rl, rl, 16, 16), 0, 15) autocorrelate(rl1) unless vequal(rl1, nr) snd_display("autocorrelate/corr: %s?", rl1, nr) end # catch(:done) do [16, 64, 256, 512].each do |len| rl = Vct.new(len) rla = Vct.new(len) xim = Vct.new(len) xrl = Vct.new(len) len2 = len / 2 rl[0] = 1.0 rl[4] = 1.0 snd_transform($autocorrelation, rl, 0) if fneq(rl[0], 2.0) snd_display("autocorrelation %s 0: %s?", len, rl[0]) end if fneq(rl[4], 1.0) snd_display("autocorrelation %s 4: %s?", len, rl[0]) end rla[0] = 1.0 rla[4] = 1.0 autocorrelate(rla) if fneq(rla[0], 2.0) snd_display("autocorrelate %s 0: %s?", len, rla[0]) end if fneq(rla[4], 1.0) snd_display("autocorrelate %s 4: %s?", len, rla[0]) end xrl[0] = 1.0 xrl[4] = 1.0 mus_fft(xrl, xim, len, 1) xrl.map_with_index! do |val, i| val * val + xim[i] * xim[i] end xim.scale! 0.0 mus_fft(xrl, xim, len, -1) xrl.scale! 1.0 / len len2.times do |i| if fneq(rl[i], xrl[i]) snd_display("%s at %s: %s %s?", len, i, rl[i], xrl[i]) throw(:done) end end rl[0] = 0.0 rl[4] = 0.0 (len / 2).upto(len - 1) do |i| rl[i] = 0.0 end if rl.peak > 0.001 snd_display("autocorrelate peak: %s?", rl.peak) end end end catch(:done) do [16, 64, 256, 512].each do |len| rl = Vct.new(len) xim = Vct.new(len) xrl = Vct.new(len) len2 = len / 2 ones = [2, random(len2)].max ones.times do ind = random(len) rl[ind] = xrl[ind] = random(1.0) end snd_transform($autocorrelation, rl, 0) mus_fft(xrl, xim, len, 1) xrl[0] *= xrl[0] xrl[len2] *= xrl[len2] j = len - 1 (1...len2).each do |i| xrl[j] = xrl[i] = xrl[i] * xrl[i] + xim[j] * xim[j] j -= 1 end xim.scale! 0.0 mus_fft(xrl, xim, len, -1) xrl.scale! 1.0 / len len2.times do |i| if fneq(rl[i], xrl[i]) snd_display("random %s at %s: %s %s?", len, i, rl[i], xrl[i]) throw(:done) end end end end # # cepstrum # rl = vct(0.423618, 0.259318, -0.048365, 1.140571, -0.811856, -0.994098, -0.998613, -2.453642, -0.438549, -1.520463, -0.312065, -0.724707, 1.154010, 1.466936, 0.110463, -1.520854) nrl = snd_transform($cepstrum, rl, 0).scale(1.399) unless vequal(nrl, vct(1.3994950, 0.1416877, 0.0952407, 0.0052814, -0.0613192, 0.0082986, -0.0233993, -0.0476585, 0.0259498, -0.0476585, -0.0233993, 0.0082986, -0.0613192, 0.0052814, 0.0952407, 0.1416877)) snd_display("cepstrum 16: %s?", nrl) end rl = Vct.new(16) do |i| i end nrl = snd_transform($cepstrum, rl, 0).scale(2.72) unless vequal(nrl, vct(2.720, 0.452, 0.203, 0.122, 0.082, 0.061, 0.048, 0.041, 0.039, 0.041, 0.048, 0.061, 0.082, 0.122, 0.203, 0.452)) snd_display("cepstrum 16 by ones: %s?", nrl) end catch(:done) do [16, 64, 256, 512].each do |len| rl = Vct.new(len) xim = Vct.new(len) xrl = Vct.new(len) rl[0] = 1.0 rl[4] = 1.0 snd_transform($cepstrum, rl, 0) xrl[0] = 1.0 xrl[4] = 1.0 mus_fft(xrl, xim, len, 1) xrl.map_with_index! do |xval, i| if (val = xval * xval + xim[i] * xim[i]) > 0.0000001 log(sqrt(val)) else -10.0 end end xim.scale! 0.0 mus_fft(xrl, xim, len, -1) fscl = 0.0 xrl.each do |val| fscl = [fscl, val.abs].max end xrl.scale! 1.0 / fscl rl.each_with_index do |val, i| if fneq(val, xrl[i]) snd_display("%s at %s: %s %s?", len, i, val, xrl[i]) throw(:done) end end end end end def test_20_01 # # walsh # d0 = Vct.new(8) d0[0] = 1.0 snd_transform($walsh_transform, d0) unless vequal(d0, Vct.new(8, 1.0)) snd_display("walsh 1: %s?", d0) end snd_transform($walsh_transform, d0) unless vequal(d0, vct(8, 0, 0, 0, 0, 0, 0, 0)) snd_display("walsh -1: %s?", d0) end # d0 = Vct.new(8) d0[1] = 1.0 snd_transform($walsh_transform, d0) unless vequal(d0, vct(1, -1, 1, -1, 1, -1, 1, -1)) snd_display("walsh 2: %s?", d0) end snd_transform($walsh_transform, d0) unless vequal(d0, vct(0, 8, 0, 0, 0, 0, 0, 0)) snd_display("walsh -2: %s?", d0) end # d0 = Vct.new(8) d0[0] = 0.5 d0[1] = 1.0 snd_transform($walsh_transform, d0) unless vequal(d0, vct(1.5, -0.5, 1.5, -0.5, 1.5, -0.5, 1.5, -0.5)) snd_display("walsh 3: %s?", d0) end snd_transform($walsh_transform, d0) unless vequal(d0, vct(4, 8, 0, 0, 0, 0, 0, 0)) snd_display("walsh -3: %s?", d0) end # d0 = Vct.new(8) do random(1.0) end d1 = d0.dup snd_transform($walsh_transform, d0) snd_transform($walsh_transform, d0) d0.scale! 1.0 / 8.0 unless vequal(d0, d1) snd_display("walsh 4: %s %s?", d0, d1) end # d0 = vct(1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1) d1 = snd_transform($walsh_transform, d0) unless vequal(d1, vct(4, 4, 4, -4, 4, 4, 4, -4, 4, 4, 4, -4, -4, -4, -4, 4)) snd_display("walsh 5: %s?", d1) end # d0 = vct(1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) d1 = snd_transform($walsh_transform, d0) unless vequal(d1, vct(0, 2, 2, 0, 0, 2, 2, 0, 0, 2, 2, 0, 0, 2, 2, 0)) snd_display("walsh 6: %s?", d1) end d0 = vct(0.174, -0.880, -0.555, -0.879, 0.038, 0.696, -0.612, 0.006, -0.613, 0.334, -0.111, -0.821, 0.130, 0.030, -0.229, 0.170) d1 = snd_transform($walsh_transform, d0) unless vequal(d1, vct(-3.122, -0.434, 2.940, -0.468, -3.580, 2.716, -0.178, -1.386, -0.902, 0.638, 1.196, 1.848, -0.956, 2.592, -1.046, 2.926)) snd_display("walsh 7: %s?", d1) end # # haar # d0 = Vct.new(8) d0[2] = 1.0 snd_transform($haar_transform, d0) unless vequal(d0, vct(0.354, 0.354, -0.500, 0.000, 0.000, 0.707, 0.000, 0.000)) snd_display("haar 1: %s?", d0) end inverse_haar(d0) unless vequal(d0, vct(0.000, 0.000, 1.000, 0.000, 0.000, 0.000, 0.000, 0.000)) snd_display("inverse_haar 1: %s?", d0) end # d0 = Vct.new(8) d0[0] = 1.0 snd_transform($haar_transform, d0) unless vequal(d0, vct(0.354, 0.354, 0.500, 0.000, 0.707, 0.000, 0.000, 0.000)) snd_display("haar 2: %s?", d0) end inverse_haar(d0) unless vequal(d0, vct(1.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000)) snd_display("inverse_haar 2: %s?", d0) end # d0 = snd_transform($haar_transform, vct(-0.483, 0.174, -0.880, -0.555, -0.879, 0.038, 0.696, -0.612)) unless vequal(d0, vct(-0.884, -0.349, 0.563, -0.462, -0.465, -0.230, -0.648, 0.925)) snd_display("haar 3: %s?", d0) end # sq2 = sqrt(2.0) d0 = snd_transform($haar_transform, vct(4, 6, 10, 12, 8, 6, 5, 5)) unless vequal(d0, vct(14 * sq2, 2 * sq2, -6, 2, -sq2, -sq2, sq2, 0)) snd_display("haar 4: %s?", d0) end d0 = snd_transform($haar_transform, vct(2, 4, 6, 8, 10, 12, 14, 16)) unless vequal(d0, x = vct(18 * sq2, -8 * sq2, -4, -4, -sq2, -sq2, -sq2, -sq2)) snd_display("haar 5: %s?", d0, x) end # d0 = Vct.new(8) d1 = Vct.new(8) do |i| d0[i] = random(1.0) end snd_transform($haar_transform, d0) inverse_haar(d0) unless vequal(d0, d1) snd_display("inverse_haar 6: %s %s?", d0, d1) end # # wavelet # d0 = snd_transform($wavelet_transform, vct(1, 1, 0, 0, 0, 0, 0, 0), 0) # daub4 unless vequal(d0, vct(0.625, 0.375, -0.217, 1.083, -0.354, 0.000, 0.000, 0.354)) snd_display("fxt wavelet 1: %s?", d0) end [16, 64].each do |size| $wts.each do |key, val| d1 = Vct.new(size) d2 = Vct.new(size) d1[2] = 1.0 d2[2] = 1.0 wavelet(d1, size, 0, :pwt, val) snd_transform($wavelet_transform, d2, key.last) unless vequal(d1, d2) snd_display("wavelet (%s) %s:\n# %s\n# %s?", size, key, d1, d2) end wavelet(d2, size, -1, :pwt, val) d1.fill 0.0 d1[2] = 1.0 unless vequal(d1, d2) if key.last.between?(9, 10) d2[2] = 0.0 if d2.peak > 0.1 snd_display("inverse wavelet a (%s) %s:\n# %s\n# %s?", size, key, d1, d2) end else if key.last > 14 pk = d2[2] d2[2] = 0.0 if d2.peak > pk snd_display("inverse wavelet b (%s) %s:\n# %s\n# %s?", size, key, d1, d2) end else snd_display("inverse wavelet c (%s) %s:\n# %s\n# %s?", size, key, d1, d2) end end end end $wts.each do |key, val| next if key.last > 8 d2 = Vct.new(size) do random(1.0) end d1 = d2.dup snd_transform($wavelet_transform, d2, key.last) wavelet(d2, size, -1, :pwt, val) unless vequal(d1, d2) snd_display("random wavelet %s:\n# %s\n# %s?", key.first, d1, d2) end end end # set_max_transform_peaks(100) ind = open_sound("oboe.snd") ftype = add_transform("low-pass", "filtered", 0.0, 1.0, lambda { |len, fd| flt = make_fir_filter(:order, 8, :xcoeffs, Vct.new(8, 0.0125)) Vct.new(len) do fir_filter(flt, read_sample(fd)) end }) unless transform?(ftype) snd_display("transform added: %s?", ftype) end set_transform_normalization(Dont_normalize) set_transform_type(ftype, ind, 0) set_transform_size(16, ind, 0) set_transform_graph_type(Graph_once, ind, 0) set_transform_graph?(true, ind, 0) set_cursor(12000, ind, 0) samps = transform2vct(ind, 0) delete_file("s61.rb") save_state("s61.rb") delete_file("s61.rb") close_sound(ind) # ind = open_sound("oboe.snd") ftype = add_transform("abs-it", "absit", 0.0, 1.0, lambda { |len, fd| Vct.new(len) do read_sample(fd) end }) set_transform_normalization(Dont_normalize) set_transform_type(ftype, ind, 0) set_transform_size(256, ind, 0) set_transform_graph_type(Graph_once, ind, 0) set_transform_graph?(true, ind, 0) set_cursor(12000, ind, 0) samps = transform2vct(ind, 0) channel2vct(left_sample(ind, 0), 256).zip(samps) do |val1, val2| if fneq(val1, val2) snd_display("add_transform same (%s): %s %s?", ftype, val1, val2) end end set_dot_size(60, ind, 0) set_graph_style(Graph_lollipops, ind, 0) set_x_bounds([2.579, 2.580]) update_time_graph delete_transform(ftype) if transform?(ftype) snd_display("transform? deleted: %s?", ftype) end if transform?(-1) snd_display("transform? -1: %s?", ftype) end if transform?(integer2transform(123)) snd_display("transform? 123: %s?", ftype) end if (res = transform_type(ind, 0)) != $fourier_transform snd_display("after delete_transform %s -> %s?", ftype, res) end close_sound(ind) # ind1 = open_sound("oboe.snd") set_time_graph_style(Graph_lollipops, ind1, 0) graph2ps("aaa.eps") set_transform_graph?(true, ind1, 0) set_transform_graph_type(Graph_as_sonogram, ind1, 0) set_transform_size(256) update_transform_graph size = transform_framples(ind1, 0) if number?(size) or size.length != 3 snd_display("transform_framples of sonogram: %s?", size) end graph2ps("aaa.eps") old_colormap = colormap set_colormap(integer2colormap(0)) update_transform_graph set_transform_graph_type(Graph_as_spectrogram, ind1, 0) update_transform_graph graph2ps("aaa.eps") set_colormap(old_colormap) close_sound(ind1) # ind = new_sound("test.snd", :header_type, Mus_next, :sample_type, Mus_bfloat) pad_channel(0, 1000) set_transform_graph_type(Graph_once, ind, 0) set_show_transform_peaks(true, ind, 0) set_fft_log_magnitude(true, ind, 0) set_fft_log_frequency(false, ind, 0) set_transform_graph?(true, ind, 0) set_x_bounds([0.0, 0.04]) update_time_graph update_transform_graph close_sound(ind) # ind = open_sound("oboe.snd") size = 8192 v = channel2vct(1000, size, ind, 0) set_show_listener(false) set_window_height(800) set_lisp_graph?(true, ind, 0) graph(v, "biggy", 0.0, 1.0, 0.0, 1.0, ind, 0) set_transform_graph_type(Graph_once, ind, 0) set_show_transform_peaks(true, ind, 0) set_fft_log_magnitude(true, ind, 0) set_fft_log_frequency(false, ind, 0) set_transform_graph?(true, ind, 0) graph2ps("aaa.eps") set_x_bounds([0.0, 1.0]) set_max_transform_peaks(3, ind, 0) update_time_graph update_transform_graph update_lisp_graph scale_by(0.0) update_time_graph update_transform_graph undo_edit set_transform_graph_type(Graph_as_sonogram, ind, 0) set_fft_log_magnitude(false, ind, 0) update_transform_graph graph2ps("aaa.eps") set_with_gl(false) set_spectrum_end(0.2, ind, 0) set_transform_graph_type(Graph_as_spectrogram, ind, 0) update_transform_graph update_lisp_graph graph2ps("aaa.eps") set_show_listener(true) close_sound(ind) end def test_20_02 snd_test_neq(dolph(16, 2.5), vct(0.097, 0.113, 0.221, 0.366, 0.536, 0.709, 0.860, 0.963, 1.000, 0.963, 0.860, 0.709, 0.536, 0.366, 0.221, 0.113), "dolph 16 2.5 (dsp.rb)") v = Vct.new(8) v0 = Vct.new(8) do |i| v[i] = mus_random(1.0) end v = dht(dht(v)).scale(1.0 / 8.0) snd_test_any_neq(v, v0, :vvequal?, "dht twice") v.fill 0.0 v[1] = 1.0 snd_test_neq(dht(v), vct(1, 1.414, 1, 0, -1, -1.414, -1, 0), "dht of pulse") # ind = open_sound("oboe.snd") snd_test_neq(find_sine(553.0, 2000, 3000, ind).first, 0.03835, "find_sine") snd_test_neq(find_sine(620.0, 2000, 3000, ind).first, 0.0012, "find_sine") snd_test_neq(spot_freq(2000, ind, 0).round, 553, "spot_freq") down_oct(2) frq = spot_freq(2000, ind, 0) unless frq.ceil.between?(275, 277) snd_display("spot_freq down_oct: %s?", frq) end undo_edit zero_phase snd_test_neq(sample(0), 0.1472, "zero_phase") undo_edit rotate_phase(lambda do |x| x end) undo_edit brighten_slightly(0.5) undo_edit spike close_sound(ind) # ind = open_sound("1a.snd") frms = framples(ind) valf = find_sine(440.0, 0, frms, ind).first valg = 2 * (goertzel(440.0, 0, frms, ind) / frms) valf1 = find_sine(100.0, 0, frms, ind).first valg1 = 2 * (goertzel(100.0, 0, frms, ind) / frms) valf2 = find_sine(440.0, 0, frms, ind).first valg2 = 2 * (goertzel(440.0, 0, frms, ind) / frms) valf3 = find_sine(437.0, 0, frms, ind).first valg3 = 2 * (goertzel(437.0, 0, frms, ind) / frms) snd_test_neq(valg, valf, "goertzel 0") snd_test_neq(valg1, valf1, "goertzel 1") snd_test_neq(valg2, valf2, "goertzel 2") snd_test_neq(valg3, valf3, "goertzel 3") close_sound(ind) # snd_test_neq(vct_polynomial(vct(0, 2), vct(1, 2)), vct(1, 5), "vct_polynomial 0") snd_test_neq(vct_polynomial(vct(0, 1, 2), vct(0, 2, 1)), vct(0, 3, 8), "vct_polynomial 1") snd_test_neq(vct_polynomial(vct(0, 1, 2), vct(0, 2, 1, 0.5)), vct(0, 3.5, 12), "vct_polynomial 2") snd_test_neq(vct_polynomial(vct(0, 1, 2), vct(1)), vct(1, 1, 1), "vct_polynomial 3") # ind = open_sound("pistol.snd") mx = maxamp(ind, 0) channel_polynomial(vct(0, 2), ind, 0) snd_test_neq(maxamp(), mx * 2.0, "channel_polynomial 2") undo_edit channel_polynomial(vct(0.0, 0.5, 0.25, 0.25), ind, 0) snd_test_neq(maxamp(), 0.222, "channel_polynomial 3") undo_edit channel_polynomial(vct(0, 0, 1), ind, 0) if pos = scan_channel(lambda { |y| y < 0.0 }) snd_display("channel_polynomial squares: %s?", pos) end undo_edit channel_polynomial(vct(0.5, 1), ind, 0) if pos = scan_channel(lambda { |y| y < 0.0 }) snd_display("channel_polynomial offset: %s?", pos) end snd_test_neq(maxamp, 0.8575, "channel_polynomial off mx") undo_edit spectral_polynomial(vct(0, 1), ind, 0) snd_test_neq(maxamp(), 0.493, "spectral_polynomial 0 mx") snd_test_neq(framples(ind, 0), 41623, "spectral_polynomial 0 len") undo_edit spectral_polynomial(vct(0, 0.5, 0.5), ind, 0) snd_test_neq(maxamp(), 0.493, "spectral_polynomial 1 mx") snd_test_neq(framples(ind, 0), 41623 * 2, "spectral_polynomial 1 len") undo_edit spectral_polynomial(vct(0, 0, 0, 1), ind, 0) snd_test_neq(maxamp(), 0.493, "spectral_polynomial 2 mx") snd_test_neq(framples(ind, 0), 41623 * 3, "spectral_polynomial 2 len") close_sound(ind) # vals = scentroid("oboe.snd") snd_test_neq(vals[0], 1876.085, "scentroid vals[0]") snd_test_neq(vals[1], 1447.004, "scentroid vals[1]") flt = make_fir_filter(3, vct(0.5, 0.25, 0.125)) data = Vct.new(10) data[0] = 1.0 undata = Vct.new(10) do |i| fir_filter(flt, data[i]) end fdata = invert_filter(vct(0.5, 0.25, 0.125)) flt = make_fir_filter(fdata.length, fdata) undata.map! do |val| fir_filter(flt, val) end snd_test_neq(undata, data, "invert_filter") # top = 0.9 coeffs = Vct.new(6) do top -= 0.1 top + random(0.2) end flt = make_fir_filter(6, coeffs) data = Vct.new(20) data[0] = 1.0 undata = Vct.new(20) do |i| fir_filter(flt, data[i]) end fdata = invert_filter(coeffs) flt = make_fir_filter(fdata.length, fdata) undata.map! do |val| fir_filter(flt, val) end snd_test_neq(undata, data, "invert_filter (6)") # flt = make_volterra_filter(vct(1, 0.4), vct(0.3, 0.2, 0.1)) snd_test_neq(Vct.new(10) do |i| volterra_filter(flt, (i == 1 ? 0.5 : 0.0)) end, vct(0.000, 0.575, 0.250, 0.025, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000), "volterra_filter") # flt = make_volterra_filter(vct(1.0), vct(1.0)) snd_test_neq(Vct.new(10) do |i| volterra_filter(flt, (i.zero? ? 1.0 : 0.0)) end, vct(2.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000), "volterra_filter x + x^2") # flt = make_volterra_filter(vct(1.0), vct(1.0)) x = 1.1 snd_test_neq(Vct.new(10) do |i| volterra_filter(flt, x -= 0.1) end, vct(2.000, 1.710, 1.440, 1.190, 0.960, 0.750, 0.560, 0.390, 0.240, 0.110), "volterra_filter x + x^2 by -0.1") # flt = make_volterra_filter(vct(1.0, 0.5), vct(1.0)) snd_test_neq(Vct.new(10) do |i| volterra_filter(flt, (i.zero? ? 1.0 : 0.0)) end, vct(2.000, 0.500, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000), "volterra_filter x + 0.5x(n-1) + x^2") # flt = make_volterra_filter(vct(1.0, 0.5), vct(1.0, 0.6)) snd_test_neq(Vct.new(10) do |i| volterra_filter(flt, (i.zero? ? 0.9 : 0.0)) end, vct(1.710, 0.936, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000), "volterra_filter x + 0.5x(n-1) + x^2 + 0.6") # ind = new_sound("test.snd", :size, 100) gen = make_oscil(440) map_chan(lambda { |y| oscil(gen) }) down_oct(2) snd_test_neq(framples(), 200, "down_oct new len") r1 = make_sampler(0, ind, 0, 1, 1) r2 = make_sampler(0, ind, 0, 1, 2) 200.times do |i| val1 = r1.call val2 = r2.call val3 = r2.call if fneq(val1, val2) and fneq(val1, val3) snd_display(snd_format_neq(val1, val2, "down_oct[%d] %1.4f", i, val3)) end end close_sound(ind) # d0 = Vct.new(8) d1 = Vct.new(8) d0[2] = 1.0 vals = fractional_fourier_transform(d0, d1, 8, 1.0) snd_test_neq(vals[0], vct(1, 0, -1, 0, 1, 0, -1, 0), "fractional_fourier_transform vals[0]") snd_test_neq(vals[1], vct(0, 1, 0, -1, 0, 1, 0, -1), "fractional_fourier_transform vals[1]") d0 = Vct.new(8) d1 = Vct.new(8) d0[2] = 1.0 vals = z_transform(d0, 8, exp(make_rectangular(0.0, 0.25 * PI))) vals.each_with_index do |val, i| d0[i] = val.real d1[i] = val.imag end snd_test_neq(d0, vct(1, 0, -1, 0, 1, 0, -1, 0), "z_transform d0") snd_test_neq(d1, vct(0, 1, 0, -1, 0, 1, 0, -1), "z_transform d1") v1 = Vct.new(16) v1[0] = 1.0 snd_test_neq(z_transform(v1, 16, 0.5).to_vct, Vct.new(16, 1.0), "z_transform 0.5 0=1") snd_test_neq(z_transform(v1, 16, -1.0).to_vct, Vct.new(16, 1.0), "z_transform -1.0 0=1") v1[0] = 0.0 v1[1] = 1.0 snd_test_neq(z_transform(v1, 16, 0.5).to_vct, vct(1, 0.5, 0.25, 0.125, 0.062, 0.031, 0.016, 0.008, 0.004, 0.002, 0.001, 0, 0, 0, 0, 0), "z_transform 0.5 1=1") snd_test_neq(z_transform(v1, 16, 2.0).to_vct, vct(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768), "z_transform 2.0 1=1") v1[2] = 1.0 snd_test_neq(z_transform(v1, 16, 0.5).to_vct, vct(2, 0.75, 0.3125, 0.14, 0.0664, 0.0322, 0.0158, 0.00787, 0.0039, 0.0019, 0, 0, 0, 0, 0, 0), "z_transform 0.5 2=1") snd_test_neq(z_transform(v1, 16, 2.0).to_vct, vct(2, 6, 20, 72, 272, 1056, 4160, 16512, 65792, 262656, 1049600, 4196352, 16781312, 67117056, 268451840, 1073774592), "z_transform 2.0 1=1 2=1") j = 1.0 v1.map! do |ignored| val = j j *= 0.4 val end snd_test_neq(z_transform(v1, 16, 1.0).to_vct, Vct.new(16, 1.0 / (1.0 - 0.4)), "z_transform 1 0.4g") ind = open_sound("oboe.snd") automorph(Complex(0.0, 1.0), 0, 0, 1) automorph(Complex(0.0, 1.0), 0, 0, 1) automorph(Complex(0.0, 1.0), 0, 0, 1) automorph(Complex(0.0, 1.0), 0, 0, 1) mxdiff = 0.0 rd1 = make_sampler(0, ind, 0) rd2 = make_sampler(0, ind, 0, 1, 0) scan_channel(lambda do |y| diff = (rd1.call - rd2.call).abs if diff > mxdiff mxdiff = diff end false end) snd_test_gt(mxdiff, 0.003, "automorph rotation") close_sound(ind) end def test_20 if defined? bes_j0 bes_test(:bes_j0) bes_test(:bes_j1) bes_test_jn bes_test_y(:bes_y0) bes_test_y(:bes_y1) bes_test_yn bes_test_i0 bes_test_i1 bes_test_in bes_test_k0 bes_test_k1 bes_test_kn test_lgamma test_erf end test_20_00 test_20_01 if $with_test_gui test_20_02 end # ---------------- test 21: new stuff ---------------- def display_samps_in_red(snd, chn) left = left_sample(snd, chn) right = right_sample(snd, chn) old_color = foreground_color(snd, chn) red = make_color_with_catch(1, 0, 0) if left < 2000 and right > 1000 case data = make_graph_data(snd, chn) when Vct samps = [right, 2000].min - [left, 1000].max offset = [0, 1000 - left].max new_data = data.subseq(offset, offset + samps) set_foreground_color(red, snd, chn) cr = make_cairo(channel_widgets(snd, chn)[0]) graph_data(new_data, snd, chn, Copy_context, [1000, left].max, [2000, right].min, Graph_lines, cr) free_cairo(cr) set_foreground_color(old_color, snd, chn) when Array low_data = data[0] high_data = data[1] size = low_data.length samps = right - left left_offset = [0, 1000 - left].max left_bin = ((size * left_offset.to_f) / samps).round right_offset = [2000, right].min - left right_bin = ((size * right_offset.to_f) / samps).round new_low_data = low_data.subseq(left_bin, right_bin) new_high_data = high_data.subseq(left_bin, right_bin) set_foreground_color(red, snd, chn) cr = make_cairo(channel_widgets(snd, chn)[0]) graph_data([new_low_data, new_high_data], snd, chn, Copy_context, left_bin, right_bin, Graph_lines, cr) free_cairo(cr) set_foreground_color(old_color, snd, chn) end end rescue snd_display("draw error in %s", get_func_name) end def show_greeting(snd, chn) ls = left_sample(snd, chn) rs = right_sample(snd, chn) if ls < 1000 and rs > 1000 pos = x2position(1000.0 / srate(snd), snd, chn) old_color = foreground_color(snd, chn) cr = make_cairo(channel_widgets(snd, chn)[0]) set_foreground_color(make_color_with_catch(0.75, 0.75, 0.75), snd, chn) fill_rectangle(pos, 10, 50, 20, snd, chn, Time_graph, false, cr) set_foreground_color(make_color_with_catch(1, 0, 0), snd, chn) draw_string("hi!", pos + 5, 24, snd, chn, Time_graph, cr) set_foreground_color(old_color, snd, chn) free_cairo(cr) end rescue snd_display("draw error in %s", get_func_name) end def st_equal?(a, b) a == b end def st_eql?(a, b) a.eql?(b) end def st_vequal_2(a, b) vequal(a[0], b[0]) and vequal(a[1], b[1]) end def test_sound_func_1(func, ind_1, ind_2, new_val, eq_func, leq_func, set_p, chan, global) old_val = snd_func(func) old_vals = snd_func(func, true) old_default = snd_func(func, false) old_1 = snd_func(func, ind_1) old_2 = snd_func(func, ind_2) sel_snd = selected_sound() unsel_snd = sel_snd == ind_1 ? ind_2 : ind_1 caller = chan ? "channel" : "sound" snd_test_any_neq(old_val, old_default, eq_func, "%s sound_func: no arg false", func) unless method(leq_func).call(old_vals, [old_1, old_2]) or method(leq_func).call(old_vals, [old_2, old_1]) s = snd_format_neq(old_vals, [old_1, old_2], "%s sound_func true", func) snd_display_prev_caller(s) end if set_p set_snd_func(func, new_val) res1 = snd_func(func) res2 = snd_func(func, sel_snd) res3 = snd_func(func, unsel_snd) snd_test_any_neq(res1, new_val, eq_func, "set_%s no arg", func) snd_test_any_neq(res1, res2, eq_func, "set_%s no arg sel", func) if (global and (not method(eq_func).call(res1, res3))) or ((not global) and method(eq_func).call(res1, res3)) s = snd_format_neq(res1, res3, "set_%s no arg unsel", func) snd_display_prev_caller(s) end res1 = snd_func(func, true) unless method(leq_func).call(res1, [res2, res3]) or method(leq_func).call(res1, [res3, res2]) s = snd_format_neq(res1, [res2, res3], "set_%s %s_func true", func, caller) snd_display_prev_caller(s) end set_snd_func(func, old_val) if set_p == :swap set_snd_func(func, ind_1, new_val) else set_snd_func(func, new_val, ind_1) end res0 = snd_func(func, true) res1 = snd_func(func, ind_1) res2 = snd_func(func, ind_2) unless method(eq_func).call(res1, new_val) s = snd_format_neq(res1, new_val, "set_%s arg", func) snd_display_prev_caller(s) end if method(eq_func).call(res2, new_val) s = snd_format_eq(res2, new_val, "set_%s arg (2)", func) snd_display_prev_caller(s) end unless method(leq_func).call(res0, [res1, res2]) or method(leq_func).call(res0, [res2, res1]) s = snd_format_neq(res0, [res1, res2], "set_%s %s_func arg", func, caller) snd_display_prev_caller(s) end if set_p == :swap set_snd_func(func, ind_1, old_1) set_snd_func(func, true, new_val) else set_snd_func(func, old_1, ind_1) set_snd_func(func, new_val, true) end res0 = snd_func(func, true) res1 = snd_func(func, ind_1) res2 = snd_func(func, ind_2) unless method(leq_func).call(res0, [new_val, new_val]) s = snd_format_neq(res0, [new_val, new_val], "set_%s %s_func arg true", func, caller) snd_display_prev_caller(s) end unless method(eq_func).call(res1, new_val) s = snd_format_neq(res1, new_val, "set_%s %s_func arg true", func, caller) snd_display_prev_caller(s) end unless method(eq_func).call(res2, new_val) s = snd_format_neq(res2, new_val, "set_%s %s_func arg true (2)", func, caller) snd_display_prev_caller(s) end if set_p == :swap set_snd_func(func, ind_1, old_1) set_snd_func(func, ind_2, old_2) else set_snd_func(func, old_1, ind_1) set_snd_func(func, old_2, ind_2) end res1 = snd_func(func, ind_1) res2 = snd_func(func, ind_2) unless method(eq_func).call(res1, old_1) s = snd_format_neq(res1, old_1, "set_%s arg true old", func) snd_display_prev_caller(s) end unless method(eq_func).call(res2, old_2) s = snd_format_neq(res2, old_2, "set_%s arg true old (2)", func) snd_display_prev_caller(s) end end end def test_channel_func_1(func, ind_1, ind_2, new_val, eq_func, leq_func, set_p, global) old_1_0 = snd_func(func, ind_1, 0) old_2_0 = snd_func(func, ind_2, 0) old_2_1 = snd_func(func, ind_2, 1) old_1_all = snd_func(func, ind_1, true) old_2_all = snd_func(func, ind_2, true) old_all_0 = snd_func(func, true, 0) old_all_all = snd_func(func, true, true) unless method(eq_func).call(old_1_0, old_1_all[0]) s = snd_format_neq(old_1_0, old_1_all[0], "%s channel_func: old 1/true", func) snd_display_prev_caller(s) end unless method(eq_func).call(old_2_0, old_2_all[0]) s = snd_format_neq(old_2_0, old_2_all[0], "%s channel_func: old 2-1/true", func) snd_display_prev_caller(s) end unless method(eq_func).call(old_2_1, old_2_all[1]) s = snd_format_neq(old_2_1, old_2_all[1], "%s channel_func: old 2-2/true", func) snd_display_prev_caller(s) end unless method(leq_func).call(old_1_all, [old_1_0]) s = snd_format_neq(old_1_all, [old_1_0], "%s channel_func true", func) snd_display_prev_caller(s) end unless method(leq_func).call(old_2_all, [old_2_0, old_2_1]) s = snd_format_neq(old_2_all, [old_2_0, old_2_1], "%s channel_func true", func) snd_display_prev_caller(s) end unless ((method(leq_func).call(old_all_all[0], old_1_all) or method(leq_func).call(old_all_all[0], old_2_all)) and (method(leq_func).call(old_all_all[1], old_1_all) or (method(leq_func).call(old_all_all[1], old_2_all)))) s = snd_format_neq(old_all_all[0], old_1_all, "%s channel_func true true", func) snd_display_prev_caller(s) end if set_p set_snd_func(func, new_val, ind_1, 0) res1 = snd_func(func, ind_1, 0) res2 = snd_func(func, ind_2, 1) unless method(eq_func).call(res1, new_val) s = snd_format_neq(res1, new_val, "set_%s channel_func", func) snd_display_prev_caller(s) end if method(eq_func).call(res2, new_val) s = snd_format_eq(res2, new_val, "set_%s 2 channel_func", func) snd_display_prev_caller(s) end set_snd_func(func, old_1_0, ind_1, 0) set_snd_func(func, new_val, ind_2, 1) res1 = snd_func(func, ind_1, 0) res2 = snd_func(func, ind_2, 1) if method(eq_func).call(res1, new_val) s = snd_format_eq(res1, new_val, "set_%s (2) channel_func", func) snd_display_prev_caller(s) end unless method(eq_func).call(res2, new_val) s = snd_format_neq(res2, new_val, "set_%s (2) 2 channel_func", func) snd_display_prev_caller(s) end set_snd_func(func, new_val, ind_2, 0) set_snd_func(func, old_2_0, ind_2, true) res1 = snd_func(func, ind_2, 0) res2 = snd_func(func, ind_2, 1) unless method(eq_func).call(res1, old_2_0) s = snd_format_neq(res1, old_2_0, "set_%s (true 0) 2 channel_func", func) snd_display_prev_caller(s) end unless method(eq_func).call(res2, old_2_0) s = snd_format_neq(res2, old_2_0, "set_%s (true 1) 2 channel_func", func) snd_display_prev_caller(s) end set_snd_func(func, old_2_0, ind_2, 0) set_snd_func(func, old_2_1, ind_2, 1) end end def test_21_00 unless sound_file?("oboe.snd") snd_display("oboe.snd not a sound file?") end unless sound_file?("4.aiff") snd_display("4.aiff not a sound file?") end if sound_file?("snd.h") snd_display("snd.h is a sound file?") end ind1 = open_sound("oboe.snd") save_sound_as("test.snd", ind1) ind2 = open_sound("test.snd") unless channels_equal?(ind1, 0, ind2, 0) snd_display("channels_equal? of copy") end unless channels_eql?(ind1, 0, ind2, 0) snd_display("channels_eql? of copy") end pad_channel(framples(ind2, 0), 100) if channels_equal?(ind1, 0, ind2, 0) snd_display("channels_equal? of pad") end unless channels_eql?(ind1, 0, ind2, 0) snd_display("channels_eql? of pad") end set_sample(50900, 0.1, ind2, 0) if channels_equal?(ind1, 0, ind2, 0) snd_display("channels_equal? of pad+set") end if channels_eql?(ind1, 0, ind2, 0) snd_display("channels_eql? of pad+set") end unless channels_eql?(ind1, 0, ind2, 0, 0.2) snd_display("channels_eql? of pad+set .2err") end add_comment(1234, "sample 1234", ind1, 0) comments = show_comments(ind1, 0) update_time_graph if comments.null? snd_display("add_comment failed?") end display_db(ind1, 0) display_samps_in_red(ind1, 0) update_time_graph show_greeting(ind1, 0) update_time_graph color_samples(highlight_color, 0, 100, ind1, 0) update_time_graph power_env_channel(make_power_env([0, 0, 0.325, 1, 1, 32, 2, 0, 32], :duration, 2.0)) update_time_graph $with_test_motif and show_disk_space(ind1) update_time_graph revert_sound(ind1) make_selection(10000, 20000, ind1, 0) if selection? show_selection vals = x_bounds(ind1, 0) if vals.length == 2 snd_test_neq(vals[0], 10000.0 / srate(ind1), "show_selection") snd_test_neq(vals[1], 20000.0 / srate(ind1), "show_selection") end else snd_display("make_selection for show failed?") end $graph_hook.add_hook!("test-21-zoom-spectrum", &method(:zoom_spectrum).to_proc) set_transform_graph?(true, ind1, 0) ind3 = open_sound("pistol.snd") overlay_sounds(ind2, ind1, ind3) update_time_graph(ind2, 0) $after_graph_hook.reset_hook! close_sound(ind3) samples_via_colormap(ind1, 0) close_sound(ind1) $graph_hook.remove_hook!("test-21-zoom-spectrum") close_sound(ind2) # ind = new_sound("tmp.snd", 1, 22050, Mus_bfloat, Mus_next, :size, 50) set_sample(3, 1.0) filter_channel(vct(0.5, 1.0, 0.5), 3) unless vequal(res = channel2vct(0, 10), vct(0, 0, 0, 0.5, 1, 0.5, 0, 0, 0, 0)) snd_display("filter_channel (sym 3): %s?", res) end undo_edit filter_channel(vct(0.5, 1.0, 0.25), 3) unless vequal(res = channel2vct(0, 10), vct(0, 0, 0, 0.5, 1, 0.25, 0, 0, 0, 0)) snd_display("filter_channel (3): %s?", res) end undo_edit filter_channel(vct(0.5, 1.0, 1.0, 0.5), 4) unless vequal(res = channel2vct(0, 10), vct(0, 0, 0, 0.5, 1, 1, 0.5, 0, 0, 0)) snd_display("filter_channel (sym 4): %s?", res) end undo_edit filter_channel(vct(0.5, 1.0, 1.0, 0.25), 4) unless vequal(res = channel2vct(0, 10), vct(0, 0, 0, 0.5, 1, 1, 0.25, 0, 0, 0)) snd_display("filter_channel (4): %s?", res) end undo_edit close_sound(ind) # ind = new_sound("tmp.snd", 1, 22050, Mus_bfloat, Mus_next, false, 100) set_sample(10, 0.5) filter_sound(vct(1, 0, 1), 3) unless vequal(res = channel2vct(5, 10), vct(0, 0, 0, 0, 0, 0.5, 0, 0.5, 0, 0)) snd_display("filter_sound 1 0 1: %s?", res) end undo_edit filter_channel(vct(1, 0, 1), 3) unless vequal(res = channel2vct(5, 10), vct(0, 0, 0, 0, 0, 0.5, 0, 0.5, 0, 0)) snd_display("filter_channel (v) 1 0 1: %s?", res) end undo_edit filter_sound([0, 1, 1, 1], 100) coeffs = make_fir_coeffs(100, Vct.new(100, 0.5)) data = channel2vct(10, 100) data.zip(coeffs) do |val, coeff| if fneq(val, coeff) snd_display("coeffs [0, 1, 1, 1]: %s %s?", val, coeff) break end end undo_edit filter_sound([0, 1, 1, 1], 1000) unless vequal(res = channel2vct(5, 10), vct(0, 0, 0, 0, 0, 0.5, 0, 0, 0, 0)) snd_display("filter_sound 1 (1000): %s?", res) end undo_edit make_selection(5, 15) filter_selection([0, 1, 1, 1], 100) if (res = edit_fragment 2) != ["filter_selection([0.000, 1.000, 1.000, 1.000], 100", "set", 5, 11] snd_display("filter_selection truncated: %s", res) end undo_edit filter_selection([0, 1, 1, 1], 100, false) if (res = edit_fragment 2) != ["filter_selection([0.000, 1.000, 1.000, 1.000], 100", "set", 5,111] snd_display("filter_selection not truncated: %s", res) end unless vequal(res = channel2vct(50, 10), vct(-0.016, 0.018, -0.021, 0.024, -0.029, 0.035, -0.045, 0.064, -0.106, 0.318)) snd_display("filter_selection no trunc: %s?", res) end undo_edit filter_selection([0, 1, 1, 1], 1000, true) if (res = edit_fragment 2) != ["filter_selection([0.000, 1.000, 1.000, 1.000], 1000", "set", 5,11] snd_display("filter_selection truncated (1000): %s", res) end if fneq(maxamp, 0.0) snd_display("filter_selection 1000 untrunc: %s?", maxamp) end undo_edit filter_selection([0, 1, 1, 1], 1000, false) if (res = edit_fragment 2) != ["filter_selection([0.000, 1.000, 1.000, 1.000], 1000", "set", 5, 1011] snd_display("filter_selection not truncated (1000): %s", res) end if fneq(maxamp, 0.318) snd_display("filter_selection 1000 no trunc: %s?", maxamp) end unless vequal(res = channel2vct(505, 10), vct(0.035, -0.045, 0.064, -0.106, 0.318, 0.318, -0.106, 0.064, -0.045, 0.035)) snd_display("filter_selection 1000 no trunc: %s?", res) end undo_edit filter_channel([0, 1, 1, 1], 10) unless vequal(res = channel2vct(10, 10), vct(0.008, -0.025, 0.050, -0.098, 0.316, 0.316, -0.098, 0.050, -0.025, 0.008)) snd_display("filter_channel 10: %s?", res) end undo_edit filter_channel([0, 1, 1, 1], 1000) unless vequal(res = channel2vct(5, 10), vct(0, 0, 0, 0, 0, 0.5, 0, 0, 0, 0)) snd_display("filter_channel 1 (1000): %s?", res) end undo_edit filter_channel([0, 1, 1, 0], 10) unless vequal(channel2vct(0, 30), vct(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.005, 0.010, 0.006, 0.038, 0.192, 0.192, 0.038, 0.006, 0.010, 0.005, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) snd_display("filter_channel lp: %s %s %s?", channel2vct(0, 10), channel2vct(10, 10), channel2vct(20, 10)) end undo_edit filter_channel([0, 1, 1, 0], 10, 0, 20, false, false, false, false) unless vequal(channel2vct(0, 30), vct(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.005, 0.010, 0.006, 0.038, 0.192, 0.192, 0.038, 0.006, 0.010, 0.005, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) snd_display("filter_channel lp no trunc: %s %s %s?", channel2vct(0, 10), channel2vct(10, 10), channel2vct(20, 10)) end undo_edit close_sound(ind) # ind = new_sound("tmp.snd", 2, 22050, Mus_bfloat, Mus_next, false, 100) set_sample(10, 0.5) set_sample(5, -0.5, ind, 1) set_sync(1, ind) filter_sound(vct(1, 0, 1), 3) unless vequal(res = channel2vct(5, 10, ind, 0), vct(0, 0, 0,0, 0, 0.5, 0, 0.5, 0, 0)) snd_display("(2) filter_sound 1 0 1: %s?", res) end unless vequal(res = channel2vct(0, 10, ind, 1), vct(0, 0, 0,0, 0, -0.5, 0, -0.5, 0, 0)) snd_display("(2) filter_sound 1 0 2: %s?", res) end undo_edit filter_sound([0, 1, 1, 1], 1000) unless vequal(res = channel2vct(5, 10, ind, 0), vct(0, 0, 0,0, 0, 0.5, 0, 0, 0, 0)) snd_display("(2) filter_sound 1 (1000): %s?", res) end unless vequal(res = channel2vct(0, 10, ind, 1), vct(0, 0, 0,0, 0, -0.5, 0, 0, 0, 0)) snd_display("(2) filter_sound 2 (1000): %s?", res) end undo_edit make_selection(0, 20) filter_selection(vct(1, 0, 1), 3) unless vequal(res = channel2vct(5, 10, ind, 0), vct(0, 0, 0,0, 0, 0.5, 0, 0.5, 0, 0)) snd_display("(2) filter_selection 1 0 1: %s?", res) end unless vequal(res = channel2vct(0, 10, ind, 1), vct(0, 0, 0,0, 0, -0.5, 0, -0.5, 0, 0)) snd_display("(2) filter_selection 1 0 2: %s?", res) end undo_edit set_sync(0, ind) filter_selection(vct(1, 0, 1), 3) unless vequal(res = channel2vct(5, 10, ind, 0), vct(0, 0, 0,0, 0, 0.5, 0, 0.5, 0, 0)) snd_display("(2) filter_selection 1 0 1 (no sync): %s?", res) end unless vequal(res = channel2vct(0, 10, ind, 1), vct(0, 0, 0,0, 0, -0.5, 0, -0.5, 0, 0)) snd_display("(2) filter_selection 1 0 2 (no sync): %s?", res) end undo_edit(1, ind, 0) undo_edit(1, ind, 1) if (res = edit_position(ind, 0)) != 1 snd_display("edpos filter_selection undo 0: %s?", res) end if (res = edit_position(ind, 1)) != 1 snd_display("edpos filter_selection undo 1: %s?", res) end filter_sound(vct(1, 0, 1), 3) unless vequal(res = channel2vct(5, 10, ind, 0), vct(0, 0, 0,0, 0, 0.5, 0, 0.5, 0, 0)) snd_display("(2) filter_sound 1 0 1 (no sync): %s?", res) end unless vequal(res = channel2vct(0, 10, ind, 1), vct(0, 0, 0,0, 0, -0.5, 0, 0, 0, 0)) snd_display("(2) filter_sound 1 0 2 (no sync): %s?", res) end undo_edit(1, ind, 0) filter_channel([0, 1, 1, 0], 10, false, false, ind, 1) unless vequal(channel2vct(0, 30, ind, 1), vct(0, 0, 0, 0, 0, -0.005, -0.010, -0.006, -0.038, -0.192, -0.192, -0.038, -0.006, -0.010, -0.005, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) snd_display("filter_channel lp:\n# %s\n# %s\n# %s", channel2vct(0, 10, ind, 1), channel2vct(10, 10, ind, 1), channel2vct(20, 10, ind, 1)) end undo_edit(1, ind, 1) close_sound(ind) # ind = new_sound("tmp.snd", 1, 22050, Mus_bshort, Mus_next, :size, 100) set_sample(10, 0.5) set_sample(20, -0.5) scale_to(1.0) if fneq(sample(10), 0.999) snd_display("scale_to 1.0 Mus_bshort (10): %s?", sample(10)) end if fneq(sample(20), -0.999) snd_display("scale_to 1.0 Mus_bshort (20): %s?", sample(20)) end close_sound(ind) ind = new_sound("tmp.snd", 1, 22050, Mus_byte, Mus_next, :size, 100) set_sample(10, 0.5) set_sample(20, -0.5) scale_to(1.0) if fneq(sample(10), 0.992) snd_display("scale_to 1.0 Mus_byte (10): %s?", sample(10)) end if fneq(sample(20), -0.992) snd_display("scale_to 1.0 Mus_byte (20): %s?", sample(20)) end close_sound(ind) # set_transform_graph_type(Graph_once) set_fft_window(6) set_show_y_zero(false) set_show_transform_peaks(false) set_fft_log_frequency(false) set_fft_log_magnitude(false) set_with_verbose_cursor(false) set_show_grid(false) set_show_sonogram_cursor(false) set_with_tracking_cursor(false) set_show_controls(false) set_speed_control_tones(12) set_wavelet_type(0) set_spectrum_start(0.0) set_spectro_hop(4) set_fft_window_alpha(0.0) set_fft_window_beta(0.0) ind_1 = new_sound("test-1.snd", 1, 22050, Mus_lfloat, Mus_next, "mono testing", 100) ind_2 = new_sound("test-2.snd", 2, 44100, Mus_bshort, Mus_aifc, "stereo testing", 300) [[:srate, 48000, :st_equal?, :st_eql?, :swap], [:sample_type, Mus_byte, :st_equal?, :st_eql?, :swap], [:data_location, 123, :st_equal?, :st_eql?, :swap], [:data_size, 12348, :st_equal?, :st_eql?, :swap], [:framples, 12348, :st_equal?, :st_eql?, true], [:sync, 2, :st_equal?, :st_eql?, true], [:channels, 0, :st_equal?, :st_eql?, false], [:chans, 0, :st_equal?, :st_eql?, false], [:header_type, 0, :st_equal?, :st_eql?, false], [:amp_control, 0.5, :ffequal?, :vfequal?, true], [:contrast_control, 0.5, :ffequal?, :vfequal?, true], [:expand_control, 0.5, :ffequal?, :vfequal?, true], [:speed_control, 0.5, :ffequal?, :vfequal?, true], [:reverb_control_length, 0.5, :ffequal?, :vfequal?, true], [:reverb_control_scale, 0.5, :ffequal?, :vfequal?, true], [:contrast_control?, true, :st_eql?, :st_eql?, true], [:expand_control?, true, :st_eql?, :st_eql?, true], [:filter_control?, true, :st_eql?, :st_eql?, true], [:reverb_control?, true, :st_eql?, :st_eql?, true], [:read_only, true, :st_eql?, :st_eql?, true], [:file_name, nil, :st_equal?, :st_eql?, false], [:short_file_name, nil, :st_equal?, :st_eql?, false], [:comment, nil, :st_equal?, :st_eql?, false] ].each do |func, new_val, eq_func, leq_func, settable| test_sound_func_1(func, ind_1, ind_2, new_val, eq_func, leq_func, settable, false, false) end save_controls(true) restore_controls(true) reset_controls(true) close_sound(true) if sounds != nil snd_display("sounds after close_sound(true): %s?", sounds) end # # snd chn cases # ind_1 = new_sound("test-1.snd", 1, 22050, Mus_bfloat, Mus_next, "mono testing", 100) ind_2 = new_sound("test-2.snd", 2, 44100, Mus_bshort, Mus_aifc, "stereo testing", 300) set_sample(1, 0.1, ind_1, 0) set_sample(2, 0.2, ind_2, 0) set_sample(3, 0.3, ind_2, 1) vals = [[:min_dB, -100.0, :ffequal?, :vequal?, true, true], [:x_position_slider, 0.1, :ffequal?, :vequal?, true, false], [:y_position_slider, 0.5, :ffequal?, :vequal?, true, false], [:x_zoom_slider, 0.2, :ffequal?, :vequal?, true, false], [:y_zoom_slider, 0.2, :ffequal?, :vequal?, true, false], [:fft_window_alpha, 0.5, :ffequal?, :vequal?, true, true], [:fft_window_beta, 0.5, :ffequal?, :vequal?, true, true], [:spectrum_end, 0.2, :ffequal?, :vequal?, true, true], [:spectrum_start, 0.1, :ffequal?, :vequal?, true, true], [:spectro_x_angle, 10.0, :ffequal?, :vequal?, true, true], [:spectro_x_scale, 0.2, :ffequal?, :vequal?, true, true], [:spectro_y_angle, 10.0, :ffequal?, :vequal?, true, true], [:spectro_y_scale, 0.1, :ffequal?, :vequal?, true, true], [:spectro_z_angle, 10.0, :ffequal?, :vequal?, true, true], [:spectro_z_scale, 0.3, :ffequal?, :vequal?, true, true], [:beats_per_minute, 100.0, :ffequal?, :vequal?, true, true], [:spectro_hop, 10, :st_equal?, :st_eql?, true, true], [:cursor, 50, :st_equal?, :st_eql?, true, false], [:cursor_style, 1, :st_equal?, :st_eql?, true, true], [:cursor_size, 10, :st_equal?, :st_eql?, true, true], [:framples, 50, :st_equal?, :st_eql?, true, false], [:zero_pad, 1, :st_equal?, :st_eql?, true, true], [:wavelet_type, 1, :st_equal?, :st_eql?, true, true], [:time_graph_type, Graph_as_wavogram, :st_equal?, :st_eql?, true, true], [:wavo_hop, 10, :st_equal?, :st_eql?, true, true], [:wavo_trace, 10, :st_equal?, :st_eql?, true, true], [:transform_size, 64, :st_equal?, :st_eql?, true, true], [:transform_graph_type, 1, :st_equal?, :st_eql?, true, true], [:fft_window, 1, :st_equal?, :st_eql?, true, true], [:transform_normalization, 2, :st_equal?, :st_eql?, true, true], [:max_transform_peaks, 10, :st_equal?, :st_eql?, true, true], [:dot_size, 10, :st_equal?, :st_eql?, true, true], [:show_axes, 2, :st_equal?, :st_eql?, true, true], [:transform_graph?, true, :st_equal?, :st_eql?, true, false], [:time_graph?, false, :st_equal?, :st_eql?, true, false], [:lisp_graph?, true, :st_equal?, :st_eql?, true, false], [:squelch_update, true, :st_equal?, :st_eql?, true, false], [:show_y_zero, true, :st_equal?, :st_eql?, true, true], [:show_grid, true, :st_equal?, :st_eql?, true, true], [:grid_density, 0.5, :ffequal?, :vequal?, true, true], [:show_sonogram_cursor, true, :st_equal?, :st_eql?, true, true], [:show_marks, false, :st_equal?, :st_eql?, true, true], [:show_transform_peaks, true, :st_equal?, :st_eql?, true, true], [:fft_log_frequency, true, :st_equal?, :st_eql?, true, true], [:fft_log_magnitude, true, :st_equal?, :st_eql?, true, true], [:show_mix_waveforms, false, :st_equal?, :st_eql?, true, true], [:with_verbose_cursor, true, :st_equal?, :st_eql?, true, true]] vals.each do |func, new_val, eq_func, leq_func, settable, global| test_sound_func_1(func, ind_1, ind_2, new_val, eq_func, leq_func, settable, true, global) test_channel_func_1(func, ind_1, ind_2, new_val, eq_func, leq_func, settable, global) end update_time_graph(true, true) update_transform_graph(true, true) update_lisp_graph(true, true) close_sound(false) close_sound(false) if sounds != nil snd_display("sounds after close_sound(false) twice: %s?", sounds) end # ind_1 = new_sound("test-1.snd", 1, 22050, Mus_bfloat, Mus_next, "mono testing", 100) ind_2 = new_sound("test-2.snd", 2, 44100, Mus_bshort, Mus_aifc, "stereo testing", 300) # test_sound_func_2 [[:filter_control_in_dB, true, :st_eql?, :st_eql?], [:filter_control_in_hz, true, :st_eql?, :st_eql?], [:show_controls, true, :st_eql?, :st_eql?], [:speed_control_tones, 14, :st_equal?, :st_eql?], [:speed_control_style, Speed_control_as_semitone, :st_equal?, :st_eql?], [:filter_control_order, 14, :st_equal?, :st_eql?], [:expand_control_length, 0.25, :ffequal?, :vequal?], [:expand_control_ramp, 0.25, :ffequal?, :vequal?], [:expand_control_hop, 0.25, :ffequal?, :vequal?], [:expand_control_jitter, 0.25, :ffequal?, :vequal?], [:contrast_control_amp, 0.25, :ffequal?, :vequal?], [:reverb_control_feedback, 0.25, :ffequal?, :vequal?], [:reverb_control_lowpass, 0.25, :ffequal?, :vequal?], [:reverb_control_decay, 0.25, :ffequal?, :vequal?], [:amp_control_bounds, [0.0, 2.0], :vequal?, :st_vequal_2], [:contrast_control_bounds, [0.0, 2.0], :vequal?, :st_vequal_2], [:expand_control_bounds, [0.1, 2.0], :vequal?, :st_vequal_2], [:speed_control_bounds, [0.1, 2.0], :vequal?, :st_vequal_2], [:reverb_control_length_bounds, [0.0, 2.0], :vequal?, :st_vequal_2], [:reverb_control_scale_bounds, [0.0, 2.0], :vequal?, :st_vequal_2] ].each do |func, new_val, eq_func, leq_func| old_global_val = snd_func(func) old_vals = snd_func(func, true) old_1 = snd_func(func, ind_1) old_2 = snd_func(func, ind_2) sel_snd = selected_sound unsel_snd = sel_snd == ind_1 ? ind_2 : ind_1 unless method(leq_func).call(old_vals, [old_1, old_2]) or method(leq_func).call(old_vals, [old_2, old_1]) snd_display(snd_format_neq(old_vals, [old_1, old_2], "%s sound_func true", func)) end # set_snd_func(func, new_val) res1 = snd_func(func) res2 = snd_func(func, sel_snd) res3 = snd_func(func, unsel_snd) snd_test_any_neq(res1, new_val, eq_func, "set_%s global no arg", func) snd_test_any_neq(res1, res2, eq_func, "set_%s global no arg sel", func) snd_test_any_neq(res1, res3, eq_func, "set_%s global no arg unsel", func) res1 = snd_func(func, true) unless method(leq_func).call(res1, [res2, res3]) or method(leq_func).call(res1, [res3, res2]) snd_display(snd_format_neq(res1, [res2, res3], "set_%s true", func)) end set_snd_func(func, old_global_val) set_snd_func(func, new_val, ind_1) res1 = snd_func(func, true) res2 = snd_func(func, ind_1) res3 = snd_func(func, ind_2) snd_test_any_neq(res2, new_val, eq_func, "set_%s arg", func) snd_test_any_eq(res3, new_val, eq_func, "set_%s arg (2)", func) unless method(leq_func).call(res1, [res2, res3]) or method(leq_func).call(res1, [res3, res2]) snd_display(snd_format_neq(res1, [res2, res3], "set_%s arg", func)) end set_snd_func(func, old_1, ind_1) set_snd_func(func, new_val, true) res1 = snd_func(func, true) res2 = snd_func(func, ind_1) res3 = snd_func(func, ind_2) snd_test_any_neq(res1, [new_val, new_val], leq_func, "set_%s arg true", func) snd_test_any_neq(res2, new_val, eq_func, "set_%s arg true", func) snd_test_any_neq(res3, new_val, eq_func, "set_%s arg true (2)", func) res1 = snd_func(func) snd_test_any_eq(res1, new_val, eq_func, "set_%s overwrote global", func) set_snd_func(func, old_1, ind_1) set_snd_func(func, old_2, ind_2) res2 = snd_func(func, ind_1) res3 = snd_func(func, ind_2) snd_test_any_neq(res2, old_1, eq_func, "set_%s arg true old", func) snd_test_any_neq(res3, old_2, eq_func, "set_%s arg true old (2)", func) end close_sound(true) end def test_21_02 set_remember_sound_state(true) ind = open_sound("oboe.snd") set_transform_graph?(true, ind, 0) set_show_transform_peaks(true, ind, 0) set_show_y_zero(true, ind, 0) close_sound(ind) ind = open_sound("oboe.snd") res1 = transform_graph?(ind, 0) res2 = show_transform_peaks(ind, 0) res3 = show_y_zero(ind, 0) if (not res1.kind_of?(TrueClass)) or (not res2.kind_of?(TrueClass)) or (not res3.kind_of?(TrueClass)) snd_display("remember_sound_state: %s %s %s?", res1.inspect, res2.inspect, res3.inspect) end close_sound(ind) reset_almost_all_hooks set_remember_sound_state(false) # map_sound_files do |n| if mus_sound_duration(n) > 1000.0 snd_display("%s is pretty long! %s", n, mus_sound_duration(n)) end mus_sound_forget(n) end map_sound_files($sf_dir) do |n| Snd.catch do if mus_sound_duration(n) > 1000.0 snd_display("%s is pretty long! %s", n, mus_sound_duration(n)) end mus_sound_forget(n) end end # snd = new_sound("test.snd") pad_channel(0, 20) map_channel($init_channel) env_channel_with_base([0, 0, 1, 1], 1.0) snd_test_neq(channel2vct(0, 20), vct(0.0, 0.05, 0.10, 0.15, 0.20, 0.25, 0.30, 0.35, 0.40, 0.45, 0.50, 0.55, 0.60, 0.65, 0.70, 0.75, 0.80, 0.85, 0.90, 0.95), "env_chan 1.0") undo_edit env_channel_with_base([0, 0, 1, 1, 2, 1, 3, 0], 0.0) snd_test_neq(channel2vct(0, 20), vct(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0), "env_chan 0.0") undo_edit env_channel_with_base([0, 0, 1, 1], 100.0) snd_test_neq(channel2vct(0, 20), vct(0.0, 0.003, 0.006, 0.010, 0.015, 0.022, 0.030, 0.041, 0.054, 0.070, 0.091, 0.117, 0.150, 0.191, 0.244, 0.309, 0.392, 0.496, 0.627, 0.792), "env_chan 100.0") undo_edit env_channel_with_base([0, 0, 1, 1], 0.01) snd_test_neq(channel2vct(0, 20), vct(0.0, 0.208, 0.373, 0.504, 0.608, 0.691, 0.756, 0.809, 0.850, 0.883, 0.909, 0.930, 0.946, 0.959, 0.970, 0.978, 0.985, 0.990, 0.994, 0.997), "env_chan 0.01") undo_edit env_channel_with_base([0, 0, 1, 1], 1.0, 5, 10) snd_test_neq(channel2vct(0, 20), vct(1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.111, 0.222, 0.333, 0.444, 0.556, 0.667, 0.778, 0.889, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0), "env_chan 1.0 seg") undo_edit env_channel_with_base([0, 0, 1, 1, 2, 1, 3, 0], 0.0, 5, 10) snd_test_neq(channel2vct(0, 20), vct(1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0), "env_chan 0.0 seg") undo_edit env_channel_with_base([0, 0, 1, 1], 100.0, 5, 10) snd_test_neq(channel2vct(0, 20), vct(1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.007, 0.018, 0.037, 0.068, 0.120, 0.208, 0.353, 0.595, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0), "env_chan 100.0 seg") undo_edit env_channel_with_base([0, 0, 1, 1], 0.01, 5, 10) snd_test_neq(channel2vct(0, 20), vct(1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.405, 0.647, 0.792, 0.880, 0.932, 0.963, 0.982, 0.993, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0), "env_chan 0.01 seg") undo_edit close_sound(snd) # ind1 = open_sound("now.snd") ind2 = open_sound("oboe.snd") [[:channel_mean, 5.02560673308833e-5], [:channel_total_energy, 50.7153476262465], [:channel_average_power, 0.00155078578803922], [:channel_rms, 0.039380017623653], [:channel_norm, 7.12147088923675], [:channel_variance, 50.7153476237207]].each do |func_sym, req| snd_test_neq(snd_func(func_sym, ind1, 0), req, "%s", func_sym) end [[2, 7.12147088923675], [1, 775.966033935547]].each do |arg, req| snd_test_neq(channel_lp(arg, ind1, 0), req, "channel_lp %d", arg) end snd_test_neq(channel2_inner_product(ind1, 0, ind2, 0), 1.52892031334341, "channel2_inner_product") snd_test_neq(channel2_angle(ind1, 0, ind2, 0), 1.55485084385627, "channel2_angle") snd_test_neq(channel2_orthogonal?(ind1, 0, ind2, 0), false, "channel2_orthogonal?") snd_test_neq(channel2_coefficient_of_projection(ind1, 0, ind2, 0), 0.0301470932351876, "channel2_coefficient_of_projection") close_sound(ind1) ind1 = open_sound("oboe.snd") scale_by(0.99, ind1, 0) snd_test_neq(channel_distance(ind1, 0, ind2, 0), 0.1346, "channel_distance") [ind1, ind2].apply(:close_sound) # file_copy("oboe.snd", "test.snd") ind = open_sound("test.snd") mx = maxamp(ind, 0) chns = channels(ind) sr = srate(ind) fr = framples(ind, 0) with_local_hook($update_hook, lambda do |orig_ind| lambda do |new_ind| ind = new_ind end end) do 10.times do |i| v = channel2vct array2file("test.snd", v, fr, sr, chns) update_sound(ind) snd_test_neq(maxamp(ind, 0), mx, "update_sound looped maxamp %d", i) snd_test_neq(chans(ind), chns, "update_sound looped chans") snd_test_neq(srate(ind), sr, "update_sound looped srate") snd_test_neq(framples(ind), fr, "update_sound looped framples") end old_ind = open_sound("oboe.snd") diff = 0.0 rd = make_sampler(0, ind, 0) home = sampler_home(rd) scan_channel(lambda do |y| if (cd = (y - rd.call).abs) > diff diff = cd end false end, 0, fr, old_ind, 0) snd_test_neq(diff, 0.0, "update_sound looped overall max diff old_ind %s rd %s", old_ind, home) close_sound(old_ind) end close_sound(ind) # delete_file("test.snd") ind = open_sound("oboe.snd") data = channel2vct 5.times do |i| array2file("test.snd", data, framples(ind), 22050, 1) file2array("test.snd", 0, 0, framples, data) diff = 0.0 ctr = 0 scan_channel(lambda do |y| if (cd = (y - data[ctr]).abs) > diff diff = cd end ctr += 1 false end) snd_test_neq(diff, 0.0, "array2file2array overall max diff") end # set_colormap_size(16) set_transform_size(8, ind, 0) set_transform_graph_type(Graph_as_sonogram, ind, 0) set_transform_graph?(true, ind, 0) update_transform_graph set_x_bounds([0.0, 0.04]) update_time_graph update_transform_graph set_zoom_focus_style(lambda do |s, c, z, x0, x1, range| 0 end) unless proc?(res = zoom_focus_style) snd_display("zoom_focus_style as func: %s?", res) end set_zoom_focus_style(Zoom_focus_right) snd_test_neq(zoom_focus_style(), Zoom_focus_right, "unset zoom_focus_style as func") close_sound(ind) # delete_files("test.snd", "fmv.snd") rdin = false rdout = false len = mus_sound_framples("oboe.snd") types = [Mus_riff, Mus_aifc, Mus_next, Mus_nist, Mus_ircam] forms = [Mus_lshort, Mus_bshort, Mus_b24int, Mus_l24int, Mus_bint] file_copy("oboe.snd", "fmv.snd") types.zip(forms) do |tp, fm| rdin = make_readin(:file, "fmv.snd") rdout = make_sample2file("test.snd", 1, fm, tp) len.times do |k| sample2file(rdout, k, 0, readin(rdin)) end rdout.close rdin.close file_copy("test.snd", "fmv.snd") delete_file("test.snd") ["test.snd", "fmv.snd"].apply(:mus_sound_forget) end diff = 0.0 ctr = 0 ind1 = open_sound("oboe.snd") ind2 = make_file2sample("fmv.snd") scan_channel(lambda do |y| if (cd = (y - file2sample(ind2, ctr, 0)).abs) > diff diff = cd end ctr += 1 false end) snd_test_neq(diff, 0.0, "file2sample2file overall max diff") close_sound(ind1) # ind = open_sound("1a.snd") mx = maxamp() [["scale_by", lambda do scale_by(2.0) end], ["scale_channel", lambda do scale_channel(2.0) end], ["map_channel", lambda do map_channel(lambda do |y| y * 2.0 end) end], ["set_maxamp", lambda do set_maxamp(2 * maxamp) end], ["env_sound", lambda do env_sound([0, 2, 1, 2]) end], ["env_channel", lambda do env_channel(make_env([0, 1, 1, 1], :scaler, 2.0, :length, framples)) end], ["clm_channel", lambda do clm_channel(make_one_zero(:a0, 2.0, :a1, 0.0)) end], ["filter_channel", lambda do filter_channel(vct(2.0), 1) end], ["vct2channel", lambda do vct2channel(channel2vct.scale(2.0), 0) end], ["mix_selection", lambda do select_all mix_selection(0) end], ["scale_selection_by", lambda do select_all scale_selection_by(2.0) end], ["mix", lambda do save_sound_as("temp.snd") mix("temp.snd", 0) delete_file("temp.snd") end], ["convolve", lambda do flt = Vct.new(8) flt[0] = 2.0 cnv = make_convolve(:filter, flt) sf = make_sampler(0) map_channel(lambda do |y| convolve(cnv, lambda do |dir| read_sample(sf) end) end) end], ["fft", lambda do len = framples fsize = 2 ** (log(len) / log(2)).ceil rl = channel2vct(0, fsize) im = Vct.new(fsize) mus_fft(rl, im, fsize) mus_fft(rl, im, fsize) mus_fft(rl, im, fsize) mus_fft(rl, im, fsize) vct2channel(rl.scale(2.0 / (fsize * fsize)), 0, len) end], ["set_samples", lambda do set_squelch_update(true) 100.times do |i| set_sample(i, 2.0 * sample(i)) end set_squelch_update(false) end], ["coroutines", lambda do set_squelch_update(true) make_scaler = lambda do |start, dur| ctr = start us = lambda do |them| set_sample(ctr, 2.0 * sample(ctr)) ctr += 2 if ctr <= dur them.call(us) end end us end make_scaler.call(0, 100).call(make_scaler.call(1, 100)) set_squelch_update(false) end]].each do |name, func| func.call next if name == "set_samples" next if name == "coroutines" snd_test_neq(maxamp() / mx, 2.0, "silly scalers %s", name) revert_sound end close_sound(ind) end def test_21 test_21_00 if $with_test_gui test_21_02 end # ---------------- test 23: with-sound ---------------- require "clm-ins" def bigbird_2(start, dur, freq, freqskew, amp, freq_envelope, amp_envelope, partials) gls_env = make_env(:envelope, freq_envelope, :scaler, hz2radians(freqskew), :duration, dur) os = make_oscil(:frequency, freq) amp_env = make_env(:envelope, amp_envelope, :scaler, amp, :duration, dur) coeffs = partials2polynomial(normalize_partials(partials)) run_instrument(start, dur) do env(amp_env) * polynomial(coeffs, oscil(os, env(gls_env))) end end def bird_2(start, dur, freq, freqskew, amp, freq_envelope, amp_envelope) gls_env = make_env(:envelope, freq_envelope, :scaler, hz2radians(freqskew), :duration, dur) os = make_oscil(:frequency, freq) amp_env = make_env(:envelope, amp_envelope, :scaler, amp, :duration, dur) run_instrument(start, dur) do env(amp_env) * oscil(os, env(gls_env)) end end # scissor-tailed flycatcher # # mix a scissor-tailed flycatcher call into the current sound # see bird.rb for lots more birds def scissor_2(start) bigbird_2(start, 0.05, 1800, 1800, 0.2, [0, 0, 40, 1, 60, 1, 100, 0], # scissor function [0, 0, 25, 1, 75, 1, 100, 0], [1, 0.5, 2, 1, 3, 0.5, 4, 0.1, 5, 0.01]) end def bobwhite_2(beg) main_amp = [0.00, 0.00, 0.25, 1.00, 0.60, 0.70, 0.75, 1.00, 1.00, 0.0] bobup1 = [0.00, 0.00, 0.40, 1.00, 1.00, 1.0] bobup2 = [0.00, 0.00, 0.65, 0.50, 1.00, 1.0] bigbird_2(0.4, 0.2, 1800, 200, 0.1, bobup1, main_amp, [1, 1, 2, 0.02]) bigbird_2(1, 0.20, 1800, 1200, 0.2, bobup2, main_amp, [1, 1, 2, 0.02]) end class Sinc_train def initialize(freq, width) @range = if width width else PI * ((2 * (mus_srate() / (2.2 * freq)).floor) - 1) end @ang = -(@range * 0.5) @frq = (@range * freq) / mus_srate() end def sinc_train(fm) top = @range * 0.5 val = (@ang.zero? ? 1.0 : (sin(@ang) / @ang)) new_ang = @ang + @frq + fm @ang = ((new_ang > top) ? (new_ang - @range) : new_ang) val end end def make_sinc_train(freq = 440.0, width = false) Sinc_train.new(freq, width) end def sinc_train(gen, fm = 0.0) gen.sinc_train(fm) end def ws_sine(freq) os = make_oscil(freq) 100.times do |i| outa(i, oscil(os), $output) end end def step_src rd = make_sampler(0) os = make_oscil(2205) sr = make_src(:srate, 0.0, :input, lambda do |dir| read_sample(rd) end) incr = 2.0 + oscil(os) tempfile = with_sound(:output, snd_tempnam(), :srate, srate(), :comment, get_func_name) do samp = 0 until sampler_at_end?(rd) out_any(samp, src(sr, incr), 0, $output) if (samp % 2205).zero? incr = 2.0 + oscil(os) end samp += 1 end end.output len = mus_sound_framples(tempfile) set_samples(0, len - 1, tempfile, false, false, true, get_func_name, 0, false, true) end # optkey returns an array of values or, if array length is 1, returns # the single value. All examples below could be written without local # variables: # # def optkey_n(*args) # optkey(args, :a, ...) # end def optkey_1(*args) # single return value, no array returned a = optkey(args, :a) a end def optkey_2(*args) # local variables a and b will be set by optkey, thats why function # binding as second argument a, b = nil optkey(args, binding, [:a, 3], :b) [a, b] end def optkey_3(*args) a, b, c = nil optkey(args, binding, :a, :b, :c) [a, b, c] end def optkey_4(*args) a, b, c, d = nil optkey(args, binding, [:a, 1], [:b, 2], [:c, 3], :d) [a, b, c, d] end def test_23_00 set_mus_srate($clm_srate = 22050) set_default_output_srate(22050) with_sound(:reverb, :nrev, :play, false) do fmt1 = [0, 1200, 100, 1000] fmt2 = [0, 2250, 100, 1800] fmt3 = [0, 4500, 100, 4500] fmt4 = [0, 6750, 100, 8100] amp1 = [0, 0.67, 100, 0.7] amp2 = [0, 0.95, 100, 0.95] amp3 = [0, 0.28, 100, 0.33] amp4 = [0, 0.14, 100, 0.15] ind1 = [0, 0.75, 100, 0.65] ind2 = [0, 0.75, 100, 0.75] ind3 = [0, 1, 100, 1] ind4 = [0, 1, 100, 1] skwf = [0, 0, 100, 0] ampf = [0, 0, 25, 1, 75, 1, 100, 0] ranf = [0, 0.5, 100, 0.5] index = [0, 1, 100, 1] solid = [0, 0, 5, 1, 95, 1, 100, 0] bassdr2 = [0.5, 0.06, 1, 0.62, 1.5, 0.07, 2, 0.6, 2.5, 0.08, 3, 0.56, 4, 0.24, 5, 0.98, 6, 0.53, 7, 0.16, 8, 0.33, 9, 0.62, 10, 0.12, 12, 0.14, 14, 0.86, 16, 0.12, 23, 0.14, 24, 0.17] tenordr = [0.3, 0.04, 1, 0.81, 2, 0.27, 3, 0.2, 4, 0.21, 5, 0.18, 6, 0.35, 7, 0.03, 8, 0.07, 9, 0.02, 10, 0.025, 11, 0.035] # drone(0, 4, 115, 0.125, solid, bassdr2, 0.1, 0.5, 0.03, 45, 1, 0.01, 10) drone(0, 4, 229, 0.125, solid, tenordr, 0.1, 0.5, 0.03, 45, 1, 0.01, 11) drone(0, 4, 229.5, 0.125, solid, tenordr, 0.1, 0.5, 0.03, 45, 1, 0.01, 9) canter(0.000, 0.231, 918.000, 0.175, 45.0, 1, 0.05, ampf, ranf, skwf, 0.05, 0.01, 10, index, 0.005, 0.005, amp1, ind1, fmt1, amp2, ind2, fmt2, amp3, ind3, fmt3, amp4, ind4, fmt4) canter(2.100, 0.300, 688.500, 0.175, 45.0, 1, 0.05, ampf, ranf, skwf, 0.050, 0.01, 10, index, 0.005, 0.005, amp1, ind1, fmt1, amp2, ind2, fmt2, amp3, ind3, fmt3, amp4, ind4, fmt4) canter(2.400, 0.040, 826.200, 0.175, 45.0, 1, 0.05, ampf, ranf, skwf, 0.050, 0.01, 10, index, 0.005, 0.005, amp1, ind1, fmt1, amp2, ind2, fmt2, amp3, ind3, fmt3, amp4, ind4, fmt4) canter(2.440, 0.560, 459.000, 0.175, 45.0, 1, 0.05, ampf, ranf, skwf, 0.050, 0.01, 10, index, 0.005, 0.005, amp1, ind1, fmt1, amp2, ind2, fmt2, amp3, ind3, fmt3, amp4, ind4, fmt4) canter(3.000, 0.040, 408.000, 0.175, 45.0, 1, 0.05, ampf, ranf, skwf, 0.050, 0.01, 10, index, 0.005, 0.005, amp1, ind1, fmt1, amp2, ind2, fmt2, amp3, ind3, fmt3, amp4, ind4, fmt4) canter(3.040, 0.040, 619.650, 0.175, 45.0, 1, 0.05, ampf, ranf, skwf, 0.050, 0.01, 10, index, 0.005, 0.005, amp1, ind1, fmt1, amp2, ind2, fmt2, amp3, ind3, fmt3, amp4, ind4, fmt4) canter(3.080, 0.040, 408.000, 0.175, 45.0, 1, 0.05, ampf, ranf, skwf, 0.050, 0.01, 10, index, 0.005, 0.005, amp1, ind1, fmt1, amp2, ind2, fmt2, amp3, ind3, fmt3, amp4, ind4, fmt4) canter(3.120, 0.040, 688.500, 0.175, 45.0, 1, 0.05, ampf, ranf, skwf, 0.050, 0.01, 10, index, 0.005, 0.005, amp1, ind1, fmt1, amp2, ind2, fmt2, amp3, ind3, fmt3, amp4, ind4, fmt4) canter(3.160, 0.290, 459.000, 0.175, 45.0, 1, 0.05, ampf, ranf, skwf, 0.050, 0.01, 10, index, 0.005, 0.005, amp1, ind1, fmt1, amp2, ind2, fmt2, amp3, ind3, fmt3, amp4, ind4, fmt4) canter(3.450, 0.150, 516.375, 0.175, 45.0, 1, 0.05, ampf, ranf, skwf, 0.050, 0.01, 10, index, 0.005, 0.005, amp1, ind1, fmt1, amp2, ind2, fmt2, amp3, ind3, fmt3, amp4, ind4, fmt4) canter(3.600, 0.040, 826.200, 0.175, 45.0, 1, 0.05, ampf, ranf, skwf, 0.050, 0.01, 10, index, 0.005, 0.005, amp1, ind1, fmt1, amp2, ind2, fmt2, amp3, ind3, fmt3, amp4, ind4, fmt4) canter(3.640, 0.040, 573.750, 0.175, 45.0, 1, 0.05, ampf, ranf, skwf, 0.050, 0.01, 10, index, 0.005, 0.005, amp1, ind1, fmt1, amp2, ind2, fmt2, amp3, ind3, fmt3, amp4, ind4, fmt4) canter(3.680, 0.040, 619.650, 0.175, 45.0, 1, 0.05, ampf, ranf, skwf, 0.050, 0.01, 10, index, 0.005, 0.005, amp1, ind1, fmt1, amp2, ind2, fmt2, amp3, ind3, fmt3, amp4, ind4, fmt4) canter(3.720, 0.180, 573.750, 0.175, 45.0, 1, 0.05, ampf, ranf, skwf, 0.050, 0.01, 10, index, 0.005, 0.005, amp1, ind1, fmt1, amp2, ind2, fmt2, amp3, ind3, fmt3, amp4, ind4, fmt4) canter(3.900, 0.040, 688.500, 0.175, 45.0, 1, 0.05, ampf, ranf, skwf, 0.050, 0.01, 10, index, 0.005, 0.005, amp1, ind1, fmt1, amp2, ind2, fmt2, amp3, ind3, fmt3, amp4, ind4, fmt4) canter(3.940, 0.260, 459.000, 0.175, 45.0, 1, 0.05, ampf, ranf, skwf, 0.050, 0.01, 10, index, 0.005, 0.005, amp1, ind1, fmt1, amp2, ind2, fmt2, amp3, ind3, fmt3, amp4, ind4, fmt4) end if sound?(ind = find_sound("test.snd")) close_sound(ind) else snd_display("missing test.snd (%s)", get_func_name) end end def test_23_01 set_mus_srate($clm_srate = 22050) set_default_output_srate(22050) with_sound(:srate, 22050, :play, false) do fm_violin(0, 0.01, 440, 0.1, :noise_amount, 0.0) pluck(0.05, 0.01, 330, 0.1, 0.95, 0.95) maraca(0.1, 0.1) big_maraca(0.2, 0.5, 0.25, 0.95, 0.9985, 0.0312, [2300, 5600, 8100], [0.96, 0.995, 0.995], 0.01) fm_bell(0.3, 1.0, 220, 0.5, [0, 0, 0.1, 1, 10, 0.6, 25, 0.3, 50, 0.15, 90, 0.1, 100, 0], [0, 1, 2, 1.1, 25, 0.75, 75, 0.5, 100, 0.2], 1.0) singer(0.4, 0.1, [[0.4, Ehh_shp, Test_glt, 523.0, 0.8, 0.0, 0.01], [0.6, Oo_shp, Test_glt, 523.0, 0.7, 0.1, 0.01]]) stereo_flute(0.6, 0.2, 440, 0.55, :flow_envelope, [0, 0, 1, 1, 2, 1, 3, 0]) fofins(1, 0.3, 270, 0.4, 0.001, 730, 0.6, 1090, 0.3, 2440, 0.1) bow(1.2, 0.3, 400, 0.5, :vb, 0.15, :fb, 0.1, :inharm, 0.25) pqw_vox(1.5, 1, 300, 300, 0.1, [0, 0, 50, 1, 100, 0], [0, 0, 100, 0], 0, [0, :L, 100, :L], [0.33, 0.33, 0.33], [[1, 1, 2, 0.5], [1, 0.5, 2, 0.5, 3, 1], [1, 1, 4, 0.5]]) fm_noise(2, 0.5, 500, 0.25, [0, 0, 25, 1, 75, 1, 100, 0], 0.1, 0.1, 1000, [0, 0, 100, 1], 0.1, 0.1, 10, 1000, [0, 0, 100, 1], 0, 0, 100, 500, [0, 0, 100, 1], 0, 0) bes_fm(2.5, 0.5, 440, 5.0, 1.0, 8.0) chain_dsps(3, 0.5, [0, 0, 1, 0.1, 2, 0], make_oscil(440)) chain_dsps(3.5, 1.0, [0, 0, 1, 1, 2, 0], make_one_zero(0.5), make_readin("oboe.snd")) vox(4, 2, 170, 0.4, [0, 0, 25, 1, 75, 1, 100, 0], [0, 0, 5, 0.5, 10, 0, 100, 1], 0.1, [0, :E, 25, :AE, 35, :ER, 65, :ER, 75, :I, 100, :UH], 0.05, 0.1) p(5.0, :duration, 0.5, :keyNum, 36, :strike_velocity, 0.5, :amp, 0.4, :dryPedalResonanceFactor, 0.25) bobwhite_2(5.5) scissor_2(2.0) plucky(3.25, 0.3, 440, 0.2, 1.0) bowstr(3.75, 0.3, 220, 0.2, 1.0) brass(4.2, 0.3, 440, 0.2, 1.0) clarinet(5.75, 0.3, 440, 0.2, 1.0) flute(6, 0.3, 440, 0.2, 1.0) fm_trumpet(6.5, 0.25) touch_tone(6.75, [7, 2, 3, 4, 9, 7, 1]) pins(7.0, 1.0, "now.snd", 1.0, :time_scaler, 2.0) # locust = [0, 0, 40, 1, 95, 1, 100, 0.5] bug_hi = [0, 1, 25, 0.7, 75, 0.78, 100, 1] amp = [0, 0, 25, 1, 75, 0.7, 100, 0] fm_insect(7.000, 1.699, 4142.627, 0.015, amp, 60, -16.707, locust, 500.866, bug_hi, 0.346, 0.5) fm_insect(7.195, 0.233, 4126.284, 0.030, amp, 60, -12.142, locust, 649.490, bug_hi, 0.407, 0.5) fm_insect(7.217, 2.057, 3930.258, 0.045, amp, 60, -3.011, locust, 562.087, bug_hi, 0.591, 0.5) fm_insect(9.100, 1.500, 900.627, 0.060, amp, 40, -16.707, locust, 300.866, bug_hi, 0.346, 0.5) fm_insect(10.00, 1.500, 900.627, 0.060, amp, 40, -16.707, locust, 300.866, bug_hi, 0.046, 0.5) fm_insect(10.45, 1.500, 900.627, 0.090, amp, 40, -16.707, locust, 300.866, bug_hi, 0.006, 0.5) fm_insect(10.95, 1.500, 900.627, 0.120, amp, 40, -10.707, locust, 300.866, bug_hi, 0.346, 0.5) fm_insect(11.30, 1.500, 900.627, 0.090, amp, 40, -20.707, locust, 300.866, bug_hi, 0.246, 0.5) # fm_drum(7.5, 1.5, 55, 0.3, 5, false) fm_drum(8, 1.5, 66, 0.3, 4, true) gong(9, 3, 261.61, 0.6) attract(10, 0.25, 0.5, 2.0) pqw(11, 0.5, 200, 1000, 0.2, [0, 0, 25, 1, 100, 0], [0, 1, 100, 0], [2, 0.1, 3, 0.3, 6, 0.5]) # zn(10, 1, 100, 0.1, 20, 100, 0.995) zn(11.5, 1, 100, 0.1, 100, 20, 0.995) zc(11, 1, 100, 0.1, 20, 100, 0.95) zc(12.5, 1, 100, 0.1, 100, 20, 0.95) za(13, 1, 100, 0.1, 20, 100, 0.95, 0.95) za(14.5, 1, 100, 0.1, 100, 20, 0.95, 0.95) # tubebell(12, 2, 440, 0.2) wurley(12.5, 0.25, 440, 0.2) rhodey(12.75, 0.25, 440, 0.2) hammondoid(13, 0.25, 440, 0.2) metal(13.5, 0.25, 440, 0.2) reson(14.0, 1.0, 440, 0.1, 2, [0, 0, 100, 1], [0, 0, 100, 1], 0.1, 0.1, 0.1, 5, 0.01, 5, 0.01, 0, 1.0, 0.01, [[[0, 0, 100, 1], 1200, 0.5, 0.1, 0.1, 0, 1.0, 0.1, 0.1], [[0, 1, 100, 0], 2400, 0.5, 0.1, 0.1, 0, 1.0, 0.1, 0.1]]) cellon(14.5, 1, 220, 0.1, [0, 0, 25, 1, 75, 1, 100, 0], [0, 0, 25, 1, 75, 1, 100, 0], 0.75, 1.0, 0, 0, 0, 0, 1, 0, 0, 220, [0, 0, 25, 1, 75, 1, 100, 0], 0, 0, 0, 0, [0, 0, 100, 0], 0, 0, 0, 0, [0, 0, 100, 0]) clm_expsrc(14.75, 2.5, "oboe.snd", 2.0, 1.0, 1.0) scratch(15.0, "now.snd", 1.5, [0.0, 0.5, 0.25, 1.0]) two_tab(15, 1, 440, 0.1) exp_snd("fyow.snd", 15, 1.5, 1, [0, 1, 1, 3], 0.4, 0.15, [0, 2, 1, 0.5], 0.05) exp_snd("oboe.snd", 16, 1, 1, [0, 1, 1, 3], 0.4, 0.15, [0, 2, 1, 0.5], 0.2) gran_synth(15.5, 1, 300, 0.0189, 0.03, 0.4) spectra(16, 1, 440, 0.1, [1, 0.4, 2, 0.2, 3, 0.2, 4, 0.1, 6, 0.1], [0, 0, 1, 1, 5, 0.9, 12, 0.5, 25, 0.25, 100, 0]) lbj_piano(16.5, 1, 440, 0.2) resflt(17, 1, 0, 0, 0, false, 0.1, 200, 230, 10, [0, 0, 50, 1, 100, 0], [0, 0, 100, 1], 500, 0.995, 0.1, 1000, 0.995, 0.1, 2000, 0.995, 0.1) resflt(17.5, 1, 1, 10000, 0.01, [0, 0, 50, 1, 100, 0], 0, 0, 0, 0, false, false, 500, 0.995, 0.1, 1000, 0.995, 0.1, 2000, 0.995, 0.1) bes_fm(18, 1, 440, 10.0, 1.0, 4.0) graph_eq("oboe.snd", 19, 1) end if sound?(ind = find_sound("test.snd")) close_sound(ind) else snd_display("missing test.snd (%s)", get_func_name) end end def test_23_02 set_mus_srate($clm_srate = 22050) set_default_output_srate(22050) [Mus_bshort, Mus_lshort, Mus_mulaw, Mus_alaw, Mus_byte, Mus_lfloat, Mus_bint, Mus_lint, Mus_b24int, Mus_l24int, Mus_ubshort, Mus_ulshort, Mus_ubyte, Mus_bfloat, Mus_bdouble, Mus_ldouble].each do |type| ind = find_sound(with_sound(:sample_type, type, :srate, 22050) do fm_violin(0, 0.1, 440, 0.1) fm_violin(10, 0.1, 440, 0.1) fm_violin(100, 0.1, 440, 0.1) fm_violin(250, 0.1, 440, 0.1) end.output) snd_test_any_neq(maxamp(ind), 0.1, :ffequal?, "format %s", mus_sample_type2string(type)) end 3.times do |i| with_sound(:srate, 22050) do fm_violin(0, 0.1, 110.0 * (1.0 + i), 0.1) end ind = find_sound("test.snd") unless ind snd_display("with_sound: %s?", Snd.sounds.map do |s| file_name(s) end) end if fneq(res = maxamp, 0.1) snd_display("with_sound max (%s): %s?", i, res) end if srate(ind) != 22050 snd_display("with_sound srate: %s (%s %s)?", srate(ind), mus_srate, mus_sound_srate("test.snd")) end if framples(ind) != 2205 snd_display("with_sound framples (%s): %s?", i, framples(ind)) end end # with_sound do fm_violin(0, 0.1, 440, 0.1) end with_sound(:continue_old_file, true) do fm_violin(0.2, 0.1, 660, 0.04) end ind = find_sound("test.snd") if fneq(res = maxamp, 0.1) snd_display("maxamp after continued sound: %s?", res) end if fneq(res = framples(ind) / srate(ind).to_f, 0.3) snd_display("duration after continued sound: %s?", res) end close_sound(ind) # with_sound(:srate, 22050, :channels, 2, :output, "test1.snd") do fm_violin(0, 0.1, 440, 0.1, :degree, 45.0) end ind = find_sound("test1.snd") unless ind snd_display("with_sound (1): %s?", file_name(true)) end if fneq(res = maxamp, 0.05) snd_display("with_sound max (1): %s?", res) end if srate(ind) != 22050 or mus_sound_srate("test1.snd") != 22050 snd_display("with_sound srate (1): %s (%s %s)?", srate(ind), mus_srate, mus_sound_srate("test1.snd")) end if framples(ind) != 2205 snd_display("with_sound framples (1): %s?", framples(ind)) end if chans(ind) != 2 or mus_sound_chans("test1.snd") != 2 snd_display("with_sound chans (1): %s?", chans(ind)) end close_sound(ind) delete_file("test1.snd") # with_sound(:srate, 48000, :channels, 2, :header_type, Mus_riff, :sample_type, Mus_lshort, :output, "test1.snd") do fm_violin(0, 0.1, 440, 0.1) end ind = find_sound("test1.snd") if srate(ind) != 48000 or mus_sound_srate("test1.snd") != 48000 snd_display("with_sound srate (48000, r): %s (%s, %s)?", srate(ind), mus_srate, mus_sound_srate("test1.snd")) end if (res = header_type(ind)) != Mus_riff snd_display("with_sound type (%s, r): %s?", Mus_riff, res) end if (res = chans(ind)) != 2 snd_display("with_sound chans (2, r): %s?", res) end close_sound(ind) delete_file("test1.snd") # with_sound(:srate, 48000, :channels, 2, :header_type, Mus_caff, :sample_type, Mus_lshort, :output, "test1.snd") do fm_violin(0, 0.1, 440, 0.1) end ind = find_sound("test1.snd") if srate(ind) != 48000 or mus_sound_srate("test1.snd") != 48000 snd_display("with_sound srate (48000, r): %s (%s, %s)?", srate(ind), mus_srate, mus_sound_srate("test1.snd")) end if (res = header_type(ind)) != Mus_caff snd_display("with_sound type (%s, r): %s?", Mus_caff, res) end if (res = channels(ind)) != 2 snd_display("with_sound Mus_caff chans (2, r): %s?", res) end close_sound(ind) delete_file("test1.snd") # with_sound(:srate, 8000, :channels, 3, :header_type, Mus_next, :output, "test1.snd") do fm_violin(0, 0.1, 440, 0.1) end ind = find_sound("test1.snd") if srate(ind) != 8000 or mus_sound_srate("test1.snd") != 8000 snd_display("with_sound srate (8000, s): %s (%s, %s)?", srate(ind), mus_srate, mus_sound_srate("test1.snd")) end if (res = header_type(ind)) != Mus_next snd_display("with_sound type (%s, s): %s?", Mus_next, res) end if (res = channels(ind)) != 3 snd_display("with_sound chans (3, s): %s?", res) end close_sound(ind) delete_file("test1.snd") # my_srate = 96000 with_sound(:srate, my_srate, :channels, 4, :header_type, Mus_aifc, :output, "test1.snd") do fm_violin(0, 0.1, 440, 0.1) end ind = find_sound("test1.snd") if srate(ind) != my_srate or mus_sound_srate("test1.snd") != my_srate snd_display("with_sound srate (%s, t): %s (%s, %s)?", my_srate, srate(ind), mus_srate, mus_sound_srate("test1.snd")) end if (res = header_type(ind)) != Mus_aifc snd_display("with_sound type (%s, t): %s?", Mus_aifc, res) end if (res = channels(ind)) != 4 snd_display("with_sound chans (4, t): %s?", res) end close_sound(ind) delete_file("test1.snd") with_sound(:srate, 22050, :channels, 1, :header_type, Mus_raw, :output, "test1.snd") do fm_violin(0, 0.1, 440, 0.1) end ind = find_sound("test1.snd") if srate(ind) != 22050 or mus_sound_srate("test1.snd") != 22050 snd_display("with_sound srate (22050, u: %s (%s, %s)?", srate(ind), mus_srate, mus_sound_srate("test1.snd")) end if (res = header_type(ind)) != Mus_raw snd_display("with_sound type (%s, u): %s?", Mus_raw, res) end if (res = channels(ind)) != 1 snd_display("with_sound chans (1, u): %s?", res) end close_sound(ind) delete_file("test1.snd") # with_sound(:srate, 22050, :channels, 2, :output, "test1.snd", :reverb, :jc_reverb) do if (res = mus_sound_srate(mus_file_name($output))) != 22050 snd_display("srate file $output: %s?", res) end if (res = mus_sound_srate(mus_file_name($reverb))) != 22050 snd_display("srate file $reverb: %s?", res) end fm_violin(0, 0.1, 440, 0.1, :degree, 45.0) end if sound?(ind = find_sound("test1.snd")) if framples(ind) - (22050 + 2205) > 1 snd_display("with_sound reverbed framples (2): %s?", framples(ind)) end close_sound(ind) else snd_display("with_sound (2): %s?", file_name(true)) end # with_sound(:srate, 22050, :comment, "Snd+Run!", :scaled_to, 0.5) do fm_violin(0, 0.1, 440, 0.1) end ind = find_sound("test.snd") unless ind snd_display("with_sound: %s?", file_name(true)) end if fneq(res = maxamp(ind), 0.5) snd_display("with_sound scaled_to: %s?", res) end if (res = comment(ind)) != "Snd+Run!" snd_display("with_sound comment: %s (%s)?", res, mus_sound_comment("test.snd")) end close_sound(ind) # with_sound(:srate, 22050, :scaled_by, 0.5, :header_type, Mus_aifc, :sample_type, Mus_bfloat) do fm_violin(0, 0.1, 440, 0.1) end ind = find_sound("test.snd") unless ind snd_display("with_sound: %s?", file_name(true)) end if fneq(res = maxamp(ind), 0.05) snd_display("with_sound scaled_by: %s?", res) end if (res = header_type(ind)) != Mus_aifc snd_display("with_sound type: %s (%s)?", res, mus_header_type_name(res)) end if (res = sample_type(ind)) != Mus_bfloat snd_display("with_sound format: %s (%s)?", res, mus_sample_type_name(res)) end close_sound(ind) # $open_raw_sound_hook.add_hook!("with-sound") do |file, choice| [1, 22050, Mus_bshort] end with_sound(:header_type, Mus_raw) do fm_violin(0, 0.1, 440, 0.1) end $open_raw_sound_hook.remove_hook!("with-sound") unless sound?(ind = find_sound("test.snd")) snd_display("with_sound (raw out): %s?", file_name(true)) end if (res = header_type(ind)) != Mus_raw snd_display("with_sound type raw: %s (%s)?", res, mus_header_type_name(res)) end if (res = sample_type(ind)) != Mus_bshort and res != Mus_bfloat and res != Mus_lfloat snd_display("with_sound format raw: %s (%s)?", res, mus_sample_type_name(res)) end close_sound(ind) # with_sound(:srate, 44100) do ws_sine(1000) end ind = find_sound("test.snd") i = -1 scan_channel(lambda { |y| i += 1 if fneq(y, res = sin(TWO_PI * i * (1000.0 / 44100.0))) snd_display("with_sound sine: %s %s %s", i, y, res) true else false end }) close_sound(ind) # if File.exist?("ii.rb") with_time("load(\"ii.rb\")") do load("ii.rb") end Snd.sounds.apply(:close_sound) delete_files("test.snd", "rest.reverb") end set_mus_srate($clm_srate = 22050) set_default_output_srate(22050) # outer = with_sound do sound_let(Proc.new do fm_violin(0, 0.1, 440, 0.1) end) do |tmp| clm_mix(tmp) end end.output unless string?(outer) snd_display("with_sound returns: %s?", outer) end ind = find_sound(outer) if (not sound?(ind)) or (framples(ind) - (res = (mus_srate * 0.1).floor)) > 1 snd_display("sound_let: %s %s?", framples(ind), res) end close_sound(ind) delete_file("test.snd") # outer = with_sound do sound_let(Proc.new do fm_violin(0, 0.1, 440, 0.1) end, 100) do |a, b| clm_mix(a, b) sound_let([:channels, 1, :output, "temp.snd", Proc.new do fm_violin(0, 0.1, 110, 0.1) end]) do |c| clm_mix(c) end end end.output unless string?(outer) snd_display("with_sound (2) returns: %s?", outer) end ind = find_sound(outer) if (not sound?(ind)) or (framples(ind) - (res = 100 + (mus_srate * 0.1).floor)) > 1 snd_display("sound_let (2): %s %s?", framples(ind), res) end if File.exist?("temp.snd") snd_display("sound_let explicit output exists?") end close_sound(ind) end def test_23_03 set_mus_srate($clm_srate = 22050) set_default_output_srate(22050) with_sound(:channels, 2) do fullmix("pistol.snd") fullmix("oboe.snd", 1, 2, 0, [[0.1, make_env([0, 0, 1, 1], :duration, 2, :scaler, 0.5)]]) end if sound?(ind = find_sound("test.snd")) close_sound(ind) end with_sound(:channels, 2) do fullmix("4.aiff", 0.0, 0.1, 36.4, [[0.0, 0.0], [0.0, 0.0], [1.0, 0.0], [0.0, 1.0]]) end if sound?(ind = find_sound("test.snd")) snd_test_neq(maxamp(), 0.8865, "4->2(0) fullmix") close_sound(ind) end with_sound(:channels, 1) do fullmix("4.aiff", 0.0, 0.1, 36.4, [[1.0], [0.0], [0.0], [0.0]]) end if sound?(ind = find_sound("test.snd")) snd_test_neq(maxamp(), 0.221649169921875, "4->1(0) fullmix") close_sound(ind) end with_sound(:channels, 1) do fullmix("4.aiff", 0.0, 0.1, 36.4, [[0.0], [1.0], [0.0], [0.0]]) end if sound?(ind = find_sound("test.snd")) snd_test_neq(maxamp(), 0.44329833984375, "4->1(1) fullmix") close_sound(ind) end with_sound(:channels, 1) do fullmix("4.aiff", 0.0, 0.1, 36.4, [[0.0], [0.0], [1.0], [0.0]]) end if sound?(ind = find_sound("test.snd")) snd_test_neq(maxamp(), 0.664947509765625, "4->1(2) fullmix") close_sound(ind) end with_sound(:channels, 1) do fullmix("4.aiff", 0.0, 0.1, 36.4, [[0.0], [0.0], [0.0], [1.0]]) end if sound?(ind = find_sound("test.snd")) snd_test_neq(maxamp(), 0.8865966796875, "4->1(3) fullmix") close_sound(ind) end with_sound(:channels, 2) do fullmix("4.aiff", 0.0, 0.1, 36.4, [[0.0, 0.0], [0.0, 0.0], [1.0, 0.0], [0.0, 1.0]]) end if sound?(ind = find_sound("test.snd")) mxs = maxamp(ind, true) req1 = 0.664947509765625 req2 = 0.8865966796875 if fneq(mxs[0], req1) or fneq(mxs[1], req2) snd_test_neq(mxs[0], req1, "4->2(1a) fullmix") snd_test_neq(mxs[1], req2, "4->2(1b) fullmix") end close_sound(ind) end with_sound(:channels, 2) do fullmix("4.aiff", 0.0, 0.1, 36.4, [[0.0, 0.0], [0.0, 0.0], [0.0, 1.0], [1.0, 0.0]]) end if sound?(ind = find_sound("test.snd")) mxs = maxamp(ind, true) req1 = 0.8865966796875 req2 = 0.664947509765625 if fneq(mxs[0], req1) or fneq(mxs[1], req2) snd_test_neq(mxs[0], req2, "4->2(2a) fullmix") snd_test_neq(mxs[1], req1, "4->2(2b) fullmix") end close_sound(ind) end with_sound(:channels, 2, :reverb, :nrev) do fullmix("pistol.snd", 0.0, 2.0, 0.25, false, 2.0, 0.1) fullmix("pistol.snd", 1.0, 2.0, 0.25, 0.2, 2.0, 0.1) fullmix("2a.snd", false, false, false, [[0.5, 0.0], [0.0, 0.75]]) fullmix("oboe.snd", false, false, false, [[[0, 0, 1, 1, 2, 0], 0.5]]) fullmix("oboe.snd", 3, 2, 0, [[0.1, make_env([0, 0, 1, 1], :duration, 2, :scaler, 0.5)]]) end if sound?(ind = find_sound("test.snd")) close_sound(ind) end end def test_23_04 set_mus_srate($clm_srate = 22050) set_default_output_srate(22050) with_sound(:srate, 22050) do sound_let(Proc.new do fm_violin(0, 1, 440, 0.1) end, Proc.new do fm_violin(0, 2, 660, 0.1, :base, 32.0) fm_violin(0.125, 0.5, 880, 0.1) end) do |temp_1, temp_2| clm_mix(temp_1, 0) clm_mix(temp_2, 22050) end end if sound?(ind = find_sound("test.snd")) unless maxamp(ind).between?(0.15, 0.2) snd_display("with_sound+sound_lets maxamp: %s?", maxamp(ind)) end if fneq(res = framples(ind) / srate(ind).to_f, 3.0) snd_display("with_sound+sound_lets dur: res %s frms %s sr %s?", res, framples(ind), srate(ind)) end close_sound(ind) else snd_display("with_sound+sound_lets init: no test.snd?") end # with_sound(:srate, 44100) do bigbird_2(0, 2.0, 60, 0, 0.5, [0, 0, 1, 1], [0, 0, 1, 1, 2, 1, 3, 0], [1, 1, 2, 1, 3, 1, 4, 1, 5, 1, 6, 1, 7, 1, 8, 1, 9, 1, 10, 1]) end ind = (find_sound("test.snd") or open_sound("oboe.snd")) mx = maxamp val = 0.0 freqs = Array.new(50) do |i| val += 60.0 end notch_sound(freqs) snd_test_neq(mx, 0.5, "notch_sound 60 Hz (1a)") snd_test_any_neq(maxamp(), 0.027, :ffequal?, "notch_sound 60 Hz (1b)") undo_edit notch_sound(freqs, false, ind, 0, 10) snd_test_any_neq(maxamp(), 0.011, :ffequal?, "notch_sound 60 Hz 2") undo_edit notch_channel(freqs, false, false, false, ind, 0, false, false, 10) snd_test_neq(maxamp(), 0.004, "notch_channel 60 Hz 2") undo_edit make_selection(10000, 11000) notch_selection(freqs, false, 10) close_sound(ind) # with_sound(:srate, 44100) do bigbird_2(0, 30, 60, 0, 0.5, [0, 0, 1, 1], [0, 0, 1, 1, 2, 1, 3, 0], [1, 1, 2, 1, 3, 1, 4, 1, 5, 1, 6, 1, 7, 1, 8, 1, 9, 1, 10, 1]) end ind = find_sound("test.snd") notch_sound(freqs, false, ind, 0, 10) snd_test_neq(maxamp(), 0.011, "notch_sound 60 Hz 2 60") close_sound(ind) # # from play.rb play_sine(440, 0.1) play_sines([425, 0.05], [450, 0.01], [470, 0.01], [546, 0.02], [667, 0.01], [789, 0.034], [910, 0.032]) # grani from clm-ins.rb with_sound(:channels, 2, :reverb, :jc_reverb, :reverb_channels, 1) do grani(0, 1, 0.5, "oboe.snd", :grain_envelope, [0, 0, 0.2, 0.2, 0.5, 1, 0.8, 0.2, 1, 0]) grani(0, 4, 1, "oboe.snd") grani(0, 4, 1, "oboe.snd", :grains, 10) grani(0, 4, 1, "oboe.snd", :grain_start, 0.11, :amp_envelope, [0, 1, 1, 1], :grain_density, 8, :grain_envelope, [0, 0, 0.2, 0.2, 0.5, 1, 0.8, 0.2, 1, 0], :grain_envelope_end, [0, 0, 0.01, 1, 0.99, 1, 1, 0], :grain_envelope_transition, [0, 0, 0.4, 1, 0.8, 0, 1, 0]) grani(0, 3, 1, "oboe.snd", :grain_start, 0.1, :amp_envelope, [0, 1, 1, 1], :grain_density, 20, :grain_duration, [0, 0.003, 0.2, 0.01, 1, 0.3]) grani(0, 3, 1, "oboe.snd", :grain_start, 0.1, :amp_envelope, [0, 1, 1, 1], :grain_density, 20, :grain_duration, [0, 0.003, 0.2, 0.01, 1, 0.3], :grain_duration_limit, 0.02) grani(0, 2, 1, "oboe.snd", :amp_envelope, [0, 1, 1, 1], :grain_density, 40, :grain_start, [0, 0.1, 0.3, 0.1, 1, 0.6]) grani(0, 2, 1, "oboe.snd", :amp_envelope, [0, 1, 1, 1], :grain_density, 40, :grain_start, [0, 0.1, 0.3, 0.1, 1, 0.6], :grain_start_spread, 0.01) grani(0, 2.6, 1, "oboe.snd", :grain_start, 0.1, :grain_start_spread, 0.01, :amp_envelope, [0, 1, 1, 1], :grain_density, 40, :srate, [0, 0, 0.2, 0, 0.6, 5, 1, 5]) grani(0, 2.6, 1, "oboe.snd", :grain_start, 0.1, :grain_start_spread, 0.01, :amp_envelope, [0, 1, 1, 1], :grain_density, 40, :srate_base, 2, :srate, [0, 0, 0.2, 0, 0.6, -1, 1, -1]) grani(0, 2.6, 1, "oboe.snd", :grain_start, 0.1, :grain_start_spread, 0.01, :amp_envelope, [0, 1, 1, 1], :grain_density, 40, :srate_linear, true, :srate, [0, 0, 0.2, 1, 0.6, 2 ** (5.0 / 12.0), 1, 2 ** (5.0 / 12.0)]) grani(0, 2, 1, "oboe.snd", :grain_start, 0.1, :grain_start_spread, 0.01, :amp_envelope, [0, 1, 1, 1], :grain_density, 40, :grain_duration, [0, 0.02, 1, 0.1], :grain_duration_spread, [0, 0, 0.5, 0.1, 1, 0], :where_to, Grani_to_grain_duration, :where_bins, vct(0, 0.05, 1)) grani(0, 2, 1, "oboe.snd", :grain_start, 0.1, :grain_start_spread, 0.01, :amp_envelope, [0, 1, 1, 1], :grain_density, 40, :grain_degree, [0, 0, 1, 90], :grain_degree_spread, 10) end # ind = open_sound("oboe.snd") with_sound(:output, "test1.snd") do fm_violin(0, 0.1, 440, 0.1) end set_samples(0, 2205, "test1.snd", ind, 0, false, "set_samples auto-delete test", 0, false, true) unless File.exist?("test1.snd") snd_display("oops: auto-delete test1.snd?") end undo_edit(1, ind) with_sound(:output, "test2.snd") do fm_violin(0, 0.1, 440, 0.1) end insert_sound("test2.snd", 0, 0, ind, 0, false, true) if File.exist?("test1.snd") snd_display("auto-delete set_samples?") end undo_edit(1, ind) with_sound(:output, "test3.snd") do fm_violin(0, 0.1, 440, 0.1) end insert_samples(0, 2205, "test3.snd", ind, 0, false, true) if File.exist?("test2.snd") snd_display("auto-delete insert_sound?") end undo_edit(1, ind) with_sound(:output, "test4.snd") do fm_violin(0, 0.1, 440, 0.1) end mix("test4.snd", 0, 0, ind, 0, false, true) if File.exist?("test3.snd") snd_display("auto-delete insert_samples?") end undo_edit(1, ind) delete_sample(100, ind, 0) if File.exist?("test4.snd") snd_display("auto-delete mix?") end with_sound(:output, "test5.snd") do fm_violin(0, 0.1, 440, 0.1) end mix("test5.snd", 0, 0, ind, 0, true, true) revert_sound(ind) close_sound(ind) if File.exist?("test5.snd") snd_display("auto-delete mix (with-tag)?") end Snd.sounds.apply(:close_sound) # if (res = optkey_1(1)) != 1 snd_display("optkey_1: %s?", res) end if (res = optkey_1(:a, 1)) != 1 snd_display("optkey_1 1: %s?", res) end if (res = optkey_1) != nil snd_display("optkey_1 2: %s?", res) end # if (res = optkey_2(1, 2)) != [1, 2] snd_display("optkey_2: %s?", res) end if (res = optkey_2(:a, 1, :b, 2)) != [1, 2] snd_display("optkey_2 1: %s?", res) end if (res = optkey_2) != [3, nil] snd_display("optkey_2 2: %s?", res) end if (res = optkey_2(1, :b, 2)) != [1, 2] snd_display("optkey_2 3: %s?", res) end # if (res = optkey_3(1, 2, 3)) != [1, 2, 3] snd_display("optkey_3: %s?", res) end if (res = optkey_3(1, :b, 2, :c, 3)) != [1, 2, 3] snd_display("optkey_3 1: %s?", res) end if (res = optkey_3(1, 2, :c, 3)) != [1, 2, 3] snd_display("optkey_3 2: %s?", res) end # if (res = optkey_4) != [1, 2, 3, nil] snd_display("optkey_4: %s?", res) end if (res = optkey_4(1, :b, 3, :c, 4, :d, 5)) != [1, 3, 4, 5] snd_display("optkey_4 1: %s?", res) end if (res = optkey_4(1, :d, 5, :c, 4, :b, 3)) != [1, 3, 4, 5] snd_display("optkey_4 2: %s 1?", res) end if (res = optkey_4(1, 3, 4, 5)) != [1, 3, 4, 5] snd_display("optkey_4 3: %s 2?", res) end # if defined? variable_display wid1 = make_variable_display("do-loop-1", "i*1", :text) wid2 = make_variable_display("do-loop-2", "i*2", :scale, [-1.0, 1.0]) wid3 = make_variable_display("do-loop-3", "i3", :spectrum) wid4 = make_variable_display("do-loop-4", "i4", :graph) if variable_display?(wid1) and variable_display?(wid2) and variable_display?(wid3) and variable_display?(wid4) 1000.times do |i| variable_display(wid4, variable_display(wid3, variable_display(wid2, sin(variable_display(wid1, 1) * 0.1)) * 0.5)) end tag = Snd.catch do set_sample(0, 0.5, wid3.snd, 0) end if (res = edit_position(wid3.snd, 0)) > 0 snd_display("edited variable graph: %s %s?", tag, res) end [wid1, wid2, wid3, wid4].each do |w| variable_display_close(w) end else [wid1, wid2, wid3, wid4].each_with_index do |w, i| if variable_display?(w) variable_display_close(w) else snd_display("variable_display(do-loop-%d): %s", i, w.inspect) end end end dismiss_all_dialogs end # [[:clm_srate, default_output_srate], [:clm_channels, default_output_chans], [:clm_header_type, default_output_header_type], [:clm_sample_type, default_output_sample_type], [:clm_reverb_channels, 1], [:clm_file_name, "test.snd"], [:clm_play, false], [:clm_verbose, false], [:clm_statistics, false], [:clm_reverb, nil], [:clm_delete_reverb, false], [:clm_reverb_data, []]].each do |sym, req| snd_test_neq(eval("$" + sym.to_s), req, "$%s", sym.to_s) end # $clm_channels = 2 $clm_srate = 44100 $clm_file_name = "test.wav" $clm_verbose = false $clm_statistics = false $clm_play = false $clm_sample_type = Mus_mulaw $clm_header_type = Mus_riff $clm_delete_reverb = true $clm_reverb = :jc_reverb $clm_reverb_data = [:low_pass, true, :volume, 2.0, :amp_env, [0, 1, 3, 1, 4, 0]] with_sound(:comment, "fm_violin(:reverb_amount, 0.1)") do fm_violin(0, 1, 440, 0.1, :reverb_amount, 0.1) end unless sound?(ind = find_sound("test.wav")) snd_display("default output in ws: %s?", file_name(true)) else if (res = srate(ind)) != 44100 snd_display("default srate in ws: %s %s?", res, $clm_srate) end if (res = channels(ind)) != 2 snd_display("default channels in ws: %s %s?", res, $clm_channels) end if (res = sample_type(ind)) != Mus_mulaw snd_display("default format in ws: %s %s?", res, $clm_sample_type) end if (res = header_type(ind)) != Mus_riff snd_display("default type in ws: %s %s?", res, $clm_header_type) end if (res = framples(ind)) != 88200 snd_display("reverb+1 sec out in ws: %s?", res) end if File.exist?("test.reverb") snd_display("perhaps reverb not deleted in ws?") end close_sound(ind) end # val = 0 old_hook = $clm_notehook $clm_notehook = lambda do |*args| val = 1 end with_sound(:comment, "$clm_notehook") do fm_violin(0, 0.1, 440, 0.1) end if val != 1 snd_display("$clm_notehook (1): %s %s?", val, $clm_notehook.inspect) end with_sound(:notehook, lambda do |*args| val=2 end, :comment, ":notehook") do fm_violin(0, 0.1, 440, 0.1) end if val != 2 snd_display(":notehook: %s?", val) end with_sound(:comment, "$clm_notehook (2)") do fm_violin(0, 0.1, 440, 0.1) end if val != 1 snd_display("$clm_notehook (2): %s %s?", val, $clm_notehook.inspect) end $clm_notehook = old_hook # $clm_channels = 1 $clm_srate = 22050 $clm_file_name = "test.snd" $clm_verbose = false $clm_statistics = false $clm_play = false $clm_sample_type = Mus_lfloat $clm_header_type = Mus_next $clm_delete_reverb = false $clm_reverb = nil $clm_reverb_data = [] # with_sound(:reverb, :jl_reverb) do attract(0, 1, 0.1, 2.0) expfil(0, 2, 0.2, 0.01, 0.1, "oboe.snd", "fyow.snd") fm_violin(0, 0.1, 660, 0.1, :reverb_amount, 0.1) anoi("oboe.snd", 1, 1) ind = open_sound("oboe.snd") ind1 = open_sound("now.snd") zp = make_zipper(make_env(:envelope, [0, 0, 1, 1], :length, 22050), 0.05, make_env(:envelope, [0, mus_srate() * 0.05], :length, 22050)) reader0 = make_sampler(0, ind, 0) reader1 = make_sampler(0, ind1, 0) 22050.times do |i| outa(i, zipper(zp, reader0, reader1), $output) end [ind, ind1].apply(:close_sound) end if sound?(ind = find_sound("test.snd")) select_sound(ind) zip_sound(1, 1, "fyow.snd", "now.snd", [0, 0, 1, 1], 0.05) zip_sound(2, 3, "mb.snd", "fyow.snd", [0, 0, 1, 0, 1.5, 1, 3, 1], 0.025) close_sound(ind) else snd_display("zip_sound: no test.snd?") end # ind = open_sound("oboe.snd") pv = make_pvocoder(256, 4, 64) rd = make_sampler(0) map_channel(lambda do |y| pvocoder(pv, rd) end) close_sound(ind) # make_birds if $with_test_nogui puts end Snd.sounds.apply(:close_sound) # # clm23.scm tests skipped # file = with_sound(:clipped, false, :sample_type, Mus_bfloat, :header_type, Mus_next) do fm_violin(0, 0.1, 440, PI) end.output ind = find_sound(file) if fneq(res = maxamp(ind), PI) snd_display("clipped false: %s?", res) end close_sound(ind) file = with_sound(:clipped, true, :sample_type, Mus_bfloat, :header_type, Mus_next) do fm_violin(0, 0.1, 440, PI) end.output ind = find_sound(file) if fneq(res = maxamp(ind), 1.0) snd_display("clipped true: %s?", res) end close_sound(ind) file = with_sound(:clipped, false, :sample_type, Mus_bfloat, :header_type, Mus_next, :scaled_by, 0.1) do fm_violin(0, 0.1, 440, PI) end.output ind = find_sound(file) if fneq(res = maxamp(ind), 0.314159) snd_display("scaled_by: %s?", res) end close_sound(ind) file = with_sound(:clipped, false, :sample_type, Mus_bfloat, :header_type, Mus_next, :scaled_to, 0.1) do fm_violin(0, 0.1, 440, PI) end.output ind = find_sound(file) if fneq(res = maxamp(ind), 0.1) snd_display("scaled_to: %s?", res) end close_sound(ind) # old_bufsize = $clm_file_buffer_size old_tsize = $clm_table_size old_arrp = $clm_array_print_length $clm_file_buffer_size = 1024 * 1024 $clm_table_size = 256 $clm_array_print_length = 123 tsize = 0 arrp = 0 mx = 0 file = with_sound(:sample_type, Mus_bfloat, :header_type, Mus_next) do mx = mus_file_buffer_size tsize = clm_table_size arrp = mus_array_print_length fm_violin(0, 0.1, 440, 0.1) end.output ind = find_sound(file) if mx != 1024 * 1024 snd_display("$clm_file_buffer_size: %s?", mx) end if tsize != 256 snd_display("$clm_table_size: %s?", tsize) end if arrp != 123 snd_display("$clm_array_print_length: %s?", arrp) end $clm_file_buffer_size = old_bufsize $clm_table_size = old_tsize $clm_array_print_length = old_arrp close_sound(ind) # file = with_sound() do fm_violin(0, 3.0, 440, 0.1) end.output ind = find_sound(file) set_amp_control(0.5, ind) set_x_bounds([1.0, 2.0], ind, 0) file = with_sound(:clm, false) do fm_violin(0, 4.0, 440, 0.1) end.output ind = find_sound(file) res = amp_control(ind) snd_test_neq(res, 0.5, "update ws amp") res = x_bounds(ind, 0) req = [1.0, 2.0] if fneq(res[0], req[0]) or fneq(res[1], req[1]) snd_format_neq(res, req, "update ws bounds") end close_sound(ind) # file = with_sound(:reverb, :jc_reverb) do fm_violin(0, 0.1, 440, 0.1, :reverb_amount, 0.1) end.output ind = find_sound(file) mx = maxamp(ind) file = with_sound(:reverb, :jc_reverb, :reverb_data, [:volume, 12.0, :amp_env, [0, 0, 1, 1, 20, 1, 21, 0]]) do fm_violin(0, 4, 440, 0.1, :reverb_amount, 0.1) end.output ind = find_sound(file) if maxamp(ind) <= mx snd_display("reverb_data: %s %s?", mx, maxamp(ind)) end close_sound(ind) # ind = open_sound("oboe.snd") step_src if (framples - 24602).abs > 100 snd_display("step_src framples: %s (%s)?", framples, edits) end close_sound(ind) Snd.sounds.apply(:close_sound) # file = with_sound do gen = make_sinc_train(440.0, 9 * PI) 1102.times do |i| outa(i, sinc_train(gen), $output) end end.output ind = find_sound(file) if sound?(ind) if fneq(res = maxamp(ind), 1.0) snd_display("with_sound sinc_train max: %s?", res) end close_sound(ind) else snd_display("with_sound let -> %s (%s)?", ind, file) end end require "strad" require "noise" require "piano" require "maraca" require "play" require "prc95" require "singer" require "zip" def test_23 $clm_verbose = false $clm_statistics = false $clm_play = false $clm_info = $DEBUG test_23_00 test_23_01 test_23_02 test_23_03 test_23_04 end # ---------------- test 28: errors ---------------- def check_error_tag(expected_tag, &thunk) tag = Snd.catch do thunk.call end if tag.first != expected_tag snd_display_prev_caller("%s %s: %s", get_func_name, expected_tag.inspect, tag.inspect) end end Procs = [ :add_mark, :add_sound_file_extension, :add_source_file_extension, :sound_file_extensions, :sound_file?, :add_to_main_menu, :add_to_menu, :add_transform, :amp_control, :ask_about_unsaved_edits, :as_one_edit, :ask_before_overwrite, :auto_resize, :auto_update, :autocorrelate, :axis_color, :axis_info, :axis_label_font, :axis_numbers_font, :basic_color, :bind_key, :apply_controls, :change_samples_with_origin, :channel_style, :channel_widgets, :channels, :chans, :peaks_font, :bold_peaks_font, :close_sound, :combined_data_color, :color_cutoff, :color_orientation_dialog, :colormap_ref, :add_colormap, :delete_colormap, :colormap_size, :colormap_name, :color_inverted, :color_scale, :color2list, :colormap, :color?, :comment, :contrast_control, :contrast_control_amp, :channel_properties, :channel_property, :controls2channel, :amp_control_bounds, :speed_control_bounds, :expand_control_bounds, :contrast_control_bounds, :sound_file_extensions, :reverb_control_length_bounds, :reverb_control_scale_bounds, :cursor_update_interval, :cursor_location_offset, :auto_update_interval, :current_font, :cursor, :cursor_color, :with_tracking_cursor, :cursor_size, :cursor_style, :tracking_cursor_style, :dac_combines_channels, :dac_size, :clipping, :data_color, :sample_type, :data_location, :data_size, :default_output_chans, :default_output_sample_type, :default_output_srate, :default_output_header_type, :insert_file_dialog, :file_write_date, :define_envelope, :delete_mark, :delete_marks, :forget_region, :delete_sample, :delete_samples, :delete_samples_and_smooth, :delete_selection, :delete_selection_and_smooth, :dialog_widgets, :display_edits, :dot_size, :draw_dot, :draw_dots, :draw_line, :draw_lines, :draw_string, :edit_header_dialog, :edit_fragment, :edit_list2function, :edit_position, :edit_tree, :edits, :env_selection, :env_sound, :enved_envelope, :enved_base, :enved_clip?, :enved_in_dB, :enved_dialog, :enved_style, :enved_power, :enved_target, :enved_waveform_color, :enved_wave?, :eps_file, :eps_left_margin, :eps_bottom_margin, :eps_size, :expand_control, :expand_control_hop, :expand_control_jitter, :expand_control_length, :expand_control_ramp, :expand_control?, :fft, :fft_window_beta, :fft_window_alpha, :fft_with_phases, :fft_log_frequency, :fft_log_magnitude, :transform_size, :disk_kspace, :transform_graph_type, :fft_window, :transform_graph?, :mix_file_dialog, :file_name, :fill_polygon, :fill_rectangle, :filter_sound, :filter_control_in_dB, :filter_control_envelope, :enved_filter_order, :enved_filter, :filter_control_in_hz, :filter_control_order, :filter_selection, :filter_channel, :filter_control_waveform_color, :filter_control?, :find_mark, :find_sound, :finish_progress_report, :foreground_color, :framples, :free_sampler, :graph, :transform?, :delete_transform, :graph_color, :graph_cursor, :graph_data, :graph2ps, :gl_graph2ps, :graph_style, :lisp_graph?, :graphs_horizontal, :header_type, :help_dialog, :info_dialog, :highlight_color, :call_in, :insert_region, :insert_sample, :insert_samples, :insert_samples_with_origin, :insert_selection, :insert_silence, :insert_sound, :just_sounds, :key, :key_binding, :left_sample, :listener_color, :listener_font, :listener_prompt, :listener_selection, :listener_text_color, :main_widgets, :make_color, :make_graph_data, :make_mix_sampler, :make_player, :make_region, :make_region_sampler, :make_sampler, :map_chan, :mark_color, :mark_name, :mark_properties, :mark_property, :mark_sample, :mark_sync, :mark_sync_max, :mark_home, :marks, :mark?, :max_transform_peaks, :max_regions, :maxamp, :maxamp_position, :menu_widgets, :min_dB, :log_freq_start, :mix, :mixes, :mix_amp, :mix_amp_env, :mix_color, :mix_length, :mix?, :view_mixes_dialog, :mix_position, :mix_dialog_mix, :mix_name, :mix_sync_max, :mix_sync, :mix_properties, :mix_property, :mix_region, :mix_sampler?, :mix_selection, :mix_home, :mix_speed, :mix_tag_height, :mix_tag_width, :mark_tag_height, :mark_tag_width, :mix_tag_y, :mix_vct, :mix_waveform_height, :time_graph_style, :lisp_graph_style, :transform_graph_style, :read_mix_sample, :next_sample, :read_region_sample, :show_full_duration, :show_full_range, :initial_beg, :initial_dur, :transform_normalization, :open_file_dialog_directory, :open_raw_sound, :open_sound, :color_orientation_dialog, :previous_sample, :peaks, :player?, :players, :play_arrow_size, :position_color, :position2x, :position2y, :print_length, :progress_report, :read_only, :redo_edit, :region_chans, :view_regions_dialog, :region_home, :region_graph_style, :region_framples, :region_position, :region_maxamp, :region_maxamp_position, :remember_sound_state, :selection_maxamp, :selection_maxamp_position, :region_sample, :region2vct, :region_srate, :regions, :region?, :remove_from_menu, :reset_controls, :restore_controls, :restore_region, :reverb_control_decay, :reverb_control_feedback, :reverb_control_length, :reverb_control_lowpass, :reverb_control_scale, :reverb_control?, :reverse_sound, :reverse_selection, :revert_sound, :right_sample, :sample, :sampler_at_end?, :sampler?, :samples, :sampler_position, :sash_color, :save_controls, :ladspa_dir, :peak_env_dir, :save_dir, :save_edit_history, :save_envelopes, :save_listener, :save_marks, :save_region, :save_selection, :save_sound, :save_sound_as, :save_state, :save_state_file, :scale_by, :scale_selection_by, :scale_selection_to, :scale_to, :search_procedure, :select_all, :select_channel, :select_sound, :selected_channel, :selected_data_color, :selected_graph_color, :selected_sound, :selection_position, :selection_color, :selection_creates_region, :selection_framples, :selection_member?, :selection?, :short_file_name, :show_axes, :show_controls, :show_transform_peaks, :show_indices, :show_listener, :show_selection, :unselect_all, :show_marks, :show_mix_waveforms, :show_selection_transform, :show_y_zero, :sinc_width, :show_grid, :show_sonogram_cursor, :grid_density, :smooth_sound, :smooth_selection, :snd_spectrum, :snd_tempnam, :snd_version, :sound_files_in_directory, :sound_loop_info, :sound_widgets, :soundfont_info, :sound?, :sounds, :spectrum_end, :spectro_hop, :spectrum_start, :spectro_x_angle, :spectro_x_scale, :spectro_y_angle, :spectro_y_scale, :spectro_z_angle, :spectro_z_scale, :speed_control, :speed_control_style, :speed_control_tones, :squelch_update, :srate, :src_sound, :src_selection, :start_progress_report, :stop_player, :stop_playing, :swap_channels, :syncd_marks, :sync, :sync_max, :sound_properties, :sound_property, :temp_dir, :text_focus_color, :tiny_font, :region_sampler?, :transform_dialog, :transform_sample, :transform2vct, :transform_framples, :transform_type, :with_file_monitor, :unbind_key, :update_transform_graph, :update_time_graph, :update_lisp_graph, :update_sound, :clm_table_size, :with_verbose_cursor, :view_sound, :wavelet_type, :with_inset_graph, :with_interrupts, :with_pointer_focus, :with_smpte_label, :with_toolbar, :with_tooltips, :with_menu_icons, :save_as_dialog_src, :save_as_dialog_auto_comment, :time_graph?, :time_graph_type, :wavo_hop, :wavo_trace, :window_height, :window_width, :window_x, :window_y, :with_mix_tags, :with_relative_panes, :with_gl, :x_axis_style, :beats_per_measure, :beats_per_minute, :x_bounds, :x_position_slider, :x2position, :x_zoom_slider, :mus_header_type2string, :mus_sample_type2string, :y_bounds, :y_position_slider, :y2position, :y_zoom_slider, :zero_pad, :zoom_color, :zoom_focus_style, :sync_style, :mus_set_formant_radius_and_frequency, :mus_sound_samples, :mus_sound_framples, :mus_sound_duration, :mus_sound_datum_size, :mus_sound_data_location, :data_size, :mus_sound_chans, :mus_sound_srate, :mus_sound_header_type, :mus_sound_sample_type, :mus_sound_length, :mus_sound_type_specifier, :mus_header_type_name, :mus_sample_type_name, :mus_sound_comment, :mus_sound_write_date, :mus_bytes_per_sample, :mus_sound_loop_info, :mus_sound_mark_info, :mus_sound_maxamp, :mus_sound_maxamp_exists?, :mus_clipping, :mus_file_clipping, :mus_header_raw_defaults, :moving_average, :moving_average?, :make_moving_average, :mus_expand_filename, :all_pass, :all_pass?, :amplitude_modulate, :array2file, :array_interp, :mus_interpolate, :asymmetric_fm, :asymmetric_fm?, :comb, :comb?, :filtered_comb, :filtered_comb?, :contrast_enhancement, :convolution, :convolve, :convolve?, :db2linear, :degrees2radians, :delay, :delay?, :dot_product, :env, :env_interp, :env?, :file2array, :file2frample, :file2frample?, :file2sample, :file2sample?, :filter, :filter?, :fir_filter, :fir_filter?, :formant, :formant_bank, :formant_bank?, :formant?, :frample2file, :frample2file?, :frample2frample, :granulate, :granulate?, :hz2radians, :iir_filter, :iir_filter?, :in_any, :ina, :inb, :linear2db, :locsig, :locsig_ref, :locsig_reverb_ref, :locsig_reverb_set!, :locsig_set!, :locsig?, :make_all_pass, :make_asymmetric_fm, :make_comb, :make_convolve, :make_delay, :make_env, :make_fft_window, :make_file2frample, :make_file2sample, :make_filter, :make_fir_filter, :make_formant, :make_frample2file, :make_granulate, :make_iir_filter, :make_locsig, :move_locsig, :make_notch, :make_one_pole, :make_one_zero, :make_oscil, :make_pulse_train, :make_rand, :make_rand_interp, :make_readin, :make_sample2file, :make_sawtooth_wave, :make_square_wave, :make_src, :make_ssb_am, :make_table_lookup, :make_triangle_wave, :make_two_pole, :make_two_zero, :make_wave_train, :move_sound, :make_move_sound, :move_sound?, :mus_float_equal_fudge_factor, :mus_array_print_length, :mus_channel, :mus_channels, :make_polyshape, :polyshape, :polyshape?, :mus_close, :mus_data, :mus_feedback, :mus_feedforward, :mus_fft, :mus_frequency, :mus_hop, :mus_increment, :mus_input?, :mus_file_name, :mus_length, :mus_location, :mus_order, :mus_output?, :mus_phase, :mus_ramp, :mus_random, :mus_scaler, :mus_srate, :mus_xcoeffs, :mus_ycoeffs, :notch, :notch?, :one_pole, :one_pole?, :one_zero, :one_zero?, :oscil, :oscil?, :out_any, :outa, :outb, :outc, :outd, :partials2polynomial, :partials2wave, :phase_partials2wave, :polynomial, :pulse_train, :pulse_train?, :radians2degrees, :radians2hz, :rand, :rand_interp, :rand_interp?, :rand?, :readin, :readin?, :rectangular2polar, :rectangular2magnitudes, :ring_modulate, :sample2file, :sample2file?, :sawtooth_wave, :sawtooth_wave?, :spectrum, :square_wave, :square_wave?, :src, :src?, :ssb_am, :ssb_am?, :table_lookup, :table_lookup?, :tap, :triangle_wave, :triangle_wave?, :two_pole, :two_pole?, :two_zero, :two_zero?, :wave_train, :wave_train?, :make_vct, :vct_add!, :vct_subtract!, :vct_copy, :vct_length, :vct_multiply!, :vct_offset!, :vct_ref, :vct_scale!, :vct_set!, :vct_peak, :vct?, :list2vct, :vct2list, :vector2vct, :vct2vector, :vct_move!, :vct_reverse!, :vct_subseq, :vct, :little_endian?, :vct2string, :clm_channel, :env_channel, :map_channel, :scan_channel, :reverse_channel, :seconds2samples, :samples2seconds, :vct2channel, :smooth_channel, :channel2vct, :src_channel, :scale_channel, :ramp_channel, :pad_channel, :normalize_channel, :cursor_position, :mus_sound_prune, :mus_sound_forget, :xramp_channel, :snd2sample, :snd2sample?, :make_snd2sample, :beats_per_minute, :beats_per_measure, :channel_amp_envs, :convolve_files, :filter_control_coeffs, :locsig_type, :make_phase_vocoder, :mus_describe, :mus_error_type2string, :mus_file_buffer_size, :mus_name, :mus_offset, :mus_reset, :mus_rand_seed, :mus_width, :phase_vocoder?, :polar2rectangular, :phase_vocoder_amp_increments, :phase_vocoder_amps, :phase_vocoder_freqs, :phase_vocoder_phase_increments, :phase_vocoder_phases, :mus_generator?, :read_sample, :reset_listener_cursor, :goto_listener_end, :sampler_home, :selection_chans, :selection_srate, :snd_gcs, :snd_font, :snd_color, :snd_warning, :channel_data, :x_axis_label, :variable_graph?, :y_axis_label, :snd_url, :snd_urls, :free_player, :delay_tick, :playing, :draw_axes, :copy_sampler, :html_dir, :html_program, :make_fir_coeffs, :mus_interp_type, :mus_run, :phase_vocoder, :player_home, :redo_edit, :undo_edit, :widget_position, :widget_size, :focus_widget] Set_procs = [ :amp_control, :ask_before_overwrite, :auto_resize, :sound_file_extensions, :auto_update, :axis_color, :axis_label_font, :axis_numbers_font, :channel_style, :peaks_font, :bold_peaks_font, :show_full_duration, :show_full_range, :initial_beg, :initial_dur, :color_cutoff, :color_inverted, :color_scale, :contrast_control, :contrast_control_amp, :combined_data_color, :amp_control_bounds, :speed_control_bounds, :expand_control_bounds, :contrast_control_bounds, :reverb_control_length_bounds, :reverb_control_scale_bounds, :cursor_update_interval, :cursor_location_offset, :contrast_control?, :auto_update_interval, :current_font, :cursor, :cursor_color, :channel_properties, :channel_property, :with_tracking_cursor, :cursor_size, :cursor_style, :tracking_cursor_style, :dac_combines_channels, :dac_size, :clipping, :data_color, :default_output_chans, :default_output_sample_type, :default_output_srate, :default_output_header_type, :dot_size, :enved_envelope, :enved_base, :enved_clip?, :enved_in_dB, :enved_style, :enved_power, :enved_target, :enved_waveform_color, :enved_wave?, :eps_file, :eps_left_margin, :eps_bottom_margin, :eps_size, :expand_control, :expand_control_hop, :expand_control_jitter, :expand_control_length, :expand_control_ramp, :expand_control?, :fft_window_beta, :fft_window_alpha, :fft_with_phases, :fft_log_frequency, :fft_log_magnitude, :transform_size, :transform_graph_type, :fft_window, :transform_graph?, :filter_control_in_dB, :filter_control_envelope, :axis_color, :enved_filter_order, :enved_filter, :filter_control_in_hz, :filter_control_order, :filter_control_waveform_color, :filter_control?, :foreground_color, :graph_color, :graph_cursor, :graph_style, :lisp_graph?, :graphs_horizontal, :highlight_color, :just_sounds, :left_sample, :listener_color, :listener_font, :listener_prompt, :listener_text_color, :mark_color, :mark_name, :mark_properties, :mark_property, :mark_sample, :mark_sync, :max_transform_peaks, :max_regions, :min_dB, :log_freq_start, :mix_amp, :mix_amp_env, :mix_color, :mix_name, :mix_position, :mix_sync, :mix_properties, :mix_property, :mix_speed, :mix_tag_height, :mix_tag_width, :mix_tag_y, :mark_tag_width, :mark_tag_height, :mix_waveform_height, :transform_normalization, :open_file_dialog_directory, :position_color, :print_length, :play_arrow_size, :region_graph_style, :reverb_control_decay, :reverb_control_feedback, :reverb_control_length, :reverb_control_lowpass, :reverb_control_scale, :time_graph_style, :lisp_graph_style, :transform_graph_style, :reverb_control?, :sash_color, :ladspa_dir, :peak_env_dir, :save_dir, :save_state_file, :selected_data_color, :selected_graph_color, :selection_color, :selection_creates_region, :show_axes, :show_controls, :show_transform_peaks, :show_indices, :show_marks, :show_mix_waveforms, :show_selection_transform, :show_listener, :show_y_zero, :show_grid, :show_sonogram_cursor, :sinc_width, :spectrum_end, :spectro_hop, :spectrum_start, :spectro_x_angle, :grid_density, :spectro_x_scale, :spectro_y_angle, :spectro_y_scale, :spectro_z_angle, :spectro_z_scale, :speed_control, :speed_control_style, :speed_control_tones, :squelch_update, :sync, :sound_properties, :sound_property, :temp_dir, :text_focus_color, :tiny_font, :y_bounds, :transform_type, :with_file_monitor, :with_verbose_cursor, :with_inset_graph, :with_interrupts, :with_pointer_focus, :wavelet_type, :x_bounds, :with_smpte_label, :with_toolbar, :with_tooltips, :with_menu_icons, :save_as_dialog_src, :save_as_dialog_auto_comment, :time_graph?, :wavo_hop, :wavo_trace, :with_gl, :with_mix_tags, :x_axis_style, :beats_per_minute, :zero_pad, :zoom_color, :zoom_focus_style, :sync_style, :with_relative_panes, :window_x, :window_y, :window_width, :window_height, :mix_dialog_mix, :beats_per_measure, :channels, :chans, :colormap, :comment, :sample_type, :data_location, :data_size, :edit_position, :framples, :header_type, :maxamp, :read_only, :right_sample, :sample, :samples, :selected_channel, :colormap_size, :selected_sound, :selection_position, :selection_framples, :selection_member?, :sound_loop_info, :srate, :time_graph_type, :x_position_slider, :x_zoom_slider, :y_position_slider, :y_zoom_slider, :mus_array_print_length, :mus_float_equal_fudge_factor, :mus_feedback, :mus_feedforward, :mus_frequency, :mus_hop, :mus_increment, :mus_length, :mus_location, :mus_phase, :mus_ramp, :mus_scaler, :x_axis_label, :locsig_type, :mus_file_buffer_size, :mus_rand_seed, :mus_width, :clm_table_size, :mus_offset, :html_dir, :html_program, :widget_position, :widget_size, :mus_clipping, :mus_header_raw_defaults] Make_procs = [ :make_all_pass, :make_asymmetric_fm, :make_snd2sample, :make_moving_average, :make_moving_max, :make_comb, :make_filtered_comb, :make_convolve, :make_delay, :make_env, :make_fft_window, :make_file2frample, :make_file2sample, :make_filter, :make_fir_filter, :make_formant, :make_frample2file, :make_granulate, :make_iir_filter, :make_locsig, :make_notch, :make_one_pole, :make_one_zero, :make_oscil, :make_pulse_train, :make_rand, :make_rand_interp, :make_readin, :make_sample2file, :make_sawtooth_wave, :make_square_wave, :make_src, :make_table_lookup, :make_triangle_wave, :make_two_pole, :make_two_zero, :make_wave_train, :make_phase_vocoder, :make_ssb_am, :make_polyshape, :make_color, :make_player, :make_region] Keyargs = [ :frequency, :initial_phase, :wave, :cosines, :amplitude, :ratio, :size, :a0, :a1, :a2, :b1, :b2, :input, :srate, :file, :channel, :start, :initial_contents, :initial_element, :scaler, :feedforward, :feedback, :max_size, :radius, :gain, :partials, :r, :a, :n, :fill_time, :order, :xcoeffs, :ycoeffs, :envelope, :base, :duration, :offset, :end, :direction, :degree, :distance, :reverb, :output, :fft_size, :expansion, :length, :hop, :ramp, :jitter, :type, :format, :comment, :channels, :filter, :revout, :width, :edit, :synthesize, :analyze, :interp, :overlap, :pitch, :distribution, :sines, :dur] class Array # If body results in true, returns the rejected elements in a new # array and remove these elements from the original. def remove_if! ret = [] self.map! do |x| if yield(x) ret.push(x) nil else x end end self.compact! ret end end Procs00 = Procs.remove_if! do |n| function?(n) and arity_ok(n, 0) end Set_procs00 = Set_procs.remove_if! do |n| function?(n) and set_arity_ok(n, 1) end Procs01 = Procs.remove_if! do |n| function?(n) and arity_ok(n, 1) end Set_procs01 = Set_procs.remove_if! do |n| function?(n) and set_arity_ok(n, 2) end Procs02 = Procs.remove_if! do |n| function?(n) and arity_ok(n, 2) end Set_procs02 = Set_procs.remove_if! do |n| function?(n) and set_arity_ok(n, 3) end Procs03 = Procs.remove_if! do |n| function?(n) and arity_ok(n, 3) end Set_procs03 = Set_procs.remove_if! do |n| function?(n) and set_arity_ok(n, 4) end Procs04 = Procs.remove_if! do |n| function?(n) and arity_ok(n, 4) end Set_procs04 = Set_procs.remove_if! do |n| function?(n) and set_arity_ok(n, 5) end Procs05 = Procs.remove_if! do |n| function?(n) and arity_ok(n, 5) end Procs06 = Procs.remove_if! do |n| function?(n) and arity_ok(n, 6) end # Procs07 is not used Procs07 = Procs.remove_if! do |n| function?(n) and arity_ok(n, 7) end Procs08 = Procs.remove_if! do |n| function?(n) and arity_ok(n, 8) end Procs10 = Procs.remove_if! do |n| function?(n) and arity_ok(n, 10) end $delay_32 = make_oscil(440) $color_95 = vector(1, 2, 3) $vector_0 = make_comb(0.1, 3) $vct_3 = Vct.new(3) def test_28_00 procs1 = [ :amp_control, :apply_controls, :comment, :contrast_control, :amp_control_bounds, :speed_control_bounds, :expand_control_bounds, :contrast_control_bounds, :reverb_control_length_bounds, :reverb_control_scale_bounds, :contrast_control_amp, :contrast_control?, :sample_type, :data_location, :data_size, :expand_control, :expand_control_hop, :expand_control_jitter, :expand_control_length, :expand_control_ramp, :expand_control?, :filter_control_in_dB, :filter_control_in_hz, :filter_control_envelope, :filter_control_order, :filter_control?, :finish_progress_report, :framples, :header_type, :progress_report, :read_only, :reset_controls, :restore_controls, :reverb_control_decay, :reverb_control_feedback, :reverb_control_length, :reverb_control_lowpass, :reverb_control_scale, :reverb_control?, :save_controls, :select_sound, :short_file_name, :sound_loop_info, :soundfont_info, :speed_control, :speed_control_style, :speed_control_tones, :srate, :channel_style, :start_progress_report, :sync, :sound_properties, :sound_property, :swap_channels] procs1.each do |n| tag = Snd.catch do snd_func(n, integer2sound(123)) end if tag.first != :no_such_sound snd_display("snd :no_such_sound %s: %s", n, tag) end end [sqrt(-1.0), 1.5, "hiho"].each do |arg| procs1.each do |n| next if n == :progress_report tag = Snd.catch do snd_func(n, arg) end if tag.first != :wrong_type_arg and tag.first != :mus_error and tag.first != :no_such_sound snd_display("snd :wrong_type_arg %s: %s %s", n, tag, arg) end end end progs2 = [ :amp_control, :channels, :chans, :comment, :contrast_control, :amp_control_bounds, :speed_control_bounds, :expand_control_bounds, :contrast_control_bounds, :reverb_control_length_bounds, :reverb_control_scale_bounds, :contrast_control_amp, :contrast_control?, :sample_type, :data_location, :data_size, :expand_control, :expand_control_hop, :expand_control_jitter, :expand_control_length, :expand_control_ramp, :expand_control?, :filter_control_in_dB, :filter_control_in_hz, :filter_control_envelope, :filter_control_order, :filter_control?, :framples, :header_type, :read_only, :reverb_control_decay, :reverb_control_feedback, :reverb_control_length, :reverb_control_lowpass, :reverb_control_scale, :reverb_control?, :sound_loop_info, :speed_control, :speed_control_style, :speed_control_tones, :srate, :channel_style, :sync] [sqrt(-1.0), 1.5, "hiho"].each do |arg| progs2.each_with_index do |n, i| if (tag = Snd.catch do case n when :channels, :chans, :sample_type, :data_location, :data_size, :header_type, :srate, :comment # g_set_channels(snd, val) set_snd_func(n, arg, 0) else # g_set_amp_control(val, snd, chn) set_snd_func(n, 0, arg) end end).first != :wrong_type_arg snd_display("snd set :wrong_type_arg %s %s: %s %s", i, n, tag, arg) end end end progs3 = [ :amp_control, :contrast_control, :amp_control_bounds, :speed_control_bounds, :expand_control_bounds, :contrast_control_bounds, :reverb_control_length_bounds, :reverb_control_scale_bounds, :contrast_control_amp, :contrast_control?, :expand_control, :expand_control_hop, :expand_control_jitter, :expand_control_length, :expand_control_ramp, :expand_control?, :filter_control_in_dB, :filter_control_in_hz, :filter_control_envelope, :filter_control_order, :filter_control?, :reverb_control_decay, :reverb_control_feedback, :reverb_control_length, :reverb_control_lowpass, :reverb_control_scale, :reverb_control?, :speed_control, :speed_control_style, :speed_control_tones, :channel_style, :sync] index = open_sound("obtest.snd") [sqrt(-1.0), "hiho"].each do |arg| progs3.each_with_index do |n, i| tag = Snd.catch do set_snd_func(n, arg, index) end if tag.first != :wrong_type_arg snd_display("snd safe set :wrong_type_arg %s %s: %s %s", i, n, tag, arg) end end end close_sound(index) [Array.new(1), "hiho", sqrt(-1.0), 1.5, [1, 0], [0, 1]].each do |arg| [:make_vct, :vct_copy, :vct_length, :vct2list, :vct_peak].each do |n| if (tag = Snd.catch do snd_func(n, arg) end).first != :wrong_type_arg snd_display("vct 0 :wrong_type_arg %s: %s %s", n, tag, arg) end end end [Array.new(1), "hiho", sqrt(-1.0), 1.5, [1, 0], [0, 1]].each do |arg1| ["hiho", sqrt(-1.0), 1.5, [1, 0], [0, 1]].each do |arg2| [:vct_add!, :vct_subtract!, :vct_multiply!, :vct_ref, :vct_scale!].each do |n| case tag = (res = Snd.catch do snd_func(n, arg1, arg2) end).first when :wrong_type_arg, :wrong_number_of_args, :mus_error nil else snd_display("vct 1 :wrong_whatever %s: %s %s %s (%s)", n, tag, arg1, arg2, res) end end end end [Array.new(1), "hiho", sqrt(-1.0), [1, 0], [0, 1]].each do |arg| [:vct_add!, :vct_subtract!, :vct_multiply!, :vct_ref, :vct_scale!].each do |n| tag = Snd.catch do snd_func(n, $vct_3, arg) end if tag.first != :wrong_type_arg snd_display("vct 2 :wrong_type_arg %s: %s %s", n, tag, arg) end end end if (tag = Snd.catch do make_vct(-23) end).first != :out_of_range snd_display("make_vct -23: %s", tag) end if (tag = Snd.catch do Vct.new(-23) end).first != :out_of_range snd_display("Vct.new -23: %s", tag) end v = $vct_3 if (tag = Snd.catch do vct_ref(v, 12) end).first != :out_of_range snd_display("vct_ref 12: %s", tag) end if (tag = Snd.catch do v[12] end).first != :out_of_range snd_display("v[12]: %s", tag) end procs_p = [ :all_pass?, :asymmetric_fm?, :comb?, :filtered_comb?, :convolve?, :delay?, :env?, :file2frample?, :file2sample?, :snd2sample?, :filter?, :fir_filter?, :formant?, :frample2file?, :frame?, :granulate?, :iir_filter?, :locsig?, :mixer?, :move_sound?, :mus_input?, :mus_output?, :notch?, :one_pole?, :one_zero?, :oscil?, :phase_vocoder?, :pulse_train?, :rand_interp?, :rand?, :readin?, :sample2file?, :sawtooth_wave?, :square_wave?, :src?, :table_lookup?, :triangle_wave?, :two_pole?, :two_zero?, :wave_train?, :color?, :mix_sampler?, :moving_average?, :ssb_am?, :sampler?, :region_sampler?, :vct?] [Array.new(1), "hiho", sqrt(-1.0), 1.5, [1, 0], [0, 1]].each do |arg| procs_p.each do |n| if (tag = Snd.catch do snd_func(n, arg) end).first.kind_of?(TrueClass) snd_display("?proc %s: %s %s", n, tag, arg) end end end procs_p.each do |n| next if n == :oscil? tag = Snd.catch do snd_func(n, make_oscil(440)) end if tag.first.kind_of?(TrueClass) snd_display("oscil?proc %s: %s", n, tag) end end [:reverse_selection, :selection_position, :selection_framples, :smooth_selection, :scale_selection_to, :insert_selection, :delete_selection, :delete_selection_and_smooth, :mix_selection].each do |n| if (tag = Snd.catch do snd_func(n) end).first != :no_active_selection snd_display("selection %s: %s", n, tag) end end [:src_selection, :filter_selection, :env_selection].each do |n| if (tag = Snd.catch do snd_func(n, 0.0) end).first != :no_active_selection snd_display("selection %s: %s", n, tag) end end [make_vector(1), $color_95, [1.0]].each do |arg| [:all_pass, :asymmetric_fm, :comb, :filtered_comb, :convolve, :db2linear, :moving_average, :degrees2radians, :delay, :env, :formant, :granulate, :hz2radians, :linear2db, :make_all_pass, :make_asymmetric_fm, :make_comb, :make_filtered_comb, :make_convolve, :make_delay, :make_env, :make_file2frample, :make_file2sample, :make_filter, :make_fir_filter, :make_formant, :make_granulate, :make_iir_filter, :make_locsig, :make_notch, :make_one_pole, :make_one_zero, :make_oscil, :make_pulse_train, :make_rand, :make_rand_interp, :make_readin, :make_sawtooth_wave, :make_square_wave, :make_src, :make_table_lookup, :make_triangle_wave, :make_two_pole, :make_two_zero, :make_wave_train, :make_ssb_am, :mus_channel, :mus_channels, :make_polyshape, :mus_data, :mus_feedback, :mus_feedforward, :mus_frequency, :mus_hop, :mus_increment, :mus_length, :mus_file_name, :mus_location, :mus_order, :mus_phase, :mus_ramp, :mus_random, :mus_run, :mus_scaler, :mus_xcoeffs, :mus_ycoeffs, :notch, :one_pole, :one_zero, :make_moving_average, :seconds2samples, :samples2seconds, :oscil, :partials2polynomial, :partials2wave, :phase_vocoder, :pulse_train, :radians2degrees, :radians2hz, :rand, :rand_interp, :readin, :sawtooth_wave, :square_wave, :src, :table_lookup, :tap, :triangle_wave, :two_pole, :two_zero, :wave_train, :ssb_am].each do |n| tag = Snd.catch do snd_func(n, arg) end case tag.first when :wrong_type_arg, :no_data, :no_such_method, :bad_type, :error, :arg_error next else snd_display("clm %s: tag %s, arg %s", n, tag, arg) end end end # XXX: phase_partials2wave in clm (test 28) # Original included in test above but Ruby's phase_partials2wave # takes Arrays and Vecs as lists. [make_vector(1), $color_95.to_a + [0], [1.0]].each do |arg| n = :phase_partials2wave tag = Snd.catch do snd_func(n, arg) end case tag.first when :wrong_type_arg, :no_data, :no_such_method, :bad_type, :error, :arg_error next else snd_display("clm %s: tag %s, arg %s", n, tag, arg) end end [:all_pass, :array_interp, :asymmetric_fm, :comb, :filtered_comb, :contrast_enhancement, :convolution, :convolve, :moving_average, :moving_max, :convolve_files, :delay, :dot_product, :env_interp, :file2frample, :file2sample, :snd2sample, :filter, :fir_filter, :formant, :firmant, :formant_bank, :granulate, :iir_filter, :ina, :inb, :locsig_ref, :locsig_reverb_ref, :make_all_pass, :make_asymmetric_fm, :make_comb, :make_filtered_comb, :make_delay, :make_env, :make_fft_window, :make_filter, :make_fir_filter, :make_formant, :make_firmant, :make_granulate, :make_iir_filter, :make_locsig, :make_notch, :make_one_pole, :make_one_zero, :make_oscil, :make_phase_vocoder, :make_pulse_train, :make_rand, :make_rand_interp, :make_readin, :make_sawtooth_wave, :make_moving_average, :make_nrxysin, :make_nrxycos, :make_square_wave, :make_src, :make_ncos, :make_nsin, :make_table_lookup, :make_triangle_wave, :make_two_pole, :make_two_zero, :make_wave_train, :notch, :one_pole, :one_zero, :oscil, :partials2polynomial, :partials2wave, :make_polyshape, :make_polywave, :phase_partials2wave, :phase_vocoder, :polynomial, :pulse_train, :rand, :rand_interp, :rectangular2polar, :rectangular2magnitudes, :ring_modulate, :sawtooth_wave, :nrxysin, :nrxycos, :square_wave, :src, :ncos, :nsin, :table_lookup, :tap, :triangle_wave, :two_pole, :two_zero, :wave_train, :ssb_am, :make_ssb_am].each do |n| tag = Snd.catch do snd_func(n, make_oscil, $vct_3) end case tag.first when :wrong_type_arg, :bad_arity, :error, :mus_error next else snd_display("clm-1 %s: %s", n, tag) end end [:mus_data, :mus_feedback, :mus_feedforward, :mus_frequency, :mus_hop, :mus_increment, :mus_length, :mus_location, :mus_phase, :mus_ramp, :mus_scaler].each do |n| tag = Snd.catch do set_snd_func(n, make_oscil, $vector_0) end case tag.first when :wrong_type_arg, :error next else snd_display("mus-gen %s: %s", n, tag) end end mus_procs = [ :mus_sound_samples, :mus_sound_framples, :mus_sound_duration, :mus_sound_datum_size, :mus_sound_data_location, :mus_sound_chans, :mus_sound_srate, :mus_sound_header_type, :mus_sound_sample_type, :mus_sound_length, :mus_sound_type_specifier, :mus_header_type_name, :mus_sample_type_name, :mus_sound_comment, :mus_sound_write_date, :mus_bytes_per_sample, :mus_sound_loop_info, :mus_sound_mark_info, :mus_sound_maxamp, :mus_sound_maxamp_exists?, :mus_header_type2string, :mus_sample_type2string] mus_procs.each do |n| tag = Snd.catch do snd_func(n, $vct_3) end if tag.first != :wrong_type_arg snd_display("mus-sound %s: %s", n, tag) end end mus_procs.each do |n| tag = Snd.catch do snd_func(n) end case tag.first when :wrong_number_of_args, :error next else snd_display("no arg mus-sound %s: %s", n, tag) end end end def test_28_01 [:mus_sound_samples, :mus_sound_framples, :mus_sound_duration, :mus_sound_datum_size, :mus_sound_data_location, :mus_sound_chans, :mus_sound_srate, :mus_sound_header_type, :mus_sound_sample_type, :mus_sound_length, :mus_sound_type_specifier, :mus_sound_comment, :mus_sound_write_date, :mus_sound_maxamp, :mus_sound_maxamp_exists?].each do |n| tag = Snd.catch do snd_func(n, "/bad/baddy") end if tag.first != :mus_error snd_display("bad file mus-sound %s: %s", n, tag) end end mus_sound_forget("/bad/baddy") [:channel_widgets, :cursor, :channel_properties, :channel_property, :cursor_position, :cursor_size, :cursor_style, :tracking_cursor_style, :delete_sample, :display_edits, :dot_size, :draw_dots, :draw_lines, :edit_fragment, :edit_list2function, :edit_position, :edit_tree, :edits, :fft_window_alpha, :fft_window_beta, :fft_log_frequency, :fft_log_magnitude, :fft_with_phases, :transform_size, :transform_graph_type, :fft_window, :transform_graph?, :graph, :graph_style, :lisp_graph?, :insert_sound, :time_graph_style, :lisp_graph_style, :transform_graph_style, :left_sample, :make_graph_data, :map_chan, :max_transform_peaks, :maxamp_position, :min_dB, :mix_region, :transform_normalization, :peaks, :play, :position2x, :position2y, :reverse_sound, :revert_sound, :right_sample, :sample, :save_sound, :save_sound_as, :select_channel, :show_axes, :show_transform_peaks, :show_marks, :show_mix_waveforms, :show_y_zero, :show_grid, :show_sonogram_cursor, :spectrum_end, :spectro_hop, :spectrum_start, :spectro_x_angle, :spectro_x_scale, :spectro_y_angle, :grid_density, :spectro_y_scale, :spectro_z_angle, :spectro_z_scale, :squelch_update, :transform_sample, :transform2vct, :transform_framples, :transform_type, :update_transform_graph, :update_time_graph, :update_lisp_graph, :update_sound, :wavelet_type, :time_graph?, :time_graph_type, :wavo_hop, :wavo_trace, :x_bounds, :x_position_slider, :x_zoom_slider, :x_axis_label, :y_axis_label, :y_bounds, :y_position_slider, :y_zoom_slider, :zero_pad].each_with_index do |n, i| case (tag = Snd.catch do snd_func(n, $vct_3) end).first when :wrong_type_arg, :no_such_sound next else snd_display("%s: chn (no snd) procs %s: %s", i, n, tag) end end [:channel_widgets, :cursor, :channel_properties, :channel_property, :combined_data_color, :cursor_position, :cursor_size, :cursor_style, :tracking_cursor_style, :delete_sample, :display_edits, :dot_size, :draw_dots, :draw_lines, :edit_fragment, :edit_position, :edit_tree, :edits, :fft_window_beta, :fft_window_alpha, :fft_with_phases, :fft_log_frequency, :fft_log_magnitude, :transform_size, :transform_graph_type, :fft_window, :transform_graph?, :graph, :graph_style, :lisp_graph?, :insert_region, :insert_sound, :left_sample, :time_graph_style, :lisp_graph_style, :transform_graph_style, :make_graph_data, :map_chan, :max_transform_peaks, :maxamp, :maxamp_position, :min_dB, :mix_region, :transform_normalization, :peaks, :position2x, :position2y, :reverse_sound, :right_sample, :sample, :save_sound_as, :show_axes, :show_transform_peaks, :show_marks, :show_mix_waveforms, :show_y_zero, :show_grid, :show_sonogram_cursor, :spectrum_end, :spectro_hop, :spectrum_start, :spectro_x_angle, :spectro_x_scale, :spectro_y_angle, :spectro_y_scale, :spectro_z_angle, :spectro_z_scale, :squelch_update, :grid_density, :transform_sample, :transform2vct, :transform_framples, :transform_type, :update_transform_graph, :update_time_graph, :update_lisp_graph, :wavelet_type, :time_graph?, :time_graph_type, :wavo_hop, :wavo_trace, :x_bounds, :x_position_slider, :x_zoom_slider, :x_axis_label, :y_axis_label, :y_bounds, :y_position_slider, :y_zoom_slider, :zero_pad].each_with_index do |n, i| if (tag = Snd.catch do snd_func(n, 0, $vct_3) end).first != :wrong_type_arg snd_display("%s: chn (no chn) procs %s: %s", i, n, tag) end end idx = open_sound("oboe.snd") [:delete_sample, :edit_fragment, :graph_data, :position2x, :position2y, :redo_edit, :scale_by, :scale_to, :undo_edit, :x2position, :y2position].each_with_index do |n, i| tag = Snd.catch do snd_func(n, 0, idx, 1234) end if tag.first != :no_such_channel snd_display("%s: snd(1 1234) chn procs %s: %s", i, n, tag) end end close_sound(idx) idx = open_sound("oboe.snd") [:channel_widgets, :cursor, :cursor_position, :cursor_size, :cursor_style, :tracking_cursor_style, :display_edits, :dot_size, :edit_position, :edit_tree, :edits, :fft_window_alpha, :fft_window_beta, :fft_log_frequency, :fft_log_magnitude, :fft_with_phases, :transform_size, :transform_graph_type, :fft_window, :transform_graph?, :graph_style, :lisp_graph?, :left_sample, :time_graph_style, :lisp_graph_style, :transform_graph_style, :combined_data_color, :make_graph_data, :max_transform_peaks, :maxamp, :maxamp_position, :min_dB, :transform_normalization, :reverse_sound, :right_sample, :show_axes, :show_transform_peaks, :show_marks, :show_mix_waveforms, :show_y_zero, :show_grid, :show_sonogram_cursor, :grid_density, :spectrum_end, :spectro_hop, :spectrum_start, :spectro_x_angle, :spectro_x_scale, :spectro_y_angle, :spectro_y_scale, :spectro_z_angle, :spectro_z_scale, :squelch_update, :transform2vct, :transform_framples, :transform_type, :update_transform_graph, :update_time_graph, :update_lisp_graph, :wavelet_type, :time_graph?, :time_graph_type, :wavo_hop, :wavo_trace, :x_bounds, :x_position_slider, :x_axis_label, :x_zoom_slider, :y_bounds, :y_position_slider, :y_zoom_slider, :zero_pad, :channel_properties, :channel_property].each_with_index do |n, i| tag = Snd.catch do snd_func(n, idx, 1234) end if tag.first != :no_such_sound and tag.first != :no_such_channel snd_display("%s: chn procs %s: %s", i, n, tag) end end close_sound(idx) [:delete_sample, :edit_fragment, :graph_data, :graph_style, :position2x, :position2y, :redo_edit, :time_graph_style, :lisp_graph_style, :transform_graph_style, :scale_by, :scale_to, :undo_edit, :x2position, :y2position, :x_axis_label].each_with_index do |n, i| if (tag = Snd.catch do snd_func(n, 0, 1234) end).first != :no_such_sound snd_display("%s: snd(1) chn procs %s: %s", i, n, tag) end end idx = open_sound("oboe.snd") [:channel_widgets, :cursor, :cursor_position, :cursor_size, :cursor_style, :tracking_cursor_style, :display_edits, :dot_size, :edit_position, :edit_tree, :edits, :fft_window_beta, :fft_window_alpha, :fft_with_phases, :fft_log_frequency, :fft_log_magnitude, :transform_size, :transform_graph_type, :fft_window, :transform_graph?, :graph_style, :lisp_graph?, :left_sample, :time_graph_style, :lisp_graph_style, :transform_graph_style, :make_graph_data, :max_transform_peaks, :maxamp, :maxamp_position, :min_dB, :transform_normalization, :reverse_sound, :right_sample, :show_axes, :show_transform_peaks, :show_marks, :show_mix_waveforms, :show_y_zero, :show_grid, :show_sonogram_cursor, :grid_density, :spectrum_end, :spectro_hop, :spectrum_start, :spectro_x_angle, :spectro_x_scale, :spectro_y_angle, :spectro_y_scale, :spectro_z_angle, :spectro_z_scale, :squelch_update, :transform2vct, :transform_framples, :transform_type, :update_transform_graph, :update_time_graph, :update_lisp_graph, :wavelet_type, :time_graph?, :time_graph_type, :wavo_hop, :wavo_trace, :x_bounds, :x_position_slider, :x_axis_label, :x_zoom_slider, :y_bounds, :y_position_slider, :y_zoom_slider, :zero_pad, :channel_properties, :channel_property].each_with_index do |n, i| case (tag = Snd.catch do snd_func(n, idx, 1234) end).first when :no_such_sound, :no_such_channel next else snd_display("%s: chn (2) procs %s: %s", i, n, tag) end end [:channel_widgets, :cursor, :cursor_position, :display_edits, :dot_size, :edit_tree, :edits, :fft_window_beta, :fft_with_phases, :fft_window_alpha, :fft_log_frequency, :fft_log_magnitude, :transform_size, :transform_graph_type, :fft_window, :transform_graph?, :graph_style, :lisp_graph?, :left_sample, :make_graph_data, :max_transform_peaks, :maxamp, :maxamp_position, :time_graph_style, :lisp_graph_style, :transform_graph_style, :combined_data_color, :min_dB, :transform_normalization, :reverse_sound, :right_sample, :show_axes, :grid_density, :show_transform_peaks, :show_marks, :show_mix_waveforms, :show_y_zero, :show_grid, :show_sonogram_cursor, :spectrum_end, :spectro_hop, :spectrum_start, :spectro_x_angle, :spectro_x_scale, :spectro_y_angle, :spectro_y_scale, :spectro_z_angle, :spectro_z_scale, :squelch_update, :transform2vct, :transform_framples, :transform_type, :update_transform_graph, :update_time_graph, :update_lisp_graph, :wavelet_type, :time_graph?, :time_graph_type, :wavo_hop, :wavo_trace, :x_bounds, :x_position_slider, :x_zoom_slider, :y_bounds, :y_position_slider, :y_zoom_slider, :zero_pad, :x_axis_label].each_with_index do |n, i| tag = Snd.catch do set_snd_func(n, $vct_3, idx, 0) end if tag.first != :wrong_type_arg and tag.first != :no_method_error and tag.first != :name_error snd_display("%s: set chn procs %s: %s", i, n, tag) end end close_sound(idx) [:mix_amp, :mix_amp_env, :mix_length, :mix_name, :mix_position, :mix_home, :mix_speed, :mix_tag_y].each_with_index do |n, i| if (tag = Snd.catch do snd_func(n, $vct_3) end).first != :wrong_type_arg snd_display("%s: mix (1) procs %s: %s", i, n, tag) end end [:mix_amp, :mix_length, :mix_name, :mix_position, :mix_home, :mix_speed, :mix_tag_y].each_with_index do |n, i| if (tag = Snd.catch do snd_func(n, integer2mix(1234)) end).first != :no_such_mix snd_display("%s: mix (2) procs %s: %s", i, n, tag) end end [:mix_name, :mix_position, :mix_speed, :mix_tag_y].each_with_index do |n, i| tag = Snd.catch do set_snd_func(n, integer2mix(1234), $vct_3) end if tag.car != :wrong_type_arg and tag.car != :no_such_mix snd_display("%s: set mix (3) procs %s: %s", i, n, tag) end end index = open_sound("oboe.snd") id = mix_sound("oboe.snd", 10).car [:mix_name, :mix_position, :mix_speed, :mix_tag_y].each_with_index do |n, i| if (tag = Snd.catch do set_snd_func(n, id, $vct_3) end).first != :wrong_type_arg snd_display("%s: set mix (4) procs %s: %s", i, n, tag) end end close_sound(index) [:add_mark, :mark_name, :mark_sample, :mark_sync, :mark_home, :delete_mark, :delete_marks, :find_mark].each_with_index do |n, i| if (tag = Snd.catch do snd_func(n, $vct_3) end).first != :wrong_type_arg snd_display("%s: mark (1) procs %s: %s", i, n, tag) end end [:mark_name, :mark_sample, :mark_sync, :mark_home, :delete_mark].each_with_index do |n, i| if (tag = Snd.catch do snd_func(n, integer2mark(1234)) end).first != :no_such_mark snd_display("%s: mark (2) procs %s: %s", i, n, tag) end end index = open_sound("oboe.snd") id = add_mark(0, index, 0) [:mark_name, :mark_sample, :mark_sync].each_with_index do |n, i| if (tag = Snd.catch do set_snd_func(n, id, $vct_3) end).first != :wrong_type_arg snd_display("%s: set mark (3) procs %s: %s", i, n, tag) end end close_sound(index) [[0, 1], sqrt(-1.0), "hiho", [0, 1]].each do |arg| [:region_chans, :region_home, :region_framples, :region_position, :region_maxamp, :region_maxamp_position, :region_sample, :region2vct, :region_srate, :forget_region].each_with_index do |n, i| if (tag = Snd.catch do snd_func(n, arg) end).first != :wrong_type_arg snd_display("%s: region (1) procs %s: %s %s", i, n, tag, arg) end end end [:region_chans, :region_home, :region_framples, :region_position, :region_maxamp, :region_maxamp_position, :region_srate, :forget_region].each_with_index do |n, i| if (tag = Snd.catch do snd_func(n, integer2region(1234)) end).first != :no_such_region snd_display("%s: (no) region (2) procs %s: %s", i, n, tag) end end [:enved_filter_order, :enved_filter, :filter_control_waveform_color, :ask_before_overwrite, :auto_resize, :auto_update, :axis_label_font, :axis_numbers_font, :basic_color, :show_full_duration, :show_full_range, :initial_beg, :initial_dur, :channel_style, :color_cutoff, :color_inverted, :color_scale, :cursor_color, :dac_combines_channels, :dac_size, :clipping, :data_color, :default_output_chans, :default_output_sample_type, :default_output_srate, :default_output_header_type, :enved_envelope, :enved_base, :enved_clip?, :enved_in_dB, :enved_style, :enved_power, :enved_target, :enved_waveform_color, :enved_wave?, :eps_file, :eps_left_margin, :eps_bottom_margin, :eps_size, :foreground_color, :graph_color, :graph_cursor, :highlight_color, :just_sounds, :listener_color, :listener_font, :listener_prompt, :listener_text_color, :max_regions, :mix_waveform_height, :region_graph_style, :position_color, :time_graph_style, :lisp_graph_style, :transform_graph_style, :peaks_font, :bold_peaks_font, :print_length, :play_arrow_size, :sash_color, :ladspa_dir, :peak_env_dir, :save_dir, :save_state_file, :selected_channel, :selected_data_color, :selected_graph_color, :selected_sound, :selection_creates_region, :show_controls, :show_indices, :show_listener, :show_selection_transform, :sinc_width, :temp_dir, :text_focus_color, :tiny_font, :with_file_monitor, :with_verbose_cursor, :with_inset_graph, :with_interrupts, :with_pointer_focus, :window_height, :beats_per_measure, :with_smpte_label, :with_toolbar, :with_tooltips, :with_menu_icons, :remember_sound_state, :save_as_dialog_src, :save_as_dialog_auto_comment, :window_width, :window_x, :window_y, :with_gl, :with_mix_tags, :x_axis_style, :beats_per_minute, :zoom_color, :mix_tag_height, :mix_tag_width, :with_relative_panes, :clm_table_size, :mark_tag_width, :mark_tag_height].each do |n| tag = Snd.catch do set_snd_func(n, $vct_3) end if tag.first != :wrong_type_arg and tag.first != :mus_error snd_display("misc procs %s: %s", n, tag.inspect) end end [:after_graph_hook, :lisp_graph_hook, :before_transform_hook, :mix_release_hook, :save_hook, :before_save_as_hook, :after_save_as_hook, :save_state_hook, :new_sound_hook, :mus_error_hook, :mouse_enter_graph_hook, :mouse_leave_graph_hook, :open_raw_sound_hook, :select_channel_hook, :after_open_hook, :close_hook, :draw_mark_hook, :draw_mix_hook, :mark_click_hook, :listener_click_hook, :mix_click_hook, :after_save_state_hook, :before_save_state_hook, :mark_hook, :mark_drag_hook, :mix_drag_hook, :name_click_hook, :after_apply_controls_hook, :open_hook, :output_comment_hook, :help_hook, :play_hook, :new_widget_hook, :read_hook, :bad_header_hook, :snd_error_hook, :snd_warning_hook, :start_playing_hook, :stop_playing_hook, :mouse_enter_listener_hook, :mouse_leave_listener_hook, :select_sound_hook, :during_open_hook, :after_transform_hook, :mouse_enter_label_hook, :mouse_leave_label_hook, :initial_graph_hook, :graph_hook, :key_press_hook, :mouse_drag_hook, :mouse_press_hook, :mouse_click_hook, :enved_hook].each_with_index do |n, i| hook = eval("$#{n}") fnc = lambda do || 1 + 2 end tag = Snd.catch do hook.add_hook!("test28-1", &fnc) end if tag.first != :wrong_type_arg snd_display("%s: hooks (1) %s: %s", i, n, tag) end end [:exit_hook, :stop_playing_selection_hook, :color_hook, :orientation_hook, :start_playing_selection_hook].each_with_index do |n, i| hook = eval("$#{n}") fnc = lambda do |a, b, c| a + b + c end tag = Snd.catch do hook.add_hook!("test28-2", &fnc) end if tag.first != :wrong_type_arg snd_display("%s: hooks (2) %s: %s", i, n, tag) end end end def test_28_02 # XXX: 'not_an_env = nil' otherwise name_error: no such variable or function not_an_env = nil check_error_tag(:no_such_envelope) do set_enved_envelope("not_an_env") end check_error_tag(:cannot_save) do save_envelopes("/bad/baddy") end check_error_tag(:cannot_save) do mus_sound_report_cache("/bad/baddy") end check_error_tag(:bad_arity) do set_search_procedure(lambda do |a, b, c| a end) end check_error_tag(:no_such_channel) do make_sampler(0, "oboe.snd", 1) end check_error_tag(:no_such_channel) do make_sampler(0, "oboe.snd", -1) end check_error_tag(:bad_arity) do bind_key(key_to_int(?p), 0, lambda do |a, b| play_often([1, a].max) end) end check_error_tag(:bad_arity) do set_zoom_focus_style(lambda do |a| 0 end) end check_error_tag(:no_such_sound) do set_sound_loop_info(123, [0, 0, 1, 1]) end check_error_tag(:bad_header) do new_sound("fmv.snd", 2, 22050, Mus_bfloat, Mus_nist, "this is a comment") end check_error_tag(:wrong_type_arg) do player_home(123) end check_error_tag(:no_such_file) do set_temp_dir("/hiho") end check_error_tag(:no_such_file) do set_save_dir("/hiho") end check_error_tag(:out_of_range) do snd_transform(integer2transform(20), make_vct(4)) end check_error_tag(:bad_header) do mus_sound_maxamp($sf_dir + "bad_chans.snd") end check_error_tag(:bad_header) do set_mus_sound_maxamp($sf_dir + "bad_chans.snd", [0.0, 0.0]) end check_error_tag(:mus_error) do make_iir_filter(:order, 32, :ycoeffs, make_vct(4)) end check_error_tag(:mus_error) do make_iir_filter(:coeffs, make_vct(4), :ycoeffs, make_vct(4)) end check_error_tag(:mus_error) do make_iir_filter(:coeffs, make_vct(4), :xcoeffs, make_vct(4)) end check_error_tag(:out_of_range) do make_table_lookup(:size, 123456789) end check_error_tag(:out_of_range) do make_granulate(:ramp, -0.5) end check_error_tag(:out_of_range) do make_granulate(:ramp, 1.5) end check_error_tag(:mus_error) do make_granulate(:expansion, 32000.0) end check_error_tag(:out_of_range) do new_sound("test.snd", :channels, 0) end check_error_tag(:out_of_range) do new_sound("test.snd", :srate, 0) end check_error_tag(:out_of_range) do new_sound("test.snd", :size, -1) end check_error_tag(:out_of_range) do make_readin("oboe.snd", :size, 0) end check_error_tag(:out_of_range) do make_readin("oboe.snd", :size, -1) end check_error_tag(:out_of_range) do make_file2sample("oboe.snd", 0) end check_error_tag(:out_of_range) do make_file2sample("oboe.snd", -1) end check_error_tag(:out_of_range) do make_file2frample("oboe.snd", 0) end check_error_tag(:out_of_range) do make_file2frample("oboe.snd", -1) end check_error_tag(:out_of_range) do set_default_output_sample_type(-1) end check_error_tag(:out_of_range) do set_default_output_header_type(Mus_soundfont) end check_error_tag(:mus_error) do mus_sound_chans($sf_dir + "bad_location.nist") end check_error_tag(:mus_error) do mus_sound_chans($sf_dir + "bad_field.nist") end if $with_test_motif check_error_tag(:no_such_widget) do widget_position([:Widget, 0]) end check_error_tag(:no_such_widget) do widget_size([:Widget, 0]) end check_error_tag(:no_such_widget) do widget_text([:Widget, 0]) end check_error_tag(:no_such_widget) do set_widget_position([:Widget, 0], [0, 0]) end check_error_tag(:no_such_widget) do set_widget_size([:Widget, 0], [10, 10]) end check_error_tag(:no_such_widget) do set_widget_text([:Widget, 0], "hiho") end end check_error_tag(:no_such_menu) do main_menu(-1) end check_error_tag(:no_such_menu) do main_menu(111) end check_error_tag(:out_of_range) do new_sound("hiho", :header_type, 123) end check_error_tag(:out_of_range) do new_sound("hiho", :header_type, Mus_nist, :sample_type, 123) end check_error_tag(:bad_header) do new_sound("hiho", :header_type, Mus_nist, :sample_type, Mus_bfloat) end check_error_tag(:out_of_range) do set_mus_array_print_length(-1) end check_error_tag(:out_of_range) do set_print_length(-1) end check_error_tag(:out_of_range) do set_play_arrow_size(-1) end check_error_tag(:wrong_type_arg) do vector2vct(make_array(3, "hio")) end check_error_tag(:out_of_range) do set_enved_style(12) end check_error_tag(:out_of_range) do make_color(1.5, 0.0, 0.0) end check_error_tag(:out_of_range) do make_color(-0.5, 0.0, 0.0) end check_error_tag(:wrong_type_arg) do make_variable_graph(false) end check_error_tag(:cannot_print) do graph2ps end ind = open_sound("oboe.snd") set_selection_creates_region(true) select_all check_error_tag(:mus_error) do save_selection("sel0.snd", :not_a_key, 3) end check_error_tag(:wrong_type_arg) do read_only([ind]) end check_error_tag(:wrong_type_arg) do framples(ind, [0]) end check_error_tag(:wrong_type_arg) do smooth_sound(0, -10) end check_error_tag(:no_such_channel) do mix_selection(0, ind, 123) end check_error_tag(:no_such_channel) do insert_selection(0, ind, 123) end check_error_tag(:out_of_range) do set_channels(ind, 0) end check_error_tag(:wrong_type_arg) do set_channels(ind, -1) end check_error_tag(:out_of_range) do set_channels(ind, 12340) end check_error_tag(:out_of_range) do set_sample_type(ind, 12340) end check_error_tag(:out_of_range) do set_header_type(ind, 12340) end check_error_tag(:out_of_range) do set_srate(ind, 0) end check_error_tag(:wrong_type_arg) do set_data_location(ind, -1) end check_error_tag(:wrong_type_arg) do set_data_size(ind, -1) end check_error_tag(:no_such_sample) do set_sample(-1, -1) end check_error_tag(:no_such_sample) do sample(-1) end check_error_tag(:out_of_range) do set_framples(-10) end check_error_tag(:out_of_range) do set_min_dB(0.0) end check_error_tag(:out_of_range) do set_min_dB(0.0, ind, 0) end check_error_tag(:out_of_range) do start_playing(1, -22) end check_error_tag(:out_of_range) do start_playing(1, 0) end check_error_tag(:out_of_range) do set_filter_control_envelope([0.0, 1.0, 0.1, -0.1, 1.0, 0.0], ind) end check_error_tag(:out_of_range) do set_filter_control_envelope([0.0, 1.0, 0.1, 1.1, 1.0, 0.0], ind) end check_error_tag(:env_error) do filter_sound([0, 0, 0.1, 0.1, 0.05, 0.1, 1, 1], 32) end check_error_tag(:out_of_range) do apply_controls(ind, 123) end check_error_tag(:out_of_range) do set_speed_control_bounds([0.0, 2.0]) end check_error_tag(:out_of_range) do set_expand_control_bounds([0.0, 2.0]) end check_error_tag(:out_of_range) do set_speed_control_bounds([2.0, 0.0]) end check_error_tag(:out_of_range) do set_expand_control_bounds([2.0, 0.0]) end check_error_tag(:bad_header) do insert_sound($sf_dir + "bad_chans.snd") end check_error_tag(:io_error) do convolve_with($sf_dir + "bad_chans.snd") end check_error_tag(:cannot_save) do save_sound_as("hiho.snd", ind, -12) end check_error_tag(:cannot_save) do save_sound_as("hiho.snd", ind, :header_type, Mus_next, :sample_type, -12) end check_error_tag(:cannot_save) do save_sound_as("test.snd", ind, :header_type, Mus_nist, :sample_type, Mus_bdouble) end check_error_tag(:cannot_save) do save_sound_as("test.snd", ind, :header_type, Mus_aifc, :sample_type, Mus_lfloat) end check_error_tag(:cannot_save) do save_sound_as("test.snd", ind, :header_type, Mus_riff, :sample_type, Mus_bshort) end check_error_tag(:cannot_save) do save_sound_as("test.snd", ind, :header_type, Mus_voc, :sample_type, Mus_bshort) end check_error_tag(:cannot_save) do save_selection("test.snd", 22050, Mus_bshort, Mus_riff) end check_error_tag(:cannot_save) do save_selection("test.snd", 22050, Mus_bshort, Mus_voc) end check_error_tag(:out_of_range) do src_channel(make_env([0, 0, 1, 1], :length, 11)) end check_error_tag(:out_of_range) do src_channel(make_env([0, 1, 1, 0], :length, 11)) end check_error_tag(:out_of_range) do src_channel(make_env([0, 1, 1, -1], :length, 11)) end check_error_tag(:out_of_range) do src_channel(make_env([0, -1, 1, 1], :length, 11)) end check_error_tag(:out_of_range) do src_sound(make_env([0, 0, 1, 1], :length, 11)) end check_error_tag(:out_of_range) do src_sound(make_env([0, 1, 1, 0], :length, 11)) end check_error_tag(:out_of_range) do src_sound(make_env([0, 1, 1, -1], :length, 11)) end check_error_tag(:out_of_range) do src_sound(make_env([0, -1, 1, 1], :length, 11)) end check_error_tag(:mus_error) do make_readin(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) end check_error_tag(:out_of_range) do filter_sound($vct_3, 32) end check_error_tag(:out_of_range) do filter_sound([0, 0, 1, 1], 0) end check_error_tag(:no_such_sound) do swap_channels(ind, 0, 12345, 0) end check_error_tag(:no_such_sample) do mix_vct(vct(0.1, 0.2, 0.3), -1, ind, 0, true) end check_error_tag(:out_of_range) do snd_spectrum(Vct.new(8), 0, -123) end check_error_tag(:out_of_range) do snd_spectrum(Vct.new(8), 0, 0) end check_error_tag(:no_such_file) do play("/baddy/hiho") end check_error_tag(:bad_sample_type) do play($sf_dir + "nist-shortpack.wav") end check_error_tag(:no_such_sound) do play(123, 0) end check_error_tag(:no_such_channel) do make_player(ind, 123) end check_error_tag(:no_such_file) do mix("/baddy/hiho") end check_error_tag(:no_such_channel) do mix("oboe.snd", 0, 2) end check_error_tag(:no_such_file) do mix_sound("/baddy/hiho", 0) end check_error_tag(:no_such_file) do insert_sound("/baddy/hiho.snd") end check_error_tag(:no_such_file) do insert_samples(0, 10, "/baddy/hiho.snd") end check_error_tag(:no_data) do set_filter_control_envelope([], ind) end check_error_tag(:out_of_range) do set_sample_type(ind, 123) end check_error_tag(:out_of_range) do set_header_type(ind, 123) end check_error_tag(:no_such_channel) do set_selected_channel(ind, 123) end check_error_tag(:bad_arity) do set_search_procedure(lambda do |a, b, c| true end) end check_error_tag(:bad_arity) do map_chan(lambda do |a, b, c| 1.0 end) end check_error_tag(:bad_arity) do scan_channel(lambda do |a, b, c| 1.0 end) end check_error_tag(:bad_arity) do set_cursor_style(lambda do |a| 32 end, ind, 0) end check_error_tag(:no_such_graphics_context) do draw_line(0, 0, 1, 1, ind, 0, 1234) end check_error_tag(:no_such_graphics_context) do foreground_color(ind, 0, 1234) end check_error_tag(:no_such_graphics_context) do current_font(ind, 0, 1234) end check_error_tag(:no_such_graphics_context) do graph_data([$vct_3, $vct_3], ind, 0, 1234, 0, 1, 0) end check_error_tag(:no_such_axis) do position2x(100, ind, 0, 1234) end check_error_tag(:no_such_axis) do position2y(100, ind, 0, 1234) end check_error_tag(:no_such_axis) do x2position(100, ind, 0, 1234) end check_error_tag(:no_such_axis) do y2position(100, ind, 0, 1234) end check_error_tag(:no_such_axis) do axis_info(ind, 0, 1234) end check_error_tag(:out_of_range) do draw_axes(channel_widgets.car, snd_gcs.car, "hiho", 0.0, 1.0, -1.0, 1.0, X_axis_in_seconds,1234) end check_error_tag(:out_of_range) do draw_axes(channel_widgets.car, snd_gcs.car, "hiho", 0.0, 1.0, -1.0, 1.0, 1234) end check_error_tag(:no_such_channel) do axis_info(ind, 1234) end check_error_tag(:no_such_sound) do axis_info(1234) end set_time_graph_type(Graph_once) check_error_tag(:out_of_range) do set_x_bounds([0.1, -0.1]) end check_error_tag(:out_of_range) do make_region(100, 0) end check_error_tag(:no_such_sample) do delete_sample(-1) end check_error_tag(:no_such_sample) do delete_sample(2 * framples(ind)) end regions.empty? and make_region(0, 100) check_error_tag(:no_such_channel) do region_sample(regions.car, 0, 1234) end check_error_tag(:no_such_channel) do region_framples(regions.car, 1234) end check_error_tag(:no_such_channel) do region_position(regions.car, 1234) end check_error_tag(:no_such_channel) do region2vct(regions.car, 0, 1, 1234) end check_error_tag(:cannot_save) do save_sound_as("/bad/baddy.snd") end check_error_tag(:no_such_sound) do transform_sample(0, 1, 1234) end check_error_tag(:no_such_channel) do transform_sample(0, 1, ind, 1234) end check_error_tag(:no_such_sound) do graph(vct(0, 1), "hi", 0, 1, 0, 1, 1234) end check_error_tag(:no_such_channel) do graph(vct(0, 1), "hi", 0, 1, 0, 1, ind, 1234) end set_selection_member?(false, true) check_error_tag(:no_active_selection) do filter_selection(vct(0, 0, 1, 1), 4) end check_error_tag(:no_active_selection) do save_selection("/bad/baddy.snd") end check_error_tag(:no_active_selection) do env_selection([0, 0, 1, 1]) end check_error_tag(:no_such_region) do save_region(integer2region(1234), "/bad/baddy.snd") end make_region(0, 100, ind, 0) check_error_tag(:cannot_save) do save_selection("/bad/baddy.snd") end check_error_tag(:cannot_save) do save_region(regions.car, "/bad/baddy.snd") end check_error_tag(:no_such_mix) do make_mix_sampler(integer2mix(1234)) end check_error_tag(:no_such_sound) do make_region(0, 12, 1234, true) end set_read_only(true, ind) check_error_tag(:cannot_save) do set_sound_loop_info(ind, [0, 0, 1, 1]) end check_error_tag(:no_such_direction) do make_sampler(0, ind, 0, 123) end check_error_tag(:no_such_direction) do make_sampler(0, ind, 0, 0) end check_error_tag(:no_such_direction) do make_sampler(0, ind, 0, -2) end check_error_tag(:no_data) do scale_by([]) end check_error_tag(:no_data) do scale_to([]) end check_error_tag(:no_such_sample) do set_selection_position(-999, ind, 0) end check_error_tag(:wrong_type_arg) do set_selection_framples(-999, ind, 0) end check_error_tag(:wrong_type_arg) do set_selection_framples(0, ind, 0) end check_error_tag(:no_such_edit) do edit_fragment(-1) end check_error_tag(:no_such_edit) do edit_fragment(101, ind, 0) end check_error_tag(:no_such_edit) do edit_tree(ind, 0, -2) end check_error_tag(:no_such_edit) do edit_tree(ind, 0, 101) end check_error_tag(:no_such_sample) do add_mark(-1) end check_error_tag(:no_such_sample) do add_mark(framples * 2) end check_error_tag(:no_such_file) do convolve_with("/bad/baddy") end check_error_tag(:no_such_file) do mix("/bad/baddy") end check_error_tag(:no_such_sound) do swap_channels(ind, 0, 123) end check_error_tag(:out_of_range) do set_show_axes(123, ind, 0) end check_error_tag(:out_of_range) do set_show_axes(-123, ind, 0) end check_error_tag(:out_of_range) do set_x_axis_style(123, ind, 0) end check_error_tag(:out_of_range) do set_x_axis_style(-123, ind, 0) end check_error_tag(:out_of_range) do set_graph_style(123, ind, 0) end check_error_tag(:out_of_range) do set_graph_style(-123, ind, 0) end check_error_tag(:out_of_range) do env_sound([0, 0, 1, 1], 0, false, -1.5) end check_error_tag(:out_of_range) do xramp_channel(0.0, 1.0, -1.6) end check_error_tag(:wrong_type_arg) do set_samples(0, 2, -1) end check_error_tag(:wrong_type_arg) do left_sample([0]) end check_error_tag(:wrong_type_arg) do amp_control([0]) end check_error_tag(:wrong_type_arg) do sound_loop_info([0]) end check_error_tag(:wrong_type_arg) do add_mark(123, [0]) end check_error_tag(:no_such_sound) do filter_channel([0, 0, 1, 1], 100, false, false, 1234, 0) end check_error_tag(:no_such_channel) do filter_channel([0, 0, 1, 1], 100, false, false, ind, 1) end check_error_tag(:no_such_channel) do filter_channel(vct(0, 0, 1, 1), 4, false, false, ind, 1) end check_error_tag(:out_of_range) do filter_sound(vct(0, 0, 1, 1), 0) end check_error_tag(:out_of_range) do filter_sound(vct(0, 0, 1, 1), 10) end check_error_tag(:out_of_range) do set_reverb_control_length_bounds([0.1, 0.01], ind) end check_error_tag(:out_of_range) do set_reverb_control_scale_bounds([0.1, 0.01], ind) end check_error_tag(:wrong_type_arg) do scale_by(false) end check_error_tag(:wrong_type_arg) do src_sound(3.0, 1.0, true) end check_error_tag(:wrong_type_arg) do src_sound(3.0, 1.0, ind, true) end check_error_tag(:no_such_edit) do display_edits(ind, 0, 123) end check_error_tag(:no_such_edit) do marks(ind, 0, 123) end check_error_tag(:no_such_edit) do save_sound_as("test.snd", :edit_position, 123) end check_error_tag(:no_such_auto_delete_choice) do insert_sound("1a.snd", 0, 0, ind, 0, 0, 123) end close_sound(ind) check_error_tag(:bad_arity) do add_transform("hiho", "time", 0, 1, lambda do | | 1.0 end) end check_error_tag(:cannot_save) do save_state("/bad/baddy") end check_error_tag(:no_such_menu) do add_to_menu(1234, "hi", lambda do | | false end) end check_error_tag(:bad_arity) do add_to_main_menu("hi", lambda do |a, b| false end) end check_error_tag(:bad_arity) do add_to_menu(1, "hi", lambda do |a, b| false end) end check_error_tag(:wrong_type_arg) do set_transform_type(integer2transform(-1)) end check_error_tag(:out_of_range) do set_transform_type(integer2transform(123)) end check_error_tag(:wrong_type_arg) do help_dialog([0, 1], "hiho") end check_error_tag(:wrong_type_arg) do info_dialog([0, 1], "hiho") end check_error_tag(:no_such_sound) do edit_header_dialog(1234) end check_error_tag(:no_such_file) do open_sound("/bad/baddy.snd") end check_error_tag(:no_such_file) do open_raw_sound("/bad/baddy.snd", 1, 22050, Mus_lshort) end check_error_tag(:no_such_file) do view_sound("/bad/baddy.snd") end check_error_tag(:no_such_file) do make_sampler(0, "/bad/baddy.snd") end check_error_tag(:no_such_region) do make_region_sampler(integer2region(1234567), 0) end check_error_tag(:no_such_key) do bind_key(12345678, 0, false) end check_error_tag(:no_such_key) do bind_key(-1, 0, false) end check_error_tag(:no_such_key) do bind_key(12, 17, false) end check_error_tag(:no_such_key) do bind_key(12, -1, false) end check_error_tag(:no_such_key) do key_binding(12345678, 0) end check_error_tag(:no_such_key) do key_binding(-1, 0) end check_error_tag(:no_such_key) do key_binding(12, 17) end check_error_tag(:no_such_key) do key_binding(12, -1) end check_error_tag(:bad_header) do file2array($sf_dir + "bad_chans.snd", 0, 0, 123, Vct.new(123)) end check_error_tag(:bad_header) do make_readin($sf_dir + "bad_chans.snd") end check_error_tag(:mus_error) do make_iir_filter(30, Vct.new(3)) end check_error_tag(:out_of_range) do make_wave_train(:size, 2 ** 30) end check_error_tag(:out_of_range) do set_mus_srate(0.0) end check_error_tag(:out_of_range) do set_mus_srate(-1000) end check_error_tag(:out_of_range) do dot_product(Vct.new(3), Vct.new(3), -1) end check_error_tag(:out_of_range) do make_delay(3, :initial_element, 0.0, :initial_contents, vct(0.1, 0.2, 0.3)) end check_error_tag(:out_of_range) do make_delay(3, :max_size, 100, :initial_contents, vct(0.1, 0.2, 0.3)) end check_error_tag(:out_of_range) do make_table_lookup(:size, 100, :wave, Vct.new(3)) end check_error_tag(:out_of_range) do make_wave_train(:size, 100, :wave, Vct.new(3)) end check_error_tag(:out_of_range) do make_ssb_am(100, 12345678) end check_error_tag(:mus_error) do make_rand(:envelope, [0, 0, 1, 1], :distribution, Vct.new(10)) end check_error_tag(:mus_error) do make_rand(:envelope, [0, 0, 1]) end check_error_tag(:out_of_range) do make_rand(:envelope, [0, 0, 1, 1], :size, -2) end check_error_tag(:out_of_range) do make_rand(:envelope, [0, 0, 1, 1], :size, 1234567890) end check_error_tag(:bad_arity) do grn = make_granulate granulate(grn, false, lambda do |a, s, d| false end) end check_error_tag(:bad_arity) do pv = make_phase_vocoder phase_vocoder(pv, false, lambda do | | false end) end check_error_tag(:bad_arity) do pv = make_phase_vocoder phase_vocoder(pv, false, false, lambda do | | false end) end check_error_tag(:bad_arity) do pv = make_phase_vocoder phase_vocoder(pv, false, false, false, lambda do | | false end) end check_error_tag(:mus_error) do f = make_filter(3, :xcoeffs, $vct_3, :ycoeffs, $vct_3) mus_xcoeff(f, 4) end check_error_tag(:mus_error) do f = make_filter(3, :xcoeffs, $vct_3, :ycoeffs, $vct_3) mus_ycoeff(f, 4) end check_error_tag(:mus_error) do f = make_filter(3, :xcoeffs, $vct_3, :ycoeffs, $vct_3) set_mus_xcoeff(f, 4, 1.0) end check_error_tag(:mus_error) do f = make_filter(3, :xcoeffs, $vct_3, :ycoeffs, $vct_3) set_mus_ycoeff(f, 4, 1.0) end check_error_tag(:mus_error) do make_filter(:ycoeffs, Vct.new(4), :order, 12) end check_error_tag(:mus_error) do hi = make_oscil set_mus_offset(hi, 1) end check_error_tag(:out_of_range) do make_locsig(:channels, 2 ** 30) end check_error_tag(:out_of_range) do make_src(:width, 3000) end check_error_tag(:bad_arity) do add_colormap("baddy", lambda do | | false end) end check_error_tag(:bad_arity) do add_colormap("baddy", lambda do |a, b, c| false end) end check_error_tag(:out_of_range) do sr = make_src(:input, lambda do |dir| 1.0 end) src(sr, 2000000.0) end check_error_tag(:out_of_range) do partials2polynomial([1, 1], -1) end check_error_tag(:out_of_range) do partials2polynomial([1, 1], 3) end check_error_tag(:out_of_range) do make_polyshape(440.0, :partials, [1, 1], :kind, -1) end check_error_tag(:out_of_range) do make_polyshape(440.0, :partials, [1, 1], :kind, 3) end check_error_tag(:wrong_type_arg) do set_mus_header_raw_defaults(1234) end check_error_tag(:wrong_type_arg) do set_mus_header_raw_defaults([44100, 2.123, "hi"]) end check_error_tag(:wrong_type_arg) do set_with_toolbar(123) end check_error_tag(:wrong_type_arg) do set_with_tooltips(123) end check_error_tag(:wrong_type_arg) do set_with_menu_icons(123) end check_error_tag(:wrong_type_arg) do set_save_as_dialog_src(123) end check_error_tag(:wrong_type_arg) do set_save_as_dialog_auto_comment(123) end check_error_tag(:wrong_type_arg) do set_with_smpte_label(123) end check_error_tag(:wrong_type_arg) do set_ask_about_unsaved_edits(123) end check_error_tag(:no_such_mix) do mix_properties(integer2mix(mix_sync_max + 1)) end check_error_tag(:no_such_mix) do set_mix_properties(integer2mix(mix_sync_max + 1), 1) end # if $with_test_motif [:widget_position, :widget_size, :widget_text, :hide_widget, :show_widget, :focus_widget].each do |n| tag = Snd.catch do snd_func(n, [:Widget, 0]) end if tag.first != :no_such_widget snd_display("%s of null widget: %s", n, tag) end end end end def test_28_03 new_wave = Vct.new(1) [[:make_table_lookup, :table_lookup]].each do |mg, g| gen = snd_func(mg, :wave, new_wave) snd_func(g, gen, 1.0) end # old_srate = mus_srate old_clm_srate = $clm_srate [100, 1].each do |n| set_mus_srate(n) $clm_srate = n [:make_oscil, :make_asymmetric_fm, :make_triangle_wave, :make_square_wave, :make_pulse_train, :make_sawtooth_wave, :make_rand, :make_rand_interp].each do |g| tag = Snd.catch do snd_func(g, :frequency, 440.0) end if tag.first != :out_of_range snd_display("srate %s: %s -> %s", n, g, tag.inspect) end end end set_mus_srate(old_srate) $clm_srate = old_clm_srate # now try everything! (all we care about here is that Snd keeps running) random_args = [1.5, [0, 1], 1234, true] main_args = [1.5, [0, 1], 1234, $vct_3, $color_95, sqrt(-1.0), $delay_32, :feedback, false] few_args = [1.5, [0, 1], 1234, sqrt(-1.0), $delay_32, true] fewer_args = [1.5, $vct_3, sqrt(-1.0)] less_args = $all_args ? main_args : few_args # # key args # if $VERBOSE snd_info("keyargs-2-args") end Keyargs.each do |arg1| random_args.each do |arg2| Make_procs.each do |n| Snd.catch do snd_func(n, arg1, arg2) end end end end dismiss_all_dialogs if $all_args if $VERBOSE snd_info("keyargs-3-args") end random_args.each do |arg1| Keyargs.each do |arg2| random_args.each do |arg3| Make_procs.each do |n| Snd.catch do snd_func(n, arg1, arg2, arg3) end end end end end dismiss_all_dialogs if $VERBOSE snd_info("keyargs-4-args") end random_args.each do |arg1| Keyargs.each do |arg2| random_args.each do |arg3| Keyargs.each do |arg4| Make_procs.each do |n| Snd.catch do snd_func(n, arg1, arg2, arg3, arg4) end end end end end end dismiss_all_dialogs end # # 0 Args # unless Procs00.empty? if $VERBOSE snd_info("no-args") end Procs00.each do |n| if (tag = Snd.catch do snd_func(n) end).first == :wrong_number_of_args snd_display("procs00: %s %s\n# %s", tag, n, snd_help(n)) end end dismiss_all_dialogs end # # set no Args # unless Set_procs00.empty? if $VERBOSE snd_info("set-no-args") end main_args.each do |val| Set_procs00.each do |n| if (tag = Snd.catch do set_snd_func(n, val) end).first == :wrong_number_of_args snd_display("set_procs00: %s set_%s\n# %s", tag, n, snd_help(n)) end end end dismiss_all_dialogs end # # 1 Arg # unless Procs01.empty? if $VERBOSE snd_info("1-arg") end main_args.each do |arg| Procs01.each do |n| if (tag = Snd.catch do snd_func(n, arg) end).first == :wrong_number_of_args snd_display("procs01: %s %s\n# %s", tag, n, snd_help(n)) end end end dismiss_all_dialogs end # # set 1 Arg # unless Set_procs01.empty? if $VERBOSE snd_info("set-1-arg") end main_args.each do |arg1| main_args.each do |arg2| Set_procs01.each do |n| if (tag = Snd.catch do set_snd_func(n, arg1, arg2) end).first == :wrong_number_of_args snd_display("set_procs01: %s set_%s\n# %s", tag, n, snd_help(n)) end end end end dismiss_all_dialogs end # # 2 Args # unless Procs02.empty? if $VERBOSE snd_info("2-args") end main_args.each do |arg1| main_args.each do |arg2| Procs02.each do |n| if (tag = Snd.catch do snd_func(n, arg1, arg2) end).first == :wrong_number_of_args snd_display("procs02: %s %s\n# %s", tag, n, snd_help(n)) end end end end dismiss_all_dialogs end # # set 2 Args # unless Set_procs02.empty? if $VERBOSE snd_info("set-2-args") end less_args.each do |arg1| less_args.each do |arg2| less_args.each do |arg3| Set_procs02.each do |n| if (tag = Snd.catch do set_snd_func(n, arg1, arg2, arg3) end).first == :wrong_number_of_args snd_display("set_procs02: %s set_%s\n# %s", tag, n, snd_help(n)) end end end end end dismiss_all_dialogs end # # 3 Args # unless Procs03.empty? if $VERBOSE snd_info("3-args") end less_args.each do |arg1| less_args.each do |arg2| less_args.each do |arg3| Procs03.each do |n| if (tag = Snd.catch do snd_func(n, arg1, arg2, arg3) end).first == :wrong_number_of_args snd_display("procs03: %s %s\n# %s", tag, n, snd_help(n)) end end end end end dismiss_all_dialogs end # # set 3 Args # unless Set_procs03.empty? if $VERBOSE snd_info("set-3-args") end less_args.each do |arg1| less_args.each do |arg2| less_args.each do |arg3| less_args.each do |arg4| Set_procs03.each do |n| if (tag = Snd.catch do set_snd_func(n, arg1, arg2, arg3, arg4) end).first == :wrong_number_of_args snd_display("set_procs03: %s set_%s\n# %s", tag, n, snd_help(n)) end end end end end end dismiss_all_dialogs end # # 4 Args # unless Procs04.empty? if $VERBOSE snd_info("4-args") end few_args.each do |arg1| few_args.each do |arg2| few_args.each do |arg3| few_args.each do |arg4| Procs04.each do |n| if (tag = Snd.catch do snd_func(n, arg1, arg2, arg3, arg4) end).first == :wrong_number_of_args snd_display("procs04: %s %s\n# %s", tag, n, snd_help(n)) end end end end end end dismiss_all_dialogs end # # set 4 Args # unless Set_procs04.empty? if $VERBOSE snd_info("set-4-args") end few_args.each do |arg1| few_args.each do |arg2| few_args.each do |arg3| few_args.each do |arg4| few_args.each do |arg5| Set_procs04.each do |n| if (tag = Snd.catch do set_snd_func(n, arg1, arg2, arg3, arg4, arg5) end).first == :wrong_number_of_args snd_display("set_procs04: %s set_%s\n# %s", tag, n, snd_help(n)) end end end end end end end stop_playing dismiss_all_dialogs end # # 5 Args # unless Procs05.empty? if $VERBOSE snd_info("5-args") end fewer_args.each do |arg1| fewer_args.each do |arg2| fewer_args.each do |arg3| fewer_args.each do |arg4| fewer_args.each do |arg5| Procs05.each do |n| if (tag = Snd.catch do snd_func(n, arg1, arg2, arg3, arg4, arg5) end).first == :wrong_number_of_args snd_display("procs05: %s %s\n# %s", tag, n, snd_help(n)) end end end end end end end dismiss_all_dialogs end # # 6 Args # unless Procs06.empty? if $VERBOSE snd_info("6-args") end fewer_args.each do |arg1| fewer_args.each do |arg2| fewer_args.each do |arg3| fewer_args.each do |arg4| fewer_args.each do |arg5| fewer_args.each do |arg6| Procs06.each do |n| if (tag = Snd.catch do snd_func(n, arg1, arg2, arg3, arg4, arg5, arg6) end).first == :wrong_number_of_args snd_display("procs06: %s %s\n# %s", tag, n, snd_help(n)) end end end end end end end end dismiss_all_dialogs end # # 8 Args # unless Procs08.empty? if $VERBOSE snd_info("8-args") end fewer_args.each do |arg1| fewer_args.each do |arg2| fewer_args.each do |arg3| fewer_args.each do |arg4| fewer_args.each do |arg5| fewer_args.each do |arg6| fewer_args.each do |arg7| fewer_args.each do |arg8| Procs08.each do |n| if (tag = Snd.catch do snd_func(n, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) end).first == :wrong_number_of_args snd_display("procs08: %s %s\n# %s", tag, n, snd_help(n)) end end end end end end end end end end dismiss_all_dialogs end # # 10 Args # unless Procs10.empty? if $VERBOSE snd_info("10-args") end fewer_args.each do |arg1| fewer_args.each do |arg2| fewer_args.each do |arg3| fewer_args.each do |arg4| fewer_args.each do |arg5| fewer_args.each do |arg6| fewer_args.each do |arg7| fewer_args.each do |arg8| fewer_args.each do |arg9| fewer_args.each do |arg10| Procs10.each do |n| if (tag = Snd.catch do snd_func(n, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10) end).first == :wrong_number_of_args snd_display("procs10: %s %s\n# %s", tag, n, snd_help(n)) end end end end end end end end end end end end dismiss_all_dialogs end set_ask_about_unsaved_edits(false) end def test_28_04 File.exist?("test.snd") and File.chmod(0644, "test.snd") and File.unlink("test.snd") file_copy("oboe.snd", "test.snd") ind = open_sound("test.snd") delete_file("test.snd") if (tag = Snd.catch do update_sound(ind) end).first != :cant_update_file snd_display("update_sound after deletion: %s", tag) end delete_sample(10) if (tag = Snd.catch do save_sound(ind) end).first != :cannot_save snd_display("save file deleted: %s", tag) end close_sound(ind) # file_copy("oboe.snd", "test.snd") ind = open_sound("test.snd") reg = select_all delete_file("test.snd") view_regions_dialog close_sound(ind) # file_copy("oboe.snd", "test.snd") ind = open_sound("test.snd") File.chmod(0400, "test.snd") delete_sample(10) if (tag = Snd.catch do save_sound(ind) end).first != :cannot_save snd_display("save protected sound msg: %s", tag) end close_sound(ind) File.chmod(0644, "test.snd") delete_file("test.snd") # res = Snd.catch do open_sound("test.snd") end if res.first != :no_such_file and res.first != :mus_error snd_display("open read_protected sound: %s", res) sound?(res.car) and close_sound(res.car) end # file_copy("oboe.snd", "test.snd") File.chmod(0400, "test.snd") ind = open_sound("oboe.snd") delete_sample(10) if (res = Snd.catch do save_sound_as("test.snd") end).first != :cannot_save snd_display("save_as write_protected sound: %s", res) end close_sound(ind) File.chmod(0644, "test.snd") delete_file("test.snd") end def test_28 set_with_background_processes(true) set_remember_sound_state(false) if $VERBOSE snd_info("procs prcs/set-prcs") snd_info("====================") snd_info("proc00: %3d/%3d", Procs00.length, Set_procs00.length) snd_info("proc01: %3d/%3d", Procs01.length, Set_procs01.length) snd_info("proc02: %3d/%3d", Procs02.length, Set_procs02.length) snd_info("proc03: %3d/%3d", Procs03.length, Set_procs03.length) snd_info("proc04: %3d/%3d", Procs04.length, Set_procs04.length) snd_info("proc05: %3d", Procs05.length) snd_info("proc06: %3d", Procs06.length) snd_info("proc07: %3d", Procs07.length) snd_info("proc08: %3d", Procs08.length) snd_info("proc10: %3d", Procs10.length) end if $with_test_gui unless Procs.empty? snd_display("procs: %s?", Procs) end unless Set_procs.empty? snd_display("set_procs: %s?", Set_procs) end end reset_almost_all_hooks test_28_00 if $with_test_gui test_28_01 test_28_02 end test_28_03 test_28_04 end # ---------------- test all done def test_30 # $bigtest_08 = true # test_08_24 test_28_00 end main_test # snd-test.rb ends here snd-16.1/snd-marks.c0000644000076400007640000022535712603035272012414 0ustar bilbil#include "snd.h" struct mark { mus_long_t samp; char *name; int id, sync; bool visible; Xen properties; int properties_gc_loc; }; static int mark_id_counter = 0; int mark_to_int(mark *m) {return(m->id);} mus_long_t mark_sample(mark *m) {return(m->samp);} static int sync_max = 0; int mark_sync_max(void) { return(sync_max); } int mark_sync(mark *m) {return(m->sync);} void set_mark_sync(mark *m, int val) { m->sync = val; if (val > sync_max) sync_max = val; } static mark *make_mark_1(mus_long_t samp, const char *name, int id, int sc) { mark *mp; mp = (mark *)calloc(1, sizeof(mark)); if (name) mp->name = mus_strdup(name); else mp->name = NULL; mp->samp = samp; mp->id = id; set_mark_sync(mp, sc); mp->properties_gc_loc = NOT_A_GC_LOC; mp->properties = Xen_false; return(mp); } static mark *make_mark(mus_long_t samp, const char *name) { return(make_mark_1(samp, name, mark_id_counter++, 0)); } static mark *copy_mark(mark *m) { return(make_mark_1(m->samp, m->name, m->id, m->sync)); } static mark *free_mark(mark *mp) { if (mp) { if (mp->name) free(mp->name); if (mp->properties_gc_loc != NOT_A_GC_LOC) { snd_unprotect_at(mp->properties_gc_loc); mp->properties_gc_loc = NOT_A_GC_LOC; mp->properties = Xen_false; } free(mp); } return(NULL); } static mark *map_over_marks(chan_info *cp, mark *(*func)(chan_info *ncp, mark *mp1, void *p1), void *m, read_direction_t direction) { ed_list *ed; ed = cp->edits[cp->edit_ctr]; if ((ed) && (ed->marks)) { int marks; mark **mps; mps = ed->marks; marks = ed->mark_ctr; if (mps) { mark *mp; int i; if (direction == READ_FORWARD) { for (i = 0; i <= marks; i++) if (mps[i]) /* can be null if we're running delete_marks at a higher level and draw-mark-hook is active */ { mp = (*func)(cp, mps[i], m); if (mp) return(mp); } } else { for (i = marks; i >= 0; i--) if (mps[i]) { mp = (*func)(cp, mps[i], m); if (mp) return(mp); } } } } return(NULL); } static mark *map_over_marks_with_int(chan_info *cp, mark *(*func)(chan_info *ncp, mark *mp1, int val1), int value, read_direction_t direction) { ed_list *ed; ed = cp->edits[cp->edit_ctr]; if ((ed) && (ed->marks)) { int marks; mark **mps; mps = ed->marks; marks = ed->mark_ctr; if (mps) { mark *mp; int i; if (direction == READ_FORWARD) { for (i = 0; i <= marks; i++) if (mps[i]) /* can be null if we're running delete_marks at a higher level and draw-mark-hook is active */ { mp = (*func)(cp, mps[i], value); if (mp) return(mp); } } else { for (i = marks; i >= 0; i--) if (mps[i]) { mp = (*func)(cp, mps[i], value); if (mp) return(mp); } } } } return(NULL); } static mark *find_mark_id_1(chan_info *cp, mark *mp, int id) { if (mp->id == id) return(mp); return(NULL); } static mark *find_mark_from_id(int id, chan_info **cps, int pos) { int i; for (i = 0; i < ss->max_sounds; i++) { chan_info *cp; snd_info *sp; int j; sp = ss->sounds[i]; if ((sp) && (sp->inuse == SOUND_NORMAL)) for (j = 0; j<(sp->nchans); j++) if ((cp = ((chan_info *)(sp->chans[j])))) { if (pos < cp->edit_size) /* pos can be -1 */ { int old_pos; mark *mp; old_pos = cp->edit_ctr; if (pos >= 0) cp->edit_ctr = pos; /* memoization would have to be done here where we know cp->edit_ctr */ mp = map_over_marks_with_int(cp, find_mark_id_1, id, READ_FORWARD); cp->edit_ctr = old_pos; if (mp) { if (cps) cps[0] = cp; return(mp); } } } } return(NULL); } mus_long_t mark_id_to_sample(int id) { mark *m; m = find_mark_from_id(id, NULL, AT_CURRENT_EDIT_POSITION); if (m) return(m->samp); return(-1); } static mark *find_previous_mark_1(chan_info *cp, mark *mp, void *m) { if (mp->samp < (*((mus_long_t *)m))) return(mp); return(NULL); } static mark *find_previous_mark(mus_long_t current_sample, chan_info *cp) { return(map_over_marks(cp, find_previous_mark_1, (void *)(¤t_sample), READ_BACKWARD)); } static mark *find_next_mark_1(chan_info *cp, mark *mp, void *m) { if (mp->samp > (*((mus_long_t *)m))) return(mp); return(NULL); } static mark *find_next_mark(mus_long_t current_sample, chan_info *cp) { return(map_over_marks(cp, find_next_mark_1, (void *)(¤t_sample), READ_FORWARD)); } static mark* marks_off_1(chan_info *cp, mark *mp, void *ignore) { mp->visible = false; return(NULL); } void marks_off(chan_info *cp) { map_over_marks(cp, marks_off_1, NULL, READ_FORWARD); } static void show_mark(chan_info *cp, mark *mp, bool show); static Xen draw_mark_hook; static void draw_mark_1(chan_info *cp, mark *mp, bool show) { /* fields are samp and name */ if (!(cp->graph_time_on)) return; if (Xen_hook_has_list(draw_mark_hook)) { Xen res; res = run_progn_hook(draw_mark_hook, Xen_list_1(new_xen_mark(mp->id)), S_draw_mark_hook); if (Xen_is_true(res)) { mp->visible = show; return; } } show_mark(cp, mp, show); } static void draw_mark(chan_info *cp, mark *mp) { if (!(mp->visible)) draw_mark_1(cp, mp, true); } static void erase_mark(chan_info *cp, mark *mp) { #if (!USE_GTK) if (mp->visible) draw_mark_1(cp, mp, false); #endif } typedef struct { int x, y; mark *all_done; } mdata; static mark *hit_mark_1(chan_info *cp, mark *mp, void *m) { int mx; mdata *md = (mdata *)m; axis_info *ap; ap = cp->axis; if (mp->samp < ap->losamp) return(NULL); if (mp->samp > ap->hisamp) return(md->all_done); /* grf_x clips so we can be confused by off-screen marks */ mx = grf_x((double)(mp->samp) / (double)snd_srate(cp->sound), cp->axis); if (mx > (md->x + mark_tag_width(ss))) return(md->all_done); /* past it */ if (mx < (md->x - mark_tag_width(ss))) return(NULL); /* before it */ if (mp->name == NULL) /* check y if unnamed */ { if ((md->y >= ap->y_axis_y1) && (md->y <= (ap->y_axis_y1 + mark_tag_height(ss)))) return(mp); else return(NULL); } else return(mp); } #define HIT_SLOP 4 static mark *hit_mark_triangle_1(chan_info *cp, mark *mp, void *m) { /* m->samp = raw x mouse position */ /* we're going left to right, so after passing x, give up */ int mx, y; mdata *md = (mdata *)m; axis_info *ap; ap = cp->axis; if (mp->samp < ap->losamp) return(NULL); if (mp->samp > ap->hisamp) return(md->all_done); /* grf_x clips so we can be confused by off-screen marks */ mx = grf_x((double)(mp->samp) / (double)snd_srate(cp->sound), cp->axis); if (mx > (md->x + HIT_SLOP)) return(md->all_done); if ((mx + play_arrow_size(ss) + HIT_SLOP) < md->x) return(NULL); y = md->y - ap->y_axis_y0 - play_arrow_size(ss); if (y < 0) y = -y; if ((mx + play_arrow_size(ss) - y + HIT_SLOP) >= md->x) return(mp); /* the last is assuming the triangle shape for hit detection */ return(NULL); } mark *hit_mark_triangle(chan_info *cp, int x, int y) { if (cp->edits[cp->edit_ctr]->marks) { axis_info *ap; ap = cp->axis; /* first check that we're in the bottom portion of the graph where the mark triangles are */ if ((y >= ap->y_axis_y0) && (y <= (ap->y_axis_y0 + 2 * play_arrow_size(ss)))) { mark *mp; mdata *md; md = (mdata *)calloc(2, sizeof(mdata)); md->x = x; md->y = y; md->all_done = (mark *)1; mp = map_over_marks(cp, hit_mark_triangle_1, (void *)md, READ_FORWARD); if (mp == (mark *)1) mp = NULL; free(md); return(mp); } } return(NULL); } static Xen mark_drag_hook; static Xen mark_hook; /* add, delete, move */ static bool watching_mouse = false; /* this is tracking axis moves */ static int last_mouse_x = 0; static mark *moving_mark = NULL; /* used only while "off-screen" during axis moves */ static timeout_result_t watch_mouse_button = 0; #if (!USE_NO_GUI) static void move_axis_to_track_mark(chan_info *cp); static TIMEOUT_TYPE watch_mouse(TIMEOUT_ARGS) { chan_info *cp = (chan_info *)context; if (watch_mouse_button) { move_axis_to_track_mark(cp); watch_mouse_button = CALL_TIMEOUT(watch_mouse, 50, cp); } TIMEOUT_RESULT } #endif static void start_mark_watching(chan_info *cp, mark *mp) { moving_mark = mp; watch_mouse_button = CALL_TIMEOUT(watch_mouse, 50, cp); watching_mouse = true; } static void cancel_mark_watch(chan_info *cp) { #if (!USE_NO_GUI) if (watch_mouse_button) TIMEOUT_REMOVE(watch_mouse_button); #endif watch_mouse_button = 0; watching_mouse = false; moving_mark = NULL; } static bool move_mark_1(chan_info *cp, mark *mp, int x) { axis_info *ap; int nx; mus_long_t samps; bool redraw; ap = cp->axis; redraw = (!watching_mouse); if ((x > ap->x_axis_x1) || (x < ap->x_axis_x0)) { if (watching_mouse) { if (((x < ap->x_axis_x0) && (ap->x0 == ap->xmin)) || ((x > ap->x_axis_x1) && (ap->x1 == ap->xmax))) return(false); } nx = move_axis(cp, x); if (!watching_mouse) start_mark_watching(cp, mp); } else { erase_mark(cp, mp); nx = x; if (watching_mouse) { cancel_mark_watch(cp); redraw = false; } } mp->samp = (mus_long_t)(ungrf_x(ap, nx) * snd_srate(cp->sound)); if (mp->samp < 0) mp->samp = 0; samps = current_samples(cp); if (mp->samp > samps) mp->samp = samps; if (Xen_hook_has_list(mark_drag_hook)) ss->squelch_mark_drag_info = Xen_is_true(run_progn_hook(mark_drag_hook, Xen_list_1(new_xen_mark(mp->id)), S_mark_drag_hook)); else ss->squelch_mark_drag_info = false; return(redraw); } static int compare_mark_samps(const void *mp1, const void *mp2) { mark *m1, *m2; m1 = (mark *)(*((mark **)mp1)); m2 = (mark *)(*((mark **)mp2)); if (m1->samp < m2->samp) return(-1); if (m1->samp == m2->samp) return(0); return(1); } static void sort_marks(chan_info *cp) { ed_list *ed; ed = cp->edits[cp->edit_ctr]; if (ed) qsort((void *)(ed->marks), ed->mark_ctr + 1, sizeof(mark *), compare_mark_samps); } typedef enum {MARK_ADD, MARK_DELETE, MARK_MOVE, MARKS_DELETE, MARK_RELEASE} mark_hook_reason_t; static void run_mark_hook(chan_info *cp, int id, mark_hook_reason_t reason) { /* called after the mark list has been made consistent */ if (Xen_hook_has_list(mark_hook)) run_hook(mark_hook, Xen_list_4(new_xen_mark(id), C_int_to_Xen_sound(cp->sound->index), C_int_to_Xen_integer(cp->chan), C_int_to_Xen_integer((int)reason)), S_mark_hook); if (Xen_hook_has_list(ss->effects_hook)) run_hook(ss->effects_hook, Xen_empty_list, S_effects_hook); } #define MARKS_ALLOC_SIZE 4 mark *add_mark(mus_long_t samp, const char *name, chan_info *cp) { int i, med; mark **mps; ed_list *ed; ed = cp->edits[cp->edit_ctr]; if (!(ed->marks)) { ed->mark_size = MARKS_ALLOC_SIZE; ed->mark_ctr = -1; ed->marks = (mark **)calloc(MARKS_ALLOC_SIZE, sizeof(mark *)); } ed->mark_ctr++; if (ed->mark_ctr >= ed->mark_size) { ed->mark_size += MARKS_ALLOC_SIZE; ed->marks = (mark **)realloc(ed->marks, ed->mark_size * sizeof(mark *)); for (i = ed->mark_size - MARKS_ALLOC_SIZE; i < ed->mark_size; i++) ed->marks[i] = NULL; } mps = ed->marks; med = ed->mark_ctr; if (med == 0) { if (mps[0]) free_mark(mps[0]); mps[0] = make_mark(samp, name); run_mark_hook(cp, mps[0]->id, MARK_ADD); return(mps[0]); } else { for (i = 0; i < med; i++) /* not <= because we pre-incremented above */ { mark *mp; mp = mps[i]; if (samp < mp->samp) { int j; if (mps[med]) free_mark(mps[med]); for (j = med; j > i; j--) mps[j] = mps[j - 1]; mps[i] = make_mark(samp, name); run_mark_hook(cp, mps[i]->id, MARK_ADD); return(mps[i]); } } /* insert at end */ if (mps[med]) free_mark(mps[med]); mps[med] = make_mark(samp, name); run_mark_hook(cp, mps[med]->id, MARK_ADD); return(mps[med]); } } bool delete_mark_samp(mus_long_t samp, chan_info *cp) { if (cp) { ed_list *ed; ed = cp->edits[cp->edit_ctr]; if (ed->marks) { mark **mps; mps = ed->marks; if (mps) { int i, edm; edm = ed->mark_ctr; for (i = 0; i <= edm; i++) { mark *mp; mp = mps[i]; if (mp->samp == samp) { axis_info *ap; int id = -1; ap = cp->axis; if ((mp->samp >= ap->losamp) && (mp->samp <= ap->hisamp)) erase_mark(cp, mp); id = mp->id; free_mark(mp); mps[i] = NULL; if (i < edm) { int j; for (j = i; j < edm; j++) mps[j] = mps[j + 1]; mps[edm] = NULL; } ed->mark_ctr--; run_mark_hook(cp, id, MARK_DELETE); return(true); } } } } } return(false); } static bool delete_mark_id(int id, chan_info *cp) { if (cp) { ed_list *ed; ed = cp->edits[cp->edit_ctr]; if (ed->marks) { mark **mps; mps = ed->marks; if (mps) { int i, edm; edm = ed->mark_ctr; for (i = 0; i <= edm; i++) { mark *mp; mp = mps[i]; if (mp->id == id) { axis_info *ap; ap = cp->axis; if ((mp->samp >= ap->losamp) && (mp->samp <= ap->hisamp)) erase_mark(cp, mp); free_mark(mp); mps[i] = NULL; if (i < edm) { int j; for (j = i; j < edm; j++) mps[j] = mps[j + 1]; mps[edm] = NULL; } ed->mark_ctr--; run_mark_hook(cp, id, MARK_DELETE); return(true); } } } } } return(false); } static void delete_marks(chan_info *cp) { if (cp) { ed_list *ed; ed = cp->edits[cp->edit_ctr]; if (ed->marks) { mark **mps; mps = ed->marks; if (mps) { int i; for (i = 0; i < ed->mark_size; i++) { mark *mp; mp = mps[i]; if (mp) { axis_info *ap; ap = cp->axis; if ((mp->samp >= ap->losamp) && (mp->samp <= ap->hisamp)) erase_mark(cp, mp); free_mark(mp); mps[i] = NULL; } } ed->mark_ctr = -1; run_mark_hook(cp, -1, MARKS_DELETE); } } } } void free_mark_list(ed_list *ed) { if (ed->marks) { int j; for (j = 0; j < ed->mark_size; j++) { mark *mp; mp = ed->marks[j]; if (mp) free_mark(mp); ed->marks[j] = NULL; } free(ed->marks); ed->marks = NULL; ed->mark_size = 0; } } /* save and restore across update-sound */ typedef struct { mark **marks; int ctr; int size; } mark_info; typedef struct { mark_info **ms; int size; } marks_info; void *sound_store_marks(snd_info *sp) { int i; mark_info **res = NULL; marks_info *rtn = NULL; res = (mark_info **)calloc(sp->nchans, sizeof(mark_info *)); rtn = (marks_info *)calloc(1, sizeof(marks_info)); rtn->ms = res; rtn->size = sp->nchans; for (i = 0; i < sp->nchans; i++) { chan_info *cp; cp = sp->chans[i]; if (cp) { ed_list *ed; ed = cp->edits[cp->edit_ctr]; if (ed) { res[i] = (mark_info *)calloc(1, sizeof(mark_info)); res[i]->marks = ed->marks; res[i]->ctr = ed->mark_ctr; res[i]->size = ed->mark_size; ed->marks = NULL; ed->mark_size = 0; ed->mark_ctr = -1; } } } return((void *)rtn); } void sound_restore_marks(snd_info *sp, void *mrk) { marks_info *mrks = (marks_info *)mrk; if (mrks) { int i, lim; mark_info **marks; marks = mrks->ms; lim = mrks->size; if (sp->nchans < lim) lim = sp->nchans; /* update can change channel number either way */ for (i = 0; i < lim; i++) { if (marks[i]) { ed_list *ed; chan_info *cp; cp = sp->chans[i]; ed = cp->edits[0]; if (ed) { ed->marks = marks[i]->marks; ed->mark_ctr = marks[i]->ctr; ed->mark_size = marks[i]->size; } } } for (i = 0; i < mrks->size; i++) if (marks[i]) free(marks[i]); /* possible memleak here if chan num has lessened */ free(marks); free(mrks); } } static mark *find_nth_mark(chan_info *cp, int count) { int i, c; mus_long_t samp; mark *mp = NULL; if ((!cp) || (!cp->edits[cp->edit_ctr]->marks)) return(NULL); if (count > 0) c = count; else c = -count; samp = cursor_sample(cp); for (i = 0; i < c; i++) { if (count > 0) mp = find_next_mark(samp, cp); else mp = find_previous_mark(samp, cp); if (!mp) break; samp = mp->samp; } return(mp); } bool goto_mark(chan_info *cp, int count) { mark *mp; if ((!cp) || (!cp->edits[cp->edit_ctr]->marks)) return(false); mp = find_nth_mark(cp, count); if (!mp) return(false); cursor_moveto(cp, mp->samp); return(true); } #if 0 static mark *find_named_mark_1(chan_info *cp, mark *mp, void *uname) { char *name = (char *)uname; if ((mp->name) && (mus_strcmp(mp->name, name))) return(mp); else return(NULL); } static mark *find_named_mark(chan_info *cp, const char *name) { return(map_over_marks(cp, find_named_mark_1, (void *)name, READ_FORWARD)); } void goto_named_mark(chan_info *cp, const char *name) { mark *mp; mp = find_named_mark(cp, name); if (mp) cursor_moveto(cp, mp->samp); } #endif static mark *active_mark_1(chan_info *cp, mark *mp, void *ignore) { axis_info *ap; ap = cp->axis; if ((mp->samp >= ap->losamp) && (mp->samp <= ap->hisamp)) return(mp); return(NULL); } mark *active_mark(chan_info *cp) { return(map_over_marks(cp, active_mark_1, NULL, READ_FORWARD)); } mus_long_t mark_beg(chan_info *cp) { /* called only in snd-chn.c for active zoom */ mark *mp; mp = active_mark(cp); if (mp) return(mp->samp); return(-1); } typedef struct { mus_long_t last_samp; } dpy_last; static mark *display_channel_marks_1(chan_info *cp, mark *mp, void *m) { axis_info *ap; dpy_last *ls = (dpy_last *)m; ap = cp->axis; if (mp->samp > ap->hisamp) return(mp); /* terminates loop */ if (mp->samp == ls->last_samp) return(NULL); /* actually this should notice how wide in samples the mark stem is and avoid any redraw until we get to the next clear pixel */ else ls->last_samp = mp->samp; /* avoid drawing twice at same point == erase */ if ((mp->samp >= ap->losamp) && (mp->samp <= ap->hisamp) && (mp != moving_mark)) draw_mark(cp, mp); return(NULL); } void display_channel_marks(chan_info *cp) { if ((cp->edits[cp->edit_ctr]->marks) && (cp->show_marks)) { dpy_last ls; ls.last_samp = -1; map_over_marks(cp, display_channel_marks_1, (void *)(&ls), READ_FORWARD); } } void ripple_marks(chan_info *cp, mus_long_t beg, mus_long_t change) { /* if change = 0, just set ptr, else copy and fixup with deletions */ /* this is called after the tree has been pushed forward, so edit_ctr is ahead of us */ /* but we don't do anything if no marks */ if ((cp) && (cp->edit_ctr > 0)) { ed_list *old_ed, *new_ed; new_ed = cp->edits[cp->edit_ctr]; old_ed = cp->edits[cp->edit_ctr - 1]; if (new_ed->marks) { /* release current */ free_mark_list(new_ed); } /* copy old with position change */ new_ed->mark_ctr = old_ed->mark_ctr; new_ed->mark_size = old_ed->mark_size; if (new_ed->mark_size > 0) { new_ed->marks = (mark **)calloc(new_ed->mark_size, sizeof(mark *)); if (new_ed->mark_ctr >= 0) { int i; mark **mps, **mpo; mark *mp; mps = new_ed->marks; mpo = old_ed->marks; for (i = 0; i <= new_ed->mark_ctr; i++) mps[i] = copy_mark(mpo[i]); if (change < 0) { mus_long_t end; /* if (change < 0) and any marks are between beg and beg+change, they must be deleted */ end = beg - change - 1; i = 0; while (i <= new_ed->mark_ctr) { mp = mps[i]; if ((mp->samp >= beg) && (mp->samp <= end)) /* was mp->samp > beg, ditto end, beg can = end */ delete_mark_samp(mp->samp, cp); /* changes cp->mark_ctr, hence the while loop? */ else { if (mp->samp > beg) /* don't change marks that precede the point of the change */ mp->samp += change; i++; } } } else { if (change > 0) for (i = 0; i <= new_ed->mark_ctr; i++) { mp = mps[i]; if (mp->samp > beg) mp->samp += change; } } } } } } bool mark_define_region(chan_info *cp, int count) { if ((cp) && (max_regions(ss) > 0)) { ed_list *ed; ed = cp->edits[cp->edit_ctr]; if (ed->marks) { mus_long_t beg; mark *mp; beg = cursor_sample(cp); mp = find_nth_mark(cp, count); if (mp) { mus_long_t end; end = mp->samp; if (end != beg) { mus_long_t ends[1]; sync_info *si; int i; ends[0] = end; if (end < beg) { ends[0] = beg; beg = end; } deactivate_selection(); si = sync_to_chan(cp); si->begs[0] = beg; define_region(si, ends); for (i = 0; i < si->chans; i++) { reactivate_selection(si->cps[i], beg, ends[0]); update_graph(si->cps[i]); } si = free_sync_info(si); return(true); } } } } return(false); } static mark *reverse_mark_1(chan_info *cp, mark *mp, void *um) { mark *m = (mark *)um; mp->samp = m->samp - mp->samp; return(NULL); } void reverse_marks(chan_info *cp, mus_long_t beg, mus_long_t dur) /* beg -1 for full sound */ { ed_list *ed; ed = cp->edits[cp->edit_ctr]; if (ed->marks) { mark *m; mark **mps; mps = ed->marks; if (beg == -1) { m = make_mark_1(current_samples(cp) - 1, NULL, 0, 0); map_over_marks(cp, reverse_mark_1, (void *)m, READ_FORWARD); free_mark(m); } else { mus_long_t end; int i, marks; end = beg + dur - 1; marks = ed->mark_ctr; for (i = 0; i <= marks; i++) { m = mps[i]; if ((m->samp >= beg) && (m->samp <= end)) m->samp = end - (m->samp - beg); } } if (ed->mark_ctr >= 0) qsort((void *)mps, ed->mark_ctr + 1, sizeof(mark *), compare_mark_samps); } } void src_marks(chan_info *cp, mus_float_t ratio, mus_long_t old_samps, mus_long_t new_samps, mus_long_t beg, bool over_selection) { ed_list *ed; ed = cp->edits[cp->edit_ctr]; if ((ed->marks) && (ed->mark_ctr >= 0)) { int i, marks; mark *m; mark **mps; mps = ed->marks; marks = ed->mark_ctr; if (!over_selection) { for (i = 0; i <= marks; i++) { m = mps[i]; if (ratio > 0.0) m->samp = (mus_long_t)(m->samp / ratio); else m->samp = (mus_long_t)((old_samps - 1 - m->samp) / (-ratio)); /* ratio < 0 here */ } } else { mus_long_t end; end = beg + old_samps - 1; for (i = 0; i <= marks; i++) { m = mps[i]; if ((m->samp >= beg) && (m->samp <= end)) { if (ratio > 0.0) m->samp = beg + (mus_long_t)((m->samp - beg) / ratio); else m->samp = beg + (mus_long_t)((old_samps - 1 - (m->samp - beg)) / (-ratio)); } else { if (m->samp > end) m->samp += (new_samps - old_samps); } } } if (ratio < 0.0) qsort((void *)mps, marks + 1, sizeof(mark *), compare_mark_samps); } } void reset_marks(chan_info *cp, int cur_marks, mus_long_t *samps, mus_long_t end, mus_long_t extension, bool over_selection) { ed_list *ed; ed = cp->edits[cp->edit_ctr]; if ((ed->marks) && (ed->mark_ctr >= 0)) { int i, marks; mark *m; mark **mps; mps = ed->marks; marks = ed->mark_ctr; if (over_selection) for (i = 0; i <= marks; i++) { m = mps[i]; if (m->samp > end) m->samp += extension; } for (i = 0; (i <= marks) && (i < cur_marks); i++) { m = mps[i]; if (samps[i] >= 0) m->samp = samps[i]; } qsort((void *)mps, marks + 1, sizeof(mark *), compare_mark_samps); } } void ripple_trailing_marks(chan_info *cp, mus_long_t beg, mus_long_t old_len, mus_long_t new_len) { ed_list *ed; ed = cp->edits[cp->edit_ctr]; if ((ed->marks) && (ed->mark_ctr >= 0)) { int i, marks; mark **mps; ripple_marks(cp, 0, 0); mps = ed->marks; marks = ed->mark_ctr; for (i = 0; i <= marks; i++) { mark *m; m = mps[i]; if (m->samp > (beg + old_len)) m->samp += (new_len - old_len); } } } void swap_marks(chan_info *cp0, chan_info *cp1) { ed_list *ed0, *ed1; ed0 = cp0->edits[cp0->edit_ctr]; ed1 = cp1->edits[cp1->edit_ctr]; if ((ed0->marks) || (ed1->marks)) { mark **mps0 = NULL, **mps1 = NULL; int ctr0 = -1, ctr1 = -1; int size0 = 0, size1 = 0; if (ed0->marks) { mps0 = ed0->marks; ctr0 = ed0->mark_ctr; size0 = ed0->mark_size; } if (ed1->marks) { mps1 = ed1->marks; ctr1 = ed1->mark_ctr; size1 = ed1->mark_size; } ed0->marks = mps1; ed0->mark_ctr = ctr1; ed0->mark_size = size1; ed1->marks = mps0; ed1->mark_ctr = ctr0; ed1->mark_size = size0; } } /* -------------------------------- SYNCD AND DRAGGED MARKS -------------------------------- */ typedef struct { mark **marks; chan_info **chans; int marks_size; int mark_ctr; int sync; mus_long_t *initial_samples; } syncdata; static syncdata *make_syncdata(int sync) { syncdata *sd; sd = (syncdata *)calloc(1, sizeof(syncdata)); sd->sync = sync; sd->mark_ctr = 0; sd->marks_size = 8; sd->marks = (mark **)calloc(sd->marks_size, sizeof(mark *)); sd->chans = (chan_info **)calloc(sd->marks_size, sizeof(chan_info *)); sd->initial_samples = (mus_long_t *)calloc(sd->marks_size, sizeof(mus_long_t)); return(sd); } static void add_syncd_mark(syncdata *sd, mark *mp, chan_info *cp) { sd->marks[sd->mark_ctr] = mp; sd->initial_samples[sd->mark_ctr] = mp->samp; sd->chans[sd->mark_ctr++] = cp; if (sd->mark_ctr == sd->marks_size) { int i; sd->marks = (mark **)realloc(sd->marks, sd->marks_size * 2 * sizeof(mark *)); sd->chans = (chan_info **)realloc(sd->chans, sd->marks_size * 2 * sizeof(chan_info *)); /* why was initial_samples missing? 2-May-02 */ sd->initial_samples = (mus_long_t *)realloc(sd->initial_samples, sd->marks_size * 2 * sizeof(mus_long_t)); for (i = sd->marks_size; i < sd->marks_size * 2; i++) {sd->marks[i] = NULL; sd->chans[i] = NULL;} sd->marks_size *= 2; } } static mark *gather_local_syncd_marks(chan_info *cp, mark *mp, void *usd) { syncdata *sd = (syncdata *)usd; if (sd->sync == mp->sync) add_syncd_mark(sd, mp, cp); return(NULL); } static void gather_chan_syncd_marks(chan_info *cp, void *sd) { map_over_marks(cp, gather_local_syncd_marks, sd, READ_FORWARD); } static syncdata *gather_syncd_marks(int sync) { syncdata *sd; sd = make_syncdata(sync); for_each_normal_chan_with_void(gather_chan_syncd_marks, (void *)sd); return(sd); } static syncdata *free_syncdata(syncdata *sd) { if (sd) { if (sd->marks) free(sd->marks); if (sd->initial_samples) free(sd->initial_samples); if (sd->chans) free(sd->chans); free(sd); } return(NULL); } static bool mark_control_clicked = false; /* C-click of mark -> drag data as mark is dragged */ static mus_long_t mark_initial_sample = 0; static syncdata *mark_sd = NULL; typedef struct { widget_t graph; point_t *p0, *p1; int lastpj; color_t color; } mark_context; static mark_context **mark_movers = NULL; static mark_context *make_mark_context(chan_info *cp) { mark_context *g; g = (mark_context *)calloc(1, sizeof(mark_context)); g->graph = channel_graph(cp); g->color = ss->mark_color; return(g); } static mark_context *free_mark_context(mark_context *ms) { if (ms->p0) {free(ms->p0); ms->p0 = NULL;} if (ms->p1) {free(ms->p1); ms->p1 = NULL;} free(ms); return(NULL); } static void mark_save_graph(mark_context *ms, int j); static void make_mark_graph(chan_info *cp, mus_long_t initial_sample, mus_long_t current_sample, int which); static void initialize_md_context(int size, chan_info **cps) { int i; mark_movers = (mark_context **)calloc(size, sizeof(mark_context *)); for (i = 0; i < size; i++) { mark_context *ms; mark_movers[i] = make_mark_context(cps[i]); ms = mark_movers[i]; ms->lastpj = make_dragged_marks_graph(cps[i]); mark_save_graph(ms, ms->lastpj); } } static void finalize_md_context(int size) { if (mark_movers) { int i; for (i = 0; i < size; i++) if (mark_movers[i]) free_mark_context(mark_movers[i]); free(mark_movers); mark_movers = NULL; } } void set_mark_control(chan_info *cp, mark *mp, int key_state) { mark_control_clicked = (key_state & snd_ControlMask); if (mark_control_clicked) { mark_initial_sample = mp->samp; if (mark_sd) { if ((mark_sd->mark_ctr > 1) && (mark_sd->marks[0] != mp)) { int loc; for (loc = 1; loc < mark_sd->mark_ctr; loc++) if (mark_sd->marks[loc] == mp) break; if (loc < mark_sd->mark_ctr) { chan_info *tc; mus_long_t ts; mark *tm; tm = mark_sd->marks[0]; ts = mark_sd->initial_samples[0]; tc = mark_sd->chans[0]; mark_sd->marks[0] = mark_sd->marks[loc]; mark_sd->initial_samples[0] = mark_sd->initial_samples[loc]; mark_sd->chans[0] = mark_sd->chans[loc]; mark_sd->marks[loc] = tm; mark_sd->initial_samples[loc] = ts; mark_sd->chans[loc] = tc; } } initialize_md_context(mark_sd->mark_ctr, mark_sd->chans); } else initialize_md_context(1, &cp); } } mark *hit_mark(chan_info *cp, int x, int y) { ed_list *ed; ed = cp->edits[cp->edit_ctr]; if ((ed->marks) && (ed->mark_ctr >= 0)) { axis_info *ap; ap = cp->axis; /* first check that we're in the top portion of the graph where the mark tabs are */ if ((y >= ap->y_axis_y1) && (y <= (ap->y_axis_y1 + mark_tag_height(ss) + 10))) /* + 10 for named marks -- checked again later */ { mark *mp; mdata *md; md = (mdata *)calloc(1, sizeof(mdata)); md->x = x; md->y = y; md->all_done = (mark *)1; mp = map_over_marks(cp, hit_mark_1, (void *)md, READ_FORWARD); if (mp == (mark *)1) mp = NULL; free(md); if (mp) { if (mp->sync != 0) { if (mark_sd) mark_sd = free_syncdata(mark_sd); mark_sd = gather_syncd_marks(mp->sync); } } return(mp); } } return(NULL); } #if (!USE_NO_GUI) static void allocate_erase_grf_points(mark_context *ms) { if (ms->p0 == NULL) { ms->p0 = (point_t *)calloc(POINT_BUFFER_SIZE, sizeof(point_t)); ms->p1 = (point_t *)calloc(POINT_BUFFER_SIZE, sizeof(point_t)); } } static void backup_erase_grf_points(mark_context *ms, int nj) { ms->lastpj = nj; memcpy((void *)(ms->p0), (void *)get_grf_points(), nj * sizeof(point_t)); memcpy((void *)(ms->p1), (void *)get_grf_points1(), nj * sizeof(point_t)); } static void mark_save_graph(mark_context *ms, int j) { allocate_erase_grf_points(ms); backup_erase_grf_points(ms, j); } static void erase_and_draw_grf_points(mark_context *ms, chan_info *cp, int nj) { graphics_context *ax; point_t *points; chan_info *draw_cp; #if USE_MOTIF GC draw_gc, undraw_gc; #else gc_t *draw_gc, *undraw_gc; #endif points = get_grf_points(); draw_cp = channel_to_chan(cp); ax = draw_cp->ax; #if USE_GTK ss->cr = make_cairo(ax->wn); #endif undraw_gc = erase_GC(draw_cp); draw_gc = copy_GC(draw_cp); if (draw_cp->time_graph_style == GRAPH_LINES) { ax->gc = undraw_gc; draw_lines(ax, ms->p0, ms->lastpj); ax->gc = draw_gc; draw_lines(ax, points, nj); } else { ax->gc = undraw_gc; draw_points(ax, ms->p0, ms->lastpj, draw_cp->dot_size); ax->gc = draw_gc; draw_points(ax, points, nj, draw_cp->dot_size); } backup_erase_grf_points(ms, nj); ax->gc = draw_gc; #if USE_GTK free_cairo(ss->cr); ss->cr = NULL; #endif } static void erase_and_draw_both_grf_points(mark_context *ms, chan_info *cp, int nj) { graphics_context *ax; point_t *points, *points1; chan_info *draw_cp; #if USE_MOTIF GC draw_gc, undraw_gc; #else gc_t *draw_gc, *undraw_gc; #endif points = get_grf_points(); points1 = get_grf_points1(); draw_cp = channel_to_chan(cp); ax = draw_cp->ax; #if USE_GTK ss->cr = make_cairo(ax->wn); #endif undraw_gc = erase_GC(draw_cp); draw_gc = copy_GC(draw_cp); if (draw_cp->time_graph_style == GRAPH_LINES) { ax->gc = undraw_gc; draw_lines(ax, ms->p0, ms->lastpj); draw_lines(ax, ms->p1, ms->lastpj); ax->gc = draw_gc; draw_lines(ax, points, nj); draw_lines(ax, points1, nj); } else { ax->gc = undraw_gc; draw_points(ax, ms->p0, ms->lastpj, draw_cp->dot_size); draw_points(ax, ms->p1, ms->lastpj, draw_cp->dot_size); ax->gc = draw_gc; draw_points(ax, points, nj, draw_cp->dot_size); draw_points(ax, points1, nj, draw_cp->dot_size); } backup_erase_grf_points(ms, nj); ax->gc = draw_gc; #if USE_GTK free_cairo(ss->cr); ss->cr = NULL; #endif } #else static void mark_save_graph(mark_context *ms, int j) {} #endif static bool move_syncd_mark(chan_info *cp, mark *m, int x) { mus_long_t old_samp, diff; bool redraw; old_samp = m->samp; redraw = move_mark_1(cp, m, x); diff = m->samp - old_samp; if (diff != 0) { if ((mark_sd) && (mark_sd->mark_ctr > 1)) { int i; for (i = 0; i < mark_sd->mark_ctr; i++) { mark *mp; mp = mark_sd->marks[i]; if (mp != m) { axis_info *ap; mus_long_t samps; chan_info *ncp; ncp = mark_sd->chans[i]; ap = ncp->axis; if ((mp->samp >= ap->losamp) && (mp->samp <= ap->hisamp)) erase_mark(ncp, mp); mp->samp += diff; if (mp->samp < 0) mp->samp = 0; samps = current_samples(ncp); if (mp->samp > samps) mp->samp = samps; if (mark_control_clicked) make_mark_graph(ncp, mark_sd->initial_samples[i], mp->samp, i); if ((mp->samp >= ap->losamp) && (mp->samp <= ap->hisamp)) draw_mark(ncp, mp); } } } } return(redraw); } #if (!USE_NO_GUI) static void move_axis_to_track_mark(chan_info *cp) { if (moving_mark) { bool redraw; if (moving_mark->sync) redraw = move_syncd_mark(cp, moving_mark, last_mouse_x); else redraw = move_mark_1(cp, moving_mark, last_mouse_x); if (redraw) draw_mark(cp, moving_mark); } } #endif void move_mark(chan_info *cp, mark *mp, int x) /* from mouse drag callback in snd-chn.c, called whenever mark is visible */ { bool redraw; last_mouse_x = x; if (mp->sync) redraw = move_syncd_mark(cp, mp, x); else redraw = move_mark_1(cp, mp, x); if (mark_control_clicked) make_mark_graph(cp, mark_initial_sample, mp->samp, 0); #if (!USE_GTK) if (redraw) draw_mark(cp, mp); #else if ((redraw) && (!mark_control_clicked)) display_channel_time_data(cp); #endif } static void edit_dragged_mark(chan_info *cp, mark *m, mus_long_t initial_sample) { /* edit -- initial_sample is where we were when the drag started, ended at m->samp */ mus_long_t num, mark_final_sample; int id; mark *new_m; mark_final_sample = m->samp; num = mark_final_sample - initial_sample; m->samp = initial_sample; id = m->id; if (num > 0) extend_with_zeros(cp, initial_sample, num, cp->edit_ctr, "drag mark"); /* at this point, old mark pointer is irrelevant (it lives in the previous edit history list) */ /* but since the ripple didn't touch it, we need to move it forward to reflect the insertion */ else if (num < 0) { new_m = map_over_marks_with_int(cp, find_mark_id_1, id, READ_FORWARD); new_m->samp = initial_sample; delete_samples(mark_final_sample, -num, cp, cp->edit_ctr); } if (num != 0) { new_m = map_over_marks_with_int(cp, find_mark_id_1, id, READ_FORWARD); new_m->samp = mark_final_sample; update_graph(cp); } } void finish_moving_mark(chan_info *cp, mark *m) /* button release called from snd-chn.c */ { if (watching_mouse) cancel_mark_watch(cp); if ((m->sync != 0) && (mark_sd)) { int i; if (Xen_hook_has_list(mark_hook)) for (i = 0; i < mark_sd->mark_ctr; i++) run_mark_hook(mark_sd->chans[i], mark_sd->marks[i]->id, MARK_RELEASE); if (mark_control_clicked) { for (i = mark_sd->mark_ctr - 1; i >= 0; i--) { /* do the edits in reverse order on the assumption that marks sharing a channel were ordered to begin with, * so they'll happen in reverse order here, so the lower sample edits in rippling won't affect the higher */ mark *sdm; sdm = mark_sd->marks[i]; edit_dragged_mark(mark_sd->chans[i], sdm, mark_sd->initial_samples[i]); } finalize_md_context(mark_sd->mark_ctr); } for (i = 0; i < mark_sd->mark_ctr; i++) if (mark_sd->chans[i]) { int j; sort_marks(mark_sd->chans[i]); /* resort marks in case movement scrambled them */ for (j = i + 1; j < mark_sd->mark_ctr; j++) /* only sort each channel once */ if (mark_sd->chans[j] == mark_sd->chans[i]) mark_sd->chans[j] = NULL; } } else { run_mark_hook(cp, m->id, MARK_RELEASE); if (mark_control_clicked) { edit_dragged_mark(cp, m, mark_initial_sample); finalize_md_context(1); } sort_marks(cp); } if (mark_sd) mark_sd = free_syncdata(mark_sd); } void play_syncd_mark(chan_info *cp, mark *m) { syncdata *sd; sd = gather_syncd_marks(m->sync); if ((sd) && (sd->mark_ctr > 0)) play_channels(sd->chans, sd->mark_ctr, sd->initial_samples, NULL, IN_BACKGROUND, C_int_to_Xen_integer(AT_CURRENT_EDIT_POSITION), false, "play sync'd mark", 0); if (sd) free_syncdata(sd); } static void make_mark_graph(chan_info *cp, mus_long_t initial_sample, mus_long_t current_sample, int which) { #if (!USE_NO_GUI) snd_info *sp; int j = 0; mus_long_t i, k, samps; axis_info *ap; double samples_per_pixel, x; int pixels; snd_fd *sf = NULL; int x_start, x_end; double start_time = 0.0, cur_srate; sp = cp->sound; ap = cp->axis; cur_srate = (double)snd_srate(sp); ap->losamp = (mus_long_t)(ap->x0 * cur_srate); if (ap->losamp < 0) ap->losamp = 0; if (ap->x0 != ((double)(ap->losamp) / cur_srate)) ap->losamp++; start_time = (double)(ap->losamp) / cur_srate; ap->hisamp = (mus_long_t)(ap->x1 * cur_srate); if ((ap->losamp == 0) && (ap->hisamp == 0)) return; x_start = ap->x_axis_x0; x_end = ap->x_axis_x1; samps = ap->hisamp - ap->losamp + 1; if ((x_start == x_end) && (samps > 10)) return; /* must be too-tiny graph */ pixels = x_end - x_start; if (pixels >= POINT_BUFFER_SIZE) pixels = POINT_BUFFER_SIZE - 1; if ((x_start == x_end) || (samps <= 1)) samples_per_pixel = 0.01; /* any non-zero value < 1.0 should be ok here */ else samples_per_pixel = (mus_float_t)((double)(samps - 1) / (mus_float_t)pixels); /* this is assuming one dragged mark per channel */ if ((samples_per_pixel < 5.0) && (samps < POINT_BUFFER_SIZE)) { double incr; sf = init_sample_read(ap->losamp, cp, READ_FORWARD); if (sf == NULL) return; incr = (double)1.0 / cur_srate; if (current_sample < initial_sample) { for (j = 0, i = ap->losamp, x = start_time; i <= ap->hisamp; i++, j++, x += incr) { if (i == current_sample) for (k = current_sample; k < initial_sample; k++) read_sample(sf); set_grf_point(grf_x(x, ap), j, grf_y(read_sample(sf), ap)); } } else { for (j = 0, i = ap->losamp, x = start_time; i <= ap->hisamp; i++, j++, x += incr) { double samp; if ((i < initial_sample) || (i >= current_sample)) samp = read_sample(sf); else samp = 0.0; set_grf_point(grf_x(x, ap), j, grf_y(samp, ap)); } } erase_and_draw_grf_points(mark_movers[which], cp, j); } else { mus_float_t ymin, ymax; int xi; double xf; if (peak_env_usable(cp, samples_per_pixel, ap->hisamp, false, cp->edit_ctr, (samps > PEAK_ENV_CUTOFF))) { /* needs two sets of pointers and a frame within the amp env: * sample given mark edit: i and xk * sample within (original, unedited) amp env: ii and xki (xf) * frame bounds within amp env if relevant: k and kk * this is confusing code! */ double step, xk, xki; mus_long_t ii; peak_env_info *ep; ep = cp->edits[cp->edit_ctr]->peak_env; step = samples_per_pixel / (mus_float_t)(ep->samps_per_bin); xf = (double)(ap->losamp) / (double)(ep->samps_per_bin); j = 0; x = ap->x0; xi = grf_x(x, ap); i = ap->losamp; ii = ap->losamp; xk = i; xki = (double)(ap->losamp); while (i <= ap->hisamp) { mus_long_t kk; k = (mus_long_t)xf; kk = (mus_long_t)(xf + step); if (((current_sample >= initial_sample) && (i >= initial_sample) && (i < current_sample)) || (kk >= ep->peak_env_size)) { ymin = 0.0; ymax = 0.0; } else { ymin = ep->fmax; ymax = ep->fmin; for (; k <= kk; k++) { if (ep->data_min[k] < ymin) ymin = ep->data_min[k]; if (ep->data_max[k] > ymax) ymax = ep->data_max[k]; } } set_grf_points(xi++, j++, grf_y(ymin, ap), grf_y(ymax, ap)); xk += samples_per_pixel; i = (mus_long_t)xk; if ((current_sample < initial_sample) && (ii >= current_sample) && (ii < initial_sample)) { xf = (mus_float_t)((double)initial_sample / (mus_float_t)ep->samps_per_bin); ii = initial_sample; xki = (double)initial_sample; } else { if ((current_sample < initial_sample) || (i >= current_sample) || (i < initial_sample)) { xf += step; xki += samples_per_pixel; ii = (mus_long_t)xki; } } } erase_and_draw_both_grf_points(mark_movers[which], cp, j); } else { mus_float_t msamp; sf = init_sample_read(ap->losamp, cp, READ_FORWARD); if (sf == NULL) return; j = 0; /* graph point counter */ x = ap->x0; xi = grf_x(x, ap); xf = 0.0; /* samples per pixel counter */ ymin = MIN_INIT; ymax = MAX_INIT; if (current_sample < initial_sample) { for (i = ap->losamp; i <= ap->hisamp; i++) { if (i == current_sample) for (k = current_sample; k < initial_sample; k++) read_sample(sf); msamp = read_sample(sf); if (msamp > ymax) ymax = msamp; if (msamp < ymin) ymin = msamp; xf += 1.0; if (xf > samples_per_pixel) { set_grf_points(xi, j, grf_y(ymin, ap), grf_y(ymax, ap)); xi++; j++; xf -= samples_per_pixel; ymin = MIN_INIT; ymax = MAX_INIT; } } } else { for (i = ap->losamp, xf = 0.0; i <= ap->hisamp; i++) { if ((i < initial_sample) || (i >= current_sample)) msamp = read_sample(sf); else msamp = 0.0; if (msamp > ymax) ymax = msamp; if (msamp < ymin) ymin = msamp; xf += 1.0; if (xf > samples_per_pixel) { set_grf_points(xi, j, grf_y(ymin, ap), grf_y(ymax, ap)); xi++; j++; xf -= samples_per_pixel; ymin = MIN_INIT; ymax = MAX_INIT; } } } erase_and_draw_both_grf_points(mark_movers[which], cp, j); } } free_snd_fd(sf); #endif } #if (!USE_NO_GUI) /* -------------------------------- display mark -------------------------------- */ static void show_mark(chan_info *cp, mark *mp, bool show) { int top, cx, y0, y1; axis_info *ap; graphics_context *ax; #if USE_MOTIF #define STRING_Y_OFFSET 6 #else #define STRING_Y_OFFSET -6 #endif ap = cp->axis; top = ap->y_axis_y1; y1 = top; y0 = ap->y_axis_y0; if (mp->name) top += 10; cx = grf_x((double)(mp->samp) / (double)snd_srate(cp->sound), ap); ax = mark_tag_context(cp); #if USE_GTK ss->cr = make_cairo(ax->wn); #endif if (mp->name) { int len; #if USE_MOTIF ax->current_font = ss->peaks_fontstruct->fid; XSetFont(ax->dp, ax->gc, ss->peaks_fontstruct->fid); #else ax->current_font = PEAKS_FONT(ss); #endif len = mark_name_width(mp->name); draw_string(ax, (int)(cx - 0.5 * len), y1 + STRING_Y_OFFSET, mp->name, strlen(mp->name)); } fill_rectangle(ax, cx - mark_tag_width(ss), top, 2 * mark_tag_width(ss), mark_tag_height(ss)); draw_line(ax, cx, top + 4, cx, y0); if (mp->samp != cursor_sample(cp)) fill_polygon(ax, 4, cx, y0, cx + play_arrow_size(ss), y0 + play_arrow_size(ss), cx, y0 + 2 * play_arrow_size(ss), cx, y0); mp->visible = show; #if USE_GTK free_cairo(ss->cr); ss->cr = NULL; copy_context(cp); #endif } #else /* no gui */ static void show_mark(chan_info *cp, mark *mp, bool show) {} #endif /* ---------------------------------------- mark object ---------------------------------------- */ typedef struct { int n; } xen_mark; #define Xen_to_xen_mark(arg) ((xen_mark *)Xen_object_ref(arg)) int xen_mark_to_int(Xen n) { xen_mark *mx; mx = Xen_to_xen_mark(n); return(mx->n); } static Xen_object_type_t xen_mark_tag; bool xen_is_mark(Xen obj) { return(Xen_c_object_is_type(obj, xen_mark_tag)); } static void xen_mark_free(xen_mark *v) {if (v) free(v);} Xen_wrap_free(xen_mark, free_xen_mark, xen_mark_free) static char *xen_mark_to_string(xen_mark *v) { #define MARK_PRINT_BUFFER_SIZE 64 char *buf; if (v == NULL) return(NULL); buf = (char *)calloc(MARK_PRINT_BUFFER_SIZE, sizeof(char)); snprintf(buf, MARK_PRINT_BUFFER_SIZE, "#", v->n); return(buf); } Xen_wrap_print(xen_mark, print_xen_mark, xen_mark_to_string) #if HAVE_FORTH || HAVE_RUBY static Xen g_xen_mark_to_string(Xen obj) { char *vstr; Xen result; #define S_xen_mark_to_string "mark->string" Xen_check_type(xen_is_mark(obj), obj, 1, S_xen_mark_to_string, "a mark"); vstr = xen_mark_to_string(Xen_to_xen_mark(obj)); result = C_string_to_Xen_string(vstr); free(vstr); return(result); } #endif #if (!HAVE_SCHEME) static bool xen_mark_equalp(xen_mark *v1, xen_mark *v2) { return((v1 == v2) || (v1->n == v2->n)); } static Xen equalp_xen_mark(Xen obj1, Xen obj2) { if ((!(xen_is_mark(obj1))) || (!(xen_is_mark(obj2)))) return(Xen_false); return(C_bool_to_Xen_boolean(xen_mark_equalp(Xen_to_xen_mark(obj1), Xen_to_xen_mark(obj2)))); } #endif static xen_mark *xen_mark_make(int n) { xen_mark *new_v; new_v = (xen_mark *)malloc(sizeof(xen_mark)); new_v->n = n; return(new_v); } Xen new_xen_mark(int n) { xen_mark *mx; if (n < 0) return(Xen_false); mx = xen_mark_make(n); return(Xen_make_object(xen_mark_tag, mx, 0, free_xen_mark)); } #if HAVE_SCHEME static bool s7_xen_mark_equalp(void *obj1, void *obj2) { return((obj1 == obj2) || (((xen_mark *)obj1)->n == ((xen_mark *)obj2)->n)); } static Xen s7_xen_mark_copy(s7_scheme *sc, s7_pointer args) { s7_pointer obj; int id; mark *m; chan_info *cps[1] = {NULL}; obj = s7_car(args); id = xen_mark_to_int(obj); m = find_mark_from_id(id, cps, AT_CURRENT_EDIT_POSITION); if (m) { mark *new_m; new_m = add_mark(m->samp, m->name, cps[0]); new_m->sync = m->sync; return(new_xen_mark(new_m->id)); } return(obj); } #endif static void init_xen_mark(void) { #if HAVE_SCHEME xen_mark_tag = s7_new_type_x(s7, "", print_xen_mark, free_xen_mark, s7_xen_mark_equalp, NULL, NULL, NULL, NULL, s7_xen_mark_copy, NULL, NULL); #else #if HAVE_RUBY xen_mark_tag = Xen_make_object_type("XenMark", sizeof(xen_mark)); #else xen_mark_tag = Xen_make_object_type("Mark", sizeof(xen_mark)); #endif #endif #if HAVE_FORTH fth_set_object_inspect(xen_mark_tag, print_xen_mark); fth_set_object_dump(xen_mark_tag, g_xen_mark_to_string); fth_set_object_equal(xen_mark_tag, equalp_xen_mark); fth_set_object_free(xen_mark_tag, free_xen_mark); #endif #if HAVE_RUBY rb_define_method(xen_mark_tag, "to_s", Xen_procedure_cast print_xen_mark, 0); rb_define_method(xen_mark_tag, "eql?", Xen_procedure_cast equalp_xen_mark, 1); rb_define_method(xen_mark_tag, "==", Xen_procedure_cast equalp_xen_mark, 1); rb_define_method(xen_mark_tag, "to_str", Xen_procedure_cast g_xen_mark_to_string, 0); #endif } /* -------------------------------------------------------------------------------- */ static Xen g_integer_to_mark(Xen n) { #define H_integer_to_mark "(" S_integer_to_mark " n) returns a mark object corresponding to the given integer" Xen_check_type(Xen_is_integer(n), n, 1, S_integer_to_mark, "an integer"); return(new_xen_mark(Xen_integer_to_C_int(n))); } static Xen g_mark_to_integer(Xen n) { #define H_mark_to_integer "(" S_mark_to_integer " id) returns the integer corresponding to the given mark object" Xen_check_type(xen_is_mark(n), n, 1, S_mark_to_integer, "a mark"); return(C_int_to_Xen_integer(xen_mark_to_int(n))); } static Xen snd_no_such_mark_error(const char *caller, Xen id) { Xen_error(Xen_make_error_type("no-such-mark"), Xen_list_3(C_string_to_Xen_string("~A: no such mark ~A"), C_string_to_Xen_string(caller), id)); return(Xen_false); } typedef enum {MARK_SAMPLE, MARK_NAME, MARK_SYNC, MARK_HOME} mark_field_t; static Xen mark_get(Xen n, mark_field_t fld, Xen pos_n, const char *caller) { int pos; chan_info *ncp[1]; mark *m = NULL; pos = (Xen_is_integer(pos_n)) ? Xen_integer_to_C_int(pos_n) : AT_CURRENT_EDIT_POSITION; m = find_mark_from_id(Xen_mark_to_C_int(n), ncp, pos); if (m == NULL) return(snd_no_such_mark_error(caller, n)); switch (fld) { case MARK_SAMPLE: return(C_llong_to_Xen_llong(m->samp)); break; case MARK_SYNC: return(C_int_to_Xen_integer(m->sync)); break; case MARK_NAME: if (m->name) return(C_string_to_Xen_string(m->name)); else return(C_string_to_Xen_string("")); break; case MARK_HOME: return(Xen_list_2(C_int_to_Xen_sound((ncp[0]->sound)->index), C_int_to_Xen_integer(ncp[0]->chan))); break; } return(Xen_false); } static Xen mark_set(Xen mark_n, Xen val, mark_field_t fld, const char *caller) { chan_info *cp[1]; mark *m; m = find_mark_from_id(Xen_mark_to_C_int(mark_n), cp, AT_CURRENT_EDIT_POSITION); if (m == NULL) return(snd_no_such_mark_error(caller, mark_n)); switch (fld) { case MARK_SAMPLE: m->samp = mus_oclamp(0, (Xen_is_llong(val)) ? Xen_llong_to_C_llong(val) : 0, current_samples(cp[0])); sort_marks(cp[0]); /* update and re-sort current mark list */ run_mark_hook(cp[0], m->id, MARK_MOVE); update_graph(cp[0]); break; case MARK_SYNC: if (Xen_is_integer(val)) set_mark_sync(m, Xen_integer_to_C_int(val)); else set_mark_sync(m, (int)Xen_boolean_to_C_bool(val)); break; case MARK_NAME: if (m->name) free(m->name); if (Xen_is_false(val)) m->name = NULL; else m->name = mus_strdup(Xen_string_to_C_string(val)); update_graph(cp[0]); break; default: break; } return(val); } static Xen g_is_mark(Xen id_n) { #define H_is_mark "(" S_is_mark " id): " PROC_TRUE " if mark is active" if (xen_is_mark(id_n)) return(C_bool_to_Xen_boolean(find_mark_from_id(Xen_mark_to_C_int(id_n), NULL, AT_CURRENT_EDIT_POSITION))); return(Xen_false); } static Xen g_mark_sample(Xen mark_n, Xen pos_n) { #define H_mark_sample "(" S_mark_sample " id :optional pos): mark's location (sample number) at edit history pos" Xen_check_type(xen_is_mark(mark_n), mark_n, 1, S_mark_sample, "a mark"); Xen_check_type(Xen_is_integer_or_unbound(pos_n), pos_n, 2, S_mark_sample, "an integer"); return(mark_get(mark_n, MARK_SAMPLE, pos_n, S_mark_sample)); } static Xen g_set_mark_sample(Xen mark_n, Xen samp_n) { Xen_check_type(xen_is_mark(mark_n), mark_n, 1, S_set S_mark_sample, "a mark"); Xen_check_type(Xen_is_llong(samp_n) || !Xen_is_bound(samp_n), samp_n, 2, S_set S_mark_sample, "an integer"); return(mark_set(mark_n, samp_n, MARK_SAMPLE, S_set S_mark_sample)); } Xen g_mark_sync(Xen mark_n) { #define H_mark_sync "(" S_mark_sync " id): mark's sync value (default: 0)" Xen_check_type(xen_is_mark(mark_n), mark_n, 1, S_mark_sync, "a mark"); return(mark_get(mark_n, MARK_SYNC, Xen_undefined, S_mark_sync)); } Xen g_set_mark_sync(Xen mark_n, Xen sync_n) { Xen_check_type(xen_is_mark(mark_n), mark_n, 1, S_set S_mark_sync, "a mark"); Xen_check_type(Xen_is_integer_or_boolean(sync_n), sync_n, 2, S_set S_mark_sync, "an integer"); return(mark_set(mark_n, sync_n, MARK_SYNC, S_set S_mark_sync)); } static Xen g_mark_name(Xen mark_n) { #define H_mark_name "(" S_mark_name " id): mark's name" Xen_check_type(xen_is_mark(mark_n), mark_n, 1, S_mark_name, "a mark"); return(mark_get(mark_n, MARK_NAME, Xen_undefined, S_mark_name)); } static Xen g_set_mark_name(Xen mark_n, Xen name) { Xen_check_type(xen_is_mark(mark_n), mark_n, 1, S_set S_mark_name, "a mark"); Xen_check_type(Xen_is_string(name) || Xen_is_false(name), name, 2, S_set S_mark_name, "a string"); return(mark_set(mark_n, name, MARK_NAME, S_set S_mark_name)); } static Xen g_mark_sync_max(void) { #define H_mark_sync_max "(" S_mark_sync_max "): max mark sync value seen so far" return(C_int_to_Xen_integer(mark_sync_max())); } static Xen g_mark_home(Xen mark_n) { #define H_mark_home "(" S_mark_home " id): the sound (index) and channel that hold mark id" Xen_check_type(xen_is_mark(mark_n), mark_n, 1, S_mark_home, "a mark"); return(mark_get(mark_n, MARK_HOME, Xen_undefined, S_mark_home)); } static Xen g_find_mark(Xen samp_n, Xen snd, Xen chn_n, Xen edpos) { #define H_find_mark "(" S_find_mark " samp-or-name :optional snd chn edpos): \ find the mark in snd's channel chn at samp (if a number) or with the given name (if a string); return the mark or " PROC_FALSE " if no mark found." mark **mps; int pos; chan_info *cp = NULL; Xen_check_type((Xen_is_llong(samp_n) || Xen_is_string(samp_n) || (Xen_is_false(samp_n))), samp_n, 1, S_find_mark, "an integer or string or " PROC_FALSE); Snd_assert_channel(S_find_mark, snd, chn_n, 2); cp = get_cp(snd, chn_n, S_find_mark); if (!cp) return(Xen_false); pos = to_c_edit_position(cp, edpos, S_find_mark, 4); mps = cp->edits[pos]->marks; if (mps) { int i; mus_long_t samp = 0; const char *name = NULL; if (Xen_is_string(samp_n)) name = Xen_string_to_C_string(samp_n); else { if (Xen_is_llong(samp_n)) samp = Xen_llong_to_C_llong(samp_n); } if (name) { for (i = 0; i <= cp->edits[pos]->mark_ctr; i++) if ((mps[i]) && (mus_strcmp(name, mps[i]->name))) return(new_xen_mark(mps[i]->id)); } else { for (i = 0; i <= cp->edits[pos]->mark_ctr; i++) if ((mps[i]) && (mps[i]->samp == samp)) return(new_xen_mark(mps[i]->id)); } } return(Xen_false); } static Xen g_add_mark_1(Xen samp_n, Xen snd, Xen chn_n, Xen name, Xen sync, bool check_sample, const char *caller) { #define H_add_mark "(" S_add_mark " samp :optional snd chn name (sync 0)): add a mark at sample samp returning the mark." mark *m = NULL; chan_info *cp; mus_long_t loc = 0; int msync = 0; const char *mname = NULL; Xen_check_type(Xen_is_llong(samp_n) || !Xen_is_bound(samp_n), samp_n, 1, caller, "an integer"); Xen_check_type(Xen_is_string_or_unbound(name) || Xen_is_false(name), name, 4, caller, "a string"); Xen_check_type(Xen_is_integer_or_unbound(sync), sync, 5, caller, "an integer"); Snd_assert_channel(caller, snd, chn_n, 2); cp = get_cp(snd, chn_n, caller); if (!cp) return(Xen_false); if (Xen_is_llong(samp_n)) loc = Xen_llong_to_C_llong(samp_n); if ((!check_sample) && (loc >= current_samples(cp))) return(Xen_false); if ((loc < 0) || (loc >= current_samples(cp))) Xen_error(NO_SUCH_SAMPLE, Xen_list_2(C_string_to_Xen_string(S_add_mark ": no such sample, ~A"), samp_n)); if (Xen_is_string(name)) mname = Xen_string_to_C_string(name); if (Xen_is_integer(sync)) msync = Xen_integer_to_C_int(sync); m = add_mark(loc, mname, cp); if (m) { if (msync != 0) set_mark_sync(m, msync); update_graph(cp); return(new_xen_mark(m->id)); } return(Xen_false); } static Xen g_add_mark(Xen samp_n, Xen snd, Xen chn_n, Xen name, Xen sync) { return(g_add_mark_1(samp_n, snd, chn_n, name, sync, true, S_add_mark)); } static Xen g_add_mark_unchecked(Xen samp_n, Xen snd, Xen chn_n, Xen name, Xen sync) { #define H_add_mark_unchecked "(add-mark! samp :optional snd chn name (sync 0)): add a mark at sample samp returning the mark.\ Unlike add-mark, add-mark! does not check for an invalid sample number." return(g_add_mark_1(samp_n, snd, chn_n, name, sync, false, S_add_mark "!")); } static Xen g_delete_mark(Xen id_n) { #define H_delete_mark "(" S_delete_mark " id): delete mark id" chan_info *cp[1]; mark *m; int id; Xen_check_type(xen_is_mark(id_n), id_n, 1, S_delete_mark, "a mark"); id = Xen_mark_to_C_int(id_n); m = find_mark_from_id(id, cp, AT_CURRENT_EDIT_POSITION); if (m == NULL) return(snd_no_such_mark_error(S_delete_mark, id_n)); if (delete_mark_id(id, cp[0])) update_graph(cp[0]); else return(snd_no_such_mark_error(S_delete_mark, id_n)); return(id_n); } static Xen g_delete_marks(Xen snd, Xen chn_n) { #define H_delete_marks "(" S_delete_marks " :optional snd chn): delete all marks in snd's channel chn" chan_info *cp; Snd_assert_channel(S_delete_marks, snd, chn_n, 1); cp = get_cp(snd, chn_n, S_delete_marks); if (!cp) return(Xen_false); delete_marks(cp); return(Xen_false); } static Xen int_array_to_mark_list(int *arr, int i, int len) { if (i < len) return(Xen_cons(new_xen_mark(arr[i]), int_array_to_mark_list(arr, i + 1, len))); return(Xen_cons(new_xen_mark(arr[i]), Xen_empty_list)); } static int *syncd_marks(int sync) { syncdata *sd; int *ids; int i; sd = make_syncdata(sync); for_each_normal_chan_with_void(gather_chan_syncd_marks, (void *)sd); ids = (int *)calloc(1 + sd->mark_ctr, sizeof(int)); ids[0] = sd->mark_ctr; for (i = 0; i < sd->mark_ctr; i++) ids[i + 1] = sd->marks[i]->id; free_syncdata(sd); return(ids); } static Xen g_syncd_marks(Xen sync) { #define H_syncd_marks "(" S_syncd_marks " sync): list of marks that share a given sync value (" S_mark_sync ")" int *ids; Xen res; Xen_check_type(Xen_is_integer(sync), sync, 1, S_syncd_marks, "an integer"); ids = syncd_marks(Xen_integer_to_C_int(sync)); if (ids == NULL) return(Xen_empty_list); if (ids[0] == 0) {free(ids); return(Xen_empty_list);} res = int_array_to_mark_list(ids, 1, ids[0]); free(ids); return(res); } static Xen g_mark_tag_width(void) {return(C_int_to_Xen_integer(mark_tag_width(ss)));} static Xen g_set_mark_tag_width(Xen val) { #define H_mark_tag_width "(" S_mark_tag_width "): width (pixels) of mark tags (10)" int width; Xen_check_type(Xen_is_integer(val), val, 1, S_set S_mark_tag_width, "an integer"); width = mus_iclamp(0, Xen_integer_to_C_int(val), LOTSA_PIXELS); set_mark_tag_width(width); for_each_normal_chan(update_graph); return(C_int_to_Xen_integer(mark_tag_width(ss))); } static Xen g_mark_tag_height(void) {return(C_int_to_Xen_integer(mark_tag_height(ss)));} static Xen g_set_mark_tag_height(Xen val) { #define H_mark_tag_height "(" S_mark_tag_height "): height (pixels) of mark tags (4)" int height; Xen_check_type(Xen_is_integer(val), val, 1, S_set S_mark_tag_height, "an integer"); height = mus_iclamp(0, Xen_integer_to_C_int(val), LOTSA_PIXELS); set_mark_tag_height(height); for_each_normal_chan(update_graph); return(C_int_to_Xen_integer(mark_tag_height(ss))); } static int *channel_marks(chan_info *cp, int pos) { int *ids = NULL; ed_list *ed; ed = cp->edits[pos]; if (ed->marks) { mark **mps; int marks; mps = ed->marks; marks = ed->mark_ctr; if (mps) { int i; ids = (int *)calloc(marks + 2, sizeof(int)); /* 1 for size, 1 because mark_ctr is current count */ ids[0] = marks + 1; for (i = 0; i <= marks; i++) ids[i + 1] = mps[i]->id; } } return(ids); } static Xen g_marks(Xen snd, Xen chn_n, Xen pos_n) { #define H_marks "(" S_marks " :optional snd chn edpos): list of marks in snd/chn at edit history position pos. \ mark list is: channel given: (id id ...), snd given: ((id id) (id id ...)), neither given: (((id ...) ...) ...)." chan_info *cp; snd_info *sp; Xen res1 = Xen_empty_list; Snd_assert_channel(S_marks, snd, chn_n, 0); if (Xen_is_integer(snd) || xen_is_sound(snd)) { int *ids; if (Xen_is_integer(chn_n)) { int pos; Xen res; cp = get_cp(snd, chn_n, S_marks); if (!cp) return(Xen_false); if (Xen_is_integer(pos_n)) { pos = Xen_integer_to_C_int(pos_n); if (pos == AT_CURRENT_EDIT_POSITION) pos = cp->edit_ctr; if ((pos < 0) || (pos >= cp->edit_size) || (cp->edits[pos] == NULL)) Xen_error(NO_SUCH_EDIT, Xen_list_2(C_string_to_Xen_string(S_marks ": no such edit, ~A"), pos_n)); } else pos = cp->edit_ctr; ids = channel_marks(cp, pos); if (ids == NULL) return(Xen_empty_list); if (ids[0] == 0) { free(ids); return(Xen_empty_list); } res = int_array_to_mark_list(ids, 1, ids[0]); free(ids); return(res); } else { int i; sp = get_sp(snd); if (sp == NULL) return(snd_no_such_sound_error(S_marks, snd)); for (i = sp->nchans - 1; i >= 0; i--) { cp = sp->chans[i]; ids = channel_marks(cp, cp->edit_ctr); if ((ids == NULL) || (ids[0] == 0)) res1 = Xen_cons(Xen_empty_list, res1); else res1 = Xen_cons(int_array_to_mark_list(ids, 1, ids[0]), res1); if (ids) free(ids); } } } else { int j; /* all marks */ for (j = ss->max_sounds - 1; j >= 0; j--) { sp = ss->sounds[j]; if ((sp) && (sp->inuse == SOUND_NORMAL)) res1 = Xen_cons(g_marks(C_int_to_Xen_integer(j), Xen_undefined, Xen_undefined), res1); } } return(res1); } /* ---------------- saved marks ---------------- * * upon restoration, pre-existing marks can collide both in mark-id and mark-sync * with the saved marks, so these need to be fixed-up as they are encountered. * Also mark-sync-max needs to reflect the newly chosen sync values. * * We used to try to save the entire mark history, but I can't see how that can work * in general -- the save-marks output can be loaded at any time, so we can't * rely on anything in regard to the edit history. */ static bool find_any_marks(chan_info *cp) { ed_list *ed; ed = cp->edits[cp->edit_ctr]; return((ed->marks) && (ed->mark_ctr >= 0)); /* initialized to -1 -- 0 is first mark */ } typedef struct { FILE *fd; int size; int *syncs; } save_mark_info; #define SYNC_BASE "_sync_" #define SYNC_NAME_SIZE 32 static char *mark_sync_name(int cur_sync) { char *result; result = (char *)calloc(SYNC_NAME_SIZE, sizeof(char)); snprintf(result, SYNC_NAME_SIZE, "%s%d", SYNC_BASE, cur_sync); return(result); } static char *map_mark_sync(chan_info *cp, mark *m, save_mark_info *sv) { /* if sync 0 just return "0", else if already in syncs array, use _sync_n_ as name, * else open a let, declare _sync_n_ with new safe value, * add current int value to syncs array (can't assume unshared here will not collide later) */ int i, cur_sync; cur_sync = m->sync; if (cur_sync == 0) return(mus_strdup("0")); if (sv->size > 0) for (i = 0; i < sv->size; i++) if (cur_sync == sv->syncs[i]) return(mark_sync_name(cur_sync)); /* add sync to current set (protect against later collisions, take current shared-syncs into account) */ if (sv->size == 0) sv->syncs = (int *)calloc(1, sizeof(int)); else sv->syncs = (int *)realloc(sv->syncs, (sv->size + 1) * sizeof(int)); sv->syncs[sv->size++] = cur_sync; #if (!HAVE_FORTH) fprintf(sv->fd, " "); for (i = 0; i < sv->size - 1; i++) fprintf(sv->fd, " "); /* previous lets */ #endif #if HAVE_SCHEME fprintf(sv->fd, "(let ((%s%d (1+ (mark-sync-max))))\n", SYNC_BASE, cur_sync); #endif #if HAVE_RUBY fprintf(sv->fd, "begin\n %s%d = mark_sync_max + 1\n", SYNC_BASE, cur_sync); #endif #if HAVE_FORTH fprintf(sv->fd, "mark-sync-max 1 + value %s%d\n", SYNC_BASE, cur_sync); #endif return(mark_sync_name(cur_sync)); } static mark *save_mark(chan_info *cp, mark *m, void *info) { /* we're called within "sound_block" where "sfile" = current sound index */ save_mark_info *sv = (save_mark_info *)info; char *mapped_sync; int i; mapped_sync = map_mark_sync(cp, m, sv); fprintf(sv->fd, " "); for (i = 0; i < sv->size; i++) fprintf(sv->fd, " "); /* lets */ /* here we need to use the "!" form of add-mark to ignore bad sample numbers -- these can come about during * the save-state process when redoable edits causing extensions are undone before marks are added, * possibly to the extended portion -- we'll simply drop those marks, rather than wrecking the restore * process with an error. */ #if HAVE_SCHEME if (m->name) fprintf(sv->fd, "(add-mark! %lld sfile %d \"%s\" %s)\n", m->samp, cp->chan, m->name, mapped_sync); else fprintf(sv->fd, "(add-mark! %lld sfile %d #f %s)\n", m->samp, cp->chan, mapped_sync); #endif #if HAVE_RUBY if (m->name) fprintf(sv->fd, "add_mark!(%lld, sfile, %d, \"%s\", %s)\n", m->samp, cp->chan, m->name, mapped_sync); else fprintf(sv->fd, "add_mark!(%lld, sfile, %d, false, %s)\n", m->samp, cp->chan, mapped_sync); #endif #if HAVE_FORTH if (m->name) fprintf(sv->fd, "%lld sfile %d \"%s\" %s add-mark! drop\n", m->samp, cp->chan, m->name, mapped_sync); else fprintf(sv->fd, "%lld sfile %d #f %s add-mark! drop\n", m->samp, cp->chan, mapped_sync); #endif free(mapped_sync); return(NULL); /* returning a mark here breaks out of the map mark loop */ } void save_mark_list(FILE *fd, chan_info *cp, bool all_chans) { /* used in save-marks (below) and the edit history stuff in snd-edits.c * changed 23-Sep-06 -- restore-marks is now a no-op, and no attempt is made to save the entire mark history. */ save_mark_info *sv; if ((!all_chans) && (!(find_any_marks(cp)))) return; /* in the sound (all_chans) case, this has been checked already */ sv = (save_mark_info *)calloc(1, sizeof(save_mark_info)); sv->fd = fd; sv->size = 0; sv->syncs = NULL; if (all_chans) { int i; snd_info *sp; sp = cp->sound; for (i = 0; i < sp->nchans; i++) map_over_marks(sp->chans[i], save_mark, (void *)sv, READ_FORWARD); } else map_over_marks(cp, save_mark, (void *)sv, READ_FORWARD); if (sv->size > 0) { #if HAVE_SCHEME || HAVE_RUBY int i; #endif fprintf(fd, " "); #if HAVE_SCHEME for (i = 0; i < sv->size; i++) fprintf(fd, ")"); #endif #if HAVE_RUBY for (i = 0; i < sv->size; i++) fprintf(fd, "end\n"); #endif fprintf(fd, "\n"); } if (sv->syncs) free(sv->syncs); free(sv); } static Xen g_save_marks(Xen snd, Xen filename) { #define H_save_marks "(" S_save_marks " :optional snd (filename \".marks\")): save snd's marks in filename. \ The saved file is " Xen_language " code, so to restore the marks, load that file." snd_info *sp; Xen res = Xen_false; Snd_assert_sound(S_save_marks, snd, 1); Xen_check_type(Xen_is_string_or_unbound(filename), filename, 2, S_save_marks, "a string"); sp = get_sp(snd); if (sp == NULL) return(snd_no_such_sound_error(S_save_marks, snd)); if (map_over_sound_chans(sp, find_any_marks)) /* are there any marks? */ { char *newname = NULL; FILE *fd; if (Xen_is_string(filename)) newname = mus_strdup(Xen_string_to_C_string(filename)); else { int i, len; len = strlen(sp->filename); newname = (char *)calloc(len + 7, sizeof(char)); strcopy(newname, sp->filename, len + 7); for (i = len - 1; i > 0; i--) if (newname[i] == '.') break; if (i > 0) len = i; newname[len] = '\0'; strcat(newname, ".marks"); } fd = FOPEN(newname, "w"); if (fd == NULL) { Xen lname; lname = C_string_to_Xen_string(newname); free(newname); Xen_error(CANNOT_SAVE, Xen_list_3(C_string_to_Xen_string(S_save_marks ": can't save ~S, ~A"), lname, C_string_to_Xen_string(snd_open_strerror()))); } else { #if HAVE_FORTH fprintf(fd, "#f value sfile\n"); #endif open_save_sound_block(sp, fd, false); /* find-sound or open it with enclosing let */ save_mark_list(fd, sp->chans[0], true); /* true -> save all chans, matching cross-channel syncs */ close_save_sound_block(fd, false); /* close the let form */ snd_fclose(fd, newname); res = C_string_to_Xen_string(newname); } free(newname); } return(res); } static Xen g_mark_properties(Xen n) { mark *m; #define H_mark_properties "(" S_mark_properties " id): A property list associated with the given mark." Xen_check_type(xen_is_mark(n), n, 1, S_mark_properties, "a mark"); m = find_mark_from_id(Xen_mark_to_C_int(n), NULL, AT_CURRENT_EDIT_POSITION); if (m == NULL) return(snd_no_such_mark_error(S_mark_properties, n)); if (!(Xen_is_vector(m->properties))) { m->properties = Xen_make_vector(1, Xen_empty_list); m->properties_gc_loc = snd_protect(m->properties); } return(Xen_vector_ref(m->properties, 0)); } static Xen g_set_mark_properties(Xen n, Xen val) { mark *m; Xen_check_type(xen_is_mark(n), n, 1, S_mark_properties, "a mark"); m = find_mark_from_id(Xen_mark_to_C_int(n), NULL, AT_CURRENT_EDIT_POSITION); if (m == NULL) return(snd_no_such_mark_error(S_set S_mark_properties, n)); if (!(Xen_is_vector(m->properties))) { m->properties = Xen_make_vector(1, Xen_empty_list); m->properties_gc_loc = snd_protect(m->properties); } Xen_vector_set(m->properties, 0, val); return(Xen_vector_ref(m->properties, 0)); } static Xen g_mark_property(Xen key, Xen id) { #define H_mark_property "(" S_mark_property " key id) returns the value associated with 'key' in the given mark's property list, or " PROC_FALSE "." Xen_check_type(xen_is_mark(id), id, 2, S_mark_property, "a mark"); return(Xen_assoc_ref(key, g_mark_properties(id))); } static Xen g_set_mark_property(Xen key, Xen id, Xen val) { Xen_check_type(xen_is_mark(id), id, 2, S_mark_property, "a mark"); g_set_mark_properties(id, Xen_assoc_set(key, val, g_mark_properties(id))); return(val); } Xen_wrap_2_optional_args(g_mark_sample_w, g_mark_sample) Xen_wrap_2_args(g_set_mark_sample_w, g_set_mark_sample) Xen_wrap_1_arg(g_mark_sync_w, g_mark_sync) Xen_wrap_2_args(g_set_mark_sync_w, g_set_mark_sync) Xen_wrap_1_arg(g_mark_name_w, g_mark_name) Xen_wrap_2_args(g_set_mark_name_w, g_set_mark_name) Xen_wrap_no_args(g_mark_sync_max_w, g_mark_sync_max) Xen_wrap_1_arg(g_mark_home_w, g_mark_home) Xen_wrap_3_optional_args(g_marks_w, g_marks) Xen_wrap_5_optional_args(g_add_mark_w, g_add_mark) Xen_wrap_5_optional_args(g_add_mark_unchecked_w, g_add_mark_unchecked) Xen_wrap_1_arg(g_delete_mark_w, g_delete_mark) Xen_wrap_2_optional_args(g_delete_marks_w, g_delete_marks) Xen_wrap_1_arg(g_syncd_marks_w, g_syncd_marks) Xen_wrap_no_args(g_mark_tag_width_w, g_mark_tag_width) Xen_wrap_1_arg(g_set_mark_tag_width_w, g_set_mark_tag_width) Xen_wrap_no_args(g_mark_tag_height_w, g_mark_tag_height) Xen_wrap_1_arg(g_set_mark_tag_height_w, g_set_mark_tag_height) Xen_wrap_4_optional_args(g_find_mark_w, g_find_mark) Xen_wrap_2_optional_args(g_save_marks_w, g_save_marks) Xen_wrap_1_arg(g_is_mark_w, g_is_mark) Xen_wrap_1_arg(g_integer_to_mark_w, g_integer_to_mark) Xen_wrap_1_arg(g_mark_to_integer_w, g_mark_to_integer) Xen_wrap_1_arg(g_mark_properties_w, g_mark_properties) Xen_wrap_2_args(g_set_mark_properties_w, g_set_mark_properties) Xen_wrap_2_args(g_mark_property_w, g_mark_property) Xen_wrap_3_args(g_set_mark_property_w, g_set_mark_property) #if HAVE_SCHEME static s7_pointer acc_mark_tag_height(s7_scheme *sc, s7_pointer args) {return(g_set_mark_tag_height(s7_cadr(args)));} static s7_pointer acc_mark_tag_width(s7_scheme *sc, s7_pointer args) {return(g_set_mark_tag_width(s7_cadr(args)));} #endif void g_init_marks(void) { #define H_mark_drag_hook S_mark_drag_hook " (id): called when a mark is dragged" #define H_mark_hook S_mark_hook " (id snd chn reason): called when a mark added, deleted, or moved. \ 'Reason' can be 0: add, 1: delete, 2: move, 3: delete all marks" init_xen_mark(); mark_drag_hook = Xen_define_hook(S_mark_drag_hook, "(make-hook 'id)", 1, H_mark_drag_hook); mark_hook = Xen_define_hook(S_mark_hook, "(make-hook 'id 'snd 'chn 'reason)", 4, H_mark_hook); Xen_define_dilambda(S_mark_sample, g_mark_sample_w, H_mark_sample, S_set S_mark_sample, g_set_mark_sample_w, 1, 1, 2, 0); Xen_define_dilambda(S_mark_sync, g_mark_sync_w, H_mark_sync, S_set S_mark_sync, g_set_mark_sync_w, 1, 0, 2, 0); Xen_define_dilambda(S_mark_name, g_mark_name_w, H_mark_name, S_set S_mark_name, g_set_mark_name_w, 1, 0, 2, 0); Xen_define_safe_procedure(S_mark_sync_max, g_mark_sync_max_w, 0, 0, 0, H_mark_sync_max); Xen_define_safe_procedure(S_mark_home, g_mark_home_w, 1, 0, 0, H_mark_home); Xen_define_safe_procedure(S_marks, g_marks_w, 0, 3, 0, H_marks); Xen_define_safe_procedure(S_add_mark, g_add_mark_w, 0, 5, 0, H_add_mark); Xen_define_safe_procedure(S_add_mark "!", g_add_mark_unchecked_w, 0, 5, 0, H_add_mark_unchecked); Xen_define_safe_procedure(S_delete_mark, g_delete_mark_w, 1, 0, 0, H_delete_mark); Xen_define_safe_procedure(S_delete_marks, g_delete_marks_w, 0, 2, 0, H_delete_marks); Xen_define_safe_procedure(S_syncd_marks, g_syncd_marks_w, 1, 0, 0, H_syncd_marks); Xen_define_safe_procedure(S_find_mark, g_find_mark_w, 1, 3, 0, H_find_mark); Xen_define_safe_procedure(S_save_marks, g_save_marks_w, 0, 2, 0, H_save_marks); Xen_define_safe_procedure(S_is_mark, g_is_mark_w, 1, 0, 0, H_is_mark); Xen_define_safe_procedure(S_integer_to_mark, g_integer_to_mark_w, 1, 0, 0, H_integer_to_mark); Xen_define_safe_procedure(S_mark_to_integer, g_mark_to_integer_w, 1, 0, 0, H_mark_to_integer); Xen_define_dilambda(S_mark_tag_width, g_mark_tag_width_w, H_mark_tag_width, S_set S_mark_tag_width, g_set_mark_tag_width_w, 0, 0, 1, 0); Xen_define_dilambda(S_mark_tag_height, g_mark_tag_height_w, H_mark_tag_height, S_set S_mark_tag_height, g_set_mark_tag_height_w, 0, 0, 1, 0); Xen_define_dilambda(S_mark_properties, g_mark_properties_w, H_mark_properties, S_set S_mark_properties, g_set_mark_properties_w, 1, 0, 2, 0); Xen_define_dilambda(S_mark_property, g_mark_property_w, H_mark_property, S_set S_mark_property, g_set_mark_property_w, 2, 0, 3, 0); #define H_draw_mark_hook S_draw_mark_hook " (id): called before a mark is drawn. \ If the hook returns " PROC_TRUE ", the mark is not drawn." draw_mark_hook = Xen_define_hook(S_draw_mark_hook, "(make-hook 'id)", 1, H_draw_mark_hook); #if HAVE_SCHEME s7_symbol_set_access(s7, ss->mark_tag_height_symbol, s7_make_function(s7, "[acc-" S_mark_tag_height "]", acc_mark_tag_height, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->mark_tag_width_symbol, s7_make_function(s7, "[acc-" S_mark_tag_width "]", acc_mark_tag_width, 2, 0, false, "accessor")); s7_symbol_set_documentation(s7, ss->mark_tag_height_symbol, "*mark-tag-height*: height (pixels) of mark tags (4)"); s7_symbol_set_documentation(s7, ss->mark_tag_width_symbol, "*mark-tag-width*: width (pixels) of mark tags (10)"); #endif } snd-16.1/snd-xm.rb0000644000076400007640000021650712462674025012111 0ustar bilbil# snd-xm.rb -- snd-motif and snd-gtk classes and functions # Author: Michael Scholz # Created: 04/02/25 05:31:02 # Changed: 14/12/07 06:34:47 # Requires --with-motif|gtk # # Tested with Snd 15.x # Ruby 2.x.x # Motif 2.3.3 X11R6 # # module Snd_XM # make_snd_menu(name, args) do ... end # make_menu(name, parent) do ... end # make_popup_menu(name, parent) do ... end # make_dialog(label, *rest) do |w, c, i| ... end # format_sound_comment(comment) # scale_log2linear(lo, val, hi) # scale_linear2log(lo, val, hi) # scale_log_label(lo, val, hi) # semi_scale_label(val) # semitones2ratio # ratio2semitones # get_color(*new_color) # create_color(color) # yellow_pixel # red_pixel # white_pixel # black_pixel # update_label(list) # change_label(widget, string, [property: only Motif]) # find_child(widget, name) # each_child(widget) do |w| .... end # widget?(obj) # is_managed?(widget) # widget_name(widget) # set_scale_value(widget, value, scaler) # get_scale_value(widget, info, scaler) # raise_dialog(widget) # activate_dialog(dialog) # set_label_sensitive(widget, name, set_p) # set_sensitive(widget, flag) # add_main_pane(name, type, *args) # show_disk_space(snd) # # class Scale_widget # initialize(parent) # scale # label (only Motif) # add_scale(title, low, init, high, scale, kind) # # class Dialog_base # initialize(label, ok_cb, reset_cb, clear_cb, target_cb, help_cb) # dialog # parent # okay_button # doit_string(*args) # dismiss_string(*args) # help_string(*args) # reset_string(*args) # clear_string(*args) # # class Dialog < Dialog_base # add_slider(title, low, init, high, scl, kind, parent) do |w, c, i| ... end # add_toggle(label, value) do |val| ... end # add_target(labels) do |val| ... end # # Snd_Gtk only: # > module Snd_Gtk # > add_event_handler(parent, event, cb_data) do |w, e, d| ... end # > add_callback(parent, event, cb_data) do |w, d| ... end # > g_list_each(glist) do |val| ... end # # Snd_Motif only: # > module Snd_Motif # > string2compound(*args) # > compound2string(xstr) # > get_xtvalue(widget, item) # > current_label(widget) # > current_screen # > get_pixmap(screen, file) # > screen_depth # > display_widget_tree(widget, spaces) # > add_sound_pane(snd, name, type, *args) # > add_channel_pane(snd, chn, name, type, *args) # > menu_option(name) # > set_main_color_of_widget(w) # > # > add_mark_pane # > # > class Mark_pane # > initialize # > make_list(snd, chn) # > deactivate_channel(snd, chn) # > # > class Variable_display # > initialize(page_name, variable_name) # > inspect # > make_dialog # > create # > close # > reset # > # > class Variable_display_text < Variable_display # > create # > display(var) # > # > class Variable_display_scale < Variable_display # > initialize(page_name, variable_name, range) # > inspect # > create # > display(var) # > # > class Variable_display_graph < Variable_display # > create # > display(var) # > reset # > # > class Variable_display_spectrum < Variable_display # > create # > display(var) # > reset # > # > make_variable_display(page_name, variable_name, type, range) # > variable_display(vd, var) # > variable_display_close(vd) # > variable_display_reset(vd) # > variable_display?(vd) # > # > class Dialog # > add_frame(args) # > add_label(label, args) # > add_textfield(string, label, columns) do |w, c, i| ... end # > add_text(*args) # # class Menu # initialize(name, menu, args) # menu # each_entry do |child| ... end # change_menu_color(new_color) # # class Snd_main_menu < Menu # initialize(name, parent, args) do ... end # menu_number # entry(klass, *rest) or entry(name) do ... end # separator # cascade(name, args) do ... end require "clm" $with_motif = provided?(:snd_motif) $with_gtk = provided?(:snd_gtk) unless $with_motif or $with_gtk Snd.raise(:runtime_error, __FILE__, "--with-motif or --with-gtk required") end if $with_gtk and !provided?(:gtk3) Snd.raise(:runtime_error, __FILE__, "gtk3 required") end # # --- functions working with Motif as well as with Gtk --- # module Snd_XM class SndXError < StandardError end Ruby_exceptions[:snd_x_error] = SndXError Dismiss_string = "Go Away" Help_string = "Help" Okay_string = "DoIt" Reset_string = "Reset" Clear_string = "Clear" # main_widgets Top_level_application = 0 Top_level_shell = 1 Main_pane_shell = 2 Main_sound_pane = 3 Listener_pane = 4 Notebook_outer_pane = 5 # menu_widgets Top_menu_bar = 0 File_menu = 1 Edit_menu = 2 View_menu = 3 Options_menu = 4 Help_menu = 5 # sound_widgets Main_pane = 0 Name_label = 1 Control_panel = 2 Minibuffer = 3 Play = 4 Filter_graph = 5 Unite = 6 Minibuffer_label = 7 Name_icon = 8 Sync = 9 # channel_widgets Graph = 0 W = 1 F = 2 Sx = 3 Sy = 4 Zx = 5 Zy = 6 Edhist = 7 Gsy = 8 Gzy = 9 Channel_main_pane = 10 # dialog_widgets Orientation_dialog = 0 Enved_dialog = 1 Transform_dialog = 2 File_open_dialog = 3 File_save_as_dialog = 4 View_files_dialog = 5 Raw_data_dialog = 6 New_file_dialog = 7 File_mix_dialog = 8 Edit_header_dialog = 9 Find_dialog = 10 Help_dialog = 11 Mix_panel_dialog = 12 Print_dialog = 13 Region_dialog = 14 Info_dialog = 15 Extra_controls_dialog = 16 Save_selection_dialog = 17 Insert_file_dialog = 18 Save_region_dialog = 19 Preferences_dialog = 20 # # old names # Color_dialog = 0 Error_dialog = 0 Yes_or_no_dialog = 0 Completion_dialog = 0 Recorder_dialog = 0 Track_dialog = 0 # MAKE_MENU as well as MAKE_POPUP_MENU may be used in non-Snd # scripts. MAKE_SND_MENU and MAKE_SND_POPUP (see popup.rb) are # specialized using them in Snd. # # [...] # main_widget = RXmCreateMainWindow(top_level, "main", []) # menu_bar = RXmCreateMenuBar(main_widget, "menu-bar", []) # RXtManageChild(menu_bar) # make_menu("file-button", menu_bar) do # entry("quit") do |w, c, i| exit(0) end # end # make_menu("help-button", menu_bar) do # entry("general-help") do |w, c, i| ... end # end def make_menu(name, parent, &body) Main_menu.new(name, parent, [], &body) end # play = lambda do |w, c, i| # @play = Rset(i) # send_values(!@play) # end # make_popup_menu("popup", main_widget) do # entry("play", :widget_class, RxmToggleButtonWidgetClass, &play) # separator # entry("quit") do |w, c, i| exit(0) end # end def make_popup_menu(name, parent, &body) Main_popup_menu.new(name, parent, [], &body) end def make_dialog(label, *rest, &ok_cb) reset_cb, clear_cb, target_cb, help_cb, help_str = optkey(rest, :reset_cb, :clear_cb, :target_cb, :help_cb, :info) unless proc?(help_cb) if string?(help_str) and !help_str.empty? help_cb = lambda do |w, c, i| help_dialog(label, help_str) end end end d = Dialog.new(label, ok_cb, reset_cb, clear_cb, target_cb, help_cb) d.create_dialog d end # simple comment formatter, indents comment text in popup.rb and nb.rb # comment: long comment # text ... # and so on def format_sound_comment(com) if com.empty? com else len = 0 text_length = if widget?(wid = dialog_widgets[Info_dialog]) widget_size(wid).first / 10 else 56 end indent_length = "comment: ".length str = "" format("comment: %s", com).split(/ /).each do |s| unless (len += s.length + 1) < text_length len = indent_length + s.length str << "\n" << " " * indent_length end str << s << " " end str << "\n" end end $semi_range = 24 unless defined? $semi_range $log_scale_ticks = 500 unless defined? $log_scale_ticks Log2 = log(2.0) def scale_log2linear(lo, val, hi) log_lo = log([lo, 1.0].max) / Log2 log_hi = log(hi) / Log2 log_val = log(val) / Log2 $log_scale_ticks.to_f * ((log_val - log_lo) / (log_hi - log_lo)) end def scale_linear2log(lo, val, hi) log_lo = log([lo, 1.0].max) / Log2 log_hi = log(hi) / Log2 log_val = log_lo + ((val / $log_scale_ticks.to_f) * (log_hi - log_lo)) 2.0 ** log_val end def scale_log_label(lo, val, hi) format("%1.2f", scale_linear2log(lo, val, hi)) end def semi_scale_label(val) format("semitones: %d", val - $semi_range) end def semitones2ratio(val) (2.0 ** val) / 12.0 end def ratio2semitones(ratio) (12.0 * (log(ratio) / log(2.0))).round end # get_color("ivory2") # get_color(0.93, 0.93, 0.87) # get_color(Ivory2) # from rgb.rb def get_color(*new_color) if string?(new_color[0]) create_color(new_color[0]) elsif new_color.length == 3 make_color(*new_color) elsif color?(new_color[0]) new_color[0] else make_color(0.0, 0.0, 0.0) end end def yellow_pixel create_color("yellow") end def red_pixel create_color("red") end def update_label(list) if array?(list) and (not widget?(list)) list.each do |prc| prc.call end end end add_help(:find_child, "find_child(widget, name) \ Returns a widget named NAME, \ if one can be found in the widget hierarchy beneath WIDGET.") def find_child(widget, name) res = false each_child(widget) do |child| if widget_name(child) == name # INFO # Wed Nov 17 14:41:50 CET 2010 # "return child" # RETURN seems not to return a value with RUBY_VERSION 1.8.0 res = child return res end end if res res else Snd.raise(:no_such_widget, name) end end def set_label_sensitive(widget, name, set_p = false) wid = Snd.catch(:no_such_widget) do find_child(widget, name) end.first if widget?(wid) set_sensitive(wid, set_p) end end set_property(:show_disk_space, :labelled_snds, []) def labelled_snds property(:show_disk_space, :labelled_snds) end def kmg(num) if num <= 0 "disk full!" else if num > 1024 if num > 1024 * 1024 format("space: %6.3fG", (num / (1024.0 * 1024)).round) else format("space: %6.3fM", (num / 1024.0).round) end else format("space: %10dK", num) end end end end class Dialog_base def initialize(label, ok_cb, reset_cb, clear_cb, target_cb, help_cb) @label = label @ok_cb = ok_cb @reset_cb = reset_cb @clear_cb = clear_cb @target_cb = target_cb @help_cb = help_cb @doit = Okay_string @dismiss = Dismiss_string @help = Help_string @reset = Reset_string @clear = Clear_string @dialog = nil @parent = nil @reset_button = nil @clear_button = nil @okay_button = nil @dismiss_button = nil @help_button = nil end attr_reader :dialog, :parent, :okay_button def doit_string(*args) change_label(@okay_button, @doit = format(*args)) end def dismiss_string(*args) change_label(@dismiss_button, @dismiss = format(*args)) end def help_string(*args) change_label(@help_button, @help = format(*args)) end def reset_string(*args) change_label(@reset_button, @reset = format(*args)) end def clear_string(*args) change_label(@clear_button, @clear = format(*args)) end end # # --- GTK --- # module Snd_Gtk def make_snd_menu(name, args = [], &body) Snd_main_menu.new(name, nil, args, &body) end def create_color(color_string) tmp = RGdkColor() Rgdk_color_parse(color_string, tmp) col = Rgdk_color_copy(tmp) Rgdk_rgb_find_color(Rgdk_colormap_get_system(), col) col end def white_pixel create_color("white") end def black_pixel create_color("black") end def change_label(widget, string) if widget if RGTK_IS_LABEL(widget) Rgtk_label_set_text(RGTK_LABEL(widget), string) else c = Rgtk_bin_get_child(RGTK_BIN(widget)) Rgtk_label_set_text(RGTK_LABEL(c), string) end end end def each_child(widget, &body) if widget?(widget) body.call(widget) Rgtk_container_foreach(RGTK_CONTAINER(widget), lambda do |w, d| body.call(RGTK_WIDGET(w)) end) end end alias for_each_child each_child def widget?(obj) obj.kind_of?(Array) and obj.length == 2 and obj.first == :GtkWidget_ end if defined? Rgtk_widget_get_realized def is_managed?(wid) Rgtk_widget_get_realized(wid) end else alias is_managed? widget? end # you should have set the name before: # Rgtk_widget_set_name(widget, "my-name") def widget_name(wid) Rgtk_widget_get_name(wid) end def set_scale_value(widget, value, scaler = 1.0) Rgtk_adjustment_set_value(RGTK_ADJUSTMENT(widget), value) end def get_scale_value(widget, info, scaler = 1.0) Rgtk_adjustment_get_value(RGTK_ADJUSTMENT(widget)) end def raise_dialog(widget) Rgtk_widget_show(widget) Rgtk_window_present(RGTK_WINDOW(widget)) end def activate_dialog(dialog) Rgtk_widget_show(dialog) raise_dialog(dialog) end def set_sensitive(widget, flag) Rgtk_widget_set_sensitive(widget, flag) end # main_widgets[5] (without -notebook) and # main_widgets[2] # seem to be of kind GTK_BOX [ms] def add_main_pane(name, motif_class_not_needed = nil, *motif_args_not_needed) pane = Rgtk_box_new(RGTK_ORIENTATION_HORIZONTAL, 0) unless RGTK_IS_BOX(parent = main_widgets[Notebook_outer_pane]) parent = main_widgets[Main_pane_shell] end unless RGTK_IS_BOX(parent) Snd.raise(:snd_x_error, "no GTK_BOX widget found") end Rgtk_box_pack_start(RGTK_BOX(parent), pane, false, false, 4) Rgtk_widget_show(pane) Rgtk_widget_set_name(pane, name) pane end def show_disk_space(snd) previous_label = labelled_snds.detect do |n| n.first == snd end unless previous_label name_form = sound_widgets[10] space = kmg(disk_kspace(file_name(snd))) new_label = Rgtk_label_new(space) Rgtk_box_pack_start(RGTK_BOX(name_form), new_label, false, false, 6) Rgtk_widget_show(new_label) previous_label = [snd, new_label] labelled_snds.push(previous_label) end show_label = lambda do |data| if sound?(data.first) space = kmg(disk_kspace(file_name(data.first))) Rgtk_label_set_text(RGTK_LABEL(data[1]), space) Rg_timeout_add(10000, show_label, data) 0 end end Rg_timeout_add(10000, show_label, previous_label) end # $after_open_hook.add_hook!("disk-space", &method(:show_disk_space).to_proc) # body.arity == 3 # lambda do |w, e, d| ... end # cclosure_new "GClosure* g_cclosure_new(GCallback func, # lambda_data func_data, # GClosureNotify destroy_data)" def add_event_handler(parent, event, cb_data = false, &body) t = RG_OBJECT_TYPE(RG_OBJECT(parent)) Rg_signal_connect_closure_by_id(RGPOINTER(parent), Rg_signal_lookup(event, t), 0, Rg_cclosure_new(body, cb_data, false), false) end # body.arity == 2 # lambda do |w, d| ... end def add_callback(parent, event, cb_data = false, &body) Rg_signal_connect(parent, event, body, cb_data) end def g_list_each(glist) Rg_list_length(glist).times do |i| yield(Rg_list_nth_data(glist, i)) end end class Scale_widget include Snd_XM def initialize(parent) @parent = if RGTK_IS_DIALOG(parent) Rgtk_dialog_get_content_area(RGTK_DIALOG(parent)) else parent end @scale = nil end attr_reader :scale def add_scale(title, low, init, high, scale, kind) tbl = Rgtk_grid_new() Rgtk_box_pack_start(RGTK_BOX(@parent), tbl, false, false, 4) Rgtk_widget_show(tbl) @scale = case kind when :log Rgtk_adjustment_new(scale_log2linear(low, init, high), 0, $log_scale_ticks, 1, 10, 1) else Rgtk_adjustment_new(init, low, high, 0.0, 0.0, 0.0) end scl = Rgtk_scale_new(RGTK_ORIENTATION_HORIZONTAL, RGTK_ADJUSTMENT(@scale)) sclscl = RGTK_SCALE(scl) tbltbl = RGTK_GRID(tbl) unless provided?(:GTK3) Rgtk_range_set_update_policy(RGTK_RANGE(sclscl), RGTK_UPDATE_CONTINUOUS) end Rgtk_scale_set_value_pos(sclscl, RGTK_POS_TOP) # expand_fill = RGTK_EXPAND | RGTK_FILL case kind when :log Rgtk_scale_set_digits(sclscl, 0) Rgtk_scale_set_draw_value(sclscl, false) log_lab = Rgtk_label_new("%1.2f" % init) Rgtk_misc_set_alignment(RGTK_MISC(log_lab), 0.0, 0.0) Rgtk_grid_attach(tbltbl, log_lab, 0, 1, 1, 1) Rgtk_widget_show(log_lab) add_callback(@scale, "value_changed") do |w, d| val = Rgtk_adjustment_get_value(RGTK_ADJUSTMENT(@scale)) change_label(log_lab, scale_log_label(low, val, high)) end else Rgtk_scale_set_digits(sclscl, case scale when 1000 3 when 100 2 when 10 1 else 0 end) Rgtk_scale_set_draw_value(sclscl, true) end label = Rgtk_label_new(title) Rgtk_misc_set_alignment(RGTK_MISC(label), 0.0, 0.0) Rgtk_widget_set_hexpand(scl, true) Rgtk_grid_attach(tbltbl, scl, 1, 1, 1, 1) Rgtk_widget_show(scl) Rgtk_grid_attach(tbltbl, label, 1, 1, 1, 1) Rgtk_widget_show(label) Rgtk_widget_set_name(scl, title) end end class Dialog < Dialog_base include Snd_XM def create_dialog @dialog = Rgtk_dialog_new() @dismiss_button = Rgtk_button_new_with_label(@dismiss) @help_button = Rgtk_button_new_with_label(@help) @okay_button = Rgtk_button_new_with_label(@doit) Rgtk_widget_set_name(@dismiss_button, "quit_button") Rgtk_widget_set_name(@help_button, "help_button") Rgtk_widget_set_name(@okay_button, "doit_button") # Rgtk_container_set_border_width(RGTK_CONTAINER(@dialog), 10) window = RGTK_WINDOW(@dialog) Rgtk_window_set_title(window, @label) Rgtk_window_set_default_size(window, -1, -1) Rgtk_window_set_resizable(window, true) # box = RGTK_BOX(Rgtk_dialog_get_action_area(RGTK_DIALOG(@dialog))) add_event_handler(@dialog, "delete_event") do |w, e, d| Rgtk_widget_hide(@dialog) end Rgtk_box_pack_start(box, @dismiss_button, true, true, 20) add_callback(@dismiss_button, "clicked") do |w, d| Rgtk_widget_hide(@dialog) end Rgtk_widget_show(@dismiss_button) # Rgtk_box_pack_start(box, @okay_button, true, true, 20) add_callback(@okay_button, "clicked") do |w, d| @ok_cb.call(w, d, nil) end Rgtk_widget_show(@okay_button) # if @reset_cb @reset_button = Rgtk_button_new_with_label(@reset) Rgtk_widget_set_name(@reset_button, "reset_button") Rgtk_box_pack_start(box, @reset_button, true, true, 20) add_callback(@reset_button, "clicked") do |w, d| @reset_cb.call(w, d, nil) end Rgtk_widget_show(@reset_button) end # if @clear_cb @clear_button = Rgtk_button_new_with_label(@clear) Rgtk_widget_set_name(@clear_button, "clear_button") Rgtk_box_pack_start(box, @clear_button, true, true, 20) add_callback(@clear_button, "clicked") do |w, d| @clear_cb.call(w, d, nil) end Rgtk_widget_show(@clear_button) end Rgtk_box_pack_start(box, @help_button, true, true, 20) # if @help_cb add_callback(@help_button, "clicked") do |w, d| @help_cb.call(w, d, nil) end end Rgtk_widget_show(@help_button) # if @target_cb $effects_hook.add_hook!("create-dialog-target") do | | Rgtk_widget_set_sensitive(@okay_button, @target_cb.call()) end else $effects_hook.add_hook!("create-dialog-target") do | | Rgtk_widget_set_sensitive(@okay_button, (not Snd.sounds.empty?)) end end # Rg_object_set_data(RG_OBJECT(@dialog), "ok-button", RGPOINTER(@okay_button)) @parent = Rgtk_dialog_get_content_area(RGTK_DIALOG(@dialog)) end # kind :log, :linear # returns instance of Scale_widget not widget # so we can access the widget and label if needed # slider = @dialog.add_slider(...) # slider.scale --> widget # slider.label --> label def add_slider(title, low, init, high, scale = 1, kind = :linear, parent = @dialog, &func) slider = Scale_widget.new(parent) slider.add_scale(title, low, init, high, scale, kind) add_callback(slider.scale, "value_changed") do |w, d| func.call(w, d, nil) end slider end # change_cb.arity == 1 def add_toggle(label = "truncate at end", value = true, &change_cb) wid = Rgtk_check_button_new_with_label(label) Rgtk_box_pack_start(RGTK_BOX(@parent), wid, false, false, 4) Rgtk_toggle_button_set_active(RGTK_TOGGLE_BUTTON(wid), value) Rgtk_widget_show(wid) add_callback(wid, "clicked") do |w, d| change_cb.call(Rgtk_toggle_button_get_active(RGTK_TOGGLE_BUTTON(w))) end end def add_target(labels = [["entire sound", :sound, true], ["selection", :selection, false], ["between marks", :marks, false]], &target_cb) rc = Rgtk_box_new(RGTK_ORIENTATION_HORIZONTAL, 0) Rgtk_box_pack_start(RGTK_BOX(@parent), rc, false, false, 4) Rgtk_widget_show(rc) group = false labels.map do |name, type, on| button = Rgtk_radio_button_new_with_label(group, name) group = Rgtk_radio_button_get_group(RGTK_RADIO_BUTTON(button)) Rgtk_box_pack_start(RGTK_BOX(rc), button, false, false, 4) Rgtk_toggle_button_set_active(RGTK_TOGGLE_BUTTON(button), on) Rgtk_widget_show(button) add_callback(button, "clicked") do |w, d| target_cb.call(type) end end end end end # # --- Motif --- # module Snd_Motif def make_snd_menu(name, args = [RXmNbackground, basic_color], &body) Snd_main_menu.new(name, nil, args, &body) end def create_color(color) col = RXColor() dpy = RXtDisplay(main_widgets[Top_level_shell]) c = RXAllocNamedColor(dpy, RDefaultColormap(dpy, RDefaultScreen(dpy)), color, col, col) if c.zero? Snd.raise(:no_such_color, color, "can't allocate") else Rpixel(col) end end def white_pixel RWhitePixelOfScreen(current_screen) end def black_pixel RBlackPixelOfScreen(current_screen) end def change_label(widget, string, property = RXmNlabelString) xs = string2compound(string) RXtSetValues(widget, [property, xs]) RXmStringFree(xs) end add_help(:each_child, "each_child(w, &func) \ Applies FUNC to W and each of its children.") add_help(:for_each_child, "for_each_child(w, &func) \ Applies FUNC to W and each of its children.") def each_child(widget, &body) if RWidget?(widget) body.call(widget) if RXtIsComposite(widget) (get_xtvalue(widget, RXmNchildren) or []).each do |wid| each_child(wid, &body) end end end end alias for_each_child each_child def widget?(obj) RWidget?(obj) end def is_managed?(wid) RXtIsManaged(wid) end def widget_name(wid) RXtName(wid) end def set_scale_value(widget, value, scaler = 1.0) RXmScaleSetValue(widget, (value * Float(scaler)).round) end def get_scale_value(widget, info, scaler = 1.0) Rvalue(info) / Float(scaler) end def raise_dialog(widget) if RWidget?(widget) and RXtIsManaged(widget) parent = RXtParent(widget) if RWidget?(parent) and RXtIsSubclass(parent, RxmDialogShellWidgetClass) RXtPopup(parent, RXtGrabNone) end end end def activate_dialog(dialog) RXtIsManaged(dialog) ? raise_dialog(dialog) : RXtManageChild(dialog) end def set_sensitive(widget, flag) RXtSetSensitive(widget, flag) end def add_main_pane(name, type, *args) w = main_widgets[Notebook_outer_pane] or main_widgets[Main_sound_pane] RXtCreateManagedWidget(name, type, w, *args) end def add_sound_pane(snd, name, type, *args) RXtCreateManagedWidget(name, type, sound_widgets(snd)[Main_pane], *args) end def add_channel_pane(snd, chn, name, type, *args) xp = RXtParent(RXtParent(channel_widgets(snd, chn)[Edhist])) RXtCreateManagedWidget(name, type, xp, *args) end # string must be freed def string2compound(*args) args[0] = String(args[0]) RXmStringCreateLocalized(format(*args)) end def compound2string(xstr) RXmStringUnparse(xstr, false, RXmCHARSET_TEXT, RXmCHARSET_TEXT, false, 0, RXmOUTPUT_ALL) end def get_xtvalue(widget, item) RXtVaGetValues(widget, [item, 0])[1] end def current_label(widget) compound2string(get_xtvalue(widget, RXmNlabelString)) end add_help(:current_screen, "current_screen() \ Returns the current X screen number of the current display.") def current_screen RDefaultScreenOfDisplay(RXtDisplay(main_widgets[Top_level_shell])) end def get_pixmap(screen, file) pix = RXmGetPixmap(screen, file, RBlackPixelOfScreen(screen), RWhitePixelOfScreen(screen)) if pix == RXmUNSPECIFIED_PIXMAP Snd.raise(:snd_x_error, pix, "can't create pixmap") else pix end end def screen_depth RDefaultDepthOfScreen(current_screen) end add_help(:display_widget_tree, "display_widget_tree(widget, spaces=\"\") \ Displays the hierarchy of widgets beneath WIDGET." ) def display_widget_tree(widget, spaces = "") if (name = RXtName(widget)).null? name = "" end Snd.display("%s%s", spaces, name) if RXtIsComposite(widget) (get_xtvalue(widget, RXmNchildren) or []).each do |w| display_widget_tree(w, spaces + " ") end end end add_help(:show_disk_space, "show_disk_space(snd) \ Adds a label to the minibuffer area showing \ the current free space (for use with $after_open_hook).") def show_disk_space(snd) previous_label = labelled_snds.detect do |n| n.first == snd end unless previous_label app = main_widgets[Top_level_application] minibuffer = sound_widgets(snd)[Minibuffer] name_form = RXtParent(minibuffer) space = kmg(disk_kspace(file_name(snd))) str = RXmStringCreateLocalized(space) new_label = RXtCreateManagedWidget("space:", RxmLabelWidgetClass, name_form, [RXmNbackground, basic_color, RXmNleftAttachment, RXmATTACH_WIDGET, RXmNleftWidget, minibuffer, RXmNlabelString, str, RXmNrightAttachment, RXmATTACH_NONE, RXmNtopAttachment, RXmATTACH_FORM]) RXmStringFree(str) previous_label = [snd, new_label, app] labelled_snds.push(previous_label) end show_label = lambda do |data, id| if sound?(data.first) space = kmg(disk_kspace(file_name(data.first))) str = RXmStringCreateLocalized(space) RXtSetValues(data[1], [RXmNlabelString, str]) RXmStringFree(str) RXtAppAddTimeOut(data[2], 10000, show_label, data) end end RXtAppAddTimeOut(previous_label[2], 10000, show_label, previous_label) end # $after_open_hook.add_hook!("disk-space", &method(:show_disk_space).to_proc) add_help(:menu_option, "menu_option(name) \ Finds the widget associated with a given menu item NAME.") def menu_option(name) menu_widgets.cdr.each do |top_menu| each_child(top_menu) do |w| option_holder = RXtGetValues(w, [RXmNsubMenuId, 0]).cadr each_child(option_holder) do |menu| if name == RXtName(menu) return menu else if RXmIsCascadeButton(menu) options = RXtGetValues(menu, [RXmNsubMenuId, 0]).cadr each_child(options) do |inner_menu| if name == RXtName(inner_menu) return inner_menu end end end end end end end Snd.raise(:no_such_menu, name) end add_help(:set_main_color_of_widget, "set_main_color_of_widget(widget) \ Sets the background color of WIDGET.") def set_main_color_of_widget(w) each_child(w) do |n| if RXtIsWidget(n) if RXmIsScrollBar(n) RXmChangeColor(n, position_color) else RXmChangeColor(n, basic_color) end end end end # # add_mark_pane # # Adds a pane to each channel giving the current mark locations # (sample values). These can be edited to move the mark, or deleted # to delete the mark. Can't use channel-property here because the # widget lists are permanent (just unmanaged) $including_mark_pane = false # for prefs def add_mark_pane mark_pane = Mark_pane.new $mark_hook.add_hook!("remark") do |id, snd, chn, reason| mark_pane.make_list(snd, chn) end $close_hook.add_hook!("unremark") do |snd| channels(snd).times do |chn| mark_pane.deactivate_channel(snd, chn) end end $after_open_hook.add_hook!("open-remarks") do |snd| chans(snd).times do |chn| after_edit_hook(snd, chn).add_hook!("open-remarks") do | | if RWidget?(mark_pane.list(snd, chn)) mark_pane.make_list(snd, chn) end end undo_hook(snd, chn).add_hook!("open-remarks") do | | if RWidget?(mark_pane.list(snd, chn)) mark_pane.make_list(snd, chn) end end end end $update_hook.add_hook!("") do |snd| lambda do |update_snd| chans(update_snd).times do |chn| mark_pane.make_list(update_snd, chn) end end end $including_mark_pane = true end class Mark_pane def initialize @mark_list_lengths = [] @mark_lists = [] end def make_list(snd, chn) deactivate_channel(snd, chn) unless RWidget?(list(snd, chn)) mark_box = add_channel_pane(snd, chn, "mark-box", RxmFormWidgetClass, [RXmNbackground, basic_color, RXmNorientation, RXmVERTICAL, RXmNpaneMinimum, 100, RXmNbottomAttachment, RXmATTACH_FORM]) ls = [RXmNbackground, highlight_color, RXmNleftAttachment, RXmATTACH_FORM, RXmNrightAttachment, RXmATTACH_FORM, RXmNalignment, RXmALIGNMENT_CENTER, RXmNtopAttachment, RXmATTACH_FORM] mark_label = RXtCreateManagedWidget("Marks", RxmLabelWidgetClass, mark_box, ls) ls = [RXmNbackground, basic_color, RXmNscrollingPolicy, RXmAUTOMATIC, RXmNscrollBarDisplayPolicy, RXmSTATIC, RXmNleftAttachment, RXmATTACH_FORM, RXmNrightAttachment, RXmATTACH_FORM, RXmNtopAttachment, RXmATTACH_WIDGET, RXmNtopWidget, mark_label, RXmNbottomAttachment, RXmATTACH_FORM] mark_scr = RXtCreateManagedWidget("mark-scr", RxmScrolledWindowWidgetClass, mark_box, ls) ls = [RXmNorientation, RXmVERTICAL, RXmNtopAttachment, RXmATTACH_FORM, RXmNbottomAttachment, RXmATTACH_FORM, RXmNspacing, 0] mlist = RXtCreateManagedWidget("mark-list", RxmRowColumnWidgetClass, mark_scr, ls) set_main_color_of_widget(mark_scr) RXtSetValues(mark_box, [RXmNpaneMinimum, 1]) set_list(snd, chn, mlist) end lst = list(snd, chn) new_marks = Snd.marks(snd, chn) current_list_length = @mark_list_lengths.length if new_marks.length > current_list_length current_list_length.upto(new_marks.length) do tf = RXtCreateWidget("field", RxmTextFieldWidgetClass, lst, [RXmNbackground, basic_color]) RXtAddCallback(tf, RXmNfocusCallback, lambda do |w, c, i| RXtSetValues(w, [RXmNbackground, text_focus_color]) end) RXtAddCallback(tf, RXmNlosingFocusCallback, lambda do |w, c, i| RXtSetValues(w, [RXmNbackground, basic_color]) end) RXtAddCallback(tf, RXmNactivateCallback, lambda do |w, c, i| id = RXtGetValues(w, [RXmNuserData, 0]).cadr txt = RXtGetValues(w, [RXmNvalue, 0]).cadr if string?(txt) and txt.length > 0 set_mark_sample(id, txt.to_i) else delete_mark(id) end RXtSetValues(w, [RXmNbackground, basic_color]) end) RXtAddEventHandler(tf, REnterWindowMask, false, lambda do |w, c, i, f| $mouse_enter_text_hook.call(w) end) RXtAddEventHandler(tf, RLeaveWindowMask, false, lambda do |w, c, i, f| $mouse_leave_text_hook.call(w) end) end end set_length(snd, chn, new_marks.length) RXtGetValues(lst, [RXmNchildren, 0], 1).cadr.each do |n| break if new_marks.empty? if RXmIsTextField(n) mk = new_marks.shift RXtSetValues(n, [RXmNvalue, mark_sample(mk).to_s, RXmNuserData, mk]) RXtManageChild(n) end end false end def deactivate_channel(snd, chn) if length(snd, chn) > 0 and RWidget?(list(snd, chn)) RXtGetValues(list(snd, chn), [RXmNchildren, 0], 1).cadr.each do |n| RXtUnmanageChild(n) end end end def list(snd, chn) find(snd, chn, @mark_lists) end private def find(snd, chn, dats) val = dats.detect do |dat| snd == dat.car and chn == dat.cadr end if val val.caddr else false end end def length(snd, chn) find(snd, chn, @mark_list_lengths) or 0 end def set_length(snd, chn, len) @mark_list_lengths.delete_if do |dat| snd == dat.car and chn == dat.cadr end @mark_list_lengths.push([snd, chn, len]) end def set_list(snd, chn, wid) @mark_lists.push([snd, chn, wid]) end end class Variable_display include Snd_XM def initialize(page_name, variable_name) @name = page_name @variable = variable_name @@dialog = nil unless defined? @@dialog @@pages = {} unless defined? @@pages @@notebook = nil unless defined? @@notebook @widget = nil @snd = false @data = nil @default_background = nil create end attr_reader :snd, :data def dialog_widget @@dialog end def inspect format("%s.new(%s, %s)", self.class, @name, @variable) end def make_dialog xdismiss = RXmStringCreateLocalized("Dismiss") titlestr = RXmStringCreateLocalized("Variables") @@dialog = RXmCreateTemplateDialog(main_widgets[Top_level_shell], "variables-dialog", [RXmNokLabelString, xdismiss, RXmNautoUnmanage, false, RXmNdialogTitle, titlestr, RXmNresizePolicy, RXmRESIZE_GROW, RXmNnoResize, false, RXmNtransient, false, RXmNheight, 400, RXmNwidth, 400, RXmNbackground, basic_color]) RXtAddCallback(@@dialog, RXmNokCallback, lambda do |w, c, i| RXtUnmanageChild(@@dialog) end) RXmStringFree(xdismiss) RXmStringFree(titlestr) ls = [RXmNleftAttachment, RXmATTACH_FORM, RXmNrightAttachment, RXmATTACH_FORM, RXmNtopAttachment, RXmATTACH_FORM, RXmNbottomAttachment, RXmATTACH_WIDGET, RXmNbottomWidget, RXmMessageBoxGetChild(@@dialog, RXmDIALOG_SEPARATOR), RXmNbackground, basic_color, RXmNframeBackground, zoom_color, RXmNbindingWidth, 14] @@notebook = RXtCreateManagedWidget("variables-notebook", RxmNotebookWidgetClass, @@dialog, ls) RXtManageChild(@@dialog) c = RDefaultScreenOfDisplay(RXtDisplay(@@dialog)) @default_background = RWhitePixelOfScreen(c) end def create unless RWidget?(@@dialog) make_dialog end unless @@pages[@name] panes = RXtCreateManagedWidget(@name, RxmPanedWindowWidgetClass, @@notebook, []) simple_cases = RXtCreateManagedWidget(@name, RxmRowColumnWidgetClass, panes, [RXmNorientation, RXmVERTICAL, RXmNpaneMinimum, 30, RXmNbackground, basic_color]) RXtCreateManagedWidget(@name, RxmPushButtonWidgetClass, @@notebook, [RXmNnotebookChildType, RXmMAJOR_TAB, RXmNbackground, basic_color]) @@pages[@name] = [@name, panes, simple_cases] end @@pages[@name] end def close RXtUnmanageChild(@@dialog) end def reset end end class Variable_display_text < Variable_display def create page_info = super row_pane = page_info[2] var_label = @variable + ":" row = RXtCreateManagedWidget(@variable + "-row", RxmRowColumnWidgetClass, row_pane, [RXmNorientation, RXmHORIZONTAL, RXmNbackground, basic_color]) RXtCreateManagedWidget(var_label, RxmLabelWidgetClass, row, [RXmNbackground, basic_color]) @widget = RXtCreateManagedWidget(@variable + "-value", RxmTextFieldWidgetClass, row, [RXmNeditable, false, RXmNresizeWidth, true, RXmNbackground, @default_background]) end def display(var) old_str = RXmTextFieldGetString(@widget) new_str = var.to_s if old_str != new_str RXmTextFieldSetString(@widget, new_str) if RXtIsManaged(@widget) RXmUpdateDisplay(@widget) end end var end end class Variable_display_scale < Variable_display def initialize(page_name, variable_name, range = [0.0, 1.0]) @range = range super(page_name, variable_name) end def inspect format("%s.new(%s, %s, %s)", self.class, @name, @variable, @range) end def create page_info = super() row_pane = page_info[2] var_label = @variable + ":" title = RXmStringCreateLocalized(var_label) @widget = RXtCreateManagedWidget(@variable, RxmScaleWidgetClass, row_pane, [RXmNbackground, basic_color, RXmNslidingMode, RXmTHERMOMETER, RXmNminimum, (100.0 * @range[0]).floor, RXmNmaximum, (100.0 * @range[1]).floor, RXmNdecimalPoints, 2, RXmNtitleString, title, RXmNorientation, RXmHORIZONTAL, RXmNshowValue, RXmNEAR_BORDER]) wid = Snd.catch(:no_such_widget) do find_child(@widget, "Scrollbar") end.first if widget?(wid) RXtVaSetValues(wid, [RXmNtroughColor, red_pixel]) end RXmStringFree(title) end def display(var) RXmScaleSetValue(@widget, (100.0 * var).floor) var end end class Variable_display_graph < Variable_display def create page_info = super pane = page_info[1] var_label = @variable + ":" form = RXtCreateManagedWidget(var_label, RxmFormWidgetClass, pane, [RXmNpaneMinimum, 100]) @snd = make_variable_graph(form, @variable + ": time", 2048, mus_srate.to_i) @data = channel_data(@snd, 0) end def display(var) frames = @data.length loc = cursor(snd, 0) @data[loc] = var if time_graph?(@snd) update_time_graph(@snd) end if transform_graph?(@snd) update_transform_graph(@snd) end if loc + 1 == frames set_cursor(0, @snd, 0) else set_cursor(loc + 1, @snd, 0) end var end def reset set_cursor(0, @snd, 0) @data.fill(0.0) end end class Variable_display_spectrum < Variable_display def create page_info = super pane = page_info[1] var_label = @variable + ":" form = RXtCreateManagedWidget(var_label, RxmFormWidgetClass, pane, [RXmNpaneMinimum, 100]) @snd = make_variable_graph(form, @variable, 2048, mus_srate.to_i) set_time_graph?(false, @snd, 0) set_transform_graph?(true, @snd, 0) set_x_axis_label(@variable + ": frequency", @snd, 0, Transform_graph) @data = channel_data(@snd, 0) end def display(var) frames = @data.length loc = cursor(snd, 0) @data[loc] = var if time_graph?(@snd) update_time_graph(@snd) end if transform_graph?(@snd) update_transform_graph(@snd) end if loc + 1 == frames set_cursor(0, @snd, 0) else set_cursor(loc + 1, @snd, 0) end var end def reset set_cursor(0, @snd, 0) @data.fill(0.0) end end def make_variable_display(page_name, variable_name, type = :text, range = [0.0, 1.0]) case type when :text Variable_display_text.new(page_name, variable_name) when :scale Variable_display_scale.new(page_name, variable_name, range) when :graph Variable_display_graph.new(page_name, variable_name) when :spectrum Variable_display_spectrum.new(page_name, variable_name) else nil end end def variable_display(vd, var) vd.display(var) end def variable_display_close(vd) vd.close end def variable_display_reset(vd) vd.reset end def variable_display?(vd) vd.kind_of?(Variable_display) end class Scale_widget include Snd_XM def initialize(parent) @parent = parent @scale = nil @label = nil end attr_reader :scale, :label def add_scale(title, low, init, high, scale, kind) xtitle = string2compound(title) rc = RXtCreateManagedWidget("rc", RxmRowColumnWidgetClass, @parent, [RXmNorientation, RXmVERTICAL, RXmNbackground, highlight_color]) case kind when :log s = format("%1.2f", init), @label = RXtCreateManagedWidget(s, RxmLabelWidgetClass, rc, [RXmNalignment, RXmALIGNMENT_BEGINNING, RXmNbackground, basic_color]) @scale = general_scale(rc, title, xtitle) RXtVaSetValues(@scale, [RXmNmaximum, $log_scale_ticks, RXmNvalue, scale_log2linear(low, init, high).round]) RXtAddCallback(@scale, RXmNvalueChangedCallback, lambda do |w, c, i| change_label(@label, scale_log_label(low, Rvalue(i), high)) end) RXtAddCallback(@scale, RXmNdragCallback, lambda do |w, c, i| change_label(@label, scale_log_label(low, Rvalue(i), high)) end) when :semi s = format("semitones: %d", ratio2semitones(init)) @label = RXtCreateManagedWidget(s, RxmLabelWidgetClass, rc, [RXmNalignment, RXmALIGNMENT_BEGINNING, RXmNbackground, basic_color]) @scale = general_scale(rc, title, xtitle) RXtVaSetValues(@scale, [RXmNmaximum, 2 * $semi_range, RXmNvalue, $semi_range + ratio2semitones(init)]) RXtAddCallback(@scale, RXmNvalueChangedCallback, lambda do |w, c, i| change_label(@label, semi_scale_label(Rvalue(i))) end) RXtAddCallback(@scale, RXmNdragCallback, lambda do |w, c, i| change_label(@label, semi_scale_label(Rvalue(i))) end) else @scale = linear_scale(rc, title, xtitle, low, init, high, scale) end RXmStringFree(xtitle) end private def linear_scale(parent, title, xtitle, low, init, high, scale) RXtCreateManagedWidget(title, RxmScaleWidgetClass, parent, [RXmNorientation, RXmHORIZONTAL, RXmNshowValue, true, RXmNminimum, (low * scale).round, RXmNmaximum, (high * scale).round, RXmNtitleString, xtitle, RXmNbackground, basic_color, RXmNvalue, (init * scale).round, RXmNdecimalPoints, case scale when 1000 3 when 100 2 when 10 1 else 0 end]) end def general_scale(parent, title, xtitle) RXtCreateManagedWidget(title, RxmScaleWidgetClass, parent, [RXmNorientation, RXmHORIZONTAL, RXmNshowValue, false, RXmNminimum, 0, RXmNdecimalPoints, 0, RXmNtitleString, xtitle, RXmNbackground, basic_color]) end end class Dialog < Dialog_base include Snd_XM def create_dialog xdismiss = RXmStringCreateLocalized(@dismiss) xhelp = RXmStringCreateLocalized(@help) xok = RXmStringCreateLocalized(@doit) titlestr = RXmStringCreateLocalized(@label) @dialog = RXmCreateTemplateDialog(main_widgets[Top_level_shell], @label, [RXmNcancelLabelString, xdismiss, RXmNhelpLabelString, xhelp, RXmNokLabelString, xok, RXmNautoUnmanage, false, RXmNdialogTitle, titlestr, RXmNresizePolicy, RXmRESIZE_GROW, RXmNnoResize, false, RXmNbackground, basic_color, RXmNtransient, false]) RXmStringFree(xhelp) RXmStringFree(xok) RXmStringFree(xdismiss) RXmStringFree(titlestr) if defined?(R_XEditResCheckMessages()) RXtAddEventHandler(RXtParent(@dialog), 0, true, lambda do |w, c, i, f| R_XEditResCheckMessages(w, c, i, f) end) end [[RXmDIALOG_HELP_BUTTON, highlight_color], [RXmDIALOG_CANCEL_BUTTON, highlight_color], [RXmDIALOG_OK_BUTTON, highlight_color]].each do |button, color| RXtVaSetValues(RXmMessageBoxGetChild(@dialog, button), [RXmNarmColor, selection_color, RXmNbackground, color]) end RXtAddCallback(@dialog, RXmNcancelCallback, lambda do |w, c, i| RXtUnmanageChild(@dialog) end) RXtAddCallback(@dialog, RXmNhelpCallback, lambda do |w, c, i| @help_cb.call(w, c, i) end) RXtAddCallback(@dialog, RXmNokCallback, lambda do |w, c, i| @ok_cb.call(w, c, i) end) vals = [RXmNbackground, highlight_color, RXmNforeground, black_pixel, RXmNarmColor, selection_color] if @clear_cb @clear_button = RXtCreateManagedWidget(@clear, RxmPushButtonWidgetClass, @dialog, vals) RXtAddCallback(@clear_button, RXmNactivateCallback, lambda do |w, c, i| @clear_cb.call(w, c, i) end) end if @reset_cb @reset_button = RXtCreateManagedWidget(@reset, RxmPushButtonWidgetClass, @dialog, vals) RXtAddCallback(@reset_button, RXmNactivateCallback, lambda do |w, c, i| @reset_cb.call(w, c, i) end) end @help_button = RXmMessageBoxGetChild(@dialog, RXmDIALOG_HELP_BUTTON) @dismiss_button = RXmMessageBoxGetChild(@dialog, RXmDIALOG_CANCEL_BUTTON) @okay_button = RXmMessageBoxGetChild(@dialog, RXmDIALOG_OK_BUTTON) if @target_cb RXtSetSensitive(@okay_button, @target_cb.call()) $effects_hook.add_hook!("create-dialog-target") do | | RXtSetSensitive(@okay_button, @target_cb.call()) end else RXtSetSensitive(@okay_button, (not Snd.sounds.empty?)) $effects_hook.add_hook!("create-dialog-target") do | | RXtSetSensitive(@okay_button, (not Snd.sounds.empty?)) end end @parent = RXtCreateManagedWidget("pane", RxmPanedWindowWidgetClass, @dialog, [RXmNsashHeight, 1, RXmNsashWidth, 1, RXmNbackground, basic_color, RXmNseparatorOn, true, RXmNalignment, RXmALIGNMENT_BEGINNING, RXmNorientation, RXmVERTICAL]) end # kind :log, :semi, :linear # returns instance of Scale_widget not widget # so we can access the widget and label if needed # slider = @dialog.add_slider(...) # slider.scale --> widget # slider.label --> label def add_slider(title, low, init, high, scale = 1, kind = :linear, parent = @parent, &func) slider = Scale_widget.new(parent) slider.add_scale(title, low, init, high, scale, kind) unless proc?(func) and func.arity == 3 func = lambda do |w, c, i| func.call end end RXtAddCallback(slider.scale, RXmNvalueChangedCallback, func) slider end # change_cb.arity == 1 def add_toggle(label = "truncate at end", value = true, &change_cb) button = RXtCreateManagedWidget(label, RxmToggleButtonWidgetClass, @parent, [RXmNbackground, basic_color, RXmNalignment, RXmALIGNMENT_BEGINNING, RXmNset, value, RXmNselectColor, yellow_pixel]) RXtAddCallback(button, RXmNvalueChangedCallback, lambda do |w, c, i| change_cb.call(Rset(i)) end) h = get_xtvalue(button, RXmNheight) h += (h * 0.1).round RXtVaSetValues(button, [RXmNpaneMinimum, h, RXmNpaneMaximum, h]) button end # target_cb.arity == 1 def add_target(labels = [["entire sound", :sound, true], ["selection", :selection, false], ["between marks", :marks, false]], &target_cb) RXtCreateManagedWidget("sep", RxmSeparatorWidgetClass, @parent, [RXmNorientation, RXmHORIZONTAL, RXmNseparatorType, RXmSHADOW_ETCHED_OUT, RXmNbackground, basic_color]) ls = [RXmNorientation, RXmHORIZONTAL, RXmNbackground, basic_color, RXmNradioBehavior, true, RXmNradioAlwaysOne, true, RXmNbottomAttachment, RXmATTACH_FORM, RXmNleftAttachment, RXmATTACH_FORM, RXmNrightAttachment, RXmATTACH_FORM, RXmNentryClass, RxmToggleButtonWidgetClass, RXmNisHomogeneous, true] rc = RXtCreateManagedWidget("rc", RxmRowColumnWidgetClass, @parent, ls) labels.map do |name, type, on| RXtCreateManagedWidget(name, RxmToggleButtonWidgetClass, rc, [RXmNbackground, basic_color, RXmNselectColor, yellow_pixel, RXmNset, on, RXmNindicatorType, RXmONE_OF_MANY_ROUND, RXmNarmCallback, [lambda do |w, c, i| target_cb.call(type) end, false]]) end rc end def add_frame(args = []) RXtCreateManagedWidget("frame", RxmFrameWidgetClass, @parent, args) # [RXmNshadowThickness, 4, RXmNshadowType, RXmSHADOW_ETCHED_OUT] end def add_label(label, args = []) RXtCreateManagedWidget(label, RxmLabelWidgetClass, @parent, [RXmNalignment, RXmALIGNMENT_BEGINNING, RXmNbackground, basic_color] + args) end def add_textfield(string, label = nil, columns = 80, &activate_cb) rc = RXtCreateManagedWidget("rc", RxmRowColumnWidgetClass, @parent, [RXmNorientation, RXmVERTICAL, RXmNbackground, basic_color]) if string?(label) RXtCreateManagedWidget(label, RxmLabelWidgetClass, rc, [RXmNalignment, RXmALIGNMENT_BEGINNING, RXmNbackground, basic_color]) end text_field = RXtCreateManagedWidget("text", RxmTextFieldWidgetClass, rc, [RXmNvalue, string, RXmNresizeWidth, false, RXmNcolumns, columns, RXmNbackground, basic_color]) RXtAddCallback(text_field, RXmNactivateCallback, activate_cb) RXtAddCallback(text_field, RXmNfocusCallback, lambda do |w, c, i| RXtSetValues(w, [RXmNbackground, text_focus_color]) end) RXtAddCallback(text_field, RXmNlosingFocusCallback, lambda do |w, c, i| RXtSetValues(w, [RXmNbackground, basic_color]) end) RXtAddEventHandler(text_field, REnterWindowMask, false, lambda do |w, c, i, f| $mouse_enter_text_hook.call(w) end) RXtAddEventHandler(text_field, RLeaveWindowMask, false, lambda do |w, c, i, f| $mouse_leave_text_hook.call(w) end) text_field end def add_text(*args) rows, columns, wordwrap, value, horizontal = optkey(args, [:rows, 16], [:columns, 60], [:wordwrap, true], [:value, ""], [:scroll_horizontal, false]) text = RXmCreateScrolledText(@parent, "text", [RXmNtopAttachment, RXmATTACH_WIDGET, RXmNeditMode, RXmMULTI_LINE_EDIT, RXmNrows, rows, RXmNcolumns, columns, RXmNwordWrap, wordwrap, RXmNscrollHorizontal, horizontal, RXmNvalue, value, RXmNbackground, basic_color]) RXtAddCallback(text, RXmNfocusCallback, lambda do |w, c, i| RXtSetValues(w, [RXmNbackground, text_focus_color]) end) RXtAddCallback(text, RXmNlosingFocusCallback, lambda do |w, c, i| RXtSetValues(w, [RXmNbackground, basic_color]) end) RXtAddEventHandler(text, REnterWindowMask, false, lambda do |w, c, i, f| $mouse_enter_text_hook.call(w) end) RXtAddEventHandler(text, RLeaveWindowMask, false, lambda do |w, c, i, f| $mouse_leave_text_hook.call(w) end) RXtManageChild(text) text end end end module Snd_XM if $with_motif include Snd_Motif elsif $with_gtk include Snd_Gtk else Snd.raise(:snd_x_error, "neither Motif nor Gtk?") end alias is_managed is_managed? end =begin add_channel_pane(0, 0, "new-pane", RxmDrawingAreaWidgetClass, [RXmNbackground, graph_color, RXmNforeground, data_color]) =end # SND_MAIN_MENU (for a similar popup menu class see popup.rb) # # make_snd_menu(name, args) do ... end # # class Menu # initialize(name, menu, args) # menu # each_entry do |child| ... end # change_menu_color(new_color) # # class Snd_main_menu < Menu # initialize(name, parent, args) do ... end # menu_number # entry(klass, *rest) or entry(name) do ... end # separator # cascade(name, args) do ... end # # `Snd_main_menu#entry(arg, *rest, &body)': If ARG is of kind Class, # `entry' calls klass.new(*rest), so you can set initialize values # (e.g. the label or other args). If ARG is not of kind Class it is # taken as a label string and a block must exist. Classes for the # menu must have a method `post_dialog' and `inspect'. `inspect' # shows the values in the menu label. See the various examples in # effects.rb. # # class Foo # def initialize(label, val1, val2) # @label = label # @val1 = val1 # @val2 = val2 # @dialog = nil # ... # end # # def inspect # format("%s (%.3f %.3f", @label, @val1, @val2) # end # # def post_dialog # ... # unless @dialog.kind_of?(Dialog) and RWidget?(@dialog.dialog) # ... # @dialog = make_dialog(@label, # :info, "Help text", # :reset_cb, lambda do |w, c, i| # ... (reset your values) # end) do |w, c, i| # ... (main action) # end # ... # end # activate_dialog(@dialog.dialog) # end # end # # make_snd_menu("Foo Menu") do # entry(Foo, 3.14, 0.0) # end =begin # example menu using Effects (see effects.rb and new-effects.scm) require "effects" make_snd_menu("Effects") do cascade("Amplitude Effects") do entry(Gain, "Gain") entry(Normalize, "Normalize") entry(Gate, "Gate") end cascade("Delay Effects") do entry(Echo, "Echo") entry(Filtered_echo, "Filtered echo") entry(Modulated_echo, "Modulated echo") end separator entry("Octave-down") do down_oct end entry("Remove DC") do lastx = lasty = 0.0 map_chan(lambda do |inval| lasty = inval + (0.999 * lasty - lastx) lastx = inval lasty end) end entry("Spiker") do spike end end =end class Menu include Snd_XM def initialize(name, menu, args) @label = name @menu = menu @args = args end attr_reader :menu def inspect format("#<%s: label: %p, menu: %p, args: %p>", self.class, @label, @menu, @args) end def entry(name, *rest, &body) child = false if $with_motif args, widget_class = optkey(rest, [:args, @args], [:widget_class, RxmPushButtonWidgetClass]) child = RXtCreateManagedWidget(name, widget_class, @menu, args) case widget_class when RxmPushButtonWidgetClass RXtAddCallback(child, RXmNactivateCallback, body) when RxmToggleButtonWidgetClass RXtAddCallback(child, RXmNvalueChangedCallback, body) end else child = Rgtk_menu_item_new_with_label(name) Rgtk_menu_shell_append(RGTK_MENU_SHELL(@menu), child) Rgtk_widget_show(child) add_callback(child, "activate") do |w, d| body.call(w, d, nil) end end child end def label(name, args = @args) label = false if $with_motif label = RXtCreateManagedWidget(name, RxmLabelWidgetClass, @menu, args) else label = Rgtk_menu_item_new_with_label(name) Rgtk_menu_shell_append(RGTK_MENU_SHELL(@menu), label) Rgtk_widget_show(label) end label end def separator(single = :single) if $with_motif line = (single == :double ? RXmDOUBLE_LINE : RXmSINGLE_LINE) RXtCreateManagedWidget("s", RxmSeparatorWidgetClass, @menu, [RXmNseparatorType, line]) else sep = Rgtk_menu_item_new() Rgtk_menu_shell_append(RGTK_MENU_SHELL(@menu), sep) Rgtk_widget_show(sep) end end def each_entry(&body) each_child(@menu, &body) end # $menu.change_menu_color("ivory2") # $menu.change_menu_color([0.93, 0.93, 0.87]) # require 'rgb' # $menu.change_menu_color(Ivory2) def change_menu_color(new_color) color_pixel = get_color(new_color) if $with_motif each_child(@menu) do |child| RXmChangeColor(child, color_pixel) end else each_child(@menu) do |child| Rgtk_widget_modify_bg(child, RGTK_STATE_NORMAL, color_pixel) end end end end class Snd_main_menu < Menu def initialize(name, parent, args, &body) if widget? parent @menu_number = -1 super(name, parent, args) else @menu_number = add_to_main_menu(name, lambda do | | end) super(name, main_menu(@menu_number), args) instance_eval(&body) if block_given? end end attr_reader :menu_number def entry(arg, *rest, &body) if arg.class == Class menu = arg.new(*rest) if menu.respond_to?(:post_dialog) if $with_motif child = RXtCreateManagedWidget(rest[0].to_s, RxmPushButtonWidgetClass, @menu, @args) RXtAddCallback(child, RXmNactivateCallback, lambda do |w, c, i| menu.post_dialog end) else child = Rgtk_menu_item_new_with_label(rest[0].to_s) Rgtk_menu_shell_append(RGTK_MENU_SHELL(@menu), child) Rgtk_widget_show(child) add_callback(child, "activate") do |w, d| menu.post_dialog end end child else Snd.raise(:snd_x_error, arg.class, "class does not respond to `post_dialog'") end else if block_given? add_to_menu(@menu_number, arg, body) else Snd.raise(:wrong_number_of_args, "no block given") end end end def separator add_to_menu(@menu_number, false, false) end def cascade(name, args = @args, &body) cas = Cascade.new(name, @menu, args) cas.instance_eval(&body) if block_given? cas end class Cascade < Snd_main_menu def initialize(name, parent, args) super @children = [] if $with_motif @menu = RXmCreatePulldownMenu(parent, @label, @args) cascade = RXtCreateManagedWidget(@label, RxmCascadeButtonWidgetClass, parent, [RXmNsubMenuId, @menu] + @args) RXtAddCallback(cascade, RXmNcascadingCallback, lambda do |w, c, i| update_label(@children) end) else cascade = Rgtk_menu_item_new_with_label(@label) s = RGTK_MENU_SHELL(Rgtk_menu_item_get_submenu(RGTK_MENU_ITEM(parent))) Rgtk_menu_shell_append(s, cascade) Rgtk_widget_show(cascade) @menu = Rgtk_menu_new() Rgtk_menu_item_set_submenu(RGTK_MENU_ITEM(cascade), @menu) add_callback(cascade, "activate") do |w, d| update_label(@children) end end end def entry(arg, *rest, &body) child = false if arg.class == Class menu = arg.new(*rest) if menu.respond_to?(:post_dialog) if $with_motif child = RXtCreateManagedWidget(rest[0].to_s, RxmPushButtonWidgetClass, @menu, @args) RXtAddCallback(child, RXmNactivateCallback, lambda do |w, c, i| menu.post_dialog end) else child = Rgtk_menu_item_new_with_label(rest[0].to_s) Rgtk_menu_shell_append(RGTK_MENU_SHELL(@menu), child) Rgtk_widget_show(child) add_callback(child, "activate") do |w, d| menu.post_dialog end end @children.push(lambda do | | change_label(child, menu.inspect) end) else Snd.raise(:snd_x_error, arg.class, "class does not respond to `post_dialog'") end else if block_given? if $with_motif child = RXtCreateManagedWidget(arg.to_s, RxmPushButtonWidgetClass, @menu, @args) RXtAddCallback(child, RXmNactivateCallback, lambda do |w, c, i| body.call end) else child = Rgtk_menu_item_new_with_label(arg.to_s) Rgtk_menu_shell_append(RGTK_MENU_SHELL(@menu), child) Rgtk_widget_show(child) add_callback(child, "activate") do |w, d| body.call end end change_label(child, arg) else Snd.raise(:wrong_number_of_args, "no block given") end end child end def separator(single = :single) if $with_motif line = (single == :double ? RXmDOUBLE_LINE : RXmSINGLE_LINE) RXtCreateManagedWidget("s", RxmSeparatorWidgetClass, @menu, [RXmNseparatorType, line]) else sep = Rgtk_menu_item_new() Rgtk_menu_shell_append(RGTK_MENU_SHELL(@menu), sep) Rgtk_widget_show(sep) end end end end # non-Snd menu functions, may be used outside Snd scripts class Main_menu < Menu def initialize(name, parent, args, &body) super(name, parent, args) if $with_motif @menu = RXmCreatePulldownMenu(parent, "pulldown-menu", @args) wid = RXtCreateManagedWidget(@label, RxmCascadeButtonWidgetClass, parent, [RXmNsubMenuId, @menu] + @args) RXtVaSetValues(parent, [RXmNmenuHelpWidget, wid]) if name =~ /help/ else wid = Rgtk_menu_item_new_with_label(@label) s = RGTK_MENU_SHELL(Rgtk_menu_item_get_submenu(RGTK_MENU_ITEM(parent))) Rgtk_menu_shell_append(s, wid) Rgtk_widget_show(wid) @menu = Rgtk_menu_new() Rgtk_menu_item_set_submenu(RGTK_MENU_ITEM(wid), @menu) end if block_given? instance_eval(&body) end end end class Main_popup_menu < Menu def initialize(name, parent, args, &body) super(name, parent, args) @parent = parent if $with_motif @menu = RXmCreatePopupMenu(@parent, "popup-menu", [RXmNpopupEnabled, RXmPOPUP_AUTOMATIC] + @args) RXtAddEventHandler(@parent, RButtonPressMask, false, lambda do |w, c, i, f| if Rbutton(i) == 3 RXmMenuPosition(@menu, i) RXtManageChild(@menu) end end) else =begin # FIXME: needs some work @menu = Rgtk_menu_new() add_event_handler(@parent, "button_press_event") do |w, e, d| ev = RGDK_EVENT_BUTTON(e) if Rbutton(ev) == 3 Rgtk_widget_show(@menu) Rgtk_menu_popup(RGTK_MENU(@menu), false, false, false, false, Rbutton(ev), Rtime(ev)) end end =end end unless @label.empty? label(@label) separator end if block_given? instance_eval(&body) end end end include Snd_XM # snd-xm.rb ends here snd-16.1/hooks.fs0000644000076400007640000000554712476114577012041 0ustar bilbil\ hooks.fs -- hooks.scm -> hooks.fs \ Author: Michael Scholz \ Created: 06/08/08 23:27:50 \ Changed: 15/02/27 22:24:42 \ \ @(#)hooks.fs 1.25 2/27/15 \ snd-hooks Array with all Snd hooks. \ reset-all-hooks ( -- ) \ with-local-hook ( hook local-hook-procs thunk -- result ) \ for all-chans require examp [defined] after-apply-controls-hook [if] #( after-apply-controls-hook after-graph-hook after-lisp-graph-hook after-open-hook after-save-as-hook after-save-state-hook after-transform-hook bad-header-hook before-close-hook before-exit-hook before-save-as-hook before-save-state-hook before-transform-hook clip-hook close-hook color-hook draw-mark-hook draw-mix-hook drop-hook during-open-hook effects-hook enved-hook exit-hook graph-hook help-hook initial-graph-hook key-press-hook lisp-graph-hook listener-click-hook mark-click-hook mark-drag-hook mark-hook mix-click-hook mix-drag-hook mix-release-hook mouse-click-hook mouse-drag-hook mouse-enter-graph-hook mouse-enter-label-hook mouse-enter-listener-hook mouse-enter-text-hook mouse-leave-graph-hook mouse-leave-label-hook mouse-leave-listener-hook mouse-leave-text-hook mouse-press-hook mus-error-hook name-click-hook new-sound-hook new-widget-hook open-hook open-raw-sound-hook orientation-hook output-comment-hook play-hook read-hook save-hook save-state-hook select-channel-hook select-sound-hook snd-error-hook snd-warning-hook start-playing-hook start-playing-selection-hook stop-playing-hook stop-playing-selection-hook update-hook ) [else] #() [then] constant snd-hooks : hooks-reset-hook { obj -- } obj hook? if obj reset-hook! then ; : reset-all-hooks ( -- ) doc" Remove all Snd hook functions." snd-hooks each ( hook ) hooks-reset-hook end-each nil nil nil { lst snd chn } all-chans each to lst lst 0 array-ref to snd lst 1 array-ref to chn snd chn edit-hook hooks-reset-hook snd chn after-edit-hook hooks-reset-hook snd chn undo-hook hooks-reset-hook end-each ; : with-local-hook <{ hook local-hook-procs thunk -- }> doc" Evaluate THUNK (an xt) \ with HOOK set to LOCAL-HOOK-PROCS (an array of procs), \ then restores HOOK to its previous state." hook hook? hook 1 "a hook" assert-type local-hook-procs array? local-hook-procs 2 "an array" assert-type thunk word? thunk 3 "a proc or xt" assert-type hook hook->array { old-procs } hook reset-hook! local-hook-procs each ( proc ) hook swap add-hook! end-each thunk '() run-proc drop hook reset-hook! old-procs each ( proc ) hook swap add-hook! end-each ; \ hooks.fs ends here snd-16.1/primes.scm0000644000076400007640000123756412306421671012362 0ustar bilbil;(load "t.scm") (define primes (vector 1 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199 211 223 227 229 233 239 241 251 257 263 269 271 277 281 283 293 307 311 313 317 331 337 347 349 353 359 367 373 379 383 389 397 401 409 419 421 431 433 439 443 449 457 461 463 467 479 487 491 499 503 509 521 523 541 547 557 563 569 571 577 587 593 599 601 607 613 617 619 631 641 643 647 653 659 661 673 677 683 691 701 709 719 727 733 739 743 751 757 761 769 773 787 797 809 811 821 823 827 829 839 853 857 859 863 877 881 883 887 907 911 919 929 937 941 947 953 967 971 977 983 991 997 1009 1013 1019 1021 1031 1033 1039 1049 1051 1061 1063 1069 1087 1091 1093 1097 1103 1109 1117 1123 1129 1151 1153 1163 1171 1181 1187 1193 1201 1213 1217 1223 1229 1231 1237 1249 1259 1277 1279 1283 1289 1291 1297 1301 1303 1307 1319 1321 1327 1361 1367 1373 1381 1399 1409 1423 1427 1429 1433 1439 1447 1451 1453 1459 1471 1481 1483 1487 1489 1493 1499 1511 1523 1531 1543 1549 1553 1559 1567 1571 1579 1583 1597 1601 1607 1609 1613 1619 1621 1627 1637 1657 1663 1667 1669 1693 1697 1699 1709 1721 1723 1733 1741 1747 1753 1759 1777 1783 1787 1789 1801 1811 1823 1831 1847 1861 1867 1871 1873 1877 1879 1889 1901 1907 1913 1931 1933 1949 1951 1973 1979 1987 1993 1997 1999 2003 2011 2017 2027 2029 2039 2053 2063 2069 2081 2083 2087 2089 2099 2111 2113 2129 2131 2137 2141 2143 2153 2161 2179 2203 2207 2213 2221 2237 2239 2243 2251 2267 2269 2273 2281 2287 2293 2297 2309 2311 2333 2339 2341 2347 2351 2357 2371 2377 2381 2383 2389 2393 2399 2411 2417 2423 2437 2441 2447 2459 2467 2473 2477 2503 2521 2531 2539 2543 2549 2551 2557 2579 2591 2593 2609 2617 2621 2633 2647 2657 2659 2663 2671 2677 2683 2687 2689 2693 2699 2707 2711 2713 2719 2729 2731 2741 2749 2753 2767 2777 2789 2791 2797 2801 2803 2819 2833 2837 2843 2851 2857 2861 2879 2887 2897 2903 2909 2917 2927 2939 2953 2957 2963 2969 2971 2999 3001 3011 3019 3023 3037 3041 3049 3061 3067 3079 3083 3089 3109 3119 3121 3137 3163 3167 3169 3181 3187 3191 3203 3209 3217 3221 3229 3251 3253 3257 3259 3271 3299 3301 3307 3313 3319 3323 3329 3331 3343 3347 3359 3361 3371 3373 3389 3391 3407 3413 3433 3449 3457 3461 3463 3467 3469 3491 3499 3511 3517 3527 3529 3533 3539 3541 3547 3557 3559 3571 3581 3583 3593 3607 3613 3617 3623 3631 3637 3643 3659 3671 3673 3677 3691 3697 3701 3709 3719 3727 3733 3739 3761 3767 3769 3779 3793 3797 3803 3821 3823 3833 3847 3851 3853 3863 3877 3881 3889 3907 3911 3917 3919 3923 3929 3931 3943 3947 3967 3989 4001 4003 4007 4013 4019 4021 4027 4049 4051 4057 4073 4079 4091 4093 4099 4111 4127 4129 4133 4139 4153 4157 4159 4177 4201 4211 4217 4219 4229 4231 4241 4243 4253 4259 4261 4271 4273 4283 4289 4297 4327 4337 4339 4349 4357 4363 4373 4391 4397 4409 4421 4423 4441 4447 4451 4457 4463 4481 4483 4493 4507 4513 4517 4519 4523 4547 4549 4561 4567 4583 4591 4597 4603 4621 4637 4639 4643 4649 4651 4657 4663 4673 4679 4691 4703 4721 4723 4729 4733 4751 4759 4783 4787 4789 4793 4799 4801 4813 4817 4831 4861 4871 4877 4889 4903 4909 4919 4931 4933 4937 4943 4951 4957 4967 4969 4973 4987 4993 4999 5003 5009 5011 5021 5023 5039 5051 5059 5077 5081 5087 5099 5101 5107 5113 5119 5147 5153 5167 5171 5179 5189 5197 5209 5227 5231 5233 5237 5261 5273 5279 5281 5297 5303 5309 5323 5333 5347 5351 5381 5387 5393 5399 5407 5413 5417 5419 5431 5437 5441 5443 5449 5471 5477 5479 5483 5501 5503 5507 5519 5521 5527 5531 5557 5563 5569 5573 5581 5591 5623 5639 5641 5647 5651 5653 5657 5659 5669 5683 5689 5693 5701 5711 5717 5737 5741 5743 5749 5779 5783 5791 5801 5807 5813 5821 5827 5839 5843 5849 5851 5857 5861 5867 5869 5879 5881 5897 5903 5923 5927 5939 5953 5981 5987 6007 6011 6029 6037 6043 6047 6053 6067 6073 6079 6089 6091 6101 6113 6121 6131 6133 6143 6151 6163 6173 6197 6199 6203 6211 6217 6221 6229 6247 6257 6263 6269 6271 6277 6287 6299 6301 6311 6317 6323 6329 6337 6343 6353 6359 6361 6367 6373 6379 6389 6397 6421 6427 6449 6451 6469 6473 6481 6491 6521 6529 6547 6551 6553 6563 6569 6571 6577 6581 6599 6607 6619 6637 6653 6659 6661 6673 6679 6689 6691 6701 6703 6709 6719 6733 6737 6761 6763 6779 6781 6791 6793 6803 6823 6827 6829 6833 6841 6857 6863 6869 6871 6883 6899 6907 6911 6917 6947 6949 6959 6961 6967 6971 6977 6983 6991 6997 7001 7013 7019 7027 7039 7043 7057 7069 7079 7103 7109 7121 7127 7129 7151 7159 7177 7187 7193 7207 7211 7213 7219 7229 7237 7243 7247 7253 7283 7297 7307 7309 7321 7331 7333 7349 7351 7369 7393 7411 7417 7433 7451 7457 7459 7477 7481 7487 7489 7499 7507 7517 7523 7529 7537 7541 7547 7549 7559 7561 7573 7577 7583 7589 7591 7603 7607 7621 7639 7643 7649 7669 7673 7681 7687 7691 7699 7703 7717 7723 7727 7741 7753 7757 7759 7789 7793 7817 7823 7829 7841 7853 7867 7873 7877 7879 7883 7901 7907 7919 7927 7933 7937 7949 7951 7963 7993 8009 8011 8017 8039 8053 8059 8069 8081 8087 8089 8093 8101 8111 8117 8123 8147 8161 8167 8171 8179 8191 8209 8219 8221 8231 8233 8237 8243 8263 8269 8273 8287 8291 8293 8297 8311 8317 8329 8353 8363 8369 8377 8387 8389 8419 8423 8429 8431 8443 8447 8461 8467 8501 8513 8521 8527 8537 8539 8543 8563 8573 8581 8597 8599 8609 8623 8627 8629 8641 8647 8663 8669 8677 8681 8689 8693 8699 8707 8713 8719 8731 8737 8741 8747 8753 8761 8779 8783 8803 8807 8819 8821 8831 8837 8839 8849 8861 8863 8867 8887 8893 8923 8929 8933 8941 8951 8963 8969 8971 8999 9001 9007 9011 9013 9029 9041 9043 9049 9059 9067 9091 9103 9109 9127 9133 9137 9151 9157 9161 9173 9181 9187 9199 9203 9209 9221 9227 9239 9241 9257 9277 9281 9283 9293 9311 9319 9323 9337 9341 9343 9349 9371 9377 9391 9397 9403 9413 9419 9421 9431 9433 9437 9439 9461 9463 9467 9473 9479 9491 9497 9511 9521 9533 9539 9547 9551 9587 9601 9613 9619 9623 9629 9631 9643 9649 9661 9677 9679 9689 9697 9719 9721 9733 9739 9743 9749 9767 9769 9781 9787 9791 9803 9811 9817 9829 9833 9839 9851 9857 9859 9871 9883 9887 9901 9907 9923 9929 9931 9941 9949 9967 9973 10007 10009 10037 10039 10061 10067 10069 10079 10091 10093 10099 10103 10111 10133 10139 10141 10151 10159 10163 10169 10177 10181 10193 10211 10223 10243 10247 10253 10259 10267 10271 10273 10289 10301 10303 10313 10321 10331 10333 10337 10343 10357 10369 10391 10399 10427 10429 10433 10453 10457 10459 10463 10477 10487 10499 10501 10513 10529 10531 10559 10567 10589 10597 10601 10607 10613 10627 10631 10639 10651 10657 10663 10667 10687 10691 10709 10711 10723 10729 10733 10739 10753 10771 10781 10789 10799 10831 10837 10847 10853 10859 10861 10867 10883 10889 10891 10903 10909 10937 10939 10949 10957 10973 10979 10987 10993 11003 11027 11047 11057 11059 11069 11071 11083 11087 11093 11113 11117 11119 11131 11149 11159 11161 11171 11173 11177 11197 11213 11239 11243 11251 11257 11261 11273 11279 11287 11299 11311 11317 11321 11329 11351 11353 11369 11383 11393 11399 11411 11423 11437 11443 11447 11467 11471 11483 11489 11491 11497 11503 11519 11527 11549 11551 11579 11587 11593 11597 11617 11621 11633 11657 11677 11681 11689 11699 11701 11717 11719 11731 11743 11777 11779 11783 11789 11801 11807 11813 11821 11827 11831 11833 11839 11863 11867 11887 11897 11903 11909 11923 11927 11933 11939 11941 11953 11959 11969 11971 11981 11987 12007 12011 12037 12041 12043 12049 12071 12073 12097 12101 12107 12109 12113 12119 12143 12149 12157 12161 12163 12197 12203 12211 12227 12239 12241 12251 12253 12263 12269 12277 12281 12289 12301 12323 12329 12343 12347 12373 12377 12379 12391 12401 12409 12413 12421 12433 12437 12451 12457 12473 12479 12487 12491 12497 12503 12511 12517 12527 12539 12541 12547 12553 12569 12577 12583 12589 12601 12611 12613 12619 12637 12641 12647 12653 12659 12671 12689 12697 12703 12713 12721 12739 12743 12757 12763 12781 12791 12799 12809 12821 12823 12829 12841 12853 12889 12893 12899 12907 12911 12917 12919 12923 12941 12953 12959 12967 12973 12979 12983 13001 13003 13007 13009 13033 13037 13043 13049 13063 13093 13099 13103 13109 13121 13127 13147 13151 13159 13163 13171 13177 13183 13187 13217 13219 13229 13241 13249 13259 13267 13291 13297 13309 13313 13327 13331 13337 13339 13367 13381 13397 13399 13411 13417 13421 13441 13451 13457 13463 13469 13477 13487 13499 13513 13523 13537 13553 13567 13577 13591 13597 13613 13619 13627 13633 13649 13669 13679 13681 13687 13691 13693 13697 13709 13711 13721 13723 13729 13751 13757 13759 13763 13781 13789 13799 13807 13829 13831 13841 13859 13873 13877 13879 13883 13901 13903 13907 13913 13921 13931 13933 13963 13967 13997 13999 14009 14011 14029 14033 14051 14057 14071 14081 14083 14087 14107 14143 14149 14153 14159 14173 14177 14197 14207 14221 14243 14249 14251 14281 14293 14303 14321 14323 14327 14341 14347 14369 14387 14389 14401 14407 14411 14419 14423 14431 14437 14447 14449 14461 14479 14489 14503 14519 14533 14537 14543 14549 14551 14557 14561 14563 14591 14593 14621 14627 14629 14633 14639 14653 14657 14669 14683 14699 14713 14717 14723 14731 14737 14741 14747 14753 14759 14767 14771 14779 14783 14797 14813 14821 14827 14831 14843 14851 14867 14869 14879 14887 14891 14897 14923 14929 14939 14947 14951 14957 14969 14983 15013 15017 15031 15053 15061 15073 15077 15083 15091 15101 15107 15121 15131 15137 15139 15149 15161 15173 15187 15193 15199 15217 15227 15233 15241 15259 15263 15269 15271 15277 15287 15289 15299 15307 15313 15319 15329 15331 15349 15359 15361 15373 15377 15383 15391 15401 15413 15427 15439 15443 15451 15461 15467 15473 15493 15497 15511 15527 15541 15551 15559 15569 15581 15583 15601 15607 15619 15629 15641 15643 15647 15649 15661 15667 15671 15679 15683 15727 15731 15733 15737 15739 15749 15761 15767 15773 15787 15791 15797 15803 15809 15817 15823 15859 15877 15881 15887 15889 15901 15907 15913 15919 15923 15937 15959 15971 15973 15991 16001 16007 16033 16057 16061 16063 16067 16069 16073 16087 16091 16097 16103 16111 16127 16139 16141 16183 16187 16189 16193 16217 16223 16229 16231 16249 16253 16267 16273 16301 16319 16333 16339 16349 16361 16363 16369 16381 16411 16417 16421 16427 16433 16447 16451 16453 16477 16481 16487 16493 16519 16529 16547 16553 16561 16567 16573 16603 16607 16619 16631 16633 16649 16651 16657 16661 16673 16691 16693 16699 16703 16729 16741 16747 16759 16763 16787 16811 16823 16829 16831 16843 16871 16879 16883 16889 16901 16903 16921 16927 16931 16937 16943 16963 16979 16981 16987 16993 17011 17021 17027 17029 17033 17041 17047 17053 17077 17093 17099 17107 17117 17123 17137 17159 17167 17183 17189 17191 17203 17207 17209 17231 17239 17257 17291 17293 17299 17317 17321 17327 17333 17341 17351 17359 17377 17383 17387 17389 17393 17401 17417 17419 17431 17443 17449 17467 17471 17477 17483 17489 17491 17497 17509 17519 17539 17551 17569 17573 17579 17581 17597 17599 17609 17623 17627 17657 17659 17669 17681 17683 17707 17713 17729 17737 17747 17749 17761 17783 17789 17791 17807 17827 17837 17839 17851 17863 17881 17891 17903 17909 17911 17921 17923 17929 17939 17957 17959 17971 17977 17981 17987 17989 18013 18041 18043 18047 18049 18059 18061 18077 18089 18097 18119 18121 18127 18131 18133 18143 18149 18169 18181 18191 18199 18211 18217 18223 18229 18233 18251 18253 18257 18269 18287 18289 18301 18307 18311 18313 18329 18341 18353 18367 18371 18379 18397 18401 18413 18427 18433 18439 18443 18451 18457 18461 18481 18493 18503 18517 18521 18523 18539 18541 18553 18583 18587 18593 18617 18637 18661 18671 18679 18691 18701 18713 18719 18731 18743 18749 18757 18773 18787 18793 18797 18803 18839 18859 18869 18899 18911 18913 18917 18919 18947 18959 18973 18979 19001 19009 19013 19031 19037 19051 19069 19073 19079 19081 19087 19121 19139 19141 19157 19163 19181 19183 19207 19211 19213 19219 19231 19237 19249 19259 19267 19273 19289 19301 19309 19319 19333 19373 19379 19381 19387 19391 19403 19417 19421 19423 19427 19429 19433 19441 19447 19457 19463 19469 19471 19477 19483 19489 19501 19507 19531 19541 19543 19553 19559 19571 19577 19583 19597 19603 19609 19661 19681 19687 19697 19699 19709 19717 19727 19739 19751 19753 19759 19763 19777 19793 19801 19813 19819 19841 19843 19853 19861 19867 19889 19891 19913 19919 19927 19937 19949 19961 19963 19973 19979 19991 19993 19997 20011 20021 20023 20029 20047 20051 20063 20071 20089 20101 20107 20113 20117 20123 20129 20143 20147 20149 20161 20173 20177 20183 20201 20219 20231 20233 20249 20261 20269 20287 20297 20323 20327 20333 20341 20347 20353 20357 20359 20369 20389 20393 20399 20407 20411 20431 20441 20443 20477 20479 20483 20507 20509 20521 20533 20543 20549 20551 20563 20593 20599 20611 20627 20639 20641 20663 20681 20693 20707 20717 20719 20731 20743 20747 20749 20753 20759 20771 20773 20789 20807 20809 20849 20857 20873 20879 20887 20897 20899 20903 20921 20929 20939 20947 20959 20963 20981 20983 21001 21011 21013 21017 21019 21023 21031 21059 21061 21067 21089 21101 21107 21121 21139 21143 21149 21157 21163 21169 21179 21187 21191 21193 21211 21221 21227 21247 21269 21277 21283 21313 21317 21319 21323 21341 21347 21377 21379 21383 21391 21397 21401 21407 21419 21433 21467 21481 21487 21491 21493 21499 21503 21517 21521 21523 21529 21557 21559 21563 21569 21577 21587 21589 21599 21601 21611 21613 21617 21647 21649 21661 21673 21683 21701 21713 21727 21737 21739 21751 21757 21767 21773 21787 21799 21803 21817 21821 21839 21841 21851 21859 21863 21871 21881 21893 21911 21929 21937 21943 21961 21977 21991 21997 22003 22013 22027 22031 22037 22039 22051 22063 22067 22073 22079 22091 22093 22109 22111 22123 22129 22133 22147 22153 22157 22159 22171 22189 22193 22229 22247 22259 22271 22273 22277 22279 22283 22291 22303 22307 22343 22349 22367 22369 22381 22391 22397 22409 22433 22441 22447 22453 22469 22481 22483 22501 22511 22531 22541 22543 22549 22567 22571 22573 22613 22619 22621 22637 22639 22643 22651 22669 22679 22691 22697 22699 22709 22717 22721 22727 22739 22741 22751 22769 22777 22783 22787 22807 22811 22817 22853 22859 22861 22871 22877 22901 22907 22921 22937 22943 22961 22963 22973 22993 23003 23011 23017 23021 23027 23029 23039 23041 23053 23057 23059 23063 23071 23081 23087 23099 23117 23131 23143 23159 23167 23173 23189 23197 23201 23203 23209 23227 23251 23269 23279 23291 23293 23297 23311 23321 23327 23333 23339 23357 23369 23371 23399 23417 23431 23447 23459 23473 23497 23509 23531 23537 23539 23549 23557 23561 23563 23567 23581 23593 23599 23603 23609 23623 23627 23629 23633 23663 23669 23671 23677 23687 23689 23719 23741 23743 23747 23753 23761 23767 23773 23789 23801 23813 23819 23827 23831 23833 23857 23869 23873 23879 23887 23893 23899 23909 23911 23917 23929 23957 23971 23977 23981 23993 24001 24007 24019 24023 24029 24043 24049 24061 24071 24077 24083 24091 24097 24103 24107 24109 24113 24121 24133 24137 24151 24169 24179 24181 24197 24203 24223 24229 24239 24247 24251 24281 24317 24329 24337 24359 24371 24373 24379 24391 24407 24413 24419 24421 24439 24443 24469 24473 24481 24499 24509 24517 24527 24533 24547 24551 24571 24593 24611 24623 24631 24659 24671 24677 24683 24691 24697 24709 24733 24749 24763 24767 24781 24793 24799 24809 24821 24841 24847 24851 24859 24877 24889 24907 24917 24919 24923 24943 24953 24967 24971 24977 24979 24989 25013 25031 25033 25037 25057 25073 25087 25097 25111 25117 25121 25127 25147 25153 25163 25169 25171 25183 25189 25219 25229 25237 25243 25247 25253 25261 25301 25303 25307 25309 25321 25339 25343 25349 25357 25367 25373 25391 25409 25411 25423 25439 25447 25453 25457 25463 25469 25471 25523 25537 25541 25561 25577 25579 25583 25589 25601 25603 25609 25621 25633 25639 25643 25657 25667 25673 25679 25693 25703 25717 25733 25741 25747 25759 25763 25771 25793 25799 25801 25819 25841 25847 25849 25867 25873 25889 25903 25913 25919 25931 25933 25939 25943 25951 25969 25981 25997 25999 26003 26017 26021 26029 26041 26053 26083 26099 26107 26111 26113 26119 26141 26153 26161 26171 26177 26183 26189 26203 26209 26227 26237 26249 26251 26261 26263 26267 26293 26297 26309 26317 26321 26339 26347 26357 26371 26387 26393 26399 26407 26417 26423 26431 26437 26449 26459 26479 26489 26497 26501 26513 26539 26557 26561 26573 26591 26597 26627 26633 26641 26647 26669 26681 26683 26687 26693 26699 26701 26711 26713 26717 26723 26729 26731 26737 26759 26777 26783 26801 26813 26821 26833 26839 26849 26861 26863 26879 26881 26891 26893 26903 26921 26927 26947 26951 26953 26959 26981 26987 26993 27011 27017 27031 27043 27059 27061 27067 27073 27077 27091 27103 27107 27109 27127 27143 27179 27191 27197 27211 27239 27241 27253 27259 27271 27277 27281 27283 27299 27329 27337 27361 27367 27397 27407 27409 27427 27431 27437 27449 27457 27479 27481 27487 27509 27527 27529 27539 27541 27551 27581 27583 27611 27617 27631 27647 27653 27673 27689 27691 27697 27701 27733 27737 27739 27743 27749 27751 27763 27767 27773 27779 27791 27793 27799 27803 27809 27817 27823 27827 27847 27851 27883 27893 27901 27917 27919 27941 27943 27947 27953 27961 27967 27983 27997 28001 28019 28027 28031 28051 28057 28069 28081 28087 28097 28099 28109 28111 28123 28151 28163 28181 28183 28201 28211 28219 28229 28277 28279 28283 28289 28297 28307 28309 28319 28349 28351 28387 28393 28403 28409 28411 28429 28433 28439 28447 28463 28477 28493 28499 28513 28517 28537 28541 28547 28549 28559 28571 28573 28579 28591 28597 28603 28607 28619 28621 28627 28631 28643 28649 28657 28661 28663 28669 28687 28697 28703 28711 28723 28729 28751 28753 28759 28771 28789 28793 28807 28813 28817 28837 28843 28859 28867 28871 28879 28901 28909 28921 28927 28933 28949 28961 28979 29009 29017 29021 29023 29027 29033 29059 29063 29077 29101 29123 29129 29131 29137 29147 29153 29167 29173 29179 29191 29201 29207 29209 29221 29231 29243 29251 29269 29287 29297 29303 29311 29327 29333 29339 29347 29363 29383 29387 29389 29399 29401 29411 29423 29429 29437 29443 29453 29473 29483 29501 29527 29531 29537 29567 29569 29573 29581 29587 29599 29611 29629 29633 29641 29663 29669 29671 29683 29717 29723 29741 29753 29759 29761 29789 29803 29819 29833 29837 29851 29863 29867 29873 29879 29881 29917 29921 29927 29947 29959 29983 29989 30011 30013 30029 30047 30059 30071 30089 30091 30097 30103 30109 30113 30119 30133 30137 30139 30161 30169 30181 30187 30197 30203 30211 30223 30241 30253 30259 30269 30271 30293 30307 30313 30319 30323 30341 30347 30367 30389 30391 30403 30427 30431 30449 30467 30469 30491 30493 30497 30509 30517 30529 30539 30553 30557 30559 30577 30593 30631 30637 30643 30649 30661 30671 30677 30689 30697 30703 30707 30713 30727 30757 30763 30773 30781 30803 30809 30817 30829 30839 30841 30851 30853 30859 30869 30871 30881 30893 30911 30931 30937 30941 30949 30971 30977 30983 31013 31019 31033 31039 31051 31063 31069 31079 31081 31091 31121 31123 31139 31147 31151 31153 31159 31177 31181 31183 31189 31193 31219 31223 31231 31237 31247 31249 31253 31259 31267 31271 31277 31307 31319 31321 31327 31333 31337 31357 31379 31387 31391 31393 31397 31469 31477 31481 31489 31511 31513 31517 31531 31541 31543 31547 31567 31573 31583 31601 31607 31627 31643 31649 31657 31663 31667 31687 31699 31721 31723 31727 31729 31741 31751 31769 31771 31793 31799 31817 31847 31849 31859 31873 31883 31891 31907 31957 31963 31973 31981 31991 32003 32009 32027 32029 32051 32057 32059 32063 32069 32077 32083 32089 32099 32117 32119 32141 32143 32159 32173 32183 32189 32191 32203 32213 32233 32237 32251 32257 32261 32297 32299 32303 32309 32321 32323 32327 32341 32353 32359 32363 32369 32371 32377 32381 32401 32411 32413 32423 32429 32441 32443 32467 32479 32491 32497 32503 32507 32531 32533 32537 32561 32563 32569 32573 32579 32587 32603 32609 32611 32621 32633 32647 32653 32687 32693 32707 32713 32717 32719 32749 32771 32779 32783 32789 32797 32801 32803 32831 32833 32839 32843 32869 32887 32909 32911 32917 32933 32939 32941 32957 32969 32971 32983 32987 32993 32999 33013 33023 33029 33037 33049 33053 33071 33073 33083 33091 33107 33113 33119 33149 33151 33161 33179 33181 33191 33199 33203 33211 33223 33247 33287 33289 33301 33311 33317 33329 33331 33343 33347 33349 33353 33359 33377 33391 33403 33409 33413 33427 33457 33461 33469 33479 33487 33493 33503 33521 33529 33533 33547 33563 33569 33577 33581 33587 33589 33599 33601 33613 33617 33619 33623 33629 33637 33641 33647 33679 33703 33713 33721 33739 33749 33751 33757 33767 33769 33773 33791 33797 33809 33811 33827 33829 33851 33857 33863 33871 33889 33893 33911 33923 33931 33937 33941 33961 33967 33997 34019 34031 34033 34039 34057 34061 34123 34127 34129 34141 34147 34157 34159 34171 34183 34211 34213 34217 34231 34253 34259 34261 34267 34273 34283 34297 34301 34303 34313 34319 34327 34337 34351 34361 34367 34369 34381 34403 34421 34429 34439 34457 34469 34471 34483 34487 34499 34501 34511 34513 34519 34537 34543 34549 34583 34589 34591 34603 34607 34613 34631 34649 34651 34667 34673 34679 34687 34693 34703 34721 34729 34739 34747 34757 34759 34763 34781 34807 34819 34841 34843 34847 34849 34871 34877 34883 34897 34913 34919 34939 34949 34961 34963 34981 35023 35027 35051 35053 35059 35069 35081 35083 35089 35099 35107 35111 35117 35129 35141 35149 35153 35159 35171 35201 35221 35227 35251 35257 35267 35279 35281 35291 35311 35317 35323 35327 35339 35353 35363 35381 35393 35401 35407 35419 35423 35437 35447 35449 35461 35491 35507 35509 35521 35527 35531 35533 35537 35543 35569 35573 35591 35593 35597 35603 35617 35671 35677 35729 35731 35747 35753 35759 35771 35797 35801 35803 35809 35831 35837 35839 35851 35863 35869 35879 35897 35899 35911 35923 35933 35951 35963 35969 35977 35983 35993 35999 36007 36011 36013 36017 36037 36061 36067 36073 36083 36097 36107 36109 36131 36137 36151 36161 36187 36191 36209 36217 36229 36241 36251 36263 36269 36277 36293 36299 36307 36313 36319 36341 36343 36353 36373 36383 36389 36433 36451 36457 36467 36469 36473 36479 36493 36497 36523 36527 36529 36541 36551 36559 36563 36571 36583 36587 36599 36607 36629 36637 36643 36653 36671 36677 36683 36691 36697 36709 36713 36721 36739 36749 36761 36767 36779 36781 36787 36791 36793 36809 36821 36833 36847 36857 36871 36877 36887 36899 36901 36913 36919 36923 36929 36931 36943 36947 36973 36979 36997 37003 37013 37019 37021 37039 37049 37057 37061 37087 37097 37117 37123 37139 37159 37171 37181 37189 37199 37201 37217 37223 37243 37253 37273 37277 37307 37309 37313 37321 37337 37339 37357 37361 37363 37369 37379 37397 37409 37423 37441 37447 37463 37483 37489 37493 37501 37507 37511 37517 37529 37537 37547 37549 37561 37567 37571 37573 37579 37589 37591 37607 37619 37633 37643 37649 37657 37663 37691 37693 37699 37717 37747 37781 37783 37799 37811 37813 37831 37847 37853 37861 37871 37879 37889 37897 37907 37951 37957 37963 37967 37987 37991 37993 37997 38011 38039 38047 38053 38069 38083 38113 38119 38149 38153 38167 38177 38183 38189 38197 38201 38219 38231 38237 38239 38261 38273 38281 38287 38299 38303 38317 38321 38327 38329 38333 38351 38371 38377 38393 38431 38447 38449 38453 38459 38461 38501 38543 38557 38561 38567 38569 38593 38603 38609 38611 38629 38639 38651 38653 38669 38671 38677 38693 38699 38707 38711 38713 38723 38729 38737 38747 38749 38767 38783 38791 38803 38821 38833 38839 38851 38861 38867 38873 38891 38903 38917 38921 38923 38933 38953 38959 38971 38977 38993 39019 39023 39041 39043 39047 39079 39089 39097 39103 39107 39113 39119 39133 39139 39157 39161 39163 39181 39191 39199 39209 39217 39227 39229 39233 39239 39241 39251 39293 39301 39313 39317 39323 39341 39343 39359 39367 39371 39373 39383 39397 39409 39419 39439 39443 39451 39461 39499 39503 39509 39511 39521 39541 39551 39563 39569 39581 39607 39619 39623 39631 39659 39667 39671 39679 39703 39709 39719 39727 39733 39749 39761 39769 39779 39791 39799 39821 39827 39829 39839 39841 39847 39857 39863 39869 39877 39883 39887 39901 39929 39937 39953 39971 39979 39983 39989 40009 40013 40031 40037 40039 40063 40087 40093 40099 40111 40123 40127 40129 40151 40153 40163 40169 40177 40189 40193 40213 40231 40237 40241 40253 40277 40283 40289 40343 40351 40357 40361 40387 40423 40427 40429 40433 40459 40471 40483 40487 40493 40499 40507 40519 40529 40531 40543 40559 40577 40583 40591 40597 40609 40627 40637 40639 40693 40697 40699 40709 40739 40751 40759 40763 40771 40787 40801 40813 40819 40823 40829 40841 40847 40849 40853 40867 40879 40883 40897 40903 40927 40933 40939 40949 40961 40973 40993 41011 41017 41023 41039 41047 41051 41057 41077 41081 41113 41117 41131 41141 41143 41149 41161 41177 41179 41183 41189 41201 41203 41213 41221 41227 41231 41233 41243 41257 41263 41269 41281 41299 41333 41341 41351 41357 41381 41387 41389 41399 41411 41413 41443 41453 41467 41479 41491 41507 41513 41519 41521 41539 41543 41549 41579 41593 41597 41603 41609 41611 41617 41621 41627 41641 41647 41651 41659 41669 41681 41687 41719 41729 41737 41759 41761 41771 41777 41801 41809 41813 41843 41849 41851 41863 41879 41887 41893 41897 41903 41911 41927 41941 41947 41953 41957 41959 41969 41981 41983 41999 42013 42017 42019 42023 42043 42061 42071 42073 42083 42089 42101 42131 42139 42157 42169 42179 42181 42187 42193 42197 42209 42221 42223 42227 42239 42257 42281 42283 42293 42299 42307 42323 42331 42337 42349 42359 42373 42379 42391 42397 42403 42407 42409 42433 42437 42443 42451 42457 42461 42463 42467 42473 42487 42491 42499 42509 42533 42557 42569 42571 42577 42589 42611 42641 42643 42649 42667 42677 42683 42689 42697 42701 42703 42709 42719 42727 42737 42743 42751 42767 42773 42787 42793 42797 42821 42829 42839 42841 42853 42859 42863 42899 42901 42923 42929 42937 42943 42953 42961 42967 42979 42989 43003 43013 43019 43037 43049 43051 43063 43067 43093 43103 43117 43133 43151 43159 43177 43189 43201 43207 43223 43237 43261 43271 43283 43291 43313 43319 43321 43331 43391 43397 43399 43403 43411 43427 43441 43451 43457 43481 43487 43499 43517 43541 43543 43573 43577 43579 43591 43597 43607 43609 43613 43627 43633 43649 43651 43661 43669 43691 43711 43717 43721 43753 43759 43777 43781 43783 43787 43789 43793 43801 43853 43867 43889 43891 43913 43933 43943 43951 43961 43963 43969 43973 43987 43991 43997 44017 44021 44027 44029 44041 44053 44059 44071 44087 44089 44101 44111 44119 44123 44129 44131 44159 44171 44179 44189 44201 44203 44207 44221 44249 44257 44263 44267 44269 44273 44279 44281 44293 44351 44357 44371 44381 44383 44389 44417 44449 44453 44483 44491 44497 44501 44507 44519 44531 44533 44537 44543 44549 44563 44579 44587 44617 44621 44623 44633 44641 44647 44651 44657 44683 44687 44699 44701 44711 44729 44741 44753 44771 44773 44777 44789 44797 44809 44819 44839 44843 44851 44867 44879 44887 44893 44909 44917 44927 44939 44953 44959 44963 44971 44983 44987 45007 45013 45053 45061 45077 45083 45119 45121 45127 45131 45137 45139 45161 45179 45181 45191 45197 45233 45247 45259 45263 45281 45289 45293 45307 45317 45319 45329 45337 45341 45343 45361 45377 45389 45403 45413 45427 45433 45439 45481 45491 45497 45503 45523 45533 45541 45553 45557 45569 45587 45589 45599 45613 45631 45641 45659 45667 45673 45677 45691 45697 45707 45737 45751 45757 45763 45767 45779 45817 45821 45823 45827 45833 45841 45853 45863 45869 45887 45893 45943 45949 45953 45959 45971 45979 45989 46021 46027 46049 46051 46061 46073 46091 46093 46099 46103 46133 46141 46147 46153 46171 46181 46183 46187 46199 46219 46229 46237 46261 46271 46273 46279 46301 46307 46309 46327 46337 46349 46351 46381 46399 46411 46439 46441 46447 46451 46457 46471 46477 46489 46499 46507 46511 46523 46549 46559 46567 46573 46589 46591 46601 46619 46633 46639 46643 46649 46663 46679 46681 46687 46691 46703 46723 46727 46747 46751 46757 46769 46771 46807 46811 46817 46819 46829 46831 46853 46861 46867 46877 46889 46901 46919 46933 46957 46993 46997 47017 47041 47051 47057 47059 47087 47093 47111 47119 47123 47129 47137 47143 47147 47149 47161 47189 47207 47221 47237 47251 47269 47279 47287 47293 47297 47303 47309 47317 47339 47351 47353 47363 47381 47387 47389 47407 47417 47419 47431 47441 47459 47491 47497 47501 47507 47513 47521 47527 47533 47543 47563 47569 47581 47591 47599 47609 47623 47629 47639 47653 47657 47659 47681 47699 47701 47711 47713 47717 47737 47741 47743 47777 47779 47791 47797 47807 47809 47819 47837 47843 47857 47869 47881 47903 47911 47917 47933 47939 47947 47951 47963 47969 47977 47981 48017 48023 48029 48049 48073 48079 48091 48109 48119 48121 48131 48157 48163 48179 48187 48193 48197 48221 48239 48247 48259 48271 48281 48299 48311 48313 48337 48341 48353 48371 48383 48397 48407 48409 48413 48437 48449 48463 48473 48479 48481 48487 48491 48497 48523 48527 48533 48539 48541 48563 48571 48589 48593 48611 48619 48623 48647 48649 48661 48673 48677 48679 48731 48733 48751 48757 48761 48767 48779 48781 48787 48799 48809 48817 48821 48823 48847 48857 48859 48869 48871 48883 48889 48907 48947 48953 48973 48989 48991 49003 49009 49019 49031 49033 49037 49043 49057 49069 49081 49103 49109 49117 49121 49123 49139 49157 49169 49171 49177 49193 49199 49201 49207 49211 49223 49253 49261 49277 49279 49297 49307 49331 49333 49339 49363 49367 49369 49391 49393 49409 49411 49417 49429 49433 49451 49459 49463 49477 49481 49499 49523 49529 49531 49537 49547 49549 49559 49597 49603 49613 49627 49633 49639 49663 49667 49669 49681 49697 49711 49727 49739 49741 49747 49757 49783 49787 49789 49801 49807 49811 49823 49831 49843 49853 49871 49877 49891 49919 49921 49927 49937 49939 49943 49957 49991 49993 49999 50021 50023 50033 50047 50051 50053 50069 50077 50087 50093 50101 50111 50119 50123 50129 50131 50147 50153 50159 50177 50207 50221 50227 50231 50261 50263 50273 50287 50291 50311 50321 50329 50333 50341 50359 50363 50377 50383 50387 50411 50417 50423 50441 50459 50461 50497 50503 50513 50527 50539 50543 50549 50551 50581 50587 50591 50593 50599 50627 50647 50651 50671 50683 50707 50723 50741 50753 50767 50773 50777 50789 50821 50833 50839 50849 50857 50867 50873 50891 50893 50909 50923 50929 50951 50957 50969 50971 50989 50993 51001 51031 51043 51047 51059 51061 51071 51109 51131 51133 51137 51151 51157 51169 51193 51197 51199 51203 51217 51229 51239 51241 51257 51263 51283 51287 51307 51329 51341 51343 51347 51349 51361 51383 51407 51413 51419 51421 51427 51431 51437 51439 51449 51461 51473 51479 51481 51487 51503 51511 51517 51521 51539 51551 51563 51577 51581 51593 51599 51607 51613 51631 51637 51647 51659 51673 51679 51683 51691 51713 51719 51721 51749 51767 51769 51787 51797 51803 51817 51827 51829 51839 51853 51859 51869 51871 51893 51899 51907 51913 51929 51941 51949 51971 51973 51977 51991 52009 52021 52027 52051 52057 52067 52069 52081 52103 52121 52127 52147 52153 52163 52177 52181 52183 52189 52201 52223 52237 52249 52253 52259 52267 52289 52291 52301 52313 52321 52361 52363 52369 52379 52387 52391 52433 52453 52457 52489 52501 52511 52517 52529 52541 52543 52553 52561 52567 52571 52579 52583 52609 52627 52631 52639 52667 52673 52691 52697 52709 52711 52721 52727 52733 52747 52757 52769 52783 52807 52813 52817 52837 52859 52861 52879 52883 52889 52901 52903 52919 52937 52951 52957 52963 52967 52973 52981 52999 53003 53017 53047 53051 53069 53077 53087 53089 53093 53101 53113 53117 53129 53147 53149 53161 53171 53173 53189 53197 53201 53231 53233 53239 53267 53269 53279 53281 53299 53309 53323 53327 53353 53359 53377 53381 53401 53407 53411 53419 53437 53441 53453 53479 53503 53507 53527 53549 53551 53569 53591 53593 53597 53609 53611 53617 53623 53629 53633 53639 53653 53657 53681 53693 53699 53717 53719 53731 53759 53773 53777 53783 53791 53813 53819 53831 53849 53857 53861 53881 53887 53891 53897 53899 53917 53923 53927 53939 53951 53959 53987 53993 54001 54011 54013 54037 54049 54059 54083 54091 54101 54121 54133 54139 54151 54163 54167 54181 54193 54217 54251 54269 54277 54287 54293 54311 54319 54323 54331 54347 54361 54367 54371 54377 54401 54403 54409 54413 54419 54421 54437 54443 54449 54469 54493 54497 54499 54503 54517 54521 54539 54541 54547 54559 54563 54577 54581 54583 54601 54617 54623 54629 54631 54647 54667 54673 54679 54709 54713 54721 54727 54751 54767 54773 54779 54787 54799 54829 54833 54851 54869 54877 54881 54907 54917 54919 54941 54949 54959 54973 54979 54983 55001 55009 55021 55049 55051 55057 55061 55073 55079 55103 55109 55117 55127 55147 55163 55171 55201 55207 55213 55217 55219 55229 55243 55249 55259 55291 55313 55331 55333 55337 55339 55343 55351 55373 55381 55399 55411 55439 55441 55457 55469 55487 55501 55511 55529 55541 55547 55579 55589 55603 55609 55619 55621 55631 55633 55639 55661 55663 55667 55673 55681 55691 55697 55711 55717 55721 55733 55763 55787 55793 55799 55807 55813 55817 55819 55823 55829 55837 55843 55849 55871 55889 55897 55901 55903 55921 55927 55931 55933 55949 55967 55987 55997 56003 56009 56039 56041 56053 56081 56087 56093 56099 56101 56113 56123 56131 56149 56167 56171 56179 56197 56207 56209 56237 56239 56249 56263 56267 56269 56299 56311 56333 56359 56369 56377 56383 56393 56401 56417 56431 56437 56443 56453 56467 56473 56477 56479 56489 56501 56503 56509 56519 56527 56531 56533 56543 56569 56591 56597 56599 56611 56629 56633 56659 56663 56671 56681 56687 56701 56711 56713 56731 56737 56747 56767 56773 56779 56783 56807 56809 56813 56821 56827 56843 56857 56873 56891 56893 56897 56909 56911 56921 56923 56929 56941 56951 56957 56963 56983 56989 56993 56999 57037 57041 57047 57059 57073 57077 57089 57097 57107 57119 57131 57139 57143 57149 57163 57173 57179 57191 57193 57203 57221 57223 57241 57251 57259 57269 57271 57283 57287 57301 57329 57331 57347 57349 57367 57373 57383 57389 57397 57413 57427 57457 57467 57487 57493 57503 57527 57529 57557 57559 57571 57587 57593 57601 57637 57641 57649 57653 57667 57679 57689 57697 57709 57713 57719 57727 57731 57737 57751 57773 57781 57787 57791 57793 57803 57809 57829 57839 57847 57853 57859 57881 57899 57901 57917 57923 57943 57947 57973 57977 57991 58013 58027 58031 58043 58049 58057 58061 58067 58073 58099 58109 58111 58129 58147 58151 58153 58169 58171 58189 58193 58199 58207 58211 58217 58229 58231 58237 58243 58271 58309 58313 58321 58337 58363 58367 58369 58379 58391 58393 58403 58411 58417 58427 58439 58441 58451 58453 58477 58481 58511 58537 58543 58549 58567 58573 58579 58601 58603 58613 58631 58657 58661 58679 58687 58693 58699 58711 58727 58733 58741 58757 58763 58771 58787 58789 58831 58889 58897 58901 58907 58909 58913 58921 58937 58943 58963 58967 58979 58991 58997 59009 59011 59021 59023 59029 59051 59053 59063 59069 59077 59083 59093 59107 59113 59119 59123 59141 59149 59159 59167 59183 59197 59207 59209 59219 59221 59233 59239 59243 59263 59273 59281 59333 59341 59351 59357 59359 59369 59377 59387 59393 59399 59407 59417 59419 59441 59443 59447 59453 59467 59471 59473 59497 59509 59513 59539 59557 59561 59567 59581 59611 59617 59621 59627 59629 59651 59659 59663 59669 59671 59693 59699 59707 59723 59729 59743 59747 59753 59771 59779 59791 59797 59809 59833 59863 59879 59887 59921 59929 59951 59957 59971 59981 59999 60013 60017 60029 60037 60041 60077 60083 60089 60091 60101 60103 60107 60127 60133 60139 60149 60161 60167 60169 60209 60217 60223 60251 60257 60259 60271 60289 60293 60317 60331 60337 60343 60353 60373 60383 60397 60413 60427 60443 60449 60457 60493 60497 60509 60521 60527 60539 60589 60601 60607 60611 60617 60623 60631 60637 60647 60649 60659 60661 60679 60689 60703 60719 60727 60733 60737 60757 60761 60763 60773 60779 60793 60811 60821 60859 60869 60887 60889 60899 60901 60913 60917 60919 60923 60937 60943 60953 60961 61001 61007 61027 61031 61043 61051 61057 61091 61099 61121 61129 61141 61151 61153 61169 61211 61223 61231 61253 61261 61283 61291 61297 61331 61333 61339 61343 61357 61363 61379 61381 61403 61409 61417 61441 61463 61469 61471 61483 61487 61493 61507 61511 61519 61543 61547 61553 61559 61561 61583 61603 61609 61613 61627 61631 61637 61643 61651 61657 61667 61673 61681 61687 61703 61717 61723 61729 61751 61757 61781 61813 61819 61837 61843 61861 61871 61879 61909 61927 61933 61949 61961 61967 61979 61981 61987 61991 62003 62011 62017 62039 62047 62053 62057 62071 62081 62099 62119 62129 62131 62137 62141 62143 62171 62189 62191 62201 62207 62213 62219 62233 62273 62297 62299 62303 62311 62323 62327 62347 62351 62383 62401 62417 62423 62459 62467 62473 62477 62483 62497 62501 62507 62533 62539 62549 62563 62581 62591 62597 62603 62617 62627 62633 62639 62653 62659 62683 62687 62701 62723 62731 62743 62753 62761 62773 62791 62801 62819 62827 62851 62861 62869 62873 62897 62903 62921 62927 62929 62939 62969 62971 62981 62983 62987 62989 63029 63031 63059 63067 63073 63079 63097 63103 63113 63127 63131 63149 63179 63197 63199 63211 63241 63247 63277 63281 63299 63311 63313 63317 63331 63337 63347 63353 63361 63367 63377 63389 63391 63397 63409 63419 63421 63439 63443 63463 63467 63473 63487 63493 63499 63521 63527 63533 63541 63559 63577 63587 63589 63599 63601 63607 63611 63617 63629 63647 63649 63659 63667 63671 63689 63691 63697 63703 63709 63719 63727 63737 63743 63761 63773 63781 63793 63799 63803 63809 63823 63839 63841 63853 63857 63863 63901 63907 63913 63929 63949 63977 63997 64007 64013 64019 64033 64037 64063 64067 64081 64091 64109 64123 64151 64153 64157 64171 64187 64189 64217 64223 64231 64237 64271 64279 64283 64301 64303 64319 64327 64333 64373 64381 64399 64403 64433 64439 64451 64453 64483 64489 64499 64513 64553 64567 64577 64579 64591 64601 64609 64613 64621 64627 64633 64661 64663 64667 64679 64693 64709 64717 64747 64763 64781 64783 64793 64811 64817 64849 64853 64871 64877 64879 64891 64901 64919 64921 64927 64937 64951 64969 64997 65003 65011 65027 65029 65033 65053 65063 65071 65089 65099 65101 65111 65119 65123 65129 65141 65147 65167 65171 65173 65179 65183 65203 65213 65239 65257 65267 65269 65287 65293 65309 65323 65327 65353 65357 65371 65381 65393 65407 65413 65419 65423 65437 65447 65449 65479 65497 65519 65521 65537 65539 65543 65551 65557 65563 65579 65581 65587 65599 65609 65617 65629 65633 65647 65651 65657 65677 65687 65699 65701 65707 65713 65717 65719 65729 65731 65761 65777 65789 65809 65827 65831 65837 65839 65843 65851 65867 65881 65899 65921 65927 65929 65951 65957 65963 65981 65983 65993 66029 66037 66041 66047 66067 66071 66083 66089 66103 66107 66109 66137 66161 66169 66173 66179 66191 66221 66239 66271 66293 66301 66337 66343 66347 66359 66361 66373 66377 66383 66403 66413 66431 66449 66457 66463 66467 66491 66499 66509 66523 66529 66533 66541 66553 66569 66571 66587 66593 66601 66617 66629 66643 66653 66683 66697 66701 66713 66721 66733 66739 66749 66751 66763 66791 66797 66809 66821 66841 66851 66853 66863 66877 66883 66889 66919 66923 66931 66943 66947 66949 66959 66973 66977 67003 67021 67033 67043 67049 67057 67061 67073 67079 67103 67121 67129 67139 67141 67153 67157 67169 67181 67187 67189 67211 67213 67217 67219 67231 67247 67261 67271 67273 67289 67307 67339 67343 67349 67369 67391 67399 67409 67411 67421 67427 67429 67433 67447 67453 67477 67481 67489 67493 67499 67511 67523 67531 67537 67547 67559 67567 67577 67579 67589 67601 67607 67619 67631 67651 67679 67699 67709 67723 67733 67741 67751 67757 67759 67763 67777 67783 67789 67801 67807 67819 67829 67843 67853 67867 67883 67891 67901 67927 67931 67933 67939 67943 67957 67961 67967 67979 67987 67993 68023 68041 68053 68059 68071 68087 68099 68111 68113 68141 68147 68161 68171 68207 68209 68213 68219 68227 68239 68261 68279 68281 68311 68329 68351 68371 68389 68399 68437 68443 68447 68449 68473 68477 68483 68489 68491 68501 68507 68521 68531 68539 68543 68567 68581 68597 68611 68633 68639 68659 68669 68683 68687 68699 68711 68713 68729 68737 68743 68749 68767 68771 68777 68791 68813 68819 68821 68863 68879 68881 68891 68897 68899 68903 68909 68917 68927 68947 68963 68993 69001 69011 69019 69029 69031 69061 69067 69073 69109 69119 69127 69143 69149 69151 69163 69191 69193 69197 69203 69221 69233 69239 69247 69257 69259 69263 69313 69317 69337 69341 69371 69379 69383 69389 69401 69403 69427 69431 69439 69457 69463 69467 69473 69481 69491 69493 69497 69499 69539 69557 69593 69623 69653 69661 69677 69691 69697 69709 69737 69739 69761 69763 69767 69779 69809 69821 69827 69829 69833 69847 69857 69859 69877 69899 69911 69929 69931 69941 69959 69991 69997 70001 70003 70009 70019 70039 70051 70061 70067 70079 70099 70111 70117 70121 70123 70139 70141 70157 70163 70177 70181 70183 70199 70201 70207 70223 70229 70237 70241 70249 70271 70289 70297 70309 70313 70321 70327 70351 70373 70379 70381 70393 70423 70429 70439 70451 70457 70459 70481 70487 70489 70501 70507 70529 70537 70549 70571 70573 70583 70589 70607 70619 70621 70627 70639 70657 70663 70667 70687 70709 70717 70729 70753 70769 70783 70793 70823 70841 70843 70849 70853 70867 70877 70879 70891 70901 70913 70919 70921 70937 70949 70951 70957 70969 70979 70981 70991 70997 70999 71011 71023 71039 71059 71069 71081 71089 71119 71129 71143 71147 71153 71161 71167 71171 71191 71209 71233 71237 71249 71257 71261 71263 71287 71293 71317 71327 71329 71333 71339 71341 71347 71353 71359 71363 71387 71389 71399 71411 71413 71419 71429 71437 71443 71453 71471 71473 71479 71483 71503 71527 71537 71549 71551 71563 71569 71593 71597 71633 71647 71663 71671 71693 71699 71707 71711 71713 71719 71741 71761 71777 71789 71807 71809 71821 71837 71843 71849 71861 71867 71879 71881 71887 71899 71909 71917 71933 71941 71947 71963 71971 71983 71987 71993 71999 72019 72031 72043 72047 72053 72073 72077 72089 72091 72101 72103 72109 72139 72161 72167 72169 72173 72211 72221 72223 72227 72229 72251 72253 72269 72271 72277 72287 72307 72313 72337 72341 72353 72367 72379 72383 72421 72431 72461 72467 72469 72481 72493 72497 72503 72533 72547 72551 72559 72577 72613 72617 72623 72643 72647 72649 72661 72671 72673 72679 72689 72701 72707 72719 72727 72733 72739 72763 72767 72797 72817 72823 72859 72869 72871 72883 72889 72893 72901 72907 72911 72923 72931 72937 72949 72953 72959 72973 72977 72997 73009 73013 73019 73037 73039 73043 73061 73063 73079 73091 73121 73127 73133 73141 73181 73189 73237 73243 73259 73277 73291 73303 73309 73327 73331 73351 73361 73363 73369 73379 73387 73417 73421 73433 73453 73459 73471 73477 73483 73517 73523 73529 73547 73553 73561 73571 73583 73589 73597 73607 73609 73613 73637 73643 73651 73673 73679 73681 73693 73699 73709 73721 73727 73751 73757 73771 73783 73819 73823 73847 73849 73859 73867 73877 73883 73897 73907 73939 73943 73951 73961 73973 73999 74017 74021 74027 74047 74051 74071 74077 74093 74099 74101 74131 74143 74149 74159 74161 74167 74177 74189 74197 74201 74203 74209 74219 74231 74257 74279 74287 74293 74297 74311 74317 74323 74353 74357 74363 74377 74381 74383 74411 74413 74419 74441 74449 74453 74471 74489 74507 74509 74521 74527 74531 74551 74561 74567 74573 74587 74597 74609 74611 74623 74653 74687 74699 74707 74713 74717 74719 74729 74731 74747 74759 74761 74771 74779 74797 74821 74827 74831 74843 74857 74861 74869 74873 74887 74891 74897 74903 74923 74929 74933 74941 74959 75011 75013 75017 75029 75037 75041 75079 75083 75109 75133 75149 75161 75167 75169 75181 75193 75209 75211 75217 75223 75227 75239 75253 75269 75277 75289 75307 75323 75329 75337 75347 75353 75367 75377 75389 75391 75401 75403 75407 75431 75437 75479 75503 75511 75521 75527 75533 75539 75541 75553 75557 75571 75577 75583 75611 75617 75619 75629 75641 75653 75659 75679 75683 75689 75703 75707 75709 75721 75731 75743 75767 75773 75781 75787 75793 75797 75821 75833 75853 75869 75883 75913 75931 75937 75941 75967 75979 75983 75989 75991 75997 76001 76003 76031 76039 76079 76081 76091 76099 76103 76123 76129 76147 76157 76159 76163 76207 76213 76231 76243 76249 76253 76259 76261 76283 76289 76303 76333 76343 76367 76369 76379 76387 76403 76421 76423 76441 76463 76471 76481 76487 76493 76507 76511 76519 76537 76541 76543 76561 76579 76597 76603 76607 76631 76649 76651 76667 76673 76679 76697 76717 76733 76753 76757 76771 76777 76781 76801 76819 76829 76831 76837 76847 76871 76873 76883 76907 76913 76919 76943 76949 76961 76963 76991 77003 77017 77023 77029 77041 77047 77069 77081 77093 77101 77137 77141 77153 77167 77171 77191 77201 77213 77237 77239 77243 77249 77261 77263 77267 77269 77279 77291 77317 77323 77339 77347 77351 77359 77369 77377 77383 77417 77419 77431 77447 77471 77477 77479 77489 77491 77509 77513 77521 77527 77543 77549 77551 77557 77563 77569 77573 77587 77591 77611 77617 77621 77641 77647 77659 77681 77687 77689 77699 77711 77713 77719 77723 77731 77743 77747 77761 77773 77783 77797 77801 77813 77839 77849 77863 77867 77893 77899 77929 77933 77951 77969 77977 77983 77999 78007 78017 78031 78041 78049 78059 78079 78101 78121 78137 78139 78157 78163 78167 78173 78179 78191 78193 78203 78229 78233 78241 78259 78277 78283 78301 78307 78311 78317 78341 78347 78367 78401 78427 78437 78439 78467 78479 78487 78497 78509 78511 78517 78539 78541 78553 78569 78571 78577 78583 78593 78607 78623 78643 78649 78653 78691 78697 78707 78713 78721 78737 78779 78781 78787 78791 78797 78803 78809 78823 78839 78853 78857 78877 78887 78889 78893 78901 78919 78929 78941 78977 78979 78989 79031 79039 79043 79063 79087 79103 79111 79133 79139 79147 79151 79153 79159 79181 79187 79193 79201 79229 79231 79241 79259 79273 79279 79283 79301 79309 79319 79333 79337 79349 79357 79367 79379 79393 79397 79399 79411 79423 79427 79433 79451 79481 79493 79531 79537 79549 79559 79561 79579 79589 79601 79609 79613 79621 79627 79631 79633 79657 79669 79687 79691 79693 79697 79699 79757 79769 79777 79801 79811 79813 79817 79823 79829 79841 79843 79847 79861 79867 79873 79889 79901 79903 79907 79939 79943 79967 79973 79979 79987 79997 79999 80021 80039 80051 80071 80077 80107 80111 80141 80147 80149 80153 80167 80173 80177 80191 80207 80209 80221 80231 80233 80239 80251 80263 80273 80279 80287 80309 80317 80329 80341 80347 80363 80369 80387 80407 80429 80447 80449 80471 80473 80489 80491 80513 80527 80537 80557 80567 80599 80603 80611 80621 80627 80629 80651 80657 80669 80671 80677 80681 80683 80687 80701 80713 80737 80747 80749 80761 80777 80779 80783 80789 80803 80809 80819 80831 80833 80849 80863 80897 80909 80911 80917 80923 80929 80933 80953 80963 80989 81001 81013 81017 81019 81023 81031 81041 81043 81047 81049 81071 81077 81083 81097 81101 81119 81131 81157 81163 81173 81181 81197 81199 81203 81223 81233 81239 81281 81283 81293 81299 81307 81331 81343 81349 81353 81359 81371 81373 81401 81409 81421 81439 81457 81463 81509 81517 81527 81533 81547 81551 81553 81559 81563 81569 81611 81619 81629 81637 81647 81649 81667 81671 81677 81689 81701 81703 81707 81727 81737 81749 81761 81769 81773 81799 81817 81839 81847 81853 81869 81883 81899 81901 81919 81929 81931 81937 81943 81953 81967 81971 81973 82003 82007 82009 82013 82021 82031 82037 82039 82051 82067 82073 82129 82139 82141 82153 82163 82171 82183 82189 82193 82207 82217 82219 82223 82231 82237 82241 82261 82267 82279 82301 82307 82339 82349 82351 82361 82373 82387 82393 82421 82457 82463 82469 82471 82483 82487 82493 82499 82507 82529 82531 82549 82559 82561 82567 82571 82591 82601 82609 82613 82619 82633 82651 82657 82699 82721 82723 82727 82729 82757 82759 82763 82781 82787 82793 82799 82811 82813 82837 82847 82883 82889 82891 82903 82913 82939 82963 82981 82997 83003 83009 83023 83047 83059 83063 83071 83077 83089 83093 83101 83117 83137 83177 83203 83207 83219 83221 83227 83231 83233 83243 83257 83267 83269 83273 83299 83311 83339 83341 83357 83383 83389 83399 83401 83407 83417 83423 83431 83437 83443 83449 83459 83471 83477 83497 83537 83557 83561 83563 83579 83591 83597 83609 83617 83621 83639 83641 83653 83663 83689 83701 83717 83719 83737 83761 83773 83777 83791 83813 83833 83843 83857 83869 83873 83891 83903 83911 83921 83933 83939 83969 83983 83987 84011 84017 84047 84053 84059 84061 84067 84089 84121 84127 84131 84137 84143 84163 84179 84181 84191 84199 84211 84221 84223 84229 84239 84247 84263 84299 84307 84313 84317 84319 84347 84349 84377 84389 84391 84401 84407 84421 84431 84437 84443 84449 84457 84463 84467 84481 84499 84503 84509 84521 84523 84533 84551 84559 84589 84629 84631 84649 84653 84659 84673 84691 84697 84701 84713 84719 84731 84737 84751 84761 84787 84793 84809 84811 84827 84857 84859 84869 84871 84913 84919 84947 84961 84967 84977 84979 84991 85009 85021 85027 85037 85049 85061 85081 85087 85091 85093 85103 85109 85121 85133 85147 85159 85193 85199 85201 85213 85223 85229 85237 85243 85247 85259 85297 85303 85313 85331 85333 85361 85363 85369 85381 85411 85427 85429 85439 85447 85451 85453 85469 85487 85513 85517 85523 85531 85549 85571 85577 85597 85601 85607 85619 85621 85627 85639 85643 85661 85667 85669 85691 85703 85711 85717 85733 85751 85781 85793 85817 85819 85829 85831 85837 85843 85847 85853 85889 85903 85909 85931 85933 85991 85999 86011 86017 86027 86029 86069 86077 86083 86111 86113 86117 86131 86137 86143 86161 86171 86179 86183 86197 86201 86209 86239 86243 86249 86257 86263 86269 86287 86291 86293 86297 86311 86323 86341 86351 86353 86357 86369 86371 86381 86389 86399 86413 86423 86441 86453 86461 86467 86477 86491 86501 86509 86531 86533 86539 86561 86573 86579 86587 86599 86627 86629 86677 86689 86693 86711 86719 86729 86743 86753 86767 86771 86783 86813 86837 86843 86851 86857 86861 86869 86923 86927 86929 86939 86951 86959 86969 86981 86993 87011 87013 87037 87041 87049 87071 87083 87103 87107 87119 87121 87133 87149 87151 87179 87181 87187 87211 87221 87223 87251 87253 87257 87277 87281 87293 87299 87313 87317 87323 87337 87359 87383 87403 87407 87421 87427 87433 87443 87473 87481 87491 87509 87511 87517 87523 87539 87541 87547 87553 87557 87559 87583 87587 87589 87613 87623 87629 87631 87641 87643 87649 87671 87679 87683 87691 87697 87701 87719 87721 87739 87743 87751 87767 87793 87797 87803 87811 87833 87853 87869 87877 87881 87887 87911 87917 87931 87943 87959 87961 87973 87977 87991 88001 88003 88007 88019 88037 88069 88079 88093 88117 88129 88169 88177 88211 88223 88237 88241 88259 88261 88289 88301 88321 88327 88337 88339 88379 88397 88411 88423 88427 88463 88469 88471 88493 88499 88513 88523 88547 88589 88591 88607 88609 88643 88651 88657 88661 88663 88667 88681 88721 88729 88741 88747 88771 88789 88793 88799 88801 88807 88811 88813 88817 88819 88843 88853 88861 88867 88873 88883 88897 88903 88919 88937 88951 88969 88993 88997 89003 89009 89017 89021 89041 89051 89057 89069 89071 89083 89087 89101 89107 89113 89119 89123 89137 89153 89189 89203 89209 89213 89227 89231 89237 89261 89269 89273 89293 89303 89317 89329 89363 89371 89381 89387 89393 89399 89413 89417 89431 89443 89449 89459 89477 89491 89501 89513 89519 89521 89527 89533 89561 89563 89567 89591 89597 89599 89603 89611 89627 89633 89653 89657 89659 89669 89671 89681 89689 89753 89759 89767 89779 89783 89797 89809 89819 89821 89833 89839 89849 89867 89891 89897 89899 89909 89917 89923 89939 89959 89963 89977 89983 89989 90001 90007 90011 90017 90019 90023 90031 90053 90059 90067 90071 90073 90089 90107 90121 90127 90149 90163 90173 90187 90191 90197 90199 90203 90217 90227 90239 90247 90263 90271 90281 90289 90313 90353 90359 90371 90373 90379 90397 90401 90403 90407 90437 90439 90469 90473 90481 90499 90511 90523 90527 90529 90533 90547 90583 90599 90617 90619 90631 90641 90647 90659 90677 90679 90697 90703 90709 90731 90749 90787 90793 90803 90821 90823 90833 90841 90847 90863 90887 90901 90907 90911 90917 90931 90947 90971 90977 90989 90997 91009 91019 91033 91079 91081 91097 91099 91121 91127 91129 91139 91141 91151 91153 91159 91163 91183 91193 91199 91229 91237 91243 91249 91253 91283 91291 91297 91303 91309 91331 91367 91369 91373 91381 91387 91393 91397 91411 91423 91433 91453 91457 91459 91463 91493 91499 91513 91529 91541 91571 91573 91577 91583 91591 91621 91631 91639 91673 91691 91703 91711 91733 91753 91757 91771 91781 91801 91807 91811 91813 91823 91837 91841 91867 91873 91909 91921 91939 91943 91951 91957 91961 91967 91969 91997 92003 92009 92033 92041 92051 92077 92083 92107 92111 92119 92143 92153 92173 92177 92179 92189 92203 92219 92221 92227 92233 92237 92243 92251 92269 92297 92311 92317 92333 92347 92353 92357 92363 92369 92377 92381 92383 92387 92399 92401 92413 92419 92431 92459 92461 92467 92479 92489 92503 92507 92551 92557 92567 92569 92581 92593 92623 92627 92639 92641 92647 92657 92669 92671 92681 92683 92693 92699 92707 92717 92723 92737 92753 92761 92767 92779 92789 92791 92801 92809 92821 92831 92849 92857 92861 92863 92867 92893 92899 92921 92927 92941 92951 92957 92959 92987 92993 93001 93047 93053 93059 93077 93083 93089 93097 93103 93113 93131 93133 93139 93151 93169 93179 93187 93199 93229 93239 93241 93251 93253 93257 93263 93281 93283 93287 93307 93319 93323 93329 93337 93371 93377 93383 93407 93419 93427 93463 93479 93481 93487 93491 93493 93497 93503 93523 93529 93553 93557 93559 93563 93581 93601 93607 93629 93637 93683 93701 93703 93719 93739 93761 93763 93787 93809 93811 93827 93851 93871 93887 93889 93893 93901 93911 93913 93923 93937 93941 93949 93967 93971 93979 93983 93997 94007 94009 94033 94049 94057 94063 94079 94099 94109 94111 94117 94121 94151 94153 94169 94201 94207 94219 94229 94253 94261 94273 94291 94307 94309 94321 94327 94331 94343 94349 94351 94379 94397 94399 94421 94427 94433 94439 94441 94447 94463 94477 94483 94513 94529 94531 94541 94543 94547 94559 94561 94573 94583 94597 94603 94613 94621 94649 94651 94687 94693 94709 94723 94727 94747 94771 94777 94781 94789 94793 94811 94819 94823 94837 94841 94847 94849 94873 94889 94903 94907 94933 94949 94951 94961 94993 94999 95003 95009 95021 95027 95063 95071 95083 95087 95089 95093 95101 95107 95111 95131 95143 95153 95177 95189 95191 95203 95213 95219 95231 95233 95239 95257 95261 95267 95273 95279 95287 95311 95317 95327 95339 95369 95383 95393 95401 95413 95419 95429 95441 95443 95461 95467 95471 95479 95483 95507 95527 95531 95539 95549 95561 95569 95581 95597 95603 95617 95621 95629 95633 95651 95701 95707 95713 95717 95723 95731 95737 95747 95773 95783 95789 95791 95801 95803 95813 95819 95857 95869 95873 95881 95891 95911 95917 95923 95929 95947 95957 95959 95971 95987 95989 96001 96013 96017 96043 96053 96059 96079 96097 96137 96149 96157 96167 96179 96181 96199 96211 96221 96223 96233 96259 96263 96269 96281 96289 96293 96323 96329 96331 96337 96353 96377 96401 96419 96431 96443 96451 96457 96461 96469 96479 96487 96493 96497 96517 96527 96553 96557 96581 96587 96589 96601 96643 96661 96667 96671 96697 96703 96731 96737 96739 96749 96757 96763 96769 96779 96787 96797 96799 96821 96823 96827 96847 96851 96857 96893 96907 96911 96931 96953 96959 96973 96979 96989 96997 97001 97003 97007 97021 97039 97073 97081 97103 97117 97127 97151 97157 97159 97169 97171 97177 97187 97213 97231 97241 97259 97283 97301 97303 97327 97367 97369 97373 97379 97381 97387 97397 97423 97429 97441 97453 97459 97463 97499 97501 97511 97523 97547 97549 97553 97561 97571 97577 97579 97583 97607 97609 97613 97649 97651 97673 97687 97711 97729 97771 97777 97787 97789 97813 97829 97841 97843 97847 97849 97859 97861 97871 97879 97883 97919 97927 97931 97943 97961 97967 97973 97987 98009 98011 98017 98041 98047 98057 98081 98101 98123 98129 98143 98179 98207 98213 98221 98227 98251 98257 98269 98297 98299 98317 98321 98323 98327 98347 98369 98377 98387 98389 98407 98411 98419 98429 98443 98453 98459 98467 98473 98479 98491 98507 98519 98533 98543 98561 98563 98573 98597 98621 98627 98639 98641 98663 98669 98689 98711 98713 98717 98729 98731 98737 98773 98779 98801 98807 98809 98837 98849 98867 98869 98873 98887 98893 98897 98899 98909 98911 98927 98929 98939 98947 98953 98963 98981 98993 98999 99013 99017 99023 99041 99053 99079 99083 99089 99103 99109 99119 99131 99133 99137 99139 99149 99173 99181 99191 99223 99233 99241 99251 99257 99259 99277 99289 99317 99347 99349 99367 99371 99377 99391 99397 99401 99409 99431 99439 99469 99487 99497 99523 99527 99529 99551 99559 99563 99571 99577 99581 99607 99611 99623 99643 99661 99667 99679 99689 99707 99709 99713 99719 99721 99733 99761 99767 99787 99793 99809 99817 99823 99829 99833 99839 99859 99871 99877 99881 99901 99907 99923 99929 99961 99971 99989 99991 100003 100019 100043 100049 100057 100069 100103 100109 100129 100151 100153 100169 100183 100189 100193 100207 100213 100237 100267 100271 100279 100291 100297 100313 100333 100343 100357 100361 100363 100379 100391 100393 100403 100411 100417 100447 100459 100469 100483 100493 100501 100511 100517 100519 100523 100537 100547 100549 100559 100591 100609 100613 100621 100649 100669 100673 100693 100699 100703 100733 100741 100747 100769 100787 100799 100801 100811 100823 100829 100847 100853 100907 100913 100927 100931 100937 100943 100957 100981 100987 100999 101009 101021 101027 101051 101063 101081 101089 101107 101111 101113 101117 101119 101141 101149 101159 101161 101173 101183 101197 101203 101207 101209 101221 101267 101273 101279 101281 101287 101293 101323 101333 101341 101347 101359 101363 101377 101383 101399 101411 101419 101429 101449 101467 101477 101483 101489 101501 101503 101513 101527 101531 101533 101537 101561 101573 101581 101599 101603 101611 101627 101641 101653 101663 101681 101693 101701 101719 101723 101737 101741 101747 101749 101771 101789 101797 101807 101833 101837 101839 101863 101869 101873 101879 101891 101917 101921 101929 101939 101957 101963 101977 101987 101999 102001 102013 102019 102023 102031 102043 102059 102061 102071 102077 102079 102101 102103 102107 102121 102139 102149 102161 102181 102191 102197 102199 102203 102217 102229 102233 102241 102251 102253 102259 102293 102299 102301 102317 102329 102337 102359 102367 102397 102407 102409 102433 102437 102451 102461 102481 102497 102499 102503 102523 102533 102539 102547 102551 102559 102563 102587 102593 102607 102611 102643 102647 102653 102667 102673 102677 102679 102701 102761 102763 102769 102793 102797 102811 102829 102841 102859 102871 102877 102881 102911 102913 102929 102931 102953 102967 102983 103001 103007 103043 103049 103067 103069 103079 103087 103091 103093 103099 103123 103141 103171 103177 103183 103217 103231 103237 103289 103291 103307 103319 103333 103349 103357 103387 103391 103393 103399 103409 103421 103423 103451 103457 103471 103483 103511 103529 103549 103553 103561 103567 103573 103577 103583 103591 103613 103619 103643 103651 103657 103669 103681 103687 103699 103703 103723 103769 103787 103801 103811 103813 103837 103841 103843 103867 103889 103903 103913 103919 103951 103963 103967 103969 103979 103981 103991 103993 103997 104003 104009 104021 104033 104047 104053 104059 104087 104089 104107 104113 104119 104123 104147 104149 104161 104173 104179 104183 104207 104231 104233 104239 104243 104281 104287 104297 104309 104311 104323 104327 104347 104369 104381 104383 104393 104399 104417 104459 104471 104473 104479 104491 104513 104527 104537 104543 104549 104551 104561 104579 104593 104597 104623 104639 104651 104659 104677 104681 104683 104693 104701 104707 104711 104717 104723 104729 104743 104759 104761 104773 104779 104789 104801 104803 104827 104831 104849 104851 104869 104879 104891 104911 104917 104933 104947 104953 104959 104971 104987 104999 105019 105023 105031 105037 105071 105097 105107 105137 105143 105167 105173 105199 105211 105227 105229 105239 105251 105253 105263 105269 105277 105319 105323 105331 105337 105341 105359 105361 105367 105373 105379 105389 105397 105401 105407 105437 105449 105467 105491 105499 105503 105509 105517 105527 105529 105533 105541 105557 105563 105601 105607 105613 105619 105649 105653 105667 105673 105683 105691 105701 105727 105733 105751 105761 105767 105769 105817 105829 105863 105871 105883 105899 105907 105913 105929 105943 105953 105967 105971 105977 105983 105997 106013 106019 106031 106033 106087 106103 106109 106121 106123 106129 106163 106181 106187 106189 106207 106213 106217 106219 106243 106261 106273 106277 106279 106291 106297 106303 106307 106319 106321 106331 106349 106357 106363 106367 106373 106391 106397 106411 106417 106427 106433 106441 106451 106453 106487 106501 106531 106537 106541 106543 106591 106619 106621 106627 106637 106649 106657 106661 106663 106669 106681 106693 106699 106703 106721 106727 106739 106747 106751 106753 106759 106781 106783 106787 106801 106823 106853 106859 106861 106867 106871 106877 106903 106907 106921 106937 106949 106957 106961 106963 106979 106993 107021 107033 107053 107057 107069 107071 107077 107089 107099 107101 107119 107123 107137 107171 107183 107197 107201 107209 107227 107243 107251 107269 107273 107279 107309 107323 107339 107347 107351 107357 107377 107441 107449 107453 107467 107473 107507 107509 107563 107581 107599 107603 107609 107621 107641 107647 107671 107687 107693 107699 107713 107717 107719 107741 107747 107761 107773 107777 107791 107827 107837 107839 107843 107857 107867 107873 107881 107897 107903 107923 107927 107941 107951 107971 107981 107999 108007 108011 108013 108023 108037 108041 108061 108079 108089 108107 108109 108127 108131 108139 108161 108179 108187 108191 108193 108203 108211 108217 108223 108233 108247 108263 108271 108287 108289 108293 108301 108343 108347 108359 108377 108379 108401 108413 108421 108439 108457 108461 108463 108497 108499 108503 108517 108529 108533 108541 108553 108557 108571 108587 108631 108637 108643 108649 108677 108707 108709 108727 108739 108751 108761 108769 108791 108793 108799 108803 108821 108827 108863 108869 108877 108881 108883 108887 108893 108907 108917 108923 108929 108943 108947 108949 108959 108961 108967 108971 108991 109001 109013 109037 109049 109063 109073 109097 109103 109111 109121 109133 109139 109141 109147 109159 109169 109171 109199 109201 109211 109229 109253 109267 109279 109297 109303 109313 109321 109331 109357 109363 109367 109379 109387 109391 109397 109423 109433 109441 109451 109453 109469 109471 109481 109507 109517 109519 109537 109541 109547 109567 109579 109583 109589 109597 109609 109619 109621 109639 109661 109663 109673 109717 109721 109741 109751 109789 109793 109807 109819 109829 109831 109841 109843 109847 109849 109859 109873 109883 109891 109897 109903 109913 109919 109937 109943 109961 109987 110017 110023 110039 110051 110059 110063 110069 110083 110119 110129 110161 110183 110221 110233 110237 110251 110261 110269 110273 110281 110291 110311 110321 110323 110339 110359 110419 110431 110437 110441 110459 110477 110479 110491 110501 110503 110527 110533 110543 110557 110563 110567 110569 110573 110581 110587 110597 110603 110609 110623 110629 110641 110647 110651 110681 110711 110729 110731 110749 110753 110771 110777 110807 110813 110819 110821 110849 110863 110879 110881 110899 110909 110917 110921 110923 110927 110933 110939 110947 110951 110969 110977 110989 111029 111031 111043 111049 111053 111091 111103 111109 111119 111121 111127 111143 111149 111187 111191 111211 111217 111227 111229 111253 111263 111269 111271 111301 111317 111323 111337 111341 111347 111373 111409 111427 111431 111439 111443 111467 111487 111491 111493 111497 111509 111521 111533 111539 111577 111581 111593 111599 111611 111623 111637 111641 111653 111659 111667 111697 111721 111731 111733 111751 111767 111773 111779 111781 111791 111799 111821 111827 111829 111833 111847 111857 111863 111869 111871 111893 111913 111919 111949 111953 111959 111973 111977 111997 112019 112031 112061 112067 112069 112087 112097 112103 112111 112121 112129 112139 112153 112163 112181 112199 112207 112213 112223 112237 112241 112247 112249 112253 112261 112279 112289 112291 112297 112303 112327 112331 112337 112339 112349 112361 112363 112397 112403 112429 112459 112481 112501 112507 112543 112559 112571 112573 112577 112583 112589 112601 112603 112621 112643 112657 112663 112687 112691 112741 112757 112759 112771 112787 112799 112807 112831 112843 112859 112877 112901 112909 112913 112919 112921 112927 112939 112951 112967 112979 112997 113011 113017 113021 113023 113027 113039 113041 113051 113063 113081 113083 113089 113093 113111 113117 113123 113131 113143 113147 113149 113153 113159 113161 113167 113171 113173 113177 113189 113209 113213 113227 113233 113279 113287 113327 113329 113341 113357 113359 113363 113371 113381 113383 113417 113437 113453 113467 113489 113497 113501 113513 113537 113539 113557 113567 113591 113621 113623 113647 113657 113683 113717 113719 113723 113731 113749 113759 113761 113777 113779 113783 113797 113809 113819 113837 113843 113891 113899 113903 113909 113921 113933 113947 113957 113963 113969 113983 113989 114001 114013 114031 114041 114043 114067 114073 114077 114083 114089 114113 114143 114157 114161 114167 114193 114197 114199 114203 114217 114221 114229 114259 114269 114277 114281 114299 114311 114319 114329 114343 114371 114377 114407 114419 114451 114467 114473 114479 114487 114493 114547 114553 114571 114577 114593 114599 114601 114613 114617 114641 114643 114649 114659 114661 114671 114679 114689 114691 114713 114743 114749 114757 114761 114769 114773 114781 114797 114799 114809 114827 114833 114847 114859 114883 114889 114901 114913 114941 114967 114973 114997 115001 115013 115019 115021 115057 115061 115067 115079 115099 115117 115123 115127 115133 115151 115153 115163 115183 115201 115211 115223 115237 115249 115259 115279 115301 115303 115309 115319 115321 115327 115331 115337 115343 115361 115363 115399 115421 115429 115459 115469 115471 115499 115513 115523 115547 115553 115561 115571 115589 115597 115601 115603 115613 115631 115637 115657 115663 115679 115693 115727 115733 115741 115751 115757 115763 115769 115771 115777 115781 115783 115793 115807 115811 115823 115831 115837 115849 115853 115859 115861 115873 115877 115879 115883 115891 115901 115903 115931 115933 115963 115979 115981 115987 116009 116027 116041 116047 116089 116099 116101 116107 116113 116131 116141 116159 116167 116177 116189 116191 116201 116239 116243 116257 116269 116273 116279 116293 116329 116341 116351 116359 116371 116381 116387 116411 116423 116437 116443 116447 116461 116471 116483 116491 116507 116531 116533 116537 116539 116549 116579 116593 116639 116657 116663 116681 116687 116689 116707 116719 116731 116741 116747 116789 116791 116797 116803 116819 116827 116833 116849 116867 116881 116903 116911 116923 116927 116929 116933 116953 116959 116969 116981 116989 116993 117017 117023 117037 117041 117043 117053 117071 117101 117109 117119 117127 117133 117163 117167 117191 117193 117203 117209 117223 117239 117241 117251 117259 117269 117281 117307 117319 117329 117331 117353 117361 117371 117373 117389 117413 117427 117431 117437 117443 117497 117499 117503 117511 117517 117529 117539 117541 117563 117571 117577 117617 117619 117643 117659 117671 117673 117679 117701 117703 117709 117721 117727 117731 117751 117757 117763 117773 117779 117787 117797 117809 117811 117833 117839 117841 117851 117877 117881 117883 117889 117899 117911 117917 117937 117959 117973 117977 117979 117989 117991 118033 118037 118043 118051 118057 118061 118081 118093 118127 118147 118163 118169 118171 118189 118211 118213 118219 118247 118249 118253 118259 118273 118277 118297 118343 118361 118369 118373 118387 118399 118409 118411 118423 118429 118453 118457 118463 118471 118493 118529 118543 118549 118571 118583 118589 118603 118619 118621 118633 118661 118669 118673 118681 118687 118691 118709 118717 118739 118747 118751 118757 118787 118799 118801 118819 118831 118843 118861 118873 118891 118897 118901 118903 118907 118913 118927 118931 118967 118973 119027 119033 119039 119047 119057 119069 119083 119087 119089 119099 119101 119107 119129 119131 119159 119173 119179 119183 119191 119227 119233 119237 119243 119267 119291 119293 119297 119299 119311 119321 119359 119363 119389 119417 119419 119429 119447 119489 119503 119513 119533 119549 119551 119557 119563 119569 119591 119611 119617 119627 119633 119653 119657 119659 119671 119677 119687 119689 119699 119701 119723 119737 119747 119759 119771 119773 119783 119797 119809 119813 119827 119831 119839 119849 119851 119869 119881 119891 119921 119923 119929 119953 119963 119971 119981 119983 119993 120011 120017 120041 120047 120049 120067 120077 120079 120091 120097 120103 120121 120157 120163 120167 120181 120193 120199 120209 120223 120233 120247 120277 120283 120293 120299 120319 120331 120349 120371 120383 120391 120397 120401 120413 120427 120431 120473 120503 120511 120539 120551 120557 120563 120569 120577 120587 120607 120619 120623 120641 120647 120661 120671 120677 120689 120691 120709 120713 120721 120737 120739 120749 120763 120767 120779 120811 120817 120823 120829 120833 120847 120851 120863 120871 120877 120889 120899 120907 120917 120919 120929 120937 120941 120943 120947 120977 120997 121001 121007 121013 121019 121021 121039 121061 121063 121067 121081 121123 121139 121151 121157 121169 121171 121181 121189 121229 121259 121267 121271 121283 121291 121309 121313 121321 121327 121333 121343 121349 121351 121357 121367 121369 121379 121403 121421 121439 121441 121447 121453 121469 121487 121493 121501 121507 121523 121531 121547 121553 121559 121571 121577 121579 121591 121607 121609 121621 121631 121633 121637 121661 121687 121697 121711 121721 121727 121763 121787 121789 121843 121853 121867 121883 121889 121909 121921 121931 121937 121949 121951 121963 121967 121993 121997 122011 122021 122027 122029 122033 122039 122041 122051 122053 122069 122081 122099 122117 122131 122147 122149 122167 122173 122201 122203 122207 122209 122219 122231 122251 122263 122267 122273 122279 122299 122321 122323 122327 122347 122363 122387 122389 122393 122399 122401 122443 122449 122453 122471 122477 122489 122497 122501 122503 122509 122527 122533 122557 122561 122579 122597 122599 122609 122611 122651 122653 122663 122693 122701 122719 122741 122743 122753 122761 122777 122789 122819 122827 122833 122839 122849 122861 122867 122869 122887 122891 122921 122929 122939 122953 122957 122963 122971 123001 123007 123017 123031 123049 123059 123077 123083 123091 123113 123121 123127 123143 123169 123191 123203 123209 123217 123229 123239 123259 123269 123289 123307 123311 123323 123341 123373 123377 123379 123397 123401 123407 123419 123427 123433 123439 123449 123457 123479 123491 123493 123499 123503 123517 123527 123547 123551 123553 123581 123583 123593 123601 123619 123631 123637 123653 123661 123667 123677 123701 123707 123719 123727 123731 123733 123737 123757 123787 123791 123803 123817 123821 123829 123833 123853 123863 123887 123911 123923 123931 123941 123953 123973 123979 123983 123989 123997 124001 124021 124067 124087 124097 124121 124123 124133 124139 124147 124153 124171 124181 124183 124193 124199 124213 124231 124247 124249 124277 124291 124297 124301 124303 124309 124337 124339 124343 124349 124351 124363 124367 124427 124429 124433 124447 124459 124471 124477 124489 124493 124513 124529 124541 124543 124561 124567 124577 124601 124633 124643 124669 124673 124679 124693 124699 124703 124717 124721 124739 124753 124759 124769 124771 124777 124781 124783 124793 124799 124819 124823 124847 124853 124897 124907 124909 124919 124951 124979 124981 124987 124991 125003 125017 125029 125053 125063 125093 125101 125107 125113 125117 125119 125131 125141 125149 125183 125197 125201 125207 125219 125221 125231 125243 125261 125269 125287 125299 125303 125311 125329 125339 125353 125371 125383 125387 125399 125407 125423 125429 125441 125453 125471 125497 125507 125509 125527 125539 125551 125591 125597 125617 125621 125627 125639 125641 125651 125659 125669 125683 125687 125693 125707 125711 125717 125731 125737 125743 125753 125777 125789 125791 125803 125813 125821 125863 125887 125897 125899 125921 125927 125929 125933 125941 125959 125963 126001 126011 126013 126019 126023 126031 126037 126041 126047 126067 126079 126097 126107 126127 126131 126143 126151 126173 126199 126211 126223 126227 126229 126233 126241 126257 126271 126307 126311 126317 126323 126337 126341 126349 126359 126397 126421 126433 126443 126457 126461 126473 126481 126487 126491 126493 126499 126517 126541 126547 126551 126583 126601 126611 126613 126631 126641 126653 126683 126691 126703 126713 126719 126733 126739 126743 126751 126757 126761 126781 126823 126827 126839 126851 126857 126859 126913 126923 126943 126949 126961 126967 126989 127031 127033 127037 127051 127079 127081 127103 127123 127133 127139 127157 127163 127189 127207 127217 127219 127241 127247 127249 127261 127271 127277 127289 127291 127297 127301 127321 127331 127343 127363 127373 127399 127403 127423 127447 127453 127481 127487 127493 127507 127529 127541 127549 127579 127583 127591 127597 127601 127607 127609 127637 127643 127649 127657 127663 127669 127679 127681 127691 127703 127709 127711 127717 127727 127733 127739 127747 127763 127781 127807 127817 127819 127837 127843 127849 127859 127867 127873 127877 127913 127921 127931 127951 127973 127979 127997 128021 128033 128047 128053 128099 128111 128113 128119 128147 128153 128159 128173 128189 128201 128203 128213 128221 128237 128239 128257 128273 128287 128291 128311 128321 128327 128339 128341 128347 128351 128377 128389 128393 128399 128411 128413 128431 128437 128449 128461 128467 128473 128477 128483 128489 128509 128519 128521 128549 128551 128563 128591 128599 128603 128621 128629 128657 128659 128663 128669 128677 128683 128693 128717 128747 128749 128761 128767 128813 128819 128831 128833 128837 128857 128861 128873 128879 128903 128923 128939 128941 128951 128959 128969 128971 128981 128983 128987 128993 129001 129011 129023 129037 129049 129061 129083 129089 129097 129113 129119 129121 129127 129169 129187 129193 129197 129209 129221 129223 129229 129263 129277 129281 129287 129289 129293 129313 129341 129347 129361 129379 129401 129403 129419 129439 129443 129449 129457 129461 129469 129491 129497 129499 129509 129517 129527 129529 129533 129539 129553 129581 129587 129589 129593 129607 129629 129631 129641 129643 129671 129707 129719 129733 129737 129749 129757 129763 129769 129793 129803 129841 129853 129887 129893 129901 129917 129919 129937 129953 129959 129967 129971 130003 130021 130027 130043 130051 130057 130069 130073 130079 130087 130099 130121 130127 130147 130171 130183 130199 130201 130211 130223 130241 130253 130259 130261 130267 130279 130303 130307 130337 130343 130349 130363 130367 130369 130379 130399 130409 130411 130423 130439 130447 130457 130469 130477 130483 130489 130513 130517 130523 130531 130547 130553 130579 130589 130619 130621 130631 130633 130639 130643 130649 130651 130657 130681 130687 130693 130699 130729 130769 130783 130787 130807 130811 130817 130829 130841 130843 130859 130873 130927 130957 130969 130973 130981 130987 131009 131011 131023 131041 131059 131063 131071 131101 131111 131113 131129 131143 131149 131171 131203 131213 131221 131231 131249 131251 131267 131293 131297 131303 131311 131317 131321 131357 131363 131371 131381 131413 131431 131437 131441 131447 131449 131477 131479 131489 131497 131501 131507 131519 131543 131561 131581 131591 131611 131617 131627 131639 131641 131671 131687 131701 131707 131711 131713 131731 131743 131749 131759 131771 131777 131779 131783 131797 131837 131839 131849 131861 131891 131893 131899 131909 131927 131933 131939 131941 131947 131959 131969 132001 132019 132047 132049 132059 132071 132103 132109 132113 132137 132151 132157 132169 132173 132199 132229 132233 132241 132247 132257 132263 132283 132287 132299 132313 132329 132331 132347 132361 132367 132371 132383 132403 132409 132421 132437 132439 132469 132491 132499 132511 132523 132527 132529 132533 132541 132547 132589 132607 132611 132619 132623 132631 132637 132647 132661 132667 132679 132689 132697 132701 132707 132709 132721 132739 132749 132751 132757 132761 132763 132817 132833 132851 132857 132859 132863 132887 132893 132911 132929 132947 132949 132953 132961 132967 132971 132989 133013 133033 133039 133051 133069 133073 133087 133097 133103 133109 133117 133121 133153 133157 133169 133183 133187 133201 133213 133241 133253 133261 133271 133277 133279 133283 133303 133319 133321 133327 133337 133349 133351 133379 133387 133391 133403 133417 133439 133447 133451 133481 133493 133499 133519 133541 133543 133559 133571 133583 133597 133631 133633 133649 133657 133669 133673 133691 133697 133709 133711 133717 133723 133733 133769 133781 133801 133811 133813 133831 133843 133853 133873 133877 133919 133949 133963 133967 133979 133981 133993 133999 134033 134039 134047 134053 134059 134077 134081 134087 134089 134093 134129 134153 134161 134171 134177 134191 134207 134213 134219 134227 134243 134257 134263 134269 134287 134291 134293 134327 134333 134339 134341 134353 134359 134363 134369 134371 134399 134401 134417 134437 134443 134471 134489 134503 134507 134513 134581 134587 134591 134593 134597 134609 134639 134669 134677 134681 134683 134699 134707 134731 134741 134753 134777 134789 134807 134837 134839 134851 134857 134867 134873 134887 134909 134917 134921 134923 134947 134951 134989 134999 135007 135017 135019 135029 135043 135049 135059 135077 135089 135101 135119 135131 135151 135173 135181 135193 135197 135209 135211 135221 135241 135257 135271 135277 135281 135283 135301 135319 135329 135347 135349 135353 135367 135389 135391 135403 135409 135427 135431 135433 135449 135461 135463 135467 135469 135479 135497 135511 135533 135559 135571 135581 135589 135593 135599 135601 135607 135613 135617 135623 135637 135647 135649 135661 135671 135697 135701 135719 135721 135727 135731 135743 135757 135781 135787 135799 135829 135841 135851 135859 135887 135893 135899 135911 135913 135929 135937 135977 135979 136013 136027 136033 136043 136057 136067 136069 136093 136099 136111 136133 136139 136163 136177 136189 136193 136207 136217 136223 136237 136247 136261 136273 136277 136303 136309 136319 136327 136333 136337 136343 136351 136361 136373 136379 136393 136397 136399 136403 136417 136421 136429 136447 136453 136463 136471 136481 136483 136501 136511 136519 136523 136531 136537 136541 136547 136559 136573 136601 136603 136607 136621 136649 136651 136657 136691 136693 136709 136711 136727 136733 136739 136751 136753 136769 136777 136811 136813 136841 136849 136859 136861 136879 136883 136889 136897 136943 136949 136951 136963 136973 136979 136987 136991 136993 136999 137029 137077 137087 137089 137117 137119 137131 137143 137147 137153 137177 137183 137191 137197 137201 137209 137219 137239 137251 137273 137279 137303 137321 137339 137341 137353 137359 137363 137369 137383 137387 137393 137399 137413 137437 137443 137447 137453 137477 137483 137491 137507 137519 137537 137567 137573 137587 137593 137597 137623 137633 137639 137653 137659 137699 137707 137713 137723 137737 137743 137771 137777 137791 137803 137827 137831 137849 137867 137869 137873 137909 137911 137927 137933 137941 137947 137957 137983 137993 137999 138007 138041 138053 138059 138071 138077 138079 138101 138107 138113 138139 138143 138157 138163 138179 138181 138191 138197 138209 138239 138241 138247 138251 138283 138289 138311 138319 138323 138337 138349 138371 138373 138389 138401 138403 138407 138427 138433 138449 138451 138461 138469 138493 138497 138511 138517 138547 138559 138563 138569 138571 138577 138581 138587 138599 138617 138629 138637 138641 138647 138661 138679 138683 138727 138731 138739 138763 138793 138797 138799 138821 138829 138841 138863 138869 138883 138889 138893 138899 138917 138923 138937 138959 138967 138977 139021 139033 139067 139079 139091 139109 139121 139123 139133 139169 139177 139187 139199 139201 139241 139267 139273 139291 139297 139301 139303 139309 139313 139333 139339 139343 139361 139367 139369 139387 139393 139397 139409 139423 139429 139439 139457 139459 139483 139487 139493 139501 139511 139537 139547 139571 139589 139591 139597 139609 139619 139627 139661 139663 139681 139697 139703 139709 139721 139729 139739 139747 139753 139759 139787 139801 139813 139831 139837 139861 139871 139883 139891 139901 139907 139921 139939 139943 139967 139969 139981 139987 139991 139999 140009 140053 140057 140069 140071 140111 140123 140143 140159 140167 140171 140177 140191 140197 140207 140221 140227 140237 140249 140263 140269 140281 140297 140317 140321 140333 140339 140351 140363 140381 140401 140407 140411 140417 140419 140423 140443 140449 140453 140473 140477 140521 140527 140533 140549 140551 140557 140587 140593 140603 140611 140617 140627 140629 140639 140659 140663 140677 140681 140683 140689 140717 140729 140731 140741 140759 140761 140773 140779 140797 140813 140827 140831 140837 140839 140863 140867 140869 140891 140893 140897 140909 140929 140939 140977 140983 140989 141023 141041 141061 141067 141073 141079 141101 141107 141121 141131 141157 141161 141179 141181 141199 141209 141221 141223 141233 141241 141257 141263 141269 141277 141283 141301 141307 141311 141319 141353 141359 141371 141397 141403 141413 141439 141443 141461 141481 141497 141499 141509 141511 141529 141539 141551 141587 141601 141613 141619 141623 141629 141637 141649 141653 141667 141671 141677 141679 141689 141697 141707 141709 141719 141731 141761 141767 141769 141773 141793 141803 141811 141829 141833 141851 141853 141863 141871 141907 141917 141931 141937 141941 141959 141961 141971 141991 142007 142019 142031 142039 142049 142057 142061 142067 142097 142099 142111 142123 142151 142157 142159 142169 142183 142189 142193 142211 142217 142223 142231 142237 142271 142297 142319 142327 142357 142369 142381 142391 142403 142421 142427 142433 142453 142469 142501 142529 142537 142543 142547 142553 142559 142567 142573 142589 142591 142601 142607 142609 142619 142657 142673 142697 142699 142711 142733 142757 142759 142771 142787 142789 142799 142811 142837 142841 142867 142871 142873 142897 142903 142907 142939 142949 142963 142969 142973 142979 142981 142993 143053 143063 143093 143107 143111 143113 143137 143141 143159 143177 143197 143239 143243 143249 143257 143261 143263 143281 143287 143291 143329 143333 143357 143387 143401 143413 143419 143443 143461 143467 143477 143483 143489 143501 143503 143509 143513 143519 143527 143537 143551 143567 143569 143573 143593 143609 143617 143629 143651 143653 143669 143677 143687 143699 143711 143719 143729 143743 143779 143791 143797 143807 143813 143821 143827 143831 143833 143873 143879 143881 143909 143947 143953 143971 143977 143981 143999 144013 144031 144037 144061 144071 144073 144103 144139 144161 144163 144167 144169 144173 144203 144223 144241 144247 144253 144259 144271 144289 144299 144307 144311 144323 144341 144349 144379 144383 144407 144409 144413 144427 144439 144451 144461 144479 144481 144497 144511 144539 144541 144563 144569 144577 144583 144589 144593 144611 144629 144659 144667 144671 144701 144709 144719 144731 144737 144751 144757 144763 144773 144779 144791 144817 144829 144839 144847 144883 144887 144889 144899 144917 144931 144941 144961 144967 144973 144983 145007 145009 145021 145031 145037 145043 145063 145069 145091 145109 145121 145133 145139 145177 145193 145207 145213 145219 145253 145259 145267 145283 145289 145303 145307 145349 145361 145381 145391 145399 145417 145423 145433 145441 145451 145459 145463 145471 145477 145487 145501 145511 145513 145517 145531 145543 145547 145549 145577 145589 145601 145603 145633 145637 145643 145661 145679 145681 145687 145703 145709 145721 145723 145753 145757 145759 145771 145777 145799 145807 145819 145823 145829 145861 145879 145897 145903 145931 145933 145949 145963 145967 145969 145987 145991 146009 146011 146021 146023 146033 146051 146057 146059 146063 146077 146093 146099 146117 146141 146161 146173 146191 146197 146203 146213 146221 146239 146249 146273 146291 146297 146299 146309 146317 146323 146347 146359 146369 146381 146383 146389 146407 146417 146423 146437 146449 146477 146513 146519 146521 146527 146539 146543 146563 146581 146603 146609 146617 146639 146647 146669 146677 146681 146683 146701 146719 146743 146749 146767 146777 146801 146807 146819 146833 146837 146843 146849 146857 146891 146893 146917 146921 146933 146941 146953 146977 146983 146987 146989 147011 147029 147031 147047 147073 147083 147089 147097 147107 147137 147139 147151 147163 147179 147197 147209 147211 147221 147227 147229 147253 147263 147283 147289 147293 147299 147311 147319 147331 147341 147347 147353 147377 147391 147397 147401 147409 147419 147449 147451 147457 147481 147487 147503 147517 147541 147547 147551 147557 147571 147583 147607 147613 147617 147629 147647 147661 147671 147673 147689 147703 147709 147727 147739 147743 147761 147769 147773 147779 147787 147793 147799 147811 147827 147853 147859 147863 147881 147919 147937 147949 147977 147997 148013 148021 148061 148063 148073 148079 148091 148123 148139 148147 148151 148153 148157 148171 148193 148199 148201 148207 148229 148243 148249 148279 148301 148303 148331 148339 148361 148367 148381 148387 148399 148403 148411 148429 148439 148457 148469 148471 148483 148501 148513 148517 148531 148537 148549 148573 148579 148609 148627 148633 148639 148663 148667 148669 148691 148693 148711 148721 148723 148727 148747 148763 148781 148783 148793 148817 148829 148853 148859 148861 148867 148873 148891 148913 148921 148927 148931 148933 148949 148957 148961 148991 148997 149011 149021 149027 149033 149053 149057 149059 149069 149077 149087 149099 149101 149111 149113 149119 149143 149153 149159 149161 149173 149183 149197 149213 149239 149249 149251 149257 149269 149287 149297 149309 149323 149333 149341 149351 149371 149377 149381 149393 149399 149411 149417 149419 149423 149441 149459 149489 149491 149497 149503 149519 149521 149531 149533 149543 149551 149561 149563 149579 149603 149623 149627 149629 149689 149711 149713 149717 149729 149731 149749 149759 149767 149771 149791 149803 149827 149837 149839 149861 149867 149873 149893 149899 149909 149911 149921 149939 149953 149969 149971 149993 150001 150011 150041 150053 150061 150067 150077 150083 150089 150091 150097 150107 150131 150151 150169 150193 150197 150203 150209 150211 150217 150221 150223 150239 150247 150287 150299 150301 150323 150329 150343 150373 150377 150379 150383 150401 150407 150413 150427 150431 150439 150473 150497 150503 150517 150523 150533 150551 150559 150571 150583 150587 150589 150607 150611 150617 150649 150659 150697 150707 150721 150743 150767 150769 150779 150791 150797 150827 150833 150847 150869 150881 150883 150889 150893 150901 150907 150919 150929 150959 150961 150967 150979 150989 150991 151007 151009 151013 151027 151049 151051 151057 151091 151121 151141 151153 151157 151163 151169 151171 151189 151201 151213 151237 151241 151243 151247 151253 151273 151279 151289 151303 151337 151339 151343 151357 151379 151381 151391 151397 151423 151429 151433 151451 151471 151477 151483 151499 151507 151517 151523 151531 151537 151549 151553 151561 151573 151579 151597 151603 151607 151609 151631 151637 151643 151651 151667 151673 151681 151687 151693 151703 151717 151729 151733 151769 151771 151783 151787 151799 151813 151817 151841 151847 151849 151871 151883 151897 151901 151903 151909 151937 151939 151967 151969 152003 152017 152027 152029 152039 152041 152063 152077 152081 152083 152093 152111 152123 152147 152183 152189 152197 152203 152213 152219 152231 152239 152249 152267 152287 152293 152297 152311 152363 152377 152381 152389 152393 152407 152417 152419 152423 152429 152441 152443 152459 152461 152501 152519 152531 152533 152539 152563 152567 152597 152599 152617 152623 152629 152639 152641 152657 152671 152681 152717 152723 152729 152753 152767 152777 152783 152791 152809 152819 152821 152833 152837 152839 152843 152851 152857 152879 152897 152899 152909 152939 152941 152947 152953 152959 152981 152989 152993 153001 153059 153067 153071 153073 153077 153089 153107 153113 153133 153137 153151 153191 153247 153259 153269 153271 153277 153281 153287 153313 153319 153337 153343 153353 153359 153371 153379 153407 153409 153421 153427 153437 153443 153449 153457 153469 153487 153499 153509 153511 153521 153523 153529 153533 153557 153563 153589 153607 153611 153623 153641 153649 153689 153701 153719 153733 153739 153743 153749 153757 153763 153817 153841 153871 153877 153887 153889 153911 153913 153929 153941 153947 153949 153953 153991 153997 154001 154027 154043 154057 154061 154067 154073 154079 154081 154087 154097 154111 154127 154153 154157 154159 154181 154183 154211 154213 154229 154243 154247 154267 154277 154279 154291 154303 154313 154321 154333 154339 154351 154369 154373 154387 154409 154417 154423 154439 154459 154487 154493 154501 154523 154543 154571 154573 154579 154589 154591 154613 154619 154621 154643 154667 154669 154681 154691 154699 154723 154727 154733 154747 154753 154769 154787 154789 154799 154807 154823 154841 154849 154871 154873 154877 154883 154897 154927 154933 154937 154943 154981 154991 155003 155009 155017 155027 155047 155069 155081 155083 155087 155119 155137 155153 155161 155167 155171 155191 155201 155203 155209 155219 155231 155251 155269 155291 155299 155303 155317 155327 155333 155371 155377 155381 155383 155387 155399 155413 155423 155443 155453 155461 155473 155501 155509 155521 155537 155539 155557 155569 155579 155581 155593 155599 155609 155621 155627 155653 155657 155663 155671 155689 155693 155699 155707 155717 155719 155723 155731 155741 155747 155773 155777 155783 155797 155801 155809 155821 155833 155849 155851 155861 155863 155887 155891 155893 155921 156007 156011 156019 156041 156059 156061 156071 156089 156109 156119 156127 156131 156139 156151 156157 156217 156227 156229 156241 156253 156257 156259 156269 156307 156319 156329 156347 156353 156361 156371 156419 156421 156437 156467 156487 156491 156493 156511 156521 156539 156577 156589 156593 156601 156619 156623 156631 156641 156659 156671 156677 156679 156683 156691 156703 156707 156719 156727 156733 156749 156781 156797 156799 156817 156823 156833 156841 156887 156899 156901 156913 156941 156943 156967 156971 156979 157007 157013 157019 157037 157049 157051 157057 157061 157081 157103 157109 157127 157133 157141 157163 157177 157181 157189 157207 157211 157217 157219 157229 157231 157243 157247 157253 157259 157271 157273 157277 157279 157291 157303 157307 157321 157327 157349 157351 157363 157393 157411 157427 157429 157433 157457 157477 157483 157489 157513 157519 157523 157543 157559 157561 157571 157579 157627 157637 157639 157649 157667 157669 157679 157721 157733 157739 157747 157769 157771 157793 157799 157813 157823 157831 157837 157841 157867 157877 157889 157897 157901 157907 157931 157933 157951 157991 157999 158003 158009 158017 158029 158047 158071 158077 158113 158129 158141 158143 158161 158189 158201 158209 158227 158231 158233 158243 158261 158269 158293 158303 158329 158341 158351 158357 158359 158363 158371 158393 158407 158419 158429 158443 158449 158489 158507 158519 158527 158537 158551 158563 158567 158573 158581 158591 158597 158611 158617 158621 158633 158647 158657 158663 158699 158731 158747 158749 158759 158761 158771 158777 158791 158803 158843 158849 158863 158867 158881 158909 158923 158927 158941 158959 158981 158993 159013 159017 159023 159059 159073 159079 159097 159113 159119 159157 159161 159167 159169 159179 159191 159193 159199 159209 159223 159227 159233 159287 159293 159311 159319 159337 159347 159349 159361 159389 159403 159407 159421 159431 159437 159457 159463 159469 159473 159491 159499 159503 159521 159539 159541 159553 159563 159569 159571 159589 159617 159623 159629 159631 159667 159671 159673 159683 159697 159701 159707 159721 159737 159739 159763 159769 159773 159779 159787 159791 159793 159799 159811 159833 159839 159853 159857 159869 159871 159899 159911 159931 159937 159977 159979 160001 160009 160019 160031 160033 160049 160073 160079 160081 160087 160091 160093 160117 160141 160159 160163 160169 160183 160201 160207 160217 160231 160243 160253 160309 160313 160319 160343 160357 160367 160373 160387 160397 160403 160409 160423 160441 160453 160481 160483 160499 160507 160541 160553 160579 160583 160591 160603 160619 160621 160627 160637 160639 160649 160651 160663 160669 160681 160687 160697 160709 160711 160723 160739 160751 160753 160757 160781 160789 160807 160813 160817 160829 160841 160861 160877 160879 160883 160903 160907 160933 160967 160969 160981 160997 161009 161017 161033 161039 161047 161053 161059 161071 161087 161093 161123 161137 161141 161149 161159 161167 161201 161221 161233 161237 161263 161267 161281 161303 161309 161323 161333 161339 161341 161363 161377 161387 161407 161411 161453 161459 161461 161471 161503 161507 161521 161527 161531 161543 161561 161563 161569 161573 161591 161599 161611 161627 161639 161641 161659 161683 161717 161729 161731 161741 161743 161753 161761 161771 161773 161779 161783 161807 161831 161839 161869 161873 161879 161881 161911 161921 161923 161947 161957 161969 161971 161977 161983 161999 162007 162011 162017 162053 162059 162079 162091 162109 162119 162143 162209 162221 162229 162251 162257 162263 162269 162277 162287 162289 162293 162343 162359 162389 162391 162413 162419 162439 162451 162457 162473 162493 162499 162517 162523 162527 162529 162553 162557 162563 162577 162593 162601 162611 162623 162629 162641 162649 162671 162677 162683 162691 162703 162709 162713 162727 162731 162739 162749 162751 162779 162787 162791 162821 162823 162829 162839 162847 162853 162859 162881 162889 162901 162907 162917 162937 162947 162971 162973 162989 162997 163003 163019 163021 163027 163061 163063 163109 163117 163127 163129 163147 163151 163169 163171 163181 163193 163199 163211 163223 163243 163249 163259 163307 163309 163321 163327 163337 163351 163363 163367 163393 163403 163409 163411 163417 163433 163469 163477 163481 163483 163487 163517 163543 163561 163567 163573 163601 163613 163621 163627 163633 163637 163643 163661 163673 163679 163697 163729 163733 163741 163753 163771 163781 163789 163811 163819 163841 163847 163853 163859 163861 163871 163883 163901 163909 163927 163973 163979 163981 163987 163991 163993 163997 164011 164023 164039 164051 164057 164071 164089 164093 164113 164117 164147 164149 164173 164183 164191 164201 164209 164231 164233 164239 164249 164251 164267 164279 164291 164299 164309 164321 164341 164357 164363 164371 164377 164387 164413 164419 164429 164431 164443 164447 164449 164471 164477 164503 164513 164531 164569 164581 164587 164599 164617 164621 164623 164627 164653 164663 164677 164683 164701 164707 164729 164743 164767 164771 164789 164809 164821 164831 164837 164839 164881 164893 164911 164953 164963 164987 164999 165001 165037 165041 165047 165049 165059 165079 165083 165089 165103 165133 165161 165173 165181 165203 165211 165229 165233 165247 165287 165293 165311 165313 165317 165331 165343 165349 165367 165379 165383 165391 165397 165437 165443 165449 165457 165463 165469 165479 165511 165523 165527 165533 165541 165551 165553 165559 165569 165587 165589 165601 165611 165617 165653 165667 165673 165701 165703 165707 165709 165713 165719 165721 165749 165779 165799 165811 165817 165829 165833 165857 165877 165883 165887 165901 165931 165941 165947 165961 165983 166013 166021 166027 166031 166043 166063 166081 166099 166147 166151 166157 166169 166183 166189 166207 166219 166237 166247 166259 166273 166289 166297 166301 166303 166319 166349 166351 166357 166363 166393 166399 166403 166409 166417 166429 166457 166471 166487 166541 166561 166567 166571 166597 166601 166603 166609 166613 166619 166627 166631 166643 166657 166667 166669 166679 166693 166703 166723 166739 166741 166781 166783 166799 166807 166823 166841 166843 166847 166849 166853 166861 166867 166871 166909 166919 166931 166949 166967 166973 166979 166987 167009 167017 167021 167023 167033 167039 167047 167051 167071 167077 167081 167087 167099 167107 167113 167117 167119 167149 167159 167173 167177 167191 167197 167213 167221 167249 167261 167267 167269 167309 167311 167317 167329 167339 167341 167381 167393 167407 167413 167423 167429 167437 167441 167443 167449 167471 167483 167491 167521 167537 167543 167593 167597 167611 167621 167623 167627 167633 167641 167663 167677 167683 167711 167729 167747 167759 167771 167777 167779 167801 167809 167861 167863 167873 167879 167887 167891 167899 167911 167917 167953 167971 167987 168013 168023 168029 168037 168043 168067 168071 168083 168089 168109 168127 168143 168151 168193 168197 168211 168227 168247 168253 168263 168269 168277 168281 168293 168323 168331 168347 168353 168391 168409 168433 168449 168451 168457 168463 168481 168491 168499 168523 168527 168533 168541 168559 168599 168601 168617 168629 168631 168643 168673 168677 168697 168713 168719 168731 168737 168743 168761 168769 168781 168803 168851 168863 168869 168887 168893 168899 168901 168913 168937 168943 168977 168991 169003 169007 169009 169019 169049 169063 169067 169069 169079 169093 169097 169111 169129 169151 169159 169177 169181 169199 169217 169219 169241 169243 169249 169259 169283 169307 169313 169319 169321 169327 169339 169343 169361 169369 169373 169399 169409 169427 169457 169471 169483 169489 169493 169501 169523 169531 169553 169567 169583 169591 169607 169627 169633 169639 169649 169657 169661 169667 169681 169691 169693 169709 169733 169751 169753 169769 169777 169783 169789 169817 169823 169831 169837 169843 169859 169889 169891 169909 169913 169919 169933 169937 169943 169951 169957 169987 169991 170003 170021 170029 170047 170057 170063 170081 170099 170101 170111 170123 170141 170167 170179 170189 170197 170207 170213 170227 170231 170239 170243 170249 170263 170267 170279 170293 170299 170327 170341 170347 170351 170353 170363 170369 170371 170383 170389 170393 170413 170441 170447 170473 170483 170497 170503 170509 170537 170539 170551 170557 170579 170603 170609 170627 170633 170641 170647 170669 170689 170701 170707 170711 170741 170749 170759 170761 170767 170773 170777 170801 170809 170813 170827 170837 170843 170851 170857 170873 170881 170887 170899 170921 170927 170953 170957 170971 171007 171023 171029 171043 171047 171049 171053 171077 171079 171091 171103 171131 171161 171163 171167 171169 171179 171203 171233 171251 171253 171263 171271 171293 171299 171317 171329 171341 171383 171401 171403 171427 171439 171449 171467 171469 171473 171481 171491 171517 171529 171539 171541 171553 171559 171571 171583 171617 171629 171637 171641 171653 171659 171671 171673 171679 171697 171707 171713 171719 171733 171757 171761 171763 171793 171799 171803 171811 171823 171827 171851 171863 171869 171877 171881 171889 171917 171923 171929 171937 171947 172001 172009 172021 172027 172031 172049 172069 172079 172093 172097 172127 172147 172153 172157 172169 172171 172181 172199 172213 172217 172219 172223 172243 172259 172279 172283 172297 172307 172313 172321 172331 172343 172351 172357 172373 172399 172411 172421 172423 172427 172433 172439 172441 172489 172507 172517 172519 172541 172553 172561 172573 172583 172589 172597 172603 172607 172619 172633 172643 172649 172657 172663 172673 172681 172687 172709 172717 172721 172741 172751 172759 172787 172801 172807 172829 172849 172853 172859 172867 172871 172877 172883 172933 172969 172973 172981 172987 172993 172999 173021 173023 173039 173053 173059 173081 173087 173099 173137 173141 173149 173177 173183 173189 173191 173207 173209 173219 173249 173263 173267 173273 173291 173293 173297 173309 173347 173357 173359 173429 173431 173473 173483 173491 173497 173501 173531 173539 173543 173549 173561 173573 173599 173617 173629 173647 173651 173659 173669 173671 173683 173687 173699 173707 173713 173729 173741 173743 173773 173777 173779 173783 173807 173819 173827 173839 173851 173861 173867 173891 173897 173909 173917 173923 173933 173969 173977 173981 173993 174007 174017 174019 174047 174049 174061 174067 174071 174077 174079 174091 174101 174121 174137 174143 174149 174157 174169 174197 174221 174241 174257 174259 174263 174281 174289 174299 174311 174329 174331 174337 174347 174367 174389 174407 174413 174431 174443 174457 174467 174469 174481 174487 174491 174527 174533 174569 174571 174583 174599 174613 174617 174631 174637 174649 174653 174659 174673 174679 174703 174721 174737 174749 174761 174763 174767 174773 174799 174821 174829 174851 174859 174877 174893 174901 174907 174917 174929 174931 174943 174959 174989 174991 175003 175013 175039 175061 175067 175069 175079 175081 175103 175129 175141 175211 175229 175261 175267 175277 175291 175303 175309 175327 175333 175349 175361 175391 175393 175403 175411 175433 175447 175453 175463 175481 175493 175499 175519 175523 175543 175573 175601 175621 175631 175633 175649 175663 175673 175687 175691 175699 175709 175723 175727 175753 175757 175759 175781 175783 175811 175829 175837 175843 175853 175859 175873 175891 175897 175909 175919 175937 175939 175949 175961 175963 175979 175991 175993 176017 176021 176023 176041 176047 176051 176053 176063 176081 176087 176089 176123 176129 176153 176159 176161 176179 176191 176201 176207 176213 176221 176227 176237 176243 176261 176299 176303 176317 176321 176327 176329 176333 176347 176353 176357 176369 176383 176389 176401 176413 176417 176419 176431 176459 176461 176467 176489 176497 176503 176507 176509 176521 176531 176537 176549 176551 176557 176573 176591 176597 176599 176609 176611 176629 176641 176651 176677 176699 176711 176713 176741 176747 176753 176777 176779 176789 176791 176797 176807 176809 176819 176849 176857 176887 176899 176903 176921 176923 176927 176933 176951 176977 176983 176989 177007 177011 177013 177019 177043 177091 177101 177109 177113 177127 177131 177167 177173 177209 177211 177217 177223 177239 177257 177269 177283 177301 177319 177323 177337 177347 177379 177383 177409 177421 177427 177431 177433 177467 177473 177481 177487 177493 177511 177533 177539 177553 177589 177601 177623 177647 177677 177679 177691 177739 177743 177761 177763 177787 177791 177797 177811 177823 177839 177841 177883 177887 177889 177893 177907 177913 177917 177929 177943 177949 177953 177967 177979 178001 178021 178037 178039 178067 178069 178091 178093 178103 178117 178127 178141 178151 178169 178183 178187 178207 178223 178231 178247 178249 178259 178261 178289 178301 178307 178327 178333 178349 178351 178361 178393 178397 178403 178417 178439 178441 178447 178469 178481 178487 178489 178501 178513 178531 178537 178559 178561 178567 178571 178597 178601 178603 178609 178613 178621 178627 178639 178643 178681 178691 178693 178697 178753 178757 178781 178793 178799 178807 178813 178817 178819 178831 178853 178859 178873 178877 178889 178897 178903 178907 178909 178921 178931 178933 178939 178951 178973 178987 179021 179029 179033 179041 179051 179057 179083 179089 179099 179107 179111 179119 179143 179161 179167 179173 179203 179209 179213 179233 179243 179261 179269 179281 179287 179317 179321 179327 179351 179357 179369 179381 179383 179393 179407 179411 179429 179437 179441 179453 179461 179471 179479 179483 179497 179519 179527 179533 179549 179563 179573 179579 179581 179591 179593 179603 179623 179633 179651 179657 179659 179671 179687 179689 179693 179717 179719 179737 179743 179749 179779 179801 179807 179813 179819 179821 179827 179833 179849 179897 179899 179903 179909 179917 179923 179939 179947 179951 179953 179957 179969 179981 179989 179999 180001 180007 180023 180043 180053 180071 180073 180077 180097 180137 180161 180179 180181 180211 180221 180233 180239 180241 180247 180259 180263 180281 180287 180289 180307 180311 180317 180331 180337 180347 180361 180371 180379 180391 180413 180419 180437 180463 180473 180491 180497 180503 180511 180533 180539 180541 180547 180563 180569 180617 180623 180629 180647 180667 180679 180701 180731 180749 180751 180773 180779 180793 180797 180799 180811 180847 180871 180883 180907 180949 180959 181001 181003 181019 181031 181039 181061 181063 181081 181087 181123 181141 181157 181183 181193 181199 181201 181211 181213 181219 181243 181253 181273 181277 181283 181297 181301 181303 181361 181387 181397 181399 181409 181421 181439 181457 181459 181499 181501 181513 181523 181537 181549 181553 181603 181607 181609 181619 181639 181667 181669 181693 181711 181717 181721 181729 181739 181751 181757 181759 181763 181777 181787 181789 181813 181837 181871 181873 181889 181891 181903 181913 181919 181927 181931 181943 181957 181967 181981 181997 182009 182011 182027 182029 182041 182047 182057 182059 182089 182099 182101 182107 182111 182123 182129 182131 182141 182159 182167 182177 182179 182201 182209 182233 182239 182243 182261 182279 182297 182309 182333 182339 182341 182353 182387 182389 182417 182423 182431 182443 182453 182467 182471 182473 182489 182503 182509 182519 182537 182549 182561 182579 182587 182593 182599 182603 182617 182627 182639 182641 182653 182657 182659 182681 182687 182701 182711 182713 182747 182773 182779 182789 182803 182813 182821 182839 182851 182857 182867 182887 182893 182899 182921 182927 182929 182933 182953 182957 182969 182981 182999 183023 183037 183041 183047 183059 183067 183089 183091 183119 183151 183167 183191 183203 183247 183259 183263 183283 183289 183299 183301 183307 183317 183319 183329 183343 183349 183361 183373 183377 183383 183389 183397 183437 183439 183451 183461 183473 183479 183487 183497 183499 183503 183509 183511 183523 183527 183569 183571 183577 183581 183587 183593 183611 183637 183661 183683 183691 183697 183707 183709 183713 183761 183763 183797 183809 183823 183829 183871 183877 183881 183907 183917 183919 183943 183949 183959 183971 183973 183979 184003 184007 184013 184031 184039 184043 184057 184073 184081 184087 184111 184117 184133 184153 184157 184181 184187 184189 184199 184211 184231 184241 184259 184271 184273 184279 184291 184309 184321 184333 184337 184351 184369 184409 184417 184441 184447 184463 184477 184487 184489 184511 184517 184523 184553 184559 184567 184571 184577 184607 184609 184627 184631 184633 184649 184651 184669 184687 184693 184703 184711 184721 184727 184733 184753 184777 184823 184829 184831 184837 184843 184859 184879 184901 184903 184913 184949 184957 184967 184969 184993 184997 184999 185021 185027 185051 185057 185063 185069 185071 185077 185089 185099 185123 185131 185137 185149 185153 185161 185167 185177 185183 185189 185221 185233 185243 185267 185291 185299 185303 185309 185323 185327 185359 185363 185369 185371 185401 185429 185441 185467 185477 185483 185491 185519 185527 185531 185533 185539 185543 185551 185557 185567 185569 185593 185599 185621 185641 185651 185677 185681 185683 185693 185699 185707 185711 185723 185737 185747 185749 185753 185767 185789 185797 185813 185819 185821 185831 185833 185849 185869 185873 185893 185897 185903 185917 185923 185947 185951 185957 185959 185971 185987 185993 186007 186013 186019 186023 186037 186041 186049 186071 186097 186103 186107 186113 186119 186149 186157 186161 186163 186187 186191 186211 186227 186229 186239 186247 186253 186259 186271 186283 186299 186301 186311 186317 186343 186377 186379 186391 186397 186419 186437 186451 186469 186479 186481 186551 186569 186581 186583 186587 186601 186619 186629 186647 186649 186653 186671 186679 186689 186701 186707 186709 186727 186733 186743 186757 186761 186763 186773 186793 186799 186841 186859 186869 186871 186877 186883 186889 186917 186947 186959 187003 187009 187027 187043 187049 187067 187069 187073 187081 187091 187111 187123 187127 187129 187133 187139 187141 187163 187171 187177 187181 187189 187193 187211 187217 187219 187223 187237 187273 187277 187303 187337 187339 187349 187361 187367 187373 187379 187387 187393 187409 187417 187423 187433 187441 187463 187469 187471 187477 187507 187513 187531 187547 187559 187573 187597 187631 187633 187637 187639 187651 187661 187669 187687 187699 187711 187721 187751 187763 187787 187793 187823 187843 187861 187871 187877 187883 187897 187907 187909 187921 187927 187931 187951 187963 187973 187987 188011 188017 188021 188029 188107 188137 188143 188147 188159 188171 188179 188189 188197 188249 188261 188273 188281 188291 188299 188303 188311 188317 188323 188333 188351 188359 188369 188389 188401 188407 188417 188431 188437 188443 188459 188473 188483 188491 188519 188527 188533 188563 188579 188603 188609 188621 188633 188653 188677 188681 188687 188693 188701 188707 188711 188719 188729 188753 188767 188779 188791 188801 188827 188831 188833 188843 188857 188861 188863 188869 188891 188911 188927 188933 188939 188941 188953 188957 188983 188999 189011 189017 189019 189041 189043 189061 189067 189127 189139 189149 189151 189169 189187 189199 189223 189229 189239 189251 189253 189257 189271 189307 189311 189337 189347 189349 189353 189361 189377 189389 189391 189401 189407 189421 189433 189437 189439 189463 189467 189473 189479 189491 189493 189509 189517 189523 189529 189547 189559 189583 189593 189599 189613 189617 189619 189643 189653 189661 189671 189691 189697 189701 189713 189733 189743 189757 189767 189797 189799 189817 189823 189851 189853 189859 189877 189881 189887 189901 189913 189929 189947 189949 189961 189967 189977 189983 189989 189997 190027 190031 190051 190063 190093 190097 190121 190129 190147 190159 190181 190207 190243 190249 190261 190271 190283 190297 190301 190313 190321 190331 190339 190357 190367 190369 190387 190391 190403 190409 190471 190507 190523 190529 190537 190543 190573 190577 190579 190583 190591 190607 190613 190633 190639 190649 190657 190667 190669 190699 190709 190711 190717 190753 190759 190763 190769 190783 190787 190793 190807 190811 190823 190829 190837 190843 190871 190889 190891 190901 190909 190913 190921 190979 190997 191021 191027 191033 191039 191047 191057 191071 191089 191099 191119 191123 191137 191141 191143 191161 191173 191189 191227 191231 191237 191249 191251 191281 191297 191299 191339 191341 191353 191413 191441 191447 191449 191453 191459 191461 191467 191473 191491 191497 191507 191509 191519 191531 191533 191537 191551 191561 191563 191579 191599 191621 191627 191657 191669 191671 191677 191689 191693 191699 191707 191717 191747 191749 191773 191783 191791 191801 191803 191827 191831 191833 191837 191861 191899 191903 191911 191929 191953 191969 191977 191999 192007 192013 192029 192037 192043 192047 192053 192091 192097 192103 192113 192121 192133 192149 192161 192173 192187 192191 192193 192229 192233 192239 192251 192259 192263 192271 192307 192317 192319 192323 192341 192343 192347 192373 192377 192383 192391 192407 192431 192461 192463 192497 192499 192529 192539 192547 192553 192557 192571 192581 192583 192587 192601 192611 192613 192617 192629 192631 192637 192667 192677 192697 192737 192743 192749 192757 192767 192781 192791 192799 192811 192817 192833 192847 192853 192859 192877 192883 192887 192889 192917 192923 192931 192949 192961 192971 192977 192979 192991 193003 193009 193013 193031 193043 193051 193057 193073 193093 193133 193139 193147 193153 193163 193181 193183 193189 193201 193243 193247 193261 193283 193301 193327 193337 193357 193367 193373 193379 193381 193387 193393 193423 193433 193441 193447 193451 193463 193469 193493 193507 193513 193541 193549 193559 193573 193577 193597 193601 193603 193607 193619 193649 193663 193679 193703 193723 193727 193741 193751 193757 193763 193771 193789 193793 193799 193811 193813 193841 193847 193859 193861 193871 193873 193877 193883 193891 193937 193939 193943 193951 193957 193979 193993 194003 194017 194027 194057 194069 194071 194083 194087 194093 194101 194113 194119 194141 194149 194167 194179 194197 194203 194239 194263 194267 194269 194309 194323 194353 194371 194377 194413 194431 194443 194471 194479 194483 194507 194521 194527 194543 194569 194581 194591 194609 194647 194653 194659 194671 194681 194683 194687 194707 194713 194717 194723 194729 194749 194767 194771 194809 194813 194819 194827 194839 194861 194863 194867 194869 194891 194899 194911 194917 194933 194963 194977 194981 194989 195023 195029 195043 195047 195049 195053 195071 195077 195089 195103 195121 195127 195131 195137 195157 195161 195163 195193 195197 195203 195229 195241 195253 195259 195271 195277 195281 195311 195319 195329 195341 195343 195353 195359 195389 195401 195407 195413 195427 195443 195457 195469 195479 195493 195497 195511 195527 195539 195541 195581 195593 195599 195659 195677 195691 195697 195709 195731 195733 195737 195739 195743 195751 195761 195781 195787 195791 195809 195817 195863 195869 195883 195887 195893 195907 195913 195919 195929 195931 195967 195971 195973 195977 195991 195997 196003 196033 196039 196043 196051 196073 196081 196087 196111 196117 196139 196159 196169 196171 196177 196181 196187 196193 196201 196247 196271 196277 196279 196291 196303 196307 196331 196337 196379 196387 196429 196439 196453 196459 196477 196499 196501 196519 196523 196541 196543 196549 196561 196579 196583 196597 196613 196643 196657 196661 196663 196681 196687 196699 196709 196717 196727 196739 196751 196769 196771 196799 196817 196831 196837 196853 196871 196873 196879 196901 196907 196919 196927 196961 196991 196993 197003 197009 197023 197033 197059 197063 197077 197083 197089 197101 197117 197123 197137 197147 197159 197161 197203 197207 197221 197233 197243 197257 197261 197269 197273 197279 197293 197297 197299 197311 197339 197341 197347 197359 197369 197371 197381 197383 197389 197419 197423 197441 197453 197479 197507 197521 197539 197551 197567 197569 197573 197597 197599 197609 197621 197641 197647 197651 197677 197683 197689 197699 197711 197713 197741 197753 197759 197767 197773 197779 197803 197807 197831 197837 197887 197891 197893 197909 197921 197927 197933 197947 197957 197959 197963 197969 197971 198013 198017 198031 198043 198047 198073 198083 198091 198097 198109 198127 198139 198173 198179 198193 198197 198221 198223 198241 198251 198257 198259 198277 198281 198301 198313 198323 198337 198347 198349 198377 198391 198397 198409 198413 198427 198437 198439 198461 198463 198469 198479 198491 198503 198529 198533 198553 198571 198589 198593 198599 198613 198623 198637 198641 198647 198659 198673 198689 198701 198719 198733 198761 198769 198811 198817 198823 198827 198829 198833 198839 198841 198851 198859 198899 198901 198929 198937 198941 198943 198953 198959 198967 198971 198977 198997 199021 199033 199037 199039 199049 199081 199103 199109 199151 199153 199181 199193 199207 199211 199247 199261 199267 199289 199313 199321 199337 199343 199357 199373 199379 199399 199403 199411 199417 199429 199447 199453 199457 199483 199487 199489 199499 199501 199523 199559 199567 199583 199601 199603 199621 199637 199657 199669 199673 199679 199687 199697 199721 199729 199739 199741 199751 199753 199777 199783 199799 199807 199811 199813 199819 199831 199853 199873 199877 199889 199909 199921 199931 199933 199961 199967 199999 200003 200009 200017 200023 200029 200033 200041 200063 200087 200117 200131 200153 200159 200171 200177 200183 200191 200201 200227 200231 200237 200257 200273 200293 200297 200323 200329 200341 200351 200357 200363 200371 200381 200383 200401 200407 200437 200443 200461 200467 200483 200513 200569 200573 200579 200587 200591 200597 200609 200639 200657 200671 200689 200699 200713 200723 200731 200771 200779 200789 200797 200807 200843 200861 200867 200869 200881 200891 200899 200903 200909 200927 200929 200971 200983 200987 200989 201007 201011 201031 201037 201049 201073 201101 201107 201119 201121 201139 201151 201163 201167 201193 201203 201209 201211 201233 201247 201251 201281 201287 201307 201329 201337 201359 201389 201401 201403 201413 201437 201449 201451 201473 201491 201493 201497 201499 201511 201517 201547 201557 201577 201581 201589 201599 201611 201623 201629 201653 201661 201667 201673 201683 201701 201709 201731 201743 201757 201767 201769 201781 201787 201791 201797 201809 201821 201823 201827 201829 201833 201847 201881 201889 201893 201907 201911 201919 201923 201937 201947 201953 201961 201973 201979 201997 202001 202021 202031 202049 202061 202063 202067 202087 202099 202109 202121 202127 202129 202183 202187 202201 202219 202231 202243 202277 202289 202291 202309 202327 202339 202343 202357 202361 202381 202387 202393 202403 202409 202441 202471 202481 202493 202519 202529 202549 202567 202577 202591 202613 202621 202627 202637 202639 202661 202667 202679 202693 202717 202729 202733 202747 202751 202753 202757 202777 202799 202817 202823 202841 202859 202877 202879 202889 202907 202921 202931 202933 202949 202967 202973 202981 202987 202999 203011 203017 203023 203039 203051 203057 203117 203141 203173 203183 203207 203209 203213 203221 203227 203233 203249 203279 203293 203309 203311 203317 203321 203323 203339 203341 203351 203353 203363 203381 203383 203387 203393 203417 203419 203429 203431 203449 203459 203461 203531 203549 203563 203569 203579 203591 203617 203627 203641 203653 203657 203659 203663 203669 203713 203761 203767 203771 203773 203789 203807 203809 203821 203843 203857 203869 203873 203897 203909 203911 203921 203947 203953 203969 203971 203977 203989 203999 204007 204013 204019 204023 204047 204059 204067 204101 204107 204133 204137 204143 204151 204161 204163 204173 204233 204251 204299 204301 204311 204319 204329 204331 204353 204359 204361 204367 204371 204377 204397 204427 204431 204437 204439 204443 204461 204481 204487 204509 204511 204517 204521 204557 204563 204583 204587 204599 204601 204613 204623 204641 204667 204679 204707 204719 204733 204749 204751 204781 204791 204793 204797 204803 204821 204857 204859 204871 204887 204913 204917 204923 204931 204947 204973 204979 204983 205019 205031 205033 205043 205063 205069 205081 205097 205103 205111 205129 205133 205141 205151 205157 205171 205187 205201 205211 205213 205223 205237 205253 205267 205297 205307 205319 205327 205339 205357 205391 205397 205399 205417 205421 205423 205427 205433 205441 205453 205463 205477 205483 205487 205493 205507 205519 205529 205537 205549 205553 205559 205589 205603 205607 205619 205627 205633 205651 205657 205661 205663 205703 205721 205759 205763 205783 205817 205823 205837 205847 205879 205883 205913 205937 205949 205951 205957 205963 205967 205981 205991 205993 206009 206021 206027 206033 206039 206047 206051 206069 206077 206081 206083 206123 206153 206177 206179 206183 206191 206197 206203 206209 206221 206233 206237 206249 206251 206263 206273 206279 206281 206291 206299 206303 206341 206347 206351 206369 206383 206399 206407 206411 206413 206419 206447 206461 206467 206477 206483 206489 206501 206519 206527 206543 206551 206593 206597 206603 206623 206627 206639 206641 206651 206699 206749 206779 206783 206803 206807 206813 206819 206821 206827 206879 206887 206897 206909 206911 206917 206923 206933 206939 206951 206953 206993 207013 207017 207029 207037 207041 207061 207073 207079 207113 207121 207127 207139 207169 207187 207191 207197 207199 207227 207239 207241 207257 207269 207287 207293 207301 207307 207329 207331 207341 207343 207367 207371 207377 207401 207409 207433 207443 207457 207463 207469 207479 207481 207491 207497 207509 207511 207517 207521 207523 207541 207547 207551 207563 207569 207589 207593 207619 207629 207643 207653 207661 207671 207673 207679 207709 207719 207721 207743 207763 207769 207797 207799 207811 207821 207833 207847 207869 207877 207923 207931 207941 207947 207953 207967 207971 207973 207997 208001 208003 208009 208037 208049 208057 208067 208073 208099 208111 208121 208129 208139 208141 208147 208189 208207 208213 208217 208223 208231 208253 208261 208277 208279 208283 208291 208309 208319 208333 208337 208367 208379 208387 208391 208393 208409 208433 208441 208457 208459 208463 208469 208489 208493 208499 208501 208511 208513 208519 208529 208553 208577 208589 208591 208609 208627 208631 208657 208667 208673 208687 208697 208699 208721 208729 208739 208759 208787 208799 208807 208837 208843 208877 208889 208891 208907 208927 208931 208933 208961 208963 208991 208993 208997 209021 209029 209039 209063 209071 209089 209123 209147 209159 209173 209179 209189 209201 209203 209213 209221 209227 209233 209249 209257 209263 209267 209269 209299 209311 209317 209327 209333 209347 209353 209357 209359 209371 209381 209393 209401 209431 209441 209449 209459 209471 209477 209497 209519 209533 209543 209549 209563 209567 209569 209579 209581 209597 209621 209623 209639 209647 209659 209669 209687 209701 209707 209717 209719 209743 209767 209771 209789 209801 209809 209813 209819 209821 209837 209851 209857 209861 209887 209917 209927 209929 209939 209953 209959 209971 209977 209983 209987 210011 210019 210031 210037 210053 210071 210097 210101 210109 210113 210127 210131 210139 210143 210157 210169 210173 210187 210191 210193 210209 210229 210233 210241 210247 210257 210263 210277 210283 210299 210317 210319 210323 210347 210359 210361 210391 210401 210403 210407 210421 210437 210461 210467 210481 210487 210491 210499 210523 210527 210533 210557 210599 210601 210619 210631 210643 210659 210671 210709 210713 210719 210731 210739 210761 210773 210803 210809 210811 210823 210827 210839 210853 210857 210869 210901 210907 210911 210913 210923 210929 210943 210961 210967 211007 211039 211049 211051 211061 211063 211067 211073 211093 211097 211129 211151 211153 211177 211187 211193 211199 211213 211217 211219 211229 211231 211241 211247 211271 211283 211291 211297 211313 211319 211333 211339 211349 211369 211373 211403 211427 211433 211441 211457 211469 211493 211499 211501 211507 211543 211559 211571 211573 211583 211597 211619 211639 211643 211657 211661 211663 211681 211691 211693 211711 211723 211727 211741 211747 211777 211781 211789 211801 211811 211817 211859 211867 211873 211877 211879 211889 211891 211927 211931 211933 211943 211949 211969 211979 211997 212029 212039 212057 212081 212099 212117 212123 212131 212141 212161 212167 212183 212203 212207 212209 212227 212239 212243 212281 212293 212297 212353 212369 212383 212411 212419 212423 212437 212447 212453 212461 212467 212479 212501 212507 212557 212561 212573 212579 212587 212593 212627 212633 212651 212669 212671 212677 212683 212701 212777 212791 212801 212827 212837 212843 212851 212867 212869 212873 212881 212897 212903 212909 212917 212923 212969 212981 212987 212999 213019 213023 213029 213043 213067 213079 213091 213097 213119 213131 213133 213139 213149 213173 213181 213193 213203 213209 213217 213223 213229 213247 213253 213263 213281 213287 213289 213307 213319 213329 213337 213349 213359 213361 213383 213391 213397 213407 213449 213461 213467 213481 213491 213523 213533 213539 213553 213557 213589 213599 213611 213613 213623 213637 213641 213649 213659 213713 213721 213727 213737 213751 213791 213799 213821 213827 213833 213847 213859 213881 213887 213901 213919 213929 213943 213947 213949 213953 213973 213977 213989 214003 214007 214009 214021 214031 214033 214043 214051 214063 214069 214087 214091 214129 214133 214141 214147 214163 214177 214189 214211 214213 214219 214237 214243 214259 214283 214297 214309 214351 214363 214373 214381 214391 214399 214433 214439 214451 214457 214463 214469 214481 214483 214499 214507 214517 214519 214531 214541 214559 214561 214589 214603 214607 214631 214639 214651 214657 214663 214667 214673 214691 214723 214729 214733 214741 214759 214763 214771 214783 214787 214789 214807 214811 214817 214831 214849 214853 214867 214883 214891 214913 214939 214943 214967 214987 214993 215051 215063 215077 215087 215123 215141 215143 215153 215161 215179 215183 215191 215197 215239 215249 215261 215273 215279 215297 215309 215317 215329 215351 215353 215359 215381 215389 215393 215399 215417 215443 215447 215459 215461 215471 215483 215497 215503 215507 215521 215531 215563 215573 215587 215617 215653 215659 215681 215687 215689 215693 215723 215737 215753 215767 215771 215797 215801 215827 215833 215843 215851 215857 215863 215893 215899 215909 215921 215927 215939 215953 215959 215981 215983 216023 216037 216061 216071 216091 216103 216107 216113 216119 216127 216133 216149 216157 216173 216179 216211 216217 216233 216259 216263 216289 216317 216319 216329 216347 216371 216373 216379 216397 216401 216421 216431 216451 216481 216493 216509 216523 216551 216553 216569 216571 216577 216607 216617 216641 216647 216649 216653 216661 216679 216703 216719 216731 216743 216751 216757 216761 216779 216781 216787 216791 216803 216829 216841 216851 216859 216877 216899 216901 216911 216917 216919 216947 216967 216973 216991 217001 217003 217027 217033 217057 217069 217081 217111 217117 217121 217157 217163 217169 217199 217201 217207 217219 217223 217229 217241 217253 217271 217307 217309 217313 217319 217333 217337 217339 217351 217361 217363 217367 217369 217387 217397 217409 217411 217421 217429 217439 217457 217463 217489 217499 217517 217519 217559 217561 217573 217577 217579 217619 217643 217661 217667 217681 217687 217691 217697 217717 217727 217733 217739 217747 217771 217781 217793 217823 217829 217849 217859 217901 217907 217909 217933 217937 217969 217979 217981 218003 218021 218047 218069 218077 218081 218083 218087 218107 218111 218117 218131 218137 218143 218149 218171 218191 218213 218227 218233 218249 218279 218287 218357 218363 218371 218381 218389 218401 218417 218419 218423 218437 218447 218453 218459 218461 218479 218509 218513 218521 218527 218531 218549 218551 218579 218591 218599 218611 218623 218627 218629 218641 218651 218657 218677 218681 218711 218717 218719 218723 218737 218749 218761 218783 218797 218809 218819 218833 218839 218843 218849 218857 218873 218887 218923 218941 218947 218963 218969 218971 218987 218989 218993 219001 219017 219019 219031 219041 219053 219059 219071 219083 219091 219097 219103 219119 219133 219143 219169 219187 219217 219223 219251 219277 219281 219293 219301 219311 219313 219353 219361 219371 219377 219389 219407 219409 219433 219437 219451 219463 219467 219491 219503 219517 219523 219529 219533 219547 219577 219587 219599 219607 219613 219619 219629 219647 219649 219677 219679 219683 219689 219707 219721 219727 219731 219749 219757 219761 219763 219767 219787 219797 219799 219809 219823 219829 219839 219847 219851 219871 219881 219889 219911 219917 219931 219937 219941 219943 219953 219959 219971 219977 219979 219983 220009 220013 220019 220021 220057 220063 220123 220141 220147 220151 220163 220169 220177 220189 220217 220243 220279 220291 220301 220307 220327 220333 220351 220357 220361 220369 220373 220391 220399 220403 220411 220421 220447 220469 220471 220511 220513 220529 220537 220543 220553 220559 220573 220579 220589 220613 220663 220667 220673 220681 220687 220699 220709 220721 220747 220757 220771 220783 220789 220793 220807 220811 220841 220859 220861 220873 220877 220879 220889 220897 220901 220903 220907 220919 220931 220933 220939 220973 221021 221047 221059 221069 221071 221077 221083 221087 221093 221101 221159 221171 221173 221197 221201 221203 221209 221219 221227 221233 221239 221251 221261 221281 221303 221311 221317 221327 221393 221399 221401 221411 221413 221447 221453 221461 221471 221477 221489 221497 221509 221537 221539 221549 221567 221581 221587 221603 221621 221623 221653 221657 221659 221671 221677 221707 221713 221717 221719 221723 221729 221737 221747 221773 221797 221807 221813 221827 221831 221849 221873 221891 221909 221941 221951 221953 221957 221987 221989 221999 222007 222011 222023 222029 222041 222043 222059 222067 222073 222107 222109 222113 222127 222137 222149 222151 222161 222163 222193 222197 222199 222247 222269 222289 222293 222311 222317 222323 222329 222337 222347 222349 222361 222367 222379 222389 222403 222419 222437 222461 222493 222499 222511 222527 222533 222553 222557 222587 222601 222613 222619 222643 222647 222659 222679 222707 222713 222731 222773 222779 222787 222791 222793 222799 222823 222839 222841 222857 222863 222877 222883 222913 222919 222931 222941 222947 222953 222967 222977 222979 222991 223007 223009 223019 223037 223049 223051 223061 223063 223087 223099 223103 223129 223133 223151 223207 223211 223217 223219 223229 223241 223243 223247 223253 223259 223273 223277 223283 223291 223303 223313 223319 223331 223337 223339 223361 223367 223381 223403 223423 223429 223439 223441 223463 223469 223481 223493 223507 223529 223543 223547 223549 223577 223589 223621 223633 223637 223667 223679 223681 223697 223711 223747 223753 223757 223759 223781 223823 223829 223831 223837 223841 223843 223849 223903 223919 223921 223939 223963 223969 223999 224011 224027 224033 224041 224047 224057 224069 224071 224101 224113 224129 224131 224149 224153 224171 224177 224197 224201 224209 224221 224233 224239 224251 224261 224267 224291 224299 224303 224309 224317 224327 224351 224359 224363 224401 224423 224429 224443 224449 224461 224467 224473 224491 224501 224513 224527 224563 224569 224579 224591 224603 224611 224617 224629 224633 224669 224677 224683 224699 224711 224717 224729 224737 224743 224759 224771 224797 224813 224831 224863 224869 224881 224891 224897 224909 224911 224921 224929 224947 224951 224969 224977 224993 225023 225037 225061 225067 225077 225079 225089 225109 225119 225133 225143 225149 225157 225161 225163 225167 225217 225221 225223 225227 225241 225257 225263 225287 225289 225299 225307 225341 225343 225347 225349 225353 225371 225373 225383 225427 225431 225457 225461 225479 225493 225499 225503 225509 225523 225527 225529 225569 225581 225583 225601 225611 225613 225619 225629 225637 225671 225683 225689 225697 225721 225733 225749 225751 225767 225769 225779 225781 225809 225821 225829 225839 225859 225871 225889 225919 225931 225941 225943 225949 225961 225977 225983 225989 226001 226007 226013 226027 226063 226087 226099 226103 226123 226129 226133 226141 226169 226183 226189 226199 226201 226217 226231 226241 226267 226283 226307 226313 226337 226357 226367 226379 226381 226397 226409 226427 226433 226451 226453 226463 226483 226487 226511 226531 226547 226549 226553 226571 226601 226609 226621 226631 226637 226643 226649 226657 226663 226669 226691 226697 226741 226753 226769 226777 226783 226789 226799 226813 226817 226819 226823 226843 226871 226901 226903 226907 226913 226937 226943 226991 227011 227027 227053 227081 227089 227093 227111 227113 227131 227147 227153 227159 227167 227177 227189 227191 227207 227219 227231 227233 227251 227257 227267 227281 227299 227303 227363 227371 227377 227387 227393 227399 227407 227419 227431 227453 227459 227467 227471 227473 227489 227497 227501 227519 227531 227533 227537 227561 227567 227569 227581 227593 227597 227603 227609 227611 227627 227629 227651 227653 227663 227671 227693 227699 227707 227719 227729 227743 227789 227797 227827 227849 227869 227873 227893 227947 227951 227977 227989 227993 228013 228023 228049 228061 228077 228097 228103 228113 228127 228131 228139 228181 228197 228199 228203 228211 228223 228233 228251 228257 228281 228299 228301 228307 228311 228331 228337 228341 228353 228359 228383 228409 228419 228421 228427 228443 228451 228457 228461 228469 228479 228509 228511 228517 228521 228523 228539 228559 228577 228581 228587 228593 228601 228611 228617 228619 228637 228647 228677 228707 228713 228731 228733 228737 228751 228757 228773 228793 228797 228799 228829 228841 228847 228853 228859 228869 228881 228883 228887 228901 228911 228913 228923 228929 228953 228959 228961 228983 228989 229003 229027 229037 229081 229093 229123 229127 229133 229139 229153 229157 229171 229181 229189 229199 229213 229217 229223 229237 229247 229249 229253 229261 229267 229283 229309 229321 229343 229351 229373 229393 229399 229403 229409 229423 229433 229459 229469 229487 229499 229507 229519 229529 229547 229549 229553 229561 229583 229589 229591 229601 229613 229627 229631 229637 229639 229681 229693 229699 229703 229711 229717 229727 229739 229751 229753 229759 229763 229769 229771 229777 229781 229799 229813 229819 229837 229841 229847 229849 229897 229903 229937 229939 229949 229961 229963 229979 229981 230003 230017 230047 230059 230063 230077 230081 230089 230101 230107 230117 230123 230137 230143 230149 230189 230203 230213 230221 230227 230233 230239 230257 230273 230281 230291 230303 230309 230311 230327 230339 230341 230353 230357 230369 230383 230387 230389 230393 230431 230449 230453 230467 230471 230479 230501 230507 230539 230551 230561 230563 230567 230597 230611 230647 230653 230663 230683 230693 230719 230729 230743 230761 230767 230771 230773 230779 230807 230819 230827 230833 230849 230861 230863 230873 230891 230929 230933 230939 230941 230959 230969 230977 230999 231001 231017 231019 231031 231041 231053 231067 231079 231107 231109 231131 231169 231197 231223 231241 231269 231271 231277 231289 231293 231299 231317 231323 231331 231347 231349 231359 231367 231379 231409 231419 231431 231433 231443 231461 231463 231479 231481 231493 231503 231529 231533 231547 231551 231559 231563 231571 231589 231599 231607 231611 231613 231631 231643 231661 231677 231701 231709 231719 231779 231799 231809 231821 231823 231827 231839 231841 231859 231871 231877 231893 231901 231919 231923 231943 231947 231961 231967 232003 232007 232013 232049 232051 232073 232079 232081 232091 232103 232109 232117 232129 232153 232171 232187 232189 232207 232217 232259 232303 232307 232333 232357 232363 232367 232381 232391 232409 232411 232417 232433 232439 232451 232457 232459 232487 232499 232513 232523 232549 232567 232571 232591 232597 232607 232621 232633 232643 232663 232669 232681 232699 232709 232711 232741 232751 232753 232777 232801 232811 232819 232823 232847 232853 232861 232871 232877 232891 232901 232907 232919 232937 232961 232963 232987 233021 233069 233071 233083 233113 233117 233141 233143 233159 233161 233173 233183 233201 233221 233231 233239 233251 233267 233279 233293 233297 233323 233327 233329 233341 233347 233353 233357 233371 233407 233417 233419 233423 233437 233477 233489 233509 233549 233551 233557 233591 233599 233609 233617 233621 233641 233663 233669 233683 233687 233689 233693 233713 233743 233747 233759 233777 233837 233851 233861 233879 233881 233911 233917 233921 233923 233939 233941 233969 233983 233993 234007 234029 234043 234067 234083 234089 234103 234121 234131 234139 234149 234161 234167 234181 234187 234191 234193 234197 234203 234211 234217 234239 234259 234271 234281 234287 234293 234317 234319 234323 234331 234341 234343 234361 234383 234431 234457 234461 234463 234467 234473 234499 234511 234527 234529 234539 234541 234547 234571 234587 234589 234599 234613 234629 234653 234659 234673 234683 234713 234721 234727 234733 234743 234749 234769 234781 234791 234799 234803 234809 234811 234833 234847 234851 234863 234869 234893 234907 234917 234931 234947 234959 234961 234967 234977 234979 234989 235003 235007 235009 235013 235043 235051 235057 235069 235091 235099 235111 235117 235159 235171 235177 235181 235199 235211 235231 235241 235243 235273 235289 235307 235309 235337 235349 235369 235397 235439 235441 235447 235483 235489 235493 235513 235519 235523 235537 235541 235553 235559 235577 235591 235601 235607 235621 235661 235663 235673 235679 235699 235723 235747 235751 235783 235787 235789 235793 235811 235813 235849 235871 235877 235889 235891 235901 235919 235927 235951 235967 235979 235997 236017 236021 236053 236063 236069 236077 236087 236107 236111 236129 236143 236153 236167 236207 236209 236219 236231 236261 236287 236293 236297 236323 236329 236333 236339 236377 236381 236387 236399 236407 236429 236449 236461 236471 236477 236479 236503 236507 236519 236527 236549 236563 236573 236609 236627 236641 236653 236659 236681 236699 236701 236707 236713 236723 236729 236737 236749 236771 236773 236779 236783 236807 236813 236867 236869 236879 236881 236891 236893 236897 236909 236917 236947 236981 236983 236993 237011 237019 237043 237053 237067 237071 237073 237089 237091 237137 237143 237151 237157 237161 237163 237173 237179 237203 237217 237233 237257 237271 237277 237283 237287 237301 237313 237319 237331 237343 237361 237373 237379 237401 237409 237467 237487 237509 237547 237563 237571 237581 237607 237619 237631 237673 237683 237689 237691 237701 237707 237733 237737 237749 237763 237767 237781 237791 237821 237851 237857 237859 237877 237883 237901 237911 237929 237959 237967 237971 237973 237977 237997 238001 238009 238019 238031 238037 238039 238079 238081 238093 238099 238103 238109 238141 238151 238157 238159 238163 238171 238181 238201 238207 238213 238223 238229 238237 238247 238261 238267 238291 238307 238313 238321 238331 238339 238361 238363 238369 238373 238397 238417 238423 238439 238451 238463 238471 238477 238481 238499 238519 238529 238531 238547 238573 238591 238627 238639 238649 238657 238673 238681 238691 238703 238709 238723 238727 238729 238747 238759 238781 238789 238801 238829 238837 238841 238853 238859 238877 238879 238883 238897 238919 238921 238939 238943 238949 238967 238991 239017 239023 239027 239053 239069 239081 239087 239119 239137 239147 239167 239171 239179 239201 239231 239233 239237 239243 239251 239263 239273 239287 239297 239329 239333 239347 239357 239383 239387 239389 239417 239423 239429 239431 239441 239461 239489 239509 239521 239527 239531 239539 239543 239557 239567 239579 239587 239597 239611 239623 239633 239641 239671 239689 239699 239711 239713 239731 239737 239753 239779 239783 239803 239807 239831 239843 239849 239851 239857 239873 239879 239893 239929 239933 239947 239957 239963 239977 239999 240007 240011 240017 240041 240043 240047 240049 240059 240073 240089 240101 240109 240113 240131 240139 240151 240169 240173 240197 240203 240209 240257 240259 240263 240271 240283 240287 240319 240341 240347 240349 240353 240371 240379 240421 240433 240437 240473 240479 240491 240503 240509 240517 240551 240571 240587 240589 240599 240607 240623 240631 240641 240659 240677 240701 240707 240719 240727 240733 240739 240743 240763 240769 240797 240811 240829 240841 240853 240859 240869 240881 240883 240893 240899 240913 240943 240953 240959 240967 240997 241013 241027 241037 241049 241051 241061 241067 241069 241079 241093 241117 241127 241141 241169 241177 241183 241207 241229 241249 241253 241259 241261 241271 241291 241303 241313 241321 241327 241333 241337 241343 241361 241363 241391 241393 241421 241429 241441 241453 241463 241469 241489 241511 241513 241517 241537 241543 241559 241561 241567 241589 241597 241601 241603 241639 241643 241651 241663 241667 241679 241687 241691 241711 241727 241739 241771 241781 241783 241793 241807 241811 241817 241823 241847 241861 241867 241873 241877 241883 241903 241907 241919 241921 241931 241939 241951 241963 241973 241979 241981 241993 242009 242057 242059 242069 242083 242093 242101 242119 242129 242147 242161 242171 242173 242197 242201 242227 242243 242257 242261 242273 242279 242309 242329 242357 242371 242377 242393 242399 242413 242419 242441 242447 242449 242453 242467 242479 242483 242491 242509 242519 242521 242533 242551 242591 242603 242617 242621 242629 242633 242639 242647 242659 242677 242681 242689 242713 242729 242731 242747 242773 242779 242789 242797 242807 242813 242819 242863 242867 242873 242887 242911 242923 242927 242971 242989 242999 243011 243031 243073 243077 243091 243101 243109 243119 243121 243137 243149 243157 243161 243167 243197 243203 243209 243227 243233 243239 243259 243263 243301 243311 243343 243367 243391 243401 243403 243421 243431 243433 243437 243461 243469 243473 243479 243487 243517 243521 243527 243533 243539 243553 243577 243583 243587 243589 243613 243623 243631 243643 243647 243671 243673 243701 243703 243707 243709 243769 243781 243787 243799 243809 243829 243839 243851 243857 243863 243871 243889 243911 243917 243931 243953 243973 243989 244003 244009 244021 244033 244043 244087 244091 244109 244121 244129 244141 244147 244157 244159 244177 244199 244217 244219 244243 244247 244253 244261 244291 244297 244301 244303 244313 244333 244339 244351 244357 244367 244379 244381 244393 244399 244403 244411 244423 244429 244451 244457 244463 244471 244481 244493 244507 244529 244547 244553 244561 244567 244583 244589 244597 244603 244619 244633 244637 244639 244667 244669 244687 244691 244703 244711 244721 244733 244747 244753 244759 244781 244787 244813 244837 244841 244843 244859 244861 244873 244877 244889 244897 244901 244939 244943 244957 244997 245023 245029 245033 245039 245071 245083 245087 245107 245129 245131 245149 245171 245173 245177 245183 245209 245251 245257 245261 245269 245279 245291 245299 245317 245321 245339 245383 245389 245407 245411 245417 245419 245437 245471 245473 245477 245501 245513 245519 245521 245527 245533 245561 245563 245587 245591 245593 245621 245627 245629 245639 245653 245671 245681 245683 245711 245719 245723 245741 245747 245753 245759 245771 245783 245789 245821 245849 245851 245863 245881 245897 245899 245909 245911 245941 245963 245977 245981 245983 245989 246011 246017 246049 246073 246097 246119 246121 246131 246133 246151 246167 246173 246187 246193 246203 246209 246217 246223 246241 246247 246251 246271 246277 246289 246317 246319 246329 246343 246349 246361 246371 246391 246403 246439 246469 246473 246497 246509 246511 246523 246527 246539 246557 246569 246577 246599 246607 246611 246613 246637 246641 246643 246661 246683 246689 246707 246709 246713 246731 246739 246769 246773 246781 246787 246793 246803 246809 246811 246817 246833 246839 246889 246899 246907 246913 246919 246923 246929 246931 246937 246941 246947 246971 246979 247001 247007 247031 247067 247069 247073 247087 247099 247141 247183 247193 247201 247223 247229 247241 247249 247259 247279 247301 247309 247337 247339 247343 247363 247369 247381 247391 247393 247409 247421 247433 247439 247451 247463 247501 247519 247529 247531 247547 247553 247579 247591 247601 247603 247607 247609 247613 247633 247649 247651 247691 247693 247697 247711 247717 247729 247739 247759 247769 247771 247781 247799 247811 247813 247829 247847 247853 247873 247879 247889 247901 247913 247939 247943 247957 247991 247993 247997 247999 248021 248033 248041 248051 248057 248063 248071 248077 248089 248099 248117 248119 248137 248141 248161 248167 248177 248179 248189 248201 248203 248231 248243 248257 248267 248291 248293 248299 248309 248317 248323 248351 248357 248371 248389 248401 248407 248431 248441 248447 248461 248473 248477 248483 248509 248533 248537 248543 248569 248579 248587 248593 248597 248609 248621 248627 248639 248641 248657 248683 248701 248707 248719 248723 248737 248749 248753 248779 248783 248789 248797 248813 248821 248827 248839 248851 248861 248867 248869 248879 248887 248891 248893 248903 248909 248971 248981 248987 249017 249037 249059 249079 249089 249097 249103 249107 249127 249131 249133 249143 249181 249187 249199 249211 249217 249229 249233 249253 249257 249287 249311 249317 249329 249341 249367 249377 249383 249397 249419 249421 249427 249433 249437 249439 249449 249463 249497 249499 249503 249517 249521 249533 249539 249541 249563 249583 249589 249593 249607 249647 249659 249671 249677 249703 249721 249727 249737 249749 249763 249779 249797 249811 249827 249833 249853 249857 249859 249863 249871 249881 249911 249923 249943 249947 249967 249971 249973 249989 250007 250013 250027 250031 250037 250043 250049 250051 250057 250073 250091 250109 250123 250147 250153 250169 250199 250253 250259 250267 250279 250301 250307 250343 250361 250403 250409 250423 250433 250441 250451 250489 250499 250501 250543 250583 250619 250643 250673 250681 250687 250693 250703 250709 250721 250727 250739 250741 250751 250753 250777 250787 250793 250799 250807 250813 250829 250837 250841 250853 250867 250871 250889 250919 250949 250951 250963 250967 250969 250979 250993 251003 251033 251051 251057 251059 251063 251071 251081 251087 251099 251117 251143 251149 251159 251171 251177 251179 251191 251197 251201 251203 251219 251221 251231 251233 251257 251261 251263 251287 251291 251297 251323 251347 251353 251359 251387 251393 251417 251429 251431 251437 251443 251467 251473 251477 251483 251491 251501 251513 251519 251527 251533 251539 251543 251561 251567 251609 251611 251621 251623 251639 251653 251663 251677 251701 251707 251737 251761 251789 251791 251809 251831 251833 251843 251857 251861 251879 251887 251893 251897 251903 251917 251939 251941 251947 251969 251971 251983 252001 252013 252017 252029 252037 252079 252101 252139 252143 252151 252157 252163 252169 252173 252181 252193 252209 252223 252233 252253 252277 252283 252289 252293 252313 252319 252323 252341 252359 252383 252391 252401 252409 252419 252431 252443 252449 252457 252463 252481 252509 252533 252541 252559 252583 252589 252607 252611 252617 252641 252667 252691 252709 252713 252727 252731 252737 252761 252767 252779 252817 252823 252827 252829 252869 252877 252881 252887 252893 252899 252911 252913 252919 252937 252949 252971 252979 252983 253003 253013 253049 253063 253081 253103 253109 253133 253153 253157 253159 253229 253243 253247 253273 253307 253321 253343 253349 253361 253367 253369 253381 253387 253417 253423 253427 253433 253439 253447 253469 253481 253493 253501 253507 253531 253537 253543 253553 253567 253573 253601 253607 253609 253613 253633 253637 253639 253651 253661 253679 253681 253703 253717 253733 253741 253751 253763 253769 253777 253787 253789 253801 253811 253819 253823 253853 253867 253871 253879 253901 253907 253909 253919 253937 253949 253951 253969 253987 253993 253999 254003 254021 254027 254039 254041 254047 254053 254071 254083 254119 254141 254147 254161 254179 254197 254207 254209 254213 254249 254257 254279 254281 254291 254299 254329 254369 254377 254383 254389 254407 254413 254437 254447 254461 254489 254491 254519 254537 254557 254593 254623 254627 254647 254659 254663 254699 254713 254729 254731 254741 254747 254753 254773 254777 254783 254791 254803 254827 254831 254833 254857 254869 254873 254879 254887 254899 254911 254927 254929 254941 254959 254963 254971 254977 254987 254993 255007 255019 255023 255043 255049 255053 255071 255077 255083 255097 255107 255121 255127 255133 255137 255149 255173 255179 255181 255191 255193 255197 255209 255217 255239 255247 255251 255253 255259 255313 255329 255349 255361 255371 255383 255413 255419 255443 255457 255467 255469 255473 255487 255499 255503 255511 255517 255523 255551 255571 255587 255589 255613 255617 255637 255641 255649 255653 255659 255667 255679 255709 255713 255733 255743 255757 255763 255767 255803 255839 255841 255847 255851 255859 255869 255877 255887 255907 255917 255919 255923 255947 255961 255971 255973 255977 255989 256019 256021 256031 256033 256049 256057 256079 256093 256117 256121 256129 256133 256147 256163 256169 256181 256187 256189 256199 256211 256219 256279 256301 256307 256313 256337 256349 256363 256369 256391 256393 256423 256441 256469 256471 256483 256489 256493 256499 256517 256541 256561 256567 256577 256579 256589 256603 256609 256639 256643 256651 256661 256687 256699 256721 256723 256757 256771 256799 256801 256813 256831 256873 256877 256889 256901 256903 256931 256939 256957 256967 256981 257003 257017 257053 257069 257077 257093 257099 257107 257123 257141 257161 257171 257177 257189 257219 257221 257239 257249 257263 257273 257281 257287 257293 257297 257311 257321 257339 257351 257353 257371 257381 257399 257401 257407 257437 257443 257447 257459 257473 257489 257497 257501 257503 257519 257539 257561 257591 257611 257627 257639 257657 257671 257687 257689 257707 257711 257713 257717 257731 257783 257791 257797 257837 257857 257861 257863 257867 257869 257879 257893 257903 257921 257947 257953 257981 257987 257989 257993 258019 258023 258031 258061 258067 258101 258107 258109 258113 258119 258127 258131 258143 258157 258161 258173 258197 258211 258233 258241 258253 258277 258283 258299 258317 258319 258329 258331 258337 258353 258373 258389 258403 258407 258413 258421 258437 258443 258449 258469 258487 258491 258499 258521 258527 258539 258551 258563 258569 258581 258607 258611 258613 258617 258623 258631 258637 258659 258673 258677 258691 258697 258703 258707 258721 258733 258737 258743 258763 258779 258787 258803 258809 258827 258847 258871 258887 258917 258919 258949 258959 258967 258971 258977 258983 258991 259001 259009 259019 259033 259099 259121 259123 259151 259157 259159 259163 259169 259177 259183 259201 259211 259213 259219 259229 259271 259277 259309 259321 259339 259379 259381 259387 259397 259411 259421 259429 259451 259453 259459 259499 259507 259517 259531 259537 259547 259577 259583 259603 259619 259621 259627 259631 259639 259643 259657 259667 259681 259691 259697 259717 259723 259733 259751 259771 259781 259783 259801 259813 259823 259829 259837 259841 259867 259907 259933 259937 259943 259949 259967 259991 259993 260003 260009 260011 260017 260023 260047 260081 260089 260111 260137 260171 260179 260189 260191 260201 260207 260209 260213 260231 260263 260269 260317 260329 260339 260363 260387 260399 260411 260413 260417 260419 260441 260453 260461 260467 260483 260489 260527 260539 260543 260549 260551 260569 260573 260581 260587 260609 260629 260647 260651 260671 260677 260713 260717 260723 260747 260753 260761 260773 260791 260807 260809 260849 260857 260861 260863 260873 260879 260893 260921 260941 260951 260959 260969 260983 260987 260999 261011 261013 261017 261031 261043 261059 261061 261071 261077 261089 261101 261127 261167 261169 261223 261229 261241 261251 261271 261281 261301 261323 261329 261337 261347 261353 261379 261389 261407 261427 261431 261433 261439 261451 261463 261467 261509 261523 261529 261557 261563 261577 261581 261587 261593 261601 261619 261631 261637 261641 261643 261673 261697 261707 261713 261721 261739 261757 261761 261773 261787 261791 261799 261823 261847 261881 261887 261917 261959 261971 261973 261977 261983 262007 262027 262049 262051 262069 262079 262103 262109 262111 262121 262127 262133 262139 262147 262151 262153 262187 262193 262217 262231 262237 262253 262261 262271 262303 262313 262321 262331 262337 262349 262351 262369 262387 262391 262399 262411 262433 262459 262469 262489 262501 262511 262513 262519 262541 262543 262553 262567 262583 262597 262621 262627 262643 262649 262651 262657 262681 262693 262697 262709 262723 262733 262739 262741 262747 262781 262783 262807 262819 262853 262877 262883 262897 262901 262909 262937 262949 262957 262981 263009 263023 263047 263063 263071 263077 263083 263089 263101 263111 263119 263129 263167 263171 263183 263191 263201 263209 263213 263227 263239 263257 263267 263269 263273 263287 263293 263303 263323 263369 263383 263387 263399 263401 263411 263423 263429 263437 263443 263489 263491 263503 263513 263519 263521 263533 263537 263561 263567 263573 263591 263597 263609 263611 263621 263647 263651 263657 263677 263723 263729 263737 263759 263761 263803 263819 263821 263827 263843 263849 263863 263867 263869 263881 263899 263909 263911 263927 263933 263941 263951 263953 263957 263983 264007 264013 264029 264031 264053 264059 264071 264083 264091 264101 264113 264127 264133 264137 264139 264167 264169 264179 264211 264221 264263 264269 264283 264289 264301 264323 264331 264343 264349 264353 264359 264371 264391 264403 264437 264443 264463 264487 264527 264529 264553 264559 264577 264581 264599 264601 264619 264631 264637 264643 264659 264697 264731 264739 264743 264749 264757 264763 264769 264779 264787 264791 264793 264811 264827 264829 264839 264871 264881 264889 264893 264899 264919 264931 264949 264959 264961 264977 264991 264997 265003 265007 265021 265037 265079 265091 265093 265117 265123 265129 265141 265151 265157 265163 265169 265193 265207 265231 265241 265247 265249 265261 265271 265273 265277 265313 265333 265337 265339 265381 265399 265403 265417 265423 265427 265451 265459 265471 265483 265493 265511 265513 265541 265543 265547 265561 265567 265571 265579 265607 265613 265619 265621 265703 265709 265711 265717 265729 265739 265747 265757 265781 265787 265807 265813 265819 265831 265841 265847 265861 265871 265873 265883 265891 265921 265957 265961 265987 266003 266009 266023 266027 266029 266047 266051 266053 266059 266081 266083 266089 266093 266099 266111 266117 266129 266137 266153 266159 266177 266183 266221 266239 266261 266269 266281 266291 266293 266297 266333 266351 266353 266359 266369 266381 266401 266411 266417 266447 266449 266477 266479 266489 266491 266521 266549 266587 266599 266603 266633 266641 266647 266663 266671 266677 266681 266683 266687 266689 266701 266711 266719 266759 266767 266797 266801 266821 266837 266839 266863 266867 266891 266897 266899 266909 266921 266927 266933 266947 266953 266957 266971 266977 266983 266993 266999 267017 267037 267049 267097 267131 267133 267139 267143 267167 267187 267193 267199 267203 267217 267227 267229 267233 267259 267271 267277 267299 267301 267307 267317 267341 267353 267373 267389 267391 267401 267403 267413 267419 267431 267433 267439 267451 267469 267479 267481 267493 267497 267511 267517 267521 267523 267541 267551 267557 267569 267581 267587 267593 267601 267611 267613 267629 267637 267643 267647 267649 267661 267667 267671 267677 267679 267713 267719 267721 267727 267737 267739 267749 267763 267781 267791 267797 267803 267811 267829 267833 267857 267863 267877 267887 267893 267899 267901 267907 267913 267929 267941 267959 267961 268003 268013 268043 268049 268063 268069 268091 268123 268133 268153 268171 268189 268199 268207 268211 268237 268253 268267 268271 268283 268291 268297 268343 268403 268439 268459 268487 268493 268501 268507 268517 268519 268529 268531 268537 268547 268573 268607 268613 268637 268643 268661 268693 268721 268729 268733 268747 268757 268759 268771 268777 268781 268783 268789 268811 268813 268817 268819 268823 268841 268843 268861 268883 268897 268909 268913 268921 268927 268937 268969 268973 268979 268993 268997 268999 269023 269029 269039 269041 269057 269063 269069 269089 269117 269131 269141 269167 269177 269179 269183 269189 269201 269209 269219 269221 269231 269237 269251 269257 269281 269317 269327 269333 269341 269351 269377 269383 269387 269389 269393 269413 269419 269429 269431 269441 269461 269473 269513 269519 269527 269539 269543 269561 269573 269579 269597 269617 269623 269641 269651 269663 269683 269701 269713 269719 269723 269741 269749 269761 269779 269783 269791 269851 269879 269887 269891 269897 269923 269939 269947 269953 269981 269987 270001 270029 270031 270037 270059 270071 270073 270097 270121 270131 270133 270143 270157 270163 270167 270191 270209 270217 270223 270229 270239 270241 270269 270271 270287 270299 270307 270311 270323 270329 270337 270343 270371 270379 270407 270421 270437 270443 270451 270461 270463 270493 270509 270527 270539 270547 270551 270553 270563 270577 270583 270587 270593 270601 270619 270631 270653 270659 270667 270679 270689 270701 270709 270719 270737 270749 270761 270763 270791 270797 270799 270821 270833 270841 270859 270899 270913 270923 270931 270937 270953 270961 270967 270973 271003 271013 271021 271027 271043 271057 271067 271079 271097 271109 271127 271129 271163 271169 271177 271181 271211 271217 271231 271241 271253 271261 271273 271277 271279 271289 271333 271351 271357 271363 271367 271393 271409 271429 271451 271463 271471 271483 271489 271499 271501 271517 271549 271553 271571 271573 271597 271603 271619 271637 271639 271651 271657 271693 271703 271723 271729 271753 271769 271771 271787 271807 271811 271829 271841 271849 271853 271861 271867 271879 271897 271903 271919 271927 271939 271967 271969 271981 272003 272009 272011 272029 272039 272053 272059 272093 272131 272141 272171 272179 272183 272189 272191 272201 272203 272227 272231 272249 272257 272263 272267 272269 272287 272299 272317 272329 272333 272341 272347 272351 272353 272359 272369 272381 272383 272399 272407 272411 272417 272423 272449 272453 272477 272507 272533 272537 272539 272549 272563 272567 272581 272603 272621 272651 272659 272683 272693 272717 272719 272737 272759 272761 272771 272777 272807 272809 272813 272863 272879 272887 272903 272911 272917 272927 272933 272959 272971 272981 272983 272989 272999 273001 273029 273043 273047 273059 273061 273067 273073 273083 273107 273113 273127 273131 273149 273157 273181 273187 273193 273233 273253 273269 273271 273281 273283 273289 273311 273313 273323 273349 273359 273367 273433 273457 273473 273503 273517 273521 273527 273551 273569 273601 273613 273617 273629 273641 273643 273653 273697 273709 273719 273727 273739 273773 273787 273797 273803 273821 273827 273857 273881 273899 273901 273913 273919 273929 273941 273943 273967 273971 273979 273997 274007 274019 274033 274061 274069 274081 274093 274103 274117 274121 274123 274139 274147 274163 274171 274177 274187 274199 274201 274213 274223 274237 274243 274259 274271 274277 274283 274301 274333 274349 274357 274361 274403 274423 274441 274451 274453 274457 274471 274489 274517 274529 274579 274583 274591 274609 274627 274661 274667 274679 274693 274697 274709 274711 274723 274739 274751 274777 274783 274787 274811 274817 274829 274831 274837 274843 274847 274853 274861 274867 274871 274889 274909 274931 274943 274951 274957 274961 274973 274993 275003 275027 275039 275047 275053 275059 275083 275087 275129 275131 275147 275153 275159 275161 275167 275183 275201 275207 275227 275251 275263 275269 275299 275309 275321 275323 275339 275357 275371 275389 275393 275399 275419 275423 275447 275449 275453 275459 275461 275489 275491 275503 275521 275531 275543 275549 275573 275579 275581 275591 275593 275599 275623 275641 275651 275657 275669 275677 275699 275711 275719 275729 275741 275767 275773 275783 275813 275827 275837 275881 275897 275911 275917 275921 275923 275929 275939 275941 275963 275969 275981 275987 275999 276007 276011 276019 276037 276041 276043 276047 276049 276079 276083 276091 276113 276137 276151 276173 276181 276187 276191 276209 276229 276239 276247 276251 276257 276277 276293 276319 276323 276337 276343 276347 276359 276371 276373 276389 276401 276439 276443 276449 276461 276467 276487 276499 276503 276517 276527 276553 276557 276581 276587 276589 276593 276599 276623 276629 276637 276671 276673 276707 276721 276739 276763 276767 276779 276781 276817 276821 276823 276827 276833 276839 276847 276869 276883 276901 276907 276917 276919 276929 276949 276953 276961 276977 277003 277007 277021 277051 277063 277073 277087 277097 277099 277157 277163 277169 277177 277183 277213 277217 277223 277231 277247 277259 277261 277273 277279 277297 277301 277309 277331 277363 277373 277411 277421 277427 277429 277483 277493 277499 277513 277531 277547 277549 277567 277577 277579 277597 277601 277603 277637 277639 277643 277657 277663 277687 277691 277703 277741 277747 277751 277757 277787 277789 277793 277813 277829 277847 277859 277883 277889 277891 277897 277903 277919 277961 277993 277999 278017 278029 278041 278051 278063 278071 278087 278111 278119 278123 278143 278147 278149 278177 278191 278207 278209 278219 278227 278233 278237 278261 278269 278279 278321 278329 278347 278353 278363 278387 278393 278413 278437 278459 278479 278489 278491 278497 278501 278503 278543 278549 278557 278561 278563 278581 278591 278609 278611 278617 278623 278627 278639 278651 278671 278687 278689 278701 278717 278741 278743 278753 278767 278801 278807 278809 278813 278819 278827 278843 278849 278867 278879 278881 278891 278903 278909 278911 278917 278947 278981 279001 279007 279023 279029 279047 279073 279109 279119 279121 279127 279131 279137 279143 279173 279179 279187 279203 279211 279221 279269 279311 279317 279329 279337 279353 279397 279407 279413 279421 279431 279443 279451 279479 279481 279511 279523 279541 279551 279553 279557 279571 279577 279583 279593 279607 279613 279619 279637 279641 279649 279659 279679 279689 279707 279709 279731 279751 279761 279767 279779 279817 279823 279847 279857 279863 279883 279913 279919 279941 279949 279967 279977 279991 280001 280009 280013 280031 280037 280061 280069 280097 280099 280103 280121 280129 280139 280183 280187 280199 280207 280219 280223 280229 280243 280249 280253 280277 280297 280303 280321 280327 280337 280339 280351 280373 280409 280411 280451 280463 280487 280499 280507 280513 280537 280541 280547 280549 280561 280583 280589 280591 280597 280603 280607 280613 280627 280639 280673 280681 280697 280699 280703 280711 280717 280729 280751 280759 280769 280771 280811 280817 280837 280843 280859 280871 280879 280883 280897 280909 280913 280921 280927 280933 280939 280949 280957 280963 280967 280979 280997 281023 281033 281053 281063 281069 281081 281117 281131 281153 281159 281167 281189 281191 281207 281227 281233 281243 281249 281251 281273 281279 281291 281297 281317 281321 281327 281339 281353 281357 281363 281381 281419 281423 281429 281431 281509 281527 281531 281539 281549 281551 281557 281563 281579 281581 281609 281621 281623 281627 281641 281647 281651 281653 281663 281669 281683 281717 281719 281737 281747 281761 281767 281777 281783 281791 281797 281803 281807 281833 281837 281839 281849 281857 281867 281887 281893 281921 281923 281927 281933 281947 281959 281971 281989 281993 282001 282011 282019 282053 282059 282071 282089 282091 282097 282101 282103 282127 282143 282157 282167 282221 282229 282239 282241 282253 282281 282287 282299 282307 282311 282313 282349 282377 282383 282389 282391 282407 282409 282413 282427 282439 282461 282481 282487 282493 282559 282563 282571 282577 282589 282599 282617 282661 282671 282677 282679 282683 282691 282697 282703 282707 282713 282767 282769 282773 282797 282809 282827 282833 282847 282851 282869 282881 282889 282907 282911 282913 282917 282959 282973 282977 282991 283001 283007 283009 283027 283051 283079 283093 283097 283099 283111 283117 283121 283133 283139 283159 283163 283181 283183 283193 283207 283211 283267 283277 283289 283303 283369 283397 283403 283411 283447 283463 283487 283489 283501 283511 283519 283541 283553 283571 283573 283579 283583 283601 283607 283609 283631 283637 283639 283669 283687 283697 283721 283741 283763 283769 283771 283793 283799 283807 283813 283817 283831 283837 283859 283861 283873 283909 283937 283949 283957 283961 283979 284003 284023 284041 284051 284057 284059 284083 284093 284111 284117 284129 284131 284149 284153 284159 284161 284173 284191 284201 284227 284231 284233 284237 284243 284261 284267 284269 284293 284311 284341 284357 284369 284377 284387 284407 284413 284423 284429 284447 284467 284477 284483 284489 284507 284509 284521 284527 284539 284551 284561 284573 284587 284591 284593 284623 284633 284651 284657 284659 284681 284689 284701 284707 284723 284729 284731 284737 284741 284743 284747 284749 284759 284777 284783 284803 284807 284813 284819 284831 284833 284839 284857 284881 284897 284899 284917 284927 284957 284969 284989 285007 285023 285031 285049 285071 285079 285091 285101 285113 285119 285121 285139 285151 285161 285179 285191 285199 285221 285227 285251 285281 285283 285287 285289 285301 285317 285343 285377 285421 285433 285451 285457 285463 285469 285473 285497 285517 285521 285533 285539 285553 285557 285559 285569 285599 285611 285613 285629 285631 285641 285643 285661 285667 285673 285697 285707 285709 285721 285731 285749 285757 285763 285767 285773 285781 285823 285827 285839 285841 285871 285937 285949 285953 285977 285979 285983 285997 286001 286009 286019 286043 286049 286061 286063 286073 286103 286129 286163 286171 286199 286243 286249 286289 286301 286333 286367 286369 286381 286393 286397 286411 286421 286427 286453 286457 286459 286469 286477 286483 286487 286493 286499 286513 286519 286541 286543 286547 286553 286589 286591 286609 286613 286619 286633 286651 286673 286687 286697 286703 286711 286721 286733 286751 286753 286763 286771 286777 286789 286801 286813 286831 286859 286873 286927 286973 286981 286987 286999 287003 287047 287057 287059 287087 287093 287099 287107 287117 287137 287141 287149 287159 287167 287173 287179 287191 287219 287233 287237 287239 287251 287257 287269 287279 287281 287291 287297 287321 287327 287333 287341 287347 287383 287387 287393 287437 287449 287491 287501 287503 287537 287549 287557 287579 287597 287611 287629 287669 287671 287681 287689 287701 287731 287747 287783 287789 287801 287813 287821 287849 287851 287857 287863 287867 287873 287887 287921 287933 287939 287977 288007 288023 288049 288053 288061 288077 288089 288109 288137 288179 288181 288191 288199 288203 288209 288227 288241 288247 288257 288283 288293 288307 288313 288317 288349 288359 288361 288383 288389 288403 288413 288427 288433 288461 288467 288481 288493 288499 288527 288529 288539 288551 288559 288571 288577 288583 288647 288649 288653 288661 288679 288683 288689 288697 288731 288733 288751 288767 288773 288803 288817 288823 288833 288839 288851 288853 288877 288907 288913 288929 288931 288947 288973 288979 288989 288991 288997 289001 289019 289021 289031 289033 289039 289049 289063 289067 289099 289103 289109 289111 289127 289129 289139 289141 289151 289169 289171 289181 289189 289193 289213 289241 289243 289249 289253 289273 289283 289291 289297 289309 289319 289343 289349 289361 289369 289381 289397 289417 289423 289439 289453 289463 289469 289477 289489 289511 289543 289559 289573 289577 289589 289603 289607 289637 289643 289657 289669 289717 289721 289727 289733 289741 289759 289763 289771 289789 289837 289841 289843 289847 289853 289859 289871 289889 289897 289937 289951 289957 289967 289973 289987 289999 290011 290021 290023 290027 290033 290039 290041 290047 290057 290083 290107 290113 290119 290137 290141 290161 290183 290189 290201 290209 290219 290233 290243 290249 290317 290327 290347 290351 290359 290369 290383 290393 290399 290419 290429 290441 290443 290447 290471 290473 290489 290497 290509 290527 290531 290533 290539 290557 290593 290597 290611 290617 290621 290623 290627 290657 290659 290663 290669 290671 290677 290701 290707 290711 290737 290761 290767 290791 290803 290821 290827 290837 290839 290861 290869 290879 290897 290923 290959 290963 290971 290987 290993 290999 291007 291013 291037 291041 291043 291077 291089 291101 291103 291107 291113 291143 291167 291169 291173 291191 291199 291209 291217 291253 291257 291271 291287 291293 291299 291331 291337 291349 291359 291367 291371 291373 291377 291419 291437 291439 291443 291457 291481 291491 291503 291509 291521 291539 291547 291559 291563 291569 291619 291647 291649 291661 291677 291689 291691 291701 291721 291727 291743 291751 291779 291791 291817 291829 291833 291853 291857 291869 291877 291887 291899 291901 291923 291971 291979 291983 291997 292021 292027 292037 292057 292069 292079 292081 292091 292093 292133 292141 292147 292157 292181 292183 292223 292231 292241 292249 292267 292283 292301 292309 292319 292343 292351 292363 292367 292381 292393 292427 292441 292459 292469 292471 292477 292483 292489 292493 292517 292531 292541 292549 292561 292573 292577 292601 292627 292631 292661 292667 292673 292679 292693 292703 292709 292711 292717 292727 292753 292759 292777 292793 292801 292807 292819 292837 292841 292849 292867 292879 292909 292921 292933 292969 292973 292979 292993 293021 293071 293081 293087 293093 293099 293107 293123 293129 293147 293149 293173 293177 293179 293201 293207 293213 293221 293257 293261 293263 293269 293311 293329 293339 293351 293357 293399 293413 293431 293441 293453 293459 293467 293473 293483 293507 293543 293599 293603 293617 293621 293633 293639 293651 293659 293677 293681 293701 293717 293723 293729 293749 293767 293773 293791 293803 293827 293831 293861 293863 293893 293899 293941 293957 293983 293989 293999 294001 294013 294023 294029 294043 294053 294059 294067 294103 294127 294131 294149 294157 294167 294169 294179 294181 294199 294211 294223 294227 294241 294247 294251 294269 294277 294289 294293 294311 294313 294317 294319 294337 294341 294347 294353 294383 294391 294397 294403 294431 294439 294461 294467 294479 294499 294509 294523 294529 294551 294563 294629 294641 294647 294649 294659 294673 294703 294731 294751 294757 294761 294773 294781 294787 294793 294799 294803 294809 294821 294829 294859 294869 294887 294893 294911 294919 294923 294947 294949 294953 294979 294989 294991 294997 295007 295033 295037 295039 295049 295073 295079 295081 295111 295123 295129 295153 295187 295199 295201 295219 295237 295247 295259 295271 295277 295283 295291 295313 295319 295333 295357 295363 295387 295411 295417 295429 295433 295439 295441 295459 295513 295517 295541 295553 295567 295571 295591 295601 295663 295693 295699 295703 295727 295751 295759 295769 295777 295787 295819 295831 295837 295843 295847 295853 295861 295871 295873 295877 295879 295901 295903 295909 295937 295943 295949 295951 295961 295973 295993 296011 296017 296027 296041 296047 296071 296083 296099 296117 296129 296137 296159 296183 296201 296213 296221 296237 296243 296249 296251 296269 296273 296279 296287 296299 296347 296353 296363 296369 296377 296437 296441 296473 296477 296479 296489 296503 296507 296509 296519 296551 296557 296561 296563 296579 296581 296587 296591 296627 296651 296663 296669 296683 296687 296693 296713 296719 296729 296731 296741 296749 296753 296767 296771 296773 296797 296801 296819 296827 296831 296833 296843 296909 296911 296921 296929 296941 296969 296971 296981 296983 296987 297019 297023 297049 297061 297067 297079 297083 297097 297113 297133 297151 297161 297169 297191 297233 297247 297251 297257 297263 297289 297317 297359 297371 297377 297391 297397 297403 297421 297439 297457 297467 297469 297481 297487 297503 297509 297523 297533 297581 297589 297601 297607 297613 297617 297623 297629 297641 297659 297683 297691 297707 297719 297727 297757 297779 297793 297797 297809 297811 297833 297841 297853 297881 297889 297893 297907 297911 297931 297953 297967 297971 297989 297991 298013 298021 298031 298043 298049 298063 298087 298093 298099 298153 298157 298159 298169 298171 298187 298201 298211 298213 298223 298237 298247 298261 298283 298303 298307 298327 298339 298343 298349 298369 298373 298399 298409 298411 298427 298451 298477 298483 298513 298559 298579 298583 298589 298601 298607 298621 298631 298651 298667 298679 298681 298687 298691 298693 298709 298723 298733 298757 298759 298777 298799 298801 298817 298819 298841 298847 298853 298861 298897 298937 298943 298993 298999 299011 299017 299027 299029 299053 299059 299063 299087 299099 299107 299113 299137 299147 299171 299179 299191 299197 299213 299239 299261 299281 299287 299311 299317 299329 299333 299357 299359 299363 299371 299389 299393 299401 299417 299419 299447 299471 299473 299477 299479 299501 299513 299521 299527 299539 299567 299569 299603 299617 299623 299653 299671 299681 299683 299699 299701 299711 299723 299731 299743 299749 299771 299777 299807 299843 299857 299861 299881 299891 299903 299909 299933 299941 299951 299969 299977 299983 299993 300007 300017 300023 300043 300073 300089 300109 300119 300137 300149 300151 300163 300187 300191 300193 300221 300229 300233 300239 300247 300277 300299 300301 300317 300319 300323 300331 300343 300347 300367 300397 300413 300427 300431 300439 300463 300481 300491 300493 300497 300499 300511 300557 300569 300581 300583 300589 300593 300623 300631 300647 300649 300661 300667 300673 300683 300691 300719 300721 300733 300739 300743 300749 300757 300761 300779 300787 300799 300809 300821 300823 300851 300857 300869 300877 300889 300893 300929 300931 300953 300961 300967 300973 300977 300997 301013 301027 301039 301051 301057 301073 301079 301123 301127 301141 301153 301159 301177 301181 301183 301211 301219 301237 301241 301243 301247 301267 301303 301319 301331 301333 301349 301361 301363 301381 301403 301409 301423 301429 301447 301459 301463 301471 301487 301489 301493 301501 301531 301577 301579 301583 301591 301601 301619 301627 301643 301649 301657 301669 301673 301681 301703 301711 301747 301751 301753 301759 301789 301793 301813 301831 301841 301843 301867 301877 301897 301901 301907 301913 301927 301933 301943 301949 301979 301991 301993 301997 301999 302009 302053 302111 302123 302143 302167 302171 302173 302189 302191 302213 302221 302227 302261 302273 302279 302287 302297 302299 302317 302329 302399 302411 302417 302429 302443 302459 302483 302507 302513 302551 302563 302567 302573 302579 302581 302587 302593 302597 302609 302629 302647 302663 302681 302711 302723 302747 302759 302767 302779 302791 302801 302831 302833 302837 302843 302851 302857 302873 302891 302903 302909 302921 302927 302941 302959 302969 302971 302977 302983 302989 302999 303007 303011 303013 303019 303029 303049 303053 303073 303089 303091 303097 303119 303139 303143 303151 303157 303187 303217 303257 303271 303283 303287 303293 303299 303307 303313 303323 303337 303341 303361 303367 303371 303377 303379 303389 303409 303421 303431 303463 303469 303473 303491 303493 303497 303529 303539 303547 303551 303553 303571 303581 303587 303593 303613 303617 303619 303643 303647 303649 303679 303683 303689 303691 303703 303713 303727 303731 303749 303767 303781 303803 303817 303827 303839 303859 303871 303889 303907 303917 303931 303937 303959 303983 303997 304009 304013 304021 304033 304039 304049 304063 304067 304069 304081 304091 304099 304127 304151 304153 304163 304169 304193 304211 304217 304223 304253 304259 304279 304301 304303 304331 304349 304357 304363 304373 304391 304393 304411 304417 304429 304433 304439 304457 304459 304477 304481 304489 304501 304511 304517 304523 304537 304541 304553 304559 304561 304597 304609 304631 304643 304651 304663 304687 304709 304723 304729 304739 304751 304757 304763 304771 304781 304789 304807 304813 304831 304847 304849 304867 304879 304883 304897 304901 304903 304907 304933 304937 304943 304949 304961 304979 304981 305017 305021 305023 305029 305033 305047 305069 305093 305101 305111 305113 305119 305131 305143 305147 305209 305219 305231 305237 305243 305267 305281 305297 305329 305339 305351 305353 305363 305369 305377 305401 305407 305411 305413 305419 305423 305441 305449 305471 305477 305479 305483 305489 305497 305521 305533 305551 305563 305581 305593 305597 305603 305611 305621 305633 305639 305663 305717 305719 305741 305743 305749 305759 305761 305771 305783 305803 305821 305839 305849 305857 305861 305867 305873 305917 305927 305933 305947 305971 305999 306011 306023 306029 306041 306049 306083 306091 306121 306133 306139 306149 306157 306167 306169 306191 306193 306209 306239 306247 306253 306259 306263 306301 306329 306331 306347 306349 306359 306367 306377 306389 306407 306419 306421 306431 306437 306457 306463 306473 306479 306491 306503 306511 306517 306529 306533 306541 306563 306577 306587 306589 306643 306653 306661 306689 306701 306703 306707 306727 306739 306749 306763 306781 306809 306821 306827 306829 306847 306853 306857 306871 306877 306883 306893 306899 306913 306919 306941 306947 306949 306953 306991 307009 307019 307031 307033 307067 307079 307091 307093 307103 307121 307129 307147 307163 307169 307171 307187 307189 307201 307243 307253 307259 307261 307267 307273 307277 307283 307289 307301 307337 307339 307361 307367 307381 307397 307399 307409 307423 307451 307471 307481 307511 307523 307529 307537 307543 307577 307583 307589 307609 307627 307631 307633 307639 307651 307669 307687 307691 307693 307711 307733 307759 307817 307823 307831 307843 307859 307871 307873 307891 307903 307919 307939 307969 308003 308017 308027 308041 308051 308081 308093 308101 308107 308117 308129 308137 308141 308149 308153 308213 308219 308249 308263 308291 308293 308303 308309 308311 308317 308323 308327 308333 308359 308383 308411 308423 308437 308447 308467 308489 308491 308501 308507 308509 308519 308521 308527 308537 308551 308569 308573 308587 308597 308621 308639 308641 308663 308681 308701 308713 308723 308761 308773 308801 308809 308813 308827 308849 308851 308857 308887 308899 308923 308927 308929 308933 308939 308951 308989 308999 309007 309011 309013 309019 309031 309037 309059 309079 309083 309091 309107 309109 309121 309131 309137 309157 309167 309173 309193 309223 309241 309251 309259 309269 309271 309277 309289 309293 309311 309313 309317 309359 309367 309371 309391 309403 309433 309437 309457 309461 309469 309479 309481 309493 309503 309521 309523 309539 309541 309559 309571 309577 309583 309599 309623 309629 309637 309667 309671 309677 309707 309713 309731 309737 309769 309779 309781 309797 309811 309823 309851 309853 309857 309877 309899 309929 309931 309937 309977 309989 310019 310021 310027 310043 310049 310081 310087 310091 310111 310117 310127 310129 310169 310181 310187 310223 310229 310231 310237 310243 310273 310283 310291 310313 310333 310357 310361 310363 310379 310397 310423 310433 310439 310447 310459 310463 310481 310489 310501 310507 310511 310547 310553 310559 310567 310571 310577 310591 310627 310643 310663 310693 310697 310711 310721 310727 310729 310733 310741 310747 310771 310781 310789 310801 310819 310823 310829 310831 310861 310867 310883 310889 310901 310927 310931 310949 310969 310987 310997 311009 311021 311027 311033 311041 311099 311111 311123 311137 311153 311173 311177 311183 311189 311197 311203 311237 311279 311291 311293 311299 311303 311323 311329 311341 311347 311359 311371 311393 311407 311419 311447 311453 311473 311533 311537 311539 311551 311557 311561 311567 311569 311603 311609 311653 311659 311677 311681 311683 311687 311711 311713 311737 311743 311747 311749 311791 311803 311807 311821 311827 311867 311869 311881 311897 311951 311957 311963 311981 312007 312023 312029 312031 312043 312047 312071 312073 312083 312089 312101 312107 312121 312161 312197 312199 312203 312209 312211 312217 312229 312233 312241 312251 312253 312269 312281 312283 312289 312311 312313 312331 312343 312349 312353 312371 312383 312397 312401 312407 312413 312427 312451 312469 312509 312517 312527 312551 312553 312563 312581 312583 312589 312601 312617 312619 312623 312643 312673 312677 312679 312701 312703 312709 312727 312737 312743 312757 312773 312779 312799 312839 312841 312857 312863 312887 312899 312929 312931 312937 312941 312943 312967 312971 312979 312989 313003 313009 313031 313037 313081 313087 313109 313127 313129 313133 313147 313151 313153 313163 313207 313211 313219 313241 313249 313267 313273 313289 313297 313301 313307 313321 313331 313333 313343 313351 313373 313381 313387 313399 313409 313471 313477 313507 313517 313543 313549 313553 313561 313567 313571 313583 313589 313597 313603 313613 313619 313637 313639 313661 313669 313679 313699 313711 313717 313721 313727 313739 313741 313763 313777 313783 313829 313849 313853 313879 313883 313889 313897 313909 313921 313931 313933 313949 313961 313969 313979 313981 313987 313991 313993 313997 314003 314021 314059 314063 314077 314107 314113 314117 314129 314137 314159 314161 314173 314189 314213 314219 314227 314233 314239 314243 314257 314261 314263 314267 314299 314329 314339 314351 314357 314359 314399 314401 314407 314423 314441 314453 314467 314491 314497 314513 314527 314543 314549 314569 314581 314591 314597 314599 314603 314623 314627 314641 314651 314693 314707 314711 314719 314723 314747 314761 314771 314777 314779 314807 314813 314827 314851 314879 314903 314917 314927 314933 314953 314957 314983 314989 315011 315013 315037 315047 315059 315067 315083 315097 315103 315109 315127 315179 315181 315193 315199 315223 315247 315251 315257 315269 315281 315313 315349 315361 315373 315377 315389 315407 315409 315421 315437 315449 315451 315461 315467 315481 315493 315517 315521 315527 315529 315547 315551 315559 315569 315589 315593 315599 315613 315617 315631 315643 315671 315677 315691 315697 315701 315703 315739 315743 315751 315779 315803 315811 315829 315851 315857 315881 315883 315893 315899 315907 315937 315949 315961 315967 315977 316003 316031 316033 316037 316051 316067 316073 316087 316097 316109 316133 316139 316153 316177 316189 316193 316201 316213 316219 316223 316241 316243 316259 316271 316291 316297 316301 316321 316339 316343 316363 316373 316391 316403 316423 316429 316439 316453 316469 316471 316493 316499 316501 316507 316531 316567 316571 316577 316583 316621 316633 316637 316649 316661 316663 316681 316691 316697 316699 316703 316717 316753 316759 316769 316777 316783 316793 316801 316817 316819 316847 316853 316859 316861 316879 316891 316903 316907 316919 316937 316951 316957 316961 316991 317003 317011 317021 317029 317047 317063 317071 317077 317087 317089 317123 317159 317171 317179 317189 317197 317209 317227 317257 317263 317267 317269 317279 317321 317323 317327 317333 317351 317353 317363 317371 317399 317411 317419 317431 317437 317453 317459 317483 317489 317491 317503 317539 317557 317563 317587 317591 317593 317599 317609 317617 317621 317651 317663 317671 317693 317701 317711 317717 317729 317731 317741 317743 317771 317773 317777 317783 317789 317797 317827 317831 317839 317857 317887 317903 317921 317923 317957 317959 317963 317969 317971 317983 317987 318001 318007 318023 318077 318103 318107 318127 318137 318161 318173 318179 318181 318191 318203 318209 318211 318229 318233 318247 318259 318271 318281 318287 318289 318299 318301 318313 318319 318323 318337 318347 318349 318377 318403 318407 318419 318431 318443 318457 318467 318473 318503 318523 318557 318559 318569 318581 318589 318601 318629 318641 318653 318671 318677 318679 318683 318691 318701 318713 318737 318743 318749 318751 318781 318793 318809 318811 318817 318823 318833 318841 318863 318881 318883 318889 318907 318911 318917 318919 318949 318979 319001 319027 319031 319037 319049 319057 319061 319069 319093 319097 319117 319127 319129 319133 319147 319159 319169 319183 319201 319211 319223 319237 319259 319279 319289 319313 319321 319327 319339 319343 319351 319357 319387 319391 319399 319411 319427 319433 319439 319441 319453 319469 319477 319483 319489 319499 319511 319519 319541 319547 319567 319577 319589 319591 319601 319607 319639 319673 319679 319681 319687 319691 319699 319727 319729 319733 319747 319757 319763 319811 319817 319819 319829 319831 319849 319883 319897 319901 319919 319927 319931 319937 319967 319973 319981 319993 320009 320011 320027 320039 320041 320053 320057 320063 320081 320083 320101 320107 320113 320119 320141 320143 320149 320153 320179 320209 320213 320219 320237 320239 320267 320269 320273 320291 320293 320303 320317 320329 320339 320377 320387 320389 320401 320417 320431 320449 320471 320477 320483 320513 320521 320533 320539 320561 320563 320591 320609 320611 320627 320647 320657 320659 320669 320687 320693 320699 320713 320741 320759 320767 320791 320821 320833 320839 320843 320851 320861 320867 320899 320911 320923 320927 320939 320941 320953 321007 321017 321031 321037 321047 321053 321073 321077 321091 321109 321143 321163 321169 321187 321193 321199 321203 321221 321227 321239 321247 321289 321301 321311 321313 321319 321323 321329 321331 321341 321359 321367 321371 321383 321397 321403 321413 321427 321443 321449 321467 321469 321509 321547 321553 321569 321571 321577 321593 321611 321617 321619 321631 321647 321661 321679 321707 321709 321721 321733 321743 321751 321757 321779 321799 321817 321821 321823 321829 321833 321847 321851 321889 321901 321911 321947 321949 321961 321983 321991 322001 322009 322013 322037 322039 322051 322057 322067 322073 322079 322093 322097 322109 322111 322139 322169 322171 322193 322213 322229 322237 322243 322247 322249 322261 322271 322319 322327 322339 322349 322351 322397 322403 322409 322417 322429 322433 322459 322463 322501 322513 322519 322523 322537 322549 322559 322571 322573 322583 322589 322591 322607 322613 322627 322631 322633 322649 322669 322709 322727 322747 322757 322769 322771 322781 322783 322807 322849 322859 322871 322877 322891 322901 322919 322921 322939 322951 322963 322969 322997 322999 323003 323009 323027 323053 323077 323083 323087 323093 323101 323123 323131 323137 323149 323201 323207 323233 323243 323249 323251 323273 323333 323339 323341 323359 323369 323371 323377 323381 323383 323413 323419 323441 323443 323467 323471 323473 323507 323509 323537 323549 323567 323579 323581 323591 323597 323599 323623 323641 323647 323651 323699 323707 323711 323717 323759 323767 323789 323797 323801 323803 323819 323837 323879 323899 323903 323923 323927 323933 323951 323957 323987 324011 324031 324053 324067 324073 324089 324097 324101 324113 324119 324131 324143 324151 324161 324179 324199 324209 324211 324217 324223 324239 324251 324293 324299 324301 324319 324329 324341 324361 324391 324397 324403 324419 324427 324431 324437 324439 324449 324451 324469 324473 324491 324497 324503 324517 324523 324529 324557 324587 324589 324593 324617 324619 324637 324641 324647 324661 324673 324689 324697 324707 324733 324743 324757 324763 324773 324781 324791 324799 324809 324811 324839 324847 324869 324871 324889 324893 324901 324931 324941 324949 324953 324977 324979 324983 324991 324997 325001 325009 325019 325021 325027 325043 325051 325063 325079 325081 325093 325133 325153 325163 325181 325187 325189 325201 325217 325219 325229 325231 325249 325271 325301 325307 325309 325319 325333 325343 325349 325379 325411 325421 325439 325447 325453 325459 325463 325477 325487 325513 325517 325537 325541 325543 325571 325597 325607 325627 325631 325643 325667 325673 325681 325691 325693 325697 325709 325723 325729 325747 325751 325753 325769 325777 325781 325783 325807 325813 325849 325861 325877 325883 325889 325891 325901 325921 325939 325943 325951 325957 325987 325993 325999 326023 326057 326063 326083 326087 326099 326101 326113 326119 326141 326143 326147 326149 326153 326159 326171 326189 326203 326219 326251 326257 326309 326323 326351 326353 326369 326437 326441 326449 326467 326479 326497 326503 326537 326539 326549 326561 326563 326567 326581 326593 326597 326609 326611 326617 326633 326657 326659 326663 326681 326687 326693 326701 326707 326737 326741 326773 326779 326831 326863 326867 326869 326873 326881 326903 326923 326939 326941 326947 326951 326983 326993 326999 327001 327007 327011 327017 327023 327059 327071 327079 327127 327133 327163 327179 327193 327203 327209 327211 327247 327251 327263 327277 327289 327307 327311 327317 327319 327331 327337 327343 327347 327401 327407 327409 327419 327421 327433 327443 327463 327469 327473 327479 327491 327493 327499 327511 327517 327529 327553 327557 327559 327571 327581 327583 327599 327619 327629 327647 327661 327667 327673 327689 327707 327721 327737 327739 327757 327779 327797 327799 327809 327823 327827 327829 327839 327851 327853 327869 327871 327881 327889 327917 327923 327941 327953 327967 327979 327983 328007 328037 328043 328051 328061 328063 328067 328093 328103 328109 328121 328127 328129 328171 328177 328213 328243 328249 328271 328277 328283 328291 328303 328327 328331 328333 328343 328357 328373 328379 328381 328397 328411 328421 328429 328439 328481 328511 328513 328519 328543 328579 328589 328591 328619 328621 328633 328637 328639 328651 328667 328687 328709 328721 328753 328777 328781 328787 328789 328813 328829 328837 328847 328849 328883 328891 328897 328901 328919 328921 328931 328961 328981 329009 329027 329053 329059 329081 329083 329089 329101 329111 329123 329143 329167 329177 329191 329201 329207 329209 329233 329243 329257 329267 329269 329281 329293 329297 329299 329309 329317 329321 329333 329347 329387 329393 329401 329419 329431 329471 329473 329489 329503 329519 329533 329551 329557 329587 329591 329597 329603 329617 329627 329629 329639 329657 329663 329671 329677 329683 329687 329711 329717 329723 329729 329761 329773 329779 329789 329801 329803 329863 329867 329873 329891 329899 329941 329947 329951 329957 329969 329977 329993 329999 330017 330019 330037 330041 330047 330053 330061 330067 330097 330103 330131 330133 330139 330149 330167 330199 330203 330217 330227 330229 330233 330241 330247 330271 330287 330289 330311 330313 330329 330331 330347 330359 330383 330389 330409 330413 330427 330431 330433 330439 330469 330509 330557 330563 330569 330587 330607 330611 330623 330641 330643 330653 330661 330679 330683 330689 330697 330703 330719 330721 330731 330749 330767 330787 330791 330793 330821 330823 330839 330853 330857 330859 330877 330887 330899 330907 330917 330943 330983 330997 331013 331027 331031 331043 331063 331081 331099 331127 331141 331147 331153 331159 331171 331183 331207 331213 331217 331231 331241 331249 331259 331277 331283 331301 331307 331319 331333 331337 331339 331349 331367 331369 331391 331399 331423 331447 331451 331489 331501 331511 331519 331523 331537 331543 331547 331549 331553 331577 331579 331589 331603 331609 331613 331651 331663 331691 331693 331697 331711 331739 331753 331769 331777 331781 331801 331819 331841 331843 331871 331883 331889 331897 331907 331909 331921 331937 331943 331957 331967 331973 331997 331999 332009 332011 332039 332053 332069 332081 332099 332113 332117 332147 332159 332161 332179 332183 332191 332201 332203 332207 332219 332221 332251 332263 332273 332287 332303 332309 332317 332393 332399 332411 332417 332441 332447 332461 332467 332471 332473 332477 332489 332509 332513 332561 332567 332569 332573 332611 332617 332623 332641 332687 332699 332711 332729 332743 332749 332767 332779 332791 332803 332837 332851 332873 332881 332887 332903 332921 332933 332947 332951 332987 332989 332993 333019 333023 333029 333031 333041 333049 333071 333097 333101 333103 333107 333131 333139 333161 333187 333197 333209 333227 333233 333253 333269 333271 333283 333287 333299 333323 333331 333337 333341 333349 333367 333383 333397 333419 333427 333433 333439 333449 333451 333457 333479 333491 333493 333497 333503 333517 333533 333539 333563 333581 333589 333623 333631 333647 333667 333673 333679 333691 333701 333713 333719 333721 333737 333757 333769 333779 333787 333791 333793 333803 333821 333857 333871 333911 333923 333929 333941 333959 333973 333989 333997 334021 334031 334043 334049 334057 334069 334093 334099 334127 334133 334157 334171 334177 334183 334189 334199 334231 334247 334261 334289 334297 334319 334331 334333 334349 334363 334379 334387 334393 334403 334421 334423 334427 334429 334447 334487 334493 334507 334511 334513 334541 334547 334549 334561 334603 334619 334637 334643 334651 334661 334667 334681 334693 334699 334717 334721 334727 334751 334753 334759 334771 334777 334783 334787 334793 334843 334861 334877 334889 334891 334897 334931 334963 334973 334987 334991 334993 335009 335021 335029 335033 335047 335051 335057 335077 335081 335089 335107 335113 335117 335123 335131 335149 335161 335171 335173 335207 335213 335221 335249 335261 335273 335281 335299 335323 335341 335347 335381 335383 335411 335417 335429 335449 335453 335459 335473 335477 335507 335519 335527 335539 335557 335567 335579 335591 335609 335633 335641 335653 335663 335669 335681 335689 335693 335719 335729 335743 335747 335771 335807 335809 335813 335821 335833 335843 335857 335879 335893 335897 335917 335941 335953 335957 335999 336029 336031 336041 336059 336079 336101 336103 336109 336113 336121 336143 336151 336157 336163 336181 336199 336211 336221 336223 336227 336239 336247 336251 336253 336263 336307 336317 336353 336361 336373 336397 336403 336419 336437 336463 336491 336499 336503 336521 336527 336529 336533 336551 336563 336571 336577 336587 336593 336599 336613 336631 336643 336649 336653 336667 336671 336683 336689 336703 336727 336757 336761 336767 336769 336773 336793 336799 336803 336823 336827 336829 336857 336863 336871 336887 336899 336901 336911 336929 336961 336977 336983 336989 336997 337013 337021 337031 337039 337049 337069 337081 337091 337097 337121 337153 337189 337201 337213 337217 337219 337223 337261 337277 337279 337283 337291 337301 337313 337327 337339 337343 337349 337361 337367 337369 337397 337411 337427 337453 337457 337487 337489 337511 337517 337529 337537 337541 337543 337583 337607 337609 337627 337633 337639 337651 337661 337669 337681 337691 337697 337721 337741 337751 337759 337781 337793 337817 337837 337853 337859 337861 337867 337871 337873 337891 337901 337903 337907 337919 337949 337957 337969 337973 337999 338017 338027 338033 338119 338137 338141 338153 338159 338161 338167 338171 338183 338197 338203 338207 338213 338231 338237 338251 338263 338267 338269 338279 338287 338293 338297 338309 338321 338323 338339 338341 338347 338369 338383 338389 338407 338411 338413 338423 338431 338449 338461 338473 338477 338497 338531 338543 338563 338567 338573 338579 338581 338609 338659 338669 338683 338687 338707 338717 338731 338747 338753 338761 338773 338777 338791 338803 338839 338851 338857 338867 338893 338909 338927 338959 338993 338999 339023 339049 339067 339071 339091 339103 339107 339121 339127 339137 339139 339151 339161 339173 339187 339211 339223 339239 339247 339257 339263 339289 339307 339323 339331 339341 339373 339389 339413 339433 339467 339491 339517 339527 339539 339557 339583 339589 339601 339613 339617 339631 339637 339649 339653 339659 339671 339673 339679 339707 339727 339749 339751 339761 339769 339799 339811 339817 339821 339827 339839 339841 339863 339887 339907 339943 339959 339991 340007 340027 340031 340037 340049 340057 340061 340063 340073 340079 340103 340111 340117 340121 340127 340129 340169 340183 340201 340211 340237 340261 340267 340283 340297 340321 340337 340339 340369 340381 340387 340393 340397 340409 340429 340447 340451 340453 340477 340481 340519 340541 340559 340573 340577 340579 340583 340591 340601 340619 340633 340643 340649 340657 340661 340687 340693 340709 340723 340757 340777 340787 340789 340793 340801 340811 340819 340849 340859 340877 340889 340897 340903 340909 340913 340919 340927 340931 340933 340937 340939 340957 340979 340999 341017 341027 341041 341057 341059 341063 341083 341087 341123 341141 341171 341179 341191 341203 341219 341227 341233 341269 341273 341281 341287 341293 341303 341311 341321 341323 341333 341339 341347 341357 341423 341443 341447 341459 341461 341477 341491 341501 341507 341521 341543 341557 341569 341587 341597 341603 341617 341623 341629 341641 341647 341659 341681 341687 341701 341729 341743 341749 341771 341773 341777 341813 341821 341827 341839 341851 341863 341879 341911 341927 341947 341951 341953 341959 341963 341983 341993 342037 342047 342049 342059 342061 342071 342073 342077 342101 342107 342131 342143 342179 342187 342191 342197 342203 342211 342233 342239 342241 342257 342281 342283 342299 342319 342337 342341 342343 342347 342359 342371 342373 342379 342389 342413 342421 342449 342451 342467 342469 342481 342497 342521 342527 342547 342553 342569 342593 342599 342607 342647 342653 342659 342673 342679 342691 342697 342733 342757 342761 342791 342799 342803 342821 342833 342841 342847 342863 342869 342871 342889 342899 342929 342949 342971 342989 343019 343037 343051 343061 343073 343081 343087 343127 343141 343153 343163 343169 343177 343193 343199 343219 343237 343243 343253 343261 343267 343289 343303 343307 343309 343313 343327 343333 343337 343373 343379 343381 343391 343393 343411 343423 343433 343481 343489 343517 343529 343531 343543 343547 343559 343561 343579 343583 343589 343591 343601 343627 343631 343639 343649 343661 343667 343687 343709 343727 343769 343771 343787 343799 343801 343813 343817 343823 343829 343831 343891 343897 343901 343913 343933 343939 343943 343951 343963 343997 344017 344021 344039 344053 344083 344111 344117 344153 344161 344167 344171 344173 344177 344189 344207 344209 344213 344221 344231 344237 344243 344249 344251 344257 344263 344269 344273 344291 344293 344321 344327 344347 344353 344363 344371 344417 344423 344429 344453 344479 344483 344497 344543 344567 344587 344599 344611 344621 344629 344639 344653 344671 344681 344683 344693 344719 344749 344753 344759 344791 344797 344801 344807 344819 344821 344843 344857 344863 344873 344887 344893 344909 344917 344921 344941 344957 344959 344963 344969 344987 345001 345011 345017 345019 345041 345047 345067 345089 345109 345133 345139 345143 345181 345193 345221 345227 345229 345259 345263 345271 345307 345311 345329 345379 345413 345431 345451 345461 345463 345473 345479 345487 345511 345517 345533 345547 345551 345571 345577 345581 345599 345601 345607 345637 345643 345647 345659 345673 345679 345689 345701 345707 345727 345731 345733 345739 345749 345757 345769 345773 345791 345803 345811 345817 345823 345853 345869 345881 345887 345889 345907 345923 345937 345953 345979 345997 346013 346039 346043 346051 346079 346091 346097 346111 346117 346133 346139 346141 346147 346169 346187 346201 346207 346217 346223 346259 346261 346277 346303 346309 346321 346331 346337 346349 346361 346369 346373 346391 346393 346397 346399 346417 346421 346429 346433 346439 346441 346447 346453 346469 346501 346529 346543 346547 346553 346559 346561 346589 346601 346607 346627 346639 346649 346651 346657 346667 346669 346699 346711 346721 346739 346751 346763 346793 346831 346849 346867 346873 346877 346891 346903 346933 346939 346943 346961 346963 347003 347033 347041 347051 347057 347059 347063 347069 347071 347099 347129 347131 347141 347143 347161 347167 347173 347177 347183 347197 347201 347209 347227 347233 347239 347251 347257 347287 347297 347299 347317 347329 347341 347359 347401 347411 347437 347443 347489 347509 347513 347519 347533 347539 347561 347563 347579 347587 347591 347609 347621 347629 347651 347671 347707 347717 347729 347731 347747 347759 347771 347773 347779 347801 347813 347821 347849 347873 347887 347891 347899 347929 347933 347951 347957 347959 347969 347981 347983 347987 347989 347993 348001 348011 348017 348031 348043 348053 348077 348083 348097 348149 348163 348181 348191 348209 348217 348221 348239 348241 348247 348253 348259 348269 348287 348307 348323 348353 348367 348389 348401 348407 348419 348421 348431 348433 348437 348443 348451 348457 348461 348463 348487 348527 348547 348553 348559 348563 348571 348583 348587 348617 348629 348637 348643 348661 348671 348709 348731 348739 348757 348763 348769 348779 348811 348827 348833 348839 348851 348883 348889 348911 348917 348919 348923 348937 348949 348989 348991 349007 349039 349043 349051 349079 349081 349093 349099 349109 349121 349133 349171 349177 349183 349187 349199 349207 349211 349241 349291 349303 349313 349331 349337 349343 349357 349369 349373 349379 349381 349387 349397 349399 349403 349409 349411 349423 349471 349477 349483 349493 349499 349507 349519 349529 349553 349567 349579 349589 349603 349637 349663 349667 349697 349709 349717 349729 349753 349759 349787 349793 349801 349813 349819 349829 349831 349837 349841 349849 349871 349903 349907 349913 349919 349927 349931 349933 349939 349949 349963 349967 349981 350003 350029 350033 350039 350087 350089 350093 350107 350111 350137 350159 350179 350191 350213 350219 350237 350249 350257 350281 350293 350347 350351 350377 350381 350411 350423 350429 350431 350437 350443 350447 350453 350459 350503 350521 350549 350561 350563 350587 350593 350617 350621 350629 350657 350663 350677 350699 350711 350719 350729 350731 350737 350741 350747 350767 350771 350783 350789 350803 350809 350843 350851 350869 350881 350887 350891 350899 350941 350947 350963 350971 350981 350983 350989 351011 351023 351031 351037 351041 351047 351053 351059 351061 351077 351079 351097 351121 351133 351151 351157 351179 351217 351223 351229 351257 351259 351269 351287 351289 351293 351301 351311 351341 351343 351347 351359 351361 351383 351391 351397 351401 351413 351427 351437 351457 351469 351479 351497 351503 351517 351529 351551 351563 351587 351599 351643 351653 351661 351667 351691 351707 351727 351731 351733 351749 351751 351763 351773 351779 351797 351803 351811 351829 351847 351851 351859 351863 351887 351913 351919 351929 351931 351959 351971 351991 352007 352021 352043 352049 352057 352069 352073 352081 352097 352109 352111 352123 352133 352181 352193 352201 352217 352229 352237 352249 352267 352271 352273 352301 352309 352327 352333 352349 352357 352361 352367 352369 352381 352399 352403 352409 352411 352421 352423 352441 352459 352463 352481 352483 352489 352493 352511 352523 352543 352549 352579 352589 352601 352607 352619 352633 352637 352661 352691 352711 352739 352741 352753 352757 352771 352813 352817 352819 352831 352837 352841 352853 352867 352883 352907 352909 352931 352939 352949 352951 352973 352991 353011 353021 353047 353053 353057 353069 353081 353099 353117 353123 353137 353147 353149 353161 353173 353179 353201 353203 353237 353263 353293 353317 353321 353329 353333 353341 353359 353389 353401 353411 353429 353443 353453 353459 353471 353473 353489 353501 353527 353531 353557 353567 353603 353611 353621 353627 353629 353641 353653 353657 353677 353681 353687 353699 353711 353737 353747 353767 353777 353783 353797 353807 353813 353819 353833 353867 353869 353879 353891 353897 353911 353917 353921 353929 353939 353963 354001 354007 354017 354023 354031 354037 354041 354043 354047 354073 354091 354097 354121 354139 354143 354149 354163 354169 354181 354209 354247 354251 354253 354257 354259 354271 354301 354307 354313 354317 354323 354329 354337 354353 354371 354373 354377 354383 354391 354401 354421 354439 354443 354451 354461 354463 354469 354479 354533 354539 354551 354553 354581 354587 354619 354643 354647 354661 354667 354677 354689 354701 354703 354727 354737 354743 354751 354763 354779 354791 354799 354829 354833 354839 354847 354869 354877 354881 354883 354911 354953 354961 354971 354973 354979 354983 354997 355007 355009 355027 355031 355037 355039 355049 355057 355063 355073 355087 355093 355099 355109 355111 355127 355139 355171 355193 355211 355261 355297 355307 355321 355331 355339 355343 355361 355363 355379 355417 355427 355441 355457 355463 355483 355499 355501 355507 355513 355517 355519 355529 355541 355549 355559 355571 355573 355591 355609 355633 355643 355651 355669 355679 355697 355717 355721 355723 355753 355763 355777 355783 355799 355811 355819 355841 355847 355853 355867 355891 355909 355913 355933 355937 355939 355951 355967 355969 356023 356039 356077 356093 356101 356113 356123 356129 356137 356141 356143 356171 356173 356197 356219 356243 356261 356263 356287 356299 356311 356327 356333 356351 356387 356399 356441 356443 356449 356453 356467 356479 356501 356509 356533 356549 356561 356563 356567 356579 356591 356621 356647 356663 356693 356701 356731 356737 356749 356761 356803 356819 356821 356831 356869 356887 356893 356927 356929 356933 356947 356959 356969 356977 356981 356989 356999 357031 357047 357073 357079 357083 357103 357107 357109 357131 357139 357169 357179 357197 357199 357211 357229 357239 357241 357263 357271 357281 357283 357293 357319 357347 357349 357353 357359 357377 357389 357421 357431 357437 357473 357503 357509 357517 357551 357559 357563 357569 357571 357583 357587 357593 357611 357613 357619 357649 357653 357659 357661 357667 357671 357677 357683 357689 357703 357727 357733 357737 357739 357767 357779 357781 357787 357793 357809 357817 357823 357829 357839 357859 357883 357913 357967 357977 357983 357989 357997 358031 358051 358069 358073 358079 358103 358109 358153 358157 358159 358181 358201 358213 358219 358223 358229 358243 358273 358277 358279 358289 358291 358297 358301 358313 358327 358331 358349 358373 358417 358427 358429 358441 358447 358459 358471 358483 358487 358499 358531 358541 358571 358573 358591 358597 358601 358607 358613 358637 358667 358669 358681 358691 358697 358703 358711 358723 358727 358733 358747 358753 358769 358783 358793 358811 358829 358847 358859 358861 358867 358877 358879 358901 358903 358907 358909 358931 358951 358973 358979 358987 358993 358999 359003 359017 359027 359041 359063 359069 359101 359111 359129 359137 359143 359147 359153 359167 359171 359207 359209 359231 359243 359263 359267 359279 359291 359297 359299 359311 359323 359327 359353 359357 359377 359389 359407 359417 359419 359441 359449 359477 359479 359483 359501 359509 359539 359549 359561 359563 359581 359587 359599 359621 359633 359641 359657 359663 359701 359713 359719 359731 359747 359753 359761 359767 359783 359837 359851 359869 359897 359911 359929 359981 359987 360007 360023 360037 360049 360053 360071 360089 360091 360163 360167 360169 360181 360187 360193 360197 360223 360229 360233 360257 360271 360277 360287 360289 360293 360307 360317 360323 360337 360391 360407 360421 360439 360457 360461 360497 360509 360511 360541 360551 360589 360593 360611 360637 360649 360653 360749 360769 360779 360781 360803 360817 360821 360823 360827 360851 360853 360863 360869 360901 360907 360947 360949 360953 360959 360973 360977 360979 360989 361001 361003 361013 361033 361069 361091 361093 361111 361159 361183 361211 361213 361217 361219 361223 361237 361241 361271 361279 361313 361321 361327 361337 361349 361351 361357 361363 361373 361409 361411 361421 361433 361441 361447 361451 361463 361469 361481 361499 361507 361511 361523 361531 361541 361549 361561 361577 361637 361643 361649 361651 361663 361679 361687 361723 361727 361747 361763 361769 361787 361789 361793 361799 361807 361843 361871 361873 361877 361901 361903 361909 361919 361927 361943 361961 361967 361973 361979 361993 362003 362027 362051 362053 362059 362069 362081 362093 362099 362107 362137 362143 362147 362161 362177 362191 362203 362213 362221 362233 362237 362281 362291 362293 362303 362309 362333 362339 362347 362353 362357 362363 362371 362377 362381 362393 362407 362419 362429 362431 362443 362449 362459 362473 362521 362561 362569 362581 362599 362629 362633 362657 362693 362707 362717 362723 362741 362743 362749 362753 362759 362801 362851 362863 362867 362897 362903 362911 362927 362941 362951 362953 362969 362977 362983 362987 363017 363019 363037 363043 363047 363059 363061 363067 363119 363149 363151 363157 363161 363173 363179 363199 363211 363217 363257 363269 363271 363277 363313 363317 363329 363343 363359 363361 363367 363371 363373 363379 363397 363401 363403 363431 363437 363439 363463 363481 363491 363497 363523 363529 363533 363541 363551 363557 363563 363569 363577 363581 363589 363611 363619 363659 363677 363683 363691 363719 363731 363751 363757 363761 363767 363773 363799 363809 363829 363833 363841 363871 363887 363889 363901 363911 363917 363941 363947 363949 363959 363967 363977 363989 364027 364031 364069 364073 364079 364103 364127 364129 364141 364171 364183 364187 364193 364213 364223 364241 364267 364271 364289 364291 364303 364313 364321 364333 364337 364349 364373 364379 364393 364411 364417 364423 364433 364447 364451 364459 364471 364499 364513 364523 364537 364541 364543 364571 364583 364601 364607 364621 364627 364643 364657 364669 364687 364691 364699 364717 364739 364747 364751 364753 364759 364801 364829 364853 364873 364879 364883 364891 364909 364919 364921 364937 364943 364961 364979 364993 364997 365003 365017 365021 365039 365063 365069 365089 365107 365119 365129 365137 365147 365159 365173 365179 365201 365213 365231 365249 365251 365257 365291 365293 365297 365303 365327 365333 365357 365369 365377 365411 365413 365419 365423 365441 365461 365467 365471 365473 365479 365489 365507 365509 365513 365527 365531 365537 365557 365567 365569 365587 365591 365611 365627 365639 365641 365669 365683 365689 365699 365747 365749 365759 365773 365779 365791 365797 365809 365837 365839 365851 365903 365929 365933 365941 365969 365983 366001 366013 366019 366029 366031 366053 366077 366097 366103 366127 366133 366139 366161 366167 366169 366173 366181 366193 366199 366211 366217 366221 366227 366239 366259 366269 366277 366287 366293 366307 366313 366329 366341 366343 366347 366383 366397 366409 366419 366433 366437 366439 366461 366463 366467 366479 366497 366511 366517 366521 366547 366593 366599 366607 366631 366677 366683 366697 366701 366703 366713 366721 366727 366733 366787 366791 366811 366829 366841 366851 366853 366859 366869 366881 366889 366901 366907 366917 366923 366941 366953 366967 366973 366983 366997 367001 367007 367019 367021 367027 367033 367049 367069 367097 367121 367123 367127 367139 367163 367181 367189 367201 367207 367219 367229 367231 367243 367259 367261 367273 367277 367307 367309 367313 367321 367357 367369 367391 367397 367427 367453 367457 367469 367501 367519 367531 367541 367547 367559 367561 367573 367597 367603 367613 367621 367637 367649 367651 367663 367673 367687 367699 367711 367721 367733 367739 367751 367771 367777 367781 367789 367819 367823 367831 367841 367849 367853 367867 367879 367883 367889 367909 367949 367957 368021 368029 368047 368059 368077 368083 368089 368099 368107 368111 368117 368129 368141 368149 368153 368171 368189 368197 368227 368231 368233 368243 368273 368279 368287 368293 368323 368327 368359 368363 368369 368399 368411 368443 368447 368453 368471 368491 368507 368513 368521 368531 368539 368551 368579 368593 368597 368609 368633 368647 368651 368653 368689 368717 368729 368737 368743 368773 368783 368789 368791 368801 368803 368833 368857 368873 368881 368899 368911 368939 368947 368957 369007 369013 369023 369029 369067 369071 369077 369079 369097 369119 369133 369137 369143 369169 369181 369191 369197 369211 369247 369253 369263 369269 369283 369293 369301 369319 369331 369353 369361 369407 369409 369419 369469 369487 369491 369539 369553 369557 369581 369637 369647 369659 369661 369673 369703 369709 369731 369739 369751 369791 369793 369821 369827 369829 369833 369841 369851 369877 369893 369913 369917 369947 369959 369961 369979 369983 369991 369997 370003 370009 370021 370033 370057 370061 370067 370081 370091 370103 370121 370133 370147 370159 370169 370193 370199 370207 370213 370217 370241 370247 370261 370373 370387 370399 370411 370421 370423 370427 370439 370441 370451 370463 370471 370477 370483 370493 370511 370529 370537 370547 370561 370571 370597 370603 370609 370613 370619 370631 370661 370663 370673 370679 370687 370693 370723 370759 370793 370801 370813 370837 370871 370873 370879 370883 370891 370897 370919 370949 371027 371029 371057 371069 371071 371083 371087 371099 371131 371141 371143 371153 371177 371179 371191 371213 371227 371233 371237 371249 371251 371257 371281 371291 371299 371303 371311 371321 371333 371339 371341 371353 371359 371383 371387 371389 371417 371447 371453 371471 371479 371491 371509 371513 371549 371561 371573 371587 371617 371627 371633 371639 371663 371669 371699 371719 371737 371779 371797 371831 371837 371843 371851 371857 371869 371873 371897 371927 371929 371939 371941 371951 371957 371971 371981 371999 372013 372023 372037 372049 372059 372061 372067 372107 372121 372131 372137 372149 372167 372173 372179 372223 372241 372263 372269 372271 372277 372289 372293 372299 372311 372313 372353 372367 372371 372377 372397 372401 372409 372413 372443 372451 372461 372473 372481 372497 372511 372523 372539 372607 372611 372613 372629 372637 372653 372661 372667 372677 372689 372707 372709 372719 372733 372739 372751 372763 372769 372773 372797 372803 372809 372817 372829 372833 372839 372847 372859 372871 372877 372881 372901 372917 372941 372943 372971 372973 372979 373003 373007 373019 373049 373063 373073 373091 373127 373151 373157 373171 373181 373183 373187 373193 373199 373207 373211 373213 373229 373231 373273 373291 373297 373301 373327 373339 373343 373349 373357 373361 373363 373379 373393 373447 373453 373459 373463 373487 373489 373501 373517 373553 373561 373567 373613 373621 373631 373649 373657 373661 373669 373693 373717 373721 373753 373757 373777 373783 373823 373837 373859 373861 373903 373909 373937 373943 373951 373963 373969 373981 373987 373999 374009 374029 374039 374041 374047 374063 374069 374083 374089 374093 374111 374117 374123 374137 374149 374159 374173 374177 374189 374203 374219 374239 374287 374291 374293 374299 374317 374321 374333 374347 374351 374359 374389 374399 374441 374443 374447 374461 374483 374501 374531 374537 374557 374587 374603 374639 374641 374653 374669 374677 374681 374683 374687 374701 374713 374719 374729 374741 374753 374761 374771 374783 374789 374797 374807 374819 374837 374839 374849 374879 374887 374893 374903 374909 374929 374939 374953 374977 374981 374987 374989 374993 375017 375019 375029 375043 375049 375059 375083 375091 375097 375101 375103 375113 375119 375121 375127 375149 375157 375163 375169 375203 375209 375223 375227 375233 375247 375251 375253 375257 375259 375281 375283 375311 375341 375359 375367 375371 375373 375391 375407 375413 375443 375449 375451 375457 375467 375481 375509 375511 375523 375527 375533 375553 375559 375563 375569 375593 375607 375623 375631 375643 375647 375667 375673 375703 375707 375709 375743 375757 375761 375773 375779 375787 375799 375833 375841 375857 375899 375901 375923 375931 375967 375971 375979 375983 375997 376001 376003 376009 376021 376039 376049 376063 376081 376097 376099 376127 376133 376147 376153 376171 376183 376199 376231 376237 376241 376283 376291 376297 376307 376351 376373 376393 376399 376417 376463 376469 376471 376477 376483 376501 376511 376529 376531 376547 376573 376577 376583 376589 376603 376609 376627 376631 376633 376639 376657 376679 376687 376699 376709 376721 376729 376757 376759 376769 376787 376793 376801 376807 376811 376819 376823 376837 376841 376847 376853 376889 376891 376897 376921 376927 376931 376933 376949 376963 376969 377011 377021 377051 377059 377071 377099 377123 377129 377137 377147 377171 377173 377183 377197 377219 377231 377257 377263 377287 377291 377297 377327 377329 377339 377347 377353 377369 377371 377387 377393 377459 377471 377477 377491 377513 377521 377527 377537 377543 377557 377561 377563 377581 377593 377599 377617 377623 377633 377653 377681 377687 377711 377717 377737 377749 377761 377771 377779 377789 377801 377809 377827 377831 377843 377851 377873 377887 377911 377963 377981 377999 378011 378019 378023 378041 378071 378083 378089 378101 378127 378137 378149 378151 378163 378167 378179 378193 378223 378229 378239 378241 378253 378269 378277 378283 378289 378317 378353 378361 378379 378401 378407 378439 378449 378463 378467 378493 378503 378509 378523 378533 378551 378559 378569 378571 378583 378593 378601 378619 378629 378661 378667 378671 378683 378691 378713 378733 378739 378757 378761 378779 378793 378809 378817 378821 378823 378869 378883 378893 378901 378919 378929 378941 378949 378953 378967 378977 378997 379007 379009 379013 379033 379039 379073 379081 379087 379097 379103 379123 379133 379147 379157 379163 379177 379187 379189 379199 379207 379273 379277 379283 379289 379307 379319 379333 379343 379369 379387 379391 379397 379399 379417 379433 379439 379441 379451 379459 379499 379501 379513 379531 379541 379549 379571 379573 379579 379597 379607 379633 379649 379663 379667 379679 379681 379693 379699 379703 379721 379723 379727 379751 379777 379787 379811 379817 379837 379849 379853 379859 379877 379889 379903 379909 379913 379927 379931 379963 379979 379993 379997 379999 380041 380047 380059 380071 380117 380129 380131 380141 380147 380179 380189 380197 380201 380203 380207 380231 380251 380267 380269 380287 380291 380299 380309 380311 380327 380329 380333 380363 380377 380383 380417 380423 380441 380447 380453 380459 380461 380483 380503 380533 380557 380563 380591 380621 380623 380629 380641 380651 380657 380707 380713 380729 380753 380777 380797 380803 380819 380837 380839 380843 380867 380869 380879 380881 380909 380917 380929 380951 380957 380971 380977 380983 381001 381011 381019 381037 381047 381061 381071 381077 381097 381103 381167 381169 381181 381209 381221 381223 381233 381239 381253 381287 381289 381301 381319 381323 381343 381347 381371 381373 381377 381383 381389 381401 381413 381419 381439 381443 381461 381467 381481 381487 381509 381523 381527 381529 381533 381541 381559 381569 381607 381629 381631 381637 381659 381673 381697 381707 381713 381737 381739 381749 381757 381761 381791 381793 381817 381841 381853 381859 381911 381917 381937 381943 381949 381977 381989 381991 382001 382003 382021 382037 382061 382069 382073 382087 382103 382117 382163 382171 382189 382229 382231 382241 382253 382267 382271 382303 382331 382351 382357 382363 382373 382391 382427 382429 382457 382463 382493 382507 382511 382519 382541 382549 382553 382567 382579 382583 382589 382601 382621 382631 382643 382649 382661 382663 382693 382703 382709 382727 382729 382747 382751 382763 382769 382777 382801 382807 382813 382843 382847 382861 382867 382871 382873 382883 382919 382933 382939 382961 382979 382999 383011 383023 383029 383041 383051 383069 383077 383081 383083 383099 383101 383107 383113 383143 383147 383153 383171 383179 383219 383221 383261 383267 383281 383291 383297 383303 383321 383347 383371 383393 383399 383417 383419 383429 383459 383483 383489 383519 383521 383527 383533 383549 383557 383573 383587 383609 383611 383623 383627 383633 383651 383657 383659 383681 383683 383693 383723 383729 383753 383759 383767 383777 383791 383797 383807 383813 383821 383833 383837 383839 383869 383891 383909 383917 383923 383941 383951 383963 383969 383983 383987 384001 384017 384029 384049 384061 384067 384079 384089 384107 384113 384133 384143 384151 384157 384173 384187 384193 384203 384227 384247 384253 384257 384259 384277 384287 384289 384299 384301 384317 384331 384343 384359 384367 384383 384403 384407 384437 384469 384473 384479 384481 384487 384497 384509 384533 384547 384577 384581 384589 384599 384611 384619 384623 384641 384673 384691 384697 384701 384719 384733 384737 384751 384757 384773 384779 384817 384821 384827 384841 384847 384851 384889 384907 384913 384919 384941 384961 384973 385001 385013 385027 385039 385057 385069 385079 385081 385087 385109 385127 385129 385139 385141 385153 385159 385171 385193 385199 385223 385249 385261 385267 385279 385289 385291 385321 385327 385331 385351 385379 385391 385393 385397 385403 385417 385433 385471 385481 385493 385501 385519 385531 385537 385559 385571 385573 385579 385589 385591 385597 385607 385621 385631 385639 385657 385661 385663 385709 385739 385741 385771 385783 385793 385811 385817 385831 385837 385843 385859 385877 385897 385901 385907 385927 385939 385943 385967 385991 385997 386017 386039 386041 386047 386051 386083 386093 386117 386119 386129 386131 386143 386149 386153 386159 386161 386173 386219 386227 386233 386237 386249 386263 386279 386297 386299 386303 386329 386333 386339 386363 386369 386371 386381 386383 386401 386411 386413 386429 386431 386437 386471 386489 386501 386521 386537 386543 386549 386569 386587 386609 386611 386621 386629 386641 386647 386651 386677 386689 386693 386713 386719 386723 386731 386747 386777 386809 386839 386851 386887 386891 386921 386927 386963 386977 386987 386989 386993 387007 387017 387031 387047 387071 387077 387083 387089 387109 387137 387151 387161 387169 387173 387187 387197 387199 387203 387227 387253 387263 387269 387281 387307 387313 387329 387341 387371 387397 387403 387433 387437 387449 387463 387493 387503 387509 387529 387551 387577 387587 387613 387623 387631 387641 387659 387677 387679 387683 387707 387721 387727 387743 387749 387763 387781 387791 387799 387839 387853 387857 387911 387913 387917 387953 387967 387971 387973 387977 388009 388051 388057 388067 388081 388099 388109 388111 388117 388133 388159 388163 388169 388177 388181 388183 388187 388211 388231 388237 388253 388259 388273 388277 388301 388313 388319 388351 388363 388369 388373 388391 388403 388459 388471 388477 388481 388483 388489 388499 388519 388529 388541 388567 388573 388621 388651 388657 388673 388691 388693 388697 388699 388711 388727 388757 388777 388781 388789 388793 388813 388823 388837 388859 388879 388891 388897 388901 388903 388931 388933 388937 388961 388963 388991 389003 389023 389027 389029 389041 389047 389057 389083 389089 389099 389111 389117 389141 389149 389161 389167 389171 389173 389189 389219 389227 389231 389269 389273 389287 389297 389299 389303 389357 389369 389381 389399 389401 389437 389447 389461 389479 389483 389507 389513 389527 389531 389533 389539 389561 389563 389567 389569 389579 389591 389621 389629 389651 389659 389663 389687 389699 389713 389723 389743 389749 389761 389773 389783 389791 389797 389819 389839 389849 389867 389891 389897 389903 389911 389923 389927 389941 389947 389953 389957 389971 389981 389989 389999 390001 390043 390067 390077 390083 390097 390101 390107 390109 390113 390119 390151 390157 390161 390191 390193 390199 390209 390211 390223 390263 390281 390289 390307 390323 390343 390347 390353 390359 390367 390373 390389 390391 390407 390413 390419 390421 390433 390437 390449 390463 390479 390487 390491 390493 390499 390503 390527 390539 390553 390581 390647 390653 390671 390673 390703 390707 390721 390727 390737 390739 390743 390751 390763 390781 390791 390809 390821 390829 390851 390869 390877 390883 390889 390893 390953 390959 390961 390967 390989 390991 391009 391019 391021 391031 391049 391057 391063 391067 391073 391103 391117 391133 391151 391159 391163 391177 391199 391217 391219 391231 391247 391249 391273 391283 391291 391301 391331 391337 391351 391367 391373 391379 391387 391393 391397 391399 391403 391441 391451 391453 391487 391519 391537 391553 391579 391613 391619 391627 391631 391639 391661 391679 391691 391693 391711 391717 391733 391739 391751 391753 391757 391789 391801 391817 391823 391847 391861 391873 391879 391889 391891 391903 391907 391921 391939 391961 391967 391987 391999 392011 392033 392053 392059 392069 392087 392099 392101 392111 392113 392131 392143 392149 392153 392159 392177 392201 392209 392213 392221 392233 392239 392251 392261 392263 392267 392269 392279 392281 392297 392299 392321 392333 392339 392347 392351 392363 392383 392389 392423 392437 392443 392467 392473 392477 392489 392503 392519 392531 392543 392549 392569 392593 392599 392611 392629 392647 392663 392669 392699 392723 392737 392741 392759 392761 392767 392803 392807 392809 392827 392831 392837 392849 392851 392857 392879 392893 392911 392923 392927 392929 392957 392963 392969 392981 392983 393007 393013 393017 393031 393059 393073 393077 393079 393083 393097 393103 393109 393121 393137 393143 393157 393161 393181 393187 393191 393203 393209 393241 393247 393257 393271 393287 393299 393301 393311 393331 393361 393373 393377 393383 393401 393403 393413 393451 393473 393479 393487 393517 393521 393539 393541 393551 393557 393571 393577 393581 393583 393587 393593 393611 393629 393637 393649 393667 393671 393677 393683 393697 393709 393713 393721 393727 393739 393749 393761 393779 393797 393847 393853 393857 393859 393863 393871 393901 393919 393929 393931 393947 393961 393977 393989 393997 394007 394019 394039 394049 394063 394073 394099 394123 394129 394153 394157 394169 394187 394201 394211 394223 394241 394249 394259 394271 394291 394319 394327 394357 394363 394367 394369 394393 394409 394411 394453 394481 394489 394501 394507 394523 394529 394549 394571 394577 394579 394601 394619 394631 394633 394637 394643 394673 394699 394717 394721 394727 394729 394733 394739 394747 394759 394787 394811 394813 394817 394819 394829 394837 394861 394879 394897 394931 394943 394963 394967 394969 394981 394987 394993 395023 395027 395039 395047 395069 395089 395093 395107 395111 395113 395119 395137 395141 395147 395159 395173 395189 395191 395201 395231 395243 395251 395261 395273 395287 395293 395303 395309 395321 395323 395377 395383 395407 395429 395431 395443 395449 395453 395459 395491 395509 395513 395533 395537 395543 395581 395597 395611 395621 395627 395657 395671 395677 395687 395701 395719 395737 395741 395749 395767 395803 395849 395851 395873 395887 395891 395897 395909 395921 395953 395959 395971 396001 396029 396031 396041 396043 396061 396079 396091 396103 396107 396119 396157 396173 396181 396197 396199 396203 396217 396239 396247 396259 396269 396293 396299 396301 396311 396323 396349 396353 396373 396377 396379 396413 396427 396437 396443 396449 396479 396509 396523 396527 396533 396541 396547 396563 396577 396581 396601 396619 396623 396629 396631 396637 396647 396667 396679 396703 396709 396713 396719 396733 396833 396871 396881 396883 396887 396919 396931 396937 396943 396947 396953 396971 396983 396997 397013 397027 397037 397051 397057 397063 397073 397093 397099 397127 397151 397153 397181 397183 397211 397217 397223 397237 397253 397259 397283 397289 397297 397301 397303 397337 397351 397357 397361 397373 397379 397427 397429 397433 397459 397469 397489 397493 397517 397519 397541 397543 397547 397549 397567 397589 397591 397597 397633 397643 397673 397687 397697 397721 397723 397729 397751 397753 397757 397759 397763 397799 397807 397811 397829 397849 397867 397897 397907 397921 397939 397951 397963 397973 397981 398011 398023 398029 398033 398039 398053 398059 398063 398077 398087 398113 398117 398119 398129 398143 398149 398171 398207 398213 398219 398227 398249 398261 398267 398273 398287 398303 398311 398323 398339 398341 398347 398353 398357 398369 398393 398407 398417 398423 398441 398459 398467 398471 398473 398477 398491 398509 398539 398543 398549 398557 398569 398581 398591 398609 398611 398621 398627 398669 398681 398683 398693 398711 398729 398731 398759 398771 398813 398819 398821 398833 398857 398863 398887 398903 398917 398921 398933 398941 398969 398977 398989 399023 399031 399043 399059 399067 399071 399079 399097 399101 399107 399131 399137 399149 399151 399163 399173 399181 399197 399221 399227 399239 399241 399263 399271 399277 399281 399283 399353 399379 399389 399391 399401 399403 399409 399433 399439 399473 399481 399491 399493 399499 399523 399527 399541 399557 399571 399577 399583 399587 399601 399613 399617 399643 399647 399667 399677 399689 399691 399719 399727 399731 399739 399757 399761 399769 399781 399787 399793 399851 399853 399871 399887 399899 399911 399913 399937 399941 399953 399979 399983 399989 400009 400031 400033 400051 400067 400069 400087 400093 400109 400123 400151 400157 400187 400199 400207 400217 400237 400243 400247 400249 400261 400277 400291 400297 400307 400313 400321 400331 400339 400381 400391 400409 400417 400429 400441 400457 400471 400481 400523 400559 400579 400597 400601 400607 400619 400643 400651 400657 400679 400681 400703 400711 400721 400723 400739 400753 400759 400823 400837 400849 400853 400859 400871 400903 400927 400931 400943 400949 400963 400997 401017 401029 401039 401053 401057 401069 401077 401087 401101 401113 401119 401161 401173 401179 401201 401209 401231 401237 401243 401279 401287 401309 401311 401321 401329 401341 401347 401371 401381 401393 401407 401411 401417 401473 401477 401507 401519 401537 401539 401551 401567 401587 401593 401627 401629 401651 401669 401671 401689 401707 401711 401743 401771 401773 401809 401813 401827 401839 401861 401867 401887 401903 401909 401917 401939 401953 401957 401959 401981 401987 401993 402023 402029 402037 402043 402049 402053 402071 402089 402091 402107 402131 402133 402137 402139 402197 402221 402223 402239 402253 402263 402277 402299 402307 402313 402329 402331 402341 402343 402359 402361 402371 402379 402383 402403 402419 402443 402487 402503 402511 402517 402527 402529 402541 402551 402559 402581 402583 402587 402593 402601 402613 402631 402691 402697 402739 402751 402757 402761 402763 402767 402769 402797 402803 402817 402823 402847 402851 402859 402863 402869 402881 402923 402943 402947 402949 402991 403001 403003 403037 403043 403049 403057 403061 403063 403079 403097 403103 403133 403141 403159 403163 403181 403219 403241 403243 403253 403261 403267 403289 403301 403309 403327 403331 403339 403363 403369 403387 403391 403433 403439 403483 403499 403511 403537 403547 403549 403553 403567 403577 403591 403603 403607 403621 403649 403661 403679 403681 403687 403703 403717 403721 403729 403757 403783 403787 403817 403829 403831 403849 403861 403867 403877 403889 403901 403933 403951 403957 403969 403979 403981 403993 404009 404011 404017 404021 404029 404051 404081 404099 404113 404119 404123 404161 404167 404177 404189 404191 404197 404213 404221 404249 404251 404267 404269 404273 404291 404309 404321 404323 404357 404381 404387 404389 404399 404419 404423 404429 404431 404449 404461 404483 404489 404497 404507 404513 404527 404531 404533 404539 404557 404597 404671 404693 404699 404713 404773 404779 404783 404819 404827 404837 404843 404849 404851 404941 404951 404959 404969 404977 404981 404983 405001 405011 405029 405037 405047 405049 405071 405073 405089 405091 405143 405157 405179 405199 405211 405221 405227 405239 405241 405247 405253 405269 405277 405287 405299 405323 405341 405343 405347 405373 405401 405407 405413 405437 405439 405473 405487 405491 405497 405499 405521 405527 405529 405541 405553 405577 405599 405607 405611 405641 405659 405667 405677 405679 405683 405689 405701 405703 405709 405719 405731 405749 405763 405767 405781 405799 405817 405827 405829 405857 405863 405869 405871 405893 405901 405917 405947 405949 405959 405967 405989 405991 405997 406013 406027 406037 406067 406073 406093 406117 406123 406169 406171 406177 406183 406207 406247 406253 406267 406271 406309 406313 406327 406331 406339 406349 406361 406381 406397 406403 406423 406447 406481 406499 406501 406507 406513 406517 406531 406547 406559 406561 406573 406577 406579 406583 406591 406631 406633 406649 406661 406673 406697 406699 406717 406729 406739 406789 406807 406811 406817 406837 406859 406873 406883 406907 406951 406969 406981 406993 407023 407047 407059 407083 407119 407137 407149 407153 407177 407179 407191 407203 407207 407219 407221 407233 407249 407257 407263 407273 407287 407291 407299 407311 407317 407321 407347 407357 407359 407369 407377 407383 407401 407437 407471 407483 407489 407501 407503 407509 407521 407527 407567 407573 407579 407587 407599 407621 407633 407639 407651 407657 407669 407699 407707 407713 407717 407723 407741 407747 407783 407789 407791 407801 407807 407821 407833 407843 407857 407861 407879 407893 407899 407917 407923 407947 407959 407969 407971 407977 407993 408011 408019 408041 408049 408071 408077 408091 408127 408131 408137 408169 408173 408197 408203 408209 408211 408217 408223 408229 408241 408251 408263 408271 408283 408311 408337 408341 408347 408361 408379 408389 408403 408413 408427 408431 408433 408437 408461 408469 408479 408491 408497 408533 408539 408553 408563 408607 408623 408631 408637 408643 408659 408677 408689 408691 408701 408703 408713 408719 408743 408763 408769 408773 408787 408803 408809 408817 408841 408857 408869 408911 408913 408923 408943 408953 408959 408971 408979 408997 409007 409021 409027 409033 409043 409063 409069 409081 409099 409121 409153 409163 409177 409187 409217 409237 409259 409261 409267 409271 409289 409291 409327 409333 409337 409349 409351 409369 409379 409391 409397 409429 409433 409441 409463 409471 409477 409483 409499 409517 409523 409529 409543 409573 409579 409589 409597 409609 409639 409657 409691 409693 409709 409711 409723 409729 409733 409753 409769 409777 409781 409813 409817 409823 409831 409841 409861 409867 409879 409889 409891 409897 409901 409909 409933 409943 409951 409961 409967 409987 409993 409999 410009 410029 410063 410087 410093 410117 410119 410141 410143 410149 410171 410173 410203 410231 410233 410239 410243 410257 410279 410281 410299 410317 410323 410339 410341 410353 410359 410383 410387 410393 410401 410411 410413 410453 410461 410477 410489 410491 410497 410507 410513 410519 410551 410561 410587 410617 410621 410623 410629 410651 410659 410671 410687 410701 410717 410731 410741 410747 410749 410759 410783 410789 410801 410807 410819 410833 410857 410899 410903 410929 410953 410983 410999 411001 411007 411011 411013 411031 411041 411049 411067 411071 411083 411101 411113 411119 411127 411143 411157 411167 411193 411197 411211 411233 411241 411251 411253 411259 411287 411311 411337 411347 411361 411371 411379 411409 411421 411443 411449 411469 411473 411479 411491 411503 411527 411529 411557 411563 411569 411577 411583 411589 411611 411613 411617 411637 411641 411667 411679 411683 411703 411707 411709 411721 411727 411737 411739 411743 411751 411779 411799 411809 411821 411823 411833 411841 411883 411919 411923 411937 411941 411947 411967 411991 412001 412007 412019 412031 412033 412037 412039 412051 412067 412073 412081 412099 412109 412123 412127 412133 412147 412157 412171 412187 412189 412193 412201 412211 412213 412219 412249 412253 412273 412277 412289 412303 412333 412339 412343 412387 412397 412411 412457 412463 412481 412487 412493 412537 412561 412567 412571 412589 412591 412603 412609 412619 412627 412637 412639 412651 412663 412667 412717 412739 412771 412793 412807 412831 412849 412859 412891 412901 412903 412939 412943 412949 412967 412987 413009 413027 413033 413053 413069 413071 413081 413087 413089 413093 413111 413113 413129 413141 413143 413159 413167 413183 413197 413201 413207 413233 413243 413251 413263 413267 413293 413299 413353 413411 413417 413429 413443 413461 413477 413521 413527 413533 413537 413551 413557 413579 413587 413597 413629 413653 413681 413683 413689 413711 413713 413719 413737 413753 413759 413779 413783 413807 413827 413849 413863 413867 413869 413879 413887 413911 413923 413951 413981 414013 414017 414019 414031 414049 414053 414061 414077 414083 414097 414101 414107 414109 414131 414157 414179 414199 414203 414209 414217 414221 414241 414259 414269 414277 414283 414311 414313 414329 414331 414347 414361 414367 414383 414389 414397 414413 414431 414433 414451 414457 414461 414467 414487 414503 414521 414539 414553 414559 414571 414577 414607 414611 414629 414641 414643 414653 414677 414679 414683 414691 414697 414703 414707 414709 414721 414731 414737 414763 414767 414769 414773 414779 414793 414803 414809 414833 414857 414871 414889 414893 414899 414913 414923 414929 414949 414959 414971 414977 414991 415013 415031 415039 415061 415069 415073 415087 415097 415109 415111 415133 415141 415147 415153 415159 415171 415187 415189 415201 415213 415231 415253 415271 415273 415319 415343 415379 415381 415391 415409 415427 415447 415469 415477 415489 415507 415517 415523 415543 415553 415559 415567 415577 415603 415607 415609 415627 415631 415643 415651 415661 415669 415673 415687 415691 415697 415717 415721 415729 415759 415783 415787 415799 415801 415819 415823 415861 415873 415879 415901 415931 415937 415949 415951 415957 415963 415969 415979 415993 415999 416011 416023 416071 416077 416089 416107 416147 416149 416153 416159 416167 416201 416219 416239 416243 416249 416257 416263 416281 416291 416333 416359 416387 416389 416393 416399 416401 416407 416413 416417 416419 416441 416443 416459 416473 416477 416491 416497 416501 416503 416513 416531 416543 416573 416579 416593 416621 416623 416629 416659 416677 416693 416719 416761 416797 416821 416833 416839 416849 416851 416873 416881 416887 416947 416957 416963 416989 417007 417017 417019 417023 417037 417089 417097 417113 417119 417127 417133 417161 417169 417173 417181 417187 417191 417203 417217 417227 417239 417251 417271 417283 417293 417311 417317 417331 417337 417371 417377 417379 417383 417419 417437 417451 417457 417479 417491 417493 417509 417511 417523 417541 417553 417559 417577 417581 417583 417617 417623 417631 417643 417649 417671 417691 417719 417721 417727 417731 417733 417737 417751 417763 417773 417793 417811 417821 417839 417863 417869 417881 417883 417899 417931 417941 417947 417953 417959 417961 417983 417997 418007 418009 418027 418031 418043 418051 418069 418073 418079 418087 418109 418129 418157 418169 418177 418181 418189 418199 418207 418219 418259 418273 418279 418289 418303 418321 418331 418337 418339 418343 418349 418351 418357 418373 418381 418391 418423 418427 418447 418459 418471 418493 418511 418553 418559 418597 418601 418603 418631 418633 418637 418657 418667 418699 418709 418721 418739 418751 418763 418771 418783 418787 418793 418799 418811 418813 418819 418837 418843 418849 418861 418867 418871 418883 418889 418909 418921 418927 418933 418939 418961 418981 418987 418993 418997 419047 419051 419053 419057 419059 419087 419141 419147 419161 419171 419183 419189 419191 419201 419231 419249 419261 419281 419291 419297 419303 419317 419329 419351 419383 419401 419417 419423 419429 419443 419449 419459 419467 419473 419477 419483 419491 419513 419527 419537 419557 419561 419563 419567 419579 419591 419597 419599 419603 419609 419623 419651 419687 419693 419701 419711 419743 419753 419777 419789 419791 419801 419803 419821 419827 419831 419873 419893 419921 419927 419929 419933 419953 419959 419999 420001 420029 420037 420041 420047 420073 420097 420103 420149 420163 420191 420193 420221 420241 420253 420263 420269 420271 420293 420307 420313 420317 420319 420323 420331 420341 420349 420353 420361 420367 420383 420397 420419 420421 420439 420457 420467 420479 420481 420499 420503 420521 420551 420557 420569 420571 420593 420599 420613 420671 420677 420683 420691 420731 420737 420743 420757 420769 420779 420781 420799 420803 420809 420811 420851 420853 420857 420859 420899 420919 420929 420941 420967 420977 420997 421009 421019 421033 421037 421049 421079 421081 421093 421103 421121 421123 421133 421147 421159 421163 421177 421181 421189 421207 421241 421273 421279 421303 421313 421331 421339 421349 421361 421381 421397 421409 421417 421423 421433 421453 421459 421469 421471 421483 421493 421501 421517 421559 421607 421609 421621 421633 421639 421643 421657 421661 421691 421697 421699 421703 421709 421711 421717 421727 421739 421741 421783 421801 421807 421831 421847 421891 421907 421913 421943 421973 421987 421997 422029 422041 422057 422063 422069 422077 422083 422087 422089 422099 422101 422111 422113 422129 422137 422141 422183 422203 422209 422231 422239 422243 422249 422267 422287 422291 422309 422311 422321 422339 422353 422363 422369 422377 422393 422407 422431 422453 422459 422479 422537 422549 422551 422557 422563 422567 422573 422581 422621 422627 422657 422689 422701 422707 422711 422749 422753 422759 422761 422789 422797 422803 422827 422857 422861 422867 422869 422879 422881 422893 422897 422899 422911 422923 422927 422969 422987 423001 423013 423019 423043 423053 423061 423067 423083 423091 423097 423103 423109 423121 423127 423133 423173 423179 423191 423209 423221 423229 423233 423251 423257 423259 423277 423281 423287 423289 423299 423307 423323 423341 423347 423389 423403 423413 423427 423431 423439 423457 423461 423463 423469 423481 423497 423503 423509 423541 423547 423557 423559 423581 423587 423601 423617 423649 423667 423697 423707 423713 423727 423749 423751 423763 423769 423779 423781 423791 423803 423823 423847 423853 423859 423869 423883 423887 423931 423949 423961 423977 423989 423991 424001 424003 424007 424019 424027 424037 424079 424091 424093 424103 424117 424121 424129 424139 424147 424157 424163 424169 424187 424199 424223 424231 424243 424247 424261 424267 424271 424273 424313 424331 424339 424343 424351 424397 424423 424429 424433 424451 424471 424481 424493 424519 424537 424547 424549 424559 424573 424577 424597 424601 424639 424661 424667 424679 424687 424693 424709 424727 424729 424757 424769 424771 424777 424811 424817 424819 424829 424841 424843 424849 424861 424867 424889 424891 424903 424909 424913 424939 424961 424967 424997 425003 425027 425039 425057 425059 425071 425083 425101 425107 425123 425147 425149 425189 425197 425207 425233 425237 425251 425273 425279 425281 425291 425297 425309 425317 425329 425333 425363 425377 425387 425393 425417 425419 425423 425441 425443 425471 425473 425489 425501 425519 425521 425533 425549 425563 425591 425603 425609 425641 425653 425681 425701 425713 425779 425783 425791 425801 425813 425819 425837 425839 425851 425857 425861 425869 425879 425899 425903 425911 425939 425959 425977 425987 425989 426007 426011 426061 426073 426077 426089 426091 426103 426131 426161 426163 426193 426197 426211 426229 426233 426253 426287 426301 426311 426319 426331 426353 426383 426389 426401 426407 426421 426427 426469 426487 426527 426541 426551 426553 426563 426583 426611 426631 426637 426641 426661 426691 426697 426707 426709 426731 426737 426739 426743 426757 426761 426763 426773 426779 426787 426799 426841 426859 426863 426871 426889 426893 426913 426917 426919 426931 426941 426971 426973 426997 427001 427013 427039 427043 427067 427069 427073 427079 427081 427103 427117 427151 427169 427181 427213 427237 427241 427243 427247 427249 427279 427283 427307 427309 427327 427333 427351 427369 427379 427381 427403 427417 427421 427423 427429 427433 427439 427447 427451 427457 427477 427513 427517 427523 427529 427541 427579 427591 427597 427619 427621 427681 427711 427717 427723 427727 427733 427751 427781 427787 427789 427813 427849 427859 427877 427879 427883 427913 427919 427939 427949 427951 427957 427967 427969 427991 427993 427997 428003 428023 428027 428033 428039 428041 428047 428083 428093 428137 428143 428147 428149 428161 428167 428173 428177 428221 428227 428231 428249 428251 428273 428297 428299 428303 428339 428353 428369 428401 428411 428429 428471 428473 428489 428503 428509 428531 428539 428551 428557 428563 428567 428569 428579 428629 428633 428639 428657 428663 428671 428677 428683 428693 428731 428741 428759 428777 428797 428801 428807 428809 428833 428843 428851 428863 428873 428899 428951 428957 428977 429007 429017 429043 429083 429101 429109 429119 429127 429137 429139 429161 429181 429197 429211 429217 429223 429227 429241 429259 429271 429277 429281 429283 429329 429347 429349 429361 429367 429389 429397 429409 429413 429427 429431 429449 429463 429467 429469 429487 429497 429503 429509 429511 429521 429529 429547 429551 429563 429581 429587 429589 429599 429631 429643 429659 429661 429673 429677 429679 429683 429701 429719 429727 429731 429733 429773 429791 429797 429817 429823 429827 429851 429853 429881 429887 429889 429899 429901 429907 429911 429917 429929 429931 429937 429943 429953 429971 429973 429991 430007 430009 430013 430019 430057 430061 430081 430091 430093 430121 430139 430147 430193 430259 430267 430277 430279 430289 430303 430319 430333 430343 430357 430393 430411 430427 430433 430453 430487 430499 430511 430513 430517 430543 430553 430571 430579 430589 430601 430603 430649 430663 430691 430697 430699 430709 430723 430739 430741 430747 430751 430753 430769 430783 430789 430799 430811 430819 430823 430841 430847 430861 430873 430879 430883 430891 430897 430907 430909 430921 430949 430957 430979 430981 430987 430999 431017 431021 431029 431047 431051 431063 431077 431083 431099 431107 431141 431147 431153 431173 431191 431203 431213 431219 431237 431251 431257 431267 431269 431287 431297 431311 431329 431339 431363 431369 431377 431381 431399 431423 431429 431441 431447 431449 431479 431513 431521 431533 431567 431581 431597 431603 431611 431617 431621 431657 431659 431663 431671 431693 431707 431729 431731 431759 431777 431797 431801 431803 431807 431831 431833 431857 431863 431867 431869 431881 431887 431891 431903 431911 431929 431933 431947 431983 431993 432001 432007 432023 432031 432037 432043 432053 432059 432067 432073 432097 432121 432137 432139 432143 432149 432161 432163 432167 432199 432203 432227 432241 432251 432277 432281 432287 432301 432317 432323 432337 432343 432349 432359 432373 432389 432391 432401 432413 432433 432437 432449 432457 432479 432491 432499 432503 432511 432527 432539 432557 432559 432569 432577 432587 432589 432613 432631 432637 432659 432661 432713 432721 432727 432737 432743 432749 432781 432793 432797 432799 432833 432847 432857 432869 432893 432907 432923 432931 432959 432961 432979 432983 432989 433003 433033 433049 433051 433061 433073 433079 433087 433093 433099 433117 433123 433141 433151 433187 433193 433201 433207 433229 433241 433249 433253 433259 433261 433267 433271 433291 433309 433319 433337 433351 433357 433361 433369 433373 433393 433399 433421 433429 433439 433453 433469 433471 433501 433507 433513 433549 433571 433577 433607 433627 433633 433639 433651 433661 433663 433673 433679 433681 433703 433723 433729 433747 433759 433777 433781 433787 433813 433817 433847 433859 433861 433877 433883 433889 433931 433943 433963 433967 433981 434009 434011 434029 434039 434081 434087 434107 434111 434113 434117 434141 434167 434179 434191 434201 434209 434221 434237 434243 434249 434261 434267 434293 434297 434303 434311 434323 434347 434353 434363 434377 434383 434387 434389 434407 434411 434431 434437 434459 434461 434471 434479 434501 434509 434521 434561 434563 434573 434593 434597 434611 434647 434659 434683 434689 434699 434717 434719 434743 434761 434783 434803 434807 434813 434821 434827 434831 434839 434849 434857 434867 434873 434881 434909 434921 434923 434927 434933 434939 434947 434957 434963 434977 434981 434989 435037 435041 435059 435103 435107 435109 435131 435139 435143 435151 435161 435179 435181 435187 435191 435221 435223 435247 435257 435263 435277 435283 435287 435307 435317 435343 435349 435359 435371 435397 435401 435403 435419 435427 435437 435439 435451 435481 435503 435529 435541 435553 435559 435563 435569 435571 435577 435583 435593 435619 435623 435637 435641 435647 435649 435653 435661 435679 435709 435731 435733 435739 435751 435763 435769 435779 435817 435839 435847 435857 435859 435881 435889 435893 435907 435913 435923 435947 435949 435973 435983 435997 436003 436013 436027 436061 436081 436087 436091 436097 436127 436147 436151 436157 436171 436181 436217 436231 436253 436273 436279 436283 436291 436307 436309 436313 436343 436357 436399 436417 436427 436439 436459 436463 436477 436481 436483 436507 436523 436529 436531 436547 436549 436571 436591 436607 436621 436627 436649 436651 436673 436687 436693 436717 436727 436729 436739 436741 436757 436801 436811 436819 436831 436841 436853 436871 436889 436913 436957 436963 436967 436973 436979 436993 436999 437011 437033 437071 437077 437083 437093 437111 437113 437137 437141 437149 437153 437159 437191 437201 437219 437237 437243 437263 437273 437279 437287 437293 437321 437351 437357 437363 437387 437389 437401 437413 437467 437471 437473 437497 437501 437509 437519 437527 437533 437539 437543 437557 437587 437629 437641 437651 437653 437677 437681 437687 437693 437719 437729 437743 437753 437771 437809 437819 437837 437849 437861 437867 437881 437909 437923 437947 437953 437959 437977 438001 438017 438029 438047 438049 438091 438131 438133 438143 438169 438203 438211 438223 438233 438241 438253 438259 438271 438281 438287 438301 438313 438329 438341 438377 438391 438401 438409 438419 438439 438443 438467 438479 438499 438517 438521 438523 438527 438533 438551 438569 438589 438601 438611 438623 438631 438637 438661 438667 438671 438701 438707 438721 438733 438761 438769 438793 438827 438829 438833 438847 438853 438869 438877 438887 438899 438913 438937 438941 438953 438961 438967 438979 438983 438989 439007 439009 439063 439081 439123 439133 439141 439157 439163 439171 439183 439199 439217 439253 439273 439279 439289 439303 439339 439349 439357 439367 439381 439409 439421 439427 439429 439441 439459 439463 439471 439493 439511 439519 439541 439559 439567 439573 439577 439583 439601 439613 439631 439639 439661 439667 439687 439693 439697 439709 439723 439729 439753 439759 439763 439771 439781 439787 439799 439811 439823 439849 439853 439861 439867 439883 439891 439903 439919 439949 439961 439969 439973 439981 439991 440009 440023 440039 440047 440087 440093 440101 440131 440159 440171 440177 440179 440183 440203 440207 440221 440227 440239 440261 440269 440281 440303 440311 440329 440333 440339 440347 440371 440383 440389 440393 440399 440431 440441 440443 440471 440497 440501 440507 440509 440527 440537 440543 440549 440551 440567 440569 440579 440581 440641 440651 440653 440669 440677 440681 440683 440711 440717 440723 440731 440753 440761 440773 440807 440809 440821 440831 440849 440863 440893 440903 440911 440939 440941 440953 440959 440983 440987 440989 441011 441029 441041 441043 441053 441073 441079 441101 441107 441109 441113 441121 441127 441157 441169 441179 441187 441191 441193 441229 441247 441251 441257 441263 441281 441307 441319 441349 441359 441361 441403 441421 441443 441449 441461 441479 441499 441517 441523 441527 441547 441557 441563 441569 441587 441607 441613 441619 441631 441647 441667 441697 441703 441713 441737 441751 441787 441797 441799 441811 441827 441829 441839 441841 441877 441887 441907 441913 441923 441937 441953 441971 442003 442007 442009 442019 442027 442031 442033 442061 442069 442097 442109 442121 442139 442147 442151 442157 442171 442177 442181 442193 442201 442207 442217 442229 442237 442243 442271 442283 442291 442319 442327 442333 442363 442367 442397 442399 442439 442447 442457 442469 442487 442489 442499 442501 442517 442531 442537 442571 442573 442577 442579 442601 442609 442619 442633 442691 442699 442703 442721 442733 442747 442753 442763 442769 442777 442781 442789 442807 442817 442823 442829 442831 442837 442843 442861 442879 442903 442919 442961 442963 442973 442979 442987 442991 442997 443011 443017 443039 443041 443057 443059 443063 443077 443089 443117 443123 443129 443147 443153 443159 443161 443167 443171 443189 443203 443221 443227 443231 443237 443243 443249 443263 443273 443281 443291 443293 443341 443347 443353 443363 443369 443389 443407 443413 443419 443423 443431 443437 443453 443467 443489 443501 443533 443543 443551 443561 443563 443567 443587 443591 443603 443609 443629 443659 443687 443689 443701 443711 443731 443749 443753 443759 443761 443771 443777 443791 443837 443851 443867 443869 443873 443879 443881 443893 443899 443909 443917 443939 443941 443953 443983 443987 443999 444001 444007 444029 444043 444047 444079 444089 444109 444113 444121 444127 444131 444151 444167 444173 444179 444181 444187 444209 444253 444271 444281 444287 444289 444293 444307 444341 444343 444347 444349 444401 444403 444421 444443 444449 444461 444463 444469 444473 444487 444517 444523 444527 444529 444539 444547 444553 444557 444569 444589 444607 444623 444637 444641 444649 444671 444677 444701 444713 444739 444767 444791 444793 444803 444811 444817 444833 444841 444859 444863 444869 444877 444883 444887 444893 444901 444929 444937 444953 444967 444971 444979 445001 445019 445021 445031 445033 445069 445087 445091 445097 445103 445141 445157 445169 445183 445187 445199 445229 445261 445271 445279 445283 445297 445307 445321 445339 445363 445427 445433 445447 445453 445463 445477 445499 445507 445537 445541 445567 445573 445583 445589 445597 445619 445631 445633 445649 445657 445691 445699 445703 445741 445747 445769 445771 445789 445799 445807 445829 445847 445853 445871 445877 445883 445891 445931 445937 445943 445967 445969 446003 446009 446041 446053 446081 446087 446111 446123 446129 446141 446179 446189 446191 446197 446221 446227 446231 446261 446263 446273 446279 446293 446309 446323 446333 446353 446363 446387 446389 446399 446401 446417 446441 446447 446461 446473 446477 446503 446533 446549 446561 446569 446597 446603 446609 446647 446657 446713 446717 446731 446753 446759 446767 446773 446819 446827 446839 446863 446881 446891 446893 446909 446911 446921 446933 446951 446969 446983 447001 447011 447019 447053 447067 447079 447101 447107 447119 447133 447137 447173 447179 447193 447197 447211 447217 447221 447233 447247 447257 447259 447263 447311 447319 447323 447331 447353 447401 447409 447427 447439 447443 447449 447451 447463 447467 447481 447509 447521 447527 447541 447569 447571 447611 447617 447637 447641 447677 447683 447701 447703 447743 447749 447757 447779 447791 447793 447817 447823 447827 447829 447841 447859 447877 447883 447893 447901 447907 447943 447961 447983 447991 448003 448013 448027 448031 448057 448067 448073 448093 448111 448121 448139 448141 448157 448159 448169 448177 448187 448193 448199 448207 448241 448249 448303 448309 448313 448321 448351 448363 448367 448373 448379 448387 448397 448421 448451 448519 448531 448561 448597 448607 448627 448631 448633 448667 448687 448697 448703 448727 448733 448741 448769 448793 448801 448807 448829 448843 448853 448859 448867 448871 448873 448879 448883 448907 448927 448939 448969 448993 448997 448999 449003 449011 449051 449077 449083 449093 449107 449117 449129 449131 449149 449153 449161 449171 449173 449201 449203 449209 449227 449243 449249 449261 449263 449269 449287 449299 449303 449311 449321 449333 449347 449353 449363 449381 449399 449411 449417 449419 449437 449441 449459 449473 449543 449549 449557 449563 449567 449569 449591 449609 449621 449629 449653 449663 449671 449677 449681 449689 449693 449699 449741 449759 449767 449773 449783 449797 449807 449821 449833 449851 449879 449921 449929 449941 449951 449959 449963 449971 449987 449989 450001 450011 450019 450029 450067 450071 450077 450083 450101 450103 450113 450127 450137 450161 450169 450193 450199 450209 450217 450223 450227 450239 450257 450259 450277 450287 450293 450299 450301 450311 450343 450349 450361 450367 450377 450383 450391 450403 450413 450421 450431 450451 450473 450479 450481 450487 450493 450503 450529 450533 450557 450563 450581 450587 450599 450601 450617 450641 450643 450649 450677 450691 450707 450719 450727 450761 450767 450787 450797 450799 450803 450809 450811 450817 450829 450839 450841 450847 450859 450881 450883 450887 450893 450899 450913 450917 450929 450943 450949 450971 450991 450997 451013 451039 451051 451057 451069 451093 451097 451103 451109 451159 451177 451181 451183 451201 451207 451249 451277 451279 451301 451303 451309 451313 451331 451337 451343 451361 451387 451397 451411 451439 451441 451481 451499 451519 451523 451541 451547 451553 451579 451601 451609 451621 451637 451657 451663 451667 451669 451679 451681 451691 451699 451709 451723 451747 451753 451771 451783 451793 451799 451823 451831 451837 451859 451873 451879 451897 451901 451903 451909 451921 451933 451937 451939 451961 451967 451987 452009 452017 452027 452033 452041 452077 452083 452087 452131 452159 452161 452171 452191 452201 452213 452227 452233 452239 452269 452279 452293 452297 452329 452363 452377 452393 452401 452443 452453 452497 452519 452521 452531 452533 452537 452539 452549 452579 452587 452597 452611 452629 452633 452671 452687 452689 452701 452731 452759 452773 452797 452807 452813 452821 452831 452857 452869 452873 452923 452953 452957 452983 452989 453023 453029 453053 453073 453107 453119 453133 453137 453143 453157 453161 453181 453197 453199 453209 453217 453227 453239 453247 453269 453289 453293 453301 453311 453317 453329 453347 453367 453371 453377 453379 453421 453451 453461 453527 453553 453559 453569 453571 453599 453601 453617 453631 453637 453641 453643 453659 453667 453671 453683 453703 453707 453709 453737 453757 453797 453799 453823 453833 453847 453851 453877 453889 453907 453913 453923 453931 453949 453961 453977 453983 453991 454009 454021 454031 454033 454039 454061 454063 454079 454109 454141 454151 454159 454183 454199 454211 454213 454219 454229 454231 454247 454253 454277 454297 454303 454313 454331 454351 454357 454361 454379 454387 454409 454417 454451 454453 454483 454501 454507 454513 454541 454543 454547 454577 454579 454603 454609 454627 454637 454673 454679 454709 454711 454721 454723 454759 454763 454777 454799 454823 454843 454847 454849 454859 454889 454891 454907 454919 454921 454931 454943 454967 454969 454973 454991 455003 455011 455033 455047 455053 455093 455099 455123 455149 455159 455167 455171 455177 455201 455219 455227 455233 455237 455261 455263 455269 455291 455309 455317 455321 455333 455339 455341 455353 455381 455393 455401 455407 455419 455431 455437 455443 455461 455471 455473 455479 455489 455491 455513 455527 455531 455537 455557 455573 455579 455597 455599 455603 455627 455647 455659 455681 455683 455687 455701 455711 455717 455737 455761 455783 455789 455809 455827 455831 455849 455863 455881 455899 455921 455933 455941 455953 455969 455977 455989 455993 455999 456007 456013 456023 456037 456047 456061 456091 456107 456109 456119 456149 456151 456167 456193 456223 456233 456241 456283 456293 456329 456349 456353 456367 456377 456403 456409 456427 456439 456451 456457 456461 456499 456503 456517 456523 456529 456539 456553 456557 456559 456571 456581 456587 456607 456611 456613 456623 456641 456647 456649 456653 456679 456683 456697 456727 456737 456763 456767 456769 456791 456809 456811 456821 456871 456877 456881 456899 456901 456923 456949 456959 456979 456991 457001 457003 457013 457021 457043 457049 457057 457087 457091 457097 457099 457117 457139 457151 457153 457183 457189 457201 457213 457229 457241 457253 457267 457271 457277 457279 457307 457319 457333 457339 457363 457367 457381 457393 457397 457399 457403 457411 457421 457433 457459 457469 457507 457511 457517 457547 457553 457559 457571 457607 457609 457621 457643 457651 457661 457669 457673 457679 457687 457697 457711 457739 457757 457789 457799 457813 457817 457829 457837 457871 457889 457903 457913 457943 457979 457981 457987 458009 458027 458039 458047 458053 458057 458063 458069 458119 458123 458173 458179 458189 458191 458197 458207 458219 458239 458309 458317 458323 458327 458333 458357 458363 458377 458399 458401 458407 458449 458477 458483 458501 458531 458533 458543 458567 458569 458573 458593 458599 458611 458621 458629 458639 458651 458663 458669 458683 458701 458719 458729 458747 458789 458791 458797 458807 458819 458849 458863 458879 458891 458897 458917 458921 458929 458947 458957 458959 458963 458971 458977 458981 458987 458993 459007 459013 459023 459029 459031 459037 459047 459089 459091 459113 459127 459167 459169 459181 459209 459223 459229 459233 459257 459271 459293 459301 459313 459317 459337 459341 459343 459353 459373 459377 459383 459397 459421 459427 459443 459463 459467 459469 459479 459509 459521 459523 459593 459607 459611 459619 459623 459631 459647 459649 459671 459677 459691 459703 459749 459763 459791 459803 459817 459829 459841 459847 459883 459913 459923 459929 459937 459961 460013 460039 460051 460063 460073 460079 460081 460087 460091 460099 460111 460127 460147 460157 460171 460181 460189 460211 460217 460231 460247 460267 460289 460297 460301 460337 460349 460373 460379 460387 460393 460403 460409 460417 460451 460463 460477 460531 460543 460561 460571 460589 460609 460619 460627 460633 460637 460643 460657 460673 460697 460709 460711 460721 460771 460777 460787 460793 460813 460829 460841 460843 460871 460891 460903 460907 460913 460919 460937 460949 460951 460969 460973 460979 460981 460987 460991 461009 461011 461017 461051 461053 461059 461093 461101 461119 461143 461147 461171 461183 461191 461207 461233 461239 461257 461269 461273 461297 461299 461309 461317 461323 461327 461333 461359 461381 461393 461407 461411 461413 461437 461441 461443 461467 461479 461507 461521 461561 461569 461581 461599 461603 461609 461627 461639 461653 461677 461687 461689 461693 461707 461717 461801 461803 461819 461843 461861 461887 461891 461917 461921 461933 461957 461971 461977 461983 462013 462041 462067 462073 462079 462097 462103 462109 462113 462131 462149 462181 462191 462199 462221 462239 462263 462271 462307 462311 462331 462337 462361 462373 462377 462401 462409 462419 462421 462437 462443 462467 462481 462491 462493 462499 462529 462541 462547 462557 462569 462571 462577 462589 462607 462629 462641 462643 462653 462659 462667 462673 462677 462697 462713 462719 462727 462733 462739 462773 462827 462841 462851 462863 462871 462881 462887 462899 462901 462911 462937 462947 462953 462983 463003 463031 463033 463093 463103 463157 463181 463189 463207 463213 463219 463231 463237 463247 463249 463261 463283 463291 463297 463303 463313 463319 463321 463339 463343 463363 463387 463399 463433 463447 463451 463453 463457 463459 463483 463501 463511 463513 463523 463531 463537 463549 463579 463613 463627 463633 463643 463649 463663 463679 463693 463711 463717 463741 463747 463753 463763 463781 463787 463807 463823 463829 463831 463849 463861 463867 463873 463889 463891 463907 463919 463921 463949 463963 463973 463987 463993 464003 464011 464021 464033 464047 464069 464081 464089 464119 464129 464131 464137 464141 464143 464171 464173 464197 464201 464213 464237 464251 464257 464263 464279 464281 464291 464309 464311 464327 464351 464371 464381 464383 464413 464419 464437 464447 464459 464467 464479 464483 464521 464537 464539 464549 464557 464561 464587 464591 464603 464617 464621 464647 464663 464687 464699 464741 464747 464749 464753 464767 464771 464773 464777 464801 464803 464809 464813 464819 464843 464857 464879 464897 464909 464917 464923 464927 464939 464941 464951 464953 464963 464983 464993 464999 465007 465011 465013 465019 465041 465061 465067 465071 465077 465079 465089 465107 465119 465133 465151 465161 465163 465167 465169 465173 465187 465209 465211 465259 465271 465277 465281 465293 465299 465317 465319 465331 465337 465373 465379 465383 465407 465419 465433 465463 465469 465523 465529 465541 465551 465581 465587 465611 465631 465643 465649 465659 465679 465701 465721 465739 465743 465761 465781 465797 465799 465809 465821 465833 465841 465887 465893 465901 465917 465929 465931 465947 465977 465989 466009 466019 466027 466033 466043 466061 466069 466073 466079 466087 466091 466121 466139 466153 466171 466181 466183 466201 466243 466247 466261 466267 466273 466283 466303 466321 466331 466339 466357 466369 466373 466409 466423 466441 466451 466483 466517 466537 466547 466553 466561 466567 466573 466579 466603 466619 466637 466649 466651 466673 466717 466723 466729 466733 466747 466751 466777 466787 466801 466819 466853 466859 466897 466909 466913 466919 466951 466957 466997 467003 467009 467017 467021 467063 467081 467083 467101 467119 467123 467141 467147 467171 467183 467197 467209 467213 467237 467239 467261 467293 467297 467317 467329 467333 467353 467371 467399 467417 467431 467437 467447 467471 467473 467477 467479 467491 467497 467503 467507 467527 467531 467543 467549 467557 467587 467591 467611 467617 467627 467629 467633 467641 467651 467657 467669 467671 467681 467689 467699 467713 467729 467737 467743 467749 467773 467783 467813 467827 467833 467867 467869 467879 467881 467893 467897 467899 467903 467927 467941 467953 467963 467977 468001 468011 468019 468029 468049 468059 468067 468071 468079 468107 468109 468113 468121 468133 468137 468151 468157 468173 468187 468191 468199 468239 468241 468253 468271 468277 468289 468319 468323 468353 468359 468371 468389 468421 468439 468451 468463 468473 468491 468493 468499 468509 468527 468551 468557 468577 468581 468593 468599 468613 468619 468623 468641 468647 468653 468661 468667 468683 468691 468697 468703 468709 468719 468737 468739 468761 468773 468781 468803 468817 468821 468841 468851 468859 468869 468883 468887 468889 468893 468899 468913 468953 468967 468973 468983 469009 469031 469037 469069 469099 469121 469127 469141 469153 469169 469193 469207 469219 469229 469237 469241 469253 469267 469279 469283 469303 469321 469331 469351 469363 469367 469369 469379 469397 469411 469429 469439 469457 469487 469501 469529 469541 469543 469561 469583 469589 469613 469627 469631 469649 469657 469673 469687 469691 469717 469723 469747 469753 469757 469769 469787 469793 469801 469811 469823 469841 469849 469877 469879 469891 469907 469919 469939 469957 469969 469979 469993 470021 470039 470059 470077 470081 470083 470087 470089 470131 470149 470153 470161 470167 470179 470201 470207 470209 470213 470219 470227 470243 470251 470263 470279 470297 470299 470303 470317 470333 470347 470359 470389 470399 470411 470413 470417 470429 470443 470447 470453 470461 470471 470473 470489 470501 470513 470521 470531 470539 470551 470579 470593 470597 470599 470609 470621 470627 470647 470651 470653 470663 470669 470689 470711 470719 470731 470749 470779 470783 470791 470819 470831 470837 470863 470867 470881 470887 470891 470903 470927 470933 470941 470947 470957 470959 470993 470999 471007 471041 471061 471073 471089 471091 471101 471137 471139 471161 471173 471179 471187 471193 471209 471217 471241 471253 471259 471277 471281 471283 471299 471301 471313 471353 471389 471391 471403 471407 471439 471451 471467 471481 471487 471503 471509 471521 471533 471539 471553 471571 471589 471593 471607 471617 471619 471641 471649 471659 471671 471673 471677 471683 471697 471703 471719 471721 471749 471769 471781 471791 471803 471817 471841 471847 471853 471871 471893 471901 471907 471923 471929 471931 471943 471949 471959 471997 472019 472027 472051 472057 472063 472067 472103 472111 472123 472127 472133 472139 472151 472159 472163 472189 472193 472247 472249 472253 472261 472273 472289 472301 472309 472319 472331 472333 472349 472369 472391 472393 472399 472411 472421 472457 472469 472477 472523 472541 472543 472559 472561 472573 472597 472631 472639 472643 472669 472687 472691 472697 472709 472711 472721 472741 472751 472763 472793 472799 472817 472831 472837 472847 472859 472883 472907 472909 472921 472937 472939 472963 472993 473009 473021 473027 473089 473101 473117 473141 473147 473159 473167 473173 473191 473197 473201 473203 473219 473227 473257 473279 473287 473293 473311 473321 473327 473351 473353 473377 473381 473383 473411 473419 473441 473443 473453 473471 473477 473479 473497 473503 473507 473513 473519 473527 473531 473533 473549 473579 473597 473611 473617 473633 473647 473659 473719 473723 473729 473741 473743 473761 473789 473833 473839 473857 473861 473867 473887 473899 473911 473923 473927 473929 473939 473951 473953 473971 473981 473987 473999 474017 474029 474037 474043 474049 474059 474073 474077 474101 474119 474127 474137 474143 474151 474163 474169 474197 474211 474223 474241 474263 474289 474307 474311 474319 474337 474343 474347 474359 474379 474389 474391 474413 474433 474437 474443 474479 474491 474497 474499 474503 474533 474541 474547 474557 474569 474571 474581 474583 474619 474629 474647 474659 474667 474671 474707 474709 474737 474751 474757 474769 474779 474787 474809 474811 474839 474847 474857 474899 474907 474911 474917 474923 474931 474937 474941 474949 474959 474977 474983 475037 475051 475073 475081 475091 475093 475103 475109 475141 475147 475151 475159 475169 475207 475219 475229 475243 475271 475273 475283 475289 475297 475301 475327 475331 475333 475351 475367 475369 475379 475381 475403 475417 475421 475427 475429 475441 475457 475469 475483 475511 475523 475529 475549 475583 475597 475613 475619 475621 475637 475639 475649 475669 475679 475681 475691 475693 475697 475721 475729 475751 475753 475759 475763 475777 475789 475793 475807 475823 475831 475837 475841 475859 475877 475879 475889 475897 475903 475907 475921 475927 475933 475957 475973 475991 475997 476009 476023 476027 476029 476039 476041 476059 476081 476087 476089 476101 476107 476111 476137 476143 476167 476183 476219 476233 476237 476243 476249 476279 476299 476317 476347 476351 476363 476369 476381 476401 476407 476419 476423 476429 476467 476477 476479 476507 476513 476519 476579 476587 476591 476599 476603 476611 476633 476639 476647 476659 476681 476683 476701 476713 476719 476737 476743 476753 476759 476783 476803 476831 476849 476851 476863 476869 476887 476891 476911 476921 476929 476977 476981 476989 477011 477013 477017 477019 477031 477047 477073 477077 477091 477131 477149 477163 477209 477221 477229 477259 477277 477293 477313 477317 477329 477341 477359 477361 477383 477409 477439 477461 477469 477497 477511 477517 477523 477539 477551 477553 477557 477571 477577 477593 477619 477623 477637 477671 477677 477721 477727 477731 477739 477767 477769 477791 477797 477809 477811 477821 477823 477839 477847 477857 477863 477881 477899 477913 477941 477947 477973 477977 477991 478001 478039 478063 478067 478069 478087 478099 478111 478129 478139 478157 478169 478171 478189 478199 478207 478213 478241 478243 478253 478259 478271 478273 478321 478339 478343 478351 478391 478399 478403 478411 478417 478421 478427 478433 478441 478451 478453 478459 478481 478483 478493 478523 478531 478571 478573 478579 478589 478603 478627 478631 478637 478651 478679 478697 478711 478727 478729 478739 478741 478747 478763 478769 478787 478801 478811 478813 478823 478831 478843 478853 478861 478871 478879 478897 478901 478913 478927 478931 478937 478943 478963 478967 478991 478999 479023 479027 479029 479041 479081 479131 479137 479147 479153 479189 479191 479201 479209 479221 479231 479239 479243 479263 479267 479287 479299 479309 479317 479327 479357 479371 479377 479387 479419 479429 479431 479441 479461 479473 479489 479497 479509 479513 479533 479543 479561 479569 479581 479593 479599 479623 479629 479639 479701 479749 479753 479761 479771 479777 479783 479797 479813 479821 479833 479839 479861 479879 479881 479891 479903 479909 479939 479951 479953 479957 479971 480013 480017 480019 480023 480043 480047 480049 480059 480061 480071 480091 480101 480107 480113 480133 480143 480157 480167 480169 480203 480209 480287 480299 480317 480329 480341 480343 480349 480367 480373 480379 480383 480391 480409 480419 480427 480449 480451 480461 480463 480499 480503 480509 480517 480521 480527 480533 480541 480553 480563 480569 480583 480587 480647 480661 480707 480713 480731 480737 480749 480761 480773 480787 480803 480827 480839 480853 480881 480911 480919 480929 480937 480941 480959 480967 480979 480989 481001 481003 481009 481021 481043 481051 481067 481073 481087 481093 481097 481109 481123 481133 481141 481147 481153 481157 481171 481177 481181 481199 481207 481211 481231 481249 481297 481301 481303 481307 481343 481363 481373 481379 481387 481409 481417 481433 481447 481469 481489 481501 481513 481531 481549 481571 481577 481589 481619 481633 481639 481651 481667 481673 481681 481693 481697 481699 481721 481751 481753 481769 481787 481801 481807 481813 481837 481843 481847 481849 481861 481867 481879 481883 481909 481939 481963 481997 482017 482021 482029 482033 482039 482051 482071 482093 482099 482101 482117 482123 482179 482189 482203 482213 482227 482231 482233 482243 482263 482281 482309 482323 482347 482351 482359 482371 482387 482393 482399 482401 482407 482413 482423 482437 482441 482483 482501 482507 482509 482513 482519 482527 482539 482569 482593 482597 482621 482627 482633 482641 482659 482663 482683 482687 482689 482707 482711 482717 482719 482731 482743 482753 482759 482767 482773 482789 482803 482819 482827 482837 482861 482863 482873 482897 482899 482917 482941 482947 482957 482971 483017 483031 483061 483071 483097 483127 483139 483163 483167 483179 483209 483211 483221 483229 483233 483239 483247 483251 483281 483289 483317 483323 483337 483347 483367 483377 483389 483397 483407 483409 483433 483443 483467 483481 483491 483499 483503 483523 483541 483551 483557 483563 483577 483611 483619 483629 483643 483649 483671 483697 483709 483719 483727 483733 483751 483757 483761 483767 483773 483787 483809 483811 483827 483829 483839 483853 483863 483869 483883 483907 483929 483937 483953 483971 483991 484019 484027 484037 484061 484067 484079 484091 484111 484117 484123 484129 484151 484153 484171 484181 484193 484201 484207 484229 484243 484259 484283 484301 484303 484327 484339 484361 484369 484373 484397 484411 484417 484439 484447 484457 484459 484487 484489 484493 484531 484543 484577 484597 484607 484609 484613 484621 484639 484643 484691 484703 484727 484733 484751 484763 484769 484777 484787 484829 484853 484867 484927 484951 484987 484999 485021 485029 485041 485053 485059 485063 485081 485101 485113 485123 485131 485137 485161 485167 485171 485201 485207 485209 485263 485311 485347 485351 485363 485371 485383 485389 485411 485417 485423 485437 485447 485479 485497 485509 485519 485543 485567 485587 485593 485603 485609 485647 485657 485671 485689 485701 485717 485729 485731 485753 485777 485819 485827 485831 485833 485893 485899 485909 485923 485941 485959 485977 485993 486023 486037 486041 486043 486053 486061 486071 486091 486103 486119 486133 486139 486163 486179 486181 486193 486203 486221 486223 486247 486281 486293 486307 486313 486323 486329 486331 486341 486349 486377 486379 486389 486391 486397 486407 486433 486443 486449 486481 486491 486503 486509 486511 486527 486539 486559 486569 486583 486589 486601 486617 486637 486641 486643 486653 486667 486671 486677 486679 486683 486697 486713 486721 486757 486767 486769 486781 486797 486817 486821 486833 486839 486869 486907 486923 486929 486943 486947 486949 486971 486977 486991 487007 487013 487021 487049 487051 487057 487073 487079 487093 487099 487111 487133 487177 487183 487187 487211 487213 487219 487247 487261 487283 487303 487307 487313 487349 487363 487381 487387 487391 487397 487423 487427 487429 487447 487457 487463 487469 487471 487477 487481 487489 487507 487561 487589 487601 487603 487607 487637 487649 487651 487657 487681 487691 487703 487709 487717 487727 487733 487741 487757 487769 487783 487789 487793 487811 487819 487829 487831 487843 487873 487889 487891 487897 487933 487943 487973 487979 487997 488003 488009 488011 488021 488051 488057 488069 488119 488143 488149 488153 488161 488171 488197 488203 488207 488209 488227 488231 488233 488239 488249 488261 488263 488287 488303 488309 488311 488317 488321 488329 488333 488339 488347 488353 488381 488399 488401 488407 488417 488419 488441 488459 488473 488503 488513 488539 488567 488573 488603 488611 488617 488627 488633 488639 488641 488651 488687 488689 488701 488711 488717 488723 488729 488743 488749 488759 488779 488791 488797 488821 488827 488833 488861 488879 488893 488897 488909 488921 488947 488959 488981 488993 489001 489011 489019 489043 489053 489061 489101 489109 489113 489127 489133 489157 489161 489179 489191 489197 489217 489239 489241 489257 489263 489283 489299 489329 489337 489343 489361 489367 489389 489407 489409 489427 489431 489439 489449 489457 489479 489487 489493 489529 489539 489551 489553 489557 489571 489613 489631 489653 489659 489673 489677 489679 489689 489691 489733 489743 489761 489791 489793 489799 489803 489817 489823 489833 489847 489851 489869 489871 489887 489901 489911 489913 489941 489943 489959 489961 489977 489989 490001 490003 490019 490031 490033 490057 490097 490103 490111 490117 490121 490151 490159 490169 490183 490201 490207 490223 490241 490247 490249 490267 490271 490277 490283 490309 490313 490339 490367 490393 490417 490421 490453 490459 490463 490481 490493 490499 490519 490537 490541 490543 490549 490559 490571 490573 490577 490579 490591 490619 490627 490631 490643 490661 490663 490697 490733 490741 490769 490771 490783 490829 490837 490849 490859 490877 490891 490913 490921 490927 490937 490949 490951 490957 490967 490969 490991 490993 491003 491039 491041 491059 491081 491083 491129 491137 491149 491159 491167 491171 491201 491213 491219 491251 491261 491273 491279 491297 491299 491327 491329 491333 491339 491341 491353 491357 491371 491377 491417 491423 491429 491461 491483 491489 491497 491501 491503 491527 491531 491537 491539 491581 491591 491593 491611 491627 491633 491639 491651 491653 491669 491677 491707 491719 491731 491737 491747 491773 491783 491789 491797 491819 491833 491837 491851 491857 491867 491873 491899 491923 491951 491969 491977 491983 492007 492013 492017 492029 492047 492053 492059 492061 492067 492077 492083 492103 492113 492227 492251 492253 492257 492281 492293 492299 492319 492377 492389 492397 492403 492409 492413 492421 492431 492463 492467 492487 492491 492511 492523 492551 492563 492587 492601 492617 492619 492629 492631 492641 492647 492659 492671 492673 492707 492719 492721 492731 492757 492761 492763 492769 492781 492799 492839 492853 492871 492883 492893 492901 492911 492967 492979 493001 493013 493021 493027 493043 493049 493067 493093 493109 493111 493121 493123 493127 493133 493139 493147 493159 493169 493177 493193 493201 493211 493217 493219 493231 493243 493249 493277 493279 493291 493301 493313 493333 493351 493369 493393 493397 493399 493403 493433 493447 493457 493463 493481 493523 493531 493541 493567 493573 493579 493583 493607 493621 493627 493643 493657 493693 493709 493711 493721 493729 493733 493747 493777 493793 493807 493811 493813 493817 493853 493859 493873 493877 493897 493919 493931 493937 493939 493967 493973 493979 493993 494023 494029 494041 494051 494069 494077 494083 494093 494101 494107 494129 494141 494147 494167 494191 494213 494237 494251 494257 494267 494269 494281 494287 494317 494327 494341 494353 494359 494369 494381 494383 494387 494407 494413 494441 494443 494471 494497 494519 494521 494539 494561 494563 494567 494587 494591 494609 494617 494621 494639 494647 494651 494671 494677 494687 494693 494699 494713 494719 494723 494731 494737 494743 494749 494759 494761 494783 494789 494803 494843 494849 494873 494899 494903 494917 494927 494933 494939 494959 494987 495017 495037 495041 495043 495067 495071 495109 495113 495119 495133 495139 495149 495151 495161 495181 495199 495211 495221 495241 495269 495277 495289 495301 495307 495323 495337 495343 495347 495359 495361 495371 495377 495389 495401 495413 495421 495433 495437 495449 495457 495461 495491 495511 495527 495557 495559 495563 495569 495571 495587 495589 495611 495613 495617 495619 495629 495637 495647 495667 495679 495701 495707 495713 495749 495751 495757 495769 495773 495787 495791 495797 495799 495821 495827 495829 495851 495877 495893 495899 495923 495931 495947 495953 495959 495967 495973 495983 496007 496019 496039 496051 496063 496073 496079 496123 496127 496163 496187 496193 496211 496229 496231 496259 496283 496289 496291 496297 496303 496313 496333 496339 496343 496381 496399 496427 496439 496453 496459 496471 496477 496481 496487 496493 496499 496511 496549 496579 496583 496609 496631 496669 496681 496687 496703 496711 496733 496747 496763 496789 496813 496817 496841 496849 496871 496877 496889 496891 496897 496901 496913 496919 496949 496963 496997 496999 497011 497017 497041 497047 497051 497069 497093 497111 497113 497117 497137 497141 497153 497171 497177 497197 497239 497257 497261 497269 497279 497281 497291 497297 497303 497309 497323 497339 497351 497389 497411 497417 497423 497449 497461 497473 497479 497491 497501 497507 497509 497521 497537 497551 497557 497561 497579 497587 497597 497603 497633 497659 497663 497671 497677 497689 497701 497711 497719 497729 497737 497741 497771 497773 497801 497813 497831 497839 497851 497867 497869 497873 497899 497929 497957 497963 497969 497977 497989 497993 497999 498013 498053 498061 498073 498089 498101 498103 498119 498143 498163 498167 498181 498209 498227 498257 498259 498271 498301 498331 498343 498361 498367 498391 498397 498401 498403 498409 498439 498461 498467 498469 498493 498497 498521 498523 498527 498551 498557 498577 498583 498599 498611 498613 498643 498647 498653 498679 498689 498691 498733 498739 498749 498761 498767 498779 498781 498787 498791 498803 498833 498857 498859 498881 498907 498923 498931 498937 498947 498961 498973 498977 498989 499021 499027 499033 499039 499063 499067 499099 499117 499127 499129 499133 499139 499141 499151 499157 499159 499181 499183 499189 499211 499229 499253 499267 499277 499283 499309 499321 499327 499349 499361 499363 499391 499397 499403 499423 499439 499459 499481 499483 499493 499507 499519 499523 499549 499559 499571 499591 499601 499607 499621 499633 499637 499649 499661 499663 499669 499673 499679 499687 499691 499693 499711 499717 499729 499739 499747 499781 499787 499801 499819 499853 499879 499883 499897 499903 499927 499943 499957 499969 499973 499979 500009 500029 500041 500057 500069 500083 )) ;;; length = 41544 (define (factorize num) (let ((factors ())) (call-with-exit (lambda (return) (for-each (lambda (p) ; first use the primes listed above (do ((val (/ num p) (/ num p))) ((not (integer? val))) ; checked before body is evaluated (set! factors (cons p factors)) (set! num val) (if (= num 1) (return (reverse factors))))) primes))) (if (> num 1) (call-with-exit (lambda (return) (do ((p 65539 (+ p 2))) (#f) ; now dumbly check all odd numbers above 65537 (do ((val (/ num p) (/ num p))) ((not (integer? val))) (set! factors (cons p factors)) (set! num val) (if (= num 1) (return (reverse factors)))))))) (reverse factors))) ;(factorize (* 76507 81299)) ;(factorize (* 3 98947 48781 77591 54709)) ;(factorize (expt 2 24)) ;(factorize (* 98947 98947)) ;(factorize (* 499523 499549 499559 499571 499591 499601 499607 499621 499633)) #| (define (factorize-1 num) ;; much slower in Scheme! (let ((factors ())) (call-with-exit (lambda (return) (for-each (lambda (p) ; first use the primes listed above (do ((val (/ num p) (/ num p))) ((not (integer? val))) ; checked before body is evaluated (set! factors (cons p factors)) (set! num val) (if (= num 1) (return (reverse factors))))) primes))) (if (> num 1) (call-with-exit (lambda (return) (do ((p 65539 (+ p 2)) ; fix this starting point! (ctr3 2 (+ ctr3 1)) (ctr5 2 (+ ctr5 1)) (ctr7 6 (+ ctr7 1))) (#f) (if (= ctr3 3) (set! ctr3 0)) (if (= ctr5 5) (set! ctr5 0)) (if (= ctr7 7) (set! ctr7 0)) (if (and (> ctr3 0) (> ctr5 0) (> ctr7 0)) (do ((val (/ num p) (/ num p))) ((not (integer? val))) (set! factors (cons p factors)) (set! num val) (if (= num 1) (return (reverse factors))))))))) (reverse factors)) |# #| (do ((i 0 (+ 1 i))) ((= i 10)) (let ((num (random (* 75000 75000)))) (display (format #f "~A " num)) (let ((val1 (factorize num))) (display (format #f "~A " val1)) (let ((val2 (factorize-1 num))) (display (format #f "~A " val2)) (if (not (equal? val1 val2)) (display "oops")) (display (format #f "~%")))))) |# snd-16.1/gtk-effects-utils.scm0000644000076400007640000001542112435167075014414 0ustar bilbil(require snd-gtk) (provide 'snd-gtk-effects-utils.scm) (with-let *gtk* (if (not (defined? 'all-chans)) (define (all-chans) (let ((sndlist ()) (chnlist ())) (for-each (lambda (snd) (do ((i (- (channels snd) 1) (- i 1))) ((< i 0)) (set! sndlist (cons snd sndlist)) (set! chnlist (cons i chnlist)))) (sounds)) (list sndlist chnlist)))) (define (update-label effects) (if (pair? effects) (begin ((car effects)) (update-label (cdr effects))))) (define (effect-target-ok target) (if (eq? target 'sound) (pair? (sounds)) (if (eq? target 'selection) (selection?) (and (selected-sound) (>= (length (marks (selected-sound) (selected-channel))) 2))))) (define* (make-effect-dialog label ok-callback help-callback reset-callback target-ok-callback) ;; make a standard dialog ;; callbacks take 2 args: widget data (let ((new-dialog (gtk_dialog_new)) (dismiss-button #f) (help-button #f) (ok-button #f) (reset-button #f)) (gtk_window_set_title (GTK_WINDOW new-dialog) label) (gtk_container_set_border_width (GTK_CONTAINER new-dialog) 10) (gtk_window_set_default_size (GTK_WINDOW new-dialog) -1 -1) (gtk_window_set_resizable (GTK_WINDOW new-dialog) #t) (gtk_widget_realize new-dialog) (g_signal_connect new-dialog "delete_event" (lambda (w ev data) (gtk_widget_hide new-dialog) #t) ; this is crucial -- thanks to Kjetil for catching it! #f) (set! dismiss-button (gtk_dialog_add_button (GTK_DIALOG new-dialog) "Go Away" GTK_RESPONSE_NONE)) (g_signal_connect dismiss-button "clicked" (lambda (w data) (gtk_widget_hide new-dialog)) #f) (gtk_widget_show dismiss-button) (set! ok-button (gtk_dialog_add_button (GTK_DIALOG new-dialog) "DoIt" GTK_RESPONSE_NONE)) (g_signal_connect ok-button "clicked" ok-callback #f) (gtk_widget_show ok-button) (if reset-callback (begin (set! reset-button (gtk_dialog_add_button (GTK_DIALOG new-dialog) "Reset" GTK_RESPONSE_NONE)) (g_signal_connect reset-button "clicked" reset-callback #f) (gtk_widget_set_name reset-button "reset_button") (gtk_widget_show reset-button))) (set! help-button (gtk_dialog_add_button (GTK_DIALOG new-dialog) "Help" GTK_RESPONSE_NONE)) (g_signal_connect help-button "clicked" help-callback #f) (gtk_widget_show help-button) (gtk_widget_set_name dismiss-button "quit_button") (gtk_widget_set_name help-button "help_button") (gtk_widget_set_name ok-button "doit_button") (if target-ok-callback (begin (gtk_widget_set_sensitive ok-button (target-ok-callback)) (hook-push effects-hook (lambda (hook) (gtk_widget_set_sensitive ok-button (target-ok-callback))))) (begin (gtk_widget_set_sensitive ok-button (pair? (sounds))) (hook-push effects-hook (lambda (hook) (gtk_widget_set_sensitive ok-button (pair? (sounds))))))) (g_object_set_data (G_OBJECT new-dialog) "ok-button" (GPOINTER ok-button)) new-dialog)) (define (change-label w new-label) (if w (if (GTK_IS_LABEL w) (gtk_label_set_text (GTK_LABEL w) new-label) (gtk_label_set_text (GTK_LABEL (gtk_bin_get_child (GTK_BIN w))) new-label)))) ;;; -------- log scaler widget (define log-scale-ticks 500) ; sets precision (to some extent) of slider (define (scale-log->linear lo val hi) ;; given user-relative low..val..hi return val as scale-relative (0..log-scale-ticks) (let (;; using log 2 here to get equally spaced octaves (log-lo (log (max lo 1.0) 2)) (log-hi (log hi 2)) (log-val (log val 2))) (floor (* log-scale-ticks (/ (- log-val log-lo) (- log-hi log-lo)))))) (define (scale-linear->log lo val hi) ;; given user-relative lo..hi and scale-relative val, return user-relative val ;; since log-scale widget assumes 0..log-scale-ticks, val can be used as ratio (log-wise) between lo and hi (let* ((log-lo (log (max lo 1.0) 2)) (log-hi (log hi 2)) (log-val (+ log-lo (* (/ val log-scale-ticks) (- log-hi log-lo))))) (expt 2.0 log-val))) (define (scale-log-label lo val hi) (format #f "~,2F" (scale-linear->log lo val hi))) (define (add-sliders dialog sliders) ;; sliders is a list of lists, each inner list being (title low initial high callback scale ['log]) ;; returns list of widgets (for reset callbacks) (let* ((mainform (gtk_box_new GTK_ORIENTATION_VERTICAL 2)) (use-hbox (= (length sliders) 1)) (table (if (not use-hbox) (gtk_grid_new))) (slider 0)) (gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG dialog))) mainform #f #f 4) (gtk_widget_show mainform) (if (not use-hbox) (begin (gtk_box_pack_start (GTK_BOX mainform) table #f #f 4) (gtk_grid_set_row_spacing (GTK_GRID table) 4) (gtk_grid_set_column_spacing (GTK_GRID table) 4) (gtk_widget_show table))) (map (lambda (slider-data) (let* ((title (slider-data 0)) (low (slider-data 1)) (initial (slider-data 2)) (high (slider-data 3)) (func (slider-data 4)) (scaler (slider-data 5)) (use-log (and (= (length slider-data) 7) (eq? (slider-data 6) 'log))) (hbox (and use-hbox (gtk_box_new GTK_ORIENTATION_HORIZONTAL 0))) (label (gtk_label_new (if use-hbox (if use-log (format #f "~A: ~,2F" title initial) (format #f "~A:" title)) (if use-log (format #f "~A (~,2F)" title initial) (format #f "~A" title))))) (adj (if use-log (gtk_adjustment_new (scale-log->linear low initial high) 0 log-scale-ticks 1 10 1) (gtk_adjustment_new initial low high 0.0 0.0 0.0))) (scale (gtk_scale_new GTK_ORIENTATION_HORIZONTAL (GTK_ADJUSTMENT adj)))) (if use-hbox (begin (gtk_box_pack_start (GTK_BOX mainform) hbox #f #f 2) (gtk_widget_show hbox) (gtk_box_pack_start (GTK_BOX hbox) label #f #f 6)) (gtk_grid_attach (GTK_GRID table) label 0 slider 1 1) ) (gtk_widget_show label) (gtk_scale_set_digits (GTK_SCALE scale) (if use-log 0 (if (= scaler 1000) 3 (if (= scaler 100) 2 (if (= scaler 10) 1 0))))) (gtk_scale_set_draw_value (GTK_SCALE scale) (not use-log)) (if use-hbox (gtk_box_pack_start (GTK_BOX hbox) scale #t #t 0) (begin (gtk_widget_set_hexpand (GTK_WIDGET scale) #t) (gtk_grid_attach (GTK_GRID table) scale 1 slider 1 1) (set! slider (+ 1 slider)))) (gtk_widget_show scale) (if use-log (g_signal_connect adj "value_changed" (lambda (w d) (func w d) (change-label label (format #f "~A: ~,2F" title (scale-linear->log low (gtk_adjustment_get_value (GTK_ADJUSTMENT adj)) high)))) #f) (g_signal_connect adj "value_changed" func #f)) adj)) sliders))) (define (activate-dialog w) (gtk_widget_show w) (gtk_window_present (GTK_WINDOW w))) ) snd-16.1/bess1.scm0000644000076400007640000004705212511600662012063 0ustar bilbil;;; bess1.scm -- some examples from clm-2/rt.lisp and clm-2/bess5.cl ;; Author: Michael Scholz ;; Created: Thu May 29 04:14:35 CEST 2003 ;; Last: Sun Jun 15 03:50:21 CEST 2003 ;; changed slightly 14-Jun-06 Bill to match bess.scm, fix pitch problem in make-oscil. ;; then again 18-Dec-09 to use s7 rather than Guile ;; changed float-vector-map! to use a loop instead (Bill 4-July-12) (if (not (provided? 'snd-motif)) (error "bess1.scm needs motif")) ;;; Commentary: ;; This file provides simple mono real time output to DAC. Tempo, ;; frequency, amplitude, and FM index can be controlled via sliders. ;; The music algorithms are taken from clm-2/rt.lisp and ;; clm-2/bess5.cl. ;; (main) calls (rt-motif) which starts a Motif widget with two DAC ;; tests. ;; ;; (rt-motif :srate *clm-srate* ;; 22050 ;; :bufsize *clm-rt-bufsize* ;; 128 ;; :sample-type *clm-sample-type*) ;; mus-lshort ;;; Code: (with-let *motif* (set! *clm-srate* 22050) (define *clm-sample-type* mus-lfloat) (define *clm-rt-bufsize* 1024) (define *output* #f) ;holds fd from (mus-audio-open-output) (define ctempo 0.25) (define camp 1.0) (define cfreq 1.0) (define cindex 1.0) (define cplay #f) (define sliderback "lightsteelblue") (define background "lightsteelblue1") ;(define (seconds->samples secs) (round (* secs *clm-srate*))) ;; called by XtAppAddWorkProc (define (rt-send->dac func) (if cplay (let ((data (make-float-vector *clm-rt-bufsize*))) (do ((i 0 (+ i 1))) ((= i *clm-rt-bufsize*)) (set! (data i) (func))) (mus-audio-write *output* (copy data (make-float-vector (list 1 *clm-rt-bufsize*) 0.0)) *clm-rt-bufsize*) #f) (begin (mus-audio-close *output*) #t))) (define make-rt-violin (let ((documentation "(make-rt-violin dur freq amp (fm-index 1.0) (amp-env '(0 0 25 1 75 1 100 0))) real time simple violin (see fm.html)")) (lambda* (dur freq amp (fm-index 1.0) (amp-env '(0 0 25 1 75 1 100 0))) (let* ((frq-scl (hz->radians freq)) (maxdev (* frq-scl fm-index)) (index1 (* maxdev (/ 5.0 (log freq)))) (index2 (* maxdev 3.0 (/ (- 8.5 (log freq)) (+ 3.0 (/ freq 1000))))) (index3 (* maxdev (/ 4.0 (sqrt freq)))) (carrier (make-oscil :frequency freq)) (fmosc1 (make-oscil :frequency freq)) (fmosc2 (make-oscil :frequency (* 3 freq))) (fmosc3 (make-oscil :frequency (* 4 freq))) (ampf (make-env :envelope amp-env :scaler amp :duration dur)) (indf1 (make-env :envelope '(0 1 25 0.4 75 0.6 100 0) :scaler index1 :duration dur)) (indf2 (make-env :envelope '(0 1 25 0.4 75 0.6 100 0) :scaler index2 :duration dur)) (indf3 (make-env :envelope '(0 1 25 0.4 75 0.6 100 0) :scaler index3 :duration dur)) (pervib (make-triangle-wave :frequency 5 :amplitude (* 0.0025 frq-scl))) (ranvib (make-rand-interp :frequency 16 :amplitude (* 0.005 frq-scl)))) (lambda () (let ((vib (+ (triangle-wave pervib) (rand-interp ranvib)))) (* (env ampf) (oscil carrier (+ vib (* (env indf1) (oscil fmosc1 vib)) (* (env indf2) (oscil fmosc2 (* 3.0 vib))) (* (env indf3) (oscil fmosc3 (* 4.0 vib)))))))))))) (define lim 256) ;; from clm-2/rt.lisp (define* (make-float-vector-test (srate *clm-srate*) (bufsize *clm-rt-bufsize*) (sample-type *clm-sample-type*)) (let ((vmode (vector 0 12 2 4 14 4 5 5 0 7 7 11 11)) (vpits (make-vector (+ 1 lim) 0)) (vbegs (make-vector (+ 1 lim) 0)) (cellbeg 0) (cellsiz 6) (cellctr 0) (func #f) (len 0) (dur 0.0)) (do ((i 0 (+ 1 i))) ((= i lim)) (set! (vpits i) (floor (random 12.0))) (set! (vbegs i) (+ 1 (floor (random 3.0))))) (set! *clm-srate* srate) (set! *clm-rt-bufsize* bufsize) (set! *output* (mus-audio-open-output mus-audio-default srate 1 sample-type (* bufsize 2))) (lambda () (if (> len 1) (set! len (- len 1)) (begin (set! dur (* ctempo (vbegs (+ cellctr 1)))) (set! cellctr (+ cellctr 1)) (if (> cellctr (+ cellsiz cellbeg)) (begin (if (> (random 1.0) 0.5) (set! cellbeg (+ 1 cellbeg))) (if (> (random 1.0) 0.5) (set! cellsiz (+ 1 cellsiz))) (set! cellctr cellbeg))) (format #t "dur: ~A, freq: ~A, amp: ~A, index: ~A~%" dur (let ((freq (* cfreq 16.351 16 (expt 2 (/ (vmode (vpits cellctr)) 12.0))))) (if (< (* 8 freq) *clm-srate*) freq (/ freq 4))) (* camp 0.3) cindex) (set! func (make-rt-violin dur (let ((freq (* cfreq 16.351 16 (expt 2 (/ (vmode (vpits cellctr)) 12.0))))) (if (< (* 8 freq) *clm-srate*) freq (/ freq 4))) (* camp 0.3) :fm-index cindex)) (set! len (ceiling (/ (seconds->samples dur) bufsize))))) func))) ;; from clm-2/bess5.cl and clm-2/clm-example.lisp (define time 60) (define mode (vector 0 0 2 4 11 11 5 6 7 9 2 0 0)) (define rats (vector 1.0 256/243 9/8 32/27 81/64 4/3 1024/729 3/2 128/81 27/16 16/9 243/128 2.0)) (define bell '(0 0 10 0.25 90 1.0 100 1.0)) (define pits (make-vector (+ 1 lim) 0)) (define octs (make-vector (+ 1 lim) 0)) (define rhys (make-vector (+ 1 lim) 0)) (define begs (make-vector (+ 1 lim) 0)) (define amps (make-vector (+ 1 lim) 0)) (define (tune x) (let* ((pit (modulo x 12)) (oct (floor (/ x 12))) (base (rats pit))) (* base (expt 2 oct)))) (define (rbell x) (envelope-interp (* x 100) bell)) (define* (make-agn (srate *clm-srate*) (bufsize *clm-rt-bufsize*) (sample-type *clm-sample-type*)) (let ((wins (vector '(0 0 40 0.1 60 0.2 75 0.4 82 1 90 1 100 0) '(0 0 60 0.1 80 0.2 90 0.4 95 1 100 0) '(0 0 10 1 16 0 32 0.1 50 1 56 0 60 0 90 0.3 100 0) '(0 0 30 1 56 0 60 0 90 0.3 100 0) '(0 0 50 1 80 0.3 100 0) '(0 0 40 0.1 60 0.2 75 0.4 82 1 90 1 100 0) '(0 0 40 0.1 60 0.2 75 0.4 82 1 90 1 100 0) '(0 0 10 1 32 0.1 50 1 90 0.3 100 0) '(0 0 60 0.1 80 0.3 95 1 100 0) '(0 0 80 0.1 90 1 100 0))) (nextbeg 0.0) (beg 0.0) (dur 0.0) (freq 0.0) (ampl 0.0) (ind 0.0) (cellctr 0) (cellsiz 4) (cellbeg 0) (whichway 1) (func #f) (len 0)) (do ((i 0 (+ i 1))) ((= i lim)) (set! (octs i) (floor (+ 4 (* 2 (rbell (random 1.0)))))) (set! (pits i) (mode (floor (random 12.0)))) (set! (rhys i) (floor (+ 4 (random 6.0)))) (set! (begs i) (if (< (random 1.0) 0.9) (floor (+ 4 (random 2.0))) (floor (random 24.0)))) (set! (amps i) (floor (+ 1 (* 8 (rbell (random 1.0))))))) (set! *clm-srate* srate) (set! *clm-rt-bufsize* bufsize) (set! *output* (mus-audio-open-output mus-audio-default srate 1 sample-type (* bufsize 2))) (lambda () (if (> len 1) (set! len (- len 1)) (begin (set! beg (+ beg nextbeg)) (set! nextbeg (+ nextbeg (max 0.025 (* ctempo (+ 0.95 (random 0.1)) (begs cellctr))))) (set! dur (max 0.025 (* ctempo (+ 0.85 (random 0.1)) (rhys cellctr)))) (set! freq (* cfreq 16.351 (tune (pits cellctr)) (expt 2 (octs cellctr)))) (set! ampl (* camp 10 (max 0.003 (* (amps cellctr) 0.01)))) (set! ind (* cindex (random 3.0))) (set! cellctr (+ cellctr 1)) (if (> cellctr (+ cellsiz cellbeg)) (begin (set! cellbeg (+ 1 cellbeg)) (if (> (random 1.0) 0.5) (set! cellsiz (+ cellsiz whichway))) (if (and (> cellsiz 10) (> (random 1.0) 0.99)) (set! whichway -2) (if (and (> cellsiz 6) (> (random 1.0) 0.999)) (set! whichway -1) (if (< cellsiz 4) (set! whichway 1)))) (set! nextbeg (+ nextbeg (random 1.0))) (set! cellctr cellbeg))) (set! func (make-rt-violin dur freq ampl :fm-index ind :amp-env (wins (floor (* 10 (- beg (floor beg))))))) (set! len (ceiling (/ (seconds->samples dur) bufsize))))) func))) #| ;; from env.scm (define* (envelope-interp :rest args) (let ((x (car args)) (env (cadr args)) (base (if (null? (cddr args)) #f (caddr args)))) (cond ((null? env) 0.0) ((or (<= x (car env)) (null? (cddr env))) (cadr env)) ((> (caddr env) x) (if (or (= (cadr env) (cadddr env)) (and base (= base 0.0))) (cadr env) (if (or (not base) (= base 1.0)) (+ (cadr env) (* (- x (car env)) (/ (- (cadddr env) (cadr env)) (- (caddr env) (car env))))) (+ (cadr env) (* (/ (- (cadddr env) (cadr env)) (- base 1.0)) (- (expt base (/ (- x (car env)) (- (caddr env) (car env)))) 1.0)))))) (else (envelope-interp x (cddr env)))))) |# (define* (rt-motif :rest args) (let* ((shell-app (XtVaOpenApplication "FM" 0 () applicationShellWidgetClass (list XmNallowShellResize #t))) (app (cadr shell-app)) (shell (car shell-app)) (dpy (XtDisplay shell)) (screen (DefaultScreenOfDisplay dpy)) (cmap (DefaultColormap dpy (DefaultScreen dpy))) (black (BlackPixelOfScreen screen))) (define (get-color color) (let ((col (XColor))) (if (= (XAllocNamedColor dpy cmap color col col) 0) (error (format #f "can't allocate ~A" color)) (.pixel col)))) (define (set-flabel label value) (let ((s1 (XmStringCreate (format #f "~5,3F" value) XmFONTLIST_DEFAULT_TAG))) (XtVaSetValues label (list XmNlabelString s1)) (XmStringFree s1))) (XtSetValues shell (list XmNtitle "FM Forever!")) (let* ((light-blue (get-color sliderback)) (form (XtCreateManagedWidget "form" xmFormWidgetClass shell (list XmNbackground (get-color background) XmNforeground black XmNresizePolicy XmRESIZE_GROW))) ;; play (play-button (XtCreateManagedWidget "play" xmToggleButtonWidgetClass form (list XmNleftAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_NONE XmNtopAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_NONE XmNbackground (get-color background)))) ;; radio (radio (XmCreateRadioBox form "radio" (list XmNorientation XmHORIZONTAL XmNleftAttachment XmATTACH_WIDGET XmNleftWidget play-button XmNbottomAttachment XmATTACH_NONE XmNtopAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_NONE XmNbackground (get-color background)))) ;; play agn (agn-button (XtCreateManagedWidget "agn" xmToggleButtonWidgetClass radio (list XmNleftAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_NONE XmNtopAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_NONE XmNbackground (get-color background)))) ;; play test (test-button (XtCreateManagedWidget "test" xmToggleButtonWidgetClass radio (list XmNleftAttachment XmATTACH_WIDGET XmNleftWidget agn-button XmNbottomAttachment XmATTACH_NONE XmNtopAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_NONE XmNbackground (get-color background)))) ;; quit (quit-button (XtCreateManagedWidget " quit " xmPushButtonWidgetClass form (list XmNleftAttachment XmATTACH_WIDGET XmNleftWidget radio XmNbottomAttachment XmATTACH_NONE XmNtopAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNbackground (get-color background)))) (sep (XtCreateManagedWidget "sep" xmSeparatorWidgetClass form (list XmNleftAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_NONE XmNtopAttachment XmATTACH_WIDGET XmNtopWidget radio XmNrightAttachment XmATTACH_FORM XmNheight 4 XmNorientation XmHORIZONTAL))) ;; tempo (tempo (XtCreateManagedWidget " tempo:" xmLabelWidgetClass form (list XmNleftAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_NONE XmNtopAttachment XmATTACH_WIDGET XmNtopWidget sep XmNrightAttachment XmATTACH_NONE XmNrecomputeSize #f XmNbackground (get-color background)))) (tempo-label (XtCreateManagedWidget "label" xmLabelWidgetClass form (list XmNleftAttachment XmATTACH_WIDGET XmNleftWidget tempo XmNbottomAttachment XmATTACH_NONE XmNtopAttachment XmATTACH_OPPOSITE_WIDGET XmNtopWidget tempo XmNrightAttachment XmATTACH_NONE XmNbackground (get-color background)))) (tempo-scale (XtCreateManagedWidget "tempo" xmScaleWidgetClass form (list XmNleftAttachment XmATTACH_WIDGET XmNleftWidget tempo-label XmNbottomAttachment XmATTACH_NONE XmNtopAttachment XmATTACH_OPPOSITE_WIDGET XmNtopWidget tempo-label XmNrightAttachment XmATTACH_FORM XmNshowValue #f XmNorientation XmHORIZONTAL XmNheight 20 XmNbackground light-blue))) ;; freq (freq (XtCreateManagedWidget " freq:" xmLabelWidgetClass form (list XmNleftAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_NONE XmNtopAttachment XmATTACH_WIDGET XmNtopWidget tempo XmNrightAttachment XmATTACH_NONE XmNrecomputeSize #f XmNbackground (get-color background)))) (freq-label (XtCreateManagedWidget "label" xmLabelWidgetClass form (list XmNleftAttachment XmATTACH_WIDGET XmNleftWidget freq XmNbottomAttachment XmATTACH_NONE XmNtopAttachment XmATTACH_OPPOSITE_WIDGET XmNtopWidget freq XmNrightAttachment XmATTACH_NONE XmNbackground (get-color background)))) (freq-scale (XtCreateManagedWidget "freq" xmScaleWidgetClass form (list XmNleftAttachment XmATTACH_WIDGET XmNleftWidget freq-label XmNbottomAttachment XmATTACH_NONE XmNtopAttachment XmATTACH_OPPOSITE_WIDGET XmNtopWidget freq-label XmNrightAttachment XmATTACH_FORM XmNshowValue #f XmNorientation XmHORIZONTAL XmNheight 20 XmNbackground light-blue))) ;; amp (amp (XtCreateManagedWidget " amp:" xmLabelWidgetClass form (list XmNleftAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_NONE XmNtopAttachment XmATTACH_WIDGET XmNtopWidget freq XmNrightAttachment XmATTACH_NONE XmNrecomputeSize #f XmNbackground (get-color background)))) (amp-label (XtCreateManagedWidget "label" xmLabelWidgetClass form (list XmNleftAttachment XmATTACH_WIDGET XmNleftWidget amp XmNbottomAttachment XmATTACH_NONE XmNtopAttachment XmATTACH_OPPOSITE_WIDGET XmNtopWidget amp XmNrightAttachment XmATTACH_NONE XmNbackground (get-color background)))) (amp-scale (XtCreateManagedWidget "amp" xmScaleWidgetClass form (list XmNleftAttachment XmATTACH_WIDGET XmNleftWidget amp-label XmNbottomAttachment XmATTACH_NONE XmNtopAttachment XmATTACH_OPPOSITE_WIDGET XmNtopWidget amp-label XmNrightAttachment XmATTACH_FORM XmNshowValue #f XmNorientation XmHORIZONTAL XmNheight 20 XmNbackground light-blue))) ;; index (index (XtCreateManagedWidget " index:" xmLabelWidgetClass form (list XmNleftAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_NONE XmNtopAttachment XmATTACH_WIDGET XmNtopWidget amp XmNrightAttachment XmATTACH_NONE XmNrecomputeSize #f XmNbackground (get-color background)))) (index-label (XtCreateManagedWidget "label" xmLabelWidgetClass form (list XmNleftAttachment XmATTACH_WIDGET XmNleftWidget index XmNbottomAttachment XmATTACH_NONE XmNtopAttachment XmATTACH_OPPOSITE_WIDGET XmNtopWidget index XmNrightAttachment XmATTACH_NONE XmNbackground (get-color background)))) (index-scale (XtCreateManagedWidget "index" xmScaleWidgetClass form (list XmNleftAttachment XmATTACH_WIDGET XmNleftWidget index-label XmNbottomAttachment XmATTACH_NONE XmNtopAttachment XmATTACH_OPPOSITE_WIDGET XmNtopWidget index-label XmNrightAttachment XmATTACH_FORM XmNshowValue #f XmNorientation XmHORIZONTAL XmNheight 20 XmNbackground light-blue))) (low-tempo 0.05) (high-tempo 0.5) (high-amp 1.0) (low-freq 0.1) (high-freq 4.0) (high-index 2.0) (which-play 0) (proc #f) (func #f)) (define (tempo-callback w c i) (set! ctempo (+ low-tempo (* (.value i) (/ (- high-tempo low-tempo) 100.0)))) (set-flabel tempo-label ctempo)) (define (amp-callback w c i) (set! camp (* (.value i) (/ high-amp 100.0))) (set-flabel amp-label camp)) (define (freq-callback w c i) (set! cfreq (+ low-freq (* (.value i) (/ (- high-freq low-freq) 100.0)))) (set-flabel freq-label cfreq)) (define (index-callback w c i) (set! cindex (* (.value i) (/ high-index 100.0))) (set-flabel index-label cindex)) (define (set-defaults) (set! ctempo 0.25) (set! camp 1.0) (set! cfreq 1.0) (set! cindex 1.0) (set-flabel tempo-label ctempo) (set-flabel amp-label camp) (set-flabel freq-label cfreq) (set-flabel index-label cindex) (XmScaleSetValue tempo-scale (floor (* 100 (/ (- ctempo low-tempo) (- high-tempo low-tempo))))) (XmScaleSetValue freq-scale (floor (* 100 (/ (- cfreq low-freq) (- high-freq low-freq))))) (XmScaleSetValue amp-scale (floor (* 100 camp))) (XmScaleSetValue index-scale (floor (* 100 (/ cindex high-index))))) (XtManageChild radio) ;; add scale-change (drag and value-changed) callbacks (XtAddCallback tempo-scale XmNdragCallback tempo-callback) (XtAddCallback tempo-scale XmNvalueChangedCallback tempo-callback) (XtAddCallback amp-scale XmNdragCallback amp-callback) (XtAddCallback amp-scale XmNvalueChangedCallback amp-callback) (XtAddCallback freq-scale XmNdragCallback freq-callback) (XtAddCallback freq-scale XmNvalueChangedCallback freq-callback) (XtAddCallback index-scale XmNdragCallback index-callback) (XtAddCallback index-scale XmNvalueChangedCallback index-callback) (XtAddCallback agn-button XmNvalueChangedCallback (lambda (w c i) (if (.set i) (set! which-play 0)) (set! cplay #f) (XmToggleButtonSetState play-button cplay #f))) (XmToggleButtonSetState agn-button #t #f) (XtAddCallback test-button XmNvalueChangedCallback (lambda (w c i) (if (.set i) (set! which-play 1)) (set! cplay #f) (XmToggleButtonSetState play-button cplay #f))) (XtAddCallback quit-button XmNactivateCallback (lambda (w c i) (set! cplay #f) (if proc (XtRemoveWorkProc proc)) (exit 0))) (XtAddCallback play-button XmNvalueChangedCallback (lambda (w c i) (set! cplay (.set i)) (if cplay (begin (set-defaults) (if (= which-play 0) (set! func (apply make-agn (or args ()))) (set! func (apply make-float-vector-test (or args ())))) (set! proc (XtAppAddWorkProc app (lambda (c) (rt-send->dac func))))) (if proc (XtRemoveWorkProc proc))))) (XmToggleButtonSetState play-button cplay #f) (set-defaults) (XtRealizeWidget shell)) (XtAppMainLoop app))) (rt-motif) ) ;; bess1.scm ends here snd-16.1/poly.scm0000644000076400007640000005716412615151310012032 0ustar bilbil;;; polynomial-related stuff ;;; ;;; poly+ poly* poly/ poly-gcd poly-reduce poly-roots poly-derivative poly-resultant poly-discriminant ;;; ;;; this file really needs doubles (--with-doubles in configure, double as s7_double in s7.h) (provide 'snd-poly.scm) (when (provided? 'pure-s7) (define (make-polar mag ang) (if (and (real? mag) (real? ang)) (complex (* mag (cos ang)) (* mag (sin ang))) (error 'wrong-type-arg "make-polar args should be real")))) (define (vector->float-vector v) (copy v (make-float-vector (length v) 0.0))) (define (float-vector->vector v) (copy v (make-vector (length v) 0.0))) ;;; using lists and vectors internally for complex intermediates (define vector-add! (let ((documentation "(vector-add! p1 p2) adds (elementwise) the vectors p1 and p2")) (lambda (p1 p2) (let ((len (min (length p1) (length p2)))) (do ((i 0 (+ i 1))) ((= i len)) (set! (p1 i) (+ (p1 i) (p2 i)))) p1)))) (define vector-scale! (let ((documentation "(vector-scale! p1 scl) scales each element of the vector p1 by scl")) (lambda (p1 scl) (let ((len (length p1))) (do ((i 0 (+ i 1))) ((= i len)) (set! (p1 i) (* scl (p1 i)))) p1)))) (define poly-as-vector-eval (let ((documentation "(poly-as-vector-eval v x) treats 'v' as a vector of polynomial coefficients, returning the value of the polynomial at x")) (lambda (v x) (let ((top (- (length v) 1))) (let ((sum (v top))) (do ((i (- top 1) (- i 1))) ((< i 0) sum) (set! sum (+ (* sum x) (v i))))))))) (define poly-as-vector-reduce (let ((documentation "(poly-as-vector-reduce p1) removes trailing (high-degree) zeros from the vector p1")) (lambda (p1) ;; always return at least a 0 coeff (rather than return #f=0 polynomial) (let ((new-len (do ((i (- (length p1) 1) (- i 1))) ((or (= i 0) (not (= (p1 i) 0.0))) (+ i 1))))) (if (= new-len (length p1)) p1 (let ((np (make-vector new-len))) (do ((i 0 (+ i 1))) ((= i new-len)) (set! (np i) (p1 i))) np)))))) (define poly-reduce (let ((documentation "(poly-reduce p1) removes trailing (high-degree) zeros from the float-vector p1")) (lambda (p1) (if (= (p1 (- (length p1) 1)) 0.0) (vector->float-vector (poly-as-vector-reduce (float-vector->vector p1))) p1)))) ;;; (poly-reduce (float-vector 1 2 3)) -> # ;;; (poly-reduce (float-vector 1 2 3 0 0 0)) -> # ;;; (poly-reduce (float-vector 0 0 0 0 1 0)) -> # (define poly-as-vector+ (let ((documentation "(poly-as-vector+ p1 p2) adds vectors p1 and p2")) (lambda (p1 p2) (if (vector? p1) (if (vector? p2) (if (> (length p1) (length p2)) (vector-add! (copy p1) p2) (vector-add! (copy p2) p1)) (let ((v (copy p1))) (set! (v 0) (+ (v 0) p2)) v)) (let ((v (copy p2))) (set! (v 0) (+ (v 0) p1)) v))))) (define poly+ (let ((documentation "(poly+ p1 p2) adds vectors or float-vectors p1 and p2")) (lambda (p1 p2) (vector->float-vector (poly-as-vector+ (if (float-vector? p1) (float-vector->vector p1) p1) (if (float-vector? p2) (float-vector->vector p2) p2)))))) ;;; (poly+ (float-vector .1 .2 .3) (float-vector 0.0 1.0 2.0 3.0 4.0)) -> # ;;; (poly+ (float-vector .1 .2 .3) .5) -> # ;;; (poly+ .5 (float-vector .1 .2 .3)) -> # (define poly-as-vector* (let ((documentation "(poly-as-vector* p1 p2) multiplies (as polynomials) the vectors p1 and p2")) (lambda (p1 p2) (if (vector? p1) (if (vector? p2) (let* ((p1len (length p1)) (p2len (length p2)) (len (+ p1len p2len)) (m (make-vector len 0))) (do ((i 0 (+ i 1))) ((= i p1len)) (do ((j 0 (+ j 1))) ((= j p2len)) (set! (m (+ i j)) (+ (m (+ i j)) (* (p1 i) (p2 j)))))) m) (vector-scale! (copy p1) p2)) (vector-scale! (copy p2) p1))))) (define poly* (let ((documentation "(poly* p1 p2) multiplies the polynomials (float-vectors or vectors) p1 and p2")) (lambda (p1 p2) (vector->float-vector (poly-as-vector* (if (float-vector? p1) (float-vector->vector p1) p1) (if (float-vector? p2) (float-vector->vector p2) p2)))))) ;;; (poly* (float-vector 1 1) (float-vector -1 1)) -> # ;;; (poly* (float-vector -5 1) (float-vector 3 7 2)) -> # ;;; (poly* (float-vector -30 -4 2) (float-vector 0.5 1)) -> # ;;; (poly* (float-vector -30 -4 2) 0.5) -> # ;;; (poly* 2.0 (float-vector -30 -4 2)) -> # (define poly-as-vector/ (let ((documentation "(poly-as-vector/ p1 p2) divides the polynomial p1 by p2 (both vectors)")) (lambda (p1 p2) (if (vector? p1) (if (vector? p2) ;; Numerical Recipes poldiv (let ((p1len (length p1)) (p2len (length p2))) (if (> p2len p1len) (list (vector 0) p2) (let* ((len (max p1len p2len)) (r (make-vector len 0)) (q (make-vector len 0))) (do ((i 0 (+ i 1))) ((= i len)) (set! (r i) (p1 i))) (let ((n (- p1len 1)) (nv (- p2len 1))) (do ((k (- n nv) (- k 1))) ((< k 0)) (set! (q k) (/ (r (+ nv k)) (p2 nv))) (do ((j (+ nv k -1) (- j 1))) ((< j k)) (set! (r j) (- (r j) (* (q k) (p2 (- j k))))))) (do ((j nv (+ j 1))) ((> j n)) (set! (r j) 0)) (list q r))))) (list (poly-as-vector* p1 (/ p2)) (vector 0))) (list (vector 0) p2))))) (define poly/ (let ((documentation "(poly/ p1 p2) divides p1 by p2, both polynomials either float-vectors or vectors")) (lambda (p1 p2) (map vector->float-vector (poly-as-vector/ (if (float-vector? p1) (float-vector->vector p1) p1) (if (float-vector? p2) (float-vector->vector p2) p2)))))) ;;; (poly/ (float-vector -1.0 -0.0 1.0) (vector 1.0 1.0)) -> (# #) ;;; (poly/ (float-vector -15 -32 -3 2) (vector -5 1)) -> (# #) ;;; (poly/ (float-vector -15 -32 -3 2) (vector 3 1)) -> (# #) ;;; (poly/ (float-vector -15 -32 -3 2) (vector .5 1)) -> (# #) ;;; (poly/ (float-vector -15 -32 -3 2) (vector 3 7 2)) -> (# #) ;;; (poly/ (float-vector -15 -32 -3 2) 2.0) -> (# #) (define poly-as-vector-derivative (let ((documentation "(poly-as-vector-derivative p1) returns the derivative or polynomial p1 (as a vector)")) (lambda (p1) (let* ((len (- (length p1) 1)) (v (make-vector len))) (do ((i (- len 1) (- i 1)) (j len (- j 1))) ((< i 0) v) (set! (v i) (* j (p1 j)))))))) (define poly-derivative (let ((documentation "(poly-derivative p1) returns the derivative of p1, either a float-vector or vector")) (lambda (p1) (vector->float-vector (poly-as-vector-derivative (float-vector->vector p1)))))) ;;; (poly-derivative (float-vector 0.5 1.0 2.0 4.0)) -> # ;;; poly-antiderivative with random number as constant? or max of all coeffs? -- 0.0 seems like a bad idea -- maybe an optional arg ;;; then poly-integrate: (let ((integral (poly-antiderivative p1))) (- (poly-as-vector-eval integral end) (poly-as-vector-eval integral beg))) (define (submatrix mx row col) (let* ((old-n (car (vector-dimensions mx))) (new-n (- old-n 1)) (nmx (make-float-vector (list new-n new-n) 0.0))) (do ((i 0 (+ i 1)) (ni 0)) ((= i old-n)) (if (not (= i row)) (begin (do ((j 0 (+ j 1)) (nj 0)) ((= j old-n)) (if (not (= j col)) (begin (set! (nmx ni nj) (mx i j)) (set! nj (+ nj 1))))) (set! ni (+ 1 ni))))) nmx)) (define (determinant mx) (if (not (float-vector? mx)) (error 'wrong-type-arg "determinant argument should be a float-vector") (let ((n (car (vector-dimensions mx)))) (if (= n 1) (mx 0 0) (if (= n 2) (- (* (mx 0 0) (mx 1 1)) (* (mx 0 1) (mx 1 0))) (if (= n 3) (- (+ (* (mx 0 0) (mx 1 1) (mx 2 2)) (* (mx 0 1) (mx 1 2) (mx 2 0)) (* (mx 0 2) (mx 1 0) (mx 2 1))) (+ (* (mx 0 0) (mx 1 2) (mx 2 1)) (* (mx 0 1) (mx 1 0) (mx 2 2)) (* (mx 0 2) (mx 1 1) (mx 2 0)))) (let ((sum 0.0) (sign 1)) (do ((i 0 (+ i 1))) ((= i n)) (let ((mult (mx 0 i))) (if (not (= mult 0.0)) (set! sum (+ sum (* sign mult (determinant (submatrix mx 0 i)))))) (set! sign (- sign)))) sum))))))) (define (poly-as-vector-resultant p1 p2) (if (or (not (vector? p1)) (not (vector? p2))) (error 'wrong-type-arg "poly-as-vector-resultant arguments should be vectors") (let* ((m (length p1)) (n (length p2)) (d (+ n m -2)) (mat (make-float-vector (list d d) 0.0))) ;; load matrix with n-1 rows of m's coeffs then m-1 rows of n's coeffs (reversed in sense), return determinant (do ((i 0 (+ i 1))) ((= i (- n 1))) (do ((j 0 (+ j 1))) ((= j m)) (set! (mat i (+ i j)) (p1 (- m j 1))))) (do ((i 0 (+ i 1))) ((= i (- m 1))) (do ((j 0 (+ j 1))) ((= j n)) (set! (mat (+ i n -1) (+ i j)) (p2 (- n j 1))))) (determinant mat)))) (define poly-resultant (let ((documentation "(poly-resultant p1 p2) returns the resultant of polynomials p1 and p2 (float-vectors or vectors)")) (lambda (p1 p2) (poly-as-vector-resultant (if (float-vector? p1) (float-vector->vector p1) p1) (if (float-vector? p2) (float-vector->vector p2) p2))))) (define poly-as-vector-discriminant (let ((documentation "(poly-as-vector-discriminant p1) returns the discriminant of polynomial p1 (a vector)")) (lambda (p1) (poly-as-vector-resultant p1 (poly-as-vector-derivative p1))))) (define poly-discriminant (let ((documentation "(poly-discriminant p1) returns the discriminant of polynomial p1 (either a float-vector or a vector)")) (lambda (p1) (poly-as-vector-discriminant (if (float-vector? p1) (float-vector->vector p1) p1))))) ;;; (poly-as-vector-resultant (vector -1 0 1) (vector 1 -2 1)) 0.0 (x=1 is the intersection) ;;; (poly-as-vector-resultant (vector -1 0 2) (vector 1 -2 1)) 1.0 ;;; (poly-as-vector-resultant (vector -1 0 1) (vector 1 1)) 0.0 (x=-1 is the intersection) ;;; (poly-as-vector-resultant (vector -1 0 1) (vector 2 1)) 3.0 ;;; (poly-as-vector-discriminant (vector -1 0 1)) -4.0 ;;; (poly-as-vector-discriminant (vector 1 -2 1)) 0.0 ;;; (poly-discriminant (poly-reduce (poly* (poly* (float-vector -1 1) (float-vector -1 1)) (float-vector 3 1)))) 0.0 ;;; (poly-discriminant (poly-reduce (poly* (poly* (poly* (float-vector -1 1) (float-vector -1 1)) (float-vector 3 1)) (float-vector 2 1)))) 0.0 ;;; (poly-discriminant (poly-reduce (poly* (poly* (poly* (float-vector 1 1) (float-vector -1 1)) (float-vector 3 1)) (float-vector 2 1)))) 2304 ;;; (poly-discriminant (poly-reduce (poly* (poly* (poly* (float-vector 1 1) (float-vector -1 1)) (float-vector 3 1)) (float-vector 3 1)))) 0.0 (define poly-roots-epsilon 1.0e-7) (define simplify-complex (let ((documentation "(simplify-complex a) sets to 0.0 real or imaginary parts of 'a' that are less than poly-roots-epsilon")) (lambda (a) (if (< (abs (imag-part a)) poly-roots-epsilon) (if (< (abs (real-part a)) poly-roots-epsilon) 0.0 (real-part a)) (if (< (abs (real-part a)) poly-roots-epsilon) (complex 0.0 (imag-part a)) a))))) (define poly-gcd (let ((documentation "(poly-gcd p1 p2) returns the GCD of polynomials p1 and p2 (both float-vectors)")) (lambda (p1 p2) (if (< (length p1) (length p2)) (float-vector 0.0) (let ((qr (map poly-reduce (poly/ p1 p2)))) (if (= (length (cadr qr)) 1) (if (= (float-vector-ref (cadr qr) 0) 0.0) p2 (float-vector 0.0)) (apply poly-gcd qr))))))) (define poly-as-vector-gcd (let ((documentation "(poly-as-vector-gcd p1 p2) returns the GCD of polynomials p1 and p2 (both vectors)")) (lambda (p1 p2) (if (< (length p1) (length p2)) (vector 0) (let ((qr (map poly-as-vector-reduce (poly-as-vector/ p1 p2)))) (if (= (length (cadr qr)) 1) (if (= ((cadr qr) 0) 0.0) p2 (vector 0)) (apply poly-as-vector-gcd qr))))))) ;;; (poly-gcd (poly-reduce (poly* (float-vector 2 1) (float-vector -3 1))) (float-vector 2 1)) -> # ;;; (poly-gcd (poly-reduce (poly* (float-vector 2 1) (float-vector -3 1))) (float-vector 3 1)) -> # ;;; (poly-gcd (poly-reduce (poly* (float-vector 2 1) (float-vector -3 1))) (float-vector -3 1)) -> # ;;; (poly-gcd (poly-reduce (poly* (float-vector 8 1) (poly* (float-vector 2 1) (float-vector -3 1)))) (float-vector -3 1)) -> # ;;; (poly-gcd (poly-reduce (poly* (float-vector 8 1) (poly* (float-vector 2 1) (float-vector -3 1)))) (poly-reduce (poly* (float-vector 8 1) (float-vector -3 1)))) -> # ;;; (poly-gcd (float-vector -1 0 1) (float-vector 2 -2 -1 1)) -> # ;;; (poly-gcd (float-vector 2 -2 -1 1) (float-vector -1 0 1)) -> # ;;; (poly-gcd (float-vector 2 -2 -1 1) (float-vector -2.5 1)) -> # (define (poly-as-vector-roots p1) (define (linear-root a b) ; ax + b (list (/ (- b) a))) (define (quadratic-roots a b c) ; ax^2 + bx + c (let ((d (sqrt (- (* b b) (* 4 a c))))) (list (/ (+ (- b) d) (* 2 a)) (/ (- (- b) d) (* 2 a))))) (define (cubic-roots a b c d) ; ax^3 + bx^2 + cx + d ;; Abramowitz & Stegun 3.8.2 (let* ((a0 (/ d a)) (a1 (/ c a)) (a2 (/ b a)) (q (- (/ a1 3) (/ (* a2 a2) 9))) (r (- (/ (- (* a1 a2) (* 3 a0)) 6) (/ (* a2 a2 a2) 27))) (q3r2 (+ (* q q q) (* r r))) (sq3r2 (sqrt q3r2)) (r1 (expt (+ r sq3r2) 1/3)) (r2 (expt (- r sq3r2) 1/3)) (incr (/ (* 2 pi 0+i) 3))) (call-with-exit (lambda (return) (do ((i 0 (+ i 1))) ; brute force! this can almost certainly be optimized ((= i 3)) (do ((j 0 (+ j 1))) ((= j 3)) (let* ((s1 (* r1 (exp (* i incr)))) (s2 (* r2 (exp (* j incr)))) (z1 (simplify-complex (- (+ s1 s2) (/ a2 3))))) (if (< (magnitude (poly-as-vector-eval (vector a0 a1 a2 1) z1)) poly-roots-epsilon) (let ((z2 (simplify-complex (+ (* -0.5 (+ s1 s2)) (/ a2 -3) (* (- s1 s2) 0.5 (sqrt -3)))))) (if (< (magnitude (poly-as-vector-eval (vector a0 a1 a2 1) z2)) poly-roots-epsilon) (let ((z3 (simplify-complex (+ (* -0.5 (+ s1 s2)) (/ a2 -3) (* (- s1 s2) -0.5 (sqrt -3)))))) (if (< (magnitude (poly-as-vector-eval (vector a0 a1 a2 1) z3)) poly-roots-epsilon) (return (list z1 z2 z3)))))))))) #f)))) (define (quartic-roots a b c d e) ; ax^4 + bx^3 + cx^2 + dx + e ;; Weisstein, "Encyclopedia of Mathematics" (call-with-exit (lambda (return) (let* ((a0 (/ e a)) (a1 (/ d a)) (a2 (/ c a)) (a3 (/ b a)) (yroot (poly-as-vector-roots (vector (+ (* 4 a2 a0) (- (* a1 a1)) (- (* a3 a3 a0))) (- (* a1 a3) (* 4 a0)) (- a2) 1.0)))) (if (and yroot (pair? yroot) (= (length yroot) 4)) (do ((i 0 (+ i 1))) ((= i 3)) (let* ((y1 (yroot i)) (R (sqrt (+ (* 0.25 a3 a3) (- a2) y1))) (D (if (= R 0) (sqrt (+ (* 0.75 a3 a3) (* -2 a2) (* 2 (sqrt (- (* y1 y1) (* 4 a0)))))) (sqrt (+ (* 0.75 a3 a3) (* -2 a2) (- (* R R)) (/ (* 0.25 (+ (* 4 a3 a2) (* -8 a1) (- (* a3 a3 a3)))) R))))) (E (if (= R 0) (sqrt (+ (* 0.75 a3 a3) (* -2 a2) (* -2 (sqrt (- (* y1 y1) (* 4 a0)))))) (sqrt (+ (* 0.75 a3 a3) (* -2 a2) (- (* R R)) (/ (* -0.25 (+ (* 4 a3 a2) (* -8 a1) (- (* a3 a3 a3)))) R))))) (z1 (+ (* -0.25 a3) (* 0.5 R) (* 0.5 D))) (z2 (+ (* -0.25 a3) (* 0.5 R) (* -0.5 D))) (z3 (+ (* -0.25 a3) (* -0.5 R) (* 0.5 E))) (z4 (+ (* -0.25 a3) (* -0.5 R) (* -0.5 E)))) (if (< (magnitude (poly-as-vector-eval (vector e d c b a) z1)) poly-roots-epsilon) (return (list z1 z2 z3 z4)))))) #f)))) (define (nth-roots a b deg) ; ax^n + b (let ((n (expt (/ (- b) a) (/ 1.0 deg))) (incr (/ (* 2 pi 0+i) deg)) (roots ())) (do ((i 0 (+ i 1))) ((= i deg)) (set! roots (cons (simplify-complex (* n (exp (* i incr)))) roots))) roots)) (let ((deg (- (length p1) 1))) (if (= deg 0) ; just constant () (if (= (p1 0) 0.0) ; constant=0.0, divide through by x, recurse on new (if (= deg 1) (list 0.0) (let ((pnew (make-vector deg))) (do ((i 1 (+ i 1))) ((> i deg)) (set! (pnew (- i 1)) (p1 i))) (append (list 0.0) (poly-as-vector-roots pnew)))) (if (= deg 1) ; ax + b -> -b/a (linear-root (p1 1) (p1 0)) (if (= deg 2) ; ax^2 + bx + c -> -b +/- sqrt(b^2 - 4ac) / 2a (quadratic-roots (p1 2) (p1 1) (p1 0)) (or (and (= deg 3) ;; it may be better to fall into Newton's method here (cubic-roots (p1 3) (p1 2) (p1 1) (p1 0))) (and (= deg 4) (quartic-roots (p1 4) (p1 3) (p1 2) (p1 1) (p1 0))) ;; degree>4 (or trouble above), use Newton's method unless some simple case pops up (let ((ones 0)) (do ((i 1 (+ i 1))) ((> i deg)) (if (not (= (p1 i) 0.0)) (set! ones (+ 1 ones)))) (if (= ones 1) ; x^n + b -- "linear" in x^n (nth-roots (p1 deg) (p1 0) deg) (if (and (= ones 2) (even? deg) (not (= (p1 (/ deg 2)) 0.0))) (let ((roots ()) ; quadratic in x^(n/2) (n (/ deg 2))) (for-each (lambda (r) (set! roots (append roots (nth-roots 1.0 (- r) n)))) (poly-as-vector-roots (vector (p1 0) (p1 (/ deg 2)) (p1 deg)))) roots) (if (and (> deg 3) (= ones 3) (= (modulo deg 3) 0) (not (= (p1 (/ deg 3)) 0.0)) (not (= (p1 (/ (* 2 deg) 3)) 0.0))) (let ((roots ()) ; cubic in x^(n/3) (n (/ deg 3))) (for-each (lambda (r) (set! roots (append roots (nth-roots 1.0 (- r) n)))) (poly-as-vector-roots (vector (p1 0) (p1 (/ deg 3)) (p1 (/ (* 2 deg) 3)) (p1 deg)))) roots) ;; perhaps get derivative roots, plug in main -- need to get nth derivative to be safe in this ;; from Cohen, "Computational Algebraic Number Theory" (let* ((roots ()) (q (copy p1)) (pp (poly-as-vector-derivative p1)) (qp (copy pp)) (n deg) (x 1.3+0.314159i) (v (poly-as-vector-eval q x)) (m (* (magnitude v) (magnitude v))) (dx 0.0) (last-dx 1.0) ; guard against infinite loop (happy #f)) (do () (happy) (set! dx (/ v (poly-as-vector-eval qp x))) (if (or (<= (magnitude dx) poly-roots-epsilon) (= dx last-dx)) (set! happy #t) (begin (set! last-dx dx) (do ((c 0 (+ 1 c)) (step3 #f)) ((or (>= c 20) step3 (<= (magnitude dx) poly-roots-epsilon))) (let* ((y (- x dx)) (v1 (poly-as-vector-eval q y)) (m1 (* (magnitude v1) (magnitude v1)))) (if (< m1 m) (begin (set! x y) (set! v v1) (set! m m1) (set! step3 #t)) (set! dx (/ dx 4.0)))))))) (set! x (- x (/ (poly-as-vector-eval p1 x) (poly-as-vector-eval pp x)))) (set! x (- x (/ (poly-as-vector-eval p1 x) (poly-as-vector-eval pp x)))) (if (< (imag-part x) poly-roots-epsilon) (begin (set! x (real-part x)) (set! q (poly-as-vector/ q (vector (- x) 1.0))) (set! n (- n 1))) (begin (set! q (poly-as-vector/ q (vector (magnitude x) 0.0 1.0))) (set! n (- n 2)))) (set! roots (cons x roots)) (if (> n 0) (set! roots (append (poly-as-vector-roots (poly-as-vector-reduce (car q))) roots))) roots)))))))))))) (define poly-roots (let ((documentation "(poly-roots p1) returns the roots of polynomial p1")) (lambda (p1) (let* ((v1 (float-vector->vector (poly-reduce p1))) (roots (poly-as-vector-roots v1))) (for-each (lambda (q) (let ((dx (magnitude (poly-as-vector-eval v1 q)))) (if (> dx poly-roots-epsilon) (format #t ";poly.scm 502: (poly-roots ~A) numerical trouble (polynomial root is not very good): ~A at ~A: ~A" p1 v1 q dx)))) roots) roots)))) #| (do ((i 0 (+ i 1))) ((= i 10)) (poly-as-vector-roots (vector (complex (mus-random 1.0) (mus-random 1.0)) (complex (mus-random 1.0) (mus-random 1.0))))) (do ((i 0 (+ i 1))) ((= i 10)) (poly-as-vector-roots (vector (complex (mus-random 1.0) (mus-random 1.0)) (complex (mus-random 1.0) (mus-random 1.0)) (complex (mus-random 1.0) (mus-random 1.0))))) (do ((i 0 (+ i 1))) ((= i 10)) (poly-roots (float-vector (mus-random 1.0) (mus-random 1.0) (mus-random 1.0) (mus-random 1.0)))) (do ((i 0 (+ i 1))) ((= i 10)) (poly-as-vector-roots (vector (complex (mus-random 1.0) (mus-random 1.0)) (complex (mus-random 1.0) (mus-random 1.0)) (complex (mus-random 1.0) (mus-random 1.0)) (complex (mus-random 1.0) (mus-random 1.0))))) (do ((i 0 (+ i 1))) ((= i 10)) (poly-roots (float-vector (mus-random 1.0) (mus-random 1.0) (mus-random 1.0) (mus-random 1.0) (mus-random 1.0)))) (do ((i 0 (+ i 1))) ((= i 10)) (poly-as-vector-roots (vector (complex (mus-random 1.0) (mus-random 1.0)) (complex (mus-random 1.0) (mus-random 1.0)) (complex (mus-random 1.0) (mus-random 1.0)) (complex (mus-random 1.0) (mus-random 1.0)) (complex (mus-random 1.0) (mus-random 1.0))))) (do ((i 3 (+ i 1))) ((= i 20)) (let ((v (make-float-vector i 0.0))) (set! (v 0) (mus-random 1.0)) (set! (v (- i 1)) 1.0) (poly-roots v))) (do ((i 3 (+ i 2))) ((= i 21)) (let ((v (make-float-vector i 0.0))) (set! (v 0) (mus-random 1.0)) (set! (v (- i 1)) 1.0) (set! (v (/ (- i 1) 2)) 1.0) (poly-roots v))) ;;; these can be off by a lot! (do ((i 0 (+ i 1))) ((= i 10)) (poly-roots (float-vector (mus-random 1.0) (mus-random 1.0) (mus-random 1.0) (mus-random 1.0) (mus-random 1.0) (mus-random 1.0)))) (poly-roots (poly* (poly* (poly* (float-vector -1 1) (float-vector 1 1)) (poly* (float-vector -2 1) (float-vector 2 1))) (poly* (float-vector -3 1) (float-vector 3 1)))) -> (-3.0 3.0 -1.0 1.0 -2.0 2.0) (poly-roots (poly* (poly* (float-vector -1 1) (float-vector 1 1)) (poly* (float-vector -2 1) (poly* (float-vector 2 1) (float-vector 3 1))))) -> (2.0 -1.0 -2.0 -3.0 1.0) ;;; numerical trouble: (poly-roots (float-vector 1000 .01 0 1)) ;; failed to find a root within poly-roots-epsilon -- get the best available (let ((s1 backup-s1) (s2 backup-s2)) (list (simplify-complex (- (+ s1 s2) (/ a2 3.0))) (simplify-complex (+ (* -0.5 (+ s1 s2)) (/ a2 -3.0) (* (- s1 s2) 0.5 (sqrt -3.0)))) (simplify-complex (+ (* -0.5 (+ s1 s2)) (/ a2 -3.0) (* (- s1 s2) -0.5 (sqrt -3.0)))))))))) |# snd-16.1/mix.rb0000644000076400007640000001574312434353162011472 0ustar bilbil# mix.rb -- mix.scm --> mix.rb # Translator: Michael Scholz # Created: 05/02/22 13:40:33 # Changed: 14/11/13 05:01:39 # various mix related functions # # module Mix (see mix.scm) # mix_sound(file, start) # silence_all_mixes # find_mix(sample, snd, chn) # mix2vct(id) # mix_maxamp(id) # snap_mix_to_beat(at_tag_position) # # mix_click_sets_amp(id) # mix_click_info(id) # mix_name2id(name) # # delete_mix(id) # scale_mixes(mix_list, scl) # silence_mixes(mix_list) # move_mixes(mix_list, samps) # src_mixes(mix_list, sr) # transpose_mixes(mix_list, semitones) # color_mixes(mix_list, col) # set_mixes_tag_y(mix_list, new_y) # mixes_maxamp(mix_list) # scale_tempo(mix_list, tempo_scl) # mixes_length(mix_list) require "clm" module Mix # # === MIX === # add_help(:mix_sound, "mix_sound(file, start) \ Mixes file (all chans) at start in the currently selected sound.") def mix_sound(file, start) mix(file, start, true) end add_help(:delete_all_mixes, "delete_all_mixes() \ Sets all mix amps to 0.") def silence_all_mixes as_one_edit_rb(get_func_name) do (mixes or []).flatten.each do |id| set_mix_amp(id, 0.0) end end end add_help(:find_mix, "find_mix(sample, snd=false, chn=false) \ Returns the id of the mix at the given sample, or nil.") def find_mix(sample, snd = false, chn = false) (mixes(Snd.snd(snd), Snd.chn(chn)) or []).detect do |n| mix_position(n) == sample end end add_help(:mix2vct, "mix2vct(id) \ Returns mix's data in vct.") def mix2vct(id) Snd.raise(:no_such_mix, id) unless mix?(id) len = mix_length(id) rd = make_mix_sampler(id) v = Vct.new(len) do |i| read_mix_sample(rd) end free_sampler(rd) v end add_help(:mix_maxamp, "mix_maxamp(id) \ Returns the max amp in the given mix.") def mix_maxamp(id) Snd.raise(:no_such_mix, id) unless mix?(id) len = mix_length(id) rd = make_mix_sampler(id) peak = read_mix_sample(rd).abs (1...len).each do peak = [peak, read_mix_sample(rd).abs].max end free_sampler(rd) peak end add_help(:snap_mix_to_beat, "snap_mix_to_beat() \ Forces a dragged mix to end up on a beat (see beats-per-minute). \ Reset $mix_release_hook to cancel.") def snap_mix_to_beat $mix_release_hook.add_hook!(get_func_name) do |id, samps_moved| samp = samps_moved + mix_position(id) snd = mix_home(id)[0] chn = mix_home(id)[1] bps = beats_per_minute(snd, chn) / 60.0 sr = srate(snd).to_f beat = ((samp * bps) / sr).floor lower = ((beat * sr) / bps).floor higher = (((beat + 1) * sr) / bps).floor set_mix_position(id, if (samp - lower) < (higher - samp) [0, lower].max else higher end) true end end # # === Mix Property === # def mix_click_sets_amp(id) unless mix_property(:zero, id) set_mix_property(:amp, id, mix_amp(id)) set_mix_amp(id, 0.0) set_mix_property(:zero, id, true) else set_mix_amp(id, mix_property(:amp, id)) set_mix_property(:zero, id, false) end true end # $mix_click_hook.add_hook!("mix-click-sets-amp", # &method(:mix_click_sets_amp).to_proc) # # === Mix Click Info === # add_help(:mix_click_info, "mix_click_info(n) \ Is a $mix_click_hook function that describes a mix and its properties.") def mix_click_info(id) Snd.raise(:no_such_mix, id) unless mix?(id) mnamestr = "" mname = mix_name(id) if mname mnamestr = format("\n mix name: %p", mname) end msr = srate(mix_home(id)[0]).to_f propstr = "" props = mix_properties(id) if props propstr = format("\n properties: %p", props) end mpos = mix_position(id) mlen = mix_length(id) info_dialog("Mix Info", format("\ mix id: %s%s position: %d (%1.3f secs) length: %d (%1.3f secs) in: %s[%d] scaler: %s speed: %s env: %s%s", id, mnamestr, mpos, mpos / msr, mlen, mlen / msr, short_file_name(mix_home(id)[0]), mix_home(id)[1], mix_amp(id), mix_speed(id), mix_amp_env(id), propstr)) true end # $mix_click_hook.add_hook!("mix-click-info", # &method(:mix_click_info).to_proc) add_help(:mix_name2id, "mix_name2id(name) \ Returns the mix id associated with NAME.") def mix_name2id(name) ret = :no_such_mix Snd.sounds.each do |snd| channels(snd).times do |chn| mixes(snd, chn).each do |m| if mix_name(m) == name ret = m break end end end end ret end # ;;; ---------------- backwards compatibilty def delete_mix(id) set_mix_amp(id, 0.0) end # ;;; -------- mix lists (used to be "tracks") def scale_mixes(mix_list, scl) as_one_edit_rb(get_func_name) do mix_list.each do |m| set_mix_amp(m, scl * mix_amp(m)) end end end def silence_mixes(mix_list) scale_mixes(mix_list, 0.0) end def move_mixes(mix_list, samps) as_one_edit_rb(get_func_name) do mix_list.each do |m| set_mix_position(m, mix_position(m) + samps) end end end def src_mixes(mix_list, sr) as_one_edit_rb(get_func_name) do mix_list.each do |m| set_mix_speed(m, mix_speed(m) * sr) end end end add_help(:transpose_track, "transpose_mixes(mix_list, semitones) \ Transposes each mix in MIX_LIST by SEMITONES.") def transpose_mixes(mix_list, semitones) src_mixes(mix_list, 2.0 ** (semitones / 12.0)) end def color_mixes(mix_list, col) mix_list.each do |m| set_mix_color(m, col) end end def set_mixes_tag_y(mix_list, new_y) mix_list.each do |m| set_mix_tag_y(m, new_y) end end def mixes_maxamp(mix_list) mx = 0.0 mix_list.each do |m| mx = [mx, mix_maxamp(m)].max end mx end def scale_tempo(mix_list, tempo_scl) first_beg = last_beg = mix_position(mix_list.car) mix_list.cdr.each do |m| pos = mix_position(m) first_beg = [first_beg, pos].min last_beg = [last_beg, pos].max end tempo_scl = tempo_scl.to_f as_one_edit_rb(get_func_name) do mix_list.each do |m| diff = (tempo_scl * (mix_position(m) - first_beg)).round if diff != 0 set_mix_position(m, first_beg + diff) end end end end # reverse_mix_list is scale_tempo(mix_list, -1.0) def mixes_length(mix_list) max_len = mix_list.map do |m| mix_position(m) + mix_length(m) end.max min_len = mix_list.map do |m| mix_position(m) end.min max_len - min_len + 1 end end include Mix # mix.rb ends here snd-16.1/write.scm0000644000076400007640000003221512534352107012176 0ustar bilbil(provide 'write.scm) ;;; -------------------------------- pretty-print -------------------------------- (define pretty-print (let ((*pretty-print-length* 100) (*pretty-print-spacing* 2) (*pretty-print-float-format* "~,4F")) (lambda* (obj (port (current-output-port)) (column 0)) (define (pretty-print-1 obj port column) (define (spaces n) (write-char #\newline port) (do ((i 0 (+ i 1))) ((= i n)) (write-char #\space port))) (define (stacked-list lst col) (do ((l1 lst (cdr l1))) ((not (pair? l1))) (let ((added 0)) (if (not (eq? l1 lst)) (spaces col)) (let* ((str (object->string (car l1))) (len (length str))) (if (and (keyword? (car l1)) (pair? (cdr l1))) (begin (write (car l1) port) (write-char #\space port) (set! added (+ 1 len)) (set! l1 (cdr l1)))) (if (pair? l1) (if (and (pair? (car l1)) (pair? (cdar l1)) (null? (cddar l1)) (> len (/ *pretty-print-length* 2))) (begin (write-char #\( port) (pretty-print-1 (caar l1) port col) (spaces (+ col 1)) (pretty-print-1 (cadar l1) port (+ col 1)) (write-char #\) port)) (pretty-print-1 (car l1) port (+ col added))) (format port " . ~S" l1))) (set! added 0)))) (define (stacked-split-list lst col) (if (pair? lst) (do ((l1 lst (cdr l1))) ((not (pair? l1))) (if (not (eq? l1 lst)) (spaces col)) (write-char #\( port) (if (pair? (car l1)) (begin (write (caar l1) port) (write-char #\space port) (if (and (pair? (cdar l1)) (symbol? (caar l1))) (pretty-print-1 (cadar l1) port (+ col (length (symbol->string (caar l1))) 2)) (write (cdar l1) port))) (write (car l1) port)) (write-char #\) port)) (write lst port))) (define (messy-number z) (if (real? z) (if (or (nan? z) (infinite? z)) (object->string z) (if (= z pi) "pi" (format #f *pretty-print-float-format* z))) (format "~A~A~Ai" (messy-number (real-part z)) (if (negative? (imag-part z)) "-" "+") (messy-number (abs (imag-part z)))))) (define (any-keyword? lst) (and (pair? lst) (or (keyword? (car lst)) (any-keyword? (cdr lst))))) (cond ((number? obj) (if (rational? obj) (write obj port) (display (messy-number obj) port))) ((pair? obj) (let ((cobj (if (symbol? (car obj)) (string->symbol (symbol->string (car obj))) (car obj)))) ; this clears out some optimization confusion (case cobj ((lambda lambda* define* define-macro define-macro* define-bacro define-bacro* with-let when unless call-with-input-string call-with-input-file call-with-output-file with-input-from-file with-input-from-string with-output-to-file) (if (or (not (pair? (cdr obj))) ; (when) or (when . #t) (not (pair? (cddr obj)))) (write obj port) (begin (format port "(~A ~A" (car obj) (cadr obj)) (spaces (+ column *pretty-print-spacing*)) (stacked-list (cddr obj) (+ column *pretty-print-spacing*)) (write-char #\) port)))) ((defmacro defmacro*) (if (or (not (pair? (cdr obj))) (not (pair? (cddr obj)))) (write obj port) (begin (format port "(~A ~A ~A" (car obj) (cadr obj) (caddr obj)) (spaces (+ column *pretty-print-spacing*)) (stacked-list (cdddr obj) (+ column *pretty-print-spacing*)) (write-char #\) port)))) ((define) (if (not (pair? (cdr obj))) (write obj port) (begin (format port "(~A ~A " (car obj) (cadr obj)) (if (pair? (cadr obj)) (begin (spaces (+ column *pretty-print-spacing*)) (stacked-list (cddr obj) (+ column *pretty-print-spacing*))) (begin (if (pair? (cddr obj)) (let ((str (object->string (caddr obj)))) (if (> (length str) 60) (begin (spaces (+ column *pretty-print-spacing*)) (pretty-print-1 (caddr obj) port (+ column *pretty-print-spacing*))) (write (caddr obj) port))) (write (cddr obj) port)))) (write-char #\) port)))) ((do) (if (not (pair? (cdr obj))) (write obj port) (begin (format port "(do (") (if (pair? (cadr obj)) (stacked-list (cadr obj) (+ column 5))) (write-char #\) port) (if (pair? (cddr obj)) (let ((end (caddr obj))) (spaces (+ column 4)) (if (< (length (object->string end)) (- *pretty-print-length* column)) (write end port) (begin (write-char #\( port) (pretty-print-1 (car end) port (+ column 4)) (spaces (+ column 5)) (stacked-list (cdr end) (+ column 5)) (write-char #\) port))) (spaces (+ column *pretty-print-spacing*)) (stacked-list (cdddr obj) (+ column *pretty-print-spacing*)) (write-char #\) port)) (write-char #\) port))))) ((cond) (format port "(cond ") (stacked-list (cdr obj) (+ column 6)) (write-char #\) port)) ((or and) (if (> (length (object->string obj)) 40) (begin (format port "(~A " (car obj)) (stacked-list (cdr obj) (+ column *pretty-print-spacing* (length (symbol->string (car obj))))) (write-char #\) port)) (write obj port))) ((case) (if (not (pair? (cdr obj))) (write obj port) (begin (format port "(case ~A" (cadr obj)) ; send out the selector (do ((lst (cddr obj) (cdr lst))) ((not (pair? lst))) (spaces (+ column *pretty-print-spacing*)) (if (not (pair? (car lst))) (write (car lst) port) (begin (write-char #\( port) (if (not (pair? (caar lst))) (write (caar lst) port) (let ((len (length (caar lst)))) (if (< len 6) (write (caar lst) port) (let ((p (caar lst))) (write-char #\( port) (do ((i 0 (+ i 6))) ((>= i len)) (do ((j 0 (+ j 1))) ((or (= j 6) (null? p)) (if (pair? p) (spaces (+ column 4)))) (write (car p) port) (set! p (cdr p)) (if (pair? p) (write-char #\space port)))) (write-char #\) port))))) (if (and (pair? (cdar lst)) (null? (cddar lst)) (< (length (object->string (cadar lst))) 60)) (begin (write-char #\space port) (write (cadar lst) port)) (begin (spaces (+ column 3)) (stacked-list (cdar lst) (+ column 3)))) (write-char #\) port)))) (write-char #\) port)))) ((begin call-with-exit call/cc call-with-current-continuation with-baffle with-output-to-string call-with-output-string map for-each) (format port "(~A" (car obj)) (if (pair? (cdr obj)) (begin (spaces (+ column *pretty-print-spacing*)) (stacked-list (cdr obj) (+ column *pretty-print-spacing*)))) (write-char #\) port)) ((dynamic-wind) (format port "(dynamic-wind") (spaces (+ column *pretty-print-spacing*)) (stacked-list (cdr obj) (+ column *pretty-print-spacing*)) (write-char #\) port)) ((if) (let ((objstr (object->string obj)) (ifcol (+ column 4))) (if (< (length objstr) 40) (display objstr port) (begin (format port "(if ") (pretty-print-1 (cadr obj) port ifcol) (spaces (+ column 4)) (pretty-print-1 (caddr obj) port ifcol) (if (pair? (cdddr obj)) (begin (spaces (+ column 4)) (pretty-print-1 (cadddr obj) port ifcol))) (write-char #\) port))))) ((let let* letrec letrec*) (if (or (not (pair? (cdr obj))) (not (pair? (cddr obj)))) (write obj port) (let ((head-len (length (symbol->string (car obj))))) (if (symbol? (cadr obj)) (begin (format port "(~A ~A (" (car obj) (cadr obj)) (if (pair? (cddr obj)) (if (pair? (caddr obj)) ; (let x () ...) (stacked-split-list (caddr obj) (+ column head-len (length (symbol->string (cadr obj))) 4)) (write (caddr obj) port)) (if (not (null? (cddr obj))) (format port " . ~S" (cddr obj))))) (begin (format port "(~A (" (car obj)) (if (pair? (cadr obj)) (stacked-split-list (cadr obj) (+ column head-len 3))))) (write-char #\) port) (spaces (+ column *pretty-print-spacing*)) (if (pair? ((if (symbol? (cadr obj)) cdddr cddr) obj)) (stacked-list ((if (symbol? (cadr obj)) cdddr cddr) obj) (+ column *pretty-print-spacing*))) (write-char #\) port)))) ((inlet) (format port "(inlet") (if (pair? (cdr obj)) (do ((lst (cdr obj) (cddr lst))) ((or (not (pair? lst)) (not (pair? (cdr lst))))) (spaces (+ column *pretty-print-spacing*)) (if (pair? (cdr lst)) (begin (write (car lst) port) (write-char #\space port) (pretty-print-1 (cadr lst) port (+ column *pretty-print-spacing* (length (object->string (car lst)))))) (write lst port)))) (write-char #\) port)) ((set!) (let ((str (object->string obj))) (if (> (length str) 60) (let ((settee (object->string (cadr obj)))) (format port "(set! ~A" settee) (if (> (length settee) 20) (begin (spaces (+ column 6)) (pretty-print-1 (caddr obj) port (+ column 6))) (begin (write-char #\space port) (pretty-print-1 (caddr obj) port (+ column 7 (length settee))))) (write-char #\) port)) (display str port)))) ((quote) (if (not (pair? (cdr obj))) ; (quote) or (quote . 1) (write obj port) (begin (write-char #\' port) (pretty-print-1 (cadr obj) port column)))) (else (let* ((objstr (object->string obj)) (strlen (length objstr))) (if (< (+ column strlen) *pretty-print-length*) (display objstr port) (let ((lstlen (length obj))) (if (or (infinite? lstlen) (< lstlen 2)) (display objstr port) (if (and (pair? (car obj)) (member (caar obj) '(lambda lambda*) eq?)) (begin (write-char #\( port) (pretty-print-1 (car obj) port column) (spaces (+ column 1)) (display (cadr obj) port) (write-char #\) port)) (let* ((carstr (object->string (car obj))) (carstrlen (length carstr))) (if (eq? (car obj) 'quote) (write-char #\' port) (format port "(~A" carstr)) (if (any-keyword? (cdr obj)) (begin (spaces (+ column *pretty-print-spacing*)) (stacked-list (cdr obj) (+ column *pretty-print-spacing*))) (let ((line-len (ceiling (/ (- strlen carstrlen) 40))) (line-start (+ column *pretty-print-spacing* carstrlen))) (if (= lstlen 2) (begin (write-char #\space port) (pretty-print-1 (cadr obj) port line-start)) (if (< lstlen 5) (begin (write-char #\space port) (stacked-list (cdr obj) line-start)) (let ((lst (cdr obj))) (do ((i 1 (+ i line-len))) ((>= i lstlen)) (do ((k 0 (+ k 1))) ((or (null? lst) (= k line-len))) (let ((str (format #f "~S" (car lst)))) (if (> (length str) (- *pretty-print-length* line-start)) (begin (if (not (zero? k)) (spaces line-start)) (pretty-print-1 (car lst) port line-start)) (begin (if (or (not (zero? k)) (= i 1)) (write-char #\space port)) (display str port)))) (set! lst (cdr lst))) (if (pair? lst) (spaces line-start)))))))) (if (not (eq? (car obj) 'quote)) (write-char #\) port)))))))))))) (else (write obj port)))) (let ((old-port port)) (if (boolean? old-port) (set! port (open-output-string))) (pretty-print-1 obj port column) (flush-output-port port) (if (boolean? old-port) (let ((str (get-output-string port))) (close-output-port port) (if (eq? old-port #t) (display str)) str) (values)))))) (define (pp obj) (call-with-output-string (lambda (p) (pretty-print obj p)))) #| (define (pretty-print-all) (let ((st (symbol-table))) (for-each (lambda (sym) (if (defined? sym) (let ((val (symbol->value sym))) (let ((source (and (procedure? val) (procedure-source val)))) (if (pair? source) (format *stderr* "~ ~:~%~<(pp source)~>~%~%")))))) st))) (define-macro (fully-macroexpand form) (define (expand form) ;; walk form looking for macros, expand any that are found -- see stuff.scm for a newer version (if (pair? form) (if (and (symbol? (car form)) (macro? (symbol->value (car form)))) (expand ((eval (procedure-source (symbol->value (car form)))) form)) (cons (expand (car form)) (expand (cdr form)))) form)) `(pretty-print ',(expand form))) (define* (pp-sequence seq) (let ((iter (make-iterator seq)) (strs ()) (plen (*s7* 'print-length))) (do ((i 0 (+ i 1)) (entry (iterate iter) (iterate iter))) ((or (= i plen) (eof-object? entry)) (if (not (eof-object? entry)) (apply string-append (append (reverse! strs) (list "..."))) (apply string-append (reverse! strs)))) (set! strs (cons (format #f "~S " entry) strs))))) |# snd-16.1/dsp.scm0000644000076400007640000030144412625163701011636 0ustar bilbil;;; a DSP-related grabbag (provide 'snd-dsp.scm) (if (provided? 'snd) (require snd-ws.scm) (require sndlib-ws.scm)) (require snd-env.scm) (when (provided? 'pure-s7) (define (make-polar mag ang) (if (and (real? mag) (real? ang)) (complex (* mag (cos ang)) (* mag (sin ang))) (error 'wrong-type-arg "make-polar args should be real")))) (define binomial (let ((documentation "(binomial n k) computes the binomial coefficient C(N,K)")) (lambda (n k) (let ((mn (min k (- n k)))) (if (< mn 0) 0 (if (= mn 0) 1 (let* ((mx (max k (- n k))) (cnk (+ 1 mx))) (do ((i 2 (+ 1 i))) ((> i mn) cnk) (set! cnk (/ (* cnk (+ mx i)) i)))))))))) (define log10 (let ((documentation "(log10 a) returns the log base 10 of 'a'")) (lambda (a) (log a 10)))) ;;; src-duration (see src-channel in extsnd.html) (define src-duration (let ((documentation "(src-duration envelope) returns the new duration of a sound after using 'envelope' for time-varying sampling-rate conversion")) (lambda (e) (let* ((len (length e)) (ex0 (e 0)) (ex1 (e (- len 2))) (all-x (- ex1 ex0)) (dur 0.0)) (do ((i 0 (+ i 2))) ((>= i (- len 2)) dur) (let* ((x0 (e i)) (x1 (e (+ i 2))) (y0 (e (+ i 1))) ; 1/x x points (y1 (e (+ i 3))) (area (if (< (abs (- y0 y1)) .0001) (/ (- x1 x0) (* y0 all-x)) (* (/ (- (log y1) (log y0)) (- y1 y0)) ; or (/ (log (/ y1 y0)) (- y1 y0)) (/ (- x1 x0) all-x))))) (set! dur (+ dur (abs area))))))))) ;;; :(src-duration '(0 1 1 2)) ;;; 0.69314718055995 ;;; :(src-duration #(0 1 1 2)) ;;; 0.69314718055995 (define (src-fit-envelope e target-dur) (scale-envelope e (/ (src-duration e) target-dur))) ; scale-envelope is in env.scm ;;; -------- Dolph-Chebyshev window ;;; ;;; formula taken from Richard Lyons, "Understanding DSP" ;;; see clm.c for C version (using either GSL's or GCC's complex trig functions) (define dolph (let ((documentation "(dolph n gamma) produces a Dolph-Chebyshev FFT data window of 'n' points using 'gamma' as the window parameter.")) (lambda (N gamma) (let* ((alpha (cosh (/ (acosh (expt 10.0 gamma)) N))) (den (/ 1.0 (cosh (* N (acosh alpha))))) (freq (/ pi N)) (rl (make-float-vector N)) (im (make-float-vector N))) (do ((i 0 (+ i 1)) (phase 0.0 (+ phase freq))) ((= i N)) (let ((val (* den (cos (* N (acos (* alpha (cos phase)))))))) (set! (rl i) (real-part val)) (set! (im i) (imag-part val)))) ;this is always essentially 0.0 (fft rl im -1) ;direction could also be 1 (let ((pk (float-vector-peak rl))) (float-vector-scale! rl (/ 1.0 pk))) (do ((i 0 (+ i 1)) (j (/ N 2))) ((= i N)) (set! (im i) (rl j)) (set! j (+ j 1)) (if (= j N) (set! j 0))) im)))) ;;; this version taken from Julius Smith's "Spectral Audio..." with three changes ;;; it does the DFT by hand, and is independent of anything from Snd (fft, float-vectors etc) (define dolph-1 (let ((documentation "(dolph-1 n gamma) produces a Dolph-Chebyshev FFT data window of 'n' points using 'gamma' as the window parameter.")) (lambda (N gamma) (let* ((alpha (cosh (/ (acosh (expt 10.0 gamma)) N))) (den (/ 1.0 (cosh (* N (acosh alpha))))) (freq (/ pi N)) (vals (make-vector N)) (w (make-vector N)) (pk 0.0) (mult -1)) (do ((i 0 (+ i 1)) (phase (* -0.5 pi) (+ phase freq))) ((= i N)) (set! (vals i) (* mult den (cos (* N (acos (* alpha (cos phase))))))) (set! mult (- mult))) ;; now take the DFT (do ((i 0 (+ i 1))) ((= i N)) (let ((sum 0.0)) (do ((k 0 (+ k 1))) ((= k N)) (set! sum (+ sum (* (vals k) (exp (/ (* 2.0 0+1.0i pi k i) N)))))) (set! (w i) (magnitude sum)) (if (> (w i) pk) (set! pk (w i))))) ;; scale to 1.0 (it's usually pretty close already, that is pk is close to 1.0) (do ((i 0 (+ i 1))) ((= i N)) (set! (w i) (/ (w i) pk))) w)))) ;;; -------- move sound down by n (a power of 2) (define down-oct (let ((documentation "(down-n n) moves a sound down by n-1 octaves")) (lambda* (n snd chn) ;; I think this is "stretch" in DSP jargon -- to interpolate in the time domain we're squeezing the frequency domain ;; the power-of-2 limitation is based on the underlying fft function's insistence on power-of-2 data sizes ;; see stretch-sound-via-dft below for a general version (let* ((len (framples snd chn)) (pow2 (ceiling (log len 2))) (fftlen (floor (expt 2 pow2))) (fftlen2 (/ fftlen 2)) (fft-1 (- (* n fftlen) 1)) (fftscale (/ 1.0 fftlen)) (rl1 (channel->float-vector 0 fftlen snd chn)) (im1 (make-float-vector fftlen))) (fft rl1 im1 1) (float-vector-scale! rl1 fftscale) (float-vector-scale! im1 fftscale) (let ((rl2 (make-float-vector (* n fftlen))) (im2 (make-float-vector (* n fftlen)))) (copy rl1 rl2 0 fftlen2) (copy im1 im2 0 fftlen2) (do ((k (- fftlen 1) (- k 1)) (j fft-1 (- j 1))) ((= k fftlen2)) (float-vector-set! rl2 j (float-vector-ref rl1 k)) (float-vector-set! im2 j (float-vector-ref im1 k))) (fft rl2 im2 -1) (float-vector->channel rl2 0 (* n len) snd chn #f (format #f "down-oct ~A" n))))))) (define stretch-sound-via-dft (let ((documentation "(stretch-sound-via-dft factor snd chn) makes the given channel longer ('factor' should be > 1.0) by \ squeezing in the frequency domain, then using the inverse DFT to get the time domain result.")) (lambda* (factor snd chn) ;; this is very slow! factor>1.0 (let* ((n (framples snd chn)) (n2 (floor (/ n 2.0))) (out-n (round (* n factor))) (in-data (channel->float-vector 0 n snd chn)) (out-data (make-float-vector out-n)) (fr (make-vector out-n 0.0)) (freq (/ (* 2 pi) n))) (do ((i 0 (+ i 1))) ((= i n)) ;; DFT + split (if (< i n2) (set! (fr i) (edot-product (* freq 0.0-1.0i i) in-data)) (set! (fr (+ i (- out-n n 1))) (edot-product (* freq 0.0-1.0i i) in-data)))) (set! freq (/ (* 2 pi) out-n)) (do ((i 0 (+ i 1))) ((= i out-n)) ;; inverse DFT (set! (out-data i) (real-part (/ (edot-product (* freq 0.0+1.0i i) fr) n)))) (float-vector->channel out-data 0 out-n snd chn #f (format #f "stretch-sound-via-dft ~A" factor)))))) ;;; -------- compute-uniform-circular-string ;;; ;;; this is a simplification of the underlying table-filling routine for "scanned synthesis". ;;; To watch the wave, open some sound (so Snd has some place to put the graph), turn off ;;; the time domain display (to give our graph all the window -- to do this in a much more ;;; elegant manner, see snd-motif.scm under scanned-synthesis). #| (define old-compute-uniform-circular-string (lambda (size x0 x1 x2 mass xspring damp) (define circle-ref (lambda (v i) (if (< i 0) (v (+ size i)) (if (>= i size) (v (- i size)) (v i))))) (let* ((dm (/ damp mass)) (km (/ xspring mass)) (denom (+ 1.0 dm)) (p1 (/ (+ 2.0 (- dm (* 2.0 km))) denom)) (p2 (/ km denom)) (p3 (/ -1.0 denom))) (do ((i 0 (+ i 1))) ((= i size)) (set! (x0 i) (+ (* p1 (x1 i)) (* p2 (+ (circle-ref x1 (- i 1)) (circle-ref x1 (+ i 1)))) (* p3 (x2 i))))) (copy x1 x2) (copy x0 x1)))) ;;; (compute-uniform-circular-string 100 (make-float-vector 100) (make-float-vector 100) (make-float-vector 100) .5 .5 .5) |# (define (compute-uniform-circular-string size x0 x1 x2 mass xspring damp) (let* ((dm (/ damp mass)) (km (/ xspring mass)) (denom (+ 1.0 dm)) (p2 (/ km denom)) (s1 (- size 1))) (float-vector-scale! x2 (/ -1.0 denom)) (copy x1 x0) (float-vector-scale! x0 (/ (+ 2.0 (- dm (* 2.0 km))) denom)) (float-vector-add! x0 x2) (set! (x0 0) (+ (x0 0) (* p2 (+ (x1 s1) (x1 1))))) (do ((i 1 (+ i 1))) ((= i s1)) (float-vector-set! x0 i (+ (float-vector-ref x0 i) (* p2 (+ (float-vector-ref x1 (- i 1)) (float-vector-ref x1 (+ i 1))))))) (set! (x0 s1) (+ (x0 s1) (* p2 (+ (x1 (- s1 1)) (x1 0))))) (copy x1 x2) (copy x0 x1))) (define (compute-string size x0 x1 x2 masses xsprings esprings damps haptics) ;; this is the more general form (do ((i 0 (+ i 1))) ((= i size)) (let ((mass (masses i))) (let ((dm (/ (damps i) mass)) (km (/ (xsprings i) mass)) (cm (/ (esprings i) mass))) (let ((denom (+ 1.0 dm cm))) (let ((p1 (/ (+ 2.0 (- dm (* 2.0 km))) denom)) (p2 (/ km denom)) (p3 (/ -1.0 denom)) (p4 (/ (haptics i) (* mass denom))) (j (if (= i 0) size (- i 1))) (k (if (= i (- size 1)) 0 (+ i 1)))) (set! (x0 i) (+ (* p1 (x1 i)) (* p2 (+ (x1 j) (x1 k))) (* p3 (x2 i)) p4))))))) (copy x1 x2) (copy x0 x1)) ;;; -------- "frequency division" -- an effect from sed_sed@my-dejanews.com (define freqdiv (let ((documentation "(freqdiv n snd chn) repeats each nth sample n times (clobbering the intermediate samples): (freqdiv 8)")) (lambda* (n snd chn) (let* ((data (channel->float-vector 0 #f snd chn)) (len (length data))) (if (> n 1) (do ((i 0 (+ i n))) ((>= i len) (float-vector->channel data 0 len snd chn)) (let ((val (data i)) (stop (min len (+ i n)))) (do ((k (+ i 1) (+ k 1))) ((= k stop)) (float-vector-set! data k val))))))))) ;;; -------- "adaptive saturation" -- an effect from sed_sed@my-dejanews.com ;;; ;;; a more extreme effect is "saturation": ;;; (map-channel (lambda (val) (if (< (abs val) .1) val (if (>= val 0.0) 0.25 -0.25)))) (define adsat (let ((documentation "(adsat size beg dur snd chn) is an 'adaptive saturation' sound effect")) (lambda* (size (beg 0) dur snd chn) (let* ((len (if (number? dur) dur (- (framples snd chn) beg))) (data (make-float-vector (* size (ceiling (/ len size)))))) (let ((reader (make-sampler beg snd chn)) (mn 0.0) (mx 0.0) (vals (make-float-vector size))) (do ((i 0 (+ i size))) ((>= i len)) (do ((k 0 (+ k 1))) ((= k size)) (float-vector-set! vals k (next-sample reader))) (set! mn (float-vector-min vals)) (set! mx (float-vector-max vals)) (do ((k 0 (+ k 1))) ((= k size)) (if (negative? (float-vector-ref vals k)) (float-vector-set! data (+ i k) mn) (float-vector-set! data (+ i k) mx)))) (float-vector->channel data beg len snd chn current-edit-position (format #f "adsat ~A ~A ~A" size beg dur))))))) ;;; -------- spike ;;; ;;; makes sound more spikey -- sometimes a nice effect #| (define spike (let ((documentation "(spike snd chn) multiplies successive samples together to make a sound more spikey")) (lambda* (snd chn) (let* ((len (framples snd chn)) (data (make-float-vector len)) (amp (maxamp snd chn))) ; keep resultant peak at maxamp (let ((reader (make-sampler 0 snd chn)) (x1 0.0) (x2 0.0) (amp1 (/ 1.0 (* amp amp)))) (do ((i 0 (+ i 1))) ((= i len)) (let ((x0 (next-sample reader))) (float-vector-set! data i (* x0 x1 x2)) (set! x2 x1) (set! x1 (abs x0)))) (float-vector->channel (float-vector-scale! data amp1) 0 len snd chn current-edit-position "spike")))))) |# (define spike (let ((documentation "(spike snd chn) multiplies successive samples together to make a sound more spikey")) (lambda* (snd chn) (let* ((len (framples snd chn)) (data (channel->float-vector 0 (+ len 2) snd chn)) (amp (maxamp snd chn))) ; keep resultant peak at maxamp ;; multiply x[0]*x[1]*x[2] (let ((data1 (make-float-vector (+ len 1)))) (copy data data1 1) (float-vector-abs! (float-vector-multiply! data1 data)) (float-vector-multiply! data (make-shared-vector data1 (list len) 1)) (let ((amp1 (/ amp (float-vector-peak data)))) (float-vector->channel (float-vector-scale! data amp1) 0 len snd chn current-edit-position "spike"))))))) ;;; the more successive samples we include in the product, the more we ;;; limit the output to pulses placed at (just after) wave peaks ;;; -------- easily-fooled autocorrelation-based pitch tracker (define spot-freq (let ((documentation "(spot-freq samp snd chn) tries to determine the current pitch: (spot-freq (left-sample))")) (lambda* (s0 snd chn) (let* ((pow2 (ceiling (log (/ (srate snd) 20.0) 2))) (fftlen (floor (expt 2 pow2))) (data (autocorrelate (channel->float-vector s0 fftlen snd chn))) (cor-peak (float-vector-peak data))) (if (= cor-peak 0.0) 0.0 (call-with-exit (lambda (return) (do ((i 1 (+ i 1))) ((= i (- fftlen 2)) 0) (if (and (< (data i) (data (+ i 1))) (> (data (+ i 1)) (data (+ i 2)))) (let* ((logla (log10 (/ (+ cor-peak (data i)) (* 2 cor-peak)))) (logca (log10 (/ (+ cor-peak (data (+ i 1))) (* 2 cor-peak)))) (logra (log10 (/ (+ cor-peak (data (+ i 2))) (* 2 cor-peak)))) (offset (/ (* 0.5 (- logla logra)) (+ logla logra (* -2.0 logca))))) (return (/ (srate snd) (* 2 (+ i 1 offset)))))))))))))) ;(hook-push graph-hook ; (lambda (hook) ; (status-report (format #f "~A" (spot-freq (left-sample)))))) ;;; -------- chorus (doesn't always work and needs speedup) (define chorus-size 5) (define chorus-time .05) (define chorus-amount 20.0) (define chorus-speed 10.0) (define chorus (let ((documentation "(chorus) tries to produce the chorus sound effect")) (lambda () (define (make-flanger) (let* ((ri (make-rand-interp :frequency chorus-speed :amplitude chorus-amount)) (len (floor (random (* 3.0 chorus-time (srate))))) (gen (make-delay len :max-size (+ len chorus-amount 1)))) (list gen ri))) (define (flanger dly inval) (+ inval (delay (car dly) inval (rand-interp (cadr dly))))) (let ((dlys (make-vector chorus-size))) (do ((i 0 (+ i 1))) ((= i chorus-size)) (set! (dlys i) (make-flanger))) (lambda (inval) (do ((sum 0.0) (i 0 (+ i 1))) ((= i chorus-size) (* .25 sum)) (set! sum (+ sum (flanger (dlys i) inval))))))))) ;;; -------- chordalize (comb filters to make a chord using chordalize-amount and chordalize-base) (define chordalize-amount .95) (define chordalize-base 100) (define chordalize-chord '(1 3/4 5/4)) (define chordalize (let ((documentation "(chordalize) uses harmonically-related comb-filters to bring out a chord in a sound")) (lambda () ;; chord is a list of members of chord such as '(1 5/4 3/2) (let ((combs (make-comb-bank (apply vector (map (lambda (interval) (make-comb chordalize-amount (floor (* chordalize-base interval)))) chordalize-chord)))) (scaler (/ 0.5 (length chordalize-chord)))) ; just a guess -- maybe this should rescale to old maxamp (lambda (x) (* scaler (comb-bank combs x))))))) ;;; -------- zero-phase, rotate-phase ;;; fft games (from the "phazor" package of Scott McNab) (define zero-phase (let ((documentation "(zero-phase snd chn) calls fft, sets all phases to 0, and un-ffts")) (lambda* (snd chn) (let* ((len (framples snd chn)) (pow2 (ceiling (log len 2))) (fftlen (floor (expt 2 pow2))) (fftscale (/ 1.0 fftlen)) (rl (channel->float-vector 0 fftlen snd chn)) (old-pk (float-vector-peak rl)) (im (make-float-vector fftlen))) (if (> old-pk 0.0) (begin (fft rl im 1) (rectangular->magnitudes rl im) (float-vector-scale! rl fftscale) (float-vector-scale! im 0.0) (fft rl im -1) (let ((pk (float-vector-peak rl))) (float-vector->channel (float-vector-scale! rl (/ old-pk pk)) 0 len snd chn #f "zero-phase")))))))) (define rotate-phase (let ((documentation "(rotate-phase func snd chn) calls fft, applies func to each phase, then un-ffts")) (lambda* (func snd chn) (let* ((len (framples snd chn)) (pow2 (ceiling (log len 2))) (fftlen (floor (expt 2 pow2))) (fftlen2 (floor (/ fftlen 2))) (fftscale (/ 1.0 fftlen)) (rl (channel->float-vector 0 fftlen snd chn)) (old-pk (float-vector-peak rl)) (im (make-float-vector fftlen))) (if (> old-pk 0.0) (begin (fft rl im 1) (rectangular->magnitudes rl im) (float-vector-scale! rl fftscale) (set! (im 0) 0.0) (do ((i 1 (+ i 1)) (j (- fftlen 1) (- j 1))) ((= i fftlen2)) ;; rotate the fft vector by func, keeping imaginary part complex conjgate of real (set! (im i) (func (im i))) (set! (im j) (- (im i)))) (polar->rectangular rl im) (fft rl im -1) (let ((pk (float-vector-peak rl))) (float-vector->channel (float-vector-scale! rl (/ old-pk pk)) 0 len snd chn #f (format #f "rotate-phase ~A" (procedure-source func)))))))))) #| (rotate-phase (lambda (x) 0.0)) is the same as (zero-phase) (rotate-phase (lambda (x) (random pi))) randomizes phases (rotate-phase (lambda (x) x)) returns original (rotate-phase (lambda (x) (- x))) reverses original (might want to write fftlen samps here) (rotate-phase (lambda (x) (* x 2))) reverb-effect (best with voice) (rotate-phase (lambda (x) (* x 12)) "bruise blood" effect |# (define (signum n) ;; in CL this returns 1.0 if n is float (if (positive? n) 1 (if (zero? n) 0 -1))) ;;; -------- brighten-slightly (define brighten-slightly (let ((documentation "(brighten-slightly amount snd chn) is a form of contrast-enhancement ('amount' between ca .1 and 1)")) (lambda* (amount snd chn) (let* ((mx (maxamp)) (brt (* 2 pi amount)) (len (framples snd chn)) (data (make-float-vector len)) (reader (make-sampler 0 snd chn))) (do ((i 0 (+ i 1))) ((= i len)) (float-vector-set! data i (sin (* (next-sample reader) brt)))) (float-vector->channel (float-vector-scale! data (/ mx (float-vector-peak data))) 0 len snd chn current-edit-position (format #f "brighten-slightly ~A" amount)))))) (define brighten-slightly-1 (let ((documentation "(brighten-slightly-1 coeffs) is a form of contrast-enhancement: (brighten-slightly-1 '(1 .5 3 1))")) (lambda (coeffs) (let ((pcoeffs (partials->polynomial coeffs)) (mx (maxamp)) (len (framples))) (let ((data (make-float-vector len)) (reader (make-sampler 0))) (do ((i 0 (+ i 1))) ((= i len)) (float-vector-set! data i (polynomial pcoeffs (next-sample reader)))) (float-vector->channel (float-vector-scale! data (/ mx (float-vector-peak data))))))))) ;;; -------- FIR filters ;;; Snd's (very simple) spectrum->coefficients procedure is: (define spectrum->coeffs (let ((documentation "(spectrum->coeffs order spectr) returns FIR filter coefficients given the filter order and desired spectral envelope (a float-vector)")) (lambda (order spectr) (let* ((coeffs (make-float-vector order)) (n order) (m (floor (/ (+ n 1) 2))) (am (* 0.5 (+ n 1))) (q (/ (* pi 2.0) n))) (if (not (float-vector? spectr)) (error "spectrum->coeffs spectrum argument should be a float-vector")) (do ((j 0 (+ j 1)) (jj (- n 1) (- jj 1))) ((= j m) coeffs) (let ((xt (* 0.5 (spectr 0)))) (do ((i 1 (+ i 1))) ((= i m)) (set! xt (+ xt (* (spectr i) (cos (* q i (- am j 1))))))) (let ((coeff (* 2.0 (/ xt n)))) (set! (coeffs j) coeff) (set! (coeffs jj) coeff)))))))) ;; (filter-channel et al reflect around the midpoint, so to match exactly you need to take ;; the env passed and flip it backwards for the back portion -- that is to say, this function ;; needs a wrapper to make it act like anyone would expect) (define fltit-1 (let ((documentation "(fltit-1 order spectrum) creates an FIR filter from spectrum and order and returns a closure that calls it: \ (map-channel (fltit-1 10 (float-vector 0 1.0 0 0 0 0 0 0 1.0 0)))")) (lambda (order spectr) (let ((flt (make-fir-filter order (spectrum->coeffs order spectr)))) (lambda (x) (fir-filter flt x)))))) ;(map-channel (fltit-1 10 (float-vector 0 1.0 0 0 0 0 0 0 1.0 0))) ; ;(let ((notched-spectr (make-float-vector 40))) ; (set! (notched-spectr 2) 1.0) ; (set! (notched-spectr 37) 1.0) ; (map-channel (fltit-1 40 notched-spectr))) ; ;;; -------- Hilbert transform (define make-hilbert-transform (let ((documentation "(make-hilbert-transform (len 30)) makes a Hilbert transform filter")) (lambda* ((len 30)) (let* ((arrlen (+ 1 (* 2 len))) (arr (make-float-vector arrlen)) (lim (if (even? len) len (+ 1 len)))) (do ((i (- len) (+ i 1))) ((= i lim)) (let ((k (+ i len)) (denom (* pi i)) (num (- 1.0 (cos (* pi i))))) (if (or (= num 0.0) (= i 0)) (set! (arr k) 0.0) ;; this is the "ideal" -- rectangular window -- version: ;; (set! (arr k) (/ num denom)) ;; this is the Hamming window version: (set! (arr k) (* (/ num denom) (+ .54 (* .46 (cos (/ (* i pi) len)))))) ; window ))) (make-fir-filter arrlen arr))))) (define hilbert-transform fir-filter) #| (let ((h (make-hilbert-transform 15))) (map-channel (lambda (y) (hilbert-transform h y)))) ;;; this comes from R Lyons: (define* (sound->amp-env snd chn) (let ((hlb (make-hilbert-transform 40)) (d (make-delay 40))) (map-channel (lambda (y) (let ((hy (hilbert-transform hlb y)) (dy (delay d y))) (sqrt (+ (* hy hy) (* dy dy))))) 0 #f snd chn #f "sound->amp-env"))) (define* (hilbert-transform-via-fft snd chn) ;; same as FIR version but use FFT and change phases by hand ;; see snd-test.scm test 18 for a faster version (let* ((size (framples snd chn)) (len (expt 2 (ceiling (log size 2.0)))) (rl (make-float-vector len)) (im (make-float-vector len)) (rd (make-sampler 0 snd chn)) (pi2 (* 0.5 pi))) (do ((i 0 (+ i 1))) ((= i size)) (set! (rl i) (rd))) (mus-fft rl im len) (do ((i 0 (+ i 1))) ((= i len)) (let* ((c (complex (rl i) (im i))) (ph (angle c)) (mag (magnitude c))) (if (< i (/ len 2)) (set! ph (+ ph pi2)) (set! ph (- ph pi2))) (set! c (make-polar mag ph)) (set! (rl i) (real-part c)) (set! (im i) (imag-part c)))) (mus-fft rl im len -1) (float-vector-scale! rl (/ 1.0 len)) (float-vector->channel rl 0 len snd chn #f "hilbert-transform-via-fft"))) |# ;;; -------- highpass filter (define make-highpass (let ((documentation "(make-highpass fc (len 30)) makes an FIR highpass filter")) (lambda* (fc (len 30)) (let* ((arrlen (+ 1 (* 2 len))) (arr (make-float-vector arrlen))) (do ((i (- len) (+ i 1))) ((= i len)) (let ((k (+ i len)) (denom (* pi i)) (num (- (sin (* fc i))))) (if (= i 0) (set! (arr k) (- 1.0 (/ fc pi))) (set! (arr k) (* (/ num denom) (+ .54 (* .46 (cos (/ (* i pi) len))))))))) (make-fir-filter arrlen arr))))) (define highpass fir-filter) #| (let ((hp (make-highpass (* .1 pi)))) (map-channel (lambda (y) (highpass hp y)))) |# ;;; -------- lowpass filter (define make-lowpass (let ((documentation "(make-lowpass fc (len 30)) makes an FIR lowpass filter")) (lambda* (fc (len 30)) (let* ((arrlen (+ 1 (* 2 len))) (arr (make-float-vector arrlen))) (do ((i (- len) (+ i 1))) ((= i len)) (let ((k (+ i len)) (denom (* pi i)) (num (sin (* fc i)))) (if (= i 0) (set! (arr k) (/ fc pi)) (set! (arr k) (* (/ num denom) (+ .54 (* .46 (cos (/ (* i pi) len))))))))) (make-fir-filter arrlen arr))))) (define lowpass fir-filter) #| (let ((hp (make-lowpass (* .2 pi)))) (map-channel (lambda (y) (lowpass hp y)))) |# ;;; -------- bandpass filter (define make-bandpass (let ((documentation "(make-bandpass flo fhi (len 30)) makes an FIR bandpass filter")) (lambda* (flo fhi (len 30)) (let* ((arrlen (+ 1 (* 2 len))) (arr (make-float-vector arrlen))) (do ((i (- len) (+ i 1))) ((= i len)) (let ((k (+ i len)) (denom (* pi i)) (num (- (sin (* fhi i)) (sin (* flo i))))) (if (= i 0) (set! (arr k) (/ (- fhi flo) pi)) (set! (arr k) (* (/ num denom) (+ .54 (* .46 (cos (/ (* i pi) len))))))))) (make-fir-filter arrlen arr))))) (define bandpass fir-filter) #| (let ((hp (make-bandpass (* .1 pi) (* .2 pi)))) (map-channel (lambda (y) (bandpass hp y)))) ;; for more bands, you can add the coeffs: (define* (make-bandpass-2 flo1 fhi1 flo2 fhi2 (len 30)) (let* ((f1 (make-bandpass flo1 fhi1 len)) (f2 (make-bandpass flo2 fhi2 len))) (float-vector-add! (mus-xcoeffs f1) (mus-xcoeffs f2)) f1)) (let ((ind (new-sound "test.snd"))) (map-channel (lambda (y) (mus-random 1.0)) 0 10000) (let ((f2 (make-bandpass-2 (* .12 pi) (* .15 pi) (* .22 pi) (* .25 pi) 100))) (map-channel (lambda (y) (fir-filter f2 y))) )) |# ;;; -------- bandstop filter (define make-bandstop (let ((documentation "(make-bandstop flo fhi (len 30)) makes an FIR bandstop (notch) filter")) (lambda* (flo fhi (len 30)) (let* ((arrlen (+ 1 (* 2 len))) (arr (make-float-vector arrlen))) (do ((i (- len) (+ i 1))) ((= i len)) (let ((k (+ i len)) (denom (* pi i)) (num (- (sin (* flo i)) (sin (* fhi i))))) (if (= i 0) (set! (arr k) (- 1.0 (/ (- fhi flo) pi))) (set! (arr k) (* (/ num denom) (+ .54 (* .46 (cos (/ (* i pi) len))))))))) (make-fir-filter arrlen arr))))) (define bandstop fir-filter) #| (let ((hp (make-bandstop (* .1 pi) (* .3 pi)))) (map-channel (lambda (y) (bandstop hp y)))) |# ;;; -------- differentiator (define make-differentiator (let ((documentation "(make-differentiator (len 30)) makes an FIR differentiator (highpass) filter")) (lambda* ((len 30)) (let* ((arrlen (+ 1 (* 2 len))) (arr (make-float-vector arrlen))) (do ((i (- len) (+ i 1))) ((= i len)) (let ((k (+ i len))) (if (= i 0) (set! (arr k) 0.0) (set! (arr k) (* (/ (cos (* pi i)) i) (+ .54 (* .46 (cos (/ (* i pi) len))))))))) (make-fir-filter arrlen arr))))) (define differentiator fir-filter) #| (let ((hp (make-differentiator))) (map-channel (lambda (y) (differentiator hp y)))) |# ;;; -------- IIR filters ;;; see analog-filter.scm for the usual suspects ;;; -------- Butterworth filters (see also further below -- make-butter-lp et al) ;;; ;; translated from CLM butterworth.cl: ;; ;; Sam Heisz, January 1998 ;; inspired by some unit generators written for Csound by Paris Smaragdis ;; who based his work on formulas from ;; Charles Dodge, Computer music: synthesis, composition, and performance. (define butter filter) (define make-butter-high-pass (let ((documentation "(make-butter-high-pass freq) makes a Butterworth filter with high pass cutoff at 'freq'")) (lambda (fq) ;; this is the same as iir-low-pass-2 below with 'din' set to (sqrt 2.0) -- similarly with the others (let* ((r (tan (/ (* pi fq) (srate)))) (r2 (* r r)) (c1 (/ 1.0 (+ 1.0 (* r (sqrt 2.0)) r2))) (c2 (* -2.0 c1)) (c3 c1) (c4 (* 2.0 (- r2 1.0) c1)) (c5 (* (+ (- 1.0 (* r (sqrt 2.0))) r2) c1))) (make-filter 3 (float-vector c1 c2 c3) (float-vector 0.0 c4 c5)))))) (define make-butter-low-pass (let ((documentation "(make-butter-low-pass freq) makes a Butterworth filter with low pass cutoff at 'freq'. The result \ can be used directly: (filter-sound (make-butter-low-pass 500.0)), or via the 'butter' generator")) (lambda (fq) (let* ((r (/ 1.0 (tan (/ (* pi fq) (srate))))) (r2 (* r r)) (c1 (/ 1.0 (+ 1.0 (* r (sqrt 2.0)) r2))) (c2 (* 2.0 c1)) (c3 c1) (c4 (* 2.0 (- 1.0 r2) c1)) (c5 (* (+ (- 1.0 (* r (sqrt 2.0))) r2) c1))) (make-filter 3 (float-vector c1 c2 c3) (float-vector 0.0 c4 c5)))))) (define make-butter-band-pass (let ((documentation "(make-butter-band-pass freq band) makes a bandpass Butterworth filter with low edge at 'freq' and width 'band'")) (lambda (fq bw) (let* ((d (* 2.0 (cos (/ (* 2.0 pi fq) (srate))))) (c (/ 1.0 (tan (/ (* pi bw) (srate))))) (c1 (/ 1.0 (+ 1.0 c))) (c2 0.0) (c3 (- c1)) (c4 (* (- c) d c1)) (c5 (* (- c 1.0) c1))) (make-filter 3 (float-vector c1 c2 c3) (float-vector 0.0 c4 c5)))))) (define make-butter-band-reject (let ((documentation "(make-butter-band-reject freq band) makes a band-reject Butterworth filter with low edge at 'freq' and width 'band'")) (lambda (fq bw) (let* ((d (* 2.0 (cos (/ (* 2.0 pi fq) (srate))))) (c (tan (/ (* pi bw) (srate)))) (c1 (/ 1.0 (+ 1.0 c))) (c2 (* (- d) c1)) (c3 c1) (c4 c2) (c5 (* (- 1.0 c) c1))) (make-filter 3 (float-vector c1 c2 c3) (float-vector 0.0 c4 c5)))))) ;;; simplest use is (filter-sound (make-butter-low-pass 500.0)) ;;; see also effects.scm ;;; from "DSP Filter Cookbook" by Lane et al, Prompt Pubs, 2001 ;;; ;;; use with the filter generator ;;; (define gen (make-iir-high-pass-2 1000)) ;;; (filter gen 1.0) ;;; etc (define make-biquad (let ((documentation "(make-biquad a0 a1 a2 b1 b2) returns a biquad filter (use with the CLM filter gen)")) (lambda (a0 a1 a2 b1 b2) (make-filter 3 (float-vector a0 a1 a2) (float-vector 0.0 b1 b2))))) (define* (make-iir-low-pass-2 fc din) ; din=(sqrt 2.0) for example (suggested range 0.2.. 10) (let* ((theta (/ (* 2 pi fc) *clm-srate*)) (d (or din (sqrt 2.0))) (beta (* 0.5 (/ (- 1.0 (* (/ d 2) (sin theta))) (+ 1.0 (* (/ d 2) (sin theta)))))) (gamma (* (+ 0.5 beta) (cos theta))) (alpha (* 0.5 (+ 0.5 beta (- gamma))))) (make-filter 3 (float-vector alpha (* 2.0 alpha) alpha) (float-vector 0.0 (* -2.0 gamma) (* 2.0 beta))))) (define* (make-iir-high-pass-2 fc din) (let* ((theta (/ (* 2 pi fc) *clm-srate*)) (d (or din (sqrt 2.0))) (beta (* 0.5 (/ (- 1.0 (* (/ d 2) (sin theta))) (+ 1.0 (* (/ d 2) (sin theta)))))) (gamma (* (+ 0.5 beta) (cos theta))) (alpha (* 0.5 (+ 0.5 beta gamma)))) (make-filter 3 (float-vector alpha (* -2.0 alpha) alpha) (float-vector 0.0 (* -2.0 gamma) (* 2.0 beta))))) (define (make-iir-band-pass-2 f1 f2) (let* ((theta (/ (* 2 pi (sqrt (* f1 f2))) *clm-srate*)) (Q (/ (sqrt (* f1 f2)) (- f2 f1))) (t2 (tan (/ theta (* 2 Q)))) (beta (* 0.5 (/ (- 1.0 t2) (+ 1.0 t2)))) (gamma (* (+ 0.5 beta) (cos theta))) (alpha (- 0.5 beta))) (make-filter 3 (float-vector alpha 0.0 (- alpha)) (float-vector 0.0 (* -2.0 gamma) (* 2.0 beta))))) (define (make-iir-band-stop-2 f1 f2) (let* ((theta (/ (* 2 pi (sqrt (* f1 f2))) *clm-srate*)) (Q (/ (sqrt (* f1 f2)) (- f2 f1))) (t2 (tan (/ theta (* 2 Q)))) (beta (* 0.5 (/ (- 1.0 t2) (+ 1.0 t2)))) (gamma (* (+ 0.5 beta) (cos theta))) (alpha (+ 0.5 beta))) (make-filter 3 (float-vector alpha (* -2.0 gamma) alpha) (float-vector 0.0 (* -2.0 gamma) (* 2.0 beta))))) #| (define* (old-make-eliminate-hum (hum-freq 60.0) (hum-harmonics 5) (bandwidth 10)) (let ((gen (make-vector hum-harmonics))) (do ((i 0 (+ i 1))) ((= i hum-harmonics)) (let ((center (* (+ i 1.0) hum-freq)) (b2 (* 0.5 bandwidth))) (set! (gen i) (make-iir-band-stop-2 (- center b2) (+ center b2))))) gen)) (define (old-eliminate-hum gen x0) (do ((i 0 (+ i 1))) ((= i (length gen)) x0) (set! x0 (filter (vector-ref gen i) x0)))) ; "cascade" n filters ;;; (let ((hummer (old-make-eliminate-hum))) (map-channel (lambda (x) (old-eliminate-hum hummer x)))) |# ;;; the new form is creating a function/closure of the form: ;;; (let ((g0 (make-iir-band-stop-2 c00 c01)) (g1 (make-iir-band-stop-2 c10 c11))) (lambda (y) (filter g1 (filter g0 y)))) (define-macro* (make-eliminate-hum (hum-freq 60.0) (hum-harmonics 5) (bandwidth 10)) `(let ((body 'y) (closure ())) (do ((i 0 (+ i 1))) ((= i ,hum-harmonics)) (let ((filt (string->symbol (format #f "g~D" i))) (center (* (+ i 1.0) ,hum-freq)) (b2 (* 0.5 ,bandwidth))) (set! body (list 'filter filt body)) (set! closure (cons (list filt (list 'make-iir-band-stop-2 (- center b2) (+ center b2))) closure)))) (apply let closure `((lambda (y) ,body))))) ;;; (map-channel (make-eliminate-hum)) (define (make-peaking-2 f1 f2 m) ;; bandpass, m is gain at center of peak ;; use map-channel with this one (not clm-channel or filter) (let* ((theta (/ (* 2 pi (sqrt (* f1 f2))) *clm-srate*)) (Q (/ (sqrt (* f1 f2)) (- f2 f1))) (t2 (* (/ 4.0 (+ m 1)) (tan (/ theta (* 2 Q))))) (beta (* 0.5 (/ (- 1.0 t2) (+ 1.0 t2)))) (gamma (* (+ 0.5 beta) (cos theta))) (alpha (- 0.5 beta)) (flt (make-filter 3 (float-vector alpha 0.0 (- alpha)) (float-vector 0.0 (* -2.0 gamma) (* 2.0 beta)))) (m1 (- m 1.0))) (lambda (x) (+ x (* m1 (filter flt x)))))) (define cascade->canonical (let ((documentation "(cascade->canonical A) converts a list of cascade coeffs (float-vectors with 3 entries) to canonical form")) ;; from Orfanidis "Introduction to Signal Processing" (lambda (A) (define (conv M h L x y) ;; x * h -> y (do ((n 0 (+ n 1))) ((= n (+ L M))) (let ((sum 0.0) (start (max 0 (- n (+ L 1)))) (end (min n M))) (do ((m start (+ m 1))) ((> m end)) (set! sum (+ sum (* (h m) (x (- n m)))))) (set! (y n) sum)))) (let* ((K (length A)) (d (make-float-vector (+ 1 (* 2 K)))) (a1 (make-float-vector (+ 1 (* 2 K))))) (set! (a1 0) 1.0) (do ((i 0 (+ i 1))) ((= i K)) (conv 2 (A i) (+ 1 (* 2 i)) a1 d) (copy d a1 0 (+ 3 (* 2 i)))) a1)))) (define make-butter-lp (let ((documentation "(make-butter-lp M fc) returns a butterworth low-pass filter; its order is 'M' * 2, 'fc' is the cutoff frequency in Hz")) (lambda (M fc) (let* ((xcoeffs ()) (ycoeffs ()) (theta (/ (* 2 pi fc) *clm-srate*)) (st (sin theta)) (ct (cos theta))) (do ((k 1 (+ k 1))) ((> k M)) (let* ((d (* 2 (sin (/ (* pi (- (* 2 k) 1)) (* 4 M))))) (beta (* 0.5 (/ (- 1.0 (* 0.5 d st)) (+ 1.0 (* 0.5 d st))))) (gamma (* ct (+ 0.5 beta))) (alpha (* 0.25 (+ 0.5 beta (- gamma))))) (set! xcoeffs (cons (float-vector (* 2 alpha) (* 4 alpha) (* 2 alpha)) xcoeffs)) (set! ycoeffs (cons (float-vector 1.0 (* -2.0 gamma) (* 2.0 beta)) ycoeffs)))) (make-filter (+ 1 (* 2 M)) (cascade->canonical xcoeffs) (cascade->canonical ycoeffs)))))) (define make-butter-hp (let ((documentation "(make-butter-hp M fc) returns a butterworth high-pass filter; its order is 'M' * 2, 'fc' is the cutoff frequency in Hz")) (lambda (M fc) (let* ((xcoeffs ()) (ycoeffs ()) (theta (/ (* 2 pi fc) *clm-srate*)) (st (sin theta)) (ct (cos theta))) (do ((k 1 (+ k 1))) ((> k M)) (let* ((d (* 2 (sin (/ (* pi (- (* 2 k) 1)) (* 4 M))))) (beta (* 0.5 (/ (- 1.0 (* 0.5 d st)) (+ 1.0 (* 0.5 d st))))) (gamma (* ct (+ 0.5 beta))) (alpha (* 0.25 (+ 0.5 beta gamma)))) (set! xcoeffs (cons (float-vector (* 2 alpha) (* -4 alpha) (* 2 alpha)) xcoeffs)) (set! ycoeffs (cons (float-vector 1.0 (* -2.0 gamma) (* 2.0 beta)) ycoeffs)))) (make-filter (+ 1 (* 2 M)) (cascade->canonical xcoeffs) (cascade->canonical ycoeffs)))))) (define make-butter-bp (let ((documentation "(make-butter-bp M f1 f2) returns a butterworth band-pass filter; its order is 'M' * 2, 'f1' and 'f2' are the band edge frequencies in Hz")) (lambda (M f1 f2) (let* ((xcoeffs ()) (ycoeffs ()) (f0 (sqrt (* f1 f2))) (Q (/ f0 (- f2 f1))) (theta0 (/ (* 2 pi f0) *clm-srate*)) (de (/ (* 2 (tan (/ theta0 (* 2 Q)))) (sin theta0))) (de2 (/ de 2)) (tn0 (tan (* theta0 0.5)))) (do ((i 1 (+ i 1)) (k 1) (j 1)) ((> i M)) (let* ((Dk (* 2 (sin (/ (* pi (- (* 2 k) 1)) (* 2 M))))) (Ak (/ (+ 1 (* de2 de2)) (* Dk de2))) (dk1 (sqrt (/ (* de Dk) (+ Ak (sqrt (- (* Ak Ak) 1)))))) (Bk (* de2 (/ Dk dk1))) (Wk (real-part (+ Bk (sqrt (- (* Bk Bk) 1.0))))) ; fp inaccuracies causing tiny (presumably bogus) imaginary part here (thetajk (if (= j 1) (* 2 (atan tn0 Wk)) (* 2 (atan (* tn0 Wk))))) (betajk (* 0.5 (/ (- 1.0 (* 0.5 dk1 (sin thetajk))) (+ 1.0 (* 0.5 dk1 (sin thetajk)))))) (gammajk (* (+ 0.5 betajk) (cos thetajk))) (wk2 (/ (- Wk (/ 1.0 Wk)) dk1)) (alphajk (* 0.5 (- 0.5 betajk) (sqrt (+ 1.0 (* wk2 wk2)))))) (set! xcoeffs (cons (float-vector (* 2 alphajk) 0.0 (* -2 alphajk)) xcoeffs)) (set! ycoeffs (cons (float-vector 1.0 (* -2.0 gammajk) (* 2.0 betajk)) ycoeffs)) (if (= j 1) (set! j 2) (begin (set! k (+ k 1)) (set! j 1))))) (make-filter (+ 1 (* 2 M)) (cascade->canonical xcoeffs) (cascade->canonical ycoeffs)))))) (define make-butter-bs (let ((documentation "(make-butter-bs M f1 f2) returns a butterworth band-stop filter; its order is 'M' * 2, 'f1' and 'f2' are the band edge frequencies in Hz")) (lambda (M f1 f2) (let* ((xcoeffs ()) (ycoeffs ()) (f0 (sqrt (* f1 f2))) (Q (/ f0 (- f2 f1))) (theta0 (/ (* 2 pi f0) *clm-srate*)) (de (/ (* 2 (tan (/ theta0 (* 2 Q)))) (sin theta0))) (de2 (/ de 2)) (ct (cos theta0)) (tn0 (tan (* theta0 0.5)))) (do ((i 1 (+ i 1)) (k 1) (j 1)) ((> i M)) (let* ((Dk (* 2 (sin (/ (* pi (- (* 2 k) 1)) (* 2 M))))) (Ak (/ (+ 1 (* de2 de2)) (* Dk de2))) (dk1 (sqrt (/ (* de Dk) (+ Ak (sqrt (- (* Ak Ak) 1)))))) (Bk (* de2 (/ Dk dk1))) (Wk (real-part (+ Bk (sqrt (- (* Bk Bk) 1.0))))) (thetajk (if (= j 1) (* 2 (atan tn0 Wk)) (* 2 (atan (* tn0 Wk))))) (betajk (* 0.5 (/ (- 1.0 (* 0.5 dk1 (sin thetajk))) (+ 1.0 (* 0.5 dk1 (sin thetajk)))))) (gammajk (* (+ 0.5 betajk) (cos thetajk))) (alphajk (* 0.5 (+ 0.5 betajk) (/ (- 1.0 (cos thetajk)) (- 1.0 ct))))) (set! xcoeffs (cons (float-vector (* 2 alphajk) (* -4 ct alphajk) (* 2 alphajk)) xcoeffs)) (set! ycoeffs (cons (float-vector 1.0 (* -2.0 gammajk) (* 2.0 betajk)) ycoeffs)) (if (= j 1) (set! j 2) (begin (set! k (+ k 1)) (set! j 1))))) (make-filter (+ 1 (* 2 M)) (cascade->canonical xcoeffs) (cascade->canonical ycoeffs)))))) ;;; -------- notch filters (define* (make-notch-frequency-response cur-srate freqs (notch-width 2)) (let ((freq-response (list 1.0 0.0))) (for-each (lambda (i) (set! freq-response (cons (/ (* 2 (- i notch-width)) cur-srate) freq-response)) ; left upper y hz (set! freq-response (cons 1.0 freq-response)) ; left upper y resp (set! freq-response (cons (/ (* 2 (- i (/ notch-width 2))) cur-srate) freq-response)) ; left bottom y hz (set! freq-response (cons 0.0 freq-response)) ; left bottom y resp (set! freq-response (cons (/ (* 2 (+ i (/ notch-width 2))) cur-srate) freq-response)) ; right bottom y hz (set! freq-response (cons 0.0 freq-response)) ; right bottom y resp (set! freq-response (cons (/ (* 2 (+ i notch-width)) cur-srate) freq-response)) ; right upper y hz (set! freq-response (cons 1.0 freq-response))) ; right upper y resp freqs) (set! freq-response (cons 1.0 (cons 1.0 freq-response))) (reverse freq-response))) (define notch-channel (let ((documentation "(notch-channel freqs filter-order beg dur snd chn edpos (truncate #t) (notch-width 2)) -> notch filter removing freqs")) (lambda* (freqs filter-order beg dur snd chn edpos (truncate #t) (notch-width 2)) (filter-channel (make-notch-frequency-response (* 1.0 (srate snd)) freqs notch-width) (or filter-order (min (framples snd chn) (expt 2 (floor (log (/ (srate snd) notch-width) 2))))) beg dur snd chn edpos truncate (format #f "notch-channel '~A ~A ~A ~A" freqs filter-order beg dur))))) (define notch-sound (let ((documentation "(notch-sound freqs filter-order snd chn (notch-width 2)) -> notch filter removing freqs")) (lambda* (freqs filter-order snd chn (notch-width 2)) (filter-sound (make-notch-frequency-response (* 1.0 (srate snd)) freqs notch-width) (or filter-order (min (framples snd chn) (expt 2 (floor (log (/ (srate snd) notch-width) 2))))) snd chn #f (format #f "notch-channel '~A ~A 0 #f" freqs filter-order))))) (define notch-selection (let ((documentation "(notch-selection freqs filter-order (notch-width 2)) -> notch filter removing freqs")) (lambda* (freqs filter-order (notch-width 2)) (if (selection?) (filter-selection (make-notch-frequency-response (* 1.0 (selection-srate)) freqs notch-width) (or filter-order (min (selection-framples) (expt 2 (floor (log (/ (selection-srate) notch-width) 2)))))))))) ;; apparently I'm using powers of 2 here so that mus_make_fir_coeffs, called from get_filter_coeffs, can use an fft ;; the others use the fft internally for the fir filter, but not filter-selection ;;; -------- fractional Fourier Transform, z transform ;;; ;;; translated from the fxt package of Joerg Arndt (define fractional-fourier-transform (let ((documentation "(fractional-fourier-transform real imaginary n angle) performs a fractional Fourier transform on data; if angle=1.0, you get a normal Fourier transform")) (lambda (fr fi n v) ;; this is the slow (dft) form ;; v=1 -> normal fourier transform (let ((hr (make-float-vector n)) (hi (make-float-vector n)) (ph0 (/ (* v 2 pi) n))) (do ((w 0 (+ 1 w))) ((= w n)) (let ((sr 0.0) (si 0.0)) (do ((k 0 (+ k 1))) ((= k n)) (let* ((phase (* ph0 k w)) (c (cos phase)) (s (sin phase)) (x (fr k)) (y (fi k)) (r (- (* x c) (* y s))) (i (+ (* y c) (* x s)))) (set! sr (+ sr r)) (set! si (+ si i)))) (set! (hr w) sr) (set! (hi w) si))) (list hr hi))))) (define z-transform (let ((documentation "(z-transform data n z) performs a Z transform on data; if z=e^2*pi*j/n you get a Fourier transform; complex results in returned vector")) (lambda (f n z) ;; using vector to allow complex sums (z=e^2*pi*i/n -> fourier transform) ;; (z-transform data n (exp (complex 0.0 (* (/ 2.0 n) pi)))) (let ((res (if (float-vector? f) (make-float-vector n) (make-vector n)))) (do ((w 0 (+ 1 w))) ((= w n)) (let ((sum 0.0) (t 1.0) (m (expt z w))) ;; -w?? there seems to be confusion here -- slowzt.cc in the fxt package uses +w (do ((k 0 (+ k 1))) ((= k n)) (set! sum (+ sum (* (f k) t))) (set! t (* t m))) (set! (res w) sum))) res)))) ;;; -------- slow Hartley transform (define dht (let ((documentation "(dht data) returns the Hartley transform of 'data'.")) (lambda (data) ;; taken from Perry Cook's SignalProcessor.m (the slow version of the Hartley transform) (let* ((len (length data)) (arr (make-float-vector len)) (w (/ (* 2.0 pi) len))) (do ((i 0 (+ i 1))) ((= i len)) (do ((j 0 (+ j 1))) ((= j len)) (set! (arr i) (+ (arr i) (* (data j) (+ (cos (* i j w)) (sin (* i j w)))))))) arr)))) (define find-sine (let ((documentation "(find-sine freq beg dur snd) returns the amplitude and initial-phase (for sin) at freq")) (lambda* (freq beg dur snd) (let ((incr (/ (* freq 2 pi) (srate snd))) (sw 0.0) (cw 0.0) (reader (make-sampler beg snd)) (samp 0.0)) (do ((i 0 (+ i 1)) ; this could also use edot-product (x 0.0 (+ x incr))) ((= i dur)) (set! samp (next-sample reader)) (set! sw (+ sw (* samp (sin x)))) (set! cw (+ cw (* samp (cos x))))) (list (* 2 (/ (sqrt (+ (* sw sw) (* cw cw))) dur)) (atan cw sw)))))) ;;; this is a faster version of find-sine using the "Goertzel algorithm" taken from R Lyons "Understanding DSP" p 529 ;;; it returns the same result as find-sine above if you take (* 2 (/ (goertzel...) dur)) -- see snd-test.scm examples (define goertzel (let ((documentation "(goertzel freq beg dur snd) returns the amplitude of the 'freq' spectral component")) (lambda* (freq (beg 0) dur snd) (let* ((sr (srate snd)) (rfreq (/ (* 2.0 pi freq) sr)) (cs (* 2.0 (cos rfreq)))) (let ((reader (make-sampler beg snd 0)) (len (- (if (number? dur) dur (- (framples snd 0) beg)) 2)) (flt (make-two-pole 1.0 (- cs) 1.0))) (do ((i 0 (+ i 1))) ((= i len)) (two-pole flt (next-sample reader))) (let ((y1 (two-pole flt (next-sample reader))) (y0 (two-pole flt (next-sample reader)))) (magnitude (- y0 (* y1 (exp (complex 0.0 (- rfreq)))))))))))) #| ;; old version: (let ((y2 0.0) (y1 0.0) (y0 0.0) (reader (make-sampler beg snd 0)) (len (if (number? dur) dur (- (framples snd 0) beg)))) (do ((i 0 (+ i 1))) ((= i len)) (set! y2 y1) (set! y1 y0) (set! y0 (+ (- (* y1 cs) y2) (next-sample reader)))) |# (define make-spencer-filter (let ((documentation "(make-spencer-filter) is a version of make-fir-filter; it returns one of the standard smoothing filters from \ the era when computers were human beings")) (lambda () (make-fir-filter 15 (apply float-vector (map (lambda (n) (/ n 320.0)) (list -3 -6 -5 3 21 46 67 74 67 46 21 3 -5 -6 -3))))))) ;;; -------- any-random ;;; ;;; arbitrary random number distributions via the "rejection method" (define* (any-random amount e) (if (= amount 0.0) 0.0 (if (not e) (random amount) (letrec ((next-random (lambda () (let* ((len (length e)) (x (random (* 1.0 (e (- len 2))))) (y (random 1.0))) (if (<= y (envelope-interp x e)) x (next-random)))))) (next-random))))) (define (gaussian-distribution s) (let ((e ()) (den (* 2.0 s s))) (do ((i 0 (+ i 1)) (x 0.0 (+ x .05)) (y -4.0 (+ y .4))) ((= i 21)) (set! e (cons (exp (- (/ (* y y) den))) (cons x e)))) (reverse e))) (define (pareto-distribution a) (let ((e ()) (scl (/ (expt 1.0 (+ a 1.0)) a))) (do ((i 0 (+ i 1)) (x 0.0 (+ x .05)) (y 1.0 (+ y .2))) ((= i 21)) (set! e (cons (* scl (/ a (expt y (+ a 1.0)))) (cons x e)))) (reverse e))) ;(map-channel (lambda (y) (any-random 1.0 '(0 1 1 1)))) ; uniform distribution ;(map-channel (lambda (y) (any-random 1.0 '(0 0 0.95 0.1 1 1)))) ; mostly toward 1.0 ;(let ((g (gaussian-distribution 1.0))) (map-channel (lambda (y) (any-random 1.0 g)))) ;(let ((g (pareto-distribution 1.0))) (map-channel (lambda (y) (any-random 1.0 g)))) ;;; this is the inverse integration function used by CLM to turn a distribution function into a weighting function (define* (inverse-integrate dist (data-size 512) (e-size 50)) (let* ((e ()) (sum (cadr dist)) (first-sum sum) (data (make-float-vector data-size)) (x0 (car dist)) (x1 (dist (- (length dist) 2))) (xincr (/ (- x1 x0) e-size))) (do ((i 0 (+ i 1)) (x x0 (+ x xincr))) ((> i e-size)) (set! e (cons x (cons sum e))) (set! sum (+ sum (envelope-interp x dist)))) (let ((incr (/ (- (cadr e) first-sum) (- data-size 1)))) (set! e (reverse e)) (do ((i 0 (+ i 1)) (x first-sum (+ x incr))) ((= i data-size)) (set! (data i) (envelope-interp x e))) data))) (define (gaussian-envelope s) (let ((e ()) (den (* 2.0 s s))) (do ((i 0 (+ i 1)) (x -1.0 (+ x .1)) (y -4.0 (+ y .4))) ((= i 21)) (set! e (cons (exp (- (/ (* y y) den))) (cons x e)))) (reverse e))) ;;; (make-rand :envelope (gaussian-envelope 1.0)) ;;; ---------------- Julius Smith stuff ---------------- ;;; ;;; these are from "Mathematics of the DFT", W3K Pubs (define channel-mean ; / n (let ((documentation "(channel-mean snd chn) returns the average of the samples in the given channel: /n")) (lambda* (snd chn) (let ((N (framples snd chn)) (reader (make-sampler 0 snd chn)) (incr (make-one-pole 1.0 -1.0))) (do ((i 0 (+ i 1))) ((= i N)) (one-pole incr (next-sample reader))) (/ (one-pole incr 0.0) N))))) (define channel-total-energy ; (let ((documentation "(channel-total-energy snd chn) returns the sum of the squares of all the samples in the given channel: ")) (lambda* (snd chn) (let ((data (samples 0 (framples snd chn) snd chn))) (dot-product data data))))) #| (let ((sum 0.0) (N (framples snd chn)) (reader (make-sampler 0 snd chn))) (do ((i 0 (+ i 1))) ((= i N)) (let ((y (next-sample reader))) (set! sum (+ sum (* y y))))) sum)) |# (define channel-average-power ; / n (let ((documentation "(channel-average-power snd chn) returns the average power in the given channel: /n")) (lambda* (snd chn) (/ (channel-total-energy snd chn) (framples snd chn))))) (define channel-rms ; sqrt( / n) (let ((documentation "(channel-rms snd chn) returns the RMS value of the samples in the given channel: sqrt(/n)")) (lambda* (snd chn) (sqrt (channel-average-power snd chn))))) (define channel-variance ; "sample-variance" might be better, - ( / n) ^ 2 with quibbles (let ((documentation "(channel-variance snd chn) returns the sample variance in the given channel: -((/ n)^2")) (lambda* (snd chn) (let* ((N (framples snd chn)) (mu (* (/ N (- N 1)) (channel-mean snd chn))) ; avoid bias sez JOS (P (channel-total-energy snd chn))) (- P (* mu mu)))))) (define channel-norm ; sqrt() (let ((documentation "(channel-norm snd chn) returns the norm of the samples in the given channel: sqrt()")) (lambda* (snd chn) (sqrt (channel-total-energy snd chn))))) (define channel-lp (let ((documentation "(channel-lp p snd chn) returns the Lp norm of the samples in the given channel")) (lambda* (p snd chn) (let ((incr (make-one-pole 1.0 -1.0)) (N (framples snd chn)) (reader (make-sampler 0 snd chn))) (do ((i 0 (+ i 1))) ((= i N)) (one-pole incr (expt (abs (next-sample reader)) p))) (expt (one-pole incr 0.0) (/ 1.0 p)))))) (define channel-lp-inf maxamp) #| "(channel-lp-inf snd chn) returns the maxamp in the given channel (the name is just math jargon for maxamp)" (let ((mx 0.0) (N (framples snd chn)) (reader (make-sampler 0 snd chn))) (do ((i 0 (+ i 1))) ((= i N)) (set! mx (max mx (abs (next-sample reader))))) mx)) |# (define channel2-inner-product ; (let ((documentation "(channel2-inner-product s1 c1 s2 c2) returns the inner-product of the two channels: ")) (lambda (s1 c1 s2 c2) (dot-product (samples 0 (framples s1 c1) s1 c1) (samples 0 (framples s1 c1) s2 c2))))) #| (let ((N (framples s1 c1)) (sum 0.0) (r1 (make-sampler 0 s1 c1)) (r2 (make-sampler 0 s2 c2))) (do ((i 0 (+ i 1))) ((= i N)) (set! sum (+ sum (* (r1) (r2))))) sum)) |# (define channel2-angle ; acos( / (sqrt() * sqrt())) (let ((documentation "(channel2-angle s1 c1 s2 c2) treats the two channels as vectors, returning the 'angle' between them: acos(/(sqrt()*sqrt()))")) (lambda (s1 c1 s2 c2) (let ((inprod (channel2-inner-product s1 c1 s2 c2)) (norm1 (channel-norm s1 c1)) (norm2 (channel-norm s2 c2))) (acos (/ inprod (* norm1 norm2))))))) (define channel2-orthogonal? ; == 0 (let ((documentation "(channel2-orthogonal? s1 c1 s2 c2) returns #t if the two channels' inner-product is 0: ==0")) (lambda (s1 c1 s2 c2) (= (channel2-inner-product s1 c1 s2 c2) 0.0)))) (define channel2-coefficient-of-projection ; s1,c1 = x, s2,c2 = y, / (let ((documentation "(channel2-coefficient-of-projection s1 c1 s2 c2) returns /")) (lambda (s1 c1 s2 c2) (/ (channel2-inner-product s1 c1 s2 c2) (channel-total-energy s1 c1))))) ;;; -------- end of JOS stuff -------- #| (define channel-distance-1 ; sqrt() (let ((documentation "(channel-distance s1 c1 s2 c2) returns the euclidean distance between the two channels: sqrt()")) (lambda* ((s1 0) (c1 0) (s2 1) (c2 0)) (let ((r1 (make-sampler 0 s1 c1)) (r2 (make-sampler 0 s2 c2)) (sum 0.0) (N (min (framples s1 c1) (framples s2 c2))) (diff 0.0)) (do ((i 0 (+ i 1))) ((= i N)) (set! diff (- (r1) (r2))) (set! sum (+ sum (* diff diff)))) (sqrt sum))))) |# (define channel-distance ; sqrt() (let ((documentation "(channel-distance s1 c1 s2 c2) returns the euclidean distance between the two channels: sqrt()")) (lambda* ((s1 0) (c1 0) (s2 1) (c2 0)) (let ((N (min (framples s1 c1) (framples s2 c2)))) (let ((data1 (samples 0 N s1 c1)) (data2 (samples 0 N s2 c2))) (float-vector-subtract! data1 data2) (sqrt (dot-product data1 data1))))))) (define periodogram (let ((documentation "(periodogram N) displays an 'N' point Bartlett periodogram of the samples in the current channel")) (lambda (N) (let* ((len (framples)) (average-data (make-float-vector N)) (rd (make-sampler 0)) (N2 (* 2 N)) (rl (make-float-vector N2)) (im (make-float-vector N2))) (do ((i 0 (+ i N))) ((>= i len)) (float-vector-scale! rl 0.0) (float-vector-scale! im 0.0) (do ((k 0 (+ k 1))) ((= k N)) (float-vector-set! rl k (read-sample rd))) (mus-fft rl im) (float-vector-multiply! rl rl) (float-vector-multiply! im im) (float-vector-add! average-data (float-vector-add! rl im))) ;; or add snd-spectrum results (graph (float-vector-scale! average-data (/ 1.0 (ceiling (/ len N))))))))) ;;; -------- ssb-am friends (define shift-channel-pitch (let ((documentation "(shift-channel-pitch freq (order 40) (beg 0) dur snd chn edpos) uses the ssb-am CLM generator to \ shift the given channel in pitch without changing its length. The higher 'order', the better usually.")) (lambda* (freq (order 40) (beg 0) dur snd chn edpos) ;; higher order = better cancellation (let ((gen (make-ssb-am freq order))) (map-channel (lambda (y) (ssb-am gen y)) beg dur snd chn edpos (format #f "shift-channel-pitch ~A ~A ~A ~A" freq order beg dur)))))) (define hz->2pi (let ((documentation "(hz->2pi freq) is like hz->radians but uses the current sound's srate, not mus-srate")) (lambda (freq) (/ (* 2 pi freq) (srate))))) (define* (ssb-bank old-freq new-freq pairs (order 40) (bw 50.0) (beg 0) dur snd chn edpos) (let ((ssbs (make-vector pairs)) (bands (make-vector pairs)) (factor (/ (- new-freq old-freq) old-freq))) (do ((i 1 (+ i 1))) ((> i pairs)) (let ((aff (* i old-freq)) (bwf (* bw (+ 1.0 (/ i (* 2 pairs)))))) (set! (ssbs (- i 1)) (make-ssb-am (* i factor old-freq))) (set! (bands (- i 1)) (make-bandpass (hz->2pi (- aff bwf)) (hz->2pi (+ aff bwf)) order)))) (let ((data (channel->float-vector beg dur snd chn edpos))) (let ((len (length data)) (mx (float-vector-peak data))) (let ((summer (make-float-vector len 0.0))) (set! *output* summer) (do ((i 0 (+ i 1))) ((= i pairs)) (let ((gen (vector-ref ssbs i)) (filt (vector-ref bands i))) (do ((k 0 (+ k 1))) ((= k len)) (outa k (ssb-am gen (bandpass filt (ina k data))))))) ; outa adds, (ina i v) is the same as (float-vector-ref v i) (set! *output* #f) (float-vector-scale! summer (/ mx (float-vector-peak summer))) (float-vector->channel summer beg len snd chn current-edit-position (format #f "ssb-bank ~A ~A ~A ~A ~A ~A ~A" old-freq new-freq pairs order bw beg dur))))))) ;;; (let ((ind (open-sound "oboe.snd"))) (ssb-bank 550.0 660.0 10)) (define* (ssb-bank-env old-freq new-freq freq-env pairs (order 40) (bw 50.0) (beg 0) dur snd chn edpos) ;; this version adds a frequency envelope ;; (ssb-bank-env 557 880 '(0 0 1 100.0) 7) (let ((ssbs (make-vector pairs)) (bands (make-vector pairs)) (factor (/ (- new-freq old-freq) old-freq)) (frenvs (make-vector pairs))) (do ((i 1 (+ i 1))) ((> i pairs)) (let ((aff (* i old-freq)) (bwf (* bw (+ 1.0 (/ i (* 2 pairs)))))) (set! (ssbs (- i 1)) (make-ssb-am (* i factor old-freq))) (set! (bands (- i 1)) (make-bandpass (hz->2pi (- aff bwf)) (hz->2pi (+ aff bwf)) order)) (set! (frenvs (- i 1)) (make-env freq-env :scaler (hz->radians i) :length (framples))))) (let ((data (channel->float-vector beg dur snd chn edpos))) (let ((len (length data)) (mx (float-vector-peak data))) (let ((summer (make-float-vector len 0.0))) (set! *output* summer) (do ((i 0 (+ i 1))) ((= i pairs)) (let ((gen (vector-ref ssbs i)) (filt (vector-ref bands i)) (e (vector-ref frenvs i))) (do ((k 0 (+ k 1))) ((= k len)) (outa k (ssb-am gen (bandpass filt (ina k data)) (env e)))))) (set! *output* #f) (float-vector-scale! summer (/ mx (float-vector-peak summer))) (float-vector->channel summer beg len snd chn current-edit-position (format #f "ssb-bank-env ~A ~A '~A ~A ~A ~A ~A ~A" old-freq new-freq freq-env pairs order bw beg dur))))))) ;;; (let ((ind (open-sound "oboe.snd"))) (ssb-bank-env 550 600 '(0 1 1 2) 10)) #| ;;; a "bump function" (Stein and Shakarchi) (define (bumpy) (let* ((x 0.0) (xi (/ 1.0 (framples))) (start 0) (end 1) (scl (exp (/ 4.0 (- end start))))) ; normalize it (map-channel (lambda (y) (let ((val (if (or (<= x start) ; don't divide by zero (>= x end)) 0.0 (* (exp (/ -1.0 (- x start))) (exp (/ -1.0 (- end x))))))) (set! x (+ x xi)) (* scl val)))))) |# ;;; float-vector|channel|spectral-polynomial (define (float-vector-polynomial v coeffs) ;; Horner's rule applied to entire float-vector (let* ((v-len (length v)) (num-coeffs (length coeffs)) (new-v (make-float-vector v-len (coeffs (- num-coeffs 1))))) (do ((i (- num-coeffs 2) (- i 1))) ((< i 0)) (float-vector-offset! (float-vector-multiply! new-v v) (coeffs i))) new-v)) (define* (channel-polynomial coeffs snd chn) (let ((len (framples snd chn))) (float-vector->channel (float-vector-polynomial (channel->float-vector 0 len snd chn) coeffs) 0 len snd chn #f (format #f "channel-polynomial ~A" (float-vector->string coeffs))))) ;;; (channel-polynomial (float-vector 0.0 .5)) = x*.5 ;;; (channel-polynomial (float-vector 0.0 1.0 1.0 1.0)) = x*x*x + x*x + x ;;; convolution -> * in freq (define* (spectral-polynomial coeffs snd chn) (let* ((len (framples snd chn)) (sound (channel->float-vector 0 len snd chn)) (num-coeffs (length coeffs)) (fft-len (if (< num-coeffs 2) len (expt 2 (ceiling (log (* (- num-coeffs 1) len) 2))))) (rl1 (make-float-vector fft-len 0.0)) (rl2 (make-float-vector fft-len 0.0)) (newv (make-float-vector fft-len))) (if (> (coeffs 0) 0.0) (let ((dither (coeffs 0))) (do ((i 0 (+ i 1))) ((= i fft-len)) (float-vector-set! newv i (mus-random dither))))) (if (> num-coeffs 1) (begin (float-vector-add! newv (float-vector-scale! (copy sound) (coeffs 1))) (if (> num-coeffs 2) (let ((peak (maxamp snd chn))) (copy sound rl1) (do ((i 2 (+ i 1))) ((= i num-coeffs)) (copy sound rl2) (convolution rl1 rl2 fft-len) (let ((pk (float-vector-peak rl1))) (float-vector-add! newv (float-vector-scale! (copy rl1) (/ (* (coeffs i) peak) pk))))) (let ((pk (float-vector-peak newv))) (float-vector-scale! newv (/ peak pk))))))) (float-vector->channel newv 0 (max len (* len (- num-coeffs 1))) snd chn #f (format #f "spectral-polynomial ~A" (float-vector->string coeffs))))) ;;; ---------------- ;;; SCENTROID ;;; ;;; by Bret Battey ;;; Version 1.0 July 13, 2002 ;;; translated to Snd/Scheme Bill S 19-Jan-05 ;;; ;;; Returns the continuous spectral centroid envelope of a sound. ;;; The spectral centroid is the "center of gravity" of the spectrum, and it ;;; has a rough correlation to our sense of "brightness" of a sound. ;;; ;;; [Beauchamp, J., "Synthesis by spectral amplitude and 'brightness' matching ;;; analyzed musical sounds". Journal of Audio Engineering Society 30(6), 396-406] ;;; ;;; The formula used is: ;;; C = [SUMF(n)A(n)] / [SUMA(n)] ;;; Where j is the number of bins in the analysis, ;;; F(n) is the frequency of a given bin, ;;; A(n) is the magnitude of the given bin. ;;; ;;; If a pitch envelope for the analyzed sound is available, the results ;;; of SCENTROID can be used with the function NORMALIZE-CENTROID, below, ;;; to provide a "normalized spectral centroid". ;;; ;;; DB-FLOOR -- Frames below this decibel level (0 dB = max) will be discarded ;;; and returned with spectral centroid = 0 ;;; ;;; RFREQ -- Rendering frequency. Number of measurements per second. ;;; ;;; FFTSIZE -- FFT window size. Must be a power of 2. 4096 is recommended. (define scentroid (let ((documentation "(scentroid file (beg 0.0) dur (db-floor -40.0) (rfreq 100.0) (fftsize 4096)) returns the spectral centroid envelope of a sound; 'rfreq' is \ the rendering frequency, the number of measurements per second; 'db-floor' is the level below which data will be ignored")) (lambda* (file (beg 0.0) dur (db-floor -40.0) (rfreq 100.0) (fftsize 4096)) (let* ((fsr (srate file)) (incrsamps (floor (/ fsr rfreq))) (start (floor (* beg fsr))) (end (+ start (if dur (floor (* dur fsr)) (- (framples file) beg)))) (fdr (make-float-vector fftsize)) (fdi (make-float-vector fftsize)) (scl (make-float-vector (/ fftsize 2))) (ones (make-float-vector (/ fftsize 2) 1.0)) (windows (+ 1 (floor (/ (- end start) incrsamps)))) (results (make-float-vector windows)) (fft2 (floor (/ fftsize 2))) (binwidth (* 1.0 (/ fsr fftsize))) (rd (make-readin file))) (do ((k 0 (+ k 1))) ((= k fft2)) (float-vector-set! scl k (* k binwidth))) (do ((i start (+ i incrsamps)) (loc 0 (+ 1 loc))) ((>= i end)) (set! (mus-location rd) i) (do ((j 0 (+ j 1))) ((= j fftsize)) (float-vector-set! fdr j (readin rd))) (if (>= (linear->db (sqrt (/ (dot-product fdr fdr) fftsize))) db-floor) (begin (fill! fdi 0.0) (mus-fft fdr fdi fftsize) (rectangular->magnitudes fdr fdi) (set! (results loc) (/ (dot-product scl fdr fft2) (dot-product ones fdr fft2)))))) results)))) ;;; ---------------- ;;; ;;; invert-filter inverts an FIR filter ;;; ;;; say we previously filtered a sound via (filter-channel (float-vector .5 .25 .125)) ;;; and we want to undo it without using (undo): ;;; (filter-channel (invert-filter (float-vector .5 .25 .125))) ;;; ;;; there are a million gotchas here. The primary one is that the inverse filter ;;; can "explode" -- the coefficients can grow without bound. For example, any ;;; filter returned by spectrum->coeffs above will be a problem (it always returns ;;; a "linear phase" filter). Could this be used to remove reverb? (define invert-filter (let ((documentation "(invert-filter coeffs) tries to return an inverse filter to undo the effect of the FIR filter coeffs.")) (lambda (fcoeffs) (let* ((flen (length fcoeffs)) (coeffs (make-float-vector (+ 32 flen))) ; add room for coeffs to die away (order (length coeffs))) (do ((i 0 (+ i 1))) ((= i flen)) (set! (coeffs i) (fcoeffs i))) (let ((nfilt (make-float-vector order))) (set! (nfilt 0) (/ 1.0 (coeffs 0))) (do ((i 1 (+ i 1))) ((= i order)) (let ((sum 0.0)) (do ((j 0 (+ j 1)) (k i (- k 1))) ((= j i)) (set! sum (+ sum (* (nfilt j) (coeffs k))))) (set! (nfilt i) (/ sum (- (coeffs 0)))))) nfilt))))) ;;; ---------------- ;;; ;;; Volterra filter ;;; ;;; one of the standard non-linear filters ;;; this version is taken from Monson Hayes "Statistical DSP and Modeling" ;;; it is a slight specialization of the form mentioned by J O Smith and others (define make-volterra-filter (let ((documentation "(make-volterra-filter acoeffs bcoeffs) returns a list for use with volterra-filter, producing one of the standard non-linear filters")) (lambda (acoeffs bcoeffs) (list acoeffs bcoeffs (make-float-vector (max (length acoeffs) (length bcoeffs))))))) (define volterra-filter (let ((documentation "(volterra-filter flt x) takes 'flt', a list returned by make-volterra-filter, and an input 'x', and returns the (non-linear filtered) result")) (lambda (flt x) (let* ((as (car flt)) (bs (cadr flt)) (xs (caddr flt)) (xlen (length xs)) (x1len (length as)) (x2len (length bs)) (sum 0.0)) (float-vector-move! xs (- xlen 1) (- xlen 2) #t) (set! (xs 0) x) (set! sum (dot-product as xs x1len)) (do ((i 0 (+ i 1))) ((= i x2len)) (do ((j i (+ j 1))) ((= j x2len)) (set! sum (+ sum (* (bs j) (xs i) (xs j)))))) sum)))) ;;; (define flt (make-volterra-filter (float-vector .5 .1) (float-vector .3 .2 .1))) ;;; (map-channel (lambda (x) (volterra-filter flt x))) ;;; ---------------- ;;; ;;; harmonicizer (each harmonic is split into a set of harmonics via Chebyshev polynomials) ;;; obviously very similar to ssb-bank above, but splits harmonics individually, rather than pitch-shifting them (define harmonicizer (let ((documentation "(harmonicizer freq coeffs pairs (order 40) (bw 50.0) (beg 0) dur snd chn edpos) splits out each harmonic \ and replaces it with the spectrum given in coeffs")) (lambda* (freq coeffs pairs (order 40) (bw 50.0) (beg 0) dur snd chn edpos) (let ((bands (make-vector pairs)) (pcoeffs (partials->polynomial coeffs)) (peaks (make-vector pairs)) (peaks2 (make-vector pairs)) (flt (make-filter 2 (float-vector 1 -1) (float-vector 0 -0.9))) (old-mx (maxamp)) (startup 40) (len (- (or dur (framples snd chn edpos)) beg))) (let ((summer (make-float-vector len)) (indata (channel->float-vector beg len snd chn edpos))) (do ((i 0 (+ i 1))) ((= i pairs)) (let ((aff (* (+ i 1) freq)) (bwf (* bw (+ 1.0 (/ (+ i 1) (* 2 pairs)))))) (set! (peaks i) (make-moving-max 128)) (set! (peaks2 i) (make-moving-norm 128)) (set! (bands i) (make-bandpass (hz->2pi (- aff bwf)) (hz->2pi (+ aff bwf)) order)))) ;; ignore startup (do ((k 0 (+ k 1))) ((= k startup)) (let ((sum 0.0)) (do ((i 0 (+ i 1))) ((= i pairs)) (let ((sig (bandpass (vector-ref bands i) (float-vector-ref indata k)))) (set! sum (+ sum (* (moving-max (vector-ref peaks i) sig) (polynomial pcoeffs (* sig (moving-norm (vector-ref peaks2 i) sig)))))))) (filter flt sum))) (set! *output* summer) (do ((pair 0 (+ pair 1))) ((= pair pairs)) (let ((bp (vector-ref bands pair)) (pk (vector-ref peaks pair)) (pk2 (vector-ref peaks2 pair))) (do ((k startup (+ k 1))) ((= k len)) (let ((x (bandpass bp (float-vector-ref indata k)))) (outa k (* (moving-max pk x) (polynomial pcoeffs (* x (moving-norm pk2 x))))))))) ;; we're normalizing the polynomial input so its waveshaping index is more-or-less 1.0 ;; this might work better with len=256, max .1 -- we're assuming a well-behaved signal (set! *output* #f) (do ((k startup (+ k 1))) ((= k len)) (float-vector-set! summer k (filter flt (float-vector-ref summer k)))) (let ((nmx (float-vector-peak summer))) (if (> nmx 0.0) (float-vector-scale! summer (/ old-mx nmx)))) (float-vector->channel summer beg len snd chn)))))) ;;; (harmonicizer 550.0 (list 1 .5 2 .3 3 .2) 10) ;;; ---------------- ;;; ;;; linear sampling rate conversion (define linear-src-channel (let ((documentation "(linear-src-channel sr snd chn) performs sampling rate conversion using linear interpolation.")) (lambda* (sr snd chn) (let* ((rd (make-sampler 0 snd chn)) (last (rd)) (next (rd)) (intrp 0.0) (tempfile (with-sound (:output (snd-tempnam) :srate (srate snd) :to-snd #f) (do ((samp 0 (+ samp 1))) ((sampler-at-end? rd)) (outa samp (let ((pos intrp)) (if (>= pos 1.0) (let ((num (floor pos))) (do ((i 0 (+ i 1))) ((= i num)) (set! last next) (set! next (read-sample rd))) (set! pos (- pos num)))) (set! intrp (+ pos sr)) (+ last (* pos (- next last)))) )))) (len (framples tempfile))) (set-samples 0 (- len 1) tempfile snd chn #t "linear-src" 0 #f #t) ;; first #t=truncate to new length, #f=at current edpos, #t=auto delete temp file )))) ;;; -------- spectrum displayed in various frequency scales (define display-bark-fft ;; click in lisp-graph to change the tick placement choice (let ((snd-color-1 (lambda args (and (defined? 'snd-color) (apply snd-color args))))) (let ((bark-fft-size 0) (bark-tick-function 0) (color1 (snd-color-1 8)) ; selected-data-color (color2 (snd-color-1 2)) ; red (color3 (snd-color-1 4))) ; blue (define (bark f) (let ((f2 (/ f 7500))) (+ (* 13.5 (atan (* .00076 f))) (* 3.5 (atan (* f2 f2)))))) (define (mel f) (* 1127 (log (+ 1.0 (/ f 700.0))))) (define (erb f) (+ 43.0 (* 11.17 (log (/ (+ f 312) (+ f 14675)))))) (define (display-bark-fft-1 hook) (let* ((snd (hook 'snd)) (chn (hook 'chn)) (ls (left-sample snd chn)) (rs (right-sample snd chn)) (fftlen (floor (expt 2 (ceiling (log (+ 1 (- rs ls)) 2)))))) (if (> fftlen 0) (let ((data (channel->float-vector ls fftlen snd chn)) (normalized (not (= (transform-normalization snd chn) dont-normalize))) (linear #t)) ; can't currently show lisp graph in dB ;; snd-axis make_axes: WITH_LOG_Y_AXIS, but LINEAR currently in snd-chn.c 3250 (if (float-vector? data) (let ((fftdata (snd-spectrum data ; returns fftlen / 2 data points (fft-window snd chn) fftlen linear (fft-window-beta snd chn) #f normalized))) (if (float-vector? fftdata) (let* ((sr (srate snd)) (mx (float-vector-peak fftdata)) (data-len (length fftdata)) ;; bark settings (bark-low (floor (bark 20.0))) (bark-high (ceiling (bark (* 0.5 sr)))) (bark-frqscl (/ data-len (- bark-high bark-low))) (bark-data (make-float-vector data-len)) ;; mel settings (mel-low (floor (mel 20.0))) (mel-high (ceiling (mel (* 0.5 sr)))) (mel-frqscl (/ data-len (- mel-high mel-low))) (mel-data (make-float-vector data-len)) ;; erb settings (erb-low (floor (erb 20.0))) (erb-high (ceiling (erb (* 0.5 sr)))) (erb-frqscl (/ data-len (- erb-high erb-low))) (erb-data (make-float-vector data-len))) (set! bark-fft-size fftlen) (do ((i 0 (+ i 1))) ((= i data-len)) (let* ((val (fftdata i)) (frq (* sr (/ i fftlen))) (bark-bin (round (* bark-frqscl (- (bark frq) bark-low)))) (mel-bin (round (* mel-frqscl (- (mel frq) mel-low)))) (erb-bin (round (* erb-frqscl (- (erb frq) erb-low))))) (if (and (>= bark-bin 0) (< bark-bin data-len)) (set! (bark-data bark-bin) (+ val (bark-data bark-bin)))) (if (and (>= mel-bin 0) (< mel-bin data-len)) (set! (mel-data mel-bin) (+ val (mel-data mel-bin)))) (if (and (>= erb-bin 0) (< erb-bin data-len)) (set! (erb-data erb-bin) (+ val (erb-data erb-bin)))))) (if normalized (let ((bmx (float-vector-peak bark-data)) (mmx (float-vector-peak mel-data)) (emx (float-vector-peak erb-data))) (if (> (abs (- mx bmx)) .01) (float-vector-scale! bark-data (/ mx bmx))) (if (> (abs (- mx mmx)) .01) (float-vector-scale! mel-data (/ mx mmx))) (if (> (abs (- mx emx)) .01) (float-vector-scale! erb-data (/ mx emx))))) (graph (list bark-data mel-data erb-data) "ignored" 20.0 (* 0.5 sr) 0.0 (if normalized 1.0 (* data-len (y-zoom-slider snd chn))) snd chn #f show-bare-x-axis))))))) (list color1 color2 color3))) ; tell lisp graph display what colors to use (define (make-bark-labels hook) ;; at this point the x axis has no markings, but there is room for labels and ticks (let* ((snd (hook 'snd)) (chn (hook 'chn)) (old-foreground-color (foreground-color snd chn copy-context))) (let* ((axinfo (axis-info snd chn lisp-graph)) (axis-x0 (axinfo 10)) (axis-x1 (axinfo 12)) (axis-y0 (axinfo 13)) (axis-y1 (axinfo 11)) (label-height 15) (char-width 8) (sr2 (* 0.5 (srate snd))) (minor-tick-len 6) (major-tick-len 12) (tick-y0 axis-y1) (minor-y0 (+ axis-y1 minor-tick-len)) (major-y0 (+ axis-y1 major-tick-len)) (bark-label-font (snd-font 3)) (bark-numbers-font (snd-font 2)) (label-pos (+ axis-x0 (* .45 (- axis-x1 axis-x0)))) (cr (make-cairo (car (channel-widgets snd chn))))) (define (scale-position scale f) (let ((b20 (scale 20.0))) (round (+ axis-x0 (/ (* (- axis-x1 axis-x0) (- (scale f) b20)) (- (scale sr2) b20)))))) (define (bark-position f) (scale-position bark f)) (define (mel-position f) (scale-position mel f)) (define (erb-position f) (scale-position erb f)) (define (draw-bark-ticks bark-function) (if bark-numbers-font (set! (current-font snd chn copy-context) bark-numbers-font)) (draw-line axis-x0 tick-y0 axis-x0 major-y0 snd chn copy-context cr) (let ((i1000 (scale-position bark-function 1000.0)) (i10000 (scale-position bark-function 10000.0))) (draw-line i1000 tick-y0 i1000 major-y0 snd chn copy-context cr) (draw-line i10000 tick-y0 i10000 major-y0 snd chn copy-context cr) (draw-string "20" axis-x0 major-y0 snd chn copy-context cr) (draw-string "1000" (- i1000 (* 3 4)) major-y0 snd chn copy-context cr) (draw-string "10000" (- i10000 (* 6 4)) major-y0 snd chn copy-context cr) (draw-string (format #f "fft size: ~D" bark-fft-size) (+ axis-x0 10) axis-y0 snd chn copy-context cr) (do ((i 100 (+ i 100))) ((= i 1000)) (let ((i100 (scale-position bark-function i))) (draw-line i100 tick-y0 i100 minor-y0 snd chn copy-context cr))) (do ((i 2000 (+ i 1000))) ((= i 10000)) (let ((i1000 (scale-position bark-function i))) (draw-line i1000 tick-y0 i1000 minor-y0 snd chn copy-context cr))))) ;; bark label/ticks (set! (foreground-color snd chn copy-context) color1) (if (= bark-tick-function 0) (draw-bark-ticks bark-position)) (if bark-label-font (set! (current-font snd chn copy-context) bark-label-font)) (draw-string "bark," label-pos (+ axis-y1 label-height) snd chn copy-context cr) ;; mel label/ticks (set! (foreground-color snd chn copy-context) color2) (if (= bark-tick-function 1) (draw-bark-ticks mel-position)) (if bark-label-font (set! (current-font snd chn copy-context) bark-label-font)) (draw-string "mel," (+ (* char-width 6) label-pos) (+ axis-y1 label-height) snd chn copy-context cr) ;; erb label/ticks (set! (foreground-color snd chn copy-context) color3) (if (= bark-tick-function 2) (draw-bark-ticks erb-position)) (if bark-label-font (set! (current-font snd chn copy-context) bark-label-font)) (draw-string "erb" (+ (* char-width (+ 6 5)) label-pos) (+ axis-y1 label-height) snd chn copy-context cr) (free-cairo cr)) (set! (foreground-color snd chn copy-context) old-foreground-color))) ;; mouse click = move to next scale's ticks (define (choose-bark-ticks hook) (if (= (hook 'axis) lisp-graph) (begin (set! bark-tick-function (+ bark-tick-function 1)) (if (> bark-tick-function 2) (set! bark-tick-function 0)) (update-lisp-graph (hook 'snd) (hook 'chn))))) ;; user's view of display-bark-fft function (lambda* (off col1 col2 col3) (if col1 (set! color1 col1)) (if col2 (set! color2 col2)) (if col3 (set! color3 col3)) (if (not off) (begin (hook-push lisp-graph-hook display-bark-fft-1) (hook-push after-lisp-graph-hook make-bark-labels) (hook-push mouse-click-hook choose-bark-ticks) (for-each (lambda (snd) (do ((c 0 (+ 1 c))) ((= c (channels snd))) (update-lisp-graph snd c))) (sounds))) (begin (hook-remove lisp-graph-hook display-bark-fft-1) (hook-remove after-lisp-graph-hook make-bark-labels) (hook-remove mouse-click-hook choose-bark-ticks) (for-each (lambda (snd) (do ((c 0 (+ 1 c))) ((= c (channels snd))) (set! (lisp-graph? snd c) #f))) (sounds)))))))) (define (undisplay-bark-fft) (display-bark-fft #t)) ;;; -------- lpc-coeffs, lpc-predict (define lpc-coeffs (let ((documentation "(lpc-coeffs data n m) returns 'm' LPC coeffients (in a vector) given 'n' data points in the float-vector 'data'")) (lambda (data n m) ;; translated and changed to use 0-based arrays from memcof of NRinC (let ((d (make-float-vector m 0.0)) (wk1 (make-float-vector n 0.0)) (wk2 (make-float-vector n 0.0)) (wkm (make-float-vector n 0.0))) (copy data wk1) (do ((j 1 (+ j 1)) (k 0 (+ k 1))) ((= j n)) (float-vector-set! wk2 k (float-vector-ref data j))) (do ((k 0 (+ k 1))) ((= k m) d) (let ((end (- n k 1))) (let ((num (dot-product wk1 wk2 end)) (denom (+ (dot-product wk1 wk1 end) (dot-product wk2 wk2 end)))) (if (not (= denom 0.0)) (set! (d k) (/ (* 2.0 num) denom)))) (let ((d-k (d k))) (do ((i 0 (+ i 1)) (k1 (- k 1) (- k1 1))) ((= i k)) ; 1st time is skipped presumably (float-vector-set! d i (- (float-vector-ref wkm i) (* d-k (float-vector-ref wkm k1)))))) (if (< k (- m 1)) (let ((end (- n k 2))) (copy d wkm 0 (+ k 1)) (let ((wkm-k (float-vector-ref wkm k)) (old-wk1 (copy wk1))) (do ((j 0 (+ j 1))) ((= j end)) (float-vector-set! wk1 j (- (float-vector-ref wk1 j) (* wkm-k (float-vector-ref wk2 j))))) (do ((j 0 (+ j 1)) (j1 1 (+ j1 1))) ((= j end)) (float-vector-set! wk2 j (- (float-vector-ref wk2 j1) (* wkm-k (float-vector-ref old-wk1 j1)))))))))))))) (define lpc-predict ;; translated and changed to use 0-based arrays from predic of NRinC ;; incoming coeffs are assumed to be in a vector (from lpc-coeffs) (let ((documentation "(lpc-predict data n coeffs m nf clipped) takes the output of lpc-coeffs ('coeffs', a float-vector) and the length thereof ('m'), \ 'n' data points of 'data' (a float-vector), and produces 'nf' new data points (in a float-vector) as its prediction. If 'clipped' is #t, the new data \ is assumed to be outside -1.0 to 1.0.")) (lambda* (data n coeffs m nf clipped) (let ((future (make-float-vector nf 0.0)) (reg (make-float-vector m 0.0))) (do ((i 0 (+ i 1)) (j (- n 1) (- j 1))) ((= i m)) (set! (reg i) (data j))) (do ((j 0 (+ j 1))) ((= j nf) future) (let ((sum (dot-product coeffs reg m))) (do ((k (- m 1) (- k 1))) ((= k 0)) (set! (reg k) (reg (- k 1)))) ;; added this block (if clipped (if (> sum 0.0) (if (< sum 1.0) (set! sum 1.0)) (if (> sum -1.0) (set! sum -1.0)))) (set! (reg 0) sum) (set! (future j) sum))))))) ;;; -------- unclip-channel (define unclip-channel (let ((documentation "(unclip-channel snd chn) looks for clipped portions and tries to reconstruct the original using LPC")) (lambda* (snd chn) (let ((clips 0) ; number of clipped portions * 2 (unclipped-max 0.0) (len (framples snd chn)) (data (channel->float-vector 0 #f snd chn)) (clip-size 1000) (clip-data (make-vector 1000 0))) ;; count clipped portions (let ((in-clip #f) (clip-beg 0)) (float-vector-abs! data) (do ((i 0 (+ i 1))) ((= i len)) (if (> (float-vector-ref data i) .9999) ; this sample is clipped (if (not in-clip) (begin (set! in-clip #t) (set! clip-beg i))) (begin ; not clipped (set! unclipped-max (max unclipped-max (float-vector-ref data i))) ; this is not the same as (float-vector-peak ...) (if in-clip (begin (set! in-clip #f) (set! (clip-data clips) clip-beg) (set! (clip-data (+ 1 clips)) (- i 1)) (set! clips (+ clips 2)) (if (> clips clip-size) (let ((new-clip-data (make-vector (* 2 clip-size) 0))) (copy clip-data new-clip-data) (set! clip-data new-clip-data) (set! clip-size (* 2 clip-size)))))))))) (if (> clips 0) ;; try to restore clipped portions (let ((min-data-len 32) (max-len 0)) (as-one-edit (lambda () (do ((clip 0 (+ clip 2))) ; so go through all... ((>= clip clips)) (let* ((clip-beg (clip-data clip)) ; clip-beg to clip-end inclusive are clipped (clip-end (clip-data (+ 1 clip))) (clip-len (+ 1 (- clip-end clip-beg))) (data-len (max min-data-len (* clip-len 4)))) (if (> clip-len max-len) (set! max-len clip-len)) (let ((forward-data-len data-len) (backward-data-len data-len) (previous-end (if (= clip 0) 0 (clip-data (- clip 1)))) (next-beg (if (< clip (- clips 3)) (clip-data (+ clip 2)) (framples snd chn)))) (if (< (- clip-beg data-len) previous-end) ; current beg - data collides with previous (set! forward-data-len (max 4 (- clip-beg previous-end)))) (if (> (+ clip-end data-len) next-beg) ; current end + data collides with next (set! backward-data-len (max 4 (- next-beg clip-end)))) (let ((forward-predict-len (min (max clip-len (floor (/ forward-data-len 2))) forward-data-len)) (backward-predict-len (min (max clip-len (floor (/ backward-data-len 2))) backward-data-len))) ;; use LPC to reconstruct going both forwards and backwards (let* ((data (channel->float-vector (- clip-beg forward-data-len) forward-data-len snd chn)) (future (lpc-predict data forward-data-len (lpc-coeffs data forward-data-len forward-predict-len) forward-predict-len clip-len #f)) (rdata (reverse! (channel->float-vector (+ 1 clip-end) backward-data-len snd chn))) (past (lpc-predict rdata backward-data-len (lpc-coeffs rdata backward-data-len backward-predict-len) backward-predict-len clip-len #f)) (new-data (make-float-vector clip-len 0.0))) (if (> clip-len 1) (do ((i 0 (+ i 1)) (j (- clip-len 1) (- j 1))) ((= i clip-len)) (let ((sn (* 0.5 (+ 1.0 (cos (* pi (/ i (- clip-len 1)))))))) (set! (new-data i) (+ (* sn (future i)) (* (- 1.0 sn) (past j)))))) ;; todo perhaps move this mix dependent on data-lens? ;; todo perhaps special case for 2 samps (what if both 1.0 for example?) ;; todo perhaps if multichannel and channels are correlated and one is not clipped -- use ;; its data to help reconstruct clipped case? (set! (new-data 0) (if (> (future 0) 0.0) (max (future 0) (past 0)) (min (future 0) (past 0))))) ;; write reconstruction (float-vector->channel new-data clip-beg clip-len snd chn)))))))) (if (> unclipped-max .95) (set! unclipped-max .999)) (scale-channel (/ unclipped-max (maxamp snd chn)) 0 (framples snd chn) snd chn) (list 'max unclipped-max 'clips (/ clips 2) 'max-len max-len)) 'no-clips))))) (define unclip-sound (let ((documentation "(unclip-sound snd) applies unclip-channel to each channel of 'snd'.")) (lambda* (snd) (let ((index (or snd (selected-sound) (car (sounds))))) (if (not (sound? index)) (error 'no-such-sound (list "unclip-sound" snd)) (let ((chns (channels index))) (do ((chn 0 (+ 1 chn))) ((= chn chns)) (unclip-channel index chn)))))))) (define* (kalman-filter-channel (Q 1.0e-5)) ;; translated from http://www.scipy.org/Cookbook/KalmanFiltering by Andrew Straw (but "R" here is a signal) (let ((size (framples)) (mx (maxamp)) (data (channel->float-vector 0)) (xhat 0.0) (P 1.0) ; any non-zero value ok here (R 0.01) ; first guess (Pminus 0.0) (frm (make-formant :radius (- 1.0 (/ 2000.0 (srate))) :frequency 1000)) (del (make-moving-average 256)) (K 0.0)) (do ((k 1 (+ k 1))) ((= k size)) (let ((datum (data k)) (xhatminus xhat)) (let* ((res (formant frm datum)) (avg (moving-average del (abs res)))) (set! R (/ .000001 (+ avg .001)))) ;; K now goes between say .5 if avg large to almost 0 if avg 0 (R is inverse essentially) ;; so filter lp effect increases as apparent true signal decreases ;; "truth" here is based on vocal resonances (set! (data k) xhatminus) ; filter output (set! Pminus (+ P Q)) (set! K (/ Pminus (+ Pminus R))) (set! xhat (+ xhatminus (* K (- datum xhatminus)))) (set! P (* (- 1.0 K) Pminus)))) (float-vector-scale! data (/ mx (float-vector-peak data))) (float-vector->channel data))) ;;; -------- Savitzky-Golay filter coefficients (FIR filter -- returns float-vector of coeffs centered at float-vector midpoint) ;;; ;;; based on Numerical Recipes in C p 652 (define invert-matrix (let ((documentation "(invert-matrix matrix b (zero 1.0e-7)) inverts 'matrix'")) (lambda* (matrix b (zero 1.0e-7)) ;; translated from Numerical Recipes (gaussj) ;(format #t "~%~%invert-matrix n: ~D, ~S, b: ~A, ~S~%" (length matrix) matrix (and b (length b)) b) (call-with-exit (lambda (return) (let* ((n (car (vector-dimensions matrix))) (cols (make-vector n 0)) (rows (make-vector n 0)) (pivots (make-vector n 0))) (do ((i 0 (+ i 1))) ((= i n)) (let ((biggest 0.0) (col 0) (row 0)) (do ((j 0 (+ j 1))) ((= j n)) ;(format #t "j: ~A, n: ~A~%" j n) (if (not (= (pivots j) 1)) (do ((k 0 (+ k 1))) ((= k n)) (if (= (pivots k) 0) (let ((val (abs (matrix j k)))) (if (> val biggest) (begin (set! col k) (set! row j) ;(format #t "k: ~A, row: ~D, col: ~A~%" k row col) (set! biggest val)))) (if (> (pivots k) 1) (return #f)))))) (if (< biggest zero) (return #f)) ; this can be fooled (floats...): (invert-matrix (make-share-vector (float-vector 1 2 3 3 2 1 4 5 6) (list 3 3))) (set! (pivots col) (+ (pivots col) 1)) ;(format #t "i: ~D, row: ~D, col: ~A~%" i row col) (if (not (= row col)) (let ((temp (if b (b row) 0.0))) (if b (begin (set! (b row) (b col)) (set! (b col) temp))) (do ((k 0 (+ k 1))) ((= k n)) (set! temp (matrix row k)) (set! (matrix row k) (matrix col k)) (set! (matrix col k) temp)))) (set! (cols i) col) (set! (rows i) row) ;; round-off troubles here (if (< (abs (matrix col col)) zero) (return #f)) (let ((inverse-pivot (/ 1.0 (matrix col col)))) (set! (matrix col col) 1.0) (do ((k 0 (+ k 1))) ((= k n)) (set! (matrix col k) (* inverse-pivot (matrix col k)))) (if b (set! (b col) (* inverse-pivot (b col))))) (do ((k 0 (+ k 1))) ((= k n)) (if (not (= k col)) (let ((scl (matrix k col))) (set! (matrix k col) 0.0) (do ((m 0 (+ 1 m))) ((= m n)) (set! (matrix k m) (- (matrix k m) (* scl (matrix col m))))) (if b (set! (b k) (- (b k) (* scl (b col)))))))))) (do ((i (- n 1) (- i 1))) ((< i 0)) (if (not (= (rows i) (cols i))) (do ((k 0 (+ k 1))) ((= k n)) (let ((temp (matrix k (rows i)))) (set! (matrix k (rows i)) (matrix k (cols i))) (set! (matrix k (cols i)) temp))))) (list matrix b))))))) (define (matrix-solve A b) (let ((val (invert-matrix A b))) (and val (cadr val)))) (define* (make-savitzky-golay-filter size (order 2)) ;assuming symmetric filter (left = right) (if (even? size) (set! size (+ size 1))) (let ((n (/ (- size 1) 2)) (a (make-float-vector (list (+ 1 order) (+ 1 order)) 0.0))) (do ((i 0 (+ i 1))) ((> i (* order 2))) (let ((sum (if (= i 0) 1.0 0.0))) (if (even? i) (do ((k 1 (+ k 1))) ((> k n)) ;(set! sum (+ sum (expt k i) (expt (- k) i))) ; kinda nuts (set! sum (+ sum (* 2 (expt k i)))))) (let ((m i)) (if (> i (- (* 2 order) i)) (set! m (- (* 2 order) i))) (do ((k (- m) (+ k 2))) ((> k m)) (set! (a (/ (+ i k) 2) (/ (- i k) 2)) sum))))) (let ((b (matrix-solve a (let ((f (make-float-vector (+ order 1) 0.0))) (set! (f 0) 1.0) ; set others instead for derivative f))) (result (make-float-vector size 0.0))) (do ((k (- n) (+ k 1)) (i 0 (+ i 1))) ((> k n)) (let ((sum (b 0)) (fac 1.0)) (do ((m 1 (+ 1 m))) ((> m order)) (set! fac (* fac k)) (set! sum (+ sum (* (b m) fac)))) (set! (result i) sum))) (make-fir-filter :order size :xcoeffs result)))) (define savitzky-golay-filter fir-filter) #| ;; NRinC examples (2nd ed, p651) :(make-savitzky-golay-filter 5 2) # :(make-savitzky-golay-filter 11 2) # :(make-savitzky-golay-filter 11 4) # :(make-savitzky-golay-filter 25 2) # |# ;;; -------- hard and soft clipping ;;; ;;; from Julius Smith's http://ccrma.stanford.edu/~jos/pasp/Cubic_Soft_Clipper.html (define (hard-clipped x) (max -1.0 (min 1.0 x))) (define (soft-clipped x) (max -0.6667 (min 0.6667 (- x (* 0.3333 x x x))))) ;;; -------- parallel FM spectrum calculator ;(fm-parallel-component 200 2000.0 (list 2000.0 200.0) (list 0.5 1.0) () () #t) (define fm-parallel-component (let ((documentation "(fm-parallel-component freq carrier modfreqs indices () () with-sines) returns the amplitude of \"freq\" in \ the multi-modulator FM case described by the list of modulator frequencies and indices")) (lambda (freq-we-want wc wms inds ns bs using-sine) (if (pair? wms) (let* ((sum 0.0) (index (car inds)) (mx (ceiling (* 7 index))) (wm (car wms))) (do ((k (- mx) (+ k 1))) ((>= k mx) sum) (set! sum (+ sum (fm-parallel-component freq-we-want (+ wc (* k wm)) (cdr wms) (cdr inds) (append ns (list k)) (append bs (list index)) using-sine))))) (if (< (abs (- freq-we-want (abs wc))) .1) (let ((bmult 1.0)) (for-each (lambda (n index) (set! bmult (* bmult (bes-jn n index)))) ns bs) (if (and using-sine (< wc 0.0)) (set! bmult (- bmult))) ;(format #t ";add ~A from ~A ~A" bmult ns bs) bmult) 0.0))))) ;;; this returns the component in FM with complex index (using-sine ignored for now) ;;; this needs the Bessel functions (gsl or snd-test.scm) (define (fm-complex-component freq-we-want wc wm a b interp using-sine) (define (~,3f x) (format #f "~,3F" x)) (let ((sum 0.0) (mxa (ceiling (* 7 a))) (mxb (ceiling (* 7 b)))) (do ((k (- mxa) (+ k 1))) ((>= k mxa)) (do ((j (- mxb) (+ j 1))) ((>= j mxb)) (if (< (abs (- freq-we-want (+ wc (* k wm) (* j wm)))) 0.1) (let ((curJI (* (bes-jn k a) (bes-in (abs j) b) (expt 0.0+1.0i j)))) (set! sum (+ sum curJI)) (if (> (magnitude curJI) 0.001) (format #t ";fm-complex-component add ~,3f from J~D(~A) = ~,3f and I~D(~A) = ~,3f~%" curJI k a (bes-jn k a) j b (bes-in (abs j) b))))))) (list sum (+ (* (- 1.0 interp) (real-part sum)) (* interp (imag-part sum)))))) ;(fm-complex-component 1200 1000 100 1.0 3.0 0.0 #f) ;(fm-complex-component 1200 1000 100 1.0 4.0 0.0 #f) hits the commentary (define (fm-cascade-component freq-we-want wc wm1 a wm2 b) (define (~,3f x) (format #f "~,3F" x)) (let ((sum 0.0) (mxa (ceiling (* 7 a))) (mxb (ceiling (* 7 b)))) (do ((k (- mxa) (+ k 1))) ((>= k mxa)) (do ((j (- mxb) (+ j 1))) ((>= j mxb)) (if (< (abs (- freq-we-want (+ wc (* k wm1) (* j wm2)))) 0.1) (let ((curJJ (* (bes-jn k a) (bes-jn j (* k b))))) (set! sum (+ sum curJJ)) (if (> (magnitude curJJ) 0.001) (format #t ";fm-cascade-component add ~,3f from J~D(~A) = ~,3f and J~D(~A) = ~,3f~%" curJJ k a (bes-jn k a) j b (bes-jn j (* k b)))))))) sum)) ;(fm-cascade-component 2000 2000 500 1.5 50 1.0) ;;; waveshaping harmonic amplitude at a given index (define (cheby-hka k a coeffs) ; (coeff 0 = DC) (let ((sum 0.0) (n (length coeffs))) (do ((j 0 (+ j 1))) ((= j n)) (let ((dsum 0.0) (p (+ k (* 2 j)))) (do ((i 0 (+ i 1))) ((>= (+ p (* 2 i)) n)) (set! dsum (+ dsum (* (expt -1 i) (coeffs (+ p (* 2 i))) (+ (binomial (+ p i) i) (binomial (+ p i -1) (- i 1))))))) (set! sum (+ sum (* dsum (expt a p) (binomial p j)))))) sum)) #| (with-sound () (let ((gen (make-polyshape 1000.0 :partials (list 1 .5 2 .25 3 .125 4 .125)))) (do ((i 0 (+ i 1))) ((= i 88200)) (outa i (* .5 (polyshape gen 0.25)))))) (cheby-hka 1 0.25 (float-vector 0 .5 .25 .125 .125)) |# ;;; find not-so-spikey amps for waveshaping (define* (flatten-partials any-partials (tries 32)) (define (cos-fft-to-max n cur-amps) (let* ((size 1024) (fft-rl (make-float-vector size)) (fft-im (make-float-vector size))) (do ((i 0 (+ i 1)) (bin 2 (+ bin 2))) ((= i n)) (set! (fft-rl bin) (cur-amps i))) (float-vector-peak (mus-fft fft-rl fft-im size -1)))) (let* ((partials (if (list? any-partials) (apply float-vector any-partials) any-partials)) (len (length partials)) (topk 0) (DC 0.0) (original-sum (let ((sum 0.0)) (do ((i 0 (+ i 2))) ((>= i len) sum) (let ((hnum (partials i)) (amp (partials (+ i 1)))) (if (= hnum 0) (set! DC amp) (begin (set! topk (max topk hnum)) (set! sum (+ sum amp)))))))) (min-sum original-sum) (original-partials (let ((v (make-float-vector topk))) (do ((i 0 (+ i 2))) ((>= i len) v) (let ((hnum (partials i))) (if (not (= hnum 0)) (set! (v (- hnum 1)) (partials (+ i 1)))))))) (min-partials (copy original-partials))) (if (<= topk (log tries 2)) (set! tries (floor (expt 2 (- topk 1))))) (do ((try 0 (+ 1 try))) ((= try tries)) (let ((new-partials (copy original-partials))) (do ((k 0 (+ k 1))) ((= k topk)) (if (> (random 1.0) 0.5) (set! (new-partials k) (- (new-partials k))))) (let ((new-sum (cos-fft-to-max topk new-partials))) (if (< new-sum min-sum) (begin (set! min-partials (copy new-partials)) (set! min-sum new-sum)))))) (let ((new-amps (float-vector-scale! min-partials (/ original-sum min-sum))) (new-partials (copy partials))) (do ((i 0 (+ i 2))) ((>= i len)) (let ((hnum (new-partials i))) (if (= hnum 0) (set! (new-partials (+ i 1)) DC) (set! (new-partials (+ i 1)) (new-amps (- hnum 1)))))) new-partials))) #| (with-sound (:clipped #f :statistics #t :channels 2) (let* ((amps (normalize-partials (list 1 .25 2 .5 3 .25))) (gen1 (make-polywave 400.0 amps)) (gen2 (make-polywave 400.0 (flatten-partials amps)))) (do ((i 0 (+ i 1))) ((= i 44100)) (outa i (polywave gen1)) (outb i (polywave gen2))))) |# #| ;;; these are standard FFTs for s7 (define* (fft! rl im n (dir 1)) (if (not im) (let ((clear (copy rl))) (fill! clear 0.0) (set! im clear))) (if (not n) (set! n (length rl))) (do ((i 0 (+ i 1)) (j 0)) ((= i n)) (if (> j i) (let ((tempr (rl j)) (tempi (im j))) (set! (rl j) (rl i)) (set! (im j) (im i)) (set! (rl i) tempr) (set! (im i) tempi))) (let ((m (/ n 2))) (do () ((or (< m 2) (< j m))) (set! j (- j m)) (set! m (/ m 2))) (set! j (+ j m)))) (let ((ipow (floor (log n 2))) (prev 1)) (do ((lg 0 (+ lg 1)) (mmax 2 (* mmax 2)) (pow (/ n 2) (/ pow 2)) (theta (* pi dir) (* theta 0.5))) ((= lg ipow)) (let ((wpr (cos theta)) (wpi (sin theta)) (wr 1.0) (wi 0.0)) (do ((ii 0 (+ ii 1))) ((= ii prev)) (do ((jj 0 (+ jj 1)) (i ii (+ i mmax)) (j (+ ii prev) (+ j mmax))) ((>= jj pow)) (let ((tempr (- (* wr (rl j)) (* wi (im j)))) (tempi (+ (* wr (im j)) (* wi (rl j))))) (set! (rl j) (- (rl i) tempr)) (set! (rl i) (+ (rl i) tempr)) (set! (im j) (- (im i) tempi)) (set! (im i) (+ (im i) tempi)))) (let ((wtemp wr)) (set! wr (- (* wr wpr) (* wi wpi))) (set! wi (+ (* wi wpr) (* wtemp wpi))))) (set! prev mmax)))) rl) (define* (cfft! data n (dir 1)) (if (not n) (set! n (length data))) (do ((i 0 (+ i 1)) (j 0)) ((= i n)) (if (> j i) (let ((temp (data j))) (set! (data j) (data i)) (set! (data i) temp))) (let ((m (/ n 2))) (do () ((or (< m 2) (< j m))) (set! j (- j m)) (set! m (/ m 2))) (set! j (+ j m)))) (let ((ipow (floor (log n 2))) (prev 1)) (do ((lg 0 (+ lg 1)) (mmax 2 (* mmax 2)) (pow (/ n 2) (/ pow 2)) (theta (complex 0.0 (* pi dir)) (* theta 0.5))) ((= lg ipow)) (let ((wpc (exp theta)) (wc 1.0)) (do ((ii 0 (+ ii 1))) ((= ii prev)) (do ((jj 0 (+ jj 1)) (i ii (+ i mmax)) (j (+ ii prev) (+ j mmax))) ((>= jj pow)) (let ((tc (* wc (data j)))) (set! (data j) (- (data i) tc)) (set! (data i) (+ (data i) tc)))) (set! wc (* wc wpc))) (set! prev mmax)))) data) ;;; > (cfft! (list 0.0 1+i 0.0 0.0)) ;;; (1+1i -1+1i -1-1i 1-1i) ;;; ;;; > (cfft! (vector 0.0 1+i 0.0 0.0)) ;;; #(1+1i -1+1i -1-1i 1-1i) ;;; ;;; ;; check against built-in FFT ;;; > (let ((rl (float-vector 0.0 1.0 0.0 0.0)) ;;; (im (float-vector 0.0 1.0 0.0 0.0))) ;;; (mus-fft rl im) ;;; (map complex rl im)) ;;; (1+1i -1+1i -1-1i 1-1i) |# snd-16.1/gl2ps.h0000644000076400007640000001534512306421667011552 0ustar bilbil/* * GL2PS, an OpenGL to PostScript Printing Library * Copyright (C) 1999-2012 C. Geuzaine * * This program is free software; you can redistribute it and/or * modify it under the terms of either: * * a) the GNU Library General Public License as published by the Free * Software Foundation, either version 2 of the License, or (at your * option) any later version; or * * b) the GL2PS License as published by Christophe Geuzaine, either * version 2 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See either * the GNU Library General Public License or the GL2PS License for * more details. * * You should have received a copy of the GNU Library General Public * License along with this library in the file named "COPYING.LGPL"; * if not, write to the Free Software Foundation, Inc., 51 Franklin * Street, Fifth Floor, Boston, MA 02110-1301, USA. * * You should have received a copy of the GL2PS License with this * library in the file named "COPYING.GL2PS"; if not, I will be glad * to provide one. * * For the latest info about gl2ps and a full list of contributors, * see http://www.geuz.org/gl2ps/. * * Please report all bugs and problems to . */ #ifndef __GL2PS_H__ #define __GL2PS_H__ #include #include /* Define GL2PSDLL at compile time to build a Windows DLL */ #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) # if defined(_MSC_VER) # pragma warning(disable:4115) # pragma warning(disable:4996) # endif # include # if defined(GL2PSDLL) # if defined(GL2PSDLL_EXPORTS) # define GL2PSDLL_API __declspec(dllexport) # else # define GL2PSDLL_API __declspec(dllimport) # endif # else # define GL2PSDLL_API # endif #else # define GL2PSDLL_API #endif #if defined(__APPLE__) || defined(HAVE_OPENGL_GL_H) # include #else # include #endif /* Support for compressed PostScript/PDF/SVG and for embedded PNG images in SVG */ #if defined(HAVE_ZLIB) || defined(HAVE_LIBZ) # define GL2PS_HAVE_ZLIB # if defined(HAVE_LIBPNG) || defined(HAVE_PNG) # define GL2PS_HAVE_LIBPNG # endif #endif #if defined(HAVE_NO_VSNPRINTF) # define GL2PS_HAVE_NO_VSNPRINTF #endif /* Version number */ #define GL2PS_MAJOR_VERSION 1 #define GL2PS_MINOR_VERSION 3 #define GL2PS_PATCH_VERSION 8 #define GL2PS_EXTRA_VERSION "" #define GL2PS_VERSION (GL2PS_MAJOR_VERSION + \ 0.01 * GL2PS_MINOR_VERSION + \ 0.0001 * GL2PS_PATCH_VERSION) #define GL2PS_COPYRIGHT "(C) 1999-2012 C. Geuzaine" /* Output file formats (the values and the ordering are important!) */ #define GL2PS_PS 0 #define GL2PS_EPS 1 #define GL2PS_TEX 2 #define GL2PS_PDF 3 #define GL2PS_SVG 4 #define GL2PS_PGF 5 /* Sorting algorithms */ #define GL2PS_NO_SORT 1 #define GL2PS_SIMPLE_SORT 2 #define GL2PS_BSP_SORT 3 /* Message levels and error codes */ #define GL2PS_SUCCESS 0 #define GL2PS_INFO 1 #define GL2PS_WARNING 2 #define GL2PS_ERROR 3 #define GL2PS_NO_FEEDBACK 4 #define GL2PS_OVERFLOW 5 #define GL2PS_UNINITIALIZED 6 /* Options for gl2psBeginPage */ #define GL2PS_NONE 0 #define GL2PS_DRAW_BACKGROUND (1<<0) #define GL2PS_SIMPLE_LINE_OFFSET (1<<1) #define GL2PS_SILENT (1<<2) #define GL2PS_BEST_ROOT (1<<3) #define GL2PS_OCCLUSION_CULL (1<<4) #define GL2PS_NO_TEXT (1<<5) #define GL2PS_LANDSCAPE (1<<6) #define GL2PS_NO_PS3_SHADING (1<<7) #define GL2PS_NO_PIXMAP (1<<8) #define GL2PS_USE_CURRENT_VIEWPORT (1<<9) #define GL2PS_COMPRESS (1<<10) #define GL2PS_NO_BLENDING (1<<11) #define GL2PS_TIGHT_BOUNDING_BOX (1<<12) /* Arguments for gl2psEnable/gl2psDisable */ #define GL2PS_POLYGON_OFFSET_FILL 1 #define GL2PS_POLYGON_BOUNDARY 2 #define GL2PS_LINE_STIPPLE 3 #define GL2PS_BLEND 4 /* Text alignment (o=raster position; default mode is BL): +---+ +---+ +---+ +---+ +---+ +---+ +-o-+ o---+ +---o | o | o | | o | | | | | | | | | | | | +---+ +---+ +---+ +-o-+ o---+ +---o +---+ +---+ +---+ C CL CR B BL BR T TL TR */ #define GL2PS_TEXT_C 1 #define GL2PS_TEXT_CL 2 #define GL2PS_TEXT_CR 3 #define GL2PS_TEXT_B 4 #define GL2PS_TEXT_BL 5 #define GL2PS_TEXT_BR 6 #define GL2PS_TEXT_T 7 #define GL2PS_TEXT_TL 8 #define GL2PS_TEXT_TR 9 typedef GLfloat GL2PSrgba[4]; #if defined(__cplusplus) extern "C" { #endif GL2PSDLL_API GLint gl2psBeginPage(const char *title, const char *producer, GLint viewport[4], GLint format, GLint sort, GLint options, GLint colormode, GLint colorsize, GL2PSrgba *colormap, GLint nr, GLint ng, GLint nb, GLint buffersize, FILE *stream, const char *filename); GL2PSDLL_API GLint gl2psEndPage(void); GL2PSDLL_API GLint gl2psSetOptions(GLint options); GL2PSDLL_API GLint gl2psGetOptions(GLint *options); GL2PSDLL_API GLint gl2psBeginViewport(GLint viewport[4]); GL2PSDLL_API GLint gl2psEndViewport(void); GL2PSDLL_API GLint gl2psText(const char *str, const char *fontname, GLshort fontsize); GL2PSDLL_API GLint gl2psTextOpt(const char *str, const char *fontname, GLshort fontsize, GLint align, GLfloat angle); GL2PSDLL_API GLint gl2psTextOptColor(const char *str, const char *fontname, GLshort fontsize, GLint align, GLfloat angle, GL2PSrgba color); GL2PSDLL_API GLint gl2psSpecial(GLint format, const char *str); GL2PSDLL_API GLint gl2psDrawPixels(GLsizei width, GLsizei height, GLint xorig, GLint yorig, GLenum format, GLenum type, const void *pixels); GL2PSDLL_API GLint gl2psEnable(GLint mode); GL2PSDLL_API GLint gl2psDisable(GLint mode); GL2PSDLL_API GLint gl2psPointSize(GLfloat value); GL2PSDLL_API GLint gl2psLineWidth(GLfloat value); GL2PSDLL_API GLint gl2psBlendFunc(GLenum sfactor, GLenum dfactor); /* undocumented */ GL2PSDLL_API GLint gl2psDrawImageMap(GLsizei width, GLsizei height, const GLfloat position[3], const unsigned char *imagemap); GL2PSDLL_API const char *gl2psGetFileExtension(GLint format); GL2PSDLL_API const char *gl2psGetFormatDescription(GLint format); GL2PSDLL_API GLint gl2psGetFileFormat(); #if defined(__cplusplus) } #endif #endif /* __GL2PS_H__ */ snd-16.1/animals.scm0000644000076400007640000170374712562736221012514 0ustar bilbil;;; animals.scm ;;; sources: ;;; "The Diversity of Animal Sounds", Cornell Lab of Ornithology ;;; Geoffrey Keller, "Bird Songs of California" (Cornell) ;;; Geoffrey Keller, "Bird Songs of Southeastern Arizona and Sonora, Mexico" (Cornell) ;;; Bret Whitney et al, "Voices of New World Parrots" (Cornell) ;;; Carlos Davidson, "Frog and Toad Calls of the Rocky Mountains" (Cornell) ;;; Geoffrey Keller, "Bird Songs of the Lower Rio Grande Valley" (Cornell) ;;; Vyn, Budney, "Voices of North American Owls" (Cornell) ;;; Roche and Chevereau, "Guide to the Sounds of the Birds of Europe" ;;; from Richard Mankin, Reference Library of Digitized Insect Sounds, http://www.ars.usda.gov/sp2UserFiles/person/3559/soundlibrary.html ;;; Lang Elliott, Donald and Lillian Stokes, "Stokes Field Guide to Bird Songs, Eastern Region" ;;; Lang Elliott "The Calls of Frogs and Toads" ;;; Lang Elliott and W Herschberger "The Songs of the Insects" ;;; Lang Elliott "Music of the Birds" ;;; Cocroft, Morales, McDiarmid "Frogs of Tambopata, Peru" (Cornell) ;;; Ross, Whitney, "Voices of Costa Rican Birds" (Cornell) ;;; Rebolledo, Ramirez, Cuervo, "A Guide to the Bird Sounds of the Colombian Andes" (Humboldt and Cornell) ;;; Emmons, Whitney, Ross, "Sounds of Neotropical Rainforest Mammals" (Cornell) ;;; Marantz, Zimmer, "Bird Voices of the Alta Floresta" (Cornell) ;;; "Voices of the Night" (Cornell) ;;; Keller, Vyn, "Bird Songs of the Pacific Northwest" (Cornell) ;;; -------- frogs and toads -------- ;;; Oak toad ;;; Knudsen's frog ;;; Southern cricket frog ;;; Northern leopard frog (2) ;;; Spring peeper ;;; Crawfish frog ;;; River frog ;;; Green tree-frog ;;; Pinewoods tree frog ;;; Squirrel tree frog ;;; Ornate chorus frog ;;; Bullfrog ;;; Texas toad ;;; American toad ;;; Plains spadefoot ;;; Barking tree-frog ;;; Western toad ;;; Southwestern toad ;;; Great Plains Narrow-mouthed toad ;;; Pacific chorus frog ;;; Red-spotted toad ;;; Green toad ;;; Little grass frog ;;; Sonoran desert toad ;;; Amargosa toad ;;; -------- mammals -------- ;;; Indri ;;; -------- insects -------- ;;; mosquito ;;; Long-spurred meadow katydid ;;; Handsome trig ;;; Dog-day cicada ;;; Linnaeus' cicada ;;; Lyric cicada ;;; Southern mole cricket ;;; Confused ground cricket ;;; Tinkling ground cricket ;;; Striped ground cricket ;;; Sphagnum ground cricket ;;; Southeastern field cricket ;;; Snowy tree cricket ;;; Pine tree cricket ;;; Davis's tree cricket ;;; Broad-winged tree cricket ;;; Fast-calling tree cricket ;;; Black-horned tree cricket ;;; Narrow-winged tree cricket ;;; Four-spotted tree cricket ;;; Marsh meadow grasshopper ;;; Carolina grasshopper ;;; Slightly musical conehead ;;; -------- birds -------- ;;; Fox sparrow ;;; White-throated sparrow ;;; Henslow's sparrow ;;; Field sparrow ;;; Savannah sparrow ;;; Chipping sparrow ;;; Bachman's sparrow ;;; Grasshopper sparrow ;;; Black-chinned sparrow ;;; Golden-crowned sparrow ;;; Cassin's sparrow ;;; Song sparrow ;;; Sage sparrow ;;; House sparrow ;;; Black-throated sparrow ;;; Dark-eyed junco ;;; Purple finch ;;; House finch ;;; Gray-crowned rosy-finch ;;; Eastern wood-pewee (2) ;;; Western wood-pewee (2) ;;; Greater pewee ;;; Tufted titmouse ;;; Oak titmouse ;;; Bushtit ;;; Wrentit ;;; California towhee ;;; Green-tailed towhee ;;; Carolina wren ;;; Warbling vireo ;;; Plumbeous vireo (2) ;;; Cassin's vireo ;;; Hutton's vireo ;;; Gray vireo (5) ;;; Yellow-green vireo ;;; Red-eyed vireo ;;; White-eyed vireo ;;; Philadelphia vireo ;;; Nashville warbler ;;; Orange-crowned warbler ;;; Yellow warbler ;;; Yellow-rumped warbler ;;; Lucy's warbler ;;; Macgillivray's warbler ;;; Wilson's warbler ;;; Magnolia warbler ;;; Chestnut-sided warbler ;;; Black-throated blue warbler ;;; Pine warbler ;;; Cape May warbler ;;; Kirtland's warbler ;;; Verdin ;;; Townsend's solitaire ;;; Cedar waxwing ;;; Western meadowlark ;;; Eastern meadowlark ;;; Ruby-crowned kinglet ;;; Least flycatcher ;;; Acadian flycatcher ;;; Vermillion flycatcher ;;; Ash-throated flycatcher ;;; Olive-sided flycatcher ;;; Willow flycatcher ;;; Hammond's flycatcher ;;; Pacific-slope flycatcher ;;; Dusky flycatcher ;;; Yellow-bellied flycatcher ;;; Great crested flycatcher ;;; Brown-crested flycatcher (2) ;;; Black phoebe ;;; Say's phoebe ;;; Northern beardless tyrannulet ;;; Great kiskadee ;;; Scrub euphonia ;;; Eastern bluebird ;;; Common yellowthroat ;;; Blue grosbeak ;;; Evening grosbeak ;;; Cardinal ;;; American robin ;;; Scott's oriole ;;; Swainson's thrush ;;; Varied thrush ;;; Hermit thrush ;;; Western tanager ;;; Summer tanager ;;; Chuck-will's-widow ;;; Whip-poor-will ;;; Lesser nighthawk ;;; Common pauraque ;;; Mourning dove ;;; Inca dove (2) ;;; White-tipped dove ;;; Bobwhite ;;; California quail ;;; Gambel's quail ;;; Scaled quail ;;; Montezuma quail ;;; Mountain quail ;;; Ruffed grouse ;;; Great-horned owl ;;; Barred owl ;;; Flammulated owl ;;; Burrowing owl ;;; Barn owl ;;; Long-eared owl ;;; Northern goshawk ;;; Red-shouldered hawk ;;; Zone-tailed hawk ;;; Bald eagle ;;; Crested caracara ;;; Pileated woodpecker ;;; White-headed woodpecker ;;; Acorn woodpecker ;;; Hairy woodpecker ;;; Red-breasted nuthatch ;;; White-breasted nuthatch ;;; Pygmy nuthatch ;;; Common loon (2) ;;; American crow ;;; Brown jay ;;; Steller's jay ;;; Pinyon jay ;;; Groove-billed ani ;;; Loggerhead shrike (2) ;;; Greater roadrunner ;;; Common Gull ;;; Willet ;;; Black-necked stilt ;;; Whooping crane ;;; Sandhill crane ;;; Trumpeter swan ;;; Canada goose ;;; Wood duck ;;; Black-crowned night heron ;;; Least bittern ;;; Black rail ;;; Virginia rail ;;; Sora ;;; Plain chacalaca ;;; Black-billed cuckoo ;;; Eared grebe ;;; Killdeer (provide 'snd-animals.scm) (require snd-generators.scm) ;; rk!cos blackman=polywave rcos rxycos (if (provided? 'snd) (require snd-ws.scm) (require sndlib-ws.scm)) (set! *clm-default-frequency* 0.0) (define-macro (defanimal args . body) (let ((name (car args)) (targs (cdr args))) `(begin (define (,name ,@targs) (if *clm-notehook* (*clm-notehook* (symbol->string ',name) ,@targs)) ,@body) ,@(if *definstrument-hook* (list (*definstrument-hook* name targs)) (list))))) #| (define-macro (defanimal args . body) (let ((name (car args)) (targs (cdr args))) `(begin (define (,name ,@targs) (if *clm-notehook* (*clm-notehook* (symbol->string ',name) ,@targs)) (let ((start (get-internal-real-time))) ,@body (format #t "~A: ~A~%" (- (get-internal-real-time) start) ,name))) ,@(if *definstrument-hook* (list (*definstrument-hook* name targs)) (list))))) |# #| ;;; ================================================================================ ;;; useful settings and functions for this work (I have these in my init file): (define (clean-string e) ;; make the envelope lists look prettier (format #f "(~{~,3F~^ ~})" e)) (define (seldur) (list (/ (selection-framples) 44100.0) (selection-maxamp))) (define (sp) (* 22050 (spectrum-end 0 0))) ;;; save us some dialog setup (set! (show-transform-peaks) #t) (set! (transform-size) 512) (set! (fft-window) blackman10-window) (set! (colormap) 7) ; jet (set! (speed-control-style) speed-control-as-ratio) (set! (color-cutoff) .001) (set! (enved-clip?) #t) ;;; if click play button and there's a selection, play the selection ;;; otherwise if the file is long (like most bird recordings), play what's in the current window. ;;; This is mainly to cut out the ubiquitous and useless announcer. (if (null? (hook-functions start-playing-hook)) (hook-push start-playing-hook (lambda (hook) (let ((snd (hook 'snd))) (if (sound? snd) ; meaning not 123456 = temp-sound-index from View:Files play button (if (and (selection?) (selection-member? snd)) (begin (play (selection)) #t) (if (> (framples snd) (* 10 (srate snd))) (let ((chn (or (selected-channel) 0))) (with-temporary-selection (lambda () (play (selection))) (left-sample snd chn) (- (right-sample snd chn) (left-sample snd chn)) snd chn) #t) #f)) #f))))) ;;; precision window movements via arrow keys (define (move-one-pixel s c right) (let* ((ax (axis-info s c time-graph)) (lo (ax 0)) (hi (ax 1)) (lo-pix (ax 10)) (hi-pix (ax 12)) (samps-per-pixel (max 1 (round (/ (- hi lo) (- hi-pix lo-pix))))) (change (if right (- (min (+ hi samps-per-pixel) (framples s c)) hi) (- (max 0 (- lo samps-per-pixel)) lo)))) (set! (left-sample) (min (max 0 (+ lo change)) (framples s c))) keyboard-no-action)) (bind-key "Left" 0 (lambda () "move one pixel backward" (move-one-pixel (selected-sound) (selected-channel) #f))) (bind-key "Right" 0 (lambda () "move one pixel forward" (move-one-pixel (selected-sound) (selected-channel) #t))) (define (move-more-pixels s c right) (let* ((ax (axis-info s c time-graph)) (lo (ax 0)) (hi (ax 1)) (lo-pix (ax 10)) (hi-pix (ax 12)) (samps-per-pixel (* 8 (max 1 (round (/ (- hi lo) (- hi-pix lo-pix)))))) (change (if right (- (min (+ hi samps-per-pixel) (framples s c)) hi) (- (max 0 (- lo samps-per-pixel)) lo)))) (set! (left-sample) (min (max 0 (+ lo change)) (framples s c))) keyboard-no-action)) (bind-key "Left" 4 (lambda () "move some pixels backward" (move-more-pixels (selected-sound) (selected-channel) #f))) (bind-key "Right" 4 (lambda () "move some pixels forward" (move-more-pixels (selected-sound) (selected-channel) #t))) (define (zoom-one-pixel s c in) (let* ((ax (axis-info s c time-graph)) (lo (ax 0)) (hi (ax 1)) (lo-pix (ax 10)) (hi-pix (ax 12)) (samps-per-pixel (max 1 (round (/ (- hi lo) (- hi-pix lo-pix))))) (len (framples s c))) (if in (if (> (- hi-pix lo-pix) samps-per-pixel) (begin (set! (left-sample) (+ lo samps-per-pixel)) (set! (x-zoom-slider) (* 1.0 (/ (max samps-per-pixel (- hi lo (* 2 samps-per-pixel))) len))))) (begin (set! (left-sample) (max 0 (- lo samps-per-pixel))) (set! (x-zoom-slider) (* 1.0 (/ (min len (+ (- hi lo) (* 2 samps-per-pixel))) len))))) keyboard-no-action)) (bind-key "Up" 0 (lambda () "zoom out one pixel" (zoom-one-pixel (selected-sound) (selected-channel) #f))) ;up (bind-key "Down" 0 (lambda () "zoom in one pixel" (zoom-one-pixel (selected-sound) (selected-channel) #t))) ;down ;;; save the current window so that PageUp returns to it (bind-key "Page_Down" 0 (lambda () (let ((last-page-state (map (lambda (snd) (let ((data (list snd (file-name snd)))) (do ((i 0 (+ i 1))) ((= i (channels snd)) data) (set! data (append data (list (cons i (axis-info snd i)))))))) (sounds)))) (bind-key "Page_Up" 0 (lambda () (if last-page-state (for-each (lambda (lst) (let ((snd (lst 0)) (name (lst 1))) (if (and (sound? snd) (string=? (file-name snd) name)) (for-each (lambda (chan-data) (let ((chn (chan-data 0)) (x0 (chan-data 3)) (x1 (chan-data 5)) (y0 (chan-data 4)) (y1 (chan-data 6))) (set! (x-bounds snd chn) (list x0 x1)) (set! (y-bounds snd chn) (list y0 y1)))) (cddr lst))))) last-page-state))))))) ;;; "m" -> make enved amp display suitable for drawing the amp env (bind-key #\m 0 (lambda () (set! (y-bounds (selected-sound) (selected-channel)) (list 0 (selection-maxamp)))) #t) ;;; "C-m" returns to normal after "m" (bind-key #\m 4 (lambda () (set! (y-bounds (selected-sound) (selected-channel)) (list -1.0 1.0))) #t) |# ;;; ================================================================================ ;;; some of these need srate=44100 since various frequencies are (well) over 10KHz ;;; also, I have bare indices scattered around -- ideally these would be wrapped in hz->radians ;;; these were done more or less in the order they occur within a section ;;; ================ Frogs and Toads ================ ;;; ;;; ;;; Knudsen's frog (defanimal (a-frog beg dur freq amp amp-env gliss gliss-env pulse-dur pulse-env fm-index fm-freq) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (base (make-oscil freq)) (modm (make-oscil fm-freq)) (frqf (make-env (or gliss-env '(0 0 1 0)) :duration dur :base 32 :scaler (hz->radians gliss))) (pulse (make-pulsed-env pulse-env pulse-dur (/ 1.0 pulse-dur))) (ampf (make-env amp-env :duration dur :scaler amp)) (index (hz->radians (* fm-freq fm-index)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (pulsed-env pulse) (oscil base (+ (env frqf) (* index (oscil modm))))))))) (define (knudsens-frog beg amp) (a-frog beg .25 480 amp '(0 0 1 1 3 1 4 0) 50 '(0 0 .5 .2 .8 1 1 1) (/ .25 7) '(0 .1 .5 .4 .6 .75 1 .9 1.5 1 2 .9 2.3 .1) 1.75 40)) ; 0.01 here is about 1.75 as an fm index: (/ (radians->hz .01) 40) #| ;;; cricket-like: (with-sound (:play #t) (a-frog 0 .25 2000 .5 '(0 0 1 1 3 1 4 0) ; or 3000 6000 etc 50 '(0 0 .5 .2 .8 1 1 1) (/ .25 5) '(0 0 1 0 5 1 8 0 20 0) 0.01 40)) (with-sound (:play #t) (a-frog 0 .25 4000 .5 '(0 0 1 1 3 1 4 0) 0 #f (/ .25 10) '(0 0 1 1 2 1 4 0 10 0) 0.0 10)) ;;; frog-like (with-sound (:play #t) (a-frog 0 .25 2000 .5 '(0 0 1 1 3 1 4 0) 50 '(0 0 .5 .2 .8 1 1 1) (/ .25 10) '(0 0 1 1 2 1 3 0 4 0 5 1 7 1 8 0 20 0) 0.0 10)) |# (defanimal (a-cricket beg dur freq freq1 amp amp-env pulse-dur pulse-env) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (base (make-oscil freq)) (base1 (make-oscil freq1)) (pulse (make-pulsed-env pulse-env pulse-dur (/ 1.0 pulse-dur))) (ampf (make-env amp-env :duration dur :scaler amp))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (pulsed-env pulse) (+ (* .8 (oscil base)) (* .2 (oscil base1)))))))) ;; (with-sound (:play #t) (a-cricket 0 .12 4500 5400 .5 '(0 0 1 1 3 1 4 0) (/ .11 3) '(0 0 1 .8 5 1 6 0 15 0))) ;;; -------------------------------------------------------------------------------- ;;; ;;; Oak Toad ;;; might be slightly too much noise (the peep I worked on turned out to be a raspy one) (defanimal (oak-toad beg amp) (let ((dur .15) (start (seconds->samples beg))) (let ((stop (seconds->samples (+ beg dur))) (ampf (make-env '(0 0 10 1 15 0) :base .3 :duration dur :scaler amp)) (gen1 (make-polywave 2150 '(1 .01 2 1.0 3 .001 4 .005 6 .02))) (frqf (make-env '(0 -.5 1 1 5 -1) :duration .15 :scaler (hz->radians (+ 50 (random 40))))) (noise (make-rand-interp 1000 (+ .01 (random .005))))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (+ (env frqf) (rand-interp noise))))))))) #| (with-sound (:play #t) (let ((last-beg 0.0)) (do ((k 0 (+ k 1))) ((= k 12)) (let ((beg (+ last-beg .37 (random .08)))) (oak-toad beg (+ .25 (random .3))) (set! last-beg beg))))) |# ;;; (with-sound (:play #t) (oak-toad 0 .25)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Southern cricket frog (defanimal (southern-cricket-frog beg amp) (let ((dur1 .03) (start (seconds->samples beg))) (let ((stop (seconds->samples (+ beg dur1))) (ampf (make-env '(0 0 .75 1 5 1 10 0) :scaler amp :duration dur1)) (gen1 (make-oscil 3500)) (gen2 (make-oscil 6400)) (pulse (make-pulsed-env '(0 .1 1 .6 2 .8 3 1 6 .1 8 .1) (/ dur1 8) (/ 8 dur1))) (index (hz->radians 300)) (f1 (make-env '(0 .9 9 .9 10 0) :duration dur1)) (f2 (make-env '(0 .05 8 .1 10 .8 11 .1) :duration dur1)) (fm (make-oscil 150))) (do ((i start (+ i 1))) ((= i stop)) (let ((fm1 (* index (oscil fm)))) (outa i (* (env ampf) (pulsed-env pulse) (+ (* (env f1) (oscil gen1 fm1)) (* (env f2) (oscil gen2 (* 2 fm1))))))))))) ;; (with-sound (:play #t) (southern-cricket-frog 0 0.5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Northern leopard frog (2) (defanimal (northern-leopard-frog-1 beg amp) ;; this is slightly low-passed, and I don't quite have the vowel right at the end (let ((dur 4.2)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (gen1 (make-oscil 440)) (gen2 (make-oscil 1030)) ; there's also a 1500 formant that follows the 1000 case -- looks a lot like FM index 1 ca 600Hz (gen3 (make-oscil 2600)) (pulsef1 (make-env '(0 0 .1 1 10 0) :duration .013 :base 32.0)) (pulsef2 (make-env '(0 0 4 1 10 0) :duration .013 :base 3.0)) (interpf (make-env '(0 0 6 1 8 1 10 .5) :duration dur)) (ampf (make-env '(0 0 3 1 9.5 1 10 0) :base .2 :duration dur :scaler amp)) (gen1f (make-env '(0 1 8 1 10 0) :duration dur :scaler .65 :base 3)) (gen2f (make-env '(0 0 8 0 10 1) :duration dur :scaler (hz->radians 90))) (gen3f (make-env '(0 1 6 1 10 0) :duration dur :offset (hz->radians 2200) :scaler (hz->radians 400))) (gen4f (make-env '(0 0 8 0 10 .02) :duration dur)) (gen5f (make-env '(0 0 5 0 10 -1) :duration dur :scaler (hz->radians 200))) (pulf (make-env (list 0.0 (/ 1.0 14.0) 2.0 (/ 1.0 11.0) 10.0 (/ 1.0 11.0)) :duration dur)) (gen6 (make-polywave 170 '(1 .075))) (pulse-samps (seconds->samples 0.013))) (let ((pulse-sep (seconds->samples (env pulf)))) (do ((i start (+ i pulse-sep))) ((>= i stop)) (let ((pstop (+ i pulse-samps))) (set! (mus-location interpf) (- i start)) (set! (mus-location ampf) (- i start)) (set! (mus-location gen1f) (- i start)) (set! (mus-location gen2f) (- i start)) (set! (mus-location gen3f) (- i start)) (set! (mus-location gen4f) (- i start)) (set! (mus-location gen5f) (- i start)) (let ((intrp (env interpf)) (gen1trp (env gen1f)) (gen2trp (env gen2f)) (gen3trp (env gen3f)) (gen4trp (env gen4f)) (gen5trp (env gen5f)) (pulse-amp (env ampf))) (let ((intrp-1 (- 1.0 intrp)) (gen1trp-1 (- 1.0 gen1trp)) (gen4trp-1 (- 1.0 gen4trp))) (do ((k i (+ k 1))) ((= k pstop)) (outa k (* pulse-amp (+ (* intrp (env pulsef1)) (* intrp-1 (env pulsef2))) (+ (* gen1trp (oscil gen2 gen5trp)) (* gen1trp-1 (+ (* gen4trp-1 (oscil gen1 gen2trp)) (* gen4trp (oscil gen3 (+ gen3trp (polywave gen6)))))))))))) (mus-reset pulsef1) (mus-reset pulsef2) (mus-reset gen1) (mus-reset gen2) (set! (mus-location pulf) (- (+ i pulse-sep) start)) (set! pulse-sep (seconds->samples (env pulf))))))))) ;; (with-sound (:statistics #t :play #t) (northern-leopard-frog-1 0 .5)) (defanimal (northern-leopard-frog-2 beg amp) ;; rocky 57 2 (let ((start (seconds->samples beg)) (dur 1.53) (pulse-dur .03)) (let ((stop (seconds->samples (+ beg dur))) (pulse-samps (seconds->samples .045)) (pulse-out (seconds->samples pulse-dur)) (ampf (make-env '(0.000 0.108 0.118 0.596 0.167 0.719 0.357 0.827 0.604 0.838 0.745 0.912 0.860 1.000 0.929 0.962 0.984 0.831 1.000 0.000) :duration dur :scaler amp)) (frqf2 (make-env '(0.000 0.198 0.021 0.209 0.110 0.239 0.178 0.239 0.294 0.247 0.343 0.260 0.463 0.255 0.593 0.265 0.704 0.252 0.788 0.244 0.881 0.228 0.941 0.204 1.000 0.18) :duration dur :scaler 6100.0)) (frqf1 (make-env '(0.000 0.086 0.462 0.110 1.000 0.118) :duration dur :scaler 6100.0)) (frqf3 (make-env '(0.000 0.721 0.508 0.786 0.698 0.761 0.876 0.689 0.935 0.563 1.000 0.509) :duration dur :scaler 6100.0)) (frqf4 (make-env '(0 7200 .5 7600 .9 7000 1 5400) :duration dur)) (frm1 (make-formant 900 .995)) (frm2 (make-formant 1260 .99)) (frm3 (make-formant 4500 .99)) (frm4 (make-formant 7200 .9)) (ampfr1 (make-env '(0 .5 1 3) :duration dur :scaler (* 2 5 (sin (hz->radians 900))) :base 3)) (ampfr2 (make-env '(0 .25 .5 .4 1 1) :duration dur :scaler (* 2 5 (sin (hz->radians 1260))))) (ampfr4 (make-env '(0 0 .3 1 1 1) :duration dur :scaler (* 2 5 (sin (hz->radians 7200))))) (ampfr3 (* 2 5 (sin (hz->radians 4500)))) (gen1 (make-rk!cos 100 13.0)) (ampf1 (make-env '(0 1 1 0) :base 3 :duration dur)) (pulsef (make-env '(0.000 0.000 0.01 1 0.15 0.936 0.2 0.100 0.792 0.000 0.906 0.107 1.000 0.000) :duration pulse-dur)) (pulse-frqf (make-env '(0 0 1 .9 2 1 ) :base .1 :duration pulse-dur :scaler (hz->radians 100)))) (let ((fb (vector frm1 frm2 frm3 frm4)) (fs (float-vector 0.0 0.0 ampfr3 0.0)) (rk (make-float-vector pulse-out))) (set! fb (make-formant-bank fb fs)) (do ((i start (+ i pulse-samps))) ((>= i stop)) (set! (mus-location ampf) (- i start)) (set! (mus-location ampf1) (- i start)) (set! (mus-location ampfr1) (- i start)) (set! (mus-location ampfr2) (- i start)) (set! (mus-location ampfr4) (- i start)) (set! (mus-location frqf1) (- i start)) (set! (mus-location frqf2) (- i start)) (set! (mus-location frqf3) (- i start)) (set! (mus-location frqf4) (- i start)) (set! (mus-location ampfr1) (- i start)) (set! (mus-location ampfr2) (- i start)) (set! (mus-location ampfr4) (- i start)) (set! (mus-frequency frm1) (env frqf1)) (set! (mus-frequency frm2) (env frqf2)) (set! (mus-frequency frm3) (env frqf3)) (set! (mus-frequency frm4) (env frqf4)) (let ((reset-stop (min stop (+ i pulse-out))) (pulse-amp (env ampf)) (val-amp (env ampf1))) (set! (fs 0) (env ampfr1)) (set! (fs 1) (env ampfr2)) (set! (fs 3) (env ampfr4)) (do ((k 0 (+ k 1))) ((= k pulse-out)) (set! (rk k) (rk!cos gen1 (env pulse-frqf)))) (do ((k i (+ k 1))) ((= k reset-stop)) (let ((val (* pulse-amp (env pulsef) (rk (- k i))))) ;(rk!cos gen1 (env pulse-frqf))))) (outa k (+ (* val val-amp) (formant-bank fb val))))) (set! (mus-phase gen1) (* -0.1 pi)) (mus-reset pulse-frqf) (mus-reset pulsef))))))) ;; (with-sound (:play #t :statistics #t) (northern-leopard-frog-2 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Green tree-frog (defanimal (green-tree-frog beg amp) (let ((dur 0.2) (pitch 277) (start (seconds->samples beg))) (let ((stop (seconds->samples (+ beg dur))) (ampf (make-env '(0 0 1 1 8 1 12 0) :scaler (* .333 amp) :duration dur)) (gen2770 (make-oscil (* 10 pitch) (* 0.5 pi))) (mod277 (make-oscil pitch (* 0.5 pi))) (gen7479 (make-oscil (* pitch 27))) (poly (make-polywave pitch (list 3 (* .78 .3) 8 (* .78 .2) 9 (* .78 .2) 10 (* .78 .9) 11 0.78 12 (* .78 .5)))) (poly2 (make-polywave 860 (list 1 (* .25 .4) 2 (* .25 .1) 3 (* .25 .03) 4 (* .25 .3) 5 (* .25 .03)))) (index (hz->radians 277)) (frqf (make-env '(0 -.3 1 .3 2 0 5 0 6 -1) :duration dur :scaler (hz->radians 70))) (pulsef (make-pulsed-env '(0 .2 1 1 3 .7 5 .2) (/ 1.0 pitch) pitch))) (do ((i start (+ i 1))) ((= i stop)) (let ((md (* index (oscil mod277))) (frq (env frqf))) (outa i (* (env ampf) (pulsed-env pulsef frq) (+ (polywave poly frq) (* .2 (oscil gen2770 (* 10 (+ frq md)))) (* .02 (oscil gen7479 (* 27 (+ frq md)))) (polywave poly2 (* 3.0 frq)))))))))) ;; (with-sound (:play #t) (green-tree-frog 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Pinewoods tree-frog (defanimal (pinewoods-tree-frog beg dur amp) (let ((pitch 205.0) (pulse-dur .009) (start (seconds->samples beg)) (stop (seconds->samples (+ beg dur)))) (let ((pulsef (make-env '(0.000 0.000 0.065 0.5 0.117 0.85 0.179 1.0 0.236 0.9 0.503 0.4 0.606 0.2 1.000 0.000) :duration pulse-dur)) (pulses (if (> (random 1.0) .6) 5 4)) (pulse-amps (apply vector (map (lambda (x) (* amp x)) '(.7 .9 1.0 .9 .6)))) (gen1 (make-oscil (* pitch 10) (* 0.5 pi))) (gen3 (make-oscil (* pitch 18) (* 0.5 pi))) (gen4 (make-oscil (* pitch 28) (* 0.5 pi))) (pulse-samps (seconds->samples pulse-dur)) (pulse-sep (seconds->samples 0.078)) (rnd (make-rand-interp (* 10 pitch) (hz->radians (* 3 pitch))))) ; not sure this actually helps (do ((i start (+ i pulse-sep))) ((>= i stop)) (do ((pulse 0 (+ pulse 1)) (pulse-start i (+ pulse-start pulse-samps))) ((= pulse pulses)) (let ((pulse-amp (pulse-amps pulse)) (pulse-stop (+ pulse-start pulse-samps))) (if (< pulse 3) (set! (mus-frequency gen1) (* pitch 10)) (set! (mus-frequency gen1) (* pitch 11))) (do ((k pulse-start (+ k 1))) ((= k pulse-stop)) (let ((noise (rand-interp rnd))) (outa k (* pulse-amp (env pulsef) (+ (* .9 (oscil gen1 (* .1 noise))) (* .08 (oscil gen3 (* .18 noise))) (* .02 (oscil gen4 (* .28 noise)))))))) (mus-reset pulsef) (set! (mus-phase gen1) (* 0.5 pi)) (set! (mus-phase gen3) (* 0.5 pi)) (set! (mus-phase gen4) (* 0.5 pi)))) (set! pulses (if (> (random 1.0) .6) 5 4)))))) ;; (with-sound (:play #t) (pinewoods-tree-frog 0 1 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Squirrel tree frog (defanimal (squirrel-tree-frog beg dur amp) (let ((pitch 120) (pulse-dur 0.24)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (gen1 (make-blackman pitch 4)) (gen2 (make-oscil (* 10 pitch))) (gen3 (make-oscil (* 24 pitch))) (gen4 (make-polywave pitch (list 1 (hz->radians .1)))) (gen5 (make-oscil (* 14 pitch))) (gen6 (make-oscil (* 6 pitch))) (rnd (make-rand-interp 100 (hz->radians 5))) (frqf (make-env '(0 0 .2 0 .4 .75 .8 1 1.0 .5) :duration pulse-dur :scaler (hz->radians 15))) (pulsef (make-env '(0 0 .5 .7 2 1 3.5 .7 4 0) :duration pulse-dur :scaler amp)) (pulse-samps (seconds->samples 0.52)) (pulse-out (seconds->samples pulse-dur)) (indf (make-env '(0 .3 1 .5 2 .5 3 0) :duration pulse-dur)) (indf-1 (make-env '(0 .3 1 .5 2 .5 3 0) :offset 1.0 :scaler -1.0 :duration pulse-dur))) (do ((i start (+ i pulse-samps))) ((>= i stop)) (let ((reset-stop (min stop (+ i pulse-out)))) (do ((k i (+ k 1))) ((= k reset-stop)) (let ((ind (+ (env frqf) (polywave gen4) (rand-interp rnd)))) (outa k (* (env pulsef) (blackman gen1) (+ (* (env indf) (oscil gen2 (* 10.0 ind))) (* (env indf-1) (oscil gen3 (* 24.0 ind))) (* .1 (oscil gen5 (* 14.0 ind))) (* .1 (oscil gen6 (* 6.0 ind)))))))) (mus-reset frqf) (mus-reset pulsef) (mus-reset indf-1) (mus-reset indf)))))) ;;; (with-sound (:play #t) (squirrel-tree-frog 0 1.0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Ornate chorus frog (defanimal (ornate-chorus-frog beg dur amp) (let ((pulse-dur 0.024) (pitch 1210) (start (seconds->samples beg)) (stop (seconds->samples (+ beg dur)))) (let ((pulsef (make-env '(0.000 0.000 0.057 0.445 0.124 0.797 0.220 0.977 0.337 1.000 0.477 0.987 0.634 0.907 0.760 0.791 0.828 0.475 0.913 0.206 1.000 0.000) :scaler amp :duration pulse-dur)) (gen1 (make-polywave pitch '(1 .02 2 .95 3 .01 4 .02 5 .01 6 .04 7 .01 8 .02))) (next-pulse (seconds->samples .4)) (pulse-samps (seconds->samples pulse-dur))) (do ((i start (+ i next-pulse))) ((>= i stop)) (let ((reset-stop (min stop (+ i pulse-samps)))) (do ((k i (+ k 1))) ((= k reset-stop)) (outa k (* (env pulsef) (polywave gen1)))) (mus-reset pulsef) (if (> (random 1.0) .8) (set! next-pulse (seconds->samples (+ .25 (random .3)))) (set! next-pulse (seconds->samples .4)))))))) ;; (with-sound (:play #t) (ornate-chorus-frog 0 4 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Spring peeper (defanimal (spring-peeper beg amp) (let ((dur 0.17) (pause 0.23) (dur2 .13) (index (hz->radians (* 0.1 2900)))) ;; first note (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0 0 .25 .6 8 1 10 .8 10.5 0) :scaler amp :duration dur :base .03)) (gen1 (make-oscil 2400)) (gen2 (make-oscil 1200)) (gen2a (make-oscil 2400)) (frqf (make-env '(0 0 1 1) :scaler (hz->radians 600) :duration dur :base 30.0))) (do ((i start (+ i 1))) ((= i stop)) (let ((frq (env frqf))) (outa i (* (env ampf) (oscil gen1 (+ frq (* index (+ (* 0.2 (oscil gen2 (* 0.5 frq))) (* 1.5 (oscil gen2a frq)))))))))) ; end is not quite right (original has a catch) ;; second note (let ((start2 (+ stop (seconds->samples pause)))) (let ((stop2 (+ start2 (seconds->samples dur2))) (ampf2 (make-env '(0 0 .125 .8 1 .9 2 .7 4 1 10 0) :base .1 :duration dur2 :scaler (* .4 amp))) (frqf2 (make-env '(0 0 2 1 3 .75) :duration dur2 :base .03 :scaler (hz->radians 300))) (gen3 (make-oscil 2900)) (gen4 (make-oscil 1450))) (do ((i start2 (+ i 1))) ((= i stop2)) (let ((frq (env frqf2))) (outa i (* (env ampf2) (oscil gen3 (+ frq (* index (oscil gen4 (* 0.5 frq)))))))))))))) ;; (with-sound (:play #t) (spring-peeper 0 .5)) ;;;-------------------------------------------------------------------------------- ;;; ;;; Crawfish frog (defanimal (crawfish-frog beg amp) (let ((dur 0.6) (pitch 58)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0 0 4 1 8 1 9 .7 10 0) :scaler amp :duration dur)) (pulse-samps (seconds->samples (/ 1.0 pitch))) (pulsef (make-env '(0 0 1 1 10 0) :base 32.0 :duration (/ 1.0 pitch))) (fmd (make-oscil pitch)) (gen1 (make-oscil (* pitch 15))) (frqf (make-env '(0 .5 .2 0 1 1) :scaler (hz->radians pitch) :base 10.0 :duration dur)) (index (hz->radians pitch)) (poly1 (make-polywave (* pitch 6) '(1 .5 2 1 5 .5))) (poly2 (make-polywave (* pitch 6) '(2 .5 3 1 7 .25))) (intrp (make-env '(0 1 1 0) :duration dur :scaler .2 :base 4)) (intrp-1 (make-env '(0 0 1 1) :duration dur :scaler .2 :base .25))) (do ((i start (+ i pulse-samps))) ((>= i stop)) (set! (mus-location ampf) (- i start)) (let ((reset-stop (min stop (+ i pulse-samps))) (pulse-amp (env ampf))) (do ((k i (+ k 1))) ((= k reset-stop)) (let ((frq (env frqf))) (outa k (* pulse-amp (env pulsef) (+ (* .5 (oscil gen1 (+ frq (* index (oscil fmd (* frq .067)))))) (* (env intrp) (polywave poly1 frq)) (* (env intrp-1) (polywave poly2 frq))))))) (mus-reset pulsef) (mus-reset gen1) (mus-reset fmd)))))) ;; (with-sound (:play #t) (crawfish-frog 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; River frog ;;; ;;; original formants were much sharper, but using rxyk!cos to sharpen ours didn't seem to help ;;; animal seems to group these in 3's (defanimal (river-frog beg amp) (let ((dur 1.85) (pulse-pitch 42) (mid-pitch 185) (mid-pitch-change 10)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0 0 2 1 7 .9 10 0) :scaler amp :duration dur :base .1)) (pulsef #f) (pulse-samps (seconds->samples (/ 1.0 pulse-pitch))) (frqf (make-env '(0 .1 .2 -.02 .5 0 .65 0 1 1) :scaler (hz->radians mid-pitch-change) :duration dur)) (vib (make-rand-interp 100 (hz->radians 10.0))) (fm (make-polywave pulse-pitch (list 1 (hz->radians pulse-pitch)) mus-chebyshev-second-kind)) ;; cheb2 is needed here to match the original code which used (* index (oscil fm)) ;; if cheb1, the main sideband is below rather than above, giving the frog a deeper call ;; does this make any sense?!? (poly1 (make-polywave mid-pitch (normalize-partials '(2 1.2 4 .1 7 0.75 8 .1 10 .5)))) (poly2 (make-polywave mid-pitch (normalize-partials '(2 1.0 7 .5 9 .7 12 .01)))) (interpf (make-env '(0 0 2 0 5 1 7 1) :duration dur)) (interpf-1 (make-env '(0 0 2 0 5 1 7 1) :duration dur :offset 1.0 :scaler -1.0))) (do ((i start (+ i pulse-samps))) ((>= i stop)) (set! (mus-location ampf) (- i start)) (let ((reset-stop (min stop (+ i pulse-samps))) (pulse-amp (env ampf))) (set! pulsef (make-env '(0 .1 3 .1 3.1 1 4 1 6 .1 9 .1) :scaler pulse-amp :duration (/ 1.0 pulse-pitch))) (do ((k i (+ k 1))) ((= k reset-stop)) (let ((frq (+ (env frqf) (rand-interp vib) (polywave fm)))) (outa k (* (env pulsef) (+ (* (env interpf-1) (polywave poly1 frq)) (* (env interpf) (polywave poly2 frq)))))))))))) ;;; pulsed-env here was basically the same speed as using the nested do loop ;;; pulsed-env doesn't buy us anything if there's no run-time modulation ;; (with-sound (:play #t :statistics #t) (river-frog 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Bullfrog (defanimal (bullfrog beg amp) (let ((start (seconds->samples beg)) (dur 0.81)) (let ((stop (seconds->samples (+ beg dur))) (ampf (make-env '(0 0 1 1 2 1 3 0) :duration dur :scaler amp :base 10)) (frqf (make-env '(0 0 1 6 2 0) :duration dur :scaler (hz->radians 1.0))) (f1 (make-rxyk!cos 200 (/ 100 200) 0.6)) (f2 (make-rxyk!cos 230 (/ 100 230) 1.2)) (f3 (make-rxyk!cos 600 (/ 100 600) 8.0)) (f4 (make-rxyk!cos 630 (/ 100 630) 8.0)) (rnd (make-rand-interp 4000 .2)) (rnd1 (make-rand-interp 200 (hz->radians 2))) (frm1 (make-formant 400 .99)) (frm2 (make-formant 1200 .98)) (frm3 (make-formant 5000 .97)) (frm1f (* 2 7.0 (sin (hz->radians 400)))) (frm2f (* 2 14.0 (sin (hz->radians 1200)))) (frm3f (* 2 4.0 (sin (hz->radians 5000)))) (intrpf (make-env '(0 1 .6 0 1 1) :offset 1000.0 :scaler 200.0 :duration dur))) (let ((fb (vector frm1 frm2 frm3)) (fs (float-vector frm1f frm2f frm3f))) (set! fb (make-formant-bank fb fs)) (do ((i start (+ i 1))) ((= i stop)) (let ((frq (+ (env frqf) (rand-interp rnd1)))) (mus-set-formant-frequency frm2 (env intrpf)) (outa i (formant-bank fb (* (env ampf) (+ .8 (rand-interp rnd)) (+ (rxyk!cos f1 (* 2.0 frq)) (* .5 (rxyk!cos f2 (* 2.3 frq))) (* .1 (rxyk!cos f3 (* 6.0 frq))) (* .1 (rxyk!cos f4 (* 6.3 frq))))))))))))) ;; (with-sound (:statistics #t) (bullfrog 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Texas toad (define (texas-toad beg1 dur1 amp1) (defanimal (texas-toad-1 beg dur amp) (let ((pulse-dur .0173)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (gen (make-polywave 2460 '(1 .9 2 .01 3 .05 4 .005 5 .01))) (pulsef (make-env '(0 0 1 1 3 1 4 0) :duration pulse-dur :scaler amp)) (pulse2 (make-blackman (/ 4.0 pulse-dur) 2)) (pulse-samps (seconds->samples .02666)) (pulse-out (seconds->samples pulse-dur)) (rnd (make-rand-interp 4000 (hz->radians 200)))) (do ((i start (+ i pulse-samps))) ((>= i stop)) (let ((reset-stop (+ i pulse-out))) (if (<= reset-stop stop) (do ((k i (+ k 1))) ((= k reset-stop)) (outa k (* (env pulsef) (blackman pulse2) (polywave gen (rand-interp rnd)))))) (mus-reset pulsef) (mus-reset pulse2)))))) (let ((last-dur 0.0) (last-call (+ beg1 dur1 -0.4))) (do ((call-beg beg1 (+ call-beg last-dur 0.3 (random 0.2)))) ((>= call-beg last-call)) (set! last-dur (+ .6 (random .25))) (texas-toad-1 call-beg last-dur amp1)))) ;; (with-sound (:play #t) (texas-toad 0 2.0 0.5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; American toad (defanimal (american-toad beg dur amp) (let ((pulse-dur .024) (pulse-sep .045) (start (seconds->samples beg))) (let ((stop (seconds->samples (+ beg dur))) (pulse-samps (seconds->samples pulse-sep)) (pulse-out (seconds->samples pulse-dur)) (ampf (make-env '(0 0.05 4 1 20 1 21 0) :duration dur :scaler amp)) (gen1 #f) (frqf (make-env '(0 150 .1 250 .5 300 .9 200 1 0) :duration pulse-dur :scaler (hz->radians 1.0))) (pulsef (make-env '(0.000 0.000 0.147 0.700 0.261 0.968 0.405 0.996 0.601 0.830 0.878 0.198 1.000 0.000) :duration pulse-dur)) (pulse-frqf (make-env (list 0 1100 .4 1300 dur (- 1300 (* dur 8))) :duration dur :scaler (hz->radians 1.0)))) (do ((i start (+ i pulse-samps))) ((>= i stop)) (set! (mus-location ampf) (- i start)) (let ((reset-stop (min stop (+ i pulse-out))) (pulse-amp (env ampf))) (set! gen1 (make-polywave 0.0 (list 1 (* pulse-amp .94) 2 (* pulse-amp .03) 3 (* pulse-amp .01) 4 (* pulse-amp .003) 5 (* pulse-amp .005) 7 (* pulse-amp .002)))) (set! (mus-location ampf) (- i start)) (do ((k i (+ k 1))) ((= k reset-stop)) (outa k (* (env pulsef) (polywave gen1 (+ (env frqf) (env pulse-frqf)))))) (mus-reset pulsef) (mus-reset frqf)))))) ;; (with-sound (:play #t) (american-toad 0 2 .25)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Plains spadefoot (defanimal (plains-spadefoot beg amp) (let ((dur 0.73) (pulse-dur .019) (start (seconds->samples beg))) (let ((stop (seconds->samples (+ beg dur))) (pulse-samps (seconds->samples pulse-dur)) (ampf (make-env '(0.000 0.000 0.098 0.423 0.310 0.747 0.630 0.929 0.785 0.830 0.902 0.553 1.000 0.000) :scaler amp :duration dur)) (gen1 (make-oscil)) (gen2 #f) (ampf2 (make-env '(0 0 .3 0 .8 1 1 1) :duration dur :scaler 0.4)) (frqf (make-env '(0 1520 .4 1650 1 1630) :duration dur :scaler (hz->radians 1.0))) (pulsef #f) (rnd (make-rand-interp 100 (hz->radians 100)))) (do ((i start (+ i pulse-samps))) ((>= i stop)) (set! (mus-location ampf) (- i start)) (set! (mus-location frqf) (- i start)) (set! (mus-location ampf2) (- i start)) (let ((reset-stop (min stop (+ i pulse-samps))) (pulse-amp (env ampf)) (pulse-amp2 (env ampf2)) (pulse-frq (env frqf))) (if (= pulse-amp2 0.0) (set! gen2 (make-polywave 0.0 (list 1 0.0))) (set! gen2 (make-polywave 0.0 (list 1 (* pulse-amp2 .01) 2 (* pulse-amp2 .01) 6 (* pulse-amp2 .01) 8 (* pulse-amp2 .1) 10 (* pulse-amp2 .01))))) (set! pulsef (make-env (list 0.000 0.000 0.03 pulse-amp 0.08 pulse-amp 0.160 (* pulse-amp 0.486) 0.304 (* pulse-amp 0.202) 0.508 (* pulse-amp 0.087) 1.000 0.000) :duration pulse-dur)) (do ((k i (+ k 1))) ((= k reset-stop)) (let ((frq (+ pulse-frq (rand-interp rnd)))) (outa k (* (env pulsef) (+ (oscil gen1 frq) (polywave gen2 (* 0.25 frq)))))))))))) ;; (with-sound (:play #t) (plains-spadefoot 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Barking tree-frog (defanimal (barking-tree-frog beg amp) (let ((dur 0.165)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.015 0.131 0.038 0.110 0.066 0.621 0.078 0.488 0.090 0.977 0.104 0.423 0.108 0.013 0.113 0.504 0.122 0.005 0.129 0.979 0.138 0.337 0.142 0.470 0.152 0.008 0.156 0.561 0.160 0.008 0.165 1.000 0.177 0.535 0.183 0.744 0.189 0.290 0.193 0.731 0.200 0.381 0.209 0.977 0.217 0.499 0.237 0.846 0.247 0.896 0.260 0.898 0.464 0.846 0.623 0.689 0.801 0.305 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0 480 .3 430 1 425) :duration dur :scaler (hz->radians 1.0))) (gen1 (make-polywave 0.0 (normalize-partials '(1 .9 2 .06 3 .25 4 .79 5 .18 6 .03 7 .02 8 .03 9 .01 10 .02 11 .005 12 .005)))) (rnd (make-rand-interp 1000 (hz->radians 10))) (gen2 (make-oscil)) (frqf2 (make-env '(0 4750 .2 4790 .5 4710 1 4300) :duration dur :scaler (hz->radians 1.0))) (attack (make-rand-interp 4000 (hz->radians 400))) (gen3 (make-oscil 1720)) (attackf (make-env '(0.000 0.000 0.068 0.000 0.093 0.614 0.098 0.000 0.114 0.000 0.120 0.969 0.131 0.000 0.155 0.000 0.159 0.997 0.175 0.000 0.198 0.000 0.2 1.000 0.224 0.000 0.241 0.000 0.243 0.984 0.260 0.000 1.000 0.000) :duration dur :scaler amp))) (do ((i start (+ i 1))) ((= i stop)) (outa i (+ (* (env ampf) (+ (polywave gen1 (+ (env frqf) (rand-interp rnd))) (* .02 (oscil gen2 (env frqf2))))) (* (env attackf) (oscil gen3 (rand-interp attack))))))))) ;; (with-sound (:play #t) (barking-tree-frog 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Western toad (defanimal (western-toad beg dur amp) (let ((start (seconds->samples beg))) (let ((stop (seconds->samples (+ beg dur))) (gen (make-polywave 0.0 '(1 .95 2 .02 3 .03 4 .005))) (cur-start start) (cur-is-long #t)) (do () ((>= cur-start stop)) (let ((pulse-samps (seconds->samples (if cur-is-long (+ 0.04 (random .04)) (+ .01 (random .02)))))) (let ((pulse-ampf (make-env (if cur-is-long (vector 0 0 .1 .5 2 1 3 0) (vector 0 0 1 1 1.5 .3 2 0)) :scaler (* amp (if cur-is-long (+ .6 (random .4)) (+ .1 (random .7)))) :length pulse-samps :base (if cur-is-long 6.0 3.0))) (pulse-frqf (make-env (if cur-is-long '(0 -.5 .5 0 1 -.3) '(0 -1 .1 0 1 0)) :length pulse-samps :base .1 :offset (hz->radians (if cur-is-long (if (> (random 1.0) .6) 1340 1260) 1200)) :scaler (hz->radians (random 500.0)))) (cur-end (+ cur-start pulse-samps))) (do ((i cur-start (+ i 1))) ((= i cur-end)) (outa i (* (env pulse-ampf) (polywave gen (env pulse-frqf))))) (if cur-is-long (set! cur-start (+ cur-end (seconds->samples (+ .015 (if (> (random 1.0) .8) (random .15) (random .04)))))) (set! cur-start (+ cur-end (seconds->samples (+ .01 (random .01)))))) (set! cur-is-long (or (not cur-is-long) (> (random 1.0) .3))))))))) ;; (with-sound (:play #t) (western-toad 0 2 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Southwestern toad (defanimal (southwestern-toad beg dur amp) (let ((pulse-dur 0.0135) (pulse-space 0.0236) (start (seconds->samples beg))) (let ((stop (seconds->samples (+ beg dur))) (pulse-samps (seconds->samples pulse-space)) (pulse-out (seconds->samples pulse-dur)) (ampf (make-env (list 0 0 1.3 1 dur 1 (* 1.01 dur) 0) :duration dur :scaler amp :base .3)) (frqf (make-env (list 0 940 1 1230 dur 1230) :base 3.0 :duration dur :scaler (hz->radians 1.0) :offset (hz->radians -300))) (gen1 #f) (rnd (make-rand-interp 4000 (hz->radians 80))) (pulse-ampf (make-env '(0 0 1 1 1.5 1 2 .5 3 0) :base .3 :duration pulse-dur)) (pulse-frqf (make-env '(0 0 .3 .8 1.5 1 2.7 .8 3 .3) :duration pulse-dur :scaler (hz->radians 300)))) (do ((i start (+ i pulse-samps))) ((>= i stop)) (set! (mus-location ampf) (- i start)) (let ((reset-stop (min stop (+ i pulse-out))) (pulse-amp (env ampf))) (set! (mus-location ampf) (- i start)) (set! (mus-location frqf) (- i start)) (set! gen1 (make-polywave 0.0 (list 1 (* pulse-amp .95) 2 (* pulse-amp .02) 3 (* pulse-amp .03)))) (do ((k i (+ k 1))) ((= k reset-stop)) (outa k (* (env pulse-ampf) (polywave gen1 (+ (env frqf) (env pulse-frqf) (rand-interp rnd)))))) (mus-reset pulse-ampf) (mus-reset pulse-frqf)))))) ;; (with-sound (:play #t) (southwestern-toad 0 2 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Great Plains Narrow-mouthed toad (defanimal (great-plains-narrow-mouthed-toad beg dur1 amp) ;; rocky 75 28 (let ((attack-dur 0.155)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg (max dur1 0.3)))) ;; attack portion (attack-stop (seconds->samples (+ beg attack-dur))) (attack-ampf (make-env '(0.000 0.000 0.015 0.078 0.020 0.289 0.042 0.000 0.057 0.000 0.069 0.409 0.093 0.425 0.101 0.520 0.113 0.588 0.141 0.218 0.159 0.537 0.182 0.695 0.221 0.140 0.223 0.640 0.233 0.872 0.253 0.602 0.269 0.000 0.280 0.000 0.292 0.915 0.319 0.520 0.322 0.000 0.333 0.000 0.347 0.912 0.359 0.777 0.371 0.509 0.381 0.000 0.391 0.000 0.399 0.611 0.407 0.948 0.428 0.475 0.433 0.000 0.448 0.000 0.468 0.905 0.491 0.206 0.504 0.000 0.513 0.000 0.528 0.909 0.537 0.583 0.543 0.125 0.554 0.000 0.572 0.911 0.578 0.957 0.597 0.132 0.611 0.000 0.619 0.000 0.639 0.803 0.648 0.643 0.655 0.108 0.660 0.000 0.677 0.000 0.683 0.629 0.693 0.902 0.706 0.186 0.716 0.000 0.731 0.000 0.736 0.568 0.747 0.985 0.767 0.000 0.790 0.000 0.791 0.358 0.804 0.666 0.818 0.145 0.825 0.000 0.842 0.000 0.848 0.408 0.857 0.768 0.878 0.000 0.898 0.000 0.904 0.511 0.915 0.883 0.929 0.000 0.952 0.000 0.970 0.688 0.977 0.280 0.988 0.052 1.000 0.000) :duration attack-dur :scaler amp)) (attack-frqf (make-env '(0.000 0.124 0.037 0.145 0.060 0.205 0.067 0.152 0.091 0.132 0.107 0.145 0.126 0.175 0.147 0.150 0.166 0.173 0.190 0.173 0.206 0.137 0.219 0.179 0.232 0.192 0.245 0.177 0.260 0.158 0.274 0.177 0.288 0.203 0.298 0.186 0.312 0.167 0.325 0.147 0.336 0.190 0.347 0.207 0.362 0.184 0.377 0.158 0.393 0.190 0.403 0.220 0.421 0.190 0.434 0.158 0.453 0.197 0.465 0.229 0.480 0.199 0.496 0.169 0.515 0.197 0.525 0.218 0.532 0.194 0.544 0.171 0.558 0.197 0.573 0.222 0.584 0.197 0.606 0.177 0.623 0.201 0.633 0.222 0.645 0.203 0.661 0.182 0.676 0.209 0.690 0.222 0.700 0.203 0.717 0.177 0.735 0.207 0.749 0.207 0.771 0.179 0.791 0.205 0.805 0.203 0.814 0.179 0.846 0.209 0.862 0.212 0.869 0.186 0.912 0.207 0.969 0.220 1.000 0.218) :duration attack-dur :scaler (hz->radians 8900.0))) (attack-gen1 (make-polywave 0.0 '(1 .92 2 .05 3 .02 4 .01)))) (do ((i start (+ i 1))) ((= i attack-stop)) (outa i (* (env attack-ampf) (polywave attack-gen1 (env attack-frqf))))) ;; main portion (let ((dur (- dur1 attack-dur))) (let ((ampf (make-env '(0 1 1 1 10 1 11 0) :duration dur :scaler amp)) (frqf (make-env '(0 2000 .9 2000 1 1700) :duration dur :scaler (hz->radians 1.0))) (gen1 (make-polywave 0.0 '(1 .92 2 .05 3 .02 4 .01))) (frqf2 (make-env '(0 0 .1 25 4 20) :duration dur :scaler (hz->radians 1.0))) (gp (make-polywave 100 '(4 1 9 1))) (low-ampf (make-env (list 0 0 .2 1 dur 1) :duration dur :scaler .15)) (pulser (make-pulse-train 100)) (pulse-ampf (make-env '(0.000 0.000 0.227 0.057 0.319 0.164 0.407 0.946 0.554 0.706 0.707 0.036 0.839 0.031 0.930 0.097 1.000 0.000) :duration .008)) (rnd (make-rand-interp 20 (hz->radians 3))) (pulse-amp amp) (saved-frq (make-float-vector (floor (* .03 *clm-srate*)))) ; 100 hz in pulser, so this is 3 times bigger than expected (last-stop attack-stop)) (pulse-train pulser 0.0) ; flush the startup pulse (do ((i attack-stop (+ i 1)) (j 0 (+ j 1))) ((= i stop)) (if (> (pulse-train pulser (float-vector-set! saved-frq j (+ (env frqf2) (rand-interp rnd)))) 0.1) (begin (do ((k 0 (+ k 1)) (n last-stop (+ n 1))) ((= k j)) (outa n (* pulse-amp (env pulse-ampf) (+ (* (env low-ampf) (polywave gp (ina k saved-frq))) (polywave gen1 (env frqf)))))) (mus-reset pulse-ampf) (set! (mus-location ampf) (- i attack-stop)) (set! pulse-amp (env ampf)) (set! (mus-phase gen1) (* pi .75)) (set! last-stop i) (set! j 0))))))))) ;; (with-sound (:play #t) (great-plains-narrow-mouthed-toad 0 2 .25)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Pacific chorus frog (defanimal (pacific-chorus-frog beg amp) (let ((dur 0.25)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.011 0.147 0.023 0.131 0.028 0.034 0.059 0.000 0.063 0.153 0.067 0.113 0.072 0.391 0.081 0.095 0.088 0.052 0.102 0.025 0.124 0.000 0.131 0.452 0.139 0.327 0.144 0.099 0.156 0.097 0.160 0.048 0.186 0.000 0.194 0.438 0.200 0.366 0.201 0.156 0.211 0.063 0.247 0.000 0.256 0.628 0.268 0.154 0.274 0.190 0.285 0.027 0.296 0.059 0.309 0.031 0.312 0.481 0.322 0.939 0.331 0.314 0.351 0.061 0.363 0.099 0.374 0.056 0.377 0.438 0.389 0.858 0.394 0.467 0.403 0.241 0.414 0.197 0.415 0.127 0.425 0.075 0.436 0.090 0.441 0.526 0.454 0.869 0.471 0.239 0.490 0.029 0.503 0.117 0.505 0.485 0.514 0.811 0.528 0.415 0.538 0.088 0.552 0.056 0.561 0.106 0.580 0.075 0.597 0.000 0.776 0.000 0.777 0.573 0.786 0.145 0.801 0.054 0.826 0.000 0.827 0.632 0.844 1.000 0.856 0.524 0.866 0.031 0.883 0.074 0.891 0.136 0.896 0.745 0.907 0.424 0.915 0.765 0.934 0.059 0.951 0.048 0.962 0.079 0.970 0.436 0.986 0.266 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.220 0.074 0.249 0.133 0.249 0.194 0.240 0.258 0.252 0.324 0.264 0.389 0.267 0.456 0.270 0.520 0.264 0.847 0.270 0.920 0.273 1.000 0.279) :duration dur :scaler (hz->radians (* 0.5 0.205 22050.0)))) (gen1 (make-polywave 0.0 '(2 .35 3 .1 4 .8 5 .01 6 .03 8 .005))) (rnd (make-rand-interp 600 (hz->radians 50)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (+ (env frqf) (rand-interp rnd))))))))) ;; (with-sound (:play #t) (pacific-chorus-frog 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Red-spotted toad (defanimal (red-spotted-toad beg dur amp) ;; rocky 23 1 (let ((pulse-dur 0.0138) (pulse-space 0.0234) (start (seconds->samples beg))) (let ((stop (seconds->samples (+ beg dur))) (pulse-samps (seconds->samples pulse-space)) (pulse-out (seconds->samples pulse-dur)) (ampf (make-env '(0 0 .5 .8 .8 .8 .9 1 .98 1 1 0) :duration dur :scaler amp)) (frqf (make-env '(0 1900 .2 2200 .4 2250 .9 2200 1 2100) :duration dur :scaler (hz->radians 1.0))) (rnd (make-rand-interp 1000 (hz->radians 40))) (gen1 #f) (pulse-ampf (make-env '(0 0 1 1 1.25 1 2 .5 3 0) :base .3 :duration pulse-dur))) (do ((i start (+ i pulse-samps))) ((>= i stop)) (set! (mus-location ampf) (- i start)) (let ((reset-stop (min stop (+ i pulse-out))) (pulse-amp (env ampf))) (set! gen1 (make-polywave 0.0 (list 1 (* pulse-amp .99) 3 (* pulse-amp .005)))) (set! (mus-location ampf) (- i start)) (set! (mus-location frqf) (- i start)) (do ((k i (+ k 1))) ((= k reset-stop)) (outa k (* (env pulse-ampf) (polywave gen1 (+ (env frqf) (rand-interp rnd)))))) (mus-reset pulse-ampf)))))) ;; (with-sound (:play #t) (red-spotted-toad 0 4 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Green toad (defanimal (green-toad beg dur amp) ;; rocky 31 1 ;; (an experiment with wave-train in place of pulsed env) (let* ((wave-len 256) (pulse (let ((v (make-float-vector wave-len 0.0)) (pulse-ampf (make-env '(0.000 0.000 0.063 0.312 0.277 0.937 0.405 1.000 0.617 0.696 0.929 0.146 2.000 0.000) :length wave-len))) (do ((i 0 (+ i 1))) ((= i wave-len)) (set! (v i) (env pulse-ampf))) v))) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env (list 0 0 .2 .9 .3 .7 .4 1 (max .5 (- dur .01)) 1 (max .51 dur) 0) :duration dur :scaler amp)) (frqf (make-env (list 0 2540 .2 3250 (max .5 dur) 3200) :base 10 :duration dur :scaler (hz->radians 1.0))) (pulse1 (make-wave-train 56.0 :wave pulse)) (pulse2 (make-delay (seconds->samples .0078))) ; pulses come in pairs (gen1 (make-polywave 0.0 '(1 .95 2 .04 3 .01))) (rnd (make-rand-interp 100 (hz->radians 2.0))) (rnd1 (make-rand-interp 1000 (hz->radians 80)))) (do ((i start (+ i 1))) ((= i stop)) (let ((val (wave-train pulse1 (rand-interp rnd)))) (outa i (* (env ampf) (+ val (delay pulse2 val)) (polywave gen1 (+ (env frqf) (rand-interp rnd1)))))))))) ;; (with-sound (:play #t) (green-toad 0 1 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Little grass frog (defanimal (little-grass-frog beg amp) ;; frogs 26 8.5 (let ((dur .032)) ;; initial note (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.061 0.739 0.124 0.998 0.358 0.902 0.630 0.419 0.727 0.469 0.813 0.391 0.857 0.046 0.884 0.256 0.918 0.121 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.289 0.534 0.302 0.793 0.299 1.000 0.307) :duration dur :scaler (hz->radians (* 0.5 21900.0)))) (gen1 (make-polywave 0.0 '(1 .005 2 .97 3 .02 4 .01)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))) ;; 4 tinks (let ((begs (vector 0.085 0.118 0.141 0.162)) (amps (vector 1.0 1.0 .8 .6)) (frqs (vector 6840 6940 6890 6940))) (do ((call 0 (+ call 1))) ((= call 4)) (let ((start (seconds->samples (+ beg (begs call)))) (dur .01)) (let ((stop (+ start (seconds->samples dur))) (ampf (make-env '(0.000 0.000 0.082 0.967 0.149 1.000 0.183 0.977 0.299 0.529 0.334 0.595 0.451 0.312 0.520 0.176 0.639 0.155 0.753 0.077 1.000 0.000) :duration dur :scaler (* amp (amps call)))) (frq (hz->radians (* 0.5 (frqs call)))) (gen1 (make-polywave 0.0 '(1 .005 2 .97 3 .02 4 .01)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 frq)))))))))) ;; (with-sound (:play #t) (little-grass-frog 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Sonoran desert toad (defanimal (sonoran-desert-toad beg dur amp) ;; rocky 13 1 (let ((start (seconds->samples beg))) (let ((stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.011 0.201 0.193 0.704 0.338 0.878 0.593 0.986 0.865 0.972 0.954 0.895 0.970 0.645 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.360 0.069 0.387 0.144 0.411 0.500 0.428 0.649 0.432 0.746 0.425 0.877 0.435 0.974 0.418 1.000 0.291) :duration dur :scaler (hz->radians 2800.0))) (gen1 (make-oscil)) (gen2 (make-oscil)) (ampf2 (make-env (list 0 .1 .05 1 .2 .1 .3 .01 (- dur .1) .1 dur 1) :duration dur :scaler .2)) (gen3 (make-polywave 0.0 '(3 .5 4 .2 5 .1 6 .08 7 .05 9 .03))) (ampf3 (make-env (list 0 .2 .1 1 (- dur .2) 1 dur .5) :duration dur :scaler .1)) (rnd (make-rand-interp 4000 (hz->radians 200))) (env1 (vector 0 0 .6 1 1 0)) (env2 (vector 0 0 .3 .7 .5 1 .8 .9 1 0)) (env3 (vector 0 0 .2 .7 .3 .1 .5 1 .7 .8 1 0)) (next-pulse start) (pulse-samps 0) (pulse-ampf #f)) (do ((i start (+ i pulse-samps))) ((>= i stop)) (if (>= i next-pulse) (let ((pulse-dur (+ .01 (random .003))) (env-choice (random 3))) (set! pulse-ampf (make-env (if (= env-choice 0) env1 (if (= env-choice 1) env2 env3)) :duration pulse-dur :scaler (+ .7 (random .3)))) (set! pulse-samps (seconds->samples (+ pulse-dur (random 0.005)))) (set! next-pulse (+ next-pulse pulse-samps)))) (set! (mus-location ampf) (- i start)) (set! (mus-location frqf) (- i start)) (let ((pulse-end (+ i pulse-samps)) (pulse-amp (env ampf)) (pulse-frq (env frqf))) (do ((k i (+ k 1))) ((= k pulse-end)) (let ((frq (+ pulse-frq (rand-interp rnd)))) (outa k (* pulse-amp (env pulse-ampf) (+ (* .7 (oscil gen1 frq)) (* (env ampf2) (oscil gen2 (* 2.0 frq))) (* (env ampf3) (polywave gen3 frq)))))))))))) ;; (with-sound (:play #t) (sonoran-desert-toad 0 .8 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Amargosa toad (define (amargosa-toad beg1 amp1) ;; rocky 17 0 (defanimal (amargosa-toad-1 beg dur frqscl frqenv ampscl ampenv) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env ampenv :duration dur :scaler ampscl)) (frqf (make-env frqenv :duration dur :scaler (hz->radians frqscl))) (gen1 (make-polywave :partials (normalize-partials '(1 1 2 .18 3 .19 4 .04 5 .03 6 .04 8 .01 9 .01 10 .005 11 .01 12 .005))))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf))))))) (let ((begs (vector 0.0 0.15 0.325 0.47 0.61)) (durs (vector 0.027 0.06 0.065 0.042 0.05)) (amps (vector 0.9 1.0 1.0 0.4 0.1)) (frqs (vector 14800 14020 (* 1/3 14800) 14800 (* 1/2 14800))) (ampenvs (vector '(0.000 0.000 0.085 0.906 0.117 1.000 0.328 0.909 0.715 0.464 0.892 0.118 1.000 0.000) '(0.000 0.000 0.025 1.000 0.056 0.201 0.121 0.848 0.151 0.503 0.217 0.395 0.441 0.556 0.602 0.868 0.642 0.870 0.734 0.726 0.808 0.456 0.964 0.141 1.000 0.000) '(0.000 0.000 0.026 0.053 0.047 1.000 0.063 0.809 0.079 0.181 0.106 0.637 0.151 0.442 0.180 0.604 0.346 0.507 0.463 0.511 0.582 0.694 0.641 0.663 0.697 0.519 0.744 0.331 0.806 0.087 1.000 0.000) '(0.000 0.000 0.037 0.108 0.070 1.000 0.090 0.700 0.117 0.067 0.144 0.462 0.166 0.523 0.209 0.168 0.234 0.410 0.639 0.278 0.823 0.373 1.000 0.000) '(0.000 0.000 0.091 0.302 0.184 0.083 0.243 0.639 0.286 0.120 0.364 0.465 0.570 0.187 0.739 0.434 1.000 0.000))) (frqenvs (vector '(0.000 0.075 0.317 0.073 1.000 0.065) '(0.000 0.076 0.031 0.106 0.064 0.085 0.098 0.073 0.158 0.079 0.821 0.076 1.000 0.067) '(0.000 0.201 0.050 0.209 0.090 0.213 0.257 0.217 0.377 0.215 0.486 0.221 0.548 0.231 0.669 0.233 0.751 0.225 0.852 0.215 1.000 0.227) '(0.000 0.071 0.063 0.081 0.097 0.083 0.155 0.073 0.195 0.069 0.832 0.069 1.000 0.053) '(0.000 0.120 0.132 0.128 0.218 0.126 0.272 0.120 0.326 0.120 0.513 0.120 0.730 0.118 1.000 0.096)))) (do ((call 0 (+ call 1))) ((= call 5)) (amargosa-toad-1 (+ beg1 (begs call)) (durs call) (frqs call) (frqenvs call) (* amp1 (amps call)) (ampenvs call))))) ;; (with-sound (:play #t) (amargosa-toad 0 .5)) ;;; ================ Mammals ================ ;;; ;;; ;;; Indri ;;; ;;; close in spectrum, amp, freq, but the original has what sounds like a ton of reverb ;;; if I add the reverb, it's close -- is this really what this animal sounds like? (defanimal (indri beg amp) (let ((pitch 900) (dur 1.5)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (gen1 (make-polywave (* 2 pitch) '(1 .9))) (gen4 (make-polywave pitch '(1 .125))) (gen2 (make-polywave (* 8 pitch) '(1 .1))) (gen3 (make-polywave pitch '(1 .2))) (ampf (make-env '(0.0 0.0 0.05 0.4 0.1 0.65 0.2 0.5 0.27 1.0 0.4 0.43 0.43 0.53 0.5 0.5 0.53 0.36 0.6 1.0 0.64 0.99 0.69 0.6 0.7 0.3 0.77 0.15 0.8 0.04 1.0 0.0) :duration dur :scaler amp)) (frqf (make-env '(0 1 2 0 6 0 7 3 9 3) :scaler (hz->radians 60) :duration dur)) (vib (make-polywave 2 (list 1 (hz->radians 10))))) (do ((i start (+ i 1))) ((= i stop)) (let ((frq (+ (env frqf) (polywave vib)))) (outa i (* (env ampf) (+ (polywave gen1 (+ (* 2.0 frq) (polywave gen4 frq))) (polywave gen2 (+ (* 8.0 frq) (polywave gen3 frq))))))))))) ;; (with-sound (:play #t) (indri 0 .5)) ;;; ================ Insects ================ ;;; ;;; ;;; mosquito ;;; ;;; need to make freq env flicks at call time (is there a comb-filter effect as it gets near?) (defanimal (mosquito beg dur freq amp) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (carrier (make-oscil freq)) (modulator1 (make-polywave (* freq 2) '(1 .6))) ; or 1 (but leave lower mult at 2??) (modulator3 (make-polywave (* freq 3) '(1 .3))) (modulator2 (make-polywave (* freq 8) '(1 .1))) ; or 9 (ampf (make-env '(0 0 .2 .5 1 .5 2 .5 3 1 4 .5 5 .5 5.1 0) :scaler amp :duration dur :base 32)) (frqf (make-env '(0 0 1 0 1.01 0.1 1.03 -0.1 1.05 0.0 3 0 3.02 .05 3.03 -0.1 3.1 0 5 0.0) :duration dur :scaler (hz->radians freq))) (vib (make-rand-interp 10.0 (hz->radians 10))) (indf (make-rand-interp 1 .5)) (index2 (hz->radians (* freq 1.0))) (index3 (hz->radians (* freq 0.5))) (hfreq (hz->radians freq))) (do ((i start (+ i 1))) ((= i stop)) (let* ((frq (+ (env frqf) (rand-interp vib))) (pitch (oscil carrier frq))) (outa i (* (env ampf) (+ (polywave modulator1 (+ (* 2.0 frq) (* hfreq pitch (+ 1.0 (rand-interp indf))))) (polywave modulator3 (+ (* 3.0 frq) (* index3 pitch))) (polywave modulator2 (+ (* 8.0 frq) (* index2 pitch)))))))))) ;; (with-sound (:play #t) (mosquito 0 5 560 .2) (mosquito 1 3 880 .05)) ;; (with-sound () (mosquito 0 1 560 .1)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Southern mole cricket (defanimal (southern-mole-cricket beg dur amp) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (gen1 (make-oscil 2700)) (gen2 (make-oscil (* 2700 2.4))) (gen3 (make-oscil 60)) (gen5 (make-polywave 360 '(0 .035 1 .015))) (gen4 (make-oscil (* 2700 3.2))) (gargle (make-rand-interp 360 (hz->radians (* .25 360))))) (do ((i start (+ i 1))) ((= i stop)) (let ((pval (oscil gen3)) (noise (rand-interp gargle))) (outa i (* amp (+ (* (polywave gen5) (- 1.0 pval) (oscil gen2 (* 2.4 noise))) (* (max 0.0 pval) (+ (* .95 (oscil gen1 noise)) (* .05 (oscil gen4 noise))))))))))) ;; (with-sound (:play #t) (southern-mole-cricket 0 3 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Broad-winged Tree cricket (defanimal (broad-winged-tree-cricket beg dur amp) (let ((freq 1700)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (gp (make-polywave freq '(1 .7 2 .05 3 .04))) (gb (make-polywave freq '(4 .02 5 .02))) (ampmod (make-triangle-wave 155 :amplitude .07)) (ampf (make-env '(0 0 8 1 20 1 21 0) :duration dur :scaler amp)) (frqf (make-env '(0 1 1 -1 2 -1) :duration .06 :base 10.0 :scaler (hz->radians 40.0))) (pulsef #f) (pulse-samps (seconds->samples .06)) (indf (make-env '(0 0 10 0 18 1 23 1 26 0 30 0) :duration .06)) (noise (make-rand-interp 1000 .005))) (do ((i start (+ i pulse-samps))) ((>= i stop)) (set! (mus-location ampf) (- i start)) (let ((reset-stop (min stop (+ i pulse-samps))) (pulse-amp (env ampf))) (set! pulsef (make-env '(0 0 1 .1 6 .2 7 0 8 .3 10 1 18 .9 21 .1 23 .3 28 .1 30 0) :scaler pulse-amp :duration .06 :base .1)) (do ((k i (+ k 1))) ((= k reset-stop)) (let ((buzz (+ (env frqf) (rand-interp noise)))) (outa k (* (env pulsef) (+ .93 (triangle-wave ampmod)) (+ (polywave gp buzz) (* (env indf) (polywave gb buzz))))))) (mus-reset pulsef) (mus-reset frqf) (mus-reset indf)))))) ;; (with-sound (:play #t) (broad-winged-tree-cricket 0 1.0 0.3)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Long-spurred meadow katydid ;;; ;;; I can barely hear this at its true pitch, so the match was ;;; done down one or two octaves -- I think the recording has cut off high info (above 20Khz) -- ;;; need much higher srate to see what this guy is really doing. This is not very good... (defanimal (long-spurred-meadow-katydid beg amp) (let ((dur 10.1) ; overall duration (slow-start 2.2)) ; buzz at start (let ((soft-end (+ slow-start 4.0))) ; softer section, rest is full vol (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) ;; looks like the same basic pulse throughout, almost same speed at start but every other one is squelched ;; slow startup pulse starts much faster (.06 mid-pulse duration, .0013 base pulse) (carrier (make-polywave 400 (list 33 .36 35 (* .36 .7) 37 (* .36 .49) 39 (* .36 .343) 41 (* .36 .242)))) (modulator (make-polywave 1500 '(1 .003))) ; cos^2 = 1/2(cos 2x + 1), but polywave has constant term via partial 0 (modulator1 (make-polywave 3000 '(0 .5 1 .5))) (noise (make-rand-interp 5000 .003)) (peep (make-pulsed-env '(0 0 1 0 2 .2 3 0 5 .75 8 1 10 0 11 0) .06 (/ 1.0 .06))) (ampf (make-env (list 0 0 .5 .5 slow-start .4 soft-end .4 (+ soft-end .5) 1 (- dur 1) 1 dur 0.0) :duration dur :scaler amp)) (pulsef (make-env (list 0 -1 slow-start -1 (+ slow-start .03) 0 dur 0) :duration dur :scaler (hz->radians 8))) (pulsef1 (make-env (list 0 -1 slow-start -1 (+ slow-start .03) 0 dur 0) :duration dur :scaler (hz->radians (* 24.75 8))))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave modulator1) (pulsed-env peep (env pulsef)) (polywave carrier (+ (env pulsef1) (rand-interp noise) (polywave modulator)))))))))) ;; (with-sound (:statistics #t) (long-spurred-meadow-katydid 0 .5)) #| (defanimal (long-spurred-meadow-katydid beg amp) (let ((dur 10.1) ; overall duration (slow-start 2.2)) ; buzz at start (let ((soft-end (+ slow-start 4.0))) ; softer section, rest is full vol (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) ;; looks like the same basic pulse throughout, almost same speed at start but every other one is squelched ;; slow startup pulse starts much faster (.06 mid-pulse duration, .0013 base pulse) (carrier (make-nrxysin 13200 (/ 800 13200) 4 .7)) (modulator (make-oscil 1500 (* 0.5 pi))) (noise (make-rand-interp 5000 .1)) (nrx 0.0) (peep (make-pulsed-env '(0 0 1 0 2 .2 3 0 5 .75 8 1 10 0 11 0) .06 (/ 1.0 .06))) (ampf (make-env (list 0 0 .5 .5 slow-start .4 soft-end .4 (+ soft-end .5) 1 (- dur 1) 1 dur 0.0) :duration dur :scaler amp)) (pulsef (make-env (list 0 -1 slow-start -1 (+ slow-start .03) 0 dur 0) :duration dur :scaler (hz->radians 8)))) (do ((i start (+ i 1))) ((= i stop)) (let ((frq (env pulsef)) (md (oscil modulator))) (set! nrx (nrxysin carrier (+ (* 825.0 frq) ; (/ 13200 16)) (rand-interp noise) (* .1 md)))) (set! md (* md md nrx (pulsed-env peep frq))) (outa i (* md (env ampf))))))))) |# #| ;; this is slower! (do ((i start (+ i 1))) ((= i stop)) (let ((frq (env pulsef)) (md (oscil modulator))) (outa i (* md md (nrxysin carrier (+ (* 825.0 frq) ; (/ 13200 16)) (rand-interp noise) (* .1 md))) (pulsed-env peep frq) (env ampf))))))))) |# ;;; -------------------------------------------------------------------------------- ;;; ;;; Handsome trig (defanimal (handsome-trig beg dur amp) (let ((freqs (apply float-vector (map hz->radians '(6439 6585 6860 6940 7090 7266 7362)))) (amps (float-vector 0.355 0.355 0.089 0.060 0.071 0.035 0.035)) (pulse-dur .02)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (pulsef (make-env '(0.0 0.0 0.05 1.0 0.13 1.0 0.4 0.1 1.0 0.0) :scaler amp :duration pulse-dur)) (pulse-samps (seconds->samples pulse-dur)) (pulse-sep (seconds->samples pulse-dur)) (pulses 0) (obank (make-oscil-bank freqs (make-float-vector 7 0.0) amps #t))) (do ((i start (+ i pulse-sep))) ((>= i stop)) (let ((pulse-stop (+ i pulse-samps))) (do ((k i (+ k 1))) ((= k pulse-stop)) (outa k (* (env pulsef) (oscil-bank obank))))) (set! pulses (+ pulses 1)) ;; count pulses in current group -- at least 2, at most 4, if 2 or 3, possibly and if 4 definitely insert a space (if (or (= pulses 4) (and (= pulses 2) (> (random 1.0) 0.6)) (and (= pulses 3) (> (random 1.0) 0.3))) (begin (set! pulse-sep (+ pulse-samps (seconds->samples (+ .015 (random .005))))) (set! pulses 0)) (set! pulse-sep pulse-samps)) (mus-reset pulsef) (mus-reset obank))))) ;; (with-sound (:play #t :statistics #t) (handsome-trig 0 2 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Fast calling tree cricket ;;; ;;; (use fm for noise to get the burble right, and pm for spectrum) (defanimal (fast-calling-tree-cricket beg dur amp) (let ((pulse-dur .0167)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (pulsef (make-env '(0.0 0.0 0.05 0.07 0.08 0.4 0.2 0.7 0.37 0.93 0.52 1.0 0.6 0.4 0.67 0.2 0.84 0.16 0.88 0.06 0.96 0.03 1.0 0.0) :scaler amp :duration pulse-dur)) (pulse-samps (seconds->samples (/ 1.0 55))) (pulse-out (seconds->samples pulse-dur)) (gen1 (make-oscil 4100)) (md (make-oscil 4100)) (md1 (make-oscil 205)) (rnd (make-rand-interp 180 .01))) ;; 1.0 .04 .007 (do ((i start (+ i pulse-samps))) ((>= i stop)) (let ((reset-stop (min stop (+ i pulse-out)))) (do ((k i (+ k 1))) ((= k reset-stop)) (outa k (* (env pulsef) (oscil gen1 (rand-interp rnd) (+ (* .1 (oscil md)) (* .2 (oscil md1))))))) (mus-reset pulsef)))))) ;; (with-sound (:play #t) (fast-calling-tree-cricket 0 2 .25)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Dog-day cicada (defanimal (dog-day-cicada beg dur amp) ; dur ca 10 ..15 secs (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.0 0.0 0.1 0.03 0.2 0.2 0.3 0.6 0.34 0.8 0.44 1.0 0.5 0.83 0.55 0.92 0.6 0.86 0.66 1.0 0.7 0.7 0.88 0.25 0.91 0.24 0.93 0.02 1.0 0.0) :duration dur :scaler (* 0.5 amp))) (gen1 (make-oscil 7500)) (gen2 (make-polywave 200 '(1 .15))) (rnd (make-rand-interp 200)) (rndf (make-env '(0 .3 .7 .3 .8 1 1 0) :duration dur :scaler (hz->radians 120))) (frqf (make-env '(0 -.5 .2 0 .85 0 1 -1) :scaler (hz->radians 400) :duration dur)) (rx (make-rxyk!cos 4000 (/ 600 4000) 8.0))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (+ (oscil gen1 (+ (env frqf) (* (env rndf) (rand-interp rnd)) (polywave gen2))) (rxyk!cos rx))))))) ;; (with-sound (:play #t) (dog-day-cicada 0 2 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Linnaeus' Cicada (defanimal (linnaeus-cicada beg dur amp) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0 0 1 .8 10 1 11 0) :duration dur :scaler amp)) (frqf (make-env '(0 0 3 .02 6 0 8 .03 9.8 0 10.6 -1 11 -1) :scaler (hz->radians 450) :duration dur :base 32)) (gp1 (make-polywave 1280 '(1 .8 2 .02 3 .02))) (gp2 (make-polywave 1100 '(1 .15))) (gp3 (make-polywave 1460 '(1 .07))) (rnd (make-rand-interp 1280 .014)) (saw (make-sawtooth-wave 180 .5))) (do ((i start (+ i 1))) ((= i stop)) (let ((sw (sawtooth-wave saw)) (md (+ (env frqf) (rand-interp rnd)))) (outa i (* (env ampf) (+ .75 (* sw sw)) (+ (polywave gp1 md) (polywave gp2 (* 0.8593 md)) ;(/ 1100 1280) (polywave gp3 (* 1.1406 md))))))))) ;(/ 1460 1280) ;; (with-sound (:statistics #t) (linnaeus-cicada 0 2 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Lyric cicada (defanimal (lyric-cicada beg dur amp) (let ((p0 400)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (pulsef (make-pulsed-env '(0.0 0.0 0.038 0.16 0.044 0.6 0.07 0.6 0.08 0.26 0.1 0.09 0.12 0.43 0.14 0.19 0.18 0.07 0.22 0.048 0.23 0.65 0.25 0.65 0.26 0.23 0.28 0.044 0.3 0.55 0.31 0.31 0.35 0.05 0.38 0.01 0.39 1.0 0.41 0.36 0.42 0.16 0.44 0.02 0.46 0.7 0.48 0.23 0.5 0.1 0.55 0.01 0.56 0.97 0.6 0.12 0.612 0.02 0.63 0.61 0.65 0.18 0.69 0.07 0.7 0.61 0.72 0.16 0.76 0.05 0.78 0.37 0.790 0.13 0.82 0.02 0.83 0.4 0.85 0.12 0.9 0.01 0.92 0.29 0.95 0.2 0.96 0.08 1.0 0) .02 50.0)) (gen1 (make-oscil (* p0 16))) (gen2 (make-polywave p0 '(1 .15))) (rnd (make-rand-interp p0 (hz->radians 800))) (ampf (make-env '(0 0 1 1 10 1 11 0) :duration dur :scaler amp))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (pulsed-env pulsef) (oscil gen1 (+ (polywave gen2) (rand-interp rnd))))))))) ;; (with-sound (:play #t) (lyric-cicada 0 2 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Confused ground cricket (defanimal (confused-ground-cricket beg dur amp) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (gen1 (make-oscil 5700)) (gen2 (make-polywave 5700 '(1 .01))) (rnd (make-rand-interp 600 (hz->radians 166))) (songf (make-env '(0.0 0.0 0.02 0.5 0.18 0.5 0.24 0.28 0.28 0.27 0.45 0.8 0.65 1.0 0.93 0.94 1.0 0.0) :duration .4)) (pulsef #f) (pulse-samps (seconds->samples .01)) (song-samps (seconds->samples .4))) (do ((i start (+ i (seconds->samples (+ .5 (random .2)))))) ((>= i stop)) (let ((song-stop (min stop (+ i song-samps)))) (do ((k i (+ k (seconds->samples (+ .01 (random .006)))))) ((>= k song-stop)) (set! (mus-location songf) (- k i)) (let ((pstop (+ k pulse-samps)) (pulse-amp (env songf))) (set! pulsef (make-env '(0.0 0.0 0.16 0.0 0.23 0.57 0.36 0.57 0.42 0.83 0.56 1.0 0.64 0.81 0.75 0.2 0.86 0.02 1.0 0.0) :scaler (* pulse-amp amp) :duration .01)) (do ((j k (+ j 1))) ((= j pstop)) (outa j (* (env pulsef) (oscil gen1 (+ (polywave gen2) (rand-interp rnd)))))))) (mus-reset songf))))) ;; (with-sound (:play #t) (confused-ground-cricket 0 3 .3)) ;;; ------------------------------------------------------------------------------------------ ;;; ;;; Tinkling ground cricket ;;; ;;; There's a secondary (slower) peep -- is this part of our cricket's song, or another cricket in the background? (defanimal (tinkling-ground-cricket beg dur amp) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (gen1 (make-oscil 7200)) (gp (make-polywave 80 '(1 .01))) (pulser (make-env '(0.0 0.0 0.07 0.5 0.28 0.86 0.42 0.97 0.55 1.0 0.63 0.88 0.71 0.6 0.85 0.14 0.9 0.1 0.94 0.02 1.0 0.0) :scaler amp :duration .03)) (pulse-samps (seconds->samples .15)) (pulse-out (seconds->samples .03))) (do ((i start (+ i pulse-samps))) ((>= i stop)) (let ((reset-stop (min stop (+ i pulse-out)))) (do ((k i (+ k 1))) ((= k reset-stop)) (outa k (* (env pulser) (oscil gen1 (polywave gp))))) (mus-reset pulser))))) ;; (with-sound (:play #t) (tinkling-ground-cricket 0 3 .3)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Marsh meadow grasshopper ;;; ;;; this is just a random number generator with an elaborate amplitude envelope (defanimal (marsh-meadow-grasshopper beg amp) (let ((dur 4.8)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0 0 .2 .6 .65 1.0 .87 .87 1.0 0) :duration dur :scaler amp)) (pulsef (make-env '(0.000 0.000 0.070 0.086 0.176 0.083 0.311 0.170 0.432 0.173 0.470 0.321 0.487 0.021 0.503 0.021 0.504 0.304 0.540 0.298 0.553 0.435 0.600 0.193 0.614 0.458 0.652 0.315 0.665 0.024 0.689 0.018 0.699 0.638 0.725 0.582 0.727 0.027 0.790 0.009 0.799 0.819 0.824 0.635 0.833 0.036 0.926 0.015 0.941 0.866 0.949 0.053 0.968 0.570 1.000 0.000) :duration .19)) (pulse-samps (seconds->samples (+ .19 .02))) (pulse-out (seconds->samples .19)) (r (make-rand 20000.0 1.0)) (oz (make-one-zero -1.0 1.0))) (do ((i start (+ i pulse-samps))) ((>= i stop)) (set! (mus-location ampf) (- i start)) (let ((reset-stop (min stop (+ i pulse-out))) (pulse-amp (env ampf))) (set! (mus-scaler r) pulse-amp) (do ((k i (+ k 1))) ((= k reset-stop)) (outa k (one-zero oz (* (env pulsef) (rand r))))) (mus-reset pulsef)))))) ;; (with-sound (:play #t :statistics #t) (marsh-meadow-grasshopper 0 .3)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Carolina grasshopper ;;; ;;; tricky! spikes are at 48 Hz, but the sound they make requires 24 Hz pulse -- I presume ;;; I'm seeing the 2 or 4 wings alternating? (defanimal (carolina-grasshopper beg dur amp) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env ;'(0.000 0.000 0.032 0.115 0.151 0.044 0.181 0.485 0.254 0.841 0.620 0.431 0.731 0.051 0.757 0.292 0.898 0.620 0.984 0.380 1.000 0.000) '(0.000 0.000 0.031 0.122 0.076 0.054 0.148 0.010 0.177 0.512 0.199 0.366 0.246 0.868 0.291 0.336 0.320 0.644 0.386 0.244 0.450 0.553 0.535 0.142 0.583 0.424 0.611 0.427 0.727 0.081 0.778 0.315 0.835 0.319 0.899 0.600 0.972 0.356 1.000 0.000) :duration dur :scaler (* 3 amp))) (spikes1 (make-nsin 24 250)) (spikes1a (make-nsin 24 250)) (spikes2 (make-nsin 48 140)) (spikes3 (make-nsin 48 120)) (rnd (make-rand-interp 100 .0001)) ; perhaps this is too much -- it clobbers the comb filter (frqf (make-env '(0 0 1 -.4 2 0 3 -.2 4 .3 6 -1.0) :scaler (hz->radians .4) :duration dur)) (oz (make-one-zero 1.0 -1.0))) (set! (mus-phase spikes1a) pi) (set! (mus-phase spikes2) .7) (set! (mus-phase spikes3) 1.4) (do ((i start (+ i 1))) ((= i stop)) (let* ((noi (rand-interp rnd)) (frq (+ noi (env frqf)))) (outa i (one-zero oz (* (env ampf) (+ (* .6 (nsin spikes1 noi)) (* .6 (nsin spikes1a noi)) (* .4 (nsin spikes2 frq)) (* .3 (nsin spikes3 frq)))))))))) ;; (with-sound (:play #t) (carolina-grasshopper 0 1.5 1.0)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Striped ground cricket (defanimal (striped-ground-cricket beg dur amp) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (gen1 (make-oscil (* 2 6600))) (gen2 (make-oscil (* 2 66) (* 0.5 (+ pi (hz->radians (* 2 66)))))) (gen3 (make-oscil 6600)) (gen4 (make-oscil 66 (* 0.5 (+ pi (hz->radians 66))))) (pulsef (make-env '(0.000 0.000 0.041 0.466 0.144 0.775 0.359 1.0 0.484 0.858 1.000 0.000) :scaler amp :duration .012)) (pulsef1 (make-env '(0.000 0.000 0.041 0.466 0.144 0.775 0.359 1.0 0.484 0.858 1.000 0.000) :scaler (* 0.5 amp) :duration .012)) (pulse-samps (seconds->samples 0.012)) (pulse-sep (seconds->samples 0.015)) (long-pulse-samps (seconds->samples .54)) (rnd (make-rand-interp (* 3 66) .04))) (do ((i start (+ i long-pulse-samps))) ((>= i stop)) ;; do the 1st 0.5 amp pulse (let ((pstop (+ i pulse-samps)) (next-start i) (pulses (+ 8 (random 3)))) (do ((j i (+ j 1))) ((= j pstop)) (outa j (* (env pulsef1) (+ (* .2 (oscil gen1 (* .075 (oscil gen2)))) (* .8 (oscil gen3 (+ (* .0125 (oscil gen4)) (rand-interp rnd)))))))) (mus-reset pulsef1) ;; now the remaining pulses (do ((k 1 (+ k 1))) ((= k pulses)) (set! next-start (+ next-start pulse-sep)) (set! pstop (+ next-start pulse-samps)) (do ((j next-start (+ j 1))) ((= j pstop)) (outa j (* (env pulsef) (+ (* .2 (oscil gen1 (* .075 (oscil gen2)))) (* .8 (oscil gen3 (+ (* .0125 (oscil gen4)) (rand-interp rnd)))))))) (mus-reset pulsef)))))) ;; (with-sound (:play #t) (striped-ground-cricket 0 3 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Sphagnum ground cricket (defanimal (sphagnum-ground-cricket beg dur amp) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (gen1 (make-oscil 8850)) (gen2 (make-oscil (* 8850 2))) (rnd1 (make-rand-interp 885 .03)) (rnd2 (make-rand-interp 885 .1)) (ampf (make-env '(0 0 1 1 10 1 11 0) :duration dur :scaler amp)) (pulsef (make-env '(0.000 0.000 0.041 0.5 0.250 0.7 0.4 1.0 0.5 0.9 0.8 0.3 1.000 0.000) :duration .013)) (pulse-samps (seconds->samples .019)) (pulse-out (seconds->samples .013))) (do ((i start (+ i pulse-samps))) ((>= i stop)) (set! (mus-location ampf) (- i start)) (let ((reset-stop (min stop (+ i pulse-out))) (pulse-amp (env ampf))) (do ((k i (+ k 1))) ((= k reset-stop)) (outa k (* pulse-amp (env pulsef) (+ (* .9 (oscil gen1 (rand-interp rnd1))) (* .1 (oscil gen2 (rand-interp rnd2))))))) (mus-reset pulsef))))) ;; (with-sound (:play #t) (sphagnum-ground-cricket 0 2 .3)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Southeastern field cricket (defanimal (southeastern-field-cricket beg dur amp) (let ((pulse-dur 0.027)) ; occasionally a hicccup = .039, 30..100 pulses per song (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (gen1 (make-polywave 4730 '(1 .8 2 .1 3 .1))) (rnd (make-rand-interp (* 2 473) 1)) (oz (make-one-zero 1.0 -1.0)) (ampf (make-env '(0 0 1 1 10 1 11 0) :duration dur :scaler amp)) (pulsef (make-env '(0.0 0.0 0.05 0.38 0.14 0.77 0.26 0.95 0.47 1.0 0.57 0.9 0.81 0.5 0.85 0.3 1.0 0.0) :duration .014)) (pulses (+ 30 (random 70))) (pulse-samps (seconds->samples pulse-dur)) (current-pulse-samps (seconds->samples pulse-dur))) (do ((i start (+ i current-pulse-samps))) ((>= i stop)) (set! (mus-location ampf) (- i start)) (let ((reset-stop (min stop (+ i pulse-samps))) (pulse-amp (env ampf))) (do ((k i (+ k 1))) ((= k reset-stop)) (outa k (* pulse-amp (env pulsef) (polywave gen1 (one-zero oz (rand-interp rnd)))))) (mus-reset pulsef) (set! pulses (- pulses 1)) (if (<= pulses 0) (begin (set! current-pulse-samps (+ pulse-samps (seconds->samples (+ .2 (random .1))))) (set! pulses (+ 30 (random 70)))) (begin (if (> (random 1.0) .95) (set! pulse-samps (seconds->samples (+ pulse-dur .005 (random .01)))) (set! pulse-samps (seconds->samples pulse-dur))) (set! current-pulse-samps pulse-samps)))))))) ;; (with-sound (:play #t) (southeastern-field-cricket 0 5 .3)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Snowy tree cricket (defanimal (snowy-tree-cricket beg dur amp) (let ((pitch 1690)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (gp (make-polywave pitch '(1 .9 2 .05 3 .05))) (rnd (make-rand-interp 1000 .014)) (pulsef (make-env '(0.0 0.0 0.04 0.79 0.08 0.09 0.11 0.02 0.14 0.83 0.15 0.95 0.21 0.05 0.26 0.02 0.29 0.79 0.31 0.89 0.35 0.07 0.38 0.04 0.39 0.79 0.42 0.94 0.45 0.08 0.48 0.05 0.50 0.80 0.52 0.96 0.59 0.02 0.64 0.01 0.66 0.78 0.68 0.95 0.72 0.06 0.75 0.04 0.76 0.70 0.79 0.96 0.83 0.07 0.85 0.02 0.88 0.80 0.90 1.0 0.95 0.12 0.97 0.04 1.00 0.00) :scaler amp :duration .352 :base .1)) (frqf (make-env '(0.0 0.0 0.04 1.0 0.08 0.0 0.11 0.0 0.14 1.0 0.15 0.0 0.21 0.0 0.26 0.0 0.29 1.0 0.31 0.0 0.35 0.0 0.38 0.0 0.39 1.0 0.42 0.0 0.45 0.0 0.48 0.0 0.50 1.0 0.52 0.0 0.59 0.0 0.64 0.0 0.66 1.0 0.68 0.0 0.72 0.0 0.75 0.0 0.76 1.0 0.79 0.0 0.83 0.0 0.85 0.0 0.88 1.0 0.90 0.0 0.95 0.0 0.97 0.0 1.00 0.0) :duration .352 :scaler (hz->radians 60))) (reset-samps (seconds->samples .85)) (on-samps (seconds->samples .36))) ; else ampf is 0.0 (do ((i start (+ i reset-samps))) ((>= i stop)) (let ((reset-stop (min stop (+ i on-samps)))) (do ((k i (+ k 1))) ((= k reset-stop)) (outa k (* (env pulsef) (polywave gp (+ (env frqf) (rand-interp rnd)))))) (mus-reset pulsef) (mus-reset frqf)))))) ;; (with-sound (:play #t) (snowy-tree-cricket 0 2 .3)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Slightly musical conehead ;;; ;;; this could use some work (defanimal (slightly-musical-conehead beg dur amp) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (gen1 (make-oscil 11000)) (gp (make-polywave 1100 '(1 .1 5 .05))) (rnd1 (make-rand-interp 1100 .05)) (rnd2 (make-rand-interp 1100 .4)) (pulse-samps (seconds->samples .36)) (pulse-out (seconds->samples .146)) (pulsef (make-env '(0.00 0.00 0.02 0.29 0.04 0.55 0.07 0.37 0.08 0.06 0.11 0.48 0.14 0.13 0.15 0.69 0.18 0.31 0.20 0.07 0.22 0.77 0.23 0.52 0.25 0.77 0.26 0.21 0.28 0.70 0.30 0.12 0.34 0.80 0.38 0.17 0.39 0.79 0.42 0.08 0.44 0.54 0.48 0.53 0.50 0.85 0.53 0.11 0.55 0.51 0.58 0.79 0.60 0.22 0.62 0.84 0.65 0.09 0.67 0.56 0.70 0.91 0.74 0.81 0.77 0.10 0.79 0.70 0.83 0.51 0.85 0.90 0.88 0.03 0.90 0.55 0.93 0.60 0.95 0.11 0.97 0.97 1.0 0.00) :scaler amp :duration .146))) (do ((i start (+ i pulse-samps))) ((>= i stop)) (let ((reset-stop (min stop (+ i pulse-out)))) (do ((k i (+ k 1))) ((= k reset-stop)) (outa k (* (env pulsef) (+ .6 (rand-interp rnd2)) (oscil gen1 (polywave gp (rand-interp rnd1)))))) (mus-reset pulsef))))) ;; (with-sound (:play #t) (slightly-musical-conehead 0 2 .4)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Pine tree cricket (defanimal (pine-tree-cricket beg dur amp) (let ((pulse-dur .014)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (pulsef (make-env '(0.000 0.000 0.027 0.196 0.104 0.448 0.236 0.773 0.341 0.910 0.416 0.975 0.532 1.0 0.671 0.868 0.751 0.711 0.833 0.504 0.926 0.160 1.000 0.000) :scaler amp :duration pulse-dur)) (gp (make-polywave 3580 '(1 .97 3 .03))) (frqf (make-env '(0 1 1 0) :scaler (hz->radians 100) :duration pulse-dur)) (pulse-samps (seconds->samples .022)) (pulse-out (seconds->samples pulse-dur)) (rnd (make-rand-interp 100 .004))) (do ((i start (+ i pulse-samps))) ((>= i stop)) (let ((reset-stop (min stop (+ i pulse-out)))) (do ((k i (+ k 1))) ((= k reset-stop)) (outa k (* (env pulsef) (polywave gp (+ (env frqf) (rand-interp rnd)))))) (mus-reset frqf) (mus-reset pulsef)))))) ;; (with-sound (:play #t) (pine-tree-cricket 0 2 .25)) ;;;-------------------------------------------------------------------------------- ;;; ;;; Davis's tree cricket (defanimal (davis-tree-cricket beg dur amp) (let ((pulse-dur .013) (pitch 2420)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (pulse-samps (seconds->samples 0.014)) (pulse-out (seconds->samples pulse-dur)) (pulsef (make-env '(0.000 0.000 0.079 0.395 0.245 0.925 0.410 1.000 0.470 0.874 0.554 0.549 0.614 0.312 0.728 0.170 1.000 0.000) :scaler amp :duration pulse-dur)) (gp (make-polywave pitch '(1 .93 2 .07))) (rnd (make-rand-interp 150 .004))) (do ((i start (+ i pulse-samps))) ((>= i stop)) (let ((reset-stop (min stop (+ i pulse-out)))) (do ((k i (+ k 1))) ((= k reset-stop)) (outa k (* (env pulsef) (polywave gp (rand-interp rnd))))) (mus-reset pulsef)))))) ;; (with-sound (:play #t) (davis-tree-cricket 0 2 .25)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Black-horned tree cricket (defanimal (black-horned-tree-cricket beg dur amp) (let ((pulse-dur 0.0173) (pulse-space 0.0219) (start (seconds->samples beg))) (let ((stop (seconds->samples (+ beg dur))) (pulse-samps (seconds->samples pulse-space)) (pulse-out (seconds->samples pulse-dur)) (ampf (make-env '(0 0 .05 1 .95 1 1 0) :duration dur :scaler amp)) (gen1 #f) (rnd (make-rand-interp 1000 (hz->radians 50))) (pulse-ampf (make-env '(0.000 0.000 0.076 0.443 0.277 0.866 0.454 0.925 0.603 0.771 0.690 0.573 0.726 0.304 1.000 0.000) :duration pulse-dur))) (do ((i start (+ i pulse-samps))) ((>= i stop)) (set! (mus-location ampf) (- i start)) (let ((reset-stop (min stop (+ i pulse-out))) (pulse-amp (env ampf))) (set! gen1 (make-polywave 3680.0 (list 1 (* pulse-amp .94) 2 (* pulse-amp .04) 3 (* pulse-amp .01) 4 (* pulse-amp .005) 5 (* pulse-amp .003)))) (do ((k i (+ k 1))) ((= k reset-stop)) (outa k (* (env pulse-ampf) (polywave gen1 (rand-interp rnd))))) (mus-reset pulse-ampf)))))) ;; (with-sound (:play #t) (black-horned-tree-cricket 0 2 .25)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Narrow-winged tree cricket (defanimal (narrow-winged-tree-cricket beg dur amp) ;; insects 18 4 (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0 0 .1 1 20 1 20.1 0) :duration dur :scaler amp)) (pulser (make-wave-train-with-env 43.0 '(0.000 0.000 0.144 0.332 0.269 0.715 0.361 0.838 0.459 0.866 0.609 0.727 0.652 0.530 0.780 0.194 1.000 0.000) (seconds->samples .0185))) (gen1 (make-polywave 1900 '(1 .8 2 .07 3 .13))) (rnd (make-rand-interp 150 (hz->radians 20)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (wave-train pulser) (polywave gen1 (rand-interp rnd))))))) ;; (with-sound (:play #t) (narrow-winged-tree-cricket 0 2 .25)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Four-spotted tree cricket (defanimal (four-spotted-tree-cricket beg dur amp) ;; insects 16 4 (let ((index (hz->radians 400))) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0 0 .3 1 20 1 20.3 0) :duration dur :scaler amp)) (amp-pulser (make-table-lookup-with-env 40.0 '(0.000 0.000 0.071 0.518 0.174 0.783 0.315 0.885 0.492 0.727 0.579 0.466 0.625 0.186 0.671 0.028 0.755 0.083 0.848 0.024 0.935 0.126 1.000 0.000 1.5 0) (seconds->samples .025))) (frq-pulser (make-table-lookup-with-env 40.0 (list 0 index 1 0 2 0) (seconds->samples .025))) (gen1 (make-polywave 3220 '(1 .92 2 .07 3 .01))) (gen2 (make-oscil 5000)) (gen3 (make-oscil 2200)) (rnd1 (make-rand-interp 8000 (hz->radians 2000))) (rnd (make-rand-interp 200 (hz->radians 30)))) (do ((i start (+ i 1))) ((= i stop)) (let ((noise (rand-interp rnd1))) (outa i (* (env ampf) (+ (* (table-lookup amp-pulser) (polywave gen1 (+ (rand-interp rnd) (table-lookup frq-pulser)))) (* .05 (+ (oscil gen2 noise) (* .2 (oscil gen3 (* .2 noise))))))))))))) ;; (with-sound (:play #t) (four-spotted-tree-cricket 0 1 .5)) ;;; ================ Birds ================ ;;; ;;; ;;; Fox sparrow (defanimal (fox-sparrow beg dur amp) (let ((begs (vector 0.0 0.3 0.6 0.93 1.23 1.49 1.74 1.98 2.12 2.29 3.0)) (ends (vector 0.12 0.46 0.85 1.17 1.44 1.7 1.95 2.08 2.26 2.45)) (low-frqs (vector 4260 4010 3910 4970 3360 3160 2810 2310 2700 2700)) (high-frqs (vector 5120 4170 5420 5520 4220 3410 5470 2460 3710 3710)) (start (seconds->samples beg))) (let ((stop (seconds->samples (+ beg dur))) (amp-envs (make-vector 10 #f)) (frq-envs (make-vector 10 #f)) (gen1 (make-oscil)) (gen2 (make-oscil)) (peep 0) (peep-dur 0) (peep-start 0) (durs (let ((v (make-vector 10 0.0))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v i) (- (ends i) (begs i)))) v)) (scls (vector .09 .19 .22 .19 .27 .23 .21 .04 .17 .17)) (amps (vector '(0.000 0.000 0.17 0.13 0.38 0.67 0.64 1.0 0.78 0.79 0.9 0.04 1.0 0.0) '(0.000 0.000 0.15 0.15 0.27 0.67 0.37 0.89 0.69 1.0 0.79 0.6 0.8 0.05 1.0 0.0) '(0.000 0.000 0.11 0.28 0.18 0.66 0.35 0.98 0.90 0.92 1.0 0.0) '(0.000 0.000 0.11 0.28 0.14 0.70 0.32 0.98 0.85 0.84 1.0 0.0) '(0.000 0.000 0.11 0.28 0.14 0.70 0.32 0.98 0.85 0.84 1.0 0.0) '(0.000 0.000 0.15 0.86 0.24 1.00 0.63 0.64 0.89 0.61 1.0 0.0) '(0.000 0.000 0.27 0.80 0.37 1.00 0.63 0.64 0.88 0.51 1.0 0.0) '(0.000 0.000 0.08 0.48 0.37 1.00 0.88 0.76 1.00 0.0) '(0.000 0.000 0.12 0.43 0.24 1.00 0.59 0.72 0.88 0.35 1.0 0.0) '(0.000 0.000 0.12 0.43 0.24 1.00 0.59 0.72 0.88 0.35 1.0 0.0))) (frqs (vector '(0 1 1 0) '(0 0 1 .5 8 .6 9 1.0) '(0 1 1 .5 2 .2 3 0) '(0 1 1 0 5 0) '(0 1 1 .3 2 0) '(0 1 1 1) '(0 1 2 .2 3 0) '(0 0 1 .9 2 1) '(0 1 1 .4 2 0) '(0 1 1 .3 2 0))) (rnd (make-rand-interp 100 .01))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (amp-envs i) (make-env (amps i) :scaler (/ (* amp (scls i)) .27) :duration (durs i))) (set! (frq-envs i) (make-env (frqs i) :scaler (hz->radians (- (high-frqs i) (low-frqs i))) :offset (hz->radians (low-frqs i)) :duration (durs i)))) (set! peep-dur (seconds->samples (durs 0))) (set! peep-start (+ start (seconds->samples (begs 0)))) (call-with-exit (lambda (done) (do ((i peep-start peep-start)) ((>= i stop)) (let ((fe (frq-envs peep)) (ae (amp-envs peep)) (reset-stop (min stop (+ i peep-dur)))) (do ((k i (+ k 1))) ((= k reset-stop)) (let ((frq (+ (env fe) (rand-interp rnd)))) (outa k (* (env ae) (oscil gen1 frq (* .03 (oscil gen2 (* 2.0 frq))))))))) (set! peep (+ peep 1)) (if (>= peep 10) (done)) (set! peep-start (+ start (seconds->samples (begs peep)))) (set! peep-dur (seconds->samples (durs peep))))))))) ;; (with-sound (:play #t) (fox-sparrow 0 3 .25)) ;;; -------------------------------------------------------------------------------- ;;; ;;; White-throated sparrow ;;; ;;; probably music of birds 14, 1st song (defanimal (white-throated-sparrow beg amp) (let ((dur (+ 3.25 (random .2))) (pitch 3800)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.00 0.00 0.04 0.44 0.09 0.59 0.12 0.59 0.16 0.75 0.17 0.00 0.22 0.00 0.25 0.76 0.28 0.89 0.29 0.14 0.31 0.93 0.34 0.87 0.35 0.14 0.36 0.85 0.37 0.84 0.38 0.00 0.42 0.00 0.44 0.86 0.46 0.83 0.47 0.91 0.51 0.92 0.52 0.87 0.53 0.00 0.57 0.00 0.58 0.65 0.60 0.88 0.61 0.14 0.62 0.95 0.63 0.94 0.64 0.20 0.66 0.99 0.67 0.88 0.68 0.00 0.72 0.00 0.73 0.65 0.75 0.82 0.76 0.13 0.77 0.78 0.78 0.88 0.79 0.83 0.797 0.12 0.803 0.12 0.81 0.79 0.82 0.87 0.83 0.00 0.87 0.00 0.89 0.58 0.91 0.75 0.917 0.13 0.923 0.13 0.93 0.73 0.94 0.84 0.95 0.77 0.957 0.12 0.963 0.12 0.97 0.81 0.98 0.79 1.00 0.00) :duration dur :scaler amp)) (frqf (make-env '(0 0 .17 0.0 .21 1 0.22 1.5 0.23 1 0.41 1 0.42 1.25 0.43 1 0.56 1 0.57 1.25 0.58 1 0.71 1 0.72 1.25 0.73 1 0.86 1 0.87 1.25 0.88 1 1 1) :scaler (hz->radians 720) :duration dur)) (gen1 (make-polywave pitch :partials '(1 .9 2 .025 3 .075))) (rnd (make-rand-interp 30 .005))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (+ (env frqf) (mus-random 0.001) (rand-interp rnd))))))))) ;; (with-sound (:play #t) (white-throated-sparrow 0 .25)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Henslow's sparrow (defanimal (henslows-sparrow beg amp) ;; "the poorest vocal effort of any bird" -- R T Peterson (let ((dur 0.24)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.00 0.00 0.05 0.42 0.08 0.03 0.10 0.30 0.12 0.02 0.21 0.00 0.22 0.69 0.23 0.34 0.24 0.84 0.26 0.64 0.28 0.04 0.29 0.11 0.30 0.47 0.32 0.00 0.46 0.00 0.48 0.04 0.52 1.00 0.53 0.97 0.54 0.44 0.55 0.80 0.57 0.02 0.58 0.07 0.59 0.72 0.60 0.45 0.61 0.79 0.62 0.66 0.63 0.81 0.66 0.05 0.67 0.16 0.73 0.50 0.75 0.52 0.78 0.04 0.81 0.03 0.82 0.08 0.85 0.47 0.87 0.22 0.88 0.39 0.90 0.09 0.91 0.36 0.96 0.39 0.98 0.07 1.00 0.00) :duration dur :scaler amp)) (gen1 (make-oscil)) (frqf (make-env '(0.00 9310 0.05 9560 0.08 9480 0.10 9900 0.11 8140 0.12 9900 0.21 9980 0.22 8630 0.23 8800 0.24 8400 0.26 8800 0.28 8600 0.29 8800 0.30 8300 0.32 8100 0.46 8100 0.48 5600 0.49 5200 0.52 6200 0.54 4800 0.55 6600 0.57 5800 0.58 5800 0.59 6200 0.60 6200 0.62 5800 0.66 3600 0.67 4400 0.73 3900 0.78 3100 0.85 4900 0.88 3600 0.90 3900 0.91 4400 1.00 3900) :duration dur :scaler (hz->radians 1.0)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (oscil gen1 (env frqf)))))))) ;; (with-sound (:play #t) (henslows-sparrow 0 .25)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Eastern wood-pewee (defanimal (eastern-wood-pewee-1 beg amp) ;; probably east 39 3 (let ((dur 1.07)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.037 0.894 0.045 0.711 0.061 0.845 0.072 0.760 0.076 0.912 0.084 0.838 0.099 0.982 0.111 0.729 0.124 0.879 0.142 0.011 0.15 0.01 0.165 0.778 0.172 0.601 0.180 0.706 0.212 0.441 0.258 0.227 0.298 0.325 0.312 0.564 0.334 0.312 0.365 0.399 0.416 0.260 0.475 0.196 0.555 0.356 0.631 0.363 0.712 0.294 0.746 0.464 0.753 0.369 0.776 0.508 0.799 0.425 0.825 0.479 0.869 0.485 0.877 0.567 0.907 0.541 0.918 0.459 0.942 0.513 0.977 0.366 1.000 0.000) :duration dur :scaler amp)) (gen1 (make-polywave 0.0 '(1 .905 2 .025 3 .025))) (frqf (make-env '(0 3370 .03 4300 .1 4600 .14 3400 0.15 4400 .16 3700 .18 4400 .24 4700 .3 4600 .34 3600 .4 3700 .6 3800 .8 4000 1.0 3900) :duration dur :base .1 :scaler (hz->radians 1.0)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) ;; (with-sound (:play #t) (eastern-wood-pewee-1 0 .25)) (defanimal (eastern-wood-pewee-2 beg amp) ;; probably east 39 14 (let ((dur 1.07)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.055 0.665 0.081 0.657 0.101 0.456 0.140 0.572 0.165 0.477 0.219 0.564 0.288 0.526 0.306 0.668 0.328 0.613 0.387 0.830 0.402 1.000 0.434 0.768 0.455 0.214 0.470 0.173 0.484 0.387 0.499 0.631 0.512 0.229 0.559 0.142 0.582 0.165 0.698 0.085 1.000 0.000) :duration dur :scaler amp)) (gen1 (make-oscil)) (gen2 (make-oscil)) (gen3 (make-oscil)) (frqf (make-env '(0 3250 .1 4400 .2 4800 .3 4800 .47 4000 .49 6300 .51 3600 1.0 2800) :duration dur :base .03 :scaler (hz->radians 1.0))) (indf (make-env '(0 0 .35 0 .55 1 1 1) :duration dur :scaler 0.1)) (indf-1 (make-env '(0 0 .35 0 .55 1 1 1) :duration dur :offset 1.0 :scaler -1.0))) (do ((i start (+ i 1))) ((= i stop)) (let ((frq (env frqf))) (outa i (* (env ampf) (+ (* .9 (oscil gen1 frq)) (* (env indf) (oscil gen2 (* 2.0 frq))) (* (env indf-1) .075 (oscil gen3 (* 3.0 frq))))))))))) ;; (with-sound (:play #t) (eastern-wood-pewee-2 0 .25)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Field sparrow (defanimal (field-sparrow beg amp) (let ((dur 2.92)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.025 0.201 0.095 0.307 0.113 0.235 0.122 0.005 0.146 0.000 0.167 0.696 0.201 0.430 0.241 0.325 0.243 0.000 0.265 0.000 0.287 0.840 0.300 0.791 0.312 0.567 0.354 0.369 0.365 0.000 0.388 0.000 0.405 0.853 0.430 0.621 0.449 0.387 0.470 0.314 0.477 0.000 0.493 0.000 0.511 0.887 0.529 0.796 0.552 0.402 0.566 0.327 0.578 0.000 0.594 0.000 0.614 0.966 0.629 0.446 0.645 0.273 0.649 0.000 0.65 0.0 0.664 0.026 0.673 1.0 0.690 0.459 0.706 0.000 0.714 0.031 0.719 0.892 0.74 0.0 0.747 0.000 0.755 0.851 0.773 0.0 0.781 0.000 0.790 0.869 0.81 0.0 0.814 0.000 0.827 0.827 0.845 0.0 0.849 0.000 0.861 0.786 0.878 0.0 0.882 0.000 0.894 0.716 0.912 0.0 0.918 0.000 0.925 0.711 0.943 0.0 0.949 0.000 0.959 0.657 0.97 0.0 0.975 0.000 0.984 0.536 0.993 0.149 1.000 0.000) :duration dur :scaler amp)) (gp (make-polywave 0.0 '(1 .99 2 .01))) (frqf (make-env '(0.000 4300 0.025 4300 0.1 3300 0.122 3300 0.146 4300 0.18 4300 0.23 3300 0.243 3300 0.265 4300 0.3 4300 0.35 3300 0.365 3300 0.388 4300 0.42 4300 0.46 3300 0.477 3300 0.493 4300 0.52 4300 0.56 3300 0.578 3300 0.594 4300 0.61 4300 0.63 3300 0.649 3300 0.65 4300 0.664 4300 0.68 4300 0.714 3300 0.716 4300 0.74 3200 0.747 4300 0.75 4300 0.773 3200 0.781 4300 0.785 4300 0.81 3200 0.814 4300 0.82 4300 0.845 3200 0.849 4300 0.85 4300 0.878 3200 0.882 4300 0.89 4300 0.912 3200 0.918 4300 0.92 4300 0.943 3200 0.949 4300 0.95 4300 0.97 3200 0.975 4300 0.98 4300 0.993 3200 1.000 3300) :duration dur :scaler (hz->radians 1.0)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gp (env frqf)))))))) ;; (with-sound (:play #t) (field-sparrow 0 .25)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Tufted titmouse (defanimal (tufted-titmouse beg amp) (let ((dur 1.0)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.00 0.034 0.637 0.060 0.591 0.074 0.458 0.095 0.872 0.119 0.473 0.185 0.033 0.211 0.102 0.233 0.00 0.384 0.00 0.425 0.926 0.447 0.898 0.461 0.665 0.471 1.0 0.497 0.578 0.529 0.422 0.565 0.054 0.594 0.107 0.616 0.00 0.755 0.00 0.807 0.905 0.829 0.870 0.837 0.675 0.847 0.992 0.867 0.739 0.891 0.486 0.942 0.056 0.970 0.130 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.0 3730 .04 3900 .07 3770 .09 2800 .17 2470 .19 2050 .21 2320 .23 2100 .38 3730 .42 3900 .45 3770 .46 2760 .53 2470 .55 2050 .58 2320 .6 2100 .75 3730 .79 3900 .83 3770 .84 2720 .91 2470 .94 2050 .96 2320 1.0 2100) :duration dur :base .1 :scaler (hz->radians 1.0))) (gen1 (make-polywave 0.0 '(1 .99 2 .01)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) ;; (with-sound (:play #t) (tufted-titmouse 0 .3)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Savannah sparrow ;;; ;;; 8 separate calls make up a song (defanimal (savannah-sparrow beg amp) (define (savannah-1 beg amp) ;; peeps (let ((dur .05) (hi-pitch 9000) (lo-pitch 7460)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0 0 1 1 2 0) :duration dur :scaler amp)) (frqf (make-env '(0 1 1 0) :duration dur :scaler (hz->radians (- hi-pitch lo-pitch)) :offset (hz->radians lo-pitch))) (gp (make-polywave 0.0 '(1 .98 2 .02))) (gen3 (make-oscil 80))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (+ .8 (* .2 (abs (oscil gen3)))) (polywave gp (env frqf)))))))) (define (savannah-2 beg amp pitch) ;; buzz (let ((dur .008) (hi-pitch (+ pitch 400)) (lo-pitch pitch)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.094 0.228 0.148 0.832 0.248 1.000 0.364 0.695 0.522 0.586 0.634 0.284 0.801 0.558 0.891 0.102 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0 1 1 0) :duration dur :scaler (hz->radians (- hi-pitch lo-pitch)) :offset (hz->radians lo-pitch))) (gen1 (make-oscil)) (rnd (make-rand-interp 300 .03))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (oscil gen1 (+ (env frqf) (rand-interp rnd))))))))) (define (savannah-3 beg amp) ;; ticks (let ((dur .004)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (rnd (make-rand 4000 .4)) (gen1 (make-oscil 8000)) (ampf (make-env '(0 0 1 1 2 .3 10 0) :duration dur :base 32 :scaler amp))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (oscil gen1 (rand rnd)))))))) (define (savannah-4 beg amp) (let ((dur .034)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (rnd (make-rand 12000 .1)) (gen1 (make-oscil 6400)) (frqf (make-env '(0 .5 1 0 2 1 4 1) :scaler (hz->radians 400) :duration dur)) (ampf (make-env '(0.000 0.000 0.045 0.018 0.067 0.196 0.096 0.004 0.166 0.032 0.196 0.207 0.209 0.116 0.239 0.575 0.249 0.639 0.280 0.063 0.297 0.032 0.312 0.070 0.339 0.021 0.372 0.049 0.378 0.544 0.391 0.088 0.437 0.211 0.441 0.611 0.455 0.218 0.480 0.140 0.498 0.253 0.506 0.593 0.516 0.228 0.532 0.098 0.551 0.200 0.569 0.544 0.593 0.253 0.630 0.540 0.660 0.133 0.684 0.540 0.722 0.158 0.748 0.604 0.760 0.779 0.787 0.260 0.824 1.000 0.847 0.249 0.878 0.874 0.917 0.204 0.976 0.056 1.000 0.000) :duration dur :scaler amp))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (oscil gen1 (+ (env frqf) (rand rnd))))))))) (define (savannah-5 beg amp) (let ((dur .071)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (rnd (make-rand 12000 .1)) (gen1 (make-oscil 8500)) (ampf (make-env '(0.000 0.000 0.067 0.060 0.084 0.432 0.098 0.414 0.111 1.000 0.123 0.267 0.148 0.028 0.160 0.877 0.181 0.151 0.189 0.007 0.305 0.007 0.316 0.347 0.331 0.225 0.341 1.000 0.353 0.382 0.360 0.137 0.374 0.039 0.388 0.053 0.398 0.919 0.404 0.688 0.415 0.196 0.438 0.000 0.530 0.000 0.542 0.502 0.561 0.151 0.573 0.958 0.586 0.218 0.599 0.035 0.616 0.067 0.623 0.811 0.642 0.144 0.661 0.000 0.767 0.000 0.785 0.225 0.799 0.923 0.822 0.000 0.853 0.000 0.861 0.674 0.880 0.053 0.906 0.000 1.000 0.000) :duration dur :scaler amp))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (oscil gen1 (rand rnd)))))))) (define (savannah-6 beg amp) (let ((dur .023)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (rnd (make-rand 3500 .15)) (gen1 (make-oscil 3600)) (ampf (make-env '(0.000 0.000 0.297 0.323 0.339 0.547 0.388 0.891 0.439 1.000 0.553 0.975 0.591 0.295 0.615 0.168 0.678 0.011 0.731 0.105 0.758 0.709 0.800 0.312 0.884 0.077 1.000 0.000) :duration dur :scaler amp))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (oscil gen1 (rand rnd)))))))) (define (savannah-7 beg amp) (let ((dur .053) (hi-pitch 8250) (lo-pitch 6900)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0 0 2 1 3 0) :duration dur :scaler amp)) (frqf (make-env '(0 0 1 1) :duration dur :scaler (hz->radians (- hi-pitch lo-pitch)) :offset (hz->radians lo-pitch))) (gen1 (make-oscil)) (gen2 (make-oscil 220))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (+ .25 (* .75 (abs (oscil gen2)))) (oscil gen1 (env frqf)))))))) (define (savannah-8 beg amp) (let ((dur .023)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (gen1 (make-oscil 3800)) (gen2 (make-oscil 150)) (ampf (make-env '(0.000 0.000 0.138 0.098 0.199 0.218 0.258 0.018 0.367 0.404 0.422 0.361 0.462 0.011 0.549 0.782 0.639 0.519 0.665 0.000 0.678 0.379 0.707 1.000 0.801 0.551 0.835 0.165 0.850 0.337 1.000 0.000) :duration dur :scaler amp))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (oscil gen1 0.0 (* 2.0 (oscil gen2))))))))) ;; -------- (savannah-1 beg (* amp .21)) (savannah-1 (+ beg .35) (* amp .45)) (savannah-1 (+ beg .35 .28) (* amp .51)) (savannah-1 (+ beg .35 .28 .24) (* amp .64)) (savannah-1 (+ beg .35 .28 .24 .26) amp) (savannah-1 (+ beg .35 .28 .24 .26 .17) amp) (savannah-4 (+ .97 beg) (* amp .21)) (do ((i 0 (+ i 1))) ((= i 6)) (savannah-3 (+ beg 1.02 (* i .014)) (* amp .12))) (savannah-5 (+ beg 1.19) (* amp .2)) (savannah-5 (+ beg 1.36) (* amp .2)) (savannah-6 (+ beg 1.46) (* amp .15)) (savannah-6 (+ beg 1.5) (* amp .15)) (let* ((repeats 20) (af-incr (/ .6 repeats))) (do ((i 0 (+ i 1)) (beg2 0.0 (+ beg2 .004)) (af af-incr (+ af af-incr))) ((= i repeats)) (savannah-2 (+ beg 1.58 beg2) (* amp af) 5250))) (let ((af .24)) (do ((i 0 (+ i 1))) ((= i 40)) (savannah-2 (+ beg 1.29 .36 (* i .0145)) (* amp af) 5600) (if (< i 20) (set! af (+ af .004)) (set! af (- af .004))))) (savannah-7 (+ beg 2.27) (* .4 amp)) (let ((dist 0.01)) (do ((i 0 (+ i 1)) (beg2 (+ beg 2.36) (+ beg2 dist)) (af .1 (* af .85))) ((= i 20)) (savannah-8 beg2 (* amp af)) (set! dist (+ dist .001))))) ;; (with-sound (:play #t) (savannah-sparrow 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Chipping sparrow (defanimal (chipping-sparrow beg amp) (let ((dur .055) (repeats (+ 20 (random 25)))) (let ((start (seconds->samples beg)) (total-dur (* repeats .068))) (let ((stop (+ start (seconds->samples total-dur))) (ampf (make-env '(0 0 1 .7 2 1 10 1 11 0) :duration total-dur :scaler amp)) (pulsef (make-env '(0.000 0.000 0.049 0.091 0.179 0.636 0.253 0.186 0.293 0.518 0.361 0.170 0.413 0.079 0.503 0.253 0.609 0.976 0.660 0.937 0.742 0.688 0.783 0.292 0.853 0.043 0.913 0.119 1.000 0.000) :duration dur)) (frqf (make-env '(0 7600 .1 7900 .18 8700 .2 9000 .23 8300 .32 5300 .4 4300 .5 4800 .6 5600 0.8 6400 1.0 5400) :duration dur :base 32 :scaler (hz->radians 1.0))) (gen1 #f) (pulse-samps (seconds->samples .068)) (pulse-out (seconds->samples dur)) ; pulsef and frqf dur (rnd (make-rand-interp 100 .02))) (do ((i start (+ i pulse-samps))) ((>= i stop)) (set! (mus-location ampf) (- i start)) (let ((reset-stop (min stop (+ i pulse-out))) (pulse-amp (env ampf))) (set! gen1 (make-polywave 0.0 (list 1 pulse-amp))) (do ((k i (+ k 1))) ((= k reset-stop)) (outa k (* (env pulsef) (polywave gen1 (+ (env frqf) (rand-interp rnd)))))) (mus-reset pulsef) (mus-reset frqf))))))) ;; (with-sound (:play #t) (chipping-sparrow 0 .3)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Least flycatcher (defanimal (least-flycatcher beg amp) (let ((call1-dur .032) (pause .065) (call2-dur .04) (start (seconds->samples beg))) (let ((stop1 (+ start (seconds->samples call1-dur))) (ampf1 (make-env '(0.000 0.000 0.223 0.158 0.386 0.379 0.617 1.0 0.679 0.929 0.810 0.458 1.000 0.000) :duration call1-dur :scaler amp)) (gen1 (make-oscil)) (gen11 (make-oscil)) (frqf1 (make-env '(0 3000 .4 6250 .5 6400 1.0 6000) :duration call1-dur :scaler (hz->radians 1.0))) (start2 (+ start (seconds->samples pause)))) (let ((stop2 (+ start2 (seconds->samples call2-dur))) (ampf2 (make-env '(0.000 0.000 0.088 0.124 0.157 0.258 0.198 0.202 0.237 0.264 0.273 0.823 0.286 0.419 0.328 0.814 0.343 1.000 0.360 0.329 0.409 0.413 0.435 0.935 0.448 0.295 0.481 0.183 0.539 0.901 0.563 0.444 0.619 0.373 0.644 0.944 0.662 0.311 0.724 0.053 0.756 0.186 0.782 0.432 0.823 0.512 0.865 0.174 0.886 0.230 1.000 0.000) :duration call2-dur :scaler (* .5 amp))) (gen2 (make-oscil 4600)) (gen21 (make-oscil 5600)) (gen22 (make-rand-interp 2000 (hz->radians 1000)))) (do ((i start (+ i 1))) ((= i stop1)) (let ((frq (env frqf1))) (outa i (* (env ampf1) (+ (* .9 (oscil gen1 frq)) (* .1 (oscil gen11 (* 2.0 frq)))))))) (do ((i start2 (+ i 1))) ((= i stop2)) (let ((noise (rand-interp gen22))) (outa i (* (env ampf2) (+ (* .7 (oscil gen2 noise)) (* .3 (oscil gen21 noise))))))))))) ;; (with-sound (:play #t) (least-flycatcher 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Acadian flycatcher (defanimal (acadian-flycatcher beg amp) (let ((dur 0.3)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.102 0.301 0.221 0.705 0.287 0.332 0.357 0.801 0.406 0.385 0.45 0 0.55 0 0.567 0.298 0.623 1.0 0.706 0.727 0.729 0.292 0.860 0.239 0.885 0.484 1.000 0.000) :duration dur :scaler amp)) (gen1 (make-polywave 0.0 '(1 .95 2 .05))) (frqf (make-env '(0 2800 .075 3600 .11 4200 .22 4900 .28 3200 .35 5400 .45 4200 .47 4000 .55 4900 .62 5000 .7 5500 .75 5200 .8 5500 .87 5400 1.0 2800) :duration dur :scaler (hz->radians 1.0) :base 32))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) ;; (with-sound (:play #t) (acadian-flycatcher 0 .25)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Swainson's thrush ;;; ;;; are there really multiphonics in this birdsong? ;;; also, is this a song that uses both parts of the syrinx? -- I think the doubled stuff is reverb (defanimal (swainsons-thrush beg amp) (let ((dur 2.0)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.058 0.146 0.075 0.127 0.085 0.000 0.113 0.000 0.143 0.481 0.150 0.516 0.227 0.735 0.238 0.000 0.260 0.000 0.289 0.474 0.311 0.423 0.316 0.000 0.337 0.000 0.350 0.559 0.355 0.805 0.367 0.895 0.413 0.990 0.427 0.598 0.446 0.373 0.452 0.066 0.460 0.103 0.470 0.651 0.492 0.828 0.510 0.502 0.531 0.457 0.541 0.000 0.568 0.000 0.569 0.424 0.587 0.548 0.603 0.553 0.613 0.061 0.645 0.633 0.686 0.760 0.703 0.000 0.726 0.000 0.727 0.236 0.735 0.037 0.793 0.301 0.815 0.125 0.835 0.130 0.847 0.000 0.868 0.000 0.931 0.180 1.000 0.000) :duration dur :scaler amp)) (gen1 (make-polywave 0.0 '(1 0.96 2 0.01 3 0.02 4 0.001 5 .005))) (gen2 (make-oscil)) ; eschew aliasing (intrpf (make-env '(0 1 .7 1 .75 0 1 0) :duration dur)) (intrpf-1 (make-env '(0 1 .7 1 .75 0 1 0) :duration dur :offset 1.0 :scaler -1.0)) (frqf (make-env '(0.000 0.000 0.01 0.175 0.015 0.264 0.02 0.172 0.025 0.263 0.03 0.171 0.035 0.260 0.04 0.172 0.045 0.263 0.05 0.172 0.055 0.265 0.06 0.171 0.065 0.263 0.07 0.170 0.077 0.267 0.08 0.174 0.085 0.266 0.09 0.170 0.095 0.265 0.1 0.171 0.105 0.266 0.107 0.186 0.128 0.172 0.141 0.240 0.155 0.238 0.164 0.280 0.170 0.180 0.178 0.330 0.181 0.177 0.190 0.322 0.196 0.185 0.201 0.326 0.207 0.288 0.242 0.283 0.272 0.238 0.276 0.238 0.288 0.238 0.318 0.238 0.342 0.240 0.344 0.270 0.355 0.325 0.365 0.376 0.370 0.325 0.378 0.376 0.383 0.325 0.390 0.376 0.395 0.309 0.401 0.426 0.410 0.502 0.424 0.305 0.433 0.280 0.436 0.238 0.447 0.241 0.453 0.199 0.466 0.378 0.471 0.431 0.482 0.391 0.494 0.384 0.504 0.350 0.516 0.334 0.532 0.334 0.558 0.330 0.564 0.412 0.569 0.477 0.578 0.511 0.582 0.568 0.590 0.429 0.596 0.553 0.604 0.416 0.620 0.735 0.629 0.653 0.641 0.617 0.647 0.572 0.656 0.542 0.662 0.510 0.681 0.436 0.689 0.379 0.694 0.293 0.719 0.395 0.723 0.510 0.734 0.555 0.743 0.807 0.765 0.786 0.783 0.637 0.797 0.875 0.806 0.902 0.812 0.957 0.832 0.981 0.85 .9 0.868 0.416 0.895 0.814 0.900 0.788 0.903 0.735 0.917 0.635 0.922 0.686 0.931 0.855 0.949 0.952 0.965 0.939 1.000 .9) :duration dur :scaler (hz->radians 8200)))) (do ((i start (+ i 1))) ((= i stop)) (let ((frq (env frqf))) (outa i (* (env ampf) (+ (* (env intrpf) (polywave gen1 frq)) (* (env intrpf-1) (oscil gen2 frq)))))))))) ;; (with-sound (:play #t) (swainsons-thrush 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Carolina wren (defanimal (carolina-wren beg amp) (let ((dur 1.84) (pulse-dur 0.25)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (pulsef (make-env '(0.000 0.000 0.027 0.031 0.049 0.185 0.065 0.749 0.121 0.508 0.137 0.339 0.146 0.270 0.195 0.571 0.247 0.806 0.270 0.994 0.311 0.837 0.325 0.129 0.335 0.373 0.354 0.000 0.512 0.000 0.525 0.677 0.548 0.831 0.560 0.737 0.594 0.082 0.602 0.000 0.618 0.223 0.635 0.313 0.657 0.712 0.698 0.649 0.716 0.517 0.741 0.006 0.775 0.094 0.791 0.467 0.808 0.373 0.838 0.480 0.885 0.414 0.917 0.160 0.930 0.031 1.000 0.000) :duration pulse-dur)) (frqf (make-env '(0.000 0.3 0.06 0.209 0.079 0.204 0.084 0.158 0.171 0.160 0.260 0.175 0.310 0.185 0.495 0.153 0.582 0.155 0.621 0.145 0.653 0.125 0.738 0.121 0.794 0.125 0.805 0.109 0.835 0.104 1.000 0.102) :duration pulse-dur :scaler (hz->radians 22050))) (ampf (make-env '(0 0 1 .5 16 1 18 .8 20 0) :duration dur :scaler amp)) (gen1 #f) (pulse-samps (seconds->samples (/ 1.6 6.0)))) ; .26 (do ((i start (+ i pulse-samps))) ((>= i stop)) (set! (mus-location ampf) (- i start)) (let ((reset-stop (min stop (+ i pulse-samps))) (pulse-amp (env ampf))) (set! gen1 (make-polywave 0.0 (list 1 (* pulse-amp .95) 2 (* pulse-amp .015) 3 (* pulse-amp .025) 3 (* pulse-amp .01)))) (do ((k i (+ k 1))) ((= k reset-stop)) (outa k (* (env pulsef) (polywave gen1 (env frqf))))) (mus-reset pulsef) (mus-reset frqf)))))) ;; (with-sound (:play #t) (carolina-wren 0 .25)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Bachman's sparrow (defanimal (bachmans-sparrow beg amp) ;; two pieces -- initial steady tone, then 10 repetitions of 2nd call (let ((call1-dur .576) (call2-dur .172) (start (seconds->samples beg))) (let ((stop1 (+ start (seconds->samples call1-dur))) (ampf1 (make-env '(0.000 0.000 0.684 0.978 0.863 1.0 0.962 0.773 1.000 0.000) :duration call1-dur :scaler (* .5 amp))) (gen1 (make-polywave 0.0 '(1 .98 3 .02))) ; first section uses ampf1 for amp scaling (.5) (frqf1 (make-env '(0 4970 1 4850) :duration call1-dur :scaler (hz->radians 1.0))) (pulse-samps (seconds->samples .184)) (pulse-out (seconds->samples call2-dur)) (stop2 (+ start (seconds->samples 2.4))) (ampf2 (make-env '(0.000 0.000 0.070 0.025 0.239 0.430 0.331 0.404 0.381 0.000 0.422 0.007 0.495 0.560 0.541 0.596 0.552 0.466 0.578 0.469 0.592 1.000 0.616 0.798 0.642 0.751 0.75 0 0.786 0.000 0.834 0.267 0.859 0.227 0.902 0.043 1.000 0.000) :duration call2-dur :scaler amp)) ;; these two envs may not be aligned correctly -- maybe backup the frq slightly? (frqf2 (make-env '(0.000 0.252 0.129 0.266 0.210 0.291 0.282 0.293 0.336 0.293 0.442 0.404 0.473 0.416 0.515 0.416 0.556 0.447 0.576 0.6 0.598 0.443 0.607 0.386 0.638 0.342 0.688 0.332 0.784 0.338 0.796 0.340 0.886 0.57 0.948 0.697 1 .7) :duration call2-dur :scaler (hz->radians 10000))) (ampf (make-env '(0 1 1.78 1 1.79 0 1.82 0) :duration 1.82))) (do ((i start (+ i 1))) ((= i stop1)) (outa i (* (env ampf1) (polywave gen1 (env frqf1))))) (do ((i stop1 (+ i pulse-samps))) ((>= i stop2)) (set! (mus-location ampf) (- i stop1)) (let ((reset-stop (min stop2 (+ i pulse-out))) (pulse-amp (env ampf))) (set! gen1 (make-polywave 0.0 (list 1 (* pulse-amp .98) 3 (* pulse-amp .02)))) (do ((k i (+ k 1))) ((= k reset-stop)) (outa k (* (env ampf2) (polywave gen1 (env frqf2))))) (mus-reset ampf2) (mus-reset frqf2)))))) ;; (with-sound (:play #t) (bachmans-sparrow 0 .25)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Grasshopper sparrow (defanimal (grasshopper-sparrow beg amp) ;; 2 portions -- simple tones, then a buzz (calif case has much tighter (faster) buzz) (let ((start (seconds->samples beg)) (begs (vector 0.0 .24 .36 .44 .55)) (durs (vector 0.019 0.020 0.011 0.021 1.09)) (amps (vector .48 .54 .07 .22 1.0)) (frqs (vector 8500 7240 9730 4920 8000)) (starts (make-vector 4 0)) (stops (make-vector 4 0)) (ampfs (make-vector 4 #f)) (gen1 (make-oscil))) (let ((buzz-start (+ start (seconds->samples (begs 4))))) (let ((buzz-end (+ buzz-start (seconds->samples (durs 4)))) (buzz-ampf (make-env '(0.000 0.000 0.095 0.953 0.114 0.182 0.158 0.822 0.236 0.996 0.332 1.000 0.848 0.589 0.957 0.372 1.000 0.000) :duration (durs 4) :scaler amp)) (buzzer (make-nrxysin 40 :n 5 :r .5)) ; sawtooth not great here due to broad spectrum (buzzer-index (hz->radians 2000)) (buzzer-amp (make-triangle-wave 40 0.8))) (do ((i 0 (+ i 1))) ((= i 4)) (set! (ampfs i) (make-env '(0 0 1 .8 1.5 1 2 .8 3 0) :duration (durs i) :scaler (* amp (amps i)))) (set! (starts i) (+ start (seconds->samples (begs i)))) (set! (stops i) (+ (starts i) (seconds->samples (durs i))))) ;; first the 4 tones (do ((tone 0 (+ 1 tone))) ((= tone 4)) (set! (mus-frequency gen1) (frqs tone)) (let ((ampf (ampfs tone)) (start (starts tone)) (end (stops tone))) (do ((i start (+ i 1))) ((= i end)) (outa i (* (env ampf) (oscil gen1)))))) ;; then the buzz (set! (mus-frequency gen1) 8000.0) (do ((i buzz-start (+ i 1))) ((= i buzz-end)) (outa i (* (env buzz-ampf) (+ 0.2 (abs (triangle-wave buzzer-amp))) (oscil gen1 (* buzzer-index (nrxysin buzzer)))))))))) ;; (with-sound (:play #t) (grasshopper-sparrow 0 .25)) ;;; -------------------------------------------------------------------------------- ;;; ;;; American robin (defanimal (american-robin beg amp) (let ((start (seconds->samples beg)) (ampfs (make-vector 4 #f)) (frqfs (make-vector 4 #f)) (starts (make-vector 4 0)) (stops (make-vector 4 0)) (begs (vector 0.0 0.6 1.3 1.8)) (durs (vector 0.34 0.25 0.16 0.39)) (amps (vector 0.6 1.0 0.7 0.95)) (gen1 (make-polywave 0.0 '(1 .95 2 .03 3 .01 4 .01))) (amp-envs (vector '(0.000 0.000 0.085 0.847 0.117 0.555 0.125 0.731 0.137 0.505 0.158 0.635 0.178 0.595 0.200 0.449 0.224 0.578 0.241 0.395 0.274 0.515 0.372 0.415 0.409 0.243 0.434 0.266 0.445 0.000 0.463 0.166 0.489 0.080 0.527 0.272 0.535 0.150 0.559 0.777 0.594 0.967 0.632 0.811 0.650 0.897 0.692 0.718 0.710 0.525 0.726 0.588 0.743 0.000 0.746 0.661 0.764 0.748 0.782 0.711 0.799 0.528 0.824 0.678 0.834 0.615 0.864 0.721 0.883 0.548 0.904 0.625 0.940 0.458 0.957 0.505 1.000 0.000) '(0.000 0.000 0.117 0.734 0.200 0.934 0.220 0.814 0.233 0.900 0.254 0.864 0.268 0.538 0.280 0.718 0.302 0.063 0.328 0.439 0.340 0.445 0.356 0.070 0.401 0.123 0.437 0.000 0.529 0.000 0.543 0.372 0.566 0.512 0.579 0.369 0.630 0.449 0.654 0.402 0.704 0.555 0.794 0.515 0.814 0.442 0.822 0.213 0.838 0.654 0.947 0.502 1.000 0.000) '(0.000 0.000 0.013 0.282 0.085 0.568 0.140 0.522 0.174 0.678 0.217 0.960 0.232 1.000 0.258 0.718 0.277 0.877 0.310 0.970 0.361 0.927 0.429 0.864 0.487 0.641 0.513 0.382 0.565 0.425 0.586 0.166 0.611 0.040 0.647 0.319 0.692 0.784 0.806 0.947 0.846 0.671 0.875 0.462 0.905 0.605 0.959 0.508 1.000 0.000) '(0.000 0.000 0.059 0.282 0.107 0.711 0.154 0.711 0.176 0.588 0.221 0.525 0.289 0.475 0.386 0.445 0.415 0.199 0.438 0.286 0.451 0.060 0.455 0.269 0.479 0.090 0.493 0.196 0.577 0.924 0.674 0.924 0.699 0.608 0.710 0.831 0.762 0.571 0.778 0.645 0.842 0.425 0.899 0.372 0.933 0.415 1.000 0.000))) (frq-envs (vector '(0.000 0.491 0.026 0.502 0.083 0.509 0.098 0.456 0.132 0.428 0.165 0.428 0.190 0.442 0.350 0.436 0.367 0.419 0.440 0.415 0.450 0.606 0.485 0.608 0.502 0.634 0.583 0.636 0.607 0.677 0.658 0.684 0.663 0.562 0.687 0.564 0.703 0.546 0.725 0.546 0.773 0.564 0.793 0.560 0.808 0.555 1.000 0.555) '(0.000 0.634 0.074 0.647 0.094 0.666 0.113 0.671 0.130 0.663 0.147 0.625 0.172 0.620 0.189 0.601 0.219 0.601 0.229 0.627 0.251 0.622 0.265 0.601 0.329 0.597 0.481 0.601 0.508 0.602 0.514 0.504 0.556 0.502 0.625 0.473 0.722 0.477 0.729 0.583 0.825 0.572 0.852 0.553 0.892 0.555 1.000 0.578) '(0.000 0.509 0.075 0.518 0.124 0.560 0.150 0.640 0.192 0.663 0.223 0.654 0.271 0.551 0.313 0.539 0.354 0.551 0.389 0.583 0.433 0.601 0.542 0.606 0.595 0.564 0.669 0.558 0.736 0.557 0.749 0.610 0.788 0.655 0.821 0.678 0.857 0.680 0.874 0.611 0.907 0.595 1.000 0.580) '(0.000 0.481 0.032 0.491 0.084 0.530 0.098 0.595 0.113 0.592 0.118 0.458 0.186 0.436 0.229 0.445 0.313 0.442 0.330 0.452 0.346 0.440 0.386 0.442 0.464 0.428 0.504 0.560 0.529 0.641 0.573 0.636 0.605 0.647 0.657 0.661 0.690 0.680 0.705 0.558 0.758 0.549 0.787 0.555 0.821 0.544 0.849 0.532 0.913 0.535 0.939 0.548 1.000 0.537)))) (do ((i 0 (+ i 1))) ((= i 4)) (set! (ampfs i) (make-env (amp-envs i) :duration (durs i) :scaler (* amp (amps i)))) (set! (frqfs i) (make-env (frq-envs i) :duration (durs i) :scaler (hz->radians 5000))) (set! (starts i) (+ start (seconds->samples (begs i)))) (set! (stops i) (+ (starts i) (seconds->samples (durs i))))) (do ((tone 0 (+ 1 tone))) ((= tone 4)) (let ((ampf (ampfs tone)) (frqf (frqfs tone)) (start (starts tone)) (end (stops tone))) (do ((i start (+ i 1))) ((= i end)) (outa i (* (env ampf) (polywave gen1 (env frqf))))))))) ;; (with-sound (:play #t) (american-robin 0 .25)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Common loon (defanimal (common-loon-1 beg amp) (let ((dur 2.5)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.049 0.134 0.122 0.131 0.174 0.070 0.178 0.244 0.522 0.954 0.649 0.922 0.736 1.0 0.860 0.962 0.957 0.839 .98 .5 1.000 0.000) :duration dur :scaler amp)) (gen1 (make-polywave 0.0 '(1 .85 2 .1 3 .02 4 .05 5 .01 7 .003 9 .001))) (frqf (make-env '(0.000 0.330 0.030 0.388 0.087 0.395 0.155 0.509 0.158 0.609 0.204 0.633 0.346 0.685 0.35 0.852 0.469 0.882 0.585 0.886 0.780 0.888 0.896 0.878 0.961 0.869 .98 .8 1.000 0.76) :duration dur :scaler (hz->radians 1000.0)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) ;; (with-sound (:play #t) (common-loon-1 0 .25)) (defanimal (common-loon-2 beg amp) (let ((dur 0.63)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.021 0.270 0.045 0.253 0.088 0.103 0.141 0.416 0.165 0.251 0.179 0.107 0.192 0.403 0.211 0.399 0.222 0.208 0.242 0.206 0.286 0.895 0.303 0.882 0.327 0.672 0.350 0.324 0.362 0.150 0.378 0.236 0.389 0.268 0.423 0.991 0.447 0.923 0.459 0.785 0.488 0.242 0.506 0.200 0.531 0.245 0.540 0.371 0.556 0.785 0.566 0.792 0.573 0.981 0.579 0.873 0.585 0.931 0.600 0.811 0.622 0.354 0.636 0.191 0.652 0.120 0.663 0.148 0.674 0.099 0.687 0.163 0.707 0.489 0.720 0.631 0.731 0.624 0.765 0.339 0.778 0.170 0.810 0.056 0.842 0.116 0.863 0.227 0.899 0.240 0.907 0.189 0.965 0.122 1.000 0.000) :duration dur :scaler amp)) (gen1 (make-polywave 0.0 '(1 .85 2 .02 3 .008 4 .01 5 .006))) (frqf (make-env '(0.000 0.267 0.029 0.354 0.131 0.349 0.188 0.414 0.202 0.534 0.232 0.453 0.250 0.427 0.267 0.455 0.279 0.505 0.296 0.540 0.312 0.549 0.332 0.532 0.365 0.442 0.380 0.427 0.395 0.443 0.417 0.512 0.430 0.544 0.446 0.558 0.465 0.542 0.503 0.436 0.521 0.421 0.535 0.440 0.558 0.510 0.570 0.534 0.588 0.544 0.608 0.525 0.625 0.479 0.646 0.425 0.669 0.410 0.690 0.432 0.715 0.514 0.733 0.532 0.753 0.514 0.801 0.423 0.817 0.421 0.830 0.304 0.866 0.343 0.891 0.354 0.913 0.338 0.950 0.312 1.000 0.304) :duration dur :scaler (hz->radians 2000.0)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) ;; (with-sound (:play #t) (common-loon-2 0 .25)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Hermit thrush (defanimal (hermit-thrush beg amp) (let ((start (seconds->samples beg)) (ampfs (make-vector 3 #f)) (frqf1s (make-vector 3 #f)) (frqf2s (make-vector 3 #f)) (starts (make-vector 3 0)) (stops (make-vector 3 0)) (begs (vector 0.0 0.42 0.84)) (durs (vector 0.34 0.35 0.56)) (amps (vector 0.6 0.8 1.0)) (gen1 (make-polywave 0.0 (list 1 (* .55 .95) 2 (* .55 .01) 3 (* .55 .03)))) (gen2 (make-polywave 0.0 (list 1 (* .45 .95) 2 (* .45 .01) 3 (* .45 .03)))) (amp-envs (vector '(0.000 0.000 0.117 0.054 0.301 0.269 0.518 0.605 0.608 0.620 0.703 0.783 0.779 0.900 0.804 0.857 0.863 0.987 0.912 0.959 0.943 1.000 0.967 0.900 1.000 0.000) '(0.000 0.000 0.028 0.109 0.037 0.059 0.056 0.223 0.066 0.000 0.094 0.252 0.104 0.488 0.136 0.605 0.151 0.770 0.154 0.000 0.162 0.857 0.175 0.727 0.187 0.000 0.198 0.505 0.217 0.280 0.229 0.427 0.240 0.291 0.249 0.479 0.266 0.369 0.277 0.518 0.289 0.380 0.297 0.503 0.310 0.380 0.321 0.495 0.334 0.000 0.343 0.584 0.376 0.545 0.398 0.649 0.412 0.605 0.423 0.642 0.445 0.607 0.456 0.651 0.493 0.638 0.516 0.586 0.532 0.000 0.541 0.386 0.570 0.579 0.577 0.210 0.603 0.885 0.627 0.704 0.645 0.000 0.647 0.482 0.659 0.584 0.673 0.148 0.683 0.573 0.698 0.432 0.708 0.649 0.722 0.529 0.735 0.701 0.754 0.586 0.764 0.709 0.777 0.575 0.791 0.716 0.802 0.568 0.819 0.681 0.837 0.601 0.872 0.783 0.933 0.967 0.978 0.902 1.000 0.000) '(0.000 0.000 0.006 0.202 0.014 0.082 0.023 0.349 0.057 0.605 0.064 0.581 0.071 0.367 0.105 0.184 0.107 0.000 0.152 0.421 0.171 0.538 0.183 0.443 0.210 0.000 0.230 0.150 0.250 0.707 0.264 0.716 0.276 0.579 0.280 0.499 0.306 0.712 0.328 0.711 0.340 0.852 0.356 0.850 0.367 0.957 0.391 0.904 0.412 0.616 0.420 0.000 0.446 0.516 0.452 0.482 0.456 0.391 0.457 0.256 0.487 0.000 0.511 0.247 0.554 0.213 0.572 0.106 0.606 0.000 0.645 0.340 0.668 0.167 0.706 0.000 0.725 0.273 0.736 0.267 0.753 0.000 0.779 0.364 0.799 0.347 0.823 0.256 0.847 0.132 0.853 0.000 0.877 0.160 0.887 0.078 0.924 0.000 0.948 0.095 1.000 0.000))) (frq1-envs (vector '(0.000 0.352 1.000 0.345) '(0.000 0.485 0.037 0.482 0.058 0.511 0.068 0.482 0.085 0.523 0.102 0.489 0.112 0.562 0.200 0.549 0.215 0.490 0.233 0.510 0.243 0.487 0.256 0.508 0.265 0.484 0.281 0.508 0.293 0.482 0.302 0.499 0.318 0.489 0.528 0.492 0.544 0.516 0.557 0.487 0.572 0.492 0.576 0.518 0.578 0.549 0.675 0.542 0.680 0.496 0.691 0.485 0.704 0.508 0.712 0.487 0.728 0.506 0.743 0.480 0.755 0.503 0.770 0.482 0.782 0.497 0.794 0.478 0.805 0.492 0.827 0.490 0.851 0.397 1.000 0.392) '(0.000 0.499 0.018 0.497 0.029 0.563 0.061 0.563 0.074 0.553 0.086 0.487 0.098 0.513 0.105 0.492 0.116 0.510 0.127 0.612 0.137 0.641 0.190 0.641 0.202 0.510 0.213 0.487 0.224 0.548 0.235 0.510 0.244 0.567 0.268 0.553 0.277 0.501 0.286 0.489 0.314 0.504 0.323 0.449 0.423 0.442 0.432 0.553 0.446 0.567 0.457 0.503 0.467 0.487 0.481 0.497 0.506 0.563 0.526 0.553 0.533 0.510 0.544 0.496 0.555 0.510 0.582 0.556 0.583 0.624 0.591 0.645 0.649 0.643 0.662 0.515 0.674 0.489 0.708 0.551 0.722 0.553 0.740 0.490 0.761 0.487 0.793 0.506 0.820 0.556 0.859 0.560 0.889 0.490 0.926 0.494 0.928 0.556 0.946 0.555 0.972 0.489 1.000 0.487))) (frq2-envs (vector '(0.000 0.352 1.000 0.345) '(0.000 0.000 0.001 0.352 0.025 0.440 0.034 0.388 0.051 0.438 0.064 0.380 0.088 0.425 0.098 0.383 0.120 0.350 0.146 0.357 0.193 0.336 0.207 0.409 0.219 0.381 0.231 0.418 0.243 0.388 0.259 0.421 0.268 0.388 0.279 0.426 0.293 0.388 0.307 0.426 0.316 0.397 0.336 0.428 0.345 0.402 0.364 0.430 0.371 0.397 0.372 0.492 0.534 0.494 0.549 0.402 0.565 0.386 0.585 0.347 0.614 0.355 0.663 0.336 0.672 0.354 0.678 0.395 0.697 0.388 0.707 0.406 0.735 0.407 0.758 0.406 0.804 0.397 0.830 0.400 0.846 0.397 1.000 0.395) '(0.000 0.409 0.018 0.392 0.034 0.364 0.069 0.343 0.080 0.400 0.092 0.357 0.100 0.399 0.114 0.354 0.136 0.347 0.157 0.315 0.195 0.399 0.206 0.376 0.218 0.399 0.231 0.348 0.257 0.345 0.270 0.393 0.286 0.400 0.293 0.440 0.312 0.447 0.410 0.445 0.424 0.350 0.434 0.340 0.449 0.393 0.462 0.393 0.476 0.406 0.489 0.366 0.504 0.348 0.516 0.360 0.530 0.404 0.538 0.380 0.551 0.397 0.569 0.348 0.589 0.350 0.615 0.324 0.643 0.357 0.653 0.400 0.678 0.400 0.685 0.376 0.694 0.352 0.716 0.350 0.730 0.404 0.748 0.411 0.757 0.447 0.830 0.447 0.851 0.350 0.873 0.400 0.901 0.406 0.917 0.360 0.946 0.357 1.000 0.447)))) (do ((i 0 (+ i 1))) ((= i 3)) (set! (ampfs i) (make-env (amp-envs i) :duration (durs i) :scaler (* amp (amps i)))) (set! (frqf1s i) (make-env (frq1-envs i) :duration (durs i) :scaler (hz->radians 10000))) (set! (frqf2s i) (make-env (frq2-envs i) :duration (durs i) :scaler (hz->radians 10000))) (set! (starts i) (+ start (seconds->samples (begs i)))) (set! (stops i) (+ (starts i) (seconds->samples (durs i))))) (do ((tone 0 (+ 1 tone))) ((= tone 3)) (let ((ampf (ampfs tone)) (frqf1 (frqf1s tone)) (frqf2 (frqf2s tone)) (start (starts tone)) (end (stops tone))) (do ((i start (+ i 1))) ((= i end)) (outa i (* (env ampf) (+ (polywave gen1 (env frqf1)) (polywave gen2 (env frqf2)))))))))) ;; (with-sound (:play #t) (hermit-thrush 0 .25)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Chuck-will's-widow (defanimal (chuck-wills-widow beg amp) (let ((dur 1.05)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.017 0.656 0.026 0.136 0.048 0.000 0.289 0.000 0.328 0.154 0.353 0.405 0.361 0.961 0.369 0.667 0.381 0.918 0.394 0.269 0.402 0.204 0.425 0.333 0.440 0.570 0.466 0.444 0.515 0.470 0.592 0.294 0.65 0.000 .68 0.0 .7 .1 .74 0 0.762 0.000 0.791 0.305 0.818 0.337 0.832 1.000 0.844 0.699 0.857 0.903 0.867 0.405 0.883 0.398 0.895 0.853 0.907 0.853 0.921 0.297 0.953 0.294 0.981 0.140 1.000 0.000) :duration dur :scaler amp)) (gen1 (make-polywave 0.0 '(1 .97 3 .02 4 .01))) (rnd (make-rand-interp 100 .25)) (frqf (make-env '(0.000 0.702 0.014 0.637 0.023 0.478 0.048 0.343 0.298 0.385 0.335 0.389 0.353 0.459 0.362 0.546 0.371 0.687 0.376 0.715 0.383 0.687 0.388 0.635 0.391 0.565 0.398 0.474 0.417 0.370 0.455 0.561 0.490 0.389 0.504 0.465 0.523 0.483 0.541 0.461 0.552 0.413 0.605 0.409 0.610 0.370 0.781 0.380 0.804 0.417 0.823 0.457 0.837 0.517 0.851 0.693 0.858 0.737 0.867 0.702 0.871 0.572 0.878 0.496 0.889 0.430 0.904 0.535 0.914 0.630 0.924 0.554 0.933 0.457 0.951 0.380 1.000 0.354) :duration dur :scaler (hz->radians 3000.0)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (+ .75 (abs (rand-interp rnd))) (polywave gen1 (env frqf)))))))) ;; (with-sound (:play #t) (chuck-wills-widow 0 .25)) ;;; -------------------------------------------------------------------------------- ;;; ;;; California towhee (defanimal (california-towhee beg amp) (let ((dur 1.17) ;; peep pitch changes (amps (vector .5 .8 .85 .9 .95 1.0)) (begs (vector 0.0 0.39 0.67 0.86 0.96 1.09)) (frqs (vector 4750 4950 4880 4920 5210 5140)) (starts (make-vector 7 0)) (peep-dur 0.055) (start (seconds->samples beg))) (let ((stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.141 0.119 0.220 0.652 0.329 0.968 0.495 0.830 0.603 0.399 0.715 0.178 1.000 0.000) :duration peep-dur :scaler amp)) (gen1 #f) (frqf (make-env '(0 .5 .1 3 .2 1 .4 0 1 .2) :duration peep-dur :scaler (hz->radians 800))) (peep-samps (seconds->samples peep-dur)) (peep-amp 1.0) (peep-ctr 0)) (do ((i 0 (+ i 1))) ((= i 6)) (set! (starts i) (+ start (seconds->samples (begs i))))) (set! (starts 6) (+ 1 stop)) (do ((i start start)) ((>= i stop)) (set! peep-amp (amps peep-ctr)) (set! gen1 (make-polywave (frqs peep-ctr) :partials (list 1 (* peep-amp .97) 2 (* peep-amp .02) 3 (* peep-amp .01)))) (set! peep-ctr (+ peep-ctr 1)) (let ((reset-stop (min stop (+ i peep-samps)))) (do ((k i (+ k 1))) ((= k reset-stop)) (outa k (* (env ampf) (polywave gen1 (env frqf))))) (set! start (starts peep-ctr)) (mus-reset ampf) (mus-reset frqf)))))) ;; (with-sound (:play #t) (california-towhee 0 .25)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Black-chinned sparrow (defanimal (black-chinned-sparrow beg amp gliss-up) (let ((initial-dur .36) (initial-pitch 6800) (initial-amp .05) (buzz-dur 2.62) (buzz-frq0 (/ 1.0 (* 2 .34))) (buzz-frq1 (/ 1.0 .02)) (buzz-frqmid (/ 1.0 .15)) (buzz-size 128) (buzz-low 3000) (buzz-high 8500) (buzz-mid 4000) (start (seconds->samples beg))) (let (;; initial stable pitch, then the gliss->buzz with frq going either up or down (initial-stop (+ start (seconds->samples initial-dur))) (initial-ampf (make-env '(0 0 1 1 10 1 11 0) :duration initial-dur :scaler (* amp initial-amp))) (initial-gen (make-oscil initial-pitch)) (buzz-frq-table (let ((v (make-float-vector buzz-size 0.0)) (bfrqf (make-env (if gliss-up (list 0 buzz-low .5 buzz-mid 1 buzz-high) (list 0 buzz-high .5 buzz-mid 1 buzz-low)) :length buzz-size :scaler (hz->radians 1.0)))) (do ((i 0 (+ i 1))) ((= i buzz-size)) (set! (v i) (env bfrqf))) v)) (buzz-amp-table (let ((v (make-float-vector buzz-size 0.0)) (bampf (make-env (if gliss-up '(0 0 1 1 2.5 .7 3 0 3.5 0) '(0 0 .5 1 2 1 3 0 3.5 0)) :length buzz-size))) (do ((i 0 (+ i 1))) ((= i buzz-size)) (set! (v i) (env bampf))) v))) (let ((buzz-stop (+ initial-stop (seconds->samples buzz-dur))) (buzz-amp (make-env '(0.000 0.000 0.035 0.190 0.082 0.336 0.168 0.625 0.348 0.743 0.467 0.763 0.530 0.723 0.628 0.818 0.668 1.000 0.728 0.913 0.777 0.506 0.818 0.174 1.000 0.000) :duration buzz-dur :scaler amp)) (buzz-frq (make-env (list 0 buzz-frq0 .5 buzz-frqmid 1 buzz-frq1) :duration buzz-dur :scaler (hz->radians 1.0))) (buzz-frqf (make-table-lookup buzz-frq0 :wave buzz-frq-table)) (buzz-ampf (make-table-lookup buzz-frq0 :wave buzz-amp-table)) (buzz-gen (make-polywave 0.0 '(1 .98 2 .005 3 .01)))) (do ((i start (+ i 1))) ((= i initial-stop)) (outa i (* (env initial-ampf) (oscil initial-gen)) )) (do ((i initial-stop (+ i 1))) ((= i buzz-stop)) (let ((frq (env buzz-frq))) (outa i (* (env buzz-amp) (table-lookup buzz-ampf frq) (polywave buzz-gen (table-lookup buzz-frqf frq)))))))))) ;; (with-sound (:play #t) (black-chinned-sparrow 0 .25 #t)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Mourning dove (defanimal (mourning-dove beg amp) (let ((dur 4.1)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (rnd (make-rand-interp 2000 (hz->radians 200.0))) (rndf (make-env '(0 1 2 .3 5 .3) :duration dur :scaler .1)) (gen2 (make-oscil 620)) (gen1 (make-polywave 0.0 (list 1 (* .95 .95) 2 (* .95 .05) 3 (* .95 .005)))) (ampf (make-env '(0.000 0.000 0.012 0.256 0.032 0.247 0.048 0.188 0.197 0.156 0.224 0.988 0.238 0.844 0.256 0.881 0.309 0.000 0.390 0.000 0.414 0.881 0.441 0.819 0.494 0.394 0.564 0.175 0.579 0.000 0.647 0.000 0.678 0.725 0.703 0.659 0.786 0.000 0.856 0.000 0.879 0.631 0.892 0.675 0.920 0.494 0.986 0.162 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.395 0.019 0.449 0.065 0.439 0.159 0.439 0.198 0.427 0.217 0.493 0.229 0.621 0.236 0.658 0.270 0.642 0.298 0.555 0.309 0.495 0.414 0.487 0.432 0.499 0.477 0.497 0.537 0.484 0.577 0.468 0.588 0.427 0.674 0.480 0.698 0.493 0.729 0.487 0.771 0.472 0.877 0.468 0.903 0.493 0.960 0.478 1.000 0.462) :duration dur :scaler (hz->radians 1000.0)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (+ (polywave gen1 (env frqf)) (* (env rndf) (oscil gen2 (rand-interp rnd)))))))))) ;; (with-sound (:play #t) (mourning-dove 0 .25)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Bobwhite (defanimal (bobwhite beg amp) (let ((call1-dur .32) (call1-amp .07) (call2-beg .80) (call2-dur .20) (call2-amp .35) (call3-beg 1.43) (call3-dur .22) (call3-amp 1.0) (call1-start (seconds->samples beg))) (let ((call1-gen (make-oscil 1450)) (call1-ampf (make-env '(0 0 1 1 8 1 9 0) :duration call1-dur :scaler (* amp call1-amp))) (call1-frqf (make-env '(0 1 1 0) :duration call1-dur :scaler (hz->radians 80))) (call1-stop (+ call1-start (seconds->samples call1-dur))) (call2-gen (make-polywave 1320 '(1 .95 2 .04 3 .01 4 .02 5 .01))) (call2-ampf (make-env '(0 0 1 1 4 1 5 0) :duration call2-dur :scaler (* amp call2-amp))) (call2-frqf (make-env '(0 0 1 1 4 1 5 .5) :duration call2-dur :scaler (hz->radians 430))) (call2-start (+ call1-start (seconds->samples call2-beg)))) (let ((call2-stop (+ call2-start (seconds->samples call2-dur))) (call3-gen (make-polywave 0.0 '(1 .95 2 .04 4 .01))) (call4-gen (make-polywave 0.0 '(1 .05 2 .6 3 .2 4 .1 5 .01 6 .005))) (call3-ampf (make-env '(0 0 .5 1 .75 .2 1 0) :duration call3-dur :scaler (* amp call3-amp))) (call3-frqf (make-env '(0.000 0.245 0.135 0.304 0.399 0.335 0.439 0.345 0.491 0.384 0.551 0.434 0.591 0.485 0.65 0.65 .67 .5 1 .3) :duration call3-dur :scaler (hz->radians 6000.0))) (call3-f1 (make-env '(0 1 .6 1 .75 0 1 0) :duration call3-dur)) (call3-f2 (make-env '(0 0 .6 0 .64 1 1 1) :duration call3-dur)) (call3-start (+ call1-start (seconds->samples call3-beg)))) (let ((call3-stop (+ call3-start (seconds->samples call3-dur)))) (do ((i call1-start (+ i 1))) ((= i call1-stop)) (outa i (* (env call1-ampf) (oscil call1-gen (env call1-frqf))))) (do ((i call2-start (+ i 1))) ((= i call2-stop)) (outa i (* (env call2-ampf) (polywave call2-gen (env call2-frqf))))) (do ((i call3-start (+ i 1))) ((= i call3-stop)) (let ((frq (env call3-frqf))) (outa i (* (env call3-ampf) (+ (* (env call3-f1) (polywave call3-gen frq)) (* (env call3-f2) (polywave call4-gen (* 0.5 frq))))))))))))) ;; (with-sound (:play #t) (bobwhite 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Warbling vireo (defanimal (warbling-vireo beg amp) (let ((dur 2.25)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.018 0.042 0.046 0.000 0.074 0.113 0.091 0.111 0.096 0.000 0.113 0.000 0.129 0.124 0.144 0.089 0.148 0.026 0.164 0.000 0.187 0.108 0.209 0.000 0.220 0.000 0.222 0.103 0.235 0.218 0.245 0.205 0.258 0.000 0.268 0.000 0.279 0.087 0.305 0.089 0.316 0.000 0.338 0.000 0.345 0.216 0.379 0.726 0.402 0.000 0.411 0.000 0.414 0.324 0.437 0.155 0.455 0.139 0.461 0.000 0.473 0.000 0.482 0.126 0.492 0.126 0.497 0.321 0.509 0.139 0.520 0.003 0.536 0.308 0.552 0.187 0.565 0.250 0.572 0.000 0.587 0.000 0.596 0.737 0.619 0.966 0.646 0.501 0.661 0.000 0.670 0.000 0.679 0.266 0.697 0.097 0.703 0.711 0.719 0.000 0.736 0.000 0.746 0.997 0.756 0.282 0.775 0.392 0.787 0.000 0.804 0.000 0.813 0.811 0.826 0.463 0.836 0.411 0.847 0.000 0.862 0.000 0.873 0.284 0.893 0.192 0.899 0.066 0.912 0.329 0.921 0.000 0.931 0.000 0.934 0.303 0.947 0.466 0.960 0.418 0.980 0.258 1.000 0.000) :duration dur :scaler amp)) (gen1 (make-oscil)) (frqf (make-env '(0.000 0.184 0.010 0.214 0.026 0.214 0.036 0.197 0.057 0.197 0.066 0.233 0.085 0.266 0.099 0.260 0.113 0.255 0.124 0.274 0.125 0.222 0.134 0.249 0.146 0.227 0.165 0.227 0.169 0.178 0.179 0.184 0.191 0.192 0.209 0.175 0.221 0.186 0.226 0.312 0.227 0.258 0.233 0.285 0.234 0.236 0.242 0.274 0.245 0.241 0.252 0.230 0.268 0.227 0.272 0.203 0.284 0.225 0.295 0.216 0.306 0.208 0.316 0.219 0.346 0.233 0.357 0.282 0.359 0.252 0.366 0.296 0.369 0.252 0.373 0.304 0.376 0.255 0.382 0.301 0.385 0.263 0.390 0.301 0.412 0.279 0.418 0.321 0.421 0.247 0.424 0.279 0.427 0.233 0.441 0.211 0.450 0.208 0.457 0.178 0.480 0.197 0.484 0.238 0.488 0.205 0.492 0.241 0.495 0.200 0.499 0.247 0.506 0.241 0.512 0.186 0.529 0.192 0.530 0.255 0.548 0.238 0.557 0.214 0.568 0.241 0.582 0.230 0.591 0.299 0.599 0.307 0.609 0.301 0.615 0.274 0.627 0.342 0.645 0.359 0.648 0.329 0.670 0.332 0.672 0.247 0.700 0.227 0.705 0.304 0.715 0.249 0.722 0.244 0.738 0.247 0.749 0.307 0.753 0.425 0.762 0.422 0.770 0.468 0.774 0.392 0.786 0.342 0.808 0.326 0.821 0.255 0.832 0.285 0.843 0.266 0.866 0.263 0.891 0.197 0.915 0.247 0.935 0.285 0.942 0.345 0.945 0.290 0.947 0.441 0.950 0.353 0.953 0.411 0.957 0.367 0.960 0.405 0.964 0.370 0.967 0.405 0.973 0.373 0.979 0.373 0.990 0.296 1.000 0.255) :duration dur :scaler (hz->radians 11900)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (oscil gen1 (env frqf)))))))) ;; (with-sound (:play #t) (warbling-vireo 0 .25)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Great-horned owl (defanimal (great-horned-owl beg amp) (let ((begs (vector 0.0 0.26 1.42 2.16)) (durs (vector 0.14 0.40 0.43 0.37)) (amps (vector .75 .9 .95 1.0))) (do ((call 0 (+ call 1))) ((= call 4)) (let ((start (seconds->samples (+ beg (begs call))))) (let ((stop (+ start (seconds->samples (durs call)))) (gen (make-polywave 0.0 '(1 .9 2 .12 3 .007 7 .003))) (rnd (make-rand-interp 30 (hz->radians 5))) (ampf (make-env '(0 0 1 1 4 .9 5 0) :duration (durs call) :scaler (* amp (amps call)))) (frqf (make-env '(0 1.25 .5 2 4.4 1.95 5 1) :base .1 :duration (durs call) :scaler (hz->radians (* 0.5 328))))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen (+ (env frqf) (rand-interp rnd))))))))))) ;; (with-sound (:play #t) (great-horned-owl 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Western tanager (defanimal (western-tanager beg amp) (let ((gen (make-polywave 0.0 '(1 .98 2 .02))) (begs (vector 0.0 0.7 1.4 2.0)) (durs (vector 0.27 0.32 0.25 0.24)) (amps (vector 0.32 0.85 1.0 0.65))) (let ((ampfs (vector (make-env '(0.000 0.000 0.086 0.398 0.247 0.610 0.363 0.000 0.416 0.000 0.513 0.603 0.610 0.603 0.708 0.507 0.733 0.232 0.798 0.895 0.848 1.000 0.898 0.927 1.000 0.000) :duration (durs 0) :scaler (* amp (amps 0))) (make-env '(0.000 0.000 0.060 0.735 0.303 1.000 0.394 0.408 0.503 0.318 0.617 0.879 0.912 0.258 0.939 0.055 1.000 0.000) :duration (durs 1) :scaler (* amp (amps 1))) (make-env '(0.000 0.000 0.098 0.837 0.183 0.704 0.395 1.000 0.469 0.185 0.553 0.086 0.731 0.841 0.785 0.834 1.000 0.000) :duration (durs 2) :scaler (* amp (amps 2))) (make-env '(0.000 0.000 0.047 0.837 0.117 0.172 0.167 0.157 0.234 0.993 0.296 0.826 0.319 0.609 0.431 0.781 0.567 0.506 0.642 0.166 0.673 0.757 0.769 0.874 0.873 0.766 0.919 0.605 0.956 0.230 1.000 0.000) :duration (durs 3) :scaler (* amp (amps 3))))) (frqfs (vector (make-env '(0.000 0.437 0.056 0.561 0.075 0.558 0.094 0.459 0.109 0.536 0.128 0.411 0.142 0.521 0.156 0.435 0.172 0.532 0.190 0.450 0.214 0.556 0.226 0.459 0.239 0.556 0.350 0.318 0.409 0.313 0.491 0.461 0.614 0.461 0.665 0.428 0.702 0.340 0.718 0.406 0.739 0.331 0.756 0.470 0.772 0.336 0.803 0.510 0.818 0.353 0.845 0.536 0.862 0.415 0.886 0.545 0.903 0.470 0.924 0.534 0.945 0.442 1.000 0.395) :duration (durs 0) :scaler (hz->radians 6000)) (make-env '(0.000 0.587 0.045 0.543 0.064 0.459 0.088 0.563 0.105 0.481 0.127 0.600 0.141 0.514 0.172 0.620 0.185 0.532 0.212 0.640 0.233 0.567 0.251 0.629 0.266 0.589 0.374 0.448 0.440 0.404 0.528 0.406 0.557 0.450 0.583 0.466 0.604 0.517 0.618 0.481 0.648 0.552 0.667 0.499 0.691 0.556 0.710 0.517 0.739 0.561 0.758 0.519 0.791 0.561 0.814 0.510 0.833 0.534 0.975 0.483 1.000 0.488) :duration (durs 1) :scaler (hz->radians 6000)) (make-env '(0.000 0.247 0.059 0.539 0.073 0.556 0.131 0.490 0.150 0.444 0.172 0.501 0.199 0.402 0.222 0.512 0.249 0.430 0.279 0.552 0.304 0.464 0.340 0.600 0.360 0.479 0.383 0.567 0.496 0.311 0.611 0.320 0.635 0.470 0.655 0.331 0.680 0.492 0.703 0.349 0.742 0.534 0.770 0.373 0.797 0.536 0.823 0.419 0.856 0.536 0.881 0.433 0.910 0.506 0.950 0.397 0.978 0.508 1.000 0.514) :duration (durs 2) :scaler (hz->radians 6000)) (make-env '(0.000 0.614 0.031 0.607 0.046 0.514 0.072 0.430 0.145 0.307 0.168 0.380 0.191 0.536 0.205 0.453 0.223 0.570 0.239 0.457 0.261 0.547 0.282 0.426 0.297 0.503 0.318 0.426 0.341 0.453 0.449 0.468 0.580 0.435 0.635 0.419 0.652 0.353 0.674 0.494 0.687 0.545 0.706 0.455 0.732 0.556 0.754 0.457 0.783 0.547 0.807 0.455 0.840 0.558 0.858 0.453 0.885 0.539 0.914 0.439 0.938 0.541 0.965 0.433 1.000 0.472) :duration (durs 3) :scaler (hz->radians 6000))))) (do ((call 0 (+ call 1))) ((= call 4)) (let ((ampf (ampfs call)) (frqf (frqfs call)) (start (seconds->samples (+ beg (begs call))))) (let ((stop (+ start (seconds->samples (durs call))))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen (env frqf))))))))))) ;; (with-sound (:play #t) (western-tanager 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Pileated woodpecker (defanimal (pileated-woodpecker beg amp) (let ((dur 2.28) (pulse-space .137) (pulse-dur .06) (start (seconds->samples beg))) (let ((gen #f) (partials '(1 .06 2 1.0 3 .1 4 .13 5 .07 6 .01 7 .015 8 .01 9 .017 10 .006)) ; .705 is scaling (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0 .5 4 1 15 1) :duration dur :scaler (* .705 amp))) (pulse-ampf (make-env '(0.000 0.000 0.20 0.625 0.511 0.985 0.663 1.000 0.802 0.940 0.906 0.731 0.961 0.157 1.000 0.000) :duration pulse-dur)) (pulse-frqf (make-env '(0 0 .3 .9 .6 1 .8 1 1 .75) :duration pulse-dur :scaler (hz->radians 300))) (pulse-off (make-env '(0 1120 .25 1140 .4 1190 .9 1150) :length 18)) (pulse-samps (seconds->samples pulse-space)) (pulse-out (seconds->samples pulse-dur))) (do ((i start (+ i pulse-samps))) ((>= i stop)) (set! (mus-location ampf) (- i start)) (let ((reset-stop (min stop (+ i pulse-out))) (pulse-amp (env ampf))) (set! gen (make-polywave :partials (let ((xcoord #f)) (map (lambda (x) (set! xcoord (not xcoord)) (if xcoord x (* x pulse-amp))) partials)))) (set! (mus-frequency gen) (- (env pulse-off) 300.0)) (do ((k i (+ k 1))) ((= k reset-stop)) (outa k (* (env pulse-ampf) (polywave gen (env pulse-frqf))))) (mus-reset pulse-ampf) (mus-reset pulse-frqf)))))) ;; (with-sound (:play #t) (pileated-woodpecker 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Whip-poor-will (defanimal (whip-poor-will beg amp) (let ((dur 0.75)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.043 0.172 0.063 0.341 0.093 0.256 0.188 0.159 0.209 0.000 0.466 0.000 0.527 0.097 0.558 0.081 0.626 0.309 0.650 0.288 0.657 0.140 0.674 0.142 0.708 0.322 0.750 0.343 0.765 0.121 0.787 0.201 0.805 0.381 0.826 0.470 0.861 0.144 0.867 0.451 0.877 0.106 0.890 0.964 0.914 0.117 0.919 0.377 0.926 0.233 0.931 0.324 0.949 0.244 0.977 0.377 1.000 0.000) :duration dur :scaler amp)) (gen1 (make-polywave 0.0 '(1 .98 2 .01 3 .01))) (frqf (make-env '(0 1170 .093 1680 .2 1640 .46 1170 .558 1170 .626 1450 .650 1530 .66 1290 .707 1480 .750 1480 .765 1290 .78 1320 .8 1600 .81 1300 .82 1900 .83 1500 .84 2100 .85 1700 .86 2150 .87 1900 .89 2460 .914 2160 .93 1680 1.0 1600) :duration dur :scaler (hz->radians 1.0)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) ;; (with-sound (:play #t) (whip-poor-will 0 .25)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Varied thrush (defanimal (varied-thrush beg amp) (let ((dur 1.02)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.052 0.100 0.130 0.538 0.261 0.845 0.438 0.983 0.580 0.917 0.738 0.720 0.860 0.475 0.941 0.172 1.000 0.000) :duration dur :scaler (/ amp 2.25))) (gen1 (make-rxyk!cos 3360 (/ -200 3360) 0.7)) (gen2 (make-rxyk!cos 3760 (/ 200 3760) 0.3)) (gen3 (make-polywave 3660 (list 1 (* .25 .98) 2 (* .25 .02)))) (frqf (make-env '(0 1 .1 0 .95 0 1.0 -.1) :duration dur :scaler (hz->radians 10.0))) (rnd (make-rand-interp 100 (hz->radians 3)))) (do ((i start (+ i 1))) ((= i stop)) (let ((fm (+ (env frqf) (rand-interp rnd)))) (outa i (* (env ampf) (+ (rxyk!cos gen1 (* 16.8 fm)) (rxyk!cos gen2 (* 18.8 fm)) (polywave gen3 fm))))))))) ;; (with-sound (:play #t) (varied-thrush 0 .25)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Nashville warbler (defanimal (nashville-warbler beg amp) (define (nashville-warbler-1 beg dur amp) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.111 0.837 0.169 0.995 0.328 1.000 0.430 0.905 0.561 0.333 0.595 0.000 0.61 0.0 0.62 0.154 0.715 0.675 0.806 0.959 0.969 0.908 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0 7200 .1 5500 .3 4800 .56 4400 .59 4500 .62 7200 .72 7200 .8 6800 .83 6700 .85 6700 .87 6600 .9 6600 .92 6500 .96 6500 1 6520) :duration dur :scaler (hz->radians 1.0))) (gen1 (make-polywave 0.0 '(1 .95 2 .005 3 .03)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf))))))) (define (nashville-warbler-2 beg dur amp) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.049 0.165 0.082 0.591 0.123 0.561 0.139 0.434 0.219 0.981 0.325 0.984 0.374 0.100 0.438 0.100 0.484 0.415 0.552 0.818 0.618 0.995 0.753 0.748 0.888 0.439 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0 3450 .1 5000 .14 4800 .37 5600 .44 8600 .55 6600 .61 5300 1 3200) :duration dur :scaler (hz->radians 1.0))) (gen1 (make-polywave 0.0 '(1 .95 2 .005 3 .03)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf))))))) (define (nashville-warbler-3 beg amp) (let ((dur .1)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0 0 1 1 3 1 4 0) :duration dur :scaler amp)) (frqf (make-env '(0 7580 .6 5100 1 5000) :duration dur :scaler (hz->radians 1.0))) (gen1 (make-polywave 0.0 '(1 .95 2 .005 3 .03)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) (define (nashville-warbler-4 beg amp) (let ((dur 0.07)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.129 0.201 0.182 0.382 0.197 1.000 0.243 0.350 0.342 0.520 0.393 0.759 0.485 0.878 0.647 0.694 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0 3300 .195 4800 .24 5500 .26 5500 .4 4500 .7 3460 1 3000) :duration dur :scaler (hz->radians 1.0))) (gen1 (make-polywave 0.0 '(1 .96 2 .03 3 .005 4 .004)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) (let ((amps1 (vector .2 .5 .7 .9 1.0 1.0))) (do ((call 0 (+ call 1))) ((= call 6)) (nashville-warbler-1 (+ beg (* .21 call)) (+ .15 (random .02)) (* amp (amps1 call)))) (do ((call 0 (+ call 1))) ((= call 3)) (nashville-warbler-2 (+ beg 1.26 (* .17 call)) (+ .13 (random .02)) amp)) (nashville-warbler-3 (+ beg 1.8) amp) (nashville-warbler-4 (+ beg 1.94) (* 0.4 amp)))) ;; (with-sound (:play #t) (nashville-warbler 0 .25)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Ruffed grouse (defanimal (ruffed-grouse beg amp) (let ((dur 10.33) (bump-dur 0.27)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.006 0.097 0.045 0.135 0.091 0.244 0.141 0.223 0.219 0.552 0.301 0.682 0.360 0.689 0.503 0.766 0.696 0.619 0.751 0.622 0.806 0.705 0.820 0.552 0.829 0.787 0.849 0.687 0.867 1.1000 0.910 0.494 0.929 0.559 0.944 0.527 0.969 0.339 1.000 0.000) :duration dur :scaler (* 3 amp))) (frqf (make-env (list 0 (/ 1.0 .45) .18 (/ 1.0 .45) .19 (/ 1.0 .8) .22 (/ 1.0 .8) .25 (/ 1.0 .6) .5 (/ 1.0 .4) .74 (/ 1.0 .15) .9 (/ 1.0 .08) 1 (/ 1.0 .4)) :duration dur :scaler (hz->radians 1.0))) (bump-samps (seconds->samples bump-dur)) (bump (make-env '(0.000 0.499 0.040 0.499 0.063 0.506 0.089 0.492 0.108 0.499 0.122 0.523 0.134 0.506 0.143 0.462 0.153 0.425 0.164 0.457 0.171 0.508 0.173 0.580 0.176 0.647 0.181 0.691 0.186 0.650 0.195 0.404 0.197 0.355 0.202 0.311 0.208 0.362 0.222 0.657 0.229 0.696 0.235 0.661 0.258 0.350 0.263 0.311 0.271 0.297 0.283 0.343 0.311 0.661 0.316 0.703 0.322 0.733 0.333 0.698 0.340 0.643 0.375 0.343 0.379 0.304 0.389 0.278 0.404 0.353 0.443 0.624 0.458 0.661 0.473 0.631 0.494 0.508 0.517 0.434 0.537 0.394 0.557 0.436 0.589 0.520 0.618 0.564 0.644 0.538 0.679 0.490 0.703 0.473 0.736 0.483 0.794 0.510 0.831 0.510 0.909 0.494 1.000 0.499) :duration bump-dur :offset -0.5))) (let ((bump-wave (make-float-vector bump-samps 0.0))) (do ((i 0 (+ i 1))) ((= i bump-samps)) (set! (bump-wave i) (env bump))) (let ((wt (make-wave-train 0.0 0.0 bump-wave))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (wave-train wt (env frqf)))))))))) #| ;; old form: (do ((i start (+ i 1))) ((= i stop)) (if (> (pulse-train pulser (env frqf)) .1) (let ((bump-stop (+ i bump-samps))) (set! (mus-location ampf) (- i start)) (let ((vol (env ampf))) (mus-reset bump) (do ((k i (+ k 1))) ((= k bump-stop)) (outa k (* vol (env bump))))))))))) |# ;; (with-sound (:play #t) (ruffed-grouse 0 0.5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Plumbeous vireo (defanimal (plumbeous-vireo-1 beg amp) (let ((dur 0.34)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 .02 .1 0.124 0.146 0.142 0.370 0.251 1.000 0.277 0.373 .29 .1 0.393 0.326 0.419 0.731 0.568 0.407 0.713 0.286 0.885 0.351 0.947 0.311 0.967 0.123 1.000 0.000) :duration dur :scaler amp)) (gen1 (make-polywave 0.0 '(1 .98 3 .01 5 .004))) (ampf1a (make-env '(0 .2 .15 .25 .2 .01 .24 .02 .25 .1 .32 .1 .34 .005 .37 .001 .4 .05 .6 .03 1 0) :duration dur)) (gen1a (make-oscil)) (frqf (make-env '(0.000 0.181 0.054 0.175 0.072 0.187 0.087 0.156 0.097 0.177 0.118 0.154 0.151 0.259 0.201 0.320 0.243 0.293 0.256 0.261 0.275 0.202 0.295 0.162 0.316 0.204 0.328 0.314 0.339 0.446 0.359 0.489 0.382 0.454 0.394 0.352 0.425 0.286 0.449 0.277 0.467 0.246 0.494 0.238 0.507 0.211 0.525 0.234 0.551 0.166 0.570 0.215 0.586 0.207 0.595 0.161 0.617 0.211 0.633 0.203 0.642 0.159 0.657 0.207 0.692 0.168 0.711 0.231 0.728 0.227 0.742 0.188 0.750 0.257 0.795 0.218 0.802 0.283 0.845 0.234 0.856 0.296 0.897 0.229 0.909 0.292 0.958 0.227 0.969 0.261 1.000 0.252) :duration dur :scaler (hz->radians 10000.0))) (gen2 (make-polywave 0.0 '(1 .05 2 .1 3 .2 4 .3 5 .2 6 .1 7 .05))) (ampf2 (make-env '(0 1 .15 0 1 0) :duration dur :scaler (* .5 amp))) (frqf2 (make-env '(0 850 1 700) :duration dur :scaler (hz->radians 1.0))) (rnd (make-rand-interp 1000 (hz->radians 50))) (buzz (make-rand-interp 1000 (hz->radians 40)))) (do ((i start (+ i 1))) ((= i stop)) (let ((frq (+ (env frqf) (rand-interp rnd)))) (outa i (* (env ampf) (+ (polywave gen1 frq) (* (env ampf1a) (oscil gen1a (* 2.0 frq))) (* (env ampf2) (polywave gen2 (+ (env frqf2) (rand-interp buzz)))))))))))) ;; (with-sound (:play #t) (plumbeous-vireo-1 0 .25)) (defanimal (plumbeous-vireo-2 beg amp) (let ((dur 0.455)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.106 0.184 0.148 0.082 0.169 0.156 0.183 0.441 0.199 0.484 0.216 0.379 0.234 0.770 0.244 0.748 0.252 0.527 0.261 0.992 0.320 0.961 0.343 0.742 0.360 0.832 0.395 0.916 0.411 0.145 0.416 0.559 0.421 0.126 0.424 0.577 0.435 0.791 0.448 0.529 0.452 0.089 0.460 0.639 0.472 0.777 0.485 0.181 0.495 0.656 0.499 0.319 0.506 0.854 0.515 0.668 0.516 0.186 0.523 0.559 0.535 0.933 0.540 0.599 0.545 0.923 0.554 0.282 0.562 0.795 0.569 0.609 0.574 0.988 0.579 0.908 0.588 0.772 0.593 0.161 0.597 0.646 0.604 0.879 0.612 0.931 0.625 0.800 0.630 0.267 0.634 0.782 0.644 0.926 0.649 0.812 0.652 0.423 0.658 0.955 0.664 0.718 0.670 0.973 0.675 0.235 0.682 0.752 0.691 1.000 0.698 0.938 0.706 0.153 0.712 0.889 0.720 0.693 0.735 0.906 0.745 0.661 0.750 0.228 0.754 0.594 0.757 0.683 0.763 0.411 0.767 0.621 0.779 0.797 0.793 0.693 0.797 0.532 0.802 0.564 0.810 0.386 0.814 0.653 0.839 0.535 0.840 0.092 0.843 0.495 0.851 0.572 0.862 0.627 0.870 0.490 0.873 0.592 0.882 0.416 0.888 0.054 0.889 0.359 0.896 0.465 0.901 0.379 0.908 0.543 0.919 0.413 0.926 0.443 0.931 0.218 0.949 0.516 0.959 0.423 0.979 0.151 1.000 0.000 ) :duration dur :scaler amp)) (frqf (make-env '(0.030 0.200 0.053 0.223 0.086 0.262 0.135 0.262 0.179 0.225 0.200 0.215 0.210 0.257 0.222 0.374 0.235 0.441 0.266 0.396 0.293 0.376 0.332 0.401 0.345 0.418 0.353 0.450 0.365 0.413 0.382 0.465 0.397 0.428 0.413 0.505 0.427 0.433 0.446 0.537 0.461 0.438 0.480 0.550 0.494 0.446 0.508 0.525 0.533 0.386 0.546 0.473 0.565 0.371 0.581 0.455 0.607 0.344 0.618 0.426 0.646 0.324 0.658 0.391 0.687 0.300 0.704 0.364 0.730 0.302 0.747 0.359 0.773 0.297 0.789 0.347 0.815 0.290 0.832 0.342 0.861 0.285 0.883 0.347 0.907 0.285 0.923 0.332 1.000 0.252) :duration dur :scaler (hz->radians 8100.0))) (gen1 (make-polywave 0.0 '(1 .99 3 .005))) (gen2 (make-oscil)) (gen3 (make-oscil)) (ampf2 (make-env '(0 .2 .1 1 .13 0 1 0) :duration dur :scaler .5)) (ampf3 (make-env '(0 .3 .1 .3 .16 1 .19 0 1 0) :duration dur :scaler 1)) (rnd (make-rand-interp 1000 (hz->radians 50)))) (do ((i start (+ i 1))) ((= i stop)) (let ((frq (+ (env frqf) (rand-interp rnd)))) (outa i (* (env ampf) (+ (polywave gen1 frq) (* (env ampf2) (oscil gen2 (* 1.5 frq))) (* (env ampf3) (oscil gen3 (* 2.0 frq))))))))))) ;; (with-sound (:play #t) (plumbeous-vireo-2 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Least bittern (defanimal (least-bittern beg amp) (let ((dur 1.25) (pulse-dur .09)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.100 0.123 0.388 0.454 0.884 0.649 0.995 0.754 0.776 1.000 0.100) :duration dur :scaler amp)) (frqf (make-env '(0 .6 1 .75 2 1 3 .40) :duration dur :scaler (hz->radians 90))) (gen1 #f) (rnd (make-rand-interp 200 (hz->radians 40))) (pulse-samps (seconds->samples .13)) (pulse-out (seconds->samples pulse-dur)) (pulse-ampf (make-env '(0.000 0.000 0.119 0.698 0.258 1.000 0.355 0.310 0.564 0.1 0.7 0.070 1.3 0) :duration pulse-dur)) (pulse-frqf (make-env '(0 150 .3 300 1 250 2 200 3 200 3.5 150 4 230) :duration pulse-dur :scaler (hz->radians 1.0))) (pulse-rnd #f)) (do ((i start (+ i pulse-samps))) ((>= i stop)) (set! (mus-location ampf) (- i start)) (let ((reset-stop (min stop (+ i pulse-out))) (pulse-amp (env ampf))) (set! (mus-location frqf) (- i start)) (set! gen1 (make-polywave 0.0 (list 1 (* pulse-amp .25) 2 (* pulse-amp .6) 3 (* pulse-amp .2) 4 (* pulse-amp .01) 5 (* pulse-amp .01)))) (set! pulse-rnd (make-rand-interp 4000 (* pulse-amp .2))) (do ((k i (+ k 1))) ((= k reset-stop)) (outa k (* (env pulse-ampf) (+ (polywave gen1 (+ (env frqf) (env pulse-frqf) (rand-interp rnd))) (rand-interp pulse-rnd))))) (mus-reset pulse-ampf) (mus-reset pulse-frqf)))))) ;; (with-sound (:play #t) (least-bittern 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; American crow (define (nrcos->polywave n r scl) (if (and (positive? n) (< n 8192)) (let ((lst ()) (total (polynomial (make-float-vector n 1.0) r))) (set! scl (/ scl total)) (do ((i 0 (+ i 1))) ((= i n) (reverse lst)) (set! lst (cons (* scl (expt r i)) (cons (+ i 1) lst))))) (error 'out-of-range "nrcos->polywave: too many partials"))) (defanimal (american-crow beg amp) (let ((dur 0.27)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 .02 .1 .04 .01 .06 0.056 0.110 0.700 0.258 1.000 0.344 0.970 0.369 0.677 .7 .3 1.000 0.000) :duration dur :scaler (* 2 amp))) (frqf (make-env '(0.000 0.360 0.038 0.362 0.052 0.396 0.076 0.403 0.095 0.445 0.129 0.445 0.153 0.493 0.201 0.495 0.231 0.501 0.260 0.490 0.297 0.503 0.317 0.499 0.346 0.473 0.407 0.473 0.435 0.424 0.495 0.439 0.528 0.392 0.589 0.405 0.621 0.362 0.677 0.373 0.704 0.332 0.767 0.325 0.791 0.281 0.832 0.278 0.859 0.251 0.890 0.225 0.912 0.255 0.950 0.263 1.000 0.26) :duration dur :scaler (hz->radians 1250.0))) (frm1 (make-formant 1400 .995)) (frm2 (make-formant 5500 .98)) (frm3 (make-formant 3800 .98)) (fr1 (* 2 20 (sin (hz->radians 1400)))) (fr2 (* 2 (sin (hz->radians 5500)))) (fr3 (* 2 2 (sin (hz->radians 3800)))) (gen (make-polywave 0.0 (nrcos->polywave 15 .75 1.0))) (rnd (make-rand-interp 5000 .007))) (let ((fb (vector frm1 frm2 frm3)) (fs (float-vector fr1 fr2 fr3))) (set! fb (make-formant-bank fb fs)) (do ((i start (+ i 1))) ((= i stop)) (outa i (formant-bank fb (* (env ampf) (polywave gen (+ (env frqf) (rand-interp rnd))))))))))) ;; (with-sound (:play #t) (american-crow 0 .5)) (defanimal (american-crow-no-formants beg amp) ; this is for sndclm.html (let ((dur 0.27)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 .02 .1 .04 .01 .06 0.056 0.110 0.700 0.258 1.000 0.344 0.970 0.369 0.677 .7 .3 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.360 0.038 0.362 0.052 0.396 0.076 0.403 0.095 0.445 0.129 0.445 0.153 0.493 0.201 0.495 0.231 0.501 0.260 0.490 0.297 0.503 0.317 0.499 0.346 0.473 0.407 0.473 0.435 0.424 0.495 0.439 0.528 0.392 0.589 0.405 0.621 0.362 0.677 0.373 0.704 0.332 0.767 0.325 0.791 0.281 0.832 0.278 0.859 0.251 0.890 0.225 0.912 0.255 0.950 0.263 1.000 0.26) :duration dur :scaler (hz->radians 1250.0))) (gen (make-polywave 0.0 (nrcos->polywave 15 .75 1.0) mus-chebyshev-second-kind)) (rnd (make-rand-interp 5000 .007))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen (+ (env frqf) (rand-interp rnd))))))))) ;;; -------------------------------------------------------------------------------- ;;; ;;; Orange-crowned warbler (defanimal (orange-crowned-warbler beg amp) (let ((dur 1.5) (pulse-dur 0.045) (call2-dur 0.13) (start (seconds->samples beg))) (let ((stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.05 0.347 1.000 0.838 0.831 1.000 0.000) :duration dur :scaler amp)) (gen1 (make-oscil)) (frqf (make-env '(0 0 7 1 10 0) :duration dur :scaler (hz->radians 600.0))) (pulse-ampf1 (make-env '(0.000 0.000 0.038 0.152 0.062 0.115 0.148 0.468 0.211 0.530 0.228 0.290 0.266 0.642 0.313 0.873 0.362 0.623 0.401 0.918 0.443 0.054 0.475 0.983 0.490 0.901 0.501 0.290 0.525 0.668 0.576 0.189 0.605 0.155 0.621 0.313 0.656 0.082 0.679 0.259 0.703 0.118 0.730 0.177 0.752 0.062 0.775 0.155 0.798 0.048 0.812 0.099 0.831 0.059 0.885 0.096 0.922 0.048 0.947 0.087 1.000 0.000) :duration pulse-dur)) (pulse-frqf1 (make-env '(0 3700 .2 4500 .3 4500 .45 4000 .8 4000 1 4300) :duration pulse-dur :scaler (hz->radians 1.0))) (pulse-samps (seconds->samples pulse-dur)) (call1-stop (+ start (seconds->samples 1.35))) (call2-start (+ start (seconds->samples 1.36))) (pulse-ampf2 (make-env '(0.000 0.000 0.074 0.994 0.135 0.375 0.184 0.637 0.238 0.721 0.290 0.411 0.381 0.003 0.537 0.000 0.591 0.186 0.704 0.121 0.737 0.437 0.843 0.358 0.880 0.045 0.908 0.225 1.000 0.000) :duration call2-dur :scaler (* 0.5 amp))) (pulse-frqf2 (make-env '(0 4800 .1 3950 .15 3820 .22 3950 .4 4800 .6 4600 .7 3480 .75 3940 .86 5200 1 5150) :duration call2-dur :scaler (hz->radians 1.0)))) ;; 30 repetitions, then 2 special end tones (do ((i start (+ i pulse-samps))) ((>= i call1-stop)) (set! (mus-location ampf) (- i start)) (let ((reset-stop (min call1-stop (+ i pulse-samps))) (pulse-amp (env ampf))) (do ((k i (+ k 1))) ((= k reset-stop)) (outa k (* pulse-amp (env pulse-ampf1) (oscil gen1 (+ (env frqf) (env pulse-frqf1)))))) (mus-reset pulse-ampf1) (mus-reset pulse-frqf1))) (do ((i call2-start (+ i 1))) ((= i stop)) (outa i (* (env pulse-ampf2) (oscil gen1 (env pulse-frqf2)))))))) ;; (with-sound (:play #t) (orange-crowned-warbler 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Loggerhead shrike (defanimal (loggerhead-shrike-1 beg amp) (let ((dur 0.65) (open-dur .036) (pulse-dur .008) (start (seconds->samples beg))) (let ((stop (seconds->samples (+ beg dur))) (ampf (make-env '(0 0 .01 1 .99 1 1 0) :duration dur :scaler amp)) (gen1 (make-oscil)) (frqf (make-env '(0 0 1 1) :duration dur :scaler (hz->radians 100.0))) (open-samps (seconds->samples open-dur))) (let ((open-stop (+ start open-samps)) (open-ampf (make-env '(0.000 0.000 0.158 0.063 0.280 0.162 0.386 0.775 0.418 0.644 0.465 0.000 0.573 0.000 0.592 0.921 .62 .1 0.633 0.866 0.726 0.000 0.788 0.000 0.829 0.399 0.889 0.154 1.000 0.000) :duration open-dur :scaler .75)) (open-frqf (make-env '(0 4200 .35 3900 .46 3800 .57 3600 .6 3900 .61 5100 .72 5100 .8 3400 .83 4200 1 4200) :duration open-dur :scaler (hz->radians 1.0))) (pulse-samps (seconds->samples pulse-dur)) (pulse-ampf (make-env '(0 0 .05 1 .3 1 .8 .1 1 0) :duration pulse-dur)) (pulse-frqf (make-env '(0 3600 .2 4800 .5 5000 .85 4000 1 3700) :duration pulse-dur :scaler (hz->radians 1.0))) (trem (make-oscil 160)) (rnd (make-rand-interp 500 .04)) (rnd1 (make-rand-interp 100 .01))) ;; special starting call, then the buzz (do ((i start (+ i 1))) ((= i open-stop)) (outa i (* (env open-ampf) (env ampf) (oscil gen1 (+ (env frqf) (env open-frqf)))))) (do ((i open-stop (+ i pulse-samps))) ((>= i stop)) (set! (mus-location ampf) (- i start)) (let ((reset-stop (min stop (+ i pulse-samps))) (pulse-amp (env ampf))) (do ((k i (+ k 1))) ((= k reset-stop)) (outa k (* pulse-amp (* (env pulse-ampf) (+ .5 (* .5 (abs (oscil trem (rand-interp rnd1))))) (oscil gen1 (+ (env frqf) (env pulse-frqf) (rand-interp rnd))))))) (mus-reset pulse-ampf) (mus-reset pulse-frqf))))))) ;; (with-sound (:play #t) (loggerhead-shrike-1 0 .5)) (defanimal (loggerhead-shrike-2 beg amp) (let ((dur 0.4) (pulse-dur .08) (frqs (vector .9 .95 .95 1.0 1.0 1.0)) (start (seconds->samples beg))) (let ((stop (seconds->samples (+ beg dur))) (pulse-samps (seconds->samples pulse-dur)) (pulse-ampf (make-env '(0.000 0.000 0.114 0.077 0.153 0.943 0.191 0.960 0.291 0.510 0.320 0.114 0.342 0.647 0.373 0.191 0.400 0.490 0.419 0.066 0.456 0.291 0.728 0.288 0.769 0.479 0.792 0.407 0.812 0.003 1.000 0.000) :duration pulse-dur :scaler amp)) (frqf1 (make-env '(0.000 0.229 0.310 0.231 0.325 0.271 0.345 0.273 0.377 0.237 0.397 0.240 0.615 0.235 0.7 0.235 1.000 0.235) :duration pulse-dur :scaler (hz->radians 10500.0))) (frqf2 (make-env '(0.000 0.13 .6 .13 0.7 0.15 .9 .15 1.000 0.1) :duration pulse-dur :scaler (hz->radians 10500.0)))) (let ((ampf1 (make-env '(0 1 .8 1 1 0) :duration pulse-dur)) (ampf2 (make-env '(0 0 .6 0 .7 1 1 1) :duration pulse-dur)) (gen1 (make-polywave 0.0 '(1 .95 2 .04 3 .005))) (gen2 (make-polywave 0.0 '(1 .5 2 .5 4 .01))) (pulse-frq (frqs 0)) (pulse-ctr 1) (rnd (make-rand-interp 500 .02))) (do ((i start (+ i pulse-samps))) ((>= i stop)) (let ((reset-stop (min stop (+ i pulse-samps)))) (do ((k i (+ k 1))) ((= k reset-stop)) (let ((noise (rand-interp rnd))) (outa k (* (env pulse-ampf) (+ (* (env ampf1) (polywave gen1 (* pulse-frq (+ noise (env frqf1))))) (* (env ampf2) (polywave gen2 (* pulse-frq (+ noise (env frqf2)))))))))) (set! pulse-frq (frqs pulse-ctr)) (set! pulse-ctr (+ pulse-ctr 1)) (mus-reset pulse-ampf) (mus-reset ampf1) (mus-reset ampf2) (mus-reset frqf1) (mus-reset frqf2))))))) ;; (with-sound (:play #t) (loggerhead-shrike-2 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; California Quail (defanimal (california-quail beg amp) (let ((durs (vector .075 .23 .16)) (begs (vector 0.0 .21 .58)) (ampfs (make-vector 3 #f)) (frqfs (make-vector 3 #f)) (gens (make-vector 3 #f)) (starts (make-vector 3 0)) (stops (make-vector 3 0)) (frm1 (make-formant 1000 .995)) (frm2 (make-formant 1700 .99)) (frm3 (make-formant 5600 .98)) (fr1 (* 2 5 (sin (hz->radians 1000)))) (fr2 (* 2 15 (sin (hz->radians 1700)))) (fr3 (* 2 5 (sin (hz->radians 5600))))) (let ((fb (vector frm1 frm2 frm3)) (fs (float-vector fr1 fr2 fr3))) (set! fb (make-formant-bank fb fs)) (do ((i 0 (+ i 1))) ((= i 3)) (set! (starts i) (seconds->samples (+ beg (begs i)))) (set! (stops i) (+ (starts i) (seconds->samples (durs i))))) (set! (gens 0) (make-nrxysin 530 1.0 8 .5)) (set! (gens 1) (make-nrxysin 450 1.0 15 .6)) (set! (gens 2) (make-nrxysin 400 1.0 8 .5)) (set! (ampfs 0) (make-env '(0 0 1.25 1 1.75 1 3 0) :base 10 :duration (durs 0) :scaler (* amp 0.25))) (set! (ampfs 1) (make-env '(0.000 0.000 0.208 0.719 0.292 0.965 0.809 0.869 0.928 0.682 1.000 0.000) :base 10 :duration (durs 1) :scaler (* 0.5 amp))) (set! (ampfs 2) (make-env '(0 0 1 1 3 1 6 0) :base 10 :duration (durs 2) :scaler (* amp .375))) (set! (frqfs 0) (make-env '(0 0 1.3 1 2 0) :duration (durs 0) :scaler (hz->radians 300))) (set! (frqfs 1) (make-env '(0 0 1.5 .8 2.5 1 4 .95 5 .25) :base .03 :duration (durs 1) :scaler (hz->radians 520))) (set! (frqfs 2) (make-env '(0 0 .2 .7 .3 1 1 .5) :duration (durs 2) :scaler (hz->radians 450.0))) (do ((k 0 (+ k 1))) ((= k 3)) (let ((start (starts k)) (stop (stops k)) (ampf (ampfs k)) (frqf (frqfs k)) (gen (gens k))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (formant-bank fb (nrxysin gen (env frqf))))))))))) ;; (with-sound (:play #t) (california-quail 0 .25)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Vermillion flycatcher (defanimal (vermillion-flycatcher beg amp) (let ((dur 0.72)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.023 0.527 0.045 0.000 0.264 0.000 0.282 0.868 0.295 0.231 0.312 0.000 0.462 0.000 0.481 0.918 0.503 0.206 0.520 0.000 0.598 0.000 0.614 0.848 0.633 0.729 0.648 0.164 0.660 0.000 0.685 0.000 0.696 0.654 0.709 0.746 0.719 0.532 0.738 0.000 0.747 0.100 0.750 0.570 0.770 0.435 0.779 0.000 0.814 0.000 0.823 0.923 0.836 0.525 0.840 0.998 0.855 0.968 0.866 0.321 0.883 0.095 0.909 0.517 0.924 0.600 0.961 0.440 1.000 0.000) :duration dur :scaler amp)) (gen1 (make-polywave 0.0 '(1 .98 2 .015 3 .006))) (frqf (make-env '(0.000 0.378 0.022 0.474 0.032 0.400 0.266 0.378 0.278 0.496 0.297 0.402 0.462 0.351 0.469 0.466 0.482 0.526 0.504 0.398 0.602 0.378 0.607 0.486 0.617 0.546 0.637 0.490 0.643 0.398 0.686 0.402 0.689 0.510 0.709 0.582 0.721 0.560 0.736 0.558 0.744 0.406 0.752 0.562 0.767 0.679 0.793 0.394 0.810 0.394 0.827 0.851 0.836 0.633 0.849 0.564 0.856 0.478 0.871 0.448 0.887 0.480 0.902 0.506 0.924 0.510 0.950 0.500 0.973 0.466 1.000 0.470) :duration dur :scaler (hz->radians 8000.0)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) ;; (with-sound (:play #t) (vermillion-flycatcher 0 .5)) ;;;-------------------------------------------------------------------------------- ;;; ;;; Cardinal (defanimal (cardinal beg amp) (let ((call1-dur 0.185) (call2-dur 0.19) (start (seconds->samples beg))) (let ((stop (+ start (seconds->samples 3.26))) (call 0) (next-call 0) (gen1 (make-polywave 0.0 (normalize-partials '(1 1 2 .08 3 .01 4 .05 5 .005 6 .01)))) (call1-ampf (make-env '(0.000 0.000 0.174 0.333 0.243 0.273 0.332 0.446 0.391 0.373 0.446 0.488 0.496 0.363 0.545 0.064 0.606 0.048 0.632 0.614 0.676 0.783 0.732 0.655 0.764 0.667 0.802 0.992 0.841 0.659 0.888 0.633 0.951 0.347 0.974 0.122 1.000 0.000) :duration call1-dur :scaler (* 0.5 amp))) (call1-frqf (make-env '(0.000 0.299 0.230 0.320 0.387 0.339 0.513 0.349 0.586 0.349 0.610 0.534 0.622 0.570 0.654 0.585 0.703 0.594 0.753 0.584 0.778 0.566 0.803 0.560 0.911 0.434 1.000 0.435) :duration call1-dur :scaler (hz->radians 6000.0))) (call2-ampf (make-env '(0.000 0.000 0.041 0.159 0.101 0.263 0.167 0.247 0.246 0.126 0.266 0.150 0.443 0.000 0.573 0.000 0.599 0.202 0.635 0.299 0.667 0.273 0.683 0.371 0.724 0.411 0.796 0.000 0.83 0.0 0.848 0.155 0.870 1.000 0.925 0.639 0.951 0.126 1.000 0.000) :duration call2-dur :scaler amp)) (call2-frqf (make-env '(0.000 0.138 0.032 0.173 0.063 0.187 0.215 0.176 0.403 0.140 0.542 0.117 0.590 0.214 0.659 0.218 0.750 0.250 0.794 0.244 0.832 0.618 0.843 0.518 0.876 0.352 0.909 0.335 0.954 0.323 1.000 0.311) :duration call2-dur :scaler (hz->radians 10000.0)))) (let ((call-ampf call1-ampf) (call-frqf call1-frqf) (call-samps (seconds->samples call1-dur))) (do ((i start next-call)) ((>= i stop)) (let ((call-stop (min stop (+ i call-samps)))) (do ((k i (+ k 1))) ((= k call-stop)) (outa k (* (env call-ampf) (polywave gen1 (env call-frqf)))))) (mus-reset call-ampf) (mus-reset call-frqf) (if (= call 0) (set! next-call (+ start (seconds->samples 0.35))) (if (= call 1) (begin (set! next-call (+ next-call (seconds->samples (- 0.63 0.35)))) (set! call-samps (seconds->samples call2-dur)) (set! call-ampf call2-ampf) (set! call-frqf call2-frqf)) (set! next-call (+ next-call (seconds->samples 0.24))))) (set! call (+ call 1))))))) ;; (with-sound (:play #t) (cardinal 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Black phoebe (defanimal (black-phoebe beg amp) (let ((dur 0.36)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.082 0.899 0.098 0.957 0.118 0.892 0.142 0.396 0.181 0.000 0.287 0.000 0.367 0.661 0.396 0.000 0.440 0.778 0.458 0.739 0.479 0.300 0.507 0.636 0.532 0.558 0.555 0.380 0.588 0.535 0.807 0.325 0.926 0.181 1.000 0.000) :duration dur :scaler amp)) (gen1 (make-polywave 0.0 '(1 .9 2 .1 3 .006))) (frqf (make-env '(0.000 0.167 0.066 0.212 0.077 0.234 0.104 0.231 0.132 0.187 0.148 0.181 0.166 0.153 0.231 0.146 0.289 0.101 0.298 0.196 0.319 0.229 0.339 0.222 0.349 0.240 0.357 0.219 0.377 0.159 0.388 0.146 0.401 0.167 0.417 0.199 0.438 0.209 0.456 0.202 0.467 0.177 0.479 0.174 0.485 0.196 0.503 0.206 0.531 0.201 0.550 0.176 0.563 0.194 0.602 0.196 0.622 0.186 0.658 0.192 0.931 0.163 1.000 0.141) :duration dur :scaler (hz->radians 22050.0)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) ;; (with-sound (:play #t) (black-phoebe 0 .25)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Yellow warbler (defanimal (yellow-warbler beg amp) (let ((dur 1.38)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (gen1 (make-oscil)) (ampf (make-env '(0.000 0.000 0.028 0.077 0.056 0.000 0.135 0.000 0.156 0.125 0.182 0.112 0.197 0.000 0.268 0.000 0.287 0.235 0.314 0.243 0.326 0.000 0.406 0.000 0.415 0.339 0.440 0.301 0.463 0.000 0.486 0.000 0.499 0.403 0.513 0.611 0.531 0.592 0.553 0.000 0.582 0.000 0.596 0.517 0.606 0.648 0.627 0.621 0.640 0.000 0.667 0.000 0.673 0.533 0.696 0.896 0.720 0.000 0.750 0.000 0.774 1.000 0.800 0.000 0.831 0.000 0.858 0.971 0.884 0.000 0.905 0.000 0.926 0.349 0.942 0.424 0.978 0.421 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.827 0.026 0.661 0.042 0.706 0.104 0.695 0.134 0.909 0.167 0.672 0.184 0.708 0.229 0.677 0.271 0.909 0.292 0.715 0.303 0.670 0.310 0.713 0.342 0.674 0.396 0.911 0.418 0.715 0.425 0.672 0.441 0.727 0.480 0.720 0.487 0.476 0.491 0.533 0.510 0.558 0.526 0.704 0.539 0.765 0.563 0.754 0.578 0.472 0.582 0.526 0.594 0.540 0.618 0.720 0.630 0.781 0.656 0.765 0.674 0.683 0.693 0.567 0.713 0.408 0.735 0.410 0.751 0.711 0.765 0.654 0.795 0.358 0.817 0.355 0.826 0.708 0.839 0.681 0.854 0.565 0.881 0.330 0.904 0.308 0.924 0.351 0.957 0.460 0.967 0.408 0.976 0.362 1.000 0.314) :duration dur :scaler (hz->radians 10000.0)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (oscil gen1 (env frqf)))))))) ;; (with-sound (:play #t) (yellow-warbler 0 .25)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Barred owl (the "hoo-aw" call, not the more complex one -- I haven't succeeded with the latter yet) (defanimal (barred-owl-1 beg amp) (let ((dur 1.27) (owl-env '(0 0 .53 0 .54 1 1 1))) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.030 0.308 0.052 0.345 0.057 0.932 0.104 0.567 0.161 0.605 0.259 0.510 0.299 0.399 0.371 0.535 0.396 0.463 0.472 0.678 0.495 1.000 0.517 0.995 0.534 0.000 0.538 0.365 0.560 0.435 0.630 0.254 0.828 0.338 0.850 0.190 0.897 0.154 0.929 0.079 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.09 0.025 0.09 0.092 0.156 0.435 0.149 0.491 0.132 0.517 0.124 0.53 .124 0.536 0.088 0.830 0.061 1.000 0.013) :base .03 :duration dur :scaler (hz->radians 4060.0))) (gen1 (make-polywave 0.0 (nrcos->polywave 9 .5 1.0))) (rnd (make-rand-interp 300 (hz->radians 5))) (intrpf (make-env owl-env :duration dur)) (intrpf1 (make-env owl-env :offset (hz->radians 550.0) :scaler (hz->radians 80.0) :duration dur)) (intrpf2 (make-env owl-env :offset (hz->radians 1500.0) :scaler (hz->radians -400.0) :duration dur)) (intrpf3 (make-env owl-env :offset (hz->radians 2300.0) :scaler (hz->radians 150.0) :duration dur)) (rnd1 (make-rand-interp 1000 .1)) (frm1 (make-formant 730 .995)) (frm2 (make-formant 1090 .999)) (frm3 (make-formant 2240 .993)) (fr1 (* 2 15 (sin (hz->radians 730)))) (fr2 (* 2 (sin (hz->radians 1090)))) (fr3 (* 2 (sin (hz->radians 2240)))) (vib (make-polywave 12.0 (list 1 (hz->radians 7.0))))) (do ((i start (+ i 1))) ((= i stop)) (let ((val (* (+ .9 (rand-interp rnd1)) (polywave gen1 (+ (env frqf) (* (env intrpf) (+ (polywave vib) (rand-interp rnd)))))))) (outa i (* (env ampf) (+ (* fr1 (formant frm1 val (env intrpf1))) (* fr2 (formant frm2 val (env intrpf2))) (* fr3 (formant frm3 val (env intrpf3))))))))))) ;; (with-sound (:play #t :statistics #t) (barred-owl-1 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Say's phoebe (defanimal (says-phoebe beg amp) (let ((dur 0.64)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.017 0.223 0.039 0.372 0.056 0.000 0.101 0.000 0.122 0.132 0.145 0.000 0.192 0.000 0.214 0.639 0.232 0.507 0.324 0.981 0.415 0.402 0.496 0.413 0.610 0.317 0.771 0.287 0.970 0.179 1.000 0.000) :duration dur :scaler amp)) (gen1 (make-polywave 0.0 '(1 .98 2 .07 3 .08 4 .01 5 .003))) (frqf (make-env '(0.000 0.221 0.022 0.305 0.032 0.318 0.040 0.297 0.054 0.225 0.106 0.229 0.111 0.250 0.130 0.240 0.139 0.215 0.196 0.238 0.205 0.274 0.223 0.322 0.249 0.337 0.295 0.333 0.324 0.310 0.356 0.293 0.584 0.265 0.781 0.261 0.958 0.250 1.000 0.204) :duration dur :scaler (hz->radians 10040.0)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) ;; (with-sound (:play #t) (says-phoebe 0 .25)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Yellow-rumped warbler (defanimal (yellow-rumped-warbler beg amp) (let ((dur 1.6)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.009 0.038 0.022 0.220 0.028 0.000 0.037 0.152 0.048 0.000 0.079 0.000 0.088 0.218 0.094 0.000 0.109 0.132 0.122 0.488 0.127 0.363 0.128 0.000 0.133 0.303 0.141 0.381 0.147 0.000 0.178 0.000 0.196 0.296 0.201 0.000 0.216 0.432 0.227 0.515 0.231 0.000 0.242 0.601 0.250 0.000 0.269 0.000 0.290 0.187 0.298 0.040 0.305 0.227 0.311 0.000 0.316 0.486 0.327 0.579 0.331 0.000 0.336 0.407 0.343 0.459 0.345 0.000 0.371 0.000 0.376 0.085 0.386 0.122 0.393 0.399 0.397 0.000 0.405 0.194 0.412 0.045 0.419 0.470 0.428 0.505 0.431 0.000 0.444 0.630 0.446 0.100 0.458 0.000 0.474 0.000 0.477 0.114 0.488 0.169 0.496 0.412 0.500 0.000 0.505 0.207 0.509 0.100 0.516 0.265 0.524 0.748 0.530 0.599 0.537 0.000 0.541 0.613 0.545 0.819 0.551 0.000 0.577 0.000 0.584 0.151 0.591 0.200 0.601 0.577 0.607 0.004 0.610 0.319 0.614 0.111 0.618 0.283 0.621 0.132 0.626 0.993 0.637 0.924 0.642 0.000 0.644 0.621 0.652 0.855 0.655 0.000 0.681 0.000 0.687 0.156 0.696 0.214 0.706 0.613 0.709 0.000 0.711 0.187 0.719 0.120 0.726 0.902 0.733 0.494 0.737 0.955 0.749 0.000 0.753 0.673 0.768 0.000 0.784 0.000 0.810 0.768 0.821 0.227 0.829 0.000 0.849 0.592 0.855 0.281 0.863 0.000 0.874 0.354 0.875 0.000 0.901 0.000 0.913 0.430 0.931 0.517 0.941 0.000 0.948 0.000 0.965 0.454 0.971 0.169 0.975 0.120 0.987 0.225 0.993 0.045 1.000 0.000) :duration dur :scaler amp)) (gen1 (make-polywave 0.0 '(1 .99 2 .01 3 .005))) (frqf (make-env '(0.000 0.371 0.017 0.571 0.030 0.491 0.035 0.397 0.037 0.321 0.043 0.466 0.047 0.438 0.052 0.387 0.087 0.344 0.095 0.417 0.102 0.290 0.106 0.458 0.108 0.507 0.117 0.542 0.122 0.513 0.131 0.446 0.135 0.384 0.136 0.323 0.145 0.446 0.150 0.407 0.151 0.356 0.185 0.403 0.189 0.442 0.190 0.337 0.201 0.440 0.205 0.294 0.212 0.483 0.218 0.536 0.224 0.515 0.234 0.434 0.235 0.317 0.243 0.446 0.248 0.436 0.252 0.309 0.279 0.352 0.286 0.438 0.290 0.405 0.291 0.356 0.298 0.425 0.302 0.307 0.307 0.468 0.311 0.530 0.318 0.530 0.330 0.436 0.335 0.350 0.340 0.429 0.343 0.458 0.345 0.436 0.350 0.382 0.377 0.389 0.381 0.434 0.386 0.350 0.397 0.446 0.403 0.331 0.408 0.495 0.411 0.517 0.417 0.526 0.428 0.458 0.431 0.417 0.434 0.348 0.441 0.476 0.449 0.401 0.479 0.362 0.485 0.431 0.490 0.354 0.499 0.438 0.502 0.342 0.509 0.515 0.513 0.540 0.521 0.515 0.529 0.456 0.536 0.366 0.541 0.479 0.551 0.374 0.582 0.370 0.588 0.440 0.591 0.348 0.601 0.421 0.605 0.356 0.611 0.515 0.616 0.532 0.623 0.517 0.636 0.425 0.638 0.339 0.644 0.464 0.650 0.438 0.654 0.395 0.655 0.344 0.680 0.368 0.688 0.425 0.692 0.356 0.702 0.421 0.706 0.344 0.710 0.497 0.718 0.509 0.727 0.476 0.740 0.397 0.743 0.470 0.747 0.534 0.754 0.497 0.760 0.446 0.788 0.499 0.793 0.528 0.796 0.448 0.814 0.507 0.816 0.374 0.826 0.352 0.835 0.360 0.839 0.389 0.846 0.438 0.851 0.337 0.862 0.333 0.868 0.395 0.900 0.485 0.907 0.489 0.909 0.431 0.922 0.452 0.926 0.485 0.934 0.317 0.943 0.350 0.954 0.352 0.961 0.423 0.965 0.325 0.974 0.317 0.983 0.376 0.985 0.436 1.000 0.454) :duration dur :scaler (hz->radians 10125.0)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) ;; (with-sound (:play #t) (yellow-rumped-warbler 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Purple finch (defanimal (purple-finch beg amp) (let ((dur 2.5)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.0000 0.0000 0.0150 0.0420 0.0210 0.0018 0.0291 0.0804 0.0355 0.1682 0.0402 0.0658 0.0428 0.2468 0.0449 0.0676 0.0505 0.1243 0.0522 0.0000 0.0651 0.0000 0.0702 0.1298 0.0741 0.0841 0.0766 0.1590 0.0848 0.0000 0.0890 0.0530 0.0950 0.2724 0.1006 0.2249 0.1032 0.1499 0.1057 0.3784 0.1104 0.2578 0.1143 0.0000 0.1259 0.0000 0.1284 0.1901 0.1323 0.1079 0.1361 0.2358 0.1417 0.0000 0.1468 0.0000 0.1507 0.2486 0.1558 0.2888 0.1614 0.1207 0.1648 0.5503 0.1678 0.2267 0.1691 0.3693 0.1717 0.0000 0.1858 0.0000 0.1896 0.1938 0.1931 0.0859 0.1952 0.2267 0.2016 0.0000 0.2063 0.0420 0.2149 0.4771 0.2188 0.4004 0.2209 0.1865 0.2256 0.6399 0.2265 0.2596 0.2295 0.4644 0.2354 0.0000 0.2436 0.0000 0.2491 0.2431 0.2513 0.1718 0.2568 0.3528 0.2616 0.0000 0.2748 0.0640 0.2868 0.4388 0.2967 0.4954 0.3018 0.0000 0.3215 0.0000 0.3318 0.1865 0.3339 0.1097 0.3412 0.7697 0.3438 0.3857 0.3450 0.7770 0.3472 0.4260 0.3485 0.7843 0.3502 0.3565 0.3528 0.7751 0.3566 0.0000 0.3669 0.0000 0.3716 0.5686 0.3737 0.2303 0.3776 0.9854 0.3801 0.3108 0.3840 0.3309 0.3857 0.5960 0.3908 0.1207 0.3934 0.5759 0.4003 0.0000 0.4127 0.0000 0.4199 0.2176 0.4234 0.1152 0.4272 0.5850 0.4281 0.2980 0.4324 0.5009 0.4345 0.3693 0.4379 0.4241 0.4405 0.2943 0.4452 0.5046 0.4533 0.1408 0.4568 0.5795 0.4606 0.0000 0.4735 0.0000 0.4837 0.8501 0.4842 0.6088 0.4880 0.7093 0.4893 0.6581 0.4923 0.9049 0.4953 0.1828 0.4974 0.7770 0.5009 0.0859 0.5060 0.8537 0.5132 0.0000 0.5256 0.0000 0.5321 0.7477 0.5368 0.3364 0.5420 0.6527 0.5454 0.2834 0.5488 0.2212 0.5518 0.0512 0.5552 0.6691 0.5634 0.0000 0.5766 0.0000 0.5775 0.3364 0.5809 0.0000 0.5826 0.4826 0.5860 0.0037 0.5920 0.6362 0.5963 0.5448 0.5967 0.6600 0.5993 0.5759 0.6002 0.6289 0.6040 0.5503 0.6100 0.9360 0.6160 0.0000 0.6271 0.0000 0.6280 0.3583 0.6322 0.0000 0.6327 0.4388 0.6366 0.0000 0.6430 0.7733 0.6468 0.6088 0.6481 0.7532 0.6528 0.7166 0.6541 0.4899 0.6563 0.8355 0.6648 0.0000 0.6777 0.0000 0.6781 0.2523 0.6817 0.0000 0.6832 0.2943 0.6870 0.0000 0.6952 0.5850 0.7033 0.4095 0.7098 0.6728 0.7145 0.0000 0.7286 0.0000 0.7295 0.1609 0.7334 0.0000 0.7359 0.3382 0.7380 0.0000 0.7483 0.4845 0.7539 0.5814 0.7624 0.0000 0.7748 0.0000 0.7783 0.2633 0.7811 0.0000 0.7825 0.2541 0.7869 0.0000 0.7958 0.4717 0.8031 0.5393 0.8116 0.0000 0.8271 0.0000 0.8288 0.2431 0.8315 0.0000 0.8339 0.0000 0.8399 0.2687 0.8433 0.1700 0.8446 0.3967 0.8506 0.4826 0.8600 0.0000 0.8754 0.0000 0.8767 0.1207 0.8796 0.0000 0.8818 0.2377 0.8844 0.0000 0.8951 0.3528 0.9114 0.0000 0.9255 0.0000 0.9285 0.1024 0.9322 0.0000 0.9336 0.1737 0.9388 0.0000 0.9439 0.0859 0.9482 0.2431 0.9521 0.1024 0.9546 0.2761 0.9636 0.0000 0.9850 0.0000 0.9927 0.0402 1.0000 0.0000) :duration dur :scaler amp)) (gen1 (make-polywave 0.0 '(1 .98 2 .01 3 .005 4 .003))) (rnd (make-rand-interp 800 (hz->radians 200))) (frqf (make-env '(0.0000 0.2374 0.0125 0.1869 0.0192 0.1616 0.0250 0.1835 0.0370 0.3316 0.0388 0.2407 0.0419 0.3013 0.0450 0.2003 0.0473 0.2694 0.0513 0.2155 0.0646 0.2003 0.0727 0.2761 0.0728 0.2020 0.0798 0.2559 0.0852 0.1751 0.0936 0.2424 0.0994 0.3535 0.1025 0.2424 0.1048 0.3030 0.1074 0.2138 0.1110 0.2576 0.1271 0.2290 0.1315 0.2037 0.1355 0.2374 0.1404 0.3451 0.1453 0.1684 0.1587 0.3350 0.1605 0.2542 0.1632 0.3131 0.1658 0.2525 0.1690 0.2744 0.1868 0.2239 0.1935 0.3249 0.1979 0.2357 0.2069 0.1835 0.2167 0.3316 0.2207 0.2559 0.2225 0.3199 0.2269 0.2273 0.2300 0.2795 0.2341 0.2290 0.2461 0.2222 0.2479 0.2559 0.2514 0.2138 0.2555 0.2576 0.2595 0.2020 0.2662 0.1667 0.2853 0.2458 0.2951 0.2778 0.3027 0.2256 0.3255 0.2306 0.3290 0.1902 0.3388 0.2811 0.3433 0.3232 0.3455 0.2424 0.3486 0.3754 0.3513 0.2155 0.3522 0.3333 0.3549 0.2879 0.3691 0.3519 0.3749 0.2710 0.3785 0.3384 0.3807 0.2811 0.3848 0.2576 0.3870 0.3064 0.3923 0.2492 0.3941 0.2997 0.3968 0.2744 0.4155 0.1852 0.4222 0.2357 0.4289 0.2845 0.4391 0.2845 0.4463 0.2795 0.4525 0.2340 0.4579 0.2980 0.4610 0.2138 0.4753 0.2980 0.4819 0.3249 0.4864 0.3636 0.4900 0.4040 0.4931 0.3468 0.4962 0.2795 0.4993 0.3535 0.5029 0.2542 0.5051 0.3788 0.5087 0.3114 0.5127 0.2811 0.5145 0.2189 0.5310 0.3519 0.5372 0.2811 0.5408 0.3603 0.5439 0.2862 0.5515 0.2441 0.5582 0.2997 0.5631 0.2239 0.5778 0.3131 0.5809 0.5017 0.5863 0.3266 0.5934 0.3990 0.5961 0.3064 0.6054 0.3603 0.6135 0.2761 0.6291 0.3215 0.6349 0.5051 0.6371 0.2997 0.6433 0.3822 0.6469 0.3232 0.6540 0.3451 0.6603 0.2929 0.6643 0.2458 0.6799 0.3114 0.6830 0.4983 0.6906 0.2424 0.6973 0.3098 0.7044 0.3485 0.7107 0.3165 0.7156 0.2593 0.7321 0.3249 0.7356 0.5286 0.7445 0.2138 0.7477 0.3030 0.7543 0.3064 0.7633 0.2256 0.7793 0.2761 0.7864 0.5034 0.7900 0.2189 0.7954 0.2205 0.7967 0.2778 0.8038 0.3182 0.8123 0.1734 0.8292 0.2290 0.8324 0.4293 0.8377 0.2155 0.8444 0.2121 0.8471 0.2929 0.8533 0.2963 0.8613 0.2037 0.8823 0.2391 0.8850 0.4478 0.8903 0.1886 0.8939 0.2256 0.8979 0.2946 0.9015 0.3131 0.9104 0.2088 0.9309 0.2172 0.9358 0.5556 0.9403 0.2172 0.9456 0.2290 0.9563 0.3215 0.9666 0.2104 0.9924 0.1785 1.0000 0.1801) :duration dur :scaler (hz->radians 10035.0)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (+ (env frqf) (rand-interp rnd))))))))) ;; (with-sound (:play #t) (purple-finch 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Northern goshawk (defanimal (northern-goshawk beg amp) (let ((dur 0.31)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.124 0.399 0.174 0.520 0.223 0.881 0.355 0.998 0.499 0.644 1.000 0.000) :duration dur :scaler amp)) (gen1 (make-polywave 0.0 '(1 .1 2 .8 3 .3 4 .05 5 .01 6 .005 7 .003))) (frqf (make-env '(0.000 0.137 0.126 0.138 0.237 0.144 0.314 0.142 0.400 0.140 1.000 0.130) :duration dur :scaler (hz->radians 9040.0)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) ;; (with-sound (:play #t) (northern-goshawk 0 .25)) ;;;-------------------------------------------------------------------------------- ;;; ;;; Common Gull (defanimal (common-gull beg amp) (let ((dur 0.42)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0 0 1 1 1.4 1 1.7 .8 1.8 .2 2 0) :duration dur :scaler amp)) (gen1 (make-rcos 1200 0.5)) (gen2 (make-rxycos 1800 (/ 1200 1800.0) 0.75)) (frqf (make-env '(0.000 0.326 0.057 0.599 0.075 0.602 0.102 0.637 0.140 0.618 0.255 0.626 0.378 0.607 0.401 0.589 0.441 0.584 0.491 0.562 0.591 0.544 0.628 0.557 0.675 0.541 0.733 0.538 0.756 0.523 0.809 0.501 0.853 0.469 0.887 0.390 1.000 0.325) :duration dur :offset (hz->radians -1200) :scaler (hz->radians 2000.0))) (intrpf (make-env '(0 1 .2 1 .5 0 1 0) :duration dur :scaler .3 :base 10)) (rnd (make-rand-interp 800 .2)) (attf (make-env '(0 1 .15 0 1 0) :duration dur :base 10)) (frm1 (make-formant 2300 .99)) (frm2 (make-formant 6100 .98)) (frm3 (make-formant 3800 .98)) (frm4 (make-formant 1800 .99)) (fr1 (* 2 5 (sin (hz->radians 2300)))) (fr2 (* 2 3 (sin (hz->radians 6100)))) (fr3 (* 2 5 (sin (hz->radians 3800)))) (fr4 (* 2 7 (sin (hz->radians 1800)))) (rnd2 (make-rand-interp 300 (hz->radians 15)))) (let ((fb (vector frm1 frm2 frm3 frm4)) (fs (float-vector fr1 fr2 fr3 fr4))) (set! fb (make-formant-bank fb fs)) (do ((i start (+ i 1))) ((= i stop)) (let ((frq (+ (env frqf) (rand-interp rnd2) (* (env attf) (rand-interp rnd))))) (outa i (* (env ampf) (formant-bank fb (+ (rcos gen1 frq) (* (env intrpf) (rxycos gen2 frq)))))))))))) ;; (with-sound (:play #t) (common-gull 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Ash-throated flycatcher (defanimal (ash-throated-flycatcher beg amp) (let ((dur 0.47)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.018 0.176 0.030 0.756 0.041 1.000 0.052 0.916 0.066 0.198 0.097 0.046 0.128 0.000 0.165 0.000 0.211 0.141 0.224 0.108 0.244 0.149 0.261 0.105 0.267 0.031 0.272 0.218 0.278 0.125 0.302 0.237 0.315 0.510 0.336 0.255 0.346 0.000 0.369 0.000 0.386 0.345 0.403 0.246 0.412 0.000 0.481 0.000 0.490 0.084 0.504 0.330 0.514 0.174 0.527 0.070 0.531 0.000 0.546 0.000 0.550 0.055 0.556 0.000 0.560 0.000 0.565 0.053 0.571 0.000 0.575 0.000 0.580 0.048 0.587 0.000 0.592 0.000 0.597 0.064 0.601 0.000 0.605 0.000 0.609 0.084 0.616 0.000 0.620 0.000 0.623 0.086 0.631 0.000 0.636 0.000 0.638 0.103 0.644 0.000 0.650 0.000 0.653 0.095 0.657 0.000 0.663 0.000 0.669 0.105 0.675 0.000 0.679 0.000 0.683 0.046 0.689 0.000 0.722 0.000 0.727 0.084 0.736 0.312 0.741 0.365 0.747 0.314 0.756 0.000 0.819 0.000 0.830 0.086 0.838 0.369 0.845 0.411 0.854 0.365 0.861 0.000 0.864 0.092 0.869 0.081 0.873 0.200 0.881 0.336 0.889 0.374 0.901 0.033 0.908 0.000 0.913 0.066 0.929 0.310 0.936 0.266 0.940 0.079 0.948 0.000 0.967 0.044 0.973 0.101 1.000 0.000) :duration dur :scaler amp)) (gen1 (make-polywave 0.0 '(1 .98 2 .02 4 .01))) (frqf (make-env '(0.000 0.317 0.013 0.368 0.029 0.464 0.048 0.485 0.062 0.469 0.100 0.310 0.176 0.320 0.224 0.389 0.242 0.395 0.270 0.370 0.280 0.492 0.284 0.304 0.292 0.363 0.305 0.411 0.322 0.464 0.347 0.306 0.376 0.269 0.386 0.368 0.396 0.398 0.407 0.366 0.415 0.290 0.485 0.288 0.520 0.405 0.536 0.315 0.690 0.313 0.728 0.267 0.733 0.350 0.743 0.375 0.756 0.345 0.759 0.281 0.827 0.285 0.834 0.349 0.850 0.375 0.868 0.312 0.878 0.358 0.886 0.375 0.897 0.352 0.910 0.297 0.923 0.342 0.932 0.361 0.942 0.342 0.960 0.283 0.968 0.327 0.978 0.350 0.989 0.335 1.000 0.290) :duration dur :scaler (hz->radians 6070.0)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) ;; (with-sound (:play #t) (ash-throated-flycatcher 0 .25)) ;;; -------------------------------------------------------------------------------- ;;; ;;; White-header woodpecker (defanimal (white-headed-woodpecker beg amp) ;; spectrum travels right off the top -- I wonder how high it actually goes (let ((dur 0.16)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.053 0.952 0.066 0.865 0.079 0.386 0.091 0.937 0.145 0.963 0.182 0.923 0.197 0.384 0.221 0.892 0.256 0.751 0.298 0.000 0.410 0.000 0.430 0.915 0.450 0.836 0.464 0.307 0.479 0.873 0.496 0.952 0.531 0.886 0.554 0.291 0.575 0.892 0.606 0.717 0.654 0.000 0.775 0.000 0.801 0.712 0.814 0.233 0.822 0.712 0.893 0.712 0.923 0.225 0.938 0.758 0.959 0.640 1.000 0.000 ) :duration dur :scaler amp)) (frqf1 (make-env '(0.000 0.106 0.051 0.119 0.063 0.177 0.087 0.230 0.198 0.228 0.211 0.175 0.236 0.153 0.282 0.122 0.427 0.103 0.465 0.156 0.483 0.214 0.542 0.220 0.563 0.159 0.588 0.146 0.615 0.095 0.767 0.122 0.8 0.2 0.851 0.2 0.871 0.16 0.903 0.148 0.939 0.143 .95 .14) :duration dur :scaler (hz->radians (/ 22050.0 3.0)))) (frqf2 (make-env '(0.000 0.230 0.061 0.262 0.088 0.341 0.152 0.323 0.206 0.341 0.219 0.265 0.237 0.235 0.450 0.220 0.459 0.317 0.514 0.302 0.558 0.354 0.605 0.246 0.772 0.246 0.838 0.323 0.857 0.278 0.864 0.325 0.914 0.222 .95 .22) :duration dur :scaler (hz->radians (/ 22050.0 5.0)))) (gen1 (make-polywave 0.0 (list 1 (* .8 .01) 2 (* .8 .1) 3 (* .8 .6) 4 (* .8 .02) 6 (* .8 .4) 7 (* .8 .05) 9 (* .8 .1) 10 (* .8 .1) 12 (* .8 .01)))) (gen2 (make-polywave 0.0 (list 5 (* .2 .9) 8 (* .2 .3) 11 (* .2 .1)))) (rnd (make-sawtooth-wave 700 .01)) (rndf (make-env '(0 0 .01 1 .08 .02 .25 .02 .3 1 .45 1 .47 .03 .64 .01 .65 1 .75 1 .77 .05 .92 .01 1 1) :duration dur))) (do ((i start (+ i 1))) ((= i stop)) (let ((noise (* (env rndf) (sawtooth-wave rnd)))) (outa i (* (env ampf) (+ (polywave gen1 (+ (env frqf1) noise)) (polywave gen2 (+ (env frqf2) (* 10.0 noise))))))))))) ;; (with-sound (:play #t) (white-headed-woodpecker 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Phainopepla (defanimal (phainopepla beg amp) (let ((dur 0.26)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.063 0.073 0.119 0.181 0.142 0.290 0.178 0.617 0.192 0.525 0.236 0.288 0.255 0.000 0.272 0.557 0.285 0.178 0.296 0.095 0.393 0.088 0.501 0.000 0.522 0.108 0.538 0.634 0.647 0.000 0.663 0.000 0.681 0.484 0.704 0.211 0.777 0.643 0.850 0.961 0.880 0.998 0.899 0.974 0.958 0.277 1.000 0.000) :duration dur :scaler amp)) (gen1 (make-polywave 0.0 '(1 .9 2 .1 3 .01))) (frqf (make-env '(0.000 0.203 0.061 0.309 0.259 0.317 0.276 0.533 0.300 0.720 0.329 0.739 0.373 0.697 0.450 0.792 0.496 0.836 0.516 0.794 0.525 0.689 0.532 0.417 0.550 0.351 0.573 0.314 0.607 0.296 0.624 0.351 0.629 0.435 0.652 0.425 0.660 0.219 0.698 0.398 0.726 0.441 0.839 0.433 1.000 0.427) :duration dur :scaler (hz->radians 8040.0)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) ;; (with-sound (:play #t) (phainopepla 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Golden-crowned sparrow (defanimal (golden-crowned-sparrow beg amp) (let ((dur 2.13)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.079 0.343 0.188 0.391 0.301 0.504 0.343 0.963 0.379 0.887 0.388 0.000 0.459 0.000 0.474 0.480 0.494 0.549 0.595 0.984 0.637 1.000 0.688 0.720 0.701 0.000 0.770 0.000 0.795 0.311 0.863 0.420 0.916 0.383 0.985 0.272 1.000 0.000) :duration dur :scaler amp)) (gen1 (make-polywave 0.0 '(1 .9 2 .01 3 .1))) (frqf (make-env '(0.000 0.814 0.028 0.730 0.064 0.690 0.122 0.549 0.156 0.551 0.178 0.573 0.207 0.544 0.272 0.556 0.296 0.580 0.320 0.549 0.343 0.501 0.377 0.468 0.452 0.446 0.467 0.475 0.488 0.470 0.523 0.477 0.529 0.561 0.535 0.480 0.572 0.473 0.589 0.494 0.612 0.477 0.655 0.456 0.672 0.482 0.691 0.463 0.767 0.413 0.819 0.394 0.861 0.396 0.865 0.449 0.873 0.408 0.894 0.401 0.930 0.401 0.975 0.396 1.000 0.329 ) :duration dur :scaler (hz->radians 8040.0))) (vib (make-rand-interp 50 (hz->radians 80)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (+ (env frqf) (rand-interp vib))))))))) ;; (with-sound (:play #t) (golden-crowned-sparrow 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; House finch (defanimal (house-finch beg amp) (let ((dur 3.16)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.014 0.128 0.021 0.000 0.052 0.000 0.058 0.146 0.062 0.314 0.068 0.301 0.073 0.000 0.097 0.000 0.101 0.296 0.104 0.151 0.106 0.447 0.114 0.459 0.119 0.143 0.125 0.000 0.151 0.000 0.162 0.415 0.180 0.375 0.188 0.000 0.209 0.000 0.212 0.353 0.214 0.175 0.217 0.442 0.222 0.153 0.225 0.528 0.232 0.002 0.246 0.000 0.247 0.109 0.258 0.030 0.259 0.294 0.263 0.180 0.267 0.333 0.271 0.000 0.290 0.000 0.295 0.128 0.298 0.388 0.303 0.000 0.313 0.857 0.322 0.000 0.346 0.000 0.358 0.990 0.359 0.528 0.361 0.778 0.370 0.000 0.384 0.000 0.390 0.504 0.395 0.227 0.399 0.328 0.409 0.000 0.420 0.993 0.425 0.402 0.433 0.000 0.444 0.000 0.449 0.380 0.455 0.978 0.461 0.000 0.472 0.000 0.480 0.477 0.487 0.000 0.492 0.558 0.500 0.430 0.506 0.000 0.516 0.000 0.525 0.844 0.533 0.104 0.537 0.072 0.541 0.538 0.550 0.067 0.557 0.067 0.559 0.232 0.564 0.528 0.567 0.064 0.573 0.901 0.579 0.084 0.582 0.551 0.587 0.430 0.593 0.000 0.606 0.000 0.611 0.257 0.618 0.000 0.625 0.079 0.629 0.516 0.636 0.642 0.639 0.489 0.643 0.104 0.653 0.000 0.672 0.000 0.680 0.736 0.694 0.696 0.701 0.121 0.707 0.057 0.713 0.558 0.722 0.000 0.752 0.000 0.757 0.723 0.774 0.546 0.782 0.116 0.794 0.207 0.801 0.499 0.818 0.689 0.833 0.388 0.847 0.000 0.859 0.000 0.863 0.123 0.867 0.726 0.872 0.000 0.878 0.116 0.879 0.385 0.885 0.669 0.944 0.835 0.989 0.328 0.995 0.035 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.0000 0.3997 0.0085 0.4810 0.0103 0.3943 0.0166 0.4228 0.0573 0.4268 0.0605 0.4932 0.0663 0.4160 0.0708 0.4363 0.0985 0.4228 0.1008 0.2846 0.1066 0.4228 0.1146 0.3089 0.1187 0.3238 0.1339 0.3225 0.1487 0.4864 0.1617 0.4607 0.1769 0.4512 0.1818 0.3740 0.1948 0.3794 0.2100 0.4214 0.2114 0.2859 0.2172 0.4350 0.2248 0.3157 0.2293 0.3320 0.2427 0.5054 0.2512 0.4214 0.2557 0.3374 0.2584 0.4648 0.2620 0.5434 0.2665 0.3835 0.2888 0.4119 0.2942 0.3794 0.3014 0.5813 0.3032 0.3130 0.3081 0.4892 0.3144 0.3266 0.3193 0.3388 0.3395 0.4065 0.3462 0.4824 0.3542 0.4458 0.3605 0.3333 0.3645 0.3144 0.3820 0.2927 0.3842 0.2751 0.3887 0.3360 0.3932 0.4173 0.4017 0.5705 0.4035 0.4607 0.4107 0.3862 0.4187 0.3360 0.4263 0.2737 0.4438 0.3062 0.4456 0.3686 0.4478 0.4228 0.4541 0.3266 0.4635 0.3225 0.4720 0.2317 0.4765 0.3225 0.4814 0.3726 0.4828 0.4702 0.4877 0.4363 0.4913 0.3672 0.4922 0.3130 0.4993 0.2846 0.5204 0.3496 0.5280 0.2913 0.5311 0.2195 0.5361 0.4241 0.5428 0.3089 0.5567 0.2913 0.5584 0.4295 0.5625 0.3198 0.5665 0.5000 0.5723 0.4065 0.5808 0.3225 0.5902 0.2060 0.6064 0.2642 0.6117 0.3374 0.6122 0.2195 0.6189 0.1789 0.6296 0.3591 0.6444 0.1599 0.6458 0.4160 0.6771 0.4201 0.6950 0.4214 0.7026 0.2778 0.7112 0.2764 0.7228 0.1897 0.7394 0.4092 0.7546 0.4160 0.7721 0.4187 0.7895 0.3198 0.8343 0.3184 0.8616 0.2344 0.8634 0.3808 0.8697 0.2276 0.8804 0.3279 0.9149 0.3835 0.9472 0.4688 1.0000 0.8306) :duration dur :scaler (hz->radians 9130.0))) (gen1 (make-polywave 0.0 '(1 .98 2 .01 3 .01))) (gen2 (make-polywave 0.0 '(1 .98 2 .005))) (buzz (make-oscil 0)) (buzzsweep (make-nrxysin :n 5 :r .5)) (bsweep (hz->radians 500)) (buzzf (make-env '(0 0 .14 0 .15 1 .19 1 .20 0 .66 0 .67 1 1 1) :duration dur)) (buzzf-1 (make-env '(0 0 .14 0 .15 1 .19 1 .20 0 .66 0 .67 1 1 1) :duration dur :offset 1.0 :scaler -1.0)) (buzzfrqf (make-env '(0 110 .5 110 .6 70 .85 70 .86 130 1 130) :duration dur :scaler (hz->radians 1.0))) (rnd (make-rand-interp 400 (hz->radians 100)))) (do ((i start (+ i 1))) ((= i stop)) (let ((frq (env frqf)) (bfrq (env buzzfrqf))) (outa i (* (env ampf) (+ (* (env buzzf-1) (polywave gen1 frq)) (* (env buzzf) (+ .1 (* .9 (abs (oscil buzz bfrq)))) (polywave gen2 (+ frq (* bsweep (nrxysin buzzsweep bfrq)) (rand-interp rnd)))))))))))) ;; (with-sound (:play #t) (house-finch 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Ruby-crowned kinglet (defanimal (ruby-crowned-kinglet beg amp) (let ((dur 2.17)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.017 0.053 0.025 0.000 0.034 0.000 0.044 0.088 0.053 0.076 0.057 0.000 0.112 0.000 0.133 0.298 0.151 0.060 0.167 0.158 0.179 0.000 0.214 0.000 0.232 0.496 0.247 0.100 0.265 0.745 0.275 0.000 0.310 0.000 0.318 0.601 0.326 0.714 0.344 0.169 0.361 0.334 0.372 0.000 0.401 0.000 0.417 1.000 0.433 0.115 0.450 0.979 0.459 0.000 0.496 0.000 0.506 0.745 0.516 0.778 0.526 0.322 0.537 0.236 0.546 0.258 0.553 0.212 0.559 0.000 0.599 0.000 0.613 0.967 0.631 0.189 0.647 0.933 0.656 0.000 0.697 0.000 0.706 0.726 0.714 0.589 0.719 0.714 0.729 0.236 0.737 0.160 0.743 0.241 0.754 0.198 0.761 0.000 0.808 0.000 0.826 0.752 0.839 0.098 0.856 0.599 0.862 0.558 0.868 0.000 0.921 0.000 0.932 0.470 0.941 0.511 0.951 0.179 0.976 0.229 0.980 0.057 1.000 0.000) :duration dur :scaler amp)) (gen1 (make-polywave 0.0 '(1 .98 2 .01 3 .004))) (frqf (make-env '(0.000 0.671 0.017 0.698 0.026 0.786 0.031 0.785 0.032 0.556 0.039 0.556 0.053 0.646 0.059 0.591 0.119 0.476 0.146 0.284 0.193 0.269 0.216 0.549 0.225 0.464 0.238 0.564 0.244 0.477 0.250 0.411 0.262 0.411 0.268 0.442 0.274 0.414 0.316 0.446 0.337 0.289 0.363 0.285 0.368 0.267 0.391 0.287 0.404 0.523 0.410 0.481 0.423 0.553 0.432 0.426 0.441 0.401 0.452 0.441 0.458 0.396 0.502 0.444 0.528 0.285 0.550 0.285 0.557 0.259 0.572 0.260 0.594 0.513 0.607 0.482 0.618 0.568 0.626 0.529 0.629 0.451 0.642 0.429 0.650 0.462 0.653 0.427 0.703 0.442 0.729 0.282 0.750 0.285 0.756 0.259 0.778 0.259 0.793 0.616 0.806 0.588 0.813 0.481 0.825 0.571 0.841 0.444 0.851 0.416 0.860 0.442 0.923 0.444 0.952 0.279 1.000 0.275) :duration dur :scaler (hz->radians 9060.0)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) ;; (with-sound (:play #t) (ruby-crowned-kinglet 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Green-tailed towhee ;;; ;;; not very elegant, but a real test of the envelope editor (defanimal (green-tailed-towhee beg amp) (let ((dur 1.86)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.010 0.168 0.013 0.000 0.018 0.000 0.021 0.200 0.027 0.255 0.033 0.119 0.039 0.000 0.141 0.000 0.149 0.104 0.159 0.586 0.163 0.438 0.166 0.586 0.168 0.374 0.171 0.519 0.173 0.429 0.176 0.487 0.179 0.284 0.180 0.554 0.184 0.261 0.186 0.539 0.189 0.270 0.190 0.530 0.194 0.243 0.197 0.449 0.200 0.272 0.202 0.443 0.205 0.243 0.207 0.377 0.218 0.200 0.222 0.000 0.277 0.000 0.286 0.122 0.289 0.417 0.292 0.055 0.296 0.417 0.299 0.490 0.303 0.058 0.307 0.336 0.309 0.000 0.323 0.093 0.327 0.658 0.330 0.087 0.335 0.530 0.341 0.000 0.343 0.438 0.346 0.000 0.356 0.061 0.362 0.232 0.365 0.872 0.368 0.145 0.372 0.655 0.378 0.061 0.381 0.542 0.383 0.000 0.392 0.000 0.397 0.159 0.403 0.739 0.406 0.081 0.411 0.600 0.416 0.000 0.420 0.452 0.422 0.000 0.432 0.078 0.437 0.235 0.441 0.788 0.445 0.078 0.450 0.614 0.454 0.078 0.459 0.357 0.460 0.000 0.470 0.081 0.476 0.281 0.479 0.733 0.485 0.070 0.489 0.588 0.493 0.000 0.498 0.194 0.500 0.000 0.533 0.000 0.535 0.374 0.538 0.090 0.550 1.000 0.557 0.991 0.572 0.078 0.577 0.145 0.583 0.354 0.612 0.000 0.646 0.000 0.663 0.588 0.671 0.583 0.686 0.081 0.701 0.591 0.706 0.577 0.721 0.000 0.759 0.000 0.763 0.420 0.765 0.084 0.768 0.191 0.772 0.136 0.775 0.000 0.778 0.464 0.780 0.119 0.783 0.212 0.788 0.154 0.790 0.003 0.794 0.571 0.796 0.136 0.799 0.241 0.803 0.165 0.807 0.009 0.810 0.710 0.812 0.125 0.814 0.275 0.819 0.174 0.822 0.017 0.824 0.536 0.828 0.136 0.831 0.272 0.835 0.186 0.837 0.006 0.841 0.684 0.844 0.142 0.846 0.345 0.855 0.006 0.856 0.617 0.860 0.130 0.862 0.287 0.870 0.006 0.873 0.606 0.876 0.142 0.879 0.290 0.883 0.154 0.885 0.009 0.889 0.623 0.892 0.139 0.893 0.281 0.903 0.023 0.904 0.600 0.908 0.130 0.911 0.241 0.918 0.006 0.921 0.580 0.924 0.110 0.926 0.209 0.934 0.009 0.938 0.455 0.940 0.090 0.943 0.159 0.951 0.003 0.955 0.391 0.956 0.093 0.959 0.136 0.967 0.012 0.970 0.386 0.974 0.116 0.983 0.012 0.987 0.333 0.990 0.049 1.000 0.000) :duration dur :scaler amp)) (gen1 (make-oscil)) (frqf (make-env '(0.0000 0.3575 0.0067 0.4860 0.0110 0.5475 0.0119 0.3203 0.0181 0.3911 0.0219 0.5438 0.0229 0.3389 0.0267 0.4860 0.0300 0.3948 0.0334 0.3259 0.1411 0.3315 0.1478 0.4953 0.1554 0.4413 0.1635 0.3296 0.1640 0.4376 0.1697 0.3315 0.1698 0.4302 0.1755 0.3389 0.1759 0.4153 0.1797 0.3296 0.1821 0.4358 0.1859 0.3240 0.1864 0.4078 0.1892 0.3575 0.1907 0.4358 0.1959 0.3240 0.1964 0.4134 0.2031 0.3128 0.2032 0.4376 0.2078 0.3035 0.2126 0.3166 0.2127 0.4246 0.2183 0.3464 0.2194 0.4320 0.2216 0.3669 0.2698 0.3892 0.2827 0.7318 0.2898 0.5214 0.2941 0.3054 0.2979 0.5978 0.3046 0.3091 0.3207 0.7745 0.3241 0.6685 0.3322 0.2868 0.3346 0.5512 0.3394 0.2626 0.3547 0.8209 0.3608 0.6462 0.3689 0.2756 0.3723 0.5196 0.3785 0.2868 0.3918 0.8425 0.3999 0.6331 0.4066 0.3110 0.4109 0.5568 0.4175 0.3147 0.4280 0.8541 0.4337 0.7263 0.4409 0.5531 0.4447 0.2961 0.4485 0.6555 0.4561 0.2607 0.4682 0.8375 0.4743 0.6853 0.4790 0.5661 0.4833 0.3315 0.4871 0.6089 0.4933 0.3315 0.4976 0.6462 0.5353 0.4860 0.5362 0.6872 0.5377 0.2849 0.5405 0.4488 0.5458 0.4860 0.5567 0.4600 0.5648 0.3464 0.5758 0.2458 0.5877 0.3240 0.6025 0.2495 0.6482 0.3222 0.6568 0.4860 0.6754 0.4618 0.6888 0.4823 0.6892 0.2775 0.7021 0.3315 0.7188 0.2682 0.7541 0.2793 0.7610 0.6542 0.7649 0.2737 0.7650 0.6574 0.7717 0.4097 0.7769 0.6499 0.7798 0.3222 0.7822 0.5791 0.7879 0.3743 0.7927 0.6480 0.7939 0.3003 0.7974 0.6034 0.8022 0.3799 0.8065 0.6518 0.8117 0.2961 0.8136 0.6425 0.8184 0.4041 0.8241 0.6499 0.8255 0.2896 0.8282 0.6167 0.8341 0.4004 0.8379 0.6610 0.8442 0.2857 0.8451 0.6145 0.8506 0.3969 0.8537 0.6491 0.8585 0.3066 0.8600 0.6269 0.8652 0.3816 0.8700 0.6422 0.8755 0.2760 0.8756 0.6238 0.8831 0.3697 0.8870 0.6499 0.8919 0.2794 0.8923 0.6145 0.8985 0.3526 0.9021 0.6405 0.9066 0.3408 0.9075 0.3066 0.9080 0.6071 0.9145 0.3748 0.9175 0.6388 0.9238 0.3135 0.9249 0.6065 0.9306 0.3714 0.9351 0.6303 0.9390 0.2998 0.9404 0.5791 0.9442 0.3855 0.9514 0.6294 0.9542 0.3575 0.9571 0.5791 0.9628 0.3724 0.9670 0.6235 0.9720 0.3152 0.9747 0.5680 0.9795 0.3594 0.9858 0.5963 0.9900 0.3520 1.0000 0.2777) :duration dur :scaler (hz->radians 10030.0)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (oscil gen1 (env frqf)))))))) ;; (with-sound (:play #t) (green-tailed-towhee 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Lucy's warbler (defanimal (lucys-warbler beg amp) (let ((dur 1.72)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.019 0.093 0.038 0.000 0.057 0.000 0.066 0.170 0.073 0.132 0.081 0.168 0.091 0.000 0.116 0.000 0.125 0.269 0.132 0.211 0.137 0.280 0.149 0.000 0.174 0.000 0.185 0.384 0.191 0.261 0.196 0.461 0.209 0.000 0.233 0.000 0.239 0.416 0.245 0.474 0.248 0.284 0.254 0.543 0.259 0.405 0.267 0.000 0.287 0.000 0.295 0.659 0.301 0.507 0.308 0.655 0.320 0.000 0.343 0.000 0.355 0.881 0.358 0.629 0.365 0.761 0.377 0.000 0.396 0.000 0.408 0.965 0.424 0.573 0.431 0.000 0.450 0.000 0.459 0.983 0.471 0.466 0.477 0.000 0.494 0.000 0.503 0.853 0.516 0.442 0.520 0.000 0.536 0.000 0.549 0.853 0.567 0.000 0.581 0.000 0.596 0.981 0.614 0.000 0.628 0.000 0.634 0.813 0.640 0.425 0.642 0.860 0.653 0.422 0.657 0.000 0.678 0.000 0.682 0.757 0.686 0.364 0.688 0.875 0.704 0.000 0.720 0.000 0.727 0.761 0.731 0.440 0.733 0.875 0.743 0.461 0.750 0.000 0.768 0.000 0.773 0.993 0.781 0.601 0.785 0.918 0.798 0.000 0.816 0.000 0.823 0.877 0.827 0.535 0.830 0.877 0.855 0.000 0.879 0.000 0.885 0.638 0.889 0.741 0.919 0.000 0.945 0.000 0.950 0.556 0.955 0.379 0.959 0.563 0.986 0.037 1.000 0.000) :duration dur :scaler amp)) (gen1 (make-polywave 0.0 '(1 .98 2 .015 3 .005))) (frqf (make-env '(0.000 0.651 0.018 0.637 0.040 0.401 0.049 0.361 0.055 0.658 0.072 0.644 0.087 0.526 0.098 0.358 0.106 0.340 0.110 0.677 0.130 0.665 0.136 0.595 0.146 0.509 0.155 0.361 0.161 0.342 0.175 0.628 0.191 0.602 0.202 0.536 0.212 0.394 0.219 0.361 0.229 0.648 0.244 0.623 0.254 0.590 0.263 0.500 0.271 0.382 0.278 0.354 0.285 0.627 0.302 0.611 0.315 0.536 0.322 0.391 0.328 0.356 0.333 0.661 0.357 0.644 0.369 0.547 0.379 0.387 0.390 0.363 0.396 0.630 0.415 0.613 0.425 0.543 0.432 0.394 0.442 0.351 0.449 0.724 0.462 0.708 0.474 0.538 0.475 0.418 0.488 0.365 0.491 0.774 0.502 0.743 0.513 0.613 0.519 0.438 0.528 0.389 0.533 0.821 0.544 0.800 0.551 0.688 0.562 0.526 0.565 0.387 0.577 0.354 0.579 0.807 0.588 0.795 0.597 0.701 0.606 0.595 0.612 0.384 0.621 0.339 0.624 0.797 0.634 0.773 0.648 0.627 0.657 0.385 0.663 0.333 0.664 0.809 0.678 0.799 0.686 0.696 0.695 0.575 0.701 0.389 0.709 0.345 0.714 0.825 0.724 0.797 0.736 0.630 0.746 0.432 0.748 0.373 0.759 0.325 0.760 0.813 0.770 0.780 0.785 0.623 0.789 0.507 0.793 0.405 0.802 0.342 0.803 0.837 0.818 0.795 0.829 0.630 0.836 0.535 0.854 0.372 0.864 0.309 0.868 0.826 0.878 0.802 0.884 0.727 0.888 0.618 0.915 0.373 0.930 0.314 0.931 0.819 0.944 0.792 0.951 0.670 0.963 0.563 0.977 0.448 0.981 0.387 1.000 0.318) :duration dur :scaler (hz->radians 8070.0)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) ;; (with-sound (:play #t) (lucys-warbler 0 .25)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Cassin's vireo (defanimal (cassins-vireo beg amp) (let ((dur 0.5)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.028 0.110 0.037 0.062 0.050 0.098 0.060 0.075 0.078 0.179 0.085 0.065 0.093 0.116 0.100 0.379 0.119 0.163 0.136 0.457 0.147 0.473 0.159 0.180 0.173 0.608 0.182 0.655 0.193 0.001 0.200 0.292 0.210 0.180 0.219 0.262 0.224 0.103 0.241 0.204 0.253 0.055 0.268 0.225 0.285 0.061 0.299 0.251 0.312 0.171 0.330 0.298 0.366 0.182 0.375 0.138 0.384 0.159 0.391 0.000 0.512 0.000 0.527 0.085 0.539 0.267 0.553 0.111 0.565 0.200 0.574 0.150 0.583 0.360 0.587 0.117 0.595 0.257 0.602 0.096 0.610 0.297 0.623 0.072 0.635 0.241 0.640 0.201 0.653 0.336 0.669 0.996 0.679 0.730 0.689 0.235 0.702 0.336 0.714 0.688 0.725 0.752 0.733 0.466 0.744 0.680 0.752 0.070 0.763 0.628 0.766 0.567 0.774 0.671 0.786 0.094 0.792 0.514 0.797 0.099 0.800 0.187 0.807 0.224 0.810 0.523 0.820 0.444 0.824 0.155 0.829 0.481 0.832 0.598 0.838 0.521 0.843 0.070 0.847 0.209 0.857 0.476 0.862 0.294 0.873 0.775 0.880 0.175 0.884 0.495 0.888 0.083 0.896 0.644 0.916 0.074 0.919 0.379 0.926 0.072 0.940 0.657 0.944 0.613 0.955 0.070 0.960 0.181 0.966 0.087 0.970 0.111 0.975 0.069 0.981 0.173 0.989 0.021 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.069 0.028 0.063 0.060 0.075 0.078 0.110 0.100 0.144 0.121 0.159 0.141 0.162 0.160 0.154 0.188 0.130 0.206 0.119 0.216 0.120 0.225 0.100 0.239 0.119 0.254 0.093 0.265 0.117 0.281 0.094 0.298 0.120 0.325 0.129 0.356 0.133 0.382 0.128 0.395 0.100 0.516 0.090 0.568 0.108 0.600 0.075 0.621 0.150 0.639 0.183 0.662 0.178 0.682 0.159 0.703 0.155 0.721 0.139 0.735 0.157 0.753 0.123 0.769 0.148 0.784 0.124 0.795 0.159 0.816 0.139 0.831 0.172 0.845 0.148 0.857 0.180 0.872 0.178 0.881 0.159 0.892 0.198 0.908 0.178 0.922 0.206 0.942 0.194 0.957 0.212 0.982 0.199 1.000 0.179) :duration dur :scaler (hz->radians 22050.0))) (gen1 (make-oscil)) (gen2 (make-oscil)) (gen3 (make-oscil)) (gen4 (make-oscil)) (gen5 (make-oscil)) (f1 (make-env '(0 .01 .06 .01 .1 1 .3 1 .5 .01 .65 .05 .67 1 1 1) :duration dur)) (f2 (make-env '(0 .25 .06 .5 .1 .01 .3 .01 .5 .75 .6 .5 .64 .01 1 .01) :duration dur)) (f3 (make-env '(0 1 .06 .5 .1 .01 .3 .01 .5 .01 .6 .3 .65 .01 .67 .01 1 .01) :duration dur))) (do ((i start (+ i 1))) ((= i stop)) (let ((frq (env frqf))) (outa i (* (env ampf) (+ (* (env f1) (oscil gen1 frq)) (* (env f2) (oscil gen2 (* 2.0 frq))) (+ (* (env f3) (oscil gen3 (* 3.0 frq))) (* .005 (oscil gen4 (* 4.0 frq))) (* .005 (oscil gen5 (* 5.0 frq)))))))))))) ;;; formants sounded bad here, polywave worse ;; (with-sound (:play #t) (cassins-vireo 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Plain chacalaca ;;; ;;; the recording doesn't do this bird justice -- it actually does say "chacalaca" ;;; (and the mosquitos darken the skies) (define (plain-chacalaca beg1 amp) (defanimal (plain-chacalaca-1 beg dur amp frmfrq frqlst) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 2 1 4 1 6 0) :duration dur :scaler (* 0.5 amp))) (frqf (make-env frqlst :duration dur :scaler (hz->radians 1.0))) (frm1 (make-formant frmfrq .99)) (frm2 (make-formant 4200 .98)) (frm3 (make-formant 2800 .98)) (fr1 (* 2 20 (sin (hz->radians frmfrq)))) (fr2 (* 2 (sin (hz->radians 4200)))) (fr3 (* 2 8 (sin (hz->radians 2800)))) (gen (make-polywave 0.0 (nrcos->polywave 15 .75 1.0))) (rnd (make-rand-interp 5000 .03)) (rnd1 (make-rand-interp 1000 .15)) (vib (make-blackman 50 4)) (vib-index (hz->radians -100))) (let ((fb (vector frm1 frm2 frm3)) (fs (float-vector fr1 fr2 fr3))) (set! fb (make-formant-bank fb fs)) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (formant-bank fb (* (+ .85 (abs (rand-interp rnd1))) (polywave gen (+ (env frqf) (rand-interp rnd) (* vib-index (blackman vib)))))))))))) (plain-chacalaca-1 beg1 0.17 (* .7 amp) 1700 '(0 450 1 680)) (plain-chacalaca-1 (+ beg1 0.20) 0.12 amp 1400 '(0 500 1 680 2 660)) (plain-chacalaca-1 (+ beg1 0.35) 0.20 amp 1400 '(0 500 1 680 4 660))) ;; (with-sound (:play #t) (plain-chacalaca 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Black-billed cuckoo (defanimal (black-billed-cuckoo beg amp) (let ((dur 0.68)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.013 0.388 0.023 0.303 0.026 0.419 0.042 0.530 0.066 0.104 0.128 0.000 0.215 0.000 0.243 0.642 0.257 0.536 0.266 0.725 0.296 0.737 0.311 0.044 0.357 0.070 0.367 0.000 0.421 0.000 0.448 0.856 0.460 0.807 0.468 0.913 0.483 0.960 0.515 0.928 0.535 0.048 0.575 0.085 0.584 0.000 0.638 0.000 0.658 0.903 0.674 0.989 0.708 0.822 0.732 0.079 0.781 0.038 0.798 0.070 0.806 0.028 0.823 0.059 0.845 0.000 0.883 0.000 0.892 0.593 0.913 0.739 0.940 0.031 0.976 0.066 1.000 0.000) :duration dur :scaler amp)) (gen1 (make-polywave 0.0 '(1 .97 2 .005 3 .008 5 .005))) (rnd (make-rand-interp 400 (hz->radians 25))) (frqf (make-env '(0.000 0.568 0.057 0.568 0.078 0.399 0.203 0.315 0.218 0.632 0.252 0.557 0.314 0.553 0.340 0.350 0.410 0.337 0.426 0.667 0.469 0.557 0.528 0.559 0.548 0.381 0.616 0.352 0.624 0.617 0.659 0.544 0.721 0.544 0.748 0.350 0.840 0.297 0.851 0.615 0.889 0.540 0.926 0.542 0.948 0.416 1.000 0.419) :duration dur :scaler (hz->radians 1190.0)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (+ (env frqf) (rand-interp rnd))))))))) ;; (with-sound (:play #t) (black-billed-cuckoo 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Eared grebe (defanimal (eared-grebe beg amp) ;; note #1 (let ((dur 0.3)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0 0 9 1 10 0) :duration dur :scaler amp)) (frqf (make-env '(0 1050 1 1400) :duration dur :scaler (hz->radians 1.0))) (gen1 (make-oscil)) (gen2 (make-oscil)) (gen3 (make-oscil)) (gen4 (make-oscil)) (gen5 (make-oscil)) (f1 (make-env '(0 .03 9 .144 10 .1) :duration dur)) (f2 (make-env '(0 .5 9 .844 10 .2) :duration dur)) (f3 (make-env '(0 .01 9 .03 10 .02) :duration dur)) (f4 (make-env '(0 0 1 .002 7 .003 10 0) :duration dur))) (do ((i start (+ i 1))) ((= i stop)) (let ((frq (env frqf))) (outa i (* (env ampf) (+ (* (env f1) (oscil gen1 frq)) (* (env f2) (oscil gen2 (* 2.0 frq))) (+ (* (env f3) (oscil gen3 (* 3.0 frq))) (* (env f4) (oscil gen4 (* 4.0 frq))) (* .005 (oscil gen5 (* 5.0 frq))))))))))) ;; note #2 (let ((dur 0.085) (start (seconds->samples (+ beg 0.29)))) (let ((stop (+ start (seconds->samples dur))) (ampf (make-env '(0 0 1 1 2 .5 2.9 1 3 0) :duration dur :scaler amp)) (frqf (make-env '(0 2280 .25 2320 .6 2440 .65 3240 .8 3470 1 3260) :duration dur :scaler (hz->radians 1.0))) (gen1 (make-oscil)) (gen2 (make-oscil)) (f1 (make-env '(0 .5 .6 1 .62 .05 .65 .5 1 .5) :duration dur))) (do ((i start (+ i 1))) ((= i stop)) (let ((frq (env frqf))) (outa i (* (env ampf) (+ (* (env f1) (oscil gen1 frq)) (* .01 (oscil gen2 (* 2.0 frq)))))))))) ;; note #3 (let ((dur 0.02) (start (seconds->samples (+ beg 0.446)))) (let ((stop (+ start (seconds->samples dur))) (ampf (make-env '(0 0 1 1 2.5 0) :duration dur :scaler (* .5 amp))) (frqf1 (make-env '(0 1120 .5 1540 1 1100) :duration dur :scaler (hz->radians 1.0))) (frqf2 (make-env '(0 2400 .5 2520 1 2300) :duration dur :scaler (hz->radians 1.0))) (gen1 (make-oscil)) (gen2 (make-oscil)) (gen3 (make-oscil)) (gen4 (make-oscil)) (f1 (make-env '(0 .9 .2 1 .6 1 .8 0 1 0) :duration dur)) (f2 (make-env '(0 .5 .2 1 .6 .01 1 0) :duration dur)) (f3 (make-env '(0 .1 .2 0 1 0) :duration dur)) (f4 (make-env '(0 0 .2 0 .7 .25 1 .1) :duration dur)) (rnd (make-rand-interp 3000 (hz->radians 100)))) (do ((i start (+ i 1))) ((= i stop)) (let ((frq1 (+ (env frqf1) (rand-interp rnd)))) (outa i (* (env ampf) (+ (* (env f1) (oscil gen1 (* 2.0 frq1))) (* (env f2) (oscil gen2 frq1)) (* (env f3) (oscil gen3 (* 3.0 frq1))) (* (env f4) (oscil gen4 (env frqf2))))))))))) ;; (with-sound (:play #t :statistics #t) (eared-grebe 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Brown jay (defanimal (brown-jay beg amp) (let ((dur 0.26)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.012 0.106 0.044 0.151 0.072 0.267 0.129 0.766 0.221 0.889 0.372 1.000 0.455 0.837 0.534 0.553 0.632 0.660 0.762 0.540 0.912 0.105 1.000 0.000) :duration dur :scaler amp)) (gen1 (make-polywave 0.0 '(1 .1 2 .9 3 .3 4 .07 5 .05 6 .2 7 .01 8 .005 9 .004 10 .003))) (gen2 (make-polywave 0.0 '( 2 .5 3 .1 4 .05))) (intrpf (make-env '(0 1 .5 1 .8 .6 1 0) :duration dur)) (intrpf-1 (make-env '(0 1 .5 1 .8 .6 1 0) :duration dur :offset 1.0 :scaler -1.0)) (frqf (make-env '(0.000 0.201 0.052 0.201 0.091 0.271 0.143 0.285 0.631 0.288 0.659 0.268 0.858 0.257 .93 .2 1.000 0.22) :duration dur :scaler (hz->radians 4060.0))) (rnd (make-rand-interp 500 (hz->radians 15)))) (do ((i start (+ i 1))) ((= i stop)) (let ((frq (+ (env frqf) (rand-interp rnd)))) (outa i (* (env ampf) (+ (* (env intrpf) (polywave gen1 frq)) (* (env intrpf-1) (polywave gen2 frq)))))))))) ;; (with-sound (:play #t) (brown-jay 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Blue grosbeak (defanimal (blue-grosbeak beg amp) (let ((dur 2.26)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.010 0.029 0.019 0.110 0.032 0.024 0.055 0.260 0.058 0.003 0.062 0.034 0.071 0.282 0.078 0.000 0.119 0.000 0.124 0.057 0.129 0.335 0.134 0.410 0.138 0.035 0.143 0.464 0.146 0.430 0.150 0.034 0.156 0.593 0.162 0.513 0.167 0.355 0.172 0.319 0.175 0.000 0.213 0.000 0.222 0.279 0.223 0.099 0.226 0.224 0.228 0.055 0.232 0.087 0.238 0.503 0.249 0.663 0.253 0.025 0.255 0.060 0.256 0.435 0.261 0.468 0.274 0.000 0.315 0.000 0.326 0.426 0.333 0.046 0.342 0.499 0.349 0.658 0.351 0.090 0.355 0.868 0.360 0.677 0.367 0.000 0.390 0.000 0.399 0.673 0.400 0.270 0.403 0.949 0.406 0.934 0.418 0.002 0.429 0.072 0.442 0.240 0.449 0.528 0.455 0.585 0.458 0.533 0.464 0.000 0.484 0.000 0.487 0.323 0.491 0.187 0.495 0.439 0.505 0.683 0.513 0.000 0.526 0.000 0.534 0.784 0.541 0.648 0.545 0.781 0.548 0.160 0.553 0.734 0.569 0.077 0.572 0.097 0.580 0.532 0.583 0.505 0.589 0.000 0.620 0.000 0.627 0.520 0.631 0.543 0.637 0.071 0.641 0.402 0.653 0.846 0.656 0.075 0.662 1.000 0.674 0.000 0.696 0.000 0.702 0.155 0.703 0.361 0.705 0.046 0.710 0.491 0.719 0.133 0.723 0.091 0.730 0.074 0.735 0.110 0.744 0.406 0.753 0.467 0.758 0.053 0.760 0.007 0.765 0.029 0.771 0.481 0.774 0.539 0.781 0.000 0.820 0.000 0.823 0.168 0.825 0.045 0.827 0.005 0.830 0.050 0.831 0.360 0.834 0.047 0.837 0.017 0.843 0.441 0.844 0.086 0.848 0.036 0.854 0.437 0.857 0.085 0.860 0.231 0.864 0.626 0.869 0.136 0.873 0.324 0.880 0.081 0.883 0.344 0.888 0.076 0.890 0.045 0.893 0.235 0.899 0.000 0.932 0.000 0.942 0.091 0.946 0.007 0.951 0.035 0.956 0.104 0.963 0.319 0.970 0.424 0.973 0.065 0.976 0.011 0.977 0.058 0.980 0.244 0.992 0.059 1.000 0.000) :duration dur :scaler amp)) (gen1 (make-polywave 0.0 '(1 .97 2 .03 3 .01 4 .005))) (frqf (make-env '(0.0000 0.5530 0.0090 0.5109 0.0278 0.3367 0.0521 0.5167 0.0589 0.7257 0.0718 0.5675 0.0756 0.4949 0.1252 0.4717 0.1282 0.5501 0.1354 0.3120 0.1418 0.4775 0.1495 0.3222 0.1568 0.4761 0.1649 0.3962 0.1717 0.4557 0.1743 0.3919 0.2174 0.3266 0.2213 0.3904 0.2234 0.5559 0.2268 0.3033 0.2358 0.3861 0.2456 0.4833 0.2499 0.5457 0.2525 0.7083 0.2563 0.5225 0.2597 0.4441 0.2704 0.3367 0.2994 0.3367 0.3093 0.5849 0.3165 0.5835 0.3217 0.4833 0.3268 0.4180 0.3319 0.2917 0.3353 0.4935 0.3396 0.4441 0.3456 0.4688 0.3481 0.5109 0.3520 0.7547 0.3537 0.5602 0.3584 0.5094 0.3635 0.4630 0.3904 0.5167 0.3934 0.7010 0.3947 0.5065 0.3964 0.6546 0.3981 0.4659 0.3998 0.7242 0.4020 0.5007 0.4032 0.6168 0.4041 0.5399 0.4075 0.4833 0.4122 0.3904 0.4186 0.2467 0.4421 0.3759 0.4541 0.4296 0.4724 0.4282 0.4776 0.3077 0.484 0.3091 0.488 0.4146 0.4920 0.3120 0.4964 0.4209 0.5015 0.4601 0.5058 0.4238 0.5088 0.3062 0.5203 0.3048 0.5229 0.6067 0.5284 0.6081 0.5344 0.5138 0.5412 0.4630 0.5451 0.5181 0.5481 0.6923 0.5515 0.5733 0.5540 0.4702 0.5592 0.4078 0.5716 0.3106 0.5805 0.4282 0.6010 0.4282 0.6168 0.3672 0.6215 0.3687 0.6232 0.5704 0.6258 0.4398 0.6314 0.4267 0.6369 0.2903 0.6416 0.4369 0.6489 0.4644 0.6536 0.5327 0.6561 0.7983 0.6587 0.6038 0.6617 0.5472 0.6702 0.4514 0.6822 0.4485 0.6890 0.3425 0.6980 0.3440 0.7031 0.3890 0.7053 0.7286 0.7074 0.5152 0.7172 0.3498 0.7258 0.3048 0.7347 0.3396 0.7428 0.4035 0.7531 0.5007 0.7612 0.7257 0.7800 0.5007 0.8232 0.5936 0.8249 0.7837 0.8300 0.6734 0.8334 0.5646 0.8351 0.7576 0.8394 0.6415 0.8428 0.5094 0.8462 0.7460 0.8484 0.6299 0.8526 0.4586 0.8578 0.6386 0.8620 0.4151 0.8672 0.5631 0.8710 0.3701 0.8770 0.4848 0.8804 0.3527 0.8855 0.4761 0.8902 0.3295 0.8958 0.4964 0.8975 0.2874 0.9381 0.2903 0.9436 0.5036 0.9470 0.2642 0.9680 0.4731 0.9718 0.5559 0.9765 0.7881 0.9795 0.5414 0.9889 0.3657 1.0000 0.3033) :base 10 :duration dur :scaler (hz->radians 7190.0)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) ;; (with-sound (:play #t) (blue-grosbeak 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Acorn woodpecker (defanimal (acorn-woodpecker beg1 amp1) (define (acorn-woodpecker-1 beg dur ampf frqf ampf2 ampf4 rndf) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (gen1 (make-polywave 0.0 '(1 .2 2 1 3 .01 4 .005))) (gen2 (make-polywave 0.0 '(3 .5 5 1 6 .05 7 .1))) (gen3 (make-polywave 0.0 (list 5 (* 2 .005) 6 (* 2 .01) 7 (* 2 .003) 8 (* 2 .005) 9 (* 2 .002) 10 (* 2 .005) 11 (* 2 .001) 13 (* 2 .003) 15 (* 2 .001)))) (gen4 (make-oscil)) (rnd (make-rand-interp 1000 (hz->radians 200)))) (do ((i start (+ i 1))) ((= i stop)) (let ((frq (+ (env frqf) (* (env rndf) (rand-interp rnd)))) (amp2 (env ampf2))) (outa i (* (env ampf) (+ (polywave gen1 (* 2.0 frq)) (* amp2 (polywave gen2 frq)) (* (- 1.0 amp2) (polywave gen3 (* 2.0 frq))) (* (env ampf4) (oscil gen4 (* 6.0 frq)))))))))) ;; note #1 (let ((dur1 0.36)) (acorn-woodpecker-1 beg1 dur1 (make-env '(0.000 0.000 0.046 0.257 0.248 0.331 0.371 0.745 0.564 1.000 0.738 0.970 0.909 0.442 1.000 0.000) :duration dur1 :scaler amp1) (make-env '(0.000 0.430 0.054 0.526 0.171 0.534 0.244 0.591 0.284 0.603 0.317 0.630 0.378 0.639 0.414 0.658 0.518 0.662 0.581 0.693 0.627 0.697 0.671 0.685 0.726 0.685 0.762 0.710 0.807 0.714 0.829 0.691 0.854 0.710 1.000 0.618) :duration dur1 :scaler (hz->radians (* 0.25 3030))) (make-env '(0 .2 .2 .2 .3 0 1 0) :duration dur1) (make-env '(0 1 .2 1 .25 0 .4 1 .5 0 .6 1 .7 0 .9 1 1 1) :duration dur1 :scaler .1) (make-env '(0 .03 .85 .03 1 1) :duration dur1))) ;; note #2 (let ((dur1 0.35)) (acorn-woodpecker-1 (+ beg1 0.55) dur1 (make-env '(0 0 .2 .1 .9 1 1 0) :duration dur1 :scaler amp1) (make-env '(0.000 0.466 0.088 0.497 0.202 0.513 0.319 0.585 0.386 0.596 0.747 0.632 0.835 0.671 0.882 0.661 1.000 0.350) :duration dur1 :scaler (hz->radians (* 0.25 3080))) (make-env '(0 0 .2 .1 .3 .1 .4 0 1 0) :duration dur1) (make-env '(0 1 .2 1 .25 0 .4 0 .6 1 .7 0 .9 1 1 1) :duration dur1 :scaler .2) (make-env '(0 .3 .05 .03 .8 .03 1 .3) :duration dur1 :base 10))) ;; note #3 (let ((dur1 0.34)) (acorn-woodpecker-1 (+ beg1 1.17) dur1 (make-env '(0 0 .2 .1 .8 1 .9 1 1 0) :duration dur1 :scaler amp1) (make-env '(0.000 0.310 0.076 0.331 0.118 0.388 0.184 0.422 0.239 0.484 0.336 0.544 0.720 0.549 0.831 0.581 0.896 0.570 0.920 0.630 0.938 0.604 1.000 0.448) :duration dur1 :scaler (hz->radians (* 0.25 3310))) (make-env '(0 0 .2 .1 .3 .1 .4 0 .5 0 .6 .1 .7 .1 .8 0 1 0) :duration dur1) (make-env '(0 1 .2 1 .25 0 .4 0 .6 1 .7 0 .8 1 .9 1 1 1) :duration dur1 :scaler .3) (make-env '(0 .1 .05 .03 .8 .03 1 .5) :duration dur1 :base 10)))) ;; (with-sound (:play #t) (acorn-woodpecker 0 .3)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Lesser nighhawk (defanimal (lesser-nighthawk beg dur amp) (let ((pulse-dur .021) (pulse-sep .047)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0 0 2 1 10 1 11 0) :duration dur :scaler amp :base 10)) (gen1 #f) (pulsef (make-env '(0.000 0.000 .6 1 1 0) :base .1 :duration pulse-dur)) (pulse-samps (seconds->samples pulse-sep)) (pulse-out (seconds->samples pulse-dur)) (frqf (make-env (list 0 600 .5 620 (max .55 (- dur .5)) 620 (max .6 dur) 570) :duration dur :scaler (hz->radians 1.0)))) (do ((i start (+ i pulse-samps))) ((>= i stop)) (set! (mus-location ampf) (- i start)) (let ((reset-stop (min stop (+ i pulse-out))) (pulse-amp (env ampf)) (pulse-frq (env frqf))) (set! (mus-location frqf) (- i start)) (set! gen1 (make-polywave 0.0 (list 1 (* pulse-amp .94) 3 (* pulse-amp .04) 4 (* pulse-amp .01)))) (do ((k i (+ k 1))) ((= k reset-stop)) (outa k (* (env pulsef) (polywave gen1 pulse-frq)))) (mus-reset pulsef)))))) ;; (with-sound (:play #t) (lesser-nighthawk 0 1 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Olive-sided flycatcher (defanimal (olive-sided-flycatcher beg amp) (let ((dur 1.08)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.021 0.129 0.035 0.369 0.053 0.250 0.064 0.000 0.352 0.000 0.381 0.674 0.394 0.483 0.407 0.834 0.418 0.852 0.425 0.795 0.440 0.898 0.457 0.931 0.489 0.922 0.506 0.878 0.534 0.991 0.548 0.988 0.577 0.717 0.593 0.834 0.615 0.000 0.690 0.000 0.704 0.698 0.710 0.436 0.712 0.610 0.726 0.395 0.736 0.483 0.756 0.545 0.773 0.795 0.786 0.583 0.808 0.919 0.816 0.843 0.826 0.898 0.837 0.797 0.844 0.659 0.860 0.640 0.879 0.334 0.975 0.176 0.989 0.034 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.175 0.020 0.235 0.035 0.269 0.041 0.311 0.070 0.224 0.356 0.209 0.377 0.309 0.402 0.352 0.449 0.360 0.549 0.348 0.574 0.339 0.588 0.354 0.596 0.330 0.603 0.354 0.612 0.235 0.691 0.213 0.702 0.313 0.725 0.380 0.743 0.397 0.765 0.354 0.794 0.328 0.844 0.299 0.876 0.277 0.975 0.254 1.000 0.198) :duration dur :scaler (hz->radians 10100.0))) (gen1 (make-polywave 0.0 '(1 .95 2 .03 3 .01 4 .005)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) ;; (with-sound (:play #t) (olive-sided-flycatcher 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Red-shouldered hawk ;;; ;;; ending is not right (defanimal (red-shouldered-hawk beg amp) (let ((dur 0.475)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.071 0.704 0.128 0.964 0.168 0.593 0.383 0.356 0.399 0.798 0.446 0.901 0.492 0.628 0.595 0.771 0.677 0.700 0.693 0.439 0.715 0.593 0.750 0.715 0.872 0.648 0.894 0.360 0.938 0.360 0.984 0.213 1.000 0.000) :duration dur :scaler (* 0.2 amp))) (frqf (make-env '(0.000 0.083 0.027 0.094 0.035 0.129 0.103 0.143 0.116 0.180 0.370 0.167 0.381 0.13 0.66 .114 .72 .116 .8 .112 0.871 0.105 0.888 0.080 0.976 0.078 1.000 0.08) :base .1 :duration dur :scaler (hz->radians (* 0.5 9130.0)))) (histuff (make-polywave 0.0 '(1 .1 2 .75 3 .1 4 .1 5 .01 6 .01 7 .01 8 .02 9 .01 11 .005 ))) (lostuff (make-polywave 0.0 '(2 .1 3 .3 5 .03 7 .1 9 .01 13 .1 15 .1 17 .05 19 .03))) (midstuff (make-polywave 0.0 '(1 .3 3 .7))) (midf (make-env '(0 1 .3 1 .4 .1 1 0) :duration dur :scaler 1.0)) (oddf (make-env '(0 1 .1 1 .12 .01 .45 .01 .55 .75 1 0) :duration dur :scaler 0.7 :base 10)) (frm1 (make-formant 2300 .98)) (frm2 (make-formant 3200 .99)) (frm3 (make-formant 5300 .97)) (frm4 (make-formant 1600 .99)) (fr1 (* 2 10 (sin (hz->radians 2300)))) (fr2 (* 2 3 (sin (hz->radians 3200)))) (fr3 (* 2 5 (sin (hz->radians 5300)))) (fr4 (* 2 5 (sin (hz->radians 1600)))) (rnd (make-rand-interp 400 (hz->radians 10)))) (let ((fb (vector frm1 frm2 frm3 frm4)) (fs (float-vector fr1 fr2 fr3 fr4))) (set! fb (make-formant-bank fb fs)) (do ((i start (+ i 1))) ((= i stop)) (let* ((frq (+ (env frqf) (rand-interp rnd))) (val (* (env ampf) (+ (polywave histuff (* 2.0 frq)) (* (env oddf) (polywave lostuff frq)) (* (env midf) (polywave midstuff (* 2.0 frq))))))) (outa i (+ val (formant-bank fb val))))))))) ;; (with-sound (:play #t) (red-shouldered-hawk 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Common yellowthroat (define (common-yellowthroat beg1 amp1) (defanimal (common-yellowthroat-1 beg amp) (let ((dur .42)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.067 0.312 0.105 0.773 0.132 0.685 0.160 0.168 0.178 0.075 0.192 0.178 0.211 0.636 0.227 0.782 0.236 0.623 0.258 0.807 0.283 0.639 0.299 0.000 0.434 0.000 0.482 0.751 0.503 0.804 0.518 0.651 0.540 0.000 0.638 0.000 0.661 0.576 0.715 0.664 0.736 0.984 0.763 0.685 0.784 0.620 0.817 0.894 0.830 0.745 0.912 0.134 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.296 0.029 0.290 0.052 0.305 0.072 0.334 0.088 0.367 0.108 0.381 0.132 0.348 0.159 0.305 0.183 0.352 0.210 0.410 0.241 0.436 0.267 0.441 0.292 0.434 0.398 0.417 0.410 0.682 0.428 0.686 0.457 0.581 0.475 0.534 0.491 0.503 0.521 0.485 0.531 0.468 0.645 0.488 0.672 0.506 0.690 0.530 0.704 0.543 0.718 0.521 0.733 0.486 0.763 0.457 0.791 0.423 0.838 0.356 0.918 0.261 0.951 0.252 1.000 0.194) :duration dur :scaler (hz->radians 10150.0))) (gen1 (make-polywave 0.0 '(1 .99 2 .01)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) (common-yellowthroat-1 beg1 (* 0.4 amp1)) (common-yellowthroat-1 (+ beg1 0.44) amp1) (common-yellowthroat-1 (+ beg1 0.90) amp1) (common-yellowthroat-1 (+ beg1 1.36) (* 0.8 amp1))) ;; (with-sound (:play #t) (common-yellowthroat 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Cassin's sparrow (define (cassins-sparrow beg amp) ;; buzz1 (let ((dur 0.2) (pulse-dur .0064) (start (seconds->samples beg))) (let ((stop (seconds->samples (+ beg dur))) (gen1 (make-polywave 0.0 '(1 .95 2 .05))) (ampf (make-env '(0.000 0.000 0.139 0.174 0.302 0.577 0.492 0.601 0.720 0.415 0.853 0.628 0.962 0.945 1.000 0.000) :duration dur :scaler (* .3 amp))) (pulse-samps (seconds->samples pulse-dur)) (pulse-frqf (make-env '(0 0 1 200 3 0) :duration pulse-dur :scaler (hz->radians 1.0))) (frqf (make-env '(0 5850 .2 6200 .3 6000 1 6100) :duration dur :scaler (hz->radians 1.0))) (pulse-ampf (make-env '(0.000 0.2 0.435 0.356 0.701 0.925 0.785 0.984 0.880 0.779 0.973 0.395 1.000 0.2) :duration pulse-dur))) (do ((i start (+ i pulse-samps))) ((>= i stop)) (let ((reset-stop (min stop (+ i pulse-samps)))) (do ((k i (+ k 1))) ((= k reset-stop)) (outa k (* (env ampf) (env pulse-ampf) (polywave gen1 (+ (env pulse-frqf) (env frqf)))))) (mus-reset pulse-ampf) (mus-reset pulse-frqf))))) ;; buzz2 (let ((dur 0.22) (pulse-dur .022) (start (seconds->samples (+ beg .2)))) (let ((stop (+ start (seconds->samples dur))) (gen1 (make-polywave 0.0 '(1 .95 2 .05))) (pulse-samps (seconds->samples pulse-dur)) (pulse-frqf (make-env '(0 5400 1 6700) :duration pulse-dur :scaler (hz->radians 1.0))) (pulse-ampf (make-env '(0 0 .1 0 .7 1 1 0) :duration pulse-dur :base .1 :scaler (* .6 amp))) (rnd (make-rand-interp 600 (hz->radians 100)))) (do ((i start (+ i pulse-samps))) ((>= i stop)) (let ((reset-stop (min stop (+ i pulse-samps)))) (do ((k i (+ k 1))) ((= k reset-stop)) (outa k (* (env pulse-ampf) (polywave gen1 (+ (env pulse-frqf) (rand-interp rnd)))))) (mus-reset pulse-ampf) (mus-reset pulse-frqf))))) ;; buzz3 (let ((dur 0.51) (pulse-dur .051) (start (seconds->samples (+ beg .425)))) (let ((stop (+ start (seconds->samples dur))) (gen1 (make-polywave 0.0 '(1 .98 2 .01 3 .005))) (pulse-samps (seconds->samples 0.064)) (pulse-frqf (make-env '(0 5300 .1 5200 .2 5300 .3 6000 1 6000) :duration pulse-dur :scaler (hz->radians 1.0))) (pulse-ampf (make-env '(0 0 .1 .5 .2 0 .3 1 .4 .9 .8 1 1 0) :duration pulse-dur :scaler amp)) (frqf (make-env '(0 100 .6 0 1 50) :duration dur :scaler (hz->radians 1.0))) (ampf (make-env '(0 .6 1 1) :duration dur)) (rnd (make-rand-interp 600 (hz->radians 10)))) (do ((i start (+ i pulse-samps))) ((>= i stop)) (let ((reset-stop (min stop (+ i pulse-samps)))) (do ((k i (+ k 1))) ((= k reset-stop)) (outa k (* (env ampf) (env pulse-ampf) (polywave gen1 (+ (env pulse-frqf) (env frqf) (rand-interp rnd)))))) (mus-reset pulse-ampf) (mus-reset pulse-frqf))))) ;; 4 long pitches (let ((dur 0.74) (start (seconds->samples (+ beg .95)))) (let ((stop (+ start (seconds->samples dur))) (gen1 (make-polywave 0.0 '(1 .99 2 .01))) (frqf (make-env '(0.000 0.446 0.014 0.403 0.054 0.385 0.121 0.376 0.248 0.374 0.274 0.367 0.290 0.198 0.308 0.166 0.339 0.159 0.418 0.162 0.545 0.162 0.674 0.162 0.714 0.164 0.718 0.458 0.735 0.451 0.743 0.415 0.761 0.403 0.847 0.387 1.000 0.387) :duration dur :scaler (hz->radians 22050.0))) (ampf (make-env '(0.000 0.000 0.025 0.833 0.062 0.951 0.087 0.882 0.120 1.000 0.172 0.961 0.226 0.849 0.238 0.666 0.253 0.000 0.299 0.000 0.319 0.689 0.329 0.679 0.346 0.000 0.409 0.000 0.450 0.593 0.478 0.689 0.537 0.767 0.649 0.626 0.666 0.469 0.679 0.000 0.737 0.000 0.771 0.816 0.784 0.698 0.795 0.911 0.828 0.895 0.853 0.774 0.882 0.734 0.942 0.603 0.979 0.475 0.992 0.325 1.000 0.000) :duration dur :scaler (* .9 amp)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf))))))) ;; last buzz (let ((dur 0.32) (start (seconds->samples (+ beg 1.73)))) (let ((stop (+ start (seconds->samples dur))) (gen1 (make-oscil 3100.0)) (ampf (make-env '(0 0 1 1 2 1 3 0) :base .3 :duration dur :scaler (* .4 amp))) (buzz (make-oscil 120)) (rnd (make-rand-interp 400 (hz->radians 100)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (+ .25 (* .75 (abs (oscil buzz)))) (oscil gen1 (rand-interp rnd)))))))) ;; (with-sound (:play #t) (cassins-sparrow 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Steller's jay (define (stellers-jay beg1 amp1) (defanimal (stellers-jay-1 beg amp) (let ((dur .09)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.171 0.175 0.268 0.475 0.314 0.294 0.433 1.000 0.502 0.306 0.671 0.586 0.794 0.236 0.847 0.615 1.000 0.000) :duration dur :scaler amp)) (frqf1 (make-env '(0.000 0.393 0.343 0.411 0.423 0.366 0.478 0.405 0.542 0.508 0.582 0.526 0.683 0.414 0.849 0.417 0.957 0.218 1.000 0.196) :duration dur :scaler (hz->radians 6050.0))) (frqf2 (make-env '(0.000 0.405 0.213 0.405 0.277 0.311 0.391 0.290 0.497 0.275 0.558 0.242 0.635 0.242 0.729 0.190 0.868 0.205 1.000 0.160) :duration dur :scaler (hz->radians 6050.0))) (gen1 (make-polywave 0.0 '(1 .95 2 .1 3 .1))) (gen2 (make-polywave 0.0 '(1 .95 2 .03 3 .01))) (ampf2 (make-env '(0 0 1 1 2 0) :duration dur :scaler .3)) (rnd (make-rand-interp 8000 )) (frm1 (make-formant 2460 .99)) (frm2 (make-formant 5200 .98)) (frm3 (make-formant 8200 .97)) (fr1 (* 2 5 (sin (hz->radians 2460)))) (fr2 (* 2 5 (sin (hz->radians 5200)))) (fr3 (* 2 2 (sin (hz->radians 8200)))) (frmaf (make-env '(0 0 .6 .3 .9 .8 1 .5) :duration dur)) (frmaf-1 (make-env '(0 0 .6 .3 .9 .8 1 .5) :duration dur :offset 1.0 :scaler -1.0)) (frmf (make-env '(0 5200 .7 4900 .9 2200 1 2000) :scaler (hz->radians 1.0) :duration dur)) (frmf3 (make-env '(0 8200 .7 8400 .9 4000 1 4000) :scaler (hz->radians 1.0) :duration dur)) (frmf1 (make-env '(0 2460 .7 2400 .9 1400 1 1500) :scaler (hz->radians 1.0) :duration dur))) (do ((i start (+ i 1))) ((= i stop)) (let* ((val1 (* (env ampf) (+ (polywave gen1 (env frqf1)) (* (env ampf2) (polywave gen2 (env frqf2)))))) (frm-in (* val1 (rand-interp rnd)))) (outa i (+ (* 0.75 val1) (* fr1 (env frmaf-1) (formant frm1 frm-in (env frmf1))) (* fr2 (env frmaf) (formant frm2 frm-in (env frmf))) (* fr3 (formant frm3 frm-in (env frmf3)))))))))) (do ((beg beg1 (+ beg .15)) (i 0 (+ i 1))) ((= i 6)) (stellers-jay-1 beg amp1))) ;; (with-sound (:statistics #t) (stellers-jay 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Black rail (defanimal (black-rail beg amp) ;; notes 1 and 2 (let ((dur 0.2)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.015 0.069 0.029 0.738 0.083 0.868 0.133 0.868 0.230 0.725 0.267 0.501 0.324 0.000 0.694 0.000 0.716 1.000 0.778 0.975 0.850 0.906 0.898 0.814 0.939 0.585 0.981 0.081 1.000 0.000) :duration dur :scaler (* 0.9 amp))) (frqf (make-env '(0.000 0.484 0.028 0.458 0.210 0.456 0.296 0.444 0.324 0.404 0.700 0.461 0.728 0.453 0.916 0.453 1.000 0.390) :duration dur :scaler (hz->radians (* 0.5 8150.0)))) (gen1 (make-polywave 0.0 '(1 .09 2 1 3 .07 4 .003 5 .01 6 .03 7 .005 9 .003))) (buzz (make-oscil 240)) (buzz1 (make-oscil 240)) (scl (hz->radians 20))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (+ .8 (* .2 (oscil buzz))) (polywave gen1 (+ (env frqf) (* scl (oscil buzz1))))))))) ;; note 3 (let ((dur 0.21) (start (seconds->samples (+ beg .254)))) (let ((stop (+ start (seconds->samples dur))) (ampf (make-env '(0.000 0.000 0.031 0.980 0.106 0.725 0.141 0.811 0.182 0.567 0.225 0.779 0.272 0.473 0.318 0.648 0.375 0.292 0.410 0.585 0.467 0.212 0.507 0.335 0.550 0.192 0.585 0.301 0.643 0.155 0.678 0.261 0.721 0.152 0.756 0.201 0.811 0.172 0.845 0.052 0.879 0.140 0.924 0.066 1.000 0.000) :duration dur :scaler (* 0.4 amp))) (frqf (make-env '(0.000 0.000 0.003 0.366 0.027 0.469 0.047 0.516 0.086 0.478 0.107 0.516 0.130 0.537 0.155 0.507 0.178 0.472 0.201 0.510 0.227 0.528 0.249 0.501 0.273 0.463 0.291 0.496 0.317 0.516 0.342 0.484 0.364 0.437 0.386 0.484 0.413 0.504 0.439 0.460 0.461 0.422 0.482 0.466 0.507 0.493 0.528 0.451 0.547 0.398 0.569 0.434 0.599 0.469 0.619 0.431 0.642 0.383 0.661 0.425 0.678 0.454 0.707 0.410 0.731 0.372 0.774 0.422 0.815 0.336 0.867 0.372 0.905 0.319 1.000 0.304) :duration dur :scaler (hz->radians (* 0.25 8040.0)))) (gen1 (make-polywave 0.0 '(1 .1 2 1 3 .4 4 .1 5 .03 6 .005 7 .005 10 .005)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) ;; (with-sound (:play #t) (black-rail 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Pinyon jay (defanimal (pinyon-jay beg amp) (let ((dur 0.3)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.008 0.035 0.013 0.118 0.024 0.032 0.087 0.596 0.111 0.617 0.159 0.460 0.188 0.546 0.240 0.876 0.293 1.000 0.345 0.991 0.377 0.938 0.436 0.959 0.501 0.764 0.537 0.534 0.628 0.442 0.718 0.466 0.812 0.386 0.858 0.316 0.903 0.342 0.949 0.094 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.100 0.075 0.163 0.130 0.185 0.192 0.207 0.327 0.245 0.385 0.256 0.558 0.200 0.724 0.207 0.806 0.209 0.875 0.180 0.944 0.138 1.000 0.134) :base .1 :duration dur :scaler (hz->radians (* 0.5 8160)))) (gen1 (make-polywave 0.0 '(1 .03 2 .8 3 .05 4 .01 5 .03 6 .075 7 .03 8 .008 9 .005 10 .005 11 .003))) (gen2 (make-oscil 0.0 (* 0.5 pi))) (ampf2 (make-env '(0 .2 .1 .2 .2 0 .4 .05 .8 .02 .9 .2 1 0) :duration dur :scaler 3)) (rnd (make-rand-interp 1000 (hz->radians 10)))) (do ((i start (+ i 1))) ((= i stop)) (let ((frq (+ (env frqf) (rand-interp rnd)))) (outa i (* (env ampf) (+ (polywave gen1 frq) (* (env ampf2) (oscil gen2 (* 3.0 frq))))))))))) ;; (with-sound (:play #t) (pinyon-jay 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Sora (defanimal (sora beg amp) (let ((dur 0.41)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.011 0.109 0.066 0.180 0.360 0.192 0.442 0.229 0.473 0.203 0.575 0.276 0.621 0.345 0.702 0.361 0.751 0.661 0.792 0.713 0.839 0.606 0.885 0.873 0.904 0.788 0.937 0.980 0.953 0.998 0.962 0.911 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.358 0.103 0.332 0.209 0.327 0.328 0.341 0.572 0.363 0.771 0.429 0.893 0.458 0.965 0.462 1.000 0.448) :duration dur :scaler (hz->radians (* 0.5 6020)))) (gen1 (make-polywave 0.0 '(1 .05 2 .9 3 .05 4 .005)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) ;; (with-sound (:play #t) (sora 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Killdeer (defanimal (killdeer beg amp) (let ((dur 0.88)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.015 0.477 0.028 0.499 0.054 0.172 0.078 0.107 0.184 0.199 0.212 0.177 0.245 0.249 0.275 0.291 0.364 0.688 0.388 0.714 0.416 0.944 0.436 0.906 0.451 0.998 0.478 0.000 0.535 0.000 0.551 0.976 0.564 1.000 0.582 0.981 0.610 0.838 0.634 0.908 0.661 0.782 0.682 0.000 0.732 0.000 0.735 0.562 0.746 0.709 0.798 0.554 0.814 0.579 0.825 0.472 0.837 0.000 0.910 0.000 0.915 0.392 0.920 0.554 0.947 0.458 0.962 0.341 0.978 0.370 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.373 0.013 0.471 0.029 0.487 0.052 0.449 0.074 0.422 0.244 0.442 0.319 0.453 0.353 0.456 0.412 0.458 0.454 0.464 0.471 0.442 0.477 0.389 0.537 0.378 0.539 0.436 0.551 0.464 0.586 0.460 0.649 0.462 0.673 0.444 0.684 0.404 0.736 0.373 0.742 0.422 0.758 0.440 0.820 0.440 0.835 0.416 0.839 0.382 0.911 0.353 0.912 0.393 0.924 0.420 0.941 0.409 0.959 0.404 0.982 0.413 1.000 0.396) :duration dur :scaler (hz->radians (* 0.25 10170.0)))) (gen1 (make-polywave 0.0 '(1 .04 2 1 3 .07 4 .04 5 .005))) (gen2 (make-polywave 0.0 '(1 .01 2 .05 3 .03 4 1 5 .12 6 .1 7 .01 8 .05 9 .005))) (ampf2 (make-env '(0 0 .53 0 .64 .7 .67 0 .73 .1 .9 0 .91 .07 .94 0 1 0) :duration dur))) (do ((i start (+ i 1))) ((= i stop)) (let ((frq (env frqf))) (outa i (* (env ampf) (+ (polywave gen1 (* 2.0 frq)) (* (env ampf2) (polywave gen2 frq)))))))))) ;; (with-sound (:play #t) (killdeer 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Oak titmouse (define (oak-titmouse beg1 amp1) (defanimal (oak-titmouse-1 beg amp) (let ((dur 0.117)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.019 0.149 0.034 0.099 0.058 0.121 0.067 0.041 0.099 0.032 0.117 0.061 0.147 0.510 0.170 0.537 0.182 0.138 0.195 0.066 0.228 0.058 0.247 0.086 0.258 0.151 0.269 0.701 0.290 0.382 0.305 0.537 0.319 0.128 0.341 0.041 0.363 0.077 0.383 0.173 0.400 0.989 0.412 0.613 0.433 0.545 0.443 0.475 0.452 0.631 0.461 0.139 0.477 0.061 0.501 0.086 0.516 0.149 0.530 0.979 0.548 0.601 0.558 0.504 0.576 0.524 0.589 0.183 0.606 0.080 0.633 0.094 0.648 0.180 0.671 0.979 0.686 0.549 0.705 0.815 0.718 0.214 0.731 0.131 0.757 0.100 0.773 0.146 0.788 0.315 0.805 0.876 0.822 0.606 0.834 0.503 0.849 0.544 0.865 0.120 0.888 0.079 0.910 0.121 0.924 0.182 0.940 0.542 0.959 0.430 0.972 0.183 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0 7200 1 5200) :duration dur :scaler (hz->radians 1.0))) (gen1 (make-polywave 0.0 '(1 .97 2 .03))) (gen2 (make-oscil 63.5 (+ pi 1))) (vib-amp (hz->radians 1200))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (+ (env frqf) (* vib-amp (oscil gen2)))))))))) (defanimal (oak-titmouse-2 beg amp) (let ((dur 0.14)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.027 0.067 0.088 0.113 0.129 0.322 0.175 0.718 0.244 0.987 0.283 0.941 0.315 0.710 0.344 0.322 0.374 0.450 0.388 0.351 0.450 0.220 0.565 0.118 0.673 0.062 0.725 0.070 0.789 0.126 0.836 0.209 0.870 0.177 0.892 0.233 0.908 0.475 .92 .1 1 0) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.125 .04 .125 0.070 0.214 0.1 0.296 0.146 0.333 0.2 0.329 0.263 0.300 0.322 0.264 0.407 0.218 0.514 0.196 0.660 0.183 0.746 0.190 0.822 0.212 0.873 0.252 0.902 0.254 0.926 0.212 1.000 0.207) :duration dur :scaler (hz->radians 10230.0))) (gen1 (make-polywave 0.0 '(1 .9 2 .05 3 .01 4 .01 5 .005))) (gen2 (make-polywave 0.0 '(2 1 3 .5 4 .1))) (ampf2 (make-env '(0 1 .1 0 .8 0 1 1) :duration dur :scaler .5))) (do ((i start (+ i 1))) ((= i stop)) (let ((frq (env frqf))) (outa i (* (env ampf) (+ (polywave gen1 frq) (* (env ampf2) (polywave gen2 frq)))))))))) (let ((amps (vector .5 1.0 1.0 .9))) (do ((i 0 (+ i 1)) (bg beg1 (+ bg .35))) ((= i 4)) (oak-titmouse-1 bg (* amp1 (amps i))) (oak-titmouse-2 (+ bg .156) (* amp1 (amps i)))))) ;; (with-sound (:play #t) (oak-titmouse 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Macgillivray's warbler (define (macgillivrays-warbler beg1 amp1) ;; much more complex than it sounds -- like the Hermit Thrush, this has 2 independent sources (defanimal (macgillivrays-warbler-1 beg amp) ;; 5 of these to start (let ((dur 0.137)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.066 0.200 0.208 0.310 0.228 0.400 0.259 0.403 0.331 0.175 0.370 0.377 0.414 0.166 0.462 0.639 0.475 0.149 0.495 0.648 0.612 0.992 0.647 0.924 0.700 0.473 0.710 0.138 0.720 0.654 0.770 0.352 0.815 0.848 0.829 0.724 0.840 0.837 0.864 0.625 0.891 0.715 0.937 0.687 0.989 0.456 1.000 0.000) :duration dur :scaler (* .75 amp))) (frqf1 (make-env '(0.000 0.515 0.096 0.506 0.193 0.475 0.287 0.421 0.358 0.362 0.470 0.346 0.495 0.588 0.532 0.593 0.567 0.607 0.625 0.635 0.680 0.711 0.711 0.739 0.735 0.800 0.762 0.800 0.785 0.645 0.808 0.565 0.851 0.551 1.000 0.544) :duration dur :scaler (hz->radians 8830.0))) (ampf1 (make-env '(0 1 .35 1 .356 0 .49 0 .494 1 .73 1 .735 .25 .8 .25 .81 1 1 1) :duration dur)) (gen1 (make-polywave 0.0 '(1 .97 2 .02 3 .005))) (frqf2 (make-env '(0.000 0.515 0.326 0.522 0.370 0.454 0.413 0.416 0.419 0.492 0.427 0.586 0.451 0.534 0.472 0.461 0.493 0.593 0.540 0.598 0.587 0.614 0.647 0.656 0.698 0.725 0.728 0.562 0.758 0.492 0.788 0.468 0.803 0.501 0.814 0.555 1.000 0.544) :duration dur :scaler (hz->radians 8830.0))) (ampf2 (make-env '(0 0 .324 0 .327 .5 .73 .5 .735 1 .8 1 .81 0 1 0) :duration dur)) (gen2 (make-polywave 0.0 '(1 .97 2 .02 3 .005))) (rnd (make-rand-interp 6000 .1))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (+ .9 (rand-interp rnd)) (+ (* (env ampf1) (polywave gen1 (env frqf1))) (* (env ampf2) (polywave gen2 (env frqf2)))))))))) (defanimal (macgillivrays-warbler-2 beg amp) ;; 3 of these to end (let ((dur 0.135)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.031 0.052 0.184 0.078 0.275 0.254 0.311 0.285 0.327 0.461 0.377 0.635 0.455 0.216 0.521 0.426 0.533 0.605 0.601 0.991 0.619 0.951 0.628 0.584 0.674 0.318 0.711 0.440 0.732 0.680 0.771 0.581 0.806 0.315 0.857 0.256 0.892 0.132 0.949 0.108 1.000 0.000) :duration dur :scaler amp)) (frqf1 (make-env '(0.000 0.202 0.048 0.277 0.077 0.289 0.106 0.268 0.130 0.286 0.152 0.275 0.169 0.232 0.202 0.216 0.229 0.232 0.264 0.277 0.292 0.291 0.324 0.310 0.351 0.340 0.382 0.303 0.430 0.329 0.470 0.366 0.533 0.408 0.612 0.479 0.638 0.575 0.712 0.343 0.730 0.286 0.750 0.258 0.778 0.272 0.804 0.312 0.826 0.345 0.852 0.352 0.891 0.317 0.934 0.286 1.000 0.2) :duration dur :scaler (hz->radians 9140.0))) (ampf1 (make-env '(0 1 .1 .4 .3 .1 .5 .2 .63 .2 .64 0 .71 0 .72 .1 .8 1 1 1) :duration dur)) (gen1 (make-polywave 0.0 '(1 .6 2 .4 3 .005))) (frqf2 (make-env '(0.000 0.357 0.196 0.357 0.275 0.373 0.310 0.413 0.350 0.446 0.385 0.484 0.425 0.538 0.462 0.540 0.470 0.373 0.535 0.418 0.591 0.462 0.621 0.500 0.637 0.573 0.667 0.392 0.712 0.406 0.744 0.455 0.778 0.462 0.833 0.556 1.000 0.32) :duration dur :scaler (hz->radians 9140.0))) (ampf2 (make-env '(0 0 .19 0 .195 1 .45 .1 .46 0 .47 1 .63 1 .64 0 .67 0 .68 1 .82 1 .83 0 1 0) :duration dur)) (gen2 (make-polywave 0.0 '(1 .99 2 .01))) (rnd1 (make-rand-interp 600 (hz->radians 40))) (rnd (make-rand-interp 6000 .1))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (+ .9 (rand-interp rnd)) (+ (* (env ampf1) (polywave gen1 (env frqf1))) (* (env ampf2) (polywave gen2 (+ (env frqf2) (rand-interp rnd1))))))))))) (let ((amps (vector .4 .6 .8 .9 1.0))) (do ((note 0 (+ 1 note)) (bg beg1 (+ bg 0.18))) ((= note 5)) (macgillivrays-warbler-1 bg (* amp1 (amps note))))) (let ((amps (vector 1.0 .9 .7))) (do ((note 0 (+ 1 note)) (bg (+ beg1 0.93) (+ bg 0.17))) ((= note 3)) (macgillivrays-warbler-2 bg (* amp1 (amps note)))))) ;; (with-sound (:play #t) (macgillivrays-warbler 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Hutton's vireo (defanimal (huttons-vireo beg amp) (let ((dur 0.4)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.054 0.080 0.063 0.040 0.078 0.086 0.113 0.107 0.136 0.061 0.148 0.086 0.155 0.066 0.161 0.123 0.176 0.087 0.184 0.112 0.204 0.067 0.214 0.070 0.220 0.055 0.226 0.077 0.233 0.034 0.239 0.083 0.246 0.032 0.254 0.081 0.260 0.038 0.265 0.067 0.274 0.040 0.281 0.074 0.287 0.043 0.293 0.060 0.300 0.014 0.307 0.066 0.315 0.018 0.320 0.074 0.330 0.021 0.335 0.070 0.342 0.025 0.351 0.069 0.355 0.017 0.360 0.051 0.375 0.040 0.380 0.063 0.388 0.023 0.396 0.077 0.404 0.025 0.410 0.081 0.417 0.032 0.425 0.089 0.428 0.058 0.435 0.047 0.441 0.093 0.447 0.041 0.456 0.116 0.463 0.044 0.471 0.138 0.479 0.061 0.489 0.150 0.497 0.070 0.506 0.191 0.510 0.124 0.514 0.089 0.521 0.211 0.526 0.138 0.530 0.121 0.537 0.234 0.547 0.103 0.556 0.263 0.561 0.204 0.567 0.213 0.571 0.319 0.578 0.286 0.580 0.237 0.586 0.292 0.591 0.234 0.594 0.288 0.600 0.132 0.602 0.217 0.606 0.262 0.611 0.420 0.614 0.357 0.617 0.162 0.630 0.472 0.636 0.132 0.649 0.587 0.657 0.133 0.666 0.587 0.671 0.380 0.677 0.271 0.683 0.640 0.692 0.343 0.696 0.248 0.704 0.680 0.711 0.358 0.715 0.288 0.721 0.779 0.731 0.204 0.736 0.357 0.739 0.776 0.745 0.882 0.753 0.320 0.760 0.695 0.769 0.994 0.775 0.322 0.781 0.662 0.789 0.856 0.794 0.582 0.797 0.240 0.801 0.608 0.809 0.825 0.816 0.877 0.823 0.311 0.830 0.900 0.834 0.877 0.838 0.758 0.844 0.809 0.858 0.605 0.867 0.879 0.879 0.819 0.883 0.968 0.890 0.969 0.898 0.885 0.912 0.862 0.919 0.776 0.934 0.769 0.940 0.740 0.952 0.565 0.969 0.485 0.974 0.403 0.982 0.389 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.0000 0.4927 0.0133 0.5498 0.0177 0.6092 0.0275 0.8519 0.0276 0.5073 0.0413 0.8422 0.0428 0.4454 0.0624 0.5510 0.0954 0.5534 0.1264 0.5570 0.1391 0.5194 0.1632 0.5522 0.1750 0.4976 0.1912 0.5437 0.1996 0.4672 0.2055 0.5413 0.2134 0.4660 0.2207 0.5413 0.2266 0.4454 0.2335 0.5388 0.2380 0.4357 0.2458 0.5352 0.2522 0.4357 0.2596 0.5243 0.2635 0.4320 0.2699 0.5182 0.2788 0.4296 0.2842 0.5061 0.2935 0.4248 0.2999 0.5061 0.3068 0.4260 0.3147 0.5000 0.3210 0.4248 0.3289 0.4939 0.3358 0.4187 0.3422 0.4782 0.3500 0.4223 0.3569 0.4721 0.3658 0.4223 0.3736 0.4794 0.3800 0.4211 0.3884 0.4745 0.3948 0.4199 0.4036 0.4745 0.4105 0.4126 0.4174 0.4721 0.4258 0.4090 0.4341 0.4733 0.4410 0.4066 0.4489 0.4648 0.4577 0.4053 0.4656 0.4648 0.4730 0.3993 0.4823 0.4697 0.4887 0.3993 0.4990 0.4709 0.5059 0.4005 0.5143 0.4769 0.5236 0.3968 0.5339 0.4879 0.5393 0.3993 0.5521 0.4988 0.5590 0.4029 0.5674 0.5024 0.5777 0.4053 0.5870 0.5097 0.5954 0.4090 0.6057 0.5146 0.6121 0.4150 0.6229 0.5303 0.6332 0.4187 0.6416 0.5437 0.6529 0.4284 0.6618 0.5437 0.6711 0.4308 0.6814 0.5413 0.6868 0.4345 0.6986 0.5473 0.7065 0.4393 0.7183 0.5510 0.7281 0.4430 0.7404 0.5558 0.7557 0.4490 0.7630 0.5595 0.7763 0.4563 0.7861 0.5558 0.7984 0.4612 0.8117 0.5680 0.8265 0.5231 0.9641 0.5095 0.9754 0.3944 0.9823 0.4); 1 .4) :duration dur :scaler (hz->radians 7500.0))) (gen1 (make-polywave 0.0 '(1 .95 2 .03 3 .005)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) ;; (with-sound (:play #t) (huttons-vireo 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Western meadowlark (define (western-meadowlark beg1 amp1) ;; 1st sequence of notes (defanimal (western-meadowlark-1 beg amp) (let ((dur 1.075)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.007 0.072 0.016 0.253 0.028 0.300 0.048 0.000 0.115 0.000 0.122 0.062 0.132 0.437 0.148 0.462 0.162 0.444 0.188 0.000 0.365 0.000 0.392 0.050 0.397 0.017 0.406 0.052 0.412 0.000 0.432 0.000 0.438 0.082 0.455 0.541 0.486 0.722 0.503 0.759 0.518 0.744 0.529 0.774 0.547 0.700 0.570 0.000 0.635 0.000 0.656 0.715 0.680 0.963 0.701 1.000 0.730 0.938 0.742 0.883 0.754 0.715 0.770 0.000 0.850 0.000 0.855 0.211 0.857 0.072 0.858 0.360 0.861 0.112 0.862 0.568 0.864 0.181 0.866 0.742 0.867 0.290 0.872 0.933 0.874 0.625 0.883 0.963 0.899 0.940 0.906 0.844 0.920 0.856 0.922 0.821 0.929 0.891 0.935 0.844 0.949 0.911 0.970 0.861 0.981 0.667 0.993 0.104 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.280 0.069 0.288 0.125 0.280 0.185 0.275 0.258 0.280 0.366 0.184 0.394 0.179 0.405 0.218 0.409 0.134 0.426 0.134 0.428 0.352 0.568 0.345 0.618 0.350 0.630 0.258 0.765 0.261 0.828 0.258 0.848 0.454 1.000 0.452) :duration dur :scaler (hz->radians 7470.0))) (gen1 (make-oscil))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (oscil gen1 (env frqf)))))))) ;; 2nd sequence of notes (defanimal (western-meadowlark-2 beg amp) (let ((dur 0.45)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.014 0.080 0.030 0.297 0.036 0.100 0.043 0.109 0.050 0.436 0.055 0.191 0.057 0.435 0.064 0.338 0.067 0.000 0.070 0.830 0.079 0.255 0.084 0.883 0.090 0.982 0.099 0.000 0.100 0.553 0.102 0.626 0.113 0.035 0.118 0.261 0.129 0.047 0.151 0.000 0.218 0.000 0.224 0.041 0.227 0.015 0.233 0.083 0.248 0.000 0.263 0.141 0.282 0.209 0.310 0.389 0.331 0.377 0.354 0.148 0.383 0.829 0.393 0.733 0.406 0.294 0.412 0.559 0.436 0.512 0.440 0.250 0.443 0.465 0.446 0.117 0.453 0.324 0.460 0.094 0.464 0.070 0.470 0.192 0.477 0.058 0.483 0.023 0.490 0.686 0.501 0.788 0.509 0.756 0.532 0.129 0.550 0.000 0.613 0.000 0.619 0.062 0.625 0.015 0.631 0.042 0.634 0.117 0.641 0.070 0.659 0.102 0.675 0.067 0.687 0.000 0.730 0.000 0.734 0.118 0.745 0.139 0.746 0.252 0.762 0.329 0.770 0.898 0.772 0.223 0.777 0.856 0.785 0.900 0.792 0.126 0.797 0.071 0.803 0.742 0.809 0.688 0.824 0.179 0.832 0.197 0.836 0.294 0.880 0.017 0.895 0.041 0.915 0.029 0.924 0.008 0.935 0.029 0.956 0.041 0.978 0.033 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.506 0.042 0.501 0.068 0.481 0.125 0.300 0.153 0.293 0.204 0.963 0.217 0.918 0.223 0.720 0.235 0.588 0.353 0.553 0.358 0.328 0.400 0.323 0.412 0.293 0.418 0.318 0.421 0.273 0.429 0.315 0.435 0.263 0.443 0.263 0.449 0.221 0.472 0.218 0.483 0.223 0.487 0.320 0.499 0.266 0.530 0.266 0.545 0.253 0.550 0.201 0.622 0.211 0.635 0.241 0.640 0.149 0.684 0.161 0.725 0.169 0.727 0.305 0.736 0.268 0.742 0.238 0.752 0.236 0.757 0.310 0.759 0.166 0.773 0.400 0.777 0.350 0.791 0.347 0.803 0.303 0.829 0.303 0.840 0.206 0.872 0.208 0.894 0.146 0.918 0.161 0.930 0.102 0.964 0.134 1.000 0.146) :duration dur :scaler (hz->radians 7470.0))) (gen1 (make-polywave 0.0 '(1 .99 2 .01)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) (western-meadowlark-1 beg1 (* 0.6 amp1)) (western-meadowlark-2 (+ beg1 1.125) amp1)) ;; (with-sound (:play #t) (western-meadowlark 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Northern beardless tyrannulet ;;; ;;; this should have used 4 calls on one note (defanimal (northern-beardless-tyrannulet beg amp) (let ((dur 1.91)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.013 0.124 0.018 0.713 0.038 0.303 0.052 0.469 0.065 0.236 0.079 0.685 0.084 0.483 0.089 0.666 0.094 0.545 0.101 0.638 0.107 0.542 0.113 0.671 0.123 0.531 0.132 0.590 0.157 0.879 0.167 0.784 0.173 0.410 0.177 0.646 0.182 0.228 0.192 0.587 0.203 0.000 0.238 0.000 0.240 0.010 0.248 0.843 0.255 0.404 0.266 0.952 0.281 1.000 0.331 0.963 0.350 0.702 0.358 0.784 0.375 0.534 0.391 0.778 0.406 0.000 0.444 0.000 0.446 0.010 0.457 0.899 0.464 0.334 0.473 1.000 0.492 0.854 0.499 0.610 0.506 0.730 0.525 0.652 0.552 0.801 0.560 0.553 0.570 0.865 0.582 0.534 0.583 0.626 0.590 0.483 0.595 0.570 0.611 0.000 0.649 0.000 0.651 0.010 0.662 0.899 0.671 0.654 0.679 0.969 0.698 0.787 0.704 0.843 0.711 0.772 0.726 0.910 0.768 0.643 0.780 0.680 0.803 0.000 0.845 0.000 0.847 0.010 0.856 0.770 0.863 0.492 0.866 0.860 0.873 0.890 0.883 0.680 0.889 0.817 0.901 0.722 0.915 0.823 0.934 0.534 0.953 0.576 0.972 0.435 0.977 0.562 0.990 0.101 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.396 0.021 0.439 0.188 0.431 0.197 0.340 0.247 0.375 0.256 0.447 0.268 0.437 0.396 0.426 0.400 0.394 0.402 0.358 0.457 0.369 0.461 0.426 0.469 0.447 0.484 0.437 0.599 0.418 0.607 0.394 0.611 0.345 0.658 0.361 0.663 0.426 0.669 0.456 0.682 0.429 0.786 0.415 0.795 0.407 0.801 0.345 0.856 0.372 0.861 0.420 0.865 0.450 0.875 0.431 0.982 0.407 0.990 0.361 1.000 0.278) :duration dur :scaler (hz->radians 9230.0))) (gen1 (make-polywave 0.0 '(1 .95 2 .005 3 .02 4 .005 5 .003))) (noise (make-rand-interp 8000)) (noisef (make-env '(0 0 .011 1 .015 0 .236 0 .24 1 .245 0 .44 0 .445 1 .452 0 .647 0 .65 1 .657 0 .84 0 .845 1 .853 0 1 0) :duration dur :scaler .25))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (+ (env frqf) (* (env noisef) (rand-interp noise)))))))))) ;; (with-sound (:play #t) (northern-beardless-tyrannulet 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Scott's oriole (defanimal (scotts-oriole beg amp) (let ((dur 1.83)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.020 0.103 0.030 0.113 0.038 0.099 0.062 0.000 0.142 0.000 0.150 0.050 0.160 0.326 0.170 0.333 0.178 0.309 0.200 0.050 0.207 0.076 0.218 0.282 0.238 0.018 0.255 0.353 0.265 0.415 0.276 0.392 0.292 0.000 0.318 0.000 0.328 0.442 0.331 0.090 0.335 0.408 0.339 0.279 0.342 0.545 0.357 0.000 0.405 0.000 0.413 0.250 0.419 0.281 0.424 0.250 0.436 0.058 0.442 0.072 0.462 0.511 0.471 0.500 0.477 0.000 0.484 0.000 0.487 0.980 0.505 0.514 0.521 0.304 0.530 0.000 0.601 0.000 0.616 0.559 0.622 0.599 0.637 0.581 0.646 0.507 0.661 0.000 0.676 0.000 0.678 0.239 0.680 0.094 0.682 0.424 0.687 0.096 0.689 0.374 0.693 0.000 0.702 0.000 0.716 0.698 0.725 0.763 0.735 0.000 0.746 0.000 0.753 0.396 0.758 0.423 0.760 0.399 0.771 0.054 0.777 0.095 0.783 0.207 0.786 0.227 0.800 0.142 0.823 0.072 0.828 0.000 0.851 0.000 0.853 0.243 0.856 0.087 0.857 0.351 0.862 0.147 0.863 0.300 0.870 0.000 0.877 0.000 0.892 0.888 0.911 0.000 0.920 0.000 0.926 0.353 0.933 0.406 0.943 0.059 0.948 0.025 0.962 0.167 0.970 0.174 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.560 0.023 0.489 0.052 0.487 0.079 0.487 0.138 0.556 0.150 0.556 0.162 0.487 0.181 0.473 0.202 0.473 0.212 0.415 0.234 0.415 0.241 0.491 0.252 0.442 0.267 0.431 0.285 0.438 0.319 0.455 0.322 0.533 0.328 0.634 0.332 0.467 0.338 0.775 0.348 0.839 0.354 0.810 0.366 0.737 0.392 0.415 0.409 0.411 0.421 0.386 0.440 0.397 0.472 0.438 0.477 0.531 0.485 0.607 0.495 0.507 0.508 0.408 0.527 0.406 0.587 0.406 0.607 0.491 0.624 0.462 0.637 0.458 0.654 0.467 0.658 0.422 0.679 0.393 0.682 0.585 0.684 0.482 0.686 0.643 0.690 0.420 0.700 0.576 0.706 0.621 0.710 0.583 0.730 0.612 0.751 0.413 0.766 0.406 0.789 0.362 0.819 0.359 0.852 0.388 0.856 0.645 0.858 0.491 0.861 0.621 0.864 0.435 0.867 0.576 0.873 0.565 0.879 0.600 0.887 0.576 0.896 0.596 0.903 0.654 0.924 0.420 0.940 0.395 0.973 0.359 1.000 0.353) :duration dur :scaler (hz->radians 5080.0))) (gen1 (make-polywave 0.0 '(1 .98 2 .01 3 .003 4 .007)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) ;; (with-sound (:play #t) (scotts-oriole 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Wilson's warbler (define (wilsons-warbler beg1 amp1) ;; 3 different calls, 2(?) with 2 different tones (defanimal (wilsons-warbler-1 beg dur amp) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.101 0.169 0.138 0.169 0.179 0.297 0.226 0.377 0.269 0.092 0.318 0.513 0.340 0.651 0.359 0.156 0.372 0.654 0.387 0.156 0.428 0.700 0.491 0.808 0.607 0.721 0.659 0.923 0.747 0.995 0.909 0.813 0.965 0.528 1.000 0.000) :duration dur :scaler amp)) (frqf1 (make-env '(0.000 0.692 0.038 0.698 0.077 0.647 0.136 0.614 0.258 0.606 0.275 0.575 0.314 0.571 0.365 0.550 0.381 0.500 0.681 0.502 0.844 0.496 0.873 0.401 1.000 0.390) :duration dur :scaler (hz->radians 10210.0))) (gen1 (make-oscil)) (frqf2 (make-env '(0.000 0.692 0.038 0.698 0.077 0.647 0.136 0.614 0.258 0.606 0.275 0.575 0.314 0.571 0.365 0.550 0.376 0.394 0.490 0.353 0.594 0.347 0.681 0.392 0.740 0.418 0.818 0.416 0.886 0.399 1.000 0.390) :duration dur :scaler (hz->radians 10210.0))) (ampf1 (make-env '(0 1 .6 1 .8 0 1 0) :duration dur)) (gen2 (make-oscil)) (ampf2 (make-env '(0 .25 .35 .25 .36 0 .6 0 .7 1 1 1) :duration dur)) (rnd (make-rand-interp 4000 (hz->radians 300)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (+ (* (env ampf1) (oscil gen1 (+ (env frqf1) (rand-interp rnd)))) (* (env ampf2) (oscil gen2 (env frqf2))))))))) (defanimal (wilsons-warbler-2 beg dur frq amp) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.049 0.091 0.109 0.276 0.129 0.280 0.149 0.164 0.157 0.388 0.179 0.677 0.221 0.642 0.241 0.448 0.319 1.000 0.360 0.953 0.489 0.765 0.513 0.539 0.591 0.282 0.619 0.345 0.727 0.244 0.762 0.446 0.828 0.442 0.925 0.313 0.982 0.136 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.909 0.050 0.838 0.080 0.799 0.119 0.786 0.162 0.752 0.225 0.692 0.262 0.634 0.317 0.538 0.366 0.478 0.482 0.376 0.554 0.342 0.628 0.366 0.701 0.392 0.762 0.394 0.832 0.373 1.000 0.3) :duration dur :scaler (hz->radians (* frq 9780.0)))) (gen1 (make-oscil)) (rnd (make-rand-interp 4000 (hz->radians 200)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (oscil gen1 (+ (env frqf) (rand-interp rnd)))))))) (defanimal (wilsons-warbler-3 beg amp) (let ((dur 0.07)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.087 0.099 0.126 0.201 0.148 0.086 0.201 0.483 0.223 0.337 0.243 0.561 0.257 0.384 0.269 0.658 0.282 0.332 0.292 0.428 0.311 0.211 0.357 0.290 0.390 0.601 0.407 0.674 0.433 0.658 0.437 0.222 0.456 0.572 0.485 0.629 0.498 0.885 0.529 0.627 0.552 0.807 0.642 0.689 0.658 0.836 0.683 0.877 0.704 0.543 0.733 0.634 0.837 0.428 0.873 0.634 0.924 0.185 0.974 0.238 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.770 0.120 0.768 0.190 0.752 0.227 0.715 0.261 0.692 0.292 0.695 0.310 0.648 0.334 0.629 0.423 0.616 0.477 0.561 0.510 0.554 0.534 0.501 0.645 0.413 0.690 0.402 0.737 0.371 0.893 0.347 1.000 0.295) :duration dur :scaler (hz->radians 9780.0))) (gen1 (make-oscil)) (rnd (make-rand-interp 4000 (hz->radians 200)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (oscil gen1 (+ (env frqf) (rand-interp rnd))))))))) (wilsons-warbler-1 beg1 .046 (* .05 amp1)) (wilsons-warbler-1 (+ beg1 .147) .05 (* .1 amp1)) (let ((durs2 (vector 0.067 0.07 0.075 0.08 0.086 0.084 0.08 0.08 0.078)) (frqs2 (vector 1.0 1.0 0.95 0.93 1.0 1.0 1.0 1.0 0.95)) (amps2 (vector .2 .4 .7 1 1 .8 1 1 1))) (do ((i 0 (+ i 1))) ((= i 9)) (wilsons-warbler-2 (+ beg1 0.285 (* i .13)) (durs2 i) (frqs2 i) (* amp1 (amps2 i))))) (do ((i 0 (+ i 1))) ((= i 3)) (wilsons-warbler-3 (+ beg1 1.45 (* i 0.12)) (* amp1 .9)))) ;; (with-sound (:play #t) (wilsons-warbler 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Willow flycatcher (defanimal (willow-flycatcher beg amp) (let ((dur 0.65)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.016 0.054 0.026 0.142 0.033 0.292 0.043 0.228 0.056 0.240 0.088 0.162 0.107 0.218 0.125 0.105 0.130 0.019 0.196 0.012 0.208 0.053 0.215 0.031 0.221 0.086 0.223 0.711 0.228 0.828 0.231 0.760 0.237 0.978 0.242 0.679 0.245 0.966 0.250 0.272 0.253 0.177 0.262 0.131 0.264 0.000 0.405 0.000 0.417 0.069 0.426 0.174 0.431 0.402 0.435 0.301 0.445 0.338 0.452 0.240 0.460 0.000 0.501 0.000 0.504 0.159 0.509 0.069 0.519 0.096 0.521 0.228 0.524 0.000 0.536 0.000 0.539 0.336 0.541 0.103 0.547 0.449 0.550 0.157 0.554 0.000 0.557 0.086 0.560 0.419 0.562 0.169 0.565 0.000 0.567 0.066 0.568 0.174 0.569 0.419 0.572 0.123 0.574 0.027 0.576 0.167 0.577 0.537 0.582 0.056 0.583 0.237 0.584 0.564 0.588 0.211 0.590 0.051 0.592 0.232 0.594 0.515 0.595 0.179 0.597 0.041 0.599 0.177 0.601 0.426 0.603 0.153 0.606 0.029 0.609 0.172 0.612 0.395 0.614 0.029 0.617 0.169 0.620 0.412 0.623 0.024 0.625 0.148 0.628 0.375 0.631 0.022 0.634 0.148 0.636 0.336 0.640 0.031 0.644 0.150 0.646 0.348 0.650 0.041 0.654 0.165 0.655 0.338 0.659 0.039 0.664 0.165 0.665 0.336 0.668 0.058 0.671 0.260 0.674 0.162 0.677 0.321 0.680 0.218 0.682 0.343 0.684 0.167 0.696 0.265 0.702 0.348 0.708 0.326 0.716 0.385 0.720 0.520 0.727 0.451 0.731 0.561 0.738 0.267 0.745 0.321 0.750 0.108 0.772 0.118 0.782 0.167 0.792 0.282 0.802 0.409 0.811 0.257 0.816 0.083 0.833 0.069 0.852 0.103 0.863 0.152 0.867 0.250 0.877 0.047 0.929 0.091 0.938 0.054 0.953 0.027 0.986 0.039 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.174 0.042 0.324 0.074 0.339 0.111 0.390 0.130 0.453 0.190 0.831 0.210 0.780 0.225 0.605 0.227 0.504 0.240 0.489 0.248 0.453 0.251 0.346 0.262 0.165 0.412 0.155 0.422 0.230 0.430 0.288 0.435 0.334 0.448 0.337 0.456 0.395 0.458 0.467 0.503 0.402 0.506 0.235 0.513 0.213 0.520 0.240 0.524 0.443 0.537 0.441 0.540 0.298 0.544 0.262 0.547 0.298 0.553 0.443 0.558 0.453 0.561 0.324 0.563 0.508 0.570 0.324 0.573 0.511 0.577 0.329 0.581 0.482 0.585 0.332 0.590 0.479 0.594 0.332 0.598 0.467 0.602 0.320 0.606 0.453 0.611 0.300 0.615 0.443 0.620 0.291 0.623 0.450 0.628 0.262 0.631 0.438 0.637 0.259 0.640 0.436 0.646 0.264 0.649 0.436 0.655 0.257 0.659 0.438 0.664 0.247 0.668 0.407 0.673 0.264 0.679 0.400 0.683 0.291 0.702 0.298 0.716 0.334 0.721 0.397 0.728 0.370 0.733 0.402 0.738 0.438 0.742 0.375 0.748 0.249 0.755 0.232 0.766 0.264 0.785 0.295 0.797 0.310 0.801 0.354 0.803 0.426 0.808 0.361 0.815 0.203 0.824 0.184 0.834 0.225 0.852 0.254 0.861 0.293 0.867 0.349 0.881 0.157 0.889 0.155 0.895 0.184 0.913 0.206 0.926 0.257 0.930 0.310 0.946 0.136 0.956 0.123 0.969 0.169 0.987 0.208 1.000 0.262) :duration dur :scaler (hz->radians 10800.0))) (gen1 (make-polywave 0.0 '(1 .98 2 .005 3 .01 4 .005))) (gen2 (make-oscil)) (ampf2 (make-env '(0 0 .68 0 .9 1 1 1) :duration dur :scaler .2))) (do ((i start (+ i 1))) ((= i stop)) (let ((frq (env frqf))) (outa i (* (env ampf) (+ (polywave gen1 frq) (* (env ampf2) (oscil gen2 (* 2.0 frq))))))))))) ;; (with-sound (:play #t) (willow-flycatcher 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Black-necked stilt (defanimal (black-necked-stilt beg amp) (let ((dur 0.085)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.034 0.133 0.121 0.287 0.210 0.586 0.358 0.950 0.419 1.000 0.514 1.000 0.611 0.912 0.819 0.251 0.893 0.204 0.962 0.105 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.246 0.073 0.252 0.107 0.294 0.131 0.276 0.160 0.300 0.269 0.334 0.345 0.350 0.451 0.361 0.548 0.359 0.692 0.352 0.765 0.328 0.803 0.300 0.832 0.318 0.865 0.285 1.000 0.266) :duration dur :scaler (hz->radians (* 1/3 10100.0)))) (gen1 (make-polywave 0.0 (normalize-partials '(1 .05 2 .25 3 1 4 .5 5 .2 6 .01 8 .03 9 .03 10 .01 11 .005 12 .005)))) (gen2 (make-polywave 0.0 '(3 .03 5 .05 7 .1 9 .03 11 .04 13 .015 15 .01 17 .005 19 .005 21 .005 23 .005))) (ampf2 (make-env '(0 1 .2 .1 .3 1 .5 0 .7 0 1 .5) :duration dur)) (rnd (make-rand-interp 4000 (hz->radians 500))) (rndf (make-env '(0 1 .2 0 .9 0 1 1) :duration dur))) (do ((i start (+ i 1))) ((= i stop)) (let ((frq (+ (env frqf) (* (env rndf) (rand-interp rnd))))) (outa i (* (env ampf) (+ (polywave gen1 frq) (* (env ampf2) (polywave gen2 (* 0.5 frq))))))))))) ;; (with-sound (:play #t) (black-necked-stilt 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Bushtit (defanimal (bushtit beg amp) (let ((dur 0.368) (pulse-dur .044) (start (seconds->samples beg))) (let ((stop (seconds->samples (+ beg dur))) (frqf (make-env '(0 0 1 -1) :duration dur :scaler (hz->radians 500))) (pulse-spacing (seconds->samples .064)) (pulse-samps (seconds->samples pulse-dur))) (let ((pulse-ampf (make-env '(0.000 0.000 0.114 0.486 0.182 0.988 0.394 0.763 0.620 1.000 0.769 0.937 0.889 1.000 1.000 0.000) :duration pulse-dur :scaler amp)) (pulse-frqf (make-env '(0.000 0.230 0.109 0.291 0.212 0.322 0.298 0.343 0.410 0.348 0.654 0.357 0.821 0.354 0.889 0.337 0.952 0.304 1.000 0.231) :duration pulse-dur :scaler (hz->radians 22050.0))) (gen1 (make-polywave 0.0 '(1 .99 2 .01))) (gen2 (make-polywave 0.0 '(5 .9 7 .07 8 .02 9 .01 11 .02))) (pulse-ampf2 (make-env '(0 0 .65 0 .8 1 .9 1 1 0) :duration pulse-dur :scaler .4)) (pulse-frqf2 (make-env '(0 5400 .6 5400 .75 6300 1 5400) :duration pulse-dur :scaler (hz->radians 0.2) :base .1)) (first-stop (+ start pulse-samps))) (do ((i start (+ i 1))) ((= i first-stop)) (outa i (* (env pulse-ampf) (polywave gen1 (+ (env pulse-frqf) (env frqf)))))) (set! start (+ start pulse-spacing)) (mus-reset pulse-ampf) (mus-reset pulse-frqf) (do ((i start (+ i pulse-spacing))) ((>= i stop)) (let ((reset-stop (min stop (+ i pulse-samps)))) (do ((k i (+ k 1))) ((= k reset-stop)) (outa k (+ (* (env pulse-ampf) (polywave gen1 (+ (env pulse-frqf) (env frqf)))) (* (env pulse-ampf2) (polywave gen2 (env pulse-frqf2)))))) (mus-reset pulse-ampf) (mus-reset pulse-frqf) (mus-reset pulse-ampf2) (mus-reset pulse-frqf2))))))) ;; (with-sound (:play #t) (bushtit 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Red-breasted nuthatch (defanimal (red-breasted-nuthatch beg amp) (let ((dur 0.287)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.084 0.402 0.289 0.914 0.400 0.957 0.501 0.957 0.530 0.895 0.600 0.988 0.680 1.000 0.786 0.926 0.860 0.984 0.912 0.969 0.962 0.855 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.257 0.029 0.306 0.061 0.322 0.101 0.318 0.965 0.361 1.000 0.316) :duration dur :scaler (hz->radians (* 0.2 7510.0)))) (gen1 (make-polywave 0.0 '(1 .95 2 .03 3 .03))) (mod1 (make-oscil)) (index (hz->radians (* 510 1.25))) (rnd (make-rand-interp 100 (hz->radians 6)))) (do ((i start (+ i 1))) ((= i stop)) (let ((frq (+ (env frqf) (rand-interp rnd)))) (outa i (* (env ampf) (polywave gen1 (+ (* 5.0 frq) (* index (oscil mod1 frq))))))))))) ;; (with-sound (:play #t) (red-breasted-nuthatch 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; White-breasted nuthatch (defanimal (white-breasted-nuthatch beg amp) (let ((dur 0.31)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.157 0.871 0.386 1.000 0.728 0.759 0.951 0.306 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.318 0.045 0.392 0.160 0.418 0.254 0.418 0.517 0.404 0.816 0.367 1.000 0.310) :duration dur :scaler (hz->radians (* 0.25 8900)))) (gen1 (make-polywave 0.0 '(1 .96 2 .02 3 .03))) (gen2 (make-polywave 0.0 '(4 .005 5 .01))) (ampf2 (make-env '(0 1 .65 1 .75 0 1 0) :duration dur)) (mod1 (make-oscil)) (index (hz->radians (* 800 0.4))) (rnd (make-rand-interp 100 (hz->radians 16))) (vib (make-oscil 40.0)) (vib-index (hz->radians 50))) (do ((i start (+ i 1))) ((= i stop)) (let* ((vb (oscil vib)) (frq (+ (env frqf) (rand-interp rnd) (* vib-index vb))) (mfrq (+ (* 3.0 frq) (* index (oscil mod1 frq))))) (outa i (* (env ampf) (+ .7 (* .3 (abs vb))) (+ (polywave gen1 mfrq) (* (env ampf2) (polywave gen2 mfrq)))))))))) ;; (with-sound (:play #t) (white-breasted-nuthatch 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Pygmy nuthatch (defanimal (pygmy-nuthatch beg amp) (let ((dur 0.12)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.096 0.247 0.148 0.591 0.206 0.767 0.244 0.995 0.260 0.470 0.385 0.406 0.406 0.240 0.425 0.370 0.475 0.244 0.488 0.324 0.511 0.326 0.528 0.258 0.544 0.336 0.594 0.331 0.638 0.256 0.689 0.288 0.720 0.279 0.769 0.299 0.795 0.249 0.818 0.272 0.841 0.242 0.856 0.292 0.865 0.205 0.876 0.304 0.897 0.304 0.932 0.126 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.096 0.063 0.174 0.090 0.199 0.127 0.205 0.25 0.210 0.26 0.237 0.733 0.222 0.865 0.210 0.890 0.195 0.912 0.159 0.930 0.145 1.000 0.138) :duration dur :scaler (hz->radians 21500.0))) (gen1 (make-polywave 0.0 '(1 .98 2 .005 3 .01)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) ;; (with-sound (:play #t) (pygmy-nuthatch 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Flammulated owl (defanimal (flammulated-owl beg amp) (let ((dur 0.25)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.146 0.603 0.286 0.858 0.455 0.992 0.629 0.983 0.789 0.819 0.907 0.473 0.946 0.445 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0 340 .1 400 .15 410 .9 420 1 380) :duration dur :scaler (hz->radians 1.0))) (gen1 (make-polywave 0.0 '(1 .98 2 .01 3 .005)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) ;; (with-sound (:play #t) (flammulated-owl 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Song sparrow (define (song-sparrow beg1 amp1) (defanimal (song-sparrow-big-buzz beg amp) (let ((dur 0.25)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.106 0.826 0.190 0.996 0.418 0.818 0.688 0.458 0.897 0.447 0.962 0.348 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0 4400 .4 4200 1 4300) :duration dur :scaler (hz->radians 1.0))) (gen-up (make-polywave 0.0 (vector 1 .95 2 .03 3 .02))) (gen-down (make-polywave 0.0 (vector 1 .95 2 .03 3 .02))) (mod-up (make-oscil 142.0)) (mod-down (make-oscil 142.0)) (pulse-samps (seconds->samples (/ 1.0 142.0))) (ampf-up (make-env '(0 .1 .23 .01 .27 .01 .6 .5 .75 1 .8 .4 1 .1) :duration (/ 1.0 142.0))) (ampf-down (make-env '(0 .1 .2 .6 .25 1 .6 .1 .75 .001 1 .1) :duration (/ 1.0 142.0))) (ampf2 (make-env '(0 1 1 0) :duration dur :scaler 0.7)) (rnd (make-rand-interp 6000 (hz->radians 300))) (h700 (hz->radians 700.0)) (h800 (hz->radians 800.0)) (h600 (hz->radians -600.0))) (do ((i start (+ i pulse-samps))) ((>= i stop)) (set! (mus-location frqf) (- i start)) (set! (mus-location ampf) (- i start)) (set! (mus-location ampf2) (- i start)) (let ((reset-stop (min stop (+ i pulse-samps))) (pulse-amp (env ampf)) (pulse-amp2 (env ampf2)) (pulse-frq (env frqf))) (do ((k i (+ k 1))) ((= k reset-stop)) (let ((frq (+ pulse-frq (rand-interp rnd)))) (outa k (* pulse-amp (+ (* (env ampf-up) (polywave gen-up (+ frq h700 (* h800 (oscil mod-up))))) (* pulse-amp2 (env ampf-down) (polywave gen-down (+ frq h600 (* h800 (oscil mod-down)))))))))) (mus-reset ampf-up) (mus-reset ampf-down)))))) (defanimal (song-sparrow-clear-tone beg frq amp) (let ((dur 0.062)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.054 0.208 0.138 0.327 0.162 0.292 0.306 0.659 0.352 0.698 0.400 0.835 0.468 0.894 0.507 0.808 0.548 0.906 0.593 0.833 0.623 0.939 0.668 0.902 0.710 0.971 0.735 0.678 0.759 0.937 0.777 1.000 0.792 0.820 0.800 0.922 0.847 0.806 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.203 0.043 0.253 0.118 0.276 0.446 0.263 0.575 0.251 0.707 0.226 0.883 0.187 1.000 0.153) :duration dur :scaler (hz->radians (* frq 22050.0)))) (gen1 (make-polywave 0.0 '(1 .98 2 .005 3 .01)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) (defanimal (song-sparrow-sweep-tone beg amp) (let ((dur 0.036)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.048 0.158 0.098 0.474 0.201 0.574 0.235 0.206 0.357 0.206 0.419 0.366 0.468 0.331 0.489 0.173 0.519 0.579 0.567 0.639 0.604 0.972 0.647 0.556 0.697 0.391 0.75 0.0) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.358 0.033 0.355 0.060 0.321 0.078 0.240 0.098 0.214 0.120 0.257 0.153 0.364 0.187 0.420 0.242 0.428 0.289 0.418 0.348 0.390 0.465 0.381 0.531 0.360 0.571 0.338 0.609 0.306 0.668 0.246 0.75 0.223) :duration dur :scaler (hz->radians 22050.0))) (gen1 (make-polywave 0.0 '(1 .95 2 .05)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) (defanimal (song-sparrow-sweep-caw beg amp) (let ((dur 0.025)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.155 0.364 0.185 0.154 0.242 0.542 0.283 0.526 0.321 0.660 0.386 0.846 0.451 0.292 0.481 1.000 0.546 0.881 0.584 0.676 0.636 0.798 0.685 0.269 0.755 0.640 0.791 0.316 0.957 0.115 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.210 0.170 0.232 0.187 0.164 0.453 0.212 0.462 0.159 0.668 0.201 0.699 0.147 0.905 0.181 1.000 0.164) :duration dur :scaler (* .5 (hz->radians 22050.0)))) (gen (make-polywave 0.0 '(2 .92 3 .02 4 .01 5 .005))) (rnd (make-rand-interp 4000 (hz->radians 500)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen (+ (env frqf) (rand-interp rnd))))))))) (defanimal (song-sparrow-little-buzz beg amp) (let ((dur 0.17)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0 0 1 1 2 1 4 0) :duration dur :scaler amp)) (frqf (make-env '(0 0 1 1) :duration dur :scaler (hz->radians 20))) (gen (make-polywave 610.0 (normalize-partials '(3 .4 4 1 5 .01 6 .2 7 .03 8 .02 9 .01 10 .01 11 .01 12 .005)))) (rnd (make-rand-interp 4000 (hz->radians 50))) (tri (make-triangle-wave 60 0.6))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (+ .4 (abs (triangle-wave tri))) (polywave gen (+ (env frqf) (rand-interp rnd))))))))) (defanimal (song-sparrow-sweep-down beg amp) (let ((dur 0.186)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.125 0.212 0.164 1.000 0.206 0.218 0.231 0.278 0.243 0.470 0.273 0.136 0.301 0.419 0.311 0.691 0.329 0.530 0.341 0.501 0.354 0.295 0.373 0.382 0.383 0.193 0.397 0.232 0.403 0.127 0.415 0.238 0.426 0.173 0.433 0.238 0.452 0.088 0.528 0.286 0.552 0.150 0.564 0.309 0.590 0.133 0.608 0.303 0.635 0.204 0.659 0.215 0.673 0.275 0.709 0.380 0.718 0.292 0.727 0.354 0.749 0.235 0.800 0.139 0.831 0.153 0.853 0.232 0.886 0.130 0.911 0.337 0.932 0.147 0.949 0.224 0.965 0.082 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0 9000 .08 7900 .164 7385 .2 7000 1 6960) :duration dur :scaler (hz->radians 1.0))) (gen1 (make-polywave 0.0 '(1 .95 2 .05)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) (defanimal (song-sparrow-sweep-up beg amp) (let ((dur 0.076)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0 0 1 1 2 1 3 0) :base .1 :duration dur :scaler amp)) (frqf (make-env '(0 2260 .3 3000 .9 3100 1 3300) :duration dur :scaler (hz->radians 1.0))) (gen1 (make-polywave 0.0 '(1 .98 2 .005 3 .01 4 .005)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) (defanimal (song-sparrow-2nd-buzz beg amp) (let ((dur 0.053)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.101 0.110 0.174 0.229 0.206 0.229 0.220 0.153 0.231 0.285 0.263 0.449 0.293 0.424 0.315 0.698 0.374 0.661 0.416 0.884 0.554 0.785 0.587 0.661 0.600 0.037 0.608 0.859 0.685 0.554 0.692 0.034 0.705 0.734 0.729 0.602 0.741 0.079 0.753 0.695 0.787 0.737 0.803 0.110 0.813 0.520 0.841 0.757 0.868 0.085 0.882 0.398 0.899 0.514 0.922 0.172 0.952 0.280 0.962 0.150 0.993 0.198 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0 3100 .4 3430 1 3140) :duration dur :offset (hz->radians 40) :scaler (hz->radians 0.5))) (gen1 (make-polywave 0.0 '(1 .1 2 .5 3 .2 4 .1 6 .05 8 .03))) (vib (make-blackman 320 4)) (scl (hz->radians 200))) (do ((i start (+ i 1))) ((= i stop)) (let ((vb (blackman vib))) (outa i (* (env ampf) (+ .4 (* .6 vb)) (polywave gen1 (+ (env frqf) (* scl vb)))))))))) (defanimal (song-sparrow-chiff beg amp) (let ((dur 0.019)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0 0 1 1 2 0) :duration dur :scaler amp)) (frqf (make-env '(0 4800 .4 5500 .6 6060 .9 4200 1 4100) :duration dur :scaler (hz->radians 0.32))) (gen1 (make-polywave 0.0 '(3 .7 4 .3 7 .01)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) (song-sparrow-little-buzz beg1 (* .25 amp1)) (song-sparrow-clear-tone (+ beg1 0.2) 1.0 (* 0.9 amp1)) (song-sparrow-little-buzz (+ beg1 .37) (* .4 amp1)) (song-sparrow-clear-tone (+ beg1 0.57) 1.0 amp1) (let ((amps (vector .14 .33 .37 .37 .30 .30 .30))) (do ((i 0 (+ i 1)) (x 0.68 (+ x .1))) ((= i 7)) (song-sparrow-sweep-tone (+ beg1 x) (* (amps i) amp1)) (song-sparrow-sweep-caw (+ beg1 x .05) (* 0.5 amp1)))) (song-sparrow-sweep-tone (+ beg1 1.37) (* .27 amp1)) (song-sparrow-big-buzz (+ beg1 1.44) (* 0.75 amp1)) (song-sparrow-2nd-buzz (+ 1.73 beg1) (* .25 amp1)) (song-sparrow-sweep-up (+ 1.8 beg1) (* .5 amp1)) (song-sparrow-chiff (+ 1.92 beg1) (* .3 amp1)) (song-sparrow-sweep-down (+ beg1 1.96) (* .3 amp1)) (song-sparrow-clear-tone (+ beg1 2.22) 0.86 (* .8 amp1))) ;; (with-sound (:play #t) (song-sparrow 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Burrowing owl (defanimal (burrowing-owl beg amp) (let ((dur 0.6)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.038 0.510 0.060 0.743 0.082 0.822 0.114 0.775 0.125 0.692 0.204 0.000 0.416 0.000 0.465 0.858 0.500 1.000 0.571 0.921 0.611 0.937 0.927 0.526 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.029 0.035 0.108 0.045 0.133 0.091 0.135 0.129 0.132 0.176 0.107 0.190 0.043 0.424 0.046 0.446 0.110 0.468 0.133 0.75 .133 0.8 .129 0.936 0.127 0.973 0.104 1.000 0.035) :duration dur :scaler (hz->radians 6800.0))) (rnd (make-rand-interp 200 (hz->radians 5))) (gen1 (make-polywave 0.0 '(1 .92 2 .08))) (gen2 (make-polywave 0.0 '(3 .01 4 .01 6 .005 7 .007 8 .002 9 .002 10 .002 12 .001))) (ampf2 (make-env '(0 0 .05 0 .09 1 .13 1 .2 0 .45 0 .5 1 .9 1 1 0) :duration dur)) (gen3 (make-oscil)) (ampf3 (make-env '(0 0 .08 0 .12 .4 .2 0 .46 0 .5 .5 .6 0 .65 0 .8 1 .9 1 1 0) :duration dur :scaler .015))) (do ((i start (+ i 1))) ((= i stop)) (let ((frq (+ (env frqf) (rand-interp rnd)))) (outa i (* (env ampf) (+ (polywave gen1 frq) (* (env ampf2) (polywave gen2 frq)) (* (env ampf3) (oscil gen3 (* 5.0 frq))))))))))) ;; (with-sound (:play #t) (burrowing-owl 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Gray vireo ;;; ;;; (I didn't really intend to do 5 of these calls) (defanimal (gray-vireo-1 beg amp) (let ((dur 0.23)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.059 0.052 0.078 0.132 0.085 0.076 0.099 0.100 0.108 0.260 0.125 0.102 0.134 0.280 0.143 0.254 0.146 0.306 0.158 0.197 0.184 0.403 0.193 0.403 0.201 0.180 0.208 0.239 0.217 0.375 0.222 0.000 0.229 0.232 0.237 0.158 0.254 0.800 0.263 0.846 0.307 0.785 0.322 0.850 0.334 1.000 0.350 0.731 0.357 0.822 0.369 0.599 0.378 0.711 0.384 0.375 0.389 0.688 0.393 0.315 0.396 0.657 0.410 0.291 0.419 0.414 0.491 0.412 0.566 0.258 0.593 0.06 0.659 0.01 0.754 0.06 0.772 0.245 0.854 0.523 0.892 0.330 0.932 0.436 0.947 0.182 0.957 0.228 0.981 0.063 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.203 0.033 0.198 0.051 0.218 0.064 0.189 0.085 0.226 0.101 0.187 0.116 0.214 0.133 0.183 0.199 0.172 0.216 0.186 0.242 0.288 0.256 0.330 0.297 0.330 0.324 0.316 0.441 0.243 0.506 0.215 0.556 0.206 0.690 0.107 0.721 0.104 0.739 0.136 0.769 0.215 0.796 0.266 0.833 0.282 1.000 0.29) :duration dur :scaler (hz->radians 10250.0))) (gen1 (make-oscil)) (gen2 (make-oscil)) (interpf (make-env '(0 .5 .2 .1 .25 .99 .6 .95 .7 .3 .75 .99 1 .99) :duration dur)) (interpf-1 (make-env '(0 .5 .2 .1 .25 .99 .6 .95 .7 .3 .75 .99 1 .99) :duration dur :offset 1.0 :scaler -1.0))) (do ((i start (+ i 1))) ((= i stop)) (let ((frq (env frqf))) (outa i (* (env ampf) (+ (* (env interpf) (oscil gen1 frq)) (* (env interpf-1) (oscil gen2 (* 2.0 frq))))))))))) ;; (with-sound (:play #t) (gray-vireo-1 0 .5)) (defanimal (gray-vireo-2 beg amp) ;; probably calif2 18 4 (let ((dur 0.23)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.026 0.099 0.067 0.176 0.097 0.111 0.110 0.199 0.147 0.096 0.186 0.110 0.214 0.068 0.228 0.113 0.245 0.069 0.254 0.097 0.264 0.209 0.274 0.143 0.291 0.096 0.301 0.250 0.315 0.347 0.332 0.166 0.343 0.144 0.353 0.369 0.364 0.446 0.371 0.429 0.390 0.196 0.403 0.383 0.411 0.495 0.434 0.372 0.442 0.192 0.456 0.449 0.471 0.364 0.479 0.505 0.486 0.487 0.492 0.413 0.500 0.455 0.509 0.323 0.515 0.361 0.519 0.212 0.524 0.259 0.529 0.469 0.548 0.549 0.562 0.235 0.565 0.316 0.576 0.385 0.582 0.488 0.594 0.493 0.600 0.402 0.612 0.355 0.616 0.414 0.624 0.306 0.636 0.289 0.641 0.223 0.648 0.349 0.655 0.287 0.674 0.325 0.682 0.270 0.691 0.133 0.712 0.275 0.726 0.319 0.743 0.578 0.765 0.722 0.776 0.651 0.796 1.000 0.808 0.686 0.816 0.556 0.825 0.826 0.833 0.527 0.835 0.725 0.848 0.281 0.855 0.639 0.861 0.405 0.863 0.485 0.869 0.250 0.871 0.414 0.876 0.193 0.882 0.468 0.886 0.443 0.894 0.141 0.897 0.312 0.901 0.181 0.903 0.435 0.907 0.339 0.910 0.432 0.937 0.399 0.949 0.234 0.974 0.243 0.993 0.159 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.260 0.040 0.245 0.091 0.203 0.122 0.174 0.152 0.221 0.174 0.240 0.190 0.297 0.211 0.232 0.227 0.284 0.248 0.250 0.261 0.331 0.289 0.260 0.304 0.333 0.321 0.336 0.337 0.286 0.356 0.349 0.371 0.346 0.386 0.299 0.406 0.359 0.422 0.359 0.439 0.307 0.460 0.383 0.474 0.380 0.489 0.352 0.513 0.414 0.533 0.378 0.546 0.385 0.564 0.432 0.582 0.383 0.598 0.393 0.609 0.435 0.678 0.430 0.719 0.466 0.780 0.518 0.821 0.560 0.856 0.620 0.922 0.677 1.000 0.701) :duration dur :scaler (hz->radians 6030.0))) (gen1 (make-oscil)) (gen2 (make-oscil)) (gen3 (make-oscil)) (interpf (make-env '(0 .1 .2 .1 .3 .99 1 .99) :duration dur)) (interpf-1 (make-env '(0 .1 .2 .1 .3 .99 1 .99) :duration dur :offset 1.0 :scaler -0.5))) (do ((i start (+ i 1))) ((= i stop)) (let ((frq (env frqf))) (outa i (* (env ampf) (+ (* (env interpf) (oscil gen1 frq)) (* (env interpf-1) (+ (oscil gen2 (* 2.0 frq)) (oscil gen3 (* 3.0 frq)))))))))))) ;; (with-sound (:play #t) (gray-vireo-2 0 .5)) (defanimal (gray-vireo-3 beg amp) ;; south 44 4 ;; part 1 -- I could not find a way to get this right short of brute force additive synthesis (let ((dur 0.1)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.167 0.561 0.210 0.243 0.245 0.298 0.272 0.793 0.437 0.171 0.572 0.296 0.604 0.202 0.734 0.599 0.759 0.597 0.829 0.425 0.881 0.843 1.000 0.000) :duration dur :scaler (* 0.2 amp))) (frqf (make-env '(0.000 0.260 0.060 0.301 0.100 0.371 0.151 0.442 0.191 0.465 0.251 0.447 0.313 0.365 0.381 0.266 0.458 0.228 0.546 0.231 0.632 0.243 0.708 0.275 0.792 0.310 0.855 0.339 0.899 0.389 0.934 0.404 0.964 0.398 1.000 0.363) :duration dur :scaler (hz->radians (* 1/3 11500.0)))) (ampfs (make-vector 5))) (set! (ampfs 0) (make-env '(0.000 0.000 0.061 0.000 0.201 0.997 0.278 0.997 0.441 0.000 0.662 0.000 0.783 0.456 0.864 0.459 0.970 0.000 1.000 0.000) :duration dur :scaler .1)) (set! (ampfs 1) (make-env '(0.000 0.000 0.153 0.639 0.307 0.639 0.457 0.109 0.617 0.107 0.739 1.000 0.913 1.000 1.000 0.298) :duration dur :scaler .4)) (set! (ampfs 2) (make-env '(0.000 0.000 0.190 0.842 0.266 0.514 0.297 1.000 0.456 0.257 0.599 0.260 0.670 0.702 0.707 0.579 0.739 0.710 0.808 0.325 0.865 0.519 1.000 0.402) :duration dur :scaler .2)) (set! (ampfs 3) (make-env '(0.000 0.000 0.064 0.077 0.157 0.653 0.255 0.699 0.311 0.995 0.352 0.615 0.389 0.986 0.458 0.178 0.667 0.363 0.750 0.000 1.000 0.000) :duration dur :scaler .07)) (set! (ampfs 4) (make-env '(0.000 0.000 0.159 0.995 0.314 0.997 0.598 0.000 1.000 0.000) :duration dur :scaler .01)) (let ((frqs (make-float-vector 5 0.0)) (amps (make-float-vector 5 0.0))) (let ((obank (make-oscil-bank frqs (make-float-vector 5 0.0) amps))) (do ((i start (+ i 1))) ((= i stop)) (let ((frq (env frqf))) (do ((k 0 (+ k 1)) (f frq (+ f frq))) ((= k 5)) (set! (amps k) (env (vector-ref ampfs k))) (set! (frqs k) f)) (outa i (* (env ampf) (oscil-bank obank))))))))) ;; part 2 (let ((dur 0.137)) (let ((start (seconds->samples (+ beg 0.1))) (stop (seconds->samples (+ beg 0.1 dur))) (ampf (make-env '(0.000 0.000 0.042 0.123 0.086 0.399 0.155 0.626 0.176 0.169 0.190 0.691 0.205 0.877 0.224 0.552 0.246 0.828 0.274 0.978 0.319 0.937 0.356 0.893 0.410 0.866 0.461 0.956 0.565 0.784 0.622 0.311 0.648 0.423 0.671 0.279 0.688 0.096 0.705 0.328 0.713 0.284 0.725 0.096 0.807 0.254 0.844 0.134 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.493 0.034 0.542 0.048 0.550 0.066 0.515 0.102 0.485 0.151 0.463 0.168 0.431 0.181 0.455 0.198 0.450 0.216 0.436 0.232 0.439 0.444 0.439 0.572 0.444 0.703 0.463 0.800 0.472 1.000 0.458) :duration dur :scaler (hz->radians 7300.0))) (gen1 (make-polywave 0.0 '(1 .95 2 .01 3 .02 4 .005)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) ;; (with-sound (:play #t) (gray-vireo-3 0 .5)) (defanimal (gray-vireo-4 beg amp) (let ((dur 0.23)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.081 0.163 0.123 0.184 0.185 0.447 0.204 0.081 0.230 0.626 0.245 0.607 0.271 0.398 0.293 0.130 0.305 0.347 0.326 0.444 0.339 0.279 0.349 0.382 0.366 0.751 0.388 0.347 0.405 0.965 0.417 0.783 0.435 0.992 0.452 0.737 0.471 0.916 0.523 0.702 0.534 0.526 0.543 0.770 0.563 0.496 0.581 0.558 0.625 0.393 0.646 0.439 0.712 0.388 0.761 0.455 0.832 0.141 0.845 0.081 0.875 0.106 0.911 0.068 0.959 0.154 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.534 0.054 0.509 0.089 0.480 0.128 0.447 0.168 0.477 0.195 0.531 0.224 0.661 0.240 0.507 0.278 0.350 0.304 0.295 0.319 0.333 0.334 0.409 0.352 0.369 0.370 0.442 0.398 0.431 0.414 0.504 0.485 0.493 0.563 0.458 0.621 0.431 0.697 0.423 0.814 0.409 1.000 0.420) :duration dur :scaler (hz->radians 6230.0))) (gen1 (make-polywave 0.0 '(1 .98 2 .003 3 .007))) (ampf1 (make-env '(0 0 .22 0 .23 1 1 1) :duration dur)) (gen2 (make-polywave 0.0 '(1 .05 2 .9 3 .1 4 .07))) (ampf2 (make-env '(0 1 .2 1 .22 0 1 0) :duration dur))) (do ((i start (+ i 1))) ((= i stop)) (let ((frq (env frqf))) (outa i (* (env ampf) (+ (* (env ampf1) (polywave gen1 frq)) (* (env ampf2) (polywave gen2 (* 0.5 frq))))))))))) ;; (with-sound (:play #t) (gray-vireo-4 0 .5)) (defanimal (gray-vireo-5 beg amp) (let ((dur 0.256)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.010 0.160 0.025 0.133 0.044 0.301 0.060 0.314 0.072 0.724 0.085 0.678 0.088 0.374 0.106 0.634 0.114 0.930 0.127 0.718 0.141 1.000 0.175 0.233 0.220 0.528 0.244 0.496 0.270 0.648 0.320 0.564 0.353 0.393 0.376 0.667 0.443 0.623 0.493 0.447 0.524 0.474 0.570 0.287 0.583 0.320 0.682 0.117 0.856 0.079 0.933 0.057 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.371 0.029 0.393 0.047 0.428 0.074 0.425 0.097 0.333 0.116 0.206 0.149 0.168 0.192 0.190 0.242 0.214 0.314 0.217 0.437 0.198 0.876 0.165 1.000 0.146) :duration dur :scaler (hz->radians 11150.0))) (gen1 (make-polywave 0.0 '(1 .98 2 .01 4 .005))) (ampf1 (make-env '(0 1 .09 1 .14 .1 .2 1 .6 .8 .9 .8 1 1) :duration dur)) (gen2 (make-oscil)) (ampf2 (make-env '(0 0 .09 0 .14 1 .18 1 .23 0 .6 0 .7 .4 1 0) :duration dur :scaler .5)) (gen3 (make-oscil)) (ampf3 (make-env '(0 0 .2 0 .25 1 .5 1 .6 0 1 0) :duration dur :scaler .01))) (do ((i start (+ i 1))) ((= i stop)) (let ((frq (env frqf))) (outa i (* (env ampf) (+ (* (env ampf1) (polywave gen1 frq)) (* (env ampf2) (oscil gen2 (* frq 2))) (* (env ampf3) (oscil gen3 (* frq 3))))))))))) ;; (with-sound (:play #t) (gray-vireo-5 0 .5)) (define (gray-vireo beg amp) (gray-vireo-3 beg amp) (gray-vireo-4 (+ beg 1.1) amp) (gray-vireo-5 (+ beg 2.1) amp)) ;; (with-sound (:play #t) (gray-vireo 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Bald eagle (define (bald-eagle beg amp) (defanimal (bald-eagle-1 beg amp) (let ((dur 0.153)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.016 0.145 0.042 0.773 0.084 0.471 0.097 0.265 0.112 0.124 0.123 0.297 0.134 0.937 0.151 0.665 0.166 0.810 0.194 0.733 0.228 0.218 0.244 0.059 0.269 0.373 0.280 0.621 0.292 0.597 0.314 0.681 0.368 0.241 0.389 0.332 0.411 0.688 0.431 0.674 0.447 0.539 0.477 0.452 0.517 0.572 0.534 0.550 0.555 0.455 0.576 0.457 0.597 0.494 0.613 0.391 0.630 0.073 0.648 0.164 0.671 0.119 0.680 0.014 0.700 0.077 0.737 0.045 0.757 0.075 0.803 0.024 0.817 0.065 0.855 0.028 0.866 0.063 0.906 0.033 0.973 0.042 1.000 0.000) :duration dur :scaler amp)) (frqf1 (make-env '(0.000 0.268 0.042 0.273 0.132 0.280 0.281 0.280 0.409 0.273 0.609 0.282 0.686 0.289 1.000 0.273) :duration dur :scaler (hz->radians 10000.0))) (frqf2 (make-env '(0.000 0.541 0.050 0.543 0.130 0.555 0.202 0.559 0.271 0.568 0.413 0.534 0.522 0.543 0.586 0.559 0.638 0.582 0.706 0.566 0.791 0.539 0.852 0.516 0.922 0.466 0.962 0.400 1.000 0.309) :duration dur :scaler (hz->radians 10000.0))) (gen1 (make-polywave 0.0 '(1 .98 3 .02))) (gen2 (make-polywave 0.0 '(1 .95 2 .05))) (intrpf (make-env '(0 .9 .6 .9 .7 .5 1 .5) :duration dur)) (intrpf-1 (make-env '(0 .9 .6 .9 .7 .5 1 .5) :duration dur :offset 1.0 :scaler -1.0)) (rnd (make-rand-interp 2000 )) (rndf (make-env '(0 0 .02 0 .04 1 .06 0 .13 0 .135 1 .14 0 .27 0 .276 1 .28 0 .4 0 .405 1 .41 0 .678 0 .682 1 1 1) :duration dur :offset (hz->radians 40) :scaler (hz->radians 100)))) (do ((i start (+ i 1))) ((= i stop)) (let ((noise (* (env rndf) (rand-interp rnd)))) (outa i (* (env ampf) (+ (* (env intrpf) (polywave gen1 (+ (env frqf1) noise))) (* (env intrpf-1) (polywave gen2 (+ (env frqf2) (* 2.0 noise)))))))))))) (defanimal (bald-eagle-2 beg amp) (let ((dur 0.074)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.045 0.084 0.073 0.223 0.176 0.395 0.207 1.000 0.245 0.616 0.276 0.093 0.301 0.325 0.349 0.316 0.396 0.211 0.445 0.075 0.643 0.145 0.777 0.170 0.804 0.291 0.848 0.164 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.752 0.065 0.617 0.116 0.597 0.140 0.513 0.158 0.420 0.177 0.273 0.255 0.285 0.351 0.285 0.393 0.285 0.467 0.287 0.518 0.293 0.582 0.301 0.638 0.163 0.690 0.225 0.752 0.282 0.800 0.262 0.875 0.268 1.000 0.290) :duration dur :scaler (hz->radians 10100.0))) (gen1 (make-polywave 0.0 '(1 .99 2 .01))) (rnd (make-rand-interp 2000)) (rndf (make-env '(0 0 .16 0 .25 1 1 .5) :duration dur :offset (hz->radians 100) :scaler (hz->radians 500)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (+ (env frqf) (* (env rndf) (rand-interp rnd)))))))))) (defanimal (bald-eagle-3 beg amp) (let ((dur 0.074)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.048 0.225 0.130 0.273 0.170 0.507 0.190 1.000 0.204 0.775 0.259 0.761 0.318 0.349 0.361 0.501 0.447 0.045 0.476 0.375 0.539 0.476 0.560 0.679 0.593 0.670 0.613 0.583 0.668 0.028 0.684 0.177 0.727 0.068 0.741 0.400 0.766 0.504 0.784 0.372 0.826 0.400 0.857 0.318 0.879 0.085 0.937 0.045 0.979 0.073 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.449 0.076 0.410 0.122 0.325 0.150 0.195 0.190 0.195 0.255 0.198 0.371 0.198 0.436 0.198 0.465 0.215 0.521 0.203 0.745 0.198 1.000 0.195) :duration dur :scaler (hz->radians 14000.0))) (gen1 (make-polywave 0.0 '(1 .99 3 .01))) (gen2 (make-polywave 0.0 '(1 .9 2 .1))) (ampf2 (make-env '(0 0 .2 0 .25 1 .3 1 .35 0 .5 0 .55 1 .6 1 .65 0 .75 0 .8 .5 .9 0 1 0) :scaler .1 :duration dur)) (rnd (make-rand-interp 2000 (hz->radians 200)))) (do ((i start (+ i 1))) ((= i stop)) (let ((frq (+ (env frqf) (rand-interp rnd)))) (outa i (* (env ampf) (+ (polywave gen1 frq) (* (env ampf2) (polywave gen2 (* 2.0 frq))))))))))) (defanimal (bald-eagle-4 beg frqscl amp) (let ((dur 0.056)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.079 0.116 0.125 0.198 0.154 0.867 0.190 0.994 0.214 0.743 0.260 0.867 0.282 0.802 0.315 0.825 0.330 0.636 0.371 0.678 0.423 0.825 0.468 0.734 0.504 0.542 0.549 0.619 0.595 0.960 0.637 0.686 0.669 0.130 0.772 0.418 0.823 0.147 0.890 0.056 0.929 0.090 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.215 0.035 0.243 0.060 0.285 0.086 0.268 0.121 0.198 0.135 0.137 0.154 0.167 0.218 0.186 0.880 0.181 1.000 0.192) :duration dur :scaler (hz->radians (* frqscl 13920)))) (gen1 (make-polywave 0.0 '(1 .96 2 .04 3 .007 4 .002))) (rnd (make-rand-interp 4000 (hz->radians 100)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (+ (env frqf) (rand-interp rnd))))))))) (bald-eagle-1 beg (* amp .8)) (bald-eagle-2 (+ beg .195) (* amp .7)) (bald-eagle-3 (+ beg .32) (* amp .7)) (bald-eagle-4 (+ beg .47) 1.1 amp) (bald-eagle-4 (+ beg .63) 1.05 amp) (bald-eagle-4 (+ beg .806) 1.0 amp)) ;; (with-sound (:play #t) (bald-eagle 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Eastern meadowlark (defanimal (eastern-meadowlark beg amp) (let ((dur 1.65)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.011 0.304 0.022 0.310 0.032 0.162 0.039 0.000 0.121 0.000 0.136 0.148 0.145 0.138 0.152 0.184 0.170 0.430 0.188 0.406 0.213 0.556 0.244 0.700 0.273 0.999 0.280 0.992 0.293 0.000 0.335 0.000 0.341 0.169 0.356 0.786 0.369 0.941 0.389 0.689 0.399 0.622 0.430 0.515 0.480 0.426 0.494 0.000 0.518 0.000 0.524 0.383 0.528 0.017 0.540 0.446 0.549 0.000 0.585 0.000 0.591 0.113 0.610 0.134 0.631 0.175 0.644 0.261 0.656 0.212 0.665 0.282 0.680 0.196 0.691 0.233 0.702 0.182 0.715 0.226 0.726 0.281 0.733 0.268 0.747 0.370 0.753 0.328 0.760 0.450 0.767 0.402 0.770 0.469 0.777 0.412 0.795 0.714 0.812 0.515 0.825 0.444 0.839 0.250 0.843 0.015 0.852 0.295 0.856 0.254 0.858 0.045 0.863 0.008 0.867 0.075 0.870 0.279 0.878 0.304 0.891 0.189 0.910 0.115 0.932 0.068 0.960 0.034 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.197 0.051 0.192 0.097 0.437 0.129 0.421 0.201 0.371 0.285 0.332 0.325 0.343 0.341 0.358 0.386 0.269 0.410 0.245 0.481 0.231 0.524 0.229 0.533 0.214 0.557 0.214 0.576 0.231 0.579 0.725 0.588 0.710 0.594 0.635 0.606 0.596 0.644 0.509 0.724 0.439 0.756 0.397 0.800 0.297 0.825 0.264 0.851 0.271 0.870 0.275 0.892 0.214 0.925 0.194 1.000 0.197) :duration dur :scaler (hz->radians 10280.0))) (gen1 (make-polywave 0.0 '(1 .98 2 .005 3 .01 4 .005 5 .002))) (buzz (make-oscil 350)) (buzzf (make-env '(0 0 .59 0 .6 1 .61 1 .64 0 1 0) :duration dur :scaler (hz->radians 300)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (+ (env frqf) (* (env buzzf) (oscil buzz)))))))))) ;; (with-sound (:play #t) (eastern-meadowlark 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Yellow-green vireo (defanimal (yellow-green-vireo beg amp) ;; south 48 3.5 (let ((dur 0.22)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.054 0.070 0.083 0.403 0.109 0.142 0.137 0.558 0.155 0.682 0.173 0.408 0.183 0.915 0.213 0.879 0.236 1.000 0.290 0.938 0.309 0.257 0.311 0.800 0.321 0.384 0.329 0.607 0.337 0.117 0.345 0.930 0.357 0.155 0.390 0.329 0.395 0.486 0.418 0.359 0.436 0.274 0.493 0.384 0.518 0.363 0.529 0.276 0.542 0.471 0.567 0.490 0.573 0.361 0.587 0.618 0.595 0.380 0.600 0.722 0.609 0.365 0.622 0.845 0.652 0.193 0.665 0.913 0.715 0.713 0.731 0.837 0.745 0.486 0.753 0.826 0.764 0.713 0.780 0.204 0.787 0.437 0.799 0.053 0.816 0.255 0.859 0.501 0.885 0.735 0.910 0.378 0.924 0.724 0.958 0.098 0.966 0.197 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.310 0.043 0.321 0.074 0.470 0.095 0.523 0.113 0.544 0.138 0.513 0.170 0.451 0.224 0.413 0.291 0.418 0.314 0.451 0.330 0.392 0.348 0.340 0.369 0.298 0.392 0.278 0.442 0.262 0.515 0.266 0.574 0.295 0.617 0.338 0.647 0.380 0.672 0.418 0.692 0.439 0.738 0.454 0.793 0.464 0.843 0.464 0.890 0.477 0.923 0.490 0.955 0.494 0.978 0.475 1.000 0.433) :duration dur :scaler (hz->radians 10000.0))) (gen1 (make-polywave 0.0 '(1 .98 2 .003 3 .02)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) ;; (with-sound (:play #t) (yellow-green-vireo 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Magnolia warbler (defanimal (magnolia-warbler beg amp) ;; east 13 3 (let ((dur 0.96)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.018 0.030 0.034 0.085 0.060 0.000 0.071 0.040 0.087 0.058 0.105 0.137 0.110 0.027 0.118 0.000 0.176 0.000 0.211 0.076 0.226 0.218 0.229 0.366 0.240 0.419 0.252 0.088 0.261 0.000 0.300 0.000 0.321 0.391 0.325 0.340 0.330 0.490 0.336 0.516 0.338 0.482 0.342 0.620 0.344 0.364 0.346 0.600 0.357 0.562 0.365 0.000 0.370 0.059 0.384 0.542 0.387 0.484 0.393 0.626 0.406 0.788 0.422 0.000 0.458 0.000 0.474 0.186 0.490 0.246 0.498 0.275 0.511 0.541 0.513 0.475 0.526 0.917 0.536 0.633 0.539 0.698 0.554 0.000 0.593 0.000 0.610 0.414 0.613 0.794 0.617 0.689 0.619 0.847 0.625 0.942 0.628 0.480 0.631 0.904 0.636 0.814 0.653 0.000 0.657 0.083 0.671 0.768 0.675 0.655 0.679 0.801 0.686 0.999 0.695 0.818 0.704 0.000 0.734 0.000 0.750 0.657 0.756 0.797 0.762 0.750 0.768 0.581 0.772 0.970 0.778 0.869 0.783 0.710 0.789 0.573 0.796 0.549 0.805 0.251 0.807 0.524 0.816 0.199 0.823 0.257 0.831 0.541 0.841 0.565 0.847 0.847 0.852 0.653 0.856 0.511 0.861 0.429 0.866 0.472 0.871 0.285 0.876 0.463 0.882 0.216 0.887 0.387 0.891 0.311 0.895 0.369 0.902 0.301 0.905 0.359 0.912 0.326 0.915 0.410 0.919 0.369 0.924 0.394 0.925 0.357 0.932 0.398 0.952 0.277 0.973 0.064 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.530 0.020 0.591 0.048 0.447 0.055 0.754 0.073 0.660 0.101 0.579 0.108 0.519 0.180 0.349 0.196 0.348 0.212 0.359 0.223 0.440 0.233 0.499 0.243 0.414 0.258 0.268 0.287 0.268 0.297 0.523 0.306 0.532 0.317 0.558 0.328 0.575 0.341 0.512 0.353 0.458 0.365 0.773 0.379 0.660 0.392 0.606 0.411 0.543 0.455 0.353 0.495 0.353 0.524 0.486 0.540 0.386 0.553 0.272 0.571 0.274 0.588 0.471 0.605 0.518 0.620 0.551 0.642 0.425 0.650 0.739 0.673 0.628 0.687 0.562 0.700 0.536 0.740 0.433 0.768 0.527 0.800 0.702 0.804 0.636 0.811 0.516 0.821 0.421 0.833 0.490 0.845 0.532 0.855 0.621 0.870 0.702 0.875 0.638 0.888 0.455 1.000 0.301) :duration dur :scaler (hz->radians 10000.0))) (gen1 (make-polywave 0.0 '(1 .98 2 .005 3 .01)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) ;; (with-sound (:play #t) (magnolia-warbler 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Eastern bluebird (define (eastern-bluebird beg1 amp1) ;; east 75 10 (defanimal (eastern-bluebird-1 beg amp) (let ((dur 0.285)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.067 0.103 0.083 0.145 0.134 0.636 0.152 0.615 0.197 0.872 0.238 1.000 0.272 1.000 0.298 0.842 0.340 0.889 0.415 0.820 0.455 0.194 0.464 0.400 0.500 0.243 0.559 0.267 0.589 0.229 0.635 0.274 0.687 0.835 0.712 0.896 0.805 0.811 0.926 0.759 0.972 0.225 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.103 0.049 0.138 0.119 0.200 0.198 0.229 0.251 0.234 0.317 0.247 0.422 0.250 0.540 0.250 0.643 0.235 0.722 0.229 0.902 0.217 0.936 0.207 0.970 0.150 1.000 0.136) :duration dur :scaler (hz->radians 10200.0))) (gen1 (make-polywave 0.0 '(1 .8 2 .01 3 .05 4 .01 5 .005))) (gen2 (make-polywave 0.0 '(1 .92 2 .01 3 .05 4 .01 5 .005))) (ampf2 (make-env '(0 1 .2 0 1 0) :duration dur)) (rnd (make-nrxysin 200 :n 2 :r .5)) (rndf (make-env '(0 0 .1 1 .25 0 .45 0 .5 1 .6 0 1 0) :duration dur :scaler (hz->radians 200))) (rndfrqf (make-env '(0 1 .45 1 .5 .2 .6 .2 1 0) :duration dur :scaler (hz->radians 200)))) (do ((i start (+ i 1))) ((= i stop)) (let ((frq (+ (env frqf) (* (env rndf) (nrxysin rnd (env rndfrqf)))))) (outa i (* (env ampf) (+ (polywave gen1 frq) (* (env ampf2) (polywave gen2 (* 1.5 frq))))))))))) (defanimal (eastern-bluebird-2 beg amp) (let ((dur 0.33)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.023 0.324 0.046 0.438 0.089 0.551 0.136 0.994 0.248 0.978 0.470 0.452 0.506 0.432 0.556 0.479 0.629 0.197 0.681 0.211 0.746 0.330 0.791 0.161 0.814 0.180 0.828 0.127 0.916 0.291 0.959 0.102 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.195 0.019 0.246 0.042 0.294 0.066 0.308 0.093 0.294 0.122 0.254 0.202 0.246 0.554 0.237 0.604 0.206 0.643 0.175 0.673 0.184 0.707 0.206 0.743 0.220 0.791 0.201 0.832 0.167 0.856 0.198 0.879 0.212 0.918 0.234 0.942 0.209 0.960 0.186 1.000 0.158) :duration dur :scaler (hz->radians 10000.0))) (gen1 (make-polywave 0.0 '(1 .8 2 .01 3 .05 4 .01 5 .005))) (gen2 (make-polywave 0.0 '(2 .01 4 .7 5 .01 6 .01 7 .01 8 .05 9 .01 10 .01 11 .01 12 .005 13 .01 14 .10 15 .10 16 .01))) (frqf2 (make-env '(0.000 0.345 0.052 0.393 0.098 0.345 0.271 0.311 0.443 0.305 0.506 0.319 0.559 0.339 0.613 0.322 0.661 0.294 0.705 0.314 0.738 0.353 0.769 0.364 0.797 0.356 0.818 0.316 0.845 0.285 0.882 0.339 0.905 0.362 0.928 0.364 0.960 0.319 1.000 0.209) :duration dur :scaler (hz->radians 2500.0))) (ampf2 (make-env '(0 0 .1 0 .2 1 1 1) :scaler .3 :duration dur))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (+ (polywave gen1 (env frqf)) (* (env ampf2) (polywave gen2 (env frqf2)))))))))) (eastern-bluebird-1 beg1 amp1) (eastern-bluebird-2 (+ beg1 0.33) amp1)) ;; (with-sound (:play #t) (eastern-bluebird 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Greater roadrunner (defanimal (greater-roadrunner beg amp) ;; south 13 3 (let ((dur 4.36)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.043 0.623 0.069 0.901 0.079 0.000 0.155 0.000 0.168 0.292 0.193 0.771 0.231 0.947 0.240 0.000 0.310 0.000 0.317 0.327 0.369 0.947 0.385 0.894 0.401 0.000 0.458 0.000 0.491 0.620 0.510 0.810 0.538 0.757 0.563 0.000 0.627 0.000 0.646 0.408 0.691 0.680 0.709 0.148 0.750 0.000 0.813 0.004 0.825 0.201 0.847 0.317 0.867 0.211 0.881 0.067 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.215 0.075 0.178 0.114 0.172 0.137 0.231 0.166 0.215 0.188 0.190 0.230 0.178 0.265 0.176 0.284 0.217 0.316 0.201 0.349 0.183 0.388 0.174 0.421 0.174 0.443 0.211 0.465 0.197 0.503 0.176 0.542 0.169 0.556 0.137 0.591 0.142 0.600 0.195 0.638 0.185 0.674 0.174 0.697 0.167 0.709 0.140 0.733 0.137 0.766 0.130 0.793 0.174 0.820 0.169 0.868 0.162 0.879 0.133 1.000 0.089) :duration dur :scaler (hz->radians 3000.0))) (gen1 (make-polywave 0.0 '(1 .95 2 .03 3 .01 4 .005 5 .005 7 .005))) (rnd (make-rand-interp 200 .3))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (+ .7 (abs (rand-interp rnd))) (polywave gen1 (env frqf)))))))) ;; (with-sound (:play #t) (greater-roadrunner 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Evening grosbeak (defanimal (evening-grosbeak beg amp) ;; east 98 7.5 (let ((dur 0.17)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.050 0.121 0.068 0.000 0.081 0.000 0.097 0.329 0.109 0.000 0.125 0.451 0.135 0.344 0.144 0.462 0.162 0.000 0.171 0.058 0.177 0.688 0.188 0.558 0.208 0.477 0.220 0.283 0.246 0.373 0.265 0.373 0.277 0.566 0.303 0.775 0.328 0.824 0.360 0.711 0.383 0.838 0.405 0.835 0.413 0.711 0.443 0.939 0.514 0.948 0.576 1.000 0.626 0.942 0.658 0.951 0.707 0.864 0.742 0.728 0.777 0.682 0.820 0.610 0.926 0.260 0.949 0.072 0.978 0.107 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.196 0.021 0.259 0.038 0.355 0.055 0.322 0.066 0.276 0.096 0.255 0.116 0.287 0.124 0.371 0.134 0.390 0.146 0.325 0.158 0.371 0.181 0.386 0.203 0.397 0.227 0.449 0.262 0.451 0.283 0.437 0.465 0.388 0.599 0.374 0.701 0.350 0.834 0.327 1.000 0.243) :duration dur :scaler (hz->radians 10200.0))) (gen1 (make-polywave 0.0 '(1 .97 2 .01 3 .015 4 .004))) (vib (make-oscil 300)) (vibf (make-env '(0 0 .25 0 .3 1 1 1) :duration dur :scaler (hz->radians 200))) (emph (make-oscil)) (emphf (make-env '(0 0 .3 1 .4 0 1 0) :duration dur :scaler .2))) (do ((i start (+ i 1))) ((= i stop)) (let ((frq (+ (env frqf) (* (env vibf) (oscil vib))))) (outa i (* (env ampf) (+ (polywave gen1 frq) (* (env emphf) (oscil emph (* 2.0 frq))))))))))) ;; (with-sound (:play #t) (evening-grosbeak 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Dark-eyed junco (define (dark-eyed-junco beg1 amp1) ;; calif 49 3 (defanimal (dark-eyed-junco-1 beg amp) (let ((dur 0.11)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.042 0.085 0.115 0.572 0.161 0.288 0.192 0.604 0.214 0.661 0.241 1.000 0.289 0.085 0.316 0.748 0.345 0.950 0.387 0.307 0.413 0.082 0.431 0.497 0.459 0.481 0.486 0.133 0.552 0.078 0.710 0.382 0.777 0.236 0.795 0.291 0.872 0.156 0.899 0.169 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.578 0.069 0.569 0.119 0.535 0.173 0.427 0.175 0.575 0.204 0.566 0.235 0.536 0.273 0.473 0.299 0.401 0.304 0.535 0.327 0.547 0.358 0.513 0.404 0.416 0.415 0.555 0.445 0.549 0.482 0.493 0.520 0.396 0.549 0.367 0.695 0.369 0.846 0.330 0.934 0.297 1.000 0.243) :duration dur :scaler (hz->radians 10050.0))) (gen1 (make-polywave 0.0 '(1 .99 2 .01)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) (let ((amps (vector .3 .5 .8 .8 .8 .8 .8 1.0 .8 .8 .4))) (do ((call 0 (+ call 1))) ((= call 11)) (dark-eyed-junco-1 (+ beg1 (* call .122)) (* amp1 (amps call)))))) ;; (with-sound (:play #t) (dark-eyed-junco 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Groove-billed ani (defanimal (groove-billed-ani beg amp) ;; south 14 17 ;; first note (let ((dur 0.067)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.110 0.124 0.121 0.469 0.137 0.323 0.149 0.524 0.195 0.654 0.212 0.906 0.226 0.204 0.245 0.744 0.317 0.991 0.481 0.824 0.517 0.558 0.556 0.746 0.573 0.446 0.581 0.590 0.597 0.668 0.606 0.231 0.622 0.698 0.653 0.686 0.718 0.185 0.884 0.046 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.112 0.058 0.098 0.114 0.098 0.18 0.143 0.208 0.309 0.339 0.325 0.445 0.327 0.597 0.318 0.636 0.297 0.673 0.240 0.744 0.229 0.775 0.160 0.801 0.117 0.838 0.082 0.884 0.082 .95 0.059 ) :duration dur :scaler (hz->radians 17100.0))) (gen1 (make-polywave 0.0 '(1 .96 2 .04 3 .005))) (gen2 (make-polywave 0.0 '(1 .1 2 .7 3 .1 4 .005 5 .005 6 .002))) (ampf2 (make-env '(0 0 .025 1 .2 0 .7 0 .9 1 1 0) :duration dur)) (rnd (make-rand-interp 400 (hz->radians 100)))) (do ((i start (+ i 1))) ((= i stop)) (let ((frq (+ (env frqf) (rand-interp rnd)))) (outa i (* (env ampf) (+ (polywave gen1 frq) (* (env ampf2) (polywave gen2 frq))))))))) ;; second note (let ((dur 0.265) (start (seconds->samples (+ beg 0.27)))) (let ((stop (+ start (seconds->samples dur))) (ampf (make-env '(0.000 0.000 0.020 0.160 0.091 0.182 0.138 0.132 0.174 0.162 0.239 0.120 0.390 0.297 0.427 0.216 0.474 0.530 0.521 1.000 0.565 0.893 0.590 0.498 0.605 0.656 0.634 0.171 0.676 0.209 0.696 0.130 0.754 0.222 0.786 0.173 0.818 0.214 0.835 0.177 0.884 0.199 0.911 0.107 0.922 0.158 0.961 0.071 0.978 0.378 1.000 0.000) :duration dur :scaler (* .4 amp))) (frqf (make-env '(0.000 0.125 0.048 0.142 0.139 0.133 0.303 0.131 0.443 0.150 0.495 0.156 0.508 0.206 0.568 0.200 0.612 0.219 0.621 0.289 0.627 0.439 0.690 0.458 0.752 0.464 0.823 0.464 0.900 0.450 0.947 0.425 0.975 0.194 1.000 0.2 ) :duration dur :scaler (hz->radians 10300.0))) (gen1 (make-oscil)) (gen2 (make-oscil)) (gen3 (make-oscil)) (ampf1 (make-env '(0 1 .63 1 .65 .1 .94 .1 1 1) :scaler .95 :duration dur)) (ampf2 (make-env '(0 .5 .6 1 .9 1 1 .5) :scaler .1 :duration dur)) (ampf3 (make-env '(0 1 .59 1 .6 0 .65 0 .66 1 .8 1 .9 0 1 0) :scaler .05 :duration dur)) (rnd (make-rand-interp 400 (hz->radians 30)))) (do ((i start (+ i 1))) ((= i stop)) (let ((frq (+ (env frqf) (rand-interp rnd)))) (outa i (* (env ampf) (+ (* (env ampf1) (oscil gen1 frq)) (* (env ampf2) (oscil gen2 (* 2.0 frq))) (* (env ampf3) (oscil gen3 (* 3.0 frq))))))))))) ;; (with-sound (:play #t) (groove-billed-ani 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Common pauraque (defanimal (common-pauraque beg amp) ;; south 20 1.7 (let ((dur 0.65)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.134 0.124 0.181 0.079 0.203 0.169 0.275 0.160 0.341 0.494 0.390 0.850 0.443 0.561 0.462 0.783 0.502 0.768 0.535 1.000 0.587 0.795 0.742 0.802 0.821 0.702 0.856 0.458 0.884 0.263 0.926 0.241 1.000 0.000 ) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.168 0.175 0.190 0.328 0.225 0.399 0.237 0.472 0.310 0.504 0.342 0.539 0.345 0.572 0.326 0.594 0.294 0.644 0.275 0.731 0.259 0.797 0.244 0.832 0.231 0.868 0.212 1.000 0.155 ) :duration dur :scaler (hz->radians 7700.0))) (gen1 (make-polywave 0.0 '(1 .98 2 .005 3 .015))) (vib (make-oscil 120)) (vibf (make-env '(0 0 .25 0 .4 .3 .5 .1 .6 1 1 0) :duration dur :scaler (hz->radians 100)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (+ (env frqf) (* (env vibf) (oscil vib)))))))))) ;; (with-sound (:play #t) (common-pauraque 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Hammond's flycatcher (defanimal (hammonds-flycatcher beg amp) ;; calif2 5 8.2 (let ((dur 0.23)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.090 0.518 0.153 0.872 0.167 0.795 0.190 0.952 0.251 0.000 0.453 0.000 0.502 0.434 0.521 0.295 0.542 0.053 0.580 0.051 0.606 0.000 0.691 0.000 0.701 0.062 0.731 0.089 0.735 0.000 0.746 0.000 0.754 0.212 0.764 0.119 0.784 0.110 0.794 0.148 0.800 0.007 0.815 0.080 0.823 0.301 0.834 0.126 0.854 0.151 0.862 0.062 0.873 0.009 0.880 0.075 0.890 0.297 0.910 0.205 0.921 0.078 0.934 0.032 0.948 0.208 0.959 0.285 0.971 0.260 0.984 0.091 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.401 0.037 0.480 0.073 0.538 0.109 0.596 0.142 0.628 0.175 0.697 0.206 0.794 0.218 0.812 0.233 0.800 0.240 0.773 0.260 0.693 0.404 0.381 0.416 0.356 0.437 0.347 0.460 0.359 0.482 0.439 0.497 0.532 0.529 0.659 0.546 0.836 0.587 0.614 0.690 0.460 0.700 0.282 0.713 0.247 0.725 0.285 0.727 0.525 0.739 0.594 0.756 0.314 0.769 0.276 0.784 0.280 0.788 0.329 0.796 0.736 0.811 0.543 0.828 0.301 0.843 0.282 0.851 0.325 0.861 0.780 0.887 0.377 0.899 0.321 0.909 0.370 0.926 0.681 0.944 0.449 0.959 0.421 0.977 0.433 1.000 0.471) :duration dur :scaler (hz->radians 9000.0))) (gen1 (make-polywave 0.0 '(1 .99 2 .01 3 .005)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) ;; (with-sound (:play #t) (hammonds-flycatcher 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Barn owl ;;; ;;; not as good as some of the others -- ending slightly wrong, formants need tuning a bit, etc (defanimal (barn-owl beg amp) ;; calif 50 2.9 (let ((dur 0.9)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0 0 1 1 20 1 21 0) :duration dur :scaler (* 0.5 amp) :base 3)) (ampf1 (make-env '(0 1 19 1 21 0 22 0) :base 10 :duration dur)) (gen1 (make-polywave 1110.0 '(2 .6 3 .2 4 .1 5 .1 6 .05 7 .1 9 .01))) (ampf2 (make-env '(0 0 19 0 20 .5 22 0) :base 10 :duration dur)) (frqf2 (make-env '(0 1550 18 1550 19 1200 20 1700 22 1500) :scaler (hz->radians 1.0) :duration dur :base 10)) (gen2 (make-polywave 0.0 '(1 .2 2 .01 3 .8 4 .3 5 .1 6 .01))) (rnd (make-rand-interp 10000 (hz->radians 400))) (rndf (make-env '(0 1 19 1 20 .1 22 .01) :duration dur)) (trem (make-rand-interp 120 .6)) (frm1 (make-formant 2800 .98)) (frm2 (make-formant 4400 .92)) (frm4 (make-formant 6000 .97)) (frm5 (make-formant 7500 .96)) (frm3 (make-formant 9000 .96)) (fr1 (* 2 7 (sin (hz->radians 2800)))) (fr2 (* 2 3 (sin (hz->radians 4400)))) (fr3 (* 2 0.5 (sin (hz->radians 9000)))) (fr4 (* 2 3 (sin (hz->radians 6000)))) (fr5 (* 2 (sin (hz->radians 7500))))) (let ((fb (vector frm1 frm2 frm3 frm4 frm5)) (fs (float-vector fr1 fr2 fr3 fr4 fr5))) (set! fb (make-formant-bank fb fs)) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (formant-bank fb (* (+ .4 (abs (rand-interp trem))) (+ (* (env ampf1) (polywave gen1 (* (env rndf) (rand-interp rnd)))) (* (env ampf2) (polywave gen2 (env frqf2))))))))))))) ;; (with-sound (:play #t :statistics #t) (barn-owl 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Long-eared owl (defanimal (long-eared-owl beg amp) (let ((dur 0.37)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.119 0.319 0.193 0.682 0.251 0.767 0.309 0.958 0.485 0.930 0.505 1.000 0.574 0.895 0.698 0.901 0.902 0.767 0.965 0.401 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.276 0.185 0.328 0.273 0.338 0.462 0.343 0.735 0.340 0.894 0.337 0.938 0.305 1.000 0.231) :duration dur :scaler (hz->radians 980.0))) (gen1 (make-polywave 0.0 '(1 1 2 .23 3 .034 4 .008 5 .005 7 .003)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) ;; (with-sound (:play #t) (long-eared-owl 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Summer tanager (define (summer-tanager beg1 amp1) ;; calif 24 18 (defanimal (summer-tanager-1 beg dur amp ampl frq frql rndl) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env ampl :duration dur :scaler amp)) (frqf (make-env frql :duration dur :scaler (hz->radians frq))) (gen1 (make-polywave 0.0 '(1 .98 2 .01 3 .006 4 .008 5 .004))) (rndf (make-env rndl :duration dur)) (rnd (make-rand-interp 600))) (do ((i start (+ i 1))) ((= i stop)) (let ((rf (env rndf))) (outa i (* (env ampf) (+ (- 1.0 rf) (* rf (rand-interp rnd))) (polywave gen1 (env frqf)))))))) (summer-tanager-1 beg1 .29 (* .4 amp1) '(0.000 0.000 0.123 0.450 0.194 0.404 0.210 0.055 0.232 0.437 0.251 0.193 0.277 0.263 0.292 0.135 0.349 0.202 0.369 0.156 0.381 0.291 0.458 0.177 0.554 0.153 0.682 0.875 0.734 0.988 0.768 1.000 0.802 0.722 0.829 0.887 0.918 0.251 1.000 0.000) 6070 '(0.000 0.583 0.035 0.583 0.116 0.452 0.145 0.452 0.179 0.345 0.200 0.414 0.224 0.313 0.241 0.400 0.260 0.299 0.289 0.348 0.311 0.304 0.332 0.359 0.343 0.299 0.362 0.394 0.376 0.328 0.399 0.409 0.417 0.426 0.431 0.475 0.620 0.452 0.750 0.412 0.888 0.423 0.924 0.371 0.934 0.429 0.958 0.391 0.974 0.429 1.000 0.403) '(0 .3 .2 .3 .45 .8 .6 .1 1 .1)) (summer-tanager-1 (+ beg1 .56) .13 (* .6 amp1) '(0.000 0.000 0.105 0.113 0.172 0.052 0.243 0.128 0.449 0.980 0.485 0.980 0.518 0.855 0.603 0.983 0.671 0.745 0.708 0.858 0.786 0.041 0.885 0.203 1.000 0.000) 10800 '(0.000 0.300 0.302 0.269 1.000 0.273) '(0 .2 .3 .2 .4 0 1 0)) (summer-tanager-1 (+ beg1 .71) .24 (* .9 amp1) '(0.000 0.000 0.056 0.292 0.072 0.209 0.086 0.439 0.103 0.379 0.114 0.565 0.134 0.644 0.215 0.190 0.276 0.107 0.334 0.237 0.367 0.715 0.416 0.988 0.457 0.889 0.533 0.462 0.624 0.186 0.668 0.245 0.697 0.356 0.750 0.474 0.902 0.107 1.000 0.000) 6700 '(0.000 0.506 0.072 0.450 0.133 0.390 0.190 0.307 0.255 0.251 0.327 0.259 0.377 0.335 0.416 0.386 0.539 0.398 0.676 0.382 0.717 0.371 0.761 0.335 0.840 0.283 0.930 0.263 1.000 0.307) '(0 .3 .3 .3 .4 .1 .75 .1 .8 .8 1 .5)) (summer-tanager-1 (+ beg1 1.28) .25 amp1 '(0.000 0.000 0.043 0.092 0.098 0.442 0.163 0.622 0.204 0.649 0.271 0.562 0.289 0.398 0.306 0.295 0.316 0.371 0.340 0.191 0.371 0.414 0.420 0.363 0.437 0.610 0.449 0.442 0.460 0.745 0.485 0.641 0.522 0.777 0.531 0.534 0.558 1.000 0.583 0.713 0.631 0.801 0.646 0.462 0.661 0.773 0.669 0.510 0.677 0.733 0.688 0.335 0.699 0.494 0.711 0.514 0.716 0.299 0.735 0.653 0.758 0.546 0.786 0.562 0.808 0.227 0.825 0.386 0.845 0.367 0.878 0.096 1.000 0.000) 6160 '(0.000 0.333 0.056 0.369 0.097 0.452 0.160 0.448 0.238 0.401 0.284 0.389 0.365 0.381 0.394 0.476 0.439 0.508 0.491 0.536 0.555 0.548 0.615 0.552 0.733 0.484 0.853 0.464 1.000 0.464) '(0 0 .3 .1 .6 .1 .7 .3 1 .4)) (summer-tanager-1 (+ beg1 1.86) .27 (* .9 amp1) '(0.000 0.000 0.053 0.142 0.152 0.943 0.200 0.880 0.223 0.983 0.267 0.844 0.314 0.875 0.369 0.679 0.412 0.361 0.462 0.236 0.477 0.132 0.513 0.073 0.684 0.172 0.759 0.351 0.871 0.233 1.000 0.000) 6700 '(0.000 0.375 0.027 0.427 0.051 0.364 0.068 0.451 0.090 0.364 0.107 0.472 0.132 0.364 0.152 0.441 0.177 0.369 0.202 0.412 0.259 0.409 0.326 0.385 0.410 0.311 0.466 0.272 0.526 0.256 0.570 0.296 0.588 0.280 0.597 0.354 0.616 0.280 0.630 0.359 0.645 0.288 0.665 0.354 0.684 0.280 0.706 0.351 0.724 0.277 0.740 0.364 0.758 0.285 0.773 0.361 0.799 0.317 1.000 0.251) '(0 0 .3 0 .4 .3 .6 .3 .7 0 1 0)) (summer-tanager-1 (+ beg1 2.42) .11 (* .9 amp1) '(0.000 0.000 0.079 0.182 0.187 0.604 0.222 0.544 0.261 0.710 0.291 0.169 0.309 0.921 0.326 0.982 0.387 0.596 0.440 1.000 0.470 0.628 0.523 0.836 0.616 0.615 0.685 0.164 0.719 0.346 0.752 0.119 0.767 0.185 0.877 0.024 0.948 0.069 1.000 0.000) 6750 '(0.000 0.504 0.143 0.441 0.197 0.425 0.265 0.443 0.312 0.483 0.375 0.557 0.440 0.520 1.000 0.520) '(0 0 .3 0 .5 .4 .7 0 1 0)) (summer-tanager-1 (+ beg1 2.61) .16 (* .9 amp1) '(0.000 0.000 0.196 0.778 0.231 0.528 0.256 0.628 0.295 0.354 0.331 0.530 0.397 0.332 0.425 0.776 0.442 0.074 0.453 0.649 0.463 0.298 0.474 0.620 0.498 0.781 0.513 0.694 0.539 0.683 0.551 0.406 0.597 0.868 0.617 0.815 0.653 0.984 0.672 0.815 0.700 0.966 0.718 0.905 0.727 0.734 0.748 0.834 0.780 0.570 0.793 0.683 0.817 0.602 0.835 0.406 0.855 0.609 0.865 0.483 0.886 0.530 0.900 0.412 0.923 0.412 1.000 0.000) 6750 '(0.000 0.438 0.193 0.443 0.367 0.446 0.409 0.425 0.433 0.501 0.462 0.388 0.489 0.472 0.511 0.433 0.526 0.367 0.552 0.454 0.579 0.367 0.609 0.409 0.666 0.385 0.728 0.377 0.865 0.348 1.000 0.346) '(0 0 .5 .1 .9 .5 1 .4)) (summer-tanager-1 (+ beg1 3.14) .23 (* .9 amp1) '(0.000 0.000 0.268 0.594 0.365 0.153 0.412 0.040 0.520 0.475 0.578 0.918 0.614 0.736 0.629 0.491 0.654 0.997 0.682 0.794 0.693 0.660 0.716 0.887 0.740 0.786 0.762 0.897 0.827 0.792 0.890 0.446 1.000 0.000) 6750 '(0.000 0.306 0.025 0.322 0.048 0.425 0.079 0.325 0.101 0.375 0.131 0.314 0.156 0.346 0.269 0.369 0.388 0.369 0.427 0.456 0.465 0.449 0.510 0.464 0.623 0.427 0.768 0.420 1.000 0.4) '(0 0 .5 0 .6 .3 1 0)) (summer-tanager-1 (+ beg1 3.54) .18 (* .5 amp1) '(0.000 0.000 0.087 0.327 0.198 0.834 0.235 0.805 0.283 0.995 0.313 0.778 0.379 0.678 0.471 0.235 0.509 0.369 0.525 0.288 0.574 0.631 0.626 0.863 0.663 0.770 0.708 0.852 0.732 0.533 0.748 0.739 0.770 0.633 0.791 0.757 0.808 0.636 0.823 0.699 0.869 0.636 0.937 0.393 1.000 0.000) 6750 '(0.000 0.406 0.200 0.396 0.299 0.412 0.462 0.401 0.579 0.396 0.804 0.348 1.000 0.356) '(0 .1 1 .1))) ;; (with-sound (:play #t) (summer-tanager 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Whooping crane (defanimal (whooping-crane beg amp) ;; east 63 53 (is this 2 birds?) (let ((dur 0.68)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.036 0.069 0.052 0.000 0.115 0.000 0.127 0.343 0.137 0.254 0.143 0.400 0.162 0.000 0.184 0.000 0.191 0.524 0.202 0.772 0.224 0.131 0.241 0.392 0.259 0.770 0.274 0.699 0.305 0.692 0.362 0.852 0.432 0.768 0.449 0.985 0.484 1.000 0.604 0.969 0.640 0.783 0.672 0.489 0.687 0.752 0.725 0.290 0.742 0.376 0.801 0.281 0.906 0.197 0.928 0.128 0.943 0.192 0.950 0.365 0.977 0.086 1.000 0.000) :duration dur :scaler (* 0.33 amp))) (frqf1 (make-env '(0.000 0.158 0.120 0.175 0.137 0.227 0.145 0.180 0.190 0.173 0.204 0.249 0.219 0.230 0.324 0.237 0.428 0.242 0.585 0.240 0.655 0.232 0.689 0.215 0.958 0.205 0.966 0.128 1.000 0.123) :duration dur :scaler (hz->radians 5000.0))) (frqf2 (make-env '(0.000 0.104 0.342 0.121 0.376 0.136 0.435 0.128 0.447 0.175 0.498 0.173 1.000 0.170) :duration dur :scaler (hz->radians 5000.0))) (ampf1 (make-env '(0 1 .65 1 .70 0 1 0) :duration dur)) (ampf2 (make-env '(0 0 .32 0 .48 1 .68 1 .75 0 1 0) :duration dur)) (ampf3 (make-env '(0 0 .6 0 .65 1 1 1) :duration dur)) (gen1 (make-polywave 0.0 (normalize-partials '(1 .3 2 1 3 -.8 4 .25 5 .45 6 .22 7 .13 8 .05 9 .02 10 .005 11 .005)))) (gen2 (make-polywave 0.0 (normalize-partials '(1 .91 2 .17 3 -.77 4 .25 5 .2 6 .2 7 .18 8 .1 10 .01)))) (gen3 (make-polywave 0.0 (normalize-partials '(1 -1 2 .11 3 .45 4 .44 5 .62 6 .27 7 .02 8 .005)))) (rnd (make-rand-interp 2000 (hz->radians 200))) (rndf1 (make-env '(0 1 .2 1 .3 0 .65 0 .7 1 .8 0 1 0) :duration dur)) (rndf2 (make-env '(0 0 .32 0 .48 1 .5 0 .7 0 .75 1 .8 0 1 0) :duration dur)) (rndf3 (make-env '(0 0 .6 0 .65 1 .7 0 .9 0 1 1) :duration dur))) (do ((i start (+ i 1))) ((= i stop)) (let ((frq1 (env frqf1)) (rn (rand-interp rnd))) (outa i (* (env ampf) (+ (* (env ampf1) (polywave gen1 (+ frq1 (* rn (env rndf1))))) (* (env ampf2) (polywave gen2 (+ (env frqf2) (* rn (env rndf2))))) (* (env ampf3) (polywave gen3 (+ frq1 (* rn (env rndf3))))))))))))) ;; (with-sound (:play #t) (whooping-crane 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Sandhill crane (defanimal (sandhill-crane beg amp) ;; calif 30 13 (let ((dur 0.64)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.042 0.100 0.130 0.108 0.175 0.155 0.183 0.052 0.200 0.000 0.230 0.000 0.240 0.052 0.244 0.681 0.252 0.545 0.260 0.602 0.264 0.000 0.269 0.397 0.277 0.845 0.288 0.547 0.292 0.734 0.304 0.624 0.313 0.453 0.320 0.215 0.324 0.373 0.328 0.359 0.335 0.143 0.344 0.282 0.371 0.291 0.380 0.256 0.386 0.333 0.390 0.773 0.404 0.428 0.409 0.577 0.417 0.612 0.424 0.374 0.427 0.562 0.433 0.405 0.436 0.452 0.442 0.285 0.446 0.417 0.460 0.034 0.468 0.319 0.480 0.036 0.485 0.852 0.493 0.606 0.498 0.636 0.503 0.526 0.519 0.471 0.525 0.980 0.532 0.134 0.535 0.467 0.546 0.236 0.550 0.044 0.561 0.069 0.565 0.276 0.576 0.739 0.584 0.581 0.592 0.797 0.605 0.168 0.606 0.268 0.613 0.076 0.620 0.145 0.631 0.035 0.635 0.164 0.639 0.080 0.643 0.939 0.656 0.508 0.664 0.623 0.672 0.165 0.678 0.040 0.681 0.157 0.687 0.187 0.695 0.038 0.700 0.293 0.704 0.155 0.709 0.719 0.715 0.701 0.720 0.420 0.724 0.559 0.728 0.249 0.737 0.069 0.741 0.168 0.748 0.103 0.751 0.051 0.757 0.072 0.758 0.196 0.763 0.129 0.769 0.666 0.778 0.515 0.785 0.126 0.791 0.108 0.800 0.029 0.809 0.087 0.821 0.016 0.826 0.327 0.832 0.135 0.840 0.084 0.848 0.025 0.858 0.440 0.866 0.168 0.873 0.123 0.878 0.033 0.886 0.055 0.900 0.008 0.907 0.593 0.918 0.102 0.923 0.463 0.930 0.361 0.940 0.343 0.947 0.182 0.953 0.236 0.964 0.025 0.967 0.061 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.063 0.163 0.065 0.171 0.092 0.182 0.063 0.238 0.090 0.244 0.115 0.251 0.094 0.267 0.092 0.285 0.094 0.381 0.096 0.387 0.129 0.398 0.092 0.427 0.094 0.438 0.069 0.445 0.094 0.473 0.092 0.483 0.100 0.492 0.092 0.523 0.096 0.559 0.094 0.571 0.104 0.581 0.092 0.618 0.096 0.633 0.096 0.645 0.100 0.661 0.085 0.673 0.096 0.708 0.096 0.723 0.085 0.768 0.090 0.791 0.090 0.824 0.075 0.850 0.083 0.853 0.117 0.863 0.094 0.888 0.094 0.906 0.115 0.920 0.110 0.931 0.085 1.000 0.087 ) :duration dur :scaler (hz->radians 8300.0))) (gen1 (make-polywave 0.0 '(1 .6 2 -.1 3 .01 4 .05 5 .03 6 .01 7 .01 8 .005))) (rnd (make-rand-interp 3000 (hz->radians 100)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (+ (env frqf) (rand-interp rnd))))))))) ;; (with-sound (:play #t) (sandhill-crane 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Gray-crowned rosy-finch (defanimal (gray-crowned-rosy-finch beg amp) ;; calif 64 5.1 (let ((dur 0.15)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.339 0.937 0.454 0.992 0.609 0.860 0.807 0.575 1.000 0.000) :duration dur :scaler amp)) (ampf2 (make-env '(0 1 .5 1 .55 0 1 0) :duration dur :scaler .2)) (frqf1 (make-env '(0.000 0.000 0.004 0.271 0.031 0.299 0.085 0.313 0.167 0.318 0.227 0.317 0.243 0.326 0.281 0.296 0.299 0.318 0.309 0.299 0.325 0.299 0.338 0.285 0.356 0.321 0.369 0.301 0.387 0.294 0.396 0.280 0.415 0.313 0.430 0.282 0.452 0.283 0.462 0.263 0.483 0.304 0.497 0.280 0.517 0.288 0.534 0.249 0.550 0.293 0.568 0.254 0.587 0.285 0.611 0.222 0.627 0.274 0.647 0.238 0.662 0.263 0.677 0.247 0.696 0.203 0.708 0.219 0.715 0.250 0.734 0.230 0.755 0.246 0.781 0.198 0.800 0.250 0.811 0.228 0.834 0.250 0.869 0.191 0.893 0.252 0.915 0.220 0.939 0.244 0.967 0.220 1.000 0.222) :duration dur :scaler (hz->radians 13400.0))) (frqf2 (make-env '(0.000 0.328 0.086 0.397 0.158 0.441 0.219 0.446 0.232 0.420 0.258 0.430 0.281 0.387 0.307 0.419 0.330 0.400 0.344 0.369 0.357 0.395 0.382 0.397 0.396 0.365 0.416 0.398 0.442 0.402 0.460 0.354 0.480 0.397 0.504 0.384 0.526 0.329 0.550 0.294 1.000 0.288) :duration dur :scaler (hz->radians 13400.0))) (gen1 (make-polywave 0.0 '(1 .99 2 .005))) (gen2 (make-oscil)) (rnd (make-rand-interp 400 .5)) (rnd1 (make-rand-interp 2000 (hz->radians 100)))) (do ((i start (+ i 1))) ((= i stop)) (let ((rn (rand-interp rnd1))) (outa i (* (env ampf) (+ .5 (abs (rand-interp rnd))) (+ (polywave gen1 (+ rn (env frqf1))) (* (env ampf2) (oscil gen2 (+ rn (env frqf2)))))))))))) ;; (with-sound (:play #t) (gray-crowned-rosy-finch 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Virginia rail (define (virginia-rail beg amp) ;; calif 28 20 (defanimal (virginia-rail-1 beg amp) (let ((dur 0.048)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.021 0.076 0.040 0.233 0.058 0.307 0.075 0.254 0.099 0.000 0.118 0.213 0.131 0.118 0.180 0.935 0.217 0.207 0.224 0.315 0.253 0.142 0.274 1.000 0.290 0.956 0.305 0.247 0.321 0.203 0.332 0.070 0.362 0.896 0.376 0.706 0.384 0.237 0.402 0.292 0.417 0.556 0.431 0.607 0.438 0.767 0.469 0.858 0.480 0.729 0.492 0.080 0.503 0.355 0.510 0.256 0.539 0.706 0.549 0.641 0.574 0.104 0.591 0.285 0.637 0.004 0.670 0.154 0.683 0.146 0.699 0.087 1.000 0.000) :duration dur :scaler amp)) (gen1 (make-polywave 2700 (list 1 (* .55 .98) 2 (* .55 .01) 3 (* .55 .05) 5 (* .55 .005)))) (gen2 (make-polywave 2400 (list 1 (* .45 .98) 2 (* .45 .01) 3 (* .45 .03) 5 (* .45 .005)))) (rnd (make-rand-interp 4000 (hz->radians 300)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (+ (polywave gen1 (rand-interp rnd)) (polywave gen2)))))))) (defanimal (virginia-rail-2 beg amp) (let ((dur 0.048)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.042 0.141 0.071 0.749 0.087 0.659 0.104 0.283 0.118 0.150 0.133 0.229 0.146 0.147 0.153 0.385 0.172 0.503 0.195 0.950 0.219 0.075 0.227 0.257 0.245 0.101 0.264 0.193 0.282 0.976 0.312 0.815 0.346 0.437 0.387 0.888 0.406 0.622 0.434 0.767 0.451 0.277 0.463 0.363 0.486 0.106 0.497 0.690 0.507 0.727 0.523 0.338 0.540 0.910 0.555 0.892 0.563 0.582 0.578 0.716 0.588 0.637 0.605 0.171 0.631 0.939 0.646 0.862 0.664 0.413 0.687 0.061 0.703 0.171 0.724 0.072 0.743 0.150 0.776 0.103 0.801 0.139 0.828 0.066 0.909 0.029 0.957 0.061 1.000 0.000) :duration dur :scaler amp)) (gen1 (make-polywave 2700 (list 1 (* .45 .98) 2 (* .45 .01) 3 (* .45 .05) 5 (* .45 .005)))) (gen2 (make-polywave 2400 (list 1 (* .55 .98) 2 (* .55 .01) 3 (* .55 .05) 5 (* .55 .005)))) (rnd (make-rand-interp 4000 (hz->radians 200)))) (do ((i start (+ i 1))) ((= i stop)) (let ((frq (rand-interp rnd))) (outa i (* (env ampf) (+ (polywave gen1 frq) (polywave gen2 frq))))))))) (defanimal (virginia-rail-3 beg amp) (let ((dur 0.048)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.062 0.158 0.095 0.921 0.127 0.411 0.237 0.954 0.260 0.382 0.294 0.993 0.315 0.473 0.326 0.583 0.353 0.217 0.406 0.991 0.428 0.437 0.449 0.769 0.498 0.305 0.526 0.883 0.548 0.367 0.562 0.892 0.578 0.347 0.597 0.316 0.612 0.890 0.637 0.717 0.665 0.235 0.696 0.545 0.711 0.233 0.754 0.754 0.818 0.099 0.854 0.123 0.910 0.033 0.940 0.117 1.000 0.000) :duration dur :scaler amp)) (gen1 (make-polywave 2700 (list 1 (* .5 .98) 2 (* .5 .01) 3 (* .5 .05) 5 (* .5 .005)))) (gen2 (make-polywave 2500 (list 1 (* .4 .98) 2 (* .4 .01) 3 (* .4 .05) 5 (* .4 .005)))) (gen3 (make-polywave 3000 (list 1 (* .1 .98) 2 (* .1 .01) 3 (* .1 .05) 5 (* .1 .005)))) (rnd (make-rand-interp 4000 (hz->radians 300)))) (do ((i start (+ i 1))) ((= i stop)) (let ((frq (rand-interp rnd))) (outa i (* (env ampf) (+ (polywave gen1 frq) (polywave gen2 frq) (polywave gen3 frq))))))))) (virginia-rail-1 beg amp) (virginia-rail-2 (+ beg .46) amp) (virginia-rail-3 (+ beg .55) amp) (virginia-rail-2 (+ beg .95) amp) (virginia-rail-3 (+ beg 1.03) amp) (virginia-rail-2 (+ beg 1.41) amp) (virginia-rail-3 (+ beg 1.48) amp) (virginia-rail-2 (+ beg 1.88) amp) (virginia-rail-3 (+ beg 1.97) amp) (virginia-rail-1 (+ beg 2.06) amp)) ;; (with-sound (:play #t) (virginia-rail 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Sage Sparrow ;;; ;;; this is one of the best so far (defanimal (sage-sparrow beg amp) ;; calif 39 4 ;; first 4 pure tones (let ((dur 0.23)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.038 0.048 0.075 0.162 0.185 0.000 0.262 0.000 0.284 0.118 0.333 0.592 0.363 0.526 0.429 0.000 0.502 0.000 0.528 0.184 0.579 0.912 0.613 0.846 0.665 0.140 0.688 0.000 0.766 0.000 0.786 0.250 0.831 1.000 0.871 0.961 0.933 0.276 1.000 0.000) :duration dur :scaler (* .7 amp))) (gen1 (make-polywave 3800.0 '(1 .995 2 .005)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1)))))) ;; 3 buzzes (let ((dur 0.23) (start (seconds->samples (+ beg 0.264)))) (let ((stop (+ start (seconds->samples dur))) (ampf (make-env '(0.000 0.000 0.055 0.118 0.071 0.099 0.079 0.329 0.107 0.208 0.114 0.248 0.125 0.568 0.153 0.202 0.159 0.224 0.173 0.532 0.200 0.199 0.213 0.226 0.226 0.467 0.255 0.128 0.270 0.348 0.299 0.106 0.313 0.138 0.351 0.000 0.454 0.000 0.464 0.052 0.471 0.021 0.481 0.046 0.485 0.138 0.496 0.058 0.502 0.104 0.507 0.322 0.515 0.163 0.523 0.124 0.534 0.584 0.537 0.350 0.544 0.230 0.549 0.411 0.555 0.825 0.560 0.439 0.569 0.323 0.573 0.421 0.579 1.000 0.591 0.348 0.603 0.981 0.612 0.433 0.618 0.235 0.628 0.981 0.636 0.425 0.643 0.301 0.649 0.432 0.653 0.799 0.666 0.185 0.671 0.286 0.680 0.660 0.691 0.061 0.698 0.139 0.704 0.334 0.719 0.093 0.769 0.038 0.805 0.026 0.838 0.060 0.854 0.139 0.865 0.046 0.872 0.201 0.880 0.004 0.891 0.174 0.899 0.042 0.907 0.201 0.918 0.029 0.926 0.113 0.936 0.019 0.943 0.068 0.957 0.013 0.960 0.074 0.971 0.021 1.000 0.000 ) :duration dur :scaler (* .4 amp))) (frqf (make-env '(0.000 0.609 0.026 0.606 0.056 0.316 0.060 0.568 0.080 0.455 0.096 0.309 0.101 0.574 0.128 0.451 0.144 0.300 0.150 0.563 0.176 0.451 0.194 0.281 0.199 0.549 0.223 0.465 0.244 0.295 0.256 0.506 0.274 0.435 0.289 0.291 0.307 0.487 0.335 0.284 0.456 0.373 0.467 0.584 0.480 0.435 0.490 0.604 0.507 0.426 0.512 0.606 0.529 0.416 0.532 0.510 0.537 0.597 0.551 0.412 0.554 0.508 0.560 0.597 0.576 0.426 0.579 0.519 0.586 0.600 0.598 0.442 0.608 0.584 0.623 0.449 0.633 0.588 0.649 0.442 0.655 0.570 0.673 0.453 0.681 0.563 0.700 0.396 0.706 0.570 0.819 0.469 0.829 0.307 0.835 0.471 0.847 0.307 0.854 0.515 0.865 0.323 0.871 0.522 0.881 0.314 0.886 0.398 0.889 0.531 0.904 0.304 0.909 0.494 0.920 0.311 0.925 0.499 0.942 0.284 0.943 0.428 0.957 0.371 0.958 0.513 1.000 0.508 ) :duration dur :scaler (hz->radians 4300.0) :offset (hz->radians 1000))) (gen1 (make-polywave 0.0 '(1 .99 2 .005 3 .005)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf))))))) ;; next pure tone (overlaps next) (let ((dur (* 3 0.088)) (start (seconds->samples (+ beg 0.517)))) (let ((stop (+ start (seconds->samples dur))) (ampf (make-env '(0.000 0.000 0.079 0.082 0.202 0.616 0.333 0.966 0.423 1.000 0.548 0.851 0.831 0.146 1.000 0.050 3 0) :duration dur :scaler amp)) (gen1 (make-polywave 3900.0 '(1 .985 2 .005 3 .01)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1)))))) ;; another buzz (let ((dur 0.236) (start (seconds->samples (+ beg 0.627)))) (let ((stop (+ start (seconds->samples dur))) (ampf (make-env '(0.000 0.000 0.020 0.352 0.045 0.261 0.068 0.462 0.086 0.256 0.109 0.295 0.130 0.506 0.152 0.151 0.176 0.705 0.192 0.359 0.202 0.169 0.230 0.666 0.247 0.293 0.263 0.190 0.282 0.652 0.307 0.124 0.323 0.259 0.343 0.723 0.353 0.364 0.368 0.167 0.384 0.293 0.397 0.785 0.405 0.380 0.421 0.128 0.437 0.256 0.452 0.762 0.466 0.300 0.481 0.112 0.490 0.245 0.507 0.826 0.522 0.334 0.529 0.165 0.539 0.103 0.563 0.762 0.575 0.309 0.593 0.192 0.608 0.318 0.617 0.945 0.645 0.098 0.663 0.256 0.677 0.906 0.691 0.384 0.707 0.092 0.721 0.334 0.736 1.000 0.757 0.316 0.760 0.144 0.769 0.080 0.777 0.297 0.794 0.771 0.825 0.108 0.837 0.277 0.854 0.867 0.864 0.263 0.881 0.085 0.899 0.204 0.913 0.753 0.944 0.098 0.958 0.130 0.974 0.563 1.000 0.000 ) :duration dur :scaler (* .125 amp))) (frqf (make-env '(0.000 0.403 0.030 0.502 0.034 0.369 0.067 0.433 0.084 0.556 0.087 0.375 0.104 0.386 0.121 0.457 0.131 0.512 0.135 0.345 0.147 0.372 0.168 0.437 0.184 0.509 0.189 0.362 0.214 0.416 0.238 0.505 0.242 0.358 0.265 0.403 0.290 0.509 0.295 0.352 0.317 0.396 0.345 0.509 0.350 0.345 0.377 0.416 0.401 0.509 0.404 0.362 0.428 0.403 0.456 0.505 0.461 0.362 0.482 0.406 0.508 0.509 0.513 0.355 0.524 0.354 0.539 0.399 0.563 0.505 0.568 0.358 0.581 0.364 0.624 0.505 0.627 0.352 0.638 0.354 0.652 0.399 0.682 0.495 0.687 0.355 0.699 0.371 0.715 0.416 0.741 0.512 0.745 0.352 0.757 0.361 0.772 0.403 0.797 0.495 0.802 0.354 0.814 0.364 0.834 0.416 0.858 0.519 0.862 0.358 0.884 0.406 0.914 0.498 0.923 0.369 0.940 0.381 0.955 0.435 0.976 0.493 0.982 0.361 1.000 0.364) :duration dur :scaler (hz->radians 6100))) (gen1 (make-polywave 0.0 '(1 .99 2 .01)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf))))))) ;; 2 more buzzes (let ((dur 0.22) (start (seconds->samples (+ beg 0.897)))) (let ((stop (+ start (seconds->samples dur))) (ampf (make-env '(0.000 0.000 0.024 0.034 0.032 0.018 0.042 0.059 0.047 0.029 0.057 0.101 0.062 0.043 0.072 0.146 0.079 0.016 0.087 0.183 0.095 0.031 0.103 0.194 0.109 0.050 0.117 0.241 0.125 0.031 0.132 0.268 0.140 0.038 0.148 0.335 0.155 0.050 0.164 0.351 0.170 0.068 0.182 0.401 0.187 0.151 0.194 0.511 0.203 0.187 0.212 0.531 0.218 0.273 0.227 0.662 0.233 0.473 0.242 0.775 0.249 0.604 0.268 0.919 0.279 0.878 0.289 1.000 0.301 0.795 0.313 0.775 0.331 0.563 0.341 0.561 0.375 0.236 0.407 0.124 0.426 0.108 0.436 0.000 0.591 0.000 0.618 0.052 0.626 0.032 0.649 0.122 0.657 0.076 0.676 0.270 0.687 0.205 0.704 0.469 0.713 0.360 0.721 0.442 0.728 0.227 0.735 0.585 0.751 0.518 0.757 0.272 0.768 0.694 0.780 0.592 0.790 0.324 0.799 0.712 0.811 0.680 0.821 0.286 0.833 0.718 0.840 0.687 0.850 0.216 0.861 0.656 0.874 0.592 0.881 0.194 0.892 0.477 0.901 0.468 0.914 0.153 0.924 0.349 0.939 0.085 1.000 0.000) :duration dur :scaler (* .8 amp))) (frqf (make-env '(0.000 0.600 0.214 0.619 0.258 0.609 0.298 0.534 0.391 0.427 0.629 0.483 0.646 0.613 0.660 0.513 0.678 0.623 0.694 0.508 0.708 0.628 0.724 0.529 0.737 0.642 0.753 0.527 0.769 0.634 0.783 0.527 0.800 0.642 0.814 0.521 0.831 0.648 0.845 0.523 0.862 0.644 0.876 0.536 0.893 0.640 0.908 0.531 0.923 0.642 1.000 0.563) :duration dur :scaler (hz->radians 5950))) (gen1 (make-polywave 0.0 '(1 .98 2 .01 3 .006 4 .004)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf))))))) ;; two tones (let ((dur 0.145) (start (seconds->samples (+ beg 1.123)))) (let ((stop (+ start (seconds->samples dur))) (ampf (make-env '(0.000 0.000 0.060 0.075 0.110 0.186 0.159 0.285 0.209 0.328 0.268 0.305 0.384 0.002 0.461 0.000 0.497 0.144 0.572 0.851 0.631 1.000 0.661 0.989 0.712 0.835 0.768 0.540 0.822 0.136 0.861 0.061 0.915 0.044 0.942 0.069 1.000 0.000) :duration dur :scaler (* .6 amp))) (frqf (make-env '(0.000 0.313 0.164 0.305 0.379 0.289 0.421 0.292 0.432 0.411 0.642 0.398 1.000 0.401) :duration dur :scaler (hz->radians 7900))) (gen1 (make-polywave 0.0 '(1 .98 2 .005 3 .01 4 .005)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf))))))) ;; last buzz (let ((dur 0.321) (start (seconds->samples (+ beg 1.25)))) (let ((stop (+ start (seconds->samples dur))) (ampf (make-env '(0.000 0.000 0.011 0.132 0.016 0.059 0.027 0.220 0.034 0.078 0.044 0.323 0.051 0.080 0.059 0.561 0.065 0.103 0.072 0.674 0.085 0.028 0.094 0.072 0.102 0.654 0.108 0.088 0.118 0.922 0.139 0.031 0.145 0.109 0.149 0.579 0.156 0.134 0.165 0.917 0.173 0.770 0.179 0.222 0.185 0.023 0.189 0.096 0.196 0.690 0.201 0.039 0.209 0.961 0.217 0.842 0.225 0.031 0.238 0.067 0.244 0.566 0.249 0.129 0.257 0.904 0.262 0.801 0.270 0.147 0.278 0.049 0.283 0.140 0.288 0.612 0.294 0.036 0.301 0.979 0.309 0.925 0.318 0.124 0.329 0.052 0.334 0.432 0.339 0.041 0.348 0.718 0.354 0.879 0.366 0.065 0.377 0.080 0.380 0.494 0.387 0.103 0.401 0.817 0.413 0.054 0.423 0.088 0.429 0.447 0.434 0.057 0.446 0.824 0.450 0.708 0.459 0.070 0.470 0.059 0.473 0.279 0.478 0.044 0.489 0.760 0.494 0.726 0.507 0.072 0.514 0.044 0.520 0.276 0.527 0.052 0.535 0.506 0.539 0.592 0.552 0.054 0.559 0.078 0.564 0.245 0.573 0.052 0.584 0.633 0.589 0.483 0.596 0.088 0.605 0.065 0.611 0.258 0.616 0.067 0.625 0.488 0.628 0.545 0.642 0.054 0.653 0.085 0.656 0.227 0.665 0.049 0.670 0.401 0.674 0.468 0.679 0.416 0.687 0.062 0.696 0.072 0.701 0.147 0.708 0.078 0.715 0.444 0.719 0.514 0.734 0.052 0.741 0.031 0.748 0.142 0.753 0.065 0.764 0.442 0.780 0.065 0.787 0.052 0.794 0.147 0.801 0.054 0.811 0.370 0.815 0.331 0.825 0.054 0.834 0.041 0.840 0.140 0.846 0.049 0.858 0.362 0.863 0.279 0.870 0.044 0.882 0.034 0.885 0.109 0.892 0.052 0.897 0.072 0.902 0.209 0.908 0.269 0.916 0.044 0.930 0.021 0.934 0.085 0.942 0.026 0.958 0.129 0.972 0.039 1.000 0.000) :duration dur :scaler (* .25 amp))) (frqf (make-env '(0.000 0.592 0.013 0.550 0.023 0.615 0.035 0.548 0.043 0.612 0.054 0.530 0.063 0.646 0.071 0.556 0.098 0.545 0.103 0.654 0.113 0.558 0.143 0.550 0.150 0.664 0.155 0.550 0.178 0.556 0.185 0.641 0.191 0.556 0.227 0.563 0.234 0.643 0.238 0.550 0.270 0.553 0.276 0.630 0.280 0.553 0.310 0.550 0.317 0.620 0.322 0.550 0.356 0.548 0.363 0.612 0.367 0.548 0.402 0.550 0.407 0.628 0.413 0.553 0.445 0.550 0.449 0.607 0.453 0.537 0.485 0.540 0.492 0.615 0.497 0.545 0.529 0.543 0.537 0.612 0.542 0.537 0.572 0.532 0.579 0.581 0.583 0.537 0.613 0.537 0.617 0.597 0.623 0.522 0.656 0.525 0.662 0.589 0.668 0.535 0.703 0.535 0.706 0.597 0.712 0.530 0.742 0.530 0.747 0.581 0.757 0.540 0.786 0.540 0.791 0.602 0.797 0.537 0.832 0.537 0.836 0.605 0.843 0.532 0.859 0.587 0.891 0.491 0.901 0.594 1.000 0.545) :duration dur :scaler (hz->radians 5400))) (gen1 (make-polywave 0.0 '(1 .99 2 .01)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) ;; (with-sound (:play #t) (sage-sparrow 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Hairy woodpecker (defanimal (hairy-woodpecker beg amp) ;; calif 81 10 (let ((dur 0.08)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.099 0.188 0.152 0.148 0.211 0.558 0.242 0.267 0.278 0.519 0.434 0.472 0.527 0.543 0.612 0.479 0.792 0.941 0.831 0.523 0.854 1.000 0.913 0.422 0.927 0.200 0.946 0.430 0.971 0.304 1.000 0.000 ) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.180 0.056 0.213 0.135 0.241 0.167 0.305 0.191 0.396 0.212 0.402 0.242 0.485 0.288 0.506 0.390 0.524 0.509 0.530 0.637 0.537 0.732 0.530 0.770 0.503 0.808 0.503 0.826 0.427 0.848 0.366 0.889 0.345 0.913 0.232 1.000 0.198) :duration dur :scaler (hz->radians 10000.0))) (gen1 (make-polywave 0.0 '(1 .9 2 .09 3 .01))) (gen2 (make-polywave 0.0 '(1 .2 2 .1 3 .1 4 .1 5 .1 6 .05 7 .01))) (ampf2 (make-env '(0 1 .3 1 .4 0 .75 0 .8 1 1 1) :duration dur :scaler 1.0))) (do ((i start (+ i 1))) ((= i stop)) (let ((frq (env frqf))) (outa i (* (env ampf) (+ (polywave gen1 frq) (* (env ampf2) (polywave gen2 (* 0.5 frq))))))))))) ;; (with-sound (:play #t) (hairy-woodpecker 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Pacific-slope flycatcher (defanimal (pacific-slope-flycatcher beg amp) ;; calif 8 22 (let ((dur 0.3)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.015 0.088 0.017 0.256 0.032 0.345 0.054 0.354 0.082 0.210 0.101 0.000 0.161 0.000 0.232 0.860 0.320 1.000 0.368 0.848 0.401 0.927 0.466 0.000 0.486 0.000 0.528 0.463 0.687 0.643 0.708 0.515 0.719 0.686 0.812 0.787 0.863 0.707 0.896 0.497 0.939 0.500 0.970 0.396 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.266 0.014 0.487 0.023 0.451 0.033 0.528 0.042 0.480 0.058 0.480 0.076 0.420 0.102 0.511 0.172 0.618 0.212 0.663 0.252 0.694 0.295 0.709 0.351 0.775 0.382 0.771 0.397 0.726 0.406 0.671 0.433 0.443 0.455 0.318 0.491 0.250 0.532 0.451 0.547 0.486 0.565 0.503 0.678 0.520 0.753 0.539 0.818 0.570 0.951 0.661 1.000 0.672) :duration dur :scaler (hz->radians 10100.0))) (gen1 (make-polywave 0.0 '(1 .98 2 .005 3 .01)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) ;; (with-sound (:play #t) (pacific-slope-flycatcher 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Dusky flycatcher (defanimal (dusky-flycatcher beg amp) ;; calif 7 20.4 (let ((dur 0.125)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.018 0.291 0.036 0.414 0.103 0.559 0.131 0.572 0.212 0.748 0.279 1.000 0.297 0.994 0.354 0.272 0.400 0.102 0.417 0.000 0.580 0.000 0.588 0.089 0.619 0.164 0.647 0.362 0.660 0.364 0.687 0.042 0.700 0.091 0.731 0.692 0.746 0.659 0.766 0.385 0.779 0.314 0.794 0.071 0.812 0.042 0.844 0.374 0.868 0.333 0.891 0.177 0.924 0.069 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.535 0.036 0.500 0.087 0.460 0.145 0.451 0.229 0.458 0.288 0.470 0.335 0.507 0.386 0.533 0.416 0.521 0.583 0.314 0.656 0.353 0.677 0.398 0.682 0.537 0.696 0.567 0.711 0.540 0.723 0.414 0.751 0.419 0.788 0.470 0.796 0.567 0.809 0.600 0.829 0.574 0.841 0.460 0.864 0.460 0.892 0.505 0.924 0.528 0.971 0.516 1.000 0.495) :duration dur :scaler (hz->radians 10100.0))) (gen1 (make-polywave 0.0 '(1 .99 2 .01 3 .005)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) ;; (with-sound (:play #t) (dusky-flycatcher 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Inca dove (defanimal (inca-dove-1 beg amp) ;; south 11 9.6 (let ((dur 0.76)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.022 0.506 0.046 0.664 0.079 0.889 0.109 0.684 0.136 0.980 0.166 0.806 0.264 0.779 0.427 0.000 0.674 0.000 0.707 0.751 0.750 0.609 0.777 0.747 0.791 0.403 0.815 0.680 0.842 0.368 0.875 0.285 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.268 0.048 0.323 0.106 0.338 0.184 0.331 0.247 0.321 0.284 0.294 0.314 0.296 0.419 0.287 0.435 0.254 0.683 0.237 0.696 0.285 0.715 0.323 0.748 0.321 0.781 0.306 0.830 0.300 0.875 0.277 0.922 0.264 1.000 0.208) :duration dur :scaler (hz->radians 2850.0))) (gen1 (make-polywave 0.0 '(1 .99 3 .01))) (rndf (make-env '(0 0 .3 0 .4 1 .5 0 .65 0 .7 .1 .85 .1 1 1) :duration dur)) (rnd (make-rand-interp 400 (hz->radians 100)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (+ (env frqf) (* (env rndf) (rand-interp rnd)))))))))) ;; (with-sound (:play #t) (inca-dove-1 0 .5)) (defanimal (inca-dove-2 beg amp) ;; south 11 11.3 ("what the hell") (let ((pitch 5150) (dur1 .1) (dur2 .07) (dur3 .29) (start1 (seconds->samples beg))) (let ((stop1 (+ start1 (seconds->samples dur1))) (ampf1 (make-env '(0.000 0.000 0.354 0.256 0.417 0.212 0.543 0.031 0.579 0.101 0.608 0.606 0.635 0.822 0.666 0.744 0.724 0.046 0.749 0.637 0.783 0.981 0.821 0.966 0.869 0.660 0.905 0.746 0.930 0.702 0.972 0.197 1.000 0.000) :duration dur1 :scaler amp)) (frqf1 (make-env '(0.000 0.092 0.082 0.115 0.201 0.137 0.351 0.143 0.477 0.140 0.553 0.162 0.624 0.166 0.675 0.159 0.770 0.166 0.838 0.162 0.933 0.156 1.000 0.156) :duration dur1 :scaler (hz->radians pitch))) (start2 (seconds->samples (+ beg .2)))) (let ((stop2 (+ start2 (seconds->samples dur2))) (ampf2 (make-env '(0.000 0.000 0.254 0.252 0.513 0.997 0.612 0.943 0.675 0.990 0.851 0.809 0.906 0.608 1.000 0.000) :duration dur2 :scaler amp)) (frqf2 (make-env '(0.000 0.129 0.158 0.154 0.369 0.173 0.450 0.173 0.867 0.164 1.000 0.138) :duration dur2 :scaler (hz->radians pitch))) (start3 (seconds->samples (+ beg .3)))) (let ((stop3 (+ start3 (seconds->samples dur3))) (ampf3 (make-env '(0.000 0.000 0.017 0.084 0.043 1.000 0.049 0.964 0.065 0.202 0.071 0.311 0.084 1.000 0.096 0.851 0.109 0.363 0.123 0.920 0.140 0.790 0.150 0.308 0.162 0.931 0.166 0.896 0.177 0.414 0.186 0.859 0.190 0.794 0.197 0.264 0.204 0.890 0.209 0.858 0.216 0.218 0.228 0.934 0.233 0.885 0.243 0.331 0.248 0.776 0.253 0.877 0.264 0.372 0.274 0.881 0.277 0.869 0.287 0.128 0.290 0.481 0.292 0.789 0.296 0.848 0.302 0.660 0.307 0.182 0.311 0.478 0.313 0.831 0.318 0.950 0.322 0.881 0.330 0.175 0.334 0.559 0.338 0.896 0.341 0.953 0.350 0.438 0.356 0.829 0.362 0.952 0.364 0.887 0.374 0.309 0.387 0.942 0.391 0.930 0.396 0.796 0.407 0.912 0.421 0.272 0.428 0.633 0.431 0.847 0.436 0.878 0.446 0.222 0.452 0.811 0.459 0.967 0.468 0.825 0.475 0.942 0.480 0.896 0.491 0.153 0.506 0.919 0.512 0.867 0.523 0.482 0.532 0.581 0.544 0.402 0.551 0.633 0.559 0.767 0.563 0.740 0.575 0.485 0.587 0.638 0.597 0.656 0.606 0.590 0.616 0.477 0.627 0.025 0.634 0.213 0.642 0.301 0.665 0.251 0.673 0.156 0.687 0.276 0.717 0.159 0.725 0.207 0.735 0.094 0.749 0.157 0.769 0.108 0.799 0.155 0.827 0.115 0.858 0.142 0.876 0.070 1.000 0.000) :duration dur3 :scaler amp)) (frqf3 (make-env '(0.000 0.172 0.135 0.191 0.199 0.192 0.266 0.176 0.325 0.173 0.384 0.182 0.423 0.186 0.614 0.173 0.896 0.145 1.000 0.138) :duration dur3 :scaler (hz->radians pitch))) (gen1 (make-polywave 0.0 '(1 .99 3 .01))) (rnd (make-rand-interp 300 (hz->radians 50)))) (do ((i start1 (+ i 1))) ((= i stop1)) (outa i (* (env ampf1) (polywave gen1 (env frqf1))))) (do ((i start2 (+ i 1))) ((= i stop2)) (outa i (* (env ampf2) (polywave gen1 (env frqf2))))) (do ((i start3 (+ i 1))) ((= i stop3)) (outa i (* (env ampf3) (polywave gen1 (+ (env frqf3) (rand-interp rnd))))))))))) ;; (with-sound (:play #t) (inca-dove-2 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Great kiskadee (defanimal (great-kiskadee beg amp) ;; south 37 16.5 ;; note #1 (let ((dur 0.123)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.013 0.068 0.026 0.000 0.048 0.030 0.053 0.211 0.068 0.000 0.083 0.000 0.093 0.184 0.098 0.479 0.114 0.000 0.125 0.000 0.135 0.216 0.140 0.526 0.159 0.000 0.172 0.000 0.174 0.159 0.179 0.252 0.185 0.625 0.190 0.578 0.205 0.000 0.218 0.066 0.225 0.301 0.230 0.715 0.240 0.592 0.250 0.000 0.260 0.077 0.280 0.800 0.295 0.000 0.305 0.099 0.324 0.822 0.341 0.000 0.351 0.137 0.370 0.855 0.377 0.660 0.389 0.000 0.396 0.110 0.405 0.397 0.414 0.868 0.422 0.751 0.442 0.071 0.457 0.562 0.461 0.827 0.470 0.759 0.488 0.438 0.496 0.863 0.506 0.822 0.519 0.666 0.538 0.737 0.553 0.737 0.567 0.871 0.619 0.973 0.650 0.847 0.694 0.375 0.766 0.238 0.789 0.353 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.357 0.048 0.353 0.056 0.407 0.098 0.353 0.105 0.395 0.142 0.347 0.145 0.390 0.183 0.353 0.194 0.403 0.231 0.374 0.240 0.420 0.273 0.372 0.285 0.434 0.317 0.388 0.332 0.438 0.364 0.376 0.382 0.438 0.406 0.384 0.427 0.447 0.454 0.370 0.472 0.432 0.489 0.436 0.500 0.399 0.527 0.418 0.561 0.420 0.647 0.359 0.711 0.317 0.736 0.313 .9 .2 .95 .15) :duration dur :scaler (hz->radians (* 0.5 8280.0)))) (gen1 (make-polywave 0.0 (normalize-partials '(1 .17 3 .1 4 .1 5 .14 6 .01)))) (ampf1 (make-env '(0 .1 .3 1 .5 1 .8 0 1 0) :duration dur)) (gen2 (make-polywave 0.0 (normalize-partials '(2 .95 3 .04 4 .03))))) (do ((i start (+ i 1))) ((= i stop)) (let ((frq (env frqf))) (outa i (* (env ampf) (+ (* (env ampf1) (polywave gen1 frq)) (polywave gen2 frq)))))))) ;; note #2 (let ((dur 0.38)) (let ((start (seconds->samples (+ beg .2))) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.024 0.225 0.147 0.534 0.263 0.731 0.406 0.881 0.597 0.873 0.772 0.754 0.897 0.503 0.926 0.582 1.000 0.000) :duration dur :scaler (* 0.8 amp))) (frqf (make-env '(0.000 0.195 0.066 0.286 0.086 0.305 0.120 0.365 0.187 0.417 0.345 0.461 0.525 0.483 0.748 0.450 0.853 0.429 0.919 0.392 0.957 0.328 0.971 0.253 1.000 0.214) :duration dur :scaler (hz->radians (* 0.5 5500.0)))) (gen1 (make-polywave 0.0 (normalize-partials '(3 .01 4 .01 5 .01 6 .01)))) (gen2 (make-polywave 0.0 (normalize-partials '(1 .08 2 1.0 3 .06 5 .02 7 .007 8 .003 10 .001)))) (ampf1 (make-env '(0 1 .07 1 .15 .1 .85 .1 .9 1 1 1) :duration dur)) (ampf2 (make-env '(0 0 .3 1 .8 1 1 0) :duration dur))) (do ((i start (+ i 1))) ((= i stop)) (let ((frq (env frqf))) (outa i (* (env ampf) (+ (* (env ampf1) (polywave gen1 frq)) (* (env ampf2) (polywave gen2 frq)))))))))) ;; (with-sound (:play #t) (great-kiskadee 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Chestnut-sided warbler (define (chestnut-sided-warbler beg1 amp1) ;; east 12 3.5 (defanimal (chestnut-sided-warbler-1 beg amp) ;; 1st 6 notes (let ((dur 0.11)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.188 0.446 0.230 0.412 0.276 0.190 0.298 0.330 0.302 0.158 0.309 0.278 0.312 0.037 0.324 0.126 0.367 0.077 0.400 0.261 0.459 0.880 0.482 0.710 0.493 0.798 0.503 0.628 0.519 0.998 0.534 0.591 0.559 0.843 0.565 0.769 0.579 0.835 0.601 0.562 0.622 0.663 0.641 0.581 0.642 0.689 0.660 0.465 0.682 0.601 0.707 0.678 0.724 0.603 0.746 0.668 0.758 0.589 0.768 0.682 0.814 0.549 0.833 0.638 0.865 0.582 0.881 0.618 0.915 0.527 0.965 0.143 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.262 0.127 0.273 0.263 0.273 0.294 0.320 0.318 0.383 0.346 0.410 0.373 0.386 0.396 0.353 0.421 0.339 0.458 0.336 0.490 0.306 0.516 0.303 0.534 0.287 0.598 0.267 0.689 0.245 0.806 0.223 1.000 0.212) :duration dur :scaler (hz->radians 22000.0))) (gen1 (make-polywave 0.0 '(1 .99 2 .01)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) (defanimal (chestnut-sided-warbler-2 beg amp) ;; notes 7 and 8 (let ((dur 0.17)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.213 0.394 0.239 0.394 0.319 0.669 0.337 0.584 0.354 0.683 0.369 0.620 0.381 0.705 0.387 0.556 0.398 0.642 0.419 0.683 0.468 0.576 0.490 0.424 0.513 0.576 0.589 0.212 0.644 0.380 0.693 0.609 0.708 0.537 0.721 0.402 0.729 0.515 0.754 0.620 0.767 0.526 0.785 0.749 0.812 0.942 0.827 0.675 0.835 0.733 0.853 0.573 0.863 0.369 0.876 1.000 0.881 0.565 0.887 0.893 0.910 0.857 0.919 0.672 0.939 0.774 0.950 0.551 0.968 0.477 0.982 0.050 0.989 0.102 1.000 0.000) :duration dur :scaler (* .9 amp))) (frqf (make-env '(0.000 0.129 0.067 0.160 0.129 0.174 0.184 0.176 0.273 0.196 0.351 0.212 0.390 0.229 0.426 0.251 0.470 0.270 0.503 0.253 0.538 0.204 0.563 0.182 0.594 0.168 0.633 0.176 0.688 0.218 0.715 0.223 0.733 0.240 0.750 0.281 0.794 0.303 0.844 0.314 0.894 0.320 0.945 0.336 1.000 0.325) :duration dur :scaler (hz->radians 22000.0))) (gen1 (make-polywave 0.0 '(1 .98 2 .01 3 .005 4 .003)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) (defanimal (chestnut-sided-warbler-3 beg amp) ;; last note (let ((dur 0.19)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.015 0.036 0.074 0.344 0.105 0.331 0.111 0.427 0.137 0.455 0.152 0.567 0.166 0.466 0.178 0.840 0.194 0.749 0.207 0.884 0.232 0.992 0.239 0.953 0.245 0.763 0.255 0.895 0.260 0.749 0.272 0.862 0.286 0.650 0.295 0.744 0.302 0.636 0.334 0.501 0.352 0.711 0.375 0.730 0.384 0.559 0.395 0.620 0.404 0.576 0.419 0.656 0.443 0.540 0.462 0.559 0.473 0.490 0.487 0.534 0.566 0.267 0.582 0.320 0.645 0.154 0.714 0.113 1.000 0.000) :duration dur :scaler (* .7 amp))) (frqf (make-env '(0.000 0.416 0.039 0.419 0.063 0.410 0.092 0.386 0.127 0.342 0.167 0.314 0.229 0.278 0.334 0.245 0.497 0.198 0.579 0.179 0.628 0.176 0.675 0.171 0.731 0.160 0.841 0.152 1.000 0.118) :duration dur :scaler (hz->radians 22000.0))) (gen1 (make-polywave 0.0 '(1 .98 2 .01)))) ; there are 3 to 5, but they alias at 44KHz (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) (let ((amps (vector .1 .3 .6 .8 .9 1.0)) (begs (vector 0.0 0.156 .311 .454 .594 .731))) (do ((call 0 (+ call 1))) ((= call 6)) (chestnut-sided-warbler-1 (+ beg1 (begs call)) (* amp1 (amps call))))) (chestnut-sided-warbler-2 (+ beg1 .88) amp1) (chestnut-sided-warbler-2 (+ beg1 1.09) amp1) (chestnut-sided-warbler-3 (+ beg1 1.3) amp1)) ;; (with-sound (:play #t) (chestnut-sided-warbler 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Yellow-bellied flycatcher (defanimal (yellow-bellied-flycatcher beg amp) ;; east 40 3.1 (let ((dur 0.167)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.031 0.122 0.054 0.665 0.082 0.777 0.092 0.724 0.105 0.774 0.109 0.639 0.116 0.697 0.121 0.577 0.135 0.781 0.149 0.368 0.153 0.419 0.171 0.092 0.176 0.234 0.224 0.028 0.264 0.191 0.284 0.619 0.299 0.709 0.304 0.914 0.311 0.861 0.316 0.945 0.320 0.809 0.327 0.957 0.332 0.786 0.337 0.972 0.348 0.973 0.362 0.742 0.377 0.358 0.390 0.388 0.413 0.035 0.420 0.070 0.428 0.031 0.450 0.068 0.458 0.022 0.471 0.088 0.480 0.051 0.490 0.189 0.499 0.041 0.509 0.164 0.518 0.101 0.526 0.230 0.536 0.046 0.544 0.188 0.554 0.241 0.557 0.139 0.563 0.214 0.567 0.316 0.578 0.038 0.584 0.192 0.595 0.303 0.598 0.186 0.607 0.381 0.615 0.082 0.621 0.132 0.628 0.286 0.634 0.266 0.638 0.300 0.646 0.385 0.655 0.109 0.662 0.084 0.664 0.170 0.668 0.247 0.675 0.212 0.687 0.382 0.697 0.122 0.704 0.086 0.708 0.236 0.715 0.262 0.718 0.334 0.724 0.251 0.727 0.364 0.730 0.319 0.740 0.088 0.744 0.045 0.749 0.120 0.752 0.286 0.759 0.373 0.764 0.259 0.770 0.341 0.778 0.234 0.782 0.057 0.789 0.122 0.794 0.245 0.801 0.336 0.808 0.231 0.813 0.327 0.821 0.224 0.826 0.045 0.838 0.197 0.846 0.346 0.861 0.266 0.867 0.074 0.874 0.189 0.880 0.168 0.887 0.388 0.904 0.489 0.917 0.520 0.922 0.497 0.929 0.258 0.936 0.253 0.943 0.124 0.950 0.180 0.959 0.051 0.971 0.099 0.974 0.061 0.980 0.089 0.988 0.032 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.341 0.025 0.368 0.045 0.434 0.059 0.482 0.073 0.482 0.086 0.465 0.101 0.434 0.127 0.416 0.150 0.392 0.181 0.341 0.205 0.319 0.232 0.339 0.268 0.407 0.289 0.458 0.311 0.500 0.324 0.509 0.390 0.518 0.408 0.590 0.444 0.487 0.455 0.247 0.470 0.253 0.479 0.289 0.485 0.394 0.495 0.421 0.502 0.370 0.507 0.304 0.515 0.286 0.522 0.304 0.523 0.438 0.529 0.454 0.538 0.441 0.546 0.319 0.552 0.295 0.559 0.326 0.562 0.425 0.567 0.452 0.574 0.427 0.582 0.357 0.592 0.324 0.600 0.344 0.602 0.416 0.608 0.445 0.616 0.447 0.625 0.339 0.634 0.322 0.642 0.337 0.643 0.394 0.645 0.454 0.654 0.452 0.664 0.357 0.674 0.335 0.683 0.339 0.685 0.427 0.692 0.458 0.698 0.430 0.704 0.352 0.714 0.337 0.721 0.346 0.727 0.436 0.731 0.456 0.737 0.434 0.742 0.374 0.756 0.346 0.767 0.355 0.773 0.443 0.780 0.460 0.786 0.438 0.791 0.385 0.799 0.348 0.810 0.366 0.815 0.421 0.821 0.434 0.824 0.419 0.831 0.372 0.841 0.359 0.851 0.357 0.854 0.388 0.856 0.515 0.864 0.568 0.871 0.555 0.883 0.436 0.914 0.421 0.930 0.385 1.000 0.368) :duration dur :scaler (hz->radians 10000.0))) (gen1 (make-polywave 0.0 '(1 .98 2 .02 3 .005)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) ;; (with-sound (:play #t) (yellow-bellied-flycatcher 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Black-throated blue warbler (define (black-throated-blue-warbler beg1 amp1) ;; east 15 9.8 (defanimal (black-throated-blue-warbler-1 beg dur amp ampf frq frqf ind) (let ((speed 200)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env ampf :duration dur :scaler amp)) (frqf1 (make-env frqf :duration dur :scaler (hz->radians frq))) (gen1 (make-polywave 0.0 '(1 .99 2 .008 3 .003))) (vib (make-oscil speed)) (vibf (make-env '(0 1 .8 1 .9 0 1 0) :duration dur :scaler (hz->radians ind))) (rnd (make-rand-interp 800)) (trem (make-oscil (* 2 speed)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (+ .25 (* .45 (abs (+ (rand-interp rnd) (* .7 (oscil trem)))))) (polywave gen1 (+ (env frqf1) (* (env vibf) (oscil vib)))))))))) (let ((main-ampf '(0.000 0.000 0.321 0.215 0.679 0.569 0.826 0.992 0.874 1.000 1.000 0.000)) (main-frqf '(0.000 0.228 0.795 0.210 0.816 0.235 0.827 0.199 0.846 0.217 0.882 0.181 1.000 0.206)) (other-ampf '(0.000 0.000 0.139 0.356 0.541 0.652 0.766 0.838 0.834 1.000 0.932 0.257 1.000 0.000))) (black-throated-blue-warbler-1 beg1 .053 (* .2 amp1) '(0.000 0.000 0.017 0.079 0.082 0.142 0.142 0.122 0.199 0.213 0.237 0.150 0.291 0.201 0.317 0.102 0.352 0.197 0.395 0.248 0.415 0.201 0.435 0.335 0.468 0.323 0.488 0.429 0.514 0.350 0.581 0.870 0.616 0.583 0.678 0.697 0.709 0.618 0.752 1.000 0.801 0.350 0.815 0.295 0.838 0.500 0.895 0.197 0.911 0.366 0.929 0.220 0.955 0.248 0.972 0.134 0.987 0.197 1.000 0.000) 22000 '(0.000 0.222 0.038 0.204 0.099 0.208 0.134 0.197 0.205 0.208 0.244 0.186 0.288 0.211 0.336 0.194 0.382 0.201 0.421 0.190 0.475 0.215 0.511 0.190 0.563 0.208 0.613 0.190 0.656 0.208 0.695 0.194 0.755 0.194 1.000 0.133) 10) (black-throated-blue-warbler-1 (+ beg1 .156) .11 (* .4 amp1) main-ampf 20000 main-frqf 100) (black-throated-blue-warbler-1 (+ beg1 .33) .135 (* .6 amp1) main-ampf 21000 main-frqf 200) (black-throated-blue-warbler-1 (+ beg1 .33) .135 (* .6 amp1) main-ampf 22000 main-frqf 200) (black-throated-blue-warbler-1 (+ beg1 .51) .175 amp1 other-ampf 22400.0 main-frqf 200) (black-throated-blue-warbler-1 (+ beg1 .72) .152 amp1 other-ampf 23000.0 main-frqf 200) (black-throated-blue-warbler-1 (+ beg1 .94) .23 (* .5 amp1) '(0.000 0.000 0.022 0.300 0.067 0.788 0.191 0.919 0.331 0.958 0.581 1.000 0.805 0.946 0.929 0.773 1.000 0.000) 5400.0 '(0 1 1 1) 400))) ;; (with-sound (:play #t) (black-throated-blue-warbler 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Great crested flycatcher (defanimal (great-crested-flycatcher beg amp) ;; east 46 6 (let ((dur 0.318)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.122 0.198 0.136 0.168 0.165 0.235 0.184 0.411 0.191 0.373 0.212 0.542 0.224 0.499 0.242 0.715 0.288 0.617 0.294 0.559 0.307 0.644 0.338 0.491 0.348 0.586 0.357 0.576 0.368 0.491 0.373 0.539 0.392 0.536 0.427 0.656 0.446 0.642 0.528 0.795 0.556 0.636 0.566 0.997 0.582 0.100 0.590 0.384 0.597 0.097 0.601 0.213 0.607 0.120 0.614 0.586 0.653 0.334 0.658 0.225 0.676 0.639 0.703 0.195 0.711 0.363 0.733 0.358 0.746 0.280 0.771 0.551 0.793 0.226 0.840 0.258 0.922 0.183 0.973 0.150 1.000 0.000) :duration dur :scaler amp)) (frqf1 (make-env '(0.000 0.226 0.033 0.284 0.076 0.324 0.128 0.376 0.200 0.423 0.254 0.439 0.314 0.441 0.391 0.438 0.488 0.432 0.533 0.436 0.559 0.445 0.566 0.486 0.586 0.660 0.606 0.656 0.612 0.544 0.627 0.535 0.643 0.546 0.689 0.535 0.708 0.523 0.718 0.546 0.735 0.528 0.740 0.501 1.000 0.416) :duration dur :scaler (hz->radians 7090.0))) (ampf1 (make-env '(0 1 .6 1 .65 .1 .7 .5 .75 0 1 0) :duration dur)) (gen1 (make-polywave 0.0 '(1 .92 2 .05 3 .01 4 .005 6 .005))) (frqf2 (make-env '(0.000 0.407 0.256 0.439 0.492 0.434 0.566 0.447 0.595 0.430 0.609 0.309 0.626 0.266 0.646 0.297 0.661 0.396 0.673 0.430 0.681 0.474 0.695 0.412 0.702 0.325 0.719 0.320 0.736 0.335 0.762 0.409 0.774 0.445 0.786 0.414 0.791 0.335 0.806 0.311 0.824 0.329 0.839 0.376 0.856 0.349 0.876 0.324 0.916 0.324 0.951 0.293 1.000 0.25) :duration dur :scaler (hz->radians 7090.0))) (ampf2 (make-env '(0 0 .5 0 .55 .2 .7 1 1 .5) :duration dur)) (gen2 (make-polywave 0.0 '(1 .95 2 .01 3 .01 4 .01 5 .005 6 .01))) (rnd (make-rand-interp 100 .7))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (+ (* (env ampf1) (polywave gen1 (env frqf1))) (* (env ampf2) (+ .3 (abs (rand-interp rnd))) (polywave gen2 (env frqf2)))))))))) ;; (with-sound (:play #t) (great-crested-flycatcher 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; House sparrow (defanimal (house-sparrow-1 beg amp) ;; east 99 2.9 (let ((dur 0.144)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.073 0.108 0.086 0.220 0.182 0.225 0.190 0.281 0.200 0.151 0.240 0.529 0.254 0.436 0.259 0.558 0.266 0.536 0.284 0.856 0.299 0.461 0.311 0.888 0.330 0.281 0.339 0.612 0.344 0.559 0.355 0.178 0.376 0.575 0.380 0.407 0.389 0.919 0.394 0.686 0.399 0.836 0.407 0.547 0.412 0.976 0.422 0.176 0.426 0.476 0.442 0.942 0.461 0.347 0.475 0.281 0.485 0.069 0.488 0.222 0.499 0.200 0.505 0.259 0.527 0.422 0.559 0.583 0.576 0.324 0.599 0.578 0.611 0.556 0.626 0.268 0.640 0.525 0.652 0.471 0.657 0.237 0.685 0.556 0.703 0.449 0.714 0.175 0.756 0.308 0.803 0.229 0.926 0.112 0.963 0.056 0.972 0.093 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.217 0.130 0.236 0.169 0.261 0.196 0.321 0.238 0.414 0.260 0.445 0.286 0.462 0.302 0.451 0.316 0.472 0.329 0.458 0.346 0.507 0.361 0.530 0.383 0.501 0.408 0.400 0.427 0.420 0.451 0.395 0.465 0.333 0.485 0.275 0.503 0.290 0.518 0.321 0.563 0.373 0.622 0.441 0.643 0.387 0.664 0.325 0.684 0.360 0.700 0.358 0.713 0.282 0.734 0.267 0.746 0.288 0.769 0.325 0.799 0.290 0.833 0.321 0.859 0.292 0.888 0.304 0.913 0.265 0.944 0.265 0.964 0.226 0.984 0.209 1.000 0.224) :duration dur :scaler (hz->radians 10550.0))) (rnd (make-rand-interp 4000 (hz->radians 300))) (rnd1 (make-rand-interp 4000)) (rndf1 (make-env '(0 1 .15 1 .2 0 .75 0 .8 1 1 1) :duration dur :scaler .75)) (gen1 (make-oscil)) (ampf1 (make-env '(0 0 .15 0 .2 1 .9 1 1 .2) :duration dur)) (gen2 (make-oscil)) (ampf2 (make-env '(0 .5 .15 .5 .2 .05 1 .01) :duration dur)) (gen3 (make-oscil)) (ampf3 (make-env '(0 .5 .15 .5 .2 .005 1 .005) :duration dur))) (do ((i start (+ i 1))) ((= i stop)) (let ((rf (env rndf1)) (frq (+ (env frqf) (rand-interp rnd)))) (outa i (* (env ampf) (+ (- 1.0 rf) (* rf (abs (rand-interp rnd1)))) (+ (* (env ampf1) (oscil gen1 frq)) (* (env ampf2) (oscil gen2 (* 2.0 frq))) (* (env ampf3) (oscil gen3 (* 3.0 frq))))))))))) ;; (with-sound (:play #t) (house-sparrow-1 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Gambel's quail (defanimal (gambels-quail beg amp) ;; south 8 3 (let ((dur 0.56)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.105 0.364 0.146 0.379 0.231 0.694 0.471 0.838 0.567 0.785 0.637 0.649 0.681 0.626 0.750 0.513 0.771 0.417 0.828 0.351 0.864 0.212 0.952 0.048 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.080 0.029 0.091 0.079 0.131 0.103 0.136 0.165 0.148 0.219 0.164 0.341 0.176 0.469 0.173 0.714 0.162 0.819 0.157 0.902 0.150 0.949 0.138 1.000 0.141) :duration dur :scaler (hz->radians (* 0.5 10950)))) (gen1 (make-polywave 0.0 (normalize-partials '(1 .21 2 .83 3 .05)))) (gen2 (make-polywave 0.0 (normalize-partials '(4 .03 5 .02 6 .12)))) (gen3 (make-polywave 0.0 (normalize-partials '(7 .01 8 .02 9 .007 10 .003)))) (ampf2 (make-env '(0 0 .05 0 .1 .2 .15 0 .275 1 .6 1 .9 0 1 0) :duration dur :scaler .15)) (ampf3 (make-env '(0 0 .18 0 .5 1 .7 1 .85 0 1 0) :duration dur :scaler .08))) (do ((i start (+ i 1))) ((= i stop)) (let ((frq (env frqf))) (outa i (* (env ampf) (+ (polywave gen1 frq) (* (env ampf2) (polywave gen2 frq)) (* (env ampf3) (polywave gen3 frq)))))))))) ;; (with-sound (:play #t) (gambels-quail 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Scaled quail (define (scaled-quail beg1 amp1) ;; south 7 7 (defanimal (scaled-quail-1 beg dur amp frqscl frm1frq frm2frq frmamp vibamp vibf amp4 amp5) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.026 0.166 0.052 0.609 0.058 0.250 0.066 0.892 0.070 0.465 0.073 0.909 0.079 0.255 0.088 0.766 0.091 0.350 0.096 0.607 0.105 0.504 0.106 0.932 0.119 0.296 0.126 0.978 0.129 0.540 0.134 0.609 0.136 0.347 0.140 0.425 0.142 0.274 0.148 0.998 0.154 0.393 0.156 0.816 0.161 0.266 0.166 0.614 0.170 0.810 0.174 0.482 0.177 0.773 0.184 0.305 0.192 0.937 0.198 0.296 0.199 0.596 0.203 0.350 0.207 0.738 0.212 0.399 0.213 0.602 0.222 0.650 0.228 0.464 0.238 0.526 0.246 0.266 0.259 0.403 0.283 0.320 0.323 0.365 0.388 0.249 0.405 0.196 0.432 0.191 0.496 0.135 0.582 0.120 0.621 0.071 1.000 0.000) :duration dur :scaler (* 0.3 amp))) (frqf (make-env '(0.000 0.157 0.051 0.204 0.075 0.267 0.142 0.281 0.196 0.267 0.268 0.191 0.353 0.171 1.000 0.175) :duration dur :scaler (hz->radians frqscl))) (gen1 (make-polywave 0.0 :partials '(1 2))) (gen2 (make-polywave 0.0 (list 2 (* 2 .3) 3 (* 2 .7)))) (gen6 (make-polywave 0.0 (normalize-partials '(4 .1 5 .05 6 .02)))) (gen3 (make-polywave 0.0 (normalize-partials '(9 .12 10 .02 11 .003 12 .006 15 .005 16 .004)))) (gen4 (make-oscil)) (gen5 (make-oscil)) (ampf1 (make-env '(0 1 .6 1 .9 0 1 0) :duration dur :scaler .1)) (ampf3 (make-env '(0 0 .1 .2 .4 1 .5 1 .8 0 1 0) :duration dur :scaler .3)) (ampf4 (make-env amp4 :duration dur :scaler .25)) (ampf5 (make-env amp5 :duration dur :scaler .125)) (ampf6 (make-env '(0 0 .3 0 .4 1 1 0) :duration dur :scaler .5)) (vib (make-oscil 1000)) (vibf1 (make-env vibf :duration dur :scaler (hz->radians 200))) (rnd (make-rand-interp 10000 vibamp)) (frm1 (make-formant frm1frq .97)) (frm2 (make-formant frm2frq .95)) (fr1 (* 2 5 (sin (hz->radians frm1frq)))) (fr2 (* 2 4 (sin (hz->radians frm2frq)))) (frmf (make-env frmamp :duration dur))) (do ((i start (+ i 1))) ((= i stop)) (let* ((frq (+ (env frqf) (* (env vibf1) (+ (oscil vib) (rand-interp rnd))))) (frm (env frmf)) (val (* (env ampf) (+ (* (env ampf1) (polywave gen1 frq)) (* (env ampf4) (oscil gen4 (* frq 5))) (* (env ampf5) (oscil gen5 (* frq 6))) (+ (polywave gen2 frq) (* (env ampf3) (polywave gen3 frq)) (* (env ampf6) (polywave gen6 frq))))))) (outa i (+ (* frm (+ (* fr1 (formant frm1 val)) (* fr2 (formant frm2 val)))) (* (- 1.0 frm) val))))))) (scaled-quail-1 beg1 .18 amp1 4200 2300 6400 '(0 0 .1 1 .45 1 .5 0 .7 0 .8 1 1 1) 1.5 '(0 1 .1 1 .45 1 .5 0 .6 0 .65 1 1 1) '(0 0 .1 1 .4 1 .5 0 1 0) '(0 0 .1 0 .4 1 .5 0 1 0)) (scaled-quail-1 (+ beg1 .35) .27 amp1 4000 2700 6000 '(0 0 .1 1 .25 1 .3 0 1 0) 2.0 '(0 1 .1 1 .25 1 .3 0 .9 0 1 .5) '(0 0 .1 1 .2 1 .3 0 1 0) '(0 0 .1 0 .2 1 .3 0 1 0))) ;; (with-sound (:play #t) (scaled-quail 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Montezuma quail (defanimal (montezuma-quail beg amp) ;; south 9 15 (let ((dur 1.3)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.022 0.069 0.036 0.196 0.088 0.615 0.138 0.837 0.168 0.873 0.202 0.837 0.217 0.743 0.225 0.850 0.242 0.962 0.255 0.839 0.270 0.914 0.309 0.916 0.322 0.796 0.365 0.831 0.407 0.941 0.432 0.975 0.442 0.885 0.461 0.919 0.480 0.850 0.494 0.651 0.504 0.903 0.527 0.773 0.546 0.870 0.585 0.813 0.604 0.880 0.630 0.836 0.642 0.789 0.662 0.898 0.689 0.817 0.779 0.656 0.834 0.668 0.895 0.449 0.927 0.372 0.950 0.350 0.965 0.229 0.981 0.253 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.284 0.052 0.254 0.128 0.239 0.256 0.229 0.404 0.219 0.580 0.211 0.707 0.206 1.000 0.216) :duration dur :scaler (hz->radians 8700.0))) (gen1 (make-polywave 0.0 '(1 .91 2 .008 3 .07 4 .003))) (vib (make-oscil 50)) (vibf (make-env '(0 .1 .4 .6 .9 1 1 .4) :duration dur :scaler (hz->radians 100))) (vibr (make-rand-interp 200 .5)) (rnd (make-rand-interp 240 .5))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (+ .5 (abs (rand-interp rnd))) (polywave gen1 (+ (env frqf) (* (env vibf) (+ (oscil vib) (rand-interp vibr))))))))))) ;; (with-sound (:play #t) (montezuma-quail 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Mountain quail (defanimal (mountain-quail beg amp) (let ((dur .2)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.152 0.128 0.179 0.040 0.219 0.173 0.271 0.864 0.289 0.754 0.300 0.666 0.316 0.804 0.339 0.666 0.362 0.628 0.402 0.477 0.493 0.653 0.513 0.721 0.573 0.736 0.599 0.626 0.666 0.804 0.741 0.887 0.786 0.977 0.818 0.814 0.837 0.807 0.872 0.889 0.899 0.761 0.920 0.588 0.932 0.656 0.956 0.427 0.970 0.176 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.103 0.036 0.108 0.151 0.103 0.175 0.156 0.219 0.160 0.261 0.162 0.322 0.144 0.397 0.149 0.894 0.146 0.945 0.130 1.000 0.121) :duration dur :scaler (hz->radians 10000.0))) (gen1 (make-oscil)) (ampf2 (make-env '(0 0 .1 0 .2 1 1 1) :duration dur)) (gen2 (make-polywave 0.0 '(2 .01 3 .005 4 .04 5 .003))) (rnd (make-rand-interp 4000 (hz->radians 500))) (rndf (make-env '(0 1 .2 .1 .9 .1 1 1) :duration dur))) (do ((i start (+ i 1))) ((= i stop)) (let ((frq (+ (env frqf) (* (env rndf) (rand-interp rnd))))) (outa i (* (env ampf) (+ (oscil gen1 frq) (* (env ampf2) (polywave gen2 frq)))))))))) ;; (with-sound (:play #t) (mountain-quail 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Verdin (defanimal (verdin beg amp) ;; south 57 18 (let ((begs (vector 0.0 0.28 0.57)) (durs (vector 0.12 0.15 0.15)) (amps (vector 0.25 0.75 1.0)) (frqs (vector '(0.000 0.162 0.246 0.168 0.505 0.168 0.867 0.183 0.956 0.198 1.000 0.192) '(0.000 0.162 0.246 0.168 0.867 0.183 0.897 0.186 0.926 0.204 1.000 0.192) '(0.000 0.189 0.039 0.168 0.246 0.168 1.000 0.192))) (gen1 (make-polywave 0.0 '(1 .98 2 .015 3 .005)))) (do ((call 0 (+ call 1))) ((= call 3)) (let ((start (seconds->samples (+ beg (begs call)))) (dur (durs call))) (let ((stop (+ start (seconds->samples dur))) (ampf (make-env '(0.000 0.000 0.016 0.207 0.079 0.402 0.131 0.348 0.224 0.562 0.255 0.592 0.316 0.757 0.367 0.637 0.407 0.664 0.428 0.613 0.474 0.751 0.495 0.757 0.522 0.898 0.609 1.000 0.701 0.778 0.738 0.967 0.770 0.892 0.797 0.898 0.819 0.790 0.835 0.931 0.852 0.892 0.874 0.997 0.903 0.775 0.928 0.718 0.957 0.736 1.000 0.000) :duration dur :scaler (* amp (amps call)))) (frqf (make-env (frqs call) :duration dur :scaler (hz->radians 22000.0)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))))) ;; (with-sound (:play #t) (verdin 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; White-tipped dove (defanimal (white-tipped-dove beg amp) (let ((dur 1.7)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.097 0.071 0.140 0.147 0.190 0.000 0.328 0.000 0.405 0.652 0.426 0.596 0.447 0.136 0.465 0.109 0.473 0.000 0.511 0.000 0.555 0.354 0.625 0.578 0.672 0.820 0.745 1.000 0.782 0.897 0.874 0.755 0.930 0.614 0.975 0.139 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.172 0.137 0.170 0.175 0.165 0.340 0.172 0.451 0.160 0.544 0.165 .6 .160 1.000 0.170) :duration dur :scaler (hz->radians 2550.0))) (gen1 (make-polywave 0.0 '(1 .94 2 .02 3 .05 4 .005)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) ;; (with-sound (:play #t) (white-tipped-dove 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Zone-tailed hawk (defanimal (zone-tailed-hawk beg amp) (let ((dur 1.82)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.014 0.170 0.019 0.000 0.046 0.074 0.054 0.327 0.090 0.448 0.106 0.781 0.130 0.852 0.139 1.000 0.174 1.000 0.359 0.691 0.383 0.435 0.427 0.494 0.545 0.448 0.654 0.463 0.704 0.485 0.741 0.330 0.752 0.407 0.785 0.435 0.792 0.238 0.793 0.528 0.825 0.528 0.838 0.475 0.846 0.225 0.850 0.509 0.872 0.485 0.892 0.367 0.913 0.497 0.949 0.500 0.978 0.537 0.988 0.099 1.000 0.000) :duration dur :scaler (* 0.8 amp))) (frqf (make-env '(0.000 0.283 0.026 0.321 0.048 0.368 0.051 0.404 0.055 0.330 0.064 0.357 0.076 0.357 0.097 0.387 0.108 0.427 0.184 0.438 0.356 0.452 0.371 0.431 0.380 0.408 0.460 0.401 0.510 0.390 0.555 0.397 0.589 0.386 0.615 0.388 0.667 0.376 0.718 0.382 0.783 0.365 0.807 0.348 0.841 0.333 0.875 0.314 0.905 0.314 0.925 0.340 0.957 0.344 0.972 0.325 0.983 0.302 1.000 0.237) :duration dur :scaler (hz->radians (* 0.5 8150.0)))) (gen1 (make-polywave 0.0 (list 1 (* .5 0.328) 2 (* .5 0.328) 3 (* .5 0.066) 4 (* .5 0.262) 5 (* .5 0.013) 7 (* .5 0.004)))) (gen2 (make-oscil)) (gen3 (make-polywave 0.0 (normalize-partials '(3 .2 5 .1 7 .1 9 .05 11 .05 13 .01)))) (ampf2 (make-env '(0 0 .05 0 .12 1 .18 1 .2 .6 .5 .8 .75 0 .8 .7 1 .7) :duration dur :scaler .5)) (ampf3 (make-env '(0 0 .05 0 .12 1 .6 1 .75 0 1 0) :duration dur :scaler .3 :base 10)) (rnd (make-rand-interp 3000)) (rndf (make-env '(0 0 .12 .2 .25 1 .35 1 .4 .2 .75 .3 .9 .1 .93 .4 1 0) :duration dur :scaler (hz->radians 100))) (vib (make-triangle-wave 40 (hz->radians 20))) (vibf (make-env '(0 0 .15 0 .2 1 .4 0 1 0) :duration dur))) (do ((i start (+ i 1))) ((= i stop)) (let ((noise (* (env rndf) (rand-interp rnd))) (frq (+ (env frqf) (* (env vibf) (triangle-wave vib))))) (outa i (* (env ampf) (+ (polywave gen1 (+ frq (* 1.5 noise))) (* (env ampf2) (oscil gen2 (+ (* 2.0 frq) (* 0.5 noise)))) (* (env ampf3) (polywave gen3 (+ (* 0.5 frq) (* 2.0 noise)))))))))))) ;; (with-sound (:play #t) (zone-tailed-hawk 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Red-eyed vireo (defanimal (red-eyed-vireo beg amp) ;; south 47 46 (let ((dur 0.29)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.033 0.082 0.069 0.415 0.081 0.426 0.102 0.204 0.119 0.156 0.137 0.307 0.146 0.159 0.156 0.378 0.182 0.685 0.188 0.556 0.205 0.735 0.212 0.479 0.223 0.484 0.236 0.939 0.243 0.344 0.246 0.825 0.254 0.415 0.258 0.611 0.273 0.587 0.279 0.251 0.290 0.992 0.297 0.865 0.304 0.937 0.314 0.735 0.324 0.770 0.340 0.365 0.352 0.590 0.367 0.230 0.387 0.000 0.495 0.000 0.510 0.331 0.535 0.339 0.560 0.249 0.572 0.116 0.592 0.146 0.604 0.275 0.628 0.410 0.634 0.339 0.668 0.619 0.684 0.220 0.709 0.656 0.731 0.593 0.761 0.598 0.770 0.534 0.783 0.720 0.797 0.632 0.809 0.479 0.819 0.288 0.833 0.444 0.849 0.423 0.857 0.325 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.375 0.022 0.420 0.044 0.492 0.067 0.531 0.079 0.506 0.095 0.352 0.105 0.336 0.121 0.359 0.147 0.417 0.163 0.462 0.178 0.520 0.188 0.590 0.197 0.662 0.209 0.685 0.225 0.669 0.245 0.625 0.266 0.606 0.283 0.576 0.329 0.406 0.342 0.387 0.371 0.338 0.484 0.289 0.505 0.340 0.529 0.347 0.541 0.368 0.558 0.268 0.572 0.245 0.589 0.259 0.607 0.305 0.642 0.368 0.672 0.396 0.704 0.420 0.752 0.431 0.775 0.452 0.795 0.527 0.815 0.534 0.824 0.492 0.835 0.387 0.861 0.336 0.891 0.305 0.946 0.298 1.000 0.240) :duration dur :scaler (hz->radians 8100.0))) (gen1 (make-polywave 0.0 '(1 .985 2 .005 3 .01)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) ;; (with-sound (:play #t) (red-eyed-vireo 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Crested caracara ;;; ;;; not perfect... original seems to have a harder attack, slightly different timbre, etc (defanimal (crested-caracara beg amp) ;; south 5 6.5 (do ((i 0 (+ i 1))) ((= i 17)) (let ((start (seconds->samples (+ beg (* i .04) (random .005)))) (dur (+ 0.04 (random .005)))) (let ((stop (+ start (seconds->samples dur))) (ampf (make-env '(0.000 0.000 0.003 0.273 0.032 0.068 0.055 0.147 0.073 0.033 0.116 0.958 0.143 0.641 0.180 0.869 0.193 0.340 0.207 0.618 0.235 0.881 0.258 0.587 0.293 0.387 0.320 0.676 0.334 0.263 0.352 0.338 0.369 0.000 0.396 0.573 0.407 0.333 0.417 0.660 0.431 0.779 0.445 0.268 0.498 0.1 1.000 0.000) :duration dur :scaler amp)) (gen1 (make-polywave 1600 (normalize-partials '(1 .4 2 .7 3 .01 4 .01 5 .01)))) (gen2 (make-polywave 1200 '(1 .4 2 1))) (index (hz->radians 800)) (rnd (make-rand-interp 4000 .425))) (do ((k start (+ k 1))) ((= k stop)) (outa k (* (env ampf) (polywave gen1 (* index (+ (polywave gen2) (rand-interp rnd))))))))))) ;; (with-sound (:play #t) (crested-caracara 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Trumpeter swan ;;; ;;; this is a good one ;;; (someday also 55) (define (trumpeter-swan-1 beg amp) ;; east 19 44 (defanimal (trumpeter-swan-a beg amp) (let ((dur 0.053)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.086 0.411 0.253 0.887 0.466 0.989 0.627 0.992 0.782 0.842 1.000 0.000) :duration dur :scaler amp)) (gen1 (make-polywave 356.0 (normalize-partials '(1 .1 2 1.0 3 .08 4 .2 5 .1 6 .03 7 .03 8 .03)))) (vib (make-oscil 130.0)) (index (hz->radians 30))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (* index (oscil vib))))))))) (defanimal (trumpeter-swan-b beg amp) (let ((dur 0.12)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.038 0.460 0.106 0.554 0.152 1.000 0.187 0.569 0.225 0.694 0.316 0.000 0.381 0.000 0.462 0.827 0.512 0.000 0.539 0.613 0.571 0.859 0.609 0.528 0.632 0.815 0.715 0.661 0.764 0.782 0.837 0.800 0.884 0.724 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.251 0.088 0.259 0.144 0.290 0.173 0.228 0.276 0.228 0.387 0.245 0.429 0.296 0.457 0.310 0.484 0.296 0.514 0.265 0.548 0.307 0.599 0.377 0.641 0.352 0.706 0.346 0.741 0.338 0.773 0.346 1.000 0.346) :duration dur :scaler (hz->radians (* 0.5 3140)))) (gen2 (make-polywave 0.0 (float-vector 2 (* .6 .8) 3 (* .6 .2)))) (gen2a (make-polywave 0.0 (normalize-partials '( 4 .35 5 .19 6 .12 7 .03 8 .02)))) (ampf2a (make-env '(0 1 .6 1 1 0) :duration dur :scaler .4 :base 10)) (gen3 (make-nrxysin :n 12 :r .85 :ratio 1/9)) (ampf3 (make-env '(0 0 .1 0 .15 .5 .2 0 .4 0 .45 .7 .5 0 .55 1 .7 1 .8 0 .9 .1 1 0) :duration dur :scaler .02)) (gen1 (make-oscil)) (ampf1 (make-env '(0 0 .5 0 .6 1 .9 1 1 0) :duration dur :scaler .2))) (set! (mus-phase gen2) (* 0.5 pi)) (set! (mus-phase gen2a) (* 0.5 pi)) (do ((i start (+ i 1))) ((= i stop)) (let ((frq (env frqf))) (outa i (* (env ampf) (+ (polywave gen2 frq) (* (env ampf2a) (polywave gen2a frq)) (* (env ampf1) (oscil gen1 frq)) (* (env ampf3) (nrxysin gen3 (* 9.0 frq))))))))))) (defanimal (trumpeter-swan-c beg amp) (let ((dur 0.11)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.029 0.244 0.084 0.525 0.111 0.515 0.124 0.376 0.153 0.334 0.183 0.166 0.205 0.000 0.240 0.769 0.261 0.775 0.280 0.271 0.297 0.000 0.338 0.773 0.423 1.000 0.529 0.758 0.621 0.845 0.783 0.630 0.849 0.676 0.896 0.538 0.930 0.252 0.957 0.118 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.085 0.189 0.079 0.222 0.113 0.251 0.123 0.278 0.105 0.312 0.121 0.349 0.125 0.377 0.133 0.412 0.127 0.510 0.123 0.691 0.129 0.778 0.125 0.830 0.127 1.000 0.129) :duration dur :scaler (hz->radians (* 0.5 8650.0)))) (gen1 (make-polywave 0.0 (normalize-partials '(1 .01 2 .98 3 .05 4 .02 5 .005 6 .005)))) (gen2 (make-polywave 0.0 (normalize-partials '(1 .44 2 1.0 3 .34 4 .31 5 .19 6 .075 7 .04 8 .03)))) (gen3 (make-nrxysin :n 12 :r .85 :ratio 1/9)) (intrpf (make-env '(0 1 .19 1 .2 0 1 0) :duration dur)) (intrpf-1 (make-env '(0 1 .19 1 .2 0 1 0) :duration dur :offset 1.0 :scaler -1.0))) (set! (mus-phase gen2) (* 0.5 pi)) (do ((i start (+ i 1))) ((= i stop)) (let ((frq (env frqf))) (outa i (* (env ampf) (+ (* (env intrpf) (polywave gen1 frq)) (* (env intrpf-1) (+ (polywave gen2 frq) (* .03 (nrxysin gen3 (* 9.0 frq))))))))))))) (defanimal (trumpeter-swan-d beg amp) (let ((dur 0.082)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.068 0.279 0.121 0.989 0.178 0.755 0.208 0.451 0.234 0.834 0.291 0.921 0.355 0.459 0.371 0.158 0.401 0.876 0.494 1.000 0.614 0.851 0.797 0.510 0.862 0.166 0.928 0.146 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.328 0.092 0.328 0.147 0.370 0.212 0.314 0.256 0.356 0.345 0.359 0.389 0.373 0.438 0.370 0.489 0.420 0.532 0.398 0.601 0.398 0.641 0.375 0.685 0.364 0.739 0.401 0.799 0.417 0.856 0.398 1.000 0.401) :duration dur :scaler (hz->radians 1350))) (gen1 (make-oscil)) (ampf1 (make-env '(0 0 .4 .1 .5 1 .9 .5 1 0) :duration dur :scaler .3)) (gen2 (make-oscil)) (ampf2 (make-env '(0 1 .45 1 .5 .5 .6 .8 .7 .8 .75 .1 .8 .5 1 0) :duration dur :scaler .5)) (gen3 (make-nrxysin :n 12 :r .8 :ratio 1/8)) (ampf3 (make-env '(0 0 .1 1 .6 1 .8 0 1 0) :duration dur :scaler .15)) (gen4 (make-polywave 0.0 (normalize-partials '(3 .4 4 .4 5 .2 6 .1 7 .05)))) (ampf4 (make-env '(0 1 .8 1 1 0) :duration dur :scaler .5))) (do ((i start (+ i 1))) ((= i stop)) (let ((frq (env frqf))) (outa i (* (env ampf) (+ (* (env ampf1) (oscil gen1 frq)) (* (env ampf2) (oscil gen2 (* 2.0 frq))) (* (env ampf3) (nrxysin gen3 (* 8.0 frq))) (* (env ampf4) (polywave gen4 frq)))))))))) (defanimal (trumpeter-swan-e beg amp) (let ((dur 0.04) (frq 434)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.087 0.300 0.206 0.927 0.265 1.000 0.324 0.894 0.382 0.482 0.445 0.515 0.692 0.364 0.752 0.218 1.000 0.000) :duration dur :scaler amp)) (gen1 (make-polywave frq '(1 .05 2 .85 3 .1 5 .01))) (gen2 (make-nrxysin (* frq 7) 1/7 10 .8)) (ampf2 (make-env '(0 0 .1 1 .4 0 1 0) :duration dur :scaler .2)) (vib (make-rand-interp 200)) (index (hz->radians 40))) (do ((i start (+ i 1))) ((= i stop)) (let ((vb (* index (rand-interp vib)))) (outa i (* (env ampf) (+ (polywave gen1 vb) (* (env ampf2) (nrxysin gen2 vb)))))))))) (trumpeter-swan-a beg (* amp .6)) (trumpeter-swan-b (+ beg .126) (* amp .9)) (trumpeter-swan-c (+ beg .259) amp) (trumpeter-swan-d (+ beg .408) (* amp .6)) (trumpeter-swan-e (+ beg .54) (* amp .3))) ;; (with-sound (:play #t) (trumpeter-swan-1 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Wrentit (define (wrentit beg1 amp1) ;; calif 1 3 (defanimal (wrentit-1 beg dur amp frqscl) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.095 0.221 0.193 0.692 0.293 0.814 0.380 0.727 0.486 1.000 0.543 0.972 0.611 0.664 0.720 0.435 0.788 0.115 0.853 0.138 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.262 0.112 0.288 0.197 0.304 0.275 0.319 0.508 0.313 0.634 0.281 0.743 0.281 0.811 0.249 0.869 0.256 1.000 0.240) :duration dur :scaler (hz->radians (* frqscl 5000.0)))) (gen1 (make-polywave 0.0 '(1 .005 2 .9 3 .005 4 .01 6 .03 7 .005 8 .005)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf))))))) (defanimal (wrentit-2 beg dur amp frqscl) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.091 0.616 0.150 0.724 0.195 0.667 0.259 0.686 0.387 1.000 0.447 0.770 0.482 0.740 0.507 0.623 0.552 0.693 0.629 0.557 0.684 0.288 0.713 0.321 0.738 0.232 0.754 0.162 0.771 0.225 0.786 0.150 0.792 0.197 0.801 0.126 0.808 0.225 0.816 0.122 0.829 0.178 0.832 0.105 0.840 0.211 0.849 0.094 0.856 0.173 0.880 0.089 0.898 0.220 0.914 0.124 .925 .01 1 0) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.269 0.105 0.297 0.182 0.319 0.311 0.319 0.428 0.304 0.534 0.281 0.688 0.269 0.789 0.244 0.825 0.215 1 .21) :duration dur :scaler (hz->radians (* frqscl 5040.0)))) (gen1 (make-polywave 0.0 '(1 .005 3 .005 4 .01 6 .03 7 .005 8 .005))) (ampf1 (make-env '(0 1 .6 1 .7 0 1 0) :duration dur)) (gen2 (make-oscil)) (gen3 (make-oscil)) (ampf3 (make-env '(0 0 .7 0 1 1) :duration dur :scaler .5))) (do ((i start (+ i 1))) ((= i stop)) (let ((frq (env frqf))) (outa i (* (env ampf) (+ (* (env ampf1) (polywave gen1 frq)) (* .9 (oscil gen2 (* 2.0 frq))) (* (env ampf3) (oscil gen3 (* 3.0 frq)))))))))) (wrentit-1 beg1 .041 (* amp1 0.6) 1.0) (wrentit-1 (+ beg1 .35) .05 amp1 1.0) (wrentit-2 (+ beg1 .45) .062 amp1 1.02) (wrentit-1 (+ beg1 .8) .048 amp1 1.03) (wrentit-2 (+ beg1 .87) .064 amp1 1.03) (let ((ampf (make-env '(0 1 1 .8) :length 10)) (frqf (make-env (list 0 1 1 (/ 3050.0 3200.0)) :length 10)) (call-init 1.0)) (do ((call 0 (+ call 1))) ((= call 10)) (let ((call-amp (env ampf)) (call-frq (env frqf))) (let ((call-beg (+ beg1 call-init (* call .15) (random .01)))) (wrentit-1 call-beg (+ .03 (random .005)) (* amp1 call-amp) call-frq) (wrentit-2 (+ call-beg .048) (+ .06 (random .005)) (* amp1 call-amp) call-frq)))) (wrentit-1 (+ beg1 2.6) .041 (* amp1 0.5) 1.0))) ;; (with-sound (:play #t) (wrentit 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Western wood-pewee (defanimal (western-wood-pewee-1 beg amp) ;; calif 2 8 (let ((dur 0.89)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.009 0.038 0.014 0.140 0.019 0.184 0.030 0.178 0.038 0.055 0.046 0.000 0.210 0.000 0.217 0.165 0.229 0.263 0.239 0.253 0.246 0.204 0.254 0.000 0.336 0.000 0.338 0.122 0.355 0.373 0.363 0.356 0.367 0.151 0.371 0.260 0.383 0.000 0.408 0.000 0.415 0.302 0.421 0.349 0.425 0.496 0.429 0.420 0.439 0.382 0.452 0.460 0.459 0.401 0.466 0.438 0.469 0.498 0.484 0.567 0.505 0.603 0.518 0.541 0.531 0.580 0.543 0.582 0.554 0.473 0.564 0.535 0.587 0.534 0.594 0.495 0.616 0.567 0.633 0.530 0.651 0.570 0.665 0.544 0.683 0.566 0.698 0.521 0.704 0.402 0.709 0.000 0.727 0.001 0.738 0.865 0.742 0.951 0.747 0.997 0.750 0.971 0.763 0.000 0.783 0.000 0.786 0.342 0.794 0.832 0.800 0.611 0.805 0.764 0.811 0.705 0.815 0.863 0.819 0.822 0.829 0.0 0.834 0.0 0.840 0.630 0.850 0.185 0.861 0.000 0.865 0.000 0.872 0.113 0.881 0.211 0.899 0.260 0.907 0.441 0.913 0.340 0.917 0.424 0.919 0.317 0.921 0.444 0.930 0.198 0.935 0.174 0.949 0.136 0.953 0.109 0.964 0.122 0.973 0.110 0.982 0.140 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.379 0.016 0.432 0.034 0.438 0.214 0.395 0.219 0.428 0.230 0.446 0.247 0.444 0.339 0.407 0.346 0.444 0.356 0.452 0.365 0.436 0.369 0.415 0.375 0.434 0.380 0.411 0.411 0.420 0.419 0.450 0.429 0.464 0.447 0.460 0.464 0.466 0.496 0.473 0.571 0.483 0.691 0.485 0.701 0.468 0.710 0.409 0.728 0.314 0.734 0.464 0.740 0.511 0.746 0.521 0.756 0.485 0.764 0.420 0.786 0.428 0.789 0.481 0.798 0.550 0.808 0.552 0.818 0.489 0.823 0.46 0.825 0.481 0.829 0.809 0.835 0.792 0.839 0.546 0.842 0.487 0.848 0.442 0.855 0.397 0.870 0.409 0.877 0.442 0.898 0.442 0.913 0.468 0.921 0.519 0.927 0.580 0.938 0.650 0.948 0.697 0.954 0.684 0.958 0.705 0.967 0.680 0.983 0.666 0.991 0.593 1.000 0.452) :duration dur :scaler (hz->radians 7100.0))) (gen1 (make-polywave 0.0 '(1 .99 2 .005 3 .005)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) ;; (with-sound (:play #t) (western-wood-pewee-1 0 .5)) (defanimal (western-wood-pewee-2 beg amp) (let ((dur 0.69)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.016 0.098 0.038 0.208 0.060 0.000 0.254 0.000 0.293 0.846 0.306 0.975 0.345 1.000 0.391 0.833 0.457 0.809 0.545 0.843 0.596 0.836 0.713 0.669 0.724 0.583 0.729 0.326 0.740 0.324 0.751 0.240 0.774 0.179 0.794 0.600 0.812 0.632 0.878 0.539 0.912 0.392 0.971 0.316 0.984 0.091 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.409 0.030 0.400 0.039 0.436 0.067 0.444 0.279 0.434 0.291 0.505 0.327 0.561 0.420 0.578 0.482 0.569 0.648 0.532 0.728 0.527 0.753 0.593 0.779 0.650 0.802 0.605 0.827 0.532 0.854 0.507 0.977 0.485 1.000 0.43) :duration dur :scaler (hz->radians 7300.0))) (gen1 (make-polywave 0.0 '(1 .99 2 .005 3 .005))) (vib (make-oscil 152)) (index (hz->radians 500)) (vibf (make-env '(0 0 .29 0 .38 1 .7 .5 .75 0 1 0) :duration dur)) (trem (make-triangle-wave 76 .8))) (do ((i start (+ i 1))) ((= i stop)) (let ((vbf (env vibf))) (outa i (* (env ampf) (- 1.0 (* vbf (abs (triangle-wave trem)))) (polywave gen1 (+ (env frqf) (* vbf index (oscil vib))))))))))) ;; (with-sound (:play #t) (western-wood-pewee-2 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Cedar waxwing (defanimal (cedar-waxwing beg amp) ;; probably the simplest bird call ;; calif 10 10 (hard to find one call by itself) ;; a cleaner original is east 3 3 with a slightly sharper frq env (let ((dur 0.5)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.133 0.217 0.337 0.854 0.470 0.826 0.533 0.751 0.617 0.980 0.704 1.000 0.883 0.881 0.943 0.747 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.267 0.097 0.287 0.242 0.301 0.472 0.304 0.684 0.301 0.788 0.301 0.973 0.293 1.000 0.264) :duration dur :scaler (hz->radians 22000.0))) (gen1 (make-polywave 0.0 '(1 .99 2 .006 3 .004)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) ;; (with-sound (:play #t) (cedar-waxwing 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Townsend's solitaire (define (townsends-solitaire beg1 amp1) ;; calif 67 33 (defanimal (townsends-solitaire-1 beg amp) (let ((dur 0.15)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.056 0.074 0.084 0.182 0.122 0.118 0.163 0.168 0.224 0.104 0.257 0.343 0.289 0.337 0.299 0.155 0.308 0.242 0.320 0.185 0.329 0.125 0.389 0.145 0.436 0.242 0.466 0.195 0.484 0.313 0.495 0.455 0.571 0.535 0.634 0.566 0.684 0.727 0.717 0.926 0.751 0.983 0.786 0.960 0.891 0.717 0.957 0.242 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.321 0.055 0.337 0.081 0.365 0.103 0.370 0.113 0.303 0.153 0.308 0.192 0.329 0.233 0.342 0.261 0.376 0.282 0.358 0.306 0.285 0.358 0.272 0.427 0.308 0.490 0.360 0.584 0.376 0.813 0.360 1.000 0.342) :duration dur :scaler (hz->radians 8100.0))) (gen1 (make-polywave 0.0 '(1 .995 2 .005)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) (defanimal (townsends-solitaire-2 beg amp) (let ((dur 0.037)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.077 0.215 0.112 0.907 0.198 0.189 0.212 0.096 0.235 0.0 0.333 0.085 0.433 0.515 0.471 0.481 0.517 0.622 0.571 0.526 0.671 1.000 0.699 0.752 0.718 0.904 0.781 0.915 0.862 0.374 0.968 0.289 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.395 0.077 0.351 0.121 0.293 0.169 0.225 0.218 0.196 0.286 0.163 0.345 0.185 0.407 0.221 1.000 0.36) :duration dur :scaler (hz->radians 13800.0))) (gen1 (make-polywave 0.0 '(1 .98 2 .01 3 .005 4 .005)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) (defanimal (townsends-solitaire-3 beg amp) (let ((dur 0.323)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.106 0.301 0.117 0.254 0.156 0.475 0.198 0.359 0.221 0.043 0.228 0.214 0.307 0.848 0.337 0.391 0.355 0.355 0.366 0.467 0.381 0.409 0.397 0.649 0.407 0.576 0.424 0.105 0.453 0.449 0.474 0.627 0.485 0.558 0.488 0.703 0.506 0.482 0.514 0.261 0.523 0.203 0.572 0.529 0.581 0.449 0.586 0.641 0.606 0.000 0.634 0.359 0.661 0.598 0.675 0.522 0.684 0.750 0.701 0.616 0.709 0.380 0.718 0.250 0.733 0.188 0.768 0.478 0.778 0.362 0.796 0.000 0.822 0.373 0.849 0.587 0.861 0.478 0.881 0.891 0.888 0.804 0.904 0.996 0.935 0.703 0.946 0.768 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.549 0.083 0.595 0.114 0.606 0.144 0.641 0.179 0.656 0.213 0.643 0.229 0.590 0.247 0.573 0.283 0.564 0.313 0.538 0.344 0.484 0.347 0.641 0.361 0.610 0.387 0.586 0.404 0.547 0.419 0.486 0.435 0.477 0.440 0.645 0.450 0.667 0.456 0.634 0.472 0.610 0.507 0.529 0.527 0.492 0.535 0.688 0.559 0.625 0.605 0.519 0.618 0.505 0.629 0.678 0.654 0.619 0.672 0.590 0.711 0.519 0.732 0.510 0.734 0.702 0.758 0.632 0.797 0.508 0.813 0.671 0.828 0.662 0.840 0.608 0.882 0.560 0.922 0.525 1.000 0.475) :duration dur :scaler (hz->radians 6000.0))) (gen1 (make-polywave 0.0 '(1 .99 2 .004 3 .006)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) (defanimal (townsends-solitaire-4 beg amp) (let ((dur 0.217)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.065 0.296 0.096 0.261 0.145 0.368 0.179 0.580 0.196 0.375 0.227 0.560 0.272 0.000 0.314 0.000 0.380 0.451 0.416 0.325 0.433 0.183 0.456 0.351 0.483 0.303 0.509 0.410 0.528 0.255 0.627 0.089 0.640 0.000 0.660 0.196 0.699 0.307 0.711 0.706 0.722 0.719 0.740 0.481 0.755 0.455 0.763 0.362 0.775 0.453 0.793 0.059 0.796 0.214 0.807 0.000 0.810 0.124 0.828 0.187 0.856 0.240 0.867 0.205 0.883 0.253 0.902 0.882 0.909 1.000 0.955 0.438 0.963 0.603 0.969 0.497 0.982 0.153 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.486 0.036 0.486 0.128 0.538 0.134 0.473 0.166 0.481 0.183 0.512 0.200 0.534 0.219 0.484 0.227 0.425 0.244 0.386 0.287 0.366 0.307 0.499 0.328 0.527 0.341 0.508 0.424 0.429 0.507 0.410 0.599 0.364 0.617 0.381 0.628 0.414 0.659 0.427 0.685 0.460 0.707 0.475 0.729 0.514 0.759 0.551 0.774 0.521 0.779 0.449 0.797 0.386 0.833 0.414 0.873 0.451 0.905 0.492 0.941 0.547 0.959 0.545 0.970 0.423 1.000 0.322) :duration dur :scaler (hz->radians 6050.0))) (gen1 (make-polywave 0.0 '(1 .99 2 .006 3 .004)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) (defanimal (townsends-solitaire-5 beg amp) (let ((dur 0.007)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0 0 1 1 3 0) :duration dur :scaler amp)) (frqf (make-env '(0 4600 1 3000) :duration dur :scaler (hz->radians 1.0))) (gen1 (make-polywave 0.0 '(1 .99 2 .01)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) (townsends-solitaire-3 beg1 (* amp1 .7)) (townsends-solitaire-1 (+ beg1 .37) amp1) (townsends-solitaire-1 (+ beg1 .59) amp1) (do ((call 0 (+ call 1))) ((= call 5)) (townsends-solitaire-2 (+ beg1 .85 (* call .059)) (* .3 amp1))) (townsends-solitaire-5 (+ beg1 1.139) (* amp1 .2)) (townsends-solitaire-4 (+ beg1 1.178) (* amp1 .6))) ;; (with-sound (:play #t) (townsends-solitaire 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Canada goose (defanimal (canada-goose-1 beg amp) ;; east 21 28 (let ((dur 0.375)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.446 0.182 0.489 0.778 0.521 0.465 0.610 0.356 0.682 0.553 0.741 1.000 0.785 0.513 0.811 0.350 0.878 0.270 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.362 0.321 0.378 0.422 0.398 0.445 0.418 0.461 0.388 0.485 0.428 0.606 0.434 0.624 0.421 0.643 0.444 0.662 0.405 0.670 0.451 0.685 0.378 0.691 0.428 0.700 0.378 0.708 0.434 0.748 0.457 0.819 0.467 0.870 0.464 0.910 0.414 1.000 0.382) :duration dur :scaler (hz->radians (* 0.5 3500)))) (gen1 (make-oscil)) (ampf1 (make-env '(0 1 .44 1 .455 .5 .46 1 .465 .5 .5 1 .67 1 .68 .1 .69 1 .71 1 .72 .1 .73 1 1 1) :duration dur :scaler .4)) (gen2 (make-oscil)) (gen3 (make-oscil)) (ampf3 (make-env '(0 .2 .4 .2 .5 1 .68 1 .7 .5 .9 .5 1 0) :duration dur :scaler .3)) (gen4 (make-polywave 0.0 '(4 .8 5 .2))) (ampf4 (make-env '(0 0 .4 .1 .5 1 .75 1 .9 0 1 0) :duration dur :scaler .05)) (gen5 (make-nrxysin :n 12 :r .8 :ratio 1/6)) (ampf5 (make-env '(0 0 .4 0 .5 1 .65 .1 .7 1 .9 0 1 0) :duration dur :scaler .2)) (trem (make-triangle-wave (* 0.5 170))) (tremf (make-env '(0 1 .45 1 .5 .3 .65 .2 .7 1 .75 .2 1 .2) :duration dur)) (tremf-1 (make-env '(0 1 .45 1 .5 .3 .65 .2 .7 1 .75 .2 1 .2) :duration dur :offset 1.0 :scaler -1.0)) (hum (make-oscil)) (humf (make-env '(0 .1 .1 1 .2 .1 .3 1 .4 1 .45 .1 .8 0 1 0) :duration dur :scaler .4)) (rnd (make-rand-interp 2000)) (rndf (make-env '(0 .1 .3 .2 .4 1 .45 1 .5 .1 .6 .01 .65 1 .7 .1 1 .25) :duration dur :scaler (hz->radians 200))) (gen6 (make-nrxysin :n 12 :r .8 :ratio 1/6)) (ampf6 (make-env '(0 0 .4 0 .45 1 .5 0 .65 0 .7 1 .75 0 1 0) :duration dur :scaler .2))) (do ((i start (+ i 1))) ((= i stop)) (let ((frq (+ (env frqf) (* (env rndf) (rand-interp rnd))))) (outa i (* (env ampf) (+ (env tremf-1) (* (env tremf) (abs (triangle-wave trem)))) (+ (* (env ampf1) (oscil gen1 frq)) (* .5 (oscil gen2 (* 2.0 frq))) (* (env ampf3) (oscil gen3 (* 3.0 frq))) (+ (* (env ampf4) (polywave gen4 frq)) ; extra + to make the optimizer happy (* (env ampf5) (nrxysin gen5 (* 6.0 frq))) (* (env ampf6) (nrxysin gen6 (* 3.0 frq))) (* (env humf) (oscil hum (* .25 frq)))))))))))) (defanimal (canada-goose-2 beg amp) (let ((dur 0.245)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.027 0.057 0.054 0.000 0.072 0.076 0.080 0.000 0.098 0.078 0.106 0.005 0.121 0.087 0.133 0.000 0.147 0.101 0.157 0.005 0.174 0.119 0.183 0.005 0.200 0.119 0.208 0.002 0.225 0.128 0.236 0.000 0.249 0.112 0.259 0.000 0.270 0.098 0.283 0.000 0.299 0.105 0.308 0.000 0.322 0.133 0.329 0.066 0.345 0.151 0.352 0.085 0.361 0.201 0.375 0.114 0.383 0.217 0.397 0.124 0.406 0.195 0.414 0.085 0.442 0.373 0.620 1.000 0.640 0.686 0.705 0.469 0.757 0.352 0.818 0.300 0.846 0.405 0.942 0.133 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.276 0.164 0.300 0.307 0.308 0.599 0.297 0.651 0.302 0.661 0.354 0.755 0.357 0.827 0.342 0.855 0.310 1.000 0.283) :duration dur :scaler (hz->radians (* 0.5 4300)))) (gen1 (make-oscil)) (ampf1 (make-env '(0 1 .4 1 .55 1 .6 .7 1 1) :duration dur :scaler .5)) (gen2 (make-oscil)) (ampf2 (make-env '(0 .5 .55 .2 .6 1 .7 .2 1 1) :duration dur :scaler .5)) (gen3 (make-oscil)) (ampf3 (make-env '(0 .2 .6 .1 .65 1 .75 1 .9 0 1 0) :duration dur :scaler .3)) (gen4 (make-polywave 0.0 '(4 .8 5 .2))) (ampf4 (make-env '(0 0 .4 .1 .65 1 .75 1 .8 0 .85 1 .9 .5 1 .5) :duration dur :scaler .1)) (gen5 (make-nrxysin :n 12 :r .8 :ratio 1/6)) (ampf5 (make-env '(0 0 .5 0 .55 1 .6 0 .65 1 .7 1 .8 0 1 0) :duration dur :scaler .2)) (hum (make-oscil)) (humf (make-env '(0 1 .4 1 .42 .1 .6 0 1 0) :duration dur :scaler .4)) (rnd (make-rand-interp 2000)) (rndf (make-env '(0 .1 .3 .2 .65 1 .7 .1 1 .25) :duration dur :scaler (hz->radians 100))) (gen6 (make-nrxysin :n 12 :r .8 :ratio 1/6)) (ampf6 (make-env '(0 0 .65 0 .7 1 .75 0 1 0) :duration dur :scaler .3))) (do ((i start (+ i 1))) ((= i stop)) (let ((frq (+ (env frqf) (* (env rndf) (rand-interp rnd))))) (outa i (* (env ampf) (+ (* (env ampf1) (oscil gen1 frq)) (* (env ampf2) (oscil gen2 (* 2.0 frq))) (* (env ampf3) (oscil gen3 (* 3.0 frq))) (+ (* (env ampf4) (polywave gen4 frq)) (* (env ampf5) (nrxysin gen5 (* 6.0 frq))) (* (env ampf6) (nrxysin gen6 (* 3.0 frq))) (* (env humf) (oscil hum (* .25 frq)))))))))))) (defanimal (canada-goose-3 beg amp) ;; east 21 29 (let ((dur 0.33)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.082 0.112 0.207 0.158 0.218 0.089 0.246 0.214 0.278 0.181 .32 .3 0.364 0.944 0.374 1.000 0.384 0.974 0.394 0.757 0.431 0.645 0.584 0.201 0.639 0.688 0.657 0.717 0.714 0.477 0.800 0.319 0.882 0.253 0.902 0.164 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.291 0.311 0.299 0.338 0.299 0.358 0.414 0.395 0.443 0.454 0.455 0.547 0.418 0.596 0.389 0.614 0.414 0.634 0.393 0.682 0.418 0.764 0.426 0.846 0.410 0.874 0.369 0.907 0.352 1.000 0.307) :duration dur :scaler (hz->radians (* 0.5 3600)))) (gen1 (make-oscil)) (ampf1 (make-env '(0 .1 .5 .2 .6 1 .65 .3 1 1) :duration dur :scaler .3)) (gen2 (make-oscil)) (gen3 (make-oscil)) (ampf3 (make-env '(0 .1 .3 .2 .4 1 1 1) :duration dur :scaler .1)) (gen4 (make-polywave 0.0 '(4 .8 5 .2))) (ampf4 (make-env '(0 0 .3 0 .4 1 .9 1 1 0) :duration dur :scaler .05)) (gen5 (make-nrxysin :n 12 :r .7 :ratio 1/6)) (ampf5 (make-env '(0 0 .3 0 .4 1 .5 .1 .55 0 .6 .1 .63 1 .85 0 1 0) :duration dur :scaler .3)) (trem (make-triangle-wave (* 0.5 170))) (tremf (make-env '(0 1 .3 1 .35 .1 .6 .2 .65 1 .7 .2 1 .2) :duration dur)) (tremf-1 (make-env '(0 1 .3 1 .35 .1 .6 .2 .65 1 .7 .2 1 .2) :duration dur :offset 1.0 :scaler -1.0)) (hum (make-oscil)) (humf (make-env '(0 .5 .45 .4 .5 1 .6 .5 .7 0 1 0) :duration dur :scaler .2)) (humfrq (make-env '(0 150 .6 190 1 200) :duration dur :scaler (hz->radians 1.0))) (tri1 (make-triangle-wave 75 .75)) (rnd (make-rand-interp 2000)) (rndf (make-env '(0 .1 .3 1 .35 .1 .4 .01 .55 .01 .6 1 .65 .01 1 .01) :duration dur :scaler (hz->radians 200)))) (do ((i start (+ i 1))) ((= i stop)) (let ((frq (+ (env frqf) (* (env rndf) (rand-interp rnd))))) (outa i (* (env ampf) (+ (env tremf-1) (* (env tremf) (abs (triangle-wave trem)))) (+ (* (env ampf1) (oscil gen1 frq)) (* .5 (oscil gen2 (* 2.0 frq))) (* (env ampf3) (oscil gen3 (* 3.0 frq))) (+ (* (env ampf4) (polywave gen4 frq)) (* (env ampf5) (nrxysin gen5 (* 6.0 frq))) (* (env humf) (+ .25 (abs (triangle-wave tri1))) (oscil hum (env humfrq)))))))))))) (define (canada-goose beg1 amp1) (canada-goose-1 beg1 amp1) (canada-goose-2 (+ beg1 .54) amp1) (canada-goose-3 (+ beg1 .97) amp1)) ;; (with-sound (:play #t) (canada-goose 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Pine warbler (defanimal (pine-warbler beg amp) ;; east 21 3 (let ((call-ampf (make-env '(0 .05 1 .2 3 .8 5 1 10 1 16 .4) :length 16)) (call-frqf (make-env '(0 1.1 4 1.0 13 .98 15 1.0) :length 16))) (do ((call 0 (+ call 1))) ((= call 16)) (let ((start (seconds->samples (+ beg (* call .115) (random .01)))) (dur (+ .105 (random .01)))) (let ((stop (+ start (seconds->samples dur))) (ampf (make-env '(0.000 0.000 0.147 0.356 0.216 0.403 0.257 0.135 0.310 0.000 0.347 0.000 0.447 0.468 0.474 0.694 0.489 0.656 0.500 0.729 0.514 0.632 0.529 0.815 0.562 0.644 0.578 0.809 0.590 0.626 0.602 0.982 0.621 0.765 0.629 0.950 0.639 0.829 0.648 0.982 0.662 0.818 0.669 0.644 0.675 0.824 0.685 0.932 0.699 0.579 0.706 0.353 0.723 0.800 0.737 1.000 0.753 0.959 0.765 0.529 0.773 0.638 0.781 0.971 0.790 0.941 0.798 0.547 0.803 0.591 0.808 0.806 0.822 0.832 0.833 0.124 0.839 0.415 0.874 0.132 0.887 0.206 0.923 0.062 0.933 0.174 0.939 0.091 0.948 0.159 0.960 0.079 0.967 0.176 0.981 0.062 1.000 0.000) :duration dur :scaler (* amp (env call-ampf)))) (frqf (make-env '(0.000 0.118 0.056 0.132 0.133 0.146 0.190 0.148 0.233 0.134 0.261 0.132 0.288 0.137 0.311 0.154 0.332 0.176 0.365 0.151 0.415 0.151 0.477 0.164 0.526 0.171 0.636 0.199 0.730 0.204 0.855 0.221 0.962 0.218 1.000 0.199) :duration dur :scaler (hz->radians (* 22000.0 (env call-frqf))))) (gen1 (make-polywave 0.0 '(1 .97))) (gen2 (make-polywave 0.0 '(2 .005 3 .03 4 .003))) (ampf2 (make-env '(0 0 .3 0 .4 1 1 1) :duration dur))) (do ((i start (+ i 1))) ((= i stop)) (let ((frq (env frqf))) (outa i (* (env ampf) (+ (polywave gen1 frq) (* (env ampf2) (polywave gen2 frq)))))))))))) ;; (with-sound (:play #t) (pine-warbler 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Black-throated sparrow (define (black-throated-sparrow beg1 amp1) ;; south 85 2 (defanimal (black-throated-sparrow-1 beg amp) (let ((dur .034)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.057 0.806 0.073 0.857 0.111 0.783 0.139 0.988 0.216 0.817 0.235 0.574 0.324 0.333 0.473 0.216 0.725 0.679 0.805 0.649 0.887 0.484 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.301 0.059 0.288 0.090 0.281 0.123 0.286 0.149 0.299 0.189 0.303 0.250 0.299 0.341 0.292 0.568 0.296 0.746 0.299 1.000 0.296) :duration dur :scaler (hz->radians 22000.0))) (gen1 (make-polywave 0.0 '(1 .99 2 .007 3 .003)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) (defanimal (black-throated-sparrow-2 beg amp) (let ((dur .11)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.026 0.514 0.080 0.667 0.120 0.618 0.183 0.000 0.223 0.000 0.260 0.913 0.281 0.977 0.311 0.895 0.343 0.631 0.399 0.000 0.444 0.000 0.504 0.130 0.514 0.070 0.533 0.173 0.567 0.128 0.576 0.217 0.587 0.202 0.596 0.117 0.613 0.171 0.640 0.104 0.654 0.166 0.677 0.087 0.729 0.000 0.820 0.000 0.844 0.940 0.865 1.000 0.909 0.927 0.968 0.499 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.176 0.167 0.176 0.196 0.158 0.246 0.160 0.272 0.174 0.407 0.169 0.487 0.093 0.504 0.117 0.518 0.093 0.543 0.117 0.562 0.093 0.579 0.117 0.599 0.093 0.615 0.113 0.635 0.090 0.656 0.115 0.671 0.088 0.689 0.111 0.705 0.088 0.809 0.172 0.835 0.176 1.000 0.176) :duration dur :scaler (hz->radians 22000.0))) (gen1 (make-polywave 0.0 '(1 .99 2 .007 3 .003)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) (defanimal (black-throated-sparrow-3 beg amp) (let ((dur .153)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.099 0.442 0.124 0.456 0.146 0.372 0.164 0.203 0.243 0.061 0.257 0.352 0.294 0.433 0.371 0.221 0.380 0.000 0.525 0.000 0.552 0.138 0.559 0.068 0.579 0.314 0.595 0.074 0.621 0.643 0.636 0.738 0.649 0.542 0.660 0.147 0.670 0.853 0.681 0.986 0.690 0.941 0.717 0.149 0.728 0.862 0.743 0.995 0.751 0.950 0.777 0.149 0.790 0.853 0.799 0.901 0.805 0.840 0.825 0.056 0.835 0.609 0.851 0.822 0.858 0.795 0.873 0.061 0.885 0.738 0.894 0.813 0.903 0.745 0.919 0.097 0.925 0.438 0.945 0.591 0.957 0.149 0.971 0.289 0.985 0.065 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.192 0.090 0.195 0.119 0.197 0.156 0.211 0.163 0.142 0.242 0.128 0.254 0.211 0.276 0.178 0.326 0.169 0.355 0.169 0.379 0.181 0.542 0.238 0.563 0.247 0.586 0.240 0.618 0.245 0.640 0.238 0.664 0.247 0.690 0.240 0.721 0.240 0.748 0.233 0.782 0.243 0.809 0.238 0.832 0.243 0.858 0.233 0.880 0.245 0.903 0.233 0.923 0.245 0.944 0.238 1.000 0.240) :duration dur :scaler (hz->radians 22000.0))) (gen1 (make-polywave 0.0 '(1 .99 2 .007 3 .003)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) (black-throated-sparrow-3 beg1 (* .4 amp1)) (let ((ampf (make-env '(0 .4 5 1.0 7 .9) :length 7))) (do ((call 0 (+ call 1))) ((= call 7)) (black-throated-sparrow-1 (+ beg1 .2 (* call .042) (random .003)) (* amp1 (env ampf))))) (do ((call 0 (+ call 1))) ((= call 3)) (black-throated-sparrow-2 (+ beg1 .53 (* call .134)) (* 0.6 amp1)))) ;; (with-sound (:play #t) (black-throated-sparrow 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Cape May warbler (defanimal (cape-may-warbler beg amp) ;; east 14 2 ;; note #1 (let ((dur 0.234)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.115 0.517 0.170 0.326 0.214 0.400 0.272 0.397 0.298 0.289 0.486 0.674 0.529 0.564 0.537 0.744 0.554 0.605 0.570 0.871 0.617 0.637 0.646 0.986 0.664 0.857 0.675 1.000 0.697 0.279 0.713 0.626 0.756 0.522 0.772 0.342 0.792 0.600 0.813 0.319 0.825 0.667 0.856 0.330 0.864 0.642 0.890 0.568 0.899 0.242 0.920 0.573 0.983 0.323 1.000 0.000) :duration dur :scaler (* .2 amp))) (frqf (make-env '(0.000 0.357 0.070 0.364 0.119 0.362 0.246 0.378 0.318 0.380 0.397 0.387 0.538 0.398 0.628 0.416 0.733 0.430 0.811 0.437 0.852 0.443 0.912 0.441 1.000 0.441) :duration dur :scaler (hz->radians 22000.0))) (gen1 (make-oscil))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (oscil gen1 (env frqf))))))) ;; next 4 notes (let ((begs (vector 0.31 0.61 0.86 1.11)) (durs (vector 0.23 0.19 0.18 0.18)) (amps (vector 0.6 0.95 1.0 0.8)) (ampenv '(0.000 0.000 0.081 0.593 0.118 0.676 0.139 0.952 0.174 1.000 0.198 0.762 0.255 0.701 0.276 0.824 0.316 0.572 0.372 0.794 0.411 0.572 0.506 0.663 0.550 0.514 0.582 0.622 0.633 0.337 0.653 0.520 0.685 0.536 0.700 0.389 0.780 0.462 0.796 0.267 0.804 0.380 0.814 0.231 0.832 0.330 0.895 0.310 0.942 0.238 1.000 0.000)) (frqenv '(0.000 0.326 0.102 0.344 0.182 0.351 0.269 0.360 0.352 0.373 0.503 0.382 0.614 0.394 0.730 0.410 0.833 0.423 1.000 0.434)) (gen1 (make-oscil))) (do ((call 0 (+ call 1))) ((= call 4)) (let ((start (seconds->samples (+ beg (begs call)))) (dur (durs call))) (let ((stop (+ start (seconds->samples dur))) (ampf (make-env ampenv :duration dur :scaler (* amp (amps call)))) (frqf (make-env frqenv :duration dur :scaler (hz->radians 22000)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (oscil gen1 (env frqf)))))))))) ;; (with-sound (:play #t) (cape-may-warbler 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Kirtland's warbler (define (kirtlands-warbler beg1 amp1) ;; east 22 3 (defanimal (kirtlands-warbler-1 beg dur frqscl frqenv ampscl ampenv) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env ampenv :duration dur :scaler ampscl)) (frqf (make-env frqenv :duration dur :scaler (hz->radians frqscl))) (gen1 (make-polywave 0.0 (normalize-partials '(1 1.0 2 .08 3 .1 4 .03 5 .05))))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf))))))) (let ((begs (vector 0.0 0.25 0.47 0.65 0.79 0.99 1.17 1.33)) (durs (vector 0.05 0.05 0.06 0.07 0.14 0.14 0.12 0.11)) (amps (vector 0.04 0.6 0.8 0.80 1.0 0.94 0.92 0.75)) (frqs (vector 6020 6020 13370 13360 13360 13360 13360 13360)) (ampenvs (vector '(0.000 0.000 0.063 0.289 0.098 0.838 0.139 0.960 0.217 0.213 0.389 0.115 0.484 0.775 0.524 0.530 0.546 0.842 0.587 0.375 0.630 0.909 0.739 0.613 0.764 0.320 0.829 0.443 0.910 0.356 0.929 0.162 1.000 0.000) '(0.000 0.000 0.049 0.166 0.083 0.204 0.111 0.348 0.149 0.271 0.190 0.665 0.238 0.671 0.303 0.477 0.390 0.032 0.570 0.026 0.614 0.277 0.643 0.591 0.664 0.527 0.695 0.785 0.732 0.492 0.767 0.856 0.809 0.933 0.853 0.576 0.907 0.346 0.960 0.140 1.000 0.000) '(0.000 0.000 0.097 0.340 0.127 0.181 0.157 0.578 0.185 0.426 0.234 0.718 0.267 0.624 0.300 0.613 0.416 0.041 0.506 0.034 0.554 0.232 0.575 0.561 0.609 0.318 0.651 0.865 0.696 0.884 0.763 0.763 0.821 0.533 0.862 0.340 0.919 0.148 1.000 0.000) '(0.000 0.000 0.077 0.052 0.138 0.196 0.159 0.368 0.178 0.067 0.210 0.589 0.224 0.256 0.251 0.658 0.286 0.529 0.324 0.751 0.345 0.578 0.374 0.477 0.453 0.043 0.524 0.043 0.595 0.413 0.609 0.258 0.635 0.333 0.654 0.667 0.685 0.852 0.703 0.871 0.725 0.789 0.748 0.837 0.813 0.602 0.845 0.329 0.904 0.110 1.000 0.000) '(0.000 0.000 0.063 0.075 0.109 0.275 0.125 0.262 0.135 0.146 0.166 0.523 0.184 0.503 0.194 0.157 0.203 0.477 0.231 0.725 0.263 0.804 0.282 0.613 0.350 0.561 0.387 0.295 0.442 0.060 0.489 0.054 0.545 0.303 0.562 0.140 0.632 0.583 0.669 0.594 0.705 0.923 0.813 0.540 0.857 0.118 0.921 0.039 1.000 0.000) '(0.000 0.000 0.085 0.308 0.096 0.153 0.143 0.477 0.154 0.239 0.161 0.443 0.196 0.755 0.264 0.903 0.282 0.804 0.315 0.796 0.357 0.325 0.407 0.047 0.469 0.049 0.519 0.310 0.543 0.159 0.552 0.480 0.657 0.908 0.769 0.570 0.828 0.142 0.882 0.071 1.000 0.000) '(0.000 0.000 0.315 0.112 0.450 0.310 0.710 0.963 0.805 0.862 0.913 0.460 0.952 0.099 1.000 0.000) '(0.000 0.000 0.264 0.138 0.326 0.135 0.510 0.688 0.621 0.766 0.656 0.768 0.697 0.923 0.717 0.809 0.743 0.892 0.824 0.871 0.877 0.725 1.000 0.000))) (frqenvs (vector '(0.000 0.314 0.074 0.394 0.101 0.462 0.127 0.486 0.157 0.458 0.178 0.372 0.243 0.310 0.348 0.299 0.425 0.323 0.463 0.413 0.496 0.505 0.522 0.533 0.552 0.492 0.567 0.415 0.597 0.389 0.633 0.426 0.654 0.486 0.686 0.495 0.732 0.389 0.820 0.344 1.000 0.314) '(0.000 0.394 0.044 0.458 0.059 0.578 0.085 0.606 0.113 0.542 0.125 0.475 0.150 0.462 0.182 0.518 0.210 0.551 0.238 0.516 0.266 0.465 0.305 0.411 0.356 0.381 0.428 0.323 0.508 0.312 0.588 0.348 0.628 0.426 0.646 0.499 0.669 0.525 0.695 0.510 0.713 0.469 0.736 0.454 0.761 0.480 0.793 0.512 0.824 0.480 0.863 0.415 0.934 0.387 1.000 0.340) '(0.000 0.204 0.027 0.258 0.053 0.267 0.077 0.224 0.096 0.196 0.119 0.222 0.136 0.252 0.160 0.265 0.183 0.247 0.211 0.224 0.250 0.200 0.304 0.191 0.387 0.157 0.441 0.146 0.494 0.168 0.528 0.178 0.548 0.206 0.564 0.243 0.584 0.265 0.609 0.245 0.646 0.217 0.695 0.228 0.744 0.204 0.771 0.194 0.799 0.194 0.879 0.163 1.000 0.144) '(0.000 0.202 0.138 0.204 0.162 0.273 0.186 0.314 0.201 0.273 0.211 0.237 0.229 0.224 0.252 0.239 0.275 0.260 0.303 0.239 0.332 0.209 0.392 0.185 0.434 0.161 0.490 0.144 0.547 0.170 0.588 0.198 0.600 0.239 0.624 0.265 0.650 0.241 0.677 0.228 0.716 0.245 0.752 0.219 0.801 0.198 1.000 0.140) '(0.000 0.161 0.050 0.163 0.075 0.237 0.095 0.363 0.119 0.398 0.160 0.396 0.190 0.391 0.207 0.363 0.240 0.323 0.263 0.303 0.292 0.258 0.320 0.241 0.376 0.228 0.430 0.224 0.466 0.247 0.481 0.327 0.498 0.381 0.530 0.398 0.570 0.385 0.599 0.359 0.659 0.329 0.701 0.286 0.765 0.219 0.822 0.191 0.857 0.168 0.899 0.151 1.000 0.135) '(0.000 0.245 0.021 0.353 0.047 0.402 0.087 0.406 0.122 0.381 0.147 0.353 0.180 0.329 0.222 0.267 0.263 0.247 0.360 0.228 0.382 0.243 0.404 0.226 0.422 0.222 0.438 0.241 0.463 0.314 0.488 0.376 0.521 0.387 0.553 0.381 0.570 0.361 0.599 0.353 0.622 0.329 0.656 0.312 0.689 0.286 0.769 0.213 0.813 0.194 0.857 0.170 1.000 0.142) '(0.000 0.110 0.160 0.138 0.284 0.159 0.389 0.172 0.504 0.196 0.555 0.215 0.628 0.239 0.693 0.256 0.744 0.277 0.796 0.286 0.828 0.308 0.867 0.299 0.894 0.305 0.922 0.297 1.000 0.267) '(0.000 0.123 0.079 0.148 0.131 0.153 0.274 0.168 0.340 0.170 0.432 0.194 0.494 0.200 0.520 0.215 0.595 0.219 0.628 0.241 0.675 0.245 0.752 0.273 0.864 0.310 0.898 0.297 0.930 0.292 0.964 0.269 1.000 0.247)))) (do ((call 0 (+ call 1))) ((= call 8)) (kirtlands-warbler-1 (+ beg1 (begs call)) (durs call) (frqs call) (frqenvs call) (* amp1 (amps call)) (ampenvs call))))) ;; (with-sound (:play #t) (kirtlands-warbler 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Wood duck ;;; ;;; reverb in original makes this hard to match (defanimal (wood-duck beg amp) ;; east 22 19 (let ((dur 0.75)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.022 0.070 0.027 0.433 0.041 0.441 0.047 0.256 .06 .1 0.088 0.888 0.1 0 0.115 0.692 0.120 0.266 0.132 0.379 0.149 0.277 0.166 0.360 0.174 0.269 0.203 0.386 0.219 0.295 0.269 0.413 0.316 0.287 0.338 0.428 0.354 0.292 0.369 0.397 0.424 0.290 0.476 0.368 0.52 .01 0.53 0.029 0.58 0.916 0.634 0.875 0.657 0.781 0.682 1.000 0.718 0.961 0.734 0.705 0.761 0.864 0.785 0.841 0.830 0.606 0.85 0.454 0.87 0.0 .88 0.0 0.919 0.292 0.966 0.240 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.110 0.029 0.174 0.048 0.232 0.075 0.256 0.096 0.238 0.120 0.191 0.199 0.168 0.272 0.168 0.369 0.186 0.522 0.226 0.528 0.368 0.539 0.345 0.714 0.339 0.847 0.328 0.879 0.325 0.885 0.200 0.956 0.157 1.000 0.122) :duration dur :scaler (hz->radians 4890.0))) (gen1 (make-oscil)) (ampf1 (make-env '(0 .2 .45 .15 .5 .25 .53 1 .85 1 .88 .4 1 .1) :duration dur :scaler .8)) (gen2 (make-oscil)) (ampf2 (make-env '(0 1 .1 1 .15 .75 .4 .75 .5 .1 .6 .75 .8 .75 .85 .1 .88 .5 .95 .5 1 .2) :duration dur :scaler .6)) (gen3 (make-oscil)) (ampf3 (make-env '(0 1 .2 .3 .4 .1 .5 1 .52 1 .7 1 .75 .3 1 .1) :duration dur :scaler .1)) (gen4 (make-oscil)) (gen5 (make-oscil)) (ampf4 (make-env '(0 .2 .4 .05 .5 .2 .55 0 1 0) :duration dur :scaler .1)) (rnd (make-rand-interp 400 (hz->radians 40))) (rndf (make-env '(0 0 .05 4 .1 .5 .9 .1 1 1) :duration dur)) (rnd1 (make-rand-interp 500 .1)) (att (make-polywave 0.0 '(3 .3 5 .5 7 .1 9 .1))) (attf (make-env '(0 0 .05 1 .1 0 1 0) :duration dur :scaler .125))) (do ((i start (+ i 1))) ((= i stop)) (let ((frq (+ (env frqf) (* (env rndf) (rand-interp rnd))))) (outa i (* (env ampf) (+ .9 (abs (rand-interp rnd1))) (+ (* (env attf) (polywave att (* 0.5 frq))) (* (env ampf1) (oscil gen1 frq)) (+ (* (env ampf2) (oscil gen2 (* 2.0 frq))) (* (env ampf3) (oscil gen3 (* 3.0 frq))) (* (env ampf4) (+ (oscil gen4 (* 4.0 frq)) (oscil gen5 (* 5.0 frq))))))))))))) ;; (with-sound (:play #t) (wood-duck 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; White-eyed vireo (defanimal (white-eyed-vireo beg amp) ;; south 41 2 ;; note #1 (let ((dur 0.1)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.067 0.143 0.150 0.431 0.174 0.392 0.215 0.866 0.243 1.000 0.265 1.000 0.309 0.589 0.322 0.742 0.347 1.000 0.371 0.487 0.415 0.617 0.496 0.457 0.546 0.604 0.644 0.686 0.677 0.593 0.703 0.721 0.741 0.745 0.757 0.693 0.772 0.500 0.828 0.615 0.838 0.766 0.875 0.965 0.897 0.905 0.912 0.461 0.932 0.868 0.952 0.855 1.000 0.000) :duration dur :scaler (* .5 amp))) (frqf (make-env '(0.000 0.109 0.076 0.131 0.112 0.144 0.155 0.156 0.235 0.193 0.259 0.198 0.287 0.215 0.352 0.232 0.382 0.257 0.462 0.270 0.599 0.273 0.748 0.272 0.776 0.262 0.798 0.260 0.897 0.227 0.927 0.211 0.960 0.195 1.000 0.191) :duration dur :scaler (hz->radians 22000.0))) (gen1 (make-polywave 0.0 '(1 .99 2 .01 3 .005)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf))))))) ;; note #2 (let ((dur 0.046) (start (seconds->samples (+ beg 0.23)))) (let ((stop (+ start (seconds->samples dur))) (ampf (make-env '(0.000 0.000 0.052 0.258 0.111 0.138 0.273 0.508 0.356 0.992 0.419 0.569 0.493 0.547 0.584 0.374 0.668 0.629 0.703 0.659 0.732 0.884 0.813 0.077 0.857 0.190 0.913 0.087 1.000 0.000) :duration dur :scaler (* .6 amp))) (frqf (make-env '(0.000 0.203 0.071 0.200 0.111 0.203 0.134 0.227 0.200 0.238 0.249 0.255 0.329 0.263 0.469 0.265 0.627 0.245 0.728 0.233 0.891 0.146 0.948 0.131 1.000 0.144) :duration dur :scaler (hz->radians (* 1/3 22000.0)))) (gen1 (make-polywave 0.0 (normalize-partials '( 2 1 3 .05 4 .02 5 .005 6 .01 7 .005)))) (gen2 (make-oscil)) (ampf2 (make-env '(0 .5 .4 1 .7 1 .8 0 1 0) :duration dur :scaler .05)) (gen3 (make-oscil)) (ampf3 (make-env '(0 1 .1 0 1 0) :duration dur :scaler .1))) (do ((i start (+ i 1))) ((= i stop)) (let ((frq (env frqf))) (outa i (* (env ampf) (+ (* (env ampf2) (oscil gen2 frq)) (* (env ampf3) (oscil gen3 (* 3.0 frq))) (polywave gen1 frq)))))))) ;; note #3 (let ((dur 0.078) (start (seconds->samples (+ beg 0.33)))) (let ((stop (+ start (seconds->samples dur))) (ampf (make-env '(0.000 0.000 0.054 0.208 0.443 0.794 0.762 0.943 0.848 0.901 0.922 0.586 0.967 0.104 1.000 0.000) :duration dur :scaler (* 0.3 amp))) (frqf (make-env '(0.000 0.111 0.853 0.135 1.000 0.114) :duration dur :scaler (hz->radians 22000.0))) (gen1 (make-polywave 0.0 '(1 .95 2 .01 3 .03 4 .01 5 .005 ))) (vib (make-oscil 370)) (vib-index (hz->radians 300)) (rnd (make-rand-interp 4000 (hz->radians 200)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (+ (env frqf) (* vib-index (oscil vib)) (rand-interp rnd)))))))) ;; note #4 (let ((dur 0.2) (start (seconds->samples (+ beg 0.426)))) (let ((stop (+ start (seconds->samples dur))) (ampf (make-env '(0.000 0.000 0.023 0.147 0.041 0.537 0.063 0.716 0.077 0.179 0.092 0.812 0.121 0.710 0.128 0.625 0.163 0.959 0.251 0.161 0.338 0.504 0.355 0.551 0.366 0.689 0.383 0.507 0.393 0.845 0.406 0.806 0.410 0.601 0.421 0.815 0.444 0.856 0.456 0.575 0.500 0.742 0.510 0.619 0.515 0.408 0.524 0.754 0.537 0.563 0.546 0.331 0.551 0.683 0.564 0.625 0.572 0.493 0.580 0.704 0.593 0.639 0.597 0.396 0.604 0.721 0.621 0.551 0.624 0.413 0.630 0.660 0.647 0.557 0.650 0.416 0.660 0.707 0.678 0.472 0.685 0.686 0.703 0.496 0.716 0.733 0.732 0.575 0.740 0.739 0.750 0.648 0.765 0.762 0.771 0.727 0.777 0.636 0.792 0.809 0.806 0.648 0.830 0.845 0.841 0.745 0.875 0.982 0.906 1.000 0.931 0.944 0.970 0.645 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.197 0.042 0.463 0.047 0.513 0.060 0.492 0.067 0.553 0.076 0.624 0.086 0.592 0.100 0.513 0.135 0.453 0.186 0.411 0.224 0.395 0.250 0.403 0.281 0.368 0.357 0.366 0.370 0.397 0.384 0.376 0.396 0.426 0.412 0.400 0.426 0.445 0.440 0.421 0.449 0.476 0.463 0.437 0.478 0.497 0.490 0.453 0.503 0.503 0.515 0.447 0.531 0.503 0.545 0.461 0.557 0.511 0.569 0.463 0.580 0.516 0.595 0.455 0.608 0.505 0.625 0.455 0.638 0.505 0.649 0.455 0.665 0.495 0.679 0.455 0.693 0.500 0.707 0.447 0.721 0.487 0.735 0.455 0.750 0.479 0.766 0.453 0.778 0.479 0.793 0.439 0.808 0.461 0.821 0.437 0.837 0.458 0.861 0.437 1.000 0.408) :duration dur :scaler (hz->radians 7800.0))) (gen1 (make-polywave 0.0 '(1 .98 2 .01 3 .01 4 .005 5 .005)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf))))))) ;; note #5 (let ((dur 0.14) (start (seconds->samples (+ beg 0.65)))) (let ((stop (+ start (seconds->samples dur))) (ampf (make-env '(0.000 0.000 0.033 0.216 0.110 0.247 0.218 0.800 0.263 0.734 0.301 0.889 0.370 0.966 0.470 0.905 0.494 0.658 0.531 0.666 0.727 0.508 1.000 0.000) :duration dur :scaler (* .3 amp))) (frqf (make-env '(0.124 0.214 0.222 0.265 0.311 0.310 0.400 0.317 0.501 0.307 0.651 0.283 0.752 0.262 1.000 0.198) :duration dur :scaler (hz->radians 8100.0))) (gen1 (make-polywave 0.0 (normalize-partials '(1 1.5 2 .01 3 .01 4 .07 5 .04 6 .05 8 .005)))) (rnd (make-rand-interp 3000)) (rndf (make-env '(0 1 .2 0 .7 0 .8 1 1 1) :duration dur :scaler (hz->radians 200)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (+ (env frqf) (* (env rndf) (rand-interp rnd)))))))))) ;; (with-sound (:play #t) (white-eyed-vireo 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Willet (defanimal (willet beg amp) ;; calif2 36 2 ;; note #1 (let ((dur 0.037)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.017 0.603 0.397 0.986 0.531 0.915 0.750 0.255 0.836 0.383 0.913 0.420 1.000 0.000) :duration dur :scaler (* .25 amp))) (frqf (make-env '(0.000 0.172 0.152 0.172 0.401 0.188 0.667 0.201 0.808 0.205 0.951 0.227 1.000 0.234) :duration dur :scaler (hz->radians (* 1/3 13000.0)))) (gen1 (make-polywave 0.0 (normalize-partials '(1 .03 2 .1 3 1 4 .6 5 .5 6 .4 7 .1 8 .04 9 .01 10 .01 11 .005))))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf))))))) ;; note #2 (let ((dur 0.029) (start (seconds->samples (+ beg 0.054)))) (let ((stop (+ start (seconds->samples dur))) (ampf (make-env '(0.000 0.000 0.063 0.263 0.086 0.656 0.113 0.877 0.429 0.753 0.681 0.578 0.830 0.224 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.178 0.849 0.156 1.000 0.156) :duration dur :scaler (hz->radians (* 1/2 14900.0)))) (gen1 (make-polywave 0.0 (normalize-partials '(1 .07 2 1 3 .8 4 .47 5 .14 6 .04 7 .03 8 .01))))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) ;; (with-sound (:play #t) (willet 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Philadelphia vireo (defanimal (philadelphia-vireo beg amp) ;; east 58 3 (let ((dur 0.364)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.051 0.03 0.078 0.168 0.100 0.358 0.120 0.179 0.146 0.059 0.166 0.551 0.175 0.363 0.188 0.486 0.197 0.441 0.212 0.559 0.226 1.000 0.311 0.105 0.317 0.227 0.348 0.152 0.380 0.142 0.408 0.067 0.469 0.000 0.615 0.000 0.637 0.094 0.702 0.138 0.731 0.055 0.784 0.028 0.835 0.168 0.899 0.429 0.928 0.323 0.942 0.220 0.953 0.309 0.957 0.050 0.968 0.264 0.984 0.032 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.912 0.033 0.904 0.060 0.664 0.092 0.555 0.110 0.499 0.148 0.403 0.167 0.480 0.178 0.567 0.198 0.593 0.221 0.563 0.236 0.510 0.254 0.465 0.283 0.430 0.331 0.373 0.385 0.338 0.444 0.296 0.509 0.306 0.635 0.396 0.653 0.443 0.667 0.456 0.683 0.437 0.719 0.351 0.745 0.296 0.765 0.281 0.802 0.298 0.835 0.358 0.868 0.452 0.904 0.507 0.955 0.505 0.966 0.488 0.971 0.520 0.980 0.493 1.000 0.510) :duration dur :scaler (hz->radians 7400.0))) (gen1 (make-polywave 0.0 '(1 .98 2 .015 3 .005)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) ;; (with-sound (:play #t) (philadelphia-vireo 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Black-crowned night heron (defanimal (black-crowned-night-heron beg amp) ;; east 15 6 (let ((dur 0.145)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.045 0.233 0.289 0.674 0.508 0.865 0.762 1.000 0.847 0.900 0.929 0.368 0.958 0.100 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.119 0.219 0.149 0.385 0.168 0.501 0.182 0.555 0.201 0.708 0.190 1.000 0.168) :duration dur :scaler (hz->radians (* 1/2 7150.0)))) (gen1 (make-oscil)) (gens (make-nrxycos 0.0 1/6 15 .9)) (gens0 (make-polywave 0.0 (nrcos->polywave 6 .5 .2))) (rf (make-env '(0 .5 .4 .9 .7 .8 1 .5) :duration dur)) (rnd (make-rand-interp 1000 (hz->radians 50))) (vib (make-triangle-wave 500 (hz->radians 30))) (rnd1 (make-rand-interp 1000 .5))) (do ((i start (+ i 1))) ((= i stop)) (let ((frq (+ (env frqf) (triangle-wave vib) (rand-interp rnd)))) (set! (mus-scaler gens) (env rf)) ;scaler=r (outa i (* (env ampf) (+ .5 (abs (rand-interp rnd1))) (+ (oscil gen1 (* 2.0 frq)) (polywave gens0 frq) (nrxycos gens (* 6.0 frq)))))))))) ;; (with-sound (:play #t) (black-crowned-night-heron 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Scrub Euphonia (defanimal (scrub-euphonia beg amp) ;; arizona 90 3.0 (let ((dur 0.49)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.067 0.188 0.111 0.676 0.151 0.838 0.239 0.988 0.275 0.000 0.346 0.000 0.386 0.243 0.399 0.615 0.427 0.719 0.445 0.587 0.464 0.664 0.521 0.630 0.533 0.571 0.567 0.868 0.580 0.877 0.611 0.176 0.628 0.138 0.637 0.000 0.671 0.000 0.676 0.168 0.690 0.204 0.725 0.694 0.742 0.725 0.821 0.464 0.904 0.696 0.939 0.109 1.000 0.000) :duration dur :scaler amp)) (gen1 (make-polywave 0.0 '(1 .99 2 .01))) (frqf (make-env '(0.000 0.819 0.024 0.761 0.063 0.686 0.101 0.642 0.171 0.586 0.229 0.556 0.271 0.558 0.342 0.556 0.347 0.883 0.361 0.900 0.367 0.719 0.390 0.656 0.436 0.589 0.480 0.564 0.529 0.547 0.555 0.525 0.605 0.519 0.640 0.528 0.660 0.869 0.673 0.869 0.683 0.681 0.717 0.625 0.763 0.561 0.791 0.564 0.817 0.544 0.857 0.533 0.894 0.522 0.924 0.531 1.000 0.531) :duration dur :scaler (hz->radians 7160)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) ;; (with-sound (:play #t) (scrub-euphonia 0 .25)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Greater pewee (defanimal (greater-pewee beg1 amp) ;; arizona 52 2 (define (greater-pewee-first-and-last beg) (let ((dur 0.4)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.011 0.083 0.220 0.268 0.374 0.325 0.463 0.337 0.542 0.289 0.599 0.000 0.668 0.000 0.683 0.554 0.701 0.501 0.735 1.000 0.775 0.039 0.829 0.806 0.852 0.862 0.877 0.979 0.888 0.912 0.900 0.968 0.912 0.822 0.928 0.866 0.939 0.762 0.950 0.783 0.970 0.637 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.102 0.018 0.114 0.138 0.124 0.251 0.124 0.438 0.124 0.511 0.124 0.589 0.119 0.649 0.124 0.663 0.169 0.672 0.150 0.704 0.124 0.750 0.135 0.777 0.124 0.795 0.121 0.969 0.147 1.000 0.162) :duration dur :scaler (hz->radians 22500))) ; not a typo... (gen1 (make-polywave 0.0 '(1 .96 2 .02 3 .02)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) (define (greater-pewee-midsection beg) (let ((dur 1.65)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.023 0.155 0.085 0.349 0.196 0.507 0.219 0.513 0.227 0.000 0.295 0.000 0.306 0.510 0.333 0.741 0.356 0.825 0.370 0.752 0.386 0.775 0.394 0.713 0.409 0.761 0.431 0.668 0.439 0.713 0.456 0.701 0.469 0.000 0.570 0.000 0.578 0.093 0.619 0.152 0.653 0.223 0.684 0.217 0.721 0.299 0.745 0.507 0.780 0.620 0.795 0.586 0.808 0.679 0.836 0.428 0.852 0.563 0.862 0.997 0.875 0.625 0.887 0.476 0.982 0.251 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.274 0.038 0.283 0.219 0.291 0.302 0.293 0.410 0.324 0.451 0.327 0.464 0.315 0.518 0.324 0.542 0.213 0.580 0.223 0.715 0.242 0.759 0.293 0.813 0.308 0.828 0.320 0.843 0.341 0.857 0.337 0.877 0.276 0.896 0.252 1.000 0.230) :duration dur :scaler (hz->radians 10000))) (gen1 (make-polywave 0.0 '(1 .98 2 .01 3 .01)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) (greater-pewee-first-and-last beg1) (greater-pewee-midsection (+ beg1 1.13)) (greater-pewee-first-and-last (+ beg1 3.2))) ;; (with-sound (:play #t) (greater-pewee 0 .5)) ;;; -------------------------------------------------------------------------------- ;;; ;;; Brown-crested flycatcher (defanimal (brown-crested-flycatcher-1 beg amp) ;; calif 13 7 (let ((dur 0.66)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.017 0.616 0.035 0.803 0.044 0.410 0.050 0.674 0.056 0.157 0.065 0.452 0.081 0.350 0.105 0.426 0.106 0.279 0.111 0.439 0.122 0.483 0.133 0.743 0.192 0.466 0.197 0.608 0.212 0.424 0.221 0.998 0.236 0.335 0.244 0.690 0.260 0.652 0.274 0.703 0.283 0.537 0.288 0.847 0.298 0.743 0.305 0.829 0.323 0.324 0.336 0.619 0.349 0.075 0.357 0.457 0.362 0.322 0.366 0.426 0.390 0.193 0.396 0.452 0.413 0.000 0.415 0.302 0.422 0.220 0.426 0.259 0.433 0.120 0.437 0.191 0.452 0.000 0.530 0.000 0.556 0.144 0.564 0.399 0.589 0.000 0.617 0.000 0.623 0.149 0.634 0.392 0.655 0.000 0.678 0.000 0.682 .100 0.695 0.153 0.707 0.000 0.715 0.073 0.727 0.111 0.737 0.000 0.778 0.000 0.786 0.089 0.798 0.060 0.806 0.175 0.815 0.000 0.829 0.000 0.830 0.217 0.842 0.146 0.846 0.222 0.859 0.000 0.872 0.000 0.874 0.191 0.885 0.146 0.894 0.222 0.908 0.000 0.918 0.000 0.919 0.166 0.924 0.115 0.929 0.169 0.938 0.091 0.942 0.038 0.949 0.069 0.953 0.038 0.960 0.102 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.492 0.013 0.588 0.027 0.615 0.047 0.551 0.072 0.531 0.097 0.551 0.137 0.579 0.197 0.588 0.211 0.608 0.219 0.654 0.225 0.592 0.237 0.583 0.270 0.581 0.288 0.695 0.299 0.572 0.304 0.599 0.310 0.563 0.326 0.558 0.340 0.692 0.356 0.579 0.364 0.538 0.375 0.510 0.390 0.501 0.397 0.610 0.414 0.576 0.417 0.478 0.436 0.462 0.442 0.513 0.454 0.339 0.524 0.339 0.566 0.503 0.587 0.310 0.610 0.308 0.628 0.485 0.638 0.460 0.655 0.292 0.674 0.294 0.685 0.431 0.699 0.417 0.715 0.351 0.728 0.524 0.745 0.519 0.760 0.369 0.780 0.369 0.788 0.442 0.805 0.460 0.809 0.574 0.830 0.576 0.832 0.469 0.846 0.474 0.854 0.574 0.873 0.604 0.877 0.476 0.892 0.476 0.901 0.592 0.917 0.563 0.923 0.458 0.939 0.462 0.955 0.431 0.976 0.431 1.000 0.351) :duration dur :scaler (hz->radians 4500))) (gen1 (make-polywave 0.0 '(1 .9 2 .03 3 .05 4 .01 5 .01)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) ;; (with-sound (:play #t) (brown-crested-flycatcher-1 0 .5)) (defanimal (brown-crested-flycatcher-2 beg amp) ;; calif 13 63.5 (let ((dur 0.47)) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0.000 0.000 0.021 0.219 0.040 0.847 0.057 0.948 0.071 0.929 0.084 0.000 0.119 0.000 0.132 0.633 0.145 0.711 0.153 0.836 0.175 0.000 0.202 0.000 0.215 0.237 0.233 0.232 0.255 0.000 0.403 0.000 0.426 0.091 0.449 0.032 0.469 0.164 0.494 0.064 0.536 0.219 0.568 0.125 0.586 0.210 0.622 0.185 0.627 0.128 0.652 0.155 0.675 0.271 0.692 0.205 0.699 0.077 0.719 0.144 0.757 0.296 0.779 0.084 0.801 0.175 0.821 0.371 0.851 0.180 0.867 0.112 0.898 0.273 0.942 0.080 0.976 0.294 0.991 0.262 1.000 0.000) :duration dur :scaler amp)) (frqf (make-env '(0.000 0.392 0.036 0.595 0.049 0.626 0.064 0.601 0.082 0.405 0.117 0.387 0.126 0.497 0.138 0.540 0.150 0.538 0.158 0.499 0.173 0.392 0.201 0.346 0.210 0.444 0.219 0.474 0.231 0.465 0.239 0.433 0.254 0.346 0.404 0.349 0.423 0.417 0.439 0.401 0.461 0.410 0.469 0.440 0.502 0.415 0.520 0.451 0.536 0.456 0.554 0.435 0.575 0.428 0.597 0.492 0.636 0.440 0.678 0.506 0.694 0.465 0.723 0.476 0.751 0.517 0.762 0.478 0.789 0.478 0.818 0.522 0.839 0.508 0.854 0.474 0.882 0.492 0.901 0.515 0.925 0.490 0.947 0.481 0.958 0.501 0.986 0.494 1.000 0.633) :duration dur :scaler (hz->radians 4100))) (gen1 (make-polywave 0.0 '(1 .9 2 .02 3 .005 4 .02 5 .007 6 .01)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (polywave gen1 (env frqf)))))))) ;; (with-sound (:play #t) (brown-crested-flycatcher-2 0 .5)) ;;; ================ calling-all-animals ================ (define* (calling-all-frogs (beg 0.0) (spacing 0.0)) (plains-spadefoot (+ beg 0) 0.25) (set! beg (+ beg spacing)) (barking-tree-frog (+ beg 1) 0.25) (set! beg (+ beg spacing)) (western-toad (+ beg 1.5) 2 0.25) (set! beg (+ beg spacing)) (southwestern-toad (+ beg 4) 2 0.25) (set! beg (+ beg spacing)) (american-toad (+ beg 6.5) 3 0.25) (set! beg (+ beg spacing)) (texas-toad (+ beg 10) 2.0 0.125) (set! beg (+ beg spacing)) (bullfrog (+ beg 12.5) 0.125) (set! beg (+ beg spacing)) (ornate-chorus-frog (+ beg 14) 2 0.1) (set! beg (+ beg spacing)) (squirrel-tree-frog (+ beg 16.5) 1 0.1) (set! beg (+ beg spacing)) (pinewoods-tree-frog (+ beg 18) 1.5 0.15) (set! beg (+ beg spacing)) (great-plains-narrow-mouthed-toad (+ beg 20) 2 .25) (set! beg (+ beg spacing)) (northern-leopard-frog-2 (+ beg 22.5) 0.5) (set! beg (+ beg spacing)) (pacific-chorus-frog (+ beg 24.5) .5) (set! beg (+ beg spacing)) (oak-toad (+ beg 25) 0.3) (set! beg (+ beg spacing)) (southern-cricket-frog (+ beg 25.5) 0.5) (set! beg (+ beg spacing)) (northern-leopard-frog-1 (+ beg 26) 0.5) (set! beg (+ beg spacing)) (green-tree-frog (+ beg 30.5) 0.5) (set! beg (+ beg spacing)) (knudsens-frog (+ beg 31) 0.5) (set! beg (+ beg spacing)) (spring-peeper (+ beg 31.5) 0.5) (set! beg (+ beg spacing)) (crawfish-frog (+ beg 32) 0.5) (set! beg (+ beg spacing)) (river-frog (+ beg 33) 0.5) (set! beg (+ beg spacing)) (red-spotted-toad (+ beg 35) 4 .25) (set! beg (+ beg spacing)) (green-toad (+ beg 39.5) 2 .25) (set! beg (+ beg spacing)) (little-grass-frog (+ beg 42.0) .25) (set! beg (+ beg spacing)) (sonoran-desert-toad (+ beg 43.0) .8 .25) (set! beg (+ beg spacing)) (amargosa-toad (+ beg 44.0) 0.5) (set! beg (+ beg spacing)) (+ beg 45)) (define* (calling-all-mammals (beg 0.0) (spacing 0.0)) (indri beg 0.25) (set! beg (+ beg spacing)) (+ beg 2)) (define* (calling-all-insects (beg 0.0) (spacing 0.0)) (mosquito (+ beg 0) 5 560 0.2) (set! beg (+ beg spacing)) (mosquito (+ beg 1) 3 880 0.05) (set! beg (+ beg spacing)) (broad-winged-tree-cricket (+ beg 5.5) 2.0 0.2) (set! beg (+ beg spacing)) (long-spurred-meadow-katydid (+ beg 8) 0.5) (set! beg (+ beg spacing)) (southern-mole-cricket (+ beg 18.5) 3 0.15) (set! beg (+ beg spacing)) (handsome-trig (+ beg 22) 2 0.5) (set! beg (+ beg spacing)) (fast-calling-tree-cricket (+ beg 24.5) 2 0.25) (set! beg (+ beg spacing)) (dog-day-cicada (+ beg 27) 2 0.1) (set! beg (+ beg spacing)) (linnaeus-cicada (+ beg 29.5) 2 0.125) (set! beg (+ beg spacing)) (lyric-cicada (+ beg 32) 2 0.125) (set! beg (+ beg spacing)) (confused-ground-cricket (+ beg 34.5) 2 0.3) (set! beg (+ beg spacing)) (tinkling-ground-cricket (+ beg 37) 2 0.3) (set! beg (+ beg spacing)) (marsh-meadow-grasshopper (+ beg 39.5) 0.3) (set! beg (+ beg spacing)) (striped-ground-cricket (+ beg 45) 2 0.25) (set! beg (+ beg spacing)) (sphagnum-ground-cricket (+ beg 47.5) 2 0.3) (set! beg (+ beg spacing)) (southeastern-field-cricket (+ beg 50) 2 0.13) (set! beg (+ beg spacing)) (snowy-tree-cricket (+ beg 52.5) 2.1 0.3) (set! beg (+ beg spacing)) (slightly-musical-conehead (+ beg 55) 2 0.4) (set! beg (+ beg spacing)) (pine-tree-cricket (+ beg 57.5) 2 0.125) (set! beg (+ beg spacing)) (davis-tree-cricket (+ beg 60) 2 0.125) (set! beg (+ beg spacing)) (carolina-grasshopper (+ beg 62.5) 1.5 1.0) (set! beg (+ beg spacing)) (black-horned-tree-cricket (+ beg 64.5) 2 0.125) (set! beg (+ beg spacing)) (narrow-winged-tree-cricket (+ beg 67.0) 2.0 .25) (set! beg (+ beg spacing)) (four-spotted-tree-cricket (+ beg 69.5) 1.0 .25) (set! beg (+ beg spacing)) (+ beg 71)) (define* (calling-all-birds (beg 0.0) (spacing .25)) (ruffed-grouse (+ beg 0.0) 0.5) (set! beg (+ beg spacing)) (eastern-wood-pewee-1 (+ beg 11.0) 0.25) (set! beg (+ beg spacing)) (eastern-wood-pewee-2 (+ beg 12.5) 0.25) (set! beg (+ beg spacing)) (field-sparrow (+ beg 14.0) 0.25) (set! beg (+ beg spacing)) (fox-sparrow (+ beg 17.5) 3 0.25) (set! beg (+ beg spacing)) (white-throated-sparrow (+ beg 21.0) 0.25) (set! beg (+ beg spacing)) (tufted-titmouse (+ beg 25.0) 0.3) (set! beg (+ beg spacing)) (savannah-sparrow (+ beg 26.5) 0.5) (set! beg (+ beg spacing)) (chipping-sparrow (+ beg 30.0) 0.3) (set! beg (+ beg spacing)) (henslows-sparrow (+ beg 33.0) 0.5) (set! beg (+ beg spacing)) (least-flycatcher (+ beg 33.5) 0.5) (set! beg (+ beg spacing)) (acadian-flycatcher (+ beg 34.0) 0.25) (set! beg (+ beg spacing)) (swainsons-thrush (+ beg 35.0) 0.25) (set! beg (+ beg spacing)) (carolina-wren (+ beg 37.5) 0.25) (set! beg (+ beg spacing)) (bachmans-sparrow (+ beg 40.0) 0.25) (set! beg (+ beg spacing)) (grasshopper-sparrow (+ beg 43.0) 0.25) (set! beg (+ beg spacing)) (american-robin (+ beg 45.0) 0.25) (set! beg (+ beg spacing)) (common-loon-1 (+ beg 47.5) 0.125) (set! beg (+ beg spacing)) (common-loon-2 (+ beg 50.5) 0.125) (set! beg (+ beg spacing)) (hermit-thrush (+ beg 51.5) 0.25) (set! beg (+ beg spacing)) (chuck-wills-widow (+ beg 53.5) 0.25) (set! beg (+ beg spacing)) (california-towhee (+ beg 55.0) 0.25) (set! beg (+ beg spacing)) (black-chinned-sparrow (+ beg 56.5) 0.25 #t) (set! beg (+ beg spacing)) (mourning-dove (+ beg 60.0) 0.125) (set! beg (+ beg spacing)) (bobwhite (+ beg 64.5) 0.25) (set! beg (+ beg spacing)) (warbling-vireo (+ beg 66.5) 0.25) (set! beg (+ beg spacing)) (great-horned-owl (+ beg 69.0) 0.25) (set! beg (+ beg spacing)) (western-tanager (+ beg 72.0) 0.25) (set! beg (+ beg spacing)) (pileated-woodpecker (+ beg 74.5) 0.125) (set! beg (+ beg spacing)) (whip-poor-will (+ beg 77.5) 0.25) (set! beg (+ beg spacing)) (varied-thrush (+ beg 79.0) 0.125) (set! beg (+ beg spacing)) (nashville-warbler (+ beg 80.5) 0.25) (set! beg (+ beg spacing)) (plumbeous-vireo-1 (+ beg 83.0) 0.25) (set! beg (+ beg spacing)) (american-crow (+ beg 84.0) 0.5) (set! beg (+ beg spacing)) (least-bittern (+ beg 85.0) 0.5) (set! beg (+ beg spacing)) (orange-crowned-warbler (+ beg 87.0) 0.25) (set! beg (+ beg spacing)) (loggerhead-shrike-1 (+ beg 89.0) 0.125) (set! beg (+ beg spacing)) (loggerhead-shrike-2 (+ beg 90.0) 0.125) (set! beg (+ beg spacing)) (california-quail (+ beg 91.0) 0.25) (set! beg (+ beg spacing)) (vermillion-flycatcher (+ beg 92.0) 0.25) (set! beg (+ beg spacing)) (cardinal (+ beg 93.0) 0.25) (set! beg (+ beg spacing)) (black-phoebe (+ beg 97.0) 0.25) (set! beg (+ beg spacing)) (yellow-warbler (+ beg 98.0) 0.25) (set! beg (+ beg spacing)) (barred-owl-1 (+ beg 100.0) 0.25) (set! beg (+ beg spacing)) (says-phoebe (+ beg 102.0) 0.25) (set! beg (+ beg spacing)) (yellow-rumped-warbler (+ beg 103.0) 0.25) (set! beg (+ beg spacing)) (purple-finch (+ beg 105.0) 0.25) (set! beg (+ beg spacing)) (northern-goshawk (+ beg 108.0) 0.125) (set! beg (+ beg spacing)) (common-gull (+ beg 109.0) 0.25) (set! beg (+ beg spacing)) (ash-throated-flycatcher (+ beg 110.0) 0.25) (set! beg (+ beg spacing)) (white-headed-woodpecker (+ beg 111.0) 0.25) (set! beg (+ beg spacing)) (phainopepla (+ beg 111.5) 0.5) (set! beg (+ beg spacing)) (golden-crowned-sparrow (+ beg 112.5) 0.25) (set! beg (+ beg spacing)) (house-finch (+ beg 115.0) 0.25) (set! beg (+ beg spacing)) (ruby-crowned-kinglet (+ beg 118.5) 0.25) (set! beg (+ beg spacing)) (green-tailed-towhee (+ beg 121.0) 0.25) (set! beg (+ beg spacing)) (lucys-warbler (+ beg 124.0) 0.25) (set! beg (+ beg spacing)) (cassins-vireo (+ beg 126.0) 0.25) (set! beg (+ beg spacing)) (plain-chacalaca (+ beg 127.0) 0.5) (set! beg (+ beg spacing)) (black-billed-cuckoo (+ beg 128.0) 0.25) (set! beg (+ beg spacing)) (eared-grebe (+ beg 129.0) 0.25) (set! beg (+ beg spacing)) (brown-jay (+ beg 130.0) 0.5) (set! beg (+ beg spacing)) (blue-grosbeak (+ beg 131.0) 0.25) (set! beg (+ beg spacing)) (acorn-woodpecker (+ beg 134.0) 0.5) (set! beg (+ beg spacing)) (red-shouldered-hawk (+ beg 136.0) 0.5) (set! beg (+ beg spacing)) (lesser-nighthawk (+ beg 137.0) 2 0.25) (set! beg (+ beg spacing)) (olive-sided-flycatcher (+ beg 139.5) 0.125) (set! beg (+ beg spacing)) (common-yellowthroat (+ beg 141.0) 0.25) (set! beg (+ beg spacing)) (cassins-sparrow (+ beg 143.5) 0.25) (set! beg (+ beg spacing)) (stellers-jay (+ beg 146.0) 0.25) (set! beg (+ beg spacing)) (black-rail (+ beg 147.5) 0.25) (set! beg (+ beg spacing)) (pinyon-jay (+ beg 148.5) 0.25) (set! beg (+ beg spacing)) (sora (+ beg 149.5) 0.25) (set! beg (+ beg spacing)) (killdeer (+ beg 150.5) 0.25) (set! beg (+ beg spacing)) (oak-titmouse (+ beg 152.0) 0.25) (set! beg (+ beg spacing)) (macgillivrays-warbler (+ beg 154.0) 0.25) (set! beg (+ beg spacing)) (huttons-vireo (+ beg 156.0) 0.25) (set! beg (+ beg spacing)) (western-meadowlark (+ beg 157.0) 0.25) (set! beg (+ beg spacing)) (northern-beardless-tyrannulet (+ beg 159.0) 0.25) (set! beg (+ beg spacing)) (scotts-oriole (+ beg 161.5) 0.25) (set! beg (+ beg spacing)) (wilsons-warbler (+ beg 164.0) 0.25) (set! beg (+ beg spacing)) (willow-flycatcher (+ beg 166.5) 0.25) (set! beg (+ beg spacing)) (black-necked-stilt (+ beg 167.5) 0.25) (set! beg (+ beg spacing)) (bushtit (+ beg 168.0) 0.25) (set! beg (+ beg spacing)) (red-breasted-nuthatch (+ beg 169.0) 0.25) (set! beg (+ beg spacing)) (white-breasted-nuthatch (+ beg 170.0) 0.25) (set! beg (+ beg spacing)) (pygmy-nuthatch (+ beg 171.0) 0.25) (set! beg (+ beg spacing)) (flammulated-owl (+ beg 171.5) 0.25) (set! beg (+ beg spacing)) (song-sparrow (+ beg 172.0) 0.25) (set! beg (+ beg spacing)) (burrowing-owl (+ beg 175.0) 0.25) (set! beg (+ beg spacing)) (gray-vireo-1 (+ beg 176.0) 0.25) (set! beg (+ beg spacing)) (gray-vireo-2 (+ beg 176.5) 0.25) (set! beg (+ beg spacing)) (bald-eagle (+ beg 177.0) 0.25) (set! beg (+ beg spacing)) (eastern-meadowlark (+ beg 178.5) 0.25) (set! beg (+ beg spacing)) (plumbeous-vireo-2 (+ beg 180.5) 0.25) (set! beg (+ beg spacing)) (yellow-green-vireo (+ beg 181.5) 0.25) (set! beg (+ beg spacing)) (magnolia-warbler (+ beg 182.0) 0.25) (set! beg (+ beg spacing)) (eastern-bluebird (+ beg 183.5) 0.25) (set! beg (+ beg spacing)) (evening-grosbeak (+ beg 184.5) 0.25) (set! beg (+ beg spacing)) (greater-roadrunner (+ beg 185.0) 0.5) (set! beg (+ beg spacing)) (dark-eyed-junco (+ beg 190.0) 0.25) (set! beg (+ beg spacing)) (groove-billed-ani (+ beg 192.0) 0.25) (set! beg (+ beg spacing)) (common-pauraque (+ beg 193.0) 0.25) (set! beg (+ beg spacing)) (hammonds-flycatcher (+ beg 194.0) 0.25) (set! beg (+ beg spacing)) (barn-owl (+ beg 194.5) 0.25) (set! beg (+ beg spacing)) (long-eared-owl (+ beg 196.0) 0.25) (set! beg (+ beg spacing)) (summer-tanager (+ beg 197.0) 0.25) (set! beg (+ beg spacing)) (whooping-crane (+ beg 201.0) .5) (set! beg (+ beg spacing)) (sandhill-crane (+ beg 202.0) .5) (set! beg (+ beg spacing)) (gray-crowned-rosy-finch (+ beg 203.0) .25) (set! beg (+ beg spacing)) (virginia-rail (+ beg 203.5) .25) (set! beg (+ beg spacing)) (sage-sparrow (+ beg 206.0) .25) (set! beg (+ beg spacing)) (hairy-woodpecker (+ beg 208.0) .25) (set! beg (+ beg spacing)) (pacific-slope-flycatcher (+ beg 208.5) .25) (set! beg (+ beg spacing)) (dusky-flycatcher (+ beg 209.0) .25) (set! beg (+ beg spacing)) (inca-dove-1 (+ beg 209.5) .25) (set! beg (+ beg spacing)) (inca-dove-2 (+ beg 210.5) .25) (set! beg (+ beg spacing)) (great-kiskadee (+ beg 211.0) .25) (set! beg (+ beg spacing)) (chestnut-sided-warbler (+ beg 212.0) .25) (set! beg (+ beg spacing)) (yellow-bellied-flycatcher (+ beg 213.5) .25) (set! beg (+ beg spacing)) (black-throated-blue-warbler (+ beg 214.0) .25) (set! beg (+ beg spacing)) (great-crested-flycatcher (+ beg 215.5) .25) (set! beg (+ beg spacing)) (gray-vireo (+ beg 216.0) .25) (set! beg (+ beg spacing)) (house-sparrow-1 (+ beg 218.0) .25) (set! beg (+ beg spacing)) (gambels-quail (+ beg 218.5) .25) (set! beg (+ beg spacing)) (scaled-quail (+ beg 219.5) .25) (set! beg (+ beg spacing)) (montezuma-quail (+ beg 221.0) .25) (set! beg (+ beg spacing)) (mountain-quail (+ beg 222.5) .25) (set! beg (+ beg spacing)) (verdin (+ beg 223.0) .25) (set! beg (+ beg spacing)) (white-tipped-dove (+ beg 224.0) .25) (set! beg (+ beg spacing)) (zone-tailed-hawk (+ beg 226.0) .25) (set! beg (+ beg spacing)) (red-eyed-vireo (+ beg 228.0) .25) (set! beg (+ beg spacing)) (crested-caracara (+ beg 228.5) .25) (set! beg (+ beg spacing)) (trumpeter-swan-1 (+ beg 229.5) .25) (set! beg (+ beg spacing)) (wrentit (+ beg 230.5) .25) (set! beg (+ beg spacing)) (western-wood-pewee-1 (+ beg 233.5) .25) (set! beg (+ beg spacing)) (western-wood-pewee-2 (+ beg 234.5) .25) (set! beg (+ beg spacing)) (cedar-waxwing (+ beg 235.5) .25) (set! beg (+ beg spacing)) (townsends-solitaire (+ beg 236.0) .25) (set! beg (+ beg spacing)) (canada-goose (+ beg 237.5) .25) (set! beg (+ beg spacing)) (pine-warbler (+ beg 239.0) .25) (set! beg (+ beg spacing)) (black-throated-sparrow (+ beg 241.5) .25) (set! beg (+ beg spacing)) (cape-may-warbler (+ beg 242.5) .25) (set! beg (+ beg spacing)) (kirtlands-warbler (+ beg 244.0) .25) (set! beg (+ beg spacing)) (wood-duck (+ beg 245.5) .25) (set! beg (+ beg spacing)) (white-eyed-vireo (+ beg 246.5) .25) (set! beg (+ beg spacing)) (philadelphia-vireo (+ beg 247.5) .25) (set! beg (+ beg spacing)) (willet (+ beg 248.3) .25) (set! beg (+ beg spacing)) (black-crowned-night-heron (+ beg 249.0) .25) (set! beg (+ beg spacing)) (scrub-euphonia (+ beg 249.5) .25) (set! beg (+ beg spacing)) (greater-pewee (+ beg 250.0) .25) (set! beg (+ beg spacing)) (brown-crested-flycatcher-1 (+ beg 254.0) .25) (set! beg (+ beg spacing)) (brown-crested-flycatcher-2 (+ beg 254.9) .25) (set! beg (+ beg spacing)) (+ beg 255.5)) (define (calling-all-animals) (with-sound (:srate 44100) ;(srate needed by snd-test) (let ((beg 0.0)) (set! beg (calling-all-frogs beg)) (set! beg (calling-all-mammals beg)) (set! beg (calling-all-insects beg)) (set! beg (calling-all-birds beg))))) snd-16.1/marks-menu.scm0000644000076400007640000011771512622705137013137 0ustar bilbil(provide 'snd-marks-menu.scm) (if (provided? 'xm) (begin (require snd-effects-utils.scm) (if (not (defined? 'mark-sync-color)) (load "snd-motif.scm")))) (when (provided? 'snd-motif) (define mark-sync-color (*motif* 'mark-sync-color))) (if (provided? 'xg) (begin (require snd-gtk-effects-utils.scm) (if (not (defined? 'mark-sync-color)) (define (mark-sync-color x) x)))) (if (not (defined? 'mark-loops)) (load "examp.scm")) (if (not (defined? 'play-between-marks)) (load "marks.scm")) (if (not (defined? 'loop-between-marks)) (load "play.scm")) (define *e* (if (provided? 'snd-motif) *motif* *gtk*)) (define update-label (*e* 'update-label)) (define change-label (*e* 'change-label)) (define make-effect-dialog (*e* 'make-effect-dialog)) (define add-sliders (*e* 'add-sliders)) (define activate-dialog (*e* 'activate-dialog)) (define select-file (*e* 'select-file)) (define marks-list ()) ; menu labels are updated to show current default settings (define marks-menu (add-to-main-menu "Marks" (lambda () (update-label marks-list)))) (define find-two-marks (let ((documentation "(find-two-marks) looks for the marks for the marks-menu functions to use")) (lambda () (let* ((snd (selected-sound)) (chn (selected-channel)) (ms (marks snd chn))) (if (> (length ms) 1) (map mark->integer (list (car ms) (cadr ms))) (list)))))) ;;; -------- Play between by marks (define play-between-marks-m1 0) (define play-between-marks-m2 1) (define play-between-marks-label "Play between marks") (define play-between-marks-dialog #f) (define play-between-marks-menu-label #f) (define cp-play-between-marks (let ((documentation "(cp-play-between-marks) plays between 2 marks (marks-menu)")) (lambda () (play-between-marks (integer->mark play-between-marks-m1) (integer->mark play-between-marks-m2))))) (if (or (provided? 'xm) (provided? 'xg)) (begin (define (set-syncs) (for-each (lambda (snd-marks) (for-each (lambda (chan-marks) (for-each (lambda (m) (if (or (= (mark->integer m) play-between-marks-m1) (= (mark->integer m) play-between-marks-m2)) (set! (sync m) 1) (set! (sync m) 0))) chan-marks)) snd-marks)) (marks)) (update-time-graph)) (define (max-mark) ; "id" here (apply max (map mark->integer (marks (selected-sound) (selected-channel))))) (define (min-mark) (apply min (map mark->integer (marks (selected-sound) (selected-channel))))) (define (post-play-between-marks-dialog) (if (not play-between-marks-dialog) (let ((inits (find-two-marks)) (max-mark-id (max-mark)) (sliders ())) (if (null? inits) (snd-display ";no marks") (begin (set! play-between-marks-m1 (car inits)) (set! play-between-marks-m2 (cadr inits)) (set-syncs) (mark-sync-color "yellow") (set! play-between-marks-dialog (make-effect-dialog play-between-marks-label (if (provided? 'snd-gtk) (lambda (w context) (cp-play-between-marks)) (lambda (w context info) (cp-play-between-marks))) (if (provided? 'snd-gtk) (lambda (w context) (help-dialog "Define selection by marks Help" "Plays area between specified marks. Use the sliders to select the boundary marks.")) (lambda (w context info) (help-dialog "Define selection by marks Help" "Plays area between specified marks. Use the sliders to select the boundary marks."))) (if (provided? 'snd-gtk) (lambda (w data) ((*gtk* 'gtk_adjustment_set_value) ((*gtk* 'GTK_ADJUSTMENT) (car sliders)) play-between-marks-m1) ((*gtk* 'gtk_adjustment_set_value) ((*gtk* 'GTK_ADJUSTMENT) (cadr sliders)) play-between-marks-m2) ) (lambda (w c i) ((*motif* 'XtSetValues) (sliders 0) (list (*motif* 'XmNvalue) play-between-marks-m1)) ((*motif* 'XtSetValues) (sliders 1) (list (*motif* 'XmNvalue) play-between-marks-m2)))))) (set! sliders (add-sliders play-between-marks-dialog (list (list "mark one" 0 play-between-marks-m1 max-mark-id (if (provided? 'snd-gtk) (lambda (w context) (set! play-between-marks-m1 ((*gtk* 'gtk_adjustment_get_value) ((*gtk* 'GTK_ADJUSTMENT) w))) (set-syncs)) (lambda (w context info) (set! play-between-marks-m1 ((*motif* '.value) info)) (set-syncs))) 1) (list "mark two" 0 play-between-marks-m2 max-mark-id (if (provided? 'snd-gtk) (lambda (w context) (set! play-between-marks-m2 ((*gtk* 'gtk_adjustment_get_value) ((*gtk* 'GTK_ADJUSTMENT) w))) (set-syncs)) (lambda (w context info) (set! play-between-marks-m2 ((*motif* '.value) info)) (set-syncs))) 1)))) (if (provided? 'snd-motif) (with-let (sublet *motif*) (hook-push select-channel-hook (lambda (hook) (let ((max-ms (max-mark)) (min-ms (min-mark)) (current-ms (find-two-marks))) (if (null? current-ms) (set! current-ms (list min-ms max-ms))) (if max-ms (for-each (lambda (slider) (XtVaSetValues slider (list XmNmaximum max-ms XmNminimum min-ms XmNvalue (car current-ms))) (set! current-ms (cdr current-ms))) sliders))))) (hook-push mark-hook (lambda (hook) (if (and (= (hook 'snd) (selected-sound)) (= (hook 'chn) (selected-channel)) (= (hook 'reason) 0)) ; add-mark (for-each (lambda (slider) (XtVaSetValues slider (list XmNmaximum (max-mark)))) sliders)))))))) (if play-between-marks-dialog (activate-dialog play-between-marks-dialog))))) (set! play-between-marks-menu-label (add-to-menu marks-menu "Play between marks" post-play-between-marks-dialog))) (set! play-between-marks-menu-label (add-to-menu marks-menu play-between-marks-label cp-play-between-marks))) (set! marks-list (cons (lambda () (let ((new-label (format #f "Play between marks (~D ~D)" play-between-marks-m1 play-between-marks-m2))) (if play-between-marks-menu-label (change-label play-between-marks-menu-label new-label)) (set! play-between-marks-label new-label))) marks-list)) ;;; -------- Loop play between marks (if (provided? 'xm) (with-let (sublet *motif*) (define loop-between-marks-m1 0) (define loop-between-marks-m2 1) (define loop-between-marks-buffer-size 512) (define loop-between-marks-label "Loop play between marks") (define loop-between-marks-dialog #f) (define loop-between-marks-default-buffer-widget #f) (define loop-between-marks-menu-label #f) (define use-combo-box-for-buffer-size #f) ; radio-buttons or combo-box choice (define (cp-loop-between-marks) ;; cp-loop-between-marks) loops between two marks, playing (marks-menu) (loop-between-marks (integer->mark loop-between-marks-m1) (integer->mark loop-between-marks-m2) loop-between-marks-buffer-size)) (define (overall-max-mark-id default-max) (let ((maxid default-max)) (for-each (lambda (snd-marks) (for-each (lambda (chan-marks) (for-each (lambda (m) (set! maxid (max maxid (mark->integer m)))) chan-marks)) snd-marks)) (marks)) maxid)) (define (post-loop-between-marks-dialog) (if (not loop-between-marks-dialog) ;; if loop-between-marks-dialog doesn't exist, create it (let ((initial-loop-between-marks-m1 0) (initial-loop-between-marks-m2 1) (sliders ()) (max-mark-id (overall-max-mark-id 25))) (set! loop-between-marks-dialog (make-effect-dialog loop-between-marks-label (lambda (w context info) (cp-loop-between-marks)) (lambda (w context info) (help-dialog "Loop play between marks" "Move the sliders to set the mark numbers. Check a radio button to set the buffer size.")) (lambda (w c i) (stop-playing)))) (set! sliders (add-sliders loop-between-marks-dialog (list (list "mark one" 0 initial-loop-between-marks-m1 max-mark-id (lambda (w context info) (set! loop-between-marks-m1 (.value info))) 1) (list "mark two" 0 initial-loop-between-marks-m2 max-mark-id (lambda (w context info) (set! loop-between-marks-m2 (.value info))) 1)))) ;; now add either a radio-button box or a combo-box for the buffer size ;; need to use XtParent here since "mainform" isn't returned by add-sliders (if use-combo-box-for-buffer-size ;; this block creates a "combo box" to handle the buffer size (let* ((s1 (XmStringCreateLocalized "Buffer size")) (frame (XtCreateManagedWidget "frame" xmFrameWidgetClass (XtParent (car sliders)) (list XmNborderWidth 1 XmNshadowType XmSHADOW_ETCHED_IN XmNpositionIndex 2))) (frm (XtCreateManagedWidget "frm" xmFormWidgetClass frame (list XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_FORM XmNbackground *basic-color*))) (lab (XtCreateManagedWidget "Buffer size" xmLabelWidgetClass frm (list XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_NONE XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_FORM XmNlabelString s1 XmNbackground *basic-color*))) (buffer-labels (map XmStringCreateLocalized (list "64" "128" "256" "512" "1024" "2048" "4096"))) (combo (XtCreateManagedWidget "buffersize" xmComboBoxWidgetClass frm (list XmNleftAttachment XmATTACH_WIDGET XmNleftWidget lab XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_FORM XmNitems buffer-labels XmNitemCount (length buffer-labels) XmNcomboBoxType XmDROP_DOWN_COMBO_BOX XmNbackground *basic-color*)))) (set! loop-between-marks-default-buffer-widget combo) (for-each XmStringFree buffer-labels) (XmStringFree s1) (XtSetValues combo (list XmNselectedPosition 1)) (XtAddCallback combo XmNselectionCallback (lambda (w c i) (let* ((selected (.item_or_text i)) (size-as-string (XmStringUnparse selected #f XmCHARSET_TEXT XmCHARSET_TEXT #f 0 XmOUTPUT_ALL))) (set! loop-between-marks-buffer-size (string->number size-as-string)))))) ;; this block creates a "radio button box" (let* ((s1 (XmStringCreateLocalized "Buffer size")) (frame (XtCreateManagedWidget "frame" xmFrameWidgetClass (XtParent (car sliders)) (list XmNborderWidth 1 XmNshadowType XmSHADOW_ETCHED_IN XmNpositionIndex 2))) (frm (XtCreateManagedWidget "frm" xmFormWidgetClass frame (list XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_FORM XmNbackground *basic-color*))) (rc (XtCreateManagedWidget "rc" xmRowColumnWidgetClass frm (list XmNorientation XmHORIZONTAL XmNradioBehavior #t XmNradioAlwaysOne #t XmNentryClass xmToggleButtonWidgetClass XmNisHomogeneous #t XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_NONE XmNbackground *basic-color*)))) (XtCreateManagedWidget "Buffer size" xmLabelWidgetClass frm (list XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_WIDGET XmNtopWidget rc XmNbottomAttachment XmATTACH_FORM XmNlabelString s1 XmNalignment XmALIGNMENT_BEGINNING XmNbackground *basic-color*)) (for-each (lambda (size) (let ((button (XtCreateManagedWidget (format #f "~D" size) xmToggleButtonWidgetClass rc (list XmNbackground *basic-color* XmNvalueChangedCallback (list (lambda (w c i) (if (.set i) (set! loop-between-marks-buffer-size c))) size) XmNset (= size loop-between-marks-buffer-size))))) (if (= size loop-between-marks-buffer-size) (set! loop-between-marks-default-buffer-widget button)))) (list 64 128 256 512 1024 2048 4096)) (XmStringFree s1))))) (activate-dialog loop-between-marks-dialog)) (set! loop-between-marks-menu-label (add-to-menu marks-menu "Loop play between marks" post-loop-between-marks-dialog)) (set! marks-list (cons (lambda () (let ((new-label (format #f "Loop play between marks (~D ~D ~D)" loop-between-marks-m1 loop-between-marks-m2 loop-between-marks-buffer-size))) (if loop-between-marks-menu-label (change-label loop-between-marks-menu-label new-label)) (set! loop-between-marks-label new-label))) marks-list)))) (add-to-menu marks-menu #f #f) ;;; -------- trim from and back (goes by first or last mark) (define trim-front (let ((documentation "trim-front finds the first mark in each of the syncd channels and removes all samples before it")) (lambda () (let ((snc (sync))) (define (trim-front-one-channel snd chn) (if (< (length (marks snd chn)) 1) (status-report "trim-front needs a mark" snd) (delete-samples 0 (mark-sample (car (marks snd chn))) snd chn))) (if (> snc 0) (apply map (lambda (snd chn) (if (= (sync snd) snc) (trim-front-one-channel snd chn))) (all-chans)) (trim-front-one-channel (selected-sound) (selected-channel))))))) (add-to-menu marks-menu "Trim before mark" trim-front) (define trim-back (let ((documentation "trim-back finds the last mark in each of the syncd channels and removes all samples after it")) (lambda () (let ((snc (sync))) (define (trim-back-one-channel snd chn) (if (< (length (marks snd chn)) 1) (status-report "trim-back needs a mark" snd) (let ((endpt (mark-sample (car (reverse (marks snd chn)))))) (delete-samples (+ endpt 1) (- (framples snd chn) endpt))))) (if (> snc 0) (apply map (lambda (snd chn) (if (= (sync snd) snc) (trim-back-one-channel snd chn))) (all-chans)) (trim-back-one-channel (selected-sound) (selected-channel))))))) (add-to-menu marks-menu "Trim behind mark" trim-back) ;;; -------- crop (trims front and back) (define crop (let ((documentation "crop finds the first and last marks in each of the syncd channels and removes all samples outside them")) (lambda () (let ((snc (sync))) (define (crop-one-channel snd chn) (if (< (length (marks snd chn)) 2) (status-report "crop needs start and end marks" snd) (as-one-edit (lambda () (delete-samples 0 (mark-sample (car (marks snd chn))) snd chn) (let ((endpt (mark-sample (car (reverse (marks snd chn)))))) (delete-samples (+ endpt 1) (- (framples snd chn) endpt)))) "crop"))) (if (> snc 0) (apply map (lambda (snd chn) (if (= (sync snd) snc) (crop-one-channel snd chn))) (all-chans)) (crop-one-channel (selected-sound) (selected-channel))))))) (add-to-menu marks-menu "Crop around marks" crop) (add-to-menu marks-menu #f #f) ;;; -------- Fit selection to marks (define fit-to-mark-one 0) (define fit-to-mark-two 1) (define fit-to-mark-label "Fit selection to marks") (define fit-to-mark-dialog #f) (define fit-to-mark-menu-label #f) (define cp-fit-to-marks (let ((documentation "(cp-fit-to-marks) fits the selection between two marks (marks-menu)")) (lambda () (if (selection?) (fit-selection-between-marks (integer->mark fit-to-mark-one) (integer->mark fit-to-mark-two)) (define-selection-via-marks (integer->mark fit-to-mark-one) (integer->mark fit-to-mark-two)))))) (if (or (provided? 'xm) (provided? 'xg)) (begin (define (post-fit-to-mark-dialog) (if (not fit-to-mark-dialog) (let ((initial-fit-to-mark-one 0) (initial-fit-to-mark-two 1) (sliders ())) (set! fit-to-mark-dialog (make-effect-dialog fit-to-mark-label (if (provided? 'snd-gtk) (lambda (w context) (cp-fit-to-marks)) (lambda (w context info) (cp-fit-to-marks))) (if (provided? 'snd-gtk) (lambda (w context) (help-dialog "Fit selection to marks Help" "Fit-selection-between-marks tries to squeeze the current selection between two marks,\ using the granulate generator to fix up the selection duration (this still is not perfect). Move the sliders to set the mark numbers.")) (lambda (w context info) (help-dialog "Fit selection to marks Help" "Fit-selection-between-marks tries to squeeze the current selection between two marks,\ using the granulate generator to fix up the selection duration (this still is not perfect). Move the sliders to set the mark numbers."))) (if (provided? 'snd-gtk) (lambda (w data) (set! fit-to-mark-one initial-fit-to-mark-one) ((*gtk* 'gtk_adjustment_set_value) ((*gtk* 'GTK_ADJUSTMENT) (car sliders)) fit-to-mark-one) (set! fit-to-mark-two initial-fit-to-mark-two) ((*gtk* 'gtk_adjustment_set_value) ((*gtk* 'GTK_ADJUSTMENT) (cadr sliders)) fit-to-mark-two) ) (lambda (w c i) (set! fit-to-mark-one initial-fit-to-mark-one) ((*motif* 'XtSetValues) (sliders 0) (list (*motif* 'XmNvalue) fit-to-mark-one)) (set! fit-to-mark-two initial-fit-to-mark-two) ((*motif* 'XtSetValues) (sliders 1) (list (*motif* 'XmNvalue) fit-to-mark-two)))))) (set! sliders (add-sliders fit-to-mark-dialog (list (list "mark one" 0 initial-fit-to-mark-one 20 (if (provided? 'snd-gtk) (lambda (w context) (set! fit-to-mark-one ((*gtk* 'gtk_adjustment_get_value) ((*gtk* 'GTK_ADJUSTMENT) w)))) (lambda (w context info) (set! fit-to-mark-one ((*motif* '.value) info)))) 1) (list "mark two" 0 initial-fit-to-mark-two 20 (if (provided? 'snd-gtk) (lambda (w context) (set! fit-to-mark-two ((*gtk* 'gtk_adjustment_get_value) ((*gtk* 'GTK_ADJUSTMENT) w)))) (lambda (w context info) (set! fit-to-mark-two (.value info)))) 1)))))) (activate-dialog fit-to-mark-dialog)) (set! fit-to-mark-menu-label (add-to-menu marks-menu "Fit selection to marks" post-fit-to-mark-dialog))) (set! fit-to-mark-menu-label (add-to-menu marks-menu fit-to-mark-label cp-fit-to-marks))) (set! marks-list (cons (lambda () (let ((new-label (format #f "Fit selection to marks (~D ~D)" fit-to-mark-one fit-to-mark-two))) (if fit-to-mark-menu-label (change-label fit-to-mark-menu-label new-label)) (set! fit-to-mark-label new-label))) marks-list)) ;;; -------- Define selection by marks (define define-by-mark-one 0) (define define-by-mark-two 1) (define define-by-mark-label "Define selection by marks") (define define-by-mark-dialog #f) (define define-by-mark-menu-label #f) (define define-selection-via-marks (let ((documentation "(define-selection-via-marks m1 m2) defines the selection via marks (marks-menu)")) (lambda (m1 m2) (let ((m1sc (mark-home m1)) (m2sc (mark-home m2))) (if (not (equal? m1sc m2sc)) (snd-error "define-selection-via-marks assumes the marks are in the same channel") (let ((beg (min (mark-sample m1) (mark-sample m2))) (end (max (mark-sample m1) (mark-sample m2))) (snd (car m1sc)) (chn (cadr m1sc))) (set! (selection-member? snd chn) #t) (set! (selection-position snd chn) beg) (set! (selection-framples snd chn) (+ 1 (- end beg))))))))) (define (cp-define-by-marks) (define-selection-via-marks (integer->mark define-by-mark-one) (integer->mark define-by-mark-two))) (if (or (provided? 'xm) (provided? 'xg)) (begin (define (post-define-by-mark-dialog) (if (not define-by-mark-dialog) (let ((initial-define-by-mark-one 0) (initial-define-by-mark-two 1) (sliders ())) (set! define-by-mark-dialog (make-effect-dialog define-by-mark-label (if (provided? 'snd-gtk) (lambda (w context) (cp-define-by-marks)) (lambda (w context info) (cp-define-by-marks))) (if (provided? 'snd-gtk) (lambda (w context) (help-dialog "Define selection by marks Help" "Selects and highlights area between marks. Use the sliders to choose the boundary marks.")) (lambda (w context info) (help-dialog "Define selection by marks Help" "Selects and highlights area between marks. Use the sliders to choose the boundary marks."))) (if (provided? 'snd-gtk) (lambda (w data) (set! define-by-mark-one initial-define-by-mark-one) ((*gtk* 'gtk_adjustment_set_value) ((*gtk* 'GTK_ADJUSTMENT) (car sliders)) define-by-mark-one) (set! define-by-mark-two initial-define-by-mark-two) ((*gtk* 'gtk_adjustment_set_value) ((*gtk* 'GTK_ADJUSTMENT) (cadr sliders)) define-by-mark-two) ) (lambda (w c i) (set! define-by-mark-one initial-define-by-mark-one) ((*motif* 'XtSetValues) (sliders 0) (list (*motif* 'XmNvalue) define-by-mark-one)) (set! define-by-mark-two initial-define-by-mark-two) ((*motif* 'XtSetValues) (sliders 1) (list (*motif* 'XmNvalue) define-by-mark-two)))))) (set! sliders (add-sliders define-by-mark-dialog (list (list "mark one" 0 initial-define-by-mark-one 25 (if (provided? 'snd-gtk) (lambda (w context) (set! define-by-mark-one ((*gtk* 'gtk_adjustment_get_value) ((*gtk* 'GTK_ADJUSTMENT) w)))) (lambda (w context info) (set! define-by-mark-one ((*motif* '.value) info)))) 1) (list "mark two" 0 initial-define-by-mark-two 25 (if (provided? 'snd-gtk) (lambda (w context) (set! define-by-mark-two ((*gtk* 'gtk_adjustment_get_value) ((*gtk* 'GTK_ADJUSTMENT) w)))) (lambda (w context info) (set! define-by-mark-two ((*motif* '.value) info)))) 1)))))) (activate-dialog define-by-mark-dialog)) (set! define-by-mark-menu-label (add-to-menu marks-menu "Define selection by marks" post-define-by-mark-dialog))) (set! define-by-mark-menu-label (add-to-menu marks-menu define-by-mark-label cp-define-by-marks))) (set! marks-list (cons (lambda () (let ((new-label (format #f "Define selection by marks (~D ~D)" define-by-mark-one define-by-mark-two))) (if define-by-mark-menu-label (change-label define-by-mark-menu-label new-label)) (set! define-by-mark-label new-label))) marks-list)) (add-to-menu marks-menu #f #f) ;;; ------- Start/stop mark sync (define mark-sync-menu-label #f) (define mark-sync-number 0) (define start-sync (let ((documentation "(start-sync) starts mark syncing (marks-menu)")) (lambda () (set! mark-sync-number (+ (mark-sync-max) 1))))) (define stop-sync (let ((documentation "(stop-sync) stops mark-syncing (marks-menu)")) (lambda () (set! mark-sync-number 0)))) (define click-to-sync (let ((documentation "(click-to-sync id) sets a mark's sync field when it is clicked (marks-menu)")) (lambda (id) (set! (sync id) mark-sync-number) #f))) (hook-push mark-click-hook (lambda (hook) (click-to-sync (hook 'id)))) (define m-sync #f) (define m-sync-label "Mark sync (On)") (define no-m-sync-label "Mark sync (Off)") (define msync! (let ((documentation "(msync!) starts mark syncing (marks-menu)")) (lambda () (set! m-sync #t) (if mark-sync-menu-label (change-label mark-sync-menu-label m-sync-label)) (start-sync) (mark-sync-color "yellow")))) (define unmsync! (let ((documentation "(unmsync!) stops mark syncing (marks-menu)")) (lambda () (set! m-sync #f) (if mark-sync-menu-label (change-label mark-sync-menu-label no-m-sync-label)) (stop-sync)))) (set! mark-sync-menu-label (add-to-menu marks-menu no-m-sync-label (lambda () (if m-sync (unmsync!) (msync!))))) (add-to-menu marks-menu #f #f) ;;; -------- Places marks at loop points specified in the file header (add-to-menu marks-menu "Mark sample loop points" mark-loops) ;;; -------- mark loop dialog (this refers to sound header mark points, not Snd mark objects!) (if (provided? 'xm) (with-let (sublet *motif*) ;; Here is a first stab at the loop dialog (I guessed a lot as to what these buttons ;; are supposed to do -- have never used these loop points). (define loop-dialog #f) (define loop-data '(0 0 0 0 0 0 1 1)) (define (update-labels start range end sus-rel range-in-secs) (if range-in-secs (begin (change-label start (format #f "~,3F" (/ (loop-data (* sus-rel 2)) (srate)))) (change-label range (format #f "~,3F" (/ (- (loop-data (+ 1 (* sus-rel 2))) (loop-data (* sus-rel 2))) (srate)))) (change-label end (format #f "~,3F" (/ (loop-data (+ 1 (* sus-rel 2))) (srate))))) (begin (change-label start (format #f "~D" (loop-data (* sus-rel 2)))) (change-label range (format #f "~D" (- (loop-data (+ 1 (* sus-rel 2))) (loop-data (* sus-rel 2))))) (change-label end (format #f "~D" (loop-data (+ 1 (* sus-rel 2)))))))) (define (create-loop-dialog) (if (not (Widget? loop-dialog)) (let ((xdismiss (XmStringCreate "Go Away" XmFONTLIST_DEFAULT_TAG)) (xsave (XmStringCreate "Save" XmFONTLIST_DEFAULT_TAG)) (xhelp (XmStringCreate "Help" XmFONTLIST_DEFAULT_TAG)) (titlestr (XmStringCreate "Loop Points" XmFONTLIST_DEFAULT_TAG))) (set! loop-dialog (XmCreateTemplateDialog (cadr (main-widgets)) "loop-points" (list XmNcancelLabelString xdismiss XmNhelpLabelString xhelp XmNokLabelString xsave XmNautoUnmanage #f XmNdialogTitle titlestr XmNresizePolicy XmRESIZE_GROW XmNnoResize #f XmNbackground *basic-color* XmNtransient #f))) (XtAddCallback loop-dialog XmNcancelCallback (lambda (w context info) (XtUnmanageChild loop-dialog))) (XtAddCallback loop-dialog XmNhelpCallback (lambda (w context info) (snd-print "set loop points"))) (XtAddCallback loop-dialog XmNokCallback (lambda (w context info) (set! (sound-loop-info) loop-data))) (XmStringFree xhelp) (XmStringFree xdismiss) (XmStringFree titlestr) (XmStringFree xsave) (let* ((mainform (XtCreateManagedWidget "form" xmFormWidgetClass loop-dialog (list XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_WIDGET XmNbottomWidget (XmMessageBoxGetChild loop-dialog XmDIALOG_SEPARATOR) XmNbackground *basic-color*))) (leftform (XtCreateManagedWidget "lform" xmFormWidgetClass mainform (list XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_POSITION XmNrightPosition 50 XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_FORM XmNbackground *basic-color*))) (rightform (XtCreateManagedWidget "rform" xmFormWidgetClass mainform (list XmNleftAttachment XmATTACH_WIDGET XmNleftWidget leftform XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_FORM XmNbackground *basic-color*)))) (for-each (lambda (parent top-label offset) (let* ((main-label (XtCreateManagedWidget top-label xmLabelWidgetClass parent (list XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_NONE))) (main-frame (XtCreateManagedWidget "fr" xmFrameWidgetClass parent (list XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_WIDGET XmNtopWidget main-label XmNbottomAttachment XmATTACH_FORM XmNshadowThickness 6 XmNshadowType XmSHADOW_ETCHED_OUT))) (frame-form (XtCreateManagedWidget "fform" xmFormWidgetClass main-frame ())) (top-frame (XtCreateManagedWidget "topf" xmFrameWidgetClass frame-form (list XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_NONE))) (top-form (XtCreateManagedWidget "tform" xmFormWidgetClass top-frame ())) (left-column (XtCreateManagedWidget "lcol" xmRowColumnWidgetClass top-form (list XmNorientation XmVERTICAL XmNbackground *position-color* XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_POSITION XmNrightPosition 40 XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_FORM))) (mid-column (XtCreateManagedWidget "lcol" xmFormWidgetClass top-form (list XmNleftAttachment XmATTACH_WIDGET XmNleftWidget left-column XmNrightAttachment XmATTACH_POSITION XmNrightPosition 60 XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_FORM))) (right-column (XtCreateManagedWidget "lcol" xmRowColumnWidgetClass top-form (list XmNorientation XmVERTICAL XmNbackground *position-color* XmNleftAttachment XmATTACH_WIDGET XmNleftWidget mid-column XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_FORM))) (rowlefttop (XtCreateManagedWidget "r1" xmRowColumnWidgetClass left-column (list XmNorientation XmHORIZONTAL XmNbackground *position-color* XmNspacing 0))) (leftrange (XtCreateManagedWidget "range" xmPushButtonWidgetClass left-column ())) (rowleftbottom (XtCreateManagedWidget "r1" xmRowColumnWidgetClass left-column (list XmNorientation XmHORIZONTAL XmNbackground *position-color* XmNspacing 0))) (rowrighttop (XtCreateManagedWidget "r1" xmRowColumnWidgetClass right-column (list XmNorientation XmHORIZONTAL XmNbackground *position-color* XmNspacing 0))) (rowrightmid (XtCreateManagedWidget "r1" xmRowColumnWidgetClass right-column (list XmNorientation XmHORIZONTAL XmNbackground *position-color*))) (rightsep (XtCreateManagedWidget "rsep" xmSeparatorWidgetClass rowrightmid (list XmNseparatorType XmNO_LINE XmNorientation XmVERTICAL XmNbackground *position-color* XmNwidth 20))) (rightlock (XtCreateManagedWidget "lock" xmToggleButtonWidgetClass rowrightmid ())) (rowrightbottom (XtCreateManagedWidget "r1" xmRowColumnWidgetClass right-column (list XmNorientation XmHORIZONTAL XmNbackground *position-color* XmNspacing 0))) (midlab1 (XtCreateManagedWidget "0.000" xmLabelWidgetClass mid-column (list XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_POSITION XmNtopPosition 10 XmNbottomAttachment XmATTACH_NONE))) (midlab2 (XtCreateManagedWidget "0.000" xmLabelWidgetClass mid-column (list XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_POSITION XmNtopPosition 40 XmNbottomAttachment XmATTACH_NONE))) (midlab3 (XtCreateManagedWidget "0.000" xmLabelWidgetClass mid-column (list XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_NONE XmNbottomAttachment XmATTACH_POSITION XmNbottomPosition 90))) (bottom-form (XtCreateManagedWidget "bform" xmFormWidgetClass frame-form (list XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_WIDGET XmNtopWidget top-frame XmNbottomAttachment XmATTACH_FORM))) (bottom-left (XtCreateManagedWidget "bleft" xmFormWidgetClass bottom-form (list XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_NONE XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_FORM))) (bottom-right (XtCreateManagedWidget "bright" xmFrameWidgetClass bottom-form (list XmNleftAttachment XmATTACH_WIDGET XmNleftWidget bottom-left XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_FORM))) (bottom-left-label (XtCreateManagedWidget "Loop Mode" xmLabelWidgetClass bottom-left (list XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_NONE))) (bottom-left-button (XtCreateManagedWidget "forwards" xmPushButtonWidgetClass bottom-left (list XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_WIDGET XmNtopWidget bottom-left-label XmNbottomAttachment XmATTACH_FORM))) (range-in-secs #t)) (let ((mode 1)) (XtAddCallback bottom-left-button XmNactivateCallback (lambda (w context info) (if (= mode 1) (set! mode 2) (set! mode 1)) (set! (loop-data (+ offset 6)) mode) (change-label w (if (= mode 1) "forward" "forw/back"))))) (XtAddCallback leftrange XmNactivateCallback (lambda (w c i) (set! range-in-secs (not range-in-secs)) (update-labels midlab1 midlab2 midlab3 offset range-in-secs))) (for-each (lambda (rparent loc) (let ((farleft (XtCreateManagedWidget "<<" xmPushButtonWidgetClass rparent ())) (stopleft (XtCreateManagedWidget " O " xmPushButtonWidgetClass rparent ())) (lotsleft (XtCreateManagedWidget "<< " xmPushButtonWidgetClass rparent ())) (someleft (XtCreateManagedWidget " < " xmPushButtonWidgetClass rparent ())) (sus-rel-start (* offset 2))) (XtAddCallback farleft XmNactivateCallback (lambda (w c i) (let ((ml (if (= loc 0) 0 (loop-data sus-rel-start)))) (set! (loop-data (+ loc (* offset 2))) ml) (update-labels midlab1 midlab2 midlab3 offset range-in-secs)))) (XtAddCallback stopleft XmNactivateCallback (lambda (w c i) (let ((ml (if (= loc 0) 0 (loop-data sus-rel-start)))) (set! (loop-data (+ loc (* offset 2))) ml) (update-labels midlab1 midlab2 midlab3 offset range-in-secs)))) (XtAddCallback lotsleft XmNactivateCallback (lambda (w c i) (let ((ml (if (= loc 0) 0 (loop-data sus-rel-start)))) (set! (loop-data (+ loc (* offset 2))) (max ml (- (loop-data (+ loc (* offset 2))) 10))) (update-labels midlab1 midlab2 midlab3 offset range-in-secs)))) (XtAddCallback someleft XmNactivateCallback (lambda (w c i) (let ((ml (if (= loc 0) 0 (loop-data sus-rel-start)))) (set! (loop-data (+ loc (* offset 2))) (max ml (- (loop-data (+ loc (* offset 2))) 1))) (update-labels midlab1 midlab2 midlab3 offset range-in-secs)))))) (list rowlefttop rowleftbottom) (list 0 1)) (for-each (lambda (rparent loc) (let ((someright (XtCreateManagedWidget " > " xmPushButtonWidgetClass rparent ())) (lotsright (XtCreateManagedWidget " >>" xmPushButtonWidgetClass rparent ())) (stopright (XtCreateManagedWidget " O " xmPushButtonWidgetClass rparent ())) (farright (XtCreateManagedWidget ">>" xmPushButtonWidgetClass rparent ())) (sus-rel-start (* offset 2))) (XtAddCallback farright XmNactivateCallback (lambda (w c i) (let ((ml (if (= loc 0) (loop-data (+ sus-rel-start 1)) (framples)))) (set! (loop-data (+ loc (* offset 2))) ml) (update-labels midlab1 midlab2 midlab3 offset range-in-secs)))) (XtAddCallback stopright XmNactivateCallback (lambda (w c i) (let ((ml (if (= loc 0) (loop-data (+ sus-rel-start 1)) (framples)))) (set! (loop-data (+ loc (* offset 2))) ml) (update-labels midlab1 midlab2 midlab3 offset range-in-secs)))) (XtAddCallback lotsright XmNactivateCallback (lambda (w c i) (let ((ml (if (= loc 0) (loop-data (+ sus-rel-start 1)) (framples)))) (set! (loop-data (+ loc (* offset 2))) (min ml (+ (loop-data (+ loc (* offset 2))) 10))) (update-labels midlab1 midlab2 midlab3 offset range-in-secs)))) (XtAddCallback someright XmNactivateCallback (lambda (w c i) (let ((ml (if (= loc 0) (loop-data (+ sus-rel-start 1)) (framples)))) (set! (loop-data (+ loc (* offset 2))) (min ml (+ (loop-data (+ loc (* offset 2))) 1))) (update-labels midlab1 midlab2 midlab3 offset range-in-secs)))))) (list rowrighttop rowrightbottom) (list 0 1)))) (list leftform rightform) (list "Sustain" "Release") (list 0 1))) (for-each-child loop-dialog (lambda (n) (if (and (XtIsWidget n) (not (XmIsRowColumn n)) (not (XmIsSeparator n))) (begin (XmChangeColor n *basic-color*) (if (XmIsToggleButton n) (XtVaSetValues n (list XmNselectColor (let* ((col (XColor)) (dpy (XtDisplay (cadr (main-widgets)))) (scr (DefaultScreen dpy)) (cmap (DefaultColormap dpy scr))) (XAllocNamedColor dpy cmap "yellow" col col) (.pixel col))))))))) )) (XtManageChild loop-dialog)) (add-to-menu marks-menu "Show loop editor" create-loop-dialog) )) (add-to-menu marks-menu #f #f) ;;; -------- Delete all marks (add-to-menu marks-menu "Delete all marks" delete-marks) (add-to-menu marks-menu #f #f) ;;; -------- Explode all marks to separate files (define mark-explode (let ((documentation "(mark-explode) produces separate files as delineated by successive marks (marks-menu)")) (lambda () (let ((start 0)) (for-each (lambda (mark) (let ((len (- (mark-sample mark) start)) (filename (snd-tempnam))) (array->file filename (channel->float-vector start len) len (srate) 1) (set! start (mark-sample mark)))) (caar (marks))))))) (add-to-menu marks-menu "Explode marks to files" mark-explode) snd-16.1/stochastic.scm0000644000076400007640000000743412350136561013215 0ustar bilbil;; CLM implementation of Xenakis' Dynamic Stochastic Synthesis as heard in ;; his GENDY3, S.709, Legende d'Eer, etc. ;; 12/17/03 ;; revised 01/22/06 ;; Bill Sack wsack@buffalo.edu ;; revised slightly to accommodate the run macro, Bill 13-Jun-06 (if (provided? 'snd) (require snd-ws.scm) (require sndlib-ws.scm)) (require snd-env.scm) (definstrument (stochastic start dur (amp .9) (bits 16) (xmin 1) (xmax 20) (xwig 0) (xstep 1) (ywig 0) (xfb 0) (init-array '((10 0) (10 1) (10 0) (10 -.7) (10 0) (10 .5) (10 0) (10 -.3) (10 0) (10 .2) (10 0) (10 -.1)))) ;;some explanation of the parameters: ;;amp - scales overall amplitude ;;bits - the resolution of the wave's amplitude dimension ;;xmin - minimum number of samples between time breakpoints. must be equal to or greater than 1 ;;xmax - maximum number of samples between time breakpoints. ;;xwig - amplitude applied to random walk function in time dimension ;;xstep - quantization of freedom in time dimension, in samples. minimum of 1 ;;ywig - amplitude applied to random walk function in amplitude dimension, in ;; percent of overall possible amplitude ;;xfb - an attempt at an FIR low-pass filter - the old (n + (x * n-1)) trick, ;; not really that useful ;;init-array - initial x and y breakpoints for wave. x values must be ;; integers and 1 or greater, y values between -1.0 and 1.0 (let* ((y 0.0) (dx 0) (prev-dx 0) (dy 0.0) (j 0.0) (m 0) (dt 0) (output 0.0) (oldy 0.0) (xdev 0) (ydev 0) (beg (seconds->samples start)) (end (+ beg (seconds->samples dur))) (d-click (make-env (list 0 1 (- end 100) 1 end 0) :duration dur)) (b (expt 2 (- bits 1))); because we use signed ints - see (- b) below ;;make float-vector to hold x,y breakpoints (xy-array (make-float-vector (* (length init-array) 2))) (xy-array-l (floor (length xy-array))) ) ;;fill xy-array with values from init-array (do ((iy 0 (+ iy 2));;index for reading values from init-array (a 2-dimensional list) (jy 0 (+ jy 1)));;index for writing to xy-array (a 1-dimensional float-vector) ((= iy xy-array-l) xy-array) (set! (xy-array iy) ((init-array jy) 0)) (set! (xy-array (+ iy 1)) ;;convert signed float y values into signed integers (floor (* b ((init-array jy) 1))))) (do ((i beg (+ i 1))) ((= i end)) (if (= dx dt);;when current sample is a breakpoint (begin (set! dx (floor (xy-array (modulo m xy-array-l)))) (set! y (xy-array (+ (modulo m xy-array-l) 1))) (set! prev-dx (floor (xy-array (modulo (- m 2) xy-array-l)))) (set! dy (- y oldy)) (set! oldy y) ;;straight uniform distribution for y (set! ydev (round (mus-random (* .01 b ywig)))) ;;gaussian distribution for x (set! xdev (* xstep (round (* xwig (sqrt (* -2.0 (log (- 1 (random 1.0))))) ; ?? (cos (random 6.283185307179586)))))) (set! (xy-array (modulo m xy-array-l)) ;;mirror stuff for x (cond ((or (< (round xmax) (+ dx xdev)) (> (round xmin)(+ dx xdev))) (max (min ;;this mirror is attentuated (round (+ (* xfb prev-dx) (* (- 1 xfb) (+ dx (- xdev))))) (round xmax)) (round xmin))) (else (round (+ (* xfb prev-dx) (* (- 1 xfb) (+ dx xdev))))))) (set! (xy-array (+ (modulo m xy-array-l) 1)) ;;mirror stuff for y (cond ((or (< b (+ y ydev)) (> (- b) (+ y ydev))) (max (min (+ y (- ydev)) b) (- b))) (else (+ y ydev)))) (set! m (+ m 2)) (set! dt 0))) (set! dt (+ dt 1)) (set! j (+ j (/ dy dx)));linear interpolation (set! output (/ j b));normalization -1 to 1 (outa i (* amp output (env d-click)))))) ;(with-sound (:statistics #t)(stochastic 0 10 :xwig .25 :ywig 10.0)) snd-16.1/xen.h0000644000076400007640000025353312571434530011315 0ustar bilbil#ifndef XEN_H #define XEN_H /* macros for extension language support * * Ruby: covers 1.8.0 to present * Forth: covers 1.0 to present * s7: all versions * None: all versions */ #define XEN_MAJOR_VERSION 3 #define XEN_MINOR_VERSION 25 #define XEN_VERSION "3.25" /* HISTORY: * * 20-Aug-15: Xen_define_typed_procedure, Xen_define_typed_dilambda. * -------- * 27-Dec: Xen_arity in s7 now uses s7_arity. Xen_define_integer_procedure, Xen_define_dilambda. * 21-Feb: Xen_is_number and friends. * 7-Jan-14: in s7, C_TO_XEN_STRING and XEN_TO_C_STRING now treat a null string as a string (not #f). * -------- * 9-Nov: removed XEN_DEFINE_PROCEDURE_WITH_REVERSED_SETTER. * 11-Oct: removed XEN_EXACT_P. * 23-Sep: removed *_OR_ELSE, XEN_ARG_*, and OFF_T* macros; added XEN_ARGIFY* to the Forth section. * 7-Jul-13: removed int64 stuff (it was not used anywhere). Made various Ruby changes (NUM2ULL etc). * -------- * 5-Nov: minor s7-related changes. * 9-July: XEN_VECTOR_ELEMENTS and XEN_VECTOR_COPY. * 4-June: XEN_PROVIDE * 8-May: added description arg to XEN_DEFINE_SIMPLE_HOOK and XEN_DEFINE_HOOK, only used in scheme. * 12-Jan-12: added reverse argument to s7 version of XEN_MAKE_OBJECT_TYPE. * -------- * 20-Oct: XEN_LONG_LONG_P. * 5-Jun-11: XEN_DEFINE_SAFE_PROCEDURE, an experiment with s7. * -------- * 25-Nov: updates for Ruby 1.9.*. * 7-Nov: XEN_ADD_HOOK. * 23-Oct: use s7_call_with_location, rather than s7_call, for better error reporting. * 19-Mar: removed s7_define_set_function (removed encapsulation from s7, so it's not useful anymore). * 17-Feb: various s7 changes. * 5-Feb-10: XEN_ASSOC_REF and XEN_ASSOC_SET. XEN_ASSOC_REF returns the value, not the key/value pair. * -------- * 16-Dec: removed Guile support. removed xen_return_first (a guile-ism). * 2-Nov: XEN_VECTOR_RANK. * 5-Oct: use s7_c_pointer etc. * 7-Aug: use s7_new_type_x in XEN_MAKE_OBJECT_TYPE. XEN_DEFINE_SET_PROCEDURE. * 27-Jul: INT64_T cases paralleling OFF_T (the latter may go away someday). * 14-Jul: s7_define_function_star via XEN_DEFINE_PROCEDURE_STAR. * 6-Jul: cleaned up XEN_WRAP_C_POINTER et al (Mike Scholz). * 29-Jun: some fth changes. * 30-Mar: added a bunch of file-oriented functions for s7 (xen.c). * 14-Mar: removed XEN_LOCAL_GC_PROTECT and XEN_LOCAL_GC_UNPROTECT. * 14-Jan-09: s7_xen_initialize. * -------- * 17-Nov: use s7_define_constant in XEN_DEFINE_CONSTANT. * 1-Nov: changed s7 and Guile C_TO_XEN_STRING slightly. * 16-Oct: removed Gauche support. * 10-Aug: S7, a TinyScheme derivative. * changed XEN_NUMERATOR and XEN_DENOMINATOR to return off_t not XEN. * 23-Jul: be more careful about wrapping POINTERs (they say 64-bit MS C void* == unsigned long long, but not unsigned long). * 30-Jun: XEN_OFF_T_IF_BOUND_P. * 19-May: more const char* arg declarations. * 14-May: changed XEN_ARITY in Guile to use scm_procedure_property. * 1-May: XEN_NAN_P and XEN_INF_P (Guile). * 23-Apr: try to get old Gauche (8.7) to work again. * 1-Mar-08: no ext case now checks arg consistency. * -------- * 12-Dec: Gauche uses COMPNUM, not COMPLEX (after 0.8.7?), NUMBERP for complex? * 21-Nov: XEN_HAVE_COMPLEX_NUMBERS. * 18-Jul: Gauche error handling changes. * 28-Apr: Gauche API changes in versions 0.8.8, 0.8.10, and 0.9. * 14-Feb: XEN_PUTS and friends for fth (Mike). * 17-Jan-07: rb_errinfo changes (Mike Scholz). * -------- * 14-Nov: check for Scm_EvalRec (Gauche 0.8.8). * 9-Sep: XEN_LOAD_PATH and XEN_ADD_TO_LOAD_PATH * 1-Sep: string and array changes for Ruby (from Mike). * 7-Aug: more careful list length handling in Ruby (from Mike). * 23-May: added xen_rb_repl_set_prompt to set (no-gui) Ruby repl prompt. * 12-May: changed HAVE_RATIOS to XEN_HAVE_RATIOS. * 17-Apr: removed XEN_MAKE_OBJECT. * 15-Apr: Gauche support. * 28-Mar-06: Forth support thanks to Mike Scholz. * -------- * 7-Nov: xen_rb_defined_p (Mike Scholz). * 16-Sep: removed some debugging extras that caused confusion on 64-bit machines. * 12-Aug: include guile setter procedure names for better error reporting. * 14-Jun: XEN_DEFINE (XEN value, not assumed to be int as in XEN_DEFINE_CONSTANT). * XEN_ASSOC, XEN_MEMBER, and XEN_PROCEDURE_NAME for Scheme side. * XEN_DEFINE_HOOK and XEN_DEFINE_SIMPLE_HOOK no longer take the "Var" arg. * 18-May: deprecate XEN_NUMBER_OR_BOOLEAN_IF_BOUND_P and XEN_NUMBER_OR_BOOLEAN_P. * 29-Mar: C_TO_XEN_STRINGN changes. * 24-Mar: Ruby properties (Mike Scholz). * 8-Mar: Ruby improvements in keywords and hooks (Mike Scholz). * 7-Mar: C99 complex number changes (creal, _Complex_I) (Steve Bankowitz). * 2-Mar: Ruby support for off_t (Mike Scholz). * 4-Jan-05: more guile changes. * -------- * 31-Dec: removed "caller" arg from *_NO_CATCH. * 10-Nov: scm_c_vector* (new Guile functions) * 21-Oct: XEN_LIST_REVERSE, (using rb_ary_dup available in 1.8) * 7-Oct: keyword changes for new Guile. * 28-Sep: deprecated *_WITH_CALLER -- these no longer do anything useful in Guile. * NaNs and Infs -> 0 or 0.0 in XEN_TO_C_INT|DOUBLE -- perhaps I should add another set of macros? * 23-Aug: more Guile name changes. * 12-Aug: more Guile name changes, C_TO_XEN_STRINGN (Guile) * 3-Aug: xen_to_c_int bugfix thanks to Kjetil S. Matheussen. * 29-Jul: deprecated XEN_TO_C_BOOLEAN_OR_TRUE. * 21-Jul: deprecated XEN_TO_SMALL_C_INT and C_TO_SMALL_XEN_INT. * use new Guile 1.7 numerical function names (under flag HAVE_SCM_TO_SIGNED_INTEGER). * 28-Jun: XEN_REQUIRED_ARGS_OK to make it easier to turn off this check. * 9-June: complex number conversions (Guile) -- Ruby complex numbers are an optional module? * 21-May: plug some memory leaks in Ruby cases. * 23-Feb: changed DEBUGGING to XEN_DEBUGGING, added redefinition checks under that switch. * 2-Feb: C_TO_XEN_CHAR, ratio support (Guile), XEN_CONS_P, XEN_PAIR_P, etc * 6-Jan: XEN_VARIABLE_REF in Guile changed to support 1.4 and older versions. * 5-Jan-04: hook support in Ruby thanks to Michael Scholz. * -------- * 1-Nov: protect several macros from hidden double evaluations. * 29-Sep: fixed incorrect assumption in xen_rb_cons (xen.c) that arg2 was list. * 8-Sep: removed xen_malloc -- can't remember now why this existed. * 19-Aug: xen_rb_str_new2 to avoid unwanted side-effects. * 12-Aug: various changes for ISO C99. * 30-Jul: use new SCM_VECTOR_REF/SET macros if they're defined. * 7-Apr: changes to error handlers for more perspicuous error messages * changed XEN_PROTECT_FROM_GC in Ruby to use rb_gc_register_address, added XEN_UNPROTECT_FROM_GC (rb_gc_unregister_address) * 10-Mar: XEN_OUT_OF_RANGE_ERROR, XEN_BAD_ARITY_ERROR * 17-Feb: XEN_HOOK_P * 20-Jan-03: added Windows case for auto-import loader bugfix. * -------- * 19-Dec: proc arg checks for Ruby (to make sure XEN_[N|V]ARGIFY|DEFINE_PROCEDURE[etc] agree) * 29-Jul: SCM_WRITABLE_VELTS for current CVS Guile * 28-May: off_t equivalents in Ruby 1.7 * 6-May: off_t (long long) macros. * 2-Jan-02: removed TIMING and MCHECK debugging stuff, VARIABLE_REF -> XEN_VARIABLE_REF * -------- * 22-Sep-01: removed (redundant) UNSIGNED_LONG macros -- use ULONG instead */ #ifndef __cplusplus #include #ifndef _MSC_VER #include #else #ifndef true #define bool unsigned char #define true 1 #define false 0 #endif #endif #endif #if ((!__NetBSD__) && ((_MSC_VER) || (!defined(__STC__)) || (defined(__STDC_VERSION__) && (__STDC_VERSION__ < 199901L)))) #define __func__ __FUNCTION__ #endif /* ------------------------------ RUBY ------------------------------ */ /* other possibilities: * XEN_DEFINE_METHOD, XEN_DEFINE_ALIAS, rb_ary_unsift = XEN_LIST_PREPEND?, * various property macros -- in Scheme as well, rb_const_defined, rb_yield, XEN_INCLUDE_MODULE, * rb_id2name (XEN_SYMBOL...), rb_raise. */ #if HAVE_RUBY #ifdef _GNU_SOURCE #undef _GNU_SOURCE #endif #include #if defined(__GNUC__) && (!(defined(__cplusplus))) #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #endif #define XEN_OK 1 #define XEN VALUE #define XEN_FILE_EXTENSION "rb" #define XEN_COMMENT_STRING "#" #define XEN_LANGUAGE_NAME "Ruby" #define XEN_FALSE Qfalse #define XEN_TRUE Qtrue #define XEN_TRUE_P(a) ((a) == Qtrue) #define XEN_FALSE_P(a) ((a) == Qfalse) #define C_TO_XEN_BOOLEAN(a) ((a) ? Qtrue : Qfalse) #define XEN_TO_C_BOOLEAN(a) (!(XEN_FALSE_P(a))) /* #define XEN_UNDEFINED Qundef */ #define XEN_UNDEFINED ID2SYM(rb_intern("undefined")) #define XEN_BOUND_P(Arg) ((Arg) != XEN_UNDEFINED) #if defined(__GNUC__) && (!(defined(__cplusplus))) #define XEN_BOOLEAN_P(Arg) ({ XEN _xen_h_7_ = Arg; (XEN_TRUE_P(_xen_h_7_) || XEN_FALSE_P(_xen_h_7_)); }) #define XEN_NUMBER_P(Arg) ({ int _xen_h_8_ = TYPE(Arg); ((_xen_h_8_ == T_FLOAT) || (_xen_h_8_ == T_FIXNUM) || (_xen_h_8_ == T_BIGNUM)); }) #define XEN_INTEGER_P(Arg) ({ int _xen_h_9_ = TYPE(Arg); ((_xen_h_9_ == T_FIXNUM) || (_xen_h_9_ == T_BIGNUM)); }) #define XEN_PROCEDURE_P(Arg) ({ XEN _xen_h_10_ = Arg; (XEN_BOUND_P(_xen_h_10_) && (rb_obj_is_kind_of(_xen_h_10_, rb_cProc))); }) #define XEN_KEYWORD_P(Obj) ({ XEN _xen_h_12_ = Obj; (XEN_BOUND_P(_xen_h_12_) && SYMBOL_P(_xen_h_12_)); }) #else #define XEN_BOOLEAN_P(Arg) (XEN_TRUE_P(Arg) || XEN_FALSE_P(Arg)) #define XEN_NUMBER_P(Arg) ((TYPE(Arg) == T_FLOAT) || (TYPE(Arg) == T_FIXNUM) || (TYPE(Arg) == T_BIGNUM)) #define XEN_INTEGER_P(Arg) ((TYPE(Arg) == T_FIXNUM) || (TYPE(Arg) == T_BIGNUM)) #define XEN_PROCEDURE_P(Arg) (XEN_BOUND_P(Arg) && (rb_obj_is_kind_of(Arg, rb_cProc))) #define XEN_KEYWORD_P(Obj) (XEN_BOUND_P(Obj) && SYMBOL_P(Obj)) #endif /* ---- lists ---- */ #define XEN_EMPTY_LIST Qnil #define XEN_NULL_P(a) (XEN_LIST_LENGTH(a) == 0) #define XEN_CONS_P(Arg) (TYPE(Arg) == T_ARRAY) #define XEN_PAIR_P(Arg) (TYPE(Arg) == T_ARRAY) #define XEN_CONS(Arg1, Arg2) xen_rb_cons(Arg1, Arg2) #define XEN_CONS_2(Arg1, Arg2, Arg3) xen_rb_cons2(Arg1, Arg2, Arg3) #define XEN_CAR(a) xen_rb_list_ref(a, 0) #define XEN_CADR(a) xen_rb_list_ref(a, 1) #define XEN_CADDR(a) xen_rb_list_ref(a, 2) #define XEN_CADDDR(a) xen_rb_list_ref(a, 3) #define XEN_CDR(a) xen_rb_cdr(a) #define XEN_CDDR(a) XEN_CDR(XEN_CDR(a)) #define XEN_CDDDR(a) XEN_CDR(XEN_CDR(XEN_CDR(a))) #define XEN_LIST_P(Arg) ((Arg) == XEN_EMPTY_LIST || XEN_CONS_P(Arg)) #define XEN_LIST_P_WITH_LENGTH(Arg, Len) ((Len = XEN_LIST_LENGTH(Arg)) >= 0) #define XEN_LIST_LENGTH(Arg) xen_rb_list_length(Arg) #define XEN_EQ_P(a, b) ((a) == (b)) #define XEN_LIST_1(a) rb_ary_new3(1, a) #define XEN_LIST_2(a, b) rb_ary_new3(2, a, b) #define XEN_LIST_3(a, b, c) rb_ary_new3(3, a, b, c) #define XEN_LIST_4(a, b, c, d) rb_ary_new3(4, a, b, c, d) #define XEN_LIST_5(a, b, c, d, e) rb_ary_new3(5, a, b, c, d, e) #define XEN_LIST_6(a, b, c, d, e, f) rb_ary_new3(6, a, b, c, d, e, f) #define XEN_LIST_7(a, b, c, d, e, f, g) rb_ary_new3(7, a, b, c, d, e, f, g) #define XEN_LIST_8(a, b, c, d, e, f, g, h) rb_ary_new3(8, a, b, c, d, e, f, g, h) #define XEN_LIST_9(a, b, c, d, e, f, g, h, i) rb_ary_new3(9, a, b, c, d, e, f, g, h, i) #define XEN_COPY_ARG(Lst) xen_rb_copy_list(Lst) #define XEN_LIST_REF(Lst, Num) xen_rb_list_ref(Lst, Num) #define XEN_LIST_SET(Lst, Num, Val) xen_rb_list_set(Lst, Num, Val) #define XEN_APPEND(X, Y) rb_ary_concat(X, Y) #define XEN_LIST_REVERSE(Lst) ((Lst == XEN_EMPTY_LIST) ? XEN_EMPTY_LIST : rb_ary_reverse(XEN_COPY_ARG(Lst))) /* ---- numbers ---- */ #define XEN_ZERO INT2NUM(0) #define XEN_DOUBLE_P(Arg) XEN_NUMBER_P(Arg) #define XEN_TO_C_DOUBLE(a) NUM2DBL(a) #define C_TO_XEN_DOUBLE(a) rb_float_new(a) #define XEN_TO_C_INT(a) rb_num2long(a) /* apparently no complex numbers (built-in) in Ruby? */ #define XEN_COMPLEX_P(Arg) 1 #define C_TO_XEN_COMPLEX(a) XEN_ZERO #define XEN_TO_C_COMPLEX(a) 0.0 #define XEN_ULONG_P(Arg1) XEN_INTEGER_P(Arg1) #define XEN_WRAPPED_C_POINTER_P(Arg1) XEN_INTEGER_P(Arg1) #define C_TO_XEN_INT(a) INT2NUM(a) #define XEN_TO_C_ULONG(a) NUM2ULONG(a) #ifdef ULONG2NUM #define C_TO_XEN_ULONG(a) ULONG2NUM((unsigned long)a) #else #define C_TO_XEN_ULONG(a) UINT2NUM((unsigned long)a) #endif #ifdef NUM2ULL /* ruby 1.9.3 */ #define C_TO_XEN_LONG_LONG(a) LL2NUM(a) #define XEN_TO_C_LONG_LONG(a) NUM2LL(a) #define XEN_ULONG_LONG_P(Arg) XEN_INTEGER_P(Arg) #define XEN_TO_C_ULONG_LONG(Arg) NUM2ULL(Arg) /* NUM2ULONG(Arg) */ #define C_TO_XEN_ULONG_LONG(Arg) ULL2NUM(Arg) /* INT2NUM(Arg) */ #else /* older versions -- no dependable version number in ruby -- these macros may not work on a 64-bit machine */ #ifndef OFFT2NUM #define OFFT2NUM(a) INT2NUM(a) #endif #ifndef NUM2OFFT #define NUM2OFFT(a) NUM2LONG(a) #endif #define C_TO_XEN_LONG_LONG(a) OFFT2NUM(a) #define XEN_TO_C_LONG_LONG(a) NUM2OFFT(a) #define XEN_ULONG_LONG_P(Arg) XEN_INTEGER_P(Arg) #define XEN_TO_C_ULONG_LONG(Arg) NUM2OFFT(Arg) #define C_TO_XEN_ULONG_LONG(Arg) OFFT2NUM(Arg) #endif /* ---- strings ---- */ #define XEN_STRING_P(Arg) ((TYPE(Arg) == T_STRING) && (!SYMBOL_P(Arg))) #define C_TO_XEN_STRING(a) xen_rb_str_new2((char *)a) #define C_TO_XEN_STRINGN(a, len) rb_str_new((char *)a, len) #ifndef RSTRING_PTR #define XEN_TO_C_STRING(Str) RSTRING(Str)->ptr #else #define XEN_TO_C_STRING(Str) RSTRING_PTR(Str) #endif #define XEN_CHAR_P(Arg) XEN_STRING_P(Arg) #define XEN_TO_C_CHAR(Arg) XEN_TO_C_STRING(Arg)[0] #define C_TO_XEN_CHAR(Arg) rb_str_new((char *)(&(Arg)), 1) #define XEN_NAME_AS_C_STRING_TO_VALUE(a) xen_rb_gv_get(a) #define XEN_EVAL_C_STRING(Arg) xen_rb_eval_string_with_error(Arg) #define XEN_TO_STRING(Obj) xen_rb_obj_as_string(Obj) #define XEN_LOAD_FILE(a) xen_rb_load_file_with_error(C_TO_XEN_STRING(a)) #define XEN_LOAD_PATH XEN_NAME_AS_C_STRING_TO_VALUE("$LOAD_PATH") #define XEN_ADD_TO_LOAD_PATH(Path) xen_rb_add_to_load_path(Path) /* ---- hooks ---- */ #define XEN_HOOK_P(Arg) xen_rb_hook_p(Arg) #define XEN_HOOK_PROCEDURES(a) xen_rb_hook_to_a(a) #define XEN_CLEAR_HOOK(a) xen_rb_hook_reset_hook(a) #define XEN_HOOKED(a) (!xen_rb_hook_empty_p(a)) #define XEN_DEFINE_HOOK(Name, Descr, Arity, Help) xen_rb_create_hook((char *)(Name), Arity, (char *)Help) #define XEN_DEFINE_SIMPLE_HOOK(Descr, Arity) xen_rb_create_simple_hook(Arity); #define XEN_ADD_HOOK(Hook, Func, Name, Doc) xen_rb_add_hook(Hook, (XEN (*)())Func, Name, Doc) /* ---- vectors ---- */ #define XEN_VECTOR_P(Arg) (TYPE(Arg) == T_ARRAY) #define XEN_VECTOR_LENGTH(Arg) xen_rb_list_length(Arg) #define XEN_VECTOR_REF(Vect, Num) xen_rb_list_ref(Vect, Num) #define XEN_VECTOR_SET(Vect, Num, Val) xen_rb_list_set(Vect, Num, Val) #define XEN_MAKE_VECTOR(Num, Fill) xen_rb_ary_new_with_initial_element(Num, Fill) #define XEN_VECTOR_TO_LIST(a) a #define XEN_VECTOR_COPY(Vect) rb_ary_dup(Vect) #define XEN_ASSOC_REF(Item, Lst) xen_assoc(Item, Lst) #define XEN_ASSOC_SET(Sym, Val, Lst) xen_set_assoc(Sym, Val, Lst) /* ---- symbols ---- */ #define XEN_SYMBOL_P(Arg) SYMBOL_P(Arg) #define XEN_SYMBOL_TO_C_STRING(a) ((char *)rb_id2name(SYM2ID(a))) #define C_STRING_TO_XEN_SYMBOL(a) ID2SYM(rb_intern(a)) #define XEN_SYMBOL_TO_STRING(Sym) C_TO_XEN_STRING(XEN_SYMBOL_TO_C_STRING(Sym)) #define XEN_DOCUMENTATION_SYMBOL C_STRING_TO_XEN_SYMBOL("documentation") #define XEN_OBJECT_HELP(Name) rb_documentation(Name) #define XEN_SET_OBJECT_HELP(Name, Help) rb_set_documentation(Name, Help) #define C_SET_OBJECT_HELP(name, help) XEN_SET_OBJECT_HELP(C_TO_XEN_STRING(name), C_TO_XEN_STRING(help)) #define XEN_VARIABLE_SET(a, b) xen_rb_gv_set(a, b) #define XEN_VARIABLE_REF(a) xen_rb_gv_get(a) #define XEN_DEFINE_CONSTANT(Name, Value, Help) \ do { \ char *temp; \ temp = xen_scheme_constant_to_ruby(Name); \ rb_define_global_const(temp, C_TO_XEN_INT(Value)); \ if ((Name) && (Help)) C_SET_OBJECT_HELP(temp, Help); \ if (temp) free(temp); \ } while (0) #define XEN_DEFINE_VARIABLE(Name, Var, Value) \ { \ char *temp; \ Var = Value; \ temp = xen_scheme_global_variable_to_ruby(Name); \ rb_define_variable(temp, (VALUE *)(&Var)); \ if (temp) free(temp); \ } #define XEN_DEFINE(Name, Value) xen_rb_define(Name, Value) #define XEN_DEFINED_P(Name) xen_rb_defined_p(Name) /* ---- C structs ---- */ #define XEN_MARK_OBJECT_TYPE void * #define XEN_MAKE_AND_RETURN_OBJECT(Tag, Val, Mark, Free) return(Data_Wrap_Struct(Tag, Mark, Free, Val)) #define XEN_MAKE_OBJECT(Tag, Val, Mark, Free) Data_Wrap_Struct(Tag, Mark, Free, Val) #define XEN_OBJECT_REF(a) DATA_PTR(a) #define XEN_OBJECT_TYPE VALUE #define XEN_OBJECT_TYPE_P(OBJ, TAG) (XEN_BOUND_P(OBJ) && (rb_obj_is_instance_of(OBJ, TAG))) #define XEN_MAKE_OBJECT_TYPE(Typ, Siz) xen_rb_define_class(Typ) #define XEN_MAKE_OBJECT_FREE_PROCEDURE(Type, Wrapped_Free, Original_Free) \ static void *Wrapped_Free(XEN obj) \ { \ Original_Free((Type *)obj); \ return(NULL); \ } #define XEN_MAKE_OBJECT_PRINT_PROCEDURE(Type, Wrapped_Print, Original_Print) \ static XEN Wrapped_Print(XEN obj) \ { \ XEN val; \ char *str; \ str = Original_Print((Type *)XEN_OBJECT_REF(obj)); \ val = C_TO_XEN_STRING(str); \ free(str); \ return(val); \ } /* ---- procedures ---- */ #ifdef __cplusplus #ifdef ANYARGS #define XEN_PROCEDURE_CAST (XEN (*)(ANYARGS)) #define XEN_VALUE_ARG_PROCEDURE_CAST (XEN (*)(VALUE)) #else #define XEN_PROCEDURE_CAST (XEN (*)()) #define XEN_VALUE_ARG_PROCEDURE_CAST (XEN (*)()) #endif #else #define XEN_PROCEDURE_CAST #define XEN_VALUE_ARG_PROCEDURE_CAST #endif #define XEN_ARITY(Func) rb_funcall(Func, rb_intern("arity"), 0) #define XEN_REQUIRED_ARGS(Func) xen_rb_required_args(XEN_ARITY(Func)) #define XEN_REQUIRED_ARGS_OK(Func, Args) (xen_rb_required_args(XEN_ARITY(Func)) == Args) #define XEN_DEFINE_PROCEDURE(Name, Func, ReqArg, OptArg, RstArg, Doc) \ do { \ char *temp; \ temp = xen_scheme_procedure_to_ruby(Name); \ rb_define_global_function(temp, XEN_PROCEDURE_CAST Func, ((RstArg > 0) ? -2 : (OptArg > 0) ? -1 : ReqArg)); \ if ((Name) && (Doc)) C_SET_OBJECT_HELP(temp, Doc); \ if (temp) free(temp); \ } while (0) #define XEN_DEFINE_PROCEDURE_WITH_SETTER(Get_Name, Get_Func, Get_Help, Set_Name, Set_Func, Get_Req, Get_Opt, Set_Req, Set_Opt) \ do { \ XEN_DEFINE_PROCEDURE(Get_Name, XEN_PROCEDURE_CAST Get_Func, Get_Req, Get_Opt, 0, Get_Help); \ XEN_DEFINE_PROCEDURE(Set_Name, XEN_PROCEDURE_CAST Set_Func, Set_Req, Set_Opt, 0, Get_Help); \ } while (0) #define XEN_DEFINE_SAFE_PROCEDURE(Name, Func, ReqArg, OptArg, RstArg, Doc) XEN_DEFINE_PROCEDURE(Name, Func, ReqArg, OptArg, RstArg, Doc) #define XEN_CALL_0(Func, Caller) xen_rb_funcall_0(Func) #define XEN_CALL_1(Func, Arg1, Caller) rb_funcall(Func, rb_intern("call"), 1, Arg1) #define XEN_CALL_2(Func, Arg1, Arg2, Caller) rb_funcall(Func, rb_intern("call"), 2, Arg1, Arg2) #define XEN_CALL_3(Func, Arg1, Arg2, Arg3, Caller) rb_funcall(Func, rb_intern("call"), 3, Arg1, Arg2, Arg3) #define XEN_CALL_4(Func, Arg1, Arg2, Arg3, Arg4, Caller) rb_funcall(Func, rb_intern("call"), 4, Arg1, Arg2, Arg3, Arg4) #define XEN_CALL_5(Func, Arg1, Arg2, Arg3, Arg4, Arg5, Caller) rb_funcall(Func, rb_intern("call"), 5, Arg1, Arg2, Arg3, Arg4, Arg5) #define XEN_CALL_6(Func, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Caller) rb_funcall(Func, rb_intern("call"), 6, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) #define XEN_APPLY(Func, Args, Caller) xen_rb_apply(Func, Args) #define XEN_CALL_0_NO_CATCH(Func) xen_rb_funcall_0(Func) #define XEN_CALL_1_NO_CATCH(Func, Arg1) rb_funcall(Func, rb_intern("call"), 1, Arg1) #define XEN_CALL_2_NO_CATCH(Func, Arg1, Arg2) rb_funcall(Func, rb_intern("call"), 2, Arg1, Arg2) #define XEN_CALL_3_NO_CATCH(Func, Arg1, Arg2, Arg3) rb_funcall(Func, rb_intern("call"), 3, Arg1, Arg2, Arg3) #define XEN_APPLY_NO_CATCH(Func, Args) xen_rb_apply(Func, Args) /* ---- keywords, etc ---- */ #define XEN_KEYWORD_EQ_P(k1, k2) ((k1) == (k2)) #define XEN_MAKE_KEYWORD(Arg) xen_rb_make_keyword(Arg) #define XEN_PROVIDE(a) rb_provide(a) #define XEN_PROTECT_FROM_GC(Var) rb_gc_register_address(&(Var)) #define XEN_UNPROTECT_FROM_GC(Var) rb_gc_unregister_address(&(Var)) /* ---- errors ---- */ #define XEN_ERROR_TYPE(Name) xen_rb_intern(Name) #if USE_SND #define XEN_ERROR(Type, Info) snd_rb_raise(Type, Info) #define XEN_OUT_OF_RANGE_ERROR(Caller, ArgN, Arg, Descr) \ snd_rb_raise(XEN_ERROR_TYPE("out-of-range"), \ XEN_LIST_5(C_TO_XEN_STRING("~A: argument ~A, ~A, is out of range (~A)"), \ C_TO_XEN_STRING(xen_scheme_procedure_to_ruby(Caller)), \ C_TO_XEN_INT(ArgN), \ Arg, \ C_TO_XEN_STRING(Descr))) #define XEN_WRONG_TYPE_ARG_ERROR(Caller, ArgN, Arg, Descr) \ snd_rb_raise(XEN_ERROR_TYPE("wrong-type-arg"), \ XEN_LIST_5(C_TO_XEN_STRING("~A: argument ~A, ~A, should be ~A"), \ C_TO_XEN_STRING(xen_scheme_procedure_to_ruby(Caller)), \ C_TO_XEN_INT(ArgN), \ Arg, \ C_TO_XEN_STRING(Descr))) #else #define XEN_ERROR(Type, Info) xen_rb_raise(Type, Info) #define XEN_OUT_OF_RANGE_ERROR(Caller, ArgN, Arg, Descr) \ rb_raise(rb_eRangeError, "%s: argument %d, %s, is out of range (%s)\n", \ Caller, (int)ArgN, XEN_AS_STRING(Arg), Descr) #define XEN_WRONG_TYPE_ARG_ERROR(Caller, ArgN, Arg, Descr) \ rb_raise(rb_eTypeError, "%s: argument %d, %s, should be %s\n", \ Caller, (int)ArgN, XEN_AS_STRING(Arg), Descr) #endif #define XEN_ASSERT_TYPE(Assertion, Arg, Position, Caller, Correct_Type) \ if (!(Assertion)) \ XEN_WRONG_TYPE_ARG_ERROR(Caller, Position, Arg, Correct_Type) #define XEN_THROW(Type, Info) xen_rb_raise(Type, Info) #define XEN_ARGIFY_1(OutName, InName) \ static XEN OutName(int argc, XEN *argv, XEN self) \ { \ return(InName((argc > 0) ? argv[0] : XEN_UNDEFINED)); \ } #define XEN_ARGIFY_2(OutName, InName) \ static XEN OutName(int argc, XEN *argv, XEN self) \ { \ return(InName((argc > 0) ? argv[0] : XEN_UNDEFINED, \ (argc > 1) ? argv[1] : XEN_UNDEFINED)); \ } #define XEN_ARGIFY_3(OutName, InName) \ static XEN OutName(int argc, XEN *argv, XEN self) \ { \ return(InName((argc > 0) ? argv[0] : XEN_UNDEFINED, \ (argc > 1) ? argv[1] : XEN_UNDEFINED, \ (argc > 2) ? argv[2] : XEN_UNDEFINED)); \ } #define XEN_ARGIFY_4(OutName, InName) \ static XEN OutName(int argc, XEN *argv, XEN self) \ { \ return(InName((argc > 0) ? argv[0] : XEN_UNDEFINED, \ (argc > 1) ? argv[1] : XEN_UNDEFINED, \ (argc > 2) ? argv[2] : XEN_UNDEFINED, \ (argc > 3) ? argv[3] : XEN_UNDEFINED)); \ } #define XEN_ARGIFY_5(OutName, InName) \ static XEN OutName(int argc, XEN *argv, XEN self) \ { \ return(InName((argc > 0) ? argv[0] : XEN_UNDEFINED, \ (argc > 1) ? argv[1] : XEN_UNDEFINED, \ (argc > 2) ? argv[2] : XEN_UNDEFINED, \ (argc > 3) ? argv[3] : XEN_UNDEFINED, \ (argc > 4) ? argv[4] : XEN_UNDEFINED)); \ } #define XEN_ARGIFY_6(OutName, InName) \ static XEN OutName(int argc, XEN *argv, XEN self) \ { \ return(InName((argc > 0) ? argv[0] : XEN_UNDEFINED, \ (argc > 1) ? argv[1] : XEN_UNDEFINED, \ (argc > 2) ? argv[2] : XEN_UNDEFINED, \ (argc > 3) ? argv[3] : XEN_UNDEFINED, \ (argc > 4) ? argv[4] : XEN_UNDEFINED, \ (argc > 5) ? argv[5] : XEN_UNDEFINED)); \ } #define XEN_ARGIFY_7(OutName, InName) \ static XEN OutName(int argc, XEN *argv, XEN self) \ { \ return(InName((argc > 0) ? argv[0] : XEN_UNDEFINED, \ (argc > 1) ? argv[1] : XEN_UNDEFINED, \ (argc > 2) ? argv[2] : XEN_UNDEFINED, \ (argc > 3) ? argv[3] : XEN_UNDEFINED, \ (argc > 4) ? argv[4] : XEN_UNDEFINED, \ (argc > 5) ? argv[5] : XEN_UNDEFINED, \ (argc > 6) ? argv[6] : XEN_UNDEFINED)); \ } #define XEN_ARGIFY_8(OutName, InName) \ static XEN OutName(int argc, XEN *argv, XEN self) \ { \ return(InName((argc > 0) ? argv[0] : XEN_UNDEFINED, \ (argc > 1) ? argv[1] : XEN_UNDEFINED, \ (argc > 2) ? argv[2] : XEN_UNDEFINED, \ (argc > 3) ? argv[3] : XEN_UNDEFINED, \ (argc > 4) ? argv[4] : XEN_UNDEFINED, \ (argc > 5) ? argv[5] : XEN_UNDEFINED, \ (argc > 6) ? argv[6] : XEN_UNDEFINED, \ (argc > 7) ? argv[7] : XEN_UNDEFINED)); \ } #define XEN_ARGIFY_9(OutName, InName) \ static XEN OutName(int argc, XEN *argv, XEN self) \ { \ return(InName((argc > 0) ? argv[0] : XEN_UNDEFINED, \ (argc > 1) ? argv[1] : XEN_UNDEFINED, \ (argc > 2) ? argv[2] : XEN_UNDEFINED, \ (argc > 3) ? argv[3] : XEN_UNDEFINED, \ (argc > 4) ? argv[4] : XEN_UNDEFINED, \ (argc > 5) ? argv[5] : XEN_UNDEFINED, \ (argc > 6) ? argv[6] : XEN_UNDEFINED, \ (argc > 7) ? argv[7] : XEN_UNDEFINED, \ (argc > 8) ? argv[8] : XEN_UNDEFINED)); \ } #define XEN_NARGIFY_0(OutName, InName) \ static XEN OutName(void) {return(InName());} #define XEN_NARGIFY_1(OutName, InName) \ static XEN OutName(XEN self, XEN Arg) {return(InName(Arg));} #define XEN_NARGIFY_2(OutName, InName) \ static XEN OutName(XEN self, XEN Arg1, XEN Arg2) {return(InName(Arg1, Arg2));} #define XEN_NARGIFY_3(OutName, InName) \ static XEN OutName(XEN self, XEN Arg1, XEN Arg2, XEN Arg3) {return(InName(Arg1, Arg2, Arg3));} #define XEN_NARGIFY_4(OutName, InName) \ static XEN OutName(XEN self, XEN Arg1, XEN Arg2, XEN Arg3, XEN Arg4) {return(InName(Arg1, Arg2, Arg3, Arg4));} #define XEN_NARGIFY_5(OutName, InName) \ static XEN OutName(XEN self, XEN Arg1, XEN Arg2, XEN Arg3, XEN Arg4, XEN Arg5) {return(InName(Arg1, Arg2, Arg3, Arg4, Arg5));} #define XEN_NARGIFY_6(OutName, InName) \ static XEN OutName(XEN self, XEN Arg1, XEN Arg2, XEN Arg3, XEN Arg4, XEN Arg5, XEN Arg6) {return(InName(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6));} #define XEN_NARGIFY_7(OutName, InName) \ static XEN OutName(XEN self, XEN Arg1, XEN Arg2, XEN Arg3, XEN Arg4, XEN Arg5, XEN Arg6, XEN Arg7) \ {return(InName(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7));} #define XEN_NARGIFY_8(OutName, InName) \ static XEN OutName(XEN self, XEN Arg1, XEN Arg2, XEN Arg3, XEN Arg4, XEN Arg5, XEN Arg6, XEN Arg7, XEN Arg8) \ {return(InName(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8));} #define XEN_NARGIFY_9(OutName, InName) \ static XEN OutName(XEN self, XEN Arg1, XEN Arg2, XEN Arg3, XEN Arg4, XEN Arg5, XEN Arg6, XEN Arg7, XEN Arg8, XEN Arg9) \ {return(InName(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9));} #define XEN_VARGIFY(OutName, InName) \ static XEN OutName(XEN self, XEN Args) {return(InName(Args));} #ifdef __cplusplus extern "C" { #endif XEN xen_rb_gv_get(const char *name); XEN xen_rb_gv_set(const char *name, XEN new_val); XEN xen_rb_intern(const char *name); XEN xen_rb_make_keyword(const char *name); void xen_rb_define(const char *name, XEN value); XEN xen_rb_cdr(XEN val); XEN xen_rb_cons(XEN arg1, XEN arg2); XEN xen_rb_cons2(XEN arg1, XEN arg2, XEN arg3); char *xen_scheme_constant_to_ruby(const char *name); char *xen_scheme_procedure_to_ruby(const char *name); char *xen_scheme_global_variable_to_ruby(const char *name); bool xen_rb_defined_p(const char *name); XEN xen_rb_define_class(const char *name); int xen_rb_list_length(XEN obj); XEN xen_rb_list_ref(XEN obj, int index); XEN xen_rb_list_set(XEN obj, int index, XEN value); void xen_rb_raise(XEN type, XEN info); XEN xen_rb_obj_as_string(XEN obj); XEN xen_rb_eval_string_with_error(const char *str); XEN xen_rb_load_file_with_error(XEN file); XEN xen_rb_ary_new_with_initial_element(long num, XEN element); XEN xen_rb_apply(XEN func, XEN args); XEN xen_rb_funcall_0(XEN func); int xen_rb_required_args(XEN val); XEN xen_rb_copy_list(XEN val); XEN xen_rb_str_new2(char *arg); void xen_add_help(char *name, const char *help); char *xen_help(char *name); /* class Hook */ bool xen_rb_hook_p(XEN hook); bool xen_rb_hook_empty_p(XEN hook); XEN xen_rb_hook_c_new(char *name, int arity, char *help); XEN xen_rb_hook_reset_hook(XEN hook); XEN xen_rb_hook_to_a(XEN hook); void Init_Hook(void); XEN xen_rb_create_hook(char *name, int arity, char *help); XEN xen_rb_create_simple_hook(int arity); XEN xen_rb_add_hook(XEN hook, VALUE (*func)(), const char *name, const char *doc); typedef XEN (*XEN_CATCH_BODY_TYPE) (void *data); XEN rb_properties(void); XEN rb_property(XEN obj, XEN prop); XEN rb_set_property(XEN obj, XEN prop, XEN val); XEN rb_documentation(XEN name); XEN rb_set_documentation(XEN name, XEN help); bool xen_rb_arity_ok(int rargs, int args); void xen_rb_repl_set_prompt(const char *prompt); XEN xen_rb_add_to_load_path(char *path); XEN xen_set_assoc(XEN key, XEN val, XEN alist); XEN xen_assoc(XEN key, XEN alist); #ifdef __cplusplus } #endif #endif /* end HAVE_RUBY */ /* ------------------------------ FORTH ------------------------------ */ #if HAVE_FORTH #include #if USE_SND # undef gettext_noop # undef _ # undef N_ #endif #define XEN_OK true #define XEN FTH #define XEN_FILE_EXTENSION FTH_FILE_EXTENSION #define XEN_COMMENT_STRING "\\" #define XEN_LANGUAGE_NAME "Forth" #define XEN_FALSE FTH_FALSE #define XEN_TRUE FTH_TRUE #define XEN_EMPTY_LIST FTH_NIL #define XEN_UNDEFINED FTH_UNDEF #define XEN_DOCUMENTATION_SYMBOL FTH_DOCUMENTATION_SYMBOL #define XEN_DEFINED_P(name) fth_defined_p((char *)name) #define XEN_PROVIDE(feature) fth_add_feature(feature) /* === Boolean, Bound, Equal === */ #define XEN_BOOLEAN_P(Arg) FTH_BOOLEAN_P(Arg) #define XEN_TRUE_P(a) FTH_TRUE_P(a) #define XEN_FALSE_P(a) FTH_FALSE_P(a) #define C_TO_XEN_BOOLEAN(a) BOOL_TO_FTH(a) #define XEN_TO_C_BOOLEAN(a) FTH_TO_BOOL(a) #define XEN_BOUND_P(Arg) FTH_BOUND_P(Arg) #define XEN_EQ_P(a, b) ((a) == (b)) /* === Number === */ #define XEN_ZERO FTH_ZERO #define XEN_NUMBER_P(Arg) FTH_NUMBER_P(Arg) #define XEN_WRAPPED_C_POINTER_P(Arg) FTH_EXACT_P(Arg) #define XEN_INTEGER_P(Arg) FTH_INTEGER_P(Arg) #define C_TO_XEN_INT(a) fth_make_int(a) #define XEN_TO_C_INT(a) fth_int_ref(a) #define XEN_ULONG_P(Arg) FTH_UNSIGNED_P(Arg) #define C_TO_XEN_ULONG(a) fth_make_unsigned((unsigned long)(a)) #define XEN_TO_C_ULONG(a) fth_unsigned_ref(a) #define XEN_ULONG_LONG_P(Arg) XEN_ULONG_P(Arg) #define XEN_TO_C_ULONG_LONG(Arg) fth_ulong_long_ref(Arg) #define C_TO_XEN_ULONG_LONG(Arg) fth_make_ulong_long((unsigned long long)Arg) #define C_TO_XEN_LONG_LONG(a) fth_make_long_long(a) #define XEN_TO_C_LONG_LONG(a) fth_long_long_ref(a) #define XEN_DOUBLE_P(Arg) FTH_FLOAT_P(Arg) #define C_TO_XEN_DOUBLE(a) fth_make_float(a) #define XEN_TO_C_DOUBLE(a) fth_float_ref(a) #if HAVE_COMPLEX_NUMBERS # define XEN_COMPLEX_P(Arg) FTH_NUMBER_P(Arg) # define C_TO_XEN_COMPLEX(a) fth_make_complex(a) # define XEN_TO_C_COMPLEX(a) fth_complex_ref(a) # define XEN_HAVE_COMPLEX_NUMBERS 1 #else # define XEN_COMPLEX_P(Arg) false # define C_TO_XEN_COMPLEX(a) XEN_ZERO # define XEN_TO_C_COMPLEX(a) 0.0 #endif #if HAVE_MAKE_RATIO # define XEN_HAVE_RATIOS true # define XEN_RATIO_P(Arg) FTH_RATIO_P(Arg) # define XEN_MAKE_RATIO(Num, Den) fth_make_ratio(Num, Den) # define XEN_NUMERATOR(Arg) XEN_TO_C_LONG_LONG(fth_numerator(Arg)) # define XEN_DENOMINATOR(Arg) XEN_TO_C_LONG_LONG(fth_denominator(Arg)) # define XEN_RATIONALIZE(Arg1, Arg2) fth_rationalize(Arg1, Arg2) #endif /* === String, Symbol, Keyword, Eval === */ #define XEN_CHAR_P(Arg) FTH_CHAR_P(Arg) #define C_TO_XEN_CHAR(Arg) CHAR_TO_FTH(Arg) #define XEN_TO_C_CHAR(Arg) FTH_TO_CHAR(Arg) #define XEN_STRING_P(Arg) FTH_STRING_P(Arg) #define C_TO_XEN_STRING(str) fth_make_string(str) #define C_TO_XEN_STRINGN(str, len) fth_make_string_len(str, len) #define XEN_TO_C_STRING(Str) fth_string_ref(Str) #if HAVE_FTH_PORT_PUTS /* port = XEN_FALSE means default output handler (snd-print). */ #define XEN_PUTS(Str, Port) fth_port_puts(Port, Str) #define XEN_DISPLAY(Val, Port) fth_port_display(Port, Val) #define XEN_FLUSH_PORT(Port) fth_port_flush(Port) #define XEN_CLOSE_PORT(Port) fth_port_close(Port) #define XEN_PORT_TO_STRING(Port) fth_port_to_string(Port) #endif #define XEN_TO_STRING(Obj) fth_object_to_string(Obj) #define XEN_SYMBOL_P(Arg) FTH_SYMBOL_P(Arg) #define C_STRING_TO_XEN_SYMBOL(a) fth_symbol(a) #define XEN_SYMBOL_TO_C_STRING(Sym) fth_symbol_ref(Sym) #define XEN_KEYWORD_P(Obj) FTH_KEYWORD_P(Obj) #define XEN_MAKE_KEYWORD(arg) fth_keyword(arg) #define XEN_KEYWORD_EQ_P(K1, K2) XEN_EQ_P(K1, K2) #define XEN_EVAL_C_STRING(arg) fth_eval(arg) #define XEN_LOAD_FILE(a) fth_load_file(a) #define XEN_LOAD_PATH XEN_NAME_AS_C_STRING_TO_VALUE("*load-path*") #define XEN_ADD_TO_LOAD_PATH(Path) fth_add_load_path(Path) /* === Vector (Array) === */ #define XEN_MAKE_VECTOR(Num, Fill) fth_make_array_with_init(Num, Fill) #define XEN_VECTOR_P(Arg) FTH_ARRAY_P(Arg) #define XEN_VECTOR_LENGTH(Arg) ((int)fth_array_length(Arg)) #define XEN_VECTOR_TO_LIST(Vect) fth_array_to_list(Vect) #define XEN_VECTOR_REF(Vect, Num) fth_array_ref(Vect, Num) #define XEN_VECTOR_SET(Vect, Num, Val) fth_array_set(Vect, Num, Val) #define XEN_VECTOR_COPY(Vect) fth_array_copy(Vect) /* === List === */ #define XEN_NULL_P(a) FTH_NIL_P(a) #define XEN_LIST_P(Arg) FTH_LIST_P(Arg) #define XEN_CONS_P(Arg) FTH_CONS_P(Arg) #define XEN_PAIR_P(Arg) FTH_PAIR_P(Arg) #define XEN_CONS(Arg1, Arg2) fth_cons(Arg1, Arg2) #define XEN_CONS_2(Arg1, Arg2, Arg3) fth_cons_2(Arg1, Arg2, Arg3) #define XEN_LIST_REF(Lst, Num) fth_list_ref(Lst, Num) #define XEN_LIST_SET(Lst, Num, Val) fth_list_set(Lst, Num, Val) #define XEN_LIST_REVERSE(Lst) fth_list_reverse(Lst) #define XEN_LIST_P_WITH_LENGTH(Arg, Len) ((Len = XEN_LIST_LENGTH(Arg)) >= 0) #define XEN_LIST_LENGTH(Arg) ((int)fth_list_length(Arg)) #define XEN_LIST_1(a) FTH_LIST_1(a) #define XEN_LIST_2(a, b) FTH_LIST_2(a, b) #define XEN_LIST_3(a, b, c) FTH_LIST_3(a, b, c) #define XEN_LIST_4(a, b, c, d) FTH_LIST_4(a, b, c, d) #define XEN_LIST_5(a, b, c, d, e) FTH_LIST_5(a, b, c, d, e) #define XEN_LIST_6(a, b, c, d, e, f) FTH_LIST_6(a, b, c, d, e, f) #define XEN_LIST_7(a, b, c, d, e, f, g) FTH_LIST_7(a, b, c, d, e, f, g) #define XEN_LIST_8(a, b, c, d, e, f, g, h) FTH_LIST_8(a, b, c, d, e, f, g, h) #define XEN_LIST_9(a, b, c, d, e, f, g, h, i) FTH_LIST_9(a, b, c, d, e, f, g, h, i) #define XEN_CAR(a) fth_car(a) #define XEN_CADR(a) FTH_CADR(a) #define XEN_CADDR(a) FTH_CADDR(a) #define XEN_CADDDR(a) FTH_CADDDR(a) #define XEN_CDR(a) fth_cdr(a) #define XEN_CDDR(a) FTH_CDDR(a) #define XEN_CDDDR(a) FTH_CDDDR(a) #define XEN_COPY_ARG(Lst) fth_list_copy(Lst) #define XEN_APPEND(a, b) fth_list_append(XEN_LIST_2(a, b)) #define XEN_ASSOC_REF(Item, Lst) fth_list_assoc_ref(Lst, Item) #define XEN_ASSOC_SET(Sym, Val, Lst) fth_list_assoc_set(Lst, Sym, Val) #define XEN_ASSOC(Item, Lst) fth_list_assoc_ref(Lst, Item) /* perhaps fth_list_assoc? */ #define XEN_MEMBER(Item, Lst) fth_list_member_p(Lst, Item) /* === Hook, Procedure === */ #define XEN_HOOK_P(Arg) FTH_HOOK_P(Arg) #define XEN_HOOKED(a) (!fth_hook_empty_p(a)) #define XEN_DEFINE_HOOK(name, descr, arity, help) fth_make_hook(name, arity, help) #define XEN_DEFINE_SIMPLE_HOOK(descr, arity) fth_make_simple_hook(arity) #define XEN_CLEAR_HOOK(Arg) fth_hook_clear(Arg) #define XEN_HOOK_PROCEDURES(Obj) fth_hook_procedure_list(Obj) #define XEN_ADD_HOOK(Hook, Func, Name, Doc) fth_add_hook(Hook, (FTH)fth_define_procedure(Name, Func, fth_hook_arity(Hook), 0, false, Doc)) #define XEN_PROCEDURE_P(Arg) FTH_PROC_P(Arg) #define XEN_PROCEDURE_NAME(Func) C_TO_XEN_STRING(fth_proc_name(Func)) #define XEN_PROCEDURE_HELP(Name) fth_documentation_ref(Name) #define XEN_ARITY(Func) INT_TO_FIX(XEN_REQUIRED_ARGS(Func)) #define XEN_REQUIRED_ARGS(Func) fth_proc_arity(Func) #define XEN_REQUIRED_ARGS_OK(Func, args) (XEN_REQUIRED_ARGS(Func) == (args)) #define XEN_CALL_0(Func, Caller) fth_proc_call(Func, Caller, 0) #define XEN_CALL_1(Func, Arg1, Caller) fth_proc_call(Func, Caller, 1, Arg1) #define XEN_CALL_2(Func, Arg1, Arg2, Caller) fth_proc_call(Func, Caller, 2, Arg1, Arg2) #define XEN_CALL_3(Func, Arg1, Arg2, Arg3, Caller) fth_proc_call(Func, Caller, 3, Arg1, Arg2, Arg3) #define XEN_CALL_4(Func, Arg1, Arg2, Arg3, Arg4, Caller) \ fth_proc_call(Func, Caller, 4, Arg1, Arg2, Arg3, Arg4) #define XEN_CALL_5(Func, Arg1, Arg2, Arg3, Arg4, Arg5, Caller) \ fth_proc_call(Func, Caller, 5, Arg1, Arg2, Arg3, Arg4, Arg5) #define XEN_CALL_6(Func, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Caller) \ fth_proc_call(Func, Caller, 6, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) #define XEN_APPLY(Func, Args, Caller) fth_proc_apply(Func, Args, Caller) #define XEN_CALL_0_NO_CATCH(Func) XEN_CALL_0(Func, NULL) #define XEN_CALL_1_NO_CATCH(Func, Arg1) XEN_CALL_1(Func, Arg1, NULL) #define XEN_CALL_2_NO_CATCH(Func, Arg1, Arg2) XEN_CALL_2(Func, Arg1, Arg2, NULL) #define XEN_CALL_3_NO_CATCH(Func, Arg1, Arg2, Arg3) XEN_CALL_3(Func, Arg1, Arg2, Arg3, NULL) #define XEN_APPLY_NO_CATCH(Func, Args) XEN_APPLY(Func, Args, NULL) /* === Define === */ #define XEN_DEFINE(name, Value) fth_define(name, Value) #define XEN_DEFINE_CONSTANT(name, Value, help) fth_define_constant(name, Value, help) #define XEN_DEFINE_VARIABLE(name, Var, Value) (Var = fth_define_variable(name, Value, NULL)) #define XEN_VARIABLE_SET(name, Value) fth_variable_set((char *)(name), Value) #define XEN_VARIABLE_REF(name) fth_variable_ref((char *)(name)) #define XEN_NAME_AS_C_STRING_TO_VARIABLE(name) fth_word_ref((char *)(name)) #define XEN_NAME_AS_C_STRING_TO_VALUE(name) XEN_VARIABLE_REF(name) #ifdef __cplusplus # define XEN_PROCEDURE_CAST (XEN (*)()) #else # define XEN_PROCEDURE_CAST #endif #define XEN_DEFINE_PROCEDURE(Name, Func, ReqArg, OptArg, RstArg, Doc) \ fth_define_procedure(Name, XEN_PROCEDURE_CAST Func, ReqArg, OptArg, RstArg, Doc) #define XEN_DEFINE_PROCEDURE_WITH_SETTER(Get_Name, Get_Func, Get_Help, Set_Name, Set_Func, Get_Req, Get_Opt, Set_Req, Set_Opt) \ do { \ XEN_DEFINE_PROCEDURE(Get_Name, XEN_PROCEDURE_CAST Get_Func, Get_Req, Get_Opt, 0, Get_Help); \ XEN_DEFINE_PROCEDURE(Set_Name, XEN_PROCEDURE_CAST Set_Func, Set_Req, Set_Opt, 0, Get_Help); \ } while (0) #define XEN_DEFINE_SAFE_PROCEDURE(Name, Func, ReqArg, OptArg, RstArg, Doc) XEN_DEFINE_PROCEDURE(Name, Func, ReqArg, OptArg, RstArg, Doc) /* === Object === */ #define XEN_OBJECT_TYPE FTH #define XEN_MARK_OBJECT_TYPE void #define XEN_MAKE_AND_RETURN_OBJECT(Tag, Val, Mark, Free) return(fth_make_instance(Tag, Val)) #define XEN_MAKE_OBJECT(Tag, Val, Mark, Free) fth_make_instance(Tag, Val) #define XEN_OBJECT_TYPE_P(Obj, Tag) fth_object_is_instance_of(Obj, Tag) #define XEN_OBJECT_REF(Obj) fth_instance_ref_gen(Obj) #define XEN_MAKE_OBJECT_TYPE(Typ, Siz) fth_make_object_type(Typ) #define XEN_OBJECT_HELP(Name) fth_documentation_ref(Name) #define XEN_PROTECT_FROM_GC(Obj) fth_gc_protect(Obj) #define XEN_UNPROTECT_FROM_GC(Obj) fth_gc_unprotect(Obj) #define XEN_MAKE_OBJECT_PRINT_PROCEDURE(Type, Wrapped_Print, Original_Print) \ static XEN Wrapped_Print(XEN obj) \ { \ char * str = Original_Print((Type *)XEN_OBJECT_REF(obj)); \ XEN val = C_TO_XEN_STRING(str); \ free(str); \ return val; \ } #define XEN_MAKE_OBJECT_FREE_PROCEDURE(Type, Wrapped_Free, Original_Free) \ static void Wrapped_Free(XEN obj) \ { \ Original_Free((Type *)XEN_OBJECT_REF(obj)); \ } /* === Error === */ #define XEN_ASSERT_TYPE(Assertion, Arg, Position, Caller, Correct_Type) \ FTH_ASSERT_TYPE(Assertion, Arg, Position, Caller, Correct_Type) #define XEN_ERROR_TYPE(Typ) fth_exception(Typ) #define XEN_ERROR(Type, Info) fth_throw_list(Type, Info) #define XEN_THROW(Type, Info) XEN_ERROR(Type, Info) #define XEN_OUT_OF_RANGE_ERROR(Caller, ArgN, Arg, Descr) \ FTH_OUT_OF_RANGE_ERROR(Caller, ArgN, Arg, Descr) #define XEN_WRONG_TYPE_ARG_ERROR(Caller, ArgN, Arg, Descr) \ FTH_WRONG_TYPE_ARG_ERROR(Caller, ArgN, Arg, Descr) typedef XEN (*XEN_CATCH_BODY_TYPE) (void *data); #define XEN_NARGIFY_0(OutName, InName) static XEN (*OutName)(void) = InName; #define XEN_NARGIFY_1(OutName, InName) static XEN (*OutName)(XEN a1) = InName; #define XEN_NARGIFY_2(OutName, InName) static XEN (*OutName)(XEN a1, XEN a2) = InName; #define XEN_NARGIFY_3(OutName, InName) static XEN (*OutName)(XEN a1, XEN a2, XEN a3) = InName; #define XEN_NARGIFY_4(OutName, InName) static XEN (*OutName)(XEN a1, XEN a2, XEN a3, XEN a4) = InName; #define XEN_NARGIFY_5(OutName, InName) static XEN (*OutName)(XEN a1, XEN a2, XEN a3, XEN a4, XEN a5) = InName; #define XEN_NARGIFY_6(OutName, InName) static XEN (*OutName)(XEN a1, XEN a2, XEN a3, XEN a4, XEN a5, XEN a6) = InName; #define XEN_NARGIFY_7(OutName, InName) static XEN (*OutName)(XEN a1, XEN a2, XEN a3, XEN a4, XEN a5, XEN a6, XEN a7) = InName; #define XEN_NARGIFY_8(OutName, InName) static XEN (*OutName)(XEN a1, XEN a2, XEN a3, XEN a4, XEN a5, XEN a6, XEN a7, XEN a8) = InName; #define XEN_NARGIFY_9(OutName, InName) static XEN (*OutName)(XEN a1, XEN a2, XEN a3, XEN a4, XEN a5, XEN a6, XEN a7, XEN a8, XEN a9) = InName; #define XEN_ARGIFY_1(OutName, InName) static XEN (*OutName)(XEN a1) = InName; #define XEN_ARGIFY_2(OutName, InName) static XEN (*OutName)(XEN a1, XEN a2) = InName; #define XEN_ARGIFY_3(OutName, InName) static XEN (*OutName)(XEN a1, XEN a2, XEN a3) = InName; #define XEN_ARGIFY_4(OutName, InName) static XEN (*OutName)(XEN a1, XEN a2, XEN a3, XEN a4) = InName; #define XEN_ARGIFY_5(OutName, InName) static XEN (*OutName)(XEN a1, XEN a2, XEN a3, XEN a4, XEN a5) = InName; #define XEN_ARGIFY_6(OutName, InName) static XEN (*OutName)(XEN a1, XEN a2, XEN a3, XEN a4, XEN a5, XEN a6) = InName; #define XEN_ARGIFY_7(OutName, InName) static XEN (*OutName)(XEN a1, XEN a2, XEN a3, XEN a4, XEN a5, XEN a6, XEN a7) = InName; #define XEN_ARGIFY_8(OutName, InName) static XEN (*OutName)(XEN a1, XEN a2, XEN a3, XEN a4, XEN a5, XEN a6, XEN a7, XEN a8) = InName; #define XEN_ARGIFY_9(OutName, InName) static XEN (*OutName)(XEN a1, XEN a2, XEN a3, XEN a4, XEN a5, XEN a6, XEN a7, XEN a8, XEN a9) = InName; #define XEN_VARGIFY(OutName, InName) static XEN (*OutName)(XEN a1) = InName; #endif /* end HAVE_FORTH */ /* ------------------------------ s7 ------------------------------ */ #if HAVE_SCHEME #define XEN_OK 1 #include "s7.h" #ifdef __cplusplus extern "C" { #endif extern s7_scheme *s7; /* s7 is a pointer to the current scheme */ #ifdef __cplusplus } #endif #define XEN s7_pointer #define XEN_FILE_EXTENSION "scm" #define XEN_LANGUAGE_NAME "s7" #define XEN_COMMENT_STRING ";" extern XEN xen_false, xen_true, xen_nil, xen_undefined, xen_zero; extern size_t xen_s7_number_location, xen_s7_denominator_location; #define XEN_FALSE xen_false #define XEN_TRUE xen_true #define XEN_TRUE_P(Arg) ((Arg) == XEN_TRUE) /* not scheme-wise, but Snd-wise (#t as special arg) */ #define XEN_FALSE_P(Arg) ((Arg) == XEN_FALSE) #define XEN_BOOLEAN_P(Arg) s7_is_boolean(Arg) #define C_TO_XEN_BOOLEAN(Arg) ((Arg) ? XEN_TRUE : XEN_FALSE) #define XEN_TO_C_BOOLEAN(Arg) ((XEN_TRUE_P(Arg)) ? true : false) #define XEN_NULL_P(Arg) ((Arg) == xen_nil) #define XEN_BOUND_P(Arg) ((Arg) != xen_undefined) #define XEN_EMPTY_LIST xen_nil #define XEN_UNDEFINED xen_undefined #define XEN_EQ_P(Arg1, Arg2) ((Arg1) == (Arg2)) #define XEN_CONS_P(Arg) s7_cons_p(Arg) #define XEN_CONS(Arg1, Arg2) s7_cons(s7, Arg1, Arg2) #define XEN_CONS_2(Arg1, Arg2, Arg3) s7_cons(s7, Arg1, s7_cons(s7, Arg2, Arg3)) #define XEN_PAIR_P(Arg) s7_is_pair(Arg) #define XEN_CAR(Arg) s7_car(Arg) #define XEN_CDR(Arg) s7_cdr(Arg) #define XEN_CADR(Arg) s7_cadr(Arg) #define XEN_CADDR(Arg) s7_caddr(Arg) #define XEN_CADDDR(Arg) s7_cadddr(Arg) #define XEN_CDDR(Arg) s7_cddr(Arg) #define XEN_CDDDR(Arg) s7_cdddr(Arg) #define XEN_LIST_P(Arg) s7_is_list(s7, Arg) /* not pair? because we want '() to return #t here */ #define XEN_LIST_LENGTH(Arg) s7_list_length(s7, Arg) #define XEN_LIST_P_WITH_LENGTH(Arg, Len) ((s7_is_list(s7, Arg)) && ((Len = XEN_LIST_LENGTH(Arg)) >= 0)) #define XEN_LIST_1(a) s7_list(s7, 1, a) #define XEN_LIST_2(a, b) s7_list(s7, 2, a, b) #define XEN_LIST_3(a, b, c) s7_list(s7, 3, a, b, c) #define XEN_LIST_4(a, b, c, d) s7_list(s7, 4, a, b, c, d) #define XEN_LIST_5(a, b, c, d, e) s7_list(s7, 5, a, b, c, d, e) #define XEN_LIST_6(a, b, c, d, e, f) s7_list(s7, 6, a, b, c, d, e, f) #define XEN_LIST_7(a, b, c, d, e, f, g) s7_list(s7, 7, a, b, c, d, e, f, g) #define XEN_LIST_8(a, b, c, d, e, f, g, h) s7_list(s7, 8, a, b, c, d, e, f, g, h) #define XEN_LIST_9(a, b, c, d, e, f, g, h, i) s7_list(s7, 9, a, b, c, d, e, f, g, h, i) #define XEN_LIST_REF(Lst, Num) s7_list_ref(s7, Lst, Num) #define XEN_LIST_SET(Lst, Num, Val) s7_list_set(s7, Lst, Num, Val) #define XEN_LIST_REVERSE(Lst) s7_reverse(s7, Lst) #define XEN_COPY_ARG(Lst) Lst #define XEN_APPEND(Arg1, Arg2) s7_append(s7, Arg1, Arg2) #define XEN_ASSOC_REF(Sym, Lst) xen_assoc(s7, Sym, Lst) #define XEN_ASSOC_SET(Sym, Val, Lst) xen_set_assoc(s7, Sym, Val, Lst) #define XEN_ASSOC(Sym, Lst) s7_assoc(s7, Sym, Lst) #define XEN_MEMBER(Sym, Lst) s7_member(s7, Sym, Lst) #define XEN_STRING_P(Arg) s7_is_string(Arg) #define XEN_NAME_AS_C_STRING_TO_VALUE(Arg) s7_name_to_value(s7, Arg) #define XEN_TO_C_STRING(Str) s7_string(Str) #define C_TO_XEN_STRING(Str) s7_make_string(s7, Str) #define C_TO_XEN_STRINGN(Str, Len) s7_make_string_with_length(s7, Str, Len) #define XEN_ZERO xen_zero #define XEN_INTEGER_P(Arg) s7_is_integer(Arg) #define C_TO_XEN_INT(Arg) s7_make_integer(s7, Arg) #define XEN_TO_C_INT(Arg) s7_integer(Arg) #define XEN_ULONG_P(Arg) s7_is_ulong(Arg) #define XEN_TO_C_ULONG(Arg) s7_ulong(Arg) #define C_TO_XEN_ULONG(Arg) s7_make_ulong(s7, (unsigned long)Arg) #define XEN_ULONG_LONG_P(Arg) s7_is_ulong_long(Arg) #define XEN_TO_C_ULONG_LONG(Arg) s7_ulong_long(Arg) #define C_TO_XEN_ULONG_LONG(Arg) s7_make_ulong_long(s7, (unsigned long long)Arg) #define C_TO_XEN_LONG_LONG(Arg) s7_make_integer(s7, Arg) #define XEN_TO_C_LONG_LONG(Arg) s7_integer(Arg) #define XEN_NUMBER_P(Arg) s7_is_real(Arg) #define XEN_WRAPPED_C_POINTER_P(Arg) s7_is_c_pointer(Arg) #define XEN_DOUBLE_P(Arg) s7_is_real(Arg) #define XEN_TO_C_DOUBLE(Arg) ((double)s7_number_to_real(s7, Arg)) #define C_TO_XEN_DOUBLE(Arg) s7_make_real(s7, Arg) #if HAVE_COMPLEX_NUMBERS #define XEN_HAVE_COMPLEX_NUMBERS 1 #define XEN_COMPLEX_P(Arg) s7_is_complex(Arg) #define XEN_TO_C_COMPLEX(a) (s7_real_part(a) + s7_imag_part(a) * _Complex_I) #define C_TO_XEN_COMPLEX(a) s7_make_complex(s7, creal(a), cimag(a)) #else #define XEN_HAVE_COMPLEX_NUMBERS 0 #define XEN_COMPLEX_P(Arg) false #define XEN_TO_C_COMPLEX(a) 0.0 #define C_TO_XEN_COMPLEX(a) XEN_ZERO #endif #define XEN_HAVE_RATIOS 1 #define XEN_NUMERATOR(Arg) s7_numerator(Arg) #define XEN_DENOMINATOR(Arg) s7_denominator(Arg) #define XEN_RATIONALIZE(Arg1, Arg2) s7_rationalize(s7, XEN_TO_C_DOUBLE(Arg1), XEN_TO_C_DOUBLE(Arg2)) #define XEN_RATIO_P(Arg) s7_is_ratio(Arg) #define XEN_MAKE_RATIO(Num, Den) s7_make_ratio(s7, XEN_TO_C_INT(Num), XEN_TO_C_INT(Den)) #define XEN_EVAL_C_STRING(Arg) s7_eval_c_string(s7, Arg) #define XEN_TO_STRING(Obj) s7_object_to_string(s7, Obj, false) #define XEN_SYMBOL_TO_C_STRING(Arg) s7_symbol_name(Arg) #define XEN_SYMBOL_P(Arg) s7_is_symbol(Arg) #define C_STRING_TO_XEN_SYMBOL(Arg) s7_make_symbol(s7, Arg) #define XEN_DOCUMENTATION_SYMBOL C_STRING_TO_XEN_SYMBOL("documentation") #define XEN_SET_DOCUMENTATION(Var, Doc) #define XEN_VECTOR_P(Arg) s7_is_vector(Arg) #define XEN_VECTOR_LENGTH(Arg) s7_vector_length(Arg) #define XEN_VECTOR_REF(Vect, Num) s7_vector_ref(s7, Vect, Num) #define XEN_VECTOR_SET(Vect, Num, Val) s7_vector_set(s7, Vect, Num, Val) #define XEN_MAKE_VECTOR(Num, Fill) s7_make_and_fill_vector(s7, Num, Fill) #define XEN_VECTOR_TO_LIST(Vect) s7_vector_to_list(s7, Vect) #define XEN_VECTOR_RANK(Vect) s7_vector_rank(Vect) #define XEN_VECTOR_COPY(Vect) s7_vector_copy(s7, Vect) #define XEN_VECTOR_ELEMENTS(Vect) s7_vector_elements(Vect) #define XEN_CHAR_P(Arg) s7_is_character(Arg) #define XEN_TO_C_CHAR(Arg) s7_character(Arg) #define C_TO_XEN_CHAR(Arg) s7_make_character(s7, Arg) #define XEN_KEYWORD_P(Obj) s7_is_keyword(Obj) #define XEN_KEYWORD_EQ_P(k1, k2) ((k1) == (k2)) #define XEN_MAKE_KEYWORD(Arg) s7_make_keyword(s7, Arg) #define XEN_PROCEDURE_P(Arg) s7_is_procedure(Arg) #define XEN_LOAD_FILE(File) s7_load(s7, File) #define XEN_LOAD_PATH s7_load_path(s7) #define XEN_ADD_TO_LOAD_PATH(Path) s7_add_to_load_path(s7, Path) #define XEN_ERROR_TYPE(Typ) C_STRING_TO_XEN_SYMBOL(Typ) #define XEN_ERROR(Type, Info) s7_error(s7, Type, Info) #define XEN_THROW(Type, Info) s7_error(s7, Type, Info) #define XEN_PROVIDE(Feature) s7_provide(s7, Feature) #define XEN_PROTECT_FROM_GC(Arg) s7_gc_protect(s7, Arg) #define XEN_WRONG_TYPE_ARG_ERROR(Caller, ArgN, Arg, Descr) s7_wrong_type_arg_error(s7, Caller, ArgN, Arg, Descr) #define XEN_OUT_OF_RANGE_ERROR(Caller, ArgN, Arg, Descr) s7_out_of_range_error(s7, Caller, ArgN, Arg, Descr) #define XEN_ASSERT_TYPE(Assertion, Arg, Position, Caller, Correct_Type) if (!(Assertion)) XEN_WRONG_TYPE_ARG_ERROR(Caller, Position, Arg, Correct_Type) #define XEN_NARGIFY_0(OutName, InName) static s7_pointer OutName(s7_scheme *sc, s7_pointer args) {return(InName());} #define XEN_NARGIFY_1(OutName, InName) static s7_pointer OutName(s7_scheme *sc, s7_pointer args) {return(InName(XEN_CAR(args)));} #define XEN_NARGIFY_2(OutName, InName) static s7_pointer OutName(s7_scheme *sc, s7_pointer args) {return(s7_apply_2(s7, args, InName));} #define XEN_NARGIFY_3(OutName, InName) static s7_pointer OutName(s7_scheme *sc, s7_pointer args) {return(s7_apply_3(s7, args, InName));} #define XEN_NARGIFY_4(OutName, InName) static s7_pointer OutName(s7_scheme *sc, s7_pointer args) {return(s7_apply_4(s7, args, InName));} #define XEN_NARGIFY_5(OutName, InName) static s7_pointer OutName(s7_scheme *sc, s7_pointer args) {return(s7_apply_5(s7, args, InName));} #define XEN_NARGIFY_6(OutName, InName) static s7_pointer OutName(s7_scheme *sc, s7_pointer args) {return(s7_apply_6(s7, args, InName));} #define XEN_NARGIFY_7(OutName, InName) static s7_pointer OutName(s7_scheme *sc, s7_pointer args) {return(s7_apply_7(s7, args, InName));} #define XEN_NARGIFY_8(OutName, InName) static s7_pointer OutName(s7_scheme *sc, s7_pointer args) {return(s7_apply_8(s7, args, InName));} #define XEN_NARGIFY_9(OutName, InName) static s7_pointer OutName(s7_scheme *sc, s7_pointer args) {return(s7_apply_9(s7, args, InName));} #define XEN_ARGIFY_1(OutName, InName) static s7_pointer OutName(s7_scheme *sc, s7_pointer args) {return(s7_apply_n_1(s7, args, InName));} #define XEN_ARGIFY_2(OutName, InName) static s7_pointer OutName(s7_scheme *sc, s7_pointer args) {return(s7_apply_n_2(s7, args, InName));} #define XEN_ARGIFY_3(OutName, InName) static s7_pointer OutName(s7_scheme *sc, s7_pointer args) {return(s7_apply_n_3(s7, args, InName));} #define XEN_ARGIFY_4(OutName, InName) static s7_pointer OutName(s7_scheme *sc, s7_pointer args) {return(s7_apply_n_4(s7, args, InName));} #define XEN_ARGIFY_5(OutName, InName) static s7_pointer OutName(s7_scheme *sc, s7_pointer args) {return(s7_apply_n_5(s7, args, InName));} #define XEN_ARGIFY_6(OutName, InName) static s7_pointer OutName(s7_scheme *sc, s7_pointer args) {return(s7_apply_n_6(s7, args, InName));} #define XEN_ARGIFY_7(OutName, InName) static s7_pointer OutName(s7_scheme *sc, s7_pointer args) {return(s7_apply_n_7(s7, args, InName));} #define XEN_ARGIFY_8(OutName, InName) static s7_pointer OutName(s7_scheme *sc, s7_pointer args) {return(s7_apply_n_8(s7, args, InName));} #define XEN_ARGIFY_9(OutName, InName) static s7_pointer OutName(s7_scheme *sc, s7_pointer args) {return(s7_apply_n_9(s7, args, InName));} #define XEN_VARGIFY(OutName, InName) static s7_pointer OutName(s7_scheme *sc, s7_pointer args) {return(InName(args));} #define XEN_DEFINE_PROCEDURE(Name, Func, ReqArg, OptArg, RstArg, Doc) s7_define_function(s7, Name, Func, ReqArg, OptArg, RstArg, Doc) #define XEN_DEFINE_SAFE_PROCEDURE(Name, Func, ReqArg, OptArg, RstArg, Doc) s7_define_safe_function(s7, Name, Func, ReqArg, OptArg, RstArg, Doc) #define XEN_DEFINE_PROCEDURE_STAR(Name, Func, Args, Doc) s7_define_function_star(s7, Name, Func, Args, Doc) #define XEN_DEFINE_PROCEDURE_WITH_SETTER(Get_Name, Get_Func, Get_Help, Set_Name, Set_Func, Get_Req, Get_Opt, Set_Req, Set_Opt) \ s7_dilambda(s7, Get_Name, Get_Func, Get_Req, Get_Opt, Set_Func, Set_Req, Set_Opt, Get_Help) #define XEN_ARITY(Func) s7_arity(s7, Func) #define XEN_REQUIRED_ARGS(Func) XEN_TO_C_INT(XEN_CAR(XEN_ARITY(Func))) #define XEN_REQUIRED_ARGS_OK(Func, Args) s7_is_aritable(s7, Func, Args) /* (XEN_REQUIRED_ARGS(Func) == Args) */ #define XEN_CALL_0(Func, Caller) s7_call_with_location(s7, Func, XEN_EMPTY_LIST, Caller, __FILE__, __LINE__) /* these need a catch */ #define XEN_CALL_1(Func, Arg1, Caller) s7_call_with_location(s7, Func, XEN_LIST_1(Arg1), Caller, __FILE__, __LINE__) #define XEN_CALL_2(Func, Arg1, Arg2, Caller) s7_call_with_location(s7, Func, XEN_LIST_2(Arg1, Arg2), Caller, __FILE__, __LINE__) #define XEN_CALL_3(Func, Arg1, Arg2, Arg3, Caller) s7_call_with_location(s7, Func, XEN_LIST_3(Arg1, Arg2, Arg3), Caller, __FILE__, __LINE__) #define XEN_CALL_4(Func, Arg1, Arg2, Arg3, Arg4, Caller) s7_call_with_location(s7, Func, XEN_LIST_4(Arg1, Arg2, Arg3, Arg4), Caller, __FILE__, __LINE__) #define XEN_CALL_5(Func, Arg1, Arg2, Arg3, Arg4, Arg5, Caller) s7_call_with_location(s7, Func, XEN_LIST_5(Arg1, Arg2, Arg3, Arg4, Arg5), Caller, __FILE__, __LINE__) #define XEN_CALL_6(Func, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Caller) s7_call_with_location(s7, Func, XEN_LIST_6(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6), Caller, __FILE__, __LINE__) #define XEN_APPLY(Func, Args, Caller) s7_call_with_location(s7, Func, Args, Caller, __FILE__, __LINE__) #define XEN_CALL_0_NO_CATCH(Func) s7_call_with_location(s7, Func, XEN_EMPTY_LIST, __func__, __FILE__, __LINE__) #define XEN_CALL_1_NO_CATCH(Func, Arg1) s7_call_with_location(s7, Func, XEN_LIST_1(Arg1), __func__, __FILE__, __LINE__) #define XEN_CALL_2_NO_CATCH(Func, Arg1, Arg2) s7_call_with_location(s7, Func, XEN_LIST_2(Arg1, Arg2), __func__, __FILE__, __LINE__) #define XEN_CALL_3_NO_CATCH(Func, Arg1, Arg2, Arg3) s7_call_with_location(s7, Func, XEN_LIST_3(Arg1, Arg2, Arg3), __func__, __FILE__, __LINE__) #define XEN_APPLY_NO_CATCH(Func, Args) s7_call_with_location(s7, Func, Args, __func__, __FILE__, __LINE__) typedef XEN (*XEN_CATCH_BODY_TYPE) (void *data); #define XEN_DEFINE_CONSTANT(Name, Value, Help) s7_define_constant_with_documentation(s7, Name, s7_make_integer(s7, Value), Help) #define XEN_DEFINE(Name, Value) s7_define_variable(s7, Name, Value) #define XEN_DEFINED_P(Name) s7_is_defined(s7, Name) #define XEN_DEFINE_VARIABLE(Name, Var, Value) Var = s7_define_variable(s7, Name, Value) #define XEN_VARIABLE_SET(Var, Val) s7_symbol_set_value(s7, Var, Val) #define XEN_VARIABLE_REF(Var) s7_symbol_value(s7, Var) #define XEN_NAME_AS_C_STRING_TO_VARIABLE(a) s7_make_symbol(s7, a) #define XEN_MARK_OBJECT_TYPE void #define XEN_MAKE_OBJECT_TYPE(Name, Print, Free, Equal, Gc_Mark, Apply, Set, Length, Copy, Reverse, Fill) \ s7_new_type_x(Name, Print, Free, Equal, Gc_Mark, Apply, Set, Length, Copy, Reverse, Fill) #define XEN_MAKE_OBJECT_FREE_PROCEDURE(Type, Wrapped_Free, Original_Free) \ static void Wrapped_Free(void *obj) {Original_Free((Type *)obj);} #define XEN_MAKE_OBJECT_PRINT_PROCEDURE(Type, Wrapped_Print, Original_Print) \ static char *Wrapped_Print(s7_scheme *sc, void *obj) {return(Original_Print((Type *)obj));} #define XEN_MAKE_AND_RETURN_OBJECT(Tag, Val, ig1, ig2) return(s7_make_object(s7, Tag, Val)) #define XEN_MAKE_OBJECT(Tag, Val, ig1, ig2) s7_make_object(s7, Tag, Val) #define XEN_OBJECT_REF(Arg) s7_object_value(Arg) #define XEN_OBJECT_TYPE int /* tag type */ #define XEN_OBJECT_TYPE_P(Obj, Tag) (s7_object_type(Obj) == Tag) #define XEN_HOOK_P(Arg) ((Arg) != XEN_FALSE) #define XEN_DEFINE_HOOK(Name, Descr, Arity, Help) s7_define_constant_with_documentation(s7, Name, s7_eval_c_string(s7, Descr), Help) /* "simple hooks are for channel-local hooks (unnamed, accessed through the channel) */ #define XEN_DEFINE_SIMPLE_HOOK(Descr, Arity) s7_eval_c_string(s7, Descr) #define XEN_HOOKED(Hook) s7_is_pair(s7_hook_functions(s7, Hook)) #define XEN_CLEAR_HOOK(Hook) s7_hook_set_functions(s7, Hook, s7_nil(s7)) #define XEN_HOOK_PROCEDURES(Hook) s7_hook_functions(s7, Hook) #define XEN_ADD_HOOK(Hook, Func, Name, Doc) s7_hook_set_functions(s7, Hook, s7_cons(s7, s7_make_function(s7, Name, Func, 1, 0, false, Doc), s7_hook_functions(s7, Hook))) #ifdef __cplusplus extern "C" { #endif s7_scheme *s7_xen_initialize(s7_scheme *sc); void xen_s7_set_repl_prompt(const char *new_prompt); XEN xen_set_assoc(s7_scheme *sc, s7_pointer key, s7_pointer val, s7_pointer alist); XEN xen_assoc(s7_scheme *sc, XEN key, XEN alist); #ifdef __cplusplus } #endif #endif /* end s7 */ /* ------------------------------ NO EXTENSION LANGUAGE ------------------------------ */ #ifndef XEN_OK #define XEN int #define XEN_FILE_EXTENSION "txt" #define XEN_LANGUAGE_NAME "What Language?" #define XEN_COMMENT_STRING ";" #define XEN_FALSE 0 #define XEN_TRUE 1 #define XEN_TRUE_P(a) ((a) == XEN_TRUE) #define XEN_FALSE_P(a) ((a) == XEN_FALSE) #define XEN_BOOLEAN_P(Arg) 0 #define C_TO_XEN_BOOLEAN(a) 0 #define XEN_TO_C_BOOLEAN(a) 0 #define XEN_NULL_P(a) ((a) == XEN_EMPTY_LIST) #define XEN_BOUND_P(Arg) 0 #define XEN_EMPTY_LIST 0 #define XEN_UNDEFINED 0 #define XEN_EQ_P(a, b) 0 #define XEN_CONS_P(Arg) 0 #define XEN_CONS(Arg1, Arg2) 0 #define XEN_CONS_2(Arg1, Arg2, Arg3) 0 #define XEN_PAIR_P(Arg) 0 #define XEN_CAR(a) 0 #define XEN_CADR(a) 0 #define XEN_CADDR(a) 0 #define XEN_CADDDR(a) 0 #define XEN_CDR(a) 0 #define XEN_CDDR(a) 0 #define XEN_CDDDR(a) 0 #define XEN_LIST_P(Arg) 0 #define XEN_LIST_P_WITH_LENGTH(Arg, Len) 0 #define XEN_LIST_LENGTH(Arg) 0 #define XEN_LIST_1(a) 0 #define XEN_LIST_2(a, b) 0 #define XEN_LIST_3(a, b, c) 0 #define XEN_LIST_4(a, b, c, d) 0 #define XEN_LIST_5(a, b, c, d, e) 0 #define XEN_LIST_6(a, b, c, d, e, f) 0 #define XEN_LIST_7(a, b, c, d, e, f, g) 0 #define XEN_LIST_8(a, b, c, d, e, f, g, h) 0 #define XEN_LIST_9(a, b, c, d, e, f, g, h, i) 0 #define XEN_LIST_REF(Lst, Num) 0 #define XEN_LIST_SET(Lst, Num, Val) #define XEN_LIST_REVERSE(Lst) 0 #define XEN_COPY_ARG(Lst) Lst #define XEN_APPEND(X, Y) 0 #define XEN_STRING_P(Arg) 0 #define XEN_NAME_AS_C_STRING_TO_VALUE(a) 0 #define XEN_TO_C_STRING(STR) "(not a string)" #define C_TO_XEN_STRING(a) 0 #define C_TO_XEN_STRINGN(Str, Len) 0 #define C_STRING_TO_XEN_SYMBOL(a) 0 #define XEN_ZERO 0 #define XEN_NUMBER_P(Arg) 0 #define XEN_DOUBLE_P(Arg) 0 #define XEN_TO_C_DOUBLE(a) 0.0 #define C_TO_XEN_DOUBLE(a) 0 #define XEN_INTEGER_P(Arg) 0 #define C_TO_XEN_INT(a) a #define XEN_TO_C_INT(a) 0 #define XEN_COMPLEX_P(Arg) 0 #define XEN_TO_C_COMPLEX(a) 0.0 #define C_TO_XEN_COMPLEX(a) a #define XEN_ULONG_P(Arg) 0 #define XEN_TO_C_ULONG(a) 0 #define C_TO_XEN_ULONG(a) 0 #define C_TO_XEN_LONG_LONG(a) a #define XEN_TO_C_LONG_LONG(a) a #define XEN_ULONG_LONG_P(Arg) 0 #define XEN_TO_C_ULONG_LONG(Arg) 0 #define C_TO_XEN_ULONG_LONG(Arg) 0 #define XEN_WRAPPED_C_POINTER_P(Arg) 0 #define XEN_EVAL_C_STRING(Arg) 0 #define XEN_SYMBOL_TO_C_STRING(a) "(not a symbol)" #define XEN_TO_STRING(Obj) "(unknown)" #define XEN_PROCEDURE_P(Arg) 0 #define XEN_ARGIFY_1(OutName, InName) static int OutName(void) {return(-1);} #define XEN_ARGIFY_2(OutName, InName) static int OutName(void) {return(-2);} #define XEN_ARGIFY_3(OutName, InName) static int OutName(void) {return(-3);} #define XEN_ARGIFY_4(OutName, InName) static int OutName(void) {return(-4);} #define XEN_ARGIFY_5(OutName, InName) static int OutName(void) {return(-5);} #define XEN_ARGIFY_6(OutName, InName) static int OutName(void) {return(-6);} #define XEN_ARGIFY_7(OutName, InName) static int OutName(void) {return(-7);} #define XEN_ARGIFY_8(OutName, InName) static int OutName(void) {return(-8);} #define XEN_ARGIFY_9(OutName, InName) static int OutName(void) {return(-9);} #define XEN_NARGIFY_0(OutName, InName) static int OutName(void) {return(0);} #define XEN_NARGIFY_1(OutName, InName) static int OutName(void) {return(1);} #define XEN_NARGIFY_2(OutName, InName) static int OutName(void) {return(2);} #define XEN_NARGIFY_3(OutName, InName) static int OutName(void) {return(3);} #define XEN_NARGIFY_4(OutName, InName) static int OutName(void) {return(4);} #define XEN_NARGIFY_5(OutName, InName) static int OutName(void) {return(5);} #define XEN_NARGIFY_6(OutName, InName) static int OutName(void) {return(6);} #define XEN_NARGIFY_7(OutName, InName) static int OutName(void) {return(7);} #define XEN_NARGIFY_8(OutName, InName) static int OutName(void) {return(8);} #define XEN_NARGIFY_9(OutName, InName) static int OutName(void) {return(9);} #define XEN_VARGIFY(OutName, InName) static int OutName(void) {return(-100);} #define XEN_DEFINE_PROCEDURE(Name, Func, ReqArg, OptArg, RstArg, Doc) \ xen_no_ext_lang_check_args(Name, Func(), ReqArg, OptArg, RstArg) #define XEN_DEFINE_PROCEDURE_WITH_SETTER(Get_Name, Get_Func, Get_Help, Set_Name, Set_Func, Get_Req, Get_Opt, Set_Req, Set_Opt) \ {xen_no_ext_lang_check_args(Get_Name, Get_Func(), Get_Req, Get_Opt, 0); xen_no_ext_lang_check_args(Set_Name, Set_Func(), Set_Req, Set_Opt, 0);} #define XEN_DEFINE_SAFE_PROCEDURE(Name, Func, ReqArg, OptArg, RstArg, Doc) XEN_DEFINE_PROCEDURE(Name, Func, ReqArg, OptArg, RstArg, Doc) #define XEN_ARITY(Func) 0 #define XEN_REQUIRED_ARGS(Func) 0 #define XEN_REQUIRED_ARGS_OK(Func, Args) false #define XEN_CALL_0(Func, Caller) 0 #define XEN_CALL_1(Func, Arg1, Caller) 0 #define XEN_CALL_2(Func, Arg1, Arg2, Caller) 0 #define XEN_CALL_3(Func, Arg1, Arg2, Arg3, Caller) 0 #define XEN_CALL_4(Func, Arg1, Arg2, Arg3, Arg4, Caller) 0 #define XEN_CALL_5(Func, Arg1, Arg2, Arg3, Arg4, Arg5, Caller) 0 #define XEN_CALL_6(Func, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Caller) 0 #define XEN_APPLY(Func, Args, Caller) 0 #define XEN_CALL_0_NO_CATCH(Func) 0 #define XEN_CALL_1_NO_CATCH(Func, Arg1) 0 #define XEN_CALL_2_NO_CATCH(Func, Arg1, Arg2) 0 #define XEN_CALL_3_NO_CATCH(Func, Arg1, Arg2, Arg3) 0 #define XEN_APPLY_NO_CATCH(Func, Args) 0 #define XEN_DEFINE_CONSTANT(a, b, c) #define XEN_DEFINE_VARIABLE(a, b, c) #define XEN_DEFINE(Name, Value) #define XEN_VARIABLE_SET(a, b) #define XEN_VARIABLE_REF(a) 0 #define XEN_MARK_OBJECT_TYPE XEN #define XEN_MAKE_OBJECT_TYPE(Typ, Siz) 0 #define XEN_MAKE_OBJECT_PRINT_PROCEDURE(Type, Wrapped_Print, Original_Print) #define XEN_MAKE_OBJECT_FREE_PROCEDURE(Type, Wrapped_Free, Original_Free) #define XEN_MAKE_AND_RETURN_OBJECT(Tag, Val, ig1, ig2) return(0) #define XEN_MAKE_OBJECT(Tag, Val, ig1, ig2) 0 #define XEN_OBJECT_REF(a) 0 #define XEN_OBJECT_TYPE int #define XEN_OBJECT_TYPE_P(OBJ, TAG) 0 #define XEN_SYMBOL_P(Arg) 0 #define XEN_HOOK_P(Arg) 0 #define XEN_HOOKED(a) 0 #define XEN_DEFINE_HOOK(Name, Descr, Arity, Help) 0 #define XEN_DEFINE_SIMPLE_HOOK(Descr, Arity) 0 #define XEN_CLEAR_HOOK(Arg) #define XEN_HOOK_PROCEDURES(a) 0 #define XEN_ADD_HOOK(Hook, Func, Name, Doc) #define XEN_VECTOR_P(Arg) 0 #define XEN_VECTOR_LENGTH(Arg) 0 #define XEN_VECTOR_REF(Vect, Num) 0 #define XEN_VECTOR_SET(a, b, c) #define XEN_MAKE_VECTOR(Num, Fill) 0 #define XEN_VECTOR_TO_LIST(Vect) 0 #define XEN_ASSOC_REF(Sym, Lst) 0 #define XEN_ASSOC_SET(Sym, Val, Lst) 0 #define XEN_CHAR_P(Arg) 0 #define XEN_TO_C_CHAR(Arg) 0 #define C_TO_XEN_CHAR(Arg) 0 #define XEN_KEYWORD_P(Obj) 0 #define XEN_KEYWORD_EQ_P(k1, k2) 0 #define XEN_MAKE_KEYWORD(Arg) 0 #define XEN_PROVIDE(Feature) #define XEN_DOCUMENTATION_SYMBOL 0 #define XEN_OBJECT_HELP(Name) 0 #define XEN_PROTECT_FROM_GC(a) 0 #define XEN_LOAD_FILE(a) 0 #define XEN_LOAD_PATH XEN_FALSE #define XEN_ADD_TO_LOAD_PATH(Path) XEN_FALSE #define XEN_ERROR_TYPE(Typ) XEN_FALSE #define XEN_ERROR(Type, Info) fprintf(stderr, "error") #define XEN_THROW(Type, Info) fprintf(stderr, "error") #define XEN_ASSERT_TYPE(Assertion, Arg, Position, Caller, Correct_Type) #define XEN_WRONG_TYPE_ARG_ERROR(Caller, ArgN, Arg, Descr) #define XEN_OUT_OF_RANGE_ERROR(Caller, ArgN, Arg, Descr) typedef XEN (*XEN_CATCH_BODY_TYPE) (void *data); #define XEN_UNPROTECT_FROM_GC(Var) 0 #ifdef __cplusplus extern "C" { #endif void xen_no_ext_lang_check_args(const char *name, int args, int req_args, int opt_args, int rst_args); #ifdef __cplusplus } #endif #endif /* end NO EXTENSION LANGUAGE */ #define XEN_NOT_TRUE_P(a) (!(XEN_TRUE_P(a))) #define XEN_NOT_FALSE_P(a) (!(XEN_FALSE_P(a))) #define XEN_NOT_NULL_P(a) (!(XEN_NULL_P(a))) #define XEN_NOT_BOUND_P(Arg) (!(XEN_BOUND_P(Arg))) #if defined(__GNUC__) && (!(defined(__cplusplus))) #define XEN_BOOLEAN_IF_BOUND_P(Arg) ({ XEN _xen_h_14_ = Arg; ((XEN_BOOLEAN_P(_xen_h_14_)) || (XEN_NOT_BOUND_P(_xen_h_14_))); }) #define XEN_INTEGER_IF_BOUND_P(Arg) ({ XEN _xen_h_15_ = Arg; ((XEN_NOT_BOUND_P(_xen_h_15_)) || (XEN_INTEGER_P(_xen_h_15_))); }) #define XEN_NUMBER_IF_BOUND_P(Arg) ({ XEN _xen_h_16_ = Arg; ((XEN_NOT_BOUND_P(_xen_h_16_)) || (XEN_NUMBER_P(_xen_h_16_))); }) #define XEN_STRING_IF_BOUND_P(Arg) ({ XEN _xen_h_17_ = Arg; ((XEN_NOT_BOUND_P(_xen_h_17_)) || (XEN_STRING_P(_xen_h_17_))); }) #define XEN_INTEGER_OR_BOOLEAN_IF_BOUND_P(Arg) ({ XEN _xen_h_18_ = Arg; ((XEN_BOOLEAN_P(_xen_h_18_)) || (XEN_NOT_BOUND_P(_xen_h_18_)) || (XEN_INTEGER_P(_xen_h_18_))); }) #define XEN_INTEGER_OR_BOOLEAN_P(Arg) ({ XEN _xen_h_21_ = Arg; ((XEN_BOOLEAN_P(_xen_h_21_)) || (XEN_INTEGER_P(_xen_h_21_))); }) #else #define XEN_BOOLEAN_IF_BOUND_P(Arg) ((XEN_BOOLEAN_P(Arg)) || (XEN_NOT_BOUND_P(Arg))) #define XEN_INTEGER_IF_BOUND_P(Arg) ((XEN_NOT_BOUND_P(Arg)) || (XEN_INTEGER_P(Arg))) #define XEN_NUMBER_IF_BOUND_P(Arg) ((XEN_NOT_BOUND_P(Arg)) || (XEN_NUMBER_P(Arg))) #define XEN_STRING_IF_BOUND_P(Arg) ((XEN_NOT_BOUND_P(Arg)) || (XEN_STRING_P(Arg))) #define XEN_INTEGER_OR_BOOLEAN_IF_BOUND_P(Arg) ((XEN_BOOLEAN_P(Arg)) || (XEN_NOT_BOUND_P(Arg)) || (XEN_INTEGER_P(Arg))) #define XEN_INTEGER_OR_BOOLEAN_P(Arg) ((XEN_BOOLEAN_P(Arg)) || (XEN_INTEGER_P(Arg))) #endif #if (!HAVE_FORTH) #define XEN_LONG_LONG_P(Arg) XEN_INTEGER_P(Arg) #else #define XEN_LONG_LONG_P(Arg) FTH_LONG_LONG_P(Arg) #endif #define XEN_LONG_LONG_IF_BOUND_P(Arg) ((XEN_NOT_BOUND_P(Arg)) || (XEN_LONG_LONG_P(Arg))) #if (!HAVE_SCHEME) #define XEN_AS_STRING(form) XEN_TO_C_STRING(XEN_TO_STRING(form)) #define XEN_VECTOR_RANK(Vect) 1 #else #define XEN_AS_STRING(form) s7_object_to_c_string(s7, form) #endif #define XEN_BAD_ARITY_ERROR(Caller, ArgN, Arg, Descr) \ XEN_ERROR(XEN_ERROR_TYPE("bad-arity"), \ XEN_LIST_3(C_TO_XEN_STRING(Caller), \ C_TO_XEN_STRING(Descr), \ Arg)) #ifndef XEN_HAVE_RATIOS #define XEN_NUMERATOR(Arg) 0 #define XEN_DENOMINATOR(Arg) 1 #define XEN_RATIONALIZE(Arg1, Arg2) 1 #define XEN_RATIO_P(Arg) false #define XEN_MAKE_RATIO(Num, Den) 1 #endif #ifndef XEN_DEFINED_P #define XEN_DEFINED_P(Name) false #endif /* (need a way to pass an uninterpreted pointer from C to XEN then back to C) */ #if HAVE_SCHEME #define XEN_WRAP_C_POINTER(a) s7_make_c_pointer(s7, (void *)(a)) #define XEN_UNWRAP_C_POINTER(a) s7_c_pointer(a) #else #if (SIZEOF_VOID_P == 4) #define XEN_WRAP_C_POINTER(a) ((XEN)(C_TO_XEN_ULONG((unsigned int)a))) #define XEN_UNWRAP_C_POINTER(a) XEN_TO_C_ULONG(a) #else #define XEN_WRAP_C_POINTER(a) C_TO_XEN_ULONG_LONG((unsigned long long int)(a)) #define XEN_UNWRAP_C_POINTER(a) XEN_TO_C_ULONG_LONG(a) #endif #endif /* Feb-14: the upper case macro names and the old-fashioned _p names are ugly and hard to read -- start replacing them */ #define Xen_is_number(Arg) XEN_NUMBER_P(Arg) #define Xen_is_integer(Arg) XEN_INTEGER_P(Arg) #define Xen_is_llong(Arg) XEN_LONG_LONG_P(Arg) #define Xen_is_keyword(Arg) XEN_KEYWORD_P(Arg) #define Xen_is_true(Arg) XEN_TRUE_P(Arg) #define Xen_is_false(Arg) XEN_FALSE_P(Arg) #define Xen_is_bound(Arg) XEN_BOUND_P(Arg) #define Xen_is_boolean(Arg) XEN_BOOLEAN_P(Arg) #define Xen_is_null(Arg) XEN_NULL_P(Arg) #define Xen_is_eq(Arg1, Arg2) XEN_EQ_P(Arg1, Arg2) #define Xen_is_cons(Arg) XEN_CONS_P(Arg) #define Xen_is_pair(Arg) XEN_PAIR_P(Arg) #define Xen_is_list(Arg) XEN_LIST_P(Arg) #define Xen_is_string(Arg) XEN_STRING_P(Arg) #define Xen_is_double(Arg) XEN_DOUBLE_P(Arg) #define Xen_is_complex(Arg) XEN_COMPLEX_P(Arg) #define Xen_is_ulong(Arg) XEN_ULONG_P(Arg) #define Xen_is_ullong(Arg) XEN_ULONG_LONG_P(Arg) #define Xen_is_wrapped_c_pointer(Arg) XEN_WRAPPED_C_POINTER_P(Arg) #define Xen_is_procedure(Arg) XEN_PROCEDURE_P(Arg) #define Xen_c_object_is_type(Obj, Tag) XEN_OBJECT_TYPE_P(Obj, Tag) #define Xen_is_symbol(Arg) XEN_SYMBOL_P(Arg) #define Xen_is_hook(Arg) XEN_HOOK_P(Arg) #define Xen_is_vector(Arg) XEN_VECTOR_P(Arg) #define Xen_is_char(Arg) XEN_CHAR_P(Arg) #define Xen_keyword_is_eq(Arg1, Arg2) XEN_KEYWORD_EQ_P(Arg1, Arg2) #define Xen_is_defined(Arg) XEN_DEFINED_P(Arg) #define Xen_is_ratio(Arg) XEN_RATIO_P(Arg) #define Xen_is_llong_or_unbound(Arg) XEN_LONG_LONG_IF_BOUND_P(Arg) #define Xen_is_boolean_or_unbound(Arg) XEN_BOOLEAN_IF_BOUND_P(Arg) #define Xen_is_integer_or_unbound(Arg) XEN_INTEGER_IF_BOUND_P(Arg) #define Xen_is_number_or_unbound(Arg) XEN_NUMBER_IF_BOUND_P(Arg) #define Xen_is_string_or_unbound(Arg) XEN_STRING_IF_BOUND_P(Arg) #define Xen_is_integer_boolean_or_unbound(Arg) XEN_INTEGER_OR_BOOLEAN_IF_BOUND_P(Arg) #define Xen_is_integer_or_boolean(Arg) XEN_INTEGER_OR_BOOLEAN_P(Arg) #define Xen_append(a, b) XEN_APPEND(a, b) #define Xen_cadddr(a) XEN_CADDDR(a) #define Xen_caddr(a) XEN_CADDR(a) #define Xen_cadr(a) XEN_CADR(a) #define Xen_car(a) XEN_CAR(a) #define Xen_cddr(a) XEN_CDDR(a) #define Xen_cdddr(a) XEN_CDDDR(a) #define Xen_cdr(a) XEN_CDR(a) #define Xen_cons(a, b) XEN_CONS(a, b) #define Xen_cons_2(a, b, c) XEN_CONS_2(a, b, c) #define Xen_list_1(a) XEN_LIST_1(a) #define Xen_list_2(a, b) XEN_LIST_2(a, b) #define Xen_list_3(a, b, c) XEN_LIST_3(a, b, c) #define Xen_list_4(a, b, c, d) XEN_LIST_4(a, b, c, d) #define Xen_list_5(a, b, c, d, e) XEN_LIST_5(a, b, c, d, e) #define Xen_list_6(a, b, c, d, e, f) XEN_LIST_6(a, b, c, d, e, f) #define Xen_list_7(a, b, c, d, e, f, g) XEN_LIST_7(a, b, c, d, e, f, g) #define Xen_list_8(a, b, c, d, e, f, g, h) XEN_LIST_8(a, b, c, d, e, f, g, h) #define Xen_list_9(a, b, c, d, e, f, g, h, i) XEN_LIST_9(a, b, c, d, e, f, g, h, i) #define Xen_list_length(a) XEN_LIST_LENGTH(a) #define Xen_list_ref(a, b) XEN_LIST_REF(a, b) #define Xen_list_reverse(a) XEN_LIST_REVERSE(a) #define Xen_list_set(a, b, c) XEN_LIST_SET(a, b, c) #define Xen_member(a, b) XEN_MEMBER(a, b) #define Xen_make_keyword(a) XEN_MAKE_KEYWORD(a) #define Xen_make_vector(a, b) XEN_MAKE_VECTOR(a, b) #define Xen_throw(a) XEN_THROW(a) #define Xen_vector_length(a) XEN_VECTOR_LENGTH(a) #define Xen_vector_ref(a, b) XEN_VECTOR_REF(a, b) #define Xen_vector_set(a, b, c) XEN_VECTOR_SET(a, b, c) #define Xen_vector_to_Xen_list(a) XEN_VECTOR_TO_LIST(a) #define C_bool_to_Xen_boolean(a) C_TO_XEN_BOOLEAN(a) #define C_char_to_Xen_char(a) C_TO_XEN_CHAR(a) #define C_complex_to_Xen_complex(a) C_TO_XEN_COMPLEX(a) #define C_double_to_Xen_real(a) C_TO_XEN_DOUBLE(a) #define C_int_to_Xen_integer(a) C_TO_XEN_INT(a) #define C_llong_to_Xen_llong(a) C_TO_XEN_LONG_LONG(a) #define C_string_to_Xen_string(a) C_TO_XEN_STRING(a) #define C_string_to_Xen_string_with_length(a, b) C_TO_XEN_STRINGN(a, b) #define C_string_to_Xen_symbol(a) C_STRING_TO_XEN_SYMBOL(a) #define C_ulong_to_Xen_ulong(a) C_TO_XEN_ULONG(a) #define C_ullong_to_Xen_ullong(a) C_TO_XEN_ULONG_LONG(a) #define Xen_boolean_to_C_bool(a) XEN_TO_C_BOOLEAN(a) #define Xen_char_to_C_char(a) XEN_TO_C_CHAR(a) #define Xen_complex_to_C_complex(a) XEN_TO_C_COMPLEX(a) #define Xen_real_to_C_double(a) XEN_TO_C_DOUBLE(a) #define Xen_integer_to_C_int(a) XEN_TO_C_INT(a) #define Xen_llong_to_C_llong(a) XEN_TO_C_LONG_LONG(a) #define Xen_string_to_C_string(a) XEN_TO_C_STRING(a) #define Xen_symbol_to_C_string(a) XEN_SYMBOL_TO_C_STRING(a) #define C_string_to_Xen_value(a) XEN_NAME_AS_C_STRING_TO_VALUE(a) #define Xen_ulong_to_C_ulong(a) XEN_TO_C_ULONG(a) #define Xen_ullong_to_C_ullong(a) XEN_TO_C_ULONG_LONG(a) #define Xen_wrap_C_pointer(a) XEN_WRAP_C_POINTER(a) #define Xen_unwrap_C_pointer(a) XEN_UNWRAP_C_POINTER(a) #define Xen_numerator(a) XEN_NUMERATOR(a) #define Xen_denominator(a) XEN_DENOMINATOR(a) #define Xen_rationalize(a, b) XEN_RATIONALIZE(a, b) #define Xen_make_ratio(a, b) XEN_MAKE_RATIO(a, b) #define Xen_load(a) XEN_LOAD_FILE(a) #define Xen_documentation(a) XEN_OBJECT_HELP(a) #define Xen_vector_rank(a) XEN_VECTOR_RANK(a) #define Xen_wrap_no_args(a, b) XEN_NARGIFY_0(a, b) #define Xen_wrap_1_arg(a, b) XEN_NARGIFY_1(a, b) #define Xen_wrap_2_args(a, b) XEN_NARGIFY_2(a, b) #define Xen_wrap_3_args(a, b) XEN_NARGIFY_3(a, b) #define Xen_wrap_4_args(a, b) XEN_NARGIFY_4(a, b) #define Xen_wrap_5_args(a, b) XEN_NARGIFY_5(a, b) #define Xen_wrap_6_args(a, b) XEN_NARGIFY_6(a, b) #define Xen_wrap_7_args(a, b) XEN_NARGIFY_7(a, b) #define Xen_wrap_8_args(a, b) XEN_NARGIFY_8(a, b) #define Xen_wrap_9_args(a, b) XEN_NARGIFY_9(a, b) #define Xen_wrap_1_optional_arg(a, b) XEN_ARGIFY_1(a, b) #define Xen_wrap_2_optional_args(a, b) XEN_ARGIFY_2(a, b) #define Xen_wrap_3_optional_args(a, b) XEN_ARGIFY_3(a, b) #define Xen_wrap_4_optional_args(a, b) XEN_ARGIFY_4(a, b) #define Xen_wrap_5_optional_args(a, b) XEN_ARGIFY_5(a, b) #define Xen_wrap_6_optional_args(a, b) XEN_ARGIFY_6(a, b) #define Xen_wrap_7_optional_args(a, b) XEN_ARGIFY_7(a, b) #define Xen_wrap_8_optional_args(a, b) XEN_ARGIFY_8(a, b) #define Xen_wrap_9_optional_args(a, b) XEN_ARGIFY_9(a, b) #define Xen_wrap_any_args(a, b) XEN_VARGIFY(a, b) #define Xen_apply(a, b, c) XEN_APPLY(a, b, c) #define Xen_unprotected_apply(a, b) XEN_APPLY_NO_CATCH(a, b) #define Xen_eval_C_string(a) XEN_EVAL_C_STRING(a) #define Xen_error(a, b) XEN_ERROR(a, b) #define Xen_call_with_no_args(a, b) XEN_CALL_0(a, b) #define Xen_call_with_1_arg(a, b, c) XEN_CALL_1(a, b, c) #define Xen_call_with_2_args(a, b, c, d) XEN_CALL_2(a, b, c, d) #define Xen_call_with_3_args(a, b, c, d, e) XEN_CALL_3(a, b, c, d, e) #define Xen_call_with_4_args(a, b, c, d, e, f) XEN_CALL_4(a, b, c, d, e, f) #define Xen_call_with_5_args(a, b, c, d, e, f, g) XEN_CALL_5(a, b, c, d, e, f, g) #define Xen_call_with_6_args(a, b, c, d, e, f, g, h) XEN_CALL_6(a, b, c, d, e, f, g, h) #define Xen_unprotected_call_with_no_args(a) XEN_CALL_0_NO_CATCH(a) #define Xen_unprotected_call_with_1_arg(a, b) XEN_CALL_1_NO_CATCH(a, b) #define Xen_unprotected_call_with_2_args(a, b, c) XEN_CALL_2_NO_CATCH(a, b, c) #define Xen_unprotected_call_with_3_args(a, b, c, d) XEN_CALL_3_NO_CATCH(a, b, c, d) #define Xen_define(a, b) XEN_DEFINE(a, b) #define Xen_define_constant(a, b, c) XEN_DEFINE_CONSTANT(a, b, c) #define Xen_define_hook(a, b, c, d) XEN_DEFINE_HOOK(a, b, c, d) #define Xen_define_procedure(a, b, c, d, e, f) XEN_DEFINE_PROCEDURE(a, b, c, d, e, f) #define Xen_define_procedure_with_setter(a, b, c, d, e, f, g, h, i) XEN_DEFINE_PROCEDURE_WITH_SETTER(a, b, c, d, e, f, g, h, i) #define Xen_define_dilambda(a, b, c, d, e, f, g, h, i) XEN_DEFINE_PROCEDURE_WITH_SETTER(a, b, c, d, e, f, g, h, i) #define Xen_define_safe_procedure(a, b, c, d, e, f) XEN_DEFINE_SAFE_PROCEDURE(a, b, c, d, e, f) #define Xen_define_integer_procedure(a, b, c, d, e, f) XEN_DEFINE_SAFE_PROCEDURE(a, b, c, d, e, f) /*obsolete */ #define Xen_define_simple_hook(a, b) XEN_DEFINE_SIMPLE_HOOK(a, b) #define Xen_define_variable(a, b, c) XEN_DEFINE_VARIABLE(a, b, c) #define Xen_out_of_range_error(a, b, c, d) XEN_OUT_OF_RANGE_ERROR(a, b, c, d) #define Xen_wrong_type_arg_error(a, b, c, d) XEN_WRONG_TYPE_ARG_ERROR(a, b, c, d) #define Xen_bad_arity_error(a, b, c, d) XEN_BAD_ARITY_ERROR(a, b, c, d) #define Xen_clear_hook_list(a) XEN_CLEAR_HOOK(a) #define Xen_hook_has_list(a) XEN_HOOKED(a) #define Xen_hook_list(a) XEN_HOOK_PROCEDURES(a) #define Xen_add_to_hook_list(a, b, c, d) XEN_ADD_HOOK(a, b, c, d) #define Xen_GC_protect(a) XEN_PROTECT_FROM_GC(a) #define Xen_GC_unprotect(a) XEN_UNPROTECT_FROM_GC(a) #define Xen_provide_feature(a) XEN_PROVIDE(a) #define Xen_arity(a) XEN_ARITY(a) #define Xen_add_to_load_path(a) XEN_ADD_TO_LOAD_PATH(a) #define Xen_check_type(a, b, c, d, e) XEN_ASSERT_TYPE(a, b, c, d, e) #define Xen_make_object(a, b, c, d) XEN_MAKE_OBJECT(a, b, c, d) #define Xen_variable_ref(a) XEN_VARIABLE_REF(a) #define Xen_variable_set(a, b) XEN_VARIABLE_SET(a, b) #define Xen_object_ref(a) XEN_OBJECT_REF(a) #define Xen_copy_arg(a) XEN_COPY_ARG(a) #define Xen_assoc(a, b) XEN_ASSOC(a, b) #define Xen_assoc_ref(a, b) XEN_ASSOC_REF(a, b) #define Xen_assoc_set(a, b, c) XEN_ASSOC_SET(a, b, c) #define Xen_make_error_type(a) XEN_ERROR_TYPE(a) #define Xen_required_args(a) XEN_REQUIRED_ARGS(a) #define Xen_is_aritable(a, b) XEN_REQUIRED_ARGS_OK(a, b) #define Xen_object_to_C_string(a) XEN_AS_STRING(a) #define Xen_wrap_free(a, b, c) XEN_MAKE_OBJECT_FREE_PROCEDURE(a, b, c) #define Xen_wrap_print(a, b, c) XEN_MAKE_OBJECT_PRINT_PROCEDURE(a, b, c) #define Xen_make_object_type(a, b) XEN_MAKE_OBJECT_TYPE(a, b) #define Xen_object_mark_t XEN_MARK_OBJECT_TYPE #define Xen_object_type_t XEN_OBJECT_TYPE #define Xen_catch_t XEN_CATCH_BODY_TYPE #define Xen_comment_mark XEN_COMMENT_STRING #define Xen_documentation_symbol XEN_DOCUMENTATION_SYMBOL #define Xen_empty_list XEN_EMPTY_LIST #define Xen_false XEN_FALSE #define Xen_true XEN_TRUE #define Xen_undefined XEN_UNDEFINED #define Xen_integer_zero XEN_ZERO #define Xen_file_extension XEN_FILE_EXTENSION #define Xen_language XEN_LANGUAGE_NAME #define Xen_load_path XEN_LOAD_PATH #define Xen_procedure_cast XEN_PROCEDURE_CAST #define Xen XEN #if HAVE_SCHEME #define Xen_define_typed_procedure(Name, Func, ReqArg, OptArg, RstArg, Doc, Sig) s7_define_typed_function(s7, Name, Func, ReqArg, OptArg, RstArg, Doc, Sig) #define Xen_define_typed_dilambda(Get_Name, Get_Func, Get_Help, Set_Name, Set_Func, Get_Req, Get_Opt, Set_Req, Set_Opt, Get_Sig, Set_Sig) \ s7_typed_dilambda(s7, Get_Name, Get_Func, Get_Req, Get_Opt, Set_Func, Set_Req, Set_Opt, Get_Help, Get_Sig, Set_Sig) #else #define Xen_define_typed_procedure(Name, Func, ReqArg, OptArg, RstArg, Doc, Sig) Xen_define_safe_procedure(Name, Func, ReqArg, OptArg, RstArg, Doc) #define Xen_define_typed_dilambda(a, b, c, d, e, f, g, h, i, j, k) XEN_DEFINE_PROCEDURE_WITH_SETTER(a, b, c, d, e, f, g, h, i) #endif #ifdef __cplusplus extern "C" { #endif char *xen_strdup(const char *str); char *xen_version(void); void xen_repl(int argc, char **argv); void xen_initialize(void); void xen_gc_mark(XEN val); #ifdef __cplusplus } #endif #endif snd-16.1/snd-select.c0000644000076400007640000014547012555416060012557 0ustar bilbil#include "snd.h" #include "clm2xen.h" static bool cp_has_selection(chan_info *cp) { ed_list *ed; ed = cp->edits[cp->edit_ctr]; return((ed) && (ed->selection_beg != NO_SELECTION)); } static bool map_over_chans(bool (*func)(chan_info *ncp)) { /* non-zero = abort map, skips inactive sounds */ int i, j; bool val = false; for (i = 0; i < ss->max_sounds; i++) { snd_info *sp; chan_info *cp; sp = ss->sounds[i]; if ((sp) && (sp->inuse == SOUND_NORMAL)) for (j = 0; j < sp->nchans; j++) if ((cp = ((chan_info *)(sp->chans[j])))) if (cp) { val = (*func)(cp); if (val) return(val); } } return(val); } bool selection_is_active(void) { /* is selection active in any channel */ return(map_over_chans(cp_has_selection)); } bool selection_is_active_in_channel(chan_info *cp) { return((cp) && (cp_has_selection(cp))); } static bool selection_is_visible(chan_info *cp) { ed_list *ed; axis_info *ap; ed = cp->edits[cp->edit_ctr]; if (ed->selection_beg == NO_SELECTION) return(false); ap = cp->axis; return((ed) && (ap->losamp < ed->selection_end) && (ap->hisamp > ed->selection_beg)); } bool selection_is_visible_in_channel(chan_info *cp) { return((cp_has_selection(cp)) && (selection_is_visible(cp))); } static mus_long_t mus_long_t_map_over_chans(mus_long_t (*func)(chan_info *, mus_long_t *), mus_long_t *userptr) { int i, j; mus_long_t val = 0; for (i = 0; i < ss->max_sounds; i++) { snd_info *sp; chan_info *cp; sp = ss->sounds[i]; if ((sp) && (sp->inuse == SOUND_NORMAL)) for (j = 0; j < sp->nchans; j++) if ((cp = ((chan_info *)(sp->chans[j])))) { val = (*func)(cp, userptr); if (val) return(val); } } return(val); } static mus_long_t cp_selection_beg(chan_info *cp, mus_long_t *beg) { ed_list *ed; ed = cp->edits[cp->edit_ctr]; if (ed->selection_beg != NO_SELECTION) { beg[0] = ed->selection_beg; return(1); /* i.e. stop map_over_chans */ } return(0); } mus_long_t selection_beg(chan_info *cp) { mus_long_t beg[1]; beg[0] = 0; if (cp) cp_selection_beg(cp, beg); else mus_long_t_map_over_chans(cp_selection_beg, beg); return(beg[0]); } static int xen_selection_counter = 0; static void cp_set_selection_beg(chan_info *cp, mus_long_t beg) { ed_list *ed; mus_long_t len; ed = cp->edits[cp->edit_ctr]; len = current_samples(cp); if (beg < len) ed->selection_beg = beg; else ed->selection_beg = len - 1; xen_selection_counter++; ed->selection_maxamp = -1.0; ed->selection_maxamp_position = -1; } mus_long_t selection_end(chan_info *cp) /* never called without selection_member check in advance */ { return(cp->edits[cp->edit_ctr]->selection_end); } static mus_long_t cp_selection_len(chan_info *cp, mus_long_t *ptr) { ed_list *ed; ed = cp->edits[cp->edit_ctr]; if ((ed) && (ed->selection_beg != NO_SELECTION)) return(ed->selection_end - ed->selection_beg + 1); return(0); } mus_long_t selection_len(void) { return(mus_long_t_map_over_chans(cp_selection_len, NULL)); } static void cp_set_selection_len(chan_info *cp, mus_long_t len) { ed_list *ed; mus_long_t cplen; ed = cp->edits[cp->edit_ctr]; cplen = current_samples(cp); ed->selection_end = ed->selection_beg + len - 1; if (ed->selection_end >= cplen) ed->selection_end = cplen - 1; ed->selection_maxamp = -1.0; ed->selection_maxamp_position = -1; } static void selection_chans_1(chan_info *cp, int *counter) { if (cp_has_selection(cp)) counter[0]++; } int selection_chans(void) { int count[1]; count[0] = 0; for_each_normal_chan_with_refint(selection_chans_1, count); return(count[0]); } static mus_long_t selection_srate_1(chan_info *cp, mus_long_t *ignored) { if (cp_has_selection(cp)) return((mus_long_t)snd_srate(cp->sound)); return(0); } int selection_srate(void) { if (selection_is_active()) return((int)mus_long_t_map_over_chans(selection_srate_1, NULL)); return(0); } mus_float_t selection_maxamp(chan_info *cp) { mus_float_t val = 0.0; if (selection_is_active_in_channel(cp)) { mus_long_t maxpos = 0; val = ed_selection_maxamp(cp); if (val >= 0.0) return(val); val = channel_local_maxamp(cp, selection_beg(cp), selection_end(cp) - selection_beg(cp) + 1, cp->edit_ctr, &maxpos); set_ed_selection_maxamp(cp, val); set_ed_selection_maxamp_position(cp, maxpos); } return(val); } static mus_long_t selection_maxamp_position(chan_info *cp) { selection_maxamp(cp); return(ed_selection_maxamp_position(cp)); } void cp_delete_selection(chan_info *cp) { ed_list *ed; ed = cp->edits[cp->edit_ctr]; if ((ed) && (ed->selection_beg != NO_SELECTION)) { delete_samples(ed->selection_beg, cp_selection_len(cp, NULL), cp, cp->edit_ctr); ed = cp->edits[cp->edit_ctr]; ed->selection_beg = NO_SELECTION; } } bool delete_selection(cut_selection_regraph_t regraph) { if (selection_is_active()) { for_each_normal_chan(cp_delete_selection); if (regraph == UPDATE_DISPLAY) for_each_normal_chan(update_graph); enved_reflect_selection(false); if (Xen_hook_has_list(ss->effects_hook)) run_hook(ss->effects_hook, Xen_empty_list, S_effects_hook); return(true); } return(false); } static void cp_deactivate_selection(chan_info *cp) { ed_list *ed; ed = cp->edits[cp->edit_ctr]; if (ed) ed->selection_beg = NO_SELECTION; } static sync_info *syncd_chans = NULL; void deactivate_selection(void) { for_each_normal_chan(cp_deactivate_selection); for_each_normal_chan(update_graph); enved_reflect_selection(false); if (Xen_hook_has_list(ss->effects_hook)) run_hook(ss->effects_hook, Xen_empty_list, S_effects_hook); if (syncd_chans) syncd_chans = free_sync_info(syncd_chans); } void reactivate_selection(chan_info *cp, mus_long_t beg, mus_long_t end) { ed_list *ed; mus_long_t len; ed = cp->edits[cp->edit_ctr]; len = current_samples(cp) - 1; if (beg < 0) beg = 0; if (end < 0) end = 0; if (beg > len) beg = len; if (end > len) end = len; if (beg > end) end = beg; ed->selection_beg = beg; ed->selection_end = end; cp->selection_visible = false; ed->selection_maxamp = -1.0; ed->selection_maxamp_position = -1; xen_selection_counter++; enved_reflect_selection(true); reflect_selection_in_save_as_dialog(true); if (Xen_hook_has_list(ss->effects_hook)) run_hook(ss->effects_hook, Xen_empty_list, S_effects_hook); } void ripple_selection(ed_list *ed, mus_long_t beg, mus_long_t num) { /* beg = insert or delete begin point (snd-edits.c), num = samps inserted (num positive) or deleted (num negative) at beg */ if (ed->selection_beg != NO_SELECTION) { if (beg < ed->selection_beg) { ed->selection_beg += num; if (beg >= ed->selection_beg) ed->selection_beg = NO_SELECTION; /* deletion included some of current selection from outside */ else ed->selection_end += num; } else { if (beg < ed->selection_end) { ed->selection_end += num; if (ed->selection_end < beg) ed->selection_beg = NO_SELECTION; /* same as above but from end */ } } } } static void next_selection_chan(chan_info *cp, void *sidata) { if (cp_has_selection(cp)) { sync_info *si = (sync_info *)sidata; int chan; chan = si->chans; si->chans++; si->begs[chan] = selection_beg(cp); si->cps[chan] = cp; } } sync_info *selection_sync(void) { sync_info *si; if (!(selection_is_active())) return(NULL); si = (sync_info *)calloc(1, sizeof(sync_info)); si->chans = selection_chans(); si->cps = (chan_info **)calloc(si->chans, sizeof(chan_info *)); si->begs = (mus_long_t *)calloc(si->chans, sizeof(mus_long_t)); si->chans = 0; for_each_normal_chan_with_void(next_selection_chan, (void *)si); return(si); } static int mix_selection(chan_info *cp, sync_info *si_out, mus_long_t beg, io_error_t *err, int start_chan) { char *tempfile = NULL; int id = INVALID_MIX_ID; io_error_t io_err = IO_NO_ERROR; tempfile = snd_tempnam(); io_err = save_selection(tempfile, snd_srate(cp->sound), MUS_OUT_SAMPLE_TYPE, MUS_NEXT, NULL, SAVE_ALL_CHANS); if (io_err == IO_NO_ERROR) { char *origin = NULL; #if HAVE_FORTH origin = mus_format("%lld snd chn %s", beg, S_mix_selection); #else origin = mus_format("%s" PROC_OPEN "%lld", to_proc_name(S_mix_selection), beg); #endif if (si_out->chans > 1) remember_temp(tempfile, si_out->chans); id = mix_file(beg, selection_len(), si_out->chans, si_out->cps, tempfile, (si_out->chans > 1) ? MULTICHANNEL_DELETION : DELETE_ME, origin, with_mix_tags(ss), start_chan); free(origin); } if (tempfile) free(tempfile); (*err) = io_err; return(id); } void add_selection_or_region(int reg, chan_info *cp) { /* in all cases, this has a local sound to report in (kbd, xmenu) */ if (cp) { if (is_editable(cp)) { io_error_t io_err = IO_NO_ERROR; bool got_selection; got_selection = ((reg == 0) && (selection_is_active())); if (got_selection) { sync_info *si_out; si_out = sync_to_chan(cp); mix_selection(cp, si_out, cursor_sample(cp), &io_err, 0); free_sync_info(si_out); } else io_err = add_region(reg, cp); if (io_err != IO_NO_ERROR) status_report(cp->sound, "can't mix %s: %s", (got_selection) ? "selection" : "region", io_error_name(io_err)); } } else snd_error_without_format("no channel to mix into?"); } static io_error_t insert_selection(chan_info *cp, sync_info *si_out, mus_long_t beg) { char *tempfile = NULL; mus_sample_t out_format = MUS_OUT_SAMPLE_TYPE; io_error_t io_err = IO_NO_ERROR; if (mus_header_writable(MUS_NEXT, cp->sound->hdr->sample_type)) out_format = cp->sound->hdr->sample_type; tempfile = snd_tempnam(); io_err = save_selection(tempfile, snd_srate(cp->sound), out_format, MUS_NEXT, NULL, SAVE_ALL_CHANS); if (io_err == IO_NO_ERROR) { int i; sync_info *si_in; si_in = selection_sync(); if (si_in) { if (si_in->chans > 1) remember_temp(tempfile, si_in->chans); for (i = 0; ((i < si_in->chans) && (i < si_out->chans)); i++) { char *origin; chan_info *cp_in, *cp_out; mus_long_t len; cp_out = si_out->cps[i]; /* currently syncd chan that we might paste to */ cp_in = si_in->cps[i]; /* selection chan to paste in (no wrap-around here) */ len = cp_selection_len(cp_in, NULL); #if HAVE_FORTH origin = mus_format("%lld %s", beg, S_insert_selection); #else origin = mus_format("%s" PROC_OPEN "%lld", to_proc_name(S_insert_selection), beg); #endif if (file_insert_samples(beg, len, tempfile, cp_out, i, (si_in->chans > 1) ? MULTICHANNEL_DELETION : DELETE_ME, origin, cp_out->edit_ctr)) update_graph(cp_out); free(origin); } free_sync_info(si_in); } } if (tempfile) free(tempfile); return(io_err); } static void insert_selection_or_region(int reg, chan_info *cp) { if (cp) { io_error_t err = IO_NO_ERROR; bool got_selection; got_selection = ((reg == 0) && (selection_is_active())); if (got_selection) { sync_info *si_out; si_out = sync_to_chan(cp); err = insert_selection(cp, si_out, cursor_sample(cp)); free_sync_info(si_out); } else err = paste_region(reg, cp); if (err != IO_NO_ERROR) status_report(cp->sound, "can't insert %s: %s", (got_selection) ? "selection" : "region", io_error_name(err)); } } void insert_selection_from_menu(void) { insert_selection_or_region(0, selected_channel()); } /* we're drawing the selection in one channel, but others may be sync'd to it */ void start_selection_creation(chan_info *cp, mus_long_t samp) { int i; if ((syncd_chans) && (selection_creates_region(ss))) /* hmmm -- if keyboard selection in progress, then mouse press? */ make_region_from_selection(); deactivate_selection(); syncd_chans = sync_to_chan(cp); syncd_chans->begs[0] = samp; /* begs not otherwise used here, so treat as pivot point */ for (i = 0; i < syncd_chans->chans; i++) reactivate_selection(syncd_chans->cps[i], samp, samp); } void restart_selection_creation(chan_info *cp, bool right) { syncd_chans = sync_to_chan(cp); if (right) syncd_chans->begs[0] = selection_beg(cp); else syncd_chans->begs[0] = selection_end(cp); } bool selection_creation_in_progress(void) {return(syncd_chans != NULL);} void finish_selection_creation(void) { if (syncd_chans) { if (selection_creates_region(ss)) make_region_from_selection(); enved_reflect_selection(true); reflect_selection_in_save_as_dialog(true); if (Xen_hook_has_list(ss->effects_hook)) run_hook(ss->effects_hook, Xen_empty_list, S_effects_hook); syncd_chans = free_sync_info(syncd_chans); } } static void show_selection_triangle(chan_info *cp, graphics_context *ax, int x0, int x1, mus_long_t beg, mus_long_t end); static void cp_redraw_selection(chan_info *cp) { int x0, x1; mus_long_t beg, end; axis_info *ap; double sp_srate; graphics_context *ax; ap = cp->axis; beg = selection_beg(cp); end = selection_end(cp); sp_srate = (double)snd_srate(cp->sound); if (ap->losamp < beg) x0 = grf_x((double)beg / sp_srate, ap); else x0 = ap->x_axis_x0; if (ap->hisamp > end) x1 = grf_x((double)end / sp_srate, ap); else x1 = ap->x_axis_x1; ax = selection_context(cp); #if USE_GTK if (x0 <= ap->x_axis_x0) x0 += 2; /* dont' erase the y axis */ #else if (cp->selection_visible) { fill_rectangle(ax, cp->old_x0, ap->y_axis_y1, cp->old_x1 - cp->old_x0, (int)(ap->y_axis_y0 - ap->y_axis_y1)); show_selection_triangle(cp, ax, cp->old_x0, cp->old_x1, beg, end); } #endif fill_rectangle(ax, x0, ap->y_axis_y1, x1 - x0, (int)(ap->y_axis_y0 - ap->y_axis_y1)); show_selection_triangle(cp, ax, x0, x1, beg, end); cp->old_x0 = x0; cp->old_x1 = x1; cp->selection_visible = true; } static void redraw_selection(void) { int i; for (i = 0; i < ss->max_sounds; i++) { snd_info *sp; sp = ss->sounds[i]; if (sp) { if (sp->inuse == SOUND_NORMAL) { int j; for (j = 0; j < sp->nchans; j++) { chan_info *cp; cp = sp->chans[j]; if ((cp) && (selection_is_visible(cp))) { #if (!USE_GTK) cp_redraw_selection(cp); if ((cp->graph_transform_on) && (!(chan_fft_in_progress(cp))) && (show_selection_transform(ss))) calculate_fft(cp); #else if ((cp->graph_transform_on) && (!(chan_fft_in_progress(cp))) && (show_selection_transform(ss))) update_graph(cp); else display_channel_time_data(cp); #endif if (sp->channel_style == CHANNELS_SUPERIMPOSED) break; } } } } } } void display_selection(chan_info *cp) { if (selection_is_visible(cp)) cp_redraw_selection(cp); /* draw just this chan */ } void update_possible_selection_in_progress(mus_long_t samp) { if (syncd_chans) { int i; mus_long_t original_beg; if (samp < 0) samp = 0; original_beg = syncd_chans->begs[0]; for (i = 0; i < syncd_chans->chans; i++) { chan_info *cp; ed_list *ed; mus_long_t new_end; cp = syncd_chans->cps[i]; ed = cp->edits[cp->edit_ctr]; ed->selection_maxamp = -1.0; ed->selection_maxamp_position = -1; if (samp > current_samples(cp)) new_end = current_samples(cp); else new_end = samp; if (new_end < original_beg) { ed->selection_beg = new_end; ed->selection_end = original_beg; } else { ed->selection_beg = original_beg; ed->selection_end = new_end; } } redraw_selection(); } } int make_region_from_selection(void) { mus_long_t *ends = NULL; int i, id = -1; bool happy = false; sync_info *si; if (!(selection_is_active())) return(-1); if (max_regions(ss) == 0) return(-1); si = selection_sync(); ends = (mus_long_t *)calloc(si->chans, sizeof(mus_long_t)); for (i = 0; i < si->chans; i++) { ends[i] = selection_end(si->cps[i]); if (ends[i] > si->begs[i]) happy = true; /* C-space followed by mouse click causes a bogus selection-creation event */ } if (happy) id = define_region(si, ends); si = free_sync_info(si); if (ends) free(ends); return(id); } int select_all(chan_info *cp) { if (cp) { sync_info *si; int i; deactivate_selection(); si = sync_to_chan(cp); for (i = 0; i < si->chans; i++) { if (current_samples(si->cps[i]) > 0) { reactivate_selection(si->cps[i], 0, current_samples(si->cps[i])); update_graph(si->cps[i]); } } si = free_sync_info(si); if ((selection_is_active()) && (selection_creates_region(ss))) return(make_region_from_selection()); } return(-1); } /* ---------------- selection mouse motion ---------------- */ static int last_selection_x = 0; static timeout_result_t watch_selection_button = 0; void cancel_selection_watch(void) { #if (!USE_NO_GUI) if (watch_selection_button) TIMEOUT_REMOVE(watch_selection_button); #endif watch_selection_button = 0; } static void move_selection_1(chan_info *cp, int x); #if (!USE_NO_GUI) static TIMEOUT_TYPE watch_selection(TIMEOUT_ARGS) { chan_info *cp = (chan_info *)context; if (watch_selection_button) { move_selection_1(cp, last_selection_x); watch_selection_button = CALL_TIMEOUT(watch_selection, 50, cp); } TIMEOUT_RESULT } #endif static void move_selection_1(chan_info *cp, int x) { axis_info *ap; ap = cp->axis; if ((x > ap->x_axis_x1) || (x < ap->x_axis_x0)) { if (((x > ap->x_axis_x1) && (ap->x1 == ap->xmax)) || ((x < ap->x_axis_x0) && (ap->x0 == ap->xmin))) return; move_axis(cp, x); if (!watch_selection_button) watch_selection_button = CALL_TIMEOUT(watch_selection, 50, cp); } else if (watch_selection_button) cancel_selection_watch(); redraw_selection(); } void move_selection(chan_info *cp, int x) { last_selection_x = x; /* called in snd-xchn -- sets last_selection_x */ move_selection_1(cp, x); } static void show_selection_triangle(chan_info *cp, graphics_context *ax, int x0, int x1, mus_long_t beg, mus_long_t end) { int y0; y0 = ((axis_info *)(cp->axis))->y_axis_y0; if ((cp->axis->losamp <= beg) && (cp->axis->hisamp > beg)) { fill_polygon(ax, 4, x0, y0, x0 + play_arrow_size(ss), y0 + play_arrow_size(ss), x0, y0 + 2 * play_arrow_size(ss), x0, y0); } if ((cp->axis->losamp < end) && (cp->axis->hisamp >= end)) { fill_polygon(ax, 4, x1, y0, x1 - play_arrow_size(ss), y0 + play_arrow_size(ss), x1, y0 + 2 * play_arrow_size(ss), x1, y0); } } #define HIT_SLOP 4 bool hit_selection_triangle(chan_info *cp, int x, int y) { axis_info *ap; mus_long_t beg; int mx; beg = selection_beg(cp); ap = cp->axis; if (beg < ap->losamp) return(false); if (beg > ap->hisamp) return(false); mx = grf_x((double)beg / (double)snd_srate(cp->sound), ap); if (mx > (x + HIT_SLOP)) return(false); /* click point is to the left of the triangle */ if ((mx + play_arrow_size(ss) + HIT_SLOP) < x) return(false); /* click point is to the right of the triangle */ y = y - ap->y_axis_y0 - play_arrow_size(ss); if (y < 0) y = -y; return((mx + play_arrow_size(ss) - y + HIT_SLOP) >= x); } bool hit_selection_loop_triangle(chan_info *cp, int x, int y) { axis_info *ap; mus_long_t end; int mx; end = selection_end(cp); ap = cp->axis; if (end < ap->losamp) return(false); if (end > ap->hisamp) return(false); mx = grf_x((double)end / (double)snd_srate(cp->sound), ap); if ((mx - play_arrow_size(ss) - HIT_SLOP) > x) return(false); if (mx < (x - HIT_SLOP)) return(false); y = y - ap->y_axis_y0 - play_arrow_size(ss); if (y < 0) y = -y; return((mx - play_arrow_size(ss) - y - HIT_SLOP) <= x); } /* ---------------------------------------- selection object ---------------------------------------- */ typedef struct { int n; } xen_selection; #define Xen_to_xen_selection(arg) ((xen_selection *)Xen_object_ref(arg)) static Xen_object_type_t xen_selection_tag; bool xen_is_selection(Xen obj) { return(Xen_c_object_is_type(obj, xen_selection_tag)); } static void xen_selection_free(xen_selection *v) {if (v) free(v);} Xen_wrap_free(xen_selection, free_xen_selection, xen_selection_free) static char *xen_selection_to_string(xen_selection *v) { #define xen_is_selectionRINT_BUFFER_SIZE 64 char *buf; if (v == NULL) return(NULL); buf = (char *)calloc(xen_is_selectionRINT_BUFFER_SIZE, sizeof(char)); snprintf(buf, xen_is_selectionRINT_BUFFER_SIZE, "#", v->n); return(buf); } Xen_wrap_print(xen_selection, print_xen_selection, xen_selection_to_string) #if HAVE_FORTH || HAVE_RUBY static Xen g_xen_selection_to_string(Xen obj) { char *vstr; Xen result; #define S_xen_selection_to_string "selection->string" Xen_check_type(xen_is_selection(obj), obj, 1, S_xen_selection_to_string, "a selection"); vstr = xen_selection_to_string(Xen_to_xen_selection(obj)); result = C_string_to_Xen_string(vstr); free(vstr); return(result); } #endif #if (!HAVE_SCHEME) static bool xen_selection_equalp(xen_selection *v1, xen_selection *v2) { return((v1 == v2) || (v1->n == v2->n)); } static Xen equalp_xen_selection(Xen obj1, Xen obj2) { if ((!(xen_is_selection(obj1))) || (!(xen_is_selection(obj2)))) return(Xen_false); return(C_bool_to_Xen_boolean(xen_selection_equalp(Xen_to_xen_selection(obj1), Xen_to_xen_selection(obj2)))); } #endif static xen_selection *xen_selection_make(int n) { xen_selection *new_v; new_v = (xen_selection *)malloc(sizeof(xen_selection)); new_v->n = n; return(new_v); } static Xen g_selection(void) { #define H_selection "(" S_selection" ) returns an object representing the current selection, or " PROC_FALSE " if there is no active selection" if (selection_is_active()) { xen_selection *mx; mx = xen_selection_make(xen_selection_counter); return(Xen_make_object(xen_selection_tag, mx, 0, free_xen_selection)); } return(Xen_false); } #if HAVE_SCHEME static Xen s7_xen_selection_length(s7_scheme *sc, Xen obj) { return(g_selection_framples(Xen_undefined, Xen_undefined)); } static bool s7_xen_selection_equalp(void *obj1, void *obj2) { return((obj1 == obj2) || (((xen_selection *)obj1)->n == ((xen_selection *)obj2)->n)); } static Xen s7_xen_selection_copy(s7_scheme *sc, Xen args) { if (selection_is_active()) { snd_info *sp; char *name; name = snd_tempnam(); save_selection(name, selection_srate(), MUS_OUT_SAMPLE_TYPE, MUS_NEXT, NULL, SAVE_ALL_CHANS); sp = snd_open_file(name, FILE_READ_WRITE); free(name); return(new_xen_sound(sp->index)); } return(Xen_false); } static Xen s7_xen_selection_fill(s7_scheme *sc, Xen args) { sync_info *si; mus_float_t valf; s7_pointer val; val = s7_cadr(args); valf = Xen_real_to_C_double(val); if (valf == 0.0) { mus_float_t vals[1] = {0.0}; scale_by(NULL, vals, 1, true); /* 1 entry in vals array, true = over selection */ return(Xen_false); } si = selection_sync(); if (si) { int i; for (i = 0; i < si->chans; i++) { mus_long_t beg, end, len, j; mus_float_t *data; beg = selection_beg(si->cps[i]); end = selection_end(si->cps[i]); len = end - beg + 1; data = (mus_float_t *)malloc(len * sizeof(mus_float_t)); for (j = 0; j < len; j++) data[j] = valf; if (change_samples(beg, len, data, si->cps[i], "fill! selection", si->cps[i]->edit_ctr, fabs(valf))) update_graph(si->cps[i]); free(data); } } return(Xen_false); } #endif static void init_xen_selection(void) { #if HAVE_SCHEME xen_selection_tag = s7_new_type_x(s7, "", print_xen_selection, free_xen_selection, s7_xen_selection_equalp, NULL, NULL, NULL, s7_xen_selection_length, s7_xen_selection_copy, NULL, s7_xen_selection_fill); #else #if HAVE_RUBY xen_selection_tag = Xen_make_object_type("XenSelection", sizeof(xen_selection)); #else xen_selection_tag = Xen_make_object_type("selection", sizeof(xen_selection)); #endif #endif #if HAVE_FORTH fth_set_object_inspect(xen_selection_tag, print_xen_selection); fth_set_object_dump(xen_selection_tag, g_xen_selection_to_string); fth_set_object_equal(xen_selection_tag, equalp_xen_selection); fth_set_object_free(xen_selection_tag, free_xen_selection); #endif #if HAVE_RUBY rb_define_method(xen_selection_tag, "to_s", Xen_procedure_cast print_xen_selection, 0); rb_define_method(xen_selection_tag, "eql?", Xen_procedure_cast equalp_xen_selection, 1); rb_define_method(xen_selection_tag, "==", Xen_procedure_cast equalp_xen_selection, 1); rb_define_method(xen_selection_tag, "to_str", Xen_procedure_cast g_xen_selection_to_string, 0); #endif } /* -------------------------------------------------------------------------------- */ io_error_t save_selection(const char *ofile, int srate, mus_sample_t samp_type, mus_header_t head_type, const char *comment, int chan) { /* type and format have already been checked */ int ofd; io_error_t io_err = IO_NO_ERROR; mus_long_t oloc, alloc_len; sync_info *si = NULL; mus_long_t *ends; int i, j, k, chans; mus_long_t dur; snd_fd **sfs; snd_info *sp = NULL; mus_float_t **data; si = selection_sync(); if ((si) && (si->cps) && (si->cps[0])) sp = si->cps[0]->sound; if (head_type == MUS_UNKNOWN_HEADER) { if ((sp) && (mus_header_writable(sp->hdr->type, MUS_IGNORE_SAMPLE))) head_type = sp->hdr->type; else head_type = MUS_NEXT; } if (samp_type == MUS_UNKNOWN_SAMPLE) { if ((sp) && (mus_header_writable(head_type, sp->hdr->sample_type))) samp_type = sp->hdr->sample_type; else samp_type = MUS_OUT_SAMPLE_TYPE; } if (!mus_header_writable(head_type, samp_type)) { head_type = MUS_NEXT; samp_type = MUS_OUT_SAMPLE_TYPE; } if (srate == -1) srate = selection_srate(); dur = selection_len(); if (chan == SAVE_ALL_CHANS) chans = si->chans; else chans = 1; io_err = snd_write_header(ofile, head_type, srate, chans, chans * dur, samp_type, comment, NULL); if (io_err != IO_NO_ERROR) { si = free_sync_info(si); return(io_err); } oloc = mus_header_data_location(); ofd = snd_reopen_write(ofile); if (sp) { int bps; mus_long_t num; disk_space_t no_space; bool copy_ok = false; bps = mus_bytes_per_sample(samp_type); num = dur * bps * chans; no_space = disk_has_space(num, ofile); if (no_space != DISK_SPACE_OK) { snd_close(ofd, ofile); si = free_sync_info(si); return(IO_DISK_FULL); } copy_ok = ((samp_type == sp->hdr->sample_type) && (chans == sp->nchans) && (chan == SAVE_ALL_CHANS)); if (copy_ok) for (i = 0; i < chans; i++) if ((sp->chans[i]->edit_ctr != 0) || (si->cps[i]->sound != sp) || (si->begs[i] != si->begs[0])) { copy_ok = false; break; } if (copy_ok) { /* write next header with correct len * seek loc in sp->filename * copy len*data-size bytes * get max from amp envs */ int fdi; lseek(ofd, oloc, SEEK_SET); fdi = mus_file_open_read(sp->filename); /* this does not read the header */ if (fdi == -1) { snd_close(ofd, ofile); si = free_sync_info(si); return(IO_CANT_READ_SELECTION_FILE); } /* snd_error("can't read selection's original sound? %s: %s", sp->filename, snd_io_strerror()); */ else { mus_long_t iloc; char *buffer; iloc = mus_sound_data_location(sp->filename); lseek(fdi, iloc + chans * bps * si->begs[0], SEEK_SET); buffer = (char *)malloc(MAX_BUFFER_SIZE * sizeof(char)); for (j = 0; j < num; j += MAX_BUFFER_SIZE) { ssize_t n; mus_long_t bytes; bytes = num - j; if (bytes > MAX_BUFFER_SIZE) bytes = MAX_BUFFER_SIZE; n = read(fdi, buffer, bytes); if (n != 0) n = write(ofd, buffer, bytes); if (n == 0) fprintf(stderr, "IO error while saving selection"); } free(buffer); snd_close(fdi, sp->filename); } snd_close(ofd, ofile); si = free_sync_info(si); #if USE_MOTIF if (!(ss->file_monitor_ok)) alert_new_file(); #endif return(IO_NO_ERROR); } } ends = (mus_long_t *)calloc(chans, sizeof(mus_long_t)); sfs = (snd_fd **)calloc(chans, sizeof(snd_fd *)); if (chan == SAVE_ALL_CHANS) { for (i = 0; i < chans; i++) { ends[i] = selection_end(si->cps[i]); sfs[i] = init_sample_read(selection_beg(si->cps[i]), si->cps[i], READ_FORWARD); } } else { ends[0] = selection_end(si->cps[chan]); sfs[0] = init_sample_read(selection_beg(si->cps[chan]), si->cps[chan], READ_FORWARD); } snd_file_open_descriptors(ofd, ofile, samp_type, oloc, chans, head_type); mus_file_set_clipping(ofd, clipping(ss)); lseek(ofd, oloc, SEEK_SET); data = (mus_float_t **)calloc(chans, sizeof(mus_float_t *)); if (dur > REPORTING_SIZE) alloc_len = REPORTING_SIZE; else alloc_len = dur; for (i = 0; i < chans; i++) data[i] = (mus_float_t *)calloc(alloc_len, sizeof(mus_float_t)); if (alloc_len == dur) { for (k = 0; k < chans; k++) samples_to_vct_with_reader(dur, data[k], sfs[k]); mus_file_write(ofd, 0, dur - 1, chans, data); } else { mus_long_t ioff; ss->stopped_explicitly = false; for (k = 0; k < chans; k++) sampler_set_safe(sfs[k], ends[k]); for (ioff = 0; ioff < dur; ioff += alloc_len) { mus_long_t kdur; kdur = dur - ioff; if (kdur > alloc_len) kdur = alloc_len; for (j = 0; j < kdur; j++) { for (k = 0; k < chans; k++) { if ((ioff + j) <= ends[k]) data[k][j] = read_sample(sfs[k]); else data[k][j] = 0.0; } } io_err = sndlib_error_to_snd(mus_file_write(ofd, 0, j - 1, chans, data)); if (io_err != IO_NO_ERROR) { snd_warning("%s %s: %s", io_error_name(io_err), ofile, snd_io_strerror()); break; } if (ss->stopped_explicitly) { ss->stopped_explicitly = false; snd_warning_without_format("save selection stopped"); io_err = IO_INTERRUPTED; break; } } } for (i = 0; i < chans; i++) { free_snd_fd(sfs[i]); free(data[i]); } free(sfs); free(data); si = free_sync_info(si); free(ends); if (mus_file_close(ofd) != 0) return(IO_CANT_CLOSE_FILE); #if USE_MOTIF if (!(ss->file_monitor_ok)) alert_new_file(); #endif return(io_err); } static Xen g_delete_selection(void) { #define H_delete_selection "(" S_delete_selection "): delete the currently selected portion" if (selection_is_active()) { delete_selection(UPDATE_DISPLAY); return(Xen_true); } return(snd_no_active_selection_error(S_delete_selection)); } static Xen g_insert_selection(Xen beg, Xen snd, Xen chn) { #define H_insert_selection "(" S_insert_selection " :optional (beg 0) snd chn): insert the currently selected portion starting at beg" if (selection_is_active()) { chan_info *cp; mus_long_t samp; io_error_t io_err = IO_NO_ERROR; sync_info *si_out; Snd_assert_channel(S_insert_selection, snd, chn, 2); Xen_check_type(Xen_is_integer_or_unbound(beg), beg, 1, S_insert_selection, "an integer"); cp = get_cp(snd, chn, S_insert_selection); if ((!cp) || (!(is_editable(cp)))) return(Xen_false); samp = beg_to_sample(beg, S_insert_selection); if (Xen_is_integer(chn)) si_out = make_simple_sync(cp, samp); /* ignore sync */ else si_out = sync_to_chan(cp); io_err = insert_selection(cp, si_out, samp); free_sync_info(si_out); if (is_serious_io_error(io_err)) Xen_error(Xen_make_error_type("IO-error"), Xen_list_2(C_string_to_Xen_string(S_insert_selection ": IO error ~A"), C_string_to_Xen_string(io_error_name(io_err)))); return(Xen_false); } return(snd_no_active_selection_error(S_insert_selection)); } static Xen g_mix_selection(Xen beg, Xen snd, Xen chn, Xen sel_chan) { #define H_mix_selection "(" S_mix_selection " :optional (beg 0) snd chn (selection-channel " PROC_TRUE ")): mix the currently selected portion starting at beg" if (selection_is_active()) { chan_info *cp; mus_long_t obeg; io_error_t io_err = IO_NO_ERROR; int i, selection_chan = 0, id = -1, chans = 0; sync_info *si_out; Xen result = Xen_empty_list; Snd_assert_channel(S_mix_selection, snd, chn, 2); Xen_check_type(Xen_is_integer_or_unbound(beg), beg, 1, S_mix_selection, "an integer"); Xen_check_type(Xen_is_integer_boolean_or_unbound(sel_chan), sel_chan, 4, S_mix_selection, "an integer or " PROC_TRUE); cp = get_cp(snd, chn, S_mix_selection); if ((!cp) || (!(is_editable(cp)))) return(Xen_false); obeg = beg_to_sample(beg, S_mix_selection); if (Xen_is_integer(sel_chan)) selection_chan = Xen_integer_to_C_int(sel_chan); if (Xen_is_integer(chn)) si_out = make_simple_sync(cp, obeg); /* ignore sync */ else si_out = sync_to_chan(cp); id = mix_selection(cp, si_out, obeg, &io_err, selection_chan); chans = si_out->chans; /* save for loop below */ free_sync_info(si_out); if (is_serious_io_error(io_err)) Xen_error(Xen_make_error_type("IO-error"), Xen_list_2(C_string_to_Xen_string(S_mix_selection ": IO error ~A"), C_string_to_Xen_string(io_error_name(io_err)))); if (id == -1) return(Xen_false); for (i = 0; i < chans; i++) result = Xen_cons(new_xen_mix(id + i), result); return(Xen_list_reverse(result)); } return(snd_no_active_selection_error(S_mix_selection)); } static Xen g_selection_to_mix(void) { #define H_selection_to_mix "(" S_selection_to_mix "): turns the current selection into a mix" if (selection_is_active()) { chan_info *cp; io_error_t io_err = IO_NO_ERROR; int i, id = INVALID_MIX_ID, chans = 0, sync = GET_NEW_SYNC; sync_info *si_out; Xen result = Xen_empty_list; char *tempfile = NULL, *origin = NULL; si_out = selection_sync(); cp = si_out->cps[0]; tempfile = snd_tempnam(); io_err = save_selection(tempfile, snd_srate(cp->sound), MUS_OUT_SAMPLE_TYPE, MUS_NEXT, NULL, SAVE_ALL_CHANS); if (is_serious_io_error(io_err)) { if (tempfile) free(tempfile); free_sync_info(si_out); Xen_error(Xen_make_error_type("IO-error"), Xen_list_2(C_string_to_Xen_string(S_selection_to_mix ": IO error ~A"), C_string_to_Xen_string(io_error_name(io_err)))); } origin = mus_format("%s", S_selection_to_mix); if (si_out->chans > 1) remember_temp(tempfile, si_out->chans); g_scale_selection_by(C_double_to_Xen_real(0.0)); id = mix_file(selection_beg(NULL), selection_len(), si_out->chans, si_out->cps, tempfile, (si_out->chans > 1) ? MULTICHANNEL_DELETION : DELETE_ME, origin, true, 0); deactivate_selection(); free(origin); if (tempfile) free(tempfile); chans = si_out->chans; /* save for loop below */ free_sync_info(si_out); if (id == -1) return(Xen_false); if (chans == 1) return(Xen_cons(new_xen_mix(id), Xen_empty_list)); /* no sync */ for (i = 0; i < chans; i++) { sync = mix_set_sync_from_id(id + i, sync); result = Xen_cons(new_xen_mix(id + i), result); } if ((mix_dialog_mix() >= id) && (mix_dialog_mix() < (id + chans))) reflect_mix_change(id); /* this update is needed in a case like: file close (closing old mix), open new, mix -- this mix can now have old mix's id */ return(Xen_list_reverse(result)); } return(snd_no_active_selection_error(S_selection_to_mix)); } static Xen g_is_selection(Xen sel) { #define H_is_selection "(" S_is_selection " :optional obj): " PROC_TRUE " if selection is currently active, visible, etc. \ If 'obj' is passed, " S_is_selection " returns " PROC_TRUE " if obj is a selection object and there is a current selection." if ((Xen_is_bound(sel)) && (!(xen_is_selection(sel)))) return(Xen_false); return(C_bool_to_Xen_boolean(selection_is_active())); } static Xen g_selection_position(Xen snd, Xen chn) { #define H_selection_position "(" S_selection_position " :optional snd chn): selection start samp" if (selection_is_active()) { if (!Xen_is_bound(snd)) return(C_llong_to_Xen_llong(selection_beg(NULL))); else { chan_info *cp; Snd_assert_channel(S_selection_position, snd, chn, 1); cp = get_cp(snd, chn, S_selection_position); if (!cp) return(Xen_false); return(C_llong_to_Xen_llong(selection_beg(cp))); } } return(snd_no_active_selection_error(S_selection_position)); } static Xen g_set_selection_position(Xen pos, Xen snd, Xen chn) { chan_info *cp; mus_long_t beg; Snd_assert_channel(S_set S_selection_position, snd, chn, 2); Xen_check_type(Xen_is_integer(pos), pos, 1, S_selection_position, "an integer"); beg = beg_to_sample(pos, S_set S_selection_position); if (!Xen_is_bound(snd)) { sync_info *si = NULL; if (selection_is_active()) si = selection_sync(); else { cp = current_channel(); if (cp) si = sync_to_chan(cp); } if (si) { int i; for (i = 0; i < si->chans; i++) cp_set_selection_beg(si->cps[i], beg); si = free_sync_info(si); } } else { cp = get_cp(snd, chn, S_set S_selection_position); if (!cp) return(Xen_false); cp_set_selection_beg(cp, beg); } redraw_selection(); return(pos); } with_three_setter_args(g_set_selection_position_reversed, g_set_selection_position) Xen g_selection_framples(Xen snd, Xen chn) { #define H_selection_framples "(" S_selection_framples " :optional snd chn): selection length" if (selection_is_active()) { if (!Xen_is_bound(snd)) return(C_llong_to_Xen_llong(selection_len())); else { chan_info *cp; Snd_assert_channel(S_selection_framples, snd, chn, 1); cp = get_cp(snd, chn, S_selection_framples); if (!cp) return(Xen_false); return(C_llong_to_Xen_llong(cp_selection_len(cp, NULL))); } } return(snd_no_active_selection_error(S_selection_framples)); } static Xen g_set_selection_framples(Xen samps, Xen snd, Xen chn) { chan_info *cp; mus_long_t len; Xen_check_type(Xen_is_llong(samps), samps, 1, S_set S_selection_framples, "an integer"); len = Xen_llong_to_C_llong(samps); if (len <= 0) Xen_wrong_type_arg_error(S_set S_selection_framples, 1, samps, "a positive integer"); if (!Xen_is_bound(snd)) { sync_info *si = NULL; if (selection_is_active()) si = selection_sync(); else { cp = current_channel(); if (cp) si = sync_to_chan(cp); } if (si) { int i; for (i = 0; i < si->chans; i++) cp_set_selection_len(si->cps[i], len); si = free_sync_info(si); } } else { Snd_assert_channel(S_set S_selection_framples, snd, chn, 2); cp = get_cp(snd, chn, S_set S_selection_framples); if (!cp) return(Xen_false); cp_set_selection_len(cp, len); } redraw_selection(); return(samps); } with_three_setter_args(g_set_selection_framples_reversed, g_set_selection_framples) static Xen g_selection_member(Xen snd, Xen chn) { #define H_selection_member "(" S_selection_member " :optional snd chn): " PROC_TRUE " if snd's channel chn is a member of the current selection" chan_info *cp; Snd_assert_channel(S_selection_member, snd, chn, 1); cp = get_cp(snd, chn, S_selection_member); if (!cp) return(Xen_false); return(C_bool_to_Xen_boolean(selection_is_active_in_channel(cp))); } static Xen g_set_selection_member(Xen on, Xen snd, Xen chn) { Xen_check_type(Xen_is_boolean(on), on, 1, S_set S_selection_member, "a boolean"); if ((Xen_is_true(snd)) && (Xen_is_false(on))) deactivate_selection(); else { chan_info *cp; Snd_assert_channel(S_set S_selection_member, snd, chn, 2); cp = get_cp(snd, chn, S_set S_selection_member); if (!cp) return(Xen_false); if (Xen_is_true(on)) { if (selection_is_active()) cp_set_selection_beg(cp, selection_beg(NULL)); else cp_set_selection_beg(cp, 0); } else cp_deactivate_selection(cp); enved_reflect_selection(selection_is_active()); reflect_selection_in_save_as_dialog(selection_is_active()); if (Xen_hook_has_list(ss->effects_hook)) run_hook(ss->effects_hook, Xen_empty_list, S_effects_hook); if (selection_is_active()) redraw_selection(); } return(on); } with_three_setter_args(g_set_selection_member_reversed, g_set_selection_member) static Xen g_select_all(Xen snd_n, Xen chn_n) { #define H_select_all "(" S_select_all " :optional snd chn): make a new selection containing all of snd's channel chn. \ If sync is set, all chans are included. The new region id is returned (if " S_selection_creates_region " is " PROC_TRUE ")." chan_info *cp; int id; Snd_assert_channel(S_select_all, snd_n, chn_n, 1); cp = get_cp(snd_n, chn_n, S_select_all); if (!cp) return(Xen_false); id = select_all(cp); if (selection_creates_region(ss)) return(C_int_to_Xen_region(id)); else return(Xen_false); } static Xen kw_header_type, kw_comment, kw_file, kw_srate, kw_channel, kw_sample_type; static void init_selection_keywords(void) { kw_header_type = Xen_make_keyword("header-type"); kw_sample_type = Xen_make_keyword("sample-type"); kw_comment = Xen_make_keyword("comment"); kw_file = Xen_make_keyword("file"); kw_srate = Xen_make_keyword("srate"); kw_channel = Xen_make_keyword("channel"); } static Xen g_save_selection(Xen arglist) { #define H_save_selection "(" S_save_selection " file srate sample-type header-type comment channel): \ save the current selection in file using the indicated file attributes. If channel is given, save only that channel." mus_header_t head_type = MUS_UNKNOWN_HEADER; mus_sample_t samp_type = MUS_UNKNOWN_SAMPLE; int sr = -1, chn = 0; io_error_t io_err = IO_NO_ERROR; const char *com = NULL, *file = NULL; char *fname = NULL; Xen args[12]; Xen keys[6]; int orig_arg[6] = {0, 0, 0, 0, 0, 0}; int vals, i, arglist_len; if (!(selection_is_active())) return(snd_no_active_selection_error(S_save_selection)); /* changed 7-Dec-08 to be more like save-sound-as in default values -- if just one * sound involved, or all sounds same, use current choices rather than MUS_NEXT etc: * hdr->type|srate|format */ keys[0] = kw_file; keys[1] = kw_srate; keys[2] = kw_sample_type; keys[3] = kw_header_type; keys[4] = kw_comment; keys[5] = kw_channel; for (i = 0; i < 12; i++) args[i] = Xen_undefined; arglist_len = Xen_list_length(arglist); if (arglist_len > 12) Xen_out_of_range_error(S_save_selection, 0, arglist, "too many arguments"); for (i = 0; i < arglist_len; i++) args[i] = Xen_list_ref(arglist, i); vals = mus_optkey_unscramble(S_save_selection, 6, keys, args, orig_arg); if (vals > 0) { file = mus_optkey_to_string(keys[0], S_save_selection, orig_arg[0], NULL); sr = mus_optkey_to_int(keys[1], S_save_selection, orig_arg[1], selection_srate()); samp_type = (mus_sample_t)mus_optkey_to_int(keys[2], S_save_selection, orig_arg[2], (int)samp_type); head_type = (mus_header_t)mus_optkey_to_int(keys[3], S_save_selection, orig_arg[3], (int)head_type); com = mus_optkey_to_string(keys[4], S_save_selection, orig_arg[4], NULL); chn = mus_optkey_to_int(keys[5], S_save_selection, orig_arg[5], SAVE_ALL_CHANS); } if (file == NULL) Xen_error(Xen_make_error_type("IO-error"), Xen_list_1(C_string_to_Xen_string(S_save_selection ": no output file?"))); if ((head_type != MUS_UNKNOWN_HEADER) && (!(mus_header_writable(head_type, MUS_IGNORE_SAMPLE)))) Xen_error(CANNOT_SAVE, Xen_list_2(C_string_to_Xen_string(S_save_selection ": can't write a ~A header"), C_string_to_Xen_string(mus_header_type_name(head_type)))); if ((head_type != MUS_UNKNOWN_HEADER) && (samp_type != MUS_UNKNOWN_SAMPLE) && (!(mus_header_writable(head_type, samp_type)))) Xen_error(CANNOT_SAVE, Xen_list_3(C_string_to_Xen_string(S_save_selection ": can't write ~A data to a ~A header"), C_string_to_Xen_string(mus_sample_type_name(samp_type)), C_string_to_Xen_string(mus_header_type_name(head_type)))); if ((sr != -1) && (sr <= 0)) Xen_error(CANNOT_SAVE, Xen_list_2(C_string_to_Xen_string(S_save_selection ": srate (~A) can't be <= 0"), C_int_to_Xen_integer(sr))); fname = mus_expand_filename(file); io_err = save_selection(fname, sr, samp_type, head_type, com, chn); if (fname) free(fname); if ((io_err != IO_NO_ERROR) && (io_err != IO_INTERRUPTED) && (io_err != IO_SAVE_HOOK_CANCELLATION)) Xen_error(CANNOT_SAVE, Xen_list_3(C_string_to_Xen_string(S_save_selection ": can't save ~S, ~A"), keys[0], C_string_to_Xen_string(snd_open_strerror()))); return(args[orig_arg[0] - 1]); } Xen g_selection_chans(void) { #define H_selection_chans "(" S_selection_chans "): chans in active selection" return(C_int_to_Xen_integer(selection_chans())); } Xen g_selection_srate(void) { #define H_selection_srate "(" S_selection_srate "): selection srate" return(C_int_to_Xen_integer(selection_srate())); } Xen g_selection_maxamp(Xen snd, Xen chn) { #define H_selection_maxamp "(" S_selection_maxamp " :optional snd chn): selection maxamp in given channel, or overall maxamp if no args passed." if (Xen_is_bound(snd)) { chan_info *cp; Snd_assert_channel(S_selection_maxamp, snd, chn, 1); cp = get_cp(snd, chn, S_selection_maxamp); if (!cp) return(Xen_false); return(C_double_to_Xen_real(selection_maxamp(cp))); } else { mus_float_t mx = 0.0; int i; sync_info *si; si = selection_sync(); if (!si) return(C_double_to_Xen_real(0.0)); /* no selection -- error? */ for (i = 0; i < si->chans; i++) { mus_float_t cur_mx; cur_mx = selection_maxamp(si->cps[i]); if (cur_mx > mx) mx = cur_mx; } free_sync_info(si); return(C_double_to_Xen_real(mx)); } } static Xen g_selection_maxamp_position(Xen snd, Xen chn) { #define H_selection_maxamp_position "(" S_selection_maxamp_position " :optional snd chn): location of selection maxamp (0 = start of selection)" chan_info *cp; Snd_assert_channel(S_selection_maxamp_position, snd, chn, 1); cp = get_cp(snd, chn, S_selection_maxamp_position); if (!cp) return(Xen_false); return(C_llong_to_Xen_llong(selection_maxamp_position(cp))); } static double sel_beg, sel_end; static bool get_selection_bounds(chan_info *cp) { if (selection_is_active_in_channel(cp)) { mus_long_t samp; double x; samp = selection_beg(cp); x = (double)samp / snd_srate(cp->sound); if ((sel_beg < 0.0) || (x < sel_beg)) sel_beg = x; samp = selection_end(cp); x = (double)samp / snd_srate(cp->sound); if ((sel_end < 0.0) || (x > sel_end)) sel_end = x; } return(false); } static bool update_bounds(chan_info *cp) { set_x_axis_x0x1(cp, sel_beg, sel_end); return(false); } void show_selection(void) { sel_beg = -1.0; sel_end = -1.0; map_over_chans(get_selection_bounds); map_over_chans(update_bounds); } static Xen g_show_selection(void) { #define H_show_selection "(" S_show_selection ") adjusts graph bounds to display the current selection in full" if (selection_is_active()) show_selection(); return(Xen_false); } static Xen g_unselect_all(void) { #define H_unselect_all "(" S_unselect_all ") deactivates (unselects) the current selection." deactivate_selection(); return(Xen_false); } Xen_wrap_2_optional_args(g_selection_position_w, g_selection_position) Xen_wrap_2_optional_args(g_selection_framples_w, g_selection_framples) Xen_wrap_2_optional_args(g_selection_member_w, g_selection_member) Xen_wrap_no_args(g_selection_w, g_selection) Xen_wrap_1_optional_arg(g_is_selection_w, g_is_selection) Xen_wrap_no_args(g_selection_chans_w, g_selection_chans) Xen_wrap_no_args(g_selection_srate_w, g_selection_srate) Xen_wrap_2_optional_args(g_selection_maxamp_w, g_selection_maxamp) Xen_wrap_2_optional_args(g_selection_maxamp_position_w, g_selection_maxamp_position) Xen_wrap_no_args(g_delete_selection_w, g_delete_selection) Xen_wrap_3_optional_args(g_insert_selection_w, g_insert_selection) Xen_wrap_4_optional_args(g_mix_selection_w, g_mix_selection) Xen_wrap_no_args(g_selection_to_mix_w, g_selection_to_mix) Xen_wrap_2_optional_args(g_select_all_w, g_select_all) Xen_wrap_any_args(g_save_selection_w, g_save_selection) Xen_wrap_no_args(g_show_selection_w, g_show_selection) Xen_wrap_no_args(g_unselect_all_w, g_unselect_all) #if HAVE_SCHEME #define g_set_selection_position_w g_set_selection_position_reversed #define g_set_selection_framples_w g_set_selection_framples_reversed #define g_set_selection_member_w g_set_selection_member_reversed #else Xen_wrap_3_optional_args(g_set_selection_position_w, g_set_selection_position) Xen_wrap_3_optional_args(g_set_selection_framples_w, g_set_selection_framples) Xen_wrap_3_optional_args(g_set_selection_member_w, g_set_selection_member) #endif void g_init_selection(void) { init_selection_keywords(); init_xen_selection(); Xen_define_dilambda(S_selection_position, g_selection_position_w, H_selection_position, S_set S_selection_position, g_set_selection_position_w, 0, 2, 1, 2); Xen_define_dilambda(S_selection_framples, g_selection_framples_w, H_selection_framples, S_set S_selection_framples, g_set_selection_framples_w, 0, 2, 1, 2); Xen_define_dilambda(S_selection_member, g_selection_member_w, H_selection_member, S_set S_selection_member, g_set_selection_member_w, 0, 2, 1, 2); Xen_define_safe_procedure(S_selection, g_selection_w, 0, 0, 0, H_selection); Xen_define_safe_procedure(S_is_selection, g_is_selection_w, 0, 1, 0, H_is_selection); Xen_define_safe_procedure(S_selection_chans, g_selection_chans_w, 0, 0, 0, H_selection_chans); Xen_define_safe_procedure(S_selection_srate, g_selection_srate_w, 0, 0, 0, H_selection_srate); Xen_define_safe_procedure(S_selection_maxamp, g_selection_maxamp_w, 0, 2, 0, H_selection_maxamp); Xen_define_safe_procedure(S_selection_maxamp_position, g_selection_maxamp_position_w, 0, 2, 0, H_selection_maxamp_position); Xen_define_procedure(S_delete_selection, g_delete_selection_w, 0, 0, 0, H_delete_selection); Xen_define_procedure(S_insert_selection, g_insert_selection_w, 0, 3, 0, H_insert_selection); Xen_define_procedure(S_mix_selection, g_mix_selection_w, 0, 4, 0, H_mix_selection); Xen_define_procedure(S_selection_to_mix, g_selection_to_mix_w, 0, 0, 0, H_selection_to_mix); Xen_define_procedure(S_select_all, g_select_all_w, 0, 2, 0, H_select_all); Xen_define_procedure(S_save_selection, g_save_selection_w, 0, 0, 1, H_save_selection); Xen_define_procedure(S_show_selection, g_show_selection_w, 0, 0, 0, H_show_selection); Xen_define_procedure(S_unselect_all, g_unselect_all_w, 0, 0, 0, H_unselect_all); } snd-16.1/snd-main.c0000644000076400007640000034777612603035272012235 0ustar bilbil#include "snd.h" #include "clm-strings.h" #include "sndlib-strings.h" #include "clm2xen.h" #if HAVE_RUBY #define TO_GVAR_NAME(Str) xen_scheme_global_variable_to_ruby(Str) #else #define TO_GVAR_NAME(Str) Str #endif static void remove_temp_files(chan_info *cp) { free_sound_list(cp); delete_any_remaining_mix_temp_files_at_exit(cp); } static void save_peak_env_info(chan_info *cp) { write_peak_env_info_file(cp); /* this returns bool, but for_each_chan wants void */ } static Xen exit_hook; static Xen before_exit_hook; bool snd_exit_cleanly(bool force_exit) { Xen res = Xen_false; ss->exiting = true; /* if segfault during exit code, don't try to restart at event loop! */ /* before-exit-hook can cancel the exit, whereas exit-hook can't */ if (Xen_hook_has_list(before_exit_hook)) res = run_or_hook(before_exit_hook, Xen_empty_list, S_before_exit_hook); if ((Xen_is_true(res)) && (!force_exit)) return(false); /* does it make any sense to call this hook if we're forced to exit anyway? */ #if (!USE_NO_GUI) if (ask_about_unsaved_edits(ss)) { int i; bool found_saver = false; for (i = 0; i < ss->max_sounds; i++) { snd_info *sp; sp = ss->sounds[i]; if ((sp) && (sp->inuse == SOUND_NORMAL) && (has_unsaved_edits(sp))) { found_saver = true; save_edits_now(sp); } } if (found_saver) return(false); } #endif if (peak_env_dir(ss)) for_each_chan(save_peak_env_info); if (Xen_hook_has_list(exit_hook)) run_hook(exit_hook, Xen_empty_list, S_exit_hook); if (ss->file_monitor_ok) cleanup_file_monitor(); cleanup_dac(); for_each_normal_chan(remove_temp_files); cleanup_region_temp_files(); forget_temps(); return(true); } void sound_not_current(snd_info *sp) { /* check for change in update status */ bool needs_update; if (ss->file_monitor_ok) return; needs_update = (file_write_date(sp->filename) != sp->write_date); if (needs_update != sp->need_update) { sp->need_update = needs_update; if (needs_update) { if (auto_update(ss)) snd_update(sp); /* will stop bomb via need_update flag */ else start_bomb(sp); } else stop_bomb(sp); } } /* ---------------- save sound state (options, or entire state) ---------------- */ static bool fneq(mus_float_t a, mus_float_t b) { /* floating point != replacement */ return(fabs(a - b) > .00001); } static const char *cursor_style_name(cursor_style_t style) { switch (style) { case CURSOR_CROSS: return(TO_VAR_NAME(S_cursor_cross)); break; case CURSOR_LINE: return(TO_VAR_NAME(S_cursor_line)); break; default: /* proc?? */ return(TO_VAR_NAME(S_cursor_cross)); break; } } static const char *show_axes2string(show_axes_t ax) { switch (ax) { case SHOW_NO_AXES: return(TO_VAR_NAME(S_show_no_axes)); break; case SHOW_X_AXIS: return(TO_VAR_NAME(S_show_x_axis)); break; case SHOW_X_AXIS_UNLABELLED: return(TO_VAR_NAME(S_show_x_axis_unlabelled)); break; case SHOW_ALL_AXES: return(TO_VAR_NAME(S_show_all_axes)); break; case SHOW_BARE_X_AXIS: return(TO_VAR_NAME(S_show_bare_x_axis)); break; default: return(TO_VAR_NAME(S_show_all_axes_unlabelled)); break; } } static const char *zoom_focus_style_name(zoom_focus_t choice) { switch (choice) { case ZOOM_FOCUS_LEFT: return(TO_VAR_NAME(S_zoom_focus_left)); break; case ZOOM_FOCUS_RIGHT: return(TO_VAR_NAME(S_zoom_focus_right)); break; case ZOOM_FOCUS_MIDDLE: return(TO_VAR_NAME(S_zoom_focus_middle)); break; /* proc?? */ default: return(TO_VAR_NAME(S_zoom_focus_active)); break; } } static const char *transform_normalization_name(fft_normalize_t choice) { switch (choice) { case DONT_NORMALIZE: return(TO_VAR_NAME(S_dont_normalize)); break; case NORMALIZE_BY_CHANNEL:return(TO_VAR_NAME(S_normalize_by_channel)); break; case NORMALIZE_BY_SOUND: return(TO_VAR_NAME(S_normalize_by_sound)); break; case NORMALIZE_GLOBALLY: return(TO_VAR_NAME(S_normalize_globally)); break; default: return(TO_VAR_NAME(S_normalize_by_channel)); break; } } static const char *graph_style_name(graph_style_t choice) { switch (choice) { case GRAPH_DOTS: return(TO_VAR_NAME(S_graph_dots)); break; case GRAPH_DOTS_AND_LINES: return(TO_VAR_NAME(S_graph_dots_and_lines)); break; case GRAPH_LOLLIPOPS: return(TO_VAR_NAME(S_graph_lollipops)); break; case GRAPH_FILLED: return(TO_VAR_NAME(S_graph_filled)); break; case GRAPH_LINES: default: return(TO_VAR_NAME(S_graph_lines)); break; } } static const char *transform_graph_type_name(graph_type_t choice) { switch (choice) { case GRAPH_AS_SONOGRAM: return(TO_VAR_NAME(S_graph_as_sonogram)); break; case GRAPH_AS_SPECTROGRAM: return(TO_VAR_NAME(S_graph_as_spectrogram)); break; default: return(TO_VAR_NAME(S_graph_once)); break; } } static const char *time_graph_type_name(graph_type_t choice) { switch (choice) { case GRAPH_AS_WAVOGRAM: return(TO_VAR_NAME(S_graph_as_wavogram)); break; default: return(TO_VAR_NAME(S_graph_once)); break; } } static const char *x_axis_style_name(x_axis_style_t choice) { switch (choice) { case X_AXIS_AS_CLOCK: return(TO_VAR_NAME(S_x_axis_as_clock)); break; case X_AXIS_IN_SAMPLES: return(TO_VAR_NAME(S_x_axis_in_samples)); break; case X_AXIS_AS_PERCENTAGE: return(TO_VAR_NAME(S_x_axis_as_percentage)); break; case X_AXIS_IN_BEATS: return(TO_VAR_NAME(S_x_axis_in_beats)); break; case X_AXIS_IN_MEASURES: return(TO_VAR_NAME(S_x_axis_in_measures)); break; default: return(TO_VAR_NAME(S_x_axis_in_seconds)); break; } } static const char *speed_control_style_name(speed_style_t choice) { switch (choice) { case SPEED_CONTROL_AS_RATIO: return(TO_VAR_NAME(S_speed_control_as_ratio)); break; case SPEED_CONTROL_AS_SEMITONE: return(TO_VAR_NAME(S_speed_control_as_semitone)); break; default: return(TO_VAR_NAME(S_speed_control_as_float)); break; } } static const char *channel_style_name(channel_style_t choice) { switch (choice) { case CHANNELS_COMBINED: return(TO_VAR_NAME(S_channels_combined)); break; case CHANNELS_SUPERIMPOSED: return(TO_VAR_NAME(S_channels_superimposed)); break; default: return(TO_VAR_NAME(S_channels_separate)); break; } } static const char *sync_style_name(sync_style_t choice) { switch (choice) { case SYNC_NONE: return(TO_VAR_NAME(S_sync_none)); break; case SYNC_ALL: return(TO_VAR_NAME(S_sync_all)); break; default: return(TO_VAR_NAME(S_sync_by_sound)); break; } } static const char *enved_target_name(enved_target_t choice) { switch (choice) { case ENVED_SPECTRUM: return(TO_VAR_NAME(S_enved_spectrum)); break; case ENVED_SRATE: return(TO_VAR_NAME(S_enved_srate)); break; default: return(TO_VAR_NAME(S_enved_amplitude)); break; } } static const char *b2s(bool val) {return((val) ? (char *)PROC_TRUE : (char *)PROC_FALSE);} /* cast needed by g++ > 3.4 */ #if (!USE_NO_GUI) static char *colvarname = NULL; static char *colormap_variable_name(int col) { if (colvarname) free(colvarname); colvarname = (char *)calloc(64, sizeof(char)); snprintf(colvarname, 64, "%s-colormap", colormap_name(col)); return(colvarname); } #endif #define white_space " " static bool b_ok = false; #if HAVE_RUBY static void pss_ss(FILE *fd, const char *name, const char *val) {fprintf(fd, "set_%s(%s)\n", to_proc_name(name), val);} static void pss_sq(FILE *fd, const char *name, const char *val) {fprintf(fd, "set_%s(\"%s\")\n", to_proc_name(name), val);} static void pss_sd(FILE *fd, const char *name, int val) {fprintf(fd, "set_%s(%d)\n", to_proc_name(name), val);} static void pss_sod(FILE *fd, const char *name, mus_long_t val) {fprintf(fd, "set_%s(%lld)\n", to_proc_name(name), val);} static void pss_sf(FILE *fd, const char *name, mus_float_t val) {fprintf(fd, "set_%s(%.4f)\n", to_proc_name(name), val);} static void pss_sl(FILE *fd, const char *name, mus_float_t val1, mus_float_t val2) {fprintf(fd, "set_%s([%f, %f])\n", to_proc_name(name), val1, val2);} static void psp_ss(FILE *fd, const char *name, const char *val) {fprintf(fd, "%sset_%s(%s, sfile)\n", white_space, to_proc_name(name), val);} static void psp_sd(FILE *fd, const char *name, int val) {fprintf(fd, "%sset_%s(%d, sfile)\n", white_space, to_proc_name(name), val);} static void psp_sf(FILE *fd, const char *name, mus_float_t val) {fprintf(fd, "%sset_%s(%.4f, sfile)\n", white_space, to_proc_name(name), val);} static void psp_sl(FILE *fd, const char *name, mus_float_t val1, mus_float_t val2) {fprintf(fd, "%sset_%s([%f, %f], sfile)\n", white_space, to_proc_name(name), val1, val2);} static void pcp_ss(FILE *fd, const char *name, const char *val, int chan) {fprintf(fd, "%sset_%s(%s, sfile, %d)\n", white_space, to_proc_name(name), val, chan);} static void pcp_sss(FILE *fd, const char *name, const char *val, int chan, const char *grf) {fprintf(fd, "%sset_%s(\"%s\", sfile, %d, %s)\n", white_space, to_proc_name(name), val, chan, TO_VAR_NAME(grf));} static void pcp_sd(FILE *fd, const char *name, int val, int chan) {fprintf(fd, "%sset_%s(%d, sfile, %d)\n", white_space, to_proc_name(name), val, chan);} static void pcp_sod(FILE *fd, const char *name, mus_long_t val, int chan) {fprintf(fd, "%sset_%s(%lld, sfile, %d)\n", white_space, to_proc_name(name), val, chan);} static void pcp_sf(FILE *fd, const char *name, mus_float_t val, int chan) {fprintf(fd, "%sset_%s(%.4f, sfile, %d)\n", white_space, to_proc_name(name), val, chan);} static void pcp_sl(FILE *fd, const char *name, mus_float_t val1, mus_float_t val2, int chan) {fprintf(fd, "%sset_%s([%f, %f], sfile, %d)\n", white_space, to_proc_name(name), val1, val2, chan);} #endif #if HAVE_FORTH static void pss_ss(FILE *fd, const char *name, const char *val) {fprintf(fd, "%s set-%s drop\n", val, name);} static void pss_sq(FILE *fd, const char *name, const char *val) {fprintf(fd, "\"%s\" set-%s drop\n", val, name);} static void pss_sd(FILE *fd, const char *name, int val) {fprintf(fd, "%d set-%s drop\n", val, name);} static void pss_sod(FILE *fd, const char *name, mus_long_t val) {fprintf(fd, "%lld set-%s drop\n", val, name);} static void pss_sf(FILE *fd, const char *name, mus_float_t val) {fprintf(fd, "%.4f set-%s drop\n", val, name);} static void pss_sl(FILE *fd, const char *name, mus_float_t val1, mus_float_t val2) {fprintf(fd, "%s'( %f %f ) set-%s drop\n", white_space, val1, val2, name);} static void psp_ss(FILE *fd, const char *name, const char *val) {fprintf(fd, "%s%s sfile set-%s drop\n", white_space, val, name);} static void psp_sd(FILE *fd, const char *name, int val) {fprintf(fd, "%s%d sfile set-%s drop\n", white_space, val, name);} static void psp_sf(FILE *fd, const char *name, mus_float_t val) {fprintf(fd, "%s%.4f sfile set-%s drop\n", white_space, val, name);} static void psp_sl(FILE *fd, const char *name, mus_float_t val1, mus_float_t val2) {fprintf(fd, "%s'( %f %f ) sfile set-%s drop\n", white_space, val1, val2, name);} static void pcp_ss(FILE *fd, const char *name, const char *val, int chan) {fprintf(fd, "%s%s sfile %d set-%s drop\n", white_space, val, chan, name);} static void pcp_sss(FILE *fd, const char *name, const char *val, int chan, const char *grf) {fprintf(fd, "%s\"%s\" sfile %d %s set-%s drop\n", white_space, val, chan, grf, name);} static void pcp_sd(FILE *fd, const char *name, int val, int chan) {fprintf(fd, "%s%d sfile %d set-%s drop\n", white_space, val, chan, name);} static void pcp_sod(FILE *fd, const char *name, mus_long_t val, int chan) {fprintf(fd, "%s%lld sfile %d set-%s drop\n", white_space, val, chan, name);} static void pcp_sf(FILE *fd, const char *name, mus_float_t val, int chan) {fprintf(fd, "%s%.4f sfile %d set-%s drop\n", white_space, val, chan, name);} static void pcp_sl(FILE *fd, const char *name, mus_float_t val1, mus_float_t val2, int chan) {fprintf(fd, "%s'( %f %f ) sfile %d set-%s drop\n", white_space, val1, val2, chan, name);} #endif #if HAVE_SCHEME || (!HAVE_EXTENSION_LANGUAGE) static void pss_ss(FILE *fd, const char *name, const char *val) {fprintf(fd, "(set! (%s) %s)\n", name, val);} static void pss_sq(FILE *fd, const char *name, const char *val) {fprintf(fd, "(set! (%s) \"%s\")\n", name, val);} static void pss_sd(FILE *fd, const char *name, int val) {fprintf(fd, "(set! (%s) %d)\n", name, val);} static void pss_sod(FILE *fd, const char *name, mus_long_t val) {fprintf(fd, "(set! (%s) %lld)\n", name, val);} static void pss_sf(FILE *fd, const char *name, mus_float_t val) {fprintf(fd, "(set! (%s) %.4f)\n", name, val);} static void pss_sl(FILE *fd, const char *name, mus_float_t val1, mus_float_t val2) {fprintf(fd, "(set! (%s) (list %f %f))\n", name, val1, val2);} static void psp_ss(FILE *fd, const char *name, const char *val) {b_ok = true; fprintf(fd, "%s(set! (%s sfile) %s)\n", white_space, name, val);} static void psp_sd(FILE *fd, const char *name, int val) {b_ok = true; fprintf(fd, "%s(set! (%s sfile) %d)\n", white_space, name, val);} static void psp_sf(FILE *fd, const char *name, mus_float_t val) {b_ok = true; fprintf(fd, "%s(set! (%s sfile) %.4f)\n", white_space, name, val);} static void psp_sl(FILE *fd, const char *name, mus_float_t val1, mus_float_t val2) {b_ok = true; fprintf(fd, "%s(set! (%s sfile) (list %f %f))\n", white_space, name, val1, val2);} static void pcp_ss(FILE *fd, const char *name, const char *val, int chan) {b_ok = true; fprintf(fd, "%s(set! (%s sfile %d) %s)\n", white_space, name, chan, val);} static void pcp_sss(FILE *fd, const char *name, const char *val, int chan, const char *grf) {b_ok = true; fprintf(fd, "%s(set! (%s sfile %d %s) \"%s\")\n", white_space, name, chan, grf, val);} static void pcp_sd(FILE *fd, const char *name, int val, int chan) {b_ok = true; fprintf(fd, "%s(set! (%s sfile %d) %d)\n", white_space, name, chan, val);} static void pcp_sod(FILE *fd, const char *name, mus_long_t val, int chan) {b_ok = true; fprintf(fd, "%s(set! (%s sfile %d) %lld)\n", white_space, name, chan, val);} static void pcp_sf(FILE *fd, const char *name, mus_float_t val, int chan) {b_ok = true; fprintf(fd, "%s(set! (%s sfile %d) %.4f)\n", white_space, name, chan, val);} static void pcp_sl(FILE *fd, const char *name, mus_float_t val1, mus_float_t val2, int chan) {b_ok = true; fprintf(fd, "%s(set! (%s sfile %d) (list %f %f))\n", white_space, name, chan, val1, val2);} #endif static void save_options(FILE *fd) { fprintf(fd, "\n%s Snd %s (%s) options saved %s\n", Xen_comment_mark, SND_VERSION, SND_DATE, snd_local_time()); if (transform_size(ss) != DEFAULT_TRANSFORM_SIZE) pss_sod(fd, S_transform_size, transform_size(ss)); if (fft_window(ss) != DEFAULT_FFT_WINDOW) pss_ss(fd, S_fft_window, TO_VAR_NAME(mus_fft_window_xen_name(fft_window(ss)))); if (transform_graph_type(ss) != DEFAULT_TRANSFORM_GRAPH_TYPE) pss_ss(fd, S_transform_graph_type, transform_graph_type_name(transform_graph_type(ss))); if (time_graph_type(ss) != DEFAULT_TIME_GRAPH_TYPE) pss_ss(fd, S_time_graph_type, time_graph_type_name(time_graph_type(ss))); if (x_axis_style(ss) != DEFAULT_X_AXIS_STYLE) pss_ss(fd, S_x_axis_style, x_axis_style_name(x_axis_style(ss))); if (fneq(beats_per_minute(ss), DEFAULT_BEATS_PER_MINUTE)) pss_sf(fd, S_beats_per_minute, beats_per_minute(ss)); if (beats_per_measure(ss) != DEFAULT_BEATS_PER_MEASURE) pss_sd(fd, S_beats_per_measure, beats_per_measure(ss)); if (graph_style(ss) != DEFAULT_GRAPH_STYLE) pss_ss(fd, S_graph_style, graph_style_name(graph_style(ss))); if (region_graph_style(ss) != DEFAULT_GRAPH_STYLE) pss_ss(fd, S_region_graph_style, graph_style_name(region_graph_style(ss))); if (channel_style(ss) != DEFAULT_CHANNEL_STYLE) pss_ss(fd, S_channel_style, channel_style_name(channel_style(ss))); if (sync_style(ss) != DEFAULT_SYNC_STYLE) pss_ss(fd, S_sync_style, sync_style_name(sync_style(ss))); if (enved_target(ss) != DEFAULT_ENVED_TARGET) pss_ss(fd, S_enved_target, enved_target_name(enved_target(ss))); if (transform_type(ss) != DEFAULT_TRANSFORM_TYPE) pss_ss(fd, S_transform_type, TO_VAR_NAME(transform_program_name(transform_type(ss)))); if (zoom_focus_style(ss) != ZOOM_FOCUS_ACTIVE) pss_ss(fd, S_zoom_focus_style, zoom_focus_style_name(zoom_focus_style(ss))); if (transform_normalization(ss) != DEFAULT_TRANSFORM_NORMALIZATION) pss_ss(fd, S_transform_normalization, transform_normalization_name(transform_normalization(ss))); if (with_file_monitor(ss) != DEFAULT_WITH_FILE_MONITOR) pss_ss(fd, S_with_file_monitor, b2s(with_file_monitor(ss))); if (just_sounds(ss) != DEFAULT_JUST_SOUNDS) pss_ss(fd, S_just_sounds, b2s(just_sounds(ss))); if (play_arrow_size(ss) != DEFAULT_PLAY_ARROW_SIZE) pss_sd(fd, S_play_arrow_size, play_arrow_size(ss)); if (show_selection_transform(ss) != DEFAULT_SHOW_SELECTION_TRANSFORM) pss_ss(fd, S_show_selection_transform, b2s(show_selection_transform(ss))); if (with_gl(ss) != DEFAULT_WITH_GL) pss_ss(fd, S_with_gl, b2s(with_gl(ss))); if (with_mix_tags(ss) != DEFAULT_WITH_MIX_TAGS) pss_ss(fd, S_with_mix_tags, b2s(with_mix_tags(ss))); if (with_relative_panes(ss) != DEFAULT_WITH_RELATIVE_PANES) pss_ss(fd, S_with_relative_panes, b2s(with_relative_panes(ss))); if (sinc_width(ss) != DEFAULT_SINC_WIDTH) pss_sd(fd, S_sinc_width, sinc_width(ss)); if (ss->init_window_width != DEFAULT_INIT_WINDOW_WIDTH) pss_sd(fd, S_window_width, ss->init_window_width); if (ss->init_window_height != DEFAULT_INIT_WINDOW_HEIGHT) pss_sd(fd, S_window_height, ss->init_window_height); if (ss->init_window_x != DEFAULT_INIT_WINDOW_X) pss_sd(fd, S_window_x, ss->init_window_x); if (ss->init_window_y != DEFAULT_INIT_WINDOW_Y) pss_sd(fd, S_window_y, ss->init_window_y); if (default_output_chans(ss) != DEFAULT_OUTPUT_CHANS) pss_sd(fd, S_default_output_chans, default_output_chans(ss)); if (default_output_srate(ss) != DEFAULT_OUTPUT_SRATE) pss_sd(fd, S_default_output_srate, default_output_srate(ss)); if (default_output_header_type(ss) != DEFAULT_OUTPUT_HEADER_TYPE) pss_ss(fd, S_default_output_header_type, mus_header_type_to_string(default_output_header_type(ss))); if (default_output_sample_type(ss) != DEFAULT_OUTPUT_SAMPLE_TYPE) pss_ss(fd, S_default_output_sample_type, mus_sample_type_to_string(default_output_sample_type(ss))); if (auto_resize(ss) != DEFAULT_AUTO_RESIZE) pss_ss(fd, S_auto_resize, b2s(auto_resize(ss))); if (graphs_horizontal(ss) != DEFAULT_GRAPHS_HORIZONTAL) pss_ss(fd, S_graphs_horizontal, b2s(graphs_horizontal(ss))); if (auto_update(ss) != DEFAULT_AUTO_UPDATE) pss_ss(fd, S_auto_update, b2s(auto_update(ss))); if (color_inverted(ss) != DEFAULT_COLOR_INVERTED) pss_ss(fd, S_color_inverted, b2s(color_inverted(ss))); if (zero_pad(ss) != DEFAULT_ZERO_PAD) pss_sd(fd, S_zero_pad, zero_pad(ss)); if (ask_before_overwrite(ss) != DEFAULT_ASK_BEFORE_OVERWRITE) pss_ss(fd, S_ask_before_overwrite, b2s(ask_before_overwrite(ss))); if (with_toolbar(ss) != DEFAULT_WITH_TOOLBAR) pss_ss(fd, S_with_toolbar, b2s(with_toolbar(ss))); if (with_tooltips(ss) != DEFAULT_WITH_TOOLTIPS) pss_ss(fd, S_with_tooltips, b2s(with_tooltips(ss))); if (with_menu_icons(ss) != DEFAULT_WITH_MENU_ICONS) pss_ss(fd, S_with_menu_icons, b2s(with_menu_icons(ss))); if (remember_sound_state(ss) != DEFAULT_REMEMBER_SOUND_STATE) pss_ss(fd, S_remember_sound_state, b2s(remember_sound_state(ss))); if (ask_about_unsaved_edits(ss) != DEFAULT_ASK_ABOUT_UNSAVED_EDITS) pss_ss(fd, S_ask_about_unsaved_edits, b2s(ask_about_unsaved_edits(ss))); if (save_as_dialog_src(ss) != DEFAULT_SAVE_AS_DIALOG_SRC) pss_ss(fd, S_save_as_dialog_src, b2s(save_as_dialog_src(ss))); if (save_as_dialog_auto_comment(ss) != DEFAULT_SAVE_AS_DIALOG_AUTO_COMMENT) pss_ss(fd, S_save_as_dialog_auto_comment, b2s(save_as_dialog_auto_comment(ss))); if (show_full_duration(ss) != DEFAULT_SHOW_FULL_DURATION) pss_ss(fd, S_show_full_duration, b2s(show_full_duration(ss))); if (show_full_range(ss) != DEFAULT_SHOW_FULL_RANGE) pss_ss(fd, S_show_full_range, b2s(show_full_range(ss))); if (fneq(initial_beg(ss), DEFAULT_INITIAL_BEG)) pss_sf(fd, S_initial_beg, initial_beg(ss)); if (fneq(initial_dur(ss), DEFAULT_INITIAL_DUR)) pss_sf(fd, S_initial_dur, initial_dur(ss)); if (dac_combines_channels(ss) != DEFAULT_DAC_COMBINES_CHANNELS) pss_ss(fd, S_dac_combines_channels, b2s(dac_combines_channels(ss))); if (wavo_hop(ss) != DEFAULT_WAVO_HOP) pss_sd(fd, S_wavo_hop, wavo_hop(ss)); if (wavo_trace(ss) != DEFAULT_WAVO_TRACE) pss_sd(fd, S_wavo_trace, wavo_trace(ss)); if (spectro_hop(ss) != DEFAULT_SPECTRO_HOP) pss_sd(fd, S_spectro_hop, spectro_hop(ss)); #if (!USE_NO_GUI) if ((color_map(ss) != DEFAULT_COLOR_MAP) && (color_map(ss) <= 15)) pss_ss(fd, S_colormap, TO_GVAR_NAME(colormap_variable_name(color_map(ss)))); if (color_map_size(ss) != DEFAULT_COLOR_MAP_SIZE) pss_sd(fd, S_colormap_size, color_map_size(ss)); #endif if (wavelet_type(ss) != DEFAULT_WAVELET_TYPE) pss_sd(fd, S_wavelet_type, wavelet_type(ss)); if (cursor_style(ss) != DEFAULT_CURSOR_STYLE) pss_ss(fd, S_cursor_style, cursor_style_name(cursor_style(ss))); if (tracking_cursor_style(ss) != DEFAULT_TRACKING_CURSOR_STYLE) pss_ss(fd, S_tracking_cursor_style, cursor_style_name(tracking_cursor_style(ss))); if (cursor_size(ss) != DEFAULT_CURSOR_SIZE) pss_sd(fd, S_cursor_size, cursor_size(ss)); if (dot_size(ss) != DEFAULT_DOT_SIZE) pss_sd(fd, S_dot_size, dot_size(ss)); if (dac_size(ss) != DEFAULT_DAC_SIZE) pss_sd(fd, S_dac_size, dac_size(ss)); if (selection_creates_region(ss) != DEFAULT_SELECTION_CREATES_REGION) pss_ss(fd, S_selection_creates_region, b2s(selection_creates_region(ss))); if (enved_filter_order(ss) != DEFAULT_ENVED_FILTER_ORDER) pss_sd(fd, S_enved_filter_order, enved_filter_order(ss)); if (max_transform_peaks(ss) != DEFAULT_MAX_TRANSFORM_PEAKS) pss_sd(fd, S_max_transform_peaks, max_transform_peaks(ss)); if (max_regions(ss) != DEFAULT_MAX_REGIONS) pss_sd(fd, S_max_regions, max_regions(ss)); if (fneq(auto_update_interval(ss), DEFAULT_AUTO_UPDATE_INTERVAL)) pss_sf(fd, S_auto_update_interval, auto_update_interval(ss)); if (fneq(cursor_update_interval(ss), DEFAULT_CURSOR_UPDATE_INTERVAL)) pss_sf(fd, S_cursor_update_interval, cursor_update_interval(ss)); if (cursor_location_offset(ss) != DEFAULT_CURSOR_LOCATION_OFFSET) pss_sd(fd, S_cursor_location_offset, cursor_location_offset(ss)); if (with_verbose_cursor(ss) != DEFAULT_WITH_VERBOSE_CURSOR) pss_ss(fd, S_with_verbose_cursor, b2s(with_verbose_cursor(ss))); if (with_inset_graph(ss) != DEFAULT_WITH_INSET_GRAPH) pss_ss(fd, S_with_inset_graph, b2s(with_inset_graph(ss))); if (with_interrupts(ss) != DEFAULT_WITH_INTERRUPTS) pss_ss(fd, S_with_interrupts, b2s(with_interrupts(ss))); if (with_smpte_label(ss) != DEFAULT_WITH_SMPTE_LABEL) pss_ss(fd, S_with_smpte_label, b2s(with_smpte_label(ss))); if (with_pointer_focus(ss) != DEFAULT_WITH_POINTER_FOCUS) pss_ss(fd, S_with_pointer_focus, b2s(with_pointer_focus(ss))); if (show_indices(ss) != DEFAULT_SHOW_INDICES) pss_ss(fd, S_show_indices, b2s(show_indices(ss))); if (show_transform_peaks(ss) != DEFAULT_SHOW_TRANSFORM_PEAKS) pss_ss(fd, S_show_transform_peaks, b2s(show_transform_peaks(ss))); if (show_y_zero(ss) != DEFAULT_SHOW_Y_ZERO) pss_ss(fd, S_show_y_zero, b2s(show_y_zero(ss))); if (show_grid(ss) != DEFAULT_SHOW_GRID) pss_ss(fd, S_show_grid, b2s((bool)show_grid(ss))); if (fneq(grid_density(ss), DEFAULT_GRID_DENSITY)) pss_sf(fd, S_grid_density, grid_density(ss)); if (show_sonogram_cursor(ss) != DEFAULT_SHOW_SONOGRAM_CURSOR) pss_ss(fd, S_show_sonogram_cursor, b2s(show_sonogram_cursor(ss))); if (show_axes(ss) != DEFAULT_SHOW_AXES) pss_ss(fd, S_show_axes, show_axes2string(show_axes(ss))); if (show_marks(ss) != DEFAULT_SHOW_MARKS) pss_ss(fd, S_show_marks, b2s(show_marks(ss))); if (clipping(ss) != DEFAULT_CLIPPING) pss_ss(fd, S_clipping, b2s(clipping(ss))); #if USE_MOTIF if (view_files_sort(ss) != DEFAULT_VIEW_FILES_SORT) pss_sd(fd, S_view_files_sort, view_files_sort(ss)); #endif if (fft_log_magnitude(ss) != DEFAULT_FFT_LOG_MAGNITUDE) pss_ss(fd, S_fft_log_magnitude, b2s(fft_log_magnitude(ss))); if (fft_log_frequency(ss) != DEFAULT_FFT_LOG_FREQUENCY) pss_ss(fd, S_fft_log_frequency, b2s(fft_log_frequency(ss))); if (fft_with_phases(ss) != DEFAULT_FFT_WITH_PHASES) pss_ss(fd, S_fft_with_phases, b2s(fft_with_phases(ss))); if (print_length(ss) != DEFAULT_PRINT_LENGTH) pss_sd(fd, S_print_length, print_length(ss)); if (show_mix_waveforms(ss) != DEFAULT_SHOW_MIX_WAVEFORMS) pss_ss(fd, S_show_mix_waveforms, b2s(show_mix_waveforms(ss))); if (mix_waveform_height(ss) != DEFAULT_MIX_WAVEFORM_HEIGHT) pss_sd(fd, S_mix_waveform_height, mix_waveform_height(ss)); if (mix_tag_height(ss) != DEFAULT_MIX_TAG_HEIGHT) pss_sd(fd, S_mix_tag_height, mix_tag_height(ss)); if (mix_tag_width(ss) != DEFAULT_MIX_TAG_WIDTH) pss_sd(fd, S_mix_tag_width, mix_tag_width(ss)); if (mark_tag_height(ss) != DEFAULT_MARK_TAG_HEIGHT) pss_sd(fd, S_mark_tag_height, mark_tag_height(ss)); if (mark_tag_width(ss) != DEFAULT_MARK_TAG_WIDTH) pss_sd(fd, S_mark_tag_width, mark_tag_width(ss)); if (enved_with_wave(ss) != DEFAULT_ENVED_WITH_WAVE) pss_ss(fd, S_enved_with_wave, b2s(enved_with_wave(ss))); if (enved_in_dB(ss) != DEFAULT_ENVED_IN_DB) pss_ss(fd, S_enved_in_dB, b2s(enved_in_dB(ss))); if (enved_clipping(ss) != DEFAULT_ENVED_CLIPPING) pss_ss(fd, S_enved_clipping, b2s(enved_clipping(ss))); if (enved_style(ss) == ENVELOPE_EXPONENTIAL) pss_ss(fd, S_enved_style, TO_VAR_NAME(S_envelope_exponential)); if ((!tiny_font(ss)) || (!(mus_strcmp(tiny_font(ss), DEFAULT_TINY_FONT)))) pss_sq(fd, S_tiny_font, tiny_font(ss)); if ((!peaks_font(ss)) || (!(mus_strcmp(peaks_font(ss), DEFAULT_PEAKS_FONT)))) pss_sq(fd, S_peaks_font, peaks_font(ss)); if ((!bold_peaks_font(ss)) || (!(mus_strcmp(bold_peaks_font(ss), DEFAULT_BOLD_PEAKS_FONT)))) pss_sq(fd, S_bold_peaks_font, bold_peaks_font(ss)); if ((!axis_label_font(ss)) || (!(mus_strcmp(axis_label_font(ss), DEFAULT_AXIS_LABEL_FONT)))) pss_sq(fd, S_axis_label_font, axis_label_font(ss)); if ((!axis_numbers_font(ss)) || (!(mus_strcmp(axis_numbers_font(ss), DEFAULT_AXIS_NUMBERS_FONT)))) pss_sq(fd, S_axis_numbers_font, axis_numbers_font(ss)); if (listener_font(ss)) pss_sq(fd, S_listener_font, listener_font(ss)); if (listener_is_visible()) pss_ss(fd, S_show_listener, b2s(true)); #if USE_MOTIF || USE_GTK if (in_graph_cursor(ss) != DEFAULT_GRAPH_CURSOR) pss_sd(fd, S_graph_cursor, in_graph_cursor(ss)); #endif save_added_sound_file_extensions(fd); save_added_source_file_extensions(fd); if (save_state_file(ss)) pss_sq(fd, S_save_state_file, save_state_file(ss)); if (peak_env_dir(ss)) pss_sq(fd, S_peak_env_dir, peak_env_dir(ss)); if (temp_dir(ss)) pss_sq(fd, S_temp_dir, temp_dir(ss)); if (save_dir(ss)) pss_sq(fd, S_save_dir, save_dir(ss)); if (open_file_dialog_directory(ss)) pss_sq(fd, S_open_file_dialog_directory, open_file_dialog_directory(ss)); if (ladspa_dir(ss)) pss_sq(fd, S_ladspa_dir, ladspa_dir(ss)); if ((eps_file(ss)) && (!(mus_strcmp(eps_file(ss), DEFAULT_EPS_FILE)))) pss_sq(fd, S_eps_file, eps_file(ss)); if ((listener_prompt(ss)) && (!(mus_strcmp(listener_prompt(ss), DEFAULT_LISTENER_PROMPT)))) pss_sq(fd, S_listener_prompt, listener_prompt(ss)); if ((html_program(ss)) && (!(mus_strcmp(html_program(ss), DEFAULT_HTML_PROGRAM)))) pss_sq(fd, S_html_program, html_program(ss)); if (html_dir(ss)) pss_sq(fd, S_html_dir, html_dir(ss)); if (fneq(fft_window_alpha(ss), DEFAULT_FFT_WINDOW_ALPHA)) pss_sf(fd, S_fft_window_alpha, fft_window_alpha(ss)); if (fneq(fft_window_beta(ss), DEFAULT_FFT_WINDOW_BETA)) pss_sf(fd, S_fft_window_beta, fft_window_beta(ss)); if (fneq(min_dB(ss), DEFAULT_MIN_DB)) pss_sf(fd, S_min_dB, min_dB(ss)); if (fneq(log_freq_start(ss), DEFAULT_LOG_FREQ_START)) pss_sf(fd, S_log_freq_start, log_freq_start(ss)); if (fneq(color_cutoff(ss), DEFAULT_COLOR_CUTOFF)) pss_sf(fd, S_color_cutoff, color_cutoff(ss)); if (fneq(color_scale(ss), DEFAULT_COLOR_SCALE)) pss_sf(fd, S_color_scale, color_scale(ss)); if (fneq(spectro_x_scale(ss), DEFAULT_SPECTRO_X_SCALE)) pss_sf(fd, S_spectro_x_scale, spectro_x_scale(ss)); if (fneq(spectro_y_scale(ss), DEFAULT_SPECTRO_Y_SCALE)) pss_sf(fd, S_spectro_y_scale, spectro_y_scale(ss)); if (fneq(spectro_z_scale(ss), DEFAULT_SPECTRO_Z_SCALE)) pss_sf(fd, S_spectro_z_scale, spectro_z_scale(ss)); if (fneq(spectro_z_angle(ss), DEFAULT_SPECTRO_Z_ANGLE)) pss_sf(fd, S_spectro_z_angle, spectro_z_angle(ss)); if (fneq(spectro_x_angle(ss), DEFAULT_SPECTRO_X_ANGLE)) pss_sf(fd, S_spectro_x_angle, spectro_x_angle(ss)); if (fneq(spectro_y_angle(ss), DEFAULT_SPECTRO_Y_ANGLE)) pss_sf(fd, S_spectro_y_angle, spectro_y_angle(ss)); if (fneq(spectrum_end(ss), DEFAULT_SPECTRUM_END)) pss_sf(fd, S_spectrum_end, spectrum_end(ss)); if (fneq(spectrum_start(ss), DEFAULT_SPECTRUM_START)) pss_sf(fd, S_spectrum_start, spectrum_start(ss)); if (fneq(enved_base(ss), DEFAULT_ENVED_BASE)) pss_sf(fd, S_enved_base, enved_base(ss)); if (fneq(enved_power(ss), DEFAULT_ENVED_POWER)) pss_sf(fd, S_enved_power, enved_power(ss)); if (fneq(eps_bottom_margin(ss), DEFAULT_EPS_BOTTOM_MARGIN)) pss_sf(fd, S_eps_bottom_margin, eps_bottom_margin(ss)); if (fneq(eps_left_margin(ss), DEFAULT_EPS_LEFT_MARGIN)) pss_sf(fd, S_eps_left_margin, eps_left_margin(ss)); if (fneq(eps_size(ss), DEFAULT_EPS_SIZE)) pss_sf(fd, S_eps_size, eps_size(ss)); if ((fneq(contrast_control_min(ss), DEFAULT_CONTRAST_CONTROL_MIN)) || (fneq(contrast_control_max(ss), DEFAULT_CONTRAST_CONTROL_MAX))) pss_sl(fd, S_contrast_control_bounds, contrast_control_min(ss), contrast_control_max(ss)); if (fneq(contrast_control_amp(ss), DEFAULT_CONTRAST_CONTROL_AMP)) pss_sf(fd, S_contrast_control_amp, contrast_control_amp(ss)); if ((fneq(expand_control_min(ss), DEFAULT_EXPAND_CONTROL_MIN)) || (fneq(expand_control_max(ss), DEFAULT_EXPAND_CONTROL_MAX))) pss_sl(fd, S_expand_control_bounds, expand_control_min(ss), expand_control_max(ss)); if (fneq(expand_control_ramp(ss), DEFAULT_EXPAND_CONTROL_RAMP)) pss_sf(fd, S_expand_control_ramp, expand_control_ramp(ss)); if (fneq(expand_control_hop(ss), DEFAULT_EXPAND_CONTROL_HOP)) pss_sf(fd, S_expand_control_hop, expand_control_hop(ss)); if (fneq(expand_control_jitter(ss), DEFAULT_EXPAND_CONTROL_JITTER)) pss_sf(fd, S_expand_control_jitter, expand_control_jitter(ss)); if (fneq(expand_control_length(ss), DEFAULT_EXPAND_CONTROL_LENGTH)) pss_sf(fd, S_expand_control_length, expand_control_length(ss)); if (speed_control_tones(ss) != DEFAULT_SPEED_CONTROL_TONES) pss_sd(fd, S_speed_control_tones, speed_control_tones(ss)); if (speed_control_style(ss) != DEFAULT_SPEED_CONTROL_STYLE) pss_ss(fd, S_speed_control_style, speed_control_style_name(speed_control_style(ss))); if ((fneq(speed_control_min(ss), DEFAULT_SPEED_CONTROL_MIN)) || (fneq(speed_control_max(ss), DEFAULT_SPEED_CONTROL_MAX))) pss_sl(fd, S_speed_control_bounds, speed_control_min(ss), speed_control_max(ss)); if ((fneq(reverb_control_scale_min(ss), DEFAULT_REVERB_CONTROL_SCALE_MIN)) || (fneq(reverb_control_scale_max(ss), DEFAULT_REVERB_CONTROL_SCALE_MAX))) pss_sl(fd, S_reverb_control_scale_bounds, reverb_control_scale_min(ss), reverb_control_scale_max(ss)); if ((fneq(reverb_control_length_min(ss), DEFAULT_REVERB_CONTROL_LENGTH_MIN)) || (fneq(reverb_control_length_max(ss), DEFAULT_REVERB_CONTROL_LENGTH_MAX))) pss_sl(fd, S_reverb_control_length_bounds, reverb_control_length_min(ss), reverb_control_length_max(ss)); if (fneq(reverb_control_feedback(ss), DEFAULT_REVERB_CONTROL_FEEDBACK)) pss_sf(fd, S_reverb_control_feedback, reverb_control_feedback(ss)); if (fneq(reverb_control_lowpass(ss), DEFAULT_REVERB_CONTROL_LOWPASS)) pss_sf(fd, S_reverb_control_lowpass, reverb_control_lowpass(ss)); if (fneq(reverb_control_decay(ss), DEFAULT_REVERB_CONTROL_DECAY)) pss_sf(fd, S_reverb_control_decay, reverb_control_decay(ss)); if ((fneq(amp_control_min(ss), DEFAULT_AMP_CONTROL_MIN)) || (fneq(amp_control_max(ss), DEFAULT_AMP_CONTROL_MAX))) pss_sl(fd, S_amp_control_bounds, amp_control_min(ss), amp_control_max(ss)); if (filter_control_order(ss) != DEFAULT_FILTER_CONTROL_ORDER) pss_sd(fd, S_filter_control_order, filter_control_order(ss)); if (filter_control_in_dB(ss) != DEFAULT_FILTER_CONTROL_IN_DB) pss_ss(fd, S_filter_control_in_dB, b2s(filter_control_in_dB(ss))); if (filter_control_in_hz(ss) != DEFAULT_FILTER_CONTROL_IN_HZ) pss_ss(fd, S_filter_control_in_hz, b2s(filter_control_in_hz(ss))); if (with_tracking_cursor(ss) != DEFAULT_WITH_TRACKING_CURSOR) pss_sd(fd, S_with_tracking_cursor, (int)with_tracking_cursor(ss)); if (in_show_controls(ss) != DEFAULT_SHOW_CONTROLS) pss_ss(fd, S_show_controls, b2s(in_show_controls(ss))); save_colors(fd); if (fneq(mus_srate(), MUS_DEFAULT_SAMPLING_RATE)) pss_sf(fd, S_mus_srate, mus_srate()); if (mus_file_buffer_size() != MUS_DEFAULT_FILE_BUFFER_SIZE) pss_sd(fd, S_mus_file_buffer_size, mus_file_buffer_size()); if (mus_array_print_length() != MUS_DEFAULT_ARRAY_PRINT_LENGTH) pss_sd(fd, S_mus_array_print_length, mus_array_print_length()); if (clm_default_table_size_c() != MUS_CLM_DEFAULT_TABLE_SIZE) pss_sod(fd, S_clm_table_size, clm_default_table_size_c()); if (fneq(clm_default_frequency_c(), MUS_CLM_DEFAULT_FREQUENCY)) pss_sf(fd, S_clm_default_frequency, clm_default_frequency_c()); { int srate = 0, chans = 0; mus_sample_t samp_type = MUS_UNKNOWN_SAMPLE; mus_header_raw_defaults(&srate, &chans, &samp_type); if ((chans != 2) || (srate != 44100) || (samp_type != MUS_BSHORT)) { #if HAVE_SCHEME fprintf(fd, "(set! (mus-header-raw-defaults) (list %d %d %s))\n", srate, chans, mus_sample_type_to_string(samp_type)); #endif #if HAVE_RUBY fprintf(fd, "set_mus_header_raw_defaults([%d, %d, %s])\n", srate, chans, mus_sample_type_to_string(samp_type)); #endif #if HAVE_FORTH fprintf(fd, "'( %d %d %s ) set-mus-header-raw-defaults drop\n", srate, chans, mus_sample_type_to_string(samp_type)); #endif } } fprintf(fd, "%s end of snd options\n", Xen_comment_mark); } /* next two are for the help menu */ void global_control_panel_state(void) { char *buf; snd_help_append("\n\nCurrent control panel defaults:\n\n"); buf = (char *)calloc(1024, sizeof(char)); snprintf(buf, 1024, "amp bounds: %.3f to %.3f\n", amp_control_min(ss), amp_control_max(ss)); snd_help_append(buf); snprintf(buf, 1024, "speed bounds: %.3f to %.3f, tones: %d, style: %s\n", speed_control_min(ss), speed_control_max(ss), speed_control_tones(ss), speed_control_style_name(speed_control_style(ss))); snd_help_append(buf); snprintf(buf, 1024, "expand bounds: %.3f to %.3f, ramp: %.3f, hop: %.3f, length: %.3f, jitter: %.3f\n", expand_control_min(ss), expand_control_max(ss), expand_control_ramp(ss), expand_control_hop(ss), expand_control_length(ss), expand_control_jitter(ss)); snd_help_append(buf); snprintf(buf, 1024, "contrast bounds: %.3f to %.3f, amp: %.3f\n", contrast_control_min(ss), contrast_control_max(ss), contrast_control_amp(ss)); snd_help_append(buf); snprintf(buf, 1024, "reverb scale: %.3f to %.3f, length: %.3f to %.3f, feedbacl: %.3f, lowpass: %.3f, decay: %.3f\n", reverb_control_scale_min(ss), reverb_control_scale_max(ss), reverb_control_length_min(ss), reverb_control_length_max(ss), reverb_control_feedback(ss), reverb_control_lowpass(ss), reverb_control_decay(ss)); snd_help_append(buf); snprintf(buf, 1024, "filter order: %d, in dB: %s, in Hz: %s\n", filter_control_order(ss), b2s(filter_control_in_dB(ss)), b2s(filter_control_in_hz(ss))); snd_help_append(buf); snd_help_back_to_top(); free(buf); } void global_fft_state(void) { char *buf; snd_help_append("\n\nCurrent FFT defaults:\n\n"); buf = (char *)calloc(1024, sizeof(char)); snprintf(buf, 1024, "fft size: %lld\n type: %s\n window: %s (alpha: %.3f, beta: %.3f)\n", transform_size(ss), TO_VAR_NAME(transform_program_name(transform_type(ss))), TO_VAR_NAME(mus_fft_window_xen_name(fft_window(ss))), fft_window_alpha(ss), fft_window_beta(ss)); snd_help_append(buf); snprintf(buf, 1024, " graph-type: %s\n show-peaks: %s (max: %d)\n show-selection-fft: %s\n", transform_graph_type_name(transform_graph_type(ss)), b2s(show_transform_peaks(ss)), max_transform_peaks(ss), b2s(show_selection_transform(ss))); snd_help_append(buf); snprintf(buf, 1024, " log freq: %s (start: %.3f)\n dB: %s, min-dB: %.3f\n normalization: %s\n", b2s(fft_log_frequency(ss)), log_freq_start(ss), b2s(fft_log_magnitude(ss)), min_dB(ss), transform_normalization_name(transform_normalization(ss))); snd_help_append(buf); snd_help_back_to_top(); free(buf); } #if HAVE_SCHEME static void set_print_lengths(int len); static void save_property_list(FILE *fd, Xen property_list, int chan, int edpos) { Xen ignore_list; int old_print_length, old_vct_print_length; int old_s7_print_length; old_s7_print_length = s7_print_length(s7); old_vct_print_length = mus_vct_print_length(); old_print_length = print_length(ss); /* make sure we don't truncate vector output with "..." */ set_print_lengths(1000000); /* this sets all three lengths */ ignore_list = Xen_assoc(C_string_to_Xen_symbol("save-state-ignore"), property_list); if (!(Xen_is_list(ignore_list))) { char *temp = NULL; if (chan == -1) fprintf(fd, "%s(set! (%s sfile) \'%s)\n", white_space, S_sound_properties, temp = Xen_object_to_C_string(property_list)); else { if (edpos == -1) fprintf(fd, "%s(set! (%s sfile %d) \'%s)\n", white_space, S_channel_properties, chan, temp = Xen_object_to_C_string(property_list)); else fprintf(fd, "%s(set! (%s sfile %d %d) \'%s)\n", white_space, S_edit_properties, chan, edpos, temp = Xen_object_to_C_string(property_list)); } if (temp) free(temp); } else { Xen new_properties = Xen_empty_list; int i, property_len, gc_loc; gc_loc = snd_protect(new_properties); property_len = Xen_list_length(property_list); for (i = 0; i < property_len; i++) { Xen property; property = Xen_list_ref(property_list, i); if (Xen_is_false(Xen_member(Xen_car(property), ignore_list))) new_properties = Xen_cons(property, new_properties); } if (!(Xen_is_null(new_properties))) { char *temp = NULL; if (chan == -1) fprintf(fd, "%s(set! (%s sfile) \'%s)\n", white_space, S_sound_properties, temp = Xen_object_to_C_string(new_properties)); else { if (edpos == -1) fprintf(fd, "%s(set! (%s sfile %d) \'%s)\n", white_space, S_channel_properties, chan, temp = Xen_object_to_C_string(new_properties)); else fprintf(fd, "%s(set! (%s sfile %d %d) \'%s)\n", white_space, S_edit_properties, chan, edpos, temp = Xen_object_to_C_string(new_properties)); } if (temp) free(temp); } snd_unprotect_at(gc_loc); } /* restore the various print lengths */ set_print_length(old_print_length); mus_vct_set_print_length(old_vct_print_length); s7_set_print_length(s7, old_s7_print_length); } #endif #if HAVE_RUBY static void save_property_list(FILE *fd, Xen property_list, int chan, int edpos) { Xen ignore_list; ignore_list = rb_ary_assoc(property_list, C_string_to_Xen_symbol("save_state_ignore")); if (!(Xen_is_vector(ignore_list))) { if (chan == -1) fprintf(fd, "%sset_%s(%s, sfile)\n", white_space, to_proc_name(S_sound_properties), Xen_object_to_C_string(property_list)); else { if (edpos == -1) fprintf(fd, "%sset_%s(%s, sfile, %d)\n", white_space, to_proc_name(S_channel_properties), Xen_object_to_C_string(property_list), chan); else fprintf(fd, "%sset_%s(%s, sfile, %d, %d)\n", white_space, to_proc_name(S_edit_properties), Xen_object_to_C_string(property_list), chan, edpos); } } else { Xen ignore_vec, new_properties = Xen_empty_list; int i, property_len, gc_loc; gc_loc = snd_protect(new_properties); property_len = Xen_list_length(property_list); ignore_vec = Xen_vector_ref(ignore_list, 1); if (Xen_is_vector(ignore_vec)) { for (i = 0; i < property_len; i++) { Xen property; property = Xen_list_ref(property_list, i); if (Xen_is_false(rb_ary_includes(ignore_vec, Xen_car(property)))) new_properties = Xen_cons(property, new_properties); } } else { for (i = 0; i < property_len; i++) new_properties = Xen_cons(Xen_list_ref(property_list, i), new_properties); } if (!(Xen_is_null(new_properties))) { if (chan == -1) fprintf(fd, "%sset_%s(%s, sfile)\n", white_space, to_proc_name(S_sound_properties), Xen_object_to_C_string(new_properties)); else { if (edpos == -1) fprintf(fd, "%sset_%s(%s, sfile, %d)\n", white_space, to_proc_name(S_channel_properties), Xen_object_to_C_string(new_properties), chan); else fprintf(fd, "%sset_%s(%s, sfile, %d, %d)\n", white_space, to_proc_name(S_edit_properties), Xen_object_to_C_string(new_properties), chan, edpos); } } snd_unprotect_at(gc_loc); } } #endif #if HAVE_FORTH static void save_property_list(FILE *fd, Xen property_list, int chan, int edpos) { Xen ignore_list; ignore_list = Xen_assoc(C_string_to_Xen_symbol("save-state-ignore"), property_list); if (!(Xen_is_list(ignore_list))) { if (chan == -1) fprintf(fd, "%s%s sfile set-%s drop\n", white_space, fth_to_c_dump(property_list), S_sound_properties); else { if (edpos == -1) fprintf(fd, "%s%s sfile %d set-%s drop\n", white_space, fth_to_c_dump(property_list), chan, S_channel_properties); else fprintf(fd, "%s%s sfile %d %d set-%s drop\n", white_space, fth_to_c_dump(property_list), chan, edpos, S_edit_properties); } } else { Xen new_properties = Xen_empty_list; int i, property_len, gc_loc; gc_loc = snd_protect(new_properties); property_len = Xen_list_length(property_list); for (i = 0; i < property_len; i++) { Xen property; property = Xen_list_ref(property_list, i); if (Xen_is_false(Xen_member(Xen_car(property), ignore_list))) new_properties = Xen_cons(property, new_properties); } if (!(Xen_is_null(new_properties))) { if (chan == -1) fprintf(fd, "%s%s sfile set-%s drop\n", white_space, fth_to_c_dump(new_properties), S_sound_properties); else { if (edpos == -1) fprintf(fd, "%s%s sfile %d set-%s drop\n", white_space, fth_to_c_dump(new_properties), chan, S_channel_properties); else fprintf(fd, "%s%s sfile %d %d set-%s drop\n", white_space, fth_to_c_dump(new_properties), chan, edpos, S_edit_properties); } } snd_unprotect_at(gc_loc); } } #endif #if (!HAVE_EXTENSION_LANGUAGE) static void save_property_list(FILE *fd, Xen property_list, int chan, int edpos) {} #endif static void check_selection(FILE *fd, chan_info *cp) { if (selection_is_active_in_channel(cp)) { mus_long_t beg, end; beg = selection_beg(cp); end = selection_end(cp); pcp_ss(fd, S_selection_member, b2s(true), cp->chan); pcp_sod(fd, S_selection_position, beg, cp->chan); pcp_sod(fd, S_selection_framples, end - beg + 1, cp->chan); } } static int find_sound_nth(snd_info *nsp) { int i, which = 0; for (i = 0; i < nsp->index; i++) { snd_info *sp; sp = ss->sounds[i]; if ((sp) && (sp->inuse == SOUND_NORMAL)) if ((mus_strcmp(nsp->short_filename, sp->short_filename)) || (mus_strcmp(nsp->filename, sp->filename))) which++; } return(which); } void open_save_sound_block(snd_info *sp, FILE *fd, bool with_nth) { /* here we have to use the 'nth' arg to find_sound -- it should return #f if such an 'nth' case is not found, * so that we can tell when to open another view on a given file */ #if HAVE_RUBY fprintf(fd, "begin\n sfile = %s(\"%s\", %d)\n if (sfile == false)\n sfile = %s(\"%s\")\n end\n", to_proc_name(S_find_sound), sp->short_filename, (with_nth) ? find_sound_nth(sp) : 0, to_proc_name((sp->user_read_only == FILE_READ_ONLY) ? S_view_sound : S_open_sound), sp->filename); #endif #if HAVE_SCHEME fprintf(fd, "(let ((sfile (or (%s \"%s\" %d) (%s \"%s\"))))\n (if sfile\n (begin\n", S_find_sound, sp->short_filename, /* short filename ok because find-sound searches for that name as well as the full filename */ (with_nth) ? find_sound_nth(sp) : 0, (sp->user_read_only == FILE_READ_ONLY) ? S_view_sound : S_open_sound, sp->filename); #endif #if HAVE_FORTH fprintf(fd, "\"%s\" %d %s to sfile\nsfile false? [if] \"%s\" %s to sfile [then]\n", sp->short_filename, (with_nth) ? find_sound_nth(sp) : 0, S_find_sound, sp->filename, (sp->user_read_only == FILE_READ_ONLY) ? S_view_sound : S_open_sound); #endif } void close_save_sound_block(FILE *fd, bool need_f) { #if HAVE_RUBY fprintf(fd, "end\n"); #endif #if HAVE_SCHEME if (need_f) fprintf(fd, " #f)))\n"); /* avoid empty begin if no field was output */ else fprintf(fd, " )))\n"); #endif #if HAVE_FORTH fprintf(fd, "\n"); #endif } static bool is_default_envelope(env *e) { return((e) && (e->pts == 2) && (e->base == 1.0) && (e->data[0] == 0.0) && (e->data[1] == 1.0) && (e->data[2] == 1.0) && (e->data[3] == 1.0)); } void save_sound_state(snd_info *sp, void *ptr) { /* called only after the global settings have been established, so here we can't use the DEFAULT_* macros that are ambiguous */ int chan; FILE *fd; chan_info *cp; fd = (FILE *)ptr; open_save_sound_block(sp, fd, true); b_ok = false; if (sp->sync != DEFAULT_SYNC) psp_sd(fd, S_sync, sp->sync); if (sp->contrast_control_on != DEFAULT_CONTRAST_CONTROL_ON) psp_ss(fd, S_contrast_control_on, b2s(sp->contrast_control_on)); if (fneq(sp->contrast_control, DEFAULT_CONTRAST_CONTROL)) psp_sf(fd, S_contrast_control, sp->contrast_control); if ((fneq(sp->contrast_control_min, DEFAULT_CONTRAST_CONTROL_MIN)) || (fneq(sp->contrast_control_max, DEFAULT_CONTRAST_CONTROL_MAX))) psp_sl(fd, S_contrast_control_bounds, sp->contrast_control_min, sp->contrast_control_max); if (fneq(sp->contrast_control_amp, DEFAULT_CONTRAST_CONTROL_AMP)) psp_sf(fd, S_contrast_control_amp, sp->contrast_control_amp); if (sp->expand_control_on != DEFAULT_EXPAND_CONTROL_ON) psp_ss(fd, S_expand_control_on, b2s(sp->expand_control_on)); if (fneq(sp->expand_control, DEFAULT_EXPAND_CONTROL)) psp_sf(fd, S_expand_control, sp->expand_control); if ((fneq(sp->expand_control_min, DEFAULT_EXPAND_CONTROL_MIN)) || (fneq(sp->expand_control_max, DEFAULT_EXPAND_CONTROL_MAX))) psp_sl(fd, S_expand_control_bounds, sp->expand_control_min, sp->expand_control_max); if (fneq(sp->expand_control_ramp, DEFAULT_EXPAND_CONTROL_RAMP)) psp_sf(fd, S_expand_control_ramp, sp->expand_control_ramp); if (fneq(sp->expand_control_hop, DEFAULT_EXPAND_CONTROL_HOP)) psp_sf(fd, S_expand_control_hop, sp->expand_control_hop); if (fneq(sp->expand_control_jitter, DEFAULT_EXPAND_CONTROL_JITTER)) psp_sf(fd, S_expand_control_jitter, sp->expand_control_jitter); if (fneq(sp->expand_control_length, DEFAULT_EXPAND_CONTROL_LENGTH)) psp_sf(fd, S_expand_control_length, sp->expand_control_length); if (sp->speed_control_tones != DEFAULT_SPEED_CONTROL_TONES) psp_sd(fd, S_speed_control_tones, sp->speed_control_tones); if (sp->speed_control_style != DEFAULT_SPEED_CONTROL_STYLE) psp_ss(fd, S_speed_control_style, speed_control_style_name(sp->speed_control_style)); if (fneq(sp->speed_control, DEFAULT_SPEED_CONTROL)) { #if XEN_HAVE_RATIOS if (sp->speed_control == SPEED_CONTROL_AS_RATIO) { /* no ratios in Ruby */ #if HAVE_FORTH fprintf(fd, "%s%d/%d set-%s drop\n", white_space, sp->speed_control_numerator, sp->speed_control_denominator, S_speed_control); #else fprintf(fd, "%s(set! (%s sfile) %d/%d)\n", white_space, S_speed_control, sp->speed_control_numerator, sp->speed_control_denominator); #endif } else #endif psp_sf(fd, S_speed_control, sp->speed_control); } if ((fneq(sp->speed_control_min, DEFAULT_SPEED_CONTROL_MIN)) || (fneq(sp->speed_control_max, DEFAULT_SPEED_CONTROL_MAX))) psp_sl(fd, S_speed_control_bounds, sp->speed_control_min, sp->speed_control_max); if (sp->reverb_control_on != DEFAULT_REVERB_CONTROL_ON) psp_ss(fd, S_reverb_control_on, b2s(sp->reverb_control_on)); if (fneq(sp->reverb_control_scale, DEFAULT_REVERB_CONTROL_SCALE)) psp_sf(fd, S_reverb_control_scale, sp->reverb_control_scale); if ((fneq(sp->reverb_control_scale_min, DEFAULT_REVERB_CONTROL_SCALE_MIN)) || (fneq(sp->reverb_control_scale_max, DEFAULT_REVERB_CONTROL_SCALE_MAX))) psp_sl(fd, S_reverb_control_scale_bounds, sp->reverb_control_scale_min, sp->reverb_control_scale_max); if (fneq(sp->reverb_control_length, DEFAULT_REVERB_CONTROL_LENGTH)) psp_sf(fd, S_reverb_control_length, sp->reverb_control_length); if ((fneq(sp->reverb_control_length_min, DEFAULT_REVERB_CONTROL_LENGTH_MIN)) || (fneq(sp->reverb_control_length_max, DEFAULT_REVERB_CONTROL_LENGTH_MAX))) psp_sl(fd, S_reverb_control_length_bounds, sp->reverb_control_length_min, sp->reverb_control_length_max); if (fneq(sp->reverb_control_feedback, DEFAULT_REVERB_CONTROL_FEEDBACK)) psp_sf(fd, S_reverb_control_feedback, sp->reverb_control_feedback); if (fneq(sp->reverb_control_lowpass, DEFAULT_REVERB_CONTROL_LOWPASS)) psp_sf(fd, S_reverb_control_lowpass, sp->reverb_control_lowpass); if (fneq(sp->reverb_control_decay, DEFAULT_REVERB_CONTROL_DECAY)) psp_sf(fd, S_reverb_control_decay, sp->reverb_control_decay); if (fneq(sp->amp_control, DEFAULT_AMP_CONTROL)) psp_sf(fd, S_amp_control, sp->amp_control); if ((fneq(sp->amp_control_min, DEFAULT_AMP_CONTROL_MIN)) || (fneq(sp->amp_control_max, DEFAULT_AMP_CONTROL_MAX))) psp_sl(fd, S_amp_control_bounds, sp->amp_control_min, sp->amp_control_max); if (sp->filter_control_on != DEFAULT_FILTER_CONTROL_ON) psp_ss(fd, S_filter_control_on, b2s(sp->filter_control_on)); if (sp->filter_control_order != DEFAULT_FILTER_CONTROL_ORDER) psp_sd(fd, S_filter_control_order, sp->filter_control_order); if (sp->filter_control_in_dB != DEFAULT_FILTER_CONTROL_IN_DB) psp_ss(fd, S_filter_control_in_dB, b2s(sp->filter_control_in_dB)); if (sp->filter_control_in_hz != DEFAULT_FILTER_CONTROL_IN_HZ) psp_ss(fd, S_filter_control_in_hz, b2s(sp->filter_control_in_hz)); if ((sp->filter_control_envelope) && (!(is_default_envelope(sp->filter_control_envelope)))) { char *tmpstr = NULL; psp_ss(fd, S_filter_control_envelope, tmpstr = env_to_string(sp->filter_control_envelope)); if (tmpstr) free(tmpstr); } if ((Xen_is_vector(sp->properties)) && (Xen_is_list(Xen_vector_ref(sp->properties, 0))) && (!(Xen_is_null(Xen_vector_ref(sp->properties, 0))))) { save_property_list(fd, Xen_vector_ref(sp->properties, 0), -1, -1); /* sound-properties */ } for (chan = 0; chan < sp->nchans; chan++) { axis_info *ap; cp = sp->chans[chan]; if ((!cp) || (!cp->edits) || (!cp->sounds)) break; ap = cp->axis; if (!(cp->graph_time_on)) pcp_ss(fd, S_time_graph_on, b2s(cp->graph_time_on), chan); if (cp->graph_transform_on) pcp_ss(fd, S_transform_graph_on, b2s(cp->graph_transform_on), chan); if (cp->graph_lisp_on) pcp_ss(fd, S_lisp_graph_on, b2s(cp->graph_lisp_on), chan); if (ap) { if (((ap->x0 != 0.0) || (ap->x1 != 0.1)) && (ap->x1 > .0005)) pcp_sl(fd, S_x_bounds, ap->x0, ap->x1, chan); if ((ap->y0 != -1.0) || (ap->y1 != 1.0)) pcp_sl(fd, S_y_bounds, ap->y0, ap->y1, chan); } if (cursor_sample(cp) != 0) pcp_sod(fd, S_cursor, cursor_sample(cp), chan); if (cp->cursor_size != DEFAULT_CURSOR_SIZE) pcp_sd(fd, S_cursor_size, cp->cursor_size, chan); if (cp->cursor_style != DEFAULT_CURSOR_STYLE) pcp_ss(fd, S_cursor_style, cursor_style_name(cp->cursor_style), chan); if (cp->tracking_cursor_style != DEFAULT_TRACKING_CURSOR_STYLE) pcp_ss(fd, S_tracking_cursor_style, cursor_style_name(cp->tracking_cursor_style), chan); if (cp->show_marks != show_marks(ss)) pcp_ss(fd, S_show_marks, b2s(cp->show_marks), chan); if (cp->show_y_zero != show_y_zero(ss)) pcp_ss(fd, S_show_y_zero, b2s(cp->show_y_zero), chan); if (cp->show_grid != show_grid(ss)) pcp_ss(fd, S_show_grid, b2s((bool)(cp->show_grid)), chan); if (cp->show_sonogram_cursor != show_sonogram_cursor(ss)) pcp_ss(fd, S_show_sonogram_cursor, b2s(cp->show_sonogram_cursor), chan); if (cp->wavo_hop != wavo_hop(ss)) pcp_sd(fd, S_wavo_hop, cp->wavo_hop, chan); if (cp->wavo_trace != wavo_trace(ss)) pcp_sd(fd, S_wavo_trace, cp->wavo_trace, chan); if (cp->max_transform_peaks != max_transform_peaks(ss)) pcp_sd(fd, S_max_transform_peaks, cp->max_transform_peaks, chan); if (cp->show_transform_peaks != show_transform_peaks(ss)) pcp_ss(fd, S_show_transform_peaks, b2s(cp->show_transform_peaks), chan); if (cp->fft_log_frequency != fft_log_frequency(ss)) pcp_ss(fd, S_fft_log_frequency, b2s(cp->fft_log_frequency), chan); if (cp->fft_log_magnitude != fft_log_magnitude(ss)) pcp_ss(fd, S_fft_log_magnitude, b2s(cp->fft_log_magnitude), chan); if (cp->fft_with_phases != fft_with_phases(ss)) pcp_ss(fd, S_fft_with_phases, b2s(cp->fft_with_phases), chan); if (cp->with_verbose_cursor != with_verbose_cursor(ss)) pcp_ss(fd, S_with_verbose_cursor, b2s(cp->with_verbose_cursor), chan); if (cp->zero_pad != zero_pad(ss)) pcp_sd(fd, S_zero_pad, cp->zero_pad, chan); if (cp->wavelet_type != wavelet_type(ss)) pcp_sd(fd, S_wavelet_type, cp->wavelet_type, chan); if (fneq(cp->min_dB, min_dB(ss))) pcp_sf(fd, S_min_dB, cp->min_dB, chan); if (fneq(cp->spectro_x_angle, spectro_x_angle(ss))) pcp_sf(fd, S_spectro_x_angle, cp->spectro_x_angle, chan); if (fneq(cp->spectro_y_angle, spectro_y_angle(ss))) pcp_sf(fd, S_spectro_y_angle, cp->spectro_y_angle, chan); if (fneq(cp->spectro_z_angle, spectro_z_angle(ss))) pcp_sf(fd, S_spectro_z_angle, cp->spectro_z_angle, chan); if (fneq(cp->spectro_x_scale, spectro_x_scale(ss))) pcp_sf(fd, S_spectro_x_scale, cp->spectro_x_scale, chan); if (fneq(cp->spectro_y_scale, spectro_y_scale(ss))) pcp_sf(fd, S_spectro_y_scale, cp->spectro_y_scale, chan); if (fneq(cp->spectro_z_scale, spectro_z_scale(ss))) pcp_sf(fd, S_spectro_z_scale, cp->spectro_z_scale, chan); if (fneq(cp->spectrum_end, spectrum_end(ss))) pcp_sf(fd, S_spectrum_end, cp->spectrum_end, chan); if (fneq(cp->spectrum_start, spectrum_start(ss))) pcp_sf(fd, S_spectrum_start, cp->spectrum_start, chan); if (fneq(cp->fft_window_alpha, fft_window_alpha(ss))) pcp_sf(fd, S_fft_window_alpha, cp->fft_window_alpha, chan); if (fneq(cp->fft_window_beta, fft_window_beta(ss))) pcp_sf(fd, S_fft_window_beta, cp->fft_window_beta, chan); if (cp->spectro_hop != spectro_hop(ss)) pcp_sd(fd, S_spectro_hop, cp->spectro_hop, chan); if (cp->transform_size != transform_size(ss)) pcp_sod(fd, S_transform_size, cp->transform_size, chan); if (cp->transform_graph_type != transform_graph_type(ss)) pcp_ss(fd, S_transform_graph_type, transform_graph_type_name(cp->transform_graph_type), chan); if (cp->time_graph_type != time_graph_type(ss)) pcp_ss(fd, S_time_graph_type, time_graph_type_name(cp->time_graph_type), chan); if (cp->fft_window != fft_window(ss)) pcp_ss(fd, S_fft_window, TO_VAR_NAME(mus_fft_window_xen_name(cp->fft_window)), chan); if (cp->transform_type != transform_type(ss)) pcp_ss(fd, S_transform_type, TO_VAR_NAME(transform_program_name(cp->transform_type)), chan); /* this is assuming the added transform definition (if any) can be found -- maybe not a good idea */ if (cp->transform_normalization != transform_normalization(ss)) pcp_ss(fd, S_transform_normalization, transform_normalization_name(cp->transform_normalization), chan); if (cp->time_graph_style != graph_style(ss)) pcp_ss(fd, S_time_graph_style, graph_style_name(cp->time_graph_style), chan); if (cp->lisp_graph_style != graph_style(ss)) pcp_ss(fd, S_lisp_graph_style, graph_style_name(cp->lisp_graph_style), chan); if (cp->transform_graph_style != graph_style(ss)) pcp_ss(fd, S_transform_graph_style, graph_style_name(cp->transform_graph_style), chan); if (cp->show_mix_waveforms != show_mix_waveforms(ss)) pcp_ss(fd, S_show_mix_waveforms, b2s(cp->show_mix_waveforms), chan); if (cp->dot_size != dot_size(ss)) pcp_sd(fd, S_dot_size, cp->dot_size, chan); if (fneq(cp->grid_density, grid_density(ss))) pcp_sf(fd, S_grid_density, cp->grid_density, chan); if (cp->x_axis_style != x_axis_style(ss)) pcp_ss(fd, S_x_axis_style, x_axis_style_name(cp->x_axis_style), chan); if (fneq(cp->beats_per_minute, beats_per_minute(ss))) pcp_sf(fd, S_beats_per_minute, cp->beats_per_minute, chan); if (cp->beats_per_measure != beats_per_measure(ss)) pcp_sd(fd, S_beats_per_measure, cp->beats_per_measure, chan); if (cp->show_axes != show_axes(ss)) pcp_ss(fd, S_show_axes, show_axes2string(cp->show_axes), chan); if (cp->graphs_horizontal != graphs_horizontal(ss)) pcp_ss(fd, S_graphs_horizontal, b2s(cp->graphs_horizontal), chan); if ((Xen_is_vector(cp->properties)) && (Xen_is_list(Xen_vector_ref(cp->properties, 0))) && (!(Xen_is_null(Xen_vector_ref(cp->properties, 0))))) { save_property_list(fd, Xen_vector_ref(cp->properties, 0), chan, -1); /* channel-properties */ } /* ap->default_xlabel if not null, user explicitly set it */ /* ylabel can only be a user choice -- never set by Snd */ if (cp->axis) { if (cp->axis->default_xlabel) pcp_sss(fd, S_x_axis_label, cp->axis->default_xlabel, chan, "time-graph"); if (cp->axis->ylabel) pcp_sss(fd, S_y_axis_label, cp->axis->ylabel, chan, "time-graph"); } if ((cp->fft) && (cp->fft->axis)) { if (cp->fft->axis->default_xlabel) pcp_sss(fd, S_x_axis_label, cp->fft->axis->default_xlabel, chan, "transform-graph"); if (cp->fft->axis->ylabel) pcp_sss(fd, S_y_axis_label, cp->fft->axis->ylabel, chan, "transform-graph"); } /* lisp_info is hidden in snd-chn.c */ edit_history_to_file(fd, cp, true); { int i; for (i = 0; i <= cp->edit_ctr; i++) { ed_list *ed; ed = cp->edits[i]; if ((Xen_is_vector(ed->properties)) && (Xen_is_list(Xen_vector_ref(ed->properties, 0))) && (!(Xen_is_null(Xen_vector_ref(ed->properties, 0))))) { save_property_list(fd, Xen_vector_ref(ed->properties, 0), chan, i); /* edit-properties */ } } } check_selection(fd, cp); if ((!sp->remembering) && (selected_channel() == cp)) { #if HAVE_SCHEME fprintf(fd, "%s(set! _saved_snd_selected_sound_ sfile)\n", white_space); fprintf(fd, "%s(set! _saved_snd_selected_channel_ %d)\n", white_space, cp->chan); #endif #if HAVE_RUBY fprintf(fd, "%ssaved_snd_selected_sound = sfile\n", white_space); fprintf(fd, "%ssaved_snd_selected_channel = %d\n", white_space, cp->chan); #endif #if HAVE_FORTH fprintf(fd, "%ssfile to saved_snd_selected_sound\n", white_space); fprintf(fd, "%s%d to saved_snd_selected_channel\n", white_space, cp->chan); #endif } } close_save_sound_block(fd, !b_ok); } static Xen after_save_state_hook; static Xen before_save_state_hook; void save_state(const char *save_state_name) { FILE *save_fd; char *fullname; bool append_new_state = false; if (!save_state_name) { snd_error("no save state file name?"); return; } fullname = mus_expand_filename(save_state_name); if (Xen_hook_has_list(before_save_state_hook)) { Xen res; res = run_or_hook(before_save_state_hook, Xen_list_1(C_string_to_Xen_string(fullname)), S_before_save_state_hook); append_new_state = Xen_boolean_to_C_bool(res); } if (append_new_state) save_fd = FOPEN(fullname, "a"); else save_fd = FOPEN(fullname, "w"); if (fullname) {free(fullname); fullname = NULL;} if (save_fd == NULL) { snd_error("can't write %s: %s", save_state_name, snd_io_strerror()); return; } save_options(save_fd); /* options = user-settable global state variables */ /* the global settings need to precede possible local settings */ if (ss->active_sounds > 0) { if (ss->selected_sound != NO_SELECTION) { #if HAVE_SCHEME fprintf(save_fd, "\n(define _saved_snd_selected_sound_ #f)\n"); fprintf(save_fd, "(define _saved_snd_selected_channel_ #f)\n"); #endif #if HAVE_RUBY fprintf(save_fd, "\nsaved_snd_selected_sound = -1\n"); fprintf(save_fd, "saved_snd_selected_channel = -1\n"); #endif #if HAVE_FORTH fprintf(save_fd, "\n#f value saved_snd_selected_sound\n"); fprintf(save_fd, "#f value saved_snd_selected_channel\n"); fprintf(save_fd, "#f value sfile\n"); #endif } for_each_sound_with_void(save_sound_state, (void *)save_fd); /* current sound state -- will traverse chans */ if (ss->selected_sound != NO_SELECTION) { #if HAVE_SCHEME fprintf(save_fd, "(if _saved_snd_selected_sound_\n"); fprintf(save_fd, " (begin\n"); fprintf(save_fd, " (%s _saved_snd_selected_sound_)\n", S_select_sound); fprintf(save_fd, " (%s _saved_snd_selected_channel_)))\n", S_select_channel); #endif #if HAVE_RUBY fprintf(save_fd, "if saved_snd_selected_sound != -1\n"); fprintf(save_fd, " select_sound(saved_snd_selected_sound)\n"); fprintf(save_fd, " select_channel(saved_snd_selected_channel)\n"); fprintf(save_fd, "end\n"); #endif #if HAVE_FORTH fprintf(save_fd, "saved_snd_selected_sound false? not [if]\n"); fprintf(save_fd, " saved_snd_selected_sound %s drop\n", S_select_sound); fprintf(save_fd, " saved_snd_selected_channel %s drop\n", S_select_channel); fprintf(save_fd, "[then]\n\n"); #endif } } fprintf(save_fd, "\n"); save_envelope_editor_state(save_fd); /* current envelope editor window state */ save_regions(save_fd); /* regions */ if (transform_dialog_is_active()) fprintf(save_fd, BPAREN "%s" EPAREN "\n", to_proc_name(S_transform_dialog)); if (enved_dialog_is_active()) fprintf(save_fd, BPAREN "%s" EPAREN "\n", to_proc_name(S_enved_dialog)); if (color_orientation_dialog_is_active()) fprintf(save_fd, BPAREN "%s" EPAREN "\n", to_proc_name(S_color_orientation_dialog)); if (region_dialog_is_active()) fprintf(save_fd, BPAREN "%s" EPAREN "\n", to_proc_name(S_view_regions_dialog)); save_post_it_dialog_state(save_fd); save_find_dialog_state(save_fd); save_edit_header_dialog_state(save_fd); #if USE_MOTIF save_print_dialog_state(save_fd); save_view_files_dialogs(save_fd); #endif save_file_dialog_state(save_fd); /* saving mix/track state is problematic. For example, if we make a selection, mix it, * then make another selection and mix it, we get an edit list: * * (change-samples-with-origin 266 451 "set! -mix-0 (mix-selection 266)" "/home/bil/zap/snd/snd_3309_9.snd" sfile 0 #f (list 1145009982 1848)) * (change-samples-with-origin 1655 480 "set! -mix-1 (mix-selection 1655)" "/home/bil/zap/snd/snd_3309_10.snd" sfile 0 #f (list 1145009982 1964)) * (set! (selection-member? sfile 0) #t) * (set! (selection-position sfile 0) 816) * (set! (selection-framples sfile 0) 480) * * which won't even work for the current selection case! If we mix some piece of a sound * being edited in another window, we'd need to keep all edits in sync during the restore! * But each mix has a temp file of its data, so perhaps an internal function to fake a mix * using it? * * :(edit-list->function) * # * * which is also wrong! This has to use the shadowing temp files. * so edit-list->function fails if selections involved (mix-selection) [or is this what is expected?] * * To keep the mix/track dialogs in sync with the newly restored mixes would require keeping the * old mix/track numbers and mapping to the new ones. */ /* the problem here (with saving hooks) is that it is not straightforward to save the function source * (with the current print-set! source option, or with an earlier procedure->string function using * funclet etc); many types print in this case in ways that are not readable. * The functions may depend on globals that are not in loaded files, or that were changed since * loading, and trying to map over the current module's obarray, saving each such variable in * its current form, is a major undertaking (although this can be done for simple vars); additionally, * what if the user has changed these before restoring -- should the old forms be restored? */ snd_fclose(save_fd, save_state_name); if (Xen_hook_has_list(after_save_state_hook)) run_hook(after_save_state_hook, Xen_list_1(C_string_to_Xen_string(save_state_name)), S_after_save_state_hook); } const char *save_options_in_prefs(void) { #if HAVE_EXTENSION_LANGUAGE FILE *fd; char *fullname; #if HAVE_RUBY #define SND_PREFS "~/.snd_prefs_ruby" #endif #if HAVE_FORTH #define SND_PREFS "~/.snd_prefs_forth" #endif #if HAVE_SCHEME #define SND_PREFS "~/.snd_prefs_s7" #endif fullname = mus_expand_filename(SND_PREFS); fd = FOPEN(fullname, "w"); if (!fd) { snd_error("can't write %s: %s", SND_PREFS, snd_io_strerror()); return(NULL); } save_options(fd); snd_fclose(fd, SND_PREFS); free(fullname); return(SND_PREFS); #else return(NULL); #endif } #if 0 static char *file_extension(char *arg) { char *dot = NULL, *sp; if (arg) for (sp = arg; (*sp) != '\0'; sp++) if ((*sp) == '.') dot = (++sp); return(dot); } #endif #if (!DISABLE_DEPRECATED) static Xen start_hook; static bool dont_start(char *filename) { Xen res = Xen_false; if (Xen_hook_has_list(start_hook)) res = run_or_hook(start_hook, Xen_list_1(C_string_to_Xen_string(filename)), S_start_hook); return(Xen_is_true(res)); } #endif static char *startup_filename = NULL; static int script_arg = 0, script_argn = 0; static char **script_args; static Xen g_script_arg(void) { #define H_script_arg "(" S_script_arg "): where we are in the startup arg list" return(C_int_to_Xen_integer(script_arg)); } static Xen g_set_script_arg(Xen arg) { script_arg = Xen_integer_to_C_int(arg); return(arg); } static Xen g_script_args(void) { #define H_script_args "(" S_script_args "): the args passed to Snd at startup as a list of strings" Xen lst = Xen_empty_list; int i; for (i = script_argn - 1; i >= 0; i--) lst = Xen_cons(C_string_to_Xen_string(script_args[i]), lst); return(lst); } static void printout_to_stdout(const char *msg, void *ignore) { puts(msg); } int handle_next_startup_arg(int auto_open_ctr, char **auto_open_file_names, bool with_title, int args) { char *argname; argname = auto_open_file_names[auto_open_ctr]; if (argname) { /* wanted to use "-d" and "-i" but they're in use */ if ((mus_strcmp("-h", argname)) || (mus_strcmp("-horizontal", argname)) || (mus_strcmp("--horizontal", argname)) || (mus_strcmp("-v", argname)) || (mus_strcmp("-vertical", argname)) || (mus_strcmp("--vertical", argname)) || (mus_strcmp("-notebook", argname)) || (mus_strcmp("--notebook", argname)) || (mus_strcmp("-separate", argname)) || (mus_strcmp("--separate", argname)) || (mus_strcmp("-nostdin", argname)) || (mus_strcmp("-noglob", argname)) || (mus_strcmp("-noinit", argname)) || (mus_strcmp("--noinit", argname))) return(auto_open_ctr + 1); else { if (mus_strcmp("-init", argname)) return(auto_open_ctr + 2); else { #if (!USE_NO_GUI) if ((mus_strcmp("-p", argname)) || (mus_strcmp("-preload", argname)) || (mus_strcmp("--preload", argname))) { /* preload sound files in dir (can be ., should be unquoted) */ auto_open_ctr++; if ((auto_open_ctr >= args) || (auto_open_file_names[auto_open_ctr] == NULL)) snd_error("%s but no directory to add?", argname); else view_files_add_directory(NULL_WIDGET, auto_open_file_names[auto_open_ctr]); } else #endif { if ((mus_strcmp("-l", argname)) || (mus_strcmp("-load", argname)) || (mus_strcmp("--load", argname)) || (mus_strcmp("-b", argname)) || (mus_strcmp("-batch", argname)) || (mus_strcmp("--batch", argname)) || (is_source_file(argname))) { if ((mus_strcmp("-l", argname)) || (mus_strcmp("-load", argname)) || (mus_strcmp("--load", argname)) || (mus_strcmp("-b", argname)) || (mus_strcmp("-batch", argname)) || (mus_strcmp("--batch", argname))) auto_open_ctr++; if ((auto_open_ctr >= args) || (auto_open_file_names[auto_open_ctr] == NULL)) snd_error("%s but no file to load?", argname); else { script_arg = auto_open_ctr; script_argn = args; script_args = auto_open_file_names; redirect_everything_to(printout_to_stdout, NULL); snd_load_file(auto_open_file_names[auto_open_ctr]); redirect_everything_to(NULL, NULL); if (script_arg > auto_open_ctr) auto_open_ctr = script_arg; } } else { if ((mus_strcmp("-e", argname)) || (mus_strcmp("-eval", argname)) || (mus_strcmp("--eval", argname))) { /* evaluate expression */ auto_open_ctr++; if ((auto_open_ctr >= args) || (auto_open_file_names[auto_open_ctr] == NULL)) snd_error("%s but no form to evaluate?", argname); else { char *buf; buf = auto_open_file_names[auto_open_ctr]; redirect_everything_to(printout_to_stdout, NULL); snd_report_result(snd_catch_any(eval_str_wrapper, (void *)buf, buf), buf); redirect_everything_to(NULL, NULL); } } else { if ((with_title) && (mus_strcmp("-title", argname))) { auto_open_ctr++; if ((auto_open_ctr >= args) || (auto_open_file_names[auto_open_ctr] == NULL)) snd_error_without_format("-title but no title?"); /* for gtk -- Xt handles the Motif case */ else ss->startup_title = mus_strdup(auto_open_file_names[auto_open_ctr]); } else { if (mus_strcmp("-I", argname)) { /* added 24-Oct-02: add to load path in either extension language */ auto_open_ctr++; if ((auto_open_ctr >= args) || (auto_open_file_names[auto_open_ctr] == NULL)) snd_error_without_format("-I but no path?"); else { Xen_add_to_load_path(auto_open_file_names[auto_open_ctr]); } } else { if (startup_filename == NULL) { startup_filename = mus_strdup(argname); #if (!DISABLE_DEPRECATED) if (dont_start(startup_filename)) snd_exit(1); #endif } ss->open_requestor = FROM_STARTUP; if (snd_open_file(argname, FILE_READ_WRITE) == NULL) { /* non-existent file at startup */ if (argname[0] == '-') { /* probably a bad option */ fprintf(stdout, "bad option: %s\n", argname); } else { fprintf(stdout, "can't open %s\n", argname); if (ss->startup_errors) ss->startup_errors = mus_format("%s\n%s ;%s\"%s\"\n", ss->startup_errors, listener_prompt(ss), "can't open ", argname); else ss->startup_errors = mus_format(";%s\"%s\"\n", "can't open ", argname); } } } } } } } } } } return(auto_open_ctr + 1); } static void save_state_error_handler(const char *msg, void *data) { char *filename = (char *)data; Xen fname; if (filename) { fname = C_string_to_Xen_string(filename); free(filename); /* this is "name" below */ } else fname = C_string_to_Xen_string(save_state_file(ss)); redirect_snd_error_to(NULL, NULL); Xen_error(CANNOT_SAVE, Xen_list_2(C_string_to_Xen_string(S_save_state ": can't save ~S"), fname)); } static Xen g_save_state(Xen filename) { char *name = NULL; Xen res; #define H_save_state "(" S_save_state " :optional filename): save the current Snd state in filename; (load filename) restores it. The \ default " S_save_state " filename is " DEFAULT_SAVE_STATE_FILE ". It can be changed via " S_save_state_file "." Xen_check_type(Xen_is_string_or_unbound(filename), filename, 1, S_save_state, "a string"); if (Xen_is_bound(filename)) name = mus_strdup(Xen_string_to_C_string(filename)); else name = mus_strdup(save_state_file(ss)); redirect_snd_error_to(save_state_error_handler, (void *)name); save_state(name); redirect_snd_error_to(NULL, NULL); res = C_string_to_Xen_string(name); free(name); return(res); } static Xen g_exit(Xen val) { #define H_exit "(" S_exit " :optional val): exit Snd" if (snd_exit_cleanly(EXIT_NOT_FORCED)) snd_exit((Xen_is_integer(val)) ? Xen_integer_to_C_int(val) : 1); return(Xen_false); } static int snd_access(const char *dir, const char *caller) { int err; char *temp; temp = shorter_tempnam(dir, "snd_"); err = mus_file_create(temp); if (err == -1) { Xen res; free(temp); temp = mus_format("%s: directory %s is not writable: %s", caller, dir, snd_open_strerror()); res = C_string_to_Xen_string(temp); free(temp); Xen_error(NO_SUCH_FILE, Xen_list_1(res)); return(0); } else snd_close(err, temp); snd_remove(temp, IGNORE_CACHE); free(temp); return(1); } static Xen g_temp_dir(void) {return(C_string_to_Xen_string(temp_dir(ss)));} static Xen g_set_temp_dir(Xen val) { #define H_temp_dir "(" S_temp_dir "): name of directory for temp files (or " PROC_FALSE "=null)" const char *dir = MUS_DEFAULT_TEMP_DIR; Xen_check_type(Xen_is_string(val) || Xen_is_false(val), val, 1, S_set S_temp_dir, "a string or " PROC_FALSE "=default (null)"); if (Xen_is_string(val)) dir = Xen_string_to_C_string(val); if (snd_access(dir, S_temp_dir)) { if (temp_dir(ss)) free(temp_dir(ss)); set_temp_dir(mus_strdup(dir)); } return(C_string_to_Xen_string(temp_dir(ss))); } static Xen g_peak_env_dir(void) {return(C_string_to_Xen_string(peak_env_dir(ss)));} static Xen g_set_peak_env_dir(Xen val) { #define H_peak_env_dir "(" S_peak_env_dir "): name of directory for peak env files (or " PROC_FALSE "=null)" Xen_check_type(Xen_is_string(val) || Xen_is_false(val), val, 1, S_set S_peak_env_dir, "a string or " PROC_FALSE "=default (null)"); if (Xen_is_string(val)) { const char *dir = NULL; dir = Xen_string_to_C_string(val); if (snd_access(dir, S_peak_env_dir)) { if (peak_env_dir(ss)) free(peak_env_dir(ss)); set_peak_env_dir(mus_strdup(dir)); } } else { if (peak_env_dir(ss)) free(peak_env_dir(ss)); set_peak_env_dir(NULL); } return(C_string_to_Xen_string(peak_env_dir(ss))); } static Xen g_ladspa_dir(void) {return(C_string_to_Xen_string(ladspa_dir(ss)));} static Xen g_set_ladspa_dir(Xen val) { #define H_ladspa_dir "(" S_ladspa_dir "): name of directory for ladspa plugin libraries" Xen_check_type(Xen_is_string(val) || Xen_is_false(val), val, 1, S_set S_ladspa_dir, "a string or " PROC_FALSE "=default (null)"); if (ladspa_dir(ss)) free(ladspa_dir(ss)); if (Xen_is_false(val)) set_ladspa_dir(mus_strdup(DEFAULT_LADSPA_DIR)); else set_ladspa_dir(mus_strdup(Xen_string_to_C_string(val))); return(C_string_to_Xen_string(ladspa_dir(ss))); } static Xen g_save_state_file(void) {return(C_string_to_Xen_string(save_state_file(ss)));} static Xen g_set_save_state_file(Xen val) { const char *filename; #define H_save_state_file "(" S_save_state_file "): the name of the saved state file (\"saved-snd." Xen_file_extension "\")" Xen_check_type(Xen_is_string(val), val, 1, S_set S_save_state_file, "a string"); filename = Xen_string_to_C_string(val); if (save_state_file(ss)) free(save_state_file(ss)); in_set_save_state_file(mus_strdup(filename)); return(C_string_to_Xen_string(save_state_file(ss))); } static Xen g_save_dir(void) {return(C_string_to_Xen_string(save_dir(ss)));} static Xen g_set_save_dir(Xen val) { #define H_save_dir "(" S_save_dir "): name of directory for saved state data (or " PROC_FALSE "=null)" const char *dir = MUS_DEFAULT_SAVE_DIR; Xen_check_type(Xen_is_string(val) || Xen_is_false(val), val, 1, S_set S_save_dir, "a string or " PROC_FALSE "=default (null)"); if (Xen_is_string(val)) dir = Xen_string_to_C_string(val); if (snd_access(dir, S_save_dir)) { if (save_dir(ss)) free(save_dir(ss)); set_save_dir(mus_strdup(dir)); } return(C_string_to_Xen_string(save_dir(ss))); } static Xen g_open_file_dialog_directory(void) {return(C_string_to_Xen_string(open_file_dialog_directory(ss)));} static Xen g_set_open_file_dialog_directory(Xen val) { #define H_open_file_dialog_directory "(" S_open_file_dialog_directory "): name of directory for initial open file dialog search" const char *dir; Xen_check_type(Xen_is_string(val), val, 1, S_set S_open_file_dialog_directory, "a string"); dir = Xen_string_to_C_string(val); if (snd_access(dir, S_open_file_dialog_directory)) { if (open_file_dialog_directory(ss)) free(open_file_dialog_directory(ss)); set_open_file_dialog_directory(mus_strdup(dir)); } return(C_string_to_Xen_string(open_file_dialog_directory(ss))); } static int snd_screen_height(void) { #if USE_MOTIF return(HeightOfScreen(ScreenOfDisplay(MAIN_DISPLAY(ss), 0))); #else #if USE_GTK return(gdk_screen_height()); #else return(4000); #endif #endif } static int snd_screen_width(void) { #if USE_MOTIF return(WidthOfScreen(ScreenOfDisplay(MAIN_DISPLAY(ss), 0))); #else #if USE_GTK return(gdk_screen_width()); #else return(4000); #endif #endif } static Xen g_window_height(void) { #define H_window_height "(" S_window_height "): current Snd window height in pixels" return(C_int_to_Xen_integer(widget_height(MAIN_SHELL(ss)))); } static Xen g_set_window_height(Xen height) { int val; Xen_check_type(Xen_is_integer(height), height, 1, S_set S_window_height, "an integer"); val = Xen_integer_to_C_int(height); if ((val > 0) && (val < snd_screen_height())) { #if (!USE_NO_GUI) set_widget_height(MAIN_SHELL(ss), val); #endif ss->init_window_height = val; } return(height); } static Xen g_window_width(void) { #define H_window_width "(" S_window_width "): current Snd window width in pixels" return(C_int_to_Xen_integer(widget_width(MAIN_SHELL(ss)))); } static Xen g_set_window_width(Xen width) { int val; Xen_check_type(Xen_is_integer(width), width, 1, S_set S_window_width, "an integer"); val = Xen_integer_to_C_int(width); if ((val > 0) && (val < snd_screen_width())) { #if (!USE_NO_GUI) set_widget_width(MAIN_SHELL(ss), val); #endif ss->init_window_width = val; } return(width); } static Xen g_window_x(void) { #define H_window_x "(" S_window_x "): current Snd window x position in pixels" return(C_int_to_Xen_integer(widget_x(MAIN_SHELL(ss)))); } static Xen g_set_window_x(Xen val) { int x; Xen_check_type(Xen_is_integer(val), val, 1, S_set S_window_x, "an integer"); x = Xen_integer_to_C_int(val); if ((x >= 0) && (x < snd_screen_width())) { set_widget_x(MAIN_SHELL(ss), x); ss->init_window_x = x; } return(val); } static Xen g_window_y(void) { #define H_window_y "(" S_window_y "): current Snd window y position in pixels" return(C_int_to_Xen_integer(widget_y(MAIN_SHELL(ss)))); } static Xen g_set_window_y(Xen val) { int y; Xen_check_type(Xen_is_integer(val), val, 1, S_set S_window_y, "an integer"); y = Xen_integer_to_C_int(val); if ((y >= 0) && (y < snd_screen_height())) { set_widget_y(MAIN_SHELL(ss), y); ss->init_window_y = y; } return(val); } static Xen g_just_sounds(void) { #define H_just_sounds "(" S_just_sounds "): the 'just sounds' choice in the file chooser dialog" return(C_bool_to_Xen_boolean(just_sounds(ss))); } static Xen g_set_just_sounds(Xen on) { Xen_check_type(Xen_is_boolean(on), on, 1, S_set S_just_sounds, "a boolean"); set_just_sounds(Xen_boolean_to_C_bool(on)); reflect_just_sounds(); return(C_bool_to_Xen_boolean(just_sounds(ss))); } static Xen g_play_arrow_size(void) { #define H_play_arrow_size "(" S_play_arrow_size "): the size of the play triangles" return(C_int_to_Xen_integer(play_arrow_size(ss))); } static Xen g_set_play_arrow_size(Xen size) { int arrow_size; Xen_check_type(Xen_is_integer(size), size, 1, S_set S_play_arrow_size, "an integer"); arrow_size = Xen_integer_to_C_int(size); if (arrow_size >= 0) set_play_arrow_size(arrow_size); else Xen_out_of_range_error(S_set S_play_arrow_size, 1, size, "must be >= 0"); for_each_chan(update_graph); return(size); } static Xen g_with_inset_graph(void) { #define H_with_inset_graph "(" S_with_inset_graph "): if " PROC_TRUE " (default is " PROC_FALSE "), display the inset graph in the time domain section." return(C_bool_to_Xen_boolean(with_inset_graph(ss))); } static Xen g_set_with_inset_graph(Xen on) { Xen_check_type(Xen_is_boolean(on), on, 1, S_set S_with_inset_graph, "a boolean"); set_with_inset_graph(Xen_boolean_to_C_bool(on)); for_each_chan(update_graph); return(C_bool_to_Xen_boolean(with_inset_graph(ss))); } static Xen g_with_interrupts(void) { #define H_with_interrupts "(" S_with_interrupts "): if " PROC_TRUE ", check for GUI events during computations." return(C_bool_to_Xen_boolean(with_interrupts(ss))); } static Xen g_set_with_interrupts(Xen on) { Xen_check_type(Xen_is_boolean(on), on, 1, S_set S_with_interrupts, "a boolean"); set_with_interrupts(Xen_boolean_to_C_bool(on)); return(C_bool_to_Xen_boolean(with_interrupts(ss))); } static Xen g_with_smpte_label(void) { #define H_with_smpte_label "(" S_with_smpte_label "): if " PROC_TRUE " (default is " PROC_FALSE "), display the SMPTE data in the time domain section." return(C_bool_to_Xen_boolean(with_smpte_label(ss))); } static Xen g_set_with_smpte_label(Xen on) { Xen_check_type(Xen_is_boolean(on), on, 1, S_set S_with_smpte_label, "a boolean"); set_with_smpte_label(Xen_boolean_to_C_bool(on)); for_each_chan(update_graph); return(C_bool_to_Xen_boolean(with_smpte_label(ss))); } static Xen g_with_pointer_focus(void) { #define H_with_pointer_focus "(" S_with_pointer_focus "): if " PROC_TRUE " (default is " PROC_FALSE "), activate the text or graph widget beneath the mouse." return(C_bool_to_Xen_boolean(with_pointer_focus(ss))); } static Xen g_set_with_pointer_focus(Xen on) { Xen_check_type(Xen_is_boolean(on), on, 1, S_set S_with_pointer_focus, "a boolean"); set_with_pointer_focus(Xen_boolean_to_C_bool(on)); return(C_bool_to_Xen_boolean(with_pointer_focus(ss))); } static Xen g_tiny_font(void) {return(C_string_to_Xen_string(tiny_font(ss)));} static Xen g_set_tiny_font(Xen val) { #define H_tiny_font "(" S_tiny_font "): font use for some info in the graphs" Xen_check_type(Xen_is_string(val), val, 1, S_set S_tiny_font, "a string"); set_tiny_font(Xen_string_to_C_string(val)); return(C_string_to_Xen_string(tiny_font(ss))); } static Xen g_axis_label_font(void) {return(C_string_to_Xen_string(axis_label_font(ss)));} static Xen g_set_axis_label_font(Xen val) { #define H_axis_label_font "(" S_axis_label_font "): font used for axis labels" Xen_check_type(Xen_is_string(val), val, 1, S_set S_axis_label_font, "a string"); set_axis_label_font(Xen_string_to_C_string(val)); return(C_string_to_Xen_string(axis_label_font(ss))); } static Xen g_axis_numbers_font(void) {return(C_string_to_Xen_string(axis_numbers_font(ss)));} static Xen g_set_axis_numbers_font(Xen val) { #define H_axis_numbers_font "(" S_axis_numbers_font "): font used for axis numbers" Xen_check_type(Xen_is_string(val), val, 1, S_set S_axis_numbers_font, "a string"); set_axis_numbers_font(Xen_string_to_C_string(val)); return(C_string_to_Xen_string(axis_numbers_font(ss))); } static Xen g_listener_font(void) {return(C_string_to_Xen_string(listener_font(ss)));} static Xen g_set_listener_font(Xen val) { #define H_listener_font "(" S_listener_font "): font used by the lisp listener" Xen_check_type(Xen_is_string(val), val, 1, S_set S_listener_font, "a string"); set_listener_font(Xen_string_to_C_string(val)); return(C_string_to_Xen_string(listener_font(ss))); } static Xen g_bold_peaks_font(void) {return(C_string_to_Xen_string(bold_peaks_font(ss)));} static Xen g_set_bold_peaks_font(Xen val) { #define H_bold_peaks_font "(" S_bold_peaks_font "): bold font used by fft peak display" Xen_check_type(Xen_is_string(val), val, 1, S_set S_bold_peaks_font, "a string"); set_bold_peaks_font(Xen_string_to_C_string(val)); return(C_string_to_Xen_string(bold_peaks_font(ss))); } static Xen g_peaks_font(void) {return(C_string_to_Xen_string(peaks_font(ss)));} static Xen g_set_peaks_font(Xen val) { #define H_peaks_font "(" S_peaks_font "): normal font used by fft peak display" Xen_check_type(Xen_is_string(val), val, 1, S_set S_peaks_font, "a string"); set_peaks_font(Xen_string_to_C_string(val)); return(C_string_to_Xen_string(peaks_font(ss))); } static Xen g_auto_resize(void) {return(C_bool_to_Xen_boolean(auto_resize(ss)));} static Xen g_set_auto_resize(Xen val) { #define H_auto_resize "(" S_auto_resize "): " PROC_TRUE " if Snd can change its main window size as it pleases (default: " PROC_TRUE ")" Xen_check_type(Xen_is_boolean(val), val, 1, S_set S_auto_resize, "a boolean"); set_auto_resize(Xen_boolean_to_C_bool(val)); #if USE_MOTIF XtVaSetValues(MAIN_SHELL(ss), XmNallowShellResize, auto_resize(ss), NULL); #endif return(C_bool_to_Xen_boolean(auto_resize(ss))); } static Xen g_color_cutoff(void) {return(C_double_to_Xen_real(color_cutoff(ss)));} static Xen g_set_color_cutoff(Xen val) { #define H_color_cutoff "(" S_color_cutoff "): color map cutoff point (default .003). Any values \ below the cutoff are displayed in the background color" Xen_check_type(Xen_is_number(val), val, 1, S_set S_color_cutoff, "a number"); set_color_cutoff(mus_fclamp(0.0, Xen_real_to_C_double(val), #if USE_MOTIF 0.25 #else 1.0 #endif )); return(C_double_to_Xen_real(color_cutoff(ss))); } static Xen g_color_inverted(void) {return(C_bool_to_Xen_boolean(color_inverted(ss)));} static Xen g_set_color_inverted(Xen val) { #define H_color_inverted "(" S_color_inverted "): whether the colormap in operation should be inverted" Xen_check_type(Xen_is_boolean(val), val, 1, S_set S_color_inverted, "a boolean"); set_color_inverted(Xen_boolean_to_C_bool(val)); return(C_bool_to_Xen_boolean(color_inverted(ss))); } static Xen g_color_scale(void) {return(C_double_to_Xen_real(color_scale(ss)));} static Xen g_set_color_scale(Xen val) { #define H_color_scale "(" S_color_scale "): darkness setting for colormaps (0.5)" Xen_check_type(Xen_is_number(val), val, 1, S_set S_color_scale, "a number"); set_color_scale(mus_fclamp(0.0, Xen_real_to_C_double(val), 1000.0)); return(C_double_to_Xen_real(color_scale(ss))); } static Xen g_selection_creates_region(void) {return(C_bool_to_Xen_boolean(selection_creates_region(ss)));} static Xen g_set_selection_creates_region(Xen val) { #define H_selection_creates_region "(" S_selection_creates_region "): " PROC_TRUE " if a region should be created each time a selection is made. \ The default is currently " PROC_TRUE ", but that may change. If you're dealing with large selections, and have no need of \ regions (saved selections), you can speed up many operations by setting this flag to " PROC_FALSE Xen_check_type(Xen_is_boolean(val), val, 1, S_set S_selection_creates_region, "a boolean"); set_selection_creates_region(Xen_boolean_to_C_bool(val)); return(C_bool_to_Xen_boolean(selection_creates_region(ss))); } static void set_print_lengths(int len) { set_print_length(len); mus_vct_set_print_length(len); #if HAVE_SCHEME s7_set_print_length(s7, len); #endif } static Xen g_print_length(void) {return(C_int_to_Xen_integer(print_length(ss)));} static Xen g_set_print_length(Xen val) { int len; #define H_print_length "(" S_print_length "): number of vector elements to print in the listener (default: 12)" Xen_check_type(Xen_is_integer(val), val, 1, S_set S_print_length, "an integer"); len = Xen_integer_to_C_int(val); if (len < 0) Xen_out_of_range_error(S_set S_print_length, 1, val, "must be >= 0"); set_print_lengths(len); return(C_int_to_Xen_integer(print_length(ss))); } static Xen g_show_indices(void) {return(C_bool_to_Xen_boolean(show_indices(ss)));} static Xen g_set_show_indices(Xen val) { #define H_show_indices "(" S_show_indices "): " PROC_TRUE " if sound name should be preceded by its index in the sound display." Xen_check_type(Xen_is_boolean(val), val, 1, S_set S_show_indices, "a boolean"); set_show_indices(Xen_boolean_to_C_bool(val)); for_each_sound(update_sound_label); return(C_bool_to_Xen_boolean(show_indices(ss))); } static Xen g_with_relative_panes(void) {return(C_bool_to_Xen_boolean(with_relative_panes(ss)));} static Xen g_set_with_relative_panes(Xen val) { #define H_with_relative_panes "(" S_with_relative_panes "): " PROC_TRUE " if multichannel sounds should try to maintain relative pane sizes" Xen_check_type(Xen_is_boolean(val), val, 1, S_set S_with_relative_panes, "a boolean"); set_with_relative_panes(Xen_boolean_to_C_bool(val)); return(C_bool_to_Xen_boolean(with_relative_panes(ss))); } static Xen g_with_background_processes(void) {return(C_bool_to_Xen_boolean(with_background_processes(ss)));} static Xen g_set_with_background_processes(Xen val) { #define H_with_background_processes "(" S_with_background_processes "): " PROC_TRUE " if Snd should use background (idle time) processing" Xen_check_type(Xen_is_boolean(val), val, 1, S_set S_with_background_processes, "a boolean"); set_with_background_processes(Xen_boolean_to_C_bool(val)); return(C_bool_to_Xen_boolean(with_background_processes(ss))); } static Xen g_with_file_monitor(void) {return(C_bool_to_Xen_boolean(with_file_monitor(ss)));} static Xen g_set_with_file_monitor(Xen val) { #define H_with_file_monitor "(" S_with_file_monitor "): " PROC_TRUE " if the file alteration monitor is active" Xen_check_type(Xen_is_boolean(val), val, 1, S_set S_with_file_monitor, "a boolean"); set_with_file_monitor(Xen_boolean_to_C_bool(val)); return(C_bool_to_Xen_boolean(with_file_monitor(ss))); } static Xen g_snd_version(void) { #define H_snd_version "(" S_snd_version "): current Snd version (a string)" return(C_string_to_Xen_string("Snd " SND_VERSION ", " SND_DATE)); /* make it look like s7-version's output */ } static Xen g_color_orientation_dialog(Xen managed) { #define H_color_orientation_dialog "(" S_color_orientation_dialog " :optional managed): start the Color/Orientation dialog" Xen_check_type(Xen_is_boolean_or_unbound(managed), managed, 1, S_color_orientation_dialog, "a boolean"); return(Xen_wrap_widget(make_color_orientation_dialog(Xen_boolean_to_C_bool(managed)))); } static Xen g_transform_dialog(Xen managed) { #define H_transform_dialog "(" S_transform_dialog " :optional (managed " PROC_TRUE ")): start the Transforms dialog" Xen_check_type(Xen_is_boolean_or_unbound(managed), managed, 1, S_transform_dialog, "a boolean"); return(Xen_wrap_widget(make_transform_dialog(Xen_boolean_to_C_bool(managed)))); } static Xen g_print_dialog(Xen managed, Xen direct_to_printer) { #define H_print_dialog "(" S_print_dialog " :optional managed direct): start the File Print dialog" Xen_check_type(Xen_is_boolean_or_unbound(managed), managed, 1, S_print_dialog, "a boolean"); Xen_check_type(Xen_is_boolean_or_unbound(direct_to_printer), direct_to_printer, 2, S_print_dialog, "a boolean"); return(Xen_wrap_widget(make_file_print_dialog(!(Xen_is_false(managed)), Xen_is_true(direct_to_printer)))); } static Xen g_preferences_dialog(void) { #define H_preferences_dialog "(" S_preferences_dialog "): start the Options:Preferences dialog" return(Xen_wrap_widget(make_preferences_dialog())); } static Xen g_abort(void) { #define H_abort "(" S_abort "): exit Snd via \"abort\", presumably to land in the debugger" abort(); return(Xen_false); } #if (!HAVE_SCHEME) static Xen g_abortq(void) { #define H_abortQ "(" S_c_g "): allow pending user interface events to occur, returning " PROC_TRUE " if C-g was typed" check_for_event(); if ((ss->C_g_typed) || (ss->stopped_explicitly)) { ss->stopped_explicitly = false; ss->C_g_typed = false; return(Xen_true); } return(Xen_false); } #endif Xen_wrap_no_args(g_save_state_file_w, g_save_state_file) Xen_wrap_1_arg(g_set_save_state_file_w, g_set_save_state_file) Xen_wrap_no_args(g_save_dir_w, g_save_dir) Xen_wrap_1_arg(g_set_save_dir_w, g_set_save_dir) Xen_wrap_no_args(g_open_file_dialog_directory_w, g_open_file_dialog_directory) Xen_wrap_1_arg(g_set_open_file_dialog_directory_w, g_set_open_file_dialog_directory) Xen_wrap_no_args(g_peak_env_dir_w, g_peak_env_dir) Xen_wrap_1_arg(g_set_peak_env_dir_w, g_set_peak_env_dir) Xen_wrap_no_args(g_temp_dir_w, g_temp_dir) Xen_wrap_1_arg(g_set_temp_dir_w, g_set_temp_dir) Xen_wrap_no_args(g_ladspa_dir_w, g_ladspa_dir) Xen_wrap_1_arg(g_set_ladspa_dir_w, g_set_ladspa_dir) Xen_wrap_1_optional_arg(g_save_state_w, g_save_state) Xen_wrap_1_optional_arg(g_exit_w, g_exit) Xen_wrap_no_args(g_script_arg_w, g_script_arg) Xen_wrap_1_arg(g_set_script_arg_w, g_set_script_arg) Xen_wrap_no_args(g_script_args_w, g_script_args) Xen_wrap_no_args(g_window_x_w, g_window_x) Xen_wrap_1_arg(g_set_window_x_w, g_set_window_x) Xen_wrap_no_args(g_window_y_w, g_window_y) Xen_wrap_1_arg(g_set_window_y_w, g_set_window_y) Xen_wrap_no_args(g_window_width_w, g_window_width) Xen_wrap_1_arg(g_set_window_width_w, g_set_window_width) Xen_wrap_no_args(g_window_height_w, g_window_height) Xen_wrap_1_arg(g_set_window_height_w, g_set_window_height) Xen_wrap_no_args(g_just_sounds_w, g_just_sounds) Xen_wrap_1_arg(g_set_just_sounds_w, g_set_just_sounds) Xen_wrap_no_args(g_play_arrow_size_w, g_play_arrow_size) Xen_wrap_1_arg(g_set_play_arrow_size_w, g_set_play_arrow_size) Xen_wrap_no_args(g_with_inset_graph_w, g_with_inset_graph) Xen_wrap_1_arg(g_set_with_inset_graph_w, g_set_with_inset_graph) Xen_wrap_no_args(g_with_interrupts_w, g_with_interrupts) Xen_wrap_1_arg(g_set_with_interrupts_w, g_set_with_interrupts) Xen_wrap_no_args(g_with_smpte_label_w, g_with_smpte_label) Xen_wrap_1_arg(g_set_with_smpte_label_w, g_set_with_smpte_label) Xen_wrap_no_args(g_with_pointer_focus_w, g_with_pointer_focus) Xen_wrap_1_arg(g_set_with_pointer_focus_w, g_set_with_pointer_focus) Xen_wrap_no_args(g_auto_resize_w, g_auto_resize) Xen_wrap_1_arg(g_set_auto_resize_w, g_set_auto_resize) Xen_wrap_no_args(g_color_cutoff_w, g_color_cutoff) Xen_wrap_1_arg(g_set_color_cutoff_w, g_set_color_cutoff) Xen_wrap_no_args(g_color_inverted_w, g_color_inverted) Xen_wrap_1_arg(g_set_color_inverted_w, g_set_color_inverted) Xen_wrap_no_args(g_color_scale_w, g_color_scale) Xen_wrap_1_arg(g_set_color_scale_w, g_set_color_scale) Xen_wrap_no_args(g_selection_creates_region_w, g_selection_creates_region) Xen_wrap_1_arg(g_set_selection_creates_region_w, g_set_selection_creates_region) Xen_wrap_no_args(g_print_length_w, g_print_length) Xen_wrap_1_arg(g_set_print_length_w, g_set_print_length) Xen_wrap_no_args(g_show_indices_w, g_show_indices) Xen_wrap_1_arg(g_set_show_indices_w, g_set_show_indices) Xen_wrap_no_args(g_with_relative_panes_w, g_with_relative_panes) Xen_wrap_1_arg(g_set_with_relative_panes_w, g_set_with_relative_panes) Xen_wrap_no_args(g_with_background_processes_w, g_with_background_processes) Xen_wrap_1_arg(g_set_with_background_processes_w, g_set_with_background_processes) Xen_wrap_no_args(g_with_file_monitor_w, g_with_file_monitor) Xen_wrap_1_arg(g_set_with_file_monitor_w, g_set_with_file_monitor) Xen_wrap_no_args(g_tiny_font_w, g_tiny_font) Xen_wrap_1_arg(g_set_tiny_font_w, g_set_tiny_font) Xen_wrap_no_args(g_peaks_font_w, g_peaks_font) Xen_wrap_1_arg(g_set_peaks_font_w, g_set_peaks_font) Xen_wrap_no_args(g_bold_peaks_font_w, g_bold_peaks_font) Xen_wrap_1_arg(g_set_bold_peaks_font_w, g_set_bold_peaks_font) Xen_wrap_no_args(g_axis_label_font_w, g_axis_label_font) Xen_wrap_1_arg(g_set_axis_label_font_w, g_set_axis_label_font) Xen_wrap_no_args(g_axis_numbers_font_w, g_axis_numbers_font) Xen_wrap_1_arg(g_set_axis_numbers_font_w, g_set_axis_numbers_font) Xen_wrap_no_args(g_listener_font_w, g_listener_font) Xen_wrap_1_arg(g_set_listener_font_w, g_set_listener_font) Xen_wrap_no_args(g_snd_version_w, g_snd_version) Xen_wrap_1_optional_arg(g_color_orientation_dialog_w, g_color_orientation_dialog) Xen_wrap_1_optional_arg(g_transform_dialog_w, g_transform_dialog) Xen_wrap_2_optional_args(g_print_dialog_w, g_print_dialog) Xen_wrap_no_args(g_preferences_dialog_w, g_preferences_dialog) Xen_wrap_no_args(g_abort_w, g_abort) #if (!HAVE_SCHEME) Xen_wrap_no_args(g_abortq_w, g_abortq) #endif #if HAVE_SCHEME static s7_pointer acc_temp_dir(s7_scheme *sc, s7_pointer args) {return(g_set_temp_dir(s7_cadr(args)));} static s7_pointer acc_save_dir(s7_scheme *sc, s7_pointer args) {return(g_set_save_dir(s7_cadr(args)));} static s7_pointer acc_ladspa_dir(s7_scheme *sc, s7_pointer args) {return(g_set_ladspa_dir(s7_cadr(args)));} static s7_pointer acc_peak_env_dir(s7_scheme *sc, s7_pointer args) {return(g_set_peak_env_dir(s7_cadr(args)));} static s7_pointer acc_listener_font(s7_scheme *sc, s7_pointer args) {return(g_set_listener_font(s7_cadr(args)));} static s7_pointer acc_axis_label_font(s7_scheme *sc, s7_pointer args) {return(g_set_axis_label_font(s7_cadr(args)));} static s7_pointer acc_axis_numbers_font(s7_scheme *sc, s7_pointer args) {return(g_set_axis_numbers_font(s7_cadr(args)));} static s7_pointer acc_tiny_font(s7_scheme *sc, s7_pointer args) {return(g_set_tiny_font(s7_cadr(args)));} static s7_pointer acc_peaks_font(s7_scheme *sc, s7_pointer args) {return(g_set_peaks_font(s7_cadr(args)));} static s7_pointer acc_bold_peaks_font(s7_scheme *sc, s7_pointer args) {return(g_set_bold_peaks_font(s7_cadr(args)));} static s7_pointer acc_with_inset_graph(s7_scheme *sc, s7_pointer args) {return(g_set_with_inset_graph(s7_cadr(args)));} static s7_pointer acc_with_pointer_focus(s7_scheme *sc, s7_pointer args) {return(g_set_with_pointer_focus(s7_cadr(args)));} static s7_pointer acc_with_smpte_label(s7_scheme *sc, s7_pointer args) {return(g_set_with_smpte_label(s7_cadr(args)));} static s7_pointer acc_with_interrupts(s7_scheme *sc, s7_pointer args) {return(g_set_with_interrupts(s7_cadr(args)));} static s7_pointer acc_color_scale(s7_scheme *sc, s7_pointer args) {return(g_set_color_scale(s7_cadr(args)));} static s7_pointer acc_color_cutoff(s7_scheme *sc, s7_pointer args) {return(g_set_color_cutoff(s7_cadr(args)));} static s7_pointer acc_color_inverted(s7_scheme *sc, s7_pointer args) {return(g_set_color_inverted(s7_cadr(args)));} static s7_pointer acc_auto_resize(s7_scheme *sc, s7_pointer args) {return(g_set_auto_resize(s7_cadr(args)));} static s7_pointer acc_print_length(s7_scheme *sc, s7_pointer args) {return(g_set_print_length(s7_cadr(args)));} static s7_pointer acc_selection_creates_region(s7_scheme *sc, s7_pointer args) {return(g_set_selection_creates_region(s7_cadr(args)));} static s7_pointer acc_save_state_file(s7_scheme *sc, s7_pointer args) {return(g_set_save_state_file(s7_cadr(args)));} static s7_pointer acc_with_background_processes(s7_scheme *sc, s7_pointer args) {return(g_set_with_background_processes(s7_cadr(args)));} static s7_pointer acc_with_file_monitor(s7_scheme *sc, s7_pointer args) {return(g_set_with_file_monitor(s7_cadr(args)));} static s7_pointer acc_show_indices(s7_scheme *sc, s7_pointer args) {return(g_set_show_indices(s7_cadr(args)));} static s7_pointer acc_just_sounds(s7_scheme *sc, s7_pointer args) {return(g_set_just_sounds(s7_cadr(args)));} static s7_pointer acc_play_arrow_size(s7_scheme *sc, s7_pointer args) {return(g_set_play_arrow_size(s7_cadr(args)));} static s7_pointer acc_with_relative_panes(s7_scheme *sc, s7_pointer args) {return(g_set_with_relative_panes(s7_cadr(args)));} static s7_pointer acc_open_file_dialog_directory(s7_scheme *sc, s7_pointer args) {return(g_set_open_file_dialog_directory(s7_cadr(args)));} #endif void g_init_main(void) { #if HAVE_SCHEME s7_pointer pl_b, pl_bb, pl_i, pl_ii, pl_s, pl_ss, pl_d, pl_dr, pl_p, pl_z, pl_zb, pl_zbb; { s7_pointer i, b, d, r, s, p, z; i = s7_make_symbol(s7, "integer?"); b = s7_make_symbol(s7, "boolean?"); d = s7_make_symbol(s7, "float?"); r = s7_make_symbol(s7, "real?"); s = s7_make_symbol(s7, "string?"); p = s7_make_symbol(s7, "pair?"); z = s7_make_signature(s7, 2, p, b); pl_b = s7_make_signature(s7, 1, b); pl_bb = s7_make_signature(s7, 2, b, b); pl_i = s7_make_signature(s7, 1, i); pl_ii = s7_make_signature(s7, 2, i, i); pl_s = s7_make_signature(s7, 1, s); pl_ss = s7_make_signature(s7, 2, s, s); pl_d = s7_make_signature(s7, 1, d); pl_dr = s7_make_signature(s7, 2, d, r); pl_p = s7_make_signature(s7, 1, p); pl_z = s7_make_signature(s7, 1, z); pl_zb = s7_make_signature(s7, 2, z, b); pl_zbb = s7_make_signature(s7, 3, z, b, b); } #endif Xen_define_typed_procedure(S_save_state, g_save_state_w, 0, 1, 0, H_save_state, pl_ss); #if HAVE_FORTH /* exit is an existing word */ Xen_define_procedure("snd-" S_exit, g_exit_w, 0, 1, 0, H_exit); #else Xen_define_procedure(S_exit, g_exit_w, 0, 1, 0, H_exit); #endif Xen_define_typed_dilambda(S_save_state_file, g_save_state_file_w, H_save_state_file, S_set S_save_state_file, g_set_save_state_file_w, 0, 0, 1, 0, pl_s, pl_ss); Xen_define_typed_dilambda(S_save_dir, g_save_dir_w, H_save_dir, S_set S_save_dir, g_set_save_dir_w, 0, 0, 1, 0, pl_s, pl_ss); Xen_define_typed_dilambda(S_open_file_dialog_directory, g_open_file_dialog_directory_w, H_open_file_dialog_directory, S_set S_open_file_dialog_directory, g_set_open_file_dialog_directory_w, 0, 0, 1, 0, pl_s, pl_ss); Xen_define_typed_dilambda(S_peak_env_dir, g_peak_env_dir_w, H_peak_env_dir, S_set S_peak_env_dir, g_set_peak_env_dir_w, 0, 0, 1, 0, pl_s, pl_ss); Xen_define_typed_dilambda(S_temp_dir, g_temp_dir_w, H_temp_dir, S_set S_temp_dir, g_set_temp_dir_w, 0, 0, 1, 0, pl_s, pl_ss); Xen_define_typed_dilambda(S_ladspa_dir, g_ladspa_dir_w, H_ladspa_dir, S_set S_ladspa_dir, g_set_ladspa_dir_w, 0, 0, 1, 0, pl_s, pl_ss); #if (!DISABLE_DEPRECATED) #define H_start_hook S_start_hook " (name): called upon start-up. If it returns " PROC_TRUE ", snd exits immediately." start_hook = Xen_define_hook(S_start_hook, "(make-hook 'name)", 1, H_start_hook); #endif #define H_before_exit_hook S_before_exit_hook " (): called upon exit. If it returns " PROC_TRUE ", Snd does not exit." before_exit_hook = Xen_define_hook(S_before_exit_hook, "(make-hook)", 0, H_before_exit_hook); #define H_exit_hook S_exit_hook " (): called upon exit. This can be used to perform cleanup activities." exit_hook = Xen_define_hook(S_exit_hook, "(make-hook)", 0, H_exit_hook); #define H_after_save_state_hook S_after_save_state_hook " (name): called after Snd state has been saved; filename is the save state file." after_save_state_hook = Xen_define_hook(S_after_save_state_hook, "(make-hook 'name)", 1, H_after_save_state_hook); #define H_before_save_state_hook S_before_save_state_hook " (name): called before Snd state is saved. If \ the hook functions return " PROC_TRUE ", the save state process opens the file 'name' for appending, rather than truncating." before_save_state_hook = Xen_define_hook(S_before_save_state_hook, "(make-hook 'name)", 1, H_before_save_state_hook); Xen_define_typed_dilambda(S_script_arg, g_script_arg_w, H_script_arg, S_set S_script_arg, g_set_script_arg_w, 0, 0, 1, 0, pl_i, pl_ii); Xen_define_typed_procedure(S_script_args, g_script_args_w, 0, 0, 0, H_script_args, pl_p); Xen_define_typed_dilambda(S_window_x, g_window_x_w, H_window_x, S_set S_window_x, g_set_window_x_w, 0, 0, 1, 0, pl_i, pl_ii); Xen_define_typed_dilambda(S_window_y, g_window_y_w, H_window_y, S_set S_window_y, g_set_window_y_w, 0, 0, 1, 0, pl_i, pl_ii); Xen_define_typed_dilambda(S_window_width, g_window_width_w, H_window_width, S_set S_window_width, g_set_window_width_w, 0, 0, 1, 0, pl_i, pl_ii); Xen_define_typed_dilambda(S_window_height, g_window_height_w, H_window_height, S_set S_window_height, g_set_window_height_w, 0, 0, 1, 0, pl_i, pl_ii); Xen_define_typed_dilambda(S_auto_resize, g_auto_resize_w, H_auto_resize, S_set S_auto_resize, g_set_auto_resize_w, 0, 0, 1, 0, pl_b, pl_bb); Xen_define_typed_dilambda(S_color_cutoff, g_color_cutoff_w, H_color_cutoff, S_set S_color_cutoff, g_set_color_cutoff_w, 0, 0, 1, 0, pl_d, pl_dr); Xen_define_typed_dilambda(S_color_inverted, g_color_inverted_w, H_color_inverted, S_set S_color_inverted, g_set_color_inverted_w, 0, 0, 1, 0, pl_b, pl_bb); Xen_define_typed_dilambda(S_color_scale, g_color_scale_w, H_color_scale, S_set S_color_scale, g_set_color_scale_w, 0, 0, 1, 0, pl_d, pl_dr); Xen_define_typed_dilambda(S_selection_creates_region, g_selection_creates_region_w, H_selection_creates_region, S_set S_selection_creates_region, g_set_selection_creates_region_w, 0, 0, 1, 0, pl_b, pl_bb); Xen_define_typed_dilambda(S_print_length, g_print_length_w, H_print_length, S_set S_print_length, g_set_print_length_w, 0, 0, 1, 0, pl_i, pl_ii); Xen_define_typed_dilambda(S_show_indices, g_show_indices_w, H_show_indices, S_set S_show_indices, g_set_show_indices_w, 0, 0, 1, 0, pl_b, pl_bb); Xen_define_typed_dilambda(S_with_relative_panes, g_with_relative_panes_w, H_with_relative_panes, S_set S_with_relative_panes, g_set_with_relative_panes_w, 0, 0, 1, 0, pl_b, pl_bb); Xen_define_typed_dilambda(S_with_background_processes, g_with_background_processes_w, H_with_background_processes, S_set S_with_background_processes, g_set_with_background_processes_w, 0, 0, 1, 0, pl_b, pl_bb); Xen_define_typed_dilambda(S_with_file_monitor, g_with_file_monitor_w, H_with_file_monitor, S_set S_with_file_monitor, g_set_with_file_monitor_w, 0, 0, 1, 0, pl_b, pl_bb); Xen_define_typed_dilambda(S_tiny_font, g_tiny_font_w, H_tiny_font, S_set S_tiny_font, g_set_tiny_font_w, 0, 0, 1, 0, pl_s, pl_ss); Xen_define_typed_dilambda(S_peaks_font, g_peaks_font_w, H_peaks_font, S_set S_peaks_font, g_set_peaks_font_w, 0, 0, 1, 0, pl_s, pl_ss); Xen_define_typed_dilambda(S_bold_peaks_font, g_bold_peaks_font_w, H_bold_peaks_font, S_set S_bold_peaks_font, g_set_bold_peaks_font_w, 0, 0, 1, 0, pl_s, pl_ss); Xen_define_typed_dilambda(S_axis_label_font, g_axis_label_font_w, H_axis_label_font, S_set S_axis_label_font, g_set_axis_label_font_w, 0, 0, 1, 0, pl_s, pl_ss); Xen_define_typed_dilambda(S_axis_numbers_font, g_axis_numbers_font_w, H_axis_numbers_font, S_set S_axis_numbers_font, g_set_axis_numbers_font_w, 0, 0, 1, 0, pl_s, pl_ss); Xen_define_typed_dilambda(S_listener_font, g_listener_font_w, H_listener_font, S_set S_listener_font, g_set_listener_font_w, 0, 0, 1, 0, pl_s, pl_ss); Xen_define_typed_dilambda(S_just_sounds, g_just_sounds_w, H_just_sounds, S_set S_just_sounds, g_set_just_sounds_w, 0, 0, 1, 0, pl_b, pl_bb); Xen_define_typed_dilambda(S_play_arrow_size, g_play_arrow_size_w, H_play_arrow_size, S_set S_play_arrow_size, g_set_play_arrow_size_w, 0, 0, 1, 0, pl_i, pl_ii); Xen_define_typed_dilambda(S_with_inset_graph, g_with_inset_graph_w, H_with_inset_graph, S_set S_with_inset_graph, g_set_with_inset_graph_w, 0, 0, 1, 0, pl_b, pl_bb); Xen_define_typed_dilambda(S_with_interrupts, g_with_interrupts_w, H_with_interrupts, S_set S_with_interrupts, g_set_with_interrupts_w, 0, 0, 1, 0, pl_b, pl_bb); Xen_define_typed_dilambda(S_with_smpte_label, g_with_smpte_label_w, H_with_smpte_label, S_set S_with_smpte_label, g_set_with_smpte_label_w, 0, 0, 1, 0, pl_b, pl_bb); Xen_define_typed_dilambda(S_with_pointer_focus, g_with_pointer_focus_w, H_with_pointer_focus, S_set S_with_pointer_focus, g_set_with_pointer_focus_w, 0, 0, 1, 0, pl_b, pl_bb); Xen_define_typed_procedure(S_snd_version, g_snd_version_w, 0, 0, 0, H_snd_version, pl_s); Xen_define_typed_procedure(S_color_orientation_dialog,g_color_orientation_dialog_w, 0, 1, 0, H_color_orientation_dialog, pl_zb); Xen_define_typed_procedure(S_transform_dialog, g_transform_dialog_w, 0, 1, 0, H_transform_dialog, pl_zb); Xen_define_typed_procedure(S_print_dialog, g_print_dialog_w, 0, 2, 0, H_print_dialog, pl_zbb); Xen_define_typed_procedure(S_preferences_dialog, g_preferences_dialog_w, 0, 0, 0, H_preferences_dialog, pl_z); Xen_define_procedure(S_abort, g_abort_w, 0, 0, 0, H_abort); #if (!HAVE_SCHEME) Xen_define_procedure(S_c_g, g_abortq_w, 0, 0, 0, H_abortQ); #endif #if HAVE_SCHEME s7_symbol_set_documentation(s7, ss->temp_dir_symbol, "*temp-dir*: name of directory for temp files (or #f=null)"); s7_symbol_set_documentation(s7, ss->save_dir_symbol, "*save-dir*: name of directory for saved state data (or #f=null)"); s7_symbol_set_documentation(s7, ss->ladspa_dir_symbol, "*ladspa-dir*: name of directory for ladspa plugin libraries"); s7_symbol_set_documentation(s7, ss->peak_env_dir_symbol, "*peak-env-dir*: name of directory for peak env files (or #f=null)"); s7_symbol_set_documentation(s7, ss->listener_font_symbol, "*listener-font*: font used by the lisp listener"); s7_symbol_set_documentation(s7, ss->axis_label_font_symbol, "*axis-label-font*: font used for axis labels"); s7_symbol_set_documentation(s7, ss->axis_numbers_font_symbol, "*axis-numbers-font*: font used for axis numbers"); s7_symbol_set_documentation(s7, ss->tiny_font_symbol, "*tiny-font*: font use for some info in the graphs"); s7_symbol_set_documentation(s7, ss->peaks_font_symbol, "*peaks-font*: normal font used by fft peak display"); s7_symbol_set_documentation(s7, ss->bold_peaks_font_symbol, "*bold-peaks-font*: bold font used by fft peak display"); s7_symbol_set_documentation(s7, ss->with_inset_graph_symbol, "*with-inset-graph*: if #t, display the inset graph in the time domain section."); s7_symbol_set_documentation(s7, ss->with_pointer_focus_symbol, "*with-pointer-focus*: if #t, activate the text or graph widget beneath the mouse."); s7_symbol_set_documentation(s7, ss->with_smpte_label_symbol, "*with-smpte-label*: if #t, display the SMPTE data in the time domain section."); s7_symbol_set_documentation(s7, ss->with_interrupts_symbol, "*with-interrupts*: if #t, check for GUI events during computations."); s7_symbol_set_documentation(s7, ss->color_scale_symbol, "*color-scale*: darkness setting for colormaps (0.5)"); s7_symbol_set_documentation(s7, ss->color_cutoff_symbol, "*color-cutoff*: color map cutoff point (default .003)."); s7_symbol_set_documentation(s7, ss->color_inverted_symbol, "*color-inverted*: whether the colormap in operation should be inverted"); s7_symbol_set_documentation(s7, ss->auto_resize_symbol, "*auto-resize*: #t if Snd can change its main window size as it pleases"); s7_symbol_set_documentation(s7, ss->print_length_symbol, "*print-length*: number of vector elements to print in the listener (12)"); s7_symbol_set_documentation(s7, ss->selection_creates_region_symbol, "*selection-creates-region*: #t if a region should be created each time a selection is made."); s7_symbol_set_documentation(s7, ss->save_state_file_symbol, "*save-state-file*: the name of the saved state file (\"saved-snd.scm\")"); s7_symbol_set_documentation(s7, ss->with_background_processes_symbol, "*with-background-processes*: #t if Snd should use background (idle time) processing"); s7_symbol_set_documentation(s7, ss->with_file_monitor_symbol, "*with-file-monitor*: #t if the file alteration monitor is active"); s7_symbol_set_documentation(s7, ss->show_indices_symbol, "*show-indices*: #t if sound name should be preceded by its index in the sound display."); s7_symbol_set_documentation(s7, ss->just_sounds_symbol, "*just-sounds*: the 'just sounds' choice in the file chooser dialog"); s7_symbol_set_documentation(s7, ss->play_arrow_size_symbol, "*play-arrow-size*: the size of the play triangles"); s7_symbol_set_documentation(s7, ss->with_relative_panes_symbol, "*with-relative-panes*: #t if multichannel sounds should try to maintain relative pane sizes"); s7_symbol_set_documentation(s7, ss->open_file_dialog_directory_symbol, "*open-file-dialog-directory*: name of directory for initial open file dialog search"); s7_symbol_set_access(s7, ss->temp_dir_symbol, s7_make_function(s7, "[acc-" S_temp_dir "]", acc_temp_dir, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->save_dir_symbol, s7_make_function(s7, "[acc-" S_save_dir "]", acc_save_dir, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->ladspa_dir_symbol, s7_make_function(s7, "[acc-" S_ladspa_dir "]", acc_ladspa_dir, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->peak_env_dir_symbol, s7_make_function(s7, "[acc-" S_peak_env_dir "]", acc_peak_env_dir, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->listener_font_symbol, s7_make_function(s7, "[acc-" S_listener_font "]", acc_listener_font, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->axis_label_font_symbol, s7_make_function(s7, "[acc-" S_axis_label_font "]", acc_axis_label_font, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->axis_numbers_font_symbol, s7_make_function(s7, "[acc-" S_axis_numbers_font "]", acc_axis_numbers_font, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->tiny_font_symbol, s7_make_function(s7, "[acc-" S_tiny_font "]", acc_tiny_font, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->peaks_font_symbol, s7_make_function(s7, "[acc-" S_peaks_font "]", acc_peaks_font, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->bold_peaks_font_symbol, s7_make_function(s7, "[acc-" S_bold_peaks_font "]", acc_bold_peaks_font, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->with_inset_graph_symbol, s7_make_function(s7, "[acc-" S_with_inset_graph "]", acc_with_inset_graph, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->with_pointer_focus_symbol, s7_make_function(s7, "[acc-" S_with_pointer_focus "]", acc_with_pointer_focus, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->with_smpte_label_symbol, s7_make_function(s7, "[acc-" S_with_smpte_label "]", acc_with_smpte_label, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->with_interrupts_symbol, s7_make_function(s7, "[acc-" S_with_interrupts "]", acc_with_interrupts, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->color_scale_symbol, s7_make_function(s7, "[acc-" S_color_scale "]", acc_color_scale, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->color_cutoff_symbol, s7_make_function(s7, "[acc-" S_color_cutoff "]", acc_color_cutoff, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->color_inverted_symbol, s7_make_function(s7, "[acc-" S_color_inverted "]", acc_color_inverted, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->auto_resize_symbol, s7_make_function(s7, "[acc-" S_auto_resize "]", acc_auto_resize, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->print_length_symbol, s7_make_function(s7, "[acc-" S_print_length "]", acc_print_length, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->selection_creates_region_symbol, s7_make_function(s7, "[acc-" S_selection_creates_region "]", acc_selection_creates_region, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->save_state_file_symbol, s7_make_function(s7, "[acc-" S_save_state_file "]", acc_save_state_file, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->with_background_processes_symbol, s7_make_function(s7, "[acc-" S_with_background_processes "]", acc_with_background_processes, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->with_file_monitor_symbol, s7_make_function(s7, "[acc-" S_with_file_monitor "]", acc_with_file_monitor, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->show_indices_symbol, s7_make_function(s7, "[acc-" S_show_indices "]", acc_show_indices, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->just_sounds_symbol, s7_make_function(s7, "[acc-" S_just_sounds "]", acc_just_sounds, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->play_arrow_size_symbol, s7_make_function(s7, "[acc-" S_play_arrow_size "]", acc_play_arrow_size, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->with_relative_panes_symbol, s7_make_function(s7, "[acc-" S_with_relative_panes "]", acc_with_relative_panes, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->open_file_dialog_directory_symbol, s7_make_function(s7, "[acc-" S_open_file_dialog_directory "]", acc_open_file_dialog_directory, 2, 0, false, "accessor")); #endif } snd-16.1/zip.scm0000644000076400007640000001167012446644400011652 0ustar bilbil;;; create the 'digital zipper' effect ;;; a not-very-debonair way to fade out file1 and fade in file2 ;;; this is also good if the same file is used twice -- sort of like a CD player gone berserk ;;; ;;; changed 21-Sep-10 to use defgenerator ;;; changed 19-Apr-05 to use def-clm-struct and envelopes (and fixed duration bug in zip-sound) (provide 'snd-zip.scm) (if (provided? 'snd) (require snd-ws.scm) (require sndlib-ws.scm)) (define (safe-srate) (if (pair? (sounds)) (srate) *clm-srate*)) (defgenerator zdata (low-start 20) (frame-loc 0) (cursamples 0) (frame0 #f) (frame1 #f) (frame2 #f) (fe #f) (rampe #f) input1 input2) (define make-zipper (let ((documentation "(make-zipper ramp-env frame-size frame-env) makes a zipper generator. 'ramp-env' is an envelope (normally a ramp from 0 to 1) which sets where we are in the zipping process, 'frame-size' is the maximum frame length during the zip in seconds (defaults to 0.05), and 'frame-env' is an envelope returning the current frame size during the zip process.")) (lambda* (ramp-env frame-size frame-env) (let ((max-size (+ 1 (ceiling (* (safe-srate) (or frame-size 0.05)))))) (make-zdata :low-start 20 :frame-loc 0 :cursamples 0 :frame0 (make-float-vector max-size) :frame1 (make-float-vector max-size) :frame2 (make-float-vector max-size) :fe (or frame-env (make-env (list 0 (* (safe-srate) 0.05)) :length (mus-length ramp-env))) ; a bit of a kludge... :rampe ramp-env))))) (define zipper (let ((documentation "(zipper zip in1 in2) creates the digital zipper sound effect using zipper generator 'zip' and the two samplers 'in1' and 'in2'")) (lambda (zp input1 input2) (let-set! zp 'input1 input1) (let-set! zp 'input2 input2) (with-let zp (let* ((frame-samples (floor (env fe))) (chunk-len (round (* frame-samples (env rampe))))) (if (<= chunk-len low-start) (begin (set! frame-loc 0) (read-sample input1)) (if (>= chunk-len (- frame-samples low-start)) (begin (set! frame-loc 0) (input2)) ;; else we're in the ramp phase ;; read frame if we're within its bounds (begin (if (>= frame-loc cursamples) ;; now get next portion of the ramp (begin (set! frame-loc 0) (set! cursamples frame-samples) (do ((k 0 (+ k 1))) ((= k frame-samples)) (float-vector-set! frame1 k (read-sample input1))) (do ((k 0 (+ k 1))) ((= k frame-samples)) (float-vector-set! frame2 k (read-sample input2))) ;; now resample each dependent on location in ramp (samp1 and samp2 are increments) (fill! frame0 0.0) (let ((samp2 (* 1.0 (/ frame-samples chunk-len)))) ; this was floor (and also below)? (do ((k 0 (+ k 1)) (start-ctr 0.0 (+ start-ctr samp2))) ((= k chunk-len)) (let ((ictr (floor start-ctr))) (let ((y0 (float-vector-ref frame2 ictr)) (y1 (float-vector-ref frame2 (+ ictr 1)))) (float-vector-set! frame0 k (+ y0 (* (- y1 y0) (- start-ctr ictr)))))))) (let ((samp1 (* 1.0 (/ frame-samples (- frame-samples chunk-len))))) (do ((k chunk-len (+ k 1)) (start-ctr 0.0 (+ start-ctr samp1))) ((= k frame-samples)) (let ((ictr (floor start-ctr))) (let ((y0 (float-vector-ref frame1 ictr)) (y1 (float-vector-ref frame1 (+ ictr 1)))) (float-vector-set! frame0 k (+ y0 (* (- y1 y0) (- start-ctr ictr)))))))))) (let ((result (float-vector-ref frame0 frame-loc))) (set! frame-loc (+ frame-loc 1)) result))))))))) ;; (zip-sound 0 1 "fyow.snd" "now.snd" '(0 0 1 1) .05) ;; (zip-sound 0 3 "mb.snd" "fyow.snd" '(0 0 1.0 0 1.5 1.0 3.0 1.0) .025) (define zip-sound (let ((documentation "(zip-sound beg dur file1 file2 ramp-env size) zips the two files and mixes the result into the current sound")) (lambda* (beg-in-seconds dur-in-seconds file1 file2 ramp size) (let* ((beg (seconds->samples beg-in-seconds)) (dur (seconds->samples dur-in-seconds)) (zip (make-zipper (make-env (or ramp (list 0 0 1 1)) :length dur) (or size 0.05) (make-env (list 0 (* (srate) (or size 0.05))) :length dur))) (read0 (make-sampler 0 file1)) (read1 (make-sampler 0 file2))) (map-channel (lambda (y) (+ y (zipper zip read0 read1))) beg dur))))) #| (define (ramp-test) (let ((data (make-float-vector 10000))) (new-sound "new-0.snd") (do ((i 0 (+ i 1))) ((= i 10000)) (set! (data i) (* i .0001))) (float-vector->channel data 0 10000 0) (new-sound "new-1.snd") (do ((i 0 (+ i 1))) ((= i 10000)) (set! (data i) (- 1.0 (* i .0001)))) (float-vector->channel data 0 10000 1) (let* ((dur (framples)) (zp (make-zipper (make-env '(0 0 1 1) :length dur) 0.05 (make-env (list 0 (* (safe-srate) 0.05)) :length dur))) (reader0 (make-sampler 0 0 0)) (reader1 (make-sampler 0 1 0))) (map-channel (lambda (val) (zipper zp reader0 reader1)))))) |# snd-16.1/spectr.fs0000644000076400007640000065203212306421672012200 0ustar bilbil\ spectr.fs -- spectr.cl --> spectr.fs \ Translator: Michael Scholz \ Created: Thu Nov 18 15:26:46 CET 2004 \ Changed: Fri Mar 23 22:51:31 CET 2012 \ Commentary: \ Original comment in spectr.cl: \ \ "Spectra courtesy J.A. Moorer \ \ "I removed phase information, since the psychoacousticians tell us \ that these normally don't matter. Also, I omitted any partials with \ amplitude below 0.0001, although this may have thrown away good \ data, because the original data was not normalized in any way." \ contents: \ \ bass clarinet (bc) \ bassoon (bsn) \ cello (c) \ clarinet (cl) \ french horn (fh) \ (fhf) \ flute (fl) \ oboe (ob) \ piano (p) \ saxophone (sax) \ soprano sax (ssax) \ (tbf) \ (tbp) \ trumpet (trp) \ (trpf) \ violin (vl) \ (almf) \ ********************************************************** \ bass clarinet \ ********************************************************** #( 1.00 0.0370 1.98 0.0037 2.99 0.0862 3.98 0.0011 4.97 0.0270 5.98 0.0030 6.97 0.0586 7.95 0.0031 8.96 0.0363 9.95 0.0076 10.93 0.0310 11.95 0.0097 12.93 0.0206 13.92 0.0045 14.93 0.0044 15.91 0.0021 16.90 0.0220 17.91 0.0082 18.90 0.0227 19.88 0.0049 20.90 0.0090 21.87 0.0004 22.87 0.0051 23.88 0.0010 24.86 0.0072 25.85 0.0026 26.86 0.0044 27.84 0.0035 28.85 0.0031 29.84 0.0025 30.83 0.0042 31.84 0.0024 32.83 0.0022 33.81 0.0021 34.82 0.0011 35.81 0.0008 36.79 0.0013 37.80 0.0024 38.78 0.0028 39.78 0.0016 40.79 0.0024 41.77 0.0005 42.76 0.0005 43.77 0.0003 44.76 0.0002 45.74 0.0005 46.75 0.0003 47.74 0.0006 48.73 0.0003 49.74 0.0009 50.72 0.0002 51.71 0.0007 52.72 0.0004 53.70 0.0005 54.70 0.0004 55.71 0.0005 56.69 0.0002 57.68 0.0003 58.69 0.0002 59.68 0.0002 60.68 0.0003 61.68 0.0002 62.66 0.0002 63.66 0.0002 65.65 0.0001 67.64 0.0002 69.63 0.0002 70.63 0.0002 71.60 0.0002 72.62 0.0002 73.60 0.0002 75.59 0.0002 76.59 0.0002 77.58 0.0001 78.59 0.0001 79.57 0.0002 80.57 0.0002 81.57 0.0002 82.54 0.0001 83.56 0.0002 84.54 0.0001 85.53 0.0001 87.53 0.0002 89.53 0.0002 ) constant bc-c2 #( 1.02 0.0306 2.00 0.0016 2.99 0.0926 4.00 0.0027 5.01 0.0305 5.99 0.0006 6.99 0.0158 8.00 0.0025 9.01 0.0072 10.01 0.0057 10.99 0.0203 12.00 0.0078 13.01 0.0147 14.02 0.0036 15.00 0.0103 16.07 0.0007 17.01 0.0070 18.01 0.0053 19.00 0.0049 20.02 0.0027 21.01 0.0024 22.01 0.0014 23.00 0.0011 24.02 0.0023 25.00 0.0031 26.01 0.0021 27.00 0.0029 28.02 0.0010 29.02 0.0026 30.04 0.0011 31.00 0.0019 32.01 0.0010 33.03 0.0004 34.02 0.0002 36.02 0.0004 37.05 0.0002 38.04 0.0004 39.00 0.0003 40.02 0.0002 41.01 0.0002 42.01 0.0002 43.00 0.0001 44.02 0.0001 45.01 0.0002 47.01 0.0002 48.03 0.0001 49.00 0.0002 50.03 0.0001 51.02 0.0001 55.00 0.0001 56.99 0.0002 73.98 0.0001 75.02 0.0001 75.98 0.0001 ) constant bc-cs2 #( 1.01 0.1419 1.97 0.0009 3.00 0.0865 4.01 0.0008 5.00 0.0059 6.00 0.0009 7.00 0.0110 8.00 0.0014 9.00 0.0050 10.00 0.0057 11.01 0.0267 12.01 0.0091 13.00 0.0238 14.02 0.0023 15.01 0.0069 16.01 0.0033 17.00 0.0064 18.01 0.0036 18.99 0.0067 20.01 0.0026 21.01 0.0047 22.01 0.0037 22.99 0.0040 24.00 0.0038 25.01 0.0036 26.01 0.0032 27.00 0.0036 27.99 0.0019 29.00 0.0034 30.00 0.0014 31.00 0.0007 31.98 0.0003 33.04 0.0002 34.05 0.0003 35.04 0.0003 35.95 0.0002 37.05 0.0003 37.98 0.0002 39.07 0.0002 40.02 0.0002 40.95 0.0001 42.01 0.0003 42.98 0.0002 44.02 0.0004 44.99 0.0002 46.03 0.0002 46.98 0.0002 48.04 0.0001 49.01 0.0001 51.02 0.0002 52.03 0.0002 53.01 0.0002 54.01 0.0001 55.01 0.0002 56.02 0.0001 65.00 0.0002 66.99 0.0001 69.01 0.0001 71.00 0.0002 73.00 0.0001 74.99 0.0001 ) constant bc-d2 #( 1.01 0.2718 2.01 0.0016 3.01 0.0476 4.01 0.0022 5.01 0.0228 6.00 0.0005 7.01 0.0466 8.01 0.0014 9.00 0.0179 10.01 0.0059 11.00 0.0254 12.01 0.0099 13.00 0.0176 14.01 0.0031 15.02 0.0109 16.00 0.0007 17.02 0.0090 18.03 0.0038 19.02 0.0036 20.02 0.0029 21.02 0.0045 22.02 0.0026 23.02 0.0060 24.02 0.0031 25.02 0.0023 26.02 0.0033 27.02 0.0041 28.02 0.0033 29.02 0.0034 30.03 0.0007 31.04 0.0005 32.03 0.0005 33.05 0.0005 34.03 0.0006 35.05 0.0002 36.04 0.0004 37.03 0.0002 38.03 0.0003 39.03 0.0004 40.03 0.0002 41.03 0.0004 42.03 0.0003 43.03 0.0006 44.04 0.0002 45.05 0.0005 46.04 0.0001 47.05 0.0003 48.04 0.0002 49.05 0.0003 50.04 0.0001 51.04 0.0003 52.04 0.0002 53.04 0.0001 55.04 0.0002 57.05 0.0002 59.06 0.0002 61.07 0.0002 62.06 0.0001 63.06 0.0002 64.05 0.0001 65.06 0.0001 66.06 0.0002 67.06 0.0002 68.06 0.0002 70.06 0.0002 72.06 0.0001 74.08 0.0001 ) constant bc-ds2 #( 1.01 0.1365 2.01 0.0009 3.03 0.0219 3.99 0.0004 5.04 0.0239 6.03 0.0013 7.02 0.0284 8.04 0.0029 9.03 0.0167 10.06 0.0042 11.05 0.0059 12.03 0.0012 13.07 0.0095 14.07 0.0013 15.08 0.0109 16.06 0.0038 17.06 0.0042 18.09 0.0006 19.07 0.0034 20.10 0.0036 21.09 0.0018 22.08 0.0025 23.11 0.0054 24.08 0.0008 25.12 0.0035 26.09 0.0013 27.13 0.0022 28.13 0.0009 29.12 0.0006 30.14 0.0004 31.13 0.0005 32.15 0.0003 33.15 0.0003 35.15 0.0002 36.13 0.0001 37.17 0.0003 38.19 0.0002 39.16 0.0006 40.21 0.0001 41.17 0.0005 42.18 0.0002 43.19 0.0003 44.18 0.0001 45.21 0.0002 46.19 0.0002 47.22 0.0004 48.22 0.0002 49.20 0.0002 50.23 0.0001 55.24 0.0001 56.23 0.0001 57.26 0.0002 59.26 0.0001 61.25 0.0002 62.29 0.0002 64.27 0.0001 ) constant bc-e2 #( 0.99 0.1014 2.00 0.0021 3.02 0.0301 4.02 0.0012 5.00 0.0893 6.02 0.0028 7.03 0.0333 8.04 0.0046 9.05 0.0109 10.03 0.0033 11.03 0.0174 12.05 0.0075 13.06 0.0085 14.06 0.0037 15.04 0.0133 16.08 0.0021 17.07 0.0017 18.07 0.0009 19.05 0.0015 20.07 0.0002 21.08 0.0068 22.09 0.0033 23.10 0.0060 24.07 0.0031 25.08 0.0036 26.10 0.0009 27.11 0.0001 28.11 0.0010 29.10 0.0007 30.10 0.0004 31.12 0.0005 32.13 0.0002 33.11 0.0005 34.11 0.0003 35.12 0.0004 36.13 0.0002 37.14 0.0005 38.12 0.0001 39.14 0.0005 40.14 0.0002 41.16 0.0002 43.14 0.0003 45.17 0.0004 46.18 0.0002 47.16 0.0002 49.18 0.0002 51.18 0.0001 53.19 0.0002 55.22 0.0001 56.19 0.0002 57.21 0.0001 58.22 0.0002 60.23 0.0002 62.22 0.0001 ) constant bc-f2 #( 1.01 0.0724 2.02 0.0045 3.01 0.0626 4.01 0.0014 5.00 0.1104 6.00 0.0041 7.00 0.0216 8.03 0.0017 9.03 0.0255 10.02 0.0011 11.02 0.0152 12.02 0.0019 13.01 0.0061 14.02 0.0018 15.04 0.0077 16.05 0.0009 17.04 0.0031 18.04 0.0014 19.02 0.0058 20.04 0.0005 21.03 0.0030 22.03 0.0030 23.05 0.0048 24.06 0.0013 25.04 0.0009 26.04 0.0002 27.03 0.0008 28.05 0.0005 29.05 0.0003 30.06 0.0002 31.06 0.0004 32.05 0.0005 33.05 0.0003 34.04 0.0002 35.05 0.0004 37.08 0.0006 38.06 0.0002 39.07 0.0003 41.06 0.0003 42.07 0.0001 43.07 0.0003 44.09 0.0002 45.10 0.0001 47.07 0.0001 51.10 0.0002 53.10 0.0002 54.10 0.0001 56.09 0.0002 57.09 0.0001 58.12 0.0001 62.11 0.0001 64.11 0.0001 ) constant bc-fs2 #( 1.00 0.0567 1.99 0.0037 3.00 0.1114 3.98 0.0030 4.99 0.1112 5.98 0.0041 6.99 0.0195 7.99 0.0061 8.98 0.0081 9.97 0.0084 10.98 0.0139 11.98 0.0038 12.98 0.0092 13.97 0.0038 14.97 0.0042 15.97 0.0003 16.97 0.0012 17.96 0.0019 18.97 0.0040 19.95 0.0032 20.97 0.0088 21.95 0.0022 22.96 0.0025 23.94 0.0004 24.94 0.0003 25.92 0.0005 26.95 0.0005 27.91 0.0003 28.95 0.0003 29.90 0.0002 30.94 0.0006 31.89 0.0001 32.93 0.0007 34.92 0.0005 35.89 0.0002 36.92 0.0003 37.89 0.0001 38.91 0.0002 39.88 0.0002 40.90 0.0004 41.88 0.0002 43.88 0.0002 50.90 0.0001 51.89 0.0002 52.93 0.0001 53.89 0.0003 55.87 0.0002 ) constant bc-g2 #( 0.99 0.0794 2.00 0.0021 3.00 0.1294 3.98 0.0015 4.98 0.0849 5.98 0.0058 6.99 0.0389 7.97 0.0113 8.97 0.0154 9.98 0.0026 10.98 0.0172 11.95 0.0048 12.95 0.0099 13.98 0.0011 14.97 0.0029 15.95 0.0013 16.95 0.0055 17.97 0.0014 18.96 0.0052 19.94 0.0040 20.94 0.0038 21.96 0.0006 22.94 0.0003 23.92 0.0005 24.93 0.0005 25.93 0.0002 26.94 0.0006 27.92 0.0003 28.91 0.0007 29.91 0.0004 30.93 0.0006 31.90 0.0003 32.90 0.0006 33.90 0.0003 34.91 0.0004 35.89 0.0001 36.89 0.0003 37.90 0.0003 38.90 0.0003 40.88 0.0002 42.89 0.0001 45.89 0.0002 47.87 0.0001 49.87 0.0003 50.86 0.0002 51.85 0.0002 53.86 0.0001 ) constant bc-gs2 #( 0.99 0.1177 1.99 0.0047 2.99 0.2346 3.99 0.0023 4.98 0.0538 5.99 0.0060 6.98 0.0493 7.99 0.0062 8.99 0.0103 9.99 0.0030 10.99 0.0146 11.99 0.0126 12.99 0.0042 13.99 0.0016 14.99 0.0060 15.98 0.0034 16.96 0.0039 17.96 0.0036 18.96 0.0076 19.96 0.0018 20.96 0.0025 22.95 0.0018 23.95 0.0005 24.94 0.0003 25.95 0.0005 26.95 0.0006 27.95 0.0008 28.96 0.0005 29.96 0.0005 30.96 0.0007 31.95 0.0005 32.95 0.0005 33.95 0.0001 34.95 0.0003 35.93 0.0002 36.94 0.0003 38.92 0.0002 42.93 0.0001 44.93 0.0001 46.93 0.0002 47.92 0.0001 ) constant bc-a2 #( 1.00 0.1279 1.99 0.0028 2.99 0.1611 3.98 0.0034 4.97 0.0322 5.97 0.0085 6.98 0.0274 7.97 0.0068 8.96 0.0245 9.97 0.0022 10.94 0.0254 11.93 0.0010 12.93 0.0078 13.95 0.0022 14.94 0.0035 15.92 0.0022 16.92 0.0033 17.91 0.0039 18.90 0.0037 19.92 0.0012 20.92 0.0003 21.91 0.0008 22.89 0.0005 23.88 0.0007 24.87 0.0007 25.87 0.0005 26.88 0.0007 27.86 0.0001 28.86 0.0014 29.84 0.0004 30.85 0.0005 31.85 0.0001 32.85 0.0004 33.84 0.0004 34.84 0.0003 36.82 0.0003 40.81 0.0003 42.80 0.0001 43.79 0.0002 44.79 0.0002 45.79 0.0003 46.79 0.0001 47.79 0.0002 49.77 0.0001 ) constant bc-as2 #( 1.00 0.1161 1.98 0.0036 2.97 0.1813 3.98 0.0038 4.96 0.0298 5.95 0.0073 6.95 0.0125 7.95 0.0064 8.92 0.0175 9.94 0.0087 10.91 0.0117 11.91 0.0025 12.91 0.0055 13.92 0.0027 14.88 0.0069 15.88 0.0034 16.88 0.0052 17.85 0.0038 18.88 0.0003 19.83 0.0005 20.83 0.0005 21.78 0.0002 22.82 0.0004 23.74 0.0002 24.81 0.0008 25.76 0.0003 26.78 0.0005 27.78 0.0006 28.78 0.0005 29.74 0.0002 30.75 0.0001 31.75 0.0004 32.72 0.0002 33.73 0.0002 34.73 0.0002 41.69 0.0002 42.68 0.0002 43.67 0.0002 44.68 0.0002 45.67 0.0001 ) constant bc-b2 #( 1.00 0.1579 1.99 0.0068 2.99 0.1885 3.99 0.0022 4.97 0.0384 5.96 0.0054 6.97 0.0247 7.97 0.0023 8.96 0.0114 9.95 0.0096 10.93 0.0054 11.95 0.0030 12.94 0.0036 13.92 0.0075 14.93 0.0033 15.92 0.0052 16.91 0.0010 17.91 0.0011 18.90 0.0004 19.89 0.0006 20.90 0.0005 21.89 0.0003 22.87 0.0004 23.88 0.0004 24.87 0.0005 25.86 0.0008 26.87 0.0005 27.85 0.0002 28.84 0.0002 29.85 0.0003 30.83 0.0002 31.84 0.0002 32.83 0.0002 35.83 0.0001 36.80 0.0002 38.81 0.0002 39.78 0.0002 40.78 0.0003 41.79 0.0001 ) constant bc-c3 #( 1.00 0.2106 1.98 0.0073 2.99 0.1027 3.98 0.0038 4.97 0.0191 5.98 0.0036 6.97 0.0256 7.95 0.0035 8.97 0.0347 9.95 0.0039 10.94 0.0048 11.95 0.0026 12.94 0.0089 13.93 0.0011 14.93 0.0052 15.93 0.0033 16.96 0.0002 17.93 0.0003 18.94 0.0001 19.92 0.0002 20.91 0.0007 21.91 0.0006 22.89 0.0005 23.90 0.0005 24.90 0.0005 25.87 0.0005 26.89 0.0003 27.88 0.0005 28.87 0.0003 29.87 0.0003 31.85 0.0002 33.84 0.0001 34.84 0.0001 36.82 0.0003 37.83 0.0001 38.83 0.0003 ) constant bc-cs3 #( 1.01 0.2039 2.00 0.0041 3.00 0.0640 3.99 0.0062 5.00 0.0192 6.00 0.0013 7.01 0.0225 8.00 0.0034 9.01 0.0245 10.00 0.0038 11.02 0.0028 12.01 0.0030 13.02 0.0042 14.00 0.0021 15.01 0.0049 16.02 0.0006 17.02 0.0003 18.02 0.0007 19.00 0.0001 20.03 0.0005 21.02 0.0010 22.05 0.0002 23.04 0.0012 24.05 0.0003 25.02 0.0002 26.03 0.0003 27.02 0.0004 28.03 0.0001 29.05 0.0002 30.05 0.0001 33.03 0.0001 34.04 0.0001 35.04 0.0001 36.04 0.0003 38.05 0.0001 40.04 0.0001 ) constant bc-d3 #( 1.01 0.1501 2.00 0.0036 3.00 0.0682 4.00 0.0069 4.99 0.0142 5.98 0.0017 6.99 0.0322 7.99 0.0063 8.98 0.0019 10.00 0.0010 11.00 0.0046 11.99 0.0023 12.99 0.0035 13.98 0.0041 14.98 0.0020 15.97 0.0001 16.98 0.0003 17.98 0.0008 18.98 0.0009 20.03 0.0002 21.00 0.0007 21.99 0.0006 22.99 0.0006 23.99 0.0003 24.98 0.0004 25.98 0.0003 26.97 0.0001 27.98 0.0001 29.97 0.0001 30.98 0.0002 32.96 0.0003 33.97 0.0003 34.95 0.0002 35.96 0.0002 36.97 0.0001 ) constant bc-ds3 #( 0.99 0.1413 1.99 0.0047 3.00 0.0710 4.01 0.0016 5.01 0.0154 6.01 0.0063 7.01 0.0122 8.02 0.0179 9.00 0.0044 10.00 0.0082 11.01 0.0058 12.01 0.0031 13.02 0.0045 14.02 0.0027 15.02 0.0004 16.03 0.0010 17.01 0.0008 18.04 0.0002 19.04 0.0004 20.03 0.0006 21.04 0.0004 22.03 0.0003 23.04 0.0004 24.04 0.0002 25.04 0.0003 26.06 0.0001 27.04 0.0003 28.03 0.0002 29.02 0.0003 30.99 0.0002 32.04 0.0006 33.03 0.0002 34.04 0.0003 36.04 0.0001 ) constant bc-e3 #( 0.99 0.2534 1.99 0.0057 3.00 0.0476 3.98 0.0101 4.98 0.0334 5.97 0.0066 6.98 0.0489 7.96 0.0038 8.96 0.0096 9.95 0.0008 10.96 0.0056 11.95 0.0049 12.95 0.0029 13.95 0.0002 14.95 0.0006 15.96 0.0002 16.96 0.0008 17.94 0.0004 18.93 0.0002 19.94 0.0009 20.94 0.0002 21.93 0.0004 22.94 0.0004 23.93 0.0004 25.90 0.0004 26.90 0.0003 27.89 0.0001 28.91 0.0004 29.87 0.0001 30.89 0.0005 32.89 0.0002 33.87 0.0001 ) constant bc-f3 #( 1.00 0.3131 1.99 0.0095 3.00 0.0885 3.99 0.0194 4.98 0.0653 5.99 0.0049 6.98 0.0528 7.99 0.0038 8.98 0.0129 9.97 0.0042 10.98 0.0063 11.97 0.0023 12.97 0.0016 13.98 0.0002 14.97 0.0004 15.97 0.0005 16.97 0.0006 17.96 0.0001 18.96 0.0008 20.95 0.0007 21.96 0.0001 22.95 0.0001 23.94 0.0003 25.94 0.0004 26.95 0.0004 27.94 0.0005 28.93 0.0003 29.94 0.0003 31.93 0.0002 33.92 0.0002 ) constant bc-fs3 #( 1.00 0.2177 2.01 0.0024 3.01 0.0126 4.02 0.0067 5.02 0.0577 6.02 0.0083 7.02 0.0215 8.03 0.0034 9.03 0.0047 10.04 0.0046 11.05 0.0143 12.04 0.0037 13.04 0.0010 14.05 0.0005 15.06 0.0005 16.06 0.0003 17.06 0.0002 18.06 0.0004 19.09 0.0001 20.08 0.0003 21.08 0.0002 23.08 0.0003 24.08 0.0003 25.08 0.0001 26.10 0.0010 27.11 0.0002 28.10 0.0004 30.12 0.0003 32.13 0.0003 ) constant bc-g3 #( 1.01 0.1420 2.01 0.0026 3.01 0.0289 4.03 0.0162 5.03 0.0373 6.02 0.0015 7.03 0.0112 8.05 0.0068 9.05 0.0063 10.04 0.0027 11.06 0.0022 12.07 0.0004 13.06 0.0008 14.07 0.0011 15.08 0.0003 16.08 0.0002 17.09 0.0005 19.11 0.0003 23.12 0.0004 24.12 0.0003 25.14 0.0002 26.14 0.0003 27.14 0.0002 28.14 0.0002 29.16 0.0002 30.16 0.0001 34.18 0.0002 ) constant bc-gs3 #( 1.01 0.2365 2.02 0.0034 3.03 0.0242 4.04 0.0251 5.04 0.0203 6.06 0.0078 7.06 0.0213 8.08 0.0162 9.09 0.0121 10.10 0.0053 11.11 0.0024 12.12 0.0028 13.14 0.0010 14.13 0.0006 15.15 0.0009 16.16 0.0008 17.17 0.0009 18.18 0.0006 19.19 0.0003 20.20 0.0003 21.20 0.0003 22.22 0.0004 23.22 0.0002 24.24 0.0007 26.26 0.0003 27.26 0.0001 29.29 0.0003 ) constant bc-a3 #( 1.00 0.1078 2.01 0.0072 3.02 0.0487 4.04 0.0332 5.05 0.0329 6.06 0.0069 7.07 0.0153 8.08 0.0061 9.08 0.0082 10.09 0.0023 11.10 0.0003 12.11 0.0009 13.12 0.0008 14.13 0.0007 15.15 0.0003 16.16 0.0006 17.16 0.0007 18.16 0.0003 19.17 0.0003 20.18 0.0005 21.19 0.0005 22.20 0.0005 23.22 0.0004 24.23 0.0001 26.25 0.0001 27.25 0.0001 28.26 0.0001 ) constant bc-as3 #( 1.01 0.0572 2.02 0.0086 3.03 0.0724 4.04 0.0057 5.04 0.0365 6.05 0.0058 7.06 0.0083 8.07 0.0113 9.08 0.0102 10.09 0.0022 11.10 0.0012 12.11 0.0005 13.11 0.0014 14.12 0.0003 15.13 0.0008 16.14 0.0009 17.15 0.0003 18.16 0.0002 19.17 0.0006 20.18 0.0009 21.19 0.0002 22.19 0.0006 23.20 0.0004 24.21 0.0004 25.22 0.0001 ) constant bc-b3 #( 1.01 0.0509 2.02 0.0146 3.02 0.0344 4.03 0.0126 5.04 0.0254 6.05 0.0004 7.05 0.0134 8.06 0.0069 9.08 0.0007 10.09 0.0005 11.09 0.0006 12.09 0.0004 13.11 0.0010 14.12 0.0001 15.12 0.0008 16.13 0.0001 17.14 0.0003 18.15 0.0002 19.17 0.0001 20.16 0.0004 21.17 0.0002 ) constant bc-c4 #( 1.00 0.1853 2.00 0.0169 3.01 0.0922 4.01 0.0035 5.01 0.0204 6.01 0.0046 7.02 0.0077 8.02 0.0085 9.02 0.0028 10.05 0.0002 11.02 0.0003 12.03 0.0006 13.05 0.0002 14.03 0.0006 15.04 0.0006 16.04 0.0004 17.02 0.0003 18.04 0.0006 19.04 0.0004 20.04 0.0003 21.06 0.0001 22.04 0.0001 23.06 0.0002 ) constant bc-cs4 #( 1.00 0.3391 2.00 0.0134 2.99 0.0186 3.99 0.0424 4.98 0.0122 5.98 0.0055 6.97 0.0197 7.98 0.0034 8.97 0.0017 9.98 0.0004 10.96 0.0008 11.96 0.0009 12.96 0.0003 13.96 0.0007 14.95 0.0004 15.94 0.0002 16.95 0.0003 17.94 0.0008 18.93 0.0002 19.93 0.0001 ) constant bc-d4 #( 0.99 0.3684 1.98 0.0187 2.98 0.0647 3.97 0.0186 4.97 0.0070 5.96 0.0127 6.95 0.0173 7.94 0.0011 8.94 0.0011 9.93 0.0014 10.92 0.0013 11.90 0.0001 12.90 0.0006 13.91 0.0003 14.89 0.0003 15.89 0.0001 16.88 0.0010 17.88 0.0004 18.86 0.0001 19.86 0.0002 20.85 0.0001 ) constant bc-ds4 #( 1.00 0.5390 3.01 0.0188 4.00 0.0247 5.00 0.0129 6.01 0.0050 7.01 0.0014 8.01 0.0012 9.01 0.0012 10.01 0.0010 11.02 0.0005 12.02 0.0002 13.03 0.0004 ) constant bc-e4 #( 1.01 0.5398 2.01 0.0309 3.01 0.0727 4.01 0.0062 5.01 0.0041 6.02 0.0280 7.02 0.0005 8.02 0.0014 9.02 0.0013 10.02 0.0030 11.03 0.0006 12.03 0.0004 14.03 0.0003 15.04 0.0003 16.04 0.0007 ) constant bc-f4 #( 1.00 0.6398 2.01 0.0314 3.01 0.0423 4.01 0.0292 5.01 0.0093 6.02 0.0088 7.02 0.0010 8.03 0.0043 9.02 0.0004 10.03 0.0013 11.03 0.0003 12.04 0.0003 13.02 0.0002 14.04 0.0010 15.04 0.0006 16.05 0.0001 17.04 0.0003 ) constant bc-fs4 #( 1.00 0.5985 1.99 0.0192 2.99 0.0346 3.99 0.0257 4.98 0.0082 5.98 0.0037 6.98 0.0008 7.99 0.0013 8.97 0.0014 9.98 0.0016 10.98 0.0010 11.98 0.0005 12.97 0.0005 13.97 0.0008 14.95 0.0002 15.96 0.0003 ) constant bc-g4 #( 1.00 0.2635 1.99 0.0230 2.99 0.0936 3.99 0.0214 4.99 0.0320 5.99 0.0013 6.99 0.0020 7.99 0.0004 8.99 0.0014 9.99 0.0003 10.99 0.0003 11.98 0.0005 12.98 0.0015 13.98 0.0005 14.98 0.0003 15.98 0.0003 18.98 0.0001 ) constant bc-gs4 #( 1.00 0.1539 2.00 0.0355 3.00 0.0834 4.01 0.0210 5.01 0.0103 6.00 0.0035 7.02 0.0004 8.01 0.0008 9.00 0.0002 10.01 0.0001 11.01 0.0005 12.01 0.0007 13.02 0.0011 14.01 0.0003 15.02 0.0003 18.02 0.0002 ) constant bc-a4 #( 1.00 0.1843 2.01 0.0229 3.00 0.0348 4.01 0.0157 5.01 0.0170 6.01 0.0037 7.02 0.0012 8.02 0.0027 9.02 0.0003 10.02 0.0011 11.03 0.0010 12.03 0.0007 13.03 0.0004 14.03 0.0002 15.03 0.0002 17.04 0.0002 ) constant bc-as4 #( 1.00 0.5063 2.01 0.0563 3.01 0.0376 4.01 0.0383 5.01 0.0135 6.02 0.0081 7.02 0.0011 8.02 0.0049 9.03 0.0007 10.03 0.0006 11.04 0.0013 12.04 0.0007 13.04 0.0004 14.05 0.0002 15.05 0.0002 17.05 0.0002 19.06 0.0001 ) constant bc-b4 #( 1.00 0.5459 2.00 0.0278 3.01 0.0456 4.01 0.0648 5.02 0.0035 6.02 0.0050 7.02 0.0025 8.02 0.0021 9.02 0.0005 10.03 0.0007 11.03 0.0016 12.03 0.0007 13.04 0.0001 14.03 0.0002 15.04 0.0002 18.05 0.0002 19.05 0.0001 20.05 0.0002 ) constant bc-c5 #( 1.00 0.2584 2.01 0.0583 3.02 0.1090 4.02 0.0290 5.02 0.0020 6.03 0.0018 7.03 0.0016 8.03 0.0001 9.04 0.0005 10.05 0.0017 11.05 0.0010 12.05 0.0002 13.06 0.0001 14.06 0.0001 17.08 0.0002 18.08 0.0001 19.08 0.0001 ) constant bc-cs5 #( 1.00 0.1626 2.00 0.0485 3.01 0.0856 4.00 0.0023 5.01 0.0096 6.01 0.0042 7.01 0.0015 8.01 0.0004 9.02 0.0019 10.02 0.0016 11.02 0.0003 12.02 0.0002 13.02 0.0002 16.03 0.0001 17.03 0.0001 18.03 0.0002 19.03 0.0001 ) constant bc-d5 #( 1.00 0.1756 1.99 0.1645 2.99 0.0381 3.98 0.0028 4.98 0.0042 5.98 0.0004 6.97 0.0025 7.97 0.0006 8.96 0.0022 9.96 0.0011 10.96 0.0002 13.94 0.0002 14.94 0.0002 15.94 0.0001 16.93 0.0001 17.93 0.0001 ) constant bc-ds5 #( 0.99 0.2661 1.99 0.1398 2.99 0.0589 3.99 0.0048 4.98 0.0022 5.98 0.0015 6.97 0.0021 7.97 0.0008 8.96 0.0011 9.96 0.0009 10.95 0.0004 11.94 0.0001 13.94 0.0001 14.94 0.0001 15.94 0.0001 ) constant bc-e5 #( 1.00 0.1378 2.00 0.0654 3.00 0.1301 4.00 0.0049 5.00 0.0030 6.01 0.0018 7.01 0.0030 8.01 0.0015 9.01 0.0008 10.01 0.0001 11.01 0.0003 12.01 0.0002 13.01 0.0001 14.01 0.0002 15.01 0.0002 16.02 0.0001 ) constant bc-f5 #( 1.00 0.3952 2.01 0.1124 3.01 0.0326 4.02 0.0104 5.03 0.0013 6.03 0.0010 7.03 0.0009 8.04 0.0009 9.05 0.0002 10.05 0.0003 11.05 0.0001 13.06 0.0002 14.07 0.0003 15.08 0.0002 ) constant bc-fs5 #( 1.01 0.3434 2.01 0.0390 3.02 0.0051 4.03 0.0057 5.04 0.0042 6.05 0.0017 7.06 0.0022 8.06 0.0012 9.07 0.0002 10.07 0.0001 11.08 0.0002 12.09 0.0002 13.10 0.0002 14.11 0.0002 15.12 0.0001 ) constant bc-g5 #( 1.00 0.1109 1.99 0.0911 2.98 0.0061 3.98 0.0062 4.98 0.0020 5.97 0.0006 6.96 0.0008 7.96 0.0013 8.95 0.0002 10.94 0.0002 11.94 0.0002 12.93 0.0002 13.93 0.0001 ) constant bc-gs5 #( 1.00 0.1585 2.00 0.0562 3.00 0.0039 4.00 0.0064 5.00 0.0016 6.00 0.0022 7.00 0.0009 8.00 0.0004 9.00 0.0002 11.00 0.0003 12.00 0.0003 13.00 0.0002 14.00 0.0002 ) constant bc-a5 #( 0.99 0.1211 1.98 0.0394 2.97 0.0093 3.96 0.0024 4.95 0.0030 5.94 0.0027 6.93 0.0006 8.92 0.0002 10.90 0.0001 12.88 0.0001 ) constant bc-as5 \ ********************************************************** \ bassoon \ ********************************************************** #( 1.00 0.0038 2.02 0.0235 3.04 0.0511 4.06 0.0348 5.07 0.0491 6.09 0.0518 7.11 0.0184 8.12 0.0381 9.11 0.1027 10.13 0.0412 11.15 0.0112 12.17 0.0144 13.18 0.0097 14.20 0.0074 15.21 0.0081 16.23 0.0067 17.22 0.0108 18.24 0.0113 19.25 0.0114 20.28 0.0066 21.30 0.0065 22.32 0.0035 23.33 0.0041 24.33 0.0036 25.34 0.0025 26.35 0.0010 27.37 0.0021 28.39 0.0007 29.42 0.0006 30.42 0.0009 31.43 0.0005 32.43 0.0003 33.46 0.0005 34.46 0.0002 35.48 0.0002 36.48 0.0004 37.52 0.0003 38.53 0.0003 39.55 0.0002 40.56 0.0002 51.69 0.0001 54.72 0.0002 ) constant bsn-as1 #( 1.01 0.0039 2.02 0.0230 3.02 0.0517 4.03 0.0473 5.03 0.0443 6.03 0.0691 7.03 0.0664 8.04 0.0408 9.04 0.1283 10.06 0.0429 11.07 0.0339 12.08 0.0223 13.08 0.0207 14.08 0.0256 15.08 0.0171 16.09 0.0106 17.09 0.0136 18.09 0.0082 19.12 0.0052 20.12 0.0041 21.13 0.0015 22.13 0.0023 23.12 0.0021 24.12 0.0009 25.13 0.0029 26.14 0.0014 27.15 0.0003 28.15 0.0010 29.17 0.0013 30.18 0.0003 31.19 0.0005 32.19 0.0007 33.19 0.0004 34.20 0.0005 35.19 0.0005 36.19 0.0003 37.21 0.0003 38.23 0.0002 39.23 0.0001 40.23 0.0001 43.23 0.0001 46.26 0.0002 49.27 0.0002 51.27 0.0003 52.27 0.0002 53.28 0.0002 ) constant bsn-b1 #( 1.01 0.0047 2.03 0.0390 3.04 0.0460 4.04 0.0217 5.05 0.0464 6.05 0.0631 7.06 0.0874 8.07 0.1167 9.08 0.0339 10.09 0.0209 11.11 0.0133 12.12 0.0088 13.11 0.0092 14.14 0.0032 15.15 0.0026 16.16 0.0061 17.17 0.0019 18.17 0.0051 19.18 0.0161 20.18 0.0048 21.20 0.0044 22.21 0.0035 23.23 0.0010 24.24 0.0028 25.25 0.0006 26.26 0.0013 27.27 0.0016 28.26 0.0002 29.28 0.0006 30.28 0.0006 31.30 0.0004 32.32 0.0012 33.33 0.0003 34.34 0.0003 35.35 0.0002 36.34 0.0001 43.41 0.0001 46.43 0.0001 48.44 0.0001 51.48 0.0001 ) constant bsn-c2 #( 1.01 0.0090 2.02 0.0531 3.01 0.0318 4.01 0.0199 5.02 0.0211 6.04 0.0629 7.04 0.1340 8.05 0.0925 9.04 0.0206 10.04 0.0584 11.05 0.0140 12.07 0.0066 13.08 0.0068 14.08 0.0011 15.07 0.0028 16.07 0.0015 17.08 0.0041 18.10 0.0106 19.10 0.0034 20.10 0.0033 21.10 0.0020 22.10 0.0021 23.11 0.0040 24.13 0.0001 25.12 0.0004 26.13 0.0003 28.13 0.0004 29.14 0.0002 30.16 0.0001 31.17 0.0001 43.20 0.0001 46.22 0.0002 ) constant bsn-cs2 #( 1.01 0.0616 2.00 0.0436 3.00 0.0430 3.99 0.0491 5.01 0.0358 6.01 0.1695 7.00 0.1562 7.99 0.0174 8.99 0.0062 10.01 0.0054 11.00 0.0104 12.00 0.0055 12.99 0.0052 13.99 0.0018 15.00 0.0021 16.00 0.0019 16.99 0.0087 17.98 0.0025 18.99 0.0027 20.00 0.0015 21.00 0.0024 21.98 0.0015 22.99 0.0002 24.00 0.0006 25.99 0.0001 26.95 0.0001 28.00 0.0001 28.94 0.0001 30.01 0.0002 ) constant bsn-d2 #( 1.01 0.0769 2.01 0.0341 3.00 0.0240 4.00 0.0633 5.00 0.0124 5.99 0.0850 6.99 0.1044 7.99 0.0115 8.99 0.0046 10.00 0.0048 11.00 0.0054 12.00 0.0082 13.00 0.0033 14.00 0.0080 15.00 0.0022 15.99 0.0081 16.99 0.0028 17.98 0.0038 18.98 0.0028 19.99 0.0032 20.99 0.0007 22.00 0.0003 22.98 0.0004 23.99 0.0001 24.98 0.0005 25.98 0.0002 26.97 0.0003 28.98 0.0001 38.97 0.0001 40.97 0.0001 ) constant bsn-ds2 #( 1.00 0.0369 1.98 0.0190 3.00 0.0291 3.98 0.0844 5.00 0.0730 5.98 0.0856 7.00 0.0563 7.98 0.0792 9.00 0.0139 9.97 0.0127 10.99 0.0046 11.96 0.0052 12.99 0.0043 13.97 0.0030 14.99 0.0102 15.98 0.0020 16.97 0.0029 17.98 0.0010 18.96 0.0040 19.98 0.0008 20.97 0.0004 21.99 0.0001 23.98 0.0004 25.96 0.0002 26.93 0.0001 36.94 0.0001 ) constant bsn-e2 #( 0.99 0.0208 2.00 0.0164 3.01 0.0576 4.02 0.0547 5.02 0.0965 5.99 0.1701 7.00 0.0206 8.01 0.0040 9.02 0.0075 10.02 0.0033 11.00 0.0067 12.00 0.0021 13.01 0.0010 14.02 0.0072 15.03 0.0014 16.01 0.0028 17.01 0.0034 18.02 0.0026 19.03 0.0007 20.05 0.0004 20.43 0.0001 22.02 0.0001 24.01 0.0003 26.03 0.0001 ) constant bsn-f2 #( 1.00 0.0112 1.99 0.0211 2.98 0.0379 3.97 0.0630 4.98 0.0727 5.97 0.1555 6.95 0.0348 7.94 0.0362 8.96 0.0083 9.94 0.0145 10.92 0.0070 11.91 0.0031 12.93 0.0059 13.92 0.0054 14.91 0.0024 15.89 0.0024 16.88 0.0045 17.90 0.0013 18.91 0.0007 19.87 0.0005 20.87 0.0004 21.88 0.0002 22.85 0.0007 23.84 0.0003 24.83 0.0002 26.84 0.0001 28.80 0.0002 29.80 0.0001 30.81 0.0003 31.81 0.0001 32.78 0.0003 33.77 0.0001 34.79 0.0002 ) constant bsn-fs2 #( 0.98 0.0330 1.99 0.0314 2.95 0.0487 3.95 0.0272 4.95 0.2864 5.91 0.0849 6.92 0.0047 7.89 0.0049 8.88 0.0015 9.88 0.0060 10.85 0.0051 11.85 0.0013 12.83 0.0083 13.82 0.0018 14.82 0.0010 15.78 0.0032 16.79 0.0007 17.77 0.0004 18.76 0.0005 19.76 0.0008 20.72 0.0004 21.72 0.0009 22.72 0.0003 23.69 0.0002 ) constant bsn-g2 #( 0.98 0.0321 1.98 0.0281 2.99 0.0196 3.99 0.0683 4.96 0.2698 5.95 0.0125 6.95 0.0153 7.96 0.0034 8.96 0.0050 9.93 0.0056 10.92 0.0049 11.92 0.0160 12.92 0.0072 13.91 0.0013 14.89 0.0028 15.91 0.0005 16.86 0.0004 17.89 0.0006 18.89 0.0009 19.87 0.0005 20.85 0.0001 21.87 0.0003 27.83 0.0001 28.82 0.0002 ) constant bsn-gs2 #( 0.99 0.0170 2.00 0.0296 3.00 0.0324 4.01 0.1542 5.02 0.1393 6.02 0.0249 7.03 0.0041 8.03 0.0022 9.01 0.0043 10.02 0.0077 11.03 0.0092 12.04 0.0021 13.04 0.0027 14.05 0.0026 15.06 0.0007 16.05 0.0001 17.05 0.0003 18.04 0.0006 19.04 0.0004 20.05 0.0002 26.06 0.0003 27.06 0.0002 29.07 0.0001 ) constant bsn-a2 #( 1.01 0.0153 2.00 0.0261 3.00 0.0305 3.99 0.1573 4.97 0.0908 5.98 0.0053 6.97 0.0054 7.98 0.0159 8.99 0.0031 9.99 0.0015 10.96 0.0124 11.96 0.0020 12.95 0.0026 13.94 0.0034 14.94 0.0005 16.95 0.0007 17.93 0.0002 18.94 0.0003 24.92 0.0002 25.91 0.0002 27.89 0.0002 28.89 0.0001 ) constant bsn-as2 #( 1.01 0.0061 2.00 0.0199 2.99 0.0393 3.98 0.2060 5.00 0.0178 5.99 0.0340 6.98 0.0029 7.98 0.0065 8.99 0.0102 9.99 0.0271 10.98 0.0068 11.97 0.0032 12.97 0.0060 13.99 0.0002 14.98 0.0005 15.96 0.0008 16.96 0.0008 17.98 0.0006 18.98 0.0001 21.96 0.0001 22.96 0.0002 23.95 0.0002 24.94 0.0002 25.94 0.0001 26.95 0.0001 28.95 0.0001 ) constant bsn-b2 #( 1.00 0.0082 1.98 0.0489 2.99 0.1248 3.98 0.1892 4.97 0.0149 5.98 0.0017 6.96 0.0172 7.95 0.0072 8.96 0.0028 9.95 0.0114 10.93 0.0055 11.94 0.0029 12.96 0.0005 13.92 0.0017 14.93 0.0008 15.91 0.0012 16.90 0.0005 17.91 0.0001 20.90 0.0001 21.88 0.0003 22.87 0.0001 24.85 0.0002 28.85 0.0001 ) constant bsn-c3 #( 1.01 0.0191 2.00 0.0451 2.99 0.2847 4.00 0.0925 5.00 0.0143 5.99 0.0024 7.00 0.0055 8.00 0.0131 8.99 0.0286 9.98 0.0021 10.99 0.0020 11.99 0.0010 12.96 0.0003 13.97 0.0005 14.98 0.0009 15.97 0.0005 20.97 0.0003 21.97 0.0003 ) constant bsn-cs3 #( 1.01 0.0218 2.01 0.0560 3.01 0.1696 4.01 0.0504 5.00 0.0268 6.02 0.0018 7.03 0.0081 8.03 0.0035 9.04 0.0026 10.04 0.0023 11.02 0.0045 12.04 0.0002 13.04 0.0004 14.04 0.0007 15.05 0.0004 16.06 0.0001 21.06 0.0001 22.07 0.0003 ) constant bsn-d3 #( 1.00 0.0185 1.99 0.0627 2.98 0.2037 3.97 0.0211 4.98 0.0204 5.97 0.0434 6.95 0.0056 7.94 0.0171 8.95 0.0014 9.94 0.0062 10.93 0.0007 11.91 0.0006 12.91 0.0004 13.90 0.0004 14.90 0.0003 16.88 0.0001 17.89 0.0002 18.88 0.0002 20.86 0.0004 21.84 0.0002 22.85 0.0001 ) constant bsn-ds3 #( 1.00 0.0167 2.00 0.0801 3.01 0.2223 4.02 0.0252 5.02 0.0098 6.01 0.0058 7.02 0.0073 8.03 0.0032 9.03 0.0066 10.04 0.0011 10.66 0.0001 12.04 0.0013 13.04 0.0013 14.05 0.0010 15.05 0.0004 18.07 0.0002 20.06 0.0003 23.07 0.0001 ) constant bsn-e3 #( 1.00 0.0152 2.01 0.0471 3.00 0.1985 4.00 0.0345 5.01 0.0136 6.00 0.0064 7.01 0.0153 8.00 0.0011 9.00 0.0093 10.02 0.0006 11.01 0.0006 12.00 0.0001 13.01 0.0008 14.01 0.0006 16.02 0.0001 17.01 0.0003 19.01 0.0002 22.01 0.0001 23.02 0.0002 ) constant bsn-f3 #( 1.01 0.0363 2.01 0.1019 3.01 0.3226 4.01 0.1274 5.03 0.0397 6.03 0.0061 7.02 0.0117 8.03 0.0099 9.04 0.0006 10.04 0.0026 11.04 0.0020 12.04 0.0008 13.05 0.0001 14.06 0.0002 15.05 0.0002 19.07 0.0002 ) constant bsn-fs3 #( 0.99 0.0358 1.99 0.0535 2.99 0.1072 3.99 0.0270 4.99 0.0106 5.98 0.0010 6.97 0.0007 7.97 0.0041 8.95 0.0002 9.94 0.0002 10.97 0.0002 12.96 0.0001 ) constant bsn-g3 #( 1.00 0.0382 1.99 0.0923 2.99 0.0199 3.99 0.0156 4.96 0.0044 5.98 0.0130 6.97 0.0020 7.97 0.0033 8.97 0.0007 9.95 0.0002 10.95 0.0001 12.95 0.0001 ) constant bsn-gs3 #( 1.00 0.0469 2.00 0.2187 3.00 0.0287 4.01 0.0121 5.01 0.0114 6.01 0.0022 7.01 0.0044 8.02 0.0008 9.02 0.0004 10.01 0.0003 13.02 0.0001 ) constant bsn-a3 #( 1.01 0.0298 2.01 0.2016 3.02 0.0058 4.00 0.0258 5.00 0.0008 6.00 0.0029 7.00 0.0031 8.01 0.0010 9.01 0.0004 10.00 0.0001 13.01 0.0001 ) constant bsn-as3 #( 1.01 0.0341 2.01 0.2100 3.01 0.0390 4.02 0.0044 5.02 0.0213 6.02 0.0044 7.02 0.0006 8.03 0.0012 9.04 0.0002 12.05 0.0002 13.05 0.0002 ) constant bsn-b3 #( 1.00 0.0684 2.00 0.2934 3.00 0.0096 4.00 0.0084 5.00 0.0039 6.00 0.0059 7.00 0.0010 8.00 0.0006 ) constant bsn-c4 #( 1.01 0.0848 2.01 0.3334 3.02 0.0152 4.03 0.0032 5.03 0.0059 6.03 0.0032 7.05 0.0013 8.05 0.0007 9.05 0.0001 10.06 0.0001 11.06 0.0002 ) constant bsn-cs4 #( 1.00 0.1020 2.00 0.1065 3.00 0.0086 3.99 0.0013 5.00 0.0038 6.00 0.0011 7.00 0.0003 8.00 0.0002 11.01 0.0003 ) constant bsn-d4 #( 1.00 0.0469 1.99 0.0248 2.96 0.0045 3.99 0.0163 4.99 0.0042 6.00 0.0004 6.98 0.0003 ) constant bsn-ds4 #( 1.00 0.0389 2.01 0.0439 3.01 0.0110 4.01 0.0072 5.02 0.0041 6.02 0.0005 7.02 0.0006 9.03 0.0003 ) constant bsn-e4 #( 1.00 0.0229 2.00 0.0331 2.99 0.0138 4.00 0.0008 4.99 0.0010 5.99 0.0004 ) constant bsn-f4 #( 1.00 0.1522 1.99 0.0563 3.00 0.0126 3.99 0.0035 4.28 0.0002 4.35 0.0002 4.43 0.0001 4.98 0.0001 5.99 0.0001 6.98 0.0002 ) constant bsn-fs4 #( 1.00 0.0415 2.00 0.0486 3.00 0.0068 4.00 0.0148 5.00 0.0016 6.00 0.0001 ) constant bsn-g4 #( 1.01 0.0811 2.01 0.0402 3.03 0.0114 4.04 0.0044 5.03 0.0004 ) constant bsn-gs4 #( 1.00 0.0399 2.01 0.0195 3.00 0.0069 4.01 0.0005 5.01 0.0009 6.01 0.0002 7.01 0.0003 ) constant bsn-a4 #( 1.01 0.1259 2.01 0.0811 3.01 0.0051 4.01 0.0027 5.01 0.0008 6.02 0.0002 7.02 0.0003 ) constant bsn-as4 #( 1.01 0.1159 2.02 0.0380 3.03 0.0089 4.04 0.0038 5.05 0.0006 6.05 0.0002 ) constant bsn-b4 #( 1.02 0.0871 2.03 0.0356 3.04 0.0192 4.06 0.0063 6.09 0.0003 7.11 0.0002 ) constant bsn-c5 #( 1.01 0.2418 2.02 0.0674 3.02 0.0067 4.03 0.0021 5.03 0.0004 6.05 0.0003 7.05 0.0005 8.06 0.0001 ) constant bsn-cs5 #( 1.01 0.1931 2.01 0.0462 3.02 0.0118 4.02 0.0014 5.03 0.0006 6.03 0.0008 8.04 0.0001 ) constant bsn-d5 \ ********************************************************** \ cello \ ********************************************************** #( 1.00 0.0047 1.99 0.0251 2.99 0.0546 4.01 0.1041 4.99 0.0279 5.97 0.0219 6.93 0.0137 7.94 0.0349 8.91 0.0151 10.04 0.0565 11.00 0.0458 12.00 0.0216 12.97 0.0151 14.52 0.0025 14.95 0.0088 16.03 0.0103 17.02 0.0027 17.98 0.0089 19.00 0.0052 20.03 0.0048 20.93 0.0051 22.04 0.0023 23.01 0.0072 24.01 0.0022 24.99 0.0027 26.03 0.0036 27.47 0.0011 27.99 0.0011 29.02 0.0012 29.86 0.0005 30.97 0.0020 31.88 0.0006 33.02 0.0021 33.98 0.0011 35.02 0.0010 36.01 0.0028 37.00 0.0022 37.99 0.0014 39.00 0.0014 40.01 0.0022 41.04 0.0021 42.02 0.0008 43.01 0.0024 44.02 0.0007 45.01 0.0003 46.00 0.0002 48.03 0.0002 48.85 0.0002 51.01 0.0001 51.98 0.0001 54.89 0.0002 55.39 0.0002 56.38 0.0001 58.02 0.0002 58.98 0.0002 62.00 0.0001 64.09 0.0001 65.02 0.0002 ) constant c-c2 #( 1.01 0.0160 2.02 0.0737 3.02 0.0287 4.02 0.0183 5.02 0.0669 6.04 0.0520 7.05 0.0043 8.06 0.0066 9.06 0.0194 10.05 0.0193 11.05 0.0254 12.06 0.0153 13.08 0.0041 14.11 0.0037 15.09 0.0098 16.09 0.0022 17.09 0.0053 18.10 0.0135 19.12 0.0118 20.13 0.0057 21.15 0.0039 22.14 0.0023 23.14 0.0027 24.15 0.0026 25.16 0.0012 26.16 0.0011 27.17 0.0020 28.17 0.0015 29.14 0.0020 30.19 0.0013 31.19 0.0019 32.20 0.0007 33.21 0.0005 34.22 0.0004 35.19 0.0012 36.20 0.0005 37.25 0.0015 38.25 0.0018 39.26 0.0014 40.40 0.0007 41.25 0.0010 42.24 0.0009 43.28 0.0003 44.31 0.0002 45.28 0.0002 46.30 0.0001 48.29 0.0002 49.31 0.0004 50.34 0.0001 51.35 0.0002 52.32 0.0003 53.50 0.0001 54.28 0.0001 57.34 0.0001 58.35 0.0002 ) constant c-cs2 #( 1.00 0.0368 2.02 0.1070 3.03 0.0107 4.04 0.0445 5.04 0.0477 6.04 0.0281 7.07 0.0191 8.06 0.0205 9.06 0.0456 10.07 0.0283 11.07 0.0320 12.08 0.0094 13.35 0.0009 14.11 0.0042 15.11 0.0066 16.12 0.0075 17.13 0.0117 18.14 0.0043 19.16 0.0067 20.14 0.0020 21.16 0.0046 22.16 0.0011 23.17 0.0029 24.17 0.0010 25.18 0.0011 26.19 0.0013 27.18 0.0029 28.20 0.0039 29.21 0.0048 30.23 0.0020 31.23 0.0006 32.25 0.0018 33.23 0.0009 34.24 0.0012 35.28 0.0016 36.27 0.0018 37.28 0.0019 38.28 0.0031 39.28 0.0008 40.25 0.0001 41.30 0.0002 42.31 0.0002 43.32 0.0001 44.32 0.0002 45.33 0.0002 46.34 0.0004 48.37 0.0002 49.37 0.0006 50.37 0.0004 51.35 0.0001 52.35 0.0001 53.40 0.0001 54.39 0.0002 55.41 0.0003 56.43 0.0002 57.41 0.0001 64.49 0.0001 65.50 0.0001 ) constant c-d2 #( 1.01 0.0485 2.01 0.1800 3.01 0.0143 4.02 0.1265 5.03 0.1372 6.03 0.0102 7.02 0.0261 8.03 0.0216 9.02 0.0145 10.04 0.0292 11.05 0.0133 12.06 0.0038 13.06 0.0026 14.04 0.0041 15.06 0.0053 16.06 0.0014 17.08 0.0051 18.06 0.0048 19.07 0.0026 20.07 0.0025 21.09 0.0039 22.08 0.0018 23.08 0.0031 24.11 0.0023 25.10 0.0035 26.10 0.0037 27.10 0.0019 28.10 0.0030 29.11 0.0020 30.10 0.0036 31.13 0.0020 32.10 0.0011 33.13 0.0013 34.12 0.0027 35.11 0.0022 36.13 0.0018 37.15 0.0005 38.13 0.0002 39.17 0.0002 40.16 0.0006 41.13 0.0002 43.16 0.0002 44.16 0.0002 45.15 0.0002 46.18 0.0003 47.17 0.0001 48.18 0.0001 49.16 0.0002 50.19 0.0001 58.35 0.0001 ) constant c-ds2 #( 1.02 0.0293 2.00 0.1425 3.04 0.0549 4.03 0.0364 5.03 0.1171 6.07 0.0100 7.04 0.0253 8.06 0.0448 9.08 0.0115 10.06 0.0116 11.08 0.0048 12.09 0.0174 13.09 0.0037 14.11 0.0029 15.11 0.0104 16.12 0.0036 17.14 0.0046 18.13 0.0016 19.16 0.0027 20.13 0.0036 21.14 0.0012 22.18 0.0027 23.17 0.0011 24.18 0.0033 25.20 0.0019 26.20 0.0016 26.99 0.0005 28.22 0.0009 29.19 0.0052 30.23 0.0021 31.21 0.0015 32.24 0.0014 33.23 0.0019 34.22 0.0033 35.27 0.0009 36.27 0.0002 38.30 0.0004 39.27 0.0005 40.26 0.0004 41.25 0.0003 42.31 0.0002 43.34 0.0007 44.32 0.0006 45.32 0.0003 46.36 0.0002 47.36 0.0001 48.34 0.0002 49.37 0.0002 54.40 0.0002 55.40 0.0001 ) constant c-e2 #( 0.99 0.0765 2.00 0.0311 3.02 0.0635 4.02 0.0223 5.15 0.0022 6.01 0.0457 7.03 0.0278 8.04 0.0188 9.04 0.0344 10.02 0.0093 11.00 0.0034 12.05 0.0172 13.06 0.0106 14.07 0.0020 15.02 0.0011 16.06 0.0022 17.08 0.0027 18.08 0.0007 19.05 0.0016 20.07 0.0015 21.07 0.0057 22.10 0.0010 23.07 0.0030 24.07 0.0013 25.07 0.0019 26.09 0.0018 27.10 0.0042 28.10 0.0020 29.09 0.0015 30.12 0.0027 31.11 0.0021 32.13 0.0035 33.08 0.0003 34.12 0.0005 35.12 0.0004 36.15 0.0008 37.15 0.0003 39.14 0.0005 40.17 0.0003 41.15 0.0003 42.14 0.0002 43.14 0.0001 44.17 0.0002 51.84 0.0001 53.18 0.0001 54.22 0.0001 ) constant c-f2 #( 1.02 0.0680 2.02 0.0790 3.03 0.0722 4.03 0.0851 5.03 0.0169 6.03 0.0073 7.02 0.0859 8.02 0.0250 9.04 0.0073 10.07 0.0037 11.04 0.0035 12.01 0.0009 13.09 0.0056 14.05 0.0059 15.05 0.0031 16.07 0.0050 17.07 0.0034 18.07 0.0010 19.47 0.0004 20.10 0.0045 21.10 0.0028 22.09 0.0039 23.10 0.0032 24.11 0.0007 25.09 0.0017 26.10 0.0041 27.16 0.0006 28.12 0.0021 29.13 0.0021 30.39 0.0004 31.11 0.0013 32.17 0.0004 33.13 0.0005 34.14 0.0014 35.07 0.0002 36.06 0.0001 37.16 0.0002 39.18 0.0007 40.18 0.0002 41.22 0.0001 42.21 0.0002 43.24 0.0003 49.15 0.0001 51.22 0.0001 52.23 0.0002 ) constant c-fs2 #( 1.00 0.0434 2.00 0.0983 2.99 0.0548 3.98 0.0364 4.98 0.0228 5.97 0.0390 6.97 0.0091 7.96 0.0154 9.03 0.0078 9.96 0.0174 10.98 0.0110 11.96 0.0125 12.97 0.0039 13.94 0.0028 14.95 0.0057 15.94 0.0020 16.95 0.0046 17.94 0.0011 18.97 0.0017 19.94 0.0010 20.98 0.0025 21.94 0.0040 22.94 0.0030 23.91 0.0064 24.95 0.0013 25.96 0.0009 26.94 0.0015 27.92 0.0014 28.93 0.0017 29.91 0.0015 30.92 0.0010 31.49 0.0002 32.83 0.0002 33.89 0.0003 34.92 0.0002 36.91 0.0003 37.91 0.0002 40.84 0.0002 41.87 0.0002 42.89 0.0002 ) constant c-g2 #( 0.98 0.0579 1.97 0.0445 2.97 0.1178 3.97 0.0806 4.96 0.1095 5.94 0.0245 6.92 0.0203 7.91 0.0153 8.92 0.0186 9.93 0.0129 10.92 0.0154 11.89 0.0040 12.87 0.0036 13.88 0.0033 14.74 0.0006 15.85 0.0011 16.86 0.0020 17.85 0.0026 18.84 0.0040 19.84 0.0022 20.83 0.0022 21.82 0.0020 22.80 0.0060 23.79 0.0073 24.81 0.0023 25.80 0.0030 26.79 0.0008 27.77 0.0005 28.75 0.0012 29.73 0.0017 30.75 0.0003 31.74 0.0005 32.74 0.0003 33.71 0.0003 34.70 0.0005 35.72 0.0002 36.67 0.0003 38.69 0.0002 39.71 0.0002 40.65 0.0001 ) constant c-gs2 #( 0.99 0.0612 1.98 0.0094 2.98 0.0435 3.98 0.0098 4.97 0.0550 5.97 0.0775 6.96 0.0337 7.96 0.0330 8.97 0.0137 9.95 0.0122 10.95 0.0080 11.94 0.0082 13.00 0.0009 13.95 0.0034 14.96 0.0029 15.94 0.0011 16.94 0.0041 17.95 0.0060 18.92 0.0008 19.97 0.0026 20.94 0.0009 21.94 0.0041 22.92 0.0050 23.92 0.0056 24.93 0.0030 25.92 0.0015 26.22 0.0002 27.90 0.0011 28.90 0.0004 29.89 0.0007 30.89 0.0009 31.90 0.0004 32.91 0.0002 33.88 0.0005 34.86 0.0001 35.89 0.0003 36.87 0.0006 37.89 0.0003 38.93 0.0002 46.84 0.0001 54.82 0.0001 ) constant c-a2 #( 1.00 0.0401 1.99 0.0101 2.98 0.0769 3.96 0.0345 4.96 0.0696 5.97 0.0342 6.95 0.0413 7.95 0.0130 8.92 0.0147 9.93 0.0034 10.94 0.0135 11.94 0.0007 12.92 0.0013 13.91 0.0017 14.89 0.0026 15.88 0.0019 16.89 0.0039 17.88 0.0034 18.86 0.0037 19.84 0.0009 20.85 0.0021 21.86 0.0021 22.85 0.0049 23.82 0.0042 24.82 0.0007 25.80 0.0007 26.82 0.0003 27.81 0.0004 28.79 0.0009 29.79 0.0007 30.77 0.0005 31.18 0.0001 31.66 0.0001 32.76 0.0002 33.78 0.0002 34.76 0.0004 35.75 0.0002 36.74 0.0002 ) constant c-as2 #( 1.00 0.0486 1.99 0.0621 2.98 0.0627 3.98 0.0145 4.98 0.0494 5.97 0.0353 6.96 0.0287 7.96 0.0169 8.95 0.0167 9.95 0.0039 10.94 0.0075 11.94 0.0043 12.95 0.0018 13.92 0.0040 14.94 0.0054 15.93 0.0046 16.93 0.0035 17.92 0.0037 18.93 0.0036 19.91 0.0055 20.89 0.0055 21.89 0.0058 22.89 0.0039 23.88 0.0005 24.87 0.0009 25.87 0.0003 26.87 0.0007 27.78 0.0002 28.86 0.0004 29.86 0.0004 30.85 0.0004 31.86 0.0001 32.83 0.0009 33.83 0.0003 34.82 0.0001 37.81 0.0002 43.79 0.0001 48.71 0.0001 ) constant c-b2 #( 0.99 0.0486 1.98 0.1268 2.99 0.0920 3.98 0.0752 4.96 0.1515 5.95 0.0086 6.97 0.0102 7.95 0.0108 8.95 0.0120 9.94 0.0034 10.95 0.0029 11.94 0.0007 12.91 0.0029 13.92 0.0077 14.90 0.0028 15.89 0.0027 16.90 0.0038 17.92 0.0034 18.87 0.0115 19.89 0.0039 20.89 0.0023 21.86 0.0023 22.88 0.0008 23.88 0.0006 24.86 0.0004 26.05 0.0002 26.84 0.0003 27.84 0.0005 28.84 0.0003 29.80 0.0004 30.82 0.0007 31.58 0.0001 31.79 0.0001 32.52 0.0001 33.80 0.0001 34.80 0.0001 39.78 0.0002 ) constant c-c3 #( 1.01 0.0839 1.99 0.0414 2.99 0.1265 4.00 0.0196 5.00 0.0377 6.00 0.0117 6.99 0.0111 8.00 0.0151 9.00 0.0207 9.98 0.0033 10.99 0.0090 11.99 0.0039 13.00 0.0039 14.01 0.0031 14.99 0.0038 16.02 0.0023 17.00 0.0026 17.98 0.0069 19.00 0.0020 20.01 0.0017 21.02 0.0007 22.02 0.0006 22.22 0.0002 22.93 0.0001 24.05 0.0003 25.04 0.0002 25.99 0.0003 27.00 0.0003 29.03 0.0003 ) constant c-cs3 #( 1.01 0.1033 2.00 0.0588 3.00 0.0184 4.00 0.0725 5.00 0.0720 6.01 0.0251 7.01 0.0292 8.02 0.0069 9.00 0.0094 10.00 0.0159 11.02 0.0134 12.00 0.0008 13.01 0.0053 14.01 0.0204 15.01 0.0122 16.02 0.0024 17.03 0.0044 18.02 0.0069 19.03 0.0043 20.01 0.0024 21.02 0.0020 22.03 0.0006 23.03 0.0005 24.02 0.0006 25.01 0.0011 26.01 0.0006 27.03 0.0007 28.04 0.0005 29.04 0.0003 30.02 0.0001 31.03 0.0002 32.04 0.0003 36.02 0.0002 38.03 0.0001 39.06 0.0002 40.01 0.0002 42.09 0.0001 43.08 0.0001 44.05 0.0002 ) constant c-d3 #( 1.01 0.1622 2.01 0.1721 3.02 0.0068 4.02 0.0256 5.03 0.0568 6.02 0.0438 7.03 0.0061 8.04 0.0086 9.04 0.0050 10.06 0.0045 11.07 0.0012 12.10 0.0025 13.08 0.0028 14.11 0.0014 15.07 0.0060 16.07 0.0014 17.13 0.0026 18.08 0.0015 19.13 0.0007 20.13 0.0003 21.15 0.0003 22.06 0.0004 23.10 0.0002 24.15 0.0001 25.12 0.0001 26.16 0.0002 27.20 0.0001 ) constant c-ds3 #( 1.00 0.1620 2.01 0.0201 3.01 0.0224 4.02 0.0903 5.03 0.0425 6.01 0.0323 7.02 0.0089 8.11 0.0023 9.02 0.0050 10.03 0.0055 11.05 0.0038 12.04 0.0099 13.04 0.0062 14.03 0.0027 15.06 0.0040 16.07 0.0035 17.07 0.0089 18.06 0.0013 19.05 0.0012 20.08 0.0004 21.06 0.0008 22.09 0.0002 23.08 0.0008 24.09 0.0005 25.08 0.0006 26.65 0.0001 27.13 0.0001 29.10 0.0002 30.10 0.0001 31.10 0.0002 32.11 0.0001 35.12 0.0003 36.10 0.0002 37.15 0.0003 38.17 0.0001 ) constant c-e3 #( 0.99 0.0412 1.99 0.0398 2.99 0.1009 3.99 0.0605 4.97 0.0481 5.96 0.0358 6.96 0.0065 7.83 0.0052 7.97 0.0050 8.95 0.0042 9.94 0.0038 10.95 0.0044 11.94 0.0120 12.93 0.0044 13.92 0.0074 14.92 0.0037 15.92 0.0030 16.92 0.0017 17.90 0.0021 18.90 0.0016 19.89 0.0016 20.89 0.0002 22.86 0.0013 23.87 0.0014 24.87 0.0006 25.86 0.0003 26.88 0.0001 29.84 0.0004 30.83 0.0002 31.82 0.0001 32.83 0.0001 33.81 0.0001 34.81 0.0002 35.82 0.0003 37.80 0.0002 ) constant c-f3 #( 1.00 0.0386 2.00 0.0915 3.00 0.0406 4.01 0.0601 5.00 0.0460 5.99 0.0213 7.01 0.0148 8.00 0.0085 9.00 0.0073 10.00 0.0017 11.01 0.0191 12.00 0.0069 13.00 0.0057 14.02 0.0023 15.01 0.0059 16.00 0.0010 17.02 0.0006 18.01 0.0019 19.00 0.0012 20.02 0.0002 20.99 0.0004 22.01 0.0013 23.02 0.0007 24.02 0.0002 24.94 0.0001 27.03 0.0001 28.02 0.0002 29.00 0.0001 31.01 0.0001 32.01 0.0001 33.02 0.0003 34.03 0.0002 ) constant c-fs3 #( 1.01 0.0124 1.99 0.0359 2.98 0.0602 3.98 0.0390 4.98 0.0496 5.98 0.0070 6.98 0.0121 7.97 0.0089 8.97 0.0044 9.97 0.0068 10.97 0.0085 11.96 0.0110 12.95 0.0034 13.95 0.0099 14.95 0.0059 15.95 0.0003 16.94 0.0014 17.94 0.0005 18.94 0.0008 19.95 0.0004 20.94 0.0007 21.39 0.0001 22.95 0.0002 24.93 0.0001 25.92 0.0002 27.91 0.0001 29.91 0.0005 30.94 0.0001 31.93 0.0002 33.90 0.0001 ) constant c-g3 #( 1.00 0.0509 1.99 0.1477 3.00 0.0407 4.00 0.0514 5.00 0.0367 6.00 0.0032 7.02 0.0097 8.00 0.0090 9.07 0.0009 10.03 0.0069 10.99 0.0020 12.03 0.0010 13.02 0.0019 14.06 0.0010 15.02 0.0010 16.03 0.0008 17.03 0.0003 18.05 0.0002 18.98 0.0004 20.09 0.0002 21.03 0.0001 28.01 0.0001 ) constant c-gs3 #( 1.00 0.0110 2.01 0.0315 3.02 0.1476 4.03 0.0358 5.01 0.0391 6.02 0.0638 7.03 0.0692 8.02 0.0039 9.04 0.0218 10.04 0.0342 11.05 0.0335 12.04 0.0187 13.05 0.0167 14.06 0.0168 15.06 0.0035 16.07 0.0019 17.07 0.0014 18.08 0.0040 19.07 0.0070 20.08 0.0014 21.09 0.0015 22.08 0.0003 23.10 0.0003 24.08 0.0011 25.10 0.0003 26.12 0.0013 27.13 0.0009 28.13 0.0006 29.12 0.0003 30.11 0.0002 31.13 0.0002 33.15 0.0002 34.13 0.0001 36.15 0.0001 41.16 0.0002 44.18 0.0001 47.17 0.0001 ) constant c-a3 #( 1.00 0.0140 2.00 0.0411 3.00 0.0723 4.00 0.1057 5.00 0.0044 6.00 0.0248 6.98 0.0048 8.00 0.0014 9.00 0.0304 9.99 0.0184 10.99 0.0130 12.00 0.0159 13.00 0.0107 13.99 0.0021 15.00 0.0015 15.99 0.0020 17.00 0.0028 18.00 0.0067 19.00 0.0005 20.04 0.0003 21.00 0.0003 22.02 0.0001 23.98 0.0003 25.01 0.0007 26.01 0.0009 27.00 0.0003 28.02 0.0002 28.98 0.0002 30.00 0.0002 31.01 0.0002 32.01 0.0002 32.99 0.0003 33.99 0.0001 35.02 0.0002 37.00 0.0002 38.98 0.0003 43.98 0.0001 44.99 0.0001 ) constant c-as3 #( 1.00 0.0648 2.00 0.0397 3.00 0.0872 4.01 0.0429 5.00 0.0213 6.01 0.0524 7.00 0.0064 8.03 0.0162 9.02 0.0212 10.01 0.0175 11.02 0.0256 12.03 0.0038 13.03 0.0039 14.04 0.0056 15.03 0.0008 16.08 0.0005 17.03 0.0032 18.04 0.0010 19.04 0.0011 20.04 0.0002 21.06 0.0010 22.05 0.0002 23.08 0.0011 24.09 0.0005 25.12 0.0003 26.07 0.0002 27.03 0.0001 39.10 0.0002 ) constant c-b3 #( 1.00 0.0472 2.00 0.1961 3.00 0.1030 4.00 0.0974 5.00 0.0183 6.00 0.0397 7.00 0.0158 8.00 0.0170 8.99 0.0253 10.00 0.0129 10.99 0.0121 11.99 0.0103 12.98 0.0055 14.03 0.0004 14.99 0.0012 15.99 0.0051 16.99 0.0009 17.99 0.0012 19.00 0.0004 19.98 0.0015 21.02 0.0002 22.00 0.0009 22.99 0.0007 24.01 0.0004 25.00 0.0002 26.00 0.0003 28.00 0.0002 28.97 0.0002 31.00 0.0002 32.98 0.0003 33.98 0.0001 34.97 0.0001 35.98 0.0002 37.97 0.0002 38.97 0.0001 ) constant c-c4 #( 1.00 0.1199 2.00 0.0345 3.01 0.0978 4.00 0.0466 5.02 0.0070 6.01 0.0258 7.02 0.0241 8.01 0.0070 9.02 0.0161 10.02 0.0124 11.02 0.0145 12.02 0.0101 13.02 0.0026 14.03 0.0011 15.02 0.0028 16.03 0.0011 17.04 0.0005 18.02 0.0003 19.05 0.0012 20.07 0.0004 21.06 0.0011 22.06 0.0007 23.04 0.0007 24.05 0.0005 26.07 0.0003 27.04 0.0002 28.05 0.0002 29.06 0.0001 32.05 0.0001 33.06 0.0002 35.07 0.0002 36.07 0.0001 37.07 0.0002 ) constant c-cs4 #( 1.00 0.0657 2.00 0.0681 3.00 0.1031 3.99 0.0157 4.99 0.0570 5.98 0.0160 6.99 0.0236 7.98 0.0259 8.99 0.0144 9.98 0.0154 10.98 0.0046 11.97 0.0104 12.98 0.0024 13.97 0.0020 14.97 0.0012 15.97 0.0010 16.97 0.0004 17.95 0.0008 18.97 0.0005 19.98 0.0007 20.98 0.0009 21.93 0.0004 22.00 0.0003 22.94 0.0002 23.95 0.0002 24.98 0.0001 25.97 0.0002 26.96 0.0001 28.94 0.0002 29.94 0.0002 30.94 0.0002 32.97 0.0001 33.97 0.0001 34.95 0.0001 36.93 0.0001 ) constant c-d4 #( 1.00 0.3562 1.99 0.0664 2.99 0.1446 3.98 0.0393 4.97 0.0363 5.97 0.0237 6.96 0.0366 7.95 0.0079 8.96 0.0127 9.95 0.0148 10.95 0.0143 11.94 0.0031 12.96 0.0022 13.94 0.0032 14.92 0.0004 15.92 0.0007 16.90 0.0007 17.92 0.0007 18.92 0.0012 19.94 0.0005 20.89 0.0003 21.88 0.0001 22.89 0.0005 23.87 0.0004 24.87 0.0001 25.89 0.0007 26.87 0.0001 29.85 0.0001 30.83 0.0001 31.82 0.0001 32.82 0.0002 33.82 0.0001 ) constant c-ds4 #( 1.00 0.0390 2.01 0.1863 3.02 0.0265 4.02 0.0184 5.02 0.0319 6.03 0.0456 7.04 0.0122 8.04 0.0149 9.05 0.0159 10.05 0.0067 11.06 0.0044 12.06 0.0053 13.08 0.0012 14.08 0.0008 15.08 0.0007 16.09 0.0021 17.09 0.0005 18.09 0.0021 19.13 0.0016 20.12 0.0004 21.12 0.0003 22.14 0.0003 23.12 0.0003 24.13 0.0003 25.14 0.0005 26.14 0.0002 27.15 0.0002 28.16 0.0002 29.18 0.0002 30.17 0.0002 31.16 0.0002 36.21 0.0001 ) constant c-e4 #( 1.00 0.1183 1.99 0.1142 2.99 0.1085 3.98 0.0306 4.99 0.0252 5.97 0.0272 6.97 0.0290 7.97 0.0142 8.97 0.0112 9.96 0.0079 10.96 0.0038 11.97 0.0026 12.96 0.0014 13.95 0.0007 14.94 0.0011 15.95 0.0008 16.94 0.0011 17.03 0.0001 17.94 0.0001 18.95 0.0004 19.94 0.0003 20.94 0.0007 21.92 0.0002 23.92 0.0002 24.92 0.0002 25.90 0.0002 26.90 0.0002 27.89 0.0001 28.89 0.0002 30.89 0.0001 ) constant c-f4 #( 1.00 0.1140 2.00 0.0935 3.00 0.0504 3.99 0.0715 4.99 0.0063 6.00 0.0808 6.99 0.0099 8.00 0.0093 9.00 0.0093 9.99 0.0019 10.99 0.0050 11.99 0.0017 12.99 0.0021 14.00 0.0003 14.99 0.0010 16.00 0.0015 17.00 0.0019 17.95 0.0002 18.00 0.0002 18.99 0.0002 19.99 0.0003 21.00 0.0002 21.99 0.0003 23.99 0.0001 24.98 0.0001 26.02 0.0001 27.01 0.0001 28.00 0.0002 ) constant c-fs4 #( 1.00 0.0809 1.99 0.1377 2.99 0.0348 3.99 0.0337 4.98 0.0177 5.98 0.0295 6.98 0.0266 7.98 0.0063 8.98 0.0105 9.97 0.0016 10.97 0.0022 11.98 0.0029 12.97 0.0018 13.96 0.0008 14.99 0.0023 15.97 0.0012 16.96 0.0009 17.97 0.0002 18.95 0.0006 20.94 0.0002 20.99 0.0002 22.95 0.0002 23.94 0.0002 24.94 0.0003 25.97 0.0003 26.95 0.0002 ) constant c-g4 #( 1.00 0.2601 1.99 0.1726 2.99 0.0722 3.99 0.0276 4.99 0.0535 5.99 0.0103 6.99 0.0244 7.99 0.0046 8.98 0.0035 9.99 0.0088 10.98 0.0038 11.98 0.0008 12.96 0.0006 13.98 0.0020 14.98 0.0016 15.98 0.0008 16.97 0.0003 17.97 0.0005 18.98 0.0006 19.96 0.0005 20.96 0.0001 21.96 0.0003 23.96 0.0002 24.96 0.0003 25.96 0.0002 ) constant c-gs4 #( 0.99 0.0363 1.98 0.2481 2.98 0.0514 3.97 0.0365 4.97 0.0468 5.95 0.0182 6.95 0.0333 7.94 0.0106 8.93 0.0048 9.92 0.0048 10.92 0.0016 11.90 0.0010 12.89 0.0011 13.92 0.0023 14.90 0.0014 15.88 0.0007 16.87 0.0002 17.89 0.0001 18.85 0.0004 19.84 0.0002 20.84 0.0003 21.84 0.0004 22.83 0.0003 23.86 0.0002 24.84 0.0002 26.82 0.0001 ) constant c-a4 #( 0.99 0.0564 1.99 0.1983 2.98 0.0520 3.97 0.0442 4.97 0.0260 5.96 0.0139 6.96 0.0099 7.94 0.0046 8.94 0.0178 9.94 0.0032 10.93 0.0021 11.00 0.0002 11.93 0.0001 12.92 0.0038 13.91 0.0011 14.90 0.0006 15.92 0.0004 16.89 0.0004 17.89 0.0002 18.87 0.0005 19.87 0.0003 20.86 0.0003 21.85 0.0003 22.85 0.0001 23.85 0.0001 24.85 0.0001 25.85 0.0002 26.84 0.0002 ) constant c-as4 #( 0.99 0.0774 1.98 0.1289 2.96 0.1071 3.95 0.0216 4.94 0.0346 5.93 0.0108 6.91 0.0239 7.90 0.0056 8.88 0.0045 9.88 0.0014 10.87 0.0057 11.85 0.0018 12.85 0.0035 13.83 0.0007 14.84 0.0003 15.80 0.0003 16.79 0.0008 17.78 0.0003 18.78 0.0002 19.76 0.0004 20.75 0.0005 21.73 0.0002 23.71 0.0001 24.68 0.0001 ) constant c-b4 #( 0.99 0.4933 1.97 0.1293 2.95 0.0971 4.92 0.0189 5.91 0.0031 6.88 0.0093 7.87 0.0143 8.85 0.0063 9.84 0.0010 10.82 0.0023 11.81 0.0015 12.79 0.0006 13.78 0.0009 14.76 0.0007 15.75 0.0004 16.72 0.0007 17.71 0.0002 18.68 0.0008 19.67 0.0004 20.66 0.0003 ) constant c-c5 #( 0.99 0.1576 1.99 0.0760 2.98 0.0560 3.97 0.1172 4.96 0.0433 5.96 0.0029 6.95 0.0079 7.95 0.0058 8.93 0.0025 9.93 0.0014 10.93 0.0054 11.92 0.0005 12.92 0.0004 13.90 0.0009 14.90 0.0015 15.89 0.0003 16.87 0.0002 17.87 0.0004 18.87 0.0002 19.86 0.0002 20.86 0.0002 21.86 0.0003 22.85 0.0002 ) constant c-cs5 #( 1.01 0.1243 2.02 0.0648 3.03 0.0586 4.04 0.0543 5.05 0.0183 6.07 0.0046 7.08 0.0080 8.09 0.0027 9.10 0.0053 10.12 0.0036 11.14 0.0014 12.14 0.0004 13.16 0.0004 14.15 0.0007 15.17 0.0005 17.20 0.0006 18.22 0.0002 19.22 0.0002 21.24 0.0001 ) constant c-d5 #( 1.01 0.1367 2.02 0.0170 3.02 0.0192 4.03 0.0425 5.04 0.0143 6.05 0.0064 7.06 0.0057 8.06 0.0028 9.08 0.0027 10.09 0.0051 11.09 0.0009 12.09 0.0001 13.10 0.0014 14.11 0.0005 15.13 0.0003 16.13 0.0003 17.14 0.0002 19.15 0.0003 20.17 0.0004 21.17 0.0001 ) constant c-ds5 #( 1.02 0.2402 2.03 0.0419 3.05 0.1068 5.08 0.0164 6.10 0.0019 7.11 0.0044 8.13 0.0018 9.15 0.0044 10.17 0.0021 11.18 0.0003 12.20 0.0007 13.21 0.0011 14.24 0.0003 15.24 0.0008 16.27 0.0001 17.28 0.0001 18.31 0.0001 ) constant c-e5 #( 1.01 0.1166 2.03 0.0750 3.04 0.0532 4.05 0.0620 5.06 0.0054 6.07 0.0141 7.08 0.0027 8.10 0.0015 9.09 0.0021 10.13 0.0006 11.13 0.0009 12.14 0.0004 13.15 0.0008 14.17 0.0003 15.18 0.0002 17.19 0.0003 18.20 0.0002 ) constant c-f5 #( 1.00 0.1595 2.00 0.0985 3.01 0.1045 4.01 0.0147 5.01 0.0078 6.01 0.0016 7.01 0.0020 8.02 0.0007 9.02 0.0015 10.03 0.0008 11.03 0.0006 12.02 0.0004 13.02 0.0009 14.03 0.0006 15.02 0.0005 16.03 0.0002 17.04 0.0001 ) constant c-fs5 #( 1.00 0.1740 1.99 0.0431 2.99 0.1899 3.99 0.0201 4.98 0.0009 5.98 0.0031 6.98 0.0055 7.97 0.0051 8.97 0.0007 9.96 0.0007 10.95 0.0006 11.95 0.0009 12.95 0.0008 13.96 0.0002 14.94 0.0001 15.95 0.0002 ) constant c-g5 #( 1.00 0.1902 1.99 0.0327 2.98 0.0551 3.98 0.0157 4.97 0.0078 5.97 0.0030 6.96 0.0035 7.96 0.0020 8.95 0.0017 9.94 0.0011 10.94 0.0005 11.93 0.0007 12.93 0.0004 13.92 0.0002 14.93 0.0003 ) constant c-gs5 #( 0.99 0.4175 1.99 0.0209 2.98 0.0274 3.97 0.0220 4.96 0.0061 5.96 0.0020 6.96 0.0038 7.95 0.0009 8.95 0.0014 9.93 0.0005 10.93 0.0005 11.91 0.0007 12.91 0.0002 13.91 0.0001 14.91 0.0001 ) constant c-a5 #( 1.00 0.4648 2.00 0.0475 3.01 0.1268 4.01 0.0164 5.02 0.0035 6.02 0.0018 7.02 0.0033 8.03 0.0028 9.03 0.0008 10.03 0.0006 11.03 0.0005 12.04 0.0006 13.05 0.0003 14.04 0.0001 ) constant c-as5 #( 1.01 0.2812 2.02 0.1380 3.02 0.0722 4.03 0.0215 5.04 0.0036 6.06 0.0018 7.05 0.0005 8.07 0.0015 9.08 0.0013 10.08 0.0003 11.10 0.0002 12.11 0.0003 13.11 0.0002 ) constant c-b5 #( 1.01 0.2553 2.01 0.1160 3.02 0.0171 4.02 0.0272 5.02 0.0020 6.03 0.0062 7.03 0.0012 8.04 0.0011 9.05 0.0007 10.05 0.0007 11.06 0.0002 12.06 0.0001 12.08 0.0001 ) constant c-c6 #( 1.01 0.1045 2.02 0.1220 3.04 0.0220 4.05 0.0094 5.06 0.0021 6.07 0.0031 7.09 0.0018 8.10 0.0020 9.11 0.0014 10.12 0.0003 11.13 0.0006 ) constant c-cs6 #( 1.00 0.0653 1.99 0.2499 2.99 0.0334 3.98 0.0098 4.98 0.0091 5.98 0.0007 6.97 0.0011 7.97 0.0008 8.96 0.0042 9.96 0.0003 10.95 0.0004 ) constant c-d6 #( 0.99 0.0485 1.99 0.1325 2.98 0.0152 3.98 0.0064 4.97 0.0043 5.97 0.0007 6.96 0.0007 7.97 0.0006 8.96 0.0003 9.95 0.0004 ) constant c-ds6 #( 1.01 0.1797 2.01 0.0750 4.03 0.0065 5.04 0.0018 6.04 0.0012 7.04 0.0004 8.06 0.0003 9.06 0.0003 ) constant c-e6 \ ********************************************************** \ clarinet \ ********************************************************** #( 1.01 0.1722 2.00 0.0056 2.99 0.1609 3.99 0.0333 5.00 0.1157 5.99 0.1149 6.98 0.0079 7.98 0.0620 8.99 0.0601 9.99 0.0104 10.98 0.0134 11.97 0.0122 12.99 0.0058 13.98 0.0110 14.98 0.0029 15.97 0.0045 16.98 0.0023 17.98 0.0010 18.97 0.0016 19.96 0.0021 20.96 0.0008 21.97 0.0021 22.96 0.0001 23.96 0.0012 24.95 0.0003 25.97 0.0002 26.96 0.0003 27.95 0.0002 30.96 0.0002 32.94 0.0002 34.96 0.0001 35.95 0.0002 37.93 0.0001 ) constant cl-d3 #( 0.99 0.1038 1.98 0.0043 2.96 0.0953 3.97 0.0013 4.94 0.1057 5.93 0.0145 6.93 0.0787 7.91 0.0328 8.89 0.0086 9.90 0.0088 10.88 0.0128 11.86 0.0005 12.86 0.0085 13.84 0.0026 14.83 0.0051 15.81 0.0030 16.82 0.0008 17.79 0.0026 18.78 0.0013 19.78 0.0015 20.76 0.0011 22.74 0.0012 23.72 0.0002 24.71 0.0006 25.70 0.0003 26.70 0.0002 28.67 0.0002 30.64 0.0002 31.64 0.0001 32.63 0.0001 33.61 0.0003 35.59 0.0002 ) constant cl-ds3 #( 1.00 0.0825 1.99 0.0024 2.97 0.0406 3.96 0.0042 4.94 0.0683 6.40 0.0010 6.92 0.0709 7.92 0.0099 8.91 0.0059 9.89 0.0055 10.88 0.0111 11.90 0.0009 12.86 0.0126 13.87 0.0021 14.84 0.0110 15.83 0.0010 16.83 0.0057 17.81 0.0007 18.80 0.0037 19.78 0.0008 20.78 0.0016 21.75 0.0006 22.75 0.0008 23.73 0.0005 24.74 0.0007 26.72 0.0004 27.68 0.0002 29.67 0.0003 31.66 0.0003 33.64 0.0002 ) constant cl-e3 #( 0.99 0.0685 1.98 0.0012 2.98 0.0854 3.98 0.0029 4.96 0.0507 5.97 0.0017 6.96 0.0507 7.94 0.0027 8.94 0.0092 9.94 0.0084 10.92 0.0116 11.91 0.0018 12.92 0.0039 13.92 0.0003 14.89 0.0013 15.88 0.0019 16.87 0.0012 17.86 0.0010 18.87 0.0011 19.86 0.0008 20.85 0.0008 21.83 0.0002 23.81 0.0004 24.83 0.0002 25.80 0.0003 27.78 0.0002 29.78 0.0001 ) constant cl-f3 #( 1.00 0.1546 1.99 0.0015 2.99 0.0594 4.00 0.0014 5.00 0.0268 6.00 0.0019 7.00 0.0170 7.97 0.0005 9.00 0.0110 9.99 0.0006 10.99 0.0077 11.99 0.0013 12.99 0.0025 14.01 0.0004 14.99 0.0018 15.98 0.0001 16.98 0.0013 17.97 0.0003 18.98 0.0013 20.97 0.0001 21.97 0.0004 22.96 0.0002 23.98 0.0002 25.99 0.0001 ) constant cl-fs3 #( 0.99 0.1660 2.00 0.0016 2.99 0.0889 3.99 0.0017 4.99 0.0430 6.00 0.0009 6.98 0.0128 8.00 0.0040 8.98 0.0077 9.99 0.0017 10.98 0.0052 11.98 0.0011 12.98 0.0012 13.97 0.0008 14.98 0.0010 15.97 0.0005 16.98 0.0005 17.96 0.0007 18.97 0.0002 19.96 0.0004 20.96 0.0003 22.94 0.0003 23.95 0.0002 24.96 0.0002 25.93 0.0001 26.94 0.0002 27.95 0.0001 ) constant cl-g3 #( 1.00 0.1107 2.00 0.0016 2.99 0.0872 3.99 0.0028 4.98 0.0293 5.97 0.0020 6.96 0.0202 7.99 0.0019 8.95 0.0118 9.94 0.0028 10.95 0.0040 11.92 0.0006 12.95 0.0030 13.92 0.0002 14.92 0.0010 15.91 0.0005 16.91 0.0015 18.90 0.0004 19.89 0.0004 20.89 0.0002 21.88 0.0004 22.87 0.0002 23.88 0.0001 24.87 0.0001 ) constant cl-gs3 #( 1.00 0.0842 2.01 0.0017 3.00 0.0420 4.01 0.0029 5.00 0.0251 6.02 0.0041 6.99 0.0115 7.96 0.0006 8.99 0.0032 9.98 0.0003 11.00 0.0018 11.96 0.0003 12.96 0.0006 14.00 0.0001 14.97 0.0001 15.97 0.0005 17.95 0.0002 18.96 0.0001 19.07 0.0001 22.06 0.0001 ) constant cl-a3 #( 1.00 0.1118 1.99 0.0006 2.98 0.0383 3.98 0.0019 4.98 0.0335 5.98 0.0034 6.97 0.0131 7.94 0.0005 8.95 0.0024 9.96 0.0028 10.96 0.0019 11.94 0.0012 12.94 0.0012 13.93 0.0003 14.94 0.0007 16.92 0.0004 17.90 0.0003 18.93 0.0002 20.89 0.0002 21.90 0.0001 ) constant cl-as3 #( 1.00 0.1324 1.99 0.0011 3.00 0.0693 4.01 0.0012 4.99 0.0279 5.98 0.0044 6.98 0.0149 7.97 0.0009 8.97 0.0028 9.97 0.0009 10.98 0.0026 11.96 0.0003 12.96 0.0006 13.95 0.0003 15.95 0.0001 16.94 0.0001 ) constant cl-b3 #( 1.00 0.2335 1.99 0.0017 2.99 0.1253 4.01 0.0023 4.99 0.0343 6.01 0.0028 6.98 0.0023 7.98 0.0014 8.98 0.0041 10.01 0.0003 10.96 0.0004 11.94 0.0008 12.94 0.0002 14.94 0.0003 15.94 0.0004 16.93 0.0002 17.91 0.0002 18.91 0.0002 19.91 0.0001 20.90 0.0001 ) constant cl-c4 #( 0.99 0.2609 2.00 0.0016 2.99 0.1469 3.99 0.0040 4.99 0.0143 5.97 0.0091 6.97 0.0055 7.97 0.0024 8.96 0.0041 9.96 0.0015 10.96 0.0021 11.95 0.0005 12.94 0.0011 13.93 0.0004 14.94 0.0006 15.94 0.0004 16.92 0.0004 17.93 0.0002 18.93 0.0001 19.91 0.0001 20.91 0.0001 21.90 0.0002 22.91 0.0001 ) constant cl-cs4 #( 1.00 0.2056 1.99 0.0006 2.99 0.1715 3.99 0.0010 4.98 0.0194 5.99 0.0028 6.98 0.0106 7.98 0.0007 8.97 0.0022 9.97 0.0005 10.96 0.0011 11.97 0.0006 12.96 0.0006 13.96 0.0003 14.95 0.0005 15.95 0.0003 17.95 0.0002 18.94 0.0002 20.94 0.0001 ) constant cl-d4 #( 1.00 0.2590 1.98 0.0019 2.99 0.1336 3.97 0.0034 4.97 0.0442 5.97 0.0017 6.96 0.0108 7.96 0.0006 8.95 0.0031 9.94 0.0003 11.93 0.0003 12.93 0.0004 13.93 0.0005 14.92 0.0001 15.91 0.0003 16.90 0.0004 17.90 0.0002 18.89 0.0001 ) constant cl-ds4 #( 1.00 0.2560 2.00 0.0013 3.00 0.0878 4.00 0.0053 5.00 0.0304 6.00 0.0009 7.00 0.0060 7.99 0.0007 9.00 0.0011 9.99 0.0006 10.99 0.0006 11.98 0.0001 13.99 0.0001 ) constant cl-e4 #( 0.99 0.1966 1.99 0.0021 2.98 0.0812 3.96 0.0018 4.97 0.0248 5.96 0.0032 6.96 0.0060 7.95 0.0024 8.95 0.0019 9.94 0.0008 10.94 0.0007 11.92 0.0005 12.91 0.0002 13.94 0.0001 14.90 0.0002 15.91 0.0002 ) constant cl-f4 #( 1.00 0.1555 2.01 0.0022 3.01 0.1755 4.01 0.0005 5.01 0.0127 6.02 0.0004 7.02 0.0031 8.02 0.0007 9.02 0.0005 10.02 0.0002 11.03 0.0003 12.02 0.0002 14.02 0.0001 15.03 0.0001 16.04 0.0001 ) constant cl-fs4 #( 1.00 0.0470 2.00 0.0016 3.00 0.0787 4.00 0.0041 5.00 0.0046 6.00 0.0010 7.00 0.0036 8.00 0.0011 9.00 0.0012 10.00 0.0002 11.00 0.0003 13.00 0.0001 ) constant cl-g4 #( 1.00 0.1205 1.99 0.0014 2.99 0.0145 3.99 0.0015 4.99 0.0030 5.99 0.0005 6.98 0.0006 9.00 0.0001 9.98 0.0001 ) constant cl-gs4 #( 1.00 0.2677 2.00 0.0592 3.01 0.0961 4.01 0.0083 5.02 0.0075 6.02 0.0027 7.03 0.0048 8.03 0.0031 9.02 0.0007 10.03 0.0003 11.03 0.0001 ) constant cl-a4 #( 1.00 0.1363 2.01 0.0056 3.00 0.0168 4.01 0.0026 5.01 0.0112 6.00 0.0011 7.01 0.0011 8.01 0.0003 10.00 0.0002 12.02 0.0001 ) constant cl-as4 #( 1.01 0.0312 2.01 0.0042 3.02 0.0061 4.02 0.0127 5.03 0.0090 6.04 0.0002 7.04 0.0021 8.05 0.0008 11.06 0.0001 ) constant cl-b4 #( 1.00 0.2597 2.00 0.0052 3.00 0.0337 4.00 0.0012 5.00 0.0025 6.00 0.0014 7.00 0.0007 7.99 0.0004 8.99 0.0003 10.00 0.0004 ) constant cl-c5 #( 1.00 0.1894 2.00 0.0060 3.00 0.0250 4.01 0.0022 5.01 0.0048 6.00 0.0004 8.01 0.0001 10.01 0.0001 ) constant cl-cs5 #( 1.00 0.1727 2.01 0.0013 3.00 0.0066 4.01 0.0011 5.00 0.0013 5.99 0.0008 8.02 0.0001 ) constant cl-d5 #( 1.00 0.3538 2.00 0.0053 3.01 0.0757 4.01 0.0009 5.01 0.0045 6.02 0.0008 7.02 0.0011 8.01 0.0003 9.02 0.0005 10.01 0.0002 11.02 0.0001 12.02 0.0002 ) constant cl-ds5 #( 1.00 0.1647 2.00 0.0048 3.00 0.0524 3.99 0.0055 4.99 0.0030 5.98 0.0011 6.99 0.0004 7.99 0.0003 ) constant cl-e5 #( 0.99 0.1880 1.99 0.0126 2.99 0.0222 3.98 0.0070 4.98 0.0135 5.97 0.0020 6.97 0.0012 7.96 0.0001 8.96 0.0007 9.95 0.0003 ) constant cl-f5 #( 1.00 0.3103 2.00 0.0104 3.00 0.0335 4.00 0.0078 5.00 0.0026 6.01 0.0005 7.01 0.0006 8.00 0.0003 ) constant cl-fs5 #( 1.01 0.4163 2.01 0.0446 3.02 0.0290 4.03 0.0031 5.02 0.0004 6.03 0.0002 7.05 0.0001 8.05 0.0001 ) constant cl-g5 #( 1.01 0.2150 2.00 0.0334 3.00 0.0012 4.02 0.0003 5.02 0.0002 ) constant cl-gs5 #( 1.01 0.5463 2.01 0.0429 3.02 0.0317 4.02 0.0159 5.03 0.0012 6.04 0.0005 7.04 0.0005 8.05 0.0002 ) constant cl-a5 #( 1.00 0.3802 2.00 0.0397 3.01 0.0186 4.01 0.0102 5.01 0.0020 6.01 0.0001 7.01 0.0002 8.02 0.0003 9.02 0.0002 10.02 0.0001 11.02 0.0001 12.02 0.0002 ) constant cl-as5 #( 1.00 0.0896 2.00 0.0851 3.00 0.0081 4.00 0.0024 5.00 0.0010 6.00 0.0001 7.00 0.0002 ) constant cl-b5 #( 1.00 0.1740 2.00 0.0081 3.01 0.0111 4.01 0.0087 5.01 0.0005 6.01 0.0007 7.01 0.0001 9.01 0.0002 10.02 0.0002 ) constant cl-c6 #( 1.00 0.1295 1.99 0.0270 2.99 0.0012 3.99 0.0004 ) constant cl-cs6 #( 1.00 0.1700 2.01 0.0603 3.01 0.0169 4.01 0.0031 5.01 0.0007 6.01 0.0002 ) constant cl-d6 #( 1.01 0.2624 2.02 0.0042 3.03 0.0049 4.03 0.0015 5.04 0.0001 ) constant cl-ds6 #( 1.02 0.0632 2.03 0.0115 3.04 0.0011 4.06 0.0006 ) constant cl-e6 #( 1.02 0.0748 2.03 0.0535 3.05 0.0044 4.07 0.0009 5.08 0.0001 7.12 0.0001 8.13 0.0001 ) constant cl-f6 #( 1.02 0.0305 2.03 0.0175 3.04 0.0005 4.05 0.0002 ) constant cl-fs6 #( 1.03 0.0026 2.04 0.0008 ) constant cl-g6 #( 1.03 0.0015 2.00 0.0002 ) constant cl-gs6 #( 1.03 0.0043 2.05 0.0010 ) constant cl-a6 #( 1.05 0.0008 2.00 0.0001 ) constant cl-as6 \ ********************************************************** \ french horn \ ********************************************************** #( 1.01 0.0041 2.00 0.0015 3.01 0.0121 4.02 0.0111 5.02 0.0343 6.03 0.0165 7.04 0.0066 8.03 0.0064 9.05 0.0049 10.06 0.0012 11.05 0.0093 12.07 0.0029 13.07 0.0042 14.08 0.0040 15.08 0.0019 16.09 0.0013 17.10 0.0009 18.04 0.0002 19.03 0.0002 20.12 0.0003 21.13 0.0003 22.13 0.0002 23.13 0.0002 ) constant fh-as1 #( 1.01 0.0035 2.03 0.0064 3.04 0.0087 4.08 0.0087 5.12 0.0049 6.08 0.0189 7.10 0.0304 8.12 0.0205 9.16 0.0026 10.18 0.0039 11.20 0.0006 12.11 0.0029 13.15 0.0037 14.24 0.0014 15.26 0.0010 16.29 0.0005 17.19 0.0003 18.21 0.0007 19.23 0.0005 20.25 0.0004 21.33 0.0003 22.36 0.0001 23.32 0.0002 24.33 0.0002 25.33 0.0001 26.39 0.0002 27.42 0.0002 ) constant fh-b1 #( 1.02 0.0034 2.02 0.0059 3.01 0.0083 4.02 0.0274 5.03 0.0206 6.03 0.0155 7.04 0.0131 8.03 0.0073 9.05 0.0014 10.03 0.0064 11.05 0.0055 12.06 0.0109 13.08 0.0037 14.10 0.0012 15.10 0.0010 16.01 0.0004 17.05 0.0009 18.06 0.0008 19.06 0.0006 20.09 0.0004 21.11 0.0002 22.14 0.0002 23.09 0.0002 24.08 0.0001 25.08 0.0002 26.07 0.0002 27.12 0.0002 28.16 0.0001 32.11 0.0001 ) constant fh-c2 #( 1.01 0.0038 1.99 0.0124 2.98 0.0065 4.00 0.0260 5.00 0.0138 5.99 0.0093 6.97 0.0077 7.95 0.0055 8.97 0.0061 9.97 0.0016 10.95 0.0034 11.96 0.0036 12.14 0.0010 12.94 0.0009 13.97 0.0008 14.86 0.0004 15.89 0.0006 16.91 0.0007 17.93 0.0004 18.94 0.0002 19.95 0.0001 20.77 0.0001 21.78 0.0002 22.86 0.0001 23.89 0.0002 ) constant fh-cs2 #( 1.01 0.0153 2.01 0.0192 3.01 0.0216 4.01 0.0371 5.01 0.0259 6.02 0.0188 7.02 0.0076 8.04 0.0009 9.03 0.0038 10.03 0.0065 11.03 0.0075 12.03 0.0026 13.03 0.0005 14.04 0.0009 15.06 0.0008 16.04 0.0006 17.03 0.0004 18.03 0.0003 19.04 0.0002 23.03 0.0002 ) constant fh-d2 #( 1.00 0.0234 1.98 0.0227 2.96 0.0129 3.97 0.0333 4.96 0.0315 5.95 0.0252 6.93 0.0076 7.94 0.0061 8.91 0.0028 9.89 0.0096 10.90 0.0089 11.89 0.0024 12.88 0.0022 13.88 0.0019 14.87 0.0010 15.79 0.0006 16.79 0.0003 17.79 0.0002 18.69 0.0002 19.68 0.0003 20.70 0.0002 21.70 0.0002 ) constant fh-ds2 #( 1.00 0.0150 1.99 0.0230 3.01 0.0204 4.00 0.0298 5.02 0.0112 6.03 0.0135 7.02 0.0019 8.03 0.0061 9.01 0.0099 10.04 0.0053 11.03 0.0006 12.04 0.0028 13.04 0.0016 14.04 0.0015 15.03 0.0009 16.02 0.0005 17.05 0.0002 20.02 0.0002 21.02 0.0001 24.00 0.0002 25.03 0.0001 ) constant fh-e2 #( 0.97 0.0088 1.96 0.0127 2.97 0.0179 3.96 0.0163 4.94 0.0421 5.91 0.0165 6.96 0.0019 7.93 0.0020 8.91 0.0112 9.85 0.0035 10.91 0.0017 12.02 0.0004 12.83 0.0014 13.79 0.0010 14.79 0.0007 15.75 0.0002 16.73 0.0003 17.74 0.0007 18.74 0.0005 19.73 0.0001 20.68 0.0002 21.66 0.0002 22.65 0.0002 23.63 0.0001 24.65 0.0001 ) constant fh-f2 #( 1.00 0.0035 1.99 0.0136 2.97 0.0394 3.96 0.0379 4.98 0.0330 5.97 0.0111 6.94 0.0156 7.94 0.0108 8.96 0.0076 9.95 0.0025 10.95 0.0021 11.93 0.0026 12.93 0.0014 13.89 0.0008 14.87 0.0006 15.78 0.0001 16.94 0.0001 17.93 0.0001 18.93 0.0001 19.89 0.0001 ) constant fh-fs2 #( 1.01 0.0150 2.01 0.0182 3.04 0.1047 4.04 0.0662 5.03 0.0448 6.06 0.0018 7.06 0.0034 8.06 0.0202 9.09 0.0051 10.09 0.0070 11.08 0.0060 12.11 0.0022 13.12 0.0011 14.13 0.0005 15.20 0.0001 16.09 0.0002 17.14 0.0002 18.14 0.0002 19.14 0.0002 20.16 0.0002 21.15 0.0001 22.15 0.0001 ) constant fh-g2 #( 0.99 0.0092 2.00 0.0177 3.00 0.0664 3.98 0.0447 4.99 0.0223 5.99 0.0144 7.00 0.0124 7.97 0.0096 8.97 0.0046 9.96 0.0011 10.99 0.0021 12.00 0.0010 12.99 0.0007 13.93 0.0007 14.92 0.0007 15.94 0.0005 16.94 0.0003 17.90 0.0002 18.88 0.0001 19.87 0.0002 20.86 0.0002 21.86 0.0001 ) constant fh-gs2 #( 1.00 0.0063 2.01 0.0609 3.03 0.0699 4.05 0.1365 5.04 0.0249 6.05 0.0103 7.07 0.0200 8.08 0.0059 9.10 0.0063 10.09 0.0046 11.10 0.0015 12.13 0.0008 13.14 0.0006 14.07 0.0004 15.05 0.0004 16.08 0.0004 17.10 0.0002 18.12 0.0002 19.10 0.0001 ) constant fh-a2 #( 1.00 0.0026 2.02 0.0329 3.03 0.0926 4.04 0.0530 5.07 0.0041 6.07 0.0072 7.09 0.0076 8.10 0.0053 9.11 0.0057 10.13 0.0017 11.16 0.0005 12.21 0.0001 13.09 0.0003 14.11 0.0003 15.18 0.0003 16.17 0.0001 ) constant fh-as2 #( 1.01 0.0154 2.02 0.0506 3.05 0.1042 4.05 0.0643 5.06 0.0151 6.08 0.0102 7.09 0.0045 8.11 0.0040 9.12 0.0033 10.12 0.0015 11.13 0.0006 12.16 0.0004 13.18 0.0003 14.95 0.0001 15.98 0.0001 16.99 0.0001 18.02 0.0001 ) constant fh-b2 #( 1.01 0.0147 2.02 0.0897 3.01 0.1180 4.01 0.0323 5.02 0.0133 6.04 0.0226 7.04 0.0033 8.06 0.0023 9.02 0.0019 10.03 0.0010 11.04 0.0009 12.06 0.0003 13.04 0.0002 14.05 0.0002 15.05 0.0002 16.01 0.0002 16.94 0.0001 ) constant fh-c3 #( 1.01 0.0345 2.00 0.1083 2.99 0.0911 4.01 0.0280 5.01 0.0071 6.00 0.0123 7.00 0.0043 8.01 0.0034 9.01 0.0014 10.02 0.0004 10.94 0.0003 11.96 0.0003 12.96 0.0002 14.89 0.0001 15.92 0.0001 ) constant fh-cs3 #( 1.01 0.0488 2.02 0.1313 3.03 0.1606 4.03 0.0029 5.04 0.0187 6.05 0.0059 7.05 0.0018 8.05 0.0023 9.05 0.0007 10.06 0.0003 11.07 0.0001 12.08 0.0002 ) constant fh-d3 #( 1.00 0.0619 2.00 0.1230 3.01 0.0981 4.02 0.0299 5.02 0.0210 6.03 0.0054 7.03 0.0023 8.04 0.0010 9.04 0.0005 10.06 0.0002 ) constant fh-ds3 #( 1.00 0.0500 2.01 0.1076 3.03 0.1077 4.04 0.0167 5.03 0.0138 6.06 0.0058 7.07 0.0036 8.06 0.0007 9.09 0.0004 10.07 0.0002 11.03 0.0001 12.05 0.0002 ) constant fh-e3 #( 1.01 0.0368 2.02 0.1311 3.02 0.0405 4.03 0.0139 5.03 0.0080 6.04 0.0052 7.05 0.0015 8.04 0.0004 9.06 0.0002 10.06 0.0002 12.08 0.0001 ) constant fh-f3 #( 1.01 0.0430 2.02 0.1877 3.05 0.0299 4.05 0.0218 5.07 0.0067 6.08 0.0054 7.10 0.0012 8.11 0.0010 9.12 0.0004 10.13 0.0002 11.15 0.0001 ) constant fh-fs3 #( 1.01 0.0339 2.04 0.1965 4.07 0.0541 5.08 0.0113 6.10 0.0049 7.10 0.0022 8.13 0.0014 9.14 0.0008 10.16 0.0005 ) constant fh-g3 #( 1.02 0.0596 2.02 0.1865 3.03 0.0629 4.04 0.0304 5.05 0.0087 6.05 0.0035 7.07 0.0008 8.09 0.0004 9.09 0.0005 10.10 0.0005 11.11 0.0002 12.12 0.0001 ) constant fh-gs3 #( 1.00 0.1160 2.02 0.2642 3.02 0.0259 4.02 0.0127 5.04 0.0095 6.04 0.0022 7.04 0.0013 8.06 0.0008 9.04 0.0003 10.01 0.0001 ) constant fh-a3 #( 1.01 0.0585 2.01 0.1648 3.02 0.0229 4.02 0.0150 5.03 0.0084 6.03 0.0016 7.06 0.0003 9.01 0.0002 ) constant fh-as3 #( 1.01 0.0741 2.00 0.1581 3.00 0.0490 4.01 0.0133 5.01 0.0045 6.02 0.0013 7.03 0.0002 8.00 0.0001 ) constant fh-b3 #( 0.99 0.1378 2.00 0.0872 2.99 0.0736 3.99 0.0065 4.99 0.0025 5.97 0.0009 6.98 0.0002 7.98 0.0005 8.98 0.0002 ) constant fh-c4 #( 1.01 0.2826 2.02 0.0676 3.02 0.0523 4.03 0.0208 5.04 0.0069 6.04 0.0009 7.05 0.0009 8.06 0.0011 9.07 0.0004 10.07 0.0001 11.08 0.0002 12.09 0.0001 ) constant fh-cs4 #( 1.01 0.2849 2.02 0.0068 3.03 0.0144 4.04 0.0066 5.05 0.0032 6.07 0.0007 7.07 0.0003 8.09 0.0003 ) constant fh-d4 #( 1.00 0.2321 2.01 0.0612 3.02 0.0150 4.03 0.0042 5.03 0.0007 6.04 0.0005 7.05 0.0002 8.06 0.0001 ) constant fh-ds4 #( 1.01 0.1701 2.01 0.0303 3.02 0.0156 4.03 0.0021 5.04 0.0009 6.04 0.0003 7.04 0.0001 ) constant fh-e4 #( 1.01 0.1957 2.01 0.0196 3.01 0.0087 4.01 0.0022 5.01 0.0006 6.02 0.0002 ) constant fh-f4 #( 1.01 0.3622 2.02 0.0601 3.03 0.0187 4.04 0.0043 5.05 0.0011 6.06 0.0005 ) constant fh-fs4 #( 1.00 0.2782 2.01 0.0918 3.01 0.0080 4.03 0.0013 5.03 0.0010 6.03 0.0003 ) constant fh-g4 #( 1.01 0.2703 2.02 0.0548 3.02 0.0083 4.03 0.0011 5.03 0.0009 6.04 0.0003 ) constant fh-gs4 #( 1.01 0.4575 2.02 0.0245 3.03 0.0049 4.04 0.0019 5.05 0.0008 6.06 0.0002 ) constant fh-a4 #( 1.00 0.2524 2.01 0.0291 3.02 0.0022 4.03 0.0011 5.03 0.0003 ) constant fh-as4 #( 1.00 0.3254 2.00 0.0428 3.00 0.0026 4.00 0.0006 ) constant fh-b4 #( 1.00 0.1672 2.00 0.0223 3.00 0.0010 4.00 0.0005 ) constant fh-c5 #( 1.00 0.1209 2.00 0.0340 3.00 0.0014 4.01 0.0004 ) constant fh-cs5 #( 1.01 0.0150 2.01 0.0313 3.02 0.0023 4.03 0.0007 ) constant fh-d5 #( 1.00 0.1633 2.00 0.0260 3.00 0.0012 4.00 0.0002 ) constant fh-ds5 #( 1.00 0.1001 2.00 0.0146 3.00 0.0019 4.00 0.0001 ) constant fh-e5 #( 1.01 0.0944 2.01 0.0114 3.02 0.0016 4.02 0.0002 ) constant fh-f5 #( 1.01 0.1904 2.02 0.0076 3.02 0.0025 4.03 0.0003 ) constant fh-fs5 #( 1.00 0.2511 2.00 0.0017 3.01 0.0010 4.01 0.0004 ) constant fh-g5 #( 1.00 0.1029 1.99 0.0050 2.99 0.0007 3.99 0.0002 ) constant fh-gs5 \ ********************************************************** \ \ ********************************************************** #( 1.01 0.0025 1.99 0.0008 3.01 0.0057 4.02 0.0063 5.03 0.0268 6.04 0.0198 7.04 0.0157 8.03 0.0160 9.05 0.0056 10.05 0.0016 11.06 0.0059 12.09 0.0009 13.10 0.0023 14.08 0.0022 15.09 0.0011 16.10 0.0011 17.11 0.0012 18.16 0.0009 19.16 0.0008 20.15 0.0005 21.16 0.0002 22.15 0.0001 23.15 0.0001 ) constant fhf-as1 #( 1.03 0.0025 2.07 0.0054 5.15 0.0276 6.18 0.0379 7.21 0.0389 8.23 0.0176 9.26 0.0020 10.29 0.0039 11.24 0.0002 12.26 0.0010 13.28 0.0015 14.34 0.0010 15.37 0.0009 16.42 0.0010 17.47 0.0027 18.49 0.0015 19.52 0.0010 20.56 0.0005 21.57 0.0004 22.59 0.0004 23.60 0.0003 24.61 0.0003 25.65 0.0002 26.67 0.0002 27.66 0.0001 28.71 0.0002 29.75 0.0001 ) constant fhf-b1 #( 1.02 0.0023 2.03 0.0041 3.03 0.0059 4.05 0.0291 5.05 0.0280 6.06 0.0396 7.06 0.0428 8.07 0.0111 9.08 0.0018 10.10 0.0049 11.12 0.0052 12.12 0.0075 13.12 0.0021 14.15 0.0009 15.18 0.0008 16.21 0.0009 17.22 0.0012 18.23 0.0008 19.23 0.0003 20.24 0.0003 21.23 0.0002 22.22 0.0002 23.22 0.0002 24.25 0.0001 25.27 0.0002 26.27 0.0001 28.25 0.0001 30.29 0.0001 32.31 0.0001 ) constant fhf-c2 #( 1.03 0.0031 2.02 0.0111 3.02 0.0074 4.01 0.0370 5.01 0.0307 6.03 0.0330 7.03 0.0281 8.02 0.0089 9.02 0.0097 9.21 0.0016 10.03 0.0014 11.04 0.0044 12.03 0.0039 12.96 0.0004 14.09 0.0011 15.10 0.0006 16.10 0.0014 17.09 0.0011 18.09 0.0006 19.10 0.0005 20.10 0.0004 21.08 0.0002 22.10 0.0003 22.28 0.0002 23.07 0.0001 24.04 0.0002 25.09 0.0001 26.10 0.0001 27.10 0.0001 32.10 0.0001 ) constant fhf-cs2 #( 1.00 0.0154 2.01 0.0193 3.01 0.0257 4.00 0.0566 5.00 0.0570 6.01 0.0680 7.01 0.0222 8.03 0.0023 9.02 0.0036 10.05 0.0043 11.07 0.0037 12.07 0.0010 12.97 0.0005 13.99 0.0014 14.99 0.0022 15.98 0.0023 16.97 0.0011 17.96 0.0007 18.95 0.0004 19.12 0.0003 19.89 0.0002 20.92 0.0003 21.11 0.0002 21.92 0.0002 22.91 0.0002 23.88 0.0002 24.92 0.0002 25.89 0.0003 26.88 0.0003 27.84 0.0001 ) constant fhf-d2 #( 1.00 0.0204 2.02 0.0234 3.03 0.0132 4.04 0.0416 5.05 0.0425 6.04 0.0258 7.06 0.0086 8.07 0.0067 9.14 0.0009 10.17 0.0030 11.20 0.0008 12.09 0.0016 13.11 0.0015 14.12 0.0029 15.11 0.0028 16.11 0.0011 17.11 0.0006 18.09 0.0003 19.13 0.0004 19.29 0.0002 20.10 0.0002 21.13 0.0002 21.29 0.0002 22.26 0.0001 23.11 0.0003 24.11 0.0003 25.08 0.0002 26.10 0.0002 27.08 0.0002 28.10 0.0001 28.28 0.0001 ) constant fhf-ds2 #( 1.00 0.0097 1.99 0.0146 3.00 0.0159 4.00 0.0246 5.02 0.0137 6.06 0.0177 7.02 0.0017 8.05 0.0029 9.04 0.0058 10.06 0.0041 10.96 0.0009 12.03 0.0029 13.08 0.0021 14.12 0.0008 15.14 0.0002 16.11 0.0002 26.90 0.0001 ) constant fhf-e2 #( 1.00 0.0039 2.02 0.0070 3.04 0.0156 4.06 0.0113 5.08 0.0222 6.07 0.0065 7.07 0.0046 8.12 0.0018 9.13 0.0081 10.13 0.0014 11.17 0.0012 12.17 0.0014 13.21 0.0007 13.98 0.0005 14.24 0.0003 14.98 0.0003 15.96 0.0002 17.21 0.0001 18.97 0.0002 20.02 0.0001 21.05 0.0001 ) constant fhf-f2 #( 1.02 0.0030 2.03 0.0096 3.04 0.0372 4.06 0.0225 5.09 0.0048 6.17 0.0019 7.19 0.0014 8.20 0.0014 9.19 0.0023 10.22 0.0008 11.09 0.0003 12.23 0.0006 13.25 0.0004 14.25 0.0002 15.14 0.0001 16.19 0.0002 17.20 0.0002 18.24 0.0002 19.23 0.0001 20.27 0.0001 21.29 0.0001 23.26 0.0001 ) constant fhf-fs2 #( 1.03 0.0067 2.02 0.0055 3.06 0.0282 5.01 0.0043 5.20 0.0033 6.05 0.0006 7.09 0.0009 8.13 0.0070 9.17 0.0006 10.20 0.0010 11.23 0.0007 12.28 0.0002 13.16 0.0001 14.23 0.0001 ) constant fhf-g2 #( 0.99 0.0029 2.02 0.0054 3.01 0.0149 4.03 0.0101 5.03 0.0047 6.02 0.0035 7.02 0.0028 8.04 0.0026 9.03 0.0010 10.03 0.0003 11.07 0.0004 11.89 0.0001 12.98 0.0001 13.99 0.0002 ) constant fhf-gs2 #( 0.99 0.0020 2.00 0.0131 3.00 0.0085 4.01 0.0199 4.99 0.0044 5.98 0.0020 7.00 0.0029 8.01 0.0009 9.02 0.0010 9.99 0.0007 10.94 0.0003 ) constant fhf-a2 #( 1.00 0.0013 2.01 0.0042 3.01 0.0101 3.99 0.0132 4.98 0.0011 5.97 0.0007 6.96 0.0031 7.99 0.0009 9.10 0.0003 9.99 0.0003 10.92 0.0002 11.88 0.0002 12.85 0.0001 ) constant fhf-as2 #( 1.01 0.0038 2.00 0.0081 2.98 0.0138 3.96 0.0105 4.96 0.0021 5.95 0.0034 6.89 0.0013 7.91 0.0006 8.86 0.0005 9.87 0.0001 ) constant fhf-b2 #( 1.00 0.0033 2.01 0.0162 3.00 0.0168 4.00 0.0069 5.00 0.0033 6.01 0.0061 7.01 0.0006 8.01 0.0003 8.98 0.0003 9.97 0.0002 10.98 0.0001 ) constant fhf-c3 #( 1.01 0.0161 2.01 0.0404 3.01 0.0208 4.02 0.0039 5.02 0.0013 6.02 0.0041 7.02 0.0019 8.01 0.0011 9.01 0.0003 ) constant fhf-cs3 #( 1.01 0.0238 2.01 0.0582 3.02 0.0679 4.02 0.0022 5.03 0.0081 6.03 0.0024 7.03 0.0012 8.05 0.0010 9.05 0.0001 10.08 0.0001 ) constant fhf-d3 #( 1.00 0.0295 2.01 0.0519 3.02 0.0343 4.04 0.0119 5.05 0.0067 6.07 0.0011 7.08 0.0013 8.09 0.0004 ) constant fhf-ds3 #( 1.01 0.0251 2.04 0.0479 3.03 0.0741 4.04 0.0054 5.05 0.0049 6.04 0.0029 7.06 0.0021 8.10 0.0006 9.11 0.0004 10.10 0.0002 11.13 0.0002 ) constant fhf-e3 #( 1.02 0.0143 2.02 0.0453 3.04 0.0115 4.05 0.0021 5.08 0.0007 6.10 0.0007 7.07 0.0006 8.04 0.0001 ) constant fhf-f3 #( 1.01 0.0220 2.03 0.0843 3.04 0.0119 4.06 0.0062 5.09 0.0022 6.12 0.0016 7.14 0.0003 9.13 0.0001 ) constant fhf-fs3 #( 1.02 0.0145 2.03 0.0700 3.03 0.0010 5.13 0.0013 6.14 0.0007 7.14 0.0002 ) constant fhf-g3 #( 1.02 0.0273 2.03 0.0703 3.04 0.0176 4.07 0.0073 5.08 0.0021 6.09 0.0004 7.09 0.0002 8.09 0.0001 ) constant fhf-gs3 #( 1.00 0.0529 2.02 0.0982 3.02 0.0066 4.04 0.0034 5.05 0.0029 6.04 0.0003 7.03 0.0002 ) constant fhf-a3a #( 1.01 0.0274 2.01 0.0613 3.02 0.0056 4.03 0.0056 5.03 0.0024 6.03 0.0003 ) constant fhf-as3 #( 1.01 0.0468 2.01 0.0884 3.01 0.0246 4.02 0.0058 5.03 0.0016 6.03 0.0005 7.02 0.0002 8.01 0.0001 ) constant fhf-b3 #( 1.01 0.0972 2.01 0.0455 3.02 0.0442 4.03 0.0073 5.03 0.0017 6.03 0.0005 7.04 0.0008 8.05 0.0003 9.05 0.0001 ) constant fhf-c4 #( 1.01 0.1452 2.01 0.0382 3.02 0.0285 4.02 0.0080 5.02 0.0019 6.01 0.0002 7.03 0.0003 8.04 0.0002 ) constant fhf-cs4 #( 1.01 0.1930 2.02 0.0066 3.03 0.0070 4.05 0.0041 5.05 0.0016 6.07 0.0003 ) constant fhf-d4 #( 1.00 0.1433 2.01 0.0414 3.02 0.0101 4.03 0.0020 5.02 0.0002 6.03 0.0003 7.06 0.0001 ) constant fhf-ds4 #( 1.00 0.1373 2.01 0.0256 3.01 0.0164 4.02 0.0026 5.02 0.0014 6.02 0.0004 7.03 0.0002 ) constant fhf-e4 #( 1.01 0.1930 2.01 0.0192 3.02 0.0124 4.02 0.0030 5.03 0.0013 6.03 0.0006 7.03 0.0002 ) constant fhf-f4 #( 1.01 0.2352 2.01 0.0485 3.02 0.0135 4.03 0.0035 5.03 0.0010 6.04 0.0004 ) constant fhf-fs4 #( 1.01 0.1991 2.03 0.0655 3.04 0.0065 4.04 0.0015 5.06 0.0006 6.07 0.0002 ) constant fhf-g4 #( 1.01 0.2177 2.02 0.0422 3.03 0.0038 4.05 0.0014 5.06 0.0006 ) constant fhf-gs4 #( 1.01 0.3779 2.02 0.0161 3.03 0.0026 4.04 0.0009 5.05 0.0005 ) constant fhf-a4 #( 1.00 0.1879 2.01 0.0205 3.02 0.0006 4.03 0.0006 ) constant fhf-as4 #( 0.99 0.2910 1.99 0.0363 2.99 0.0019 3.99 0.0001 4.98 0.0001 ) constant fhf-b4 #( 1.00 0.0690 2.01 0.0086 3.01 0.0002 4.00 0.0002 ) constant fhf-c5 #( 1.01 0.0872 2.02 0.0247 3.03 0.0008 4.05 0.0002 ) constant fhf-cs5 #( 1.01 0.0213 2.02 0.0275 3.03 0.0031 4.04 0.0008 5.05 0.0002 6.07 0.0001 ) constant fhf-d5 #( 1.01 0.1852 2.01 0.0224 3.01 0.0043 4.02 0.0006 5.03 0.0001 ) constant fhf-ds5 #( 1.01 0.1063 2.02 0.0144 3.03 0.0018 4.04 0.0006 5.05 0.0001 ) constant fhf-e5 #( 1.02 0.1058 2.04 0.0062 3.06 0.0023 4.08 0.0005 ) constant fhf-f5 #( 1.01 0.1683 2.03 0.0099 3.04 0.0026 4.05 0.0004 5.07 0.0003 ) constant fhf-fs5 #( 1.01 0.3271 2.02 0.0090 3.03 0.0022 4.04 0.0007 ) constant fhf-g5 \ ********************************************************** \ flute \ ********************************************************** #( 1.01 0.0602 2.02 0.0954 3.03 0.0270 4.03 0.0199 5.05 0.0177 6.06 0.0104 7.07 0.0040 8.08 0.0040 9.08 0.0035 10.10 0.0017 11.10 0.0009 12.12 0.0004 13.11 0.0002 14.13 0.0006 15.14 0.0003 17.15 0.0002 18.16 0.0001 ) constant fl-c4 #( 1.01 0.0672 2.01 0.0689 3.02 0.0604 4.02 0.0410 5.02 0.0130 6.03 0.0040 7.03 0.0210 8.03 0.0078 9.04 0.0010 10.07 0.0002 11.05 0.0005 12.05 0.0008 13.05 0.0004 14.06 0.0002 15.07 0.0001 19.08 0.0001 ) constant fl-cs4 #( 1.01 0.0747 2.01 0.2106 3.01 0.0522 4.02 0.0208 5.01 0.0138 6.02 0.0024 7.03 0.0071 8.03 0.0038 8.17 0.0002 8.74 0.0001 10.03 0.0004 11.04 0.0014 12.03 0.0001 13.06 0.0002 14.05 0.0003 15.06 0.0001 16.07 0.0001 17.06 0.0002 18.06 0.0002 ) constant fl-d4 #( 1.00 0.0256 2.00 0.1167 3.00 0.0241 4.01 0.0159 5.01 0.0200 6.00 0.0167 7.01 0.0069 8.04 0.0004 9.00 0.0009 10.01 0.0010 11.00 0.0004 12.00 0.0003 13.00 0.0002 14.01 0.0002 16.00 0.0002 17.01 0.0002 ) constant fl-ds4 #( 1.00 0.0572 2.01 0.1769 3.01 0.0622 4.00 0.0323 5.01 0.0210 6.01 0.0163 7.02 0.0068 8.01 0.0007 8.13 0.0002 8.39 0.0001 10.02 0.0011 11.02 0.0004 12.02 0.0003 15.03 0.0002 16.03 0.0001 17.04 0.0001 18.04 0.0001 ) constant fl-e4 #( 1.01 0.0438 2.01 0.0964 3.01 0.0569 4.01 0.0096 5.01 0.0164 6.01 0.0194 7.02 0.0024 8.01 0.0005 9.03 0.0007 10.04 0.0005 12.05 0.0002 13.04 0.0001 14.05 0.0002 ) constant fl-f4 #( 1.00 0.0952 2.00 0.1432 3.01 0.0299 4.01 0.0371 5.02 0.0189 6.02 0.0092 7.03 0.0060 8.03 0.0003 9.04 0.0025 10.04 0.0006 11.04 0.0003 13.05 0.0002 14.06 0.0002 ) constant fl-fs4 #( 1.00 0.2831 2.01 0.1781 3.01 0.0370 4.02 0.0191 5.02 0.0313 6.02 0.0048 7.04 0.0007 8.03 0.0022 9.04 0.0015 9.13 0.0001 10.04 0.0001 11.05 0.0002 12.05 0.0002 14.07 0.0001 15.06 0.0001 ) constant fl-g4 #( 1.00 0.2598 2.00 0.2241 3.01 0.0407 4.01 0.0354 5.01 0.0398 6.01 0.0111 7.03 0.0007 8.01 0.0030 9.01 0.0018 10.02 0.0002 12.02 0.0004 13.02 0.0001 14.03 0.0002 15.03 0.0001 ) constant fl-gs4 #( 1.00 0.2580 2.01 0.1605 3.00 0.0236 4.01 0.0281 5.02 0.0047 6.02 0.0024 7.02 0.0010 8.02 0.0027 9.02 0.0004 10.03 0.0002 11.03 0.0003 12.04 0.0001 13.04 0.0002 14.04 0.0002 ) constant fl-a4 #( 1.01 0.1855 2.01 0.1041 3.01 0.0480 4.02 0.0416 5.02 0.0059 6.02 0.0016 7.03 0.0004 8.03 0.0016 9.03 0.0003 10.04 0.0004 11.05 0.0003 16.07 0.0002 ) constant fl-as4 #( 1.01 0.0564 2.01 0.1996 3.02 0.0219 4.02 0.0108 5.03 0.0183 6.04 0.0005 7.04 0.0009 8.05 0.0014 10.06 0.0006 11.07 0.0003 ) constant fl-b4 #( 1.01 0.0245 2.02 0.1674 3.04 0.0228 4.05 0.0229 5.06 0.0087 6.09 0.0004 7.09 0.0004 8.10 0.0003 9.11 0.0002 10.14 0.0002 11.15 0.0001 ) constant fl-c5 #( 1.00 0.0885 2.01 0.0661 3.01 0.0281 4.02 0.0068 5.02 0.0038 6.02 0.0010 7.02 0.0008 8.03 0.0007 9.03 0.0005 10.04 0.0002 11.04 0.0003 ) constant fl-cs5 #( 1.01 0.3830 2.01 0.1043 3.01 0.0372 4.02 0.0175 5.03 0.0035 6.03 0.0011 7.04 0.0010 8.04 0.0004 9.04 0.0002 10.05 0.0001 ) constant fl-d5 #( 1.00 0.2294 2.01 0.0606 3.01 0.0238 4.01 0.0050 5.01 0.0041 6.02 0.0007 7.02 0.0007 8.02 0.0006 10.03 0.0002 12.03 0.0001 ) constant fl-ds5 #( 1.01 0.3759 2.03 0.0529 3.03 0.0595 4.05 0.0010 5.06 0.0077 6.07 0.0008 7.09 0.0007 8.09 0.0005 9.11 0.0001 10.12 0.0002 12.14 0.0001 ) constant fl-e5 #( 1.01 0.1982 2.02 0.0204 3.02 0.0554 4.03 0.0064 5.04 0.0040 6.05 0.0016 7.06 0.0007 8.07 0.0006 9.07 0.0001 10.08 0.0001 12.10 0.0001 ) constant fl-f5 #( 1.01 0.3241 2.02 0.0548 3.03 0.0082 4.04 0.0022 5.05 0.0038 6.06 0.0004 7.07 0.0009 8.09 0.0001 9.09 0.0003 10.10 0.0001 ) constant fl-fs5 #( 1.01 0.4049 2.01 0.0301 3.02 0.0229 4.03 0.0047 5.04 0.0029 6.05 0.0014 7.05 0.0009 8.06 0.0003 9.07 0.0002 10.07 0.0002 11.09 0.0001 12.09 0.0001 ) constant fl-g5 #( 1.00 0.5433 2.01 0.0536 3.01 0.0411 4.02 0.0074 5.02 0.0014 6.02 0.0011 7.03 0.0004 8.03 0.0003 9.04 0.0001 ) constant fl-gs5 #( 1.01 0.3063 2.01 0.0346 3.02 0.0102 4.03 0.0031 5.03 0.0007 6.04 0.0010 7.03 0.0003 8.06 0.0001 9.05 0.0002 11.06 0.0002 ) constant fl-a5 #( 1.01 0.1962 2.03 0.0355 3.04 0.0128 4.06 0.0020 5.07 0.0021 6.08 0.0003 7.10 0.0003 8.11 0.0002 ) constant fl-as5 #( 1.01 0.3829 2.02 0.0120 3.03 0.0037 4.04 0.0030 5.05 0.0016 6.06 0.0006 7.07 0.0002 8.08 0.0004 9.09 0.0001 ) constant fl-b5 #( 1.01 0.3072 2.02 0.0248 3.04 0.0012 4.05 0.0006 5.06 0.0011 6.07 0.0009 7.08 0.0003 8.10 0.0001 10.12 0.0001 ) constant fl-c6 #( 1.01 0.1262 2.02 0.0030 3.03 0.0012 4.04 0.0005 5.06 0.0010 6.07 0.0002 7.08 0.0004 8.09 0.0002 ) constant fl-cs6 #( 1.01 0.3050 2.03 0.0071 3.04 0.0107 4.06 0.0005 5.07 0.0015 6.08 0.0002 7.10 0.0003 8.11 0.0002 9.13 0.0001 ) constant fl-d6 #( 1.02 0.0954 2.05 0.0025 3.06 0.0047 4.09 0.0007 5.11 0.0017 6.13 0.0001 7.15 0.0002 ) constant fl-ds6 #( 1.02 0.2864 2.05 0.0057 3.08 0.0023 5.13 0.0007 6.16 0.0001 8.21 0.0001 ) constant fl-e6 #( 1.03 0.0675 2.05 0.0049 3.08 0.0024 5.13 0.0008 6.16 0.0002 7.18 0.0002 8.21 0.0001 ) constant fl-f6 #( 1.02 0.2553 2.05 0.0044 3.07 0.0032 5.12 0.0007 6.14 0.0002 8.19 0.0001 ) constant fl-fs6 #( 1.02 0.1190 2.05 0.0069 3.07 0.0046 5.12 0.0010 6.14 0.0001 7.17 0.0007 7.26 0.0001 ) constant fl-g6 #( 1.02 0.3872 2.05 0.0093 3.07 0.0051 5.12 0.0008 6.15 0.0001 7.17 0.0002 7.18 0.0001 ) constant fl-gs6 #( 1.02 0.2920 2.04 0.0122 3.06 0.0052 4.08 0.0007 5.10 0.0003 6.31 0.0002 7.15 0.0003 ) constant fl-a6 #( 1.02 0.5687 2.04 0.0090 3.06 0.0075 4.08 0.0007 5.10 0.0010 6.15 0.0002 6.21 0.0002 6.40 0.0001 6.47 0.0001 ) constant fl-as6 #( 1.03 0.2752 2.06 0.0061 3.09 0.0039 5.14 0.0002 5.86 0.0002 6.18 0.0001 6.24 0.0001 6.45 0.0001 ) constant fl-b6 #( 1.04 0.2720 2.07 0.0046 5.18 0.0003 5.40 0.0002 6.02 0.0002 ) constant fl-c7 #( 1.03 0.3752 2.06 0.0156 5.16 0.0007 5.20 0.0003 5.40 0.0001 5.41 0.0001 5.57 0.0001 ) constant fl-cs7 #( 1.04 0.2861 2.07 0.0147 5.18 0.0012 5.27 0.0002 5.30 0.0001 ) constant fl-d7 \ ********************************************************** \ oboe \ ********************************************************** #( 1.00 0.0504 2.00 0.0724 2.99 0.1036 3.99 0.1215 4.99 0.1360 5.99 0.0852 6.98 0.0593 7.97 0.0230 8.98 0.0077 9.97 0.0063 10.97 0.0016 11.96 0.0008 12.97 0.0017 13.97 0.0017 14.96 0.0020 15.96 0.0007 16.96 0.0006 17.96 0.0002 21.95 0.0001 22.95 0.0001 23.94 0.0002 24.94 0.0002 25.94 0.0001 ) constant ob-as3 #( 0.99 0.0587 1.99 0.0820 2.98 0.0673 3.98 0.1069 4.97 0.1336 5.97 0.0948 6.96 0.0455 7.96 0.0070 8.95 0.0017 9.95 0.0023 10.95 0.0063 11.93 0.0031 12.93 0.0021 13.92 0.0009 14.92 0.0005 15.92 0.0003 16.89 0.0001 21.88 0.0001 23.88 0.0001 ) constant ob-b3 #( 1.00 0.0784 2.00 0.0494 2.99 0.0668 3.99 0.0785 4.99 0.1406 5.99 0.0747 6.99 0.0460 7.98 0.0147 8.98 0.0115 9.97 0.0083 10.98 0.0058 11.98 0.0059 12.97 0.0027 13.98 0.0010 14.96 0.0006 15.97 0.0002 16.96 0.0001 17.96 0.0002 19.95 0.0001 20.96 0.0002 21.95 0.0001 ) constant ob-c4 #( 1.00 0.0801 2.00 0.0526 2.99 0.0568 3.99 0.0713 4.99 0.1811 5.99 0.0721 6.99 0.0491 7.98 0.0201 8.98 0.0128 9.98 0.0132 10.98 0.0104 11.98 0.0081 12.97 0.0055 13.97 0.0026 14.97 0.0010 15.97 0.0003 16.97 0.0004 17.96 0.0003 18.97 0.0004 19.95 0.0006 20.96 0.0003 21.96 0.0002 ) constant ob-cs4 #( 1.00 0.0775 2.00 0.0853 3.01 0.0538 4.01 0.0600 5.00 0.1853 6.01 0.0714 7.01 0.0247 8.01 0.0265 9.01 0.0028 10.01 0.0116 11.02 0.0078 12.02 0.0060 13.01 0.0036 14.02 0.0010 15.03 0.0005 16.01 0.0002 17.02 0.0002 18.01 0.0004 19.02 0.0004 20.02 0.0002 21.02 0.0001 ) constant ob-d4 #( 1.00 0.0922 1.99 0.0922 2.99 0.0912 3.99 0.0337 4.98 0.1696 5.97 0.0481 6.98 0.0184 7.97 0.0104 8.96 0.0185 9.96 0.0147 10.96 0.0057 11.95 0.0039 12.95 0.0012 13.94 0.0006 14.94 0.0009 15.94 0.0005 16.93 0.0005 17.93 0.0003 18.93 0.0001 19.92 0.0001 ) constant ob-ds4 #( 1.00 0.0970 2.01 0.0554 3.01 0.0624 4.02 0.1806 5.02 0.1392 6.02 0.0367 7.03 0.0165 8.04 0.0102 9.04 0.0159 10.04 0.0077 11.04 0.0092 12.05 0.0027 13.06 0.0004 14.06 0.0007 15.06 0.0003 16.07 0.0006 17.07 0.0003 18.08 0.0003 19.08 0.0001 20.09 0.0002 ) constant ob-e4 #( 1.00 0.0988 2.01 0.0364 3.00 0.0573 4.01 0.2291 5.01 0.0802 6.02 0.0188 7.02 0.0160 8.02 0.0143 9.02 0.0152 10.02 0.0140 11.03 0.0054 12.01 0.0003 13.03 0.0012 14.03 0.0008 15.04 0.0008 16.04 0.0006 17.04 0.0006 18.04 0.0003 19.05 0.0001 ) constant ob-f4 #( 1.01 0.0340 2.01 0.0618 3.02 0.0923 4.03 0.1479 5.03 0.1058 6.04 0.0281 7.05 0.0071 8.05 0.0157 9.06 0.0018 10.07 0.0014 11.07 0.0005 12.08 0.0013 13.09 0.0012 14.10 0.0005 15.10 0.0003 16.11 0.0005 17.12 0.0002 ) constant ob-fs4 #( 1.01 0.0606 2.01 0.0774 3.02 0.0552 4.03 0.0700 5.04 0.0194 6.04 0.0066 7.05 0.0147 8.06 0.0134 9.07 0.0055 10.08 0.0035 11.08 0.0004 12.10 0.0004 13.10 0.0008 14.11 0.0011 15.10 0.0004 ) constant ob-g4 #( 1.01 0.0573 2.01 0.0346 3.03 0.0608 4.03 0.0675 5.04 0.0643 6.05 0.0193 7.06 0.0125 8.07 0.0109 9.07 0.0010 10.09 0.0003 11.09 0.0016 12.10 0.0015 13.11 0.0006 14.11 0.0003 15.13 0.0002 16.13 0.0002 ) constant ob-gs4 #( 1.00 0.0923 2.00 0.0358 3.00 0.0726 4.00 0.2111 5.00 0.0316 5.99 0.0016 7.00 0.0080 8.00 0.0075 9.00 0.0031 10.01 0.0007 11.01 0.0008 12.00 0.0005 13.00 0.0003 14.01 0.0005 15.01 0.0001 ) constant ob-a4 #( 1.00 0.0753 2.00 0.0693 3.00 0.3731 4.01 0.0810 5.01 0.0245 6.00 0.0142 7.00 0.0061 8.01 0.0025 9.01 0.0004 10.01 0.0005 11.01 0.0005 12.02 0.0005 13.02 0.0003 ) constant ob-as4 #( 1.00 0.0618 2.01 0.0377 3.02 0.0642 4.02 0.0401 5.02 0.0165 6.03 0.0176 7.03 0.0079 8.04 0.0016 9.04 0.0003 10.06 0.0003 11.05 0.0006 12.06 0.0003 13.06 0.0001 ) constant ob-b4 #( 1.01 0.0484 2.02 0.0490 3.02 0.0364 4.03 0.0166 5.03 0.0172 6.04 0.0261 7.05 0.0120 8.06 0.0021 9.06 0.0035 10.07 0.0021 11.08 0.0008 12.08 0.0003 ) constant ob-c5 #( 1.01 0.1071 2.02 0.0487 3.03 0.1175 4.04 0.0329 5.05 0.0231 6.06 0.0136 7.07 0.0047 8.07 0.0009 9.09 0.0011 10.10 0.0016 11.10 0.0010 12.12 0.0002 ) constant ob-cs5 #( 1.01 0.1893 2.01 0.0986 3.02 0.1665 4.02 0.0326 5.03 0.0275 6.04 0.0155 7.04 0.0029 8.05 0.0013 9.06 0.0016 10.07 0.0010 11.07 0.0004 12.08 0.0001 ) constant ob-d5 #( 1.00 0.2003 2.00 0.0265 3.00 0.1047 4.00 0.0138 5.00 0.0391 6.00 0.0094 6.99 0.0023 8.00 0.0018 8.99 0.0011 9.99 0.0006 10.99 0.0002 11.99 0.0001 ) constant ob-ds5 #( 1.00 0.0906 2.00 0.4215 3.00 0.1046 3.99 0.0081 4.99 0.0118 5.99 0.0054 6.99 0.0005 7.99 0.0014 8.99 0.0005 9.99 0.0002 ) constant ob-e5 #( 1.00 0.0657 2.00 0.4134 2.99 0.0463 3.99 0.0144 4.99 0.0277 5.99 0.0047 6.98 0.0005 7.98 0.0004 8.98 0.0003 ) constant ob-f5 #( 1.01 0.0957 2.03 0.2943 3.04 0.0855 4.06 0.0568 5.07 0.0247 6.08 0.0013 7.10 0.0024 8.12 0.0011 9.13 0.0006 10.15 0.0002 11.16 0.0001 12.17 0.0001 ) constant ob-fs5 #( 1.01 0.0975 2.02 0.1012 3.04 0.0543 4.05 0.0298 5.06 0.0083 6.07 0.0026 7.08 0.0017 8.09 0.0003 9.11 0.0001 ) constant ob-g5 #( 1.01 0.0400 2.01 0.0481 3.02 0.0403 4.02 0.0169 5.03 0.0002 6.04 0.0030 7.04 0.0008 ) constant ob-gs5 #( 1.01 0.0725 2.02 0.1474 3.03 0.0327 4.04 0.0281 5.05 0.0013 6.06 0.0028 7.07 0.0004 ) constant ob-a5 #( 1.00 0.0837 2.00 0.1039 3.00 0.0366 4.01 0.0118 5.01 0.0021 6.01 0.0012 ) constant ob-as5 #( 1.02 0.0812 2.04 0.0709 3.06 0.0658 4.08 0.0099 5.10 0.0069 6.12 0.0007 7.14 0.0001 8.16 0.0001 ) constant ob-b5 #( 1.01 0.0799 2.02 0.0161 3.02 0.0476 4.03 0.0084 5.04 0.0029 6.05 0.0002 ) constant ob-c6 #( 1.01 0.2331 2.02 0.1151 3.03 0.0163 4.04 0.0013 5.05 0.0004 6.07 0.0003 ) constant ob-cs6 #( 1.02 0.2469 2.03 0.0288 3.05 0.0144 4.06 0.0012 5.08 0.0008 ) constant ob-d6 #( 1.00 0.2770 2.00 0.0028 3.00 0.0095 4.00 0.0042 5.00 0.0006 5.99 0.0002 ) constant ob-ds6 #( 1.00 0.3019 2.01 0.0125 3.01 0.0049 4.02 0.0008 5.02 0.0001 6.02 0.0001 ) constant ob-e6 #( 1.01 0.0898 2.01 0.0089 3.02 0.0067 4.02 0.0010 5.03 0.0002 6.03 0.0001 ) constant ob-f6 #( 1.01 0.1330 2.03 0.0090 3.05 0.0031 4.06 0.0001 ) constant ob-fs6 #( 1.00 0.1046 1.99 0.0228 2.99 0.0004 3.98 0.0001 ) constant ob-g6 \ ********************************************************** \ piano \ ********************************************************** #( 1.97 0.0326 2.99 0.0086 3.95 0.0163 4.97 0.0178 5.98 0.0177 6.95 0.0315 8.02 0.0001 8.94 0.0076 9.96 0.0134 10.99 0.0284 11.98 0.0229 13.02 0.0229 13.89 0.0010 15.06 0.0090 16.00 0.0003 17.08 0.0078 18.16 0.0064 19.18 0.0129 20.21 0.0085 21.27 0.0225 22.32 0.0061 23.41 0.0102 24.48 0.0005 25.56 0.0016 26.64 0.0018 27.70 0.0113 28.80 0.0111 29.91 0.0158 31.06 0.0093 32.17 0.0017 33.32 0.0002 34.42 0.0018 35.59 0.0027 36.74 0.0055 37.90 0.0037 39.06 0.0064 40.25 0.0033 41.47 0.0014 42.53 0.0004 43.89 0.0010 45.12 0.0039 46.33 0.0039 47.64 0.0009 48.88 0.0016 50.13 0.0006 51.37 0.0010 52.70 0.0002 54.00 0.0004 55.30 0.0008 56.60 0.0025 57.96 0.0010 59.30 0.0012 60.67 0.0011 61.99 0.0003 62.86 0.0001 64.36 0.0005 64.86 0.0001 66.26 0.0004 67.70 0.0006 68.94 0.0002 70.10 0.0001 70.58 0.0002 72.01 0.0007 73.53 0.0006 75.00 0.0002 77.03 0.0005 78.00 0.0002 79.57 0.0006 81.16 0.0005 82.70 0.0005 84.22 0.0003 85.41 0.0002 87.46 0.0001 90.30 0.0001 94.02 0.0001 95.26 0.0002 109.39 0.0003 ) constant p-c1 #( 1.98 0.0194 2.99 0.0210 3.97 0.0276 4.96 0.0297 5.96 0.0158 6.99 0.0207 8.01 0.0009 9.00 0.0101 10.00 0.0297 11.01 0.0289 12.02 0.0211 13.04 0.0127 14.07 0.0061 15.08 0.0174 16.13 0.0009 17.12 0.0093 18.16 0.0117 19.21 0.0122 20.29 0.0108 21.30 0.0077 22.38 0.0132 23.46 0.0073 24.14 0.0002 25.58 0.0026 26.69 0.0035 27.77 0.0053 28.88 0.0024 30.08 0.0027 31.13 0.0075 32.24 0.0027 33.36 0.0004 34.42 0.0004 35.64 0.0019 36.78 0.0037 38.10 0.0009 39.11 0.0027 40.32 0.0010 41.51 0.0013 42.66 0.0019 43.87 0.0007 45.13 0.0017 46.35 0.0019 47.65 0.0021 48.89 0.0014 50.18 0.0023 51.42 0.0015 52.73 0.0002 54.00 0.0005 55.34 0.0006 56.60 0.0010 57.96 0.0016 58.86 0.0005 59.30 0.0004 60.75 0.0005 62.22 0.0003 63.55 0.0005 64.82 0.0003 66.24 0.0003 67.63 0.0011 69.09 0.0007 70.52 0.0004 72.00 0.0005 73.50 0.0008 74.95 0.0003 77.13 0.0013 78.02 0.0002 79.48 0.0004 82.59 0.0004 84.10 0.0003 ) constant p-cs1 #( 2.00 0.0313 2.99 0.0109 4.00 0.0215 5.00 0.0242 5.98 0.0355 7.01 0.0132 8.01 0.0009 9.01 0.0071 10.00 0.0258 11.03 0.0221 12.02 0.0056 13.06 0.0196 14.05 0.0160 15.11 0.0107 16.11 0.0003 17.14 0.0111 18.21 0.0085 19.23 0.0010 20.28 0.0048 21.31 0.0128 22.36 0.0051 23.41 0.0041 24.05 0.0006 25.54 0.0019 26.62 0.0028 27.72 0.0034 28.82 0.0062 29.89 0.0039 30.98 0.0058 32.08 0.0011 33.21 0.0002 34.37 0.0008 35.46 0.0018 36.62 0.0036 37.77 0.0018 38.92 0.0042 40.07 0.0037 41.23 0.0011 42.67 0.0003 43.65 0.0018 44.68 0.0025 45.99 0.0044 47.21 0.0051 48.40 0.0044 49.67 0.0005 50.88 0.0019 52.15 0.0003 53.42 0.0008 54.69 0.0010 55.98 0.0005 57.26 0.0013 58.53 0.0027 59.83 0.0011 61.21 0.0027 62.54 0.0003 63.78 0.0003 65.20 0.0001 66.60 0.0006 67.98 0.0008 69.37 0.0019 70.73 0.0007 72.14 0.0004 73.62 0.0002 74.40 0.0003 76.52 0.0006 77.97 0.0002 79.49 0.0004 80.77 0.0003 81.00 0.0001 82.47 0.0005 83.97 0.0001 87.27 0.0002 ) constant p-d1 #( 2.00 0.0257 2.99 0.0142 3.97 0.0202 4.95 0.0148 5.95 0.0420 6.95 0.0037 7.94 0.0004 8.94 0.0172 9.95 0.0191 10.96 0.0115 11.97 0.0059 12.98 0.0140 14.00 0.0178 15.03 0.0121 16.09 0.0002 17.07 0.0066 18.08 0.0033 19.15 0.0022 20.18 0.0057 21.22 0.0077 22.29 0.0037 23.33 0.0066 24.97 0.0002 25.49 0.0019 26.55 0.0042 27.61 0.0043 28.73 0.0038 29.81 0.0084 30.91 0.0040 32.03 0.0025 33.14 0.0005 34.26 0.0003 35.38 0.0019 36.56 0.0037 37.68 0.0049 38.86 0.0036 40.11 0.0011 41.28 0.0008 42.50 0.0004 43.60 0.0002 44.74 0.0022 45.99 0.0050 47.20 0.0009 48.40 0.0036 49.68 0.0004 50.92 0.0009 52.17 0.0005 53.46 0.0007 54.76 0.0006 56.06 0.0005 57.34 0.0011 58.67 0.0005 59.95 0.0015 61.37 0.0008 62.72 0.0004 65.42 0.0009 66.96 0.0003 68.18 0.0003 69.78 0.0003 71.21 0.0004 72.45 0.0002 74.22 0.0003 75.44 0.0001 76.53 0.0003 78.31 0.0004 79.83 0.0003 80.16 0.0001 81.33 0.0003 82.44 0.0001 83.17 0.0002 84.81 0.0003 85.97 0.0003 89.08 0.0001 90.70 0.0002 92.30 0.0002 95.59 0.0002 97.22 0.0003 98.86 0.0001 108.37 0.0001 125.54 0.0001 ) constant p-ds1 #( 1.99 0.0650 3.03 0.0040 4.03 0.0059 5.02 0.0090 5.97 0.0227 6.98 0.0050 8.04 0.0020 9.00 0.0082 9.96 0.0078 11.01 0.0056 12.01 0.0095 13.02 0.0050 14.04 0.0093 15.08 0.0064 16.14 0.0017 17.06 0.0020 18.10 0.0025 19.14 0.0023 20.18 0.0015 21.24 0.0032 22.29 0.0029 23.32 0.0014 24.37 0.0005 25.43 0.0030 26.50 0.0022 27.60 0.0027 28.64 0.0024 29.76 0.0035 30.81 0.0136 31.96 0.0025 33.02 0.0003 34.13 0.0005 35.25 0.0007 36.40 0.0014 37.51 0.0020 38.64 0.0012 39.80 0.0019 40.97 0.0004 42.09 0.0003 43.24 0.0003 44.48 0.0002 45.65 0.0024 46.86 0.0005 48.07 0.0013 49.27 0.0008 50.49 0.0006 52.95 0.0001 54.23 0.0005 55.45 0.0004 56.73 0.0001 58.03 0.0003 59.29 0.0002 60.59 0.0003 62.04 0.0002 65.89 0.0002 67.23 0.0002 68.61 0.0002 69.97 0.0004 71.36 0.0005 85.42 0.0001 ) constant p-e1 #( 1.98 0.0256 2.96 0.0158 3.95 0.0310 4.94 0.0411 5.95 0.0238 6.94 0.0152 7.93 0.0011 8.95 0.0185 9.92 0.0166 10.93 0.0306 11.94 0.0258 12.96 0.0202 13.97 0.0403 14.95 0.0228 15.93 0.0005 17.01 0.0072 18.02 0.0034 19.06 0.0028 20.08 0.0124 21.13 0.0137 22.16 0.0102 23.19 0.0058 23.90 0.0013 25.30 0.0039 26.36 0.0039 27.41 0.0025 28.47 0.0071 29.64 0.0031 30.60 0.0027 31.71 0.0021 32.84 0.0003 33.82 0.0002 35.07 0.0019 36.09 0.0054 37.20 0.0038 38.33 0.0024 39.47 0.0055 40.55 0.0016 41.77 0.0006 42.95 0.0002 43.27 0.0018 44.03 0.0006 45.25 0.0019 46.36 0.0033 47.50 0.0024 48.87 0.0012 50.03 0.0016 51.09 0.0004 53.52 0.0017 54.74 0.0012 56.17 0.0003 57.40 0.0011 58.42 0.0020 59.70 0.0007 61.29 0.0008 62.56 0.0003 63.48 0.0002 64.83 0.0002 66.12 0.0012 67.46 0.0017 68.81 0.0003 69.13 0.0003 70.53 0.0002 71.84 0.0001 73.28 0.0002 75.52 0.0010 76.96 0.0005 77.93 0.0003 78.32 0.0003 79.73 0.0003 81.69 0.0002 82.52 0.0001 84.01 0.0001 84.61 0.0002 86.88 0.0001 88.36 0.0002 89.85 0.0002 91.35 0.0003 92.86 0.0002 93.40 0.0001 105.28 0.0002 106.22 0.0002 107.45 0.0001 108.70 0.0003 122.08 0.0002 ) constant p-f1 #( 1.97 0.0264 2.97 0.0211 3.98 0.0234 4.98 0.0307 5.96 0.0085 6.94 0.0140 7.93 0.0005 8.96 0.0112 9.96 0.0209 10.98 0.0194 11.98 0.0154 12.99 0.0274 13.99 0.0127 15.01 0.0101 15.99 0.0002 17.04 0.0011 18.08 0.0032 19.14 0.0028 20.12 0.0054 21.20 0.0053 22.13 0.0028 23.22 0.0030 24.32 0.0006 25.24 0.0004 26.43 0.0028 27.53 0.0048 28.52 0.0039 29.54 0.0047 30.73 0.0044 31.82 0.0007 32.94 0.0008 34.04 0.0012 35.13 0.0018 36.29 0.0007 37.35 0.0075 38.51 0.0045 39.66 0.0014 40.90 0.0004 41.90 0.0002 43.08 0.0002 44.24 0.0017 45.36 0.0013 46.68 0.0020 47.79 0.0015 48.98 0.0010 50.21 0.0012 51.34 0.0001 53.82 0.0003 55.09 0.0004 56.23 0.0005 57.53 0.0004 58.79 0.0005 59.30 0.0002 60.03 0.0002 61.40 0.0003 62.84 0.0001 66.64 0.0001 67.97 0.0001 69.33 0.0001 70.68 0.0001 73.57 0.0002 75.76 0.0002 76.45 0.0001 79.27 0.0001 80.44 0.0002 81.87 0.0002 ) constant p-fs1 #( 2.00 0.0311 2.99 0.0086 3.99 0.0266 4.97 0.0123 5.98 0.0235 6.97 0.0161 7.97 0.0008 8.96 0.0088 9.96 0.0621 10.99 0.0080 11.99 0.0034 12.99 0.0300 14.03 0.0228 15.04 0.0105 16.03 0.0004 17.06 0.0036 18.09 0.0094 18.95 0.0009 20.17 0.0071 21.21 0.0161 22.25 0.0106 23.28 0.0104 24.33 0.0008 25.38 0.0030 26.46 0.0035 27.50 0.0026 28.59 0.0028 29.66 0.0128 30.75 0.0139 31.81 0.0038 32.93 0.0006 34.04 0.0004 35.16 0.0005 36.25 0.0023 37.35 0.0012 38.46 0.0021 39.59 0.0035 40.71 0.0006 41.86 0.0007 42.42 0.0001 43.46 0.0003 44.17 0.0032 45.29 0.0013 46.57 0.0004 47.72 0.0011 48.79 0.0005 50.11 0.0005 51.29 0.0003 52.47 0.0002 53.68 0.0004 55.02 0.0005 56.18 0.0003 57.41 0.0003 58.75 0.0007 59.33 0.0009 60.00 0.0004 61.34 0.0001 64.97 0.0003 65.20 0.0002 66.48 0.0002 67.83 0.0002 68.90 0.0003 70.25 0.0003 71.59 0.0002 73.68 0.0001 75.92 0.0001 77.08 0.0002 78.45 0.0002 81.56 0.0002 82.99 0.0001 88.39 0.0001 ) constant p-g1 #( 0.97 0.0059 1.98 0.0212 2.99 0.0153 3.99 0.0227 4.96 0.0215 5.97 0.0153 6.98 0.0085 7.98 0.0007 8.97 0.0179 9.98 0.0512 10.98 0.0322 12.00 0.0098 13.02 0.0186 14.00 0.0099 15.05 0.0109 15.88 0.0011 17.07 0.0076 18.11 0.0071 19.12 0.0045 20.16 0.0038 21.23 0.0213 22.27 0.0332 23.34 0.0082 24.34 0.0014 25.42 0.0024 26.47 0.0012 27.54 0.0014 28.60 0.0024 29.72 0.0026 30.10 0.0008 31.91 0.0021 32.13 0.0011 33.02 0.0007 34.09 0.0014 35.17 0.0007 36.27 0.0024 37.39 0.0029 38.58 0.0014 39.65 0.0017 40.95 0.0012 41.97 0.0004 42.43 0.0002 43.49 0.0001 44.31 0.0012 45.42 0.0031 46.62 0.0017 47.82 0.0013 49.14 0.0013 50.18 0.0010 51.54 0.0003 53.90 0.0006 55.06 0.0010 56.31 0.0003 57.63 0.0001 59.02 0.0003 60.09 0.0004 60.35 0.0004 61.62 0.0009 63.97 0.0001 65.19 0.0001 65.54 0.0002 66.92 0.0002 67.94 0.0002 69.17 0.0003 69.60 0.0004 70.88 0.0002 72.24 0.0002 76.12 0.0001 78.94 0.0001 81.75 0.0001 82.06 0.0001 83.53 0.0001 90.29 0.0002 91.75 0.0001 92.09 0.0002 93.28 0.0001 97.07 0.0001 ) constant p-gs1 #( 1.98 0.0159 2.98 0.1008 3.98 0.0365 4.98 0.0133 5.97 0.0101 6.97 0.0115 7.97 0.0007 8.99 0.0349 10.01 0.0342 11.01 0.0236 12.00 0.0041 13.02 0.0114 14.05 0.0137 15.06 0.0100 16.05 0.0007 17.04 0.0009 18.12 0.0077 19.15 0.0023 20.12 0.0017 21.24 0.0113 22.26 0.0126 23.30 0.0093 24.36 0.0007 25.43 0.0007 26.47 0.0009 27.55 0.0013 28.59 0.0025 29.61 0.0010 30.77 0.0021 31.86 0.0023 32.96 0.0003 34.03 0.0007 35.06 0.0005 36.20 0.0006 37.34 0.0006 38.36 0.0009 39.60 0.0016 40.69 0.0005 41.77 0.0002 42.92 0.0002 44.02 0.0003 45.24 0.0006 46.33 0.0004 47.50 0.0007 48.71 0.0007 49.87 0.0002 51.27 0.0002 53.42 0.0003 55.88 0.0003 57.10 0.0004 58.34 0.0002 59.86 0.0003 61.13 0.0003 67.18 0.0001 68.50 0.0001 71.17 0.0001 83.91 0.0001 90.55 0.0001 ) constant p-a1 #( 0.98 0.0099 2.00 0.0181 2.99 0.0353 3.98 0.0285 4.97 0.0514 5.96 0.0402 6.96 0.0015 7.98 0.0012 8.98 0.0175 9.98 0.0264 10.98 0.0392 11.98 0.0236 13.00 0.0153 14.04 0.0049 15.00 0.0089 16.01 0.0001 17.03 0.0106 18.03 0.0028 19.05 0.0024 20.08 0.0040 21.11 0.0103 22.12 0.0104 23.20 0.0017 24.19 0.0008 25.20 0.0007 26.24 0.0011 27.36 0.0009 27.97 0.0030 29.40 0.0044 30.37 0.0019 31.59 0.0017 32.65 0.0008 33.59 0.0005 34.79 0.0009 35.75 0.0027 36.88 0.0035 37.93 0.0039 39.00 0.0031 40.08 0.0025 41.16 0.0010 43.25 0.0004 44.52 0.0012 45.62 0.0023 45.85 0.0012 47.00 0.0006 47.87 0.0008 48.99 0.0003 50.48 0.0003 51.62 0.0001 52.43 0.0001 53.56 0.0002 54.76 0.0002 56.04 0.0002 56.68 0.0006 57.10 0.0003 58.28 0.0005 59.47 0.0003 59.96 0.0002 60.67 0.0001 63.08 0.0002 64.29 0.0002 66.72 0.0001 67.97 0.0001 68.65 0.0001 70.43 0.0001 79.38 0.0001 80.39 0.0001 82.39 0.0001 ) constant p-as1 #( 1.00 0.0765 1.99 0.0151 2.99 0.0500 3.99 0.0197 5.00 0.0260 6.00 0.0145 6.98 0.0128 7.97 0.0004 8.98 0.0158 9.99 0.0265 11.02 0.0290 12.02 0.0053 13.03 0.0242 14.03 0.0103 15.06 0.0054 16.04 0.0006 17.08 0.0008 18.10 0.0058 19.16 0.0011 20.16 0.0055 21.18 0.0040 22.20 0.0019 23.22 0.0014 24.05 0.0005 25.31 0.0019 26.38 0.0018 27.44 0.0022 28.45 0.0024 29.57 0.0073 30.58 0.0032 31.66 0.0071 32.73 0.0015 33.85 0.0005 34.96 0.0003 36.00 0.0020 37.11 0.0018 38.18 0.0055 39.23 0.0006 40.33 0.0004 41.52 0.0003 43.41 0.0028 45.05 0.0003 45.99 0.0002 47.07 0.0003 48.52 0.0002 49.48 0.0003 50.63 0.0003 51.81 0.0002 54.05 0.0002 55.24 0.0001 56.62 0.0001 57.81 0.0004 59.16 0.0013 60.23 0.0003 66.44 0.0001 68.99 0.0004 75.49 0.0001 87.56 0.0004 ) constant p-b1 #( 0.98 0.0629 1.99 0.0232 2.98 0.0217 4.00 0.0396 4.98 0.0171 5.97 0.0098 6.99 0.0167 7.99 0.0003 8.98 0.0192 9.98 0.0266 10.99 0.0256 12.01 0.0061 13.02 0.0135 14.02 0.0062 15.05 0.0158 16.06 0.0018 17.08 0.0101 18.09 0.0053 19.11 0.0074 20.13 0.0020 21.17 0.0052 22.22 0.0077 23.24 0.0035 24.00 0.0009 25.32 0.0016 26.40 0.0022 27.43 0.0005 28.55 0.0026 29.60 0.0026 30.65 0.0010 31.67 0.0019 32.77 0.0008 33.81 0.0003 34.91 0.0003 36.01 0.0005 37.11 0.0010 38.20 0.0014 39.29 0.0039 40.43 0.0012 41.50 0.0006 43.38 0.0017 43.75 0.0002 44.94 0.0005 46.13 0.0002 47.11 0.0003 48.28 0.0005 48.42 0.0005 49.44 0.0003 50.76 0.0004 51.93 0.0002 54.15 0.0003 55.31 0.0005 55.50 0.0003 56.98 0.0003 57.90 0.0004 60.33 0.0002 61.39 0.0001 61.59 0.0001 65.09 0.0002 66.34 0.0001 68.85 0.0001 70.42 0.0002 71.72 0.0001 73.05 0.0003 79.65 0.0001 85.28 0.0002 93.52 0.0001 ) constant p-c2 #( 1.02 0.0185 1.99 0.0525 2.98 0.0613 3.99 0.0415 4.98 0.0109 5.97 0.0248 6.99 0.0102 7.98 0.0005 8.98 0.0124 9.99 0.0103 10.99 0.0124 12.00 0.0016 13.01 0.0029 14.03 0.0211 15.04 0.0128 16.07 0.0021 17.09 0.0009 18.09 0.0043 19.14 0.0022 20.13 0.0016 21.20 0.0045 22.21 0.0088 23.26 0.0046 24.29 0.0013 25.35 0.0009 26.39 0.0028 27.49 0.0009 28.51 0.0006 29.58 0.0012 30.70 0.0010 31.74 0.0019 32.75 0.0002 33.85 0.0001 34.95 0.0005 36.02 0.0003 37.16 0.0009 38.25 0.0018 39.35 0.0008 40.54 0.0004 41.61 0.0002 43.40 0.0004 43.74 0.0003 45.05 0.0001 46.11 0.0003 47.40 0.0002 48.36 0.0004 49.55 0.0004 50.72 0.0002 52.00 0.0001 55.58 0.0002 57.02 0.0001 57.98 0.0002 59.13 0.0003 61.56 0.0001 66.56 0.0001 87.65 0.0002 ) constant p-cs2 #( 1.00 0.0473 1.99 0.0506 2.99 0.0982 3.99 0.0654 5.00 0.0196 5.99 0.0094 6.99 0.0118 7.93 0.0001 8.99 0.0057 10.01 0.0285 11.01 0.0142 12.03 0.0032 13.03 0.0056 14.06 0.0064 15.06 0.0059 16.11 0.0005 17.09 0.0033 18.14 0.0027 19.15 0.0014 20.17 0.0010 21.21 0.0059 22.26 0.0043 23.31 0.0031 24.31 0.0018 25.33 0.0009 26.41 0.0005 27.47 0.0015 28.53 0.0015 29.58 0.0041 30.65 0.0025 31.73 0.0011 32.83 0.0010 34.98 0.0003 36.07 0.0009 37.23 0.0001 38.26 0.0020 39.41 0.0014 40.53 0.0005 41.40 0.0003 42.80 0.0002 43.48 0.0028 43.93 0.0001 45.03 0.0003 46.18 0.0007 47.41 0.0001 48.57 0.0002 49.67 0.0001 50.83 0.0002 54.39 0.0001 55.58 0.0002 57.97 0.0005 58.11 0.0002 59.21 0.0001 60.42 0.0002 61.66 0.0001 ) constant p-d2 #( 1.00 0.0503 2.00 0.0963 2.99 0.1304 3.99 0.0218 4.98 0.0041 5.98 0.0292 6.98 0.0482 7.99 0.0005 8.99 0.0280 10.00 0.0237 11.00 0.0152 12.02 0.0036 12.95 0.0022 14.06 0.0111 15.07 0.0196 16.08 0.0016 17.11 0.0044 18.13 0.0073 19.17 0.0055 20.19 0.0028 21.20 0.0012 22.27 0.0068 23.30 0.0036 24.35 0.0012 25.35 0.0002 26.46 0.0005 27.47 0.0005 28.59 0.0009 29.65 0.0021 30.70 0.0020 31.78 0.0012 32.89 0.0010 35.06 0.0005 36.16 0.0008 37.27 0.0010 38.36 0.0010 39.47 0.0014 40.58 0.0004 41.43 0.0007 41.82 0.0003 43.48 0.0008 44.53 0.0001 45.25 0.0003 46.43 0.0002 47.46 0.0002 48.76 0.0005 49.95 0.0004 50.96 0.0002 51.12 0.0002 52.33 0.0001 54.75 0.0001 55.75 0.0002 56.90 0.0002 58.17 0.0002 59.40 0.0004 60.62 0.0002 65.65 0.0001 66.91 0.0002 69.91 0.0001 71.25 0.0002 ) constant p-ds2 #( 1.00 0.1243 1.98 0.1611 3.00 0.0698 3.98 0.0390 5.00 0.0138 5.99 0.0154 7.01 0.0287 8.01 0.0014 9.01 0.0049 10.00 0.0144 11.01 0.0055 12.05 0.0052 13.01 0.0011 14.05 0.0118 15.07 0.0154 16.12 0.0028 17.14 0.0061 18.25 0.0007 19.22 0.0020 20.24 0.0011 21.27 0.0029 22.30 0.0046 23.34 0.0049 24.35 0.0004 25.45 0.0003 26.47 0.0007 27.59 0.0008 28.16 0.0009 29.12 0.0002 29.81 0.0006 30.81 0.0009 31.95 0.0004 33.00 0.0011 34.12 0.0005 35.18 0.0003 36.30 0.0008 37.38 0.0003 38.55 0.0003 39.64 0.0006 40.77 0.0007 41.52 0.0006 41.89 0.0006 43.04 0.0011 43.60 0.0009 44.31 0.0002 45.68 0.0002 46.56 0.0003 47.60 0.0001 48.83 0.0006 50.01 0.0003 51.27 0.0003 56.04 0.0005 57.21 0.0003 58.56 0.0004 59.83 0.0003 61.05 0.0001 62.20 0.0001 67.37 0.0002 76.53 0.0001 ) constant p-e2 #( 0.99 0.0222 1.99 0.0678 2.99 0.0683 4.00 0.0191 5.00 0.0119 6.01 0.0232 6.98 0.0336 7.99 0.0082 9.01 0.0201 10.01 0.0189 11.01 0.0041 12.01 0.0053 13.05 0.0154 14.04 0.0159 15.06 0.0092 16.11 0.0038 17.12 0.0014 18.15 0.0091 19.16 0.0006 20.30 0.0012 21.25 0.0061 22.28 0.0099 23.34 0.0028 24.38 0.0012 25.43 0.0016 26.49 0.0048 27.55 0.0025 28.62 0.0015 29.71 0.0032 30.78 0.0077 31.88 0.0011 32.97 0.0007 34.08 0.0006 35.16 0.0008 36.28 0.0004 37.41 0.0006 38.54 0.0005 39.62 0.0002 40.80 0.0003 41.93 0.0001 43.06 0.0002 44.21 0.0003 45.38 0.0002 46.54 0.0007 47.78 0.0003 48.95 0.0004 50.10 0.0003 51.37 0.0002 53.79 0.0003 56.20 0.0001 58.71 0.0002 66.47 0.0003 ) constant p-f2 #( 1.01 0.0241 1.99 0.1011 2.98 0.0938 3.98 0.0081 4.99 0.0062 5.99 0.0291 6.99 0.0676 7.59 0.0004 8.98 0.0127 9.99 0.0112 10.99 0.0142 12.00 0.0029 13.02 0.0071 14.02 0.0184 15.03 0.0064 16.07 0.0010 17.09 0.0011 18.11 0.0010 19.15 0.0060 20.19 0.0019 21.24 0.0025 22.29 0.0013 23.31 0.0050 25.41 0.0030 26.50 0.0018 27.53 0.0006 28.63 0.0012 29.66 0.0013 30.77 0.0020 31.84 0.0006 34.04 0.0001 35.14 0.0001 36.32 0.0004 37.41 0.0007 38.53 0.0007 39.67 0.0009 40.85 0.0003 45.49 0.0002 46.65 0.0001 47.81 0.0004 49.01 0.0002 53.91 0.0002 55.14 0.0002 57.69 0.0002 ) constant p-fs2 #( 1.00 0.0326 2.00 0.1066 2.99 0.1015 4.00 0.0210 4.97 0.0170 5.99 0.0813 6.98 0.0820 7.96 0.0011 8.99 0.0248 10.03 0.0107 11.01 0.0126 12.01 0.0027 13.01 0.0233 14.04 0.0151 15.05 0.0071 16.04 0.0002 17.10 0.0061 18.12 0.0059 19.15 0.0087 20.23 0.0005 21.25 0.0040 22.30 0.0032 23.35 0.0004 24.40 0.0001 25.45 0.0030 26.54 0.0022 27.60 0.0003 28.70 0.0009 29.80 0.0029 30.85 0.0006 31.97 0.0006 34.19 0.0004 35.30 0.0003 36.43 0.0007 37.56 0.0005 38.68 0.0019 39.88 0.0013 41.00 0.0003 43.35 0.0003 44.51 0.0002 45.68 0.0006 46.93 0.0010 48.11 0.0006 49.29 0.0003 55.58 0.0002 ) constant p-g2 #( 0.98 0.0113 1.99 0.0967 3.00 0.0719 3.98 0.0345 4.98 0.0121 6.00 0.0621 7.00 0.0137 7.98 0.0006 9.01 0.0314 10.01 0.0171 11.02 0.0060 12.03 0.0024 13.05 0.0077 14.07 0.0040 15.12 0.0032 16.13 0.0004 17.15 0.0011 18.20 0.0028 19.18 0.0003 20.26 0.0003 21.31 0.0025 22.35 0.0021 23.39 0.0005 25.55 0.0002 26.62 0.0014 27.70 0.0003 28.78 0.0005 29.90 0.0030 31.01 0.0011 32.12 0.0005 34.31 0.0001 35.50 0.0002 36.62 0.0002 37.76 0.0005 38.85 0.0002 40.09 0.0004 43.60 0.0001 44.73 0.0002 46.02 0.0002 47.25 0.0004 48.44 0.0004 ) constant p-gs2 #( 0.99 0.0156 1.98 0.0846 2.98 0.0178 3.98 0.0367 4.98 0.0448 5.98 0.0113 6.99 0.0189 8.00 0.0011 9.01 0.0247 10.02 0.0089 11.01 0.0184 12.03 0.0105 13.00 0.0039 14.07 0.0116 15.09 0.0078 16.13 0.0008 17.14 0.0064 18.19 0.0029 19.22 0.0028 20.25 0.0017 21.32 0.0043 22.37 0.0055 23.42 0.0034 24.48 0.0004 25.54 0.0002 26.61 0.0017 27.70 0.0011 28.80 0.0002 29.89 0.0019 30.97 0.0028 32.09 0.0007 34.30 0.0002 35.44 0.0003 36.55 0.0001 37.69 0.0004 38.93 0.0002 40.05 0.0005 41.20 0.0005 42.37 0.0002 43.54 0.0003 44.73 0.0001 45.95 0.0002 47.16 0.0001 48.43 0.0005 49.65 0.0004 55.90 0.0002 59.81 0.0004 ) constant p-a2 #( 1.01 0.0280 2.00 0.0708 2.99 0.0182 3.99 0.0248 4.98 0.0245 5.98 0.0279 6.98 0.0437 7.99 0.0065 8.99 0.0299 10.00 0.0073 10.99 0.0011 12.03 0.0122 13.03 0.0028 14.08 0.0044 15.11 0.0097 16.15 0.0010 17.17 0.0025 18.19 0.0017 19.24 0.0008 20.28 0.0040 21.32 0.0024 22.38 0.0008 23.46 0.0032 24.52 0.0010 25.59 0.0008 26.68 0.0009 27.76 0.0012 28.88 0.0003 29.95 0.0005 31.05 0.0017 32.14 0.0002 33.29 0.0003 37.88 0.0002 39.03 0.0002 40.19 0.0004 41.37 0.0003 43.74 0.0002 46.20 0.0001 48.68 0.0001 49.93 0.0001 51.19 0.0002 ) constant p-as2 #( 1.00 0.0225 1.99 0.0921 2.98 0.0933 3.99 0.0365 4.99 0.0100 5.98 0.0213 6.98 0.0049 7.98 0.0041 8.98 0.0090 9.99 0.0068 11.01 0.0040 12.03 0.0086 13.02 0.0015 14.04 0.0071 15.09 0.0082 16.14 0.0011 17.15 0.0014 18.18 0.0010 19.26 0.0013 20.26 0.0005 21.33 0.0006 22.36 0.0011 23.46 0.0016 24.52 0.0004 25.59 0.0002 26.70 0.0006 27.78 0.0007 28.87 0.0002 30.03 0.0008 31.14 0.0010 32.24 0.0006 33.37 0.0002 35.67 0.0003 37.99 0.0004 39.17 0.0004 40.35 0.0005 41.53 0.0001 46.42 0.0001 ) constant p-b2 #( 1.00 0.0465 1.99 0.0976 2.98 0.0678 4.00 0.0727 4.99 0.0305 5.98 0.0210 6.98 0.0227 8.00 0.0085 9.01 0.0183 10.02 0.0258 11.05 0.0003 12.06 0.0061 13.05 0.0021 14.10 0.0089 15.12 0.0077 16.16 0.0016 17.21 0.0061 18.23 0.0011 19.29 0.0031 20.36 0.0031 21.41 0.0007 22.48 0.0013 23.55 0.0020 24.64 0.0004 25.74 0.0005 26.81 0.0006 27.95 0.0006 29.03 0.0001 30.22 0.0010 31.30 0.0004 32.48 0.0001 33.60 0.0002 38.30 0.0003 ) constant p-c3 #( 1.00 0.0674 1.99 0.0841 2.98 0.0920 3.99 0.0328 4.99 0.0368 5.98 0.0206 6.99 0.0246 8.01 0.0048 9.01 0.0218 10.03 0.0155 11.05 0.0048 12.06 0.0077 13.00 0.0020 14.10 0.0083 15.15 0.0084 16.18 0.0015 17.22 0.0039 18.27 0.0032 19.34 0.0026 20.40 0.0012 21.47 0.0009 22.54 0.0008 23.62 0.0016 24.71 0.0005 25.82 0.0004 26.91 0.0002 28.03 0.0008 29.17 0.0002 30.32 0.0028 31.45 0.0004 32.61 0.0005 33.77 0.0001 36.14 0.0003 37.32 0.0002 38.54 0.0005 39.75 0.0002 42.23 0.0002 48.65 0.0001 ) constant p-cs3 #( 1.01 0.0423 1.99 0.0240 2.98 0.0517 4.00 0.0493 5.00 0.0324 6.00 0.0094 6.99 0.0449 7.99 0.0050 9.00 0.0197 10.03 0.0132 11.03 0.0009 12.07 0.0017 13.08 0.0023 14.12 0.0094 15.16 0.0071 16.21 0.0020 17.25 0.0005 18.30 0.0027 19.04 0.0004 20.43 0.0022 21.51 0.0002 22.59 0.0006 23.72 0.0018 24.80 0.0002 25.88 0.0002 27.03 0.0002 28.09 0.0006 29.31 0.0002 30.46 0.0004 31.61 0.0007 32.78 0.0005 33.95 0.0001 36.34 0.0002 37.56 0.0001 38.80 0.0001 40.02 0.0001 44.14 0.0001 ) constant p-d3 #( 1.00 0.0669 1.99 0.0909 2.99 0.0410 3.98 0.0292 4.98 0.0259 5.98 0.0148 6.98 0.0319 7.99 0.0076 9.01 0.0056 10.02 0.0206 11.04 0.0032 12.05 0.0085 13.08 0.0040 14.12 0.0037 15.16 0.0030 16.20 0.0013 17.24 0.0021 18.30 0.0010 19.36 0.0015 20.44 0.0013 21.50 0.0009 22.60 0.0015 23.69 0.0014 24.80 0.0006 25.87 0.0002 27.02 0.0006 28.12 0.0002 29.28 0.0003 30.43 0.0002 31.59 0.0007 32.79 0.0001 35.14 0.0001 37.57 0.0001 40.03 0.0002 41.28 0.0004 44.10 0.0001 ) constant p-ds3 #( 0.99 0.0421 1.99 0.1541 2.98 0.0596 3.98 0.0309 4.98 0.0301 5.99 0.0103 7.00 0.0240 8.01 0.0073 9.01 0.0222 10.04 0.0140 11.05 0.0033 12.08 0.0045 13.13 0.0009 14.13 0.0015 15.21 0.0026 16.24 0.0003 17.30 0.0004 18.35 0.0010 19.39 0.0003 20.50 0.0015 21.57 0.0003 22.68 0.0011 23.80 0.0005 24.90 0.0008 26.02 0.0002 27.16 0.0001 28.30 0.0006 29.48 0.0002 31.81 0.0005 33.00 0.0003 34.21 0.0001 37.89 0.0001 ) constant p-e3 #( 0.99 0.0389 2.00 0.2095 3.00 0.0835 3.99 0.0289 5.00 0.0578 5.99 0.0363 7.01 0.0387 8.01 0.0056 9.04 0.0173 10.05 0.0175 11.08 0.0053 12.10 0.0056 13.15 0.0064 14.19 0.0036 15.22 0.0019 16.29 0.0010 17.36 0.0017 18.43 0.0018 19.51 0.0004 20.60 0.0011 21.70 0.0003 22.82 0.0003 23.95 0.0001 25.05 0.0004 26.17 0.0001 28.50 0.0003 29.68 0.0001 32.07 0.0003 33.28 0.0004 34.52 0.0001 ) constant p-f3 #( 1.00 0.1238 1.99 0.2270 3.00 0.0102 3.99 0.0181 4.98 0.0415 6.00 0.0165 7.01 0.0314 8.02 0.0148 9.04 0.0203 10.05 0.0088 11.07 0.0062 12.11 0.0070 13.14 0.0054 14.19 0.0028 15.24 0.0044 16.30 0.0029 17.38 0.0009 18.45 0.0026 19.56 0.0003 20.65 0.0025 21.74 0.0014 22.87 0.0013 23.99 0.0007 25.15 0.0002 27.46 0.0004 28.39 0.0006 28.65 0.0004 29.85 0.0001 31.05 0.0002 32.27 0.0003 33.52 0.0002 34.76 0.0003 ) constant p-fs3 #( 1.00 0.1054 2.00 0.2598 2.99 0.0369 3.98 0.0523 4.99 0.0020 5.99 0.0051 7.00 0.0268 8.01 0.0027 9.04 0.0029 10.05 0.0081 11.08 0.0047 12.12 0.0051 13.16 0.0091 14.19 0.0015 15.27 0.0030 16.34 0.0017 17.42 0.0006 18.51 0.0003 19.61 0.0007 20.72 0.0003 21.84 0.0001 22.99 0.0010 24.13 0.0001 28.44 0.0001 30.09 0.0001 ) constant p-g3 #( 0.99 0.0919 2.00 0.0418 2.99 0.0498 3.99 0.0135 4.99 0.0026 6.00 0.0155 7.01 0.0340 8.02 0.0033 9.04 0.0218 10.08 0.0084 11.11 0.0057 12.15 0.0051 13.21 0.0043 14.25 0.0015 15.31 0.0023 16.40 0.0008 17.48 0.0004 18.59 0.0016 19.71 0.0010 20.84 0.0018 21.98 0.0002 23.11 0.0013 24.26 0.0003 26.67 0.0002 29.12 0.0002 30.37 0.0002 31.62 0.0003 32.92 0.0001 ) constant p-gs3 #( 0.99 0.1174 1.99 0.1126 2.99 0.0370 3.99 0.0159 5.01 0.0472 6.01 0.0091 7.03 0.0211 8.05 0.0015 9.07 0.0098 10.11 0.0038 11.15 0.0042 12.20 0.0018 13.24 0.0041 14.32 0.0033 15.41 0.0052 16.49 0.0001 17.61 0.0004 18.71 0.0004 19.84 0.0004 20.99 0.0002 22.14 0.0006 23.31 0.0006 24.50 0.0004 25.70 0.0002 28.09 0.0002 28.66 0.0002 32.00 0.0001 ) constant p-a3 #( 1.00 0.1085 2.00 0.1400 2.99 0.0173 3.99 0.0229 5.00 0.0272 6.02 0.0077 7.03 0.0069 8.04 0.0017 9.08 0.0045 10.10 0.0030 11.15 0.0040 12.20 0.0007 13.25 0.0019 14.32 0.0008 15.42 0.0024 16.50 0.0002 17.59 0.0005 18.71 0.0003 19.83 0.0002 20.98 0.0005 23.29 0.0008 ) constant p-as3 #( 1.00 0.0985 2.00 0.1440 2.99 0.0364 3.99 0.0425 5.00 0.0190 6.01 0.0089 7.03 0.0278 8.04 0.0006 9.07 0.0083 10.10 0.0021 11.14 0.0050 12.18 0.0005 13.26 0.0036 14.33 0.0005 15.41 0.0026 17.62 0.0004 18.75 0.0004 19.89 0.0003 21.04 0.0012 22.21 0.0002 23.38 0.0004 27.04 0.0001 ) constant p-b3 #( 0.99 0.1273 2.00 0.1311 2.99 0.0120 4.00 0.0099 5.00 0.0235 6.02 0.0068 7.03 0.0162 8.06 0.0009 9.08 0.0083 10.12 0.0014 11.17 0.0050 12.24 0.0010 13.29 0.0013 14.39 0.0022 15.48 0.0011 16.59 0.0002 17.70 0.0003 18.84 0.0010 20.00 0.0003 21.17 0.0003 23.56 0.0004 28.79 0.0003 ) constant p-c4 #( 1.00 0.1018 2.00 0.1486 3.00 0.0165 4.00 0.0186 5.01 0.0194 6.02 0.0045 7.04 0.0083 8.06 0.0012 9.10 0.0066 10.15 0.0009 11.19 0.0008 12.26 0.0011 13.34 0.0028 14.45 0.0006 15.53 0.0009 16.66 0.0002 17.79 0.0006 18.94 0.0005 20.11 0.0003 21.29 0.0005 22.49 0.0003 23.73 0.0005 26.22 0.0001 27.52 0.0001 28.88 0.0002 ) constant p-cs4 #( 1.00 0.1889 1.99 0.1822 3.00 0.0363 4.00 0.0047 5.01 0.0202 6.03 0.0053 7.05 0.0114 8.01 0.0002 9.13 0.0048 10.17 0.0010 11.23 0.0033 12.30 0.0010 13.38 0.0006 14.50 0.0002 15.62 0.0010 20.27 0.0001 21.47 0.0001 ) constant p-d4 #( 1.00 0.0522 1.99 0.0763 2.99 0.0404 4.00 0.0139 5.01 0.0185 6.01 0.0021 7.06 0.0045 8.09 0.0002 9.11 0.0003 10.17 0.0006 11.25 0.0004 12.32 0.0005 13.40 0.0003 14.53 0.0003 15.65 0.0007 16.80 0.0001 17.95 0.0002 19.14 0.0006 20.34 0.0002 21.56 0.0003 ) constant p-ds4 #( 0.99 0.1821 1.99 0.0773 3.00 0.0125 4.01 0.0065 5.01 0.0202 6.03 0.0071 7.05 0.0090 8.08 0.0006 9.13 0.0008 10.18 0.0013 11.25 0.0010 12.33 0.0012 13.42 0.0006 14.54 0.0005 15.65 0.0004 17.97 0.0002 19.15 0.0001 ) constant p-e4 #( 1.00 0.1868 2.00 0.0951 3.00 0.0147 4.01 0.0134 5.02 0.0184 6.04 0.0132 7.06 0.0011 8.11 0.0008 9.15 0.0010 10.22 0.0012 11.30 0.0011 12.40 0.0003 13.11 0.0004 13.49 0.0002 14.62 0.0003 15.77 0.0001 ) constant p-f4 #( 1.00 0.1933 2.00 0.0714 3.00 0.0373 4.00 0.0108 5.02 0.0094 6.02 0.0010 7.07 0.0022 8.11 0.0002 9.16 0.0065 10.23 0.0015 11.31 0.0023 12.40 0.0003 13.53 0.0014 14.66 0.0002 15.81 0.0011 18.20 0.0002 19.41 0.0001 ) constant p-fs4 #( 0.99 0.2113 1.99 0.0877 3.00 0.0492 4.01 0.0094 5.02 0.0144 6.04 0.0103 7.07 0.0117 8.12 0.0006 9.19 0.0019 10.25 0.0007 11.35 0.0017 12.45 0.0010 13.58 0.0003 14.74 0.0003 15.91 0.0003 19.57 0.0002 ) constant p-g4 #( 0.99 0.2455 1.99 0.0161 3.00 0.0215 4.01 0.0036 5.03 0.0049 6.04 0.0012 7.09 0.0036 8.14 0.0011 9.21 0.0009 10.30 0.0001 11.40 0.0012 12.50 0.0001 13.66 0.0005 14.84 0.0001 ) constant p-gs4 #( 1.00 0.1132 2.00 0.0252 3.00 0.0292 4.01 0.0136 5.03 0.0045 6.06 0.0022 7.11 0.0101 8.17 0.0004 9.23 0.0010 10.33 0.0012 11.44 0.0013 12.58 0.0011 13.75 0.0002 14.93 0.0005 16.14 0.0002 ) constant p-a4 #( 1.00 0.1655 2.00 0.0445 3.00 0.0120 4.00 0.0038 5.02 0.0015 6.07 0.0038 7.11 0.0003 8.19 0.0002 9.25 0.0010 10.36 0.0011 11.48 0.0005 12.63 0.0002 13.79 0.0003 16.24 0.0002 ) constant p-as4 #( 0.99 0.3637 1.99 0.0259 3.01 0.0038 4.01 0.0057 5.03 0.0040 6.07 0.0067 7.12 0.0014 8.19 0.0004 9.27 0.0003 10.38 0.0002 12.67 0.0001 ) constant p-b4 #( 1.00 0.1193 2.00 0.0230 3.00 0.0104 4.01 0.0084 5.04 0.0047 6.08 0.0035 7.13 0.0041 8.20 0.0002 9.29 0.0005 10.40 0.0005 11.53 0.0003 12.70 0.0002 13.91 0.0002 ) constant p-c5 #( 1.00 0.0752 2.00 0.0497 3.00 0.0074 4.02 0.0076 5.05 0.0053 6.09 0.0043 7.15 0.0024 8.22 0.0001 9.32 0.0006 10.45 0.0002 11.58 0.0001 12.78 0.0001 15.22 0.0001 ) constant p-cs5 #( 1.00 0.2388 2.00 0.0629 3.01 0.0159 4.04 0.0063 5.07 0.0051 6.12 0.0045 7.19 0.0026 8.29 0.0015 9.43 0.0001 11.75 0.0002 ) constant p-d5 #( 1.00 0.1919 2.01 0.0116 3.01 0.0031 4.03 0.0090 5.07 0.0061 6.13 0.0036 7.19 0.0013 8.30 0.0016 9.13 0.0001 10.59 0.0002 11.78 0.0002 ) constant p-ds5 #( 1.00 0.1296 2.00 0.0135 3.01 0.0041 4.04 0.0045 5.09 0.0028 6.14 0.0046 7.23 0.0007 8.32 0.0007 9.50 0.0001 ) constant p-e5 #( 1.00 0.0692 2.00 0.0209 3.02 0.0025 4.05 0.0030 5.09 0.0047 6.17 0.0022 7.25 0.0015 8.36 0.0015 9.53 0.0010 10.69 0.0001 13.40 0.0001 ) constant p-f5 #( 1.00 0.1715 2.00 0.0142 3.01 0.0024 4.03 0.0015 5.07 0.0017 6.13 0.0018 7.22 0.0009 8.33 0.0014 9.51 0.0007 10.69 0.0002 ) constant p-fs5 #( 1.00 0.1555 2.01 0.0148 3.02 0.0007 4.06 0.0006 5.10 0.0005 6.16 0.0008 7.26 0.0009 8.39 0.0008 9.58 0.0002 ) constant p-g5 #( 1.00 0.1357 2.00 0.0116 3.02 0.0026 4.04 0.0009 5.09 0.0004 6.17 0.0005 7.27 0.0002 8.40 0.0001 ) constant p-gs5 #( 1.00 0.2185 2.01 0.0087 3.03 0.0018 4.06 0.0025 5.11 0.0020 6.20 0.0012 7.32 0.0005 8.46 0.0001 9.66 0.0003 ) constant p-a5 #( 1.00 0.2735 2.00 0.0038 3.02 0.0008 4.06 0.0012 5.12 0.0008 6.22 0.0011 7.35 0.0003 8.50 0.0002 ) constant p-as5 #( 1.00 0.1441 1.99 0.0062 3.01 0.0023 4.05 0.0011 5.11 0.0012 6.20 0.0003 7.33 0.0004 8.50 0.0001 ) constant p-b5 #( 1.00 0.0726 2.01 0.0293 3.03 0.0022 5.14 0.0005 6.26 0.0011 7.41 0.0002 8.63 0.0002 ) constant p-c6 #( 1.00 0.0516 2.00 0.0104 3.02 0.0029 5.15 0.0002 6.27 0.0001 ) constant p-cs6 #( 1.00 0.0329 2.00 0.0033 3.03 0.0013 4.10 0.0005 5.19 0.0004 6.32 0.0002 ) constant p-d6 #( 1.00 0.0179 1.99 0.0012 3.04 0.0005 4.10 0.0017 5.20 0.0005 6.35 0.0001 ) constant p-ds6 #( 1.00 0.0334 2.01 0.0033 3.04 0.0011 4.13 0.0003 5.22 0.0003 ) constant p-e6 #( 0.99 0.0161 2.01 0.0100 3.04 0.0020 4.13 0.0003 ) constant p-f6 #( 1.00 0.0475 1.99 0.0045 3.03 0.0035 4.12 0.0011 ) constant p-fs6 #( 1.00 0.0593 2.00 0.0014 4.17 0.0002 ) constant p-g6 #( 1.00 0.0249 2.01 0.0016 ) constant p-gs6 #( 1.00 0.0242 2.00 0.0038 4.19 0.0002 ) constant p-a6 #( 1.00 0.0170 2.02 0.0030 ) constant p-as6 #( 1.00 0.0381 2.00 0.0017 3.09 0.0002 ) constant p-b6 #( 1.00 0.0141 2.03 0.0005 3.11 0.0003 4.26 0.0001 ) constant p-c7 #( 1.00 0.0122 2.03 0.0024 ) constant p-cs7 #( 1.00 0.0107 2.07 0.0007 3.12 0.0004 ) constant p-d7 #( 1.00 0.0250 2.02 0.0026 3.15 0.0002 ) constant p-ds7 #( 1.01 0.0092 ) constant p-e7 #( 1.01 0.0102 2.09 0.0005 ) constant p-f7 #( 1.00 0.0080 2.00 0.0005 3.19 0.0001 ) constant p-fs7 #( 1.01 0.0298 2.01 0.0005 ) constant p-g7 \ ********************************************************** \ sax \ ********************************************************** #( 1.01 0.0565 2.01 0.0374 3.00 0.0377 4.00 0.0498 5.02 0.0907 6.02 0.0361 7.02 0.0250 8.01 0.0036 9.02 0.0181 10.03 0.0319 11.03 0.0075 12.03 0.0068 13.03 0.0037 14.03 0.0015 15.05 0.0021 16.04 0.0034 17.04 0.0076 18.04 0.0101 19.06 0.0056 20.06 0.0051 21.05 0.0046 22.05 0.0029 23.05 0.0015 24.07 0.0026 25.07 0.0023 26.06 0.0025 27.06 0.0010 28.08 0.0011 29.08 0.0005 30.07 0.0017 31.07 0.0025 32.07 0.0032 33.09 0.0026 34.09 0.0023 35.09 0.0038 36.09 0.0023 37.09 0.0018 38.11 0.0023 39.11 0.0017 40.10 0.0015 41.10 0.0010 42.10 0.0008 43.13 0.0004 45.13 0.0001 46.11 0.0005 47.12 0.0004 48.12 0.0006 49.11 0.0004 50.12 0.0008 51.13 0.0006 52.14 0.0009 53.13 0.0006 54.13 0.0008 55.13 0.0007 56.15 0.0005 57.16 0.0002 58.13 0.0001 59.17 0.0001 61.15 0.0001 62.15 0.0002 63.16 0.0002 65.17 0.0004 66.18 0.0005 67.18 0.0003 68.17 0.0002 69.17 0.0005 70.18 0.0003 71.18 0.0002 72.18 0.0005 73.18 0.0003 74.18 0.0003 75.20 0.0003 76.19 0.0003 77.19 0.0002 78.19 0.0004 80.20 0.0002 81.19 0.0001 82.21 0.0001 89.23 0.0002 90.23 0.0002 91.23 0.0003 92.22 0.0001 ) constant sax-cs3 #( 1.00 0.0423 1.99 0.0487 2.98 0.0259 3.99 0.0630 4.99 0.1026 5.97 0.0532 6.97 0.0259 7.98 0.0110 8.97 0.0076 9.96 0.0123 10.97 0.0162 11.96 0.0128 12.95 0.0178 13.94 0.0114 14.96 0.0134 15.95 0.0186 16.94 0.0180 17.93 0.0087 18.94 0.0084 19.93 0.0064 20.92 0.0033 21.93 0.0025 22.93 0.0041 23.91 0.0041 24.90 0.0034 25.91 0.0012 26.90 0.0013 27.90 0.0020 28.89 0.0036 29.90 0.0054 30.89 0.0054 31.88 0.0038 32.89 0.0059 33.89 0.0037 34.88 0.0024 35.86 0.0024 36.87 0.0023 37.87 0.0017 38.86 0.0020 39.85 0.0019 40.86 0.0021 41.86 0.0007 42.84 0.0012 43.84 0.0007 44.84 0.0010 45.85 0.0005 46.82 0.0006 47.84 0.0009 48.82 0.0009 49.82 0.0006 50.81 0.0008 51.82 0.0012 52.80 0.0012 54.81 0.0005 55.78 0.0003 56.79 0.0003 57.78 0.0003 58.79 0.0003 59.80 0.0004 60.77 0.0003 61.78 0.0004 62.77 0.0005 63.77 0.0001 64.75 0.0004 65.76 0.0003 66.77 0.0003 67.76 0.0006 68.75 0.0006 69.75 0.0007 70.74 0.0004 71.74 0.0010 72.73 0.0008 73.74 0.0007 75.74 0.0002 76.72 0.0004 77.72 0.0002 78.71 0.0004 79.70 0.0001 80.71 0.0001 81.70 0.0002 82.70 0.0001 83.70 0.0004 84.69 0.0003 85.68 0.0008 86.68 0.0003 87.69 0.0001 88.69 0.0002 90.66 0.0001 ) constant sax-d3 #( 1.00 0.0338 1.99 0.0765 2.97 0.0602 3.96 0.0870 4.97 0.1666 5.96 0.0394 6.95 0.0067 7.94 0.0199 8.94 0.0418 9.93 0.0110 10.92 0.0101 11.91 0.0077 12.90 0.0052 13.91 0.0148 14.90 0.0172 15.88 0.0218 16.87 0.0110 17.88 0.0086 18.87 0.0045 19.86 0.0009 20.85 0.0014 21.85 0.0045 22.84 0.0037 23.83 0.0010 24.82 0.0028 25.81 0.0013 26.82 0.0032 27.81 0.0040 28.79 0.0067 29.78 0.0035 30.79 0.0041 31.78 0.0028 32.76 0.0017 33.75 0.0011 34.76 0.0015 35.75 0.0018 36.73 0.0021 37.72 0.0017 38.71 0.0019 39.72 0.0014 40.71 0.0015 41.70 0.0016 42.69 0.0006 43.69 0.0021 44.69 0.0024 45.67 0.0003 46.66 0.0014 47.66 0.0002 48.66 0.0011 49.65 0.0010 50.63 0.0002 51.62 0.0008 52.63 0.0007 53.62 0.0008 54.60 0.0004 56.59 0.0005 57.59 0.0003 58.58 0.0007 60.56 0.0004 61.56 0.0002 62.55 0.0004 63.54 0.0004 64.53 0.0008 65.54 0.0011 66.53 0.0003 67.52 0.0009 68.51 0.0008 69.51 0.0013 70.50 0.0002 71.49 0.0004 72.47 0.0004 73.47 0.0002 74.48 0.0002 75.46 0.0002 76.45 0.0005 77.45 0.0003 78.45 0.0008 79.44 0.0003 80.42 0.0008 81.41 0.0005 82.41 0.0001 83.42 0.0001 ) constant sax-ds3 #( 1.00 0.0225 1.99 0.0627 2.99 0.0834 3.98 0.0804 4.98 0.0984 5.97 0.0393 6.96 0.0345 7.96 0.0102 8.95 0.0084 9.94 0.0129 10.93 0.0214 11.93 0.0154 12.92 0.0184 13.91 0.0167 14.91 0.0213 15.90 0.0116 16.89 0.0090 17.88 0.0045 18.88 0.0008 19.87 0.0024 20.86 0.0045 21.86 0.0058 22.85 0.0012 23.84 0.0012 24.84 0.0030 25.83 0.0035 26.82 0.0067 27.83 0.0048 28.82 0.0016 29.82 0.0012 30.81 0.0015 31.81 0.0032 32.80 0.0033 33.80 0.0038 34.79 0.0032 35.78 0.0025 36.78 0.0008 37.77 0.0007 38.76 0.0020 39.75 0.0009 40.75 0.0007 41.74 0.0018 42.73 0.0024 43.72 0.0012 44.72 0.0016 45.71 0.0015 46.70 0.0019 47.69 0.0005 48.69 0.0007 49.68 0.0006 50.67 0.0003 51.68 0.0006 52.67 0.0002 53.66 0.0004 54.65 0.0004 55.65 0.0005 56.64 0.0004 57.64 0.0006 58.64 0.0004 59.64 0.0004 60.63 0.0011 61.62 0.0004 62.62 0.0003 63.61 0.0005 64.60 0.0011 65.60 0.0010 65.74 0.0001 66.59 0.0001 67.58 0.0006 68.57 0.0007 69.56 0.0003 70.56 0.0002 71.56 0.0002 72.55 0.0007 73.54 0.0009 74.53 0.0008 75.52 0.0007 76.52 0.0006 77.51 0.0002 79.50 0.0002 ) constant sax-e3 #( 0.98 0.0394 1.98 0.0562 2.97 0.0897 3.96 0.0683 4.96 0.0231 5.95 0.0309 6.94 0.0308 7.91 0.0176 8.91 0.0089 9.90 0.0084 10.89 0.0141 11.89 0.0045 12.88 0.0070 13.87 0.0083 14.85 0.0142 15.84 0.0089 16.83 0.0048 17.82 0.0015 18.82 0.0028 19.82 0.0027 20.81 0.0015 21.79 0.0012 22.77 0.0015 23.76 0.0050 24.76 0.0041 25.75 0.0048 26.75 0.0015 27.74 0.0007 28.73 0.0011 29.71 0.0016 30.70 0.0020 31.69 0.0019 32.68 0.0032 33.68 0.0026 34.67 0.0014 35.66 0.0013 36.64 0.0009 37.63 0.0014 38.62 0.0009 39.61 0.0018 40.61 0.0008 41.60 0.0013 42.59 0.0007 43.57 0.0010 44.56 0.0006 45.57 0.0002 46.54 0.0009 47.53 0.0005 48.51 0.0002 49.53 0.0001 50.52 0.0005 51.49 0.0002 52.49 0.0006 53.47 0.0001 54.48 0.0002 55.46 0.0003 56.47 0.0002 57.45 0.0006 58.43 0.0004 59.42 0.0003 60.41 0.0006 61.41 0.0005 62.40 0.0005 63.40 0.0002 64.38 0.0003 65.37 0.0001 66.35 0.0002 68.34 0.0005 69.33 0.0003 70.33 0.0005 71.32 0.0001 72.30 0.0002 75.27 0.0001 ) constant sax-f3 #( 0.99 0.0784 1.99 0.0550 2.97 0.0439 3.97 0.0998 4.95 0.0679 5.95 0.0244 6.93 0.0178 7.94 0.0130 8.92 0.0186 9.92 0.0204 10.90 0.0091 11.90 0.0102 12.88 0.0166 13.88 0.0130 14.86 0.0079 15.86 0.0039 16.86 0.0023 17.84 0.0052 18.84 0.0049 19.82 0.0042 20.82 0.0027 21.81 0.0027 22.80 0.0057 23.78 0.0042 24.79 0.0042 25.77 0.0015 26.77 0.0008 27.75 0.0020 28.75 0.0021 29.73 0.0032 30.73 0.0036 31.71 0.0022 32.71 0.0011 33.71 0.0015 34.69 0.0011 35.69 0.0012 36.67 0.0013 37.67 0.0014 38.65 0.0006 39.65 0.0013 40.64 0.0004 41.63 0.0010 42.62 0.0002 43.62 0.0010 44.60 0.0003 45.59 0.0003 46.58 0.0004 47.59 0.0005 48.57 0.0002 49.55 0.0005 50.55 0.0002 51.54 0.0002 52.53 0.0005 53.53 0.0006 54.52 0.0006 55.51 0.0002 56.50 0.0008 57.47 0.0003 58.48 0.0007 59.47 0.0003 60.46 0.0002 61.44 0.0002 62.45 0.0002 63.43 0.0001 64.43 0.0004 65.42 0.0005 66.41 0.0007 67.40 0.0002 68.39 0.0002 69.39 0.0002 70.37 0.0001 ) constant sax-fs3 #( 1.00 0.1076 1.99 0.0463 2.98 0.1092 3.97 0.0816 4.95 0.0831 5.94 0.0118 6.93 0.0095 7.94 0.0104 8.93 0.0148 9.92 0.0144 10.91 0.0117 11.90 0.0196 12.89 0.0153 13.88 0.0107 14.87 0.0052 15.86 0.0033 16.86 0.0058 17.85 0.0042 18.83 0.0013 19.83 0.0029 20.82 0.0067 21.81 0.0040 22.80 0.0057 23.79 0.0022 24.79 0.0019 25.78 0.0009 26.78 0.0017 27.76 0.0025 28.76 0.0024 29.74 0.0020 30.73 0.0011 31.72 0.0010 32.73 0.0007 33.72 0.0013 34.70 0.0019 35.69 0.0017 36.69 0.0011 37.67 0.0006 38.67 0.0008 39.67 0.0005 40.66 0.0005 41.65 0.0011 42.64 0.0003 43.63 0.0004 44.62 0.0007 45.60 0.0007 46.60 0.0006 47.59 0.0006 48.59 0.0003 49.59 0.0007 50.57 0.0006 51.57 0.0007 52.55 0.0003 53.54 0.0008 54.53 0.0005 55.53 0.0005 56.51 0.0003 57.52 0.0005 59.50 0.0001 60.48 0.0002 61.47 0.0006 62.46 0.0005 63.46 0.0003 64.46 0.0002 65.45 0.0002 ) constant sax-g3 #( 0.98 0.0781 1.97 0.0393 2.96 0.0842 3.94 0.0434 4.93 0.0378 5.91 0.0141 6.89 0.0201 7.87 0.0294 8.86 0.0169 9.85 0.0124 10.84 0.0137 11.81 0.0238 12.80 0.0172 13.78 0.0094 14.77 0.0040 15.76 0.0036 16.74 0.0061 17.72 0.0032 18.70 0.0035 19.69 0.0086 20.68 0.0065 21.66 0.0097 22.65 0.0036 23.63 0.0010 24.62 0.0006 25.61 0.0018 26.59 0.0026 27.58 0.0023 28.56 0.0017 29.54 0.0010 30.52 0.0012 31.50 0.0018 32.50 0.0021 33.48 0.0025 34.46 0.0010 35.45 0.0028 36.42 0.0018 37.41 0.0009 38.41 0.0007 39.38 0.0006 40.37 0.0004 41.36 0.0005 42.34 0.0007 43.31 0.0001 44.29 0.0002 45.29 0.0006 46.28 0.0005 47.26 0.0005 48.25 0.0006 49.22 0.0006 50.21 0.0003 51.20 0.0007 52.18 0.0004 53.16 0.0003 54.15 0.0004 55.14 0.0001 56.10 0.0001 57.11 0.0005 58.09 0.0007 59.07 0.0005 59.22 0.0001 61.04 0.0004 63.02 0.0002 ) constant sax-gs3 #( 0.99 0.0950 1.97 0.0374 2.95 0.0738 3.94 0.0772 4.93 0.0103 5.92 0.0135 6.90 0.0099 7.88 0.0088 8.88 0.0151 9.86 0.0150 10.84 0.0177 11.83 0.0121 12.82 0.0071 13.81 0.0049 14.79 0.0025 15.77 0.0046 16.77 0.0023 17.75 0.0020 18.73 0.0079 19.71 0.0057 20.70 0.0068 21.69 0.0036 22.67 0.0007 23.65 0.0003 24.65 0.0006 25.64 0.0016 26.62 0.0013 27.60 0.0006 28.59 0.0005 29.59 0.0005 30.56 0.0013 31.55 0.0015 32.53 0.0013 33.52 0.0009 34.51 0.0016 35.48 0.0002 36.47 0.0007 37.46 0.0002 38.46 0.0003 39.43 0.0002 40.42 0.0003 41.40 0.0006 42.40 0.0006 43.39 0.0002 44.36 0.0009 45.35 0.0008 46.34 0.0010 47.32 0.0003 48.30 0.0009 49.29 0.0006 50.28 0.0002 51.27 0.0004 52.25 0.0002 54.23 0.0003 55.21 0.0001 56.19 0.0002 58.17 0.0002 ) constant sax-a3 #( 0.99 0.0856 1.98 0.0365 2.97 0.0409 3.96 0.0666 4.94 0.0192 5.94 0.0263 6.92 0.0311 7.91 0.0175 8.90 0.0203 9.89 0.0358 10.87 0.0214 11.87 0.0177 12.85 0.0068 13.84 0.0071 14.83 0.0068 15.82 0.0040 16.80 0.0040 17.80 0.0126 18.78 0.0101 19.77 0.0086 20.75 0.0053 21.75 0.0012 22.73 0.0026 23.73 0.0019 24.71 0.0018 25.71 0.0026 26.68 0.0023 27.68 0.0022 28.66 0.0015 29.66 0.0031 30.64 0.0008 31.63 0.0023 32.61 0.0029 33.61 0.0007 34.59 0.0016 35.59 0.0009 36.57 0.0006 37.56 0.0012 38.54 0.0004 39.53 0.0005 40.52 0.0007 41.52 0.0006 42.50 0.0009 43.50 0.0015 44.48 0.0005 45.47 0.0012 46.46 0.0007 47.45 0.0003 48.44 0.0007 49.41 0.0003 50.41 0.0003 51.40 0.0011 52.39 0.0007 53.37 0.0005 54.36 0.0005 55.34 0.0002 56.34 0.0002 ) constant sax-as3 #( 0.99 0.1015 1.99 0.0817 2.98 0.0315 3.98 0.0386 4.97 0.0424 5.96 0.0104 6.96 0.0144 7.94 0.0361 8.94 0.0182 9.93 0.0238 10.93 0.0139 11.93 0.0063 12.91 0.0058 13.91 0.0071 14.91 0.0051 15.89 0.0035 16.90 0.0114 17.88 0.0097 18.88 0.0081 19.87 0.0043 20.86 0.0014 21.86 0.0009 22.85 0.0012 23.86 0.0006 24.84 0.0013 25.83 0.0006 26.83 0.0010 27.82 0.0015 28.80 0.0008 29.80 0.0012 30.80 0.0017 31.77 0.0002 32.78 0.0016 33.78 0.0006 34.77 0.0003 35.77 0.0009 36.76 0.0006 37.75 0.0011 38.75 0.0006 39.74 0.0011 40.74 0.0011 41.73 0.0006 42.72 0.0015 43.72 0.0008 44.70 0.0002 45.71 0.0005 46.70 0.0004 47.69 0.0003 48.69 0.0005 49.67 0.0005 50.64 0.0001 51.66 0.0003 ) constant sax-b3 #( 0.99 0.1462 1.98 0.0760 2.98 0.0464 3.97 0.0292 4.95 0.0393 5.95 0.0117 6.94 0.0150 7.93 0.0251 8.93 0.0238 9.92 0.0182 10.90 0.0142 11.89 0.0100 12.89 0.0108 13.88 0.0029 14.87 0.0060 15.86 0.0116 16.85 0.0066 17.84 0.0072 18.84 0.0034 19.83 0.0010 20.82 0.0013 21.81 0.0015 22.80 0.0012 23.80 0.0011 24.79 0.0004 25.77 0.0027 26.76 0.0021 27.75 0.0018 28.75 0.0013 29.74 0.0015 30.73 0.0008 31.72 0.0004 32.71 0.0007 33.71 0.0011 34.70 0.0002 35.68 0.0010 36.67 0.0002 37.66 0.0003 38.67 0.0010 39.66 0.0008 40.64 0.0019 41.64 0.0005 42.62 0.0010 43.62 0.0003 45.60 0.0005 46.59 0.0002 47.59 0.0002 48.58 0.0002 49.57 0.0002 50.55 0.0001 ) constant sax-c4 #( 0.99 0.0832 1.97 0.0162 2.96 0.0337 3.95 0.0272 4.94 0.0264 5.93 0.0256 6.93 0.0180 7.92 0.0206 8.90 0.0167 9.89 0.0172 10.88 0.0075 11.86 0.0087 12.85 0.0048 13.85 0.0051 14.83 0.0134 15.83 0.0091 16.82 0.0065 17.80 0.0008 18.80 0.0018 19.78 0.0023 20.77 0.0025 21.76 0.0021 22.74 0.0013 23.74 0.0011 24.72 0.0032 25.72 0.0006 26.72 0.0005 27.69 0.0026 28.69 0.0009 29.68 0.0006 30.66 0.0003 31.65 0.0007 32.64 0.0003 33.62 0.0014 34.61 0.0007 35.60 0.0007 36.59 0.0005 37.60 0.0004 38.56 0.0006 39.54 0.0004 40.55 0.0004 41.55 0.0003 42.50 0.0002 43.51 0.0005 44.50 0.0003 45.50 0.0002 46.48 0.0002 47.48 0.0002 ) constant sax-cs4 #( 0.98 0.0860 1.97 0.0143 2.95 0.0061 3.94 0.0407 4.93 0.0204 5.91 0.0066 6.90 0.0372 7.89 0.0217 8.87 0.0220 9.86 0.0147 10.85 0.0042 11.83 0.0072 12.82 0.0023 13.81 0.0074 14.79 0.0104 15.78 0.0050 16.76 0.0005 17.74 0.0036 18.73 0.0056 19.71 0.0022 20.70 0.0040 21.69 0.0021 22.68 0.0018 23.66 0.0026 24.65 0.0035 25.64 0.0021 26.62 0.0011 27.61 0.0013 28.59 0.0006 29.58 0.0002 30.57 0.0010 31.69 0.0001 32.54 0.0004 33.52 0.0009 34.50 0.0005 35.49 0.0004 36.47 0.0013 37.46 0.0015 38.45 0.0009 39.43 0.0003 40.42 0.0004 41.41 0.0008 42.40 0.0005 43.38 0.0004 44.37 0.0006 ) constant sax-d4 #( 0.98 0.0870 1.97 0.0204 2.96 0.0184 3.94 0.0494 4.92 0.0500 5.91 0.0163 6.90 0.0267 7.88 0.0158 8.86 0.0159 9.85 0.0095 10.84 0.0095 11.82 0.0039 12.81 0.0053 13.79 0.0074 14.78 0.0054 15.77 0.0004 16.75 0.0027 17.73 0.0034 18.71 0.0035 19.70 0.0019 20.69 0.0028 21.67 0.0032 22.65 0.0016 23.64 0.0018 24.63 0.0033 25.61 0.0006 26.59 0.0015 27.58 0.0005 28.57 0.0010 29.56 0.0006 30.54 0.0010 31.52 0.0009 32.51 0.0004 33.50 0.0012 34.47 0.0006 35.46 0.0009 36.45 0.0007 37.44 0.0002 38.42 0.0006 39.41 0.0003 40.38 0.0003 41.38 0.0005 42.36 0.0003 ) constant sax-ds4 #( 0.99 0.0111 1.97 0.0520 2.96 0.0287 3.94 0.0704 4.93 0.0240 5.91 0.0286 6.89 0.0516 7.89 0.0184 8.87 0.0076 9.86 0.0113 10.84 0.0049 11.83 0.0044 12.81 0.0111 13.79 0.0080 14.78 0.0008 15.76 0.0031 16.76 0.0042 17.74 0.0016 18.73 0.0021 19.71 0.0010 20.69 0.0048 21.68 0.0014 22.66 0.0020 23.66 0.0016 24.64 0.0011 25.62 0.0011 26.61 0.0001 27.59 0.0011 28.58 0.0013 29.56 0.0011 30.55 0.0004 31.54 0.0015 32.52 0.0023 33.51 0.0015 34.49 0.0004 35.48 0.0003 36.46 0.0007 37.45 0.0003 38.43 0.0003 39.42 0.0009 ) constant sax-e4 #( 1.00 0.0896 2.00 0.1802 3.00 0.0636 4.00 0.0344 5.01 0.0214 6.01 0.0196 7.01 0.0241 8.01 0.0118 9.01 0.0057 10.01 0.0060 11.01 0.0059 12.01 0.0032 13.02 0.0055 14.02 0.0023 15.01 0.0020 16.02 0.0027 17.02 0.0022 18.02 0.0017 19.02 0.0015 20.02 0.0020 21.03 0.0014 22.03 0.0010 23.02 0.0006 24.03 0.0007 25.03 0.0005 27.03 0.0006 28.03 0.0005 29.04 0.0003 30.04 0.0009 31.03 0.0006 32.04 0.0003 33.04 0.0002 34.04 0.0003 35.04 0.0001 36.04 0.0002 37.05 0.0003 ) constant sax-f4 #( 0.99 0.0786 1.99 0.1613 2.99 0.0550 3.98 0.0380 4.98 0.0201 5.98 0.0245 6.97 0.0212 7.96 0.0069 8.96 0.0130 9.96 0.0029 10.95 0.0084 11.95 0.0093 12.94 0.0026 13.94 0.0015 14.93 0.0022 15.93 0.0025 16.93 0.0022 17.92 0.0015 18.91 0.0011 19.91 0.0011 20.91 0.0006 21.90 0.0010 22.89 0.0003 23.89 0.0003 24.89 0.0004 25.89 0.0003 26.88 0.0011 26.95 0.0003 27.87 0.0003 28.87 0.0012 29.87 0.0002 30.86 0.0004 31.85 0.0003 32.85 0.0005 33.84 0.0006 34.84 0.0002 34.90 0.0001 ) constant sax-fs4 #( 1.00 0.0747 2.00 0.1351 3.00 0.0384 4.00 0.0519 5.00 0.0376 6.00 0.0323 7.00 0.0212 8.00 0.0091 9.00 0.0086 10.00 0.0060 11.00 0.0132 12.00 0.0038 13.00 0.0016 14.00 0.0044 15.00 0.0023 16.00 0.0029 17.00 0.0031 18.00 0.0011 19.00 0.0008 20.00 0.0006 21.01 0.0005 22.00 0.0006 23.00 0.0007 24.00 0.0008 25.01 0.0003 26.01 0.0017 27.00 0.0012 28.00 0.0005 29.03 0.0001 30.00 0.0004 31.00 0.0005 32.00 0.0001 33.00 0.0003 34.00 0.0001 ) constant sax-g4 #( 1.00 0.0671 1.99 0.0676 2.98 0.0664 3.97 0.0207 4.97 0.0170 5.96 0.0406 6.96 0.0157 7.95 0.0093 8.94 0.0032 9.93 0.0117 10.93 0.0059 11.93 0.0034 12.92 0.0052 13.91 0.0036 14.90 0.0010 15.89 0.0023 16.89 0.0019 17.89 0.0011 18.88 0.0013 19.87 0.0009 20.86 0.0005 21.86 0.0006 22.86 0.0011 23.85 0.0006 24.85 0.0008 25.83 0.0010 26.83 0.0010 27.82 0.0007 28.80 0.0002 29.82 0.0006 31.80 0.0001 ) constant sax-gs4 #( 0.99 0.0707 1.99 0.1376 2.99 0.0767 3.98 0.0191 4.98 0.0316 5.97 0.0241 6.97 0.0070 7.97 0.0095 8.96 0.0085 9.96 0.0109 10.96 0.0012 11.95 0.0047 12.94 0.0051 13.94 0.0022 14.93 0.0020 15.93 0.0007 16.93 0.0016 17.92 0.0014 18.92 0.0008 19.92 0.0005 20.91 0.0008 21.91 0.0005 22.91 0.0002 23.90 0.0008 24.89 0.0015 25.89 0.0004 26.89 0.0003 27.88 0.0002 28.88 0.0002 29.88 0.0002 ) constant sax-a4 #( 0.99 0.0652 1.98 0.0768 2.97 0.0399 3.96 0.0314 4.95 0.0539 5.94 0.0282 6.93 0.0048 7.93 0.0059 8.91 0.0163 9.90 0.0039 10.89 0.0052 11.88 0.0086 12.87 0.0025 13.86 0.0011 14.85 0.0069 15.84 0.0006 16.84 0.0018 17.82 0.0008 18.80 0.0004 19.81 0.0004 20.78 0.0002 21.79 0.0010 22.78 0.0038 23.76 0.0018 24.75 0.0010 25.74 0.0002 26.73 0.0005 27.72 0.0006 28.71 0.0003 ) constant sax-as4 #( 1.00 0.1365 1.99 0.0773 2.98 0.0370 3.97 0.0399 4.97 0.0441 5.96 0.0193 6.95 0.0055 7.95 0.0036 8.94 0.0106 9.93 0.0050 10.93 0.0075 11.92 0.0047 12.91 0.0013 13.90 0.0034 14.90 0.0024 15.89 0.0018 16.89 0.0005 17.87 0.0006 18.87 0.0014 19.87 0.0011 20.86 0.0017 21.84 0.0018 22.84 0.0007 23.83 0.0003 24.82 0.0006 25.83 0.0002 26.81 0.0002 ) constant sax-b4 #( 0.99 0.1197 1.98 0.0661 2.97 0.0448 3.96 0.0398 4.96 0.0311 5.95 0.0167 6.93 0.0068 7.93 0.0249 8.92 0.0065 9.91 0.0104 10.90 0.0081 11.89 0.0032 12.88 0.0060 13.87 0.0037 14.86 0.0020 15.86 0.0008 16.84 0.0005 17.84 0.0025 18.83 0.0010 19.81 0.0020 20.81 0.0017 21.80 0.0013 22.79 0.0016 23.78 0.0009 24.77 0.0006 25.76 0.0002 ) constant sax-c5 #( 0.98 0.0251 1.97 0.0316 2.95 0.0599 3.93 0.0403 4.92 0.0418 5.90 0.0065 6.89 0.0047 7.86 0.0085 8.85 0.0061 9.84 0.0097 10.82 0.0033 10.87 0.0006 12.26 0.0004 12.78 0.0040 13.77 0.0023 14.75 0.0020 15.73 0.0003 16.72 0.0011 17.71 0.0012 18.69 0.0013 19.67 0.0008 20.66 0.0013 21.64 0.0005 22.62 0.0004 23.60 0.0005 ) constant sax-cs5 #( 0.99 0.0055 1.97 0.0823 2.95 0.0106 3.94 0.0646 4.93 0.0345 5.91 0.0069 6.90 0.0201 7.89 0.0165 8.87 0.0171 9.86 0.0114 10.85 0.0050 11.82 0.0053 12.82 0.0107 13.81 0.0033 14.78 0.0026 15.78 0.0016 16.76 0.0019 17.74 0.0011 18.72 0.0030 19.73 0.0009 20.70 0.0021 21.67 0.0003 22.67 0.0003 23.65 0.0001 ) constant sax-d5 #( 0.98 0.0699 1.97 0.0761 2.95 0.0777 3.93 0.0573 4.92 0.0236 5.90 0.0082 6.88 0.0195 7.87 0.0108 8.85 0.0205 9.83 0.0042 10.82 0.0112 11.80 0.0039 12.78 0.0018 13.77 0.0027 14.75 0.0017 15.73 0.0015 16.72 0.0019 17.70 0.0047 18.68 0.0011 19.67 0.0020 20.65 0.0027 21.63 0.0002 ) constant sax-ds5 #( 0.99 0.1082 1.99 0.1222 2.99 0.0874 3.98 0.0436 4.98 0.0208 5.98 0.0141 6.97 0.0193 7.97 0.0172 8.97 0.0118 9.96 0.0082 10.96 0.0133 11.96 0.0062 12.95 0.0058 13.95 0.0013 14.94 0.0017 15.94 0.0029 16.94 0.0032 17.93 0.0006 18.93 0.0028 19.92 0.0004 ) constant sax-e5 #( 1.00 0.1462 2.00 0.0665 3.01 0.0741 4.01 0.0382 5.01 0.0262 6.02 0.0172 7.02 0.0168 8.02 0.0172 9.02 0.0087 10.02 0.0145 11.03 0.0046 12.03 0.0033 13.03 0.0032 14.03 0.0030 15.03 0.0040 16.04 0.0059 17.04 0.0026 18.04 0.0005 19.05 0.0009 ) constant sax-f5 #( 1.00 0.0652 2.00 0.0563 3.00 0.0939 3.99 0.0334 5.00 0.0109 5.99 0.0258 6.99 0.0213 7.99 0.0135 8.99 0.0018 9.99 0.0205 10.99 0.0043 11.99 0.0004 12.99 0.0037 13.98 0.0017 14.98 0.0071 15.98 0.0035 16.98 0.0029 17.98 0.0005 ) constant sax-fs5 #( 1.00 0.0918 1.99 0.0493 2.99 0.0565 3.98 0.0225 4.98 0.0118 5.98 0.0184 6.97 0.0138 7.99 0.0042 8.98 0.0077 9.95 0.0104 10.96 0.0018 11.94 0.0022 12.98 0.0061 13.96 0.0032 14.96 0.0023 15.96 0.0016 16.90 0.0008 ) constant sax-g5 #( 0.99 0.1447 1.98 0.0908 2.97 0.0522 3.96 0.0607 4.96 0.0316 5.95 0.0115 6.94 0.0147 7.93 0.0148 8.92 0.0221 9.91 0.0097 10.90 0.0087 11.90 0.0078 12.89 0.0127 13.88 0.0042 14.87 0.0007 15.86 0.0012 ) constant sax-gs5 #( 0.97 0.1089 1.94 0.0491 4.85 0.0162 5.82 0.0156 6.78 0.0130 7.75 0.0174 8.72 0.0104 8.75 0.0087 8.77 0.0024 8.80 0.0019 8.82 0.0014 9.72 0.0010 10.66 0.0033 11.63 0.0092 11.66 0.0045 12.59 0.0028 12.65 0.0015 12.67 0.0011 13.64 0.0007 14.56 0.0017 14.59 0.0017 14.61 0.0010 14.62 0.0008 14.64 0.0005 15.50 0.0003 15.53 0.0002 15.56 0.0002 15.58 0.0001 ) constant sax-a5 \ ********************************************************** \ soprano sax \ ********************************************************** #( 1.01 0.0846 2.02 0.0851 3.03 0.0782 4.03 0.0250 5.04 0.0513 6.05 0.0121 7.07 0.0065 8.08 0.0409 9.09 0.0134 10.09 0.0032 11.10 0.0168 12.12 0.0076 13.13 0.0054 14.13 0.0091 15.14 0.0078 16.15 0.0029 17.16 0.0103 18.18 0.0103 19.18 0.0071 20.19 0.0105 21.20 0.0063 22.20 0.0054 23.21 0.0011 24.22 0.0008 25.24 0.0003 26.23 0.0001 27.26 0.0002 28.25 0.0006 29.27 0.0004 30.29 0.0008 31.29 0.0004 32.31 0.0002 33.32 0.0003 34.32 0.0003 35.33 0.0001 36.34 0.0002 37.35 0.0005 38.36 0.0003 39.37 0.0003 40.37 0.0002 41.39 0.0002 42.40 0.0002 43.41 0.0002 44.43 0.0001 45.43 0.0007 46.43 0.0004 47.44 0.0002 48.46 0.0001 49.48 0.0001 50.48 0.0002 51.49 0.0002 52.49 0.0002 53.50 0.0002 54.51 0.0002 55.53 0.0003 56.54 0.0003 57.54 0.0002 58.55 0.0002 59.55 0.0001 ) constant ssax-gs3 #( 0.99 0.1143 1.99 0.0599 2.99 0.0780 3.99 0.0629 4.99 0.0063 5.99 0.0066 6.99 0.0283 7.99 0.0134 8.98 0.0083 9.97 0.0114 10.97 0.0087 11.97 0.0171 12.97 0.0109 13.97 0.0149 14.97 0.0075 15.97 0.0164 16.97 0.0174 17.94 0.0021 18.97 0.0139 19.96 0.0073 20.95 0.0122 21.95 0.0018 22.95 0.0022 23.94 0.0002 24.95 0.0014 25.94 0.0006 26.95 0.0007 27.94 0.0012 28.94 0.0013 29.93 0.0009 30.94 0.0014 31.92 0.0012 32.93 0.0008 33.93 0.0015 34.93 0.0021 35.92 0.0009 36.93 0.0011 37.93 0.0011 38.94 0.0005 39.92 0.0008 41.93 0.0004 42.91 0.0012 43.87 0.0002 44.93 0.0006 45.92 0.0006 46.91 0.0002 47.92 0.0002 48.91 0.0004 49.89 0.0004 50.89 0.0003 51.89 0.0003 52.90 0.0003 53.90 0.0003 54.91 0.0003 55.90 0.0003 56.89 0.0002 ) constant ssax-a3 #( 1.00 0.0772 1.99 0.0797 2.98 0.0350 3.99 0.1086 4.98 0.0418 5.97 0.0170 6.98 0.0247 7.97 0.0288 8.96 0.0041 9.95 0.0047 10.95 0.0120 11.95 0.0176 12.93 0.0128 13.95 0.0151 14.94 0.0162 15.92 0.0152 16.93 0.0077 17.93 0.0111 18.92 0.0092 19.91 0.0079 20.91 0.0053 21.89 0.0009 22.90 0.0008 24.88 0.0004 25.88 0.0009 26.88 0.0009 27.87 0.0014 28.87 0.0008 29.87 0.0023 30.87 0.0013 31.85 0.0012 32.87 0.0015 33.85 0.0011 34.85 0.0024 35.84 0.0021 36.86 0.0024 37.87 0.0008 38.82 0.0007 39.85 0.0009 40.79 0.0007 41.83 0.0009 42.84 0.0007 43.84 0.0006 44.82 0.0001 46.83 0.0004 47.83 0.0003 48.81 0.0003 49.82 0.0002 50.82 0.0001 51.82 0.0002 52.81 0.0002 54.81 0.0004 55.80 0.0002 ) constant ssax-as3 #( 0.99 0.0413 1.98 0.0949 2.98 0.0746 3.96 0.0636 4.96 0.0383 5.95 0.0300 6.93 0.0190 7.93 0.0159 8.92 0.0172 9.90 0.0159 10.90 0.0047 11.89 0.0087 12.88 0.0153 13.87 0.0129 14.87 0.0112 15.85 0.0054 16.84 0.0076 17.84 0.0060 18.82 0.0064 19.81 0.0050 20.81 0.0009 21.80 0.0013 22.78 0.0003 23.79 0.0005 24.78 0.0005 25.76 0.0020 26.75 0.0020 27.75 0.0016 28.73 0.0012 29.72 0.0009 30.72 0.0017 31.70 0.0018 32.69 0.0012 33.69 0.0022 34.67 0.0014 35.67 0.0015 36.66 0.0009 37.65 0.0013 38.64 0.0019 39.63 0.0010 40.62 0.0012 41.61 0.0003 42.61 0.0003 43.60 0.0003 44.58 0.0004 45.58 0.0003 47.55 0.0004 48.54 0.0002 49.54 0.0003 50.53 0.0002 51.52 0.0002 ) constant ssax-b3 #( 0.99 0.1251 1.98 0.0932 2.97 0.1614 3.97 0.0801 4.96 0.0100 5.94 0.0183 6.94 0.0221 7.93 0.0060 8.92 0.0055 9.91 0.0162 10.90 0.0171 11.89 0.0181 12.88 0.0135 13.88 0.0102 14.87 0.0071 15.86 0.0066 16.84 0.0071 17.83 0.0057 18.83 0.0027 19.82 0.0006 20.82 0.0008 21.80 0.0003 22.78 0.0007 23.78 0.0011 24.77 0.0019 25.77 0.0010 26.76 0.0016 27.74 0.0008 28.74 0.0013 29.73 0.0025 30.72 0.0019 31.71 0.0029 32.70 0.0022 33.69 0.0011 34.68 0.0014 35.68 0.0010 36.67 0.0014 37.65 0.0007 38.64 0.0005 39.62 0.0001 40.63 0.0004 41.62 0.0006 42.61 0.0005 43.60 0.0003 44.58 0.0003 45.58 0.0003 46.58 0.0006 47.57 0.0003 48.56 0.0002 ) constant ssax-c4 #( 0.98 0.0809 1.97 0.0745 2.96 0.1141 3.95 0.0537 4.95 0.0028 5.92 0.0112 6.93 0.0029 7.90 0.0117 8.89 0.0101 9.89 0.0091 10.87 0.0113 11.86 0.0048 12.85 0.0076 13.84 0.0054 14.82 0.0089 15.81 0.0068 16.80 0.0065 17.79 0.0031 18.77 0.0009 19.76 0.0007 20.75 0.0005 21.73 0.0010 22.72 0.0016 23.71 0.0009 24.70 0.0016 25.68 0.0010 26.68 0.0018 27.66 0.0018 28.65 0.0009 29.64 0.0012 30.63 0.0017 31.61 0.0016 32.60 0.0008 33.59 0.0012 34.58 0.0014 35.57 0.0005 36.56 0.0006 37.54 0.0008 38.53 0.0005 39.52 0.0004 40.50 0.0004 41.49 0.0001 42.47 0.0004 43.46 0.0002 ) constant ssax-cs4 #( 0.99 0.0919 1.98 0.0711 2.98 0.0924 3.97 0.0396 4.95 0.0407 5.94 0.0357 6.93 0.0035 7.93 0.0079 8.91 0.0110 9.90 0.0191 10.89 0.0103 11.89 0.0134 12.88 0.0025 13.86 0.0014 14.86 0.0082 15.85 0.0084 16.84 0.0024 17.82 0.0011 18.82 0.0011 19.81 0.0010 20.80 0.0002 21.79 0.0015 22.78 0.0011 23.76 0.0025 24.77 0.0018 25.75 0.0027 26.74 0.0036 27.73 0.0023 28.73 0.0034 29.72 0.0032 30.70 0.0011 31.70 0.0017 32.69 0.0014 33.68 0.0013 34.66 0.0004 35.65 0.0003 36.64 0.0002 37.63 0.0002 38.62 0.0004 39.62 0.0008 40.61 0.0004 41.60 0.0005 42.59 0.0005 43.59 0.0003 44.56 0.0002 ) constant ssax-d4 #( 0.99 0.0684 1.98 0.0744 2.97 0.1315 3.96 0.0137 4.94 0.0352 5.94 0.0195 6.93 0.0148 7.91 0.0275 8.91 0.0191 9.90 0.0268 10.88 0.0194 11.86 0.0044 12.86 0.0046 13.85 0.0090 14.84 0.0072 15.83 0.0049 16.82 0.0015 17.80 0.0017 18.80 0.0006 19.79 0.0008 20.77 0.0020 21.76 0.0010 22.75 0.0025 23.74 0.0033 24.73 0.0023 25.72 0.0041 26.71 0.0051 27.70 0.0043 28.69 0.0033 29.68 0.0010 30.66 0.0013 31.65 0.0013 32.64 0.0013 33.63 0.0008 34.64 0.0001 35.61 0.0002 36.60 0.0003 37.62 0.0002 38.58 0.0006 39.57 0.0005 40.58 0.0001 41.55 0.0002 ) constant ssax-ds4 #( 1.00 0.0363 1.98 0.1101 2.98 0.1009 3.96 0.0168 4.95 0.0610 5.95 0.0099 6.94 0.0066 7.93 0.0157 8.92 0.0162 9.91 0.0154 10.90 0.0131 11.89 0.0061 12.88 0.0029 13.87 0.0058 14.86 0.0040 15.85 0.0015 16.84 0.0012 17.84 0.0005 18.82 0.0005 19.81 0.0008 20.85 0.0007 21.80 0.0005 22.78 0.0016 23.77 0.0017 24.76 0.0022 25.76 0.0010 26.80 0.0006 27.74 0.0012 28.72 0.0007 29.71 0.0004 30.70 0.0004 31.69 0.0001 32.68 0.0001 33.67 0.0003 34.65 0.0004 35.65 0.0003 36.64 0.0003 37.63 0.0002 38.61 0.0002 ) constant ssax-e4 #( 1.00 0.0607 1.99 0.1291 3.00 0.0576 3.99 0.0530 4.99 0.0330 5.98 0.0364 6.98 0.0116 7.98 0.0252 8.97 0.0175 9.97 0.0166 10.97 0.0147 11.97 0.0096 12.96 0.0060 13.96 0.0022 14.95 0.0018 15.95 0.0018 16.96 0.0003 17.94 0.0012 18.94 0.0021 19.94 0.0051 20.94 0.0018 21.93 0.0034 22.93 0.0038 23.93 0.0035 24.92 0.0041 25.92 0.0015 26.91 0.0024 27.92 0.0019 28.92 0.0008 29.91 0.0005 30.92 0.0003 31.91 0.0005 32.91 0.0006 33.90 0.0003 34.89 0.0002 35.89 0.0005 36.89 0.0002 ) constant ssax-f4 #( 0.99 0.0502 1.98 0.0678 2.96 0.0319 3.95 0.0589 4.93 0.0093 5.93 0.0072 6.91 0.0063 7.89 0.0224 8.88 0.0185 9.87 0.0096 10.86 0.0046 11.84 0.0060 12.83 0.0052 13.82 0.0008 14.80 0.0022 15.79 0.0009 16.79 0.0008 17.76 0.0011 18.75 0.0024 19.74 0.0013 20.71 0.0009 21.71 0.0038 22.70 0.0037 23.68 0.0023 24.66 0.0010 25.66 0.0007 26.64 0.0009 27.64 0.0007 28.61 0.0002 29.61 0.0006 30.60 0.0004 31.58 0.0008 32.56 0.0004 33.55 0.0005 35.53 0.0002 ) constant ssax-fs4 #( 1.00 0.0253 1.99 0.0803 2.98 0.0107 3.97 0.0688 4.96 0.0361 5.96 0.0208 6.96 0.0172 7.95 0.0172 8.94 0.0189 9.93 0.0080 10.92 0.0114 11.92 0.0059 12.91 0.0058 13.90 0.0007 14.89 0.0011 15.89 0.0011 16.88 0.0023 17.87 0.0046 18.87 0.0024 19.85 0.0043 20.86 0.0087 21.83 0.0023 22.84 0.0043 23.84 0.0039 24.83 0.0020 25.81 0.0017 26.81 0.0009 27.82 0.0006 28.80 0.0004 29.79 0.0007 30.80 0.0005 31.78 0.0011 32.78 0.0004 33.76 0.0001 ) constant ssax-g4 #( 1.00 0.0453 2.00 0.1198 2.99 0.0370 3.99 0.1319 4.98 0.0327 5.97 0.0018 6.98 0.0199 7.97 0.0362 8.97 0.0196 9.96 0.0065 10.96 0.0061 11.96 0.0025 12.95 0.0026 13.95 0.0010 14.94 0.0005 15.94 0.0027 16.94 0.0031 17.93 0.0037 18.92 0.0019 19.92 0.0034 20.92 0.0087 21.92 0.0034 22.91 0.0029 23.91 0.0024 24.90 0.0006 25.90 0.0002 26.90 0.0009 27.90 0.0003 28.90 0.0015 29.89 0.0011 30.89 0.0004 31.88 0.0001 ) constant ssax-gs4 #( 1.00 0.0568 1.99 0.1275 2.98 0.0496 3.98 0.0504 4.97 0.0277 5.96 0.0064 6.95 0.0205 7.95 0.0244 8.94 0.0067 9.93 0.0133 10.92 0.0045 11.92 0.0035 12.91 0.0028 13.90 0.0010 14.90 0.0011 15.89 0.0035 16.89 0.0034 17.88 0.0037 18.87 0.0052 19.86 0.0027 20.86 0.0028 21.86 0.0003 22.84 0.0011 23.84 0.0005 24.83 0.0010 25.82 0.0005 26.81 0.0003 27.81 0.0007 28.80 0.0005 29.79 0.0004 ) constant ssax-a4 #( 0.99 0.0497 1.98 0.0814 2.97 0.0351 3.96 0.0207 4.95 0.0068 5.93 0.0241 6.92 0.0219 7.91 0.0187 8.90 0.0053 9.88 0.0026 10.88 0.0026 11.87 0.0027 12.85 0.0011 13.85 0.0018 14.84 0.0029 15.84 0.0013 16.83 0.0014 17.81 0.0036 18.80 0.0042 19.79 0.0015 20.78 0.0021 21.77 0.0018 22.76 0.0011 23.75 0.0004 24.66 0.0003 25.73 0.0006 26.72 0.0005 27.71 0.0002 ) constant ssax-as4 #( 0.99 0.0161 1.98 0.0825 2.96 0.0846 3.95 0.0304 4.94 0.0112 5.93 0.0158 6.91 0.0362 7.90 0.0085 8.89 0.0147 9.87 0.0047 10.85 0.0016 11.85 0.0044 12.84 0.0024 13.83 0.0044 14.82 0.0015 15.80 0.0066 16.79 0.0061 17.78 0.0135 18.77 0.0107 19.75 0.0020 20.75 0.0008 21.73 0.0010 22.71 0.0014 23.70 0.0007 24.69 0.0009 25.68 0.0008 26.67 0.0002 ) constant ssax-b4 #( 1.00 0.1378 1.99 0.1932 2.99 0.0181 3.98 0.0213 4.97 0.0472 5.97 0.0302 6.97 0.0099 7.96 0.0039 8.96 0.0052 9.95 0.0031 10.95 0.0007 11.94 0.0010 12.93 0.0015 13.93 0.0009 14.93 0.0013 15.92 0.0018 16.92 0.0015 17.91 0.0030 18.91 0.0013 19.90 0.0008 20.90 0.0008 21.89 0.0006 22.89 0.0006 23.89 0.0003 ) constant ssax-c5 #( 0.99 0.1332 1.97 0.2232 2.96 0.1240 3.95 0.0080 4.94 0.0398 5.93 0.0194 6.92 0.0059 7.90 0.0022 8.91 0.0008 9.88 0.0017 10.87 0.0005 11.85 0.0004 12.84 0.0008 13.83 0.0009 14.82 0.0032 15.81 0.0009 16.81 0.0017 17.78 0.0009 18.77 0.0003 19.76 0.0002 20.75 0.0006 21.74 0.0004 22.73 0.0002 ) constant ssax-cs5 #( 0.99 0.1242 1.98 0.0414 2.97 0.0487 3.96 0.0182 4.95 0.0225 5.94 0.0112 6.93 0.0012 7.92 0.0035 8.87 0.0004 9.90 0.0011 10.89 0.0006 11.88 0.0004 12.81 0.0008 13.87 0.0011 14.86 0.0015 15.84 0.0005 16.83 0.0002 17.82 0.0005 18.46 0.0002 19.82 0.0002 20.81 0.0002 21.66 0.0001 ) constant ssax-d5 #( 0.99 0.1419 1.98 0.0180 2.98 0.0683 3.96 0.0172 4.95 0.0329 5.94 0.0093 6.93 0.0017 7.91 0.0014 8.91 0.0022 9.90 0.0018 10.88 0.0004 11.89 0.0011 12.88 0.0009 13.87 0.0010 14.83 0.0007 15.85 0.0004 16.85 0.0002 17.85 0.0003 18.85 0.0003 20.81 0.0001 ) constant ssax-ds5 #( 1.00 0.2435 1.99 0.0422 2.99 0.0422 3.98 0.0137 4.97 0.0155 5.97 0.0127 6.96 0.0024 7.96 0.0014 8.95 0.0017 9.95 0.0011 10.94 0.0006 11.94 0.0009 12.93 0.0022 13.92 0.0048 14.92 0.0004 15.91 0.0006 16.91 0.0003 17.90 0.0002 18.89 0.0002 19.89 0.0002 ) constant ssax-e5 #( 1.00 0.2095 2.00 0.0502 3.01 0.0783 4.01 0.0216 5.01 0.0293 6.01 0.0080 7.01 0.0043 8.02 0.0036 9.02 0.0019 10.02 0.0002 11.02 0.0013 12.02 0.0010 13.02 0.0007 14.03 0.0010 15.03 0.0003 16.03 0.0013 17.04 0.0009 18.04 0.0005 ) constant ssax-f5 #( 0.99 0.1379 1.98 0.0339 2.98 0.0480 3.97 0.0340 4.96 0.0264 5.95 0.0126 6.94 0.0046 7.93 0.0030 8.92 0.0013 9.91 0.0010 10.90 0.0009 11.89 0.0007 12.88 0.0007 13.88 0.0018 14.87 0.0012 15.86 0.0006 16.85 0.0004 17.84 0.0007 ) constant ssax-fs5 #( 0.99 0.0699 1.98 0.0273 2.96 0.0227 3.95 0.0133 4.94 0.0151 5.92 0.0023 6.92 0.0024 7.91 0.0011 8.90 0.0009 9.89 0.0018 10.87 0.0009 11.88 0.0016 12.86 0.0007 13.84 0.0008 14.83 0.0007 15.82 0.0005 16.81 0.0003 ) constant ssax-g5 #( 1.00 0.1830 1.99 0.0897 2.99 0.0456 3.99 0.0296 4.99 0.0125 5.98 0.0059 6.98 0.0105 7.98 0.0027 8.97 0.0044 9.97 0.0096 10.97 0.0011 11.97 0.0027 12.97 0.0006 13.97 0.0024 14.96 0.0014 15.95 0.0002 ) constant ssax-gs5 #( 0.99 0.2010 1.98 0.0677 2.97 0.0195 3.97 0.0363 4.96 0.0191 5.95 0.0092 6.94 0.0047 7.93 0.0021 7.96 0.0004 8.91 0.0004 9.92 0.0039 10.90 0.0023 11.91 0.0005 12.88 0.0008 12.91 0.0002 13.86 0.0002 14.87 0.0007 ) constant ssax-a5 #( 1.00 0.1011 1.99 0.0696 2.99 0.0359 3.98 0.0008 4.99 0.0111 5.98 0.0027 6.98 0.0005 7.98 0.0038 8.98 0.0032 9.98 0.0037 10.97 0.0024 11.97 0.0012 12.97 0.0009 13.97 0.0004 ) constant ssax-as5 #( 0.98 0.0933 1.95 0.0632 2.93 0.0226 4.89 0.0036 5.86 0.0133 6.84 0.0018 7.82 0.0036 8.79 0.0037 9.77 0.0111 10.75 0.0011 11.72 0.0009 12.70 0.0013 ) constant ssax-b5 #( 1.01 0.0218 1.98 0.0033 3.00 0.0037 3.99 0.0010 4.03 0.0009 4.77 0.0002 4.95 0.0002 6.01 0.0001 7.00 0.0002 8.02 0.0004 9.03 0.0004 10.03 0.0003 12.03 0.0001 ) constant ssax-c6 #( 0.99 0.1143 1.99 0.0478 2.99 0.0259 3.97 0.0101 4.97 0.0058 5.96 0.0010 6.95 0.0012 7.98 0.0017 8.95 0.0024 8.98 0.0016 9.96 0.0007 10.93 0.0019 10.96 0.0010 11.90 0.0003 11.95 0.0002 ) constant ssax-cs6 #( 1.01 0.0247 2.02 0.0062 3.02 0.0036 4.03 0.0052 5.05 0.0006 6.07 0.0004 7.06 0.0013 8.07 0.0027 11.11 0.0001 ) constant ssax-d6 \ ********************************************************** \ \ ********************************************************** #( 1.01 0.0028 2.00 0.0192 3.04 0.0188 4.02 0.0134 5.02 0.0319 6.05 0.0335 7.04 0.0136 8.06 0.0074 9.07 0.0527 10.06 0.0217 11.05 0.0025 12.09 0.0068 13.08 0.0278 14.10 0.0125 15.09 0.0152 16.13 0.0101 17.13 0.0088 18.11 0.0094 19.14 0.0084 20.20 0.0008 21.13 0.0031 22.16 0.0097 23.14 0.0053 24.17 0.0030 25.20 0.0013 26.17 0.0055 27.20 0.0049 28.19 0.0040 29.21 0.0010 30.21 0.0030 31.20 0.0032 32.24 0.0031 33.21 0.0006 34.23 0.0015 35.25 0.0020 36.23 0.0012 37.25 0.0010 38.29 0.0007 39.26 0.0017 40.29 0.0014 41.27 0.0015 42.29 0.0005 43.32 0.0012 44.30 0.0014 45.32 0.0010 46.32 0.0005 47.31 0.0003 48.34 0.0009 49.32 0.0005 50.34 0.0005 51.35 0.0001 52.35 0.0005 53.37 0.0006 54.37 0.0006 55.38 0.0001 56.38 0.0002 57.39 0.0006 58.41 0.0005 59.42 0.0004 60.42 0.0001 61.43 0.0004 62.41 0.0004 63.42 0.0003 64.45 0.0002 65.46 0.0001 66.45 0.0003 67.48 0.0003 68.46 0.0001 69.50 0.0001 70.49 0.0004 71.48 0.0002 72.47 0.0001 74.52 0.0002 75.51 0.0002 76.51 0.0002 79.55 0.0002 80.56 0.0002 81.55 0.0001 83.58 0.0002 84.57 0.0001 85.59 0.0002 87.60 0.0002 88.59 0.0001 89.61 0.0002 92.62 0.0001 93.64 0.0001 96.67 0.0001 98.69 0.0001 ) constant tbf-e2 #( 0.99 0.0062 2.00 0.0189 3.01 0.0059 4.03 0.0167 5.01 0.0454 6.01 0.0190 7.03 0.0261 8.04 0.0495 9.04 0.0195 10.01 0.0059 11.02 0.0030 12.05 0.0247 13.04 0.0097 14.05 0.0122 15.04 0.0076 16.03 0.0044 17.05 0.0063 18.06 0.0045 19.06 0.0011 20.05 0.0028 21.07 0.0056 22.07 0.0019 22.55 0.0004 23.17 0.0001 24.07 0.0026 25.08 0.0016 26.10 0.0017 27.11 0.0006 28.09 0.0011 29.10 0.0014 30.10 0.0011 31.13 0.0007 32.12 0.0006 33.11 0.0009 34.10 0.0004 35.15 0.0002 36.15 0.0004 37.13 0.0006 38.11 0.0004 39.11 0.0002 40.15 0.0003 41.13 0.0004 42.13 0.0003 43.17 0.0002 44.20 0.0002 45.16 0.0002 46.18 0.0003 48.16 0.0001 49.20 0.0002 50.20 0.0002 51.21 0.0001 54.20 0.0001 ) constant tbf-f2 #( 1.02 0.0056 2.01 0.0355 3.01 0.0221 3.99 0.0130 4.99 0.0606 6.00 0.0189 7.01 0.0127 8.02 0.0612 9.01 0.0211 10.01 0.0079 10.99 0.0134 11.99 0.0205 13.00 0.0282 14.03 0.0114 15.02 0.0079 16.01 0.0116 17.00 0.0082 18.02 0.0015 19.00 0.0052 20.03 0.0082 21.03 0.0057 22.05 0.0011 23.02 0.0048 24.01 0.0035 25.01 0.0032 26.02 0.0012 27.04 0.0033 28.01 0.0015 29.03 0.0013 30.05 0.0008 31.03 0.0024 32.02 0.0010 33.02 0.0007 34.05 0.0007 35.05 0.0013 36.04 0.0008 37.03 0.0004 38.02 0.0004 39.03 0.0008 40.03 0.0005 42.07 0.0005 43.05 0.0006 44.05 0.0003 45.10 0.0002 46.05 0.0003 47.05 0.0003 48.05 0.0002 50.08 0.0003 51.07 0.0003 52.06 0.0002 53.09 0.0001 54.00 0.0001 55.06 0.0002 56.09 0.0002 57.10 0.0001 58.08 0.0001 59.05 0.0001 60.09 0.0001 62.09 0.0001 63.06 0.0001 66.13 0.0001 ) constant tbf-fs2 #( 0.99 0.0059 1.98 0.0515 2.98 0.0305 3.98 0.0081 4.97 0.0448 5.98 0.0160 6.97 0.0397 7.97 0.0418 8.93 0.0079 9.96 0.0086 10.95 0.0358 11.96 0.0207 12.94 0.0116 13.94 0.0070 14.93 0.0156 15.94 0.0120 16.98 0.0013 17.94 0.0060 18.91 0.0074 19.94 0.0070 20.94 0.0013 21.92 0.0060 22.91 0.0043 23.89 0.0014 24.95 0.0017 25.91 0.0031 26.90 0.0022 27.90 0.0009 28.91 0.0017 29.89 0.0016 30.88 0.0012 31.86 0.0004 32.88 0.0013 33.89 0.0008 34.85 0.0005 35.83 0.0005 36.85 0.0008 37.87 0.0006 38.87 0.0001 39.86 0.0004 40.90 0.0008 41.86 0.0005 42.88 0.0003 43.86 0.0005 44.84 0.0005 45.89 0.0003 46.92 0.0002 47.86 0.0003 48.77 0.0002 49.85 0.0002 50.86 0.0002 51.81 0.0003 52.88 0.0001 53.87 0.0001 54.80 0.0002 55.77 0.0001 56.88 0.0002 58.76 0.0001 59.82 0.0001 62.83 0.0001 63.88 0.0001 73.81 0.0001 ) constant tbf-g2 #( 0.99 0.0058 1.98 0.0327 2.99 0.0282 3.99 0.0353 4.98 0.0348 5.96 0.0451 6.97 0.0549 7.97 0.0183 8.96 0.0096 9.94 0.0221 10.94 0.0110 11.93 0.0102 12.92 0.0074 13.92 0.0109 14.91 0.0080 15.15 0.0013 15.91 0.0003 16.90 0.0034 17.88 0.0030 18.88 0.0036 19.14 0.0004 20.05 0.0003 20.86 0.0029 21.87 0.0014 22.84 0.0008 23.85 0.0021 24.83 0.0011 25.81 0.0007 26.80 0.0003 27.81 0.0010 28.82 0.0003 29.84 0.0003 30.77 0.0006 31.75 0.0002 32.78 0.0005 33.79 0.0003 34.77 0.0003 35.78 0.0003 37.75 0.0002 38.72 0.0002 41.75 0.0001 42.73 0.0001 45.69 0.0001 ) constant tbf-gs2 #( 1.00 0.0085 1.99 0.0291 2.99 0.0151 4.00 0.0554 5.00 0.0164 6.02 0.0087 7.00 0.0365 8.06 0.0023 9.02 0.0098 9.98 0.0165 10.97 0.0176 11.97 0.0107 12.98 0.0081 13.97 0.0077 14.97 0.0012 15.99 0.0038 16.98 0.0028 17.97 0.0017 18.97 0.0024 19.98 0.0014 20.95 0.0017 21.92 0.0009 23.01 0.0009 23.98 0.0006 24.94 0.0004 25.95 0.0013 26.95 0.0003 27.99 0.0002 28.97 0.0006 29.96 0.0002 30.90 0.0003 31.89 0.0003 32.83 0.0002 33.02 0.0001 33.78 0.0001 34.94 0.0001 35.94 0.0002 38.91 0.0002 39.88 0.0001 ) constant tbf-a2 #( 1.00 0.0251 2.05 0.0009 3.02 0.0385 4.03 0.0997 5.03 0.0337 6.04 0.1061 7.04 0.0539 8.05 0.0357 9.06 0.0635 10.06 0.0233 11.05 0.0153 12.07 0.0218 13.07 0.0235 14.08 0.0092 15.08 0.0135 16.09 0.0104 17.09 0.0055 18.10 0.0130 19.11 0.0059 20.12 0.0030 21.12 0.0060 22.12 0.0029 23.12 0.0032 24.13 0.0022 25.14 0.0016 26.14 0.0007 27.15 0.0032 28.15 0.0014 29.16 0.0012 30.15 0.0015 31.18 0.0011 32.19 0.0008 33.18 0.0014 34.19 0.0007 35.19 0.0003 36.18 0.0009 37.16 0.0004 39.21 0.0007 40.22 0.0006 41.23 0.0001 42.20 0.0004 43.24 0.0007 45.25 0.0007 46.26 0.0004 47.32 0.0001 48.26 0.0004 49.26 0.0003 51.29 0.0003 52.28 0.0002 54.30 0.0003 55.32 0.0002 57.31 0.0002 58.32 0.0001 60.31 0.0002 61.30 0.0001 63.35 0.0001 64.34 0.0001 66.37 0.0001 ) constant tbf-as2 #( 1.02 0.0294 2.03 0.0276 3.03 0.0170 4.05 0.0409 5.06 0.0434 6.06 0.0552 7.06 0.0128 8.08 0.0076 9.07 0.0216 10.08 0.0169 11.07 0.0035 12.09 0.0094 13.10 0.0046 14.12 0.0021 15.12 0.0059 16.13 0.0023 17.15 0.0039 18.16 0.0035 19.17 0.0015 20.18 0.0020 21.19 0.0023 22.19 0.0005 23.22 0.0022 24.24 0.0010 25.27 0.0006 26.26 0.0008 27.27 0.0010 28.28 0.0003 29.28 0.0006 30.27 0.0005 31.32 0.0003 32.30 0.0004 33.29 0.0004 35.37 0.0004 36.34 0.0002 37.38 0.0002 38.38 0.0003 39.48 0.0002 41.43 0.0003 42.40 0.0001 44.50 0.0001 45.47 0.0001 47.46 0.0001 ) constant tbf-b2 #( 1.01 0.0167 2.00 0.0116 3.00 0.0033 3.99 0.0432 5.01 0.0116 6.00 0.0573 7.00 0.0128 8.00 0.0582 9.02 0.0354 10.01 0.0203 11.00 0.0226 12.00 0.0167 13.03 0.0055 14.02 0.0174 15.01 0.0088 16.01 0.0083 17.03 0.0066 18.03 0.0022 19.01 0.0058 20.01 0.0049 21.03 0.0016 22.03 0.0053 23.03 0.0028 24.01 0.0013 25.03 0.0028 26.03 0.0015 27.00 0.0003 28.02 0.0026 28.39 0.0002 29.70 0.0002 30.03 0.0014 31.03 0.0010 32.04 0.0007 33.03 0.0010 34.03 0.0007 35.04 0.0004 36.03 0.0009 37.03 0.0004 38.05 0.0006 39.04 0.0008 40.03 0.0003 41.04 0.0004 42.04 0.0005 43.06 0.0003 44.02 0.0004 45.03 0.0002 46.08 0.0001 47.05 0.0004 48.03 0.0002 49.06 0.0001 50.05 0.0003 51.06 0.0002 52.07 0.0002 53.04 0.0002 54.05 0.0001 55.05 0.0002 56.05 0.0001 58.05 0.0002 59.06 0.0001 61.05 0.0002 ) constant tbf-c3 #( 1.00 0.0192 1.98 0.0300 2.99 0.0565 3.98 0.0329 4.97 0.0791 5.98 0.0457 6.96 0.0053 7.95 0.0405 8.96 0.0260 9.95 0.0146 10.93 0.0283 11.95 0.0038 12.93 0.0205 13.92 0.0086 14.93 0.0028 15.91 0.0069 16.91 0.0030 17.91 0.0095 18.89 0.0058 19.90 0.0023 20.89 0.0048 21.87 0.0015 22.89 0.0033 23.88 0.0021 24.87 0.0003 25.87 0.0030 26.86 0.0014 27.85 0.0016 28.86 0.0021 29.85 0.0005 30.83 0.0019 31.84 0.0014 32.83 0.0005 33.82 0.0012 34.82 0.0006 35.81 0.0008 36.82 0.0011 37.81 0.0004 38.78 0.0004 39.80 0.0005 40.79 0.0004 41.77 0.0007 42.77 0.0002 43.78 0.0004 44.76 0.0005 45.77 0.0003 46.76 0.0003 47.75 0.0002 48.75 0.0002 49.75 0.0005 50.74 0.0002 51.73 0.0002 52.73 0.0002 53.72 0.0002 54.73 0.0003 55.70 0.0001 56.70 0.0001 57.71 0.0003 58.71 0.0001 59.70 0.0002 60.70 0.0001 61.69 0.0002 62.69 0.0003 64.67 0.0001 65.67 0.0001 67.64 0.0001 69.65 0.0001 70.63 0.0001 75.62 0.0001 ) constant tbf-cs3 #( 1.01 0.0462 2.01 0.0592 3.00 0.1127 3.99 0.0398 5.00 0.1221 6.02 0.0099 7.01 0.0396 8.01 0.0429 9.00 0.0249 10.00 0.0223 10.27 0.0015 11.03 0.0010 12.01 0.0146 13.01 0.0097 14.00 0.0008 15.00 0.0064 16.01 0.0020 17.02 0.0066 18.02 0.0043 19.02 0.0021 20.01 0.0035 21.02 0.0009 22.02 0.0022 23.03 0.0022 24.00 0.0007 25.02 0.0025 26.02 0.0002 27.03 0.0017 27.30 0.0003 28.73 0.0002 29.03 0.0016 30.02 0.0012 31.02 0.0006 32.04 0.0013 33.04 0.0005 34.02 0.0006 35.01 0.0004 36.03 0.0007 37.03 0.0009 38.05 0.0003 39.05 0.0006 40.04 0.0003 41.04 0.0003 42.04 0.0005 43.05 0.0002 44.06 0.0003 45.05 0.0001 46.05 0.0002 47.04 0.0003 48.06 0.0002 49.06 0.0003 50.06 0.0001 51.06 0.0001 52.04 0.0001 53.06 0.0001 54.06 0.0002 57.06 0.0001 58.07 0.0001 59.06 0.0002 66.09 0.0001 ) constant tbf-d3 #( 1.00 0.0462 2.01 0.0546 3.03 0.1220 4.04 0.0672 5.06 0.0575 6.07 0.0310 7.08 0.0402 8.09 0.0228 9.09 0.0345 10.10 0.0204 11.11 0.0134 12.12 0.0171 13.13 0.0056 14.15 0.0087 15.16 0.0035 16.17 0.0068 17.18 0.0027 18.18 0.0061 19.20 0.0018 20.20 0.0037 21.22 0.0030 22.24 0.0013 23.24 0.0028 23.58 0.0004 24.91 0.0002 25.26 0.0031 26.26 0.0008 27.27 0.0022 28.28 0.0021 29.29 0.0013 30.31 0.0017 31.31 0.0006 32.34 0.0015 33.34 0.0008 34.35 0.0012 35.36 0.0012 36.36 0.0008 37.37 0.0012 38.38 0.0006 39.40 0.0008 40.39 0.0002 41.43 0.0004 42.44 0.0003 43.45 0.0004 44.45 0.0004 45.45 0.0004 46.46 0.0006 47.46 0.0002 48.48 0.0004 49.47 0.0002 50.52 0.0003 51.52 0.0002 52.53 0.0003 53.53 0.0003 54.54 0.0002 55.55 0.0003 57.58 0.0002 58.58 0.0001 59.60 0.0002 60.60 0.0002 61.62 0.0002 62.63 0.0002 63.62 0.0001 64.64 0.0002 66.67 0.0001 68.68 0.0001 69.70 0.0001 71.70 0.0001 ) constant tbf-ds3 #( 1.00 0.0427 2.02 0.0329 3.03 0.0739 4.03 0.0442 5.05 0.0547 6.06 0.0547 7.06 0.0357 8.07 0.0307 9.09 0.0344 10.10 0.0088 11.10 0.0255 12.12 0.0049 13.13 0.0161 14.13 0.0032 15.14 0.0087 16.16 0.0028 17.15 0.0054 18.17 0.0018 19.18 0.0048 20.20 0.0025 21.19 0.0033 22.21 0.0032 23.22 0.0009 24.22 0.0017 25.25 0.0004 26.24 0.0011 26.54 0.0002 27.27 0.0002 28.26 0.0012 28.54 0.0002 29.26 0.0001 30.29 0.0009 31.29 0.0003 32.30 0.0007 33.32 0.0005 34.32 0.0007 35.32 0.0005 36.35 0.0004 37.36 0.0004 38.38 0.0002 39.37 0.0004 41.39 0.0004 42.42 0.0001 43.40 0.0002 45.43 0.0002 47.45 0.0002 48.45 0.0001 49.46 0.0001 50.48 0.0002 51.49 0.0001 52.49 0.0001 54.52 0.0001 56.54 0.0001 ) constant tbf-e3 #( 1.01 0.0430 2.02 0.0658 3.02 0.0533 4.02 0.1351 5.04 0.0653 6.03 0.0900 7.05 0.0410 8.05 0.0344 9.07 0.0169 10.07 0.0220 11.08 0.0159 12.08 0.0180 13.08 0.0045 14.09 0.0098 15.08 0.0023 16.10 0.0022 17.12 0.0040 18.12 0.0030 19.13 0.0031 20.14 0.0014 21.14 0.0019 22.15 0.0012 23.16 0.0015 24.16 0.0007 25.16 0.0010 26.17 0.0009 27.19 0.0009 28.19 0.0004 29.20 0.0009 30.19 0.0002 31.21 0.0007 32.23 0.0003 33.23 0.0005 35.24 0.0004 36.33 0.0001 37.25 0.0003 38.26 0.0002 39.27 0.0003 41.29 0.0002 42.29 0.0001 43.30 0.0002 45.31 0.0001 46.33 0.0001 ) constant tbf-f3 #( 1.00 0.0676 1.99 0.0337 3.00 0.0651 4.00 0.0928 4.99 0.0773 6.00 0.0359 6.99 0.0266 7.99 0.0183 9.00 0.0246 9.99 0.0092 10.98 0.0144 11.99 0.0027 12.98 0.0112 13.98 0.0019 14.99 0.0058 15.97 0.0010 16.97 0.0024 17.98 0.0033 18.97 0.0025 19.97 0.0024 20.98 0.0018 21.97 0.0030 22.98 0.0013 23.97 0.0026 24.19 0.0004 24.97 0.0003 25.97 0.0026 26.96 0.0003 27.96 0.0018 28.97 0.0006 29.96 0.0012 30.96 0.0012 31.97 0.0011 32.96 0.0012 33.95 0.0006 34.96 0.0008 35.95 0.0003 36.95 0.0009 37.95 0.0002 38.95 0.0005 39.95 0.0002 40.95 0.0005 41.95 0.0003 42.95 0.0005 43.95 0.0002 44.94 0.0003 45.95 0.0003 46.94 0.0001 47.94 0.0002 49.94 0.0003 50.94 0.0001 51.94 0.0003 53.93 0.0002 55.93 0.0002 56.93 0.0001 57.93 0.0002 58.93 0.0001 59.93 0.0001 60.93 0.0001 62.93 0.0001 64.91 0.0001 ) constant tbf-fs3 #( 1.01 0.1108 2.02 0.0159 3.03 0.0749 4.03 0.0774 5.05 0.0554 6.06 0.0287 7.06 0.0529 8.08 0.0167 9.09 0.0172 10.09 0.0181 11.10 0.0072 12.12 0.0148 13.11 0.0028 14.13 0.0060 15.14 0.0012 16.14 0.0047 17.15 0.0034 18.17 0.0009 19.17 0.0041 20.18 0.0007 21.20 0.0016 22.20 0.0011 23.21 0.0022 24.23 0.0010 25.24 0.0008 26.24 0.0015 27.25 0.0003 28.26 0.0011 29.26 0.0009 30.28 0.0009 31.29 0.0007 32.29 0.0002 33.31 0.0005 34.32 0.0001 35.32 0.0006 36.33 0.0002 37.35 0.0003 38.34 0.0004 40.37 0.0003 42.39 0.0002 43.40 0.0002 44.40 0.0001 45.41 0.0002 47.44 0.0002 50.47 0.0001 52.48 0.0001 54.49 0.0001 ) constant tbf-g3 #( 1.01 0.0962 2.01 0.0925 3.01 0.0770 4.03 0.0479 5.03 0.1190 6.03 0.0237 7.03 0.0168 8.05 0.0283 9.05 0.0100 10.05 0.0292 11.06 0.0097 12.07 0.0103 13.07 0.0121 14.07 0.0042 15.08 0.0012 16.09 0.0051 17.09 0.0023 18.09 0.0058 19.11 0.0009 20.11 0.0029 21.11 0.0028 22.12 0.0011 23.13 0.0028 24.12 0.0013 25.13 0.0016 26.14 0.0014 27.14 0.0009 28.15 0.0016 29.16 0.0007 30.16 0.0007 31.16 0.0010 32.17 0.0004 33.18 0.0006 34.18 0.0005 35.18 0.0003 36.19 0.0006 37.20 0.0003 38.20 0.0003 39.21 0.0004 40.22 0.0002 41.22 0.0004 42.23 0.0001 43.23 0.0002 44.24 0.0002 46.25 0.0003 47.25 0.0001 48.26 0.0002 49.26 0.0001 51.28 0.0001 54.29 0.0001 ) constant tbf-gs3 #( 0.99 0.0880 1.99 0.1784 2.99 0.0966 3.99 0.0789 4.99 0.0440 5.99 0.0574 6.99 0.0067 7.99 0.0384 8.98 0.0270 9.98 0.0089 10.97 0.0152 11.97 0.0039 12.97 0.0092 13.97 0.0081 14.97 0.0020 15.97 0.0030 16.96 0.0051 17.96 0.0014 18.96 0.0031 19.96 0.0026 20.95 0.0004 21.95 0.0028 22.95 0.0006 23.94 0.0012 24.94 0.0021 25.94 0.0009 26.94 0.0010 27.94 0.0010 28.94 0.0006 29.94 0.0008 30.93 0.0009 31.93 0.0001 32.92 0.0007 33.92 0.0005 34.91 0.0002 35.92 0.0005 36.91 0.0003 37.92 0.0002 38.92 0.0004 40.91 0.0002 41.90 0.0002 43.89 0.0002 44.89 0.0002 46.89 0.0001 49.89 0.0001 52.88 0.0001 ) constant tbf-a3 #( 1.00 0.0084 2.02 0.2204 3.02 0.1914 4.03 0.0999 5.03 0.0302 6.04 0.0574 7.04 0.0432 8.05 0.0168 9.05 0.0414 10.06 0.0213 11.06 0.0024 12.07 0.0063 13.08 0.0058 14.08 0.0014 15.09 0.0031 16.09 0.0067 17.10 0.0026 18.10 0.0026 19.11 0.0039 20.11 0.0016 21.12 0.0015 22.12 0.0032 23.13 0.0017 24.13 0.0010 25.14 0.0020 26.14 0.0016 27.15 0.0002 28.16 0.0013 29.16 0.0009 31.17 0.0009 32.18 0.0008 33.18 0.0004 34.19 0.0005 35.19 0.0008 36.20 0.0002 37.20 0.0004 38.21 0.0005 39.21 0.0002 40.22 0.0002 41.22 0.0003 42.23 0.0002 43.23 0.0001 44.24 0.0002 45.25 0.0001 47.26 0.0002 48.26 0.0001 50.28 0.0001 51.28 0.0001 ) constant tbf-as3 #( 1.00 0.0475 2.00 0.1146 3.01 0.1513 4.01 0.0759 5.00 0.0441 6.01 0.0348 7.01 0.0462 8.01 0.0291 9.02 0.0056 10.02 0.0281 11.01 0.0178 12.02 0.0016 13.02 0.0054 14.02 0.0082 15.03 0.0051 16.02 0.0014 17.02 0.0053 18.03 0.0050 19.03 0.0017 20.03 0.0024 21.04 0.0037 22.03 0.0025 23.03 0.0008 24.04 0.0028 25.04 0.0023 26.04 0.0007 27.04 0.0007 28.04 0.0018 29.04 0.0017 30.05 0.0003 31.04 0.0011 32.04 0.0013 33.05 0.0004 34.05 0.0005 35.05 0.0009 36.06 0.0007 37.05 0.0002 38.06 0.0004 39.06 0.0006 40.06 0.0004 41.07 0.0003 42.06 0.0005 43.06 0.0004 44.07 0.0001 45.07 0.0003 46.07 0.0003 47.08 0.0001 48.07 0.0001 49.07 0.0003 50.08 0.0002 52.08 0.0001 53.08 0.0001 ) constant tbf-b3 #( 1.01 0.0092 2.01 0.0918 3.01 0.1218 4.03 0.1524 5.03 0.0561 6.03 0.0196 7.05 0.0312 8.05 0.0481 9.05 0.0292 10.07 0.0048 11.07 0.0035 12.07 0.0096 13.08 0.0079 14.09 0.0040 15.09 0.0017 16.09 0.0054 17.11 0.0080 18.11 0.0039 19.11 0.0010 20.13 0.0034 21.13 0.0028 22.13 0.0027 23.14 0.0004 24.15 0.0015 25.15 0.0024 26.16 0.0021 27.17 0.0006 28.17 0.0008 29.17 0.0013 30.19 0.0015 31.19 0.0005 32.19 0.0002 33.21 0.0009 34.21 0.0010 35.21 0.0006 36.23 0.0003 37.23 0.0005 38.23 0.0009 39.24 0.0007 40.25 0.0002 41.25 0.0004 42.26 0.0006 43.27 0.0004 44.27 0.0002 45.27 0.0003 46.29 0.0004 47.29 0.0003 48.29 0.0001 ) constant tbf-c4 #( 1.00 0.0881 2.00 0.1170 3.00 0.0852 4.00 0.0643 5.00 0.0778 6.00 0.0489 6.99 0.0269 8.00 0.0107 8.99 0.0292 10.00 0.0159 10.99 0.0082 12.00 0.0066 12.99 0.0009 14.00 0.0050 14.99 0.0064 15.99 0.0059 17.00 0.0044 17.99 0.0024 19.00 0.0042 19.99 0.0040 21.00 0.0027 21.99 0.0023 22.99 0.0018 23.99 0.0024 24.99 0.0025 25.99 0.0019 26.99 0.0007 27.99 0.0004 28.99 0.0012 29.99 0.0014 30.99 0.0012 31.99 0.0004 32.99 0.0002 33.99 0.0007 34.98 0.0009 35.99 0.0008 36.98 0.0005 37.99 0.0002 38.98 0.0005 39.99 0.0007 40.98 0.0007 41.98 0.0004 42.98 0.0001 43.98 0.0003 44.99 0.0004 45.98 0.0003 ) constant tbf-cs4 #( 1.01 0.1228 2.02 0.1247 3.02 0.1142 4.03 0.0474 5.04 0.0335 6.04 0.0332 7.05 0.0302 8.06 0.0222 9.07 0.0090 10.08 0.0030 11.09 0.0027 12.09 0.0054 13.10 0.0059 14.10 0.0040 15.11 0.0038 16.12 0.0029 17.13 0.0011 18.14 0.0020 19.15 0.0021 20.15 0.0023 21.16 0.0016 22.17 0.0012 23.17 0.0008 24.18 0.0003 25.19 0.0006 26.20 0.0008 27.21 0.0008 28.22 0.0008 29.22 0.0004 30.23 0.0002 31.23 0.0002 32.24 0.0003 33.26 0.0004 34.26 0.0004 35.27 0.0004 36.28 0.0002 39.29 0.0002 40.30 0.0002 41.32 0.0001 ) constant tbf-d4 #( 1.01 0.1133 2.01 0.1562 3.02 0.1429 4.02 0.0366 5.02 0.0219 6.03 0.0212 7.03 0.0142 8.04 0.0216 9.04 0.0101 10.04 0.0063 11.05 0.0076 12.05 0.0081 13.06 0.0050 14.06 0.0030 15.07 0.0010 16.07 0.0011 17.07 0.0019 18.08 0.0022 19.08 0.0029 20.09 0.0028 21.09 0.0021 22.09 0.0016 23.10 0.0016 24.10 0.0010 25.11 0.0005 26.11 0.0003 27.11 0.0002 28.12 0.0006 29.12 0.0004 30.13 0.0005 31.13 0.0004 32.13 0.0006 33.14 0.0003 34.14 0.0003 35.15 0.0002 37.15 0.0002 38.15 0.0001 39.16 0.0002 40.16 0.0002 41.17 0.0002 ) constant tbf-ds4 #( 0.99 0.0906 1.99 0.1338 2.99 0.1235 3.98 0.0833 4.98 0.0601 5.98 0.0264 6.98 0.0126 7.97 0.0051 8.97 0.0026 9.97 0.0014 10.96 0.0018 11.96 0.0025 12.96 0.0031 13.96 0.0021 14.95 0.0034 15.95 0.0035 16.95 0.0037 17.94 0.0031 18.94 0.0021 19.93 0.0021 20.93 0.0016 21.92 0.0010 22.92 0.0012 23.92 0.0011 24.91 0.0007 25.91 0.0004 26.91 0.0002 28.91 0.0001 30.89 0.0001 31.90 0.0002 32.90 0.0002 33.89 0.0002 34.89 0.0002 35.88 0.0002 36.88 0.0002 37.88 0.0002 38.87 0.0001 ) constant tbf-e4 #( 1.01 0.1228 2.01 0.3008 3.01 0.1922 4.01 0.0927 5.01 0.0581 6.02 0.0447 7.02 0.0207 8.03 0.0106 9.02 0.0057 10.02 0.0018 11.03 0.0040 12.03 0.0041 13.04 0.0040 14.04 0.0039 15.04 0.0042 16.04 0.0034 17.05 0.0035 18.05 0.0038 19.06 0.0033 20.06 0.0029 21.06 0.0024 22.06 0.0020 23.07 0.0018 24.07 0.0015 25.07 0.0012 26.07 0.0009 27.07 0.0006 28.08 0.0005 29.08 0.0003 30.09 0.0003 31.10 0.0003 32.10 0.0004 33.11 0.0004 34.11 0.0004 35.10 0.0004 36.10 0.0004 37.11 0.0003 38.11 0.0002 ) constant tbf-f4 #( 1.01 0.0765 2.01 0.2561 3.02 0.0803 4.03 0.0653 5.03 0.0230 6.04 0.0093 7.05 0.0035 8.05 0.0042 9.06 0.0040 10.07 0.0052 11.07 0.0056 12.08 0.0049 13.09 0.0039 14.09 0.0035 15.10 0.0031 16.10 0.0021 17.11 0.0012 18.12 0.0010 19.12 0.0005 20.13 0.0003 21.14 0.0001 22.14 0.0001 23.15 0.0003 24.16 0.0002 25.16 0.0003 26.17 0.0003 27.18 0.0003 28.18 0.0003 29.19 0.0003 30.20 0.0002 31.20 0.0001 ) constant tbf-fs4 #( 1.01 0.0092 2.02 0.2167 3.02 0.0668 4.02 0.0254 5.03 0.0210 6.04 0.0282 7.04 0.0151 8.05 0.0130 9.05 0.0054 10.06 0.0031 11.07 0.0014 12.08 0.0020 13.08 0.0020 14.09 0.0020 15.09 0.0021 16.10 0.0015 17.10 0.0007 18.11 0.0003 19.13 0.0002 20.13 0.0004 21.13 0.0005 22.14 0.0004 23.14 0.0003 24.15 0.0003 25.15 0.0001 29.18 0.0001 30.19 0.0001 ) constant tbf-g4 #( 1.00 0.1758 2.01 0.1249 3.01 0.0253 4.02 0.0471 5.02 0.0478 6.03 0.0217 7.03 0.0025 8.04 0.0044 9.05 0.0066 10.05 0.0060 11.05 0.0030 12.06 0.0021 13.09 0.0005 14.07 0.0008 15.07 0.0014 16.08 0.0010 17.08 0.0005 18.10 0.0002 19.09 0.0003 20.10 0.0003 21.10 0.0003 22.10 0.0001 24.13 0.0001 25.13 0.0001 26.13 0.0001 ) constant tbf-gs4 #( 1.00 0.3944 2.01 0.1441 3.00 0.0979 4.01 0.0595 5.01 0.0218 6.01 0.0057 7.01 0.0131 8.01 0.0053 9.01 0.0018 10.02 0.0029 11.01 0.0042 12.02 0.0032 13.01 0.0001 14.02 0.0014 15.02 0.0017 16.02 0.0006 17.03 0.0003 18.02 0.0006 19.03 0.0009 20.03 0.0003 21.04 0.0002 22.03 0.0004 23.03 0.0004 25.04 0.0002 26.04 0.0003 27.04 0.0001 ) constant tbf-a4 #( 1.01 0.3895 2.03 0.1550 3.03 0.0985 4.05 0.0153 5.06 0.0280 6.07 0.0103 7.08 0.0028 8.10 0.0069 9.10 0.0023 10.12 0.0025 11.13 0.0029 12.14 0.0011 13.15 0.0011 14.16 0.0009 15.17 0.0002 16.19 0.0007 17.20 0.0004 18.22 0.0002 19.22 0.0003 20.23 0.0001 22.26 0.0001 ) constant tbf-as4 #( 1.00 0.2165 2.01 0.1597 3.00 0.0717 4.01 0.0353 5.01 0.0332 6.01 0.0024 7.01 0.0088 8.02 0.0009 9.02 0.0039 10.02 0.0016 11.02 0.0015 12.02 0.0014 13.03 0.0003 14.03 0.0007 16.03 0.0004 17.04 0.0002 18.03 0.0002 19.04 0.0001 ) constant tbf-b4 #( 1.01 0.1699 2.01 0.2670 3.03 0.0349 4.03 0.0454 5.05 0.0024 6.05 0.0069 7.06 0.0021 8.07 0.0015 9.08 0.0011 10.09 0.0007 11.09 0.0007 12.10 0.0001 13.11 0.0004 15.13 0.0002 ) constant tbf-c5 #( 1.00 0.2017 2.00 0.0920 3.00 0.0598 3.99 0.0086 4.99 0.0120 5.99 0.0063 6.99 0.0034 7.99 0.0029 8.99 0.0008 9.99 0.0014 10.98 0.0008 11.97 0.0007 12.98 0.0006 13.96 0.0001 14.97 0.0003 15.97 0.0001 ) constant tbf-cs5 \ ********************************************************** \ \ ********************************************************** #( 1.00 0.0179 2.00 0.0770 2.99 0.0532 3.99 0.0183 4.97 0.0494 5.98 0.0137 6.95 0.0121 7.97 0.0153 8.94 0.0012 9.96 0.0040 10.97 0.0030 11.93 0.0021 12.93 0.0034 13.94 0.0007 14.91 0.0004 16.01 0.0002 16.93 0.0003 17.92 0.0008 18.94 0.0004 19.96 0.0002 21.00 0.0001 22.95 0.0001 25.89 0.0001 ) constant tbp-e2 #( 0.99 0.0137 2.01 0.0473 3.03 0.0362 4.01 0.0117 5.02 0.0565 6.04 0.0247 7.06 0.0348 8.04 0.0251 9.05 0.0143 10.07 0.0146 11.09 0.0020 12.07 0.0048 13.09 0.0013 14.12 0.0012 15.12 0.0009 16.12 0.0004 17.10 0.0010 18.11 0.0003 19.13 0.0004 20.13 0.0001 22.14 0.0001 24.17 0.0001 ) constant tbp-f2 #( 1.02 0.0110 2.02 0.0470 3.02 0.0038 4.02 0.0343 5.01 0.0442 6.02 0.0198 7.01 0.0600 8.02 0.0144 9.05 0.0468 10.05 0.0112 11.05 0.0137 12.05 0.0078 13.05 0.0041 14.05 0.0040 15.05 0.0012 16.05 0.0018 17.05 0.0007 18.08 0.0011 19.08 0.0003 20.09 0.0005 21.08 0.0004 22.08 0.0002 23.07 0.0003 25.07 0.0001 ) constant tbp-fs2 #( 1.01 0.0148 2.00 0.0544 3.02 0.0144 4.01 0.0848 5.03 0.0334 6.02 0.0703 7.01 0.0546 8.03 0.0242 9.02 0.0235 10.04 0.0054 11.02 0.0079 12.04 0.0009 13.03 0.0032 14.02 0.0011 15.04 0.0013 16.02 0.0005 17.06 0.0005 18.01 0.0001 19.01 0.0002 20.07 0.0002 21.08 0.0001 ) constant tbp-g2 #( 0.99 0.0357 2.00 0.0505 3.00 0.0158 3.99 0.0999 4.99 0.0473 6.00 0.0633 7.00 0.0187 7.98 0.0536 8.99 0.0153 9.99 0.0238 10.98 0.0049 11.98 0.0045 12.99 0.0018 13.98 0.0031 14.97 0.0011 15.97 0.0009 16.98 0.0005 17.97 0.0007 18.97 0.0006 19.95 0.0003 20.96 0.0001 ) constant tbp-gs2 #( 1.00 0.0295 1.99 0.1044 2.98 0.0380 3.96 0.1223 4.95 0.0652 5.93 0.0906 6.93 0.0212 7.91 0.0492 8.91 0.0034 9.88 0.0180 10.87 0.0036 11.86 0.0050 12.85 0.0005 13.85 0.0016 14.84 0.0009 15.81 0.0014 16.80 0.0002 17.77 0.0003 20.73 0.0001 21.73 0.0002 22.73 0.0002 24.70 0.0001 ) constant tbp-a2 #( 1.00 0.0228 2.01 0.0987 3.02 0.0160 4.03 0.0517 5.03 0.0818 6.04 0.0522 7.06 0.0447 8.06 0.0171 9.07 0.0228 10.06 0.0032 11.08 0.0065 12.06 0.0008 13.09 0.0023 14.11 0.0008 15.09 0.0004 16.11 0.0004 17.10 0.0003 18.13 0.0002 20.07 0.0001 ) constant tbp-as2 #( 1.01 0.0076 1.99 0.0810 2.98 0.0345 3.98 0.0341 4.99 0.0653 5.99 0.0085 6.96 0.0538 7.97 0.0030 8.97 0.0204 9.96 0.0059 10.95 0.0026 11.96 0.0028 12.96 0.0006 13.94 0.0014 14.92 0.0002 15.94 0.0007 16.95 0.0002 ) constant tbp-b2 #( 1.02 0.0300 2.02 0.0703 3.03 0.1222 4.04 0.0495 5.04 0.0810 6.04 0.0372 7.05 0.0371 8.06 0.0353 9.08 0.0026 10.09 0.0078 11.10 0.0065 12.11 0.0027 13.11 0.0030 14.12 0.0006 15.12 0.0013 16.13 0.0006 17.14 0.0002 18.16 0.0002 19.18 0.0001 20.19 0.0001 21.19 0.0001 ) constant tbp-c3 #( 0.99 0.0466 1.97 0.0094 2.97 0.0953 3.95 0.0427 4.96 0.0520 5.94 0.0187 6.94 0.0127 7.92 0.0075 8.90 0.0015 9.90 0.0017 10.88 0.0009 11.89 0.0002 12.85 0.0002 ) constant tbp-cs3 #( 1.01 0.0634 2.02 0.0187 3.02 0.0987 4.02 0.0742 5.02 0.0182 6.03 0.0331 7.03 0.0132 8.03 0.0025 9.04 0.0026 10.06 0.0016 11.07 0.0002 12.08 0.0001 ) constant tbp-d3 #( 1.01 0.1106 2.01 0.0100 3.00 0.0866 4.00 0.0859 5.00 0.0217 6.00 0.0251 6.99 0.0134 7.99 0.0022 8.99 0.0026 9.99 0.0021 11.00 0.0005 14.99 0.0001 16.99 0.0001 ) constant tbp-ds3 #( 1.00 0.1452 1.99 0.0464 2.98 0.0553 3.97 0.1114 4.96 0.0181 5.95 0.0077 6.94 0.0033 7.93 0.0043 8.92 0.0023 9.92 0.0003 10.90 0.0006 11.89 0.0003 14.88 0.0001 15.87 0.0002 19.83 0.0001 ) constant tbp-e3 #( 0.99 0.0923 2.00 0.0191 3.00 0.0745 3.99 0.1014 5.00 0.0547 6.00 0.0129 6.99 0.0032 8.00 0.0023 9.00 0.0018 9.98 0.0007 10.38 0.0001 12.98 0.0001 ) constant tbp-f3 #( 1.01 0.0781 2.00 0.0346 2.99 0.0441 4.01 0.0196 5.00 0.0310 5.99 0.0213 7.00 0.0062 7.99 0.0021 9.00 0.0003 9.99 0.0002 ) constant tbp-fs3 #( 1.01 0.0733 2.03 0.0883 3.03 0.0772 4.05 0.0148 5.06 0.0055 6.06 0.0033 7.09 0.0026 8.09 0.0015 9.11 0.0003 10.12 0.0002 ) constant tbp-g3 #( 1.02 0.0885 2.03 0.1115 3.05 0.0480 4.06 0.0466 5.07 0.0106 6.09 0.0018 7.10 0.0009 ) constant tbp-gs3 #( 1.01 0.1416 2.02 0.1418 3.02 0.0683 4.03 0.0464 5.04 0.0178 6.04 0.0037 7.06 0.0018 8.07 0.0006 9.05 0.0004 ) constant tbp-a3 #( 1.01 0.1361 2.01 0.0839 3.00 0.0761 4.00 0.0211 5.00 0.0045 6.00 0.0018 7.00 0.0004 ) constant tbp-as3 #( 1.01 0.0960 2.01 0.0594 3.01 0.0315 4.01 0.0078 5.01 0.0021 6.01 0.0009 7.02 0.0005 8.03 0.0003 ) constant tbp-b3 #( 1.00 0.0855 2.00 0.1172 3.00 0.0276 4.00 0.0135 5.00 0.0053 6.00 0.0021 6.99 0.0003 ) constant tbp-c4 #( 1.01 0.0033 2.00 0.0982 2.99 0.0491 3.99 0.0185 4.99 0.0043 5.98 0.0004 6.99 0.0001 ) constant tbp-cs4 #( 1.01 0.0485 2.01 0.1552 3.01 0.0547 4.01 0.0136 5.03 0.0026 6.04 0.0010 7.05 0.0001 ) constant tbp-d4 #( 1.01 0.0030 2.01 0.1892 3.01 0.0563 4.01 0.0025 5.02 0.0034 5.97 0.0001 7.03 0.0003 ) constant tbp-ds4 #( 1.01 0.0508 2.02 0.0934 3.02 0.0147 4.03 0.0111 5.05 0.0014 6.06 0.0014 8.08 0.0001 ) constant tbp-e4 #( 1.00 0.0260 2.02 0.2047 3.02 0.0550 4.03 0.0165 5.04 0.0051 6.04 0.0005 7.05 0.0002 ) constant tbp-f4 #( 1.02 0.0971 2.03 0.0635 3.04 0.0254 4.05 0.0023 5.07 0.0002 6.08 0.0003 7.09 0.0001 ) constant tbp-fs4 #( 1.02 0.3176 2.03 0.0734 3.04 0.0332 4.05 0.0152 5.06 0.0048 6.08 0.0007 ) constant tbp-g4 #( 1.01 0.3321 2.01 0.1320 3.01 0.0072 4.02 0.0028 5.03 0.0009 6.04 0.0002 7.04 0.0002 ) constant tbp-gs4 #( 1.00 0.5149 2.00 0.2025 3.00 0.0392 3.99 0.0117 4.99 0.0035 5.99 0.0008 6.99 0.0002 7.98 0.0001 ) constant tbp-a4 #( 1.01 0.3188 2.01 0.2130 3.02 0.0427 4.03 0.0024 5.05 0.0004 6.05 0.0007 7.06 0.0002 8.06 0.0002 ) constant tbp-as4 #( 1.00 0.1685 1.99 0.0732 2.99 0.0056 3.99 0.0042 4.99 0.0009 5.99 0.0005 ) constant tbp-b4 #( 1.01 0.3386 2.02 0.0634 3.02 0.0212 4.03 0.0019 5.04 0.0004 ) constant tbp-c5 #( 1.00 0.2958 2.00 0.0843 3.01 0.0058 4.01 0.0027 5.01 0.0003 ) constant tbp-cs5 #( 1.00 0.4237 2.01 0.0453 3.01 0.0045 4.02 0.0007 5.02 0.0004 ) constant tbp-d5 \ ********************************************************** \ trumpet \ ********************************************************** #( 1.01 0.0533 2.03 0.0559 3.05 0.0505 4.06 0.0542 5.08 0.0382 6.10 0.0570 7.12 0.0321 8.14 0.0393 9.15 0.0277 10.17 0.0157 11.19 0.0165 12.20 0.0152 13.22 0.0081 14.23 0.0089 15.24 0.0035 16.26 0.0045 17.28 0.0052 18.29 0.0020 19.31 0.0021 20.33 0.0017 21.35 0.0014 22.37 0.0010 23.38 0.0009 24.40 0.0004 25.42 0.0005 26.44 0.0004 27.45 0.0004 28.46 0.0004 29.48 0.0002 30.49 0.0002 31.51 0.0002 32.53 0.0001 33.55 0.0001 ) constant trp-fs3 #( 0.99 0.0459 1.99 0.0931 3.00 0.0517 4.00 0.0496 5.00 0.0576 6.00 0.0452 7.00 0.0263 8.00 0.0125 9.01 0.0131 10.01 0.0136 11.00 0.0066 12.00 0.0081 13.00 0.0032 14.00 0.0039 14.99 0.0026 16.00 0.0017 16.99 0.0017 17.99 0.0009 19.01 0.0013 20.01 0.0008 21.01 0.0006 22.00 0.0006 23.00 0.0003 24.01 0.0004 25.01 0.0003 26.01 0.0002 27.02 0.0002 28.02 0.0001 29.02 0.0001 31.04 0.0001 ) constant trp-g3 #( 0.99 0.0455 1.99 0.0969 2.97 0.0487 3.97 0.0296 4.97 0.0186 5.95 0.0219 6.95 0.0075 7.94 0.0176 8.93 0.0202 9.93 0.0175 10.91 0.0156 11.91 0.0097 12.91 0.0066 13.89 0.0065 14.89 0.0051 15.88 0.0037 16.86 0.0015 17.87 0.0016 18.85 0.0010 19.85 0.0006 20.84 0.0006 21.84 0.0006 22.84 0.0005 23.82 0.0003 24.82 0.0003 25.80 0.0002 26.79 0.0002 27.79 0.0001 28.79 0.0001 ) constant trp-gs3 #( 0.99 0.0420 1.99 0.0954 2.99 0.0579 3.99 0.0722 4.98 0.0813 5.98 0.0399 6.98 0.0379 7.98 0.0181 8.98 0.0188 9.98 0.0147 10.97 0.0100 11.97 0.0091 12.96 0.0048 13.96 0.0091 14.96 0.0048 15.96 0.0016 16.96 0.0027 17.97 0.0020 18.96 0.0014 19.96 0.0007 20.95 0.0007 21.95 0.0006 22.94 0.0003 23.95 0.0005 24.95 0.0002 25.95 0.0002 26.95 0.0002 27.96 0.0002 28.95 0.0002 29.94 0.0001 ) constant trp-a3 #( 1.01 0.0487 2.01 0.0236 3.01 0.0599 4.01 0.0397 5.01 0.0525 6.01 0.0426 7.00 0.0144 8.01 0.0134 9.01 0.0274 10.01 0.0087 11.01 0.0041 12.00 0.0052 13.01 0.0080 14.01 0.0028 15.02 0.0022 16.01 0.0014 17.04 0.0005 18.04 0.0003 19.03 0.0005 20.02 0.0003 21.02 0.0003 22.02 0.0003 23.03 0.0002 24.03 0.0002 25.02 0.0001 ) constant trp-as3 #( 1.00 0.0534 2.00 0.0362 3.00 0.0698 4.00 0.0793 4.99 0.0301 6.00 0.0216 7.00 0.0130 8.00 0.0151 9.00 0.0172 10.00 0.0062 11.00 0.0041 11.99 0.0022 13.00 0.0017 14.00 0.0012 14.99 0.0013 15.95 0.0002 16.99 0.0001 18.00 0.0003 19.00 0.0003 20.00 0.0003 21.01 0.0001 ) constant trp-b3 #( 1.01 0.0410 2.03 0.0543 3.03 0.0487 4.04 0.0354 5.05 0.0408 6.06 0.0221 7.08 0.0099 8.09 0.0248 9.09 0.0107 10.11 0.0037 11.11 0.0087 12.13 0.0035 13.14 0.0012 14.16 0.0013 15.17 0.0002 16.18 0.0002 17.19 0.0003 18.20 0.0002 19.21 0.0002 20.22 0.0002 21.23 0.0001 22.24 0.0001 ) constant trp-c4 #( 1.01 0.0199 2.03 0.0437 3.03 0.0142 4.04 0.0534 5.04 0.0310 6.06 0.0194 7.06 0.0124 8.06 0.0071 9.07 0.0061 10.06 0.0037 11.09 0.0022 12.12 0.0007 13.11 0.0005 14.12 0.0003 15.10 0.0002 16.12 0.0002 17.13 0.0001 18.13 0.0001 ) constant trp-cs4 #( 1.01 0.0320 2.02 0.0510 3.04 0.0747 4.05 0.0619 5.06 0.0404 6.07 0.0195 7.08 0.0221 8.09 0.0112 9.11 0.0073 10.13 0.0031 11.13 0.0026 12.15 0.0017 13.16 0.0013 14.17 0.0009 15.18 0.0007 16.18 0.0004 17.19 0.0003 18.22 0.0002 19.23 0.0002 20.23 0.0002 21.25 0.0001 ) constant trp-d4 #( 1.00 0.0471 2.01 0.0466 3.02 0.0304 4.02 0.0166 5.02 0.0187 6.02 0.0086 7.03 0.0064 8.03 0.0067 9.03 0.0033 10.02 0.0016 11.05 0.0013 12.06 0.0008 13.06 0.0005 14.05 0.0002 15.04 0.0002 16.05 0.0002 17.05 0.0001 ) constant trp-ds4 #( 1.01 0.0365 2.01 0.0352 3.02 0.0462 4.02 0.0230 5.02 0.0092 6.02 0.0078 7.02 0.0059 8.04 0.0034 9.04 0.0011 10.05 0.0010 11.07 0.0003 12.07 0.0003 13.06 0.0002 14.06 0.0001 15.07 0.0001 ) constant trp-e4 #( 1.00 0.0412 2.00 0.0621 3.00 0.0180 3.99 0.0631 4.99 0.0245 5.99 0.0369 6.99 0.0093 7.99 0.0126 8.99 0.0027 9.99 0.0035 10.99 0.0021 11.99 0.0016 12.99 0.0010 13.98 0.0009 14.98 0.0006 15.98 0.0004 16.98 0.0002 ) constant trp-f4 #( 0.99 0.0581 1.98 0.0494 2.98 0.0614 3.97 0.0316 4.96 0.0151 5.96 0.0095 6.95 0.0022 7.93 0.0022 8.93 0.0013 9.94 0.0008 10.93 0.0003 11.92 0.0002 12.92 0.0001 13.93 0.0001 ) constant trp-fs4 #( 1.00 0.0979 1.99 0.0344 2.99 0.0374 3.99 0.0179 4.98 0.0148 5.98 0.0059 6.98 0.0029 7.95 0.0005 8.97 0.0004 9.97 0.0002 10.96 0.0002 ) constant trp-g4 #( 1.00 0.0670 2.00 0.0138 3.00 0.0100 4.01 0.0076 4.99 0.0070 5.99 0.0037 6.97 0.0023 7.97 0.0007 8.97 0.0002 9.98 0.0001 10.97 0.0002 ) constant trp-gs4 #( 1.00 0.0403 2.01 0.0211 3.00 0.0107 4.00 0.0052 4.99 0.0022 6.00 0.0013 7.00 0.0006 8.01 0.0002 9.02 0.0001 10.03 0.0001 ) constant trp-a4 #( 1.00 0.0128 2.01 0.0154 3.00 0.0269 3.99 0.0098 4.99 0.0021 5.98 0.0016 6.99 0.0004 8.00 0.0003 9.02 0.0002 ) constant trp-as4 #( 1.01 0.0287 2.01 0.0583 3.01 0.0386 4.00 0.0098 5.01 0.0068 6.02 0.0012 7.02 0.0012 8.03 0.0003 9.02 0.0003 10.01 0.0001 ) constant trp-b4 #( 1.01 0.0190 2.01 0.0057 3.01 0.0039 4.01 0.0051 5.03 0.0005 6.02 0.0002 7.03 0.0001 ) constant trp-c5 #( 1.01 0.0087 2.01 0.0050 3.01 0.0011 4.01 0.0002 ) constant trp-cs5 #( 1.01 0.0145 2.01 0.0098 3.01 0.0013 4.01 0.0003 ) constant trp-d5 #( 1.00 0.0231 2.00 0.0053 2.98 0.0077 3.97 0.0021 4.96 0.0003 6.98 0.0001 ) constant trp-ds5 #( 1.01 0.0520 2.02 0.0187 3.00 0.0009 4.04 0.0011 5.02 0.0001 ) constant trp-e5 #( 1.02 0.0332 2.02 0.0074 3.03 0.0031 ) constant trp-f5 #( 1.01 0.1718 2.02 0.1098 3.02 0.0288 4.02 0.0047 5.04 0.0026 6.04 0.0008 7.06 0.0004 8.06 0.0002 ) constant trp-fs5 #( 1.02 0.0825 2.03 0.0364 3.04 0.0160 4.06 0.0045 5.07 0.0011 6.09 0.0005 7.10 0.0002 ) constant trp-g5 #( 1.02 0.0114 2.02 0.0346 3.02 0.0045 4.04 0.0013 5.06 0.0002 ) constant trp-gs5 #( 1.02 0.0821 2.03 0.0089 3.04 0.0023 4.06 0.0003 5.05 0.0001 ) constant trp-a5 #( 1.01 0.1554 2.01 0.0287 3.02 0.0084 4.02 0.0035 5.03 0.0007 6.04 0.0002 7.04 0.0001 ) constant trp-as5 #( 1.01 0.0559 2.01 0.0017 3.01 0.0013 4.02 0.0001 ) constant trp-b5 #( 1.01 0.0291 2.00 0.0150 3.01 0.0032 4.02 0.0004 5.02 0.0002 ) constant trp-c6 \ ********************************************************** \ \ ********************************************************** #( 1.00 0.0292 1.99 0.0424 3.00 0.0242 4.00 0.0413 4.99 0.0315 6.00 0.0454 7.00 0.0143 7.98 0.0108 8.99 0.0077 9.99 0.0084 10.99 0.0071 11.98 0.0078 12.97 0.0085 13.98 0.0032 14.97 0.0035 15.97 0.0052 16.96 0.0021 17.96 0.0033 18.96 0.0024 19.97 0.0016 20.95 0.0015 21.95 0.0011 22.95 0.0006 23.95 0.0007 24.94 0.0006 25.94 0.0004 26.94 0.0003 27.93 0.0004 28.93 0.0003 29.93 0.0002 30.92 0.0003 31.92 0.0001 32.93 0.0001 33.91 0.0002 ) constant trpf-fs3 #( 0.99 0.0286 1.97 0.0669 2.95 0.0456 3.95 0.0345 4.94 0.0617 5.91 0.0341 6.90 0.0225 7.89 0.0264 8.88 0.0155 9.86 0.0160 10.84 0.0150 11.83 0.0085 12.82 0.0112 13.80 0.0054 14.78 0.0042 15.77 0.0056 16.76 0.0023 17.73 0.0027 18.71 0.0010 19.73 0.0014 20.69 0.0014 21.68 0.0007 22.67 0.0007 23.64 0.0007 24.63 0.0004 25.62 0.0005 26.59 0.0003 27.62 0.0002 28.56 0.0003 29.55 0.0001 30.53 0.0002 31.51 0.0002 32.50 0.0001 33.48 0.0002 35.47 0.0001 ) constant trpf-g3 #( 0.99 0.0306 1.99 0.0608 2.97 0.0495 3.97 0.0557 4.97 0.0228 5.95 0.0337 6.95 0.0177 7.94 0.0112 8.92 0.0146 9.93 0.0022 10.91 0.0069 11.89 0.0053 12.89 0.0047 13.88 0.0031 14.87 0.0063 15.87 0.0042 16.86 0.0033 17.84 0.0031 18.84 0.0028 19.83 0.0018 20.83 0.0015 21.82 0.0010 22.80 0.0010 23.80 0.0005 24.79 0.0007 25.77 0.0004 26.77 0.0005 27.76 0.0003 28.75 0.0003 29.74 0.0002 30.74 0.0002 32.73 0.0001 ) constant trpf-gs3 #( 0.99 0.0331 2.00 0.0607 3.00 0.0463 4.00 0.0350 5.00 0.0480 6.00 0.0294 7.00 0.0318 7.99 0.0150 8.98 0.0166 9.98 0.0148 10.98 0.0109 11.99 0.0052 13.02 0.0012 13.99 0.0070 14.98 0.0054 15.98 0.0035 16.97 0.0035 17.96 0.0021 18.96 0.0019 19.96 0.0008 20.96 0.0010 21.97 0.0006 22.96 0.0005 23.96 0.0007 24.96 0.0004 25.95 0.0006 26.95 0.0004 27.94 0.0003 28.94 0.0002 29.94 0.0001 30.94 0.0002 31.93 0.0002 32.93 0.0001 ) constant trpf-a3 #( 1.00 0.0250 2.00 0.0182 2.99 0.0170 3.97 0.0199 4.97 0.0223 5.97 0.0224 6.95 0.0094 7.95 0.0070 8.94 0.0069 9.92 0.0064 10.91 0.0030 11.92 0.0028 12.90 0.0024 13.01 0.0007 14.00 0.0003 14.89 0.0008 15.89 0.0007 16.91 0.0002 17.88 0.0002 18.86 0.0001 20.83 0.0001 ) constant trpf-as3 #( 1.00 0.0379 1.99 0.0221 2.99 0.0480 3.99 0.0721 4.97 0.0322 5.98 0.0203 6.97 0.0220 7.97 0.0170 8.96 0.0150 9.96 0.0042 10.95 0.0040 11.93 0.0049 12.94 0.0038 14.00 0.0011 14.95 0.0021 15.95 0.0008 16.93 0.0004 16.98 0.0004 17.90 0.0004 18.00 0.0003 18.99 0.0003 19.89 0.0003 20.88 0.0003 21.89 0.0002 22.97 0.0002 23.97 0.0002 ) constant trpf-b3 #( 1.01 0.0330 2.02 0.0365 3.02 0.0430 4.03 0.0164 5.05 0.0234 6.04 0.0138 7.05 0.0110 8.06 0.0202 9.07 0.0098 10.08 0.0030 11.09 0.0065 12.11 0.0027 13.11 0.0009 14.13 0.0014 15.15 0.0003 16.12 0.0002 17.13 0.0002 18.12 0.0002 19.14 0.0002 20.13 0.0002 21.14 0.0001 ) constant trpf-c4 #( 1.01 0.0082 2.02 0.0191 3.02 0.0152 4.01 0.0324 5.02 0.0129 6.03 0.0050 7.01 0.0093 8.01 0.0031 9.01 0.0036 10.00 0.0017 11.01 0.0010 12.00 0.0004 13.02 0.0004 14.03 0.0003 15.02 0.0002 16.03 0.0001 ) constant trpf-cs4 #( 1.01 0.0190 2.03 0.0431 3.04 0.0481 4.05 0.0399 5.07 0.0179 6.08 0.0198 7.09 0.0136 8.10 0.0081 9.12 0.0041 10.10 0.0011 11.15 0.0016 12.16 0.0014 13.17 0.0007 14.18 0.0005 15.20 0.0003 16.20 0.0002 17.22 0.0002 19.24 0.0001 ) constant trpf-d4 #( 1.00 0.0239 2.01 0.0207 3.02 0.0113 4.00 0.0083 5.00 0.0145 5.97 0.0054 6.99 0.0031 7.98 0.0026 8.97 0.0027 9.98 0.0010 11.01 0.0004 11.99 0.0004 13.00 0.0003 13.97 0.0002 14.98 0.0002 15.97 0.0002 ) constant trpf-ds4 #( 1.02 0.0134 2.03 0.0124 3.04 0.0117 4.05 0.0041 5.08 0.0007 6.06 0.0009 7.08 0.0006 8.06 0.0002 9.11 0.0002 ) constant trpf-e4 #( 1.03 0.0045 2.03 0.0019 3.03 0.0006 4.04 0.0012 5.02 0.0004 6.08 0.0001 ) constant trpf-f4 #( 1.00 0.0501 2.00 0.0385 3.00 0.0509 3.99 0.0156 4.98 0.0099 5.98 0.0063 6.99 0.0017 7.97 0.0020 8.97 0.0017 9.96 0.0012 10.96 0.0004 11.95 0.0004 12.97 0.0001 13.94 0.0002 ) constant trpf-fs4 #( 1.00 0.0998 2.00 0.0632 3.01 0.0506 4.01 0.0395 5.00 0.0265 6.01 0.0137 7.01 0.0058 8.01 0.0017 9.02 0.0010 10.02 0.0007 11.02 0.0007 12.03 0.0004 13.03 0.0004 14.03 0.0002 15.05 0.0001 ) constant trpf-g4 #( 1.00 0.0589 2.00 0.0237 2.99 0.0208 3.98 0.0103 4.98 0.0087 5.98 0.0053 6.97 0.0039 7.98 0.0017 8.98 0.0006 10.00 0.0003 10.97 0.0002 12.00 0.0001 ) constant trpf-gs4 #( 1.01 0.0482 2.01 0.0264 3.02 0.0127 4.01 0.0108 5.01 0.0039 6.01 0.0012 7.00 0.0012 8.01 0.0004 9.02 0.0002 10.02 0.0002 11.00 0.0001 ) constant trpf-a4 #( 1.00 0.0176 2.01 0.0156 3.00 0.0312 3.99 0.0057 5.00 0.0055 5.99 0.0036 6.99 0.0007 7.99 0.0005 8.99 0.0003 9.99 0.0001 10.99 0.0001 ) constant trpf-as4 #( 1.01 0.0051 1.99 0.0340 2.98 0.0087 3.97 0.0121 4.97 0.0018 5.94 0.0018 6.95 0.0005 7.93 0.0002 8.94 0.0004 ) constant trpf-b4 #( 1.01 0.0110 1.99 0.0059 3.00 0.0200 3.99 0.0059 5.00 0.0016 5.99 0.0005 6.98 0.0002 7.96 0.0002 8.99 0.0002 ) constant trpf-c5 #( 1.01 0.0257 2.01 0.0215 3.02 0.0022 4.00 0.0027 5.01 0.0007 6.00 0.0007 7.02 0.0002 ) constant trpf-cs5 #( 1.01 0.0616 2.01 0.0423 3.01 0.0140 4.01 0.0061 4.99 0.0034 5.99 0.0008 6.98 0.0006 8.00 0.0003 8.97 0.0002 ) constant trpf-d5 #( 0.99 0.0763 1.99 0.0800 2.98 0.0329 3.97 0.0255 4.96 0.0110 5.95 0.0041 6.95 0.0018 7.94 0.0006 8.93 0.0005 9.90 0.0002 9.93 0.0002 10.91 0.0002 ) constant trpf-ds5 #( 1.01 0.0196 2.00 0.0085 2.98 0.0039 3.97 0.0007 4.98 0.0003 ) constant trpf-e5 #( 1.02 0.0735 2.03 0.0526 3.04 0.0168 4.05 0.0064 5.07 0.0009 6.07 0.0008 7.09 0.0002 8.09 0.0001 9.12 0.0001 ) constant trpf-f5 #( 1.01 0.1101 2.02 0.0477 3.03 0.0090 4.04 0.0024 5.05 0.0012 6.06 0.0015 7.07 0.0004 8.08 0.0002 ) constant trpf-fs5 #( 1.02 0.1148 2.03 0.0215 3.04 0.0185 4.06 0.0077 5.07 0.0023 6.08 0.0007 7.09 0.0004 8.12 0.0002 ) constant trpf-g5 #( 1.01 0.0538 2.02 0.0584 3.03 0.0156 4.04 0.0028 5.06 0.0009 6.07 0.0006 7.07 0.0002 ) constant trpf-gs5 #( 1.01 0.1885 2.02 0.0789 3.04 0.0214 4.05 0.0086 5.06 0.0049 6.07 0.0010 7.08 0.0007 8.10 0.0003 9.11 0.0003 10.12 0.0001 11.13 0.0001 ) constant trpf-a5 #( 1.01 0.0233 2.02 0.0033 3.01 0.0008 4.03 0.0002 ) constant trpf-as5 #( 1.00 0.1077 2.01 0.0158 3.01 0.0039 4.01 0.0011 5.01 0.0003 6.02 0.0002 7.02 0.0001 ) constant trpf-b5 #( 1.01 0.0873 2.02 0.0519 3.03 0.0156 4.04 0.0042 5.04 0.0019 6.05 0.0006 7.06 0.0004 8.07 0.0002 ) constant trpf-c6 #( 1.01 0.0852 2.02 0.0049 3.03 0.0007 4.05 0.0001 ) constant trpf-cs6 \ ********************************************************** \ violin \ ********************************************************** #( 0.99 0.0159 1.99 0.1898 3.00 0.0499 3.99 0.0352 5.00 0.0192 6.00 0.0100 7.00 0.0173 8.00 0.0142 8.99 0.0045 10.01 0.0178 11.00 0.0108 12.00 0.0081 12.99 0.0254 13.99 0.0074 14.99 0.0062 16.00 0.0122 17.00 0.0049 17.99 0.0022 19.01 0.0041 20.01 0.0048 21.01 0.0037 22.01 0.0016 23.01 0.0001 24.00 0.0002 25.00 0.0006 26.00 0.0010 27.00 0.0015 28.03 0.0004 29.02 0.0007 30.01 0.0006 32.00 0.0002 33.01 0.0001 34.00 0.0001 35.01 0.0004 36.02 0.0003 37.02 0.0001 40.02 0.0001 40.99 0.0002 42.01 0.0003 48.01 0.0001 51.01 0.0001 ) constant vl-g3 #( 0.99 0.0185 1.99 0.1881 2.97 0.0463 3.97 0.0528 4.97 0.0309 5.95 0.0316 6.95 0.0104 7.93 0.0422 8.94 0.0114 9.90 0.0018 10.92 0.0088 11.89 0.0021 12.90 0.0077 13.91 0.0044 14.86 0.0029 14.93 0.0028 15.91 0.0011 16.88 0.0082 17.89 0.0022 18.88 0.0043 19.86 0.0024 20.84 0.0012 21.84 0.0007 22.87 0.0008 23.85 0.0006 24.84 0.0004 25.82 0.0010 26.81 0.0006 27.81 0.0012 28.79 0.0002 29.78 0.0002 30.77 0.0001 31.78 0.0003 33.75 0.0001 34.76 0.0002 35.75 0.0002 36.75 0.0002 37.77 0.0001 40.74 0.0001 ) constant vl-gs3 #( 0.99 0.0215 2.00 0.1550 2.99 0.0293 4.00 0.0298 5.00 0.0211 6.00 0.0389 7.00 0.0057 7.99 0.0235 8.99 0.0172 9.99 0.0040 11.00 0.0026 12.00 0.0074 12.99 0.0065 13.99 0.0192 14.99 0.0026 15.98 0.0063 16.99 0.0045 18.01 0.0036 18.99 0.0050 20.00 0.0012 20.98 0.0011 21.99 0.0007 22.99 0.0014 23.99 0.0003 25.00 0.0011 26.00 0.0008 26.99 0.0007 27.98 0.0002 28.99 0.0001 29.97 0.0004 31.00 0.0002 31.99 0.0002 32.99 0.0002 33.98 0.0001 35.03 0.0001 36.00 0.0002 36.98 0.0003 37.99 0.0002 38.99 0.0001 39.99 0.0002 41.01 0.0001 41.99 0.0001 43.04 0.0001 43.99 0.0001 ) constant vl-a3 #( 1.00 0.0210 2.00 0.1015 3.00 0.0450 3.99 0.0210 4.99 0.0266 6.00 0.0143 7.00 0.0661 7.99 0.0367 8.99 0.0149 9.99 0.0037 10.99 0.0344 11.99 0.0069 12.99 0.0110 13.98 0.0088 14.98 0.0052 15.98 0.0066 16.99 0.0038 17.98 0.0027 18.98 0.0007 19.98 0.0018 20.98 0.0009 21.99 0.0011 22.99 0.0013 23.99 0.0006 24.97 0.0004 25.98 0.0001 26.98 0.0003 27.97 0.0002 28.99 0.0002 29.97 0.0002 31.00 0.0002 31.97 0.0004 32.97 0.0001 33.99 0.0003 34.97 0.0002 35.97 0.0003 36.94 0.0001 37.99 0.0001 38.96 0.0001 41.97 0.0001 ) constant vl-as3 #( 1.00 0.0532 1.99 0.0205 3.00 0.0342 3.99 0.0312 5.00 0.0493 5.99 0.0062 6.99 0.0103 7.99 0.0240 8.99 0.0134 9.99 0.0046 10.98 0.0154 11.99 0.0077 12.98 0.0084 13.99 0.0028 14.99 0.0026 15.98 0.0054 16.98 0.0031 17.99 0.0004 18.98 0.0009 19.99 0.0005 20.52 0.0001 21.98 0.0011 22.97 0.0010 23.99 0.0004 24.96 0.0003 26.00 0.0001 27.99 0.0006 28.99 0.0001 30.97 0.0003 32.00 0.0002 32.99 0.0001 33.97 0.0002 36.99 0.0001 ) constant vl-b3 #( 0.99 0.1156 2.00 0.0827 3.00 0.0458 4.00 0.0163 5.00 0.0256 6.01 0.0103 7.02 0.0032 8.00 0.0025 8.98 0.0056 10.00 0.0072 10.98 0.0016 11.98 0.0036 13.02 0.0013 14.00 0.0021 15.00 0.0024 15.99 0.0013 16.99 0.0003 18.01 0.0001 19.01 0.0003 19.99 0.0001 21.02 0.0001 22.03 0.0002 29.00 0.0001 ) constant vl-c4 #( 1.00 0.3269 2.00 0.0869 2.99 0.0386 4.00 0.0117 4.99 0.0062 6.00 0.0264 7.00 0.0099 8.00 0.0038 9.01 0.0040 10.00 0.0057 11.03 0.0040 12.02 0.0017 13.00 0.0009 14.02 0.0026 15.02 0.0009 15.95 0.0002 16.99 0.0002 18.01 0.0001 19.01 0.0005 20.00 0.0001 21.03 0.0002 22.03 0.0001 ) constant vl-cs4 #( 1.00 0.2473 2.00 0.0621 2.98 0.0073 3.99 0.0178 5.00 0.0070 5.98 0.0041 7.02 0.0054 8.01 0.0114 9.05 0.0034 10.05 0.0024 10.93 0.0003 11.99 0.0011 13.00 0.0011 14.03 0.0010 15.01 0.0002 15.96 0.0001 17.02 0.0001 18.01 0.0005 21.00 0.0001 22.00 0.0002 ) constant vl-d4 #( 1.00 0.0394 2.00 0.0358 2.99 0.0119 3.99 0.0208 4.99 0.0064 5.98 0.0126 6.96 0.0028 7.03 0.0017 8.01 0.0006 8.92 0.0005 9.97 0.0048 10.97 0.0004 11.99 0.0005 12.97 0.0005 13.96 0.0002 14.92 0.0001 15.92 0.0001 19.93 0.0001 22.92 0.0001 23.96 0.0001 ) constant vl-ds4 #( 1.00 0.0649 2.00 0.0412 3.01 0.0315 4.00 0.0446 5.01 0.0414 6.01 0.0209 7.02 0.0189 8.01 0.0101 9.03 0.0012 10.03 0.0029 11.02 0.0041 12.00 0.0012 13.04 0.0004 14.05 0.0005 15.03 0.0009 16.06 0.0005 17.09 0.0004 18.07 0.0006 19.08 0.0004 20.10 0.0001 21.09 0.0001 22.09 0.0004 23.11 0.0002 24.06 0.0002 25.07 0.0002 26.07 0.0002 27.08 0.0002 30.10 0.0001 ) constant vl-e4 #( 1.00 0.0700 2.00 0.0235 3.00 0.0294 4.00 0.0101 4.99 0.0173 5.99 0.0081 6.99 0.0023 7.99 0.0006 8.97 0.0101 9.98 0.0060 11.00 0.0063 11.99 0.0038 13.00 0.0011 13.98 0.0003 15.01 0.0009 16.02 0.0005 17.01 0.0004 18.06 0.0002 19.01 0.0004 20.01 0.0004 21.03 0.0005 22.04 0.0002 23.00 0.0003 24.00 0.0001 25.99 0.0001 29.04 0.0001 31.04 0.0001 ) constant vl-f4 #( 1.01 0.1897 2.02 0.0152 3.02 0.0312 4.03 0.0224 5.03 0.0483 6.04 0.0217 7.05 0.0184 8.07 0.0051 9.06 0.0031 10.08 0.0047 11.09 0.0040 12.10 0.0021 13.10 0.0006 14.11 0.0010 15.14 0.0012 16.14 0.0009 17.15 0.0004 18.16 0.0010 19.18 0.0003 20.19 0.0005 21.14 0.0002 22.17 0.0002 23.18 0.0002 24.18 0.0002 26.22 0.0001 29.25 0.0002 30.26 0.0002 ) constant vl-fs4 #( 1.01 0.0788 2.01 0.0144 2.99 0.0064 3.99 0.0078 5.02 0.0053 6.00 0.0045 7.01 0.0011 7.98 0.0025 9.03 0.0010 10.02 0.0014 11.02 0.0002 12.02 0.0001 13.02 0.0003 14.05 0.0002 15.07 0.0002 17.05 0.0001 18.02 0.0002 19.07 0.0001 ) constant vl-g4 #( 1.00 0.2902 2.01 0.0644 3.01 0.0378 4.02 0.0473 5.02 0.0027 6.03 0.0278 7.04 0.0077 8.04 0.0105 9.04 0.0026 10.04 0.0106 11.05 0.0011 12.05 0.0014 13.06 0.0045 14.09 0.0015 15.09 0.0010 16.09 0.0008 17.09 0.0011 18.10 0.0010 19.09 0.0011 20.09 0.0004 21.10 0.0010 22.10 0.0006 23.11 0.0003 24.10 0.0002 24.14 0.0002 25.15 0.0002 26.14 0.0005 27.14 0.0003 30.13 0.0002 31.14 0.0001 ) constant vl-gs4 #( 1.00 0.3420 2.02 0.0045 3.00 0.0160 4.00 0.0105 5.01 0.0370 6.02 0.0193 7.01 0.0342 8.02 0.0178 9.02 0.0146 10.04 0.0025 11.03 0.0011 12.02 0.0010 13.03 0.0009 14.03 0.0003 15.05 0.0031 16.04 0.0009 17.04 0.0004 18.04 0.0004 19.03 0.0004 20.06 0.0005 21.05 0.0001 22.04 0.0001 24.06 0.0001 25.07 0.0002 26.08 0.0001 ) constant vl-a4 #( 1.00 0.1478 2.00 0.0159 3.00 0.0033 3.99 0.0600 5.00 0.0291 5.99 0.0028 7.01 0.0118 8.00 0.0115 8.99 0.0039 9.99 0.0020 10.99 0.0024 11.99 0.0012 12.99 0.0009 14.01 0.0011 15.00 0.0015 16.01 0.0004 17.02 0.0001 18.01 0.0001 19.01 0.0002 20.00 0.0002 20.98 0.0001 22.00 0.0001 24.02 0.0002 25.00 0.0002 ) constant vl-as4 #( 1.00 0.0247 2.01 0.0570 3.01 0.0115 4.02 0.0167 5.02 0.0162 6.02 0.0154 7.02 0.0056 8.04 0.0021 9.04 0.0003 10.04 0.0023 11.04 0.0003 12.07 0.0005 13.09 0.0005 14.06 0.0003 15.06 0.0004 16.09 0.0003 17.07 0.0002 18.10 0.0003 19.10 0.0002 ) constant vl-b4 #( 1.00 0.0690 1.99 0.0372 2.99 0.0326 3.99 0.0222 4.99 0.0107 5.97 0.0033 6.99 0.0029 7.98 0.0013 8.97 0.0005 9.98 0.0008 10.97 0.0004 11.97 0.0006 12.99 0.0003 13.99 0.0002 14.97 0.0001 16.95 0.0001 16.98 0.0001 17.97 0.0001 19.96 0.0001 ) constant vl-c5 #( 1.00 0.1446 2.01 0.0499 3.01 0.0768 4.02 0.0436 5.02 0.0287 6.03 0.0204 7.03 0.0301 7.11 0.0011 8.04 0.0010 9.04 0.0036 10.05 0.0030 11.05 0.0023 12.06 0.0008 13.06 0.0005 14.07 0.0009 15.08 0.0005 16.09 0.0009 17.08 0.0003 18.10 0.0006 19.09 0.0008 20.13 0.0002 21.11 0.0001 22.14 0.0001 23.11 0.0002 ) constant vl-cs5 #( 1.00 0.0614 1.99 0.0194 2.99 0.0196 3.99 0.0159 5.00 0.0057 6.00 0.0031 7.01 0.0024 8.00 0.0004 9.00 0.0003 9.98 0.0003 11.01 0.0005 11.99 0.0003 12.99 0.0002 16.99 0.0001 17.98 0.0001 ) constant vl-d5 #( 0.99 0.1393 1.99 0.0875 2.99 0.1163 3.98 0.0152 4.98 0.0551 5.97 0.0214 6.97 0.0072 7.96 0.0017 8.95 0.0028 9.96 0.0034 10.95 0.0015 11.94 0.0010 12.95 0.0009 13.91 0.0008 14.94 0.0011 15.93 0.0005 16.93 0.0007 17.92 0.0004 17.97 0.0002 18.94 0.0002 19.93 0.0003 20.92 0.0004 21.90 0.0001 ) constant vl-ds5 #( 1.00 0.1926 2.00 0.0731 3.00 0.0543 4.00 0.0258 5.02 0.0238 6.02 0.0177 7.03 0.0206 8.03 0.0081 9.03 0.0030 10.05 0.0043 11.03 0.0011 12.06 0.0007 13.08 0.0013 14.10 0.0007 15.11 0.0004 16.14 0.0002 ) constant vl-e5 #( 1.00 0.0684 2.00 0.0409 3.00 0.0344 4.00 0.0439 5.00 0.0686 6.00 0.0504 7.00 0.0045 8.00 0.0056 9.00 0.0094 10.00 0.0028 11.00 0.0015 11.99 0.0010 13.00 0.0032 14.00 0.0017 15.00 0.0010 16.01 0.0011 16.99 0.0003 18.01 0.0006 19.00 0.0003 ) constant vl-f5 #( 1.00 0.0291 2.01 0.0323 3.01 0.0110 4.02 0.0071 5.04 0.0028 6.04 0.0010 7.08 0.0007 8.08 0.0003 9.09 0.0004 10.12 0.0002 11.06 0.0003 ) constant vl-fs5 #( 1.00 0.0980 1.99 0.0303 3.00 0.0044 4.01 0.0107 5.03 0.0027 6.03 0.0011 7.00 0.0010 8.02 0.0011 8.06 0.0004 9.04 0.0003 10.04 0.0001 ) constant vl-g5 #( 1.01 0.1116 2.01 0.0200 3.03 0.0147 4.03 0.0034 5.08 0.0061 6.10 0.0012 7.06 0.0005 8.14 0.0005 9.14 0.0004 ) constant vl-gs5 #( 1.00 0.0211 2.01 0.0180 3.01 0.0158 4.02 0.0057 5.03 0.0013 6.03 0.0006 7.02 0.0001 ) constant vl-a5 #( 1.00 0.0442 2.01 0.0922 3.01 0.0102 4.00 0.0031 5.03 0.0053 6.01 0.0004 7.04 0.0018 7.08 0.0009 8.06 0.0004 9.06 0.0006 10.06 0.0003 11.06 0.0003 12.09 0.0002 13.09 0.0002 ) constant vl-as5 #( 1.01 0.0061 2.01 0.0016 3.01 0.0014 4.03 0.0005 5.04 0.0005 5.06 0.0001 ) constant vl-b5 #( 1.01 0.0039 2.00 0.0005 3.02 0.0006 4.03 0.0001 ) constant vl-c6 #( 1.00 0.0754 2.00 0.1620 3.00 0.1551 4.00 0.0277 5.00 0.0466 6.00 0.0408 7.00 0.0025 8.00 0.0055 9.00 0.0048 9.99 0.0034 10.99 0.0039 11.99 0.0005 ) constant vl-cs6 #( 1.00 0.0905 2.00 0.0808 3.00 0.0909 4.00 0.0616 5.00 0.0172 5.99 0.0043 7.01 0.0044 8.00 0.0036 9.00 0.0043 10.01 0.0015 11.03 0.0014 ) constant vl-d6 #( 1.00 0.1772 2.00 0.1029 3.00 0.0398 4.01 0.0602 5.00 0.0222 6.01 0.0073 7.01 0.0037 8.01 0.0044 9.01 0.0019 10.01 0.0028 11.01 0.0006 11.03 0.0001 ) constant vl-ds6 #( 1.00 0.1865 2.00 0.2083 2.99 0.0822 3.99 0.0298 4.99 0.0227 6.00 0.0023 6.98 0.0049 7.99 0.0021 8.98 0.0022 9.98 0.0003 9.99 0.0003 ) constant vl-e6 #( 1.01 0.0841 2.01 0.0654 3.02 0.1346 4.03 0.0041 5.04 0.0077 6.05 0.0088 7.05 0.0016 8.06 0.0017 9.06 0.0012 9.08 0.0003 9.10 0.0002 9.11 0.0001 ) constant vl-f6 #( 1.00 0.1693 2.02 0.0779 3.03 0.0411 4.03 0.0147 5.04 0.0085 6.05 0.0080 7.06 0.0088 8.06 0.0032 9.06 0.0010 9.08 0.0007 9.10 0.0004 ) constant vl-fs6 #( 1.01 0.2123 2.02 0.2854 3.03 0.0552 4.04 0.0246 5.05 0.0058 6.06 0.0022 7.07 0.0017 8.09 0.0029 9.10 0.0001 ) constant vl-g6 #( 1.02 0.1270 2.03 0.0961 3.05 0.0347 4.06 0.0032 5.08 0.0083 6.09 0.0050 7.11 0.0020 8.12 0.0013 8.14 0.0002 ) constant vl-gs6 #( 1.02 0.3359 2.03 0.1252 3.05 0.0238 4.07 0.0155 5.09 0.0053 6.10 0.0051 7.12 0.0025 7.18 0.0001 ) constant vl-a6 #( 1.01 0.2037 2.03 0.0456 3.05 0.0029 4.06 0.0053 5.07 0.0041 6.09 0.0043 7.11 0.0026 7.13 0.0006 7.14 0.0001 ) constant vl-as6 #( 1.02 0.4213 2.04 0.1379 3.06 0.0067 4.06 0.0041 4.08 0.0039 5.09 0.0026 6.11 0.0027 7.13 0.0002 ) constant vl-b6 #( 1.01 0.1299 2.02 0.1571 3.03 0.0461 4.04 0.0033 5.05 0.0057 6.06 0.0015 ) constant vl-c7 #( 1.01 0.1471 2.03 0.0526 3.05 0.0161 4.06 0.0037 5.08 0.0017 6.09 0.0005 ) constant vl-cs7 #( 1.01 0.0321 2.02 0.0529 3.03 0.0046 4.03 0.0054 4.04 0.0021 5.04 0.0010 ) constant vl-d7 #( 1.00 0.1220 2.00 0.0667 2.99 0.0319 4.00 0.0020 4.99 0.0052 5.03 0.0002 ) constant vl-ds7 #( 1.01 0.1110 2.02 0.0588 3.03 0.0143 4.04 0.0068 5.05 0.0011 ) constant vl-e7 #( 1.01 0.0798 2.02 0.0111 3.03 0.0125 4.03 0.0036 4.50 0.0002 5.04 0.0001 ) constant vl-f7 #( 1.02 0.1071 2.04 0.0117 3.06 0.0148 4.08 0.0092 4.11 0.0007 4.13 0.0005 4.16 0.0003 4.23 0.0002 4.24 0.0002 4.28 0.0002 4.34 0.0001 4.39 0.0001 ) constant vl-fs7 #( 1.02 0.2741 2.05 0.0256 3.07 0.0122 4.11 0.0002 4.14 0.0001 ) constant vl-g7 #( 1.02 0.1027 2.05 0.0192 3.07 0.0091 ) constant vl-gs7 #( 1.02 0.0796 2.04 0.0112 3.06 0.0030 ) constant vl-a7 #( 1.06 0.1256 ) constant vl-as7 #( 1.08 0.1494 3.24 0.0003 ) constant vl-b7 #( 1.07 0.0582 3.25 0.0004 ) constant vl-c8 #( 1.08 0.0889 ) constant vl-cs8 #( 1.07 0.0573 ) constant vl-d8 \ ********************************************************** \ \ ********************************************************** #( 1.01 0.0037 2.01 0.0482 3.01 0.0275 4.01 0.0182 5.03 0.0047 6.03 0.0032 7.03 0.0005 8.03 0.0050 9.05 0.0044 10.02 0.0016 11.06 0.0011 12.06 0.0004 13.06 0.0006 14.16 0.0001 15.12 0.0001 16.12 0.0004 17.12 0.0004 19.08 0.0003 20.11 0.0004 23.11 0.0002 24.14 0.0003 25.14 0.0003 27.12 0.0002 28.13 0.0001 30.17 0.0001 ) constant almf-c3 #( 1.01 0.0043 2.01 0.0357 3.02 0.0452 4.01 0.0156 5.02 0.0152 6.04 0.0022 7.04 0.0039 8.06 0.0078 9.06 0.0049 10.09 0.0046 11.24 0.0004 12.08 0.0016 13.09 0.0015 14.10 0.0021 15.12 0.0006 16.12 0.0012 17.12 0.0002 18.16 0.0004 19.16 0.0006 20.15 0.0006 21.15 0.0007 22.16 0.0005 23.17 0.0005 24.13 0.0004 25.48 0.0003 26.19 0.0002 27.18 0.0002 28.20 0.0002 30.26 0.0001 31.25 0.0002 34.23 0.0001 ) constant almf-cs3 #( 1.01 0.0052 2.03 0.0062 3.01 0.0292 4.05 0.0043 5.02 0.0149 5.97 0.0018 7.02 0.0016 8.05 0.0029 9.04 0.0005 10.06 0.0012 11.04 0.0006 12.12 0.0002 13.05 0.0005 14.10 0.0004 15.08 0.0004 15.99 0.0001 17.18 0.0001 18.07 0.0004 19.06 0.0001 20.08 0.0003 22.11 0.0003 24.13 0.0002 25.15 0.0001 26.12 0.0001 ) constant almf-d3 #( 1.01 0.0043 2.01 0.0532 3.01 0.0389 4.00 0.0094 5.01 0.0031 6.00 0.0038 7.00 0.0219 8.00 0.0122 8.99 0.0129 10.00 0.0014 11.00 0.0021 12.01 0.0037 13.01 0.0021 14.01 0.0017 15.02 0.0015 16.01 0.0023 17.03 0.0024 18.00 0.0008 19.03 0.0011 20.04 0.0003 21.04 0.0009 22.04 0.0003 23.00 0.0012 24.00 0.0011 25.01 0.0007 27.02 0.0002 28.02 0.0004 29.03 0.0003 30.04 0.0002 31.04 0.0001 46.55 0.0001 48.01 0.0001 ) constant almf-ds3 #( 1.00 0.0123 2.00 0.0733 2.99 0.0330 4.00 0.0098 5.00 0.0171 6.00 0.0013 7.01 0.0117 7.99 0.0020 9.00 0.0044 10.01 0.0012 11.01 0.0014 12.00 0.0021 13.02 0.0002 14.02 0.0016 15.03 0.0012 16.03 0.0028 17.02 0.0007 18.02 0.0019 19.03 0.0008 20.04 0.0013 21.03 0.0005 22.03 0.0005 23.03 0.0003 24.04 0.0003 26.03 0.0005 27.04 0.0001 28.06 0.0001 29.04 0.0002 ) constant almf-e3 #( 1.00 0.0185 2.00 0.0813 3.00 0.0142 3.99 0.0132 5.00 0.0066 5.99 0.0027 6.93 0.0009 8.01 0.0042 8.99 0.0018 9.97 0.0002 10.97 0.0010 12.00 0.0008 13.00 0.0012 13.98 0.0003 14.96 0.0006 16.00 0.0004 17.01 0.0005 18.00 0.0003 18.98 0.0005 19.99 0.0002 20.99 0.0002 22.00 0.0002 ) constant almf-f3 #( 1.01 0.0480 2.01 0.0778 3.01 0.0124 4.01 0.0204 5.05 0.0008 6.03 0.0068 7.05 0.0052 8.06 0.0017 9.07 0.0017 10.05 0.0008 11.07 0.0010 12.08 0.0008 13.11 0.0002 14.08 0.0006 15.10 0.0002 16.09 0.0013 17.12 0.0003 18.10 0.0003 19.11 0.0004 20.14 0.0001 23.17 0.0001 ) constant almf-fs3 #( 1.00 0.0526 2.00 0.0242 2.99 0.0351 3.99 0.0076 4.98 0.0062 5.99 0.0085 6.99 0.0061 8.04 0.0006 8.98 0.0005 10.01 0.0006 10.97 0.0003 11.96 0.0004 13.07 0.0004 13.95 0.0003 14.99 0.0003 15.20 0.0002 17.93 0.0002 18.02 0.0002 24.96 0.0001 ) constant almf-g3 #( 0.99 0.0523 1.99 0.0560 2.98 0.0166 3.98 0.0183 4.96 0.0005 5.98 0.0066 6.99 0.0026 7.96 0.0011 8.95 0.0013 9.95 0.0026 10.95 0.0019 11.96 0.0017 12.94 0.0005 13.92 0.0002 14.94 0.0006 15.95 0.0007 16.94 0.0007 17.96 0.0002 18.92 0.0002 19.93 0.0002 20.92 0.0002 21.94 0.0001 ) constant almf-gs3 #( 1.00 0.1590 2.00 0.0394 3.02 0.0076 3.99 0.0222 5.00 0.0063 5.93 0.0008 6.97 0.0016 7.95 0.0002 8.94 0.0002 9.94 0.0003 10.05 0.0002 10.15 0.0001 12.00 0.0005 12.12 0.0002 12.95 0.0001 15.98 0.0002 ) constant almf-a3 #( 1.00 0.2533 2.00 0.0498 3.00 0.0178 3.99 0.0108 5.00 0.0245 6.00 0.0112 6.99 0.0066 8.00 0.0010 8.98 0.0074 9.99 0.0042 10.99 0.0025 12.00 0.0015 13.01 0.0006 14.00 0.0012 15.00 0.0004 16.02 0.0004 17.00 0.0010 18.00 0.0005 18.99 0.0002 19.98 0.0002 ) constant almf-as3 #( 1.00 0.1639 2.00 0.0436 3.01 0.0584 4.01 0.0080 5.01 0.0117 6.01 0.0208 7.02 0.0062 8.02 0.0035 9.03 0.0037 10.03 0.0022 11.04 0.0023 12.04 0.0048 13.04 0.0022 14.04 0.0005 15.04 0.0007 16.05 0.0012 17.05 0.0010 18.06 0.0005 19.05 0.0001 20.06 0.0005 21.07 0.0002 24.07 0.0002 25.08 0.0002 27.08 0.0002 28.10 0.0001 33.12 0.0001 ) constant almf-b3 #( 1.00 0.0931 2.00 0.0251 3.00 0.0077 4.00 0.0129 5.00 0.0115 6.00 0.0055 7.00 0.0041 8.01 0.0046 9.00 0.0013 10.00 0.0067 11.02 0.0011 12.02 0.0021 12.99 0.0002 14.01 0.0007 15.02 0.0008 16.03 0.0007 17.02 0.0004 19.02 0.0003 20.05 0.0001 24.04 0.0001 ) constant almf-c4 #( 1.01 0.0587 2.01 0.0263 3.02 0.0299 4.03 0.0306 5.04 0.0172 6.04 0.0097 7.05 0.0024 8.06 0.0034 9.06 0.0053 10.07 0.0065 11.08 0.0025 12.09 0.0005 13.10 0.0016 14.11 0.0011 15.11 0.0009 16.12 0.0004 17.13 0.0002 18.13 0.0003 21.15 0.0002 23.17 0.0001 24.18 0.0001 25.19 0.0002 30.23 0.0001 32.25 0.0001 ) constant almf-cs4 #( 1.00 0.0619 2.00 0.0432 3.01 0.0479 4.01 0.0136 5.00 0.0220 6.01 0.0064 7.02 0.0138 8.02 0.0033 9.02 0.0066 10.06 0.0006 11.02 0.0019 12.01 0.0013 13.02 0.0008 14.01 0.0004 15.03 0.0007 16.04 0.0003 17.03 0.0001 18.02 0.0001 21.04 0.0003 ) constant almf-d4 #( 1.00 0.0762 1.99 0.0071 2.99 0.0085 3.99 0.0120 4.98 0.0064 5.98 0.0018 6.98 0.0039 7.99 0.0027 8.96 0.0017 9.95 0.0007 10.98 0.0006 11.95 0.0003 12.98 0.0006 13.98 0.0007 15.97 0.0002 19.96 0.0001 ) constant almf-ds4 #( 0.99 0.0726 1.99 0.0195 2.99 0.0147 3.98 0.0106 4.99 0.0069 6.00 0.0026 6.99 0.0046 7.99 0.0105 8.97 0.0017 10.01 0.0007 10.97 0.0022 11.99 0.0009 12.99 0.0011 13.98 0.0001 14.96 0.0002 15.96 0.0001 16.99 0.0001 17.95 0.0002 18.98 0.0002 20.98 0.0001 21.97 0.0001 ) constant almf-e4 #( 1.00 0.0772 2.00 0.0150 3.00 0.0166 4.01 0.0118 4.99 0.0024 6.01 0.0067 7.03 0.0017 8.00 0.0012 9.02 0.0017 10.02 0.0011 11.03 0.0008 12.04 0.0004 13.04 0.0007 14.03 0.0002 15.04 0.0002 16.04 0.0001 ) constant almf-f4 #( 0.99 0.1309 1.99 0.0550 2.98 0.0321 3.98 0.0270 4.97 0.0070 5.97 0.0099 6.96 0.0041 7.96 0.0033 8.95 0.0023 9.94 0.0017 10.94 0.0023 11.93 0.0015 12.93 0.0006 13.95 0.0002 14.93 0.0002 15.91 0.0002 16.91 0.0003 17.92 0.0001 18.90 0.0003 19.93 0.0001 22.87 0.0001 23.88 0.0001 ) constant almf-fs4 #( 0.99 0.0515 2.00 0.0153 3.00 0.0281 4.00 0.0071 5.01 0.0020 6.00 0.0045 7.02 0.0006 8.00 0.0054 8.99 0.0020 10.00 0.0031 11.01 0.0023 12.02 0.0003 13.00 0.0004 14.01 0.0002 15.02 0.0003 15.98 0.0002 16.02 0.0002 18.03 0.0002 19.01 0.0001 ) constant almf-g4 #( 1.00 0.0592 2.00 0.0287 3.00 0.0196 3.99 0.0175 4.99 0.0168 6.00 0.0071 6.07 0.0008 7.00 0.0003 7.99 0.0019 8.98 0.0007 9.98 0.0012 10.99 0.0012 11.98 0.0004 12.98 0.0003 13.99 0.0002 14.96 0.0001 15.98 0.0001 16.97 0.0002 17.96 0.0002 ) constant almf-gs4 #( 1.01 0.0784 2.01 0.0480 3.02 0.0131 4.02 0.0074 5.03 0.0141 6.03 0.0173 7.04 0.0070 8.04 0.0033 9.06 0.0154 9.12 0.0016 10.07 0.0011 11.07 0.0013 12.07 0.0009 13.09 0.0008 14.07 0.0006 15.09 0.0002 16.10 0.0005 17.10 0.0003 19.12 0.0001 23.14 0.0001 ) constant almf-a4 #( 1.00 0.0507 2.00 0.0304 3.00 0.0303 4.00 0.0084 5.00 0.0072 6.00 0.0098 6.99 0.0058 8.01 0.0036 9.01 0.0023 10.00 0.0010 11.00 0.0008 12.00 0.0007 12.97 0.0005 13.02 0.0004 14.00 0.0003 14.99 0.0003 16.01 0.0001 17.01 0.0002 18.00 0.0001 20.01 0.0001 ) constant almf-as4 #( 1.00 0.0340 2.00 0.0113 3.01 0.0098 4.02 0.0033 5.03 0.0013 6.05 0.0008 7.02 0.0007 8.07 0.0006 9.01 0.0001 ) constant almf-b4 #( 1.00 0.0384 2.00 0.0426 3.01 0.0092 4.02 0.0239 5.02 0.0184 6.02 0.0031 7.03 0.0029 8.04 0.0016 8.10 0.0006 9.04 0.0005 10.04 0.0003 11.05 0.0006 12.05 0.0007 13.06 0.0002 15.07 0.0002 ) constant almf-c5 #( 1.00 0.0159 2.00 0.0592 3.00 0.0390 4.00 0.0272 5.00 0.0121 6.00 0.0032 7.01 0.0124 8.01 0.0055 9.00 0.0009 10.01 0.0016 11.01 0.0007 12.01 0.0006 13.02 0.0020 14.02 0.0010 15.02 0.0007 16.03 0.0004 17.03 0.0002 18.02 0.0001 19.03 0.0001 20.03 0.0003 21.03 0.0002 22.03 0.0003 23.03 0.0002 ) constant almf-cs5 #( 1.01 0.0376 2.01 0.0409 3.02 0.0136 4.03 0.0016 5.05 0.0080 6.05 0.0044 7.06 0.0036 8.07 0.0018 9.07 0.0007 10.08 0.0011 11.09 0.0002 12.09 0.0004 13.12 0.0003 14.11 0.0001 16.15 0.0002 17.16 0.0001 20.18 0.0001 ) constant almf-d5 #( 1.00 0.0391 2.01 0.0445 3.01 0.0188 4.02 0.0329 5.02 0.0185 6.02 0.0311 7.03 0.0107 8.03 0.0032 9.03 0.0010 10.03 0.0009 11.04 0.0019 12.04 0.0019 13.05 0.0005 14.06 0.0004 15.05 0.0007 16.06 0.0002 17.07 0.0002 18.08 0.0002 19.07 0.0005 20.07 0.0003 21.08 0.0001 ) constant almf-ds5 #( 1.00 0.0869 2.00 0.0181 3.01 0.0252 4.01 0.0520 5.01 0.0040 6.02 0.0336 7.02 0.0108 8.03 0.0070 9.03 0.0023 10.03 0.0009 11.03 0.0017 12.02 0.0004 13.04 0.0012 14.04 0.0006 15.05 0.0016 16.06 0.0007 17.06 0.0003 18.06 0.0012 19.07 0.0001 20.06 0.0001 ) constant almf-e5 #( 1.01 0.0905 2.02 0.0649 3.02 0.0406 4.03 0.0295 5.04 0.0038 6.05 0.0088 7.06 0.0009 8.07 0.0021 9.07 0.0037 10.09 0.0022 11.09 0.0014 12.09 0.0018 13.11 0.0006 14.12 0.0009 15.13 0.0004 16.12 0.0003 17.14 0.0006 18.15 0.0002 ) constant almf-f5 #( 0.99 0.0868 1.98 0.0447 2.98 0.0303 3.97 0.0092 4.96 0.0183 5.95 0.0121 6.94 0.0033 7.95 0.0010 8.92 0.0022 9.92 0.0007 10.91 0.0007 11.90 0.0007 12.89 0.0014 13.87 0.0004 14.88 0.0006 14.91 0.0003 15.87 0.0002 16.85 0.0003 ) constant almf-fs5 #( 1.00 0.0467 2.00 0.0739 3.00 0.0255 4.00 0.0277 5.00 0.0349 6.00 0.0119 7.00 0.0024 8.00 0.0085 9.00 0.0016 9.99 0.0012 11.00 0.0004 11.99 0.0014 12.99 0.0024 13.99 0.0017 14.99 0.0007 15.99 0.0004 16.98 0.0001 ) constant almf-g5 #( 0.99 0.0605 1.99 0.0384 2.98 0.0154 3.98 0.0036 4.97 0.0164 5.96 0.0039 6.96 0.0036 7.95 0.0040 8.94 0.0012 9.94 0.0006 10.93 0.0015 11.93 0.0012 12.93 0.0008 13.91 0.0010 14.90 0.0005 15.91 0.0001 ) constant almf-gs5 #( 1.00 0.1051 2.01 0.0322 3.02 0.0393 4.03 0.0112 5.03 0.0099 6.04 0.0074 7.05 0.0054 8.05 0.0030 9.06 0.0019 10.07 0.0006 11.07 0.0023 12.08 0.0004 13.08 0.0005 14.09 0.0006 14.11 0.0001 15.11 0.0001 ) constant almf-a5 #( 1.00 0.0284 2.01 0.0161 3.02 0.0248 4.03 0.0414 5.03 0.0135 6.04 0.0028 7.05 0.0021 8.06 0.0006 9.07 0.0009 10.07 0.0010 11.08 0.0012 12.10 0.0003 13.09 0.0010 14.10 0.0003 ) constant almf-as5 #( 0.99 0.0354 1.98 0.0173 2.97 0.0086 3.96 0.0204 3.99 0.0077 4.03 0.0067 4.06 0.0037 4.95 0.0034 5.93 0.0030 5.96 0.0015 5.98 0.0009 6.92 0.0007 7.92 0.0008 8.91 0.0017 9.90 0.0008 9.93 0.0006 10.88 0.0003 11.91 0.0003 12.86 0.0004 12.90 0.0002 ) constant almf-b5 #( 1.01 0.0675 2.01 0.0578 3.02 0.0346 4.03 0.0170 5.03 0.0082 6.04 0.0050 7.06 0.0032 8.03 0.0009 9.06 0.0009 10.07 0.0008 11.09 0.0010 12.03 0.0002 ) constant almf-c6 #( 1.00 0.0896 1.99 0.0634 3.01 0.0037 3.98 0.0105 4.98 0.0030 5.98 0.0019 6.97 0.0020 7.97 0.0014 8.00 0.0007 8.99 0.0005 9.96 0.0005 10.95 0.0008 10.98 0.0005 11.00 0.0003 11.02 0.0003 11.03 0.0002 11.06 0.0002 11.95 0.0001 11.98 0.0001 ) constant almf-cs6 #( 1.00 0.0593 2.00 0.0364 3.01 0.0142 4.01 0.0065 5.02 0.0063 6.01 0.0024 7.02 0.0010 8.02 0.0019 9.02 0.0015 10.03 0.0007 11.02 0.0002 ) constant almf-d6 #( 1.00 0.0410 1.99 0.0353 2.99 0.0291 3.99 0.0089 4.99 0.0066 5.98 0.0023 6.99 0.0012 7.96 0.0011 7.99 0.0006 8.94 0.0004 8.98 0.0003 9.95 0.0001 ) constant almf-ds6 #( 1.01 0.0254 2.01 0.0252 3.02 0.0365 4.03 0.0034 5.02 0.0013 6.02 0.0010 7.08 0.0006 8.02 0.0010 9.03 0.0007 9.12 0.0004 ) constant almf-e6 #( 1.00 0.1896 2.00 0.0411 3.00 0.0216 4.00 0.0019 5.00 0.0032 6.01 0.0012 7.02 0.0007 7.99 0.0026 9.00 0.0003 9.03 0.0002 ) constant almf-f6 #( 1.01 0.0285 2.01 0.0189 3.02 0.0213 4.02 0.0033 5.03 0.0024 6.03 0.0010 7.04 0.0016 8.05 0.0015 9.05 0.0003 9.06 0.0002 ) constant almf-fs6 #( 1.00 0.1939 2.00 0.0339 3.00 0.0219 4.01 0.0079 5.01 0.0025 6.01 0.0017 7.01 0.0014 7.95 0.0009 8.00 0.0006 8.02 0.0003 ) constant almf-g6 #( 1.00 0.1069 2.00 0.0146 3.00 0.0220 4.00 0.0046 5.00 0.0020 6.00 0.0027 6.99 0.0011 8.00 0.0003 ) constant almf-gs6 #( 1.00 0.0952 1.99 0.0201 3.00 0.0015 3.99 0.0064 4.98 0.0021 5.97 0.0009 6.98 0.0010 ) constant almf-a6 #( 1.00 0.0132 1.99 0.0635 2.99 0.0057 3.98 0.0054 3.99 0.0034 4.99 0.0011 5.96 0.0012 5.98 0.0008 5.99 0.0007 6.96 0.0004 6.98 0.0004 ) constant almf-as6 #( 1.00 0.0241 2.01 0.0417 3.02 0.0098 3.99 0.0016 4.02 0.0016 5.03 0.0016 6.04 0.0012 ) constant almf-b6 \ spectr.fs ends here snd-16.1/examp.rb0000644000076400007640000023107512462674025012012 0ustar bilbil# examp.rb -- something from examp.scm # Translator/Author: Michael Scholz # Created: 02/09/04 18:34:00 # Changed: 15/01/29 23:09:30 # module Examp (examp.scm) # selection_rms # region_rms(n) # window_samples(snd, chn) # display_energy(snd, chn) # display_db(snd, chn) # window_rms # fft_peak(snd, chn, scale) # finfo(file) # display_correlate(snd, chn, y0, y1) # # zoom_spectrum(snd, chn, y0, y1) # zoom_fft(snd, chn, y0, y1) # superimpose_ffts(snd, chn, y0, y1) # locate_zero(limit) # shell(cmd, *rest) # # mpg(mpgfile, rawfile) # read_ogg(filename) # write_ogg(snd) # read_speex(filename) # write_speex(snd) # read_flac(filename) # write_flac(snd) # read_ascii(in_filename, out_filename, out_type, out_format, out_srate) # auto_dot(snd, chn, y0, y1) # # first_mark_in_window_at_left # flash_selected_data(interval) # mark_loops # do_all_chans(origin) do |y| ... end # update_graphs # do_chans(*origin) do |y| ... end # do_sound_chans(*origin) do |y| ... end # every_sample? do |y| ... end # sort_samples(nbins) # place_sound(mono_snd, stereo_snd, pan_env) # # fft_edit(bottom, top, snd, chn) # fft_squelch(squelch, snd, chn) # fft_cancel(lo_freq, hi_freq, snd, chn) # # class Ramp < Musgen # initialize(size) # run_func(up, dummy) # run(up) # # make_ramp(size) # ramp(gen, up) # squelch_vowels(snd, chn) # fft_env_data(fft_env, snd, chn) # fft_env_edit(fft_env, snd, chn) # fft_env_interp(env1, env2, interp, snd, chn) # fft_smoother(cutoff, start, samps, snd, chn) # # comb_filter(scaler, size) # comb_chord(scaler, size, amp, interval_one, interval_two) # zcomb(scaler, size, pm) # notch_filter(scaler, size) # formant_filter(radius, freq) # formants(r1, f1, r2, f2, r3, f3) # moving_formant(radius, move) # osc_formants(radius, bases, amounts, freqs) # echo(scaler, secs) # zecho(scaler, secs, freq, amp) # flecho(scaler, secs) # ring_mod(freq, gliss_env) # am(freq) # vibro(speed, depth) # hello_dentist(freq, amp, snd, chn) # fp(sr, osamp, osfreq, snd, chn) # compand() # expsrc(rate, snd, chn) # expsnd(gr_env, snd, chn) # cross_synthesis(cross_snd, amp, fftsize, r) # voiced2unvoiced(amp, fftsize, r, temp, snd, chn) # pulse_voice(cosin, freq, amp, fftsize, r, snd, chn) # cnvtest(snd0, snd1, amp) # # swap_selection_channels # make_sound_interp(start, snd, chn) # sound_interp(func, loc) # sound_via_sound(snd1, snd2) # env_sound_interp(envelope, time_scale, snd, chn) # granulated_sound_interp(en, time_scale, grain_len, grain_env, out_hop, s, c) # filtered_env(en, snd, chn) # # class Mouse # initialize # press(snd, chn, button, state, x, y) # drag(snd, chn, button, state, x, y) # # files_popup_buffer(type, position, name) # # find_click(loc) # remove_clicks # search_for_click # zero_plus # next_peak # find_pitch(pitch) # file2vct(file) # add_notes(notes, snd, chn) # region_play_list(data) # region_play_sequence(data) # replace_with_selection # explode_sf2 # # class Next_file # initialize # open_next_file_in_directory # click_middle_button_to_open_next_file_in_directory # # chain_dsps(start, dur, *dsps) # # scramble_channels(*new_order) # scramble_channel(silence) # # reverse_by_blocks(block_len, snd, chn) # reverse_within_blocks(block_len, snd, chn) # sound2segment_data(main_dir, output_file) # channel_clipped?(snd, chn) # scan_sound(func, beg, dur, snd) # or scan_sound_rb(beg, dur, snd) do |y, chn| ... end # # class Moog_filter < Musgen (moog.scm) # initialize(freq, q) # frequency=(freq) # filter(insig) # # module Moog # make_moog_filter(freq, q) # moog_filter(moog, insig) # moog(freq, q) require "clm" module Examp # (ext)snd.html examples made harder to break # # this mainly involves keeping track of the current sound/channel add_help(:selection_rms, "selection_rms() \ Returns rms of selection data using samplers.") def selection_rms if selection? reader = make_sampler(selection_position, false, false) len = selection_framples() sum = 0.0 len.times do val = next_sample(reader) sum = sum + val * val end free_sampler(reader) sqrt(sum / len) else Snd.raise(:no_active_selection) end end add_help(:region_rms, "region_rms(n=0) \ Returns rms of region N's data (chan 0).") def region_rms(n = 0) if region?(n) data = region2vct(n, 0, 0) sqrt(dot_product(data, data) / data.length) else Snd.raise(:no_such_region) end end add_help(:window_samples, "window_samples(snd=false, chn=false) \ Returns samples in snd channel chn in current graph window.") def window_samples(snd = false, chn = false) wl = left_sample(snd, chn) wr = right_sample(snd, chn) channel2vct(wl, 1 + (wr - wl), snd, chn) end add_help(:display_energy, "display_energy(snd, chn) \ Is a $lisp_graph_hook function to display the time domain \ data as energy (squared): $lisp_graph_hook.add_hook!(\"display-energy\", \ &method(:display_energy).to_proc)") def display_energy(snd, chn) ls = left_sample(snd, chn) rs = right_sample(snd, chn) datal = make_graph_data(snd, chn) data = vct?(datal) ? datal : datal[1] sr = srate(snd) y_max = y_zoom_slider(snd, chn) if data and ls and rs vct_multiply!(data, data) graph(data, "energy", ls / sr, rs / sr, 0.0, y_max * y_max, snd, chn) end end add_help(:display_db, "display_db(snd, chn) \ Is a $lisp_graph_hook function to display the time domain data in dB: $lisp_graph_hook.add_hook!(\"display-db\", &method(:display_db).to_proc)") def display_db(snd, chn) if datal = make_graph_data(snd, chn) dB = lambda do |val| if val < 0.001 -60.0 else 20.0 * log10(val) end end data = vct?(datal) ? datal : datal[1] sr = srate(snd) ls = left_sample(snd, chn) rs = right_sample(snd, chn) data.map! do |val| 60.0 + dB.call(val.abs) end graph(data, "dB", ls / sr, rs / sr, 0.0, 60.0, snd, chn) end end add_help(:window_rms, "window_rms() \ Returns rms of data in currently selected graph window.") def window_rms ls = left_sample rs = right_sample data = channel2vct(ls, 1 + (rs - ls)) sqrt(dot_product(data, data), data.length) end add_help(:fft_peak, "fft_peak(snd, chn, scale) \ Returns the peak spectral magnitude: $after_transform_hook.add_hook!(\"fft-peak\") do |snd, chn, scale| fft_peak(snd, chn, scale) end") def fft_peak(snd, chn, scale) if transform_graph? and transform_graph_type == Graph_once pk = (2.0 * vct_peak(transform2vct(snd, chn))) / transform_size status_report(pk.to_s, snd) pk else false end end # 'info' from extsnd.html using format add_help(:finfo, "finfo(file) \ Returns description (as a string) of FILE.") def finfo(file) chans = mus_sound_chans(file) sr = mus_sound_srate(file) format("%s: chans: %d, srate: %d, %s, %s, len: %1.3f", file, chans, sr, mus_header_type_name(mus_sound_header_type(file)), mus_sample_type_name(mus_sound_sample_type(file)), mus_sound_samples(file).to_f / (chans * sr.to_f)) end # Correlation # # correlation of channels in a stereo sound add_help(:display_correlate, "display_correlate(snd, chn, y0, y1) \ Returns the correlation of SND's 2 channels (intended for use with $graph_hook): $graph_hook.add_hook!(\"display_correlate\") do |snd, chn, y0, y1| display_correlate(snd, chn, y0, y1) end") def display_correlate(snd, chn, y0, y1) if channels(snd) == 2 and framples(snd, 0) > 1 and framples(snd, 1) > 1 ls = left_sample(snd, 0) rs = right_sample(snd, 0) ilen = 1 + (rs - ls) pow2 = (log(ilen) / log(2)).ceil fftlen = (2 ** pow2).to_i fftlen2 = fftlen / 2 fftscale = 1.0 / fftlen rl1 = channel2vct(ls, fftlen, snd, 0) rl2 = channel2vct(ls, fftlen, snd, 1) im1 = make_vct(fftlen) im2 = make_vct(fftlen) fft(rl1, im1, 1) fft(rl2, im2, 1) tmprl = vct_copy(rl1) tmpim = vct_copy(im1) data3 = make_vct(fftlen2) vct_multiply!(tmprl, rl2) vct_multiply!(tmpim, im2) vct_multiply!(im2, rl1) vct_multiply!(rl2, im1) vct_add!(tmprl, tmpim) vct_subtract!(im2, rl2) fft(tmprl, im2, -1) vct_add!(data3, tmprl) vct_scale!(data3, fftscale) graph(data3, "lag time", 0, fftlen2) else snd_print("correlate wants stereo input") end end # set transform-size based on current time domain window size # # also zoom spectrum based on y-axis zoom slider add_help(:zoom_spectrum, "zoom_spectrum(snd, chn, y0, y1) \ Sets the transform size to correspond to the \ time-domain window size (use with $graph_hook): $graph_hook.add_hook!(\"zoom-spectrum\") do |snd, chn, y0, y1| zoom_spectrum(snd, chn, y0, y1) end") def zoom_spectrum(snd, chn, y0, y1) if transform_graph?(snd, chn) and transform_graph_type(snd, chn) == Graph_once set_transform_size((2 ** (log(right_sample(snd, chn) - left_sample(snd, chn))/log(2.0))).to_i, snd, chn) set_spectrum_end(y_zoom_slider(snd, chn), snd, chn) end false end add_help(:zoom_fft, "zoom_fft(snd, chn, y0, y1) \ Sets the transform size if the time domain is \ not displayed (use with $graph_hook). \ It also sets the spectrum display start point \ based on the x position slider---this can be confusing \ if fft normalization is on (the default): $graph_hook.add_hook!(\"zoom-fft\") do |snd, chn, y0, y1| zoom_fft(snd, chn, y0, y1) end") def zoom_fft(snd, chn, y0, y1) if transform_graph?(snd, chn) and (not time_graph?(snd, chn)) and transform_graph_type(snd, chn) == Graph_once set_transform_size(2 ** (log(right_sample(snd, chn) - left_sample(snd, chn)) / log(2.0)).ceil, snd, chn) set_spectrum_start(x_position_slider(snd, chn), snd, chn) set_spectrum_end(y_zoom_slider(snd, chn), snd, chn) end false end # superimpose spectra of sycn'd sounds add_help(:superimpose_ffts, "superimpose_ffts(snd, chn, y0, y1) \ Superimposes ffts of multiple (syncd) sounds (use with $graph_hook): $graph_hook.add_hook!(\"superimpose-ffts\") do |snd, chn, y0, y1| superimpose_ffts(snd, chn, y0, y1) end") def superimpose_ffts(snd, chn, y0, y1) maxsync = Snd.sounds.map do |s| sync(s) end.max if sync(snd) > 0 and snd == Snd.sounds.map do |s| sync(snd) == sync(s) ? sound2integer(s) : (maxsync + 1) end.min ls = left_sample(snd, chn) rs = right_sample(snd, chn) pow2 = (log(rs - ls) / log(2)).ceil fftlen = (2 ** pow2).to_i if pow2 > 2 ffts = [] Snd.sounds.each do |s| if sync(snd) == sync(s) and channels(s) > chn fdr = channel2vct(ls, fftlen, s, chn) fdi = make_vct(fftlen) spectr = make_vct(fftlen / 2) ffts.push(spectr.add(spectrum(fdr, fdi, false, 2))) end end graph(ffts, "spectra", 0.0, 0.5, y0, y1, snd, chn) end end false end # c-g? example (Anders Vinjar) add_help(:locate_zero, "locate_zero(limit) \ Looks for successive samples that sum to less than LIMIT, \ moving the cursor if successful.") def locate_zero(limit) start = cursor sf = make_sampler(start, false, false) val0 = sf.call.abs val1 = sf.call.abs n = start until sampler_at_end?(sf) or val0 + val1 < limit val0, val1 = val1, sf.call.abs n += 1 end free_sampler(sf) set_cursor(n) end # make a system call from irb or snd listener # # shell("df") for example # or to play a sound whenever a file is closed: # $close-hook.add_hook!() do |snd| shell("sndplay wood16.wav"); false end add_help(:shell, "shell(cmd, *rest) \ Sends CMD to a shell (executes it as a shell command) \ and returns the result string.") def shell(cmd, *rest) str = "" unless cmd.null? IO.popen(format(cmd, *rest), "r") do |f| str = f.readlines.join end end str end # translate mpeg input to 16-bit linear and read into Snd # # mpg123 with the -s switch sends the 16-bit (mono or stereo) representation # of an mpeg file to stdout. There's also apparently a switch to write # 'wave' output. add_help(:mpg, "mpg(file, tmpname) \ Converts file from MPEG to raw 16-bit samples using mpg123: \ mpg(\"mpeg.mpg\", \"mpeg.raw\")") def mpg(mpgfile, rawfile) b0 = b1 = b2 = b3 = 0 File.open(mpgfile, "r") do |fd| b0 = fd.readchar b1 = fd.readchar b2 = fd.readchar b3 = fd.readchar end if b0 != 255 or (b1 & 0b11100000) != 0b11100000 Snd.display("%s is not an MPEG file (first 11 bytes: %b %b", mpgfile.inspect, b0, b1 & 0b11100000) else id = (b1 & 0b11000) >> 3 layer = (b1 & 0b110) >> 1 srate_index = (b2 & 0b1100) >> 2 channel_mode = (b3 & 0b11000000) >> 6 if id == 1 Snd.display("odd: %s is using a reserved Version ID", mpgfile) end if layer == 0 Snd.display("odd: %s is using a reserved layer description", mpgfile) end chans = channel_mode == 3 ? 1 : 2 mpegnum = id.zero? ? 4 : (id == 2 ? 2 : 1) mpeg_layer = layer == 3 ? 1 : (layer == 2 ? 2 : 3) srate = [44100, 48000, 32000, 0][srate_index] / mpegnum Snd.display("%s: %s Hz, %s, MPEG-%s", mpgfile, srate, chans == 1 ? "mono": "stereo", mpeg_layer) system(format("mpg123 -s %s > %s", mpgfile, rawfile)) open_raw_sound(rawfile, chans, srate, little_endian? ? Mus_lshort : Mus_bshort) end end # read and write OGG files add_help(:read_ogg, "read_ogg(filename) \ Read OGG files: $open_hook.add_hook!(\"read-ogg\") do |filename| if mus_sound_header_type(filename) == Mus_raw read_ogg(filename) else false end end") def read_ogg(filename) flag = false File.open(filename, "r") do |fd| flag = fd.readchar == ?O and fd.readchar == ?g and fd.readchar == ?g and fd.readchar == ?S end if flag aufile = filename + ".au" File.unlink(aufile) if File.exist?(aufile) system(format("ogg123 -d au -f %s %s", aufile, filename)) aufile else false end end def write_ogg(snd) if edits(snd)[0] > 0 or header_type(snd) != Mus_riff file = file_name(snd) + ".tmp" save_sound_as(file, snd, :header_type, Mus_riff) system("oggenc " + file) File.unlink(file) else system("oggenc " + file_name(snd)) end end # read and write Speex files def read_speex(filename) wavfile = filename + ".wav" File.unlink(wavfile) if File.exist?(wavfile) system(format("speexdec %s %s", filename, wavfile)) wavfile end def write_speex(snd) if edits(snd)[0] > 0 or header_type(snd) != Mus_riff file = file_name(snd) + ".wav" spxfile = file_name(snd) + "spx" save_sound_as(file, snd, :header_type, Mus_riff) system(format("speexenc %s %s", file, spxfile)) File.unlink(file) else system(format("speexenc %s %s", file_name(snd), spxfile)) end end # read and write FLAC files def read_flac(filename) system(format("flac -d %s", filename)) end def write_flac(snd) if edits(snd)[0] > 0 or header_type(snd) != Mus_riff file = file_name(snd) + ".wav" save_sound_as(file, snd, :header_type, Mus_riff) system(format("flac %s", file)) File.unlink(file) else system(format("flac %s ", file_name(snd))) end end # read ASCII files # # these are used by Octave (WaveLab) -- each line has one integer, # apparently a signed short. def read_ascii(in_filename, out_filename = "test.snd", out_type = Mus_next, out_format = Mus_bshort, out_srate = 44100) in_buffer = IO.readlines(in_filename) # array of strings com = format("created by %s: %s", get_func_name, in_filename) out_snd = new_sound(out_filename, 1, out_srate, out_format, out_type, com) bufsize = 512 data = make_vct(bufsize) loc = 0 frame = 0 short2float = 1.0 / 32768.0 as_one_edit_rb do | | in_buffer.each do |line| line.split.each do |str_val| val = eval(str_val) data[loc] = val * short2float loc += 1 if loc == bufsize vct2channel(data, frame, bufsize, out_snd, 0) frame += bufsize loc = 0 end end end if loc > 0 vct2channel(data, frame, loc, out_snd, 0) end end out_snd end # make dot size dependent on number of samples being displayed # # this could be extended to set time_graph_style to Graph_lines if # many samples are displayed, etc add_help(:auto_dot, "auto_dot(snd, chn, y0, y1) \ Sets the dot size depending on the number \ of samples being displayed (use with $graph_hook): $graph_hook.add_hook!(\"auto-dot\") do |snd, chn, y0, y1| auto_dot(snd, chn, y0, y1) end") def auto_dot(snd, chn, y0, y1) dots = right_sample(snd, chn) - left_sample(snd, chn) case dots when 100 set_dot_size(1, snd, chn) when 50 set_dot_size(2, snd, chn) when 25 set_dot_size(3, snd, chn) else set_dot_size(5, snd, chn) end false end # move window left edge to mark upon 'm' # # in large sounds, it can be pain to get the left edge of the window # aligned with a specific spot in the sound. In this code, we # assume the desired left edge has a mark, and the 'm' key (without # control) will move the window left edge to that mark. add_help(:first_mark_in_window_at_left, "first_mark_in_window_at_left() \ Moves the graph so that the leftmost visible mark is at the left edge: bind_key(?m, 0, lambda do | | first_mark_in_window_at_left end)") def first_mark_in_window_at_left keysnd = Snd.snd keychn = Snd.chn current_left_sample = left_sample(keysnd, keychn) chan_marks = marks(keysnd, keychn) if chan_marks.null? snd_print("no marks!") else leftmost = chan_marks.map do |m| mark_sample(m) end.detect do |m| m > current_left_sample end if leftmost.null? snd_print("no mark in window") else set_left_sample(leftmost, keysnd, keychn) Keyboard_no_action end end end # flash selected data red and green add_help(:flash_selected_data, "flash_selected_data(millisecs) \ Causes the selected data to flash red and green.") def flash_selected_data(interval) if selected_sound set_selected_data_color(selected_data_color == Red ? Green : Red) call_in(interval, lambda do | | flash_selected_data(interval) end) end end # use loop info (if any) to set marks at loop points add_help(:mark_loops, "mark_loops() \ Places marks at loop points found in the selected sound's header.") def mark_loops loops = (sound_loop_info or mus_sound_loop_info(file_name)) if loops and !loops.empty? unless loops[0].zero? and loops[1].zero? add_mark(loops[0]) add_mark(loops[1]) unless loops[2].zero? and loops[3].zero? add_mark(loops[2]) add_mark(loops[3]) end end else Snd.display("%s has no loop info", short_file_name.inspect) end end # mapping extensions (map arbitrary single-channel function over # various channel collections) add_help(:do_all_chans, "do_all_chans(edhist) do |y| ... end \ Applies func to all active channels, \ using EDHIST as the edit history indication: \ do_all_chans(\"double all samples\", do |val| 2.0 * val end)") def do_all_chans(origin, &func) Snd.sounds.each do |snd| channels(snd).times do |chn| map_channel(func, 0, false, snd, chn, false, origin) end end end add_help(:update_graphs, "update_graphs() \ Updates (redraws) all graphs.") def update_graphs Snd.sounds.each do |snd| channels(snd).times do |chn| update_time_graph(snd, chn) end end end add_help(:do_chans, "do_chans(edhist) do |y| ... end \ Applies func to all sync'd channels using EDHIST \ as the edit history indication.") def do_chans(*origin, &func) snc = sync if snc > 0 Snd.sounds.each do |snd| channels(snd).times do |chn| if sync(snd) == snc map_channel(func, 0, false, snd, chn, false, (origin.empty? ? "" : format(*origin))) end end end else snd_warning("sync not set") end end add_help(:do_sound_chans, "do_sound_chans(edhist) do |y| ... end \ Applies func to all selected channels using EDHIST \ as the edit history indication.") def do_sound_chans(*origin, &func) if snd = selected_sound channels(snd).times do |chn| map_channel(func, 0, false, snd, chn, false, (origin.empty? ? "" : format(*origin))) end else snd_warning("no selected sound") end end add_help(:every_sample?, "every_sample? do |y| ... end \ Returns true if func is not false for all samples in the current channel, \ otherwise it moves the cursor to the first offending sample.") def every_sample?(&func) snd = Snd.snd chn = Snd.chn if baddy = scan_channel(lambda do |y| (not func.call(y)) end, 0, framples(snd, chn), snd, chn) set_cursor(baddy[1]) end (not baddy) end add_help(:sort_samples, "sort_samples(bins) \ Provides a histogram in BINS bins.") def sort_samples(nbins) bins = make_array(nbins, 0) scan_channel(lambda do |y| bin = (y.abs * nbins).floor bins[bin] += 1 false end) bins end # mix mono sound into stereo sound panning according to env add_help(:place_sound, "place_sound(mono_snd, stereo_snd, pan_env) \ Mixes a mono sound into a stereo sound, splitting it into two copies \ whose amplitudes depend on the envelope PAN_ENV. \ If PAN_ENV is a number, \ the sound is split such that 0 is all in channel 0 \ and 90 is all in channel 1.") def place_sound(mono_snd, stereo_snd, pan_env) len = framples(mono_snd) if number?(pan_env) pos = pan_env / 90.0 rd0 = make_sampler(0, mono_snd, false) rd1 = make_sampler(0, mono_snd, false) map_channel(lambda do |y| y + pos * read_sample(rd1) end, 0, len, stereo_snd, 1) map_channel(lambda do |y| y + (1.0 - pos) * read_sample(rd0) end, 0, len, stereo_snd, 0) else e0 = make_env(:envelope, pan_env, :length, len) e1 = make_env(:envelope, pan_env, :length, len) rd0 = make_sampler(0, mono_snd, false) rd1 = make_sampler(0, mono_snd, false) map_channel(lambda do |y| y + env(e1) * read_sample(rd1) end, 0, len, stereo_snd, 1) map_channel(lambda do |y| y + (1.0 - env(e0)) * read_sample(rd0) end, 0, len, stereo_snd, 0) end end # FFT-based editing add_help(:fft_edit, "fft_edit(low_Hz, high_Hz) \ Ffts an entire sound, removes all energy below low-Hz and all above high-Hz, \ then inverse ffts.") def fft_edit(bottom, top, snd = false, chn = false) sr = srate(snd).to_f len = framples(snd, chn) fsize = (2.0 ** (log(len) / log(2.0)).ceil).to_i rdata = channel2vct(0, fsize, snd, chn) idata = make_vct(fsize) lo = (bottom / (sr / fsize)).round hi = (top / (sr / fsize)).round fft(rdata, idata, 1) j = fsize - 1 lo.times do |i| rdata[i] = rdata[j] = 0.0 rdata[i] = rdata[j] = 0.0 j -= 1 end j = fsize - hi (hi..(fsize / 2)).each do |i| rdata[i] = rdata[j] = 0.0 rdata[i] = rdata[j] = 0.0 j -= 1 end fft(rdata, idata, -1) vct_scale!(rdata, 1.0 / fsize) vct2channel(rdata, 0, len - 1, snd, chn, false, format("%s(%s, %s", get_func_name, bottom, top)) end add_help(:fft_squelch, "fft_squelch(squelch, snd=false, chn=false) \ Ffts an entire sound, sets all bins to 0.0 whose energy is below squelch, \ then inverse ffts.") def fft_squelch(squelch, snd = false, chn = false) len = framples(snd, chn) fsize = (2.0 ** (log(len) / log(2.0)).ceil).to_i rdata = channel2vct(0, fsize, snd, chn) idata = make_vct(fsize) fsize2 = fsize / 2 fft(rdata, idata, 1) vr = vct_copy(rdata) vi = vct_copy(idata) rectangular2polar(vr, vi) scaler = vct_peak(vr) scl_squelch = squelch * scaler j = fsize - 1 fsize2.times do |i| if sqrt(rdata[i] * rdata[i] + idata[i] * idata[i]) < scl_squelch rdata[i] = rdata[j] = 0.0 rdata[i] = rdata[j] = 0.0 end j -= 1 end fft(rdata, idata, -1) vct_scale!(rdata, 1.0 / fsize) vct2channel(rdata, 0, len - 1, snd, chn, false, format("%s(%s", get_func_name, squelch)) scaler end add_help(:fft_cancel, "fft_cancel(lo_freq, hi_freq, snd=false, chn=false) \ Ffts an entire sound, sets the bin(s) representing lo_freq to hi_freq to 0.0, \ then inverse ffts.") def fft_cancel(lo_freq, hi_freq, snd = false, chn = false) sr = srate(snd).to_f len = framples(snd, chn) fsize = (2.0 ** (log(len) / log(2.0)).ceil).to_i rdata = channel2vct(0, fsize, snd, chn) idata = make_vct(fsize) fsize2 = fsize / 2 fft(rdata, idata, 1) hz_bin = sr / fsize lo_bin = (lo_freq / hz_bin).round hi_bin = (hi_freq / hz_bin).round j = fsize - lo_bin - 1 fsize2.times do |i| if i > hi_bin rdata[i] = rdata[j] = 0.0 rdata[i] = rdata[j] = 0.0 end j -= 1 end fft(rdata, idata, -1) vct_scale!(rdata, 1.0 / fsize) vct2channel(rdata, 0, len - 1, snd, chn, false, format("%s(%s, %s", get_func_name, lo_freq, hi_freq)) end # same idea but used to distinguish vowels (steady-state) from consonants class Ramp < Musgen def initialize(size = 128) super() @val = 0.0 @size = size @incr = 1.0 / size @up = true end def inspect format("%s.new(%d)", self.class, @size) end def to_s format("#<%s size: %d, val: %1.3f, incr: %1.3f, up: %s>", self.class, @size, @val, @incr, @up) end def run_func(up = true, dummy = false) @up = up @val += (@up ? @incr : -@incr) @val = [1.0, [0.0, @val].max].min end def run(up = true) self.run_func(up, false) end end add_help(:make_ramp, "make_ramp(size=128) \ Returns a ramp generator.") def make_ramp(size = 128) Ramp.new(size) end add_help(:ramp, "ramp(gen, up) \ Is a kind of CLM generator that produces a ramp of a given length, \ then sticks at 0.0 or 1.0 until the UP argument changes.") def ramp(gen, up) gen.run_func(up, false) end add_help(:squelch_vowels, "squelch_vowels(snd=false, chn=false) \ Suppresses portions of a sound that look like steady-state.") def squelch_vowels(snd = false, chn = false) fft_size = 32 fft_mid = (fft_size / 2.0).floor ramper = Ramp.new(256) peak = maxamp(snd, chn) / fft_mid read_ahead = make_sampler(0, snd, chn) rl = Vct.new(fft_size) do read_sample(read_ahead) end im = Vct.new(fft_size, 0.0) ctr = fft_size - 1 in_vowel = false map_channel(lambda do |y| ctr += 1 if ctr == fft_size ctr = 0 fft(rl, im, 1) rl.multiply!(rl) im.multiply!(im) rl.add!(im) im.fill(0.0) in_vowel = (rl[0] + rl[1] + rl[2] + rl[3]) > peak rl.map! do read_sample(read_ahead) end end y * (1.0 - ramper.run(in_vowel)) end, 0, false, snd, chn, false, "squelch_vowels(") end add_help(:fft_env_data, "fft_env_data(fft-env, snd=false, chn=false) \ Applies fft_env as spectral env to current sound, returning vct of new data.") def fft_env_data(fft_env, snd = false, chn = false) len = framples(snd, chn) fsize = (2 ** (log(len) / log(2.0)).ceil).to_i rdata = channel2vct(0, fsize, snd, chn) idata = make_vct(fsize) fsize2 = fsize / 2 en = make_env(:envelope, fft_env, :length, fsize2) fft(rdata, idata, 1) j = fsize - 1 fsize2.times do |i| val = env(en) rdata[i] *= val idata[i] *= val rdata[j] *= val idata[j] *= val j -= 1 end fft(rdata, idata, -1) vct_scale!(rdata, 1.0 / fsize) end add_help(:fft_env_edit, "fft_env_edit(fft-env, snd=false, chn=false) \ Edits (filters) current chan using fft_env.") def fft_env_edit(fft_env, snd = false, chn = false) vct2channel(fft_env_data(fft_env, snd, chn), 0, framples(snd, chn) - 1, snd, chn, false, format("%s(%s", get_func_name, fft_env.inspect)) end add_help(:fft_env_interp, "fft_env_interp(env1, env2, interp, snd=false, chn=false) \ Interpolates between two fft-filtered \ versions (env1 and env2 are the spectral envelopes) \ following interp (an env between 0 and 1).") def fft_env_interp(env1, env2, interp, snd = false, chn = false) data1 = fft_env_data(env1, snd, chn) data2 = fft_env_data(env2, snd, chn) len = framples(snd, chn) en = make_env(:envelope, interp, :length, len) new_data = make_vct!(len) do |i| pan = env(en) (1.0 - pan) * data1[i] + pan * data2[i] end vct2channel(new_data, 0, len - 1, snd, chn, false, format("%s(%s, %s, %s", get_func_name, env1.inspect, env2.inspect, interp.inspect)) end add_help(:fft_smoother, "fft_smoother(cutoff, start, samps, snd=false, chn=false) \ Uses fft-filtering to smooth a section: \ vct2channel(fft_smoother(0.1, cursor, 400, 0, 0), cursor, 400)") def fft_smoother(cutoff, start, samps, snd = false, chn = false) fftpts = (2 ** (log(samps + 1) / log(2.0)).ceil).to_i rl = channel2vct(start, samps, snd, chn) im = make_vct(fftpts) top = (fftpts * cutoff.to_f).floor old0 = rl[0] old1 = rl[samps - 1] oldmax = vct_peak(rl) fft(rl, im, 1) (top...fftpts).each do |i| rl[i] = im[i] = 0.0 end fft(rl, im, -1) vct_scale!(rl, 1.0 / fftpts) newmax = vct_peak(rl) if newmax.zero? rl else if (scl = oldmax / newmax) > 1.5 vct_scale!(rl, scl) end new0 = rl[0] new1 = rl[samps - 1] offset0 = old0 - new0 offset1 = old1 - new1 incr = offset0 == offset1 ? 0.0 : ((offset1 - offset0) / samps) trend = offset0 - incr rl.map do |val| trend += incr val += trend end end end # comb-filter add_help(:comb_filter, "comb_filter(scaler, size) \ Returns a comb-filter ready for map_channel etc: \ map_channel(comb_filter(0.8, 32)) \ If you're in a hurry use: clm_channel(make_comb(0.8, 32)) instead.") def comb_filter(scaler, size) cmb = make_comb(scaler, size) lambda do |inval| comb(cmb, inval) end end # by using filters at harmonically related sizes, we can get chords: add_help(:comb_chord, "comb_chord(scl, size, amp, interval_one=0.75, interval_two=1.2) \ Returns a set of harmonically-related comb filters: \ map_channel(comb_chord(0.95, 100, 0.3))") def comb_chord(scaler, size, amp, interval_one = 0.75, interval_two = 1.2) c1 = make_comb(scaler, size.to_i) c2 = make_comb(scaler, (interval_one * size).to_i) c3 = make_comb(scaler, (interval_two * size).to_i) lambda do |inval| amp * (comb(c1, inval) + comb(c2, inval) + comb(c3, inval)) end end # or change the comb length via an envelope: add_help(:zcomb, "zcomb(scaler, size, pm) \ Returns a comb filter whose length varies according to an envelope: \ map_channel(zcomb(0.8, 32, [0, 0, 1, 10]))") def zcomb(scaler, size, pm) max_envelope_1 = lambda do |en, mx| 1.step(en.length - 1, 2) do |i| mx = [mx, en[i]].max.to_f end mx end cmb = make_comb(scaler, size, :max_size, (max_envelope_1.call(pm, 0.0) + size + 1).to_i) penv = make_env(:envelope, pm, :length, framples()) lambda do |inval| comb(cmb, inval, env(penv)) end end add_help(:notch_filter, "notch_filter(scaler, size) \ Returns a notch-filter: map_channel(notch_filter(0.8, 32))") def notch_filter(scaler, size) gen = make_notch(scaler, size) lambda do |inval| notch(gen, inval) end end add_help(:formant_filter, "formant_filter(radius, frequency) \ Returns a formant generator: map_channel(formant_filter(0.99, 2400)) \ Faster is: filter_sound(make_formant(2400, 0.99))") def formant_filter(radius, freq) frm = make_formant(radius, freq) lambda do |inval| formant(frm, inval) end end # to impose several formants, just add them in parallel: add_help(:formants, "formants(r1, f1, r2, f2, r3, f3) \ Returns 3 formant filters in parallel: \ map_channel(formants(0.99, 900, 0.98, 1800, 0.99 2700))") def formants(r1, f1, r2, f2, r3, f3) fr1 = make_formant(f1, r1) fr2 = make_formant(f2, r2) fr3 = make_formant(f3, r3) lambda do |inval| formant(fr1, inval) + formant(fr2, inval) + formant(fr3, inval) end end add_help(:moving_formant, "moving_formant(radius, move) \ Returns a time-varying (in frequency) formant filter: \ map_channel(moving_formant(0.99, [0, 1200, 1, 2400]))") def moving_formant(radius, move) frm = make_formant(move[1], radius) menv = make_env(:envelope, move, :length, framples()) lambda do |inval| val = formant(frm, inval) frm.frequency = env(menv) val end end add_help(:osc_formants, "osc_formants(radius, bases, amounts, freqs) \ Set up any number of independently oscillating formants, \ then calls map_channel: \ osc_formants(0.99, vct(400, 800, 1200), vct(400, 800, 1200), vct(4, 2, 3))") def osc_formants(radius, bases, amounts, freqs) len = bases.length frms = make_array(len) do |i| make_formant(bases[i], radius) end oscs = make_array(len) do |i| make_oscil(freqs[i]) end map_channel_rb() do |x| val = 0.0 frms.each_with_index do |frm, i| val += formant(frm, x) set_mus_frequency(frm, bases[i] + amounts[i] * oscil(oscs[i])) end val end end # echo add_help(:echo, "echo(scaler, secs) \ Returns an echo maker: map_channel(echo(0.5, 0.5), 0 44100)") def echo(scaler, secs) del = make_delay((secs * srate()).round) lambda do |inval| inval + delay(del, scaler * (tap(del) + inval)) end end add_help(:zecho, "zecho(scaler, secs, freq, amp) \ Returns a modulated echo maker: \ map_channel(zecho(0.5, 0.75, 6, 10.0), 0, 65000)") def zecho(scaler, secs, freq, amp) os = make_oscil(freq) len = (secs * srate()).round del = make_delay(len, :max_size, (len + amp + 1).to_i) lambda do |inval| inval + delay(del, scaler * (tap(del) + inval), amp * oscil(os)) end end add_help(:flecho, "flecho(scaler, secs) \ Returns a low-pass filtered echo maker: \ map_channel(flecho(0.5, 0.9), 0, 75000)" ) def flecho(scaler, secs) flt = make_fir_filter(:order, 4, :xcoeffs, vct(0.125, 0.25, 0.25, 0.125)) del = make_delay((secs * srate()).round) lambda do |inval| inval + delay(del, fir_filter(flt, scaler * (tap(del) + inval))) end end # ring-mod and am # # CLM instrument is ring-modulate.ins add_help(:ring_mod, "ring_mod(freq, gliss_env) \ Returns a time-varying ring-modulation filter: \ map_channel(ring_mod(10, [0, 0, 1, hz2radians(100)]))") def ring_mod(freq, gliss_env) os = make_oscil(:frequency, freq) len = framples() genv = make_env(:envelope, gliss_env, :length, len) lambda do |inval| oscil(os, env(genv)) * inval end end add_help(:am, "am(freq) \ returns an amplitude-modulator: map_channel(am(440))") def am(freq) os = make_oscil(freq) lambda do |inval| amplitude_modulate(1.0, inval, oscil(os)) end end def vibro(speed, depth) sine = make_oscil(speed) scl = 0.5 * depth offset = 1.0 - scl lambda do |inval| inval * (offset + scl * oscil(sine)) end end # hello-dentist # # CLM instrument version is in clm.html add_help(:hello_dentist, "hello_dentist(frq, amp, snd=false, chn=false) \ Varies the sampling rate randomly, \ making a voice sound quavery: hello_dentist(40.0, 0.1)") def hello_dentist(freq, amp, snd = false, chn = false) rn = make_rand_interp(:frequency, freq, :amplitude, amp) i = 0 len = framples() in_data = channel2vct(0, len, snd, chn) out_len = (len * (1.0 + 2.0 * amp)).to_i out_data = make_vct(out_len) rd = make_src(:srate, 1.0, :input, lambda do |dir| val = i.between?(0, len - 1) ? in_data[i] : 0.0 i += dir val end) vct2channel(out_data.map do |x| src(rd, rand_interp(rn)) end, 0, len, snd, chn, false, format("%s(%s, %s", get_func_name, freq, amp)) end # a very similar function uses oscil instead of rand-interp, giving # various "Forbidden Planet" sound effects: add_help(:fp, "fp(sr, osamp, osfrq, snd=false, chn=false) \ Varies the sampling rate via an oscil: fp(1.0, 0.3, 20)") def fp(sr, osamp, osfreq, snd = false, chn = false) os = make_oscil(:frequency, osfreq) s = make_src(:srate, sr) len = framples(snd, chn) sf = make_sampler(0, snd, chn) out_data = make_vct!(len) do src(s, osamp * oscil(os), lambda do |dir| dir > 0 ? next_sample(sf) : previous_sample(sf) end) end free_sampler(sf) vct2channel(out_data, 0, len, snd, chn, false, format("%s(%s, %s, %s", get_func_name, sr, osamp, osfreq)) end # compand Compand_table = vct(-1.0, -0.96, -0.9, -0.82, -0.72, -0.6, -0.45, -0.25, 0.0, 0.25, 0.45, 0.6, 0.72, 0.82, 0.9, 0.96, 1.0) add_help(:compand, "compand() \ Returns a compander: map_channel(compand())") def compand() lambda do |inval| array_interp(Compand_table, 8.0 + 8.0 * inval, Compand_table.length) end end # shift pitch keeping duration constant # # both src and granulate take a function argument to get input # whenever it is needed. in this case, src calls granulate which # reads the currently selected file. CLM version is in expsrc.ins add_help(:expsrc, "expsrc(rate, snd=false, chn=false) \ Uses sampling-rate conversion and granular synthesis to produce a sound \ at a new pitch but at the original tempo. \ It returns a function for map_chan.") def expsrc(rate, snd = false, chn = false) gr = make_granulate(:expansion, rate) sr = make_src(:srate, rate) vsize = 1024 vbeg = 0 v = channel2vct(0, vsize) inctr = 0 lambda do |inval| src(sr, 0.0, lambda do |dir| granulate(gr, lambda do |dr| val = v[inctr] inctr += dr if inctr >= vsize vbeg += inctr inctr = 0 v = channel2vct(vbeg, vsize, snd, chn) end val end) end) end end # the next (expsnd) changes the tempo according to an envelope; the # new duration will depend on the expansion envelope -- we integrate # it to get the overall expansion, then use that to decide the new # length. add_help(:expsnd, "expsnd(gr_env, snd=false, chn=false) \ Uses the granulate generator to change tempo \ according to an envelope: expsnd([0, 0.5, 2, 2.0])") def expsnd(gr_env, snd = false, chn = false) dur = ((framples(snd, chn) / srate(snd)) * integrate_envelope(gr_env) / envelope_last_x(gr_env)) gr = make_granulate(:expansion, gr_env[1], :jitter, 0) ge = make_env(:envelope, gr_env, :duration, dur) sound_len = (srate(snd) * dur).to_i len = [sound_len, framples(snd, chn)].max sf = make_sampler(0, snd, chn) out_data = make_vct!(len) do val = granulate(gr, lambda do |dir| next_sample(sf) end) gr.increment = env(ge) val end free_sampler(sf) vct2channel(out_data, 0, len, snd, chn, false, format("%s(%s", get_func_name, gr_env.inspect)) end # cross-synthesis # # CLM version is in clm.html add_help(:cross_synthesis, "cross_synthesis(cross_snd, amp, fftsize, r) \ Does cross-synthesis between CROSS_SND (a sound index) \ and the currently selected sound: \ map_channel(cross_synthesis(1, 0.5, 128, 6.0))") def cross_synthesis(cross_snd, amp, fftsize, r) freq_inc = fftsize / 2 fdr = make_vct(fftsize) fdi = make_vct(fftsize) spectr = make_vct(freq_inc) inctr = 0 ctr = freq_inc radius = 1.0 - r / fftsize.to_f bin = srate() / fftsize.to_f fmts = make_array(freq_inc) do |i| make_formant(i * bin, radius) end formants = make_formant_bank(fmts, spectr) lambda do |inval| if ctr == freq_inc fdr = channel2vct(inctr, fftsize, cross_snd, 0) inctr += freq_inc spectrum(fdr, fdi, false, 2) vct_subtract!(fdr, spectr) vct_scale!(fdr, 1.0 / freq_inc) ctr = 0 end ctr += 1 vct_add!(spectr, fdr) amp * formant_bank(formants, inval) end end # similar ideas can be used for spectral cross-fades, etc -- for example: add_help(:voiced2unvoiced, "voiced2unvoiced(amp, fftsize, r, tempo, snd=false, chn=false) \ Turns a vocal sound into whispering: voiced2unvoiced(1.0, 256, 2.0, 2.0)") def voiced2unvoiced(amp, fftsize, r, tempo, snd = false, chn = false) freq_inc = fftsize / 2 fdr = make_vct(fftsize) fdi = make_vct(fftsize) spectr = make_vct(freq_inc) noi = make_rand(:frequency, srate(snd) / 3.0) inctr = 0 ctr = freq_inc radius = 1.0 - r.to_f / fftsize bin = srate(snd).to_f / fftsize len = framples(snd, chn) outlen = (len / tempo).floor hop = (freq_inc * tempo).floor out_data = make_vct([len, outlen].max) fmts = make_array(freq_inc) do |i| make_formant(i * bin, radius) end formants = make_formant_bank(fmts, spectr) old_peak_amp = new_peak_amp = 0.0 outlen.times do |i| if ctr == freq_inc fdr = channel2vct(inctr, fftsize, snd, chn) if (pk = vct_peak(fdr)) > old_peak_amp old_peak_amp = pk end spectrum(fdr, fdi, false, 2) inctr += hop vct_subtract!(fdr, spectr) vct_scale!(fdr, 1.0 / freq_inc) ctr = 0 end ctr += 1 vct_add!(spectr, fdr) if (outval = formant_bank(formants, rand(noi))).abs > new_peak_amp new_peak_amp = outval.abs end out_data[i] = outval end vct_scale!(out_data, amp * (old_peak_amp / new_peak_amp)) vct2channel(out_data, 0, [len, outlen].max, snd, chn, false, format("%s(%s, %s, %s, %s", get_func_name, amp, fftsize, r, tempo)) end # very similar but use sum-of-cosines (glottal pulse train?) # instead of white noise add_help(:pulse_voice, "pulse_voice(cosin, freq=440.0, amp=1.0, fftsize=256, r=2.0, \ snd=false, chn=false) \ Uses sum-of-cosines to manipulate speech sounds.") def pulse_voice(cosin, freq = 440.0, amp = 1.0, fftsize = 256, r = 2.0, snd = false, chn = false) freq_inc = fftsize / 2 fdr = make_vct(fftsize) fdi = make_vct(fftsize) spectr = make_vct(freq_inc) pulse = make_sum_of_cosines(cosin, freq) inctr = 0 ctr = freq_inc radius = 1.0 - r / fftsize bin = srate(snd) / fftsize len = framples(snd, chn) out_data = make_vct(len) old_peak_amp = new_peak_amp = 0.0 fmts = make_array(freq_inc) do |i| make_formant(i * bin, radius) end formants = make_formant_bank(fmts, spectr) out_data.map do |i| outval = 0.0 if ctr == freq_inc fdr = channel2vct(inctr, fftsize, snd, chn) pk = vct_peak(fdr) if pk > old_peak_amp then old_peak_amp = pk end spectrum(fdr, fdi, false, 2) inctr += freq_inc vct_subtract!(fdr, spectr) vct_scale!(fdr, 1.0 / freq_inc) ctr = 0 end ctr += 1 vct_add!(spectr, fdr) outval = formant_bank(formants, sum_of_cosines(pulse)) if outval.abs > new_peak_amp then new_peak_amp = outval.abs end outval end vct_scale!(out_data, amp * (old_peak_amp / new_peak_amp)) vct2channel(out_data, 0, len, snd, chn) end # pulse_voice(80, 20.0, 1.0, 1024, 0.01) # pulse_voice(80, 120.0, 1.0, 1024, 0.2) # pulse_voice(30, 240.0, 1.0, 1024, 0.1) # pulse_voice(30, 240.0, 1.0, 2048) # pulse_voice( 6, 1000.0, 1.0, 512) # convolution example add_help(:cnvtest, "cnvtest(snd0, snd1, amp) \ Convolves snd0 and snd1, scaling by amp, \ returns new max amp: cnvtest(0, 1, 0.1)") def cnvtest(snd0, snd1, amp) flt_len = framples(snd0) total_len = flt_len + framples(snd1) cnv = make_convolve(:filter, channel2vct(0, flt_len, snd0)) sf = make_sampler(0, snd1, false) out_data = make_vct!(total_len) do convolve(cnv, lambda do |dir| next_sample(sf) end) end free_sampler(sf) vct_scale!(out_data, amp) max_samp = vct_peak(out_data) vct2channel(out_data, 0, total_len, snd1) if max_samp > 1.0 set_y_bounds(snd1, [-max_samp, max_samp]) end max_samp end # swap selection chans add_help(:swap_selection_channels, "swap_selection_channels() \ Swaps the currently selected data's channels.") def swap_selection_channels if (not selection?) Snd.raise(:no_active_selection) end if selection_chans != 2 Snd.raise(:wrong_number_of_channels, "need a stereo selection") end beg = selection_position() len = selection_framples() snd_chn0 = snd_chn1 = nil Snd.sounds.each do |snd| channels(snd).times do |chn| if selection_member?(snd, chn) if snd_chn0.nil? snd_chn0 = [snd, chn] elsif snd_chn1.nil? snd_chn1 = [snd, chn] break end end end end if snd_chn1.nil? Snd.raise(:wrong_number_of_channels, "need two channels to swap") end swap_channels(snd_chn0[0], snd_chn0[1], snd_chn1[0], snd_chn1[1], beg, len) end # sound interp # # make-sound-interp sets up a sound reader that reads a channel at # an arbitary location, interpolating between samples if necessary, # the corresponding "generator" is sound-interp add_help(:make_sound_interp, "make_sound_interp(start, snd=false, chn=false) \ An interpolating reader for SND's channel CHN.") def make_sound_interp(start, snd = false, chn = false) data = channel2vct(0, false, snd, chn) size = data.length lambda do |loc| array_interp(data, loc, size) end end add_help(:sound_interp, "sound_interp(func, loc) \ Sample at LOC (interpolated if necessary) from FUNC \ created by make_sound_interp.") def sound_interp(func, loc) func.call(loc) end def sound_via_sound(snd1, snd2) intrp = make_sound_interp(0, snd1, 0) len = framples(snd1, 0) - 1 rd = make_sampler(0, snd2, 0) mx = maxamp(snd2, 0) map_channel(lambda do |val| sound_interp(intrp, (len * 0.5 * (1.0 + (read_sample(rd) / mx))).floor) end) end # env_sound_interp takes an envelope that goes between 0 and 1 # (y-axis), and a time-scaler (1.0 = original length) and returns a # new version of the data in the specified channel that follows that # envelope (that is, when the envelope is 0 we get sample 0, when # the envelope is 1 we get the last sample, envelope = 0.5 we get # the middle sample of the sound and so on. env_sound_interp([0, 0, # 1, 1]) will return a copy of the current sound; # env_sound_interp([0, 0, 1, 1, 2, 0], 2.0) will return a new sound # with the sound copied first in normal order, then reversed. # src_sound with an envelope could be used for this effect, but it # is much more direct to apply the envelope to sound sample # positions. add_help(:env_sound_interp, "env_sound_interp(env, time_scale=1.0, snd=false, chn=false) \ Reads SND's channel CHN according to ENV and TIME_SCALE.") def env_sound_interp(envelope, time_scale = 1.0, snd = false, chn = false) len = framples(snd, chn) newlen = (time_scale.to_f * len).floor read_env = make_env(:envelope, envelope, :length, newlen + 1, :scaler, len) data = channel2vct(0, false, snd, chn) new_snd = Vct.new(newlen) do array_interp(data, env(read_env), len) end set_samples(0, newlen, new_snd, snd, chn, true, format("%s(%p, %s", get_func_name, envelope, time_scale), 0, Current_edit_position, true) end # env_sound_interp([0, 0, 1, 1, 2, 0], 2.0) add_help(:granulated_sound_interp, "granulated_sound_interp(env, time_scale=1.0, grain_len=0.1, \ grain_env=[0, 0, 1, 1, 2, 1, 3, 0], out_hop=0.05, snd=false, chn=false) \ Reads the given channel following ENV (as in env_sound_interp), \ using grains to create the re-tempo'd read.") def granulated_sound_interp(envelope, time_scale = 1.0, grain_length = 0.1, grain_envelope = [0, 0, 1, 1, 2, 1, 3, 0], output_hop = 0.05, snd = false, chn = false) len = framples(snd, chn) newlen = (time_scale.to_f * len).floor read_env = make_env(envelope, :length, newlen, :scaler, len) sr = srate(snd).to_f grain_frames = (grain_length * sr).to_i hop_frames = (output_hop * sr).to_i num_readers = (grain_length.to_f / output_hop).ceil cur_readers = 0 next_reader = 0 jitter = sr * 0.005 readers = Array.new(num_readers, false) grain_envs = Array.new(num_readers) do make_env(grain_envelope, :length, grain_frames) end new_snd = Vct.new(newlen, 0.0) 0.step(newlen, hop_frames) do |i| stop = [newlen, hop_frames + i].min read_env.location = i position_in_original = env(read_env) mx = [0, (position_in_original + mus_random(jitter)).round].max readers[next_reader] = make_sampler(mx, snd, chn) grain_envs[next_reader].reset next_reader += 1 next_reader %= num_readers if cur_readers < next_reader cur_readers = next_reader end (0...cur_readers).each do |j| en = grain_envs[j] rd = readers[j] (i...stop).each do |k| new_snd[k] = env(en) * rd.call() end end end set_samples(0, newlen, new_snd, snd, chn, true, format("%s(%p, %s, %s, %p, %s", get_func_name, envelope, time_scale, grain_length, grain_envelope, output_hop), 0, Current_edit_position, true) end # granulated_sound_interp([0, 0, 1, 0.1, 2, 1], 1.0, 0.2, [0, 0, 1, 1, 2, 0]) # granulated_sound_interp([0, 0, 1, 1], 2.0) # granulated_sound_interp([0, 0, 1, 0.1, 2, 1], 1.0, 0.2, [0, 0, 1, 1, 2, 0], # 0.02) # filtered-env add_help(:filtered_env, "filtered_env(env, snd=false, chn=false) \ Is a time-varying one-pole filter: when ENV is at 1.0, no filtering, \ as ENV moves to 0.0, low-pass gets more intense; \ amplitude and low-pass amount move together.") def filtered_env(en, snd = false, chn = false) flt = make_one_pole(1.0, 0.0) amp_env = make_env(:envelope, en, :length, framples()) map_channel(lambda do |val| env_val = env(amp_env) set_mus_xcoeff(flt, 0, env_val) set_mus_ycoeff(flt, 1, env_val - 1.0) one_pole(flt, env_val * val) end, 0, false, snd, chn, false, format("%s(%s", get_func_name, en.inspect)) end # lisp graph with draggable x axis class Mouse def initialize @down = 0 @pos = 0.0 @x1 = 1.0 end def press(snd, chn, button, state, x, y) @pos = x / @x1 @down = @x1 end def drag(snd, chn, button, state, x, y) xnew = x / @x1 @x1 = [1.0, [0.1, @down + (@pos - xnew)].max].min graph(make_vct!((100 * @x1).floor) do |i| i * 0.01 end, "ramp", 0.0, @x1) end end =begin let(Mouse.new) do |mouse| $mouse_drag_hook.add_hook!("Mouse") do |snd, chn, button, state, x, y| mouse.drag(snd, chn, button, state, x, y) end $mouse_press_hook.add_hook!("Mouse") do |snd, chn, button, state, x, y| mouse.press(snd, chn, button, state, x, y) end end =end # pointer focus within Snd # # $mouse_enter_graph_hook.add_hook!("focus") do |snd, chn| # focus_widget(channel_widgets(snd, chn)[0]) # end # $mouse_enter_listener_hook.add_hook!("focus") do |widget| # focus_widget(widget) # end # $mouse_enter_text_hook.add_hook!("focus") do |widget| # focus_widget(widget) # end # View: Files dialog chooses which sound is displayed # # by Anders Vinjar add_help(:files_popup_buffer, "files_popup_buffer(type, position, name) \ Hides all sounds but the one the mouse touched in the current files list. \ Use with $mouse_enter_label_hook. $mouse_enter_label_hook.add_hook!(\"files-popup\") do |type, position, name| files_popup_buffer(type, position, name) end") def files_popup_buffer(type, position, name) if snd = find_sound(name) curr_buffer = Snd.snd vals = widget_size(sound_widgets(curr_buffer)[0]) height = vals[1] Snd.sounds.each do |s| hide_widget(sound_widgets(s)[0]) end show_widget(sound_widgets(snd)[0]) set_widget_size(sound_widgets(snd)[0], [widht, height]) select_sound(snd) end end # remove-clicks add_help(:find_click, "find_click(loc) \ Finds the next click starting at LOC.") def find_click(loc) reader = make_sampler(loc, false, false) samp0 = samp1 = samp2 = 0.0 samps = make_vct(10) len = framples() samps_ctr = 0 (loc...len).each do |ctr| samp0, samp1, samp2 = samp1, samp2, next_sample(reader) samps[samps_ctr] = samp0 if samps_ctr < 9 samps_ctr += 1 else samps_ctr = 0 end local_max = [0.1, vct_peak(samps)].max if ((samp0 - samp1).abs > local_max) and ((samp1 - samp2).abs > local_max) and ((samp0 - samp2).abs < (local_max / 2)) return ctr - 1 end end false end add_help(:remove_clicks, "remove_clicks() \ Tries to find and smooth-over clicks.") def remove_clicks loc = 0 while (click = find_click(loc)) smooth_sound(click - 2, 4) loc = click + 2 end end # searching examples (zero+, next-peak) add_help(:search_for_click, "search_for_click() \ Looks for the next click (for use with C-s).") def search_for_click samp0 = samp1 = samp2 = 0.0 samps = Vct.new(10) sctr = 0 lambda do |val| samp0, samp1, samp2 = samp1, samp2, val samps[sctr] = val sctr += 1 if sctr >= 10 then sctr = 0 end local_max = [0.1, samps.peak].max if ((samp0 - samp1).abs >= local_max) and ((samp1 - samp2).abs >= local_max) and ((samp0 - samp2).abs <= (local_max / 2)) -1 else false end end end add_help(:zero_plus, "zero_plus() \ Finds the next positive-going \ zero crossing (if searching forward) (for use with C-s).") def zero_plus lastn = 0.0 lambda do |n| rtn = lastn < 0.0 and n >= 0.0 and -1 lastn = n rtn end end add_help(:next_peak, "next_peak() \ Finds the next max or min point \ in the time-domain waveform (for use with C-s).") def next_peak last0 = last1 = false lambda do |n| rtn = number?(last0) and ((last0 < last1 and last1 > n) or (last0 > last1 and last1 < n)) and -1 last0, last1 = last1, n rtn end end add_help(:find_pitch, "find_pitch(pitch) \ Finds the point in the current sound where PITCH (in Hz) \ predominates -- C-s find_pitch(300). \ In most cases, \ this will be slightly offset from the true beginning of the note.") def find_pitch(pitch) interpolated_peak_offset = lambda do |la, ca, ra| pk = 0.001 + [la, ca, ra].max logla = log([la, 0.0000001].max / pk) / log(10) logca = log([ca, 0.0000001].max / pk) / log(10) logra = log([ra, 0.0000001].max / pk) / log(10) 0.5 * (logla - logra) / ((logla + logra) - 2 * logca) end data = make_vct(transform_size) data_loc = 0 lambda do |n| data[data_loc] = n data_loc += 1 rtn = false if data_loc == transform_size data_loc = 0 if vct_peak(data) > 0.001 spectr = snd_spectrum(data, Rectangular_window, transform_size) pk = 0.0 pkloc = 0 (transform_size / 2).times do |i| if spectr[i] > pk pk = spectr[i] pkloc = i end end pit = (pkloc + (pkloc > 0 ? interpolated_peak_offset.call(*spectr[pkloc - 1, 3]) : 0.0) * srate()) / transform_size if (pitch - pit).abs < srate / (2 * transform_size) rtn = -(transform_size / 2) end end vct_fill!(data, 0.0) end rtn end end # file2vct and a sort of cue-list, I think add_help(:file2vct, "file2vct(file) \ Returns a vct with FILE's data.") def file2vct(file) len = mus_sound_framples(file) reader = make_sampler(0, file) data = make_vct!(len) do next_sample(reader) end free_sampler(reader) data end add_help(:add_notes, "add_notes(notes, snd=false, chn=false) \ Adds (mixes) NOTES which is a list of lists of the form: \ [file, offset=0.0, amp=1.0] starting at the cursor in the \ currently selected channel: \ add_notes([[\"oboe.snd\"], [\"pistol.snd\", 1.0, 2.0]])") def add_notes(notes, snd = false, chn = false) start = cursor(snd, chn) as_one_edit_rb("%s(%s", get_func_name, notes.inspect) do (notes or []).each do |note| file, offset, amp = note beg = start + (srate(snd) * (offset or 0.0)).floor if amp and amp != 1.0 mix_vct(vct_scale!(file2vct(file), amp), beg, snd, chn, false, format("%s(%s", get_func_name, notes.inspect)) else mix(file, beg, 0, snd, chn, false) end end end end add_help(:region_play_list, "region_play_list(data) \ DATA is list of lists [[time, reg], ...], time in secs, \ setting up a sort of play list: \ region_play_list([[0.0, 0], [0.5, 1], [1.0, 2], [1.0, 0]])") def region_play_list(data) (data or []).each do |tm, rg| tm = (1000.0 * tm).floor if region?(rg) call_in(tm, lambda do | | play(rg) end) end end end add_help(:region_play_sequence, "region_play_sequence(data) \ DATA is list of region ids which will be played one after the other: \ region_play_sequence([0, 2, 1])") def region_play_sequence(data) time = 0.0 region_play_list(data.map do |id| cur = time time = time + region_framples(id) / region_srate(id) [cur, id] end) end # replace-with-selection add_help(:replace_with_selection, "replace_with_selection() \ Replaces the samples from the cursor with the current selection.") def replace_with_selection beg = cursor len = selection_framples() delete_samples(beg, len) insert_selection(beg) end # explode-sf2 add_help(:explode_sf2, "explode_sf2() \ Turns the currently selected soundfont file into \ a bunch of files of the form sample-name.aif.") def explode_sf2 (soundfont_info() or []).each do |name, start, loop_start, loop_end| filename = name + ".aif" if selection? set_selection_member?(false, true) end set_selection_member?(true) set_selection_position(start) set_selection_framples(framples() - start) save_selection(filename, selection_srate(), Mus_bshort, Mus_aifc) temp = open_sound(filename) set_sound_loop_info([loop_start, loop_end], temp) close_sound(temp) end end # open-next-file-in-directory class Next_file def initialize @last_file_opened = "" @current_directory = "" @current_sorted_files = [] end def open_next_file_in_directory unless $open_hook.member?("open-next-file-in-directory") $open_hook.add_hook!("open-next-file-in-directory") do |fname| self.get_current_directory(fname) end end if @last_file_opened.empty? and sounds @last_file_opened = file_name(Snd.snd) end if @current_directory.empty? unless sounds get_current_files(Dir.pwd) else get_current_files(File.split(@last_file_opened).first) end end if @current_sorted_files.empty? Snd.raise(:no_such_file) else next_file = find_next_file if find_sound(next_file) Snd.raise(:file_already_open, next_file) else sounds and close_sound(Snd.snd) open_sound(next_file) end end true end private def find_next_file choose_next = @last_file_opened.empty? just_filename = File.basename(@last_file_opened) f = callcc do |ret| @current_sorted_files.each do |file| ret.call(file) if choose_next if file == just_filename choose_next = true end end @current_sorted_files[0] # wrapped around end @current_directory + "/" + f end def get_current_files(dir) @current_directory = dir @current_sorted_files = sound_files_in_directory(dir).sort end def get_current_directory(filename) Snd.display(@last_file_opened = filename) new_path = File.split(mus_expand_filename(filename)).first if @current_directory.empty? or @current_directory != new_path get_current_files(new_path) end false end end def click_middle_button_to_open_next_file_in_directory nf = Next_file.new $mouse_click_hook.add_hook!("next-file") do |s, c, button, st, x, y, ax| if button == 2 nf.open_next_file_in_directory end end end # chain-dsps def chain_dsps(start, dur, *dsps) dsp_chain = dsps.map do |gen| if array?(gen) make_env(:envelope, gen, :duration, dur) else gen end end run_instrument(start, dur) do val = 0.0 dsp_chain.each do |gen| if env?(gen) val *= gen.run elsif readin?(gen) val += gen.run else val = gen.run(val) end end val end end =begin with_sound() do chain_dsps(0, 1.0, [0, 0, 1, 1, 2, 0], make_oscil(:frequency, 440)) chain_dsps(0, 1.0, [0, 0, 1, 1, 2, 0], make_one_pole(0.5), make_readin("oboe.snd")) chain_dsps(0, 1.0, [0, 0, 1, 1, 2, 0], let(make_oscil(:frequency, 220), make_oscil(:frequency, 440)) do |osc1, osc2| lambda do |val| osc1.run(val) + osc2.run(2.0 * val) end end) end =end # re-order channels def scramble_channels(*new_order) len = new_order.length swap_once = lambda do |current, desired, n| if n != len cur_orig, cur_cur = current[n][0, 2] dst = desired[n] if cur_orig != dst swap_channels(false, cur_cur, false, dst) current[dst][0] = cur_orig end swape_once.call(current, desired, n + 1) end end swap_once.call(make_array(len) do |i| [i, i] end, new_order, 0) end def scramble_channel(silence) buffer = make_moving_average(128) silence = silence / 128.0 edges = [] in_silence = true old_max = max_regions old_tags = with_mix_tags set_max_regions(1024) set_with_mix_tags(false) rd = make_sampler() framples().times do |i| y = next_sample(rd) sum_of_squares = moving_average(buffer, y * y) now_silent = (sum_of_squares < silence) if now_silent != in_silence edges.push(i) end in_silence = now_silent end edges.push(framples()) len = edges.length start = 0 pieces = Array.new(len) do |i| en = edges[i] re = make_region(start, en) start = en re end start = 0 fnc = lambda do | | scale_by(0.0) len.times do |i| this = random(len) reg = pieces[this] pieces[this] = false unless reg (this + 1).upto(len - 1) do |j| reg = pieces[j] if reg pieces[j] = false break end end unless reg (this - 1).downto(0) do |j| reg = pieces[j] if reg pieces[j] = false break end end end end mix_region(reg, start) start += framples(reg) forget_region(reg) end end as_one_edit(fnc) set_max_regions(old_max) set_with_mix_tags(old_tags) end # scramble_channel(0.01) # reorder blocks within channel add_help(:reverse_by_blocks, "reverse_by_blocks(block_len, snd=false, chn=false) \ Divide sound into block-len blocks, recombine blocks in reverse order.") def reverse_by_blocks(block_len, snd = false, chn = false) len = framples(snd, chn) num_blocks = (len / (srate(snd).to_f * block_len)).floor if num_blocks > 1 actual_block_len = len / num_blocks rd = make_sampler(len - actual_block_len, snd, chn) beg = 0 ctr = 1 map_channel(lambda do |y| val = read_sample(rd) if beg < 10 val = val * beg * 0.1 else if beg > actual_block_len - 10 val = val * (actual_block_len - beg) * 0.1 end end beg += 1 if beg == actual_block_len ctr += 1 beg = 0 rd = make_sampler([len - ctr * actual_block_len, 0].max, snd, chn) end val end, 0, false, snd, chn, false, format("%s(%s", get_func_name, block_len)) end end add_help(:reverse_within_blocks, "reverse_within_blocks(block_len, snd=false, chn=false) \ Divide sound into blocks, recombine in order, \ but each block internally reversed.") def reverse_within_blocks(block_len, snd = false, chn = false) len = framples(snd, chn) num_blocks = (len / (srate(snd).to_f * block_len)).floor if num_blocks > 1 actual_block_len = len / num_blocks no_clicks_env = [0.0, 0.0, 0.01, 1.0, 0.99, 1.0, 1.0, 0.0] as_one_edit(lambda do | | 0.step(len, actual_block_len) do |beg| reverse_channel(beg, actual_block_len, snd, chn) env_channel(no_clicks_env, beg, actual_block_len, snd, chn) end end, format("%s(%s", get_func_name, block_len)) else reverse_channel(0, false, snd, chn) end end def segment_maxamp(name, beg, dur) mx = 0.0 rd = make_sampler(beg, name) dur.times do mx = [mx, next_sample(rd).abs].max end free_sampler(rd) mx end def segment_sound(name, high, low) len = mus_sound_framples(name) reader = make_sampler(0, name) avg = make_moving_average(:size, 128) lavg = make_moving_average(:size, 2048) segments = Vct.new(100) segctr = 0 possible_end = 0 in_sound = false len.times do |i| samp = next_sample(reader).abs val = moving_average(avg, samp) lval = moving_average(lavg, samp) if in_sound if val < low possible_end = i if lval < low segments[segctr] = possible_end + 128 segctr += 1 in_sound = false end else if val > high segments[segctr] = i - 128 segctr += 1 in_sound = true end end end end free_sampler(reader) if in_sound segments[segctr] = len [segctr + 1, segments] else [segctr, segments] end end def do_one_directory(fd, dir_name, ins_name, high = 0.01, low = 0.001) snd_print("# #{dir_name}") sound_files_in_directory(dir_name).each do |sound| sound_name = dir_name + "/" + sound boundary_data = segment_sound(sound_name, high, low) segments, boundaries = boundary_data fd.printf("\n\n# ", sound) fd.printf("(%s %s", ins_name, sound_name.inspect) 0.step(segments, 2) do |bnd| segbeg = boundaries[bnd].to_i segbeg = boundaries[bnd + 1].to_i fd.printf("(%s %s %s)", segbeg, segdur, segment_maxamp(sound_name, segbeg, segdur)) fd.printf(")") end mus_sound_forget(sound_name) end end def sound2segment_data(main_dir, output_file = "sounds.data") File.open(output_file, "w") do |fd| old_fam = with_file_monitor set_with_file_monitor(false) fd.printf("# sound data from %s", main_dir.inspect) if main_dir[-1] != "/" then main_dir += "/" end Dir[main_dir].each do |dir| ins_name = dir.downcase.tr(" ", "") fd.printf("\n\n# ---------------- %s ----------------", dir) if dir == "Piano" Dir[main_dir + dir].each do |inner_dir| do_one_directory(fd, main_dir + dir + "/" + inner_dir, ins_name, 0.001, 0.0001) end else do_one_directory(fd, main_dir + dir, ins_name) end end set_with_file_monitor(old_fam) end end # sounds2segment_data(ENV['HOME'] + "/.snd.d/iowa/sounds/", "iowa.data") add_help(:channel_clipped?, "channel_clipped?(snd=false, chn=false) \ Returns true and a sample number if it finds clipping.") def channel_clipped?(snd = false, chn = false) last_y = 0.0 scan_channel(lambda do |y| result = (y.abs >= 0.9999 and last_y.abs >= 0.9999) last_y = y result end, 0, false, snd, chn) end # scan-sound def scan_sound(func, beg = 0, dur = false, snd = false) if sound?(index = Snd.snd(snd)) if (chns = channels(index)) == 1 scan_channel(lambda do |y| func.call(y, 0) end, beg, dur, index, 0) else len = framples(index) fin = (dur ? [len, beg + dur].min : len) readers = make_array(chns) do |chn| make_sampler(beg, index, chn) end result = false beg.upto(fin) do |i| local_result = true readers.each_with_index do |rd, chn| local_result = (func.call(rd.call, chn) and local_result) end if local_result result = [true, i] break end end result end else Snd.raise(:no_such_sound, get_func_name, snd) end end def scan_sound_rb(beg = 0, dur = false, snd = false, &func) scan_sound(func, beg, dur, snd) end end include Examp module Moog class Moog_filter < Musgen Gaintable = vct(0.999969, 0.990082, 0.980347, 0.970764, 0.961304, 0.951996, 0.94281, 0.933777, 0.924866, 0.916077, 0.90741, 0.898865, 0.890442, 0.882141, 0.873962, 0.865906, 0.857941, 0.850067, 0.842346, 0.834686, 0.827148, 0.819733, 0.812378, 0.805145, 0.798004, 0.790955, 0.783997, 0.77713, 0.770355, 0.763672, 0.75708, 0.75058, 0.744141, 0.737793, 0.731537, 0.725342, 0.719238, 0.713196, 0.707245, 0.701355, 0.695557, 0.689819, 0.684174, 0.678558, 0.673035, 0.667572, 0.66217, 0.65686, 0.651581, 0.646393, 0.641235, 0.636169, 0.631134, 0.62619, 0.621277, 0.616425, 0.611633, 0.606903, 0.602234, 0.597626, 0.593048, 0.588531, 0.584045, 0.579651, 0.575287, 0.570953, 0.566681, 0.562469, 0.558289, 0.554169, 0.550079, 0.546051, 0.542053, 0.538116, 0.53421, 0.530334, 0.52652, 0.522736, 0.518982, 0.515289, 0.511627, 0.507996, 0.504425, 0.500885, 0.497375, 0.493896, 0.490448, 0.487061, 0.483704, 0.480377, 0.477081, 0.473816, 0.470581, 0.467377, 0.464203, 0.46109, 0.457977, 0.454926, 0.451874, 0.448883, 0.445892, 0.442932, 0.440033, 0.437134, 0.434265, 0.431427, 0.428619, 0.425842, 0.423096, 0.42038, 0.417664, 0.415009, 0.412354, 0.409729, 0.407135, 0.404572, 0.402008, 0.399506, 0.397003, 0.394501, 0.392059, 0.389618, 0.387207, 0.384827, 0.382477, 0.380127, 0.377808, 0.375488, 0.37323, 0.370972, 0.368713, 0.366516, 0.364319, 0.362122, 0.359985, 0.357849, 0.355713, 0.353607, 0.351532, 0.349457, 0.347412, 0.345398, 0.343384, 0.34137, 0.339417, 0.337463, 0.33551, 0.333588, 0.331665, 0.329773, 0.327911, 0.32605, 0.324188, 0.322357, 0.320557, 0.318756, 0.316986, 0.315216, 0.313446, 0.311707, 0.309998, 0.308289, 0.30658, 0.304901, 0.303223, 0.301575, 0.299927, 0.298309, 0.296692, 0.295074, 0.293488, 0.291931, 0.290375, 0.288818, 0.287262, 0.285736, 0.284241, 0.282715, 0.28125, 0.279755, 0.27829, 0.276825, 0.275391, 0.273956, 0.272552, 0.271118, 0.269745, 0.268341, 0.266968, 0.265594, 0.264252, 0.262909, 0.261566, 0.260223, 0.258911, 0.257599, 0.256317, 0.255035, 0.25375) Freqtable = [0, -1, 0.03311111, -0.9, 0.06457143, -0.8, 0.0960272, -0.7, 0.127483, -0.6, 0.1605941, -0.5, 0.1920544, -0.4, 0.22682086, -0.3, 0.2615873, -0.2, 0.29801363, -0.1, 0.33278003, -0.0, 0.37086168, 0.1, 0.40893877, 0.2, 0.4536417, 0.3, 0.5, 0.4, 0.5463583, 0.5, 0.5943719, 0.6, 0.6556281, 0.7, 0.72185487, 0.8, 0.8096009, 0.9, 0.87913835, 0.95, 0.9933787, 1, 1, 1] def initialize(freq, q) super() @frequency = freq @Q = q @state = make_vct(4) @A = 0.0 @freqtable = envelope_interp(freq / (srate() * 0.5), Freqtable) end attr_reader :frequency, :state, :freqtable, :A attr_accessor :Q def inspect format("%s.new(%s, %s)", self.class, @frequency, @Q) end def to_s format("#<%s freq: %1.3f, Q: %s>", self.class, @frequency, @Q) end def run_func(val1 = 0.0, val2 = 0.0) filter(val1) end def frequency=(freq) @freqtable = envelope_interp(freq / (srate() * 0.5), Freqtable) @frequency = freq end def filter(insig) a = 0.25 * (insig - @A) @state.map! do |st| new_a = saturate(a + @freqtable * (a - st)) a = saturate(new_a + st) new_a end ix = @freqtable * 99.0 ixint = ix.floor ixfrac = ix - ixint @A = a * @Q * ((1.0 - ixfrac) * Gaintable[ixint + 99] + ixfrac * Gaintable[ixint + 100]) a end private def saturate(x) [[x, -0.95].max, 0.95].min end end add_help(:make_moog_filter, "make_moog_filter(freq=440.0, Q=0) \ Makes a new moog_filter generator. \ FREQUENCY is the cutoff in Hz, \ Q sets the resonance: 0 = no resonance, 1: oscillates at FREQUENCY.") def make_moog_filter(freq = 440.0, q = 0) Moog_filter.new(freq, q) end add_help(:moog_filter, "moog_filter(moog, insig=0.0) \ Is the generator associated with make_moog_filter.") def moog_filter(mg, insig = 0.0) mg.filter(insig) end def moog(freq, q) mg = Moog_filter.new(freq, q) lambda do |inval| mg.filter(inval) end end end include Moog # examp.rb ends here snd-16.1/bandedwg.cms0000644000076400007640000001501712403566572012630 0ustar bilbil;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; ;;; Banded Waveguide Instrument based on ;;; ====== ========= ;;; ;;; Essl, G. and Cook, P. "Banded ;;; Waveguides: Towards Physical Modelling of Bar ;;; Percussion Instruments", Proceedings of the ;;; 1999 International Computer Music Conference. ;;; ;;; Also, Essl, Serafin, Cook, and Smith J.O., ;;; "Theory of Banded Waveguides", CMJ, 28:1, ;;; pp37-50, Spring 2004. ;;; ;;; NOTES: ;;; As with all physical models, initial conditions matter. ;;; Frequency range is not too broad. 220Hz. is a good ;;; starting point. ;;; ;;; ;;; Tuned bar, Glass Harmonica and Uniform Bar for now. ;;; ;;; 08/22/2013 update bandpass filters with CLM's filter generator (juanig) ;;; 08/24/2013 replaced delay line macros with DelayL using clm's delay ug ;;; 08/29/2014 fixed waveguide with feed and reflections ;;; 08/30/2014 Try different delay line lengths. Fixing bandpass radius param. ;;; 09/04/2014 This SND's S7 version ;;; (define* (make-bowtable (offset 0.0) (slope 1.0)) (float-vector offset slope)) (define (bowtable b samp) (max 0.0 (- 1.0 (abs (* (b 1) (+ samp (b 0))))))) (define (make-bandpassbq freq radius) (let ((arra (make-float-vector 3)) (arrb (make-float-vector 3))) (set! (arra 1) (* -1.998 radius (cos (hz->radians freq)))) (set! (arra 2) (* radius radius)) ;;; ;;; gain gets normalized ;;; (set! (arrb 0) (- 0.5 (* 0.5 (arra 2)))) (set! (arrb 2) (- (arrb 0) )) (make-filter 3 arra arrb) )) ;;; To handle bandpass filter (define (bandpassbq f sample0) (filter f sample0)) ;;; Delay line structures and functions using SND's delay generator (as per prc95.scm) (defgenerator dlya (outp 0) (input #f)) (define (make-delayl len lag) (make-dlya :input (make-delay len :max-size (ceiling (+ len lag 1))) :outp (- lag len))) (define (delayl d samp) (delay-tick (d 'input) samp) (tap (d 'input) (d 'outp))) ;;;;;;;;;;;;;;;;;;;; (definstrument (bandedwg beg dur freq amplitude ;; vibration modes ;; 1=tuned Bar; 2=Glass Harmonica; ;; 3= Uniform bar (mode 3) (maxa 0.9998) ;; max bow velocity (bv 1.0) ;; bow velocity scaler ;; velocity envelope (vel-env '(0 1.0 .95 1.1 1 1.0)) (amp-env '(0 1 1 1)) ;;'(0 0.0 .95 1.0 .99 0.00)) (rev-amount .08) ) (let ((nrmodes 4)) (cond ((= mode 1) (set! nrmodes 4)) ((= mode 2) (set! nrmodes 6)) (else (set! nrmodes 4)) ) (let* ((start (seconds->samples beg)) (baselen (/ *clm-srate* freq)) ;; original Stk delayl length (baselag (- (/ *clm-srate* freq) 0.5)) (dtapoffs 0.0) ;; tap offset is 0.0 in StK's version (bandpass (make-vector nrmodes)) (delayslft (make-vector nrmodes)) (delaysrfl (make-vector nrmodes)) (modes (make-float-vector nrmodes)) (gains (make-float-vector nrmodes)) (basegains (make-float-vector nrmodes)) (excitations (make-float-vector nrmodes)) (delastout (make-float-vector nrmodes)) ;; (fradius 0.0) ;; radius for bandpass filter (dlength 0.0) ;; delay-line length (dlag 0.0) ;; delay lag (for tap) ;; (bowtab (make-bowtable :slope 3.0 :offset 0.001)) (ampenv (make-env amp-env :scaler amplitude :duration dur)) ;; (vel-env (make-env vel-env :scaler bv :duration dur)) ;; (maxvelocity maxa) (end (+ start (seconds->samples dur))) ) ;; ;; (cond ((= mode 1) ;; Tuned Bar (begin (set! (modes 0) 1.000) (set! (modes 1) 4.0198391420) (set! (modes 2) 10.7184986595) (set! (modes 3) 18.0697050938) (do ((i 0 (+ i 1))) ((= i nrmodes)) (set! (basegains i) (expt 0.998 (+ i 1))) (set! (excitations i) 1.0) ) )) ((= mode 2) ;; Glass Harmonica (begin (set! (modes 0) 1.000) (set! (modes 1) 2.32) (set! (modes 2) 4.25) (set! (modes 3) 6.63) (set! (modes 4) 9.38) (set! (modes 5) 12.22) (do ((i 0 (+ i 1))) ((= i nrmodes)) (set! (basegains i ) (expt 0.988 (+ i 1))) (set! (excitations i) 1.0)) )) (else ;; Uniform Bar (begin (set! (modes 0) 1.000) (set! (modes 1) 2.756) (set! (modes 2) 5.404) (set! (modes 3) 8.933) (do ((i 0 (+ i 1))) ((= i nrmodes)) (set! (basegains i ) (expt 0.9 (+ i 1))) (set! (excitations i) 1.0)) )) ) ;; ;; set-frequency method in STK's BandedWG ;; ;; (set! fradius (- 1.0 (* pi (/ 32 *clm-srate*)))) (set! fradius (- 0.3998 (* pi (/ 32 *clm-srate*)))) (do ((i 0 (+ i 1))) ((= i nrmodes)) (set! dlength (floor (/ baselen (modes i)))) (set! dlag (floor (/ baselag (modes i)))) ;; (- lag len) --> tap offset (set! (delayslft i) (make-delayl dlength dlag)) (set! (delaysrfl i) (make-delayl dlength dlag)) (set! (gains i) (basegains i)) (set! (bandpass i) (make-bandpassbq (* freq (modes i)) fradius)) ) ;; ;;;;;;;;;;;; ;; (do ((i start (+ i 1))) ((= i end)) ;; (let ((input 0.0) (velinput 0.0) (bowvelocity 0.0) (bplastout 0.0) (dlastsampl 0.0) (outsampl 0.0) ) (do ((k 0 (+ k 1))) ((= k nrmodes)) (set! velinput (+ velinput (* (basegains k) (delastout k))) ) ) ;; ;; (set! bowvelocity (* 0.3 (env vel-env) maxvelocity)) (set! bowvelocity (* 0.3 maxvelocity)) (set! input (- bowvelocity velinput)) (set! input (* input (bowtable bowtab input))) (set! input (/ input nrmodes )) ;; ;; Here the waveguide ;; (do ((j 0 (+ j 1))) ((= j nrmodes)) (set! bplastout (+ bplastout (bandpassbq (bandpass j) (delayl (delayslft j) (+ input (* (gains j) dlastsampl)) )))) (set! dlastsampl (+ dlastsampl (delayl (delaysrfl j) bplastout))) (set! (delastout j) dlastsampl) ) ;; ;; (set! outsampl (* 4.0 (env ampenv) bplastout)) (outa i outsampl) ;; (if *reverb* (begin (outa i (* outsampl rev-amount) *reverb*))) ))) )) ;;; (with-sound () (bandedwg 0 1 220 0.4)) ;;; (with-sound () (bandedwg 0 1 220 0.4 :mode 1)) ;;; (with-sound () (bandedwg 0 1 220 0.4 :mode 2)) ;;; (with-sound () (bandedwg 0 1.0 220 0.7 :mode 1 :maxa 0.497)) snd-16.1/special-menu.scm0000644000076400007640000002467112622705137013440 0ustar bilbil(provide 'snd-special-menu.scm) (if (provided? 'xm) (require snd-effects-utils.scm snd-snd-motif.scm snd-edit-menu.scm)) (if (provided? 'xg) (require snd-gtk-effects-utils.scm snd-snd-gtk.scm)) (define *e* (if (provided? 'snd-motif) *motif* *gtk*)) (define update-label (*e* 'update-label)) (define change-label (*e* 'change-label)) (define make-effect-dialog (*e* 'make-effect-dialog)) (define add-sliders (*e* 'add-sliders)) (define activate-dialog (*e* 'activate-dialog)) (define select-file (*e* 'select-file)) (require snd-edit-menu.scm) (if (not (defined? 'start-enveloping)) (load "enved.scm")) (if (not (defined? 'explode-sf2)) (load "examp.scm")) (define special-list ()) ; menu labels are updated to show current default settings (define special-menu (add-to-main-menu "Special" (lambda () (update-label special-list)))) ;;; -------- Append file ;;; (add-to-menu edit-menu "Append file" (lambda () (select-file (lambda (filename) (insert-sound filename (framples)))))) (add-to-menu special-menu #f #f) ;;; -------- MIDI to WAV ;;; (add-to-menu special-menu "MIDI to WAV" (lambda () (select-file (lambda (filename) (system (format #f "timidity -Ow ~a" filename))) "Select MIDI file" "." "*.mid" "Converts MIDI file to WAV using TiMidity. \ Output will be named after the original MIDI file, i.e., foo.mid converts to foo.wav. \ You must have TiMidity and a patch set installed for this function to work. \ See the TiMidity home page at http://www.onicos.com/staff/iz/timidity/ for more details."))) (add-to-menu special-menu #f #f) (define env-file-menu-label #f) (define env-file #f) (define yes-env-label "Envelope new file (Off)") (define no-env-label "Envelope new file (On)") (define (yesenv!) (set! env-file #t) (if env-file-menu-label (change-label env-file-menu-label no-env-label)) (start-enveloping)) (define (noenv!) (set! env-file #f) (if env-file-menu-label (change-label env-file-menu-label yes-env-label)) (stop-enveloping)) (set! env-file-menu-label (add-to-menu special-menu yes-env-label (lambda () (if env-file (noenv!) (yesenv!))))) ;;; -------- Play panned ;;; (define play-panned-file 1) (define play-panned-label "Play panned") (define play-panned-dialog #f) (define play-panned-menu-label #f) (define (cp-play-panned) (play-panned play-panned-file)) (if (or (provided? 'xm) (provided? 'xg)) (begin (define (post-play-panned-dialog) (if (not play-panned-dialog) (let ((initial-play-panned-file 1) (sliders ())) (set! play-panned-dialog (make-effect-dialog play-panned-label (if (provided? 'snd-gtk) (lambda (w context) (cp-play-panned)) (lambda (w context info) (cp-play-panned))) (if (provided? 'snd-gtk) (lambda (w context) (help-dialog "Play panned" "Move the slider to select the file to play with panning envelope.")) (lambda (w context info) (help-dialog "Play panned" "Move the slider to select the file to play with panning envelope."))) (if (provided? 'snd-gtk) (lambda (w data) (set! play-panned-file initial-play-panned-file) ((*gtk* 'gtk_adjustment_set_value) ((*gtk* 'GTK_ADJUSTMENT) (car sliders)) play-panned-file) ) (lambda (w c i) (set! play-panned-file initial-play-panned-file) ((*motif* 'XtSetValues) (car sliders) (list (*motif* 'XmNvalue) play-panned-file)))))) (set! sliders (add-sliders play-panned-dialog (list (list "soundfile number" 0 initial-play-panned-file 25 (if (provided? 'snd-gtk) (lambda (w context) (set! play-panned-file ((*gtk* 'gtk_adjustment_get_value) ((*gtk* 'GTK_ADJUSTMENT) w)))) (lambda (w context info) (set! play-panned-file ((*motif* '.value) info)))) 1)))))) (activate-dialog play-panned-dialog)) (set! play-panned-menu-label (add-to-menu special-menu "Play panned" post-play-panned-dialog))) (set! play-panned-menu-label (add-to-menu special-menu play-panned-label cp-play-panned))) (set! special-list (cons (lambda () (let ((new-label (format #f "Play panned (~D)" play-panned-file))) (if play-panned-menu-label (change-label play-panned-menu-label new-label)) (set! play-panned-label new-label))) special-list)) (add-to-menu special-menu #f #f) ;;; -------- Save as MP3 ;;; (define save-as-mp3-wav-file-number 0) (define save-as-mp3-label "Save as MP3") (define save-as-mp3-dialog #f) (define save-as-mp3-menu-label #f) (define (cp-save-as-mp3) (save-sound-as "tmp.wav" save-as-mp3-wav-file-number :header-type mus-riff) (system (format #f "bladeenc tmp.wav tmp-~D.mp3" save-as-mp3-wav-file-number))) (if (or (provided? 'xm) (provided? 'xg)) (begin (define (post-save-as-mp3-dialog) (if (not save-as-mp3-dialog) (let ((initial-save-as-mp3-wav-file-number 0) (sliders ())) (set! save-as-mp3-dialog (make-effect-dialog save-as-mp3-label (if (provided? 'snd-gtk) (lambda (w context) (cp-save-as-mp3)) (lambda (w context info) (cp-save-as-mp3))) (if (provided? 'snd-gtk) (lambda (w context) (help-dialog "Save as MP3" "Move the slider to select the file to save as an MP3. \ The new MP3 will be named tmp-N.mp3 by default. Bladeenc is currently the only supported encoder. \ Please see the Web page at bladeenc.mp3.no for details regarding Bladeenc.")) (lambda (w context info) (help-dialog "Save as MP3" "Move the slider to select the file to save as an MP3. \ The new MP3 will be named tmp-N.mp3 by default. Bladeenc is currently the only supported encoder. \ Please see the Web page at bladeenc.mp3.no for details regarding Bladeenc."))) (if (provided? 'snd-gtk) (lambda (w data) (set! save-as-mp3-wav-file-number initial-save-as-mp3-wav-file-number) ((*gtk* 'gtk_adjustment_set_value) ((*gtk* 'GTK_ADJUSTMENT) (car sliders)) save-as-mp3-wav-file-number) ) (lambda (w c i) (set! save-as-mp3-wav-file-number initial-save-as-mp3-wav-file-number) ((*motif* 'XtSetValues) (car sliders) (list (*motif* 'XmNvalue) save-as-mp3-wav-file-number)))))) (set! sliders (add-sliders save-as-mp3-dialog (list (list "soundfile number" 0 initial-save-as-mp3-wav-file-number 250 (if (provided? 'snd-gtk) (lambda (w data) (set! save-as-mp3-wav-file-number ((*gtk* 'gtk_adjustment_get_value) ((*gtk* 'GTK_ADJUSTMENT) w)))) (lambda (w context info) (set! save-as-mp3-wav-file-number ((*motif* '.value) info)))) 1)))))) (activate-dialog save-as-mp3-dialog)) (set! save-as-mp3-menu-label (add-to-menu special-menu "Save as MP3" post-save-as-mp3-dialog))) (set! save-as-mp3-menu-label (add-to-menu special-menu save-as-mp3-label cp-save-as-mp3))) (set! special-list (cons (lambda () (let ((new-label (format #f "Save as MP3 (~D)" save-as-mp3-wav-file-number))) (if save-as-mp3-menu-label (change-label save-as-mp3-menu-label new-label)) (set! save-as-mp3-label new-label))) special-list)) ;;; -------- Save as Ogg File ;;; (define save-as-ogg-wav-file-number 0) (define save-as-ogg-label "Save as Ogg file") (define save-as-ogg-dialog #f) (define save-as-ogg-menu-label #f) (define (cp-save-as-ogg) (save-sound-as "tmp.wav" save-as-ogg-wav-file-number :header-type mus-riff) (system (format #f "oggenc tmp.wav -o tmp-~D.ogg" save-as-ogg-wav-file-number))) (if (or (provided? 'xm) (provided? 'xg)) (begin (define (post-save-as-ogg-dialog) (if (not save-as-ogg-dialog) (let ((initial-save-as-ogg-wav-file-number 0) (sliders ())) (set! save-as-ogg-dialog (make-effect-dialog save-as-ogg-label (if (provided? 'snd-gtk) (lambda (w context) (cp-save-as-ogg)) (lambda (w context info) (cp-save-as-ogg))) (if (provided? 'snd-gtk) (lambda (w context) (help-dialog "Save as Ogg file" "Move the slider to select the file to save as an Ogg file. \ The new file will be named tmp-N.ogg by default. Oggenc is currently the only supported Ogg encoder. \ Please see the Web page at www.xiphophorus.org for details regarding the Ogg/Vorbis project.")) (lambda (w context info) (help-dialog "Save as Ogg file" "Move the slider to select the file to save as an Ogg file. \ The new file will be named tmp-N.ogg by default. Oggenc is currently the only supported Ogg encoder. \ Please see the Web page at www.xiphophorus.org for details regarding the Ogg/Vorbis project."))) (if (provided? 'snd-gtk) (lambda (w data) (set! save-as-ogg-wav-file-number initial-save-as-ogg-wav-file-number) ((*gtk* 'gtk_adjustment_set_value) ((*gtk* 'GTK_ADJUSTMENT) (car sliders)) save-as-ogg-wav-file-number) ) (lambda (w c i) (set! save-as-ogg-wav-file-number initial-save-as-ogg-wav-file-number) ((*motif* 'XtSetValues) (car sliders) (list (*motif* 'XmNvalue) save-as-ogg-wav-file-number)))))) (set! sliders (add-sliders save-as-ogg-dialog (list (list "soundfile number" 0 initial-save-as-ogg-wav-file-number 250 (if (provided? 'snd-gtk) (lambda (w data) (set! save-as-ogg-wav-file-number ((*gtk* 'gtk_adjustment_get_value) ((*gtk* 'GTK_ADJUSTMENT) w)))) (lambda (w context info) (set! save-as-ogg-wav-file-number ((*motif* '.value) info)))) 1)))))) (activate-dialog save-as-ogg-dialog)) (set! save-as-ogg-menu-label (add-to-menu special-menu "Save as Ogg file" post-save-as-ogg-dialog))) (set! save-as-ogg-menu-label (add-to-menu special-menu save-as-ogg-label cp-save-as-ogg))) (set! special-list (cons (lambda () (let ((new-label (format #f "Save as Ogg file (~D)" save-as-ogg-wav-file-number))) (if save-as-ogg-menu-label (change-label save-as-ogg-menu-label new-label)) (set! save-as-ogg-label new-label))) special-list)) (add-to-menu special-menu #f #f) (add-to-menu special-menu "Explode SF2" explode-sf2) snd-16.1/rubber.rb0000644000076400007640000002621612434353162012153 0ustar bilbil# rubber.rb -- Translation of rubber.scm # Translator/Author: Michael Scholz # Created: 03/02/28 03:04:03 # Changed: 14/11/23 06:14:52 # module Rubber (see rubber.scm) # add_named_mark(samp, name, snd, chn) # derumble_sound(snd, chn) # sample_sound(snd, chn) # unsample_sound(snd, chn) # crossings() # env_add(s0, s1, samps) # rubber_sound(stretch, snd, chn) require "clm" module Rubber doc "#{self.class} #{self.name} is the translation of rubber.scm.\n" $zeros_checked = 8 $extension = 10.0 $show_details = false def add_named_mark(samp, name, snd = false, chn = false) m = add_mark(samp.round, snd, chn) set_mark_name(m, name) m end def derumble_sound(snd = false, chn = false) old_length = framples(snd, chn) pow2 = (log([old_length, srate(snd)].min) / log(2)).ceil fftlen = (2 ** pow2).round flt_env = [0.0, 0.0, 32.0 / srate(snd), 0.0, 40.0 / srate(snd), 1.0, 1.0, 1.0] filter_sound(flt_env, fftlen, snd, chn) set_framples(old_length, snd, chn) end def sample_sound(snd = false, chn = false) if $extension != 1.0 src_sound(1.0 / $extension, 1.0, snd, chn) end end def unsample_sound(snd = false, chn = false) if $extension != 1.0 src_sound($extension, 1.0, snd, chn) end end def crossings crosses = 0 sr0 = make_sampler(0) samp0 = next_sample(sr0) len = framples() sum = 0.0 last_cross = 0 silence = $extension * 0.001 (0...len).each do |i| samp1 = next_sample(sr0) if samp0 <= 0.0 and samp1 > 0.0 and (i - last_cross) > 4 and sum > silence crosses += 1 last_cross = i sum = 0.0 end sum += samp0.abs samp0 = samp1 end crosses end def env_add(s0, s1, samps) data = make_vct(samps.round) x = 1.0 xinc = 1.0 / samps sr0 = make_sampler(s0.round) sr1 = make_sampler(s1.round) (0...samps).each do |i| data[i] = x * next_sample(sr0) + (1.0 - x) * next_sample(sr1) x += xinc end data end def rubber_sound(stretch, snd = false, chn = false) as_one_edit(lambda do | | derumble_sound(snd, chn) sample_sound(snd, chn) crosses = crossings() cross_samples = make_vct(crosses) cross_weights = make_vct(crosses) cross_marks = make_vct(crosses) cross_periods = make_vct(crosses) sr0 = make_sampler(0, snd, chn) samp0 = next_sample(sr0) len = framples() sum = 0.0 last_cross = 0 cross = 0 silence = $extension * 0.001 (0...len).each do |i| samp1 = next_sample(sr0) if samp0 <= 0.0 and samp1 > 0.0 and (i - last_cross) > 4 and sum > silence last_cross = i sum = 0.0 cross_samples[cross] = i cross += 1 end sum += samp0.abs samp0 = samp1 end (0...(crosses - 1)).each do |i| start = cross_samples[i] autolen = 0 s0 = start pow2 = (log($extension * (srate() / 40.0)) / log(2)).ceil fftlen = (2 ** pow2).round len4 = fftlen / 4 data = make_vct(fftlen) reader = make_sampler(s0.round) (0...fftlen).each do |j| data[j] = next_sample(reader) end autocorrelate(data) autolen = 0 (1...len4).detect do |j| if data[j] < data[j + 1] and data[j + 1] > data[j + 2] autolen = j * 2 true end end next_start = start + autolen min_i = i + 1 min_samps = (cross_samples[min_i] - next_start).abs ((i + 2)...[crosses, i + $zeros_checked].min).each do |k| dist = (cross_samples[k] - next_start).abs if dist < min_samps min_samps = dist min_i = k end end current_mark = min_i current_min = 0.0 s0 = start s1 = cross_samples[current_mark] len = autolen sr0 = make_sampler(s0.round) sr1 = make_sampler(s1.round) ampsum = 0.0 diffsum = 0.0 (0...len).each do |dummy| samp0 = next_sample(sr0) samp1 = next_sample(sr1) ampsum += samp0.abs diffsum += (samp1 - samp0).abs end if diffsum == 0.0 current_min = 0.0 else current_min = diffsum / ampsum end min_samps = 0.5 * current_min top = [crosses - 1, current_mark, i + $zeros_checked].min ((i + 1)...top).each do |k| wgt = 0.0 s0 = start s1 = cross_samples[k] len = autolen sr0 = make_sampler(s0.round) sr1 = make_sampler(s1.round) ampsum = 0.0 diffsum = 0.0 (0...len).each do |dummy| samp0 = next_sample(sr0) samp1 = next_sample(sr1) ampsum += samp0.abs diffsum += (samp1 - samp0).abs end if diffsum == 0.0 wgt = 0.0 else wgt = diffsum / ampsum end if wgt < min_samps min_samps = wgt min_i = k end end unless current_mark == min_i cross_weights[i] = 1000.0 else cross_weights[i] = current_min cross_marks[i] = current_mark cross_periods[i] = cross_samples[current_mark] - cross_samples[i] end end len = framples(snd, chn) adding = (stretch > 1.0) samps = ((stretch - 1.0).abs * len).round needed_samps = (adding ? samps : [len, samps * 2].min) handled = 0 mult = 1 curs = 0 weigths = cross_weights.length edits = make_vct(weigths) until curs == weigths or handled >= needed_samps best_mark = -1 old_handled = handled cur = 0 curmin = cross_weights[0] cross_weights.each_with_index do |cross_w, i| if cross_w < curmin cur = i curmin = cross_w end end best_mark = cur handled += cross_periods[best_mark].round if (handled < needed_samps) or ((handled - needed_samps) < (needed_samps - old_handled)) edits[curs] = best_mark curs += 1 end cross_weights[best_mark] = 1000.0 end mult = (needed_samps / handled).ceil if curs >= weigths changed_len = 0 weights = cross_weights.length (0...curs).detect do |i| best_mark = edits[i].round beg = cross_samples[best_mark].to_i next_beg = cross_samples[cross_marks[best_mark].round] len = cross_periods[best_mark].to_i if len > 0 if adding new_samps = env_add(beg, next_beg, len) if $show_details add_named_mark(beg, format("%d:%d", i, (len / $extension).round)) end insert_samples(beg, len, new_samps) if mult > 1 (1...mult).each do |k| insert_samples(beg + k * len, len, new_samps) end end changed_len = changed_len + mult * len (0...weights).each do |j| curbeg = cross_samples[j] if curbeg > beg cross_samples[j] = curbeg + len end end else frms = framples() if beg >= frms Snd.display("trouble at %d: %d of %d", i, beg, frms) end if $show_details add_named_mark(beg - 1, format("%d:%d", i, (len / $extension).round)) end delete_samples(beg, len) changed_len += len fin = beg + len (0...weights).each do |j| curbeg = cross_samples[j] if curbeg > beg if curbeg < fin cross_periods[j] = 0 else cross_samples[j] = curbeg - len end end end end end changed_len > samps end if $show_details Snd.display("wanted: %d, got %d", samps.round, changed_len.round) end unsample_sound(snd, chn) if $show_details frms0 = framples(snd, chn, 0) Snd.display("%f -> %f (%f)", frms0, framples(snd,chn), (stretch * frms0).round) end end, format("rubber_sound(%f, %p, %p,", stretch, snd, chn)) end end include Rubber # rubber.rb ends here snd-16.1/snd13.scm0000644000076400007640000012021012511331645011764 0ustar bilbil(provide 'snd-snd13.scm) (define (clm-print . args) "(clm-print . args) applies format to args and prints the result" (snd-print (apply format #f args))) #| ;;; this is now moved to C ;;; -------- envelope-interp (define* (envelope-interp x e (base 1.0)) ;e is list of x y breakpoint pairs, interpolate at x returning y ;; "(envelope-interp x e (base 1.0)) -> value of e at x; base controls connecting segment type: (envelope-interp .3 '(0 0 .5 1 1 0) -> .6" (cond ((null? e) 0.0) ;no data -- return 0.0 ((or (<= x (car e)) ;we're sitting on x val (or if < we blew it) (null? (cddr e))) ;or we're at the end of the list (cadr e)) ;so return current y value ((> (caddr e) x) ;x <= next env x axis value (if (or (= (cadr e) (cadddr e)) (= base 0.0)) (cadr e) ;y1=y0, so just return y0 (avoid endless calculations below) (if (= base 1.0) (+ (cadr e) ;y0+(x-x0)*(y1-y0)/(x1-x0) (* (- x (car e)) (/ (- (cadddr e) (cadr e)) (- (caddr e) (car e))))) (+ (cadr e) ; this does not exactly match xramp-channel (* (/ (- (cadddr e) (cadr e)) (- base 1.0)) (- (expt base (/ (- x (car e)) (- (caddr e) (car e)))) 1.0)))))) (else (envelope-interp x (cddr e) base)))) ;go on looking for x segment |# #| ;;; ---------------- waterfall spectrum ---------------- ;;; this is obsolete (define waterfall (let* ((drawer #f) (input-port #f) (input-proc 0) (gl-list #f) (slices 256) ; number of traces displayed (slice 0) (data (make-vector slices)) (bins 512) ; fft size (input-data #f) (scaler 1.0) ; data scaler before GL turns it into colors (cutoff 0.2)) ; 0.5 is full spectrum (define (redraw-graph) (let ((win (XtWindow drawer)) (dpy (XtDisplay drawer)) (cx (snd-gl-context))) (glXMakeCurrent dpy win cx) (if gl-list (glDeleteLists gl-list 1)) (set! gl-list (glGenLists 1)) (glEnable GL_DEPTH_TEST) (glShadeModel GL_SMOOTH) (glClearDepth 1.0) (glClearColor 1.0 1.0 1.0 1.0) ; todo: bg color here (glClear (logior GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT)) ;;gl_spectrogram(Xen data, Xen gl_list, Xen cutoff, Xen use_dB, Xen min_dB, Xen scale, Xen br, Xen bg, Xen bb) (glSpectrogram data gl-list cutoff #f -60.0 scaler 65535 65535 65535) (let ((vals (XtVaGetValues drawer (list XmNwidth 0 XmNheight 0)))) (glViewport 0 0 (list-ref vals 1) (list-ref vals 3))) (glMatrixMode GL_PROJECTION) (glLoadIdentity) (glRotatef (spectro-x-angle) 1.0 0.0 0.0) (glRotatef (spectro-y-angle) 0.0 1.0 0.0) (glRotatef (spectro-z-angle) 0.0 0.0 1.0) (glScalef (spectro-x-scale) (spectro-y-scale) (spectro-z-scale)) (glCallList gl-list) ;; todo: make axis (glXSwapBuffers dpy win) (glDrawBuffer GL_BACK))) (define (tick-audio id) ;; background process reads incoming audio data, creates spectrum, displays next trace (mus-audio-read input-port input-data (* bins 2)) (let ((rl-data (copy (input-data 0) (data slice)))) (snd-spectrum rl-data blackman2-window bins #t 0.0 #t #f) (redraw-graph)) (set! slice (+ 1 slice)) (if (>= slice slices) (set! slice 0)) #f) (define (stop-it) ;; turn off the waterfall display (if input-port (begin (mus-audio-close input-port) (set! input-port #f))) (if (XtWorkProcId? input-proc) (begin (XtRemoveWorkProc input-proc) (set! input-proc 0))) (do ((i 0 (+ 1 i))) ((= i slices)) (float-vector-scale! (data i) 0.0))) (define (start-it) (define (add-main-pane name type args) (XtCreateManagedWidget name type (list-ref (main-widgets) 3) args)) (if (not drawer) (let ((outer (add-main-pane "Waterfall" xmFormWidgetClass (list XmNbackground (basic-color) XmNpaneMinimum 320)))) (set! drawer (XtCreateManagedWidget "draw" xmDrawingAreaWidgetClass outer (list XmNbackground (graph-color) XmNforeground (data-color) XmNleftAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM))) (XtAddCallback drawer XmNresizeCallback (lambda (w context info) (redraw-graph))) (XtAddCallback drawer XmNexposeCallback (lambda (w context info) (redraw-graph))) (hook-push orientation-hook (lambda (hook) (redraw-graph))) (hook-push color-hook (lambda (hook) (redraw-graph))))) ;; start the waterfall display (if (not (or input-port (XtWorkProcId? input-proc))) (begin (set! input-port (mus-audio-open-input mus-audio-default 22050 1 mus-lshort 512)) (set! input-proc (XtAppAddWorkProc (car (main-widgets)) tick-audio))))) ;; turn display with orientation dialog ;; for example: x-angle 290, y angle: 60 (lambda* (start scl pc-spectrum fft-size) (if start (begin (set! cutoff pc-spectrum) (set! scaler scl) (set! bins fft-size) (set! input-data (make-float-vector (list 1 (* bins 2)) 0.0)) (do ((i 0 (+ 1 i))) ((= i slices)) (set! (data i) (make-float-vector bins))) (start-it)) (stop-it))))) (define* (start-waterfall (scl 1.0) (pc-spectrum 0.2) (fft-size 512)) "(start-waterfall (scl 1.0) (pc-spectrum 0.2) (fft-size 512)) starts a 'waterfall' spectrum display of the incoming audio data" (waterfall #t scl pc-spectrum fft-size)) (define (stop-waterfall) "(stop-waterfall) stops a waterfall display" (waterfall #f)) |# #| ;;; -------- "vector synthesis" ;;; also obsolete ;;; this idea (and the weird name) from linux-audio-development mailing list discussion ;;; apparently some commercial synths (or software?) provide this (define (vector-synthesis driver files read-even-when-not-playing) "(vector-synthesis driver files read-even-when-not-playing) uses 'driver', a function of two args (the number of files, and the number of samples between calls) to decide which file to play. If 'read-even-when-not-playing' is #t (default is #f), the input files are constantly read, even if not playing. 'files' is a list of files to be played." (let ((files-len (length files))) (if (> files-len 0) (let* ((bufsize 256) (srate (srate (car files))) (chans (apply max (map channels files))) (data (make-float-vector (list chans bufsize) 0.0)) (readers (map make-file->frame files)) (locs (make-vector files-len 0)) (pframes (make-vector files-len 0)) (current-file 0) (reading #t) (out-port (mus-audio-open-output 0 srate chans mus-lshort (* bufsize 2)))) (if (< out-port 0) (format #t "can't open audio port! ~A" out-port) (begin (do ((i 0 (+ i 1))) ((= i files-len)) (set! (pframes i) (framples (files i)))) (catch #t (lambda () (while reading (let ((next-file (driver files-len bufsize))) (if (not (= next-file current-file)) (let ((ramp-down 1.0) (ramp (/ 1.0 bufsize)) (current (readers current-file)) (current-loc (locs current-file)) (next (readers next-file)) (next-loc (locs next-file)) (up (make-frame chans)) (down (make-frame chans))) (do ((i 0 (+ i 1))) ((= i bufsize)) (file->frame next (+ next-loc i) up) (file->frame current (+ current-loc i) down) (do ((j 0 (+ 1 j))) ((= j chans)) (vector-set! data j i (+ (* ramp-down (frame-ref down j)) (* (- 1.0 ramp-down) (frame-ref up j))))) (set! ramp-down (- ramp-down ramp))) (if read-even-when-not-playing (do ((i 0 (+ i 1))) ((= i files-len)) (set! (locs i) (+ (locs i) bufsize))) (begin (set! (locs current-file) (+ (locs current-file) bufsize)) (set! (locs next-file) (+ (locs next-file) bufsize)))) (set! current-file next-file)) (let ((current (readers current-file)) (current-loc (locs current-file)) (on (make-frame chans))) (do ((i 0 (+ i 1))) ((= i bufsize)) (file->frame current (+ current-loc i) on) (do ((k 0 (+ 1 k))) ((= k chans)) (vector-set! data k i (frame-ref on k)))) (if read-even-when-not-playing (do ((i 0 (+ i 1))) ((= i files-len)) (set! (locs i) (+ (locs i) bufsize))) (set! (locs current-file) (+ (locs current-file) bufsize))))) (mus-audio-write out-port data bufsize) (set! reading (letrec ((any-data-left (lambda (f) (if (= f files-len) #f (or (< (locs f) (pframes f)) (any-data-left (+ 1 f))))))) (any-data-left 0)))))) (lambda args (begin (snd-print (format #f "error ~A" args)) (car args)))) (mus-audio-close out-port))))))) |# #| (vector-synthesis (let ((ctr 0) (file 0)) (lambda (files bufsize) (if (> ctr 4) (begin (set! file (+ 1 file)) (set! ctr 0) (if (>= file files) (set! file 0))) (set! ctr (+ ctr 1))) file)) (list "oboe.snd" "pistol.snd") #t) |# ;;; -------------------------------------------------------------------------------- ;;; old frame.scm ;;; various frame-related extensions ;;; frame-reverse! frame-copy (from mixer.scm) ;;; sound->frame frame->sound ;;; region->frame ;;; ;;; make-frame-reader frame-reader? frame-reader-at-end frame-reader-position frame-reader-home free-frame-reader copy-frame-reader frame-reader-chans ;;; next-frame previous-frame read-frame ;;; make-region-frame-reader make-selection-frame-reader ;;; make-sync-frame-reader ;;; ;;; file->frample frample->file ;;; frame->float-vector float-vector->frame ;;; ;;; insert-frame insert-float-vector ;;; mix-frame ;;; scan-sound map-sound ;;; ;;; simultaneous-zero-crossing (provide 'snd-frame.scm) (if (provided? 'snd) (require snd-ws.scm) (require sndlib-ws.scm)) (define frame-reverse! reverse) (define frame-copy copy) #| (define (frame-cross m1 m2) "(frame-cross fr1 fr2) returns the cross product (a frame) of frames fr1 and fr2" (if (or (not (= (channels m1) 3)) (not (= (channels m2) 3))) (snd-print "cross product only in 3 dimensions") (make-frame 3 (- (* (m1 1) (m2 2)) (* (m1 2) (m2 1))) (- (* (m1 2) (m2 0)) (* (m1 0) (m2 2))) (- (* (m1 0) (m2 1)) (* (m1 1) (m2 0)))))) ;;; (frame-cross (make-frame 3 0 0 1) (make-frame 3 0 -1 0)) ;;; (define (frame-normalize f) "(frame-normalize fr) scales the contents of frame fr so that its euclidean length is 1.0" (let ((mag (sqrt (dot-product (mus-data f) (mus-data f))))) (if (> mag 0.0) (frame* f (/ 1.0 mag)) f))) ;;; (frame-normalize (make-frame 3 4 3 0)) ;;; |# (define* (frame->float-vector fr v) "(frame->float-vector fr v) copies frame fr into either float-vector v or a new float-vector, returning the float-vector" (copy fr (or v (make-float-vector (length fr))))) (define* (float-vector->frame v fr) "(float-vector->frame v fr) copies float-vector v into either frame fr or a new frame, returning the frame" (copy v (or fr (make-frame (length v))))) (define frame->vct frame->float-vector) (define vct->frame float-vector->frame) (define* (sound->frame (pos 0) snd) "(sound->frame pos snd) returns a frame containing the contents of the sound snd at position pos" (let ((index (or snd (selected-sound) (car (sounds))))) (if (not (sound? index)) (error 'no-such-sound "sound->frame: ~A" snd) (let ((fr (make-frame (channels index)))) (do ((i 0 (+ i 1))) ((= i (channels index)) fr) (set! (fr i) (sample pos index i))))))) (define* (frame->sound fr (pos 0) snd) "(frame->sound fr pos snd) places the contents of frame fr into sound snd at position pos" (let ((index (or snd (selected-sound) (car (sounds))))) (if (not (sound? index)) (error 'no-such-sound "frame->sound: ~A" snd) (do ((i 0 (+ i 1))) ((= i (channels index)) fr) (set! (sample pos index i) (fr i)))))) (define (region->frame reg pos) "(region->frame pos reg) returns a frame with the contents of region reg at position pos" (if (not (region? reg)) (error 'no-such-region "region->frame: ~A" reg) (let ((fr (make-frame (channels reg)))) (do ((i 0 (+ i 1))) ((= i (channels reg)) fr) (set! (fr i) (region-sample reg pos i)))))) ;;; -------------------------------------------------------------------------------- ;;; frame-readers ;;; (defgenerator frame-sampler snd chns frm samplers) (define* (make-frame-reader (beg 0) snd dir edpos) "(make-frame-reader beg snd dir edpos) returns a frame reader, basically a sampler that reads all channels on each call" (let ((index (or snd (selected-sound) (car (sounds))))) (if (and (not (sound? index)) (not (string? index))) ; filename is a possibility here (error 'no-such-sound "make-frame-reader: ~A" snd) (let ((chns (channels index))) ; this works in both cases (make-frame-sampler index chns (make-frame chns) (let ((v (make-vector chns))) (do ((i 0 (+ i 1))) ((= i chns) v) (set! (v i) (make-sampler beg index i dir edpos))))))))) (define frame-reader? frame-sampler?) (define (frame-reader-at-end? fr) "(frame-reader-at-end? fr) -> #t if the samplers in frame-reader fr have reached the end of their respective channels" (with-let fr (call-with-exit (lambda (return) (do ((i 0 (+ i 1))) ((= i chns) #t) (if (not (sampler-at-end? (samplers i))) (return #f))))))) (define (frame-reader-position fr) "(frame-reader-position fr) -> current read position of frame-reader fr" (with-let fr (sampler-position (samplers 0)))) (define (frame-reader-home fr) "(frame-reader-home fr) -> sound object associated with frame-reader fr" (with-let fr snd)) (define (frame-reader-chans fr) "(frame-reader-chans fr) -> number of channels read by frame-reader fr" (with-let fr chns)) (define (free-frame-reader fr) "(free-frame-reader fr) frees all samplers associated with frame-reader fr" (with-let fr (do ((i 0 (+ i 1))) ((= i chns)) (free-sampler (samplers i))))) (define (copy-frame-reader fr) "(copy-frame-reader fr) returns a copy of frame-reader fr" (with-let fr (make-frame-sampler snd chns (make-frame chns) (let ((v (make-vector chns))) (do ((i 0 (+ i 1))) ((= i chns) v) (set! (v i) (copy-sampler (samplers i)))))))) (define (next-frame fr) ;; "(next-frame fr) returns the next frame as read by frame-reader fr" (with-let fr (do ((i 0 (+ i 1))) ((= i chns) frm) (set! (frm i) (next-sample (samplers i)))))) (define (previous-frame fr) "(previous-frame fr) returns the previous frame as read by frame-reader fr" (with-let fr (do ((i 0 (+ i 1))) ((= i chns) frm) (set! (frm i) (previous-sample (samplers i)))))) (define (read-frame fr) ;; "(read-frame fr) returns the next frame read by frame-reader fr taking its current read direction into account" (with-let fr (do ((i 0 (+ i 1))) ((= i chns) frm) (set! (frm i) (read-sample (samplers i)))))) (define* (make-region-frame-reader reg beg dir) "(make-region-frame-reader reg beg dir) returns a frame-reader reading the contents of region reg" (if (not (region? reg)) (error 'no-such-region "make-region-frame-reader: ~A" reg) (let ((chns (channels reg))) (make-frame-sampler reg chns (make-frame chns) (let ((v (make-vector chns))) (do ((i 0 (+ i 1))) ((= i chns) v) (set! (v i) (make-region-sampler reg beg i dir)))))))) (define* (make-sync-frame-reader (beg 0) snd dir edpos) "(make-sync-frame-reader beg snd dir edpos) returns a frame-reader that reads all channels sync'd to 'snd'" (let ((index (or snd (selected-sound) (car (sounds))))) (if (not (sound? index)) (error 'no-such-sound "make-sync-frame-reader: ~A" snd) (let ((snc (sync index))) (if (= snc 0) (make-frame-reader beg index dir edpos) (let ((chns 0)) (for-each (lambda (s) (if (= (sync s) snc) ; sync field is always an int (0 = none) (set! chns (+ chns (channels s))))) (sounds)) (make-frame-sampler index chns (make-frame chns) (let ((v (make-vector chns)) (ctr 0)) (for-each (lambda (s) (if (= (sync s) snc) (begin (do ((i 0 (+ i 1))) ((= i (channels s))) (set! (v (+ i ctr)) (make-sampler beg s i dir edpos))) (set! ctr (+ ctr (channels s)))))) (sounds)) v)))))))) (define* (make-selection-frame-reader (beg 0)) "(make-selection-frame-reader (beg 0)) returns a frame reader that reads all channels of the current selection" (if (not (selection?)) (error 'no-active-selection "make-selection-frame-reader: ~A" beg) (let ((chns (selection-chans))) (make-frame-sampler -1 chns (make-frame chns) (let ((ctr 0) (v (make-vector chns))) (for-each (lambda (snd) (do ((chn 0 (+ 1 chn))) ((= chn (channels snd))) (if (selection-member? snd chn) (begin (set! (v ctr) (make-sampler (+ beg (selection-position snd chn)) snd chn)) (set! ctr (+ ctr 1)))))) (sounds)) v))))) (define (old-file->frample file) (samples 0 (framples file) file)) (define file->vct old-file->frample) (define* (old-frample->file v file (srate 22050) (comment "")) "(frample->file v file srate comment) writes the data in float-vector v to the specified sound file" (if (float-vector? v) (let ((fd (mus-sound-open-output file srate 1 #f mus-riff comment))) (mus-sound-write fd 0 (- (length v) 1) 1 (make-shared-vector v (list 1 (length v)))) (mus-sound-close-output fd (* (mus-bytes-per-sample mus-out-format) (length v))) file) (error 'wrong-type-arg "file->frample: ~A" v))) (define vct->file old-frample->file) (define* (insert-float-vector v (beg 0) dur snd chn edpos) "(insert-float-vector v beg dur snd chn edpos) inserts float-vector v's data into sound snd at beg" (if (not (float-vector? v)) (error 'wrong-type-arg "insert-float-vector: ~A" v) (let ((len (or dur (length v)))) (insert-samples beg len v snd chn edpos #f (format #f "insert-float-vector ~A ~A ~A" (float-vector->string v) beg dur))))) (define insert-vct insert-float-vector) (define* (insert-frame fr (beg 0) snd edpos) "(insert-frame fr beg snd edpos) inserts frame fr's data into sound snd (one sample in each channel) at beg" (if (not (frame? fr)) (error 'wrong-type-arg "insert-frame: ~A" fr) (let ((index (or snd (selected-sound) (car (sounds))))) (if (not (sound? index)) (error 'no-such-sound "insert-frame: ~A" snd) (let ((chns (min (channels fr) (channels index)))) (do ((chn 0 (+ 1 chn))) ((= chn chns)) (insert-sample beg (fr chn) index chn edpos))))))) (define* (mix-frame fr (beg 0) snd) "(mix-frame fr beg snd) mixes frame fr's data into sound snd (one sample in each channel) at beg" (if (not (frame? fr)) (error 'wrong-type-arg "mix-frame: ~A" fr) (let ((index (or snd (selected-sound) (car (sounds))))) (if (not (sound? index)) (error 'no-such-sound "mix-frame: ~A" snd) (let ((chns (min (channels fr) (channels index)))) (do ((chn 0 (+ 1 chn))) ((= chn chns)) (set! (sample beg index chn) (+ (fr chn) (sample beg index chn))))))))) (define* (scan-sound func (beg 0) dur snd with-sync) "(scan-sound func beg dur snd with-sync) is like scan-channel; it passes func a frame on each call, and stops when func returns true" (let ((index (or snd (selected-sound) (car (sounds))))) (if (sound? index) (let* ((reader (if with-sync (make-sync-frame-reader beg index) (make-frame-reader beg index))) (result #f) (len (framples index)) (end (if dur (min len (+ beg dur)) len))) (do ((i beg (+ i 1))) ((or result (= i end)) (and result (list result (- i 1)))) (set! result (func (read-frame reader))))) (error 'no-such-sound "scan-sound: ~A" snd)))) (define +read-forward+ 1) (define* (map-sound func (beg 0) dur snd edpos) "(map-sound func beg dur snd edpos) is a version of map-channel that passes func a frame on each call, rather than a sample" ;; not sure map-sound with sync is a good idea -- even scale-by following sync seems bad (let ((index (or snd (selected-sound) (car (sounds))))) (if (sound? index) (let* ((out-chans (channels index)) (reader (make-frame-reader beg index +read-forward+ edpos)) (filename (snd-tempnam)) (writer (make-frame->file filename out-chans)) (len (framples index)) (end (if dur (min len (+ beg dur)) len)) (loc 0)) (do ((i beg (+ i 1))) ((= i end)) (let ((result (func (next-frame reader)))) (if result (begin (frame->file writer loc result) (set! loc (+ loc 1)))))) (mus-close writer) (free-frame-reader reader) (do ((i 0 (+ i 1))) ((= i (channels index))) (set! (samples beg loc index i #f "map-sound" i #f (= i 0)) filename))) ; edpos = #f, auto-delete = chan=0 (error 'no-such-sound "map-sound: ~A" snd)))) (define* (simultaneous-zero-crossing (beg 0) dur snd) "(simultaneous-zero-crossing :option beg dur snd) looks through all channels of 'snd' for a simultaneous zero crossing." (let ((last-fr (make-frame (channels snd)))) (scan-sound (lambda (fr) (let ((result #t)) (do ((chn 0 (+ 1 chn))) ((= chn (channels fr))) (set! result (and result (< (* (fr chn) (last-fr chn)) 0.0))) (set! (last-fr chn) (fr chn))) result)) beg dur snd))) ;;; -------------------------------------------------------------------------------- ;;; old mixer.scm ;;; mixer and frame stuff, mostly oriented toward linear algebra (see also snd-test) ;;; ;;; make-zero-mixer, mixer-diagonal?, mixer-transpose, mixer-determinant, ;;; mixer-solve, mixer-inverse, invert-matrix, mixer-trace, mixer-poly, mixer-copy (provide 'snd-mixer.scm) (define make-zero-mixer make-mixer) (define (mixer-copy umx) "(mixer-copy umx) returns a copy of its argument (a mixer)" (let* ((size (length umx)) (mx (make-mixer size))) (do ((i 0 (+ i 1))) ((= i size)) (do ((j 0 (+ j 1))) ((= j size)) (set! (mx i j) (umx i j)))) mx)) (define (mixer-diagonal? m) "(mixer-diagonal? m) returns #t if 'm' is a diagonal mixer" (let ((n (length m))) (or (= n 1) (call-with-exit (lambda (return) (do ((i 0 (+ i 1))) ((= i n) #t) (do ((j 0 (+ j 1))) ((= j n)) (if (and (not (= i j)) (not (= (m i j) 0.0))) (return #f))))))))) (define (mixer-transpose mx) "(mixer-transpose mx) returns a new mixer of 'mx' transposed" (let* ((n (length mx)) (nmx (make-zero-mixer n))) (do ((i 0 (+ i 1))) ((= i n)) (do ((j 0 (+ j 1))) ((= j n)) (set! (nmx j i) (mx i j)))) nmx)) (define (sub-matrix mx row col) "(sub-matrix mx row col) returns a portion of the matrix 'mx'" (let* ((old-n (length mx)) (new-n (- old-n 1)) (nmx (make-zero-mixer new-n))) (do ((i 0 (+ i 1)) (ni 0)) ((= i old-n)) (if (not (= i row)) (begin (do ((j 0 (+ j 1)) (nj 0)) ((= j old-n)) (if (not (= j col)) (begin (set! (nmx ni nj) (mx i j)) (set! nj (+ nj 1))))) (set! ni (+ 1 ni))))) nmx)) (define (mixer-determinant mx) "(mixer-determinant mx) returns the determinant of 'mx'" (if (not (mixer? mx)) (error 'wrong-type-arg "mixer-determinant argument should be a mixer") (let ((n (length mx))) (if (= n 1) (mx 0 0) (if (= n 2) (- (* (mx 0 0) (mx 1 1)) (* (mx 0 1) (mx 1 0))) (if (= n 3) (- (+ (* (mx 0 0) (mx 1 1) (mx 2 2)) (* (mx 0 1) (mx 1 2) (mx 2 0)) (* (mx 0 2) (mx 1 0) (mx 2 1))) (+ (* (mx 0 0) (mx 1 2) (mx 2 1)) (* (mx 0 1) (mx 1 0) (mx 2 2)) (* (mx 0 2) (mx 1 1) (mx 2 0)))) (let ((sum 0.0) (sign 1)) (do ((i 0 (+ i 1))) ((= i n)) (let ((mult (mx 0 i))) (if (not (= mult 0.0)) (set! sum (+ sum (* sign mult (mixer-determinant (sub-matrix mx 0 i)))))) (set! sign (- sign)))) sum))))))) (define* (mixer-poly mx :rest coeffs) "(mixer-poly mx :rest coeffs) returns a new mixer, the result of treating 'mx' as the argument to the polynomial defined by the 'coeffs' list" (let* ((n (length coeffs)) (nmx (make-scalar-mixer (length mx) (coeffs (- n 1)))) (x (mixer* mx 1.0))) (do ((i (- n 2) (- i 1))) ((< i 0)) (set! nmx (mixer+ nmx (mixer* x (coeffs i)))) (set! x (mixer* mx x))) nmx)) ;;; (define (float-vector-norm v1) (sqrt (dot-product v1 v1))) (define (mixer-trace mx) "(mixer-trace mx) returns the trace of 'mx'" (let ((sum 0.0) (n (length mx))) (do ((i 0 (+ i 1))) ((= i n) sum) (set! sum (+ sum (mx i i)))))) ;;; invert-matrix is in dsp.scm ;;; it would be faster to use invert-matrix to calculate the determinant (define (mixer-solve A b) "(mixer-solve A b) returns the solution of Ax=b" (let ((val (invert-matrix A b))) (and val (cadr val)))) (define (mixer-inverse A) "(mixer-inverse A) returns the inverse of 'A'" (let ((val (invert-matrix A))) (and val (car val)))) #| (define (plane p1 p2 p3) ; each p a list of 3 coords, returns list (a b c d) of ax + by + cz = 1 (d = -1) (let ((m (make-mixer 3)) (f (make-frame 3 1 1 1))) (do ((i 0 (+ i 1))) ((= i 3)) (set! (m 0 i) (p1 i)) (set! (m 1 i) (p2 i)) (set! (m 2 i) (p3 i))) (let ((b (mixer-solve m f))) (list (b 0) (b 1) (b 2) -1)))) ;;; (plane '(0 0 1) '(1 0 0) '(0 1 0)) ;;; (1.0 1.0 1.0 -1) |# ;;; backwards compatibility for snd 12 (define (mus-audio-describe) "no description available anymore") (define verbose-cursor with-verbose-cursor) (define (recorder-dialog) "recorder-dialog is obsolete") ;;; backwards compatibility for snd 11 and earlier ;;; backwards compatibility for snd 11 ;;; old Guile-style hook functions (define (hook-empty? hook) (null? (hook-functions hook))) (define (reset-hook! hook) (set! (hook-functions hook) ())) ;(define (run-hook . args) ; (hook-apply (car args) (cdr args))) (define hook->list hook-functions) (define* (add-hook! hook func at-end) (set! (hook-functions hook) (if (not at-end) (cons func (hook-functions hook)) (append (hook-functions hook) (list func))))) (define (remove-hook! hook func) (set! (hook-functions hook) (let loop ((l (hook-functions hook)) (result ())) (cond ((null? l) (reverse! result)) ((eq? func (car l)) (loop (cdr l) result)) (else (loop (cdr l) (cons (car l) result))))))) ;;; these are carried forward from snd10.scm (define sine-summation nrxysin) (define sine-summation? nrxysin?) (define sum-of-sines nsin) (define sum-of-sines? nsin?) (define sum-of-cosines ncos) (define sum-of-cosines? ncos?) (define* (make-sum-of-sines (sines 1) (frequency 0.0) (initial-phase 0.0)) (let ((gen (make-nsin :frequency frequency :n sines))) (set! (mus-phase gen) initial-phase) gen)) (define* (make-sum-of-cosines (cosines 1) (frequency 0.0) (initial-phase 0.0)) (let ((gen (make-ncos :frequency frequency :n cosines))) (set! (mus-phase gen) initial-phase) gen)) (define* (make-sine-summation (frequency 0.0) (initial-phase 0.0) (n 1) (a 0.5) (ratio 1.0)) (let ((gen (make-nrxysin :frequency frequency :ratio ratio :n n :r a))) (set! (mus-phase gen) initial-phase) gen)) (if (not (defined? 'in-hz)) (define in-hz hz->radians)) (define copy-sample-reader copy-sampler) (define free-sample-reader free-sampler) (define make-mix-sample-reader make-mix-sampler) (define make-region-sample-reader make-region-sampler) (define make-sample-reader make-sampler) (define mix-sample-reader? mix-sampler?) (define region-sample-reader? region-sampler?) (define sample-reader-at-end? sampler-at-end?) (define sample-reader-home sampler-home) (define sample-reader? sampler?) (define sample-reader-position sampler-position) ;;; -------- with-mix -------- ;;; ;;; weird syntax = with-mix (with-sound-args) file-name start-in-output &body body ;;; ;;; (with-sound () ;;; (with-mix () "section-1" 0 (fm-violin 0 1 440 .1) ;;; (fm-violin 1 2 660 .1)) ;;; ...) (define with-mix-find-file-with-extensions (let ((documentation "(with-mix-find-file-with-extensions file extensions) helps the with-mix macro find checkpoint files")) (lambda (file extensions) (if (file-exists? file) file (call-with-exit (lambda (found-one) (for-each (lambda (ext) (let ((new-file (string-append file "." ext))) (if (file-exists? new-file) (found-one new-file)))) extensions) #f)))))) (define with-mix-file-extension (let ((documentation "(with-mix-file-extension file default) is a helper function for the with-mix macro")) (lambda (file default) (let ((len (length file))) (call-with-exit (lambda (ok) (do ((i (- len 1) (- i 1))) ((= i 0)) (if (char=? (file i) #\.) (ok (substring file (+ 1 i) len)))) default)))))) (define-macro (with-mix options ur-chkpt-file ur-beg . body) `(let ((chkpt-file ,ur-chkpt-file) (beg-1 ,ur-beg)) (if (not (list? ',options)) (throw 'with-sound-interrupt (format #f "with-mix options list (arg 1) is ~A?~%;" ',options)) (if (not (string? chkpt-file)) (throw 'with-sound-interrupt (format #f "with-mix file (arg 2) is ~A?~%;" ,ur-chkpt-file)) (if (not (number? beg-1)) (throw 'with-sound-interrupt (format #f "with-mix begin time (arg 3) for ~S = ~A?~%;" chkpt-file beg-1)) (let ((beg (round (* *clm-srate* beg-1)))) (if (null? ',body) (mus-file-mix *output* chkpt-file beg) (let* ((call-str (object->string ',body)) (option-str (object->string ',options)) (sndf (with-mix-find-file-with-extensions chkpt-file (list (with-mix-file-extension *clm-file-name* "snd") "snd"))) (revf (and sndf *reverb* (with-mix-find-file-with-extensions chkpt-file (list "rev")))) (mix-values (and sndf (or (not *reverb*) revf) (let ((comment (mus-sound-comment sndf))) (and (string? comment) (catch #t (lambda () (eval-string comment)) (lambda args #f))))))) ; any error means we lost (if (and sndf (or (not *reverb*) revf) (list? mix-values) (= (length mix-values) 2) (string? (car mix-values)) (string? (cadr mix-values)) (string=? (car mix-values) option-str) (string=? (cadr mix-values) call-str)) (begin (if *clm-verbose* (snd-print (format #f "mix ~S at ~,3F~%" sndf beg))) (mus-file-mix *output* sndf beg) (if revf (mus-file-mix *reverb* revf beg))) ;; else recompute (let ((old-to-snd *to-snd*)) (set! *to-snd* #f) (if *clm-verbose* (snd-print (format #f "remake ~S at ~,3F~%" chkpt-file beg))) (let ((new-snd (apply with-sound-helper (lambda () ,@body) (append (list :output (string-append chkpt-file "." (with-mix-file-extension *clm-file-name* "snd"))) (list :comment (format #f "(begin~%;; written ~A (Snd: ~A)~%(list ~S ~S))~%" (strftime "%a %d-%b-%Y %H:%M %Z" (localtime (current-time))) (snd-version) option-str call-str)) (if (and (> (channels *output*) 1) (not (member :channels ',options))) (list :channels (channels *output*)) ()) ',options)))) (set! *to-snd* old-to-snd) (mus-file-mix *output* new-snd beg) (if revf (mus-file-mix *reverb* revf beg))))))))))))) #| ;;; this is the with-mix documentation:

with-mix

with-mix is a "checkpointing" version of with-sound, more useful in the bad old days when computers were incredibly slow, but lingering on... It is a macro, callable within with-sound or clm-load, which saves the computation in its body in a separate file, and then upon a subsequent recomputation, tries to tell (via a string comparison) when that file's data is up to date and does not need to be recomputed.

(with-sound () 
  (fm-violin 0 .1 440 .1)
  (with-mix () "sec1" .5 
    (fm-violin 0 .1 550 .1)
    (fm-violin .1 .1 660 .1))
  (with-mix (:reverb jc-reverb) "sec2" 1.0
    (fm-violin 0 .1 880 .1 :reverb-amount .2)
    (fm-violin .1 .1 1320 .1 :reverb-amount .2))
  (fm-violin 2 .1 220 .1)
  (mix "/zap/slow.snd"))

Now, if we change just the first note in the with-mix call, the second with-mix section will not be recomputed, but will be mixed in from the saved file "sec2.snd". In the old days, when notes took hours to compute, this was a big deal, but not anymore.

;;; and these are the regression tests (define (check-with-mix num dur total-dur amp opts calls old-date chkmx) (let ((ind (find-sound "test.snd"))) (if (not (sound? ind)) (snd-display #__line__ ";with-mix (~A) init: no test.snd?" num)) (if (and chkmx (fneq (maxamp ind) amp)) (snd-display #__line__ ";with-mix (~A) maxamp: ~A (~A)" num (maxamp ind) amp)) (if (not (file-exists? "with-mix.snd")) (snd-display #__line__ ";with-mix (~A) output doesn't exist" num)) (let ((mx (mus-sound-maxamp "with-mix.snd")) (date (mus-sound-write-date "with-mix.snd")) (duration (mus-sound-duration "with-mix.snd"))) (if (fneq duration dur) (snd-display #__line__ ";with-mix (~A) dur: ~A ~A" num dur duration)) (if (fneq total-dur (/ (framples ind) (srate ind))) (snd-display #__line__ ";with-mix (~A) total dur: ~A ~A" num total-dur (/ (framples ind) (srate ind)))) (if (and old-date (> (- date old-date) 1)) ; these can be off by some amount in Linux (snd-display #__line__ ";with-mix (~A) rewrote output?: ~A ~A ~A" num (- date old-date) (strftime "%d-%b-%g %H:%M:%S" (localtime old-date)) (strftime "%d-%b-%g %H:%M:%S" (localtime date)))) (if (and chkmx (or (not mx) (fneq (cadr mx) amp))) (snd-display #__line__ ";with-mix sndf (~A) maxamp: ~A (~A)" num mx amp)) (let ((header-str (mus-sound-comment "with-mix.snd"))) (if (not (string? header-str)) (snd-display #__line__ ";with-mix (~A) comment unwritten?: ~A" num (mus-sound-comment "with-mix.snd"))) (let ((header (eval-string header-str))) (if (not (list? header)) (snd-display #__line__ ";with-mix (~A) comment: ~A -> ~A" num header-str header)) (if (or (not (string=? (car header) opts)) (not (string=? (cadr header) calls))) (snd-display #__line__ ";with-mix (~A) header values: ~A" num header)))) (close-sound ind) date))) (if (file-exists? "with-mix.snd") (delete-file "with-mix.snd")) (with-sound () (with-mix () "with-mix" 0 (fm-violin 0 .1 440 .1))) (let ((old-date (check-with-mix 1 .1 .1 .1 "()" "((fm-violin 0 0.1 440 0.1))" #f #t))) (with-sound () (with-mix () "with-mix" 0 (fm-violin 0 .1 440 .1))) (check-with-mix 1 .1 .1 .1 "()" "((fm-violin 0 0.1 440 0.1))" old-date #t)) (if (file-exists? "with-mix.snd") (delete-file "with-mix.snd")) (with-sound () (fm-violin 0 .1 660 .1) (with-mix () "with-mix" .1 (fm-violin 0 .1 440 .1))) (let ((old-date (check-with-mix 2 .1 .2 .1 "()" "((fm-violin 0 0.1 440 0.1))" #f #t))) (with-sound () (fm-violin 0 .1 660 .1) (with-mix () "with-mix" .1 (fm-violin 0 .1 440 .1))) (check-with-mix 2 .1 .2 .1 "()" "((fm-violin 0 0.1 440 0.1))" old-date #t)) (if (file-exists? "with-mix.snd") (delete-file "with-mix.snd")) (with-sound () (fm-violin 0 .1 660 .1) (with-mix () "with-mix" .1 (fm-violin 0 .1 440 .1) (fm-violin .1 .1 660 .2))) (let ((old-date (check-with-mix 3 .2 .3 .2 "()" "((fm-violin 0 0.1 440 0.1) (fm-violin 0.1 0.1 660 0.2))" #f #t))) (with-sound () (fm-violin 0 .1 660 .1) (with-mix () "with-mix" .1 (fm-violin 0 .1 440 .1) (fm-violin .1 .1 660 .2))) (check-with-mix 3 .2 .3 .2 "()" "((fm-violin 0 0.1 440 0.1) (fm-violin 0.1 0.1 660 0.2))" old-date #t)) (if (file-exists? "with-mix.snd") (delete-file "with-mix.snd")) (with-sound () (with-mix () "with-mix" 0 (sound-let ((tmp () (fm-violin 0 1 440 .1))) (mus-file-mix *output* tmp 0)))) (let ((old-date (check-with-mix 4 1 1 .1 "()" "((sound-let ((tmp () (fm-violin 0 1 440 0.1))) (mus-file-mix *output* tmp 0)))" #f #t))) (with-sound () (with-mix () "with-mix" 0 (sound-let ((tmp () (fm-violin 0 1 440 .1))) (mus-file-mix *output* tmp 0)))) (check-with-mix 4 1 1 .1 "()" "((sound-let ((tmp () (fm-violin 0 1 440 0.1))) (mus-file-mix *output* tmp 0)))" old-date #t)) (if (file-exists? "with-mix.snd") (delete-file "with-mix.snd")) (with-sound (:channels 2) (fm-violin 0 .1 440 .1 :degree 0) (with-mix () "with-mix" 0 (fm-violin 0 .1 550 .3 :degree 90))) (let ((ind (find-sound "test.snd"))) (if (or (fneq (maxamp ind 0) .1) (fneq (maxamp ind 1) .3)) (snd-display #__line__ ";with-mix stereo: ~A" (maxamp ind #t))) (if (not (= (mus-sound-chans "with-mix.snd") 2)) (snd-display #__line__ ";with-mix stereo out: ~A" (mus-sound-chans "with-mix.snd")))) (let ((old-date (mus-sound-write-date "with-mix.snd"))) (with-sound (:channels 2) (fm-violin 0 .1 440 .1 :degree 0) (with-mix () "with-mix" 0 (fm-violin 0 .1 550 .3 :degree 90))) (if (not (= (mus-sound-write-date "with-mix.snd") old-date)) (snd-display #__line__ ";stereo with-mix dates: ~A ~A" old-date (mus-sound-write-date "with-mix.snd")))) (let ((ind (find-sound "test.snd"))) (close-sound ind)) (if (file-exists? "with-mix.snd") (delete-file "with-mix.snd")) (with-sound (:reverb jc-reverb) (fm-violin 0 .1 440 .1) (with-mix () "with-mix" 0 (fm-violin 0 .1 550 .3))) (let ((old-date (check-with-mix 6 .1 1.1 .398 "()" "((fm-violin 0 0.1 550 0.3))" #f #f))) (with-sound (:reverb jc-reverb) (fm-violin 0 .1 440 .1) (with-mix () "with-mix" 0 (fm-violin 0 .1 550 .3))) (check-with-mix 6 .1 1.1 .398 "()" "((fm-violin 0 0.1 550 0.3))" old-date #f)) |# ;;; -------------------------------------------------------------------------------- (define (focus-follows-mouse) (set! *with-pointer-focus* #t)) (define (make-current-window-display) (set! *with-inset-graph* #t)) (define load-from-path load) ;(define def-optkey-fun define*) ;(define def-optkey-instrument definstrument) (define spectro-cutoff spectrum-start) (define spectro-end spectrum-end) (define* (play-region reg wait stop-func) (play (if (integer? reg) (integer->region reg) reg) :wait wait :stop stop-func)) (define* (play-selection wait stop-func) (play (selection) :wait wait :stop stop-func)) (define* (play-mix id (beg 0)) (play (if (integer? id) (integer->mix id) id) beg)) (define* (play-and-wait (start 0) snd chn syncd end (pos -1) stop-proc) (if (string? start) (play start (or snd 0) :end (or chn -1) :wait #t) (play (if (integer? snd) (integer->sound snd) (if (sound? snd) snd (or (selected-sound) (car (sounds))))) :channel (or chn -1) :wait #t :with-sync syncd :start start :end (or end -1) :stop stop-proc :edit-position pos))) (define* (old-play (start 0) snd chn syncd end (pos -1) stop-proc (out-chan -1)) (play (if (integer? snd) (integer->sound snd) (if (sound? snd) snd (or (selected-sound) (car (sounds))))) :channel (or chn -1) :with-sync syncd :start start :end (or end -1) :stop stop-proc :out-channel out-chan :edit-position pos)) (define* (play-channel (beg 0) dur snd chn (pos -1) stop-proc (out-chan -1)) (play (if (integer? snd) (integer->sound snd) (if (sound? snd) snd (or (selected-sound) (car (sounds))))) :channel (or chn -1) :with-sync #f :start beg :end (if dur (+ beg dur) -1) :stop stop-proc :out-channel out-chan :edit-position pos)) ;;; -------------------------------------------------------------------------------- (define (add-watcher func) (hook-push effects-hook func)) (define (delete-watcher func) (hook-remove effects-hook func)) (define clear-selection unselect-all) (define cursor-follows-play with-tracking-cursor) snd-16.1/clean.scm0000644000076400007640000003240312621406747012134 0ustar bilbil;; clean-channel -- noise reduction (provide 'snd-clean.scm) (require snd-dsp.scm snd-generators.scm) (define goertzel-channel (let ((documentation "(goertzel-channel freq beg dur snd (chn 0)) returns the amplitude of the 'freq' spectral component")) (lambda* (freq (beg 0) dur snd chn) (let* ((sr (srate snd)) (rfreq (/ (* 2.0 pi freq) sr)) (cs (* 2.0 (cos rfreq)))) (let ((reader (make-sampler beg snd chn)) (len (- (if (number? dur) dur (- (framples snd chn) beg)) 2)) (flt (make-two-pole 1.0 (- cs) 1.0))) (do ((i 0 (+ i 1))) ((= i len)) (two-pole flt (next-sample reader))) (let ((y1 (two-pole flt (next-sample reader))) (y0 (two-pole flt (next-sample reader)))) (magnitude (- y0 (* y1 (exp (complex 0.0 (- rfreq)))))))))))) (define* (check-freq freq snd chn) (let ((hum 0.0)) (do ((i 0 (+ i 1)) (loc 0.0 (+ loc (round (/ (framples snd chn) 5))))) ((= i 4)) (set! hum (+ hum (goertzel-channel freq loc 2048 snd chn)))) (/ hum 4.0))) ;;; -------- single sample clicks (define* (remove-single-sample-clicks (jump 8) snd chn) (let* ((reader (make-sampler 0 snd chn)) (mx (make-moving-average 16)) ; local average of abs difference (samp0 0.0) (samp1 0.0) (samp2 0.0) (fixed 0) (len (framples snd chn)) (block-size (min len (* 1024 1024))) ; do edits by blocks rather than sample-at-a-time (saves time, memory etc) (block-ctr 0) (block-beg 0) (block (make-float-vector block-size)) (block-changed #f)) (do ((ctr 0 (+ ctr 1))) ((= ctr len)) (set! samp0 samp1) (set! samp1 samp2) (set! samp2 (next-sample reader)) (set! (block block-ctr) samp2) (let* ((df1 (abs (- samp1 samp0))) (df2 (abs (- samp2 samp1))) (df3 (abs (- samp2 samp0))) (local-max (moving-average mx df1))) (if (and (> df1 (* jump local-max)) (> df2 (* jump local-max)) (or (< df3 local-max) (and (< df3 (* 2 local-max)) (< (* (- samp2 samp0) (- samp1 samp0)) 0.0)))) (begin (set! samp1 (* .5 (+ samp0 samp2))) (set! (block (- block-ctr 1)) samp1) (set! block-changed #t) (set! fixed (+ 1 fixed))))) (set! block-ctr (+ 1 block-ctr)) (if (>= block-ctr block-size) (begin (if block-changed (begin (float-vector->channel block block-beg block-size snd chn) (set! block-changed #f))) (set! block-beg (+ block-beg (- block-size 1))) (set! block-ctr 1) (set! (block 0) samp2)))) (if block-changed (float-vector->channel block block-beg block-ctr snd chn)) fixed)) (define (test-remove-single-clicks) (let ((test (new-sound "test.snd"))) (let ((data (make-float-vector 1001))) (do ((i 2 (+ i 30)) (val .9 (- val .05))) ((>= i 1000)) (float-vector-set! data i val)) (set! (data 1000) .001) (float-vector->channel data) (remove-single-sample-clicks) (let ((mx (maxamp)) (loc (maxamp-position))) (if (> mx 0.06) (format #t "~%;remove-single-sample-clicks 0: ~A (at ~D)" mx loc))) (revert-sound) (do ((i 0 (+ i 1)) (ang 0.0 (+ ang .01))) ((= i 1000)) (float-vector-set! data i (+ (float-vector-ref data i) (* .2 (sin ang))))) (float-vector->channel data) (remove-single-sample-clicks) (if (fneq (maxamp) .2) (format #t "~%;remove-single-sample-clicks sin max: ~A" (maxamp))) (let ((cur-data (channel->float-vector 0)) (diff 0.0)) (do ((i 0 (+ i 1)) (ang 0.0 (+ ang .01))) ((= i 1000)) (set! diff (max diff (abs (- ( cur-data i) (* .2 (sin ang))))))) (if (> diff .2) (format #t "~%;remove-single-sample-clicks sine max diff: ~A" diff)))) (close-sound test))) ;;; -------- pops (define* (smooth-float-vector data beg dur) (let* ((y0 (data beg)) (y1 (data (+ beg dur))) (angle (if (> y1 y0) pi 0.0)) (off (* .5 (+ y0 y1))) (scale (* 0.5 (abs (- y1 y0)))) (incr (/ pi dur))) (do ((i 0 (+ i 1))) ((= i dur)) (set! (data (+ beg i)) (+ off (* scale (cos (+ angle (* i incr))))))))) (define* (remove-pops (size 8) snd chn) (let* ((reader (make-sampler 0 snd chn)) (dly0 (make-delay (* 4 size))) (dly1 (make-delay (* 5 size))) (mx-ahead (make-moving-average (* 4 size))) ; local average of abs difference ahead of current window (mx-behind (make-moving-average (* 4 size))) ; local average of abs difference behind current window (mx (make-moving-average size)) ; local average of abs difference (last-ahead-samp 0.0) (last-dly0-samp 0.0) (last-dly1-samp 0.0) (last-case 0) (fixed 0) (len (framples snd chn)) (pad (* 8 size)) (block-size (min (+ len pad) (* 1024 1024))) (block-ctr 0) (block-beg 0) (block (make-float-vector block-size)) (block-changed #f)) (let ((check-val 0.0) (check-start 0) (checker 0) (checked 0) (checking #f) (moving-start #t)) (do ((ctr 0 (+ ctr 1))) ((= ctr len)) (let* ((ahead-samp (next-sample reader)) (diff-ahead (abs (- ahead-samp last-ahead-samp))) (avg-ahead (moving-average mx-ahead diff-ahead)) (dly0-samp (delay dly0 ahead-samp)) (cur-diff (abs (- dly0-samp last-dly0-samp))) (cur-avg (moving-average mx cur-diff)) (dly1-samp (delay dly1 ahead-samp)) (diff-behind (abs (- dly1-samp last-dly1-samp))) (avg-behind (moving-average mx-behind diff-behind))) (set! last-ahead-samp ahead-samp) (set! last-dly0-samp dly0-samp) (set! last-dly1-samp dly1-samp) (set! (block block-ctr) ahead-samp) (if checking (begin (set! checked (+ checked 1)) (if (or (>= checked (* 2 size)) (< cur-avg check-val)) (begin (set! fixed (+ fixed 1)) (set! checking #f) (smooth-float-vector block (- check-start block-beg) (+ size checker)) (set! block-changed #t))) (if moving-start (begin (set! moving-start (< cur-diff avg-behind)) (if moving-start (set! check-start (+ check-start 1))))) (if (not moving-start) (set! checker (+ checker 1)))) (if (and (> (- ctr last-case) (* 2 size)) (> cur-avg (* 4 avg-ahead)) (> cur-avg (* 4 avg-behind))) ;; possible pop (begin (set! check-start (max 0 (- ctr (* 5 size)))) (set! moving-start (< cur-diff avg-behind)) (if moving-start (set! check-start (+ check-start 1))) (set! checking #t) (set! check-val cur-avg) (set! checker 0) (set! checked 0) (set! last-case ctr)))) (set! block-ctr (+ block-ctr 1)) (if (>= (+ block-ctr pad) block-size) (begin (if block-changed (begin (float-vector->channel block block-beg (- block-ctr pad) snd chn) (set! block-changed #f))) (set! block-beg (+ block-beg (- block-ctr pad))) (do ((i 0 (+ i 1)) (j (- block-ctr pad) (+ j 1))) ((= i pad)) (set! (block i) (block j))) (set! block-ctr pad))))) (if block-changed (float-vector->channel block block-beg block-ctr snd chn))) fixed)) (define (test-remove-pops) (new-sound "test.snd") (let ((data (make-float-vector 4001))) (do ((i 100 (+ i 200))) ((>= i 3800)) (let ((size (random 8))) (do ((k 0 (+ k 1))) ((= k size)) (set! (data (+ i k)) (mus-random 1.0))))) (float-vector->channel data) (remove-pops) (let ((mx (maxamp))) (if (> mx .01) (format #t "~%;test remove-pops 0 case: ~A" mx))) (revert-sound) (do ((i 0 (+ i 1)) (ang 0.0 (+ ang .01))) ((= i 4000)) (set! (data i) (+ (data i) (* .2 (sin ang))))) (float-vector->channel data) (remove-pops) (let ((mx (maxamp))) (if (fneq mx .2) (format #t "~%;test remove-pops sine case: ~A" mx))) (close-sound))) ;;; -------- hum (define (test-notch-hum) (let ((test (with-sound ("test.snd" :srate 22050) (let ((osc (make-oscil 60.0)) (e (make-env '(0 0 1 .5 9 .5 10 0) :length 44100))) (do ((i 0 (+ i 1))) ((= i 44100)) (outa i (* (env e) (oscil osc)))))))) (notch-channel (list 60.0) #f #f #f #f #f #f #t 8) (let ((mx (maxamp))) (if (> mx .02) (format #t "~%;notch hum 0: ~A" mx))) (close-sound (find-sound test))) (let ((test (with-sound ("test.snd" :srate 22050) (let ((p (make-polywave 20.0 (list 2 1 3 1 4 1))) (e (make-env '(0 0 1 .3 9 .3 10 0) :scaler 1/3 :length 44100))) (do ((i 0 (+ i 1))) ((= i 44100)) (outa i (* (env e) (polywave p)))))))) (let ((v60 (goertzel 60.0)) (v40 (goertzel 40.0)) (v80 (goertzel 80.0))) (notch-channel (list 60.0) #f #f #f #f #f #f #t 8) (let ((e60 (goertzel 60.0)) (e40 (goertzel 40.0)) (e80 (goertzel 80.0))) (if (or (fneq (/ e60 v60) 0.0) (fneq (/ e40 v40) 1.0) (fneq (/ e80 v80) 1.0)) (format #t "~%;notch 60: ~A ~A ~A -> ~A ~A ~A" v40 v60 v80 e40 e60 e80)))) (close-sound (find-sound test))) (let ((test (with-sound ("test.snd" :srate 22050) (let ((p (make-polywave 5.0 (list 11 1 12 1 13 1))) (e (make-env '(0 0 1 .3 9 .3 10 0) :scaler 1/3 :length 44100))) (do ((i 0 (+ i 1))) ((= i 44100)) (outa i (* (env e) (polywave p)))))))) (let ((v60 (goertzel 60.0)) (v40 (goertzel 55.0)) (v80 (goertzel 65.0))) (notch-channel (list 60.0) #f #f #f #f #f #f #t 2) (let ((e60 (goertzel 60.0)) (e40 (goertzel 55.0)) (e80 (goertzel 65.0))) (if (or (> (/ e60 v60) 0.01) (< (/ e40 v40) 0.99) (< (/ e80 v80) 0.99)) (format #t "~%;notch 60 tight: ~A ~A ~A -> ~A ~A ~A" v40 v60 v80 e40 e60 e80)))) (close-sound (find-sound test)))) ;;; -------- DC (define (test-remove-DC) (let ((test (new-sound "test.snd")) (data (make-float-vector 4001))) (do ((i 0 (+ i 1)) (ang 0.0 (+ ang .01))) ((= i 4000)) (float-vector-set! data i (+ .1 (mus-random 0.1) (* .2 (sin ang))))) (float-vector->channel data) (let ((dc (goertzel 0.0)) (sig (goertzel 35.0))) (let ((dcflt (make-filter 2 (float-vector 1 -1) (float-vector 0 -0.99)))) (map-channel (lambda (y) (filter dcflt y))) (let ((ndc (goertzel 0.0)) (nsig (goertzel 35.0))) (if (or (> (/ ndc dc) .1) (< (/ nsig sig) .4)) (format #t "~%;remove-DC: ~A -> ~A (~A), ~A -> ~A (~A)" dc ndc (/ ndc dc) sig nsig (/ nsig sig)))))) (close-sound test))) (define* (tvf-channel snd chn) (let* ((size (framples snd chn)) (avg-data (make-float-vector size)) (ctr 0) (mx (maxamp snd chn)) (avg-size 8192) (rd0 (make-sampler 0 snd chn)) (xhat 0.0) (frm (make-formant :radius (- 1.0 (/ 500.0 (srate snd))) :frequency 600)) (del (make-moving-sum avg-size)) (K 0.0) (maxg 0.0) (ming 1000.0) (maxK 0.0) (minK 1000.0) ) (do ((i 0 (+ i 1))) ((= i avg-size)) (moving-sum del (formant frm (rd0)))) (map-channel (lambda (datum) (let ((xhatminus xhat) (avg (moving-sum del (formant frm (rd0))))) (set! K (min 1.0 (+ .1 (/ avg 100.0)))) ; (set! K .5) (set! (avg-data ctr) K) (set! ctr (+ ctr 1)) (set! maxg (max maxg avg)) (set! ming (min ming avg)) (set! maxK (max maxK K)) (set! minK (min minK K)) (set! xhat (+ xhatminus (* K (- datum xhatminus)))) xhatminus)) 0 size snd chn) (let ((mx1 (maxamp snd chn))) (scale-channel (/ mx mx1) snd chn)) ; (format #t ";K ~A to ~A, avg ~A to ~A" minK maxK ming maxg) ; avg-data )) (define* (clean-channel snd chn) ;; look for obvious simple clicks (let ((clicks (as-one-edit (lambda () (remove-single-sample-clicks 8 snd chn))))) (if (> clicks 0) (format #t "~%; fixed ~D single sample clicks" clicks) (format #t "~%; no single-sample clicks found"))) ;; look for obvious clipping and try to reconstruct (let ((mx (maxamp snd chn))) (if (>= mx 1.0) (let ((clips (unclip-channel snd chn))) (if (eq? clips 'no-clips) (format #t "~%; no clipped portions found") (format #t "~%; reconstructed ~D clipped portions" (list-ref clips 3)))) (format #t "~%; no obvious clipping (max amp: ~A)" mx))) ;; look for pops (let ((total-pops 0)) (call-with-exit (lambda (quit) (for-each (lambda (size) (let ((pops (as-one-edit (lambda () (remove-pops size snd chn))))) (set! total-pops (+ total-pops pops)) (if (> pops 0) (format #t "~%; fixed ~D ~D-sample ~A" pops size (if (= pops 1) "pop" "pops")) (quit)))) (list 4 8 16 32)))) (if (= total-pops 0) (format #t "~%; no pops found"))) ;; look for hum (let* ((hum60 (check-freq 60.0 snd chn)) (hum55 (check-freq 55.0 snd chn)) (hum (max hum60 hum55))) (if (> hum 30.0) (let ((humf (if (> hum60 hum55) 60.0 55.0))) (notch-channel (list humf) 4096 0 (framples snd chn) snd chn #f #t 4) (format #t "~%; notch out ~D cycle hum: ~A -> ~A" (floor humf) hum (check-freq humf snd chn))))) ;; look for DC (let ((dc (check-freq 0.0 snd chn))) (if (> dc 30.0) (let ((dcflt (make-filter 2 (float-vector 1 -1) (float-vector 0 -0.99)))) (map-channel (lambda (y) (filter dcflt y)) 0 (framples snd chn) snd chn) (format #t "~%; block DC: ~A -> ~A" dc (check-freq 0.0 snd chn))))) ;; time-varying low-pass filter (tvf-channel snd chn) ) (define* (clean-sound snd) (let ((index (or snd (selected-sound) (car (sounds))))) (if (not (sound? index)) (error 'no-such-sound (list "clean-sound" snd)) (let ((chns (channels index))) (do ((chn 0 (+ chn 1))) ((= chn chns)) (clean-channel index chn)))))) snd-16.1/CM_patterns.scm0000644000076400007640000012432012542022034013252 0ustar bilbil;;; ********************************************************************** ;;; Copyright (c) 2008, 2009 Rick Taube. ;;; This program is free software; you can redistribute it and/or modify ;;; it under the terms of the Lisp Lesser Gnu Public License. The text of ;;; this agreement is available at http://www.cliki.net/LLGPL ;;; ********************************************************************** ;;; [2015-06-11, AV]: adapting to stand-alone loading in a running 's7' (i.e. snd), start ;;; snd, then load this file (require r7rs.scm) ;; some functions collect from various places (s7.scm, utilities.scm) (define-macro (with-optkeys spec . body) ((lambda (user rawspec body) (define (string->keyword str) (symbol->keyword (string->symbol str))) (define (key-parse-clause info mode args argn user) ;; return a cond clause that parses one keyword. info for each ;; var is: ( ) (let* ((got (car info)) (var (cadr info)) (key (string->keyword (symbol->string var)))) `((eq? (car ,args) ,key ) (if ,got (error "duplicate keyword: ~S" , key)) (set! ,var (if (null? (cdr ,args)) (error "missing value for keyword: ~S" , user) (cadr ,args))) (set! ,got #t) ; mark that we have a value for this param (set! ,mode #t) ; mark that we are now parsing keywords (set! ,argn (+ ,argn 1)) (set! ,args (cddr ,args))))) (define (pos-parse-clause info mode args argn I) ;; return a cond clause that parses one positional. info for ;; each var is: ( ) (let ((got (car info)) (var (cadr info))) `((= ,argn ,I) (set! ,var (car ,args)) (set! ,got #t) ; mark that we have a value for this param (set! ,argn (+ ,argn 1)) (set! ,args (cdr ,args))))) (let* ((otherkeys? (member '&allow-other-keys rawspec)) ;; remove &allow-other-keys from spec (spec (if otherkeys? (reverse (cdr (reverse rawspec))) rawspec)) (data (map (lambda (v) ;; for each optkey variable v return a list ;; ( ) where the ;; variable indicates that has been ;; set, is the optkey variable itself ;; and is its default value (if (pair? v) (cons (gensym (symbol->string (car v))) v) (list (gensym (symbol->string v)) v #f))) spec)) (args (gensym "args")) ; holds arg data as its parsed (argn (gensym "argn")) (SIZE (length data)) (mode (gensym "keyp")) ; true if parsing keywords ;; keyc are cond clauses that parse valid keyword (keyc (map (lambda (d) (key-parse-clause d mode args argn user)) data)) (posc (let lup ((tail data) (I 0)) (if (null? tail) (list) (cons (pos-parse-clause (car tail) mode args argn I) (lup (cdr tail) (+ I 1)))))) (bindings (map cdr data)) ; optkey variable bindings ) (if otherkeys? (set! bindings (cons '(&allow-other-keys (list)) bindings))) `(let* ,bindings ; bind all the optkey variables with default values ;; bind status and parsing vars (let ,(append (map (lambda (i) (list (car i) #f)) data) `((,args ,user) (,argn 0) (,mode #f))) ;; iterate arglist and set opt/key values (do () ((null? ,args) #f) (cond ;; add valid keyword clauses first ,@ keyc ;; a keyword in (car args) is now either added to ;; &allow-other-keys or an error , (if otherkeys? `((keyword? (car ,args)) (if (not (pair? (cdr ,args))) (error "missing value for keyword ~S" (car ,args))) (set! &allow-other-keys (append &allow-other-keys (list (car ,args) (cadr ,args)))) (set! ,mode #t) ; parsing keys now... (set! ,args (cddr ,args)) ) `((keyword? (car ,args)) ;(and ,mode (keyword? (car ,args))) (error "invalid keyword: ~S" (car ,args)) ) ) ;; positional clauses illegal if keywords have happened (,mode (error "positional after keywords: ~S" (car ,args))) ;; too many value specified ((not (< ,argn ,SIZE)) (error "too many args: ~S" , args)) ;; add the valid positional clauses ,@ posc )) ,@ body)) )) (car spec) (cdr spec) body )) ;;; based on define-record-type from snd/r7rs.scm. Works with srfi-17? (define-macro (define-record typename . fields) `(define-record-type ,typename (,(symbol (format #f "make-~A" typename)) ,@fields) ,(symbol (format #f "~A?" typename)) ,@(map (lambda (x) `(,x ,(symbol (format #f "~A-~A" typename x)) ,(symbol (format #f "~A-~A-set!" typename x)))) fields))) ;; grabbed from s7.scm: (define (string->keyword s) (make-keyword s)) (define (logtest a b) (not (zero? (logand a b)))) (define sort sort!) ;; grabbed from utilities.scm: (define (list-index p l) (do ((tail l (cdr tail)) (i 0 (+ i 1)) (f #f)) ((or f (null? tail )) f) (if ( p (car tail)) (set! f i)))) ;; (autoload 'with-optkeys "scm/utilities.scm") ; + quite some others ;; (autoload 'string->keyword "scm/s7.scm") ;; scm/toolboox.scm: (define (decimals value places) (let ((n (expt 10.0 places))) (if (list? value) (map (lambda (v) (/ (round (* v n)) n)) value) (/ (round (* value n)) n)))) ;;; ;;; patterns using structs instead of classes. ;;; requires with-optkeys, arithmetic-test, list-set, tb:rani tb:ranf ;;; ;;; ;;; [AV, 2015-06-11]: various ffi_ random functions are substituded ;;; with schemes standard random (define-constant +constant-data+ (ash 1 0)) ; avoid hair when possible (define-constant +default-period+ (ash 1 1)) ; no period specified (define-constant +constant-weights+ (ash 1 2)) ; avoid random index recalc (define-constant +count-periods+ (ash 1 3)) ; period counts subperiods (define-constant +count-values+ (ash 1 4)) ; period counts values (define-constant +depth-first+ (ash 1 5)) ; pattern moves on eop (define-constant +breadth-first+ (ash 1 6)) ; pattern moves each time (define-constant +nad+ '#:nad) ; "not a datum" marker (define-constant +eop+ '#:eop) ; "end of period" marker (define-constant +eod+ '#:eod) ; "end of data" marker ;;; the period struct holds information for period calculation. count ;;; is number of reads remaining in current period. when count=0 the ;;; period is reinitialized. length is maximum count of the period, ;;; either a number or #t if dynamic length. if stream is not #f a new ;;; length will be read from it each time the period is initialized. ;;; omit is the number of times this stream is skipped in its parent's ;;; pattern, if dynamic. Reps keeps track of the number of ;;; periods. Max is the max number of periods allowed, after which the ;;; pattern always returns +eod+ (define-record period count length stream default omit reps ) (define (pperiod obj ) (list 'period (period-count obj) (period-length obj) (period-stream obj) (period-default obj) (period-omit obj) (period-reps obj) )) (define-record pattern flags data length datum period value state repeat returning counting traversing next mapr cache) (define (ppattern obj ) (list 'pattern #:flags (pattern-flags obj) #:data (pattern-data obj) #:length (pattern-length obj) #:datum (pattern-datum obj) #:period (pperiod (pattern-period obj)) #:value (pattern-value obj) #:state (pattern-state obj) #:repeat (pattern-repeat obj) #:returning (pattern-returning obj) #:cache (pattern-cache obj) )) (define (%alloc-pattern) ;; flags data length datum period value state limit returning counting traversing next mapr cache (make-pattern 0 (list) #f +nad+ #f +nad+ +nad+ most-positive-fixnum #f #:periods #:depth-first #f #f #f)) (define (initialize-pattern obj data for rep flags len dper getr mapr) (pattern-data-set! obj data) (pattern-length-set! obj len) (pattern-mapr-set! obj mapr) (pattern-next-set! obj getr) ;; map data to see if it is constant data or has subpatterns (let ((con? #t)) (map-pattern-data (lambda (x) (if (pattern? x) (set! con? #f))) obj) (if con? (set! flags (logior flags +constant-data+)))) ;; parse counting option (let ((counting (pattern-counting obj))) (case counting ((#:periods ) (set! flags (logior flags +count-periods+))) ((#:values ) (set! flags (logior flags +count-values+))) (else (error "illegal counting value ~S" counting)))) ;; parse traversing option (let ((traversing (pattern-traversing obj))) (case traversing ((#:depth-first ) (set! flags (logior flags +depth-first+))) ((#:breadth-first ) (set! flags (logior flags +breadth-first+))) (else (error "illegal traversing value ~S" traversing)))) ;; if constant data and counting subperiods, switch to counting ;; values instead since its the same thing and we can avoid ;; resetting subperiods if period length is nevertheless expressed ;; dynamically. (cond ((logtest flags +count-values+) (set! flags (logand flags (lognot +count-periods+)))) (else (if (logtest flags +constant-data+) (set! flags (logior (logand flags (lognot +count-periods+)) +count-values+)) (set! flags (logior flags +count-periods+))))) (pattern-repeat-set! obj (if (and (number? rep) (> rep 0)) rep most-positive-fixnum)) (let ((per (or for dper))) ;; period not specified so mark that we are using default period (when (not for) (set! flags (logior flags +default-period+))) (pattern-period-set! obj (if (or (number? per) (eqv? per #t)) ;; count len src dper omit reps (make-period 0 per #f dper 0 0) ;; count len src dper omit reps (make-period 0 #f per dper 0 0)))) (pattern-flags-set! obj flags) (values)) ;;; ;;; Predicates for testing end-of-period and end-of-data. ;;; (define (eop? x) (if (pattern? x) (eop? (pattern-state x)) (eqv? x +eop+))) (define (eod? x) (if (pattern? x) (eod? (pattern-value x)) (eqv? x +eod+))) ;;; ;;; next returns the next value read from the object. this around ;;; method implements the basic behavior of patterns. it first checks ;;; the stream's period length and calls reset-period if at end. if ;;; the next period length is 0 it immediately returns +nad+, which ;;; causes a superior stream (if any) to skip over the current stream ;;; as it increments its pattern. otherwise, the method then ;;; increments the streams pattern until it yields a datum that is not ;;; +nad+ and that call-next-method does not return +nad+ from. if the ;;; stream's data is known to contain only constant values, ie no ;;; substreams, the testing loop is skipped. once call-next-method ;;; returns a value (not +nad+), the period and pattern of the stream ;;; are incremented according to their mode. for period incrementing, ;;; +count-periods+ increments the period count only on +eop+, and ;;; +count-values+ increments the period count every time. for pattern ;;; incrementing, +depth-first+ increments the pattern only on +eop+, ;;; and +breadth-first+ increments the pattern every time. ;;; (define (next obj . args) (let ((num (if (null? args) #f (car args)))) (if num (if (number? num ) (let ((l (list #f))) (do ((i 0 (+ 1 i)) (e l (cdr e))) ((>= i num) (cdr l)) (set-cdr! e (list (next-1 obj))))) (if (pattern? obj) (let ((l (list #f))) (do ((n (next-1 obj) ) (e l (cdr e)) (f #f)) ((or (eqv? n +eod+) f) (cdr l)) (set-cdr! e (list n)) (if (eop? obj) (set! f #t) (set! n (next-1 obj))))) (list obj))) (next-1 obj)))) (define (next-1 obj) (cond ((pattern? obj) (let ((period (pattern-period obj)) (nomore #f)) ;; reset period, return (when (= (period-count period) 0) (when (>= (period-reps period) (pattern-repeat obj)) (pattern-value-set! obj +eod+) (pattern-state-set! obj +eop+) (set! nomore +eod+)) (when (and (not nomore) (= (reset-period obj) 0)) (set! nomore +nad+) (pattern-value-set! obj +nad+) (pattern-state-set! obj +eop+))) (if nomore nomore (let ((flags (pattern-flags obj)) (retfn (pattern-returning obj)) (value #f) (state #f)) ;; increment datum until not +nad+ (if (logtest flags +constant-data+) (begin (pattern-datum-set! obj (next-in-pattern obj)) (set! value (next-1 (pattern-datum obj))) (set! state +eop+) ;;(print (list #:consant!)) ) (do ((dyn? (and (logtest flags +count-periods+) (eqv? (period-length period) #t))) (stop #f)) (stop #f) ;; increment over 0 length substreams (do () ((not (eqv? (pattern-datum obj) +nad+)) #f) (pattern-datum-set! obj (if dyn? (skip-datum? (next-in-pattern obj)) (next-in-pattern obj)))) (set! value (next-1 (pattern-datum obj))) (if (pattern? (pattern-datum obj)) (set! state (pattern-state (pattern-datum obj))) (set! state +eop+)) ;; increment over +nad+ values returned by obj. (if (eqv? value +nad+) (pattern-datum-set! obj value) (set! stop #t ))) ) ;; increment period and pattern as appropriate. (cond ((eqv? state +eop+) ;;(print (list #:state-eop!)) (period-count-set! period (- (period-count period) 1)) (pattern-datum-set! obj +nad+) (set! state #f)) (else (if (logtest flags +breadth-first+) (pattern-datum-set! obj +nad+)) (if (logtest flags +count-values+) (period-count-set! period (- (period-count period) 1))))) ;;(print (list #:period-count (period-count period))) (if (= (period-count period) 0) (begin (set! state +eop+) (period-reps-set! period (+ 1 (period-reps period)))) (set! state state)) (if retfn (set! value ( retfn value)));; thunk (pattern-state-set! obj state) (pattern-value-set! obj value) value)))) ((procedure? obj) (obj ) ) (else obj))) (define (next-in-pattern obj) ( (pattern-next obj) obj) ) (define (map-pattern-data fn obj) ( (pattern-mapr obj) fn obj) ) ;;; ;;; skip-datum? returns +nad+ if the current stream should be skipped ;;; in the pattern. this only happens if we have dynamic periodicity ;;; and the datum had a 0 length period when it was encountered by ;;; reset-period. ;;; (define (skip-datum? obj) (if (not (pattern? obj)) obj (let ((period (pattern-period obj))) (if (> (period-omit period) 0) (begin (period-omit-set! period (- (period-omit period) 1)) +nad+) obj)))) ;;; ;;; reset-period sets and returns the length of the next ;;; period. period length of constant datum is always 1. ;;; (define (reset-period obj) (if (not (pattern? obj)) 1 (let ((period (pattern-period obj)) (dyn #f) (len #f)) ;; if period is supplied as a stream get next length via item (when (period-stream period) (period-length-set! period (next-1 (period-stream period)))) (set! dyn (eqv? (period-length period) #t)) (set! len (if dyn (period-default period) (period-length period))) ;; if we have dynamic period length we adjust next period ;; length for the number of 0 subperiods that this period will ;; encounter. in order for this to work, all substream ;; periods must be reset now, at the same that the super ;; stream is reset. we can only do this if we know that all ;; subperiods are currently at end of period, ie if we are ;; counting by subperiods. if so, then by definition all the ;; substreams must be at end-of-period or we couldn't have ;; gotton here in the first place. after resetting substream ;; period lengths we decrement our current stream's period ;; length by the number of zero periods found. (when (and dyn (logtest (pattern-flags obj) +count-periods+)) (let ((zeros 0)) (map-pattern-data (lambda (x) (when (= (reset-period x) 0) (let ((p (pattern-period x))) (period-omit-set! p (+ (period-omit p) 1))) (set! zeros (+ zeros 1)) )) obj) (when (> zeros 0) (set! len (max (- len zeros) 0))))) (period-count-set! period len) len))) ;;; ;;; pattern implementations. ;;; ;;; cycle continously loops over its data. the data are held in a list ;;; of the form: (data . data). successive elements are popped from ;;; the cdr and when the cdr is null it's reset to the car. ;;; (define (make-cycle data . args) (unless (pair? data) (set! data (list data))) (with-optkeys (args for limit) (let ((obj (%alloc-pattern)) (flags 0) (len (length data))) (initialize-pattern obj (cons data data) for limit flags len len next-in-cycle (lambda (fn obj) (for-each fn (car (pattern-data obj))))) obj))) (define (next-in-cycle obj) (let ((data (pattern-data obj))) (if (null? (cdr data)) (set-cdr! data (car data))) (let ((x (cadr data))) (set-cdr! data (cddr data)) x))) ; (define aaa (make-cycle (list 1 2 3))) ; (next aaa #t) ; (define aaa (make-cycle (list 1 2 3) :for 2)) ; (next aaa #t) ; (define aaa (make-cycle (list 1 2 3) :for (make-cycle (list 3 2 1)))) ; (next aaa #t) ; (define aaa (make-cycle (list 1 2 3) :limit 2)) ; (next aaa #t) ; (define aaa (make-cycle (list (make-cycle (list 'a 'b) ) (make-cycle (list 1 2) )))) ; (next aaa #t) ; (define aaa (make-cycle (list 1 (make-cycle (list 'a 'b))))) ; (next aaa #t) ; (define aaa (make-cycle (list 1 (make-cycle (list 'a 'b) :for (make-cycle (list 3 2 1 0)))))) ; (next aaa #t) ;;; ;;; palindrome ;;; (define-record-type palin (make-palin pos len inc mode elide) palin? (pos palin-pos palin-pos-set!) (len palin-len palin-len-set!) (inc palin-inc palin-inc-set!) (mode palin-mode palin-mode-set!) (elide palin-elide palin-elide-set!)) (define (ppalin obj port) (list 'palin (palin-pos obj) (palin-len obj) (palin-inc obj) (palin-mode obj) (palin-elide obj))) (define (make-palindrome data . args) (unless (pair? data) (set! data (list data))) (with-optkeys (args for limit elide) (let ((obj (%alloc-pattern)) (flags 0) (len (length data))) (initialize-pattern obj data for limit flags len (* len 2) next-in-palindrome (lambda (fn obj) (for-each fn (pattern-data obj)))) ;; pattern cache holds palin structure (pattern-cache-set! obj (make-palin -2 (length data) #f #f elide)) obj))) (define (next-in-palindrome obj) (let* ((cache (pattern-cache obj)) (pos (palin-pos cache))) (cond ((< pos 0 ) ;; starting new up-and-back cycle (let ((m (next-1 (palin-elide cache))) (l (palin-len cache)) (i (= pos -2))) (palin-mode-set! cache m) (palin-inc-set! cache 1) ;; see if we skip repeat of first element (if (or (eqv? m #t) (and (pair? m) (eqv? (car m) #t))) ;; -2 marks very first call, dont skip inital element (if i (set! pos 0) (set! pos 1)) (set! pos 0)) (if (logtest (pattern-flags obj) +default-period+) (let* ((p (pattern-period obj)) (c (* l 2))) (cond ((eqv? m #f) (period-count-set! p c)) ((eqv? m #t) (period-count-set! p (if i (- c 2) (- c 3)))) ((equal? m '(#f #t)) (period-count-set! p (- c 1))) ((equal? m '(#t #f)) (period-count-set! p (if i (- c 1) (- c 2)))) (else (period-count-set! p c))) )) )) ((= pos (palin-len cache)) ;; reversing direction (palin-inc-set! cache -1) (let ((m (palin-mode cache))) ;; test if we skip repeat of last element (if (or (eqv? m #t) (and (pair? m) (pair? (cdr m)) (eqv? (cadr m) #t))) (set! pos (- pos 2)) (set! pos (- pos 1)))) )) (palin-pos-set! cache (+ pos (palin-inc cache))) (list-ref (pattern-data obj) pos))) ; (define aaa (make-palindrome '(a b c d) )) ; (next aaa #t) ; (define aaa (make-palindrome '(a b c d) :elide #t)) ; (next aaa #t) ; (define aaa (make-palindrome '(a b c d) :elide '(#f #t))) ; (next aaa #t) ; (define aaa (make-palindrome '(a b c d) :elide '(#t #f))) ; (next aaa #t) ; (define aaa (make-palindrome '(a b c d) :for 3)) ; (next aaa #t) ;;; ;;; line sticks on the last element. ;;; (define (make-line data . args) (unless (pair? data) (set! data (list data))) (with-optkeys (args for limit) (let ((obj (%alloc-pattern)) (flags 0) (len (length data))) (initialize-pattern obj data for limit flags len len next-in-line (lambda (fn obj) (for-each fn (pattern-data obj)))) obj))) (define (next-in-line obj) (let ((line (pattern-data obj))) (if (null? (cdr line)) (begin (period-count-set! (pattern-period obj) 1) (car line) ) (let ((x (car line))) (pattern-data-set! obj (cdr line)) x)))) ;;; (define aaa (make-line '(a b c))) ;;; (next aaa #t) ;;; (define aaa (make-line (list 'a 'b (make-cycle '(1 2 3 4))))) ;;; (next aaa #t) ;;; (define aaa (make-line (list 'a 'b (make-cycle '(1 2 3 4) :for (lambda () (+ 1 (random 4))))))) ;;; (next aaa #t) ;;; aaa ;;; ;;; heap shuffles its elements each time through ;;; (define (make-heap data . args) ;; copy data because heap destructively modifies it (if (pair? data) (set! data (append data (list))) (set! data (list data))) (with-optkeys (args for limit) (let ((obj (%alloc-pattern)) (flags 0) (len (length data))) (initialize-pattern obj (list data) for limit flags len len next-in-heap (lambda (fn obj) (for-each fn (car (pattern-data obj))))) obj))) (define (next-in-heap obj) (let ((data (pattern-data obj))) (when (null? (cdr data)) (let ((len (pattern-length obj)) (lis (car data))) (do ((i 0 (+ i 1)) (j (random len) (random len)) ;; (j (ffi_ranint len ) (ffi_ranint len)) (v #f)) ((= i len) (set-cdr! data lis)) (set! v (list-ref lis i)) (list-set! lis i (list-ref lis j)) (list-set! lis j v)))) (let ((x (cadr data))) (set-cdr! data (cddr data)) x))) ;; (define xxx '(1 2 3 4)) ;; (define aaa (make-heap xxx)) ;; (next aaa #t) ;; xxx ;; (define aaa (make-heap (list 1 2 3 (make-cycle '(a b c)) 4 5))) ;; (next aaa #t) ;;; ;;; rotation ;;; (define (make-rotation data . args) ;; copy user's data (rotation side effects data) (if (pair? data) (set! data (append data (list))) (set! data (list data))) (with-optkeys (args for limit (rotate 0)) (let ((obj (%alloc-pattern)) (flags 0) (len (length data))) ;; cdr of data initialized now so that rotations only happen ;; after the first cycle. ;; (initialize-pattern obj data args flags len dper getr mapr allow) (initialize-pattern obj (cons data data) for limit flags len len next-in-rotation (lambda (fn obj) (for-each fn (car (pattern-data obj))))) ;; pattern cache holds palin structure (pattern-cache-set! obj rotate) obj))) (define (next-in-rotation obj) (define (rotate-items items start step width end) (do ((i start (+ i step))) ((not (< i end)) items) (let ((a (list-ref items i)) (b (list-ref items (+ i width)))) (list-set! items i b) (list-set! items (+ i width) a)))) (let ((data (pattern-data obj))) (when (null? (cdr data)) (let ((l (car data)) (r (next-1 (pattern-cache obj)))) ;; start step width end (set-cdr! data (if (pair? r) (if (pair? (cdr r)) (if (pair? (cddr r)) (if (pair? (cdddr r)) (apply rotate-items l r) (rotate-items l (car r) (cadr r) (caddr r) ;; len - width (- (pattern-length obj) (caddr r)))) (rotate-items l (car r) (cadr r) 1 (- (pattern-length obj) 1))) (rotate-items l (car r) 1 1 (- (pattern-length obj) 1))) (rotate-items l r 1 1 (- (pattern-length obj) 1)))))) (let ((x (car (cdr data)))) (set-cdr! data (cddr data)) x))) ; (define aaa (make-rotation '(a b c d))) ; (next aaa #t) ; (define aaa (make-rotation '(a b c d) :rotations '(1 2))) ; (next aaa #t) ;;; ;;; weighting chooses items using weighted selection. its data are ;;; kept in a list of the form#: ((&rest choices) . last-choice). ;;; ;; (define-record random-item datum index weight min max count id minmax) (define-record-type random-item (make-random-item datum index weight min max count id minmax) random-item? (datum random-item-datum random-item-datum-set!) (index random-item-index random-item-index-set!) (weight random-item-weight random-item-weight-set!) (min random-item-min random-item-min-set!) (max random-item-max random-item-max-set!) (count random-item-count random-item-count-set!) (id random-item-id random-item-id-set!) (minmax random-item-minmax random-item-minmax-set!)) (define (prandom-item obj ) (list 'random-item #:datum (random-item-datum obj) #:index (random-item-index obj) #:weight (random-item-weight obj) #:min (random-item-min obj) #:max (random-item-max obj) #:count (random-item-count obj) #:id (random-item-id obj) #:minmax (random-item-minmax obj))) (define (make-weighting data . args) (let* ((pool (canonicalize-weighting-data data)) (obj (%alloc-pattern)) (len (length pool)) (dper #f) (const-weight #t) (const-datums #t) (num-patterns 0) (flags 0)) (for-each (lambda (item) (let ((min (random-item-min item)) (max (random-item-max item)) (wei (random-item-weight item)) (dat (random-item-datum item))) (when (pattern? dat) (set! const-datums #f) (set! num-patterns (+ num-patterns 1))) ;; check the stream for constant weights. if true, ;; calculate the range now and set a flag so we dont ;; recalulate each period. (unless (number? wei) (set! const-weight #f)))) pool) ;; set the default period length of an all-subpattern weighting to ;; 1 otherwise to the number of elements. since a weighting ;; pattern establishes no particular order itself, setting the ;; period to 1 allows the number of elements in the current period ;; to reflect the sub patterns. (set! dper (if (= num-patterns len) 1 len)) (if const-weight (set! flags (logior flags +constant-weights+))) ;; pool is ((&rest choices) . last-choice) no initial last ;; choice. a first choice for the stream could be implemented as a ;; last with min=1 (with-optkeys (args for limit) (initialize-pattern obj (list pool) for limit flags len dper next-in-weighting (lambda (fn obj) (for-each (lambda (i) ( fn (random-item-datum i))) (car (pattern-data obj)))))) ;; if we have constant weights calculate the range now as fixnums (if const-weight (recalc-weightings obj #t)) obj)) (define (canonicalize-weighting-data data) (define (%make-random-item w) (let ((item #f) (args (list))) (cond ((pair? w) (set! item (car w)) (set! args (cdr w))) (else (set! item w))) (with-optkeys (args (weight 1) (min 1) max) (make-random-item item #f weight min max 0 #f #f)))) (map %make-random-item data)) ;;; (canonicalize-weighting-data '(a b c)) ;;; (canonicalize-weighting-data '(a (b 33) c)) ;;; (canonicalize-weighting-data '(a (b :max 33) c)) (define (recalc-weightings obj fix?) (let ((data (car (pattern-data obj))) (range 0.0)) (do ((tail data (cdr tail))) ((null? tail) #f) (set! range (+ range (next-1 (random-item-weight (car tail))))) (random-item-index-set! (car tail) range)) (if fix? (do ((tail data (cdr tail)) (index 0) (total 0)) ((null? tail) (pattern-cache-set! obj total) ) (set! index (/ (random-item-index (car tail)) range)) (random-item-index-set! (car tail) index) (set! total index)) (pattern-cache-set! obj range)))) (define (next-in-weighting obj) ;; pool is ((&rest choices) . last-item) (let* ((pool (pattern-data obj)) (per (pattern-period obj)) (flags (pattern-flags obj)) (last (cdr pool))) (unless (logtest flags +constant-weights+) ;; at beginning of new period? (when (= (period-count per) (period-length per)) (recalc-weightings obj #f))) ;; if we have a last item with an unfulfilled :min value return it (if (and (not (null? last)) (begin (random-item-count-set! last (+ 1 (random-item-count last))) (< (random-item-count last) (random-item-min last)))) (random-item-datum last) (let ((range (pattern-cache obj)) (choices (car pool)) (pick (lambda (c r) (do ((tail c (cdr tail)) (index (random r)) ;; (index (ffi_ranfloat r )) ) ( (< index (random-item-index (car tail))) (car tail))))) (next #f)) (do ((item (pick choices range) (pick choices range))) ((not (and (random-item-max item) (= (random-item-count item) (random-item-max item)))) (set! next item)) ) (unless (eqv? next last) (do ((tail choices (cdr tail))) ((null? tail) #f) (random-item-count-set! (car tail) 0))) (set-cdr! pool next) ;; adjust the weight of the newly selected item (random-item-datum next))))) ;;; (define aaa (make-weighting '(a b c d e))) ;;; (next aaa #t) ;;; (define aaa (make-weighting '(a b (c :weight 10) d e))) ;;; (next aaa #t) ;;; (define aaa (make-weighting '(a b (c :min 4) d e))) ;;; (next aaa #t) ;;; ;;; markov ;;; (define (canonicalize-markov-data data) (define (parse-markov-spec spec) (if (not (pair? spec)) (error "transition ~S is not a list" spec)) (let ((rhside (or (member '-> spec) (member '#:-> spec) (error "no right hand side in transition ~S" spec))) (lhside (list)) (range 0) (outputs (list))) ;; separate lh and rh sides (let* ((head (list #f)) (tail head)) (do () ((eqv? spec rhside) (set! lhside (cdr head)) (set! rhside (cdr rhside))) (set-cdr! tail (list (car spec))) (set! tail (cdr tail)) (set! spec (cdr spec)))) (for-each (lambda (s) (let ((val #f) (pat #f) (wei #f)) (if (pair? s) (begin (set! val (car s)) (set! wei (if (null? (cdr s)) 1 (cadr s))) ;; weight may be number or pattern (set! pat wei) (unless (number? wei) (set! wei #f))) (begin (set! val s) (set! wei 1) (set! pat 1))) ;; set range to #f if any weight is pattern ;; else precalc range for the constant weights (if (and wei range) (set! range (+ range wei)) (set! range #f)) ;;(push (list val range pat) outputs) (set! outputs (cons (list val range pat) outputs)) )) rhside) (cons lhside (cons range (reverse outputs))))) (let ((transitions (list #f))) (do ((tail data (cdr tail)) (order #f) (lis transitions) (p #f)) ((null? tail) (cdr transitions) ) (set! p (parse-markov-spec (car tail))) (if (not order) (set! order (length (car p))) ;;(set! order (max order (length (first p)))) (if (not (= order (length (car p)))) (error "found left hand sides with different number of items in ~S" data)) ) (set-cdr! lis (list p)) (set! lis (cdr lis))))) ;;; (parse-markov-spec '(a a -> b c )) ;;; (canonicalize-markov-data '((a a -> b c ) ( a b -> a) (c a -> c a))) (define (make-markov data . args) (if (not (pair? data)) (error "~S is not list of markov transitions" data) (set! data (canonicalize-markov-data data))) (with-optkeys (args for limit past) (let* ((obj (%alloc-pattern)) (len (length data)) (flags 0)) (initialize-pattern obj data for limit flags len len next-in-markov (lambda (fn obj) (for-each fn (pattern-data obj)))) (unless (pair? past) (set! past (make-list (length (car (car data))) '*))) (pattern-cache-set! obj past) obj))) (define (next-in-markov obj) ;; markov data kept as a list of lists. each list is in the form#: ;; (() range . ) (letrec ((select-output (lambda (range outputs) ;; if range is #f then one or more weights in the ;; outputs are patterns. in this case we map all the ;; outputs to update weights of every outcome and then ;; select. otherwise (range is number) we simply select ;; an outcome from the precalculated distribution. (if (not range) (do ((tail outputs (cdr tail)) (out #f) (sum 0)) ((null? tail) (select-output sum outputs)) ;; out is outcome#: (val rng ) (set! out (car tail)) ;; if third element is number use it else read it (set! sum (+ sum (if (number? (caddr out)) (caddr out) (next-1 (caddr out))))) ;; always update second element to new value (set-car! (cdr out) sum)) (let ( (n (random range)) ;; (n (ffi_ranfloat range)) ) (do ((tail outputs (cdr tail))) ((< n (cadr (car tail))) (car (car tail))))) ))) (match-past (lambda (inputs past) (do ((i inputs (cdr i)) (j past (cdr j)) (f #t)) ((or (null? i) (null? j) (not f)) f) (set! f (or (eqv? (car i) '*) (equal? (car i) (car j)) (eqv? (car j) '*)))) ))) (do ((tail (pattern-data obj) (cdr tail)) (past (pattern-cache obj)) (item #f) ) ((or (null? tail) (null? past) (match-past (car (car tail)) past)) (when (null? tail) (error "no transition matches past ~S" past)) (set! item (select-output (cadr (car tail)) (cddr (car tail)))) (unless (null? past) (if (null? (cdr past)) (set-car! past item) (do ((last past (cdr last))) ((null? (cdr last)) ;; rotate past choices leftward (set-car! past item) (set-cdr! last past) (pattern-cache-set! obj (cdr past)) (set-cdr! (cdr last) (list)))))) item)) )) ;;; (define aaa (make-markov '((a -> b c d) (b -> a) (c -> d) (d -> (a 3) b c)))) ;;; (next aaa 30) (define (last-pair l) (if (pair? (cdr l)) (last-pair (cdr l)) l)) (define (markov-analyze seq . args) (let* ((morder #f) ; markov order (result #f) ; what to return (len (length seq)) (labels '()) ; the set of all outcomes (table '()) (row-label-width 8) (print-decimals 3) (field (+ print-decimals 2))) ; n.nnn (with-optkeys (args (order 1) (mode 1)) (set! morder order) (set! result mode)) (unless (member result '(1 2 3)) (error "~S is not a valid mode value" result)) (letrec ((add-outcome (lambda (prev next) (let ((entry (find-if (lambda (x) (equal? prev (car x))) table))) (if (not entry) (set! table (cons (list prev (format #f "~s" prev) (list next 1)) table)) (let ((e (assoc next (cddr entry)))) (if e (set-car! (cdr e) (+ 1 (cadr e))) (set-cdr! (last-pair (cdr entry)) (list (list next 1))))))))) (before? (lambda (x y l) (if (null? x) #t (let ((p1 (list-index (lambda (z) (equal? (car x) z)) l)) (p2 (list-index (lambda (z) (equal? (car y) z)) l))) (cond ((< p1 p2) #t) ; bug! ;((= p1 p2) (before? (cdr x) (cdr y) l)) (else #f)))))) (liststring (lambda (l) (if (null? l) "" (let ((a (format #f "~a" (car l)))) (do ((x (cdr l) (cdr x))) ((null? x) a) (set! a (string-append a (format #f " ~a" (car x)))))))))) (do ((i 0 (+ i 1))) ((= i len) #f) (do ((prev (list)) (j 0 (+ j 1)) ; j to morder (x #f)) ((> j morder) (add-outcome (reverse prev) x ) (if (not (member x labels)) (set! labels (cons x labels)))) (set! x (list-ref seq (modulo (+ i j) len))) ;; gather history in reverse order (when (< j morder) (set! prev (cons x prev))))) ;; sort the outcomes according to data (cond ((number? (car labels)) (set! labels (sort labels <))) ((and (car labels) (symbol? (car labels))) (set! labels (sort labels (lambda (x y) (string-cistring (cadr v))) (n (string-length s))) (display sp port) ;; s7: trim number to fit field (if (>= n field) (let ((d (char-position #\. s))) (set! s (substring s 0 (min (+ d 4) n))) (set! n (string-length s)))) ;; pad number (do ((i 0 (+ i 1)) (m (max (- field n) 0))) ((= i m) #f) (write-char #\space port)) (display s port) )))))) (newline port) (display (get-output-string port)) (close-output-port port) ))) (if (= result 1) (values) ;; if returning pattern or data convert table to markov lists (let ((pat (map (lambda (row) (append (car row) '(->) (cddr row))) table))) (if (= result 2) (make-markov pat) pat))))) ; (define aaa '(c4 c4 d4 c4 f4 e4 c4 c4 d4 c4 g4 f4 c4 c4 c5 a4 f4 e4 d4 bf4 bf4 a4 f4 g4 f4)) ; (define markovpat (markov-analyze aaa 1 2)) ; (next markovpat 30) ;;; ;;; Graph ;;; ;; (define-record graph-node datum to id) (define-record-type graph-node (make-graph-node datum to id) graph-node? (datum graph-node-datum graph-node-datum-set!) (to graph-node-to graph-node-to-set!) (id graph-node-id graph-node-id-set!)) (define (pgraph-node obj port) (list 'graph-node (graph-node-datum obj) (graph-node-to obj) (graph-node-id obj))) (define (make-graph data . args) (if (not (pair? data)) (error "~S is not a list of graph data" data) (set! data (canonicalize-graph-data data))) (with-optkeys (args for limit) (let* ((obj (%alloc-pattern)) (len (length data)) (flags 0)) (initialize-pattern obj (cons #f data ) for limit flags len len next-in-graph (lambda (fn obj) (for-each (lambda (n) ( fn (graph-node-datum n))) (cdr (pattern-data obj))))) obj))) (define (canonicalize-graph-data data) (let ((pos 1)) (define (parse-graph-item extern) (unless (pair? extern) (error "~S is not a graph node list" extern)) (apply (lambda (item . args) (with-optkeys (args to id) (unless id (set! id pos)) (set! pos (+ pos 1)) (make-graph-node item to id))) extern)) (map parse-graph-item data))) ;; (canonicalize-graph-data '((a :to 2) (b :id 2 :to a))) ;; (canonicalize-graph-data '((a :id 1 :to b) (b :id 2 :to a))) (define (next-in-graph obj) (let* ((graph (pattern-data obj)) (nodes (cdr graph)) (this (car graph))) (if (not this) (begin (set-car! graph (car nodes)) (graph-node-datum (car nodes))) ;; read the to: link and search for next node (let ((link (next-1 (graph-node-to this))) (next #f)) (do ((tail nodes (cdr tail))) ((or next (null? tail)) (if (not next) (error "no graph node for id ~S" link) (set-car! graph next)) (graph-node-datum next)) (if (eqv? link (graph-node-id (car tail))) (set! next (car tail)))))))) ;;; (define aaa (make-graph '((a :to b) (b :to a)))) ;;; (next aaa) ;;; (define aaa (make-graph `((a :to 2) (b :id 2 :to 3) (c :id 3 :to ,(make-weighting '(1 2 3)))))) ;;; (next aaa 20) ;;; ;;; Repeater ;;; (define (make-repeater pat . args) (with-optkeys (args for repeat limit) (let ((obj (%alloc-pattern)) (flags 0) ) (initialize-pattern obj (list) for stop flags 0 1 next-in-repeater (lambda (fn obj) (for-each fn (pattern-data obj)))) ;; pattern cache holds palin structure (pattern-cache-set! obj (list pat repeat)) obj))) (define (next-in-repeater obj) (let ((data (pattern-data obj))) (if (null? data) (let* ((per (pattern-period obj)) (res (next (car (pattern-cache obj)) #t)) (len (length res)) (for (period-length per)) (rep (cadr (pattern-cache obj)))) (if rep (begin (set! for (next rep)) (period-length-set! per len) (period-count-set! per len)) (period-count-set! per (* len for))) (let ((sav res) (don (- for 1))) (do ((i 0 (+ i 1))) ((not (< i don)) #f) (set! res (append res sav)))) (pattern-data-set! obj (cdr res)) (car res)) (begin (pattern-data-set! obj (cdr data)) (car data))))) snd-16.1/glistener.h0000644000076400007640000003476012512761107012514 0ustar bilbil#ifndef GLISTENER_H #define GLISTENER_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if (GTK_CHECK_VERSION(3, 0, 0)) #include #else #include #endif #if GTK_CHECK_VERSION(3, 16, 0) #define GDK_CURSOR_NEW(Type) gdk_cursor_new_for_display(gdk_display_get_default(), Type) #else #define GDK_CURSOR_NEW(Type) gdk_cursor_new(Type) #endif typedef struct glistener glistener; typedef enum {GLISTENER_STRING, GLISTENER_COMMENT, GLISTENER_BLOCK_COMMENT, GLISTENER_ATOM, GLISTENER_LIST, GLISTENER_BRACKET, GLISTENER_CHARACTER } glistener_colorizer_t; glistener *glistener_new(GtkWidget *parent, void (*initializations)(glistener *g, GtkWidget *new_listener)); void glistener_append_text (glistener *g, const char *msg); void glistener_insert_text (glistener *g, const char *text); char *glistener_text (glistener *g, int start, int end); void glistener_append_prompt (glistener *g); void glistener_set_prompt (glistener *g, const char *str); void glistener_set_prompt_tag (glistener *g, GtkTextTag *m); int glistener_prompt_position (glistener *g); void glistener_set_cursor_shape (glistener *g, GdkCursor *cursor_shape); int glistener_cursor_position (glistener *g); void glistener_set_cursor_position (glistener *g, int position); void glistener_scroll_to_end (glistener *g); void glistener_post_status (glistener *g, const char *msg); void glistener_clear_status (glistener *g); void glistener_clear (glistener *g); bool glistener_write (glistener *g, FILE *fp); void glistener_set_highlight_tag (glistener *g, GtkTextTag *m); void glistener_set_font (glistener *g, PangoFontDescription *font); #if (!GTK_CHECK_VERSION(3, 0, 0)) void glistener_set_text_color (glistener *g, GdkColor *p); void glistener_set_background_color(glistener *g, GdkColor *p); #else void glistener_set_text_color (glistener *g, GdkRGBA *p); void glistener_set_background_color(glistener *g, GdkRGBA *p); #endif void glistener_key_bindings (glistener *g, gpointer cls); void glistener_is_schemish (glistener *g, bool filtering); void glistener_set_completer (glistener *g, void (*completer)(glistener *g, bool (*symbol_func)(const char *symbol_name, void *data), void *data)); void glistener_set_helper (glistener *g, const char *(*help)(glistener *g, const char *text)); void glistener_set_checker (glistener *g, const char *(*check)(glistener *g, const char *text)); void glistener_set_evaluator (glistener *g, void (*eval)(glistener *g, const char *text)); void glistener_set_colorizer (glistener *g, void (*colorizer)(glistener *g, glistener_colorizer_t type, int start, int end)); void glistener_set_keyer (glistener *g, bool (*key)(glistener *g, GtkWidget *w, GdkEventKey *e)); /* these are for regression testing */ char *glistener_evaluate (glistener *g); char *glistener_complete (glistener *g); /* -------------------------------------------------------------------------------- */ /* an annotated version of the same info: * * typedef struct glistener glistener; * * our opaque handle on the info for each listener. You can run any number of listeners * at the same time. For a simple example, see s7.html#glistener. Another is snd-glistener.c * in the Snd package, and tools/gcall.c. * * * -------- * glistener *glistener_new(GtkWidget *parent, void (*initializations)(glistener *g, GtkWidget *new_listener)); * * This creates a new listener. If parent is not NULL, the listener is added to it * via gtk_container_add. The second argument is an optional function that will be called * during the listener initialization, just before the signals are connected. It * can add its own signal connections or set defaults. The "new_listener" argument * passed to it is the new GtkTextView widget. Its parent is a GtkScrolledWindow, * which is placed in a grid (or table in gtk-2) along with the listener's statusbar. * * * -------- * void glistener_append_text(glistener *g, const char *msg); * * This appends "msg" to the end of the listener text. * * * -------- * void glistener_insert_text(glistener *g, const char *text); * * This inserts "text" at the cursor. * * * -------- * char *glistener_text(glistener *g, int start, int end); * * This returns the text in the listener between the offsets (unicode positions) * "start" and "end". * * * -------- * void glistener_append_prompt(glistener *g); * * This appends a prompt at the bottom of the listener text. Everything * depends on the prompt, so you need to send one out at the end of each * evaluation. The usual sequence is: * user types in an expression followed by -> listener-text * we_eval(listener-text) -> some string * glistener_append_text(g, that string); * glistener_append_prompt(g); * * * -------- * void glistener_set_prompt(glistener *g, const char *str); * * This sets the text of the prompt. It defaults to ">" but can be anything. * One way to get, for example, the unicode lower-case lambda followed by ">" as the prompt is: * unsigned char prompt[4] = {0xce, 0xbb, '>', '\0'}; * glistener_set_prompt(g, prompt); * UTF8 lambda is 0xce 0xbb. * * * -------- * void glistener_set_prompt_tag(glistener *g, GtkTextTag *m); * * This sets the GtkTextTag for the prompt. It defaults to NULL, but it's nicer to * set off the prompt in some way (like bold-face). Here's a tag that makes our prompt * bold red: * glistener_set_prompt_tag(g, * gtk_text_buffer_create_tag(buffer, "glistener_prompt_tag", "weight", PANGO_WEIGHT_BOLD, "foreground", "red", NULL)); * * * -------- * int glistener_prompt_position(glistener *g); * * This returns the current (active) prompt offset in the listener text buffer. * * * -------- * void glistener_set_cursor_shape(glistener *g, GdkCursor *cursor_shape); * * This sets the current cursor shape. It is normally an arrow, but changes to * a watch or hour-glass during evaluation: * gdk_cursor_new(GDK_WATCH) or gdk_cursor_new(GDK_LEFT_PTR) * * * -------- * int glistener_cursor_position(glistener *g); * * This returns the cursor offset in the listener. * * * -------- * void glistener_set_cursor_position(glistener *g, int position); * * This moves the listener's cursor to the offset "position". * * * -------- * void glistener_scroll_to_end(glistener *g); * * This scrolls the view of the listener's text to the end of the text. * * * -------- * void glistener_post_status(glistener *g, const char *msg); * * This places "msg" in the listener's statusbar. The previous text, if any * is removed, so you don't need to worry about gtk_statusbar_pop. * * * -------- * void glistener_clear_status(glistener *g); * * This removes all messages from the statusbar. * * * -------- * void glistener_clear(glistener *g); * * This deletes all the text in the listener, leaving only the initial prompt. * * * -------- * bool glistener_write(glistener *g, FILE *fp); * * This writes the current listener text contents to the file "fp". * * * -------- * void glistener_set_highlight_tag(glistener *g, GtkTextTag *m); * * This sets the GtkTexTag for highlighted text, normally marking an unmatched * open parenthesis. The default is bold face, red foreground, but I may change * that to red backgound. See glistener_set_prompt_tag above for an example. * * * -------- * void glistener_set_font(glistener *g, PangoFontDescription *font); * * This sets the listener text font. It defaults to "Monospace 11". Indentation * code assumes fixed-width spacing, but that's not a big deal. * glistener_set_font(g, pango_font_description_from_string("Monospace 10")); * * * -------- * void glistener_set_text_color(glistener *g, GdkRGBA *p); * * This sets the text foreground color, normally black. In gtk 2, the color * is GdkColor*. This snippet makes the text green: * GdkRGBA color; * color.red = 0.0; color.green = 0.97; color.blue = 0.0; color.alpha = 1.0; * glistener_set_text_color(g1, &color); * * * -------- * void glistener_set_background_color(glistener *g, GdkRGBA *p); * * This sets the listener background color, normally white. In gtk 2, use * a GdkColor* instead. The following code gives the listener a light blue * background: * GdkRGBA color; * color.red = 0.94; color.green = 0.97; color.blue = 1.0; color.alpha = 1.0; * glistener_set_background_color(g1, &color); * * * -------- * void glistener_key_bindings(glistener *g, gpointer cls); * * This establishes the listener's emacs-inspired keybindings in the gtk * widget class "cls" (normally gtk_entry). In Snd I use this to make sure * all the text-oriented widgets share the same basic set: * glistener_key_bindings(g, GTK_ENTRY_GET_CLASS(GTK_ENTRY(text))); * * * -------- * void glistener_is_schemish(glistener *g, bool filtering); * * This determines whether the listener tries to parse the text before sending it to * the evaluator. It defaults to true, expecting more-or-less lispish syntax. In other * languages (Ruby and Forth in Snd, for example), set this to false. * * * * -------- * void glistener_set_completer(glistener *g, void (*completer)(glistener *g, bool (*symbol_func)(const char *symbol_name, void *data), void *data)) * * The completer is called whenever the user types TAB after what appears to be a * partial symbol name (in a string, the filename completer is called instead). * To find a plausible completion, the listener needs access to the table of currently * known symbols. In s7, s7_for_each_symbol_name runs through the symbol table, * calling a function on each symbol, and stopping when the function returns true, * so symbol completion in s7 is: * * s7_for_each_symbol_name(s7, symbol_func, data); * * The completer function in s7 is: * * static void completer(glistener *g, bool (*symbol_func)(const char *symbol_name, void *data), void *data) * { * s7_for_each_symbol_name(s7, symbol_func, data); * } * * and it is tied into the listener via: * * glistener_set_completer(g1, completer); * * * * -------- * void glistener_set_helper(glistener *g, const char *(*help)(glistener *g, const char *text)) * * The helper is called whenever the listener thinks a help string is in order. It is passed * a string ("text") about which it hopes to get help. If the helper returns NULL, nothing * happens, but otherwise, the returned help is posted in the status area. In s7, it is: * * static const char *helper(glistener *g, const char *text) * { * s7_pointer sym; * sym = s7_symbol_table_find_name(s7, text); * if (sym) * return(s7_help(s7, sym)); * glistener_clear_status(g); * return(NULL); * } * * and it is tied into the listener via: * * glistener_set_helper(g1, helper); * * * * -------- * void glistener_set_evaluator(glistener *g, void (*eval)(glistener *g, const char *text)) * * This is the heart of the listener. It gets a string ("text") and * does something debonair. In s7, it calls s7_eval_c_string, and then * displays the result. Although error handling makes the code complicated, * the basic idea is: * * static void evaluator(glistener *g, const char *text) * { * s7_pointer result; * char *msg; * result = s7_eval_c_string(s7, text); * glistener_append_text(g, "\n"); * msg = s7_object_to_c_string(s7, result); * glistener_append_text(g, msg); * if (msg) free(msg); * glistener_append_prompt(g); * } * * tied into the listener via: * * glistener_set_evaluator(g1, evaluator); * * * * -------- * void glistener_set_checker(glistener *g, const char *(*check)(glistener *g, const char *text)) * * The checker is called when close-paren is typed and the matching open-paren can be found. * "text" in this case is the expression. If it notices something awry in the expression, * it can squawk in the status area. The checker in snd-glistener.c calls s7_read on the text, * then runs various checks on that code (function argument checks and so on). * * * * -------- * void glistener_set_colorizer(glistener *g, void (*colorizer)(glistener *g, glistener_colorizer_t type, int start, int end)) * * The colorizer highlights portions of the code, normally using colors, but the GtkTextBuffer * is at your disposal. This function is called whenever there is any change in the listener * buffer's contents. The "start" and "end" ints are offsets into the buffer giving what the * listener thinks are the current bounds where there is an entity of "type", one of the glistener_colorizer_t * enums given above. See the colorizer function in snd-glistener.c. * * * * -------- * void glistener_set_keyer(glistener *g, bool (*key)(glistener *g, GtkWidget *w, GdkEventKey *e)) * * The keyer is called upon key-press. It is passed the widget involved (the listener * text-view widget), and the GdkEvent. The event has fields giving the key itself, and * any auxiliary keys (control, shift, etc). If you don't want to handle that key, or * want the built-in action to be called, return false. If keyer returns true, any * further handling of the signal is blocked. The default keyer simply returns false. * * glistener rebinds some of the keys to mimic Emacs, then adds a few others: * M-< go to start of text (also up-arrow) * M-> go to end of text (also down-arrow) * M-a go to previous prompt * M-e go to next prompt * M-n restore previous expression, moving back in the history * M-p restore previous expression, moving forward in the history * Tab complete preceding name, if any, else look for indentation opportunity * Return send current expression, if any, to evaluator, else insert return * * * * -------- * char *glistener_evaluate(glistener *g); * char *glistener_complete(glistener *g); * * These two functions are intended for regression testing. glistener_evaluate * simulates typing , and glistener_complete simulates . */ #endif snd-16.1/musglyphs.rb0000644000076400007640000021031512306421672012720 0ustar bilbil# musglyphs.rb -- musglyphs.scm and cmn-glyphs.lisp --> musglyphs.rb # Translator: Michael Scholz # Created: Wed Apr 06 00:47:44 CEST 2005 # Changed: Sat Mar 12 01:47:25 CET 2011 # Commentary: # # module Musglyphs # # class SND_Draw # initialize(*args) # inspect # to_s # comment # snd # chn # moveto(x, y) # rmoveto(x, y) # curveto(x0, y0, x1, y1, x2, y2) # lineto(x, y) # rlineto(x, y) # draw # fill_in # draw_or_fill_in # circle(x0, y0, rad) # # draw_treble_clef(*args) # draw_percussion_clef(*args) # draw_c_clef(*args) # draw_bass_clef(*args) # # draw_turn(*args) # draw_mordent(*args) # draw_double_mordent(*args) # draw_trill_section(*args) # draw_trill_sections(count, *args) # draw_arpeggio(*args) # draw_arpeggios(count, *args) # draw_tr(*args) # draw_accent(*args) # draw_tnecca(*args) # # draw_breath_mark(*args) # draw_caesura(*args) # draw_fermata(*args) # draw_upside_down_fermata(*args) # # draw_repeat_sign(*args) # draw_upper_bracket(*args) # draw_lower_bracket(*args) # draw_segno(*args) # draw_coda(*args) # draw_pedal_off(*args) # draw_ped(*args) # draw_left_paren(*args) # draw_right_paren(*args) # draw_wedge(*args) # draw_down_bow(*args) # draw_up_bow(*args) # # draw_zero(*args) # draw_one(*args) # draw_two(*args) # draw_three(*args) # draw_four(*args) # draw_five(*args) # draw_six(*args) # draw_seven(*args) # draw_eight(*args) # draw_nine(*args) # draw_common_time(*args) # draw_cut_time(*args) # draw_plus(*args) # # draw_sharp(*args) # draw_flat(*args) # draw_double_sharp(*args) # draw_natural(*args) # draw_double_flat(*args) # # draw_f(*args) # draw_p(*args) # draw_lig_p(*args) # draw_m(*args) # draw_n(*args) # draw_niente(*args) # draw_subito(*args) # draw_z(*args) # draw_s(*args) # draw_r(*args) # # draw_double_whole_note(*args) # draw_whole_note(*args) # draw_half_note(*args) # draw_quarter_note(*args) # draw_diamond(*args) # draw_diamond_1(*args) # draw_filled_diamond_1(*args) # draw_rhythmX(*args) # draw_circled_x(*args) # draw_slash(*args) # draw_mslash(*args) # draw_triangle(*args) # draw_square(*args) # draw_8th_flag_up(*args) # draw_extend_flag_up(*args) # draw_8th_flag_down(*args) # draw_extend_flag_down(*args) # # draw_draw_whole_rest(*args) # draw_half_rest(*args) # draw_quarter_rest(*args) # draw_8th_rest(*args) # draw_16th_rest(*args) # draw_32nd_rest(*args) # draw_64th_rest(*args) # draw_128th_rest(*args) # draw_measure_rest(*args) # draw_double_whole_rest(*args) # # Code: module Musglyphs class SND_Draw def initialize(com, *args) @comment = com @xoff = Float((args[0] or 0.0)) @yoff = Float((args[1] or 0.0)) @size = Float((args[2] or 50.0)) @style = (args[3] or 0) # 0: fill_in else draw @snd = (args[4] or 0) # (integer or true/false) @chn = (args[5] or 0) # (integer or true/false) @ax = (args[6] or 0) # axis-context (integer or false) @curx = 0.0 @cury = 0.0 @pathlist = [] end attr_reader :comment, :snd, :chn def inspect format("#<%s[%s:%s] offset: [%1.1f, %1.1f], size: %1.1f, style: %s, %s>", self.class, @snd, @chn, @xoff, @yoff, @size, @style, @comment.inspect) end alias to_s inspect def moveto(x, y) @curx = x.to_f @cury = y.to_f end def rmoveto(x, y) @curx += x.to_f @cury += y.to_f end def curveto(x0, y0, x1, y1, x2, y2) @pathlist.push(make_bezier(to_x(@curx), to_y(@cury), to_x(x0), to_y(y0), to_x(x1), to_y(y1), to_x(x2), to_y(y2), 50)) @curx = x2.to_f @cury = y2.to_f end def lineto(x, y) @curx = x.to_f @cury = y.to_f @pathlist.push(to_x(x), to_y(y)) end def rlineto(x, y) @curx += x.to_f @cury += y.to_f @pathlist.push(to_x(@curx), to_y(@cury)) end def draw unless @pathlist.empty? cr = make_cairo(channel_widgets(@snd, @chn)[0]) draw_lines(@pathlist.flatten.compact, @snd, @chn, @ax, cr) free_cairo(cr) end @pathlist.clear self end def fill_in unless @pathlist.empty? cr = make_cairo(channel_widgets(@snd, @chn)[0]) fill_polygon(@pathlist.flatten.compact, @snd, @chn, @ax, cr) free_cairo(cr) end @pathlist.clear self end def draw_or_fill_in if number?(@style) and @style.nonzero? draw else fill_in end end def circle(x0, y0, rad) cr = make_cairo(channel_widgets(@snd, @chn)[0]) draw_dot(to_x(x0), to_y(y0), (@size * rad * 2.0).floor, @snd, @chn, @ax, cr) free_cairo(cr) self end private def to_x(x) (@xoff + @size * x).floor end def to_y(y) (@yoff - @size * y).floor end end # # cmn-glyphs.lisp # # CLEFS # # all draw functions have optional *args # *args: x-offset (0.0) # y-offset (0.0) # size (50.0) # style (0) # 0: fill_in else draw # snd (0) # (integer or true/false) # chn (0) # (integer or true/false) # ax (0) # axis-context (integer or false) def draw_treble_clef(*args) score = SND_Draw.new("treble clef", *args) score.moveto(0.490, -0.258) score.curveto(0.516, -0.430, 0.546, -0.672, 0.298, -0.590) score.curveto(0.404, -0.580, 0.432, -0.436, 0.320, -0.398) score.curveto(0.210, -0.398, 0.180, -0.518, 0.256, -0.600) score.curveto(0.290, -0.622, 0.310, -0.630, 0.338, -0.638) score.curveto(0.576, -0.668, 0.554, -0.402, 0.522, -0.252) score.curveto(0.892, -0.126, 0.746, 0.314, 0.442, 0.236) score.curveto(0.436, 0.286, 0.410, 0.388, 0.420, 0.440) score.curveto(0.430, 0.490, 0.484, 0.558, 0.510, 0.606) score.curveto(0.624, 0.814, 0.616, 1.000, 0.496, 1.108) score.curveto(0.410, 1.118, 0.348, 0.888, 0.348, 0.744) score.curveto(0.348, 0.696, 0.364, 0.618, 0.348, 0.576) score.curveto(0.332, 0.530, 0.290, 0.482, 0.264, 0.440) score.curveto(0.152, 0.260, 0.054, 0.082, 0.182, -0.120) score.curveto(0.256, -0.238, 0.358, -0.258, 0.490, -0.258) score.moveto(0.394, 0.622) score.curveto(0.374, 0.696, 0.370, 0.978, 0.512, 0.996) score.curveto(0.666, 0.948, 0.454, 0.668, 0.394, 0.622) score.moveto(0.382, 0.398) score.lineto(0.410, 0.224) score.curveto(0.252, 0.126, 0.252, -0.062, 0.358, -0.106) score.lineto(0.372, -0.088) score.curveto(0.284, 0.004, 0.346, 0.132, 0.424, 0.136) score.lineto(0.482, -0.222) score.curveto(0.382, -0.220, 0.306, -0.222, 0.236, -0.134) score.curveto(0.096, 0.038, 0.278, 0.242, 0.384, 0.406) score.moveto(0.516, -0.220) score.lineto(0.458, 0.146) score.curveto(0.678, 0.176, 0.744, -0.146, 0.516, -0.220) score.draw_or_fill_in score end def draw_percussion_clef(*args) score = SND_Draw.new("percussion clef", *args) score.moveto(0, 0) score.lineto(0, 0.5) score.rlineto(0.045, 0) score.rlineto(0, -0.5) score.rlineto(-0.045, 0) score.draw_or_fill_in score.moveto(0.085, 0) score.rlineto(0, 0.5) score.rlineto(0.045, 0) score.rlineto(0, -0.5) score.draw_or_fill_in score end def draw_c_clef(*args) score = SND_Draw.new("c clef", *args) score.moveto(0.465, 0.442) score.lineto(0.465, 0.475) score.curveto(0.765, 0.503, 0.643, 0.012, 0.515, 0.080) score.curveto(0.453, 0.132, 0.450, 0.197, 0.423, 0.257) score.curveto(0.382, 0.115, 0.352, 0.042, 0.305, 0.005) score.lineto(0.305, 0.500) score.lineto(0.282, 0.500) score.lineto(0.282, -0.500) score.lineto(0.305, -0.500) score.lineto(0.305, -0.005) score.curveto(0.353, -0.043, 0.380, -0.112, 0.423, -0.257) score.curveto(0.452, -0.192, 0.455, -0.132, 0.517, -0.080) score.curveto(0.643, -0.012, 0.765, -0.503, 0.467, -0.475) score.lineto(0.467, -0.438) score.curveto(0.533, -0.385, 0.503, -0.293, 0.417, -0.305) score.curveto(0.263, -0.383, 0.483, -0.645, 0.692, -0.437) score.curveto(0.825, -0.283, 0.693, 0.032, 0.440, -0.075) score.lineto(0.410, 0.000) score.lineto(0.440, 0.075) score.curveto(0.693, -0.032, 0.825, 0.283, 0.692, 0.437) score.curveto(0.493, 0.647, 0.263, 0.377, 0.430, 0.303) score.curveto(0.502, 0.297, 0.547, 0.383, 0.468, 0.442) score.draw_or_fill_in score.moveto(0.120, 0.500) score.lineto(0.120, -0.500) score.lineto(0.227, -0.500) score.lineto(0.227, 0.500) score.lineto(0.120, 0.500) score.draw_or_fill_in score end def draw_bass_clef(*args) score = SND_Draw.new("bass clef", *args) score.moveto(0.058, 0.075) score.curveto(0.115, 0.053, 0.108, 0.145, 0.223, 0.098) score.curveto(0.292, 0.052, 0.278, -0.057, 0.173, -0.072) score.curveto(0.085, -0.080, 0.003, -0.018, 0.007, 0.098) score.curveto(0.045, 0.262, 0.238, 0.288, 0.343, 0.250) score.curveto(0.492, 0.192, 0.532, 0.067, 0.517, -0.047) score.curveto(0.497, -0.292, 0.072, -0.522, 0.017, -0.535) score.lineto(0.007, -0.512) score.curveto(0.127, -0.452, 0.302, -0.342, 0.367, -0.152) score.curveto(0.437, 0.045, 0.377, 0.187, 0.275, 0.227) score.curveto(0.128, 0.267, 0.012, 0.165, 0.062, 0.075) score.draw_or_fill_in score.circle(0.6, 0.1, 0.0525) score.circle(0.6, -0.1, 0.0525) score end # # ORNAMENTS and ACCENTS # def draw_turn(*args) score = SND_Draw.new("turn", *args) score.moveto(-0.096, 0.062) score.curveto(-0.130, 0.104, -0.124, 0.208, -0.048, 0.214) score.curveto( 0.060, 0.204, 0.154, 0.040, 0.258, 0.010) score.curveto( 0.384, -0.028, 0.524, 0.116, 0.418, 0.220) score.curveto( 0.372, 0.266, 0.264, 0.262, 0.278, 0.180) score.curveto( 0.310, 0.122, 0.370, 0.154, 0.394, 0.196) score.curveto( 0.432, 0.144, 0.428, 0.054, 0.342, 0.044) score.curveto( 0.242, 0.054, 0.148, 0.216, 0.046, 0.248) score.curveto(-0.080, 0.296, -0.220, 0.142, -0.114, 0.036) score.curveto(-0.070, -0.008, 0.040, -0.004, 0.028, 0.080) score.curveto(-0.002, 0.142, -0.066, 0.102, -0.096, 0.062) score.draw_or_fill_in score end def draw_mordent(*args) score = SND_Draw.new("mordent", *args) score.moveto(0.310, 0.103) score.curveto(0.335, 0.129, 0.334, 0.129, 0.359, 0.104) score.lineto(0.425, 0.031) score.curveto(0.459, -0.001, 0.444, -0.002, 0.478, 0.028) score.lineto(0.606, 0.156) score.lineto(0.606, 0.193) score.lineto(0.563, 0.146) score.curveto(0.536, 0.121, 0.535, 0.121, 0.505, 0.151) score.lineto(0.436, 0.231) score.curveto(0.407, 0.262, 0.416, 0.258, 0.388, 0.232) score.lineto(0.307, 0.156) score.curveto(0.282, 0.132, 0.283, 0.130, 0.262, 0.153) score.lineto(0.190, 0.232) score.curveto(0.161, 0.265, 0.167, 0.265, 0.136, 0.237) score.lineto(0.000, 0.111) score.lineto(0.000, 0.075) score.lineto(0.051, 0.122) score.curveto(0.083, 0.153, 0.086, 0.152, 0.109, 0.120) score.lineto(0.189, 0.030) score.curveto(0.214, 0.003, 0.206, 0.003, 0.236, 0.031) score.lineto(0.310, 0.103) score.draw_or_fill_in score end def draw_double_mordent(*args) score = SND_Draw.new("double mordent", *args) score.moveto(0.560, 0.106) score.curveto(0.586, 0.132, 0.583, 0.132, 0.620, 0.092) score.lineto(0.681, 0.031) score.curveto(0.708, 0.000, 0.707, 0.004, 0.736, 0.027) score.lineto(0.870, 0.146) score.lineto(0.870, 0.187) score.lineto(0.821, 0.138) score.curveto(0.793, 0.115, 0.796, 0.111, 0.761, 0.145) score.lineto(0.691, 0.220) score.curveto(0.662, 0.257, 0.655, 0.257, 0.629, 0.224) score.lineto(0.558, 0.145) score.curveto(0.533, 0.121, 0.537, 0.118, 0.505, 0.151) score.lineto(0.439, 0.224) score.curveto(0.416, 0.251, 0.418, 0.252, 0.393, 0.227) score.lineto(0.320, 0.159) score.curveto(0.286, 0.121, 0.286, 0.125, 0.256, 0.156) score.lineto(0.189, 0.226) score.curveto(0.154, 0.266, 0.160, 0.266, 0.131, 0.238) score.lineto(0.000, 0.115) score.lineto(0.000, 0.075) score.lineto(0.050, 0.121) score.curveto(0.081, 0.151, 0.077, 0.146, 0.108, 0.117) score.lineto(0.188, 0.029) score.curveto(0.210, 0.000, 0.210, 0.006, 0.236, 0.030) score.lineto(0.310, 0.104) score.curveto(0.333, 0.130, 0.331, 0.128, 0.358, 0.100) score.lineto(0.425, 0.027) score.curveto(0.448, 0.004, 0.444, 0.007, 0.476, 0.031) score.lineto(0.561, 0.105) score.draw_or_fill_in score end def draw_trill_section(*args) score = SND_Draw.new("trill", *args) score.moveto(-0.045, 0.053) score.lineto(-0.045, 0.075) score.curveto(-0.028, 0.099, 0.058, 0.171, 0.113, 0.158) score.curveto(0.179, 0.142, 0.245, 0.076, 0.287, 0.079) score.curveto(0.339, 0.076, 0.354, 0.095, 0.383, 0.118) score.lineto(0.383, 0.097) score.curveto(0.366, 0.076, 0.279, 0.001, 0.223, 0.008) score.curveto(0.150, 0.014, 0.095, 0.091, 0.050, 0.094) score.curveto(0.002, 0.097, -0.017, 0.079, -0.045, 0.053) score.draw_or_fill_in score end def draw_trill_sections(count, *args) score = SND_Draw.new(count.to_s + " trill sections", *args) x0 = 0.0 count.times do score.moveto(x0 + -0.045, 0.053) score.lineto(x0 + -0.045, 0.075) score.curveto(x0 + -0.028, 0.099, x0 + 0.058, 0.171, x0 + 0.113, 0.158) score.curveto(x0 + 0.179, 0.142, x0 + 0.245, 0.076, x0 + 0.287, 0.079) score.curveto(x0 + 0.339, 0.076, x0 + 0.354, 0.095, x0 + 0.383, 0.118) score.lineto(x0 + 0.383, 0.097) score.curveto(x0 + 0.366, 0.076, x0 + 0.279, 0.001, x0 + 0.223, 0.008) score.curveto(x0 + 0.150, 0.014, x0 + 0.095, 0.091, x0 + 0.050, 0.094) score.curveto(x0 + 0.002, 0.097, x0 + -0.017, 0.079, x0 + -0.045, 0.053) score.draw_or_fill_in x0 += 0.385 end score end def draw_arpeggio(*args) score = SND_Draw.new("arpeggio", *args) score.moveto(0.005, 0.147) score.curveto(-0.004, 0.115, 0.042, 0.046, 0.047, 0.039) score.curveto(0.049, 0.034, 0.068, 0.005, 0.071, 0.005) score.curveto(0.097, 0.009, 0.074, 0.027, 0.070, 0.041) score.curveto(0.054, 0.071, 0.055, 0.083, 0.056, 0.098) score.curveto(0.067, 0.137, 0.112, 0.153, 0.132, 0.203) score.curveto(0.138, 0.261, 0.042, 0.318, 0.058, 0.347) score.curveto(0.061, 0.389, 0.125, 0.414, 0.141, 0.455) score.curveto(0.142, 0.497, 0.105, 0.527, 0.097, 0.539) score.curveto(0.094, 0.541, 0.074, 0.573, 0.070, 0.574) score.curveto(0.047, 0.568, 0.065, 0.547, 0.075, 0.534) score.curveto(0.085, 0.511, 0.099, 0.513, 0.085, 0.485) score.curveto(0.061, 0.451, 0.010, 0.432, 0.004, 0.389) score.curveto(0.015, 0.326, 0.084, 0.284, 0.081, 0.245) score.curveto(0.083, 0.206, 0.018, 0.193, 0.004, 0.146) score.draw_or_fill_in score end def draw_arpeggios(count, *args) score = SND_Draw.new(count.to_s + " arpeggios", *args) y0 = 0.0 count.times do score.moveto(0.005, y0 + 0.147) score.curveto(-0.004, y0 + 0.115, 0.042, y0 + 0.046, 0.047, y0 + 0.039) score.curveto(0.049, y0 + 0.034, 0.068, y0 + 0.005, 0.071, y0 + 0.005) score.curveto(0.097, y0 + 0.009, 0.074, y0 + 0.027, 0.070, y0 + 0.041) score.curveto(0.054, y0 + 0.071, 0.055, y0 + 0.083, 0.056, y0 + 0.098) score.curveto(0.067, y0 + 0.137, 0.112, y0 + 0.153, 0.132, y0 + 0.203) score.curveto(0.138, y0 + 0.261, 0.042, y0 + 0.318, 0.058, y0 + 0.347) score.curveto(0.061, y0 + 0.389, 0.125, y0 + 0.414, 0.141, y0 + 0.455) score.curveto(0.142, y0 + 0.497, 0.105, y0 + 0.527, 0.097, y0 + 0.539) score.curveto(0.094, y0 + 0.541, 0.074, y0 + 0.573, 0.070, y0 + 0.574) score.curveto(0.047, y0 + 0.568, 0.065, y0 + 0.547, 0.075, y0 + 0.534) score.curveto(0.085, y0 + 0.511, 0.099, y0 + 0.513, 0.085, y0 + 0.485) score.curveto(0.061, y0 + 0.451, 0.010, y0 + 0.432, 0.004, y0 + 0.389) score.curveto(0.015, y0 + 0.326, 0.084, y0 + 0.284, 0.081, y0 + 0.245) score.curveto(0.083, y0 + 0.206, 0.018, y0 + 0.193, 0.004, y0 + 0.146) score.draw_or_fill_in y0 += 0.52 end score end def draw_tr(*args) score = SND_Draw.new("tr", *args) score.moveto(0.162, 0.252) score.lineto(0.198, 0.380) score.lineto(0.183, 0.380) score.lineto(0.121, 0.341) score.lineto(0.093, 0.248) score.lineto(-0.005, 0.244) score.lineto(-0.020, 0.210) score.lineto(0.083, 0.216) score.lineto(0.032, 0.050) score.curveto(0.002, -0.038, 0.044, -0.034, 0.205, 0.021) score.lineto(0.198, -0.005) score.lineto(0.262, -0.005) score.lineto(0.324, 0.205) score.curveto(0.325, 0.207, 0.339, 0.239, 0.359, 0.248) score.curveto(0.384, 0.240, 0.368, 0.222, 0.369, 0.209) score.curveto(0.380, 0.164, 0.429, 0.169, 0.434, 0.215) score.curveto(0.435, 0.281, 0.333, 0.294, 0.305, 0.222) score.curveto(0.300, 0.276, 0.243, 0.260, 0.209, 0.256) score.lineto(0.162, 0.252) score.moveto(0.146, 0.211) score.curveto(0.228, 0.220, 0.269, 0.237, 0.266, 0.216) score.lineto(0.222, 0.076) score.curveto(0.224, 0.058, 0.075, 0.005, 0.099, 0.041) score.lineto(0.146, 0.211) score.draw_or_fill_in score end def draw_accent(*args) score = SND_Draw.new("accent", *args) score.moveto(0, 0) score.lineto(0.4, 0.124) score.lineto(0, 0.248) score.lineto(0, 0.216) score.lineto(0.3, 0.124) score.lineto(0.0, 0.032) score.lineto(0, 0) score.draw_or_fill_in score end def draw_tnecca(*args) score = SND_Draw.new("accent reversed", *args) score.moveto(0, 0.124) score.lineto(0.4, 0.248) score.lineto(0.4, 0.216) score.lineto(0.1, 0.124) score.lineto(0.4, 0.032) score.lineto(0.4, 0) score.lineto(0, 0.124) score.draw_or_fill_in score end # # PAUSES # def draw_breath_mark(*args) score = SND_Draw.new("breath mark", *args) score.moveto(0.027, -0.005) score.curveto(0.047, 0.093, 0.192, 0.085, 0.186, -0.055) score.curveto(0.183, -0.144, 0.104, -0.198, 0.049, -0.224) score.lineto(0.045, -0.215) score.curveto(0.138, -0.135, 0.161, -0.087, 0.127, -0.060) score.curveto(0.093, -0.094, 0.025, -0.075, 0.027, -0.005) score.draw_or_fill_in score end def draw_caesura(*args) score = SND_Draw.new("caesura", *args) score.moveto(0, 0) score.lineto(0.05, 0) score.lineto(0.33, 0.5) score.lineto(0.28, 0.5) score.lineto(0, 0) score.draw_or_fill_in score.moveto(0.17, 0) score.lineto(0.22, 0) score.lineto(0.5, 0.5) score.lineto(0.45, 0.5) score.lineto(0.17, 0) score.draw_or_fill_in score end def draw_fermata(*args) score = SND_Draw.new("fermata", *args) score.moveto(0, 0) score.curveto(-0.023, 0.197, 0.14, 0.38, 0.338, 0.38) score.curveto(0.535, 0.38, 0.698, 0.197, 0.675, 0.0) score.rlineto(-0.01, 0.0) score.curveto(0.652, 0.173, 0.513, 0.296, 0.338, 0.296) score.curveto(0.163, 0.296, 0.023, 0.173, 0.01, 0.0) score.lineto(0, 0) score.draw_or_fill_in score.circle(0.338, 0.0925, 0.05) score end def draw_upside_down_fermata(*args) score = SND_Draw.new("fermata reversed", *args) score.moveto(0.0000, -0.003) score.curveto(-0.023, -0.199, 0.14, -0.383, 0.338, -0.383) score.curveto(0.535, -0.383, 0.698, -0.199, 0.675, -0.003) score.rlineto(-0.01, 0) score.curveto(0.652, -0.176, 0.513, -0.298, 0.338, -0.298) score.curveto(0.163, -0.298, 0.023, -0.176, 0.01, -0.003) score.lineto(0, -0.003) score.draw_or_fill_in score.circle(0.338, -0.0925, 0.05) score end # # MISCELLANEOUS # def draw_repeat_sign(*args) score = SND_Draw.new("repeat", *args) score.moveto(0, 0) score.lineto(0.425, 0.5) score.rlineto(0.173, 0) score.rlineto(-0.425, -0.5) score.draw_or_fill_in score.circle(0.121, 0.375, 0.06) score.circle(0.490, 0.121, 0.06) score end def draw_upper_bracket(*args) score = SND_Draw.new("upper bracket", *args) score.moveto(0.100, 0.365) score.rlineto(0.000, -0.145) score.rlineto(0.075, 0.000) score.rlineto(0.000, 0.110) score.curveto(0.230, 0.350, 0.270, 0.370, 0.310, 0.430) score.rlineto(-0.012, 0.003) score.curveto(0.270, 0.400, 0.230, 0.370, 0.100, 0.365) score.draw_or_fill_in score end def draw_lower_bracket(*args) score = SND_Draw.new("lower bracket", *args) score.moveto(0.100, -0.365) score.rlineto(0.000, 0.145) score.rlineto(0.075, 0.000) score.rlineto(0.000, -0.110) score.curveto(0.230, -0.350, 0.270, -0.370, 0.310, -0.430) score.rlineto(-0.012, -0.003) score.curveto(0.270, -0.400, 0.230, -0.370, 0.100, -0.365) score.draw_or_fill_in score end def draw_segno(*args) score = SND_Draw.new("segno", *args) score.moveto(0.533, 0.688) score.lineto(0.479, 0.688) score.lineto(0.278, 0.396) score.curveto(0.144, 0.515, 0.086, 0.550, 0.093, 0.611) score.curveto(0.097, 0.705, 0.264, 0.704, 0.236, 0.626) score.curveto(0.237, 0.601, 0.210, 0.596, 0.204, 0.567) score.curveto(0.211, 0.476, 0.334, 0.494, 0.315, 0.587) score.curveto(0.271, 0.850, -0.209, 0.656, 0.220, 0.312) score.lineto(0.016, 0.007) score.lineto(0.068, 0.007) score.lineto(0.262, 0.287) score.curveto(0.340, 0.236, 0.486, 0.141, 0.450, 0.059) score.curveto(0.431, -0.023, 0.305, -0.005, 0.306, 0.060) score.curveto(0.303, 0.094, 0.344, 0.087, 0.338, 0.130) score.curveto(0.331, 0.209, 0.231, 0.211, 0.224, 0.121) score.curveto(0.261, -0.190, 0.776, 0.047, 0.319, 0.374) score.lineto(0.533, 0.688) score.draw_or_fill_in score.circle(0.09, 0.28, 0.05) score.circle(0.45, 0.40, 0.05) score end def draw_coda(*args) score = SND_Draw.new("coda", *args) score.moveto(0.241, 0.379) score.lineto(0.241, 0.429) score.lineto(0.216, 0.429) score.lineto(0.216, 0.379) score.curveto(0.130, 0.375, 0.071, 0.280, 0.075, 0.196) score.lineto(0.020, 0.196) score.lineto(0.020, 0.171) score.lineto(0.077, 0.171) score.curveto(0.071, 0.090, 0.132, -0.002, 0.216, -0.006) score.lineto(0.216, -0.056) score.lineto(0.241, -0.056) score.lineto(0.241, -0.006) score.curveto(0.321, 0.002, 0.381, 0.090, 0.376, 0.171) score.lineto(0.431, 0.171) score.lineto(0.431, 0.196) score.lineto(0.376, 0.196) score.curveto(0.382, 0.279, 0.324, 0.379, 0.241, 0.379) score.moveto(0.308, 0.169) score.curveto(0.308, 0.097, 0.294, 0.037, 0.241, 0.020) score.lineto(0.241, 0.171) score.lineto(0.307, 0.171) score.moveto(0.216, 0.020) score.curveto(0.163, 0.040, 0.144, 0.109, 0.141, 0.171) score.lineto(0.216, 0.171) score.lineto(0.216, 0.020) score.moveto(0.141, 0.196) score.curveto(0.145, 0.265, 0.166, 0.346, 0.216, 0.353) score.lineto(0.216, 0.196) score.lineto(0.137, 0.196) score.moveto(0.241, 0.353) score.curveto(0.286, 0.345, 0.308, 0.265, 0.312, 0.196) score.lineto(0.241, 0.196) score.lineto(0.241, 0.353) score.draw_or_fill_in score end def draw_pedal_off(*args) score = SND_Draw.new("pedal off", *args) score.moveto(0.219, 0.198) score.curveto(0.231, 0.172, 0.195, 0.138, 0.162, 0.173) score.curveto(0.149, 0.219, 0.206, 0.231, 0.219, 0.198) score.moveto(0.144, 0.242) score.curveto(0.166, 0.223, 0.193, 0.230, 0.181, 0.267) score.curveto(0.178, 0.306, 0.144, 0.302, 0.151, 0.335) score.curveto(0.160, 0.381, 0.225, 0.377, 0.224, 0.330) score.curveto(0.228, 0.302, 0.198, 0.306, 0.197, 0.267) score.curveto(0.194, 0.237, 0.213, 0.222, 0.237, 0.247) score.curveto(0.263, 0.276, 0.234, 0.297, 0.268, 0.322) score.curveto(0.314, 0.347, 0.354, 0.297, 0.316, 0.259) score.curveto(0.296, 0.237, 0.273, 0.266, 0.246, 0.237) score.curveto(0.223, 0.217, 0.232, 0.194, 0.266, 0.197) score.curveto(0.303, 0.202, 0.302, 0.232, 0.332, 0.228) score.curveto(0.381, 0.232, 0.388, 0.156, 0.332, 0.152) score.curveto(0.302, 0.148, 0.302, 0.185, 0.266, 0.183) score.curveto(0.231, 0.186, 0.228, 0.169, 0.245, 0.143) score.curveto(0.273, 0.116, 0.297, 0.141, 0.316, 0.117) score.curveto(0.350, 0.075, 0.303, 0.029, 0.258, 0.062) score.curveto(0.237, 0.082, 0.261, 0.102, 0.233, 0.133) score.curveto(0.212, 0.151, 0.194, 0.147, 0.197, 0.113) score.curveto(0.203, 0.075, 0.232, 0.075, 0.230, 0.043) score.curveto(0.223, -0.004, 0.159, -0.002, 0.152, 0.042) score.curveto(0.148, 0.075, 0.185, 0.076, 0.183, 0.113) score.curveto(0.183, 0.147, 0.163, 0.150, 0.141, 0.133) score.curveto(0.113, 0.104, 0.140, 0.079, 0.113, 0.059) score.curveto(0.069, 0.037, 0.033, 0.077, 0.063, 0.117) score.curveto(0.082, 0.141, 0.104, 0.117, 0.132, 0.142) score.curveto(0.153, 0.163, 0.144, 0.188, 0.113, 0.182) score.curveto(0.073, 0.182, 0.075, 0.147, 0.046, 0.152) score.curveto(-0.003, 0.152, -0.003, 0.227, 0.048, 0.227) score.curveto(0.075, 0.231, 0.075, 0.198, 0.113, 0.196) score.curveto(0.141, 0.197, 0.147, 0.207, 0.133, 0.237) score.curveto(0.102, 0.264, 0.082, 0.237, 0.062, 0.261) score.curveto(0.028, 0.302, 0.077, 0.347, 0.118, 0.318) score.curveto(0.138, 0.297, 0.116, 0.275, 0.144, 0.242) score.draw_or_fill_in score end def draw_ped(*args) score = SND_Draw.new("ped", *args) score.moveto(0.368, 0.074) score.curveto(0.341, 0.121, 0.335, 0.147, 0.371, 0.203) score.curveto(0.435, 0.289, 0.531, 0.243, 0.488, 0.155) score.curveto(0.472, 0.117, 0.434, 0.096, 0.414, 0.080) score.curveto(0.429, 0.038, 0.494, -0.006, 0.541, 0.075) score.curveto(0.559, 0.123, 0.558, 0.224, 0.663, 0.252) score.curveto(0.603, 0.354, 0.449, 0.393, 0.461, 0.405) score.curveto(0.902, 0.262, 0.705, -0.124, 0.555, 0.046) score.curveto(0.488, -0.032, 0.417, 0.021, 0.389, 0.055) score.curveto(0.303, -0.018, 0.303, -0.020, 0.248, 0.040) score.curveto(0.218, 0.108, 0.191, 0.062, 0.164, 0.047) score.curveto(0.010, -0.056, 0.032, 0.019, 0.124, 0.062) score.curveto(0.229, 0.117, 0.200, 0.091, 0.228, 0.195) score.curveto(0.240, 0.241, 0.149, 0.250, 0.166, 0.311) score.lineto(0.207, 0.493) score.curveto(-0.041, 0.441, 0.049, 0.261, 0.126, 0.387) score.lineto(0.138, 0.381) score.curveto(-0.020, 0.119, -0.100, 0.472, 0.220, 0.507) score.curveto(0.548, 0.486, 0.399, 0.171, 0.254, 0.374) score.lineto(0.264, 0.384) score.curveto(0.338, 0.259, 0.521, 0.449, 0.228, 0.488) score.lineto(0.198, 0.356) score.curveto(0.181, 0.304, 0.273, 0.294, 0.262, 0.241) score.lineto(0.229, 0.101) score.curveto(0.273, 0.070, 0.282, -0.038, 0.368, 0.074) score.moveto(0.391, 0.094) score.curveto(0.456, 0.130, 0.476, 0.171, 0.468, 0.213) score.curveto(0.452, 0.276, 0.333, 0.171, 0.391, 0.094) score.moveto(0.627, 0.019) score.curveto(0.533, 0.041, 0.586, 0.228, 0.678, 0.229) score.curveto(0.729, 0.170, 0.712, 0.025, 0.627, 0.019) score.draw_or_fill_in score.circle(0.8, 0.04, 0.04) score end def draw_left_paren(*args) score = SND_Draw.new("left paren", *args) score.moveto(0.157, 0.580) score.curveto(0.090, 0.540, -0.015, 0.442, -0.012, 0.287) score.curveto(-0.007, 0.145, 0.082, 0.040, 0.147, -0.005) score.lineto(0.153, 0.003) score.curveto(0.035, 0.122, 0.047, 0.193, 0.047, 0.297) score.curveto(0.042, 0.417, 0.067, 0.490, 0.162, 0.570) score.lineto(0.157, 0.580) score.draw_or_fill_in score end def draw_right_paren(*args) score = SND_Draw.new("right paren", *args) score.moveto(0.005, 0.580) score.curveto(0.072, 0.540, 0.177, 0.442, 0.174, 0.287) score.curveto(0.169, 0.145, 0.080, 0.040, 0.015, -0.005) score.lineto(0.009, 0.003) score.curveto(0.127, 0.122, 0.115, 0.193, 0.115, 0.297) score.curveto(0.120, 0.417, 0.095, 0.490, 0.0, 0.570) score.lineto(0.005, 0.580) score.draw_or_fill_in score end def draw_wedge(*args) score = SND_Draw.new("wedge", *args) score.moveto(0, 0) score.lineto(-0.075, 0.25) score.lineto(0.075, 0.25) score.lineto(0, 0) score.draw_or_fill_in score end def draw_down_bow(*args) score = SND_Draw.new("down bow", *args) score.moveto(0, 0) score.lineto(0, 0.15) score.lineto(0.3, 0.15) score.lineto(0.3, 0) score.lineto(0.29, 0) score.lineto(0.29, 0.075) score.lineto(0.01, 0.075) score.lineto(0.01, 0) score.lineto(0, 0) score.draw_or_fill_in score end def draw_up_bow(*args) score = SND_Draw.new("up bow", *args) score.moveto(0.075, 0.000) score.lineto(0.000, 0.250) score.lineto(0.010, 0.250) score.lineto(0.075, 0.055) score.lineto(0.140, 0.250) score.lineto(0.150, 0.250) score.lineto(0.075, 0.000) score.draw_or_fill_in score end # # NUMBERS and METERS # def draw_zero(*args) score = SND_Draw.new("zero", *args) score.moveto(0.159, 0.233) score.curveto(0.272, 0.233, 0.333, 0.117, 0.333, 0.000) score.curveto(0.333, -0.130, 0.270, -0.235, 0.159, -0.233) score.curveto(0.041, -0.233, -0.013, -0.122, -0.019, -0.006) score.curveto(-0.015, 0.113, 0.043, 0.233, 0.159, 0.233) score.moveto(0.159, 0.207) score.curveto(0.218, 0.207, 0.228, 0.083, 0.229, -0.002) score.curveto(0.228, -0.085, 0.216, -0.207, 0.159, -0.207) score.curveto(0.100, -0.207, 0.089, -0.085, 0.085, 0.000) score.curveto(0.085, 0.085, 0.096, 0.207, 0.159, 0.207) score.draw_or_fill_in score end def draw_one(*args) score = SND_Draw.new("one", *args) score.moveto(0.070, -0.182) score.curveto(0.068, -0.199, 0.042, -0.203, 0.026, -0.203) score.lineto(0.026, -0.233) score.lineto(0.209, -0.233) score.lineto(0.209, -0.203) score.curveto(0.199, -0.202, 0.171, -0.203, 0.167, -0.187) score.lineto(0.167, 0.233) score.lineto(0.070, 0.233) score.lineto(-0.011, 0.034) score.lineto(0.010, 0.024) score.lineto(0.070, 0.130) score.lineto(0.070, -0.182) score.draw_or_fill_in score end def draw_two(*args) score = SND_Draw.new("two", *args) score.moveto(0.068, 0.170) score.curveto(0.093, 0.168, 0.130, 0.167, 0.130, 0.113) score.curveto(0.123, 0.042, 0.007, 0.044, 0.006, 0.131) score.curveto(0.007, 0.179, 0.074, 0.233, 0.146, 0.233) score.curveto(0.224, 0.233, 0.318, 0.202, 0.329, 0.107) score.curveto(0.320, 0.010, 0.238, -0.013, 0.152, -0.052) score.curveto(0.105, -0.071, 0.063, -0.114, 0.067, -0.137) score.curveto(0.113, -0.107, 0.157, -0.100, 0.205, -0.122) score.curveto(0.239, -0.138, 0.252, -0.170, 0.274, -0.170) score.curveto(0.329, -0.170, 0.316, -0.111, 0.316, -0.107) score.lineto(0.337, -0.107) score.curveto(0.335, -0.158, 0.326, -0.231, 0.244, -0.237) score.curveto(0.165, -0.235, 0.146, -0.172, 0.083, -0.172) score.curveto(0.015, -0.167, 0.024, -0.217, 0.019, -0.226) score.lineto(0.000, -0.226) score.lineto(0.000, -0.161) score.curveto(0.011, -0.072, 0.231, 0.014, 0.233, 0.104) score.curveto(0.233, 0.167, 0.194, 0.205, 0.111, 0.200) score.curveto(0.068, 0.198, 0.050, 0.168, 0.068, 0.170) score.draw_or_fill_in score end def draw_three(*args) score = SND_Draw.new("three", *args) score.moveto(0.094, 0.007) score.curveto(0.163, 0.028, 0.204, 0.039, 0.203, 0.102) score.curveto(0.212, 0.180, 0.159, 0.209, 0.117, 0.207) score.curveto(0.072, 0.210, 0.026, 0.165, 0.052, 0.155) score.curveto(0.113, 0.148, 0.113, 0.074, 0.050, 0.068) score.curveto(0.020, 0.070, -0.010, 0.092, -0.005, 0.147) score.curveto(0.034, 0.273, 0.291, 0.257, 0.292, 0.103) score.curveto(0.292, 0.039, 0.265, 0.019, 0.220, 0.000) score.curveto(0.259, -0.017, 0.291, -0.043, 0.289, -0.114) score.curveto(0.272, -0.281, -0.001, -0.262, -0.011, -0.134) score.curveto(-0.013, -0.091, 0.020, -0.063, 0.050, -0.067) score.curveto(0.098, -0.070, 0.113, -0.144, 0.052, -0.157) score.curveto(0.033, -0.172, 0.065, -0.207, 0.117, -0.207) score.curveto(0.170, -0.201, 0.208, -0.177, 0.204, -0.099) score.curveto(0.200, -0.038, 0.163, -0.028, 0.094, -0.007) score.lineto(0.094, 0.007) score.draw_or_fill_in score end def draw_four(*args) score = SND_Draw.new("four", *args) score.moveto(0.252, 0.233) score.lineto(0.113, 0.233) score.curveto(0.107, 0.128, 0.108, 0.003, -0.002, -0.097) score.lineto(-0.002, -0.122) score.lineto(0.159, -0.122) score.lineto(0.159, -0.188) score.curveto(0.157, -0.198, 0.130, -0.207, 0.115, -0.206) score.lineto(0.115, -0.233) score.lineto(0.309, -0.233) score.lineto(0.309, -0.207) score.curveto(0.299, -0.207, 0.274, -0.203, 0.268, -0.187) score.lineto(0.268, -0.122) score.lineto(0.309, -0.122) score.lineto(0.309, -0.096) score.lineto(0.265, -0.096) score.lineto(0.265, 0.146) score.lineto(0.159, 0.017) score.lineto(0.159, -0.096) score.lineto(0.043, -0.096) score.curveto(0.139, 0.021, 0.217, 0.149, 0.252, 0.233) score.draw_or_fill_in score end def draw_five(*args) score = SND_Draw.new("five", *args) score.moveto(0.022, 0.233) score.lineto(0.022, -0.002) score.lineto(0.050, -0.002) score.curveto(0.067, 0.026, 0.093, 0.041, 0.124, 0.041) score.curveto(0.178, 0.041, 0.207, -0.015, 0.207, -0.070) score.curveto(0.209, -0.165, 0.169, -0.211, 0.120, -0.212) score.curveto(0.098, -0.215, 0.076, -0.211, 0.056, -0.187) score.curveto(0.039, -0.149, 0.114, -0.196, 0.118, -0.126) score.curveto(0.104, -0.067, 0.015, -0.068, 0.008, -0.145) score.curveto(0.005, -0.275, 0.306, -0.297, 0.296, -0.063) score.curveto(0.283, 0.028, 0.224, 0.068, 0.137, 0.068) score.curveto(0.109, 0.068, 0.076, 0.056, 0.050, 0.030) score.lineto(0.050, 0.159) score.curveto(0.057, 0.152, 0.152, 0.135, 0.199, 0.155) score.curveto(0.248, 0.176, 0.264, 0.203, 0.269, 0.236) score.curveto(0.181, 0.212, 0.087, 0.211, 0.022, 0.233) score.draw_or_fill_in score end def draw_six(*args) score = SND_Draw.new("six", *args) score.moveto(0.168, -0.238) score.curveto(0.244, -0.235, 0.303, -0.182, 0.305, -0.096) score.curveto(0.305, -0.043, 0.274, 0.030, 0.205, 0.030) score.curveto(0.167, 0.030, 0.137, 0.015, 0.115, -0.015) score.curveto(0.093, -0.006, 0.089, 0.176, 0.150, 0.207) score.curveto(0.194, 0.235, 0.242, 0.198, 0.231, 0.181) score.curveto(0.207, 0.176, 0.188, 0.159, 0.190, 0.119) score.curveto(0.208, 0.062, 0.291, 0.069, 0.300, 0.128) score.curveto(0.299, 0.175, 0.276, 0.236, 0.179, 0.240) score.curveto(0.074, 0.235, 0.007, 0.117, 0.007, 0.004) score.curveto(0.011, -0.108, 0.057, -0.231, 0.168, -0.238) score.moveto(0.174, -0.215) score.curveto(0.220, -0.212, 0.228, -0.155, 0.228, -0.108) score.curveto(0.229, -0.061, 0.222, 0.006, 0.174, 0.006) score.curveto(0.124, 0.006, 0.115, -0.058, 0.117, -0.108) score.curveto(0.118, -0.157, 0.126, -0.215, 0.174, -0.215) score.draw_or_fill_in score end def draw_seven(*args) score = SND_Draw.new("seven", *args) score.moveto(0.068, -0.233) score.lineto(0.202, -0.233) score.curveto(0.202, -0.228, 0.185, -0.117, 0.229, -0.048) score.curveto(0.263, 0.007, 0.338, 0.076, 0.330, 0.234) score.lineto(0.306, 0.234) score.curveto(0.266, 0.147, 0.235, 0.205, 0.169, 0.225) score.curveto(0.080, 0.235, 0.061, 0.169, 0.028, 0.220) score.lineto(0.004, 0.220) score.lineto(0.004, 0.120) score.lineto(0.028, 0.120) score.curveto(0.037, 0.164, 0.106, 0.177, 0.151, 0.139) score.curveto(0.214, 0.099, 0.265, 0.112, 0.294, 0.142) score.curveto(0.286, 0.060, 0.218, 0.004, 0.159, -0.046) score.curveto(0.077, -0.112, 0.067, -0.226, 0.068, -0.233) score.draw_or_fill_in score end def draw_eight(*args) score = SND_Draw.new("eight", *args) score.moveto(0.146, 0.235) score.curveto(0.068, 0.233, 0.015, 0.198, -0.004, 0.125) score.curveto(-0.011, 0.048, 0.055, 0.024, 0.068, 0.009) score.curveto(0.042, -0.006, -0.006, -0.051, -0.007, -0.117) score.curveto(0.002, -0.189, 0.054, -0.234, 0.154, -0.238) score.curveto(0.228, -0.237, 0.295, -0.195, 0.296, -0.109) score.curveto(0.301, -0.073, 0.279, -0.025, 0.220, 0.015) score.curveto(0.265, 0.045, 0.290, 0.082, 0.287, 0.131) score.curveto(0.279, 0.193, 0.213, 0.233, 0.146, 0.235) score.moveto(0.146, 0.209) score.curveto(0.200, 0.208, 0.233, 0.170, 0.235, 0.114) score.curveto(0.237, 0.083, 0.208, 0.052, 0.185, 0.038) score.curveto(0.149, 0.070, 0.085, 0.083, 0.069, 0.140) score.curveto(0.069, 0.172, 0.101, 0.208, 0.146, 0.209) score.moveto(0.099, -0.014) score.curveto(0.132, -0.040, 0.191, -0.055, 0.224, -0.114) score.curveto(0.240, -0.166, 0.207, -0.207, 0.146, -0.207) score.curveto(0.080, -0.202, 0.051, -0.150, 0.047, -0.098) score.curveto(0.043, -0.059, 0.073, -0.024, 0.098, -0.013) score.draw_or_fill_in score end def draw_nine(*args) score = SND_Draw.new("nine", *args) score.moveto(0.129, 0.235) score.curveto(-0.113, 0.212, -0.049, -0.123, 0.189, -0.003) score.curveto(0.211, 0.006, 0.216, -0.176, 0.157, -0.198) score.curveto(0.106, -0.232, 0.072, -0.203, 0.079, -0.197) score.curveto(0.125, -0.179, 0.135, -0.142, 0.114, -0.105) score.curveto(0.096, -0.065, 0.019, -0.072, 0.003, -0.133) score.curveto(0.000, -0.193, 0.053, -0.244, 0.132, -0.235) score.curveto(0.220, -0.231, 0.307, -0.117, 0.307, -0.003) score.curveto(0.309, 0.111, 0.264, 0.240, 0.131, 0.235) score.moveto(0.131, 0.215) score.curveto(0.085, 0.213, 0.075, 0.155, 0.076, 0.109) score.curveto(0.076, 0.059, 0.080, -0.006, 0.131, -0.006) score.curveto(0.181, -0.007, 0.191, 0.059, 0.187, 0.109) score.curveto(0.187, 0.157, 0.178, 0.215, 0.131, 0.215) score.draw_or_fill_in score end def draw_common_time(*args) score = SND_Draw.new("common time", *args) score.moveto(0.004, 0.000) score.moveto(0.004, 0.000) score.curveto(0.004, -0.128, 0.096, -0.247, 0.228, -0.247) score.curveto(0.328, -0.246, 0.391, -0.171, 0.410, -0.070) score.lineto(0.383, -0.070) score.curveto(0.366, -0.160, 0.310, -0.215, 0.230, -0.223) score.curveto(0.136, -0.220, 0.110, -0.114, 0.113, -0.002) score.curveto(0.113, 0.102, 0.128, 0.200, 0.224, 0.220) score.curveto(0.266, 0.230, 0.312, 0.220, 0.344, 0.186) score.curveto(0.358, 0.172, 0.356, 0.162, 0.334, 0.156) score.curveto(0.300, 0.159, 0.263, 0.134, 0.263, 0.084) score.curveto(0.270, -0.004, 0.414, -0.001, 0.418, 0.096) score.curveto(0.418, 0.210, 0.310, 0.258, 0.218, 0.252) score.curveto(0.092, 0.246, 0.004, 0.128, 0.004, 0.000) score.draw_or_fill_in score end def draw_cut_time(*args) score = SND_Draw.new("", *args) draw_common_time(*args) score.moveto(0.194, 0.374) score.lineto(0.194, -0.414) score.lineto(0.222, -0.414) score.lineto(0.222, 0.374) score.draw_or_fill_in score end def draw_plus(*args) score = SND_Draw.new("plus", *args) score.moveto(0.000, -0.020) score.lineto(0.100, -0.020) score.lineto(0.100, -0.140) score.lineto(0.140, -0.140) score.lineto(0.140, -0.020) score.lineto(0.240, -0.020) score.lineto(0.240, 0.020) score.lineto(0.140, 0.020) score.lineto(0.140, 0.140) score.lineto(0.100, 0.140) score.lineto(0.100, 0.020) score.lineto(0.000, 0.020) score.lineto(0.000, -0.020) score.draw_or_fill_in score end # # ACCIDENTALS # def draw_sharp(*args) score = SND_Draw.new("sharp", *args) score.moveto(0.168, 0.098) score.lineto(0.168, -0.050) score.lineto(0.210, -0.032) score.lineto(0.210, -0.136) score.lineto(0.168, -0.154) score.lineto(0.168, -0.338) score.lineto(0.140, -0.338) score.lineto(0.140, -0.166) score.lineto(0.072, -0.194) score.lineto(0.072, -0.380) score.lineto(0.044, -0.380) score.lineto(0.044, -0.206) score.lineto(0.000, -0.222) score.lineto(0.000, -0.116) score.lineto(0.044, -0.100) score.lineto(0.044, 0.048) score.lineto(0.000, 0.032) score.lineto(0.000, 0.138) score.lineto(0.044, 0.154) score.lineto(0.044, 0.338) score.lineto(0.072, 0.338) score.lineto(0.072, 0.166) score.lineto(0.140, 0.192) score.lineto(0.140, 0.380) score.lineto(0.168, 0.380) score.lineto(0.168, 0.204) score.lineto(0.210, 0.222) score.lineto(0.210, 0.116) score.lineto(0.168, 0.098) score.moveto(0.140, 0.088) score.lineto(0.072, 0.060) score.lineto(0.072, -0.088) score.lineto(0.140, -0.060) score.lineto(0.140, 0.088) score.draw_or_fill_in score end def draw_flat(*args) score = SND_Draw.new("flat", *args) score.moveto(0.027, 0.086) score.lineto(0.027, 0.483) score.lineto(0.000, 0.483) score.lineto(0.000, -0.193) score.curveto(0.012, -0.186, 0.070, -0.139, 0.097, -0.119) score.curveto(0.141, -0.086, 0.244, -0.024, 0.215, 0.082) score.curveto(0.165, 0.204, 0.027, 0.087, 0.027, 0.086) score.moveto(0.027, 0.037) score.lineto(0.027, -0.137) score.curveto(0.032, -0.140, 0.206, 0.029, 0.120, 0.090) score.curveto(0.112, 0.093, 0.085, 0.105, 0.027, 0.037) score.draw_or_fill_in score end def draw_double_sharp(*args) score = SND_Draw.new("double sharp", *args) score.moveto(0.000, 0.130) score.lineto(0.090, 0.130) score.curveto(0.091, -0.002, 0.174, -0.001, 0.170, 0.130) score.lineto(0.260, 0.130) score.lineto(0.260, 0.040) score.curveto(0.127, 0.028, 0.136, -0.040, 0.260, -0.040) score.lineto(0.260, -0.130) score.lineto(0.170, -0.130) score.curveto(0.165, 0.002, 0.091, 0.000, 0.090, -0.130) score.lineto(0.000, -0.130) score.lineto(0.000, -0.043) score.curveto(0.127, -0.042, 0.127, 0.027, 0.000, 0.040) score.lineto(0.000, 0.130) score.draw_or_fill_in score end def draw_natural(*args) score = SND_Draw.new("natural", *args) score.moveto(0.000, -0.180) score.lineto(0.144, -0.142) score.lineto(0.144, -0.348) score.lineto(0.170, -0.348) score.lineto(0.170, 0.176) score.lineto(0.026, 0.138) score.lineto(0.026, 0.348) score.lineto(0.000, 0.348) score.lineto(0.000, -0.180) score.moveto(0.026, -0.076) score.lineto(0.026, 0.048) score.lineto(0.144, 0.078) score.lineto(0.144, -0.046) score.lineto(0.026, -0.076) score.draw_or_fill_in score end def draw_double_flat(*args) score = SND_Draw.new("double flat", *args) draw_flat(*args) draw_flat(*args) score end # # DYNAMICS # def draw_f(*args) score = SND_Draw.new("f", *args) score.moveto(0.420, 0.238) score.lineto(0.330, 0.238) score.curveto(0.330, 0.230, 0.334, 0.348, 0.418, 0.386) score.curveto(0.444, 0.398, 0.496, 0.400, 0.490, 0.374) score.curveto(0.488, 0.362, 0.462, 0.370, 0.452, 0.360) score.curveto(0.429, 0.342, 0.426, 0.308, 0.448, 0.292) score.curveto(0.478, 0.276, 0.521, 0.292, 0.514, 0.344) score.curveto(0.514, 0.400, 0.456, 0.432, 0.386, 0.414) score.curveto(0.258, 0.380, 0.232, 0.240, 0.234, 0.238) score.lineto(0.158, 0.238) score.lineto(0.158, 0.210) score.lineto(0.228, 0.210) score.curveto(0.228, 0.208, 0.172, -0.046, 0.122, -0.117) score.curveto(0.114, -0.133, 0.096, -0.158, 0.078, -0.158) score.curveto(0.056, -0.162, 0.046, -0.142, 0.060, -0.139) score.curveto(0.099, -0.138, 0.113, -0.074, 0.056, -0.059) score.curveto(0.022, -0.052, -0.018, -0.102, 0.007, -0.146) score.curveto(0.026, -0.176, 0.088, -0.188, 0.134, -0.162) score.curveto(0.244, -0.100, 0.287, 0.046, 0.324, 0.210) score.lineto(0.420, 0.210) score.lineto(0.420, 0.238) score.draw_or_fill_in score end def draw_p(*args) score = SND_Draw.new("p", *args) score.moveto(0.184, 0.047) score.curveto(0.203, 0.016, 0.218, 0.006, 0.248, 0.004) score.curveto(0.379, 0.002, 0.464, 0.230, 0.336, 0.290) score.curveto(0.280, 0.310, 0.228, 0.262, 0.211, 0.246) score.curveto(0.210, 0.333, 0.126, 0.312, 0.068, 0.153) score.lineto(0.089, 0.147) score.curveto(0.155, 0.310, 0.205, 0.279, 0.185, 0.224) score.lineto(0.040, -0.120) score.lineto(0.000, -0.120) score.lineto(0.000, -0.146) score.lineto(0.157, -0.146) score.lineto(0.157, -0.120) score.lineto(0.117, -0.120) score.lineto(0.184, 0.047) score.moveto(0.222, 0.047) score.curveto(0.160, 0.086, 0.245, 0.261, 0.321, 0.268) score.curveto(0.377, 0.218, 0.303, 0.029, 0.222, 0.047) score.draw_or_fill_in score end def draw_lig_p(*args) score = SND_Draw.new("P", *args) score.moveto(0.184, 0.047) score.curveto(0.203, 0.016, 0.218, 0.006, 0.248, 0.004) score.curveto(0.379, 0.002, 0.464, 0.230, 0.336, 0.290) score.curveto(0.280, 0.310, 0.228, 0.262, 0.211, 0.246) score.curveto(0.205, 0.285, 0.168, 0.304, 0.138, 0.296) score.lineto(0.136, 0.270) score.curveto(0.162, 0.278, 0.190, 0.257, 0.185, 0.224) score.lineto(0.040, -0.120) score.lineto(0.000, -0.120) score.lineto(0.000, -0.145) score.lineto(0.157, -0.145) score.lineto(0.157, -0.120) score.lineto(0.117, -0.120) score.lineto(0.184, 0.047) score.moveto(0.222, 0.047) score.curveto(0.160, 0.086, 0.245, 0.261, 0.321, 0.268) score.curveto(0.377, 0.218, 0.303, 0.029, 0.222, 0.047) score.draw_or_fill_in score end def draw_m(*args) score = SND_Draw.new("m", *args) score.moveto(0.188, 0.000) score.lineto(0.271, 0.226) score.curveto(0.287, 0.270, 0.252, 0.303, 0.207, 0.225) score.lineto(0.120, 0.000) score.lineto(0.052, 0.000) score.lineto(0.157, 0.261) score.curveto(0.160, 0.304, 0.072, 0.266, 0.045, 0.184) score.lineto(0.027, 0.184) score.curveto(0.056, 0.245, 0.100, 0.301, 0.159, 0.292) score.curveto(0.188, 0.286, 0.200, 0.262, 0.200, 0.243) score.curveto(0.228, 0.303, 0.327, 0.312, 0.333, 0.243) score.curveto(0.373, 0.317, 0.488, 0.303, 0.468, 0.236) score.lineto(0.396, 0.038) score.curveto(0.386, 0.001, 0.435, 0.024, 0.460, 0.074) score.lineto(0.472, 0.071) score.curveto(0.429, -0.026, 0.310, -0.065, 0.335, 0.019) score.lineto(0.403, 0.222) score.curveto(0.424, 0.273, 0.375, 0.291, 0.346, 0.228) score.lineto(0.264, 0.000) score.lineto(0.186, 0.000) score.draw_or_fill_in score end def draw_n(*args) score = SND_Draw.new("n", *args) score.moveto(0.210, 0.019) score.lineto(0.280, 0.226) score.curveto(0.287, 0.270, 0.253, 0.302, 0.207, 0.225) score.lineto(0.120, 0.000) score.lineto(0.052, 0.000) score.lineto(0.158, 0.261) score.curveto(0.160, 0.304, 0.072, 0.266, 0.045, 0.184) score.lineto(0.028, 0.184) score.curveto(0.056, 0.245, 0.100, 0.301, 0.159, 0.292) score.curveto(0.188, 0.286, 0.200, 0.263, 0.200, 0.242) score.curveto(0.228, 0.302, 0.338, 0.312, 0.341, 0.243) score.lineto(0.265, 0.024) score.curveto(0.264, 0.001, 0.331, 0.024, 0.340, 0.074) score.lineto(0.352, 0.071) score.curveto(0.33, -0.026, 0.210, -0.065, 0.210, 0.019) score.draw_or_fill_in score end def draw_niente(*args) score = SND_Draw.new("n.", *args) draw_n(*args) score.circle(0.425, 0.025, 0.03) score end def draw_subito(*args) score = SND_Draw.new("I", *args) score.moveto(0.3, -0.2) score.rlineto(0, 0.7) score.draw score end def draw_z(*args) score = SND_Draw.new("z", *args) score.moveto(0.082, 0.287) score.lineto(0.052, 0.222) score.lineto(0.069, 0.222) score.lineto(0.089, 0.240) score.lineto(0.238, 0.240) score.lineto(-0.003, 0.006) score.lineto(0.034, 0.006) score.curveto(0.072, 0.043, 0.156, 0.028, 0.191, 0.003) score.curveto(0.274, -0.021, 0.302, 0.046, 0.265, 0.101) score.curveto(0.251, 0.117, 0.219, 0.118, 0.205, 0.093) score.curveto(0.206, 0.050, 0.249, 0.075, 0.246, 0.041) score.curveto(0.206, 0.000, 0.196, 0.113, 0.092, 0.061) score.lineto(0.299, 0.261) score.lineto(0.299, 0.287) score.lineto(0.082, 0.287) score.draw_or_fill_in score end def draw_s(*args) score = SND_Draw.new("s", *args) score.moveto(0.148, 0.066) score.curveto(0.161, 0.028, 0.130, 0.002, 0.083, 0.009) score.curveto(0.032, 0.038, 0.107, 0.045, 0.077, 0.088) score.curveto(0.055, 0.113, 0.018, 0.101, 0.014, 0.068) score.curveto(0.019, -0.043, 0.216, -0.041, 0.208, 0.076) score.curveto(0.200, 0.141, 0.113, 0.167, 0.091, 0.211) score.curveto(0.072, 0.255, 0.134, 0.297, 0.172, 0.268) score.curveto(0.212, 0.237, 0.145, 0.225, 0.188, 0.188) score.curveto(0.223, 0.179, 0.242, 0.199, 0.236, 0.224) score.curveto(0.209, 0.327, 0.028, 0.306, 0.032, 0.212) score.curveto(0.037, 0.149, 0.142, 0.116, 0.148, 0.066) score.draw_or_fill_in score end def draw_r(*args) score = SND_Draw.new("r", *args) score.moveto(0.210, 0.010) score.curveto(0.243, 0.184, 0.262, 0.219, 0.295, 0.246) score.curveto(0.350, 0.261, 0.311, 0.213, 0.349, 0.198) score.curveto(0.398, 0.181, 0.431, 0.252, 0.368, 0.291) score.curveto(0.327, 0.308, 0.278, 0.268, 0.256, 0.235) score.curveto(0.303, 0.336, 0.172, 0.345, 0.072, 0.198) score.lineto(0.085, 0.186) score.curveto(0.123, 0.248, 0.206, 0.312, 0.185, 0.239) score.lineto(0.129, 0.010) score.lineto(0.210, 0.010) score.draw_or_fill_in score end # # NOTE HEADS and FLAGS # def draw_double_whole_note(*args) score = SND_Draw.new("double whole note", *args) score.moveto(0.298, 0.127) score.curveto(0.393, 0.127, 0.501, 0.087, 0.505, 0.000) score.curveto(0.508, -0.095, 0.393, -0.128, 0.298, -0.127) score.curveto(0.207, -0.125, 0.100, -0.087, 0.100, 0.000) score.curveto(0.102, 0.091, 0.204, 0.127, 0.298, 0.127) score.moveto(0.263, 0.108) score.curveto(0.325, 0.124, 0.370, 0.065, 0.381, 0.001) score.curveto(0.389, -0.050, 0.387, -0.091, 0.342, -0.108) score.curveto(0.286, -0.125, 0.247, -0.075, 0.230, -0.023) score.curveto(0.214, 0.039, 0.212, 0.089, 0.263, 0.108) score.draw_or_fill_in score.moveto(0.000, 0.166) score.lineto(0.031, 0.166) score.lineto(0.031, -0.166) score.lineto(0.000, -0.166) score.lineto(0.000, 0.166) score.draw_or_fill_in score.moveto(0.069, 0.166) score.lineto(0.100, 0.166) score.lineto(0.100, -0.166) score.lineto(0.069, -0.166) score.lineto(0.069, 0.166) score.draw_or_fill_in score.moveto(0.505, 0.166) score.lineto(0.537, 0.166) score.lineto(0.537, -0.166) score.lineto(0.505, -0.166) score.lineto(0.505, 0.166) score.draw_or_fill_in score.moveto(0.576, 0.166) score.lineto(0.607, 0.166) score.lineto(0.607, -0.166) score.lineto(0.576, -0.166) score.lineto(0.576, 0.166) score.draw_or_fill_in score end def draw_whole_note(*args) score = SND_Draw.new("whole note", *args) score.moveto(0.198, 0.127) score.curveto(0.293, 0.127, 0.402, 0.087, 0.405, 0.000) score.curveto(0.408, -0.095, 0.293, -0.128, 0.198, -0.127) score.curveto(0.107, -0.125, 0.000, -0.087, 0.000, 0.000) score.curveto(0.002, 0.091, 0.104, 0.127, 0.198, 0.127) score.moveto(0.163, 0.108) score.curveto(0.225, 0.124, 0.270, 0.065, 0.281, 0.001) score.curveto(0.289, -0.050, 0.287, -0.091, 0.242, -0.108) score.curveto(0.186, -0.125, 0.147, -0.075, 0.130, -0.023) score.curveto(0.114, 0.039, 0.112, 0.089, 0.163, 0.108) score.draw_or_fill_in score end def draw_half_note(*args) score = SND_Draw.new("half note", *args) score.moveto(0.020, -0.101) score.curveto(-0.063, 0.037, 0.185, 0.197, 0.268, 0.107) score.curveto(0.379, -0.010, 0.137, -0.193, 0.021, -0.101) score.moveto(0.043, -0.082) score.curveto(0.015, -0.007, 0.207, 0.125, 0.239, 0.087) score.curveto(0.291, 0.027, 0.097, -0.139, 0.043, -0.082) score.draw_or_fill_in score end def draw_quarter_note(*args) score = SND_Draw.new("quarer note", *args) score.moveto(0.014, -0.088) score.curveto(-0.014, -0.030, 0.026, 0.056, 0.090, 0.096) score.curveto(0.144, 0.128, 0.230, 0.142, 0.270, 0.092) score.curveto(0.316, 0.024, 0.258, -0.060, 0.190, -0.100) score.curveto(0.130, -0.126, 0.066, -0.136, 0.014, -0.088) score.draw_or_fill_in score end def draw_diamond(*args) score = SND_Draw.new("diamond", *args) score.moveto(0, 0) score.rlineto(0.14, 0.14) score.rlineto(0.14, -0.14) score.rlineto(-0.14, -0.14) score.rlineto(-0.14, 0.14) score.draw_or_fill_in score end def draw_diamond_1(*args) # Anders Vinjar score = SND_Draw.new("diamond-1", *args) score.moveto(0, 0) score.curveto(0.04, 0.03, 0.10, 0.07, 0.14, 0.14) score.curveto(0.12, 0.05, 0.08, 0.03, 0.0, 0.0) score.moveto(0.28, 0.0) score.curveto(0.24, -0.03, 0.18, -0.07, 0.14, -0.14) score.curveto(0.16, -0.07, 0.20, -0.03, 0.28, 0.0) score.moveto(0.0, 0.0) score.lineto(0.05, 0.03) score.curveto(0.1, 0.0, 0.13, -0.02, 0.17, -0.08) score.lineto(0.14, -0.14) score.curveto(0.10, -0.07, 0.04, -0.03, 0, 0) score.moveto(0.28, 0.0) score.lineto(0.23, -0.03) score.curveto(0.20, -0.02, 0.14, 0.01, 0.11, 0.09) score.lineto(0.14, 0.14) score.curveto(0.18, 0.07, 0.24, 0.03, 0.28, 0.0) score.draw_or_fill_in score end def draw_filled_diamond_1(*args) score = SND_Draw.new("filled diamond-1", *args) score.moveto(0, 0) score.curveto(0.04, 0.03, 0.10, 0.07, 0.14, 0.14) score.curveto(0.18, 0.07, 0.24, 0.03, 0.28, 0.0) score.curveto(0.24, -0.03, 0.18, -0.07, 0.14, -0.14) score.curveto(0.10, -0.07, 0.04, -0.03, 0, 0) score.draw_or_fill_in score end def draw_rhythmX(*args) score = SND_Draw.new("X", *args) score.moveto(0.128, 0.000) score.lineto(0.002, 0.102) score.lineto(0.020, 0.124) score.lineto(0.150, 0.020) score.lineto(0.278, 0.124) score.lineto(0.296, 0.102) score.lineto(0.170, 0.000) score.lineto(0.298, -0.102) score.lineto(0.278, -0.124) score.lineto(0.150, -0.020) score.lineto(0.020, -0.124) score.lineto(0.004, -0.104) score.lineto(0.128, 0.000) score.draw_or_fill_in score end def draw_circled_x(*args) score = SND_Draw.new("circled-X", *args) off = 0.06 size = 0.75 score.moveto(size * (off + 0.020), size * 0.124) score.lineto(size * (off + 0.150), size * 0.020) score.lineto(size * (off + 0.278), size * 0.124) score.curveto(size * (off + 0.224), size * 0.190, size * (off + 0.085), size * 0.188, size * (off + 0.020), size * 0.124) score.moveto(size * (off + 0.296), size * 0.102) score.lineto(size * (off + 0.170), size * 0.000) score.lineto(size * (off + 0.297), size * -0.101) score.curveto(size * (off + 0.341), size * -0.056, size * (off + 0.339), size * 0.050, size * (off + 0.296), size * 0.102) score.moveto(size * (off + 0.278), size * -0.124) score.lineto(size * (off + 0.150), size * -0.020) score.lineto(size * (off + 0.020), size * -0.124) score.curveto(size * (off + 0.080), size * -0.189, size * (off + 0.221), size * -0.194, size * (off + 0.278), size * -0.124) score.moveto(size * (off + 0.004), size * -0.104) score.lineto(size * (off + 0.128), size * 0.000) score.lineto(size * (off + 0.003), size * 0.102) score.curveto(size * (off + -0.048), size * 0.055, size * (off + -0.044), size * -0.061, size * (off + 0.004), size * -0.104) score.moveto(size * (off + -0.065), size * 0.003) score.curveto(size * (off + -0.064), size * 0.264, size * (off + 0.360), size * 0.280, size * (off + 0.361), size * 0.000) score.curveto(size * (off + 0.361), size * -0.278, size * (off + -0.059), size * -0.279, size * (off + -0.064), size * 0.000) score.draw_or_fill_in score end def draw_slash(*args) score = SND_Draw.new("slash", *args) score.moveto(0, -0.15) score.rlineto(0.275, 0.275) score.draw score end def draw_mslash(*args) score = SND_Draw.new("m-slash", *args) score.moveto(0.05, -0.225) score.rlineto(0.2, 0.45) score.draw score end def draw_triangle(*args) score = SND_Draw.new("triangle", *args) score.moveto(0.14, -0.11) score.rlineto(-0.14, 0) score.rlineto(0.14, 0.25) score.rlineto(0.14, -0.25) score.rlineto(-0.14, 0) score.draw_or_fill_in score end def draw_square(*args) score = SND_Draw.new("square", *args) score.moveto(0.13, -0.13) score.rlineto(-0.13, 0) score.rlineto(0, 0.26) score.rlineto(0.26, 0) score.rlineto(0, -0.26) score.rlineto(-0.13, 0) score.draw_or_fill_in score end def draw_8th_flag_up(*args) score = SND_Draw.new("8th flag up", *args) score.moveto(0.000, 0.296) score.lineto(0.019, 0.296) score.curveto(0.022, 0.239, 0.031, 0.146, 0.101, 0.092) score.curveto(0.246, -0.053, 0.275, -0.121, 0.268, -0.260) score.curveto(0.260, -0.411, 0.213, -0.482, 0.182, -0.540) score.lineto(0.175, -0.535) score.curveto(0.221, -0.453, 0.247, -0.358, 0.244, -0.257) score.curveto(0.243, -0.119, 0.118, 0.000, 0.021, 0.000) score.lineto(0.021, -0.024) score.lineto(0.000, -0.024) score.lineto(0.000, 0.296) score.draw_or_fill_in score end def draw_extend_flag_up(*args) score = SND_Draw.new("extend flag up", *args) score.moveto(0.000, 0.296) score.lineto(0.021, 0.296) score.curveto(0.025, 0.196, 0.065, 0.158, 0.122, 0.094) score.curveto(0.213, -0.011, 0.400, -0.160, 0.264, -0.512) score.lineto(0.262, -0.494) score.curveto(0.319, -0.325, 0.290, -0.185, 0.240, -0.118) score.curveto(0.194, -0.051, 0.065, 0.076, 0.026, 0.033) score.lineto(0.026, -0.025) score.lineto(0.000, -0.025) score.lineto(0.000, 0.296) score.draw_or_fill_in score end def draw_8th_flag_down(*args) score = SND_Draw.new("8th flag down", *args) score.moveto(0.000, -0.296) score.lineto(0.019, -0.296) score.curveto(0.022, -0.239, 0.031, -0.146, 0.101, -0.092) score.curveto(0.246, 0.053, 0.275, 0.121, 0.268, 0.260) score.curveto(0.260, 0.411, 0.213, 0.482, 0.182, 0.540) score.lineto(0.175, 0.535) score.curveto(0.221, 0.453, 0.247, 0.358, 0.244, 0.257) score.curveto(0.243, 0.119, 0.118, 0.000, 0.021, 0.000) score.lineto(0.021, 0.024) score.lineto(0.000, 0.024) score.lineto(0.000, -0.296) score.draw_or_fill_in score end def draw_extend_flag_down(*args) score = SND_Draw.new("extend flag down", *args) score.moveto(0.000, -0.296) score.lineto(0.021, -0.296) score.curveto(0.025, -0.196, 0.065, -0.158, 0.122, -0.094) score.curveto(0.213, 0.011, 0.400, 0.160, 0.264, 0.512) score.lineto(0.262, 0.494) score.curveto(0.319, 0.325, 0.290, 0.185, 0.240, 0.118) score.curveto(0.194, 0.051, 0.065, -0.076, 0.026, -0.033) score.lineto(0.026, 0.025) score.lineto(0.000, 0.025) score.lineto(0.000, -0.296) score.draw_or_fill_in score end # # RESTS # def draw_draw_whole_rest(*args) score = SND_Draw.new("whole rest", *args) score.moveto(0.063, 0.253) score.lineto(0.063, 0.127) score.lineto(0.359, 0.127) score.lineto(0.359, 0.253) score.lineto(0.422, 0.253) score.lineto(0.422, 0.256) score.lineto(0.000, 0.256) score.lineto(0.000, 0.253) score.lineto(0.063, 0.253) score.draw_or_fill_in score end def draw_half_rest(*args) score = SND_Draw.new("half rest", *args) score.moveto(0.063, 0.127) score.lineto(0.063, 0.000) score.lineto(0.000, 0.000) score.lineto(0.000, -0.003) score.lineto(0.422, -0.003) score.lineto(0.422, 0.000) score.lineto(0.359, 0.000) score.lineto(0.359, 0.127) score.lineto(0.063, 0.127) score.draw_or_fill_in score end def draw_quarter_rest(*args) score = SND_Draw.new("quarter rest", *args) score.moveto(0.072, 0.358) score.curveto(0.120, 0.253, 0.160, 0.158, 0.038, 0.058) score.lineto(0.182, -0.103) score.curveto(-0.028, -0.032, -0.058, -0.248, 0.180, -0.343) score.lineto(0.187, -0.322) score.curveto(0.042, -0.222, 0.150, -0.103, 0.230, -0.142) score.lineto(0.243, -0.127) score.curveto(0.220, -0.082, 0.170, -0.043, 0.157, 0.012) score.curveto(0.165, 0.120, 0.290, 0.113, 0.237, 0.187) score.lineto(0.103, 0.355) score.lineto(0.072, 0.358) score.draw_or_fill_in score end def draw_8th_rest(*args) score = SND_Draw.new("8th rest", *args) score.moveto(0.164, 0.131) score.curveto(0.171, 0.222, 0.046, 0.236, 0.028, 0.136) score.curveto(0.032, 0.030, 0.159, 0.033, 0.224, 0.086) score.lineto(0.140, -0.256) score.lineto(0.174, -0.256) score.lineto(0.286, 0.200) score.lineto(0.259, 0.200) score.curveto(0.249, 0.140, 0.188, 0.074, 0.142, 0.079) score.curveto(0.154, 0.096, 0.166, 0.114, 0.164, 0.131) score.draw_or_fill_in score end def draw_16th_rest(*args) score = SND_Draw.new("16th rest", *args) score.moveto(0.102, -0.170) score.curveto(0.128, -0.152, 0.141, -0.128, 0.136, -0.113) score.curveto(0.144, -0.032, 0.017, -0.020, 0.000, -0.113) score.curveto(0.000, -0.224, 0.146, -0.224, 0.208, -0.163) score.lineto(0.118, -0.503) score.lineto(0.150, -0.503) score.lineto(0.334, 0.200) score.lineto(0.302, 0.200) score.curveto(0.292, 0.141, 0.221, 0.065, 0.168, 0.077) score.curveto(0.167, 0.079, 0.162, 0.081, 0.164, 0.082) score.curveto(0.186, 0.096, 0.196, 0.119, 0.194, 0.136) score.curveto(0.197, 0.221, 0.070, 0.234, 0.056, 0.136) score.curveto(0.058, 0.029, 0.205, 0.018, 0.276, 0.100) score.lineto(0.232, -0.068) score.curveto(0.221, -0.126, 0.165, -0.181, 0.106, -0.171) score.draw_or_fill_in score end def draw_32nd_rest(*args) score = SND_Draw.new("32nd rest", *args) score.moveto(0.164, 0.077) score.curveto(0.182, 0.099, 0.194, 0.114, 0.199, 0.136) score.curveto(0.201, 0.228, 0.070, 0.241, 0.058, 0.136) score.curveto(0.064, 0.034, 0.211, 0.028, 0.270, 0.083) score.lineto(0.228, -0.076) score.curveto(0.219, -0.126, 0.165, -0.174, 0.107, -0.168) score.curveto(0.102, -0.170, 0.109, -0.168, 0.104, -0.168) score.curveto(0.124, -0.151, 0.136, -0.133, 0.136, -0.115) score.curveto(0.142, -0.031, 0.007, -0.019, 0.000, -0.115) score.curveto(0.003, -0.216, 0.146, -0.216, 0.206, -0.170) score.lineto(0.128, -0.510) score.lineto(0.172, -0.510) score.lineto(0.400, 0.453) score.lineto(0.364, 0.453) score.curveto(0.354, 0.393, 0.295, 0.329, 0.229, 0.334) score.curveto(0.260, 0.372, 0.253, 0.354, 0.260, 0.388) score.curveto(0.268, 0.470, 0.129, 0.486, 0.117, 0.388) score.curveto(0.125, 0.285, 0.261, 0.281, 0.330, 0.333) score.lineto(0.294, 0.196) score.curveto(0.282, 0.133, 0.235, 0.077, 0.160, 0.077) score.draw_or_fill_in score end def draw_64th_rest(*args) score = SND_Draw.new("64th rest", *args) score.moveto(0.161, 0.081) score.curveto(0.188, 0.096, 0.196, 0.117, 0.194, 0.136) score.curveto(0.205, 0.210, 0.076, 0.231, 0.058, 0.136) score.curveto(0.054, 0.029, 0.214, 0.019, 0.270, 0.087) score.lineto(0.228, -0.076) score.curveto(0.216, -0.124, 0.163, -0.184, 0.102, -0.170) score.curveto(0.129, -0.151, 0.138, -0.134, 0.136, -0.115) score.curveto(0.147, -0.039, 0.018, -0.013, 0.000, -0.115) score.curveto(0.000, -0.220, 0.151, -0.228, 0.206, -0.170) score.lineto(0.122, -0.510) score.lineto(0.164, -0.510) score.lineto(0.454, 0.708) score.lineto(0.419, 0.708) score.curveto(0.409, 0.644, 0.341, 0.566, 0.281, 0.588) score.curveto(0.306, 0.610, 0.314, 0.630, 0.314, 0.642) score.curveto(0.325, 0.721, 0.189, 0.734, 0.176, 0.642) score.curveto(0.179, 0.536, 0.333, 0.532, 0.386, 0.590) score.lineto(0.347, 0.434) score.curveto(0.341, 0.384, 0.284, 0.325, 0.225, 0.334) score.curveto(0.246, 0.350, 0.254, 0.370, 0.254, 0.388) score.curveto(0.261, 0.466, 0.134, 0.486, 0.117, 0.388) score.curveto(0.119, 0.284, 0.266, 0.279, 0.328, 0.338) score.lineto(0.296, 0.207) score.curveto(0.285, 0.154, 0.235, 0.063, 0.164, 0.080) score.draw_or_fill_in score end def draw_128th_rest(*args) score = SND_Draw.new("128th rest", *args) score.moveto(0.277, 0.586) score.curveto(0.306, 0.604, 0.314, 0.623, 0.314, 0.641) score.curveto(0.320, 0.727, 0.189, 0.733, 0.176, 0.641) score.curveto(0.181, 0.536, 0.343, 0.526, 0.386, 0.589) score.lineto(0.350, 0.434) score.curveto(0.341, 0.400, 0.309, 0.323, 0.226, 0.333) score.curveto(0.246, 0.350, 0.254, 0.369, 0.254, 0.389) score.curveto(0.267, 0.469, 0.134, 0.480, 0.119, 0.389) score.curveto(0.111, 0.286, 0.284, 0.274, 0.326, 0.336) score.lineto(0.296, 0.209) score.curveto(0.286, 0.179, 0.253, 0.067, 0.164, 0.079) score.curveto(0.189, 0.096, 0.194, 0.114, 0.194, 0.136) score.curveto(0.200, 0.223, 0.073, 0.226, 0.059, 0.136) score.curveto(0.059, 0.023, 0.221, 0.027, 0.269, 0.079) score.lineto(0.229, -0.076) score.curveto(0.214, -0.117, 0.180, -0.183, 0.106, -0.170) score.curveto(0.129, -0.153, 0.136, -0.133, 0.136, -0.116) score.curveto(0.147, -0.033, 0.004, -0.020, 0.000, -0.116) score.curveto(0.004, -0.229, 0.160, -0.224, 0.204, -0.176) score.lineto(0.121, -0.510) score.lineto(0.164, -0.510) score.lineto(0.514, 0.954) score.lineto(0.481, 0.954) score.curveto(0.467, 0.903, 0.436, 0.820, 0.340, 0.836) score.curveto(0.367, 0.849, 0.377, 0.874, 0.371, 0.890) score.curveto(0.383, 0.967, 0.250, 0.993, 0.236, 0.890) score.curveto(0.240, 0.787, 0.406, 0.776, 0.446, 0.830) score.lineto(0.416, 0.704) score.curveto(0.406, 0.684, 0.370, 0.576, 0.279, 0.583) score.draw_or_fill_in score end def draw_measure_rest(*args) score = SND_Draw.new("measure rest", *args) score.moveto(0, 0.25) score.rlineto(0, -0.5) score.moveto(0.5, 0.25) score.rlineto(0, -0.5) score.draw score.moveto(0, 0) score.lineto(0.5, 0) score.draw score end def draw_double_whole_rest(*args) score = SND_Draw.new("double whole rest", *args) score.moveto(0, 0.5) score.rlineto(0, 0.25) score.rlineto(0.15, 0) score.rlineto(0, -0.25) score.rlineto(-0.15, 0) score.draw_or_fill_in score end end include Musglyphs def musglyphs_test_1 Musglyphs.public_methods.sort.each do |dr| next unless dr =~ /^draw_/ clm_print("\n%s", dr) update_time_graph(0, 0) if dr == "draw_trill_sections" or dr == "draw_arpeggios" snd_func(dr.intern, 5, 100, 200, 200) else snd_func(dr.intern, 150, 150, 200) end sleep 1 end nil end def musglyphs_test [:draw_treble_clef, :draw_percussion_clef, :draw_c_clef, :draw_bass_clef, :draw_turn, :draw_mordent, :draw_double_mordent, :draw_trill_section, :draw_trill_sections, :draw_arpeggio, :draw_arpeggios, :draw_tr, :draw_accent, :draw_tnecca, :draw_breath_mark, :draw_caesura, :draw_fermata, :draw_upside_down_fermata, :draw_repeat_sign, :draw_upper_bracket, :draw_lower_bracket, :draw_segno, :draw_coda, :draw_pedal_off, :draw_ped, :draw_left_paren, :draw_right_paren, :draw_wedge, :draw_down_bow, :draw_up_bow, :draw_zero, :draw_one, :draw_two, :draw_three, :draw_four, :draw_five, :draw_six, :draw_seven, :draw_eight, :draw_nine, :draw_common_time, :draw_cut_time, :draw_plus, :draw_sharp, :draw_flat, :draw_double_sharp, :draw_natural, :draw_double_flat, :draw_f, :draw_p, :draw_lig_p, :draw_m, :draw_n, :draw_niente, :draw_subito, :draw_z, :draw_s, :draw_r, :draw_double_whole_note, :draw_whole_note, :draw_half_note, :draw_quarter_note, :draw_diamond, :draw_diamond_1, :draw_filled_diamond_1, :draw_rhythmX, :draw_circled_x, :draw_slash, :draw_mslash, :draw_triangle, :draw_square, :draw_8th_flag_up, :draw_extend_flag_up, :draw_8th_flag_down, :draw_extend_flag_down, :draw_draw_whole_rest, :draw_half_rest, :draw_quarter_rest, :draw_8th_rest, :draw_16th_rest, :draw_32nd_rest, :draw_64th_rest, :draw_128th_rest, :draw_measure_rest, :draw_double_whole_rest].each do |dr| clm_print("\n%s", dr) update_time_graph(0, 0) if dr == :draw_trill_sections or dr == :draw_arpeggios snd_func(dr, 5, 100, 200, 200) else snd_func(dr, 150, 150, 200) end sleep 1 end nil end # musglyphs.rb ends here snd-16.1/config.guess0000755000076400007640000012746212306421672012672 0ustar bilbil#! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # 2011, 2012, 2013 Free Software Foundation, Inc. timestamp='2012-12-30' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # # Originally written by Per Bothner. # # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD # # Please send patches with a ChangeLog entry to config-patches@gnu.org. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE_ARCH}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; *:SolidBSD:*:*) echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE="alpha" ;; "EV4.5 (21064)") UNAME_MACHINE="alpha" ;; "LCA4 (21066/21068)") UNAME_MACHINE="alpha" ;; "EV5 (21164)") UNAME_MACHINE="alphaev5" ;; "EV5.6 (21164A)") UNAME_MACHINE="alphaev56" ;; "EV5.6 (21164PC)") UNAME_MACHINE="alphapca56" ;; "EV5.7 (21164PC)") UNAME_MACHINE="alphapca57" ;; "EV6 (21264)") UNAME_MACHINE="alphaev6" ;; "EV6.7 (21264A)") UNAME_MACHINE="alphaev67" ;; "EV6.8CB (21264C)") UNAME_MACHINE="alphaev68" ;; "EV6.8AL (21264B)") UNAME_MACHINE="alphaev68" ;; "EV6.8CX (21264D)") UNAME_MACHINE="alphaev68" ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE="alphaev69" ;; "EV7 (21364)") UNAME_MACHINE="alphaev7" ;; "EV7.9 (21364A)") UNAME_MACHINE="alphaev79" ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 exit $exitcode ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; arm*:riscos:*:*|arm*:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) echo i386-pc-auroraux${UNAME_RELEASE} exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) eval $set_cc_for_build SUN_ARCH="i386" # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH="x86_64" fi fi echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`$dummy $dummyarg` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos${UNAME_RELEASE} exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH="hppa2.0n" ;; 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = "hppa2.0w" ] then eval $set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH="hppa2.0w" else HP_ARCH="hppa64" fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` case ${UNAME_PROCESSOR} in amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; *:MINGW64*:*) echo ${UNAME_MACHINE}-pc-mingw64 exit ;; *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; i*:MSYS*:*) echo ${UNAME_MACHINE}-pc-msys exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; *:Interix*:*) case ${UNAME_MACHINE} in x86) echo i586-pc-interix${UNAME_RELEASE} exit ;; authenticamd | genuineintel | EM64T) echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; IA64) echo ia64-unknown-interix${UNAME_RELEASE} exit ;; esac ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; 8664:Windows_NT:*) echo x86_64-pc-mks exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; aarch64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} exit ;; arm*:Linux:*:*) eval $set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then echo ${UNAME_MACHINE}-unknown-linux-gnu else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then echo ${UNAME_MACHINE}-unknown-linux-gnueabi else echo ${UNAME_MACHINE}-unknown-linux-gnueabihf fi fi exit ;; avr32*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; cris:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-gnu exit ;; crisv32:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-gnu exit ;; frv:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; hexagon:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; i*86:Linux:*:*) LIBC=gnu eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __dietlibc__ LIBC=dietlibc #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` echo "${UNAME_MACHINE}-pc-linux-${LIBC}" exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; mips:Linux:*:* | mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef ${UNAME_MACHINE} #undef ${UNAME_MACHINE}el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=${UNAME_MACHINE}el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=${UNAME_MACHINE} #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; or32:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; padre:Linux:*:*) echo sparc-unknown-linux-gnu exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-gnu exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-gnu ;; PA8*) echo hppa2.0-unknown-linux-gnu ;; *) echo hppa-unknown-linux-gnu ;; esac exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-gnu exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-gnu exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; tile*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-gnu exit ;; x86_64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit ;; i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configury will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo ${UNAME_MACHINE}-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; x86_64:Haiku:*:*) echo x86_64-unknown-haiku exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; SX-7:SUPER-UX:*:*) echo sx7-nec-superux${UNAME_RELEASE} exit ;; SX-8:SUPER-UX:*:*) echo sx8-nec-superux${UNAME_RELEASE} exit ;; SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux${UNAME_RELEASE} exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown case $UNAME_PROCESSOR in i386) eval $set_cc_for_build if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then UNAME_PROCESSOR="x86_64" fi fi ;; unknown) UNAME_PROCESSOR=powerpc ;; esac echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = "x86"; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NEO-?:NONSTOP_KERNEL:*:*) echo neo-tandem-nsk${UNAME_RELEASE} exit ;; NSE-*:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = "386"; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' exit ;; i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos exit ;; i*86:AROS:*:*) echo ${UNAME_MACHINE}-pc-aros exit ;; x86_64:VMkernel:*:*) echo ${UNAME_MACHINE}-unknown-esx exit ;; esac eval $set_cc_for_build cat >$dummy.c < # include #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) printf ("arm-acorn-riscix\n"); exit (0); #endif #if defined (hp300) && !defined (hpux) printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) # if !defined (ultrix) # include # if defined (BSD) # if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); # else # if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); # else printf ("vax-dec-bsd\n"); exit (0); # endif # endif # else printf ("vax-dec-bsd\n"); exit (0); # endif # else printf ("vax-dec-ultrix\n"); exit (0); # endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } # Convex versions that predate uname can use getsysinfo(1) if [ -x /usr/convex/getsysinfo ] then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd exit ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; c34*) echo c34-convex-bsd exit ;; c38*) echo c38-convex-bsd exit ;; c4*) echo c4-convex-bsd exit ;; esac fi cat >&2 < in order to provide the needed information to handle your system. config.guess timestamp = $timestamp uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: snd-16.1/piano.rb0000644000076400007640000005672512306421672012010 0ustar bilbil# piano.rb -- translation of piano.scm -*- snd-ruby -*- # ;;; CLM piano.ins (Scott Van Duyne) translated to Snd/Scheme # Ruby Translator: Michael Scholz # Created: Thu Mar 06 03:58:02 CET 2003 # Changed: Mon Nov 22 13:25:33 CET 2010 module Piano require "ws" require "env" include Math Number_of_stiffness_allpasses = 8 Longitudinal_mode_cutoff_keynum = 29 Longitudinal_mode_stiffness_coefficient = -0.5 Golden_mean = 0.618 Loop_gain_env_t60 = 0.05 Loop_gain_default = 0.9999 Nstrings = 3 # ;;keyNum indexed parameter tables # ;;these should all be &key variable defaults for p instrument Default_loudPole_table = [36, 0.8, 60, 0.85, 84, 0.7, 96, 0.6, 108, 0.5] Default_softPole_table = [36, 0.93, 60, 0.9, 84, 0.9, 96, 0.8, 108, 0.8] Default_loudGain_table = [21.0, 0.7, 36.0, 0.7, 48.0, 0.7, 60.0, 0.65, 72.0, 0.65, 84.0, 0.65, 87.006, 0.681, 88.07, 0.444, 90.653, 0.606, 95.515, 0.731, 99.77, 0.775, 101.897, 0.794, 104.024, 0.8, 105.695, 0.806] Default_softGain_table = [21, 0.25, 108, 0.25] Default_strikePosition_table = [21.0, 0.14, 23.884, 0.139, 36.0, 0.128, 56.756, 0.129, 57.765, 0.13, 59.0, 0.13, 60.0, 0.128, 61.0, 0.128, 62.0, 0.129, 66.128, 0.129, 69.0, 0.128, 72.0, 0.128, 73.0, 0.128, 79.0, 0.128, 80.0, 0.128, 96.0, 0.128, 99.0, 0.128] Default_detuning2_table = [22.017, -0.09, 23.744, -0.09, 36.0, -0.08, 48.055, -0.113, 60.0, -0.135, 67.264, -0.16, 72.0, -0.2, 84.054, -0.301, 96.148, -0.383, 108, -0.383] Default_detuning3_table = [21.435, 0.027, 23.317, 0.043, 36.0, 0.03, 48.0, 0.03, 60.0, 0.03, 72.0, 0.02, 83.984, 0.034, 96.0, 0.034, 99.766, 0.034] Default_stiffnessCoefficient_table = [21.0, -0.92, 24.0, -0.9, 36.0, -0.7, 48.0, -0.25, 60.0, -0.1, 75.179, -0.04, 82.986, -0.04, 92.24, -0.04, 96.0, -0.04, 99.0, 0.2, 108.0, 0.5] Default_singleStringDecayRate_table = [21.678, -2.895, 24.0, -3.0, 36.0, -4.641, 41.953, -5.867, 48.173, -7.113, 53.818, -8.016, 59.693, -8.875, 66.605, -9.434, 73.056, -10.035, 78.931, -10.293, 84.0, -12.185] Default_singleStringZero_table = [21.0, -0.3, 24.466, -0.117, 28.763, -0.047, 36.0, -0.03, 48.0, -0.02, 60.0, -0.01, 72.0, -0.01, 84.0, -0.01, 96.0, -0.01] Default_singleStringPole_table = [21.0, 0.0, 24.466, 0.0, 28.763, 0.0, 36.0, 0.0, 108, 0.0] Default_releaseLoopGain_table = [21.643, 0.739, 24.0, 0.8, 36.0, 0.88, 48.0, 0.91, 60.0, 0.94, 72.0, 0.965, 84.0, 0.987, 88.99, 0.987, 89.0, 1.0, 108.0, 1.0] Default_dryTapFiltCoeft60_table = [36, 0.35, 60, 0.25, 108, 0.15] Default_dryTapFiltCoefTarget_table = [36, -0.8, 60, -0.5, 84, -0.4, 108, -0.1] Default_dryTapFiltCoefCurrent_table = [0, 0, 200, 0] Default_dryTapAmpt60_table = [36, 0.55, 60, 0.5, 108, 0.45] Default_sustainPedalLevel_table = [21.0, 0.25, 24.0, 0.25, 36.0, 0.2, 48.0, 0.125, 60.0, 0.075, 72.0, 0.05, 84.0, 0.03, 96.0, 0.01, 99.0, 0.01] Default_pedalResonancePole_table = [20.841, 0.534, 21.794, 0.518, 33.222, 0.386, 45.127, 0.148, 55.445, -0.065, 69.255, -0.409, 82.905, -0.729, 95.763, -0.869, 106.398, -0.861] Default_pedalEnvelopet60_table = [21.0, 7.5, 108.0, 7.5] Default_soundboardCutofft60_table = [21.0, 0.25, 108.0, 0.25] Default_dryPedalResonanceFactor_table = [21.0, 0.5, 108.0, 0.5] Default_unaCordaGain_table = [21, 1.0, 24, 0.4, 29, 0.1, 29.1, 0.95, 108, 0.95] def p(start, *args) duration = get_args(args, :duration, 1.0) keyNum = get_args(args, :keyNum, 60.0) strike_velocity = get_args(args, :strike_velocity, 0.5) pedal_down = get_args(args, :pedal_down, false) release_time_margin = get_args(args, :release_time_margin, 0.75) amp = get_args(args, :amp, 0.5) detuningFactor = get_args(args, :detuningFactor, 1.0) detuningFactor_table = get_args(args, :detuningFactor_table, []) stiffnessFactor = get_args(args, :stiffnessFactor, 1.0) stiffnessFactor_table = get_args(args, :stiffnessFactor_table, []) pedalPresenceFactor = get_args(args, :pedalPresenceFactor, 0.3) longitudinalMode = get_args(args, :longitudinalMode, 10.5) strikePositionInvFac = get_args(args, :strikePositionInvFac, -0.9) singleStringDecayRateFactor = get_args(args, :singleStringDecayRateFactor, 1.0) loudPole = get_args(args, :loudPole, nil) loudPole_table = get_args(args, :loudPole_table, Default_loudPole_table) softPole = get_args(args, :softPole, nil) softPole_table = get_args(args, :softPole_table, Default_softPole_table) loudGain = get_args(args, :loudGain, nil) loudGain_table = get_args(args, :loudGain_table, Default_loudGain_table) softGain = get_args(args, :softGain, nil) softGain_table = get_args(args, :softGain_table, Default_softGain_table) strikePosition = get_args(args, :strikePosition, nil) strikePosition_table = get_args(args, :strikePosition_table, Default_strikePosition_table) detuning2 = get_args(args, :detuning2, nil) detuning2_table = get_args(args, :detuning2_table, Default_detuning2_table) detuning3 = get_args(args, :detuning3, nil) detuning3_table = get_args(args, :detuning3_table, Default_detuning3_table) stiffnessCoefficient = get_args(args, :stiffnessCoefficient, nil) stiffnessCoefficient_table = get_args(args, :stiffnessCoefficient_table, Default_stiffnessCoefficient_table) singleStringDecayRate = get_args(args, :singleStringDecayRate, nil) singleStringDecayRate_table = get_args(args, :singleStringDecayRate_table, Default_singleStringDecayRate_table) singleStringZero = get_args(args, :singleStringZero, nil) singleStringZero_table = get_args(args, :singleStringZero_table, Default_singleStringZero_table) singleStringPole = get_args(args, :singleStringPole, nil) singleStringPole_table = get_args(args, :singleStringPole_table, Default_singleStringPole_table) releaseLoopGain = get_args(args, :releaseLoopGain, nil) releaseLoopGain_table = get_args(args, :releaseLoopGain_table, Default_releaseLoopGain_table) dryTapFiltCoeft60 = get_args(args, :dryTapFiltCoeft60, nil) dryTapFiltCoeft60_table = get_args(args, :dryTapFiltCoeft60_table, Default_dryTapFiltCoeft60_table) dryTapFiltCoefTarget = get_args(args, :dryTapFiltCoefTarget, nil) dryTapFiltCoefTarget_table = get_args(args, :dryTapFiltCoefTarget_table, Default_dryTapFiltCoefTarget_table) dryTapFiltCoefCurrent = get_args(args, :dryTapFiltCoefCurrent, nil) dryTapFiltCoefCurrent_table = get_args(args, :dryTapFiltCoefCurrent_table, Default_dryTapFiltCoefCurrent_table) dryTapAmpt60 = get_args(args, :dryTapAmpt60, nil) dryTapAmpt60_table = get_args(args, :dryTapAmpt60_table, Default_dryTapAmpt60_table) sustainPedalLevel = get_args(args, :sustainPedalLevel, nil) sustainPedalLevel_table = get_args(args, :sustainPedalLevel_table, Default_sustainPedalLevel_table) pedalResonancePole = get_args(args, :pedalResonancePole, nil) pedalResonancePole_table = get_args(args, :pedalResonancePole_table, Default_pedalResonancePole_table) pedalEnvelopet60 = get_args(args, :pedalEnvelopet60, nil) pedalEnvelopet60_table = get_args(args, :pedalEnvelopet60_table, Default_pedalEnvelopet60_table) soundboardCutofft60 = get_args(args, :soundboardCutofft60, nil) soundboardCutofft60_table = get_args(args, :soundboardCutofft60_table, Default_soundboardCutofft60_table) dryPedalResonanceFactor = get_args(args, :dryPedalResonanceFactor, nil) dryPedalResonanceFactor_table = get_args(args, :dryPedalResonanceFactor_table, Default_dryPedalResonanceFactor_table) unaCordaGain = get_args(args, :unaCordaGain, nil) unaCordaGain_table = get_args(args, :unaCordaGain_table, Default_unaCordaGain_table) dur = seconds2samples(duration) freq = 440.0 * (2.0 ** ((keyNum - 69.0) / 12.0)) wT = (TWO_PI * freq) / mus_srate # ;;look_up parameters in tables (or else use the override value) loudPole = (loudPole or envelope_interp(keyNum, loudPole_table)) softPole = (softPole or envelope_interp(keyNum, softPole_table)) loudGain = (loudGain or envelope_interp(keyNum, loudGain_table)) softGain = (softGain or envelope_interp(keyNum, softGain_table)) strikePosition = (strikePosition or envelope_interp(keyNum, strikePosition_table)) detuning2 = (detuning2 or envelope_interp(keyNum, detuning2_table)) detuning3 = (detuning3 or envelope_interp(keyNum, detuning3_table)) stiffnessCoefficient = (stiffnessCoefficient or envelope_interp(keyNum, stiffnessCoefficient_table)) singleStringDecayRate = (singleStringDecayRate or envelope_interp(keyNum, singleStringDecayRate_table)) singleStringDecayRate = singleStringDecayRateFactor * singleStringDecayRate singleStringZero = (singleStringZero or envelope_interp(keyNum, singleStringZero_table)) singleStringPole = (singleStringPole or envelope_interp(keyNum, singleStringPole_table)) releaseLoopGain = (releaseLoopGain or envelope_interp(keyNum, releaseLoopGain_table)) dryTapFiltCoeft60 = (dryTapFiltCoeft60 or envelope_interp(keyNum, dryTapFiltCoeft60_table)) dryTapFiltCoefTarget = (dryTapFiltCoefTarget or envelope_interp(keyNum, dryTapFiltCoefTarget_table)) dryTapFiltCoefCurrent = (dryTapFiltCoefCurrent or envelope_interp(keyNum, dryTapFiltCoefCurrent_table)) dryTapAmpt60 = (dryTapAmpt60 or envelope_interp(keyNum, dryTapAmpt60_table)) sustainPedalLevel = (sustainPedalLevel or envelope_interp(keyNum, sustainPedalLevel_table)) pedalResonancePole = (pedalResonancePole or envelope_interp(keyNum, pedalResonancePole_table)) pedalEnvelopet60 = (pedalEnvelopet60 or envelope_interp(keyNum, pedalEnvelopet60_table)) soundboardCutofft60 = (soundboardCutofft60 or envelope_interp(keyNum, soundboardCutofft60_table)) dryPedalResonanceFactor = (dryPedalResonanceFactor or envelope_interp(keyNum, dryPedalResonanceFactor_table)) unaCordaGain = (unaCordaGain or envelope_interp(keyNum, unaCordaGain_table)) detuningFactor = if detuningFactor_table.empty? envelope_interp(keyNum, detuningFactor_table) else detuningFactor end stiffnessFactor = if stiffnessFactor_table.empty? envelope_interp(keyNum, stiffnessFactor_table) else stiffnessFactor end # ;;initialize soundboard impulse response elements dryTap_one_pole_one_zero_pair = make_one_pole_one_zero(1.0, 0.0, 0.0) dryTap0 = dryTap_one_pole_one_zero_pair[0] dryTap1 = dryTap_one_pole_one_zero_pair[1] dryTap_coef_expseg = make_expseg(dryTapFiltCoefCurrent, dryTapFiltCoefTarget) drycoefrate = in_t60(dryTapFiltCoeft60) dryTap_one_pole_swept = make_one_pole_swept() dryTap_amp_expseg = make_expseg(1.0, 0.0) dryamprate = in_t60(dryTapAmpt60) # ;;initialize open_string resonance elements wetTap_one_pole_one_zero_pair = make_one_pole_one_zero(1.0 - signum(pedalResonancePole) * pedalResonancePole, 0.0, -pedalResonancePole) wetTap0 = wetTap_one_pole_one_zero_pair[0] wetTap1 = wetTap_one_pole_one_zero_pair[1] wetTap_coef_expseg = make_expseg(0.0, -0.5) wetcoefrate = in_t60(pedalEnvelopet60) wetTap_one_pole_swept = make_one_pole_swept() wetTap_amp_expseg = make_expseg(sustainPedalLevel * pedalPresenceFactor * (pedal_down ? 1.0 : dryPedalResonanceFactor), 0.0) wetamprate = in_t60(pedalEnvelopet60) sb_cutoff_rate = in_t60(soundboardCutofft60) # ;;initialize velocity_dependent piano hammer filter elements hammerPole = softPole + (loudPole - softPole) * strike_velocity hammerGain = softGain + (loudGain - softGain) * strike_velocity hammer_one_pole = Array.new(4) # ;;strike position comb filter delay length agraffe_len = (mus_srate * strikePosition) / freq 0.upto(3) do |i| hammer_one_pole[i] = make_one_pole(1.0 * (1.0 - hammerPole), -hammerPole) end vals = apfloor(agraffe_len, wT) dlen1 = vals[0] apcoef1 = vals[1] agraffe_delay1 = make_delay0(dlen1) agraffe_tuning_ap1 = make_one_pole_allpass(apcoef1) # ;;compute coefficients for and initialize the coupling filter # ;;taking L=g(1 - bz^-1)/(1-b), and computing Hb = -(1-L)/(2-L) attenuationPerPeriod = 10.0 ** (singleStringDecayRate / freq / 20.0) g = attenuationPerPeriod # ;;DC gain b = singleStringZero a = singleStringPole ctemp = 1 + -b + g + -(a * g) + Nstrings * (1 + -b + -g + a * g) cfb0 = (2 * (-1 + b + g + -(a * g))) / ctemp cfb1 = (2 * (a + -(a * b) + -(b * g) + a * b * g)) / ctemp cfa1 = (-a + a * b + -(b * g) + a * b * g + Nstrings * (-a + a * b + b * g + -(a * b * g))) / ctemp couplingFilter_pair = make_one_pole_one_zero(cfb0, cfb1, cfa1) cou0 = couplingFilter_pair[0] cou1 = couplingFilter_pair[1] # ;;determine string tunings (and longitudinal modes, if present) freq1 = if keyNum <= Longitudinal_mode_cutoff_keynum freq * longitudinalMode else freq end freq2 = freq + detuning2 * detuningFactor freq3 = freq + detuning3 * detuningFactor # ;;scale stiffness coefficients, if desired stiffnessCoefficient = if stiffnessFactor > 1.0 stiffnessCoefficient - ((stiffnessCoefficient + 1) * (stiffnessFactor - 1)) else stiffnessCoefficient * stiffnessFactor end stiffnessCoefficientL = if keyNum <= Longitudinal_mode_cutoff_keynum Longitudinal_mode_stiffness_coefficient else stiffnessCoefficient end # ;;initialize the coupled_string elements vals1 = tune_piano(freq1, stiffnessCoefficientL, Number_of_stiffness_allpasses, cfb0, cfb1, cfa1) delayLength1 = vals1[0] tuningCoefficient1 = vals1[1] vals2 = tune_piano(freq2, stiffnessCoefficient, Number_of_stiffness_allpasses, cfb0, cfb1, cfa1) delayLength2 = vals2[0] tuningCoefficient2 = vals2[1] vals3 = tune_piano(freq3, stiffnessCoefficient, Number_of_stiffness_allpasses, cfb0, cfb1, cfa1) delayLength3 = vals3[0] tuningCoefficient3 = vals3[1] string1_delay = make_delay0(delayLength1 - 1) string1_tuning_ap = make_one_pole_allpass(tuningCoefficient1) string1_stiffness_ap = Array.new(8) string2_delay = make_delay0(delayLength2 - 1) string2_tuning_ap = make_one_pole_allpass(tuningCoefficient2) string2_stiffness_ap = Array.new(8) string3_delay = make_delay0(delayLength3 - 1) string3_tuning_ap = make_one_pole_allpass(tuningCoefficient3) string3_stiffness_ap = Array.new(8) # ;;initialize loop_gain envelope loop_gain_expseg = make_expseg(Loop_gain_default, releaseLoopGain) looprate = in_t60(Loop_gain_env_t60) adelOut = 0.0 loop_gain = Loop_gain_default is_release_time = false string1_junction_input = 0.0 string2_junction_input = 0.0 string3_junction_input = 0.0 couplingFilter_output = 0.0 sampCount = 0 noi = make_noise() 0.upto(7) do |i| string1_stiffness_ap[i] = make_one_pole_allpass(stiffnessCoefficientL) end 0.upto(7) do |i| string2_stiffness_ap[i] = make_one_pole_allpass(stiffnessCoefficient) end 0.upto(7) do |i| string3_stiffness_ap[i] = make_one_pole_allpass(stiffnessCoefficient) end run_instrument(start, duration + release_time_margin) do if is_release_time loop_gain = loop_gain_expseg.call(looprate) elsif sampCount == dur is_release_time = true dryamprate = sb_cutoff_rate wetamprate = sb_cutoff_rate end dryTap = (dryTap_amp_expseg.call(dryamprate) * \ dryTap_one_pole_swept.call(one_pole_one_zero(dryTap0, dryTap1, noi.call(amp)), dryTap_coef_expseg.call(drycoefrate))) openStrings = (wetTap_amp_expseg.call(wetamprate) * \ wetTap_one_pole_swept.call(one_pole_one_zero(wetTap0, wetTap1, noi.call(amp)), wetTap_coef_expseg.call(wetcoefrate))) adelIn = dryTap + openStrings 0.upto(3) do |i| adelIn = one_pole(hammer_one_pole[i], adelIn) end combedExcitationSignal = hammerGain * (adelOut + adelIn * strikePositionInvFac) adelOut = agraffe_tuning_ap1.call(delay0(agraffe_delay1, adelIn)) string1_junction_input += couplingFilter_output 0.upto(7) do |i| string1_junction_input = string1_stiffness_ap[i].call(string1_junction_input) end string1_junction_input = (unaCordaGain * combedExcitationSignal + \ loop_gain * delay0(string1_delay, string1_tuning_ap.call(string1_junction_input))) string2_junction_input += couplingFilter_output 0.upto(7) do |i| string2_junction_input = string2_stiffness_ap[i].call(string2_junction_input) end string2_junction_input = (combedExcitationSignal + \ loop_gain * delay0(string2_delay, string2_tuning_ap.call(string2_junction_input))) string3_junction_input += couplingFilter_output 0.upto(7) do |i| string3_junction_input = string3_stiffness_ap[i].call(string3_junction_input) end string3_junction_input = (combedExcitationSignal + \ loop_gain * delay0(string3_delay, string3_tuning_ap.call(string3_junction_input))) couplingFilter_input = string1_junction_input + string2_junction_input + string3_junction_input couplingFilter_output = one_pole_one_zero(cou0, cou1, couplingFilter_input) sampCount += 1 couplingFilter_input end end # ;;; converts t60 values to suitable :rate values for expseg def in_t60(t60) 1.0 - (0.001 ** (1.0 / t60 / mus_srate)) end # ;;; expseg (like musickit asymp) def make_expseg(cv = 0.0, tv = 0.0) lambda do |r| old_cv = cv cv = cv + (tv - cv) * r old_cv # ; (bil) this is slightly different (getting clicks) end end # ;;; signal controlled one-pole lowpass filter def make_one_pole_swept y1 = 0.0 lambda do |input, coef| y1 = (coef + 1) * input - coef * y1 end end # ;;; one-pole allpass filter def make_one_pole_allpass(coeff) coef = coeff x1 = 0.0 y1 = 0.0 lambda do |input| y1 = (coef * (input - y1)) + x1 x1 = input y1 end end def one_pole_one_zero(f0, f1, input) one_zero(f0, one_pole(f1, input)) end def make_one_pole_one_zero(a0, a1, b1) [make_one_zero(a0, a1), make_one_pole(1.0, b1)] end # ;;; very special noise generator def make_noise noise_seed = 16383 lambda do |amp| noise_seed = (noise_seed * 1103515245 + 12345) & 0xffffffff # ;; (bil) added the logand -- otherwise we get an overflow somewhere amp * (((noise_seed / 65536).round % 65536) * 0.0000305185 - 1.0) end end # ;;; delay line unit generator with length 0 capabilities... def make_delay0(len) len > 0 ? make_delay(len) : false end def delay0(f, input) f ? delay(f, input) : input end def ap_phase(a1, wT) atan2((a1 * a1 - 1.0) * sin(wT), 2.0 * a1 + (a1 * a1 + 1.0) * cos(wT)) end def opoz_phase(b0, b1, a1, wT) s = sin(wT) c = cos(wT) atan2(a1 * s * (b0 + b1 * c) - b1 * s * (1 + a1 * c), (b0 + b1 * c) * (1 + a1 * c) + b1 * s * a1 * s) end def get_allpass_coef(samp_frac, wT) ta = tan(-(samp_frac * wT)) c = cos(wT) s = sin(wT) (-ta + signum(ta) * sqrt((ta * ta + 1) * s * s)) / (c * ta - s) end def signum(x) if x == 0.0 0 elsif x < 0.0 -1 else 1 end end def apfloor(len, wT) len_int = len.floor.round len_frac = len - len_int if len_frac < Golden_mean len_int -= 1 len_frac += 1.0 end if len_frac < Golden_mean and len_int > 0 len_int -= 1 len_frac += 1.0 end [len_int, get_allpass_coef(len_frac, wT)] end def tune_piano(frequency, stiffnessCoefficient, numAllpasses, b0, b1, a1) wT = (frequency * TWO_PI) / mus_srate len = (TWO_PI + (numAllpasses * ap_phase(stiffnessCoefficient, wT)) + opoz_phase(1 + 3 * b0, a1 + 3 * b1, a1, wT)) / wT apfloor(len, wT) end end include Piano =begin with_sound(:clm, false, :channels, 1) do 7.times do |i| p(i * 0.5, :duration, 0.5, :keyNum, 24 + 12.0 * i, :strike_velocity, 0.5, :amp, 0.4, :dryPedalResonanceFactor, 0.25) end end with_sound(:clm, false, :channels, 1) do 7.times do |i| p(i * 0.5, :duration, 0.5, :keyNum, 24 + 12.0 * i, :strike_velocity, 0.5, :amp, 0.4, :dryPedalResonanceFactor, 0.25, :detuningFactor_table, [24, 5, 36, 7.0, 48, 7.5, 60, 12.0, 72, 20, 84, 30, 96, 100, 108, 300], :stiffnessFactor_table, [21, 1.5, 24, 1.5, 36, 1.5, 48, 1.5, 60, 1.4, 72, 1.3, 84, 1.2, 96, 1.0, 108, 1.0]) end end with_sound(:clm, false, :channels, 1) do 7.times do |i| p(i * 0.5, :duration, 0.5, :keyNum, 24 + 12.0 * i, :strike_velocity, 0.5, :amp, 0.4, :dryPedalResonanceFactor, 0.25, :singleStringDecayRate_table, [21, -5, 24.0, -5.0, 36.0, -5.4, 41.953, -5.867, 48.173, -7.113, 53.818, -8.016, 59.693, -8.875, 66.605, -9.434, 73.056, -10.035, 78.931, -10.293, 84.000, -12.185], :singleStringPole_table, [21, 0.8, 24, 0.7, 36.0, 0.6, 48, 0.5, 60, 0.3, 84, 0.1, 96, 0.03, 108, 0.03], :stiffnessCoefficient_table, [21.0, -0.92, 24.0, -0.9, 36.0, -0.7, 48.0, -0.250, 60.0, -0.1, 75.179, -0.040, 82.986, -0.040, 92.240, 0.3, 96.0, 0.5, 99.0, 0.7, 108.0, 0.7]) end end with_sound(:clm, false, :channels, 1) do p(0, :duration, 5, :keyNum, 24 + 12.0 * 5, :strike_velocity, 0.5, :amp, 0.4, :dryPedalResonanceFactor, 0.25, :singleStringDecayRateFactor, 1 / 10.0) end =end # piano.rb ends here snd-16.1/effects.rb0000644000076400007640000026054612434353162012317 0ustar bilbil# effects.rb -- Scheme -> Ruby translation # Translator/Author: Michael Scholz # Created: 03/02/07 23:56:21 # Changed: 14/11/13 04:43:14 # Requires --with-motif|gtk # # Tested with Snd 15.x # Ruby 2.x.x # Motif 2.3.3 X11R6 # # module Effects (see new-effects.scm) # plausible_mark_samples # map_chan_over_target_with_sync(target, decay, origin_func) do |in| ... end # effect_framples(target) # # effects_squelch_channel(amount, size, snd, chn) # effects_echo(input_samps, delay_time, echo_amoung, beg, dur, snd, chn) # effects_flecho_1(scaler, secs, input_samps, beg, dur, snd, chn) # effects_zecho_1(scaler, secs, frq, amp, input_samps, beg, dur, snd, chn) # # effects_comb_filter(scaler, size, beg, dur, snd, chn) # effects_comb_chord(scaler, size, amp, interval_one, interval_two, b, d, s, c) # effects_moog(freq, q, beg, dur, snd, chn) # # effects_bbp(freq, bw, beg, dur, snd, chn) # effects_bbr(freq, bw, beg, dur, snd, chn) # effects_bhp(freq, beg, dur, snd, chn) # effects_blp(freq, beg, dur, snd, chn) # # effects_am(freq, en, beg, dur, snd, chn) # effects_rm(freq, en, beg, dur, snd, chn) # # effects_cnv(snd0, amp, snd, chn) # effects_jc_reverb_1(volume, beg, dur, snd, chn) # effects_hello_dentist(frq, amp, beg, dur, snd, chn) # effects_fp(srf, osamp, osfrq, beg, dur, snd, chn) # effects_position_sound(mono_snd, pos, beg, dur, snd, chn) # effects_flange(amount, speed, time, beg, dur, snd, chn) # effects_cross_synthesis_1(cross_snd, amp, fftsize, r, beg, dur, snd, chn) require "clm" require "env" require "extensions" require "rubber" include Math require "hooks" $effects_menu = false # for prefs module Effects def plausible_mark_samples snd = selected_sound chn = selected_channel if ms = marks(snd, chn) ms = ms.map do |x| mark_sample(x) end.sort if ms.length < 2 Snd.display("mark-related action requires two marks") false else if ms.length == 2 ms else lw = left_sample(snd, chn) rw = right_sample(snd, chn) cw = cursor(snd, chn) favor = if cw >= lw and cw <= rw cw else 0.5 * (lw + rw) end centered_points = lambda do |points| if points.length == 2 points else p1, p2, p3 = points[0, 3] if (p1 - favor).abs < (p3 - favor).abs [p1, p2] else centered_points.call(points[1..-1]) end end end centered_points.call(ms) end end else Snd.display("mark-related action requires marks") false end end def map_chan_over_target_with_sync(target, decay, origin_func, &func) okay = case target when :sound (sounds or (Snd.display("no sound") and false)) when :selection selection? or (Snd.display("no selection") and false) when :marks (sounds or marks(selected_sound, selected_channel).length < 2 or (Snd.display("no marks") and false)) else true end if okay snc = sync() ssnd = selected_sound schn = selected_channel ms = (target == :marks and plausible_mark_samples) beg = case target when :sound 0 when :selection selection_position when :cursor cursor(selected_sound, selected_channel(selected_sound)) else (ms ? ms[0] : 0) end overlap = (decay ? (srate().to_f * decay).round : 0) sndlst, chnlst = (snc > 0 ? all_chans() : [[ssnd], [schn]]) sndlst.zip(chnlst) do |snd, chn| dur = if target == :sound or target == :cursor framples(snd, chn) - 1 elsif target == :selection and selection? selection_position + selection_framples else ms[1] end if sync(snd) == snc map_chan(func.call(dur - beg), beg, dur + overlap, origin_func.call(dur - beg), snd, chn) end end end end def effect_framples(target) case target when :sound framples() - 1 when :selection selection_framples else if ms = plausible_mark_samples y = ms.shift ms.each do |x| y -= x end 1 + y.abs else 1 end end end def effect_target_ok(target) if Snd.sounds.empty? false else case target when :sound true when :selection selection? when :marks Snd.marks(selected_sound, selected_channel(selected_sound)).length >= 2 else false end end end def effects_squelch_channel(amount, size, snd = false, chn = false) f0 = make_moving_average(size) f1 = make_moving_average(size, :initial_element, 1.0) map_channel(lambda do |y| y * moving_average(f1, ((moving_average(f0, y * y) < amount) ? 0.0 : 1.0)) end, 0, false, snd, chn, false, format("%s(%s, %s", get_func_name, amount, size)) end def effects_echo(input_samps, delay_time, echo_amount, beg = 0, dur = false, snd = false, chn = false) del = make_delay((delay_time.to_f * srate(snd)).round) samp = 0 samps = (input_samps or dur or framples(snd, chn)) amp = echo_amount map_channel_rb(beg, dur, snd, chn, false, format("%s(%s, %s, %s, %s, %s", get_func_name, input_samps, delay_time, echo_amount, beg, dur)) do |inval| samp += 1 inval + delay(del, amp * (tap(del) + ((samp <= samps) ? inval : 0.0))) end end def effects_flecho_1(scaler, secs, input_samps, beg = 0, dur = false, snd = false, chn = false) flt = make_fir_filter(:order, 4, :xcoeffs, vct(0.125, 0.25, 0.25, 0.125)) del = make_delay((secs.to_f * srate(snd)).round) samp = 0 samps = (input_samps or dur or framples(snd, chn)) amp = scaler map_channel_rb(beg, dur, snd, chn, false, format("%s(%s, %s, %s, %s, %s", get_func_name, scaler, secs, input_samps, beg, dur)) do |inval| samp += 1 inval + delay(del, fir_filter(flt, amp * (tap(del) + ((samp <= samps) ? inval : 0.0)))) end end def effects_zecho_1(scaler, secs, frq, amp, input_samps, beg = 0, dur = false, snd = false, chn = false) os = make_oscil(:frequency, frq) len = (secs.to_f * srate()).round del = make_delay(len, :max_size, (len + amp + 1).to_i) samp = 0 samps = (input_samps or dur or framples(snd, chn)) map_channel_rb(beg, dur, snd, chn, false, format("%s(%s, %s, %s, %s, %s, %s, %s", get_func_name, scaler, secs, frq, amp, input_samps, beg, dur)) do |inval| samp += 1 inval + delay(del, amp * (tap(del) + ((samp <= samps) ? inval : 0.0)), amp * oscil(os)) end end def effects_comb_filter(scaler, size, beg = 0, dur = false, snd = false, chn = false) delay_line = Vct.new(size) delay_loc = 0 map_channel_rb(beg, dur, snd, chn, false, format("%s(%s, %s, %s, %s", get_func_name, scaler, size, beg, dur)) do |inval| result = delay_line[delay_loc] delay_line[delay_loc] = inval + scaler * result delay_loc += 1 if delay_loc >= size then delay_loc = 0 end result end end def effects_comb_chord(scaler, size, amp, interval_one, interval_two, beg = 0, dur = false, snd = false, chn = false) c1 = make_comb(scaler, size) c2 = make_comb(scaler, size * interval_one) c3 = make_comb(scaler, size * interval_two) map_channel_rb(beg, dur, snd, chn, false, format("%s(%s, %s, %s, %s, %s, %s, %s", get_func_name, scaler, size, amp, interval_one, interval_two, beg, dur)) do |inval| amp * (comb(c1, inval) + comb(c2, inval) + comb(c3, inval)) end end def effects_moog(freq, q, beg = 0, dur = false, snd = false, chn = false) gen = make_moog_filter(freq, q) map_channel_rb(beg, dur, snd, chn, false, format("%s(%s, %s, %s, %s", get_func_name, freq, q, beg, dur)) do |inval| moog_filter(gen, inval) end end def effects_bbp(freq, bw, beg = 0, dur = false, snd = false, chn = false) flt = make_butter_band_pass(freq, bw) clm_channel(flt, beg, dur, snd, chn, false, false, format("%s(%s, %s, %s, %s", get_func_name, freq, bw, beg, dur)) end def effects_bbr(freq, bw, beg = 0, dur = false, snd = false, chn = false) flt = make_butter_band_reject(freq, bw) clm_channel(flt, beg, dur, snd, chn, false, false, format("%s(%s, %s, %s, %s", get_func_name, freq, bw, beg, dur)) end def effects_bhp(freq, beg = 0, dur = false, snd = false, chn = false) flt = make_butter_high_pass(freq) clm_channel(flt, beg, dur, snd, chn, false, false, format("%s(%s, %s, %s", get_func_name, freq, beg, dur)) end def effects_blp(freq, beg = 0, dur = false, snd = false, chn = false) flt = make_butter_low_pass(freq) clm_channel(flt, beg, dur, snd, chn, false, false, format("%s(%s, %s, %s", get_func_name, freq, beg, dur)) end def effects_am(freq, en, beg = 0, dur = false, snd = false, chn = false) os = make_oscil(:frequency, freq) e = (en and make_env(:envelope, en, :length, (dur or framples(snd, chn)))) func = if e lambda do |inval| amplitude_modulate(1.0, inval, env(e) * oscil(os)) end else lambda do |inval| amplitude_modulate(1.0, inval, oscil(os)) end end map_channel(func, beg, dur, snd, chn, false, format("%s(%s, %s, %s, %s", get_func_name, freq, (en ? en.inspect : "false"), beg, dur)) end def effects_rm(freq, gliss_env, beg = 0, dur = false, snd = false, chn = false) os = make_oscil(:frequency, freq) e = (gliss_env and make_env(:envelope, gliss_env, :length, (dur or framples(snd, chn)))) func = if e lambda do |inval| inval * env(e) * oscil(os) end else lambda do |inval| inval * oscil(os) end end map_channel(func, beg, dur, snd, chn, false, format("%s(%s, %s, %s, %s", get_func_name, freq, (gliss_env ? gliss_env.inspect : "false"), beg, dur)) end def effects_cnv(snd0, amp, snd = false, chn = false) snd0 = Snd.snd flt_len = framples(snd0) total_len = flt_len + framples(snd, chn) cnv = make_convolve(:filter, channel2vct, 0, flt_len, snd0) sf = make_sampler(0, snd, chn) out_data = Vct.new(total_len) do |i| convolve(cnv, lambda { |dir| next_sample(sf) }) end free_sampler(sf) out_data.scale!(amp) max_samp = out_data.peak vct2channel(out_data, 0, total_len, snd, chn, false, format("%s(%s, %s", get_func_name, snd0, amp)) if max_samp > 1.0 then set_y_bounds([-max_samp, max_samp], snd, chn) end max_samp end def effects_jc_reverb(input_samps, volume) allpass1 = make_all_pass(-0.7, 0.7, 1051) allpass2 = make_all_pass(-0.7, 0.7, 337) allpass3 = make_all_pass(-0.7, 0.7, 113) comb1 = make_comb(0.742, 4799) comb2 = make_comb(0.733, 4999) comb3 = make_comb(0.715, 5399) comb4 = make_comb(0.697, 5801) outdel1 = make_delay((0.013 * srate()).round) comb_sum = 0.0 comb_sum_1 = 0.0 comb_sum_2 = 0.0 samp = 0 lambda do |inval| allpass_sum = all_pass(allpass3, all_pass(allpass2, all_pass(allpass1, (samp < input_samps ? inval : 0.0)))) samp += 1 comb_sum_2 = comb_sum_1 comb_sum_1 = comb_sum comb_sum = (comb(comb1, allpass_sum) + comb(comb2, allpass_sum) + \ comb(comb3, allpass_sum) + comb(comb4, allpass_sum)) inval + volume * delay(outdel1, comb_sum) end end def effects_jc_reverb_1(volume, beg = 0, dur = false, snd = false, chn = false) map_channel(effects_jc_reverb((dur or framples(snd, chn)), volume), beg, dur, snd, chn, false, format("%s(%s, %s, %s", get_func_name, volume, beg, dur)) end def effects_hello_dentist(frq, amp, beg = 0, dur = false, snd = false, chn = false) rn = make_rand_interp(:frequency, frq, :amplitude, amp) i = j = 0 len = (dur or framples(snd, chn)) in_data = channel2vct(beg, len, snd, chn) out_len = (len.to_f * (1.0 + 2.0 * amp)).round out_data = make_vct(out_len) rd = make_src(:srate, 1.0, :input, lambda { |dir| val = (i.between?(0, len - 1) ? in_data[i] : 0.0) i += dir val }) until i == len or j == out_len out_data[j] = src(rd, rand_interp(rn)) j += 1 end vct2channel(out_data, beg, j, snd, chn, false, format("%s(%s, %s, %s, %s", get_func_name, frq, amp, beg, (len == framples(snd, chn) ? "false" : len))) end def effects_fp(srf, osamp, osfrq, beg = 0, dur = false, snd = false, chn = false) os = make_oscil(:frequency, osfrq) sr = make_src(:srate, srf) sf = make_sampler(beg) len = (dur or framples(snd, chn)) out_data = Vct.new(len) do |i| src(sr, osamp * oscil(os), lambda do |dir| if dir > 0 next_sample(sf) else previous_sample(sf) end end) end free_sampler(sf) vct2channel(out_data, beg, len, snd, chn, false, format("%s(%s, %s, %s, %s, %s", get_func_name, srf, osamp, osfrq, beg, (len == framples(snd, chn) ? "false" : len))) end def effects_position_sound(mono_snd, pos, beg = 0, dur = false, snd = false, chn = false) assert_type((sound?(mono_snd) or mono_snd == false), mono_snd, 0, "a sound index") assert_type((array?(pos) or number?(pos)), pos, 1, "an array or a number") len = framples(mono_snd) reader1 = make_sampler(0, mono_snd) if number?(pos) map_channel_rb(0, len, snd, chn, false, format("%s(%s, %s", get_func_name, mono_snd, pos)) do |inval| inval + pos * read_sample(reader1) end else if array?(pos) e1 = make_env(:envelope, pos, :length, len) if number?(chn) and chn == 1 map_channel(0, len, snd, chn, false, format("%s(%s, %s", get_func_name, mono_snd, pos.inspect)) do |inval| inval + env(e1) * read_sample(reader1) end else map_channel(0, len, snd, chn, false, format("%s(%s, %s", get_func_name, mono_snd, pos.inspect)) do |inval| inval + (1.0 - env(e1)) * read_sample(reader1) end end end end end def effects_flange(amount, speed, time, beg = 0, dur = false, snd = false, chn = false) ri = make_rand_interp(:frequency, speed, :amplitude, amount) len = (time.to_f * srate(snd)).round del = make_delay(:size, len, :max_size, (len + amount + 1).round) map_channel_rb(beg, dur, snd, chn, false, format("%s(%s, %s, %s, %s, %s", get_func_name, amount, speed, time, beg, (number?(dur) and (not dur == framples(snd, chn)) ? dur : "false"))) do |inval| 0.75 * (inval + delay(del, inval, rand_interp(ri))) end end def effects_cross_synthesis_1(cross_snd, amp, fftsize, r, beg = 0, dur = false, snd = false, chn = false) map_channel(effects_cross_synthesis(Snd.snd(cross_snd), amp, fftsize, r), beg, dur, snd, chn, false, format("%s(%s, %s, %s, %s, %s, %s", get_func_name, cross_snd, amp, fftsize, r, beg, dur)) end def effects_remove_dc(snd = false, chn = false) lastx = lasty = 0.0 map_channel_rb(0, false, snd, chn, false, "effects_remove_dc(") do |inval| lasty = inval + (0.999 * lasty - lastx) lastx = inval lasty end end def effects_compand(snd = false, chn = false) tbl = vct(-1.00, -0.96, -0.90, -0.82, -0.72, -0.60, -0.45, -0.25, 0.00, 0.25, 0.45, 0.60, 0.72, 0.82, 0.90, 0.96, 1.00) map_channel_rb(0, false, snd, chn, false, "effects_compand(") do |inval| array_interp(tbl, 8.0 + 8.0 * inval) end end end module X_Effects include Effects require "snd-xm" require "xm-enved" # # defined in snd-xm.rb: # # $with_motif # $with_gtk # if $with_motif def make_enved_widget(name, dlg, &target_body) frame = dlg.add_frame([RXmNheight, 200]) dlg.add_target() do |t| target_body.call(t) end activate_dialog(dlg.dialog) make_xenved(name, frame, :envelope, [0.0, 1.0, 1.0, 1.0], :axis_bounds, [0.0, 1.0, 0.0, 1.0]) end def set_log_value(slider, minval, init, maxval) set_scale_value(slider.scale, scale_log2linear(minval, init, maxval)) change_label(slider.label, "%1.2f" % init) end def get_log_value(wid, info, minval, maxval) scale_linear2log(minval, Rvalue(info), maxval) end else def make_enved_widget(name, dlg, &target_body) frame = dlg.parent activate_dialog(dlg.dialog) dlg.add_target() do |t| target_body.call(t) end make_xenved(name, frame, :envelope, [0.0, 1.0, 1.0, 1.0], :axis_bounds, [0.0, 1.0, 0.0, 1.0]) end def set_log_value(slider, minval, init, maxval) set_scale_value(slider.scale, scale_log2linear(minval, init, maxval)) end def get_log_value(wid, info, minval, maxval) scale_linear2log(minval, Rgtk_adjustment_get_value(RGTK_ADJUSTMENT(wid)), maxval) end end # # --- Amplitude Effects --- # class Gain def initialize(label) @label = label @amount = 1.0 @dlg = nil @target = :sound @envelope = nil end def inspect format("%s (%1.2f)", @label, @amount) end def post_dialog unless @dlg.kind_of?(Dialog) and widget?(@dlg.dialog) init_amount = 1.0 sliders = Array.new(1) @dlg = make_dialog(@label, :info, "Move the slider to change the gain scaling amount", :target_cb, lambda do | | effect_target_ok(@target) end, :reset_cb, lambda do |w, c, i| @envelope.envelope = [0.0, 1.0, 1.0, 1.0] set_scale_value(sliders[0].scale, @amount = init_amount, 100.0) end) do |w, c, i| with_env = ((@envelope.envelope != [0.0, 1.0, 1.0, 1.0]) and @envelope.scale(@amount)) case @target when :sound with_env ? env_sound(with_env) : scale_by(@amount) when :selection if selection? with_env ? env_selection(with_env) : scale_selection_by(@amount) else snd_warning("no selection") end else if pts = plausible_mark_samples if with_env env_sound(with_env, pts[0], pts[1] - pts[0]) else pos = false len = false if selection? pos = selection_position len = selection_framples end set_selection_member?(false) set_selection_position(pts[0]) set_selection_framples(pts[1] - pts[0]) scale_selection_by(@amount) if integer?(pos) set_selection_position(pos) set_selection_framples(len) else set_selection_member?(false) end end end end end sliders[0] = @dlg.add_slider("gain", 0.0, init_amount, 5.0, 100) do |w, c, i| @amount = get_scale_value(w, i, 100.0) end @envelope = make_enved_widget(@label, @dlg) do |t| set_sensitive(@dlg.okay_button, effect_target_ok(@target = t)) end else activate_dialog(@dlg.dialog) end end end class Normalize def initialize(label) @label = label @amount = 1.0 @dlg = nil @target = :sound end def inspect format("%s (%1.2f)", @label, @amount) end def post_dialog unless @dlg.kind_of?(Dialog) and widget?(@dlg.dialog) init_amount = 1.0 sliders = Array.new(1) @dlg = make_dialog(@label, :info, "Normalize scales amplitude to the normalize amount. \ Move the slider to change the scaling amount.", :target_cb, lambda do | | effect_target_ok(@target) end, :reset_cb, lambda do |w, c, i| set_scale_value(sliders[0].scale, @amount = init_amount, 100.0) end) do |w, c, i| case @target when :sound scale_to(@amount) when :selection selection? ? scale_selection_to(@amount) : snd_warning("no selection") else if pts = plausible_mark_samples pos = false len = false if selection? pos = selection_position len = selection_framples end set_selection_member?(false) set_selection_position(pts[0]) set_selection_framples(pts[1] - pts[0]) scale_selection_to(@amount) if integer?(pos) set_selection_position(pos) set_selection_framples(len) else set_selection_member?(false) end end end end sliders[0] = @dlg.add_slider("normalize", 0.0, init_amount, 1.0, 100) do |w, c, i| @amount = get_scale_value(w, i, 100.0) end @dlg.add_target() do |t| set_sensitive(@dlg.okay_button, effect_target_ok(@target = t)) end end activate_dialog(@dlg.dialog) end end class Gate def initialize(label) @label = label @amount = 0.01 @dlg = nil @size = 128 end def inspect format("%s (%1.2f)", @label, @amount) end def post_dialog unless @dlg.kind_of?(Dialog) and widget?(@dlg.dialog) init_amount = 0.01 sliders = Array.new(1) @dlg = make_dialog(@label, :info, "Move the slider to change the gate intensity. \ Higher values gate more of the sound.", :reset_cb, lambda do |w, c, i| set_scale_value(sliders[0].scale, @amount = init_amount, 1000.0) end) do |w, c, i| if (snc = sync()) > 0 sndlst, chnlst = all_chans() sndlst.zip(chnlst) do |snd, chn| if sync(snd) == snc effects_squelch_channel(@amount * @amount, @size, snd, chn) end end else effects_squelch_channel(@amount * @amount, @size, selected_sound, selected_channel) end end sliders[0] = @dlg.add_slider("gate", 0.0, init_amount, 0.1, 1000) do |w, c, i| @amount = get_scale_value(w, i, 1000.0) end end activate_dialog(@dlg.dialog) end end # # --- Delay Effects --- # class Echo def initialize(label) @label = label @delay_time = 0.5 @amount = 0.2 @dlg = nil @target = :sound @truncate = true end def inspect format("%s (%1.2f %1.2f)", @label, @delay_time, @amount) end def post_dialog unless @dlg.kind_of?(Dialog) and widget?(@dlg.dialog) init_delay_time = 0.5 init_amount = 0.2 sliders = Array.new(2) @dlg = make_dialog(@label, :info, "The sliders change the delay time and echo amount.", :target_cb, lambda do | | effect_target_ok(@target) end, :reset_cb, lambda do |w, c, i| set_scale_value(sliders[0].scale, @delay_time = init_delay_time, 100.0) set_scale_value(sliders[1].scale, @amount = init_amount, 100.0) end) do |w, c, i| map_chan_over_target_with_sync(@target, (!@truncate and 4 * @delay_time), lambda do |s| format("effects_echo(%s, %s, %s", (@target == :sound ? false : s), @delay_time, @amount) end) do |s| size = (@delay_time * srate()).round d = make_delay(size) samp = 0 lambda do |inval| samp += 1 t = if samp <= s inval else 0.0 end inval + delay(d, @amount * (tap(d) + t)) end end end sliders[0] = @dlg.add_slider("delay time", 0.0, init_delay_time, 2.0, 100) do |w, c, i| @delay_time = get_scale_value(w, i, 100.0) end sliders[1] = @dlg.add_slider("echo amount", 0.0, init_amount, 1.0, 100) do |w, c, i| @amount = get_scale_value(w, i, 100.0) end @dlg.add_target() do |t| set_sensitive(@dlg.okay_button, effect_target_ok(@target = t)) end @dlg.add_toggle() do |t| @truncate = t end end activate_dialog(@dlg.dialog) end end class Filtered_echo def initialize(label) @label = label @scaler = 0.5 @delay = 0.9 @dlg = nil @target = :sound @truncate = true end def inspect format("%s (%1.2f %1.2f)", @label, @scaler, @delay) end def flecho_1(scaler, secs, input_samps) flt = make_fir_filter(:order, 4, :xcoeffs, vct(0.125, 0.25, 0.25, 0.125)) del = make_delay((secs.to_f * srate(snd)).round) samp = 0 lambda do |inval| samp += 1 inval + delay(del, fir_filter(flt, scaler * (tap(del) + (samp <= input_samps ? inval : 0.0)))) end end def post_dialog unless @dlg.kind_of?(Dialog) and widget?(@dlg.dialog) init_scaler = 0.5 init_del = 0.9 sliders = Array.new(2) @dlg = make_dialog(@label, :info, "Move the sliders to the filter scaler and the \ delay time in seconds.", :target_cb, lambda do | | effect_target_ok(@target) end, :reset_cb, lambda do |w, c, i| set_scale_value(sliders[0].scale, @scaler = init_scaler, 100.0) set_scale_value(sliders[1].scale, @delay = init_del, 100.0) end) do |w, c, i| map_chan_over_target_with_sync(@target, (!@truncate and 4 * @delay), lambda do |s| format("effects_flecho_1(%s, %s, %s", @scaler, @delay, (@target == :sound ? false : s)) end) do |s| flecho_1(@scaler, @delay, s) end end sliders[0] = @dlg.add_slider("filter scaler", 0.0, init_scaler, 1.0, 100) do |w, c, i| @scaler = get_scale_value(w, i, 100.0) end sliders[1] = @dlg.add_slider("delay time (secs)", 0.0, init_del, 3.0, 100) do |w, c, i| @delay = get_scale_value(w, i, 100.0) end @dlg.add_target() do |t| set_sensitive(@dlg.okay_button, effect_target_ok(@target = t)) end @dlg.add_toggle() do |t| @truncate = t end end activate_dialog(@dlg.dialog) end end class Modulated_echo def initialize(label) @label = label @scaler = 0.5 @delay = 0.75 @freq = 6 @amp = 10.0 @dlg = nil @target = :sound @truncate = true end def inspect format("%s (%1.2f %1.2f %1.2f %1.2f)", @label, @scaler, @delay, @freq, @amp) end def zecho_1(scaler, secs, frq, amp, input_samps) os = make_oscil(:frequency, frq) len = (secs.to_f * srate()).round del = make_delay(len, :max_size, (len + amp + 1).to_i) samp = 0 lambda do |inval| samp += 1 inval + delay(del, scaler * (tap(del) + (samp <= input_samps ? inval : 0.0)), amp * oscil(os)) end end def post_dialog unless @dlg.kind_of?(Dialog) and widget?(@dlg.dialog) init_scaler = 0.5 init_del = 0.75 init_freq = 6 init_amp = 10.0 sliders = Array.new(4) @dlg = make_dialog(@label, :info, "Move the sliders to set the echo scaler, \ the delay time in seconds, the modulation frequency, and the echo amplitude.", :target_cb, lambda do | | effect_target_ok(@target) end, :reset_cb, lambda do |w, c, i| set_scale_value(sliders[0].scale, @scaler = init_scaler, 100.0) set_scale_value(sliders[1].scale, @delay = init_del, 100.0) set_scale_value(sliders[2].scale, @freq = init_freq, 100.0) set_scale_value(sliders[3].scale, @amp = init_amp, 100.0) end) do |w, c, i| map_chan_over_target_with_sync(@target, (!@truncate and 4 * @delay), lambda do |s| format("effects_zecho_1(%s, %s, %s, %s, %s", @scaler, @delay, @freq, @amp, (@target == :sound ? false : s)) end) do |s| zecho_1(@scaler, @delay, @freq, @amp, s) end end sliders[0] = @dlg.add_slider("echo scaler", 0.0, init_scaler, 1.0, 100) do |w, c, i| @scaler = get_scale_value(w, i, 100.0) end sliders[1] = @dlg.add_slider("delay time (secs)", 0.0, init_del, 3.0, 100) do |w, c, i| @delay = get_scale_value(w, i, 100.0) end sliders[2] = @dlg.add_slider("modulation frequency", 0.0, init_freq, 100.0, 100) do |w, c, i| @freq = get_scale_value(w, i, 100.0) end sliders[3] = @dlg.add_slider("modulation amplitude", 0.0, init_amp, 100.0, 100) do |w, c, i| @amp = get_scale_value(w, i, 100.0) end @dlg.add_target() do |t| set_sensitive(@dlg.okay_button, effect_target_ok(@target = t)) end @dlg.add_toggle() do |t| @truncate = t end end activate_dialog(@dlg.dialog) end end # # --- Filters --- # class Band_pass def initialize(label) @label = label @freq = 1000 @bw = 100 @dlg = nil @target = :sound end def inspect format("%s (%1.2f %d)", @label, @freq, @bw) end def post_dialog unless @dlg.kind_of?(Dialog) and widget?(@dlg.dialog) init_freq = 1000 init_bw = 100 sliders = Array.new(2) @dlg = make_dialog(@label, :info, "Butterworth band-pass filter. \ Move the slider to change the center frequency and bandwidth.", :target_cb, lambda do | | effect_target_ok(@target) end, :reset_cb, lambda do |w, c, i| set_log_value(sliders[0], 20, @freq = init_freq, 22050) set_scale_value(sliders[1].scale, @bw = init_bw) end) do |w, c, i| flt = make_butter_band_pass(@freq, @bw) case @target when :sound filter_sound(flt, false, false, false, false, format("effects_bbp(%s, %s, 0, false", @freq, @bw)) when :selection filter_selection(flt) else ms = plausible_mark_samples bg = ms[0] nd = ms[1] - ms[0] + 1 clm_channel(flt, bg, nd, false, false, false, false, format("effects_bbp(%s, %s, %s, %s", @freq, @bw, bg, nd)) end end sliders[0] = @dlg.add_slider("center frequency", 20, init_freq, 22050, 1, :log) do |w, c, i| @freq = get_log_value(w, i, 20, 22050) end sliders[1] = @dlg.add_slider("bandwidth", 0, init_bw, 1000) do |w, c, i| @bw = get_scale_value(w, i) end @dlg.add_target([["entire sound", :sound, true], ["selection", :selection, false]]) do |t| set_sensitive(@dlg.okay_button, effect_target_ok(@target = t)) end end activate_dialog(@dlg.dialog) end end class Band_reject def initialize(label) @label = label @freq = 100 @bw = 100 @dlg = nil @target = :sound end def inspect format("%s (%1.2f %d)", @label, @freq, @bw) end def post_dialog unless @dlg.kind_of?(Dialog) and widget?(@dlg.dialog) init_freq = 100 init_bw = 100 sliders = Array.new(2) @dlg = make_dialog(@label, :info, "Butterworth band-reject filter. \ Move the slider to change the center frequency and bandwidth.", :target_cb, lambda do | | effect_target_ok(@target) end, :reset_cb, lambda do |w, c, i| set_log_value(sliders[0], 20, @freq = init_freq, 22050) set_scale_value(sliders[1].scale, @bw = init_bw) end) do |w, c, i| flt = make_butter_band_reject(@freq, @bw) case @target when :sound filter_sound(flt, false, false, false, false, format("effects_bbr(%s, %s, 0, false", @freq, @bw)) when :selection filter_selection(flt) else ms = plausible_mark_samples bg = ms[0] nd = ms[1] - ms[0] + 1 clm_channel(flt, bg, nd, false, false, false, false, format("effects_bbr(%s, %s, %s, %s", @freq, @bw, bg, nd)) end end sliders[0] = @dlg.add_slider("center frequency", 20, init_freq, 22050, 1, :log) do |w, c, i| @freq = get_log_value(w, i, 20, 22050) end sliders[1] = @dlg.add_slider("bandwidth", 0, init_bw, 1000) do |w, c, i| @bw = get_scale_value(w, i) end @dlg.add_target([["entire sound", :sound, true], ["selection", :selection, false]]) do |t| set_sensitive(@dlg.okay_button, effect_target_ok(@target = t)) end end activate_dialog(@dlg.dialog) end end class High_pass def initialize(label) @label = label @freq = 100 @dlg = nil @target = :sound end def inspect format("%s (%1.2f)", @label, @freq) end def post_dialog unless @dlg.kind_of?(Dialog) and widget?(@dlg.dialog) init_freq = 100 sliders = Array.new(1) @dlg = make_dialog(@label, :info, "Butterworth high-pass filter. \ Move the slider to change the high-pass cutoff frequency.", :target_cb, lambda do | | effect_target_ok(@target) end, :reset_cb, lambda do |w, c, i| set_log_value(sliders[0], 20, @freq = init_freq, 22050) end) do |w, c, i| flt = make_butter_high_pass(@freq) case @target when :sound filter_sound(flt, false, false, false, false, format("effects_bhp(%s, 0, false", @freq)) when :selection filter_selection(flt) else ms = plausible_mark_samples bg = ms[0] nd = ms[1] - ms[0] + 1 clm_channel(flt, bg, nd, false, false, false, false, format("effects_bhp(%s, %s, %s", @freq, bg, nd)) end end sliders[0] = @dlg.add_slider("high-pass cutoff frequency", 20, init_freq, 22050, 1, :log) do |w, c, i| @freq = get_log_value(w, i, 20, 22050) end @dlg.add_target([["entire sound", :sound, true], ["selection", :selection, false]]) do |t| set_sensitive(@dlg.okay_button, effect_target_ok(@target = t)) end end activate_dialog(@dlg.dialog) end end class Low_pass def initialize(label) @label = label @freq = 1000 @dlg = nil @target = :sound end def inspect format("%s (%1.2f)", @label, @freq) end def post_dialog unless @dlg.kind_of?(Dialog) and widget?(@dlg.dialog) init_freq = 1000 sliders = Array.new(1) @dlg = make_dialog(@label, :info, "Butterworth low-pass filter. \ Move the slider to change the low-pass cutoff frequency.", :target_cb, lambda do | | effect_target_ok(@target) end, :reset_cb, lambda do |w, c, i| set_log_value(sliders[0], 20, @freq = init_freq, 22050) end) do |w, c, i| flt = make_butter_low_pass(@freq) case @target when :sound filter_sound(flt, false, false, false, false, format("effects_blp(%s, 0, false", @freq)) when :selection filter_selection(flt) else ms = plausible_mark_samples bg = ms[0] nd = ms[1] - ms[0] + 1 clm_channel(flt, bg, nd, false, false, false, false, format("effects_blp(%s, %s, %s", @freq, bg, nd)) end end sliders[0] = @dlg.add_slider("low-pass cutoff frequency", 20, init_freq, 22050, 1, :log) do |w, c, i| @freq = get_log_value(w, i, 20, 22050) end @dlg.add_target([["entire sound", :sound, true], ["selection", :selection, false]]) do |t| set_sensitive(@dlg.okay_button, effect_target_ok(@target = t)) end end activate_dialog(@dlg.dialog) end end class Comb def initialize(label) @label = label @scaler = 0.1 @size = 50 @dlg = nil @target = :sound end def inspect format("%s (%1.2f %d)", @label, @scaler, @size) end def post_dialog unless @dlg.kind_of?(Dialog) and widget?(@dlg.dialog) init_scaler = 0.1 init_size = 50 sliders = Array.new(2) @dlg = make_dialog(@label, :info, "Move the slider to change the comb scaler and size.", :target_cb, lambda do | | effect_target_ok(@target) end, :reset_cb, lambda do |w, c, i| set_scale_value(sliders[0].scale, @scaler = init_scaler, 100.0) set_scale_value(sliders[1].scale, @size = init_size) end) do |w, c, i| map_chan_over_target_with_sync(@target, false, lambda do |s| format("effects_comb_filter(%s, %s", @scaler, @size) end) do |ignored| comb_filter(@scaler, @size) end end sliders[0] = @dlg.add_slider("scaler", 0.0, init_scaler, 1.0, 100) do |w, c, i| @scaler = get_scale_value(w, i, 100.0) end sliders[1] = @dlg.add_slider("size", 1, init_size, 100) do |w, c, i| @size = get_scale_value(w, i) end @dlg.add_target() do |t| set_sensitive(@dlg.okay_button, effect_target_ok(@target = t)) end end activate_dialog(@dlg.dialog) end end class Comb_chord def initialize(label) @label = label @scaler = 0.95 @size = 60 @amp = 0.3 @interval_one = 0.75 @interval_two = 1.20 @dlg = nil @target = :sound end def inspect format("%s (%1.2f %d %1.2f %1.2f %1.2f)", @label, @scaler, @size, @amp, @interval_one, @interval_two) end def post_dialog unless @dlg.kind_of?(Dialog) and widget?(@dlg.dialog) init_scaler = 0.95 init_size = 60 init_amp = 0.3 init_one = 0.75 init_two = 1.20 sliders = Array.new(5) @dlg = make_dialog(@label, :info, "Comb chord filter: Creates chords by using filters at harmonically related sizes. \ Move the sliders to set the comb chord parameters.", :target_cb, lambda do | | effect_target_ok(@target) end, :reset_cb, lambda do |w, c, i| set_scale_value(sliders[0].scale, @scaler = init_scaler, 100.0) set_scale_value(sliders[1].scale, @size = init_size) set_scale_value(sliders[2].scale, @amp = init_amp, 100.0) set_scale_value(sliders[3].scale, @interval_one = init_one, 100.0) set_scale_value(sliders[4].scale, @interval_two = init_two, 100.0) end) do |w, c, i| map_chan_over_target_with_sync(@target, false, lambda do |s| format("effects_comb_chord(%s, %s, %s, %s, %s", @scaler, @size, @amp, @interval_one, @interval_two) end) do |ignored| comb_chord(@scaler, @size, @amp, @interval_one, @interval_two) end end sliders[0] = @dlg.add_slider("chord scaler", 0.0, init_scaler, 1.0, 100) do |w, c, i| @scaler = get_scale_value(w, i, 100.0) end sliders[1] = @dlg.add_slider("chord size", 1, init_size, 100) do |w, c, i| @size = get_scale_value(w, i) end sliders[2] = @dlg.add_slider("amplitude", 0.0, init_amp, 1.0, 100) do |w, c, i| @amp = get_scale_value(w, i, 100.0) end sliders[3] = @dlg.add_slider("interval one", 0.0, init_one, 2.0, 100) do |w, c, i| @interval_one = get_scale_value(w, i, 100.0) end sliders[4] = @dlg.add_slider("interval two", 0.0, init_two, 2.0, 100) do |w, c, i| @interval_two = get_scale_value(w, i, 100.0) end @dlg.add_target() do |t| set_sensitive(@dlg.okay_button, effect_target_ok(@target = t)) end end activate_dialog(@dlg.dialog) end end class Moog_filter def initialize(label) @label = label @cutoff_freq = 10000 @resonance = 0.5 @dlg = nil @target = :sound end def inspect format("%s (%1.2f %1.2f)", @label, @cutoff_freq, @resonance) end def post_dialog unless @dlg.kind_of?(Dialog) and widget?(@dlg.dialog) init_freq = 10000 init_resonance = 0.5 sliders = Array.new(2) @dlg = make_dialog(@label, :info, "Moog filter: Moog-style 4-pole lowpass filter with 24db/oct rolloff and variable resonance. \ Move the sliders to set the filter cutoff frequency and resonance.", :target_cb, lambda do | | effect_target_ok(@target) end, :reset_cb, lambda do |w, c, i| set_log_value(sliders[0], 20, @cutoff = init_freq, 22050) set_scale_value(sliders[1].scale, @resonance = init_resonance, 100.0) end) do |w, c, i| map_chan_over_target_with_sync(@target, false, lambda do |s| format("effects_moog(%s, %s", @cutoff_freq, @resonance) end) do |ignored| moog(@cutoff_freq, @resonance) end end sliders[0] = @dlg.add_slider("cutoff frequency", 20, init_freq, 22050, 1, :log) do |w, c, i| @cutoff_freq = get_log_value(w, i, 20, 22050) end sliders[1] = @dlg.add_slider("resonance", 0.0, init_resonance, 1.0, 100) do |w, c, i| @resonance = get_scale_value(w, i, 100.0) end @dlg.add_target() do |t| set_sensitive(@dlg.okay_button, effect_target_ok(@target = t)) end end activate_dialog(@dlg.dialog) end end # # --- Frequency Effects --- # class Adaptive def initialize(label) @label = label @size = 4 @dlg = nil @target = :sound end def inspect format("%s (%d)", @label, @size) end def post_dialog unless @dlg.kind_of?(Dialog) and widget?(@dlg.dialog) init_size = 4 sliders = Array.new(1) @dlg = make_dialog(@label, :info, "Move the slider to change the saturation scaling factor.", :target_cb, lambda do | | effect_target_ok(@target) end, :reset_cb, lambda do |w, c, i| set_scale_value(sliders[0].scale, @size = init_size) end) do |w, c, i| map_chan_over_target_with_sync(@target, false, lambda do |s| format("adsat(%s", @size) end) do |ignored| mn = 0.0 mx = 0.0 n = 0 vals = make_vct(@size) lambda do |val| if n == @size @size.times do |ii| if vals[ii] >= 0.0 vals[ii] = mx else vals[ii] = mn end end n, mx, mn = 0, 0.0, 0.0 vals else vals[n] = val mx = [mx, val].max mn = [mn, val].min n += 1 false end end end end sliders[0] = @dlg.add_slider("adaptive saturation size", 0, init_size, 10) do |w, c, i| @size = get_scale_value(w, i).round end @dlg.add_target() do |t| set_sensitive(@dlg.okay_button, effect_target_ok(@target = t)) end end activate_dialog(@dlg.dialog) end end class Sample_rate def initialize(label) @label = label @amount = 0.0 @dlg = nil @target = :sound end def inspect format("%s (%1.2f)", @label, @amount) end def post_dialog unless @dlg.kind_of?(Dialog) and widget?(@dlg.dialog) init_amount = 0.0 sliders = Array.new(1) @dlg = make_dialog(@label, :info, "Move the slider to change the sample rate. \ Values greater than 1.0 speed up file play, negative values reverse it.", :target_cb, lambda do | | effect_target_ok(@target) end, :reset_cb, lambda do |w, c, i| set_scale_value(sliders[0].scale, @amount = init_amount, 100.0) end) do |w, c, i| case @target when :sound src_sound(@amount) when :selection selection? ? src_selection(@amount) : snd_warning("no selection") end end sliders[0] = @dlg.add_slider("sample rate", -2.0, init_amount, 2.0, 100) do |w, c, i| @amount = get_scale_value(w, i, 100.0) end @dlg.add_target([["entire sound", :sound, true], ["selection", :selection, false]]) do |t| set_sensitive(@dlg.okay_button, effect_target_ok(@target = t)) end end activate_dialog(@dlg.dialog) end end class Time_pitch def initialize(label) @label = label @dlg = nil @target = :sound @time_scale = 1.0 @hop_size = 0.05 @segment_length = 0.15 @ramp_scale = 0.5 @pitch_scale = 1.0 end def inspect format("%s (%1.2f %1.2f)", @label, @time_scale, @pitch_scale) end def post_dialog unless @dlg.kind_of?(Dialog) and widget?(@dlg.dialog) time_scale = 1.0 hop_size = 0.05 seg_length = 0.15 ramp_scale = 0.5 pitch_scale = 1.0 sliders = Array.new(5) @dlg = make_dialog(@label, :info, "Move the sliders to change the time/pitch scaling params.", :target_cb, lambda do | | effect_target_ok(@target) end, :reset_cb, lambda do |w, c, i| set_scale_value(sliders[0].scale, @time_scale = time_scale, 100.0) set_scale_value(sliders[1].scale, @hop_size = hop_size, 100.0) set_scale_value(sliders[2].scale, @segment_length = seg_length, 100.0) set_scale_value(sliders[3].scale, @ramp_scale = ramp_scale, 100.0) set_scale_value(sliders[4].scale, @pitch_scale = pitch_scale, 100.0) end) do |w, c, i| snd = selected_sound save_controls(snd) reset_controls(snd) set_speed_control(@pitch_scale, snd) new_time = @pitch_scale * @time_scale.to_f if new_time != 1.0 set_expand_control?(true, snd) set_expand_control(new_time, snd) set_expand_control_hop(@hop_size, snd) set_expand_control_length(@segment_length, snd) set_expand_control_ramp(@ramp_scale, snd) end if @target == :marks if ms = plausible_mark_samples apply_controls(snd, 0, ms[0], 1 + (ms[1] - ms[0])) end else apply_controls(snd, (@target == :sound ? 0 : 2)) end restore_controls(snd) end sliders[0] = @dlg.add_slider("time scale", 0.0, time_scale, 5.0, 100) do |w, c, i| @time_scale = get_scale_value(w, i, 100.0) end sliders[1] = @dlg.add_slider("hop size", 0.0, hop_size, 1.0, 100) do |w, c, i| @hop_size = get_scale_value(w, i, 100.0) end sliders[2] = @dlg.add_slider("segment length", 0.0, seg_length, 0.5, 100) do |w, c, i| @segment_length = get_scale_value(w, i, 100.0) end sliders[3] = @dlg.add_slider("ramp scale", 0.0, ramp_scale, 0.5, 1000) do |w, c, i| @ramp_scale = get_scale_value(w, i, 100.0) end sliders[4] = @dlg.add_slider("pitch scale", 0.0, pitch_scale, 5.0, 100) do |w, c, i| @pitch_scale = get_scale_value(w, i, 100.0) end @dlg.add_target() do |t| set_sensitive(@dlg.okay_button, effect_target_ok(@target = t)) end end activate_dialog(@dlg.dialog) end end class Src_timevar # Time-varying sample rate conversion (resample) (KSM) def initialize(label) @label = label @scale = 1.0 @dlg = nil @target = :sound @envelope = nil end def inspect format("%s (%1.2f)", @label, @scale) end def post_dialog unless @dlg.kind_of?(Dialog) and widget?(@dlg.dialog) init_scale = 1.0 sliders = Array.new(1) @dlg = make_dialog(@label, :info, "Move the slider to change the src-timevar scaling amount.", :target_cb, lambda do | | effect_target_ok(@target) end, :reset_cb, lambda do |w, c, i| @envelope.envelope = [0.0, 1.0, 1.0, 1.0] set_scale_value(sliders[0].scale, @scale = init_scale, 100.0) end) do |w, c, i| env = @envelope.scale(@scale) case @target when :sound src_sound(env) when :selection if selection_member?(selected_sound) src_selection(env) else snd_warning("no selection") end else if pts = plausible_mark_samples beg = pts[0] len = pts[1] - beg src_channel(make_env(env, :length, len), beg, len, selected_sound) end end end sliders[0] = @dlg.add_slider("resample factor", 0.0, init_scale, 10.0, 100) do |w, c, i| @scale = get_scale_value(w, i, 100.0) end @envelope = make_enved_widget(@label, @dlg) do |t| set_sensitive(@dlg.okay_button, effect_target_ok(@target = t)) end else activate_dialog(@dlg.dialog) end end end # # --- Modulation Effects --- # class Amplitude_modulation def initialize(label) @label = label @amount = 100.0 @dlg = nil @target = :sound @envelope = nil end def inspect format("%s (%1.2f)", @label, @amount) end def post_dialog unless @dlg.kind_of?(Dialog) and widget?(@dlg.dialog) init_amount = 100.0 sliders = Array.new(1) @dlg = make_dialog(@label, :info, "Move the slider to change the modulation amount.", :target_cb, lambda do | | effect_target_ok(@target) end, :reset_cb, lambda do |w, c, i| @envelope.envelope = [0.0, 1.0, 1.0, 1.0] set_scale_value(sliders[0].scale, @amount = init_amount) end) do |w, c, i| need_env = (@envelope.envelope != [0.0, 1.0, 1.0, 1.0]) map_chan_over_target_with_sync(@target, false, lambda do |s| format("effects_am(%s, %s", @amount, ((need_env and @envelope.envelope) ? @envelope.envelope.inspect : "false")) end) do |ignored| os = make_oscil(@amount) e = (need_env and make_env(@envelope.envelope, :length, effect_framples(@target))) if need_env lambda do |inval| amplitude_modulate(1.0, inval, env(e) * oscil(os)) end else lambda do |inval| amplitude_modulate(1.0, inval, oscil(os)) end end end end sliders[0] = @dlg.add_slider("amplitude modulation", 0.0, init_amount, 1000.0) do |w, c, i| @amount = get_scale_value(w, i) end @envelope = make_enved_widget(@label, @dlg) do |t| set_sensitive(@dlg.okay_button, effect_target_ok(@target = t)) end else activate_dialog(@dlg.dialog) end end end class Ring_modulation def initialize(label) @label = label @frequency = 100 @radians = 100 @dlg = nil @target = :sound @envelope = nil end def inspect format("%s (%d %d)", @label, @frequency, @radians) end def post_dialog unless @dlg.kind_of?(Dialog) and widget?(@dlg.dialog) init_frequency = 100 init_radians = 100 sliders = Array.new(2) @dlg = make_dialog(@label, :info, "Move the sliders to change the modulation parameters.", :target_cb, lambda do | | effect_target_ok(@target) end, :reset_cb, lambda do |w, c, i| @envelope.envelope = [0.0, 1.0, 1.0, 1.0] set_scale_value(sliders[0].scale, @frequency = init_frequency) set_scale_value(sliders[1].scale, @radians = init_radians) end) do |w, c, i| need_env = (@envelope.envelope != [0.0, 1.0, 1.0, 1.0]) map_chan_over_target_with_sync(@target, false, lambda do |s| format("effects_rm(%s, %s", @frequency, ((need_env and @envelope.envelope) ? @envelope.envelope.inspect : "false")) end) do |ignored| os = make_oscil(@frequency) e = (need_env and make_env(@envelope.envelope, :length, effect_framples(@target))) if need_env lambda do |inval| inval * (env(e) * oscil(os)) end else lambda do |inval| inval * oscil(os) end end end end sliders[0] = @dlg.add_slider("modulation frequency", 0, init_frequency, 1000) do |w, c, i| @frequency = get_scale_value(w, i) end sliders[1] = @dlg.add_slider("modulation radians", 0, init_radians, 360) do |w, c, i| @radians = get_scale_value(w, i) end @envelope = make_enved_widget(@label, @dlg) do |t| set_sensitive(@dlg.okay_button, effect_target_ok(@target = t)) end else activate_dialog(@dlg.dialog) end end end # # --- Reverbs --- # class Nrev def initialize(label) @label = label @amount = 0.1 @filter = 0.5 @feedback = 1.09 @dlg = nil @target = :sound end def inspect format("%s (%1.2f %1.2f %1.2f)", @label, @amount, @filter, @feedback) end def post_dialog unless @dlg.kind_of?(Dialog) and widget?(@dlg.dialog) init_amount = 0.1 init_filter = 0.5 init_feedback = 1.09 sliders = Array.new(3) @dlg = make_dialog(@label, :info, "Reverberator from Michael McNabb. \ Adds reverberation scaled by reverb amount, lowpass filtering, and feedback. \ Move the sliders to change the reverb parameters.", :target_cb, lambda do | | effect_target_ok(@target) end, :reset_cb, lambda do |w, c, i| set_scale_value(sliders[0].scale, @amount = init_amount, 100.0) set_scale_value(sliders[1].scale, @filter = init_filter, 100.0) set_scale_value(sliders[2].scale, @feedback = init_feedback, 100.0) end) do |w, c, i| snd = selected_sound save_controls(snd) reset_controls(snd) set_reverb_control?(true, snd) set_reverb_control_scale(@amount, snd) set_reverb_control_lowpass(@filter, snd) set_reverb_control_feedback(@feedback, snd) if @target == :marks if ms = plausible_mark_samples apply_controls(snd, 0, ms[0], 1 + (ms[1] - ms[0])) end else apply_controls(snd, (@target == :sound ? 0 : 2)) end restore_controls(snd) end sliders[0] = @dlg.add_slider("reverb amount", 0.0, init_amount, 1.0, 100) do |w, c, i| @amount = get_scale_value(w, i, 100.0) end sliders[1] = @dlg.add_slider("reverb filter", 0.0, init_filter, 1.0, 100) do |w, c, i| @filter = get_scale_value(w, i, 100.0) end sliders[2] = @dlg.add_slider("reverb feedback", 0.0, init_feedback, 1.25, 100) do |w, c, i| @feedback = get_scale_value(w, i, 100.0) end @dlg.add_target() do |t| set_sensitive(@dlg.okay_button, effect_target_ok(@target = t)) end end activate_dialog(@dlg.dialog) end end class Chowning def initialize(label) @label = label @decay = 2.0 @volume = 0.1 @dlg = nil @target = :sound @truncate = true end def inspect format("%s (%1.2f %1.2f)", @label, @decay, @volume) end def post_dialog unless @dlg.kind_of?(Dialog) and widget?(@dlg.dialog) init_decay = 2.0 init_volume = 0.1 sliders = Array.new(2) @dlg = make_dialog(@label, :info, "Nice reverb from John Chowning. \ Move the sliders to change the reverb parameters.", :target_cb, lambda do | | effect_target_ok(@target) end, :reset_cb, lambda do |w, c, i| set_scale_value(sliders[0].scale, @decay = init_decay, 100.0) set_scale_value(sliders[1].scale, @volume = init_volume, 100.0) end) do |w, c, i| map_chan_over_target_with_sync(@target, (!@truncate and @decay), lambda do |s| format("effects_jc_reverb_1(%s, %s", s, @volume) end) do |s| effects_jc_reverb(s, @volume) end end sliders[0] = @dlg.add_slider("decay duration", 0.0, init_decay, 10.0, 100) do |w, c, i| @decay = get_scale_value(w, i, 100.0) end sliders[1] = @dlg.add_slider("reverb volume", 0.0, init_volume, 1.0, 100) do |w, c, i| @volume = get_scale_value(w, i, 100.0) end @dlg.add_target() do |t| set_sensitive(@dlg.okay_button, effect_target_ok(@target = t)) end @dlg.add_toggle() do |t| @truncate = t end end activate_dialog(@dlg.dialog) end end class Convolution def initialize(label) @label = label @sound_one = 0 @sound_two = 1 @amp = 0.01 @dlg = nil end def inspect format("%s (%d %d %1.2f)", @label, @sound_one, @sound_two, @amp) end def post_dialog unless @dlg.kind_of?(Dialog) and widget?(@dlg.dialog) init_one = 0 init_two = 1 init_amp = 0.01 sliders = Array.new(3) @dlg = make_dialog(@label, :info, "Very simple convolution. \ Move the sliders to set the numbers of the soundfiles to be convolved and the \ amount for the amplitude scaler. Output will be scaled to floating-point values, resulting in very large \ (but not clipped) amplitudes. Use the Normalize amplitude effect to rescale the output. The convolution data file typically defines a natural reverberation source, \ and the output from this effect can provide very striking reverb effects. \ You can find convolution data files on sites listed at \ http://www.bright.net/~dlphilp/linux_csound.html under Impulse Response Data.", :reset_cb, lambda do |w, c, i| set_scale_value(sliders[0].scale, @sound_one = init_one) set_scale_value(sliders[1].scale, @sound_two = init_two) set_scale_value(sliders[2].scale, @amp = init_amp, 100.0) end) do |w, c, i| if sound?(@sound_one) and sound?(@sound_two) effects_cnv(@sound_one, @sound_two, @amp) else snd_warning(format("sound-one: %s, sound-two: %s", sound?(@sound_one).to_s, sound?(@sound_two).to_s)) end end sliders[0] = @dlg.add_slider("impulse response file", 0, init_one, 24) do |w, c, i| @sound_one = get_scale_value(w, i).round end sliders[1] = @dlg.add_slider("sound file", 0, init_two, 24) do |w, c, i| @sound_two = get_scale_value(w, i).round end sliders[2] = @dlg.add_slider("amplitude", 0.0, init_amp, 0.1, 100) do |w, c, i| @amp = get_scale_value(w, i, 100.0) end end activate_dialog(@dlg.dialog) end end # # --- Various and Miscellaneous --- # class Placed def initialize(label) @label = label @mono_snd = 0 @stereo_snd = 1 @pan_pos = 45 @dlg = nil @target = :sound @envelope = nil end def inspect format("%s (%d %d %d)", @label, @mono_snd, @stereo_snd, @pan_pos) end def place_sound(pan_env) if number?(pan_env) effects_position_sound(@mono_snd, pos, @stereo_snd, 1) effects_position_sound(@mono_snd, 1.0 - pos, @stereo_snd, 0) else effects_position_sound(@mono_snd, pan_env, @stereo_snd, 1) effects_position_sound(@mono_snd, pan_env, @stereo_snd, 0) end end def post_dialog unless @dlg.kind_of?(Dialog) and widget?(@dlg.dialog) init_mono_snd = 0 init_stereo_snd = 1 init_pan_pos = 45 sliders = Array.new(3) @dlg = make_dialog(@label, :info, "Mixes mono sound into stereo sound field.", :target_cb, lambda do | | effect_target_ok(@target) end, :reset_cb, lambda do |w, c, i| @envelope.envelope = [0.0, 1.0, 1.0, 1.0] set_scale_value(sliders[0].scale, @mono_snd = init_mono_snd) set_scale_value(sliders[1].scale, @stereo_snd = init_stereo_snd) set_scale_value(sliders[2].scale, @pan_pos = init_pan_pos) end) do |w, c, i| if (e = @envelope.envelope) != [0.0, 1.0, 1.0, 1.0] place_sound(e) else place_sound(@pan_pos) end end sliders[0] = @dlg.add_slider("mono sound", 0, init_mono_snd, 50) do |w, c, i| @mono_snd = get_scale_value(w, i).round end sliders[1] = @dlg.add_slider("stereo sound", 0, init_stereo_snd, 50) do |w, c, i| @stereo_snd = get_scale_value(w, i).round end sliders[2] = @dlg.add_slider("pan position", 0, init_pan_pos, 90) do |w, c, i| @pan_pos = get_scale_value(w, i) end @envelope = make_enved_widget(@label, @dlg) do |t| set_sensitive(@dlg.okay_button, effect_target_ok(@target = t)) end else activate_dialog(@dlg.dialog) end end end class Add_silence def initialize(label) @label = label @amount = 1.0 @dlg = nil end def inspect format("%s (%1.2f)", @label, @amount) end def post_dialog unless @dlg.kind_of?(Dialog) and widget?(@dlg.dialog) init_amount = 1.0 sliders = Array.new(1) @dlg = make_dialog(@label, :info, "Move the slider to change the number of seconds \ of silence added at the cursor position.", :reset_cb, lambda do |w, c, i| set_scale_value(sliders[0].scale, @amount = init_amount, 100.0) end) do |w, c, i| insert_silence(cursor(), (srate().to_f * @amount).round) end sliders[0] = @dlg.add_slider("silence", 0.0, init_amount, 5.0, 100) do |w, c, i| @amount = get_scale_value(w, i, 100.0) end end activate_dialog(@dlg.dialog) end end class Contrast def initialize(label) @label = label @amount = 1.0 @dlg = nil @target = :sound end def inspect format("%s (%1.2f)", @label, @amount) end def post_dialog unless @dlg.kind_of?(Dialog) and widget?(@dlg.dialog) init_amount = 1.0 sliders = Array.new(1) @dlg = make_dialog(@label, :info, "Move the slider to change the contrast intensity.", :reset_cb, lambda do |w, c, i| set_scale_value(sliders[0].scale, @amount = init_amount, 100.0) end) do |w, c, i| peak = maxamp() save_controls reset_controls set_contrast_control?(true) set_contrast_control(@amount) set_contrast_control_amp(1.0 / peak) set_amp_control(peak) if @target == :marks if ms = plausible_mark_samples apply_controls(selected_sound, 0, ms[0], 1 + (ms[1] - ms[0])) end else apply_controls(selected_sound, (@target == :sound ? 0 : 2)) end restore_controls end sliders[0] = @dlg.add_slider("contrast enhancement", 0.0, init_amount, 10.0, 100) do |w, c, i| @amount = get_scale_value(w, i, 100.0) end @dlg.add_target() do |t| set_sensitive(@dlg.okay_button, effect_target_ok(@target = t)) end end activate_dialog(@dlg.dialog) end end class Cross_synthesis def initialize(label) @label = label @sound = 1 @amp = 0.5 @fft_size = 128 @radius = 6.0 @dlg = nil @default_fft_widget = nil @target = :sound end def inspect format("%s (%d %1.2f %d %1.2f)", @label, @sound, @amp, @fft_size, @radius) end def effects_cross_synthesis(cross_snd, amp, fftsize, r) freq_inc = fftsize / 2 fdr = make_vct(fftsize) fdi = make_vct(fftsize) spectr = make_vct(freq_inc) inctr = 0 ctr = freq_inc radius = 1.0 - r / fftsize.to_f bin = srate() / fftsize.to_f fmts = make_array(freq_inc) do |i| make_formant(i * bin, radius) end formants = make_formant_bank(fmts, spectr) lambda do |inval| if ctr == freq_inc fdr = channel2vct(inctr, fftsize, cross_snd, 0) inctr += freq_inc spectrum(fdr, fdi, false, 2) fdr.subtract!(spectr) fdr.scale!(1.0 / freq_inc) ctr = 0 end ctr += 1 spectr.add!(fdr) amp * formant_bank(formants, inval) end end def post_dialog unless @dlg.kind_of?(Dialog) and widget?(@dlg.dialog) init_sound = 1 init_amp = 0.5 init_fft_size = 128 init_radius = 6.0 sliders = Array.new(3) @dlg = make_dialog(@label, :info, "The sliders set the number of the soundfile \ to be cross_synthesized, the synthesis amplitude, the FFT size, and the radius value.", :target_cb, lambda do | | effect_target_ok(@target) end, :reset_cb, lambda do |w, c, i| set_scale_value(sliders[0].scale, @sound = init_sound) set_scale_value(sliders[1].scale, @amp = init_amp, 100.0) @fft_size = init_fft_size if $with_motif RXmToggleButtonSetState(@default_fft_widget, true, true) end set_scale_value(sliders[2].scale, @radius = init_radius, 100.0) end) do |w, c, i| if sound?(@sound) map_chan_over_target_with_sync(@target, false, lambda do |s| format("effects_cross_synthesis_1(%s, %s, %s, %s", @sound, @amp, @fft_size, @radius) end) do |ignored| effects_cross_synthesis(@sound, @amp, @fft_size, @radius) end else snd_warning(format("cross-snd: %s", sound?(@sound).to_s)) end end sliders[0] = @dlg.add_slider("input sound", 0, init_sound, 20) do |w, c, i| @sound = get_scale_value(w, i).round end sliders[1] = @dlg.add_slider("amplitude", 0.0, init_amp, 1.0, 100) do |w, c, i| @amp = get_scale_value(w, i, 100.0) end sliders[2] = @dlg.add_slider("radius", 0.0, init_radius, 360.0, 100) do |w, c, i| @radius = get_scale_value(w, i, 100.0) end if $with_motif s1 = RXmStringCreateLocalized("FFT size") frame = @dlg.add_frame([RXmNborderWidth, 1, RXmNshadowType, RXmSHADOW_ETCHED_IN, RXmNpositionIndex, 2]) frm = RXtCreateManagedWidget("frm", RxmFormWidgetClass, frame, [RXmNleftAttachment, RXmATTACH_FORM, RXmNrightAttachment, RXmATTACH_FORM, RXmNtopAttachment, RXmATTACH_FORM, RXmNbottomAttachment, RXmATTACH_FORM, RXmNbackground, basic_color]) rc = RXtCreateManagedWidget("rc", RxmRowColumnWidgetClass, frm, [RXmNorientation, RXmHORIZONTAL, RXmNradioBehavior, true, RXmNradioAlwaysOne, true, RXmNentryClass, RxmToggleButtonWidgetClass, RXmNisHomogeneous, true, RXmNleftAttachment, RXmATTACH_FORM, RXmNrightAttachment, RXmATTACH_FORM, RXmNtopAttachment, RXmATTACH_FORM, RXmNbottomAttachment, RXmATTACH_NONE, RXmNbackground, basic_color]) RXtCreateManagedWidget("FFT size", RxmLabelWidgetClass, frm, [RXmNleftAttachment, RXmATTACH_FORM, RXmNrightAttachment, RXmATTACH_FORM, RXmNtopAttachment, RXmATTACH_WIDGET, RXmNtopWidget, rc, RXmNbottomAttachment, RXmATTACH_FORM, RXmNlabelString, s1, RXmNalignment, RXmALIGNMENT_BEGINNING, RXmNbackground, basic_color]) [64, 128, 256, 512, 1024, 4096].each do |s| button = RXtCreateManagedWidget(s.to_s, RxmToggleButtonWidgetClass, rc, [RXmNbackground, basic_color, RXmNvalueChangedCallback, [lambda do |w, c, i| if Rset(i) @fft_size = c end end, s], RXmNset, (s == @fft_size)]) if s == @fft_size @default_fft_widget = button end end RXmStringFree(s1) end @dlg.add_target() do |t| set_sensitive(@dlg.okay_button, effect_target_ok(@target = t)) end end activate_dialog(@dlg.dialog) end end class Flange def initialize(label) @label = label @speed = 2.0 @amount = 5.0 @time = 0.001 @dlg = nil @target = :sound end def inspect format("%s (%1.2f %1.2f %1.3f)", @label, @speed, @amount, @time) end def post_dialog unless @dlg.kind_of?(Dialog) and widget?(@dlg.dialog) init_speed = 2.0 init_amount = 5.0 init_time = 0.001 sliders = Array.new(3) @dlg = make_dialog(@label, :info, "Move the sliders to change the flange \ speed, amount, and time.", :target_cb, lambda do | | effect_target_ok(@target) end, :reset_cb, lambda do |w, c, i| set_scale_value(sliders[0].scale, @speed = init_speed, 10.0) set_scale_value(sliders[1].scale, @amount = init_amount, 10.0) set_scale_value(sliders[2].scale, @time = init_time, 100.0) end) do |w, c, i| map_chan_over_target_with_sync(@target, false, lambda do |s| format("effects_flange(%s, %s, %s", @amount, @speed, @time) end) do |ignored| ri = make_rand_interp(:frequency, @speed, :amplitude, @amount) len = (@time.to_f * srate()).round del = make_delay(len, :max_size, (len + @amount + 1).to_i) lambda do |inval| 0.75 * (inval + delay(del, inval, rand_interp(ri))) end end end sliders[0] = @dlg.add_slider("flange speed", 0.0, init_speed, 100.0, 10) do |w, c, i| @speed = get_scale_value(w, i, 10.0) end sliders[1] = @dlg.add_slider("flange amount", 0.0, init_amount, 100.0, 10) do |w, c, i| @amount = get_scale_value(w, i, 10.0) end sliders[2] = @dlg.add_slider("flange time", 0.0, init_time, 1.0, 100) do |w, c, i| @time = get_scale_value(w, i, 100.0) end @dlg.add_target() do |t| set_sensitive(@dlg.okay_button, effect_target_ok(@target = t)) end end activate_dialog(@dlg.dialog) end end class Randomize_phase def initialize(label) @label = label @amp_scaler = 3.14 @dlg = nil end def inspect format("%s (%1.2f)", @label, @amp_scaler) end def post_dialog unless @dlg.kind_of?(Dialog) and widget?(@dlg.dialog) init_scaler = 3.14 sliders = Array.new(1) @dlg = make_dialog(@label, :info, "Move the slider to change the randomization amp scaler.", :reset_cb, lambda do |w, c, i| set_scale_value(sliders[0].scale, @amp_scaler = init_scaler, 100.0) end) do |w, c, i| rotate_phase(lambda do |x| kernel_rand(@amp_scaler) end) end sliders[0] = @dlg.add_slider("amplitude scaler", 0.0, init_scaler, 100.0, 100) do |w, c, i| @amp_scaler = get_scale_value(w, i, 100.0) end end activate_dialog(@dlg.dialog) end end class Robotize def initialize(label) @label = label @samp_rate = 1.0 @osc_amp = 0.3 @osc_freq = 20 @dlg = nil @target = :sound end def inspect format("%s (%1.2f %1.2f %1.2f)", @label, @samp_rate, @osc_amp, @osc_freq) end def post_dialog unless @dlg.kind_of?(Dialog) and widget?(@dlg.dialog) init_rate = 1.0 init_amp = 0.3 init_freq = 20 sliders = Array.new(3) @dlg = make_dialog(@label, :info, "Move the sliders to set the sample rate, \ oscillator amplitude, and oscillator frequency.", :target_cb, lambda do | | effect_target_ok(@target) end, :reset_cb, lambda do |w, c, i| set_scale_value(sliders[0].scale, @samp_rate = init_rate, 100.0) set_scale_value(sliders[1].scale, @osc_amp = init_amp, 100.0) set_scale_value(sliders[2].scale, @osc_freq = init_freq, 100.0) end) do |w, c, i| ms = (@target == :marks and plausible_mark_samples) effects_fp(@samp_rate, @osc_amp, @osc_freq, case @target when :sound 0 when :selection selection_position else ms[0] end, case @target when :sound framples when :selection selection_framples else ms[1] - ms[0] end) end sliders[0] = @dlg.add_slider("sample rate", 0.0, init_rate, 2.0, 100) do |w, c, i| @samp_rate = get_scale_value(w, i, 100.0) end sliders[1] = @dlg.add_slider("oscillator amplitude", 0.0, init_amp, 1.0, 100) do |w, c, i| @osc_amp = get_scale_value(w, i, 100.0) end sliders[2] = @dlg.add_slider("oscillator frequency", 0.0, init_freq, 60, 100) do |w, c, i| @osc_freq = get_scale_value(w, i, 100.0) end @dlg.add_target() do |t| set_sensitive(@dlg.okay_button, effect_target_ok(@target = t)) end end activate_dialog(@dlg.dialog) end end class Rubber_sound def initialize(label) @label = label @factor = 1.0 @dlg = nil @target = :sound end def inspect format("%s (%1.2f)", @label, @factor) end def post_dialog unless @dlg.kind_of?(Dialog) and widget?(@dlg.dialog) init_factor = 1.0 sliders = Array.new(1) @dlg = make_dialog(@label, :info, "Stretches or contracts the time of a sound. \ Move the slider to change the stretch factor.", :target_cb, lambda do | | effect_target_ok(@target) end, :reset_cb, lambda do |w, c, i| set_scale_value(sliders[0].scale, @factor = init_factor, 100.0) end) do |w, c, i| rubber_sound(@factor) end sliders[0] = @dlg.add_slider("stretch factor", 0.0, init_factor, 5.0, 100) do |w, c, i| @factor = get_scale_value(w, i, 100.0) end @dlg.add_target() do |t| set_sensitive(@dlg.okay_button, effect_target_ok(@target = t)) end end activate_dialog(@dlg.dialog) end end class Wobble def initialize(label) @label = label @frequency = 50 @amplitude = 0.5 @dlg = nil @target = :sound end def inspect format("%s (%1.2f %1.2f)", @label, @frequency, @amplitude) end def post_dialog unless @dlg.kind_of?(Dialog) and widget?(@dlg.dialog) init_freq = 50 init_amp = 0.5 sliders = Array.new(2) @dlg = make_dialog(@label, :info, "Move the sliders to set the wobble frequency and amplitude.", :target_cb, lambda do | | effect_target_ok(@target) end, :reset_cb, lambda do |w, c, i| set_scale_value(sliders[0].scale, @frequency = init_freq, 100.0) set_scale_value(sliders[1].scale, @amplitude = init_amp, 100.0) end) do |w, c, i| ms = (@target == :marks and plausible_mark_samples) effects_hello_dentist(@frequency, @amplitude, case @target when :sound 0 when :selection selection_position else ms[0] end, case @target when :sound framples when :selection selection_framples else ms[1] - ms[0] end) end sliders[0] = @dlg.add_slider("wobble frequency", 0, init_freq, 100, 100) do |w, c, i| @frequency = get_scale_value(w, i, 100.0) end sliders[1] = @dlg.add_slider("wobble amplitude", 0.0, init_amp, 1.0, 100) do |w, c, i| @amplitude = get_scale_value(w, i, 100.0) end @dlg.add_target() do |t| set_sensitive(@dlg.okay_button, effect_target_ok(@target = t)) end end activate_dialog(@dlg.dialog) end end end unless provided? :snd_nogui # # example menu # if provided? :snd_nogui include Effects else include X_Effects snd_main = make_snd_menu("Effects") do cascade("Amplitude Effects") do entry(Gain, "Gain") entry(Normalize, "Normalize") entry(Gate, "Gate") end cascade("Delay Effects") do entry(Echo, "Echo") entry(Filtered_echo, "Filtered echo") entry(Modulated_echo, "Modulated echo") end cascade("Filter Effects") do entry(Band_pass, "Band-pass filter") entry(Band_reject, "Band-reject filter") entry(High_pass, "High-pass filter") entry(Low_pass, "Low-pass filter") entry(Comb, "Comb filter") entry(Comb_chord, "Comb chord filter") entry(Moog_filter, "Moog filter") end cascade("Frequency Effects") do entry(Adaptive, "Adaptive saturation") entry(Sample_rate, "Sample rate conversion") entry(Time_pitch, "Time/pitch scaling") entry(Src_timevar, "Src-Timevar") end cascade("Modulation Effects") do entry(Amplitude_modulation, "Amplitude modulation") entry(Ring_modulation, "Ring modulation") end cascade("Reverbs") do entry(Nrev, "McNabb reverb") entry(Chowning, "Chowning reverb") entry(Convolution, "Convolution") end cascade("Various") do entry(Placed, "Place sound") entry(Add_silence, "Add silence") entry(Contrast, "Contrast enhancement") entry(Cross_synthesis, "Cross synthesis") entry(Flange, "Flange") entry(Randomize_phase, "Randomize phase") entry(Robotize, "Robotize") entry(Rubber_sound, "Rubber sound") entry(Wobble, "Wobble") end separator entry("Octave-down") do down_oct(2) end entry("Remove clicks") do find_click = lambda do |loc| reader = make_sampler(loc) samp0 = samp1 = samp2 = 0.0 samps = make_vct(10) len = framples() samps_ctr = 0 ret = false ctr = loc until ctr == len samp0, samp1 = samp1, samp2 samp2 = next_sample(reader) samps[samps_ctr] = samp0 if samps_ctr < 9 samps_ctr += 1 else samps_ctr = 0 end local_max = [0.1, vct_peak(samps)].max if ((samp0 - samp1).abs > local_max) and ((samp1 - samp2).abs > local_max) and ((samp0 - samp2).abs < (local_max / 2)) ret = ctr - 1 break end ctr += 1 end ret end remove_click = lambda do |loc| if click = find_click.call(loc) smooth_sound(click - 2, 4) remove_click.call(click + 2) end end remove_click.call(2) end entry("Remove DC") do effects_remove_dc end entry("Spiker") do spike end entry("Compand") do effects_compand end entry("Invert") do scale_by(-1) end entry("Reverse") do reverse_sound end entry("Null phase") do zero_phase end end set_effects_menu_sensitive = lambda do |flag| if $with_motif set_label_sensitive(menu_widgets[Top_menu_bar], "Effects", flag) else set_sensitive(snd_main.menu, flag) end end set_effects_menu_sensitive.call(Snd.sounds.length > 0) unless $open_hook.member?("effects-menu-hook") $open_hook.add_hook!("effects-menu-hook") do |snd| set_effects_menu_sensitive.call(true) false end $close_hook.add_hook!("effects-menu-hook") do |snd| set_effects_menu_sensitive.call(Snd.sounds.length > 1) false end end $effects_menu = true end # effects.rb ends here snd-16.1/v.rb0000644000076400007640000002474312434353163011143 0ustar bilbil# Translator: Michael Scholz # Created: 02/11/20 02:24:34 # Changed: 14/11/23 03:36:55 # fm_violin(start, dur, freq, amp, *args) # play_fm_violin(start, dur, freq, amp, *args) # make_fm_violin(start, dur, freq, amp, *args) # jc_reverb(*args) require "ws" v_opts_str = "fm_violin(start=0.0, dur=1.0, freq=440.0, amp=0.5, *args) :fm_index = 1.0 :amp_env = [0, 0, 25, 1, 75, 1, 100, 0] :periodic_vibrato_rate = 5.0 :random_vibrato_rate = 16.0 :periodic_vibrato_amp = 0.0025 :random_vibrato_amp = 0.005 :noise_amount = 0.0 :noise_freq = 1000.0 :ind_noise_freq = 10.0 :ind_noise_amount = 0.0 :amp_noise_freq = 20.0 :amp_noise_amount = 0.0 :gliss_env = [0, 0, 100, 0] :gliss_amount = 0.0 :fm1_env = [0, 1, 25, 0.4, 75, 0.6, 100, 0] :fm2_env = [0, 1, 25, 0.4, 75, 0.6, 100, 0] :fm3_env = [0, 1, 25, 0.4, 75, 0.6, 100, 0] :fm1_rat = 1.0 :fm2_rat = 3.0 :fm3_rat = 4.0 :fm1_index = false :fm2_index = false :fm3_index = false :base = 1.0 :index_type = :violin" add_help(:fm_violin, "#{v_opts_str} :reverb_amount = 0.01 :degree = kernel_rand(90.0) :distance = 1.0 Ruby: fm_violin(0, 1, 440, 0.1, :fm_index, 2.0) Scheme: (fm-violin 0 1 440 0.1 :fm-index 2.0) Example: with_sound do fm_violin(0, 1, 440, 0.1, :fm_index, 2.0) end") def fm_violin(start = 0.0, dur = 1.0, freq = 440.0, amp = 0.5, *args) r = get_args(args, :reverb_amount, 0.01) d = get_args(args, :degree, kernel_rand(90.0)) s = get_args(args, :distance, 1.0) fm_vln = make_fm_violin_gen(start, dur, freq, amp, *args) run_instrument(start, dur, :reverb_amount, r, :degree, d, :distance, s) do fm_vln.call(0) end end add_help(:play_fm_violin, "play_#{v_opts_str} Returns a fm_violin proc with no arg for play(proc). v = play_fm_violin(0, 1, 440, 0.5) play(v) or play(play_fm_violin(0, 1, 440, 0.5))") def play_fm_violin(start = 0.0, dur = 1.0, freq = 440.0, amp = 0.5, *args) fm_vln = make_fm_violin_gen(start, dur, freq, amp, *args) len = seconds2samples(dur) lambda do (len -= 1).positive? and fm_vln.call(0) end end # # make_fm_violin: returns lambda do |y| ... end # add_help(:make_fm_violin, "make_#{v_opts_str} Returns a proc with one arg for map_channel() *args are like fm_violin's ins = new_sound(:file, \"fmv.snd\", :srate, 22050, :channels, 2) # proc with one arg fmv1 = make_fm_violin(0, 1, 440, 0.5) map_channel(fmv1, 0, 22050, ins, 1)") def make_fm_violin(start = 0.0, dur = 1.0, freq = 440.0, amp = 1.0, *args) make_fm_violin_gen(start, dur, freq, amp, *args) end def make_fm_violin_gen(start, dur, freq, amp, *args) fm_index, amp_env, periodic_vibrato_rate, random_vibrato_rate = nil periodic_vibrato_amp, random_vibrato_amp, noise_amount, noise_freq = nil ind_noise_freq, ind_noise_amount, amp_noise_freq, amp_noise_amount = nil gliss_env, gliss_amount = nil fm1_env, fm2_env, fm3_env, fm1_rat, fm2_rat, fm3_rat = nil fm1_index, fm2_index, fm3_index, base, index_type = nil optkey(args, binding, [:fm_index, 1.0], [:amp_env, [0, 0, 25, 1, 75, 1, 100, 0]], [:periodic_vibrato_rate, 5.0], [:random_vibrato_rate, 16.0], [:periodic_vibrato_amp, 0.0025], [:random_vibrato_amp, 0.005], [:noise_amount, 0.0], [:noise_freq, 1000.0], [:ind_noise_freq, 10.0], [:ind_noise_amount, 0.0], [:amp_noise_freq, 20.0], [:amp_noise_amount, 0.0], [:gliss_env, [0, 0, 100, 0]], [:gliss_amount, 0.0], [:fm1_env, [0, 1, 25, 0.4, 75, 0.6, 100, 0]], [:fm2_env, [0, 1, 25, 0.4, 75, 0.6, 100, 0]], [:fm3_env, [0, 1, 25, 0.4, 75, 0.6, 100, 0]], [:fm1_rat, 1.0], [:fm2_rat, 3.0], [:fm3_rat, 4.0], [:fm1_index, false], [:fm2_index, false], [:fm3_index, false], [:base, 1.0], [:index_type, :violin]) frq_scl = hz2radians(freq) modulate = fm_index.nonzero? maxdev = frq_scl * fm_index vln = (index_type == :violin or index_type == 1) logfreq = log(freq) sqrtfreq = sqrt(freq) index1 = (fm1_index or [PI, maxdev * (vln ? 5.0 : 7.5) / logfreq].min) index2 = (fm2_index or [PI, maxdev * 3.0 * (vln ? ((8.5 - logfreq) / (3.0 + freq * 0.001)) : (15.0 / sqrtfreq))].min) index3 = (fm3_index or [PI, maxdev * (vln ? 4.0 : 8.0) / sqrtfreq].min) easy_case = (noise_amount.zero? and (fm1_env == fm2_env) and (fm1_env == fm3_env) and (fm1_rat - fm1_rat.floor).zero? and (fm2_rat - fm2_rat.floor).zero? and (fm3_rat - fm3_rat.floor).zero?) norm = ((easy_case and modulate and 1.0) or index1) carrier = make_oscil(freq) fmosc1 = fmosc2 = fmosc3 = false indf1 = indf2 = indf3 = false if modulate indf1 = make_env(fm1_env, norm, dur) if easy_case a = [fm1_rat.to_i, index1, (fm2_rat / fm1_rat).floor, index2, (fm3_rat / fm1_rat).floor, index3] coe = partials2polynomial(a) fmosc1 = make_polyshape(:frequency, fm1_rat * freq, :coeffs, coe) else indf2 = make_env(fm2_env, index2, dur) indf3 = make_env(fm3_env, index3, dur) if (fm1_rat * freq * 2.0) > mus_srate fmosc1 = make_oscil(:frequency, freq) else fmosc1 = make_oscil(:frequency, fm1_rat * freq) end if (fm2_rat * freq * 2.0) > mus_srate fmosc2 = make_oscil(:frequency, freq) else fmosc2 = make_oscil(:frequency, fm2_rat * freq) end if (fm3_rat * freq * 2.0) > mus_srate fmosc3 = make_oscil(:frequency, freq) else fmosc3 = make_oscil(:frequency, fm3_rat * freq) end end end ampf = make_env(amp_env, amp, dur, 0.0, base) frqf = make_env(gliss_env, gliss_amount * frq_scl, dur) pervib = make_triangle_wave(periodic_vibrato_rate, periodic_vibrato_amp * frq_scl) ranvib = make_rand_interp(random_vibrato_rate, random_vibrato_amp * frq_scl) fm_noi = if noise_amount.nonzero? make_rand(noise_freq, PI * noise_amount) else false end ind_noi = if ind_noise_amount.nonzero? and ind_noise_freq.nonzero? make_rand_interp(ind_noise_freq, ind_noise_amount) else false end amp_noi = if amp_noise_amount.nonzero? and amp_noise_freq.nonzero? make_rand_interp(amp_noise_freq, amp_noise_amount) else false end fuzz = modulation = 0.0 ind_fuzz = amp_fuzz = 1.0 if modulate if easy_case lambda do |y| vib = env(frqf) + triangle_wave(pervib) + rand_interp(ranvib) ind_fuzz = 1.0 + rand_interp(ind_noi) if ind_noi amp_fuzz = 1.0 + rand_interp(amp_noi) if amp_noi modulation = env(indf1) * polyshape(fmosc1, 1.0, vib) env(ampf) * amp_fuzz * oscil(carrier, vib + ind_fuzz * modulation) end else lambda do |y| fuzz = rand(fm_noi) if fm_noi vib = env(frqf) + triangle_wave(pervib) + rand_interp(ranvib) ind_fuzz = 1.0 + rand_interp(ind_noi) if ind_noi amp_fuzz = 1.0 + rand_interp(amp_noi) if amp_noi modulation = (env(indf1) * oscil(fmosc1, fm1_rat * vib + fuzz) + env(indf2) * oscil(fmosc2, fm2_rat * vib + fuzz) + env(indf3) * oscil(fmosc3, fm3_rat * vib + fuzz)) env(ampf) * amp_fuzz * oscil(carrier, vib + ind_fuzz * modulation) end end else lambda do |y| vib = env(frqf) + triangle_wave(pervib) + rand_interp(ranvib) ind_fuzz = 1.0 + rand_interp(ind_noi) if ind_noi amp_fuzz = 1.0 + rand_interp(amp_noi) if amp_noi env(ampf) * amp_fuzz * oscil(carrier, vib + ind_fuzz) end end end add_help(:jc_reverb, "jc_reverb(*args) :volume = 1.0 :delay1 = 0.013 :delay2 = 0.011 :delay3 = 0.015 :delay4 = 0.017 :low_pass = false :double = false :amp_env = false Chowning reverb") def jc_reverb(*args) low_pass, volume, amp_env, delay1, delay2, delay3, delay4, double = nil optkey(args, binding, [:volume, 1.0], [:delay1, 0.013], [:delay2, 0.011], [:delay3, 0.015], [:delay4, 0.017], [:low_pass, false], [:double, false], [:amp_env, false]) chan2 = (@channels > 1) chan4 = (@channels == 4) if double and chan4 error("%s: not set up for doubled reverb in quad", get_func_name) end allpass1 = make_all_pass(-0.7, 0.7, 1051) allpass2 = make_all_pass(-0.7, 0.7, 337) allpass3 = make_all_pass(-0.7, 0.7, 113) comb1 = make_comb(0.742, 4799) comb2 = make_comb(0.733, 4999) comb3 = make_comb(0.715, 5399) comb4 = make_comb(0.697, 5801) outdel1 = make_delay((delay1 * @srate).round) outdel2 = (chan2 ? make_delay((delay2 * @srate).round) : false) outdel3 = ((chan4 or double) ? make_delay((delay3 * @srate).round) : false) outdel4 = ((chan4 or (double and chan2)) ? make_delay((delay4 * @srate).round) : false) envA = if amp_env make_env(:envelope, amp_env, :scaler, volume, :duration, ws_duration(@revfile) + @decay_time) else false end comb_sum_1 = comb_sum = 0.0 out_frample = Vct.new(@channels) run_reverb() do |ho, i| allpass_sum = all_pass(allpass3, all_pass(allpass2, all_pass(allpass1, ho))) comb_sum_2, comb_sum_1 = comb_sum_1, comb_sum comb_sum = (comb(comb1, allpass_sum) + comb(comb2, allpass_sum) + comb(comb3, allpass_sum) + comb(comb4, allpass_sum)) all_sums = if low_pass 0.25 * (comb_sum + comb_sum_2) + 0.5 * comb_sum_1 else comb_sum end delA = delay(outdel1, all_sums) if double delA += delay(outdel3, all_sums) end if envA volume = env(envA) end out_frample[0] = volume * delA if chan2 delB = delay(outdel2, all_sums) if double delB += delay(outdel4, all_sums) end out_frample[1] = volume * delB if chan4 out_frample[2] = volume * delay(outdel3, all_sums) out_frample[3] = volume * delay(outdel4, all_sums) end end out_frample end end # v.rb ends here snd-16.1/clm.h0000644000076400007640000014135112570344074011272 0ustar bilbil#ifndef CLM_H #define CLM_H #define MUS_VERSION 6 #define MUS_REVISION 13 #define MUS_DATE "5-Aug-15" /* isn't mus_env_interp backwards? */ #include "sndlib.h" #ifndef _MSC_VER #include #endif #if HAVE_COMPLEX_TRIG #include #endif #if(!defined(M_PI)) #define M_PI 3.14159265358979323846264338327 #define M_PI_2 (M_PI / 2.0) #endif #define MUS_DEFAULT_SAMPLING_RATE 44100.0 #define MUS_DEFAULT_FILE_BUFFER_SIZE 8192 #define MUS_DEFAULT_ARRAY_PRINT_LENGTH 8 typedef enum {MUS_NOT_SPECIAL, MUS_SIMPLE_FILTER, MUS_FULL_FILTER, MUS_OUTPUT, MUS_INPUT, MUS_DELAY_LINE} mus_clm_extended_t; typedef struct mus_any_class mus_any_class; typedef struct { struct mus_any_class *core; } mus_any; typedef enum {MUS_INTERP_NONE, MUS_INTERP_LINEAR, MUS_INTERP_SINUSOIDAL, MUS_INTERP_ALL_PASS, MUS_INTERP_LAGRANGE, MUS_INTERP_BEZIER, MUS_INTERP_HERMITE} mus_interp_t; typedef enum {MUS_RECTANGULAR_WINDOW, MUS_HANN_WINDOW, MUS_WELCH_WINDOW, MUS_PARZEN_WINDOW, MUS_BARTLETT_WINDOW, MUS_HAMMING_WINDOW, MUS_BLACKMAN2_WINDOW, MUS_BLACKMAN3_WINDOW, MUS_BLACKMAN4_WINDOW, MUS_EXPONENTIAL_WINDOW, MUS_RIEMANN_WINDOW, MUS_KAISER_WINDOW, MUS_CAUCHY_WINDOW, MUS_POISSON_WINDOW, MUS_GAUSSIAN_WINDOW, MUS_TUKEY_WINDOW, MUS_DOLPH_CHEBYSHEV_WINDOW, MUS_HANN_POISSON_WINDOW, MUS_CONNES_WINDOW, MUS_SAMARAKI_WINDOW, MUS_ULTRASPHERICAL_WINDOW, MUS_BARTLETT_HANN_WINDOW, MUS_BOHMAN_WINDOW, MUS_FLAT_TOP_WINDOW, MUS_BLACKMAN5_WINDOW, MUS_BLACKMAN6_WINDOW, MUS_BLACKMAN7_WINDOW, MUS_BLACKMAN8_WINDOW, MUS_BLACKMAN9_WINDOW, MUS_BLACKMAN10_WINDOW, MUS_RV2_WINDOW, MUS_RV3_WINDOW, MUS_RV4_WINDOW, MUS_MLT_SINE_WINDOW, MUS_PAPOULIS_WINDOW, MUS_DPSS_WINDOW, MUS_SINC_WINDOW, MUS_NUM_FFT_WINDOWS} mus_fft_window_t; typedef enum {MUS_SPECTRUM_IN_DB, MUS_SPECTRUM_NORMALIZED, MUS_SPECTRUM_RAW} mus_spectrum_t; typedef enum {MUS_CHEBYSHEV_EITHER_KIND, MUS_CHEBYSHEV_FIRST_KIND, MUS_CHEBYSHEV_SECOND_KIND, MUS_CHEBYSHEV_BOTH_KINDS} mus_polynomial_t; #define MUS_MAX_CLM_SINC_WIDTH 65536 #define MUS_MAX_CLM_SRC 65536.0 /* this is internal -- for clm->clm2xen */ typedef struct { mus_any_class *core; int chan; mus_long_t loc; char *file_name; int chans; mus_float_t **obufs; mus_float_t *obuf0, *obuf1; mus_long_t data_start, data_end; mus_long_t out_end; mus_sample_t output_sample_type; mus_header_t output_header_type; } rdout; /* end internal stuff */ #ifdef __cplusplus extern "C" { #endif MUS_EXPORT void mus_initialize(void); MUS_EXPORT int mus_make_generator_type(void); MUS_EXPORT mus_any_class *mus_generator_class(mus_any *ptr); MUS_EXPORT mus_any_class *mus_make_generator(int type, char *name, void (*release)(mus_any *ptr), char *(*describe)(mus_any *ptr), bool (*equalp)(mus_any *gen1, mus_any *gen2)); MUS_EXPORT void mus_generator_set_length(mus_any_class *p, mus_long_t (*length)(mus_any *ptr)); MUS_EXPORT void mus_generator_set_scaler(mus_any_class *p, mus_float_t (*scaler)(mus_any *ptr)); MUS_EXPORT void mus_generator_set_channels(mus_any_class *p, int (*channels)(mus_any *ptr)); MUS_EXPORT void mus_generator_set_location(mus_any_class *p, mus_long_t (*location)(mus_any *ptr)); MUS_EXPORT void mus_generator_set_set_location(mus_any_class *p, mus_long_t (*set_location)(mus_any *ptr, mus_long_t loc)); MUS_EXPORT void mus_generator_set_channel(mus_any_class *p, int (*channel)(mus_any *ptr)); MUS_EXPORT void mus_generator_set_file_name(mus_any_class *p, char *(*file_name)(mus_any *ptr)); MUS_EXPORT void mus_generator_set_extended_type(mus_any_class *p, mus_clm_extended_t extended_type); MUS_EXPORT void mus_generator_set_read_sample(mus_any_class *p, mus_float_t (*read_sample)(mus_any *ptr, mus_long_t samp, int chan)); MUS_EXPORT void mus_generator_set_feeders(mus_any *g, mus_float_t (*feed)(void *arg, int direction), mus_float_t (*block_feed)(void *arg, int direction, mus_float_t *block, mus_long_t start, mus_long_t end)); MUS_EXPORT void mus_generator_copy_feeders(mus_any *dest, mus_any *source); MUS_EXPORT mus_float_t mus_radians_to_hz(mus_float_t radians); MUS_EXPORT mus_float_t mus_hz_to_radians(mus_float_t hz); MUS_EXPORT mus_float_t mus_degrees_to_radians(mus_float_t degrees); MUS_EXPORT mus_float_t mus_radians_to_degrees(mus_float_t radians); MUS_EXPORT mus_float_t mus_db_to_linear(mus_float_t x); MUS_EXPORT mus_float_t mus_linear_to_db(mus_float_t x); MUS_EXPORT mus_float_t mus_odd_multiple(mus_float_t x, mus_float_t y); MUS_EXPORT mus_float_t mus_even_multiple(mus_float_t x, mus_float_t y); MUS_EXPORT mus_float_t mus_odd_weight(mus_float_t x); MUS_EXPORT mus_float_t mus_even_weight(mus_float_t x); MUS_EXPORT mus_float_t mus_srate(void); MUS_EXPORT mus_float_t mus_set_srate(mus_float_t val); MUS_EXPORT mus_long_t mus_seconds_to_samples(mus_float_t secs); MUS_EXPORT mus_float_t mus_samples_to_seconds(mus_long_t samps); MUS_EXPORT int mus_array_print_length(void); MUS_EXPORT int mus_set_array_print_length(int val); MUS_EXPORT mus_float_t mus_float_equal_fudge_factor(void); MUS_EXPORT mus_float_t mus_set_float_equal_fudge_factor(mus_float_t val); MUS_EXPORT mus_float_t mus_ring_modulate(mus_float_t s1, mus_float_t s2); MUS_EXPORT mus_float_t mus_amplitude_modulate(mus_float_t s1, mus_float_t s2, mus_float_t s3); MUS_EXPORT mus_float_t mus_contrast_enhancement(mus_float_t sig, mus_float_t index); MUS_EXPORT mus_float_t mus_dot_product(mus_float_t *data1, mus_float_t *data2, mus_long_t size); #if HAVE_COMPLEX_TRIG MUS_EXPORT complex double mus_edot_product(complex double freq, complex double *data, mus_long_t size); #endif MUS_EXPORT bool mus_arrays_are_equal(mus_float_t *arr1, mus_float_t *arr2, mus_float_t fudge, mus_long_t len); MUS_EXPORT mus_float_t mus_polynomial(mus_float_t *coeffs, mus_float_t x, int ncoeffs); MUS_EXPORT void mus_rectangular_to_polar(mus_float_t *rl, mus_float_t *im, mus_long_t size); MUS_EXPORT void mus_rectangular_to_magnitudes(mus_float_t *rl, mus_float_t *im, mus_long_t size); MUS_EXPORT void mus_polar_to_rectangular(mus_float_t *rl, mus_float_t *im, mus_long_t size); MUS_EXPORT mus_float_t mus_array_interp(mus_float_t *wave, mus_float_t phase, mus_long_t size); MUS_EXPORT mus_float_t mus_bessi0(mus_float_t x); MUS_EXPORT mus_float_t mus_interpolate(mus_interp_t type, mus_float_t x, mus_float_t *table, mus_long_t table_size, mus_float_t y); MUS_EXPORT bool mus_is_interp_type(int val); MUS_EXPORT bool mus_is_fft_window(int val); MUS_EXPORT int mus_sample_type_zero(mus_sample_t samp_type); MUS_EXPORT mus_float_t (*mus_run_function(mus_any *g))(mus_any *gen, mus_float_t arg1, mus_float_t arg2); /* -------- generic functions -------- */ MUS_EXPORT int mus_type(mus_any *ptr); MUS_EXPORT void mus_free(mus_any *ptr); MUS_EXPORT char *mus_describe(mus_any *gen); MUS_EXPORT bool mus_equalp(mus_any *g1, mus_any *g2); MUS_EXPORT mus_float_t mus_phase(mus_any *gen); MUS_EXPORT mus_float_t mus_set_phase(mus_any *gen, mus_float_t val); MUS_EXPORT mus_float_t mus_set_frequency(mus_any *gen, mus_float_t val); MUS_EXPORT mus_float_t mus_frequency(mus_any *gen); MUS_EXPORT mus_float_t mus_run(mus_any *gen, mus_float_t arg1, mus_float_t arg2); MUS_EXPORT mus_long_t mus_length(mus_any *gen); MUS_EXPORT mus_long_t mus_set_length(mus_any *gen, mus_long_t len); MUS_EXPORT mus_long_t mus_order(mus_any *gen); MUS_EXPORT mus_float_t *mus_data(mus_any *gen); MUS_EXPORT mus_float_t *mus_set_data(mus_any *gen, mus_float_t *data); MUS_EXPORT const char *mus_name(mus_any *ptr); MUS_EXPORT mus_float_t mus_scaler(mus_any *gen); MUS_EXPORT mus_float_t mus_set_scaler(mus_any *gen, mus_float_t val); MUS_EXPORT mus_float_t mus_offset(mus_any *gen); MUS_EXPORT mus_float_t mus_set_offset(mus_any *gen, mus_float_t val); MUS_EXPORT mus_float_t mus_width(mus_any *gen); MUS_EXPORT mus_float_t mus_set_width(mus_any *gen, mus_float_t val); MUS_EXPORT char *mus_file_name(mus_any *ptr); MUS_EXPORT void mus_reset(mus_any *ptr); MUS_EXPORT mus_any *mus_copy(mus_any *gen); MUS_EXPORT mus_float_t *mus_xcoeffs(mus_any *ptr); MUS_EXPORT mus_float_t *mus_ycoeffs(mus_any *ptr); MUS_EXPORT mus_float_t mus_xcoeff(mus_any *ptr, int index); MUS_EXPORT mus_float_t mus_set_xcoeff(mus_any *ptr, int index, mus_float_t val); MUS_EXPORT mus_float_t mus_ycoeff(mus_any *ptr, int index); MUS_EXPORT mus_float_t mus_set_ycoeff(mus_any *ptr, int index, mus_float_t val); MUS_EXPORT mus_float_t mus_increment(mus_any *rd); MUS_EXPORT mus_float_t mus_set_increment(mus_any *rd, mus_float_t dir); MUS_EXPORT mus_long_t mus_location(mus_any *rd); MUS_EXPORT mus_long_t mus_set_location(mus_any *rd, mus_long_t loc); MUS_EXPORT int mus_channel(mus_any *rd); MUS_EXPORT int mus_channels(mus_any *ptr); MUS_EXPORT int mus_position(mus_any *ptr); /* only C, envs (snd-env.c), shares slot with mus_channels */ MUS_EXPORT int mus_interp_type(mus_any *ptr); MUS_EXPORT mus_long_t mus_ramp(mus_any *ptr); MUS_EXPORT mus_long_t mus_set_ramp(mus_any *ptr, mus_long_t val); MUS_EXPORT mus_long_t mus_hop(mus_any *ptr); MUS_EXPORT mus_long_t mus_set_hop(mus_any *ptr, mus_long_t val); MUS_EXPORT mus_float_t mus_feedforward(mus_any *gen); MUS_EXPORT mus_float_t mus_set_feedforward(mus_any *gen, mus_float_t val); MUS_EXPORT mus_float_t mus_feedback(mus_any *rd); MUS_EXPORT mus_float_t mus_set_feedback(mus_any *rd, mus_float_t dir); /* -------- generators -------- */ MUS_EXPORT mus_float_t mus_oscil(mus_any *o, mus_float_t fm, mus_float_t pm); MUS_EXPORT mus_float_t mus_oscil_unmodulated(mus_any *ptr); MUS_EXPORT mus_float_t mus_oscil_fm(mus_any *ptr, mus_float_t fm); MUS_EXPORT mus_float_t mus_oscil_pm(mus_any *ptr, mus_float_t pm); MUS_EXPORT bool mus_is_oscil(mus_any *ptr); MUS_EXPORT mus_any *mus_make_oscil(mus_float_t freq, mus_float_t phase); MUS_EXPORT bool mus_is_oscil_bank(mus_any *ptr); MUS_EXPORT mus_float_t mus_oscil_bank(mus_any *ptr); MUS_EXPORT mus_any *mus_make_oscil_bank(int size, mus_float_t *freqs, mus_float_t *phases, mus_float_t *amps, bool stable); MUS_EXPORT mus_any *mus_make_ncos(mus_float_t freq, int n); MUS_EXPORT mus_float_t mus_ncos(mus_any *ptr, mus_float_t fm); MUS_EXPORT bool mus_is_ncos(mus_any *ptr); MUS_EXPORT mus_any *mus_make_nsin(mus_float_t freq, int n); MUS_EXPORT mus_float_t mus_nsin(mus_any *ptr, mus_float_t fm); MUS_EXPORT bool mus_is_nsin(mus_any *ptr); MUS_EXPORT mus_any *mus_make_nrxysin(mus_float_t frequency, mus_float_t y_over_x, int n, mus_float_t r); MUS_EXPORT mus_float_t mus_nrxysin(mus_any *ptr, mus_float_t fm); MUS_EXPORT bool mus_is_nrxysin(mus_any *ptr); MUS_EXPORT mus_any *mus_make_nrxycos(mus_float_t frequency, mus_float_t y_over_x, int n, mus_float_t r); MUS_EXPORT mus_float_t mus_nrxycos(mus_any *ptr, mus_float_t fm); MUS_EXPORT bool mus_is_nrxycos(mus_any *ptr); MUS_EXPORT mus_any *mus_make_rxykcos(mus_float_t freq, mus_float_t phase, mus_float_t r, mus_float_t ratio); MUS_EXPORT mus_float_t mus_rxykcos(mus_any *ptr, mus_float_t fm); MUS_EXPORT bool mus_is_rxykcos(mus_any *ptr); MUS_EXPORT mus_any *mus_make_rxyksin(mus_float_t freq, mus_float_t phase, mus_float_t r, mus_float_t ratio); MUS_EXPORT mus_float_t mus_rxyksin(mus_any *ptr, mus_float_t fm); MUS_EXPORT bool mus_is_rxyksin(mus_any *ptr); MUS_EXPORT mus_float_t mus_delay(mus_any *gen, mus_float_t input, mus_float_t pm); MUS_EXPORT mus_float_t mus_delay_unmodulated(mus_any *ptr, mus_float_t input); MUS_EXPORT mus_float_t mus_tap(mus_any *gen, mus_float_t loc); MUS_EXPORT mus_float_t mus_tap_unmodulated(mus_any *gen); MUS_EXPORT mus_any *mus_make_delay(int size, mus_float_t *line, int line_size, mus_interp_t type); MUS_EXPORT bool mus_is_delay(mus_any *ptr); MUS_EXPORT bool mus_is_tap(mus_any *ptr); MUS_EXPORT mus_float_t mus_delay_tick(mus_any *ptr, mus_float_t input); MUS_EXPORT mus_float_t mus_delay_unmodulated_noz(mus_any *ptr, mus_float_t input); MUS_EXPORT mus_float_t mus_comb(mus_any *gen, mus_float_t input, mus_float_t pm); MUS_EXPORT mus_float_t mus_comb_unmodulated(mus_any *gen, mus_float_t input); MUS_EXPORT mus_any *mus_make_comb(mus_float_t scaler, int size, mus_float_t *line, int line_size, mus_interp_t type); MUS_EXPORT bool mus_is_comb(mus_any *ptr); MUS_EXPORT mus_float_t mus_comb_unmodulated_noz(mus_any *ptr, mus_float_t input); MUS_EXPORT mus_float_t mus_comb_bank(mus_any *bank, mus_float_t inval); MUS_EXPORT mus_any *mus_make_comb_bank(int size, mus_any **combs); MUS_EXPORT bool mus_is_comb_bank(mus_any *g); MUS_EXPORT mus_float_t mus_notch(mus_any *gen, mus_float_t input, mus_float_t pm); MUS_EXPORT mus_float_t mus_notch_unmodulated(mus_any *gen, mus_float_t input); MUS_EXPORT mus_any *mus_make_notch(mus_float_t scaler, int size, mus_float_t *line, int line_size, mus_interp_t type); MUS_EXPORT bool mus_is_notch(mus_any *ptr); MUS_EXPORT mus_float_t mus_all_pass(mus_any *gen, mus_float_t input, mus_float_t pm); MUS_EXPORT mus_float_t mus_all_pass_unmodulated(mus_any *gen, mus_float_t input); MUS_EXPORT mus_any *mus_make_all_pass(mus_float_t backward, mus_float_t forward, int size, mus_float_t *line, int line_size, mus_interp_t type); MUS_EXPORT bool mus_is_all_pass(mus_any *ptr); MUS_EXPORT mus_float_t mus_all_pass_unmodulated_noz(mus_any *ptr, mus_float_t input); MUS_EXPORT mus_float_t mus_all_pass_bank(mus_any *bank, mus_float_t inval); MUS_EXPORT mus_any *mus_make_all_pass_bank(int size, mus_any **combs); MUS_EXPORT bool mus_is_all_pass_bank(mus_any *g); MUS_EXPORT mus_any *mus_make_moving_average(int size, mus_float_t *line); MUS_EXPORT mus_any *mus_make_moving_average_with_initial_sum(int size, mus_float_t *line, mus_float_t sum); MUS_EXPORT bool mus_is_moving_average(mus_any *ptr); MUS_EXPORT mus_float_t mus_moving_average(mus_any *ptr, mus_float_t input); MUS_EXPORT mus_any *mus_make_moving_max(int size, mus_float_t *line); MUS_EXPORT bool mus_is_moving_max(mus_any *ptr); MUS_EXPORT mus_float_t mus_moving_max(mus_any *ptr, mus_float_t input); MUS_EXPORT mus_any *mus_make_moving_norm(int size, mus_float_t *line, mus_float_t norm); MUS_EXPORT bool mus_is_moving_norm(mus_any *ptr); MUS_EXPORT mus_float_t mus_moving_norm(mus_any *ptr, mus_float_t input); MUS_EXPORT mus_float_t mus_table_lookup(mus_any *gen, mus_float_t fm); MUS_EXPORT mus_float_t mus_table_lookup_unmodulated(mus_any *gen); MUS_EXPORT mus_any *mus_make_table_lookup(mus_float_t freq, mus_float_t phase, mus_float_t *wave, mus_long_t wave_size, mus_interp_t type); MUS_EXPORT bool mus_is_table_lookup(mus_any *ptr); MUS_EXPORT mus_float_t *mus_partials_to_wave(mus_float_t *partial_data, int partials, mus_float_t *table, mus_long_t table_size, bool normalize); MUS_EXPORT mus_float_t *mus_phase_partials_to_wave(mus_float_t *partial_data, int partials, mus_float_t *table, mus_long_t table_size, bool normalize); MUS_EXPORT mus_float_t mus_sawtooth_wave(mus_any *gen, mus_float_t fm); MUS_EXPORT mus_any *mus_make_sawtooth_wave(mus_float_t freq, mus_float_t amp, mus_float_t phase); MUS_EXPORT bool mus_is_sawtooth_wave(mus_any *gen); MUS_EXPORT mus_float_t mus_square_wave(mus_any *gen, mus_float_t fm); MUS_EXPORT mus_any *mus_make_square_wave(mus_float_t freq, mus_float_t amp, mus_float_t phase); MUS_EXPORT bool mus_is_square_wave(mus_any *gen); MUS_EXPORT mus_float_t mus_triangle_wave(mus_any *gen, mus_float_t fm); MUS_EXPORT mus_any *mus_make_triangle_wave(mus_float_t freq, mus_float_t amp, mus_float_t phase); MUS_EXPORT bool mus_is_triangle_wave(mus_any *gen); MUS_EXPORT mus_float_t mus_triangle_wave_unmodulated(mus_any *ptr); MUS_EXPORT mus_float_t mus_pulse_train(mus_any *gen, mus_float_t fm); MUS_EXPORT mus_any *mus_make_pulse_train(mus_float_t freq, mus_float_t amp, mus_float_t phase); MUS_EXPORT bool mus_is_pulse_train(mus_any *gen); MUS_EXPORT mus_float_t mus_pulse_train_unmodulated(mus_any *ptr); MUS_EXPORT void mus_set_rand_seed(unsigned long seed); MUS_EXPORT unsigned long mus_rand_seed(void); MUS_EXPORT mus_float_t mus_random(mus_float_t amp); MUS_EXPORT mus_float_t mus_frandom(mus_float_t amp); MUS_EXPORT int mus_irandom(int amp); MUS_EXPORT mus_float_t mus_rand(mus_any *gen, mus_float_t fm); MUS_EXPORT mus_any *mus_make_rand(mus_float_t freq, mus_float_t base); MUS_EXPORT bool mus_is_rand(mus_any *ptr); MUS_EXPORT mus_any *mus_make_rand_with_distribution(mus_float_t freq, mus_float_t base, mus_float_t *distribution, int distribution_size); MUS_EXPORT mus_float_t mus_rand_interp(mus_any *gen, mus_float_t fm); MUS_EXPORT mus_any *mus_make_rand_interp(mus_float_t freq, mus_float_t base); MUS_EXPORT bool mus_is_rand_interp(mus_any *ptr); MUS_EXPORT mus_any *mus_make_rand_interp_with_distribution(mus_float_t freq, mus_float_t base, mus_float_t *distribution, int distribution_size); MUS_EXPORT mus_float_t mus_rand_interp_unmodulated(mus_any *ptr); MUS_EXPORT mus_float_t mus_rand_unmodulated(mus_any *ptr); MUS_EXPORT mus_float_t mus_asymmetric_fm(mus_any *gen, mus_float_t index, mus_float_t fm); MUS_EXPORT mus_float_t mus_asymmetric_fm_unmodulated(mus_any *gen, mus_float_t index); MUS_EXPORT mus_any *mus_make_asymmetric_fm(mus_float_t freq, mus_float_t phase, mus_float_t r, mus_float_t ratio); MUS_EXPORT bool mus_is_asymmetric_fm(mus_any *ptr); MUS_EXPORT mus_float_t mus_one_zero(mus_any *gen, mus_float_t input); MUS_EXPORT mus_any *mus_make_one_zero(mus_float_t a0, mus_float_t a1); MUS_EXPORT bool mus_is_one_zero(mus_any *gen); MUS_EXPORT mus_float_t mus_one_pole(mus_any *gen, mus_float_t input); MUS_EXPORT mus_any *mus_make_one_pole(mus_float_t a0, mus_float_t b1); MUS_EXPORT bool mus_is_one_pole(mus_any *gen); MUS_EXPORT mus_float_t mus_two_zero(mus_any *gen, mus_float_t input); MUS_EXPORT mus_any *mus_make_two_zero(mus_float_t a0, mus_float_t a1, mus_float_t a2); MUS_EXPORT bool mus_is_two_zero(mus_any *gen); MUS_EXPORT mus_any *mus_make_two_zero_from_frequency_and_radius(mus_float_t frequency, mus_float_t radius); MUS_EXPORT mus_float_t mus_two_pole(mus_any *gen, mus_float_t input); MUS_EXPORT mus_any *mus_make_two_pole(mus_float_t a0, mus_float_t b1, mus_float_t b2); MUS_EXPORT bool mus_is_two_pole(mus_any *gen); MUS_EXPORT mus_any *mus_make_two_pole_from_frequency_and_radius(mus_float_t frequency, mus_float_t radius); MUS_EXPORT mus_float_t mus_one_pole_all_pass(mus_any *f, mus_float_t input); MUS_EXPORT mus_any *mus_make_one_pole_all_pass(int size, mus_float_t coeff); MUS_EXPORT bool mus_is_one_pole_all_pass(mus_any *ptr); MUS_EXPORT mus_float_t mus_formant(mus_any *ptr, mus_float_t input); MUS_EXPORT mus_any *mus_make_formant(mus_float_t frequency, mus_float_t radius); MUS_EXPORT bool mus_is_formant(mus_any *ptr); MUS_EXPORT mus_float_t mus_set_formant_frequency(mus_any *ptr, mus_float_t freq_in_hz); MUS_EXPORT void mus_set_formant_radius_and_frequency(mus_any *ptr, mus_float_t radius, mus_float_t frequency); MUS_EXPORT mus_float_t mus_formant_with_frequency(mus_any *ptr, mus_float_t input, mus_float_t freq_in_radians); MUS_EXPORT mus_float_t mus_formant_bank(mus_any *bank, mus_float_t inval); MUS_EXPORT mus_float_t mus_formant_bank_with_inputs(mus_any *bank, mus_float_t *inval); MUS_EXPORT mus_any *mus_make_formant_bank(int size, mus_any **formants, mus_float_t *amps); MUS_EXPORT bool mus_is_formant_bank(mus_any *g); MUS_EXPORT mus_float_t mus_firmant(mus_any *ptr, mus_float_t input); MUS_EXPORT mus_any *mus_make_firmant(mus_float_t frequency, mus_float_t radius); MUS_EXPORT bool mus_is_firmant(mus_any *ptr); MUS_EXPORT mus_float_t mus_firmant_with_frequency(mus_any *ptr, mus_float_t input, mus_float_t freq_in_radians); MUS_EXPORT mus_float_t mus_filter(mus_any *ptr, mus_float_t input); MUS_EXPORT mus_any *mus_make_filter(int order, mus_float_t *xcoeffs, mus_float_t *ycoeffs, mus_float_t *state); MUS_EXPORT bool mus_is_filter(mus_any *ptr); MUS_EXPORT mus_float_t mus_fir_filter(mus_any *ptr, mus_float_t input); MUS_EXPORT mus_any *mus_make_fir_filter(int order, mus_float_t *xcoeffs, mus_float_t *state); MUS_EXPORT bool mus_is_fir_filter(mus_any *ptr); MUS_EXPORT mus_float_t mus_iir_filter(mus_any *ptr, mus_float_t input); MUS_EXPORT mus_any *mus_make_iir_filter(int order, mus_float_t *ycoeffs, mus_float_t *state); MUS_EXPORT bool mus_is_iir_filter(mus_any *ptr); MUS_EXPORT mus_float_t *mus_make_fir_coeffs(int order, mus_float_t *env, mus_float_t *aa); MUS_EXPORT mus_float_t *mus_filter_set_xcoeffs(mus_any *ptr, mus_float_t *new_data); MUS_EXPORT mus_float_t *mus_filter_set_ycoeffs(mus_any *ptr, mus_float_t *new_data); MUS_EXPORT int mus_filter_set_order(mus_any *ptr, int order); MUS_EXPORT mus_float_t mus_filtered_comb(mus_any *ptr, mus_float_t input, mus_float_t pm); MUS_EXPORT mus_float_t mus_filtered_comb_unmodulated(mus_any *ptr, mus_float_t input); MUS_EXPORT bool mus_is_filtered_comb(mus_any *ptr); MUS_EXPORT mus_any *mus_make_filtered_comb(mus_float_t scaler, int size, mus_float_t *line, int line_size, mus_interp_t type, mus_any *filt); MUS_EXPORT mus_float_t mus_filtered_comb_bank(mus_any *bank, mus_float_t inval); MUS_EXPORT mus_any *mus_make_filtered_comb_bank(int size, mus_any **combs); MUS_EXPORT bool mus_is_filtered_comb_bank(mus_any *g); MUS_EXPORT mus_float_t mus_wave_train(mus_any *gen, mus_float_t fm); MUS_EXPORT mus_float_t mus_wave_train_unmodulated(mus_any *gen); MUS_EXPORT mus_any *mus_make_wave_train(mus_float_t freq, mus_float_t phase, mus_float_t *wave, mus_long_t wsize, mus_interp_t type); MUS_EXPORT bool mus_is_wave_train(mus_any *gen); MUS_EXPORT mus_float_t *mus_partials_to_polynomial(int npartials, mus_float_t *partials, mus_polynomial_t kind); MUS_EXPORT mus_float_t *mus_normalize_partials(int num_partials, mus_float_t *partials); MUS_EXPORT mus_any *mus_make_polyshape(mus_float_t frequency, mus_float_t phase, mus_float_t *coeffs, int size, int cheby_choice); MUS_EXPORT mus_float_t mus_polyshape(mus_any *ptr, mus_float_t index, mus_float_t fm); MUS_EXPORT mus_float_t mus_polyshape_unmodulated(mus_any *ptr, mus_float_t index); #define mus_polyshape_no_input(Obj) mus_polyshape(Obj, 1.0, 0.0) MUS_EXPORT bool mus_is_polyshape(mus_any *ptr); MUS_EXPORT mus_any *mus_make_polywave(mus_float_t frequency, mus_float_t *coeffs, int n, int cheby_choice); MUS_EXPORT mus_any *mus_make_polywave_tu(mus_float_t frequency, mus_float_t *tcoeffs, mus_float_t *ucoeffs, int n); MUS_EXPORT bool mus_is_polywave(mus_any *ptr); MUS_EXPORT mus_float_t mus_polywave_unmodulated(mus_any *ptr); MUS_EXPORT mus_float_t mus_polywave(mus_any *ptr, mus_float_t fm); MUS_EXPORT mus_float_t mus_chebyshev_t_sum(mus_float_t x, int n, mus_float_t *tn); MUS_EXPORT mus_float_t mus_chebyshev_u_sum(mus_float_t x, int n, mus_float_t *un); MUS_EXPORT mus_float_t mus_chebyshev_tu_sum(mus_float_t x, int n, mus_float_t *tn, mus_float_t *un); MUS_EXPORT mus_float_t (*mus_polywave_function(mus_any *g))(mus_any *gen, mus_float_t fm); MUS_EXPORT mus_float_t mus_env(mus_any *ptr); MUS_EXPORT mus_any *mus_make_env(mus_float_t *brkpts, int npts, mus_float_t scaler, mus_float_t offset, mus_float_t base, mus_float_t duration, mus_long_t end, mus_float_t *odata); MUS_EXPORT bool mus_is_env(mus_any *ptr); MUS_EXPORT mus_float_t mus_env_interp(mus_float_t x, mus_any *env); MUS_EXPORT mus_long_t *mus_env_passes(mus_any *gen); /* for Snd */ MUS_EXPORT mus_float_t *mus_env_rates(mus_any *gen); /* for Snd */ MUS_EXPORT mus_float_t mus_env_offset(mus_any *gen); /* for Snd */ MUS_EXPORT mus_float_t mus_env_scaler(mus_any *gen); /* for Snd */ MUS_EXPORT mus_float_t mus_env_initial_power(mus_any *gen); /* for Snd */ MUS_EXPORT int mus_env_breakpoints(mus_any *gen); /* for Snd */ MUS_EXPORT mus_float_t mus_env_any(mus_any *e, mus_float_t (*connect_points)(mus_float_t val)); MUS_EXPORT mus_float_t (*mus_env_function(mus_any *g))(mus_any *gen); MUS_EXPORT mus_any *mus_make_pulsed_env(mus_any *e, mus_any *p); MUS_EXPORT bool mus_is_pulsed_env(mus_any *ptr); MUS_EXPORT mus_float_t mus_pulsed_env(mus_any *pl, mus_float_t inval); MUS_EXPORT mus_float_t mus_pulsed_env_unmodulated(mus_any *pl); MUS_EXPORT bool mus_is_file_to_sample(mus_any *ptr); MUS_EXPORT mus_any *mus_make_file_to_sample(const char *filename); MUS_EXPORT mus_any *mus_make_file_to_sample_with_buffer_size(const char *filename, mus_long_t buffer_size); MUS_EXPORT mus_float_t mus_file_to_sample(mus_any *ptr, mus_long_t samp, int chan); MUS_EXPORT mus_float_t mus_readin(mus_any *rd); MUS_EXPORT mus_any *mus_make_readin_with_buffer_size(const char *filename, int chan, mus_long_t start, int direction, mus_long_t buffer_size); #define mus_make_readin(Filename, Chan, Start, Direction) mus_make_readin_with_buffer_size(Filename, Chan, Start, Direction, mus_file_buffer_size()) MUS_EXPORT bool mus_is_readin(mus_any *ptr); MUS_EXPORT bool mus_is_output(mus_any *ptr); MUS_EXPORT bool mus_is_input(mus_any *ptr); MUS_EXPORT mus_float_t mus_in_any(mus_long_t frample, int chan, mus_any *IO); MUS_EXPORT bool mus_in_any_is_safe(mus_any *IO); /* new 6.0 */ MUS_EXPORT mus_float_t *mus_file_to_frample(mus_any *ptr, mus_long_t samp, mus_float_t *f); MUS_EXPORT mus_any *mus_make_file_to_frample(const char *filename); MUS_EXPORT bool mus_is_file_to_frample(mus_any *ptr); MUS_EXPORT mus_any *mus_make_file_to_frample_with_buffer_size(const char *filename, mus_long_t buffer_size); MUS_EXPORT mus_float_t *mus_frample_to_frample(mus_float_t *matrix, int mx_chans, mus_float_t *in_samps, int in_chans, mus_float_t *out_samps, int out_chans); MUS_EXPORT bool mus_is_frample_to_file(mus_any *ptr); MUS_EXPORT mus_float_t *mus_frample_to_file(mus_any *ptr, mus_long_t samp, mus_float_t *data); MUS_EXPORT mus_any *mus_make_frample_to_file_with_comment(const char *filename, int chans, mus_sample_t samp_type, mus_header_t head_type, const char *comment); #define mus_make_frample_to_file(Filename, Chans, SampType, HeadType) mus_make_frample_to_file_with_comment(Filename, Chans, SampType, HeadType, NULL) MUS_EXPORT mus_any *mus_continue_frample_to_file(const char *filename); MUS_EXPORT void mus_file_mix_with_reader_and_writer(mus_any *outf, mus_any *inf, mus_long_t out_start, mus_long_t out_framples, mus_long_t in_start, mus_float_t *mx, int mx_chans, mus_any ***envs); MUS_EXPORT void mus_file_mix(const char *outfile, const char *infile, mus_long_t out_start, mus_long_t out_framples, mus_long_t in_start, mus_float_t *mx, int mx_chans, mus_any ***envs); MUS_EXPORT bool mus_is_sample_to_file(mus_any *ptr); MUS_EXPORT mus_any *mus_make_sample_to_file_with_comment(const char *filename, int out_chans, mus_sample_t samp_type, mus_header_t head_type, const char *comment); #define mus_make_sample_to_file(Filename, Chans, SampType, HeadType) mus_make_sample_to_file_with_comment(Filename, Chans, SampType, HeadType, NULL) MUS_EXPORT mus_float_t mus_sample_to_file(mus_any *ptr, mus_long_t samp, int chan, mus_float_t val); MUS_EXPORT mus_any *mus_continue_sample_to_file(const char *filename); MUS_EXPORT int mus_close_file(mus_any *ptr); MUS_EXPORT mus_any *mus_sample_to_file_add(mus_any *out1, mus_any *out2); MUS_EXPORT mus_float_t mus_out_any(mus_long_t frample, mus_float_t val, int chan, mus_any *IO); MUS_EXPORT mus_float_t mus_safe_out_any_to_file(mus_long_t samp, mus_float_t val, int chan, mus_any *IO); MUS_EXPORT bool mus_out_any_is_safe(mus_any *IO); MUS_EXPORT mus_float_t mus_out_any_to_file(mus_any *ptr, mus_long_t samp, int chan, mus_float_t val); MUS_EXPORT void mus_locsig(mus_any *ptr, mus_long_t loc, mus_float_t val); MUS_EXPORT mus_any *mus_make_locsig(mus_float_t degree, mus_float_t distance, mus_float_t reverb, int chans, mus_any *output, int rev_chans, mus_any *revput, mus_interp_t type); MUS_EXPORT bool mus_is_locsig(mus_any *ptr); MUS_EXPORT mus_float_t mus_locsig_ref(mus_any *ptr, int chan); MUS_EXPORT mus_float_t mus_locsig_set(mus_any *ptr, int chan, mus_float_t val); MUS_EXPORT mus_float_t mus_locsig_reverb_ref(mus_any *ptr, int chan); MUS_EXPORT mus_float_t mus_locsig_reverb_set(mus_any *ptr, int chan, mus_float_t val); MUS_EXPORT void mus_move_locsig(mus_any *ptr, mus_float_t degree, mus_float_t distance); MUS_EXPORT mus_float_t *mus_locsig_outf(mus_any *ptr); MUS_EXPORT mus_float_t *mus_locsig_revf(mus_any *ptr); MUS_EXPORT void *mus_locsig_closure(mus_any *ptr); MUS_EXPORT void mus_locsig_set_detour(mus_any *ptr, void (*detour)(mus_any *ptr, mus_long_t val)); MUS_EXPORT int mus_locsig_channels(mus_any *ptr); MUS_EXPORT int mus_locsig_reverb_channels(mus_any *ptr); MUS_EXPORT bool mus_is_move_sound(mus_any *ptr); MUS_EXPORT mus_float_t mus_move_sound(mus_any *ptr, mus_long_t loc, mus_float_t val); MUS_EXPORT mus_any *mus_make_move_sound(mus_long_t start, mus_long_t end, int out_channels, int rev_channels, mus_any *doppler_delay, mus_any *doppler_env, mus_any *rev_env, mus_any **out_delays, mus_any **out_envs, mus_any **rev_envs, int *out_map, mus_any *output, mus_any *revput, bool free_arrays, bool free_gens); MUS_EXPORT mus_float_t *mus_move_sound_outf(mus_any *ptr); MUS_EXPORT mus_float_t *mus_move_sound_revf(mus_any *ptr); MUS_EXPORT void *mus_move_sound_closure(mus_any *ptr); MUS_EXPORT void mus_move_sound_set_detour(mus_any *ptr, void (*detour)(mus_any *ptr, mus_long_t val)); MUS_EXPORT int mus_move_sound_channels(mus_any *ptr); MUS_EXPORT int mus_move_sound_reverb_channels(mus_any *ptr); MUS_EXPORT mus_any *mus_make_src(mus_float_t (*input)(void *arg, int direction), mus_float_t srate, int width, void *closure); MUS_EXPORT mus_any *mus_make_src_with_init(mus_float_t (*input)(void *arg, int direction), mus_float_t srate, int width, void *closure, void (*init)(void *p, mus_any *g)); MUS_EXPORT mus_float_t mus_src(mus_any *srptr, mus_float_t sr_change, mus_float_t (*input)(void *arg, int direction)); MUS_EXPORT bool mus_is_src(mus_any *ptr); MUS_EXPORT mus_float_t *mus_src_20(mus_any *srptr, mus_float_t *in_data, mus_long_t dur); MUS_EXPORT mus_float_t *mus_src_05(mus_any *srptr, mus_float_t *in_data, mus_long_t dur); MUS_EXPORT void mus_src_to_buffer(mus_any *srptr, mus_float_t (*input)(void *arg, int direction), mus_float_t *out_data, mus_long_t dur); MUS_EXPORT void mus_src_init(mus_any *ptr); MUS_EXPORT bool mus_is_convolve(mus_any *ptr); MUS_EXPORT mus_float_t mus_convolve(mus_any *ptr, mus_float_t (*input)(void *arg, int direction)); MUS_EXPORT mus_any *mus_make_convolve(mus_float_t (*input)(void *arg, int direction), mus_float_t *filter, mus_long_t fftsize, mus_long_t filtersize, void *closure); MUS_EXPORT mus_float_t *mus_spectrum(mus_float_t *rdat, mus_float_t *idat, mus_float_t *window, mus_long_t n, mus_spectrum_t type); MUS_EXPORT void mus_fft(mus_float_t *rl, mus_float_t *im, mus_long_t n, int is); MUS_EXPORT mus_float_t *mus_make_fft_window(mus_fft_window_t type, mus_long_t size, mus_float_t beta); MUS_EXPORT mus_float_t *mus_make_fft_window_with_window(mus_fft_window_t type, mus_long_t size, mus_float_t beta, mus_float_t mu, mus_float_t *window); MUS_EXPORT const char *mus_fft_window_name(mus_fft_window_t win); MUS_EXPORT const char **mus_fft_window_names(void); MUS_EXPORT mus_float_t *mus_autocorrelate(mus_float_t *data, mus_long_t n); MUS_EXPORT mus_float_t *mus_correlate(mus_float_t *data1, mus_float_t *data2, mus_long_t n); MUS_EXPORT mus_float_t *mus_convolution(mus_float_t *rl1, mus_float_t *rl2, mus_long_t n); MUS_EXPORT void mus_convolve_files(const char *file1, const char *file2, mus_float_t maxamp, const char *output_file); MUS_EXPORT mus_float_t *mus_cepstrum(mus_float_t *data, mus_long_t n); MUS_EXPORT bool mus_is_granulate(mus_any *ptr); MUS_EXPORT mus_float_t mus_granulate(mus_any *ptr, mus_float_t (*input)(void *arg, int direction)); MUS_EXPORT mus_float_t mus_granulate_with_editor(mus_any *ptr, mus_float_t (*input)(void *arg, int direction), int (*edit)(void *closure)); MUS_EXPORT mus_any *mus_make_granulate(mus_float_t (*input)(void *arg, int direction), mus_float_t expansion, mus_float_t length, mus_float_t scaler, mus_float_t hop, mus_float_t ramp, mus_float_t jitter, int max_size, int (*edit)(void *closure), void *closure); MUS_EXPORT int mus_granulate_grain_max_length(mus_any *ptr); MUS_EXPORT void mus_granulate_set_edit_function(mus_any *ptr, int (*edit)(void *closure)); MUS_EXPORT mus_long_t mus_set_file_buffer_size(mus_long_t size); MUS_EXPORT mus_long_t mus_file_buffer_size(void); MUS_EXPORT mus_float_t mus_apply(mus_any *gen, mus_float_t f1, mus_float_t f2); MUS_EXPORT bool mus_is_phase_vocoder(mus_any *ptr); MUS_EXPORT mus_any *mus_make_phase_vocoder(mus_float_t (*input)(void *arg, int direction), int fftsize, int overlap, int interp, mus_float_t pitch, bool (*analyze)(void *arg, mus_float_t (*input)(void *arg1, int direction)), int (*edit)(void *arg), /* return value is ignored (int return type is intended to be consistent with granulate) */ mus_float_t (*synthesize)(void *arg), void *closure); MUS_EXPORT mus_float_t mus_phase_vocoder(mus_any *ptr, mus_float_t (*input)(void *arg, int direction)); MUS_EXPORT mus_float_t mus_phase_vocoder_with_editors(mus_any *ptr, mus_float_t (*input)(void *arg, int direction), bool (*analyze)(void *arg, mus_float_t (*input)(void *arg1, int direction)), int (*edit)(void *arg), mus_float_t (*synthesize)(void *arg)); MUS_EXPORT mus_float_t *mus_phase_vocoder_amp_increments(mus_any *ptr); MUS_EXPORT mus_float_t *mus_phase_vocoder_amps(mus_any *ptr); MUS_EXPORT mus_float_t *mus_phase_vocoder_freqs(mus_any *ptr); MUS_EXPORT mus_float_t *mus_phase_vocoder_phases(mus_any *ptr); MUS_EXPORT mus_float_t *mus_phase_vocoder_phase_increments(mus_any *ptr); MUS_EXPORT mus_any *mus_make_ssb_am(mus_float_t freq, int order); MUS_EXPORT bool mus_is_ssb_am(mus_any *ptr); MUS_EXPORT mus_float_t mus_ssb_am_unmodulated(mus_any *ptr, mus_float_t insig); MUS_EXPORT mus_float_t mus_ssb_am(mus_any *ptr, mus_float_t insig, mus_float_t fm); MUS_EXPORT void mus_clear_sinc_tables(void); MUS_EXPORT void *mus_environ(mus_any *gen); MUS_EXPORT void *mus_set_environ(mus_any *gen, void *e); MUS_EXPORT mus_any *mus_bank_generator(mus_any *g, int i); #ifdef __cplusplus } #endif #endif /* Change log. * * 5-Aug: removed some now-obsolete mus_locsig functions. * 5-Jul: added stable arg to mus_make_oscil_bank. * 15-Feb: removed mus_set_name, changed mus_free to void. * 31-Jan-15: removed mus_multiply_arrays. * -------- * 8-Nov: mus_copy, mus_bank_generator. * 24-Oct: mus_generator_set_feeders. * 10-Aug: data-format -> sample-type. * 17-Apr: moving_norm generator. * 14-Apr: mus_frame and mus_mixer removed, "frame" replaced by "frample" in IO functions. * 11-Apr: mus_even|odd_weight|multiple. * 9-Apr: deprecate mus_is_delay_line. * 2-Apr: mus_make_moving_average_with_sum. * 19-Mar: deprecate mus_make_env_with_length. * 17-Feb-14: mus_*_p -> mus_is_*. * -------- * 7-Dec: mus_set_formant_frequency, mus_src_20 and mus_src_05 changed. Removed mus_in_any_from_file. * 29-Nov: mus_make_polywave_tu. * 11-Oct: mus_vector_to_file, mus_vector_mix. * 19-Apr: rxyk!cos and rxyk!sin from generators.scm. * 11-Apr: mus_tap_p as a better name for mus_delay_line_p. * 27-Mar: comb-bank, all-pass-bank, filtered-comb-bank, pulsed-env, oscil-bank. * 21-Mar: one-pole-all-pass generator. * 14-Mar: formant-bank generator. * removed mus_delay_tick_noz. * 4-Mar: moving_max generator. * removed the unstable filter check in make_two_pole. * 21-Jan-13: changed mus_formant_bank parameters. * -------- * 22-Dec: removed all the safety settings. * 15-Nov: removed mus_env_t, mus_env_type, and other recently deprecated stuff. * 15-Jul: more changes for clm2xen. * 4-July-12: moved various struct definitions to clm.c * added accessors for mus_any_class etc. * -------- * 1-Sep: mus_type. * 20-Aug: changed type of mus_locsig to void, added mus_locsig_function_reset. * removed function-as-output-location from locsig et al. * 14-Jul-11: removed pthread stuff. * -------- * 7-Mar-10: protect in-any and out-any from sample numbers less than 0. * -------- * 14-Oct: sine-summation, sum-of-sines, sum-of-cosines removed. * 28-Aug: changed some fft-related sizes from int to mus_long_t. * 17-Aug: mus_frame|mixer_copy|fill. * 27-Jul: mus_float_t for Float, and mus_long_t for off_t. * 15-Jun: mus_rectangular_to_magnitudes (polar, but ignore phases). * 11-Jun: mus_cepstrum. * 11-May: MUS_ENV_LINEAR and friends, also mus_env_linear|exponential. * mus_frame_to_frame_mono|stereo. * 12-Mar: sinc, papoulis and dpss (slepian windows). * 1-Jan-09: added MUS_EXPORT. * -------- * 11-Dec: deprecated the sine-summation, sum-of-cosines, and sum-of-sines generators. * 30-Oct: mus_sample_to_file_add. * mus_describe once again allocates a fresh output string. * finally removed sine-bank. * 9-Oct: various thread-related internal changes. * 14-Jul: mus_data_format_zero. * 12-Jul: mus_interp_type_p and mus_fft_window_p for C++'s benefit. * 1-July: mus-safety and various ints changed to mus_long_t. * 20-Jun: support for pthreads. * 16-Jun: changed init_mus_module to mus_initialize. * 30-May: changed polyshape to use cos and added cheby_choice arg to mus_make_polyshape. * 27-May: mus_waveshape retired -- generators.scm has a wrapper for it. * clm_free, clm_realloc etc for rt work. * mus_chebyshev_tu_sum. * 25-May: mus_polywave algorithm changed. * 17-May: mus_normalize_partials. * 12-Apr: added choice arg to mus_make_polywave. * 8-Apr: polywave uses sine-bank if highest harmonic out of Chebyshev range. * 1-Mar: mus_set_name. * 26-Feb: removed mus_cosines (use mus_length) * 24-Feb: removed mus_make_env_with_start, added mus_make_env_with_length * 20-Feb: clm 4: * polywave for polyshape and waveshape. * mus_formant_with_frequency. * firmant generator. * removed mus_formant_radius and mus_set_formant_radius. * removed "gain" arg from mus_make_formant. * reversed the order of the arguments to mus_make_formant. * fixed long-standing bug in gain calculation in mus_formant. * mus_env_any for arbitrary connecting functions. * 15-Feb: nrxysin and nrxycos for sine-summation. * 12-Feb: nsin for sum_of_sines, ncos for sum_of_cosines. * 4-Feb: clm_default_frequency (clm2xen) and *clm-default-frequency* (ws.scm). * 7-Jan-08: :dur replaced by :length in make-env. * -------- * 19-Oct: all *_0 *_1 *_2 names now use _fm|_pm|_unmodulated|_no_input. * 17-Oct: replace some method macros with functions (def-clm-struct local methods need true names). * 15-Oct: mus_oscil_1 -> _fm, _2->_pm. * mus_phase_vocoder_outctr accessors changed to use mus_location. * 11-Oct: changed default srate to 44100. * 5-Oct: mus_oscil_2. * 6-Sep: changed asymmetric-fm to use cos(sin) and added amplitude normalization. * 6-Aug: mus_autocorrelate, mus_correlate. * 3-Aug: blackman5..10 and Rife-Vincent (RV2..4 fft), mlt-sine windows. * 16-July: removed start arg from mus_make_env (see mus_make_env_with_start). * 5-July: changed some mus_float_ts to doubles in env funcs. * exp envs now use repeated multiplies rather than direct exp call. * 19-June: mus-increment on gens with a notion of frequency (phase increment); * to make room for this, asymmetric-fm ratio and sine-summation b moved to mus-offset. * 22-Feb: mus_big_fft and mus_spectrum_t. * 21-Feb: mus_fft_window_name. * 14-Feb-07: three more fft window choices. * -------- * 27-Nov: move-sound array access parallel to locsig. * 22-Nov: had to add non-backwards-compatible reverb chans arg to mus_make_locsig. * 21-Nov: mus_float_equal_fudge_factor, mus_arrays_are_equal. * 30-July: renamed average to moving_average. * 28-July: renamed make_ppolar and make_zpolar to make_two_pole|zero_from_radius_and_frequency. * added mus_scaler and mus_frequency methods for two_pole and two_zero. * 21-July: removed mus_wrapper field -- old way can't work since we need the original Xen object. * 3-July: mus_move_sound (dlocsig) generator. * changed return type of mus_locsig to float. * 28-June: mus_filtered_comb generator. * 8-May: mus_apply now takes 3 args: gen, two doubles (rather than bug-prone varargs). * 1-Mar-06: granulate now has a local random number seed (settable via the mus-location method). * -------- * 20-Dec: samaraki and ultraspherical windows. * this required a non-backwards-compatible additional argument in mus_make_fft_window_with_window. * 1-Nov: mus_filter_set_x|ycoeffs, mus_filter_set_order (needed by Snd). * 1-May: mus-scaler|feedback ok with delay and average. * 18-Apr: mus_set_environ. * 11-Apr: mus_mixer|frame_offset, mus_frame_scale (for higher level generic functions). * 23-Mar: frame_to_frame arg interpretation changed. * 21-Mar: mus_make_readin|file_to_sample|file_to_frame_with_buffer_size. * 16-Mar: polyshape generator (waveshaper as polynomial + oscil) * mus_chebyshev_first|second_kind. * mus_partials_to_waveshape no longer normalizes the partials. * 18-Feb: mus_interpolate. * 14-Feb: deprecated mus_restart_env and mus_clear_filter_state. * 7-Feb-05: mus_reset method, replaces mus_restart_env and mus_clear_filter_state. * -------- * 20-Dec: changed "jitter" handling if hop < .05 in granulate. * 15-Dec: mus_generator? for type checks (clm2xen). * 11-Sep: removed buffer generator. * 6-Sep: removed mus_oscil_bank, mus_bank. * 24-Aug: removed mus_inspect method -- overlaps mus_describe and is useless given gdb capabilities. * 27-July: mus_granulate_with_editor and mus_phase_vocoder_with_editors. * 21-July: edit-func as run-time arg to granulate (for CL/clm compatibility) * 19-July: clm 3: * deprecated mus_ina|b, mus-outa|b|c|d. * mus_make_frame_to_file_with_comment, mus_mixer_scale, mus_make_frame|mixer_with_data. * mus_make_scalar_mixer, mus_mixer_add, mus_continue_frame_to_file. * changed pv_* to phase_vocoder_* * 28-June: ssb_am + added fm arg (ssb_am_1 is the previous form). * 21-June: wrapper method. * 14-June: ssb_am generator. * deprecated mus-a*|b*, replaced by mus-x|ycoeff. * 9-June: mus_edot_product. * 7-June: removed mus-x*|y* generic functions. * 24-May: distribution arg to make-rand, make-rand-interp. * 11-May: type arg to mus_make_table_lookup|wave_train, MUS_INTERP_NONE, MUS_INTERP_HERMITE. * mus-interp-type. * 10-May: changed MUS_LINEAR and MUS_SINUSOIDAL to MUS_INTERP_LINEAR and MUS_INTERP_SINUSOIDAL. * mus-linear renamed mus-interp-linear, mus-sinusoidal renamed mus-interp-sinusoidal. * added type arg to mus_make_delay|all_pass|comb|notch. * added mus_delay_tick, all-pass delay line interpolation. * 3-May: envelope arg to make-rand and make-rand-interp to give any arbitrary random number distribution. * added mus_make_rand_with_distribution and mus_make_rand_interp_with_distribution. * rand/rand-interp mus-data returns distribution (weight) function, mus-length its length. * locsig mus-data returns output scalers, mus-xcoeffs returns reverb scalers * 26-Apr: mus_sum_of_sines changed to mus_sine_bank. * new mus_sum_of_sines parallels mus_sum_of_cosines. * deprecated mus_sin. * 14-Apr: changed "2" to "_to_" in several function names. * 12-Apr: mus_average, mus_average_p, mus_make_average. * 17-Mar: edit function added to mus_granulate. * replaced MUS_DATA_POSITION with MUS_DATA_WRAPPER. * 22-Jan: various "environ" variables renamed for Windows' benefit. * 5-Jan-04: env_interp bugfix. * -------- * 29-Sep: removed length arg from spectrum in clm2xen. * 24-Aug: changed mus_length|ramp|hop type to mus_long_t. * 21-Aug: export MUS_INPUT and friends (needed for specialized INA handlers). * 11-Aug: int -> bool. * 7-Aug: removed mus_type. * 20-July: more run methods. * 15-July: linear->dB check for 0.0 arg. * 27-June: mus_samples_to_seconds and mus_seconds_to_samples. * 9-June: mus_mix_with_reader_and_writer. * 27-May: bugfix: interpolating all-pass ("zall-pass") had an extra delay. * 25-Apr: mus_spectrum and mus_convolution now return mus_float_t*. * 9-Apr: removed MUS_HANNING_WINDOW (use MUS_HANN_WINDOW). * 3-Mar: mus_delay_line_p for tap error checking. * 27-Feb: mus_length for env -> original duration in samples. * 21-Feb: mus_set_cosines added, mus_cosines moved to hop slot. * mus_[set_]x1/x2/y1/y2. * 10-Feb: mus_file_name moved into the mus_input|output structs. * folded mus_input|output into mus_any. * moved mus_frame|mixer declarations into clm.c. * all mus_input|output|frame|mixer pointers->mus_any. * all method void pointers->mus_any. * 7-Feb: split strings out of clm2xen.c into clm-strings.h. * 3-Feb: mus_offset for envs, mus_width for square_wave et al. * new core class fields(10) for various methods. * 7-Jan-03: mus_src with very large sr_change segfault bugfix. * -------- * 17-Dec: mus_env_offset|initial_power for Snd exp env optimizations. * 13-Sep: mus_frandom and mus_irandom(for Snd optimizer). * 19-Aug: changed internal phase-vocoder array accessor names * 13-Aug: set!(*-ref) for frame, locsig, mixer, locsig-reverb. * 29-Jul: various *_1 cases for the optimizer. * 15-Jul: mus_continue_sample2file. * 10-Jul: mus_file_name. * 7-Jun: fftw support added. * 31-May: changed mus_any_class. * 3-May: many int->mus_long_t changes for large files. * 8-Apr: off-by-1 env bug(Lisp/C are now identical), env_interp of exp env beyond end bugfix. * 1-Apr: sine-summation n=0 bugfix. * 27-Mar: negative degree locsig bugfix. * 18-Mar: mus_move_locsig. * 15-Mar: n-chan locsig(and reverb scalers), 'type' arg to mus_make_locsig. * 6-Mar: mus_scaler in asymmetric-fm now refers to the "r" parameter, "a" in sine-summation. * 5-Mar: dumb typo in asymmetric-fm generator fixed. * 19-Feb: buffer reallocation redundant free bugfix. * 25-Jan-02: mus_increment of env returns base. * -------- * 10-Dec: add outctr calls, phase-vocoder bugfixes, thanks to Scott Wilson. * 21-Oct: fill in some set-data methods. * 1-Sep: mus_polar2rectangular. * 6-July: scm -> xen. * 26-May: mus_rand_seed. * 22-May: locsig reverb distance calc was upside down. * 18-May: mus_describe and mus_inspect returned string should not be freed any more. * 7-May: filled in some leftover equal_p methods. * 1-Apr: mus_make_file2sample_with_comment and mus_length for file->sample/sample->file. * mus_file_buffer_size. * 26-Mar: extended_type field added to mus_any_class for more robust type checking. * 16-Mar: mus_phase of env -> current_value. * 28-Feb: added mus_position(currently only for envs). * 8-Feb: clm2scm.h. * 24-Jan: mus-bank in clm2scm. * 5-Jan: clm2scm gens are applicable. * 4-Jan: mus_bank. * 2-Jan-01: mus_run method. * -------- * 28-Dec: mus_clear_filter_state and other minor tweaks for Snd. * 28-Nov: Dolph-Chebyshev window(under HAVE_GSL flag -- needs complex trig support). * 8-Nov: mus_clear_sinc_tables. * 12-Oct: mus_formant_bank takes one input(can't remember why I had an array here) * 27-Sep: mus_array_interp bugfix(imitates mus.lisp now). * 18-Sep: clm now assumes it's used as a part of sndlib. * 11-Sep: generalized set! to generic functions in clm2scm.c. * 31-Aug: changed formant field setters(thanks to Anders Vinjar). * 10-Aug: removed built-in setf support(clm2scm.c). * 31-Jul: mus_granulate tries to protect against illegal length and ramp values. * 24-Jul: mus_make_fir_coeffs. * 20-Jul: sum_of_sines, atan2 to rectangular->polar, phase_vocoder gen. * 22-June: made mus_bessi0 local again. * 1-June: bugfixes for linuxppc 2000. * 19-May: mus_apply. * 8-May: added "const" and XEN_PROCEDURE_CAST(for c++), made mus_bessi0 global. * 24-Apr: changed formant radius to match lisp version(it's now 1-old_radius) * 20-Apr: mus_convolve_files * 7-Apr: src width bug fixed * 31-Mar: finally implemented set-location for envs. * 14-Feb: buffer-full?. * 1-Feb: removed mus_phasepartials2waveshape. * 3-Jan-00: format and type args added to make_sample2file, * mus_file_close. * removed make_file_input and make_file_output. * -------- * 29-Dec: various bugfixes especially in envelope handlers. * 19-Nov: mus_oscil_bank and mus_formant_bank. * 5-Nov: mus_sin exported. * 4-Oct:(scm) make-env arg order changed to reflect mus.lisp. * 29-Sep: implemented mus-increment and mus-frequency for granulate(as in mus.lisp). * clm's fft renamed mus-fft to avoid collision with snd's version. * added max_size arg to make_granulate(to reflect mus.lisp). * 25-Sep-99: added width arg to make_src -- forgot this somehow in first pass. * decided to make mus_inspect return char* like mus_describe. */ snd-16.1/config.sub0000755000076400007640000010554612306421672012334 0ustar bilbil#! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # 2011, 2012, 2013 Free Software Foundation, Inc. timestamp='2013-01-11' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # Please send patches with a ChangeLog entry to config-patches@gnu.org. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ knetbsd*-gnu* | netbsd*-gnu* | \ kopensolaris*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; android-linux) os=-linux-android basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray | -microblaze*) os= basic_machine=$1 ;; -bluegene*) os=-cnk ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco6) os=-sco5v6 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*178) os=-lynxos178 ;; -lynx*5) os=-lynxos5 ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | aarch64 | aarch64_be \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc \ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ | avr | avr32 \ | be32 | be64 \ | bfin \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ | epiphany \ | fido | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | le32 | le64 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64octeon | mips64octeonel \ | mips64orion | mips64orionel \ | mips64r5900 | mips64r5900el \ | mips64vr | mips64vrel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipsr5900 | mipsr5900el \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nds32 | nds32le | nds32be \ | nios | nios2 \ | ns16k | ns32k \ | open8 \ | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pyramid \ | rl78 | rx \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | spu \ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | ubicom32 \ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | we32k \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown ;; c54x) basic_machine=tic54x-unknown ;; c55x) basic_machine=tic55x-unknown ;; c6x) basic_machine=tic6x-unknown ;; m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; ms1) basic_machine=mt-unknown ;; strongarm | thumb | xscale) basic_machine=arm-unknown ;; xgate) basic_machine=$basic_machine-unknown os=-none ;; xscaleeb) basic_machine=armeb-unknown ;; xscaleel) basic_machine=armel-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | aarch64-* | aarch64_be-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | hexagon-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | le32-* | le64-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ | microblaze-* | microblazeel-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64octeon-* | mips64octeonel-* \ | mips64orion-* | mips64orionel-* \ | mips64r5900-* | mips64r5900el-* \ | mips64vr-* | mips64vrel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipsr5900-* | mipsr5900el-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nds32-* | nds32le-* | nds32be-* \ | nios-* | nios2-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | open8-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pyramid-* \ | rl78-* | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tile*-* \ | tron-* \ | ubicom32-* \ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ | vax-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ | ymp-* \ | z8k-* | z80-*) ;; # Recognize the basic CPU types without company name, with glob match. xtensa*) basic_machine=$basic_machine-unknown ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aros) basic_machine=i386-pc os=-aros ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; blackfin) basic_machine=bfin-unknown os=-linux ;; blackfin-*) basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; bluegene*) basic_machine=powerpc-ibm os=-cnk ;; c54x-*) basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c55x-*) basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c6x-*) basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c90) basic_machine=c90-cray os=-unicos ;; cegcc) basic_machine=arm-unknown os=-cegcc ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16 | cr16-*) basic_machine=cr16-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dicos) basic_machine=i686-pc os=-dicos ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; microblaze*) basic_machine=microblaze-xilinx ;; mingw64) basic_machine=x86_64-pc os=-mingw64 ;; mingw32) basic_machine=i386-pc os=-mingw32 ;; mingw32ce) basic_machine=arm-unknown os=-mingw32ce ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; msys) basic_machine=i386-pc os=-msys ;; mvs) basic_machine=i370-ibm os=-mvs ;; nacl) basic_machine=le32-unknown os=-nacl ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; neo-tandem) basic_machine=neo-tandem ;; nse-tandem) basic_machine=nse-tandem ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; parisc) basic_machine=hppa-unknown os=-linux ;; parisc-*) basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pc98) basic_machine=i386-pc ;; pc98-*) basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc | ppcbe) basic_machine=powerpc-unknown ;; ppc-* | ppcbe-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rdos | rdos64) basic_machine=x86_64-pc os=-rdos ;; rdos32) basic_machine=i386-pc os=-rdos ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sde) basic_machine=mipsisa32-sde os=-elf ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh5el) basic_machine=sh5le-unknown ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; strongarm-* | thumb-*) basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tile*) basic_machine=$basic_machine-unknown os=-linux-gnu ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; xscale-* | xscalee[bl]-*) basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; z80-*-coff) basic_machine=z80-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -auroraux) os=-auroraux ;; -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ | -sym* | -kopensolaris* | -plan9* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -bitrig* | -openbsd* | -solidbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-musl* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; -nacl*) ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in score-*) os=-elf ;; spu-*) os=-elf ;; *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; hexagon-*) os=-elf ;; tic54x-*) os=-coff ;; tic55x-*) os=-coff ;; tic6x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 ;; m68*-cisco) os=-aout ;; mep-*) os=-elf ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-haiku) os=-haiku ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -cnk*|-aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: snd-16.1/libc.scm0000644000076400007640000026312712571434531011770 0ustar bilbil;;; libc.scm ;;; ;;; tie the C library into the *libc* environment (provide 'libc.scm) ;; if loading from a different directory, pass that info to C (let ((current-file (port-filename (current-input-port)))) (let ((directory (and (or (char=? (current-file 0) #\/) (char=? (current-file 0) #\~)) (substring current-file 0 (- (length current-file) 9))))) (when (and directory (not (member directory *load-path*))) (set! *load-path* (cons directory *load-path*))) (with-let (rootlet) (require cload.scm)) (when (and directory (not (string-position directory *cload-cflags*))) (set! *cload-cflags* (string-append "-I" directory " " *cload-cflags*))))) (if (not (defined? '*libc*)) (define *libc* (with-let (unlet) (set! *libraries* (cons (cons "libc.scm" (curlet)) *libraries*)) ;; -------- stddef.h -------- (define NULL (c-pointer 0)) (define (c-null? p) (equal? p NULL)) ;; -------- stdbool.h -------- (define false #f) (define true #t) ;; -------- iso646.h -------- ;; spelled-out names for & = bitand et al ;; -------- stdarg.h -------- ;; the varargs macros ;; -------- assert.h -------- ;; assert macro #| (define-expansion (assert assertion) (reader-cond ((not (defined? 'NDEBUG)) `(if (not ,assertion) (error 'assert-failure "~S[~D]: ~A failed~%" (port-filename) (port-line-number) ',assertion))) (#t (values)))) (define (hiho a) (assert (> a 2)) (+ a 1)) (define-expansion (comment . stuff) (reader-cond (#t (values)))) |# ;; -------- setjmp.h -------- ;; longjmp etc ;; -------- dlfn.h -------- ;; see libdl.scm, similarly for pthreads see libpthread.scm ;; -------- sys/types.h inttypes.h getopt.h-------- ;; C type declarations (c-define '(;; -------- limits.h -------- (C-macro (int (SCHAR_MIN SCHAR_MAX UCHAR_MAX CHAR_BIT CHAR_MIN CHAR_MAX __WORDSIZE SHRT_MIN SHRT_MAX USHRT_MAX INT_MIN INT_MAX UINT_MAX LONG_MIN LONG_MAX ULONG_MAX LLONG_MIN LLONG_MAX ULLONG_MAX _POSIX_AIO_LISTIO_MAX _POSIX_AIO_MAX _POSIX_ARG_MAX _POSIX_CHILD_MAX _POSIX_DELAYTIMER_MAX _POSIX_HOST_NAME_MAX _POSIX_LINK_MAX _POSIX_LOGIN_NAME_MAX _POSIX_MAX_CANON _POSIX_MAX_INPUT _POSIX_MQ_OPEN_MAX _POSIX_MQ_PRIO_MAX _POSIX_NAME_MAX _POSIX_NGROUPS_MAX _POSIX_OPEN_MAX _POSIX_FD_SETSIZE _POSIX_PATH_MAX _POSIX_PIPE_BUF _POSIX_RE_DUP_MAX _POSIX_RTSIG_MAX _POSIX_SEM_NSEMS_MAX _POSIX_SEM_VALUE_MAX _POSIX_SIGQUEUE_MAX _POSIX_SSIZE_MAX _POSIX_STREAM_MAX _POSIX_SYMLINK_MAX _POSIX_SYMLOOP_MAX _POSIX_TIMER_MAX _POSIX_TTY_NAME_MAX _POSIX_TZNAME_MAX _POSIX_QLIMIT _POSIX_HIWAT _POSIX_UIO_MAXIOV _POSIX_CLOCKRES_MIN SSIZE_MAX NGROUPS_MAX _POSIX2_BC_BASE_MAX _POSIX2_BC_DIM_MAX _POSIX2_BC_SCALE_MAX _POSIX2_BC_STRING_MAX _POSIX2_COLL_WEIGHTS_MAX _POSIX2_EXPR_NEST_MAX _POSIX2_LINE_MAX _POSIX2_RE_DUP_MAX _POSIX2_CHARCLASS_NAME_MAX BC_BASE_MAX BC_DIM_MAX BC_SCALE_MAX BC_STRING_MAX COLL_WEIGHTS_MAX EXPR_NEST_MAX LINE_MAX CHARCLASS_NAME_MAX RE_DUP_MAX))) ;; -------- float.h -------- (C-macro (int (FLT_RADIX FLT_MANT_DIG DBL_MANT_DIG LDBL_MANT_DIG FLT_DIG DBL_DIG LDBL_DIG FLT_MIN_EXP DBL_MIN_EXP LDBL_MIN_EXP FLT_MIN_10_EXP DBL_MIN_10_EXP LDBL_MIN_10_EXP FLT_MAX_EXP DBL_MAX_EXP LDBL_MAX_EXP FLT_MAX_10_EXP DBL_MAX_10_EXP LDBL_MAX_10_EXP FLT_ROUNDS FLT_EVAL_METHOD))) (C-macro (double (FLT_MAX DBL_MAX LDBL_MAX FLT_EPSILON DBL_EPSILON LDBL_EPSILON FLT_MIN DBL_MIN LDBL_MIN))) ;; -------- stdint.h -------- (C-macro (int (INT8_MIN INT16_MIN INT32_MIN INT64_MIN INT8_MAX INT16_MAX INT32_MAX INT64_MAX UINT8_MAX UINT16_MAX UINT32_MAX UINT64_MAX INT_LEAST8_MIN INT_LEAST16_MIN INT_LEAST32_MIN INT_LEAST64_MIN INT_LEAST8_MAX INT_LEAST16_MAX INT_LEAST32_MAX INT_LEAST64_MAX UINT_LEAST8_MAX UINT_LEAST16_MAX UINT_LEAST32_MAX UINT_LEAST64_MAX INT_FAST8_MIN INT_FAST16_MIN INT_FAST32_MIN INT_FAST64_MIN INT_FAST8_MAX INT_FAST16_MAX INT_FAST32_MAX INT_FAST64_MAX UINT_FAST8_MAX UINT_FAST16_MAX UINT_FAST32_MAX UINT_FAST64_MAX INTPTR_MIN INTPTR_MAX UINTPTR_MAX INTMAX_MIN INTMAX_MAX UINTMAX_MAX PTRDIFF_MIN PTRDIFF_MAX SIG_ATOMIC_MIN SIG_ATOMIC_MAX SIZE_MAX WCHAR_MIN WCHAR_MAX WINT_MIN WINT_MAX ))) (c-pointer (stdin stdout stderr)) ;; -------- endian.h -------- ;; also has htobe16 etc (C-macro (int (__BYTE_ORDER __BIG_ENDIAN __LITTLE_ENDIAN))) (in-C "static s7_pointer g_c_pointer_to_string(s7_scheme *sc, s7_pointer args) {return(s7_make_string_with_length(sc, (const char *)s7_c_pointer(s7_car(args)), s7_integer(s7_cadr(args))));} static s7_pointer g_string_to_c_pointer(s7_scheme *sc, s7_pointer args) { if (s7_is_string(s7_car(args))) return(s7_make_c_pointer(sc, (void *)s7_string(s7_car(args)))); return(s7_car(args)); }") (C-function ("c-pointer->string" g_c_pointer_to_string "" 2)) (C-function ("string->c-pointer" g_string_to_c_pointer "" 1)) ;; -------- ctype.h -------- (int isalnum (int)) (int isalpha (int)) (int iscntrl (int)) (int isdigit (int)) (int islower (int)) (int isgraph (int)) (int isprint (int)) (int ispunct (int)) (int isspace (int)) (int isupper (int)) (int isxdigit (int)) (int tolower (int)) (int toupper (int)) ;; -------- fcntl.h -------- (C-macro (int (S_IFMT S_IFDIR S_IFCHR S_IFBLK S_IFREG S_IFIFO __S_IFLNK S_IFSOCK S_ISUID S_ISGID S_IRUSR S_IWUSR S_IXUSR S_IRWXU S_IRGRP S_IWGRP S_IXGRP S_IRWXG S_IROTH S_IWOTH S_IXOTH S_IRWXO R_OK W_OK X_OK F_OK SEEK_SET SEEK_CUR SEEK_END F_ULOCK F_LOCK F_TLOCK F_TEST O_ACCMODE O_RDONLY O_WRONLY O_RDWR O_CREAT O_EXCL O_NOCTTY O_TRUNC O_APPEND O_NONBLOCK O_NDELAY O_SYNC O_FSYNC O_ASYNC O_DSYNC O_RSYNC O_LARGEFILE F_DUPFD F_GETFD F_SETFD F_GETFL F_SETFL F_GETLK F_SETLK F_SETLKW F_GETLK64 F_SETLK64 F_SETLKW64 FD_CLOEXEC F_RDLCK F_WRLCK F_UNLCK POSIX_FADV_NORMAL POSIX_FADV_RANDOM POSIX_FADV_SEQUENTIAL POSIX_FADV_WILLNEED POSIX_FADV_DONTNEED POSIX_FADV_NOREUSE))) (int fcntl (int int)) (in-C "static s7_pointer g_c_open(s7_scheme *sc, s7_pointer args) { s7_pointer arg; char* name; int flags, mode; arg = args; if (s7_is_string(s7_car(arg))) name = (char*)s7_string(s7_car(arg)); else return(s7_wrong_type_arg_error(sc, \"open\", 1, s7_car(arg), \"string\")); arg = s7_cdr(arg); if (s7_is_integer(s7_car(arg))) flags = (int)s7_integer(s7_car(arg)); else return(s7_wrong_type_arg_error(sc, \"open\", 2, s7_car(arg), \"integer\")); if (s7_is_pair(s7_cdr(arg))) { arg = s7_cdr(arg); if (s7_is_integer(s7_car(arg))) mode = (int)s7_integer(s7_car(arg)); else return(s7_wrong_type_arg_error(sc, \"open\", 3, s7_car(arg), \"integer\")); return(s7_make_integer(sc, (s7_int)open(name, flags, mode))); } return(s7_make_integer(sc, (s7_int)open(name, flags))); }") (C-function ("open" g_c_open "" 2 1)) (int creat (char* (mode_t int))) (int lockf (int int int)) (reader-cond ((provided? 'linux) (int posix_fadvise (int int int int)) (int posix_fallocate (int int int)))) ;; -------- fenv.h -------- (C-macro (int (FE_INEXACT FE_DIVBYZERO FE_UNDERFLOW FE_OVERFLOW FE_INVALID FE_ALL_EXCEPT FE_TONEAREST FE_UPWARD FE_DOWNWARD FE_TOWARDZERO))) (int feclearexcept (int)) (int fegetexceptflag (fexcept_t* int) ) (int feraiseexcept (int) ) (int fesetexceptflag (fexcept_t* int) ) (int fetestexcept (int) ) (int fegetround (void) ) (int fesetround (int) ) (int fegetenv (fenv_t*) ) (int feholdexcept (fenv_t*) ) (int fesetenv (fenv_t*) ) (int feupdateenv (fenv_t*) ) ;; -------- fnmatch.h -------- (C-macro (int (FNM_PATHNAME FNM_NOESCAPE FNM_PERIOD FNM_FILE_NAME FNM_LEADING_DIR FNM_CASEFOLD FNM_EXTMATCH FNM_NOMATCH))) (int fnmatch (char* char* int)) ;; -------- string.h -------- (void* memcpy (void* void* size_t)) (void* memmove (void* void* size_t)) (void* memset (void* int size_t)) (int memcmp (void* void* size_t)) (void* memchr (void* int size_t)) (char* strcpy (char* char*)) (char* strncpy (char* char* size_t)) (char* strcat (char* char*)) (char* strncat (char* char* size_t)) (int strcmp (char* char*)) (int strncmp (char* char* size_t)) (int strcoll (char* char*)) (size_t strxfrm (char* char* size_t)) (char* strchr (char* int)) (char* strrchr (char* int)) (size_t strcspn (char* char*)) (size_t strspn (char* char*)) (char* strpbrk (char* char*)) (char* strstr (char* char*)) (char* strtok (char* char*)) (size_t strlen (char*)) (reader-cond ((not (provided? 'osx)) (size_t strnlen (char* size_t)))) ;; strnlen is in OSX 10.8, not 10.6 (char* strerror (int)) (int strcasecmp (char* char*)) (int strncasecmp (char* char* size_t)) ;; -------- stdio.h -------- (C-macro (int (_IOFBF _IOLBF _IONBF BUFSIZ EOF L_tmpnam TMP_MAX FILENAME_MAX L_ctermid L_cuserid FOPEN_MAX IOV_MAX))) (C-macro (char* P_tmpdir)) (int remove (char*)) (int rename (char* char*)) (FILE* tmpfile (void)) (reader-cond ((not (provided? 'osx)) (char* tmpnam (char*)) (char* tempnam (char* char*)))) (int fclose (FILE*)) (int fflush (FILE*)) ;; (reader-cond ((provided? 'linux) (int fcloseall (void)))) (FILE* fopen (char* char*)) (FILE* freopen (char* char* FILE*)) (FILE* fdopen (int char*)) (void setbuf (FILE* char*)) (int setvbuf (FILE* char* int size_t)) (void setlinebuf (FILE*)) (int fgetc (FILE*)) (int getc (FILE*)) (int getchar (void)) (int fputc (int FILE*)) (int putc (int FILE*)) (int putchar (int)) (char* fgets (char* int FILE*)) (int fputs (char* FILE*)) (int puts (char*)) (int ungetc (int FILE*)) (size_t fread (void* size_t size_t FILE*)) (size_t fwrite (void* size_t size_t FILE*)) (int fseek (FILE* int int)) (int ftell (FILE*)) (void rewind (FILE*)) (int fgetpos (FILE* fpos_t*)) (int fsetpos (FILE* fpos_t*)) (void clearerr (FILE*)) (int feof (FILE*)) (int ferror (FILE*)) (void perror (char*)) (int fileno (FILE*)) (FILE* popen (char* char*)) (int pclose (FILE*)) (char* ctermid (char*)) ;; (reader-cond ((provided? 'linux) (char* cuserid (char*)))) (void flockfile (FILE*)) (int ftrylockfile (FILE*)) (void funlockfile (FILE*)) ;; int fprintf (FILE* char* ...) ;; int printf (char* ...) ;; int sprintf (char* char* ...) ;; int vfprintf (FILE* char* va_list) ;; int vprintf (char* va_list) ;; int vsprintf (char* char* va_list) ;; int snprintf (char* size_t char* ...) ;; int vsnprintf (char* size_t char* va_list) ;; int vasprintf (char** char* va_list) ;; int asprintf (char** char* ...) ;; int fscanf (FILE* char* ...) ;; int scanf (char* ...) ;; int sscanf (char* char* ...) ;; int vfscanf (FILE* char* va_list) ;; int vscanf (char* va_list) ;; int vsscanf (char* char* va_list) ;; -------- stdlib.h -------- (C-macro (int (RAND_MAX EXIT_FAILURE EXIT_SUCCESS MB_CUR_MAX))) (double atof (char*)) (int atoi (char*)) (int atol (char*)) (int atoll (char*)) (int random (void)) (void srandom (int)) (char* initstate (int char* size_t)) (char* setstate (char*)) (int rand (void)) (void srand (int)) (void* malloc (size_t)) (void* calloc (size_t size_t)) (void* realloc (void* size_t)) (void free (void*)) (void abort (void)) (void exit (int)) (char* getenv (char*)) (int putenv (char*)) (int setenv (char* char* int)) (int unsetenv (char*)) (char* mktemp (char*)) (int mkstemp (char*)) (int system (char*)) (char* realpath (char* char*)) (int abs (int)) (int labs (int)) (in-C "static s7_pointer g_llabs(s7_scheme *sc, s7_pointer args) { #if ((__GNUC__) && ((__GNUC__ < 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ < 4)))) return(s7_make_integer(sc, labs(s7_integer(s7_car(args))))); #else return(s7_make_integer(sc, llabs(s7_integer(s7_car(args))))); #endif } static s7_pointer g_strtod(s7_scheme *sc, s7_pointer args) {return(s7_make_real(sc, strtod(s7_string(s7_car(args)), NULL)));} static s7_pointer g_strtof(s7_scheme *sc, s7_pointer args) {return(s7_make_real(sc, strtof(s7_string(s7_car(args)), NULL)));} static s7_pointer g_strtol(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, strtol(s7_string(s7_car(args)), NULL, s7_integer(s7_cadr(args)))));} static s7_pointer g_strtoll(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, strtoll(s7_string(s7_car(args)), NULL, s7_integer(s7_cadr(args)))));} static s7_pointer g_div(s7_scheme *sc, s7_pointer args) { div_t d; d = div(s7_integer(s7_car(args)), s7_integer(s7_cadr(args))); return(s7_list(sc, 2, s7_make_integer(sc, d.quot), s7_make_integer(sc, d.rem))); } static s7_pointer g_ldiv(s7_scheme *sc, s7_pointer args) { ldiv_t d; d = ldiv(s7_integer(s7_car(args)), s7_integer(s7_cadr(args))); return(s7_list(sc, 2, s7_make_integer(sc, d.quot), s7_make_integer(sc, d.rem))); } ") (C-function ("llabs" g_llabs "" 1)) (C-function ("strtod" g_strtod "" 1)) (C-function ("strtof" g_strtof "" 1)) (C-function ("strtol" g_strtol "" 2)) (C-function ("strtoll" g_strtoll "" 2)) (C-function ("div" g_div "" 1)) (C-function ("ldiv" g_ldiv "" 1)) ;; -------- errno.h -------- ;; pws for errno? (C-macro (int (__GLIBC__ __GLIBC_MINOR__ ; features.h from errno.h ECANCELED EOWNERDEAD ENOTRECOVERABLE ERFKILL EILSEQ ;; asm-generic/errno-base.h EPERM ENOENT ESRCH EINTR EIO ENXIO E2BIG ENOEXEC EBADF ECHILD EAGAIN ENOMEM EACCES EFAULT ENOTBLK EBUSY EEXIST EXDEV ENODEV ENOTDIR EISDIR EINVAL ENFILE EMFILE ENOTTY ETXTBSY EFBIG ENOSPC ESPIPE EROFS EMLINK EPIPE EDOM ERANGE ))) (in-C "static s7_pointer g_errno(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, errno));} static s7_pointer g_set_errno(s7_scheme *sc, s7_pointer args) {errno = (int)s7_integer(s7_car(args)); return(s7_car(args));}") (C-function ("errno" g_errno "" 0)) (C-function ("set_errno" g_set_errno "" 1)) ;; -------- locale.h -------- (C-macro (int (LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES LC_ALL LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT LC_IDENTIFICATION))) (char* setlocale (int char*)) (in-C " static s7_pointer g_localeconv(s7_scheme *sc, s7_pointer args) { struct lconv *lc; lc = localeconv(); return(s7_inlet(sc, s7_list(sc, 36, s7_make_symbol(sc, \"decimal_point\"), s7_make_string(sc, lc->decimal_point), s7_make_symbol(sc, \"thousands_sep\"), s7_make_string(sc, lc->thousands_sep), s7_make_symbol(sc, \"grouping\"), s7_make_string(sc, lc->grouping), s7_make_symbol(sc, \"int_curr_symbol\"), s7_make_string(sc, lc->int_curr_symbol), s7_make_symbol(sc, \"currency_symbol\"), s7_make_string(sc, lc->currency_symbol), s7_make_symbol(sc, \"mon_decimal_point\"), s7_make_string(sc, lc->mon_decimal_point), s7_make_symbol(sc, \"mon_thousands_sep\"), s7_make_string(sc, lc->mon_thousands_sep), s7_make_symbol(sc, \"mon_grouping\"), s7_make_string(sc, lc->mon_grouping), s7_make_symbol(sc, \"positive_sign\"), s7_make_string(sc, lc->positive_sign), s7_make_symbol(sc, \"negative_sign\"), s7_make_string(sc, lc->negative_sign), s7_make_symbol(sc, \"int_frac_digits\"), s7_make_integer(sc, lc->int_frac_digits), s7_make_symbol(sc, \"frac_digits\"), s7_make_integer(sc, lc->frac_digits), s7_make_symbol(sc, \"p_cs_precedes\"), s7_make_integer(sc, lc->p_cs_precedes), s7_make_symbol(sc, \"p_sep_by_space\"), s7_make_integer(sc, lc->p_sep_by_space), s7_make_symbol(sc, \"n_cs_precedes\"), s7_make_integer(sc, lc->n_cs_precedes), s7_make_symbol(sc, \"n_sep_by_space\"), s7_make_integer(sc, lc->n_sep_by_space), s7_make_symbol(sc, \"p_sign_posn\"), s7_make_integer(sc, lc->p_sign_posn), s7_make_symbol(sc, \"n_sign_posn\"), s7_make_integer(sc, lc->n_sign_posn)))); }") (C-function ("localeconv" g_localeconv "" 0)) ;; -------- sys/utsname.h -------- (in-C " static s7_pointer g_uname(s7_scheme *sc, s7_pointer args) { struct utsname buf; uname(&buf); return(s7_list(sc, 5, s7_make_string(sc, buf.sysname), s7_make_string(sc, buf.machine), s7_make_string(sc, buf.nodename), s7_make_string(sc, buf.version), s7_make_string(sc, buf.release))); }") (C-function ("uname" g_uname "" 0)) ;; -------- unistd.h -------- (C-macro (int (_POSIX_VERSION _POSIX2_VERSION _POSIX_JOB_CONTROL _POSIX_SAVED_IDS _POSIX_PRIORITY_SCHEDULING _POSIX_SYNCHRONIZED_IO _POSIX_FSYNC _POSIX_MAPPED_FILES _POSIX_MEMLOCK _POSIX_MEMLOCK_RANGE _POSIX_MEMORY_PROTECTION _POSIX_CHOWN_RESTRICTED _POSIX_VDISABLE _POSIX_NO_TRUNC _POSIX_THREADS _POSIX_REENTRANT_FUNCTIONS _POSIX_THREAD_SAFE_FUNCTIONS _POSIX_THREAD_PRIORITY_SCHEDULING _POSIX_THREAD_ATTR_STACKSIZE _POSIX_THREAD_ATTR_STACKADDR _POSIX_THREAD_PRIO_INHERIT _POSIX_THREAD_PRIO_PROTECT _POSIX_SEMAPHORES _POSIX_REALTIME_SIGNALS _POSIX_ASYNCHRONOUS_IO _POSIX_ASYNC_IO _POSIX_PRIORITIZED_IO _POSIX_SHARED_MEMORY_OBJECTS _POSIX_CPUTIME _POSIX_THREAD_CPUTIME _POSIX_REGEXP _POSIX_READER_WRITER_LOCKS _POSIX_SHELL _POSIX_TIMEOUTS _POSIX_SPIN_LOCKS _POSIX_SPAWN _POSIX_TIMERS _POSIX_BARRIERS _POSIX_MESSAGE_PASSING _POSIX_THREAD_PROCESS_SHARED _POSIX_MONOTONIC_CLOCK _POSIX_CLOCK_SELECTION _POSIX_ADVISORY_INFO _POSIX_IPV6 _POSIX_RAW_SOCKETS _POSIX2_CHAR_TERM _POSIX_SPORADIC_SERVER _POSIX_THREAD_SPORADIC_SERVER _POSIX_TRACE _POSIX_TRACE_EVENT_FILTER _POSIX_TRACE_INHERIT _POSIX_TRACE_LOG _POSIX_TYPED_MEMORY_OBJECTS STDIN_FILENO STDOUT_FILENO STDERR_FILENO))) (C-macro (int (_PC_LINK_MAX _PC_MAX_CANON _PC_MAX_INPUT _PC_NAME_MAX _PC_PATH_MAX _PC_PIPE_BUF _PC_CHOWN_RESTRICTED _PC_NO_TRUNC _PC_VDISABLE _PC_SYNC_IO _PC_ASYNC_IO _PC_PRIO_IO _PC_SOCK_MAXBUF _PC_FILESIZEBITS _PC_REC_INCR_XFER_SIZE _PC_REC_MAX_XFER_SIZE _PC_REC_MIN_XFER_SIZE _PC_REC_XFER_ALIGN _PC_ALLOC_SIZE_MIN _PC_SYMLINK_MAX _PC_2_SYMLINKS _SC_ARG_MAX _SC_CHILD_MAX _SC_CLK_TCK _SC_NGROUPS_MAX _SC_OPEN_MAX _SC_STREAM_MAX _SC_TZNAME_MAX _SC_JOB_CONTROL _SC_SAVED_IDS _SC_REALTIME_SIGNALS _SC_PRIORITY_SCHEDULING _SC_TIMERS _SC_ASYNCHRONOUS_IO _SC_PRIORITIZED_IO _SC_SYNCHRONIZED_IO _SC_FSYNC _SC_MAPPED_FILES _SC_MEMLOCK _SC_MEMLOCK_RANGE _SC_MEMORY_PROTECTION _SC_MESSAGE_PASSING _SC_SEMAPHORES _SC_SHARED_MEMORY_OBJECTS _SC_AIO_LISTIO_MAX _SC_AIO_MAX _SC_AIO_PRIO_DELTA_MAX _SC_DELAYTIMER_MAX _SC_MQ_OPEN_MAX _SC_MQ_PRIO_MAX _SC_VERSION _SC_PAGESIZE _SC_PAGE_SIZE _SC_RTSIG_MAX _SC_SEM_NSEMS_MAX _SC_SEM_VALUE_MAX _SC_SIGQUEUE_MAX _SC_TIMER_MAX _SC_BC_BASE_MAX _SC_BC_DIM_MAX _SC_BC_SCALE_MAX _SC_BC_STRING_MAX _SC_COLL_WEIGHTS_MAX _SC_EQUIV_CLASS_MAX _SC_EXPR_NEST_MAX _SC_LINE_MAX _SC_RE_DUP_MAX _SC_CHARCLASS_NAME_MAX _SC_2_VERSION _SC_2_C_BIND _SC_2_C_DEV _SC_2_FORT_DEV _SC_2_FORT_RUN _SC_2_SW_DEV _SC_2_LOCALEDEF _SC_PII _SC_PII_XTI _SC_PII_SOCKET _SC_PII_INTERNET _SC_PII_OSI _SC_POLL _SC_SELECT _SC_UIO_MAXIOV _SC_IOV_MAX _SC_PII_INTERNET_STREAM _SC_PII_INTERNET_DGRAM _SC_PII_OSI_COTS _SC_PII_OSI_CLTS _SC_PII_OSI_M _SC_T_IOV_MAX _SC_THREADS _SC_THREAD_SAFE_FUNCTIONS _SC_GETGR_R_SIZE_MAX _SC_GETPW_R_SIZE_MAX _SC_LOGIN_NAME_MAX _SC_TTY_NAME_MAX _SC_THREAD_DESTRUCTOR_ITERATIONS _SC_THREAD_KEYS_MAX _SC_THREAD_STACK_MIN _SC_THREAD_THREADS_MAX _SC_THREAD_ATTR_STACKADDR _SC_THREAD_ATTR_STACKSIZE _SC_THREAD_PRIO_INHERIT _SC_THREAD_PRIO_PROTECT _SC_THREAD_PROCESS_SHARED _SC_NPROCESSORS_CONF _SC_NPROCESSORS_ONLN _SC_PHYS_PAGES _SC_AVPHYS_PAGES _SC_ATEXIT_MAX _SC_PASS_MAX _SC_2_CHAR_TERM _SC_2_C_VERSION _SC_2_UPE _SC_CHAR_BIT _SC_CHAR_MAX _SC_CHAR_MIN _SC_INT_MAX _SC_INT_MIN _SC_LONG_BIT _SC_WORD_BIT _SC_MB_LEN_MAX _SC_NZERO _SC_SSIZE_MAX _SC_SCHAR_MAX _SC_SCHAR_MIN _SC_SHRT_MAX _SC_SHRT_MIN _SC_UCHAR_MAX _SC_UINT_MAX _SC_ULONG_MAX _SC_USHRT_MAX _SC_NL_ARGMAX _SC_NL_LANGMAX _SC_NL_MSGMAX _SC_NL_NMAX _SC_NL_SETMAX _SC_NL_TEXTMAX _SC_ADVISORY_INFO _SC_BARRIERS _SC_BASE _SC_C_LANG_SUPPORT _SC_C_LANG_SUPPORT_R _SC_CLOCK_SELECTION _SC_CPUTIME _SC_THREAD_CPUTIME _SC_DEVICE_IO _SC_DEVICE_SPECIFIC _SC_DEVICE_SPECIFIC_R _SC_FD_MGMT _SC_FIFO _SC_PIPE _SC_FILE_ATTRIBUTES _SC_FILE_LOCKING _SC_FILE_SYSTEM _SC_MONOTONIC_CLOCK _SC_MULTI_PROCESS _SC_SINGLE_PROCESS _SC_NETWORKING _SC_READER_WRITER_LOCKS _SC_SPIN_LOCKS _SC_REGEXP _SC_REGEX_VERSION _SC_SHELL _SC_SIGNALS _SC_SPAWN _SC_SPORADIC_SERVER _SC_THREAD_SPORADIC_SERVER _SC_SYSTEM_DATABASE _SC_SYSTEM_DATABASE_R _SC_TIMEOUTS _SC_TYPED_MEMORY_OBJECTS _SC_USER_GROUPS _SC_USER_GROUPS_R _SC_2_PBS _SC_2_PBS_ACCOUNTING _SC_2_PBS_LOCATE _SC_2_PBS_MESSAGE _SC_2_PBS_TRACK _SC_SYMLOOP_MAX _SC_STREAMS _SC_2_PBS_CHECKPOINT _SC_HOST_NAME_MAX _SC_TRACE _SC_TRACE_EVENT_FILTER _SC_TRACE_INHERIT _SC_TRACE_LOG _SC_LEVEL1_ICACHE_SIZE _SC_LEVEL1_ICACHE_ASSOC _SC_LEVEL1_ICACHE_LINESIZE _SC_LEVEL1_DCACHE_SIZE _SC_LEVEL1_DCACHE_ASSOC _SC_LEVEL1_DCACHE_LINESIZE _SC_LEVEL2_CACHE_SIZE _SC_LEVEL2_CACHE_LINESIZE _SC_LEVEL3_CACHE_SIZE _SC_LEVEL3_CACHE_ASSOC _SC_LEVEL3_CACHE_LINESIZE _SC_LEVEL4_CACHE_SIZE _SC_LEVEL4_CACHE_LINESIZE _SC_IPV6 _SC_RAW_SOCKETS _SC_SS_REPL_MAX _SC_TRACE_EVENT_NAME_MAX _SC_TRACE_NAME_MAX _SC_TRACE_SYS_MAX _SC_TRACE_USER_EVENT_MAX _SC_THREAD_ROBUST_PRIO_INHERIT _SC_THREAD_ROBUST_PRIO_PROTECT _CS_PATH _CS_GNU_LIBC_VERSION _SC_THREAD_PRIORITY_SCHEDULING _SC_LEVEL2_CACHE_ASSOC _SC_LEVEL4_CACHE_ASSOC _CS_GNU_LIBPTHREAD_VERSION))) (int access (char* int)) (int lseek (int int int)) (int close (int)) (ssize_t read (int void* size_t)) (ssize_t write (int void* size_t)) (ssize_t pread (int void* size_t int)) (ssize_t pwrite (int void* size_t int)) (int pipe (int*)) (int alarm (int)) (int sleep (int)) (int pause (void)) (int chown (char* int int)) (int chdir (char*)) (char* getcwd (char* size_t)) ;; (deprecated) (char* getwd (char*)) (int dup (int)) (int dup2 (int int)) (void _exit (int)) (int pathconf (char* int)) (int fpathconf (int int)) (int sysconf (int)) (size_t confstr (int char* size_t)) (int getpid (void)) (int getppid (void)) (int getpgid (int)) (int setpgid (int int)) (int setsid (void)) (int getsid (int)) (int getuid (void)) (int geteuid (void)) (int getgid (void)) (int getegid (void)) (int setuid (int)) (int setgid (int)) (int fork (void)) (char* ttyname (int)) (int isatty (int)) (int link (char* char*)) (int unlink (char*)) (int rmdir (char*)) (int tcgetpgrp (int)) (int tcsetpgrp (int int)) (char* getlogin (void)) (int truncate (char* int)) (int ftruncate (int int)) (in-C "extern char **environ; static s7_pointer getenvs(s7_scheme *sc, s7_pointer args) { s7_pointer p; int i; p = s7_nil(sc); for (i = 0; environ[i]; i++) { const char *eq; s7_pointer name, value; eq = strchr((const char *)environ[i], (int)'='); name = s7_make_string_with_length(sc, environ[i], eq - environ[i]); value = s7_make_string(sc, (char *)(eq + 1)); p = s7_cons(sc, s7_cons(sc, name, value), p); } return(p); } static s7_pointer g_getgroups(s7_scheme *sc, s7_pointer args) { gid_t *gds; int i, size, res; s7_pointer lst; size = s7_integer(s7_car(args)); if (size == 0) return(s7_make_integer(sc, getgroups(0, NULL))); gds = (gid_t *)calloc(size, sizeof(gid_t)); res = getgroups(size, gds); if (res != -1) { lst = s7_nil(sc); for (i = 0; i < size; i++) lst = s7_cons(sc, s7_make_integer(sc, gds[i]), lst); } else lst = s7_make_integer(sc, -1); free(gds); return(lst); } ") (C-function ("getenvs" getenvs "(getenvs) returns all the environment variables in an alist" 0)) (C-function ("getgroups" g_getgroups "" 1)) ;; perhaps call these as (define* n (path ...) = args? and use execve for all? ;; but are these useful in this context? How is fork used here? ;; int execve (char* path char* argv[] char* envp[]) ;; int execv (char* path char* argv[]) ;; int execle (char* path char* arg ...) ;; int execl (char* path char* arg ...) ;; int execvp (char* file char* argv[]) ;; int execlp (char* file char* arg ...) ;; -------- dirent.h -------- (DIR* opendir (char*)) (int closedir (DIR*)) (void rewinddir (DIR*)) (in-C "static char *read_dir(DIR *p) { struct dirent *dirp; dirp = readdir(p); if (!dirp) return(NULL); else return(dirp->d_name); }") (char* read_dir (DIR*)) ;; int scandir (char* dirent*** func func) ;; int alphasort (dirent** dirent**) ;; -------- ftw.h -------- (C-macro (int (FTW_F FTW_D FTW_DNR FTW_NS))) (in-C "static s7_scheme *internal_ftw_sc = NULL; static s7_pointer internal_ftw_closure = NULL, internal_ftw_arglist = NULL; static int internal_ftw_function(const char *fpath, const struct stat *sb, int typeflag) { s7_list_set(internal_ftw_sc, internal_ftw_arglist, 0, s7_make_string(internal_ftw_sc, fpath)); s7_list_set(internal_ftw_sc, internal_ftw_arglist, 1, s7_make_c_pointer(internal_ftw_sc, (void *)sb)); s7_list_set(internal_ftw_sc, internal_ftw_arglist, 2, s7_make_integer(internal_ftw_sc, typeflag)); return((int)s7_integer(s7_call(internal_ftw_sc, internal_ftw_closure, internal_ftw_arglist))); } static s7_pointer g_ftw(s7_scheme *sc, s7_pointer args) { if (!internal_ftw_sc) { internal_ftw_sc = sc; internal_ftw_arglist = s7_list(sc, 3, s7_nil(sc), s7_nil(sc), s7_nil(sc)); s7_gc_protect(sc, internal_ftw_arglist); } internal_ftw_closure = s7_cadr(args); return(s7_make_integer(sc, ftw(s7_string(s7_car(args)), internal_ftw_function, s7_integer(s7_caddr(args))))); }") (C-function ("ftw" g_ftw "" 3)) ;; -------- sys/stat.h -------- (C-macro (int S_IFLNK)) (in-C "static s7_pointer g_stat(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, stat(s7_string(s7_car(args)), (struct stat *)s7_c_pointer(s7_cadr(args)))));} static s7_pointer g_fstat(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, fstat(s7_integer(s7_car(args)), (struct stat *)s7_c_pointer(s7_cadr(args)))));} static s7_pointer g_lstat(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, lstat(s7_string(s7_car(args)), (struct stat *)s7_c_pointer(s7_cadr(args)))));} ") (C-function ("stat" g_stat "" 2)) (C-function ("fstat" g_fstat "" 2)) (C-function ("lstat" g_lstat "" 2)) (int chmod (char* int)) (int mkdir (char* int)) (int mknod (char* int int)) (int mkfifo (char* int)) (in-C "static s7_pointer g_isdir(s7_scheme *sc, s7_pointer args) {return(s7_make_boolean(sc, S_ISDIR(s7_integer(s7_car(args)))));} static s7_pointer g_ischr(s7_scheme *sc, s7_pointer args) {return(s7_make_boolean(sc, S_ISCHR(s7_integer(s7_car(args)))));} static s7_pointer g_isblk(s7_scheme *sc, s7_pointer args) {return(s7_make_boolean(sc, S_ISBLK(s7_integer(s7_car(args)))));} static s7_pointer g_isreg(s7_scheme *sc, s7_pointer args) {return(s7_make_boolean(sc, S_ISREG(s7_integer(s7_car(args)))));} static s7_pointer g_isfifo(s7_scheme *sc, s7_pointer args) {return(s7_make_boolean(sc, S_ISFIFO(s7_integer(s7_car(args)))));} static s7_pointer g_islnk(s7_scheme *sc, s7_pointer args) {return(s7_make_boolean(sc, S_ISLNK(s7_integer(s7_car(args)))));} static s7_pointer g_issock(s7_scheme *sc, s7_pointer args) {return(s7_make_boolean(sc, S_ISSOCK(s7_integer(s7_car(args)))));} static s7_pointer g_st_dev(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, ((struct stat *)s7_c_pointer(s7_car(args)))->st_dev));} static s7_pointer g_st_ino(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, ((struct stat *)s7_c_pointer(s7_car(args)))->st_ino));} static s7_pointer g_st_mode(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, ((struct stat *)s7_c_pointer(s7_car(args)))->st_mode));} static s7_pointer g_st_nlink(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, ((struct stat *)s7_c_pointer(s7_car(args)))->st_nlink));} static s7_pointer g_st_uid(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, ((struct stat *)s7_c_pointer(s7_car(args)))->st_uid));} static s7_pointer g_st_gid(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, ((struct stat *)s7_c_pointer(s7_car(args)))->st_gid));} static s7_pointer g_st_rdev(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, ((struct stat *)s7_c_pointer(s7_car(args)))->st_rdev));} static s7_pointer g_st_size(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, ((struct stat *)s7_c_pointer(s7_car(args)))->st_size));} static s7_pointer g_st_blksize(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, ((struct stat *)s7_c_pointer(s7_car(args)))->st_blksize));} static s7_pointer g_st_blocks(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, ((struct stat *)s7_c_pointer(s7_car(args)))->st_blocks));} static s7_pointer g_st_atime(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, ((struct stat *)s7_c_pointer(s7_car(args)))->st_atime));} static s7_pointer g_st_mtime(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, ((struct stat *)s7_c_pointer(s7_car(args)))->st_mtime));} static s7_pointer g_st_ctime(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, ((struct stat *)s7_c_pointer(s7_car(args)))->st_ctime));} static s7_pointer g_stat_make(s7_scheme *sc, s7_pointer args) {return(s7_make_c_pointer(sc, (void *)calloc(1, sizeof(struct stat))));} ") (C-function ("S_ISDIR" g_isdir "" 1)) (C-function ("S_ISCHR" g_ischr "" 1)) (C-function ("S_ISBLK" g_isblk "" 1)) (C-function ("S_ISREG" g_isreg "" 1)) (C-function ("S_ISFIFO" g_isfifo "" 1)) (C-function ("S_ISLNK" g_islnk "" 1)) (C-function ("S_ISSOCK" g_issock "" 1)) (C-function ("stat.st_dev" g_st_dev "" 1)) (C-function ("stat.st_ino" g_st_ino "" 1)) (C-function ("stat.st_mode" g_st_mode "" 1)) (C-function ("stat.st_nlink" g_st_nlink "" 1)) (C-function ("stat.st_uid" g_st_uid "" 1)) (C-function ("stat.st_gid" g_st_gid "" 1)) (C-function ("stat.st_rdev" g_st_rdev "" 1)) (C-function ("stat.st_size" g_st_size "" 1)) (C-function ("stat.st_blksize" g_st_blksize "" 1)) (C-function ("stat.st_blocks" g_st_blocks "" 1)) (C-function ("stat.st_atime" g_st_atime "" 1)) (C-function ("stat.st_mtime" g_st_mtime "" 1)) (C-function ("stat.st_ctime" g_st_ctime "" 1)) (C-function ("stat.make" g_stat_make "" 0)) ;; -------- time.h sys/time.h -------- (C-macro (int (CLOCKS_PER_SEC CLOCK_REALTIME CLOCK_MONOTONIC CLOCK_PROCESS_CPUTIME_ID CLOCK_THREAD_CPUTIME_ID CLOCK_MONOTONIC_RAW CLOCK_REALTIME_COARSE CLOCK_MONOTONIC_COARSE))) (int clock (void)) (int time (time_t*)) (double difftime ((time_t integer) (time_t integer))) (tm* gmtime (time_t*)) (char* ctime (time_t*)) (tm* localtime (time_t*)) (in-C "static s7_pointer g_mktime(s7_scheme *sc, s7_pointer args) { return(s7_make_integer(sc, (s7_int)mktime((struct tm *)s7_c_pointer(s7_car(args))))); } static s7_pointer g_time_make(s7_scheme *sc, s7_pointer args) { time_t *tm; tm = (time_t *)calloc(1, sizeof(time_t)); (*tm) = (time_t)s7_integer(s7_car(args)); return(s7_make_c_pointer(sc, (void *)tm)); } static s7_pointer g_strftime(s7_scheme *sc, s7_pointer args) { return(s7_make_integer(sc, (s7_int)strftime((char *)s7_string(s7_car(args)), (size_t)s7_integer(s7_cadr(args)), s7_string(s7_caddr(args)), (const struct tm *)s7_c_pointer(s7_cadddr(args))))); } static s7_pointer g_asctime(s7_scheme *sc, s7_pointer args) { return(s7_make_string(sc, asctime((const struct tm *)s7_c_pointer(s7_car(args))))); } static s7_pointer g_gettimeofday(s7_scheme *sc, s7_pointer args) { struct timeval t0; gettimeofday(&t0, NULL); return(s7_list(sc, 2, s7_make_integer(sc, t0.tv_sec), s7_make_integer(sc, t0.tv_usec))); } static s7_pointer g_nanosleep(s7_scheme *sc, s7_pointer args) { struct timespec t0; t0.tv_sec = (time_t)s7_integer(s7_car(args)); t0.tv_nsec = (long)s7_integer(s7_cadr(args)); return(s7_make_integer(sc, nanosleep(&t0, NULL))); } static s7_pointer g_clock_getres(s7_scheme *sc, s7_pointer args) { #if (!__APPLE__) struct timespec t0; int res; res = clock_getres(s7_integer(s7_car(args)), &t0); return(s7_list(sc, 3, s7_make_integer(sc, res), s7_make_integer(sc, t0.tv_sec), s7_make_integer(sc, t0.tv_nsec))); #else return(s7_make_integer(sc, -1)); #endif } static s7_pointer g_clock_gettime(s7_scheme *sc, s7_pointer args) { #if (!__APPLE__) struct timespec t0; int res; res = clock_gettime(s7_integer(s7_car(args)), &t0); return(s7_list(sc, 3, s7_make_integer(sc, res), s7_make_integer(sc, t0.tv_sec), s7_make_integer(sc, t0.tv_nsec))); #else return(s7_make_integer(sc, -1)); #endif } static s7_pointer g_clock_settime(s7_scheme *sc, s7_pointer args) { #if (!__APPLE__) struct timespec t0; t0.tv_sec = (time_t)s7_integer(s7_cadr(args)); t0.tv_nsec = (long)s7_integer(s7_caddr(args)); return(s7_make_integer(sc, clock_settime(s7_integer(s7_car(args)), &t0))); #else return(s7_make_integer(sc, -1)); #endif } static s7_pointer g_clock_getcpuclockid(s7_scheme *sc, s7_pointer args) { #if __linux__ clockid_t c = 0; clock_getcpuclockid((pid_t)s7_integer(s7_car(args)), &c); return(s7_make_integer(sc, (s7_int)c)); #else return(s7_make_integer(sc, -1)); #endif } static s7_pointer g_clock_nanosleep(s7_scheme *sc, s7_pointer args) { #if __linux__ struct timespec t0; t0.tv_sec = (time_t)s7_integer(s7_caddr(args)); t0.tv_nsec = (long)s7_integer(s7_cadddr(args)); return(s7_make_integer(sc, clock_nanosleep((clockid_t)s7_integer(s7_car(args)), (int)s7_integer(s7_cadr(args)), &t0, NULL))); #else return(s7_make_integer(sc, -1)); #endif } ") (C-function ("time.make" g_time_make "" 1)) (C-function ("mktime" g_mktime "" 1)) (C-function ("asctime" g_asctime "" 1)) (C-function ("strftime" g_strftime "" 4)) (C-function ("gettimeofday" g_gettimeofday "" 0)) (C-function ("nanosleep" g_nanosleep "" 2)) (C-function ("clock_getres" g_clock_getres "" 1)) (C-function ("clock_gettime" g_clock_gettime "" 1)) ; these need -lrt (C-function ("clock_settime" g_clock_settime "" 3)) (reader-cond ((not (provided? 'solaris)) (C-function ("clock_getcpuclockid" g_clock_getcpuclockid "" 1)))) (C-function ("clock_nanosleep" g_clock_nanosleep "" 4)) ;; -------- utime.h -------- (in-C "static s7_pointer g_utime(s7_scheme *sc, s7_pointer args) { struct utimbuf tb; tb.actime = (time_t)s7_integer(s7_cadr(args)); tb.modtime = (time_t)s7_integer(s7_caddr(args)); return(s7_make_integer(sc, utime(s7_string(s7_car(args)), &tb))); }") (C-function ("utime" g_utime "" 3)) ;; -------- termios.h -------- (C-macro (int (VINTR VQUIT VERASE VKILL VEOF VTIME VMIN VSWTC VSTART VSTOP VSUSP VEOL VREPRINT VDISCARD VWERASE VLNEXT VEOL2 IGNBRK BRKINT IGNPAR PARMRK INPCK ISTRIP INLCR IGNCR ICRNL IUCLC IXON IXANY IXOFF IMAXBEL IUTF8 OPOST OLCUC ONLCR OCRNL ONOCR ONLRET OFILL OFDEL ISIG ICANON ECHO ECHOE ECHOK ECHONL NOFLSH TOSTOP IEXTEN TCOOFF TCOON TCIOFF TCION TCIFLUSH TCOFLUSH TCIOFLUSH TCSANOW TCSADRAIN TCSAFLUSH))) (int tcsendbreak (int int)) (int tcdrain (int)) (int tcflush (int int)) (int tcflow (int int)) (in-C "static s7_pointer g_cfgetospeed(s7_scheme *sc, s7_pointer args) { struct termios *p; p = (struct termios *)s7_c_pointer(s7_car(args)); return(s7_make_integer(sc, (s7_int)cfgetospeed(p))); } static s7_pointer g_cfgetispeed(s7_scheme *sc, s7_pointer args) { struct termios *p; p = (struct termios *)s7_c_pointer(s7_car(args)); return(s7_make_integer(sc, (s7_int)cfgetispeed(p))); } static s7_pointer g_cfsetospeed(s7_scheme *sc, s7_pointer args) { struct termios *p; p = (struct termios *)s7_c_pointer(s7_car(args)); return(s7_make_integer(sc, cfsetospeed(p, (speed_t)s7_integer(s7_cadr(args))))); } static s7_pointer g_cfsetispeed(s7_scheme *sc, s7_pointer args) { struct termios *p; p = (struct termios *)s7_c_pointer(s7_car(args)); return(s7_make_integer(sc, cfsetispeed(p, (speed_t)s7_integer(s7_cadr(args))))); } static s7_pointer g_tcgetattr(s7_scheme *sc, s7_pointer args) { struct termios *p; p = (struct termios *)s7_c_pointer(s7_cadr(args)); return(s7_make_integer(sc, tcgetattr(s7_integer(s7_car(args)), p))); } static s7_pointer g_tcsetattr(s7_scheme *sc, s7_pointer args) { struct termios *p; p = (struct termios *)s7_c_pointer(s7_caddr(args)); return(s7_make_integer(sc, tcsetattr(s7_integer(s7_car(args)), s7_integer(s7_cadr(args)), p))); } static s7_pointer g_termios_make(s7_scheme *sc, s7_pointer args) {return(s7_make_c_pointer(sc, (void *)calloc(1, sizeof(struct termios))));} static s7_pointer g_termios_c_lflag(s7_scheme *sc, s7_pointer args) { struct termios *p; p = (struct termios *)s7_c_pointer(s7_car(args)); return(s7_make_integer(sc, (s7_int)(p->c_lflag))); } static s7_pointer g_termios_set_c_lflag(s7_scheme *sc, s7_pointer args) { struct termios *p; p = (struct termios *)s7_c_pointer(s7_car(args)); p->c_lflag = (tcflag_t)s7_integer(s7_cadr(args)); return(s7_cadr(args)); } static s7_pointer g_termios_set_c_cc(s7_scheme *sc, s7_pointer args) { struct termios *p; p = (struct termios *)s7_c_pointer(s7_car(args)); p->c_cc[(int)s7_integer(s7_cadr(args))] = (cc_t)s7_integer(s7_caddr(args)); return(s7_caddr(args)); } ") ;; tcflag_t c_iflag, c_oflag, c_cflag; cc_t c_line; ;; cc_t c_cc[NCCS]; (C-function ("cfgetospeed" g_cfgetospeed "" 1)) (C-function ("cfgetispeed" g_cfgetispeed "" 1)) (C-function ("cfsetospeed" g_cfsetospeed "" 2)) (C-function ("cfsetispeed" g_cfsetispeed "" 2)) (C-function ("tcgetattr" g_tcgetattr "" 2)) (C-function ("tcsetattr" g_tcsetattr "" 3)) (C-function ("termios.make" g_termios_make "" 0)) (C-function ("termios.c_lflag" g_termios_c_lflag "" 1)) (C-function ("termios.set_c_lflag" g_termios_set_c_lflag "" 2)) (C-function ("termios.set_c_cc" g_termios_set_c_cc "" 3)) ;; -------- grp.h -------- (void* getgrgid (int)) (void* getgrnam (char*)) (in-C "static s7_pointer g_group_gr_name(s7_scheme *sc, s7_pointer args) {return(s7_make_string(sc, ((struct group *)s7_c_pointer(s7_car(args)))->gr_name));} static s7_pointer g_group_gr_passwd(s7_scheme *sc, s7_pointer args) {return(s7_make_string(sc, ((struct group *)s7_c_pointer(s7_car(args)))->gr_passwd));} static s7_pointer g_group_gr_gid(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, (s7_int)(((struct group *)s7_c_pointer(s7_car(args)))->gr_gid)));} static s7_pointer g_group_gr_mem(s7_scheme *sc, s7_pointer args) { s7_pointer p; int i; struct group *g; g = (struct group *)s7_c_pointer(s7_car(args)); p = s7_nil(sc); for (i = 0; g->gr_mem[i]; i++) p = s7_cons(sc, s7_make_string(sc, g->gr_mem[i]), p); return(p); } ") (C-function ("group.gr_name" g_group_gr_name "" 1)) (C-function ("group.gr_passwd" g_group_gr_passwd "" 1)) (C-function ("group.gr_gid" g_group_gr_gid "" 1)) (C-function ("group.gr_mem" g_group_gr_mem "" 1)) ;; ((*libc* 'group.gr_name) ((*libc* 'getgrnam) "wheel")) -> "wheel" ;; -------- pwd.h -------- (C-macro (int NSS_BUFLEN_PASSWD)) (void setpwent (void)) (void endpwent (void)) (void* getpwent (void)) (void* getpwuid (int)) (void* getpwnam (char*)) (in-C "static s7_pointer g_passwd_pw_name(s7_scheme *sc, s7_pointer args) {return(s7_make_string(sc, ((struct passwd *)s7_c_pointer(s7_car(args)))->pw_name));} static s7_pointer g_passwd_pw_passwd(s7_scheme *sc, s7_pointer args) {return(s7_make_string(sc, ((struct passwd *)s7_c_pointer(s7_car(args)))->pw_passwd));} static s7_pointer g_passwd_pw_uid(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, ((struct passwd *)s7_c_pointer(s7_car(args)))->pw_uid));} static s7_pointer g_passwd_pw_gid(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, ((struct passwd *)s7_c_pointer(s7_car(args)))->pw_gid));} static s7_pointer g_passwd_pw_gecos(s7_scheme *sc, s7_pointer args) {return(s7_make_string(sc, ((struct passwd *)s7_c_pointer(s7_car(args)))->pw_gecos));} static s7_pointer g_passwd_pw_dir(s7_scheme *sc, s7_pointer args) {return(s7_make_string(sc, ((struct passwd *)s7_c_pointer(s7_car(args)))->pw_dir));} static s7_pointer g_passwd_pw_shell(s7_scheme *sc, s7_pointer args) {return(s7_make_string(sc, ((struct passwd *)s7_c_pointer(s7_car(args)))->pw_shell));} ") (C-function ("passwd.pw_name" g_passwd_pw_name "" 1)) (C-function ("passwd.pw_passwd" g_passwd_pw_passwd "" 1)) (C-function ("passwd.pw_uid" g_passwd_pw_uid "" 1)) (C-function ("passwd.pw_gid" g_passwd_pw_gid "" 1)) (C-function ("passwd.pw_gecos" g_passwd_pw_gecos "" 1)) (C-function ("passwd.pw_dir" g_passwd_pw_dir "" 1)) (C-function ("passwd.pw_shell" g_passwd_pw_shell "" 1)) ;; ((*libc* 'passwd.pw_name) ((*libc* 'getpwnam) "bil")) -> "bil" ;; -------- wordexp.h -------- (reader-cond ((not (provided? 'openbsd)) (int (WRDE_DOOFFS WRDE_APPEND WRDE_NOCMD WRDE_REUSE WRDE_SHOWERR WRDE_UNDEF WRDE_NOSPACE WRDE_BADCHAR WRDE_BADVAL WRDE_CMDSUB WRDE_SYNTAX)) (int wordexp (char* wordexp_t* int)) (void wordfree (wordexp_t*)) (in-C "static s7_pointer g_wordexp_make(s7_scheme *sc, s7_pointer args) {return(s7_make_c_pointer(sc, (void *)calloc(1, sizeof(wordexp_t))));} static s7_pointer g_wordexp_we_wordc(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, ((wordexp_t *)s7_c_pointer(s7_car(args)))->we_wordc));} static s7_pointer g_wordexp_we_wordv(s7_scheme *sc, s7_pointer args) { s7_pointer p; int i; wordexp_t *g; g = (wordexp_t *)s7_c_pointer(s7_car(args)); p = s7_nil(sc); for (i = 0; i < g->we_wordc; i++) p = s7_cons(sc, s7_make_string(sc, g->we_wordv[i]), p); return(p); }") (C-function ("wordexp.make" g_wordexp_make "" 0)) (C-function ("wordexp.we_wordc" g_wordexp_we_wordc "" 1)) (C-function ("wordexp.we_wordv" g_wordexp_we_wordv "" 1)))) ;; (with-let (sublet *libc*) (let ((w (wordexp.make))) (wordexp "~/cl/snd-gdraw" w 0) (wordexp.we_wordv w))) -> ("/home/bil/cl/snd-gdraw") ;; -------- glob.h -------- ;; does any of this work in openbsd? (C-macro (int (GLOB_ERR GLOB_MARK GLOB_NOSORT GLOB_DOOFFS GLOB_NOCHECK GLOB_APPEND GLOB_NOESCAPE GLOB_PERIOD GLOB_MAGCHAR GLOB_ALTDIRFUNC GLOB_BRACE GLOB_NOMAGIC GLOB_TILDE GLOB_ONLYDIR GLOB_TILDE_CHECK GLOB_NOSPACE GLOB_ABORTED GLOB_NOMATCH GLOB_NOSYS))) (void globfree (glob_t*)) (in-C "static s7_pointer g_glob_make(s7_scheme *sc, s7_pointer args) {return(s7_make_c_pointer(sc, (void *)calloc(1, sizeof(glob_t))));} static s7_pointer g_glob_gl_pathc(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, ((glob_t *)s7_c_pointer(s7_car(args)))->gl_pathc));} static s7_pointer g_glob(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, glob(s7_string(s7_car(args)), s7_integer(s7_cadr(args)), NULL, (glob_t *)s7_c_pointer(s7_caddr(args)))));} static s7_pointer g_glob_gl_pathv(s7_scheme *sc, s7_pointer args) { s7_pointer p; int i; glob_t *g; g = (glob_t *)s7_c_pointer(s7_car(args)); p = s7_nil(sc); for (i = 0; i < g->gl_pathc; i++) p = s7_cons(sc, s7_make_string(sc, g->gl_pathv[i]), p); return(p); }") (C-function ("glob.make" g_glob_make "" 0)) (C-function ("glob.gl_pathc" g_glob_gl_pathc "" 1)) (C-function ("glob.gl_pathv" g_glob_gl_pathv "" 1)) (C-function ("glob" g_glob "" 3)) ;; -------- signal.h sys/wait.h -------- (C-macro (int (SIGHUP SIGINT SIGQUIT SIGILL SIGTRAP SIGABRT SIGIOT SIGBUS SIGFPE SIGKILL SIGUSR1 SIGSEGV SIGUSR2 SIGPIPE SIGALRM SIGTERM SIGSTKFLT SIGCLD SIGCHLD SIGCONT SIGSTOP SIGTSTP SIGTTIN SIGTTOU SIGURG SIGXCPU SIGXFSZ SIGVTALRM SIGPROF SIGWINCH SIGPOLL SIGIO SIGPWR SIGSYS (reader-cond ((not (provided? 'osx)) SIGUNUSED)) WNOHANG WUNTRACED WSTOPPED WEXITED WCONTINUED WNOWAIT RLIMIT_CPU RLIMIT_FSIZE RLIMIT_DATA RLIMIT_STACK RLIMIT_CORE RLIMIT_RSS RLIMIT_NOFILE RLIMIT_OFILE RLIMIT_AS RLIMIT_NPROC RLIMIT_MEMLOCK RLIMIT_LOCKS RLIMIT_SIGPENDING RLIMIT_MSGQUEUE RLIMIT_NICE RLIMIT_RTPRIO RLIMIT_NLIMITS RLIM_NLIMITS RLIM_INFINITY RLIM_SAVED_MAX RLIM_SAVED_CUR RUSAGE_SELF RUSAGE_CHILDREN RUSAGE_THREAD RUSAGE_LWP PRIO_MIN PRIO_MAX PRIO_PROCESS PRIO_PGRP PRIO_USER SA_NOCLDSTOP SA_NOCLDWAIT SA_SIGINFO SA_ONSTACK SA_RESTART SA_NODEFER SA_RESETHAND SA_NOMASK SA_ONESHOT SA_STACK SIG_BLOCK SIG_UNBLOCK SIG_SETMASK ))) ;; (let ((v (rusage.make))) (getrusage (*libc* 'RUSAGE_SELF) v) (let ((mem (rusage.ru_maxrss v))) (free v) mem)) (int kill (int int)) (int raise (int)) (int sigemptyset (sigset_t*)) (int sigfillset (sigset_t*)) (int sigaddset (sigset_t* int)) (int sigdelset (sigset_t* int)) (int sigismember (sigset_t* int)) (int sigprocmask (int sigset_t* sigset_t*)) (int sigsuspend (sigset_t*)) (int sigpending (sigset_t*)) (int getpriority (int int)) (int setpriority (int int int)) (in-C "static s7_pointer g_rlimit_make(s7_scheme *sc, s7_pointer args) {return(s7_make_c_pointer(sc, (void *)calloc(1, sizeof(struct rlimit))));} static s7_pointer g_rlimit_rlim_cur(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, ((struct rlimit *)s7_c_pointer(s7_car(args)))->rlim_cur));} static s7_pointer g_rlimit_rlim_max(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, ((struct rlimit *)s7_c_pointer(s7_car(args)))->rlim_max));} static s7_pointer g_rusage_make(s7_scheme *sc, s7_pointer args) {return(s7_make_c_pointer(sc, (void *)calloc(1, sizeof(struct rusage))));} static s7_pointer g_rusage_ru_maxrss(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, ((struct rusage *)s7_c_pointer(s7_car(args)))->ru_maxrss));} static s7_pointer g_rusage_ru_minflt(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, ((struct rusage *)s7_c_pointer(s7_car(args)))->ru_minflt));} static s7_pointer g_rusage_ru_majflt(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, ((struct rusage *)s7_c_pointer(s7_car(args)))->ru_majflt));} static s7_pointer g_rusage_ru_inblock(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, ((struct rusage *)s7_c_pointer(s7_car(args)))->ru_inblock));} static s7_pointer g_rusage_ru_oublock(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, ((struct rusage *)s7_c_pointer(s7_car(args)))->ru_oublock));} static s7_pointer g_rusage_ru_nvcsw(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, ((struct rusage *)s7_c_pointer(s7_car(args)))->ru_nvcsw));} static s7_pointer g_rusage_ru_nivcsw(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, ((struct rusage *)s7_c_pointer(s7_car(args)))->ru_nivcsw));} static s7_pointer g_rusage_ru_utime(s7_scheme *sc, s7_pointer args) {return(s7_make_c_pointer(sc, &(((struct rusage *)s7_c_pointer(s7_car(args)))->ru_utime)));} static s7_pointer g_rusage_ru_stime(s7_scheme *sc, s7_pointer args) {return(s7_make_c_pointer(sc, &(((struct rusage *)s7_c_pointer(s7_car(args)))->ru_stime)));} static s7_pointer g_sigset_make(s7_scheme *sc, s7_pointer args) {return(s7_make_c_pointer(sc, (void *)calloc(1, sizeof(sigset_t))));} #if __linux__ static s7_pointer g_WEXITSTATUS(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, WEXITSTATUS(s7_integer(s7_car(args)))));} static s7_pointer g_WTERMSIG(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, WTERMSIG(s7_integer(s7_car(args)))));} static s7_pointer g_WSTOPSIG(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, WSTOPSIG(s7_integer(s7_car(args)))));} static s7_pointer g_WIFEXITED(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, WIFEXITED(s7_integer(s7_car(args)))));} static s7_pointer g_WIFSIGNALED(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, WIFSIGNALED(s7_integer(s7_car(args)))));} static s7_pointer g_WIFSTOPPED(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, WIFSTOPPED(s7_integer(s7_car(args)))));} #endif static s7_pointer g_wait(s7_scheme *sc, s7_pointer args) { int status, result; result = wait(&status); return(s7_list(sc, 2, s7_make_integer(sc, result), s7_make_integer(sc, status))); } static s7_pointer g_waitpid(s7_scheme *sc, s7_pointer args) { int status, result; result = waitpid((pid_t)s7_integer(s7_car(args)), &status, s7_integer(s7_cadr(args))); return(s7_list(sc, 2, s7_make_integer(sc, result), s7_make_integer(sc, status))); } static s7_pointer g_sigqueue(s7_scheme *sc, s7_pointer args) { #if (__linux__) union sigval val; if (s7_is_integer(s7_caddr(args))) val.sival_int = (int)s7_integer(s7_caddr(args)); else val.sival_ptr = (void *)s7_c_pointer(s7_caddr(args)); return(s7_make_integer(sc, sigqueue((pid_t)s7_integer(s7_car(args)), s7_integer(s7_cadr(args)), val))); #else return(s7_f(sc)); #endif } static s7_pointer g_sigwait(s7_scheme *sc, s7_pointer args) { #if (!__sun) int status, result; result = sigwait((const sigset_t *)s7_c_pointer(s7_car(args)), &status); return(s7_list(sc, 2, s7_make_integer(sc, result), s7_make_integer(sc, status))); #else return(s7_f(sc)); #endif } static s7_pointer g_sigtimedwait(s7_scheme *sc, s7_pointer args) { #if (__linux__) return(s7_make_integer(sc, sigtimedwait((const sigset_t *)s7_c_pointer(s7_car(args)), (siginfo_t *)s7_c_pointer(s7_cadr(args)), (const struct timespec *)s7_c_pointer(s7_caddr(args))))); #else return(s7_f(sc)); #endif } #if __linux__ static s7_pointer g_siginfo_make(s7_scheme *sc, s7_pointer args) {return(s7_make_c_pointer(sc, (void *)calloc(1, sizeof(siginfo_t))));} static s7_pointer g_siginfo_si_signo(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, ((siginfo_t *)s7_c_pointer(s7_car(args)))->si_signo));} static s7_pointer g_siginfo_si_errno(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, ((siginfo_t *)s7_c_pointer(s7_car(args)))->si_errno));} static s7_pointer g_siginfo_si_code(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, ((siginfo_t *)s7_c_pointer(s7_car(args)))->si_code));} static s7_pointer g_siginfo_si_pid(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, ((siginfo_t *)s7_c_pointer(s7_car(args)))->si_pid));} static s7_pointer g_siginfo_si_uid(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, ((siginfo_t *)s7_c_pointer(s7_car(args)))->si_uid));} static s7_pointer g_siginfo_si_status(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, ((siginfo_t *)s7_c_pointer(s7_car(args)))->si_status));} static s7_pointer g_siginfo_si_utime(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, ((siginfo_t *)s7_c_pointer(s7_car(args)))->si_utime));} static s7_pointer g_siginfo_si_stime(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, ((siginfo_t *)s7_c_pointer(s7_car(args)))->si_stime));} static s7_pointer g_siginfo_si_value(s7_scheme *sc, s7_pointer args) {return(s7_make_c_pointer(sc, &(((siginfo_t *)s7_c_pointer(s7_car(args)))->si_value)));} static s7_pointer g_siginfo_si_int(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, ((siginfo_t *)s7_c_pointer(s7_car(args)))->si_int));} static s7_pointer g_siginfo_si_overrun(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, ((siginfo_t *)s7_c_pointer(s7_car(args)))->si_overrun));} static s7_pointer g_siginfo_si_timerid(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, ((siginfo_t *)s7_c_pointer(s7_car(args)))->si_timerid));} static s7_pointer g_siginfo_si_band(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, ((siginfo_t *)s7_c_pointer(s7_car(args)))->si_band));} static s7_pointer g_siginfo_si_fd(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, ((siginfo_t *)s7_c_pointer(s7_car(args)))->si_fd));} static s7_pointer g_siginfo_si_ptr(s7_scheme *sc, s7_pointer args) {return(s7_make_c_pointer(sc, ((siginfo_t *)s7_c_pointer(s7_car(args)))->si_ptr));} static s7_pointer g_siginfo_si_addr(s7_scheme *sc, s7_pointer args) {return(s7_make_c_pointer(sc, ((siginfo_t *)s7_c_pointer(s7_car(args)))->si_addr));} #endif static s7_pointer g_timespec_make(s7_scheme *sc, s7_pointer args) {return(s7_make_c_pointer(sc, (void *)calloc(1, sizeof(struct timespec))));} static s7_pointer g_timespec_tv_sec(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, ((struct timespec *)s7_c_pointer(s7_car(args)))->tv_sec));} static s7_pointer g_timespec_tv_nsec(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, ((struct timespec *)s7_c_pointer(s7_car(args)))->tv_nsec));} static s7_pointer g_sigaction_make(s7_scheme *sc, s7_pointer args) {return(s7_make_c_pointer(sc, (void *)calloc(1, sizeof(sigaction))));} static s7_pointer g_sigaction_sa_flags(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, ((struct sigaction *)s7_c_pointer(s7_car(args)))->sa_flags));} static s7_pointer g_sigaction_set_sa_flags(s7_scheme *sc, s7_pointer args) {((struct sigaction *)s7_c_pointer(s7_car(args)))->sa_flags = s7_integer(s7_cadr(args)); return(s7_cadr(args));} static s7_pointer g_sigaction_sa_mask(s7_scheme *sc, s7_pointer args) {return(s7_make_c_pointer(sc, (void *)(&(((struct sigaction *)s7_c_pointer(s7_car(args)))->sa_mask))));} static s7_pointer g_sigaction_sa_handler(s7_scheme *sc, s7_pointer args) {return(s7_make_c_pointer(sc, (void *)(((struct sigaction *)s7_c_pointer(s7_car(args)))->sa_handler)));} static s7_pointer sighandlers = NULL; static s7_scheme *sighandlers_s7 = NULL; static void s7_signal_handler(int sig) { if (sighandlers) { s7_pointer handler; handler = s7_vector_ref(sighandlers_s7, sighandlers, sig); if (handler != s7_f(sighandlers_s7)) s7_call(sighandlers_s7, handler, s7_cons(sighandlers_s7, s7_make_integer(sighandlers_s7, sig), s7_nil(sighandlers_s7))); } } #ifndef SIGUNUSED #define SIGUNUSED 65 #endif static s7_pointer g_sigaction_set_sa_handler(s7_scheme *sc, s7_pointer args) { /* (sigaction.set_sa_handler ptr handler) */ if (!sighandlers) { sighandlers_s7 = sc; sighandlers = s7_make_and_fill_vector(sc, SIGUNUSED + 1, s7_f(sc)); s7_gc_protect(sc, sighandlers); } if (s7_c_pointer(s7_cadr(args)) == (void *)SIG_DFL) ((struct sigaction *)s7_c_pointer(s7_car(args)))->sa_handler = SIG_DFL; else { if (s7_c_pointer(s7_cadr(args)) == (void *)SIG_IGN) ((struct sigaction *)s7_c_pointer(s7_car(args)))->sa_handler = SIG_IGN; else { ((struct sigaction *)s7_c_pointer(s7_car(args)))->sa_handler = s7_signal_handler; s7_vector_set(sighandlers_s7, sighandlers, SIGUNUSED, s7_cons(sc, s7_cons(sc, s7_car(args), s7_cadr(args)), s7_vector_ref(sighandlers_s7, sighandlers, SIGUNUSED))); } } return(s7_cadr(args)); } static s7_pointer g_sigaction(s7_scheme *sc, s7_pointer args) { int sig; const struct sigaction *new_act; struct sigaction *old_act; s7_pointer handler; sig = (int)s7_integer(s7_car(args)); new_act = (const struct sigaction *)s7_c_pointer(s7_cadr(args)); old_act = (struct sigaction *)s7_c_pointer(s7_caddr(args)); handler = s7_assq(sc, s7_cadr(args), s7_vector_ref(sighandlers_s7, sighandlers, SIGUNUSED)); if (s7_is_pair(handler)) s7_vector_set(sighandlers_s7, sighandlers, sig, s7_cdr(handler)); return(s7_make_integer(sc, sigaction(sig, new_act, old_act))); } static s7_pointer g_signal(s7_scheme *sc, s7_pointer args) { int sig; if (!sighandlers) { sighandlers_s7 = sc; sighandlers = s7_make_and_fill_vector(sc, SIGUNUSED + 1, s7_f(sc)); s7_gc_protect(sc, sighandlers); } sig = s7_integer(s7_car(args)); if (s7_is_c_pointer(s7_cadr(args))) { if (s7_c_pointer(s7_cadr(args)) == (void *)SIG_DFL) return(s7_make_c_pointer(sc, signal(sig, SIG_DFL))); if (s7_c_pointer(s7_cadr(args)) == (void *)SIG_IGN) return(s7_make_c_pointer(sc, signal(sig, SIG_IGN))); } s7_vector_set(sc, sighandlers, sig, s7_cadr(args)); return(s7_make_c_pointer(sc, signal(sig, s7_signal_handler))); } ") (C-function ("rlimit.make" g_rlimit_make "" 0)) (C-function ("rlimit.rlim_cur" g_rlimit_rlim_cur "" 1)) (C-function ("rlimit.rlim_max" g_rlimit_rlim_max "" 1)) (C-function ("rusage.make" g_rusage_make "" 0)) (C-function ("rusage.ru_maxrss" g_rusage_ru_maxrss "" 1)) (C-function ("rusage.ru_minflt" g_rusage_ru_minflt "" 1)) (C-function ("rusage.ru_majflt" g_rusage_ru_majflt "" 1)) (C-function ("rusage.ru_inblock" g_rusage_ru_inblock "" 1)) (C-function ("rusage.ru_oublock" g_rusage_ru_oublock "" 1)) (C-function ("rusage.ru_nvcsw" g_rusage_ru_nvcsw "" 1)) (C-function ("rusage.ru_nivcsw" g_rusage_ru_nivcsw "" 1)) (C-function ("rusage.ru_utime" g_rusage_ru_utime "" 1)) (C-function ("rusage.ru_stime" g_rusage_ru_stime "" 1)) (reader-cond ((provided? 'linux) (C-function ("siginfo.make" g_siginfo_make "" 0)) (C-function ("siginfo.si_signo" g_siginfo_si_signo "" 1)) (C-function ("siginfo.si_errno" g_siginfo_si_errno "" 1)) (C-function ("siginfo.si_code" g_siginfo_si_code "" 1)) (C-function ("siginfo.si_pid" g_siginfo_si_pid "" 1)) (C-function ("siginfo.si_uid" g_siginfo_si_uid "" 1)) (C-function ("siginfo.si_status" g_siginfo_si_status "" 1)) (C-function ("siginfo.si_utime" g_siginfo_si_utime "" 1)) (C-function ("siginfo.si_stime" g_siginfo_si_stime "" 1)) (C-function ("siginfo.si_value" g_siginfo_si_value "" 1)) (C-function ("siginfo.si_int" g_siginfo_si_int "" 1)) (C-function ("siginfo.si_overrun" g_siginfo_si_overrun "" 1)) (C-function ("siginfo.si_timerid" g_siginfo_si_timerid "" 1)) (C-function ("siginfo.si_band" g_siginfo_si_band "" 1)) (C-function ("siginfo.si_fd" g_siginfo_si_fd "" 1)) (C-function ("siginfo.si_ptr" g_siginfo_si_ptr "" 1)) (C-function ("siginfo.si_addr" g_siginfo_si_addr "" 1)))) (C-function ("timespec.make" g_timespec_make "" 0)) (C-function ("timespec.tv_sec" g_timespec_tv_sec "" 1)) (C-function ("timespec.tv_nsec" g_timespec_tv_nsec "" 1)) (C-function ("sigaction.make" g_sigaction_make "" 0)) (C-function ("sigaction.sa_handler" g_sigaction_sa_handler "" 1)) (C-function ("sigaction.sa_flags" g_sigaction_sa_flags "" 1)) (C-function ("sigaction.sa_mask" g_sigaction_sa_mask "" 1)) (C-function ("sigaction.set_sa_handler" g_sigaction_set_sa_handler "" 2)) (C-function ("sigaction.set_sa_flags" g_sigaction_set_sa_flags "" 2)) ;; (define sa ((*libc* 'sigaction.make))) ;; ((*libc* 'sigemptyset) ((*libc* 'sigaction.sa_mask) sa)) ;; ((*libc* 'sigaction.set_sa_flags) sa 0) ;; ((*libc* 'sigaction.set_sa_handler) sa (lambda (i) (format *stderr* "i: ~A~%" i))) ;; ((*libc* 'sigaction) (*libc* 'SIGINT) sa (*libc* 'NULL)) ;; now type C-C to snd and it prints "i: 2"!! (reader-cond ((provided? 'linux) (C-function ("WEXITSTATUS" g_WEXITSTATUS "" 1)) (C-function ("WTERMSIG" g_WTERMSIG "" 1)) (C-function ("WSTOPSIG" g_WSTOPSIG "" 1)) (C-function ("WIFEXITED" g_WIFEXITED "" 1)) (C-function ("WIFSIGNALED" g_WIFSIGNALED "" 1)) (C-function ("WIFSTOPPED" g_WIFSTOPPED "" 1)))) (C-function ("wait" g_wait "" 0)) (C-function ("waitpid" g_waitpid "" 2)) (C-function ("sigqueue" g_sigqueue "" 3)) (reader-cond ((not (provided? 'solaris)) (C-function ("sigwait" g_sigwait "" 1)))) (C-function ("sigaction" g_sigaction "" 3)) (C-function ("sigtimedwait" g_sigtimedwait "" 3)) (C-function ("sigset.make" g_sigset_make "" 0)) (C-function ("signal" g_signal "" 2)) (int getrlimit (int void*)) (int setrlimit (int void*)) (int getrusage (int void*)) (reader-cond ((provided? 'linux) (int sigwaitinfo (sigset_t* siginfo_t*)) (int waitid (int int siginfo_t* int)))) (c-pointer (SIG_ERR SIG_DFL SIG_IGN)) ;; -------- netdb.h -------- (reader-cond ((provided? 'linux) (int (IPPORT_ECHO IPPORT_DISCARD IPPORT_SYSTAT IPPORT_DAYTIME IPPORT_NETSTAT IPPORT_FTP IPPORT_TELNET IPPORT_SMTP IPPORT_TIMESERVER IPPORT_NAMESERVER IPPORT_WHOIS IPPORT_MTP IPPORT_TFTP IPPORT_RJE IPPORT_FINGER IPPORT_TTYLINK IPPORT_SUPDUP IPPORT_EXECSERVER IPPORT_LOGINSERVER IPPORT_CMDSERVER IPPORT_EFSSERVER IPPORT_BIFFUDP IPPORT_WHOSERVER IPPORT_ROUTESERVER IPPORT_RESERVED IPPORT_USERRESERVED)))) (C-macro (int (AI_PASSIVE AI_CANONNAME AI_NUMERICHOST AI_V4MAPPED AI_ALL AI_ADDRCONFIG AI_NUMERICSERV EAI_BADFLAGS EAI_NONAME EAI_AGAIN EAI_FAIL EAI_FAMILY EAI_SOCKTYPE EAI_SERVICE EAI_MEMORY EAI_SYSTEM EAI_OVERFLOW NI_NUMERICHOST NI_NUMERICSERV NI_NOFQDN NI_NAMEREQD NI_DGRAM SOCK_STREAM SOCK_DGRAM SOCK_RAW SOCK_RDM SOCK_SEQPACKET SOCK_DCCP SOCK_PACKET SOCK_CLOEXEC SOCK_NONBLOCK _PATH_HEQUIV_PATH_HOSTS _PATH_NETWORKS _PATH_NSSWITCH_CONF _PATH_PROTOCOLS _PATH_SERVICES PF_UNSPEC PF_LOCAL PF_UNIX PF_FILE PF_INET PF_AX25 PF_IPX PF_APPLETALK PF_NETROM PF_BRIDGE PF_ATMPVC PF_X25 PF_INET6 PF_ROSE PF_DECnet PF_NETBEUI PF_SECURITY PF_KEY PF_NETLINK PF_ROUTE PF_PACKET PF_ASH PF_ECONET PF_ATMSVC PF_RDS PF_SNA PF_IRDA PF_PPPOX PF_WANPIPE PF_LLC PF_CAN PF_TIPC PF_BLUETOOTH PF_IUCV PF_RXRPC PF_ISDN PF_PHONET PF_IEEE802154 PF_MAX AF_UNSPEC AF_LOCAL AF_UNIX AF_FILE AF_INET AF_AX25 AF_IPX AF_APPLETALK AF_NETROM AF_BRIDGE AF_ATMPVC AF_X25 AF_INET6 AF_ROSE AF_DECnet AF_NETBEUI AF_SECURITY AF_KEY AF_NETLINK AF_ROUTE AF_PACKET AF_ASH AF_ECONET AF_ATMSVC AF_RDS AF_SNA AF_IRDA AF_PPPOX AF_WANPIPE AF_LLC AF_CAN AF_TIPC AF_BLUETOOTH AF_IUCV AF_RXRPC AF_ISDN AF_PHONET AF_IEEE802154 AF_MAX MSG_OOB MSG_PEEK MSG_DONTROUTE MSG_CTRUNC MSG_PROXY MSG_TRUNC MSG_DONTWAIT MSG_EOR MSG_WAITFORONE MSG_WAITALL MSG_FIN MSG_SYN MSG_CONFIRM MSG_RST MSG_ERRQUEUE MSG_NOSIGNAL MSG_MORE MSG_CMSG_CLOEXEC IPPROTO_IP IPPROTO_HOPOPTS IPPROTO_ICMP IPPROTO_IGMP IPPROTO_IPIP IPPROTO_TCP IPPROTO_EGP IPPROTO_PUP IPPROTO_UDP IPPROTO_IDP IPPROTO_TP IPPROTO_DCCP IPPROTO_IPV6 IPPROTO_ROUTING IPPROTO_FRAGMENT IPPROTO_RSVP IPPROTO_GRE IPPROTO_ESP IPPROTO_AH IPPROTO_ICMPV6 IPPROTO_NONE IPPROTO_DSTOPTS IPPROTO_MTP IPPROTO_ENCAP IPPROTO_PIM IPPROTO_COMP IPPROTO_SCTP IPPROTO_UDPLITE IPPROTO_RAW SOL_RAW SOL_DECNET SOL_X25 SOL_PACKET SOL_ATM SOL_AAL SOL_IRDA SHUT_RD SHUT_WR SHUT_RDWR))) (void sethostent (int)) (void endhostent (void)) (void* gethostent (void)) (void setservent (int)) (void endservent (void)) (void* getservent (void)) (void setprotoent (int)) (void endprotoent (void)) (void* getprotoent (void)) (void setnetent (int)) (void endnetent (void)) (void* getnetent (void)) (int socket (int int int)) (int listen (int int)) (int shutdown (int int)) (void* gethostbyname (char*)) (void* gethostbyaddr (void* int int)) (void* getnetbyname (char*)) (void* getnetbyaddr (int int)) (void* getservbyname (char* char*)) (void* getservbyport (int char*)) (void* getprotobyname (char*)) (void* getprotobynumber (int)) (void freeaddrinfo (void*)) (char* gai_strerror (int)) (int bind (int void* int)) (int connect (int void* int)) (int send (int void* int int)) (int recv (int void* int int)) (int sendto (int void* int int void* int)) (int sendmsg (int void* int)) (int recvmsg (int void* int)) (in-C "static s7_pointer g_ntohl(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, ntohl(s7_integer(s7_car(args)))));} static s7_pointer g_ntohs(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, ntohs(s7_integer(s7_car(args)))));} static s7_pointer g_htonl(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, htonl(s7_integer(s7_car(args)))));} static s7_pointer g_htons(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, htons(s7_integer(s7_car(args)))));} static s7_pointer g_addrinfo_make(s7_scheme *sc, s7_pointer args) { return(s7_make_c_pointer(sc, (void *)calloc(1, sizeof(struct addrinfo)))); } static s7_pointer g_addrinfo_ai_flags(s7_scheme *sc, s7_pointer args) { return(s7_make_integer(sc, ((struct addrinfo *)s7_c_pointer(s7_car(args)))->ai_flags)); } static s7_pointer g_addrinfo_set_ai_flags(s7_scheme *sc, s7_pointer args) { ((struct addrinfo *)s7_c_pointer(s7_car(args)))->ai_flags = (int)s7_integer(s7_cadr(args)); return(s7_cadr(args)); } static s7_pointer g_addrinfo_ai_family(s7_scheme *sc, s7_pointer args) { return(s7_make_integer(sc, ((struct addrinfo *)s7_c_pointer(s7_car(args)))->ai_family)); } static s7_pointer g_addrinfo_set_ai_family(s7_scheme *sc, s7_pointer args) { ((struct addrinfo *)s7_c_pointer(s7_car(args)))->ai_family = (int)s7_integer(s7_cadr(args)); return(s7_cadr(args)); } static s7_pointer g_addrinfo_ai_socktype(s7_scheme *sc, s7_pointer args) { return(s7_make_integer(sc, ((struct addrinfo *)s7_c_pointer(s7_car(args)))->ai_socktype)); } static s7_pointer g_addrinfo_set_ai_socktype(s7_scheme *sc, s7_pointer args) { ((struct addrinfo *)s7_c_pointer(s7_car(args)))->ai_socktype = (int)s7_integer(s7_cadr(args)); return(s7_cadr(args)); } static s7_pointer g_addrinfo_ai_protocol(s7_scheme *sc, s7_pointer args) { return(s7_make_integer(sc, ((struct addrinfo *)s7_c_pointer(s7_car(args)))->ai_protocol)); } static s7_pointer g_addrinfo_set_ai_protocol(s7_scheme *sc, s7_pointer args) { ((struct addrinfo *)s7_c_pointer(s7_car(args)))->ai_protocol = (int)s7_integer(s7_cadr(args)); return(s7_cadr(args)); } static s7_pointer g_addrinfo_ai_canonname(s7_scheme *sc, s7_pointer args) { return(s7_make_string(sc, ((struct addrinfo *)s7_c_pointer(s7_car(args)))->ai_canonname)); } static s7_pointer g_addrinfo_ai_next(s7_scheme *sc, s7_pointer args) { return(s7_make_c_pointer(sc, (void *)(((struct addrinfo *)s7_c_pointer(s7_car(args)))->ai_next))); } static s7_pointer g_getaddrinfo(s7_scheme *sc, s7_pointer args) { struct addrinfo *result; int err; err = getaddrinfo(s7_string(s7_car(args)), s7_string(s7_cadr(args)), (const struct addrinfo *)s7_c_pointer(s7_caddr(args)), &result); return(s7_list(sc, 2, s7_make_integer(sc, err), s7_make_c_pointer(sc, (void *)result))); } static s7_pointer g_getnameinfo(s7_scheme *sc, s7_pointer args) { #ifndef NI_MAXHOST #define NI_MAXHOST 1025 #endif #ifndef NI_MAXSERV #define NI_MAXSERV 32 #endif char *host, *service; int err; host = (char *)calloc(NI_MAXHOST, sizeof(char)); service = (char *)calloc(NI_MAXSERV, sizeof(char)); err = getnameinfo((const struct sockaddr *)s7_c_pointer(s7_car(args)), s7_integer(s7_cadr(args)), host, NI_MAXHOST, service, NI_MAXSERV, s7_integer(s7_caddr(args))); return(s7_list(sc, 3, s7_make_integer(sc, err), s7_make_string(sc, host), s7_make_string(sc, service))); } static s7_pointer g_socketpair(s7_scheme *sc, s7_pointer args) { int fds[2]; int err; err = socketpair(s7_integer(s7_car(args)), s7_integer(s7_cadr(args)), s7_integer(s7_caddr(args)), fds); return(s7_list(sc, 3, s7_make_integer(sc, err), s7_make_integer(sc, fds[0]), s7_make_integer(sc, fds[1]))); } static s7_pointer g_getsockname(s7_scheme *sc, s7_pointer args) { int err; socklen_t res; res = s7_integer(s7_caddr(args)); err = getsockname(s7_integer(s7_car(args)), (struct sockaddr *)s7_c_pointer(s7_cadr(args)), &res); return(s7_list(sc, 2, s7_make_integer(sc, err), s7_make_integer(sc, res))); } static s7_pointer g_getpeername(s7_scheme *sc, s7_pointer args) { int err; socklen_t res; res = s7_integer(s7_caddr(args)); err = getpeername(s7_integer(s7_car(args)), (struct sockaddr *)s7_c_pointer(s7_cadr(args)), &res); return(s7_list(sc, 2, s7_make_integer(sc, err), s7_make_integer(sc, res))); } static s7_pointer g_accept(s7_scheme *sc, s7_pointer args) { int err; socklen_t res; res = s7_integer(s7_caddr(args)); err = accept(s7_integer(s7_car(args)), (struct sockaddr *)s7_c_pointer(s7_cadr(args)), &res); return(s7_list(sc, 2, s7_make_integer(sc, err), s7_make_integer(sc, res))); } static s7_pointer g_getsockopt(s7_scheme *sc, s7_pointer args) { int err; socklen_t res; res = (socklen_t)s7_integer(s7_list_ref(sc, args, 4)); err = getsockopt(s7_integer(s7_car(args)), s7_integer(s7_cadr(args)), s7_integer(s7_caddr(args)), s7_c_pointer(s7_cadddr(args)), &res); return(s7_list(sc, 2, s7_make_integer(sc, err), s7_make_integer(sc, (s7_int)res))); } static s7_pointer g_setsockopt(s7_scheme *sc, s7_pointer args) { socklen_t res; res = (socklen_t)s7_integer(s7_list_ref(sc, args, 4)); return(s7_make_integer(sc, setsockopt(s7_integer(s7_car(args)), s7_integer(s7_cadr(args)), s7_integer(s7_caddr(args)), s7_c_pointer(s7_cadddr(args)), res))); } static s7_pointer g_recvfrom(s7_scheme *sc, s7_pointer args) { int err; socklen_t res; res = (socklen_t)s7_integer(s7_list_ref(sc, args, 5)); err = recvfrom(s7_integer(s7_car(args)), s7_c_pointer(s7_cadr(args)), s7_integer(s7_caddr(args)), s7_integer(s7_cadddr(args)), (struct sockaddr *)s7_c_pointer(s7_list_ref(sc, args, 4)), &res); return(s7_list(sc, 2, s7_make_integer(sc, err), s7_make_integer(sc, (s7_int)res))); } static s7_pointer g_hostent_h_name(s7_scheme *sc, s7_pointer args) {return(s7_make_string(sc, ((struct hostent *)s7_c_pointer(s7_car(args)))->h_name));} static s7_pointer g_netent_n_name(s7_scheme *sc, s7_pointer args) {return(s7_make_string(sc, ((struct netent *)s7_c_pointer(s7_car(args)))->n_name));} static s7_pointer g_servent_s_name(s7_scheme *sc, s7_pointer args) {return(s7_make_string(sc, ((struct servent *)s7_c_pointer(s7_car(args)))->s_name));} static s7_pointer g_servent_s_proto(s7_scheme *sc, s7_pointer args) {return(s7_make_string(sc, ((struct servent *)s7_c_pointer(s7_car(args)))->s_proto));} static s7_pointer g_protoent_p_name(s7_scheme *sc, s7_pointer args) {return(s7_make_string(sc, ((struct protoent *)s7_c_pointer(s7_car(args)))->p_name));} static s7_pointer g_hostent_h_addrtype(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, ((struct hostent *)s7_c_pointer(s7_car(args)))->h_addrtype));} static s7_pointer g_hostent_h_length(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, ((struct hostent *)s7_c_pointer(s7_car(args)))->h_length));} static s7_pointer g_netent_n_addrtype(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, ((struct netent *)s7_c_pointer(s7_car(args)))->n_addrtype));} static s7_pointer g_netent_n_net(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, ((struct netent *)s7_c_pointer(s7_car(args)))->n_net));} static s7_pointer g_servent_s_port(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, ((struct servent *)s7_c_pointer(s7_car(args)))->s_port));} static s7_pointer g_protoent_p_proto(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, ((struct protoent *)s7_c_pointer(s7_car(args)))->p_proto));} static s7_pointer g_hostent_h_aliases(s7_scheme *sc, s7_pointer args) { s7_pointer p; char **str; struct hostent *h; p = s7_nil(sc); h = (struct hostent *)s7_c_pointer(s7_car(args)); for (str = h->h_aliases; (str) && (*str); str++) p = s7_cons(sc, s7_make_string(sc, *str), p); return(p); } static s7_pointer g_servent_s_aliases(s7_scheme *sc, s7_pointer args) { s7_pointer p; char **str; struct servent *h; p = s7_nil(sc); h = (struct servent *)s7_c_pointer(s7_car(args)); for (str = h->s_aliases; (str) && (*str); str++) p = s7_cons(sc, s7_make_string(sc, *str), p); return(p); } static s7_pointer g_netent_n_aliases(s7_scheme *sc, s7_pointer args) { s7_pointer p; char **str; struct netent *h; p = s7_nil(sc); h = (struct netent *)s7_c_pointer(s7_car(args)); for (str = h->n_aliases; (str) && (*str); str++) p = s7_cons(sc, s7_make_string(sc, *str), p); return(p); } static s7_pointer g_protoent_p_aliases(s7_scheme *sc, s7_pointer args) { s7_pointer p; char **str; struct protoent *h; p = s7_nil(sc); h = (struct protoent *)s7_c_pointer(s7_car(args)); for (str = h->p_aliases; (str) && (*str); str++) p = s7_cons(sc, s7_make_string(sc, *str), p); return(p); } ") (C-function ("htonl" g_htonl "" 1)) (C-function ("htons" g_htons "" 1)) (C-function ("ntohl" g_ntohl "" 1)) (C-function ("ntohs" g_ntohs "" 1)) (C-function ("getaddrinfo" g_getaddrinfo "" 3)) (C-function ("getnameinfo" g_getnameinfo "" 3)) (C-function ("addrinfo.make" g_addrinfo_make "" 0)) (C-function ("addrinfo.ai_flags" g_addrinfo_ai_flags "" 1)) (C-function ("addrinfo.set_ai_flags" g_addrinfo_set_ai_flags "" 2)) (C-function ("addrinfo.ai_family" g_addrinfo_ai_family "" 1)) (C-function ("addrinfo.set_ai_family" g_addrinfo_set_ai_family "" 2)) (C-function ("addrinfo.ai_socktype" g_addrinfo_ai_socktype "" 1)) (C-function ("addrinfo.set_ai_socktype" g_addrinfo_set_ai_socktype "" 2)) (C-function ("addrinfo.ai_protocol" g_addrinfo_ai_protocol "" 1)) (C-function ("addrinfo.set_ai_protocol" g_addrinfo_set_ai_protocol "" 2)) (C-function ("addrinfo.ai_canonname" g_addrinfo_ai_canonname "" 1)) (C-function ("addrinfo.ai_next" g_addrinfo_ai_next "" 1)) (C-function ("hostent.h_name" g_hostent_h_name "" 1)) (C-function ("netent.n_name" g_netent_n_name "" 1)) (C-function ("servent.s_name" g_servent_s_name "" 1)) (C-function ("servent.s_proto" g_servent_s_proto "" 1)) (C-function ("protoent.p_name" g_protoent_p_name "" 1)) (C-function ("hostent.h_addrtype" g_hostent_h_addrtype "" 1)) (C-function ("hostent.h_length" g_hostent_h_length "" 1)) (C-function ("netent.n_addrtype" g_netent_n_addrtype "" 1)) (C-function ("netent.n_net" g_netent_n_net "" 1)) (C-function ("servent.s_port" g_servent_s_port "" 1)) (C-function ("protoent.p_proto" g_protoent_p_proto "" 1)) (C-function ("hostent.h_aliases" g_hostent_h_aliases "" 1)) (C-function ("servent.s_aliases" g_servent_s_aliases "" 1)) (C-function ("netent.n_aliases" g_netent_n_aliases "" 1)) (C-function ("protoent.p_aliases" g_protoent_p_aliases "" 1)) ;; (define h (gethostbyname "fatty4")) ;; ((*libc* 'hostent.h_aliases) h) -> ("localhost" "localhost.localdomain") (C-function ("socketpair" g_socketpair "" 3)) (C-function ("getsockname" g_getsockname "" 3)) (C-function ("getpeername" g_getpeername "" 3)) (C-function ("accept" g_accept "" 3)) (C-function ("getsockopt" g_getsockopt "" 5)) (C-function ("setsockopt" g_setsockopt "" 5)) (C-function ("recvfrom" g_recvfrom "" 6)) ) "" (list "limits.h" "ctype.h" "errno.h" "float.h" "stdint.h" "locale.h" "stdlib.h" "string.h" "fcntl.h" "fenv.h" "stdio.h" "sys/utsname.h" "unistd.h" "dirent.h" "ftw.h" "sys/stat.h" "time.h" "sys/time.h" "utime.h" "termios.h" "grp.h" "pwd.h" "fnmatch.h" "glob.h" "signal.h" "sys/wait.h" "netdb.h" "sys/resource.h" (reader-cond ((not (provided? 'openbsd)) "wordexp.h")) (reader-cond ((provided? 'freebsd) "sys/socket.h" "netinet/in.h")) ) "" (if (provided? 'linux) "-lrt" (if (provided? 'openbsd) "-pthread" "")) "libc_s7") (curlet)))) *libc* snd-16.1/grani.scm0000644000076400007640000005565512616231602012156 0ustar bilbil;;; ************************* ;;; ENVELOPES (env.scm) ;;; ************************* (when (provided? 'pure-s7) (define-macro (call-with-values producer consumer) `(,consumer (,producer)))) ;;;============================================================================= ;;; Exponential envelopes ;;;============================================================================= ;;; Approximate an exponential envelope with a given base and error bound ;;; by Fernando Lopez-Lezcano (nando@ccrma.stanford.edu) ;;; ;;; base: ;;; step size of the exponential envelope ;;; error: ;;; error band of the approximation ;;; scaler: ;;; scaling factor for the y coordinates ;;; offset: ;;; offset for the y coordinates ;;; cutoff: ;;; lowest value of the exponentially rendered envelope, values lower than ;;; this cutoff value will be approximated as cero. ;;; out-scaler ;;; scaler for the converted values (provide 'snd-grani.scm) (if (provided? 'snd) (require snd-ws.scm) (require sndlib-ws.scm)) (require snd-env.scm) (define grani-default-base (expt 2 1/12)) (define* (exp-envelope env1 (base grani-default-base) (error 0.01) (scaler 1) (offset 0) cutoff (out-scaler 1)) (let* ((base (* 1.0 base)) (error (* 1.0 error)) (scaler (* 1.0 scaler)) (offset (* 1.0 offset)) (out-scaler (* 1.0 out-scaler)) (ycutoff (and cutoff (expt base (+ offset (* cutoff scaler))))) (result ())) ;; linear interpolation (letrec ((interpolate (lambda (xl yl xh yh xi) (+ yl (* (- xi xl) (/ (- yh yl) (- xh xl)))))) ;; ;; recursively render one segment ;; xl,xh = x coordinates of segment ends ;; yl,yh = y coordinates of segment ends ;; yle,yhe = exponential values of y coords of segment ends ;; error = linear domain error bound for rendering ;; (exp-seg (lambda (xl yle xh yhe yl yh error) (let* ((xint (/ (+ xl xh) 2.0)) (yint (interpolate xl yl xh yh xint)) (yinte (interpolate xl yle xh yhe xint)) (yexp (expt base yint)) (yerr (- (expt base (+ yint error)) yexp))) ;; is the linear approximation accurate enough? ;; are we still over the cutoff limit? (if (and (> (abs (- yexp yinte)) yerr) (or (not ycutoff) (> yinte ycutoff))) ;; no --> add a breakpoint and recurse right and left (call-with-values (lambda () (exp-seg xl yle xint yexp yl yint error)) (lambda (xi yi) (call-with-values (lambda () (exp-seg xint yexp xh yhe yint yh error)) (lambda (xj yj) (values (append xi (list xint) xj) (append yi (list yexp) yj)))))) ;; yes --> don't need to add nu'ting to the envelope (values () ())))))) ;; loop for each segment in the envelope (let segs ((en env1)) (let* ((x (car en)) (y (* 1.0 (cadr en))) (nx (caddr en)) (ny (* 1.0 (cadddr en))) (yscl (+ offset (* y scaler))) (nyscl (+ offset (* ny scaler))) (xy (list x (if (or (not ycutoff) (>= (expt base yscl) ycutoff)) (* out-scaler (expt base yscl)) 0.0)))) (set! result (append result xy)) (call-with-values (lambda () (exp-seg x (expt base yscl) nx (expt base nyscl) yscl nyscl error)) (lambda (xs ys) (if (pair? ys) (let ((ys-scaled (map (lambda (y) (* y out-scaler)) ys))) (let vals ((xx xs) (yy ys-scaled)) (let ((x (car xx)) (y (car yy))) (set! result (append result (list x y))) (if (> (length xx) 1) (vals (cdr xx) (cdr yy))))))))) (if (<= (length en) 4) (append result (list nx (if (or (not ycutoff) (>= (expt base nyscl) ycutoff)) (* out-scaler (expt base nyscl)) 0.0))) (segs (cddr en)))))))) ;;; Amplitude envelope in dBs ;;; ;;; The db scale is defined as: ;;; value(db)=(* 20 (log10 (/ vin vref))) ;;; where: ;;; vref=1.0 reference value = digital clipping (define* (db-envelope envelope (cutoff -70) (error 0.01)) (exp-envelope envelope :base 10 :scaler 1/20 :offset 0 :cutoff cutoff :error error)) (define* (make-db-env envelope (scaler 1) (offset 0) (base 1) (duration 0) (end 0) (cutoff -70) (error 0.01)) (make-env (db-envelope envelope cutoff error) :scaler scaler :offset offset :base base :duration duration :length (+ 1 end))) ;;; Pitch envelopes (y units are semitone and octave intervals) (define* (semitones-envelope envelope (around 1.0) (error 0.01)) (exp-envelope envelope :error error :base (expt 2 1/12) :cutoff #f :scaler 1 :offset 0 :out-scaler around)) (define* (make-semitones-env envelope (around 1.0) (scaler 1.0) (offset 0.0) (base 1) (duration 0) (end 0) (error 0.01)) (make-env (semitones-envelope envelope around error) :scaler scaler :offset offset :base base :duration duration :length (+ 1 end))) (define* (octaves-envelope envelope (around 1.0) (error 0.01)) (exp-envelope envelope :error error :base 2 :cutoff #f :scaler 1 :offset 0 :out-scaler around)) (define* (make-octaves-env envelope (around 1.0) (scaler 1.0) (offset 0.0) (base 1) (duration 0) (end 0) (error 0.01)) (make-env (octaves-envelope envelope around error) :scaler scaler :offset offset :base base :duration duration :length (+ 1 end))) ;;; ************************* ;;; GRANI (clm-ins.scm) ;;; ************************* ;;; grani: a granular synthesis instrument ;;; by Fernando Lopez-Lezcano ;;; http://ccrma.stanford.edu/~nando/clm/grani/ ;;; ;;; Original grani.ins instrument written for the 220a Course by ;;; Fernando Lopez-Lezcano & Juan Pampin, November 6 1996 ;;; ;;; Mar 21 1997: working with hop and grain-dur envelopes ;;; Mar 22 1997: working with src envelope (grain wise) & src spread ;;; Jan 26 1998: started work on new version ;;; Nov 7 1998: input soundfile duration calculation wrong ;;; Nov 10 1998: bug in in-samples (thanks to Kristopher D. Giesing for this one) ;;; Dec 20 1998: added standard locsig code ;;; Feb 19 1999: added "nil" as default value of where to avoid warning (by bill) ;;; Jan 10 2000: added input-channel to select which channel of the input file ;;; to process. ;;; added grain-start-in-seconds to be able to specify input file ;;; locations in seconds for the grain-start envelope ;;; May 06 2002: fixed array passing of where-bins in clisp (reported by Charles ;;; Nichols and jennifer l doering ;;; Mar 27 2003: added option for sending grains to all channels (requested by ;;; Oded Ben-Tal) ;;; Jun 17 2006: made some changes for the run macro (Bill) ;;; Jul 14 2007: removed :start args (Bill) ;;;----------------------------------------------------------------------------- ;;; Auxiliary functions ;;; calculate a random spread around a center of 0 (define-macro (random-spread spread) `(if (not (zero? ,spread)) (- (random ,spread) (/ ,spread 2.0)) 0.0)) ;;; convert a time in seconds to a number of samples (define-macro (to-samples time srate) `(floor (* ,time ,srate))) ;;; create a constant envelope if argument is a number (define (envelope-or-number in) (if (number? in) (list 0 in 1 in) in)) ;;; create a float-vector from an envelope (define* (make-gr-env env1 (len 512)) (let ((env-float-vector (make-float-vector len)) (length-1 (* 1.0 (- len 1)))) (do ((i 0 (+ 1 i))) ((= i len) env-float-vector) (set! (env-float-vector i) (envelope-interp (/ i length-1) env1))))) ;;;----------------------------------------------------------------------------- ;;; Grain envelopes (define* (raised-cosine (duty-cycle 100) (len 128)) (let* ((v (make-float-vector len)) (active (* len duty-cycle 0.01)) (incr (/ pi (- active 1))) (start (/ (- len active) 2)) (end (/ (+ len active) 2)) (s 0)) (do ((i 0 (+ 1 i))) ((= i len) v) (if (and (>= i start) (< i end)) (let ((sine (sin (* s incr)))) (set! s (+ 1 s)) (set! (v i) (* sine sine))))))) ;;;============================================================================= ;;; Granular synthesis instrument ;;;============================================================================= ;;; input-channel: ;;; from which channel in the input file are samples read ;;; amp-envelope: ;;; amplitude envelope for the note ;;; grain-envelope: ;;; grain-envelope-end: ;;; envelopes for each individual grain. The envelope applied in the result ;;; of interpolating both envelopes. The interpolation is controlled by ;;; grain-envelope-trasition. If "grain-envelope-end" is nil interpolation ;;; is turned off and only grain-envelope is applied to the grains. ;;; grain-envelope-trasition: ;;; an enveloper that controls the interpolation between the two grain envelopes ;;; 0 -> selects "grain-envelope" ;;; 1 -> selects "grain-envelope-end" ;;; grain-envelope-array-size ;;; size of the array passed to make-table-lookup ;;; grain-duration: ;;; envelope that controls grain duration in seconds ;;; srate-linear: ;;; #t -> sample rate envelope is linear ;;; #f -> sample rate envelope is exponential ;;; srate: ;;; envelope that controls sample rate conversion. The envelope is an ;;; exponential envelope, the base and error bound of the conversion ;;; are controlled by "srate-base" and "srate-error". ;;; srate-spread: ;;; random spread of sample rate conversion around "srate" ;;; srate-base: ;;; base for the exponential conversion ;;; for example: base = (expt 2 (/ 12)) creates a semitone envelope ;;; srate-error: ;;; error bound for the exponential conversion. ;;; grain-start: ;;; envelope that determines the starting point of the current grain in ;;; the input file. "y"->0 starts the grain at the beginning of the input ;;; file. "y"->1 starts the grain at the end of the input file. ;;; grain-start-spread: ;;; random spread around the value of "grain-start" ;;; grain-start-in-seconds: ;;; #f -> grain-start y envelope expressed in percent of the duration of the input file ;;; #t -> grain-start y envelope expressed in seconds ;;; grain-density: ;;; envelope that controls the number of grains per second generated in the output file ;;; grain-density-spread: ;;; envelope that controls a random variation of density (define grani-to-locsig 0.0) (define grani-to-grain-duration 1) (define grani-to-grain-start 2) (define grani-to-grain-sample-rate 3) (define grani-to-grain-random 4) (define grani-to-grain-allchans 5) (definstrument (grani start-time duration amplitude file (input-channel 0) (grains 0) (amp-envelope '(0 0 0.3 1 0.7 1 1 0)) (grain-envelope '(0 0 0.3 1 0.7 1 1 0)) grain-envelope-end (grain-envelope-transition '(0 0 1 1)) (grain-envelope-array-size 512) (grain-duration 0.1) (grain-duration-spread 0.0) (grain-duration-limit 0.002) (srate 0.0) (srate-spread 0.0) srate-linear (srate-base grani-default-base) (srate-error 0.01) (grain-start '(0 0 1 1)) (grain-start-spread 0.0) grain-start-in-seconds (grain-density 10.0) (grain-density-spread 0.0) (reverb-amount 0.01) reversed ; change this from "reverse" 18-Nov-13 (where-to 0) where-bins ; a float-vector, not a list (grain-distance 1.0) (grain-distance-spread 0.0) (grain-degree 45.0) (grain-degree-spread 0.0) (verbose #t)) (let ((ts (times->samples start-time duration)) (in-file-channels (channels file)) (in-file-sr (* 1.0 (mus-sound-srate file)))) (let ((beg (car ts)) (end (cadr ts)) (in-file-dur (/ (framples file) in-file-sr)) (out-chans (channels *output*)) (gr-samples 0) ;; ratio between input and output sampling rates (srate-ratio (/ in-file-sr *clm-srate*)) ;; sample rate converter for input samples (rd (make-readin :file file :channel (min input-channel (- in-file-channels 1))))) (let ((last-in-sample (floor (* in-file-dur in-file-sr))) (in-file-reader (make-src :input rd :srate 1.0)) ;; sample rate conversion envelope (sr-env (make-env (if srate-linear (envelope-or-number srate) (exp-envelope (envelope-or-number srate) :base srate-base :error srate-error)) :scaler srate-ratio :duration duration)) ;; sample rate conversion random spread (sr-spread-env (make-env (envelope-or-number srate-spread) :duration duration)) ;; amplitude envelope for the note (amp-env (make-env amp-envelope :scaler amplitude :duration duration)) ;; grain duration envelope (gr-dur (make-env (envelope-or-number grain-duration) :duration duration)) (gr-dur-spread (make-env (envelope-or-number grain-duration-spread) :duration duration)) ;; position in the input file where the grain starts (gr-start-scaler (if (not grain-start-in-seconds) in-file-dur 1.0)) (gr-start (make-env (envelope-or-number grain-start) :duration duration)) ;; random variation in the position in the input file (gr-start-spread (make-env (envelope-or-number grain-start-spread) :duration duration)) ;; density envelope in grains per second (gr-dens-env (make-env (envelope-or-number grain-density) :duration duration)) ;; density spread envelope in grains per second (gr-dens-spread-env (make-env (envelope-or-number grain-density-spread) :duration duration)) ;; grain envelope (gr-env (make-table-lookup :frequency 1.0 :initial-phase 0.0 :wave (if (float-vector? grain-envelope) grain-envelope (make-gr-env grain-envelope grain-envelope-array-size)))) ;; grain envelope (gr-env-end (make-table-lookup :frequency 1.0 :initial-phase 0.0 :wave (if grain-envelope-end (if (float-vector? grain-envelope-end) grain-envelope-end (make-gr-env grain-envelope-end grain-envelope-array-size)) (make-float-vector 512)))) ;; envelope for transition between grain envelopes (gr-int-env (make-env (envelope-or-number grain-envelope-transition) :duration duration)) (gr-int-env-1 (make-env (envelope-or-number grain-envelope-transition) :duration duration :offset 1.0 :scaler -1.0)) (interp-gr-envs grain-envelope-end) ;; envelope for distance of grains (for using in locsig) (gr-dist (make-env (envelope-or-number grain-distance) :duration duration)) (gr-dist-spread (make-env (envelope-or-number grain-distance-spread) :duration duration)) ;; envelopes for angular location and spread of grain in the stereo field (gr-degree (make-env (envelope-or-number grain-degree) :duration duration)) (gr-degree-spread (make-env (envelope-or-number grain-degree-spread) :duration duration)) ;; signal locator in the stereo image (loc (make-locsig :degree 45.0 :distance 1.0 :channels out-chans)) (in-samples 0) (gr-start-sample beg) (gr-from-beg 0) (in-start 0) (in-start-value 0.0) (gr-duration 0.0) (gr-dens 0.0) (gr-dens-spread 0.0) (gr-srate 0.0) (grain-counter 0) (first-grain #t) (where 0.0) (happy #t) (where-bins-len (if (float-vector? where-bins) (length where-bins) 0))) (if (<= where-bins-len 1) (set! where-bins #f)) (if reversed (set! (mus-increment in-file-reader) -1.0)) (do () ((not happy)) ;; ;; start of a new grain ;; (if first-grain ;; first grain always starts at 0 (begin (set! first-grain #f) (set! gr-start-sample beg)) (begin ;; start grain in output file using ;; increments from previous grain (set! gr-start-sample (+ gr-start-sample (floor (* (/ (+ gr-dens gr-dens-spread)) *clm-srate*)))) ;; finish if start of grain falls outside of note ;; bounds or number of grains exceeded (if (or (> gr-start-sample end) (and (not (zero? grains)) (>= grain-counter grains))) (set! happy #f)))) (if happy (begin ;; back to the beginning of the grain ;(set! gr-offset 0) ;; start of grain in samples from beginning of note (set! gr-from-beg (floor (- gr-start-sample beg))) ;; reset out-time dependent envelopes to current time (set! (mus-location amp-env) gr-from-beg) (set! (mus-location gr-dur) gr-from-beg) (set! (mus-location gr-dur-spread) gr-from-beg) (set! (mus-location sr-env) gr-from-beg) (set! (mus-location sr-spread-env) gr-from-beg) (set! (mus-location gr-start) gr-from-beg) (set! (mus-location gr-start-spread) gr-from-beg) (set! (mus-location gr-dens-env) gr-from-beg) (set! (mus-location gr-dens-spread-env) gr-from-beg) ;; start of grain in input file (set! in-start-value (+ (* (env gr-start) gr-start-scaler) (mus-random (* 0.5 (env gr-start-spread) gr-start-scaler)))) (set! in-start (floor (* in-start-value in-file-sr))) ;; duration in seconds of the grain (set! gr-duration (max grain-duration-limit (+ (env gr-dur) (mus-random (* 0.5 (env gr-dur-spread)))))) ;; number of samples in the grain (set! gr-samples (floor (* gr-duration *clm-srate*))) ;; new sample rate for grain (set! gr-srate (if srate-linear (+ (env sr-env) (mus-random (* 0.5 (env sr-spread-env)))) (* (env sr-env) (expt srate-base (mus-random (* 0.5 (env sr-spread-env))))))) ;; set new sampling rate conversion factor (set! (mus-increment in-file-reader) gr-srate) ;; number of samples in input (set! in-samples (floor (* gr-samples srate-ratio))) ;; check for out of bounds condition in in-file pointers (if (> (+ in-start in-samples) last-in-sample) (set! in-start (- last-in-sample in-samples)) (if (< in-start 0) (set! in-start 0))) ;; reset position of input file reader (set! (mus-location rd) in-start) ;; restart grain envelopes (set! (mus-phase gr-env) 0.0) (set! (mus-phase gr-env-end) 0.0) ;; reset grain envelope durations (set! (mus-frequency gr-env) (/ gr-duration)) (set! (mus-frequency gr-env-end) (/ gr-duration)) ;; ;; move position in output file for next grain ;; (set! gr-dens (env gr-dens-env)) ;; increment spread in output file for next grain (set! gr-dens-spread (mus-random (* 0.5 (env gr-dens-spread-env)))) (set! grain-counter (+ grain-counter 1)) (set! where (cond (;; use duration of grains as delimiter (= where-to grani-to-grain-duration) gr-duration) (;; use start in input file as delimiter (= where-to grani-to-grain-start) in-start-value) (;; use sampling rate as delimiter (= where-to grani-to-grain-sample-rate) gr-srate) (;; use a random number as delimiter (= where-to grani-to-grain-random) (random 1.0)) (else grani-to-locsig))) (if (and where-bins (not (zero? where))) ;; set output scalers according to criteria (do ((chn 0 (+ chn 1))) ((or (= chn out-chans) (= chn where-bins-len))) (locsig-set! loc chn (if (< (where-bins chn) where (where-bins (+ chn 1))) 1.0 0.0))) ;; if not "where" see if the user wants to send to all channels (if (= where-to grani-to-grain-allchans) ;; send the grain to all channels (do ((chn 0 (+ chn 1))) ((= chn out-chans)) (locsig-set! loc chn 1.0)) ;; "where" is zero or unknown: use normal n-channel locsig, ;; only understands mono reverb and 1, 2 or 4 channel output (begin (set! (mus-location gr-dist) gr-from-beg) (set! (mus-location gr-dist-spread) gr-from-beg) (set! (mus-location gr-degree) gr-from-beg) (set! (mus-location gr-degree-spread) gr-from-beg) ;; set locsig parameters, for now only understands stereo (move-locsig loc (+ (env gr-degree) (mus-random (* 0.5 (env gr-degree-spread)))) (+ (env gr-dist) (mus-random (* 0.5 (env gr-dist-spread)))))))) (let ((grend (+ gr-start-sample gr-samples))) (if interp-gr-envs (do ((gr-offset gr-start-sample (+ gr-offset 1))) ((= gr-offset grend)) (locsig loc gr-offset (* (env amp-env) (src in-file-reader) (+ (* (env gr-int-env) (table-lookup gr-env-end)) (* (env gr-int-env-1) (table-lookup gr-env)))))) (do ((gr-offset gr-start-sample (+ gr-offset 1))) ((= gr-offset grend)) (locsig loc gr-offset (* (env amp-env) (table-lookup gr-env) (src in-file-reader))))))))))))) ;; (with-sound (:channels 2 :reverb jc-reverb :reverb-channels 1) (let ((file "oboe.snd")) (grani 0 2 5 file :grain-envelope (raised-cosine)))) ;; (with-sound (:channels 2) (let ((file "oboe.snd")) (grani 0 2 5 file :grain-envelope (raised-cosine)))) (define (test-grani) (with-sound (:channels 2 :reverb jc-reverb :reverb-channels 1 :statistics #t) (grani 0 1 .5 "oboe.snd" :grain-envelope '(0 0 0.2 0.2 0.5 1 0.8 0.2 1 0)) (grani 0 4 1 "oboe.snd") (grani 0 4 1 "oboe.snd" :grains 10) (grani 0 4 1 "oboe.snd" :grain-start 0.11 :amp-envelope '(0 1 1 1) :grain-density 8 :grain-envelope '(0 0 0.2 0.2 0.5 1 0.8 0.2 1 0) :grain-envelope-end '(0 0 0.01 1 0.99 1 1 0) :grain-envelope-transition '(0 0 0.4 1 0.8 0 1 0)) (grani 0 3 1 "oboe.snd" :grain-start 0.1 :amp-envelope '(0 1 1 1) :grain-density 20 :grain-duration '(0 0.003 0.2 0.01 1 0.3)) (grani 0 3 1 "oboe.snd" :grain-start 0.1 :amp-envelope '(0 1 1 1) :grain-density 20 :grain-duration '(0 0.003 0.2 0.01 1 0.3) :grain-duration-limit 0.02) (grani 0 2 1 "oboe.snd" :amp-envelope '(0 1 1 1) :grain-density 40 :grain-start '(0 0.1 0.3 0.1 1 0.6)) (grani 0 2 1 "oboe.snd" :amp-envelope '(0 1 1 1) :grain-density 40 :grain-start '(0 0.1 0.3 0.1 1 0.6) :grain-start-spread 0.01) (grani 0 2.6 1 "oboe.snd" :grain-start 0.1 :grain-start-spread 0.01 :amp-envelope '(0 1 1 1) :grain-density 40 :srate '(0 0 0.2 0 0.6 5 1 5)) (grani 0 2.6 1 "oboe.snd" :grain-start 0.1 :grain-start-spread 0.01 :amp-envelope '(0 1 1 1) :grain-density 40 :srate-base 2 :srate '(0 0 0.2 0 0.6 -1 1 -1)) (grani 0 2.6 1 "oboe.snd" :grain-start 0.1 :grain-start-spread 0.01 :amp-envelope '(0 1 1 1) :grain-density 40 :srate-linear #t :srate (list 0 1 0.2 1 0.6 (expt 2 5/12) 1 (expt 2 5/12))) (grani 0 2 1 "oboe.snd" :grain-start 0.1 :grain-start-spread 0.01 :amp-envelope '(0 1 1 1) :grain-density 40 :grain-duration '(0 0.02 1 0.1) :grain-duration-spread '(0 0 0.5 0.1 1 0) :where-to grani-to-grain-duration ; from grani.scm :where-bins (float-vector 0 0.05 1)) (grani 0 2 1 "oboe.snd" :grain-start 0.1 :grain-start-spread 0.01 :amp-envelope '(0 1 1 1) :grain-density 40 :grain-degree '(0 0 1 90) :grain-degree-spread 10)))snd-16.1/strad.rb0000644000076400007640000002521612306421672012006 0ustar bilbil# strad.rb -- Translation CLM --> Snd-Ruby # # Bowed string physical model with stiffness. CLM version adapted # from the Matlab and C versions courtesy of JOS and Stefania Serafin # from code revised on 7/14/01 # # CLM version by Juan Reyes # # Translator/Author: Michael Scholz # Created: Sun Mar 16 02:46:52 CET 2003 # Changed: Wed Nov 17 23:56:56 CET 2010 require "ws" class DCBlock def initialize(input = 0.0, output = 0.0) @dc_input = input @dc_output = output end def dcblock(sample) @dc_output = sample + (0.99 * @dc_output - @dc_input) @dc_input = sample @dc_output end def inspect format("#<%s: input: %1.3f, output: %1.3f>", self.class, @dc_input, @dc_output) end end add_help(:bow, "bow(start = 0, dur = 1, freq = 440, amp = 0.5, *args) :bufsize 2205 @srate 22050 :fb 0.2 bow force (0.0..1.0) :vb 0.05 bow velocity (0.0..0.8) :bp 0.08 bow position (0.0 bridge, 0.5 middle of string, 1.0 nut) :inharm 0.1 inharmonicity (0.0 harmonic, 1.0 not harmonic) :ampenv [0, 0, 20, 1, 48, 1, 92, 0, 100, 0] :degree 45 :dist 0.0025 :reverb 0.005") def bow(start = 0, dur = 1, freq = 440, amp = 0.5, *args) bufsize, fb, vb, bp, inharm, ampenv, degree, dist, reverb = nil optkey(args, binding, [:bufsize, 2205], [:fb, 0.2], [:vb, 0.05], [:bp, 0.08], [:inharm, 0.1], [:ampenv, [0, 0, 20, 1, 48, 1, 92, 0, 100, 0]], [:degree, 45], [:dist, 0.0025], [:reverb, 0.005]) len = seconds2samples(dur) ampf = make_env(:envelope, ampenv, :scaler, amp, :length, len) dcblocker = DCBlock.new vinut = make_vct(bufsize) vinbridge = make_vct(bufsize) vinutt = make_vct(bufsize) vinbridget = make_vct(bufsize) vib = vin = vibt = vint = 0.0 mus = 0.8 # friction coeff twavespeedfactor = 5.2 posl = posr = poslt = posrt = indexl = indexr = indexlt = indexrt = 0 indexl_1 = indexr_1 = indexlt_1 = indexrt_1 = indexl_2 = indexr_2 = indexlt_2 = indexrt_2 = 0 updl = updr = updlt = updrt = 0 # biquad coefficients from jos follow b0b = 0.859210 b1b = -0.704922 b2b = 0.022502 a1b = -0.943639 a2b = 0.120665 b0n = 7.0580050e-001 b1n = -5.3168461e-001 b2n = 1.4579750e-002 a1n = -9.9142489e-001 a2n = 1.8012052e-001 # bridge side, torsional waves b0bt = 9.9157155e-001 b1bt = -8.2342890e-001 b2bt = 8.8441749e-002 a1bt = -8.3628218e-001 a2bt = 9.2866585e-002 # finger side, torsional waves b0nt = 4.3721359e-001 b1nt = -2.7034968e-001 b2nt = -5.7147560e-002 a1nt = -1.2158343e+000 a2nt = 3.2555068e-001 # initializations for the filters xm1bt = xm2bt = xm1nt = xm2nt = ym1bt = ym2bt = ym1nt = ym2nt = xm1b = xm2b = ym1b = ym2b = 0.0 xm1n = xm2n = ym1n = ym2n = ynb = ynbt = ynn = ynnt = ya1nb = ynba1 = y1nb = 0.0 # friedlander friction inits aa = bb1 = cc1 = delta1 = bb2 = cc2 = delta2 = v = v1 = v2 = rhs = lhs = vtemp = f = 0.0 string_impedance = 0.55 string_impedancet = 1.8 stick = 0 zslope = 1.0 / ((1.0 / (2.0 * string_impedance)) + (1.0 / (2.0 * string_impedancet))) xnn = xnb = xnnt = xnbt = 0.0 alphar = alphal = alphart = alphalt = 0 l = (mus_srate() / freq) - 2 lt = l / twavespeedfactor del_right = l * bp del_left = l * (1 - bp) del_leftt = lt * (1 - bp) del_rightt = lt * bp samp_rperiod = del_right.floor samp_lperiod = del_left.floor samp_lperiodt = del_leftt.floor samp_rperiodt = del_rightt.floor samp_rperiod = [samp_rperiod, 0].max samp_rperiod = [samp_rperiod, bufsize - 1].min samp_lperiod = [samp_lperiod, 0].max samp_lperiod = [samp_lperiod, bufsize - 1].min alphar = (del_right - samp_rperiod).to_f alphal = (del_left - samp_lperiod).to_f samp_rperiodt = [samp_rperiodt, 0].max samp_rperiodt = [samp_rperiodt, bufsize - 1].min samp_lperiodt = [samp_lperiodt, 0].max samp_lperiodt = [samp_lperiodt, bufsize - 1].min alphart = (del_rightt - samp_rperiodt).to_f alphalt = (del_leftt - samp_lperiodt).to_f posr = (len + posr) % bufsize posl = (len + posl) % bufsize posrt = (len + posrt) % bufsize poslt = (len + poslt) % bufsize bowfilt = lambda do |inharmon| # initialize coefficients ynb = ((b0b * vib + b1b * xm1b + b2b * xm2b) - a1b * ym1b) - a2b * ym2b xm2b, xm1b = xm1b, vib ym2b, ym1b = ym1b, ynb ynn = ((b0n * vin + b1n * xm1n + b2n * xm2n) - a1n * ym1n) - a2n * ym2n xm2n, xm1n = xm1n, vin ym2n, ym1n = ym1n, ynn # filters for torsional waves ynbt = ((b0bt * vibt + b1bt * xm1bt + b2bt * xm2bt) - a1bt * ym1bt) - a2bt * ym2bt xm2bt, xm1bt = xm1bt, vibt ym2bt, ym1bt = ym1bt, ynbt ynnt = ((b0nt * vint + b1nt * xm1nt + b2nt * xm2nt) - a1nt * ym1nt) - a2nt * ym2nt xm2nt, xm1nt = xm1nt, vint ym2nt, ym1nt = ym1nt, ynnt inharmon = [inharmon, 0.00001].max inharmon = [inharmon, 0.9999].min ya1nb = y1nb = -(inharmon * ynb) + ynba1 + inharmon * ya1nb ynba1 = ynb y1nb = -y1nb ynn = -ynn ynbt = -ynbt end friedlander = lambda do |vh| aa = zslope bb1 = ((0.2 * zslope + 0.3 * fb) - zslope * vb) - zslope * vh cc1 = ((0.06 * fb + zslope * vh * vb) - 0.2 * zslope * vh) - 0.3 * vb * fb delta1 = bb1 * bb1 - 4 * aa * cc1 bb2 = ((-0.2 * zslope - 0.3 * fb) - zslope * vb) - zslope * vh cc2 = (((0.06 * fb + zslope * vh * vb) + 0.2 * zslope * vh) + 0.3 * vb * fb) + 0.1 * fb delta2 = bb2 * bb2 - 4 * aa * cc2 if vb.zero? or fb.zero? v = vh else if vh == vb v, stick = vb, 1 else if vh > vb lhs, rhs = 0.0, 1.0 else rhs, lhs = 0.0, 1.0 end if rhs == 1.0 if delta1 < 0 v, stick = vb, 1 else if stick == 1 vtemp = vb f = 2.0 * zslope * (vtemp - vh) if f >= (-(mus * fb)) v = vtemp else v1 = (-bb1 + sqrt(delta1)) / (2.0 * aa) v2 = (-bb1 - sqrt(delta1)) / (2.0 * aa) v = [v1, v2].min stick = 0 end else v1 = (-bb1 + sqrt(delta1)) / (2.0 * aa) v2 = (-bb1 - sqrt(delta1)) / (2.0 * aa) v = [v1, v2].min stick = 0 end end elsif lhs == 1.0 if delta2 < 0 v, stick = vb, 1 else if stick == 1 vtemp = vb f = zslope * (vtemp - vh) if f <= (mus * fb) and f > 0 v = vtemp else v1 = (-bb2 - sqrt(delta2)) / (2.0 * aa) v2 = (-bb2 + sqrt(delta2)) / (2.0 * aa) vtemp = [v1, v2].min stick = 0 if vtemp > vb v, stick = vb, 1 else v = vtemp f = zslope * (v - vh) end end else v1 = (-bb2 - sqrt(delta2)) / (2.0 * aa) v2 = (-bb2 + sqrt(delta2)) / (2.0 * aa) v = [v1, v2].min stick = 0 end end if v > vb v, stick = vb, 1 end end end f = zslope * (v - vh) xnn = y1nb + (f / (2.0 * string_impedance)) xnb = ynn + (f / (2.0 * string_impedance)) end end i = 0 run_instrument(start, dur, :distance, dist, :reverb_amount, reverb, :degree, degree) do indexl = ((i + posl + bufsize) - samp_lperiod) % bufsize indexr = ((i + posr + bufsize) - samp_rperiod) % bufsize indexlt = ((i + poslt + bufsize) - samp_lperiodt) % bufsize indexrt = ((i + posrt + bufsize) - samp_rperiodt) % bufsize indexl_1 = (((i + posl + bufsize) - samp_lperiod) - 1) % bufsize indexr_1 = (((i + posr + bufsize) - samp_rperiod) - 1) % bufsize indexlt_1 = (((i + poslt + bufsize) - samp_lperiodt) - 1) % bufsize indexrt_1 = (((i + posrt + bufsize) - samp_rperiodt) - 1) % bufsize indexl_2 = (((i + posl + bufsize) - samp_lperiod) - 2) % bufsize indexr_2 = (((i + posr + bufsize) - samp_rperiod) - 2) % bufsize indexlt_2 = (((i + poslt + bufsize) - samp_lperiodt) - 2) % bufsize indexrt_2 = (((i + posrt + bufsize) - samp_rperiodt) - 2) % bufsize # fractional delay lines vib = ((vinbridge[indexl_2] * (alphal - 1) * (alphal - 2)) / 2.0) + (vinbridge[indexl_1] * -alphal * (alphal - 2)) + ((vinbridge[indexl] * alphal * (alphal - 1)) / 2.0) vin = ((vinut[indexr_2] * (alphar - 1) * (alphar - 2)) / 2.0) + (vinut[indexr_1] * -alphar * (alphar - 2)) + ((vinut[indexr] * alphar * (alphar - 1)) / 2.0) vibt = ((vinbridget[indexlt_2] * (alphalt - 1) * (alphalt - 2)) / 2.0) + (vinbridget[indexlt_1] * -alphalt * (alphalt - 2)) + ((vinbridget[indexlt] * alphalt * (alphalt - 1)) / 2.0) vint = ((vinutt[indexrt_2] * (alphart - 1) * (alphart - 2)) / 2.0) + (vinutt[indexrt_1] * -alphart * (alphart - 2)) + ((vinutt[indexrt] * alphart * (alphart - 1)) / 2.0) # biquad filters bowfilt.call(inharm) vh1 = ynn + y1nb + ynnt + ynbt # now solve set of simultaneous equations for v and f friedlander.call(vh1) f = zslope * (v - vh1) xnnt = ynbt + (f / (2.0 * string_impedancet)) xnbt = ynnt + (f / (2.0 * string_impedancet)) updl = (i + posl + bufsize) % bufsize updr = (i + posr + bufsize) % bufsize updlt = (i + poslt + bufsize) % bufsize updrt = (i + posrt + bufsize) % bufsize vinbridge[updl] = xnb vinut[updr] = xnn vinbridget[updlt] = xnbt vinutt[updrt] = xnnt out_val = env(ampf) * dcblocker.dcblock(xnb) lhs = rhs = 0.0 i += 1 out_val end end =begin with_sound(:channels, 2) do bow(0, 3, 400, 0.5, :vb, 0.15, :fb, 0.1, :inharm, 0.25) end with_sound(:channels, 2) do bow(0, 2, 440, 0.5, :fb, 0.25) end with_sound(:channels, 2) do bow(0, 4, 600, 0.8) end with_sound(:channels, 2) do bow(0, 6, 147, 2, :fb, 0.035, :vb, 0.1) end with_sound(:channels, 2) do bow(0, 3, 1100, 0.5, :vb, 0.45, :fb, 0.9, :inharm, 0.3) end with_sound(:channels, 2) do bow(0, 3, 1500, 0.5, :vb, 0.25, :fb, 0.9, :inharm, 0.3) end with_sound(:channels, 2) do bow(0, 3, 1525, 0.5, :vb, 0.25, :fb, 0.9, :inharm, 0.3) end with_sound(:channels, 2, :reverb, :jc_reverb_rb) do bow(0, 1, 400, 0.5, :reverb, 0.0051) end with_sound(:channels, 2, :reverb, :jc_reverb_rb) do bow(0, 3, 366, 0.5, :degree, 0) bow(0, 3, 422, 0.5, :degree, 90) bow(4, 6, 147, 2, :fb, 0.035, :vb, 0.1, :reverb, 0.051) end =end # strad.rb ends here snd-16.1/snd.h0000644000076400007640000000173212626046435011303 0ustar bilbil#ifndef SND_H #define SND_H #include #include #include #include #include #include #include #include #include #include #ifndef _MSC_VER #include #include #endif #include #include #include #include #include #include "_sndlib.h" #include "xen.h" #include "clm.h" #include "sndlib2xen.h" #include "vct.h" #include "snd-0.h" #ifdef USE_MOTIF #include "snd-x0.h" #else #if USE_GTK #include "snd-g0.h" #else #include "snd-nogui0.h" #endif #endif #include "snd-1.h" #ifdef USE_MOTIF #include "snd-x1.h" #else #if USE_GTK #include "snd-g1.h" #else #include "snd-nogui1.h" #endif #endif #include "snd-strings.h" #define SND_DATE "30-Nov-15" #ifndef SND_VERSION #define SND_VERSION "16.1" #endif #define SND_MAJOR_VERSION "16" #define SND_MINOR_VERSION "1" #endif snd-16.1/snd-gmenu.c0000644000076400007640000024202612512761107012404 0ustar bilbil#include "snd.h" #include "snd-menu.h" /* gprint */ /* are the printed graphs truncated because the "printer" assumes some paper size? */ static GtkPrintSettings *settings = NULL; static void begin_print(GtkPrintOperation *operation, GtkPrintContext *context, gpointer data) { gtk_print_operation_set_n_pages(operation, 1); } static void draw_page(GtkPrintOperation *operation, GtkPrintContext *context, gint page_num, gpointer data) { chan_info *cp; ss->cr = gtk_print_context_get_cairo_context(context); switch (ss->print_choice) { case PRINT_SND: cp = selected_channel(); display_channel_data_for_print(cp); break; case PRINT_ENV: env_redisplay_with_print(); break; } } static void end_print(GtkPrintOperation *operation, GtkPrintContext *context, gpointer data) { ss->cr = NULL; } static void file_print_callback(GtkWidget *w, gpointer info) { /* called from File:Print in main menu */ GtkPrintOperation *operation; GtkPrintOperationResult res; GError *error = NULL; operation = gtk_print_operation_new (); if (settings != NULL) gtk_print_operation_set_print_settings(operation, settings); g_signal_connect(G_OBJECT(operation), "begin-print", G_CALLBACK(begin_print), NULL); g_signal_connect(G_OBJECT(operation), "draw-page", G_CALLBACK(draw_page), NULL); g_signal_connect(G_OBJECT(operation), "end-print", G_CALLBACK(end_print), NULL); res = gtk_print_operation_run(operation, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG, GTK_WINDOW(MAIN_SHELL(ss)), &error); if (res == GTK_PRINT_OPERATION_RESULT_APPLY) { if (settings != NULL) g_object_unref(settings); settings = (GtkPrintSettings *)g_object_ref(gtk_print_operation_get_print_settings(operation)); } g_object_unref(operation); if (error) { snd_warning_without_format(error->message); g_error_free (error); } } widget_t make_file_print_dialog(bool managed, bool direct_to_printer) { /* xen print-dialog code */ file_print_callback(NULL, NULL); return(NULL); } /* gmenu */ static const char *ml[NUM_MENU_WIDGETS]; void set_menu_label(GtkWidget *w, const char *label) {if (w) set_button_label(w, label);} /* -------------------------------- FILE MENU -------------------------------- */ static GtkWidget **recent_file_items = NULL; static int recent_file_items_size = 0; static char *get_item_label(GtkWidget *w) { return((char *)gtk_label_get_text(GTK_LABEL(gtk_bin_get_child(GTK_BIN(w))))); } static void set_item_label(GtkWidget *w, const char *label) { gtk_label_set_text(GTK_LABEL(gtk_bin_get_child(GTK_BIN(w))), label); } static void open_recent_file_callback(GtkWidget *w, gpointer info) { char *filename; snd_info *sp; filename = get_item_label(w); ss->open_requestor = FROM_OPEN_RECENT_MENU; ss->open_requestor_data = NULL; sp = snd_open_file(filename, FILE_READ_WRITE); if (sp) select_channel(sp, 0); } static void file_open_recent_callback(GtkWidget *w, gpointer info) { int size; size = recent_files_size(); if (size > 0) { int i; char **recent_file_names; if (size > recent_file_items_size) { if (recent_file_items_size == 0) recent_file_items = (GtkWidget **)calloc(size, sizeof(GtkWidget *)); else { recent_file_items = (GtkWidget **)realloc(recent_file_items, size * sizeof(GtkWidget *)); for (i = recent_file_items_size; i < size; i++) recent_file_items[i] = NULL; } recent_file_items_size = size; } recent_file_names = recent_files(); for (i = 0; i < size; i++) { if (recent_file_items[i] == NULL) { recent_file_items[i] = gtk_menu_item_new_with_label(recent_file_names[i]); gtk_menu_shell_append(GTK_MENU_SHELL(file_open_recent_cascade_menu), recent_file_items[i]); gtk_widget_show(recent_file_items[i]); SG_SIGNAL_CONNECT(recent_file_items[i], "activate", open_recent_file_callback, NULL); } else { set_item_label(recent_file_items[i], recent_file_names[i]); gtk_widget_show(recent_file_items[i]); } } for (i = size; i < recent_file_items_size; i++) /* maybe previous file was deleted */ if (recent_file_items[i]) gtk_widget_hide(recent_file_items[i]); } } static void file_menu_update_1(GtkWidget *w, gpointer info) { if (recent_files_size() > 0) gtk_widget_show(file_open_recent_menu); else gtk_widget_hide(file_open_recent_menu); file_menu_update(); } static void file_open_callback(GtkWidget *w, gpointer info) {make_open_file_dialog(FILE_READ_WRITE, true);} static void file_view_callback(GtkWidget *w, gpointer info) {make_open_file_dialog(FILE_READ_ONLY, true);} static void file_new_callback(GtkWidget *w, gpointer info) {make_new_file_dialog(true);} static void file_close_callback(GtkWidget *w, gpointer info) {if (any_selected_sound()) snd_close_file(any_selected_sound());} static void file_close_all_callback(GtkWidget *w, gpointer info) {for_each_sound(snd_close_file);} static void file_save_callback(GtkWidget *w, gpointer info) {if (any_selected_sound()) save_edits_from_kbd(any_selected_sound());} static void file_update_callback(GtkWidget *w, gpointer info) {update_file_from_menu();} static void file_save_as_callback(GtkWidget *w, gpointer info) {make_sound_save_as_dialog(true);} static void file_revert_callback(GtkWidget *w, gpointer info) {revert_file_from_menu();} static void file_exit_callback(GtkWidget *w, gpointer info) {if (snd_exit_cleanly(EXIT_NOT_FORCED)) snd_exit(1);} static void file_mix_callback_1(GtkWidget *w, gpointer info) {make_mix_file_dialog(true);} static void file_insert_callback_1(GtkWidget *w, gpointer info) {make_insert_file_dialog(true);} static void file_print_callback_1(GtkWidget *w, gpointer info) {file_print_callback(w, info);} /* -------------------------------- EDIT MENU -------------------------------- */ static void edit_menu_update_1(GtkWidget *w, gpointer info) {edit_menu_update();} static void edit_mix_callback(GtkWidget *w, gpointer info) {add_selection_or_region(0, selected_channel());} static void edit_envelope_callback(GtkWidget *w, gpointer info) {create_envelope_editor();} static void edit_cut_callback(GtkWidget *w, gpointer info) {delete_selection(UPDATE_DISPLAY);} static void edit_paste_callback(GtkWidget *w, gpointer info) {insert_selection_from_menu();} static void edit_save_as_callback(GtkWidget *w, gpointer info) {make_selection_save_as_dialog(true);} static void edit_select_all_callback(GtkWidget *w, gpointer info) {select_all(current_channel());} static void edit_unselect_callback(GtkWidget *w, gpointer info) {deactivate_selection();} static void edit_undo_callback(GtkWidget *w, gpointer info) {undo_edit_with_sync(current_channel(), 1);} static void edit_redo_callback(GtkWidget *w, gpointer info) {redo_edit_with_sync(current_channel(), 1);} #if WITH_AUDIO static void edit_play_callback(GtkWidget *w, gpointer info) { if (ss->selection_play_stop) { stop_playing_all_sounds(PLAY_BUTTON_UNSET); reflect_play_selection_stop(); } else { set_menu_label(edit_play_menu, I_STOP); ss->selection_play_stop = true; play_selection(IN_BACKGROUND); } } void reflect_play_selection_stop(void) { set_menu_label(edit_play_menu, "Play Selection"); ss->selection_play_stop = false; } #else void reflect_play_selection_stop(void) { } #endif static void edit_header_callback_1(GtkWidget *w, gpointer info) { snd_info *sp; sp = any_selected_sound(); if (sp) edit_header(sp); } #if HAVE_EXTENSION_LANGUAGE static void edit_find_callback_1(GtkWidget *w, gpointer info) { edit_find_callback(w, info); } #endif /* -------------------------------- VIEW MENU -------------------------------- */ static void view_menu_update_1(GtkWidget *w, gpointer info) {view_menu_update();} static void view_separate_callback(GtkWidget *w, gpointer info) {set_channel_style(CHANNELS_SEPARATE);} static void view_combined_callback(GtkWidget *w, gpointer info) {set_channel_style(CHANNELS_COMBINED);} static void view_superimposed_callback(GtkWidget *w, gpointer info) {set_channel_style(CHANNELS_SUPERIMPOSED);} static void view_dots_callback(GtkWidget *w, gpointer info) {set_graph_style(GRAPH_DOTS);} static void view_lines_callback(GtkWidget *w, gpointer info) {set_graph_style(GRAPH_LINES);} static void view_filled_callback(GtkWidget *w, gpointer info) {set_graph_style(GRAPH_FILLED);} static void view_dots_and_lines_callback(GtkWidget *w, gpointer info) {set_graph_style(GRAPH_DOTS_AND_LINES);} static void view_lollipops_callback(GtkWidget *w, gpointer info) {set_graph_style(GRAPH_LOLLIPOPS);} static void view_zero_callback(GtkWidget *w, gpointer info) {set_show_y_zero((!(show_y_zero(ss))));} static void view_cursor_callback(GtkWidget *w, gpointer info) {set_with_verbose_cursor((!(with_verbose_cursor(ss))));} static void view_controls_callback(GtkWidget *w, gpointer info) {set_show_controls(!in_show_controls(ss));} #if HAVE_EXTENSION_LANGUAGE static void view_inset_callback(GtkWidget *w, gpointer info) { set_with_inset_graph((!(with_inset_graph(ss)))); for_each_chan(update_graph); } #endif #if HAVE_EXTENSION_LANGUAGE static void view_listener_callback(GtkWidget *w, gpointer info) {handle_listener(true);} #endif static void view_mix_dialog_callback(GtkWidget *w, gpointer info) {make_mix_dialog();} static void view_region_callback_1(GtkWidget *w, gpointer info) {view_region_callback(w, info);} static void view_color_orientation_callback_1(GtkWidget *w, gpointer info) {view_color_orientation_callback(w, info);} static void view_x_axis_seconds_callback(GtkWidget *w, gpointer info) {set_x_axis_style(X_AXIS_IN_SECONDS);} static void view_x_axis_clock_callback(GtkWidget *w, gpointer info) {set_x_axis_style(X_AXIS_AS_CLOCK);} static void view_x_axis_beats_callback(GtkWidget *w, gpointer info) {set_x_axis_style(X_AXIS_IN_BEATS);} static void view_x_axis_measures_callback(GtkWidget *w, gpointer info) {set_x_axis_style(X_AXIS_IN_MEASURES);} static void view_x_axis_samples_callback(GtkWidget *w, gpointer info) {set_x_axis_style(X_AXIS_IN_SAMPLES);} static void view_x_axis_percentage_callback(GtkWidget *w, gpointer info) {set_x_axis_style(X_AXIS_AS_PERCENTAGE);} static void view_no_axes_callback(GtkWidget *w, gpointer info) {set_show_axes(SHOW_NO_AXES);} static void view_all_axes_callback(GtkWidget *w, gpointer info) {set_show_axes(SHOW_ALL_AXES);} static void view_just_x_axis_callback(GtkWidget *w, gpointer info) {set_show_axes(SHOW_X_AXIS);} static void view_all_axes_unlabelled_callback(GtkWidget *w, gpointer info) {set_show_axes(SHOW_ALL_AXES_UNLABELLED);} static void view_just_x_axis_unlabelled_callback(GtkWidget *w, gpointer info) {set_show_axes(SHOW_X_AXIS_UNLABELLED);} static void view_bare_x_axis_callback(GtkWidget *w, gpointer info) {set_show_axes(SHOW_BARE_X_AXIS);} static void view_focus_right_callback(GtkWidget *w, gpointer info, gpointer data) {set_zoom_focus_style(ZOOM_FOCUS_RIGHT);} static void view_focus_left_callback(GtkWidget *w, gpointer info, gpointer data) {set_zoom_focus_style(ZOOM_FOCUS_LEFT);} static void view_focus_middle_callback(GtkWidget *w, gpointer info, gpointer data) {set_zoom_focus_style(ZOOM_FOCUS_MIDDLE);} static void view_focus_active_callback(GtkWidget *w, gpointer info, gpointer data) {set_zoom_focus_style(ZOOM_FOCUS_ACTIVE);} static void view_grid_callback(GtkWidget *w, gpointer info) { if (show_grid(ss) == NO_GRID) set_show_grid(WITH_GRID); else set_show_grid(NO_GRID); } /* -------------------------------- OPTIONS MENU -------------------------------- */ static void options_transform_callback(GtkWidget *w, gpointer info) {make_transform_dialog(true);} static void options_controls_callback(GtkWidget *w, gpointer info) {make_controls_dialog();} #if HAVE_EXTENSION_LANGUAGE static void options_save_state_callback(GtkWidget *w, gpointer info) {save_state_from_menu();} #endif static void options_preferences_callback(GtkWidget *w, gpointer info, gpointer data) {make_preferences_dialog();} /* -------------------------------- HELP MENU -------------------------------- */ static void help_about_snd_callback(GtkWidget *w, gpointer info) {about_snd_help();} static void help_fft_callback(GtkWidget *w, gpointer info) {fft_help();} #if HAVE_EXTENSION_LANGUAGE static void help_find_callback(GtkWidget *w, gpointer info) {find_help();} static void help_init_file_callback(GtkWidget *w, gpointer info) {init_file_help();} #endif static void help_undo_callback(GtkWidget *w, gpointer info) {undo_help();} static void help_sync_callback(GtkWidget *w, gpointer info) {sync_help();} static void help_debug_callback(GtkWidget *w, gpointer info) {debug_help();} static void help_controls_callback(GtkWidget *w, gpointer info) {controls_help();} static void help_env_callback(GtkWidget *w, gpointer info) {env_help();} static void help_marks_callback(GtkWidget *w, gpointer info) {marks_help();} static void help_mix_callback(GtkWidget *w, gpointer info) {mix_help();} static void help_sound_files_callback(GtkWidget *w, gpointer info) {sound_files_help();} static void help_keys_callback(GtkWidget *w, gpointer info) {key_help();} static void help_play_callback(GtkWidget *w, gpointer info) {play_help();} static void help_resample_callback(GtkWidget *w, gpointer info) {resample_help();} static void help_reverb_callback(GtkWidget *w, gpointer info) {reverb_help();} static void help_insert_callback(GtkWidget *w, gpointer info) {insert_help();} static void help_delete_callback(GtkWidget *w, gpointer info) {delete_help();} static void help_filter_callback(GtkWidget *w, gpointer info) {filter_help();} static void help_save_callback(GtkWidget *w, gpointer info) {save_help();} static void help_region_callback(GtkWidget *w, gpointer info) {region_help();} static void help_selection_callback(GtkWidget *w, gpointer info) {selection_help();} static void help_colors_callback(GtkWidget *w, gpointer info) {colors_help();} void check_menu_labels(int key, int state, bool extended) {} static void menu_drop_watcher(GtkWidget *w, const char *filename, int x, int y, void *data) { snd_info *sp = NULL; ss->open_requestor = FROM_DRAG_AND_DROP; sp = snd_open_file(filename, FILE_READ_WRITE); if (sp) select_channel(sp, 0); } static bool have_drag_title = false; static void menu_drag_watcher(GtkWidget *w, const char *str, int x, int y, drag_style_t dtype, void *data) { switch (dtype) { case DRAG_MOTION: case DRAG_ENTER: if (!have_drag_title) { char *new_title; new_title = mus_format("%s: drop to open file", ss->startup_title); gtk_window_set_title(GTK_WINDOW(MAIN_SHELL(ss)), new_title); have_drag_title = true; free(new_title); } break; case DRAG_LEAVE: reflect_file_change_in_title(); have_drag_title = false; break; } } /* -------------------------------- MAIN MENU -------------------------------- */ static GtkWidget *add_menu_item(GtkWidget *menu, const char *label, const char *icon, GCallback callback) { GtkWidget *w; #if GTK_CHECK_VERSION(3, 10, 0) w = gtk_menu_item_new_with_label(label); gtk_menu_shell_append(GTK_MENU_SHELL(menu), w); #else if (icon) w = gtk_image_menu_item_new_with_label(label); else w = gtk_menu_item_new_with_label(label); gtk_menu_shell_append(GTK_MENU_SHELL(menu), w); if (icon) gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(w), image_new_with_icon(icon, GTK_ICON_SIZE_MENU)); #endif if (callback) SG_SIGNAL_CONNECT(w, "activate", callback, NULL); gtk_widget_show(w); return(w); } static GtkWidget *add_insensitive_menu_item(GtkWidget *menu, const char *label, const char *icon, GCallback callback) { GtkWidget *w; w = add_menu_item(menu, label, icon, callback); set_sensitive(w, false); return(w); } static GtkWidget *add_menu_separator(GtkWidget *menu) { GtkWidget *w; w = gtk_menu_item_new(); gtk_menu_shell_append(GTK_MENU_SHELL(menu), w); gtk_widget_show(w); widget_modify_bg(w, GTK_STATE_NORMAL, ss->black); return(w); } #define WITH_MENU_ACCELERATORS false GtkWidget *add_menu(void) { #if WITH_MENU_ACCELERATORS /* these take precedence over everything, even in the listener? * also what are MOD1...5? MOD1->meta MOD2->?? SUPER->"windoze key" and HYPER also * but these look stupid -- maybe add with-menu-accelerators but then add_menu has to be smarter (not at startup) * and we need a way to unaccellerate if set to #f */ GtkAccelGroup *accel_group; accel_group = gtk_accel_group_new(); gtk_window_add_accel_group(GTK_WINDOW(MAIN_SHELL(ss)), accel_group); #endif ss->mw = (GtkWidget **)calloc(NUM_MENU_WIDGETS, sizeof(GtkWidget *)); main_menu = gtk_menu_bar_new(); ml[m_menu] = NULL; add_drag_and_drop(main_menu, menu_drop_watcher, menu_drag_watcher, NULL); gtk_box_pack_start(GTK_BOX(MAIN_PANE(ss)), main_menu, false, true, 0); add_menu_style(main_menu); gtk_widget_show(main_menu); /* -------- FILE MENU -------- */ file_menu = gtk_menu_item_new_with_label("File"); ml[f_menu] = "File"; gtk_menu_shell_append(GTK_MENU_SHELL(main_menu), file_menu); add_menu_style(file_menu); gtk_widget_show(file_menu); file_cascade_menu = gtk_menu_new(); add_menu_style(file_cascade_menu); ml[f_cascade_menu] = NULL; gtk_menu_item_set_submenu(GTK_MENU_ITEM(file_menu), file_cascade_menu); file_open_menu = add_menu_item(file_cascade_menu, "Open", ICON_OPEN, (GCallback)file_open_callback); ml[f_open_menu] = "Open"; #if WITH_MENU_ACCELERATORS gtk_widget_add_accelerator (file_open_menu, "activate", accel_group, GDK_O, GDK_HYPER_MASK | GDK_SHIFT_MASK, GTK_ACCEL_VISIBLE); #endif file_open_recent_menu = add_menu_item(file_cascade_menu, "Open recent", ICON_OPEN, (GCallback)file_open_recent_callback); ml[f_open_recent_menu] = "Open recent"; gtk_widget_hide(file_open_recent_menu); file_open_recent_cascade_menu = gtk_menu_new(); add_menu_style(file_open_recent_cascade_menu); ml[f_open_recent_cascade_menu] = NULL; gtk_menu_item_set_submenu(GTK_MENU_ITEM(file_open_recent_menu), file_open_recent_cascade_menu); file_close_menu = add_insensitive_menu_item(file_cascade_menu, "Close", ICON_CLOSE, (GCallback)file_close_callback); ml[f_close_menu] = "Close"; file_close_all_menu = add_menu_item(file_cascade_menu, "Close all", ICON_CLOSE, (GCallback)file_close_all_callback); ml[f_close_all_menu] = "Close all"; gtk_widget_hide(file_close_all_menu); file_save_menu = add_insensitive_menu_item(file_cascade_menu, "Save", ICON_SAVE, (GCallback)file_save_callback); ml[f_save_menu] = "Save"; file_save_as_menu = add_insensitive_menu_item(file_cascade_menu, "Save as", ICON_SAVE_AS, (GCallback)file_save_as_callback); ml[f_save_as_menu] = "Save as"; file_revert_menu = add_insensitive_menu_item(file_cascade_menu, "Revert", ICON_REVERT_TO_SAVED, (GCallback)file_revert_callback); ml[f_revert_menu] = "Revert"; file_mix_menu = add_insensitive_menu_item(file_cascade_menu, "Mix", ICON_ADD, (GCallback)file_mix_callback_1); ml[f_mix_menu] = "Mix"; file_insert_menu = add_insensitive_menu_item(file_cascade_menu, "Insert", ICON_PASTE, (GCallback)file_insert_callback_1); ml[f_insert_menu] = "Insert"; file_update_menu = add_insensitive_menu_item(file_cascade_menu, "Update", ICON_REFRESH, (GCallback)file_update_callback); ml[f_update_menu] = "Update"; file_new_menu = add_menu_item(file_cascade_menu, "New", ICON_NEW, (GCallback)file_new_callback); ml[f_new_menu] = "New"; file_view_menu = add_menu_item(file_cascade_menu, "View", ICON_OPEN, (GCallback)file_view_callback); ml[f_view_menu] = "View"; file_print_menu = add_insensitive_menu_item(file_cascade_menu, "Print", ICON_PRINT, (GCallback)file_print_callback_1); ml[f_print_menu] = "Print"; file_sep_menu = add_menu_separator(file_cascade_menu); ml[f_sep_menu] = NULL; file_exit_menu = add_menu_item(file_cascade_menu, "Exit", ICON_QUIT, (GCallback)file_exit_callback); ml[f_exit_menu] = "Exit"; /* -------- EDIT MENU -------- */ edit_menu = gtk_menu_item_new_with_label("Edit"); ml[e_menu] = "Edit"; gtk_menu_shell_append(GTK_MENU_SHELL(main_menu), edit_menu); add_menu_style(edit_menu); gtk_widget_show(edit_menu); edit_cascade_menu = gtk_menu_new(); add_menu_style(edit_cascade_menu); ml[e_cascade_menu] = NULL; gtk_menu_item_set_submenu(GTK_MENU_ITEM(edit_menu), edit_cascade_menu); edit_undo_menu = add_insensitive_menu_item(edit_cascade_menu, "Undo", ICON_UNDO, (GCallback)edit_undo_callback); ml[e_undo_menu] = "Undo"; edit_redo_menu = add_insensitive_menu_item(edit_cascade_menu, "Redo", ICON_REDO, (GCallback)edit_redo_callback); ml[e_redo_menu] = "Redo"; #if HAVE_EXTENSION_LANGUAGE edit_find_menu = add_insensitive_menu_item(edit_cascade_menu, I_FIND, ICON_FIND, (GCallback)edit_find_callback_1); ml[e_find_menu] = I_FIND; #endif edit_select_sep_menu = add_menu_separator(edit_cascade_menu); ml[e_select_sep_menu] = NULL; edit_cut_menu = add_insensitive_menu_item(edit_cascade_menu, "Delete selection", ICON_CUT, (GCallback)edit_cut_callback); ml[e_cut_menu] = "Delete Selection"; edit_paste_menu = add_insensitive_menu_item(edit_cascade_menu, "Insert selection", ICON_PASTE, (GCallback)edit_paste_callback); ml[e_paste_menu] = "Insert Selection"; edit_mix_menu = add_insensitive_menu_item(edit_cascade_menu, "Mix selection", ICON_ADD, (GCallback)edit_mix_callback); ml[e_mix_menu] = "Mix Selection"; #if WITH_AUDIO edit_play_menu = add_insensitive_menu_item(edit_cascade_menu, "Play selection", ICON_MEDIA_PLAY, (GCallback)edit_play_callback); ml[e_play_menu] = "Play Selection"; #endif edit_save_as_menu = add_insensitive_menu_item(edit_cascade_menu, "Save selection", ICON_SAVE_AS, (GCallback)edit_save_as_callback); ml[e_save_as_menu] = "Save Selection"; edit_select_all_menu = add_insensitive_menu_item(edit_cascade_menu, "Select all", ICON_SELECT_ALL, (GCallback)edit_select_all_callback); ml[e_select_all_menu] = "Select all"; edit_unselect_menu = add_insensitive_menu_item(edit_cascade_menu, "Unselect all", ICON_CLEAR, (GCallback)edit_unselect_callback); ml[e_unselect_menu] = "Unselect all"; edit_edit_sep_menu = add_menu_separator(edit_cascade_menu); ml[e_edit_sep_menu] = NULL; edit_env_menu = add_menu_item(edit_cascade_menu, "Edit envelope", NULL, (GCallback)edit_envelope_callback); ml[e_env_menu] = "Edit Envelope"; edit_header_menu = add_insensitive_menu_item(edit_cascade_menu, "Edit header", ICON_EDIT, (GCallback)edit_header_callback_1); ml[e_header_menu] = "Edit Header"; /* -------- VIEW MENU -------- */ view_menu = gtk_menu_item_new_with_label("View"); ml[v_menu] = "View"; gtk_menu_shell_append(GTK_MENU_SHELL(main_menu), view_menu); add_menu_style(view_menu); gtk_widget_show(view_menu); view_cascade_menu = gtk_menu_new(); add_menu_style(view_cascade_menu); ml[v_cascade_menu] = NULL; gtk_menu_item_set_submenu(GTK_MENU_ITEM(view_menu), view_cascade_menu); #if HAVE_EXTENSION_LANGUAGE view_listener_menu = add_menu_item(view_cascade_menu, "Open listener", NULL, (GCallback)view_listener_callback); ml[v_listener_menu] = "Open listener"; /* handle_listener in snd-glistener hides this -- is it ever displayed? */ #endif view_files_menu = add_insensitive_menu_item(view_cascade_menu, "Files", NULL, (GCallback)view_files_callback); ml[v_files_menu] = "Files"; view_mix_dialog_menu = add_menu_item(view_cascade_menu, "Mixes", NULL, (GCallback)view_mix_dialog_callback); ml[v_mix_dialog_menu] = "Mixes"; view_region_menu = add_insensitive_menu_item(view_cascade_menu, "Regions", NULL, (GCallback)view_region_callback_1); ml[v_region_menu] = "Regions"; view_color_orientation_menu = add_menu_item(view_cascade_menu, "Color/Orientation", ICON_SELECT_COLOR, (GCallback)view_color_orientation_callback_1); ml[v_color_orientation_menu] = "Color/Orientation"; view_controls_menu = add_menu_item(view_cascade_menu, "Show controls", NULL, (GCallback)view_controls_callback); ml[v_controls_menu] = "Show controls"; view_sep2_menu = add_menu_separator(view_cascade_menu); ml[v_sep2_menu] = NULL; view_graph_style_menu = add_menu_item(view_cascade_menu, I_LINES_OR_DOTS, NULL, NULL); ml[v_graph_style_menu] = I_LINES_OR_DOTS; view_graph_style_cascade_menu = gtk_menu_new(); add_menu_style(view_graph_style_cascade_menu); ml[v_graph_style_cascade_menu] = NULL; gtk_menu_item_set_submenu(GTK_MENU_ITEM(view_graph_style_menu), view_graph_style_cascade_menu); view_lines_menu = add_menu_item(view_graph_style_cascade_menu, "lines", NULL, (GCallback)view_lines_callback); ml[v_lines_menu] = "lines"; if (graph_style(ss) == GRAPH_LINES) set_sensitive(view_lines_menu, false); view_dots_menu = add_menu_item(view_graph_style_cascade_menu, "dots", NULL, (GCallback)view_dots_callback); ml[v_dots_menu] = "dots"; if (graph_style(ss) == GRAPH_DOTS) set_sensitive(view_dots_menu, false); view_filled_menu = add_menu_item(view_graph_style_cascade_menu, "filled", NULL, (GCallback)view_filled_callback); ml[v_filled_menu] = "filled"; if (graph_style(ss) == GRAPH_FILLED) set_sensitive(view_filled_menu, false); view_dots_and_lines_menu = add_menu_item(view_graph_style_cascade_menu, "dots and lines", NULL, (GCallback)view_dots_and_lines_callback); ml[v_dots_and_lines_menu] = "dots and lines"; if (graph_style(ss) == GRAPH_DOTS_AND_LINES) set_sensitive(view_dots_and_lines_menu, false); view_lollipops_menu = add_menu_item(view_graph_style_cascade_menu, "lollipops", NULL, (GCallback)view_lollipops_callback); ml[v_lollipops_menu] = "lollipops"; if (graph_style(ss) == GRAPH_LOLLIPOPS) set_sensitive(view_lollipops_menu, false); view_cursor_menu = add_menu_item(view_cascade_menu, "Verbose cursor", NULL, (GCallback)view_cursor_callback); ml[v_cursor_menu] = "Verbose cursor"; #if HAVE_EXTENSION_LANGUAGE view_inset_menu = add_menu_item(view_cascade_menu, "With inset graph", NULL, (GCallback)view_inset_callback); ml[v_inset_menu] = "With inset graph"; #endif view_combine_menu = add_menu_item(view_cascade_menu, I_CHANNEL_LAYOUT, NULL, NULL); ml[v_combine_menu] = I_CHANNEL_LAYOUT; view_combine_cascade_menu = gtk_menu_new(); add_menu_style(view_combine_cascade_menu); ml[v_combine_cascade_menu] = NULL; gtk_menu_item_set_submenu(GTK_MENU_ITEM(view_combine_menu), view_combine_cascade_menu); view_combine_separate_menu = add_menu_item(view_combine_cascade_menu, "separate", NULL, (GCallback)view_separate_callback); ml[v_combine_separate_menu] = "separate"; if (channel_style(ss) == CHANNELS_SEPARATE) set_sensitive(view_combine_separate_menu, false); view_combine_combined_menu = add_menu_item(view_combine_cascade_menu, "combined", NULL, (GCallback)view_combined_callback); ml[v_combine_combined_menu] = "combined"; if (channel_style(ss) == CHANNELS_COMBINED) set_sensitive(view_combine_combined_menu, false); view_combine_superimposed_menu = add_menu_item(view_combine_cascade_menu, "superimposed", NULL, (GCallback)view_superimposed_callback); ml[v_combine_superimposed_menu] = "superimposed"; if (channel_style(ss) == CHANNELS_SUPERIMPOSED) set_sensitive(view_combine_superimposed_menu, false); view_zero_menu = add_menu_item(view_cascade_menu, "Show y = 0", NULL, (GCallback)view_zero_callback); ml[v_zero_menu] = "Show y = 0"; view_x_axis_menu = add_menu_item(view_cascade_menu, "X axis units", NULL, NULL); ml[v_x_axis_menu] = "X axis units"; view_x_axis_cascade_menu = gtk_menu_new(); add_menu_style(view_x_axis_cascade_menu); ml[v_x_axis_cascade_menu] = NULL; gtk_menu_item_set_submenu(GTK_MENU_ITEM(view_x_axis_menu), view_x_axis_cascade_menu); view_x_axis_seconds_menu = add_insensitive_menu_item(view_x_axis_cascade_menu, "seconds", NULL, (GCallback)view_x_axis_seconds_callback); ml[v_x_axis_seconds_menu] = "seconds"; view_x_axis_samples_menu = add_menu_item(view_x_axis_cascade_menu, "samples", NULL, (GCallback)view_x_axis_samples_callback); ml[v_x_axis_samples_menu] = "samples"; view_x_axis_clock_menu = add_menu_item(view_x_axis_cascade_menu, "clock", NULL, (GCallback)view_x_axis_clock_callback); ml[v_x_axis_clock_menu] = "clock"; view_x_axis_percentage_menu = add_menu_item(view_x_axis_cascade_menu, "percentage", NULL, (GCallback)view_x_axis_percentage_callback); ml[v_x_axis_percentage_menu] = "percentage"; view_x_axis_beats_menu = add_menu_item(view_x_axis_cascade_menu, "beats", NULL, (GCallback)view_x_axis_beats_callback); ml[v_x_axis_beats_menu] = "beats"; view_x_axis_measures_menu = add_menu_item(view_x_axis_cascade_menu, "measures", NULL, (GCallback)view_x_axis_measures_callback); ml[v_x_axis_measures_menu] = "measures"; view_axes_menu = add_menu_item(view_cascade_menu, I_AXIS_LAYOUT, NULL, NULL); ml[v_axes_menu] = I_AXIS_LAYOUT; view_axes_cascade_menu = gtk_menu_new(); add_menu_style(view_axes_cascade_menu); ml[v_axes_cascade_menu] = NULL; gtk_menu_item_set_submenu(GTK_MENU_ITEM(view_axes_menu), view_axes_cascade_menu); view_no_axes_menu = add_menu_item(view_axes_cascade_menu, "no axes", NULL, (GCallback)view_no_axes_callback); ml[v_no_axes_menu] = "no axes"; view_all_axes_menu = add_menu_item(view_axes_cascade_menu, "both axes", NULL, (GCallback)view_all_axes_callback); ml[v_all_axes_menu] = "both axes"; view_just_x_axis_menu = add_menu_item(view_axes_cascade_menu, "just x axis", NULL, (GCallback)view_just_x_axis_callback); ml[v_just_x_axis_menu] = "just x axis"; view_all_axes_unlabelled_menu = add_menu_item(view_axes_cascade_menu, "both axes, no labels", NULL, (GCallback)view_all_axes_unlabelled_callback); ml[v_all_axes_unlabelled_menu] = "both axes, no labels"; view_just_x_axis_unlabelled_menu = add_menu_item(view_axes_cascade_menu, "just x axis, no label", NULL, (GCallback)view_just_x_axis_unlabelled_callback); ml[v_just_x_axis_unlabelled_menu] = "just x axis, no label"; view_bare_x_axis_menu = add_menu_item(view_axes_cascade_menu, "bare x axis", NULL, (GCallback)view_bare_x_axis_callback); ml[v_bare_x_axis_menu] = "base x axis"; view_focus_style_menu = add_menu_item(view_cascade_menu, I_ZOOM_CENTERS_ON, NULL, NULL); ml[v_focus_style_menu] = I_ZOOM_CENTERS_ON; view_focus_cascade_menu = gtk_menu_new(); add_menu_style(view_focus_cascade_menu); ml[v_focus_cascade_menu] = NULL; gtk_menu_item_set_submenu(GTK_MENU_ITEM(view_focus_style_menu), view_focus_cascade_menu); view_focus_left_menu = add_menu_item(view_focus_cascade_menu, "window left edge", NULL, (GCallback)view_focus_left_callback); ml[v_focus_left_menu] = "window left edge"; view_focus_right_menu = add_menu_item(view_focus_cascade_menu, "window right edge", NULL, (GCallback)view_focus_right_callback); ml[v_focus_right_menu] = "window right edge"; view_focus_middle_menu = add_menu_item(view_focus_cascade_menu, "window midpoint", NULL, (GCallback)view_focus_middle_callback); ml[v_focus_middle_menu] = "window midpoint"; view_focus_active_menu = add_menu_item(view_focus_cascade_menu, "cursor or selection", NULL, (GCallback)view_focus_active_callback); ml[v_focus_active_menu] = "cursor or selection"; view_grid_menu = add_menu_item(view_cascade_menu, "With grid", NULL, (GCallback)view_grid_callback); ml[v_grid_menu] = "With grid"; /* -------- OPTIONS MENU -------- */ options_menu = gtk_menu_item_new_with_label("Options"); ml[o_menu] = "Options"; gtk_menu_shell_append(GTK_MENU_SHELL(main_menu), options_menu); add_menu_style(options_menu); gtk_widget_show(options_menu); options_cascade_menu = gtk_menu_new(); add_menu_style(options_cascade_menu); ml[o_cascade_menu] = NULL; gtk_menu_item_set_submenu(GTK_MENU_ITEM(options_menu), options_cascade_menu); options_transform_menu = add_menu_item(options_cascade_menu, "Transform options", NULL, (GCallback)options_transform_callback); ml[o_transform_menu] = "Transform Options"; options_controls_menu = add_menu_item(options_cascade_menu, "Control panel options", NULL, (GCallback)options_controls_callback); ml[o_controls_menu] = "Control panel options"; #if HAVE_EXTENSION_LANGUAGE options_save_state_menu = add_menu_item(options_cascade_menu, "Save session", NULL, (GCallback)options_save_state_callback); ml[o_save_state_menu] = "Save session"; #endif add_menu_separator(options_cascade_menu); ml[o_sep_menu] = NULL; options_preferences_menu = add_menu_item(options_cascade_menu, "Preferences", ICON_PREFERENCES, (GCallback)options_preferences_callback); ml[o_preferences_menu] = "Preferences"; /* -------- HELP MENU -------- */ help_menu = gtk_menu_item_new_with_label(I_HELP); ml[h_menu] = I_HELP; gtk_menu_shell_append(GTK_MENU_SHELL(main_menu), help_menu); add_menu_style(help_menu); #if GTK_CHECK_VERSION(3, 0, 0) /* gtk_widget_set_halign(GTK_WIDGET(help_menu), GTK_ALIGN_END); * gtk_widget_set_hexpand(GTK_WIDGET(help_menu), true); * * this is no longer supported in Gtk -- they say "use gtk_widget_set_hexpand() and gtk_widget_set_halign()" * but who gets the hexpand? not main_menu, not help_menu... */ #else gtk_menu_item_set_right_justified(GTK_MENU_ITEM(help_menu), true); #endif gtk_widget_show(help_menu); help_cascade_menu = gtk_menu_new(); add_menu_style(help_cascade_menu); ml[h_cascade_menu] = NULL; gtk_menu_item_set_submenu(GTK_MENU_ITEM(help_menu), help_cascade_menu); help_about_snd_menu = add_menu_item(help_cascade_menu, "About Snd", NULL, (GCallback)help_about_snd_callback); ml[h_about_snd_menu] = "About Snd"; #if HAVE_EXTENSION_LANGUAGE help_init_file_menu = add_menu_item(help_cascade_menu, "Customization", NULL, (GCallback)help_init_file_callback); ml[h_init_file_menu] = "Customization"; #endif help_controls_menu = add_menu_item(help_cascade_menu, "Control panel", NULL, (GCallback)help_controls_callback); ml[h_controls_menu] = "Control Panel"; help_keys_menu = add_menu_item(help_cascade_menu, "Key bindings", NULL, (GCallback)help_keys_callback); ml[h_keys_menu] = "Key bindings"; help_play_menu = add_menu_item(help_cascade_menu, "Play", NULL, (GCallback)help_play_callback); ml[h_play_menu] = "Play"; help_save_menu = add_menu_item(help_cascade_menu, "Save", NULL, (GCallback)help_save_callback); ml[h_save_menu] = "Save"; help_mix_menu = add_menu_item(help_cascade_menu, "Mix", NULL, (GCallback)help_mix_callback); ml[h_mix_menu] = "Mix"; help_resample_menu = add_menu_item(help_cascade_menu, "Resample", NULL, (GCallback)help_resample_callback); ml[h_resample_menu] = "Resample"; help_fft_menu = add_menu_item(help_cascade_menu, "FFT", NULL, (GCallback)help_fft_callback); ml[h_fft_menu] = "FFT"; help_filter_menu = add_menu_item(help_cascade_menu, "Filter", NULL, (GCallback)help_filter_callback); ml[h_filter_menu] = "Filter"; help_reverb_menu = add_menu_item(help_cascade_menu, "Reverb", NULL, (GCallback)help_reverb_callback); ml[h_reverb_menu] = "Reverb"; help_env_menu = add_menu_item(help_cascade_menu, "Envelope", NULL, (GCallback)help_env_callback); ml[h_env_menu] = "Envelope"; help_marks_menu = add_menu_item(help_cascade_menu, "Marks", NULL, (GCallback)help_marks_callback); ml[h_marks_menu] = "Marks"; help_insert_menu = add_menu_item(help_cascade_menu, "Insert", NULL, (GCallback)help_insert_callback); ml[h_insert_menu] = "Insert"; help_delete_menu = add_menu_item(help_cascade_menu, "Delete", NULL, (GCallback)help_delete_callback); ml[h_delete_menu] = "Delete"; help_undo_menu = add_menu_item(help_cascade_menu, "Undo and redo", NULL, (GCallback)help_undo_callback); ml[h_undo_menu] = "Undo and redo"; #if HAVE_EXTENSION_LANGUAGE help_find_menu = add_menu_item(help_cascade_menu, I_FIND, NULL, (GCallback)help_find_callback); ml[h_find_menu] = I_FIND; #endif help_sync_menu = add_menu_item(help_cascade_menu, "Sync and unite", NULL, (GCallback)help_sync_callback); ml[h_sync_menu] = "Sync and unite"; help_sound_files_menu = add_menu_item(help_cascade_menu, "Headers and data", NULL, (GCallback)help_sound_files_callback); ml[h_sound_files_menu] = "Headers and data"; help_debug_menu = add_menu_item(help_cascade_menu, "Debugging", NULL, (GCallback)help_debug_callback); ml[h_debug_menu] = "Debugging"; help_region_menu = add_menu_item(help_cascade_menu, "Regions", NULL, (GCallback)help_region_callback); ml[h_region_menu] = "Regions"; help_selection_menu = add_menu_item(help_cascade_menu, "Selection", NULL, (GCallback)help_selection_callback); ml[h_selection_menu] = "Selection"; help_colors_menu = add_menu_item(help_cascade_menu, "Colors", NULL, (GCallback)help_colors_callback); ml[h_colors_menu] = "Colors"; SG_SIGNAL_CONNECT(file_menu, "activate", file_menu_update_1, NULL); SG_SIGNAL_CONNECT(edit_menu, "activate", edit_menu_update_1, NULL); SG_SIGNAL_CONNECT(view_menu, "activate", view_menu_update_1, NULL); return(main_menu); } /* -------------------------------- POPUP MENUS -------------------------------- */ static GtkWidget *basic_popup_menu = NULL, *selection_popup_menu = NULL; /* -------- basic popup -------- */ static void popup_info_callback(GtkWidget *w, gpointer info) { snd_info *sp; sp = any_selected_sound(); if (sp) display_info(sp); } static gboolean popup_menu_button_release(GtkWidget *w, GdkEventButton *ev, gpointer data) { gtk_widget_hide(w); return(false); } static void popup_normalize_callback(GtkWidget *w, gpointer info) { mus_float_t scl[1]; scl[0] = 1.0; scale_to(any_selected_sound(), current_channel(), scl, 1, OVER_SOUND); } static void popup_reverse_callback(GtkWidget *w, gpointer info) { reverse_sound(current_channel(), OVER_SOUND, C_int_to_Xen_integer(AT_CURRENT_EDIT_POSITION), 0); } static void stop_everything_callback(GtkWidget *w, gpointer info) { control_g(any_selected_sound()); } static void popup_play_channel_callback(GtkWidget *w, gpointer info) { chan_info *cp; cp = current_channel(); play_channel(cp, 0, current_samples(cp)); } static GtkWidget *popup_play = NULL; void post_basic_popup_menu(void *e) { GdkEventButton *ev = (GdkEventButton *)e; snd_info *sp; if (!basic_popup_menu) { basic_popup_menu = gtk_menu_new(); add_menu_style(basic_popup_menu); gtk_widget_set_events(basic_popup_menu, GDK_ALL_EVENTS_MASK); gtk_widget_show(basic_popup_menu); SG_SIGNAL_CONNECT(basic_popup_menu, "button_release_event", popup_menu_button_release, NULL); add_menu_item(basic_popup_menu, "Info", NULL, (GCallback)popup_info_callback); add_menu_item(basic_popup_menu, "Select all", NULL, (GCallback)edit_select_all_callback); popup_play = add_menu_item(basic_popup_menu, "Play channel", NULL, (GCallback)popup_play_channel_callback); add_menu_item(basic_popup_menu, "Stop!", NULL, (GCallback)stop_everything_callback); add_menu_item(basic_popup_menu, "-> 1.0", NULL, (GCallback)popup_normalize_callback); add_menu_item(basic_popup_menu, "Reverse", NULL, (GCallback)popup_reverse_callback); } sp = any_selected_sound(); if ((!sp) || (sp->nchans == 1)) gtk_widget_hide(popup_play); else gtk_widget_show(popup_play); gtk_menu_popup(GTK_MENU(basic_popup_menu), NULL, NULL, NULL, NULL, POPUP_BUTTON, EVENT_TIME(ev)); } /* -------- selection popup -------- */ static void popup_show_selection_callback(GtkWidget *w, gpointer info) { show_selection(); } static void popup_zero_selection_callback(GtkWidget *w, gpointer info) { mus_float_t scl[1]; scl[0] = 0.0; scale_by(NULL, scl, 1, OVER_SELECTION); } static void popup_normalize_selection_callback(GtkWidget *w, gpointer info) { mus_float_t scl[1]; scl[0] = 1.0; scale_to(NULL, NULL, scl, 1, OVER_SELECTION); } static void popup_error_handler(const char *msg, void *data) { redirect_snd_error_to(NULL, NULL); redirect_snd_warning_to(NULL, NULL); status_report(any_selected_sound(), "%s: %s", (char *)data, msg); } static void popup_cut_to_new_callback_1(bool cut) { char *temp_file; io_error_t io_err = IO_NO_ERROR; temp_file = snd_tempnam(); io_err = save_selection(temp_file, selection_srate(), default_output_sample_type(ss), default_output_header_type(ss), NULL, SAVE_ALL_CHANS); if (io_err == IO_NO_ERROR) { if (cut) delete_selection(UPDATE_DISPLAY); ss->open_requestor = FROM_POPUP_CUT_TO_NEW; redirect_snd_error_to(popup_error_handler, (void *)"popup cut->new"); snd_open_file(temp_file, FILE_READ_WRITE); redirect_snd_error_to(NULL, NULL); free(temp_file); } } static void popup_cut_to_new_callback(GtkWidget *w, gpointer info) {popup_cut_to_new_callback_1(true);} static void popup_copy_to_new_callback(GtkWidget *w, gpointer info) {popup_cut_to_new_callback_1(false);} static void crop(chan_info *cp) { if (selection_is_active_in_channel(cp)) { mus_long_t beg, end, framples; framples = current_samples(cp); beg = selection_beg(cp); end = selection_end(cp); if (beg > 0) delete_samples(0, beg, cp, cp->edit_ctr); if (end < (framples - 1)) delete_samples(end + 1, framples - end, cp, cp->edit_ctr); } } static void popup_crop_callback(GtkWidget *w, gpointer info) { for_each_chan(crop); } static void popup_cut_and_smooth_callback(GtkWidget *w, gpointer info) { for_each_chan(cut_and_smooth); } static void mark_selection(chan_info *cp) { if (selection_is_active_in_channel(cp)) { add_mark(selection_beg(cp), NULL, cp); add_mark(selection_end(cp), NULL, cp); } } static void popup_mark_selection_callback(GtkWidget *w, gpointer info) { for_each_chan(mark_selection); } static void popup_reverse_selection_callback(GtkWidget *w, gpointer info) { reverse_sound(current_channel(), OVER_SELECTION, C_int_to_Xen_integer(AT_CURRENT_EDIT_POSITION), 0); } static mus_float_t selection_max = 0.0; static void selection_info(chan_info *cp) { if ((selection_is_active_in_channel(cp)) && (selection_maxamp(cp) > selection_max)) selection_max = selection_maxamp(cp); } static void popup_selection_info_callback(GtkWidget *w, gpointer info) { selection_max = 0.0; for_each_chan(selection_info); status_report(any_selected_sound(), "selection max: %f", selection_max); } #if WITH_AUDIO static void popup_loop_play_callback(GtkWidget *w, gpointer info) { if (ss->selection_play_stop) { stop_playing_all_sounds(PLAY_BUTTON_UNSET); reflect_play_selection_stop(); } else { set_menu_label(edit_play_menu, I_STOP); ss->selection_play_stop = true; loop_play_selection(); } } #endif void post_selection_popup_menu(void *e) { GdkEventButton *ev = (GdkEventButton *)e; if (!selection_popup_menu) { selection_popup_menu = gtk_menu_new(); add_menu_style(selection_popup_menu); gtk_widget_set_events(selection_popup_menu, GDK_ALL_EVENTS_MASK); gtk_widget_show(selection_popup_menu); SG_SIGNAL_CONNECT(selection_popup_menu, "button_release_event", popup_menu_button_release, NULL); add_menu_item(selection_popup_menu, "Fill window", NULL, (GCallback)popup_show_selection_callback); add_menu_item(selection_popup_menu, "Cut", NULL, (GCallback)edit_cut_callback); add_menu_item(selection_popup_menu, "Cut and smooth", NULL, (GCallback)popup_cut_and_smooth_callback); add_menu_item(selection_popup_menu, "Cut -> new", NULL, (GCallback)popup_cut_to_new_callback); add_menu_item(selection_popup_menu, "Save as", NULL, (GCallback)edit_save_as_callback); #if WITH_AUDIO add_menu_item(selection_popup_menu, "Play", NULL, (GCallback)edit_play_callback); add_menu_item(selection_popup_menu, "Play looping", NULL, (GCallback)popup_loop_play_callback); #endif add_menu_item(selection_popup_menu, "Crop", NULL, (GCallback)popup_crop_callback); add_menu_item(selection_popup_menu, "Unselect all", NULL, (GCallback)edit_unselect_callback); add_menu_item(selection_popup_menu, "Copy -> new", NULL, (GCallback)popup_copy_to_new_callback); add_menu_item(selection_popup_menu, "-> 0.0", NULL, (GCallback)popup_zero_selection_callback); add_menu_item(selection_popup_menu, "-> 1.0", NULL, (GCallback)popup_normalize_selection_callback); add_menu_item(selection_popup_menu, "Paste", NULL, (GCallback)edit_paste_callback); add_menu_item(selection_popup_menu, "Mix", NULL, (GCallback)edit_mix_callback); add_menu_item(selection_popup_menu, "Mark", NULL, (GCallback)popup_mark_selection_callback); add_menu_item(selection_popup_menu, "Reverse", NULL, (GCallback)popup_reverse_selection_callback); add_menu_item(selection_popup_menu, "Info", NULL, (GCallback)popup_selection_info_callback); } gtk_menu_popup(GTK_MENU(selection_popup_menu), NULL, NULL, NULL, NULL, POPUP_BUTTON, EVENT_TIME(ev)); } /* -------- fft popup -------- */ static GtkWidget *fft_popup_menu = NULL; static void popup_peaks_callback(GtkWidget *w, gpointer info) { FILE *peaks_fd; peaks_fd = FOPEN("fft.txt", "w"); if (peaks_fd) { write_transform_peaks(peaks_fd, current_channel()); /* follows sync */ fclose(peaks_fd); } } static void fft_size_16_callback(GtkWidget *w, gpointer info) {set_transform_size(16);} static void fft_size_64_callback(GtkWidget *w, gpointer info) {set_transform_size(64);} static void fft_size_256_callback(GtkWidget *w, gpointer info) {set_transform_size(256);} static void fft_size_1024_callback(GtkWidget *w, gpointer info) {set_transform_size(1024);} static void fft_size_4096_callback(GtkWidget *w, gpointer info) {set_transform_size(4096);} static void fft_size_16384_callback(GtkWidget *w, gpointer info) {set_transform_size(16384);} static void fft_size_65536_callback(GtkWidget *w, gpointer info) {set_transform_size(65536);} static void fft_size_262144_callback(GtkWidget *w, gpointer info) {set_transform_size(262144);} static void fft_size_1048576_callback(GtkWidget *w, gpointer info) {set_transform_size(1048576);} static void fft_window_rectangular_callback(GtkWidget *w, gpointer info) {set_fft_window(MUS_RECTANGULAR_WINDOW);} static void fft_window_hann_callback(GtkWidget *w, gpointer info) {set_fft_window(MUS_HANN_WINDOW);} static void fft_window_welch_callback(GtkWidget *w, gpointer info) {set_fft_window(MUS_WELCH_WINDOW);} static void fft_window_parzen_callback(GtkWidget *w, gpointer info) {set_fft_window(MUS_PARZEN_WINDOW);} static void fft_window_bartlett_callback(GtkWidget *w, gpointer info) {set_fft_window(MUS_BARTLETT_WINDOW);} static void fft_window_blackman2_callback(GtkWidget *w, gpointer info) {set_fft_window(MUS_BLACKMAN2_WINDOW);} static void fft_window_blackman3_callback(GtkWidget *w, gpointer info) {set_fft_window(MUS_BLACKMAN3_WINDOW);} static void fft_window_blackman4_callback(GtkWidget *w, gpointer info) {set_fft_window(MUS_BLACKMAN4_WINDOW);} static void fft_window_hamming_callback(GtkWidget *w, gpointer info) {set_fft_window(MUS_HAMMING_WINDOW);} static void fft_window_exponential_callback(GtkWidget *w, gpointer info) {set_fft_window(MUS_EXPONENTIAL_WINDOW);} static void fft_window_riemann_callback(GtkWidget *w, gpointer info) {set_fft_window(MUS_RIEMANN_WINDOW);} static void fft_window_kaiser_callback(GtkWidget *w, gpointer info) {set_fft_window(MUS_KAISER_WINDOW);} static void fft_window_cauchy_callback(GtkWidget *w, gpointer info) {set_fft_window(MUS_CAUCHY_WINDOW);} static void fft_window_poisson_callback(GtkWidget *w, gpointer info) {set_fft_window(MUS_POISSON_WINDOW);} static void fft_window_gaussian_callback(GtkWidget *w, gpointer info) {set_fft_window(MUS_GAUSSIAN_WINDOW);} static void fft_window_tukey_callback(GtkWidget *w, gpointer info) {set_fft_window(MUS_TUKEY_WINDOW);} static void fft_window_dolph_chebyshev_callback(GtkWidget *w, gpointer info) {set_fft_window(MUS_DOLPH_CHEBYSHEV_WINDOW);} static void fft_window_blackman6_callback(GtkWidget *w, gpointer info) {set_fft_window(MUS_BLACKMAN6_WINDOW);} static void fft_window_blackman8_callback(GtkWidget *w, gpointer info) {set_fft_window(MUS_BLACKMAN8_WINDOW);} static void fft_window_blackman10_callback(GtkWidget *w, gpointer info) {set_fft_window(MUS_BLACKMAN10_WINDOW);} static void fft_type_fourier_callback(GtkWidget *w, gpointer info) {set_transform_type(FOURIER);} static void fft_type_wavelet_callback(GtkWidget *w, gpointer info) {set_transform_type(WAVELET);} static void fft_type_autocorrelation_callback(GtkWidget *w, gpointer info) {set_transform_type(AUTOCORRELATION);} static void fft_type_cepstrum_callback(GtkWidget *w, gpointer info) {set_transform_type(CEPSTRUM);} static void fft_graph_once_callback(GtkWidget *w, gpointer info) {set_transform_graph_type(GRAPH_ONCE);} static void fft_graph_sonogram_callback(GtkWidget *w, gpointer info) {set_transform_graph_type(GRAPH_AS_SONOGRAM);} static void fft_graph_spectrogram_callback(GtkWidget *w, gpointer info) {set_transform_graph_type(GRAPH_AS_SPECTROGRAM);} static void fft_gray_callback(GtkWidget *w, gpointer info) {set_color_map(GRAY_COLORMAP);} static void fft_hot_callback(GtkWidget *w, gpointer info) {set_color_map(HOT_COLORMAP);} static void fft_cool_callback(GtkWidget *w, gpointer info) {set_color_map(COOL_COLORMAP);} static void fft_bone_callback(GtkWidget *w, gpointer info) {set_color_map(BONE_COLORMAP);} static void fft_copper_callback(GtkWidget *w, gpointer info) {set_color_map(COPPER_COLORMAP);} static void fft_pink_callback(GtkWidget *w, gpointer info) {set_color_map(PINK_COLORMAP);} static void fft_jet_callback(GtkWidget *w, gpointer info) {set_color_map(JET_COLORMAP);} static void fft_prism_callback(GtkWidget *w, gpointer info) {set_color_map(PRISM_COLORMAP);} static void fft_autumn_callback(GtkWidget *w, gpointer info) {set_color_map(AUTUMN_COLORMAP);} static void fft_winter_callback(GtkWidget *w, gpointer info) {set_color_map(WINTER_COLORMAP);} static void fft_spring_callback(GtkWidget *w, gpointer info) {set_color_map(SPRING_COLORMAP);} static void fft_summer_callback(GtkWidget *w, gpointer info) {set_color_map(SUMMER_COLORMAP);} static void fft_rainbow_callback(GtkWidget *w, gpointer info) {set_color_map(RAINBOW_COLORMAP);} static void fft_flag_callback(GtkWidget *w, gpointer info) {set_color_map(FLAG_COLORMAP);} static void fft_phases_callback(GtkWidget *w, gpointer info) {set_color_map(PHASES_COLORMAP);} static void fft_black_and_white_callback(GtkWidget *w, gpointer info) {set_color_map(BLACK_AND_WHITE_COLORMAP);} void post_fft_popup_menu(void *e) { GdkEventButton *ev = (GdkEventButton *)e; if (!fft_popup_menu) { GtkWidget *outer_menu, *cascade_menu; fft_popup_menu = gtk_menu_new(); add_menu_style(fft_popup_menu); gtk_widget_set_events(fft_popup_menu, GDK_ALL_EVENTS_MASK); gtk_widget_show(fft_popup_menu); SG_SIGNAL_CONNECT(fft_popup_menu, "button_release_event", popup_menu_button_release, NULL); outer_menu = add_menu_item(fft_popup_menu, "Size", NULL, NULL); cascade_menu = gtk_menu_new(); add_menu_style(cascade_menu); gtk_menu_item_set_submenu(GTK_MENU_ITEM(outer_menu), cascade_menu); add_menu_item(cascade_menu, "16", NULL, (GCallback)fft_size_16_callback); add_menu_item(cascade_menu, "64", NULL, (GCallback)fft_size_64_callback); add_menu_item(cascade_menu, "256", NULL, (GCallback)fft_size_256_callback); add_menu_item(cascade_menu, "1024", NULL, (GCallback)fft_size_1024_callback); add_menu_item(cascade_menu, "4096", NULL, (GCallback)fft_size_4096_callback); add_menu_item(cascade_menu, "16384", NULL, (GCallback)fft_size_16384_callback); add_menu_item(cascade_menu, "65536", NULL, (GCallback)fft_size_65536_callback); add_menu_item(cascade_menu, "262144", NULL, (GCallback)fft_size_262144_callback); add_menu_item(cascade_menu, "1048576", NULL, (GCallback)fft_size_1048576_callback); outer_menu = add_menu_item(fft_popup_menu, "Window", NULL, NULL); cascade_menu = gtk_menu_new(); add_menu_style(cascade_menu); gtk_menu_item_set_submenu(GTK_MENU_ITEM(outer_menu), cascade_menu); add_menu_item(cascade_menu, "rectangular", NULL, (GCallback)fft_window_rectangular_callback); add_menu_item(cascade_menu, "hann", NULL, (GCallback)fft_window_hann_callback); add_menu_item(cascade_menu, "welch", NULL, (GCallback)fft_window_welch_callback); add_menu_item(cascade_menu, "parzen", NULL, (GCallback)fft_window_parzen_callback); add_menu_item(cascade_menu, "bartlett", NULL, (GCallback)fft_window_bartlett_callback); add_menu_item(cascade_menu, "hamming", NULL, (GCallback)fft_window_hamming_callback); add_menu_item(cascade_menu, "blackman2", NULL, (GCallback)fft_window_blackman2_callback); add_menu_item(cascade_menu, "blackman3", NULL, (GCallback)fft_window_blackman3_callback); add_menu_item(cascade_menu, "blackman4", NULL, (GCallback)fft_window_blackman4_callback); add_menu_item(cascade_menu, "exponential", NULL, (GCallback)fft_window_exponential_callback); add_menu_item(cascade_menu, "riemann", NULL, (GCallback)fft_window_riemann_callback); add_menu_item(cascade_menu, "kaiser", NULL, (GCallback)fft_window_kaiser_callback); add_menu_item(cascade_menu, "cauchy", NULL, (GCallback)fft_window_cauchy_callback); add_menu_item(cascade_menu, "poisson", NULL, (GCallback)fft_window_poisson_callback); add_menu_item(cascade_menu, "gaussian", NULL, (GCallback)fft_window_gaussian_callback); add_menu_item(cascade_menu, "tukey", NULL, (GCallback)fft_window_tukey_callback); add_menu_item(cascade_menu, "dolph-chebyshev", NULL, (GCallback)fft_window_dolph_chebyshev_callback); add_menu_item(cascade_menu, "blackman6", NULL, (GCallback)fft_window_blackman6_callback); add_menu_item(cascade_menu, "blackman8", NULL, (GCallback)fft_window_blackman8_callback); add_menu_item(cascade_menu, "blackman10" , NULL, (GCallback)fft_window_blackman10_callback); outer_menu = add_menu_item(fft_popup_menu, "Graph type", NULL, NULL); cascade_menu = gtk_menu_new(); add_menu_style(cascade_menu); gtk_menu_item_set_submenu(GTK_MENU_ITEM(outer_menu), cascade_menu); add_menu_item(cascade_menu, "one fft", NULL, (GCallback)fft_graph_once_callback); add_menu_item(cascade_menu, "sonogram", NULL, (GCallback)fft_graph_sonogram_callback); add_menu_item(cascade_menu, "spectrogram", NULL, (GCallback)fft_graph_spectrogram_callback); outer_menu = add_menu_item(fft_popup_menu, "Transform type", NULL, NULL); cascade_menu = gtk_menu_new(); add_menu_style(cascade_menu); gtk_menu_item_set_submenu(GTK_MENU_ITEM(outer_menu), cascade_menu); add_menu_item(cascade_menu, "fourier", NULL, (GCallback)fft_type_fourier_callback); add_menu_item(cascade_menu, "wavelet", NULL, (GCallback)fft_type_wavelet_callback); add_menu_item(cascade_menu, "autocorrelation", NULL, (GCallback)fft_type_autocorrelation_callback); add_menu_item(cascade_menu, "cepstrum", NULL, (GCallback)fft_type_cepstrum_callback); outer_menu = add_menu_item(fft_popup_menu, "Colormap", NULL, NULL); cascade_menu = gtk_menu_new(); add_menu_style(cascade_menu); gtk_menu_item_set_submenu(GTK_MENU_ITEM(outer_menu), cascade_menu); add_menu_item(cascade_menu, "gray", NULL, (GCallback)fft_gray_callback); add_menu_item(cascade_menu, "autumn", NULL, (GCallback)fft_autumn_callback); add_menu_item(cascade_menu, "spring", NULL, (GCallback)fft_spring_callback); add_menu_item(cascade_menu, "winter", NULL, (GCallback)fft_winter_callback); add_menu_item(cascade_menu, "summer", NULL, (GCallback)fft_summer_callback); add_menu_item(cascade_menu, "cool", NULL, (GCallback)fft_cool_callback); add_menu_item(cascade_menu, "copper", NULL, (GCallback)fft_copper_callback); add_menu_item(cascade_menu, "flag", NULL, (GCallback)fft_flag_callback); add_menu_item(cascade_menu, "prism", NULL, (GCallback)fft_prism_callback); add_menu_item(cascade_menu, "bone", NULL, (GCallback)fft_bone_callback); add_menu_item(cascade_menu, "hot", NULL, (GCallback)fft_hot_callback); add_menu_item(cascade_menu, "jet", NULL, (GCallback)fft_jet_callback); add_menu_item(cascade_menu, "pink", NULL, (GCallback)fft_pink_callback); add_menu_item(cascade_menu, "rainbow", NULL, (GCallback)fft_rainbow_callback); add_menu_item(cascade_menu, "phases", NULL, (GCallback)fft_phases_callback); add_menu_item(cascade_menu, "black and white", NULL, (GCallback)fft_black_and_white_callback); add_menu_item(fft_popup_menu, "Peaks->fft.txt", NULL, (GCallback)popup_peaks_callback); } gtk_menu_popup(GTK_MENU(fft_popup_menu), NULL, NULL, NULL, NULL, POPUP_BUTTON, EVENT_TIME(ev)); } void post_lisp_popup_menu(void *e) {} /* ---------------- toolbar ---------------- */ void add_tooltip(GtkWidget *w, const char *tip) { #if (!GTK_CHECK_VERSION(3, 0, 0)) gtk_widget_set_tooltip_text(w, tip); #else char *str; int i, len; len = mus_strlen(tip); str = (char *)calloc(len + 1, sizeof(char)); for (i = 0; i < len; i++) { if (tip[i] == '\n') str[i] = ' '; else str[i] = tip[i]; } gtk_widget_set_tooltip_text(w, str); free(str); #endif } /* suddenly in 3.3.12 the icon backgrounds are gray and everything has endless white space around it! * now in 3.3.14, the whitespace is gone, but the backgrounds are following a different (white-base) cairo pattern -- sigh... * and previously gray backgrounds are now black? */ static GtkWidget *add_to_toolbar(GtkWidget *bar, const gchar *stock, const char *tip, GCallback callback) { GtkToolItem *w; #if GTK_CHECK_VERSION(3, 10, 0) GtkWidget *pw; GtkIconTheme *icon_theme; GdkPixbuf *pixbuf; icon_theme = gtk_icon_theme_get_default(); pixbuf = gtk_icon_theme_load_icon(icon_theme, stock, 16, (GtkIconLookupFlags)0, NULL); pw = gtk_image_new_from_pixbuf(pixbuf); gtk_widget_show(pw); w = gtk_tool_button_new(pw, NULL); #else w = gtk_tool_button_new_from_stock(stock); #endif add_toolbar_style(GTK_WIDGET(w)); gtk_toolbar_insert(GTK_TOOLBAR(bar), w, -1); /* -1 = at end */ add_tooltip(GTK_WIDGET(w), tip); gtk_widget_show(GTK_WIDGET(w)); g_signal_connect(GTK_WIDGET(w), "clicked", callback, NULL); return(GTK_WIDGET(w)); } static void add_separator_to_toolbar(GtkWidget *bar) { GtkToolItem *w; w = gtk_separator_tool_item_new(); gtk_toolbar_insert(GTK_TOOLBAR(bar), w, -1); gtk_widget_show(GTK_WIDGET(w)); } #if WITH_AUDIO static void play_from_start_callback(GtkWidget *w, gpointer info) { snd_info *sp; sp = any_selected_sound(); if (sp) play_sound(sp, 0, NO_END_SPECIFIED); } static void play_from_cursor_callback(GtkWidget *w, gpointer info) { snd_info *sp; sp = any_selected_sound(); if (sp) { chan_info *cp; cp = any_selected_channel(sp); if (cp) play_sound(sp, cursor_sample(cp), NO_END_SPECIFIED); } } static void stop_playing_callback(GtkWidget *w, gpointer info) { stop_playing_all_sounds(PLAY_C_G); reflect_play_selection_stop(); /* this sets ss->selection_play_stop = false; */ } #endif static void full_dur_callback(GtkWidget *w, gpointer info) { snd_info *sp; sp = any_selected_sound(); if (sp) { int i; for (i = 0; i < sp->nchans; i++) set_x_axis_x0x1(sp->chans[i], 0.0, sp->chans[i]->axis->xmax); } } static void zoom_out_callback(GtkWidget *w, gpointer info) { snd_info *sp; sp = any_selected_sound(); if (sp) { int i; for (i = 0; i < sp->nchans; i++) zx_incremented(sp->chans[i], 2.0); } } static void zoom_in_callback(GtkWidget *w, gpointer info) { snd_info *sp; sp = any_selected_sound(); if (sp) { int i; for (i = 0; i < sp->nchans; i++) zx_incremented(sp->chans[i], 0.5); } } static void goto_start_callback(GtkWidget *w, gpointer info) { snd_info *sp; sp = any_selected_sound(); if (sp) { int i; for (i = 0; i < sp->nchans; i++) set_x_axis_x0x1(sp->chans[i], 0.0, sp->chans[i]->axis->x1 - sp->chans[i]->axis->x0); } } static void go_back_callback(GtkWidget *w, gpointer info) { snd_info *sp; sp = any_selected_sound(); if (sp) { int i; for (i = 0; i < sp->nchans; i++) sx_incremented(sp->chans[i], -1.0); } } static void go_forward_callback(GtkWidget *w, gpointer info) { snd_info *sp; sp = any_selected_sound(); if (sp) { int i; for (i = 0; i < sp->nchans; i++) sx_incremented(sp->chans[i], 1.0); } } static void goto_end_callback(GtkWidget *w, gpointer info) { snd_info *sp; sp = any_selected_sound(); if (sp) { int i; for (i = 0; i < sp->nchans; i++) set_x_axis_x0x1(sp->chans[i], sp->chans[i]->axis->xmax - sp->chans[i]->axis->x1 + sp->chans[i]->axis->x0, sp->chans[i]->axis->xmax); } } static gboolean close_selected_tooltip(GtkWidget *w, gint x, gint y, gboolean keyboard_tip, GtkTooltip *tooltip, gpointer data) { snd_info *sp; sp = any_selected_sound(); if (sp) { char *tip; if ((!ask_about_unsaved_edits(ss)) && (has_unsaved_edits(sp))) tip = mus_format("close %s (throwing away the current edits)", sp->short_filename); else tip = mus_format("close %s", sp->short_filename); gtk_tooltip_set_text(tooltip, tip); free(tip); } else gtk_tooltip_set_text(tooltip, "close the current sound"); /* gtk_tooltip_set_markup(tooltip, "close the current sound"); * this is almost right -- the padding (or margin?) is still in the ugly yellow color * how to set that color?? */ return(true); } static gboolean save_selected_tooltip(GtkWidget *w, gint x, gint y, gboolean keyboard_tip, GtkTooltip *tooltip, gpointer data) { snd_info *sp; sp = any_selected_sound(); if (sp) { char *tip; if (has_unsaved_edits(sp)) tip = mus_format("save edits to %s (overwriting)", sp->short_filename); else tip = mus_format("save %s, but it has no unsaved edits", sp->short_filename); gtk_tooltip_set_text(tooltip, tip); free(tip); } else gtk_tooltip_set_text(tooltip, "save the current sound"); return(true); } #if 0 static gboolean save_as_tooltip(GtkWidget *w, gint x, gint y, gboolean keyboard_tip, GtkTooltip *tooltip, gpointer data) { snd_info *sp; sp = any_selected_sound(); if (sp) { char *tip; tip = mus_format("save %s in a new file", sp->short_filename); gtk_tooltip_set_text(tooltip, tip); free(tip); } else gtk_tooltip_set_text(tooltip, "save the current sound in a new file"); return(true); } #endif static gboolean revert_selected_tooltip(GtkWidget *w, gint x, gint y, gboolean keyboard_tip, GtkTooltip *tooltip, gpointer data) { snd_info *sp; sp = any_selected_sound(); if (sp) { char *tip; if (has_unsaved_edits(sp)) tip = mus_format("return %s to its saved state, undoing the current edits", sp->short_filename); else tip = mus_format("undo all edits in %s, but it has no edits", sp->short_filename); gtk_tooltip_set_text(tooltip, tip); free(tip); } else gtk_tooltip_set_text(tooltip, "undo all edits in the current sound"); return(true); } static gboolean undo_selected_tooltip(GtkWidget *w, gint x, gint y, gboolean keyboard_tip, GtkTooltip *tooltip, gpointer data) { chan_info *cp; cp = current_channel(); if (cp) { snd_info *sp; char *tip; sp = cp->sound; if (cp->edit_ctr > 0) { if (syncd_channels(sp->sync) <= 1) { if (sp->nchans == 1) tip = mus_format("undo the last edit to %s", sp->short_filename); else tip = mus_format("undo the last edit to channel %d of %s", cp->chan, sp->short_filename); } else tip = mus_format("undo the last edit to %s (and also in anything sync'd with it)", sp->short_filename); } else { if (sp->nchans == 1) tip = mus_format("undo an edit to %s, but it has no edits", sp->short_filename); else tip = mus_format("undo an edit to channel %d of %s, but it has no edits", cp->chan, sp->short_filename); } gtk_tooltip_set_text(tooltip, tip); free(tip); } else gtk_tooltip_set_text(tooltip, "undo the last edit to the current channel"); return(true); } #if 0 static gboolean redo_selected_tooltip(GtkWidget *w, gint x, gint y, gboolean keyboard_tip, GtkTooltip *tooltip, gpointer data) { chan_info *cp; cp = current_channel(); if (cp) { snd_info *sp; char *tip; sp = cp->sound; if ((cp->edit_size > cp->edit_ctr) && (cp->edits[cp->edit_ctr + 1])) { if (syncd_channels(sp->sync) <= 1) { if (sp->nchans == 1) tip = mus_format("redo one edit to %s", sp->short_filename); else tip = mus_format("redo one edit to channel %d of %s", cp->chan, sp->short_filename); } else tip = mus_format("redo one edit to %s (and anything sync'd with it)", sp->short_filename); } else { if (sp->nchans == 1) tip = mus_format("redo one edit %s, but it has no %sedits", sp->short_filename, (cp->edit_ctr == 0) ? "" : "redoable "); else tip = mus_format("redo one edit to channel %d of %s, but it has no %sedits", cp->chan, sp->short_filename, (cp->edit_ctr == 0) ? "" : "redoable "); } gtk_tooltip_set_text(tooltip, tip); free(tip); } else gtk_tooltip_set_text(tooltip, "redo one edit in the current channel"); return(true); } #endif #if WITH_AUDIO static gboolean play_selected_tooltip(GtkWidget *w, gint x, gint y, gboolean keyboard_tip, GtkTooltip *tooltip, gpointer data) { snd_info *sp; sp = any_selected_sound(); if (sp) { char *tip; tip = mus_format("play %s from the top", sp->short_filename); gtk_tooltip_set_text(tooltip, tip); free(tip); } else gtk_tooltip_set_text(tooltip, "play the current sound"); return(true); } static gboolean play_selected_from_cursor_tooltip(GtkWidget *w, gint x, gint y, gboolean keyboard_tip, GtkTooltip *tooltip, gpointer data) { snd_info *sp; sp = any_selected_sound(); if (sp) { char *tip; chan_info *cp; cp = any_selected_channel(sp); tip = mus_format("play %s from the cursor (%.3f seconds in)", sp->short_filename, ((double)cursor_sample(cp)) / ((double)(snd_srate(sp)))); gtk_tooltip_set_text(tooltip, tip); free(tip); } else gtk_tooltip_set_text(tooltip, "play the current sound from the cursor"); return(true); } #endif static gboolean full_dur_tooltip(GtkWidget *w, gint x, gint y, gboolean keyboard_tip, GtkTooltip *tooltip, gpointer data) { snd_info *sp; sp = any_selected_sound(); if (sp) { char *tip; tip = mus_format("show all of %s", sp->short_filename); gtk_tooltip_set_text(tooltip, tip); free(tip); } else gtk_tooltip_set_text(tooltip, "show all of the current sound"); return(true); } static gboolean zoom_out_tooltip(GtkWidget *w, gint x, gint y, gboolean keyboard_tip, GtkTooltip *tooltip, gpointer data) { snd_info *sp; sp = any_selected_sound(); if (sp) { char *tip; tip = mus_format("show more of %s (zoom out)", sp->short_filename); gtk_tooltip_set_text(tooltip, tip); free(tip); } else gtk_tooltip_set_text(tooltip, "show more of the current sound (zoom out)"); return(true); } static gboolean zoom_in_tooltip(GtkWidget *w, gint x, gint y, gboolean keyboard_tip, GtkTooltip *tooltip, gpointer data) { snd_info *sp; sp = any_selected_sound(); if (sp) { char *tip; tip = mus_format("show less of %s (zoom in)", sp->short_filename); gtk_tooltip_set_text(tooltip, tip); free(tip); } else gtk_tooltip_set_text(tooltip, "show less of the current sound (zoom in)"); return(true); } static gboolean goto_start_tooltip(GtkWidget *w, gint x, gint y, gboolean keyboard_tip, GtkTooltip *tooltip, gpointer data) { snd_info *sp; sp = any_selected_sound(); if (sp) { char *tip; tip = mus_format("go to the beginning of %s", sp->short_filename); gtk_tooltip_set_text(tooltip, tip); free(tip); } else gtk_tooltip_set_text(tooltip, "go to the beginning of the current sound"); return(true); } static gboolean goto_end_tooltip(GtkWidget *w, gint x, gint y, gboolean keyboard_tip, GtkTooltip *tooltip, gpointer data) { snd_info *sp; sp = any_selected_sound(); if (sp) { char *tip; tip = mus_format("go to the end of %s", sp->short_filename); gtk_tooltip_set_text(tooltip, tip); free(tip); } else gtk_tooltip_set_text(tooltip, "go to the end of the current sound"); return(true); } static gboolean go_back_tooltip(GtkWidget *w, gint x, gint y, gboolean keyboard_tip, GtkTooltip *tooltip, gpointer data) { snd_info *sp; sp = any_selected_sound(); if (sp) { char *tip; tip = mus_format("go back one window in %s", sp->short_filename); gtk_tooltip_set_text(tooltip, tip); free(tip); } else gtk_tooltip_set_text(tooltip, "go back one window in the current sound"); return(true); } static gboolean go_forward_tooltip(GtkWidget *w, gint x, gint y, gboolean keyboard_tip, GtkTooltip *tooltip, gpointer data) { snd_info *sp; sp = any_selected_sound(); if (sp) { char *tip; tip = mus_format("go forward one window in %s", sp->short_filename); gtk_tooltip_set_text(tooltip, tip); free(tip); } else gtk_tooltip_set_text(tooltip, "go forward one window in the current sound"); return(true); } #if 0 static gboolean unselect_all_tooltip(GtkWidget *w, gint x, gint y, gboolean keyboard_tip, GtkTooltip *tooltip, gpointer data) { if (selection_is_active()) gtk_tooltip_set_text(tooltip, "unselect the currently selected portion"); else gtk_tooltip_set_text(tooltip, "when something is selected, this unselects it"); return(true); } #endif static gboolean delete_selection_tooltip(GtkWidget *w, gint x, gint y, gboolean keyboard_tip, GtkTooltip *tooltip, gpointer data) { if (selection_is_active()) gtk_tooltip_set_text(tooltip, "delete the currently selected portion"); else gtk_tooltip_set_text(tooltip, "when something is selected, this deletes it"); return(true); } static gboolean insert_selection_tooltip(GtkWidget *w, gint x, gint y, gboolean keyboard_tip, GtkTooltip *tooltip, gpointer data) { if (selection_is_active()) { snd_info *sp; char *tip; chan_info *cp; sp = any_selected_sound(); cp = any_selected_channel(sp); tip = mus_format("insert the selected portion at the cursor (at time %.3f) in %s", ((double)cursor_sample(cp)) / ((double)(snd_srate(sp))), sp->short_filename); gtk_tooltip_set_text(tooltip, tip); free(tip); } else gtk_tooltip_set_text(tooltip, "when something is selected, this inserts it at the cursor in the current sound"); return(true); } static GtkWidget *toolbar = NULL; void show_toolbar(void) { if (!toolbar) { GtkWidget *w; toolbar = gtk_toolbar_new(); #if GTK_CHECK_VERSION(3, 0, 0) add_toolbar_style(toolbar); gtk_toolbar_set_icon_size(GTK_TOOLBAR(toolbar), GTK_ICON_SIZE_SMALL_TOOLBAR); #endif gtk_box_pack_start(GTK_BOX(MAIN_PANE(ss)), toolbar, false, false, 0); /* MAIN_PANE = top level vbox */ gtk_box_reorder_child(GTK_BOX(MAIN_PANE(ss)), toolbar, 1); /* put toolbar just under the top level menubar */ add_to_toolbar(toolbar, ICON_NEW, "open a new sound", (GCallback)file_new_callback); add_to_toolbar(toolbar, ICON_OPEN, "open a sound", (GCallback)file_open_callback); w = add_to_toolbar(toolbar, ICON_SAVE, "save current sound, overwriting", (GCallback)file_save_callback); g_signal_connect(w, "query-tooltip", G_CALLBACK(save_selected_tooltip), NULL); #if 0 w = add_to_toolbar(toolbar, ICON_SAVE_AS, "save selected sound in new file", (GCallback)file_save_as_callback); g_signal_connect(w, "query-tooltip", G_CALLBACK(save_as_tooltip), NULL); #endif w = add_to_toolbar(toolbar, ICON_REVERT_TO_SAVED, "revert to saved", (GCallback)file_revert_callback); g_signal_connect(w, "query-tooltip", G_CALLBACK(revert_selected_tooltip), NULL); w = add_to_toolbar(toolbar, ICON_UNDO, "undo edit", (GCallback)edit_undo_callback); g_signal_connect(w, "query-tooltip", G_CALLBACK(undo_selected_tooltip), NULL); #if 0 w = add_to_toolbar(toolbar, ICON_REDO, "redo last (undone) edit", (GCallback)edit_redo_callback); g_signal_connect(w, "query-tooltip", G_CALLBACK(redo_selected_tooltip), NULL); #endif w = add_to_toolbar(toolbar, ICON_CLOSE, "close selected sound", (GCallback)file_close_callback); g_signal_connect(w, "query-tooltip", G_CALLBACK(close_selected_tooltip), NULL); add_separator_to_toolbar(toolbar); #if WITH_AUDIO w = add_to_toolbar(toolbar, ICON_MEDIA_PLAY, "play from the start", (GCallback)play_from_start_callback); g_signal_connect(w, "query-tooltip", G_CALLBACK(play_selected_tooltip), NULL); w = add_to_toolbar(toolbar, ICON_MEDIA_FORWARD, "play from the cursor", (GCallback)play_from_cursor_callback); g_signal_connect(w, "query-tooltip", G_CALLBACK(play_selected_from_cursor_tooltip), NULL); add_to_toolbar(toolbar, ICON_MEDIA_STOP, "stop playing", (GCallback)stop_playing_callback); add_separator_to_toolbar(toolbar); #endif w = add_to_toolbar(toolbar, ICON_FULLSCREEN, "show full sound", (GCallback)full_dur_callback); g_signal_connect(w, "query-tooltip", G_CALLBACK(full_dur_tooltip), NULL); w = add_to_toolbar(toolbar, ICON_ZOOM_OUT, "zoom out", (GCallback)zoom_out_callback); g_signal_connect(w, "query-tooltip", G_CALLBACK(zoom_out_tooltip), NULL); w = add_to_toolbar(toolbar, ICON_ZOOM_IN, "zoom in", (GCallback)zoom_in_callback); g_signal_connect(w, "query-tooltip", G_CALLBACK(zoom_in_tooltip), NULL); w = add_to_toolbar(toolbar, ICON_GOTO_FIRST, "go to start of sound", (GCallback)goto_start_callback); g_signal_connect(w, "query-tooltip", G_CALLBACK(goto_start_tooltip), NULL); w = add_to_toolbar(toolbar, ICON_GO_BACK, "go back a window", (GCallback)go_back_callback); g_signal_connect(w, "query-tooltip", G_CALLBACK(go_back_tooltip), NULL); w = add_to_toolbar(toolbar, ICON_GO_FORWARD, "go forward a window", (GCallback)go_forward_callback); g_signal_connect(w, "query-tooltip", G_CALLBACK(go_forward_tooltip), NULL); w = add_to_toolbar(toolbar, ICON_GOTO_LAST, "go to end of sound", (GCallback)goto_end_callback); g_signal_connect(w, "query-tooltip", G_CALLBACK(goto_end_tooltip), NULL); add_separator_to_toolbar(toolbar); #if 0 add_to_toolbar(toolbar, ICON_SELECT_ALL, "select all of the current sound",(GCallback)edit_select_all_callback); w = add_to_toolbar(toolbar, ICON_CLEAR, "unselect everything", (GCallback)edit_unselect_callback); g_signal_connect(w, "query-tooltip", G_CALLBACK(unselect_all_tooltip), NULL); #endif w = add_to_toolbar(toolbar, ICON_CUT, "delete the selected portion",(GCallback)edit_cut_callback); g_signal_connect(w, "query-tooltip", G_CALLBACK(delete_selection_tooltip), NULL); w = add_to_toolbar(toolbar, ICON_PASTE, "insert the selection at the cursor", (GCallback)edit_paste_callback); g_signal_connect(w, "query-tooltip", G_CALLBACK(insert_selection_tooltip), NULL); add_separator_to_toolbar(toolbar); #if (!WITH_AUDIO) add_to_toolbar(toolbar, ICON_PREFERENCES, "open the preferences dialog",(GCallback)options_preferences_callback); #endif add_to_toolbar(toolbar, ICON_CANCEL, "stop everything", (GCallback)stop_everything_callback); add_to_toolbar(toolbar, ICON_QUIT, "exit Snd", (GCallback)file_exit_callback); } gtk_widget_show(toolbar); } void hide_toolbar(void) { if (toolbar) gtk_widget_hide(toolbar); } /* ---------------- tie in menu stuff to extlang ---------------- */ static GtkWidget *added_menus[MAX_MAIN_MENUS]; static int new_menu = 5; static GtkWidget **added_options = NULL; static char **added_options_names = NULL; static int *added_options_menus = NULL; static int added_options_size = 0; static int added_options_pos = 0; static int *added_options_callb = NULL; enum {FILE_MENU, EDIT_MENU, VIEW_MENU, OPTIONS_MENU, HELP_MENU}; #define INVALID_MENU -1 static int callb2option(int callb) { int i; for (i = 0; i < added_options_pos; i++) if (added_options_callb[i] == callb) return(i); return(-1); } static void menu_callback(GtkWidget *w, gpointer info) { int callb, opt; callb = get_user_int_data(G_OBJECT(w)); opt = callb2option(callb); if (opt != -1) g_menu_callback(callb); } GtkWidget *menu_widget(int which_menu) { switch (which_menu) { case FILE_MENU: return(file_menu); break; case EDIT_MENU: return(edit_menu); break; case VIEW_MENU: return(view_menu); break; case OPTIONS_MENU: return(options_menu); break; case HELP_MENU: return(help_menu); break; default: return(added_menus[which_menu]); break; } return(NULL); } static void add_option(GtkWidget *w, int which_menu, const char *label, int callb) { if (added_options_pos == added_options_size) { added_options_size += 8; if (added_options_pos == 0) { added_options = (GtkWidget **)calloc(added_options_size, sizeof(GtkWidget *)); added_options_names = (char **)calloc(added_options_size, sizeof(char *)); added_options_menus = (int *)calloc(added_options_size, sizeof(int)); added_options_callb = (int *)calloc(added_options_size, sizeof(int)); } else { int i; added_options = (GtkWidget **)realloc(added_options, added_options_size * sizeof(GtkWidget *)); added_options_names = (char **)realloc(added_options_names, added_options_size * sizeof(char *)); added_options_menus = (int *)realloc(added_options_menus, added_options_size * sizeof(int)); added_options_callb = (int *)realloc(added_options_callb, added_options_size * sizeof(int)); for (i = added_options_pos; i < added_options_size; i++) { added_options[i] = NULL; added_options_callb[i] = 0; } } } added_options[added_options_pos] = w; added_options_menus[added_options_pos] = which_menu; added_options_names[added_options_pos] = mus_strdup(label); added_options_callb[added_options_pos] = callb; added_options_pos++; } static int remove_option(int which_menu, const char *label) { int i; for (i = 0; i < added_options_pos; i++) if ((added_options_menus[i] == which_menu) && (mus_strcmp(label, added_options_names[i])) && (added_options[i])) { unprotect_callback(added_options_callb[i]); gtk_widget_hide(added_options[i]); /* destroy here causes segfault in gtk2? */ added_options[i] = NULL; added_options_menus[i] = -1; free(added_options_names[i]); added_options_names[i] = NULL; return(0); } for (i = 0; i < NUM_MENU_WIDGETS; i++) if ((ml[i]) && (strcmp(label, ml[i]) == 0)) { gtk_widget_hide(ss->mw[i]); return(0); } return(INVALID_MENU); } int g_add_to_main_menu(const char *label, int slot) { GtkWidget *m, *mc; if (new_menu >= MAX_MAIN_MENUS) return(INVALID_MENU); m = gtk_menu_item_new_with_label(label); gtk_menu_shell_append(GTK_MENU_SHELL(main_menu), m); gtk_widget_show(m); set_user_int_data(G_OBJECT(m), slot); if (slot >= 0) { SG_SIGNAL_CONNECT(m, "activate", menu_callback, NULL); add_option(m, new_menu + 1, label, slot); } mc = gtk_menu_new(); add_menu_style(mc); gtk_menu_item_set_submenu(GTK_MENU_ITEM(m), mc); new_menu++; added_menus[new_menu] = m; /* was mc -- 1-Mar-06 */ return(new_menu); } GtkWidget *get_help_menu_widget(void) { return(help_cascade_menu); } GtkWidget *g_add_to_menu(int which_menu, const char *label, int callb, int position) { GtkWidget *m, *menw; switch (which_menu) { case FILE_MENU: menw = file_cascade_menu; break; case EDIT_MENU: menw = edit_cascade_menu; break; case VIEW_MENU: menw = view_cascade_menu; break; case OPTIONS_MENU: menw = options_cascade_menu; break; case HELP_MENU: menw = help_cascade_menu; break; default: if (which_menu < MAX_MAIN_MENUS) menw = gtk_menu_item_get_submenu(GTK_MENU_ITEM(added_menus[which_menu])); else return(NULL); break; } if (label) m = gtk_menu_item_new_with_label(label); else m = gtk_menu_item_new(); if (position >= 0) gtk_menu_shell_insert(GTK_MENU_SHELL(menw), m, position); else gtk_menu_shell_append(GTK_MENU_SHELL(menw), m); gtk_widget_show(m); if (label) { set_user_int_data(G_OBJECT(m), callb); SG_SIGNAL_CONNECT(m, "activate", menu_callback, NULL); add_option(m, which_menu, label, callb); } return(m); } int g_remove_from_menu(int which_menu, const char *label) { return(remove_option(which_menu, label)); } static Xen g_menu_widgets(void) { #define H_menu_widgets "(" S_menu_widgets "): a list of the top level menu widgets: ((0)main (1)file (2)edit (3)view (4)options (5)help)" return(Xen_cons(Xen_wrap_widget(main_menu), Xen_cons(Xen_wrap_widget(file_menu), Xen_cons(Xen_wrap_widget(edit_menu), Xen_cons(Xen_wrap_widget(view_menu), Xen_cons(Xen_wrap_widget(options_menu), Xen_cons(Xen_wrap_widget(help_menu), Xen_empty_list))))))); } Xen_wrap_no_args(g_menu_widgets_w, g_menu_widgets) void g_init_gxmenu(void) { Xen_define_procedure(S_menu_widgets, g_menu_widgets_w, 0, 0, 0, H_menu_widgets); } snd-16.1/snd-help.c0000644000076400007640000042552712605550141012227 0ustar bilbil#include "snd.h" #include "sndlib-strings.h" #include "clm-strings.h" static const char **snd_xrefs(const char *topic); static const char **snd_xref_urls(const char *topic); static char **snd_itoa_strs = NULL; static int snd_itoa_ctr = 0, snd_itoa_size = 0; static char *snd_itoa(int n) { char *str; if (snd_itoa_strs == NULL) { snd_itoa_size = 32; snd_itoa_strs = (char **)calloc(snd_itoa_size, sizeof(char *)); } else { if (snd_itoa_ctr >= snd_itoa_size) { int i; snd_itoa_size += 32; snd_itoa_strs = (char **)realloc(snd_itoa_strs, snd_itoa_size * sizeof(char *)); for (i = snd_itoa_ctr; i < snd_itoa_size; i++) snd_itoa_strs[i] = NULL; } } str = (char *)calloc(LABEL_BUFFER_SIZE, sizeof(char)); snprintf(str, LABEL_BUFFER_SIZE, "%d", n); snd_itoa_strs[snd_itoa_ctr++] = str; return(str); } static void free_snd_itoa(void) { int i; for (i = 0; i < snd_itoa_ctr; i++) if (snd_itoa_strs[i]) { free(snd_itoa_strs[i]); snd_itoa_strs[i] = NULL; } snd_itoa_ctr = 0; } static char *vstrcat(const char *arg1, ...) { char *buf; va_list ap; int len = 0; char *str; len = strlen(arg1); va_start(ap, arg1); while ((str = va_arg(ap, char *))) len += strlen(str); va_end(ap); buf = (char *)calloc(len + 32, sizeof(char)); strcat(buf, arg1); va_start(ap, arg1); while ((str = va_arg(ap, char *))) strcat(buf, str); va_end(ap); return(buf); } static const char *main_snd_xrefs[16] = { "{CLM}: sound synthesis", "{CM}: algorithmic composition", "{CMN}: music notation", "{Ruby}: extension language", "{Forth}: extension language", "{s7}: extension language", "{Emacs}: Snd as Emacs subjob", "{Sndlib}: underlying sound support library", "{Scripting}: Snd with no GUI", "{Motif}: Motif extensions", "{Gtk}: Gtk extensions", "{Ladspa}: plugins", "{Multiprecision arithmetic}: libgmp and friends", NULL }; static const char *main_snd_xref_urls[16] = { "grfsnd.html#sndwithclm", "grfsnd.html#sndwithcm", "sndscm.html#musglyphs", "grfsnd.html#sndandruby", "grfsnd.html#sndandforth", "grfsnd.html#sndands7", "grfsnd.html#emacssnd", "sndlib.html#introduction", "grfsnd.html#sndwithnogui", "grfsnd.html#sndwithmotif", "grfsnd.html#sndwithgtk", "grfsnd.html#sndandladspa", "grfsnd.html#sndandgmp", NULL, }; static void main_snd_help(const char *subject, ...) { va_list ap; char *helpstr; snd_help_with_xrefs(subject, "", WITHOUT_WORD_WRAP, main_snd_xrefs, main_snd_xref_urls); va_start(ap, subject); while ((helpstr = va_arg(ap, char *))) snd_help_append(helpstr); va_end(ap); snd_help_back_to_top(); } #if USE_MOTIF #include #include #endif #if HAVE_LADSPA #include #endif #if HAVE_FFTW3 #include #endif #if USE_MOTIF #define XM_VERSION_NAME "xm-version" #else #define XM_VERSION_NAME "xg-version" #endif #if WITH_GMP #include #include #include #endif static char *xm_version(void) { Xen xm_val = Xen_false; #if HAVE_SCHEME #if USE_MOTIF xm_val = Xen_eval_C_string("(and (defined? 'xm-version) xm-version)"); #else #if USE_GTK xm_val = Xen_eval_C_string("(and (defined? 'xg-version) xg-version)"); #endif #endif #endif #if HAVE_FORTH xm_val = Xen_variable_ref(XM_VERSION_NAME); #endif #if HAVE_RUBY #if USE_MOTIF if (rb_const_defined(rb_cObject, rb_intern("Xm_Version"))) xm_val = Xen_eval_C_string("Xm_Version"); #else #if USE_GTK if (rb_const_defined(rb_cObject, rb_intern("Xg_Version"))) xm_val = Xen_eval_C_string("Xg_Version"); #endif #endif #endif if (Xen_is_string(xm_val)) { char *version = NULL; version = (char *)calloc(32, sizeof(char)); snprintf(version, 32, "\n %s: %s", #if USE_MOTIF "xm", #else "xg", #endif Xen_string_to_C_string(xm_val)); if (snd_itoa_ctr < snd_itoa_size) snd_itoa_strs[snd_itoa_ctr++] = version; return(version); } return(mus_strdup(" ")); /* not null because that breaks the sequence for --version (xm-version not defined by that point) */ } #if HAVE_GL void Init_libgl(void); static char *gl_version(void) { Xen gl_val = Xen_false; Init_libgl(); /* define the version string, if ./snd --version */ #if HAVE_SCHEME gl_val = Xen_eval_C_string("(and (provided? 'gl) gl-version)"); /* this refers to gl.c, not the GL library */ #endif #if HAVE_RUBY if (rb_const_defined(rb_cObject, rb_intern("Gl_Version"))) gl_val = Xen_eval_C_string("Gl_Version"); #endif #if HAVE_FORTH if (fth_provided_p("gl")) gl_val = Xen_variable_ref("gl-version"); #endif if (Xen_is_string(gl_val)) { char *version = NULL; version = (char *)calloc(32, sizeof(char)); snprintf(version, 32, " (snd gl: %s)", Xen_string_to_C_string(gl_val)); if (snd_itoa_ctr < snd_itoa_size) snd_itoa_strs[snd_itoa_ctr++] = version; return(version); } return(mus_strdup(" ")); } #if WITH_GL2PS char *gl2ps_version(void); /* snd-print.c */ #endif static char *glx_version(void) { #if USE_MOTIF #define VERSION_SIZE 128 char *version = NULL; if ((ss->dialogs == NULL) || /* snd --help for example */ (MAIN_DISPLAY(ss) == NULL)) return(mus_strdup(" ")); version = (char *)calloc(VERSION_SIZE, sizeof(char)); if (ss->cx) { glXMakeCurrent(MAIN_DISPLAY(ss), XtWindow(ss->mainshell), ss->cx); snprintf(version, VERSION_SIZE, " %s", glGetString(GL_VERSION)); } else { int major = 0, minor = 0; glXQueryVersion(MAIN_DISPLAY(ss), &major, &minor); snprintf(version, VERSION_SIZE, " %d.%d", major, minor); } if (snd_itoa_ctr < snd_itoa_size) snd_itoa_strs[snd_itoa_ctr++] = version; return(version); #else #if USE_GTK && (0) /* TODO: need to gdk_gl_context_make_current then gdk_gl_context_get_version or better gtk_gl_area_make_current */ #define VERSION_SIZE 128 char *version = NULL; int major, minor; if ((ss->dialogs == NULL) || (MAIN_DISPLAY(ss) == NULL)) /* TODO: MAIN_DISPLAY needs to be the gl context here (it's not otherwise used in gtk snd) */ return(mus_strdup(" ")); version = (char *)calloc(VERSION_SIZE, sizeof(char)); gdk_gl_context_get_version(MAIN_DISPLAY(ss), &major, &minor); snprintf(version, VERSION_SIZE, " %d.%d", major, minor); if (snd_itoa_ctr < snd_itoa_size) snd_itoa_strs[snd_itoa_ctr++] = version; return(version); #else return(mus_strdup(" ")); #endif #endif } #endif #if HAVE_GSL #include #endif #ifndef _MSC_VER #include #endif char *version_info(void) { char *result, *xversion = NULL, *consistent = NULL; #if HAVE_GL && WITH_GL2PS char *gl2ps_name = NULL; #endif #ifndef _MSC_VER int uname_ok; struct utsname uts; uname_ok = uname(&uts); /* 0=success */ #endif snd_itoa_ctr = 0; xversion = xen_version(); result = vstrcat( "This is Snd version ", SND_VERSION, " of ", SND_DATE, ":\n ", xversion, "\n ", mus_audio_moniker(), "\n Sndlib ", snd_itoa(SNDLIB_VERSION), ".", snd_itoa(SNDLIB_REVISION), " (", SNDLIB_DATE, ")", "\n CLM ", snd_itoa(MUS_VERSION), ".", snd_itoa(MUS_REVISION), " (", MUS_DATE, ")", #if HAVE_GSL "\n GSL", #ifdef GSL_VERSION " ", GSL_VERSION, #endif #endif #if HAVE_FFTW3 "\n ", fftw_version, #endif #if USE_MOTIF "\n Motif ", snd_itoa(XmVERSION), ".", snd_itoa(XmREVISION), ".", snd_itoa(XmUPDATE_LEVEL), " X", snd_itoa(X_PROTOCOL), "R", snd_itoa(XT_REVISION), #endif #if USE_GTK "\n Gtk+ ", snd_itoa(GTK_MAJOR_VERSION), ".", snd_itoa(GTK_MINOR_VERSION), ".", snd_itoa(GTK_MICRO_VERSION), ", Glib ", snd_itoa(GLIB_MAJOR_VERSION), ".", snd_itoa(GLIB_MINOR_VERSION), ".", snd_itoa(GLIB_MICRO_VERSION), #ifdef PANGO_VERSION_MAJOR ", Pango ", snd_itoa(PANGO_VERSION_MAJOR), ".", snd_itoa(PANGO_VERSION_MINOR), ".", snd_itoa(PANGO_VERSION_MICRO), #endif #ifdef CAIRO_VERSION_MAJOR ", Cairo ", snd_itoa(CAIRO_VERSION_MAJOR), ".", snd_itoa(CAIRO_VERSION_MINOR), ".", snd_itoa(CAIRO_VERSION_MICRO), #endif #endif xm_version(), /* omitted if --version/--help because the init procs haven't run at that point */ #if HAVE_GL "\n OpenGL", glx_version(), gl_version(), #if WITH_GL2PS ", ", gl2ps_name = gl2ps_version(), #endif #endif #if (!USE_MOTIF) && (!USE_GTK) "\n without any graphics system", #endif #if USE_MOTIF "\n Xpm ", snd_itoa(XpmFormat), ".", snd_itoa(XpmVersion), ".", snd_itoa(XpmRevision), #endif #if HAVE_LADSPA "\n Ladspa: ", #ifdef LADSPA_VERSION LADSPA_VERSION, #else "1.0", #endif #endif #if WITH_GMP "\n gmp: ", gmp_version, ", mpfr: ", mpfr_get_version(), ", mpc: ", mpc_get_version(), #endif #ifdef __DATE__ "\n Compiled ", __DATE__, " ", __TIME__, #endif #ifdef __VERSION__ #ifndef __cplusplus "\n C: ", #else "\n C++: ", #endif __VERSION__, #endif "\n", #ifndef _MSC_VER (uname_ok == 0) ? " " : "", (uname_ok == 0) ? uts.sysname : "", (uname_ok == 0) ? " " : "", (uname_ok == 0) ? uts.release : "", (uname_ok == 0) ? " " : "", (uname_ok == 0) ? uts.machine : "", (uname_ok == 0) ? "\n" : "", #endif NULL); free_snd_itoa(); if (xversion) free(xversion); /* calloc in xen.c */ if (consistent) free(consistent); #if HAVE_GL && WITH_GL2PS if (gl2ps_name) free(gl2ps_name); #endif return(result); } void about_snd_help(void) { char *info = NULL, *features = NULL; #if HAVE_RUBY features = word_wrap(Xen_object_to_C_string(Xen_eval_C_string((char *)"$\".join(' ')")), 400); #endif #if HAVE_FORTH features = word_wrap(Xen_object_to_C_string(Xen_eval_C_string("*features*")), 400); #endif #if HAVE_SCHEME { char *temp = NULL; features = word_wrap(temp = Xen_object_to_C_string(Xen_eval_C_string("*features*")), 400); if (temp) free(temp); } #endif info = version_info(); /* -------------------------------------------------------------------------------- */ main_snd_help("Snd is a sound editor.", info, #if HAVE_RUBY "\n $LOADED_FEATURES: \n", features, "\n\n", #endif #if HAVE_FORTH "\n *features*:\n ", features, "\n\n", #endif #if HAVE_SCHEME "\n *features*:\n '", features, "\n\n", #endif #if (!HAVE_EXTENSION_LANGUAGE) "\n", #endif "Please send bug reports or suggestions to bil@ccrma.stanford.edu.", NULL); if (info) free(info); if (features) free(features); } /* ---------------- help menu help texts ---------------- */ static bool append_key_help(const char *name, int key, int state, bool cx_extended, bool first_time) { int pos; pos = in_keymap(key, state, cx_extended); if (pos != -1) { char *msg, *tmp = NULL; msg = mus_format("%s%s is bound to %s", (first_time) ? "\n\ncurrently " : "\n ", name, tmp = key_description(key, state, cx_extended)); snd_help_append(msg); free(msg); if (tmp) free(tmp); return(false); } return(first_time); } /* ---------------- Find ---------------- */ void find_help(void) { #if HAVE_SCHEME #define basic_example "(lambda (y) (> y 0.1))" #define find_channel_example " >(find-channel (lambda (y) (> y .1)))\n (#t 4423)" #define count_matches_example " >(count-matches (lambda (y) (> y .1)))\n 2851" #define search_procedure_example " >(set! (search-procedure) (lambda (y) (> y .1)))" #endif #if HAVE_RUBY #define basic_example "lambda do |y| y > 0.1 end" #define find_channel_example " >find_channel(lambda do |y| y > 0.1 end)\n [true, 4423]" #define count_matches_example " >count_matches(lambda do |y| y > 0.1 end)\n 2851" #define search_procedure_example " >set_search_procedure(lambda do |y| y > 0.1 end)" #endif #if HAVE_FORTH #define basic_example "lambda: <{ y }> y 0.1 f> ;" #define find_channel_example " >lambda: <{ y }> 0.1 y f< ; find-channel\n '( #t 4423 )" #define count_matches_example " >lambda: <{ y }> 0.1 y f< ; count-matches\n 2851" #define search_procedure_example " >lambda: <{ y }> 0.1 y f< ; set-search-procedure" #endif snd_help_with_xrefs(I_FIND, #if HAVE_EXTENSION_LANGUAGE "Searches in Snd refer to the sound data. When you type \ C-s, the find dialog is activated and you are asked for the search expression. \ The expression is a function that takes one argument, the current sample value, and returns " PROC_TRUE " when it finds a match. \ To look for the next sample that is greater than .1, " basic_example ". The cursor then moves \ to that sample, if any. Successive C-s's continue the search starting from the next sample.\ \n\n\ The primary searching function is:\n\ \n\ " S_find_channel " (proc :optional (sample 0) snd chn edpos)\n\ This function finds the sample that satisfies the function 'proc'. \n\ 'sample' determines where to start the search. \n\ " find_channel_example "\n\ \n\ Closely related is:\n\ \n\ " S_count_matches " (proc :optional (sample 0) snd chn edpos)\n\ This returns how many samples satisfy the function 'proc'.\n\ " count_matches_example "\n\ \n\ To find whether a given sound is currently open in Snd, use:\n\ \n\ " S_find_sound " (filename :optional (nth 0))\n\ " S_find_sound " returns the index of 'filename' or " PROC_FALSE ".\n\ \n\ The current search procedure (for the Edit:Find dialog) is:\n\ \n\ " S_search_procedure " (:optional snd)\n\ " search_procedure_example "\n\ ", #else "Searches in Snd depend completely on the extension language. Since none is loaded,\ the searching mechanisms are disabled.", #endif WITH_WORD_WRAP, snd_xrefs("Search"), snd_xref_urls("Search")); append_key_help("C-s", snd_K_s, snd_ControlMask, false, true); } /* ---------------- Undo ---------------- */ void undo_help(void) { #if HAVE_SCHEME #define H_undo S_undo #define H_redo S_redo #define edit_position_example "(set! (edit-position) 0) ; revert channel" #endif #if HAVE_RUBY #define H_undo "undo_edit" #define H_redo "redo_edit" #define edit_position_example "set_edit_position(0) # revert channel" #endif #if HAVE_FORTH #define H_undo S_undo #define H_redo S_redo #define edit_position_example "0 set-edit-position \\ revert channel" #endif snd_help_with_xrefs("Undo and Redo", #if HAVE_EXTENSION_LANGUAGE "Snd supports 'unlimited undo' in the sense that you can move back and forth in the list of edits without any \ limit on how long that list can get. Each editing operation \ extends the current edit list; each undo backs up in that list, and each redo moves forward in the list of previously \ un-done edits. Besides the Edit and Popup menu options, and the " H_undo " and " H_redo " functions, \ there are these keyboard sequences: \ \n\n\ C-x r redo last edit\n\ C-x u undo last edit\n\ C-x C-r redo last edit\n\ C-x C-u undo last edit\n\ C-_ undo last edit\n\ \n\ File:Revert is the same as undo all edits.\ In the listener, C-M-g deletes all text, and C-_ deletes back to the previous command.\ In the sound display, the number at the lower left shows the current edit position and the channel number.\ The main functions that affect the edit position are:\n\ \n\ " H_undo " (:optional (edits 1) snd chn)\n\ This undoes 'edits' edits in snd's channel chn.\n\ \n\ " H_redo " (:optional (edits 1) snd chn)\n\ This re-activates 'edits' edits in snd's channel chn.\n\ \n\ " S_revert_sound " (:optional snd)\n\ This reverts 'snd' to its saved (unedited) state.\n\ \n\ " S_edit_position " (:optional snd chn)\n\ This is the current position in the edit history list.\n\ " edit_position_example "\n\ ", #else "Snd supports 'unlimited undo' in the sense that you can move back and forth in the list of edits without any \ limit on how long that list can get. Each editing operation \ extends the current edit list; each undo backs up in that list, and each redo moves forward in the list of previously \ un-done edits. Besides the Edit and Popup menu options,\ there are these keyboard sequences: \ \n\n\ C-x r redo last edit\n\ C-x u undo last edit\n\ C-x C-r redo last edit\n\ C-x C-u undo last edit\n\ C-_ undo last edit\n\ \n\ File:Revert is the same as undo all edits.", #endif WITH_WORD_WRAP, snd_xrefs("Undo"), snd_xref_urls("Undo")); append_key_help("C-M-g", snd_K_g, snd_ControlMask | snd_MetaMask, false, append_key_help("C-_", snd_K_underscore, snd_ControlMask, false, append_key_help("C-x C-u", snd_K_u, snd_ControlMask, true, append_key_help("C-x C-r", snd_K_r, snd_ControlMask, true, append_key_help("C-x u", snd_K_u, 0, true, append_key_help("C-x r", snd_K_r, 0, true, true)))))); } /* ---------------- Sync and Unite ---------------- */ static const char *sync_xrefs[5] = { "sound sync field: {" S_sync "}, {" S_sync_max "}", "mark sync field: {" S_mark_sync "}, {" S_mark_sync_max "}, {mark-sync-color}, {" S_syncd_marks "}", "mix sync field: {" S_mix_sync "}", "channel display choice: {" S_channel_style "}", NULL}; void sync_help(void) { #if HAVE_SCHEME #define channel_style_example "(set! (channel-style snd) channels-combined)" #define H_channels_separate S_channels_separate #define H_channels_combined S_channels_combined #define H_channels_superimposed S_channels_superimposed #endif #if HAVE_RUBY #define channel_style_example "set_channel_style(Channels_combined, snd)" #define H_channels_separate "Channels_separate" #define H_channels_combined "Channels_combined" #define H_channels_superimposed "Channels_superimposed" #endif #if HAVE_FORTH #define channel_style_example "channels-combined set-channel-style" #define H_channels_separate S_channels_separate #define H_channels_combined S_channels_combined #define H_channels_superimposed S_channels_superimposed #endif snd_help_with_xrefs("Sync", #if HAVE_EXTENSION_LANGUAGE "The sync button causes certain operations to apply to all channels or multiple sounds simultaneously. \ For example, to get a multichannel selection, set the sync button, then define the selection (by dragging \ the mouse) in one channel, and the parallel portions of the other channels are also selected. \ The default sync setting is set by " S_sync_style ", which defaults to " S_sync_by_sound ". \ This ties together all the channels in a sound, but keeps sounds separate. The other sync styles \ are " S_sync_none ", and " S_sync_all ". " S_sync_none " means each channel is separate, and " S_sync_all " means \ everything is handled together. You can set the sync style via " S_sync ". \ Marks and mixes can also be sync'd together.\n\ \n\ Similarly, the unite button combines channels of a \ multichannel sound into one display window. control-click the unite button to have the channels \ superimposed on each other. The function associated with this is:\n\ \n\ " S_channel_style " (:optional snd)\n\ " S_channel_style " reflects the value of the 'unite' button in multichannel files.\n\ Possible values are " H_channels_separate ", " H_channels_combined ", and " H_channels_superimposed ".\n\ " channel_style_example "\n\ ", #else "The sync button causes certain operations to apply to all channels or multiple sounds simultaneously. \ For example, to get a multichannel selection, set the sync button, then define the selection (by dragging \ the mouse) in one channel, and the parallel portions of the other channels are also selected. \ Marks and mixes can also be sync'd together.\n\ \n\ Similarly, the unite button combines channels of a \ multichannel sound into one display window. control-click the unite button to have the channels \ superimposed on each other.", #endif WITH_WORD_WRAP, sync_xrefs, NULL); } /* ---------------- Debug ---------------- */ static const char *debug_xrefs[5] = { "C debugging: {gdb}", "CLM Instrument debugging: {variable-display}", "Error handling", "Print statement: {" S_snd_print "}", NULL}; static const char *debug_urls[5] = { "extsnd.html#cdebugging", "sndscm.html#variabledisplay", "extsnd.html#snderrors", "extsnd.html#sndprint", NULL}; void debug_help(void) { #if HAVE_SCHEME #define vardpy_reference "variable-display in snd-motif.scm" #endif #if HAVE_RUBY #define vardpy_reference "variable_display in snd-xm.rb" #endif #if HAVE_FORTH #define vardpy_reference "variable-display, which isn't written yet" #endif snd_help_with_xrefs("Debugging", #if HAVE_EXTENSION_LANGUAGE "There are several sets of debugging aids, each aimed at a different level of code. \ C code is normally debugged with gdb. If you hit a segfault in Snd, please tell me \ about it! If possible, run Snd in gdb and send me the stack trace: \n\n\ gdb snd\n\ run\n\ \n\ where\n\ \n\ See README.Snd for more about C-level troubles. For CLM-based instruments, " vardpy_reference " might \ help. For debugging your own Scheme/Ruby/Forth \ code (or Snd's for that matter), see the \"Errors and Debugging\" section of \ extsnd.html. For notelist debugging, see ws-backtrace.", #else "If you hit a segfault in Snd, please tell me \ about it! If possible, run Snd in gdb and send me the stack trace: \n\n\ gdb snd\n\ run\n\ \n\ where\n\ \n", #endif WITH_WORD_WRAP, debug_xrefs, debug_urls); } /* ---------------- Envelope ---------------- */ void env_help(void) { #if HAVE_SCHEME #define envelope_example "'(0 0 1 1 2 0)" #define env_sound_example "(env-sound '(0 0 1 1 2 0))" #endif #if HAVE_RUBY #define envelope_example "[0.0, 0.0, 1.0, 1.0, 2.0, 0.0]" #define env_sound_example "env_sound([0.0, 0.0, 1.0, 1.0, 2.0, 0.0])" #endif #if HAVE_FORTH #define envelope_example "'( 0.0 0.0 1.0 1.0 2.0 0.0 )" #define env_sound_example "'( 0.0 0.0 1.0 1.0 2.0 0.0 ) env-sound" #endif snd_help_with_xrefs("Envelope", #if HAVE_EXTENSION_LANGUAGE "An envelope in Snd is a list (an array in Ruby) of x y break-point pairs. The x axis range is arbitrary. \ To define a triangle curve: " envelope_example ".\ There is no preset limit on the number of breakpoints. Use the envelope editor to draw envelopes with the mouse. \ \n\n\ To apply an envelope to a sound, use " S_env_sound ". The primary enveloping functions are:\n\ \n\ " S_env_sound " (envelope :optional (samp 0) samps (env-base 1.0) snd chn edpos)\n\ " S_env_sound " applies the amplitude envelope to snd's channel chn.\n\ " env_sound_example "\n\ \n\ " S_env_channel " (clm-env-gen :optional beg dur snd chn edpos)\n\ This is the channel-specific version of " S_env_sound ".\n\ ", #else "It is hard to define or use an envelope if there's no extension language.", #endif WITH_WORD_WRAP, snd_xrefs("Envelope"), /* snd-xref.c */ snd_xref_urls("Envelope")); } /* ---------------- FFT ---------------- */ void fft_help(void) { #if HAVE_SCHEME #define transform_normalization_example "(set! (transform-normalization) dont-normalize)" #define transform_size_example "(set! (transform-size) 512)" #define transform_type_example "(set! (transform-type) autocorrelation)" #define fft_window_example "(set! (fft-window) rectangular-window)" #define transform_graph_example "(set! (transform-graph?) #t)" #define transform_graph_type_example "(set! (transform-graph-type) graph-as-sonogram)" #define transform_log_magnitude_example "(set! (transform-log-magnitude) #f)" #define transform_types "fourier-transform wavelet-transform haar-transform\n autocorrelation walsh-transform cepstrum" #define transform_graph_types "graph-once graph-as-sonogram graph-as-spectrogram" #define transform_normalizations "dont-normalize normalize-by-channel normalize-by-sound normalize-globally" #define fft_windows " bartlett-window blackman2-window blackman3-window blackman4-window\n cauchy-window connes-window dolph-chebyshev-window exponential-window\n gaussian-window hamming-window hann-poisson-window hann-window\n kaiser-window parzen-window poisson-window rectangular-window\n riemann-window samaraki-window tukey-window ultraspherical-window\n welch-window bartlett-hann-window bohman-window flat-top-window blackman5..10-window" #endif #if HAVE_RUBY #define transform_normalization_example "set_transform_normalization(Dont_normalize)" #define transform_size_example "set_transform_size(512)" #define transform_type_example "set_transform_type(Autocorrelation)" #define fft_window_example "set_fft_window(Rectangular_window)" #define transform_graph_example "set_transform_graph?(#t)" #define transform_graph_type_example "set_transform_graph_type(Graph_as_sonogram)" #define transform_log_magnitude_example "set_transform_log_magnitude(#f)" #define transform_types "Fourier_transform Wavelet_transform Haar_transform\n Autocorrelation Walsh_transform Cepstrum" #define transform_graph_types "graph_once graph_as_sonogram graph_as_spectrogram" #define transform_normalizations "Dont_normalize Normalize_by_channel Normalize_by_sound Normalize_globally" #define fft_windows " Bartlett_window Blackman2_window Blackman3_window Blackman4_window\n Cauchy_window Connes_window Dolph_chebyshev_window Exponential_window\n Gaussian_window Hamming_window Hann_poisson_window Hann_window\n Kaiser_window Parzen_window Poisson_window Rectangular_window\n Riemann_window Samaraki_window Tukey_window Ultraspherical_window\n Welch_window Bartlett_hann_window Bohman_window Flat_top_window Blackman5..10_window" #endif #if HAVE_FORTH #define transform_normalization_example "dont-normalize set-transform-normalization" #define transform_size_example "512 set-transform-size" #define transform_type_example "autocorrelation set-transform-type" #define fft_window_example "rectangular-window set-fft-window" #define transform_graph_example "#t set-transform-graph?" #define transform_graph_type_example "graph-as-sonogram set-transform-graph-type" #define transform_log_magnitude_example "#f set-transform-log-magnitude" #define transform_types "fourier-transform wavelet-transform haar-transform\n autocorrelation walsh-transform cepstrum" #define transform_graph_types "graph-once graph-as-sonogram graph-as-spectrogram" #define transform_normalizations "dont-normalize normalize-by-channel normalize-by-sound normalize-globally" #define fft_windows " bartlett-window blackman2-window blackman3-window blackman4-window\n cauchy-window connes-window dolph-chebyshev-window exponential-window\n gaussian-window hamming-window hann-poisson-window hann-window\n kaiser-window parzen-window poisson-window rectangular-window\n riemann-window samaraki-window tukey-window ultraspherical-window\n welch-window bartlett-hann-window bohman-window flat-top-window blackman5..10-window" #endif snd_help_with_xrefs("FFT", #if HAVE_EXTENSION_LANGUAGE "The FFT performs a projection of the time domain into the frequency domain. Good discussions of the Fourier Transform \ and the trick used in the FFT itself can be found in many DSP books; those I know of include 'A Digital Signal Processing \ Primer', Ken Steiglitz, or 'Numerical Recipes in C'. \ For the Fourier transform itself, good books abound: \ 'Mathematics of the DFT', Julius Smith, or 'Understanding DSP', Lyons, etc. For more sophistication, \ 'Fourier Analysis', Korner, 'Fourier Analysis', Stein and Shakarchi, or 'Trigonometric Series', Zygmund. \ \n\n\ The FFT size can be any power of 2. The larger, the longer it takes to compute, and the larger the amount of the time domain \ that gets consumed. Interpretation of the FFT results is not straightforward! The window choices are taken primarily \ from Harris' article: Fredric J. Harris, 'On the Use of Windows for Harmonic Analysis with the Discrete Fourier Transform', Proceedings of the \ IEEE, Vol. 66, No. 1, January 1978, with updates from: Albert H. Nuttall, 'Some Windows with Very Good Sidelobe Behaviour', IEEE Transactions \ of Acoustics, Speech, and Signal Processing, Vol. ASSP-29, 1, February 1981. \ \n\n\ Nearly all the transform-related choices are set by the transform dialog launched from the Options \ Menu Transform item. Most of this dialog should be self-explanatory. Some of the windows take an \ additional parameter sometimes known as alpha or beta. This can be set by the scale(s) next to the fft window graph in the \ transform dialog, or via " S_fft_window_alpha " and " S_fft_window_beta ". \ \n\n\ To change the defaults, you can set the various values in your initialization file (see examples below), \ or use the Options:Preferences dialog's Transforms section.\ \n\n\ The FFT display is activated by setting the 'f' button on the channel's window. It then updates \ itself each time the time domain waveform moves or changes. \ The FFT is taken from the start (the left edge) of the current window and is updated as the window bounds change. \ The data is scaled to fit between 0.0 and 1.0 unless transform normalization is off. \ The full frequency axis is normally displayed, but the axis is draggable -- put the mouse on the axis \ and drag it either way to change the range (this is equivalent to changing the variable " S_spectrum_end "). \ You can also click on any point in the fft to get the associated fft value at that point displayed; \ if " S_with_verbose_cursor " is " PROC_TRUE ", you can drag the mouse through the fft display and \ the description in the status area is constantly updated. To change the fft size by powers of two, \ you can use the keypad keys '*' and '/'. \ \n\n\ The main FFT-related functions are:\ \n\n\ " S_transform_size " (:optional snd chn)\n\ the fft size (a power of 2): " transform_size_example "\n\ \n\ " S_transform_type " (:optional snd chn)\n\ which transform is performed: " transform_type_example "\n\ the built-in transform choices are:\n\ " transform_types "\n\ \n\ " S_transform_graph_type " (:optional snd chn)\n\ the display choice, one of: " transform_graph_types "\n\ " transform_graph_type_example "\n\ \n\ " S_fft_window " (:optional snd chn)\n\ the fft data window: " fft_window_example "\n\ the windows are:\n\ " fft_windows "\n\ \n\ " S_show_transform_peaks " and " S_max_transform_peaks "\n\ these control the peak info display\n\ \n\ " S_fft_log_magnitude " and " S_fft_log_frequency "\n\ these set whether the axes are linear or logarithmic\n\ \n\ " S_fft_with_phases " (:optional snd chn)\n\ sets whether the single fft display includes phase information\n\ \n\ " S_transform_graph_on " (:optional snd chn)\n\ if " PROC_TRUE ", the fft graph is displayed: " transform_graph_example "\n\ \n\ " S_transform_normalization " (:optional snd chn)\n\ how fft data is normalized. " transform_normalization_example "\n\ the choices are:\n\ " transform_normalizations "\n\ \n\ " S_peaks " (:optional file snd chn) writes out current peak info as text\n\ \n\ Other related functions: " S_zero_pad ", " S_wavelet_type ", " S_add_transform "\n\ " S_min_dB ", " S_snd_spectrum ", " S_show_selection_transform ".", #else "Nearly all the transform-related choices can be set in the transform dialog launched from the Options \ Menu Transform item. Most of this dialog should be self-explanatory. Some of the windows take an \ additional parameter sometimes known as alpha or beta. This can be set by the scale(s) next to the fft window graph in the \ transform dialog, or via the variables " S_fft_window_alpha " and " S_fft_window_beta ".\ \n\n\ The FFT display is activated by setting the 'f' button on the channel's window. It then updates \ itself each time the time domain waveform moves or changes. \ The FFT is taken from the start (the left edge) of the current window and is updated as the window bounds change. \ The data is scaled to fit between 0.0 and 1.0 unless transform normalization is off. \ The full frequency axis is normally displayed, but the axis is draggable -- put the mouse on the axis \ and drag it either way to change the range. \ You can also click on any point in the fft to get the associated fft value at that point displayed. \ To change the fft size by powers of two, \ you can use the keypad keys '*' and '/'.", #endif WITH_WORD_WRAP, snd_xrefs("FFT"), snd_xref_urls("FFT")); global_fft_state(); } /* ---------------- Control Panel ---------------- */ static const char *control_xrefs[9] = { "various control panel variables: {Control panel}", "amplitude: {" S_scale_by "}", "speed or srate: {" S_src_sound "}", "expand: {granulate}", "contrast: {" S_contrast_enhancement "}", "filter: {" S_filter_sound "}", "{" S_apply_controls "}", "{" S_controls_to_channel "}", NULL}; void controls_help(void) { #if HAVE_SCHEME #define amp_control_example "(set! (amp-control) 0.5)" #define amp_control_bounds_example "(set! (amp-control-bounds) (list 0.0 20.0))" #define speed_control_styles "speed-control-as-float speed-control-as-ratio speed-control-as-semitone" #endif #if HAVE_RUBY #define amp_control_example "set_amp_control(0.5)" #define amp_control_bounds_example "set_amp_control_bounds([0.0, 20.0])" #define speed_control_styles "Speed_control_as_float Speed_control_as_ratio Speed_control_as_semitone" #endif #if HAVE_FORTH #define amp_control_example "0.5 set-amp-control" #define amp_control_bounds_example "'( 0.0 20.0 ) set-amp-control-bounds" #define speed_control_styles "speed-control-as-float speed-control-as-ratio speed-control-as-semitone" #endif snd_help_with_xrefs("The Control Panel", #if HAVE_EXTENSION_LANGUAGE "The control panel is the portion of each sound's pane beneath the channel graphs. \ The controls are: amp, speed, expand, contrast, reverb, and filter. \ \n\n\ 'Speed' here refers to the rate at which the sound data is consumed during playback. \ Another term might be 'srate'. The arrow button on the right determines \ the direction Snd moves through the data. The scroll bar position is normally interpreted \ as a float between .05 and 20. \ \n\n\ 'Expand' refers to granular synthesis used to change the tempo of events \ in the sound without changing pitch. Successive short slices of the file are overlapped with \ the difference in size between the input and output hops (between successive slices) giving \ the change in tempo. This doesn't work in all files -- it sometimes sounds like execrable reverb \ or is too buzzy -- but it certainly is more robust than the phase vocoder approach to the \ same problem. The expander is on only if the expand button is set. \ \n\n\ The reverberator is a version of Michael McNabb's Nrev. In addition to the controls \ in the control pane, you can set the reverb feedback gain and the coefficient of the lowpass \ filter in the allpass bank. The reverb is on only if the reverb button is set. The reverb length \ field takes effect only when the reverb is set up (when the DAC is started by clicking \ 'play' when nothing else is being played). \ \n\n\ 'Contrast enhancement' is my name for a somewhat weird waveshaper or compander. It \ phase-modulates a sound, which can in some cases make it sound sharper or brighter. \ For softer sounds, it causes only an amplitude change. To scale a soft sound up before \ being 'contrasted', use the variable " S_contrast_control_amp ". Contrast is on only if the contrast button is set. \ \n\n\ The filter is an arbitrary (even) order FIR filter specified by giving the frequency response \ envelope and filter order in the text windows provided. \ The envelope X axis goes from 0 to half the sampling rate. The actual frequency response (given the current filter order) \ is displayed in blue. The filter is on only if the filter button is set. \ \n\n\ See the Options:controls menu item for even more controls.\ The keyboard commands associated with the control panel are: \ \n\n\ C-x C-o show control panel\n\ C-x C-c hide control panel\n\ \n\ There are functions to get and set every aspect of the control panel -- far too many to list! \ As an example of how they all work, to set the amplitude slider from a function: \n\ \n\ " amp_control_example "\n\ \n\ To set its overall bounds:\n\ \n\ " amp_control_bounds_example "\n\ \n\ The speed control can be interpreted as a float, a ratio, or a semitone. The choices are:\n\ \n\ " speed_control_styles "\n\ \n\ To apply the current settings as an edit, call:\n\ \n\ " S_apply_controls " (:optional snd (target 0) beg dur)\n\ where 'target' selects what gets edited: \n\ 0 = sound, 1 = channel, 2 = selection.", #else "The control panel is the portion of each sound's pane beneath the channel graphs. \ The controls are: amp, speed, expand, contrast, reverb, and filter. \ \n\n\ 'Speed' here refers to the rate at which the sound data is consumed during playback. \ Another term might be 'srate'. The arrow button on the right determines \ the direction Snd moves through the data. The scroll bar position is normally interpreted \ as a float between .05 and 20. \ \n\n\ 'Expand' refers to granular synthesis used to change the tempo of events \ in the sound without changing pitch. Successive short slices of the file are overlapped with \ the difference in size between the input and output hops (between successive slices) giving \ the change in tempo. This doesn't work in all files -- it sometimes sounds like execrable reverb \ or is too buzzy -- but it certainly is more robust than the phase vocoder approach to the \ same problem. The expander is on only if the expand button is set. \ \n\n\ The reverberator is a version of Michael McNabb's Nrev. In addition to the controls \ in the control pane, you can set the reverb feedback gain and the coefficient of the lowpass \ filter in the allpass bank. The reverb is on only if the reverb button is set. The reverb length \ field takes effect only when the reverb is set up (when the DAC is started by clicking \ 'play' when nothing else is being played). \ \n\n\ 'Contrast enhancement' is my name for a somewhat weird waveshaper or compander. It \ phase-modulates a sound, which can in some cases make it sound sharper or brighter. \ For softer sounds, it causes only an amplitude change. \ Contrast is on only if the contrast button is set. \ \n\n\ The filter is an arbitrary (even) order FIR filter specified by giving the frequency response \ envelope and filter order in the text windows provided. \ The envelope X axis goes from 0 to half the sampling rate. The actual frequency response (given the current filter order) \ is displayed in blue. The filter is on only if the filter button is set.", #endif WITH_WORD_WRAP, control_xrefs, NULL); global_control_panel_state(); append_key_help("C-x C-o", snd_K_o, snd_ControlMask, true, append_key_help("C-x C-c", snd_K_c, snd_ControlMask, true, true)); } /* ---------------- Marks ---------------- */ void marks_help(void) { #if HAVE_SCHEME #define add_mark_example "(add-mark 1234)" #define mark_name_example "(set! (mark-name 0) \"mark-0\")" #endif #if HAVE_RUBY #define add_mark_example "add_mark(1234)" #define mark_name_example "set_mark_name(0, \"mark-0\")" #endif #if HAVE_FORTH #define add_mark_example "1234 add-mark" #define mark_name_example "0 \"mark-0\" set-mark-name" #endif snd_help_with_xrefs("Marks", #if HAVE_EXTENSION_LANGUAGE "A 'mark' marks a particular sample in a sound (not a position in that sound). \ If we mark a sample, then delete 100 samples before it, the mark follows the sample, changing its current position \ in the data. If we delete the sample, the mark is also deleted; a subsequent undo that returns the sample also \ returns its associated mark. I'm not sure this is the right thing, but it's a lot less stupid than marking \ a position. \ \n\n\ Once set, a mark can be moved by dragging the horizontal tab at the top. Control-click of the tab followed by mouse \ drag will drag the underlying data too, either inserting zeros or deleting data. \ Click on the triangle at the bottom to play (or stop playing) from the mark. \ \n\n\ A mark can be named or unnamed. It it has a name, it is displayed above the horizontal tab at the top of the window. As with \ sounds and mixes, marks can be grouped together through the sync field; marks sharing the same sync value (other \ than 0) will move together when one is moved, and so on. The following keyboard commands relate to marks: \ \n\n\ C-m place (or remove if argument negative) mark at cursor\n\ C-M place syncd marks at all currently syncd chan cursors\n\ C-x / place named mark at cursor\n\ C-x C-m add named mark\n\ C-j go to mark\n\ \n\ The main mark-related functions are:\n\ \n\ " S_add_mark " (sample :optional snd chn)\n\ add a mark at sample 'sample': " add_mark_example "\n\ \n\ " S_delete_mark " (mark-id) \n\ delete mark (the 'mark-id' is returned by " S_add_mark ")\n\ \n\ " S_mark_sample " (mark-id): sample marked by the mark\n\ " S_mark_name " (mark-id): mark's name, if any\n\ " mark_name_example "\n\ \n\ Other such functions: " S_find_mark ", " S_mark_color ", " S_mark_tag_width ",\n\ " S_mark_tag_height ", " S_mark_sync ", " S_show_marks ", " S_save_marks ",\n\ " S_marks "\n", #else "A 'mark' marks a particular sample in a sound (not a position in that sound). \ If we mark a sample, then delete 100 samples before it, the mark follows the sample, changing its current position \ in the data. If we delete the sample, the mark is also deleted; a subsequent undo that returns the sample also \ returns its associated mark.\ \n\n\ Once set, a mark can be moved by dragging the horizontal tab at the top. Control-click of the tab followed by mouse \ drag will drag the underlying data too, either inserting zeros or deleting data. \ Click on the triangle at the bottom to play (or stop playing) from the mark. \ The following keyboard commands relate to marks: \ \n\n\ C-m place (or remove if argument negative) mark at cursor\n\ C-M place syncd marks at all currently syncd chan cursors\n\ C-x / place named mark at cursor\n\ C-x C-m add named mark\n\ C-j go to mark", #endif WITH_WORD_WRAP, snd_xrefs("Mark"), snd_xref_urls("Mark")); append_key_help("C-x C-m", snd_K_m, snd_ControlMask, true, append_key_help("C-x /", snd_K_slash, 0, true, append_key_help("C-j", snd_K_j, snd_ControlMask, false, append_key_help("C-m", snd_K_m, snd_ControlMask, false, true)))); } /* ---------------- Mixes ---------------- */ void mix_help(void) { #if HAVE_SCHEME #define mix_example "(mix \"oboe.snd\" 1234)" #define mix_vct_example "(mix-float-vector (float-vector 0 .1 .2) 1234)" #define mix_amp_example "(set! (mix-amp 0) .5)" #define mix_amp_env_example "(set! (mix-amp-env 0) '(0 0 1 1))" #endif #if HAVE_RUBY #define mix_example "mix(\"oboe.snd\", 1234)" #define mix_vct_example "mix_vct(vct(0.0, 0.1, 0.2), 1234)" #define mix_amp_example "set_mix_amp(0, .5)" #define mix_amp_env_example "set_mix_amp_env(0, [0.0, 0.0, 1.0, 1.0])" #endif #if HAVE_FORTH #define mix_example "\"oboe.snd\" 1234 mix" #define mix_vct_example "0.0 0.1 0.2 vct 1234 mix-vct" #define mix_amp_example "0 0.5 set-mix-amp" #define mix_amp_env_example "0 '( 0.0 0.0 1.0 1.0 ) set-mix-amp-env" #endif snd_help_with_xrefs("Mixing", #if HAVE_EXTENSION_LANGUAGE "Since mixing is the most common and most useful editing operation performed on \ sounds, there is relatively elaborate support for it in Snd. To mix in a file, \ use the File Mix menu option, the command C-x C-q, or one of the various \ mixing functions. Currently the only difference between the first two is that \ the Mix menu option tries to take the current sync state into account, whereas \ the C-x C-q command does not. To mix a selection, use C-x q. The mix starts at \ the current cursor location. It is displayed as a separate waveform above \ the main waveform with a tag at the beginning. You can drag the tag to \ reposition the mix. \ \n\n\ The Mix dialog (under the View Menu) provides various \ commonly-used controls on the currently chosen mix. At the top are the mix id, \ name, begin and end times, and a play button. Beneath that are \ various sliders controlling the speed (sampling rate) of the mix, amplitude of \ each input channel, and the amplitude envelopes. \ \n\n\ The main mix-related functions are:\n\ \n\ " S_mix " (file :optional samp in-chan snd chn tags delete)\n\ mix file's channel in-chan starting at samp\n\ " mix_example "\n\ \n\ " S_mix_selection " (:optional beg snd chn selection-channel)\n\ mix (add) selection starting at beg\n\ \n\ " S_mix_region " (:optional samp reg snd chn region-channel)\n\ mix region reg at sample samp (default is cursor sample)\n\ \n\ " S_mix_vct " (v :optional beg snd chn with-mix-tags origin)\n\ mix the contents of " S_vct " starting at beg:\n\ " mix_vct_example "\n\ \n\ " S_mix_amp " (mix)\n\ amplitude of mix:\n\ " mix_amp_example "\n\ \n\ " S_mix_amp_env " (mix)\n\ amplitude envelope of mix:\n\ " mix_amp_env_example "\n\ \n\ " S_mix_speed " (mix)\n\ speed (resampling ratio) of mix; 1.0 means no change;\n\ 2.0 reads the mix data twice as fast\n\ \n\ " S_mix_position " (mix)\n\ position (a sample number) of mix\n\ \n\ " S_mix_length " (mix)\n\ mix's length in samples\n\ \n\ Other such function include: " S_mix_waveform_height ", " S_with_mix_tags ", " S_mix_tag_width ",\n\ " S_mix_tag_height ", " S_mix_tag_y ", " S_mixes ".", #else "Since mixing is the most common and most useful editing operation performed on \ sounds, there is relatively elaborate support for it in Snd. To mix in a file, \ use the File Mix menu option, the command C-x C-q, or one of the various \ mixing functions. Currently the only difference between the first two is that \ the Mix menu option tries to take the current sync state into account, whereas \ the C-x C-q command does not. To mix a selection, use C-x q. The mix starts at \ the current cursor location. It is displayed as a separate waveform above \ the main waveform with a tag at the beginning. You can drag the tag to \ reposition the mix. \ \n\n\ The Mix dialog (under the View Menu) provides various \ commonly-used controls on the currently chosen mix. At the top are the mix id, \ name, begin and end times, and a play button. Beneath that are \ various sliders controlling the speed (sampling rate), amplitude, \ and amplitude envelope applied to the mix. \ \n\n", #endif WITH_WORD_WRAP, snd_xrefs("Mix"), snd_xref_urls("Mix")); append_key_help("C-x q", snd_K_q, 0, true, append_key_help("C-x C-q", snd_K_q, snd_ControlMask, true, true)); } /* ---------------- Headers etc ---------------- */ static const char *header_and_data_xrefs[10] = { "sample type discussion: {" S_sample_type "}", "sample type constants: {" S_mus_sample_type_name "}", "header type discussion: {" S_header_type "}", "header type constants: {" S_mus_header_type_name "}", "MPEG support: mpg in examp." Xen_file_extension, "OGG support: read-ogg in examp." Xen_file_extension, "Speex support: read-speex in examp." Xen_file_extension, "Flac support: read-flac in examp." Xen_file_extension, "{Sndlib}: underlying support", NULL}; static const char *header_and_data_urls[10] = { "extsnd.html#sampletype", "extsnd.html#defaultoutputsampletype", "extsnd.html#headertype", "extsnd.html#defaultoutputheadertype", "sndscm.html#exmpg", "sndscm.html#exmpg", "sndscm.html#exmpg", "sndscm.html#exmpg", "sndlib.html#introduction", NULL}; void sound_files_help(void) { snd_help_with_xrefs("Headers and Data", "Snd can handle the following file and data types: \ \n\n\ read/write (many sample types):\n\ NeXT/Sun/DEC/AFsp\n\ AIFF/AIFC\n\ RIFF (Microsoft wave)\n\ RF64\n\ IRCAM (old style)\n\ NIST-sphere\n\ CAFF\n\ no header ('raw')\n\ \n\n\ read-only (in selected sample types):\n\ 8SVX (IFF), EBICSF, INRS, ESPS, SPPACK, ADC (OGI), AVR, VOC, PVF,\n\ Sound Tools, Turtle Beach SMP, SoundFont 2.0, Sound Designer I, PSION, MAUD, Kurzweil 2000,\n\ Gravis Ultrasound, ASF, PAF, CSL, Comdisco SPW, Goldwave sample, omf, quicktime, sox,\n\ Sonic Foundry (w64), SBStudio II, Delusion digital, Digiplayer ST3, Farandole Composer WaveSample,\n\ Ultratracker WaveSample, Sample Dump exchange, Yamaha SY85, SY99, and TX16, Covox v8, AVI, \n\ Impulse tracker, Korg, Akai, Turtle Beach, Matlab-5\n\ \n\n\ automatically translated to a readable sample and header type:\n\ IEEE text, Mus10, SAM 16-bit (modes 1 and 4), AVI, \n\ NIST shortpack, HCOM, Intel, IBM, and Oki (Dialogic) ADPCM, \n\ G721, G723_24, G723_40, MIDI sample dump, Ogg, Speex, \n\ Flac, Midi, Mpeg, Shorten, Wavepack, tta (via external programs)\n\ \n\n\ The files can have any number of channels. Data can be either big or little endian. \ The file types listed above as 'automatically translated' are \ decoded upon being opened, translated to some type that Snd can read and write, \ and rewritten as a new file with an added (possibly redundant) extension .snd, \ and that file is the one the editor sees from then on.\ \n\n\ " S_sample_type " returns the current sound's sample type, and " S_header_type " returns \ its header type.", WITH_WORD_WRAP, header_and_data_xrefs, header_and_data_urls); } /* ---------------- Initialization File ---------------- */ static const char *init_file_xrefs[5] = { "{Invocation flags}", "~/.snd: {Initialization file}", "{Customization}", "examples of ~/.snd", NULL}; static const char *init_file_urls[6] = { "grfsnd.html#sndswitches", "grfsnd.html#sndinitfile", "extsnd.html#lisplistener", "grfsnd.html#sndinitfile", NULL}; void init_file_help(void) { snd_help_with_xrefs("Customization", #if HAVE_EXTENSION_LANGUAGE "Nearly everything in Snd can be set in an initialization file, loaded at any time from a saved-state file, specified \ via inter-process communciation from any other program, or \ dealt with from the lisp listener panel. I've tried to bring out to lisp nearly every portion of Snd, \ both the signal-processing functions, and much of the user interface. You can, for example, add your own menu choices, \ editing operations, or graphing alternatives. These extensions can be loaded at any time. One of the \ easier ways to start an initialization file is to go to the Options:Preferences dialog, set the choices \ you want, then save those choices. The initialization file is just program text, so you can edit it and so on.", #else "Snd depends heavily on the extension language to provide much of its functionality. Since none \ is loaded, there's not much customization you can do.", #endif WITH_WORD_WRAP, init_file_xrefs, init_file_urls); } /* ---------------- Keys ---------------- */ static const char *key_xrefs[4] = { "To change a key's action: {" S_bind_key "}", "To undefine a key: {" S_unbind_key "}", "Current key action: {" S_key_binding "}", NULL}; static void show_key_help(int key, int state, bool cx, char *help) { /* this frees the help string since it's always coming from key_description, and * is a bother to handle in the loops that call us */ if (help) { char buf[1024]; char cbuf[256]; make_key_name(cbuf, 256, key, state, cx); snprintf(buf, 1024, "\n%s: %s", cbuf, help); snd_help_append(buf); free(help); } } static bool find_unbuckified_keys(int key, int state, bool cx, Xen func) { if ((key > 256) && (state == 0) && (!cx) && (Xen_is_bound(func))) show_key_help(key, state, cx, key_description(key, state, cx)); return(false); } static bool find_buckified_keys(int key, int state, bool cx, Xen func) { if ((key > 256) && (state == snd_ControlMask) && (!cx) && (Xen_is_bound(func))) show_key_help(key, state, cx, key_description(key, state, cx)); return(false); } static bool find_unbuckified_cx_keys(int key, int state, bool cx, Xen func) { if ((key > 256) && (state == 0) && (cx) && (Xen_is_bound(func))) show_key_help(key, state, cx, key_description(key, state, cx)); return(false); } static bool find_buckified_cx_keys(int key, int state, bool cx, Xen func) { if ((key > 256) && (state == snd_ControlMask) && (cx) && (Xen_is_bound(func))) show_key_help(key, state, cx, key_description(key, state, cx)); return(false); } static bool find_leftover_keys(int key, int state, bool cx, Xen func) { if ((key > 256) && (state & snd_MetaMask)) show_key_help(key, state, cx, key_description(key, state, cx)); return(false); } void key_help(void) { #if HAVE_SCHEME #define bind_key_example "(bind-key \"End\" 0\n (lambda () \"view full sound\"\n (set! (x-bounds) (list 0.0 (/ (framples) (srate))))))" #endif #if HAVE_RUBY #define bind_key_example "bind_key(\"End\", 0,\n lambda do ||\n set_x_bounds([0.0, framples.to_f / srate.to_f])\n end)" #endif #if HAVE_FORTH #define bind_key_example "\"End\" 0\n lambda: <{ -- val }> doc\" view full sound\"\n '( 0.0 #f #f #f framples #f srate f/ ) #f #f undef set-x-bounds ; bind-key" #endif int i; snd_help_with_xrefs("Keys", #if HAVE_EXTENSION_LANGUAGE "Although Snd has a number of built-in key actions (listed below), you can redefine \ any key via:\n\ \n\ " S_bind_key " (key state func :optional extended origin)\n\ this function causes 'key' (an integer or a key name) with \n\ modifiers 'state' (and preceding C-x if 'extended') to evaluate\n\ 'func'. For example, to set the End key to cause the full sound\n\ to be displayed:\n\n\ " bind_key_example "\n\n\nKeys:\n", #else "If there's no extension language, you're stuck with the built-in key actions:", #endif WITHOUT_WORD_WRAP, key_xrefs, NULL); /* run through bindings straight, C-key, C-x key, C-x C-key appending description in help dialog */ for (i = 0; i < 256; i++) show_key_help(i, 0, false, key_description(i, 0, false)); map_over_keys(find_unbuckified_keys); for (i = 0; i < 256; i++) show_key_help(i, snd_ControlMask, false, key_description(i, snd_ControlMask, false)); map_over_keys(find_buckified_keys); for (i = 0; i < 256; i++) show_key_help(i, snd_MetaMask, false, key_description(i, snd_MetaMask, false)); for (i = 0; i < 256; i++) show_key_help(i, snd_ControlMask | snd_MetaMask, false, key_description(i, snd_ControlMask | snd_MetaMask, false)); for (i = 0; i < 256; i++) show_key_help(i, 0, true, key_description(i, 0, true)); map_over_keys(find_unbuckified_cx_keys); for (i = 0; i < 256; i++) show_key_help(i, snd_ControlMask, true, key_description(i, snd_ControlMask, true)); map_over_keys(find_buckified_cx_keys); map_over_keys(find_leftover_keys); snd_help_back_to_top(); } /* ---------------- Play ---------------- */ void play_help(void) { #if WITH_AUDIO #if HAVE_SCHEME #define play_cursor_example "(play (cursor))" #define play_file_example "(play \"oboe.snd\")" #define play_previous_version_example "(play 0 #f #f #f #f (1- (edit-position)))" #define H_cursor_line S_cursor_line #endif #if HAVE_RUBY #define play_cursor_example "play(cursor())" #define play_file_example "play(\"oboe.snd\")" #define play_previous_version_example "play(0, false, false, false, false, edit_position() - 1)" #define H_cursor_line "Cursor_line" #endif #if HAVE_FORTH #define play_cursor_example "cursor play" #define play_file_example "\"oboe.snd\" play" #define play_previous_version_example "0 #f #f #f #f 0 0 edit-position 1- play" #define H_cursor_line S_cursor_line #endif snd_help_with_xrefs("Play", #if HAVE_EXTENSION_LANGUAGE "To play a sound, click the 'play' button. If the sound has more channels than your DAC(s), Snd will (normally) try to mix the extra channels \ into the available DAC outputs. While it is playing, you can click the button again to stop it, or click some other \ file's 'play' button to mix it into the current set of sounds being played. To play from a particular point, set the cursor \ or a mark \ there, then click its 'play triangle' (the triangular portion below the x axis). (Use control-click here to play all channels \ from the mark point). To play simultaneously from an arbitrary group of start points (possibly spread among many sounds), \ set syncd marks at the start points, then click the play triangle of one of them. \ \n\n\ The Edit menu 'Play' option plays the current selection, if any. The Popup menu's 'Play' option plays the \ currently selected sound. And the region and file browsers provide play buttons for each of the listed regions or files. If you \ hold down the control key when you click 'play', the cursor follows along as the sound is played. \ \n\n\ In a multichannel file, C-q plays all channels from the current channel's \ cursor if the sync button is on, and otherwise plays only the current channel. \ Except in the browsers, what is actually played depends on the control panel.\ \n\n\ Use the play function to play any object.", #else "To play a sound, click the 'play' button. If the sound has more channels than your DAC(s), Snd will (normally) try to mix the extra channels \ into the available DAC outputs. While it is playing, you can click the button again to stop it, or click some other \ file's 'play' button to mix it into the current set of sounds being played. To play from a particular point, set a mark \ there, then click its 'play triangle' (the triangular portion below the x axis). (Use control-click here to play all channels \ from the mark point). To play simultaneously from an arbitrary group of start points (possibly spread among many sounds), \ set syncd marks at the start points, then click the play triangle of one of them. \ \n\n\ The Edit menu 'Play' option plays the current selection, if any. The Popup menu's 'Play' option plays the \ currently selected sound. And the region and file browsers provide play buttons for each of the listed regions or files. If you \ hold down the control key when you click 'play', the cursor follows along as the sound is played. \ \n\n\ In a multichannel file, C-q plays all channels from the current channel's \ cursor if the sync button is on, and otherwise plays only the current channel. \ Except in the browsers, what is actually played depends on the control panel.", #endif WITH_WORD_WRAP, snd_xrefs("Play"), snd_xref_urls("Play")); append_key_help("C-q", snd_K_q, snd_ControlMask, true, true); #else snd_help("Play", "this version of Snd can't play!", WITH_WORD_WRAP); #endif } /* ---------------- Reverb ---------------- */ void reverb_help(void) { #if HAVE_SCHEME #define reverb_control_length_bounds_example "(set! (reverb-control-length-bounds) (list 0.0 10.0))" #define reverb_control_p_example "(set! (reverb-control?) #t)" #define mention_hidden_controls "\nThe lowpass and feedback controls are accessible from the \"Option:Controls\" dialog." #endif #if HAVE_RUBY #define reverb_control_length_bounds_example "set_reverb_control_length_bounds([0.0, 10.0])" #define reverb_control_p_example "set_reverb_control?(true)" #define mention_hidden_controls "" #endif #if HAVE_FORTH #define reverb_control_length_bounds_example "'( 0.0 10.0 ) set-reverb-control-length-bounds" #define reverb_control_p_example "#t set-reverb-control?" #define mention_hidden_controls "" #endif snd_help_with_xrefs("Reverb", #if HAVE_EXTENSION_LANGUAGE "The reverb in the control panel is a version of Michael McNabb's Nrev (if it seems to be \ non-functional, make sure the reverb button on the far right is clicked). There are other \ reverbs mentioned in the related topics list. The control panel reverb functions are:\n\ \n\ " S_reverb_control_decay " (:optional snd):\n\ length (in seconds) of the reverberation after the sound has finished\n\ \n\ " S_reverb_control_feedback " (:optional snd):\n\ reverb feedback coefficient\n\ \n\ " S_reverb_control_length " (:optional snd):\n\ reverb delay line length scaler. \n\ Longer reverb simulates a bigger hall.\n\ \n\ " S_reverb_control_length_bounds " (:optional snd):\n\ reverb-control-length min and max amounts as a list\n\ " reverb_control_length_bounds_example "\n\ \n\ " S_reverb_control_lowpass " (:optional snd):\n\ reverb low pass filter coefficient. (filter in feedback loop).\n\ \n\ " S_reverb_control_on " (:optional snd):\n\ " PROC_TRUE " if the reverb button is set (i.e. the reverberator is active).\n\ " reverb_control_p_example "\n\ \n\ " S_reverb_control_scale " (:optional snd):\n\ reverb amount (the amount of the direct signal sent to the reverb).\n\ \n\ " S_reverb_control_scale_bounds " (:optional snd):\n\ reverb-control-scale min and max amounts as a list.\n" mention_hidden_controls "\n", #else "The reverb in the control panel is a version of Michael McNabb's Nrev (if it seems to be \ non-functional, make sure the reverb button on the far right is clicked).", #endif WITH_WORD_WRAP, snd_xrefs("Reverb"), snd_xref_urls("Reverb")); } /* ---------------- Save ---------------- */ void save_help(void) { snd_help_with_xrefs("Save", "To save the current edited state of a file, use the File:Save option (to overwrite the old version of the \ file), or File:Save as (to write to a new file, leaving the old file unchanged). The equivalent keyboard \ command is C-x C-s (save). ", WITH_WORD_WRAP, snd_xrefs("Save"), snd_xref_urls("Save")); append_key_help("C-x C-s", snd_K_s, snd_ControlMask, true, true); } /* ---------------- Filter ---------------- */ void filter_help(void) { #if HAVE_SCHEME #define filter_sound_env_example "(filter-sound '(0 1 1 0) 1024)" #define filter_sound_vct_example "(filter-sound (float-vector .1 .2 .3 .3 .2 .1) 6)" #define filter_sound_clm_example "(filter-sound (make-filter 2 (float-vector 1 -1) (float-vector 0 -0.99)))" #endif #if HAVE_RUBY #define filter_sound_env_example "filter_sound([0.0, 1.0, 1.0, 0.0], 1024)" #define filter_sound_vct_example "filter_sound(vct(0.1, 0.2, 0.3, 0.3, 0.2, 0.1), 6)" #define filter_sound_clm_example "filter_sound(make_filter(2, vct(1.0, -1.0), vct(0.0, -0.99)))" #endif #if HAVE_FORTH #define filter_sound_env_example "'( 0.0 1.0 1.0 0.0 ) 1024 filter-sound" #define filter_sound_vct_example "'( .1 .2 .3 .3 .2 .1 ) list->vct 6 filter-sound" #define filter_sound_clm_example "2 '( 1 -1 ) list->vct '( 0.0 -0.99 ) list->vct make-filter filter-sound" #endif snd_help_with_xrefs("Filter", #if HAVE_EXTENSION_LANGUAGE "There is an FIR Filter in the control panel, a filtering option in the envelope editor dialog, and a variety of other filters scattered around; \ see sndclm.html, dsp." Xen_file_extension " and analog-filters." Xen_file_extension " in particular. The \ built-in filtering functions include: \n\ \n\ " S_filter_channel " (env :optional order beg dur snd chn edpos trunc origin)\n\ apply FIR filter to channel; 'env' is frequency response.\n\ \n\ " S_filter_selection " (env :optional order truncate)\n\ apply FIR filter with frequency response 'env' to the selection.\n\ \n\ " S_filter_sound " (env :optional order snd chn edpos origin)\n\ apply FIR filter with freq response, clm gen, or coeffs 'env'\n\ \n\ " filter_sound_env_example "\n\ " filter_sound_vct_example "\n\ " filter_sound_clm_example "\n\ \n\ The control filter functions are:\n\ \n\ " S_filter_control_coeffs " (:optional snd)\n\ filter coefficients (read-only currently)\n\ \n\ " S_filter_control_envelope " (:optional snd)\n\ filter (frequency reponse) envelope\n\ \n\ " S_filter_control_in_dB " (:optional snd)\n\ The filter dB button. If " PROC_TRUE ", the graph is displayed in dB.\n\ \n\ " S_filter_control_in_hz " (:optional snd)\n\ If " PROC_TRUE ", the filter frequency response envelope x axis is in Hz,\n\ otherwise 0 to 1.0 (where 1.0 corresponds to srate/2).\n\ \n\ " S_filter_control_order " (:optional snd)\n\ The filter order\n\ \n\ " S_filter_control_on " (:optional snd)\n\ " PROC_TRUE " if the filter is active.\n\ \n\ " S_filter_control_waveform_color "\n\ The filter frequency response waveform color.\n", #else "There is an FIR Filter in the control panel, and a filtering option in the Edit envelope dialog.", #endif WITH_WORD_WRAP, snd_xrefs("Filter"), snd_xref_urls("Filter")); } /* ---------------- Resample ---------------- */ void resample_help(void) { #if HAVE_SCHEME #define src_number_example "(src-channel 2.0) ; go twice as fast" #define src_env_example "(src-channel '(0 1 1 2))" #define src_clm_example "(src-channel (make-env '(0 1 1 2) :end (framples)))" #define H_speed_control_as_float S_speed_control_as_float #define H_speed_control_as_ratio S_speed_control_as_ratio #define H_speed_control_as_semitone S_speed_control_as_semitone #define H_src_duration "src-duration" #endif #if HAVE_RUBY #define src_number_example "src_channel(2.0) # go twice as fast" #define src_env_example "src_channel([0.0, 1.0, 1.0, 2.0])" #define src_clm_example "src_channel(make_env([0.0, 1.0, 1.0, 2.0], :end, framples()))" #define H_speed_control_as_float "Speed_control_as_float" #define H_speed_control_as_ratio "Speed_control_as_ratio" #define H_speed_control_as_semitone "Speed_control_as_semitone" #define H_src_duration "src_duration" #endif #if HAVE_FORTH #define src_number_example "2.0 src-channel \\ go twice as fast" #define src_env_example "'( 0.0 1.0 1.0 2.0 ) src-channel" #define src_clm_example "'( 0.0 1.0 1.0 2.0 ) :end 0 0 -1 framples make-env src-channel" #define H_speed_control_as_float S_speed_control_as_float #define H_speed_control_as_ratio S_speed_control_as_ratio #define H_speed_control_as_semitone S_speed_control_as_semitone #define H_src_duration "src-duration" #endif snd_help_with_xrefs("Resample", #if HAVE_EXTENSION_LANGUAGE "There is a sampling rate changer in the control panel, and a resampling option in the envelope \ editor dialog; see also sndclm.html and examp." Xen_file_extension ". \ The basic resampling functions are:\n\ \n\ " S_src_channel " (num-or-env :optional beg dur snd chn edpos)\n\ resample (change the speed/pitch of) a channel.\n\ 'num-or-env' can be the resampling ratio (higher=faster)\n\ an envelope, or a CLM env generator:\n\ \n\ " src_number_example "\n\ " src_env_example "\n\ " src_clm_example "\n\ \n\ In the envelope case, the function " H_src_duration " can help \n\ you predict the result's duration.\n\ \n\ " S_src_selection " (num-or-env :optional base)\n\ apply sampling rate conversion to the selection\n\ \n\ " S_src_sound " (num-or-env :optional base snd chn edpos)\n\ resample sound\n\ \n\ The control panel 'speed' functions are:\n\ \n\ " S_speed_control " (:optional snd)\n\ current speed (sampling rate conversion factor)\n\ \n\ " S_speed_control_bounds " (:optional snd)\n\ speed-control min and max amounts as a list.\n\ The default is (list 0.05 20.0). If no 'snd' argument\n\ is given, this affects Mix and View:Files dialogs.\n\ \n\ " S_speed_control_style " (:optional snd)\n\ The speed control can be a float, (" H_speed_control_as_float "),\n\ a ratio of integers (" H_speed_control_as_ratio "), or a step \n\ in a (possibly microtonal) scale (" H_speed_control_as_semitone ")\n\ \n\ " S_speed_control_tones " (:optional snd)\n\ number of tones per octave in the " H_speed_control_as_semitone "\n\ speed style (default: 12).", #else "There is a sampling rate changer in the control panel, and a resampling option in the Edit envelope dialog.", #endif WITH_WORD_WRAP, snd_xrefs("Resample"), snd_xref_urls("Resample")); } /* ---------------- Insert ---------------- */ void insert_help(void) { snd_help_with_xrefs("Insert", #if HAVE_EXTENSION_LANGUAGE "C-o inserts a \ zero sample at the cursor. There are also the File:Insert and Edit:Insert Selection \ dialogs. The insertion-related functions are:\n\ \n\ " S_pad_channel " (beg dur :optional snd chn edpos)\n\ insert 'dur' zeros at 'beg'\n\ \n\ " S_insert_silence " (beg num :optional snd chn)\n\ insert 'num' zeros at 'beg'\n\ \n\ " S_insert_region " (:optional beg reg snd chn)\n\ insert region 'reg' at sample 'beg'\n\ \n\ " S_insert_selection " (:optional beg snd chn)\n\ insert selection starting at 'beg'\n\ \n\ " S_insert_sample " (samp value :optional snd chn edpos)\n\ insert sample 'value' at sample 'samp'\n\ \n\ " S_insert_samples " (samp samps data :optional snd chn pos del org)\n\ insert 'samps' samples of 'data' (normally a " S_vct ") starting at\n\ sample 'samp'. 'data' can also be a filename.\n\ \n\ " S_insert_sound " (file :optional beg in-chan snd chn pos del)\n\ insert channel 'in-chan' of 'file' at sample 'beg' (cursor position\n\ by default). If 'in-chan' is not given (or is " PROC_FALSE "), all\n\ channels are inserted.\n", #else "C-o inserts a \ zero sample at the cursor. There are also the File:Insert and Edit:Insert Selection dialogs.", #endif WITH_WORD_WRAP, snd_xrefs("Insert"), snd_xref_urls("Insert")); append_key_help("C-o", snd_K_o, snd_ControlMask, false, true); } /* ---------------- Delete ---------------- */ void delete_help(void) { snd_help_with_xrefs("Delete", #if HAVE_EXTENSION_LANGUAGE "To delete a sample, use C-d; to delete the selection, C-w. The main deletion-related \ functions are:\n\ \n\ " S_delete_sample " (samp :optional snd chn edpos)\n\ delete sample number 'samp'.\n\ \n\ " S_delete_samples " (samp samps :optional snd chn edpos)\n\ delete 'samps' samples starting at 'samp'\n\ \n\ " S_delete_selection " (): delete selected portions.\n\ " S_delete_mark " (id): delete mark 'id'", #else "To delete a sample, use C-d; to delete the selection, C-w, or the Edit menu Delete Selection option.", #endif WITH_WORD_WRAP, snd_xrefs("Delete"), snd_xref_urls("Delete")); append_key_help("C-w", snd_K_w, snd_ControlMask, false, append_key_help("C-d", snd_K_d, snd_ControlMask, false, true)); } /* ---------------- Regions ---------------- */ void region_help(void) { #if HAVE_SCHEME #define region_to_vct_example "(region->float-vector 0 0 reg) ; len=0 => entire region" #define save_region_example "(save-region reg :file \"reg0.snd\" :header-type mus-next)" #endif #if HAVE_RUBY #define region_to_vct_example "region2vct(0, 0, reg) # len=0 => entire region" #define save_region_example "save_region(reg, :file, \"reg0.snd\", :header_type, Mus_next)" #endif #if HAVE_FORTH #define region_to_vct_example "0 0 reg region->vct \\ len=0 => entire region" #define save_region_example "reg :file \"reg0.snd\" :header-type mus-next save-region" #endif snd_help_with_xrefs("Region", #if HAVE_EXTENSION_LANGUAGE "A region is a saved portion of the sound data. When a sound portion is selected, it is (by default) saved \ as the new region; subsequent edits will not affect the region data. You can disable the region creation \ by setting the variable " S_selection_creates_region " to " PROC_FALSE " (its default is " PROC_TRUE " which can slow down editing \ of very large sounds). Regions can be defined by " S_make_region ", by dragging the mouse through a portion \ of the data, or via the Select All menu option. If the mouse drags off the end of the graph, the x axis \ moves, in a sense dragging the data along to try to keep up with the mouse; the further away the mouse \ is from the display, the faster the axis moves. A region can also be defined with keyboard commands, \ much as in Emacs. C-[space] starts the region definition and the various cursor moving commands \ continue the definition. As regions are defined, the new ones are pushed on a stack, and if enough regions already exist, \ old ones are pushed off (and deleted) to make room. Each region has a unique id returned \ by " S_make_region " and shown beside the region name in the Region Browser. \ Most of the region arguments below default to the current region (the top of the regions stack). \ The main region-related functions are:\n\ \n\ " S_view_regions_dialog ": start the Region browser\n\ " S_save_region_dialog ": start the Save region dialog\n\ \n\ " S_insert_region " (:optional beg reg snd chn)\n\ insert region 'reg' at sample 'beg'\n\ \n\ " S_mix_region " (:optional samp reg snd chn reg-chan)\n\ mix in region 'reg' at sample 'samp' (defaults to the cursor sample)\n\ \n\ " S_save_region " (reg :file :header-type :sample-type :comment)\n\ save region 'reg' in 'file' in sample-type (default is mus-bshort),\n\ header type (default is mus-next), and comment. Return the output\n\ filename.\n\ \n\ " save_region_example "\n\ \n\ " S_region_to_vct " (:optional samp samps reg chn v)\n\ return a " S_vct " containing 'samps' samples starting at 'samp'\n\ in region 'reg's channel 'chn'. If 'v' (a " S_vct ") is provided,\n\ it is filled, rather than creating a new " S_vct ".\n\ \n\ " region_to_vct_example "\n\ \n\ " S_make_region " (:optional beg end snd chn)\n\ create a new region spanning samples 'beg' to 'end';\n\ return the new region's id.\n\ \n\ " S_forget_region " (:optional reg): remove region from region list\n\ \n\ " S_is_region " (reg): " PROC_TRUE " if 'reg' is a known region id\n\ \n\ " S_regions ": list of currently active regions\n\ \n\ " S_max_regions ": how big the region stack can get\n\ \n\ " S_selection_creates_region ": does making a selection create a region\n\ \n\ " S_region_chans " (:optional reg): region chans\n\ " S_region_framples " (:optional reg chan): region length\n\ " S_region_maxamp " (:optional reg): region maxamp\n\ " S_region_maxamp_position " (:optional reg): maxamp location (sample number)\n\ " S_region_position " (:optional reg chan): original begin time of region\n\ " S_region_sample " (:optional samp reg chan): sample value\n\ " S_region_srate " (:optional reg): original data's sampling rate\n", #else "A region is a portion of the sound data. When a sound portion is selected, it is (by default) saved \ as the new region; subsequent edits will not affect the region data. \ of very large sounds). Regions can be defined by dragging the mouse through a portion \ of the data, or via the Select All menu option. If the mouse drags off the end of the graph, the x axis \ moves, in a sense dragging the data along to try to keep up with the mouse; the further away the mouse \ is from the display, the faster the axis moves. A region can also be defined with keyboard commands, \ much as in Emacs. C-[space] starts the region definition and the various cursor moving commands \ continue the definition.", #endif WITH_WORD_WRAP, snd_xrefs("Region"), snd_xref_urls("Region")); append_key_help("C-[space]", snd_K_space, snd_ControlMask, false, true); } /* ---------------- Selections ---------------- */ void selection_help(void) { #if HAVE_SCHEME #define env_selection_example "(env-selection '(0 0 1 1 2 0))" #define save_selection_example "(save-selection \"sel.snd\" :channel 1)" #define scale_selection_list_example "(scale-selection-by '(0.0 2.0))" #define scale_selection_number_example "(scale-selection-by 2.0)" #endif #if HAVE_RUBY #define env_selection_example "env_selection([0.0, 0.0, 1.0, 1.0, 2.0, 0.0])" #define save_selection_example "save_selection(\"sel.snd\", :channel, 1)" #define scale_selection_list_example "scale_selection_by([0.0, 2.0])" #define scale_selection_number_example "scale_selection_by(2.0)" #endif #if HAVE_FORTH #define env_selection_example "'( 0.0 0.0 1.0 1.0 2.0 0.0 ) env-selection" #define save_selection_example "\"sel.snd\" :channel 1 save-selection" #define scale_selection_list_example "'( 0.0 2.0 ) scale-selection-by" #define scale_selection_number_example "2.0 scale-selection-by" #endif snd_help_with_xrefs("Selection", #if HAVE_EXTENSION_LANGUAGE "The selection is a high-lighted portion of the current sound. \ You can create it by dragging the mouse through the data, or via various functions. \ The primary selection-related functions are:\n\ \n\ " S_convolve_selection_with " (file :optional amp)\n\ convolve the selected portion with 'file'\n\ \n\ " S_delete_selection " (): delete the selected portion\n\ \n\ " S_env_selection " (envelope :optional env-base)\n\ apply amplitude envelope to selected portion\n\ \n\ " env_selection_example "\n\ \n\ " S_filter_selection " (env :optional order truncate)\n\ apply an FIR filter with frequency response 'env' to the \n\ selection. env can be the filter coefficients themselves in\n\ a " S_vct " with at least 'order' elements, or a CLM filter\n\ \n\ " S_insert_selection " (:optional beg snd chn)\n\ insert (a copy of) selection starting at 'beg'\n\ \n\ " S_mix_selection " (:optional beg snd chn selection-chan)\n\ mix (add) selection starting at 'beg'\n\ \n\ " S_reverse_selection "(): reverse selected portion\n\ \n\ " S_save_selection " (:file (:header-type mus-next)\n\ :sample-type :srate :comment :channel)\n\ save the selection in file. If channel is given, save\n\ only that channel.\n\ \n\ " save_selection_example "\n\ \n\ " S_scale_selection_by " (scalers)\n\ scale the selection by 'scalers' which can be either a float,\n\ a list of floats, or a " S_vct ". In a multichannel selection, each\n\ member of the " S_vct " or list is applied to the next channel in the\n\ selection. " scale_selection_list_example " scales the first\n\ channel by 0.0, the second (if any) by 2.0.\n\ " scale_selection_number_example " scales all channels by 2.0.\n\ \n\ " S_scale_selection_to " (norms)\n\ normalize the selection to norms which can be either a float,\n\ a list of floats, or a " S_vct ".\n\ \n\ " S_select_all " (:optional snd chn)\n\ select all samples\n\ \n\ " S_smooth_selection "()\n\ apply a smoothing function to the selection. \n\ This produces a sinusoid between the end points.\n\ \n\ " S_src_selection " (num-or-env :optional base)\n\ apply sampling rate conversion to the selection\n\ \n\ " S_save_selection_dialog " (:optional managed)\n\ start the Save Selection dialog.\n\ \n\ " S_selection_creates_region "\n\ if " PROC_TRUE ", a region is created whenever a selection is made.\n\ \n\ " S_selection_chans ": chans in selection\n\ " S_selection_color ": color to highlight selection\n\ " S_selection_framples " (:optional snd chn): length of selection\n\ " S_selection_maxamp " (:optional snd chn): maxamp of selection\n\ " S_selection_maxamp_position " (:optional snd chn): sample number of maxamp\n\ " S_selection_member " (:optional snd chn): \n\ " PROC_TRUE " if snd's channel chn has selected data.\n\ " S_is_selection ": " PROC_TRUE " if there's a selection\n\ " S_selection_position " (:optional snd chn): \n\ sample number where selection starts\n\ " S_selection_srate ": nominal srate of selected portion.\n\ \n\ There are many more selection-oriented functions scattered around the various *." Xen_file_extension " files. \ See the related topics list below.", #else "The selection is a high-lighted portion of the current sound. \ You can create it by dragging the mouse.", #endif WITH_WORD_WRAP, snd_xrefs("Selection"), snd_xref_urls("Selection")); } /* ---------------- Colors ---------------- */ void colors_help(void) { #if HAVE_SCHEME #define make_color_example "(define blue (make-color 0.0 0.0 1.0))" #define set_basic_color_example "(set! (basic-color) blue)" #endif #if HAVE_RUBY #define make_color_example "Blue = make_color(0.0, 0.0, 1.0)" #define set_basic_color_example "set_basic_color(Blue)" #endif #if HAVE_FORTH #define make_color_example ": blue 0 0 1 make-color ;" #define set_basic_color_example "blue set-basic-color" #endif snd_help_with_xrefs("Colors", #if HAVE_EXTENSION_LANGUAGE "A color in Snd is an object with three fields representing the rgb (red green blue) settings \ as numbers between 0.0 and 1.0. A color object is created via " S_make_color ":\n\ " make_color_example "\n\ \n\ This declares the variable \"blue\" and gives it the value of the color whose rgb components \ include only blue in full force. The X11 color names are defined in rgb." Xen_file_extension ". The overall widget background color is " S_basic_color ".\n\ \n\ " set_basic_color_example "\n\ \n\ The color variables are:\n\ " S_basic_color ": main Snd color.\n\ " S_cursor_color ": cursor color.\n\ " S_data_color ": color of data in unselected graph.\n\ " S_enved_waveform_color ": color of waveform displayed in envelope editor.\n\ " S_filter_control_waveform_color ": color of control panel filter waveform.\n\ " S_graph_color ": background color of unselected graph.\n\ " S_highlight_color ": highlighting color.\n\ " S_listener_color ": background color of lisp listener.\n\ " S_listener_text_color ": text color in lisp listener.\n\ " S_mark_color ": color of mark indicator.\n\ " S_mix_color ": color of mix waveforms.\n\ " S_position_color ": position slider color\n\ " S_sash_color ": color of paned window sashes.\n\ " S_selected_data_color ": color of data in currently selected graph.\n\ " S_selected_graph_color ": background color of currently selected graph.\n\ " S_selection_color ": color of selected portion of graph.\n\ " S_text_focus_color ": color of text field when it has focus.\n\ " S_zoom_color ": zoom slider color.\n\ \n\ The easiest way to try out other colors is to use the Options:Preferences dialog. \ The sonogram colors can be set in the View:Colors dialog.", #else "To change the various Snd colors, use the Options:Preferences Dialog. The sonogram colors can be set in the View:Colors dialog.", #endif WITH_WORD_WRAP, snd_xrefs("Color"), snd_xref_urls("Color")); } /* -------- dialog help texts -------- */ /* ---------------- Envelope Editor ---------------- */ void envelope_editor_dialog_help(void) { #if HAVE_SCHEME #define define_envelope_name "define, or define-envelope" #define ramp_envelope_example "'(0 0 1 1)" #define define_envelope_example " (define-envelope pyramid '(0 0 1 1 2 0))" #endif #if HAVE_RUBY #define define_envelope_name "define_envelope" #define ramp_envelope_example "[0.0, 0.0, 1.0, 1.0]" #define define_envelope_example " define_envelope(\"ramp\", [0.0, 0.0, 1.0, 1.0])\n define_envelope(\"pyramid\", [0.0, 0.0, 1.0, 1.0, 2.0, 0.0])" #endif #if HAVE_FORTH #define define_envelope_name "define-envelope" #define ramp_envelope_example "'( 0.0 0.0 1.0 1.0 )" #define define_envelope_example " \"ramp\" '( 0.0 0.0 1.0 1.0 ) define-envelope\n \"pyramid\" '( 0.0 0.0 1.0 1.0 2.0 0.0 ) define-envelope" #endif #if (!HAVE_EXTENSION_LANGUAGE) #define define_envelope_name "" #define ramp_envelope_example "'(0 0 1 1)" #define define_envelope_example "" #endif snd_help_with_xrefs("Envelope Editor", "The Edit Envelope dialog (under the Edit menu) opens a window for viewing and editing envelopes. \ The dialog has a display showing either the envelope currently being edited or \ a panorama of all currently loaded envelopes. The current envelope can be edited with the mouse: click at some spot in the graph to place a \ new breakpoint, drag an existing breakpoint to change its position, and click an existing breakpoint to delete it. \ The Undo and Redo buttons can be used to move around in the list of envelope edits; the current state \ of the envelope can be saved with the 'save' button. Envelopes can be defined via " define_envelope_name ": \ \n\n" define_envelope_example "\n\n\ defines two envelopes that can be used in Snd wherever an envelope is needed. You can also define \ a new envelope in the dialog's text field; " ramp_envelope_example " creates a ramp as a new envelope. \ \n\n\ In the overall view of envelopes, click an envelope, or click its name in the scrolled \ list on the left to select it; click the selected envelope to load it into the editor portion, clearing out whatever \ was previously there. To load an existing envelope into the editor, you can also type its name in the text field; to give a name to \ the envelope as it is currently defined in the graph viewer, type its name in this field, then \ either push return or the 'save' button. \ \n\n\ Once you have an envelope in the editor, you can apply it to the current sounds with the 'Apply' or 'Undo&Apply' buttons; the latter \ first tries to undo the previous edit, then applies the envelope. The envelope can be applied to \ the amplitude, the spectrum, or the sampling rate. The choice is made via the three buttons marked 'amp', \ 'flt', and 'src'. The filter order is the variable " S_enved_filter_order " which defaults to 40. To use fft-filtering (convolution) \ instead, click the 'fir' button, changing its label to 'fft'. If you are displaying the fft graph of the current channel, \ and the fft is large enough to include the entire sound, and the 'wave' button is set, \ the spectrum is also displayed in the envelope editor, making it easier to perform accurate (fussy?) filtering operations. \ \n\n\ To apply the envelope to the current selection, rather than the current sound, set the 'selection' button. \ To apply it to the currently selected mix, set the 'mix' button. \ control-click 'mix' to load the current mix amplitude \ envelope into the editor. \ \n\n\ The two toggle buttons at the lower right choose whether to show a light-colored version of \ the currently active sound (the 'wave' button), and whether to clip mouse movement at the current y axis bounds (the \ 'clip' button). The 'linear' and 'exp' buttons choose the type of connecting lines, and the 'exp base' slider at \ the bottom sets the 'base' of the exponential curves, just as in CLM. If the envelope is being treated as a spectrum ('flt' \ is selected), the 'wave' button shows the actual frequency response of the filter that will be applied to the waveform \ by the 'apply' buttons. Increase the " S_enved_filter_order " to \ improve the fit. In this case, the X axis goes from 0 Hz to half the sampling rate, labelled as 1.0.", WITH_WORD_WRAP, snd_xrefs("Envelope"), snd_xref_urls("Envelope")); } /* ---------------- Transform Options ---------------- */ void transform_dialog_help(void) { snd_help_with_xrefs("Transform Options", "This dialog presents the various transform (fft) related choices. \ \n\n\ On the upper left is a list of available transform types; next on the right is a list of fft sizes; \ next is a panel of buttons that sets various display-oriented choices; the lower left panel \ sets the current wavelet, when relevant; next is the fft data window choice; and next to it is a \ graph of the current fft window; when the window has an associated parameter (sometimes known as \ 'alpha' or 'beta'), the slider beneath the window list is highlighted and can be used to choose the \ desired member of that family of windows. The lower (second) scale sets the 'mu' parameter in the ultraspherical window. \ \n\n\ If the 'selection' button is not set, the FFT is taken from the start (the left edge) of the \ current window and is updated as the window bounds change; otherwise the FFT is taken over the extent \ of the selection, if any is active in the current channel. The fft data is scaled to fit \ between 0.0 and 1.0 unless the fft normalization is off. The full frequency axis is normally \ displayed, but the axis is 'draggable' -- put the mouse on the axis and drag it either way to change \ the range (this is equivalent to changing the variable " S_spectrum_end "). You can also click on \ any point in the fft to get the associated fft data displayed; if " S_with_verbose_cursor " is on, you can \ drag the mouse through the fft display and the description in the minibuffer will be constantly updated. \ \n\n\ The harmonic analysis function is normally the Fourier Transform, but others are available, \ including about 20 wavelet choices. \ \n\n\ The top three buttons in the transform dialog choose between a normal fft, a sonogram, or a \ spectrogram. The 'peaks' button affects whether peak info is displayed alongside the graph of the \ spectrum. The 'dB' button selects between a linear and logarithmic Y (magnitude) axis. The 'log freq' \ button makes a similar choice along the frequency axis. \ \n\n\ If you choose dB, the fft window graph (in the lower right) displays the window spectrum in dB, \ but the y axis labelling is still 0.0 to 1.0 to reflect the fact that the fft window itself is still displayed \ in linear terms.", WITH_WORD_WRAP, snd_xrefs("FFT"), snd_xref_urls("FFT")); } /* ---------------- Color/Orientation Dialog ---------------- */ static const char *color_orientation_dialog_xrefs[11] = { "colormap variable: {colormap}", "orientation variables: {" S_spectro_x_scale "}, {" S_spectro_x_angle "}, etc", "colormap constants: rgb." Xen_file_extension, "colormap colors: {" S_colormap_ref "}", "color dialog variables: {" S_color_cutoff "}, {" S_color_inverted "}, {" S_color_scale "}", "start the color/orientation dialog: {" S_color_orientation_dialog "}", "add a new colormap: {" S_add_colormap "}", "remove a colormap: {" S_delete_colormap "}", "specialize orientation dialog actions: {" S_orientation_hook "}", "specialize color dialog actions: {" S_color_hook "}", NULL}; void color_orientation_dialog_help(void) { snd_help_with_xrefs("View Color/Orientation", "This dialog sets the viewing projection (\"orientation\"), colormap and associated settings used during sonogram, spectrogram, \ and wavogram display. The cutoff scale refers to the minimum data value to be displayed. \ You can add your own colormaps to the list via " S_add_colormap ", or delete one with " S_delete_colormap ".\ The 'angle' scalers change the viewing angle, the 'scale' scalers change the 'stretch' amount \ along a given axis, and 'hop' refers to the density of the traces (the jump in samples between successive \ ffts or time domain scans). If the 'use openGL' button is set, the \ spectrogram is drawn by openGL. In the spectrogram, 'x' refers to the time axis, \ 'y' to the amplitude axis, and 'z' to the frequency axis.", WITH_WORD_WRAP, color_orientation_dialog_xrefs, NULL); } /* ---------------- Region Dialog ---------------- */ void region_dialog_help(void) { snd_help_with_xrefs("Region Browser", "This is the 'region browser'. The scrolled window contains the list of current regions \ with a brief title to indicate the source thereof, and a button to play the region. \ One channel of the currently selected region is displayed in the graph window. The up and \ down arrows move up or down in the region's list of channels. If you click a region's \ title, that region is displayed in the graph area. The 'print' button produces a Postscript \ rendition of the current graph contents, using the default eps output name. 'play' plays the region. \ The 'edit' button loads the region into the main editor as a temporary file. It can be edited or renamed, etc. If you save \ the file, the region is updated to reflect any edits you made.", WITH_WORD_WRAP, snd_xrefs("Region"), snd_xref_urls("Region")); } /* ---------------- Raw Sound Dialog ---------------- */ static const char *raw_xrefs[7] = { "specialize handing of raw sounds: {" S_open_raw_sound_hook "}", "open a headerless sound: {" S_open_raw_sound "}", "header type constants: {" S_mus_header_type_name "}", "sample type constants: {" S_mus_sample_type_name "}", "what are these sample types?", "what are these headers?", NULL}; static const char *raw_urls[7] = { NULL, NULL, NULL, NULL, "extsnd.html#sampletype", "extsnd.html#headertype", NULL }; void raw_data_dialog_help(const char *info) { if (info) { snd_help_with_xrefs("Raw Data", "This file seems to have an invalid header. I'll append what sense I can make of it. \ To display and edit sound data, Snd needs to know how the data's sampling rate, number \ of channels, and sample type.\n\n", WITH_WORD_WRAP, raw_xrefs, raw_urls); snd_help_append(info); } else { snd_help_with_xrefs("Raw Data", "To display and edit sound data, Snd needs to know how the data's sampling rate, number \ of channels, and sample type. This dialog gives you a chance to set those fields. \ To use the defaults, click the 'Reset' button.", WITH_WORD_WRAP, raw_xrefs, NULL); } } /* ---------------- Save as Dialog ---------------- */ void save_as_dialog_help(void) { snd_help_with_xrefs("Save As", "You can save the current state of a file with File:Save As, or the current selection with Edit:Save as. \ The output header type, sample type, sampling rate, and comment can also be set. If the 'src' button \ is not set, setting the srate does not affect the data -- it is just a number placed in the sound file header. \ Otherwise, if the output sampling rate differs from the current one, the data is converted to the new rate automatically. \ The notation \"(be)\" in the sample type lists stands for big endian; similarly, \"(le)\" is little endian.\ If a file by the chosen name already exists \ it is overwritten, unless that file is already open in Snd and has edits. In that case, \ you'll be asked what to do. If you want to be warned whenever a file is about to be overwritten by this \ option, set the variable " S_ask_before_overwrite " to " PROC_TRUE ". \ If you give the current file name to Save As, \ any current edits will be saved and the current version in Snd will be updated (that is, in this \ case, the edit tree is not preserved). To save (extract) just one channel of a multichannel file, \ put the (0-based) channel number in the 'extract channel' field, then click 'Extract', rather \ than 'Save'.", WITH_WORD_WRAP, snd_xrefs("Save"), snd_xref_urls("Save")); } /* ---------------- Open File ---------------- */ static const char *open_file_xrefs[] = { "open file: {" S_open_sound "}", "add to sound file extension list (for '" S_just_sounds "'): {" S_add_sound_file_extension "}", "specialize open: {" S_open_hook "}, {" S_after_open_hook "}, etc", "start the file dialog: {" S_open_file_dialog "}", #if HAVE_SCHEME "specialize file list: {install-searcher} in snd-motif.scm", "keep dialog active after opening: {keep-file-dialog-open-upon-ok} in snd-motif.scm", #endif NULL}; void open_file_dialog_help(void) { #if USE_MOTIF snd_help_with_xrefs("Open File", "The file selection dialog is slightly different from the Gtk or Motif default. If you single click \ in the directory list, that directory is immediately opened and displayed. Also there are \ two popup menus to set the \ current sort routine (right click over the file list), and jump to a higher level directory (right click \ in the directory list). \ The 'sound files only' button filters out all non-sound files from the files list (using the \ extension -- you can add to the list of sound file extensions via " S_add_sound_file_extension ". \ When a sound file is selected, information about it is posted under the lists, and a 'play' \ button is displayed. The name field has completion, of course, and also \ watches as you type a new name, reflecting that partial name by moving the file list to \ display possible matches.", WITH_WORD_WRAP, open_file_xrefs, NULL); #else snd_help_with_xrefs("Open File", "This dialog provides a clumsy way to open a file.", WITH_WORD_WRAP, open_file_xrefs, NULL); #endif } /* ---------------- Mix File ---------------- */ void mix_file_dialog_help(void) { snd_help_with_xrefs("Mix File", "The file will be mixed (added into the selected sound) at the cursor. If you click the 'Sound Files Only' button, \ only those files in the current directory that look vaguely like sound files will be displayed. For more control \ of the initial mix, use the View:Files dialog. To edit the mix, use the View:Mixes dialog.", WITH_WORD_WRAP, snd_xrefs("Mix"), snd_xref_urls("Mix")); } /* ---------------- Insert File ---------------- */ void insert_file_dialog_help(void) { snd_help_with_xrefs("Insert File", "The file will be inserted (pasted into the selected file) at the cursor. If you click the 'Sound Files Only' button, \ only those files in the current directory that look vaguely like sound files will be displayed. For more control \ of the insertion, use the View:Files dialog.", WITH_WORD_WRAP, snd_xrefs("Insert"), snd_xref_urls("Insert")); } /* ---------------- Find Dialog ---------------- */ void find_dialog_help(void) { #if HAVE_SCHEME #define find_example "(lambda (n) (> n .1))" #define zero_plus "zero+" #define closure_example " (define (zero+)\n (let ((lastn 0.0))\n (lambda (n)\n (let ((rtn (and (< lastn 0.0) (>= n 0.0) -1)))\n (set! lastn n)\n rtn)))" #endif #if HAVE_RUBY #define find_example "lambda do |y| y > 0.1 end" #define zero_plus "zero_plus" #define closure_example "def zero_plus\n lastn = 0.0\n lambda do |n|\n rtn = lastn < 0.0 and n >= 0.0 and -1\n lastn = n\n rtn\n end\nend" #endif #if HAVE_FORTH #define find_example "lambda: <{ y }> 0.1 y f< ;" #define zero_plus "zero+" #define closure_example ": zero+ ( -- prc; n self -- val )\n lambda-create 0.0 ( lastn ) , latestxt 1 make-proc\n does> { n self -- val }\n self @ ( lastn ) f0< n f0>= && -1 && { rtn }\n n self ! ( lastn = n )\n rtn\n;" #endif snd_help_with_xrefs("Search all sounds", #if HAVE_EXTENSION_LANGUAGE "This search travels through all the current channels in parallel until a match is found. The find \ expression is a function of one argument, the current sample value. It is evaluated on each sample, and should return " PROC_TRUE " when the \ search is satisfied. For example, \n\n " find_example "\n\nlooks for the next sample that is greater than .1. \ If you need to compare the current sample with a previous one, use a 'closure' as in " zero_plus " in \ examp." Xen_file_extension ": \n\n" closure_example "\n\nThere are several other \ search function examples in that file that search for peaks, clicks, or a particular pitch.", #else "This search mechanism is built on the extension language, which isn't available in this version of Snd.", #endif WITH_WORD_WRAP, snd_xrefs(I_FIND), snd_xref_urls(I_FIND)); } /* ---------------- Mix Dialog ---------------- */ void mix_dialog_help(void) { #if HAVE_EXTENSION_LANGUAGE #define mix_dialog_mix_help "The function " S_mix_dialog_mix " gives (or sets) the currently displayed mix's id. " #else #define mix_dialog_mix_help "" #endif snd_help_with_xrefs("Mixes", "This dialog provides various commonly-used controls on the currently \ chosen mix. At the top are the mix id, begin and end times, \ and a play button. " mix_dialog_mix_help "Beneath that are various sliders \ controlling the speed (sampling rate) and amplitude of the mix, \ and finally, an envelope editor for the mix. \ The current mix amp env is not actually changed until you click 'Apply Env'.\ The editor envelope is drawn in black with dots whereas the current \ mix amp env (if any) is drawn in blue.", WITH_WORD_WRAP, snd_xrefs("Mix"), snd_xref_urls("Mix")); } /* ---------------- New File ---------------- */ static const char *new_file_xrefs[5] = { "open a new sound: {" S_new_sound "}", "specialize making a new sound: {" S_new_sound_hook "}", "header type constants: {" S_mus_header_type_name "}", "sample type constants: {" S_mus_sample_type_name "}", NULL}; void new_file_dialog_help(void) { snd_help_with_xrefs("New File", #if HAVE_EXTENSION_LANGUAGE "This dialog sets the new file's output header type, sample type, srate, chans, and comment. \ The 'srate:' and 'channels:' labels are actually drop-down menus providing quick access to common choices. \ The default values for the fields can be set by clicking 'Reset'. These values \ are " S_default_output_chans ", " S_default_output_sample_type ", " S_default_output_srate ", and " S_default_output_header_type ". \ The notation \"(be)\" in the sample type lists stands for big endian; similarly, \"(le)\" is little endian.\ Click 'Ok' to open the new sound. The actual new file representing the new sound is not written \ until you save the new sound.", #else "This dialog sets the new file's output header type, sample type, srate, chans, and comment. \ The 'srate:' and 'channels:' labels are actually drop-down menus providing quick access to common choices. \ The default values for the fields can be set by clicking 'Reset'. Click 'Ok' to open the new sound. \ The actual new file representing the new sound is not written \ until you save the new sound.", #endif WITH_WORD_WRAP, new_file_xrefs, NULL); } /* ---------------- Edit Header ---------------- */ static const char *edit_header_xrefs[11] = { "change srate: {" S_src_channel "}", "convert data to a new sample type: {" S_save_sound_as "}", "interpret current data in new sample type: {" S_sample_type "}", "convert header to a new type: {" S_save_sound_as "}", "interpret current header differently: {" S_header_type "}", "extract or combine chans: {mono->stereo}", "change data location: {" S_data_location "}", "change number of samples: {framples}", "what are these sample types?", "what are these headers?", NULL }; static const char *edit_header_urls[11] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "extsnd.html#sampletype", "extsnd.html#headertype", NULL }; void edit_header_dialog_help(void) { snd_help_with_xrefs("Edit Header", "This dialog edits the header of a sound file; no change is made to the actual sound data. \ The notation \"(be)\" in the sample type lists stands for big endian; similarly, \"(le)\" is little endian.\ If you specify 'raw' as the type, any existing header is removed. This dialog is aimed at adding or removing an entire header, \ or editing the header comments; anything else is obviously dangerous.", WITH_WORD_WRAP, edit_header_xrefs, edit_header_urls); } /* ---------------- Print Dialog ---------------- */ static const char *print_xrefs[4] = { "default eps file name: {" S_eps_file "}", "eps overall size: {" S_eps_size "}", "eps margins: {" S_eps_bottom_margin "}, {" S_eps_left_margin "}", NULL}; void print_dialog_help(void) { snd_help_with_xrefs("File Print", #if HAVE_EXTENSION_LANGUAGE "Print causes the currently active graph(s) to be printed (via the lpr command) or saved as \ a Postscript file. In the latter case, the file name is set either by the dialog, or taken from the \ variable " S_eps_file " (normally \"snd.eps\"). The functions that refer to this dialog are:\n\ \n\ " S_print_dialog " (:optional managed print): start the print dialog\n\ " S_eps_file ": eps file name (\"snd.eps\")\n\ " S_eps_bottom_margin ": bottom margin (0.0)\n\ " S_eps_left_margin ": left margin (0.0)\n\ " S_eps_size ": overall eps size scaler (1.0)\n\ " S_graph_to_ps " (:optional file): write current graph to eps file\n\n\ For openGL graphics, use " S_gl_graph_to_ps ".\n", #else "Print causes the currently active display to be either printed (via the lpr command) or saved as \ an eps file. Currently the openGL graphics can't be printed by Snd, \ but you can use Gimp or some such program to get a screenshot, and print that.", #endif WITH_WORD_WRAP, print_xrefs, NULL); } /* ---------------- View Files ---------------- */ static const char *view_files_xrefs[5] = { "place sound in view files list: {" S_add_file_to_view_files_list "}", "place all sounds from a directory in view files list: {" S_add_directory_to_view_files_list "}", "specialize view files selection: {" S_view_files_select_hook "}", "the sort choice: {" S_view_files_sort "}", NULL}; void view_files_dialog_help(void) { snd_help_with_xrefs("File Browser", #if USE_MOTIF "The View:Files dialog provides a list of sounds and various things to do with them.\ The play button plays the file. \ Double click a file name, and that file is opened in Snd. You can also mix or insert the \ selected file with amplitude envelopes and so on. \ \n\n\ Files can be added to the list via the -p startup switch, and by the functions " S_add_file_to_view_files_list " \ and " S_add_directory_to_view_files_list ". \ \n\n\ The 'sort' label on the right activates a menu of sorting choices; 'name' sorts the \ files list alphabetically, 'date' sorts by date written, and 'size' sorts by the \ number of samples in the sound. The variable " S_view_files_sort " refers to this menu. \ The functions that refer to this dialog are: \n\ \n\ " S_view_files_dialog " (:optional managed): start this dialog\n\ " S_add_directory_to_view_files_list " (dir): add directory's files to list\n\ " S_add_file_to_view_files_list " (file): add file to list\n\ " S_view_files_files ": list of all files in dialog's file list\n\ " S_view_files_selected_files ": list of currently selected files\n\ " S_view_files_sort ": dialog's sort choice\n\ " S_view_files_amp ": dialog's amp slider value\n\ " S_view_files_amp_env ": dialog's amp env\n\ " S_view_files_speed ": dialog's speed value\n\ " S_view_files_speed_style ": dialog's speed style\n", #else "The View:Files dialog provides a list of files preloaded via the -p startup switch.", #endif WITH_WORD_WRAP, view_files_xrefs, NULL); } /* ---------------- help dialog special cases ---------------- */ static void copy_help(void) { snd_help_with_xrefs("Copy", "The copying functions are listed in the 'related topics' section. See also 'Save'", WITH_WORD_WRAP, snd_xrefs("Copy"), snd_xref_urls("Copy")); } static void cursor_help(void) { snd_help_with_xrefs("Cursor", "A big '+' marks the current sample. This is Snd's cursor, and the \ various cursor moving commands apply to it. See also 'Tracking cursor'", WITH_WORD_WRAP, snd_xrefs("Cursor"), snd_xref_urls("Cursor")); } static void tracking_cursor_help(void) { snd_help_with_xrefs("Tracking cursor", "If you want the cursor to follow along more-or-less in time while \ playing a sound, set " S_with_tracking_cursor " to " PROC_TRUE ". See also 'Cursor'", WITH_WORD_WRAP, snd_xrefs("Tracking cursor"), snd_xref_urls("Tracking cursor")); } static void smooth_help(void) { snd_help_with_xrefs("Smoothing", "Smoothing applies a sinusoidal curve to a portion of a sound to smooth \ out any clicks. See also 'Filter'", WITH_WORD_WRAP, snd_xrefs("Smooth"), snd_xref_urls("Smooth")); } static void maxamp_help(void) { snd_help_with_xrefs("Maxamp", "Maxamp refers to the maximum amplitude in a sound", WITH_WORD_WRAP, snd_xrefs("Maxamp"), snd_xref_urls("Maxamp")); } static void reverse_help(void) { snd_help_with_xrefs("Reverse", "There are various things that can be reversed. See the list below.", WITH_WORD_WRAP, snd_xrefs("Reverse"), snd_xref_urls("Reverse")); } static void random_numbers_help(void) { snd_help_with_xrefs("Random Numbers", "", WITH_WORD_WRAP, snd_xrefs("Random Numbers"), snd_xref_urls("Random Numbers")); } static const char *Wavogram_xrefs[] = { "wavogram picture", "{wavo-hop}", "{wavo-trace}", "time-graph-type: {graph-as-wavogram}", NULL}; static const char *Wavogram_urls[] = { "snd.html#wavogram", "extsnd.html#wavohop", "extsnd.html#wavotrace", "extsnd#timegraphtype", NULL}; static void wavogram_help(void) { snd_help_with_xrefs("Wavogram", "The 'wavogram' is a 3-D view of the time-domain data. If you set each trace length correctly, \ you can often get periods to line up vertically, making a pretty picture.", WITH_WORD_WRAP, Wavogram_xrefs, Wavogram_urls); } static void window_size_help(void) { snd_help_with_xrefs("Window Size", "", WITH_WORD_WRAP, snd_xrefs("Window Size"), snd_xref_urls("Window Size")); } #if HAVE_SCHEME #define S_Vct "Float-vector" #else #define S_Vct "Vct" #endif #include "snd-xref.c" #define NUM_TOPICS 37 static const char *topic_names[NUM_TOPICS] = { "Hook", S_Vct, "Sample reader", "Mark", "Mix", "Region", "Edit list", "Transform", "Error", "Color", "Font", "Graphic", "Widget", "Emacs", "CLM", "Instrument", "CM", "CMN", "Sndlib", "Motif", "Gtk", "Script", "Ruby", "s7", "LADSPA", "OpenGL", "Gdb", "Control panel", "X resources", "Invocation flags", "Initialization file", "Customization", "Window Size", "Color", "Random Number", "Wavogram", "Forth" }; static const char *topic_urls[NUM_TOPICS] = { "extsnd.html#sndhooks", "extsnd.html#Vcts", "extsnd.html#samplers", "extsnd.html#sndmarks", "extsnd.html#sndmixes", "extsnd.html#sndregions", "extsnd.html#editlists", "extsnd.html#sndtransforms", "extsnd.html#snderrors", "extsnd.html#colors", "extsnd.html#fonts", "extsnd.html#sndgraphics", "extsnd.html#sndwidgets", "grfsnd.html#emacssnd", "grfsnd.html#sndwithclm", "grfsnd.html#sndinstruments", "grfsnd.html#sndwithcm", "sndscm.html#musglyphs", "sndlib.html#introduction", "grfsnd.html#sndwithmotif", "grfsnd.html#sndwithgtk", "grfsnd.html#sndwithnogui", "grfsnd.html#sndandruby", "grfsnd.html#sndands7", "grfsnd.html#sndandladspa", "grfsnd.html#sndandgl", "grfsnd.html#sndandgdb", "extsnd.html#customcontrols", "grfsnd.html#sndresources", "grfsnd.html#sndswitches", "grfsnd.html#sndinitfile", "extsnd.html#extsndcontents", "extsnd.html#movingwindows", "extsnd.html#colors", "sndscm.html#allrandomnumbers", "snd.html#wavogram", "grfsnd.html#sndandforth" }; static int min_strlen(const char *a, const char *b) { int lena, lenb; lena = strlen(a); lenb = strlen(b); if (lena < lenb) return(lena); return(lenb); } static const char *topic_url(const char *topic) { int i; for (i = 0; i < NUM_TOPICS; i++) if (STRNCMP(topic, topic_names[i], min_strlen(topic, topic_names[i])) == 0) return(topic_urls[i]); return(NULL); } #define NUM_XREFS 33 static const char *xrefs[NUM_XREFS] = { "Mark", "Mix", "Region", "Selection", "Cursor", "Tracking cursor", "Delete", "Envelope", "Filter", "Search", "Insert", "Maxamp", "Play", "Reverse", "Save", "Smooth", "Resample", "FFT", "Reverb", "Src", I_FIND, "Undo", "Redo", "Sync", "Control panel", "Header", "Key", "Copy", "Window Size", "Color", "Control", "Random Numbers", "Wavogram" }; static const char **xref_tables[NUM_XREFS] = { Marking_xrefs, Mixing_xrefs, Regions_xrefs, Selections_xrefs, Cursors_xrefs, Tracking_cursors_xrefs, Deletions_xrefs, Envelopes_xrefs, Filters_xrefs, Searching_xrefs, Insertions_xrefs, Maxamps_xrefs, Playing_xrefs, Reversing_xrefs, Saving_xrefs, Smoothing_xrefs, Resampling_xrefs, FFTs_xrefs, Reverb_xrefs, Resampling_xrefs, Searching_xrefs, Undo_and_Redo_xrefs, Undo_and_Redo_xrefs, sync_xrefs, control_xrefs, header_and_data_xrefs, key_xrefs, Copying_xrefs, Window_size_and_position_xrefs, Colors_xrefs, control_xrefs, Random_Numbers_xrefs, Wavogram_xrefs }; static const char **xref_url_tables[NUM_XREFS] = { Marking_urls, Mixing_urls, Regions_urls, Selections_urls, Cursors_urls, Tracking_cursors_urls, Deletions_urls, Envelopes_urls, Filters_urls, Searching_urls, Insertions_urls, Maxamps_urls, Playing_urls, Reversing_urls, Saving_urls, Smoothing_urls, Resampling_urls, FFTs_urls, Reverb_urls, Resampling_urls, Searching_urls, Undo_and_Redo_urls, Undo_and_Redo_urls, NULL, NULL, NULL, NULL, Copying_urls, Window_size_and_position_urls, Colors_urls, NULL, Random_Numbers_urls, Wavogram_urls }; typedef void (*help_func)(void); /* if an entry is null here, the main help window will display "(no help found)" */ static help_func help_funcs[NUM_XREFS] = { &marks_help, &mix_help, ®ion_help, &selection_help, &cursor_help, &tracking_cursor_help, &delete_help, &env_help, &filter_help, &find_help, &insert_help, &maxamp_help, &play_help, &reverse_help, &save_help, &smooth_help, &resample_help, &fft_help, &reverb_help, &resample_help, &find_help, &undo_help, &undo_help, &sync_help, &controls_help, &sound_files_help, &key_help, ©_help, &window_size_help, &colors_help, &controls_help, &random_numbers_help, &wavogram_help }; static const char **snd_xrefs(const char *topic) { int i; for (i = 0; i < NUM_XREFS; i++) if (STRCMP(topic, xrefs[i]) == 0) return(xref_tables[i]); return(NULL); } static const char **snd_xref_urls(const char *topic) { int i; for (i = 0; i < NUM_XREFS; i++) if (STRCMP(topic, xrefs[i]) == 0) return(xref_url_tables[i]); return(NULL); } static int levenshtein(const char *s1, int l1, const char *s2, int l2) { /* taken with bug fixes from "The Ruby Way" by Hal Fulton, SAMS Pubs */ int i, j, val; int **distance; if (!s1) return(l2); if (!s2) return(l1); distance = (int **)calloc(l2 + 1, sizeof(int *)); for (i = 0; i <= l2; i++) distance[i] = (int *)calloc(l1 + 1, sizeof(int)); for (j = 0; j <= l1; j++) distance[0][j] = j; for (i = 0; i <= l2; i++) distance[i][0] = i; for (i = 1; i <= l2; i++) for (j = 1; j <= l1; j++) { int c1, c2, c3; c1 = distance[i][j - 1] + 1; c2 = distance[i - 1][j] + 1; c3 = distance[i - 1][j - 1] + ((s2[i - 1] == s1[j - 1]) ? 0 : 1); if (c1 > c2) c1 = c2; if (c1 > c3) c1 = c3; distance[i][j] = c1; } val = distance[l2][l1]; for (i = 0; i <= l2; i++) free(distance[i]); free(distance); return(val); } static int help_name_to_url(const char *name) { /* trying to be fancy here just causes trouble -- this is not a function that needs to be fast! */ int i; for (i = 0; i < HELP_NAMES_SIZE; i++) { int comp; #if HAVE_RUBY if (name[0] == '$') comp = STRCMP(help_names[i], (const char *)(name + 1)); else comp = STRCMP(help_names[i], name); #else comp = STRCMP(help_names[i], name); #endif if (comp == 0) return(i); } return(-1); } const char *snd_url(const char *name) { #if HAVE_EXTENSION_LANGUAGE /* (snd-url "save-sound-as") -> "extsnd.html#savesoundas" */ int i; i = help_name_to_url(name); if (i >= 0) return(help_urls[i]); #endif return(NULL); } static char *call_grep(const char *defstr, const char *name, const char *endstr, const char *path, char *tempfile) { int err; char *command; #ifndef __sun /* Gnu fgrep: -s switch to fgrep = "silent", I guess (--no-messages) [OSX uses Gnu fgrep] */ command = mus_format("grep -F -s \"%s%s%s\" %s/*." Xen_file_extension " --line-number > %s", defstr, name, endstr, path, tempfile); #else /* Sun fgrep: here -s means -q and --line-number prints an error message */ command = mus_format("grep -F \"%s%s%s\" %s/*." Xen_file_extension " > %s", defstr, name, endstr, path, tempfile); #endif err = system(command); free(command); if (err != -1) /* no error, so I guess tempfile exists, but might be empty */ return(file_to_string(tempfile)); /* NULL if nothing found */ return(NULL); } static char *snd_finder(const char *name, bool got_help) { /* desperation -- search *.scm/rb/fs then even *.html? for 'name' */ const char *url = NULL; char *fgrep = NULL, *tempfile = NULL, *command = NULL; bool is_defined; int a_def = 0, dir_len = 0, i; Xen dirs = Xen_empty_list; #if HAVE_SCHEME || (!HAVE_EXTENSION_LANGUAGE) #define NUM_DEFINES 7 #define TRAILER " " const char *defines[NUM_DEFINES] = {"(define (", "(define* (", "(define ", "(define+ (", "(defmacro ", "(defmacro* ", "(definstrument ("}; #endif #if HAVE_RUBY #define NUM_DEFINES 2 #define TRAILER "" const char *defines[NUM_DEFINES] = {"def ", "class "}; #endif #if HAVE_FORTH #define NUM_DEFINES 3 #define TRAILER "" const char *defines[NUM_DEFINES] = {": ", "instrument: ", "event: "}; #endif is_defined = Xen_is_defined(name); #if HAVE_SCHEME { s7_pointer help; fgrep = mus_format("(*autoload* '%s)", name); help = s7_eval_c_string(s7, fgrep); free(fgrep); fgrep = NULL; if (help != Xen_false) { command = mus_format("%s is defined in %s", name, s7_object_to_c_string(s7, help)); return(command); } } #endif url = snd_url(name); tempfile = snd_tempnam(); /* this will have a .snd extension */ dirs = Xen_load_path; dir_len = Xen_list_length(dirs); for (i = 0; (!fgrep) && (i < dir_len); i++) { if (Xen_is_string(Xen_list_ref(dirs, i))) /* *load-path* might have garbage */ { const char *path; path = Xen_string_to_C_string(Xen_list_ref(dirs, i)); if (!path) continue; for (a_def = 0; (!fgrep) && (a_def < NUM_DEFINES); a_def++) fgrep = call_grep(defines[a_def], name, TRAILER, path, tempfile); #if HAVE_SCHEME if (!fgrep) fgrep = call_grep("(define (", name, ")", path, tempfile); if (!fgrep) fgrep = call_grep("(define ", name, "\n", path, tempfile); #endif } } snd_remove(tempfile, IGNORE_CACHE); free(tempfile); if (url) { if (fgrep) command = mus_format("%s is %sdefined%s; it appears to be defined in:\n%sand documented at %s", name, (is_defined) ? "" : "not ", (is_defined && (!got_help)) ? ", but has no help string" : "", fgrep, url); else command = mus_format("%s is %sdefined%s; it is documented at %s", name, (is_defined) ? "" : "not ", (is_defined && (!got_help)) ? ", but has no help string" : "", url); } else { if (fgrep) command = mus_format("%s is %sdefined%s; it appears to be defined in:\n%s", name, (is_defined) ? "" : "not ", (is_defined && (!got_help)) ? ", but has no help string" : "", fgrep); else command = NULL; } if (fgrep) free(fgrep); /* don't free url! */ return(command); } bool snd_topic_help(const char *topic) { /* called only in snd-x|ghelp.c */ int i, topic_len; for (i = 0; i < NUM_XREFS; i++) if (STRCMP(topic, xrefs[i]) == 0) { if (help_funcs[i]) { (*help_funcs[i])(); return(true); } } topic_len = mus_strlen(topic); for (i = 0; i < NUM_XREFS; i++) { int xref_len, j, diff, min_len; const char *a, *b; xref_len = strlen(xrefs[i]); if (xref_len < topic_len) { diff = topic_len - xref_len; min_len = xref_len; a = topic; b = xrefs[i]; } else { diff = xref_len - topic_len; min_len = topic_len; a = xrefs[i]; b = topic; } for (j = 0; j < diff; j++) if (STRNCMP((char *)(a + j), b, min_len) == 0) { if (help_funcs[i]) { (*help_funcs[i])(); return(true); } } } /* try respelling topic */ { int min_diff = 1000, min_loc = 0, this_diff, topic_len; topic_len = mus_strlen(topic); for (i = 0; i < NUM_XREFS; i++) if (help_funcs[i]) { this_diff = levenshtein(topic, topic_len, xrefs[i], mus_strlen(xrefs[i])); if (this_diff < min_diff) { min_diff = this_diff; min_loc = i; } } if (min_diff < snd_int_log2(topic_len)) /* was topic_len / 2, but this gives too much leeway for substitutions */ { (*help_funcs[min_loc])(); return(true); } } /* go searching for it */ { char *str; str = snd_finder(topic, false); if (str) { snd_help(topic, str, WITH_WORD_WRAP); free(str); return(true); } } return(false); } static bool strings_might_match(const char *a, const char *b, int len) { int i; for (i = 0; i < len; i++) { if (a[i] != b[i]) return(false); #if HAVE_RUBY if (a[i] == '_') return(true); #endif #if HAVE_SCHEME || HAVE_FORTH if (a[i] == '-') return(true); #endif } return(true); } const char **help_name_to_xrefs(const char *name) { const char **xrefs = NULL; int i, xref_ctr = 0, xrefs_size = 0, name_len; #if (!HAVE_EXTENSION_LANGUAGE) return(NULL); #endif name_len = strlen(name); for (i = 0; i < HELP_NAMES_SIZE; i++) if (name[0] == help_names[i][0]) { int cur_len; cur_len = strlen(help_names[i]); if (strings_might_match(name, help_names[i], (name_len < cur_len) ? name_len : cur_len)) { if (xref_ctr >= (xrefs_size - 1)) /* need trailing NULL to mark end of table */ { xrefs_size += 8; if (xref_ctr == 0) xrefs = (const char **)calloc(xrefs_size, sizeof(char *)); else { int k; xrefs = (const char **)realloc(xrefs, xrefs_size * sizeof(char *)); for (k = xref_ctr; k < xrefs_size; k++) xrefs[k] = NULL; } } xrefs[xref_ctr++] = help_names[i]; } } return(xrefs); } char *word_wrap(const char *text, int widget_len) { char *new_text; int new_len, old_len, i, j, desired_len, line_start = 0; #if HAVE_RUBY bool move_paren = false; int in_paren = 0; #endif old_len = mus_strlen(text); new_len = old_len + 64; desired_len = (int)(widget_len * .8); new_text = (char *)calloc(new_len, sizeof(char)); for (i = 0, j = 0; i < old_len; i++) if (text[i] == '\n') { new_text[j++] = '\n'; line_start = j; } else { if ((text[i] == ' ') && (help_text_width(new_text, line_start, j) >= desired_len)) { new_text[j++] = '\n'; line_start = j; } else { #if (!HAVE_RUBY) new_text[j++] = text[i]; #else /* try to change the reported names to Ruby names */ if (text[i] == '-') { if ((i > 0) && (isalnum((int)(text[i - 1]))) && (i < old_len)) { if (isalnum((int)(text[i + 1]))) new_text[j++] = '_'; else { if (text[i + 1] == '>') { new_text[j++] = '2'; i++; } else new_text[j++] = text[i]; } } else new_text[j++] = text[i]; } else { if ((i < old_len) && (text[i] == '#')) { if (text[i + 1] == 'f') { new_text[j++] = 'f'; new_text[j++] = 'a'; new_text[j++] = 'l'; new_text[j++] = 's'; new_text[j++] = 'e'; i++; } else { if (text[i + 1] == 't') { new_text[j++] = 't'; new_text[j++] = 'r'; new_text[j++] = 'u'; new_text[j++] = 'e'; i++; } else new_text[j++] = text[i]; } } else { if ((i == 0) && (text[i] == '(')) { move_paren = true; } else { if ((move_paren) && (text[i] == ')')) { /* no args: use () */ new_text[j++] = '('; new_text[j++] = ')'; move_paren = false; in_paren = 0; } else { if ((move_paren) && (text[i] == ' ')) { new_text[j++] = '('; move_paren = false; in_paren = 1; } else { if (in_paren > 0) { if ((in_paren == 1) && (text[i] == ' ')) { new_text[j++] = ','; new_text[j++] = ' '; } else { if (text[i] == ')') in_paren--; else if (text[i] == '(') in_paren++; new_text[j++] = text[i]; } } else new_text[j++] = text[i]; }}}}} #endif } } return(new_text); } #define DOC_DIRECTORIES 6 static const char *doc_directories[DOC_DIRECTORIES] = { "/usr/share/doc/snd-" SND_VERSION, "/usr/share/doc/snd-" SND_MAJOR_VERSION, "/usr/local/share/doc/snd-" SND_VERSION, "/usr/local/share/doc/snd-" SND_MAJOR_VERSION, "/usr/doc/snd-" SND_MAJOR_VERSION, "/usr/share/docs/snd-" SND_VERSION }; static const char *doc_files[DOC_DIRECTORIES] = { "/usr/share/doc/snd-" SND_VERSION "/snd.html", "/usr/share/doc/snd-" SND_MAJOR_VERSION "/snd.html", "/usr/local/share/doc/snd-" SND_VERSION "/snd.html", "/usr/local/share/doc/snd-" SND_MAJOR_VERSION "/snd.html", "/usr/doc/snd-" SND_MAJOR_VERSION "/snd.html", "/usr/share/docs/snd-" SND_VERSION "/snd.html" }; static const char *html_directory(void) { int i; if (mus_file_probe("snd.html")) return(mus_getcwd()); if (html_dir(ss)) { bool happy; int len; char *hd = NULL; len = mus_strlen(html_dir(ss)) + 16; hd = (char *)calloc(len, sizeof(char)); snprintf(hd, len, "%s/snd.html", html_dir(ss)); happy = mus_file_probe(hd); free(hd); if (happy) return(html_dir(ss)); } #ifdef MUS_DEFAULT_DOC_DIR if (mus_file_probe(MUS_DEFAULT_DOC_DIR "/snd.html")) return(MUS_DEFAULT_DOC_DIR); #endif for (i = 0; i < DOC_DIRECTORIES; i++) if (mus_file_probe(doc_files[i])) return(doc_directories[i]); return(NULL); } void url_to_html_viewer(const char *url) { const char *dir_path; dir_path = html_directory(); if (dir_path) { char *program; program = html_program(ss); if (program) { char *path; int len, err; len = strlen(dir_path) + strlen(url) + 256; path = (char *)calloc(len, sizeof(char)); snprintf(path, len, "%s file:%s/%s &", program, dir_path, url); err = system(path); if (err == -1) fprintf(stderr, "can't start %s?", program); free(path); } } } void name_to_html_viewer(const char *red_text) { const char *url; url = snd_url(red_text); if (url == NULL) url = topic_url(red_text); if (url) url_to_html_viewer(url); } static Xen output_comment_hook; char *output_comment(file_info *hdr) { Xen hook; hook = output_comment_hook; if (Xen_hook_has_list(hook)) { Xen result; result = C_string_to_Xen_string((hdr) ? hdr->comment : NULL); #if HAVE_SCHEME result = s7_call(s7, hook, s7_cons(s7, result, s7_nil(s7))); #else { Xen procs; procs = Xen_hook_list(hook); while (!Xen_is_null(procs)) { result = Xen_call_with_1_arg(Xen_car(procs), result, S_output_comment_hook); procs = Xen_cdr(procs); } } #endif if (Xen_is_string(result)) return(mus_strdup(Xen_string_to_C_string(result))); } return(mus_strdup((hdr) ? hdr->comment : NULL)); } static Xen help_hook; Xen g_snd_help_with_search(Xen text, int widget_wid, bool search) { /* snd-help but no search for misspelled name if search=false */ #if HAVE_SCHEME #define snd_help_example "(snd-help 'make-float-vector)" #define snd_help_arg_type "can be a string, symbol, or in some cases, the object itself" #endif #if HAVE_RUBY #define snd_help_example "snd_help(\"make_vct\")" #define snd_help_arg_type "can be a string or a symbol" #endif #if HAVE_FORTH #define snd_help_example "\"make-vct\" snd-help" #define snd_help_arg_type "is a string" #endif #define H_snd_help "(" S_snd_help " :optional (arg 'snd-help) (formatted " PROC_TRUE ")): return the documentation \ associated with its argument. " snd_help_example " for example, prints out a brief description of make-" S_vct ". \ The argument " snd_help_arg_type ". \ In the help descriptions, optional arguments are in parens with the default value (if any) as the second entry. \ A ':' as the start of the argument name marks a CLM-style optional keyword argument. If you load index." Xen_file_extension " \ the functions html and ? can be used in place of help to go to the HTML description, \ and the location of the associated C code will be displayed, if it can be found. \ If " S_help_hook " is not empty, it is invoked with the subject and the snd-help result \ and its value is returned." char *str = NULL, *subject = NULL; if (Xen_is_keyword(text)) return(C_string_to_Xen_string("keyword")); #if HAVE_RUBY if (Xen_is_string(text)) subject = Xen_string_to_C_string(text); else if ((Xen_is_symbol(text)) && (Xen_is_bound(text))) { text = XEN_SYMBOL_TO_STRING(text); subject = Xen_string_to_C_string(text); } else { char *temp; temp = xen_scheme_procedure_to_ruby(S_snd_help); text = C_string_to_Xen_string(temp); if (temp) free(temp); } str = Xen_object_to_C_string(Xen_documentation(text)); #endif #if HAVE_FORTH if (Xen_is_string(text)) /* "play" snd-help */ subject = Xen_string_to_C_string(text); else if (!Xen_is_bound(text)) /* snd-help play */ { subject = fth_parse_word(); text = C_string_to_Xen_string(subject); } if (!subject) { subject = S_snd_help; text = C_string_to_Xen_string(S_snd_help); } str = Xen_object_to_C_string(Xen_documentation(text)); #endif #if HAVE_SCHEME { Xen sym = Xen_false; if (Xen_is_string(text)) { subject = (char *)Xen_string_to_C_string(text); sym = s7_name_to_value(s7, subject); } else { if (Xen_is_symbol(text)) { subject = (char *)Xen_symbol_to_C_string(text); str = (char *)s7_help(s7, text); sym = s7_symbol_value(s7, text); } else { sym = text; } } if (!str) str = (char *)s7_help(s7, sym); if ((str == NULL) || (mus_strlen(str) == 0)) { if (Xen_is_procedure(sym)) { str = (char *)s7_procedure_documentation(s7, sym); if (((str == NULL) || (mus_strlen(str) == 0)) && (s7_funclet(s7, sym) != sym)) { s7_pointer e; e = s7_funclet(s7, sym); str = (char *)calloc(256, sizeof(char)); /* unavoidable memleak I guess -- we could use a backup statically allocated buffer here */ if (s7_is_null(s7, e)) snprintf(str, 256, "this function appears to come from eval or eval-string?"); else { s7_pointer x; /* (cdr (assoc '__func__ (let->list (funclet func)))) => (name file line) or name */ x = s7_assoc(s7, s7_make_symbol(s7, "__func__"), s7_let_to_list(s7, e)); if (s7_is_pair(x)) { x = s7_cdr(x); if (s7_is_pair(x)) { const char *url; subject = (char *)s7_symbol_name(s7_car(x)); url = snd_url(subject); if (url) snprintf(str, 256, "%s is defined at line %lld of %s, and documented at %s", subject, (long long int)s7_integer(s7_car(s7_cdr(s7_cdr(x)))), s7_string(s7_car(s7_cdr(x))), url); else snprintf(str, 256, "%s is defined at line %lld of %s", subject, (long long int)s7_integer(s7_car(s7_cdr(s7_cdr(x)))), s7_string(s7_car(s7_cdr(x)))); } } } } } else { str = s7_symbol_documentation(s7, s7_make_symbol(s7, subject)); } } } #endif if (search) { bool need_free = false; if ((str == NULL) || (mus_strlen(str) == 0) || (strcmp(str, PROC_FALSE) == 0)) /* Ruby returns "false" here */ { if (!subject) return(Xen_false); str = snd_finder(subject, false); need_free = true; } if (str) { Xen help_text = Xen_false; /* so that we can free "str" */ char *new_str = NULL; if (subject) { Xen hook; hook = help_hook; if (Xen_hook_has_list(hook)) { Xen result, subj; result = C_string_to_Xen_string(str); subj = C_string_to_Xen_string(subject); #if HAVE_SCHEME result = s7_call(s7, hook, s7_cons(s7, subj, s7_cons(s7, result, s7_nil(s7)))); #else { Xen procs; procs = Xen_hook_list(hook); while (!Xen_is_null(procs)) { result = Xen_call_with_2_args(Xen_car(procs), subj, result, S_help_hook); procs = Xen_cdr(procs); } } #endif if (Xen_is_string(result)) new_str = mus_strdup(Xen_string_to_C_string(result)); else new_str = mus_strdup(str); } else new_str = mus_strdup(str); } else new_str = mus_strdup(str); if (need_free) { free(str); str = NULL; } #if (!USE_GTK) if (widget_wid > 0) { str = word_wrap(new_str, widget_wid); if (new_str) free(new_str); } else #endif str = new_str; help_text = C_string_to_Xen_string(str); if (str) free(str); return(help_text); } } if (str) return(C_string_to_Xen_string(str)); return(Xen_false); } Xen g_snd_help(Xen text, int widget_wid) { return(g_snd_help_with_search(text, widget_wid, true)); } static Xen g_listener_help(Xen arg, Xen formatted) { Xen_check_type(Xen_is_boolean_or_unbound(formatted), formatted, 2, S_snd_help, "a boolean"); if (Xen_is_false(formatted)) return(g_snd_help(arg, 0)); return(g_snd_help(arg, listener_width())); } void set_html_dir(char *new_dir) { if (html_dir(ss)) free(html_dir(ss)); set_html_dir_1(new_dir); } static Xen g_html_dir(void) { #define H_html_dir "(" S_html_dir "): location of Snd documentation" return(C_string_to_Xen_string(html_dir(ss))); } static Xen g_set_html_dir(Xen val) { Xen_check_type(Xen_is_string(val), val, 1, S_set S_html_dir, "a string"); set_html_dir(mus_strdup(Xen_string_to_C_string(val))); return(val); } static Xen g_html_program(void) { #define H_html_program "(" S_html_program "): name of documentation reader (mozilla, by default)" return(C_string_to_Xen_string(html_program(ss))); } static Xen g_set_html_program(Xen val) { Xen_check_type(Xen_is_string(val), val, 1, S_set S_html_program, "a string"); if (html_program(ss)) free(html_program(ss)); set_html_program(mus_strdup(Xen_string_to_C_string(val))); return(val); } static Xen g_snd_url(Xen name) { #define H_snd_url "(" S_snd_url " name): url corresponding to 'name'" /* given Snd entity ('open-sound) as symbol or string return associated url */ Xen_check_type(Xen_is_string(name) || Xen_is_symbol(name), name, 1, S_snd_url, "a string or symbol"); if (Xen_is_string(name)) return(C_string_to_Xen_string(snd_url(Xen_string_to_C_string(name)))); return(C_string_to_Xen_string(snd_url(Xen_symbol_to_C_string(name)))); } static Xen g_snd_urls(void) { #define H_snd_urls "(" S_snd_urls "): list of all snd names with the associated url (a list of lists)" Xen lst = Xen_empty_list; #if HAVE_EXTENSION_LANGUAGE int i; for (i = 0; i < HELP_NAMES_SIZE; i++) lst = Xen_cons(Xen_cons(C_string_to_Xen_string(help_names[i]), C_string_to_Xen_string(help_urls[i])), lst); #endif return(lst); } static const char **refs = NULL, **urls = NULL; static Xen g_help_dialog(Xen subject, Xen msg, Xen xrefs, Xen xurls) { #define H_help_dialog "(" S_help_dialog " subject message xrefs urls): start the Help window with subject and message" Xen_check_type(Xen_is_string(subject), subject, 1, S_help_dialog, "a string"); Xen_check_type(Xen_is_string(msg), msg, 2, S_help_dialog, "a string"); Xen_check_type(Xen_is_list(xrefs) || !Xen_is_bound(xrefs), xrefs, 3, S_help_dialog, "a list of related references"); Xen_check_type(Xen_is_list(xurls) || !Xen_is_bound(xurls), xurls, 4, S_help_dialog, "a list of urls"); if (refs) {free(refs); refs = NULL;} if (urls) {free(urls); urls = NULL;} if (Xen_is_list(xrefs)) { int i, len; len = Xen_list_length(xrefs); refs = (const char **)calloc(len + 1, sizeof(char *)); for (i = 0; i < len; i++) if (Xen_is_string(Xen_list_ref(xrefs, i))) refs[i] = Xen_string_to_C_string(Xen_list_ref(xrefs, i)); if (Xen_is_list(xurls)) { int ulen; ulen = Xen_list_length(xurls); if (ulen > len) ulen = len; urls = (const char **)calloc(ulen + 1, sizeof(char *)); for (i = 0; i < ulen; i++) if (Xen_is_string(Xen_list_ref(xurls, i))) urls[i] = Xen_string_to_C_string(Xen_list_ref(xurls, i)); } return(Xen_wrap_widget(snd_help_with_xrefs(Xen_string_to_C_string(subject), Xen_string_to_C_string(msg), WITH_WORD_WRAP, refs, urls))); } return(Xen_wrap_widget(snd_help(Xen_string_to_C_string(subject), Xen_string_to_C_string(msg), WITH_WORD_WRAP))); } Xen_wrap_2_optional_args(g_listener_help_w, g_listener_help) Xen_wrap_no_args(g_html_dir_w, g_html_dir) Xen_wrap_1_arg(g_set_html_dir_w, g_set_html_dir) Xen_wrap_no_args(g_html_program_w, g_html_program) Xen_wrap_1_arg(g_set_html_program_w, g_set_html_program) Xen_wrap_1_arg(g_snd_url_w, g_snd_url) Xen_wrap_no_args(g_snd_urls_w, g_snd_urls) Xen_wrap_4_optional_args(g_help_dialog_w, g_help_dialog) #if HAVE_SCHEME static s7_pointer acc_html_dir(s7_scheme *sc, s7_pointer args) {return(g_set_html_dir(s7_cadr(args)));} static s7_pointer acc_html_program(s7_scheme *sc, s7_pointer args) {return(g_set_html_program(s7_cadr(args)));} #endif void g_init_help(void) { Xen_define_procedure(S_snd_help, g_listener_help_w, 0, 2, 0, H_snd_help); #if HAVE_SCHEME Xen_eval_C_string("(define s7-help help)"); Xen_define_procedure("help", g_listener_help_w, 0, 2, 0, H_snd_help); /* override s7's help */ #endif Xen_define_safe_procedure(S_snd_url, g_snd_url_w, 1, 0, 0, H_snd_url); Xen_define_safe_procedure(S_snd_urls, g_snd_urls_w, 0, 0, 0, H_snd_urls); Xen_define_safe_procedure(S_help_dialog, g_help_dialog_w, 2, 2, 0, H_help_dialog); #define H_help_hook S_help_hook "(subject message): called from " S_snd_help ". If \ it returns a string, it replaces 'message' (the default help)" help_hook = Xen_define_hook(S_help_hook, "(make-hook 'subject 'message)", 2, H_help_hook); #if HAVE_SCHEME #define H_output_comment_hook S_output_comment_hook " (comment): called in Save-As dialog, passed current sound's comment, if any. \ If more than one hook function, each function gets the previous function's output as its input.\n\ (hook-push " S_output_comment_hook "\n\ (lambda (hook)\n\ (set! (hook 'result) (string-append (hook 'comment) \n\ \": written \"\n\ (strftime \"%a %d-%b-%Y %H:%M %Z\"\n\ (localtime (current-time)))))))" #endif #if HAVE_RUBY #define H_output_comment_hook S_output_comment_hook " (str): called in Save-As dialog, passed current sound's comment, if any. \ If more than one hook function, each function gets the previous function's output as its input.\n\ $output_comment_hook.add_hook!(\"comment\") do |str|\n\ str + \": written \" + Time.new.localtime.strftime(\"%a %d-%b-%y %H:%M %Z\")\n\ end" #endif #if HAVE_FORTH #define H_output_comment_hook S_output_comment_hook " (str): called in Save-As dialog, passed current sound's comment, if any. \ If more than one hook function, each function gets the previous function's output as its input.\n\ " S_output_comment_hook " lambda: <{ str }>\n\ \"%s: written %s\" '( str date ) format\n\ ; add-hook!" #endif output_comment_hook = Xen_define_hook(S_output_comment_hook, "(make-hook 'comment)", 1, H_output_comment_hook); Xen_define_dilambda(S_html_dir, g_html_dir_w, H_html_dir, S_set S_html_dir, g_set_html_dir_w, 0, 0, 1, 0); Xen_define_dilambda(S_html_program, g_html_program_w, H_html_program, S_set S_html_program, g_set_html_program_w, 0, 0, 1, 0); #if HAVE_SCHEME autoload_info(s7); /* snd-xref.c included above */ s7_symbol_set_access(s7, ss->html_dir_symbol, s7_make_function(s7, "[acc-" S_html_dir "]", acc_html_dir, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->html_program_symbol, s7_make_function(s7, "[acc-" S_html_program "]", acc_html_program, 2, 0, false, "accessor")); s7_symbol_set_documentation(s7, ss->html_dir_symbol, "*html-dir*: location of Snd documentation"); s7_symbol_set_documentation(s7, ss->html_program_symbol, "*html-program*: name of documentation reader (firefox)"); #endif } snd-16.1/cmn-glyphs.lisp0000644000076400007640000022007512306421671013315 0ustar bilbil;;; music symbols ;;; ;;; created from MusicTex font starting point as translated to PostScript by Matti Koskinen ;;; then edited extensively to try to approach the Sonata font using glfed.c. All symbols ;;; are expressed here nominally as 0..1.0 with scaling by font-size handled elsewhere. ;;; (that is, from cmn's point of view, a staff is 1.0 high and these glyphs fit that). ;;; ;;; Multi-glyph symbols are mostly drawn as needed from scratch, not saved as separate functions. ;;; Order of curves matters in several cases -- we want these to draw as filled polygons in X ;;; as well as PostScript, but X's filling algorithm is dumb. ;;; ;;; this set of glyphs could be turned back into the MusicTex style of font -- the overall ;;; scaler (going back) is 15.873. See also make-font.cl. ;;; The Sonata font needs work -- placements are mostly wrong (in-package :cmn) ;;; -------------------------------- CLEFS -------------------------------- (defun draw-treble-clef (score &optional style) (if (music-font score) (g-mustext score #o46 0 -.25) (progn ;(comment score "treble clef") (moveto score 0.490 -0.258) (curveto score 0.516 -0.430 0.546 -0.672 0.298 -0.590) (curveto score 0.404 -0.580 0.432 -0.436 0.320 -0.398) (curveto score 0.210 -0.398 0.180 -0.518 0.256 -0.600) (curveto score 0.290 -0.622 0.310 -0.630 0.338 -0.638) (curveto score 0.576 -0.668 0.554 -0.402 0.522 -0.252) (curveto score 0.892 -0.126 0.746 0.314 0.442 0.236) (curveto score 0.436 0.286 0.410 0.388 0.420 0.440) (curveto score 0.430 0.490 0.484 0.558 0.510 0.606) (curveto score 0.624 0.814 0.616 1.000 0.496 1.108) (curveto score 0.410 1.118 0.348 0.888 0.348 0.744) (curveto score 0.348 0.696 0.364 0.618 0.348 0.576) (curveto score 0.332 0.530 0.290 0.482 0.264 0.440) (curveto score 0.152 0.260 0.054 0.082 0.182 -0.120) (curveto score 0.256 -0.238 0.358 -0.258 0.490 -0.258) (moveto score 0.394 0.622) (curveto score 0.374 0.696 0.370 0.978 0.512 0.996) (curveto score 0.666 0.948 0.454 0.668 0.394 0.622) (moveto score 0.382 0.398) (lineto score 0.410 0.224) (curveto score 0.252 0.126 0.252 -0.062 0.358 -0.106) (lineto score 0.372 -0.088) (curveto score 0.284 0.004 0.346 0.132 0.424 0.136) (lineto score 0.482 -0.222) (curveto score 0.382 -0.220 0.306 -0.222 0.236 -0.134) (curveto score 0.096 0.038 0.278 0.242 0.384 0.406) (moveto score 0.516 -0.220) (lineto score 0.458 0.146) (curveto score 0.678 0.176 0.744 -0.146 0.516 -0.220) (if (not style) (fill-in score) (draw score style))))) (defvar treble-clef-bounds '(0.000 -0.650 0.740 1.108)) (defun draw-percussion-clef (score &optional style) ;(comment score "percussion clef") (moveto score 0 0) (lineto score 0 .5) (rlineto score .045 0) (rlineto score 0 -.5) (rlineto score -.045 0) (if (not style) (fill-in score) (draw score style)) (moveto score .085 0) (rlineto score 0 .5) (rlineto score .045 0) (rlineto score 0 -.5) (if (not style) (fill-in score) (draw score style))) ;closepath? (defvar percussion-clef-bounds '(0.000 0.000 .13 .5)) (defun draw-c-clef (score &optional style) (if (music-font score) (g-mustext score #o102 0 -0.5) (progn ;(comment score "c clef") (moveto score 0.465 0.442) (lineto score 0.465 0.475) (curveto score 0.765 0.503 0.643 0.012 0.515 0.080) (curveto score 0.453 0.132 0.450 0.197 0.423 0.257) (curveto score 0.382 0.115 0.352 0.042 0.305 0.005) (lineto score 0.305 0.500) (lineto score 0.282 0.500) (lineto score 0.282 -0.500) (lineto score 0.305 -0.500) (lineto score 0.305 -0.005) (curveto score 0.353 -0.043 0.380 -0.112 0.423 -0.257) (curveto score 0.452 -0.192 0.455 -0.132 0.517 -0.080) (curveto score 0.643 -0.012 0.765 -0.503 0.467 -0.475) (lineto score 0.467 -0.438) (curveto score 0.533 -0.385 0.503 -0.293 0.417 -0.305) (curveto score 0.263 -0.383 0.483 -0.645 0.692 -0.437) (curveto score 0.825 -0.283 0.693 0.032 0.440 -0.075) (lineto score 0.410 0.000) (lineto score 0.440 0.075) (curveto score 0.693 -0.032 0.825 0.283 0.692 0.437) (curveto score 0.493 0.647 0.263 0.377 0.430 0.303) (curveto score 0.502 0.297 0.547 0.383 0.468 0.442) (if (not style) (fill-in score) (draw score style)) (moveto score 0.120 0.500) (lineto score 0.120 -0.500) (lineto score 0.227 -0.500) (lineto score 0.227 0.500) (lineto score 0.120 0.500) (if (not style) (fill-in score) (draw score style))))) (defvar c-clef-bounds '(0.000 -0.512 0.744 0.514)) (defun draw-bass-clef (score &optional style) (if (music-font score) (g-mustext score #o77 0 -0.75) (progn ;(comment score "bass clef") (moveto score 0.058 0.075) (curveto score 0.115 0.053 0.108 0.145 0.223 0.098) (curveto score 0.292 0.052 0.278 -0.057 0.173 -0.072) (curveto score 0.085 -0.080 0.003 -0.018 0.007 0.098) (curveto score 0.045 0.262 0.238 0.288 0.343 0.250) (curveto score 0.492 0.192 0.532 0.067 0.517 -0.047) (curveto score 0.497 -0.292 0.072 -0.522 0.017 -0.535) (lineto score 0.007 -0.512) (curveto score 0.127 -0.452 0.302 -0.342 0.367 -0.152) (curveto score 0.437 0.045 0.377 0.187 0.275 0.227) (curveto score 0.128 0.267 0.012 0.165 0.062 0.075) (if (not style) (fill-in score) (draw score style)) (circle score .6 .1 .0525 0 360 (not style)) (circle score .6 -.1 .0525 0 360 (not style))))) (defvar bass-clef-bounds '(0.000 -0.525 0.715 0.252)) ;;; -------------------------------- ORNAMENTS and ACCENTS -------------------------------- (defun draw-turn (score &optional style) (if (music-font score) (g-mustext score #o124 0 0.0) (progn ;(comment score "turn") (moveto score -0.096 0.062) (curveto score -0.130 0.104 -0.124 0.208 -0.048 0.214) (curveto score 0.060 0.204 0.154 0.040 0.258 0.010) (curveto score 0.384 -0.028 0.524 0.116 0.418 0.220) (curveto score 0.372 0.266 0.264 0.262 0.278 0.180) (curveto score 0.310 0.122 0.370 0.154 0.394 0.196) (curveto score 0.432 0.144 0.428 0.054 0.342 0.044) (curveto score 0.242 0.054 0.148 0.216 0.046 0.248) (curveto score -0.080 0.296 -0.220 0.142 -0.114 0.036) (curveto score -0.070 -0.008 0.040 -0.004 0.028 0.080) (curveto score -0.002 0.142 -0.066 0.102 -0.096 0.062) (if (not style) (fill-in score) (draw score style))))) (defvar turn-bounds '(-0.150 0.000 0.454 0.256)) (defun draw-mordent (score &optional style) (if (music-font score) (g-mustext score #o155 0 0.0) (progn ;(comment score "mordent") (moveto score 0.310 0.103) (curveto score 0.335 0.129 0.334 0.129 0.359 0.104) (lineto score 0.425 0.031) (curveto score 0.459 -0.001 0.444 -0.002 0.478 0.028) (lineto score 0.606 0.156) (lineto score 0.606 0.193) (lineto score 0.563 0.146) (curveto score 0.536 0.121 0.535 0.121 0.505 0.151) (lineto score 0.436 0.231) (curveto score 0.407 0.262 0.416 0.258 0.388 0.232) (lineto score 0.307 0.156) (curveto score 0.282 0.132 0.283 0.130 0.262 0.153) (lineto score 0.190 0.232) (curveto score 0.161 0.265 0.167 0.265 0.136 0.237) (lineto score 0.000 0.111) (lineto score 0.000 0.075) (lineto score 0.051 0.122) (curveto score 0.083 0.153 0.086 0.152 0.109 0.120) (lineto score 0.189 0.030) (curveto score 0.214 0.003 0.206 0.003 0.236 0.031) (lineto score 0.310 0.103) (if (not style) (fill-in score) (draw score style))))) (defvar mordent-bounds '(0.000 0.000 0.606 0.257)) (defun draw-double-mordent (score &optional style) (if (music-font score) (g-mustext score #o265 0 0.0) (progn ;(comment score "double mordent") (moveto score 0.560 0.106) (curveto score 0.586 0.132 0.583 0.132 0.620 0.092) (lineto score 0.681 0.031) (curveto score 0.708 0.000 0.707 0.004 0.736 0.027) (lineto score 0.870 0.146) (lineto score 0.870 0.187) (lineto score 0.821 0.138) (curveto score 0.793 0.115 0.796 0.111 0.761 0.145) (lineto score 0.691 0.220) (curveto score 0.662 0.257 0.655 0.257 0.629 0.224) (lineto score 0.558 0.145) (curveto score 0.533 0.121 0.537 0.118 0.505 0.151) (lineto score 0.439 0.224) (curveto score 0.416 0.251 0.418 0.252 0.393 0.227) (lineto score 0.320 0.159) (curveto score 0.286 0.121 0.286 0.125 0.256 0.156) (lineto score 0.189 0.226) (curveto score 0.154 0.266 0.160 0.266 0.131 0.238) (lineto score 0.000 0.115) (lineto score 0.000 0.075) (lineto score 0.050 0.121) (curveto score 0.081 0.151 0.077 0.146 0.108 0.117) (lineto score 0.188 0.029) (curveto score 0.210 0.000 0.210 0.006 0.236 0.030) (lineto score 0.310 0.104) (curveto score 0.333 0.130 0.331 0.128 0.358 0.100) (lineto score 0.425 0.027) (curveto score 0.448 0.004 0.444 0.007 0.476 0.031) (lineto score 0.561 0.105) (if (not style) (fill-in score) (draw score style))))) (defvar double-mordent-bounds '(0.000 0.000 0.870 0.257)) (defun draw-trill-section (score &optional style) ;(comment score "trill") (moveto score -0.045 0.053) (lineto score -0.045 0.075) (curveto score -0.028 0.099 0.058 0.171 0.113 0.158) (curveto score 0.179 0.142 0.245 0.076 0.287 0.079) (curveto score 0.339 0.076 0.354 0.095 0.383 0.118) (lineto score 0.383 0.097) (curveto score 0.366 0.076 0.279 0.001 0.223 0.008) (curveto score 0.150 0.014 0.095 0.091 0.050 0.094) (curveto score 0.002 0.097 -0.017 0.079 -0.045 0.053) (if (not style) (fill-in score) (draw score style))) (defvar trill-section-bounds '(-0.045 0.000 0.383 0.159)) (defun draw-trill-sections (score count &optional style) ;(comment score (format nil "~D trill sections" count)) (do ((i 0 (1+ i)) (x0 0.0 (+ x0 0.385))) ((>= i count)) ; count might be negative ;;(loop for i from 0 below count and x0 from 0.0 by 0.385 do (moveto score (+ x0 -0.045) 0.053) (lineto score (+ x0 -0.045) 0.075) (curveto score (+ x0 -0.028) 0.099 (+ x0 0.058) 0.171 (+ x0 0.113) 0.158) (curveto score (+ x0 0.179) 0.142 (+ x0 0.245) 0.076 (+ x0 0.287) 0.079) (curveto score (+ x0 0.339) 0.076 (+ x0 0.354) 0.095 (+ x0 0.383) 0.118) (lineto score (+ x0 0.383) 0.097) (curveto score (+ x0 0.366) 0.076 (+ x0 0.279) 0.001 (+ x0 0.223) 0.008) (curveto score (+ x0 0.150) 0.014 (+ x0 0.095) 0.091 (+ x0 0.050) 0.094) (curveto score (+ x0 0.002) 0.097 (+ x0 -0.017) 0.079 (+ x0 -0.045) 0.053) (if (not style) (fill-in score) (draw score style)))) (defun draw-arpeggio (score &optional style) ;(comment score "arpeggio") (moveto score 0.005 0.147) (curveto score -0.004 0.115 0.042 0.046 0.047 0.039) (curveto score 0.049 0.034 0.068 0.005 0.071 0.005) (curveto score 0.097 0.009 0.074 0.027 0.070 0.041) (curveto score 0.054 0.071 0.055 0.083 0.056 0.098) (curveto score 0.067 0.137 0.112 0.153 0.132 0.203) (curveto score 0.138 0.261 0.042 0.318 0.058 0.347) (curveto score 0.061 0.389 0.125 0.414 0.141 0.455) (curveto score 0.142 0.497 0.105 0.527 0.097 0.539) (curveto score 0.094 0.541 0.074 0.573 0.070 0.574) (curveto score 0.047 0.568 0.065 0.547 0.075 0.534) (curveto score 0.085 0.511 0.099 0.513 0.085 0.485) (curveto score 0.061 0.451 0.010 0.432 0.004 0.389) (curveto score 0.015 0.326 0.084 0.284 0.081 0.245) (curveto score 0.083 0.206 0.018 0.193 0.004 0.146) (if (not style) (fill-in score) (draw score style))) (defvar arpeggio-bounds '(0.000 0.000 0.141 0.574)) (defun draw-arpeggios (score count &optional style) ;(comment score (format nil "~D arpeggios" count)) (do ((i 0 (1+ i)) (y0 0.0 (+ y0 0.52))) ((>= i count)) ;; (loop for i from 0 below count and y0 from 0.0 by 0.52 do (moveto score 0.005 (+ y0 0.147)) (curveto score -0.004 (+ y0 0.115) 0.042 (+ y0 0.046) 0.047 (+ y0 0.039)) (curveto score 0.049 (+ y0 0.034) 0.068 (+ y0 0.005) 0.071 (+ y0 0.005)) (curveto score 0.097 (+ y0 0.009) 0.074 (+ y0 0.027) 0.070 (+ y0 0.041)) (curveto score 0.054 (+ y0 0.071) 0.055 (+ y0 0.083) 0.056 (+ y0 0.098)) (curveto score 0.067 (+ y0 0.137) 0.112 (+ y0 0.153) 0.132 (+ y0 0.203)) (curveto score 0.138 (+ y0 0.261) 0.042 (+ y0 0.318) 0.058 (+ y0 0.347)) (curveto score 0.061 (+ y0 0.389) 0.125 (+ y0 0.414) 0.141 (+ y0 0.455)) (curveto score 0.142 (+ y0 0.497) 0.105 (+ y0 0.527) 0.097 (+ y0 0.539)) (curveto score 0.094 (+ y0 0.541) 0.074 (+ y0 0.573) 0.070 (+ y0 0.574)) (curveto score 0.047 (+ y0 0.568) 0.065 (+ y0 0.547) 0.075 (+ y0 0.534)) (curveto score 0.085 (+ y0 0.511) 0.099 (+ y0 0.513) 0.085 (+ y0 0.485)) (curveto score 0.061 (+ y0 0.451) 0.010 (+ y0 0.432) 0.004 (+ y0 0.389)) (curveto score 0.015 (+ y0 0.326) 0.084 (+ y0 0.284) 0.081 (+ y0 0.245)) (curveto score 0.083 (+ y0 0.206) 0.018 (+ y0 0.193) 0.004 (+ y0 0.146)) (if (not style) (fill-in score) (draw score style)))) (defun draw-tr (score &optional style) (if (music-font score) (g-mustext score #o331 0 0.0) (progn ;(comment score "tr") (moveto score 0.162 0.252) (lineto score 0.198 0.380) (lineto score 0.183 0.380) (lineto score 0.121 0.341) (lineto score 0.093 0.248) (lineto score -0.005 0.244) (lineto score -0.020 0.210) (lineto score 0.083 0.216) (lineto score 0.032 0.050) (curveto score 0.002 -0.038 0.044 -0.034 0.205 0.021) (lineto score 0.198 -0.005) (lineto score 0.262 -0.005) (lineto score 0.324 0.205) (curveto score 0.325 0.207 0.339 0.239 0.359 0.248) (curveto score 0.384 0.240 0.368 0.222 0.369 0.209) (curveto score 0.380 0.164 0.429 0.169 0.434 0.215) (curveto score 0.435 0.281 0.333 0.294 0.305 0.222) (curveto score 0.300 0.276 0.243 0.260 0.209 0.256) (lineto score 0.162 0.252) (moveto score 0.146 0.211) (curveto score 0.228 0.220 0.269 0.237 0.266 0.216) (lineto score 0.222 0.076) (curveto score 0.224 0.058 0.075 0.005 0.099 0.041) (lineto score 0.146 0.211) (if (not style) (fill-in score) (draw score style))))) (defvar tr-bounds '(-0.020 -0.026 0.434 0.380)) (defun draw-accent (score &optional style) ;(comment score "accent") (moveto score 0 0) (lineto score .4 .124) (lineto score 0 .248) (lineto score 0 .216) (lineto score .3 .124) (lineto score .0 .032) (lineto score 0 0) (if (not style) (fill-in score) (draw score style))) (defvar accent-bounds '(0 0 .4 .248)) (defun draw-tnecca (score &optional style) ;accent backwards ;(comment score "accent reversed") (moveto score 0 .124) (lineto score .4 .248) (lineto score .4 .216) (lineto score .1 .124) (lineto score .4 .032) (lineto score .4 0) (lineto score 0 .124) (if (not style) (fill-in score) (draw score style))) (defvar tnecca-bounds '(0 0 .4 .248)) ;;; -------------------------------- PAUSES -------------------------------- (defun draw-breath-mark (score &optional style) ;(comment score "breath mark") (moveto score 0.027 -0.005) (curveto score 0.047 0.093 0.192 0.085 0.186 -0.055) (curveto score 0.183 -0.144 0.104 -0.198 0.049 -0.224) (lineto score 0.045 -0.215) (curveto score 0.138 -0.135 0.161 -0.087 0.127 -0.060) (curveto score 0.093 -0.094 0.025 -0.075 0.027 -0.005) (if (not style) (fill-in score) (draw score style))) (defvar breath-mark-bounds '(0.000 -0.217 0.185 0.057)) (defun draw-caesura (score &optional style) ;(comment score "caesura") (moveto score 0 0) (lineto score .05 0) (lineto score .33 .5) (lineto score .28 .5) (lineto score 0 0) (if (not style) (fill-in score) (draw score style)) (moveto score .17 0) (lineto score .22 0) (lineto score .5 .5) (lineto score .45 .5) (lineto score .17 0) (if (not style) (fill-in score) (draw score style))) (defvar caesura-bounds '(0.000 0.000 0.500 0.500)) (defun draw-fermata (score &optional style) (if (music-font score) (g-mustext score #o125 0 0.0) (progn ;(comment score "fermata") (moveto score 0.0 0.0) (curveto score -0.023 0.197 0.14 0.38 0.338 0.38) (curveto score 0.535 0.38 0.698 0.197 0.675 0.0) (rlineto score -.01 0.0) (curveto score 0.652 0.173 0.513 0.296 0.338 0.296) (curveto score 0.163 0.296 0.023 0.173 0.01 0.0) (lineto score 0 0) (if (not style) (fill-in score) (draw score style)) (circle score 0.338 0.0925 .05 0 360 (not style))))) (defvar fermata-bounds '(-0.002 0.000 0.676 0.380)) (defun draw-upside-down-fermata (score &optional style) (if (music-font score) (g-mustext score #o165 0 0.0) (progn ;(comment score "fermata reversed") (moveto score 0.0000 -0.003) (curveto score -0.023 -0.199 0.14 -0.383 0.338 -0.383) (curveto score 0.535 -0.383 0.698 -0.199 0.675 -0.003) (rlineto score -.01 0) (curveto score 0.652 -0.176 0.513 -0.298 0.338 -0.298) (curveto score 0.163 -0.298 0.023 -0.176 0.01 -0.003) (lineto score 0 -0.003) (if (not style) (fill-in score) (draw score style)) (circle score .338 -0.0925 .05 0 360 (not style))))) (defvar upside-down-fermata-bounds '(-0.002 -0.382 0.676 0.000)) ;;; -------------------------------- MISCELLANEOUS -------------------------------- (defun draw-repeat-sign (score &optional style) ;(comment score "repeat") (moveto score 0 0) (lineto score .425 .5) (rlineto score .173 0) (rlineto score -.425 -.5) (if (not style) (fill-in score) (draw score style)) (circle score .121 .375 .06 0 360 (not style)) (circle score .490 .121 .06 0 360 (not style))) (defvar repeat-sign-bounds '(0 0 .6 .5)) (defun draw-upper-bracket (score &optional style) ;(comment score "upper bracket") (moveto score 0.100 0.365) (rlineto score 0.000 -0.145) (rlineto score 0.075 0.000) (rlineto score 0.000 0.110) (curveto score 0.230 0.350 0.270 0.370 0.310 0.430) (rlineto score -0.012 0.003) (curveto score 0.270 0.400 0.230 0.370 0.100 0.365) (if (not style) (fill-in score) (draw score style))) (defvar upper-bracket-bounds '(0.000 0.000 0.310 0.433)) (defun draw-lower-bracket (score &optional style) ;(comment score "lower bracket") (moveto score 0.100 -0.365) (rlineto score 0.000 0.145) (rlineto score 0.075 0.000) (rlineto score 0.000 -0.110) (curveto score 0.230 -0.350 0.270 -0.370 0.310 -0.430) (rlineto score -0.012 -0.003) (curveto score 0.270 -0.400 0.230 -0.370 0.100 -0.365) (if (not style) (fill-in score) (draw score style))) (defvar lower-bracket-bounds '(0.000 -0.433 0.310 0.000)) (defun draw-segno (score &optional style) (if (music-font score) (g-mustext score #o45 0 0.0) (progn ;(comment score "segno") (moveto score 0.533 0.688) (lineto score 0.479 0.688) (lineto score 0.278 0.396) (curveto score 0.144 0.515 0.086 0.550 0.093 0.611) (curveto score 0.097 0.705 0.264 0.704 0.236 0.626) (curveto score 0.237 0.601 0.210 0.596 0.204 0.567) (curveto score 0.211 0.476 0.334 0.494 0.315 0.587) (curveto score 0.271 0.850 -0.209 0.656 0.220 0.312) (lineto score 0.016 0.007) (lineto score 0.068 0.007) (lineto score 0.262 0.287) (curveto score 0.340 0.236 0.486 0.141 0.450 0.059) (curveto score 0.431 -0.023 0.305 -0.005 0.306 0.060) (curveto score 0.303 0.094 0.344 0.087 0.338 0.130) (curveto score 0.331 0.209 0.231 0.211 0.224 0.121) (curveto score 0.261 -0.190 0.776 0.047 0.319 0.374) (lineto score 0.533 0.688) (if (not style) (fill-in score) (draw score style)) (circle score 0.09 .28 .05 0 360 (not style)) (circle score .45 .40 .05 9 360 (not style))))) (defvar segno-bounds '(0.000 0.000 0.532 0.696)) (defun draw-coda (score &optional style) (if (music-font score) (g-mustext score #o336 0 0.0) (progn ;(comment score "coda") (moveto score 0.241 0.379) (lineto score 0.241 0.429) (lineto score 0.216 0.429) (lineto score 0.216 0.379) (curveto score 0.130 0.375 0.071 0.280 0.075 0.196) (lineto score 0.020 0.196) (lineto score 0.020 0.171) (lineto score 0.077 0.171) (curveto score 0.071 0.090 0.132 -0.002 0.216 -0.006) (lineto score 0.216 -0.056) (lineto score 0.241 -0.056) (lineto score 0.241 -0.006) (curveto score 0.321 0.002 0.381 0.090 0.376 0.171) (lineto score 0.431 0.171) (lineto score 0.431 0.196) (lineto score 0.376 0.196) (curveto score 0.382 0.279 0.324 0.379 0.241 0.379) (moveto score 0.308 0.169) (curveto score 0.308 0.097 0.294 0.037 0.241 0.020) (lineto score 0.241 0.171) (lineto score 0.307 0.171) (moveto score 0.216 0.020) (curveto score 0.163 0.040 0.144 0.109 0.141 0.171) (lineto score 0.216 0.171) (lineto score 0.216 0.020) (moveto score 0.141 0.196) (curveto score 0.145 0.265 0.166 0.346 0.216 0.353) (lineto score 0.216 0.196) (lineto score 0.137 0.196) (moveto score 0.241 0.353) (curveto score 0.286 0.345 0.308 0.265 0.312 0.196) (lineto score 0.241 0.196) (lineto score 0.241 0.353) (if (not style) (fill-in score) (draw score style))))) (defvar coda-bounds '(0.000 -0.056 0.431 0.429)) (defun draw-pedal-off (score &optional style) (if (music-font score) (g-mustext score #o52 0 0.0) (progn ;(comment score "pedal off") (moveto score 0.219 0.198) (curveto score 0.231 0.172 0.195 0.138 0.162 0.173) (curveto score 0.149 0.219 0.206 0.231 0.219 0.198) (moveto score 0.144 0.242) (curveto score 0.166 0.223 0.193 0.230 0.181 0.267) (curveto score 0.178 0.306 0.144 0.302 0.151 0.335) (curveto score 0.160 0.381 0.225 0.377 0.224 0.330) (curveto score 0.228 0.302 0.198 0.306 0.197 0.267) (curveto score 0.194 0.237 0.213 0.222 0.237 0.247) (curveto score 0.263 0.276 0.234 0.297 0.268 0.322) (curveto score 0.314 0.347 0.354 0.297 0.316 0.259) (curveto score 0.296 0.237 0.273 0.266 0.246 0.237) (curveto score 0.223 0.217 0.232 0.194 0.266 0.197) (curveto score 0.303 0.202 0.302 0.232 0.332 0.228) (curveto score 0.381 0.232 0.388 0.156 0.332 0.152) (curveto score 0.302 0.148 0.302 0.185 0.266 0.183) (curveto score 0.231 0.186 0.228 0.169 0.245 0.143) (curveto score 0.273 0.116 0.297 0.141 0.316 0.117) (curveto score 0.350 0.075 0.303 0.029 0.258 0.062) (curveto score 0.237 0.082 0.261 0.102 0.233 0.133) (curveto score 0.212 0.151 0.194 0.147 0.197 0.113) (curveto score 0.203 0.075 0.232 0.075 0.230 0.043) (curveto score 0.223 -0.004 0.159 -0.002 0.152 0.042) (curveto score 0.148 0.075 0.185 0.076 0.183 0.113) (curveto score 0.183 0.147 0.163 0.150 0.141 0.133) (curveto score 0.113 0.104 0.140 0.079 0.113 0.059) (curveto score 0.069 0.037 0.033 0.077 0.063 0.117) (curveto score 0.082 0.141 0.104 0.117 0.132 0.142) (curveto score 0.153 0.163 0.144 0.188 0.113 0.182) (curveto score 0.073 0.182 0.075 0.147 0.046 0.152) (curveto score -0.003 0.152 -0.003 0.227 0.048 0.227) (curveto score 0.075 0.231 0.075 0.198 0.113 0.196) (curveto score 0.141 0.197 0.147 0.207 0.133 0.237) (curveto score 0.102 0.264 0.082 0.237 0.062 0.261) (curveto score 0.028 0.302 0.077 0.347 0.118 0.318) (curveto score 0.138 0.297 0.116 0.275 0.144 0.242) (if (not style) (fill-in score :even-odd t) (draw score style))))) (defvar pedal-off-bounds '(0.000 0.000 0.370 0.370)) (defun draw-ped (score &optional style) (if (music-font score) (g-mustext score #o241 0 0.0) (progn ;(comment score "ped") (moveto score 0.368 0.074) (curveto score 0.341 0.121 0.335 0.147 0.371 0.203) (curveto score 0.435 0.289 0.531 0.243 0.488 0.155) (curveto score 0.472 0.117 0.434 0.096 0.414 0.080) (curveto score 0.429 0.038 0.494 -0.006 0.541 0.075) (curveto score 0.559 0.123 0.558 0.224 0.663 0.252) (curveto score 0.603 0.354 0.449 0.393 0.461 0.405) (curveto score 0.902 0.262 0.705 -0.124 0.555 0.046) (curveto score 0.488 -0.032 0.417 0.021 0.389 0.055) (curveto score 0.303 -0.018 0.303 -0.020 0.248 0.040) (curveto score 0.218 0.108 0.191 0.062 0.164 0.047) (curveto score 0.010 -0.056 0.032 0.019 0.124 0.062) (curveto score 0.229 0.117 0.200 0.091 0.228 0.195) (curveto score 0.240 0.241 0.149 0.250 0.166 0.311) (lineto score 0.207 0.493) (curveto score -0.041 0.441 0.049 0.261 0.126 0.387) (lineto score 0.138 0.381) (curveto score -0.020 0.119 -0.100 0.472 0.220 0.507) (curveto score 0.548 0.486 0.399 0.171 0.254 0.374) (lineto score 0.264 0.384) (curveto score 0.338 0.259 0.521 0.449 0.228 0.488) (lineto score 0.198 0.356) (curveto score 0.181 0.304 0.273 0.294 0.262 0.241) (lineto score 0.229 0.101) (curveto score 0.273 0.070 0.282 -0.038 0.368 0.074) (moveto score 0.391 0.094) (curveto score 0.456 0.130 0.476 0.171 0.468 0.213) (curveto score 0.452 0.276 0.333 0.171 0.391 0.094) (moveto score 0.627 0.019) (curveto score 0.533 0.041 0.586 0.228 0.678 0.229) (curveto score 0.729 0.170 0.712 0.025 0.627 0.019) (if (not style) (fill-in score :even-odd t) (draw score style)) (circle score 0.8 0.04 .04 0 360 (not style))))) (defvar ped-bounds '(-0.006 -0.003 0.731 0.507)) (defun draw-left-paren (score &optional style) ;(comment score "left paren") (moveto score 0.157 0.580) (curveto score 0.090 0.540 -0.015 0.442 -0.012 0.287) (curveto score -0.007 0.145 0.082 0.040 0.147 -0.005) (lineto score 0.153 0.003) (curveto score 0.035 0.122 0.047 0.193 0.047 0.297) (curveto score 0.042 0.417 0.067 0.490 0.162 0.570) (lineto score 0.157 0.580) (if (not style) (fill-in score) (draw score style))) (defvar left-paren-bounds '(-0.012 -0.005 0.162 0.580)) (defun draw-right-paren (score &optional style) ;(comment score "right paren") (moveto score 0.005 0.580) (curveto score 0.072 0.540 0.177 0.442 0.174 0.287) (curveto score 0.169 0.145 0.080 0.040 0.015 -0.005) (lineto score 0.009 0.003) (curveto score 0.127 0.122 0.115 0.193 0.115 0.297) (curveto score 0.120 0.417 0.095 0.490 0.0 0.570) (lineto score 0.005 0.580) (if (not style) (fill-in score) (draw score style))) (defvar right-paren-bounds '(0.000 -0.005 0.173 0.580)) (defun draw-wedge (score &optional style) ;(comment score "wedge") (moveto score 0 0) (lineto score -.075 .25) (lineto score .075 .25) (lineto score 0 0) (if (not style) (fill-in score) (draw score style))) (defvar wedge-bounds '(-.075 0 .075 .25)) (defun draw-down-bow (score &optional style) ;(comment score "down bow") (moveto score 0 0) (lineto score 0 .15) (lineto score .3 .15) (lineto score .3 0) (lineto score .29 0) (lineto score .29 .075) (lineto score .01 .075) (lineto score .01 0) (lineto score 0 0) (if (not style) (fill-in score) (draw score style))) (defvar down-bow-bounds '(0.000 0.000 0.300 0.150)) (defun draw-up-bow (score &optional style) ;(comment score "up bow") (moveto score 0.075 0.000) (lineto score 0.000 0.250) (lineto score 0.010 0.250) (lineto score 0.075 0.055) (lineto score 0.140 0.250) (lineto score 0.150 0.250) (lineto score 0.075 0.000) (if (not style) (fill-in score) (draw score style))) (defvar up-bow-bounds '(0.000 0.000 0.150 0.250)) ;;; -------------------------------- NUMBERS and METERS -------------------------------- (defun draw-zero (score &optional style) (if (music-font score) (g-mustext score #o60 0 0.0) (progn ;(comment score "zero") (moveto score 0.159 0.233) (curveto score 0.272 0.233 0.333 0.117 0.333 0.000) (curveto score 0.333 -0.130 0.270 -0.235 0.159 -0.233) (curveto score 0.041 -0.233 -0.013 -0.122 -0.019 -0.006) (curveto score -0.015 0.113 0.043 0.233 0.159 0.233) (moveto score 0.159 0.207) (curveto score 0.218 0.207 0.228 0.083 0.229 -0.002) (curveto score 0.228 -0.085 0.216 -0.207 0.159 -0.207) (curveto score 0.100 -0.207 0.089 -0.085 0.085 0.000) (curveto score 0.085 0.085 0.096 0.207 0.159 0.207) (if (not style) (fill-in score :even-odd t) (draw score style))))) (defvar zero-bounds '(-0.018 -0.233 0.333 0.233)) (defun draw-one (score &optional style) (if (music-font score) (g-mustext score #o61 0 0.0) (progn ;(comment score "one") (moveto score 0.070 -0.182) (curveto score 0.068 -0.199 0.042 -0.203 0.026 -0.203) (lineto score 0.026 -0.233) (lineto score 0.209 -0.233) (lineto score 0.209 -0.203) (curveto score 0.199 -0.202 0.171 -0.203 0.167 -0.187) (lineto score 0.167 0.233) (lineto score 0.070 0.233) (lineto score -0.011 0.034) (lineto score 0.010 0.024) (lineto score 0.070 0.130) (lineto score 0.070 -0.182) (if (not style) (fill-in score) (draw score style))))) (defvar one-bounds '(0.000 -0.233 0.212 0.233)) (defun draw-two (score &optional style) (if (music-font score) (g-mustext score #o62 0 0.0) (progn ;(comment score "two") (moveto score 0.068 0.170) (curveto score 0.093 0.168 0.130 0.167 0.130 0.113) (curveto score 0.123 0.042 0.007 0.044 0.006 0.131) (curveto score 0.007 0.179 0.074 0.233 0.146 0.233) (curveto score 0.224 0.233 0.318 0.202 0.329 0.107) (curveto score 0.320 0.010 0.238 -0.013 0.152 -0.052) (curveto score 0.105 -0.071 0.063 -0.114 0.067 -0.137) (curveto score 0.113 -0.107 0.157 -0.100 0.205 -0.122) (curveto score 0.239 -0.138 0.252 -0.170 0.274 -0.170) (curveto score 0.329 -0.170 0.316 -0.111 0.316 -0.107) (lineto score 0.337 -0.107) (curveto score 0.335 -0.158 0.326 -0.231 0.244 -0.237) (curveto score 0.165 -0.235 0.146 -0.172 0.083 -0.172) (curveto score 0.015 -0.167 0.024 -0.217 0.019 -0.226) (lineto score 0.000 -0.226) (lineto score 0.000 -0.161) (curveto score 0.011 -0.072 0.231 0.014 0.233 0.104) (curveto score 0.233 0.167 0.194 0.205 0.111 0.200) (curveto score 0.068 0.198 0.050 0.168 0.068 0.170) (if (not style) (fill-in score) (draw score style))))) (defvar two-bounds '(0.000 -0.234 0.336 0.233)) (defun draw-three (score &optional style) (if (music-font score) (g-mustext score #o63 0 0.0) (progn ;(comment score "three") (moveto score 0.094 0.007) (curveto score 0.163 0.028 0.204 0.039 0.203 0.102) (curveto score 0.212 0.180 0.159 0.209 0.117 0.207) (curveto score 0.072 0.210 0.026 0.165 0.052 0.155) (curveto score 0.113 0.148 0.113 0.074 0.050 0.068) (curveto score 0.020 0.070 -0.010 0.092 -0.005 0.147) (curveto score 0.034 0.273 0.291 0.257 0.292 0.103) (curveto score 0.292 0.039 0.265 0.019 0.220 0.000) (curveto score 0.259 -0.017 0.291 -0.043 0.289 -0.114) (curveto score 0.272 -0.281 -0.001 -0.262 -0.011 -0.134) (curveto score -0.013 -0.091 0.020 -0.063 0.050 -0.067) (curveto score 0.098 -0.070 0.113 -0.144 0.052 -0.157) (curveto score 0.033 -0.172 0.065 -0.207 0.117 -0.207) (curveto score 0.170 -0.201 0.208 -0.177 0.204 -0.099) (curveto score 0.200 -0.038 0.163 -0.028 0.094 -0.007) (lineto score 0.094 0.007) (if (not style) (fill-in score) (draw score style))))) (defvar three-bounds '(-0.007 -0.234 0.292 0.234)) (defun draw-four (score &optional style) (if (music-font score) (g-mustext score #o64 0 0.0) (progn ;(comment score "four") (moveto score 0.252 0.233) (lineto score 0.113 0.233) (curveto score 0.107 0.128 0.108 0.003 -0.002 -0.097) (lineto score -0.002 -0.122) (lineto score 0.159 -0.122) (lineto score 0.159 -0.188) (curveto score 0.157 -0.198 0.130 -0.207 0.115 -0.206) (lineto score 0.115 -0.233) (lineto score 0.309 -0.233) (lineto score 0.309 -0.207) (curveto score 0.299 -0.207 0.274 -0.203 0.268 -0.187) (lineto score 0.268 -0.122) (lineto score 0.309 -0.122) (lineto score 0.309 -0.096) (lineto score 0.265 -0.096) (lineto score 0.265 0.146) (lineto score 0.159 0.017) (lineto score 0.159 -0.096) (lineto score 0.043 -0.096) (curveto score 0.139 0.021 0.217 0.149 0.252 0.233) (if (not style) (fill-in score) (draw score style))))) (defvar four-bounds '(-0.004 -0.233 0.308 0.233)) (defun draw-five (score &optional style) (if (music-font score) (g-mustext score #o65 0 0.0) (progn ;(comment score "five") (moveto score 0.022 0.233) (lineto score 0.022 -0.002) (lineto score 0.050 -0.002) (curveto score 0.067 0.026 0.093 0.041 0.124 0.041) (curveto score 0.178 0.041 0.207 -0.015 0.207 -0.070) (curveto score 0.209 -0.165 0.169 -0.211 0.120 -0.212) (curveto score 0.098 -0.215 0.076 -0.211 0.056 -0.187) (curveto score 0.039 -0.149 0.114 -0.196 0.118 -0.126) (curveto score 0.104 -0.067 0.015 -0.068 0.008 -0.145) (curveto score 0.005 -0.275 0.306 -0.297 0.296 -0.063) (curveto score 0.283 0.028 0.224 0.068 0.137 0.068) (curveto score 0.109 0.068 0.076 0.056 0.050 0.030) (lineto score 0.050 0.159) (curveto score 0.057 0.152 0.152 0.135 0.199 0.155) (curveto score 0.248 0.176 0.264 0.203 0.269 0.236) (curveto score 0.181 0.212 0.087 0.211 0.022 0.233) (if (not style) (fill-in score) (draw score style))))) (defvar five-bounds '(0.000 -0.233 0.296 0.233)) (defun draw-six (score &optional style) (if (music-font score) (g-mustext score #o66 0 0.0) (progn ;(comment score "six") (moveto score 0.168 -0.238) (curveto score 0.244 -0.235 0.303 -0.182 0.305 -0.096) (curveto score 0.305 -0.043 0.274 0.030 0.205 0.030) (curveto score 0.167 0.030 0.137 0.015 0.115 -0.015) (curveto score 0.093 -0.006 0.089 0.176 0.150 0.207) (curveto score 0.194 0.235 0.242 0.198 0.231 0.181) (curveto score 0.207 0.176 0.188 0.159 0.190 0.119) (curveto score 0.208 0.062 0.291 0.069 0.300 0.128) (curveto score 0.299 0.175 0.276 0.236 0.179 0.240) (curveto score 0.074 0.235 0.007 0.117 0.007 0.004) (curveto score 0.011 -0.108 0.057 -0.231 0.168 -0.238) (moveto score 0.174 -0.215) (curveto score 0.220 -0.212 0.228 -0.155 0.228 -0.108) (curveto score 0.229 -0.061 0.222 0.006 0.174 0.006) (curveto score 0.124 0.006 0.115 -0.058 0.117 -0.108) (curveto score 0.118 -0.157 0.126 -0.215 0.174 -0.215) (if (not style) (fill-in score :even-odd t) (draw score style))))) (defvar six-bounds '(0.000 -0.238 0.305 0.242)) (defun draw-seven (score &optional style) (if (music-font score) (g-mustext score #o67 0 0.0) (progn ;(comment score "seven") (moveto score 0.068 -0.233) (lineto score 0.202 -0.233) (curveto score 0.202 -0.228 0.185 -0.117 0.229 -0.048) (curveto score 0.263 0.007 0.338 0.076 0.330 0.234) (lineto score 0.306 0.234) (curveto score 0.266 0.147 0.235 0.205 0.169 0.225) (curveto score 0.080 0.235 0.061 0.169 0.028 0.220) (lineto score 0.004 0.220) (lineto score 0.004 0.120) (lineto score 0.028 0.120) (curveto score 0.037 0.164 0.106 0.177 0.151 0.139) (curveto score 0.214 0.099 0.265 0.112 0.294 0.142) (curveto score 0.286 0.060 0.218 0.004 0.159 -0.046) (curveto score 0.077 -0.112 0.067 -0.226 0.068 -0.233) (if (not style) (fill-in score) (draw score style))))) (defvar seven-bounds '(0.000 -0.233 0.307 0.233)) (defun draw-eight (score &optional style) (if (music-font score) (g-mustext score #o70 0 0.0) (progn ;(comment score "eight") (moveto score 0.146 0.235) (curveto score 0.068 0.233 0.015 0.198 -0.004 0.125) (curveto score -0.011 0.048 0.055 0.024 0.068 0.009) (curveto score 0.042 -0.006 -0.006 -0.051 -0.007 -0.117) (curveto score 0.002 -0.189 0.054 -0.234 0.154 -0.238) (curveto score 0.228 -0.237 0.295 -0.195 0.296 -0.109) (curveto score 0.301 -0.073 0.279 -0.025 0.220 0.015) (curveto score 0.265 0.045 0.290 0.082 0.287 0.131) (curveto score 0.279 0.193 0.213 0.233 0.146 0.235) (moveto score 0.146 0.209) (curveto score 0.200 0.208 0.233 0.170 0.235 0.114) (curveto score 0.237 0.083 0.208 0.052 0.185 0.038) (curveto score 0.149 0.070 0.085 0.083 0.069 0.140) (curveto score 0.069 0.172 0.101 0.208 0.146 0.209) (moveto score 0.099 -0.014) (curveto score 0.132 -0.040 0.191 -0.055 0.224 -0.114) (curveto score 0.240 -0.166 0.207 -0.207 0.146 -0.207) (curveto score 0.080 -0.202 0.051 -0.150 0.047 -0.098) (curveto score 0.043 -0.059 0.073 -0.024 0.098 -0.013) (if (not style) (fill-in score) (draw score style))))) (defvar eight-bounds '(-0.002 -0.238 0.290 0.233)) (defun draw-nine (score &optional style) (if (music-font score) (g-mustext score #o71 0 0.0) (progn ;(comment score "nine") (moveto score 0.129 0.235) (curveto score -0.113 0.212 -0.049 -0.123 0.189 -0.003) (curveto score 0.211 0.006 0.216 -0.176 0.157 -0.198) (curveto score 0.106 -0.232 0.072 -0.203 0.079 -0.197) (curveto score 0.125 -0.179 0.135 -0.142 0.114 -0.105) (curveto score 0.096 -0.065 0.019 -0.072 0.003 -0.133) (curveto score 0.000 -0.193 0.053 -0.244 0.132 -0.235) (curveto score 0.220 -0.231 0.307 -0.117 0.307 -0.003) (curveto score 0.309 0.111 0.264 0.240 0.131 0.235) (moveto score 0.131 0.215) (curveto score 0.085 0.213 0.075 0.155 0.076 0.109) (curveto score 0.076 0.059 0.080 -0.006 0.131 -0.006) (curveto score 0.181 -0.007 0.191 0.059 0.187 0.109) (curveto score 0.187 0.157 0.178 0.215 0.131 0.215) (if (not style) (fill-in score :even-odd t) (draw score style))))) (defvar nine-bounds '(-0.024 -0.234 0.307 0.234)) (defun draw-common-time (score &optional style) (if (music-font score) (g-mustext score #o143 0 0.0) (progn ;(comment score "common time") (moveto score 0.004 0.000) (moveto score 0.004 0.000) (curveto score 0.004 -0.128 0.096 -0.247 0.228 -0.247) (curveto score 0.328 -0.246 0.391 -0.171 0.410 -0.070) (lineto score 0.383 -0.070) (curveto score 0.366 -0.160 0.310 -0.215 0.230 -0.223) (curveto score 0.136 -0.220 0.110 -0.114 0.113 -0.002) (curveto score 0.113 0.102 0.128 0.200 0.224 0.220) (curveto score 0.266 0.230 0.312 0.220 0.344 0.186) (curveto score 0.358 0.172 0.356 0.162 0.334 0.156) (curveto score 0.300 0.159 0.263 0.134 0.263 0.084) (curveto score 0.270 -0.004 0.414 -0.001 0.418 0.096) (curveto score 0.418 0.210 0.310 0.258 0.218 0.252) (curveto score 0.092 0.246 0.004 0.128 0.004 0.000) (if (not style) (fill-in score) (draw score style))))) (defvar common-time-bounds '(0.000 -0.247 0.417 0.252)) (defun draw-cut-time (score &optional style) (if (music-font score) (g-mustext score #o103 0 0.0) (progn ;(comment score "cut time") (draw-common-time score style) (moveto score 0.194 0.374) (lineto score 0.194 -0.414) (lineto score 0.222 -0.414) (lineto score 0.222 0.374) (if (not style) (fill-in score) (draw score style))))) (defvar cut-time-bounds '(0.000 -0.414 0.418 0.374)) (defun draw-plus (score &optional style) ;(comment score "plus") (moveto score 0.000 -0.020) (lineto score 0.100 -0.020) (lineto score 0.100 -0.140) (lineto score 0.140 -0.140) (lineto score 0.140 -0.020) (lineto score 0.240 -0.020) (lineto score 0.240 0.020) (lineto score 0.140 0.020) (lineto score 0.140 0.140) (lineto score 0.100 0.140) (lineto score 0.100 0.020) (lineto score 0.000 0.020) (lineto score 0.000 -0.020) (if (not style) (fill-in score) (draw score style))) (defvar plus-bounds '(0.000 -0.140 0.240 0.140)) ;;; -------------------------------- ACCIDENTALS -------------------------------- (defun draw-sharp (score &optional style) (if (music-font score) (g-mustext score #o43 0 0.0) (progn ;(comment score "sharp") (moveto score 0.168 0.098) (lineto score 0.168 -0.050) (lineto score 0.210 -0.032) (lineto score 0.210 -0.136) (lineto score 0.168 -0.154) (lineto score 0.168 -0.338) (lineto score 0.140 -0.338) (lineto score 0.140 -0.166) (lineto score 0.072 -0.194) (lineto score 0.072 -0.380) (lineto score 0.044 -0.380) (lineto score 0.044 -0.206) (lineto score 0.000 -0.222) (lineto score 0.000 -0.116) (lineto score 0.044 -0.100) (lineto score 0.044 0.048) (lineto score 0.000 0.032) (lineto score 0.000 0.138) (lineto score 0.044 0.154) (lineto score 0.044 0.338) (lineto score 0.072 0.338) (lineto score 0.072 0.166) (lineto score 0.140 0.192) (lineto score 0.140 0.380) (lineto score 0.168 0.380) (lineto score 0.168 0.204) (lineto score 0.210 0.222) (lineto score 0.210 0.116) (lineto score 0.168 0.098) (moveto score 0.140 0.088) (lineto score 0.072 0.060) (lineto score 0.072 -0.088) (lineto score 0.140 -0.060) (lineto score 0.140 0.088) (if (not style) (fill-in score) (draw score style))))) (defvar sharp-bounds '(0.000 -0.380 0.210 0.380)) (defun draw-flat (score &optional style) (if (music-font score) (g-mustext score #o142 0 0.0) (progn ;(comment score "flat") (moveto score 0.027 0.086) (lineto score 0.027 0.483) (lineto score 0.000 0.483) (lineto score 0.000 -0.193) (curveto score 0.012 -0.186 0.070 -0.139 0.097 -0.119) (curveto score 0.141 -0.086 0.244 -0.024 0.215 0.082) (curveto score 0.165 0.204 0.027 0.087 0.027 0.086) (moveto score 0.027 0.037) (lineto score 0.027 -0.137) (curveto score 0.032 -0.140 0.206 0.029 0.120 0.090) (curveto score 0.112 0.093 0.085 0.105 0.027 0.037) (if (not style) (fill-in score :even-odd t) (draw score style))))) (defvar flat-bounds '(0.000 -0.193 0.222 0.483)) (defun draw-double-sharp (score &optional style) (if (music-font score) (g-mustext score #o334 0 0.0) (progn ;(comment score "double sharp") (moveto score 0.000 0.130) (lineto score 0.090 0.130) (curveto score 0.091 -0.002 0.174 -0.001 0.170 0.130) (lineto score 0.260 0.130) (lineto score 0.260 0.040) (curveto score 0.127 0.028 0.136 -0.040 0.260 -0.040) (lineto score 0.260 -0.130) (lineto score 0.170 -0.130) (curveto score 0.165 0.002 0.091 0.000 0.090 -0.130) (lineto score 0.000 -0.130) (lineto score 0.000 -0.043) (curveto score 0.127 -0.042 0.127 0.027 0.000 0.040) (lineto score 0.000 0.130) (if (not style) (fill-in score) (draw score style))))) (defvar double-sharp-bounds '(0.000 -0.130 0.260 0.130)) (defun draw-natural (score &optional style) (if (music-font score) (g-mustext score #o156 0 0.0) (progn ;(comment score "natural") (moveto score 0.000 -0.180) (lineto score 0.144 -0.142) (lineto score 0.144 -0.348) (lineto score 0.170 -0.348) (lineto score 0.170 0.176) (lineto score 0.026 0.138) (lineto score 0.026 0.348) (lineto score 0.000 0.348) (lineto score 0.000 -0.180) (moveto score 0.026 -0.076) (lineto score 0.026 0.048) (lineto score 0.144 0.078) (lineto score 0.144 -0.046) (lineto score 0.026 -0.076) (if (not style) (fill-in score) (draw score style))))) (defvar natural-bounds '(0.000 -0.348 0.170 0.348)) (defun draw-double-flat (score &optional style) (if (music-font score) (g-mustext score #o272 0 0.0) (progn ;(comment score "double flat") (draw-flat score style) (matrix-front score (list 1 0 0 1 (* .2 (scr-size score)) 0)) (draw-flat score style) (matrix-back score)))) (defvar double-flat-bounds '(-0.002 -0.194 0.44 0.484)) ;;; -------------------------------- DYNAMICS -------------------------------- (defun draw-f (score &optional style) (if (music-font score) (g-mustext score #o146 0 0.0) (progn ;(comment score "f") (moveto score 0.420 0.238) (lineto score 0.330 0.238) (curveto score 0.330 0.230 0.334 0.348 0.418 0.386) (curveto score 0.444 0.398 0.496 0.400 0.490 0.374) (curveto score 0.488 0.362 0.462 0.370 0.452 0.360) (curveto score 0.429 0.342 0.426 0.308 0.448 0.292) (curveto score 0.478 0.276 0.521 0.292 0.514 0.344) (curveto score 0.514 0.400 0.456 0.432 0.386 0.414) (curveto score 0.258 0.380 0.232 0.240 0.234 0.238) (lineto score 0.158 0.238) (lineto score 0.158 0.210) (lineto score 0.228 0.210) (curveto score 0.228 0.208 0.172 -0.046 0.122 -0.117) (curveto score 0.114 -0.133 0.096 -0.158 0.078 -0.158) (curveto score 0.056 -0.162 0.046 -0.142 0.060 -0.139) (curveto score 0.099 -0.138 0.113 -0.074 0.056 -0.059) (curveto score 0.022 -0.052 -0.018 -0.102 0.007 -0.146) (curveto score 0.026 -0.176 0.088 -0.188 0.134 -0.162) (curveto score 0.244 -0.100 0.287 0.046 0.324 0.210) (lineto score 0.420 0.210) (lineto score 0.420 0.238) (if (not style) (fill-in score) (draw score style))))) (defvar f-bounds '(0.000 -0.176 0.514 0.418)) (defun draw-p (score &optional style) (if (music-font score) (g-mustext score #o160 0 0.0) (progn ;(comment score "p") (moveto score 0.184 0.047) (curveto score 0.203 0.016 0.218 0.006 0.248 0.004) (curveto score 0.379 0.002 0.464 0.230 0.336 0.290) (curveto score 0.280 0.310 0.228 0.262 0.211 0.246) (curveto score 0.210 0.333 0.126 0.312 0.068 0.153) (lineto score 0.089 0.147) (curveto score 0.155 0.310 0.205 0.279 0.185 0.224) (lineto score 0.040 -0.120) (lineto score 0.000 -0.120) (lineto score 0.000 -0.146) (lineto score 0.157 -0.146) (lineto score 0.157 -0.120) (lineto score 0.117 -0.120) (lineto score 0.184 0.047) (moveto score 0.222 0.047) (curveto score 0.160 0.086 0.245 0.261 0.321 0.268) (curveto score 0.377 0.218 0.303 0.029 0.222 0.047) (if (not style) (fill-in score) (draw score style))))) (defvar p-bounds '(0.000 -0.148 0.404 0.292)) (defun draw-lig-p (score &optional style) ;; p without the pronounced upstroke (to connect to f in fp) ;(comment score "P") (moveto score 0.184 0.047) (curveto score 0.203 0.016 0.218 0.006 0.248 0.004) (curveto score 0.379 0.002 0.464 0.230 0.336 0.290) (curveto score 0.280 0.310 0.228 0.262 0.211 0.246) (curveto score 0.205 0.285 0.168 0.304 0.138 0.296) (lineto score 0.136 0.270) (curveto score 0.162 0.278 0.190 0.257 0.185 0.224) (lineto score 0.040 -0.120) (lineto score 0.000 -0.120) (lineto score 0.000 -0.145) (lineto score 0.157 -0.145) (lineto score 0.157 -0.120) (lineto score 0.117 -0.120) (lineto score 0.184 0.047) (moveto score 0.222 0.047) (curveto score 0.160 0.086 0.245 0.261 0.321 0.268) (curveto score 0.377 0.218 0.303 0.029 0.222 0.047) (if (not style) (fill-in score) (draw score style))) (defvar lig-p-bounds '(0.000 -0.147 0.404 0.299)) (defun draw-m (score &optional style) ;(comment score "m") (moveto score 0.188 0.000) (lineto score 0.271 0.226) (curveto score 0.287 0.270 0.252 0.303 0.207 0.225) (lineto score 0.120 0.000) (lineto score 0.052 0.000) (lineto score 0.157 0.261) (curveto score 0.160 0.304 0.072 0.266 0.045 0.184) (lineto score 0.027 0.184) (curveto score 0.056 0.245 0.100 0.301 0.159 0.292) (curveto score 0.188 0.286 0.200 0.262 0.200 0.243) (curveto score 0.228 0.303 0.327 0.312 0.333 0.243) (curveto score 0.373 0.317 0.488 0.303 0.468 0.236) (lineto score 0.396 0.038) (curveto score 0.386 0.001 0.435 0.024 0.460 0.074) (lineto score 0.472 0.071) (curveto score 0.429 -0.026 0.310 -0.065 0.335 0.019) (lineto score 0.403 0.222) (curveto score 0.424 0.273 0.375 0.291 0.346 0.228) (lineto score 0.264 0.000) (lineto score 0.186 0.000) (if (not style) (fill-in score) (draw score style))) (defvar m-bounds '(0.000 -0.012 0.472 0.292)) (defun draw-n (score &optional style) ;(comment score "n") (moveto score 0.210 0.019) (lineto score 0.280 0.226) (curveto score 0.287 0.270 0.253 0.302 0.207 0.225) (lineto score 0.120 0.000) (lineto score 0.052 0.000) (lineto score 0.158 0.261) (curveto score 0.160 0.304 0.072 0.266 0.045 0.184) (lineto score 0.028 0.184) (curveto score 0.056 0.245 0.100 0.301 0.159 0.292) (curveto score 0.188 0.286 0.200 0.263 0.200 0.242) (curveto score 0.228 0.302 0.338 0.312 0.341 0.243) (lineto score 0.265 0.024) (curveto score 0.264 0.001 0.331 0.024 0.340 0.074) (lineto score 0.352 0.071) (curveto score 0.33 -0.026 0.210 -0.065 0.210 0.019) (if (not style) (fill-in score) (draw score style)) ) (defvar n-bounds '(0.000 -0.034 0.367 0.292)) (defun draw-niente (score &optional style) (if *use-circle-as-niente* (progn ;(comment score "n.") (setf (line-width score) 0.02) (circle score 0.1 0.125 .05 0 360 nil) (setf (line-width score) 0.0)) (progn (draw-n score style) (circle score 0.425 0.025 0.03 0 360 t)))) (defvar niente-bounds '(0.00 0 0.45 0.175)) (defun draw-subito (score &optional style) ;(declare (ignore style)) ;(comment score "I") (setf (line-width score) 0.02) (moveto score 0.3 -0.2) (rlineto score 0 0.7) (draw score t) (setf (line-width score) 0.0)) (defvar subito-bounds '(0.0 -0.2 0.6 0.7)) (defun draw-z (score &optional style) ;(comment score "z") (moveto score 0.082 0.287) (lineto score 0.052 0.222) (lineto score 0.069 0.222) (lineto score 0.089 0.240) (lineto score 0.238 0.240) (lineto score -0.003 0.006) (lineto score 0.034 0.006) (curveto score 0.072 0.043 0.156 0.028 0.191 0.003) (curveto score 0.274 -0.021 0.302 0.046 0.265 0.101) (curveto score 0.251 0.117 0.219 0.118 0.205 0.093) (curveto score 0.206 0.050 0.249 0.075 0.246 0.041) (curveto score 0.206 0.000 0.196 0.113 0.092 0.061) (lineto score 0.299 0.261) (lineto score 0.299 0.287) (lineto score 0.082 0.287) (if (not style) (fill-in score) (draw score style))) (defvar z-bounds '(-0.003 -0.009 0.299 0.287)) (defun draw-s (score &optional style) ;(comment score "s") (moveto score 0.148 0.066) (curveto score 0.161 0.028 0.130 0.002 0.083 0.009) (curveto score 0.032 0.038 0.107 0.045 0.077 0.088) (curveto score 0.055 0.113 0.018 0.101 0.014 0.068) (curveto score 0.019 -0.043 0.216 -0.041 0.208 0.076) (curveto score 0.200 0.141 0.113 0.167 0.091 0.211) (curveto score 0.072 0.255 0.134 0.297 0.172 0.268) (curveto score 0.212 0.237 0.145 0.225 0.188 0.188) (curveto score 0.223 0.179 0.242 0.199 0.236 0.224) (curveto score 0.209 0.327 0.028 0.306 0.032 0.212) (curveto score 0.037 0.149 0.142 0.116 0.148 0.066) (if (not style) (fill-in score) (draw score style))) (defvar s-bounds '(0.000 -0.009 0.236 0.293)) (defun draw-r (score &optional style) ;(comment score "r") (moveto score 0.210 0.010) (curveto score 0.243 0.184 0.262 0.219 0.295 0.246) (curveto score 0.350 0.261 0.311 0.213 0.349 0.198) (curveto score 0.398 0.181 0.431 0.252 0.368 0.291) (curveto score 0.327 0.308 0.278 0.268 0.256 0.235) (curveto score 0.303 0.336 0.172 0.345 0.072 0.198) (lineto score 0.085 0.186) (curveto score 0.123 0.248 0.206 0.312 0.185 0.239) (lineto score 0.129 0.010) (lineto score 0.210 0.010) (if (not style) (fill-in score) (draw score style))) (defvar r-bounds '(0.000 0.000 0.396 0.297)) ;;; -------------------------------- NOTE HEADS and FLAGS -------------------------------- (defun draw-double-whole-note (score &optional style) (if (music-font score) (g-mustext score #o127 0 0.0) (progn ;(comment score "double whole note") (moveto score .298 .127) (curveto score 0.393 0.127 0.501 0.087 0.505 0.000) (curveto score 0.508 -0.095 0.393 -0.128 0.298 -0.127) (curveto score 0.207 -0.125 0.100 -0.087 0.100 0.000) (curveto score 0.102 0.091 0.204 0.127 0.298 0.127) (moveto score 0.263 .108) (curveto score 0.325 0.124 0.370 0.065 0.381 0.001) (curveto score 0.389 -0.050 0.387 -0.091 0.342 -0.108) (curveto score 0.286 -0.125 0.247 -0.075 0.230 -0.023) (curveto score 0.214 0.039 0.212 0.089 0.263 0.108) (if (not style) (fill-in score :even-odd t) (draw score style)) (moveto score 0.000 0.166) (lineto score 0.031 0.166) (lineto score 0.031 -0.166) (lineto score 0.000 -0.166) (lineto score 0.000 0.166) (if (not style) (fill-in score) (draw score style)) (moveto score 0.069 0.166) (lineto score 0.100 0.166) (lineto score 0.100 -0.166) (lineto score 0.069 -0.166) (lineto score 0.069 0.166) (if (not style) (fill-in score) (draw score style)) (moveto score 0.505 0.166) (lineto score 0.537 0.166) (lineto score 0.537 -0.166) (lineto score 0.505 -0.166) (lineto score 0.505 0.166) (if (not style) (fill-in score) (draw score style)) (moveto score 0.576 0.166) (lineto score 0.607 0.166) (lineto score 0.607 -0.166) (lineto score 0.576 -0.166) (lineto score 0.576 0.166) (if (not style) (fill-in score) (draw score style))))) (defvar double-whole-note-bounds '(0.000 -0.166 0.607 0.166)) (defun draw-whole-note (score &optional style) (if (music-font score) (g-mustext score #o167 0 0.0) (progn ;(comment score "whole note") (moveto score 0.198 0.127) (curveto score 0.293 0.127 0.402 0.087 0.405 0.000) (curveto score 0.408 -0.095 0.293 -0.128 0.198 -0.127) (curveto score 0.107 -0.125 0.000 -0.087 0.000 0.000) (curveto score 0.002 0.091 0.104 0.127 0.198 0.127) (moveto score 0.163 0.108) (curveto score 0.225 0.124 0.270 0.065 0.281 0.001) (curveto score 0.289 -0.050 0.287 -0.091 0.242 -0.108) (curveto score 0.186 -0.125 0.147 -0.075 0.130 -0.023) (curveto score 0.114 0.039 0.112 0.089 0.163 0.108) (if (not style) (fill-in score :even-odd t) (draw score style))))) (defvar whole-note-bounds '(0.000 -0.127 0.405 0.127)) (defun draw-half-note (score &optional style) (if (music-font score) (g-mustext score #o372 0 0.0) (let ((xoff -.006)) ;(comment score "half note") (moveto score (+ xoff 0.020) -0.101) (curveto score (+ xoff -0.063) 0.037 (+ xoff 0.185) 0.197 (+ xoff 0.268) 0.107) (curveto score (+ xoff 0.379) -0.010 (+ xoff 0.137) -0.193 (+ xoff 0.021) -0.101) (moveto score (+ xoff 0.043) -0.082) (curveto score (+ xoff 0.015) -0.007 (+ xoff 0.207) 0.125 (+ xoff 0.239) 0.087) (curveto score (+ xoff 0.291) 0.027 (+ xoff 0.097) -0.139 (+ xoff 0.043) -0.082) (if (not style) (fill-in score :even-odd t) (draw score style))))) (defvar half-note-bounds '(0.000 -0.131 0.291 0.134)) (defun draw-quarter-note (score &optional style) (if (music-font score) (g-mustext score #o317 0 0.0) (progn ;(comment score "quarter note") (moveto score 0.014 -0.088) (curveto score -0.014 -0.030 0.026 0.056 0.090 0.096) (curveto score 0.144 0.128 0.230 0.142 0.270 0.092) (curveto score 0.316 0.024 0.258 -0.060 0.190 -0.100) (curveto score 0.130 -0.126 0.066 -0.136 0.014 -0.088) (if (not style) (fill-in score) (draw score style))))) (defvar quarter-note-bounds '(0.000 -0.120 0.286 0.124)) (defun draw-diamond (score &optional style) ;(comment score "diamond") (setf (line-width score) .03) (moveto score 0 0) (rlineto score .14 .14) (rlineto score .14 -.14) (rlineto score -.14 -.14) (rlineto score -.14 .14) (if (not style) (fill-in score) (draw score style)) (setf (line-width score) 0)) (defvar diamond-bounds '(0.0 -.14 .28 .14)) (defun draw-diamond-1 (score &optional style) ;(comment score "diamond-1") ;Anders Vinjar (setf (line-width score) .03) (moveto score 0 0) (curveto score 0.04 0.03 0.10 .07 .14 .14) (curveto score .12 .05 .08 .03 0.0 0.0) (moveto score .28 .0) (curveto score .24 -.03 .18 -.07 .14 -.14) (curveto score .16 -.07 .20 -.03 .28 .0) (moveto score .0 .0) (lineto score .05 .03) (curveto score .1 .0 .13 -.02 .17 -.08) (lineto score .14 -.14) (curveto score .10 -.07 .04 -0.03 0 0) (moveto score .28 .0) (lineto score .23 -.03) (curveto score .20 -.02 .14 .01 .11 .09) (lineto score .14 .14) (curveto score .18 .07 .24 .03 .28 .0) (fill-in score) (if (not style) (fill-in score :even-odd t) (draw score style)) (setf (line-width score) 0)) (defun draw-filled-diamond-1 (score &optional style) ;(comment score "filled diamond-1") (setf (line-width score) .03) (moveto score 0 0) (curveto score 0.04 0.03 0.10 .07 .14 .14) (curveto score .18 .07 .24 .03 .28 .0) (curveto score .24 -.03 .18 -.07 .14 -.14) (curveto score .10 -.07 .04 -0.03 0 0) (if (not style) (fill-in score :even-odd t) (draw score style)) (setf (line-width score) 0)) (defvar diamond-1-bounds '(0.0 -.14 .28 .14)) (defun draw-rhythmX (score &optional style) ;(comment score "X") (moveto score 0.128 0.000) (lineto score 0.002 0.102) (lineto score 0.020 0.124) (lineto score 0.150 0.020) (lineto score 0.278 0.124) (lineto score 0.296 0.102) (lineto score 0.170 0.000) (lineto score 0.298 -0.102) (lineto score 0.278 -0.124) (lineto score 0.150 -0.020) (lineto score 0.020 -0.124) (lineto score 0.004 -0.104) (lineto score 0.128 0.000) (if (not style) (fill-in score) (draw score style))) (defvar rhythmX-bounds '(0.000 -0.124 0.298 0.124)) (defun draw-circled-x (score &optional style) (let ((off .06) (size .75)) ;(comment score "circled-X") (moveto score (* size (+ off 0.020)) (* size 0.124)) (lineto score (* size (+ off 0.150)) (* size 0.020)) (lineto score (* size (+ off 0.278)) (* size 0.124)) (curveto score (* size (+ off 0.224)) (* size 0.190) (* size (+ off 0.085)) (* size 0.188) (* size (+ off 0.020)) (* size 0.124)) (moveto score (* size (+ off 0.296)) (* size 0.102)) (lineto score (* size (+ off 0.170)) (* size 0.000)) (lineto score (* size (+ off 0.297)) (* size -0.101)) (curveto score (* size (+ off 0.341)) (* size -0.056) (* size (+ off 0.339)) (* size 0.050) (* size (+ off 0.296)) (* size 0.102)) (moveto score (* size (+ off 0.278)) (* size -0.124)) (lineto score (* size (+ off 0.150)) (* size -0.020)) (lineto score (* size (+ off 0.020)) (* size -0.124)) (curveto score (* size (+ off 0.080)) (* size -0.189) (* size (+ off 0.221)) (* size -0.194) (* size (+ off 0.278)) (* size -0.124)) (moveto score (* size (+ off 0.004)) (* size -0.104)) (lineto score (* size (+ off 0.128)) (* size 0.000)) (lineto score (* size (+ off 0.003)) (* size 0.102)) (curveto score (* size (+ off -0.048)) (* size 0.055) (* size (+ off -0.044)) (* size -0.061) (* size (+ off 0.004)) (* size -0.104)) (moveto score (* size (+ off -0.065)) (* size 0.003)) (curveto score (* size (+ off -0.064)) (* size 0.264) (* size (+ off 0.360)) (* size 0.280) (* size (+ off 0.361)) (* size 0.000)) (curveto score (* size (+ off 0.361)) (* size -0.278) (* size (+ off -0.059)) (* size -0.279) (* size (+ off -0.064)) (* size 0.000)) (if (not style) (fill-in score) (draw score style)))) ;(defvar circled-x-bounds (list (* .75 (+ .06 -0.065)) (* .75 -0.207) (* .75 (+ .06 0.361)) (* .75 0.204))) (defvar circled-x-bounds '(-0.00375 -.015525 0.31575 0.153)) (defun draw-slash (score &optional style) ;(comment score "slash") (setf (line-width score) .1) (moveto score 0 -.15) (rlineto score .275 .275) (draw score style) (setf (line-width score) 0)) (defvar slash-bounds '(0.0 -.15 .275 .3)) (defun draw-mslash (score &optional style) ;(comment score "slash") (setf (line-width score) .05) (moveto score .05 -.225) (rlineto score .2 .45) (draw score style) (setf (line-width score) 0)) (defvar mslash-bounds '(0.0 -.2 .225 .4)) ;;; these versions of 'triangle and 'square makes sure that the start ;;; and end of the drawn line is on the middle of one of its sides, ;;; ensuring 'sharp corners (defun draw-triangle (score &optional style) ;(comment score "triangle") (setf (line-width score) .03) (moveto score .14 -.11) (rlineto score -.14 0) (rlineto score .14 .25) (rlineto score .14 -.25) (rlineto score -.14 .0) (if (not style) (fill-in score) (draw score style)) (setf (line-width score) 0)) (defvar triangle-bounds '(0.0 -.11 .30 .14)) (defun draw-square (score &optional style) ;(comment score "square") (setf (line-width score) .04) (moveto score .13 -.13) (rlineto score -.13 0) (rlineto score 0 .26) (rlineto score .26 0) (rlineto score 0 -.26) (rlineto score -.13 0) (if (not style) (fill-in score) (draw score style)) (setf (line-width score) 0)) (defvar square-bounds '(0 -.13 .28 .13)) (defun draw-8th-flag-up (score &optional style) ;stem up, flag hangs down (if (music-font score) (g-mustext score #o152 -.265 -0.45) (progn ;(comment score "8th flag up") (moveto score 0.000 0.296) (lineto score 0.019 0.296) (curveto score 0.022 0.239 0.031 0.146 0.101 0.092) (curveto score 0.246 -0.053 0.275 -0.121 0.268 -0.260) (curveto score 0.260 -0.411 0.213 -0.482 0.182 -0.540) (lineto score 0.175 -0.535) (curveto score 0.221 -0.453 0.247 -0.358 0.244 -0.257) (curveto score 0.243 -0.119 0.118 0.000 0.021 0.000) (lineto score 0.021 -0.024) (lineto score 0.000 -0.024) (lineto score 0.000 0.296) (if (not style) (fill-in score) (draw score style))))) (defvar up8th-bounds '(0.000 -0.543 0.282 0.296)) (defun draw-extend-flag-up (score &optional style) (if (music-font score) (g-mustext score #o373 -.265 0.2) (progn ;(comment score "extend flag up") (moveto score 0.000 0.296) (lineto score 0.021 0.296) (curveto score 0.025 0.196 0.065 0.158 0.122 0.094) (curveto score 0.213 -0.011 0.400 -0.160 0.264 -0.512) (lineto score 0.262 -0.494) (curveto score 0.319 -0.325 0.290 -0.185 0.240 -0.118) (curveto score 0.194 -0.051 0.065 0.076 0.026 0.033) (lineto score 0.026 -0.025) (lineto score 0.000 -0.025) (lineto score 0.000 0.296) (if (not style) (fill-in score) (draw score style))))) (defvar extend-flag-up-bounds '(0.000 -0.401 0.280 0.212)) (defun draw-8th-flag-down (score &optional style) ;invert by hand... (if (music-font score) (g-mustext score #o112 0 0.5) (progn ;(comment score "8th flag down") (moveto score 0.000 -0.296) (lineto score 0.019 -0.296) (curveto score 0.022 -0.239 0.031 -0.146 0.101 -0.092) (curveto score 0.246 0.053 0.275 0.121 0.268 0.260) (curveto score 0.260 0.411 0.213 0.482 0.182 0.540) (lineto score 0.175 0.535) (curveto score 0.221 0.453 0.247 0.358 0.244 0.257) (curveto score 0.243 0.119 0.118 0.000 0.021 0.000) (lineto score 0.021 0.024) (lineto score 0.000 0.024) (lineto score 0.000 -0.296) (if (not style) (fill-in score) (draw score style))))) (defvar down8th-bounds '(0.000 -0.296 0.280 0.542)) (defun draw-extend-flag-down (score &optional style) (if (music-font score) (g-mustext score #o360 0 -0.2) (progn ;(comment score "extend flag down") (moveto score 0.000 -0.296) (lineto score 0.021 -0.296) (curveto score 0.025 -0.196 0.065 -0.158 0.122 -0.094) (curveto score 0.213 0.011 0.400 0.160 0.264 0.512) (lineto score 0.262 0.494) (curveto score 0.319 0.325 0.290 0.185 0.240 0.118) (curveto score 0.194 0.051 0.065 -0.076 0.026 -0.033) (lineto score 0.026 0.025) (lineto score 0.000 0.025) (lineto score 0.000 -0.296) (if (not style) (fill-in score) (draw score style))))) (defvar extend-flag-down-bounds '(0.000 -0.214 0.280 0.382)) ;;; -------------------------------- RESTS -------------------------------- (defun draw-whole-rest (score &optional style) ;(comment score "whole rest") (moveto score 0.063 0.253) (lineto score 0.063 0.127) (lineto score 0.359 0.127) (lineto score 0.359 0.253) (lineto score 0.422 0.253) (lineto score 0.422 0.256) (lineto score 0.000 0.256) (lineto score 0.000 0.253) (lineto score 0.063 0.253) (if (not style) (fill-in score) (draw score style))) (defvar whole-rest-bounds '(0.000 0.000 0.420 0.256)) (defun draw-half-rest (score &optional style) ;(comment score "half rest") (moveto score 0.063 0.127) (lineto score 0.063 0.000) (lineto score 0.000 0.000) (lineto score 0.000 -0.003) (lineto score 0.422 -0.003) (lineto score 0.422 0.000) (lineto score 0.359 0.000) (lineto score 0.359 0.127) (lineto score 0.063 0.127) (if (not style) (fill-in score) (draw score style))) (defvar half-rest-bounds '(0.000 -0.003 0.420 0.126)) (defun draw-quarter-rest (score &optional style) (if (music-font score) (g-mustext score #o316 0 0.0) (progn ;(comment score "quarter rest") (moveto score 0.072 0.358) (curveto score 0.120 0.253 0.160 0.158 0.038 0.058) (lineto score 0.182 -0.103) (curveto score -0.028 -0.032 -0.058 -0.248 0.180 -0.343) (lineto score 0.187 -0.322) (curveto score 0.042 -0.222 0.150 -0.103 0.230 -0.142) (lineto score 0.243 -0.127) (curveto score 0.220 -0.082 0.170 -0.043 0.157 0.012) (curveto score 0.165 0.120 0.290 0.113 0.237 0.187) (lineto score 0.103 0.355) (lineto score 0.072 0.358) (if (not style) (fill-in score) (draw score style))))) (defvar quarter-rest-bounds '(0.000 -0.343 0.248 0.358)) (defun draw-8th-rest (score &optional style) (if (music-font score) (g-mustext score #o344 0 0.125) (progn ;(comment score "8th rest") (moveto score 0.164 0.131) (curveto score 0.171 0.222 0.046 0.236 0.028 0.136) (curveto score 0.032 0.030 0.159 0.033 0.224 0.086) (lineto score 0.140 -0.256) (lineto score 0.174 -0.256) (lineto score 0.286 0.200) (lineto score 0.259 0.200) (curveto score 0.249 0.140 0.188 0.074 0.142 0.079) (curveto score 0.154 0.096 0.166 0.114 0.164 0.131) (if (not style) (fill-in score) (draw score style))))) (defvar rest8-bounds '(0.000 -0.256 0.286 0.202)) (defun draw-16th-rest (score &optional style) (if (music-font score) (g-mustext score #o305 0 0.125) (progn ;(comment score "16th rest") (moveto score 0.102 -0.170) (curveto score 0.128 -0.152 0.141 -0.128 0.136 -0.113) (curveto score 0.144 -0.032 0.017 -0.020 0.000 -0.113) (curveto score 0.000 -0.224 0.146 -0.224 0.208 -0.163) (lineto score 0.118 -0.503) (lineto score 0.150 -0.503) (lineto score 0.334 0.200) (lineto score 0.302 0.200) (curveto score 0.292 0.141 0.221 0.065 0.168 0.077) (curveto score 0.167 0.079 0.162 0.081 0.164 0.082) (curveto score 0.186 0.096 0.196 0.119 0.194 0.136) (curveto score 0.197 0.221 0.070 0.234 0.056 0.136) (curveto score 0.058 0.029 0.205 0.018 0.276 0.100) (lineto score 0.232 -0.068) (curveto score 0.221 -0.126 0.165 -0.181 0.106 -0.171) (if (not style) (fill-in score) (draw score style))))) (defvar rest16-bounds '(0.000 -0.508 0.334 0.202)) (defun draw-32nd-rest (score &optional style) (if (music-font score) (g-mustext score #o250 0 -0.125) (progn ;(comment score "32nd rest") (moveto score 0.164 0.077) (curveto score 0.182 0.099 0.194 0.114 0.199 0.136) (curveto score 0.201 0.228 0.070 0.241 0.058 0.136) (curveto score 0.064 0.034 0.211 0.028 0.270 0.083) (lineto score 0.228 -0.076) (curveto score 0.219 -0.126 0.165 -0.174 0.107 -0.168) (curveto score 0.102 -0.170 0.109 -0.168 0.104 -0.168) (curveto score 0.124 -0.151 0.136 -0.133 0.136 -0.115) (curveto score 0.142 -0.031 0.007 -0.019 0.000 -0.115) (curveto score 0.003 -0.216 0.146 -0.216 0.206 -0.170) (lineto score 0.128 -0.510) (lineto score 0.172 -0.510) (lineto score 0.400 0.453) (lineto score 0.364 0.453) (curveto score 0.354 0.393 0.295 0.329 0.229 0.334) (curveto score 0.260 0.372 0.253 0.354 0.260 0.388) (curveto score 0.268 0.470 0.129 0.486 0.117 0.388) (curveto score 0.125 0.285 0.261 0.281 0.330 0.333) (lineto score 0.294 0.196) (curveto score 0.282 0.133 0.235 0.077 0.160 0.077) (if (not style) (fill-in score) (draw score style))))) (defvar rest32-bounds '(0.000 -0.510 0.400 0.456)) (defun draw-64th-rest (score &optional style) (if (music-font score) (g-mustext score #o364 0 -0.125) (progn ;(comment score "64th rest") (moveto score 0.161 0.081) (curveto score 0.188 0.096 0.196 0.117 0.194 0.136) (curveto score 0.205 0.210 0.076 0.231 0.058 0.136) (curveto score 0.054 0.029 0.214 0.019 0.270 0.087) (lineto score 0.228 -0.076) (curveto score 0.216 -0.124 0.163 -0.184 0.102 -0.170) (curveto score 0.129 -0.151 0.138 -0.134 0.136 -0.115) (curveto score 0.147 -0.039 0.018 -0.013 0.000 -0.115) (curveto score 0.000 -0.220 0.151 -0.228 0.206 -0.170) (lineto score 0.122 -0.510) (lineto score 0.164 -0.510) (lineto score 0.454 0.708) (lineto score 0.419 0.708) (curveto score 0.409 0.644 0.341 0.566 0.281 0.588) (curveto score 0.306 0.610 0.314 0.630 0.314 0.642) (curveto score 0.325 0.721 0.189 0.734 0.176 0.642) (curveto score 0.179 0.536 0.333 0.532 0.386 0.590) (lineto score 0.347 0.434) (curveto score 0.341 0.384 0.284 0.325 0.225 0.334) (curveto score 0.246 0.350 0.254 0.370 0.254 0.388) (curveto score 0.261 0.466 0.134 0.486 0.117 0.388) (curveto score 0.119 0.284 0.266 0.279 0.328 0.338) (lineto score 0.296 0.207) (curveto score 0.285 0.154 0.235 0.063 0.164 0.080) (if (not style) (fill-in score) (draw score style))))) (defvar rest64-bounds '(0.000 -0.510 0.454 0.708)) (defun draw-128th-rest (score &optional style) (if (music-font score) (g-mustext score #o345 0 -0.125) (progn ;(comment score "128th rest") (moveto score 0.277 0.586) (curveto score 0.306 0.604 0.314 0.623 0.314 0.641) (curveto score 0.320 0.727 0.189 0.733 0.176 0.641) (curveto score 0.181 0.536 0.343 0.526 0.386 0.589) (lineto score 0.350 0.434) (curveto score 0.341 0.400 0.309 0.323 0.226 0.333) (curveto score 0.246 0.350 0.254 0.369 0.254 0.389) (curveto score 0.267 0.469 0.134 0.480 0.119 0.389) (curveto score 0.111 0.286 0.284 0.274 0.326 0.336) (lineto score 0.296 0.209) (curveto score 0.286 0.179 0.253 0.067 0.164 0.079) (curveto score 0.189 0.096 0.194 0.114 0.194 0.136) (curveto score 0.200 0.223 0.073 0.226 0.059 0.136) (curveto score 0.059 0.023 0.221 0.027 0.269 0.079) (lineto score 0.229 -0.076) (curveto score 0.214 -0.117 0.180 -0.183 0.106 -0.170) (curveto score 0.129 -0.153 0.136 -0.133 0.136 -0.116) (curveto score 0.147 -0.033 0.004 -0.020 0.000 -0.116) (curveto score 0.004 -0.229 0.160 -0.224 0.204 -0.176) (lineto score 0.121 -0.510) (lineto score 0.164 -0.510) (lineto score 0.514 0.954) (lineto score 0.481 0.954) (curveto score 0.467 0.903 0.436 0.820 0.340 0.836) (curveto score 0.367 0.849 0.377 0.874 0.371 0.890) (curveto score 0.383 0.967 0.250 0.993 0.236 0.890) (curveto score 0.240 0.787 0.406 0.776 0.446 0.830) (lineto score 0.416 0.704) (curveto score 0.406 0.684 0.370 0.576 0.279 0.583) (if (not style) (fill-in score) (draw score style))))) (defvar rest128-bounds '(0.000 -0.510 0.514 0.956)) (defun draw-measure-rest (score &optional style) ;(comment score "measure rest") (moveto score 0 .25) (rlineto score 0 -.5) (moveto score .5 .25) (rlineto score 0 -.5) (draw score style) (setf (line-width score) .225) (moveto score 0 0) (lineto score .5 0) (draw score style) (setf (line-width score) 0)) (defvar measure-rest-bounds '(0 -.25 .5 .25)) (defun draw-double-whole-rest (score &optional style) ;(comment score "double whole rest") (moveto score 0 .5) (rlineto score 0 .25) (rlineto score .15 0) (rlineto score 0 -.25) (rlineto score -.15 0) (if (not style) (fill-in score) (draw score style))) (defvar double-whole-rest-bounds '(0 0 .5 .75)) snd-16.1/dsp.fs0000644000076400007640000024440012327441227011463 0ustar bilbil\ dsp.fs -- dsp.scm|rb --> dsp.fs \ Author: Michael Scholz \ Created: 05/12/30 04:52:13 \ Changed: 14/04/28 03:52:17 \ \ @(#)dsp.fs 1.51 4/28/14 \ src-duration ( en -- dur ) \ src-fit-envelope ( e1 target-dur -- e2 ) \ dolph ( n gamma -- im ) \ dolph-1 (n gamma -- im ) \ down-oct ( n :optional snd chn -- vct ) \ stretch-sound-via-dft ( factor :optional snd chn -- ) \ compute-uniform-circular-string ( size x0 x1 x2 mass xspring damp -- ) \ compute-string ( size x0 x1 x2 ms xs esprs damps haptics -- ) \ freqdiv ( n :optional snd chn -- ) \ adsat ( size :optional beg dur snd chn -- res ) \ spike ( :optional snd chn -- res ) \ spot-freq ( samp :optional snd chn -- ) \ chorus ( -- proc; inval self -- val ) \ chordalize ( -- proc; x self -- val ) \ zero-phase ( :optional snd chn -- vct ) \ rotate-phase ( func :optional snd chn -- vct) \ make-asyfm ( :key freq initial-phase ratio r index -- gen ) \ asyfm-J ( gen input -- val ) \ asyfm-I ( gen input -- val ) \ make-cosine-summation ( :key frequency initial-phase -- gen ) \ cosine-summation ( gen r -- val ) \ make-kosine-summation ( :key frequency initial-phase -- gen ) \ kosine-summation ( gen r k -- val ) \ fejer-sum ( angle n -- val ) \ legendre-sum ( angle n -- val ) \ sum-of-n-sines ( angle n -- val ) \ sum-of-n-odd-sines ( angle n -- val ) \ sum-of-n-odd-cosines ( angle n -- val ) \ band-limited-sawtooth ( x a N fi -- val ) \ band-limited-square-wave ( theta n -- val ) \ brighten-slightly ( amount :optional snd chn -- ) \ brighten-slightly-1 ( coeffs :optional snd chn -- ) \ spectrum->coeffs ( order spectr -- vct ) \ fltit-1 ( order spectr -- proc; y self -- val ) \ \ make-hilbert-transform ( :optional len -- gen ) \ make-highpass ( fc :optional len -- gen ) \ make-lowpass ( fc :optional len -- gen ) \ make-bandpass ( flo fhi :optional len -- gen ) \ make-bandstop ( flo fhi :optional len -- gen ) \ make-differentiator ( :optional len -- gen ) \ make-butter-high-pass ( freq -- flt ) \ make-butter-low-pass ( freq -- flt ) \ make-butter-band-pass ( freq band -- flt ) \ make-butter-band-reject ( freq band -- flt ) \ make-biquad ( a0 a1 a2 b1 b2 -- gen ) \ make-iir-low-pass-2 ( fc :optional d -- gen ) \ make-iir-high-pass-2 ( fc :optional d -- gen ) \ make-iir-band-pass-2 ( f1 f2 -- gen ) \ make-iir-band-stop-2 ( f1 f2 -- gen ) \ make-eliminate-hum ( :optional hum-frq hum-harm bw -- ) \ \ make-peaking-2 ( f1 f2 m -- prc; y self -- val ) \ cascade->canonical ( A -- A' ) \ make-butter-lp ( M fc -- flt ) \ make-butter-hp ( M fc -- flt ) \ make-butter-bp ( M f1 f2 -- flt ) \ make-butter-bs ( M f1 f2 -- flt ) \ \ make-notch-frequency-response ( cur-sr freqs :optional notchw -- fresp ) \ notch-channel ( freqs :optional ... ) \ notch-sound ( freqs :optional filtero snd chn notchw -- f ) \ notch-selection ( freqs :optional filtero notchw -- f ) \ fractional-fourier-transform ( real imaginary n angle -- hr hi ) \ z-transform ( data n z -- ) \ dht ( data -- vct ) \ find-sine ( freq beg dur -- amp ph ) \ goertzel ( freq :optional beg dur -- amp ) \ \ make-spencer-filter ( -- gen ) \ any-random ( amount :optional en -- r ) \ gaussian-distribution ( s -- en ) \ pareto-distribution ( a -- en ) \ inverse-integrate ( dist :optional data-size e-size -- vct ) \ gaussian-envelope ( s -- en ) \ \ channel-mean ( :optional snd chn -- val ) \ channel-total-energy ( :optional snd chn -- val ) \ channel-average-power ( :optional snd chn -- val ) \ channel-rms ( :optional snd chn -- val ) \ channel-variance ( :optional snd chn -- val ) \ channel-norm ( :optional snd chn -- val ) \ channel-lp ( p :optional snd chn -- val ) \ channel-lp-inf ( :optional snd chn -- val ) \ channel2-inner-product ( s1 c1 s2 c2 -- val ) \ channel2-angle ( s1 c1 s2 c2 -- val ) \ channel2-orthogonal? ( s1 c1 s2 c2 -- f ) \ channel2-coefficient-of-projection ( s1 c1 s2 c2 -- val ) \ channel-distance ( s1 c1 s2 c2 -- val ) \ periodogram ( N -- ) \ \ shift-channel-pitch ( frq :optional ord beg dur snd chn ep -- val ) \ ssb-bank ( ofreq nfreq pairs :optional ... ) \ ssb-bank-env ( ofreq nfreq freq-env pairs :optional ... ) \ make-transposer ( ofreq nfreq pairs :optional ord bw -- gen ) \ transpose ( gen input -- val ) \ make-fdelay ( len pitch scaler -- prc; y self -- val ) \ fdelay ( gen input -- val ) \ transposed-echo ( pitch scaler secs -- val ) \ \ vct-polynomial ( v coeffs -- vct ) \ channel-polynomial ( coeffs :optional snd chn -- vct ) \ spectral-polynomial ( coeffs :optional snd chn -- vct ) \ \ scentroid ( file :key beg dur db-floor rf ffts -- vals ) \ invert-filter ( fcoeffs -- res ) \ make-volterra-filter ( acoeffs bcoeffs -- gen ) \ volterra-filter ( flt y -- val ) \ \ make-moving-max ( :optional size -- gen ) \ moving-max ( gen y -- scl ) \ make-moving-sum ( :optional size -- gen ) \ moving-sum ( gen y -- val ) \ make-moving-rms ( :optional size -- gen ) \ moving-rms ( gen y -- val ) \ make-moving-length ( :optional size -- gen ) \ moving-length ( gen y -- val ) \ make-smoothing-filter ( size -- gen ) \ smoothing-filter ( gen sig -- r ) \ make-exponentially-weighted-moving-average ( order -- r ) \ make-weighted-moving-average ( order -- r ) \ weighted-moving-average ( gen sig -- r ) \ harmonicizer ( freq coeffs pairs :optional ... ) \ linear-src-channel ( sr :optional snd chn -- file ) \ display-bark-fft ( :optional off -- ) \ undisplay-bark-fft ( -- ) \ lpc-coeffs ( data n m -- val ) \ lpc-predict ( data n coeffs m nf :optional clipped -- val ) \ unclip-channel ( :optional snd chn -- assoc ) \ unclip-sound ( :optional snd -- assoc ) require clm require env require examp \ ;;; -------- src-duration (see src-channel in extsnd.html) : src-duration ( en -- dur ) doc" Return new duration of a sound after using ENVELOPE \ for time-varying sampling-rate conversion." { en } en 0 object-ref { ex0 } en -2 object-ref { ex1 } ex1 ex0 f- { all-x } 0.0 ( dur ) en object-length 3 - 0 ?do en i object-ref { x0 } en i 1 + object-ref { xy0 } en i 2 + object-ref { x1 } en i 3 + object-ref { xy1 } xy0 f0= if 1.0 else xy0 1/f then { y0 } xy1 f0= if 1.0 else xy1 1/f then { y1 } xy0 xy1 f- fabs 0.0001 f< if x1 x0 f- all-x f/ y0 f* else y1 flog y0 flog f- xy0 xy1 f- f/ x1 x0 f- all-x f/ f* then ( area ) fabs ( dur ) f+ 2 +loop ( dur ) ; : src-fit-envelope { e1 target-dur -- e2 } e1 e1 src-duration target-dur f/ scale-envelope ; 'complex provided? [if] \ ;;; -------- Dolph-Chebyshev window \ ;;; \ ;;; formula taken from Richard Lyons, "Understanding DSP" \ ;;; see clm.c for C version (using either GSL's or GCC's complex \ ;;; trig functions) : dolph ( n gamma -- im ) doc" Produce Dolph-Chebyshev FFT data window \ of N points using GAMMA as the window parameter." { n gamma } 10.0 gamma f** cacosh n c/ ccosh { alpha } alpha cacosh n c* ccosh 1/c { den } n 0.0 make-vct { rl } n 0.0 make-vct { im } pi n f/ { freq } 0.0 { phase } n 0 ?do phase ccos alpha c* cacos n c* ccos den c* { val } rl i val real-ref vct-set! drop im i val imag-ref vct-set! drop phase freq f+ to phase loop rl im -1 fft ( rl ) dup vct-peak 1/f vct-scale! ( rl ) n 2/ cycle-start! n 0 ?do im i rl cycle-ref vct-set! drop loop im ; \ ;;; this version taken from Julius Smith's "Spectral Audio..." with \ ;;; three changes it does the DFT by hand, and is independent of \ ;;; anything from Snd (fft, vcts etc) : dolph-1 ( n gamma -- im ) { n gamma } 10.0 gamma f** cacosh n c/ ccosh { alpha } alpha cacosh n c* ccosh 1/c { den } pi n f/ { freq } half-pi fnegate { phase } -1.0 { mult } n make-array map! phase ccos alpha c* cacos n c* ccos den c* mult c* ( x ) mult fnegate to mult phase freq f+ to phase ( x ) end-map { vals } \ now take the DFT 0.0 { pk } n make-array map! 0.0 ( sum ) vals each ( val ) 0+1.0i two-pi c* j c* i c* n c/ cexp c* c+ ( sum++ ) end-each cabs { sum } sum pk f> if sum to pk then sum end-map ( w ) map! *key* pk f/ end-map ( w ) ; [then] \ ;;; ------- move sound down by n (a power of 2) --- : down-oct <{ n :optional snd #f chn #f -- vct }> doc" Move sound down by power of 2 n." snd chn #f framples { len } 2.0 len flog 2.0 flog f/ fceil ( pow2 ) f** f>s { fftlen } fftlen 1/f { fftscale } 0 fftlen snd chn #f channel->vct { rl1 } fftlen 0.0 make-vct { im1 } rl1 im1 1 fft ( rl1 ) fftscale vct-scale! drop im1 fftscale vct-scale! drop fftlen n * 0.0 make-vct { rl2 } fftlen n * 0.0 make-vct { im2 } fftlen 1- { kdx } fftlen n * 1- { jdx } fftlen 2/ 0 ?do rl2 i rl1 i vct-ref vct-set! drop rl2 jdx rl1 kdx vct-ref vct-set! drop im2 i im1 i vct-ref vct-set! drop im2 jdx im1 kdx vct-ref vct-set! drop jdx 1- to jdx kdx 1- to kdx loop rl2 im2 -1 fft ( rl2 ) 0 n len * snd chn #f "%s %s" #( n get-func-name ) string-format vct->channel ; 'complex provided? [if] : stretch-sound-via-dft <{ factor :optional snd #f chn #f -- }> doc" Make given channel longer (FACTOR should be > 1.0) \ by squeezing in the frequency domain, then using the inverse DFT \ to get the time domain result." snd chn #f framples { n } n f2/ floor f>s { n2 } n factor f* fround->s { out-n } 0 n snd chn #f channel->vct { in-data } out-n :initial-element 0.0 make-array { fr } two-pi n f/ { freq } n 0 ?do i n2 < if fr i freq 0.0-1.0i c* i c* else fr out-n n - 1- i + freq 0.0-1.0i c* i c* then in-data edot-product array-set! loop two-pi out-n f/ { freq } out-n 0.0 make-vct map! freq 0.0+1.0i c* i c* fr edot-product n c/ real-ref end-map ( out-data ) 0 out-n snd chn #f "%s %s" #( factor get-func-name ) string-format vct->channel drop ; [then] \ ;;; -------- compute-uniform-circular-string \ ;;; \ ;;; this is a simplification of the underlying table-filling routine \ ;;; for "scanned synthesis". To watch the wave, open some sound (so \ ;;; Snd has some place to put the graph), turn off the time domain display \ ;;; (to give our graph all the window -- to do this in a much more elegant \ ;;; manner, see snd-motif.scm under scanned-synthesis). : compute-uniform-circular-string ( size x0 x1 x2 mass xspring damp -- ) { size x0 x1 x2 mass xspring damp } damp mass f/ { dm } xspring mass f/ { km } 1.0 dm f+ { denom } dm km f2* f- 2.0 f+ denom f/ { p1 } km denom f/ { p2 } -1.0 denom f/ { p3 } x0 map! x1 i vct-ref p1 f* x1 i 1- object-ref x1 i 1+ size = if 0 else i 1+ then object-ref f+ p2 f* f+ x2 i vct-ref p3 f* f+ end-map to x0 x2 0.0 vct-fill! drop x2 x1 vct-add! drop x1 0.0 vct-fill! drop x1 x2 vct-add! drop ; : compute-string ( size x0 x1 x2 masses xsprings esprings damps haptics -- ) { size x0 x1 x2 masses xsprings esprings damps haptics } x0 map! damps i vct-ref masses i vct-ref f/ { dm } xsprings i vct-ref masses i vct-ref f/ { km } esprings i vct-ref masses i vct-ref f/ { cm } 1.0 dm cm f+ f+ { denom } dm km f2* f- 2.0 f+ denom f/ { p1 } km denom f/ { p2 } -1.0 denom f/ { p3 } haptics i vct-ref masses i vct-ref denom f* f/ { p4 } x1 i vct-ref p1 f* x1 i 1- object-ref x1 i 1+ size = if 0 else i 1+ then vct-ref f+ p2 f* f+ x2 i vct-ref p3 f* f+ p4 f+ end-map to x0 size 0 ?do x2 i x1 i vct-ref vct-set! drop x1 i x0 i vct-ref vct-set! drop loop ; \ ;;; -------- "frequency division" -- an effect from sed_sed@my-dejanews.com hide : freqdiv-cb { div n curval -- prc; y self -- val } 1 proc-create ( prc ) div , n , curval , does> ( y self -- val ) { y self } self @ { div } self cell+ @ { n } div 0= if y self 2 cells + ! ( curval ) then 1 self +! ( div++ ) div n = if 0 self ! then self 2 cells + @ ( curval ) ; set-current : freqdiv <{ n :optional snd #f chn #f -- val }> doc" Repeat each nth sample N times (clobbering the \ intermediate samples): 8 freqdiv." 0 n 0.0 freqdiv-cb 0 #f snd chn #f "%s %s" #( n get-func-name ) string-format map-channel ; previous \ ;;; -------- "adaptive saturation" -- an effect from sed_sed@my-dejanews.com hide : adsat-cb { mn mx n vals -- prc; inval self -- res } 1 proc-create ( prc ) vals , n , mx , mn , does> ( inval self -- res ) { inval self } self @ { vals } self 1 cells + @ { n } self 2 cells + @ { mx } self 3 cells + @ { mn } vals length n = if vals each { x } vals i x f0>= if mx else mn then vct-set! drop end-each 0 self 1 cells + ! ( n ) 0.0 self 2 cells + ! ( mx ) 0.0 self 3 cells + ! ( mn ) vals else vals n inval vct-set! drop 1 self 1 cells + +! ( n++ ) inval mx fmax self 2 cells + ! ( mx ) inval mn fmin self 3 cells + ! ( mn ) #f then ; set-current : adsat <{ size :optional beg 0 dur #f snd #f chn #f -- val }> doc" An 'adaptive saturation' sound effect." 0.0 0.0 0 size 0.0 make-vct adsat-cb beg dur snd chn #f "%s %s %s %s" #( size beg dur get-func-name ) string-format map-channel ; previous \ ;;; -------- spike --- \ ;;; \ ;;; makes sound more spikey -- sometimes a nice effect hide : spike-cb ( snd chn -- prc; x0 self -- res ) { snd chn } snd chn #f maxamp { amp } 1 proc-create ( prc ) 0.0 ( x1 ) , 0.0 ( x2 ) , amp , does> ( x0 self -- res ) { x0 self } self @ { x1 } self 1 cells + @ { x2 } self 2 cells + @ { amp } x0 amp amp f* f/ x2 fabs f* x1 fabs f* { res } x1 self cell+ ! ( x2 ) x0 self ! ( x1 ) res ; set-current : spike <{ :optional snd #f chn #f -- val }> doc" Multiply successive samples together to make a sound more spikey." snd chn spike-cb 0 #f snd chn #f get-func-name map-channel ; previous \ ;;; -------- easily-fooled autocorrelation-based pitch tracker : spot-freq <{ samp :optional snd #f chn #f -- }> doc" Try to determine the current pitch: left-sample spot-freq." snd srate s>f { sr } 2.0 sr 20.0 f/ flog 2.0 flog f/ fceil f** fround->s { fftlen } samp fftlen snd chn #f channel->vct autocorrelate { data } data vct-peak { cor-peak } cor-peak f2* { cor-peak2 } 0.0 ( ret ) fftlen 2 - 1 ?do data i vct-ref data i 1 + vct-ref f< data i 1 + vct-ref data i 2 + vct-ref f> && if drop ( old ret ) data i vct-ref cor-peak f+ cor-peak2 f/ flog10 { logla } data i 1 + vct-ref cor-peak f+ cor-peak2 f/ flog10 { logca } data i 2 + vct-ref cor-peak f+ cor-peak2 f/ flog10 { logra } logla logra f- f2/ logla logra f+ logca -2.0 f* f+ f/ { offset } sr offset i f+ 1.0 f+ f2* f/ ( new ret ) leave then loop ; 0 [if] \ Left sample: graph-hook lambda: <{ snd chn y0 y1 -- f }> "freq: %.3f" #( snd chn LEFT-SAMPLE snd chn spot-freq ) string-format snd status-report drop #f ; add-hook! \ At cursor position: mouse-click-hook lambda: <{ snd chn button state x y axis -- }> axis time-graph = if "freq: %.3f" #( snd chn #f CURSOR snd chn spot-freq ) string-format snd status-report else #f then ; add-hook! [then] \ ;;; -------- chorus (doesn't always work and needs speedup) 5 value chorus-size 0.05 value chorus-time 20.0 value chorus-amount 10.0 value chorus-speed hide : make-flanger ( -- ri gen ) :frequency chorus-speed :amplitude chorus-amount make-rand-interp { ri } chorus-time 3.0 f* #f srate f* random floor f>s { len } len :max-size len chorus-amount f>s + 1+ make-delay { gen } #( gen ri ) ; : flanger ( dly inval -- val ) { dly inval } dly 0 array-ref inval dly 1 array-ref 0.0 rand-interp delay inval f+ ; set-current : chorus ( -- prc; inval self -- val ) doc" Try to produce the chorus sound effect." chorus-size make-array map! make-flanger end-map { dlys } 1 proc-create ( prc ) dlys , does> { inval self -- val } self @ { dlys } 0.0 ( sum ) dlys each ( dly ) inval flanger f+ ( sum++ ) end-each ; previous \ ;;; -------- chordalize (comb filters to make a chord using \ ;;; chordalize-amount and chordalize-base) 0.95 value chordalize-amount 100 value chordalize-base 'ratio provided? [if] #( 1 3/4 5/4 ) [else] <'> f* alias q* <'> f>s alias q>s #( 1 3 4 f/ 5 4 f/ ) [then] value chordalize-chord : chordalize ( -- prc; x self -- val ) doc" Use harmonically-related comb-filters to bring \ out a chord in a sound. \ Global variable CHORDALIZE-CHORD is an array of members \ of chord such as #( 1 5/4 3/2 )." chordalize-chord map :scaler chordalize-amount :size chordalize-base *key* q* q>s make-comb end-map { combs } chordalize-chord length 0.5 f/ { scaler } 1 proc-create ( prc ) combs , scaler , does> { x self -- val } self @ { combs } self cell+ @ { scaler } 0.0 ( val ) combs each ( gen ) x 0.0 comb f+ ( val += ... ) end-each scaler f* ; \ ;;; -------- zero-phase, rotate-phase \ ;;; fft games (from the "phazor" package of Scott McNab) : zero-phase <{ :optional snd #f chn #f -- vct }> doc" Call fft, set all phases to 0, and un-fft." snd chn #f framples { len } 2.0 len flog 2.0 flog f/ fceil ( pow2 ) f** fround->s { fftlen } fftlen 1/f { fftscale } 0 fftlen snd chn #f channel->vct { rl } rl vct-peak { old-pk } fftlen 0.0 make-vct { im } rl im 1 fft ( rl ) im rectangular->polar drop rl fftscale vct-scale! drop im 0.0 vct-scale! drop rl im -1 fft ( rl ) vct-peak { pk } rl old-pk pk f/ vct-scale! 0 len snd chn #f get-func-name vct->channel ; : rotate-phase <{ func :optional snd #f chn #f -- vct }> doc" Call fft, apply FUNC, a proc or xt, to each phase, then un-fft." func word? func 1 "a proc or xt" assert-type snd chn #f framples { len } 2.0 len flog 2.0 flog f/ fceil ( pow2 ) f** fround->s { fftlen } fftlen 2/ { fftlen2 } fftlen 1/f { fftscale } 0 fftlen snd chn #f channel->vct { rl } rl vct-peak { old-pk } fftlen 0.0 make-vct { im } \ fft returns result in rl rl im 1 fft ( rl ) im rectangular->polar drop rl fftscale vct-scale! drop im 0 0.0 vct-set! drop func xt? if func 1 make-proc to func then fftlen2 1 ?do im i func #( im i object-ref ) run-proc object-set! \ handles negative index im i negate im i negate object-ref fnegate object-set! loop rl im -1 fft ( rl ) vct-peak { pk } func proc-name { pn } pn length 0= if "noname" to pn then "<'> %s %s" #( pn get-func-name ) string-format { origin } rl old-pk pk f/ vct-scale! 0 len snd chn #f origin vct->channel ; \ XXX: origin in rotate-phase [ms] \ If FUNC isn't a proc or xt with a name (eg: 'lambda:' has no name), \ the origin will not be useful. \ \ The next two lines will deliver a useful origin: \ : rot-zero-ph ( y -- 0.0 ) drop 0.0 ; \ <'> rot-zero-ph rotate-phase \ \ while this won't: \ lambda: { y -- 0.0 } 0.0 ; rotate-phase \ \ Here are the examples from dsp.scm: \ lambda: { y -- r } 0.0 ; rotate-phase \ is the same as zero-phase \ lambda: { y -- r } pi random ; rotate-phase \ randomizes phases \ lambda: { y -- r } y ; rotate-phase \ returns original \ lambda: { y -- r } y fnegate ; rotate-phase \ reverses original \ lambda: { y -- r } y f2* ; rotate-phase \ reverb-effect (best with voice) \ lambda: { y -- r } y 12.0 f* ; rotate-phase \ "bruise blood" effect \ ;;; -------- asymmetric FM (bes-i0 case) #( "asyfm-freq" "asyfm-phase" "asyfm-ratio" "asyfm-r" "asyfm-index" ) create-struct make-asymmetric-struct : make-asyfm <{ :key frequency *clm-default-frequency* initial-phase 0.0 ratio 1.0 r 1.0 index 1.0 -- gen }> make-asymmetric-struct { gen } gen frequency hz->radians asyfm-freq! gen initial-phase asyfm-phase! gen ratio asyfm-ratio! gen r asyfm-r! gen index asyfm-index! gen ; : asyfm-J ( gen input -- val ) doc" ;; This is the same as the CLM asymmetric-fm generator, \ set r != 1.0 to get the asymmetric spectra.\n\ :frequency 2000 :ratio 0.1 make-asyfm value gen\n\ lambda: <{ n -- r }> gen 0.0 asyfm-J ; map-channel." { gen input } gen asyfm-phase@ { phase } gen asyfm-ratio@ { ratio } gen asyfm-r@ { r } gen asyfm-index@ { index } r 1/f { r1 } ratio phase f* { modphase } r f0< r -1.0 f> && r 1.0 f> || if -1.0 else 1.0 then { one } modphase fcos one f+ r r1 f- f* index f* 0.5 f* fexp modphase fsin r r1 f+ f* index f* 0.5 f* phase f+ fcos f* ( val ) gen phase input f+ gen asyfm-freq@ f+ asyfm-phase! ( val ) ; \ Example from old dsp.scm (now in clm23.scm): \ :frequency 2000 :ratio 0.1 make-asyfm value gen \ lambda: <{ n -- r }> gen 0.0 asyfm-J ; map-channel \ \ Examples from generators.scm: 0 [if] lambda: ( -- ) :frequency 2000 :ratio 0.1 make-asyfm { gen } 10000 0 do i gen 0.0 asyfm-J f2/ *output* outa drop loop ; :clipped #f :statistics #t :play #t with-sound lambda: ( -- ) :frequency 2000 :ratio 0.1 :index 1 make-asyfm { gen } '( 0 -4 1 -1 ) :length 20000 make-env { r-env } 20000 0 do gen r-env env asyfm-r! i gen 0.0 asyfm-J *output* outa drop loop ; :clipped #f :statistics #t :play #t with-sound [then] : asyfm-I { gen input -- val } gen asyfm-phase@ { phase } gen asyfm-ratio@ { ratio } gen asyfm-r@ { r } gen asyfm-index@ { index } r 1/f { r1 } ratio phase f* { modphase } modphase fcos r r1 f+ f* index f* 0.5 f* r r1 f+ index f* bes-i0 flog 0.5 f* f- fexp modphase fsin r r1 f- f* index f* 0.5 f* phase f+ fsin f* ( val ) gen phase input f+ gen asyfm-freq@ f+ asyfm-phase! ( val ) ; \ ;;; -------- cosine-summation (a simpler version of sine-summation) \ ;;; \ ;;; from Andrews, Askey, Roy "Special Functions" 5.1.16 : cosine-summation ( gen r -- val ) doc" A variant of the CLM sine-summation generator; \ R controls successive sinusoid amplitudes." { gen r } 1.0 r r f* f- 1.0 r r f* f+ r f2* gen 0.0 0.0 oscil f* f- f/ 1.0 f- 1.0 r r f* f- 1.0 r r f* f+ r f2* f* f/ f* ; <'> make-oscil alias make-cosine-summation \ 100.0 make-cosine-summation value gen \ lambda: <{ y }> gen 0.5 cosine-summation 0.2 f* ; map-channel \ ;;; -------- kosine-summation \ ;;; \ ;;; from Askey "Ramanujan and Hypergeometric Series" in Berndt and \ ;;; Rankin "Ramanujan: Essays and Surveys" \ ;;; \ ;;; this gives a sum of cosines of decreasing amp where the "k" parameter \ ;;; determines the "index" (in FM nomenclature) -- higher k = more cosines; \ ;;; the actual amount of the nth cos involves hypergeometric series \ ;;; (looks like r^n/n! (~=e^n?) with a million other terms). : kosine-summation ( gen r k -- val ) doc" It's a variant of sum-of-cosines; \ R controls successive sinusoid amplitude; \ K controls how many sinusoids are produced." { gen r k } 1.0 r r f* f+ r f2* gen 0.0 0.0 oscil f* f- k fnegate f** 1.0 r r f* f+ r f2* f- k f** f* ; <'> make-oscil alias make-kosine-summation \ 100.0 make-kosine-summation value gen \ lambda: <{ y }> gen 0.5 5.0 kosine-summation 0.2 f* ; map-channel \ ;;; -------- legendre, fejer : fejer-sum ( angle n -- val ) doc" Produce band-limited pulse train." \ ;; from "Trigonometric Series" Zygmund p88 { angle n } angle f0= if 1.0 else n 1.0 f+ angle f* f2/ fsin angle f2/ fsin f2* f/ ( val ) dup f* n 1.0 f+ f/ f2* then ; \ 0.0 value angle \ lambda: <{ y -- val }> \ angle 3.0 fejer-sum 0.1 f* ( val ) \ angle 0.1 f+ to angle \ ; map-channel : legendre-sum ( angle n -- val ) doc" Produce band-limited pulse train." \ ;; from Andrews, Askey, Roy "Special Functions" p 314 { angle n } angle f0= if 1.0 else n 0.5 f+ angle f* fsin angle f2/ fsin f/ dup f* then ; \ 0.0 value angle \ lambda: <{ y -- val }> \ angle 3.0 legendre-sum 0.1 f* ( val ) \ angle 0.1 f+ to angle \ ; map-channel \ ;;; -------- variations on sum-of-cosines \ ;;; from "Trigonometric Delights" by Eli Maor : sum-of-n-sines ( angle n -- val ) doc" Produce the sum of N sines." { angle n } angle f2/ { a2 } a2 fsin { den } den f0= if 0.0 else n a2 f* fsin n 1.0 f+ a2 f* fsin f* den f/ then ; \ 0.0 value angle \ lambda: <{ y -- val }> \ angle 3.0 sum-of-n-sines 0.1 f* ( val ) \ angle 0.1 f+ to angle \ ; map-channel : sum-of-n-odd-sines ( angle n -- val ) doc" Produce the sum of N odd-numbered sines." { angle n } angle fsin { den } angle n f* fsin dup { na2 } den f0= if 0.0 else na2 den f/ then ; : sum-of-n-odd-cosines ( angle n -- val ) doc" Produce the sum of N odd-numbered cosines." { angle n } angle fsin f2* { den } den f0= if n else angle n f* f2* den f/ then ; : band-limited-sawtooth ( x a N fi -- val ) doc" Produce a band-limited sawtooth; \ X is the current phase, \ A is the amp (more or less), \ N is 1..10 or thereabouts, \ FI is the phase increment." { x a N fi } a dup f* x fcos a f* -2.0 f* f+ 1.0 f+ { s4 } s4 f0= if 0.0 else a N 1.0 f- f** N 1.0 f- x f* fi f+ fsin f* { s1 } a N f** N x f* fi f+ fsin f* { s2 } x fi f+ fsin a f+ { s3 } fi fsin s3 fnegate f+ s2 fnegate f+ s1 f+ s4 f/ then ; \ 0.0 value angle \ lambda: <{ y -- val }> \ angle 0.5 8.0 0.2 band-limited-sawtooth ( val ) \ angle 0.2 f+ to angle \ ; map-channel : band-limited-square-wave ( theta n -- val ) doc" Produce square-wave; N sets how squared-off it is, \ THETA is instantaneous phase." swap fsin f* ftanh ; \ 0.0 value angle \ lambda: <{ y -- val }> \ angle 10.0 band-limited-square-wave ( val ) \ angle 0.2 f+ to angle \ ; map-channel \ ;;; -------- brighten-slightly hide : bs-cb { brt mx -- prc; y self -- val } 1 proc-create ( prc ) mx , brt , does> { y self -- val } self @ { mx } self cell+ @ { brt } brt y f* fsin mx f* ; set-current : brighten-slightly <{ amount :optional snd #f chn #f -- val }> doc" It's a form of contrast-enhancement (AMOUNT between ca 0.1 and 1)." snd chn #f maxamp { mx } two-pi amount f* mx f/ { brt } brt mx bs-cb 0 #f snd chn #f "%s %s" #( amount get-func-name ) string-format map-channel ; previous hide : brighten-slightly-1-cb { pcoeffs mx -- prc; y self -- val } 1 proc-create ( prc ) mx , pcoeffs , does> { y self -- val } self @ { mx } self cell+ @ { pcoeffs } pcoeffs y mx f/ polynomial mx f* ; set-current : brighten-slightly-1 <{ coeffs :optional snd #f chn #f -- val }> doc" It's a form of contrast-enhancement (AMOUNT between ca 0.1 and 1)." snd chn #f maxamp { mx } coeffs mus-chebyshev-first-kind partials->polynomial { pcoeffs } pcoeffs mx brighten-slightly-1-cb 0 #f snd chn #f "%s %s" #( coeffs get-func-name ) string-format map-channel ; \ #( 1 0.5 3 1 ) brighten-slightly-1 previous \ ;;; -------- FIR filters : spectrum->coeffs ( order spectr -- vct ) doc" Return FIR filter coefficients given the filter order and \ desired spectral envelope." { order spectr } order 0.0 make-vct { coeffs } order { n } n 1+ f2/ { am } am floor f>s { m } two-pi n f/ { q } n 1- { jj } m 0 ?do spectr 0 vct-ref f2/ ( xt ) m 1 ?do spectr i vct-ref q i am j 1.0 f- f- f* f* fcos f* f+ ( xt += ... ) loop ( xt ) n f/ f2* { coeff } coeffs i coeff vct-set! drop coeffs jj coeff vct-set! drop -1 +to jj loop coeffs ; : fltit-1 ( order spectr -- prc; y self -- val ) doc" Create FIR filter from spectrum and order and \ return a closure that calls it:\n\ 10 vct( 0 1.0 0 0 0 0 0 0 1.0 0 ) fltit-1 map-channel." { order spectr } :order order :xcoeffs order spectr spectrum->coeffs make-fir-filter { gen } 1 proc-create ( prc ) gen , does> { y self -- val } self @ ( gen ) y fir-filter ; \ 10 vct( 0 1.0 0 0 0 0 0 0 1.0 0 ) fltit-1 map-channel \ ;;; -------- Hilbert transform : make-hilbert-transform <{ :optional len 30 -- gen }> doc" Make Hilbert transform filter." len 2* 1+ { arrlen } arrlen 0.0 make-vct { arr } len even? if len else len 1+ then { lim } lim len negate ?do i len + { kk } i pi f* { denom } 1.0 denom fcos f- { num } num f0<> i 0<> || if arr kk num denom f/ denom len f/ fcos 0.46 f* 0.54 f+ f* vct-set! drop then loop :order arrlen :xcoeffs arr make-fir-filter ; <'> fir-filter alias hilbert-transform <'> hilbert-transform "( gen :optional input 0.0 -- val ) \ The generator corresponding to make-hilbert-transform." help-set! \ 15 make-hilbert-transform value h \ lambda: <{ y -- val }> h y hilbert-transform ; map-channel \ ;;; -------- highpass filter : make-highpass <{ fc :optional len 30 -- gen }> doc" Make FIR highpass filter." len 2* 1+ { arrlen } arrlen 0.0 make-vct { arr } len len negate ?do pi i f* { denom } fc i f* fsin fnegate { num } arr i len + i 0= if 1.0 fc pi f/ f- else num denom f/ pi i f* len f/ fcos 0.46 f* 0.54 f+ f* then vct-set! drop loop :order arrlen :xcoeffs arr make-fir-filter ; <'> fir-filter alias highpass <'> highpass "( gen :optional input 0.0 -- val ) \ The generator corresponding to make-highpass." help-set! \ pi 0.1 f* make-highpass value hp \ lambda: <{ y -- val }> hp y highpass ; map-channel \ ;;; -------- lowpass filter : make-lowpass <{ fc :optional len 30 -- gen }> doc" Make FIR lowpass filter." len 2* 1+ { arrlen } arrlen 0.0 make-vct { arr } len len negate ?do pi i f* { denom } fc i f* fsin { num } arr i len + i 0= if fc pi f/ else num denom f/ pi i f* len f/ fcos 0.46 f* 0.54 f+ f* then vct-set! drop loop :order arrlen :xcoeffs arr make-fir-filter ; <'> fir-filter alias lowpass <'> lowpass "( gen :optional input 0.0 -- val ) \ The generator corresponding to make-lowpass." help-set! \ pi 0.2 f* make-lowpass value lp \ lambda: <{ y -- val }> lp y lowpass ; map-channel \ ;;; -------- bandpass filter : make-bandpass <{ flo fhi :optional len 30 -- gen }> doc" Make FIR bandpass filter." len 2* 1+ { arrlen } arrlen 0.0 make-vct { arr } len len negate ?do pi i f* { denom } fhi i f* fsin flo i f* fsin f- { num } arr i len + i 0= if fhi flo f- pi f/ else num denom f/ pi i f* len f/ fcos 0.46 f* 0.54 f+ f* then vct-set! drop loop :order arrlen :xcoeffs arr make-fir-filter ; <'> fir-filter alias bandpass <'> bandpass "( gen :optional input 0.0 -- val ) \ The generator corresponding to make-bandpass." help-set! \ pi 0.1 f* pi 0.2 f* make-bandpass value bp \ lambda: <{ y -- val }> bp y bandpass ; map-channel \ ;;; -------- bandstop filter : make-bandstop <{ flo fhi :optional len 30 -- gen }> doc" Make FIR bandstop (notch) filter." len 2* 1+ { arrlen } arrlen 0.0 make-vct { arr } len len negate ?do pi i f* { denom } fhi i f* fsin flo i f* fsin f- { num } arr i len + i 0= if 1.0 fhi flo f- pi f/ f- else num denom f/ pi i f* len f/ fcos 0.46 f* 0.54 f+ f* then vct-set! drop loop :order arrlen :xcoeffs arr make-fir-filter ; <'> fir-filter alias bandstop <'> bandstop "( gen :optional input 0.0 -- val ) \ The generator corresponding to make-bandstop." help-set! \ pi 0.1 f* pi 0.3 f* make-bandstop value bs \ lambda: <{ y -- val }> bs y bandstop ; map-channel \ ;;; -------- differentiator : make-differentiator <{ :optional len 30 -- gen }> doc" Make FIR differentiator (highpass) filter." len 2* 1+ { arrlen } arrlen 0.0 make-vct { arr } len len negate ?do i 0<> if pi i f* { pi*i } arr i len + pi*i fcos i f/ pi*i fsin pi*i i f* f/ f- pi*i len f/ fcos 0.46 f* 0.54 f+ f* vct-set! drop then loop :order arrlen :xcoeffs arr make-fir-filter ; <'> fir-filter alias differentiator <'> differentiator "( gen :optional input 0.0 -- val ) \ The generator corresponding to make-differentiator." help-set! \ make-differentiator value dt \ lambda: <{ y -- val }> dt y differentiator ; map-channel \ ;;; -------- IIR filters \ ;;; see analog-filter.scm for the usual suspects \ ;;; -------- Butterworth filters \ ;;; (see also further below -- make-butter-lp et al) \ ;;; \ ;; translated from CLM butterworth.cl: \ ;; \ ;; Sam Heisz, January 1998 \ ;; inspired by some unit generators written for Csound by Paris Smaragdis \ ;; who based his work on formulas from \ ;; Charles Dodge, Computer music: synthesis, composition, and performance. : make-butter-high-pass ( freq -- flt ) doc" Make Butterworth filter with high pass cutoff at FREQ." { freq } pi freq f* #f srate f/ ftan { r } r r f* { r2 } r 2.0 fsqrt r2 f* f* 1/f { c1 } -2.0 c1 f* { c2 } c1 { c3 } r2 1.0 f- c1 f* f2* { c4 } 1.0 2.0 fsqrt r f* f- r2 f+ c1 f* { c5 } 3 vct( c1 c2 c3 ) vct( 0.0 c4 c5 ) make-filter ; : make-butter-low-pass ( freq -- flt ) doc" Make Butterworth filter with low pass cutoff at FREQ. \ The result can be used directly: 500.0 make-butter-low-pass filter-sound, \ or via the 'butter' generator." { freq } pi freq f* #f srate f/ ftan 1/f { r } r r f* { r2 } r 2.0 fsqrt f* 1.0 r2 f* f* 1/f { c1 } c1 f2* { c2 } c1 { c3 } 1.0 r2 f- c1 f* f2* { c4 } 1.0 2.0 fsqrt r f* f- r2 f+ c1 f* { c5 } 3 vct( c1 c2 c3 ) vct( 0.0 c4 c5 ) make-filter ; : make-butter-band-pass ( freq bw -- flt ) doc" Make bandpass Butterworth filter with \ low edge at FREQ and width BAND." { freq bw } #f srate { sr } 2.0 pi freq f* f* sr f/ fcos f2* { d } pi bw f* sr f/ ftan 1/f { c } 1.0 c f+ 1/f { c1 } 0.0 { c2 } c1 fnegate { c3 } c fnegate d c1 f* f* { c4 } c 1.0 f- c1 f* { c5 } 3 vct( c1 c2 c3 ) vct( 0.0 c4 c5 ) make-filter ; : make-butter-band-reject ( freq bw -- flt ) doc" Make band-reject Butterworth filter with low edge at FREQ \ and width BAND." { freq bw } #f srate { sr } 2.0 pi freq f* f* sr f/ fcos f2* { d } pi bw f* sr f/ ftan { c } 1.0 c f+ 1/f { c1 } d fnegate c1 f* { c2 } c1 { c3 } c2 { c4 } 1.0 c f- c1 f* { c5 } 3 vct( c1 c2 c3 ) vct( 0.0 c4 c5 ) make-filter ; <'> filter alias butter <'> butter "( gen :optional input 0.0 -- val ) \ The generator side for the various make-butter procedures." help-set! \ 500.0 make-butter-low-pass filter-sound \ ;;; from "DSP Filter Cookbook" by Lane et al, Prompt Pubs, 2001 \ ;;; \ ;;; use with the filter generator \ ;;; 1000 make-iir-high-pass-2 value gen \ ;;; gen 1.0 filter \ ;;; etc : make-biquad ( a0 a1 a2 b1 b2 -- gen ) doc" Return biquad filter (use with the CLM filter gen)." { a0 a1 a2 b1 b2 } 3 vct( a0 a1 a2 ) vct( 0.0 b1 b2 ) make-filter ; : make-iir-low-pass-2 ( fc :optional d -- gen ) #( 2.0 fsqrt ) 1 get-optargs { fc d } two-pi fc f* mus-srate f/ { theta } 1.0 d f2/ theta fsin f* f- 1.0 d f2/ theta fsin f* f+ f/ f2/ { beta } beta 0.5 f+ theta fcos f* { gamma } beta 0.5 f+ gamma fnegate f+ f2/ { alpha } 3 vct( alpha alpha f2* alpha ) vct( 0.0 gamma -2.0 f* beta f2* ) make-filter ; : make-iir-high-pass-2 ( fc :optional d -- gen ) #( 2.0 fsqrt ) 1 get-optargs { fc d } two-pi fc f* mus-srate f/ { theta } 1.0 d f2/ theta fsin f* f- 1.0 d f2/ theta fsin f* f+ f/ f2/ { beta } beta 0.5 f+ theta fcos f* { gamma } beta 0.5 f+ gamma f+ f2/ { alpha } 3 vct( alpha alpha -2.0 f* alpha ) vct( 0.0 gamma -2.0 f* beta f2* ) make-filter ; : make-iir-band-pass-2 ( f1 f2 -- gen ) { f1 f2 } two-pi f1 f2 f* fsqrt mus-srate f/ { theta } f1 f2 f* fsqrt f2 f1 f- f/ { Q } theta Q f2* f/ ftan { t2 } 1.0 t2 f- 1.0 t2 f+ f/ f2/ { beta } beta 0.5 f+ theta fcos f* { gamma } 0.5 beta f- { alpha } 3 vct( alpha 0.0 alpha fnegate ) vct( 0.0 gamma -2.0 f* beta f2* ) make-filter ; : make-iir-band-stop-2 ( f1 f2 -- gen ) { f1 f2 } two-pi f1 f2 f* fsqrt mus-srate f/ { theta } f1 f2 f* fsqrt f2 f1 f- f/ { Q } theta Q f2* f/ ftan { t2 } 1.0 t2 f- 1.0 t2 f+ f/ f2/ { beta } beta 0.5 f+ theta fcos f* { gamma } 0.5 beta f+ { alpha } 3 vct( alpha gamma -2.0 f* alpha fnegate ) vct( 0.0 gamma -2.0 f* beta f2* ) make-filter ; : make-eliminate-hum <{ :optional hum-freq 60.0 hum-harmonics 5 bandwith 10 -- gen }> hum-harmonics make-array map! hum-freq i 1.0 f+ f* { center } bandwith f2/ { b2 } center b2 f- center b2 f+ make-iir-band-stop-2 end-map ( gen ) ; : eliminate-hum ( gens x0 -- val ) { gens x0 } gens each ( gen ) x0 filter to x0 end-each x0 ; \ make-eliminate-hum value hummer \ lambda: <{ y -- val }> hummer y eliminate-hum ; map-channel \ ;; bandpass, m is gain at center of peak \ ;; use map-channel with this one (not clm-channel or filter) : make-peaking-2 ( f1 f2 m -- prc; y self -- val ) { f1 f2 m } f1 f2 f* fsqrt two-pi f* mus-srate f/ { theta } f1 f2 f* fsqrt f2 f1 f- f/ { Q } 4.0 m 1.0 f+ f/ theta Q f2* f/ ftan f* { t2 } 1.0 t2 f- 1.0 t2 f+ f/ f2/ { beta } 0.5 beta f+ theta fcos f* { gamma } 0.5 beta f- { alpha } 3 vct( alpha 0.0 alpha fnegate ) vct( 0.0 -2.0 gamma f* beta f2* ) make-filter { flt } 1 proc-create ( prc ) flt , m 1.0 f- , does> { y self -- val } self @ ( flt ) y filter self cell+ @ ( m ) f* y f+ ; : cascade->canonical ( A -- A' ) doc" Convert array of cascade coeffs (vcts with 3 entries) \ to canonical form." { A } A length { K } K 2* 1+ 0.0 make-vct { d } K 2* 1+ 0.0 make-vct { a1 } a1 0 1.0 vct-set! drop A each { h } i 2* 3 + 0 ?do d i 0.0 vct-set! drop 2 i min 0 ?do d j h i vct-ref a1 j i - vct-ref f* object-set+! loop loop i 2* 3 + 0 ?do a1 j d j vct-ref vct-set! drop loop end-each a1 ; : make-butter-lp ( M fc -- flt ) doc" Return butterworth low-pass filter; \ its order is M * 2, FC is the cutoff frequency in Hz." { M fc } #() { xcoeffs } #() { ycoeffs } two-pi fc f* mus-srate f/ { theta } theta fsin { st } theta fcos { ct } M 0 ?do i 1+ 2* 1- pi f* 4 M * f/ fsin f2* { d } 1.0 d st f* f2/ f- 1.0 d st f* f2/ f/ f2/ { beta } beta 0.5 f+ ct f* { gamma } gamma fnegate beta f+ 0.5 f+ 0.25 f* { alpha } xcoeffs vct( alpha f2* alpha 4.0 f* alpha f2* ) array-push drop ycoeffs vct( 1.0 -2.0 gamma f* beta f2* ) array-push drop loop M 2* 1+ xcoeffs cascade->canonical ycoeffs cascade->canonical make-filter ; : make-butter-hp ( M fc -- flt ) doc" Return butterworth high-pass filter; \ its order is M * 2, FC is the cutoff frequency in Hz." { M fc } #() { xcoeffs } #() { ycoeffs } two-pi fc f* mus-srate f/ { theta } theta fsin { st } theta fcos { ct } M 0 ?do i 1+ 2* 1- pi f* 4 M * f/ fsin f2* { d } 1.0 d st f* f2/ f- 1.0 d st f* f2/ f/ f2/ { beta } beta 0.5 f+ ct f* { gamma } gamma beta f+ 0.5 f+ 0.25 f* { alpha } xcoeffs vct( alpha f2* alpha -4.0 f* alpha f2* ) array-push drop ycoeffs vct( 1.0 -2.0 gamma f* beta f2* ) array-push drop loop M 2* 1+ xcoeffs cascade->canonical ycoeffs cascade->canonical make-filter ; : make-butter-bp ( M f1 f2 -- flt ) doc" Return butterworth band-pass filter; \ its order is M * 2, F1 and F2 are the band edge frequencies in Hz." { M f1 f2 } #() { xcoeffs } #() { ycoeffs } f1 f2 f* fsqrt { f0 } f0 f2 f1 f- f/ { Q } two-pi f0 f* mus-srate f/ { theta0 } theta0 Q f2* f/ theta0 fsin f* f2* { de } de f2/ { de2 } theta0 f2/ ftan { tn0 } 1 1 { jj kk } M 0 ?do kk 2* 1- pi f* M 2* f/ fsin f2* { Dk } de2 de2 f* 1.0 f+ Dk de2 f* f/ { Ak } de Dk f* Ak Ak f* 1.0 f- fsqrt Ak f+ f/ fsqrt { dk1 } Dk dk1 f/ de2 f* { Bk } Bk Bk f* 1.0 f- fsqrt Bk f+ { Wk } jj 1 = if tn0 Wk f/ else tn0 Wk f* then fatan f2* { thetajk } 1.0 0.5 dk1 f* thetajk fsin f* f- 1.0 0.5 dk1 f* thetajk fsin f* f+ f/ f2/ { betajk } 0.5 betajk f+ thetajk fcos f* { gammajk } Wk Wk 1/f f- dk1 f/ { wk2 } 0.5 betajk f- wk2 wk2 f* 1.0 f+ fsqrt f* { alphajk } xcoeffs vct( alphajk f2* 0.0 -2.0 alphajk f* ) array-push drop ycoeffs vct( 1.0 -2.0 gammajk f* betajk f2* ) array-push drop jj 1 = if 2 to jj else 1 +to kk 1 to jj then loop M 2* 1+ xcoeffs cascade->canonical ycoeffs cascade->canonical make-filter ; : make-butter-bs ( M f1 f2 -- flt ) doc" Return butterworth band-stop filter; \ its order is M * 2, F1 and F2 are the band edge frequencies in Hz." { M f1 f2 } #() { xcoeffs } #() { ycoeffs } f1 f2 f* fsqrt { f0 } f0 f2 f1 f- f/ { Q } two-pi f0 f* mus-srate f/ { theta0 } theta0 Q f2* f/ theta0 fsin f* f2* { de } de f2/ { de2 } theta0 fcos { ct } theta0 f2/ ftan { tn0 } 1 1 { jj kk } M 0 ?do kk 2* 1- pi f* M 2* f/ fsin f2* { Dk } de2 de2 f* 1.0 f+ Dk de2 f* f/ { Ak } de Dk f* Ak Ak f* 1.0 f- fsqrt Ak f+ f/ fsqrt { dk1 } Dk dk1 f/ de2 f* { Bk } Bk Bk f* 1.0 f- fsqrt Bk f+ { Wk } jj 1 = if tn0 Wk f/ else tn0 Wk f* then fatan f2* { thetajk } 1.0 0.5 dk1 f* thetajk fsin f* f- 1.0 0.5 dk1 f* thetajk fsin f* f+ f/ f2/ { betajk } 0.5 betajk f+ thetajk fcos f* { gammajk } 0.5 betajk f+ 1.0 thetajk fcos f- 1.0 ct f- f/ f* f2/ { alphajk } xcoeffs vct( alphajk f2* ct alphajk f* -4.0 f* alphajk f2* ) array-push drop ycoeffs vct( 1.0 -2.0 gammajk f* betajk f2* ) array-push drop jj 1 = if 2 to jj else 1 +to kk 1 to jj then loop M 2* 1+ xcoeffs cascade->canonical ycoeffs cascade->canonical make-filter ; \ ;;; -------- notch filters : make-notch-frequency-response <{ cur-srate freqs :optional notch-width 2 -- fresp }> #( 0.0 1.0 ) ( freq-response ) freqs each { f } \ ; left upper y hz f notch-width f- f2* cur-srate f/ array-push \ ; left upper y resp 1.0 array-push \ ; left bottom y hz f notch-width f2/ f- f2* cur-srate f/ array-push \ ; left bottom y resp 0.0 array-push \ ; right bottom y hz f notch-width f2/ f+ f2* cur-srate f/ array-push \ ; right bottom y resp 0.0 array-push \ ; right upper y hz f notch-width f+ f2* cur-srate f/ array-push \ ; right upper y resp 1.0 array-push end-each #( 1.0 1.0 ) array-append ( freq-response ) ; : notch-channel <{ freqs :optional filter-order #f beg 0 dur #f snd #f chn #f edpos #f truncate #t notch-width 2 -- f }> doc" Return notch filter removing freqs." snd srate s>f freqs notch-width make-notch-frequency-response { nf } filter-order 2.0 snd srate notch-width f/ flog 2.0 flog f/ fceil f** fround->s || { order } "%s %s %s %s %s" #( freqs filter-order beg dur get-func-name ) string-format { origin } nf order beg dur snd chn edpos truncate origin filter-channel ; : notch-sound <{ freqs :optional filter-order #f snd #f chn #f notch-width 2 -- f }> doc" Return notch filter removing freqs." snd srate s>f freqs notch-width make-notch-frequency-response { nf } filter-order 2.0 snd srate notch-width f/ flog 2.0 flog f/ fceil f** fround->s || { order } "%s %s 0 #f notch-channel " #( freqs filter-order ) string-format { origin } nf order snd chn #f origin filter-sound ; : notch-selection <{ freqs :optional filter-order #f notch-width 2 -- f }> doc" Return notch filter removing freqs." undef selection? if selection-srate s>f freqs notch-width make-notch-frequency-response ( nf ) filter-order 2.0 selection-srate notch-width f/ flog 2.0 flog f/ fceil f** fround->s || ( order ) #t ( truncate ) filter-selection then ; \ ;;; -------- fractional Fourier Transform, z transform \ ;;; \ ;;; translated from the fxt package of Joerg Arndt : fractional-fourier-transform ( real imaginary n angle -- hr hi ) doc" Perform fractional Fourier transform on data; \ if angle=1.0, you get a normal Fourier transform." { fr fi n v } v two-pi f* n f/ { ph0 } n 0.0 make-vct { hi } n 0.0 make-vct map! 0.0 0.0 { sr si } fr each { x } ph0 i f* j f* { phase } phase fcos { c } phase fsin { s } phase fcos { c } fi i vct-ref { y } x c f* y s f* f- { r } y c f* x s f* f+ { i } sr r f+ to sr si i f+ to si end-each hi i si vct-set! drop sr end-map ( hr ) hi ; 'complex provided? [if] : z-transform ( data n z -- ) doc" Perform Z transform on DATA; \ if z=e^2*pi*j/n you get a Fourier transform; \ complex results in returned vector." { f n z } n make-array map! 0.0 ( sum ) 1.0 { t } z i f** { m } n 0 ?do f i vct-ref t c* c+ ( sum += ... ) t m c* to t loop ( sum ) end-map ; \ data n 0.0 2.0 n f/ pi f* make-rectangular cexp z-transform [then] \ ;;; -------- slow Hartley transform : dht ( data -- vct ) doc" Return the Hartley transform of DATA." { data } data length { len } two-pi len f/ { w } len 0.0 make-vct { arr } len 0 do len 0 do arr j data i vct-ref i j w f* f* fcos i j w f* f* fsin f+ f* object-set+! loop loop arr ; 'complex provided? [if] : find-sine ( freq beg dur -- amp ph ) doc" Return the amplitude and initial-phase (for sin) at FREQ." { freq beg dur } freq hz->radians { incr } 0.0 0.0 { sw cw } beg #f #f 1 #f make-sampler { reader } dur 0 do reader next-sample { samp } i incr c* csin samp c* sw c+ to sw i incr c* ccos samp c* cw c+ to cw loop sw dup c* cw dup c* c+ csqrt dur c/ 2.0 c* ( amp ) cw sw catan2 ( ph ) ; hide : goert-cb { y0 y1 y2 cs -- prc; y self -- f } 1 proc-create ( prc ) y0 , y1 , y2 , cs , does> { y self -- f } self 1 cells + @ self 2 cells + ! ( y2 = y1 ) self @ self 1 cells + ! ( y1 = y0 ) self 1 cells + @ { y1 } self 2 cells + @ { y2 } self 3 cells + @ { cs } y1 cs c* y2 c- y c+ self ! ( y0 = ... ) #f ; set-current : goertzel <{ freq :optional beg 0 dur #f -- amp }> doc" Return the amplitude of the FREQ spectral component." #f srate { sr } 0.0 0.0 0.0 { y0 y1 y2 } two-pi freq f* sr f/ { rfreq } rfreq fcos f2* { cs } dur unless #f #f #f framples to dur then y0 y1 y2 cs goert-cb beg dur #f #f #f scan-channel drop 0.0 rfreq fnegate make-rectangular cexp y1 c* y0 c+ magnitude ; previous [then] : make-spencer-filter ( -- gen ) doc" It's a version of make-fir-filter; \ it returns one of the standard smoothing filters \ from the era when computers were human beings." #( -3 -6 -5 3 21 46 67 74 67 46 21 3 -5 -6 -3 ) { lst } :xcoeffs lst 0.0 make-vct map! *key* 320.0 f/ end-map :order 15 make-fir-filter ; \ ;;; -------- any-random \ ;;; \ ;;; arbitrary random number distributions via the "rejection method" : any-random <{ amount :optional en #f -- r }> amount f0= if 0.0 else en if en envelope-last-x { x1 } 0.0 0.0 { x y } begin x1 random to x 1.0 random to y y x en 1.0 envelope-interp f<= until x else amount random then then ; : gaussian-distribution ( s -- en ) { s } #() { en } 2.0 s s f* f* { den } 0.0 -4.0 { x y } 21 0 do en x array-push y y f* den f/ fexp array-push to en x 0.05 f+ to x y 0.40 f* to y loop en ; : pareto-distribution ( a -- en ) { a } #() { en } 1.0 a 1.0 f+ f** a f/ { scl } 0.0 1.0 { x y } 21 0 do en x array-push a y a 1.0 f+ f** f/ scl f* array-push to en x 0.05 f+ to x y 0.20 f* to y loop en ; \ uniform distribution \ lambda: <{ y -- val }> 1.0 #( 0 1 1 1 ) any-random ; map-channel \ mostly toward 1.0 \ lambda: <{ y -- val }> 1.0 #( 0 0 0.95 0.1 1 1 ) any-random ; map-channel \ 1.0 gaussian-distribution value g \ lambda: <{ y -- val }> 1.0 g any-random ; map-channel \ 1.0 pareto-distribution value g \ lambda: <{ y -- val }> 1.0 g any-random ; map-channel \ ;;; this is the inverse integration function used by CLM to turn a \ ;;; distribution function into a weighting function : inverse-integrate <{ dist :optional data-size 512 e-size 50 -- vct }> #() { en } dist 1 array-ref exact->inexact dup { sum first-sum } dist 0 array-ref { x0 } dist envelope-last-x { x1 } x1 x0 f- e-size f/ { xincr } x0 { x } e-size 0 ?do en sum array-push x array-push to en x dist 1.0 envelope-interp sum f+ to sum x xincr f+ to x loop en -2 array-ref first-sum f- data-size 1- f/ { incr } first-sum to x data-size 0.0 make-vct map! x en 1.0 envelope-interp ( val ) x incr f+ to x end-map ( data ) ; : gaussian-envelope ( s -- en ) { s } #() { en } 2.0 s s f* f* { den } -1.0 -4.0 { x y } 21 0 do en x array-push y y f* den f/ fexp array-push to en x 0.1 f+ to x y 0.4 f* to y loop en ; \ :envelope 1.0 gaussian-envelope make-rand \ ;;; ---------------- Julius Smith stuff ---------------- \ ;;; \ ;;; these are from "Mathematics of the DFT", W3K Pubs hide : chm-cb { sum -- prc; y self -- f } 1 proc-create ( prc ) sum , does> { y self -- f } y self +! ( sum += y ) #f ; set-current : channel-mean <{ :optional snd #f chn #f -- val }> \ / n doc" Return the average of the samples in the given channel: /n." 0.0 { sum } snd chn #f framples { len } sum chm-cb 0 len snd chn #f scan-channel drop sum len f/ ; previous hide : chte-cb { sum -- prc; y self -- f } 1 proc-create ( prc ) sum , does> { y self -- f } y dup f* self +! ( sum += y ) #f ; set-current : channel-total-energy <{ :optional snd #f chn #f -- val }> \ doc" Return the sum of the squares of all the samples \ in the given channel: ." 0.0 { sum } snd chn #f framples { len } sum chte-cb 0 len snd chn #f scan-channel drop sum ; previous : channel-average-power <{ :optional snd #f chn #f -- val }> \ / n doc" Return the average power in the given channel: /n." snd chn channel-total-energy snd chn #f framples f/ ; : channel-rms <{ :optional snd #f chn #f -- val }> \ sqrt( / n) doc" Return the RMS value of the samples \ in the given channel: sqrt(/n)." snd chn channel-average-power fsqrt ; \ - ( / n) ^ 2 with quibbles : channel-variance <{ :optional snd #f chn #f -- val }> doc" Return the sample variance in the \ given channel: -((/ n)^2." snd chn #f framples { len } len len 1- f/ snd chn channel-mean f* { mu } snd chn channel-total-energy { P } P mu dup f* f- ; : channel-norm <{ :optional snd #f chn #f -- val }> \ sqrt() doc" Return the norm of the samples in the given channel: sqrt()." snd chn channel-total-energy fsqrt ; hide : chlp-cb { sum p -- prc; y self -- f } 1 proc-create ( prc ) sum , p , does> { y self -- f } y fabs self cell+ @ ( p ) f** self +! ( sum += y ** p ) ; set-current : channel-lp <{ p :optional snd #f chn #f -- val }> doc" Return the Lp norm of the samples in the given channel." 0.0 { sum } snd chn #f framples { len } sum p chlp-cb 0 len snd chn #f scan-channel drop sum p 1/f f** ; previous hide : chlpinf-cb { mx -- prc; y self -- f } 1 proc-create ( prc ) mx , does> { y self -- f } y fabs self @ fmax self ! ; set-current : channel-lp-inf <{ :optional snd #f chn #f -- val }> doc" Return the maxamp in the given channel (the name is \ just math jargon for maxamp)." 0.0 { mx } snd chn #f framples { len } mx chlpinf-cb 0 len snd chn #f scan-channel drop mx ; previous : channel2-inner-product ( s1 c1 s2 c2 -- val ) \ doc" Return the inner-product of the two channels: ." { s1 c1 s2 c2 } 0.0 { sum } 0 s1 c1 1 #f make-sampler { r1 } 0 s2 c2 1 #f make-sampler { r2 } 0.0 ( sum ) s1 c1 #f framples 0 ?do r1 next-sample r2 next-sample f* f+ ( sum += ... ) loop ( sum ) ; \ acos( / (sqrt() * sqrt())) : channel2-angle ( s1 c1 s2 c2 -- val ) doc" Treat the two channels as vectors, \ returning the 'angle' between them: acos(/(sqrt()*sqrt()))." { s1 c1 s2 c2 } s1 c1 s2 c2 channel2-inner-product { inprod } s1 c1 channel-norm { norm1 } s2 c2 channel-norm { norm2 } inprod norm1 norm2 f* f/ facos ; : channel2-orthogonal? ( s1 c1 s2 c2 -- f ) \ == 0 doc" Return #t if the two channels' inner-product is 0: ==0." { s1 c1 s2 c2 } s1 c1 s2 c2 channel2-inner-product fzero? ; \ s1,c1 = x, s2,c2 = y, / : channel2-coefficient-of-projection ( s1 c1 s2 c2 -- val ) doc" Return /." { s1 c1 s2 c2 } s1 c1 s2 c2 channel2-inner-product s1 c1 channel-total-energy f/ ; \ ;;; -------- end of JOS stuff -------- : channel-distance ( s1 c1 s2 c2 -- val ) doc" Return the euclidean distance between the two channels: \ sqrt()." { s1 c1 s2 c2 } 0 s1 c1 1 #f make-sampler { r1 } 0 s2 c2 1 #f make-sampler { r2 } 0.0 ( sum ) s1 c1 #f framples s2 c2 #f framples min 0 ?do r1 next-sample r2 next-sample f- dup f* f+ ( sum += diff^2 ) loop ( sum ) fsqrt ; : periodogram ( N -- ) doc" Display an 'N' point Bartlett periodogram \ of the samples in the current channel." { N } #f #f #f framples { len } 0 #f #f 1 #f make-sampler { rd } N 2* { N2 } N2 0.0 make-vct { rl } N 0 ?do rl i rd next-sample vct-set! drop loop N2 0.0 make-vct { im } rl im N2 1 mus-fft drop N 0.0 make-vct map! rl i vct-ref dup f* im i vct-ref dup f* f+ end-map ( average-data ) len N f/ fceil 1/f vct-scale! "average-data" 0.0 1.0 #f #f #f #f #t #t graph ; \ ;;; -------- ssb-am friends hide : scp-cb { gen -- prc; y self -- val } 1 proc-create ( prc ) gen , does> { y self -- val } self @ y 0.0 ssb-am ; set-current : shift-channel-pitch <{ freq :optional order 40 beg 0 dur #f snd #f chn #f edpos #f -- val }> :frequency freq :order order make-ssb-am { gen } "%s %s %s %s %s" #( freq order beg dur get-func-name ) string-format { origin } gen scp-cb beg dur snd chn edpos origin map-channel ; previous : hz->2pi ( freq -- r ) two-pi f* #f srate f/ ; hide : ssbmc-cb { nmx ssbs bands -- prc; y self -- val } 1 proc-create ( prc ) nmx , ssbs , bands , does> { y self -- val } self @ { nmx } self 1 cells + @ { ssbs } self 2 cells + @ { bands } 0.0 ssbs each ( gen ) bands i array-ref y bandpass 0.0 ssb-am f+ ( sum+=... ) end-each ( sum ) dup fabs nmx fmax self ! ( to nmx ) ; : ssbaoe-cb { mx ssbs bands beg dur snd chn edpos -- prc; self -- val } 0.0 { nmx } nmx ssbs bands ssbmc-cb { proc } 0 proc-create ( prc ) proc , mx , nmx , beg , dur , snd , chn , edpos , does> { self -- val } self @ { proc } self 1 cells + @ { mx } self 2 cells + @ { nmx } self 3 cells + @ { beg } self 4 cells + @ { dur } self 5 cells + @ { snd } self 6 cells + @ { chn } self 7 cells + @ { edpos } proc beg dur snd chn edpos #f map-channel drop mx nmx f/ beg dur snd chn #f scale-channel ; set-current : ssb-bank <{ old-freq new-freq pairs :optional order 40 bw 50.0 beg 0 dur #f snd #f chn #f edpos #f -- val }> pairs make-array { ssbs } pairs make-array { bands } new-freq old-freq f- old-freq f/ { factor } snd chn #f maxamp { mx } pairs 0 ?do i 1.0 f+ { idx } old-freq idx f* { aff } idx pairs f2* f/ 1.0 f+ bw f* { bwf } ssbs i :frequency idx factor f* old-freq f* :order 40 make-ssb-am array-set! bands i aff bwf f- hz->2pi aff bwf f+ hz->2pi order make-bandpass array-set! loop "%s %s %s %s %s %s %s %s" #( old-freq new-freq pairs order bw beg dur get-func-name ) string-format { origin } mx ssbs bands beg dur snd chn edpos ssbaoe-cb origin as-one-edit ; previous hide : ssbemc-cb { nmx ssbs bands frenvs -- prc; y self -- val } 1 proc-create ( prc ) nmx , ssbs , bands , frenvs , does> { y self -- val } self @ { nmx } self 1 cells + @ { ssbs } self 2 cells + @ { bands } self 3 cells + @ { frenvs } 0.0 ssbs each ( gen ) bands i array-ref y bandpass frenvs i array-ref env ssb-am f+ ( sum+=... ) end-each ( sum ) dup fabs nmx fmax self ! ( to nmx ) ( sum ) ; : ssbeaoe-cb { mx ssbs bands frenvs beg dur snd chn edpos -- prc; self -- val } 0.0 { nmx } nmx ssbs bands frenvs ssbemc-cb { proc } 0 proc-create ( prc ) proc , mx , nmx , beg , dur , snd , chn , edpos , does> { self -- val } self @ { proc } self 1 cells + @ { mx } self 2 cells + @ { nmx } self 3 cells + @ { beg } self 4 cells + @ { dur } self 5 cells + @ { snd } self 6 cells + @ { chn } self 7 cells + @ { edpos } proc beg dur snd chn edpos #f map-channel drop mx nmx f/ beg dur snd chn #f scale-channel ; set-current : ssb-bank-env <{ old-freq new-freq freq-env pairs :optional order 40 bw 50.0 beg 0 dur #f snd #f chn #f edpos #f -- val }> pairs make-array { ssbs } pairs make-array { bands } pairs make-array { frenvs } new-freq old-freq f- old-freq f/ { factor } snd chn #f maxamp { mx } snd chn #f framples 1- { len } pairs 0 ?do i 1.0 f+ { idx } old-freq idx f* { aff } idx pairs f2* f/ 1.0 f+ bw f* { bwf } ssbs i :frequency idx factor f* old-freq f* :order 40 make-ssb-am array-set! bands i aff bwf f- hz->2pi aff bwf f+ hz->2pi order make-bandpass array-set! :envelope freq-env :scaler idx hz->radians :length len make-env { en } frenvs i en array-set! loop "%s %s %s %s %s %s %s %s %s" #( old-freq new-freq freq-env pairs order bw beg dur get-func-name ) string-format { origin } mx ssbs bands frenvs beg dur snd chn edpos ssbeaoe-cb origin as-one-edit ; previous \ ;; echoes with each echo at a new pitch via ssb-am etc : make-transposer <{ old-freq new-freq pairs :optional order 40 bw 50.0 -- g }> new-freq old-freq f- old-freq f/ { factor } pairs make-array map! i 1+ factor f* old-freq f* make-ssb-am end-map { ssbs } pairs make-array map! i 1.0 f+ { idx } idx old-freq f* { aff } idx pairs f2* f/ 1.0 f+ bw f* { bwf } aff bwf f- hz->radians aff bwf f+ hz->radians order make-bandpass end-map { bands } #( ssbs bands ) ; : transpose ( gen input -- val ) { gen input } gen 0 array-ref { ssbs } gen 1 array-ref { bands } 0.0 ( sum ) ssbs each { g } g bands i array-ref input bandpass 0.0 ssb-am f+ ( sum += ) end-each ( sum ) ; : make-fdelay ( len pitch scaler -- prc; y self -- val ) { len pitch scaler } len make-delay { dly } 440.0 440.0 pitch f* 10 make-transposer { ssb } 1 proc-create ( prc ) dly , ssb , scaler , does> { y self -- val } self @ { dly } self cell+ @ { ssb } self 2 cells + @ { scaler } dly ssb dly 0.0 tap transpose scaler f* y f+ 0.0 delay ; : fdelay ( gen input -- val ) { gen input } gen #( input ) run-proc ; : transposed-echo ( pitch scaler secs -- val ) { pitch scaler secs } #f srate secs f* fround->s pitch scaler make-fdelay 0 #f #f #f #f #f map-channel ; \ ;;; vct|channel|spectral-polynomial : vct-polynomial ( v coeffs -- vct ) { v coeffs } v vct-length coeffs last-ref make-vct { new-v } coeffs vct-length 2- 0 ?do new-v v vct-multiply! coeffs i vct-ref vct-offset! drop -1 +loop new-v ; : channel-polynomial <{ coeffs :optional snd #f chn #f -- vct }> snd chn #f framples { len } "%S %s" #( coeffs get-func-name ) string-format { origin } 0 len snd chn #f channel->vct coeffs vct-polynomial 0 len snd chn #f origin vct->channel ; \ vct( 0.0 0.5 ) channel-polynomial == x*0.5 \ vct( 0.0 1.0 1.0 1.0 ) channel-polynomial == x*x*x + x*x + x \ ;;; convolution -> * in freq : spectral-polynomial <{ coeffs :optional snd #f chn #f -- vct }> snd chn #f framples { len } 0 len snd chn #f channel->vct { sound } coeffs vct-length { num-coeffs } num-coeffs 2 < if len else 2.0 num-coeffs 1 f- len f* flog 2.0 flog f/ fceil f** fround->s then { fft-len } fft-len 0.0 make-vct { rl1 } fft-len 0.0 make-vct { rl2 } fft-len 0.0 make-vct { new-sound } coeffs 0 vct-ref f0> if coeffs 0 vct-ref { dither } new-sound map! dither mus-random end-map drop then num-coeffs 1 > if new-sound sound vct-copy coeffs 1 vct-ref vct-scale! vct-add! drop num-coeffs 2 > if snd chn #f maxamp { peak } rl1 0.0 vct-scale! sound vct-add! drop 0.0 { pk } num-coeffs 2 ?do rl1 rl2 0.0 vct-scale! sound vct-add! fft-len convolution drop rl1 vct-peak to pk new-sound rl1 vct-copy coeffs i vct-ref peak f* pk f/ vct-scale! vct-add! drop loop new-sound vct-peak to pk new-sound peak pk f/ vct-scale! drop then then "%S %s" #( coeffs get-func-name ) string-format { origin } new-sound 0 num-coeffs 1- len * len max snd chn #f origin vct->channel ; \ ;;; ---------------- \ ;;; SCENTROID \ ;;; \ ;;; by Bret Battey \ ;;; Version 1.0 July 13, 2002 \ ;;; translated to Snd/Scheme Bill S 19-Jan-05 \ ;;; \ ;;; Returns the continuous spectral centroid envelope of a sound. \ ;;; The spectral centroid is the "center of gravity" of the spectrum, \ ;;; and it has a rough correlation to our sense of "brightness" of a sound. \ ;;; \ ;;; [Beauchamp, J., "Synthesis by spectral amplitude and 'brightness' \ ;;; matching analyzed musical sounds". \ ;;; Journal of Audio Engineering Society 30(6), 396-406] \ ;;; \ ;;; The formula used is: \ ;;; C = [SUMF(n)A(n)] / [SUMA(n)] \ ;;; Where j is the number of bins in the analysis, \ ;;; F(n) is the frequency of a given bin, \ ;;; A(n) is the magnitude of the given bin. \ ;;; \ ;;; If a pitch envelope for the analyzed sound is available, the results \ ;;; of SCENTROID can be used with the function NORMALIZE-CENTROID, below, \ ;;; to provide a "normalized spectral centroid". \ ;;; \ ;;; DB-FLOOR -- Frames below this decibel level (0 dB = max) will be \ ;;; discarded and returned with spectral centroid = 0 \ ;;; \ ;;; RFREQ -- Rendering frequency. Number of measurements per second. \ ;;; \ ;;; FFTSIZE -- FFT window size. Must be a power of 2. 4096 is recommended. : scentroid <{ file :key beg 0.0 dur #f db-floor -40.0 rfreq 100.0 fftsize 4094 -- vals }> doc" Return the spectral centroid envelope of a sound; \ RFREQ is the rendering frequency, the number of measurements per second; \ DB-FLOOR is the level below which data will be ignored." file find-file to file file unless 'no-such-file #( "%s: %s" get-func-name file ) fth-throw then file mus-sound-srate { fsr } fsr rfreq f/ fround->s { incrsamps } beg fsr f* fround->s { start } dur if dur fsr f* else file mus-sound-framples beg d- then { end } fftsize 0.0 make-vct { fdr } fftsize 0.0 make-vct { fdi } end start d- incrsamps d/ 1 d+ { windows } windows 0.0 make-vct { results } fftsize 2/ { fft2 } fsr fftsize f/ fround->s { binwidth } file make-readin { rd } 0 { loc } end start ?do rd i set-mus-location drop 0.0 { sum-of-squares } fdr map! rd readin { val } val dup f* sum-of-squares f+ to sum-of-squares val end-map sum-of-squares fftsize f/ fsqrt linear->db db-floor f>= if 0.0 0.0 { numsum densum } fdi 0.0 vct-fill! drop fdr fdi fftsize 1 mus-fft ( fdr ) fdi rectangular->polar drop fft2 0 ?do fdr i vct-ref binwidth f* i f* numsum f+ to numsum fdr i vct-ref densum f+ to densum loop results loc numsum densum f/ vct-set! drop then loc 1+ to loc incrsamps +loop results ; \ ;;; ---------------- \ ;;; \ ;;; invert-filter inverts an FIR filter \ ;;; \ ;;; say we previously filtered a sound via \ ;;; (filter-channel (vct .5 .25 .125)) \ ;;; and we want to undo it without using (undo): \ ;;; (filter-channel (invert-filter (vct .5 .25 .125))) \ ;;; \ ;;; there are a million gotchas here. The primary one is that the inverse \ ;;; filter can "explode" -- the coefficients can grow without bound. \ ;;; For example, any filter returned by spectrum->coeffs above will \ ;;; be a problem (it always returns a "linear phase" filter). : invert-filter ( fcoeffs -- res ) doc" Try to return an inverse filter to undo \ the effect of the FIR filter coeffs." { fcoeffs } fcoeffs length { flen } 32 flen + 0.0 make-vct { coeffs } coeffs length { order } flen 0 do coeffs i fcoeffs i vct-ref vct-set! drop loop order 0.0 make-vct { nfilt } nfilt 0 coeffs 0 vct-ref 1/f vct-set! drop order 1 ?do i { kk } 0.0 ( sum ) i 0 ?do nfilt i vct-ref coeffs kk vct-ref f* f+ ( sum += ... ) kk 1- to kk loop ( sum ) coeffs 0 vct-ref fnegate f/ nfilt i -rot vct-set! drop loop nfilt ; \ ;;; ---------------- \ ;;; \ ;;; Volterra filter \ ;;; \ ;;; one of the standard non-linear filters \ ;;; this version is taken from Monson Hayes "Statistical DSP and Modeling" \ ;;; it is a slight specialization of the form mentioned by J O Smith \ ;;; and others : make-volterra-filter ( acoeffs bcoeffs -- gen ) doc" Return array for use with volterra-filter, \ producing one of the standard non-linear filters." { acoeffs bcoeffs } #( acoeffs bcoeffs acoeffs length bcoeffs length max 0.0 make-vct ) ; : volterra-filter ( flt y -- val ) doc" Take FLT, an array returned by make-volterra-filter, \ and an input X, and returns the (non-linear filtered) result." { flt y } flt 0 array-ref { as } flt 1 array-ref { bs } flt 2 array-ref { xs } as length { x1len } bs length { x2len } xs length { xlen } xs xlen 1- xlen 2- #t vct-move! drop xs 0 y vct-set! drop as xs x1len dot-product ( sum ) x2len 0 ?do x2len 0 ?do bs i vct-ref xs j vct-ref f* xs i vct-ref f* f+ ( sum += ... ) loop loop ( sum ) ; \ vct( 0.5 0.1 ) vct( 0.3 0.2 0.1 ) make-volterra-filter value flt \ lambda: <{ y -- val }> flt y volterra-filter ; map-channel \ ;;; ---------------- \ ;;; \ ;;; moving-max generator (the max norm, or uniform norm, infinity-norm) : make-moving-max <{ :optional size 128 -- gen }> doc" Return moving-max generator. \ The generator keeps a running window of the last SIZE inputs, \ returning the maxamp in that window." save-stack { s } size make-delay { gen } s restore-stack gen 0.0 set-mus-scaler drop gen ; : moving-max ( gen y -- scl ) doc" Return the maxamp in a moving window over the last few inputs." { gen y } y fabs { absy } gen absy 0.0 delay { mx } absy gen mus-scaler f>= if gen absy set-mus-scaler else mx gen mus-scaler f>= if gen gen mus-data vct-peak set-mus-scaler else gen mus-scaler then then ; \ ;;; ---------------- \ ;;; \ ;;; moving-sum generator (the sum norm or 1-norm) : make-moving-sum <{ :optional size 128 -- gen }> doc" Return moving-sum generator. \ The generator keeps a running window of the last SIZE inputs, \ returning the sum of the absolute values of the samples in that window." size make-moving-average { gen } gen 1.0 set-mus-increment drop gen ; : moving-sum ( gen y -- val ) doc" Return the sum of the absolute values in a moving window over the \ last few inputs." ( gen y ) fabs moving-average ; \ ;;; ---------------- \ ;;; \ ;;; moving-rms generator : make-moving-rms <{ :optional size 128 -- gen }> doc" Return moving-rms generator. \ The generator keeps a running window of the last SIZE inputs, \ returning the rms of the samples in that window." size make-moving-average ; : moving-rms ( gen y -- val ) doc" Return the rms of the values in a window over the last few inputs." ( gen y ) dup f* moving-average fsqrt ; \ ;;; ---------------- \ ;;; \ ;;; moving-length generator (euclidean norm or 2-norm) : make-moving-length <{ :optional size 128 -- gen }> doc" Return moving-length generator. \ The generator keeps a running window of the last SIZE inputs, \ returning the euclidean length of the vector in that window." size make-moving-average { gen } gen 1.0 set-mus-increment drop gen ; : moving-length ( gen y -- val ) doc" Return the length of the values in a \ window over the last few inputs." ( gen y ) dup f* moving-average fsqrt ; \ ;;; ---------------- \ ;;; \ ;;; more moving-average cases \ \ ;;; a simple modification is to round-off the edges: <'> make-moving-average alias make-smoothing-filter : smoothing-filter ( gen sig -- r ) { gen sig } gen sig moving-average { val } gen tap { old-sig } gen mus-order { n } n n 1- f/ val gen mus-increment 0.5 f* sig old-sig f+ f* f- f* ; \ ;;; exponential weights : make-exponentially-weighted-moving-average ( order -- r ) { order } order 1/f order fnegate 1.0 order f+ f/ make-one-pole ; <'> one-pole alias exponentially-weighted-moving-average \ ;;; arithmetic (1/n) weights : make-weighted-moving-average ( order -- r ) { order } order make-moving-average { gen } gen 1.0 set-mus-increment drop #( gen 0.0 0.0 ) ; : weighted-moving-average ( gen sig -- r ) { gen-ary sig } gen-ary 0 array-ref { gen } gen-ary 1 array-ref { num } gen-ary 2 array-ref { sum } gen mus-order { n } n 1+ n * 2/ { den } n sig f* num f+ sum f- to num gen sig moving-average to sum gen-ary num 1 array-set! gen-ary sum 2 array-set! num den f/ ; \ ;;; ---------------- \ ;;; \ ;;; harmonicizer (each harmonic is split into a set of harmonics \ ;;; via Chebyshev polynomials) obviously very similar to ssb-bank \ ;;; above, but splits harmonics individually, rather than \ ;;; pitch-shifting them hide : harm-mc-cb { bands avgs peaks pcoeffs flt new-mx -- prc; y self -- val } 1 proc-create ( prc ) 40 ( ctr ) , bands , avgs , peaks , pcoeffs , flt , new-mx , does> { y self -- val } self @ { ctr } self cell+ @ { bands } self 2 cells + @ { avgs } self 3 cells + @ { peaks } self 4 cells + @ { pcoeffs } self 5 cells + @ { flt } self 6 cells + @ { new-mx } 0.0 ( sum ) bands each { bd } bd y bandpass { sig } peaks i array-ref sig moving-max { mx } avgs i array-ref mx f0> if 100.0 mx 1/f fmin else 0.0 then moving-average { amp } amp f0> if pcoeffs amp sig f* polynomial mx f* f+ ( sum += ... ) then end-each flt swap ( sum ) filter { val } val fabs new-mx fmax self 6 cells + ! ( to new-mx ) ctr 0= if val else -1 self +! ( ctr-- ) 0.0 then ; : harm-aoe-cb ( bands avgs peaks pcoeffs flt old-mx beg dur snd chn edpos -- prc; self -- val ) { bands avgs peaks pcoeffs flt old-mx beg dur snd chn edpos } 0 proc-create ( prc ) 0.0 ( new-mx ) , bands , avgs , peaks , pcoeffs , flt , old-mx , beg , dur , snd , chn , edpos , does> { self -- val } self @ { new-mx } self cell+ @ { bands } self 2 cells + @ { avgs } self 3 cells + @ { peaks } self 4 cells + @ { pcoeffs } self 5 cells + @ { flt } self 6 cells + @ { old-mx } self 7 cells + @ { beg } self 8 cells + @ { dur } self 9 cells + @ { snd } self 10 cells + @ { chn } self 11 cells + @ { edpos } bands avgs peaks pcoeffs flt new-mx harm-mc-cb beg dur snd chn edpos map-channel { retval } new-mx f0> if old-mx new-mx f/ beg dur snd chn #f scale-channel drop then { retval } ; set-current : harmonicizer <{ freq coeffs pairs :optional order 40 bw 50.0 beg 0 dur #f snd #f chn #f edpos #f -- val }> doc" Split out each harmonic and replaces it \ with the spectrum given in coeffs." pairs make-array map! i 1.0 f+ { idx } idx freq f/ { aff } idx pairs f2* f/ 1.0 f+ bw f* { bwf } aff bwf f- hz->2pi aff bwf f+ hz->2pi order make-bandpass end-map { bands } pairs make-array map! 128 make-moving-average end-map { avgs } pairs make-array map! 128 make-moving-max end-map { peaks } coeffs mus-chebyshev-first-kind partials->polynomial { pcoeffs } 2 vct( 1 -1 ) vct( 0 -0.9 ) make-filter { flt } snd chn #f maxamp { old-mx } bands avgs peaks pcoeffs flt old-mx beg dur snd chn edpos harm-aoe-cb get-func-name as-one-edit ; previous \ ;;; ---------------- \ ;;; \ ;;; linear sampling rate conversion hide : lsc-ws-cb { rd sr -- prc; self -- f } 0 proc-create ( prc ) rd next-sample , rd next-sample , 0.0 , rd , sr , does> { self -- f } self @ { last } self cell+ @ { next } self 2 cells + @ { intrp } self 3 cells + @ { rd } self 4 cells + @ { sr } 0 { samp } begin intrp { pos } pos 1.0 f>= if pos fround->s { num } num 0 ?do next to last rd next-sample to next loop pos num f- to pos then pos sr f+ to intrp samp next last f- pos f* last f+ 0 *output* out-any drop samp 1+ to samp rd sampler-at-end? until #f ; set-current : linear-src-channel <{ sr :optional snd #f chn #f -- file }> doc" Perform sampling rate conversion using linear interpolation." 0 snd chn 1 #f make-sampler { rd } rd sr lsc-ws-cb :output snd-tempnam :srate snd srate with-sound :output ws-ref { tempfile } tempfile mus-sound-framples { len } 0 len 1- tempfile snd chn #t ( trunc ) get-func-name 0 #f ( edpos ) #t ( autodel ) set-samples ; previous \ ;;; -------- spectrum displayed in various frequency scales 'snd-nogui provided? not [if] hide 0 value bark-fft-size 0 value bark-tick-function : bark ( r1 -- r2 ) { f } f 7500.0 f/ { f2 } f2 f2 f* fatan 3.5 f* 0.00076 f f* fatan 13.5 f* f+ ; : mel ( r1 -- r2 ) { f } f 700.0 f/ 1.0 f+ flog 1127.0 f* ; : erb ( r1 -- r2 ) { f } f 312.0 f+ f 14675.0 f+ f/ flog 11.17 f* 43.0 f+ ; : display-bark-fft-cb <{ snd chn -- f }> snd chn left-sample { ls } snd chn right-sample { rs } 2.0 rs ls - 1+ flog 2.0 flog f/ fceil f** fround->s { fftlen } fftlen 0<= if #f exit then ls fftlen snd chn #f channel->vct { data } snd chn transform-normalization dont-normalize <> { normalized } #t { linear } data vct? unless #f exit then data snd chn fft-window fftlen linear snd chn fft-window-beta #f normalized snd-spectrum { fft } fft vct? unless #f exit then snd srate { sr } fft vct-peak { mx } fft length { data-len } \ bark settings 20.0 bark floor { bark-low } sr f2/ bark fceil { bark-high } data-len bark-high bark-low f- f/ { bark-frqscl } data-len 0.0 make-vct { bark-data } \ mel settings 20.0 mel floor { mel-low } sr f2/ bark fceil { mel-high } data-len mel-high mel-low f- f/ { mel-frqscl } data-len 0.0 make-vct { mel-data } \ erb settings 20.0 erb floor { erb-low } sr f2/ bark fceil { erb-high } data-len erb-high erb-low f- f/ { erb-frqscl } data-len 0.0 make-vct { erb-data } fftlen to bark-fft-size fft each { val } i fftlen f/ sr f* { frq } frq bark bark-low f- bark-frqscl f* fround->s { b-bin } frq mel mel-low f- mel-frqscl f* fround->s { mel-bin } frq erb erb-low f- erb-frqscl f* fround->s { erb-bin } b-bin 0>= b-bin data-len < && if bark-data b-bin val object-set+! then mel-bin 0>= mel-bin data-len < && if mel-data mel-bin val object-set+! then erb-bin 0>= erb-bin data-len < && if erb-data erb-bin val object-set+! then end-each normalized if bark-data vct-peak { bmx } mel-data vct-peak { mmx } erb-data vct-peak { emx } mx bmx f- fabs 0.01 f> if bark-data mx bmx f/ vct-scale! drop then mx mmx f- fabs 0.01 f> if mel-data mx mmx f/ vct-scale! drop then mx emx f- fabs 0.01 f> if erb-data mx emx f/ vct-scale! drop then then #( bark-data mel-data erb-data ) "ignored" 20.0 sr f2/ 0.0 normalized if 1.0 else data-len snd chn y-zoom-slider * then snd chn #f show-bare-x-axis graph drop #f ; : scale-pos { axis-x0 axis-x1 sr2 f scale -- n } 20.0 scale execute { b20 } axis-x1 axis-x0 f- f scale execute b20 f- f* sr2 scale execute b20 f- f/ axis-x0 f+ fround->s ; : draw-bark-ticks { axis-x0 axis-x1 axis-y0 major-y0 minor-y0 tick-y0 sr2 bark-function cro snd chn } 2 snd-font ?dup-if snd chn copy-context set-current-font drop then axis-x0 tick-y0 axis-x0 major-y0 snd chn copy-context cro draw-line drop axis-x0 axis-x1 sr2 1000.0 bark-function scale-pos { i1000 } axis-x0 axis-x1 sr2 10000.0 bark-function scale-pos { i10000 } i1000 tick-y0 i1000 major-y0 snd chn copy-context cro draw-line drop i10000 tick-y0 i10000 major-y0 snd chn copy-context cro draw-line drop "20" axis-x0 major-y0 snd chn copy-context cro draw-string drop "1000" i1000 12 - major-y0 snd chn copy-context cro draw-string drop "10000" i10000 24 - major-y0 snd chn copy-context cro draw-string drop "fft size: %d" #( bark-fft-size ) string-format axis-x0 10 + axis-y0 snd chn copy-context cro draw-string drop 1000 100 do axis-x0 axis-x1 sr2 i bark-function scale-pos { i100 } i100 tick-y0 i100 minor-y0 snd chn copy-context cro draw-line drop 100 +loop 10000 2000 do axis-x0 axis-x1 sr2 i bark-function scale-pos { i1000 } i1000 tick-y0 i1000 minor-y0 snd chn copy-context cro draw-line drop 1000 +loop ; : make-bark-labels <{ snd chn -- f }> snd chn copy-context foreground-color { old-foreground-color } snd chn lisp-graph axis-info { axinfo } axinfo 10 array-ref { axis-x0 } axinfo 12 array-ref { axis-x1 } axinfo 13 array-ref { axis-y0 } axinfo 11 array-ref { axis-y1 } 15 { label-height } 8 { char-width } snd srate 2/ { sr2 } 6 { minor-tick-len } 12 { major-tick-len } axis-y1 { tick-y0 } axis-y1 minor-tick-len + { minor-y0 } axis-y1 major-tick-len + { major-y0 } 3 snd-font { bark-label-font } axis-x1 axis-x0 f- 0.45 f* axis-x0 f+ fround->s { label-pos } snd chn channel-widgets car make-cairo { cro } \ bark label/ticks bark-tick-function 0= if axis-x0 axis-x1 axis-y0 major-y0 minor-y0 tick-y0 sr2 <'> bark cro snd chn draw-bark-ticks then bark-label-font ?dup-if snd chn copy-context set-current-font drop then "bark," label-pos axis-y1 label-height + snd chn copy-context cro draw-string drop \ mel label/ticks 2 snd-color snd chn copy-context set-foreground-color drop bark-tick-function 1 = if axis-x0 axis-x1 axis-y0 major-y0 minor-y0 tick-y0 sr2 <'> mel cro snd chn draw-bark-ticks then bark-label-font ?dup-if snd chn copy-context set-current-font drop then "mel," label-pos char-width 6 * + axis-y1 label-height + snd chn copy-context cro draw-string drop \ erb label/ticks 4 snd-color snd chn copy-context set-foreground-color drop bark-tick-function 2 = if axis-x0 axis-x1 axis-y0 major-y0 minor-y0 tick-y0 sr2 <'> erb cro snd chn draw-bark-ticks then bark-label-font ?dup-if snd chn copy-context set-current-font drop then "erb" label-pos char-width 11 * + axis-y1 label-height + snd chn copy-context cro draw-string drop old-foreground-color snd chn copy-context set-foreground-color cro free-cairo drop ; : choose-bark-ticks <{ snd chn button state x y axis -- f }> axis lisp-graph = if bark-tick-function 1+ to bark-tick-function bark-tick-function 2 > if 0 to bark-tick-function then snd chn update-lisp-graph else #f then ; set-current : display-bark-fft <{ :optional off #f -- }> off unless lisp-graph-hook <'> display-bark-fft-cb add-hook! after-lisp-graph-hook <'> make-bark-labels add-hook! mouse-click-hook <'> choose-bark-ticks add-hook! sounds each { snd } snd channels 0 ?do snd i ( chn ) update-lisp-graph drop loop end-each else lisp-graph-hook <'> display-bark-fft-cb remove-hook! after-lisp-graph-hook <'> make-bark-labels remove-hook! mouse-click-hook <'> choose-bark-ticks remove-hook! sounds each { snd } snd channels 0 ?do #f snd i ( chn ) set-lisp-graph? drop loop end-each then ; previous : undisplay-bark-fft ( -- ) #t display-bark-fft ; [then] \ ;;; -------- lpc-coeffs, lpc-predict : lpc-coeffs ( data n m -- val ) doc" Return M LPC coeffients (in a vector) given N data \ points in the vct DATA." { data n m } m :initial-element 0.0 make-array { d } n :initial-element 0.0 make-array { wk1 } n :initial-element 0.0 make-array { wk2 } n :initial-element 0.0 make-array { wkm } wk1 0 data 0 vct-ref array-set! wk2 n 2- data n 1- vct-ref array-set! n 1- 1 ?do wk1 i data i vct-ref array-set! wk2 i 1- data i vct-ref array-set! loop m 0 ?do 0.0 0.0 { num denom } n i - 1- 0 ?do wk1 i array-ref wk2 i array-ref f* num f+ to num wk1 i array-ref wk2 i array-ref f* dup f* denom f+ to denom loop denom f0<> if d i num f2* denom f/ array-set! then i 0 ?do d i wkm i array-ref d j array-ref wkm j i - 1- array-ref f* f- array-set! loop i m 1- < if i 1+ 0 ?do wkm i d i array-ref array-set! loop n i - 2- 0 ?do wk1 i wk1 i array-ref wkm j array-ref wk2 i array-ref f* f- array-set! wk2 i wk2 i 1+ array-ref wkm j array-ref wk1 i 1+ array-ref f* f- array-set! loop then loop d ; : lpc-predict <{ data n coeffs m nf :optional clipped #f -- val }> doc" Take the output of lpc-coeffs (COEFFS, a vector) and \ the length thereof (M), N data points of DATA (a vct), \ and produces NF new data points (in a vct) as its prediction. \ If CLIPPED is #t, the new data is assumed to be outside -1.0 to 1.0." n 1- { jj } m 0.0 make-vct map! data jj vct-ref ( val ) jj 1- to jj end-map { reg } nf 0.0 make-vct map! 0.0 ( sum ) reg each ( val ) coeffs i array-ref f* f+ ( sum += ... ) end-each { sum } 0 m 1- do reg i reg i 1- vct-ref vct-set! drop -1 +loop clipped if sum f0> if sum 1.0 f< if 1.0 to sum then else sum -1.0 f> if -1.0 to sum then then then reg 0 sum vct-set! drop sum end-map ( future ) ; \ ;;; -------- unclip-channel hide : uncchn-sc-cb { clip-data unclipped-max -- prc; y self -- f } 1 proc-create ( prc ) clip-data , unclipped-max , 0 ( clip-beg ) , 0 ( samp ) , #f ( in-clip ) , does> { y self -- f } self @ { clip-data } self 1 cells + @ { unclipped-max } self 2 cells + @ { clip-beg } self 3 cells + @ { samp } self 4 cells + @ { in-clip } y fabs { absy } absy 0.9999 f> if in-clip unless #t to in-clip samp self 2 cells + ! ( to clip-beg ) then else absy unclipped-max fmax self 2 cells + ! ( to unclipped-max ) in-clip if #f self 4 cells + ! ( in-clip = #f ) clip-data #( clip-beg samp 1- ) array-push to clip-data then then 1 self 3 cells + +! ( samp++ ) #f ; : uncchn-aoe-cb { clip-data max-len snd chn len -- prc; self -- val } 0 proc-create ( prc ) clip-data , max-len , snd , chn , does> { self -- val } self @ { clip-data } self cell+ @ { max-len } self 2 cells + @ { snd } self 3 cells + @ { chn } self 4 cells + @ { len } 32 { min-data-len } clip-data each { lst } lst 0 array-ref { clip-beg } lst 1 array-ref { clip-end } clip-end clip-beg = 1+ { clip-len } min-data-len clip-len 4 * max { data-len } clip-len max-len > if clip-len to max-len then data-len { forward-data-len } data-len { backward-data-len } i 0= if 0 else clip-data i 1- array-ref 1 array-ref then { previous-end } i clip-data length 3 - < if clip-data i 1+ array-ref 0 array-ref else len then { next-beg } clip-beg data-len - previous-end < if clip-beg previous-end - 4 max to forward-data-len then clip-len data-len + next-beg > if next-beg clip-end - 4 max to backward-data-len then clip-len forward-data-len f2/ fround->s max { forward-predict-len } clip-len backward-data-len f2/ fround->s max { backward-predict-len } clip-beg forward-data-len - forward-data-len snd chn #f channel->vct { data } data forward-data-len data forward-data-len forward-predict-len lpc-coeffs forward-predict-len clip-len #f lpc-predict { future } clip-end 1+ backward-data-len snd chn #f channel->vct vct-reverse! { rdata } rdata backward-data-len rdata backward-data-len backward-predict-len lpc-coeffs backward-predict-len clip-len #f lpc-predict { past } clip-len 0.0 make-vct { new-data } clip-len 1 > if clip-len 1- { jj } clip-len 1- { clen } new-data map! i clen f/ pi f* fcos 1.0 f+ f2/ { sn } sn future i vct-ref f* 1.0 sn f- past jj vct-ref f* f+ jj 1- to jj end-map else new-data 0 future 0 vct-ref past 0 vct-ref future 0 vct-ref f0> if fmax else fmin then vct-set! drop then new-data clip-beg clip-len snd chn #f get-func-name vct->channel drop end-each #f ; set-current : unclip-channel <{ :optional snd #f chn #f -- assoc }> doc" Look for clipped portions and try to \ reconstruct the original using LPC." #() { clip-data } \ #( #( beg end ) #( ... ) ... ) 0.0 { unclipped-max } snd chn #f framples { len } clip-data unclipped-max uncchn-sc-cb 0 len snd chn #f scan-channel drop clip-data length 0> if 0 { max-len } clip-data max-len snd chn len uncchn-aoe-cb get-func-name as-one-edit drop unclipped-max 0.95 f> if 0.999 to unclipped-max then unclipped-max snd chn #f maxamp f/ 0 len snd chn #f scale-channel drop #a( :max unclipped-max :clips clip-data length 2/ :max-len max-len ) else #() then ; previous : unclip-sound <{ :optional snd #f -- assoc }> doc" Apply unclip-channel to each channel of SND." snd snd-snd to snd snd sound? if snd channels make-array map! snd i unclip-channel end-map ( res ) #() ( assoc ) snd channels 0 ?do ( assoc ) snd i unclip-channel assoc loop ( assoc ) else 'no-such-sound #( "%s: %s" get-func-name snd ) fth-throw then ; \ dsp.fs ends here snd-16.1/snd-ladspa.c0000644000076400007640000012751312567166644012557 0ustar bilbil/*****************************************************************************/ /* Snd LADSPA Support - Copyright 2000 Richard W.E. Furse. */ /*****************************************************************************/ #include "snd.h" #if HAVE_LADSPA #include #include #include /* * 19-Jun-07 added beg dur snd chn args to apply-ladspa. * 12-Jun-07 reader can be #f. * 1-Sep-05 moved stuff around for better error handling. * added code to handle 0-input plugins ("analog osc" in swh for example). * 21-Sep-03 added plugin help menu item. * 1-Aug-03 added direct struct readers for LADSPA_Descriptor * 21-Nov-02 better checks for C-g interrupt. * 2-May-02 use mus_long_t for sample number. * 14-Dec-01 various C++ cleanups. * 28-Nov-01 input chans need not equal output chans now. * 15-Oct-01 added some error returns (rather than snd_error). multichannel plugin support. * 20-Sep-01 changed location of pfInputBuffer to avoid glomming up the stack with a huge array. */ /*****************************************************************************/ typedef struct { char *m_pcPackedFilename; const char *m_pcLabel; const LADSPA_Descriptor *m_psDescriptor; void *m_pvPluginHandle; } LADSPAPluginInfo; /*****************************************************************************/ static char g_bLADSPAInitialised = 0; static LADSPAPluginInfo ** g_psLADSPARepository; static long g_lLADSPARepositoryCapacity; static long g_lLADSPARepositoryCount; #define LADSPA_REPOSITORY_CAPACITY_STEP 100 /*****************************************************************************/ static int lInputCount, lOutputCount; static void isLADSPAPluginSupported(const LADSPA_Descriptor *psDescriptor) { unsigned int lIndex; lInputCount = lOutputCount = 0; for (lIndex = 0; lIndex < psDescriptor->PortCount; lIndex++) { LADSPA_PortDescriptor iPortDescriptor; iPortDescriptor = psDescriptor->PortDescriptors[lIndex]; if (LADSPA_IS_PORT_AUDIO(iPortDescriptor)) { if (LADSPA_IS_PORT_INPUT(iPortDescriptor)) lInputCount++; else lOutputCount++; } } } /*****************************************************************************/ /* Assumes repository initialised, returns NULL if not found. */ static const LADSPA_Descriptor *findLADSPADescriptor(const char *pcPackedFilename, const char *pcLabel) { long lIndex; for (lIndex = 0; lIndex < g_lLADSPARepositoryCount; lIndex++) { LADSPAPluginInfo *psInfo; psInfo = g_psLADSPARepository[lIndex]; if ((mus_strcmp(pcLabel, psInfo->m_pcLabel)) && (mus_strcmp(pcPackedFilename, psInfo->m_pcPackedFilename))) return psInfo->m_psDescriptor; } return NULL; } /*****************************************************************************/ /* Allocate a new string. The string will contain a library filename, stripped of path and .so (if present) */ static char *packLADSPAFilename(const char * pcFilename) { const char *pcStart, * pcEnd; char *pcPackedFilename; /* Move start past last /, move pcEnd to end. */ pcStart = pcFilename; for (pcEnd = pcStart; *pcEnd != '\0'; pcEnd++) if (*pcEnd == '/') pcStart = pcEnd + 1; if (pcEnd - pcStart > 3) if (strcmp(".so", pcEnd - 3) == 0) pcEnd -= 3; pcPackedFilename = (char *)malloc(pcEnd - pcStart + 1); memcpy(pcPackedFilename, pcStart, pcEnd - pcStart); pcPackedFilename[pcEnd - pcStart] = '\0'; return pcPackedFilename; } /*****************************************************************************/ static void unloadLADSPA(void) { long lIndex; LADSPAPluginInfo *pvPluginHandle = NULL; if (g_lLADSPARepositoryCount > 0) pvPluginHandle = (LADSPAPluginInfo *)(g_psLADSPARepository[0]->m_pvPluginHandle); pvPluginHandle++; for (lIndex = 0; lIndex < g_lLADSPARepositoryCount; lIndex++) { LADSPAPluginInfo *psInfo; psInfo = g_psLADSPARepository[lIndex]; free(psInfo->m_pcPackedFilename); /* Don't free Label or Descriptor - this memory is owned by the relevant plugin library. */ if (pvPluginHandle != psInfo->m_pvPluginHandle) { pvPluginHandle = (LADSPAPluginInfo *)(psInfo->m_pvPluginHandle); dlclose(pvPluginHandle); } free(psInfo); } free(g_psLADSPARepository); g_bLADSPAInitialised = 0; } /*****************************************************************************/ /* Called only from within loadLADSPA->loadLADSPADirectory. */ static void loadLADSPALibrary(void *pvPluginHandle, char *pcFilename, LADSPA_Descriptor_Function fDescriptorFunction) { LADSPAPluginInfo **psOldRepository; long lNewCapacity, lIndex; const LADSPA_Descriptor *psDescriptor; for (lIndex = 0; (psDescriptor = fDescriptorFunction(lIndex)) != NULL; lIndex++) { LADSPAPluginInfo *psInfo; if (g_lLADSPARepositoryCount == g_lLADSPARepositoryCapacity) { psOldRepository = g_psLADSPARepository; lNewCapacity = (g_lLADSPARepositoryCapacity + LADSPA_REPOSITORY_CAPACITY_STEP); g_psLADSPARepository = (LADSPAPluginInfo **)malloc(lNewCapacity * sizeof(LADSPAPluginInfo *)); memcpy(g_psLADSPARepository, psOldRepository, sizeof(LADSPAPluginInfo *) * g_lLADSPARepositoryCount); g_lLADSPARepositoryCapacity = lNewCapacity; free(psOldRepository); } psInfo = g_psLADSPARepository[g_lLADSPARepositoryCount++] = (LADSPAPluginInfo *)malloc(sizeof(LADSPAPluginInfo)); psInfo->m_pcPackedFilename = packLADSPAFilename(pcFilename); psInfo->m_pcLabel = psDescriptor->Label; psInfo->m_psDescriptor = psDescriptor; psInfo->m_pvPluginHandle = pvPluginHandle; } } /*****************************************************************************/ /* Search just the one directory. Called only from within loadLADSPA. */ static void loadLADSPADirectory(const char *pcDirectory) { DIR *psDirectory; LADSPA_Descriptor_Function fDescriptorFunction; long lDirLength; long iNeedSlash; lDirLength = strlen(pcDirectory); if (!lDirLength) return; if (pcDirectory[lDirLength - 1] == '/') iNeedSlash = 0; else iNeedSlash = 1; psDirectory = opendir(pcDirectory); if (!psDirectory) return; while (true) { char *pcFilename = NULL; struct dirent *psDirectoryEntry; void *pvPluginHandle; psDirectoryEntry = readdir(psDirectory); if (!psDirectoryEntry) { closedir(psDirectory); return; } pcFilename = (char *)malloc(lDirLength + strlen(psDirectoryEntry->d_name) + 1 + iNeedSlash); strcpy(pcFilename, pcDirectory); if (iNeedSlash) strcat(pcFilename, "/"); strcat(pcFilename, psDirectoryEntry->d_name); pvPluginHandle = dlopen(pcFilename, RTLD_LAZY); if (pvPluginHandle) { /* This is a file and the file is a shared library! */ dlerror(); fDescriptorFunction = (LADSPA_Descriptor_Function)dlsym(pvPluginHandle, "ladspa_descriptor"); if (dlerror() == NULL && fDescriptorFunction) { loadLADSPALibrary(pvPluginHandle, pcFilename, fDescriptorFunction); } else { /* It was a library, but not a LADSPA one. Unload it. */ /* bil: this is not safe! Could be legit already-loaded library. */ /* dlclose(pcFilename); */ } } if (pcFilename) free(pcFilename); pcFilename = NULL; } } /*****************************************************************************/ static void loadLADSPA(void) { const char *pcEnd; const char *pcLADSPAPath; const char *pcStart; g_bLADSPAInitialised = 1; g_psLADSPARepository = (LADSPAPluginInfo **)malloc(sizeof(LADSPAPluginInfo *) * LADSPA_REPOSITORY_CAPACITY_STEP); g_lLADSPARepositoryCapacity = LADSPA_REPOSITORY_CAPACITY_STEP; g_lLADSPARepositoryCount = 0; pcLADSPAPath = ladspa_dir(ss); if (!pcLADSPAPath) { pcLADSPAPath = getenv("LADSPA_PATH"); if (pcLADSPAPath == NULL) { snd_warning("Warning: You have not set " S_ladspa_dir " or the environment variable LADSPA_PATH.\nUsing /usr/lib/ladspa instead."); pcLADSPAPath = "/usr/lib/ladspa"; } } pcStart = pcLADSPAPath; while (*pcStart != '\0') { char *pcBuffer; pcEnd = pcStart; while (*pcEnd != ':' && *pcEnd != '\0') pcEnd++; pcBuffer = (char *)malloc(1 + pcEnd - pcStart); if (pcEnd > pcStart) strncpy(pcBuffer, pcStart, pcEnd - pcStart); pcBuffer[pcEnd - pcStart] = '\0'; loadLADSPADirectory(pcBuffer); pcStart = pcEnd; if (*pcStart == ':') pcStart++; free(pcBuffer); } } /*****************************************************************************/ #if USE_MOTIF || USE_GTK static const char *ladspa_xrefs[6] = { "LADSPA overview: {LADSPA}", "info on specific plugin: {analyze-ladspa}", "apply plugin: {apply-ladspa}", "plugin directory: {" S_ladspa_dir "}", "GUI for plugins: see ladspa.scm", NULL}; #if USE_MOTIF static void ladspa_help_callback(Widget w, XtPointer info, XtPointer context) #endif #if USE_GTK static void ladspa_help_callback(GtkWidget *w, gpointer info) #endif { /* help dialog with currently loaded plugins (and descriptors), refs to list-ladspa etc */ int len = 0; long lIndex; LADSPAPluginInfo *psInfo; const LADSPA_Descriptor *psDescriptor; char *pcFilename; for (lIndex = g_lLADSPARepositoryCount - 1; lIndex >= 0; lIndex--) { psInfo = g_psLADSPARepository[lIndex]; len += mus_strlen(psInfo->m_pcPackedFilename); len += 32; len += mus_strlen((char *)(psInfo->m_pcLabel)); pcFilename = packLADSPAFilename(psInfo->m_pcPackedFilename); psDescriptor = findLADSPADescriptor(pcFilename, (char *)(psInfo->m_pcLabel)); free(pcFilename); len += mus_strlen(psDescriptor->Name); } if (len > 0) { char *desc; desc = (char *)calloc(len, sizeof(char)); for (lIndex = g_lLADSPARepositoryCount - 1; lIndex >= 0; lIndex--) { psInfo = g_psLADSPARepository[lIndex]; pcFilename = packLADSPAFilename(psInfo->m_pcPackedFilename); psDescriptor = findLADSPADescriptor(pcFilename, (char *)(psInfo->m_pcLabel)); free(pcFilename); strcat(desc, psInfo->m_pcPackedFilename); strcat(desc, ":"); strcat(desc, (char *)(psInfo->m_pcLabel)); if (psDescriptor->Name) { int name_len; name_len = strlen(psInfo->m_pcPackedFilename) + strlen((char *)(psInfo->m_pcLabel)); if (name_len < 20) { strcat(desc, ",\t"); if (name_len < 9) strcat(desc, "\t"); } else strcat(desc, " "); strcat(desc, psDescriptor->Name); } strcat(desc, "\n"); } snd_help_with_xrefs("Available plugins", desc, WITHOUT_WORD_WRAP, ladspa_xrefs, NULL); free(desc); } } #endif #define S_init_ladspa "init-ladspa" static Xen g_init_ladspa(void) { #define H_init_ladspa "(" S_init_ladspa "): reinitialise LADSPA. This is not \ normally necessary as LADSPA automatically initialises itself, however \ it can be useful when the plugins on the system have changed." if (g_bLADSPAInitialised) unloadLADSPA(); loadLADSPA(); #if USE_MOTIF { Widget m, help_menu; Arg args[12]; int n = 0; help_menu = menu_widget(4); XtSetArg(args[n], XmNbackground, ss->basic_color); n++; m = XtCreateManagedWidget("Plugins", xmPushButtonWidgetClass, help_menu, args, n); XtAddCallback(m, XmNactivateCallback, ladspa_help_callback, NULL); } #endif #if USE_GTK { GtkWidget *m, *help_menu; help_menu = get_help_menu_widget(); /* this is the cascade menu */ m = gtk_menu_item_new_with_label("Plugins"); gtk_menu_shell_append(GTK_MENU_SHELL(help_menu), m); gtk_widget_show(m); SG_SIGNAL_CONNECT(m, "activate", ladspa_help_callback, NULL); } #endif return(Xen_false); } /*****************************************************************************/ #define S_list_ladspa "list-ladspa" static Xen g_list_ladspa(void) { #define H_list_ladspa "(" S_list_ladspa "): return a list of lists containing \ information of the LADSPA plugins currently available. For each plugin a \ list containing the plugin-file and plugin-label is included." long lIndex; Xen xenList; if (!g_bLADSPAInitialised) loadLADSPA(); xenList = Xen_empty_list; for (lIndex = g_lLADSPARepositoryCount - 1; lIndex >= 0; lIndex--) { Xen xenPluginList; LADSPAPluginInfo *psInfo; psInfo = g_psLADSPARepository[lIndex]; xenPluginList = Xen_cons(C_string_to_Xen_string(psInfo->m_pcPackedFilename), Xen_cons(C_string_to_Xen_string((char *)psInfo->m_pcLabel), Xen_empty_list)); xenList = Xen_cons(xenPluginList, xenList); } return xenList; } /*****************************************************************************/ #define S_analyse_ladspa "analyse-ladspa" static Xen g_analyse_ladspa(Xen ladspa_plugin_filename, Xen ladspa_plugin_label) { #define H_analyse_ladspa "(" S_analyse_ladspa " library plugin): return a list of information about \ a LADSPA plugin. The plugin is identified by library and plugin. \ The items are: plugin-name, plugin-maker, \ plugin-copyright, plugin-parameter-list. The plugin-port-list contains a \ list of information for each parameter available. The first item in this \ list is the name of the port. Other hint information may follow this to help \ a user interface edit the parameter in a useful way." long lIndex; int inchans, outchans; const LADSPA_Descriptor *psDescriptor; char *pcFilename; const char *pcLabel, *pcTmp; Xen xenList, xenPortData; LADSPA_PortRangeHintDescriptor iHint; if (!g_bLADSPAInitialised) loadLADSPA(); Xen_check_type(Xen_is_string(ladspa_plugin_filename), ladspa_plugin_filename, 1, S_analyse_ladspa, "a string"); Xen_check_type(Xen_is_string(ladspa_plugin_label), ladspa_plugin_label, 2, S_analyse_ladspa, "a string"); /* Plugin. */ pcTmp = Xen_string_to_C_string(ladspa_plugin_filename); pcLabel = Xen_string_to_C_string(ladspa_plugin_label); pcFilename = packLADSPAFilename(pcTmp); psDescriptor = findLADSPADescriptor(pcFilename, pcLabel); free(pcFilename); if (!psDescriptor) { Xen_error(Xen_make_error_type("no-such-plugin"), Xen_list_3(C_string_to_Xen_string(S_analyse_ladspa ": no such plugin file: ~A, plugin label: ~A"), ladspa_plugin_filename, ladspa_plugin_label)); return(Xen_false); } isLADSPAPluginSupported(psDescriptor); inchans = lInputCount; outchans = lOutputCount; xenList = Xen_empty_list; for (lIndex = psDescriptor->PortCount - 1; lIndex >= 0; lIndex--) if (LADSPA_IS_PORT_CONTROL(psDescriptor->PortDescriptors[lIndex]) && LADSPA_IS_PORT_INPUT(psDescriptor->PortDescriptors[lIndex])) { iHint = psDescriptor->PortRangeHints[lIndex].HintDescriptor; xenPortData = Xen_empty_list; if (LADSPA_IS_HINT_TOGGLED(iHint)) xenPortData = Xen_cons(C_string_to_Xen_string("toggle"), xenPortData); if (LADSPA_IS_HINT_LOGARITHMIC(iHint)) xenPortData = Xen_cons(C_string_to_Xen_string("logarithmic"), xenPortData); if (LADSPA_IS_HINT_INTEGER(iHint)) xenPortData = Xen_cons(C_string_to_Xen_string("integer"), xenPortData); if (LADSPA_IS_HINT_SAMPLE_RATE(iHint)) xenPortData = Xen_cons(C_string_to_Xen_string("sample_rate"), xenPortData); if (LADSPA_IS_HINT_BOUNDED_ABOVE(iHint)) xenPortData = Xen_cons(C_string_to_Xen_string("maximum"), Xen_cons(C_double_to_Xen_real(psDescriptor->PortRangeHints[lIndex].UpperBound), xenPortData)); if (LADSPA_IS_HINT_BOUNDED_BELOW(iHint)) xenPortData = Xen_cons(C_string_to_Xen_string("minimum"), Xen_cons(C_double_to_Xen_real(psDescriptor->PortRangeHints[lIndex].LowerBound), xenPortData)); xenPortData = Xen_cons(C_string_to_Xen_string((char *)psDescriptor->PortNames[lIndex]), xenPortData); xenList = Xen_cons(xenPortData, xenList); } xenList = Xen_cons(C_string_to_Xen_string((char *)psDescriptor->Name), Xen_cons(C_string_to_Xen_string((char *)psDescriptor->Maker), Xen_cons(C_string_to_Xen_string((char *)psDescriptor->Copyright), Xen_cons(Xen_list_4(C_string_to_Xen_string("inputs:"), C_int_to_Xen_integer(inchans), C_string_to_Xen_string("outputs:"), C_int_to_Xen_integer(outchans)), Xen_cons(xenList, Xen_empty_list))))); return(xenList); } /*****************************************************************************/ #define S_apply_ladspa "apply-ladspa" static Xen g_apply_ladspa(Xen reader, Xen ladspa_plugin_configuration, Xen samples, Xen origin, Xen snd, Xen chn) /* these two args added (much) later */ { #define H_apply_ladspa "(" S_apply_ladspa " reader (list library plugin pars) dur origin :optional snd chn): apply a LADSPA plugin to process a \ sound. The parameters are soundfile-reader, a ladspa-plugin-configuration, \ the number of samples to process, and an `origin' for edit lists. The \ ladspa-plugin-configuration is a list containing the plugin-file and \ plugin-label for the LADSPA plugin, as provided by " S_list_ladspa ", followed \ by any arguments. The reader argument can also be a list of readers. \ Information about parameters can be acquired using " S_analyse_ladspa "." const LADSPA_Descriptor *psDescriptor; char *pcFilename; const char *pcLabel, *pcTmp; LADSPA_Handle *psHandle; unsigned long lSampleRate, lPortIndex, lSampleIndex; mus_long_t lAt; unsigned long lParameterCount; Xen xenParameters; LADSPA_PortDescriptor iPortDescriptor; LADSPA_Data *pfControls = NULL; chan_info *cp; snd_info *sp; char *ofile, *msg; int i, ofd, datumb, inchans = 1, readers = 0, outchans = 1; mus_long_t num; snd_fd **sf = NULL; file_info *hdr; mus_float_t **data; LADSPA_Data **pfInputBuffer = NULL; LADSPA_Data **pfOutputBuffer = NULL; io_error_t io_err = IO_NO_ERROR; snd_fd *tmp_fd; bool cp_from_reader = false; if (!g_bLADSPAInitialised) loadLADSPA(); /* First parameter should be a file reader or list thereof. */ Xen_check_type(is_sampler(reader) || Xen_is_list(reader) || Xen_is_false(reader), reader, 1, S_apply_ladspa, "a sampler, a list of readers, or " PROC_FALSE); if (Xen_is_list(reader)) readers = Xen_list_length(reader); else { if (!(Xen_is_false(reader))) readers = 1; } /* Second parameter should be a list of two strings, then any number (inc 0) of numbers. */ if ((Xen_list_length(ladspa_plugin_configuration) < 2) || (!(Xen_is_string(Xen_car(ladspa_plugin_configuration)))) || (!(Xen_is_string(Xen_cadr(ladspa_plugin_configuration))))) Xen_check_type(0, ladspa_plugin_configuration, 2, S_apply_ladspa, "a list of 2 or more strings"); /* Third parameter is the number of samples to process. */ Xen_check_type(Xen_is_number(samples), samples, 3, S_apply_ladspa, "a number"); /* Get sample count. */ num = Xen_llong_to_C_llong(samples); if (num <= 0) return(Xen_false); /* The fourth parameter is a tag to identify the edit. */ Xen_check_type(Xen_is_string(origin), origin, 4, S_apply_ladspa, "a string"); Snd_assert_channel(S_apply_ladspa, snd, chn, 5); /* Plugin. */ pcTmp = Xen_string_to_C_string(Xen_car(ladspa_plugin_configuration)); pcLabel = Xen_string_to_C_string(Xen_cadr(ladspa_plugin_configuration)); pcFilename = packLADSPAFilename(pcTmp); psDescriptor = findLADSPADescriptor(pcFilename, pcLabel); free(pcFilename); if (!psDescriptor) Xen_error(Xen_make_error_type("no-such-plugin"), Xen_list_2(C_string_to_Xen_string(S_apply_ladspa ": no such plugin: ~A"), ladspa_plugin_configuration)); isLADSPAPluginSupported(psDescriptor); inchans = lInputCount; outchans = lOutputCount; if (outchans == 0) Xen_error(Xen_make_error_type("plugin-error"), Xen_list_2(C_string_to_Xen_string(S_apply_ladspa ": plugins must have at least 1 output, ~A"), ladspa_plugin_configuration)); if (inchans != readers) { Xen errmsg; msg = mus_format("Ladspa %s required inputs (%d) != samplers (%d)", pcLabel, inchans, readers); errmsg = C_string_to_Xen_string(msg); free(msg); Xen_error(Xen_make_error_type("plugin-error"), Xen_list_3(C_string_to_Xen_string(S_apply_ladspa ": ~A, ~A"), ladspa_plugin_configuration, errmsg)); } lParameterCount = 0; for (lPortIndex = 0; lPortIndex < psDescriptor->PortCount; lPortIndex++) if (LADSPA_IS_PORT_CONTROL(psDescriptor->PortDescriptors[lPortIndex]) && LADSPA_IS_PORT_INPUT(psDescriptor->PortDescriptors[lPortIndex])) lParameterCount++; msg = mus_format("a list of 2 strings + %d parameters", (int)lParameterCount); Xen_check_type(Xen_list_length(ladspa_plugin_configuration) == (int)(2 + lParameterCount), ladspa_plugin_configuration, 2, S_apply_ladspa, msg); free(msg); pfControls = (LADSPA_Data *)malloc(psDescriptor->PortCount * sizeof(LADSPA_Data)); if (Xen_is_bound(snd)) cp = get_cp(snd, chn, S_apply_ladspa); else { if (inchans > 0) { if (Xen_is_list(reader)) tmp_fd = xen_to_sampler(Xen_list_ref(reader, 0)); else tmp_fd = xen_to_sampler(reader); cp = tmp_fd->cp; cp_from_reader = true; } else cp = selected_channel(); } sp = cp->sound; /* Get parameters. */ xenParameters = Xen_copy_arg(Xen_cdr(Xen_cdr(ladspa_plugin_configuration))); for (lPortIndex = 0; lPortIndex < psDescriptor->PortCount; lPortIndex++) { iPortDescriptor = psDescriptor->PortDescriptors[lPortIndex]; if (LADSPA_IS_PORT_CONTROL(iPortDescriptor) && LADSPA_IS_PORT_INPUT(iPortDescriptor)) { Xen_check_type(Xen_is_number(Xen_car(xenParameters)), ladspa_plugin_configuration, 2, S_apply_ladspa, "a number"); pfControls[lPortIndex] = (LADSPA_Data)Xen_real_to_C_double(Xen_car(xenParameters)); xenParameters = Xen_cdr(xenParameters); } } lSampleRate = (unsigned long)(sp->hdr->srate); psHandle = (LADSPA_Handle *)psDescriptor->instantiate(psDescriptor, lSampleRate); if (!psHandle) Xen_error(Xen_make_error_type("plugin-error"), Xen_list_2(C_string_to_Xen_string(S_apply_ladspa ": ~A plugin did not instantiate"), ladspa_plugin_configuration)); /* Temporary file name. */ ofile = snd_tempnam(); /* Create initial header for output file */ hdr = make_temp_header(ofile, snd_srate(sp), outchans, num, Xen_string_to_C_string(origin)); /* Open the output file, using the header we've been working on. */ ofd = open_temp_file(ofile, outchans, hdr, &io_err); if (io_err != IO_NO_ERROR) { if (ofd == -1) { free_file_info(hdr); if (pfControls) free(pfControls); psDescriptor->cleanup(psHandle); Xen_error(CANNOT_SAVE, Xen_list_3(C_string_to_Xen_string(S_apply_ladspa ": can't save ~S, ~A"), C_string_to_Xen_string(ofile), C_string_to_Xen_string(snd_io_strerror()))); return(Xen_false); } snd_warning("%s %s: %s", S_apply_ladspa, ofile, io_error_name(io_err)); } /* Tidy up header. */ datumb = mus_bytes_per_sample(hdr->sample_type); if (readers > 0) { sf = (snd_fd **)calloc(readers, sizeof(snd_fd *)); /* Local version of sound descriptor. */ if (Xen_is_list(reader)) { for (i = 0; i < readers; i++) if (!(Xen_is_false(Xen_list_ref(reader, i)))) sf[i] = xen_to_sampler(Xen_list_ref(reader, i)); } else sf[0] = xen_to_sampler(reader); } /* this code added 20-Sep-01 */ if (inchans > 0) { pfInputBuffer = (LADSPA_Data **)calloc(inchans, sizeof(LADSPA_Data *)); for (i = 0; i < inchans; i++) pfInputBuffer[i] = (LADSPA_Data *)calloc(MAX_BUFFER_SIZE, sizeof(LADSPA_Data)); } pfOutputBuffer = (LADSPA_Data **)calloc(outchans, sizeof(LADSPA_Data *)); for (i = 0; i < outchans; i++) pfOutputBuffer[i] = (LADSPA_Data *)calloc(MAX_BUFFER_SIZE, sizeof(LADSPA_Data)); data = (mus_float_t **)calloc(outchans, sizeof(mus_float_t *)); for (i = 0; i < outchans; i++) data[i] = (mus_float_t *)calloc(MAX_BUFFER_SIZE, sizeof(mus_float_t)); /* Connect input and output control ports. */ { int inc = 0, outc = 0; for (lPortIndex = 0; lPortIndex < psDescriptor->PortCount; lPortIndex++) { if (LADSPA_IS_PORT_CONTROL(psDescriptor->PortDescriptors[lPortIndex])) { psDescriptor->connect_port(psHandle, lPortIndex, pfControls + lPortIndex); /* (Output control data is quietly lost.) */ } else /* AUDIO */ { if (LADSPA_IS_PORT_INPUT(psDescriptor->PortDescriptors[lPortIndex])) psDescriptor->connect_port(psHandle, lPortIndex, pfInputBuffer[inc++]); else psDescriptor->connect_port(psHandle, lPortIndex, pfOutputBuffer[outc++]); } } } if (psDescriptor->activate) psDescriptor->activate(psHandle); lAt = 0; ss->stopped_explicitly = false; while (lAt < num) { int err; unsigned long lBlockSize; /* Decide how much audio to process this frame. */ lBlockSize = num - lAt; if (lBlockSize > MAX_BUFFER_SIZE) lBlockSize = MAX_BUFFER_SIZE; /* Prepare the input data. */ if (readers > 0) for (i = 0; i < readers; i++) { if (sf[i]) { for (lSampleIndex = 0; lSampleIndex < lBlockSize; lSampleIndex++) pfInputBuffer[i][lSampleIndex] = read_sample(sf[i]); } else { for (lSampleIndex = 0; lSampleIndex < lBlockSize; lSampleIndex++) pfInputBuffer[i][lSampleIndex] = 0.0; } } /* Run the plugin. */ psDescriptor->run(psHandle, lBlockSize); /* Prepare the output data. */ for (i = 0; i < outchans; i++) for (lSampleIndex = 0; lSampleIndex < lBlockSize; lSampleIndex++) data[i][lSampleIndex] = (pfOutputBuffer[i][lSampleIndex]); /* Send the output data to the outside world. */ err = mus_file_write(ofd, 0, lBlockSize - 1, outchans, data); if (err != MUS_NO_ERROR) break; if (ss->stopped_explicitly) break; lAt += lBlockSize; } if (psDescriptor->deactivate) psDescriptor->deactivate(psHandle); psDescriptor->cleanup(psHandle); close_temp_file(ofile, ofd, hdr->type, num * datumb * outchans); /* Discard tmp header. */ hdr = free_file_info(hdr); if (!(ss->stopped_explicitly)) { int j; if (outchans > 1) remember_temp(ofile, outchans); for (i = 0, j = 0; i < outchans; i++) { chan_info *ncp; mus_long_t beg; if ((cp_from_reader) && (sf) && (sf[j])) { ncp = sf[j]->cp; beg = sf[j]->initial_samp; } else { beg = 0; if (i < sp->nchans) ncp = sp->chans[i]; else break; } if (file_change_samples(beg, num, ofile, ncp, i, (outchans > 1) ? MULTICHANNEL_DELETION : DELETE_ME, Xen_string_to_C_string(origin), ncp->edit_ctr)) update_graph(ncp); j++; if (j >= inchans) j = 0; } } else { status_report(sp, S_apply_ladspa " interrupted"); ss->stopped_explicitly = false; } if (ofile) free(ofile); if (inchans > 0) { for (i = 0; i < inchans; i++) free(pfInputBuffer[i]); free(pfInputBuffer); } /* sf[i] is directly from scheme, so it will presumably handle reader gc */ for (i = 0; i < outchans; i++) { free(pfOutputBuffer[i]); free(data[i]); } free(pfOutputBuffer); if (sf) free(sf); if (pfControls) free(pfControls); free(data); return(Xen_false); } #if HAVE_EXTENSION_LANGUAGE #if HAVE_SCHEME #define FIELD_PREFIX "." #endif #if HAVE_RUBY #define FIELD_PREFIX "R" #endif #if HAVE_FORTH #define FIELD_PREFIX "F" #endif #if HAVE_SCHEME #define DEFINE_INTEGER(Name) s7_define_constant(s7, #Name, C_int_to_Xen_integer(Name)) #else #define DEFINE_INTEGER(Name) Xen_define(#Name, C_int_to_Xen_integer(Name)) #endif #define DEFINE_READER(Name, Value, Doc) Xen_define_procedure(FIELD_PREFIX #Name, Value, 1, 0, 0, Doc) #define C_to_Xen_Ladspa_Descriptor(Value) \ ((Value) ? Xen_list_2(C_string_to_Xen_symbol("Ladspa-Descriptor"), Xen_wrap_C_pointer(Value)) : Xen_false) #define Xen_to_C_Ladspa_Descriptor(Value) ((LADSPA_Descriptor *)(Xen_unwrap_C_pointer(Xen_cadr(Value)))) #define Xen_is_Ladspa_Descriptor(Value) (Xen_is_list(Value) && (Xen_list_length(Value) >= 2) && (Xen_is_symbol(Xen_car(Value))) && \ (strcmp("Ladspa-Descriptor", Xen_symbol_to_C_string(Xen_car(Value))) == 0)) #define C_to_Xen_Ladspa_Handle(Value) \ ((Value) ? Xen_list_2(C_string_to_Xen_symbol("Ladspa-Handle"), Xen_wrap_C_pointer(Value)) : Xen_false) #define Xen_to_C_Ladspa_Handle(Value) ((LADSPA_Handle *)(Xen_unwrap_C_pointer(Xen_cadr(Value)))) #define Xen_is_Ladspa_Handle(Value) (Xen_is_list(Value) && (Xen_list_length(Value) >= 2) && (Xen_is_symbol(Xen_car(Value))) && \ (strcmp("Ladspa-Handle", Xen_symbol_to_C_string(Xen_car(Value))) == 0)) #define S_ladspa_descriptor "ladspa-descriptor" static Xen g_ladspa_descriptor(Xen ladspa_plugin_filename, Xen ladspa_plugin_label) { #define H_ladspa_descriptor "(" S_ladspa_descriptor " library plugin): return the descriptor \ associated with the given plugin." const LADSPA_Descriptor *psDescriptor; char *pcFilename; const char *pcLabel, *pcTmp; if (!g_bLADSPAInitialised) loadLADSPA(); Xen_check_type(Xen_is_string(ladspa_plugin_filename), ladspa_plugin_filename, 1, S_ladspa_descriptor, "a string"); Xen_check_type(Xen_is_string(ladspa_plugin_label), ladspa_plugin_label, 2, S_ladspa_descriptor, "a string"); pcTmp = Xen_string_to_C_string(ladspa_plugin_filename); pcLabel = Xen_string_to_C_string(ladspa_plugin_label); pcFilename = packLADSPAFilename(pcTmp); psDescriptor = findLADSPADescriptor(pcFilename, pcLabel); free(pcFilename); if (!psDescriptor) return(Xen_false); return(C_to_Xen_Ladspa_Descriptor(psDescriptor)); } static Xen g_ladspa_Label(Xen ptr) { #define H_ladspa_Label "(" FIELD_PREFIX "Label descriptor): plugin identifier" Xen_check_type(Xen_is_Ladspa_Descriptor(ptr), ptr, 1, FIELD_PREFIX "Label", "Ladspa descriptor"); return(C_string_to_Xen_string((Xen_to_C_Ladspa_Descriptor(ptr))->Label)); } static Xen g_ladspa_Name(Xen ptr) { #define H_ladspa_Name "(" FIELD_PREFIX "Name descriptor): name of plugin" Xen_check_type(Xen_is_Ladspa_Descriptor(ptr), ptr, 1, FIELD_PREFIX "Name", "Ladspa descriptor"); return(C_string_to_Xen_string((Xen_to_C_Ladspa_Descriptor(ptr))->Name)); } static Xen g_ladspa_Copyright(Xen ptr) { #define H_ladspa_Copyright "(" FIELD_PREFIX "Copyright descriptor): plugin copyright or 'None'" Xen_check_type(Xen_is_Ladspa_Descriptor(ptr), ptr, 1, FIELD_PREFIX "Copyright", "Ladspa descriptor"); return(C_string_to_Xen_string((Xen_to_C_Ladspa_Descriptor(ptr))->Copyright)); } static Xen g_ladspa_Maker(Xen ptr) { #define H_ladspa_Maker "(" FIELD_PREFIX "Maker descriptor): plugin developer" Xen_check_type(Xen_is_Ladspa_Descriptor(ptr), ptr, 1, FIELD_PREFIX "Maker", "Ladspa descriptor"); return(C_string_to_Xen_string((Xen_to_C_Ladspa_Descriptor(ptr))->Maker)); } static Xen g_ladspa_Properties(Xen ptr) { #define H_ladspa_Properties "(" FIELD_PREFIX "Properties descriptor): plugin properties" Xen_check_type(Xen_is_Ladspa_Descriptor(ptr), ptr, 1, FIELD_PREFIX "Properties", "Ladspa descriptor"); return(C_int_to_Xen_integer((Xen_to_C_Ladspa_Descriptor(ptr))->Properties)); } static Xen g_ladspa_UniqueID(Xen ptr) { #define H_ladspa_UniqueID "(" FIELD_PREFIX "UniqueID descriptor): plugin ID number" Xen_check_type(Xen_is_Ladspa_Descriptor(ptr), ptr, 1, FIELD_PREFIX "UniqueID", "Ladspa descriptor"); return(C_int_to_Xen_integer((Xen_to_C_Ladspa_Descriptor(ptr))->UniqueID)); } static Xen g_ladspa_PortCount(Xen ptr) { #define H_ladspa_PortCount "(" FIELD_PREFIX "PortCount descriptor): plugin input and output port count" Xen_check_type(Xen_is_Ladspa_Descriptor(ptr), ptr, 1, FIELD_PREFIX "PortCount", "Ladspa descriptor"); return(C_int_to_Xen_integer((Xen_to_C_Ladspa_Descriptor(ptr))->PortCount)); } static Xen g_ladspa_PortDescriptors(Xen ptr) { #define H_ladspa_PortDescriptors "(" FIELD_PREFIX "PortDescriptors descriptor): plugin port descriptors (an array of ints)" LADSPA_Descriptor *descriptor; int i, len; Xen lst = Xen_empty_list; Xen_check_type(Xen_is_Ladspa_Descriptor(ptr), ptr, 1, FIELD_PREFIX "PortDescriptors", "Ladspa descriptor"); descriptor = Xen_to_C_Ladspa_Descriptor(ptr); len = descriptor->PortCount; for (i = len - 1; i >= 0; i--) lst = Xen_cons(C_int_to_Xen_integer(descriptor->PortDescriptors[i]), lst); return(lst); } static Xen g_ladspa_PortRangeHints(Xen ptr) { #define H_ladspa_PortRangeHints "(" FIELD_PREFIX "PortRangeHints descriptor): plugin port hints" LADSPA_Descriptor *descriptor; int i, len; Xen lst = Xen_empty_list; Xen_check_type(Xen_is_Ladspa_Descriptor(ptr), ptr, 1, FIELD_PREFIX "PortRangeHints", "Ladspa descriptor"); descriptor = Xen_to_C_Ladspa_Descriptor(ptr); len = descriptor->PortCount; for (i = len - 1; i >= 0; i--) lst = Xen_cons(Xen_list_3(C_int_to_Xen_integer(descriptor->PortRangeHints[i].HintDescriptor), C_double_to_Xen_real(descriptor->PortRangeHints[i].LowerBound), C_double_to_Xen_real(descriptor->PortRangeHints[i].UpperBound)), lst); return(lst); } static Xen g_ladspa_PortNames(Xen ptr) { #define H_ladspa_PortNames "(" FIELD_PREFIX "PortNames descriptor): plugin descriptive port names" LADSPA_Descriptor *descriptor; int i, len; Xen lst = Xen_empty_list; Xen_check_type(Xen_is_Ladspa_Descriptor(ptr), ptr, 1, FIELD_PREFIX "PortNames", "Ladspa descriptor"); descriptor = Xen_to_C_Ladspa_Descriptor(ptr); len = descriptor->PortCount; for (i = len - 1; i >= 0; i--) lst = Xen_cons(C_string_to_Xen_string(descriptor->PortNames[i]), lst); return(lst); } #define S_ladspa_instantiate "ladspa-instantiate" static Xen g_ladspa_instantiate(Xen ptr, Xen srate) { #define H_ladspa_instantiate "(" S_ladspa_instantiate " descriptor srate): run plugin's instantiate function, return handle" const LADSPA_Descriptor *descriptor; LADSPA_Handle handle; Xen_check_type(Xen_is_Ladspa_Descriptor(ptr), ptr, 1, S_ladspa_instantiate, "Ladspa descriptor"); Xen_check_type(Xen_is_ulong(srate), srate, 2, S_ladspa_instantiate, "int"); descriptor = Xen_to_C_Ladspa_Descriptor(ptr); handle = descriptor->instantiate(descriptor, Xen_ulong_to_C_ulong(srate)); return(C_to_Xen_Ladspa_Handle(handle)); } #define S_ladspa_activate "ladspa-activate" static Xen g_ladspa_activate(Xen desc, Xen ptr) { #define H_ladspa_activate "(" S_ladspa_activate " descriptor handle): run plugin's activate function" const LADSPA_Descriptor *descriptor; Xen_check_type(Xen_is_Ladspa_Descriptor(desc), desc, 1, S_ladspa_activate, "Ladspa descriptor"); Xen_check_type(Xen_is_Ladspa_Handle(ptr), ptr, 2, S_ladspa_activate, "Ladspa handle"); descriptor = Xen_to_C_Ladspa_Descriptor(desc); if (descriptor->activate) descriptor->activate(Xen_to_C_Ladspa_Handle(ptr)); return(Xen_false); } #define S_ladspa_deactivate "ladspa-deactivate" static Xen g_ladspa_deactivate(Xen desc, Xen ptr) { #define H_ladspa_deactivate "(" S_ladspa_deactivate " descriptor handle): run plugin's deactivate function" const LADSPA_Descriptor *descriptor; Xen_check_type(Xen_is_Ladspa_Descriptor(desc), desc, 1, S_ladspa_deactivate, "Ladspa descriptor"); Xen_check_type(Xen_is_Ladspa_Handle(ptr), ptr, 2, S_ladspa_deactivate, "Ladspa handle"); descriptor = Xen_to_C_Ladspa_Descriptor(desc); if (descriptor->deactivate) descriptor->deactivate(Xen_to_C_Ladspa_Handle(ptr)); return(Xen_false); } #define S_ladspa_cleanup "ladspa-cleanup" static Xen g_ladspa_cleanup(Xen desc, Xen ptr) { #define H_ladspa_cleanup "(" S_ladspa_cleanup " descriptor handle): run plugin's cleanup function" const LADSPA_Descriptor *descriptor; Xen_check_type(Xen_is_Ladspa_Descriptor(desc), desc, 1, S_ladspa_cleanup, "Ladspa descriptor"); Xen_check_type(Xen_is_Ladspa_Handle(ptr), ptr, 2, S_ladspa_cleanup, "Ladspa handle"); descriptor = Xen_to_C_Ladspa_Descriptor(desc); if (descriptor->cleanup) descriptor->cleanup(Xen_to_C_Ladspa_Handle(ptr)); return(Xen_false); } #define S_ladspa_run "ladspa-run" static Xen g_ladspa_run(Xen desc, Xen ptr, Xen count) { #define H_ladspa_run "(" S_ladspa_run " descriptor handle count): run plugin's run function" const LADSPA_Descriptor *descriptor; Xen_check_type(Xen_is_Ladspa_Descriptor(desc), desc, 1, S_ladspa_run, "Ladspa descriptor"); Xen_check_type(Xen_is_Ladspa_Handle(ptr), ptr, 2, S_ladspa_run, "Ladspa handle"); Xen_check_type(Xen_is_ulong(count), count, 3, S_ladspa_run, "unsigned long"); descriptor = Xen_to_C_Ladspa_Descriptor(desc); if (descriptor->run) descriptor->run(Xen_to_C_Ladspa_Handle(ptr), Xen_ulong_to_C_ulong(count)); return(Xen_false); } #define S_ladspa_run_adding "ladspa-run-adding" static Xen g_ladspa_run_adding(Xen desc, Xen ptr, Xen count) { #define H_ladspa_run_adding "(" S_ladspa_run_adding " descriptor handle count): run plugin's run_adding function" const LADSPA_Descriptor *descriptor; Xen_check_type(Xen_is_Ladspa_Descriptor(desc), desc, 1, S_ladspa_run_adding, "Ladspa descriptor"); Xen_check_type(Xen_is_Ladspa_Handle(ptr), ptr, 2, S_ladspa_run_adding, "Ladspa handle"); Xen_check_type(Xen_is_ulong(count), count, 3, S_ladspa_run_adding, "unsigned long"); descriptor = Xen_to_C_Ladspa_Descriptor(desc); if (descriptor->run_adding) descriptor->run_adding(Xen_to_C_Ladspa_Handle(ptr), Xen_ulong_to_C_ulong(count)); return(Xen_false); } #define S_ladspa_set_run_adding_gain "ladspa-set-run-adding-gain" static Xen g_ladspa_set_run_adding_gain(Xen desc, Xen ptr, Xen gain) { #define H_ladspa_set_run_adding_gain "(" S_ladspa_set_run_adding_gain " descriptor handle gain): run plugin's set_run_adding_gain function" const LADSPA_Descriptor *descriptor; Xen_check_type(Xen_is_Ladspa_Descriptor(desc), desc, 1, S_ladspa_set_run_adding_gain, "Ladspa descriptor"); Xen_check_type(Xen_is_Ladspa_Handle(ptr), ptr, 2, S_ladspa_set_run_adding_gain, "Ladspa handle"); Xen_check_type(Xen_is_double(gain), gain, 3, S_ladspa_set_run_adding_gain, "float"); descriptor = Xen_to_C_Ladspa_Descriptor(desc); if (descriptor->set_run_adding_gain) descriptor->set_run_adding_gain(Xen_to_C_Ladspa_Handle(ptr), (LADSPA_Data)(Xen_real_to_C_double(gain))); return(Xen_false); } static float *double_to_float(mus_float_t *data, int data_size) { float *ldata; int i; ldata = (float *)calloc(data_size, sizeof(float)); for (i = 0; i < data_size; i++) ldata[i] = (float)(data[i]); return(ldata); } #define S_ladspa_connect_port "ladspa-connect-port" static Xen g_ladspa_connect_port(Xen desc, Xen ptr, Xen port, Xen data) { #define H_ladspa_connect_port "(" S_ladspa_connect_port " descriptor handle port data): run plugin's connect_port function" const LADSPA_Descriptor *descriptor; vct *samples; Xen_check_type(Xen_is_Ladspa_Descriptor(desc), desc, 1, S_ladspa_connect_port, "Ladspa descriptor"); Xen_check_type(Xen_is_Ladspa_Handle(ptr), ptr, 2, S_ladspa_connect_port, "Ladspa handle"); Xen_check_type(Xen_is_ulong(port), port, 3, S_ladspa_connect_port, "unsigned long"); Xen_check_type(mus_is_vct(data), data, 4, S_ladspa_connect_port, S_vct); descriptor = Xen_to_C_Ladspa_Descriptor(desc); samples = Xen_to_vct(data); if (descriptor->connect_port) descriptor->connect_port(Xen_to_C_Ladspa_Handle(ptr), Xen_ulong_to_C_ulong(port), double_to_float(mus_vct_data(samples), mus_vct_length(samples)) ); return(Xen_false); } Xen_wrap_2_args(g_analyse_ladspa_w, g_analyse_ladspa) Xen_wrap_2_args(g_ladspa_descriptor_w, g_ladspa_descriptor) Xen_wrap_6_optional_args(g_apply_ladspa_w, g_apply_ladspa) Xen_wrap_no_args(g_init_ladspa_w, g_init_ladspa) Xen_wrap_no_args(g_list_ladspa_w, g_list_ladspa) Xen_wrap_1_arg(g_ladspa_Label_w, g_ladspa_Label) Xen_wrap_1_arg(g_ladspa_Name_w, g_ladspa_Name) Xen_wrap_1_arg(g_ladspa_Copyright_w, g_ladspa_Copyright) Xen_wrap_1_arg(g_ladspa_Maker_w, g_ladspa_Maker) Xen_wrap_1_arg(g_ladspa_Properties_w, g_ladspa_Properties) Xen_wrap_1_arg(g_ladspa_UniqueID_w, g_ladspa_UniqueID) Xen_wrap_1_arg(g_ladspa_PortNames_w, g_ladspa_PortNames) Xen_wrap_1_arg(g_ladspa_PortDescriptors_w, g_ladspa_PortDescriptors) Xen_wrap_1_arg(g_ladspa_PortRangeHints_w, g_ladspa_PortRangeHints) Xen_wrap_1_arg(g_ladspa_PortCount_w, g_ladspa_PortCount) Xen_wrap_2_args(g_ladspa_instantiate_w, g_ladspa_instantiate) Xen_wrap_2_args(g_ladspa_activate_w, g_ladspa_activate) Xen_wrap_2_args(g_ladspa_deactivate_w, g_ladspa_deactivate) Xen_wrap_2_args(g_ladspa_cleanup_w, g_ladspa_cleanup) Xen_wrap_3_args(g_ladspa_run_w, g_ladspa_run) Xen_wrap_3_args(g_ladspa_run_adding_w, g_ladspa_run_adding) Xen_wrap_3_args(g_ladspa_set_run_adding_gain_w, g_ladspa_set_run_adding_gain) Xen_wrap_4_args(g_ladspa_connect_port_w, g_ladspa_connect_port) void g_ladspa_to_snd(void) { Xen_define_procedure(S_analyse_ladspa, g_analyse_ladspa_w, 2, 0, 0, H_analyse_ladspa); /* British spelling not used anywhere else, so why here? */ Xen_define_procedure("analyze-ladspa", g_analyse_ladspa_w, 2, 0, 0, H_analyse_ladspa); Xen_define_procedure(S_apply_ladspa, g_apply_ladspa_w, 4, 2, 0, H_apply_ladspa); Xen_define_procedure(S_init_ladspa, g_init_ladspa_w, 0, 0, 0, H_init_ladspa); Xen_define_procedure(S_list_ladspa, g_list_ladspa_w, 0, 0, 0, H_list_ladspa); Xen_define_procedure(S_ladspa_descriptor, g_ladspa_descriptor_w, 2, 0, 0, H_ladspa_descriptor); DEFINE_INTEGER(LADSPA_PROPERTY_REALTIME); DEFINE_INTEGER(LADSPA_PROPERTY_INPLACE_BROKEN); DEFINE_INTEGER(LADSPA_PROPERTY_HARD_RT_CAPABLE); DEFINE_INTEGER(LADSPA_PORT_INPUT); DEFINE_INTEGER(LADSPA_PORT_OUTPUT); DEFINE_INTEGER(LADSPA_PORT_CONTROL); DEFINE_INTEGER(LADSPA_PORT_AUDIO); DEFINE_INTEGER(LADSPA_HINT_BOUNDED_BELOW); DEFINE_INTEGER(LADSPA_HINT_BOUNDED_ABOVE); DEFINE_INTEGER(LADSPA_HINT_TOGGLED); DEFINE_INTEGER(LADSPA_HINT_SAMPLE_RATE); DEFINE_INTEGER(LADSPA_HINT_LOGARITHMIC); DEFINE_INTEGER(LADSPA_HINT_INTEGER); #ifdef LADSPA_HINT_DEFAULT_MASK DEFINE_INTEGER(LADSPA_HINT_DEFAULT_MASK); DEFINE_INTEGER(LADSPA_HINT_DEFAULT_NONE); DEFINE_INTEGER(LADSPA_HINT_DEFAULT_MINIMUM); DEFINE_INTEGER(LADSPA_HINT_DEFAULT_LOW); DEFINE_INTEGER(LADSPA_HINT_DEFAULT_MIDDLE); DEFINE_INTEGER(LADSPA_HINT_DEFAULT_HIGH); DEFINE_INTEGER(LADSPA_HINT_DEFAULT_MAXIMUM); DEFINE_INTEGER(LADSPA_HINT_DEFAULT_0); DEFINE_INTEGER(LADSPA_HINT_DEFAULT_1); DEFINE_INTEGER(LADSPA_HINT_DEFAULT_100); DEFINE_INTEGER(LADSPA_HINT_DEFAULT_440); #endif DEFINE_READER(Label, g_ladspa_Label_w, H_ladspa_Label); DEFINE_READER(Name, g_ladspa_Name_w, H_ladspa_Name); DEFINE_READER(Copyright, g_ladspa_Copyright_w, H_ladspa_Copyright); DEFINE_READER(Maker, g_ladspa_Maker_w, H_ladspa_Maker); DEFINE_READER(Properties, g_ladspa_Properties_w, H_ladspa_Properties); DEFINE_READER(UniqueID, g_ladspa_UniqueID_w, H_ladspa_UniqueID); DEFINE_READER(PortNames, g_ladspa_PortNames_w, H_ladspa_PortNames); DEFINE_READER(PortDescriptors, g_ladspa_PortDescriptors_w, H_ladspa_PortDescriptors); DEFINE_READER(PortRangeHints, g_ladspa_PortRangeHints_w, H_ladspa_PortRangeHints); DEFINE_READER(PortCount, g_ladspa_PortCount_w, H_ladspa_PortCount); Xen_define_procedure(S_ladspa_instantiate, g_ladspa_instantiate_w, 2, 0, 0, H_ladspa_instantiate); Xen_define_procedure(S_ladspa_activate, g_ladspa_activate_w, 2, 0, 0, H_ladspa_activate); Xen_define_procedure(S_ladspa_deactivate, g_ladspa_deactivate_w, 2, 0, 0, H_ladspa_deactivate); Xen_define_procedure(S_ladspa_cleanup, g_ladspa_cleanup_w, 2, 0, 0, H_ladspa_cleanup); Xen_define_procedure(S_ladspa_run, g_ladspa_run_w, 3, 0, 0, H_ladspa_run); Xen_define_procedure(S_ladspa_run_adding, g_ladspa_run_adding_w, 3, 0, 0, H_ladspa_run_adding); Xen_define_procedure(S_ladspa_set_run_adding_gain, g_ladspa_set_run_adding_gain_w, 3, 0, 0, H_ladspa_set_run_adding_gain); Xen_define_procedure(S_ladspa_connect_port, g_ladspa_connect_port_w, 4, 0, 0, H_ladspa_connect_port); Xen_provide_feature("snd-ladspa"); } #endif #endif snd-16.1/play.scm0000644000076400007640000001652512551514311012013 0ustar bilbil;;; most of this file is obsolete. ;;; ;;; playing-related examples previously scattered around at random ;;; ;;; play-sound func -- play current sound, calling (func data) on each buffer if func is passed ;;; play-often, play-until-c-g -- play sound n times or until C-g is typed ;;; play-region-forever -- play region over and over until C-g typed ;;; loop-between-marks -- play while looping continuously between two movable marks ;;; start-dac -- hold DAC open and play sounds via keyboard ;;; "vector synthesis" ;;; play-with-amps -- play channels with individually settable amps ;;; play-sine and play-sines -- produce tones direct to DAC ;;; see also play-syncd-marks and play-between-marks in marks.scm (provide 'snd-play.scm) #| (define* (open-play-output out-chans out-srate out-format out-bufsize) ;; returns (list audio-fd chans frames) (let* ((outchans (or out-chans 1)) (cur-srate (or out-srate (and (pair? (sounds)) (srate)) 22050)) (pframes (or out-bufsize 256)) (frm (or out-format (if (little-endian?) mus-lshort mus-bshort))) (outbytes (* pframes 2)) ; 2 here since we'll first try to send short (16-bit) data to the DAC (audio-fd ;; ALSA throws an error where the rest of the audio cases simply report failure ;; so we turn off the "error" printout, catch the error itself, and toss it (let ((no-error (null? (hook-functions mus-error-hook)))) (if no-error (hook-push mus-error-hook (lambda (hook) (set! (hook 'result) #t)))) (let ((val (catch #t (lambda () (mus-audio-open-output 0 cur-srate outchans frm outbytes)) (lambda args -1)))) ; -1 returned in case of error (if no-error (set! (hook-functions mus-error-hook) ())) val)))) (if (not (= audio-fd -1)) (set! (dac-size) outbytes)) (list audio-fd outchans pframes))) (define play-sound (let ((documentation "(play-sound func) plays the currently selected sound, calling func on each data buffer, if func exists (mono only)")) (lambda* (func) (if (pair? (sounds)) (let* ((filechans (chans)) (audio-info (open-play-output filechans (srate) #f 256)) (audio-fd (car audio-info)) ;; (outchans (cadr audio-info)) (pframes (caddr audio-info))) (if (not (= audio-fd -1)) (let ((len (framples))) (do ((beg 0 (+ beg pframes))) ((> beg len)) (mus-audio-write audio-fd (make-shared-vector (func (channel->float-vector beg pframes)) (list 1 pframes)) pframes)) (mus-audio-close audio-fd)) (snd-print ";could not open dac"))) (snd-print ";no sounds open"))))) ;; (play-sound (lambda (data) (float-vector-scale! data 2.0) data)) ;; this could also be done with a function argument to the play function -- get a ;; sampler for the sound, call it on each invocation of the argument function etc |# ;;; -------- play sound n times -- (play-often 3) for example. (define play-often (let ((documentation "(play-often n) plays the selected sound 'n' times (interruptible via C-g)")) (lambda (n) (let ((plays (- n 1))) (define (play-once reason) (if (and (> plays 0) (= reason 0)) (begin (set! plays (- plays 1)) (play (selected-sound) :start 0 :stop play-once)))) (play (selected-sound) :start 0 :stop play-once))))) ;;(bind-key #\p 0 (lambda (n) "play often" (play-often (max 1 n)))) ;;; -------- play sound until c-g (define play-until-c-g (let ((documentation "(play-until-c-g) plays the selected sound until you interrupt it via C-g")) (lambda () (define (play-once reason) (if (= reason 0) (play (selected-sound) :start 0 :stop play-once))) (play (selected-sound) :start 0 :stop play-once)))) ;;; -------- play region over and over until C-g typed (define play-region-forever (let ((documentation "(play-region-forever reg) plays region 'reg' until you interrupt it via C-g")) (lambda (reg1) (let ((reg (if (integer? reg1) (integer->region reg1) reg1))) (define (play-region-again reason) (if (= reason 0) ; 0=play completed normally (play reg :wait #f :stop play-region-again))) (play reg :wait #f :stop play-region-again))))) ;(bind-key #\p 0 (lambda (n) "play region forever" (play-region-forever ((regions) (max 0 n))))) #| ;;; -------- play while looping continuously between two movable marks (define loop-between-marks (let ((documentation "(loop-between-marks mark1 mark2 buffersize) plays while looping between two marks. \ x typed in the graph, or C-g in the listener exits the loop.")) (lambda (m1 m2 bufsize) (let* ((pos1 (mark-sample m1)) (pos2 (mark-sample m2)) (beg (min pos1 pos2)) (end (max pos1 pos2)) (bytes (* bufsize 2)) ; mus-audio-write handles the translation to short (and takes frames, not bytes as 3rd arg) (audio-fd (mus-audio-open-output 0 (srate) 1 mus-lshort bytes)) (stop-looping #f)) (if (not (= audio-fd -1)) (begin (bind-key #\space 0 (lambda () (set! stop-looping #t))) ; type space in the graph to stop this loop (do () (stop-looping (mus-audio-close audio-fd) (unbind-key #\space 0)) (mus-audio-write audio-fd (make-shared-vector (channel->float-vector beg bufsize) (list 1 bufsize)) bufsize) (set! beg (+ beg bufsize)) (if (>= beg end) (begin (set! pos1 (mark-sample m1)) ; get current mark positions (can change while looping) (set! pos2 (mark-sample m2)) (set! beg (min pos1 pos2)) (set! end (max pos1 pos2))))))))))) ;; m1 and m2 are marks ;; (loop-between-marks (caaar (marks)) (cadaar (marks)) 512) |# ;;; -------- hold DAC open and play sounds via keyboard (define start-dac (let ((documentation "(start-dac (srate 44100) (chans 1)) starts the DAC running continuously in the background")) (lambda* ((sr 44100) (chans 1)) (play #f :srate sr :channels chans)))) (define stop-dac stop-playing) ;; play-with-amps -- play channels with individually settable amps (define play-with-amps (let ((documentation "(play-with-amps snd :rest amps) plays snd with each channel scaled by the corresponding amp: (play-with-amps 0 1.0 0.5) plays channel 2 of stereo sound at half amplitude")) (lambda (sound . amps) (let ((chans (channels sound))) (do ((chan 0 (+ 1 chan))) ((= chan chans)) (let ((player (make-player sound chan))) (set! (amp-control player) (amps chan)) (add-player player))) (start-playing chans (srate sound)))))) ;;; play-sine and play-sines (define play-sine (let ((documentation "(play-sine freq amp) plays a 1 second sinewave at freq and amp")) (lambda (freq amp) (let ((len 44100) (osc (make-oscil freq))) (play (lambda () (and (positive? (set! len (- len 1))) (* amp (oscil osc))))))))) (define play-sines (let ((documentation "(play-sines freqs-and-amps) produces a tone given its spectrum: (play-sines '((440 .4) (660 .3)))")) (lambda (freqs-and-amps) (let* ((len 44100) (num-oscs (length freqs-and-amps)) (frqs (make-float-vector num-oscs)) (amps (make-float-vector num-oscs))) (do ((i 0 (+ i 1))) ((= i num-oscs)) (set! (frqs i) (hz->radians (car (freqs-and-amps i)))) (set! (amps i) (cadr (freqs-and-amps i)))) (let ((ob (make-oscil-bank frqs (make-float-vector num-oscs 0.0) amps #t))) (play (lambda () (and (positive? (set! len (- len 1))) (oscil-bank ob))))))))) ;; (play-sines '((425 .05) (450 .01) (470 .01) (546 .02) (667 .01) (789 .034) (910 .032))) snd-16.1/freeverb.rb0000644000076400007640000001537712434353162012500 0ustar bilbil# freeverb.rb -- CLM -> Snd/Ruby translation of freeverb.ins # Translator/Author: Michael Scholz # Created: 03/04/08 03:53:20 # Changed: 14/11/13 15:47:00 # Original notes of Fernando Lopez-Lezcano # ;; Freeverb - Free, studio-quality reverb SOURCE CODE in the public domain # ;; # ;; Written by Jezar at Dreampoint, June 2000 # ;; http://www.dreampoint.co.uk # ;; # ;; Translated into clm-2 by Fernando Lopez-Lezcano # ;; Version 1.0 for clm-2 released in January 2001 # ;; http://ccrma.stanford.edu/~nando/clm/freeverb/ # ;; # ;; Changes to the original code by Jezar (by Fernando Lopez-Lezcano): # ;; - the clm version can now work with a mono input or an n-channel input # ;; stream (in the latter case the number of channels of the input and output # ;; streams must match. # ;; - the "wet" parameter has been eliminated as it does not apply to the model # ;; that clm uses to generate reverberation # ;; - the "width" parameter name has been changed to :global. It now controls # ;; the coefficients of an NxN matrix that specifies how the output of the # ;; reverbs is mixed into the output stream. # ;; - predelays for the input channels have been added. # ;; - damping can be controlled individually for each channel. # For more information see clm-x/freeverb.html. require "ws" # Snd-Ruby's freeverb and fcomb (see sndins.so for a faster one). unless provided? :sndins class Fcomb def initialize(scaler, size, a0, a1) @feedback = scaler.to_f @delay = make_delay(size.to_i) @filter = make_one_zero(a0, a1) end attr_accessor :feedback def fcomb(input = 0.0) delay(@delay, input + one_zero(@filter, tap(@delay)) * @feedback) end def inspect format("#<%s: %p, %p, feedback: %0.3f>", self.class, @delay, @filter, @feedback) end end def make_fcomb(scaler = 0.0, size = 1, a0 = 0.0, a1 = 0.0) Fcomb.new(scaler, size, a0, a1) end def fcomb(gen, input = 0.0) gen.fcomb(input) end def fcomb?(obj) obj.kind_of?(Fcomb) end end add_help(:freeverb, "freeverb(*args) :room_decay, 0.5, :damping, 0.5, :global, 0.3, :predelay, 0.03, :output_gain, 1.0, :output_mixer, nil, :scale_room_decay, 0.28, :offset_room_decay, 0.7, :combtuning, [1116, 1188, 1277, 1356, 1422, 1491, 1557, 1617], :allpasstuning, [556, 441, 341, 225], :scale_damping, 0.4, :stereo_spread, 23, with_sound(:reverb, :freeverb) do fm_violin(0, 1, 440, 0.3) end This is the Ruby version of freeverb. For a faster one see sndins.so.") def freeverb(*args) room_decay, damping, global, predelay, output_gain, output_mixer = nil scale_room_decay, offset_room_decay, combtuning, allpasstuning = nil scale_damping, stereo_spread = nil optkey(args, binding, [:room_decay, 0.5], [:damping, 0.5], [:global, 0.3], [:predelay, 0.03], [:output_gain, 1.0], [:output_mixer, nil], [:scale_room_decay, 0.28], [:offset_room_decay, 0.7], [:combtuning, [1116, 1188, 1277, 1356, 1422, 1491, 1557, 1617]], [:allpasstuning, [556, 441, 341, 225]], [:scale_damping, 0.4], [:stereo_spread, 23]) if @reverb_channels > 1 and @reverb_channels != @channels error("input must be mono or input channels must equal output channels") end out_gain = output_gain local_gain = (1.0 - global) * (1.0 - 1.0 / @channels) + 1.0 / @channels global_gain = (@channels - local_gain * @channels) / [(@channels * @channels - @channels), 1].max srate_scale = @srate / 44100.0 out_mix = output_mixer unless vct?(output_mixer) out_mix = Vct.new(@channels) do (out_gain * global_gain) / @channels end end predelays = make_array(@reverb_channels) do make_delay(:size, (@srate * predelay).to_i) end room_decay_val = room_decay * scale_room_decay + offset_room_decay combs = make_array(@channels) do |c| combtuning.map do |tuning| dmp = scale_damping * damping sz = (srate_scale * tuning).to_i if c.odd? sz += (srate_scale * stereo_spread).to_i end make_fcomb(room_decay_val, sz, 1.0 - dmp, dmp) end end allpasses = make_array(@channels) do |c| allpasstuning.map do |tuning| sz = (srate_scale * tuning).to_i if c.odd? sz += (srate_scale * stereo_spread).to_i end make_all_pass(:size, sz, :feedforward, -1.0, :feedback, 0.5) end end len = @ws_reverb.length + seconds2samples(@decay_time) name = get_func_name() # to satisfy with_sound-option :info and :notehook with_sound_info(name, 0, samples2seconds(len)) if @verbose Snd.message("%s on %d in and %d out channels", name, @reverb_channels, @channels) end f_in = Vct.new(@reverb_channels, 0.0) f_out = Vct.new(@channels, 0.0) out_buf = Vct.new(@channels, 0.0) if @reverb_channels == 1 len.times do |i| fin = delay(predelays[0], file2sample(@ws_reverb, i, 0)) combs.each_with_index do |fcbs, c| f_out[c] = 0.0 fcbs.each do |fcb| f_out[c] += fcomb(fcb, fin) end end allpasses.each_with_index do |apss, c| apss.each do |aps| f_out[c] = all_pass(aps, f_out[c]) end end frample2file(@ws_output, i, frample2frample(out_mix, f_out, @channels, out_buf, @channels)) end else len.times do |i| fin = file2frample(@ws_reverb, i, f_in).map_with_index do |f, c| delay(predelays[c], f) end combs.each_with_index do |fcbs, c| f_out[c] = 0.0 fcbs.each do |fcb| f_out[c] += fcomb(fcb, fin[c]) end end allpasses.each_with_index do |apss, c| apss.each do |aps| f_out[c] = all_pass(aps, f_out[c]) end end frample2file(@ws_output, i, frample2frample(out_mix, f_out, @channels, out_buf, @channels)) end end end =begin with_sound(:reverb, :freeverb, :reverb_data, [:room_decay, 0.9], :channels, 2, :reverb_channels, 1, :output, "fvrb-test.snd", :play, 1, :statistics, true) do fm_violin(0, 1, 440, 0.5) end with_sound(:statistics, true, :reverb, :freeverb, :reverb_data, [:output_gain, 3.0]) do outa(0, 0.5, @ws_reverb) end with_sound(:channels, 2, :reverb_channels, 2, :statistics, true, :reverb, :freeverb, :reverb_data, [:output_gain, 3.0]) do outa(0, 0.5, @ws_reverb) outb(0, 0.1, @ws_reverb) end =end # freeverb.rb ends here snd-16.1/prc95.rb0000644000076400007640000002142712306421672011633 0ustar bilbil# prc95.rb -- Translation of prc95.scm/prc-toolkit95.lisp to Snd/Ruby # Perry Cook's Physical Modelling Toolkit # Translator/Author: Michael Scholz # Changed: Mon Nov 22 13:28:27 CET 2010 require "ws" module PRC def play_all(dur = 1) with_sound(:clm, false, :play, 1, :statistics, true, :output, "cook.snd") do beg = 0 plucky(beg, dur, 440, 0.2, 1.0) beg += dur + 0.2 bow(beg, dur, 440, 0.2, 1.0) beg += dur + 0.2 brass(beg, dur, 440, 0.2, 1.0) beg += dur + 0.2 clarinet(beg, dur, 440, 0.2, 1.0) beg += dur + 0.2 flute(beg, dur, 440, 0.2, 1.0) end end def make_reed(*args) offset, slope = nil optkey(args, binding, [:offset, 0.6], [:slope, -0.8]) lambda do |samp| [1.0, offset + slope * samp].min end end def reedtable(r, sample) r.call(sample) end def make_bowtable(*args) offset, slope = nil optkey(args, binding, [:offset, 0.0], [:slope, 1.0]) lambda do |samp| [0.0, 1.0 - (slope * (samp + offset)).abs].max end end def bowtable(b, sample) b.call(sample) end def jettable(sample) [-1.0, [1.0, sample * (sample * sample - 1.0)].min].max end def make_onezero(*args) gain, zerocoeff = nil optkey(args, binding, [:gain, 0.5], [:zerocoeff, 1.0]) make_one_zero(gain, gain * zerocoeff) end def make_onep(*args) polecoeff = optkey(args, [:polecoeff, 0.9]) make_one_pole(1.0 - polecoeff, -polecoeff) end def set_pole(p, val) set_mus_b1(p, -val) set_mus_a0(p, 1.0 - val) end def set_gain(p, val) set_mus_a0(p, mus_a0(p) * val) end def lip_set_freq(b, freq) set_mus_frequency(b, freq) end def lip(b, mouthsample, boresample) temp = formant(b, mouthsample - boresample) temp = [1.0, temp * temp].min temp * mouthsample + ((1.0 - temp) * boresample) end def make_dc_block input = output = 0.0 lambda do |samp| output = samp + (0.99 * output - input) input = samp output end end def dc_block(b, sample) b.call(sample) end def make_delaya(len, lag) lastin = output = 0.0 input = make_delay(len) outpointer = 2.0 - lag outpointer += len while outpointer <= 0.0 outpoint = outpointer.floor alpha = outpointer - outpoint coeff = (1.0 - alpha) / (1.0 + alpha) outpoint = -outpoint lambda do |samp| delay(input, samp) temp = tap(input, outpoint) output = -coeff * output + lastin + temp * coeff lastin = temp output end end def delaya(d, sample) d.call(sample) end def make_delayl(len, lag) input = make_delay(len) outpointer = 1 - lag outpointer += len while outpointer <= 0.0 outpoint = outpointer.floor alpha = outpointer - outpoint omalpha = 1.0 - alpha outpoint = -outpoint lambda do |samp| delay(input, samp) tap(input, outpoint - 1) * omalpha + tap(input, outpoint) * alpha end end def delayl(d, sample) d.call(sample) end # sample instruments def plucky(start, dur, freq, amp, maxa) len = (mus_srate / 100.0).floor + 1 delayline = make_delaya(len, mus_srate / freq.to_f - 0.5) filter = make_onezero() dout = 0.0 len.times do |i| dout = delaya(delayline, 0.99 * dout + maxa * (1.0 - random(2.0))) end run_instrument(start, dur) do dout = delaya(delayline, one_zero(filter, dout)) amp * dout end end def bowstr(start, dur, freq, amp, maxa) len = (mus_srate / 100.0).floor + 1 ratio = 0.8317 temp = mus_srate / freq.to_f - 4.0 neckdelay = make_delayl(len, temp * ratio) bridgedelay = make_delayl((len / 2.0).floor, temp * (1.0 - ratio)) bowtab = make_bowtable(:slope, 3.0) filt = make_onep() rate = 0.001 bowing = true bowvelocity = rate maxvelocity = maxa attackrate = rate durlen = seconds2samples(dur) ctr = 0 release = (0.8 * durlen).floor bridgeout = 0.0 neckout = 0.0 set_pole(filt, 0.6) set_gain(filt, 0.3) run_instrument(start, dur) do bridgerefl = nutrefl = veldiff = stringvel = bowtemp = 0.0 if bowing unless maxvelocity == bowvelocity if bowvelocity < maxvelocity bowvelocity += attackrate else bowvelocity -= attackrate end end else if bowvelocity > 0.0 bowvelocity -= attackrate end end bowtemp = 0.3 * bowvelocity filt_output = one_pole(filt, bridgeout) bridgerefl = -filt_output nutrefl = -neckout stringvel = bridgerefl + nutrefl veldiff = bowtemp - stringvel veldiff = veldiff * bowtable(bowtab, veldiff) neckout = delayl(neckdelay, bridgerefl + veldiff) bridgeout = delayl(bridgedelay, nutrefl + veldiff) result = amp * 10.0 * filt_output if ctr == release bowing = false attackrate = 0.0005 end ctr += 1 result end end def brass(start, dur, freq, amp, maxa) len = (mus_srate / 100.0).floor + 1 delayline = make_delaya(len, 1.0 + mus_srate / freq.to_f) lipfilter = make_formant() dcblocker = make_dc_block() blowing = true rate = 0.001 breathpressure = 0.0 maxpressure = maxa attackrate = rate durlen = seconds2samples(dur) release = (0.8 * durlen).floor ctr = 0 dout = 0.0 lip_set_freq(lipfilter, freq) run_instrument(start, dur) do if blowing unless maxpressure == breathpressure if breathpressure < maxpressure breathpressure += attackrate else breathpressure -= attackrate end end else if breathpressure > 0.0 breathpressure -= attackrate end end dout = delaya(delayline, dc_block(dcblocker, lip(lipfilter, 0.3 * breathpressure, 0.9 * dout))) result = amp * dout if ctr == release blowing = false attackrate = 0.0005 end ctr += 1 result end end def clarinet(start, dur, freq, amp, maxa) len = (mus_srate / 100.0).floor + 1 delayline = make_delayl(len, 0.5 * (mus_srate / freq.to_f) - 1.0) rtable = make_reed(:offset, 0.7, :slope, -0.3) filter = make_onezero() blowing = true breathpressure = 0.0 rate = 0.001 maxpressure = maxa attackrate = rate durlen = seconds2samples(dur) release = (0.8 * durlen).floor ctr = 0 dout = 0.0 run_instrument(start, dur) do pressurediff = 0.0 if blowing unless maxpressure == breathpressure if breathpressure < maxpressure breathpressure += attackrate else breathpressure -= attackrate end end else if breathpressure > 0.0 breathpressure -= attackrate end end pressurediff = one_zero(filter, -0.95 * dout) - breathpressure dout = delayl(delayline, breathpressure + pressurediff * reedtable(rtable, pressurediff)) result = amp * dout if ctr == release blowing = false attackrate = 0.0005 end ctr += 1 result end end def flute(start, dur, freq, amp, maxa) len = (mus_srate / 100.0).floor + 1 ratio = 0.8 temp = mus_srate / freq.to_f - 0.5 jetdelay = make_delayl((len / 2.0).floor, temp * (1.0 - ratio)) boredelay = make_delayl(len, ratio * temp) filter = make_onep() dcblocker = make_dc_block() jetrefl = 0.6 sinphase = 0.0 blowing = true breathpressure = 0.0 rate = 0.0005 maxpressure = maxa attackrate = rate durlen = seconds2samples(dur) release = (0.8 * durlen).floor ctr = 0 dout = 0.0 set_pole(filter, 0.8) set_gain(filter, -1.0) run_instrument(start, dur) do randpressure = 0.1 * breathpressure * random(1.0) temp = 0.0 pressurediff = 0.0 sinphase += 0.0007 sinphase -= 6.28 if sinphase > 6.28 randpressure = randpressure + 0.05 * breathpressure * sin(sinphase) if blowing unless maxpressure == breathpressure if breathpressure < maxpressure breathpressure += attackrate else breathpressure -= attackrate end end else if breathpressure > 0.0 breathpressure -= attackrate end end temp = dc_block(dcblocker, one_pole(filter, dout)) pressurediff = jettable(delayl(jetdelay, breathpressure + (randpressure - jetrefl * temp))) dout = delayl(boredelay, pressurediff) result = 0.3 * amp * dout if ctr == release blowing = false attackrate = 0.0005 end ctr += 1 result end end end include PRC # prc95.rb ends here snd-16.1/s7test.scm0000644000076400007640002215473312625630553012320 0ustar bilbil;;; s7 test suite ;;; ;;; sources include ;;; clisp test suite ;;; sbcl test suite ;;; Paul Dietz's CL test suite (gcl/ansi-tests/*) ;;; R Kelsey, W Clinger, and J Rees r5rs.html (and r6rs.html) ;;; A Jaffer's r4rstest.scm (the inspiration for this...) ;;; guile test suite ;;; gauche test suite ;;; sacla test suite ;;; Kent Dybvig's "The Scheme Programming Language" ;;; Brad Lucier and Peter Bex ;;; GSL tests ;;; Abramowitz and Stegun, "Handbook of Mathematical Functions" ;;; Weisstein, "Encyclopedia of Mathematics" ;;; the arprec package of David Bailey et al ;;; Maxima, William Schelter et al ;;; H Cohen, "A Course in Computational Algebraic Number Theory" ;;; N Higham, "Accuracy and Stability of Numerical Algorithms" ;;; various mailing lists and websites (see individual cases below) (define full-test #f) ; this includes some time-consuming stuff (define with-bignums (provided? 'gmp)) ; scheme number has any number of bits ; we assume s7_double is double, and s7_int is long long int ; a few of the bignum tests assume the default bignum-precision is 128 (define with-complex (provided? 'complex-numbers)) (define with-windows (provided? 'windows)) (define with-qq-vectors (catch #t (lambda () (integer? (`#(,(*s7* 'safety)) 0))) (lambda any #f))) (if (not (defined? 's7test-exits)) (define s7test-exits #t)) ;;; ---------------- pure-s7 ---------------- (define pure-s7 (provided? 'pure-s7)) (when pure-s7 (define (make-polar mag ang) (if (and (real? mag) (real? ang)) (complex (* mag (cos ang)) (* mag (sin ang))) (error 'wrong-type-arg "make-polar args should be real"))) (define make-rectangular complex) (define (memq a b) (member a b eq?)) (define (memv a b) (member a b eqv?)) (define (assq a b) (assoc a b eq?)) (define (assv a b) (assoc a b eqv?)) (define (char-ci=? . chars) (apply char=? (map char-upcase chars))) (define (char-ci<=? . chars) (apply char<=? (map char-upcase chars))) (define (char-ci>=? . chars) (apply char>=? (map char-upcase chars))) (define (char-ci? . chars) (apply char>? (map char-upcase chars))) (define (string-ci=? . strs) (apply string=? (map string-upcase strs))) (define (string-ci<=? . strs) (apply string<=? (map string-upcase strs))) (define (string-ci>=? . strs) (apply string>=? (map string-upcase strs))) (define (string-ci? . strs) (apply string>? (map string-upcase strs))) (define (list->string lst) (apply string lst)) (define (list->vector lst) (apply vector lst)) (define (let->list e) (if (let? e) (reverse! (map values e)) (error 'wrong-type-arg "let->list argument should be an environment: ~A" str))) (define* (string->list str (start 0) end) (if (and (string? str) (integer? start) (not (negative? start)) (or (not end) (and (integer? end) (>= end start)))) (map values (substring str start (or end (length str)))) (error 'wrong-type-arg "string->list argument should be a string: ~A" str))) (define (string-copy str) (if (string? str) (copy str) (error 'wrong-type-arg "string-copy argument should be a string: ~A" str))) (define (string-length str) (if (string? str) (length str) (error 'wrong-type-arg "string-length argument should be a string: ~A" str))) (define (string-fill! str chr . args) (if (string? str) (apply fill! str chr args) (error 'wrong-type-arg "string-fill! argument should be a string: ~A" str))) (define* (vector->list vect (start 0) end) (if (and (vector? vect) (integer? start) (not (negative? start)) (or (not end) (and (integer? end) (>= end start)))) (if start (let ((stop (or end (length vect)))) (if (= start stop) () (map values (make-shared-vector vect (list (- stop start)) start)))) (map values vect)) (error 'wrong-type-arg "vector->list argument should be a vector: ~A" vect))) (define (vector-length vect) (if (vector? vect) (length vect) (error 'wrong-type-arg "vector-length argument should be a vector: ~A" vect))) (define (vector-fill! vect val . args) (if (vector? vect) (apply fill! vect val args) (error 'wrong-type-arg "vector-fill! argument should be a vector: ~A" str))) (define (vector-append . args) (if (null? args) #() (if (vector? (car args)) (apply append args) (error 'wrong-type-arg "vector-append arguments should be vectors: ~A" args)))) (define (hash-table-size hash) (if (hash-table? hash) (length hash) (error 'wrong-type-arg "hash-table-size argument should be a hash-table: ~A" hash))) (define* (char-ready? p) (and p (not (input-port? p)) (error 'wrong-type-arg "char-ready? arg should be an input port"))) (define (set-current-output-port port) (error 'undefined-function "set-current-output-port is not in pure-s7")) (define (set-current-input-port port) (error 'undefined-function "set-current-input-port is not in pure-s7")) (define (exact? n) (if (not (number? n)) (error 'wrong-type-arg "exact? argument should be a number: ~A" n) (rational? n))) (define (inexact? x) (if (not (number? x)) (error 'wrong-type-arg "inexact? argument should be a number: ~A" x) (not (rational? x)))) (define (inexact->exact x) (if (not (number? x)) (error 'wrong-type-arg "inexact->exact argument should be a number: ~A" x) (if (rational? x) x (rationalize x)))) (define (exact->inexact x) (if (not (number? x)) (error 'wrong-type-arg "exact->inexact argument should be a number: ~A" x) (* x 1.0))) (define (integer-length i) (if (integer? i) (if (zero? i) 0 (+ (ceiling (log (abs i) 2)) (if (and (positive? i) (zero? (logand i (- i 1)))) 1 0))) (error 'wrong-type-arg "integer-length argument should be an integer: ~A" x))) (set! *#readers* (list (cons #\i (lambda (str) (* 1.0 (string->number (substring str 1))))) (cons #\e (lambda (str) (floor (string->number (substring str 1))))))) ;; one problem (of many): (string->number "#e0a" 16) -- no simple way to tell the #e reader that we want base 16 ;; similarly #x#if -- so in pure-s7, the reader complains (define-macro (defmacro name args . body) `(define-macro ,(cons name args) ,@body)) (define-macro (defmacro* name args . body) `(define-macro* ,(cons name args) ,@body)) (define-macro (call-with-values producer consumer) `(,consumer (,producer))) (define-macro (multiple-value-bind vars expression . body) ; named "receive" in srfi-8 which strikes me as perverse (if (or (symbol? vars) (negative? (length vars))) `((lambda ,vars ,@body) ,expression) `((lambda* (,@vars . ,(gensym)) ,@body) ,expression))) (define-macro (multiple-value-set! vars expr . body) (let ((local-vars (map (lambda (n) (gensym)) vars))) `((lambda* (,@local-vars . ,(gensym)) ,@(map (lambda (n ln) `(set! ,n ,ln)) vars local-vars) ,@body) ,expr))) (define-macro (cond-expand . clauses) (letrec ((traverse (lambda (tree) (if (pair? tree) (cons (traverse (car tree)) (if (null? (cdr tree)) () (traverse (cdr tree)))) (if (memq tree '(and or not else)) tree (and (symbol? tree) (provided? tree))))))) `(cond ,@(map (lambda (clause) (cons (traverse (car clause)) (if (null? (cdr clause)) '(#f) (cdr clause)))) clauses)))) ) ;;; ---------------- end pure-s7 ---------------- (define tmp-output-file "tmp1.r5rs") (define tmp-data-file "test.dat") (define bold-text (format #f "~C[1m" #\escape)) (define unbold-text (format #f "~C[22m" #\escape)) (set! (hook-functions *unbound-variable-hook*) ()) (set! (hook-functions *missing-close-paren-hook*) ()) (define s7test-output #f) ; if a string, it's treated as a logfile ;(set! (*s7* 'gc-stats) #t) ;(set! (*s7* 'undefined-identifier-warnings) #t) (define old-stdin *stdin*) (define old-stdout *stdout*) (define old-stderr *stderr*) (define *max-arity* #x20000000) (define (-s7-stack-top-) (*s7* 'stack-top)) (define -s7-symbol-table-locked? (dilambda (lambda () (*s7* 'symbol-table-locked?)) (lambda (val) (set! (*s7* 'symbol-table-locked?) val)))) ;;; -------------------------------------------------------------------------------- (if (and (defined? 'current-time) ; in Snd (defined? 'mus-rand-seed)) (set! (mus-rand-seed) (current-time))) (define (format-logged . args) ;(if (not (eq? (current-output-port) old-stdout)) (apply format (cons old-stdout (cdr args)))) (let ((str (apply format args))) ;(if (eq? (car args) #t) (flush-output-port (current-output-port))) (if (string? s7test-output) (let ((p (open-output-file s7test-output "a"))) (display str p) (flush-output-port p) (close-output-port p))) str)) ;(define error-port (open-output-file "err")) (define (show-error args tst) (if (or (not (pair? args)) (not (pair? (cdr args))) (not (pair? (cadr args))) (not (string? (caadr args)))) (format *stderr* "~S -> ~S?~%" tst args) (let ((type (car args)) (info (cadr args))) (let ((str (apply format #f info))) (format error-port "~S -> ~S ~S~%" tst type str))))) (define (ok? otst ola oexp) (let ((result (catch #t ola (lambda args ;(show-error args otst) (if (not (eq? oexp 'error)) (begin (display args) (newline))) 'error)))) (if (not (equal? result oexp)) (format-logged #t "~A: ~A got ~S but expected ~S~%~%" (port-line-number) otst result oexp)))) (if (not (defined? 'test)) (define-macro (test tst expected) ;(display tst *stderr*) (newline *stderr*) ;; `(ok? ',tst (lambda () (eval-string (format #f "~S" ',tst))) ,expected)) ;; `(ok? ',tst (lambda () (eval ',tst)) ,expected)) ;; `(ok? ',tst (lambda () ,tst) ,expected)) ;; `(ok? ',tst (lambda () (eval-string (object->string ,tst :readable))) ,expected)) ;; `(ok? ',tst (let () (define (_s7_) ,tst)) ,expected)) ;; `(ok? ',tst (lambda () (let ((_s7_ #f)) (set! _s7_ ,tst))) ,expected)) ;; `(ok? ',tst (lambda () (let ((_s7_ ,tst)) _s7_)) ,expected)) ;; `(ok? ',tst (catch #t (lambda () (lambda* ((_a_ ,tst)) _a_)) (lambda any (lambda () 'error))) ,expected)) ;; `(ok? ',tst (lambda () (do ((_a_ ,tst)) (#t _a_))) ,expected)) ;; `(ok? ',tst (lambda () (call-with-exit (lambda (_a_) (_a_ ,tst)))) ,expected)) ;; `(ok? ',tst (lambda () (values ,tst)) ,expected)) ;; `(ok? ',tst (lambda () (define (_s7_ _a_) _a_) (_s7_ ,tst)) ,expected)) ;; `(ok? ',tst (lambda () (define* (_s7_ (_a_ #f)) (or _a_)) (_s7_ ,tst)) ,expected)) ({list} 'ok? ({list} quote tst) ({list} lambda () tst) expected)) ) (define (tok? otst ola) (let* ((data #f) (result (catch #t ola (lambda args ;(show-error args otst) (set! data args) 'error)))) (if (or (not result) (eq? result 'error)) (format-logged #t "~A: ~A got ~S ~A~%~%" (port-line-number) otst result (or data ""))))) (define-macro (test-t tst) ;(display tst *stderr*) (newline *stderr*) `(tok? ',tst (lambda () ,tst))) (define-macro (test-e tst op arg) ;(display tst *stderr*) (newline *stderr*) `(let ((result (catch #t (lambda () ,tst) (lambda args ;(show-error args ',tst) 'error)))) (if (not (eq? result 'error)) (format-logged #t "~A: (~A ~S) got ~S but expected 'error~%~%" (port-line-number) ,op ,arg result)))) (define (op-error op result expected) (define (conjugate n) (complex (real-part n) (- (imag-part n)))) (if (and (real? result) (real? expected)) (/ (abs (- result expected)) (max 1.0 (abs expected))) (case op ((acosh) (/ (magnitude (- (cosh result) (cosh expected))) (max 0.001 (magnitude (cosh expected))))) ((asin) (/ (min (magnitude (- (sin result) (sin expected))) (magnitude (- result expected))) (max 0.001 (* 10 (magnitude (sin expected)))))) ((acos) (/ (min (magnitude (- (cos result) (cos expected))) (magnitude (- result expected))) (max 0.001 (magnitude (cos expected))))) ((asinh) (/ (magnitude (- (sinh result) (sinh expected))) (max 0.001 (magnitude (sinh expected))))) ((atanh) (/ (min (magnitude (- (tanh result) (tanh expected))) (magnitude (- result expected))) (max 0.001 (magnitude (tanh expected))))) ((atan) (/ (min (magnitude (- (tan result) (tan expected))) (magnitude (- result expected))) (max 0.001 (magnitude (tan expected))))) ((cosh) (/ (min (magnitude (- result expected)) (magnitude (- result (- expected)))) (max 0.001 (magnitude expected)))) (else (/ (magnitude (- result expected)) (max 0.001 (magnitude expected))))))) ;;; relative error (/ (abs (- x res) (abs x))) (define error-12 1e-12) (define error-6 1e-6) (define (number-ok? tst result expected) (if (not (eq? result expected)) (if (or (and (not (number? expected)) (not (eq? result expected))) (and (number? expected) (nan? expected) (not (nan? result))) (and (number? result) (nan? result) (number? expected) (not (nan? expected))) (and (number? expected) (or (not (number? result)) (nan? result))) (and (rational? expected) (rational? result) (not (= result expected))) (and (or (rational? expected) (rational? result)) (real? expected) (real? result) (> (/ (abs (- result expected)) (max 1.0 (abs expected))) error-12)) (and (pair? tst) (> (op-error (car tst) result expected) error-6))) (format-logged #t "~A: ~A got ~A~Abut expected ~A~%~%" (port-line-number) tst result (if (and (rational? result) (not (rational? expected))) (format #f " (~A) " (* 1.0 result)) " ") expected)))) (define (nok? otst ola oexp) (let ((result (catch #t ola (lambda args ;(show-error args otst) 'error)))) (number-ok? otst result oexp))) (if (not (defined? 'num-test)) (define-macro (num-test tst expected) ;(display tst *stderr*) (newline *stderr*) ;; `(nok? ',tst (lambda () ,tst) ,expected)) ;; `(nok? ',tst (let () (define (_s7_) ,tst)) ,expected)) ({list} 'nok? ({list} quote tst) ({list} lambda () tst) expected))) (define-macro (num-test-1 proc val tst expected) `(let ((result (catch #t (lambda () ,tst) (lambda args ;(show-error args ',tst) 'error)))) (number-ok? (list ,proc ,val) result ,expected))) (define-macro (num-test-2 proc val1 val2 tst expected) `(let ((result (catch #t (lambda () ,tst) (lambda args ;(show-error args ',tst) 'error)))) (number-ok? (list ,proc ,val1 ,val2) result ,expected))) (define (reinvert n op1 op2 arg) (let ((body (op2 (op1 arg)))) (do ((i 1 (+ i 1))) ((= i n) body) (set! body (op2 (op1 body)))))) (define (recompose n op arg) (define (recompose-1 n) (if (= n 1) (op arg) (op (recompose-1 (- n 1))))) (recompose-1 n)) (if (symbol-access 'val) (set! (symbol-access 'val) #f)) ; might get here from snd-test (define _ht_ (make-hash-table)) ;;; -------------------------------------------------------------------------------- ;;; before starting, make a test c-object (define with-block (not (provided? 'windows))) (if with-block (begin (call-with-output-file "s7test-block.c" (lambda (p) (format p " #include #include #include #include \"s7.h\" static s7_scheme *s7; /* c-object tests */ typedef struct { size_t size; double *data; } g_block; static int g_block_type = 0; static s7_pointer g_block_methods; static s7_pointer g_make_block(s7_scheme *sc, s7_pointer args) { #define g_make_block_help \"(make-block size) returns a new block of the given size\" g_block *g; s7_pointer new_g; s7_int size; if (!s7_is_integer(s7_car(args))) return(s7_wrong_type_arg_error(sc, \"make-block\", 1, s7_car(args), \"an integer\")); size = s7_integer(s7_car(args)); if ((size < 0) || (size > 1073741824)) return(s7_out_of_range_error(sc, \"make-block\", 1, s7_car(args), \"should be something reasonable\")); g = (g_block *)calloc(1, sizeof(g_block)); g->size = (size_t)size; g->data = (double *)calloc(g->size, sizeof(double)); new_g = s7_make_object(sc, g_block_type, (void *)g); s7_object_set_let(new_g, g_block_methods); s7_openlet(sc, new_g); return(new_g); } static s7_pointer g_to_block(s7_scheme *sc, s7_pointer args) { #define g_block_help \"(block ...) returns a block object with the arguments as its contents.\" s7_pointer p, b; size_t i, len; g_block *gb; len = s7_list_length(sc, args); b = g_make_block(sc, s7_cons(sc, s7_make_integer(sc, len), s7_nil(sc))); gb = (g_block *)s7_object_value(b); for (i = 0, p = args; i < len; i++, p = s7_cdr(p)) gb->data[i] = s7_number_to_real(sc, s7_car(p)); return(b); } static char *block_write_readably(s7_scheme *sc, void *value) { g_block *b = (g_block *)value; int i, len; char *buf; char flt[64]; len = b->size; buf = (char *)calloc((len + 1) * 64, sizeof(char)); snprintf(buf, (len + 1) * 64, \"(block\"); for (i = 0; i < len; i++) { snprintf(flt, 64, \" %.3f\", b->data[i]); strcat(buf, flt); } strcat(buf, \")\"); return(buf); } static char *g_block_display(s7_scheme *sc, void *value) { g_block *b = (g_block *)value; if (b->size < 6) return(block_write_readably(sc, value)); return(strdup(\"(block ...)\")); } static void g_block_free(void *value) { g_block *g = (g_block *)value; free(g->data); free(g); } static bool g_block_is_equal(void *val1, void *val2) { int i, len; g_block *b1 = (g_block *)val1; g_block *b2 = (g_block *)val2; if (val1 == val2) return(true); len = b1->size; if (len != b2->size) return(false); for (i = 0; i < len; i++) if (b1->data[i] != b2->data[i]) return(false); return(true); } static void g_block_mark(void *val) { /* nothing to mark */ } static s7_pointer g_is_block(s7_scheme *sc, s7_pointer args) { #define g_is_block_help \"(block? obj) returns #t if obj is a block.\" return(s7_make_boolean(sc, s7_object_type(s7_car(args)) == g_block_type)); } static s7_pointer g_block_ref(s7_scheme *sc, s7_pointer obj, s7_pointer args) { g_block *g = (g_block *)s7_object_value(obj); size_t index; s7_pointer ind; if (s7_is_null(sc, args)) /* this is for an (obj) test */ return(s7_make_integer(sc, 32)); ind = s7_car(args); if (!s7_is_integer(ind)) { if (s7_is_symbol(ind)) return(s7_symbol_local_value(sc, ind, g_block_methods)); return(s7_wrong_type_arg_error(sc, \"block-ref\", 1, ind, \"an integer\")); } index = (size_t)s7_integer(ind); if (index < g->size) return(s7_make_real(sc, g->data[index])); return(s7_out_of_range_error(sc, \"block-ref\", 2, ind, \"should be less than block length\")); } static s7_pointer g_block_set(s7_scheme *sc, s7_pointer obj, s7_pointer args) { g_block *g = (g_block *)s7_object_value(obj); s7_int index; if (!s7_is_integer(s7_car(args))) return(s7_wrong_type_arg_error(sc, \"block-set!\", 1, s7_car(args), \"an integer\")); index = s7_integer(s7_car(args)); if ((index >= 0) && (index < g->size)) { g->data[index] = s7_number_to_real(sc, s7_cadr(args)); return(s7_cadr(args)); } return(s7_out_of_range_error(sc, \"block-set\", 2, s7_car(args), \"should be less than block length\")); } static s7_double c_block_ref(s7_scheme *sc, s7_pointer **p) { s7_int ind; s7_if_t xf; g_block *g; g = (g_block *)(**p); (*p)++; xf = (s7_if_t)(**p); (*p)++; ind = xf(sc, p); return(g->data[ind]); } static s7_double c_block_set(s7_scheme *sc, s7_pointer **p) { s7_int ind; s7_double x; s7_rf_t rf; s7_if_t xf; g_block *g; g = (g_block *)(**p); (*p)++; xf = (s7_if_t)(**p); (*p)++; ind = xf(sc, p); rf = (s7_rf_t)(**p); (*p)++; x = rf(sc, p); g->data[ind] = x; return(x); } static s7_rf_t block_rf(s7_scheme *sc, s7_pointer expr) { s7_pointer a1, gs; a1 = s7_car(expr); if ((s7_is_symbol(a1)) && (s7_object_type(gs = s7_symbol_value(sc, a1)) == g_block_type)) { s7_xf_store(sc, (s7_pointer)s7_object_value(gs)); if (s7_arg_to_if(sc, s7_cadr(expr))) return(c_block_ref); } return(NULL); } static s7_rf_t block_set_rf(s7_scheme *sc, s7_pointer expr) { s7_pointer a1, gs; a1 = s7_cadr(expr); if ((!s7_is_pair(a1)) || (!s7_is_symbol(s7_car(a1))) || (!s7_is_null(sc, s7_cddr(a1)))) return(NULL); gs = s7_symbol_value(sc, s7_car(a1)); if (s7_object_type(gs) == g_block_type) { s7_xf_store(sc, (s7_pointer)s7_object_value(gs)); if (!s7_arg_to_if(sc, s7_cadr(a1))) return(NULL); if (!s7_arg_to_rf(sc, s7_caddr(expr))) return(NULL); return(c_block_set); } return(NULL); } static s7_pointer block_direct_ref(s7_scheme *sc, s7_pointer obj, s7_int index) { g_block *g; g = (g_block *)s7_object_value(obj); return(s7_make_real(sc, g->data[index])); } static s7_pointer block_direct_set(s7_scheme *sc, s7_pointer obj, s7_int index, s7_pointer val) { g_block *g; g = (g_block *)s7_object_value(obj); g->data[index] = s7_number_to_real(sc, val); return(val); } static s7_pointer g_block_length(s7_scheme *sc, s7_pointer obj) { g_block *g = (g_block *)s7_object_value(obj); return(s7_make_integer(sc, g->size)); } static int get_start_and_end(s7_scheme *sc, s7_pointer args, int *start, int end) { if (s7_is_pair(s7_cdr(args))) { s7_pointer p; p = s7_cadr(args); if (s7_is_integer(p)) { int nstart; nstart = s7_integer(p); if ((nstart < 0) || (nstart >= end)) {s7_out_of_range_error(sc, \"subblock\", 2, p, \"should be less than block length\"); return(0);} *start = nstart; } if (s7_is_pair(s7_cddr(args))) { p = s7_caddr(args); if (s7_is_integer(p)) { int nend; nend = s7_integer(p); if (nend <= *start) {s7_out_of_range_error(sc, \"subblock\", 3, p, \"should be greater than the start point\"); return(0);} if (nend < end) end = nend; } } } return(end - *start); } static s7_pointer g_block_copy(s7_scheme *sc, s7_pointer args) { s7_pointer new_g, obj; g_block *g, *g1; size_t len; int start = 0; obj = s7_car(args); g = (g_block *)s7_object_value(obj); len = g->size; if (s7_is_pair(s7_cdr(args))) { new_g = s7_cadr(args); if (s7_object_type(new_g) != g_block_type) /* fall back on the float-vector code using a wrapper */ { int gc_loc; s7_pointer v; v = s7_make_float_vector_wrapper(sc, len, g->data, 1, NULL, false); gc_loc = s7_gc_protect(sc, v); new_g = s7_copy(sc, s7_append(sc, s7_list(sc, 1, v), s7_cdr(args))); s7_gc_unprotect_at(sc, gc_loc); return(new_g); } if (s7_is_pair(s7_cddr(args))) len = get_start_and_end(sc, s7_cdr(args), &start, len); } else new_g = g_make_block(sc, s7_cons(sc, s7_make_integer(sc, len), s7_nil(sc))); g1 = (g_block *)s7_object_value(new_g); if (g1->size < len) len = g1->size; memcpy((void *)(g1->data), (void *)(g->data + start), len * sizeof(double)); return(new_g); } static s7_pointer g_block_append(s7_scheme *sc, s7_pointer args) { #define g_block_append_help \"(append block...) returns a new block containing the argument blocks concatenated.\" int i, len = 0; s7_pointer p, new_g; g_block *g; for (i = 0, p = args; s7_is_pair(p); p = s7_cdr(p), i++) { g_block *g1; if (s7_object_type(s7_car(p)) != g_block_type) return(s7_wrong_type_arg_error(sc, \"block-append\", i, s7_car(p), \"a block\")); g1 = (g_block *)s7_object_value(s7_car(p)); len += g1->size; } new_g = g_make_block(sc, s7_cons(sc, s7_make_integer(sc, len), s7_nil(sc))); g = (g_block *)s7_object_value(new_g); for (i = 0, p = args; s7_is_pair(p); p = s7_cdr(p)) { g_block *g1; g1 = (g_block *)s7_object_value(s7_car(p)); memcpy((void *)(g->data + i), (void *)(g1->data), g1->size * sizeof(double)); i += g1->size; } return(new_g); } static s7_pointer g_block_reverse(s7_scheme *sc, s7_pointer args) { size_t i, j; g_block *g, *g1; s7_pointer new_g; g = (g_block *)s7_object_value(s7_car(args)); new_g = g_make_block(sc, s7_cons(sc, s7_make_integer(sc, g->size), s7_nil(sc))); g1 = (g_block *)s7_object_value(new_g); for (i = 0, j = g->size - 1; i < g->size; i++, j--) g1->data[i] = g->data[j]; return(new_g); } static s7_pointer g_block_reverse_in_place(s7_scheme *sc, s7_pointer args) { #define g_block_reverse_in_place_help \"(block-reverse! block) returns block with its data reversed.\" size_t i, j; g_block *g; s7_pointer obj; obj = s7_car(args); if (s7_object_type(obj) != g_block_type) return(s7_wrong_type_arg_error(sc, \"block-reverse!\", 0, obj, \"a block\")); g = (g_block *)s7_object_value(obj); if (g->size < 2) return(obj); for (i = 0, j = g->size - 1; i < j; i++, j--) { double temp; temp = g->data[i]; g->data[i] = g->data[j]; g->data[j] = temp; } return(obj); } static s7_pointer g_block_fill(s7_scheme *sc, s7_pointer args) { s7_pointer obj, val; size_t i, len; int start = 0; double fill_val; g_block *g; obj = s7_car(args); val = s7_cadr(args); g = (g_block *)s7_object_value(obj); fill_val = s7_number_to_real(sc, val); len = g->size; if (s7_is_pair(s7_cddr(args))) len = get_start_and_end(sc, s7_cdr(args), &start, len); if (fill_val == 0.0) memset((void *)(g->data + start), 0, len * sizeof(double)); else { for (i = 0; i < len; i++) g->data[i + start] = fill_val; } return(obj); } static s7_pointer g_blocks(s7_scheme *sc, s7_pointer args) { return(s7_copy(sc, s7_list(sc, 1, args))); } static s7_pointer g_subblock(s7_scheme *sc, s7_pointer args) { #define g_subblock_help \"(subblock block (start 0) end) returns a portion of the block.\" s7_pointer p, new_g, obj; int start = 0, new_len, i; g_block *g, *g1; obj = s7_car(args); if (s7_object_type(obj) != g_block_type) return(s7_wrong_type_arg_error(sc, \"subblock\", 1, obj, \"a block\")); g = (g_block *)s7_object_value(obj); new_len = get_start_and_end(sc, args, &start, g->size); new_g = g_make_block(sc, s7_cons(sc, s7_make_integer(sc, new_len), s7_nil(sc))); g1 = (g_block *)s7_object_value(new_g); memcpy((void *)(g1->data), (void *)(g->data + start), new_len * sizeof(double)); return(new_g); } /* function port tests */ static unsigned char *fout = NULL; static unsigned int fout_size = 0, fout_loc = 0; static void foutput(s7_scheme *sc, unsigned char c, s7_pointer port) { if (fout_size == fout_loc) { if (fout_size == 0) { fout_size = 128; fout = (unsigned char *)malloc(fout_size * sizeof(unsigned char)); } else { fout_size += 128; fout = (unsigned char *)realloc(fout, fout_size * sizeof(unsigned char)); } } fout[fout_loc++] = c; } static s7_pointer fout_open(s7_scheme *sc, s7_pointer args) { return(s7_open_output_function(sc, foutput)); } static s7_pointer fout_get_output(s7_scheme *sc, s7_pointer args) { foutput(sc, 0, s7_car(args)); /* make sure it's null-terminated */ return(s7_make_string_with_length(sc, (const char *)fout, fout_loc - 1)); } static s7_pointer fout_close(s7_scheme *sc, s7_pointer args) { fout_loc = 0; return(s7_car(args)); } static const char *fin = NULL; static unsigned int fin_size = 0, fin_loc = 0; static s7_pointer finput(s7_scheme *sc, s7_read_t peek, s7_pointer port) { switch (peek) { case S7_READ_BYTE: return(s7_make_integer(sc, (int)fin[fin_loc++])); case S7_READ_CHAR: return(s7_make_character(sc, fin[fin_loc++])); case S7_PEEK_CHAR: return(s7_make_character(sc, fin[fin_loc])); case S7_READ_LINE: { unsigned int i; s7_pointer result; for (i = fin_loc; (i < fin_size) && (fin[i] != '\\n'); i++); result = s7_make_string_with_length(sc, (char *)(fin + fin_loc), i - fin_loc); fin_loc = i + 1; return(result); } case S7_IS_CHAR_READY: return(s7_make_boolean(sc, fin_loc < fin_size)); case S7_READ: return(s7_error(sc, s7_make_symbol(sc, \"read-error\"), s7_make_string(sc, \"can't read yet!\"))); } } static s7_pointer fin_open(s7_scheme *sc, s7_pointer args) { /* arg = string to read */ s7_pointer str; fin_loc = 0; str = s7_car(args); fin = s7_string(str); /* assume caller will GC protect the string */ fin_size = s7_string_length(str); return(s7_open_input_function(sc, finput)); } /* dilambda test */ static s7_pointer g_dilambda_test(s7_scheme *sc, s7_pointer args) {return(s7_f(sc));} static s7_pointer g_dilambda_set_test(s7_scheme *sc, s7_pointer args) {return(s7_car(args));} /* hash-table tests */ static s7_pointer g_hloc(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, 0));} static s7_pointer g_heq(s7_scheme *sc, s7_pointer args) {return(s7_make_boolean(sc, s7_is_eq(s7_car(args), s7_cadr(args))));} /* optimizer tests */ static s7_pointer g_cf10(s7_scheme *sc, s7_pointer args) {return(s7_car(args));} static s7_pointer g_cf11(s7_scheme *sc, s7_pointer args) {return(s7_car(args));} static s7_pointer g_cs11(s7_scheme *sc, s7_pointer args) {return(s7_car(args));} static s7_pointer g_cf20(s7_scheme *sc, s7_pointer args) {return(s7_car(args));} static s7_pointer g_cf21(s7_scheme *sc, s7_pointer args) {return(s7_car(args));} static s7_pointer g_cf22(s7_scheme *sc, s7_pointer args) {return(s7_cadr(args));} static s7_pointer g_cf30(s7_scheme *sc, s7_pointer args) {return(s7_car(args));} static s7_pointer g_cf31(s7_scheme *sc, s7_pointer args) {return(s7_car(args));} static s7_pointer g_cf32(s7_scheme *sc, s7_pointer args) {return(s7_cadr(args));} static s7_pointer g_cf33(s7_scheme *sc, s7_pointer args) {return(s7_caddr(args));} static s7_pointer g_cf41(s7_scheme *sc, s7_pointer args) {return(s7_car(args));} static s7_pointer g_cf42(s7_scheme *sc, s7_pointer args) {return(s7_cadr(args));} static s7_pointer g_cf43(s7_scheme *sc, s7_pointer args) {return(s7_caddr(args));} static s7_pointer g_cf44(s7_scheme *sc, s7_pointer args) {return(s7_cadddr(args));} static s7_pointer g_rs11(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, s7_integer(s7_car(args)) + 1));} static s7_pointer g_cf51(s7_scheme *sc, s7_pointer args) {return(s7_car(args));} void block_init(s7_scheme *sc); void block_init(s7_scheme *sc) { s7_pointer cur_env; cur_env = s7_outlet(sc, s7_curlet(sc)); g_block_type = s7_new_type_x(sc, \"#\", g_block_display, g_block_free, g_block_is_equal, g_block_mark, g_block_ref, g_block_set, g_block_length, g_block_copy, g_block_reverse, g_block_fill); s7_set_object_print_readably(g_block_type, block_write_readably); s7_define_function(sc, \"make-block\", g_make_block, 1, 0, false, g_make_block_help); s7_define_function(sc, \"block\", g_to_block, 0, 0, true, g_block_help); s7_define_function(sc, \"subblock\", g_subblock, 1, 0, true, g_subblock_help); s7_define_function(sc, \"block-append\", g_block_append, 0, 0, true, g_block_append_help); s7_define_function(sc, \"block-reverse!\", g_block_reverse_in_place, 1, 0, true, g_block_reverse_in_place_help); s7_define_function(sc, \"block?\", g_is_block, 1, 0, false, g_is_block_help); s7_define_function_star(sc, \"blocks\", g_blocks, \"(frequency 4) (scaler 1)\", \"test for function*\"); g_block_methods = s7_eval_c_string(sc, \"(inlet 'float-vector? (lambda (p) #t) \ 'subsequence subblock \ 'append block-append \ 'reverse! block-reverse!)\"); s7_gc_protect(sc, g_block_methods); s7_object_type_set_xf(g_block_type, NULL, NULL, block_rf, block_set_rf); s7_object_type_set_direct(g_block_type, block_direct_ref, block_direct_set); s7_define_safe_function(sc, \"function-open-output\", fout_open, 0, 0, false, \"\"); s7_define_safe_function(sc, \"function-get-output\", fout_get_output, 1, 0, false, \"\"); s7_define_safe_function(sc, \"function-close-output\", fout_close, 1, 0, false, \"\"); s7_define_safe_function(sc, \"function-open-input\", fin_open, 1, 0, false, \"\"); s7_define_function_with_setter(sc, \"dilambda-test\", g_dilambda_test, g_dilambda_set_test, 0, 0, \"dilambda-test info\"); s7_define_safe_function(sc, \"hash_heq\", g_heq, 2, 0, false, \"hash-table test\"); s7_define_safe_function(sc, \"hash_hloc\", g_hloc, 1, 0, false, \"hash-table test\"); s7_define_safe_function(sc, \"cf10\", g_cf10, 1, 0, false, \"\"); s7_define_safe_function(sc, \"cf11\", g_cf11, 1, 0, false, \"\"); s7_define_safe_function(sc, \"cs11\", g_cs11, 1, 0, false, \"\"); s7_define_safe_function(sc, \"rs11\", g_rs11, 1, 0, false, \"\"); s7_define_safe_function(sc, \"cf20\", g_cf20, 2, 0, false, \"\"); s7_define_safe_function(sc, \"cf21\", g_cf21, 2, 0, false, \"\"); s7_define_safe_function(sc, \"cf22\", g_cf22, 2, 0, false, \"\"); s7_define_safe_function(sc, \"cf30\", g_cf30, 3, 0, false, \"\"); s7_define_safe_function(sc, \"cf31\", g_cf31, 3, 0, false, \"\"); s7_define_safe_function(sc, \"cf32\", g_cf32, 3, 0, false, \"\"); s7_define_safe_function(sc, \"cf33\", g_cf33, 3, 0, false, \"\"); s7_define_safe_function(sc, \"cf41\", g_cf41, 4, 0, false, \"\"); s7_define_safe_function(sc, \"cf42\", g_cf42, 4, 0, false, \"\"); s7_define_safe_function(sc, \"cf43\", g_cf43, 4, 0, false, \"\"); s7_define_safe_function(sc, \"cf44\", g_cf44, 4, 0, false, \"\"); s7_define_safe_function(sc, \"cf51\", g_cf51, 5, 0, false, \"\"); } "))) (cond ((provided? 'osx) (system "gcc -c s7test-block.c -O2") (system "gcc s7test-block.o -o s7test-block.so -dynamic -bundle -undefined suppress -flat_namespace")) ((or (provided? 'freebsd) (provided? 'netbsd)) (system "cc -fPIC -c s7test-block.c -O2") (system "cc s7test-block.o -shared -o s7test-block.so -lm -lc")) ((provided? 'openbsd) (system "gcc -fPIC -ftrampolines -c s7test-block.c -O2") (system "gcc s7test-block.o -shared -o s7test-block.so -lm -lc")) ((provided? 'solaris) (system "gcc -fPIC -c s7test-block.c") (system "gcc s7test-block.o -shared -o s7test-block.so -G -ldl -lm")) (else (system "gcc -fPIC -c s7test-block.c -O2") (system "gcc s7test-block.o -shared -o s7test-block.so -ldl -lm -Wl,-export-dynamic"))) (let ((new-env (sublet (curlet) (cons 'init_func 'block_init)))) ; load calls init_func if possible (load "s7test-block.so" new-env)) (define _c_obj_ (make-block 16)) ) (define _c_obj_ (c-pointer 0))) ; not with-block (define _null_ (c-pointer 0)) (when (and (provided? 'linux) (not (provided? 'gmp))) (system "gcc -o ffitest ffitest.c -g3 -Wall s7.o -lm -I. -ldl") (system "ffitest")) ;;; -------------------------------------------------------------------------------- ;;; eq? (test (eq? 'a 3) #f) (test (eq? #t 't) #f) (test (eq? "abs" 'abc) #f) (test (eq? "hi" '(hi)) #f) (test (eq? "hi" "hi") #f) (test (eq? "()" ()) #f) (test (eq? '(1) '(1)) #f) (test (eq? '(#f) '(#f)) #f) (test (eq? #\a #\b) #f) (test (eq? #t #t) #t) (test (eq? #f #f) #t) (test (eq? #f #t) #f) (test (eq? (null? ()) #t) #t) (test (eq? (null? '(a)) #f) #t) (test (eq? (cdr '(a)) ()) #t) (test (eq? 'a 'a) #t) (test (eq? 'a 'b) #f) (test (eq? 'a (string->symbol "a")) #t) (test (eq? (symbol "a") (string->symbol "a")) #t) (test (eq? :a :a) #t) (test (eq? ':a 'a) #f) (test (eq? ':a ':a) #t) (test (eq? :a a:) #f) (test (eq? ':a 'a:) #f) (test (eq? 'a: 'a:) #t) (test (eq? ':a: 'a:) #f) (test (eq? 'a (symbol "a")) #t) (test (eq? :: '::) #t) (test (eq? ':a (symbol->keyword (symbol "a"))) #t) ; but not a: (test (eq? '(a) '(b)) #f) (test (let ((x '(a . b))) (eq? x x)) #t) (test (let ((x (cons 'a 'b))) (eq? x x)) #t) (test (eq? (cons 'a 'b) (cons 'a 'b)) #f) (test (eq? "abc" "cba") #f) (test (let ((x "hi")) (eq? x x)) #t) (test (eq? (string #\h #\i) (string #\h #\i)) #f) (test (eq? #(a) #(b)) #f) (test (let ((x (vector 'a))) (eq? x x)) #t) (test (eq? (vector 'a) (vector 'a)) #f) (test (eq? car car) #t) (test (eq? car cdr) #f) (test (let ((x (lambda () 1))) (eq? x x)) #t) (test (let ((x (lambda () 1))) (let ((y x)) (eq? x y))) #t) (test (let ((x (lambda () 1))) (let ((y (lambda () 1))) (eq? x y))) #f) (test (eq? 'abc 'abc) #t) (test (eq? eq? eq?) #t) (test (eq? (if #f 1) 1) #f) (test (eq? () '(#||#)) #t) (test (eq? () '(#|@%$&|#)) #t) (test (eq? '#||#hi 'hi) #t) ; ?? (test (eq? '; a comment hi 'hi) #t) ; similar: (test (cadr '#| a comment |#(+ 1 2)) 1) (test `(+ 1 ,@#||#(list 2 3)) '(+ 1 2 3)) (test `(+ 1 ,#||#(+ 3 4)) '(+ 1 7)) ;; but not splitting the ",@" or splitting a number: (test (+ 1 2.0+#||#3i) 'error) (test `(+ 1 ,#||#@(list 2 3)) 'error) (test (eq? #||# (#|%%|# append #|^|#) #|?|# (#|+|# list #|<>|#) #||#) #t) (test (eq? '() ;a comment '()) #t) (test (eq? 3/4 3) #f) (test (eq? '() '()) #t) (test (eq? '() '( )) #t) (test (eq? '()'()) #t) (test (eq? '()(list)) #t) (test (eq? () (list)) #t) (test (eq? (begin) (append)) #t) (test (let ((lst (list 1 2 3))) (eq? lst (apply list lst))) #f) ; changed 26-Sep-11 ;(test (eq? 1/0 1/0) #f) ;(test (let ((+nan.0 1/0)) (eq? +nan.0 +nan.0)) #f) ;; these are "unspecified" so any boolean value is ok (test (eq? ''2 '2) #f) (test (eq? '2 '2) #t) ; unspecified?? (test (eq? '2 2) #t) (test (eq? ''2 ''2) #f) (test (eq? ''#\a '#\a) #f) (test (eq? '#\a #\a) #t) ; was #f (test (eq? 'car car) #f) (test (eq? '()()) #t) (test (eq? ''() '()) #f) (test (eq? '#f #f) #t) (test (eq? '#f '#f) #t) (test (eq? #f ' #f) #t) (test (eq? '()'()) #t) ; no space (test (#||# eq? #||# #f #||# #f #||#) #t) (test (eq? (current-input-port) (current-input-port)) #t) (test (let ((f (lambda () (quote (1 . "H"))))) (eq? (f) (f))) #t) (test (let ((f (lambda () (cons 1 (string #\H))))) (eq? (f) (f))) #f) (test (eq? *stdin* *stdin*) #t) (test (eq? *stdout* *stderr*) #f) (test (eq? *stdin* *stderr*) #f) (test (eq? else else) #t) (test (eq? :else else) #f) (test (eq? :else 'else) #f) (test (eq? :if if) #f) (test (eq? 'if 'if) #t) (test (eq? :if :if) #t) (test (eq? (string) (string)) #f) (test (eq? (string) "") #f) (test (eq? (vector) (vector)) #f) (test (eq? (vector) #()) #f) (test (eq? (list) (list)) #t) (test (eq? (list) ()) #t) (test (eq? (hash-table) (hash-table)) #f) (test (eq? (curlet) (curlet)) #t) (test (eq? (rootlet) (rootlet)) #t) (test (eq? (funclet abs) (funclet abs)) #t) ; or any other built-in... (test (eq? letrec* letrec*) #t) (test (eq? (current-input-port) (current-input-port)) #t) (test (eq? (current-error-port) (current-error-port)) #t) (test (eq? (current-output-port) (current-output-port)) #t) (test (eq? (current-input-port) (current-output-port)) #f) (test (eq? (string #\a) (string #\a)) #f) (test (eq? "a" "a") #f) (test (eq? #(1) #(1)) #f) (test (let ((a "hello") (b "hello")) (eq? a b)) #f) (test (let ((a "foo")) (eq? a (copy a))) #f) (test (let ((p (c-pointer 0))) (eq? p (copy p))) #f) (test (let ((p (c-pointer 0))) (let ((p1 p)) (eq? p p1))) #t) (begin #| ; |# (display "")) (newline) (test (; eq? ';! (;)()# );((")"; ;"#|)#"" '#|";"|#(#|;|#); ;# ;\;"#"#f )#t) (test (+ #| this is a comment |# 2 #| and this is another |# 3) 5) (test (eq? #| a comment |# #f #f) #t) (test (eq? #| a comment |##f #f) #t) ; ?? (test (eq? #| a comment | ##f|##f #f) #t) ; ?? (test (eq? #||##||##|a comment| ##f|##f #f) #t) (test (+ ;#| 3 ;|# 4) 7) (test (+ #| ; |# 3 4) 7) (test (eq? (if #f #t) (if #f 3)) #t) (test (eq?) 'error) ; "this comment is missing a double-quote (test (eq? #t) 'error) #| "this comment is missing a double-quote |# (test (eq? #t #t #t) 'error) #| and this has redundant starts #| #| |# (test (eq? #f . 1) 'error) (test (eq #f #f) 'error) (let ((things (vector #t #f #\space () "" 0 1 3/4 1+i 1.5 '(1 .2) #() (vector) (vector 1) (list 1) 'f 't #\t))) (let ((len (length things))) (do ((i 0 (+ i 1))) ((= i (- len 1))) (do ((j (+ i 1) (+ j 1))) ((= j len)) (if (eq? (vector-ref things i) (vector-ref things j)) (format-logged #t ";(eq? ~A ~A) -> #t?~%" (vector-ref things i) (vector-ref things j))))))) ;;; these are defined at user-level in s7 -- why are other schemes so coy about them? (test (eq? (if #f #f) #) #t) (test (eq? (symbol->value '_?__undefined__?_) #) #t) (test (eq? # #) #t) (test (eq? # #) #t) (test (eq? # #) #t) (test (eq? # #) #f) (test (eq? # ()) #f) (test (let () (define-macro (hi a) `(+ 1 ,a)) (eq? hi hi)) #t) (test (let () (define (hi a) (+ 1 a)) (eq? hi hi)) #t) (test (let ((x (lambda* (hi (a 1)) (+ 1 a)))) (eq? x x)) #t) (test (eq? quasiquote quasiquote) #t) (test (eq? `quasiquote 'quasiquote) #t) (test (eq? 'if (keyword->symbol :if)) #t) (test (eq? 'if (string->symbol "if")) #t) (test (eq? (copy lambda) (copy 'lambda)) #f) (test (eq? if 'if) #f) (test (eq? if `if) #f) (test (eq? if (keyword->symbol :if)) #f) (test (eq? if (string->symbol "if")) #f) (test (eq? lambda and) #f) (test (eq? let let*) #f) (test (eq? quote quote) #t) (test (eq? '"hi" '"hi") #f) ; guile also ;(test (eq? '"" "") #f) ;(test (eq? '"" '"") #f) ;(test (eq? "" "") #f) (test (eq? #() #()) #f) (test (eq? '#() #()) #f) (test (eq? '#() '#()) #f) (test (let ((v #())) (eq? v #())) #f) (test (let ((v #())) (eq? v #())) #f) (test (let ((v #())) (eq? v v)) #t) (test (call/cc (lambda (return) (return (eq? return return)))) #t) (test (let ((r #f)) (call/cc (lambda (return) (set! r return) #f)) (eq? r r)) #t) (test (eq? _unbound_variable_ #f) 'error) (when with-block (let ((b (make-block 4))) (test (eq? b b) #t) (test (equal? b b) #t) (test (block? b) #t) (test (block? #()) #f) (test (block? #f) #f) (set! (b 0) 32) (test (b 0) 32.0) (let () (define (hi b i) (b i)) (hi b 0) (test (hi b 0) 32.0)) (let () (define (hi b) (b 0)) (hi b) (test (hi b) 32.0)) (let () (define (hi b) (b)) (hi b) (test (hi b) 32)) (test b (block 32.0 0.0 0.0 0.0)) (test (object->string b) "(block 32.000 0.000 0.000 0.000)") (let ((b1 (make-block 4))) (test (eq? b b1) #f))) (test (blocks) (list 4 1)) (test (blocks :frequency 2) (list 2 1)) (test (blocks :scaler 3 :frequency 2) (list 2 3)) (test (blocks :scaler 3 :phase 1) 'error) (test (map blocks '(1 2 3)) '((1 1) (2 1) (3 1))) (test (map blocks '( 1 2 3) '(4 5 6)) '((1 4) (2 5) (3 6))) (test (procedure-documentation blocks) "test for function*") (test (apply blocks '(:frequency 5 :scaler 4)) '(5 4)) (test (let () (define (b1) (blocks 100)) (b1)) '(100 1)) (test (procedure? blocks) #t) (define (fv32) (let ((b (block 1 2 3 4)) (f (make-float-vector 4))) (do ((i 0 (+ i 1))) ((= i 4) f) (set! (f i) (+ (b i) 1.0))))) (test (fv32) (float-vector 2.0 3.0 4.0 5.0)) (define (fv33) (let ((b (block 1 2 3 4)) (f (make-block 4))) (do ((i 0 (+ i 1))) ((= i 4) f) (set! (f i) (+ (b i) 1.0))))) (test (fv33) (block 2.0 3.0 4.0 5.0)) ) (test (c-pointer? 0) #f) (test (c-pointer? _null_) #t) (if with-block (test (integer? (c-object? _c_obj_)) #t) (test (c-pointer? _c_obj_) #t)) (for-each (lambda (arg) (test (c-pointer? arg) #f) (test (c-object? arg) #f)) (list "hi" () (integer->char 65) #f #t 0+i '(1 2) _ht_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) (test (c-pointer?) 'error) (test (c-object?) 'error) (test (c-pointer? _c_obj_ 2) 'error) (test (c-object? _c_obj_ 2) 'error) (when with-bignums (test (c-pointer? (c-pointer (bignum "12341234"))) #t) (test (c-pointer (bignum "1.4")) 'error)) (when with-block (test (pair? (*s7* 'c-types)) #t)) ;;; a ridiculous optimizer typo... (test (let ((sym 'a)) (define (hi a) (eq? (cdr a) sym)) (hi '(a a))) #f) (test (let ((sym 'a)) (define (hi a) (eq? (cdr a) sym)) (hi '(a . a))) #t) (test (let ((sym 'a)) (define (hi a) (eq? (cdr a) sym)) (hi '(a . b))) #f) (for-each (lambda (arg) (let ((x arg) (y arg)) (if (not (eq? x x)) (format-logged #t ";(eq? x x) of ~A -> #f?~%" x)) (if (not (eq? x arg)) (format-logged #t ";(eq? x arg) of ~A ~A -> #f?~%" x arg)) (if (not (eq? x y)) (format-logged #t ";(eq? x y) of ~A ~A -> #f?~%" x y)))) ;; actually I hear that #f is ok here for numbers (list "hi" '(1 2) (integer->char 65) 1 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3/4 #\f (lambda (a) (+ a 1)) :hi (if #f #f) # #)) ;; this used to include 3.14 and 1+i but that means the (eq? x x) case differs from the (eq? 3.14 3.14) case (define comment-start (port-line-number)) #| :'(1(1)) (1 (1)) :'(1#(1)) (1# (1)) |# (if (not (= (- (port-line-number) comment-start) 7)) (format *stderr* ";block comment newline counter: ~D ~D~%" comment-start (port-line-number))) ;;; this comes from G Sussman (let () (define (counter count) (lambda () (set! count (+ 1 count)) count)) (define c1 (counter 0)) (define c2 (counter 0)) (test (eq? c1 c2) #f) (test (eq? c1 c1) #t) (test (eq? c2 c2) #t) (test (let ((p (lambda (x) x))) (eqv? p p)) #t) (for-each (lambda (arg) (if (not ((lambda (p) (eq? p p)) arg)) (format-logged #t "~A not eq? to itself?~%" arg))) (list "hi" '(1 2) (integer->char 65) 1 'a-symbol (make-vector 3) abs quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #\f (lambda (a) (+ a 1)) :hi (if #f #f) # # '(1 2 . 3) (let ((lst (list 1 2))) (set! (cdr (cdr lst)) lst) lst) (vector) (string) (list) (let ((x 3)) (lambda (y) (+ x y)))))) ;;; this for r7rs (test (eq? #t #true) #t) (test (eq? #f #false) #t) (test (eq? () (map values ())) #t) (let () (define (f2) f2) (test (eq? f2 (f2)) #t)) (letrec ((f2 (lambda () f2))) (test (eq? f2 (f2)) #t)) ;;; -------------------------------------------------------------------------------- ;;; eqv? (test (eqv? 'a 3) #f) (test (eqv? #t 't) #f) (test (eqv? "abs" 'abc) #f) (test (eqv? "hi" '(hi)) #f) (test (eqv? "()" ()) #f) (test (eqv? '(1) '(1)) #f) (test (eqv? '(#f) '(#f)) #f) (test (eqv? #\a #\b) #f) (test (eqv? #\a #\a) #t) (test (eqv? (integer->char 255) (string-ref (string #\x (integer->char 255) #\x) 1)) #t) (test (eqv? (integer->char #xf0) (integer->char #x70)) #f) (test (eqv? #\space #\space) #t) (test (let ((x (string-ref "hi" 0))) (eqv? x x)) #t) (test (eqv? #t #t) #t) (test (eqv? #f #f) #t) (test (eqv? #f #t) #f) (test (eqv? (null? ()) #t) #t) (test (eqv? (null? '(a)) #f) #t) (test (eqv? (cdr '(a)) '()) #t) (test (eqv? 'a 'a) #t) (test (eqv? 'a 'b) #f) (test (eqv? 'a (string->symbol "a")) #t) (test (eqv? '(a) '(b)) #f) (test (let ((x '(a . b))) (eqv? x x)) #t) (test (let ((x (cons 'a 'b))) (eqv? x x)) #t) (test (eqv? (cons 'a 'b) (cons 'a 'b)) #f) (test (eqv? "abc" "cba") #f) (test (let ((x "hi")) (eqv? x x)) #t) (test (eqv? (string #\h #\i) (string #\h #\i)) #f) (test (eqv? #(a) #(b)) #f) (test (let ((x (vector 'a))) (eqv? x x)) #t) (test (eqv? (vector 'a) (vector 'a)) #f) (test (eqv? car car) #t) (test (eqv? car cdr) #f) (test (let ((x (lambda () 1))) (eqv? x x)) #t) (test (eqv? (lambda () 1) (lambda () 1)) #f) (test (let () (define (make-adder x) (lambda (y) (+ x y))) (eqv? (make-adder 1) (make-adder 1))) #f) (test (eqv? 9/2 9/2) #t) (test (eqv? quote quote) #t) (test (eqv? () ()) #t) (test (eqv? () '()) #t) ;(test (eqv? "" "") #f) (test (eqv? "hi" "hi") #f) ; unspecified (test (eqv? #() #()) #f) ; unspecified, but in s7 (eqv? () ()) is #t (let ((c1 (let ((x 32)) (lambda () x))) (c2 (let ((x 123)) (lambda () x)))) (test (eqv? c1 c2) #f) (test (eqv? c1 c1) #t)) (test (eqv? most-positive-fixnum most-positive-fixnum) #t) (test (eqv? most-positive-fixnum most-negative-fixnum) #f) (test (eqv? 9223372036854775807 9223372036854775806) #f) (test (eqv? 9223372036854775807 -9223372036854775808) #f) (test (eqv? -9223372036854775808 -9223372036854775808) #t) (test (eqv? 123456789/2 123456789/2) #t) (test (eqv? 123456789/2 123456787/2) #f) (test (eqv? -123456789/2 -123456789/2) #t) (test (eqv? 2/123456789 2/123456789) #t) (test (eqv? -2/123456789 -2/123456789) #t) (test (eqv? 2147483647/2147483646 2147483647/2147483646) #t) (test (eqv? 3/4 12/16) #t) (test (eqv? 1/1 1) #t) (test (eqv? 312689/99532 833719/265381) #f) (test (let ((x 3.141)) (eqv? x x)) #t) (test (let ((x 1+i)) (eqv? x x)) #t) (test (let* ((x 3.141) (y x)) (eqv? x y)) #t) (test (let* ((x 1+i) (y x)) (eqv? x y)) #t) (test (let* ((x 3/4) (y x)) (eqv? x y)) #t) (test (eqv? 1.0 1.0) #t) (test (eqv? 0.6 0.6) #t) (test (eqv? 0.6 0.60) #t) (test (eqv? 1+i 1+i) #t) (test (eqv? -3.14 -3.14) #t) (test (eqv? 1e2 1e2) #t) (test (eqv? #i3/5 #i3/5) #t) (test (eqv? #e0.6 #e0.6) #t) (test (eqv? 1 1.0) #f) (test (eqv? 1/2 0.5) #f) (test (eqv? 1 1/1) #t) (test (eqv? 0.5 5e-1) #t) (test (eqv? 1/0 1/0) #f) (test (let ((+nan.0 1/0)) (eqv? +nan.0 +nan.0)) #f) (test (eqv? (cons 'a 'b) (cons 'a 'c)) #f) (test (eqv? eqv? eqv?) #t) (test (eqv? #(1) #(1)) #f) (test (eqv? '(1) '(1)) #f) (test (eqv? '() '()) #t) (test (eqv? '() (list)) #t) (test (eqv? '(()) '(())) #f) (test (eqv? (list 'abs 'cons) '(abs cons)) #f) (let ((things (vector #t #f #\space '() "" 0 1 3/4 1+i 1.5 '(1 .2) #() (vector) (vector 1) (list 1) 'f 't #\t))) (let ((len (length things))) (do ((i 0 (+ i 1))) ((= i (- len 1))) (do ((j (+ i 1) (+ j 1))) ((= j len)) (if (eqv? (vector-ref things i) (vector-ref things j)) (format-logged #t ";(eqv? ~A ~A) -> #t?~%" (vector-ref things i) (vector-ref things j))))))) (test (eqv?) 'error) (test (eqv? #t) 'error) (test (eqv? #t #t #t) 'error) (test (eqv #f #f) 'error) (test (eqv? ''2 '2) #f) (test (eqv? '2 '2) #t) (test (eqv? '2 2) #t) (test (eqv? ''2 ''2) #f) (test (eqv? ''#\a '#\a) #f) (test (eqv? '#\a #\a) #t) (test (eqv? 'car car) #f) (test (eqv? ''() '()) #f) (test (eqv? '#f #f) #t) (test (eqv? '#f '#f) #t) (test (eqv? # #) #t) (test (eqv? # #) #t) (test (eqv? # #) #t) (test (eqv? (if #f #f) #) #t) (test (eqv? # #) #f) (test (eqv? # '()) #f) (test (let () (define-macro (hi a) `(+ 1 ,a)) (eqv? hi hi)) #t) (test (let () (define (hi a) (+ 1 a)) (eqv? hi hi)) #t) (test (let ((x (lambda* (hi (a 1)) (+ 1 a)))) (eqv? x x)) #t) (test (eqv? else else) #t) (test (let ((p (lambda (x) x))) (eqv? p p)) #t) (if with-bignums (begin (test (eqv? (bignum "1+i") (bignum "1+i")) #t) (test (eqv? (bignum "1+i") 1+i) #t) (test (eqv? 1+i (bignum "1+i")) #t) (test (eqv? (bignum "2.0") (bignum "2.0")) #t) (test (eqv? (bignum "2.0") (bignum "1.0")) #f) )) ;; from M Weaver: (test (list (eqv? +0.0 -0.0) (eqv? (complex +0.0 1.0) (complex -0.0 1.0)) (eqv? (complex 1.0 +0.0) (complex 1.0 -0.0))) '(#t #t #t)) (test (list (eq? +0.0 -0.0) (eq? (complex +0.0 1.0) (complex -0.0 1.0)) (eq? (complex 1.0 +0.0) (complex 1.0 -0.0))) '(#t #f #f)) (test (list (eq? +0 -0) (eq? (complex +0 1) (complex -0 1)) (eq? (complex 1 +0) (complex 1 -0))) '(#t #f #t)) ;;; -------------------------------------------------------------------------------- ;;; equal? (test (equal? 'a 3) #f) (test (equal? #t 't) #f) (test (equal? "abs" 'abc) #f) (test (equal? "hi" '(hi)) #f) (test (equal? "()" '()) #f) (test (equal? '(1) '(1)) #t) (test (equal? '(#f) '(#f)) #t) (test (equal? '(()) '(() . ())) #t) (test (equal? #\a #\b) #f) (test (equal? #\a #\a) #t) (test (let ((x (string-ref "hi" 0))) (equal? x x)) #t) (test (equal? #t #t) #t) (test (equal? #f #f) #t) (test (equal? #f #t) #f) (test (equal? (null? '()) #t) #t) (test (equal? (null? '(a)) #f) #t) (test (equal? (cdr '(a)) '()) #t) (test (equal? 'a 'a) #t) (test (equal? 'a 'b) #f) (test (equal? 'a (string->symbol "a")) #t) (test (equal? '(a) '(b)) #f) (test (equal? '(a) '(a)) #t) (test (let ((x '(a . b))) (equal? x x)) #t) (test (let ((x (cons 'a 'b))) (equal? x x)) #t) (test (equal? (cons 'a 'b) (cons 'a 'b)) #t) (test (equal?(cons 'a 'b)(cons 'a 'b)) #t) ; no space (test (equal? "abc" "cba") #f) (test (equal? "abc" "abc") #t) (test (let ((x "hi")) (equal? x x)) #t) (test (equal? (string #\h #\i) (string #\h #\i)) #t) (test (equal? #(a) #(b)) #f) (test (equal? #(a) #(a)) #t) (test (let ((x (vector 'a))) (equal? x x)) #t) (test (equal? (vector 'a) (vector 'a)) #t) (test (equal? #(1 2) (vector 1 2)) #t) (test (equal? #(1.0 2/3) (vector 1.0 2/3)) #t) (test (equal? #(1 2) (vector 1 2.0)) #f) ; 2 not equal 2.0! (test (equal? '(1 . 2) (cons 1 2)) #t) (test (equal? '(1 #||# . #||# 2) (cons 1 2)) #t) (test (- '#||#1) -1) ; hmm (test (equal? #(1 "hi" #\a) (vector 1 "hi" #\a)) #t) (test (equal? #((1 . 2)) (vector (cons 1 2))) #t) (test (equal? #(1 "hi" #\a (1 . 2)) (vector 1 "hi" #\a (cons 1 2))) #t) (test (equal? #(#f hi (1 2) 1 "hi" #\a (1 . 2)) (vector #f 'hi (list 1 2) 1 "hi" #\a (cons 1 2))) #t) (test (equal? #(#(1) #(1)) (vector (vector 1) (vector 1))) #t) (test (equal? #(()) (vector '())) #t) (test (equal? #("hi" "ho") (vector "hi" '"ho")) #t) (test (equal? `#(1) #(1)) #t) (test (equal? ``#(1) #(1)) #t) (test (equal? '`#(1) #(1)) #t) (test (equal? ''#(1) #(1)) #f) (test (equal? ''#(1) '#(1)) #f) (test (equal? (list 1 "hi" #\a) '(1 "hi" #\a)) #t) (test (equal? (list 1.0 2/3) '(1.0 2/3)) #t) (test (equal? (list 1 2) '(1 2.0)) #f) (test (equal? #(1.0+1.0i) (vector 1.0+1.0i)) #t) (test (equal? (list 1.0+1.0i) '(1.0+1.0i)) #t) (test (equal? '((())) (list (list (list)))) #t) (test (equal? '((())) (cons (cons () ()) ())) #t) (test (equal? car car) #t) (test (equal? car cdr) #f) (test (let ((x (lambda () 1))) (equal? x x)) #t) (test (equal? (lambda () 1) (lambda () 1)) #f) (test (equal? 9/2 9/2) #t) (test (equal? #((())) #((()))) #t) (test (equal? "123""123") #t);no space (test (equal? """") #t)#|nospace|# (test (equal? #()#()) #t) (test (equal? #()()) #f) (test (equal? ()"") #f) (test (equal? "hi""hi") #t) (test (equal? # #) #t) (test (equal? # #) #t) (test (equal? # #) #t) (test (equal? (if #f #f) #) #t) (test (equal? # #) #f) (test (equal? (values) #) #f) (test (equal? (values) (values)) #t) (test (equal? # #) #f) (test (equal? (values) #) #t) (test (equal? # (values)) #t) (test (equal? # ()) #f) (test (let () (define-macro (hi a) `(+ 1 ,a)) (equal? hi hi)) #t) (test (let () (define (hi a) (+ 1 a)) (equal? hi hi)) #t) (test (let ((x (lambda* (hi (a 1)) (+ 1 a)))) (equal? x x)) #t) (test (equal? ``"" '"") #t) (test (let ((pws (dilambda (lambda () 1) (lambda (x) x)))) (equal? pws pws)) #t) (test (equal? if :if) #f) (test (equal? (list 'abs 'cons) '(abs cons)) #t) (test (equal? '(1) '(list 1)) #f) (test (equal? (values) #) #t) (test (equal? (list (values)) (list #)) #t) (test (equal? most-positive-fixnum most-positive-fixnum) #t) (test (equal? most-positive-fixnum most-negative-fixnum) #f) (test (equal? pi pi) #t) (test (equal? 9223372036854775807 9223372036854775806) #f) (test (equal? 9223372036854775807 -9223372036854775808) #f) (test (equal? -9223372036854775808 -9223372036854775808) #t) (test (equal? 123456789/2 123456789/2) #t) (test (equal? 123456789/2 123456787/2) #f) (test (equal? -123456789/2 -123456789/2) #t) (test (equal? 2/123456789 2/123456789) #t) (test (equal? -2/123456789 -2/123456789) #t) (test (equal? 2147483647/2147483646 2147483647/2147483646) #t) (test (equal? 3/4 12/16) #t) (test (equal? 1/1 1) #t) (test (equal? 312689/99532 833719/265381) #f) (test (let ((x 3.141)) (equal? x x)) #t) (test (let ((x 1+i)) (equal? x x)) #t) (test (let* ((x 3.141) (y x)) (equal? x y)) #t) (test (let* ((x 1+i) (y x)) (equal? x y)) #t) (test (let* ((x 3/4) (y x)) (equal? x y)) #t) (test (equal? '(+ '1) '(+ 1)) #f) ; !? (test (equal? '(1/0) '(1/0)) #f) (test (equal? '1/0 '1/0) #f) (test (let ((+nan.0 1/0)) (equal? '(+nan.0) '(+nan.0))) #t) (test (let ((+nan.0 1/0)) (equal? (list +nan.0) (list +nan.0))) #f) ;;; in the 1st case we're looking at the symbol, not its value (test (let ((+nan.0 1/0)) (equal? (vector +nan.0) (vector +nan.0))) #f) (test (let ((+nan.0 1/0)) (equal? #(1/0) #(1/0))) #f) (test (let ((x 3.141)) (equal? x x)) #t) (test (equal? 3 3) #t) (test (equal? 3 3.0) #f) (test (equal? 3.0 3.0) #t) (test (equal? 3-4i 3-4i) #t) (test (equal? (string #\c) "c") #t) (test (equal? equal? equal?) #t) (test (equal? (cons 1 (cons 2 3)) '(1 2 . 3)) #t) (test (equal? '() '()) #t) (test (equal? '() (list)) #t) (test (equal? (cdr ' ''0) '((quote 0))) #t) (test (equal? "\n" "\n") #t) (test (equal? #f ((lambda () #f))) #t) (test (equal? (+) 0) #t) (test (equal? (recompose 32 list '(1)) (recompose 32 list (list 1))) #t) (test (equal? (recompose 100 list '(1)) (recompose 100 list (list 1))) #t) (test (equal? (recompose 32 vector 1) (recompose 32 vector 1)) #t) (test (equal? (reinvert 32 list vector 1) (reinvert 32 list vector 1)) #t) (test (equal? (recompose 32 (lambda (a) (cons 1 a)) ()) (recompose 32 (lambda (a) (cons 1 a)) ())) #t) (test (equal? (recompose 32 (lambda (a) (list 1 a)) ()) (recompose 32 (lambda (a) (list 1 a)) ())) #t) (test (equal? "asd""asd") #t) ; is this the norm? (let ((streq (lambda (a b) (equal? a b)))) (test (streq "asd""asd") #t)) (let ((things (vector #t #f #\space () "" 0 1 3/4 1+i 1.5 '(1 .2) #() (vector 1) (list 1) 'f 't #\t))) (let ((len (length things))) (do ((i 0 (+ i 1))) ((= i (- len 1))) (do ((j (+ i 1) (+ j 1))) ((= j len)) (if (equal? (vector-ref things i) (vector-ref things j)) (format-logged #t ";(equal? ~A ~A) -> #t?~%" (vector-ref things i) (vector-ref things j))))))) (test (equal?) 'error) (test (equal? #t) 'error) (test (equal? #t #t #t) 'error) (test (equal #t #t) 'error) (when with-block (let ((b (make-block 4))) (test (equal? b b) #t) (let ((b1 (make-block 4))) (test (equal? b b1) #t) (set! (b 1) 1.0) (test (equal? b b1) #f)))) (test (let ((p (c-pointer 0))) (equal? p (copy p))) #t) (test (call-with-exit (lambda (return) (return (equal? return return)))) #t) (test (call-with-exit (lambda (return) (call-with-exit (lambda (quit) (return (equal? return quit)))))) #f) (test (call/cc (lambda (return) (return (equal? return return)))) #t) (test (let hiho ((i 0)) (equal? hiho hiho)) #t) (test (let hiho ((i 0)) (let hoho ((i 0)) (equal? hiho hoho))) #f) (test (equal? + *) #f) (test (equal? lambda lambda) #t) (test (equal? lambda lambda*) #f) (test (equal? let let) #t) (test (equal? let letrec) #f) (test (equal? define define) #t) (test (equal? + ((lambda (a) a) +)) #t) (test (let ((x "hi")) (define (hi) x) (equal? (hi) (hi))) #t) ;; so (eq? 3/4 3/4) is #f, (eqv? 3/4 3/4) is #t, ;; (eqv? #(1) #(1)) is #f, (equal? #(1) #(1)) is #t ;; (equal? 3 3.0) is #f, (= 3 3.0) is #t ;; in s7 ;; (eq? 0.0 0.0) is #t, ;; (eq? 2.0 2.0) is #f (test (equal? .0 0.) #t) (test (equal? (list "hi" (integer->char 65) 1 'a-symbol (make-vector 3) (list) (cons 1 2) abs quasiquote 3 3/4 1.0+1.0i #\f (if #f #f) # #) (list "hi" (integer->char 65) 1 'a-symbol (make-vector 3) (list) (cons 1 2) abs quasiquote 3 3/4 1.0+1.0i #\f (if #f #f) # #)) #t) (test (equal? (vector "hi" (integer->char 65) 1 'a-symbol (make-vector 3) abs quasiquote 3 3/4 1.0+1.0i #\f (if #f #f) # #) (vector "hi" (integer->char 65) 1 'a-symbol (make-vector 3) abs quasiquote 3 3/4 1.0+1.0i #\f (if #f #f) # #)) #t) (test (equal? (make-string 3) (make-string 3)) #t) (test (equal? (make-list 3) (make-list 3)) #t) (test (equal? (make-vector 3) (make-vector 3)) #t) (unless with-bignums (test (equal? (random-state 100) (random-state 100)) #t)) (test (equal? (current-input-port) (current-input-port)) #t) (test (equal? (current-input-port) (current-output-port)) #f) (test (equal? *stdin* *stderr*) #f) (test (let ((l1 (list 'a 'b)) (l2 (list 'a 'b 'a 'b))) (set! (cdr (cdr l1)) l1) (set! (cdr (cdr (cdr (cdr l2)))) l2) (equal? l1 l2)) #t) (test (let ((l1 (list 'a 'b)) (l2 (list 'a 'b 'a))) (set! (cdr (cdr l1)) l1) (set! (cdr (cdr (cdr l2))) l2) (equal? l1 l2)) #f) (test (let ((v1 (vector 1 2 3)) (v2 (vector 1 2 3))) (set! (v1 1) v1) (set! (v2 1) v2) (equal? v1 v2)) #t) (test (let ((v1 (vector 1 2 3)) (v2 (vector 1 2 4))) (set! (v1 1) v1) (set! (v2 1) v2) (equal? v1 v2)) #f) (if with-bignums (begin (test (equal? (/ (* 5 most-positive-fixnum) (* 3 most-negative-fixnum)) -46116860184273879035/27670116110564327424) #t) )) ;;; -------------------------------------------------------------------------------- ;;; morally-equal? (test (morally-equal? 'a 3) #f) (test (morally-equal? #t 't) #f) (test (morally-equal? "abs" 'abc) #f) (test (morally-equal? "hi" '(hi)) #f) (test (morally-equal? "()" '()) #f) (test (morally-equal? '(1) '(1)) #t) (test (morally-equal? '(#f) '(#f)) #t) (test (morally-equal? '(()) '(() . ())) #t) (test (morally-equal? #\a #\b) #f) (test (morally-equal? #\a #\a) #t) (test (let ((x (string-ref "hi" 0))) (morally-equal? x x)) #t) (test (morally-equal? #t #t) #t) (test (morally-equal? #f #f) #t) (test (morally-equal? #f #t) #f) (test (morally-equal? (null? '()) #t) #t) (test (morally-equal? (null? '(a)) #f) #t) (test (morally-equal? (cdr '(a)) '()) #t) (test (morally-equal? 'a 'a) #t) (test (morally-equal? 'a 'b) #f) (test (morally-equal? 'a (string->symbol "a")) #t) (test (morally-equal? '(a) '(b)) #f) (test (morally-equal? '(a) '(a)) #t) (test (let ((x '(a . b))) (morally-equal? x x)) #t) (test (let ((x (cons 'a 'b))) (morally-equal? x x)) #t) (test (morally-equal? (cons 'a 'b) (cons 'a 'b)) #t) (test (morally-equal?(cons 'a 'b)(cons 'a 'b)) #t) ; no space (test (morally-equal? "abc" "cba") #f) (test (morally-equal? "abc" "abc") #t) (test (let ((x "hi")) (morally-equal? x x)) #t) (test (morally-equal? (string #\h #\i) (string #\h #\i)) #t) (test (morally-equal? #(a) #(b)) #f) (test (morally-equal? #(a) #(a)) #t) (test (let ((x (vector 'a))) (morally-equal? x x)) #t) (test (morally-equal? (vector 'a) (vector 'a)) #t) (test (morally-equal? #(1 2) (vector 1 2)) #t) (test (morally-equal? #(1.0 2/3) (vector 1.0 2/3)) #t) (test (morally-equal? #(1 2) (vector 1 2.0)) #t) (test (morally-equal? '(1 . 2) (cons 1 2)) #t) (test (morally-equal? '(1 #||# . #||# 2) (cons 1 2)) #t) (test (- '#||#1) -1) ; hmm (test (morally-equal? #(1 "hi" #\a) (vector 1 "hi" #\a)) #t) (test (morally-equal? #((1 . 2)) (vector (cons 1 2))) #t) (test (morally-equal? #(1 "hi" #\a (1 . 2)) (vector 1 "hi" #\a (cons 1 2))) #t) (test (morally-equal? #(#f hi (1 2) 1 "hi" #\a (1 . 2)) (vector #f 'hi (list 1 2) 1 "hi" #\a (cons 1 2))) #t) (test (morally-equal? #(#(1) #(1)) (vector (vector 1) (vector 1))) #t) (test (morally-equal? #(()) (vector '())) #t) (test (morally-equal? #("hi" "ho") (vector "hi" '"ho")) #t) (test (morally-equal? `#(1) #(1)) #t) (test (morally-equal? ``#(1) #(1)) #t) (test (morally-equal? '`#(1) #(1)) #t) (test (morally-equal? ''#(1) #(1)) #f) (test (morally-equal? ''#(1) '#(1)) #f) (test (morally-equal? (list 1 "hi" #\a) '(1 "hi" #\a)) #t) (test (morally-equal? (list 1.0 2/3) '(1.0 2/3)) #t) (test (morally-equal? (list 1 2) '(1 2.0)) #t) (test (morally-equal? #(1.0+1.0i) (vector 1.0+1.0i)) #t) (test (morally-equal? (list 1.0+1.0i) '(1.0+1.0i)) #t) (test (morally-equal? '((())) (list (list (list)))) #t) (test (morally-equal? car car) #t) (test (morally-equal? car cdr) #f) (test (let ((x (lambda () 1))) (morally-equal? x x)) #t) (test (morally-equal? (lambda () 1) (lambda () 1)) #t) (test (morally-equal? 9/2 9/2) #t) (test (morally-equal? #((())) #((()))) #t) (test (morally-equal? "123""123") #t);no space (test (morally-equal? """") #t)#|nospace|# (test (morally-equal? #()#()) #t) (test (morally-equal? #()()) #f) (test (morally-equal? ()"") #f) (test (morally-equal? "hi""hi") #t) (test (morally-equal? # #) #t) (test (morally-equal? # #) #t) (test (morally-equal? # #) #t) (test (morally-equal? (if #f #f) #) #t) (test (morally-equal? # #) #f) (test (morally-equal? # '()) #f) (test (morally-equal? (values) #) #f) (test (morally-equal? # (values)) #f) (test (morally-equal? (values) (values)) #t) (test (morally-equal? # #) #f) (test (morally-equal? (values) #) #t) (test (morally-equal? # (values)) #t) (test (let () (define-macro (hi a) `(+ 1 ,a)) (morally-equal? hi hi)) #t) (test (let () (define (hi a) (+ 1 a)) (morally-equal? hi hi)) #t) (test (let ((x (lambda* (hi (a 1)) (+ 1 a)))) (morally-equal? x x)) #t) (test (morally-equal? ``"" '"") #t) (test (let ((pws (dilambda (lambda () 1) (lambda (x) x)))) (morally-equal? pws pws)) #t) (test (morally-equal? if :if) #f) (test (morally-equal? (list 'abs 'cons) '(abs cons)) #t) (test (morally-equal? (make-int-vector 2 0) (vector 0 0)) #t) (test (morally-equal? (make-vector 2 0 #t) (make-vector 2 0)) #t) (test (morally-equal? (make-int-vector 2 0) (make-vector 2 0 #t)) #t) (test (morally-equal? (make-vector 2 0 #t) (make-float-vector 2)) #t) (test (morally-equal? (vector 0.0 0) (make-vector 2 0.0 #t)) #t) (test (morally-equal? (make-int-vector 2 0) (vector 0 1.0)) #f) (test (morally-equal? (make-vector 1 1.0 #t) (make-vector 1 1.0 #t)) #t) (test (morally-equal? (make-float-vector 1 -nan.0) (make-vector 1 -nan.0 #t)) #t) (test (morally-equal? (make-iterator "") (make-iterator "")) #t) (test (morally-equal? (make-iterator "1") (make-iterator "1" (cons 1 1))) #t) (test (morally-equal? (make-iterator "1" (cons 3 4)) (make-iterator "1" (cons 1 1))) #t) (test (morally-equal? (make-iterator #()) (make-iterator #())) #t) (let ((str "123")) (let ((i1 (make-iterator str)) (i2 (make-iterator str))) (test (equal? i1 i2) #t) (test (morally-equal? i1 i2) #t) (iterate i1) (test (equal? i1 i2) #f) (test (morally-equal? i1 i2) #f) (iterate i2) (test (equal? i1 i2) #t) (test (morally-equal? i1 i2) #t))) (let ((i1 (make-iterator "123")) (i2 (make-iterator "123"))) (test (morally-equal? i1 i2) #t) (iterate i1) (test (morally-equal? i1 i2) #f) (iterate i2) (test (morally-equal? i1 i2) #t)) (let ((i1 (make-iterator (vector 1 2 3))) (i2 (make-iterator (int-vector 1 2 3)))) (test (morally-equal? i1 i2) #t) (iterate i1) (test (morally-equal? i1 i2) #f) (iterate i2) (test (morally-equal? i1 i2) #t)) (let ((i1 (make-iterator (vector 1 2 3))) (i2 (make-iterator (vector 1 2 3)))) (test (equal? i1 i2) #t) (test (morally-equal? i1 i2) #t) (iterate i1) (test (equal? i1 i2) #f) (test (morally-equal? i1 i2) #f) (iterate i2) (test (equal? i1 i2) #t) (test (morally-equal? i1 i2) #t)) (let ((str (hash-table* 'a 1 'b 2))) (let ((i1 (make-iterator str)) (i2 (make-iterator str))) (test (equal? i1 i2) #t) (test (morally-equal? i1 i2) #t) (iterate i1) (test (equal? i1 i2) #f) (test (morally-equal? i1 i2) #f) (iterate i2) (test (equal? i1 i2) #t) (test (morally-equal? i1 i2) #t))) ;;; opt bug (test (morally-equal? ''(1) (list 1)) #f) (test (morally-equal? ''(1+i) '(1+i)) #f) (test (morally-equal? '(1) (list 1)) #t) (test (morally-equal? '(1) ''(1)) #f) (test (morally-equal? (list 1) ''(1)) #f) (test (morally-equal? (list 1) '(1)) #t) (test (morally-equal? ''(1) ''(1)) #t) (test (morally-equal? '''(1) ''(1)) #f) (let () (define-macro (mac a) `(+ 1 ,a)) (define-macro (mac1 a) `(+ 1 ,a)) (define-macro (mac2 a) `(+ 2 ,a)) (define-macro (mac3 a b) `(+ ,b ,a)) (test (morally-equal? mac mac1) #t) (test (morally-equal? mac mac2) #f) (test (morally-equal? mac1 mac3) #f) (test (morally-equal? mac3 mac3) #t) (let () (define-macro (mac4 a) `(+ 1 ,a)) (test (morally-equal? mac mac4) #t)) ; was #f (define-bacro (mac5 a) `(+ 1 ,a)) (test (morally-equal? mac mac5) #f) (define-bacro (mac6 a) `(+ 1 ,a)) (test (morally-equal? mac5 mac6) #t)) (test (morally-equal? most-positive-fixnum most-positive-fixnum) #t) (test (morally-equal? most-positive-fixnum most-negative-fixnum) #f) (test (morally-equal? pi pi) #t) (test (morally-equal? 9223372036854775807 9223372036854775806) #f) (test (morally-equal? 9223372036854775807 -9223372036854775808) #f) (test (morally-equal? -9223372036854775808 -9223372036854775808) #t) (test (morally-equal? 123456789/2 123456789/2) #t) (test (morally-equal? 123456789/2 123456787/2) #f) (test (morally-equal? -123456789/2 -123456789/2) #t) (test (morally-equal? 2/123456789 2/123456789) #t) (test (morally-equal? -2/123456789 -2/123456789) #t) (test (morally-equal? 2147483647/2147483646 2147483647/2147483646) #t) (test (morally-equal? 3/4 12/16) #t) (test (morally-equal? 1/1 1) #t) (test (morally-equal? 312689/99532 833719/265381) #f) (test (let ((x 3.141)) (morally-equal? x x)) #t) (test (let ((x 1+i)) (morally-equal? x x)) #t) (test (let* ((x 3.141) (y x)) (morally-equal? x y)) #t) (test (let* ((x 1+i) (y x)) (morally-equal? x y)) #t) (test (let* ((x 3/4) (y x)) (morally-equal? x y)) #t) (test (morally-equal? .1 1/10) #t) (test (morally-equal? pi '(1 2)) #f) (test (let ((x 3.141)) (morally-equal? x x)) #t) (test (morally-equal? 3 3) #t) (test (morally-equal? 3 3.0) #t) (test (morally-equal? 3.0 3.0) #t) (test (morally-equal? 3-4i 3-4i) #t) (test (morally-equal? 1/0 0/0) #t) (test (morally-equal? 1/0 (- 1/0)) #t) ; but they print as nan.0 and -nan.0 (this is C based I think), and equal? here is #f (test (morally-equal? (real-part (log 0)) (- (real-part (log 0)))) #f) (test (morally-equal? (log 0) (log 0)) #t) (test (morally-equal? 0/0+i 0/0+i) #t) (test (morally-equal? 0/0+i 0/0-i) #f) (test (morally-equal? (list 3) (list 3.0)) #t) (test (morally-equal? (list 3.0) (list 3.0)) #t) (test (morally-equal? (list 3-4i) (list 3-4i)) #t) (test (morally-equal? (list 1/0) (list 0/0)) #t) (test (morally-equal? (list (log 0)) (list (log 0))) #t) (test (morally-equal? (list 0/0+i) (list 0/0+i)) #t) (test (morally-equal? (vector 3) (vector 3.0)) #t) (test (morally-equal? (vector 3.0) (vector 3.0)) #t) (test (morally-equal? (vector 3-4i) (vector 3-4i)) #t) (test (morally-equal? (vector 1/0) (vector 0/0)) #t) (test (morally-equal? (vector (log 0)) (vector (log 0))) #t) (test (morally-equal? (vector 0/0+i) (vector 0/0+i)) #t) (test (morally-equal? (string #\c) "c") #t) (test (morally-equal? morally-equal? morally-equal?) #t) (test (morally-equal? (cons 1 (cons 2 3)) '(1 2 . 3)) #t) (test (morally-equal? '() '()) #t) (test (morally-equal? '() (list)) #t) (test (morally-equal? (cdr ' ''0) '((quote 0))) #t) (test (morally-equal? "\n" "\n") #t) (test (morally-equal? #f ((lambda () #f))) #t) (test (morally-equal? (+) 0) #t) (test (morally-equal? (recompose 32 list '(1)) (recompose 32 list (list 1))) #t) (test (morally-equal? (recompose 100 list '(1)) (recompose 100 list (list 1))) #t) (test (morally-equal? (recompose 32 vector 1) (recompose 32 vector 1)) #t) (test (morally-equal? (reinvert 32 list vector 1) (reinvert 32 list vector 1)) #t) (test (morally-equal? (recompose 32 (lambda (a) (cons 1 a)) ()) (recompose 32 (lambda (a) (cons 1 a)) ())) #t) (test (morally-equal? (recompose 32 (lambda (a) (list 1 a)) ()) (recompose 32 (lambda (a) (list 1 a)) ())) #t) (test (morally-equal? "asd""asd") #t) ; is this the norm? (let ((streq (lambda (a b) (morally-equal? a b)))) (test (streq "asd""asd") #t)) (let ((things (vector #t #f #\space () "" 0 1 3/4 1+i 1.5 '(1 .2) #() (vector 1) (list 1) 'f 't #\t))) (let ((len (length things))) (do ((i 0 (+ i 1))) ((= i (- len 1))) (do ((j (+ i 1) (+ j 1))) ((= j len)) (if (morally-equal? (vector-ref things i) (vector-ref things j)) (format-logged #t ";(morally-equal? ~A ~A) -> #t?~%" (vector-ref things i) (vector-ref things j))))))) (test (morally-equal?) 'error) (test (morally-equal? #t) 'error) (test (morally-equal? #t #t #t) 'error) (test (equal #t #t) 'error) (test (call-with-exit (lambda (return) (return (morally-equal? return return)))) #t) (test (call-with-exit (lambda (return) (call-with-exit (lambda (quit) (return (morally-equal? return quit)))))) #f) (test (call/cc (lambda (return) (return (morally-equal? return return)))) #t) (test (let hiho ((i 0)) (morally-equal? hiho hiho)) #t) (test (let hiho ((i 0)) (let hoho ((i 0)) (morally-equal? hiho hoho))) #f) (test (morally-equal? + *) #f) (test (morally-equal? lambda lambda) #t) (test (morally-equal? lambda lambda*) #f) (test (morally-equal? let let) #t) (test (morally-equal? let letrec) #f) (test (morally-equal? define define) #t) (test (morally-equal? + ((lambda (a) a) +)) #t) (test (let ((x "hi")) (define (hi) x) (morally-equal? (hi) (hi))) #t) (test (morally-equal? (list "hi" (integer->char 65) 1 'a-symbol (make-vector 3) (list) (cons 1 2) abs quasiquote 3 3/4 1.0+1.0i #\f (if #f #f) # #) (list "hi" (integer->char 65) 1 'a-symbol (make-vector 3) (list) (cons 1 2) abs quasiquote 3 3/4 1.0+1.0i #\f (if #f #f) # #)) #t) (test (morally-equal? (vector "hi" (integer->char 65) 1 'a-symbol (make-vector 3) abs quasiquote 3 3/4 1.0+1.0i #\f (if #f #f) # #) (vector "hi" (integer->char 65) 1 'a-symbol (make-vector 3) abs quasiquote 3 3/4 1.0+1.0i #\f (if #f #f) # #)) #t) (test (morally-equal? (make-string 3) (make-string 3)) #t) (test (morally-equal? (make-list 3) (make-list 3)) #t) (test (morally-equal? (make-vector 3) (make-vector 3)) #t) (test (morally-equal? (make-float-vector 3 1.0) (vector 1 1 1)) #t) (test (morally-equal? (make-vector 3 1.0 #t) (vector 1 1 1.1)) #f) (test (morally-equal? (make-vector 0 0.0 #t) (make-vector 0 0)) #t) (test (morally-equal? (int-vector 1) (int-vector 2)) #f) (test (morally-equal? (int-vector 1) (int-vector 1)) #t) (test (morally-equal? (float-vector 0.0) (float-vector nan.0)) #f) (test (morally-equal? (float-vector nan.0) (float-vector nan.0)) #t) (let ((old-err (*s7* 'morally-equal-float-epsilon))) (set! (*s7* 'morally-equal-float-epsilon) 0.0) (test (morally-equal? (float-vector 0.0) (float-vector nan.0)) #f) (test (morally-equal? (float-vector nan.0) (float-vector nan.0)) #t) (test (morally-equal? (float-vector 0.0) (float-vector 0.0)) #t) (test (morally-equal? (float-vector 0.0) (float-vector 1e-15)) #f) (set! (*s7* 'morally-equal-float-epsilon) 0.01) (test (morally-equal? (float-vector 0.0) (float-vector 1e-15)) #t) (test (morally-equal? (float-vector 0.0) (float-vector 0.005)) #t) (test (morally-equal? (float-vector 0.0) (float-vector 0.02)) #f) (set! (*s7* 'morally-equal-float-epsilon) old-err)) (unless with-bignums (test (morally-equal? (random-state 100) (random-state 100)) #t)) (test (morally-equal? (current-input-port) (current-input-port)) #t) (test (morally-equal? (current-input-port) (current-output-port)) #f) (test (morally-equal? *stdin* *stderr*) #f) (test (morally-equal? (let () (define-macro* (a_func (an_arg (lambda () #t))) `,an_arg) (a_func)) (let () (define-macro (a_func an_arg) `,an_arg) (a_func (lambda () #t)))) #t) ; was #f (test (morally-equal? (- 4/3 1 -63.0) 190/3) #t) (test (morally-equal? 190/3 (- 4/3 1 -63.0)) #t) (if (not with-bignums) (begin (test (morally-equal? (+ 5e-16 nan.0) nan.0) #t) (test (morally-equal? (+ 0+5e-16i nan.0) nan.0) #t) (test (morally-equal? (+ 1/0 0+5e-16i) 1/0) #t) (test (morally-equal? 1/0 (+ 1/0 0+5e-16i)) #t) (test (morally-equal? 0 (+ 0 5e-16)) #t) (test (morally-equal? 0 (- 0 1/1428571428571429)) #t) (test (morally-equal? 0 (+ 0 0+5e-16i)) #t) (test (morally-equal? 0 (+ 0 0-1/1428571428571429i)) #t) (test (morally-equal? 0 (+ 0 1e-11)) #f) (test (morally-equal? 0 0) #t) (test (morally-equal? 0 1/1000) #f) (test (morally-equal? 0 0.0) #t) (test (morally-equal? 0 1e-16) #t) (test (morally-equal? 0 0+i) #f) (test (morally-equal? 0 1e-16+i) #f) (test (morally-equal? 0 0+1e-16i) #t) (test (morally-equal? 0 1e-300) #t) (test (morally-equal? 0 0+1e-300i) #t) (test (morally-equal? 0 1/0) #f) (test (morally-equal? 0 (- 0/0)) #f) (test (morally-equal? 0 (log 0)) #f) (test (morally-equal? 1 (+ 1 5e-16)) #t) (test (morally-equal? 1 (- 1 1/1428571428571429)) #t) (test (morally-equal? 1 (+ 1 0+5e-16i)) #t) (test (morally-equal? 1 (+ 1 0-1/1428571428571429i)) #t) (test (morally-equal? 1 (+ 1 1e-11)) #f) (test (morally-equal? 1 1) #t) (test (morally-equal? 1 1.0) #t) (test (morally-equal? 1 1e-16) #f) (test (morally-equal? 1 1e4) #f) (test (morally-equal? 1 0+i) #f) (test (morally-equal? 1 1e-16+i) #f) (test (morally-equal? 1 (complex 1 1/0)) #f) (test (morally-equal? 1 (complex (real-part (log 0)) 1)) #f) (test (morally-equal? 1 (complex 1 (real-part (log 0)))) #f) (test (morally-equal? 1000 (+ 1000 5e-16)) #t) (test (morally-equal? 1000 (- 1000 1/1428571428571429)) #t) (test (morally-equal? 1000 (+ 1000 0+5e-16i)) #t) (test (morally-equal? 1000 (+ 1000 0-1/1428571428571429i)) #t) (test (morally-equal? 1000 (+ 1000 1e-11)) #f) (test (morally-equal? 1000 1000) #t) (test (morally-equal? 1000 1/1000) #f) (test (morally-equal? 1000 1e4) #f) (test (morally-equal? 1/1000 (+ 1/1000 5e-16)) #t) (test (morally-equal? 1/1000 (- 1/1000 1/1428571428571429)) #t) (test (morally-equal? 1/1000 (+ 1/1000 0+5e-16i)) #t) (test (morally-equal? 1/1000 (+ 1/1000 0-1/1428571428571429i)) #t) (test (morally-equal? 1/1000 (+ 1/1000 1e-11)) #f) (test (morally-equal? 1/1000 0) #f) (test (morally-equal? 1/1000 1/1000) #t) (test (morally-equal? 1/1000 0.0) #f) (test (morally-equal? 1/1000 1e-16) #f) (test (morally-equal? 1/1000 1e-16+i) #f) (test (morally-equal? 1/1000 0+1e-16i) #f) (test (morally-equal? 1/1000 1e-300) #f) (test (morally-equal? 1/1000 0+1e-300i) #f) (test (morally-equal? 1/1000 1/0) #f) (test (morally-equal? 0.0 (+ 0.0 5e-16)) #t) (test (morally-equal? 0.0 (- 0.0 1/1428571428571429)) #t) (test (morally-equal? 0.0 (+ 0.0 0+5e-16i)) #t) (test (morally-equal? 0.0 (+ 0.0 0-1/1428571428571429i)) #t) (test (morally-equal? 0.0 (+ 0.0 1e-11)) #f) (test (morally-equal? 0.0 0) #t) (test (morally-equal? 0.0 1/1000) #f) (test (morally-equal? 0.0 0.0) #t) (test (morally-equal? 0.0 1e-16) #t) (test (morally-equal? 0.0 0+i) #f) (test (morally-equal? 0.0 1+i) #f) (test (morally-equal? 0.0 1e-16+i) #f) (test (morally-equal? 0.0 0+1e-16i) #t) (test (morally-equal? 0.0 1e-300) #t) (test (morally-equal? 0.0 0+1e-300i) #t) (test (morally-equal? 0.0 1/0) #f) (test (morally-equal? 0.0 (real-part (log 0))) #f) (test (morally-equal? 0.0 (- (real-part (log 0)))) #f) (test (morally-equal? 0.0 (- 0/0)) #f) (test (morally-equal? 0.0 (log 0)) #f) (test (morally-equal? 1.0 (+ 1.0 5e-16)) #t) (test (morally-equal? 1.0 (- 1.0 1/1428571428571429)) #t) (test (morally-equal? 1.0 (+ 1.0 0+5e-16i)) #t) (test (morally-equal? 1.0 (+ 1.0 0-1/1428571428571429i)) #t) (test (morally-equal? 1.0 (+ 1.0 1e-11)) #f) (test (morally-equal? 1.0 1) #t) (test (morally-equal? 1.0 1.0) #t) (test (morally-equal? 1.0 1e-16+i) #f) (test (morally-equal? 1.0 0+1e-16i) #f) (test (morally-equal? 1.0 1e-300) #f) (test (morally-equal? 1.0 0+1e-300i) #f) (test (morally-equal? 1.0 1/0) #f) (test (morally-equal? 1.0 (- 0/0)) #f) (test (morally-equal? 1.0 (complex 1/0 1)) #f) (test (morally-equal? 1.0 (complex 1 1/0)) #f) (test (morally-equal? 1.0 (complex 1 (real-part (log 0)))) #f) (test (morally-equal? 1e-16 (+ 1e-16 5e-16)) #t) (test (morally-equal? 1e-16 (- 1e-16 1/1428571428571429)) #t) (test (morally-equal? 1e-16 (+ 1e-16 0+5e-16i)) #t) (test (morally-equal? 1e-16 (+ 1e-16 0-1/1428571428571429i)) #t) (test (morally-equal? 1e-16 (+ 1e-16 1e-11)) #f) (test (morally-equal? 1e-16 0) #t) (test (morally-equal? 1e-16 1/1000) #f) (test (morally-equal? 1e-16 0.0) #t) (test (morally-equal? 1e-16 1e-16) #t) (test (morally-equal? 1e-16 1e-16+i) #f) (test (morally-equal? 1e-16 0+1e-16i) #t) (test (morally-equal? 1e-16 1e-300) #t) (test (morally-equal? 1e-16 0+1e-300i) #t) (test (morally-equal? 1e-16 1/0) #f) (test (morally-equal? 1e4 (+ 1e4 5e-16)) #t) (test (morally-equal? 1e4 (- 1e4 1/1428571428571429)) #t) (test (morally-equal? 1e4 (+ 1e4 0+5e-16i)) #t) (test (morally-equal? 1e4 (+ 1e4 0-1/1428571428571429i)) #t) (test (morally-equal? 1e4 (+ 1e4 1e-11)) #f) (test (morally-equal? 1e4 1000) #f) (test (morally-equal? 1e4 1/1000) #f) (test (morally-equal? 1e4 1e-16) #f) (test (morally-equal? 1e4 1e4) #t) (test (morally-equal? 1e4 1e-16+i) #f) (test (morally-equal? 1e4 0+1e-16i) #f) (test (morally-equal? 1e4 1e-300) #f) (test (morally-equal? 1e4 0+1e-300i) #f) (test (morally-equal? 1e4 1/0) #f) (test (morally-equal? 0+i (+ 0+i 5e-16)) #t) (test (morally-equal? 0+i (- 0+i 1/1428571428571429)) #t) (test (morally-equal? 0+i (+ 0+i 0+5e-16i)) #t) (test (morally-equal? 0+i (+ 0+i 0-1/1428571428571429i)) #t) (test (morally-equal? 0+i (+ 0+i 1e-11)) #f) (test (morally-equal? 0+i 0) #f) (test (morally-equal? 0+i 1/1000) #f) (test (morally-equal? 0+i 0.0) #f) (test (morally-equal? 0+i 1e-16) #f) (test (morally-equal? 0+i 0+i) #t) (test (morally-equal? 0+i 1+i) #f) (test (morally-equal? 0+i 1e-16+i) #t) (test (morally-equal? 0+i 0+1e-16i) #f) (test (morally-equal? 0+i 1e-300) #f) (test (morally-equal? 0+i 0+1e-300i) #f) (test (morally-equal? 0+i 1/0) #f) (test (morally-equal? 0+i (real-part (log 0))) #f) (test (morally-equal? 0+i (- (real-part (log 0)))) #f) (test (morally-equal? 0+i (- 0/0)) #f) (test (morally-equal? 0+i (log 0)) #f) (test (morally-equal? 0+i (complex 1/0 1)) #f) (test (morally-equal? 0+i (complex 1 1/0)) #f) (test (morally-equal? 0+i (complex 1/0 1/0)) #f) (test (morally-equal? 0+i (complex (real-part (log 0)) 1/0)) #f) (test (morally-equal? 1+i (+ 1+i 5e-16)) #t) (test (morally-equal? 1+i (- 1+i 1/1428571428571429)) #t) (test (morally-equal? 1+i (+ 1+i 0+5e-16i)) #t) (test (morally-equal? 1+i (+ 1+i 0-1/1428571428571429i)) #t) (test (morally-equal? 1+i (+ 1+i 1e-11)) #f) (test (morally-equal? 1+i 0+i) #f) (test (morally-equal? 1+i 1+i) #t) (test (morally-equal? 1+i 1e-16+i) #f) (test (morally-equal? 1+i 0+1e-16i) #f) (test (morally-equal? 1+i 1e-300) #f) (test (morally-equal? 1+i 0+1e-300i) #f) (test (morally-equal? 1e-16+i (+ 1e-16+i 5e-16)) #t) (test (morally-equal? 1e-16+i (- 1e-16+i 1/1428571428571429)) #t) (test (morally-equal? 1e-16+i (+ 1e-16+i 0+5e-16i)) #t) (test (morally-equal? 1e-16+i (+ 1e-16+i 0-1/1428571428571429i)) #t) (test (morally-equal? 1e-16+i (+ 1e-16+i 1e-11)) #f) (test (morally-equal? 1e-16+i 0) #f) (test (morally-equal? 1e-16+i 1e-16) #f) (test (morally-equal? 1e-16+i 1e4) #f) (test (morally-equal? 1e-16+i 0+i) #t) (test (morally-equal? 1e-16+i 1+i) #f) (test (morally-equal? 1e-16+i 1e-16+i) #t) (test (morally-equal? 1e-16+i 0+1e-16i) #f) (test (morally-equal? 1e-16+i 1e-300) #f) (test (morally-equal? 1e-16+i 0+1e-300i) #f) (test (morally-equal? 1e-16+i 1/0) #f) (test (morally-equal? 1e-16+i (real-part (log 0))) #f) (test (morally-equal? 1e-16+i (- (real-part (log 0)))) #f) (test (morally-equal? 1e-16+i (- 0/0)) #f) (test (morally-equal? 1e-16+i (log 0)) #f) (test (morally-equal? 1e-16+i (complex 1/0 1)) #f) (test (morally-equal? 1e-16+i (complex 1 1/0)) #f) (test (morally-equal? 1e-16+i (complex 1/0 1/0)) #f) (test (morally-equal? 1e-16+i (complex (real-part (log 0)) 1/0)) #f) (test (morally-equal? 0+1e-16i (+ 0+1e-16i 5e-16)) #t) (test (morally-equal? 0+1e-16i (- 0+1e-16i 1/1428571428571429)) #t) (test (morally-equal? 0+1e-16i (+ 0+1e-16i 0+5e-16i)) #t) (test (morally-equal? 0+1e-16i (+ 0+1e-16i 0-1/1428571428571429i)) #t) (test (morally-equal? 0+1e-16i (+ 0+1e-16i 1e-11)) #f) (test (morally-equal? 0+1e-16i 0) #t) (test (morally-equal? 0+1e-16i 1/1000) #f) (test (morally-equal? 0+1e-16i 0.0) #t) (test (morally-equal? 0+1e-16i 1e-16) #t) (test (morally-equal? 0+1e-16i 0+i) #f) (test (morally-equal? 0+1e-16i 1+i) #f) (test (morally-equal? 0+1e-16i 1e-16+i) #f) (test (morally-equal? 0+1e-16i 0+1e-16i) #t) (test (morally-equal? 0+1e-16i 1e-300) #t) (test (morally-equal? 0+1e-16i 0+1e-300i) #t) (test (morally-equal? 0+1e-16i 1/0) #f) (test (morally-equal? 0+1e-16i (real-part (log 0))) #f) (test (morally-equal? 0+1e-16i (- (real-part (log 0)))) #f) (test (morally-equal? 0+1e-16i (- 0/0)) #f) (test (morally-equal? 0+1e-16i (log 0)) #f) (test (morally-equal? 1e-300 (+ 1e-300 5e-16)) #t) (test (morally-equal? 1e-300 (- 1e-300 1/1428571428571429)) #t) (test (morally-equal? 1e-300 (+ 1e-300 0+5e-16i)) #t) (test (morally-equal? 1e-300 (+ 1e-300 0-1/1428571428571429i)) #t) (test (morally-equal? 1e-300 (+ 1e-300 1e-11)) #f) (test (morally-equal? 1e-300 0) #t) (test (morally-equal? 1e-300 1/1000) #f) (test (morally-equal? 1e-300 0.0) #t) (test (morally-equal? 1e-300 1e-16) #t) (test (morally-equal? 1e-300 1e-16+i) #f) (test (morally-equal? 1e-300 0+1e-16i) #t) (test (morally-equal? 1e-300 1e-300) #t) (test (morally-equal? 1e-300 0+1e-300i) #t) (test (morally-equal? 1e-300 1/0) #f) (test (morally-equal? 1e-300 (- 0/0)) #f) (test (morally-equal? 1e-300 (log 0)) #f) (test (morally-equal? 0+1e-300i (+ 0+1e-300i 5e-16)) #t) (test (morally-equal? 0+1e-300i (- 0+1e-300i 1/1428571428571429)) #t) (test (morally-equal? 0+1e-300i (+ 0+1e-300i 0+5e-16i)) #t) (test (morally-equal? 0+1e-300i (+ 0+1e-300i 0-1/1428571428571429i)) #t) (test (morally-equal? 0+1e-300i (+ 0+1e-300i 1e-11)) #f) (test (morally-equal? 0+1e-300i 0) #t) (test (morally-equal? 0+1e-300i 1000) #f) (test (morally-equal? 0+1e-300i 1/1000) #f) (test (morally-equal? 0+1e-300i 0.0) #t) (test (morally-equal? 0+1e-300i 1e-16) #t) (test (morally-equal? 0+1e-300i 0+i) #f) (test (morally-equal? 0+1e-300i 1e-16+i) #f) (test (morally-equal? 0+1e-300i 0+1e-16i) #t) (test (morally-equal? 0+1e-300i 1e-300) #t) (test (morally-equal? 0+1e-300i 0+1e-300i) #t) (test (morally-equal? 0+1e-300i 1/0) #f) (test (morally-equal? 0+1e-300i (- 0/0)) #f) (test (morally-equal? 1/0 (+ 1/0 5e-16)) #t) (test (morally-equal? 1/0 (- 1/0 1/1428571428571429)) #t) (test (morally-equal? 1/0 (+ 1/0 0+5e-16i)) #t) (test (morally-equal? 1/0 (+ 1/0 0-1/1428571428571429i)) #t) (test (morally-equal? 1/0 0) #f) (test (morally-equal? 1/0 1/0) #t) (test (morally-equal? 1/0 (real-part (log 0))) #f) (test (morally-equal? 1/0 (- (real-part (log 0)))) #f) (test (morally-equal? 1/0 (- 0/0)) #t) (test (morally-equal? 1/0 (log 0)) #f) (test (morally-equal? 1/0 (complex 1/0 1)) #f) (test (morally-equal? 1/0 (complex 1 1/0)) #f) (test (morally-equal? 1/0 (complex 1/0 1/0)) #f) (test (morally-equal? 1/0 (complex (real-part (log 0)) 1/0)) #f) (test (morally-equal? 1/0 (complex 1/0 (real-part (log 0)))) #f) (test (morally-equal? 1/0 (complex (real-part (log 0)) (real-part (log 0)))) #f) (test (morally-equal? 1/0 (complex (real-part (log 0)) 1)) #f) (test (morally-equal? 1/0 (complex 1 (real-part (log 0)))) #f) (test (morally-equal? (real-part (log 0)) (+ (real-part (log 0)) 5e-16)) #t) (test (morally-equal? (real-part (log 0)) (- (real-part (log 0)) 1/1428571428571429)) #t) (test (morally-equal? (real-part (log 0)) (+ (real-part (log 0)) 0+5e-16i)) #t) (test (morally-equal? (real-part (log 0)) (+ (real-part (log 0)) 0-1/1428571428571429i)) #t) (test (morally-equal? (real-part (log 0)) 0) #f) (test (morally-equal? (real-part (log 0)) 1e-16+i) #f) (test (morally-equal? (real-part (log 0)) 0+1e-16i) #f) (test (morally-equal? (real-part (log 0)) 1e-300) #f) (test (morally-equal? (real-part (log 0)) 0+1e-300i) #f) (test (morally-equal? (real-part (log 0)) 1/0) #f) (test (morally-equal? (real-part (log 0)) (real-part (log 0))) #t) (test (morally-equal? (real-part (log 0)) (- (real-part (log 0)))) #f) (test (morally-equal? (real-part (log 0)) (- 0/0)) #f) (test (morally-equal? (real-part (log 0)) (log 0)) #f) (test (morally-equal? (real-part (log 0)) (complex 1/0 1)) #f) (test (morally-equal? (real-part (log 0)) (complex 1 1/0)) #f) (test (morally-equal? (real-part (log 0)) (complex 1/0 1/0)) #f) (test (morally-equal? (real-part (log 0)) (complex (real-part (log 0)) 1/0)) #f) (test (morally-equal? (real-part (log 0)) (complex 1/0 (real-part (log 0)))) #f) (test (morally-equal? (real-part (log 0)) (complex (real-part (log 0)) (real-part (log 0)))) #f) (test (morally-equal? (real-part (log 0)) (complex (real-part (log 0)) 1)) #f) (test (morally-equal? (real-part (log 0)) (complex 1 (real-part (log 0)))) #f) (test (morally-equal? (- (real-part (log 0))) (+ (- (real-part (log 0))) 5e-16)) #t) (test (morally-equal? (- (real-part (log 0))) (- (- (real-part (log 0))) 1/1428571428571429)) #t) (test (morally-equal? (- (real-part (log 0))) (+ (- (real-part (log 0))) 0+5e-16i)) #t) (test (morally-equal? (- (real-part (log 0))) (+ (- (real-part (log 0))) 0-1/1428571428571429i)) #t) (test (morally-equal? (- (real-part (log 0))) 1e-16+i) #f) (test (morally-equal? (- (real-part (log 0))) 0+1e-16i) #f) (test (morally-equal? (- (real-part (log 0))) 1e-300) #f) (test (morally-equal? (- (real-part (log 0))) 0+1e-300i) #f) (test (morally-equal? (- (real-part (log 0))) 1/0) #f) (test (morally-equal? (- (real-part (log 0))) (real-part (log 0))) #f) (test (morally-equal? (- (real-part (log 0))) (- (real-part (log 0)))) #t) (test (morally-equal? (- (real-part (log 0))) (- 0/0)) #f) (test (morally-equal? (- (real-part (log 0))) (log 0)) #f) (test (morally-equal? (- (real-part (log 0))) (complex 1/0 1)) #f) (test (morally-equal? (- (real-part (log 0))) (complex 1 1/0)) #f) (test (morally-equal? (- (real-part (log 0))) (complex 1/0 1/0)) #f) (test (morally-equal? (- (real-part (log 0))) (complex (real-part (log 0)) 1/0)) #f) (test (morally-equal? (- (real-part (log 0))) (complex 1/0 (real-part (log 0)))) #f) (test (morally-equal? (- (real-part (log 0))) (complex (real-part (log 0)) (real-part (log 0)))) #f) (test (morally-equal? (- (real-part (log 0))) (complex (real-part (log 0)) 1)) #f) (test (morally-equal? (- (real-part (log 0))) (complex 1 (real-part (log 0)))) #f) (test (morally-equal? (- 0/0) (+ (- 0/0) 5e-16)) #t) (test (morally-equal? (- 0/0) (- (- 0/0) 1/1428571428571429)) #t) (test (morally-equal? (- 0/0) (+ (- 0/0) 0+5e-16i)) #t) (test (morally-equal? (- 0/0) (+ (- 0/0) 0-1/1428571428571429i)) #t) (test (morally-equal? (- 0/0) 0) #f) (test (morally-equal? (- 0/0) 1e-300) #f) (test (morally-equal? (- 0/0) 0+1e-300i) #f) (test (morally-equal? (- 0/0) 1/0) #t) (test (morally-equal? (- 0/0) (real-part (log 0))) #f) (test (morally-equal? (- 0/0) (- (real-part (log 0)))) #f) (test (morally-equal? (- 0/0) (- 0/0)) #t) (test (morally-equal? (- 0/0) (log 0)) #f) (test (morally-equal? (- 0/0) (complex 1/0 1)) #f) (test (morally-equal? (- 0/0) (complex 1 1/0)) #f) (test (morally-equal? (- 0/0) (complex 1/0 1/0)) #f) (test (morally-equal? (- 0/0) (complex (real-part (log 0)) 1/0)) #f) (test (morally-equal? (- 0/0) (complex 1/0 (real-part (log 0)))) #f) (test (morally-equal? (- 0/0) (complex (real-part (log 0)) (real-part (log 0)))) #f) (test (morally-equal? (- 0/0) (complex (real-part (log 0)) 1)) #f) (test (morally-equal? (- 0/0) (complex 1 (real-part (log 0)))) #f) (test (morally-equal? (log 0) (+ (log 0) 5e-16)) #t) (test (morally-equal? (log 0) (- (log 0) 1/1428571428571429)) #t) (test (morally-equal? (log 0) (+ (log 0) 0+5e-16i)) #t) (test (morally-equal? (log 0) (+ (log 0) 0-1/1428571428571429i)) #t) (test (morally-equal? (log 0) 0) #f) (test (morally-equal? (log 0) 1/0) #f) (test (morally-equal? (log 0) (real-part (log 0))) #f) (test (morally-equal? (log 0) (- (real-part (log 0)))) #f) (test (morally-equal? (log 0) (- 0/0)) #f) (test (morally-equal? (log 0) (log 0)) #t) (test (morally-equal? (log 0) (complex 1/0 1)) #f) (test (morally-equal? (log 0) (complex 1 1/0)) #f) (test (morally-equal? (log 0) (complex 1/0 1/0)) #f) (test (morally-equal? (log 0) (complex (real-part (log 0)) 1/0)) #f) (test (morally-equal? (log 0) (complex 1/0 (real-part (log 0)))) #f) (test (morally-equal? (log 0) (complex (real-part (log 0)) (real-part (log 0)))) #f) (test (morally-equal? (log 0) (complex (real-part (log 0)) 1)) #f) (test (morally-equal? (log 0) (complex 1 (real-part (log 0)))) #f) (test (morally-equal? (complex 1/0 1) (+ (complex 1/0 1) 5e-16)) #t) (test (morally-equal? (complex 1/0 1) (- (complex 1/0 1) 1/1428571428571429)) #t) (test (morally-equal? (complex 1/0 1) (+ (complex 1/0 1) 0+5e-16i)) #t) (test (morally-equal? (complex 1/0 1) (+ (complex 1/0 1) 0-1/1428571428571429i)) #t) (test (morally-equal? (complex 1/0 1) 0) #f) (test (morally-equal? (complex 1/0 1) 1) #f) (test (morally-equal? (complex 1/0 1) 1e-16+i) #f) (test (morally-equal? (complex 1/0 1) 0+1e-16i) #f) (test (morally-equal? (complex 1/0 1) 1e-300) #f) (test (morally-equal? (complex 1/0 1) 0+1e-300i) #f) (test (morally-equal? (complex 1/0 1) 1/0) #f) (test (morally-equal? (complex 1/0 1) (real-part (log 0))) #f) (test (morally-equal? (complex 1/0 1) (- (real-part (log 0)))) #f) (test (morally-equal? (complex 1/0 1) (- 0/0)) #f) (test (morally-equal? (complex 1/0 1) (log 0)) #f) (test (morally-equal? (complex 1/0 1) (complex 1/0 1)) #t) (test (morally-equal? (complex 1/0 1) (complex 1 1/0)) #f) (test (morally-equal? (complex 1/0 1) (complex 1/0 1/0)) #f) (test (morally-equal? (complex 1/0 1) (complex (real-part (log 0)) 1/0)) #f) (test (morally-equal? (complex 1/0 1) (complex 1/0 (real-part (log 0)))) #f) (test (morally-equal? (complex 1/0 1) (complex (real-part (log 0)) (real-part (log 0)))) #f) (test (morally-equal? (complex 1/0 1) (complex (real-part (log 0)) 1)) #f) (test (morally-equal? (complex 1/0 1) (complex 1 (real-part (log 0)))) #f) (test (morally-equal? (complex 1 1/0) (+ (complex 1 1/0) 5e-16)) #t) (test (morally-equal? (complex 1 1/0) (- (complex 1 1/0) 1/1428571428571429)) #t) (test (morally-equal? (complex 1 1/0) (+ (complex 1 1/0) 0+5e-16i)) #t) (test (morally-equal? (complex 1 1/0) (+ (complex 1 1/0) 0-1/1428571428571429i)) #t) (test (morally-equal? (complex 1 1/0) 0) #f) (test (morally-equal? (complex 1 1/0) 1) #f) (test (morally-equal? (complex 1 1/0) 1e-300) #f) (test (morally-equal? (complex 1 1/0) 0+1e-300i) #f) (test (morally-equal? (complex 1 1/0) 1/0) #f) (test (morally-equal? (complex 1 1/0) (real-part (log 0))) #f) (test (morally-equal? (complex 1 1/0) (- (real-part (log 0)))) #f) (test (morally-equal? (complex 1 1/0) (- 0/0)) #f) (test (morally-equal? (complex 1 1/0) (log 0)) #f) (test (morally-equal? (complex 1 1/0) (complex 1/0 1)) #f) (test (morally-equal? (complex 1 1/0) (complex 1 1/0)) #t) (test (morally-equal? (complex 1 1/0) (complex 1/0 1/0)) #f) (test (morally-equal? (complex 1 1/0) (complex (real-part (log 0)) 1/0)) #f) (test (morally-equal? (complex 1 1/0) (complex 1/0 (real-part (log 0)))) #f) (test (morally-equal? (complex 1 1/0) (complex (real-part (log 0)) (real-part (log 0)))) #f) (test (morally-equal? (complex 1 1/0) (complex (real-part (log 0)) 1)) #f) (test (morally-equal? (complex 1 1/0) (complex 1 (real-part (log 0)))) #f) (test (morally-equal? (complex 1/0 1/0) (+ (complex 1/0 1/0) 5e-16)) #t) (test (morally-equal? (complex 1/0 1/0) (- (complex 1/0 1/0) 1/1428571428571429)) #t) (test (morally-equal? (complex 1/0 1/0) (+ (complex 1/0 1/0) 0+5e-16i)) #t) (test (morally-equal? (complex 1/0 1/0) (+ (complex 1/0 1/0) 0-1/1428571428571429i)) #t) (test (morally-equal? (complex 1/0 1/0) 0) #f) (test (morally-equal? (complex 1/0 1/0) 1/0) #f) (test (morally-equal? (complex 1/0 1/0) (real-part (log 0))) #f) (test (morally-equal? (complex 1/0 1/0) (- (real-part (log 0)))) #f) (test (morally-equal? (complex 1/0 1/0) (- 0/0)) #f) (test (morally-equal? (complex 1/0 1/0) (log 0)) #f) (test (morally-equal? (complex 1/0 1/0) (complex 1/0 1)) #f) (test (morally-equal? (complex 1/0 1/0) (complex 1 1/0)) #f) (test (morally-equal? (complex 1/0 1/0) (complex 1/0 1/0)) #t) (test (morally-equal? (complex 1/0 1/0) (complex (real-part (log 0)) 1/0)) #f) (test (morally-equal? (complex 1/0 1/0) (complex 1/0 (real-part (log 0)))) #f) (test (morally-equal? (complex 1/0 1/0) (complex (real-part (log 0)) (real-part (log 0)))) #f) (test (morally-equal? (complex 1/0 1/0) (complex (real-part (log 0)) 1)) #f) (test (morally-equal? (complex 1/0 1/0) (complex 1 (real-part (log 0)))) #f) (test (morally-equal? (complex (real-part (log 0)) 1/0) (+ (complex (real-part (log 0)) 1/0) 5e-16)) #t) (test (morally-equal? (complex (real-part (log 0)) 1/0) (- (complex (real-part (log 0)) 1/0) 1/1428571428571429)) #t) (test (morally-equal? (complex (real-part (log 0)) 1/0) (+ (complex (real-part (log 0)) 1/0) 0+5e-16i)) #t) (test (morally-equal? (complex (real-part (log 0)) 1/0) (+ (complex (real-part (log 0)) 1/0) 0-1/1428571428571429i)) #t) (test (morally-equal? (complex (real-part (log 0)) 1/0) 0) #f) (test (morally-equal? (complex (real-part (log 0)) 1/0) 1) #f) (test (morally-equal? (complex (real-part (log 0)) 1/0) 1000) #f) (test (morally-equal? (complex (real-part (log 0)) 1/0) 1/1000) #f) (test (morally-equal? (complex (real-part (log 0)) 1/0) 0.0) #f) (test (morally-equal? (complex (real-part (log 0)) 1/0) 1.0) #f) (test (morally-equal? (complex (real-part (log 0)) 1/0) 1e-16) #f) (test (morally-equal? (complex (real-part (log 0)) 1/0) 1e4) #f) (test (morally-equal? (complex (real-part (log 0)) 1/0) 1/0) #f) (test (morally-equal? (complex (real-part (log 0)) 1/0) (real-part (log 0))) #f) (test (morally-equal? (complex (real-part (log 0)) 1/0) (- (real-part (log 0)))) #f) (test (morally-equal? (complex (real-part (log 0)) 1/0) (- 0/0)) #f) (test (morally-equal? (complex (real-part (log 0)) 1/0) (log 0)) #f) (test (morally-equal? (complex (real-part (log 0)) 1/0) (complex 1/0 1)) #f) (test (morally-equal? (complex (real-part (log 0)) 1/0) (complex 1 1/0)) #f) (test (morally-equal? (complex (real-part (log 0)) 1/0) (complex 1/0 1/0)) #f) (test (morally-equal? (complex (real-part (log 0)) 1/0) (complex (real-part (log 0)) 1/0)) #t) (test (morally-equal? (complex (real-part (log 0)) 1/0) (complex 1/0 (real-part (log 0)))) #f) (test (morally-equal? (complex (real-part (log 0)) 1/0) (complex (real-part (log 0)) (real-part (log 0)))) #f) (test (morally-equal? (complex (real-part (log 0)) 1/0) (complex (real-part (log 0)) 1)) #f) (test (morally-equal? (complex (real-part (log 0)) 1/0) (complex 1 (real-part (log 0)))) #f) (test (morally-equal? (complex 1/0 (real-part (log 0))) (+ (complex 1/0 (real-part (log 0))) 5e-16)) #t) (test (morally-equal? (complex 1/0 (real-part (log 0))) (- (complex 1/0 (real-part (log 0))) 1/1428571428571429)) #t) (test (morally-equal? (complex 1/0 (real-part (log 0))) (+ (complex 1/0 (real-part (log 0))) 0+5e-16i)) #t) (test (morally-equal? (complex 1/0 (real-part (log 0))) (+ (complex 1/0 (real-part (log 0))) 0-1/1428571428571429i)) #t) (test (morally-equal? (complex 1/0 (real-part (log 0))) (real-part (log 0))) #f) (test (morally-equal? (complex 1/0 (real-part (log 0))) (- (real-part (log 0)))) #f) (test (morally-equal? (complex 1/0 (real-part (log 0))) (- 0/0)) #f) (test (morally-equal? (complex 1/0 (real-part (log 0))) (log 0)) #f) (test (morally-equal? (complex 1/0 (real-part (log 0))) (complex 1/0 1)) #f) (test (morally-equal? (complex 1/0 (real-part (log 0))) (complex 1 1/0)) #f) (test (morally-equal? (complex 1/0 (real-part (log 0))) (complex 1/0 1/0)) #f) (test (morally-equal? (complex 1/0 (real-part (log 0))) (complex (real-part (log 0)) 1/0)) #f) (test (morally-equal? (complex 1/0 (real-part (log 0))) (complex 1/0 (real-part (log 0)))) #t) (test (morally-equal? (complex 1/0 (real-part (log 0))) (complex (real-part (log 0)) (real-part (log 0)))) #f) (test (morally-equal? (complex 1/0 (real-part (log 0))) (complex (real-part (log 0)) 1)) #f) (test (morally-equal? (complex 1/0 (real-part (log 0))) (complex 1 (real-part (log 0)))) #f) (test (morally-equal? (complex (real-part (log 0)) (real-part (log 0))) (+ (complex (real-part (log 0)) (real-part (log 0))) 5e-16)) #t) (test (morally-equal? (complex (real-part (log 0)) (real-part (log 0))) (- (complex (real-part (log 0)) (real-part (log 0))) 1/1428571428571429)) #t) (test (morally-equal? (complex (real-part (log 0)) (real-part (log 0))) (+ (complex (real-part (log 0)) (real-part (log 0))) 0+5e-16i)) #t) (test (morally-equal? (complex (real-part (log 0)) (real-part (log 0))) (+ (complex (real-part (log 0)) (real-part (log 0))) 0-1/1428571428571429i)) #t) (test (morally-equal? (complex (real-part (log 0)) (real-part (log 0))) 0) #f) (test (morally-equal? (complex (real-part (log 0)) (real-part (log 0))) 1/0) #f) (test (morally-equal? (complex (real-part (log 0)) (real-part (log 0))) (real-part (log 0))) #f) (test (morally-equal? (complex (real-part (log 0)) (real-part (log 0))) (- (real-part (log 0)))) #f) (test (morally-equal? (complex (real-part (log 0)) (real-part (log 0))) (- 0/0)) #f) (test (morally-equal? (complex (real-part (log 0)) (real-part (log 0))) (log 0)) #f) (test (morally-equal? (complex (real-part (log 0)) (real-part (log 0))) (complex 1/0 1)) #f) (test (morally-equal? (complex (real-part (log 0)) (real-part (log 0))) (complex 1 1/0)) #f) (test (morally-equal? (complex (real-part (log 0)) (real-part (log 0))) (complex 1/0 1/0)) #f) (test (morally-equal? (complex (real-part (log 0)) (real-part (log 0))) (complex (real-part (log 0)) 1/0)) #f) (test (morally-equal? (complex (real-part (log 0)) (real-part (log 0))) (complex 1/0 (real-part (log 0)))) #f) (test (morally-equal? (complex (real-part (log 0)) (real-part (log 0))) (complex (real-part (log 0)) (real-part (log 0)))) #t) (test (morally-equal? (complex (real-part (log 0)) (real-part (log 0))) (complex (real-part (log 0)) 1)) #f) (test (morally-equal? (complex (real-part (log 0)) (real-part (log 0))) (complex 1 (real-part (log 0)))) #f) (test (morally-equal? (complex (real-part (log 0)) 1) (+ (complex (real-part (log 0)) 1) 5e-16)) #t) (test (morally-equal? (complex (real-part (log 0)) 1) (- (complex (real-part (log 0)) 1) 1/1428571428571429)) #t) (test (morally-equal? (complex (real-part (log 0)) 1) (+ (complex (real-part (log 0)) 1) 0+5e-16i)) #t) (test (morally-equal? (complex (real-part (log 0)) 1) (+ (complex (real-part (log 0)) 1) 0-1/1428571428571429i)) #t) (test (morally-equal? (complex (real-part (log 0)) 1) 0) #f) (test (morally-equal? (complex (real-part (log 0)) 1) 1) #f) (test (morally-equal? (complex (real-part (log 0)) 1) 0+1e-300i) #f) (test (morally-equal? (complex (real-part (log 0)) 1) 1/0) #f) (test (morally-equal? (complex (real-part (log 0)) 1) (real-part (log 0))) #f) (test (morally-equal? (complex (real-part (log 0)) 1) (- (real-part (log 0)))) #f) (test (morally-equal? (complex (real-part (log 0)) 1) (- 0/0)) #f) (test (morally-equal? (complex (real-part (log 0)) 1) (log 0)) #f) (test (morally-equal? (complex (real-part (log 0)) 1) (complex 1/0 1)) #f) (test (morally-equal? (complex (real-part (log 0)) 1) (complex 1 1/0)) #f) (test (morally-equal? (complex (real-part (log 0)) 1) (complex 1/0 1/0)) #f) (test (morally-equal? (complex (real-part (log 0)) 1) (complex (real-part (log 0)) 1/0)) #f) (test (morally-equal? (complex (real-part (log 0)) 1) (complex 1/0 (real-part (log 0)))) #f) (test (morally-equal? (complex (real-part (log 0)) 1) (complex (real-part (log 0)) (real-part (log 0)))) #f) (test (morally-equal? (complex (real-part (log 0)) 1) (complex (real-part (log 0)) 1)) #t) (test (morally-equal? (complex (real-part (log 0)) 1) (complex 1 (real-part (log 0)))) #f) (test (morally-equal? (complex 1 (real-part (log 0))) (+ (complex 1 (real-part (log 0))) 5e-16)) #t) (test (morally-equal? (complex 1 (real-part (log 0))) (- (complex 1 (real-part (log 0))) 1/1428571428571429)) #t) (test (morally-equal? (complex 1 (real-part (log 0))) (+ (complex 1 (real-part (log 0))) 0+5e-16i)) #t) (test (morally-equal? (complex 1 (real-part (log 0))) (+ (complex 1 (real-part (log 0))) 0-1/1428571428571429i)) #t) (test (morally-equal? (complex 1 (real-part (log 0))) (real-part (log 0))) #f) (test (morally-equal? (complex 1 (real-part (log 0))) (- (real-part (log 0)))) #f) (test (morally-equal? (complex 1 (real-part (log 0))) (- 0/0)) #f) (test (morally-equal? (complex 1 (real-part (log 0))) (log 0)) #f) (test (morally-equal? (complex 1 (real-part (log 0))) (complex 1/0 1)) #f) (test (morally-equal? (complex 1 (real-part (log 0))) (complex 1 1/0)) #f) (test (morally-equal? (complex 1 (real-part (log 0))) (complex 1/0 1/0)) #f) (test (morally-equal? (complex 1 (real-part (log 0))) (complex (real-part (log 0)) 1/0)) #f) (test (morally-equal? (complex 1 (real-part (log 0))) (complex 1/0 (real-part (log 0)))) #f) (test (morally-equal? (complex 1 (real-part (log 0))) (complex (real-part (log 0)) (real-part (log 0)))) #f) (test (morally-equal? (complex 1 (real-part (log 0))) (complex (real-part (log 0)) 1)) #f) (test (morally-equal? (complex 1 (real-part (log 0))) (complex 1 (real-part (log 0)))) #t) )) ; end with-bignums ;;; ---------------- ;;; try a bunch of combinations (define old-readers *#readers*) (set! *#readers* (cons (cons #\_ (lambda (str) (if (string=? str "__line__") (port-line-number) #f))) *#readers*)) (let ((lst1 ()) (lst2 ())) (if (not (eq? lst1 lst2)) (format-logged #t ";~A: nils are not eq?~%" #__line__)) (if (not (eqv? lst1 lst2)) (format-logged #t ";~A: nils are not eqv?~%" #__line__)) (if (not (equal? lst1 lst2)) (format-logged #t ";~A: nils are not equal?~%" #__line__)) (let ((v1 (make-vector 100 #f)) (v2 (make-vector 100 #f))) (if (not (equal? v1 v2)) (format-logged #t ";~A: base vectors are not equal?~%" #__line__)) (let ((h1 (make-hash-table)) (h2 (make-hash-table))) (if (not (equal? h1 h2)) (format-logged #t ";~A: base hash-tables are not equal?~%" #__line__)) (let ((e1 (sublet (curlet))) (e2 (sublet (curlet)))) (if (not (equal? e1 e2)) (format-logged #t ";~A: base environments are not equal?~%" #__line__)) (let ((ctr 0)) (for-each (lambda (arg1 arg2) ;; make sure the args are eq? to themselves ;; if equal? and equal to copy place in lst1, place copy in lst2, check that they are still equal ;; similarly for vector, hash-table, envs (let ((a1 arg1) (a2 arg2)) (if (not (eq? a1 arg1)) (format-logged #t ";~A: ~A is not eq? to itself? ~A~%" #__line__ arg1 a1)) (if (and (eq? a1 a2) (not (eqv? a1 a2))) (format-logged #t ";~A: ~A is eq? but not eqv? ~A~%" #__line__ a1 a2)) (if (equal? a1 a2) (begin (if (and (eq? a1 a2) (not (eqv? a1 a2))) (format-logged #t ";~A: ~A is eq? and equal? but not eqv?? ~A~%" #__line__ a1 a2)) (if (not (morally-equal? a1 a2)) (format-logged #t ";~A: ~A is equal? but not morally-equal? ~A~%" #__line__ a1 a2)) (set! lst1 (cons a1 lst1)) (set! lst2 (cons a2 lst2)) (set! (v1 ctr) a1) (set! (v2 ctr) a2) (let* ((sym1 (string->symbol (string-append "symbol-" (number->string ctr)))) (sym2 (copy sym1))) (set! (h1 sym1) a1) (set! (h2 sym2) a2) (varlet e1 (cons sym1 a1)) (varlet e2 (cons sym2 a2)) (if (not (equal? lst1 lst2)) (begin (format-logged #t ";~A: add ~A to lists, now not equal?~%" #__line__ a1) (set! lst1 (cdr lst1)) (set! lst2 (cdr lst2)))) (if (not (equal? v1 v2)) (begin (format-logged #t ";~A: add ~A to vectors, now not equal?~%" #__line__ a1) (set! (v1 ctr) #f) (set! (v2 ctr) #f))) (if (not (equal? h1 h2)) (begin (format-logged #t ";~A: add ~A to hash-tables, now not equal?~%" #__line__ a1) (set! (h1 sym1) #f) (set! (h2 sym2) #f))) (if (not (equal? e1 e2)) (begin (format-logged #t ";~A: add ~A to environments, now not equal?~% ~A~% ~A~%" #__line__ a1 e1 e2) (eval `(set! ,sym1 #f) e1) (eval `(set! ,sym2 #f) e2))) )) (begin (if (eq? a1 arg1) (format-logged #t ";~A: ~A is eq? but not equal? ~A~%" #__line__ a1 a2)) (if (eqv? a1 arg1) (format-logged #t ";~A: ~A is eqv? but not equal? ~A~%" #__line__ a1 a2)) (format-logged #t ";~A: ~A is not equal to ~A~%" #__line__ a1 a2))) (set! ctr (+ ctr 1)))) (list "hi" "" (integer->char 65) #\space #\newline #\null 1 3/4 ;; 1.0 1+i pi (real-part (log 0)) 1e18 most-negative-fixnum most-positive-fixnum 'a-symbol (make-vector 3 #f) #() #2d((1 2) (3 4)) abs quasiquote macroexpand (log 0) (hash-table '(a . 1) '(b . 2)) (hash-table) (sublet (curlet) '(a . 1)) (rootlet) #f #t :hi # # # (cons 1 2) () '(1) (list (cons 1 2)) '(1 2 . 3) (let ((lst (cons 1 2))) (set-cdr! lst lst) lst) ) (list (string #\h #\i) (string) #\A #\space #\newline (integer->char 0) (- 2 1) (/ 3 4) ;; 1.0 1+i pi (real-part (log 0)) 1e18 -9223372036854775808 9223372036854775807 (string->symbol "a-symbol") (vector #f #f #f) (vector) #2d((1 2) (3 4)) abs quasiquote macroexpand (log 0) (let ((h (make-hash-table 31))) (set! (h 'a) 1) (set! (h 'b) 2) h) (make-hash-table 123) (sublet (curlet) '(a . 1)) (rootlet) #f #t :hi # # (if #f #f) '(1 . 2) (list) (list 1) (list (cons 1 2)) '(1 2 . 3) (let ((lst (cons 1 2))) (set-cdr! lst lst) lst) )) (set! (v1 ctr) lst1) (set! (v2 ctr) lst2) (set! ctr (+ ctr 1)) (if (not (equal? v1 v2)) (format-logged #t ";~A: add lists to vectors, now vectors not equal?~%" #__line__) (begin (set! lst1 (cons v1 lst1)) (set! lst2 (cons v2 lst2)) (if (not (equal? lst1 lst2)) (begin (format-logged #t ";~A: add vectors to lists, now lists not equal?~%" #__line__) (set! (h1 'lst1) lst1) (set! (h2 'lst2) lst2) (if (not (equal? h1 h2)) (format-logged #t ";~A: add lists to hash-tables, not hash-tables not equal?~%" #__line__) (begin (set! (v1 ctr) v1) (set! (v2 ctr) v2) (set! ctr (+ ctr 1)) (if (not (equal? v1 v2)) (format-logged #t ";~A: add vectors to themselves, now vectors not equal?~%" #__line__)) (if (not (equal? lst1 lst2)) (format-logged #t ";~A: add vectors to themselves, now lists not equal?~%" #__line__)) (set! (h1 'h1) h1) (set! (h2 'h2) h2) (if (not (equal? h1 h2)) (format-logged #t ";~A: add hash-tables to themselves, not hash-tables not equal?~%" #__line__)) ))))))))))) (set! *#readers* (cons (cons #\u (lambda (str) (string->number (substring str 1)))) ())) (test (eval (with-input-from-string "(+ 10 #u12)" read)) 22) (test (eval (with-input-from-string "(+ 10 #u87)" read)) 97) (do ((i (char->integer #\") (+ i 1))) ((= i 127)) (when (not (member (integer->char i) '(#\( #\: #\|))) (set! *#readers* (cons (cons (integer->char i) (lambda (str) (string->number (substring str 1)))) ())) (let ((val (eval (with-input-from-string (string-append "(+ 10 #" (string (integer->char i)) "12)") read)))) (if (not (equal? val 22)) (format *stderr* "~D (~C): ~A~%" i (integer->char i) val))))) (set! *#readers* old-readers) (when with-block (let ((b (make-block 4))) (test (morally-equal? b b) #t) (let ((b1 (make-block 4))) (test (morally-equal? b b1) #t) (set! (b 1) 1.0) (test (morally-equal? b b1) #f)))) (test (let ((p (c-pointer 0))) (morally-equal? p (copy p))) #t) ;;; -------------------------------------------------------------------------------- ;;; boolean? (test (boolean? #f) #t) (test (boolean? #t) #t) (test (boolean? 0) #f) (test (boolean? 1) #f) (test (boolean? "") #f) (test (boolean? #\0) #f) (test (boolean? ()) #f) (test (boolean? #()) #f) (test (boolean? 't) #f) (test (boolean? (list)) #f) (test ( boolean? #t) #t) (test (boolean? boolean?) #f) (test (boolean? or) #f) (test ( ; a comment boolean? ;;; and another #t ) #t) (for-each (lambda (arg) (if (boolean? arg) (format-logged #t ";(boolean? ~A) -> #t?~%" arg))) (list "hi" '(1 2) (integer->char 65) 1 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #\f (lambda (a) (+ a 1)) :hi (if #f #f) # #)) (test (recompose 12 boolean? #f) #t) (test (boolean?) 'error) (test (boolean? #f #t) 'error) (test (boolean #f) 'error) (test (boolean? (lambda (x) #f)) #f) (test (boolean? and) #f) (test (boolean? if) #f) (test (boolean? (values)) #f) ;(test (boolean? else) #f) ; this could also be an error -> unbound variable, like (symbol? else) ;;; -------------------------------------------------------------------------------- ;;; not (test (not #f) #t) (test (not #t) #f) (test (not (not #t)) #t) (test (not 0) #f) (test (not 1) #f) (test (not ()) #f) (test (not 't) #f) (test (not (list)) #f) (test (not (list 3)) #f) (test (not 'nil) #f) (test (not not) #f) (test (not "") #f) (test (not lambda) #f) (test (not quote) #f) (for-each (lambda (arg) (if (not arg) (format-logged #t ";(not ~A) -> #t?~%" arg))) (list "hi" (integer->char 65) 1 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #\f (lambda (a) (+ a 1)) :hi # # (if #f #f))) (test (recompose 12 not #f) #f) (test (not) 'error) (test (not #f #t) 'error) (test (not and) #f) (test (not case) #f) (let () ; check some optimizer branches (define (f1 sym) (not (symbol? sym))) (test (f1 'hi) #f) (test (f1 "hi") #t) (define (f2 sym) (not (integer? sym))) (test (f2 2) #f) (test (f2 'hi) #t) (define (f3 sym) (not (char? sym))) (test (f3 2) #t) (test (f3 #\a) #f) (define (f4 sym) (not (list? sym))) (test (f4 2) #t) (test (f4 '(1 2 3)) #f) (define (f5 sym) (not (boolean? sym))) (test (f5 2) #t) (test (f5 #f) #f) (define (f6 sym) (not (eof-object? sym))) (test (f6 2) #t) (test (f6 #) #f) (define (f7 sym) (not (pair? (car sym)))) (test (f7 '(hi)) #t) (test (f7 '((1))) #f) (define (f8 sym) (not (eq? sym 'q))) (test (f8 'a) #t) (test (f8 'q) #f) (define (f9 sym) (pair? (cadr sym))) (test (f9 '(1 2 3)) #f) (test (f9 '(1 (2 3) 4)) #t) (define (f10 lst val) (eq? (car lst) val)) (test (f10 '(#f) #f) #t) (test (f10 '(a) 32) #f) (define (f11 lst) (eq? (caar lst) 'q)) (test (f11 '((a))) #f) (test (f11 '((q))) #t) (define (f12 lst) (= (length lst) 2)) (test (f12 '(1 2)) #t) (test (f12 '(1 2 3)) #f) (define (f13 lst) (< (length lst) 2)) (test (f13 '(1 2)) #f) (test (f13 '(1)) #t) (define (f14 lst) (negative? (length lst))) (test (f14 '(1 2)) #f) (test (f14 '(1 . 3)) #t) (define (f15 lst) (memq (car lst) '(a b c))) (test (f15 '(a)) '(a b c)) (test (f15 '(d)) #f) (define (f16 a b) (if a (begin (+ b a) (format #f "~A" a) (+ a a)))) (test (f16 1 2) 2) (define (f17 a) (aritable? a 1)) (test (f17 abs) #t) (define (f18) (set! (-s7-symbol-table-locked?) #f)) (f18) (test (f18) #f) (define (f18a) (set! (-s7-symbol-table-locked?) #f)) (test (f18a) #f) (test (let () (f18a)) #f) (define (f19) (set! (-s7-symbol-table-locked?) #f) 1) (f19) (test (f19) 1) (define (f19a) (set! (-s7-symbol-table-locked?) #f) 1) (test (f19a) 1) (test (let () (f19a)) 1) (define (f20) (set! (-s7-symbol-table-locked?) #f) (+ 1 2)) (f20) (test (f20) 3) (define (f20a) (set! (-s7-symbol-table-locked?) #f) (+ 1 2)) (test (f20a) 3) (test (let () (f20a)) 3) (define (f21) (set! (-s7-symbol-table-locked?) #f) (+ 1 2) 4) (f21) (test (f21) 4) (define (f21a) (set! (-s7-symbol-table-locked?) #f) (+ 1 2) 4) (test (f21a) 4) (test (let () (f21a)) 4) (define (f22) (begin (display ":") (display (object->string 2)) (display ":"))) (test (with-output-to-string (lambda () (f22))) ":2:") (define (f23 a b) (list a b)) (define (f24 x y) (f23 (car x) (car y))) (define (f25 x y) (f23 (cdr x) (cdr y))) (test (f24 '(1 2) '(3 4)) '(1 3)) (test (f25 '(1 2) '(3 4)) '((2) (4))) (define (f24a s1 s2 s3) (+ (* s1 s2) (* (- 1.0 s1) s3))) (test (f24a 2.0 3.0 4.0) 2.0) (let () (define (a b) (define c 1) (+ b c)) (define (tst) (a 2)) (tst) (test (tst) 3)) (define (f25) (let ((x 0.0) (y 1.0)) (call-with-exit (lambda (return) (do ((i y (+ i 1))) ((= i 6)) (do ((i i (+ i 1))) ((>= i 7)) (set! x (+ x i)) (if (> x 123.0) (return x)))))) x)) (test (f25) 85.0) ) (let () (test (let () (define (ho a) (+ a 2)) (define (hi) (+ (ho 1) (ho 2))) (hi)) 7) (test (let () (define (ho a) (+ a 2)) (define (hi) (+ (ho 1) (values 3 4))) (hi)) 10) (test (let () (define (ho a) (+ a 2)) (define (hi) (+ (values 3 4) (ho 1))) (hi)) 10) (test (let () (define (hi) (+ (values 1 2) (values 3 4))) (hi)) 10) (test (let () (define (ho a) (values a 1)) (define (hi) (- (ho 2))) (hi)) 1) (test (let () (define (ho1) (s7-version)) (define (ho2) (ho1)) (string? (ho2))) #t) (test (let () (define (hi) (vector 0)) (define (ho) (hi)) (ho)) #(0))) (let () (define (make-it . names) (apply vector names)) (define (hi) (make-it pi pi pi pi)) (test (hi) (vector pi pi pi pi))) (test (let () (define (hi a b c d) (+ a (* (- b c) d))) (define (ho) (hi 1 2 3 4)) (ho)) -3) (test (let () (define (hi a b c d) (+ a (* d (- b c)))) (define (ho) (hi 1 2 3 4)) (ho)) -3) (test (let () (define (hi) (let ((x (values 1 2))) (if x (list x)))) (define (ho) (hi)) (catch #t (lambda () (ho)) (lambda args #f)) (ho)) 'error) (test (let () (define (hi a b) (- (+ a (abs b)))) (define (ho) (hi 1 -2)) (ho)) -3) (let () (define (e1) (((lambda () list)) 'a 'b 'c)) (define (e2) (e1)) (e2) (test (e2) '(a b c))) (let () (define (c1 s i) (case (string-ref s i) ((#\a) 1) (else 2))) (define (c3 s i) (c1 s i)) (c3 "hiho" 1) (test (c3 "hiho" 1) 2)) (let () (define (c1 s i) (case (string-ref s i) ((#\a) 1) ((#\i) 2))) (define (c3 s i) (c1 s i)) (c3 "hiho" 1) (test (c3 "hiho" 1) 2)) (let () (define (c1 s i) (case (string-ref s i) ((#\a #\h) 1) ((#\i #\o) 2))) (define (c3 s i) (c1 s i)) (c3 "hiho" 1) (test (c3 "hiho" 1) 2)) (let () (define (c1 s i) (case (string-ref s i) ((#\a #\h) 1) (else 2))) (define (c3 s i) (c1 s i)) (c3 "hiho" 1) (test (c3 "hiho" 1) 2)) (let () (define (d1) (do ((lst () (cons i lst)) (i 0 (+ i 1))) ((> i 6) (reverse lst)))) (define (d2) (d1)) (d2) (test (d2) '(0 1 2 3 4 5 6))) (let () (define (d3) ((define (hi a) (+ a 1)) 2)) (define (d4) (d3)) (d4) (test (d4) 3)) (let () (define (fif) (if (< 2 3) (quote . -1))) (catch #t fif (lambda args 'error)) (test (catch #t fif (lambda args 'error)) 'error)) ;(let () (define (fcond) (cond ((< 2 3) ((lambda (x) x 1 . 5) 2)))) (catch #t fcond (lambda args 'error)) (test (fcond) 'error)) ;(let () (define (fcond1) (cond ((< 2 3) ((lambda* (x) x . 5) 2)))) (catch #t fcond1 (lambda args 'error)) (test (fcond1) 'error)) ; those aren't what they appear to be: the catch does the stray dot check/error, then a call simply does what it can (let () (define (incsaa k i) (let ((sum 1)) (set! sum (+ sum (expt k i) (expt (- k) i))) sum)) (define (f1) (incsaa 3 2)) (test (f1) 19)) (let () (define (unks v1 i) (let ((x 0)) (set! x (v1 i)) x)) (define (f1) (unks (vector 1 2 3) 2)) (test (f1) 3)) ;;; -------------------------------------------------------------------------------- ;;; symbol? (test (symbol? 't) #t) (test (symbol? "t") #f) (test (symbol? '(t)) #f) (test (symbol? #t) #f) (test (symbol? 4) #f) (test (symbol? 'foo) #t) (test (symbol? (car '(a b))) #t) (test (symbol? 'nil) #t) (test (symbol? ()) #f) (test (symbol? #()) #f) (test (symbol? #f) #f) (test (symbol? 'car) #t) (test (symbol? car) #f) (test (symbol? '#f) #f) (test (symbol? #()) #f) (test (symbol? :hi) #t) (test (symbol? hi:) #t) (test (symbol? :hi:) #t) (test (symbol? ::) #t) (test (symbol? ':) #t) (test (symbol? '|) #t) (test (symbol? '|') #t) (test (symbol? '@) #t) ;(test (symbol? '#:) #t) ; confusable given guile-style keywords (test (symbol? #b1) #f) (test (symbol? 'sym0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789) #t) ;M Gran (test (symbol? (vector-ref #(1 a 34) 1)) #t) (test (if (symbol? '1+) (symbol? '0e) #t) #t) (test (symbol? 'begin) #t) (test (symbol? 'if) #t) (test (symbol? (keyword->symbol :if)) #t) (test (symbol? (string->symbol "if")) #t) (test (symbol? if) #f) (test (symbol? quote) #f) (test (symbol? '(AB\c () xyz)) #f) (for-each (lambda (arg) (if (symbol? arg) (format-logged #t ";(symbol? ~A) -> #t?~%" arg))) (list "hi" (integer->char 65) 1 (list 1 2) '#t '3 (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #\f (lambda (a) (+ a 1)) # #)) (test (symbol?) 'error) (test (symbol? 'hi 'ho) 'error) (test (symbol? 'hi 3) 'error) (test (symbol? 3 3) 'error) (test (symbol? 3 'hi) 'error) (test (symbol 'hi) 'error) ; symbol takes a string ;;; "Returns #t if obj is a symbol, otherwise returns #f" (r5|6rs.html) (test (symbol? begin) #f) ; ?? this is an error in Guile, it was #t in s7 (test (symbol? expt) #f) (test (symbol? if) #f) (test (symbol? and) #f) (test (symbol? lambda) #f) (test (symbol? 'let) #t) (test (symbol? call/cc) #f) (test (symbol? '1.2.3) #t) (test (symbol? '1.2) #f) (test (symbol? ''1.2) #f) (test (symbol? '"hi") #f) (test (let ((sym000000000000000000000 3)) (let ((sym000000000000000000001 4)) (+ sym000000000000000000000 sym000000000000000000001))) 7) (test (let ((11-1 10) (2012-4-19 21) (1+the-road 18) (-1+2 1) (1e. 2) (0+i' 3) (0.. 4)) (+ 11-1 2012-4-19 1+the-road -1+2 1e. 0+i' 0..)) 59) (test (let ((name "hiho")) (string-set! name 2 #\null) (symbol? (string->symbol name))) #t) ;;; -------------------------------------------------------------------------------- ;;; procedure? (test (procedure? car) #t) (test (procedure? procedure?) #t) (test (procedure? 'car) #f) (test (procedure? (lambda (x) x)) #t) (test (procedure? '(lambda (x) x)) #f) (test (call/cc procedure?) #t) ; ?? (test (let ((a (lambda (x) x))) (procedure? a)) #t) (test (letrec ((a (lambda () (procedure? a)))) (a)) #t) (test (let ((a 1)) (let ((a (lambda () (procedure? a)))) (a))) #f) (test (let () (define (hi) 1) (procedure? hi)) #t) (test (let () (define-macro (hi a) `(+ ,a 1)) (procedure? hi)) #f) (test (procedure? begin) #f) (test (procedure? lambda) #f) (test (procedure? (lambda* ((a 1)) a)) #t) (test (procedure? and) #f) (test (procedure? 'let) #f) (test (procedure? (dilambda (lambda () 1) (lambda (x) x))) #t) (if with-bignums (test (procedure? (bignum "1e100")) #f)) (test (procedure? quasiquote) #f) (let () (define-macro (hi a) `(+ ,a 1)) (test (procedure? hi) #f)) (test (procedure? (random-state 1234)) #f) (test (procedure? pi) #f) (test (procedure? cond) #f) (test (procedure? do) #f) (test (procedure? set!) #f) (for-each (lambda (arg) (if (procedure? arg) (format-logged #t ";(procedure? ~A) -> #t?~%" arg))) (list "hi" _ht_ _null_ _c_obj_ :hi (integer->char 65) 1 (list 1 2) '#t '3 (make-vector 3) 3.14 3/4 1.0+1.0i #\f #() (if #f #f))) (test (procedure?) 'error) (test (procedure? abs car) 'error) (test (procedure abs) 'error) ;; these are questionable -- an applicable object is a procedure (test (procedure? "hi") #f) (test (procedure? '(1 2)) #f) (test (procedure? #(1 2)) #f) ;;; -------------------------------------------------------------------------------- ;;; CHARACTERS ;;; -------------------------------------------------------------------------------- (test (eqv? '#\ #\space) #t) (test (eqv? #\newline '#\newline) #t) ;;; -------------------------------------------------------------------------------- ;;; char? (test (char? #\a) #t) (test (char? #\() #t) (test (char? #\space) #t) (test (char? '#\newline) #t) (test (char? #\1) #t) (test (char? #\$) #t) (test (char? #\.) #t) (test (char? #\\) #t) (test (char? #\)) #t) (test (char? #\%) #t) (test (char? '#\space) #t) (test (char? '#\ ) #t) (test (char? '#\newline) #t) (test (char? '#\a) #t) (test (char? '#\8) #t) (test (char? #\-) #t) (test (char? #\n) #t) (test (char? #\() #t) (test (char? #e1) #f) (test (char? #\#) #t) (test (char? #\x) #t) (test (char? #\o) #t) (test (char? #\b) #t) (test (char? #b101) #f) (test (char? #o73) #f) (test (char? #x73) #f) (test (char? 'a) #f) (test (char? 97) #f) (test (char? "a") #f) (test (char? (string-ref "hi" 0)) #t) (test (char? (string-ref (make-string 1) 0)) #t) (test (char? #\") #t) (test (char? #\') #t) (test (char? #\`) #t) (test (char? #\@) #t) (test (char? #) #f) (test (char? '1e311) #f) (for-each (lambda (arg) (if (char? arg) (format-logged #t ";(char? ~A) -> #t?~%" arg))) (list "hi" () (list 1) '(1 . 2) #f 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #f #t (if #f #f) :hi (lambda (a) (+ a 1)))) (test (char? begin) #f) (do ((i 0 (+ i 1))) ((= i 256)) (if (not (char? (integer->char i))) (format-logged #t ";(char? (integer->char ~A)) -> #f?~%" i))) (test (char?) 'error) (test (char? #\a #\b) 'error) (test (char #\a) 'error) (test (char? #\x65) #t) (test (char? #\x000000000065) #t) (test (char? #\x0) #t) (test (char=? #\x000 #\null) #t) (test (char=? #\x08 #\x8) #t) (test (char=? #\x0e #\xe) #t) ; Guile thinks both of these names are bogus (test (char=? #\x00e #\xe) #t) (test (char=? #\x0000e #\xe) #t) (test (char=? #\x00000000e #\xe) #t) ; hmmm -- surely this is a bug (test (char? #\xff) #t) ;; any larger number is a reader error (test (eval-string "(char? #\xbdca2cbec)") 'error) ; this can overflow internally! (test (eval-string "(char? #\\x#b0)") 'error) (test (eval-string "(char? #\\100)") 'error) (test (eval-string "(char? #\\x-65)") 'error) (test (eval-string "(char? #\\x6.5)") 'error) (test (eval-string "(char? #\\x6/5)") 'error) (test (eval-string "(char? #\\x6/3)") 'error) (test (eval-string "(char? #\\x6+i)") 'error) (test (eval-string "(char? #\\x6asd)") 'error) (test (eval-string "(char? #\\x6#)") 'error) (test (eval-string "(char? #\\x#b0") 'error) (test (eval-string "(char? #\\x#e0.0") 'error) (test (eval-string "(char? #\\x-0") 'error) (test (eval-string "(char? #\\x#e0e100") 'error) (test (eval-string "(char? #\\x1.4") 'error) (test (char=? #\x6a #\j) #t) (test (char? #\return) #t) (test (char? #\null) #t) (test (char? #\nul) #t) (test (char? #\linefeed) #t) (test (char? #\tab) #t) (test (char? #\space) #t) (test (char=? #\null #\nul) #t) (test (char=? #\newline #\linefeed) #t) (test (char=? #\return #\xd) #t) (test (char=? #\nul #\x0) #t) ;(test (char? #\ÿ) #t) ; this seems to involve unwanted translations in emacs? (test (eval-string (string-append "(char? " (format #f "#\\~C" (integer->char 255)) ")")) #t) (test (eval-string (string-append "(char? " (format #f "#\\~C" (integer->char 127)) ")")) #t) (test (apply char? (list (integer->char 255))) #t) (test (char? #\escape) #t) (test (char? #\alarm) #t) (test (char? #\backspace) #t) (test (char? #\delete) #t) (test (char=? #\delete #\backspace) #f) (num-test (let ((str (make-string 258 #\space))) (do ((i 1 (+ i 1))) ((= i 256)) (string-set! str i (integer->char i))) (string-set! str 257 (integer->char 0)) (string-length str)) 258) (let ((a-to-z (list #\a #\b #\c #\d #\e #\f #\g #\h #\i #\j #\k #\l #\m #\n #\o #\p #\q #\r #\s #\t #\u #\v #\x #\y #\z)) (cap-a-to-z (list #\A #\B #\C #\D #\E #\F #\G #\H #\I #\J #\K #\L #\M #\N #\O #\P #\Q #\R #\S #\T #\U #\V #\X #\Y #\Z)) (mixed-a-to-z (list #\a #\B #\c #\D #\e #\F #\g #\H #\I #\j #\K #\L #\m #\n #\O #\p #\Q #\R #\s #\t #\U #\v #\X #\y #\Z)) (digits (list #\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9))) ;;; -------------------------------------------------------------------------------- ;;; char-upper-case? (test (char-upper-case? #\a) #f) (test (char-upper-case? #\A) #t) (for-each (lambda (arg) (if (not (char-upper-case? arg)) (format-logged #t ";(char-upper-case? ~A) -> #f?~%" arg))) cap-a-to-z) (for-each (lambda (arg) (if (char-upper-case? arg) (format-logged #t ";(char-upper-case? ~A) -> #t?~%" arg))) a-to-z) (test (char-upper-case? (integer->char 192)) #t) ; 192..208 for unicode ;; non-alpha chars are "unspecified" here (test (char-upper-case? 1) 'error) (test (char-upper-case?) 'error) (test (char-upper-case? 1) 'error) (test (char-upper-case?) 'error) (test (char-upper-case? #\a #\b) 'error) (test (char-upper-case #\a) 'error) ;;; -------------------------------------------------------------------------------- ;;; char-lower-case? (test (char-lower-case? #\A) #f) (test (char-lower-case? #\a) #t) (for-each (lambda (arg) (if (not (char-lower-case? arg)) (format-logged #t ";(char-lower-case? ~A) -> #f?~%" arg))) a-to-z) (for-each (lambda (arg) (if (char-lower-case? arg) (format-logged #t ";(char-lower-case? ~A) -> #t?~%" arg))) cap-a-to-z) (test (char-lower-case? 1) 'error) (test (char-lower-case?) 'error) (test (char-lower-case? 1) 'error) (test (char-lower-case?) 'error) (test (char-lower-case? #\a #\b) 'error) (test (char-lower-case #\a) 'error) ;; (test (char-lower-case? #\xb5) #t) ; what is this? in Snd it's #t, in ex1 it's #f -- is this a locale choice? (test (char-lower-case? #\xb6) #f) (for-each (lambda (c) (test (and (not (char-upper-case? c)) (not (char-lower-case? c))) #t)) (map integer->char (list 0 1 2 3 32 33 34 170 182 247))) ;;; -------------------------------------------------------------------------------- ;;; char-upcase (test (char-upcase #\A) #\A) (test (char-upcase #\a) #\A) (test (char-upcase #\?) #\?) (test (char-upcase #\$) #\$) (test (char-upcase #\.) #\.) (test (char-upcase #\\) #\\) (test (char-upcase #\5) #\5) (test (char-upcase #\)) #\)) (test (char-upcase #\%) #\%) (test (char-upcase #\0) #\0) (test (char-upcase #\_) #\_) (test (char-upcase #\?) #\?) (test (char-upcase #\space) #\space) (test (char-upcase #\newline) #\newline) (test (char-upcase #\null) #\null) (test (char-upper-case? (char-upcase #\?)) #f) ; ! (test (char-lower-case? (char-downcase #\?)) #f) (test (char-upper-case? (char-upcase #\_)) #f) (test (or (char-upper-case? #\?) (char-lower-case? #\?)) #f) (for-each (lambda (arg1 arg2) (if (not (char=? (char-upcase arg1) arg2)) (format-logged #t ";(char-upcase ~A) != ~A?~%" arg1 arg2))) a-to-z cap-a-to-z) (do ((i 1 (+ i 1))) ((= i 256)) (if (and (not (char=? (integer->char i) (char-upcase (integer->char i)))) (not (char-alphabetic? (integer->char i)))) (format-logged #t ";(char-upcase ~A) -> ~A but not alphabetic?~%" (integer->char i) (char-upcase (integer->char i))))) (test (recompose 12 char-upcase #\a) #\A) (test (reinvert 12 char-upcase char-downcase #\a) #\a) (test (char-upcase) 'error) (test (char-upcase #\a #\b) 'error) (test (char-upcase #) 'error) (test (char-upcase #f) 'error) (test (char-upcase (list)) 'error) ;;; -------------------------------------------------------------------------------- ;;; char-downcase (test (char-downcase #\A) #\a) (test (char-downcase #\a) #\a) (test (char-downcase #\?) #\?) (test (char-downcase #\$) #\$) (test (char-downcase #\.) #\.) (test (char-downcase #\_) #\_) (test (char-downcase #\\) #\\) (test (char-downcase #\5) #\5) (test (char-downcase #\)) #\)) (test (char-downcase #\%) #\%) (test (char-downcase #\0) #\0) (test (char-downcase #\space) #\space) (for-each (lambda (arg1 arg2) (if (not (char=? (char-downcase arg1) arg2)) (format-logged #t ";(char-downcase ~A) != ~A?~%" arg1 arg2))) cap-a-to-z a-to-z) (test (recompose 12 char-downcase #\A) #\a) (test (char-downcase) 'error) (test (char-downcase #\a #\b) 'error) ;;; -------------------------------------------------------------------------------- ;;; char-numeric? (test (char-numeric? #\a) #f) (test (char-numeric? #\5) #t) (test (char-numeric? #\A) #f) (test (char-numeric? #\z) #f) (test (char-numeric? #\Z) #f) (test (char-numeric? #\0) #t) (test (char-numeric? #\9) #t) (test (char-numeric? #\space) #f) (test (char-numeric? #\;) #f) (test (char-numeric? #\.) #f) (test (char-numeric? #\-) #f) (test (char-numeric? (integer->char 200)) #f) (test (char-numeric? (integer->char 128)) #f) (test (char-numeric? (integer->char 216)) #f) ; 0 slash (test (char-numeric? (integer->char 189)) #f) ; 1/2 (for-each (lambda (arg) (if (char-numeric? arg) (format-logged #t ";(char-numeric? ~A) -> #t?~%" arg))) cap-a-to-z) (for-each (lambda (arg) (if (char-numeric? arg) (format-logged #t ";(char-numeric? ~A) -> #t?~%" arg))) a-to-z) (test (char-numeric?) 'error) (test (char-numeric? #\a #\b) 'error) ;;; -------------------------------------------------------------------------------- ;;; char-whitespace? (test (char-whitespace? #\a) #f) (test (char-whitespace? #\A) #f) (test (char-whitespace? #\z) #f) (test (char-whitespace? #\Z) #f) (test (char-whitespace? #\0) #f) (test (char-whitespace? #\9) #f) (test (char-whitespace? #\space) #t) (test (char-whitespace? #\tab) #t) (test (char-whitespace? #\newline) #t) (test (char-whitespace? #\return) #t) (test (char-whitespace? #\linefeed) #t) (test (char-whitespace? #\null) #f) (test (char-whitespace? #\;) #f) (test (char-whitespace? #\xb) #t) (test (char-whitespace? #\x0b) #t) (test (char-whitespace? #\xc) #t) (test (char-whitespace? #\xd) #t) ; #\return (test (char-whitespace? #\xe) #f) ;; unicode whitespace apparently: (test (char-whitespace? (integer->char 9)) #t) (test (char-whitespace? (integer->char 10)) #t) (test (char-whitespace? (integer->char 11)) #t) (test (char-whitespace? (integer->char 12)) #t) (test (char-whitespace? (integer->char 13)) #t) (test (char-whitespace? (integer->char 32)) #t) (test (char-whitespace? (integer->char 133)) #t) (test (char-whitespace? (integer->char 160)) #t) (for-each (lambda (arg) (if (char-whitespace? arg) (format-logged #t ";(char-whitespace? ~A) -> #t?~%" arg))) mixed-a-to-z) (for-each (lambda (arg) (if (char-whitespace? arg) (format-logged #t ";(char-whitespace? ~A) -> #t?~%" arg))) digits) (test (char-whitespace?) 'error) (test (char-whitespace? #\a #\b) 'error) ;;; -------------------------------------------------------------------------------- ;;; char-alphabetic? (test (char-alphabetic? #\a) #t) (test (char-alphabetic? #\$) #f) (test (char-alphabetic? #\A) #t) (test (char-alphabetic? #\z) #t) (test (char-alphabetic? #\Z) #t) (test (char-alphabetic? #\0) #f) (test (char-alphabetic? #\9) #f) (test (char-alphabetic? #\space) #f) (test (char-alphabetic? #\;) #f) (test (char-alphabetic? #\.) #f) (test (char-alphabetic? #\-) #f) (test (char-alphabetic? #\_) #f) (test (char-alphabetic? #\^) #f) (test (char-alphabetic? #\[) #f) ;(test (char-alphabetic? (integer->char 200)) #t) ; ?? (test (char-alphabetic? (integer->char 127)) #f) ; backspace (for-each (lambda (arg) (if (char-alphabetic? arg) (format-logged #t ";(char-alphabetic? ~A) -> #t?~%" arg))) digits) (for-each (lambda (arg) (if (not (char-alphabetic? arg)) (format-logged #t ";(char-alphabetic? ~A) -> #f?~%" arg))) mixed-a-to-z) (test (char-alphabetic?) 'error) (test (char-alphabetic? #\a #\b) 'error) (for-each (lambda (op) (for-each (lambda (arg) (test (op arg) 'error)) (list "hi" () (list 1) '(1 . 2) #f 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #f #t :hi (if #f #f) (lambda (a) (+ a 1))))) (list char-upper-case? char-lower-case? char-upcase char-downcase char-numeric? char-whitespace? char-alphabetic?)) (test (let ((unhappy ())) (do ((i 0 (+ i 1))) ((= i 256)) (let* ((ch (integer->char i)) (chu (char-upcase ch)) (chd (char-downcase ch))) (if (and (not (char=? ch chu)) (not (char-upper-case? chu))) (format-logged #t ";(char-upper-case? (char-upcase ~C)) is #f~%" ch)) (if (and (not (char=? ch chd)) (not (char-lower-case? chd))) (format-logged #t ";(char-lower-case? (char-downcase ~C)) is #f~%" ch)) (if (or (and (not (char=? ch chu)) (not (char=? ch (char-downcase chu)))) (and (not (char=? ch chd)) (not (char=? ch (char-upcase chd)))) (and (not (char=? ch chd)) (not (char=? ch chu))) (not (char-ci=? chu chd)) (not (char-ci=? ch chu)) (and (char-alphabetic? ch) (or (not (char-alphabetic? chd)) (not (char-alphabetic? chu)))) (and (char-numeric? ch) (or (not (char-numeric? chd)) (not (char-numeric? chu)))) (and (char-whitespace? ch) (or (not (char-whitespace? chd)) (not (char-whitespace? chu)))) (and (char-alphabetic? ch) (char-whitespace? ch)) (and (char-numeric? ch) (char-whitespace? ch)) (and (char-alphabetic? ch) (char-numeric? ch))) ;; there are characters that are alphabetic but the result of char-upcase is not an upper-case character ;; 223 for example, or 186 for lower case (set! unhappy (cons (format #f "~C: ~C ~C (~D)~%" ch chu chd i) unhappy))))) unhappy) ()) (for-each (lambda (op) (for-each (lambda (arg) (test (op #\a arg) 'error)) (list "hi" () (list 1) '(1 . 2) #f 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #f #t :hi (if #f #f) (lambda (a) (+ a 1))))) (list char=? char? char>=? char-ci=? char-ci? char-ci>=?)) (for-each (lambda (op) (for-each (lambda (arg) (test (op arg #\a) 'error)) (list "hi" () (list 1) '(1 . 2) #f 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #f #t :hi (if #f #f) (lambda (a) (+ a 1))))) (list char=? char? char>=? char-ci=? char-ci? char-ci>=?)) ;;; -------------------------------------------------------------------------------- ;;; char=? (test (char=? #\d #\d) #t) (test (char=? #\A #\a) #f) (test (char=? #\d #\x) #f) (test (char=? #\d #\D) #f) (test (char=? #\a #\a) #t) (test (char=? #\A #\B) #f) (test (char=? #\a #\b) #f) (test (char=? #\9 #\0) #f) (test (char=? #\A #\A) #t) (test (char=? #\ #\space) #t) (let ((i (char->integer #\space))) (test (char=? (integer->char i) #\space) #t)) (test (char=? (integer->char (char->integer #\")) #\") #t) (test (char=? #\x65 #\e) #t) (test (char=? #\d #\d #\d #\d) #t) (test (char=? #\d #\d #\x #\d) #f) (test (char=? #\d #\y #\x #\c) #f) (test (apply char=? cap-a-to-z) #f) (test (apply char=? mixed-a-to-z) #f) (test (apply char=? digits) #f) (test (char=? #\d #\c #\d) #f) (test (char=? #\a) 'error) (test (char=?) 'error) (test (char=? #\a 0) 'error) (test (char=? #\a #\b 0) 'error) ;;; -------------------------------------------------------------------------------- ;;; charchar #xf0) (integer->char #x70)) #f) (test (charchar 0) (integer->char 255)) #t) ;;; -------------------------------------------------------------------------------- ;;; char<=? (test (char<=? #\d #\x) #t) (test (char<=? #\d #\d) #t) (test (char<=? #\a #\e #\y #\z) #t) (test (char<=? #\a #\e #\e #\y) #t) (test (char<=? #\A #\B) #t) (test (char<=? #\a #\b) #t) (test (char<=? #\9 #\0) #f) (test (char<=? #\A #\A) #t) (test (char<=? #\space #\space) #t) (test (char<=? #\a #\e #\y #\z) #t) (test (char<=? #\a #\e #\e #\y) #t) (test (char<=? #\e #\e #\d #\y) #f) (test (apply char<=? a-to-z) #t) (test (apply char<=? cap-a-to-z) #t) (test (apply char<=? mixed-a-to-z) #f) (test (apply char<=? digits) #t) (test (apply char<=? (reverse a-to-z)) #f) (test (apply char<=? (reverse cap-a-to-z)) #f) (test (apply char<=? (reverse mixed-a-to-z)) #f) (test (apply char<=? (reverse digits)) #f) (test (char<=? #\b #\c #\a) #f) (test (char<=? #\B #\B #\A) #f) (test (char<=? #\b #\c #\e) #t) (test (char<=? #\b #\a "hi") 'error) (test (char<=? #\b #\a 0) 'error) (test (char<=?) 'error) ;;; -------------------------------------------------------------------------------- ;;; char>? (test (char>? #\e #\d) #t) (test (char>? #\z #\a) #t) (test (char>? #\A #\B) #f) (test (char>? #\a #\b) #f) (test (char>? #\9 #\0) #t) (test (char>? #\A #\A) #f) (test (char>? #\space #\space) #f) (test (char>? #\d #\c #\b #\a) #t) (test (char>? #\d #\d #\c #\a) #f) (test (char>? #\e #\d #\b #\c #\a) #f) (test (apply char>? a-to-z) #f) (test (apply char>? cap-a-to-z) #f) (test (apply char>? mixed-a-to-z) #f) (test (apply char>? digits) #f) (test (apply char>? (reverse a-to-z)) #t) (test (apply char>? (reverse cap-a-to-z)) #t) (test (apply char>? (reverse mixed-a-to-z)) #f) (test (apply char>? (reverse digits)) #t) (test (char>? #\d #\c #\a) #t) (test (char>? #\d #\c #\c) #f) (test (char>? #\B #\B #\C) #f) (test (char>? #\b #\c #\e) #f) (test (char>? (integer->char #xf0) (integer->char #x70)) #t) (test (char>? #\a #\b "hi") 'error) (test (char>? #\a #\b 0) 'error) (test (char>?) 'error) ;;; -------------------------------------------------------------------------------- ;;; char>=? (test (char>=? #\e #\d) #t) (test (char>=? #\A #\B) #f) (test (char>=? #\a #\b) #f) (test (char>=? #\9 #\0) #t) (test (char>=? #\A #\A) #t) (test (char>=? #\space #\space) #t) (test (char>=? #\d #\c #\b #\a) #t) (test (char>=? #\d #\d #\c #\a) #t) (test (char>=? #\e #\d #\b #\c #\a) #f) (test (apply char>=? a-to-z) #f) (test (apply char>=? cap-a-to-z) #f) (test (apply char>=? mixed-a-to-z) #f) (test (apply char>=? digits) #f) (test (apply char>=? (reverse a-to-z)) #t) (test (apply char>=? (reverse cap-a-to-z)) #t) (test (apply char>=? (reverse mixed-a-to-z)) #f) (test (apply char>=? (reverse digits)) #t) (test (char>=? #\d #\c #\a) #t) (test (char>=? #\d #\c #\c) #t) (test (char>=? #\B #\B #\C) #f) (test (char>=? #\b #\c #\e) #f) (test (char>=? #\a #\b "hi") 'error) (test (char>=? #\a #\b 0) 'error) (test (char>=?) 'error) ;;; -------------------------------------------------------------------------------- ;;; char-ci=? (test (char-ci=? #\A #\B) #f) (test (char-ci=? #\a #\B) #f) (test (char-ci=? #\A #\b) #f) (test (char-ci=? #\a #\b) #f) (test (char-ci=? #\9 #\0) #f) (test (char-ci=? #\A #\A) #t) (test (char-ci=? #\A #\a) #t) (test (char-ci=? #\a #\A) #t) (test (char-ci=? #\space #\space) #t) (test (char-ci=? #\d #\D #\d #\d) #t) (test (char-ci=? #\d #\d #\X #\d) #f) (test (char-ci=? #\d #\Y #\x #\c) #f) (test (apply char-ci=? cap-a-to-z) #f) (test (apply char-ci=? mixed-a-to-z) #f) (test (apply char-ci=? digits) #f) (test (char-ci=? #\d #\c #\d) #f) (test (char-ci=?) 'error) (test (char-ci=? #\a #\b 0) 'error) ;;; -------------------------------------------------------------------------------- ;;; char-ci? (integer->char #xf0) (integer->char #x70)) #t) #| ;; this tries them all: (do ((i 0 (+ i 1))) ((= i 256)) (do ((k 0 (+ k 1))) ((= k 256)) (let ((c1 (integer->char i)) (c2 (integer->char k))) (for-each (lambda (op1 op2) (if (not (eq? (op1 c1 c2) (op2 (string c1) (string c2)))) (format-logged #t ";(~A|~A ~A ~A) -> ~A|~A~%" op1 op2 c1 c2 (op1 c1 c2) (op2 (string c1) (string c2))))) (list char=? char? char>=? char-ci=? char-ci? char-ci>=?) (list string=? string? string>=? string-ci=? string-ci? string-ci>=?))))) |# (test (char-ci? #\a #\b "hi") 'error) (test (char-ci>? #\a #\b 0) 'error) ;;; -------------------------------------------------------------------------------- ;;; char-ci>? (test (char-ci>? #\A #\B) #f) (test (char-ci>? #\a #\B) #f) (test (char-ci>? #\A #\b) #f) (test (char-ci>? #\a #\b) #f) (test (char-ci>? #\9 #\0) #t) (test (char-ci>? #\A #\A) #f) (test (char-ci>? #\A #\a) #f) (test (char-ci>? #\^ #\a) #t) (test (char-ci>? #\_ #\e) #t) (test (char-ci>? #\[ #\S) #t) (test (char-ci>? #\\ #\l) #t) (test (char-ci>? #\t #\_) #f) (test (char-ci>? #\a #\]) #f) (test (char-ci>? #\z #\^) #f) (test (char-ci>? #\] #\X) #t) (test (char-ci>? #\d #\D #\d #\d) #f) (test (char-ci>? #\d #\d #\X #\d) #f) (test (char-ci>? #\d #\Y #\x #\c) #f) (test (apply char-ci>? cap-a-to-z) #f) (test (apply char-ci>? mixed-a-to-z) #f) (test (apply char-ci>? (reverse mixed-a-to-z)) #t) (test (apply char-ci>? digits) #f) (test (char-ci>? #\d #\c #\d) #f) (test (char-ci>? #\b #\c #\a) #f) (test (char-ci>? #\d #\C #\a) #t) ;;; -------------------------------------------------------------------------------- ;;; char-ci<=? (test (char-ci<=? #\A #\B) #t) (test (char-ci<=? #\a #\B) #t) (test (char-ci<=? #\A #\b) #t) (test (char-ci<=? #\a #\b) #t) (test (char-ci<=? #\9 #\0) #f) (test (char-ci<=? #\A #\A) #t) (test (char-ci<=? #\A #\a) #t) (test (char-ci<=? #\` #\H) #f) (test (char-ci<=? #\[ #\m) #f) (test (char-ci<=? #\j #\`) #t) (test (char-ci<=? #\\ #\E) #f) (test (char-ci<=? #\t #\_) #t) (test (char-ci<=? #\a #\]) #t) (test (char-ci<=? #\z #\^) #t) (test (char-ci<=? #\d #\D #\d #\d) #t) (test (char-ci<=? #\d #\d #\X #\d) #f) (test (char-ci<=? #\d #\Y #\x #\c) #f) (test (apply char-ci<=? cap-a-to-z) #t) (test (apply char-ci<=? mixed-a-to-z) #t) (test (apply char-ci<=? digits) #t) (test (char-ci<=? #\d #\c #\d) #f) (test (char-ci<=? #\b #\c #\a) #f) (test (char-ci<=? #\b #\c #\C) #t) (test (char-ci<=? #\b #\C #\e) #t) (test (char-ci<=? #\b #\a "hi") 'error) (test (char-ci<=? #\b #\a 0) 'error) ;;; -------------------------------------------------------------------------------- ;;; char-ci>=? (test (char-ci>=? #\A #\B) #f) (test (char-ci>=? #\a #\B) #f) (test (char-ci>=? #\A #\b) #f) (test (char-ci>=? #\a #\b) #f) (test (char-ci>=? #\9 #\0) #t) (test (char-ci>=? #\A #\A) #t) (test (char-ci>=? #\A #\a) #t) (test (char-ci>=? #\Y #\_) #f) (test (char-ci>=? #\` #\S) #t) (test (char-ci>=? #\[ #\Y) #t) (test (char-ci>=? #\t #\_) #f) (test (char-ci>=? #\a #\]) #f) (test (char-ci>=? #\z #\^) #f) (test (char-ci>=? #\d #\D #\d #\d) #t) (test (char-ci>=? #\d #\d #\X #\d) #f) (test (char-ci>=? #\d #\Y #\x #\c) #f) (test (apply char-ci>=? cap-a-to-z) #f) (test (apply char-ci>=? mixed-a-to-z) #f) (test (apply char-ci>=? (reverse mixed-a-to-z)) #t) (test (apply char-ci>=? (reverse mixed-a-to-z)) #t) (test (apply char-ci>=? digits) #f) (test (char-ci>=? #\d #\c #\d) #f) (test (char-ci>=? #\b #\c #\a) #f) (test (char-ci>=? #\d #\D #\a) #t) (test (char-ci>=? #\\ #\J #\+) #t) (test (char-ci>=? #\a #\b "hi") 'error) (test (char-ci>=? #\a #\b 0) 'error) ) ; end let with a-to-z ;;; -------------------------------------------------------------------------------- ;;; integer->char ;;; char->integer (test (integer->char (char->integer #\.)) #\.) (test (integer->char (char->integer #\A)) #\A) (test (integer->char (char->integer #\a)) #\a) (test (integer->char (char->integer #\space)) #\space) (test (char->integer (integer->char #xf0)) #xf0) (do ((i 0 (+ i 1))) ((= i 256)) (if (not (= (char->integer (integer->char i)) i)) (format-logged #t ";char->integer ~D ~A != ~A~%" i (integer->char i) (char->integer (integer->char i))))) (test (reinvert 12 integer->char char->integer 60) 60) (test (char->integer 33) 'error) (test (char->integer) 'error) (test (integer->char) 'error) (test (integer->char (expt 2 31)) 'error) (test (integer->char (expt 2 32)) 'error) (test (integer->char 12 14) 'error) (test (char->integer #\a #\b) 'error) ;(test (char->integer #\ÿ) 255) ; emacs confusion? (test (eval-string (string-append "(char->integer " (format #f "#\\~C" (integer->char 255)) ")")) 255) (for-each (lambda (arg) (test (char->integer arg) 'error)) (list -1 1 0 123456789 "hi" () (list 1) '(1 . 2) #f 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t :hi (if #f #f) (lambda (a) (+ a 1)))) (for-each (lambda (arg) (test (integer->char arg) 'error)) (list -1 257 123456789 -123456789 #\a "hi" () (list 1) '(1 . 2) #f 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t :hi most-positive-fixnum 1/0 (if #f #f) (lambda (a) (+ a 1)))) (test (#\a) 'error) (test (#\newline 1) 'error) ;;; -------------------------------------------------------------------------------- ;;; STRINGS ;;; -------------------------------------------------------------------------------- ;;; -------------------------------------------------------------------------------- ;;; string? (test (string? "abc") #t) (test (string? ':+*/-) #f) (test (string? "das ist einer der teststrings") #t) (test (string? '(das ist natuerlich falsch)) #f) (test (string? "aaaaaa") #t) (test (string? #\a) #f) (test (string? "\"\\\"") #t) (test (string? lambda) #f) (test (string? format) #f) (for-each (lambda (arg) (test (string? arg) #f)) (list #\a () (list 1) '(1 . 2) #f 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t :hi (if #f #f) (lambda (a) (+ a 1)))) (test (string?) 'error) (test (string? "hi" "ho") 'error) (test (string? #\null) #f) ;;; -------------------------------------------------------------------------------- ;;; string=? (test (string=? "foo" "foo") #t) (test (string=? "foo" "FOO") #f) (test (string=? "foo" "bar") #f) (test (string=? "FOO" "FOO") #t) (test (string=? "A" "B") #f) (test (string=? "a" "b") #f) (test (string=? "9" "0") #f) (test (string=? "A" "A") #t) (test (string=? "" "") #t) (test (string=? (string #\newline) (string #\newline)) #t) (test (string=? "A" "B" "a") #f) (test (string=? "A" "A" "a") #f) (test (string=? "A" "A" "A") #t) (test (string=? "foo" "foo" "foo") #t) (test (string=? "foo" "foo" "") #f) (test (string=? "foo" "foo" "fOo") #f) (test (string=? "foo" "FOO" 1.0) 'error) (test (let ((str (string #\" #\1 #\\ #\2 #\"))) (string=? str "\"1\\2\"")) #t) (test (let ((str (string #\\ #\\ #\\))) (string=? str "\\\\\\")) #t) (test (let ((str (string #\"))) (string=? str "\"")) #t) (test (let ((str (string #\\ #\"))) (string=? str "\\\"")) #t) (test (let ((str (string #\space #\? #\)))) (string=? str " ?)")) #t) (test (let ((str (string #\# #\\ #\t))) (string=? str "#\\t")) #t) (test (string=? (string #\x (integer->char #xf0) #\x) (string #\x (integer->char #x70) #\x)) #f) (test (string=? (string #\x (integer->char #xf0) #\x) (string #\x (integer->char #xf0) #\x)) #t) (test (string=? (string) "") #t) (test (string=? (string) (make-string 0)) #t) (test (string=? (string-copy (string)) (make-string 0)) #t) (test (string=? "" (make-string 0)) #t) (test (string=? "" (string-append)) #t) (test (string=? (string #\space #\newline) " \n") #t) (test (string=? "......" "...\ ...") #t) (test (string=? "\n" (string #\newline)) #t) (test (string=? "\ \ \ \ " "") #t) (test (string=? "" (string #\null)) #f) (test (string=? (string #\null #\null) (string #\null)) #f) (test (string=? "" "asd") #f) (test (string=? "asd" "") #f) (test (string=? "xx" (make-string 2 #\x) (string #\x #\x) (list->string (list #\x #\x)) (substring "axxb" 1 3) (string-append "x" "x")) #t) (test (let ((s1 "1234") (s2 "1245")) (string-set! s1 1 #\null) (string-set! s2 1 #\null) (string=? s1 s2)) #f) (test (let ((s1 "1234") (s2 "1234")) (string-set! s1 1 #\null) (string-set! s2 1 #\null) (string=? s1 s2)) #t) (test (let ((s1 "1234") (s2 "124")) (string-set! s1 1 #\null) (string-set! s2 1 #\null) (string=? s1 s2)) #f) (test (string=? (make-string 3 #\space) (let ((s (make-string 4 #\space))) (set! (s 3) #\null) s)) #f) (test "\x3012" "012") (for-each (lambda (arg) (test (string=? "hi" arg) 'error) (test (string=? arg "hi") 'error)) (list #\a () (list 1) '(1 . 2) #f 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t :hi (if #f #f) (lambda (a) (+ a 1)))) ;; this strikes me as highly dubious (test (call-with-input-string "1\n2" (lambda (p) (read p))) 1) (test (call-with-input-string "1\\ \n2" (lambda (p) (read p))) (symbol "1\\")) (test (call-with-input-string "1\ 2" (lambda (p) (read p))) 12) ;; do we guarantee that read takes place in the current environment? (test (let ((xyzzy 32)) (call-with-input-string "xy\ zzy" (lambda (p) (read p)))) 'xyzzy) (test (let ((xyzzy 32)) (call-with-input-string "xy\ zzy" (lambda (p) (eval (read p))))) 32) (test (let ((xyzzy 32)) (call-with-input-string "(set! xyzzy;\ this is presumably a comment 321)" (lambda (p) (eval (read p)))) xyzzy) 321) (test (let ((xyzzy 32)) (call-with-input-string "(set! xyzzy;\ this is presumably a comment;\ and more commentary 321)" (lambda (p) (eval (read p)))) xyzzy) 321) ;;; -------------------------------------------------------------------------------- ;;; stringchar #xf0)) (string (integer->char #x70))) #f) (for-each (lambda (arg) (test (string? (test (string>? "aaab" "aaaa") #t) (test (string>? "aaaaa" "aaaa") #t) (test (string>? "" "abcdefgh") #f) (test (string>? "a" "abcdefgh") #f) (test (string>? "abc" "abcdefgh") #f) (test (string>? "cabc" "abcdefgh") #t) (test (string>? "abcdefgh" "abcdefgh") #f) (test (string>? "xyzabc" "abcdefgh") #t) (test (string>? "abc" "xyzabcdefgh") #f) (test (string>? "abcdefgh" "") #t) (test (string>? "abcdefgh" "a") #t) (test (string>? "abcdefgh" "abc") #t) (test (string>? "abcdefgh" "cabc") #f) (test (string>? "abcdefgh" "xyzabc") #f) (test (string>? "xyzabcdefgh" "abc") #t) (test (string>? "abcde" "bc") #f) (test (string>? "bcdef" "abcde") #t) (test (string>? "bcdef" "abcdef") #t) (test (string>? "" "") #f) (test (string>? "A" "B") #f) (test (string>? "a" "b") #f) (test (string>? "9" "0") #t) (test (string>? "A" "A") #f) (test (string>? "A" "B" "a") #f) (test (string>? "C" "B" "A") #t) (test (string>? "A" "A" "A") #f) (test (string>? "B" "B" "A") #f) (test (string>? "foo" "foo" "foo") #f) (test (string>? "foo" "foo" "") #f) (test (string>? "foo" "foo" "fOo") #f) (test (string>? "foo" "fooo" 1.0) 'error) (test (let ((s1 "1234") (s2 "1245")) (string-set! s1 1 #\null) (string-set! s2 1 #\null) (string>? s1 s2)) #f) (test (let ((s1 "1234") (s2 "123")) (string-set! s1 1 #\null) (string-set! s2 1 #\null) (string>? s1 s2)) #t) (test (let ((s1 "123") (s2 "1234")) (string-set! s1 1 #\null) (string-set! s2 1 #\null) (string>? s1 s2)) #f) (test (string>? (string (integer->char #xf0)) (string (integer->char #x70))) #t) ; ?? (for-each (lambda (arg) (test (string>? "hi" arg) 'error) (test (string>? arg "hi") 'error)) (list #\a () (list 1) '(1 . 2) #f 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t :hi (if #f #f) (lambda (a) (+ a 1)))) ;;; -------------------------------------------------------------------------------- ;;; string<=? (test (string<=? "aaa" "aaaa") #t) (test (string<=? "aaaaa" "aaaa") #f) (test (string<=? "a" "abcdefgh") #t) (test (string<=? "abc" "abcdefgh") #t) (test (string<=? "aaabce" "aaabcdefgh") #f) (test (string<=? "cabc" "abcdefgh") #f) (test (string<=? "abcdefgh" "abcdefgh") #t) (test (string<=? "xyzabc" "abcdefgh") #f) (test (string<=? "abc" "xyzabcdefgh") #t) (test (string<=? "abcdefgh" "") #f) (test (string<=? "abcdefgh" "a") #f) (test (string<=? "abcdefgh" "abc") #f) (test (string<=? "abcdefgh" "cabc") #t) (test (string<=? "abcdefgh" "xyzabc") #t) (test (string<=? "xyzabcdefgh" "abc") #f) (test (string<=? "abcdef" "bcdefgh") #t) (test (string<=? "" "") #t) (test (string<=? "A" "B") #t) (test (string<=? "a" "b") #t) (test (string<=? "9" "0") #f) (test (string<=? "A" "A") #t) (test (string<=? "A" "B" "C") #t) (test (string<=? "C" "B" "A") #f) (test (string<=? "A" "B" "B") #t) (test (string<=? "A" "A" "A") #t) (test (string<=? "B" "B" "A") #f) (test (string<=? "foo" "foo" "foo") #t) (test (string<=? "foo" "foo" "") #f) (test (string<=? "foo" "foo" "fooo") #t) (test (string<=? "foo" "fo" 1.0) 'error) (test (let ((s1 "1234") (s2 "1245")) (string-set! s1 1 #\null) (string-set! s2 1 #\null) (string<=? s1 s2)) #t) (test (let ((s1 "1234") (s2 "123")) (string-set! s1 1 #\null) (string-set! s2 1 #\null) (string<=? s1 s2)) #f) (test (let ((s1 "123") (s2 "1234")) (string-set! s1 1 #\null) (string-set! s2 1 #\null) (string<=? s1 s2)) #t) (test (let ((s1 "1234") (s2 "1234")) (string-set! s1 1 #\null) (string-set! s2 1 #\null) (string<=? s1 s2)) #t) (for-each (lambda (arg) (test (string<=? "hi" arg) 'error) (test (string<=? arg "hi") 'error)) (list #\a () (list 1) '(1 . 2) #f 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t :hi (if #f #f) (lambda (a) (+ a 1)))) ;;; -------------------------------------------------------------------------------- ;;; string>=? (test (string>=? "aaaaa" "aaaa") #t) (test (string>=? "aaaa" "aaaa") #t) (test (string>=? "aaa" "aaaa") #f) (test (string>=? "" "abcdefgh") #f) (test (string>=? "a" "abcdefgh") #f) (test (string>=? "abc" "abcdefgh") #f) (test (string>=? "cabc" "abcdefgh") #t) (test (string>=? "abcdefgh" "abcdefgh") #t) (test (string>=? "xyzabc" "abcdefgh") #t) (test (string>=? "abc" "xyzabcdefgh") #f) (test (string>=? "abcdefgh" "") #t) (test (string>=? "abcdefgh" "a") #t) (test (string>=? "abcdefgh" "abc") #t) (test (string>=? "abcdefgh" "cabc") #f) (test (string>=? "abcdefgh" "xyzabc") #f) (test (string>=? "xyzabcdefgh" "abc") #t) (test (string>=? "bcdef" "abcdef") #t) (test (string>=? "A" "B") #f) (test (string>=? "a" "b") #f) (test (string>=? "9" "0") #t) (test (string>=? "A" "A") #t) (test (string>=? "" "") #t) (test (string>=? "A" "B" "C") #f) (test (string>=? "C" "B" "A") #t) (test (string>=? "C" "B" "B") #t) (test (string>=? "A" "B" "B") #f) (test (string>=? "A" "A" "A") #t) (test (string>=? "B" "B" "A") #t) (test (string>=? "B" "B" "C") #f) (test (string>=? "foo" "foo" "foo") #t) (test (string>=? "foo" "foo" "") #t) (test (string>=? "foo" "foo" "fo") #t) (test (string>=? "fo" "foo" 1.0) 'error) (test (let ((s1 "1234") (s2 "1245")) (string-set! s1 1 #\null) (string-set! s2 1 #\null) (string>=? s1 s2)) #f) (test (let ((s1 "1234") (s2 "123")) (string-set! s1 1 #\null) (string-set! s2 1 #\null) (string>=? s1 s2)) #t) (test (let ((s1 "123") (s2 "1234")) (string-set! s1 1 #\null) (string-set! s2 1 #\null) (string>=? s1 s2)) #f) (test (let ((s1 "1234") (s2 "1234")) (string-set! s1 1 #\null) (string-set! s2 1 #\null) (string>=? s1 s2)) #t) (for-each (lambda (arg) (test (string>=? "hi" arg) 'error) (test (string>=? arg "hi") 'error)) (list #\a () (list 1) '(1 . 2) #f 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t :hi (if #f #f) (lambda (a) (+ a 1)))) ;;; -------------------------------------------------------------------------------- ;;; string-ci=? (test (string-ci=? "A" "B") #f) (test (string-ci=? "a" "B") #f) (test (string-ci=? "A" "b") #f) (test (string-ci=? "a" "b") #f) (test (string-ci=? "9" "0") #f) (test (string-ci=? "A" "A") #t) (test (string-ci=? "A" "a") #t) (test (string-ci=? "" "") #t) (test (string-ci=? "aaaa" "AAAA") #t) (test (string-ci=? "aaaa" "Aaaa") #t) (test (string-ci=? "A" "B" "a") #f) (test (string-ci=? "A" "A" "a") #t) (test (string-ci=? "A" "A" "a") #t) (test (string-ci=? "foo" "foo" "foo") #t) (test (string-ci=? "foo" "foo" "") #f) (test (string-ci=? "foo" "Foo" "fOo") #t) (test (string-ci=? "foo" "GOO" 1.0) 'error) (test (let ((s1 "1234") (s2 "1245")) (string-set! s1 1 #\null) (string-set! s2 1 #\null) (string-ci=? s1 s2)) #f) (test (let ((s1 "1234") (s2 "1234")) (string-set! s1 1 #\null) (string-set! s2 1 #\null) (string-ci=? s1 s2)) #t) (test (let ((s1 "1234") (s2 "124")) (string-set! s1 1 #\null) (string-set! s2 1 #\null) (string-ci=? s1 s2)) #f) (test (let ((s1 "abcd") (s2 "ABCD")) (string-set! s1 1 #\null) (string-set! s2 1 #\null) (string-ci=? s1 s2)) #t) (test (let ((s1 "abcd") (s2 "ABCE")) (string-set! s1 1 #\null) (string-set! s2 1 #\null) (string-ci=? s1 s2)) #f) (test (let ((s1 "abcd") (s2 "ABC")) (string-set! s1 1 #\null) (string-set! s2 1 #\null) (string-ci=? s1 s2)) #f) (for-each (lambda (arg) (test (string-ci=? "hi" arg) 'error) (test (string-ci=? arg "hi") 'error)) (list #\a () (list 1) '(1 . 2) #f 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t :hi (if #f #f) (lambda (a) (+ a 1)))) (when full-test (let ((size 15) (tries 10000)) (let ((str1 (make-string size)) (str2 (make-string size))) (do ((i 0 (+ i 1))) ((= i tries)) (do ((k 0 (+ k 1))) ((= k size)) (set! (str1 k) (integer->char (random 128))) (if (> (random 10) 4) (set! (str2 k) (char-upcase (str1 k))) (set! (str2 k) (char-downcase (str1 k))))) (if (not (string-ci=? str1 str2)) (format-logged #t "not =: ~S ~S~%" str1 str2)) (if (and (string-ci=? str1 str2)) (format-logged #t "< : ~S ~S~%" str1 str2)) (if (and (string-ci>? str1 str2) (string-ci<=? str1 str2)) (format-logged #t "> : ~S ~S~%" str1 str2)))))) ;;; -------------------------------------------------------------------------------- ;;; string-ciP" "DMhk3Bg") #f) (test (string-cichar #xf0) (integer->char #x70)) (test (string-cichar #xf0)) (string (integer->char #x70))) #t)) (test (string-ci? (test (string-ci>? "Aaa" "AA") #t) (test (string-ci>? "A" "B") #f) (test (string-ci>? "a" "B") #f) (test (string-ci>? "A" "b") #f) (test (string-ci>? "a" "b") #f) (test (string-ci>? "9" "0") #t) (test (string-ci>? "A" "A") #f) (test (string-ci>? "A" "a") #f) (test (string-ci>? "" "") #f) (test (string-ci>? "Z" "DjNTl0") #t) (test (string-ci>? "2399dt7BVN[,A" "^KHboHV") #f) (test (string-ci>? "t" "_") #f) (test (string-ci>? "a" "]") #f) (test (string-ci>? "z" "^") #f) (test (string-ci>? "R*95oG.k;?" "`2?J6LBbLG^alB[fMD") #f) (test (string-ci>? "]" "X") #t) (test (string-ci>? "A" "B" "a") #f) (test (string-ci>? "C" "b" "A") #t) (test (string-ci>? "a" "A" "A") #f) (test (string-ci>? "B" "B" "A") #f) (test (string-ci>? "foo" "foo" "foo") #f) (test (string-ci>? "foo" "foo" "") #f) (test (string-ci>? "foo" "foo" "fOo") #f) (test (string-ci>? "ZNiuEa@/V" "KGbKliYMY" "9=69q3ica" ":]") #f) (test (string-ci>? "^" "aN@di;iEO" "7*9q6uPmX9)PaY,6J" "15vH") #t) (test (string-ci>? "foo" "fooo" 1.0) 'error) (test (let ((s1 "abcd") (s2 "ABCD")) (string-set! s1 1 #\null) (string-set! s2 1 #\null) (string-ci>? s1 s2)) #f) (test (let ((s1 "abcd") (s2 "ABCE")) (string-set! s1 1 #\null) (string-set! s2 1 #\null) (string-ci>? s1 s2)) #f) (test (let ((s1 "abcd") (s2 "ABC")) (string-set! s1 1 #\null) (string-set! s2 1 #\null) (string-ci>? s1 s2)) #t) (test (let ((s1 "abc") (s2 "ABCD")) (string-set! s1 1 #\null) (string-set! s2 1 #\null) (string-ci>? s1 s2)) #f) (for-each (lambda (arg) (test (string-ci>? "hi" arg) 'error) (test (string-ci>? arg "hi") 'error)) (list #\a () (list 1) '(1 . 2) #f 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t :hi (if #f #f) (lambda (a) (+ a 1)))) ;;; -------------------------------------------------------------------------------- ;;; string-ci<=? (test (string-ci<=? "A" "B") #t) (test (string-ci<=? "a" "B") #t) (test (string-ci<=? "A" "b") #t) (test (string-ci<=? "a" "b") #t) (test (string-ci<=? "9" "0") #f) (test (string-ci<=? "A" "A") #t) (test (string-ci<=? "A" "a") #t) (test (string-ci<=? "" "") #t) (test (string-ci<=? ":LPC`" ",O0>affA?(") #f) (test (string-ci<=? "t" "_") #t) (test (string-ci<=? "a" "]") #t) (test (string-ci<=? "z" "^") #t) (test (string-ci<=? "G888E>beF)*mwCNnagP" "`2uTd?h") #t) (test (string-ci<=? "A" "b" "C") #t) (test (string-ci<=? "c" "B" "A") #f) (test (string-ci<=? "A" "B" "B") #t) (test (string-ci<=? "a" "A" "A") #t) (test (string-ci<=? "B" "b" "A") #f) (test (string-ci<=? "foo" "foo" "foo") #t) (test (string-ci<=? "foo" "foo" "") #f) (test (string-ci<=? "FOO" "fOo" "fooo") #t) (test (string-ci<=? "78mdL82*" "EFaCrIdm@_D+" "eMu\\@dSSY") #t) (test (string-ci<=? "`5pNuFc3PM=? (test (string-ci>=? "A" "B") #f) (test (string-ci>=? "a" "B") #f) (test (string-ci>=? "A" "b") #f) (test (string-ci>=? "a" "b") #f) (test (string-ci>=? "9" "0") #t) (test (string-ci>=? "A" "A") #t) (test (string-ci>=? "A" "a") #t) (test (string-ci>=? "" "") #t) (test (string-ci>=? "5d7?[o[:hop=ktv;9)" "p^r9;TAXO=^") #f) (test (string-ci>=? "t" "_") #f) (test (string-ci>=? "a" "]") #f) (test (string-ci>=? "z" "^") #f) (test (string-ci>=? "jBS" "`<+s[[:`l") #f) (test (string-ci>=? "A" "b" "C") #f) (test (string-ci>=? "C" "B" "A") #t) (test (string-ci>=? "C" "B" "b") #t) (test (string-ci>=? "a" "B" "B") #f) (test (string-ci>=? "A" "A" "A") #t) (test (string-ci>=? "B" "B" "A") #t) (test (string-ci>=? "B" "b" "C") #f) (test (string-ci>=? "foo" "foo" "foo") #t) (test (string-ci>=? "foo" "foo" "") #t) (test (string-ci>=? "foo" "foo" "fo") #t) (test (string-ci>=? "tF?8`Sa" "NIkMd7" "f`" "1td-Z?teE" "-ik1SK)hh)Nq].>") #t) (test (string-ci>=? "Z6a8P" "^/VpmWwt):?o[a9\\_N" "8[^h)=? "fo" "foo" 1.0) 'error) (test (let ((s1 "abcd") (s2 "ABCD")) (string-set! s1 1 #\null) (string-set! s2 1 #\null) (string-ci>=? s1 s2)) #t) (test (let ((s1 "abcd") (s2 "ABCE")) (string-set! s1 1 #\null) (string-set! s2 1 #\null) (string-ci>=? s1 s2)) #f) (test (let ((s1 "abcd") (s2 "ABC")) (string-set! s1 1 #\null) (string-set! s2 1 #\null) (string-ci>=? s1 s2)) #t) (test (let ((s1 "abc") (s2 "ABCD")) (string-set! s1 1 #\null) (string-set! s2 1 #\null) (string-ci>=? s1 s2)) #f) (for-each (lambda (arg) (test (string-ci>=? "hi" arg) 'error) (test (string-ci>=? arg "hi") 'error)) (list #\a () (list 1) '(1 . 2) #f 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t :hi (if #f #f) (lambda (a) (+ a 1)))) ;;; -------------------------------------------------------------------------------- ;;; string-length (test (string-length "abc") 3) (test (string-length "") 0) (test (string-length (string)) 0) (test (string-length "\"\\\"") 3) (test (string-length (string #\newline)) 1) (test (string-length "hi there") 8) (test (string-length "\"") 1) (test (string-length "\\") 1) (test (string-length "\n") 1) (test (string-length (make-string 100 #\a)) 100) (test (string-length "1\\2") 3) (test (string-length "1\\") 2) (test (string-length "hi\\") 3) (test (string-length "\\\\\\\"") 4) (test (string-length "A ; comment") 11) (test (string-length "#| comment |#") 13) (test (string-length "'123") 4) (test (string-length '"'123") 4) (test (let ((str (string #\# #\\ #\t))) (string-length str)) 3) (test (string-length "#\\(") 3) (test (string-length ")()") 3) (test (string-length "(()") 3) (test (string-length "(string #\\( #\\+ #\\space #\\1 #\\space #\\3 #\\))") 44) (test (string-length) 'error) (test (string-length "hi" "ho") 'error) (test (string-length (string #\null)) 1) ; ?? (test (string-length (string #\null #\null)) 2) ; ?? (test (string-length (string #\null #\newline)) 2) ; ?? (test (string-length ``"hi") 2) ; ?? and in s7 ,"hi" is "hi" as with numbers (test (string-length ";~S ~S") 6) (test (string-length "\n;~S ~S") 7) (test (string-length "\n\t") 2) (test (string-length "#\newline") 8) (test (string-length "#\tab") 4) (test (string-length "a\x00b") 3) (test (string-length "123\ 456") 6) (test (string-length"123\n 456") 8) (test (string-length"123\n\ 456") 7) (for-each (lambda (arg) (test (string-length arg) 'error)) (list #\a () (list 1) '(1 . 2) #f 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t :hi (if #f #f) (lambda (a) (+ a 1)))) ;;; -------------------------------------------------------------------------------- ;;; string (for-each (lambda (arg) (test (string #\a arg) 'error) (test (string #\a #\null arg) 'error) (test (string arg) 'error)) (list () (list 1) '(1 . 2) "a" #f 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t :hi (if #f #f) (lambda (a) (+ a 1)))) (test (string) "") (test (string #\a #\b #\c) "abc") (test (string #\a) "a") (test (map string '(#\a #\b)) '("a" "b")) (test (map string '(#\a #\b) '(#\c #\d)) '("ac" "bd")) (test (map string '(#\a #\b #\c) '(#\d #\e #\f) '(#\g #\h #\i)) '("adg" "beh" "cfi")) (test (map string "abc" "def" "ghi") '("adg" "beh" "cfi")) (test (string #\" #\# #\") "\"#\"") (test (string #\\ #\\ #\# #\\ #\# #\#) "\\\\#\\##") (test (string #\' #\' #\` #\") '"''`\"") ;;; some schemes accept \' and other such sequences in a string, but the spec only mentions \\ and \" (test (string ()) 'error) (test (string "j" #\a) 'error) ;;; -------------------------------------------------------------------------------- ;;; make-string (test (make-string 0) "") (test (make-string 3 #\a) "aaa") (test (make-string 0 #\a) "") (test (make-string 3 #\space) " ") (test (let ((hi (make-string 3 #\newline))) (string-length hi)) 3) (test (make-string -1) 'error) (test (make-string -0) "") (test (make-string 2 #\a #\b) 'error) (test (make-string) 'error) (test (make-string most-positive-fixnum) 'error) (test (make-string most-negative-fixnum) 'error) (let () (define (hi size) (make-string size (integer->char (+ 1 (random 255))))) (string? (hi 3))) (for-each (lambda (arg) (test (make-string 3 arg) 'error)) (list "hi" () (list 1) '(1 . 2) #f 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t :hi (if #f #f) (lambda (a) (+ a 1)))) (for-each (lambda (arg) (test (make-string arg #\a) 'error)) (list #\a "hi" () (list 1) '(1 . 2) #f 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t :hi (if #f #f) (lambda (a) (+ a 1)))) (for-each (lambda (arg) (test (make-string arg) 'error)) (list #\a "hi" () (list 1) '(1 . 2) #f 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t :hi (if #f #f) (lambda (a) (+ a 1)))) ;;; -------------------------------------------------------------------------------- ;;; string-ref (test (string-ref "abcdef-dg1ndh" 0) #\a) (test (string-ref "abcdef-dg1ndh" 1) #\b) (test (string-ref "abcdef-dg1ndh" 6) #\-) (test (string-ref "\"\\\"" 1) #\\) (test (string-ref "\"\\\"" 2) #\") (test (let ((str (make-string 3 #\x))) (set! (string-ref str 1) #\a) str) "xax") (test (string-ref "abcdef-dg1ndh" 20) 'error) (test (string-ref "abcdef-dg1ndh") 'error) (test (string-ref "abcdef-dg1ndh" -3) 'error) (test (string-ref) 'error) (test (string-ref 2) 'error) (test (string-ref "\"\\\"" 3) 'error) (test (string-ref "" 0) 'error) (test (string-ref "" 1) 'error) (test (string-ref "hiho" (expt 2 32)) 'error) (test (char=? (string-ref (string #\null) 0) #\null) #t) (test (char=? (string-ref (string #\1 #\null #\2) 1) #\null) #t) (test (char=? ("1\x002" 1) #\null) #t) (test (char=? (string-ref (string #\newline) 0) #\newline) #t) (test (char=? (string-ref (string #\space) 0) #\space) #t) (for-each (lambda (arg) (test (string-ref arg 0) 'error)) (list #\a 1 () (list 1) '(1 . 2) #f 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t :hi (if #f #f) (lambda (a) (+ a 1)))) (for-each (lambda (arg) (test (string-ref "hiho" arg) 'error)) (list #\a -1 123 4 "hi" () (list 1) '(1 . 2) #f 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t :hi (if #f #f) (lambda (a) (+ a 1)))) (test ("hi" 1) #\i) (test (("hi" 1) 0) 'error) (test ("hi" 1 2) 'error) (test ("" 0) 'error) (test (set! ("" 0) #\a) 'error) (test (set! ("hi" 1 2) #\a) 'error) (test (set! ("hi" 1) #\a #\b) 'error) (test ("hi") 'error) (test ("") 'error) (test ((let () "hi")) 'error) (test ((let () "hi") 0) #\h) (test ("abs" most-negative-fixnum) 'error) (test (string-ref "abs" most-negative-fixnum) 'error) (test ("abs" (+ 1 most-negative-fixnum)) 'error) (test ("abs" most-positive-fixnum) 'error) ;;; -------------------------------------------------------------------------------- ;;; string-copy (test (let ((hi (string-copy "hi"))) (string-set! hi 0 #\H) hi) "Hi") (test (let ((hi (string-copy "hi"))) (string-set! hi 1 #\H) hi) "hH") (test (let ((hi (string-copy "\"\\\""))) (string-set! hi 0 #\a) hi) "a\\\"") (test (let ((hi (string-copy "\"\\\""))) (string-set! hi 1 #\a) hi) "\"a\"") (test (let ((hi (string #\a #\newline #\b))) (string-set! hi 1 #\c) hi) "acb") (test (string-copy "ab") "ab") (test (string-copy "") "") (test (string-copy "\"\\\"") "\"\\\"") (test (let ((hi "abc")) (eq? hi (string-copy hi))) #f) (test (let ((hi (string-copy (make-string 8 (integer->char 0))))) (string-fill! hi #\a) hi) "aaaaaaaa") ; is this result widely accepted? (test (string-copy (string-copy (string-copy "a"))) "a") (test (string-copy (string-copy (string-copy ""))) "") (test (string-copy "a\x00b") "a\x00b") ; prints normally as "a" however (test (string-copy (string #\1 #\null #\2)) (string #\1 #\null #\2)) (test (string-copy) 'error) (test (string-copy "hi" "ho") 'error) (for-each (lambda (arg) (test (string-copy arg) 'error)) (list #\a 1 () (list 1) '(1 . 2) #f 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t :hi (if #f #f) (lambda (a) (+ a 1)))) (test (length (string-copy (string #\null))) 1) ;;; -------------------------------------------------------------------------------- ;;; string-set! (let ((str (make-string 10 #\x))) (string-set! str 3 (integer->char 0)) (test (string=? str "xxx") #f) (test (char=? (string-ref str 4) #\x) #t) (string-set! str 4 #\a) (test (string=? str "xxx") #f) (test (char=? (string-ref str 4) #\a) #t) (string-set! str 3 #\x) (test (string=? str "xxxxaxxxxx") #t)) (test (string-set! "hiho" 1 #\c) #\c) (test (set! ("hi" 1 2) #\i) 'error) (test (set! ("hi" 1) "ho") 'error) (test (set! ("hi") #\i) 'error) (test (let ((x "hi") (y 'x)) (string-set! y 0 #\x) x) 'error) (test (let ((str "ABS")) (set! (str 0) #\a)) #\a) (test (let ((str "ABS")) (string-set! str 0 #\a)) #\a) (test (let ((str "ABS")) (set! (string-ref str 0) #\a)) #\a) (test (let ((hi (make-string 3 #\a))) (string-set! hi 1 (let ((ho (make-string 4 #\x))) (string-set! ho 1 #\b) (string-ref ho 0))) hi) "axa") (test (string-set! "hiho" (expt 2 32) #\a) 'error) (test (let ((hi (string-copy "hi"))) (string-set! hi 2 #\H) hi) 'error) (test (let ((hi (string-copy "hi"))) (string-set! hi -1 #\H) hi) 'error) (test (let ((g (lambda () "***"))) (string-set! (g) 0 #\?)) #\?) (test (string-set! "" 0 #\a) 'error) (test (string-set! "" 1 #\a) 'error) (test (string-set! (string) 0 #\a) 'error) (test (string-set! (symbol->string 'lambda) 0 #\a) #\a) (test (let ((ho (make-string 0 #\x))) (string-set! ho 0 #\a) ho) 'error) (test (let ((str "hi")) (string-set! (let () str) 1 #\a) str) "ha") ; (also in Guile) (test (let ((x 2) (str "hi")) (string-set! (let () (set! x 3) str) 1 #\a) (list x str)) '(3 "ha")) (test (let ((str "hi")) (set! ((let () str) 1) #\b) str) "hb") (test (let ((str "hi")) (string-set! (let () (string-set! (let () str) 0 #\x) str) 1 #\x) str) "xx") (test (let ((str "hi")) (string-set! (let () (set! str "hiho") str) 3 #\x) str) "hihx") ; ! (this works in Guile also) (for-each (lambda (arg) (test (string-set! arg 0 #\a) 'error)) (list #\a 1 () (list 1) '(1 . 2) #f 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t :hi (if #f #f) (lambda (a) (+ a 1)))) (for-each (lambda (arg) (test (string-set! "hiho" arg #\a) 'error)) (list #\a -1 123 4 "hi" () (list 1) '(1 . 2) #f 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t :hi (if #f #f) (lambda (a) (+ a 1)))) (for-each (lambda (arg) (test (string-set! "hiho" 0 arg) 'error)) (list 1 "hi" () (list 1) '(1 . 2) #f 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t :hi (if #f #f) (lambda (a) (+ a 1)))) (test (equal? (let ((str "hiho")) (string-set! str 2 #\null) str) "hi") #f) (test (string=? (let ((str "hiho")) (string-set! str 2 #\null) str) "hi") #f) (test (let* ((s1 "hi") (s2 s1)) (string-set! s2 1 #\x) s1) "hx") (test (let* ((s1 "hi") (s2 (copy s1))) (string-set! s2 1 #\x) s1) "hi") (test (eq? (car (catch #t (lambda () (set! ("hi") #\a)) (lambda args args))) 'wrong-number-of-args) #t) (test (eq? (car (catch #t (lambda () (set! ("hi" 0 0) #\a)) (lambda args args))) 'wrong-number-of-args) #t) ; (vector-set! 1 ...) (test (eq? (car (catch #t (lambda () (set! (("hi" 0) 0) #\a)) (lambda args args))) 'syntax-error) #t) ; (set! (1 ...)) (test (let ((s "012345")) (set! (apply s 2) #\a) s) 'error) (test (string-set! #u8(0 1 0) 0 -9223372036854775808) 'error) ;;; -------------------------------------------------------------------------------- ;;; string-fill! (test (string-fill! "hiho" #\c) #\c) (test (string-fill! "" #\a) #\a) (test (string-fill! "hiho" #\a) #\a) (test (let ((g (lambda () "***"))) (string-fill! (g) #\?)) #\?) (test (string-fill!) 'error) (test (string-fill! "hiho" #\a #\b) 'error) (test (let ((hi (string-copy "hi"))) (string-fill! hi #\s) hi) "ss") (test (let ((hi (string-copy ""))) (string-fill! hi #\x) hi) "") (test (let ((str (make-string 0))) (string-fill! str #\a) str) "") (test (let ((hi (make-string 8 (integer->char 0)))) (string-fill! hi #\a) hi) "aaaaaaaa") ; is this result widely accepted? (test (recompose 12 string-copy "xax") "xax") (test (let ((hi (make-string 3 #\x))) (recompose 12 (lambda (a) (string-fill! a #\a) a) hi)) "aaa") (test (let ((hi (make-string 3 #\x))) (recompose 12 (lambda (a) (string-fill! hi a)) #\a) hi) "aaa") (test (let ((str (string #\null #\null))) (fill! str #\x) str) "xx") (for-each (lambda (arg) (test (let ((hiho "hiho")) (string-fill! hiho arg) hiho) 'error)) (list 1 "hi" () (list 1) '(1 . 2) #f 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t :hi (if #f #f) (lambda (a) (+ a 1)))) (for-each (lambda (arg) (test (string-fill! arg #\a) 'error)) (list #\a 1 () (list 1) '(1 . 2) #f 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t :hi (if #f #f) (lambda (a) (+ a 1)))) (test (let ((str "1234567890")) (string-fill! str #\a 0) str) "aaaaaaaaaa") (test (let ((str "1234567890")) (string-fill! str #\a 0 10) str) "aaaaaaaaaa") (test (let ((str "1234567890")) (string-fill! str #\a 0 0) str) "1234567890") (test (let ((str "1234567890")) (string-fill! str #\a 4 4) str) "1234567890") (test (let ((str "1234567890")) (string-fill! str #\a 10 10) str) "1234567890") (test (let ((str "1234567890")) (string-fill! str #\a 0 4) str) "aaaa567890") (test (let ((str "1234567890")) (string-fill! str #\a 3 4) str) "123a567890") (test (let ((str "1234567890")) (string-fill! str #\a 1 9) str) "1aaaaaaaa0") (test (let ((str "1234567890")) (string-fill! str #\a 8) str) "12345678aa") (test (let ((str "1234567890")) (string-fill! str #\a 1 9 0) str) 'error) (test (let ((str "1234567890")) (string-fill! str #\a 1 0) str) 'error) (test (let ((str "1234567890")) (string-fill! str #\a 11) str) 'error) (test (let ((str "1234567890")) (string-fill! str #\a 9 11) str) 'error) (test (string-fill! "" 0 "hi") 'error) (test (string-fill! "" 0 -1 3) 'error) (test (string-fill! "" 0 1) 'error) (test (string-fill! "" 0 0 4/3) 'error) ;;; -------------------------------------------------------------------------------- ;;; string-upcase ;;; string-downcase (test (string-downcase "") "") (test (string-downcase "a") "a") (test (string-downcase "A") "a") (test (string-downcase "AbC") "abc") (test (string-downcase "\"\\\"") "\"\\\"") (test (let ((hi "abc")) (eq? hi (string-downcase hi))) #f) (test (string-downcase (string-upcase (string-downcase "a"))) "a") (test (string-downcase "a\x00b") "a\x00b") (test (string-downcase (string #\1 #\null #\2)) (string #\1 #\null #\2)) (test (string-downcase) 'error) (test (string-downcase "hi" "ho") 'error) (test (string-upcase "") "") (test (string-upcase "a") "A") (test (string-upcase "A") "A") (test (string-upcase "AbC") "ABC") (test (string-upcase "\"\\\"") "\"\\\"") (test (let ((hi "ABC")) (eq? hi (string-upcase hi))) #f) (test (string-upcase (string-downcase (string-upcase "a"))) "A") (test (string-upcase "a\x00b") "A\x00B") (test (string-upcase (string #\1 #\null #\2)) (string #\1 #\null #\2)) (test (string-upcase) 'error) (test (string-upcase "hi" "ho") 'error) (for-each (lambda (arg) (test (string-downcase arg) 'error) (test (string-upcase arg) 'error)) (list #\a 1 () (list 1) '(1 . 2) #f 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t :hi (if #f #f) (lambda (a) (+ a 1)))) ;;; for r7rs, these need to be unicode-aware ;;; -------------------------------------------------------------------------------- ;;; substring (test (substring "ab" 0 0) "") (test (substring "ab" 1 1) "") (test (substring "ab" 2 2) "") (test (substring "ab" 0 1) "a") (test (substring "ab" 1 2) "b") (test (substring "ab" 0 2) "ab") (test (substring "hi there" 3 6) "the") (test (substring "hi there" 0 (string-length "hi there")) "hi there") (test (substring "" 0 0) "") (let ((str "012345")) (let ((str1 (substring str 2 4))) (string-set! str1 1 #\x) (test (string=? str "012345") #t) (let ((str2 (substring str1 1))) (set! (str2 0) #\z) (test (string=? str "012345") #t) (test (string=? str1 "2x") #t) (test (string=? str2 "z") #t)))) (test (substring (substring "hiho" 0 2) 1) "i") (test (substring (substring "hiho" 0 2) 2) "") (test (substring (substring "hiho" 0 2) 0 1) "h") (test (substring "hi\nho" 3 5) "ho") (test (substring (substring "hi\nho" 1 4) 2) "h") (test (substring (substring "hi\nho" 3 5) 1 2) "o") (test (substring "hi\"ho" 3 5) "ho") (test (substring (substring "hi\"ho" 1 4) 2) "h") (test (substring (substring "hi\"ho" 3 5) 1 2) "o") (test (let* ((s1 "0123456789") (s2 (substring s1 1 3))) (string-set! s2 1 #\x) s1) "0123456789") (test (substring (substring "" 0 0) 0 0) "") (test (substring (format #f "") 0 0) "") (test (string=? (substring (substring (substring "01234567" 1) 1) 1) "34567") #t) (let () (define (hi) (string=? (substring (substring (substring "01234567" 1) 1) 1) "34567")) (define (ho) (hi)) (ho) (test (ho) #t)) (test (substring "012" 3) "") (test (substring "012" 10) 'error) (test (substring "012" most-positive-fixnum) 'error) (test (substring "012" -1) 'error) (test (substring "012" 3 3) "") (test (substring "012" 3 4) 'error) (test (substring "012" 3 2) 'error) (test (substring "012" 3 -2) 'error) (test (substring "012" 3 0) 'error) (test (substring "012" 0) "012") (test (substring "012" 2) "2") (test (substring "" 0) "") (test (recompose 12 (lambda (a) (substring a 0 3)) "12345") "123") (test (reinvert 12 (lambda (a) (substring a 0 3)) (lambda (a) (string-append a "45")) "12345") "12345") (test (substring "ab" 0 3) 'error) (test (substring "ab" 3 3) 'error) (test (substring "ab" 2 3) 'error) (test (substring "" 0 1) 'error) (test (substring "" -1 0) 'error) (test (substring "abc" -1 0) 'error) (test (substring "hiho" (expt 2 32) (+ 2 (expt 2 32))) 'error) (test (substring) 'error) (test (substring "hiho" 0 1 2) 'error) (test (substring "1234" -1 -1) 'error) (test (substring "1234" 1 0) 'error) (test (substring "" most-positive-fixnum 1) 'error) (let ((str "0123456789")) (string-set! str 5 #\null) (test (substring str 6) "6789") (test (substring str 5 5) "") (test (substring str 4 5) "4") (test (substring str 5 6) "\x00") (test (substring str 5 7) "\x006") (test (substring str 4 7) "4\x006")) (for-each (lambda (arg) (test (substring "hiho" arg 0) 'error)) (list "hi" #\a 1 () (list 1) '(1 . 2) #f 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t :hi (if #f #f) (lambda (a) (+ a 1)))) (for-each (lambda (arg) (test (substring "0123" arg) 'error) (test (substring "hiho" 1 arg) 'error)) (list "hi" #\a -1 () (list 1) '(1 . 2) #f 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t :hi (if #f #f) (lambda (a) (+ a 1)))) (for-each (lambda (arg) (test (substring arg 1 2) 'error)) (list #\a 1 () (list 1) '(1 . 2) #f 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t :hi (if #f #f) (lambda (a) (+ a 1)))) (define (substring? pattern target) ; taken from net somewhere (umich?) with changes for s7 (which now has string-position, so this is unneeded) (define (build-shift-vector pattern) (let* ((pat-len (length pattern)) (shift-vec (make-vector 256 (+ pat-len 1))) (max-pat-index (- pat-len 1))) (let loop ((index 0)) (set! (shift-vec (char->integer (pattern index))) (- pat-len index)) (if (< index max-pat-index) (loop (+ index 1)) shift-vec)))) (if (or (not (string? pattern)) (not (string? target))) (error 'wrong-type-arg "substring? args should be strings: ~S ~S" pattern target) (let ((pat-len (length pattern))) (if (zero? pat-len) 0 (let ((shift-vec (build-shift-vector pattern))) (let* ((tar-len (length target)) (max-tar-index (- tar-len 1)) (max-pat-index (- pat-len 1))) (let outer ((start-index 0)) (if (> (+ pat-len start-index) tar-len) #f (let inner ((p-ind 0) (t-ind start-index)) (cond ((> p-ind max-pat-index) #f) ; nothing left to check ((char=? (pattern p-ind) (target t-ind)) (if (= p-ind max-pat-index) start-index ; success -- return start index of match (inner (+ p-ind 1) (+ t-ind 1)))) ; keep checking ((> (+ pat-len start-index) max-tar-index) #f) ; fail (else (outer (+ start-index (shift-vec (char->integer (target (+ start-index pat-len))))))))))))))))) (test (substring? "hiho" "test hiho test") 5) (test (substring? "hiho" "test hihptest") #f) (test (substring? "hiho" "test hih") #f) (test (substring? "hiho" "") #f) (test (substring? "hiho" "hiho") 0) (test (substring? "" "hiho") 0) (test (substring? "abc" 'abc) 'error) ;;; -------------------------------------------------------------------------------- ;;; string-append (test (string-append "hi" "ho") "hiho") (test (string-append "hi") "hi") (test (string-append "hi" "") "hi") (test (string-append "hi" "" "ho") "hiho") (test (string-append "" "hi") "hi") (test (string-append) "") (test (string-append "a" (string-append (string-append "b" "c") "d") "e") "abcde") (test (string-append "a" "b" "c" "d" "e") "abcde") (test (string-append (string-append) (string-append (string-append))) "") (test (let ((hi "hi")) (let ((ho (string-append hi))) (eq? hi ho))) #f) (test (let ((hi "hi")) (let ((ho (string-append hi))) (string-set! ho 0 #\a) hi)) "hi") (test (let ((hi "hi")) (set! hi (string-append hi hi hi hi)) hi) "hihihihi") (test (string-append ()) 'error) (test (string=? (string-append "012" (string #\null) "456") (let ((str "0123456")) (string-set! str 3 #\null) str)) #t) (test (string=? (string-append "012" (string #\null) "356") (let ((str "0123456")) (string-set! str 3 #\null) str)) #f) (test (string-append """hi""ho""") "hiho") (test (let* ((s1 "hi") (s2 (string-append s1 s1))) (string-set! s2 1 #\x) s1) "hi") (test (let* ((s1 "hi") (s2 (string-append s1))) (string-set! s2 1 #\x) s1) "hi") (test (length (string-append (string #\x #\y (integer->char 127) #\z) (string #\a (integer->char 0) #\b #\c))) 8) (test (length (string-append "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc" "abc")) 915) (test (length (string-append (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c) (string #\a #\b #\c))) 915) (num-test (letrec ((hi (lambda (str n) (if (= n 0) str (hi (string-append str "a") (- n 1)))))) (string-length (hi "" 100))) 100) (test (let* ((str "hiho") (str1 "ha") (str2 (string-append str1 str))) (string-set! str2 1 #\x) (string-set! str2 4 #\x) (and (string=? str "hiho") (string=? str1 "ha") (string=? str2 "hxhixo"))) #t) (test (let* ((str (string-copy "hiho")) (str1 (string-copy "ha")) (str2 (string-append str1 str))) (string-set! str1 1 #\x) (string-set! str 2 #\x) (and (string=? str "hixo") (string=? str1 "hx") (string=? str2 "hahiho"))) #t) (let ((s1 (string #\x #\null #\y)) (s2 (string #\z #\null))) (test (string=? (string-append s1 s2) (string #\x #\null #\y #\z #\null)) #t) (test (string=? (string-append s2 s1) (string #\z #\null #\x #\null #\y)) #t)) (test (recompose 12 string-append "x") "x") (test (recompose 12 (lambda (a) (string-append a "x")) "a") "axxxxxxxxxxxx") (test (recompose 12 (lambda (a) (string-append "x" a)) "a") "xxxxxxxxxxxxa") (test (length (string-append "\\?" "hi")) 4) (test (string-append "hi" 1) 'error) (test (eval-string "(string-append \"\\?\")") 'error) ; guile mailing list (test (eval-string "(string-append \"\\?\" \"hi\")") 'error) ; guile mailing list (for-each (lambda (arg) (test (string-append "hiho" arg) 'error) (test (string-append arg "hi") 'error) (test (string-append "a" "b" arg) 'error)) (list #\a 1 () (list 1) '(1 . 2) #f 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t :hi (if #f #f) (lambda (a) (+ a 1)))) (test (let ((str (make-string 4 #\x)) (ctr 0)) (for-each (lambda (c) (string-set! str ctr c) (set! ctr (+ ctr 1))) "1234") str) "1234") (test (let ((str (make-string 8 #\x)) (ctr 0)) (for-each (lambda (c1 c2) (string-set! str ctr c1) (string-set! str (+ ctr 1) c2) (set! ctr (+ ctr 2))) "1234" "hiho") str) "1h2i3h4o") #| (let ((size 1024)) (let ((str (make-string size))) (do ((i 0 (+ i 1))) ((= i size)) (set! (str i) (integer->char (+ 1 (modulo i 255))))) (let ((str1 (string-copy str))) (test (string? str1) #t) (test (string-length str1) 1024) (test (string-ref str1 556) (string-ref str 556)) (test (string=? str str1) #t) (test (string<=? str str1) #t) (test (string>=? str str1) #t) (test (string-ci=? str str1) #t) (test (string-ci<=? str str1) #t) (test (string-ci>=? str str1) #t) (test (string? str str1) #f) (test (string-ci? str str1) #f) (test (substring str 123 321) (substring str1 123 321)) (string-set! str1 1000 #\space) (test (string=? str str1) #f) (test (string<=? str str1) #f) (test (string>=? str str1) #t) (test (string-ci=? str str1) #f) (test (string-ci<=? str str1) #f) (test (string-ci>=? str str1) #t) (test (string? str str1) #t) (test (string-ci? str str1) #t) (test (string-length (string-append str str1)) 2048) )))) |# ;;; -------------------------------------------------------------------------------- ;;; string->list ;;; list->string (test (string->list "abc") (list #\a #\b #\c)) (test (string->list "") ()) (test (string->list (make-string 0)) ()) (test (string->list (string #\null)) '(#\null)) (test (string->list (string)) ()) (test (string->list (substring "hi" 0 0)) ()) (test (string->list (list->string (list #\a #\b #\c))) (list #\a #\b #\c)) (test (string->list (list->string ())) ()) (test (list->string (string->list "abc")) "abc") (test (list->string (string->list "hi there")) "hi there") (test (list->string (string->list "&*#%^@%$)~@")) "&*#%^@%$)~@") (test (list->string (string->list "")) "") (test (let* ((str "abc") (lst (string->list str))) (and (string=? str "abc") (equal? lst (list #\a #\b #\c)))) #t) (test (list->string ()) "") (test (list->string (list #\a #\b #\c)) "abc") (test (list->string (list)) "") (test (list->string (list #\" #\# #\")) "\"#\"") (test (list->string (list #\\ #\\ #\# #\\ #\# #\#)) "\\\\#\\##") (test (list->string (list #\' #\' #\` #\")) '"''`\"") (test (reinvert 12 string->list list->string "12345") "12345") (test (string->list) 'error) (test (list->string) 'error) (test (string->list "hi" "ho") 'error) (test (list->string () '(1 2)) 'error) (test (string->list " hi ") '(#\space #\h #\i #\space)) (test (string->list (string (integer->char #xf0) (integer->char #x70))) (list (integer->char #xf0) (integer->char #x70))) (for-each (lambda (arg) (test (string->list arg) 'error)) (list #\a 1 () (list 1) '(1 . 2) #f 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t :hi (if #f #f) (lambda (a) (+ a 1)))) (test (let ((x (cons #\a #\b))) (set-cdr! x x) (list->string x)) 'error) (test (let ((lst (list #\a #\b))) (set! (cdr (cdr lst)) lst) (list->string lst)) 'error) (test (let ((lst (list #\a #\b))) (set! (cdr (cdr lst)) lst) (apply string lst)) 'error) (for-each (lambda (arg) (test (list->string arg) 'error)) (list "hi" #\a 1 ''foo '(1 . 2) (cons #\a #\b) #f 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t :hi (if #f #f) (lambda (a) (+ a 1)))) (let ((str (list->string '(#\x #\space #\null #\x)))) (test (length str) 4) (test (str 1) #\space) (test (str 2) #\null) (test (str 3) #\x) (test (object->string str) "\"x \\x00x\"") (let ((lst (string->list str))) (test lst '(#\x #\space #\null #\x)))) (let ((strlen 8)) (let ((str (make-string strlen))) (do ((i 0 (+ i 1))) ((= i 10)) (do ((k 0 (+ k 1))) ((= k strlen)) (set! (str k) (integer->char (random 256)))) (let ((lst (string->list str))) (let ((newstr (list->string lst))) (let ((lstlen (length lst)) (newstrlen (length newstr))) (if (or (not (= lstlen strlen newstrlen)) (not (string=? newstr str))) (format-logged #t ";string->list->string: ~S -> ~A -> ~S~%" str lst newstr)))))))) (when full-test (let () (define (all-strs len file) (let* ((funny-chars (list #\` #\# #\, #\@ #\' #\" #\. #\( #\) #\\)) (num-chars (length funny-chars))) (let ((ctrs (make-vector len 0))) (do ((i 0 (+ i 1))) ((= i (expt num-chars len))) (let ((carry #t)) (do ((k 0 (+ k 1))) ((or (= k len) (not carry))) (vector-set! ctrs k (+ 1 (vector-ref ctrs k))) (if (= (vector-ref ctrs k) num-chars) (vector-set! ctrs k 0) (set! carry #f))) (let ((strlst ())) (do ((k 0 (+ k 1))) ((= k len)) (let ((c (list-ref funny-chars (vector-ref ctrs k)))) (set! strlst (cons c strlst)))) (let ((str (list->string strlst))) (format file "(test (and (string=? ~S (string ~{#\\~C~^ ~})) (equal? '~A (string->list ~S))) #t)~%" str strlst strlst str)))))))) (call-with-output-file "strtst.scm" (lambda (p) (do ((len 3 (+ len 1))) ((= len 5)) (all-strs len p)))) (load "strtst.scm"))) (test (and (string=? "\"" (string #\")) (equal? '(#\") (string->list "\""))) #t) (test (and (string=? "#\\" (string #\# #\\)) (equal? '(#\# #\\) (string->list "#\\"))) #t) (test (and (string=? "#(" (string #\# #\()) (equal? '(#\# #\() (string->list "#("))) #t) (test (and (string=? "\"@" (string #\" #\@)) (equal? '(#\" #\@) (string->list "\"@"))) #t) (test (and (string=? "\";" (string #\" #\;)) (equal? '(#\" #\;) (string->list "\";"))) #t) (test (and (string=? ")(" (string #\) #\()) (equal? '(#\) #\() (string->list ")("))) #t) (test (and (string=? "`)#" (string #\` #\) #\#)) (equal? '(#\` #\) #\#) (string->list "`)#"))) #t) (test (and (string=? "##\\" (string #\# #\# #\\)) (equal? '(#\# #\# #\\) (string->list "##\\"))) #t) (test (and (string=? "#\"(" (string #\# #\" #\()) (equal? '(#\# #\" #\() (string->list "#\"("))) #t) (test (and (string=? "#.@" (string #\# #\. #\@)) (equal? '(#\# #\. #\@) (string->list "#.@"))) #t) (test (and (string=? ",`@" (string #\, #\` #\@)) (equal? '(#\, #\` #\@) (string->list ",`@"))) #t) (test (and (string=? "',@" (string #\' #\, #\@)) (equal? '(#\' #\, #\@) (string->list "',@"))) #t) (test (and (string=? "\"#@" (string #\" #\# #\@)) (equal? '(#\" #\# #\@) (string->list "\"#@"))) #t) (test (and (string=? "\")\"" (string #\" #\) #\")) (equal? '(#\" #\) #\") (string->list "\")\""))) #t) (test (and (string=? ")#(" (string #\) #\# #\()) (equal? '(#\) #\# #\() (string->list ")#("))) #t) (test (and (string=? "`(,@" (string #\` #\( #\, #\@)) (equal? '(#\` #\( #\, #\@) (string->list "`(,@"))) #t) (test (and (string=? "`)#\"" (string #\` #\) #\# #\")) (equal? '(#\` #\) #\# #\") (string->list "`)#\""))) #t) (test (and (string=? "#\"'#" (string #\# #\" #\' #\#)) (equal? '(#\# #\" #\' #\#) (string->list "#\"'#"))) #t) (test (and (string=? "#(@\\" (string #\# #\( #\@ #\\)) (equal? '(#\# #\( #\@ #\\) (string->list "#(@\\"))) #t) (test (and (string=? "#(\\\\" (string #\# #\( #\\ #\\)) (equal? '(#\# #\( #\\ #\\) (string->list "#(\\\\"))) #t) (test (and (string=? ",,.@" (string #\, #\, #\. #\@)) (equal? '(#\, #\, #\. #\@) (string->list ",,.@"))) #t) (test (and (string=? ",@`\"" (string #\, #\@ #\` #\")) (equal? '(#\, #\@ #\` #\") (string->list ",@`\""))) #t) (test (and (string=? "\"'\")" (string #\" #\' #\" #\))) (equal? '(#\" #\' #\" #\)) (string->list "\"'\")"))) #t) (test (and (string=? "\")#\"" (string #\" #\) #\# #\")) (equal? '(#\" #\) #\# #\") (string->list "\")#\""))) #t) (test (and (string=? "(\\`)" (string #\( #\\ #\` #\))) (equal? '(#\( #\\ #\` #\)) (string->list "(\\`)"))) #t) (test (and (string=? "))\"'" (string #\) #\) #\" #\')) (equal? '(#\) #\) #\" #\') (string->list "))\"'"))) #t) (test (and (string=? "\\,\\\"" (string #\\ #\, #\\ #\")) (equal? '(#\\ #\, #\\ #\") (string->list "\\,\\\""))) #t) (test (and (string=? "\\\"`\"" (string #\\ #\" #\` #\")) (equal? '(#\\ #\" #\` #\") (string->list "\\\"`\""))) #t) (test (and (string=? "\\\\#\"" (string #\\ #\\ #\# #\")) (equal? '(#\\ #\\ #\# #\") (string->list "\\\\#\""))) #t) (test (string->list "" 0 10) 'error) (test (string->list "1" 0 2) 'error) (test (string->list "" 0 0) ()) (test (string->list "1" 1) ()) (test (string->list "1" 0) '(#\1)) (test (string->list "" #\null) 'error) (test (string->list "" 0 #\null) 'error) (test (string->list "" -1) 'error) (test (string->list "1" -1) 'error) (test (string->list "1" 0 -1) 'error) (test (string->list "1" -2 -1) 'error) (test (string->list "1" most-negative-fixnum) 'error) (test (string->list "1" 2) 'error) (for-each (lambda (arg) (test (string->list "012345" arg) 'error) (test (string->list "012345" 1 arg) 'error)) (list #\a "hi" () (list 1) '(1 . 2) 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t :hi (if #f #f) (lambda (a) (+ a 1)))) (test (string->list "12345" 0) '(#\1 #\2 #\3 #\4 #\5)) (test (string->list "12345" 0 5) '(#\1 #\2 #\3 #\4 #\5)) (test (string->list "12345" 5 5) ()) (test (string->list "12345" 4 5) '(#\5)) (test (string->list "12345" 2 4) '(#\3 #\4)) (test (string->list "12345" 2 1) 'error) (test (string->list "12345" 2 3 4) 'error) (test (string->list (make-string 3 #\null) 2 3) '(#\null)) ;;; -------------------------------------------------------------------------------- ;;; char-position ;;; string-position (test (char-position) 'error) (test (char-position #\a) 'error) (test (char-position #\a "abc" #\0) 'error) (test (char-position #\a "abc" 0 1) 'error) (test (string-position) 'error) (test (string-position #\a) 'error) (test (string-position "a" "abc" #\0) 'error) (test (string-position "a" "abc" 0 1) 'error) (for-each (lambda (arg) (test (string-position arg "abc") 'error) (test (char-position arg "abc") 'error) (test (string-position "a" arg) 'error) (test (char-position #\a arg) 'error) (test (string-position "a" "abc" arg) 'error) (test (char-position #\a "abc" arg) 'error)) (list () (list 1) '(1 . 2) #f 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 -1 most-negative-fixnum 1.0+1.0i :hi (if #f #f) (lambda (a) (+ a 1)))) (test (char-position #\a "abc" most-positive-fixnum) #f) (test (char-position "a" "abc" most-positive-fixnum) #f) (test (string-position "a" "abc" most-positive-fixnum) #f) (test (char-position #\b "abc") 1) (test (char-position #\b "abc" 0) 1) (test (char-position #\b "abc" 1) 1) (test (char-position "b" "abc") 1) (test (char-position "b" "abc" 1) 1) (test (char-position "b" "abc") 1) (test (string-position "b" "abc") 1) (test (string-position "b" "abc" 1) 1) (test (string-position "b" "abc" 2) #f) (test (string-position "b" "abc" 3) #f) (test (char-position "b" "abc" 2) #f) (test (char-position "b" "abc" 3) #f) (test (char-position #\b "abc" 2) #f) (test (char-position #\b "abc" 3) #f) (test (char-position "ab" "abcd") 0) (test (char-position "ab" "ffbcd") 2) (test (char-position "ab" "ffacd") 2) (test (string-position "ab" "ffacd") #f) (test (string-position "ab" "ffabd") 2) (test (string-position "ab" "ffabab" 2) 2) (test (string-position "ab" "ffabab" 3) 4) (test (string-position "ab" "ffabab" 4) 4) (test (string-position "ab" "ffabab" 5) #f) (test (string-position "abc" "ab") #f) (test (string-position "abc" "") #f) (test (string-position "" "") #f) (test (char-position "\"" "a") #f) (test (char-position "\"" "a\"b") 1) (test (char-position #\" "a\"b") 1) (test (string-position "\"hiho\"" "hiho") #f) (test (string-position "\"hiho\"" "\"\"hiho\"") 1) (test (string-position "" "a") #f) ; this is a deliberate choice in s7.c (test (char-position "" "a") #f) (test (char-position #\null "a") 1) ; ?? (test (char-position #\null "") #f) ; ?? (test (string-position (string #\null) "a") 0) ; ?? (test (string-position (string #\null) "") #f) ; ?? (test (char-position #\null (string #\null)) 0) ; ?? (test (char-position #\null (string #\a #\null #\n)) 1) (test (char-position "" (string #\a #\null #\n)) #f) ;(test (char-position #\n (string #\a #\null #\n)) 2) ; ?? returns #f due to assumption of C-style strings ;(test (char-position "n" (string #\a #\null #\n)) 1) ; oops! ;(test (string-position "n" (string #\a #\null #\n)) 2) ; oops! (test (char-position "" (string #\a #\n)) #f) (test (char-position #(1) "asdasd" 63) 'error) ;; if "" as string-pos 1st, -> #f so same for char-pos, even if string contains a null (let () ;; actually more of a string-append/temp substring test (define (fixit str) (let ((pos (char-position #\& str))) (if (not pos) str (string-append (substring str 0 pos) (let ((epos (char-position #\; str pos))) (let ((substr (substring str (+ pos 1) epos))) (let ((replacement (if (string=? substr "gt") ">" (if (string=? substr "lt") "<" (if (string=? substr "mdash") "-" (format-logged #t "unknown: ~A~%" substr)))))) (string-append replacement (fixit (substring str (+ epos 1))))))))))) (test (fixit "(let ((f (hz->radians 100)) (g (hz->radians 200))) (< f g))") "(let ((f (hz->radians 100)) (g (hz->radians 200))) (< f g))")) ;;; opt bug (test (apply char-position '(#\a #u8() #f)) 'error) (test (let () (define (f1) (do ((i 0 (+ i 1))) ((= i 1) (char-position #\a #u8() #f)) (char-position #\a #u8() #f))) (f1)) 'error) ;;; -------------------------------------------------------------------------------- ;;; symbol->string ;;; string->symbol ;;; symbol (test (symbol->string 'hi) "hi") (test (string->symbol (symbol->string 'hi)) 'hi) (test (eq? (string->symbol "hi") 'hi) #t) (test (eq? (string->symbol "hi") (string->symbol "hi")) #t) (test (string->symbol "hi") 'hi) (test (let ((str (symbol->string 'hi))) (catch #t (lambda () (string-set! str 1 #\x)) (lambda args 'error)) ; can be disallowed (symbol->string 'hi)) "hi") (test (symbol->string 'sym0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789) "sym0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789") (test (string->symbol "sym0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789") 'sym0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789) (test (let ((sym0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 32)) (+ sym0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 1)) 33) (test (symbol->string (string->symbol "hi there")) "hi there") (test (symbol->string (string->symbol "Hi There")) "Hi There") (test (symbol->string (string->symbol "HI THERE")) "HI THERE") (test (symbol->string (string->symbol "")) 'error) ; this fluctuates (test (symbol? (string->symbol "(weird name for a symbol!)")) #t) (test (symbol->string (string->symbol "()")) "()") (test (symbol->string (string->symbol (string #\"))) "\"") (test (symbol->string 'quote) "quote") (test (symbol->string if) 'error) (test (symbol->string quote) 'error) (test (symbol? (string->symbol "0")) #t) (test (symbol? (symbol "0")) #t) (test (symbol? (symbol ".")) #t) ; hmmm (test (let () (define |.| 1) (+ |.| 2)) 3) (test (string->symbol "0e") '0e) (test (string->symbol "1+") '1+) (test (symbol? (string->symbol "1+i")) #t) (test (string->symbol ":0") ':0) (test (symbol? (string->symbol " hi") ) #t) (test (symbol? (string->symbol "hi ")) #t) (test (reinvert 12 string->symbol symbol->string "hiho") "hiho") (test (symbol->string) 'error) (test (string->symbol) 'error) (test (symbol->string 'hi 'ho) 'error) (test (string->symbol "hi" "ho") 'error) (test (symbol? (string->symbol (string #\x (integer->char 255) #\x))) #t) (test (symbol? (string->symbol (string #\x (integer->char 8) #\x))) #t) (test (symbol? (string->symbol (string #\x (integer->char 128) #\x))) #t) (test (symbol? (string->symbol (string #\x (integer->char 200) #\x))) #t) (test (symbol? (string->symbol (string #\x (integer->char 255) #\x))) #t) (test (symbol? (string->symbol (string #\x (integer->char 20) #\x))) #t) (test (symbol? (string->symbol (string #\x (integer->char 2) #\x))) #t) (test (symbol? (string->symbol (string #\x (integer->char 7) #\x))) #t) (test (symbol? (string->symbol (string #\x (integer->char 17) #\x))) #t) (test (symbol? (string->symbol (string #\x (integer->char 170) #\x))) #t) (test (symbol? (string->symbol (string #\x (integer->char 0) #\x))) #t) ; but the symbol's name here is "x" ;(test (eq? (string->symbol (string #\x (integer->char 0) #\x)) 'x) #t) ; hmmm... (test (symbol? (string->symbol (string #\x #\y (integer->char 127) #\z))) #t) ; xy(backspace)z (test (symbol? (string->symbol (string #\; #\" #\)))) #t) (test (let (((symbol ";")) 3) (symbol ";")) 'error) (test (symbol "") 'error) (for-each (lambda (arg) (test (symbol->string arg) 'error)) (list #\a 1 "hi" () (list 1) '(1 . 2) #f (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t (if #f #f) (lambda (a) (+ a 1)))) (for-each (lambda (arg) (test (string->symbol arg) 'error) (test (symbol arg) 'error)) (list #\a 1 () (list 1) '(1 . 2) #f 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t :hi (if #f #f) (lambda (a) (+ a 1)))) (for-each (lambda (arg) (test (symbol? (string->symbol (string arg))) #t) (test (symbol? (symbol (string arg))) #t)) (list #\; #\, #\. #\) #\( #\" #\' #\` #\x33 #\xff #\x7f #\# #\])) (test (symbol) 'error) (test (symbol "hi" "ho") 'error) (let () (define-macro (string-case selector . clauses) `(case (symbol ,selector) ,@(map (lambda (clause) (if (pair? (car clause)) `(,(map symbol (car clause)) ,@(cdr clause)) clause)) clauses))) (test (let ((str "hi")) (string-case str (("hi" "ho") 1 2 3) (("hiho") 2) (else 4))) 3)) (let () (apply define (list (symbol "(#)") 3)) (test (eval (symbol "(#)")) 3)) (let () (define (immutable obj) (string->symbol (object->string obj :readable))) (define (symbol->object sym) (eval-string (symbol->string sym))) (test (symbol->object (immutable (list 1 2 3))) (list 1 2 3)) (test (symbol->object (immutable "hi")) "hi")) #| (let ((str "(let ((X 3)) X)")) (do ((i 0 (+ i 1))) ((= i 256)) (catch #t (lambda () (if (symbol? (string->symbol (string (integer->char i)))) (catch #t (lambda () (set! (str 7) (integer->char i)) (set! (str 13) (integer->char i)) (let ((val (eval-string str))) #t)) ;(format-logged #t "ok: ~S -> ~S~%" str val))) (lambda args (format-logged #t "bad but symbol: ~S~%" str))))) ; 11 12 # ' , . (lambda args (format-logged #t "bad: ~C~%" (integer->char i)))))) ; # ( ) ' " . ` nul 9 10 13 space 0..9 ; (let ((str "(let ((XY 3)) XY)")) (do ((i 0 (+ i 1))) ((= i 256)) (do ((k 0 (+ k 1))) ((= k 256)) (catch #t (lambda () (if (symbol? (string->symbol (string (integer->char i)))) (catch #t (lambda () (set! (str 7) (integer->char i)) (set! (str 8) (integer->char k)) (set! (str 14) (integer->char i)) (set! (str 15) (integer->char k)) (let ((val (eval-string str))) #t)) ;(format-logged #t "ok: ~S -> ~S~%" str val))) (lambda args (format-logged #t "bad but symbol: ~S~%" str))))) ; 11 12 # ' , . (lambda args (format-logged #t "bad: ~C~%" (integer->char i))))))) ; # ( ) ' " . ` nul 9 10 13 space 0..9 ; |# ;;; -------------------------------------------------------------------------------- ;;; symbol->value ;;; symbol->dynamic-value (let ((sym 0)) (test (symbol->value 'sym) 0) (test (symbol->dynamic-value 'sym) 0) (for-each (lambda (arg) (set! sym arg) (test (symbol->value 'sym) arg) (test (symbol->dynamic-value 'sym) arg)) (list #\a 1 () (list 1) '(1 . 2) #f (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand (log 0) 3.14 3/4 1.0+1.0i #t (if #f #f) # (lambda (a) (+ a 1))))) (for-each (lambda (arg) (test (symbol->value arg) 'error) (test (symbol->value 'abs arg) 'error) (test (symbol->dynamic-value arg) 'error) (test (symbol->dynamic-value 'abs arg) 'error)) (list #\a 1 () (list 1) "hi" '(1 . 2) #f (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t (if #f #f) # (lambda (a) (+ a 1)))) (test (symbol->value) 'error) (test (symbol->value 'hi 'ho) 'error) (test (symbol->dynamic-value) 'error) (test (symbol->dynamic-value 'hi 'ho) 'error) (test (symbol->value 'abs (unlet)) abs) (test (symbol->value 'abs (rootlet)) abs) (test (symbol->value 'lambda) lambda) (test (symbol->value 'do) do) (test (symbol->value do) 'error) (test (symbol->value 'macroexpand) macroexpand) (test (symbol->value 'quasiquote) quasiquote) (test (symbol->value 'else) else) (test (symbol->value :hi) :hi) (test (symbol->value hi:) hi:) (test (symbol->dynamic-value 'lambda) lambda) (test (symbol->dynamic-value 'do) do) (test (symbol->dynamic-value do) 'error) (test (symbol->dynamic-value 'macroexpand) macroexpand) (test (symbol->dynamic-value 'quasiquote) quasiquote) (test (symbol->dynamic-value 'else) else) (test (symbol->dynamic-value :hi) :hi) (test (symbol->dynamic-value hi:) hi:) (test (symbol->value '#) 'error) ; because it's not a symbol: (test (symbol? '#) #f) (test (let ((a1 32)) (let () (symbol->value 'a1 (curlet)))) 32) (test (let ((a1 32)) (let ((a1 0)) (symbol->value 'a1 (curlet)))) 0) (test (let ((a1 32)) (let ((a1 0)) (symbol->value 'b1 (curlet)))) #) (test (symbol->value 'abs ()) 'error) (test (let ((a1 (let ((b1 32)) (lambda () b1)))) (symbol->value 'b1 (funclet a1))) 32) (test (let ((x #f)) (set! x (let ((a1 (let ((b1 32)) (lambda () b1)))) a1)) (symbol->value 'b1 (funclet x))) 32) (test (symbol->value 'if) if) (test (symbol->value if) 'error) (test ((define (hi a) (+ a 1)) 2) 3) (test ((define-macro (hi a) `(+ ,a 1)) 2) 3) (test (let ((mac (define-macro (hi a) `(+ ,a 1)))) (mac 3)) 4) (test (eq? #_abs (symbol->value 'abs 'unlet)) #t) (test (eq? #_lambda (symbol->value 'lambda 'unlet)) #t) (let () (define *ds* 0) (define (get-ds) (list *ds* (symbol->dynamic-value '*ds*))) (test (get-ds) '(0 0)) (let ((*ds* 32)) (test (values (get-ds)) '(0 32))) (let ((*ds* 3)) (define (gds) (list *ds* (symbol->dynamic-value '*ds*))) (test (list (get-ds) (gds)) '((0 3) (3 3))) (let ((*ds* 123)) (test (list (get-ds) (gds)) '((0 123) (3 123))))) (let ((*ds* 3)) (define (gds) (list *ds* (symbol->dynamic-value '*ds*))) (let ((*ds* 123)) (set! *ds* 321) (test (list (get-ds) (gds)) '((0 321) (3 321)))))) (test (symbol->dynamic-value 'asdasfasdasfg) #) (let ((x 32)) (define (gx) (symbol->dynamic-value 'x)) (let ((x 12)) (test (values (gx)) 12))) (let ((x "hi") (y 0) (z '(1 2 3))) (define (gx) (+ (symbol->dynamic-value 'x) (symbol->dynamic-value 'z))) (let ((x 32) (z (+ 123 (car z)))) (test (values (gx)) 156))) (let ((x 32)) (define (gx) (symbol->dynamic-value 'x)) (let ((x 100)) (let ((x 12)) (test (values (gx)) 12)))) (let ((x 32)) (define (gx) ; return both bindings of 'x (list x (symbol->value 'x) (symbol->dynamic-value 'x))) (let ((x 100)) (let ((x 12)) (test (values (gx)) '(32 32 12))))) (let ((bindings ())) ;; taken from the MIT_Scheme documentation (changing fluid-let to let) (define (write-line v) (set! bindings (cons v bindings))) (define (complicated-dynamic-binding) (let ((variable 1) (inside-continuation #f)) (write-line variable) (call-with-current-continuation (lambda (outside-continuation) (let ((variable 2)) (write-line variable) (set! variable 3) (call-with-current-continuation (lambda (k) (set! inside-continuation k) (outside-continuation #t))) (write-line variable) (set! inside-continuation #f)))) (write-line variable) (if inside-continuation (begin (set! variable 4) (inside-continuation #f))))) (complicated-dynamic-binding) (test (reverse bindings) '(1 2 1 3 4))) ;;; -------------------------------------------------------------------------------- ;;; BYTE-VECTORS ;;; -------------------------------------------------------------------------------- (let ((bv #u8(1 0 3))) (test bv #u8(1 0 3)) (test (object->string bv) "#u8(1 0 3)") (test (equal? bv #u8(1 0 3)) #t) (test (eq? bv bv) #t) (test (eqv? bv bv) #t) (test (equal? (byte-vector 1 0 3) #u8(1 0 3)) #t) (test (byte-vector? bv) #t) (test (equal? (make-byte-vector 3) #u8(0 0 0)) #t) (test (string-ref #u8(64 65 66) 1) #\A) (test (let ((nbv (copy bv))) (equal? nbv bv)) #t) (test (let ((rbv (reverse bv))) (equal? rbv #u8(3 0 1))) #t) (test (length bv) 3) ) (test (eval-string "#u8(-1)") 'error) (test (eval-string "#u8(1.0)") 'error) (test (eval-string "#u8(3/2)") 'error) (test (eval-string "#u8(1+i)") 'error) (test (eval-string "#u8((32))") 'error) (test (eval-string "#u8(#\\a)") 'error) (test (eval-string "#u8(256)") 'error) (test (eval-string "#u8(1/0)") 'error) (test (eval-string "#u8(9223372036854775807)") 'error) (test (eval-string "#u8(-9223372036854775808)") 'error) (test #u8(#b11 #x8) #u8(3 8)) (test (eval-string "#u8(1 2 . 3)") 'error) (test #u8(255) (byte-vector 255)) (test (object->string #u8()) "#u8()") (test (object->string #u8(255)) "#u8(255)") (test (object->string #u8(255 255)) "#u8(255 255)") (test (object->string #u8(128)) "#u8(128)") (test (object->string #u8(128 128)) "#u8(128 128)") (test (length #u8(0)) 1) (test (length #u8(0 0)) 2) (test (length #u8()) 0) (test (length (byte-vector)) 0) (test (byte-vector? #u8()) #t) (test (equal? (let ((bv #u8(1 0 3))) (set! (bv 2) 64) bv) #u8(1 0 64)) #t) (test (let ((bv #u8(1 0 3))) (map values bv)) '(1 0 3)) (test (let ((bv #u8(1 0 3)) (lst ())) (for-each (lambda (x) (set! lst (cons x lst))) bv) lst) '(3 0 1)) (test (let ((bv #u8(1 2 3))) (bv 1)) 2) (test (let ((bv #u8(1 2 3))) (reverse bv)) #u8(3 2 1)) (test (let ((bv #u8(1 2 3))) (object->string (reverse bv))) "#u8(3 2 1)") (test (let ((bv #u8(1 2 3))) (copy bv)) #u8(1 2 3)) (test (#u8(1 2 3) 2) 3) (test (let ((v #u8(0 1 2))) (let ((v1 (reverse! v))) (eq? v v1))) #t) (test (let ((v #u8(0 1 2))) (reverse! v)) #u8(2 1 0)) ;; should (vector? #u8(1 2)) be #t? (test (format #f "~{~A ~}" (byte-vector 255 0)) "255 0 ") ;;; ->byte-vector (test (byte-vector? (->byte-vector (string #\0))) #t) (test (byte-vector? (->byte-vector "")) #t) (test (byte-vector? (->byte-vector "1230")) #t) (test (byte-vector? (->byte-vector (->byte-vector (string #\0)))) #t) (test (byte-vector? (->byte-vector (string))) #t) (test (byte-vector? (->byte-vector #u8(1 2))) #t) (test (byte-vector? (->byte-vector #u8())) #t) (test (byte-vector? (->byte-vector #(1 2))) 'error) (test (byte-vector? (string-append #u8(1 2) #u8(3 4))) #t) (for-each (lambda (arg) (test (->byte-vector arg) 'error) (test (byte-vector? arg) #f)) (list #\a () (list 1) '(1 . 2) #f (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t (if #f #f) # (lambda (a) (+ a 1)))) ;;; an experiment: (test (->byte-vector #x010203) #u8(3 2 1 0 0 0 0 0)) ;;; make-byte-vector (test (equal? (make-byte-vector 0) #u8()) #t) (test (equal? (make-byte-vector 0 32) #u8()) #t) (test (equal? (make-byte-vector 1 32) #u8(32)) #t) (test (make-byte-vector 0 -32) 'error) (test (make-byte-vector 1 -32) 'error) (test (make-byte-vector 1 256) 'error) (for-each (lambda (arg) (test (make-byte-vector arg) 'error) (test (make-byte-vector 1 arg) 'error)) (list #\a () (list 1) '(1 . 2) #f (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t (if #f #f) # (lambda (a) (+ a 1)))) ;;; byte-vector (test (byte-vector) #u8()) (test (byte-vector 32) (make-byte-vector 1 32)) (test (byte-vector 0 256) 'error) (test (byte-vector -1) 'error) (for-each (lambda (arg) (test (byte-vector arg) 'error)) (list #\a () (list 1) '(1 . 2) #f (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t (if #f #f) # (lambda (a) (+ a 1)))) (test (map append #u8(0 1 2)) '(0 1 2)) (test (format #f "~{#x~X~| ~}" #u8(49 50 51)) "#x31 #x32 #x33") (test (format #f "~{~D~| ~}" (->byte-vector "abcd")) "97 98 99 100") (test (let ((lst ())) (for-each (lambda (c) (set! lst (cons c lst))) #u8(90 91 92)) (reverse lst)) '(90 91 92)) (test (integer? (#u8(1 2 3) 0)) #t) (test (integer? ((->byte-vector "abc") 1)) #t) (test ((vector (byte-vector 1)) 0 0) 1) ; i.e. not a character (let ((bv (byte-vector 0 1 2 3))) (fill! bv 4) (test bv #u8(4 4 4 4)) (fill! bv 1 1 3) (test bv #u8(4 1 1 4)) (let ((bv1 (copy bv))) (test bv1 #u8(4 1 1 4)) (fill! bv 1) (copy bv bv1) (test bv1 #u8(1 1 1 1)) (fill! bv 255) (copy bv bv1 1 3) (test bv1 #u8(255 255 1 1)))) ; copy and fill do not interpret their indices in the same way (one is source, the other destination) ;;; -------------------------------------------------------------------------------- ;;; LISTS ;;; -------------------------------------------------------------------------------- ;;; -------------------------------------------------------------------------------- ;;; cons (test (cons 'a ()) '(a)) (test (cons '(a) '(b c d)) '((a) b c d)) (test (cons "a" '(b c)) '("a" b c)) (test (cons 'a 3) '(a . 3)) (test (cons '(a b) 'c) '((a b) . c)) (test (cons () ()) '(())) (test (cons () 1) '(() . 1)) (test (cons 1 2) '(1 . 2)) (test (cons 1 ()) '(1)) (test (cons () 2) '(() . 2)) (test (cons 1 (cons 2 (cons 3 (cons 4 ())))) '(1 2 3 4)) (test (cons 'a 'b) '(a . b)) (test (cons 'a (cons 'b (cons 'c ()))) '(a b c)) (test (cons 'a (list 'b 'c 'd)) '(a b c d)) (test (cons 'a (cons 'b (cons 'c 'd))) '(a b c . d)) (test '(a b c d e) '(a . (b . (c . (d . (e . ())))))) (test (cons (cons 1 2) (cons 3 4)) '((1 . 2) 3 . 4)) (test (list (cons 1 2) (cons 3 4)) '((1 . 2) (3 . 4))) (test (cons (cons 1 (cons 2 3)) 4) '((1 . (2 . 3)) . 4)) (test (cons (cons 1 (cons 2 ())) (cons 1 2)) '((1 2) . (1 . 2))) (test (let ((lst (list 1 2))) (list (apply cons lst) lst)) '((1 . 2) (1 2))) (test (let ((lst (list 1 2))) (list lst (apply cons lst))) '((1 2) (1 . 2))) (test (cdadr (let ((lst (list 1 2))) (list (apply cons lst) lst))) '(2)) (test (cons '+ '=) '(+ . =)) (test (cons .(cadddr 10)) (cons cadddr 10)) (test (cons 1 ()) '( 1 )) ;;; -------------------------------------------------------------------------------- ;;; car (test (car (list 1 2 3)) 1) (test (car (cons 1 2)) 1) (test (car (list 1)) 1) (test (car '(1 2 3)) 1) (test (car '(1)) 1) (test (car '(1 . 2)) 1) (test (car '((1 2) 3)) '(1 2)) (test (car '(((1 . 2) . 3) 4)) '((1 . 2) . 3)) (test (car (list (list) (list 1 2))) ()) (test (car '(a b c)) 'a) (test (car '((a) b c d)) '(a)) (test (car (reverse (list 1 2 3 4))) 4) (test (car (list 'a 'b 'c 'd 'e 'f 'g)) 'a) (test (car '(a b c d e f g)) 'a) (test (car '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b c) e f g)) '((((1 2 3) 4) 5) (6 7))) (test (car '(a)) 'a) (test (car '(1 ^ 2)) 1) (test (car '(1 .. 2)) 1) (test (car ''foo) 'quote) (test (car '(1 2 . 3)) 1) (test (car (cons 1 ())) 1) (test (car (if #f #f)) 'error) (test (car ()) 'error) (test (car #(1 2)) 'error) (test (car #(1 2)) 'error) (for-each (lambda (arg) (if (not (equal? (car (cons arg ())) arg)) (format-logged #t ";(car '(~A)) returned ~A?~%" arg (car (cons arg ())))) (test (car arg) 'error)) (list "hi" (integer->char 65) #f 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand (log 0) 3.14 3/4 1.0+1.0i #\f #t :hi (if #f #f) (lambda (a) (+ a 1)))) (test (reinvert 12 car (lambda (a) (cons a ())) '(1)) '(1)) ;;; -------------------------------------------------------------------------------- ;;; cdr (test (cdr (list 1 2 3)) '(2 3)) (test (cdr (cons 1 2)) 2) (test (cdr (list 1)) ()) (test (cdr '(1 2 3)) '(2 3)) (test (cdr '(1)) ()) (test (cdr '(1 . 2)) 2) (test (cdr '((1 2) 3)) '(3)) (test (cdr '(((1 . 2) . 3) 4)) '(4)) (test (cdr (list (list) (list 1 2))) '((1 2))) (test (cdr '(a b c)) '(b c)) (test (cdr '((a) b c d)) '(b c d)) (test (equal? (cdr (reverse (list 1 2 3 4))) 4) #f) (test (equal? (cdr (list 'a 'b 'c 'd 'e 'f 'g)) 'a) #f) (test (cdr '((((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b c) e f) g)) '(g)) (test (cdr '(a)) ()) (test (cdr '(a b c d e f g)) '(b c d e f g)) (test (cdr '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b c) e f g)) '((((u v w) x) y) ((q w e) r) (a b c) e f g)) (test (cdr ''foo) '(foo)) (test (cdr (cons (cons 1 2) (cons 3 4))) '(3 . 4)) (test (cdr '(1 2 . 3)) '(2 . 3)) (test (cdr (if #f #f)) 'error) (test (cdr ()) 'error) (for-each (lambda (arg) (if (not (equal? (cdr (cons () arg)) arg)) (format-logged #t ";(cdr '(() ~A) -> ~A?~%" arg (cdr (cons () arg)))) (test (cdr arg) 'error)) (list "hi" (integer->char 65) #f 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand (log 0) 3.14 3/4 1.0+1.0i #\f #t :hi (if #f #f) (lambda (a) (+ a 1)))) (let* ((a (list 1 2 3)) (b a)) (set! (car a) (cadr a)) (set! (cdr a) (cddr a)) (test a (list 2 3)) (test b a)) (define (cons-r a b n) (if (= 0 n) (cons a b) (cons (cons-r (+ a 1) (+ b 1) (- n 1)) (cons-r (- a 1) (- b 1) (- n 1))))) (define (list-r a b n) (if (= 0 n) (list a b) (list (list-r (+ a 1) (+ b 1) (- n 1)) (list-r (- a 1) (- b 1) (- n 1))))) (define lists (list (list 1 2 3) (cons 1 2) (list 1) (list) (list (list 1 2) (list 3 4)) (list (list 1 2) 3) '(1 . 2) '(a b c) '((a) b (c)) '((1 2) (3 4)) '((1 2 3) (4 5 6) (7 8 9)) '(((1) (2) (3)) ((4) (5) (6)) ((7) (8) (9))) '((((1 123) (2 124) (3 125) (4 126)) ((5) (6) (7) (8)) ((9) (10) (11) (12)) ((13) (14) (15) (16))) (((21 127) (22 128) (23 129) (24 130)) ((25) (26) (27) (28)) ((29) (30) (31) (32)) ((33) (34) (35) (36))) (((41 131) (42 132) (43 133) (44 134)) ((45) (46) (47) (48)) ((49) (50) (51) (52)) ((53) (54) (55) (56))) (((61 135) (62 136) (63 137) (64 138)) ((65) (66) (67) (68)) ((69) (70) (71) (72)) ((73) (74) (75) (76))) 321) (cons 1 (cons 2 (cons 3 4))) (cons (cons 2 (cons 3 4)) 5) (cons () 1) (cons 1 ()) (cons () ()) (list 1 2 (cons 3 4) 5 (list (list 6) 7)) (cons-r 0 0 4) (cons-r 0 0 5) (cons-r 0 0 10) (list-r 0 0 3) (list-r 0 0 7) (list-r 0 0 11) ''a )) ;;; -------------------------------------------------------------------------------- ;;; cxr (define (caar-1 x) (car (car x))) (define (cadr-1 x) (car (cdr x))) (define (cdar-1 x) (cdr (car x))) (define (cddr-1 x) (cdr (cdr x))) (define (caaar-1 x) (car (car (car x)))) (define (caadr-1 x) (car (car (cdr x)))) (define (cadar-1 x) (car (cdr (car x)))) (define (caddr-1 x) (car (cdr (cdr x)))) (define (cdaar-1 x) (cdr (car (car x)))) (define (cdadr-1 x) (cdr (car (cdr x)))) (define (cddar-1 x) (cdr (cdr (car x)))) (define (cdddr-1 x) (cdr (cdr (cdr x)))) (define (caaaar-1 x) (car (car (car (car x))))) (define (caaadr-1 x) (car (car (car (cdr x))))) (define (caadar-1 x) (car (car (cdr (car x))))) (define (caaddr-1 x) (car (car (cdr (cdr x))))) (define (cadaar-1 x) (car (cdr (car (car x))))) (define (cadadr-1 x) (car (cdr (car (cdr x))))) (define (caddar-1 x) (car (cdr (cdr (car x))))) (define (cadddr-1 x) (car (cdr (cdr (cdr x))))) (define (cdaaar-1 x) (cdr (car (car (car x))))) (define (cdaadr-1 x) (cdr (car (car (cdr x))))) (define (cdadar-1 x) (cdr (car (cdr (car x))))) (define (cdaddr-1 x) (cdr (car (cdr (cdr x))))) (define (cddaar-1 x) (cdr (cdr (car (car x))))) (define (cddadr-1 x) (cdr (cdr (car (cdr x))))) (define (cdddar-1 x) (cdr (cdr (cdr (car x))))) (define (cddddr-1 x) (cdr (cdr (cdr (cdr x))))) (for-each (lambda (name op1 op2) (for-each (lambda (lst) (let ((val1 (catch #t (lambda () (op1 lst)) (lambda args 'error))) (val2 (catch #t (lambda () (op2 lst)) (lambda args 'error)))) (if (not (equal? val1 val2)) (format-logged #t ";(~A ~S) -> ~S, (~A-1): ~S?~%" name lst val1 name val2)))) lists)) (list 'caar 'cadr 'cdar 'cddr 'caaar 'caadr 'cadar 'cdaar 'caddr 'cdddr 'cdadr 'cddar 'caaaar 'caaadr 'caadar 'cadaar 'caaddr 'cadddr 'cadadr 'caddar 'cdaaar 'cdaadr 'cdadar 'cddaar 'cdaddr 'cddddr 'cddadr 'cdddar) (list caar cadr cdar cddr caaar caadr cadar cdaar caddr cdddr cdadr cddar caaaar caaadr caadar cadaar caaddr cadddr cadadr caddar cdaaar cdaadr cdadar cddaar cdaddr cddddr cddadr cdddar) (list caar-1 cadr-1 cdar-1 cddr-1 caaar-1 caadr-1 cadar-1 cdaar-1 caddr-1 cdddr-1 cdadr-1 cddar-1 caaaar-1 caaadr-1 caadar-1 cadaar-1 caaddr-1 cadddr-1 cadadr-1 caddar-1 cdaaar-1 cdaadr-1 cdadar-1 cddaar-1 cdaddr-1 cddddr-1 cddadr-1 cdddar-1)) (test (equal? (cadr (list 'a 'b 'c 'd 'e 'f 'g)) 'b) #t) (test (equal? (cddr (list 'a 'b 'c 'd 'e 'f 'g)) '(c d e f g)) #t) (test (equal? (caddr (list 'a 'b 'c 'd 'e 'f 'g)) 'c) #t) (test (equal? (cdddr (list 'a 'b 'c 'd 'e 'f 'g)) '(d e f g)) #t) (test (equal? (cadddr (list 'a 'b 'c 'd 'e 'f 'g)) 'd) #t) (test (equal? (cddddr (list 'a 'b 'c 'd 'e 'f 'g)) '(e f g)) #t) (test (equal? (caadr (list (list (list (list (list 1 2 3) 4) 5) (list 6 7)) (list (list (list 'u 'v 'w) 'x) 'y) (list (list 'q 'w 'e) 'r) (list 'a 'b 'c) 'e 'f 'g)) '((u v w) x)) #t) (test (equal? (cadar (list (list (list (list (list 1 2 3) 4) 5) (list 6 7)) (list (list (list 'u 'v 'w) 'x) 'y) (list (list 'q 'w 'e) 'r) (list 'a 'b 'c) 'e 'f 'g)) '(6 7)) #t) (test (equal? (cdaar (list (list (list (list (list 1 2 3) 4) 5) (list 6 7)) (list (list (list 'u 'v 'w) 'x) 'y) (list (list 'q 'w 'e) 'r) (list 'a 'b 'c) 'e 'f 'g)) '(5)) #t) (test (equal? (cdadr (list (list (list (list (list 1 2 3) 4) 5) (list 6 7)) (list (list (list 'u 'v 'w) 'x) 'y) (list (list 'q 'w 'e) 'r) (list 'a 'b 'c) 'e 'f 'g)) '(y)) #t) (test (equal? (cddar (list (list (list (list (list 1 2 3) 4) 5) (list 6 7)) (list (list (list 'u 'v 'w) 'x) 'y) (list (list 'q 'w 'e) 'r) (list 'a 'b 'c) 'e 'f 'g)) ()) #t) (test (equal? (caaaar (list (list (list (list (list 1 2 3) 4) 5) (list 6 7)) (list (list (list 'u 'v 'w) 'x) 'y) (list (list 'q 'w 'e) 'r) (list 'a 'b 'c) 'e 'f 'g)) '(1 2 3)) #t) (test (equal? (caadar (list (list (list (list (list 1 2 3) 4) 5) (list 6 7)) (list (list (list 'u 'v 'w) 'x) 'y) (list (list 'q 'w 'e) 'r) (list 'a 'b 'c) 'e 'f 'g)) 6) #t) (test (equal? (caaddr (list (list (list (list (list 1 2 3) 4) 5) (list 6 7)) (list (list (list 'u 'v 'w) 'x) 'y) (list (list 'q 'w 'e) 'r) (list 'a 'b 'c) 'e 'f 'g)) '(q w e)) #t) (test (equal? (cadaar (list (list (list (list (list 1 2 3) 4) 5) (list 6 7)) (list (list (list 'u 'v 'w) 'x) 'y) (list (list 'q 'w 'e) 'r) (list 'a 'b 'c) 'e 'f 'g)) 5) #t) (test (equal? (cadadr (list (list (list (list (list 1 2 3) 4) 5) (list 6 7)) (list (list (list 'u 'v 'w) 'x) 'y) (list (list 'q 'w 'e) 'r) (list 'a 'b 'c) 'e 'f 'g)) 'y) #t) (test (equal? (caddar (list (list (list (list (list 1 2 3) 4) 5) 1 6 (list 5 7)) (list (list (list 'u 'v 'w) 'x) 'y) (list (list 'q 'w 'e) 'r) (list 'a 'b 'c) 'e 'f 'g)) 6) #t) (test (equal? (cadddr (list (list (list (list (list 1 2 3) 4) 5) (list 6 7)) (list (list (list 'u 'v 'w) 'x) 'y) (list (list 'q 'w 'e) 'r) (list 'a 'b 'c) 'e 'f 'g)) '(a b c)) #t) (test (equal? (cdaaar (list (list (list (list (list 1 2 3) 4) 5) (list 6 7)) (list (list (list 'u 'v 'w) 'x) 'y) (list (list 'q 'w 'e) 'r) (list 'a 'b 'c) 'e 'f 'g)) '(4)) #t) (test (equal? (cdaadr (list (list (list (list (list 1 2 3) 4) 5) (list 6 7)) (list (list (list 'u 'v 'w) 'x) 'y) (list (list 'q 'w 'e) 'r) (list 'a 'b 'c) 'e 'f 'g)) '(x)) #t) (test (equal? (cdadar (list (list (list (list (list 1 2 3) 4) 5) (list 6 7)) (list (list (list 'u 'v 'w) 'x) 'y) (list (list 'q 'w 'e) 'r) (list 'a 'b 'c) 'e 'f 'g)) '(7)) #t) (test (caar '((a) b c d e f g)) 'a) (test (cadr '(a b c d e f g)) 'b) (test (cdar '((a b) c d e f g)) '(b)) (test (cddr '(a b c d e f g)) '(c d e f g)) (test (caaar '(((a)) b c d e f g)) 'a) (test (caadr '(a (b) c d e f g)) 'b) (test (cadar '((a b) c d e f g)) 'b) (test (caddr '(a b c d e f g)) 'c) (test (cdaar '(((a b)) c d e f g)) '(b)) (test (cdadr '(a (b c) d e f g)) '(c)) (test (cddar '((a b c) d e f g)) '(c)) (test (cdddr '(a b c d e f g)) '(d e f g)) (test (caaaar '((((a))) b c d e f g)) 'a) (test (caaadr '(a ((b)) c d e f g)) 'b) (test (caadar '((a (b)) c d e f g)) 'b) (test (caaddr '(a b (c) d e f g)) 'c) (test (cadaar '(((a b)) c d e f g)) 'b) (test (cadadr '(a (b c) d e f g)) 'c) (test (caddar '((a b c) d e f g)) 'c) (test (cadddr '(a b c d e f g)) 'd) (test (cdaaar '((((a b))) c d e f g)) '(b)) (test (cdaadr '(a ((b c)) d e f g)) '(c)) (test (cdadar '((a (b c)) d e f g)) '(c)) (test (cdaddr '(a b (c d) e f g)) '(d)) (test (cddaar '(((a b c)) d e f g)) '(c)) (test (cddadr '(a (b c d) e f g)) '(d)) (test (cdddar '((a b c d) e f g)) '(d)) (test (cddddr '(a b c d e f g)) '(e f g)) (test (cadr '(1 2 . 3)) 2) (test (cddr '(1 2 . 3)) 3) (test (cadadr '''1) 1) (test (cdadr '''1) '(1)) ;; sacla (test (caar '((a) b c)) 'a) (test (cadr '(a b c)) 'b) (test (cdar '((a . aa) b c)) 'aa) (test (cddr '(a b . c)) 'c) (test (caaar '(((a)) b c)) 'a) (test (caadr '(a (b) c)) 'b) (test (cadar '((a aa) b c)) 'aa) (test (caddr '(a b c)) 'c) (test (cdaar '(((a . aa)) b c)) 'aa) (test (cdadr '(a (b . bb) c)) 'bb) (test (cddar '((a aa . aaa) b c)) 'aaa) (test (cdddr '(a b c . d)) 'd) (test (caaaar '((((a))) b c)) 'a) (test (caaadr '(a ((b)) c)) 'b) (test (caadar '((a (aa)) b c)) 'aa) (test (caaddr '(a b (c))) 'c) (test (cadaar '(((a aa)) b c)) 'aa) (test (cadadr '(a (b bb) c)) 'bb) (test (caddar '((a aa aaa) b c)) 'aaa) (test (cadddr '(a b c d)) 'd) (test (cdaaar '((((a . aa))) b c)) 'aa) (test (cdaadr '(a ((b . bb)) c)) 'bb) (test (cdadar '((a (aa . aaa)) b c)) 'aaa) (test (cdaddr '(a b (c . cc))) 'cc) (test (cddaar '(((a aa . aaa)) b c)) 'aaa) (test (cddadr '(a (b bb . bbb) c)) 'bbb) (test (cdddar '((a aa aaa . aaaa) b c)) 'aaaa) (test (cddddr '(a b c d . e)) 'e) (test (caar '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b c) e f g)) '(((1 2 3) 4) 5)) (test (cadr '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b c) e f g)) '(((u v w) x) y)) (test (cdar '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b c) e f g)) '((6 7))) (test (cddr '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b c) e f g)) '(((q w e) r) (a b c) e f g)) (test (caaar '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b c) e f g)) '((1 2 3) 4)) (test (caadr '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b c) e f g)) '((u v w) x)) (test (cadar '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b c) e f g)) '(6 7)) (test (caddr '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b c) e f g)) '((q w e) r)) (test (cdaar '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b c) e f g)) '(5)) (test (cdadr '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b c) e f g)) '(y)) (test (cddar '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b c) e f g)) ()) (test (cdddr '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b c) e f g)) '((a b c) e f g)) (test (caaaar '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b c) e f g)) '(1 2 3)) (test (caaadr '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b c) e f g)) '(u v w)) (test (caadar '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b c) e f g)) 6) (test (caaddr '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b c) e f g)) '(q w e)) (test (cadaar '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b c) e f g)) 5) (test (cadadr '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b c) e f g)) 'y) (test (cadddr '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b c) e f g)) '(a b c)) (test (cdaaar '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b c) e f g)) '(4)) (test (cdaadr '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b c) e f g)) '(x)) (test (cdadar '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b c) e f g)) '(7)) (test (cdaddr '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b c) e f g)) '(r)) (test (cddaar '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b c) e f g)) ()) (test (cddadr '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b c) e f g)) ()) (test (cddddr '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b c) e f g)) '(e f g)) (test (cadr '(a b c d e f g)) 'b) (test (cddr '(a b c d e f g)) '(c d e f g)) (test (caddr '(a b c d e f g)) 'c) (test (cdddr '(a b c d e f g)) '(d e f g)) (test (cadddr '(a b c d e f g)) 'd) (test (cddddr '(a b c d e f g)) '(e f g)) (test (caar '((((a . b) c . d) (e . f) g . h) ((i . j) k . l) (m . n) o . p)) '((a . b) c . d)) (test (caar '(((a . b) c . d) (e . f) g . h)) '(a . b)) (test (caar '((a . b) c . d)) 'a) (test (cadr '((((a . b) c . d) (e . f) g . h) ((i . j) k . l) (m . n) o . p)) '((i . j) k . l)) (test (cadr '(((a . b) c . d) (e . f) g . h)) '(e . f)) (test (cadr '((a . b) c . d)) 'c) (test (cdar '((((a . b) c . d) (e . f) g . h) ((i . j) k . l) (m . n) o . p)) '((e . f) g . h)) (test (cdar '(((a . b) c . d) (e . f) g . h)) '(c . d)) (test (cdar '((a . b) c . d)) 'b) (test (cddr '((((a . b) c . d) (e . f) g . h) ((i . j) k . l) (m . n) o . p)) '((m . n) o . p)) (test (cddr '(((a . b) c . d) (e . f) g . h)) '(g . h)) (test (cddr '((a . b) c . d)) 'd) (test (caaar '((((a . b) c . d) (e . f) g . h) ((i . j) k . l) (m . n) o . p)) '(a . b)) (test (caaar '(((a . b) c . d) (e . f) g . h)) 'a) (test (caadr '((((a . b) c . d) (e . f) g . h) ((i . j) k . l) (m . n) o . p)) '(i . j)) (test (caadr '(((a . b) c . d) (e . f) g . h)) 'e) (test (cddar '((((a . b) c . d) (e . f) g . h) ((i . j) k . l) (m . n) o . p)) '(g . h)) (test (cddar '(((a . b) c . d) (e . f) g . h)) 'd) (test (cdddr '((((a . b) c . d) (e . f) g . h) ((i . j) k . l) (m . n) o . p)) '(o . p)) (test (cdddr '(((a . b) c . d) (e . f) g . h)) 'h) (test (caaaar '((((a . b) c . d) (e . f) g . h) ((i . j) k . l) (m . n) o . p)) 'a) (test (caaadr '((((a . b) c . d) (e . f) g . h) ((i . j) k . l) (m . n) o . p)) 'i) (test (caddar '((((a . b) c . d) (e . f) g . h) ((i . j) k . l) (m . n) o . p)) 'g) (test (cadddr '((((a . b) c . d) (e . f) g . h) ((i . j) k . l) (m . n) o . p)) 'o) (test (cdaaar '((((a . b) c . d) (e . f) g . h) ((i . j) k . l) (m . n) o . p)) 'b) (test (cdaadr '((((a . b) c . d) (e . f) g . h) ((i . j) k . l) (m . n) o . p)) 'j) (test (cdddar '((((a . b) c . d) (e . f) g . h) ((i . j) k . l) (m . n) o . p)) 'h) (test (cddddr '((((a . b) c . d) (e . f) g . h) ((i . j) k . l) (m . n) o . p)) 'p) (test (cadr ''foo) 'foo) (test (caar '((a) b c)) 'a) (test (cadr '(a b c)) 'b) (test (cdar '((a . aa) b c)) 'aa) (test (cddr '(a b . c)) 'c) (test (caaar '(((a)) b c)) 'a) (test (caadr '(a (b) c)) 'b) (test (cadar '((a aa) b c)) 'aa) (test (caddr '(a b c)) 'c) (test (cdaar '(((a . aa)) b c)) 'aa) (test (cdadr '(a (b . bb) c)) 'bb) (test (cddar '((a aa . aaa) b c)) 'aaa) (test (cdddr '(a b c . d)) 'd) (test (caaaar '((((a))) b c)) 'a) (test (caaadr '(a ((b)) c)) 'b) (test (caadar '((a (aa)) b c)) 'aa) (test (caaddr '(a b (c))) 'c) (test (cadaar '(((a aa)) b c)) 'aa) (test (cadadr '(a (b bb) c)) 'bb) (test (caddar '((a aa aaa) b c)) 'aaa) (test (cadddr '(a b c d)) 'd) (test (cdaaar '((((a . aa))) b c)) 'aa) (test (cdaadr '(a ((b . bb)) c)) 'bb) (test (cdadar '((a (aa . aaa)) b c)) 'aaa) (test (cdaddr '(a b (c . cc))) 'cc) (test (cddaar '(((a aa . aaa)) b c)) 'aaa) (test (cddadr '(a (b bb . bbb) c)) 'bbb) (test (cdddar '((a aa aaa . aaaa) b c)) 'aaaa) (test (cddddr '(a b c d . e)) 'e) (let ((lst '((((A . B) C . D) (E . F) G . H) ((I . J) K . L) (M . N) O . P))) ; from comp.lang.lisp I think (test (car lst) '(((A . B) C . D) (E . F) G . H)) (test (cdr lst) '(((I . J) K . L) (M . N) O . P)) (test (caar lst) '((A . B) C . D)) (test (cadr lst) '((I . J) K . L)) (test (cdar lst) '((E . F) G . H)) (test (cddr lst) '((M . N) O . P)) (test (caaar lst) '(A . B)) (test (caadr lst) '(I . J)) (test (cadar lst) '(E . F)) (test (caddr lst) '(M . N)) (test (cdaar lst) '(C . D)) (test (cdadr lst) '(K . L)) (test (cddar lst) '(G . H)) (test (cdddr lst) '(O . P)) (test (caaaar lst) 'A) (test (caaadr lst) 'I) (test (caadar lst) 'E) (test (caaddr lst) 'M) (test (cadaar lst) 'C) (test (cadadr lst) 'K) (test (caddar lst) 'G) (test (cadddr lst) 'O) (test (cdaaar lst) 'B) (test (cdaadr lst) 'J) (test (cdadar lst) 'F) (test (cdaddr lst) 'N) (test (cddaar lst) 'D) (test (cddadr lst) 'L) (test (cdddar lst) 'H) (test (cddddr lst) 'P)) (test (recompose 10 cdr '(1 2 3 4 5 6 7 8 9 10 11 12)) '(11 12)) (test (recompose 10 car '(((((((((((1 2 3)))))))))))) '(1 2 3)) (test (cons 1 . 2) 'error) (test (eval-string "(1 . 2 . 3)") 'error) (test (car (list)) 'error) (test (car ()) 'error) (test (cdr (list)) 'error) (test (cdr ()) 'error) (test (caddar '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b c) e f g)) 'error) (test (cdddar '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b c) e f g)) 'error) (test (caar '(a b c d e f g)) 'error) (test (cdar '(a b c d e f g)) 'error) (test (caaar '(a b c d e f g)) 'error) (test (caadr '(a b c d e f g)) 'error) (test (cadar '(a b c d e f g)) 'error) (test (cdaar '(a b c d e f g)) 'error) (test (cdadr '(a b c d e f g)) 'error) (test (cddar '(a b c d e f g)) 'error) (test (caaaar '(a b c d e f g)) 'error) (test (caaadr '(a b c d e f g)) 'error) (test (caadar '(a b c d e f g)) 'error) (test (caaddr '(a b c d e f g)) 'error) (test (cadaar '(a b c d e f g)) 'error) (test (cadadr '(a b c d e f g)) 'error) (test (caddar '(a b c d e f g)) 'error) (test (cdaaar '(a b c d e f g)) 'error) (test (cdaadr '(a b c d e f g)) 'error) (test (cdadar '(a b c d e f g)) 'error) (test (cdaddr '(a b c d e f g)) 'error) (test (cddaar '(a b c d e f g)) 'error) (test (cddadr '(a b c d e f g)) 'error) (test (cdddar '(a b c d e f g)) 'error) (test (caar 'a) 'error) (test (caar '(a)) 'error) (test (cadr 'a) 'error) (test (cadr '(a . b)) 'error) (test (cdar 'a) 'error) (test (cdar '(a . b)) 'error) (test (cddr 'a) 'error) (test (cddr '(a . b)) 'error) (test (caaar 'a) 'error) (test (caaar '(a)) 'error) (test (caaar '((a))) 'error) (test (caadr 'a) 'error) (test (caadr '(a . b)) 'error) (test (caadr '(a b)) 'error) (test (cadar 'a) 'error) (test (cadar '(a . b)) 'error) (test (cadar '((a . c) . b)) 'error) (test (caddr 'a) 'error) (test (caddr '(a . b)) 'error) (test (caddr '(a c . b)) 'error) (test (cdaar 'a) 'error) (test (cdaar '(a)) 'error) (test (cdaar '((a . b))) 'error) (test (cdadr 'a) 'error) (test (cdadr '(a . b)) 'error) (test (cdadr '(a b . c)) 'error) (test (cddar 'a) 'error) (test (cddar '(a . b)) 'error) (test (cddar '((a . b) . b)) 'error) (test (cdddr 'a) 'error) (test (cdddr '(a . b)) 'error) (test (cdddr '(a c . b)) 'error) (test (caaaar 'a) 'error) (test (caaaar '(a)) 'error) (test (caaaar '((a))) 'error) (test (caaaar '(((a)))) 'error) (test (caaadr 'a) 'error) (test (caaadr '(a . b)) 'error) (test (caaadr '(a b)) 'error) (test (caaadr '(a (b))) 'error) (test (caadar 'a) 'error) (test (caadar '(a . b)) 'error) (test (caadar '((a . c) . b)) 'error) (test (caadar '((a c) . b)) 'error) (test (caaddr 'a) 'error) (test (caaddr '(a . b)) 'error) (test (caaddr '(a c . b)) 'error) (test (caaddr '(a c b)) 'error) (test (cadaar 'a) 'error) (test (cadaar '(a)) 'error) (test (cadaar '((a . b))) 'error) (test (cadaar '((a b))) 'error) (test (cadadr 'a) 'error) (test (cadadr '(a . b)) 'error) (test (cadadr '(a b . c)) 'error) (test (cadadr '(a (b . e) . c)) 'error) (test (caddar 'a) 'error) (test (caddar '(a . b)) 'error) (test (caddar '((a . b) . b)) 'error) (test (caddar '((a b . c) . b)) 'error) (test (cadddr 'a) 'error) (test (cadddr '(a . b)) 'error) (test (cadddr '(a c . b)) 'error) (test (cadddr '(a c e . b)) 'error) (test (cdaaar 'a) 'error) (test (cdaaar '(a)) 'error) (test (cdaaar '((a))) 'error) (test (cdaaar '(((a . b)))) 'error) (test (cdaadr 'a) 'error) (test (cdaadr '(a . b)) 'error) (test (cdaadr '(a b)) 'error) (test (cdaadr '(a (b . c))) 'error) (test (cdadar 'a) 'error) (test (cdadar '(a . b)) 'error) (test (cdadar '((a . c) . b)) 'error) (test (cdadar '((a c . d) . b)) 'error) (test (cdaddr 'a) 'error) (test (cdaddr '(a . b)) 'error) (test (cdaddr '(a c . b)) 'error) (test (cdaddr '(a c b . d)) 'error) (test (cddaar 'a) 'error) (test (cddaar '(a)) 'error) (test (cddaar '((a . b))) 'error) (test (cddaar '((a b))) 'error) (test (cddadr 'a) 'error) (test (cddadr '(a . b)) 'error) (test (cddadr '(a b . c)) 'error) (test (cddadr '(a (b . e) . c)) 'error) (test (cdddar 'a) 'error) (test (cdddar '(a . b)) 'error) (test (cdddar '((a . b) . b)) 'error) (test (cdddar '((a b . c) . b)) 'error) (test (cddddr 'a) 'error) (test (cddddr '(a . b)) 'error) (test (cddddr '(a c . b)) 'error) (test (cddddr '(a c e . b)) 'error) (test (caar '((1))) 1) (test (cadr '(1 2)) 2) (test (cdar '((1 . 2))) 2) (test (cddr '(1 2 . 3)) 3) (test (caaar '(((1)))) 1) (test (caadr '(1 (2))) 2) (test (cadar '((1 2))) 2) (test (cdaar '(((1 . 2)))) 2) (test (caddr '(1 2 3)) 3) (test (cdddr '(1 2 3 . 4)) 4) (test (cdadr '(1 (2 . 3))) 3) (test (cddar '((1 2 . 3))) 3) (test (caaaar '((((1))))) 1) (test (caaadr '(1 ((2)))) 2) (test (caadar '((1 (2)))) 2) (test (cadaar '(((1 2)))) 2) (test (caaddr '(1 2 (3))) 3) (test (cadddr '(1 2 3 4)) 4) (test (cadadr '(1 (2 3))) 3) (test (caddar '((1 2 3))) 3) (test (cdaaar '((((1 . 2))))) 2) (test (cdaadr '(1 ((2 . 3)))) 3) (test (cdadar '((1 (2 . 3)))) 3) (test (cddaar '(((1 2 . 3)))) 3) (test (cdaddr '(1 2 (3 . 4))) 4) (test (cddddr '(1 2 3 4 . 5)) 5) (test (cddadr '(1 (2 3 . 4))) 4) (test (cdddar '((1 2 3 . 4))) 4) ;;; -------------------------------------------------------------------------------- ;;; length (test (length (list 'a 'b 'c 'd 'e 'f)) 6) (test (length (list 'a 'b 'c 'd)) 4) (test (length (list 'a (list 'b 'c) 'd)) 3) (test (length ()) 0) (test (length '(this-that)) 1) (test (length '(this - that)) 3) (test (length '(a b)) 2) (test (length '(a b c)) 3) (test (length '(a (b) (c d e))) 3) (test (length (list 1 (cons 1 2))) 2) (test (length (list 1 (cons 1 ()))) 2) (for-each (lambda (arg) (test (length arg) #f)) (list (integer->char 65) #f 'a-symbol abs quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #\f #t :hi (if #f #f) (lambda (a) (+ a 1)))) (test (length 'x) #f) (test (length (cons 1 2)) -1) (let ((x (list 1 2))) (set-cdr! x x) (test (infinite? (length x)) #t)) (test (length '(1 2 . 3)) -2) (test (length) 'error) (test (length '(1 2 3) #(1 2 3)) 'error) (test (integer? (length (funclet cons))) #t) (test (length '((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((0))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) 1) (test (length (make-vector 3 0 #t)) 3) ;;; -------------------------------------------------------------------------------- ;;; reverse (test (reverse '(a b c d)) '(d c b a)) (test (reverse '(a b c)) '(c b a)) (test (reverse '(a (b c) d (e (f)))) '((e (f)) d (b c) a)) (test (reverse ()) ()) (test (reverse (list 1 2 3)) '(3 2 1)) (test (reverse (list 1)) '(1)) (test (reverse (list)) (list)) (test (reverse '(1 2 3)) (list 3 2 1)) (test (reverse '(1)) '(1)) (test (reverse '((1 2) 3)) '(3 (1 2))) (test (reverse '(((1 . 2) . 3) 4)) '(4 ((1 . 2) . 3))) (test (reverse (list (list) (list 1 2))) '((1 2) ())) (test (reverse '((a) b c d)) '(d c b (a))) (test (reverse (reverse (list 1 2 3 4))) (list 1 2 3 4)) (test (reverse ''foo) '(foo quote)) (test (let ((x (list 1 2 3 4))) (let ((y (reverse x))) (and (equal? x (list 1 2 3 4)) (equal? y (list 4 3 2 1))))) #t) (test (letrec ((hi (lambda (lst n) (if (= n 0) lst (hi (reverse lst) (- n 1)))))) (hi (list 1 2 3) 100)) (list 1 2 3)) (test (let ((var (list 1 2 3))) (reverse (cdr var)) var) (list 1 2 3)) (test (let ((var '(1 2 3))) (reverse (cdr var)) var) '(1 2 3)) (test (let ((var (list 1 (list 2 3)))) (reverse (cdr var)) var) (list 1 (list 2 3))) (test (let ((var '(1 (2 3)))) (reverse (cdr var)) var) '(1 (2 3))) (test (let ((var (list (list 1 2) (list 3 4 5)))) (reverse (car var)) var) '((1 2) (3 4 5))) (test (let ((x '(1 2 3))) (list (reverse x) x)) '((3 2 1) (1 2 3))) (test (reverse '(1 2)) '(2 1)) (test (reverse '(1 2 3)) '(3 2 1)) (test (reverse '(1 2 3 4)) '(4 3 2 1)) (when with-block (test (block? (reverse _c_obj_)) #t) (let ((b (block 1 2 3 4))) (let ((b1 (reverse b))) (test b1 (block 4 3 2 1)) (test b (block 1 2 3 4))))) (for-each (lambda (lst) (if (proper-list? lst) (if (not (equal? lst (reverse (reverse lst)))) (format-logged #t ";(reverse (reverse ~A)) -> ~A?~%" lst (reverse (reverse lst)))))) lists) (for-each (lambda (lst) (if (proper-list? lst) (if (not (equal? lst (reverse (reverse (reverse (reverse lst)))))) (format-logged #t ";(reverse...(4x) ~A) -> ~A?~%" lst (reverse (reverse (reverse (reverse lst)))))))) lists) (test (let ((x (list 1 2 3))) (list (recompose 32 reverse x) x)) '((1 2 3) (1 2 3))) (test (let ((x (list 1 2 3))) (list (recompose 31 reverse x) x)) '((3 2 1) (1 2 3))) (test (reverse (cons 1 2)) '(2 . 1)) (test (reverse '(1 . 2)) '(2 . 1)) (test (reverse '(1 2 . 3)) '(3 2 1)) (test (reverse) 'error) (test (reverse '(1 2 3) '(3 2 1)) 'error) (test (reverse (make-shared-vector (make-int-vector '(2 3) 0) '(6))) (make-vector 6 0 #t)) (test (reverse (make-vector 6 0.0 #t)) (make-float-vector 6 0.0)) (for-each (lambda (arg) (test (reverse arg) 'error)) (list (integer->char 65) #f 'a-symbol abs quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #\f #t :hi (if #f #f) (lambda (a) (+ a 1)))) (test (reverse "hi") "ih") (test (reverse "") "") (test (reverse "123") "321") (test (reverse "1234") "4321") (test (reverse "12") "21") (test (reverse "a\x00b") "b\x00a") (test (reverse #()) #()) (test (reverse #(1)) #(1)) (test (reverse #(1 2)) #(2 1)) (test (reverse #(1 2 3)) #(3 2 1)) (test (reverse #(1 2 3 4)) #(4 3 2 1)) (test (reverse #2D((1 2) (3 4))) #2D((4 3) (2 1))) (test (reverse (string #\a #\null #\b)) "b\x00a") (test (reverse abs) 'error) (test (vector->list (reverse (let ((v (make-int-vector 3))) (set! (v 1) 1) (set! (v 2) 2) v))) '(2 1 0)) (test (reverse (int-vector)) #()) (test (reverse (int-vector 1)) (int-vector 1)) (test (reverse (int-vector 1 2)) (int-vector 2 1)) (test (reverse (int-vector 1 2 3)) (int-vector 3 2 1)) (test (reverse (int-vector 1 2 3 4)) (int-vector 4 3 2 1)) (test (reverse (float-vector)) #()) (test (reverse (float-vector 1)) (float-vector 1)) (test (reverse (float-vector 1 2)) (float-vector 2 1)) (test (reverse (float-vector 1 2 3)) (float-vector 3 2 1)) (test (reverse (float-vector 1 2 3 4)) (float-vector 4 3 2 1)) (test (let ((v #(1 2 3))) (reverse v) v) #(1 2 3)) (test (reverse #u8(1 2 3)) #u8(3 2 1)) (test (reverse #u8(1 2)) #u8(2 1)) (test (reverse #u8(1 2 3 4)) #u8(4 3 2 1)) (when with-block (let ((b (block 1.0 2.0 3.0))) (set! (b 1) 32.0) (test (b 1) 32.0) (let ((b1 (reverse b))) (test b1 (block 3.0 32.0 1.0))))) ;;; -------------------------------------------------------------------------------- ;;; reverse! (test (reverse! '(1 . 2)) 'error) (test (reverse! (cons 1 2)) 'error) (test (reverse! (cons 1 (cons 2 3))) 'error) (test (reverse!) 'error) (test (reverse! '(1 2 3) '(3 2 1)) 'error) (test (reverse! '(a b c d)) '(d c b a)) (test (reverse! '(a b c)) '(c b a)) (test (reverse! '(a (b c) d (e (f)))) '((e (f)) d (b c) a)) (test (reverse! ()) ()) (test (reverse! (list 1 2 3)) '(3 2 1)) (test (reverse! (list 1)) '(1)) (test (reverse! (list)) (list)) (test (reverse! '(1 2 3)) (list 3 2 1)) (test (reverse! '(1)) '(1)) (test (reverse! '((1 2) 3)) '(3 (1 2))) (test (reverse! '(((1 . 2) . 3) 4)) '(4 ((1 . 2) . 3))) (test (reverse! (list (list) (list 1 2))) '((1 2) ())) (test (reverse! '((a) b c d)) '(d c b (a))) (test (reverse! (reverse! (list 1 2 3 4))) (list 1 2 3 4)) (test (reverse! (reverse! (sort! (list 1 2 3 4) >))) (sort! (list 1 2 3 4) >)) (test (reverse! ''foo) '(foo quote)) (test (reverse (reverse! (list 1 2 3))) (list 1 2 3)) (test (reverse (reverse! (reverse! (reverse (list 1 2 3))))) (list 1 2 3)) (test (let ((x (list 1 2 3))) (recompose 31 reverse! x)) '(3 2 1)) (test (reverse! '(1 2 . 3)) 'error) (let* ((lst1 (list 1 2 3)) (lst2 (apply list '(4 5 6))) (lst3 (sort! (reverse! (append lst1 lst2)) <))) (test lst3 '(1 2 3 4 5 6)) (define (lt . args) args) (set! lst3 (sort! (apply reverse! (lt lst3)) >)) (test lst3 '(6 5 4 3 2 1))) (for-each (lambda (arg) (test (reverse! arg) 'error)) (list (integer->char 65) #f 'a-symbol abs _ht_ _null_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #\f #t (if #f #f) (lambda (a) (+ a 1)))) (test (let ((str "1234")) (reverse! str) str) "4321") (test (let ((str "123")) (reverse! str) str) "321") (test (let ((str "")) (reverse! str) str) "") (test (let ((v #(1 2 3))) (reverse! v) v) #(3 2 1)) (test (let ((v #(1 2 3 4))) (reverse! v) v) #(4 3 2 1)) (test (let ((v #())) (reverse! v) v) #()) (test (let ((v (float-vector 1.0 2.0 3.0))) (reverse! v) v) (float-vector 3.0 2.0 1.0)) (test (let ((v (float-vector 1.0 2.0 3.0 4.0))) (reverse! v) v) (float-vector 4.0 3.0 2.0 1.0)) (test (let ((v (float-vector))) (reverse! v) v) #()) (test (let ((v (int-vector 1 2 3))) (reverse! v) v) (int-vector 3 2 1)) (test (let ((v (int-vector 1 2 3 4))) (reverse! v) v) (int-vector 4 3 2 1)) (test (let ((v (int-vector))) (reverse! v) v) #()) (when with-block (test (block? (reverse! _c_obj_)) #t) (let ((b (block 1 2 3 4))) (reverse! b) (test b (block 4 3 2 1)))) (test (let ((v (make-vector 3 1 #t))) (set! (v 1) 2) (set! (v 2) 3) (reverse! v) v) (let ((v (make-vector 3 3 #t))) (set! (v 1) 2) (set! (v 2) 1) v)) (when full-test (let () ;; some sequence tests (define (fv-tst len) (let ((fv (make-float-vector len))) (if (not (= (length fv) len)) (format *stderr* "float-vector length ~A: ~A~%" fv (length fv))) (fill! fv 0.0) (let ((fv-orig (copy fv))) (do ((i 0 (+ i 1))) ((= i len)) (set! (fv i) (- (random 1000.0) 500.0))) (let ((fv-ran (copy fv)) (fv-ran1 (copy fv))) (sort! fv <) (call-with-exit (lambda (quit) (do ((i 1 (+ i 1))) ((= i len)) (when (> (fv (- i 1)) (fv i)) (format *stderr* "float-vector: ~A > ~A at ~D~%" (fv (- i 1)) (fv i) i) (quit))))) (sort! fv-ran (lambda (a b) (< a b))) (if (not (morally-equal? fv fv-ran)) (format *stderr* "float-vector closure not equal~%")) (sort! fv-ran1 (lambda (a b) (cond ((< a b) #t) (#t #f)))) (if (not (morally-equal? fv fv-ran1)) (format *stderr* "float-vector cond closure not equal~%"))) (let ((fv-copy (copy fv))) (reverse! fv) (if (and (not (morally-equal? fv-copy fv)) (morally-equal? fv fv-orig)) (format *stderr* "float-vector reverse!: ~A ~A~%" fv fv-orig)) (reverse! fv) (if (not (morally-equal? fv-copy fv)) (format *stderr* "float-vector reverse! twice: ~A ~A~%" fv fv-copy)) (let ((fv1 (apply float-vector (make-list len 1.0)))) (if (or (not (= (length fv1) len)) (not (= (fv1 (- len 1)) 1.0))) (format *stderr* "float-vector apply: ~A ~A~%" len (fv (- len 1))))) )))) (define (iv-tst len) (let ((fv (make-int-vector len 0))) (if (not (= (length fv) len)) (format *stderr* "int-vector length ~A: ~A~%" fv (length fv))) (fill! fv 0) (let ((fv-orig (copy fv))) (do ((i 0 (+ i 1))) ((= i len)) (set! (fv i) (- (random 1000000) 500000))) (let ((fv-ran (copy fv)) (fv-ran1 (copy fv))) (sort! fv <) (call-with-exit (lambda (quit) (do ((i 1 (+ i 1))) ((= i len)) (when (> (fv (- i 1)) (fv i)) (format *stderr* "int-vector: ~A > ~A at ~D~%" (fv (- i 1)) (fv i) i) (quit))))) (sort! fv-ran (lambda (a b) (< a b))) (if (not (morally-equal? fv fv-ran)) (format *stderr* "int-vector closure not equal~%")) (sort! fv-ran1 (lambda (a b) (cond ((< a b) #t) (#t #f)))) (if (not (morally-equal? fv fv-ran1)) (format *stderr* "int-vector cond closure not equal~%"))) (let ((fv-copy (copy fv))) (reverse! fv) (if (and (not (morally-equal? fv-copy fv)) (morally-equal? fv fv-orig)) (format *stderr* "int-vector reverse!: ~A ~A~%" fv fv-orig)) (reverse! fv) (if (not (morally-equal? fv-copy fv)) (format *stderr* "int-vector reverse! twice: ~A ~A~%" fv fv-copy)) )))) (define (v-tst len) (let ((fv (make-vector len))) (if (not (= (length fv) len)) (format *stderr* "vector length ~A: ~A~%" fv (length fv))) (fill! fv 0) (let ((fv-orig (copy fv))) (do ((i 0 (+ i 1))) ((= i len)) (set! (fv i) (- (random 1000000) 500000))) (let ((fv-ran (copy fv)) (fv-ran1 (copy fv))) (sort! fv <) (call-with-exit (lambda (quit) (do ((i 1 (+ i 1))) ((= i len)) (when (> (fv (- i 1)) (fv i)) (format *stderr* "vector: ~A > ~A at ~D~%" (fv (- i 1)) (fv i) i) (quit))))) (sort! fv-ran (lambda (a b) (< a b))) (if (not (morally-equal? fv fv-ran)) (format *stderr* "vector closure not equal~%")) (sort! fv-ran1 (lambda (a b) (cond ((< a b) #t) (#t #f)))) (if (not (morally-equal? fv fv-ran1)) (format *stderr* "vector cond closure not equal~%"))) (let ((fv-copy (copy fv))) (reverse! fv) (if (and (not (morally-equal? fv-copy fv)) (morally-equal? fv fv-orig)) (format *stderr* "vector reverse!: ~A ~A~%" fv fv-orig)) (reverse! fv) (if (not (morally-equal? fv-copy fv)) (format *stderr* "vector reverse! twice: ~A ~A~%" fv fv-copy)) (let ((fv1 (apply vector (make-list len 1)))) (if (or (not (= (length fv1) len)) (not (= (fv1 (- len 1)) 1))) (format *stderr* "vector apply: ~A ~A~%" len (fv (- len 1))))) )))) (define (s-tst len) (let ((fv (make-string len))) (if (not (= (length fv) len)) (format *stderr* "string length ~A: ~A~%" fv (length fv))) (fill! fv #\a) (let ((fv-orig (copy fv))) (do ((i 0 (+ i 1))) ((= i len)) (set! (fv i) (integer->char (+ 20 (random 100))))) (let ((fv-ran (copy fv)) (fv-ran1 (copy fv))) (sort! fv char? (fv (- i 1)) (fv i)) (format *stderr* "string: ~A > ~A at ~D~%" (fv (- i 1)) (fv i) i) (quit))))) (sort! fv-ran (lambda (a b) (char (car p0) (car p1)) (format *stderr* "list: ~A > ~A at ~D~%" (car p0) (car p1) i) (quit))))) (sort! fv-ran (lambda (a b) (< a b))) (if (not (morally-equal? fv fv-ran)) (format *stderr* "pair closure not equal~%"))) (let ((fv-copy (copy fv))) (set! fv (reverse! fv)) (if (and (not (morally-equal? fv-copy fv)) (morally-equal? fv fv-orig)) (format *stderr* "list reverse!: ~A ~A~%" fv fv-orig)) (set! fv (reverse! fv)) (if (not (morally-equal? fv-copy fv)) (format *stderr* "list reverse! twice: ~A ~A~%" fv fv-copy)) )))) (for-each (lambda (b p) (do ((k 0 (+ k 1))) ((= k 1000)) (fv-tst b) (iv-tst b) (v-tst b) (s-tst b) (p-tst b)) (do ((i 0 (+ i 1))) ((= i p)) (format *stderr* "~D fv " (expt b i)) (fv-tst (expt b i)) (format *stderr* "iv ") (iv-tst (expt b i)) (format *stderr* "v ") (v-tst (expt b i)) (format *stderr* "s ") (s-tst (expt b i)) (format *stderr* "p ") (p-tst (expt b i)) (newline *stderr*) )) (list 2 3 4 7 10) (list 12 4 3 6 6)) )) (test (let ((v (vector 1 2 3 4))) (let ((sv (make-shared-vector v 3))) (reverse! sv) v)) #(3 2 1 4)) (test (let ((v (vector 1 2 3 4))) (let ((sv (make-shared-vector v 3 1))) (reverse! sv) v)) #(1 4 3 2)) (test (let ((v (vector 1 2 3 4))) (let ((sv (make-shared-vector v 3 1))) (fill! sv 5) v)) #(1 5 5 5)) (test (let ((v (vector 1 2 3 4))) (let ((sv (make-shared-vector v 3 1))) (reverse sv) v)) #(1 2 3 4)) (test (let ((v (vector 1 2 3 4))) (let ((sv (make-shared-vector v 3 1))) (sort! sv >) v)) #(1 4 3 2)) (test (let ((v (make-int-vector '(3 3) 1))) (let ((sv (v 1))) (fill! sv 2) v)) (make-shared-vector (int-vector 1 1 1 2 2 2 1 1 1) '(3 3))) (test (let ((v (make-int-vector '(3 3) 1))) (do ((i 0 (+ i 1))) ((= i 3)) (do ((j 0 (+ j 1))) ((= j 3)) (set! (v i j) (+ j (* i 3))))) (let ((sv (v 1))) (fill! sv 2) v)) (make-shared-vector (int-vector 0 1 2 2 2 2 6 7 8) '(3 3))) (test (let ((v (make-int-vector '(3 3) 1))) (do ((i 0 (+ i 1))) ((= i 3)) (do ((j 0 (+ j 1))) ((= j 3)) (set! (v i j) (+ j (* i 3))))) (let ((sv (v 1))) (sort! sv >) v)) (make-shared-vector (int-vector 0 1 2 5 4 3 6 7 8) '(3 3))) (test (let ((v (make-int-vector '(3 3) 1))) (do ((i 0 (+ i 1))) ((= i 3)) (do ((j 0 (+ j 1))) ((= j 3)) (set! (v i j) (+ j (* i 3))))) (let ((sv (v 1))) (reverse! sv) v)) (make-shared-vector (int-vector 0 1 2 5 4 3 6 7 8) '(3 3))) ;;; -------------------------------------------------------------------------------- ;;; pair? (test (pair? 'a) #f) (test (pair? '()) #f) (test (pair? ()) #f) (test (pair? '(a b c)) #t) (test (pair? (cons 1 2)) #t) (test (pair? ''()) #t) (test (pair? #f) #f) (test (pair? (make-vector 6)) #f) (test (pair? #t) #f) (test (pair? '(a . b)) #t) (test (pair? #(a b)) #f) (test (pair? (list 1 2)) #t) (test (pair? (list)) #f) (test (pair? ''foo) #t) (test (pair? (list 'a 'b 'c 'd 'e 'f)) #t) (test (pair? '(this-that)) #t) (test (pair? '(this - that)) #t) (let ((x (list 1 2))) (set-cdr! x x) (test (pair? x) #t)) (test (pair? (list 1 (cons 1 2))) #t) (test (pair? (list 1 (cons 1 ()))) #t) (test (pair? (cons 1 ())) #t) (test (pair? (cons () ())) #t) (test (pair? (cons () 1)) #t) (test (pair? (list (list))) #t) (test (pair? '(())) #t) (test (pair? (cons 1 (cons 2 3))) #t) (test (pair?) 'error) (test (pair? `'1) #t) (test (pair? begin) #f) (test (pair? 'begin) #f) (test (pair? ''begin) #t) (test (pair? list) #f) (for-each (lambda (arg) (if (pair? arg) (format-logged #t ";(pair? ~A) -> #t?~%" arg))) (list "hi" (integer->char 65) #f 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #\f #t :hi (if #f #f) (lambda (a) (+ a 1)))) ;;; pair-line-number (test (pair-line-number) 'error) (test (pair-line-number () ()) 'error) (for-each (lambda (arg) (test (pair-line-number arg) 'error)) (list "hi" (integer->char 65) #f 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #\f #t :hi (if #f #f) (lambda (a) (+ a 1)))) ;;; -------------------------------------------------------------------------------- ;;; list? (test (list? 'a) #f) (test (list? ()) #t) (test (list? '(a b c)) #t) (test (list? (cons 1 2)) #t) (test (list? ''()) #t) (test (list? #f) #f) (test (list? (make-vector 6)) #f) (test (list? #t) #f) (test (list? '(a . b)) #t) (test (list? #(a b)) #f) (test (list? (list 1 2)) #t) (test (list? (list)) #t) (test (list? ''foo) #t) (test (list? ''2) #t) (test (list? (list 'a 'b 'c 'd 'e 'f)) #t) (test (list? '(this-that)) #t) (test (list? '(this - that)) #t) (let ((x (list 1 2))) (set-cdr! x x) (test (proper-list? x) #f) (test (list? x) #t)) (test (list? (list 1 (cons 1 2))) #t) (test (list? (list 1 (cons 1 ()))) #t) (test (list? (cons 1 ())) #t) (test (list? (cons () ())) #t) (test (list? (cons () 1)) #t) (test (list? (list (list))) #t) (test (list? '(())) #t) (test (list? '(1 2 . 3)) #t) (test (list? (cons 1 (cons 2 3))) #t) (test (list? '(1 . ())) #t) (test (list? '(1 2) ()) 'error) (test (list?) 'error) (for-each (lambda (arg) (if (list? arg) (format-logged #t ";(list? ~A) -> #t?~%" arg))) (list "hi" (integer->char 65) #f 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #\f #t :hi (if #f #f) (lambda (a) (+ a 1)))) ;;; proper-list? (test (proper-list? 'a) #f) (test (proper-list? ()) #t) (test (proper-list? '(a b c)) #t) (test (proper-list? (cons 1 2)) #f) (test (proper-list? ''()) #t) (test (proper-list? #f) #f) (test (proper-list? (make-vector 6)) #f) (test (proper-list? #t) #f) (test (proper-list? '(a . b)) #f) (test (proper-list? #(a b)) #f) (test (proper-list? (list 1 2)) #t) (test (proper-list? (list)) #t) (test (proper-list? ''foo) #t) (test (proper-list? ''2) #t) (test (proper-list? (list 'a 'b 'c 'd 'e 'f)) #t) (test (proper-list? '(this-that)) #t) (test (proper-list? '(this - that)) #t) (let ((x (list 1 2))) (set-cdr! x x) (test (proper-list? x) #f)) (test (proper-list? (list 1 (cons 1 2))) #t) (test (proper-list? (list 1 (cons 1 ()))) #t) (test (proper-list? (cons 1 ())) #t) (test (proper-list? (cons () ())) #t) (test (proper-list? (cons () 1)) #f) (test (proper-list? (list (list))) #t) (test (proper-list? '(())) #t) (test (proper-list? '(1 2 . 3)) #f) (test (proper-list? (cons 1 (cons 2 3))) #f) (test (proper-list? '(1 . ())) #t) (test (proper-list? '(1 2) ()) 'error) (test (proper-list?) 'error) (for-each (lambda (arg) (if (proper-list? arg) (format-logged #t ";(list? ~A) -> #t?~%" arg))) (list "hi" (integer->char 65) #f 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #\f #t :hi (if #f #f) (lambda (a) (+ a 1)))) ;;; -------------------------------------------------------------------------------- ;;; null? (test (null? 'a) '#f) (test (null? ()) #t) (test (null? ()) #t) (test (null? '(a b c)) #f) (test (null? (cons 1 2)) #f) (test (null? ''()) #f) (test (null? #f) #f) (test (null? (make-vector 6)) #f) (test (null? #t) #f) (test (null? '(a . b)) #f) (test (null? #(a b)) #f) (test (null? (list 1 2)) #f) (test (null? (list)) #t) (test (null? ''foo) #f) (test (null? (list 'a 'b 'c 'd 'e 'f)) #f) (test (null? '(this-that)) #f) (test (null? '(this - that)) #f) (let ((x (list 1 2))) (set-cdr! x x) (test (null? x) #f)) (test (null? (list 1 (cons 1 2))) #f) (test (null? (list 1 (cons 1 ()))) #f) (test (null? (cons 1 ())) #f) (test (null? (cons () ())) #f) (test (null? (cons () 1)) #f) (test (null? (list (list))) #f) (test (null? '(())) #f) (test (null? #()) #f) (test (null? (make-vector '(2 0 3))) #f) (test (null? "") #f) (test (null? lambda) #f) (test (null? cons) #f) (test (null? (begin)) #t) (test (null? (cdr (list 1))) #t) (test (null? (cdr (cons () '(())))) #f) (test (null? () ()) 'error) (test (null?) 'error) (for-each (lambda (arg) (if (null? arg) (format-logged #t ";(null? ~A) -> #t?~%" arg))) (list "hi" (integer->char 65) #f 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #\f #t (if #f #f) :hi # # (values) (lambda (a) (+ a 1)))) ;;; -------------------------------------------------------------------------------- ;;; set-car! (test (let ((x (cons 1 2))) (set-car! x 3) x) (cons 3 2)) (test (let ((x (list 1 2))) (set-car! x 3) x) (list 3 2)) (test (let ((x (list (list 1 2) 3))) (set-car! x 22) x) (list 22 3)) (test (let ((x (cons 1 2))) (set-car! x ()) x) (cons () 2)) (test (let ((x (list 1 (list 2 3 4)))) (set-car! x (list 5 (list 6))) x) (list (list 5 (list 6)) (list 2 3 4))) (test (let ((x '(((1) 2) (3)))) (set-car! x '((2) 1)) x) '(((2) 1) (3))) (test (let ((x ''foo)) (set-car! x "hi") x) (list "hi" 'foo)) (test (let ((x '((1 . 2) . 3))) (set-car! x 4) x) '(4 . 3)) (test (let ((x '(1 . 2))) (set-car! x (cdr x)) x) '(2 . 2)) (test (let ((x '(1 . 2))) (set-car! x x) (proper-list? x)) #f) (test (let ((x (list 1))) (set-car! x ()) x) '(())) (test (let ((x '(((1 2) . 3) 4))) (set-car! x 1) x) '(1 4)) (test (let ((lst (cons 1 (cons 2 3)))) (set-car! (cdr lst) 4) lst) (cons 1 (cons 4 3))) (test (let ((lst (cons 1 (cons 2 3)))) (set-car! lst 4) lst) (cons 4 (cons 2 3))) (test (let ((x (list 1 2))) (set! (car x) 0) x) (list 0 2)) (test (let ((x (cons 1 2))) (set! (cdr x) 0) x) (cons 1 0)) (test (let ((x (list 1 2))) (set-car! x (list 3 4)) x) '((3 4) 2)) (test (let ((x (cons 1 2))) (set-car! x (list 3 4)) x) '((3 4) . 2)) (test (let ((x (cons (list 1 2) 3))) (set-car! (car x) (list 3 4)) x) '(((3 4) 2) . 3)) (test (let ((lst (list 1 2 3))) (set! (car lst) 32) lst) '(32 2 3)) (test (set-car! '() 32) 'error) (test (set-car! () 32) 'error) (test (set-car! (list) 32) 'error) (test (set-car! 'x 32) 'error) (test (set-car! #f 32) 'error) (test (set-car!) 'error) (test (set-car! '(1 2) 1 2) 'error) (test (let ((lst (list 1 2))) (set-car! lst (values 2 3)) lst) 'error) (test (let ((lst '(1 2))) (set-car! lst 32)) 32) (test (let ((lst '(1 2))) (set! (car lst) 32)) 32) (test (let ((c (cons 1 2))) (set-car! c #\a) (car c)) #\a) (test (let ((c (cons 1 2))) (set-car! c #()) (car c)) #()) (test (let ((c (cons 1 2))) (set-car! c #f) (car c)) #f) (test (let ((c (cons 1 2))) (set-car! c _ht_) (car c)) _ht_) ;;; -------------------------------------------------------------------------------- ;;; set-cdr! (test (let ((x (cons 1 2))) (set-cdr! x 3) x) (cons 1 3)) (test (let ((x (list 1 2))) (set-cdr! x 3) x) (cons 1 3)) (test (let ((x (list (list 1 2) 3))) (set-cdr! x 22) x) '((1 2) . 22)) (test (let ((x (cons 1 2))) (set-cdr! x '()) x) (list 1)) (test (let ((x (list 1 (list 2 3 4)))) (set-cdr! x (list 5 (list 6))) x) '(1 5 (6))) (test (let ((x '(((1) 2) (3)))) (set-cdr! x '((2) 1)) x) '(((1) 2) (2) 1)) (test (let ((x ''foo)) (set-cdr! x "hi") x) (cons 'quote "hi")) (test (let ((x '((1 . 2) . 3))) (set-cdr! x 4) x) '((1 . 2) . 4)) (test (let ((x '(1 . 2))) (set-cdr! x (cdr x)) x) '(1 . 2)) (test (let ((x '(1 . 2))) (set-cdr! x x) (proper-list? x)) #f) (test (let ((x (list 1))) (set-cdr! x '()) x) (list 1)) (test (let ((x '(1 . (2 . (3 (4 5)))))) (set-cdr! x 4) x) '(1 . 4)) (test (let ((lst (cons 1 (cons 2 3)))) (set-cdr! (cdr lst) 4) lst) (cons 1 (cons 2 4))) (test (let ((x (cons (list 1 2) 3))) (set-cdr! (car x) (list 3 4)) x) '((1 3 4) . 3)) (test (let ((x (list 1 2))) (set-cdr! x (list 4 5)) x) '(1 4 5)) (test (let ((x (cons 1 2))) (set-cdr! x (list 4 5)) x) '(1 4 5)) ;! (test (let ((x (cons 1 2))) (set-cdr! x (cons 4 5)) x) '(1 4 . 5)) (test (let ((lst (list 1 2 3))) (set! (cdr lst) 32) lst) (cons 1 32)) (test (set-cdr! '() 32) 'error) (test (set-cdr! () 32) 'error) (test (set-cdr! (list) 32) 'error) (test (set-cdr! 'x 32) 'error) (test (set-cdr! #f 32) 'error) (test (set-cdr!) 'error) (test (set-cdr! '(1 2) 1 2) 'error) (test (let ((lst '(1 2))) (set-cdr! lst 32)) 32) (test (let ((lst '(1 2))) (set! (cdr lst) 32)) 32) (test (let ((c (cons 1 2))) (set-cdr! c #\a) (cdr c)) #\a) (test (let ((c (cons 1 2))) (set-cdr! c #()) (cdr c)) #()) (test (let ((c (cons 1 2))) (set-cdr! c #f) (cdr c)) #f) (test (let ((c (cons 1 2))) (set-cdr! c _ht_) (cdr c)) _ht_) (test (let ((c (cons 1 2))) (set-cdr! c (list 3)) c) '(1 3)) ;;; -------------------------------------------------------------------------------- ;;; list-ref (test (list-ref (list 1 2) 1) 2) (test (list-ref '(a b c d) 2) 'c) (test (list-ref (cons 1 2) 0) 1) ; !! (test (list-ref ''foo 0) 'quote) (test (list-ref '((1 2) (3 4)) 1) '(3 4)) (test (list-ref (list-ref (list (list 1 2) (list 3 4)) 1) 1) 4) (test (let ((x (list 1 2 3))) (list-ref x (list-ref x 1))) 3) (test (list-ref '(1 2 . 3) 1) 2) (test (list-ref '(1 2 . 3) 2) 'error) ; hmm... (test ('(1 2 . 3) 0) 1) (test ('(1 . 2) 0) 1) (test (let ((lst (list 1 2))) (set! (list-ref lst 1) 0) lst) (list 1 0)) (test (((lambda () list)) 'a 'b 'c) '(a b c)) (test (apply ((lambda () list)) (list 'a 'b 'c) (list 'c 'd 'e)) '((a b c) c d e)) (test (((lambda () (values list))) 1 2 3) '(1 2 3)) (test (apply list 'a 'b '(c)) '(a b c)) (for-each (lambda (name op1 op2) (for-each (lambda (lst) (let ((val1 (catch #t (lambda () (op1 lst)) (lambda args 'error))) (val2 (catch #t (lambda () (op2 lst)) (lambda args 'error)))) (if (not (equal? val1 val2)) (format-logged #t ";(~A ~A) -> ~A ~A?~%" name lst val1 val2)))) lists)) (list 'list-ref:0 'list-ref:1 'list-ref:2 'list-ref:3) (list car cadr caddr cadddr) (list (lambda (l) (list-ref l 0)) (lambda (l) (list-ref l 1)) (lambda (l) (list-ref l 2)) (lambda (l) (list-ref l 3)))) (for-each (lambda (arg) (test (list-ref (list 1 arg) 1) arg)) (list "hi" (integer->char 65) #f 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand (log 0) 3.14 3/4 1.0+1.0i #\f #t :hi (if #f #f) (lambda (a) (+ a 1)))) (test (let ((x '(1 . 2))) (set-cdr! x x) (list-ref x 0)) 1) (test (let ((x '(1 . 2))) (set-cdr! x x) (list-ref x 1)) 1) (test (let ((x '(1 . 2))) (set-cdr! x x) (list-ref x 100)) 1) (test (list-ref '((1 2 3) (4 5 6)) 1) '(4 5 6)) (test (list-ref '((1 2 3) (4 5 6)) 1 2) 6) (test (list-ref '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))) 1) '((7 8 9) (10 11 12))) (test (list-ref '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))) 1 0) '(7 8 9)) (test (list-ref '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))) 1 0 2) 9) (test (list-ref '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))) 1 0 3) 'error) (test (list-ref '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))) 1 0 2 0) 'error) (test ('((1 2 3) (4 5 6)) 1) '(4 5 6)) (test ('((1 2 3) (4 5 6)) 1 2) 6) (test ('(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))) 1) '((7 8 9) (10 11 12))) (test ('(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))) 1 0) '(7 8 9)) (test ('(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))) 1 0 2) 9) (test ('(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))) 1 0 3) 'error) (test ('(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))) 1 0 2 0) 'error) (test (let ((L '((1 2 3) (4 5 6)))) (L 1)) '(4 5 6)) (test (let ((L '((1 2 3) (4 5 6)))) (L 1 2)) 6) (test (let ((L '((1 2 3) (4 5 6)))) (L 1 2 3)) 'error) (test (let ((L '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) (L 1)) '((7 8 9) (10 11 12))) (test (let ((L '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) (L 1 0)) '(7 8 9)) (test (let ((L '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) (L 1 0 2)) 9) (test (let ((L '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) (L 1 0 2 3)) 'error) (test (let ((L '((1 2 3) (4 5 6)))) ((L 1) 2)) 6) (test (let ((L '((1 2 3) (4 5 6)))) (((L 1) 2) 3)) 'error) (test (let ((L '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) ((L 1) 0)) '(7 8 9)) (test (let ((L '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) (((L 1) 0) 2)) 9) (test (let ((L '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) ((L 1 0) 2)) 9) (test (let ((L '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) ((L 1) 0 2)) 9) (test (let ((L '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) ((((L 1) 0) 2) 3)) 'error) (test (let ((L '((1 2 3) (4 5 6)))) (list-ref (L 1) 2)) 6) (test (let ((L '((1 2 3) (4 5 6)))) (list-ref ((L 1) 2) 3)) 'error) (test (let ((L '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) (list-ref (L 1) 0)) '(7 8 9)) (test (let ((L '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) ((list-ref (L 1) 0) 2)) 9) (test (let ((L '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) (list-ref (((L 1) 0) 2) 3)) 'error) (let ((zero 0) (one 1) (two 2) (three 3)) (test (list-ref '((1 2 3) (4 5 6)) one) '(4 5 6)) (test (list-ref '((1 2 3) (4 5 6)) 1 two) 6) (test (list-ref '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))) one) '((7 8 9) (10 11 12))) (test (list-ref '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))) one zero) '(7 8 9)) (test (list-ref '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))) one zero two) 9) (test (list-ref '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))) one zero three) 'error) (test ('((1 2 3) (4 5 6)) one) '(4 5 6)) (test ('((1 2 3) (4 5 6)) 1 two) 6) (test ('(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))) one) '((7 8 9) (10 11 12))) (test ('(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))) one zero) '(7 8 9)) (test ('(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))) one zero two) 9) (test ('(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))) one zero three) 'error) (test (let ((L '((1 2 3) (4 5 6)))) (L one)) '(4 5 6)) (test (let ((L '((1 2 3) (4 5 6)))) (L 1 two)) 6) (test (let ((L '((1 2 3) (4 5 6)))) (L 1 2 3)) 'error) (test (let ((L '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) (L one)) '((7 8 9) (10 11 12))) (test (let ((L '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) (L one zero)) '(7 8 9)) (test (let ((L '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) (L one zero two)) 9) (test (let ((L '((1 2 3) (4 5 6)))) ((L one) two)) 6) (test (let ((L '((1 2 3) (4 5 6)))) (((L one) two) 3)) 'error) (test (let ((L '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) ((L one) zero)) '(7 8 9)) (test (let ((L '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) (((L one) zero) two)) 9) (test (let ((L '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) ((L one zero) two)) 9) (test (let ((L '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) ((L one) 0 two)) 9) (test (let ((L '((1 2 3) (4 5 6)))) (list-ref (L one) two)) 6) (test (let ((L '((1 2 3) (4 5 6)))) (list-ref ((L one) two) 3)) 'error) (test (let ((L '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) (list-ref (L one) zero)) '(7 8 9)) (test (let ((L '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) ((list-ref (L one) zero) two)) 9)) (test (list-ref () 0) 'error) (test (list-ref (list 1 2) 2) 'error) (test (list-ref (list 1 2) -1) 'error) (test (list-ref (list 1 2) 1.3) 'error) (test (list-ref (list 1 2) 1/3) 'error) (test (list-ref (list 1 2) 1+2.0i) 'error) (test (list-ref (cons 1 2) 1) 'error) (test (list-ref (cons 1 2) 2) 'error) (test (list-ref (list 1 2 3) (expt 2 32)) 'error) (test (list-ref '(1 2 3) 1 2) 'error) (test (list-ref) 'error) (test (list-ref '(1 2)) 'error) (test ('(0)) 'error) (test ((0)) 'error) (test (list-ref '((1 2) (3 4)) 1 1) 4) (test ('(1 2 3) 1) 2) (test ((list 1 2 3) 2) 3) (test ((list)) 'error) (test ((list 1) 0 0) 'error) (test ((list 1 (list 2 3)) 1 1) 3) (test ((append '(3) () '(1 2)) 0) 3) (test ((append '(3) () 1) 0) 3) (test ((append '(3) () 1) 1) 'error) ;; this works with 0 because: (test ((cons 1 2) 0) 1) (test (list-ref (cons 1 2) 0) 1) (test (((list (list 1 2 3)) 0) 0) 1) (test (((list (list 1 2 3)) 0) 1) 2) (test (((list (list 1 2 3)) 0 1)) 'error) ; see below (test (let ((lst (list (list 1 2 3)))) (lst 0 1)) 2) (test ((list (list 1 2 3)) 0 1) 2) (test (list-ref (list (list 1 2)) 0 ()) 'error) (test (((list +) 0) 1 2 3) 6) (let ((lst (list 1 2))) (for-each (lambda (arg) (test (list-ref (list 1 2) arg) 'error) (test ((list 1 2) arg) 'error) (test (lst arg) 'error)) (list "hi" (integer->char 65) #f '(1 2) () 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #\f #t :hi (if #f #f) (lambda (a) (+ a 1))))) ;;; -------------------------------------------------------------------------------- ;;; list-set! (test (let ((x (list 1))) (list-set! x 0 2) x) (list 2)) (test (let ((x (cons 1 2))) (list-set! x 0 3) x) '(3 . 2)) (test (let ((x (cons 1 2))) (list-set! x 1 3) x) 'error) (test (let ((x '((1) 2))) (list-set! x 0 1) x) '(1 2)) (test (let ((x '(1 2))) (list-set! x 1 (list 3 4)) x) '(1 (3 4))) (test (let ((x ''foo)) (list-set! x 0 "hi") x ) '("hi" foo)) (test (let ((x (list 1 2))) (list-set! x 0 x) (list? x)) #t) (test (let ((x (list 1 2))) (list-set! x 1 x) (list? x)) #t) (test (let ((x 2) (lst '(1 2))) (list-set! (let () (set! x 3) lst) 1 23) (list x lst)) '(3 (1 23))) (test (apply list-set! '((1 2) (3 2)) 1 '(1 2)) 2) (test (list-set! '(1 2 3) 1 4) 4) (test (set-car! '(1 2) 4) 4) (test (set-cdr! '(1 2) 4) 4) (test (fill! (list 1 2) 4) 4) (test (fill! () 1) 1) (test (list-set! '(1 2 . 3) 1 23) 23) (test (list-set! '(1 2 . 3) 2 23) 'error) (test (set! ('(1 2 . 3) 1) 23) 23) (test (let ((lst '(1 2 3))) (list-set! lst 0 32)) 32) (test (let ((lst '(1 2 3))) (set! (lst 0) 32)) 32) (test (let ((lst '(1 2 3))) (set! (list-ref lst 0) 32)) 32) (for-each (lambda (arg) (test (let ((x (list 1 2))) (list-set! x 0 arg) (list-ref x 0)) arg)) (list "hi" (integer->char 65) #f 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand (log 0) 3.14 3/4 1.0+1.0i #\f #t :hi (if #f #f) (lambda (a) (+ a 1)))) (test (let ((L '((1 2 3) (4 5 6)))) (list-set! L 1 32) L) '((1 2 3) 32)) (test (let ((L '((1 2 3) (4 5 6)))) (list-set! L 1 0 32) L) '((1 2 3) (32 5 6))) (test (let ((L '((1 2 3) (4 5 6)))) (list-set! L 1 0 2 32) L) 'error) (test (let ((L '((1 2 3) (4 5 6)))) (list-set! L 1 3 32) L) 'error) (test (let ((L '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) (list-set! L 1 32) L) '(((1 2 3) (4 5 6)) 32)) (test (let ((L '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) (list-set! L 1 0 32) L) '(((1 2 3) (4 5 6)) (32 (10 11 12)))) (test (let ((L '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) (list-set! L 1 0 2 32) L) '(((1 2 3) (4 5 6)) ((7 8 32) (10 11 12)))) (test (let ((L '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) (list-set! L 1 0 2 1 32) L) 'error) (test (let ((L '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) (list-set! L 1 4 2 32) L) 'error) (test (let ((L '((1 2 3) (4 5 6)))) (set! (L 1) 32) L) '((1 2 3) 32)) (test (let ((L '((1 2 3) (4 5 6)))) (set! (L 1 0) 32) L) '((1 2 3) (32 5 6))) (test (let ((L '((1 2 3) (4 5 6)))) (set! (L 1 0 2) 32) L) 'error) (test (let ((L '((1 2 3) (4 5 6)))) (set! (L 1 3) 32) L) 'error) (test (let ((L '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) (set! (L 1) 32) L) '(((1 2 3) (4 5 6)) 32)) (test (let ((L '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) (set! (L 1 0) 32) L) '(((1 2 3) (4 5 6)) (32 (10 11 12)))) (test (let ((L '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) (set! (L 1 0 2) 32) L) '(((1 2 3) (4 5 6)) ((7 8 32) (10 11 12)))) (test (let ((L '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) (set! (L 1 0 2 1) 32) L) 'error) (test (let ((L '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) (set! (L 1 4 2) 32) L) 'error) (test (let ((L '((1 2 3) (4 5 6)))) (set! ((L 1) 0) 32) L) '((1 2 3) (32 5 6))) (test (let ((L '((1 2 3) (4 5 6)))) (set! (((L 1) 0) 2) 32) L) 'error) (test (let ((L '((1 2 3) (4 5 6)))) (set! ((L 1) 3) 32) L) 'error) (test (let ((L '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) (set! ((L 1) 0) 32) L) '(((1 2 3) (4 5 6)) (32 (10 11 12)))) (test (let ((L '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) (set! (((L 1) 0) 2) 32) L) '(((1 2 3) (4 5 6)) ((7 8 32) (10 11 12)))) (test (let ((L '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) (set! ((((L 1) 0) 2) 1) 32) L) 'error) (test (let ((L '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) (set! (((L 1) 4) 2) 32) L) 'error) (test (let ((L '(((1 2 3))))) (set! ((L 0) 0 1) 32) L) '(((1 32 3)))) (test (let ((L '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) (set! ((L 1 0) 2) 32) L) '(((1 2 3) (4 5 6)) ((7 8 32) (10 11 12)))) (test (let ((L '((((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))) (13 14 15)))) (set! (L 0 0 1) 32) L) '((((1 2 3) 32) ((7 8 9) (10 11 12))) (13 14 15))) (test (let ((L '((((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))) (13 14 15)))) (set! ((L 0) 0 1 2) 32) L) '((((1 2 3) (4 5 32)) ((7 8 9) (10 11 12))) (13 14 15))) (test (let ((L '((((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))) (13 14 15)))) (set! ((L 0 0) 1 2) 32) L) '((((1 2 3) (4 5 32)) ((7 8 9) (10 11 12))) (13 14 15))) (test (let ((L '((((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))) (13 14 15)))) (set! ((L 0 0 1) 2) 32) L) '((((1 2 3) (4 5 32)) ((7 8 9) (10 11 12))) (13 14 15))) (test (let ((L '((((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))) (13 14 15)))) (set! (((L 0) 0) 1 2) 32) L) '((((1 2 3) (4 5 32)) ((7 8 9) (10 11 12))) (13 14 15))) (test (let ((L '((((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))) (13 14 15)))) (set! (((L 0 0) 1) 2) 32) L) '((((1 2 3) (4 5 32)) ((7 8 9) (10 11 12))) (13 14 15))) (test (let ((L '((((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))) (13 14 15)))) (set! ((((L 0) 0) 1) 2) 32) L) '((((1 2 3) (4 5 32)) ((7 8 9) (10 11 12))) (13 14 15))) (test (let ((L '(1 2 3))) (let ((L1 (list L))) (set! ((car L1) 1) 32) L)) '(1 32 3)) (let ((zero 0) (one 1) (two 2) (three 3) (thirty-two 32)) (test (let ((L '((1 2 3) (4 5 6)))) (list-set! L one thirty-two) L) '((1 2 3) 32)) (test (let ((L '((1 2 3) (4 5 6)))) (list-set! L one zero thirty-two) L) '((1 2 3) (32 5 6))) (test (let ((L '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) (list-set! L one thirty-two) L) '(((1 2 3) (4 5 6)) 32)) (test (let ((L '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) (list-set! L one zero thirty-two) L) '(((1 2 3) (4 5 6)) (32 (10 11 12)))) (test (let ((L '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) (list-set! L one zero two thirty-two) L) '(((1 2 3) (4 5 6)) ((7 8 32) (10 11 12)))) (test (let ((L '((1 2 3) (4 5 6)))) (set! (L one) thirty-two) L) '((1 2 3) 32)) (test (let ((L '((1 2 3) (4 5 6)))) (set! (L one zero) thirty-two) L) '((1 2 3) (32 5 6))) (test (let ((L '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) (set! (L one) thirty-two) L) '(((1 2 3) (4 5 6)) 32)) (test (let ((L '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) (set! (L one zero) thirty-two) L) '(((1 2 3) (4 5 6)) (32 (10 11 12)))) (test (let ((L '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) (set! (L one zero two) thirty-two) L) '(((1 2 3) (4 5 6)) ((7 8 32) (10 11 12)))) (test (let ((L '((1 2 3) (4 5 6)))) (set! ((L one) zero) thirty-two) L) '((1 2 3) (32 5 6))) (test (let ((L '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) (set! ((L one) zero) thirty-two) L) '(((1 2 3) (4 5 6)) (32 (10 11 12)))) (test (let ((L '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) (set! (((L one) zero) two) thirty-two) L) '(((1 2 3) (4 5 6)) ((7 8 32) (10 11 12)))) (test (let ((L '(((1 2 3))))) (set! ((L zero) zero one) thirty-two) L) '(((1 32 3)))) (test (let ((L '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) (set! ((L one zero) two) thirty-two) L) '(((1 2 3) (4 5 6)) ((7 8 32) (10 11 12)))) (test (let ((L '((((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))) (13 14 15)))) (set! (L zero zero one) thirty-two) L) '((((1 2 3) 32) ((7 8 9) (10 11 12))) (13 14 15))) (test (let ((L '((((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))) (13 14 15)))) (set! ((L zero) zero one two) thirty-two) L) '((((1 2 3) (4 5 32)) ((7 8 9) (10 11 12))) (13 14 15))) (test (let ((L '((((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))) (13 14 15)))) (set! ((L zero zero) one two) thirty-two) L) '((((1 2 3) (4 5 32)) ((7 8 9) (10 11 12))) (13 14 15))) (test (let ((L '((((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))) (13 14 15)))) (set! ((L zero 0 one) two) thirty-two) L) '((((1 2 3) (4 5 32)) ((7 8 9) (10 11 12))) (13 14 15))) (test (let ((L '((((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))) (13 14 15)))) (set! (((L zero) zero) one two) thirty-two) L) '((((1 2 3) (4 5 32)) ((7 8 9) (10 11 12))) (13 14 15))) (test (let ((L '((((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))) (13 14 15)))) (set! (((L zero zero) one) two) thirty-two) L) '((((1 2 3) (4 5 32)) ((7 8 9) (10 11 12))) (13 14 15))) (test (let ((L '((((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))) (13 14 15)))) (set! ((((L zero) zero) one) two) thirty-two) L) '((((1 2 3) (4 5 32)) ((7 8 9) (10 11 12))) (13 14 15))) (test (let ((L '(1 2 3))) (let ((L1 (list L))) (set! ((car L1) one) thirty-two) L)) '(1 32 3))) (test (let ((x '(1)) (y '(2))) (set! ((if #t x y) 0) 32) (list x y)) '((32) (2))) (test (list-set! () 0 1) 'error) (test (list-set! () -1 1) 'error) (test (list-set! '(1) 1 2) 'error) (test (list-set! '(1 2 3) -1 2) 'error) (test (list-set! '(1) 1.5 2) 'error) (test (list-set! '(1) 3/2 2) 'error) (test (list-set! '(1) 1+3i 2) 'error) (test (list-set! '(1 2 3) 1 2 3) 'error) (test (list-set! (list 1 2 3) (expt 2 32) 0) 'error) (test (list-set! (list 1 2) () 1) 'error) (for-each (lambda (arg) (test (list-set! (list 1 2) arg arg) 'error) (test (list-set! arg 1 2) 'error) (test (list-set! (list 1 2) arg 1) 'error)) (list "hi" (integer->char 65) #f 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #\f #t :hi (if #f #f) (lambda (a) (+ a 1)))) ;;; -------------------------------------------------------------------------------- ;;; list (test (let ((tree1 (list 1 (list 1 2) (list (list 1 2 3)) (list (list (list 1 2 3 4)))))) tree1) '(1 (1 2) ((1 2 3)) (((1 2 3 4))))) (test (let ((tree2 (list "one" (list "one" "two") (list (list "one" "two" "three"))))) tree2) '("one" ("one" "two") (("one" "two" "three")))) (test (let ((tree1 (list 1 (list 1 2) (list 1 2 3) (list 1 2 3 4)))) tree1) '(1 (1 2) (1 2 3) (1 2 3 4))) (test (let ((tree1 (list 1 (list 1 2))) (tree2 (list 1 (list 1 2)))) tree2) '(1 (1 2))) (test (let ((tree1 (list 1 (list 1 2))) (tree2 (list 1 (list 1 2)))) (eqv? tree1 tree2)) #f) (test (let ((tree1 (list ''a (list ''b ''c))) (tree2 (list ''a (list ''b ''c)))) tree2) '('a ('b 'c))) (test (let ((lst (list 1 (list 2 3)))) lst) '(1 (2 3))) (test (let* ((lst (list 1 (list 2 3))) (slst lst)) slst) '(1 (2 3))) (test (list 1) '(1)) (test (let ((a 1)) (list a 2)) '(1 2)) (test (let ((a 1)) (list 'a '2)) '(a 2)) (test (let ((a 1)) (list 'a 2)) '(a 2)) (test (list) ()) (test (let ((a (list 1 2))) a) '(1 2)) (test (let ((a (list 1 2))) (list 3 4 'a (car (cons 'b 'c)) (+ 6 -2))) '(3 4 a b 4)) (test (list) ()) (test (length (list quote do map call/cc lambda define if begin set! let let* cond and or for-each)) 15) (test (list 1(list 2)) '(1(2))) (test (list 1 2 . 3) 'error) ;(test (list 1 2 , 3) 'error) ; ,3 -> 3 in the reader now (test (list 1 2 ,@ 3) 'error) ;;; -------------------------------------------------------------------------------- ;;; list-tail (test (list-tail '(1 2 3) 0) '(1 2 3)) (test (list-tail '(1 2 3) 2) '(3)) (test (list-tail '(1 2 3) 3) ()) (test (list-tail '(1 2 3 . 4) 2) '(3 . 4)) (test (list-tail '(1 2 3 . 4) 3) 4) (test (let ((x (list 1 2 3))) (eq? (list-tail x 2) (cddr x))) #t) (test (list-tail () 0) ()) (test (list-tail () 1) 'error) (test (list-tail '(1 2 3) 4) 'error) (test (list-tail () -1) 'error) (test (list-tail (list 1 2) 2) ()) (test (list-tail (cons 1 2) 0) '(1 . 2)) (test (list-tail (cons 1 2) 1) 2) (test (list-tail (cons 1 2) 2) 'error) (test (list-tail (cons 1 2) -1) 'error) (test (list-tail ''foo 1) '(foo)) (test (list-tail '((1 2) (3 4)) 1) '((3 4))) (test (list-tail (list-tail '(1 2 3) 1) 1) '(3)) (test (list-tail (list-tail (list-tail '(1 2 3 4) 1) 1) 1) '(4)) (test (list-tail '(1 2) (list-tail '(0 . 1) 1)) '(2)) (let ((x '(1 . 2))) (set-cdr! x x) (test (list-tail x 0) x)) (let ((x '(1 . 2))) (set-cdr! x x) (test (list-tail x 1) (cdr x))) (let ((x '(1 . 2))) (set-cdr! x x) (test (list-tail x 100) x)) (let ((x (list 1 2 3))) (let ((y (list-tail x 1))) (set! (y 1) 32) (test (equal? y '(2 32)) #t) (test (equal? x '(1 2 32)) #t))) ; list-tail is not like substring (for-each (lambda (name op1 op2) (for-each (lambda (lst) (let ((val1 (catch #t (lambda () (op1 lst)) (lambda args 'error))) (val2 (catch #t (lambda () (op2 lst)) (lambda args 'error)))) (if (not (equal? val1 val2)) (format-logged #t ";(~A ~A) -> ~A ~A?~%" name lst val1 val2)))) lists)) (list 'list-tail:0 'list-tail:1 'list-tail:2 'list-tail:3 'list-tail:4) (list (lambda (l) l) cdr cddr cdddr cddddr) (list (lambda (l) (list-tail l 0)) (lambda (l) (list-tail l 1)) (lambda (l) (list-tail l 2)) (lambda (l) (list-tail l 3)) (lambda (l) (list-tail l 4)))) (test (list-tail (list 1 2) 3) 'error) (test (list-tail (list 1 2) -1) 'error) (test (list-tail (list 1 2) 1.3) 'error) (test (list-tail (list 1 2) 1/3) 'error) (test (list-tail (list 1 2) 1+2.0i) 'error) (test (list-tail '(1 2 . 3)) 'error) (test (list-tail '(1 2 . 3) 1) '(2 . 3)) (test (list-tail '(1 2 . 3) 0) '(1 2 . 3)) (test (list-tail (list 1 2 3) (+ 1 (expt 2 32))) 'error) (test (list-tail) 'error) (test (list-tail '(1)) 'error) (test (list-tail '(1) 1 2) 'error) (test (set! (list-tail (list 1 2 3)) '(32)) 'error) ; should this work? (for-each (lambda (arg) (test (list-tail (list 1 2) arg) 'error) (test (list-tail arg 0) 'error)) (list "hi" -1 3 most-negative-fixnum most-positive-fixnum (integer->char 65) #f 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #\f #t (if #f #f) # #() #(1 2 3) (lambda (a) (+ a 1)))) ;;; -------------------------------------------------------------------------------- ;;; make-list (test (make-list 0) ()) (test (make-list 0 123) ()) (test (make-list 1) '(#f)) (test (make-list 1 123) '(123)) (test (make-list 1 ()) '(())) (test (make-list 2) '(#f #f)) (test (make-list 2 1) '(1 1)) (test (make-list 2/1 1) '(1 1)) (test (make-list 2 (make-list 1 1)) '((1) (1))) (test (make-list -1) 'error) (test (make-list -0) ()) (test (make-list most-negative-fixnum) 'error) (test (make-list most-positive-fixnum) 'error) (test (make-list 0 #\a) ()) (test (make-list 1 #\a) '(#\a)) (for-each (lambda (arg) (test (make-list arg) 'error)) (list #\a #(1 2 3) 3.14 3/4 1.0+1.0i 0.0 1.0 () #t 'hi #(()) (list 1 2 3) '(1 . 2) "hi" (- (real-part (log 0.0))))) (for-each (lambda (arg) (test ((make-list 1 arg) 0) arg)) (list #\a #(1 2 3) 3.14 3/4 1.0+1.0i () #f 'hi #(()) (list 1 2 3) '(1 . 2) "hi")) (test (make-list) 'error) (test (make-list 1 2 3) 'error) (test (let ((lst (make-list 2 (make-list 1 0)))) (eq? (lst 0) (lst 1))) #t) ;;; -------------------------------------------------------------------------------- ;;; assq (let ((e '((a 1) (b 2) (c 3)))) (test (assq 'a e) '(a 1)) (test (assq 'b e) '(b 2)) (test (assq 'd e) #f)) (test (assq (list 'a) '(((a)) ((b)) ((c)))) #f) (let ((xcons (cons 1 2)) (xvect (vector 1 2)) (xlambda (lambda () 1)) (xstr "abs")) (let ((e (list (list #t 1) (list #f 2) (list 'a 3) (list xcons 4) (list xvect 5) (list xlambda 6) (list xstr 7) (list car 8)))) (test (assq #t e) (list #t 1)) (test (assq #f e) (list #f 2)) (test (assq 'a e) (list 'a 3)) (test (assq xcons e) (list xcons 4)) (test (assq xvect e) (list xvect 5)) (test (assq xlambda e) (list xlambda 6)) (test (assq xstr e) (list xstr 7)) (test (assq car e) (list car 8)))) (let ((e '((1+i 1) (3.0 2) (5/3 3)))) (test (assq 1+i e) #f) (test (assq 3.0 e) #f) (test (assq 5/3 e) #f)) (test (assq 'x (cdr (assq 'a '((b . 32) (a . ((a . 12) (b . 32) (x . 1))) (c . 1))))) '(x . 1)) (when (not pure-s7) (test (assq #f '(#f 2 . 3)) #f)) (test (assq #f '((#f 2) . 3)) '(#f 2)) (test (assq () '((() 1) (#f 2))) '(() 1)) (test (assq () '((1) (#f 2))) #f) (test (assq #() '((#f 1) (() 2) (#() 3))) #f) ; (eq? #() #()) -> #f (test (assq 'b '((a . 1) (b . 2) () (c . 3) #f)) '(b . 2)) (test (assq 'c '((a . 1) (b . 2) () (c . 3) #f)) '(c . 3)) (test (assq 'b '((a . 1) (b . 2) () (c . 3) . 4)) '(b . 2)) (when (not pure-s7) (test (assq 'c '((a . 1) (b . 2) () (c . 3) . 4)) '(c . 3))) (test (assq 'b (list '(a . 1) '(b . 2) () '(c . 3) #f)) '(b . 2)) (test (assq 'asdf (list '(a . 1) '(b . 2) () '(c . 3) #f)) #f) (test (assq "" (list '("a" . 1) '("" . 2) '(#() . 3))) #f) ; since (eq? "" "") is #f (test (assq 'a '((a . 1) (a . 2) (a . 3))) '(a . 1)) ; is this specified? (test (assq 'a '((b . 1) (a . 2) (a . 3))) '(a . 2)) ;; check the even/odd cases (let ((odd '((3 . 1) (a . 2) (3.0 . 3) (b . 4) (3/4 . 5) (c . 6) (#(1) . 7) (d . 8))) (even '((e . 1) (3 . 2) (a . 3) (3.0 . 4) (b . 5) (3/4 . 6) (c . 7) (#(1) . 8) (d . 9)))) (test (assq 'a odd) '(a . 2)) (test (assq 'a even) '(a . 3)) (test (assq 3/4 odd) #f) (test (assq 3/4 even) #f) (test (assq 3.0 odd) #f) (test (assq 3.0 even) #f) (test (assq #(1) odd) #f) (test (assq #(1) even) #f)) ;;; -------------------------------------------------------------------------------- ;;; assv (when (not pure-s7) (test (assv 1 '(1 2 . 3)) #f)) (test (assv 1 '((1 2) . 3)) '(1 2)) (let ((e '((a 1) (b 2) (c 3)))) (test (assv 'a e) '(a 1)) (test (assv 'b e) '(b 2)) (test (assv 'd e) #f)) (test (assv (list 'a) '(((a)) ((b)) ((c)))) #f) (let ((xcons (cons 1 2)) (xvect (vector 1 2)) (xlambda (lambda () 1)) (xstr "abs")) (let ((e (list (list #t 1) (list #f 2) (list 'a 3) (list xcons 4) (list xvect 5) (list xlambda 6) (list xstr 7) (list car 8)))) (test (assv #t e) (list #t 1)) (test (assv #f e) (list #f 2)) (test (assv 'a e) (list 'a 3)) (test (assv xcons e) (list xcons 4)) (test (assv xvect e) (list xvect 5)) (test (assv xlambda e) (list xlambda 6)) (test (assv xstr e) (list xstr 7)) (test (assv car e) (list car 8)))) (let ((e '((1+i 1) (3.0 2) (5/3 3) (#\a 4) ("hiho" 5)))) (test (assv 1+i e) '(1+i 1)) (test (assv 3.0 e) '(3.0 2)) (test (assv 5/3 e) '(5/3 3)) (test (assv #\a e) '(#\a 4)) (test (assv "hiho" e) #f)) (let ((e '(((a) 1) (#(a) 2) ("c" 3)))) (test (assv '(a) e) #f) (test (assv #(a) e) #f) (test (assv (string #\c) e) #f)) (let ((lst '((2 . a) (3 . b)))) (set-cdr! (assv 3 lst) 'c) (test lst '((2 . a) (3 . c)))) (test (assv () '((() 1) (#f 2))) '(() 1)) (test (assv () '((1) (#f 2))) #f) (test (assv #() '((#f 1) (() 2) (#() 3))) #f) ; (eqv? #() #()) -> #f ?? (test (assv 'b '((a . 1) (b . 2) () (c . 3) #f)) '(b . 2)) (test (assv 'c '((a . 1) (b . 2) () (c . 3) #f)) '(c . 3)) (test (assv 'b '((a . 1) (b . 2) () (c . 3) . 4)) '(b . 2)) (when (not pure-s7) (test (assv 'c '((a . 1) (b . 2) () (c . 3) . 4)) '(c . 3))) (when (not pure-s7) (test (assv 'asdf '((a . 1) (b . 2) () (c . 3) . 4)) #f)) (test (assv 'd '((a . 1) (b . 2) () (c . 3) (d . 5))) '(d . 5)) (test (assv 'a '((a . 1) (a . 2) (a . 3))) '(a . 1)) ; is this specified? (test (assv 'a '((b . 1) (a . 2) (a . 3))) '(a . 2)) (let ((odd '((3 . 1) (a . 2) (3.0 . 3) (b . 4) (3/4 . 5) (c . 6) (#(1) . 7) (d . 8))) (even '((e . 1) (3 . 2) (a . 3) (3.0 . 4) (b . 5) (3/4 . 6) (c . 7) (#(1) . 8) (d . 9)))) (test (assv 'a odd) '(a . 2)) (test (assv 'a even) '(a . 3)) (test (assv 3 odd) '(3 . 1)) (test (assv 3 even) '(3 . 2)) (test (assv 3/4 odd) '(3/4 . 5)) (test (assv 3/4 even) '(3/4 . 6)) (test (assv 3.0 odd) '(3.0 . 3)) (test (assv 3.0 even) '(3.0 . 4)) (test (assv #(1) odd) #f) (test (assv #(1) even) #f)) (test (assv 1/0 '((1/0 . 1) (1.0 . 3))) #f) (test (pair? (assv (real-part (log 0)) (list (cons 1/0 1) (cons (real-part (log 0)) 2) (cons -1 3)))) #t) (test (pair? (assv (- (real-part (log 0))) (list (cons 1/0 1) (cons (real-part (log 0)) 2) (cons -1 3)))) #f) ;;; -------------------------------------------------------------------------------- ;;; assoc (let ((e '((a 1) (b 2) (c 3)))) (test (assoc 'a e) '(a 1)) (test (assoc 'b e) '(b 2)) (test (assoc 'd e) #f)) (test (assoc (list 'a) '(((a)) ((b)) ((c)))) '((a))) (let ((xcons (cons 1 2)) (xvect (vector 1 2)) (xlambda (lambda () 1)) (xstr "abs")) (let ((e (list (list #t 1) (list #f 2) (list 'a 3) (list xcons 4) (list xvect 5) (list xlambda 6) (list xstr 7) (list car 8)))) (test (assoc #t e) (list #t 1)) (test (assoc #f e) (list #f 2)) (test (assoc 'a e) (list 'a 3)) (test (assoc xcons e) (list xcons 4)) (test (assoc xvect e) (list xvect 5)) (test (assoc xlambda e) (list xlambda 6)) (test (assoc xstr e) (list xstr 7)) (test (assoc car e) (list car 8)))) (let ((e '((1+i 1) (3.0 2) (5/3 3) (#\a 4) ("hiho" 5)))) (test (assoc 1+i e) '(1+i 1)) (test (assoc 3.0 e) '(3.0 2)) (test (assoc 5/3 e) '(5/3 3)) (test (assoc #\a e) '(#\a 4)) (test (assoc "hiho" e) '("hiho" 5))) (let ((e '(((a) 1) (#(a) 2) ("c" 3)))) (test (assoc '(a) e) '((a) 1)) (test (assoc #(a) e) '(#(a) 2)) (test (assoc (string #\c) e) '("c" 3))) (test (assoc 'a '((b c) (a u) (a i))) '(a u)) (test (assoc 'a '((b c) ((a) u) (a i))) '(a i)) (test (assoc (list 'a) '(((a)) ((b)) ((c)))) '((a))) (test (assoc 5 '((2 3) (5 7) (11 13))) '(5 7)) (test (assoc 'key ()) #f) (test (assoc 'key '(() ())) 'error) (test (assoc () ()) #f) (test (assoc 1 '((1 (2)) (((3) 4)))) '(1 (2))) (test (assoc #f () 1/9223372036854775807) 'error) (test (assoc () 1) 'error) (test (assoc (cons 1 2) 1) 'error) (test (assoc (let ((x (cons 1 2))) (set-cdr! x x)) 1) 'error) (test (assoc '((1 2) .3) 1) 'error) (test (assoc ''foo quote) 'error) (test (assoc 3 '((a . 3)) abs =) 'error) (test (assoc 1 '(1 2 . 3)) 'error) (test (assoc 1 '((1 2) . 3)) '(1 2)) (test (assoc 1 '((1) (1 3) (1 . 2))) '(1)) (test (assoc 1 '((1 2 . 3) (1 . 2))) '(1 2 . 3)) (test (assoc '(((1 2))) '((1 2) ((1 2) 3) (((1 2) 3) 4) ((((1 2) 3) 4) 5))) #f) (test (assoc '(((1 2))) '((1 2) ((1 2)) (((1 2))) ((((1 2)))))) '((((1 2))))) (test (assoc 'a '((a . 1) (a . 2) (a . 3))) '(a . 1)) ; is this specified? (test (assoc 'a '((b . 1) (a . 2) (a . 3))) '(a . 2)) (test (assoc () '((() 1) (#f 2))) '(() 1)) (test (assoc () '((1) (#f 2))) #f) (test (assoc #() '((#f 1) (() 2) (#() 3))) '(#() 3)) (test (assoc # (list (cons (apply values ()) #f))) '(# . #f)) (for-each (lambda (arg) (test (assoc arg (list (list 1 2) (list arg 3))) (list arg 3))) (list "hi" (integer->char 65) #f 'a-symbol #() abs 3/4 #\f #t (if #f #f))) (test (assoc 'b '((a . 1) (b . 2) () (c . 3) #f)) '(b . 2)) (test (assoc 'c '((a . 1) (b . 2) () (c . 3) #f)) '(c . 3)) (test (assoc 'b '((a . 1) (b . 2) () (c . 3) . 4)) '(b . 2)) (test (assoc 'c '((a . 1) (b . 2) () (c . 3) . 4)) '(c . 3)) (test (assoc 'c '((a . 1) (b . 2) () (c . 3) (c . 4) . 4)) '(c . 3)) (test (assoc 'asdf '((a . 1) (b . 2) () (c . 3) (c . 4) . 4)) #f) (test (assoc "" (list '("a" . 1) '("" . 2) '(#() . 3))) '("" . 2)) (test (assoc assoc (list (cons abs 1) (cons assoc 2) (cons + 3))) (cons assoc 2)) (let ((odd '((3 . 1) (a . 2) (3.0 . 3) (b . 4) (3/4 . 5) (c . 6) (#(1) . 7) (d . 8))) (even '((e . 1) (3 . 2) (a . 3) (3.0 . 4) (b . 5) (3/4 . 6) (c . 7) (#(1) . 8) (d . 9)))) (test (assoc 'a odd) '(a . 2)) (test (assoc 'a even) '(a . 3)) (test (assoc 3 odd) '(3 . 1)) (test (assoc 3 even) '(3 . 2)) (test (assoc 3/4 odd) '(3/4 . 5)) (test (assoc 3/4 even) '(3/4 . 6)) (test (assoc 3.0 odd =) '(3 . 1)) (test (assoc 3.0 odd) '(3.0 . 3)) (test (assoc 3.0 even) '(3.0 . 4)) (test (assoc #(1) odd) '(#(1) . 7)) (test (assoc #(1) even) '(#(1) . 8))) (test (assoc 3 '((1 . a) (2 . b) (3 . c) (4 . d)) =) '(3 . c)) (test (assoc 3 '((1 . a) (2 . b) (31 . c) (4 . d)) =) #f) (test (assoc 3 () =) #f) (test (assoc 3.0 '((1 . a) (2 . b) (3 . c) (4 . d)) =) '(3 . c)) (test (assoc #\a '((#\A . 1) (#\b . 2)) char=?) #f) (test (assoc #\a '((#\A . 1) (#\b . 2)) char-ci=?) '(#\A . 1)) (test (assoc #\a '((#\A . 1) (#\b . 2)) (lambda (a b) (char-ci=? a b))) '(#\A . 1)) (test (assoc 3 '((1 . a) (2 . b) (3 . c) (4 . d)) #(1)) 'error) (test (assoc 3 '((1 . a) (2 . b) (3 . c) (4 . d)) abs) 'error) (test (assoc 3 '((1 . a) (2 . b) (3 . c) (4 . d)) quasiquote) 'error) (test (assoc 3 '((1 . a) (2 . b) (3 . c) (4 . d)) (lambda (a b c) (= a b))) 'error) (test (assoc 3.0 '((1 . a) (2 . b) (3 . c) (4 . d)) (lambda* (a b c) (= a b))) '(3 . c)) (test (assoc 3 '((1 . a) (2 . b) (3 . c) (4 . d)) (lambda (a) (= a 1))) 'error) (test (assoc 4.0 '((1 . a) (2 . b) (3 . c) (4 . d)) (dilambda = =)) '(4 . d)) (test (catch #t (lambda () (assoc 4.0 '((1 . a) (2 . b) (3 . c) (4 . d)) (lambda (a b) (error 'assoc a)))) (lambda args (car args))) 'assoc) (test (call-with-exit (lambda (go) (assoc 4.0 '((1 . a) (2 . b) (3 . c) (4 . d)) (lambda (a b) (go 'assoc))))) 'assoc) (test (assoc 3 '((#\a . 3) (#() . 2) (3.0 . 1) ("3" . 0))) #f) (test (assoc 3 '((#\a . 3) (#() . 2) (3.0 . 1) ("3" . 0)) (lambda (a b) (= a b))) 'error) (test (assoc 3 '((#\a . 3) (#() . 2) (3.0 . 1) ("3" . 0)) (lambda (a b) (and (number? b) (= a b)))) '(3.0 . 1)) ; is this order specified? (test (let ((lst (list (cons 1 2) (cons 3 4) (cons 5 6)))) (set! (cdr (cdr lst)) lst) (assoc 3 lst)) '(3 . 4)) (test (let ((lst '((1 . 2) (3 . 4) . 5))) (assoc 3 lst)) '(3 . 4)) (test (let ((lst '((1 . 2) (3 . 4) . 5))) (assoc 5 lst)) #f) (test (let ((lst '((1 . 2) (3 . 4) . 5))) (assoc 3 lst =)) '(3 . 4)) (test (let ((lst '((1 . 2) (3 . 4) . 5))) (assoc 5 lst =)) #f) (test (assoc 3 '((1 . 2) . 3)) #f) (test (assoc 1 '((1 . 2) . 3)) '(1 . 2)) (test (assoc 3 '((1 . 2) . 3) =) #f) (test (assoc 1 '((1 . 2) . 3) =) '(1 . 2)) (test (let ((lst (list (cons 1 2) (cons 2 3) (cons 3 4)))) (and (assoc 2 lst =) lst)) '((1 . 2) (2 . 3) (3 . 4))) (test (let ((lst (list (cons 1 2) (cons 2 3) (cons 3 4)))) (set! (cdr (cdr lst)) lst) (assoc 2 lst)) '(2 . 3)) (test (let ((lst (list (cons 1 2) (cons 2 3) (cons 3 4)))) (set! (cdr (cdr lst)) lst) (assoc 2 lst =)) '(2 . 3)) (test (let ((lst (list (cons 1 2) (cons 2 3) (cons 3 4)))) (set! (cdr (cdr lst)) lst) (assoc 4 lst)) #f) (test (let ((lst (list (cons 1 2) (cons 2 3) (cons 3 4)))) (set! (cdr (cdr lst)) lst) (assoc 4 lst =)) #f) (test (let ((lst (list (cons 1 2) (cons 2 3) (cons 3 4)))) (set! (cdr (cdr (cdr lst))) lst) (assoc 3 lst =)) '(3 . 4)) (test (assoc '(1 2) '((a . 3) ((1 2) . 4))) '((1 2) . 4)) (test (assoc '(1 2) '((a . 3) ((1 2) . (3 4)))) '((1 2) 3 4)) (test (assoc '(1 2) '((a . 3) ((1 2) . (3 . 4)))) '((1 2) 3 . 4)) (test (cdr (assoc '(1 2) '((a . 3) ((1 2) . (3 . 4))))) (cons 3 4)) (test (assoc #t (list 1 2) #()) 'error) (test (assoc #t (list 1 2) (integer->char 127)) 'error) (test (assoc #t (list 1 2) (lambda (x y) (+ x 1))) 'error) ; (+ #t 1) (test (assoc #t (list 1 2) abs) 'error) (test (assoc #t (list 1 2) (lambda args args)) 'error) (test (assoc 1 '((3 . 2) 3) =) 'error) (test (assoc 1 '((1 . 2) 3) =) '(1 . 2)) ; this is like other trailing error unchecked cases -- should we check? (test (assoc 'a '((c 3) (a 1) (b 2)) (lambda (a) (eq? a b))) 'error) (test (assoc 'a '((c 3) (a 1) (b 2)) (lambda (a b) (eq? a b))) '(a 1)) (test (assoc 'a '((c 3) (a 1) (b 2)) (lambda (a b c) (eq? a b))) 'error) (test (assoc 'a '((c 3) (a 1) (b 2)) (lambda (a b c . d) (eq? a b))) 'error) (test (assoc 'a '((c 3) (a 1) (b 2)) (lambda (a b . c) (eq? a b))) '(a 1)) (test (assoc 'a '((c 3) (a 1) (b 2)) (lambda a (apply eq? a))) '(a 1)) (test (assoc 'a '((c 3) (a 1) (b 2)) (lambda (a . b) (eq? a (car b)))) '(a 1)) (test (assoc 'a '((c 3) (a 1) (b 2)) (lambda* (a) (eq? a b))) 'error) (test (assoc 'a '((c 3) (a 1) (b 2)) (lambda* (a b) (eq? a b))) '(a 1)) (test (assoc 'a '((c 3) (a 1) (b 2)) (lambda* (a b c) (eq? a b))) '(a 1)) (test (assoc 'a '((c 3) (a 1) (b 2)) (lambda* (a b c . d) (eq? a b))) '(a 1)) (test (assoc 'a '((c 3) (a 1) (b 2)) (lambda* (a b . c) (eq? a b))) '(a 1)) (test (assoc 'a '((c 3) (a 1) (b 2)) (lambda* a (apply eq? a))) '(a 1)) (test (assoc 'a '((c 3) (a 1) (b 2)) (lambda* (a . b) (eq? a (car b)))) '(a 1)) (test (assoc 'a '((c 3) (a 1) (b 2)) (lambda* (a :rest b) (eq? a (car b)))) '(a 1)) (test (assoc 'a '((c 3) (a 1) (b 2)) (lambda* (a :rest b :rest c) (eq? a (car b)))) '(a 1)) (test (assoc 'a '((c 3) (a 1) (b 2)) (lambda* (:rest a) (apply eq? a))) '(a 1)) (test (assoc 'a '((a 1) (b 2) (c 3)) (define-macro (_m_ a b) `(eq? ',a ',b))) '(a 1)) (test (assoc 'c '((a 1) (b 2) (c 3)) (define-macro (_m_ a b) `(eq? ',a ',b))) '(c 3)) (let () (define (atest a b) (eq? a b)) (atest 1 1) (let ((lst (list (cons 'a 1) (cons 'b 2)))) (test (assoc 'b lst atest) '(b . 2)))) (for-each (lambda (arg lst) (test (assoc arg lst eq?) (assq arg lst)) (test (assoc arg lst eqv?) (assv arg lst)) (test (assoc arg lst equal?) (assoc arg lst))) (list 'a #f (list 'a) 'a 1 3/4 #(1) "hi") (list '((a . 1) (b . 2) (c . 3)) '((1 . 1) ("hi" . 2) (#t . 4) (#f . 5) (2 . 3)) '((b . 1) ((a) . 2) (c . 3)) '((d . 1) (a . 2) (b . 4) . (c . 3)) '((1 . 1) (3/4 . 2) (23 . 3)) '((a . 1) (1 . 2) (#(1) . 4) (23 . 3)) '((1 . 1) ("hi" . 2) (23 . 3)))) ;;; -------------------------------------------------------------------------------- ;;; memq (test (memq 'a '(a b c)) '(a b c)) (test (memq 'a (list 'a 'b 'c)) '(a b c)) (test (memq 'b '(a b c)) '(b c)) (test (memq 'a '(b c d)) #f) (test (memq (list 'a) '(b (a) c)) #f) (test (memq 'a '(b a c a d a)) '(a c a d a)) (let ((v (vector 'a))) (test (memq v (list 'a 1.2 v "hi")) (list v "hi"))) (test (memq #f '(1 a #t "hi" #f 2)) '(#f 2)) (test (memq eq? (list 2 eqv? 1 eq?)) (list eq?)) (test (memq eq? (list 2 eqv? 2)) #f) (test (memq 6 (memq 5 (memq 4 (memq 3 (memq 2 (memq 1 '(1 2 3 4 5 6))))))) '(6)) (test (memq 1/2 (list (/ 2.0) .5 1/2)) #f) (test (memq 'a (cons 'a 'b)) '(a . b)) (test (memq) 'error) (test (memq 'a) 'error) (test (memq 'a 'b) 'error) (test (memq 'a '(a b . c)) '(a b . c)) (test (memq 'b '(a b . c)) '(b . c)) (test (memq 'c '(a b . c)) #f) ; or should it be 'c? (test (memq () '(1 () 3)) '(() 3)) (test (memq () '(1 2)) #f) (test (memq 'a '(c d a b c)) '(a b c)) (test (memq 'a '(c d f b c)) #f) (test (memq 'a ()) #f) (test (memq 'a '(c d a b . c)) '(a b . c)) (test (memq 'a '(c d f b . c)) #f) (test (memq #f '(1 "hi" #t)) #f) (test (memq () ()) #f) (test (memq () (list)) #f) (test (memq () (list ())) '(())) (test (let ((x (cons 1 2))) (memq x (list x (cons 3 4)))) '((1 . 2) (3 . 4))) (test (pair? (let ((x (lambda () 1))) (memq x (list 1 2 x 3)))) #t) (test (memq memq (list abs + memq car)) (list memq car)) (test (memq 'a '(a a a)) '(a a a)) ;? (test (memq 'a '(b a a)) '(a a)) (test (memq "hi" '(1 "hi" 2)) #f) (test (let ((str "hi")) (memq str (list 1 str 2))) '("hi" 2)) (test (memq #\a '(1 #f #\a 2)) '(#\a 2)) (test (let* ((x (vector 1 2 3)) (lst (list 1 "hi" x (vector 1 2)))) (memq x lst)) '(#(1 2 3) #(1 2))) (test (let* ((x (vector 1 2 3)) (lst (list 1 "hi" (vector 1 2 3)))) (memq x lst)) #f) (let ((odd '(3 a 3.0 b 3/4 c #(1) d)) (even '(e 3 a 3.0 b 3/4 c #(1) d))) (test (memq 'a odd) '(a 3.0 b 3/4 c #(1) d)) (test (memq 'a even) '(a 3.0 b 3/4 c #(1) d)) (test (memq 3/4 odd) #f) (test (memq 3/4 even) #f) (test (memq 3.0 odd) #f) (test (memq 3.0 even) #f) (test (memq #(1) odd) #f) (test (memq #(1) even) #f)) ;;; but (memq pi (list 1 pi 2)) -> '(3.1415926535898 2) (test (memq (values #\a '(#\A 97 a))) #f) (test (memq (values #\a '(#\A 97 #\a))) '(#\a)) (test (memq #\a (values #\a '(#\A 97 #\a))) 'error) (test (memq #\a (values '(#\A 97 #\a))) '(#\a)) (test (memq #\a '(1 2) (values)) 'error) ; hmmm (test ((values memq (values #\a '(#\A 97 #\a)))) '(#\a)) ;;; -------------------------------------------------------------------------------- ;;; memv (test (memv 101 '(100 101 102)) '(101 102)) (test (memv 101 (list 100 101 102)) '(101 102)) (test (memv 3.4 '(1.2 2.3 3.4 4.5)) '(3.4 4.5)) (test (memv 3.4 '(1.3 2.5 3.7 4.9)) #f) (test (memv 1/2 (list (/ 2.0) .5 1/2)) '(1/2)) (test (memv 1.0 '(1 2 3)) #f) (test (memv 1/0 '(1/0 1.0 3)) #f) (test (pair? (memv (real-part (log 0)) (list 1/0 (real-part (log 0)) -1))) #t) (test (pair? (memv (- (real-part (log 0))) (list 1/0 (real-part (log 0)) -1))) #f) (let ((ls (list 'a 'b 'c))) (set-car! (memv 'b ls) 'z) (test ls '(a z c))) (test (memv 1 (cons 1 2)) '(1 . 2)) (test (memv 'a (list 'a 'b . 'c)) 'error) (test (memv 'a '(a b . c)) '(a b . c)) (test (memv 'asdf '(a b . c)) #f) (test (memv) 'error) (test (memv 'a) 'error) (test (memv 'a 'b) 'error) (test (memv 'c '(a b c)) '(c)) (test (memv 'c '(a b . c)) #f) (test (memv ''a '('a b c)) #f) (test (let ((x (cons 1 2))) (memv x (list (cons 1 2) (cons 3 4)))) #f) (test (let ((x (cons 1 2))) (memv x (list x (cons 3 4)))) '((1 . 2) (3 . 4))) (test (memv 'a '(a a a)) '(a a a)) ;? (test (memv 'a '(b a a)) '(a a)) (test (memv "hi" '(1 "hi" 2)) #f) (test (memv #\a '(1 #f #\a 2)) '(#\a 2)) (test (memv cons (list car cdr cons +)) (list cons +)) (test (memv (apply values ()) (list #)) (list #)) (let ((odd '(3 a 3.0 b 3/4 c #(1) d)) (even '(e 3 a 3.0 b 3/4 c #(1) d))) (test (memv 'a odd) '(a 3.0 b 3/4 c #(1) d)) (test (memv 'a even) '(a 3.0 b 3/4 c #(1) d)) (test (memv 3/4 odd) '(3/4 c #(1) d)) (test (memv 3/4 even) '(3/4 c #(1) d)) (test (memv 3.0 odd) '(3.0 b 3/4 c #(1) d)) (test (memv 3.0 even) '(3.0 b 3/4 c #(1) d)) (test (memv #(1) odd) #f) (test (memv #(1) even) #f)) (test (memv #(1) '(1 #(1) 2)) #f) (test (memv () '(1 () 2)) '(() 2)) (test (let* ((x (vector 1 2 3)) (lst (list 1 "hi" x (vector 1 2)))) (memv x lst)) '(#(1 2 3) #(1 2))) (test (let* ((x (vector 1 2 3)) (lst (list 1 "hi" (vector 1 2 3)))) (memv x lst)) #f) ;;; -------------------------------------------------------------------------------- ;;; member (test (member (list 'a) '(b (a) c)) '((a) c)) (test (member "b" '("a" "c" "b")) '("b")) (test (member 1 '(3 2 1 4)) '(1 4)) (test (member 1 (list 3 2 1 4)) '(1 4)) (test (member car (list abs car modulo)) (list car modulo)) (test (member do (list quote map do)) (list do)) (test (member 5/2 (list 1/3 2/4 5/2)) '(5/2)) (test (member 'a '(a b c d)) '(a b c d)) (test (member 'b '(a b c d)) '(b c d)) (test (member 'c '(a b c d)) '(c d)) (test (member 'd '(a b c d)) '(d)) (test (member 'e '(a b c d)) #f) (test (member 1 (cons 1 2)) '(1 . 2)) (test (member 1 '(1 2 . 3)) '(1 2 . 3)) (test (member 2 '(1 2 . 3)) '(2 . 3)) (test (member 3 '(1 2 . 3)) #f) (test (member 4 '(1 2 . 3)) #f) (test (member 1/2 (list (/ 2.0) .5 1/2)) '(1/2)) (test (member) 'error) (test (member 'a) 'error) (test (member 'a 'b) 'error) (test (member () '(1 2 3)) #f) (test (member () '(1 2 ())) '(())) (test (member #() '(1 () 2 #() 3)) '(#() 3)) (test (member #2d((1 2) (3 4)) '(1 #() #2d((1 2) (1 2)))) #f) (test (member #2d((1 2) (3 4)) '(1 #() #2d((1 2) (3 4)))) '(#2d((1 2) (3 4)))) (test (let ((x (cons 1 2))) (member x (list (cons 1 2) (cons 3 4)))) '((1 . 2) (3 . 4))) (test (let ((x (list 1 2))) (member x (list (cons 1 2) (list 1 2)))) '((1 2))) (test (member ''a '('a b c)) '('a b c)) (test (member 'a '(a a a)) '(a a a)) ;? (test (member 'a '(b a a)) '(a a)) (test (member (member 3 '(1 2 3 4)) '((1 2) (2 3) (3 4) (4 5))) '((3 4) (4 5))) (test (member "hi" '(1 "hi" 2)) '("hi" 2)) (test (member #\a '(1 #f #\a 2)) '(#\a 2)) (test (let* ((x (vector 1 2 3)) (lst (list 1 "hi" x (vector 1 2)))) (member x lst)) '(#(1 2 3) #(1 2))) (test (let* ((x (vector 1 2 3)) (lst (list 1 "hi" (vector 1 2 3)))) (member x lst)) '(#(1 2 3))) (for-each (lambda (arg) (test (member arg (list 1 2 arg 3)) (list arg 3))) (list "hi" (integer->char 65) #f 'a-symbol abs 3/4 #\f #t (if #f #f) '(1 2 (3 (4))) most-positive-fixnum)) (test (member 3 . (1 '(2 3))) 'error) (test (member 3 '(1 2 3) = =) 'error) (test (member 3 . ('(1 2 3))) '(3)) (test (member 3 . ('(1 2 3 . 4))) '(3 . 4)) (test (member . (3 '(1 2 3))) '(3)) (test (member '(1 2) '(1 2)) #f) (test (member '(1 2) '((1 2))) '((1 2))) (test (member . '(quote . ((quote)))) #f) (test (member . '(quote . ((quote) .()))) #f) (test (member '(((1))) '((((1).()).()).())) '((((1))))) (test (member '((1)) '(1 (1) ((1)) (((1))))) '(((1)) (((1))))) (test (member member (list abs car memq member +)) (list member +)) (test (member () () "") 'error) (let ((odd '(3 a 3.0 b 3/4 c #(1) d)) (even '(e 3 a 3.0 b 3/4 c #(1) d))) (test (member 'a odd) '(a 3.0 b 3/4 c #(1) d)) (test (member 'a even) '(a 3.0 b 3/4 c #(1) d)) (test (member 3/4 odd) '(3/4 c #(1) d)) (test (member 3/4 even) '(3/4 c #(1) d)) (test (member 3.0 odd) '(3.0 b 3/4 c #(1) d)) (test (member 3.0 even) '(3.0 b 3/4 c #(1) d)) (test (member #(1) odd) '(#(1) d)) (test (member #(1) even) '(#(1) d))) (test (member 3 '(1 2 3 4) =) '(3 4)) (test (member 3 () =) #f) (test (member 3 '(1 2 4 5) =) #f) (test (member 4.0 '(1 2 4 5) =) '(4 5)) (test (member #\a '(#\b #\A #\c) char=?) #f) (test (member #\a '(#\b #\A #\c) char-ci=?) '(#\A #\c)) (test (member #\a '(#\b #\A #\c) (lambda (a b) (char-ci=? a b))) '(#\A #\c)) (test (char=? (car (member #\a '(#\b #\a))) #\a) #t) (test (char=? (car (member #\a '(#\b #\a) (lambda (a b) (char=? a b)))) #\a) #t) (test (member 3 '(1 2 3 4) <) '(4)) (test (member 3 '((1 2) (3 4)) member) '((3 4))) (test (member 3 '(((1 . 2) (4 . 5)) ((3 . 4))) assoc) '(((3 . 4)))) (test (member '(#f #f #t) '(0 1 2) list-ref) '(2)) (test (let ((v (vector 1 2 3))) (member v (list 0 v) vector-fill!)) '(0 #(0 0 0))) (test (member 3 '(1 2 3) abs) 'error) (test (member 3 '(1 2 3) quasiquote) 'error) (test (member 3 '(1 2 3) (lambda (a b c) (= a b))) 'error) (test (member 3 '(1 2 3) (lambda* (a b c) (= a b))) '(3)) (test (member 3 '(1 2 3 4) (dilambda = =)) '(3 4)) (test (catch #t (lambda () (member 3 '(1 2 3) (lambda (a b) (error 'member a)))) (lambda args (car args))) 'member) (test (call-with-exit (lambda (go) (member 3 '(1 2 3) (lambda (a b) (go 'member))))) 'member) (test (member 'a '(a a a) eq?) '(a a a)) (test (member 'a '(b a a) eqv?) '(a a)) (test (member 3.0 '(1 #\a (3 . 3) abs #() 3+i)) #f) (test (member 3.0 '(1 #\a (3 . 3) abs #() 3+i) (lambda (a b) (= (real-part a) b))) 'error) (test (member 3.0 '(1 #\a (3 . 3) abs #() 3+i) (lambda (a b) (and (number? b) (= (real-part b) a)))) '(3+i)) ;; is it guaranteed that in the comparison function the value is 1st and the list member 2nd? (test (member 4 '((1 2 3) (4 5 6) (7 8 9)) member) '((4 5 6) (7 8 9))) (test (member 4 '(1 2 3) member) 'error) (test (member 4 '((1 2) (3 5) 7) (lambda (a b) (member a (map (lambda (c) (+ c 1)) b)))) '((3 5) 7)) (test (member 4 '((1 2) (3 5) 7) (lambda (a b) (assoc a (map (lambda (c) (cons (+ c 1) c)) b)))) '((3 5) 7)) (test (let ((f #f)) (member 'a '(a b c) (lambda (a b) (if (eq? b 'a) (set! f (lambda () b))) (eq? a 123))) (f)) 'a) (test (let ((i 0) (f (make-vector 3))) (member 'a '(a b c) (lambda (a b) (vector-set! f i b) (set! i (+ i 1)) (eq? a 123))) f) #(a b c)) (test (member 1 '(0 1 2) (lambda (a b . c) (= a b))) '(1 2)) (test (member 1 '(0 1 2) (lambda* (a b c) (= a b))) '(1 2)) (test (member 1 '(0 1 2) (lambda (a) (= a b))) 'error) (test (member 1 '(0 1 2) (lambda a (= (car a) (cadr a)))) '(1 2)) (test (member 'a '(c 3 a 1 b 2) (lambda (a) (eq? a b))) 'error) (test (member 'a '(c 3 a 1 b 2) (lambda (a b) (eq? a b))) '(a 1 b 2)) (test (member 'a '(c 3 a 1 b 2) (lambda (a b c) (eq? a b))) 'error) (test (member 'a '(c 3 a 1 b 2) (lambda (a b c . d) (eq? a b))) 'error) (test (member 'a '(c 3 a 1 b 2) (lambda (a b . c) (eq? a b))) '(a 1 b 2)) (test (member 'a '(c 3 a 1 b 2) (lambda a (apply eq? a))) '(a 1 b 2)) (test (member 'a '(c 3 a 1 b 2) (lambda (a . b) (eq? a (car b)))) '(a 1 b 2)) (test (member 'a '(c 3 a 1 b 2) (lambda* (a) (eq? a b))) 'error) (test (member 'a '(c 3 a 1 b 2) (lambda* (a b) (eq? a b))) '(a 1 b 2)) (test (member 'a '(c 3 a 1 b 2) (lambda* (a b c) (eq? a b))) '(a 1 b 2)) (test (member 'a '(c 3 a 1 b 2) (lambda* (a b c . d) (eq? a b))) '(a 1 b 2)) (test (member 'a '(c 3 a 1 b 2) (lambda* (a b . c) (eq? a b))) '(a 1 b 2)) (test (member 'a '(c 3 a 1 b 2) (lambda* a (apply eq? a))) '(a 1 b 2)) (test (member 'a '(c 3 a 1 b 2) (lambda* (a . b) (eq? a (car b)))) '(a 1 b 2)) (test (member 'a '(c 3 a 1 b 2) (lambda* (a :rest b) (eq? a (car b)))) '(a 1 b 2)) (test (member 'a '(c 3 a 1 b 2) (lambda* (a :rest b :rest c) (eq? a (car b)))) '(a 1 b 2)) (test (member 'a '(c 3 a 1 b 2) (lambda* (:rest a) (apply eq? a))) '(a 1 b 2)) (test (member 'a '(a b c) (define-macro (_m_ a b) `(eq? ',a ',b))) '(a b c)) (test (member 'c '(a b c) (define-macro (_m_ a b) `(eq? ',a ',b))) '(c)) (test (member 4 '(1 2 3 4 . 5)) '(4 . 5)) (test (member 4 '(1 2 3 4 . 5) =) '(4 . 5)) (test (member 4 '(1 2 3 . 4)) #f) (test (member 4 '(1 2 3 . 4) =) #f) (test (let ((lst (list 1 2 3))) (and (member 2 lst =) lst)) '(1 2 3)) (test (pair? (let ((lst (list 1 2 3))) (set! (cdr (cdr lst)) lst) (member 2 lst))) #t) (test (pair? (let ((lst (list 1 2 3))) (set! (cdr (cdr lst)) lst) (member 2 lst =))) #t) (test (let ((lst (list 1 2 3))) (set! (cdr (cdr lst)) lst) (member 4 lst)) #f) (test (let ((lst (list 1 2 3))) (set! (cdr (cdr lst)) lst) (member 4 lst =)) #f) (test (pair? (let ((lst (list 1 2 3))) (set! (cdr (cdr (cdr lst))) lst) (member 3 lst =))) #t) (test (pair? (let ((lst (list 1 2 3 4))) (set! (cdr (cdr (cdr lst))) (cdr (cdr lst))) (member 3 lst =))) #t) (test (let ((lst (list 1 2 3 4))) (set! (cdr (cdr (cdr lst))) (cdr (cdr lst))) (member 5 lst =)) #f) (test (let ((lst (list 1 2 3 4))) (set! (cdr (cdr (cdr lst))) (cdr lst)) (member 4 lst =)) #f) (test (let ((lst '(1 2 3 5 6 9 10))) (member 3 lst (let ((last (car lst))) (lambda (a b) (let ((result (= (- b last) a))) (set! last b) result))))) '(9 10)) (test (let ((lst '(1 2 3 5 6 9 10))) (member 2 lst (let ((last (car lst))) (lambda (a b) (let ((result (= (- b last) a))) (set! last b) result))))) '(5 6 9 10)) (test (member 1 () =) #f) (test (member 1 #(1) =) 'error) (test (member 3 '(5 4 3 2 1) >) '(2 1)) (test (member 3 '(5 4 3 2 1) >=) '(3 2 1)) (test (member '(1 2) '((1) (1 . 2) (1 2 . 3) (1 2 3) (1 2) 1 . 2)) '((1 2) 1 . 2)) (test (member '(1 2 . 3) '((1) (1 . 2) (1 2 . 3) (1 2 3) (1 2) 1 . 2)) '((1 2 . 3) (1 2 3) (1 2) 1 . 2)) (let () (define (sfind obj lst) (member obj lst (lambda (a b) (catch #t (lambda () (and (equal? a b) (member obj lst (lambda (a b) (catch #t (lambda () (error 'oops)) (lambda args (equal? a b))))))) (lambda args 'oops))))) (test (sfind 'a '(b c a d)) '(a d))) (let () (define-macro (do-list lst . body) `(member #t ,(cadr lst) (lambda (a b) (let ((,(car lst) b)) ,@body #f)))) (let ((sum 0)) (do-list (x '(1 2 3)) (set! sum (+ sum x))) (test (= sum 6) #t))) (let () (define (tree-member a lst) (member a lst (lambda (c d) (if (pair? d) (tree-member c d) (equal? c d))))) (test (tree-member 1 '(2 3 (4 1) 5)) '((4 1) 5)) (test (tree-member -1 '(2 3 (4 1) 5)) #f) (test (tree-member 1 '(2 3 ((4 (1) 5)))) '(((4 (1) 5))))) (let ((lst (list 1 2 3))) (set! (cdr (cdr (cdr lst))) lst) (test (member 2 lst) (member 2 lst equal?))) (let ((lst (list 1 2 3))) (set! (cdr (cdr (cdr lst))) lst) (test (member 4 lst) (member 4 lst equal?))) (let ((lst (list 1 2 3 4))) (set! (cdr (cdr (cdr (cdr lst)))) lst) (test (member 4 lst) (member 4 lst equal?))) (let ((lst (list 1 2 3 4))) (set! (cdr (cdr (cdr (cdr lst)))) (cdr lst)) (test (member 4 lst) (member 4 lst equal?))) (for-each (lambda (arg lst) (test (member arg lst eq?) (memq arg lst)) (test (member arg lst eqv?) (memv arg lst)) (test (member arg lst equal?) (member arg lst))) (list 'a #f (list 'a) 'a 1 3/4 #(1) "hi") (list '(a b c) '(1 "hi" #t #f 2) '(b (a) c) '(d a b . c) '(1 3/4 23) '(1 3/4 23) '(a 1 #(1) 23) '(1 "hi" 23))) (for-each (lambda (op) (test (op) 'error) (for-each (lambda (arg) (let ((result (catch #t (lambda () (op arg)) (lambda args 'error)))) (if (not (eq? result 'error)) (format-logged #t ";(~A ~A) returned ~A?~%" op arg result)) (test (op arg () arg) 'error) (test (op arg) 'error))) (list () "hi" (integer->char 65) #f 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #\f #t :hi (if #f #f) (lambda (a) (+ a 1))))) (list cons car cdr set-car! set-cdr! caar cadr cdar cddr caaar caadr cadar cdaar caddr cdddr cdadr cddar caaaar caaadr caadar cadaar caaddr cadddr cadadr caddar cdaaar cdaadr cdadar cddaar cdaddr cddddr cddadr cdddar assq assv memq memv list-ref list-tail)) (for-each (lambda (op) (test (op '(1) '(2)) 'error)) (list reverse car cdr caar cadr cdar cddr caaar caadr cadar cdaar caddr cdddr cdadr cddar caaaar caaadr caadar cadaar caaddr cadddr cadadr caddar cdaaar cdaadr cdadar cddaar cdaddr cddddr cddadr cdddar list-ref list-tail list-set!)) (for-each (lambda (op) (for-each (lambda (arg) (let ((result (catch #t (lambda () (op #f arg)) (lambda args 'error)))) (if (not (eq? result 'error)) (format-logged #t ";(~A #f ~A) returned ~A?~%" op arg result)))) (list "hi" (integer->char 65) #f 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #\f #t :hi (if #f #f) (lambda (a) (+ a 1))))) (list assq assv assoc memq memv member)) ;;; -------------------------------------------------------------------------------- ;;; append (test (append '(a b c) ()) '(a b c)) (test (append () '(a b c)) '(a b c)) (test (append '(a b) '(c d)) '(a b c d)) (test (append '(a b) 'c) '(a b . c)) (test (equal? (append (list 'a 'b 'c) (list 'd 'e 'f) () '(g)) '(a b c d e f g)) #t) (test (append (list 'a 'b 'c) (list 'd 'e 'f) () (list 'g)) '(a b c d e f g)) (test (append (list 'a 'b 'c) 'd) '(a b c . d)) (test (append () ()) ()) (test (append () (list 'a 'b 'c)) '(a b c)) (test (append) ()) (test (append () 1) 1) (test (append 'a) 'a) (test (append '(x) '(y)) '(x y)) (test (append '(a) '(b c d)) '(a b c d)) (test (append '(a (b)) '((c))) '(a (b) (c))) (test (append '(a b) '(c . d)) '(a b c . d)) (test (append () 'a) 'a) (test (append '(a b) (append (append '(c)) '(e) 'f)) '(a b c e . f)) (test (append ''foo 'foo) '(quote foo . foo)) (test (append () (cons 1 2)) '(1 . 2)) (test (append () () ()) ()) (test (append (cons 1 2)) '(1 . 2)) (test (append #f) #f) (test (append () #f) #f) (test (append '(1 2) #f) '(1 2 . #f)) (test (append () () #f) #f) (test (append () '(1 2) #f) '(1 2 . #f)) (test (append '(1 2) () #f) '(1 2 . #f)) (test (append '(1 2) '(3 4) #f) '(1 2 3 4 . #f)) (test (append () () () #f) #f) (test (append '(1 2) '(3 4) '(5 6) #f) '(1 2 3 4 5 6 . #f)) (test (append () () #()) #()) (test (append () ((lambda () #f))) #f) (test (append (begin) do) do) (test (append if) if) (test (append quote) quote) (test (append 0) 0) ; is this correct? (test (append () 0) 0) (test (append () () 0) 0) (test (let* ((x '(1 2 3)) (y (append x ()))) (eq? x y)) #f) ; check that append returns a new list (test (let* ((x '(1 2 3)) (y (append x ()))) (equal? x y)) #t) (test (let* ((x (list 1 2 3)) (y (append x (list)))) (eq? x y)) #f) (test (append '(1) 2) '(1 . 2)) (let ((x (list 1 2 3))) (let ((y (append x ()))) (set-car! x 0) (test (= (car y) 1) #t))) (let ((x (list 1 2 3))) (let ((y (append x ()))) (set-cdr! x 0) (test (and (= (car y) 1) (= (cadr y) 2) (= (caddr y) 3)) #t))) (test (let ((xx (list 1 2))) (recompose 12 (lambda (x) (append (list (car x)) (cdr x))) xx)) '(1 2)) (test (append 'a 'b) 'error) (test (append 'a ()) 'error) (test (append (cons 1 2) ()) 'error) (test (append '(1) 2 '(3)) 'error) (test (append '(1) 2 3) 'error) (test (let ((lst (list 1 2 3))) (append lst lst)) '(1 2 3 1 2 3)) (test (append ''1 ''1) '(quote 1 quote 1)) (test (append '(1 2 . 3) '(4)) 'error) (test (append '(1 2 . 3)) '(1 2 . 3)) (test (append '(4) '(1 2 . 3)) '(4 1 2 . 3)) (test (append () 12 . ()) 12) (test (append '(1) 12) '(1 . 12)) (test (append '(1) 12 . ()) '(1 . 12)) (test (append () () '(1) 12) '(1 . 12)) (test (append '(1) '(2) '(3) 12) '(1 2 3 . 12)) (test (append '(((1))) '(((2)))) '(((1)) ((2)))) (test (append () . (2)) 2) (test (append . (2)) 2) (test (append ''() ()) ''()) (test (let ((i 1)) (logior 123 (append i))) 123) ; ! (for-each (lambda (arg) (test (append arg) arg) (test (append () arg) arg) (test (append () () () arg) arg)) (list "hi" #\a #f 'a-symbol _ht_ _null_ (make-vector 3) abs 1 3.14 3/4 1.0+1.0i #t # # () #() (list 1 2) (cons 1 2) #(0) (lambda (a) (+ a 1)))) (test (append not) not) (test (let ((l0 (list 0)) (l1 (list 0))) (let ((m0 (append '(2) l0)) (m1 (append '(2) l1 '()))) (and (equal? l0 l1) (equal? m0 m1) (let () (list-set! m0 1 3) (list-set! m1 1 3) (list l0 l1))))) '((3) (0))) ;;; generic append (test (append "asdasd" '("asd")) 'error) (test (append "asdasd" #("asd")) 'error) (test (append (->byte-vector "asdasd") '("asd")) 'error) (test (append (->byte-vector "asdasd") #("asd")) 'error) (test (let ((h1 (hash-table* 'a 1 'b 2)) (h2 (hash-table* 'c 3))) (append h1 h2)) (hash-table '(c . 3) '(a . 1) '(b . 2))) (test (let ((i1 (inlet 'a 1)) (i2 (inlet 'b 2 'c 3))) (append i1 i2)) (inlet 'a 1 'c 3 'b 2)) (test (let ((s1 "abc") (s2 "def")) (append s1 s2)) "abcdef") (test (let ((v1 #(0 1)) (v2 #(2 3))) (append v1 v2)) #(0 1 2 3)) (test (let ((p1 '(1 2)) (p2 '(3 4))) (append p1 p2)) '(1 2 3 4)) (test (vector? (append #())) #t) (test (float-vector? (append (float-vector))) #t) (test (int-vector? (append (int-vector))) #t) (test (append "12" '(1 . 2) "3") 'error) (for-each (lambda (arg) (test (append arg) arg) (test (append () arg) arg)) (list "" #u8() () #() (int-vector) (float-vector) (inlet) (hash-table) "123" #u8(101 102) '(1 2 3) '((e . 5) (f . 6)) #(1 2 3) #((g . 8) (h . 9)) (int-vector 1 2 3) (float-vector 1 2 3) (inlet 'a 1 'b 2) (hash-table* 'c 3 'd 4))) (test (append #u8() (int-vector 1 2 3)) #u8(1 2 3)) (test (append #u8() "123") #u8(49 50 51)) (test (append "" "123") "123") (test (append #() (hash-table)) #()) (test (append #() #u8(101 102)) #(101 102)) (test (append (float-vector) #u8(101 102)) (float-vector 101.0 102.0)) (test (append (int-vector) #u8(101 102)) (int-vector 101 102)) (test (append (hash-table) '((e . 5) (f . 6))) (hash-table '(e . 5) '(f . 6))) (test (append (inlet) #((g . 8) (h . 9))) (inlet 'g 8 'h 9)) (test (append '(1 2 3) #u8()) '(1 2 3)) (test (append '(1 2 3) #u8(101 102)) '(1 2 3 101 102)) (test (append '(1 2 3) (inlet 'a 1 'b 2)) '(1 2 3 (b . 2) (a . 1))) (test (let ((lst (append '((e . 5) (f . 6)) (hash-table '(c . 3) '(d . 4))))) (or (equal? lst '((e . 5) (f . 6) (c . 3) (d . 4))) (equal? lst '((e . 5) (f . 6) (d . 4) (c . 3))))) #t) (test (append #(1 2 3) "123") #(1 2 3 #\1 #\2 #\3)) (test (append (int-vector 1 2 3) #(1 2 3)) (int-vector 1 2 3 1 2 3)) (test (append (int-vector 1 2 3) "123") (int-vector 1 2 3 49 50 51)) (test (append (float-vector 1.0 2.0 3.0) (int-vector 1 2 3)) (float-vector 1.0 2.0 3.0 1.0 2.0 3.0)) (test (append (int-vector 1 2 3) (float-vector 1.0 2.0 3.0)) (int-vector 1 2 3 1 2 3)) (test (append (inlet 'a 1 'b 2) '((e . 5) (f . 6))) (inlet 'b 2 'a 1 'e 5 'f 6)) (test (append (inlet 'a 1 'b 2) (hash-table '(c . 3) '(d . 4))) (inlet 'b 2 'a 1 'c 3 'd 4)) (test (append "" #() #u8(101 102)) "ef") (test (append "" #u8(101 102) (hash-table)) "ef") (test (append #u8() #() #u8(101 102)) #u8(101 102)) (test (append #u8() (inlet) "") #u8()) (test (append #u8() #u8(101 102) "123") #u8(101 102 49 50 51)) (test (append () "" (int-vector 1 2 3)) (int-vector 1 2 3)) (test (let ((v (append #() #u8() (hash-table '(c . 3) '(d . 4))))) (or (equal? v #((c . 3) (d . 4))) (equal? v #((d . 4) (c . 3))))) #t) (test (append #() #(1 2 3) (inlet)) #(1 2 3)) (test (append #() (float-vector 1.0 2.0 3.0) ()) #(1.0 2.0 3.0)) (test (append (float-vector) "" "123") (float-vector 49.0 50.0 51.0)) (test (append (float-vector) (int-vector 1 2 3) #u8(101 102)) (float-vector 1.0 2.0 3.0 101.0 102.0)) (test (append (inlet) #() #((g . 8) (h . 9))) (inlet 'g 8 'h 9)) (test (append (inlet) '((e . 5) (f . 6)) (hash-table '(c . 3) '(d . 4))) (inlet 'e 5 'f 6 'c 3 'd 4)) (test (append (hash-table) "" (inlet 'a 1 'b 2)) (hash-table '(b . 2) '(a . 1))) (test (append (hash-table) '((e . 5) (f . 6)) (inlet 'a 1 'b 2)) (hash-table '(b . 2) '(e . 5) '(f . 6) '(a . 1))) (test (append (hash-table) #((g . 8) (h . 9)) '((e . 5) (f . 6))) (hash-table '(e . 5) '(g . 8) '(f . 6) '(h . 9))) (test (append "123" #u8(101 102) (hash-table)) "123ef") (test (append #u8(101 102) #u8() #u8(101 102)) #u8(101 102 101 102)) (test (append #u8(101 102) "123" (int-vector 1 2 3)) #u8(101 102 49 50 51 1 2 3)) (test (append #u8(101 102) '(1 2 3) "") #u8(101 102 1 2 3)) (test (append '(1 2 3) #u8(101 102) #(1 2 3)) '(1 2 3 101 102 1 2 3)) (test (let ((lst (append '(1 2 3) (hash-table '(c . 3) '(d . 4)) ""))) (or (equal? lst '(1 2 3 (c . 3) (d . 4))) (equal? lst '(1 2 3 (d . 4) (c . 3))))) #t) (test (append (int-vector 1 2 3) #u8(101 102) (float-vector 1.0 2.0 3.0)) (int-vector 1 2 3 101 102 1 2 3)) (test (append (int-vector 1 2 3) '(1 2 3) #u8(101 102)) (int-vector 1 2 3 1 2 3 101 102)) (test (append (hash-table '(c . 3) '(d . 4)) (hash-table '(c . 3) '(d . 4)) '((e . 5) (f . 6))) (hash-table '(e . 5) '(f . 6) '(c . 3) '(d . 4))) (when with-block (test (append (block 1 2) (block 3 4)) (block 1 2 3 4))) (test (random-state? (cdr (append '(1) (random-state 123)))) #t) (test (append '(1) (random-state 123) ()) 'error) (test (random-state? (append () (random-state 123))) #t) (when full-test (let ((seqs (list "" #u8() () #() (int-vector) (float-vector) (inlet) (hash-table) "123" #u8(101 102) '(1 2 3) '((e . 5) (f . 6)) #(1 2 3) #((g . 8) (h . 9)) (int-vector 1 2 3) (float-vector 1 2 3) (inlet 'a 1 'b 2) (hash-table* 'c 3 'd 4) 1 #f '(1 . 2) (let ((lst (list 1))) (set-cdr! lst lst))))) (define (test-append) (for-each (lambda (s1) (catch #t (lambda () (append s1) (for-each (lambda (s2) (catch #t (lambda () (append s1 s2) (for-each (lambda (s3) (catch #t (lambda () (append s1 s2 s3) (for-each (lambda (s4) (catch #t (lambda () (append s1 s2 s3 s4) (for-each (lambda (s5) (catch #t (lambda () (append s1 s2 s3 s4 s5)) (lambda args 'error))) seqs)) (lambda args 'error))) seqs)) (lambda args 'error))) seqs)) (lambda args 'error))) seqs)) (lambda args 'error))) seqs)) (test-append))) ;;; -------------------------------------------------------------------------------- ;;; VECTORS ;;; -------------------------------------------------------------------------------- ;;; -------------------------------------------------------------------------------- ;;; vector? (test (vector? (make-vector 6)) #t) (test (vector? (make-vector 6 #\a)) #t) (test (vector? (make-vector 0)) #t) ;; (test (vector? #*1011) #f) (test (vector? #(0 (2 2 2 2) "Anna")) #t) (test (vector? #()) #t) (test (vector? #("hi")) #t) (test (vector? (vector 1)) #t) (test (let ((v (vector 1 2 3))) (vector? v)) #t) (for-each (lambda (arg) (test (vector? arg) #f)) (list #\a 1 () (list 1) '(1 . 2) #f "hi" 'a-symbol abs _ht_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t :hi (if #f #f) (lambda (a) (+ a 1)))) (test (vector?) 'error) (test (vector? #() #(1)) 'error) (test (vector? begin) #f) (test (vector? vector?) #f) ;;; make a shared ref -- we'll check it later after enough has happened that an intervening GC is likely (define check-shared-vector-after-gc #f) (let ((avect (make-vector '(6 6) 32))) (do ((i 0 (+ i 1))) ((= i 6)) (do ((j 0 (+ j 1))) ((= j 6)) (set! (avect i j) (cons i j)))) (set! check-shared-vector-after-gc (avect 3))) (test (vector? (make-vector 3 1 #t)) #t) (if (not with-bignums) (test (vector? (make-vector 3 pi #t)) #t)) (test (vector? (make-vector 3 pi #f)) #t) (test (vector? (make-shared-vector (make-int-vector '(2 3)) '(3 2))) #t) ;;; -------------------------------------------------------------------------------- ;;; make-vector (test (let ((v (make-vector 3 #f))) (and (vector? v) (= (vector-length v) 3) (eq? (vector-ref v 1) #f))) #t) (test (let ((v (make-vector 1 1))) (and (vector? v) (= (vector-length v) 1) (vector-ref v 0))) 1) (test (let ((v (make-vector 0 1))) (and (vector? v) (= (vector-length v) 0))) #t) (test (do ((vec (make-vector 5)) (i 0 (+ i 1))) ((= i 5) vec) (vector-set! vec i i)) #(0 1 2 3 4)) (test (let ((v (make-vector 5))) (for-each (lambda (i) (vector-set! v i (* i i))) '(0 1 2 3 4)) v) #(0 1 4 9 16)) (test (make-vector 2 'hi) #(hi hi)) (test (make-vector 0) #()) (test (make-vector -0) #()) (test (make-vector 0 'hi) #()) (test (make-vector 3 (make-vector 1 'hi)) #(#(hi) #(hi) #(hi))) (test (make-vector 3 #(hi)) #(#(hi) #(hi) #(hi))) (test (make-vector 9/3 (list)) #(() () ())) (test (make-vector 3/1 (make-vector 1 (make-vector 1 'hi))) #(#(#(hi)) #(#(hi)) #(#(hi)))) (test (make-vector 0 0.0 #t) #()) (test (make-vector 0 0.0) #()) (test (let ((v (make-vector 3 0))) (set! (vector-ref v 1) 32) v) #(0 32 0)) (test (let ((v (make-int-vector 3))) (set! (vector-ref v 1) 0) v) (make-int-vector 3 0)) (for-each (lambda (arg) (test (vector-ref (make-vector 1 arg) 0) arg)) (list #\a 1 () (list 1) '(1 . 2) #f "hi" 'a-symbol abs _ht_ _null_ _c_obj_ quasiquote macroexpand (log 0) 3.14 3/4 1.0+1.0i #t (vector 1 2 3) (lambda (a) (+ a 1)))) (test (make-vector) 'error) (test (make-vector 1 #f #t) 'error) (test (make-vector 1 2 3) 'error) (test (make-vector most-positive-fixnum) 'error) (test (make-vector most-negative-fixnum) 'error) (test (make-vector '(2 -2)) 'error) (test (make-vector (list 2 -2 -3)) 'error) (test (make-vector (cons 2 3)) 'error) (test (make-vector '(2 3 . 4)) 'error) (test (make-vector '(2 (3))) 'error) (test (make-vector most-negative-fixnum) 'error) (test (make-vector 3 0 #f 1) 'error) (for-each (lambda (arg) (test (make-vector arg) 'error) (test (make-vector (list 2 arg)) 'error)) (list #\a () -1 #f "hi" 'a-symbol abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t (vector 1 2 3) (lambda (a) (+ a 1)))) (test (eval-string "#2147483649D()") 'error) (test (eval-string "#-9223372036854775808D()") 'error) (test (eval-string "#922D()") 'error) ;;; make-shared-vector (test (let ((v1 #2d((1 2 3) (4 5 6)))) (let ((v2 (make-shared-vector v1 '(6)))) v2)) #(1 2 3 4 5 6)) (test (let ((v1 #(1 2 3 4 5 6))) (let ((v2 (make-shared-vector v1 '(3 2)))) v2)) #2D((1 2) (3 4) (5 6))) (test (make-shared-vector #2d() '(0)) #()) (test (make-shared-vector '(1) '(1)) 'error) (test (make-shared-vector #(1) '(2)) 'error) (test (make-shared-vector #(1) '(1 2)) 'error) (test (make-shared-vector #(1 2 3 4) ()) 'error) (test (make-shared-vector #(1 2 3 4) most-positive-fixnum) 'error) (test (make-shared-vector #(1 2 3 4) most-negative-fixnum) 'error) (test (make-shared-vector #(1 2 3 4) -1) 'error) (test (make-shared-vector #(1 2 3 4) 5) 'error) (test (make-shared-vector #(1 2 3 4) 0) #()) (test (make-shared-vector #(1 2 3 4) '(2)) #(1 2)) (test (make-shared-vector #(1 2 3 4) '(2 1)) #2D((1) (2))) (test (make-shared-vector #(1 2 3 4) '(0)) #()) (for-each (lambda (arg) (test (make-shared-vector arg) 'error) (test (make-shared-vector #(1 2 3) arg) 'error)) (list #\a () -1 #f "hi" 'a-symbol abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t (vector 1 2 3) (lambda (a) (+ a 1)))) (let ((v #2d((1 2) (3 4)))) (test (make-shared-vector v '((1 2) (3 4))) 'error) (test (make-shared-vector v ()) 'error) (test (make-shared-vector v '(1.4)) 'error) (test (make-shared-vector v '(14 15)) 'error) (test (make-shared-vector v (list most-positive-fixnum)) 'error) (test (make-shared-vector v '(-1 0)) 'error) (test (make-shared-vector v '(1) most-positive-fixnum) 'error)) (let ((v (float-vector 0.0 1.0 2.0))) (let ((v1 (make-shared-vector v (list 1 3)))) (test (float-vector? v1) #t) (test (morally-equal? (v 0) (v1 0 0)) #t))) (let ((v (int-vector 0 1 2))) (let ((v1 (make-shared-vector v (list 1 3)))) (test (int-vector? v1) #t) (test (morally-equal? (v 0) (v1 0 0)) #t))) (let ((v (make-int-vector 3))) (set! (v 1) 1) (set! (v 2) 2) (let ((v1 (make-shared-vector v (list 1 3)))) (test (float-vector? v1) #f) (test (int-vector? v1) #t) (test (integer? (v1 0 2)) #t) (test (= (v 2) (v1 0 2)) #t))) (let ((v (vector 0 1 2 3 4 5 6 7 8))) (test (make-shared-vector v (list 3 2) 1) #2D((1 2) (3 4) (5 6))) (test (make-shared-vector v (list 3 2) 2) #2D((2 3) (4 5) (6 7))) (test (make-shared-vector v (list 3) 2) #(2 3 4)) (test (make-shared-vector v (list 3) 0) (make-shared-vector v (list 3))) (test (make-shared-vector v (list 3) -1) 'error) (test (make-shared-vector v (list 3) 10) 'error) (test (make-shared-vector v (list 3) 3.2) 'error) (test (make-shared-vector v (list 3) "0") 'error) ) (test (make-shared-vector (make-shared-vector (float-vector 1.0 2.0 3.0 4.0) '(2 2)) '(0)) #()) (test (make-shared-vector (make-shared-vector (float-vector 1.0 2.0 3.0 4.0) '(2 2)) '(1)) (float-vector 1.0)) (test ((make-shared-vector (make-shared-vector (float-vector 1.0 2.0 3.0 4.0) '(2 2)) '(4 1)) 2 0) 3.0) (if with-bignums (let ((v (float-vector (bignum "1.0") (bignum "2.0")))) (test (float-vector? v) #t) (test (v 0) 1.0))) (test (vector? (float-vector)) #t) (test (vector? (int-vector)) #t) (when with-block (test (float-vector? _c_obj_) #t)) (test (float-vector? 1 2) 'error) (test (float-vector?) 'error) (test (int-vector? 1 2) 'error) (test (int-vector?) 'error) (for-each (lambda (arg) (if (float-vector? arg) (format *stderr* ";~A is a float-vector?~%" arg)) (test (float-vector arg) 'error) (if (int-vector? arg) (format *stderr* ";~A is an int-vector?~%" arg)) (test (int-vector arg) 'error)) (list #\a () #f "hi" 'a-symbol abs _ht_ _null_ quasiquote macroexpand #() #t (vector 1 2 3) (lambda (a) (+ a 1)))) ;;; make-float-vector (test (float-vector? (make-float-vector 3)) #t) (test (float-vector? (make-float-vector 3 pi)) #t) (test ((make-float-vector 3) 1) 0.0) (test (float-vector? (float-vector)) #t) (test (float-vector? (make-float-vector 0)) #t) (test (float-vector? (int-vector)) #f) (test (equal? (float-vector) (int-vector)) #t) (test (equal? (vector) (int-vector)) #t) (test (equal? (make-float-vector 3 1.0) (float-vector 1.0 1.0 1.0)) #t) (test ((make-float-vector '(2 3) 2.0) 1 2) 2.0) (test (nan? ((make-float-vector 3 1/0) 0)) #t) (for-each (lambda (arg) (test (make-float-vector arg) 'error) (test (make-float-vector 3 arg) 'error)) (list #\a () #f "hi" 'a-symbol abs _ht_ _null_ _c_obj_ quasiquote macroexpand (log 0) 1.0+1.0i #t (vector 1 2 3) (lambda (a) (+ a 1)))) (test (equal? (vector) (float-vector)) #t) (test (float-vector? (make-float-vector 3 0)) #t) (test (float-vector? (make-float-vector 3 1/2)) #t) ;;; make-int-vector (test (int-vector? (make-int-vector 3)) #t) (test (int-vector? (make-int-vector 3 2)) #t) (test ((make-int-vector 3) 1) 0) (test (int-vector? (int-vector)) #t) (test (int-vector? (make-int-vector 0)) #t) (test (int-vector? (float-vector)) #f) (test (int-vector? (vector)) #f) (test (equal? (make-int-vector 3 1) (int-vector 1 1 1)) #t) (test ((make-int-vector '(2 3) 2) 1 2) 2) (for-each (lambda (arg) (test (make-int-vector arg) 'error) (test (make-int-vector 3 arg) 'error)) (list #\a () #f "hi" 'a-symbol abs _ht_ _null_ _c_obj_ quasiquote macroexpand (log 0) 1.0+1.0i 1/2 pi #t (vector 1 2 3) (lambda (a) (+ a 1)))) (test (equal? (vector) (int-vector)) #t) ;;; float-vector-ref ;;; float-vector-set! (test (float-vector-ref (float-vector 1.0 2.0) 1) 2.0) (for-each (lambda (arg) (test (float-vector-ref arg 0) 'error) (test (float-vector-ref (float-vector 1.0) arg) 'error)) (list #\a () #f "hi" 'a-symbol abs _ht_ _null_ _c_obj_ quasiquote macroexpand (log 0) 1.0+1.0i #t (vector 1 2 3) (lambda (a) (+ a 1)))) (let ((v (make-float-vector (list 2 3) 1.0)) (v1 (make-float-vector 3))) (set! (v 1 1) 2.0) (test (v 1 1) 2.0) (test (v 0 1) 1.0) (test (float-vector-ref v 1 1) 2.0) (test (float-vector-ref v 0) (float-vector 1.0 1.0 1.0)) (test (float-vector-set! v 0 0 3.0) 3.0) (test (float-vector-ref v 0 0) 3.0) (test (float-vector-ref v1 3) 'error) (test (float-vector-ref v 1 3) 'error) (test (float-vector-ref v 2 2) 'error) (test (float-vector-ref v1 most-positive-fixnum) 'error) (test (float-vector-ref v1 most-negative-fixnum) 'error) (test (float-vector-set! v1 3 0.0) 'error) (test (float-vector-set! v 1 3 0.0) 'error) (test (float-vector-set! v 2 2 0.0) 'error) (test (float-vector-set! v1 most-positive-fixnum 0.0) 'error) (test (float-vector-set! v1 most-negative-fixnum 0.0) 'error) (test (float-vector-set! v1 0 0+i) 'error) (for-each (lambda (arg) (test (float-vector-ref v 0 arg) 'error) (test (float-vector-set! arg 0 1.0) 'error) (test (float-vector-set! v1 arg) 'error) (test (float-vector-set! v1 0 arg) 'error) (test (float-vector-set! v 0 arg 1.0) 'error)) (list #\a () #f "hi" 1+i 'a-symbol abs _ht_ _null_ _c_obj_ quasiquote macroexpand #t (vector 1 2 3) (lambda (a) (+ a 1)))) (test (float-vector-ref v) 'error) (test (float-vector-set! v) 'error) (test (float-vector-ref v1 0 1) 'error) (test (float-vector-ref v 0 1 0) 'error) (test (float-vector-ref v1 -1) 'error) (float-vector-set! v1 0 2/5) (test (float-vector-ref v1 0) 0.4) (test (float-vector-set! v1 1 4) 4) (test (float-vector-ref v1 1) 4.0) (test (float-vector-ref v 3 0) 'error) (test (float-vector-ref v 1 3) 'error) (test (fill! v 0.0) 0.0)) (test (float-vector-ref (float-vector) 0) 'error) (let ((v (float-vector 1 2 3))) (set! (float-vector-ref v 1) 32) (test v (float-vector 1 32 3)) (set! (v 0) 64) (test v (float-vector 64 32 3)) (test (float-vector-set! v 2 (float-vector-set! v 1 0.0)) 0.0) (test v (float-vector 64 0 0))) (let ((v0 (make-float-vector '(3 0))) (v1 (make-float-vector '(0 3))) (v2 (make-float-vector '(2 3))) (v3 (make-float-vector '(1 3))) (v4 (make-float-vector '(3 1)))) (test (float-vector? v0) #t) (test (float-vector-ref v0 0 0) 'error) (test (vector? v0) #t) (test (vector-ref v0 0 0) 'error) (test (v0 0 0) 'error) (test (float-vector? v1) #t) (test (float-vector-ref v1 0 0) 'error) (test (vector? v1) #t) (test (vector-ref v1 0 0) 'error) (test (v1 0 0) 'error) (test (equal? v0 v1) #f) (test (float-vector? (float-vector-ref v2 1)) #t) (test (float-vector-set! v2 1 32.0) 'error) (test (float-vector-set! (float-vector-ref v2 1) 1 32.0) 32.0) (test (float-vector-ref v2 1 1) 32.0) (test (float-vector-ref v3 0) (float-vector 0 0 0)) (test (float-vector-ref v4 0) (float-vector 0)) ) (let () (define (hi) (let ((v2 (make-float-vector '(2 3)))) (float-vector-set! v2 1 12.0) v2)) (test (hi) 'error)) ;;; int-vector-ref ;;; int-vector-set! (test (int-vector-ref (int-vector 1 2) 1) 2) (for-each (lambda (arg) (test (int-vector-ref arg 0) 'error) (test (int-vector-ref (int-vector 1) arg) 'error)) (list #\a () #f "hi" 'a-symbol abs _ht_ _null_ _c_obj_ quasiquote macroexpand (log 0) 1.0+1.0i #t (vector 1 2 3) (lambda (a) (+ a 1)))) (let ((v (make-int-vector (list 2 3) 1)) (v1 (make-int-vector 3))) (set! (v 1 1) 2) (test (v 1 1) 2) (test (v 0 1) 1) (test (int-vector-ref v 1 1) 2) (test (int-vector-ref v 0) (int-vector 1 1 1)) (test (int-vector-set! v 0 0 3) 3) (test (int-vector-ref v 0 0) 3) (test (int-vector-ref v1 3) 'error) (test (int-vector-ref v 1 3) 'error) (test (int-vector-ref v 2 2) 'error) (test (int-vector-ref v1 most-positive-fixnum) 'error) (test (int-vector-ref v1 most-negative-fixnum) 'error) (test (int-vector-set! v1 3 0) 'error) (test (int-vector-set! v 1 3 0) 'error) (test (int-vector-set! v 2 2 0) 'error) (test (int-vector-set! v1 most-positive-fixnum 0) 'error) (test (int-vector-set! v1 most-negative-fixnum 0) 'error) (test (int-vector-set! v1 0 0+i) 'error) (for-each (lambda (arg) (test (int-vector-ref v 0 arg) 'error) (test (int-vector-set! arg 0 1) 'error) (test (int-vector-set! v1 arg) 'error) (test (int-vector-set! v1 0 arg) 'error) (test (int-vector-set! v 0 arg 1) 'error)) (list #\a () #f "hi" 1+i 'a-symbol abs _ht_ _null_ _c_obj_ quasiquote macroexpand #t (vector 1 2 3) (lambda (a) (+ a 1)))) (test (int-vector-ref v) 'error) (test (int-vector-set! v) 'error) (test (int-vector-ref v1 0 1) 'error) (test (int-vector-ref v 0 1 0) 'error) (test (int-vector-ref v1 -1) 'error) (int-vector-set! v1 0 2) (test (int-vector-ref v1 0) 2) (test (int-vector-set! v1 1 4) 4) (test (int-vector-ref v1 1) 4) (test (int-vector-ref v 3 0) 'error) (test (int-vector-ref v 1 3) 'error) (test (fill! v 0) 0)) (test (int-vector-ref (int-vector) 0) 'error) (let ((v (int-vector 1 2 3))) (set! (int-vector-ref v 1) 32) (test v (int-vector 1 32 3)) (set! (v 0) 64) (test v (int-vector 64 32 3)) (test (int-vector-set! v 2 (int-vector-set! v 1 0)) 0) (test v (int-vector 64 0 0))) (let ((v0 (make-int-vector '(3 0))) (v1 (make-int-vector '(0 3))) (v2 (make-int-vector '(2 3))) (v3 (make-int-vector '(1 3))) (v4 (make-int-vector '(3 1)))) (test (int-vector? v0) #t) (test (int-vector-ref v0 0 0) 'error) (test (vector? v0) #t) (test (vector-ref v0 0 0) 'error) (test (v0 0 0) 'error) (test (int-vector? v1) #t) (test (int-vector-ref v1 0 0) 'error) (test (vector? v1) #t) (test (vector-ref v1 0 0) 'error) (test (v1 0 0) 'error) (test (equal? v0 v1) #f) (test (int-vector? (int-vector-ref v2 1)) #t) (test (int-vector-set! v2 1 32) 'error) (test (int-vector-set! (int-vector-ref v2 1) 1 32) 32) (test (int-vector-ref v2 1 1) 32) (test (int-vector-ref v3 0) (int-vector 0 0 0)) (test (int-vector-ref v4 0) (int-vector 0)) ) (let () (define (hi) (let ((v2 (make-int-vector '(2 3)))) (int-vector-set! v2 1 12) v2)) (test (hi) 'error)) (let () (define (f1) (let ((x (float-vector 0.0))) (set! (x 0) (complex 1 2)))) (test (let ((x (float-vector 0.0))) (set! (x 0) 1+i)) 'error) (test (f1) 'error) (define (f2) (let ((x (int-vector 0))) (int-vector-set! x 0 (complex 1 2)))) (test (let ((x (int-vector 0))) (set! (x 0) 0+i)) 'error) (test (f2) 'error) (define (f3) (let ((x (float-vector 0.0))) (float-vector-set! x 0 (complex 1 2)))) (test (f3) 'error) (define (f4) (let ((x (int-vector 0))) (set! (x 0) (complex 1 2)))) (test (f4) 'error)) ;;; -------------------------------------------------------------------------------- ;;; vector (test (vector 1 2 3) #(1 2 3)) (test (vector 1 '(2) 3) #(1 (2) 3)) (test (vector) #()) (test (vector (vector (vector))) #(#(#()))) (test (vector (vector) (vector) (vector)) #(#() #() #())) (test (vector (list)) #(())) (test #(1 #\a "hi" hi) (vector 1 #\a "hi" 'hi)) (test (let ((v (make-vector 4 "hi"))) (vector-set! v 0 1) (vector-set! v 1 #\a) (vector-set! v 3 'hi) v) #(1 #\a "hi" hi)) (let ((x 34)) (test (vector x 'x) #(34 x))) (for-each (lambda (arg) (test (vector-ref (vector arg) 0) arg)) (list #\a 1 () (list 1) '(1 . 2) #f "hi" 'a-symbol abs _ht_ _null_ _c_obj_ quasiquote macroexpand (log 0) 3.14 3/4 1.0+1.0i #t (vector 1 2 3) (lambda (a) (+ a 1)))) ;;; -------------------------------------------------------------------------------- ;;; vector->list ;;; list->vector (test (vector->list #(0)) (list 0)) (test (vector->list (vector)) ()) (test (vector->list #(a b c)) '(a b c)) (test (vector->list #(#(0) #(1))) '(#(0) #(1))) (test (vector? (list-ref (let ((v (vector 1 2))) (vector-set! v 1 v) (vector->list v)) 1)) #t) (test (list->vector ()) #()) (test (list->vector '(a b c)) #(a b c)) (test (list->vector (list (list 1 2) (list 3 4))) #((1 2) (3 4))) (test (list->vector ''foo) #(quote foo)) (test (list->vector (list)) #()) (test (list->vector (list 1)) #(1)) (test (list->vector (list (list))) #(())) (test (list->vector (list 1 #\a "hi" 'hi)) #(1 #\a "hi" hi)) (test (list->vector ''1) #(quote 1)) (test (list->vector '''1) #(quote '1)) (for-each (lambda (arg) (if (proper-list? arg) (test (vector->list (list->vector arg)) arg))) lists) (set! lists ()) (test (list->vector (vector->list (vector))) #()) (test (list->vector (vector->list (vector 1))) #(1)) (test (vector->list (list->vector (list))) ()) (test (vector->list (list->vector (list 1))) '(1)) (test (reinvert 12 vector->list list->vector #(1 2 3)) #(1 2 3)) (test (vector->list) 'error) (test (list->vector) 'error) (test (vector->list #(1) #(2)) 'error) (test (list->vector '(1) '(2)) 'error) (for-each (lambda (arg) (test (vector->list arg) 'error)) (list #\a 1 () (list 1) '(1 . 2) #f 'a-symbol "hi" abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t :hi (if #f #f) (lambda (a) (+ a 1)))) (test (let ((x (cons #\a #\b))) (set-cdr! x x) (list->vector x)) 'error) (test (list->vector (cons 1 2)) 'error) (test (list->vector '(1 2 . 3)) 'error) (test (let ((lst (list #\a #\b))) (set! (cdr (cdr lst)) lst) (list->vector lst)) 'error) (test (let ((lst (list #\a #\b))) (set! (cdr (cdr lst)) lst) (apply vector lst)) 'error) (for-each (lambda (arg) (test (list->vector arg) 'error)) (list "hi" #\a 1 '(1 . 2) (cons #\a #\b) 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t :hi (if #f #f) (lambda (a) (+ a 1)))) (test (vector->list #(1 2 3 4) 0) '(1 2 3 4)) (test (vector->list #(1 2 3 4) 2) '(3 4)) (test (vector->list #(1 2 3 4) 0 4) '(1 2 3 4)) (test (vector->list #(1 2 3 4) 4 4) ()) (test (vector->list #(1 2 3 4) 1 2) '(2)) (test (vector->list #(1 2 3 4) -1 4) 'error) (test (vector->list #(1 2 3 4) 1 0) 'error) (test (vector->list #(1 2 3 4) 5) 'error) (test (vector->list #(1 2 3 4) 1 5) 'error) (test (vector->list #(1 2 3 4) 1 2 3) 'error) (test (vector->list #() 0 10) 'error) (test (vector->list #(1) 0 2) 'error) (test (vector->list #() 0 0) ()) (test (vector->list #(1) 1) ()) (test (vector->list #(1) 0) '(1)) (test (vector->list #() #\null) 'error) (test (vector->list #() 0 #\null) 'error) (test (vector->list #() -1) 'error) (test (vector->list #(1) -1) 'error) (test (vector->list #(1) 0 -1) 'error) (test (vector->list #(1) -2 -1) 'error) (test (vector->list #(1) most-negative-fixnum) 'error) (test (vector->list #(1) 2) 'error) (test (vector->list (make-int-vector 3)) '(0 0 0)) (test (vector->list (make-float-vector 3)) '(0.0 0.0 0.0)) (for-each (lambda (arg) (test (vector->list #(0 1 2 3 4 5) arg) 'error) (test (vector->list #(0 1 2 3 4 5) 1 arg) 'error)) (list #\a "hi" () (list 1) '(1 . 2) 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t :hi (if #f #f) (lambda (a) (+ a 1)))) ;;; -------------------------------------------------------------------------------- ;;; vector-length (test (vector-length (vector)) 0) (test (vector-length (vector 1)) 1) (test (vector-length (make-vector 128)) 128) (test (vector-length #(a b c d e f)) 6) (test (vector-length #()) 0) (test (vector-length (vector #\a (list 1 2) (vector 1 2))) 3) (test (vector-length #(#(#(hi)) #(#(hi)) #(#(hi)))) 3) (test (vector-length (vector 1 2 3 4)) 4) (test (vector-length (let ((v (vector 1 2))) (vector-set! v 1 v) v)) 2) (test (vector-length (let ((v (vector 1 2))) (vector-set! v 1 v) (vector-ref v 1))) 2) (test (vector-length (make-vector 3 0 #t)) 3) (if (not with-bignums) (test (vector-length (make-vector 3 pi #t)) 3)) (if (not with-bignums) (test (vector-length (make-vector '(2 3) pi #t)) 6)) (test (vector-length) 'error) (test (vector-length #(1) #(2)) 'error) (for-each (lambda (arg) (test (vector-length arg) 'error)) (list "hi" #\a 1 () '(1 . 2) (cons #\a #\b) #f 'a-symbol abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t :hi (if #f #f) (lambda (a) (+ a 1)))) ;;; -------------------------------------------------------------------------------- ;;; vector-ref (test (vector-ref #(1 1 2 3 5 8 13 21) 5) 8) (test (vector-ref #(1 1 2 3 5 8 13 21) (let ((i (round (* 2 (acos -1))))) (if (inexact? i) (inexact->exact i) i))) 13) (test (let ((v (make-vector 1 0))) (vector-ref v 0)) 0) (test (let ((v (vector 1 (list 2) (make-vector 3 #\a)))) (vector-ref v 1)) (list 2)) (test (let ((v (vector 1 (list 2) (make-vector 3 #\a)))) (vector-ref v 2)) #(#\a #\a #\a)) (test (let ((v (vector 1 (list 2) (make-vector 3 #\a)))) (vector-ref (vector-ref v 2) 1)) #\a) (test (vector-ref #(a b c) 1) 'b) (test (vector-ref #(()) 0) ()) (test (vector-ref #(#()) 0) #()) (test (vector-ref (vector-ref (vector-ref #(1 (2) #(3 (4) #(5))) 2) 2) 0) 5) (test (let ((v (vector 1 2))) (vector-set! v 1 v) (eq? (vector-ref v 1) v)) #t) (test (let ((v (make-int-vector 3))) (vector-ref v 1)) 0) (test (let ((v (make-vector 3 0 #f))) (vector-ref v 1)) 0) (test (let ((v (make-float-vector 3 1.0))) (vector-ref v 1)) 1.0) (test (let ((v (make-vector 6 0 #t))) (vector-set! v 3 32) (let ((v1 (make-shared-vector v '(2 3)))) (vector-ref v1 1 0))) 32) (test (vector-ref) 'error) (test (vector-ref #(1)) 'error) (test (vector-ref #(1) 0 0) 'error) (test (vector-ref () 0) 'error) (test (let ((v (make-vector 1 0))) (vector-ref v 1)) 'error) (test (let ((v (make-vector 1 0))) (vector-ref v -1)) 'error) (test (let ((v (vector 1 (list 2) (make-vector 3 #\a)))) (vector-ref (vector-ref v 2) 3)) 'error) (test (let ((v (vector 1 (list 2) (make-vector 3 #\a)))) (vector-ref (vector-ref v 3) 0)) 'error) (test (vector-ref (vector) 0) 'error) (test (vector-ref #() 0) 'error) (test (vector-ref #() -1) 'error) (test (vector-ref #() 1) 'error) (test (vector-ref #(1 2 3) (floor .1)) 1) (test (vector-ref #(1 2 3) (floor 0+0i)) 1) (test (vector-ref #10D((((((((((0 1)))))))))) 0 0 0 0 0 0 0 0 0 1) 1) (test (#(1 2) 1) 2) (test (#(1 2) 1 2) 'error) (test ((#("hi" "ho") 0) 1) #\i) (test (((vector (list 1 2) (cons 3 4)) 0) 1) 2) (test ((#(#(1 2) #(3 4)) 0) 1) 2) (test ((((vector (vector (vector 1 2) 0) 0) 0) 0) 0) 1) (test ((((list (list (list 1 2) 0) 0) 0) 0) 0) 1) (test ((((list (list (list 1 2) 0) 0) 0) 0) ((((vector (vector (vector 1 2) 0) 0) 0) 0) 0)) 2) (test (#(1 2) -1) 'error) (test (#()) 'error) (test (#(1)) 'error) (test (#2d((1 2) (3 4))) 'error) (test (apply (make-vector '(1 2))) 'error) (test (eval-string "#2/3d(1 2)") 'error) (test (eval-string "#2.1d(1 2)") 'error) (test (eval-string "#(1 2 . 3)") 'error) (test (#(#(#(#t))) 0 0 0) #t) (test (let ((v (make-vector 3 0 #t))) (v 0 0)) 'error) (test (let ((v (make-int-vector '(2 2)))) (v 0 0 0)) 'error) (test (let ((v (make-float-vector 3))) (vector-ref v 0 0)) 'error) (test (let ((v (make-vector '(2 2) 0.0 #t))) (vector-ref v 0 0 0)) 'error) (test (let ((v (make-vector 3 0))) (v 0 0)) 'error) (test (let ((v (make-vector '(2 2) 0))) (v 0 0 0)) 'error) (test (let ((v (make-vector 3 0 #t))) (vector-set! v 0 0 3)) 'error) (test (let ((v (make-vector '(2 2) 0 #t))) (set! (v 0 0 0) 3)) 'error) (let ((v #(1 2 3))) (for-each (lambda (arg) ; (format *stderr* "~A~%" arg) (test (vector-ref arg 0) 'error) (test (v arg) 'error) (test (v arg 0) 'error) (test (vector-ref v arg) 'error) (test (vector-ref v arg 0) 'error) (test (vector-ref #2d((1 2) (3 4)) 0 arg) 'error)) (list "hi" () #() #\a -1 '(1 . 2) (cons #\a #\b) #f 'a-symbol abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t (lambda (a) (+ a 1)) (make-hash-table)))) (test (vector-ref #(#(1 2 3) #(4 5 6)) 1) #(4 5 6)) (test (vector-ref #(#(1 2 3) #(4 5 6)) 1 2) 6) (test (vector-ref #(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))) 1) #(#(7 8 9) #(10 11 12))) (test (vector-ref #(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))) 1 0) #(7 8 9)) (test (vector-ref #(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))) 1 0 2) 9) (test (vector-ref #(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))) 1 0 3) 'error) (test (vector-ref #(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))) 1 0 2 0) 'error) (test (#(#(1 2 3) #(4 5 6)) 1) #(4 5 6)) (test (#(#(1 2 3) #(4 5 6)) 1 2) 6) (test (#(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))) 1) #(#(7 8 9) #(10 11 12))) (test (#(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))) 1 0) #(7 8 9)) (test (#(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))) 1 0 2) 9) (test (#(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))) 1 0 3) 'error) (test (#(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))) 1 0 2 0) 'error) (test (let ((L #(#(1 2 3) #(4 5 6)))) (L 1)) #(4 5 6)) (test (let ((L #(#(1 2 3) #(4 5 6)))) (L 1 2)) 6) (test (let ((L #(#(1 2 3) #(4 5 6)))) (L 1 2 3)) 'error) (test (let ((L #(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))))) (L 1)) #(#(7 8 9) #(10 11 12))) (test (let ((L #(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))))) (L 1 0)) #(7 8 9)) (test (let ((L #(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))))) (L 1 0 2)) 9) (test (let ((L #(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))))) (L 1 0 2 3)) 'error) (test (let ((L #(#(1 2 3) #(4 5 6)))) ((L 1) 2)) 6) (test (let ((L #(#(1 2 3) #(4 5 6)))) (((L 1) 2) 3)) 'error) (test (let ((L #(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))))) ((L 1) 0)) #(7 8 9)) (test (let ((L #(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))))) (((L 1) 0) 2)) 9) (test (let ((L #(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))))) ((L 1 0) 2)) 9) (test (let ((L #(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))))) ((L 1) 0 2)) 9) (test (let ((L #(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))))) ((((L 1) 0) 2) 3)) 'error) (test (let ((L #(#(1 2 3) #(4 5 6)))) (vector-ref (L 1) 2)) 6) (test (let ((L #(#(1 2 3) #(4 5 6)))) (vector-ref ((L 1) 2) 3)) 'error) (test (let ((L #(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))))) (vector-ref (L 1) 0)) #(7 8 9)) (test (let ((L #(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))))) ((vector-ref (L 1) 0) 2)) 9) (test (let ((L #(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))))) (vector-ref (((L 1) 0) 2) 3)) 'error) (let ((zero 0) (one 1) (two 2) (three 3) (thirty-two 32)) (test (vector-ref #(#(1 2 3) #(4 5 6)) one) #(4 5 6)) (test (vector-ref #(#(1 2 3) #(4 5 6)) one two) 6) (test (vector-ref #(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))) one) #(#(7 8 9) #(10 11 12))) (test (vector-ref #(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))) one zero) #(7 8 9)) (test (vector-ref #(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))) one zero two) 9) (test (#(#(1 2 3) #(4 5 6)) one) #(4 5 6)) (test (#(#(1 2 3) #(4 5 6)) one two) 6) (test (#(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))) one) #(#(7 8 9) #(10 11 12))) (test (#(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))) one zero) #(7 8 9)) (test (#(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))) one zero two) 9) (test (let ((L #(#(1 2 3) #(4 5 6)))) (L one)) #(4 5 6)) (test (let ((L #(#(1 2 3) #(4 5 6)))) (L one two)) 6) (test (let ((L #(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))))) (L one)) #(#(7 8 9) #(10 11 12))) (test (let ((L #(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))))) (L one zero)) #(7 8 9)) (test (let ((L #(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))))) (L one zero two)) 9) (test (let ((L #(#(1 2 3) #(4 5 6)))) ((L one) two)) 6) (test (let ((L #(#(1 2 3) #(4 5 6)))) (((L one) two) 3)) 'error) (test (let ((L #(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))))) ((L one) zero)) #(7 8 9)) (test (let ((L #(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))))) (((L one) zero) two)) 9) (test (let ((L #(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))))) ((L one zero) two)) 9) (test (let ((L #(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))))) ((L one) zero two)) 9) (test (let ((L #(#(1 2 3) #(4 5 6)))) (vector-ref (L one) two)) 6) (test (let ((L #(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))))) (vector-ref (L one) zero)) #(7 8 9)) (test (let ((L #(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))))) ((vector-ref (L one) zero) two)) 9)) (test ((#(#(:hi) #\a (3)) (#("hi" 2) 1)) (#2d((#() ()) (0 #(0))) 1 ('(cons 0) 1))) 3) (test (#(1 2 3) (#(1 2 3) 1)) 3) (test ((#(#(1 2)) (#(1 0) 1)) (#(3 2 1 0) 2)) 2) (test (apply min (#(1 #\a (3)) (#(1 2) 1))) 3) ; i.e vector ref here 2 levels -- (#(1 2) 1) is 2 and (#(1 #\a (3)) 2) is (3) ;;; vector-ref optimizer checks (define global_vector (vector 1 2 3)) (let () (define (hi i) (vector-ref global_vector i)) (test (hi 1) 2)) (let () (define (hi i) (vector-ref global_vector (vector-ref global_vector i))) (test (hi 0) 2)) (test (let ((v #(0 1 2 3 4 5))) (define (f1) (v 4/3)) (f1)) 'error) (test (let ((v "012345")) (define (f1) (v 4/3)) (f1)) 'error) (test (let ((v (list 0 1 2 3 4 5))) (define (f1) (v 4/3)) (f1)) 'error) (define-constant -a-global-vector- (vector 1 2 3)) (let () (define (fg a) (vector-ref -a-global-vector- a)) (test (fg 0) 1)) (let () (define (f1) (let ((v (vector #f)) (X #2D((1 2) (3 4)))) (do ((i 0 (+ i 1))) ((= i 1) v) (vector-set! v 0 (vector-ref X 1))))) (test (f1) #(#(3 4)))) (let () (define (f1) (let ((v (vector #f)) (X #2D((1 2) (3 4)))) (do ((i 0 (+ i 1))) ((= i 1) v) (vector-set! v 0 (vector-ref X 2))))) (test (f1) 'error)) (let () (define (f1) (let ((I 0) (v (vector #f)) (X #2D((1 2) (3 4)))) (do ((i 0 (+ i 1))) ((= i 1) v) (vector-set! v 0 (vector-ref X (+ I 1)))))) (test (f1) #(#(3 4)))) (let () (define (f1) (let ((I 1) (v (vector #f)) (X #2D((1 2) (3 4)))) (do ((i 0 (+ i 1))) ((= i 1) v) (vector-set! v 0 (vector-ref X (+ I 1)))))) (test (f1) 'error)) (set! global_vector #2D((1 2) (3 4))) (let () (define (f1) (let ((I 1) (v (vector #f))) (do ((i 0 (+ i 1))) ((= i 1) v) (vector-set! v 0 (vector-ref global_vector I))))) (test (f1) #(#(3 4)))) (let () (define (f1) (let ((I 2) (v (vector #f))) (do ((i 0 (+ i 1))) ((= i 1) v) (vector-set! v 0 (vector-ref global_vector I))))) (test (f1) 'error)) ;;; -------------------------------------------------------------------------------- ;;; vector-set! (test (let ((vec (vector 0 '(2 2 2 2) "Anna"))) (vector-set! vec 1 '("Sue" "Sue")) vec) #(0 ("Sue" "Sue") "Anna")) (test (let ((v (vector 1 2 3))) (vector-set! v 1 32) v) #(1 32 3)) (let ((v (make-vector 8 #f))) (for-each (lambda (arg) (vector-set! v 1 arg) (test (vector-ref v 1) arg)) (list #\a 1 () (list 1) '(1 . 2) #f "hi" 'a-symbol abs _ht_ _null_ _c_obj_ quasiquote macroexpand (log 0) 3.14 3/4 1.0+1.0i #t (vector 1 2 3) (lambda (a) (+ a 1))))) (test (let ((v (vector 1 2 3))) (vector-set! v 1 0) v) #(1 0 3)) (test (let ((v (vector #f))) (vector-set! v 0 (vector)) v) #(#())) (test (let ((v (vector 1 (list 2) (vector 1 2 3)))) (vector-set! (vector-ref v 2) 0 21) v) #(1 (2) #(21 2 3))) (test (let ((v (make-int-vector 3))) (vector-set! v 1 32) (vector->list v)) '(0 32 0)) (test (let ((v (make-vector 3 0 #t))) (set! (v 1) 32) (vector->list v)) '(0 32 0)) (test (vector-set! (vector 1 2) 0 4) 4) (test (vector-set!) 'error) (test (vector-set! #(1)) 'error) (test (vector-set! #(1) 0) 'error) (test (vector-set! #(1) 0 0 1) 'error) (test (vector-set! #(1) 0 0 1 2 3) 'error) (test (vector-set! #(1) #(0) 1) 'error) (test (vector-set! #(1 2) 0 2) 2) (test (let ((x 2) (v (vector 1 2))) (vector-set! (let () (set! x 3) v) 1 23) (list x v)) '(3 #(1 23))) (test (let ((v #(1 2))) (vector-set! v 0 32)) 32) (test (let ((v #(1 2))) (set! (v 0) 32)) 32) (test (let ((v #(1 2))) (set! (vector-ref v 0) 32)) 32) (for-each (lambda (arg) (test (vector-set! arg 0 0) 'error)) (list "hi" () #\a -1 '(1 . 2) (cons #\a #\b) #f 'a-symbol abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t (lambda (a) (+ a 1)) (make-hash-table))) (let ((v (vector 1 2 3))) (for-each (lambda (arg) (test (vector-set! v arg 0) 'error)) (list "hi" () #() #\a -1 '(1 . 2) (cons #\a #\b) #f 'a-symbol abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t (make-vector 3) (lambda (a) (+ a 1))))) (for-each (lambda (arg) (test (vector-set! arg 0 0) 'error)) (list "hi" () #\a 1 '(1 . 2) (cons #\a #\b) #f 'a-symbol abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t :hi (if #f #f) (lambda (a) (+ a 1)))) (let ((v #(#(0 1) #(2 3)))) (vector-set! (vector-ref v 1) 1 4) (test (v 1 1) 4) (set! ((vector-ref v 1) 1) 5) (test (v 1 1) 5) (set! ((v 1) 1) 6) (test (v 1 1) 6) (vector-set! (v 1) 1 7) (test (v 1 1) 7) (set! (v 1 1) 8) (test (v 1 1) 8)) (let ((v (vector))) (test (vector-set! v 0 0) 'error) (test (vector-set! v 1 0) 'error) (test (vector-set! v -1 0) 'error)) (test (vector-set! #() 0 123) 'error) (test (vector-set! #(1 2 3) 0 123) 123) (test (let ((v #(1 2 3))) (set! (v 0) '(+ 1 2)) v) #((+ 1 2) 2 3)) (test (let ((v #(1 2 3))) (set! (v '(+ 1 1)) 2) v) 'error) (test (let ((v #(1 2 3))) (set! (v (+ 1 1)) 2) v) #(1 2 2)) (test (let ((g (lambda () #(1 2 3)))) (vector-set! (g) 0 #\?) (g)) #(#\? 2 3)) (test (let ((g (lambda () '(1 . 2)))) (set-car! (g) 123) (g)) '(123 . 2)) (test (let ((g (lambda () '(1 2)))) (list-set! (g) 0 123) (g)) '(123 2)) (test (let ((g (lambda () (symbol->string 'hi)))) (string-set! (g) 1 #\a) (symbol->string 'hi)) "hi") (test (let ((L #(#(1 2 3) #(4 5 6)))) (vector-set! L 1 32) L) #(#(1 2 3) 32)) (test (let ((L #(#(1 2 3) #(4 5 6)))) (vector-set! L 1 0 32) L) #(#(1 2 3) #(32 5 6))) (test (let ((L #(#(1 2 3) #(4 5 6)))) (vector-set! L 1 0 2 32) L) 'error) (test (let ((L #(#(1 2 3) #(4 5 6)))) (vector-set! L 1 3 32) L) 'error) (test (let ((L #(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))))) (vector-set! L 1 32) L) #(#(#(1 2 3) #(4 5 6)) 32)) (test (let ((L #(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))))) (vector-set! L 1 0 32) L) #(#(#(1 2 3) #(4 5 6)) #(32 #(10 11 12)))) (test (let ((L #(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))))) (vector-set! L 1 0 2 32) L) #(#(#(1 2 3) #(4 5 6)) #(#(7 8 32) #(10 11 12)))) (test (let ((L #(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))))) (vector-set! L 1 0 2 1 32) L) 'error) (test (let ((L #(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))))) (vector-set! L 1 4 2 32) L) 'error) (test (let ((L #(#(1 2 3) #(4 5 6)))) (set! (L 1) 32) L) #(#(1 2 3) 32)) (test (let ((L #(#(1 2 3) #(4 5 6)))) (set! (L 1 0) 32) L) #(#(1 2 3) #(32 5 6))) (test (let ((L #(#(1 2 3) #(4 5 6)))) (set! (L 1 0 2) 32) L) 'error) (test (let ((L #(#(1 2 3) #(4 5 6)))) (set! (L 1 3) 32) L) 'error) (test (let ((L #(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))))) (set! (L 1) 32) L) #(#(#(1 2 3) #(4 5 6)) 32)) (test (let ((L #(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))))) (set! (L 1 0) 32) L) #(#(#(1 2 3) #(4 5 6)) #(32 #(10 11 12)))) (test (let ((L #(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))))) (set! (L 1 0 2) 32) L) #(#(#(1 2 3) #(4 5 6)) #(#(7 8 32) #(10 11 12)))) (test (let ((L #(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))))) (set! (L 1 0 2 1) 32) L) 'error) (test (let ((L #(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))))) (set! (L 1 4 2) 32) L) 'error) (test (let ((L #(#(1 2 3) #(4 5 6)))) (set! ((L 1) 0) 32) L) #(#(1 2 3) #(32 5 6))) (test (let ((L #(#(1 2 3) #(4 5 6)))) (set! (((L 1) 0) 2) 32) L) 'error) (test (let ((L #(#(1 2 3) #(4 5 6)))) (set! ((L 1) 3) 32) L) 'error) (test (let ((L #(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))))) (set! ((L 1) 0) 32) L) #(#(#(1 2 3) #(4 5 6)) #(32 #(10 11 12)))) (test (let ((L #(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))))) (set! (((L 1) 0) 2) 32) L) #(#(#(1 2 3) #(4 5 6)) #(#(7 8 32) #(10 11 12)))) (test (let ((L #(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))))) (set! ((((L 1) 0) 2) 1) 32) L) 'error) (test (let ((L #(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))))) (set! (((L 1) 4) 2) 32) L) 'error) (test (let ((L #(#(#(1 2 3))))) (set! ((L 0) 0 1) 32) L) #(#(#(1 32 3)))) (test (let ((L #(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))))) (set! ((L 1 0) 2) 32) L) #(#(#(1 2 3) #(4 5 6)) #(#(7 8 32) #(10 11 12)))) (test (let ((L #(#(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))) #(13 14 15)))) (set! (L 0 0 1) 32) L) #(#(#(#(1 2 3) 32) #(#(7 8 9) #(10 11 12))) #(13 14 15))) (test (let ((L #(#(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))) #(13 14 15)))) (set! ((L 0) 0 1 2) 32) L) #(#(#(#(1 2 3) #(4 5 32)) #(#(7 8 9) #(10 11 12))) #(13 14 15))) (test (let ((L #(#(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))) #(13 14 15)))) (set! ((L 0 0) 1 2) 32) L) #(#(#(#(1 2 3) #(4 5 32)) #(#(7 8 9) #(10 11 12))) #(13 14 15))) (test (let ((L #(#(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))) #(13 14 15)))) (set! ((L 0 0 1) 2) 32) L) #(#(#(#(1 2 3) #(4 5 32)) #(#(7 8 9) #(10 11 12))) #(13 14 15))) (test (let ((L #(#(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))) #(13 14 15)))) (set! (((L 0) 0) 1 2) 32) L) #(#(#(#(1 2 3) #(4 5 32)) #(#(7 8 9) #(10 11 12))) #(13 14 15))) (test (let ((L #(#(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))) #(13 14 15)))) (set! (((L 0 0) 1) 2) 32) L) #(#(#(#(1 2 3) #(4 5 32)) #(#(7 8 9) #(10 11 12))) #(13 14 15))) (test (let ((L #(#(#(#(1 2 3) #(4 5 6)) #(#(7 8 9) #(10 11 12))) #(13 14 15)))) (set! ((((L 0) 0) 1) 2) 32) L) #(#(#(#(1 2 3) #(4 5 32)) #(#(7 8 9) #(10 11 12))) #(13 14 15))) (test (eq? (car (catch #t (lambda () (set! (#(1)) 2)) (lambda args args))) 'wrong-number-of-args) #t) (test (eq? (car (catch #t (lambda () (set! (#(1) 0 0) 2)) (lambda args args))) 'syntax-error) #t) (test (eq? (car (catch #t (lambda () (set! ((#(1) 0) 0) 2)) (lambda args args))) 'syntax-error) #t) ; (set! (1 ...)) (test (let ((L #(#(1 2 3) #(4 5 6)))) (eq? (car (catch #t (lambda () (set! ((L) 1) 32) L) (lambda args args))) 'wrong-number-of-args)) #t) (test (let ((L #(#(1 2 3) #(4 5 6)))) (eq? (car (catch #t (lambda () (set! ((L)) 32) L) (lambda args args))) 'wrong-number-of-args)) #t) (test (let ((L #(#(1 2 3) #(4 5 6)))) (eq? (car (catch #t (lambda () (set! ((L 1) 2)) L) (lambda args args))) 'syntax-error)) #t) (let ((v #(1 2 3))) (define (vr v a) (vector-ref v (+ a 1))) (test (vr v 1) 3)) (let () (define (fillv) (let ((v (make-vector 10))) (do ((i 0 (+ i 1))) ((= i 10) v) (vector-set! v i i)))) (test (fillv) #(0 1 2 3 4 5 6 7 8 9))) (let () (define (vv) (let ((v #(0 1)) (i 0) (x 2)) (vector-set! v i (+ (vector-ref v i) x)))) (test (vv) 2)) (let () (define (hi) (let ((v1 #(0 1)) (i 0) (j 1)) (vector-set! v1 i (vector-ref v1 j)))) (hi) 1) ;;; -------------------------------------------------------------------------------- ;;; vector-fill! (test (fill! (vector 1 2) 4) 4) (test (let ((v (vector 1 2 3))) (vector-fill! v 0) v) #(0 0 0)) (test (let ((v (vector))) (vector-fill! v #f) v) #()) (let ((v (make-vector 8 #f))) (for-each (lambda (arg) (vector-fill! v arg) (test (vector-ref v 1) arg)) (list #\a 1 () (list 1) '(1 . 2) #f "hi" 'a-symbol abs _ht_ _null_ _c_obj_ quasiquote macroexpand (log 0) 3.14 3/4 1.0+1.0i #t (vector 1 2 3) (lambda (a) (+ a 1))))) (test (let ((str "hi") (v (make-vector 3))) (vector-fill! v str) (string-set! (vector-ref v 0) 1 #\a) str) "ha") (test (let ((lst (list 1 2)) (v (make-vector 3))) (vector-fill! v lst) (list-set! (vector-ref v 0) 1 #\a) lst) '(1 #\a)) (test (let ((v (vector 1 2 3))) (vector-set! v -1 0)) 'error) (test (let ((v (vector 1 2 3))) (vector-set! v 3 0)) 'error) (test (vector-fill! #(1 2) 2) 2) (test (vector-fill! #() 0) 0) (test (vector-fill! (vector) 0) 0) (test (let ((v (vector 1))) (vector-fill! v 32) (v 0)) 32) (test (let ((v (make-vector 11 0))) (vector-fill! v 32) (v 10)) 32) (test (let ((v (make-vector 16 0))) (vector-fill! v 32) (v 15)) 32) (test (let ((v (make-vector 3 0))) (vector-fill! v 32) (v 1)) 32) (test (let ((v (make-vector 3 0))) (fill! v 32) (v 1)) 32) (test (let ((v #2d((1 2 3) (4 5 6)))) (vector-fill! (v 1) 12) v) #2D((1 2 3) (12 12 12))) (for-each (lambda (arg) (test (vector-fill! arg 0) 'error)) (list "hi" #\a () 1 '(1 . 2) (cons #\a #\b) #f 'a-symbol abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t :hi (if #f #f) (lambda (a) (+ a 1)))) (if with-bignums (let ((v (make-vector 2 0.0))) (vector-fill! v 1180591620717411303424) (num-test (v 1) (expt 2 70)) (vector-fill! v 3/1180591620717411303424) (num-test (v 0) 3/1180591620717411303424) (vector-fill! v 1180591620717411303424.0) (num-test (v 1) 1180591620717411303424.0) (vector-fill! v (complex (expt 2 70) 1.0)) (num-test (v 0) (complex (expt 2 70) 1.0)) (set! v (float-vector 1.0)) (vector-fill! v (bignum "2.0")) (num-test (v 0) 2.0) (vector-fill! v pi) (num-test (v 0) pi) (set! v (float-vector 0.0 0.0 0.0)) (vector-fill! v (bignum "2.0") 1 2) (num-test (v 0) 0.0) (num-test (v 1) 2.0) (set! v (make-int-vector 1)) (vector-fill! v (bignum "2")) (num-test (v 0) 2) (set! v (make-vector 3 0 #t)) (vector-fill! v (bignum "2") 1 2) (num-test (v 0) 0) (num-test (v 1) 2))) (let ((v (make-vector 3))) (vector-fill! v v) (test (v 0) v) (set! (v 1) 32) (test ((v 0) 1) 32)) (test (let ((v (vector 1 2 3 4 5))) (vector-fill! v 21 0) v) #(21 21 21 21 21)) (test (let ((v (vector 1 2 3 4 5))) (vector-fill! v 21 0 5) v) #(21 21 21 21 21)) (test (let ((v (vector 1 2 3 4 5))) (vector-fill! v 21 0 3) v) #(21 21 21 4 5)) (test (let ((v (vector 1 2 3 4 5))) (vector-fill! v 21 2 3) v) #(1 2 21 4 5)) (test (let ((v (vector 1 2 3 4 5))) (vector-fill! v 21 3 3) v) #(1 2 3 4 5)) (test (let ((v (make-vector 3 1 #t))) (vector-fill! v 2) (vector->list v)) '(2 2 2)) (if (not with-bignums) (test (let ((v (make-vector 3 pi #t))) (vector-fill! v 0.0) (vector->list v)) '(0.0 0.0 0.0))) (test (let ((v (make-vector 3 1 #t))) (vector-fill! v "2.5")) 'error) (test (let ((v (make-vector 3 pi #t))) (vector-fill! v #\a)) 'error) (test (let ((v (make-float-vector 3))) (vector-fill! v 1+i) v) 'error) (test (let ((v (make-vector 3 0.0 #t))) (vector-fill! v 3/4) (vector->list v)) '(0.75 0.75 0.75)) (test (let ((v (make-vector 3 0.0 #t))) (vector-fill! v 3) (vector->list v)) '(3.0 3.0 3.0)) (test (let ((v (make-int-vector 3))) (vector-fill! v 1+i) v) 'error) (test (let ((v (make-vector 3 0 #t))) (vector-fill! v 3/4) v) 'error) (test (let ((v (make-vector 3 0 #t))) (vector-fill! v 3.0) v) 'error) (test (let ((v (make-vector 3 1 #t))) (vector-fill! v 2 1) (vector->list v)) '(1 2 2)) (test (let ((v (make-vector 3 1 #t))) (vector-fill! v 2 1 1) (vector->list v)) '(1 1 1)) (test (let ((v (make-vector 3 1 #t))) (vector-fill! v 2 1 2) (vector->list v)) '(1 2 1)) (test (let ((v (make-vector 3 1 #t))) (vector-fill! v 2 1 3) (vector->list v)) '(1 2 2)) (test (let ((v (make-vector 3 1 #t))) (vector-fill! v 2 0 3) (vector->list v)) '(2 2 2)) (test (let ((v (make-vector 3 1 #t))) (vector-fill! v 2 1 4) (vector->list v)) 'error) (test (let ((v (make-vector 3 1 #t))) (vector-fill! v 2 -1) (vector->list v)) 'error) (test (let ((v (make-vector 3 0.0 #t))) (vector-fill! v 1.0 1) (vector->list v)) '(0.0 1.0 1.0)) (test (let ((v (make-vector 3 1 #t))) (vector-fill! v "2.5" 1)) 'error) (test (let ((v (make-vector 3 pi #t))) (vector-fill! v #\a 0 1)) 'error) (test (let ((v (make-vector 3 0.0 #t))) (vector-fill! v 1+i 1) v) 'error) (test (let ((v (make-vector 3 0.0 #t))) (vector-fill! v 3/4 1) (vector->list v)) '(0.0 0.75 0.75)) (test (let ((v (make-float-vector 3))) (vector-fill! v 3 2) (vector->list v)) '(0.0 0.0 3.0)) (test (let ((v (make-vector 3 0 #t))) (vector-fill! v 1+i 2) v) 'error) (test (let ((v (make-vector 3 0 #t))) (vector-fill! v 3/4 0 1) v) 'error) (test (let ((v (make-int-vector 3))) (vector-fill! v 3.0 2) v) 'error) (test (vector-fill! #() 0 "hi") 'error) (test (vector-fill! #() 0 -1 3) 'error) (test (vector-fill! #() 0 1) 'error) (test (vector-fill! #() 0 0 4/3) 'error) ;;; -------------------------------------------------------------------------------- ;;; vector-append (test (vector-append #() #2d()) #()) (test (vector-append) #()) (test (vector-append #()) #()) (test (vector-append #(1 2)) #(1 2)) (test (vector-append #(1) #(2 3) #() #(4)) #(1 2 3 4)) (test (vector-append #(1) #2d((2 3) (4 5)) #3d()) #(1 2 3 4 5)) (test (vector-append #2d((1 2) (3 4)) #3d(((5 6) (7 8)) ((9 10) (11 12)))) #(1 2 3 4 5 6 7 8 9 10 11 12)) (test (vector-append (vector 1 2) (make-vector 1 3 #t) #(4)) #(1 2 3 4)) (test (vector-append (vector 1 2) (make-float-vector 1) #(4)) #(1 2 0.0 4)) (test (vector->list (vector-append (make-vector 1 3 #t) (make-vector 2 1 #t))) '(3 1 1)) (test (vector->list (vector-append (make-vector 1 0.0 #t) (make-vector 2 1.0 #t))) '(0.0 1.0 1.0)) (for-each (lambda (arg) (test (vector-append arg) 'error) (test (vector-append #(1 2) arg) 'error)) (list "hi" #\a () 1 '(1 . 2) (cons #\a #\b) #f 'a-symbol abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t :hi (if #f #f) (lambda (a) (+ a 1)))) (test (equal? (make-vector 3 1) (make-vector 3 1 #t)) #f) (let ((iv (make-vector 3 1 #t)) (fv (make-vector 3 2.0 #t)) (vv (make-vector 3 #f))) (test (equal? (vector-append iv iv iv) (make-vector 9 1 #t)) #t) (test (vector-append iv iv vv) 'error) (test (vector-append iv fv iv) (int-vector 1 1 1 2 2 2 1 1 1)) (test (vector-append iv fv fv) (int-vector 1 1 1 2 2 2 2 2 2)) (test (vector-append iv fv vv) 'error) (test (vector-append iv vv iv) 'error) (test (vector-append fv iv iv) (float-vector 2.0 2.0 2.0 1 1 1 1 1 1)) ; #(2.0 2.0 2.0 1 1 1 1 1 1)) (test (vector-append fv iv fv) (float-vector 2.0 2.0 2.0 1 1 1 2.0 2.0 2.0)) ; #(2.0 2.0 2.0 1 1 1 2.0 2.0 2.0)) (test (vector-append fv fv iv) (float-vector 2.0 2.0 2.0 2.0 2.0 2.0 1 1 1)) ; #(2.0 2.0 2.0 2.0 2.0 2.0 1 1 1)) (test (vector-append fv fv fv) (make-vector 9 2.0 #t)) (test (vector-append fv fv vv) 'error) (test (vector-append vv iv iv) #(#f #f #f 1 1 1 1 1 1)) (test (vector-append vv iv fv) #(#f #f #f 1 1 1 2.0 2.0 2.0)) (test (vector-append vv iv vv) #(#f #f #f 1 1 1 #f #f #f)) (test (vector-append vv fv iv) #(#f #f #f 2.0 2.0 2.0 1 1 1)) (test (vector-append vv fv fv) #(#f #f #f 2.0 2.0 2.0 2.0 2.0 2.0)) (test (vector-append vv fv vv) #(#f #f #f 2.0 2.0 2.0 #f #f #f)) (test (vector-append vv vv iv) #(#f #f #f #f #f #f 1 1 1)) (test (vector-append vv vv fv) #(#f #f #f #f #f #f 2.0 2.0 2.0)) (test (vector-append vv vv vv) #(#f #f #f #f #f #f #f #f #f))) (test (equal? (vector-append (float-vector 1 2 3) #()) (float-vector 1 2 3)) #t) (test (equal? (vector-append (float-vector) #(1 2 3) #() (make-vector 0 0 #t)) (float-vector 1 2 3)) #t) (test (equal? (float-vector) (vector-append (float-vector))) #t) (test (equal? (vector-append #() (float-vector) (make-vector 3 1 #t) (vector)) (make-vector 3 1)) #t) (test (equal? (vector-append (int-vector 1 2 3) #()) (int-vector 1 2 3)) #t) (test (equal? (vector-append (int-vector) #(1 2 3) #() (make-vector 0 0 #t)) (int-vector 1 2 3)) #t) (test (equal? (int-vector) (vector-append (int-vector))) #t) (test (equal? (vector-append #() (int-vector) (make-vector 3 1 #t) (vector)) (make-vector 3 1)) #t) (when full-test (define (test-append size) (let ((strs ()) (vecs ()) (fvecs ()) (ivecs ()) (ifvecs ()) (allvecs ()) (bvecs ()) (lsts ())) (do ((i 0 (+ i 1))) ((= i size)) (set! strs (cons (make-string size (integer->char (+ 1 (random 255)))) strs)) (set! bvecs (cons (->byte-vector (make-string size (integer->char (random 256)))) bvecs)) (set! vecs (cons (make-vector size i) vecs)) (set! ivecs (cons (make-int-vector size i) ivecs)) (set! fvecs (cons (make-float-vector size (* i 1.0)) fvecs)) (set! ifvecs (cons (make-vector size (if (even? i) (* i 1.0) i) #t) ifvecs)) (set! allvecs (cons (make-vector size (if (even? i) (* i 1.0) i) (not (zero? (modulo i 3)))) allvecs)) (set! lsts (cons (make-list size i) lsts))) (let ((lst (apply append lsts)) (vec (apply vector-append vecs)) (fvec (apply vector-append fvecs)) (ivec (apply vector-append ivecs)) (ifvec (apply vector-append ifvecs)) (allvec (apply vector-append allvecs)) (str (apply string-append strs)) (bvec (->byte-vector (apply string-append bvecs)))) (test (vector? vec) #t) (test (length vec) (* size size)) (test (float-vector? fvec) #t) (test (length fvec) (* size size)) (test (int-vector? ivec) #t) (test (length ivec) (* size size)) (test (vector? allvec) #t) (test (length allvec) (* size size)) (test (vector? ifvec) #t) (test (length ifvec) (* size size)) (test (pair? lst) #t) (test (length lst) (* size size)) (test (string? str) #t) (test (length str) (* size size)) (test (byte-vector? bvec) #t) (test (length bvec) (* size size)) ))) (do ((i 1 (* i 10))) ((> i 1000)) (test-append i))) ;;; -------------------------------------------------------------------------------- ;;; miscellaneous vectors (test (let ((sum 0)) (for-each (lambda (n) (set! sum (+ sum n))) (vector 1 2 3)) sum) 6) (test (let ((sum 0)) (for-each (lambda (n m) (set! sum (+ sum n (- m)))) (vector 1 2 3) (vector 4 5 6)) sum) -9) (test (let () (for-each (lambda (n) (error "oops")) (vector)) #f) #f) (test (let ((sum 0)) (for-each (lambda (n m p) (set! sum (+ sum n (- m) (* 2 p)))) (vector 1 2 3) (vector 4 5 6) (vector 6 7 8)) sum) 33) (test (let ((sum 0)) (for-each (lambda (n) (for-each (lambda (m) (set! sum (+ sum (* m n)))) (vector 1 2 3))) (vector 4 5 6)) sum) 90) (test (call/cc (lambda (return) (for-each (lambda (n) (return "oops")) (vector 1 2 3)))) "oops") (test (call/cc (lambda (return) (for-each (lambda (n) (if (even? n) (return n))) (vector 1 3 8 7 9 10)))) 8) (for-each (lambda (data) (let ((v data) (c #f) (y 0)) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v i) i)) (let ((tag (call/cc (lambda (exit) (for-each (lambda (x) (call/cc (lambda (return) (set! c return))) (if (and (even? (inexact->exact x)) (> x y) (< x 10)) (begin (set! (v (inexact->exact y)) 100) (set! y x) (exit x)) (set! y x))) v))))) (if (and (number? tag) (< tag 10)) (c))) (let ((correct (vector 0 100 2 100 4 100 6 100 8 9))) (do ((i 0 (+ i 1))) ((= i (length v))) (if (not (= (correct i) (inexact->exact (v i)))) (format-logged #t ";for-each call/cc data: ~A~%" v)))))) (list (make-vector 10) (make-list 10))) (test (map (lambda (n) (+ 1 n)) (vector 1 2 3)) '(2 3 4)) (test (map (lambda (n m) (- n m)) (vector 1 2 3) (vector 4 5 6)) '(-3 -3 -3)) (test (map (lambda (n m p) (+ n m p)) (vector 1 2 3) (vector 4 5 6) (vector 6 7 8)) '(11 14 17)) (test (map (lambda (n) (map (lambda (m) (* m n)) (vector 1 2 3))) (vector 4 5 6)) '((4 8 12) (5 10 15) (6 12 18))) (test (call/cc (lambda (return) (map (lambda (n) (return "oops")) (vector 1 2 3)))) "oops") (test (call/cc (lambda (return) (map (lambda (n) (if (even? n) (return n))) (vector 1 3 8 7 9 10)))) 8) (test (map (lambda (x) x) (make-vector 3 0 #t)) '(0 0 0)) (test (map (lambda (x) x) (let ((v (make-vector 3 0 #t))) (set! (v 1) 1) (set! (v 2) 2) v)) '(0 1 2)) (test (map (lambda (x) x) (make-vector 3 0.0 #t)) '(0.0 0.0 0.0)) (test (let ((lst ())) (for-each (lambda (n) (set! lst (cons n lst))) (let ((v (make-vector 3 0 #t))) (set! (v 1) 1) v)) lst) '(0 1 0)) (test (vector? (symbol-table)) #t) (let ((v (make-vector 3 (vector 1 2)))) (test (equal? (v 0) (v 1)) #t) (test (eq? (v 0) (v 1)) #t) (test (eqv? (v 0) (v 1)) #t)) (let ((v (vector (vector 1 2) (vector 1 2) (vector 1 2)))) (test (equal? (v 0) (v 1)) #t) (test (eq? (v 0) (v 1)) #f) (test (eqv? (v 0) (v 1)) #f)) (let ((v (vector (vector (vector (vector 1 2) 3) 4) 5))) (test (v 0) #(#(#(1 2) 3) 4)) (test (v 1) 5) (test (((v 0) 0) 1) 3) (test ((((v 0) 0) 0) 1) 2)) (test (make-vector 1 (make-vector 1 (make-vector 1 0))) #(#(#(0)))) (test (vector->list (let ((v (make-vector 3 0 #t))) (set! (v 0) 32) (set! (v 1) -1) (set! (v 2) 2) (sort! v <))) '(-1 2 32)) (let ((v1 (make-vector 3 1))) (num-test (v1 1) 1) (set! (v1 1) 2) (num-test (v1 1) 2) (let ((i0 0) (i2 2)) (num-test (v1 i0) 1) (num-test (vector-ref v1 i2) 1) (set! (v1 i0) 0) (num-test (v1 0) 0) (set! (v1 i0) i2) (num-test (v1 i0) i2)) (test (vector-dimensions v1) '(3)) (set! v1 (make-vector '(3 2))) (test (vector-dimensions v1) '(3 2)) (vector-set! v1 1 1 0) (num-test (vector-ref v1 1 1) 0) (let ((i0 1) (i1 1) (i2 32)) (set! (v1 i0 i1) i2) (num-test (vector-ref v1 1 1) 32) (num-test (v1 i0 i1) i2) (vector-set! v1 0 1 3) (num-test (v1 0 1) 3) (num-test (v1 1 1) 32)) (set! v1 (make-vector '(2 4 3) 1)) (test (vector-dimensions v1) '(2 4 3)) (num-test (vector-ref v1 1 1 1) 1) (vector-set! v1 0 0 0 32) (num-test (v1 0 0 0) 32) (set! (v1 0 1 1) 3) (num-test (v1 0 1 1) 3)) (for-each (lambda (arg) (test (vector-dimensions arg) 'error)) (list "hi" -1 0 #\a 'a-symbol '(1 . 2) '(1 2 3) 3.14 3/4 1.0+1.0i #t abs # # (lambda () 1))) (test (vector-dimensions) 'error) (test (vector-dimensions #() #()) 'error) (test (vector-dimensions #()) '(0)) (test (vector-dimensions (vector)) '(0)) (test (vector-dimensions (vector 0)) '(1)) (test (vector-dimensions (vector-ref #2d((1 2 3) (3 4 5)) 0)) '(3)) (test (vector-dimensions (vector-ref #3D(((1 2 3) (3 4 5)) ((5 6 1) (7 8 2))) 0)) '(2 3)) (test (vector-dimensions (vector-ref #3D(((1 2 3) (3 4 5)) ((5 6 1) (7 8 2))) 0 1)) '(3)) (test (set! (vector-dimensions #(1 2)) 1) 'error) (test (let ((v #(1 2 3))) (set! (car (vector-dimensions v)) 0) v) #(1 2 3)) (test (vector-dimensions (make-vector '(2 3) 0 #t)) '(2 3)) (let ((old-len (*s7* 'print-length))) (let ((vect1 #3D(((1 2 3) (3 4 5)) ((5 6 1) (7 8 2)))) (vect2 #2d((1 2 3 4 5 6) (7 8 9 10 11 12))) (vect3 #(1 2 3 4 5 6 7 8 9 10 11 12 13 14)) (vect4 #3D(((1 2) (3 4) (5 6)) ((7 8) (9 10) (11 12)))) (vect1t (make-vector '(2 2 3) 0 #t))) (let ((v (make-shared-vector vect1t '(12)))) (set! (v 0) 1) (set! (v 1) 2) (set! (v 2) 3) (set! (v 3) 3) (set! (v 4) 4) (set! (v 5) 5) (set! (v 6) 5) (set! (v 7) 6) (set! (v 8) 1) (set! (v 9) 7) (set! (v 10) 8) (set! (v 11) 2)) (do ((i 1 (+ i 1))) ((= i 15)) (set! (*s7* 'print-length) i) (let ((str (object->string vect1))) (test str (case i ((1) "#3D(((1 ...)...)...)") ((2) "#3D(((1 2 ...)...)...)") ((3) "#3D(((1 2 3)...)...)") ((4) "#3D(((1 2 3) (3 ...))...)") ((5) "#3D(((1 2 3) (3 4 ...))...)") ((6) "#3D(((1 2 3) (3 4 5))...)") ((7) "#3D(((1 2 3) (3 4 5)) ((5 ...)...))") ((8) "#3D(((1 2 3) (3 4 5)) ((5 6 ...)...))") ((9) "#3D(((1 2 3) (3 4 5)) ((5 6 1)...))") ((10) "#3D(((1 2 3) (3 4 5)) ((5 6 1) (7 ...)))") ((11) "#3D(((1 2 3) (3 4 5)) ((5 6 1) (7 8 ...)))") ((12) "#3D(((1 2 3) (3 4 5)) ((5 6 1) (7 8 2)))") ((13) "#3D(((1 2 3) (3 4 5)) ((5 6 1) (7 8 2)))") ((14) "#3D(((1 2 3) (3 4 5)) ((5 6 1) (7 8 2)))")))) (let ((str (object->string vect1t))) (test str (case i ((1) "(make-shared-vector (int-vector 1 ...) '(2 2 3))") ((2) "(make-shared-vector (int-vector 1 2 ...) '(2 2 3))") ((3) "(make-shared-vector (int-vector 1 2 3 ...) '(2 2 3))") ((4) "(make-shared-vector (int-vector 1 2 3 3 ...) '(2 2 3))") ((5) "(make-shared-vector (int-vector 1 2 3 3 4 ...) '(2 2 3))") ((6) "(make-shared-vector (int-vector 1 2 3 3 4 5 ...) '(2 2 3))") ((7) "(make-shared-vector (int-vector 1 2 3 3 4 5 5 ...) '(2 2 3))") ((8) "(make-shared-vector (int-vector 1 2 3 3 4 5 5 6 ...) '(2 2 3))") ((9) "(make-shared-vector (int-vector 1 2 3 3 4 5 5 6 1 ...) '(2 2 3))") ((10) "(make-shared-vector (int-vector 1 2 3 3 4 5 5 6 1 7 ...) '(2 2 3))") ((11) "(make-shared-vector (int-vector 1 2 3 3 4 5 5 6 1 7 8 ...) '(2 2 3))") ((12) "(make-shared-vector (int-vector 1 2 3 3 4 5 5 6 1 7 8 2) '(2 2 3))") ((13) "(make-shared-vector (int-vector 1 2 3 3 4 5 5 6 1 7 8 2) '(2 2 3))") ((14) "(make-shared-vector (int-vector 1 2 3 3 4 5 5 6 1 7 8 2) '(2 2 3))")))) (let ((str (object->string vect4))) (test str (case i ((1) "#3D(((1 ...)...)...)") ((2) "#3D(((1 2)...)...)") ((3) "#3D(((1 2) (3 ...)...)...)") ((4) "#3D(((1 2) (3 4)...)...)") ((5) "#3D(((1 2) (3 4) (5 ...))...)") ((6) "#3D(((1 2) (3 4) (5 6))...)") ((7) "#3D(((1 2) (3 4) (5 6)) ((7 ...)...))") ((8) "#3D(((1 2) (3 4) (5 6)) ((7 8)...))") ((9) "#3D(((1 2) (3 4) (5 6)) ((7 8) (9 ...)...))") ((10) "#3D(((1 2) (3 4) (5 6)) ((7 8) (9 10)...))") ((11) "#3D(((1 2) (3 4) (5 6)) ((7 8) (9 10) (11 ...)))") ((12) "#3D(((1 2) (3 4) (5 6)) ((7 8) (9 10) (11 12)))") ((13) "#3D(((1 2) (3 4) (5 6)) ((7 8) (9 10) (11 12)))") ((14) "#3D(((1 2) (3 4) (5 6)) ((7 8) (9 10) (11 12)))")))) (let ((str (object->string vect2))) (test str (case i ((1) "#2D((1 ...)...)") ((2) "#2D((1 2 ...)...)") ((3) "#2D((1 2 3 ...)...)") ((4) "#2D((1 2 3 4 ...)...)") ((5) "#2D((1 2 3 4 5 ...)...)") ((6) "#2D((1 2 3 4 5 6)...)") ((7) "#2D((1 2 3 4 5 6) (7 ...))") ((8) "#2D((1 2 3 4 5 6) (7 8 ...))") ((9) "#2D((1 2 3 4 5 6) (7 8 9 ...))") ((10) "#2D((1 2 3 4 5 6) (7 8 9 10 ...))") ((11) "#2D((1 2 3 4 5 6) (7 8 9 10 11 ...))") ((12) "#2D((1 2 3 4 5 6) (7 8 9 10 11 12))") ((13) "#2D((1 2 3 4 5 6) (7 8 9 10 11 12))") ((14) "#2D((1 2 3 4 5 6) (7 8 9 10 11 12))")))) (let ((str (object->string vect3))) (test str (case i ((1) "#(1 ...)") ((2) "#(1 2 ...)") ((3) "#(1 2 3 ...)") ((4) "#(1 2 3 4 ...)") ((5) "#(1 2 3 4 5 ...)") ((6) "#(1 2 3 4 5 6 ...)") ((7) "#(1 2 3 4 5 6 7 ...)") ((8) "#(1 2 3 4 5 6 7 8 ...)") ((9) "#(1 2 3 4 5 6 7 8 9 ...)") ((10) "#(1 2 3 4 5 6 7 8 9 10 ...)") ((11) "#(1 2 3 4 5 6 7 8 9 10 11 ...)") ((12) "#(1 2 3 4 5 6 7 8 9 10 11 12 ...)") ((13) "#(1 2 3 4 5 6 7 8 9 10 11 12 13 ...)") ((14) "#(1 2 3 4 5 6 7 8 9 10 11 12 13 14)"))))) (let ((vect5 (make-vector '(2 3)))) (set! (vect5 0 0) vect1) (set! (vect5 0 1) vect2) (set! (vect5 0 2) vect3) (set! (vect5 1 0) vect4) (set! (vect5 1 1) (vector 1 2 3)) (set! (vect5 1 2) #2d()) (do ((i 1 (+ i 1))) ((= i 15)) (set! (*s7* 'print-length) i) (let ((str (object->string vect5))) (test str (case i ((1) "#2D((#3D(((1 ...)...)...) ...)...)") ((2) "#2D((#3D(((1 2 ...)...)...) #2D((1 2 ...)...) ...)...)") ((3) "#2D((#3D(((1 2 3)...)...) #2D((1 2 3 ...)...) #(1 2 3 ...))...)") ((4) "#2D((#3D(((1 2 3) (3 ...))...) #2D((1 2 3 4 ...)...) #(1 2 3 4 ...)) (#3D(((1 2) (3 4)...)...) ...))") ((5) "#2D((#3D(((1 2 3) (3 4 ...))...) #2D((1 2 3 4 5 ...)...) #(1 2 3 4 5 ...)) (#3D(((1 2) (3 4) (5 ...))...) #(1 2 3) ...))") ((6) "#2D((#3D(((1 2 3) (3 4 5))...) #2D((1 2 3 4 5 6)...) #(1 2 3 4 5 6 ...)) (#3D(((1 2) (3 4) (5 6))...) #(1 2 3) #2D()))") ((7) "#2D((#3D(((1 2 3) (3 4 5)) ((5 ...)...)) #2D((1 2 3 4 5 6) (7 ...)) #(1 2 3 4 5 6 7 ...)) (#3D(((1 2) (3 4) (5 6)) ((7 ...)...)) #(1 2 3) #2D()))") ((8) "#2D((#3D(((1 2 3) (3 4 5)) ((5 6 ...)...)) #2D((1 2 3 4 5 6) (7 8 ...)) #(1 2 3 4 5 6 7 8 ...)) (#3D(((1 2) (3 4) (5 6)) ((7 8)...)) #(1 2 3) #2D()))") ((9) "#2D((#3D(((1 2 3) (3 4 5)) ((5 6 1)...)) #2D((1 2 3 4 5 6) (7 8 9 ...)) #(1 2 3 4 5 6 7 8 9 ...)) (#3D(((1 2) (3 4) (5 6)) ((7 8) (9 ...)...)) #(1 2 3) #2D()))") ((10) "#2D((#3D(((1 2 3) (3 4 5)) ((5 6 1) (7 ...))) #2D((1 2 3 4 5 6) (7 8 9 10 ...)) #(1 2 3 4 5 6 7 8 9 10 ...)) (#3D(((1 2) (3 4) (5 6)) ((7 8) (9 10)...)) #(1 2 3) #2D()))") ((11) "#2D((#3D(((1 2 3) (3 4 5)) ((5 6 1) (7 8 ...))) #2D((1 2 3 4 5 6) (7 8 9 10 11 ...)) #(1 2 3 4 5 6 7 8 9 10 11 ...)) (#3D(((1 2) (3 4) (5 6)) ((7 8) (9 10) (11 ...))) #(1 2 3) #2D()))") ((12) "#2D((#3D(((1 2 3) (3 4 5)) ((5 6 1) (7 8 2))) #2D((1 2 3 4 5 6) (7 8 9 10 11 12)) #(1 2 3 4 5 6 7 8 9 10 11 12 ...)) (#3D(((1 2) (3 4) (5 6)) ((7 8) (9 10) (11 12))) #(1 2 3) #2D()))") ((13) "#2D((#3D(((1 2 3) (3 4 5)) ((5 6 1) (7 8 2))) #2D((1 2 3 4 5 6) (7 8 9 10 11 12)) #(1 2 3 4 5 6 7 8 9 10 11 12 13 ...)) (#3D(((1 2) (3 4) (5 6)) ((7 8) (9 10) (11 12))) #(1 2 3) #2D()))") ((14) "#2D((#3D(((1 2 3) (3 4 5)) ((5 6 1) (7 8 2))) #2D((1 2 3 4 5 6) (7 8 9 10 11 12)) #(1 2 3 4 5 6 7 8 9 10 11 12 13 14)) (#3D(((1 2) (3 4) (5 6)) ((7 8) (9 10) (11 12))) #(1 2 3) #2D()))"))))))) (set! (*s7* 'print-length) old-len)) (test (object->string (make-vector 3 0 #t)) "(int-vector 0 0 0)") (let ((v (make-vector '(2 2)))) (set! (v 0 0) 1) (set! (v 0 1) 2) (set! (v 1 0) 3) (set! (v 1 1) 4) (set! (v 0 1) #2d((1 2) (3 4))) (test (object->string v) "#2D((1 #2D((1 2) (3 4))) (3 4))")) (let ((v #2d((1 2) (3 4)))) (set! (v 0 1) #2d((1 2) (3 4))) (test (object->string v) "#2D((1 #2D((1 2) (3 4))) (3 4))")) (let ((v (make-vector '(2 3)))) (do ((i 0 (+ i 1))) ((= i 2)) (do ((j 0 (+ j 1))) ((= j 3)) (set! (v i j) (list i j)))) (test (v 0 0) '(0 0)) (test ((v 1 2) 0) 1) (test (v 1 2 0) 1) (test (v 1 2 0 0) 'error) (test (object->string v) "#2D(((0 0) (0 1) (0 2)) ((1 0) (1 1) (1 2)))")) (test (object->string (make-vector 3 1.0 #t)) "(float-vector 1.0 1.0 1.0)") (test (object->string (make-vector 3 -1.5 #t)) "(float-vector -1.5 -1.5 -1.5)") (test (object->string (make-vector 3 1 #t)) "(int-vector 1 1 1)") (test (object->string (make-vector 3 -1 #t)) "(int-vector -1 -1 -1)") (test (object->string (make-vector 0 0 #t)) "#()") (test (object->string (make-vector '(3 2 0) 0.0 #t)) "#()") (test (let ((v1 (make-vector '(3 2) 1)) (v2 (make-vector '(3 2) 2)) (sum 0)) (for-each (lambda (n m) (set! sum (+ sum n m))) v1 v2) sum) 18) (test (vector->list (make-vector '(2 3) 1)) '(1 1 1 1 1 1)) (test (vector->list #2d((1 2) (3 4))) '(1 2 3 4)) (test (list->vector '((1 2) (3 4))) #((1 2) (3 4))) (test (vector->list (make-vector (list 2 0))) ()) (test (vector-dimensions #2d((1 2 3))) '(1 3)) (test (#2d((1 2 3) (4 5 6)) 0 0) 1) (test (#2d((1 2 3) (4 5 6)) 0 1) 2) (test (#2d((1 2 3) (4 5 6)) 1 1) 5) (test (#3D(((1 2) (3 4)) ((5 6) (7 8))) 0 0 0) 1) (test (#3D(((1 2) (3 4)) ((5 6) (7 8))) 1 1 0) 7) (test (#4d((((1) (2)) ((3) (4)) ((5) (6)))) 0 0 0 0) 1) (test (vector? #2d((1 2) (3 4))) #t) (test ((#2d((1 #2d((2 3) (4 5))) (6 7)) 0 1) 1 0) 4) (test ((((((((((#10D((((((((((1) (1))) (((1) (1))))) (((((1) (1))) (((1) (1))))))) (((((((1) (1))) (((1) (1))))) (((((1) (1))) (((1) (1))))))))) (((((((((1) (1))) (((1) (1))))) (((((1) (1))) (((1) (1))))))) (((((((1) (1))) (((1) (1))))) (((((1) (1))) (((1) (1)))))))))) 0) 0) 0) 0) 0) 0) 0) 0) 0) 0) 1) (test (#10D((((((((((1) (1))) (((1) (1))))) (((((1) (1))) (((1) (1))))))) (((((((1) (1))) (((1) (1))))) (((((1) (1))) (((1) (1))))))))) (((((((((1) (1))) (((1) (1))))) (((((1) (1))) (((1) (1))))))) (((((((1) (1))) (((1) (1))))) (((((1) (1))) (((1) (1)))))))))) 0 0 0 0 0 0 0 0 0 0) 1) (let ((v (make-vector (make-list 100 1) 0))) (test (equal? v #100D((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((0))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) #t) (test (apply v (make-list 100 0)) 0) (test (v 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) 0)) ;; eval-string here else these are read errors (test (eval-string "#3D(((1 2) (3 4)) ((5 6) (7)))") 'error) (test (eval-string "#3D(((1 2) (3 4)) ((5) (7 8)))") 'error) (test (eval-string "#3D(((1 2) (3 4)) (() (7 8)))") 'error) (test (eval-string "#3D(((1 2) (3 4)) ((5 6) (7 8 9)))") 'error) (test (eval-string "#3D(((1 2) (3 4)) (5 (7 8 9)))") 'error) (test (eval-string "#3D(((1 2) (3 4)) ((5 6) (7 . 8)))") 'error) (test (eval-string "#3D(((1 2) (3 4)) ((5 6) (7 8 . 9)))") 'error) (test (eval-string "#3D(((1 2) (3 4)) ((5 6) ()))") 'error) (test (eval-string "#3D(((1 2) (3 4)) ((5 6)))") 'error) (test (vector-dimensions #3D(((1 2) (3 4)) ((5 6) (7 8)))) '(2 2 2)) (test (vector-dimensions #2d((1 2 3) (4 5 6))) '(2 3)) (test (vector-dimensions #4d((((1) (2)) ((3) (4)) ((5) (6))))) '(1 3 2 1)) (test (vector-length #3D(((1 2) (3 4)) ((5 6) (7 8)))) 8) (test (length #2d((1 2 3) (4 5 6))) 6) (test (#2d((1 (2) 3) (4 () 6)) 0 1) '(2)) (test (#2d((1 (2) 3) (4 () 6)) 1 1) ()) (test (#2d((1 (2) 3) (4 6 ())) 1 2) ()) (test (#2d((() (2) ()) (4 5 6)) 0 2) ()) (test (equal? (make-vector 0) (make-vector '(0))) #t) (test (equal? #() (make-vector '(0))) #t) (test (equal? #2d((1 2) (3 4)) #2D((1 2) (3 4))) #t) (test (eq? #2d((1 2) (3 4)) #2D((1 2) (3 4))) #f) (test (eqv? #2d((1 2) (3 4)) #2D((1 2) (3 4))) #f) (test (make-vector (1 . 2) "hi") 'error) (test (make-vector (cons 1 2) "hi") 'error) (test (equal? (make-vector 0) (vector)) #t) (test (equal? #() (vector)) #t) (test (equal? (make-vector 0 0 #t) (make-vector 0 0 #t)) #t) (test (equal? #() (make-vector 0 0 #t)) #t) (test (equal? (make-vector '(2 0)) (make-vector '(2 0) 0 #t)) #t) (test (equal? (make-vector '(2 0)) (make-vector '(0 2) 0 #t)) #f) (let ((v (make-vector '(2 3) 0))) (num-test (vector-length v) 6) (test (vector-dimensions v) '(2 3)) (num-test (v 0 0) 0) (num-test (v 1 2) 0) (test (v 2 2) 'error) (test (v 2 -1) 'error) (test (v 2 0) 'error) (set! (v 0 1) 1) (num-test (v 0 1) 1) (num-test (v 1 0) 0) (set! (v 1 2) 2) (num-test (v 1 2) 2) (test (set! (v 2 2) 32) 'error) (test (set! (v 1 -1) 0) 'error) (test (set! (v 2 0) 0) 'error) (num-test (vector-ref v 0 1) 1) (num-test (vector-ref v 1 2) 2) (test (vector-ref v 2 2) 'error) (test (vector-ref v 1 -1) 'error) (vector-set! v 1 1 64) (num-test (vector-ref v 1 1) 64) (num-test (vector-ref v 0 0) 0) (test (vector-ref v 1 2 3) 'error) (test (vector-set! v 1 2 3 4) 'error) (test (v 1 1 1) 'error) (test (set! (v 1 1 1) 1) 'error)) (let ((v1 (make-vector '(3 2) 0)) (v2 (make-vector '(2 3) 0)) (v3 (make-vector '(2 3 4) 0)) (v4 (make-vector 6 0)) (v5 (make-vector '(2 3) 0))) (test (equal? v1 v2) #f) (test (equal? v1 v3) #f) (test (equal? v1 v4) #f) (test (equal? v2 v2) #t) (test (equal? v3 v2) #f) (test (equal? v4 v2) #f) (test (equal? v5 v2) #t) (test (equal? v4 v3) #f) (test (vector-dimensions v3) '(2 3 4)) (test (vector-dimensions v4) '(6)) (num-test (v3 1 2 3) 0) (set! (v3 1 2 3) 32) (num-test (v3 1 2 3) 32) (num-test (vector-length v3) 24) (num-test (vector-ref v3 1 2 3) 32) (vector-set! v3 1 2 3 -32) (num-test (v3 1 2 3) -32) (test (v3 1 2) #(0 0 0 -32)) (test (set! (v3 1 2) 3) 'error) (test (vector-ref v3 1 2) #(0 0 0 -32)) (test (vector-set! v3 1 2 32) 'error)) (test (let ((v #2d((1 2) (3 4)))) (vector-fill! v #t) v) #2D((#t #t) (#t #t))) (test (eval-string "#2d((1 2) #2d((3 4) 5 6))") 'error) (test (string=? (object->string #2d((1 2) (3 #2d((3 4) (5 6))))) "#2D((1 2) (3 #2D((3 4) (5 6))))") #t) (test (string=? (object->string #3d(((#2d((1 2) (3 4)) #(1)) (#3d(((1))) 6)))) "#3D(((#2D((1 2) (3 4)) #(1)) (#3D(((1))) 6)))") #t) (test (make-vector '(2 -2)) 'error) (test (make-vector '(2 1/2)) 'error) (test (make-vector '(2 1.2)) 'error) (test (make-vector '(2 2+i)) 'error) (test (make-vector '(2 "hi")) 'error) (let ((v (make-vector '(1 1 1) 32))) (test (vector? v) #t) (test (equal? v #()) #f) (test (vector->list v) '(32)) (test (vector-ref v 0) '#2D((32))) (test (vector-set! v 0 0) 'error) (test (vector-ref v 0 0) #(32)) (test (vector-set! v 0 0 0) 'error) (test (vector-ref v 0 0 0) 32) (test (let () (vector-set! v 0 0 0 31) (vector-ref v 0 0 0)) 31) (test (vector-length v) 1) (test (vector-dimensions v) '(1 1 1)) (test (object->string v) "#3D(((31)))") ) (test (vector? #3D(((32)))) #t) (test (equal? #3D(((32))) #()) #f) (test (vector->list #3D(((32)))) '(32)) (test (#3D(((32))) 0) '#2D((32))) (test (set! (#3D(((32))) 0) 0) 'error) (test (#3D(((32))) 0 0) #(32)) (test (set! (#3D(((32))) 0 0) 0) 'error) (test (#3D(((32))) 0 0 0) 32) (test (vector-length #3D(((32)))) 1) (test (vector-dimensions #3D(((32)))) '(1 1 1)) (test (object->string #3D(((32)))) "#3D(((32)))") (let ((v1 (make-vector '(1 0)))) (test (vector? v1) #t) (test (equal? v1 #()) #f) (test (vector->list v1) ()) (test (vector-ref v1 0) 'error) (test (vector-set! v1 0 0) 'error) (test (vector-ref v1 0 0) 'error) (test (vector-set! v1 0 0 0) 'error) (test (vector-length v1) 0) (test (vector-dimensions v1) '(1 0)) (test (object->string v1) "#2D()") ) (let ((v2 (make-vector '(10 3 0)))) (test (vector? v2) #t) (test (equal? v2 #()) #f) (test (vector->list v2) ()) (test (vector-ref v2) 'error) (test (vector-set! v2 0) 'error) (test (vector-ref v2 0) 'error) (test (vector-set! v2 0 0) 'error) (test (vector-ref v2 0 0) 'error) (test (vector-set! v2 0 0 0) 'error) (test (vector-ref v2 1 2 0) 'error) (test (vector-set! v2 1 2 0 0) 'error) (test (vector-length v2) 0) (test (vector-dimensions v2) '(10 3 0)) (test (object->string v2) "#3D()") ) (let ((v3 (make-vector '(10 0 3)))) (test (vector? v3) #t) (test (equal? v3 #()) #f) (test (vector->list v3) ()) (test (vector-ref v3) 'error) (test (vector-set! v3 0) 'error) (test (vector-ref v3 0) 'error) (test (vector-set! v3 0 0) 'error) (test (vector-ref v3 0 0) 'error) (test (vector-set! v3 0 0 0) 'error) (test (vector-ref v3 1 0 2) 'error) (test (vector-set! v3 1 0 2 0) 'error) (test (vector-length v3) 0) (test (vector-dimensions v3) '(10 0 3)) (test (object->string v3) "#3D()") ) (test (((#(("hi") ("ho")) 0) 0) 1) #\i) (test (string-ref (list-ref (vector-ref #(("hi") ("ho")) 0) 0) 1) #\i) (test (equal? #2D() (make-vector '(0 0))) #t) (test (equal? #2D() (make-vector '(1 0))) #f) (test (equal? (make-vector '(2 2) 2) #2D((2 2) (2 2))) #t) (test (equal? (make-vector '(2 2) 2) #2D((2 2) (1 2))) #f) (test (equal? (make-vector '(1 2 3) 0) (make-vector '(1 2 3) 0)) #t) (test (equal? (make-vector '(1 2 3) 0) (make-vector '(1 3 2) 0)) #f) (test (make-vector '1 2 3) 'error) (test (set! (vector) 1) 'error) (test (set! (make-vector 1) 1) 'error) (test (equal? (make-vector 10 ()) (make-hash-table 10)) #f) (test (equal? #() (copy #())) #t) (test (equal? #2d() (copy #2d())) #t) (test (fill! #() 1) 1) (test (fill! #2d() 1) 1) (test (equal? #2d((1 2) (3 4)) (copy #2d((1 2) (3 4)))) #t) (test (equal? #3d() #3d(((())))) #f) (test (equal? #3d() #3d()) #t) (test (equal? #1d() #1d()) #t) (test (equal? #3d() #2d()) #f) (test (equal? #3d() (copy #3d())) #t) (test (equal? #2d((1) (2)) #2d((1) (3))) #f) (test (equal? #2d((1) (2)) (copy #2d((1) (2)))) #t) (test (equal? (make-vector '(3 0 1)) (make-vector '(3 0 2))) #f) (test (eval-string "#0d()") 'error) (let ((v #2d((1 2 3) (4 5 6)))) (let ((v1 (v 0)) (v2 (v 1))) (if (not (equal? v1 #(1 2 3))) (format-logged #t ";(v 0) subvector: ~A~%" v1)) (if (not (equal? v2 #(4 5 6))) (format-logged #t ";(v 1) subvector: ~A~%" v2)) (let ((v3 (copy v1))) (if (not (equal? v3 #(1 2 3))) (format-logged #t ";(v 0) copied subvector: ~A~%" v3)) (if (not (= (length v3) 3)) (format-logged #t ";(v 0) copied length: ~A~%" (length v3))) (if (not (equal? v3 (copy (v 0)))) (format-logged #t ";(v 0) copied subvectors: ~A ~A~%" v3 (copy (v 0))))))) (let ((v1 (make-vector '(3 2 1) #f)) (v2 (make-vector '(3 2 1) #f))) (test (equal? v1 v2) #t) (set! (v2 0 0 0) 1) (test (equal? v1 v2) #f)) (test (equal? (make-vector '(3 2 1) #f) (make-vector '(1 2 3) #f)) #f) (test (map (lambda (n) n) #2d((1 2) (3 4))) '(1 2 3 4)) (test (let ((vals ())) (for-each (lambda (n) (set! vals (cons n vals))) #2d((1 2) (3 4))) vals) '(4 3 2 1)) (test (map (lambda (x y) (+ x y)) #2d((1 2) (3 4)) #1d(4 3 2 1)) '(5 5 5 5)) (test (let ((vals ())) (for-each (lambda (x y) (set! vals (cons (+ x y) vals))) #2d((1 2) (3 4)) #1d(4 3 2 1)) vals) '(5 5 5 5)) (let ((v #2D((#(1 2) #(3 4)) (#2d((5 6) (7 8)) #2D((9 10 11) (12 13 14)))))) (test (v 0 0) #(1 2)) (test (v 0 1) #(3 4)) (test (v 1 0) #2d((5 6) (7 8))) (test (v 1 1) #2D((9 10 11) (12 13 14))) (test ((v 1 0) 0 1) 6) (test ((v 0 1) 1) 4) (test ((v 1 1) 1 2) 14)) (let ((v #2D((#((1) #(2)) #(#(3) (4))) (#2d(((5) #(6)) (#(7) #(8))) #2D((#2d((9 10) (11 12)) (13)) (14 15)))))) (test (v 0 0) #((1) #(2))) (test (v 0 1) #(#(3) (4))) (test (v 1 0) #2D(((5) #(6)) (#(7) #(8)))) (test (v 1 1) #2D((#2D((9 10) (11 12)) (13)) (14 15))) (test ((v 1 0) 0 1) #(6)) (test (((v 1 0) 0 1) 0) 6) (test ((v 0 1) 1) '(4)) (test (((v 1 1) 0 0) 1 0) 11)) (test (let ((V #2D((1 2 3) (4 5 6)))) (V 0)) #(1 2 3)) (test (let ((V #2D((1 2 3) (4 5 6)))) (V 1)) #(4 5 6)) (test (let ((V #2D((1 2 3) (4 5 6)))) (V 2)) 'error) (test (let ((V #2D((1 2 3) (4 5 6)))) (set! (V 1) 0)) 'error) (test (let ((V #2D((1 2 3) (4 5 6)))) (let ((V1 (V 0))) (set! (V1 1) 32) V)) '#2D((1 32 3) (4 5 6))) (test (let ((V #2D((1 2 3) (4 5 6)))) (let ((V1 (V 0))) (set! (V1 3) 32) V)) 'error) (test (let ((V '#3D(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) (V 1)) '#2D((7 8 9) (10 11 12))) (test (let ((V '#3D(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) (V 1 1)) #(10 11 12)) (test (let ((V '#3D(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) (V 0 1)) #(4 5 6)) (test (let ((V '#3D(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) (V 2 1)) 'error) (test (let ((V '#3D(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) ((V 0) 1)) #(4 5 6)) (test (let ((V '#3D(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) (set! (((V 0) 1) 1) 32) V) '#3D(((1 2 3) (4 32 6)) ((7 8 9) (10 11 12)))) (test (let ((V '#3D(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) (vector-set! V 0 1 1 32) V) '#3D(((1 2 3) (4 32 6)) ((7 8 9) (10 11 12)))) (test (let ((V '#3D(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) (vector-set! V 1 1 0 32) V) '#3D(((1 2 3) (4 5 6)) ((7 8 9) (32 11 12)))) (test (let ((V '#3D(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) (vector-length (V 1))) 6) (test (let ((V '#3D(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) (vector-dimensions (V 1))) '(2 3)) (test (let ((V '#3D(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) (vector-length (V 0 1))) 3) (test (let ((V '#3D(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) (vector-dimensions (V 0 1))) '(3)) (test (let ((V '#3D(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12)))) (one 1) (zero 0)) (let ((V1 (V one zero)) (sum 0)) (for-each (lambda (n) (set! sum (+ sum n))) V1) sum)) 24) ; 7 8 9 (test (let ((V '#3D(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12)))) (two 2) (one 1) (zero 0)) (let ((V10 (V one zero)) (V00 (V zero zero)) (V01 (V zero one)) (V11 (V one one)) (sum 0)) (for-each (lambda (n0 n1 n2 n3) (set! sum (+ sum n0 n1 n2 n3))) V00 V01 V10 V11) sum)) 78) (let ((old-vlen (*s7* 'print-length))) (set! (*s7* 'print-length) 32) (test (object->string (make-vector '(8 8) 0)) "#2D((0 0 0 0 0 0 0 0) (0 0 0 0 0 0 0 0) (0 0 0 0 0 0 0 0) (0 0 0 0 0 0 0 0)...)") (test (object->string (make-vector 64 0)) "#(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ...)") (test (object->string (make-vector 32 0)) "#(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)") (test (object->string (make-vector 33 0)) "#(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ...)") (test (object->string (make-vector '(8 4) 0)) "#2D((0 0 0 0) (0 0 0 0) (0 0 0 0) (0 0 0 0) (0 0 0 0) (0 0 0 0) (0 0 0 0) (0 0 0 0))") (set! (*s7* 'print-length) old-vlen)) (let ((old-vlen (*s7* 'print-length))) (set! (*s7* 'print-length) 1024) ; check the many-() case (test (object->string (make-vector '(2 1 2 1 2 1 2 1 2 1 2 1 2 1) 0)) "#14D((((((((((((((0) (0))) (((0) (0))))) (((((0) (0))) (((0) (0))))))) (((((((0) (0))) (((0) (0))))) (((((0) (0))) (((0) (0))))))))) (((((((((0) (0))) (((0) (0))))) (((((0) (0))) (((0) (0))))))) (((((((0) (0))) (((0) (0))))) (((((0) (0))) (((0) (0))))))))))) (((((((((((0) (0))) (((0) (0))))) (((((0) (0))) (((0) (0))))))) (((((((0) (0))) (((0) (0))))) (((((0) (0))) (((0) (0))))))))) (((((((((0) (0))) (((0) (0))))) (((((0) (0))) (((0) (0))))))) (((((((0) (0))) (((0) (0))))) (((((0) (0))) (((0) (0))))))))))))) (((((((((((((0) (0))) (((0) (0))))) (((((0) (0))) (((0) (0))))))) (((((((0) (0))) (((0) (0))))) (((((0) (0))) (((0) (0))))))))) (((((((((0) (0))) (((0) (0))))) (((((0) (0))) (((0) (0))))))) (((((((0) (0))) (((0) (0))))) (((((0) (0))) (((0) (0))))))))))) (((((((((((0) (0))) (((0) (0))))) (((((0) (0))) (((0) (0))))))) (((((((0) (0))) (((0) (0))))) (((((0) (0))) (((0) (0))))))))) (((((((((0) (0))) (((0) (0))))) (((((0) (0))) (((0) (0))))))) (((((((0) (0))) (((0) (0))))) (((((0) (0))) (((0) (0))))))))))))))") (test (object->string (make-vector '(16 1 1 1 1 1 1 1 1 1 1 1 1 1) 0)) "#14D((((((((((((((0))))))))))))) (((((((((((((0))))))))))))) (((((((((((((0))))))))))))) (((((((((((((0))))))))))))) (((((((((((((0))))))))))))) (((((((((((((0))))))))))))) (((((((((((((0))))))))))))) (((((((((((((0))))))))))))) (((((((((((((0))))))))))))) (((((((((((((0))))))))))))) (((((((((((((0))))))))))))) (((((((((((((0))))))))))))) (((((((((((((0))))))))))))) (((((((((((((0))))))))))))) (((((((((((((0))))))))))))) (((((((((((((0))))))))))))))") ;;; now see if our shared vector has survived... (test (and (vector? check-shared-vector-after-gc) (= (length check-shared-vector-after-gc) 6) (do ((i 0 (+ i 1)) (happy #t)) ((= i 6) happy) (if (or (not (pair? (check-shared-vector-after-gc i))) (not (equal? (check-shared-vector-after-gc i) (cons 3 i)))) (set! happy #f)))) #t) (set! check-shared-vector-after-gc #f) (set! (*s7* 'print-length) old-vlen)) ;;; -------- circular structures -------- ;;; here's an oddity: (let ((l1 (make-list 1 #f)) (l2 (make-list 3 #f))) (set-cdr! l1 l1) (set-cdr! (list-tail l2 2) l2) (test (equal? l1 l2) #t)) ; but (eq? l1 (cdr l1)): #t, and (eq? l2 (cdr l2)): #f (let ((l1 (make-list 1 #f)) (l2 (make-list 3 #f))) (set-car! l1 #t) (set-car! l2 #t) (set-cdr! l1 l1) (set-cdr! (list-tail l2 2) l2) (test (equal? l1 l2) #f)) ;;; Guile agrees on the first, but hangs on the second ;;; CL says the first is false, but hangs on the second ;;; r7rs agrees with s7 here, to my dismay. ;;; other cases: (let ((l1 (list #f #f)) (l2 (list #f #f))) (set-cdr! l1 l1) (set-cdr! (cdr l2) l2) (test (equal? l1 l2) #t)) (let ((l1 (list #f #f #f)) (l2 (list #f #f #f))) (set-cdr! (cdr l1) l1) (set-cdr! (cddr l2) l2) (test (equal? l1 l2) #f)) ; r7rs says #t I think (let ((l1 (list #f #f #f)) (l2 (list #f #f #f))) (set-cdr! (cdr l1) l1) (set-cdr! (cddr l2) (cdr l2)) (test (equal? l1 l2) #t)) ;;; Gauche says #t #f #t #t #t, as does chibi ;;; Guile-2.0 hangs on all, as does Chicken (let ((l1 (list #t #f #f)) (l2 (list #t #f #t))) (set-cdr! (cdr l1) l1) (set-cdr! (cddr l2) (cdr l2)) (test (equal? l1 l2) #t)) (let ((l1 (list #t #f #f)) (l2 (list #t #f #f #t))) (set-cdr! (cddr l1) l1) (set-cdr! (cdddr l2) (cdr l2)) (test (equal? l1 l2) #t)) ;;; cyclic-sequences (define* (make-circular-list n init) (let ((l (make-list n init))) (set-cdr! (list-tail l (- n 1)) l))) (define (cyclic? obj) (not (null? (cyclic-sequences obj)))) (for-each (lambda (arg) (test (cyclic? arg) #f)) (list "hi" "" #\null #\a () #() 1 '(1 . 2) (cons #\a #\b) #f 'a-symbol abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t :hi (if #f #f) (lambda (a) (+ a 1)) (let ((x '(1 2))) (list x x)) (let ((x #(1 2))) (vector x x)) (let ((x "a")) (list (vector x) x)) (let ((x (hash-table '(a . 1)))) (vector x (list x x) (inlet 'b x))) (let ((x '(1))) (let ((y (list x))) (list x (list y)))))) (test (cyclic-sequences) 'error) (test (cyclic-sequences (list 1 2) (list 3 4)) 'error) (test (let ((y (make-circular-list 3))) (let ((x (cyclic-sequences y))) (list (length x) (eq? (car x) y)))) '(1 #t)) (test (let ((y (make-circular-list 3))) (let ((x (cyclic-sequences (vector y)))) (list (length x) (eq? (car x) y)))) '(1 #t)) (test (let ((y (make-circular-list 3))) (let ((x (cyclic-sequences (list y (vector y))))) (list (length x) (eq? (car x) y)))) '(1 #t)) (test (let* ((y (list 1)) (x (vector y))) (set! (y 0) x) (eq? x (car (cyclic-sequences x)))) #t) (test (let ((x (hash-table (cons 'a (make-circular-list 1))))) (eq? (car (cyclic-sequences x)) (x 'a))) #t) (test (let ((x (list (make-circular-list 1) (make-circular-list 2)))) (length (cyclic-sequences x))) 2) (test (let ((l1 '(1))) (let ((l2 (cons l1 l1))) (cyclic-sequences l2))) ()) (test (let ((l1 '(1))) (let ((l2 (list l1 l1))) (cyclic-sequences l2))) ()) (test (let ((y '(1))) (let ((x (list (make-circular-list 1) y y))) (set-cdr! (cddr x) (cdr x)) (let ((z (cyclic-sequences x))) (list (length z) (and (memq (cdr x) z) #t))))) ; "and" here just to make the result easier to check '(2 #t)) (test (let ((z (vector 1 2))) (let ((y (list 1 z 2))) (let ((x (hash-table (cons 'x y)))) (set! (z 1) x) (length (cyclic-sequences z))))) 1) (test (let ((x '(1 2))) (let ((y (list x x))) (let ((z (vector x y))) (null? (cyclic-sequences z))))) #t) (test (let ((v (vector 1 2 3 4))) (let ((lst (list 1 2))) (set-cdr! (cdr lst) lst) (set! (v 0) v) (set! (v 3) lst) (length (cyclic-sequences v)))) 2) (test (infinite? (length (make-circular-list 3))) #t) (test (object->string (make-circular-list 3)) "#1=(#f #f #f . #1#)") (let ((lst (list 1 2 3))) (set! (cdr (cddr lst)) lst) (test (apply + lst) 'error) (test (cyclic? lst) #t) (test (eq? (car (cyclic-sequences lst)) lst) #t)) (let ((l1 (list 1))) (test (object->string (list l1 1 l1)) "((1) 1 (1))") ; was "(#1=(1) 1 #1#)" (test (cyclic? (list l1 1 l1)) #f)) (let ((lst (list 1 2))) (set! (cdr (cdr lst)) (cdr lst)) (test (object->string lst) "(1 . #1=(2 . #1#))") (test (object->string lst :readable) "(let (({1} #f)) (let (({lst} (make-list 2))) (let (({x} {lst})) (set-car! {x} 1) (set! {x} (cdr {x})) (set-car! {x} 2) (set-cdr! {x} (set! {1} (let (({lst} (make-list 1))) (set! {1} {lst}) (let (({x} {lst})) (set-car! {x} 2) (set-cdr! {x} {1}) ) {lst}))) ) {lst}))")) (let ((lst (list 1 2 3))) (set! (cdr (cddr lst)) lst) (test (object->string (append '(1) lst)) "(1 . #1=(1 2 3 . #1#))")) (let ((lst (list 1 2 3))) (set! (cdr (cddr lst)) lst) (test (append lst ()) 'error)) (let ((lst (list 1 2 3))) (set! (cdr (cddr lst)) lst) (test (sort! lst <) 'error)) (let ((lst (list 1 2 3))) (set! (cdr (cddr lst)) lst) (test (object->string (list lst)) "(#1=(1 2 3 . #1#))")) (let ((lst (list 1 2 3))) (set! (cdr (cddr lst)) lst) (test (object->string (make-list 4 lst)) "(#1=(1 2 3 . #1#) #1# #1# #1#)")) (let ((lst (list 1 2 3))) (set! (cdr (cddr lst)) lst) (test (object->string (vector lst lst)) "#(#1=(1 2 3 . #1#) #1#)")) (let ((lst `(+ 1 2 3))) (set! (cdr (cdddr lst)) (cddr lst)) (test (object->string lst) "(+ 1 . #1=(2 3 . #1#))")) (let ((x (list 1 2))) (test (equal? x x) #t) (test (equal? x (cdr x)) #f) (test (equal? x ()) #f)) (let ((x (list 1 (list 2 3) (list (list 4 (list 5))))) (y (list 1 (list 2 3) (list (list 4 (list 5)))))) (test (equal? x y) #t)) (let ((x (list 1 (list 2 3) (list (list 4 (list 5))))) (y (list 1 (list 2 3) (list (list 4 (list 5) 6))))) (test (equal? x y) #f)) (test (length ()) 0) (test (length (cons 1 2)) -1) (test (length '(1 2 3)) 3) (let ((lst1 (list 1 2))) (test (length lst1) 2) (list-set! lst1 0 lst1) (test (length lst1) 2) ; its car is a circular list, but it isn't (test (eq? ((cyclic-sequences lst1) 0) lst1) #t) (test (list->string lst1) 'error) (let ((lst2 (list 1 2))) (set-car! lst2 lst2) (test (equal? lst1 lst2) #t) (test (morally-equal? lst1 lst2) #t) (test (eq? lst1 lst2) #f) (test (eqv? lst1 lst2) #f) (test (pair? lst1) #t) (test (null? lst1) #f) (test (car lst2) lst2) (test (car lst1) lst1) (test (let () (fill! lst1 32) lst1) '(32 32)))) (let ((lst1 (list 1))) (test (length lst1) 1) (set-cdr! lst1 lst1) (test (infinite? (length lst1)) #t) (test (eq? (cdr ((cyclic-sequences lst1) 0)) lst1) #t) (test (null? lst1) #f) (test (pair? lst1) #t) (let ((lst2 (cons 1 ()))) (set-cdr! lst2 lst2) (test (equal? lst1 lst2) #t) (test (morally-equal? lst1 lst2) #t) (set-car! lst2 0) (test (equal? lst1 lst2) #f) (test (morally-equal? lst1 lst2) #f) (test (infinite? (length lst2)) #t))) (let ((lst1 (list 1))) (set-cdr! lst1 lst1) (test (list-tail lst1 0) lst1) (test (list-tail lst1 3) lst1) (test (list-tail lst1 10) lst1)) (let ((lst1 (let ((lst (list 'a))) (set-cdr! lst lst) lst))) (test (apply lambda lst1 (list 1)) 'error)) ; lambda parameter 'a is used twice in the lambda argument list ! (let ((lst1 (list 1)) (lst2 (list 1))) (set-car! lst1 lst2) (set-car! lst2 lst1) (test (equal? lst1 lst2) #t) (test (morally-equal? lst1 lst2) #t) (test (length lst1) 1) (let ((lst3 (list 1))) (test (equal? lst1 lst3) #f) (test (morally-equal? lst1 lst3) #f) (set-cdr! lst3 lst3) (test (equal? lst1 lst3) #f) (test (morally-equal? lst1 lst3) #f))) (let ((lst1 (list 'a 'b 'c))) (set! (cdr (cddr lst1)) lst1) (test (infinite? (length lst1)) #t) (test (memq 'd lst1) #f) (test (memq 'a lst1) lst1) (test (memq 'b lst1) (cdr lst1))) (let ((lst1 (list 1 2 3))) (list-set! lst1 1 lst1) (test (object->string lst1) "#1=(1 #1# 3)")) (let ((lst1 (let ((lst (list 1))) (set-cdr! lst lst) lst))) (test (list-ref lst1 9223372036854775807) 'error) (test (list-set! lst1 9223372036854775807 2) 'error) (test (list-tail lst1 9223372036854775807) 'error) (test (make-vector lst1 9223372036854775807) 'error) (let ((os (*s7* 'safety))) (set! (*s7* 'safety) 1) (test (not (member (map (lambda (x) x) lst1) (list () '(1)))) #f) ; geez -- just want to allow two possible ok results (test (not (member (map (lambda (x y) x) lst1 lst1) (list () '(1)))) #f) (test (for-each (lambda (x) x) lst1) #) ; was 'error (test (for-each (lambda (x y) x) lst1 lst1) #) ; was 'error (test (not (member (map (lambda (x y) (+ x y)) lst1 '(1 2 3)) (list () '(2)))) #f) (set! (*s7* 'safety) os)) ) (let ((lst1 (list 1 -1))) (set-cdr! (cdr lst1) lst1) (let ((vals (map * '(1 2 3 4) lst1))) (test vals '(1)))) ; was '(1 -2 3 -4) -- as in other cases above, map/for-each stop when a cycle is encountered (test (let ((lst '(a b c))) (set! (cdr (cddr lst)) lst) (map cons lst '(0 1 2 3 4 5))) '((a . 0) (b . 1) (c . 2))) (test (object->string (let ((l1 (list 0 1))) (set! (l1 1) l1) (copy l1))) "(0 #1=(0 #1#))") ;;; this changed 11-Mar-15 ;;;(test (object->string (let ((lst (list 1 2))) (set! (cdr lst) lst) (copy lst))) "(1 . #1=(1 . #1#))") (test (object->string (let ((lst (list 1 2))) (set! (cdr lst) lst) (copy lst))) "#1=(1 . #1#)") (test (object->string (let ((lst (list 1 2))) (set! (cdr lst) lst) lst)) "#1=(1 . #1#)") (test (object->string (let ((l1 (list 1 2))) (copy (list l1 4 l1)))) "((1 2) 4 (1 2))") ; was "(#1=(1 2) 4 #1#)" ;;;(test (object->string (let ((lst (list 1 2 3))) (set! (cdr (cddr lst)) (cdr lst)) (copy lst))) "(1 2 3 . #1=(2 3 . #1#))") (test (object->string (let ((lst (list 1 2 3))) (set! (cdr (cddr lst)) (cdr lst)) (copy lst))) "(1 . #1=(2 3 . #1#))") (test (object->string (let ((lst (list 1 2 3))) (set! (cdr (cddr lst)) (cdr lst)) lst)) "(1 . #1=(2 3 . #1#))") (test (object->string (let ((lst (list 1 2 3))) (set! (cdr (cddr lst)) (cddr lst)) (copy lst))) "(1 2 . #1=(3 . #1#))") (test (object->string (let ((lst (list 1 2 3))) (set! (cdr (cddr lst)) (cddr lst)) lst)) "(1 2 . #1=(3 . #1#))") ;;;(test (object->string (let ((lst (list 1 2 3 4))) (set! (cdr (cdddr lst)) (cddr lst)) (copy lst))) "(1 2 3 4 . #1=(3 4 . #1#))") (test (object->string (let ((lst (list 1 2 3 4))) (set! (cdr (cdddr lst)) (cddr lst)) (copy lst))) "(1 2 . #1=(3 4 . #1#))") (test (object->string (let ((lst (list 1 2 3 4))) (set! (cdr (cdddr lst)) (cddr lst)) lst)) "(1 2 . #1=(3 4 . #1#))") ;;;(test (object->string (let ((lst (list 1 2 3 4))) (set! (cdr (cdddr lst)) (cdr lst)) (copy lst))) "(1 2 3 4 . #1=(2 3 4 . #1#))") (test (object->string (let ((lst (list 1 2 3 4))) (set! (cdr (cdddr lst)) (cdr lst)) (copy lst))) "(1 . #1=(2 3 4 . #1#))") (test (object->string (let ((lst (list 1 2 3 4))) (set! (cdr (cdddr lst)) (cdr lst)) lst)) "(1 . #1=(2 3 4 . #1#))") (test (object->string (vector (let ((lst (list 1))) (set-cdr! lst lst)))) "#(#1=(1 . #1#))") (test (object->string (let ((lst (list 1 2))) (set! (cdr (cdr lst)) lst) (set! (car lst) (vector lst)) lst)) "#1=(#(#1#) 2 . #1#)") ;; these are ugly! (test (object->string (vector (let ((lst (list 1))) (set-cdr! lst lst))) :readable) "(let (({1} #f)) (vector (set! {1} (let (({lst} (make-list 1))) (set! {1} {lst}) (let (({x} {lst})) (set-car! {x} 1) (set-cdr! {x} {1}) ) {lst}))))") (test (object->string (let ((lst (list 1 2))) (set! (cdr (cdr lst)) lst) (set! (car lst) (vector lst)) lst) :readable) "(let (({1} #f)) (set! {1} (let (({lst} (make-list 2))) (set! {1} {lst}) (let (({x} {lst})) (set-car! {x} (vector {1})) (set! {x} (cdr {x})) (set-car! {x} 2) (set-cdr! {x} {1}) ) {lst})))") (test (let ((v (vector 1 2))) (set! (v 0) v) (object->string v :readable)) "(let (({1} #f)) (set! {1} (let (({v} (make-vector 2))) (set! {1} {v}) (set! ({v} 0) {1}) (set! ({v} 1) 2) {v})))") (test (let ((v (make-vector '(2 2) 0))) (set! (v 1 1) v) (object->string v :readable)) "(let (({1} #f)) (set! {1} (let (({v} (make-vector '(2 2 )))) (set! {1} {v}) (set! ({v} 0 0) 0) (set! ({v} 0 1) 0) (set! ({v} 1 0) 0) (set! ({v} 1 1) {1}) {v})))") (test (reverse '(1 2 (3 4))) '((3 4) 2 1)) (test (reverse '(1 2 3)) '(3 2 1)) (test (reverse ()) ()) (test (let ((lst (list 1 2 3))) (set! (lst 2) lst) (object->string (reverse lst))) "(#1=(1 2 #1#) 2 1)") (test (let ((l1 (cons 1 ()))) (set-cdr! l1 l1) (object->string (reverse l1))) "(#1=(1 . #1#) 1 1 1)") (test (equal? (vector 0) (vector 0)) #t) (test (equal? (vector 0 #\a "hi" (list 1 2 3)) (vector 0 #\a "hi" (list 1 2 3))) #t) (test (let ((v (vector 0))) (equal? (vector v) (vector v))) #t) (let ((v1 (make-vector 1 0))) (set! (v1 0) v1) (test (vector? v1) #t) (let ((v2 (vector 0))) (vector-set! v2 0 v2) (test (vector-length v1) 1) (test (equal? v1 v2) #t) (test (equal? (vector-ref v1 0) v1) #t) (test (equal? (vector->list v1) (list v1)) #t) (vector-fill! v1 0) (test (equal? v1 (vector 0)) #t) (let ((v3 (copy v2))) (test (equal? v2 v3) #t) (vector-set! v3 0 0) (test (equal? v3 (vector 0)) #t)) )) (let ((v1 (make-vector 1 0)) (v2 (vector 0))) (set! (v1 0) v2) (set! (v2 0) v1) (test (equal? v1 v2) #t)) (test (vector? (let ((v (vector 0))) (set! (v 0) v) (v 0 0 0 0))) #t) ; ? (let* ((l1 (list 1 2)) (v1 (vector 1 2)) (l2 (list 1 l1 2)) (v2 (vector l1 v1 l2))) (vector-set! v1 0 v2) (list-set! l1 1 l2) (test (equal? v1 v2) #f)) (let ((v1 (make-vector 1 0))) (set! (v1 0) v1) (let ((v2 (vector 0))) (vector-set! v2 0 v2) (test (equal? v1 v2) #t))) (let ((v1 (make-vector 1 0))) (set! (v1 0) v1) (test (eq? ((cyclic-sequences v1) 0) v1) #t) (test (object->string v1) "#1=#(#1#)")) (let ((l1 (cons 0 ()))) (set-cdr! l1 l1) (test (list->vector l1) 'error)) (let ((lst (list "nothing" "can" "go" "wrong"))) (let ((slst (cddr lst)) (result ())) (set! (cdr (cdddr lst)) slst) (test (do ((i 0 (+ i 1)) (l lst (cdr l))) ((or (null? l) (= i 12)) (reverse result)) (set! result (cons (car l) result))) '("nothing" "can" "go" "wrong" "go" "wrong" "go" "wrong" "go" "wrong" "go" "wrong")))) #| ;;; here is a circular function (let () (define (cfunc) (begin (display "cfunc! ") #f)) (let ((clst (procedure-source cfunc))) (set! (cdr (cdr (car (cdr (cdr clst))))) (cdr (car (cdr (cdr clst)))))) (cfunc)) |# (test (let ((l (list 1 2))) (list-set! l 0 l) (string=? (object->string l) "#1=(#1# 2)")) #t) (test (let ((lst (list 1))) (set! (car lst) lst) (set! (cdr lst) lst) (string=? (object->string lst) "#1=(#1# . #1#)")) #t) (test (let ((lst (list 1))) (set! (car lst) lst) (set! (cdr lst) lst) (equal? (car lst) (cdr lst))) #t) (test (let ((lst (cons 1 2))) (set-cdr! lst lst) (string=? (object->string lst) "#1=(1 . #1#)")) #t) (test (let ((lst (cons 1 2))) (set-car! lst lst) (string=? (object->string lst) "#1=(#1# . 2)")) #t) (test (let ((lst (cons (cons 1 2) 3))) (set-car! (car lst) lst) (string=? (object->string lst) "#1=((#1# . 2) . 3)")) #t) (test (let ((v (vector 1 2))) (vector-set! v 0 v) (string=? (object->string v) "#1=#(#1# 2)")) #t) (test (let* ((l1 (list 1 2)) (l2 (list l1))) (list-set! l1 0 l1) (string=? (object->string l2) "(#1=(#1# 2))")) #t) (test (let ((lst (list 1 2 3))) (set! (cdr (cdr (cdr lst))) lst) (object->string lst)) "#1=(1 2 3 . #1#)") (test (let ((lst (list 1 2 3))) (set! (cdr (cdr (cdr lst))) (cdr lst)) (object->string lst)) "(1 . #1=(2 3 . #1#))") (test (let ((lst (list 1 2 3))) (set! (cdr (cdr (cdr lst))) (cdr (cdr lst))) (object->string lst)) "(1 2 . #1=(3 . #1#))") (test (let ((lst (list 1 2 3))) (set! (car lst) (cdr lst)) (object->string lst)) "((2 3) 2 3)") ; was "(#1=(2 3) . #1#)" (test (let ((lst (list 1 2 3))) (set! (car (cdr lst)) (cdr lst)) (object->string lst)) "(1 . #1=(#1# 3))") (test (let ((lst (list 1 2 3))) (set! (car (cdr lst)) lst) (object->string lst)) "#1=(1 #1# 3)") (test (let ((l1 (list 1))) (let ((l2 (list l1 l1))) (object->string l2))) "((1) (1))") ; was "(#1=(1) #1#)" (test (let* ((v1 (vector 1 2)) (v2 (vector v1))) (vector-set! v1 1 v1) (string=? (object->string v2) "#(#1=#(1 #1#))")) #t) (test (let ((v1 (make-vector 3 1))) (vector-set! v1 0 (cons 3 v1)) (string=? (object->string v1) "#1=#((3 . #1#) 1 1)")) #t) (test (let ((h1 (make-hash-table 11)) (old-print-length (*s7* 'print-length))) (set! (*s7* 'print-length) 32) (hash-table-set! h1 "hi" h1) (let ((result (object->string h1))) (set! (*s7* 'print-length) old-print-length) (let ((val (string=? result "#1=(hash-table '(\"hi\" . #1#))"))) (if (not val) (format-logged #t ";hash display:~% ~A~%" (object->string h1))) val))) #t) (test (let* ((l1 (list 1 2)) (v1 (vector 1 2)) (l2 (list 1 l1 2)) (v2 (vector l1 v1 l2))) (vector-set! v1 0 v2) (list-set! l1 1 l2) (string=? (object->string v2) "#2=#(#1=(1 #3=(1 #1# 2)) #(#2# 2) #3#)")) #t) (test (let ((l1 (list 1 2)) (l2 (list 1 2))) (set! (car l1) l2) (set! (car l2) l1) (object->string (list l1 l2))) "(#1=(#2=(#1# 2) 2) #2#)") (test (let* ((l1 (list 1 2)) (l2 (list 3 4)) (l3 (list 5 l1 6 l2 7))) (set! (cdr (cdr l1)) l1) (set! (cdr (cdr l2)) l2) (string=? (object->string l3) "(5 #1=(1 2 . #1#) 6 #2=(3 4 . #2#) 7)")) #t) (test (let* ((lst1 (list 1 2)) (lst2 (list (list (list 1 (list (list (list 2 (list (list (list 3 (list (list (list 4 lst1 5)))))))))))))) (set! (cdr (cdr lst1)) lst1) (string=? (object->string lst2) "(((1 (((2 (((3 (((4 #1=(1 2 . #1#) 5))))))))))))")) #t) (test (equal? '(a) (list 'a)) #t) (test (equal? '(a b . c) '(a b . c)) #t) (test (equal? '(a b (c . d)) '(a b (c . d))) #t) (test (equal? (list "hi" "hi" "hi") '("hi" "hi" "hi")) #t) (let ((l1 (list "hi" "hi" "hi")) (l2 (list "hi" "hi" "hi"))) (fill! l1 "ho") (test (equal? l1 l2) #f) (fill! l2 (car l1)) (test (equal? l1 l2) #t)) (let ((lst (list 1 2 3 4))) (fill! lst "hi") (test (equal? lst '("hi" "hi" "hi" "hi")) #t)) (let ((vect (vector 1 2 3 4))) (fill! vect "hi") (test (equal? vect #("hi" "hi" "hi" "hi")) #t)) (let ((lst (list 1 2 (list 3 4) (list (list 5) 6)))) (test (equal? lst '(1 2 (3 4) ((5) 6))) #t) (fill! lst #f) (test (equal? lst '(#f #f #f #f)) #t)) (let ((lst (list 1 2 3 4))) (set! (cdr (cdddr lst)) lst) (test (equal? lst lst) #t) (test (eq? lst lst) #t) (test (eqv? lst lst) #t) (fill! lst #f) (test (object->string lst) "#1=(#f #f #f #f . #1#)") (let ((l1 (copy lst))) (test (equal? lst l1) #t) (test (eq? lst l1) #f) (test (eqv? lst l1) #f))) (let ((lst '(#\( #\) #\* #\+ #\, #\- #\. #\/ #\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9 #\: #\; #\< #\= #\> #\? #\@ #\A #\B #\C #\D #\E #\F #\G #\H #\I #\J #\K #\L #\M #\N #\O #\P #\Q #\R #\S #\T #\U #\V #\W #\X #\Y #\Z #\[ #\\ #\] #\^ #\_ #\` #\a #\b #\c #\d #\e #\f #\g #\h #\i #\j #\k #\l #\m #\n #\o #\p #\q #\r #\s #\t #\u #\v #\w #\x #\y #\z #\{ #\| #\} #\~))) (let ((str (apply string lst))) (let ((lstr (list->string lst))) (let ((strl (string->list str))) (test (eq? str str) #t) (test (eq? str lstr) #f) (test (eqv? str str) #t) (test (eqv? str lstr) #f) (test (equal? str lstr) #t) (test (equal? str str) #t) (test (eq? lst strl) #f) (test (eqv? lst strl) #f) (test (equal? lst strl) #t) (let ((l2 (copy lst)) (s2 (copy str))) (test (eq? l2 lst) #f) (test (eq? s2 str) #f) (test (eqv? l2 lst) #f) (test (eqv? s2 str) #f) (test (equal? l2 lst) #t) (test (equal? s2 str) #t)))))) (let ((vect #(#\( #\) #\* #\+ #\, #\- #\. #\/ #\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9 #\: #\; #\< #\= #\> #\? #\@ #\A #\B #\C #\D #\E #\F #\G #\H #\I #\J #\K #\L #\M #\N #\O #\P #\Q #\R #\S #\T #\U #\V #\W #\X #\Y #\Z #\[ #\\ #\] #\^ #\_ #\` #\a #\b #\c #\d #\e #\f #\g #\h #\i #\j #\k #\l #\m #\n #\o #\p #\q #\r #\s #\t #\u #\v #\w #\x #\y #\z #\{ #\| #\} #\~))) (let ((lst (vector->list vect))) (let ((vect1 (list->vector lst))) (test (eq? lst lst) #t) (test (eq? lst vect) #f) (test (eqv? lst lst) #t) (test (eqv? lst vect) #f) (test (equal? vect1 vect) #t) (test (equal? lst lst) #t) (test (eq? vect vect1) #f) (test (eqv? vect vect1) #f) (test (equal? vect vect1) #t) (let ((l2 (copy vect)) (s2 (copy lst))) (test (eq? l2 vect) #f) (test (eq? s2 lst) #f) (test (eqv? l2 vect) #f) (test (eqv? s2 lst) #f) (test (equal? l2 vect) #t) (test (equal? s2 lst) #t))))) (let* ((vals (list "hi" #\A 1 'a #(1) abs _ht_ _null_ _c_obj_ quasiquote macroexpand (log 0) 3.14 3/4 1.0+1.0i #\f '(1 . 2))) (vlen (length vals))) (do ((i 0 (+ i 1))) ((= i 20)) (let* ((size (max 1 (random 20))) (vect (make-vector size ()))) (do ((n 0 (+ n 1))) ((= n size)) (let ((choice (random 4)) (len (random 4))) (if (= choice 0) (let ((v (make-vector len))) (do ((k 0 (+ k 1))) ((= k len)) (vector-set! v k (list-ref vals (random vlen)))) (vector-set! vect n v)) (if (= choice 1) (let ((lst (make-list len #f))) (do ((k 0 (+ k 1))) ((= k len)) (list-set! lst k (list-ref vals (random vlen)))) (vector-set! vect n lst)) (vector-set! vect n (list-ref vals (random vlen))))))) (test (eq? vect vect) #t) (test (eqv? vect vect) #t) (test (equal? vect vect) #t) (let ((lst1 (vector->list vect))) (let ((lst2 (copy lst1))) (test (eq? lst1 lst2) #f) (test (eqv? lst1 lst2) #f) (test (equal? lst1 lst2) #t)))))) (let* ((lst1 (list 1 2 3)) (vec1 (vector 1 2 lst1))) (list-set! lst1 2 vec1) (let* ((lst2 (list 1 2 3)) (vec2 (vector 1 2 lst2))) (list-set! lst2 2 vec2) (test (equal? lst1 lst2) #t) (test (equal? vec1 vec2) #t) (vector-set! vec1 1 vec1) (test (equal? lst1 lst2) #f) (test (equal? vec1 vec2) #f) )) (let* ((base (list #f)) (lst1 (list 1 2 3)) (vec1 (vector 1 2 base))) (list-set! lst1 2 vec1) (let* ((lst2 (list 1 2 3)) (vec2 (vector 1 2 base))) (list-set! lst2 2 vec2) (set! (car lst1) lst1) (set! (car lst2) lst2) (set! (cdr (cddr lst1)) base) (set! (cdr (cddr lst2)) base) (test (length (cyclic-sequences lst2)) 1) (test (equal? lst1 lst2) #t) (test (equal? vec1 vec2) #t) (test (object->string lst1) "#1=(#1# 2 #(1 2 (#f)) #f)"))) ; was "#1=(#1# 2 #(1 2 #2=(#f)) . #2#)" (let ((base (list 0 #f))) (let ((lst1 (list 1 base 2)) (lst2 (list 1 base 2))) (set! (cdr (cdr base)) base) (test (equal? lst1 lst2) #t))) (let ((base1 (list 0 #f)) (base2 (list 0 #f))) (let ((lst1 (list 1 base1 2)) (lst2 (list 1 base2 2))) (set! (cdr (cdr base1)) lst2) (set! (cdr (cdr base2)) lst1) (test (equal? lst1 lst2) #t) (test (object->string lst1) "#1=(1 (0 #f 1 (0 #f . #1#) 2) 2)"))) (let () (define-macro (c?r path) (define (X-marks-the-spot accessor tree) (if (pair? tree) (or (X-marks-the-spot (cons 'car accessor) (car tree)) (X-marks-the-spot (cons 'cdr accessor) (cdr tree))) (if (eq? tree 'X) accessor #f))) (let ((body 'lst)) (for-each (lambda (f) (set! body (list f body))) (reverse (X-marks-the-spot () path))) `(dilambda (lambda (lst) ,body) (lambda (lst val) (set! ,body val))))) (define (copy-tree lis) (if (pair? lis) (cons (copy-tree (car lis)) (copy-tree (cdr lis))) lis)) (let* ((l1 '(0 (1 (2 (3 (4 (5 (6 (7 (8)))))))))) (l2 (list 0 (list 1 (list 2 (list 3 (list 4 (list 5 (list 6 (list 7 (list 8)))))))))) (l3 (copy-tree l1)) (cxr (c?r (0 (1 (2 (3 (4 (5 (6 (7 (X)))))))))))) (set! (cxr l1) 3) (set! (cxr l2) 4) (test (equal? l1 l2) #f) (test (equal? l1 l3) #f) (set! (cxr l2) 3) (test (cxr l2) 3) (test (cxr l1) 3) (test (cxr l3) 8) (test (equal? l1 l2) #t) (test (equal? l2 l3) #f)) (let* ((l1 '(0 (1 (2 (3 (4 (5 (6 (7 (8)))))))))) (l2 (list 0 (list 1 (list 2 (list 3 (list 4 (list 5 (list 6 (list 7 (list 8)))))))))) (l3 (copy-tree l1)) (cxr (c?r (0 (1 (2 (3 (4 (5 (6 (7 (8 . X)))))))))))) (set! (cxr l1) l1) (set! (cxr l2) l2) (test (equal? l1 l2) #t) (test (equal? l1 l3) #f) (test (object->string l2) "#1=(0 (1 (2 (3 (4 (5 (6 (7 (8 . #1#)))))))))")) (let* ((l1 '(0 ((((((1)))))))) (l2 (copy-tree l1)) (cxr (c?r (0 ((((((1 . X)))))))))) (set! (cxr l1) l2) (set! (cxr l2) l1) (test (equal? l1 l2) #t)) (let* ((l1 '(0 1 (2 3) 4 5)) (cxr (c?r (0 1 (2 3 . X) 4 5)))) (set! (cxr l1) (cdr l1)) (test (object->string l1) "(0 . #1=(1 (2 3 . #1#) 4 5))")) (let* ((l1 '(0 1 (2 3) 4 5)) (l2 '(6 (7 8 9) 10)) (cxr1 (c?r (0 1 (2 3 . X) 4 5))) (cxr2 (c?r (6 . X))) (cxr3 (c?r (6 (7 8 9) 10 . X))) (cxr4 (c?r (0 . X)))) (set! (cxr1 l1) (cxr2 l2)) (set! (cxr3 l2) (cxr4 l1)) (test (object->string l1) "(0 . #1=(1 (2 3 (7 8 9) 10 . #1#) 4 5))") (test (cadr l1) 1) (test (cadddr l1) 4) ) (let ((l1 '((a . 2) (b . 3) (c . 4))) (cxr (c?r ((a . 2) (b . 3) (c . 4) . X)))) (set! (cxr l1) (cdr l1)) (test (assq 'a l1) '(a . 2)) (test (assv 'b l1) '(b . 3)) (test (assoc 'c l1) '(c . 4)) (test (object->string l1) "((a . 2) . #1=((b . 3) (c . 4) . #1#))") (test (assq 'asdf l1) #f) (test (assv 'asdf l1) #f) (test (assoc 'asdf l1) #f) ) (let ((l1 '(a b c d e)) (cxr (c?r (a b c d e . X)))) (set! (cxr l1) (cddr l1)) (test (memq 'b l1) (cdr l1)) (test (memv 'c l1) (cddr l1)) (test (member 'd l1) (cdddr l1)) (test (object->string l1) "(a b . #1=(c d e . #1#))") (test (memq 'asdf l1) #f) (test (memv 'asdf l1) #f) (test (member 'asdf l1) #f) (test (pair? (member 'd l1)) #t) ; #1=(d e c . #1#) ) (let ((ctr 0) (x 0)) (let ((lst `(call-with-exit (lambda (return) (set! x (+ x 1)) (if (> x 10) (return x) 0))))) (let ((acc1 (c?r (call-with-exit (lambda (return) . X)))) (acc2 (c?r (call-with-exit (lambda (return) (set! x (+ x 1)) (if (> x 10) (return x) 0) . X))))) (set! (acc2 lst) (acc1 lst)) (test (eval lst) 11)))) ) (let () ;; anonymous recursion... (define (fc?r path) (define (X-marks-the-spot accessor tree) (if (pair? tree) (or (X-marks-the-spot (cons 'car accessor) (car tree)) (X-marks-the-spot (cons 'cdr accessor) (cdr tree))) (if (eq? tree 'X) accessor #f))) (let ((body 'lst)) (for-each (lambda (f) (set! body (list f body))) (reverse (X-marks-the-spot () path))) (let ((getter (apply lambda '(lst) body ())) (setter (apply lambda '(lst val) `(set! ,body val) ()))) (dilambda getter setter)))) (let ((body '(if (not (pair? (cdr lst))) lst (begin (set! lst (cdr lst)) X)))) ; X is where we jump back to the start (let ((recurse (fc?r body))) (set! (recurse body) body) (test ((apply lambda '(lst) body ()) '(1 2 3)) '(3))))) (let ((v #2d((1 2) (3 4)))) (set! (v 1 0) v) (test (object->string v) "#1=#2D((1 2) (#1# 4))") (test (length v) 4) (test ((((v 1 0) 1 0) 1 0) 0 0) 1)) (let ((lst (list 1 2 3))) (set! (cdr (cddr lst)) lst) (test (lst 100) 2) (test ((cdddr (cdddr (cdddr lst))) 100) 2) (set! (lst 100) 32) (test (object->string lst) "#1=(1 32 3 . #1#)")) (let* ((l1 (list 1 2)) (l2 (list l1 l1))) (set! (l1 0) 32) (test (equal? l2 '((32 2) (32 2))) #t)) (let ((q (list 1 2 3 4))) (set! (cdr (cdddr q)) q) (test (car q) 1) (set! (car q) 5) (set! q (cdr q)) (test (car q) 2) (test (object->string q) "#1=(2 3 4 5 . #1#)")) (let () (define make-node vector) (define prev (dilambda (lambda (node) (node 0)) (lambda (node val) (set! (node 0) val)))) (define next (dilambda (lambda (node) (node 2)) (lambda (node val) (set! (node 2) val)))) (define data (dilambda (lambda (node) (node 1)) (lambda (node val) (set! (node 1) val)))) (let* ((head (make-node () 0 ())) (cur head)) (do ((i 1 (+ i 1))) ((= i 8)) (let ((next-node (make-node cur i ()))) (set! (next cur) next-node) (set! cur (next cur)))) (set! (next cur) head) (set! (prev head) cur) (test (object->string head) "#1=#(#7=#(#6=#(#5=#(#4=#(#3=#(#2=#(#8=#(#1# 1 #2#) 2 #3#) 3 #4#) 4 #5#) 5 #6#) 6 #7#) 7 #1#) 0 #8#)") #| ;; in CL: (let* ((head (vector nil 0 nil)) (cur head)) (do ((i 1 (+ i 1))) ((= i 8)) (let ((node (vector nil i nil))) (setf (aref node 0) cur) (setf (aref cur 2) node) (setf cur node))) (setf (aref head 0) cur) (setf (aref cur 2) head) (format t "~A~%" head)) -> "#1=#(#2=#(#3=#(#4=#(#5=#(#6=#(#7=#(#8=#(#1# 1 #7#) 2 #6#) 3 #5#) 4 #4#) 5 #3#) 6 #2#) 7 #1#) 0 #8#)" |# (let ((ahead (do ((cur head (next cur)) (dat () (cons (data cur) dat))) ((member (data cur) dat) (reverse dat))))) (let ((behind (do ((cur (prev head) (prev cur)) (dat () (cons (data cur) dat))) ((member (data cur) dat) dat)))) (test (equal? ahead behind) #t))))) (let () (define make-node list) (define prev (dilambda (lambda (node) (node 0)) (lambda (node val) (set! (node 0) val)))) (define next (dilambda (lambda (node) (node 2)) (lambda (node val) (set! (node 2) val)))) (define data (dilambda (lambda (node) (node 1)) (lambda (node val) (set! (node 1) val)))) (let* ((head (make-node () 0 ())) (cur head)) (do ((i 1 (+ i 1))) ((= i 8)) (let ((next-node (make-node cur i ()))) (set! (next cur) next-node) (set! cur (next cur)))) (set! (next cur) head) (set! (prev head) cur) (test (object->string head) "#1=(#7=(#6=(#5=(#4=(#3=(#2=(#8=(#1# 1 #2#) 2 #3#) 3 #4#) 4 #5#) 5 #6#) 6 #7#) 7 #1#) 0 #8#)") (let ((ahead (do ((cur head (next cur)) (dat () (cons (data cur) dat))) ((member (data cur) dat) (reverse dat))))) (let ((behind (do ((cur (prev head) (prev cur)) (dat () (cons (data cur) dat))) ((member (data cur) dat) dat)))) (test (equal? ahead behind) #t)))) (let* ((head (make-node () 0 ())) (cur head)) (do ((i 1 (+ i 1))) ((= i 32)) (let ((next-node (make-node cur i ()))) (set! (next cur) next-node) (set! cur (next cur)))) (set! (next cur) head) (set! (prev head) cur) (test (object->string head) "#1=(#31=(#30=(#29=(#28=(#27=(#26=(#25=(#24=(#23=(#22=(#21=(#20=(#19=(#18=(#17=(#16=(#15=(#14=(#13=(#12=(#11=(#10=(#9=(#8=(#7=(#6=(#5=(#4=(#3=(#2=(#32=(#1# 1 #2#) 2 #3#) 3 #4#) 4 #5#) 5 #6#) 6 #7#) 7 #8#) 8 #9#) 9 #10#) 10 #11#) 11 #12#) 12 #13#) 13 #14#) 14 #15#) 15 #16#) 16 #17#) 17 #18#) 18 #19#) 19 #20#) 20 #21#) 21 #22#) 22 #23#) 23 #24#) 24 #25#) 25 #26#) 26 #27#) 27 #28#) 28 #29#) 29 #30#) 30 #31#) 31 #1#) 0 #32#)"))) (test (let ((lst (list 1 2 3))) (set! (cdr (cddr lst)) lst) (append lst lst ())) 'error) (test (let ((lst (list 1 2 3))) (set! (cdr (cddr lst)) lst) (object->string (append (list lst) (list lst) ()))) "(#1=(1 2 3 . #1#) #1#)") (let ((ht (make-hash-table 3))) (set! (ht "hi") ht) (test (object->string ht) "#1=(hash-table '(\"hi\" . #1#))") (test (equal? (ht "hi") ht) #t)) (let ((l1 '(0)) (l2 '(0))) (set! (car l1) l1) (set! (cdr l1) l1) (set! (car l2) l2) (set! (cdr l2) l2) (test (object->string l1) "#1=(#1# . #1#)") (test (equal? l1 l2) #t) (set! (cdr l1) l2) (test (object->string l1) "#1=(#1# . #2=(#2# . #2#))") (test (equal? l1 l2) #t) (set! (cdr l1) ()) (test (equal? l1 l2) #f)) (let ((lst (list 1 2 3))) (set! (cdr (cddr lst)) lst) (test (map (lambda (a b) (+ a b)) (list 4 5 6) lst) '(5 7 9))) (test (let ((lst (list 1 2 3)) (result ())) (set! (cdr (cddr lst)) lst) (for-each (lambda (a b) (set! result (cons (+ a b) result))) (list 4 5 6) lst) result) '(9 7 5)) (let ((lst (list 1 2 3))) (set! (cdr (cddr lst)) lst) (test (map (lambda (a b) (+ a b)) (vector 4 5 6) lst) '(5 7 9))) (test (let ((lst (list 1 2 3))) (set! (cdr (cddr lst)) lst) (map (lambda (a b) (+ a b)) (vector 4 5 6 7 8 9 10) lst)) '(5 7 9)) ; this now quits when it sees the cycle ;'(5 7 9 8 10 12 11)) (test (map (lambda (a) a) '(0 1 2 . 3)) '(0 1 2)) (test (let ((ctr 0)) (for-each (lambda (a) (set! ctr (+ ctr a))) '(1 2 . 3)) ctr) 3) (let ((lst (list 1 2 3))) (set! (cdr (cddr lst)) lst) (test (map (lambda (a b) (+ a b)) () lst) ())) (test (let ((lst (list 1 2 3)) (ctr 0)) (set! (cdr (cddr lst)) lst) (for-each (lambda (a b) (set! ctr (+ ctr (+ a b)))) lst ()) ctr) 0) (test (let ((lst (list 1))) (set! (cdr lst) (car lst)) (object->string lst)) "(1 . 1)") (test (let ((lst (list 1))) (set! (car lst) (cdr lst)) (object->string lst)) "(())") (let ((ctr 0) (lst `(let ((x 3)) (set! ctr (+ ctr 1)) (set! (cdr (cddr lst)) `((+ x ctr))) (+ x 1)))) (test (eval lst) 4) (test (eval lst) 5) (test (eval lst) 6)) (let () (define fact ; Reini Urban, http://autocad.xarch.at/lisp/self-mod.lsp.txt (let ((old ()) (result ())) (define (last lst) (list-tail lst (- (length lst) 1))) (define (butlast lis) (let ((len (length lis))) (if (<= len 1) () (let ((result ())) (do ((i 0 (+ i 1)) (lst lis (cdr lst))) ((= i (- len 1)) (reverse result)) (set! result (cons (car lst) result))))))) (lambda (n) (cond ((zero? n) 1) (#t (set! old (procedure-source fact)) (set! fact (apply lambda '(n) `((cond ,@(butlast (cdr (car (cdr (cdr old))))) ((= n ,n) ,(let () (set! result (* n (fact (- n 1)))) result)) ,@(last (cdr (car (cdr (cdr old))))))))) result))))) (test (fact 3) 6) (test (fact 5) 120) (test (fact 2) 2)) (test (let ((f #f)) (set! f (lambda () (let* ((code (procedure-source f)) (pos (- (length code) 1))) (set! (code pos) (+ (code pos) 1))) 1)) (f) (f) (f)) 4) (let* ((x (list 1 2 3)) ; from Lambda the Ultimate I think -- I lost the reference (y (list 4 5)) (z (cons (car x) (cdr y))) (w (append y z)) (v (cons (cdr x) (cdr y)))) (set-car! x 6) (set-car! y 7) (set-cdr! (cdr x) (list 8)) (test (object->string (list x y z w v)) "((6 2 8) (7 5) (1 5) (4 5 1 5) ((2 8) 5))")) ;; was "((6 . #3=(2 8)) (7 . #1=(5)) #2=(1 . #1#) (4 5 . #2#) (#3# . #1#))" ;; circular eval (test (let ((e (list (list '+ 1)))) (set-cdr! (car e) e) (eval e)) 'error) (test (let ((e (list (list '+ 1 2)))) (set-cdr! (cdar e) e) (eval e)) 'error) (test (let ((e (list (list '+ 1 2) 3))) (set-cdr! (cdar e) e) (eval e)) 'error) (test (let ((e (list (list '+ 1) 3 4))) (set-cdr! (cdar e) e) (eval e)) 'error) (test (let ((x '(1 2 3))) (set! (x 0) (cons x 2)) (eval ({list} 'let () ({list} 'define '(f1) ({list} 'list-set! x 0 ({list} 'cons x 2))) '(catch #t f1 (lambda a 'error))))) 'error) (test (let ((x '(car (list 1 2 3)))) (set! (x 0) x) (eval ({list} 'let () ({list} 'define '(f1) x) '(catch #t f1 (lambda a 'error))))) 'error) #| (define (for-each-permutation func vals) ; for-each-combination -- use for-each-subset below "(for-each-permutation func vals) applies func to every permutation of vals" ;; (for-each-permutation (lambda args (format-logged #t "~{~A~^ ~}~%" args)) '(1 2 3)) (define (pinner cur nvals len) (if (= len 1) (apply func (cons (car nvals) cur)) (do ((i 0 (+ i 1))) ; I suppose a named let would be more Schemish ((= i len)) (let ((start nvals)) (set! nvals (cdr nvals)) (let ((cur1 (cons (car nvals) cur))) ; add (car nvals) to our arg list (set! (cdr start) (cdr nvals)) ; splice out that element and (pinner cur1 (cdr start) (- len 1)) ; pass a smaller circle on down (set! (cdr start) nvals)))))) ; restore original circle (let ((len (length vals))) (set-cdr! (list-tail vals (- len 1)) vals) ; make vals into a circle (pinner () vals len) (set-cdr! (list-tail vals (- len 1)) ()))) ; restore its original shape |# #| ;; a slightly faster version (avoids consing and some recursion) (define (for-each-permutation func vals) ; for-each-combination -- use for-each-subset below "(for-each-permutation func vals) applies func to every permutation of vals" ;; (for-each-permutation (lambda args (format-logged #t "~A~%" args)) '(1 2 3)) (let ((cur (make-list (length vals)))) (define (pinner nvals len) (if (= len 2) (begin (set! (cur 0) (car nvals)) (set! (cur 1) (cadr nvals)) (apply func cur) (set! (cur 1) (car nvals)) (set! (cur 0) (cadr nvals)) (apply func cur)) (do ((i 0 (+ i 1))) ; I suppose a named let would be more Schemish ((= i len)) (let ((start nvals)) (set! nvals (cdr nvals)) (set! (cur (- len 1)) (car nvals)) (set! (cdr start) (cdr nvals)) ; splice out that element and (pinner (cdr start) (- len 1)) ; pass a smaller circle on down (set! (cdr start) nvals))))) ; restore original circle (let ((len (length vals))) (set-cdr! (list-tail vals (- len 1)) vals) ; make vals into a circle (pinner vals len) (set-cdr! (list-tail vals (- len 1)) ())))) ; restore its original shape |# ;; and continuing down that line... (define (for-each-permutation func vals) ; for-each-combination -- use for-each-subset below "(for-each-permutation func vals) applies func to every permutation of vals" ;; (for-each-permutation (lambda args (format-logged #t "~A~%" args)) '(1 2 3)) (let ((cur (make-list (length vals)))) (define (pinner nvals len) (if (= len 3) (let ((a0 (car nvals)) (a1 (cadr nvals)) (a2 (caddr nvals)) (c1 (cdr cur)) (c2 (cddr cur))) (set-car! cur a2) (set-car! c1 a0) (set-car! c2 a1) (apply func cur) (set-car! cur a0) (set-car! c1 a2) ;(set-car! c2 a1) (apply func cur) ;(set-car! cur a0) (set-car! c1 a1) (set-car! c2 a2) (apply func cur) (set-car! cur a1) (set-car! c1 a0) ;(set-car! c2 a2) (apply func cur) ;(set-car! cur a1) (set-car! c1 a2) (set-car! c2 a0) (apply func cur) (set-car! cur a2) (set-car! c1 a1) ;(set-car! c2 a0) (apply func cur) ) (do ((i 0 (+ i 1))) ((= i len)) (let ((start nvals)) (set! nvals (cdr nvals)) (list-set! cur (- len 1) (car nvals)) (set! (cdr start) (cdr nvals)) ; splice out that element and (pinner (cdr start) (- len 1)) ; pass a smaller circle on down (set! (cdr start) nvals))))) ; restore original circle (let ((len (length vals))) (if (< len 2) (apply func vals) (if (= len 2) (let ((c1 (cdr cur))) (set-car! cur (car vals)) (set-car! c1 (cadr vals)) (apply func cur) (set-car! c1 (car vals)) (set-car! cur (cadr vals)) (apply func cur)) (begin (set-cdr! (list-tail vals (- len 1)) vals) ; make vals into a circle (pinner vals len) (set-cdr! (list-tail vals (- len 1)) ()))))))) ; restore its original shape (when full-test (let() (define ops '(+ *)) (define args '(1 pi 1+i 2/3 x y)) (define (listify lst) ((if (memq (car lst) ops) list (if (null? (cdr lst)) append values)) (if (null? (cdr lst)) (car lst) (values (car lst) (listify (cdr lst)))))) (call-with-output-file "t923.scm" (lambda (p) (let ((fctr 0)) (for-each-permutation (lambda lst (let ((expr (list (listify lst)))) (format p "(define (f~D x y) ~{~^~S ~})~%" fctr expr) (format p "(let ((e1 (f~D 3 4)))~%" fctr) (format p " (let ((e2 (let ((x 3) (y 4)) ~{~^~S ~})))~%" expr) (format p " (let ((e3 (let ((x 3) (y 4)) (f~D x y))))~%" fctr) (format p " (if (not (= e1 e2 e3))~% (format *stderr* \"~{~^~S ~}: ~~A ~~A ~~A~~%\" e1 e2 e3)))))~%~%" expr)) (set! fctr (+ fctr 1))) (append ops args))))) (load "t923.scm"))) ;; t224 also applies this to +/* (let ((perms '((3 1 2) (1 3 2) (1 2 3) (2 1 3) (2 3 1) (3 2 1))) (pos ())) (for-each-permutation (lambda args (call-with-exit (lambda (ok) (let ((ctr 0)) (for-each (lambda (a) (if (equal? a args) (begin (set! pos (cons ctr pos)) (ok))) (set! ctr (+ ctr 1))) perms))))) '(1 2 3)) (test pos '(5 4 3 2 1 0))) (test (let ((v1 (make-vector 16 0)) (v2 (make-vector 16 0))) (set! (v2 12) v2) (set! (v1 12) v1) (equal? v1 v2)) ; hmmm -- not sure this is correct #t) (test (let ((lst1 (list 1)) (lst2 (list 1))) (set-cdr! lst1 lst1) (set-cdr! lst2 lst2) (equal? lst1 lst2)) #t) (test (let ((hi 3)) (let ((e (curlet))) (set! hi (curlet)) (object->string e))) "#1=(inlet 'hi (inlet 'e #1#))") (let ((e (inlet 'a 0 'b 1))) (let ((e1 (inlet 'a e))) (set! (e 'b) e1) (test (equal? e (copy e)) #t) (test (object->string e) "#1=(inlet 'a 0 'b (inlet 'a #1#))"))) ;; eval circles -- there are many more of these that will cause stack overflow (test (let ((x '(1 2 3))) (set! (x 0) (cons x 2)) (eval `(let () (define (f1) (list-set! ,x 0 (cons ,x 2))) (catch #t f1 (lambda a 'error))))) 'error) (test (let ((x '(car (list 1 2 3)))) (set! (x 0) x) (eval `(let () (define (f1) ,x) (catch #t f1 (lambda a 'error))))) 'error) (test (apply + (cons 1 2)) 'error) (test (let ((L (list 0))) (set-cdr! L L) (apply + L)) 'error) (test (let ((L (list 0))) (set-cdr! L L) (format #f "(~S~{~^ ~S~})~%" '+ L)) 'error) (test (apply + (list (let ((L (list 0 1))) (set-cdr! L L) L))) 'error) (test (apply + (let ((L (list 0 1))) (set-cdr! L L) L)) 'error) (test (length (let ((E (inlet 'value 0))) (varlet E 'self E))) 2) ;(test (apply case 2 (list (let ((L (list (list 0 1)))) (set-cdr! L L) L))) 'error) ;(test (apply cond (list (let ((L (list 0 1))) (set-cdr! L L) L))) 'error) ;(test (apply quote (let ((L (list 0 1))) (set-car! L L) L)) 'error) ;(test (apply letrec (hash-table) (let ((L (list 0 1))) (set-car! L L) L)) 'error) ;I now think the caller should check for these, not s7 ;;; -------------------------------------------------------------------------------- ;;; HOOKS ;;; make-hook ;;; hook-functions ;;; -------------------------------------------------------------------------------- (let ((old-hook (hook-functions *error-hook*))) (for-each (lambda (arg) (test (set! *unbound-variable-hook* arg) 'error) (test (set! *missing-close-paren-hook* arg) 'error) (test (set! *load-hook* arg) 'error) (test (set! (hook-functions *unbound-variable-hook*) arg) 'error) (test (set! (hook-functions *missing-close-paren-hook*) arg) 'error) (test (set! (hook-functions *error-hook*) arg) 'error) (test (set! (hook-functions *load-hook*) arg) 'error) (test (set! (hook-functions *unbound-variable-hook*) (list arg)) 'error) (test (set! (hook-functions *missing-close-paren-hook*) (list arg)) 'error) (test (set! (hook-functions *error-hook*) (list arg)) 'error) (test (set! (hook-functions *load-hook*) (list arg)) 'error) ) (list -1 #\a #(1 2 3) 3.14 3/4 1.0+1.0i 'hi :hi # #(1 2 3) #(()) "hi" '(1 . 2) '(1 2 3))) (set! (hook-functions *error-hook*) old-hook)) (let ((old-hook (hook-functions *unbound-variable-hook*)) (hook-val #f)) (set! (hook-functions *unbound-variable-hook*) (list (lambda (hook) (set! hook-val (hook 'variable)) (set! (hook 'result) 123)))) (let ((val (catch #t (lambda () (+ 1 one-two-three)) (lambda args 'error)))) (test val 124)) (test (equal? one-two-three 123) #t) (test (equal? hook-val 'one-two-three) #t) (set! (hook-functions *unbound-variable-hook*) old-hook)) (let ((old-hook (hook-functions *unbound-variable-hook*))) (set! (hook-functions *unbound-variable-hook*) (list (lambda (hook) (set! (hook 'result) 32)))) (let ((val (+ 1 _an_undefined_variable_i_hope_))) (test val 33)) (let ((val (* _an_undefined_variable_i_hope_ _an_undefined_variable_i_hope_))) (test val 1024)) (set! (hook-functions *unbound-variable-hook*) old-hook)) (let ((old-hook (hook-functions *unbound-variable-hook*)) (x #f)) (set! (hook-functions *unbound-variable-hook*) (list (lambda (hook) (set! x 0) (set! (hook 'result) #)) (lambda (hook) (set! (hook 'result) 32)) (lambda (hook) (if (not (number? (hook 'result))) (format *stderr* "oops -- *unbound-variable-hook* func called incorrectly~%"))))) (let ((val (+ 1 _an_undefined_variable_i_hope_))) (test val 33)) (test x 0) (test (+ 1 _an_undefined_variable_i_hope_) 33) (set! (hook-functions *unbound-variable-hook*) old-hook)) (let ((old-load-hook (hook-functions *load-hook*)) (val #f)) (with-output-to-file "load-hook-test.scm" (lambda () (format-logged #t "(define (load-hook-test val) (+ val 1))"))) (set! (hook-functions *load-hook*) (list (lambda (hook) (if (or val (defined? 'load-hook-test)) (format-logged #t ";*load-hook*: ~A ~A?~%" val load-hook-test)) (set! val (hook 'name))))) (load "load-hook-test.scm") (if (or (not (string? val)) (not (string=? val "load-hook-test.scm"))) (format-logged #t ";*load-hook-test* file: ~S~%" val)) (if (not (defined? 'load-hook-test)) (format-logged #t ";load-hook-test function not defined?~%") (if (not (= (load-hook-test 1) 2)) (format-logged #t ";load-hook-test: ~A~%" (load-hook-test 1)))) (set! (hook-functions *load-hook*) old-load-hook)) (let ((old-hook (hook-functions *error-hook*))) (set! (hook-functions *error-hook*) ()) (test (hook-functions *error-hook*) ()) (set! (hook-functions *error-hook*) (list (lambda (hook) #f))) (test (list? (hook-functions *error-hook*)) #t) (set! (hook-functions *error-hook*) ()) ; (set! *error-hook* (lambda (tag args) #f)) ; this no longer works (21-Sep-12) ; (test (list? (hook-functions *error-hook*)) #t) (set! (hook-functions *error-hook*) old-hook)) (let ((old-hook (hook-functions *missing-close-paren-hook*))) (set! (hook-functions *missing-close-paren-hook*) (list (lambda (h) (set! (h 'result) 'incomplete-expr)))) (test (catch #t (lambda () (eval-string "(+ 1 2")) (lambda args (car args))) 'incomplete-expr) (test (catch #t (lambda () (eval-string "(")) (lambda args (car args))) 'incomplete-expr) (test (catch #t (lambda () (eval-string "(abs ")) (lambda args (car args))) 'incomplete-expr) (set! (hook-functions *missing-close-paren-hook*) old-hook)) (let ((h (make-hook 'x))) (test (procedure? h) #t) (test (eq? h h) #t) (test (eqv? h h) #t) (test (equal? h h) #t) (test (morally-equal? h h) #t) (let ((h1 (copy h))) (test (eq? h h1) #f) ; fluctutates... (test (morally-equal? h h1) #t)) (test (hook-functions h) ()) (test (h) #) (test (h 1) #) (test (h 1 2) 'error) (let ((f1 (lambda (hook) (set! (hook 'result) (hook 'x))))) (set! (hook-functions h) (list f1)) (test (member f1 (hook-functions h)) (list f1)) (test (hook-functions h) (list f1)) (test (h 1) 1) (set! (hook-functions h) ()) (test (hook-functions h) ()) (let ((f2 (lambda* args (set! ((car args) 'result) ((car args) 'x))))) (set! (hook-functions h) (list f2)) (test (hook-functions h) (list f2)) (test (h 1) 1))) (for-each (lambda (arg) (test (set! (hook-functions h) arg) 'error)) (list "hi" #f (integer->char 65) 1 (list 1 2) '#t '3 (make-vector 3) 3.14 3/4 1.0+1.0i #\f :hi # # #))) (let ((h (make-hook))) (test (procedure? h) #t) (test (procedure-documentation h) "") (test (hook-functions h) ()) (test (h) #) (test (h 1) 'error) (let ((f1 (lambda (hook) (set! (hook 'result) 123)))) (set! (hook-functions h) (list f1)) (test (member f1 (hook-functions h)) (list f1)) (test (hook-functions h) (list f1)) (test (h) 123) (set! (hook-functions h) ()) (test (hook-functions h) ()) (let ((f2 (lambda* args (set! ((car args) 'result) 321)))) (set! (hook-functions h) (list f2)) (test (hook-functions h) (list f2)) (test (h) 321)))) (let ((h (make-hook '(a 32) 'b))) (test (procedure? h) #t) (test (hook-functions h) ()) (test (h) #) (test (h 1) #) (test (h 1 2) #) (test (h 1 2 3) 'error) (let ((f1 (lambda (hook) (set! (hook 'result) (+ (hook 'a) (or (hook 'b) 0)))))) (set! (hook-functions h) (list f1)) (test (member f1 (hook-functions h)) (list f1)) (test (hook-functions h) (list f1)) (test (h) 32) (test (h 1) 1) (test (h 1 2) 3) (set! (hook-functions h) ()) (test (hook-functions h) ()))) (let () (for-each (lambda (arg) (test (make-hook arg) 'error)) (list "hi" #f 1 (list 1 2) '#t '3 (make-vector 3) 3.14 3/4 1.0+1.0i #\f :hi # # #))) (let ((h (make-hook))) (let ((f1 (lambda (hook) (if (number? (hook 'result)) (set! (hook 'result) (+ (hook 'result) 1)) (set! (hook 'result) 0))))) (test (h) #) (set! (hook-functions h) (list f1)) (test (h) 0) (set! (hook-functions h) (list f1 f1 f1)) (test (h) 2))) (if (not (defined? 'hook-push)) (define (hook-push hook func) (set! (hook-functions hook) (cons func (hook-functions hook))))) (let ((h (make-hook))) (hook-push h (lambda (hook) (set! (hook 'result) 32))) (test (dynamic-wind h h h) 32) (test (catch h h h) 32) ) (let ((h (make-hook 'x))) (hook-push h (lambda (hook) (set! (hook 'result) (hook 'x)))) (test (continuation? (call/cc h)) #t) (set! (hook-functions h) (list (lambda (hook) (set! (hook 'result) (+ 1 (hook 'x)))))) (test (map h '(1 2 3)) '(2 3 4)) ) (let () (define-macro (hook . body) `(let ((h (make-hook))) (set! (hook-functions h) (list (lambda (h) (set! (h 'result) (begin ,@body))))) h)) (let ((x 0)) (define hi (hook (set! x 32) (+ 2 3 1))) (test (hi) 6) (test x 32))) (let () (define-macro (hooked-catch hook . body) `(catch #t (lambda () ,@body) (lambda args (let ((val (apply ,hook args))) (if (eq? val #) ; hook did not do anything (apply error args) ; so re-raise the error val))))) (let ((a-hook (make-hook 'error-type :rest 'error-info))) (set! (hook-functions a-hook) (list (lambda (hook) ;(format-logged #t "hooked-catch: ~A~%" (apply format #t (car (hook 'error-info)))) (set! (hook 'result) 32)))) (test (hooked-catch a-hook (abs "hi")) 32) (set! (hook-functions a-hook) ()) (test (catch #t (lambda () (hooked-catch a-hook (abs "hi"))) (lambda args 123)) 123) )) (let () (define *breaklet* #f) (define *step-hook* (make-hook 'code 'e)) (define-macro* (trace/break code . break-points) (define (caller tree) (if (pair? tree) (cons (if (pair? (car tree)) (if (and (symbol? (caar tree)) (procedure? (symbol->value (caar tree)))) (if (member (car tree) break-points) `(__break__ ,(caller (car tree))) `(__call__ ,(caller (car tree)))) (caller (car tree))) (car tree)) (caller (cdr tree))) tree)) `(call-with-exit (lambda (__top__) ,(caller code)))) (define (go . args) (and (let? *breaklet*) (apply (*breaklet* 'go) args))) (define (clear-break) (set! *breaklet* #f)) (define-macro (__call__ code) `(*step-hook* ',code (curlet))) (define-macro (__break__ code) `(begin (call/cc (lambda (go) (set! *breaklet* (curlet)) (__top__ (format #f "break at: ~A~%" ',code)))) ,code)) (set! (hook-functions *step-hook*) (list (lambda (hook) (set! (hook 'result) (eval (hook 'code) (hook 'e)))) (lambda (hook) (define (uncaller tree) (if (pair? tree) (cons (if (and (pair? (car tree)) (memq (caar tree) '(__call__ __break__))) (uncaller (cadar tree)) (uncaller (car tree))) (uncaller (cdr tree))) tree)) (format (current-output-port) ": ~A -> ~A~40T~A~%" (uncaller (hook 'code)) (hook 'result) (if (and (not (eq? (hook 'e) (rootlet))) (not (defined? '__top__ (hook 'e)))) (map values (hook 'e)) ""))))) (let ((str (with-output-to-string (lambda () (trace/break (let ((a (+ 3 1)) (b 2)) (if (> (* 2 a) b) 2 3))))))) (test (or (string=? str ": (+ 3 1) -> 4 : (* 2 a) -> 8 ((a . 4) (b . 2)) : (> (* 2 a) b) -> #t ((a . 4) (b . 2)) ") (string=? str ": (+ 3 1) -> 4 : (* 2 a) -> 8 ((b . 2) (a . 4)) : (> (* 2 a) b) -> #t ((b . 2) (a . 4)) ")) #t))) ;;; -------------------------------------------------------------------------------- ;;; HASH-TABLES ;;; -------------------------------------------------------------------------------- (let ((ht (make-hash-table))) (test (hash-table? ht) #t) (test (equal? ht ht) #t) (test (let () (hash-table-set! ht 'key 3.14) (hash-table-ref ht 'key)) 3.14) (test (let () (hash-table-set! ht "ky" 3.14) (hash-table-ref ht "ky")) 3.14) (test (let () (hash-table-set! ht 123 "hiho") (hash-table-ref ht 123)) "hiho") (test (let () (hash-table-set! ht 3.14 "hi") (hash-table-ref ht 3.14)) "hi") (test (let () (hash-table-set! ht pi "hiho") (hash-table-ref ht pi)) "hiho") (test (hash-table-ref ht "123") #f) (let ((ht1 (copy ht))) (test (hash-table? ht1) #t) (test (iterator? ht1) #f) (test (iterator? (make-iterator ht1)) #t) (test (= (length ht) (length ht1)) #t) (test (equal? ht ht1) #t) (test (eq? ht ht) #t) (test (eqv? ht ht) #t) (set! (ht 'key) 32) (set! (ht1 'key) 123) (test (and (= (ht 'key) 32) (= (ht1 'key) 123)) #t) (set! (ht "key") 321) (test (ht "key") 321) (test (ht 'key) 32) (set! (ht 123) 43) (set! (ht "123") 45) (test (ht 123) 43) (test (ht "123") 45) (test (hash-table-set! ht "1" 1) 1) (test (set! (ht "2") 1) 1) (test (set! (hash-table-ref ht "3") 1) 1) (test (hash-table-ref ht "3") 1)) (test (let () (set! (hash-table-ref ht 'key) 32) (hash-table-ref ht 'key)) 32) (for-each (lambda (arg) (test (let () (hash-table-set! ht 'key arg) (hash-table-ref ht 'key)) arg)) (list "hi" -1 #\a 1 'a-symbol #(1 2 3) 3.14 3/4 1.0+1.0i #t (list 1 2 3) '(1 . 2)))) (for-each (lambda (arg) (test (iterator? arg) #f) (test (hash-table-set! arg 'key 32) 'error)) (list "hi" () -1 #\a 1 'a-symbol #(1 2 3) 3.14 3/4 1.0+1.0i #t (list 1 2 3) '(1 . 2))) (let ((ht1 (make-hash-table 31)) (ht2 (make-hash-table 31))) (if (not (equal? ht1 ht2)) (format-logged #t ";ht1 and ht2 are empty, but not equal??~%")) ;; these 1st tests take advantage of s7's hashing function (hash-table-set! ht1 'abc 1) (hash-table-set! ht1 'abcabc 2) (hash-table-set! ht1 'abcabcabc 3) (hash-table-set! ht2 'abcabcabc 3) (hash-table-set! ht2 'abcabc 2) (hash-table-set! ht2 'abc 1) (if (not (equal? ht1 ht2)) (format-logged #t ";ht1 and ht2 have the same key value pairs, but are not equal??~%")) (test (make-hash-table 1 (call-with-exit (lambda (goto) goto))) 'error) (set! ht2 (make-hash-table 31)) (hash-table-set! ht2 'abc 1) (hash-table-set! ht2 'abcabc 2) (hash-table-set! ht2 'abcabcabc 3) (if (not (equal? ht1 ht2)) (format-logged #t ";ht1 and ht2 have the same key value pairs in the same order, but are not equal??~%")) (hash-table-set! ht2 'abc "1") (if (equal? ht1 ht2) (format-logged #t ";ht1 and ht2 are equal but values are not~%")) (hash-table-set! ht2 'abc 1) (if (not (equal? ht1 ht2)) (format-logged #t ";after reset ht1 and ht2 have the same key value pairs in the same order, but are not equal??~%")) (hash-table-set! ht2 1 'abc) (if (equal? ht1 ht2) (format-logged #t ";ht1 and ht2 are equal but entries are not~%")) (hash-table-set! ht1 1 'abc) (if (not (equal? ht1 ht2)) (format-logged #t ";after add ht1 and ht2 have the same key value pairs, but are not equal??~%")) ;; these should force chaining in any case (set! ht1 (make-hash-table 31)) (set! ht2 (make-hash-table 60)) (do ((i 0 (+ i 1))) ((= i 100)) (hash-table-set! ht1 i (* i 2)) (hash-table-set! ht2 i (* i 2))) (if (not (equal? ht1 ht2)) (format-logged #t ";ht1 and ht2 have the same (integer) key value pairs in the same order, but are not equal??~%")) (let ((h1 (hash-table* "a" 1)) (h2 (hash-table* 'a 1))) (set! (h2 "a") 1) (set! (h2 'a) #f) test (equal? h1 h2) #t) (let ((ht (make-hash-table))) (set! (ht (expt 2 40)) 40) (set! (ht (expt 2 50)) 50) (set! (ht (- (expt 2 60))) -60) ; these all hash into 0 unfortunately -- maybe fold halves? (test (ht (expt 2 40)) 40) (test (ht (expt 2 50)) 50) (test (ht (expt 2 60)) #f) (test (ht (- (expt 2 60))) -60) (test (ht (expt 2 41)) #f)) (set! ht2 (make-hash-table 31)) (do ((i 99 (- i 1))) ((< i 0)) (hash-table-set! ht2 i (* i 2))) (test (hash-table-entries ht2) 100) (if (not (equal? ht1 ht2)) (format-logged #t ";ht1 and ht2 have the same (integer) key value pairs, but are not equal??~%")) (fill! ht1 ()) (test (hash-table-entries ht1) 100) (test (ht1 32) ())) (let ((h (make-hash-table))) (test (hash-table-entries h) 0) (set! (h 'a) 1) (test (hash-table-entries h) 1) (set! (h 'a) #f) (test (hash-table-entries h) 0)) (let ((ht (make-hash-table)) (l1 '(x y z)) (l2 '(y x z))) (set! (hash-table-ref ht 'x) 123) (define (hi) (hash-table-ref ht (cadr l1))) ; 123 (test (hi) #f)) (test (make-hash-table most-positive-fixnum) 'error) ;(test (make-hash-table (+ 1 (expt 2 31))) 'error) ; out-of-memory error except in clang (test (make-hash-table most-negative-fixnum) 'error) (test (make-hash-table 21 eq? 12) 'error) (test (make-hash-table 21 12) 'error) (test (make-hash-table eq? eq?) 'error) (test (make-hash-table eq? eq? 12) 'error) (test (make-hash-table ()) 'error) (test (make-hash-table 3 ()) 'error) (test (make-hash-table eq? ()) 'error) (test (make-hash-table 0) 'error) (test (make-hash-table -4) 'error) (for-each (lambda (arg) (test (make-hash-table arg) 'error)) (list "hi" #\a 'a-symbol #(1 2 3) 3.14 3/4 1.0+1.0i #t (list 1 2 3) '(1 . 2))) (let ((ht (hash-table* :a 1/0))) (test (nan? (ht :a)) #t) (set! (ht 1/0) :a) (test (ht 1/0) :a)) ; is this just by chance? (let ((ht (make-hash-table))) (define (f1) (do ((i 0 (+ i 1))) ((= i 100)) (hash-table-set! ht i #t))) (f1) (test (hash-table-entries ht) 100) (set! ht (make-hash-table)) (define (f2) (do ((i 0 (+ i 1))) ((= i 100)) (hash-table-set! ht i 0))) (f2) (test (hash-table-entries ht) 100) (set! ht (make-hash-table)) (define (f3) (do ((i 0 (+ i 1))) ((= i 100)) (hash-table-set! ht i i))) (f3) (test (hash-table-entries ht) 100)) (let ((ht (make-hash-table))) (define (f1) (do ((i 0 (+ i 1))) ((= i 1000)) (hash-table-set! ht i #t))) (f1) (test (hash-table-entries ht) 1000)) (let ((hi (make-hash-table 7))) (test (object->string hi) "(hash-table)") (set! (hi 1) "1") (test (object->string hi) "(hash-table '(1 . \"1\"))") (set! (hi -1) "-1") (test (or (string=? (object->string hi) "(hash-table '(-1 . \"-1\") '(1 . \"1\"))") (string=? (object->string hi) "(hash-table '(1 . \"1\") '(-1 . \"-1\"))")) #t) (set! (hi 9) "9") (test (or (string=? (object->string hi) "(hash-table '(9 . \"9\") '(-1 . \"-1\") '(1 . \"1\"))") (string=? (object->string hi) "(hash-table '(9 . \"9\") '(1 . \"1\") '(-1 . \"-1\"))")) #t) (set! (hi -9) "-9") (test (or (string=? (object->string hi) "(hash-table '(-9 . \"-9\") '(9 . \"9\") '(-1 . \"-1\") '(1 . \"1\"))") (string=? (object->string hi) "(hash-table '(9 . \"9\") '(1 . \"1\") '(-9 . \"-9\") '(-1 . \"-1\"))")) #t) (test (hi 1) "1") (test (hi -1) "-1") (test (hi -9) "-9") (set! (hi 2) "2") (test (or (string=? (object->string hi) "(hash-table '(-9 . \"-9\") '(9 . \"9\") '(-1 . \"-1\") '(1 . \"1\") '(2 . \"2\"))") (string=? (object->string hi) "(hash-table '(9 . \"9\") '(1 . \"1\") '(2 . \"2\") '(-9 . \"-9\") '(-1 . \"-1\"))")) #t) (let ((old-plen (*s7* 'print-length))) (set! (*s7* 'print-length) 3) (test (or (string=? (object->string hi) "(hash-table '(-9 . \"-9\") '(9 . \"9\") '(-1 . \"-1\") ...)") (string=? (object->string hi) "(hash-table '(9 . \"9\") '(1 . \"1\") '(2 . \"2\") ...)")) #t) (set! (*s7* 'print-length) 0) (test (object->string hi) "(hash-table ...)") (test (object->string (hash-table)) "(hash-table)") (set! (*s7* 'print-length) old-plen)) ) (let ((ht (make-hash-table 277))) (test (hash-table? ht) #t) (test (>= (length ht) 277) #t) (test (hash-table-entries ht) 0) (test (let () (hash-table-set! ht 'key 3.14) (hash-table-ref ht 'key)) 3.14) (test (let () (hash-table-set! ht "ky" 3.14) (hash-table-ref ht "ky")) 3.14) (for-each (lambda (arg) (test (let () (hash-table-set! ht 'key arg) (hash-table-ref ht 'key)) arg)) (list "hi" -1 #\a 1 'a-symbol #(1 2 3) 3.14 3/4 1.0+1.0i #t (list 1 2 3) '(1 . 2)))) (for-each (lambda (arg) (test (hash-table? arg) #f)) (list "hi" -1 #\a 1 'a-symbol #(1 2 3) 3.14 3/4 1.0+1.0i #t #f () #(()) (list 1 2 3) '(1 . 2))) (test (hash-table? (make-vector 3 ())) #f) (test (let ((ht (make-hash-table))) (set! (ht 'a) 123) (map values ht)) '((a . 123))) (let ((ht (make-hash-table))) (test (hash-table-ref ht 'not-a-key) #f) (test (hash-table-ref ht "not-a-key") #f) (hash-table-set! ht 'key 3/4) (hash-table-set! ht "key" "hi") (test (hash-table-ref ht "key") "hi") (test (hash-table-ref ht 'key) 3/4) (hash-table-set! ht 'asd 'hiho) (test (hash-table-ref ht 'asd) 'hiho) (hash-table-set! ht 'asd 1234) (test (hash-table-ref ht 'asd) 1234)) (let ((ht (make-hash-table))) (define (ht-add h) (+ (h 1) (h 2))) (hash-table-set! ht 1 2) (hash-table-set! ht 2 3) (test (ht-add ht) 5)) (let ((let1 (inlet 'a 1)) (let2 (inlet 'a 1)) (let3 (inlet 'a 2)) (let4 (inlet 'b 1)) (let5 (inlet 'a 2 'a 1))) (test (equal? let1 let2) #t) (test (equal? let1 let3) #f) (test (equal? let1 let5) #t) (let ((hash1 (hash-table* let1 32))) (test (integer? (hash1 let1)) #t) (test (integer? (hash1 let2)) #t) (test (integer? (hash1 let3)) #f) (test (integer? (hash1 let4)) #f) (test (integer? (hash1 let5)) #t))) (test ((hash-table* 1.5 #t #f #t) #f) #t) ; this is checking hash_float if debugging (test ((hash-table* 1.5 #t 1 #t) 1) #t) (let ((let1 (inlet 'a 1 'b 2)) (let2 (inlet 'b 2 'a 1)) (let3 (inlet 'a 1 'b 1))) (test (equal? let1 let2) #t) (let ((hash1 (hash-table* let1 32))) (test (integer? (hash1 let1)) #t) (test (integer? (hash1 let2)) #t) (test (integer? (hash1 let3)) #f))) (let ((hash1 (hash-table* 'a 1 'b 2)) (hash2 (hash-table* 'b 2 'a 1))) (test (equal? hash1 hash2) #t) (let ((hash3 (hash-table* hash1 32))) (test (integer? (hash3 hash1)) #t) (test (integer? (hash3 hash2)) #t))) (let ((hash1 (hash-table* 'b 2 'a 1))) (let ((hash2 (make-hash-table (* (length hash1) 2)))) (set! (hash2 'a) 1) (set! (hash2 'b) 2) (test (equal? hash1 hash2) #t) (let ((hash3 (make-hash-table (* 2 (length hash2))))) (set! (hash3 hash1) 32) (test (integer? (hash3 hash1)) #t) (test (integer? (hash3 hash2)) #t)))) (for-each (lambda (arg) (test (hash-table-ref arg 'key) 'error)) (list "hi" -1 #\a 1 'a-symbol #(1 2 3) 3.14 3/4 1.0+1.0i #t (list 1 2 3) '(1 . 2))) (let ((ht1 (make-hash-table 653)) (ht2 (make-hash-table 277))) (test (equal? ht1 ht2) #t) ; equal? because both are empty (hash-table-set! ht1 'key 'hiho) (hash-table-set! ht2 (hash-table-ref ht1 'key) 3.14) (test (>= (length ht1) 653) #t) (test (hash-table-ref ht2 'hiho) 3.14) (test (hash-table-ref ht2 (hash-table-ref ht1 'key)) 3.14)) (let ((ht1 (make-hash-table))) (set! (ht1 1) 'hi) (let ((ht2 (make-hash-table))) (set! (ht2 1) ht1) (test ((ht2 1) 1) 'hi))) (let ((ht1 (make-hash-table))) (set! (ht1 1/0) "NaN!") (let ((nan 1/0)) (test (ht1 nan) "NaN!") (set! (ht1 nan) 0) (test (ht1 nan) 0) (if (not with-windows) (test (object->string ht1) "(hash-table '(nan.0 . 0))")))) (if (not with-bignums) (let ((ht1 (make-hash-table))) (set! (ht1 1) "1") (set! (ht1 1.0) "1.0") (test (ht1 1) "1") (set! (ht1 1/0) "nan") (test (ht1 0/0) "nan") (set! (ht1 (/ (log 0) (log 0))) "nan-nani") (test (ht1 (/ (log 0) (log 0))) "nan-nani") (test (ht1 (- 0/0)) "nan") (test (ht1 (real-part (/ (log 0) (log 0)))) "nan") (test (ht1 (complex 0/0 1/0)) "nan-nani") (set! (ht1 (real-part (log 0))) "-inf") (test (ht1 (real-part (log 0))) "-inf") (set! (ht1 (- (real-part (log 0)))) "inf") (test (ht1 (- (real-part (log 0)))) "inf") (set! (ht1 (log 0)) "log(0)") (test (ht1 (log 0)) "log(0)") (set! (ht1 (complex 80143857/25510582 1)) "pi+i") (test (ht1 (complex pi (- 1.0 1e-16))) "pi+i"))) (let ((ht (make-hash-table))) (set! (ht (string #\a #\null #\b)) 1) (test (ht (string #\a #\null #\b)) 1) (test (ht (string #\a)) #f) (set! (ht (string #\a #\null #\b)) 12) (test (ht (string #\a #\null #\b)) 12) (fill! ht #f) (test (hash-table-entries ht) 0) (set! (ht #u8(3 0 21)) 1) (test (ht #u8(3 0 21)) 1)) (let ((ht (hash-table* 'a #t))) (test (hash-table-entries ht) 1) (do ((i 0 (+ i 1))) ((= i 10)) (set! (ht 'a) #f) (set! (ht 'a) #t)) (test (hash-table-entries ht) 1)) (when with-bignums (let ((ht (make-hash-table))) (set! (ht pi) 1) (test (ht pi) 1) (set! (ht (bignum "1")) 32) (test (ht (bignum "1")) 32) (set! (ht (/ (bignum "11") (bignum "3"))) 12) (test (ht (/ (bignum "11") (bignum "3"))) 12) (set! (ht (bignum "1+i")) -1) (test (ht (bignum "1+i")) -1) (set! (ht 3) 2) (test (ht 3) 2) (set! (ht 3.0) 3) (test (ht 3.0) 3))) (test (hash-table?) 'error) (test (hash-table? 1 2) 'error) (test (make-hash-table most-positive-fixnum) 'error) (test (make-hash-table most-negative-fixnum) 'error) (test (make-hash-table 10 1) 'error) (let ((ht (make-hash-table))) (test (hash-table? ht ht) 'error) (test (hash-table-ref ht #\a #\b) 'error) (test (hash-table-ref ht) 'error) (test (hash-table-ref) 'error) (test (hash-table-set!) 'error) (test (hash-table-set! ht) 'error) (test (hash-table-set! ht #\a) 'error) (test (hash-table-set! ht #\a #\b #\c) 'error) (set! (ht 'key) 32) (test (fill! ht 123) 123) (test (ht 'key) 123) (set! (ht 'key) 32) (test (ht 'key) 32) (set! (ht :key) 123) (test (ht 'key) 32) (test (ht :key) 123) (fill! ht ()) (test (ht 'key) ())) (let ((ht (make-hash-table))) (test (hash-table-set! ht #\a 'key) 'key) (for-each (lambda (arg) (test (hash-table-set! ht arg 3.14) 3.14)) (list #\a #(1 2 3) 3/4 1.0+1.0i #t (list 1 2 3) '(1 . 2))) (for-each (lambda (arg) (test (hash-table-ref ht arg) 3.14)) (list #\a #(1 2 3) 3/4 1.0+1.0i #t (list 1 2 3) '(1 . 2))) (test (length ht 123) 'error)) (for-each (lambda (arg) (test (make-hash-table arg) 'error)) (list "hi" -1 0 #\a 'a-symbol #(1 2 3) 3.14 3/4 1.0+1.0i #t (list 1 2 3) '(1 . 2))) (let () (define ht (make-hash-table)) (set! (ht 123) "123") (set! (ht 456) "456") (define hti (make-iterator ht)) (test (iterator? hti) #t) (test (object->string hti) "#") (test (equal? hti hti) #t) (test (eq? hti hti) #t) (test (eqv? hti hti) #t) (test (morally-equal? hti hti) #t) (let ((hti2 hti)) (test (equal? hti2 hti) #t) (test (morally-equal? hti2 hti) #t) (set! hti2 (copy hti)) (test (equal? hti2 hti) #t) (test (morally-equal? hti2 hti) #t) (test (let ((val (hti2))) (or (equal? val '(123 . "123")) (equal? val '(456 . "456")))) #t) ; order depends on table size (test (equal? hti2 hti) #f) (test (morally-equal? hti2 hti) #f) ) (let ((vals (list (hti) (hti)))) (if (not (equal? (sort! vals (lambda (a b) (< (car a) (car b)))) '((123 . "123") (456 . "456")))) (format-logged #t ";iterator: ~A~%" vals)) (let ((val (hti))) (if (not (eof-object? val)) (format-logged #t ";iterator at end: ~A~%" val))) (let ((val (hti))) (if (not (eof-object? val)) (format-logged #t ";iterator at end (2): ~A~%" val))))) (test (make-iterator) 'error) (test (make-iterator (make-hash-table) 1) 'error) (test (iterator?) 'error) (test (iterator? 1 2) 'error) (let () (define (get-iter) (let ((ht (hash-table '(a . 1) '(b . 2)))) (test (hash-table-entries ht) 2) (make-iterator ht))) (let ((hti (get-iter))) (gc) (let ((a (hti))) (let ((b (hti))) (let ((c (hti))) (test (let ((lst (list a b c))) (or (equal? lst '((a . 1) (b . 2) #)) (equal? lst '((b . 2) (a . 1) #)))) #t)))))) (let ((ht1 (make-hash-table)) (ht2 (make-hash-table))) (test (equal? ht1 ht2) #t) (test (equal? ht1 (make-vector (length ht1) ())) #f) (hash-table-set! ht1 'key 'hiho) (test (equal? ht1 ht2) #f) (hash-table-set! ht2 'key 'hiho) (test (equal? ht1 ht2) #t) (hash-table-set! ht1 'a ()) (test (ht1 'a) ()) ) (let ((ht (make-hash-table 1))) (test (>= (length ht) 1) #t) (set! (ht 1) 32) (test (>= (length ht) 1) #t)) (let ((ht (hash-table '("hi" . 32) '("ho" . 1)))) (test (hash-table-entries ht) 2) (test (ht "hi") 32) (test (ht "ho") 1)) (let ((ht (hash-table* "hi" 32 "ho" 1))) (test (hash-table-entries ht) 2) (test (ht "hi") 32) (test (ht "ho") 1)) (let ((ht (hash-table))) (test (hash-table? ht) #t) (test (>= (length ht) 1) #t) (test (ht 1) #f)) (let ((ht (hash-table*))) (test (hash-table? ht) #t) (test (>= (length ht) 1) #t) (test (ht 1) #f)) (for-each (lambda (arg) (test (hash-table arg) 'error) (test (hash-table* arg) 'error) (test ((hash-table* 'a arg) 'a) arg) (test ((hash-table* arg 'a) arg) 'a)) (list "hi" -1 0 #\a 'a-symbol #(1 2 3) 3.14 3/4 1.0+1.0i #t abs # # (lambda () 1))) (let ((ht (make-hash-table)) (lst (list 1))) (set-cdr! lst lst) (set! (ht lst) lst) (let ((lst1 (list 1 2))) (set-cdr! (cdr lst1) lst1) (set! (ht lst1) lst1) (test (ht lst) lst) (test (ht lst1) lst1) (test (or (string=? (object->string ht) "(hash-table '(#1=(1 2 . #1#) . #1#) '(#2=(1 . #2#) . #2#))") (string=? (object->string ht) "(hash-table '(#1=(1 . #1#) . #1#) '(#2=(1 2 . #2#) . #2#))")) #t))) (test (set! (hash-table) 1) 'error) (test (set! (hash-table*) 1) 'error) (test (set! (make-hash-table) 1) 'error) ;; no null hash-tables? (let ((ht (make-hash-table))) (test (map (lambda (x) x) ht) ()) (test (let ((ctr 0)) (for-each (lambda (x) (set! ctr (+ ctr 1))) ht) ctr) 0) (test (map (lambda (x y) (cons x y)) (list 1 2 3) ht) ()) ;(test (let ((ctr 0)) (for-each (lambda (x) (set! ctr (+ ctr 1))) #(1 2 3) ht) ctr) 0) ; this is now an error 15-Jan-15 (test (map (lambda (x y) (cons x y)) ht "123") ()) (test (let ((ctr 0)) (for-each (lambda (x) (set! ctr (+ ctr 1))) ht ()) ctr) 'error) ; 2 args (let ((rt (reverse ht))) (test (map (lambda (x) x) rt) ()) (test (let ((ctr 0)) (for-each (lambda (x) (set! ctr (+ ctr 1))) rt) ctr) 0)) (set! (ht 1) 32) ;; these need to be independent of entry order (test (sort! (map (lambda (x) (cdr x)) ht) <) '(32)) (test (let ((ctr 0)) (for-each (lambda (x) (set! ctr (+ ctr 1))) ht) ctr) 1) (test (map (lambda (x y) (cons x y)) () ht) ()) (test (let ((ctr 0)) (for-each (lambda (x y) (set! ctr (+ ctr 1))) ht "") ctr) 0) (test (sort! (map (lambda (x y) (max (cdr x) y)) ht (list 1 2 3)) <) '(32)) (test (let ((ctr 0)) (for-each (lambda (x y) (set! ctr (max (cdr x) y))) ht #(1 2 3)) ctr) 32) (let ((rt (reverse ht))) (test (equal? (rt 32) 1) #t) (test (equal? (rt 1) #f) #t) (test (ht (rt 32)) 32) (test (sort! (map (lambda (x) (cdr x)) rt) <) '(1)) (test (let ((ctr 0)) (for-each (lambda (x) (set! ctr (+ ctr 1))) rt) ctr) 1) (for-each (lambda (x) (test (ht (rt (cdr x))) (cdr x)) (test (rt (ht (car x))) (car x))) ht) (set! (rt 32) 123) (test (rt 32) 123) (test (ht 32) #f) (test (ht 1) 32)) (set! (ht 2) 1) (test (ht (ht 2)) 32) (test (sort! (map (lambda (x) (cdr x)) ht) <) '(1 32)) (test (let ((ctr 0)) (for-each (lambda (x) (set! ctr (+ ctr 1))) ht) ctr) 2) (set! (ht 3) 123) (test (sort! (map (lambda (x) (cdr x)) ht) <) '(1 32 123)) (test (let ((ctr 0)) (for-each (lambda (x) (set! ctr (+ ctr 1))) ht) ctr) 3) (test (let ((ctr 0)) (for-each (lambda (x y) (set! ctr (+ ctr 1))) ht '(1)) ctr) 1) (test (let ((ctr 0)) (for-each (lambda (x y z) (set! ctr (+ ctr 1))) "12" ht '(1)) ctr) 1) (test (let ((ctr 0)) (for-each (lambda (x y z) (set! ctr (+ ctr 1))) "12" ht '(1 2)) ctr) 2) (test (let ((ctr 0)) (for-each (lambda (x y z) (set! ctr (+ ctr 1))) "12345" ht '(1 2 3 4 5 6)) ctr) 3) (test (sort! (map (lambda (x y) (max x (cdr y))) (list -1 -2 -3 -4) ht) <) '(1 32 123)) (test (let ((sum 0)) (for-each (lambda (x y) (set! sum (+ sum x (cdr y)))) #(10 20 30) ht) sum) 216) (let ((rt (reverse ht))) (for-each (lambda (x) (test (ht (rt (cdr x))) (cdr x)) (test (rt (ht (car x))) (car x))) ht)) (set! (ht (list 1 2 3)) "hi") (test (ht '(1 2 3)) "hi") (test (ht 2) 1) (test (let ((ctr 0)) (for-each (lambda (x) (set! ctr (+ ctr 1))) ht) ctr) 4) (set! (ht "hi") 2) (test (ht "hi") 2) (test (ht (ht (ht "hi"))) 32) (let ((rt (reverse ht))) (test (rt "hi") '(1 2 3)) (test (rt 2) "hi") (for-each (lambda (x) (test (ht (rt (cdr x))) (cdr x)) (test (rt (ht (car x))) (car x))) ht) (set! (rt 2) "ho") (test (rt 2) "ho") (test (ht '(1 2 3)) "hi") (set! (rt 123) 321) (test (rt 123) 321) (test (ht 3) 123)) (fill! ht 0) (set! (ht "hi") 1) (set! (ht "hoi") 2) (test (sort! (map (lambda (x) (cdr x)) ht) <) '(0 0 0 0 1 2)) (test (let ((ctr 0)) (for-each (lambda (x) (set! ctr (+ ctr 1))) ht) ctr) 6) (let ((rt (reverse ht))) (test (rt 2) "hoi") (set! (rt 2) "ha") (test (ht "hoi") 2)) (set! (ht #\a) #\b) (test (ht #\a) #\b) (test (ht "hi") 1) (set! ht (hash-table)) (set! (ht #(1)) #(2)) (test (ht #(1)) #(2)) (set! (ht '(1)) '(3)) (set! (ht "1") "4") ;(set! (ht ht) "5") ;(test (ht ht) "5") (test (ht '(1)) '(3)) (test (let ((ctr 0)) (for-each (lambda (x) (set! ctr (+ ctr 1))) ht) ctr) 3) (let ((rt (reverse ht))) ;(test (rt "5") ht) (test (rt "4") "1") (for-each (lambda (x) (test (ht (rt (cdr x))) (cdr x)) (test (rt (ht (car x))) (car x))) ht)) ) (let ((ht (make-hash-table))) (let ((str (string (integer->char 255))) (u8 #u8(254 0)) (rl 1e18) (int most-negative-fixnum) (rat (/ 1 most-negative-fixnum))) (set! (ht str) 1) (set! (ht u8) 2) (set! (ht rl) 3) (set! (ht int) 4) (set! (ht rat) 5) (test (ht str) 1) (test (ht u8) 2) (test (ht rl) 3) (test (ht int) 4) (test (ht rat) 5))) (let ((ht1 (make-hash-table 32)) (ht2 (make-hash-table 1024))) (do ((i 0 (+ i 1))) ((= i 256)) (let ((str (number->string i))) (set! (ht1 str) i) (set! (ht2 i) str))) (let ((cases 0)) (for-each (lambda (a b) (if (not (equal? (string->number (car a)) (cdr a))) (format-logged #t ";hash-table for-each (str . i): ~A?~%" a)) (if (not (equal? (number->string (car b)) (cdr b))) (format-logged #t ";hash-table for-each (i . str): ~A?~%" b)) (set! cases (+ cases 1))) ht1 ht2) (if (not (= cases 256)) (format-logged #t ";hash-table for-each cases: ~A~%" cases))) (let ((iter1 (make-iterator ht1)) (iter2 (make-iterator ht2))) (test (equal? iter1 iter2) #f) (test (morally-equal? iter1 iter2) #f) (test (iterator? iter2) #t) (let ((cases 0)) (do ((a (iter1) (iter1)) (b (iter2) (iter2))) ((or (eof-object? a) (eof-object? b))) (if (not (equal? (string->number (car a)) (cdr a))) (format-logged #t ";hash-table iter1 (str . i): ~A?~%" a)) (if (not (equal? (number->string (car b)) (cdr b))) (format-logged #t ";hash-table iter2 (i . str): ~A?~%" b)) (set! cases (+ cases 1))) (if (not (= cases 256)) (format-logged #t ";hash-table iter1/2 cases: ~A~%" cases))))) (let ((ht (make-hash-table 31))) (let ((ht1 (make-hash-table 31))) (set! (ht1 'a1) 'b1) (set! (ht 'a0) ht1) (test ((ht 'a0) 'a1) 'b1) (test (hash-table-ref ht 'a0 'a1) 'b1) (test (ht 'a0 'a1) 'b1))) (let ((ht (make-hash-table 31)) (e (curlet))) (define (a-func a) (+ a 1)) (define-macro (a-macro a) `(+ 1 , a)) (define (any-func a) (let ((x a)) (lambda () x))) (set! (ht abs) 1) (set! (ht begin) 2) (set! (ht quasiquote) 3) (set! (ht a-func) 4) (set! (ht a-macro) 5) (set! (ht (any-func 6)) 6) (set! (ht e) 7) (test (ht e) 7) (set! (ht (rootlet)) 8) (test (ht abs) 1) (test (ht round) #f) (test (ht quasiquote) 3) (test (ht begin) 2) (test (ht lambda) #f) (test (ht a-func) 4) (test (ht a-macro) 5) (test (ht (any-func 6)) #f) (test (ht (rootlet)) 8) (call-with-exit (lambda (return) (set! (ht return) 9) (test (ht return) 9))) ;(set! (ht ht) 10) ;(test (ht ht) 10) ) (test (let ((h1 (hash-table '(a . 1) '(b . 2))) (h2 (make-hash-table 31))) (set! (h2 'a) 1) (set! (h2 'b) 2.0) (morally-equal? h1 h2)) #t) (test (let ((h1 (hash-table '(a . 1) '(b . 2))) (h2 (make-hash-table 31))) (set! (h2 'a) 1.0) (set! (h2 'b) 2) (morally-equal? (list h1) (list h2))) #t) (test (let ((h1 (hash-table* 'a 1 'b 2)) (h2 (make-hash-table 31))) (set! (h2 'a) 1) (set! (h2 'b) 2.0) (morally-equal? h1 h2)) #t) (test (let ((h1 (hash-table* 'a 1 'b 2)) (h2 (make-hash-table 31))) (set! (h2 'a) 1.0) (set! (h2 'b) 2) (morally-equal? (list h1) (list h2))) #t) ;(test (let ((ht (make-hash-table))) (hash-table-set! ht ht 1) (ht ht)) #f) ; this is #f now because the old ht is not equal to the new one (different number of entries) ;(test (let ((ht (make-hash-table))) (hash-table-set! ht ht ht) (equal? (ht ht) ht)) #t) (test (let ((ht (make-hash-table))) (hash-table-set! ht 'a ht) (object->string ht)) "#1=(hash-table '(a . #1#))") (test (let ((h1 (make-hash-table))) (hash-table-set! h1 "hi" h1) (object->string h1)) "#1=(hash-table '(\"hi\" . #1#))") (test (let ((ht (make-hash-table))) (hash-table-set! ht 'a ht) (morally-equal? ht (copy ht))) #t) (test (let ((ht (make-hash-table))) (hash-table-set! ht 'a ht) (equal? ht (copy ht))) #t) (test (hash-table 'a 1 'b) 'error) ;; there's no real need for multidim hashes: (let ((ht (make-hash-table))) (set! (ht (cons 'a 1)) 'b) (set! (ht (cons 'a 2)) 'c) (set! (ht (cons 'b 1)) 'd) (test (ht '(a . 1)) 'b) (test (ht '(b . 1)) 'd) (set! (ht '(a . 2)) 32) (test (ht '(a . 2)) 32) (let ((lst1 (list 1)) (lst2 (list 1))) (set-car! lst1 lst2) (set-car! lst2 lst1) (set! (ht lst1) 32) (set! (ht lst2) 3) (test (equal? lst1 lst2) #t) (test (ht lst1) 3) (test (ht lst2) 3))) (let ((ht (make-hash-table))) (set! (ht 1.0) 'a) (set! (ht 2.0) 'b) (set! (ht 3.0) 'c) (test (ht 2.0) 'b) (set! (ht 2.0) 'd) (test (ht 2.0) 'd) (test (ht 0.0) #f) (test (ht 1.0) 'a)) (let ((ht (make-hash-table))) (test (ht) 'error) (test (ht 0 1) 'error)) (let ((h (hash-table* 'a (hash-table* 'b 2 'c 3) 'b (hash-table* 'b 3 'c 4)))) (test (h 'a 'b) 2) (test (h 'b 'b) 3) (test (h 'a 'c) 3)) (let () (define-macro (memoize f) `(define ,f (let ((ht (make-hash-table)) (old-f ,f)) (lambda args (or (ht args) (let ((new-val (apply old-f args))) (set! (ht args) new-val) new-val)))))) (define (our-abs num) (abs num)) (memoize our-abs) (num-test (our-abs -1) 1) (with-let (funclet our-abs) (test (ht '(-1)) 1))) (let () (define-macro (define-memoized name&arg . body) (let ((arg (cadr name&arg)) (memo (gensym "memo"))) `(define ,(car name&arg) (let ((,memo (make-hash-table))) (lambda (,arg) (or (,memo ,arg) (set! (,memo ,arg) (begin ,@body)))))))) (define-memoized (f1 abc) (+ abc 2)) (test (f1 3) 5) (test (f1 3) 5) (test (f1 2) 4) (let ((ht (call-with-exit (lambda (return) (for-each (lambda (x) (if (hash-table? (cdr x)) (return (cdr x)))) (outlet (funclet f1))) #f)))) (if (not (hash-table? ht)) (format-logged #t ";can't find memo? ~A~%" (let->list (outlet (funclet f1)))) (test (length (map (lambda (x) x) ht)) 2)))) (let () (define-macro (define-memoized name&args . body) (let ((args (cdr name&args)) (memo (gensym "memo"))) `(define ,(car name&args) (let ((,memo (make-hash-table))) (lambda ,args (or (,memo (list ,@args)) (set! (,memo (list ,@args)) (begin ,@body)))))))) (define (ack m n) (cond ((= m 0) (+ n 1)) ((= n 0) (ack (- m 1) 1)) (else (ack (- m 1) (ack m (- n 1)))))) (define-memoized (ack1 m n) (cond ((= m 0) (+ n 1)) ((= n 0) (ack1 (- m 1) 1)) (else (ack1 (- m 1) (ack1 m (- n 1)))))) (test (ack 2 3) (ack1 2 3))) (let ((ht (make-hash-table))) (test (eq? (car (catch #t (lambda () (set! (ht) 2)) (lambda args args))) 'wrong-number-of-args) #t) (test (eq? (car (catch #t (lambda () (set! (ht 0 0) 2)) (lambda args args))) 'syntax-error) #t) ; attempt to apply boolean #f to (0) (test (eq? (car (catch #t (lambda () (set! ((ht 0) 0) 2)) (lambda args args))) 'syntax-error) #t)) (let () (define (merge-hash-tables . tables) (apply hash-table (apply append (map (lambda (table) (map values table)) tables)))) (let ((ht (merge-hash-tables (hash-table '(a . 1) '(b . 2)) (hash-table '(c . 3))))) (test (ht 'c) 3)) (test ((append (hash-table '(a . 1) '(b . 2)) (hash-table '(c . 3))) 'c) 3)) ;;; test the eq-func business (let ((ht (make-hash-table 8 eq?))) (test (hash-table-ref ht 'a) #f) (hash-table-set! ht 'a 1) (hash-table-set! ht 'c 'd) (test (hash-table-ref ht 'a) 1) (hash-table-set! ht "hi" 3) (test (hash-table-ref ht "hi") #f) (set! (ht '(a . 1)) "ho") (test (ht '(a . 1)) #f) (let ((ht1 (copy ht))) (test (ht1 'a) 1) (test (ht1 "hi") #f) (set! (ht1 #\a) #\b) (test (ht1 #\a) #\b) (test (ht #\a) #f) (let ((ht2 (reverse ht1))) (test (ht1 #\a) #\b) (test (ht2 #\b) #\a) (test (ht2 'd) 'c))) (do ((i 0 (+ i 1))) ((= i 32)) (set! (ht (string->symbol (string-append "g" (number->string i)))) i)) (test (ht 'a) 1) (test (ht 'g3) 3) (set! (ht ht) 123) (test (ht ht) 123)) (let ((ht (make-hash-table 31 string=?))) (test (length ht) 32) (set! (ht "hi") 'a) (test (ht "hi") 'a) (test (ht "Hi") #f) (set! (ht 32) 'b) (test (ht 32) #f) ) (let ((ht (make-hash-table 31 char=?))) (test (length ht) 32) (set! (ht #\a) 'a) (test (ht #\a) 'a) (test (ht #\A) #f) (set! (ht 32) 'b) (test (ht 32) #f) ) (unless pure-s7 (let ((ht (make-hash-table 31 string-ci=?))) (test (length ht) 32) (set! (ht "hi") 'a) (test (ht "hi") 'a) (test (ht "Hi") 'a) (test (ht "HI") 'a) (set! (ht 32) 'b) (test (ht 32) #f) ) (let ((ht (make-hash-table 31 char-ci=?))) (test (length ht) 32) (set! (ht #\a) 'a) (test (ht #\a) 'a) (test (ht #\A) 'a) (set! (ht 32) 'b) (test (ht 32) #f) )) (let ((ht (make-hash-table 31 =))) (test (length ht) 32) (set! (ht 1) 'a) (test (ht 1.0) 'a) (test (ht 1+i) #f) (set! (ht 32) 'b) (test (ht 32) 'b) (set! (ht 1/2) 'c) (test (ht 0.5) 'c) ) (let ((ht (make-hash-table 31 eqv?))) (test (length ht) 32) (set! (ht 1) 'a) (test (ht 1.0) #f) (set! (ht 2.0) 'b) (test (ht 2.0) 'b) (set! (ht 32) 'b) (test (ht 32) 'b) (set! (ht #\a) 1) (test (ht #\a) 1) (set! (ht ()) 2) (test (ht ()) 2) (set! (ht abs) 3) (test (ht abs) 3) ) (let ((ht (make-hash-table 8 (cons string=? (lambda (a) (string-length a)))))) (set! (ht "a") 'a) (test (ht "a") 'a) (set! (ht "abc") 'abc) (test (ht "abc") 'abc)) (let ((ht (make-hash-table 8 (cons (lambda (a b) (string=? a b)) string-length)))) (set! (ht "a") 'a) (test (ht "a") 'a) (set! (ht "abc") 'abc) (test (ht "abc") 'abc)) (let ((ht (make-hash-table 8 (cons (lambda (a b) (string=? a b)) (lambda (a) (string-length a)))))) (set! (ht "a") 'a) (test (ht "a") 'a) (set! (ht "abc") 'abc) (test (ht "abc") 'abc)) (let ((ht (make-hash-table 8 (cons string=? string-length)))) (set! (ht "a") 'a) (test (ht "a") 'a) (set! (ht "abc") 'abc) (test (ht "abc") 'abc)) (let ((h (make-hash-table 8 equal?))) (set! (h (make-int-vector 3 0)) 3) (test (h (make-int-vector 3 0)) 3) (test (h (make-vector 3 0)) #f) (test (h (make-float-vector 3 0)) #f) (let ((x 1.0) (y (+ 1.0 (* 0.5 (*s7* 'morally-equal-float-epsilon)))) (z (+ 1.0 (* 2 (*s7* 'morally-equal-float-epsilon))))) (set! (h x) 12) (test (h x) 12) ;(test (h y) #f) ;(test (h z) #f) ;default vs explicit equal? here -- sigh )) (let ((h (make-hash-table 8 morally-equal?))) (set! (h (make-int-vector 3 0)) 3) (test (h (make-int-vector 3 0)) 3) (test (h (make-vector 3 0)) 3) (test (h (make-float-vector 3 0)) 3) (let ((x 1.0) (y (+ 1.0 (* 0.5 (*s7* 'morally-equal-float-epsilon)))) (z (+ 1.0 (* 2 (*s7* 'morally-equal-float-epsilon))))) (set! (h x) 12) (test (h x) 12) (test (h y) 12) (test (h z) #f) (set! (h 1/10) 3) (test (h 0.1) 3) (set! (h #(1 2.0)) 4) (test (h (vector 1 2)) 4) (set! (h 1.0) 5) (test (h 1) 5) (set! (h (list 3)) 6) (test (h (list 3.0)) 6) )) (when with-block (let ((ht (make-hash-table 31 (cons hash_heq hash_hloc)))) (test (length ht) 32) (set! (ht 'a) 'b) (test (ht 'a) 'b) (test (ht 1) #f) (let ((ht1 (reverse ht))) (test (ht1 'b) 'a)) )) (let ((ht (make-hash-table 31 morally-equal?)) (ht1 (make-hash-table 31))) (test (length ht) 32) (test (equal? ht ht1) #t) (set! (ht 3) 1) (test (ht 3) 1) (set! (ht1 3) 1) (test (equal? ht ht1) #f) (set! (ht 3.14) 'a) (test (ht 3.14) 'a) (set! (ht "hi") 123) (test (ht "hi") 123) (set! (ht 1/0) #) (test (ht 1/0) #)) (let ((ht (make-hash-table 31 (cons (lambda (a b) (eq? a b)) (lambda (a) 0))))) (test (hash-table-ref ht 'a) #f) (hash-table-set! ht 'a 1) (hash-table-set! ht 'c 'd) (test (hash-table-ref ht 'a) 1) (hash-table-set! ht "hi" 3) (test (hash-table-ref ht "hi") #f) (set! (ht '(a . 1)) "ho") (test (ht '(a . 1)) #f) (let ((ht1 (copy ht))) (test (ht1 'a) 1) (test (ht1 "hi") #f) (set! (ht1 #\a) #\b) (test (ht1 #\a) #\b) (test (ht #\a) #f))) (when (provided? 'snd) (let ((ht (make-hash-table 31 (cons equal? mus-type)))) (let ((g1 (make-oscil 100)) (g2 (make-oscil 100))) (set! (ht g1) 32) (test (ht g1) 32) (test (ht g2) 32) (test (equal? g1 g2) #t)))) #| (define constants (vector 1)) ; etc -- see tauto.scm (define ops (list eq? eqv? equal? morally-equal? = char=? string=? char-ci=? string-ci=? (cons string=? (lambda (a) (string-length a))) (cons (lambda (a b) (string=? a b)) string-length))) (for-each (lambda (op) (for-each (lambda (val) (let ((h (make-hash-table 8 op))) (catch #t (lambda () (set! (h val) #t) (if (not (eq? (h val) (op val val))) (format *stderr* "~A ~A: ~A ~A~%" op val (h val) (op val val)))) (lambda any #f)))) constants)) ops) |# (let () (let ((ht (make-hash-table 31 (cons (lambda (a b) (eq? a b)) (lambda (a) 0))))) (hash-table-set! ht 'a 1) (test (ht 'a) 1)) (let ((ht (make-hash-table 31 (cons (lambda* (a b) (eq? a b)) (lambda (a) 0))))) (hash-table-set! ht 'a 1) (test (ht 'a) 1)) (let ((ht (make-hash-table 31 (cons (lambda* (a (b 0)) (eq? a b)) (lambda (a) 0))))) (hash-table-set! ht 'a 1) (test (ht 'a) 1)) (test (let ((ht (make-hash-table 31 (list (eq? a b))))) (hash-table-set! ht 'a 1) (ht 'a)) 'error) (test (let ((ht (make-hash-table 31 (cons abs +)))) (hash-table-set! ht 'a 1) (ht 'a)) 'error) (test (let ((ht (make-hash-table 31 (cons eq? float-vector-ref)))) (hash-table-set! ht 'a 1) (ht 'a)) 'error) (test (let ((ht (make-hash-table 31 (dilambda (lambda (a) (eq? a b)) (lambda (a) 0))))) (hash-table-set! ht 'a 1) (ht 'a)) 'error) (test (let ((ht (make-hash-table 31 (lambda a (eq? car a) (cadr s))))) (hash-table-set! ht 'a 1) (ht 'a)) 'error) (test (let ((ht (make-hash-table 31 (cons (lambda (a b c) (eq? a b)) (lambda (a) 0))))) (hash-table-set! ht 'a 1) (ht 'a)) 'error) (test (let ((ht (make-hash-table 31 (define-macro (_m_ . args) #f)))) (hash-table-set! ht 'a 1) (ht 'a)) 'error) (test (let ((ht (make-hash-table 31 abs))) (hash-table-set! ht 'a 1) (ht 'a)) 'error) (test (let ((ht (make-hash-table 31 list-set!))) (hash-table-set! ht 'a 1) (ht 'a)) 'error)) (let () (define (test-hash size) (let ((c #t)) (let ((int-hash (make-hash-table (max size 511) (cons (lambda (a b) (= a b)) (lambda (a) a))))) (do ((i 0 (+ i 1))) ((= i size)) (hash-table-set! int-hash i i)) (do ((i 0 (+ i 1))) ((= i size)) (let ((x (hash-table-ref int-hash i))) (if (not (= x i)) (format *stderr* ";test-hash(0) ~D -> ~D~%" i x))))) (let ((int-hash (make-hash-table (max size 511) (cons (lambda (a b) (and c (= a b))) (lambda (a) a))))) (do ((i 0 (+ i 1))) ((= i size)) (hash-table-set! int-hash i i)) (do ((i 0 (+ i 1))) ((= i size)) (let ((x (hash-table-ref int-hash i))) (if (not (= x i)) (format *stderr* ";test-hash(1) ~D -> ~D~%" i x))))) (let ((int-hash (make-hash-table (max size 511) (let ((c #f)) (cons (lambda (a b) (and (not c) (= a b))) (lambda (a) a)))))) (do ((i 0 (+ i 1))) ((= i size)) (hash-table-set! int-hash i i)) (do ((i 0 (+ i 1))) ((= i size)) (let ((x (hash-table-ref int-hash i))) (if (not (= x i)) (format *stderr* ";test-hash(2) ~D -> ~D~%" i x))))) )) (test-hash 10)) #| ;; another problem (let ((ht (make-hash-table)) (lst (list 1))) (set! (ht lst) 32) (let ((v1 (ht '(1))) (v2 (ht '(2)))) (set-car! lst 2) (let ((v3 (ht '(1))) (v4 (ht '(2)))) (list v1 v2 v3 v4)))) ; 32 #f #f #f (let ((ht (make-hash-table)) (lst (list 1))) (set! (ht (copy lst)) 32) (let ((v1 (ht '(1))) (v2 (ht '(2)))) (set-car! lst 2) (let ((v3 (ht '(1))) (v4 (ht '(2)))) (list v1 v2 v3 v4)))) ; 32 #f 32 #f ;; so copy the key if it might be changed |# ;;; -------------------------------------------------------------------------------- ;;; some implicit index tests (test (#(#(1 2) #(3 4)) 1 1) 4) (test (#("12" "34") 0 1) #\2) (test (#((1 2) (3 4)) 1 0) 3) (test (#((1 (2 3))) 0 1 0) 2) (test ((vector (hash-table '(a . 1) '(b . 2))) 0 'a) 1) (test ((list (lambda (x) x)) 0 "hi") "hi") (test (let ((lst '("12" "34"))) (lst 0 1)) #\2) (test (let ((lst (list #(1 2) #(3 4)))) (lst 0 1)) 2) (test (#2d(("hi" "ho") ("ha" "hu")) 1 1 0) #\h) (test ((list (lambda (a) (+ a 1)) (lambda (b) (* b 2))) 1 2) 4) (test ((lambda (arg) arg) "hi" 0) 'error) (let ((L1 (list 1 2 3)) (V1 (vector 1 2 3)) (M1 #2d((1 2 3) (4 5 6) (7 8 9))) (S1 "123") (H1 (hash-table '(1 . 1) '(2 . 2) '(3 . 3)))) (let ((L2 (list L1 V1 M1 S1 H1)) (V2 (vector L1 V1 M1 S1 H1)) (H2 (hash-table (cons 0 L1) (cons 1 V1) (cons 2 M1) (cons 3 S1) (cons 4 H1))) (M2 (let ((v (make-vector '(3 3)))) (set! (v 0 0) L1) (set! (v 0 1) V1) (set! (v 0 2) M1) (set! (v 1 0) S1) (set! (v 1 1) H1) (set! (v 1 2) L1) (set! (v 2 0) S1) (set! (v 2 1) H1) (set! (v 2 2) L1) v))) #| ;; this code generates the tests below (for-each (lambda (arg) (let* ((val (symbol->value arg)) (len (min 5 (length val)))) (do ((i 0 (+ i 1))) ((= i len)) (format *stderr* "(test (~S ~S) ~S)~%" arg i (catch #t (lambda () (val i)) (lambda args 'error))) (let ((len1 (catch #t (lambda () (min 5 (length (val i)))) (lambda args 0)))) (if (> len1 0) (do ((k 0 (+ k 1))) ((= k len1)) (format *stderr* "(test (~S ~S ~S) ~S)~%" arg i k (catch #t (lambda () (val i k)) (lambda args 'error))) (let ((len2 (catch #t (lambda () (min 5 (length (val i k)))) (lambda args 0)))) (if (> len2 0) (do ((m 0 (+ m 1))) ((= m len2)) (format *stderr* "(test (~S ~S ~S ~S) ~S)~%" arg i k m (catch #t (lambda () (val i k m)) (lambda args 'error))) (let ((len3 (catch #t (lambda () (min 5 (length (val i k m)))) (lambda args 0)))) (if (> len3 0) (do ((n 0 (+ n 1))) ((= n len3)) (format *stderr* "(test (~S ~S ~S ~S ~S) ~S)~%" arg i k m n (catch #t (lambda () (val i k m n)) (lambda args 'error))))))))))))))) (list 'L2 'V2 'M2 'H2)) |# (test (L2 0) '(1 2 3)) (test (L2 0 0) 1) (test (L2 0 1) 2) (test (L2 0 2) 3) (test (L2 1) #(1 2 3)) (test (L2 1 0) 1) (test (L2 1 1) 2) (test (L2 1 2) 3) (test (L2 2) #2D((1 2 3) (4 5 6) (7 8 9))) (test (L2 2 0) #(1 2 3)) (test (L2 2 0 0) 1) (test (L2 2 0 1) 2) (test (L2 2 0 2) 3) (test (L2 2 1) #(4 5 6)) (test (L2 2 1 0) 4) (test (L2 2 1 1) 5) (test (L2 2 1 2) 6) (test (L2 2 2) #(7 8 9)) (test (L2 2 2 0) 7) (test (L2 2 2 1) 8) (test (L2 2 2 2) 9) (test (L2 2 3) 'error) (test (L2 2 4) 'error) (test (L2 3) "123") (test (L2 3 0) #\1) (test (L2 3 1) #\2) (test (L2 3 2) #\3) (test (L2 4) H1) (test (L2 4 0) #f) (test (L2 4 1) 1) (test (L2 4 2) 2) (test (L2 4 3) 3) (test (L2 4 4) #f) (test (V2 0) '(1 2 3)) (test (V2 0 0) 1) (test (V2 0 1) 2) (test (V2 0 2) 3) (test (V2 1) #(1 2 3)) (test (V2 1 0) 1) (test (V2 1 1) 2) (test (V2 1 2) 3) (test (V2 2) #2D((1 2 3) (4 5 6) (7 8 9))) (test (V2 2 0) #(1 2 3)) (test (V2 2 0 0) 1) (test (V2 2 0 1) 2) (test (V2 2 0 2) 3) (test (V2 2 1) #(4 5 6)) (test (V2 2 1 0) 4) (test (V2 2 1 1) 5) (test (V2 2 1 2) 6) (test (V2 2 2) #(7 8 9)) (test (V2 2 2 0) 7) (test (V2 2 2 1) 8) (test (V2 2 2 2) 9) (test (V2 2 3) 'error) (test (V2 2 4) 'error) (test (V2 3) "123") (test (V2 3 0) #\1) (test (V2 3 1) #\2) (test (V2 3 2) #\3) (test (V2 4) H1) (test (V2 4 0) #f) (test (V2 4 1) 1) (test (V2 4 2) 2) (test (V2 4 3) 3) (test (V2 4 4) #f) (test (M2 0) #((1 2 3) #(1 2 3) #2D((1 2 3) (4 5 6) (7 8 9)))) (test (M2 0 0) '(1 2 3)) (test (M2 0 0 0) 1) (test (M2 0 0 1) 2) (test (M2 0 0 2) 3) (test (M2 0 1) #(1 2 3)) (test (M2 0 1 0) 1) (test (M2 0 1 1) 2) (test (M2 0 1 2) 3) (test (M2 0 2) #2D((1 2 3) (4 5 6) (7 8 9))) (test (M2 0 2 0) #(1 2 3)) (test (M2 0 2 0 0) 1) (test (M2 0 2 0 1) 2) (test (M2 0 2 0 2) 3) (test (M2 0 2 1) #(4 5 6)) (test (M2 0 2 1 0) 4) (test (M2 0 2 1 1) 5) (test (M2 0 2 1 2) 6) (test (M2 0 2 2) #(7 8 9)) (test (M2 0 2 2 0) 7) (test (M2 0 2 2 1) 8) (test (M2 0 2 2 2) 9) (test (M2 0 2 3) 'error) (test (M2 0 2 4) 'error) (test (M2 1) (vector "123" H1 '(1 2 3))) (test (M2 1 0) "123") (test (M2 1 0 0) #\1) (test (M2 1 0 1) #\2) (test (M2 1 0 2) #\3) (test (M2 1 1) H1) (test (M2 1 1 0) #f) (test (M2 1 1 1) 1) (test (M2 1 1 2) 2) (test (M2 1 1 3) 3) (test (M2 1 1 4) #f) (test (M2 1 2) '(1 2 3)) (test (M2 1 2 0) 1) (test (M2 1 2 1) 2) (test (M2 1 2 2) 3) (test (M2 2) (vector "123" H1 '(1 2 3))) (test (M2 2 0) "123") (test (M2 2 0 0) #\1) (test (M2 2 0 1) #\2) (test (M2 2 0 2) #\3) (test (M2 2 1) H1) (test (M2 2 1 0) #f) (test (M2 2 1 1) 1) (test (M2 2 1 2) 2) (test (M2 2 1 3) 3) (test (M2 2 1 4) #f) (test (M2 2 2) '(1 2 3)) (test (M2 2 2 0) 1) (test (M2 2 2 1) 2) (test (M2 2 2 2) 3) (test (M2 3) 'error) (test (M2 4) 'error) (test (H2 0) '(1 2 3)) (test (H2 0 0) 1) (test (H2 0 1) 2) (test (H2 0 2) 3) (test (H2 1) #(1 2 3)) (test (H2 1 0) 1) (test (H2 1 1) 2) (test (H2 1 2) 3) (test (H2 2) #2D((1 2 3) (4 5 6) (7 8 9))) (test (H2 2 0) #(1 2 3)) (test (H2 2 0 0) 1) (test (H2 2 0 1) 2) (test (H2 2 0 2) 3) (test (H2 2 1) #(4 5 6)) (test (H2 2 1 0) 4) (test (H2 2 1 1) 5) (test (H2 2 1 2) 6) (test (H2 2 2) #(7 8 9)) (test (H2 2 2 0) 7) (test (H2 2 2 1) 8) (test (H2 2 2 2) 9) (test (H2 2 3) 'error) (test (H2 2 4) 'error) (test (H2 3) "123") (test (H2 3 0) #\1) (test (H2 3 1) #\2) (test (H2 3 2) #\3) (test (H2 4) H1) (test (H2 4 0) #f) (test (H2 4 1) 1) (test (H2 4 2) 2) (test (H2 4 3) 3) (test (H2 4 4) #f) )) (let* ((L1 (cons 1 2)) (L2 (list L1 3))) (test (L1 0) 1) (test (L1 1) 'error) (test (L1 2) 'error) (test (L2 0 0) 1) (test (L2 0 1) 'error) (test ((cons "123" 0) 0 1) #\2)) (let ((L1 (list "123" "456" "789"))) (set-cdr! (cdr L1) L1) (test (L1 0 1) #\2) (test (L1 1 1) #\5) (test (L1 2 1) #\2) (test (L1 12 0) #\1)) (let ((L1 (list "123" "456" "789"))) (set-car! (cdr L1) L1) (test (L1 1 1 1 1 1 0 0) #\1)) (test ((list (list) "") 1 0) 'error) (test ((list (list) "") 0 0) 'error) (test (#(1 2) 0 0) 'error) (test (#(1 #()) 1 0) 'error) (test ('(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((12))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) 12) ;;; implicit index as expression (_A cases) (let ((L1 (list 1 2 3)) (V1 (vector 1 2 3)) (S1 "123") (H1 (hash-table '(1 . 1) '(2 . 2) '(3 . 3))) (E1 (inlet :a 1 :b 2))) (define (f1 i s L V S H E) (vector (L (+ i 1)) (V (+ i 1)) (S (+ i 1)) (H (+ i 1)) (E (string->symbol s)))) (test (f1 0 "a" L1 V1 S1 H1 E1) (vector 2 2 #\2 1 1)) (test (f1 1 "b" L1 V1 S1 H1 E1) (vector 3 3 #\3 2 2)) (define (f2 i s L V S H E) (vector (L (abs i)) (V (abs i)) (S (abs i)) (H (abs i)) (E (vector-ref s 0)))) (test (f2 -2 #(b a) L1 V1 S1 H1 E1) (vector 3 3 #\3 2 2))) (when with-block (define (f3 B i) (B (+ i 1))) (define (f4 B i) (B (abs i))) (let ((b (make-block 4))) (set! (b 0) 1.0) (set! (b 1) 2.0) (test (f3 b -1) 1.0) (test (f4 b -1) 2.0))) (let ((v1 #(0 1 2 3 4 5 6 7)) (v2 #2D((0 1 2 3) (4 5 6 7))) (e1 (inlet :a 1)) (p1 (list 0 1 2 3)) (s1 "0123") ) (define (call-1 func arg1 arg2) (func arg1 arg2)) (define (call-2 func arg1 arg2) (func arg1 arg2)) (define (call-3 func arg1 arg2) (func arg1 arg2)) (define (call-4 func arg1 arg2) (func arg1 arg2)) (define (call-5 func arg1 arg2) (func arg1 arg2)) (define (call-6 func) (func 'a)) (define (call-7 func) (func 'a)) (define (call-8 func arg) (func (* 2 (+ arg 1)))) (define (call-9 func arg) (func (* 2 (+ arg 1)))) (define (call-10 func arg) (func arg)) (define (call-11 func arg) (func arg)) (define (call-12 func) (func 0)) (define (call-13 func) (func 0)) (define (call-14 func arg) (func arg 2)) (define (call-15 func arg) (func 2 arg)) (define (f+ x y) (+ x y)) (define (f- x y) (- x y)) (define* (f++ (x 0) y) (+ x y)) (define* (f-- x (y 0)) (- x y)) (define (fabs x) (abs x)) (define-macro (m+ x y) `(+ ,x ,y)) (test (call-1 + 5 2) 7) (test (call-1 f- 5 2) 3) (test (call-2 f+ 5 2) 7) (test (call-2 - 5 2) 3) (test (call-3 v2 0 3) 3) (test (call-3 list 0 3) (list 0 3)) (test (call-4 f++ 5 2) 7) (test (call-4 f-- 5 2) 3) (test (call-5 m+ 5 2) 7) (test (call-5 - 5 2) 3) (test (call-6 e1) 1) (test (call-6 symbol?) #t) (test (call-7 symbol?) #t) (test (call-7 list) (list 'a)) (test (call-8 abs -3) 4) (test (call-8 f-- 10) 22) (test (call-9 fabs -3) 4) (test (call-9 list -3) (list -4)) (test (call-10 e1 'a) 1) (test (call-10 list 'a) (list 'a)) (test (call-11 symbol? 'a) #t) (test (call-11 e1 'a) 1) (test (call-12 p1) 0) (test (call-12 s1) #\0) (test (call-13 v1) 0) (test (call-13 (lambda (x) (+ x 1))) 1) (test (call-14 * 3) 6) (test (call-14 (lambda (x y) (- x y)) 3) 1) (test (call-15 (lambda (x y) (- x y)) 3) -1) (test (call-15 - 3) -1) ) ;; multi-index get/set (let ((v (vector (hash-table* 'a 1 'b 2)))) (test (v 0 'a) 1) (set! (v 0 'a) 5) (test (v 0 'a) 5)) (let ((v (vector (inlet 'a 1 'b 2)))) (test (v 0 'a) 1) (set! (v 0 'a) 5) (test (v 0 'a) 5)) (let ((v (vector (list 1 2)))) (test (v 0 1) 2) (set! (v 0 1) 5) (test (v 0 1) 5)) (let ((v (vector (string #\1 #\2)))) (test (v 0 1) #\2) (set! (v 0 1) #\5) (test (v 0 1) #\5)) (let ((v (vector (vector 1 2)))) (test (v 0 1) 2) (set! (v 0 1) 5) (test (v 0 1) 5)) (let ((v (vector (byte-vector 1 2)))) (test (v 0 1) 2) (set! (v 0 1) 5) (test (v 0 1) 5)) (when with-block (let ((v (vector (block 1 2)))) (test (v 0 1) 2.0) (set! (v 0 1) 5) (test (v 0 1) 5.0))) (let ((v (vector (float-vector 1 2)))) (test (v 0 1) 2.0) (set! (v 0 1) 5) (test (v 0 1) 5.0)) (let ((v (vector (int-vector 1 2)))) (test (v 0 1) 2) (set! (v 0 1) 5) (test (v 0 1) 5)) (let ((v (list (hash-table* 'a 1 'b 2)))) (test (v 0 'a) 1) (set! (v 0 'a) 5) (test (v 0 'a) 5)) (let ((v (list (inlet 'a 1 'b 2)))) (test (v 0 'a) 1) (set! (v 0 'a) 5) (test (v 0 'a) 5)) (let ((v (list (list 1 2)))) (test (v 0 1) 2) (set! (v 0 1) 5) (test (v 0 1) 5)) (let ((v (list (string #\1 #\2)))) (test (v 0 1) #\2) (set! (v 0 1) #\5) (test (v 0 1) #\5)) (let ((v (list (vector 1 2)))) (test (v 0 1) 2) (set! (v 0 1) 5) (test (v 0 1) 5)) (let ((v (list (byte-vector 1 2)))) (test (v 0 1) 2) (set! (v 0 1) 5) (test (v 0 1) 5)) (when with-block (let ((v (list (block 1 2)))) (test (v 0 1) 2.0) (set! (v 0 1) 5) (test (v 0 1) 5.0))) (let ((v (list (float-vector 1 2)))) (test (v 0 1) 2.0) (set! (v 0 1) 5) (test (v 0 1) 5.0)) (let ((v (list (int-vector 1 2)))) (test (v 0 1) 2) (set! (v 0 1) 5) (test (v 0 1) 5)) (let ((v (hash-table* 'a (hash-table* 'a 1 'b 2)))) (test (v 'a 'a) 1) (set! (v 'a 'a) 5) (test (v 'a 'a) 5)) (let ((v (hash-table* 'a (inlet 'a 1 'b 2)))) (test (v 'a 'a) 1) (set! (v 'a 'a) 5) (test (v 'a 'a) 5)) (let ((v (hash-table* 'a (list 1 2)))) (test (v 'a 1) 2) (set! (v 'a 1) 5) (test (v 'a 1) 5)) (let ((v (hash-table* 'a (string #\1 #\2)))) (test (v 'a 1) #\2) (set! (v 'a 1) #\5) (test (v 'a 1) #\5)) (let ((v (hash-table* 'a (vector 1 2)))) (test (v 'a 1) 2) (set! (v 'a 1) 5) (test (v 'a 1) 5)) (let ((v (hash-table* 'a (byte-vector 1 2)))) (test (v 'a 1) 2) (set! (v 'a 1) 5) (test (v 'a 1) 5)) (when with-block (let ((v (hash-table* 'a (block 1 2)))) (test (v 'a 1) 2.0) (set! (v 'a 1) 5) (test (v 'a 1) 5.0))) (let ((v (hash-table* 'a (float-vector 1 2)))) (test (v 'a 1) 2.0) (set! (v 'a 1) 5) (test (v 'a 1) 5.0)) (let ((v (hash-table* 'a (int-vector 1 2)))) (test (v 'a 1) 2) (set! (v 'a 1) 5) (test (v 'a 1) 5)) (let ((v (inlet 'a (hash-table* 'a 1 'b 2)))) (test (v 'a 'a) 1) (set! (v 'a 'a) 5) (test (v 'a 'a) 5)) (let ((v (inlet 'a (inlet 'a 1 'b 2)))) (test (v 'a 'a) 1) (set! (v 'a 'a) 5) (test (v 'a 'a) 5)) (let ((v (inlet 'a (list 1 2)))) (test (v 'a 1) 2) (set! (v 'a 1) 5) (test (v 'a 1) 5)) (let ((v (inlet 'a (string #\1 #\2)))) (test (v 'a 1) #\2) (set! (v 'a 1) #\5) (test (v 'a 1) #\5)) (let ((v (inlet 'a (vector 1 2)))) (test (v 'a 1) 2) (set! (v 'a 1) 5) (test (v 'a 1) 5)) (let ((v (inlet 'a (byte-vector 1 2)))) (test (v 'a 1) 2) (set! (v 'a 1) 5) (test (v 'a 1) 5)) (when with-block (let ((v (inlet 'a (block 1 2)))) (test (v 'a 1) 2.0) (set! (v 'a 1) 5) (test (v 'a 1) 5.0))) (let ((v (inlet 'a (float-vector 1 2)))) (test (v 'a 1) 2.0) (set! (v 'a 1) 5) (test (v 'a 1) 5.0)) (let ((v (inlet 'a (int-vector 1 2)))) (test (v 'a 1) 2) (set! (v 'a 1) 5) (test (v 'a 1) 5)) (let ((ind 0) (sym 'a) (v (vector (hash-table* 'a 1 'b 2)))) (test (v ind sym) 1) (set! (v (+ ind ind) sym) (+ ind 5)) (test (v 0 'a) 5)) (let ((v (vector (hash-table* 'a "123" 'b 2)))) (test (v 0 'a 1) #\2) (set! (v 0 'a 1) #\5) (test (v 0 'a) "153")) (let ((iv (make-vector '(2 2)))) (set! (iv 1 0) 2) (set! (iv 1 1) 4) (let ((v (vector iv))) (test (v 0 1 0) 2) (set! (v 0 1 0) 5) (test (v 0 1) #(5 4)))) (let ((ov (make-vector '(2 2))) (iv (make-vector '(2 2)))) (set! (ov 1 0) iv) (set! (iv 0 1) 3) (test (ov 1 0 0 1) 3) (set! (ov 1 0 0 1) 5) (test (ov 1 0 0 1) 5)) ;;; -------------------------------------------------------------------------------- ;;; PORTS ;;; -------------------------------------------------------------------------------- (define start-input-port (current-input-port)) (define start-output-port (current-output-port)) (test (input-port? (current-input-port)) #t) (test (input-port? *stdin*) #t) (test (input-port? (current-output-port)) #f) (test (input-port? *stdout*) #f) (test (input-port? (current-error-port)) #f) (test (input-port? *stderr*) #f) (for-each (lambda (arg) (if (input-port? arg) (format-logged #t ";(input-port? ~A) -> #t?~%" arg))) (list "hi" #f (integer->char 65) 1 (list 1 2) '#t '3 (make-vector 3) 3.14 3/4 1.0+1.0i #\f :hi # # #)) (test (call-with-input-file "s7test.scm" input-port?) #t) (if (not (eq? start-input-port (current-input-port))) (format-logged #t "call-with-input-file did not restore current-input-port? ~A from ~A~%" start-input-port (current-input-port))) (test (let ((this-file (open-input-file "s7test.scm"))) (let ((res (input-port? this-file))) (close-input-port this-file) res)) #t) (if (not (eq? start-input-port (current-input-port))) (format-logged #t "open-input-file clobbered current-input-port? ~A from ~A~%" start-input-port (current-input-port))) (test (call-with-input-string "(+ 1 2)" input-port?) #t) (test (let ((this-file (open-input-string "(+ 1 2)"))) (let ((res (input-port? this-file))) (close-input-port this-file) res)) #t) (test (let ((this-file (open-input-string "(+ 1 2)"))) (let ((len (length this-file))) (close-input-port this-file) len)) 7) ;;; (test (let ((str "1234567890")) (let ((p (open-input-string str))) (string-set! str 0 #\a) (let ((c (read-char p))) (close-input-port p) c))) #\1) ;;; is that result demanded by the scheme spec? perhaps make str immutable if so? ;;; read ;;; write (test (+ 100 (call-with-input-string "123" (lambda (p) (values (read p) 1)))) 224) (test (call-with-input-string "1234567890" (lambda (p) (call-with-input-string "0987654321" (lambda (q) (+ (read p) (read q)))))) 2222222211) (test (call-with-input-string "12345 67890" (lambda (p) (call-with-input-string "09876 54321" (lambda (q) (- (+ (read p) (read q)) (read p) (read q)))))) -99990) (call-with-output-file "empty-file" (lambda (p) #f)) (test (call-with-input-file "empty-file" (lambda (p) (eof-object? (read-char p)))) #t) (test (call-with-input-file "empty-file" (lambda (p) (eof-object? (read p)))) #t) (test (call-with-input-file "empty-file" (lambda (p) (eof-object? (read-byte p)))) #t) (test (call-with-input-file "empty-file" (lambda (p) (eof-object? (read-line p)))) #t) (test (load "empty-file") #) (test (call-with-input-file "empty-file" (lambda (p) (port-closed? p))) #f) (test (eof-object? (call-with-input-string "" (lambda (p) (read p)))) #t) (test (eof-object? #) #t) (test (let () (define (hi a) (eof-object? a)) (hi #)) #t) (let () (define (io-func) (lambda (p) (eof-object? (read-line p)))) (test (call-with-input-file (let () "empty-file") (io-func)) #t)) (let ((p1 #f)) (call-with-output-file "empty-file" (lambda (p) (set! p1 p) (write-char #\a p))) (test (port-closed? p1) #t)) (test (call-with-input-file "empty-file" (lambda (p) (and (char=? (read-char p) #\a) (eof-object? (read-char p))))) #t) (test (call-with-input-file "empty-file" (lambda (p) (and (string=? (symbol->string (read p)) "a") (eof-object? (read p))))) #t) ; Guile also returns a symbol here (test (call-with-input-file "empty-file" (lambda (p) (and (char=? (integer->char (read-byte p)) #\a) (eof-object? (read-byte p))))) #t) (test (call-with-input-file "empty-file" (lambda (p) (and (string=? (read-line p) "a") (eof-object? (read-line p))))) #t) (test (call-with-input-string "(lambda (a) (+ a 1))" (lambda (p) (let ((f (eval (read p)))) (f 123)))) 124) (test (call-with-input-string "(let ((x 21)) (+ x 1))" (lambda (p) (eval (read p)))) 22) (test (call-with-input-string "(1 2 3) (4 5 6)" (lambda (p) (list (read p) (read p)))) '((1 2 3) (4 5 6))) (test (let () (call-with-output-file "empty-file" (lambda (p) (write '(lambda (a) (+ a 1)) p))) (call-with-input-file "empty-file" (lambda (p) (let ((f (eval (read p)))) (f 123))))) 124) (test (let () (call-with-output-file "empty-file" (lambda (p) (write '(let ((x 21)) (+ x 1)) p))) (call-with-input-file "empty-file" (lambda (p) (eval (read p))))) 22) (test (let () (call-with-output-file "empty-file" (lambda (p) (write '(1 2 3) p) (write '(4 5 6) p))) (call-with-input-file "empty-file" (lambda (p) (list (read p) (read p))))) '((1 2 3) (4 5 6))) (call-with-output-file "empty-file" (lambda (p) (for-each (lambda (c) (write-char c p)) "#b11"))) (test (call-with-input-file "empty-file" (lambda (p) (and (char=? (read-char p) #\#) (char=? (read-char p) #\b) (char=? (read-char p) #\1) (char=? (read-char p) #\1) (eof-object? (read-char p))))) #t) (test (call-with-input-file "empty-file" (lambda (p) (and (= (read p) 3) (eof-object? (read p))))) #t) (test (call-with-input-file "empty-file" (lambda (p) (and (= (read-byte p) (char->integer #\#)) (= (read-byte p) (char->integer #\b)) (= (read-byte p) (char->integer #\1)) (= (read-byte p) (char->integer #\1)) (eof-object? (read-byte p))))) #t) (test (call-with-input-file "empty-file" (lambda (p) (and (string=? (read-line p) "#b11") (eof-object? (read-line p))))) #t) (test (load "empty-file") 3) (let ((p1 (dilambda (lambda (p) (and (= (read p) 3) (eof-object? (read p)))) (lambda (p) #f)))) (test (call-with-input-file "empty-file" p1) #t)) ;;; load (for-each (lambda (arg) (test (load arg) 'error) (test (load "empty-file" arg) 'error)) (list () (list 1) '(1 . 2) #f #\a 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #f #t :hi (if #f #f) (lambda (a) (+ a 1)))) (test (load) 'error) (test (load "empty-file" (curlet) 1) 'error) (test (load "not a file") 'error) (test (load "") 'error) (test (load "/home/bil/cl") 'error) (test (call-with-input-string "(display (+ 1 2))" load) 'error) (call-with-output-file "empty-file" (lambda (p) (write '(+ 1 2 3) p))) (let ((x 4)) (test (+ x (load "empty-file")) 10)) (call-with-output-file "empty-file" (lambda (p) (write '(list 1 2 3) p))) (let ((x 4)) (test (cons x (load "empty-file")) '(4 1 2 3))) (call-with-output-file "empty-file" (lambda (p) (write '(values 1 2 3) p))) (let ((x 4)) (test (+ x (load "empty-file")) 10)) (test (+ 4 (eval (call-with-input-file "empty-file" (lambda (p) (read p))))) 10) (call-with-output-file "empty-file" (lambda (p) (write '(+ x 1) p))) (let ((x 2)) (test (load "empty-file" (curlet)) 3)) (call-with-output-file "empty-file" (lambda (p) (write '(set! x 1) p))) (let ((x 2)) (load "empty-file" (curlet)) (test x 1)) (call-with-output-file "empty-file" (lambda (p) (write '(define (hi a) (values a 2)) p) (write '(hi x) p))) (let ((x 4)) (test (+ x (load "empty-file" (curlet))) 10)) (let ((x 1) (e #f)) (set! e (curlet)) (let ((x 4)) (test (+ x (load "empty-file" e)) 7))) (let () (let () (call-with-output-file "empty-file" (lambda (p) (write '(define (load_hi a) (+ a 1)) p))) (load "empty-file" (curlet)) (test (load_hi 2) 3)) (test (defined? 'load_hi) #f)) (let () (apply load '("empty-file")) (test (load_hi 2) 3)) (call-with-output-file "empty-file" (lambda (p) (display "\"empty-file\"" p))) (test (load (load "empty-file")) "empty-file") ;;; autoload (test (autoload) 'error) (test (autoload 'abs) 'error) (test (autoload :abs "dsp.scm") 'error) (for-each (lambda (arg) (test (autoload arg "dsp.scm") 'error) (test (autoload 'hi arg) 'error)) (list #f () (integer->char 65) 1 (list 1 2) _ht_ _null_ _c_obj_ '#t '3 (make-vector 3) 3.14 3/4 1.0+1.0i #\f)) (test (autoload 'abs "dsp.scm" 123) 'error) (test (autoload "" "dsp.scm") 'error) (autoload 'auto_test_var "empty-file") (test (defined? 'auto_test_var) #f) (call-with-output-file "empty-file" (lambda (p) (format p "(define auto_test_var 123)~%"))) (load "empty-file") (test (+ 1 auto_test_var) 124) (autoload 'auto_test_var_2 (lambda (e) (varlet e (cons 'auto_test_var_2 1)))) (test (let () (+ 1 auto_test_var_2)) 2) (autoload 'auto_test_var_3 (lambda (e) (varlet e (cons 'auto_test_var_3 1)))) (autoload 'auto_test_var_4 (lambda (e) (varlet e (cons 'auto_test_var_4 (+ auto_test_var_3 1))))) (test (let () (+ auto_test_var_4 1)) 3) (test (autoload 'auto_test_var_1 (lambda () #f)) 'error) (test (autoload 'auto_test_var_1 (lambda (a b) #f)) 'error) (let ((str3 #f)) ;; IO tests mainly (set! str3 "0123456789") (set! str3 (string-append str3 str3 str3 str3 str3 str3 str3 str3 str3 str3)) (set! str3 (string-append str3 str3 str3 str3 str3 str3 str3 str3 str3 str3)) (set! str3 (string-append str3 str3 str3)) (call-with-output-file "test.scm" (lambda (p) (format p "(define (big-string)~%") (format p " \"") (display str3 p) (format p "\\\n") ; this becomes \ in the midst of a string which we ignore (display str3 p) (format p "\"") (format p ")~%"))) (load "test.scm") (let ((str (big-string))) (test (length str) 6000)) (let ((big-string (eval (call-with-input-string (call-with-output-string (lambda (p) (format p "(lambda ()~%") (format p " \"") (display str3 p) (format p "\\\n") ; this becomes \ in the midst of a string which we ignore (display str3 p) (format p "\"") (format p ")~%"))) read)))) (let ((str (big-string))) (test (length str) 6000))) (call-with-output-file "test.scm" (lambda (p) (format p "(define (big-string)~%") (format p " \"") (display str3 p) (format p "\\\"") (display str3 p) (format p "\"") (format p ")~%"))) (load "test.scm") (let ((str (big-string))) (test (length str) 6001)) (let ((big-string (eval (call-with-input-string (call-with-output-string (lambda (p) (format p "(lambda ()~%") (format p " \"") (display str3 p) (format p "\\\"") (display str3 p) (format p "\"") (format p ")~%"))) read)))) (let ((str (big-string))) (test (length str) 6001))) (call-with-output-file "test.scm" (lambda (p) (format p ""))) (load "test.scm") ; # (call-with-output-file "test.scm" (lambda (p) (format p ";") (do ((i 0 (+ i 1))) ((= i 3000)) (let ((c (integer->char (random 128)))) (if (charinteger #\a))) (format p "(define (big-char)~% (string ") (do ((i 0 (+ i 1))) ((= i 2000)) (format p "#\\~C " (integer->char (+ a (modulo i 26))))) (format p "))~%")))) (load "test.scm") (let ((chars (big-char))) (test (length chars) 2000)) (call-with-output-file "test.scm" (lambda (p) (let ((a (char->integer #\a))) (format p "(define (big-xchar)~% (string ") (do ((i 0 (+ i 1))) ((= i 2000)) (format p "#\\x~X " (+ a (modulo i 26)))) (format p "))~%")))) (load "test.scm") (let ((chars (big-xchar))) (test (length chars) 2000)) (call-with-output-file "test.scm" (lambda (p) (format p "(define (ychar) #\\~C)" (integer->char 255)))) (load "test.scm") (test (ychar) (integer->char 255)) (call-with-output-file "test.scm" (lambda (p) (do ((i 0 (+ i 1))) ((= i 1000)) (format p "~D" i)) (format p "~%") (do ((i 0 (+ i 1))) ((= i 1000)) (format p "~D" i)))) (call-with-input-file "test.scm" (lambda (p) (let ((s1 (read-line p)) (s2 (read-line p))) (test (and (string=? s1 s2) (= (length s1) 2890)) #t)))) (call-with-output-file "test.scm" (lambda (p) (format p "(define (big-int)~%") (do ((i 0 (+ i 1))) ((= i 3000)) (format p "0")) (format p "123)~%"))) (load "test.scm") (test (big-int) 123) (call-with-output-file "test.scm" (lambda (p) (format p "(define (big-rat)~%") (do ((i 0 (+ i 1))) ((= i 3000)) (format p "0")) (format p "123/") (do ((i 0 (+ i 1))) ((= i 3000)) (format p "0")) (format p "2)~%"))) (load "test.scm") (test (big-rat) 123/2) (call-with-output-file "test.scm" (lambda (p) (format p "(define (big-hash)~% (hash-table ") (do ((i 0 (+ i 1))) ((= i 2000)) (format p "'(~D . ~D) " i (+ i 1))) (format p "))~%"))) (load "test.scm") (let ((ht (big-hash))) (let ((entries 0)) (for-each (lambda (htv) (set! entries (+ entries 1)) (if (not (= (+ (car htv) 1) (cdr htv))) (format *stderr* ";hashed: ~A~%" htv))) ht) (test entries 2000))) (call-with-output-file "test.scm" (lambda (p) (format p "(define (big-hash)~% (apply hash-table (list ") (do ((i 0 (+ i 1))) ((= i 2000)) (format p "(cons ~D ~D) " i (+ i 1))) (format p ")))~%"))) (load "test.scm") (let ((ht (big-hash))) (let ((entries 0)) (for-each (lambda (htv) (set! entries (+ entries 1)) (if (not (= (+ (car htv) 1) (cdr htv))) (format *stderr* ";hashed: ~A~%" htv))) ht) (test entries 2000))) (call-with-output-file "test.scm" (lambda (p) (let ((a (char->integer #\a))) (format p "(define (big-env)~% (inlet ") (do ((i 0 (+ i 1))) ((= i 2000)) (format p "'(~A . ~D) " (string (integer->char (+ a (modulo i 26))) (integer->char (+ a (modulo (floor (/ i 26)) 26))) (integer->char (+ a (modulo (floor (/ i (* 26 26))) 26)))) i)) (format p "))~%")))) (load "test.scm") (let ((E (big-env)) (a (char->integer #\a))) (do ((i 0 (+ i 1))) ((= i 2000)) (let ((sym (string->symbol (string (integer->char (+ a (modulo i 26))) (integer->char (+ a (modulo (floor (/ i 26)) 26))) (integer->char (+ a (modulo (floor (/ i (* 26 26))) 26))))))) (let ((val (E sym))) (if (not (equal? val i)) (format *stderr* ";env: ~A -> ~A, not ~D~%" sym val i)))))) (call-with-output-file "test.scm" (lambda (p) (format p ""))) (let ((val (call-with-input-file "test.scm" (lambda (p) (read p))))) (if (not (eof-object? val)) (format *stderr* ";read empty file: ~A~%" val))) (call-with-output-file "test.scm" (lambda (p) (format p " ;") (do ((i 0 (+ i 1))) ((= i 3000)) (let ((c (integer->char (random 128)))) (if (char #t?~%" arg))) (list "hi" #f () 'hi (integer->char 65) 1 (list 1 2) _ht_ _null_ _c_obj_ '#t '3 (make-vector 3) 3.14 3/4 1.0+1.0i #\f)) (for-each (lambda (arg) (test (read-line () arg) 'error) (test (read-line arg) 'error)) (list "hi" (integer->char 65) 1 #f _ht_ _null_ _c_obj_ (list) (cons 1 2) (list 1 2) (make-vector 3) 3.14 3/4 1.0+1.0i #\f)) (test (call-with-output-file tmp-output-file output-port?) #t) (if (not (eq? start-output-port (current-output-port))) (format-logged #t "call-with-output-file did not restore current-output-port? ~A from ~A~%" start-output-port (current-output-port))) (test (let ((this-file (open-output-file tmp-output-file))) (let ((res (output-port? this-file))) (close-output-port this-file) res)) #t) (if (not (eq? start-output-port (current-output-port))) (format-logged #t "open-output-file clobbered current-output-port? ~A from ~A~%" start-output-port (current-output-port))) (test (let ((val #f)) (call-with-output-string (lambda (p) (set! val (output-port? p)))) val) #t) (test (let ((res #f)) (let ((this-file (open-output-string))) (set! res (output-port? this-file)) (close-output-port this-file) res)) #t) (for-each (lambda (arg) (if (eof-object? arg) (format-logged #t ";(eof-object? ~A) -> #t?~%" arg))) (list "hi" () '(1 2) -1 #\a 1 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #f #t (if #f #f) # (lambda (a) (+ a 1)))) (for-each (lambda (arg) (let ((val (catch #t (lambda () (port-closed? arg)) (lambda args 'error)))) (if (not (eq? val 'error)) (format-logged #t ";(port-closed? ~A) -> ~S?~%" arg val)))) (list "hi" '(1 2) -1 #\a 1 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #f #t (if #f #f) # # (lambda (a) (+ a 1)))) (test (port-closed?) 'error) (test (port-closed? (current-input-port) (current-output-port)) 'error) (call-with-output-file tmp-output-file (lambda (p) (display "3.14" p))) (test (call-with-input-file tmp-output-file (lambda (p) (read p) (let ((val (read p))) (eof-object? val)))) #t) (test (call-with-input-file tmp-output-file (lambda (p) (read-char p))) #\3) (test (call-with-input-file tmp-output-file (lambda (p) (peek-char p))) #\3) (test (call-with-input-file tmp-output-file (lambda (p) (peek-char p) (read-char p))) #\3) (test (call-with-input-file tmp-output-file (lambda (p) (list->string (list (read-char p) (read-char p) (read-char p) (read-char p))))) "3.14") (test (call-with-input-file tmp-output-file (lambda (p) (list->string (list (read-char p) (peek-char p) (read-char p) (read-char p) (peek-char p) (read-char p))))) "3..144") (for-each (lambda (arg) (call-with-output-file tmp-output-file (lambda (p) (write arg p))) (if (not (morally-equal? (call-with-input-file tmp-output-file (lambda (p) (read p))) arg)) (format *stderr* "~A different after write~%" arg))) (list "hi" -1 #\a 1 'a-symbol (make-vector 3 0) 3.14 3/4 .6 1.0+1.0i #f #t (list 1 2 3) (cons 1 2) '(1 2 . 3) () '((1 2) (3 . 4)) '(()) (list (list 'a "hi") #\b 3/4) ''a (string #\a #\null #\b) "" "\"hi\"" (integer->char 128) (integer->char 127) (integer->char 255) #\space #\null #\newline #\tab #() #2d((1 2) (3 4)) #3d() :hi # # # most-negative-fixnum (if with-bignums 1239223372036854775808 123) (if with-bignums 144580536300674537151081081515762353325831/229154728370723013560448485454219755525522 11/10) (if with-bignums 221529797579218180403518826416685087012.0 1000.1) (if with-bignums 1239223372036854775808+1239223372036854775808i 1000.1-1234i) )) (for-each (lambda (arg) (call-with-output-file tmp-output-file (lambda (p) (write arg p))) (test (call-with-input-file tmp-output-file (lambda (p) (eval (read p)))) arg)) ; so read -> symbol? (list *stdout* *stdin* *stderr* abs + quasiquote ; (hash-table '(a . 1) '(b . 2)) (hash-table) ; 0/0 (real-part (log 0)) ;;; for these we need nan? and infinite? since equal? might be #f ; (lambda (a) (+ a 1)) ; pws? ; (current-output-port) ; (random-state 1234) ; (symbol ":\"") ; (let () (define-macro (hi1 a) `(+ ,a 1)) hi1) ;;; and how could a continuation work in general? )) ;;; (call-with-input-file tmp-output-file (lambda (p) (read p))) got (symbol ":\"") but expected (symbol ":\"") ;;; r4rstest (let* ((write-test-obj '(#t #f a () 9739 -3 . #((test) "te \" \" st" "" test #() b c))) (load-test-obj (list 'define 'foo (list 'quote write-test-obj)))) (define (check-test-file name) (let ((val (call-with-input-file name (lambda (test-file) (test (read test-file) load-test-obj) (test (eof-object? (peek-char test-file)) #t) (test (eof-object? (read-char test-file)) #t) (input-port? test-file))))) (if (not (eq? val #t)) (format-logged #t "input-port? in call-with-input-file? returned ~A from ~A~%" val name)))) (test (call-with-output-file tmp-output-file (lambda (test-file) (write-char #\; test-file) (display #\; test-file) (display ";" test-file) (write write-test-obj test-file) (newline test-file) (write load-test-obj test-file) (output-port? test-file))) #t) (check-test-file tmp-output-file) (let ((test-file (open-output-file "tmp2.r5rs"))) (test (port-closed? test-file) #f) (write-char #\; test-file) (display #\; test-file) (display ";" test-file) (write write-test-obj test-file) (newline test-file) (write load-test-obj test-file) (test (output-port? test-file) #t) (close-output-port test-file) (check-test-file "tmp2.r5rs"))) (call-with-output-file tmp-output-file (lambda (p) (display "3.14" p))) (test (with-input-from-file tmp-output-file read) 3.14) (if (not (eq? start-input-port (current-input-port))) (format-logged #t "with-input-from-file did not restore current-input-port? ~A from ~A~%" start-input-port (current-input-port))) (test (with-input-from-file tmp-output-file (lambda () (eq? (current-input-port) start-input-port))) #f) (test (char->integer ((with-input-from-string (string (integer->char 255))(lambda () (read-string 1))) 0)) 255) (test (with-output-to-file tmp-output-file (lambda () (eq? (current-output-port) start-output-port))) #f) (if (not (eq? start-output-port (current-output-port))) (format-logged #t "with-output-to-file did not restore current-output-port? ~A from ~A~%" start-output-port (current-output-port))) (let ((newly-found-sonnet-probably-by-shakespeare "This is the story, a sad tale but true \ Of a programmer who had far too little to do.\ One day as he sat in his hut swilling stew, \ He cried \"CLM takes forever, it's stuck in a slough!,\ Its C code is slow, too slow by a few.\ Why, with just a small effort, say one line or two,\ It could outpace a no-op, you could scarcely say 'boo'\"!\ So he sat in his kitchen and worked like a dog.\ He typed and he typed 'til his mind was a fog. \ Now 6000 lines later, what wonders we see! \ CLM is much faster, and faster still it will be!\ In fact, for most cases, C beats the DSP! \ But bummed is our coder; he grumbles at night. \ That DSP code took him a year to write. \ He was paid many dollars, and spent them with glee,\ But his employer might mutter, this result were he to see.")) (call-with-output-file tmp-output-file (lambda (p) (write newly-found-sonnet-probably-by-shakespeare p))) (let ((sonnet (with-input-from-file tmp-output-file (lambda () (read))))) (if (or (not (string? sonnet)) (not (string=? sonnet newly-found-sonnet-probably-by-shakespeare))) (format-logged #t "write/read long string returned: ~A~%" sonnet))) (let ((file (open-output-file tmp-output-file))) (let ((len (string-length newly-found-sonnet-probably-by-shakespeare))) (write-char #\" file) (do ((i 0 (+ i 1))) ((= i len)) (let ((chr (string-ref newly-found-sonnet-probably-by-shakespeare i))) (if (char=? chr #\") (write-char #\\ file)) (write-char chr file))) (write-char #\" file) (close-output-port file))) (let ((file (open-input-file tmp-output-file))) (let ((sonnet (read file))) (close-input-port file) (if (or (not (string? sonnet)) (not (string=? sonnet newly-found-sonnet-probably-by-shakespeare))) (format-logged #t "write-char/read long string returned: ~A~%" sonnet))))) (let ((file (open-output-file tmp-output-file))) (for-each (lambda (arg) (write arg file) (write-char #\space file)) (list "hi" -1 #\a 1 'a-symbol #(1 2 3) 3.14 3/4 1.0+1.0i #f #t (list 1 2 3) '(1 . 2))) (close-output-port file)) (let ((file (open-input-file tmp-output-file))) (for-each (lambda (arg) (let ((val (read file))) (if (not (equal? val arg)) (format-logged #t "read/write ~A returned ~A~%" arg val)))) (list "hi" -1 #\a 1 'a-symbol #(1 2 3) 3.14 3/4 1.0+1.0i #f #t (list 1 2 3) '(1 . 2))) (close-input-port file)) (with-output-to-file tmp-output-file (lambda () (write lists))) (let ((val (with-input-from-file tmp-output-file (lambda () (read))))) (if (not (equal? val lists)) (format-logged #t "read/write lists returned ~A~%" val))) (if (not (string=? "" (with-output-to-string (lambda () (display ""))))) (format-logged #t "with-output-to-string null string?")) (let ((str (with-output-to-string (lambda () (with-input-from-string "hiho123" (lambda () (do ((c (read-char) (read-char))) ((eof-object? c)) (display c)))))))) (if (not (string=? str "hiho123")) (format-logged #t "with string ports 0: ~S?~%" str))) (let ((p1 (open-input-string "123")) (p2 (open-input-string "123"))) (test (morally-equal? p1 p2) #t) (read-char p1) (test (morally-equal? p1 p2) #f) (read-char p2) (test (morally-equal? p1 p2) #t) (close-input-port p1) (close-input-port p2)) (let ((p1 (open-input-string "1234")) (p2 (open-input-string "123"))) (test (morally-equal? p1 p2) #f) (read-char p1) (test (morally-equal? p1 p2) #f) (close-input-port p1) (close-input-port p2)) (let ((p1 (open-output-string)) (p2 (open-output-string))) (test (morally-equal? p1 p2) #t) (write-char #\a p1) (test (morally-equal? p1 p2) #f) (close-output-port p1) (close-output-port p2)) (let () (define* (f1 (b 123)) (display b)) (test (with-output-to-string f1) "123") (define (f2) (display "123")) (test (with-output-to-string f2) "123") (define (f3 . args) (display 123)) (test (with-output-to-string f3) "123") (define-macro (m1) `(write 123)) (test (with-output-to-string m1) "123") (define-macro (m2) (write 123)) (test (with-output-to-string m2) "123") (define (f4 a b) (display 123)) (test (with-output-to-string f4) 'error) (test (with-output-to-string s7-version) "")) ; the output is a string -- not written to stdout or whatever (let () (define* (f1 a (b 123)) (display b a)) (test (call-with-output-string f1) "123") (define (f2 a) (display "123" a)) (test (call-with-output-string f2) "123") (define (f3 . args) (display 123 (car args))) (test (call-with-output-string f3) "123") (define-macro (m1 p) `(write 123 ,p)) (test (call-with-output-string m1) "123") (define-macro* (m2 (p #f)) (write 123 p)) (test (call-with-output-string m2) "123") (define (f4 a b) (display 123 a)) (test (call-with-output-string f4) 'error) (test (call-with-output-string s7-version) 'error)) (let () (define* (f1 (a #f)) (read)) (test (with-input-from-string "(+ 1 2 3)" f1) '(+ 1 2 3)) (define* (f2 . args) (read)) (test (with-input-from-string "(+ 1 2 3)" f2) '(+ 1 2 3)) (define f3 read) (test (with-input-from-string "(+ 1 2 3)" f3) '(+ 1 2 3)) (define (f4) (read)) (test (with-input-from-string "(+ 1 2 3)" f4) '(+ 1 2 3)) (define-macro (m1) `(read)) (test (with-input-from-string "(+ 1 2 3)" m1) '(+ 1 2 3)) (define-macro (m2) (read)) (test (with-input-from-string "(+ 1 2 3)" m2) 6) (define (f5 a) (read a)) (test (with-input-from-string "(+ 1 2 3)" f5) 'error) (test (with-input-from-string "(+ 1 2 3)" s7-version) (s7-version))) (let () (define* (f1 (a #f)) (read a)) (test (call-with-input-string "(+ 1 2 3)" f1) '(+ 1 2 3)) (define* (f2 . args) (read (car args))) (test (call-with-input-string "(+ 1 2 3)" f2) '(+ 1 2 3)) (define f3 read) (test (call-with-input-string "(+ 1 2 3)" f3) '(+ 1 2 3)) (define-macro (m1 p) `(read ,p)) (test (call-with-input-string "(+ 1 2 3)" m1) '(+ 1 2 3)) (define-macro* (m2 (p #f)) (read p)) (test (call-with-input-string "(+ 1 2 3)" m2) 6) (define (f4) (read)) (test (call-with-input-string "(+ 1 2 3)" f4) 'error) (test (call-with-input-string "(+ 1 2 3)" s7-version) 'error)) (let () (with-output-to-file tmp-output-file (lambda () (display "(+ 1 2 3)"))) (define* (f1 (a #f)) (read)) (test (with-input-from-file tmp-output-file f1) '(+ 1 2 3)) (define* (f2 . args) (read)) (test (with-input-from-file tmp-output-file f2) '(+ 1 2 3)) (define f3 read) (test (with-input-from-file tmp-output-file f3) '(+ 1 2 3)) (define (f4) (read)) (test (with-input-from-file tmp-output-file f4) '(+ 1 2 3)) (define-macro (m1) `(read)) (test (with-input-from-file tmp-output-file m1) '(+ 1 2 3)) (define-macro (m2) (read)) (test (with-input-from-file tmp-output-file m2) 6) (define (f5 a) (read a)) (test (with-input-from-file tmp-output-file f5) 'error) (test (with-input-from-file tmp-output-file s7-version) (s7-version))) (let () (define (eval-from-string-1 str) (define-macro (m) (read)) (with-input-from-string str m)) (test (eval-from-string-1 "(+ 1 2 3)") 6) (define (eval-from-string str) (with-input-from-string str (define-macro (m) (read)))) (test (eval-from-string "(+ 1 2 3)") 6)) (let () (define* (f1 (a #f)) (read a)) (test (call-with-input-file tmp-output-file f1) '(+ 1 2 3)) (define* (f2 . args) (read (car args))) (test (call-with-input-file tmp-output-file f2) '(+ 1 2 3)) (define f3 read) (test (call-with-input-file tmp-output-file f3) '(+ 1 2 3)) (define-macro (m1 p) `(read ,p)) (test (call-with-input-file tmp-output-file m1) '(+ 1 2 3)) (define-macro* (m2 (p #f)) (read p)) (test (call-with-input-file tmp-output-file m2) 6) (define (f4) (read)) (test (call-with-input-file tmp-output-file f4) 'error) (test (call-with-input-file tmp-output-file s7-version) 'error)) (let ((ofile tmp-output-file)) (define (get-file-contents) (with-input-from-file ofile read-line)) (define* (f1 (b 123)) (display b)) (test (let () (with-output-to-file ofile f1) (get-file-contents)) "123") (define (f2) (display "123")) (test (let () (with-output-to-file ofile f2) (get-file-contents)) "123") (define (f3 . args) (display 123)) (test (let () (with-output-to-file ofile f3) (get-file-contents)) "123") (define-macro (m1) `(write 123)) (test (let () (with-output-to-file ofile m1) (get-file-contents)) "123") (define-macro (m2) (write 123)) (test (let () (with-output-to-file ofile m2) (get-file-contents)) "123") (define (f4 a b) (display 123)) (test (let () (with-output-to-file ofile f4) (get-file-contents)) 'error) (test (let () (with-output-to-file ofile s7-version) (get-file-contents)) #) (define* (f11 a (b 123)) (display b a)) (test (let () (call-with-output-file ofile f11) (get-file-contents)) "123") (define (f21 a) (display "123" a)) (test (let () (call-with-output-file ofile f21) (get-file-contents)) "123") (define (f31 . args) (display 123 (car args))) (test (let () (call-with-output-file ofile f31) (get-file-contents)) "123") (define-macro (m3 p) `(write 123 ,p)) (test (let () (call-with-output-file ofile m3) (get-file-contents)) "123") (define-bacro* (m2 (p 123)) `(write 123 ,p)) (test (let () (call-with-output-file ofile m2) (get-file-contents)) "123") (define (f41 a b) (display 123 a)) (test (let () (call-with-output-file ofile f41) (get-file-contents)) 'error) (test (let () (call-with-output-file ofile s7-version) (get-file-contents)) 'error)) (if (not (eof-object? (with-input-from-string "" (lambda () (read-char))))) (format-logged #t ";input from null string not #?~%") (let ((EOF (with-input-from-string "" (lambda () (read-char))))) (if (not (eq? (with-input-from-string "" (lambda () (read-char))) (with-input-from-string "" (lambda () (read-char))))) (format-logged #t "# is not eq? to itself?~%")) (if (char? EOF) (do ((c 0 (+ c 1))) ((= c 256)) (if (char=? EOF (integer->char c)) (format-logged #t "# is char=? to ~C~%" (integer->char c))))))) (test (+ 100 (call-with-output-file "tmp.r5rs" (lambda (p) (write "1" p) (values 1 2)))) 103) (test (+ 100 (with-output-to-file "tmp.r5rs" (lambda () (write "2") (values 1 2)))) 103) (if (not pure-s7) (let ((str (with-output-to-string (lambda () (with-input-from-string "hiho123" (lambda () (do ((c (read-char) (read-char))) ((or (not (char-ready?)) (eof-object? c))) (display c)))))))) (if (not (string=? str "hiho123")) (format-logged #t "with string ports 1: ~S?~%" str)))) (let ((str (with-output-to-string (lambda () (with-input-from-string "" (lambda () (do ((c (read-char) (read-char))) ((eof-object? c)) (display c)))))))) (if (not (string=? str "")) (format-logged #t "with string ports and null string: ~S?~%" str))) (let ((str (with-output-to-string ; this is from the guile-user mailing list, I think -- don't know who wrote it (lambda () (with-input-from-string "A2B5E3426FG0ZYW3210PQ89R." (lambda () (call/cc (lambda (hlt) (define (nextchar) (let ((c (read-char))) (if (and (char? c) (char=? c #\space)) (nextchar) c))) (define inx (lambda() (let in1 () (let ((c (nextchar))) (if (char-numeric? c) (let ((r (nextchar))) (let out*n ((n (- (char->integer c) (char->integer #\0)))) (out r) (if (not (zero? n)) (out*n (- n 1))))) (out c)) (in1))))) (define (move-char c) (write-char c) (if (char=? c #\.) (begin (hlt)))) (define outx (lambda() (let out1 () (let h1 ((n 16)) (move-char (in)) (move-char (in)) (move-char (in)) (if (= n 1) (begin (out1)) (begin (write-char #\space) (h1 (- n 1))) ))))) (define (in) (call/cc (lambda(return) (set! outx return) (inx)))) (define (out c) (call/cc (lambda(return) (set! inx return) (outx c)))) (outx))))))))) (if (not (string=? str "ABB BEE EEE E44 446 66F GZY W22 220 0PQ 999 999 999 R.")) (format-logged #t "call/cc with-input-from-string str: ~A~%" str))) (let ((badfile tmp-output-file)) (let ((p (open-output-file badfile))) (close-output-port p)) (load badfile)) (for-each (lambda (str) ;;(test (eval-string str) 'error) ;; eval-string is confused somehow (test (with-input-from-string str read) 'error)) (list "\"\\x" "\"\\x0" "`(+ ," "`(+ ,@" "#2d(" "#\\")) (let ((loadit tmp-output-file)) (let ((p1 (open-output-file loadit))) (display "(define s7test-var 314) (define (s7test-func) 314) (define-macro (s7test-mac a) `(+ ,a 2))" p1) (newline p1) (close-output-port p1) (load loadit) (test (= s7test-var 314) #t) (test (s7test-func) 314) (test (s7test-mac 1) 3) (let ((p2 (open-output-file loadit))) ; hopefully this starts a new file (display "(define s7test-var 3) (define (s7test-func) 3) (define-macro (s7test-mac a) `(+ ,a 1))" p2) (newline p2) (close-output-port p2) (load loadit) (test (= s7test-var 3) #t) (test (s7test-func) 3) (test (s7test-mac 1) 2) (test (morally-equal? p1 p2) #t)))) (test (+ 100 (with-input-from-string "123" (lambda () (values (read) 1)))) 224) (for-each (lambda (op) (for-each (lambda (arg) ;(format-logged #t ";(~A ~A)~%" op arg) (test (op arg) 'error)) (list (integer->char 65) 1 0 -1 (list 1) (cons 1 2) 'a-symbol (make-vector 3) abs lambda with-let _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #\f #t :hi (if #f #f) (lambda (a) (+ a 1))))) (list char-ready? set-current-output-port set-current-input-port set-current-error-port close-input-port close-output-port open-input-file open-output-file read-char peek-char read (lambda (arg) (write-char #\a arg)) (lambda (arg) (write "hi" arg)) (lambda (arg) (display "hi" arg)) call-with-input-file with-input-from-file call-with-output-file with-output-to-file)) (with-output-to-file tmp-output-file (lambda () (display "this is a test") (newline))) (test (call-with-input-file tmp-output-file (lambda (p) (integer->char (read-byte p)))) #\t) (test (with-input-from-string "123" (lambda () (read-byte))) 49) ;(test (with-input-from-string "1/0" read) 'error) ; this is a reader error in CL ;;; this test causes trouble when s7test is called from snd-test -- I can't see why (let ((bytes (vector #o000 #o000 #o000 #o034 #o000 #o001 #o215 #o030 #o000 #o000 #o000 #o022 #o000 #o000 #o126 #o042 #o000 #o000 #o000 #o001 #o000 #o000 #o000 #o000 #o000 #o001))) (with-output-to-file tmp-output-file (lambda () (for-each (lambda (b) (write-byte b)) bytes))) (let ((ctr 0)) (call-with-input-file tmp-output-file (lambda (p) (if (not (string=? (port-filename p) tmp-output-file)) (display (port-filename p))) (let loop ((val (read-byte p))) (if (eof-object? val) (if (not (= ctr 26)) (format-logged #t "read-byte done at ~A~%" ctr)) (begin (if (not (= (bytes ctr) val)) (format-logged #t "read-byte bytes[~D]: ~A ~A~%" ctr (bytes ctr) val)) (set! ctr (+ 1 ctr)) (loop (read-byte p)))))))) (let ((ctr 0)) (call-with-input-file tmp-output-file (lambda (p) (let loop ((val (read-char p))) (if (eof-object? val) (if (not (= ctr 26)) (format-logged #t "read-char done at ~A~%" ctr)) (begin (if (not (= (bytes ctr) (char->integer val))) (format-logged #t "read-char bytes[~D]: ~A ~A~%" ctr (bytes ctr) (char->integer val))) (set! ctr (+ 1 ctr)) (loop (read-char p)))))))) ) (with-output-to-file tmp-output-file (lambda () (if (not (string=? (port-filename (current-output-port)) tmp-output-file)) (display (port-filename (current-output-port)))) (display "(+ 1 2) 32") (newline) (display "#\\a -1"))) (with-input-from-file tmp-output-file (lambda () (if (not (string=? (port-filename (current-input-port)) tmp-output-file)) (display (port-filename (current-input-port)))) (let ((val (read))) (if (not (equal? val (list '+ 1 2))) (format-logged #t ";file read +: ~A~%" val))) (let ((val (read))) (if (not (equal? val 32)) (format-logged #t "file read 32: ~A~%" val))) (let ((val (read))) (if (not (equal? val #\a)) (format-logged #t "file read a: ~A~%" val))) (let ((val (read))) (if (not (equal? val -1)) (format-logged #t "file read -1: ~A~%" val))) (let ((val (read))) (if (not (eof-object? val)) (format-logged #t "file read #: ~A~%" val))) (let ((val (read))) (if (not (eof-object? val)) (format-logged #t "file read # again: ~A~%" val))))) (let () (call-with-input-string "012" (lambda (p) (do ((i 0 (+ i 1))) ((= i 4)) (let ((c (peek-char p))) (let ((r (read-char p))) (if (not (equal? c r)) (format-logged #t ";peek-char: ~A ~A~%" c r)))))))) (let ((port #f)) (call-with-exit (lambda (go) (call-with-input-string "0123456789" (lambda (p) (set! port p) (if (not (char=? (peek-char p) #\0)) (format-logged #t ";peek-char input-string: ~A~%" (peek-char p))) (go))))) (if (not (input-port? port)) (format-logged #t ";c/e-> c/is -> port? ~A~%" port) (if (not (port-closed? port)) (begin (format-logged #t ";c/e -> c/is -> closed? ~A~%" port) (close-input-port port))))) (call-with-output-file tmp-output-file (lambda (p) (display "0123456789" p))) (let ((port #f)) (call-with-exit (lambda (go) (call-with-input-file tmp-output-file (lambda (p) (set! port p) (if (not (char=? (peek-char p) #\0)) (format-logged #t ";peek-char input-file: ~A~%" (peek-char p))) (go))))) (if (not (input-port? port)) (format-logged #t ";c/e -> c/if -> port? ~A~%" port) (if (not (port-closed? port)) (begin (format-logged #t ";c/e -> c/if -> closed? ~A~%" port) (close-input-port port))))) (let ((port #f)) (call-with-exit (lambda (go) (dynamic-wind (lambda () #f) (lambda () (call-with-input-string "0123456789" (lambda (p) (set! port p) (if (not (char=? (peek-char p) #\0)) (format-logged #t ";peek-char input-string 1: ~A~%" (peek-char p))) (go)))) (lambda () (close-input-port port))))) (if (not (input-port? port)) (format-logged #t ";c/e -> dw -> c/is -> port? ~A~%" port) (if (not (port-closed? port)) (begin (format-logged #t ";c/e -> dw -> c/is -> closed? ~A~%" port) (close-input-port port))))) (let ((port #f)) (call-with-exit (lambda (go) (dynamic-wind (lambda () #f) (lambda () (call-with-input-file tmp-output-file (lambda (p) (set! port p) (if (not (char=? (peek-char p) #\0)) (format-logged #t ";peek-char input-file: ~A~%" (peek-char p))) (go)))) (lambda () (close-input-port port))))) (if (not (input-port? port)) (format-logged #t ";c/e -> dw -> c/if -> port? ~A~%" port) (if (not (port-closed? port)) (begin (format-logged #t ";c/e -> dw -> c/if -> closed? ~A~%" port) (close-input-port port))))) (let ((port #f)) (catch #t (lambda () (call-with-input-string "0123456789" (lambda (p) (set! port p) (if (not (char=? (peek-char p) #\0)) (format-logged #t ";peek-char input-string: ~A~%" (peek-char p))) (error 'oops)))) (lambda args #f)) (if (not (input-port? port)) (format-logged #t ";catch -> c/is -> error -> port? ~A~%" port) (if (not (port-closed? port)) (begin (format-logged #t ";catch -> c/is -> error -> closed? ~A~%" port) (close-input-port port))))) (let ((port #f)) (catch #t (lambda () (call-with-input-file tmp-output-file (lambda (p) (set! port p) (if (not (char=? (peek-char p) #\0)) (format-logged #t ";peek-char input-file: ~A~%" (peek-char p))) (error 'oops)))) (lambda args #f)) (if (not (input-port? port)) (format-logged #t ";catch -> c/if -> error -> port? ~A~%" port) (if (not (port-closed? port)) (begin (format-logged #t ";catch -> c/if -> error -> closed? ~A~%" port) (close-input-port port))))) (test (with-output-to-string (lambda () (write (string (integer->char 4) (integer->char 8) (integer->char 20) (integer->char 30))))) "\"\\x04\\x08\\x14\\x1e\"") (test (string-length "\x04\x08\x14\x1e") 4) (test (char->integer (string-ref "\x0" 0)) 0) (test (char->integer (string-ref "\x0e" 0)) 14) (test (char->integer (string-ref "\x1e" 0)) 30) (test (char->integer (string-ref "\xff" 0)) 255) (test (string=? "\"\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\x09x\\x0b\\x0c\\x0d\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\\\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\\x7f\\x80\\x81\\x82\\x83\\x84\\x85\\x86\\x87\\x88\\x89\\x8a\\x8b\\x8c\\x8d\\x8e\\x8f\\x90\\x91\\x92\\x93\\x94\\x95\\x96\\x97\\x98\\x99\\x9a\\x9b\\x9c\\x9d\\x9e\\x9f\\xa0¡¢£¤¥¦§¨©ª«¬\\xad®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÃÂÃÄÅÆÇÈÉÊËÌÃÃŽÃÃÑÒÓÔÕÖרÙÚÛÜÃÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ\"" "\"\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\x09x\\x0b\\x0c\\x0d\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\\\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\\x7f\\x80\\x81\\x82\\x83\\x84\\x85\\x86\\x87\\x88\\x89\\x8a\\x8b\\x8c\\x8d\\x8e\\x8f\\x90\\x91\\x92\\x93\\x94\\x95\\x96\\x97\\x98\\x99\\x9a\\x9b\\x9c\\x9d\\x9e\\x9f\\xa0¡¢£¤¥¦§¨©ª«¬\\xad®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÃÂÃÄÅÆÇÈÉÊËÌÃÃŽÃÃÑÒÓÔÕÖרÙÚÛÜÃÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ\"") #t) (test (string=? "\x61\x42\x63" "aBc") #t) (if (provided? 'system-extras) (begin ;;; directory? (test (directory? tmp-output-file) #f) (test (directory? ".") #t) (test (directory?) 'error) (test (directory? "." 0) 'error) (for-each (lambda (arg) (test (directory? arg) 'error)) (list -1 #\a 1 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #f #t :hi (if #f #f) (lambda (a) (+ a 1)))) ;;; file-exists? (test (file-exists? tmp-output-file) #t) (test (file-exists? "not-a-file-I-hope") #f) (test (file-exists?) 'error) (test (file-exists? tmp-output-file 0) 'error) (for-each (lambda (arg) (test (file-exists? arg) 'error)) (list -1 #\a 1 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #f #t :hi (if #f #f) (lambda (a) (+ a 1)))) ;;; delete-file (test (delete-file tmp-output-file) 0) (test (file-exists? tmp-output-file) #f) (test (delete-file "not-a-file-I-hope") -1) (test (delete-file) 'error) (test (delete-file tmp-output-file 0) 'error) (for-each (lambda (arg) (test (delete-file arg) 'error)) (list -1 #\a 1 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #f #t :hi (if #f #f) (lambda (a) (+ a 1)))) ;;; getenv (test (pair? (member (getenv "HOME") '("/usr/home/bil" "/Users/bil" "/home/bil") string=?)) #t) (test (getenv "NO-ENV") "") (test (getenv) 'error) (test (getenv "HOME" #t) 'error) (for-each (lambda (arg) (test (getenv arg) 'error)) (list -1 #\a 1 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #f #t :hi (if #f #f) (lambda (a) (+ a 1)))) ;;; directory->list (test (directory->list) 'error) (test (directory->list "." 0) 'error) (for-each (lambda (arg) (test (directory->list arg) 'error)) (list -1 #\a 1 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #f #t :hi (if #f #f) (lambda (a) (+ a 1)))) ;;; system (test (system "test -f s7test.scm") 0) (test (system) 'error) (test (let ((str (system "man fgrep" #t))) (and (string? str) (> (length str) 10000))) ; osx: 14479, linux: 40761 #t) (for-each (lambda (arg) (test (system arg) 'error)) (list -1 #\a 1 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #f #t :hi (if #f #f) (lambda (a) (+ a 1)))) )) (let () (define (args2) (with-output-to-file tmp-data-file (lambda () (write-byte 1) (write-byte 2) (write-byte 1) (write-byte 2))) (let ((v (with-input-from-file tmp-data-file (lambda () (vector (+ (read-byte) (ash (read-byte) 8)) (+ 1 (ash 2 8)) (+ (ash (read-byte) 8) (read-byte)) (+ (ash 1 8) 2)))))) (if (not (equal? v #(513 513 258 258))) (format *stderr* ";2 arg order check: ~A~%" v)))) (args2) (define (args3) (with-output-to-file tmp-data-file (lambda () (do ((i 0 (+ i 1))) ((= i 8)) (write-byte 1) (write-byte 2) (write-byte 3)))) (let ((v (with-input-from-file tmp-data-file (lambda () (vector (+ (read-byte) (ash (read-byte) 8) (ash (read-byte) 16)) (+ 1 (ash 2 8) (ash 3 16)) (+ (read-byte) (read-byte) (ash (read-byte) 8)) (+ 1 2 (ash 3 8)) (+ (read-byte) (ash (read-byte) 8) (read-byte)) (+ 1 (ash 2 8) 3) (+ (ash (read-byte) 8) (read-byte) (read-byte)) (+ (ash 1 8) 2 3) (+ (ash (read-byte) 8) (ash (read-byte) 16) (read-byte)) (+ (ash 1 8) (ash 2 16) 3) (+ (ash (read-byte) 8) (read-byte) (ash (read-byte) 16)) (+ (ash 1 8) 2 (ash 3 16))))))) (if (not (equal? v #(197121 197121 771 771 516 516 261 261 131331 131331 196866 196866))) (format *stderr* ";3 arg order check: ~A~%" v)))) (args3)) (if (not pure-s7) (for-each (lambda (arg) (test (char-ready? arg) 'error)) (list "hi" -1 #\a 1 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #f #t :hi (if #f #f) (lambda (a) (+ a 1))))) ;;; -------- format -------- ;;; format (test (format #f "hiho") "hiho") (test (format #f "") "") (test (format #f "" 1) 'error) (test (format #f "a") "a") ;(test (format #f "a\x00b") "a") (test (format #f "~~") "~") ; guile returns this, but clisp thinks it's an error (test (format #f "~~~~") "~~") (test (format #f "a~~") "a~") (test (format #f "~~a") "~a") (test (format #f "~A" "") "") (test (format #f "~{~^~A~}" ()) "") (test (format #f "~{~^~{~^~A~}~}" '(())) "") (test (format #f "~P" 1) "") (test (format #f "~P" #\a) 'error) (test (format #f "~0T") "") (test (format #f "") "") (test (format #f "~*~*" 1 2) "") (test (format #f "~20,'~D" 3) "~~~~~~~~~~~~~~~~~~~3") (test (format #f "~0D" 123) "123") (test (format #f "~{~S~}" ()) "") (test (format #f "~-1D" 123) 'error) (test (format #f "~+1D" 123) 'error) (test (format #f "~1.D" 123) 'error) (test (format #f "~1+iD" 123) 'error) (test (format #f "~1/2D" 123) 'error) (test (format #f "~1/1D" 123) 'error) (test (format #f "~20,'-1D" 123) 'error) (for-each (lambda (arg) (test (format arg "~D" 1) 'error)) (list "hi" #\a 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand :hi (if #f #f) (lambda (a) (+ a 1)))) (for-each (lambda (directive) (for-each (lambda (arg) (test (format #f directive arg) 'error) (test (format #f directive) 'error)) (list "hi" #\a 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand #f #t :hi (if #f #f) (lambda (a) (+ a 1))))) (list "~D" "~F" "~G" "~X" "~B" "~O" "~E" "~P")) (test (format #f "~,1" 123) 'error) ;format "~,1" 123: numeric argument, but no directive! ; (format #f "~,1" 123) (test (format #f "~,123456789123456789123456789d" 1) 'error) ;format "~,123456789123456789123456789d" 1: numeric argument too large ; (format-logged #t "~,123456789123456789123456789d" 1) (test (format #f "~969424987x" 12) 'error) (test (format #f "~D" 1 2) 'error) ;format: "~D" 1 2 ; ^: too many arguments ; (format #f "~D" 1 2) (test (format #f "~D~" 1) 'error) ;format: "~D~" 1 ; ^: control string ends in tilde ; (format #f "~D~" 1) (test (format #f "~") 'error) (test (format #f " ~") 'error) (test (format #f "~~~") 'error) (test (format #f " ~~~") 'error) (test (format #f "~@D" 1) 'error) ;format "~@D" 1: unknown '@' directive ; (format #f "~@D" 1) (test (format #f "~@p" #\a) 'error) ;format "~@p" #\a: '@P' directive argument is not an integer ; (format #f "~@p" #\a) (test (format #f "~P" 1+i) 'error) ;format "~P" 1+1i: 'P' directive argument is not a real number ; (format #f "~P" 1+1i) (test (format #f "~P" (real-part (log 0))) "s") (test (format #f "~@p" 0+i) 'error) ;format "~@p" 0+1i: '@P' directive argument is not a real number ; (format #f "~@p" 0+1i) (test (format #f "~{~}") 'error) ;format "~{~}": missing argument ; (format #f "~{~}") (test (format #f "~{~a" '(1 2 3)) 'error) ;format "~{~a" (1 2 3): '{' directive, but no matching '}' ; (format #f "~{~a" '(1 2 3)) (test (format #f "~{~a~}" '(1 . 2)) 'error) ;format "~{~a~}" (1 . 2): '{' directive argument should be a proper list or something we can turn into a list ; (format #f "~{~a~}" '(1 . 2)) (test (let ((lst (cons 1 2))) (set-cdr! lst lst) (format #f "~{~A~}" lst)) 'error) ;format "~{~A~}" #1=(1 . #1#): '{' directive argument should be a proper list or something we can turn into a list ; (format #f "~{~A~}" lst) (test (format #f "~{~a~}" 'asdf) 'error) ;format "~{~a~}" asdf: '{' directive argument should be a proper list or something we can turn into a list ; (format #f "~{~a~}" 'asdf) (test (format #f "~{~a~}" ()) "") (test (format #f "~{asd~}" '(1 2 3)) 'error) ;format: "~{asd~}" (1 2 3) ; ^: '{...}' doesn't consume any arguments! ; (format #f "~{asd~}" '(1 2 3)) (test (format #f "~}" '(1 2 3)) 'error) ;format "~}" (1 2 3): unmatched '}' ; (format #f "~}" '(1 2 3)) (test (format #f "~C") 'error) ;format "~C": ~C: missing argument ; (format #f "~C") (test (format #f "~A ~C" #\a) 'error) ;format: "~A ~C" #\a ; ^: ~C: missing argument ; (format #f "~A ~C" #\a) (test (format #f "~C" 1) 'error) ;format "~C" 1: 'C' directive requires a character argument ; (format #f "~C" 1) (test (format #f "~C" #) 'error) ;format "~C" #: 'C' directive requires a character argument ; (format #f "~C" #) (test (format #f "~1,9223372036854775807f" 1) 'error) ;format "~1,9223372036854775807f" 1: numeric argument too large ; (format #f "~1,9223372036854775807f" 1) (test (format #f "~1,2A" 1) 'error) ;format "~1,2A" 1: extra numeric argument ; (format #f "~1,2A" 1) (test (format #f "~F" #\a) 'error) ;format "~F" #\a: ~F: numeric argument required ; (format #f "~F" #\a) (test (format #f "~1,") 'error) ;format "~1,": format directive does not take a numeric argument ; (format #f "~1,") (test (format #f "~-1,") 'error) ;format "~-1,": unimplemented format directive ; (format #f "~-1,") (test (format #f "~L" 1) 'error) ;format "~L" 1: unimplemented format directive ; (format #f "~L" 1) (test (format #f "~*") 'error) ;format "~*": can't skip argument! (test (format #f "~*~A") 'error) (test (format #f "~*~*" 1) 'error) (test (format #f "~N") 'error) (test (format #f "~N" 2) 'error) (test (format #f "~N." 2) 'error) (test (format #f "~NT" 2.1) 'error) (test (format #f "~NT" #\a) 'error) (test (format #f "~N," 1) 'error) (test (format #f "~N,N" 1 2) 'error) (test (format #f "~N,N." 1 2) 'error) (test (format #f "~,N" 1) 'error) (test (format #f "~,N." 1) 'error) (test (format #f "~ND" 123456789) 'error) (test (format #f "~ND" -1) 'error) (for-each (lambda (c) (test (apply format #f (string-append "~" (string c)) '(a)) 'error)) (list #\H #\I #\J #\K #\L #\M #\Q #\R #\U #\V #\Y #\Z #\[ #\\ #\] #\_ #\` #\$ #\# #\! #\" #\' #\( #\) #\+ #\, #\- #\. #\/ #\< #\= #\> #\? #\h #\i #\j #\k #\l #\m #\q #\r #\u #\v #\y #\z)) (test (format #f "~A" 1 2) 'error) ;format: "~A" 1 2 ; ^: too many arguments ; (format #f "~A" 1 2) (test (format #f "hiho~%ha") (string-append "hiho" (string #\newline) "ha")) (test (format #f "~%") (string #\newline)) (test (format #f "~%ha") (string-append (string #\newline) "ha")) (test (format #f "hiho~%") (string-append "hiho" (string #\newline))) (test (eq? #\tab ((format #f "\t") 0)) #t) (test (eq? #\newline ((format #f "\n") 0)) #t) (test (eq? #\\ ((format #f "\\") 0)) #t) (test (eq? #\" ((format #f "\"") 0)) #t) (for-each (lambda (arg res) (let ((val (catch #t (lambda () (format #f "~A" arg)) (lambda args 'error)))) (if (or (not (string? val)) (not (string=? val res))) (begin (display "(format #f \"~A\" ") (display arg) (display " returned \"") (display val) (display "\" but expected \"") (display res) (display "\"") (newline))))) (list "hiho" -1 #\a 1 #f #t #(1 2 3) 3.14 3/4 1.5+1.5i () #(()) (list 1 2 3) '(1 . 2) 'hi) (list "hiho" "-1" "a" "1" "#f" "#t" "#(1 2 3)" "3.14" "3/4" "1.5+1.5i" "()" "#(())" "(1 2 3)" "(1 . 2)" "hi")) (test (format #f "hi ~A ho" 1) "hi 1 ho") (test (format #f "hi ~a ho" 1) "hi 1 ho") (test (format #f "~a~A~a" 1 2 3) "123") (test (format #f "~a~~~a" 1 3) "1~3") (test (format #f "~a~%~a" 1 3) (string-append "1" (string #\newline) "3")) (for-each (lambda (arg res) (let ((val (catch #t (lambda () (format #f "~S" arg)) (lambda args 'error)))) (if (or (not (string? val)) (not (string=? val res))) (begin (display "(format #f \"~S\" ") (display arg) (display " returned \"") (display val) (display "\" but expected \"") (display res) (display "\"") (newline))))) (list "hiho" -1 #\a 1 #f #t #(1 2 3) 3.14 3/4 1.5+1.5i () #(()) (list 1 2 3) '(1 . 2) 'hi) (list "\"hiho\"" "-1" "#\\a" "1" "#f" "#t" "#(1 2 3)" "3.14" "3/4" "1.5+1.5i" "()" "#(())" "(1 2 3)" "(1 . 2)" "hi")) (test (format #f "hi ~S ho" 1) "hi 1 ho") (test (format #f "hi ~S ho" "abc") "hi \"abc\" ho") (test (format #f "~s~a" #\a #\b) "#\\ab") (test (format #f "~C~c~C" #\a #\b #\c) "abc") ;(test (format #f "1 2~C 3 4" #\null) "1 2") ; ?? everyone does something different here ;; s7 used to return "1 2 3 4" because it treated ~C as a string (empty in this case) (test (format #f "1 2~C 3 4" #\null) "1 2\x00 3 4") ; this is also what Guile returns (test (format #f "~nc" 3 #\a) "aaa") (test (format #f "~nc" 0 #\a) "") (test (format #f "~nc" -1 #\a) 'error) (test (format #f "~nc" most-positive-fixnum #\a) 'error) (test (format #f "~nc" 1.0 #\a) 'error) (test (format #f "~n~nc" 1 2 #\a) 'error) (test (format #f "~na" 1 #\a) 'error) (test (format #f "~{~A~}" '(1 2 3)) "123") (test (format #f "asb~{~A ~}asb" '(1 2 3 4)) "asb1 2 3 4 asb") (test (format #f "asb~{~A ~A.~}asb" '(1 2 3 4)) "asb1 2.3 4.asb") (test (format #f ".~{~A~}." ()) "..") (test (format #f "~{~A ~A ~}" '(1 "hi" 2 "ho")) "1 hi 2 ho ") (test (format #f "~{.~{+~A+~}.~}" (list (list 1 2 3) (list 4 5 6))) ".+1++2++3+..+4++5++6+.") (test (format #f "~{~s ~}" '(fred jerry jill)) "fred jerry jill ") (test (format #f "~{~s~^ ~}" '(fred jerry jill)) "fred jerry jill") (test (format #f "~{~s~^~^ ~}" '(fred jerry jill)) "fred jerry jill") (test (format #f "~{.~{~A~}+~{~A~}~}" '((1 2) (3 4 5) (6 7 8) (9))) ".12+345.678+9") (test (format #f "~{.~{+~{-~A~}~}~}" '(((1 2) (3 4 5)))) ".+-1-2+-3-4-5") (test (format #f "~{.~{+~{-~A~}~}~}" '(((1 2) (3 4 5)) ((6) (7 8 9)))) ".+-1-2+-3-4-5.+-6+-7-8-9") (test (format #f "~A ~* ~A" 1 2 3) "1 3") (test (format #f "~*" 1) "") (test (format #f "~{~* ~}" '(1 2 3)) " ") (test (format #f "~A" catch) "catch") (test (format #f "this is a ~ sentence") "this is a sentence") (test (format #f "~{~C~}" "hi") "hi") (test (format #f "~{~C~}" #(#\h #\i)) "hi") (test (format #f "~{.~{~C+~}~}" '((#\h #\i) (#\h #\o))) ".h+i+.h+o+") (test (format #f "~{.~{~C+~}~}" '("hi" "ho")) ".h+i+.h+o+") (test (format #f "~{.~{~C+~}~}" #("hi" "ho")) ".h+i+.h+o+") (test (format #f "~{.~{~C+~}~}" #(#(#\h #\i) #(#\h #\o))) ".h+i+.h+o+") ; (format #f "~{.~{~C~+~}~}" #2d((#\h #\i) (#\h #\o))) error?? -- this is documented... (test (format #f "~{~A~}" #2D((1 2) (3 4))) "1234") ; this seems inconsistent with: (test (format #f "~{~A~}" '((1 2) (3 4))) "(1 2)(3 4)") (test (format #f "~{~A ~}" #2d((1 2) (3 4))) "1 2 3 4 ") (test (format #f "1~\ a2" 3) "132") (test (format #f "~{~{~C~^ ~}~^...~}" (list "hiho" "test")) "h i h o...t e s t") ;; ~nT handling is a mess -- what are the defaults? which is column 1? do we space up to or up to and including? (test (format #f "~A:~8T~A" 100 'a) "100: a") (test (format #f "~A:~nT~A" 100 8 'a) "100: a") (test (format #f "~A:~8T~A" 0 'a) "0: a") (test (format #f "~A:~8T~A" 10000 'a) "10000: a") (test (format #f "~8T~A" 'a) " a") (test (format #f "1212:~8T~A" 'a) "1212: a") (test (format #f "~D:~8T~A" 100 'a) "100: a") (test (format #f "~D:~8T~A" 0 'a) "0: a") (test (format #f "~D:~8T~A" 10000 'a) "10000: a") (test (format #f "~a~10,7Tb" 1) "1 b") (test (format #f "~a~10,7Tb" 10000) "10000 b") (test (format #f "~a~10,12Tb" 1) "1 b") (test (format #f "~a~10,12Tb" 10000) "10000 b") (test (format #f "~a~n,nTb" 10000 10 12) "10000 b") (test (format #f "~n,'xT" 8) "xxxxxxx") (test (format #f "~n,' T" 8) " ") (test (length (format #f "~{~A~}~40T." '(1 2 3))) 40) (test (length (format #f "~{~A ~}~40T." '(1 2 3))) 40) (test (length (format #f "~{~,3F ~}~40T." '(1.0 2.0 3.0))) 40) (test (length (format #f "~S~40T." pi)) (if with-bignums 44 40)) (test (format #f "asdh~20Thiho") "asdh hiho") (test (format #f "asdh~2Thiho") "asdhhiho") (test (format #f "a~Tb") "ab") (test (format #f "0123456~4,8Tb") "0123456 b") (test (format #f "0123456~0,8Tb") "0123456b") (test (format #f "0123456~10,8Tb") "0123456 b") (test (format #f "0123456~1,0Tb") "0123456b") (test (format #f "0123456~1,Tb") "0123456b") (test (format #f "0123456~1,Tb") "0123456b") (test (format #f "0123456~,Tb") "0123456b") (test (format #f "0123456~7,10Tb") "0123456 b") (test (format #f "0123456~8,10tb") "0123456 b") (test (format #f "0123456~3,12tb") "0123456 b") (test (format #f "~40TX") " X") (test (format #f "X~,8TX~,8TX") "X X X") (test (format #f "X~8,TX~8,TX") "X XX") (test (format #f "X~8,10TX~8,10TX") "X X X") (test (format #f "X~8,0TX~8,0TX") "X XX") (test (format #f "X~0,8TX~0,8TX") "X X X") (test (format #f "X~1,8TX~1,8TX") "X X X") (test (format #f "X~,8TX~,8TX") "X X X") ; ?? (test (format #f "X~TX~TX") "XXX") ; clisp and sbcl say "X X X" here and similar differences elsewhere -- is it colnum or colinc as default if no comma? (test (format #f "X~2TX~4TX") "XX X") (test (format #f "X~0,0TX~0,0TX") "XXX") (test (format #f "X~0,TX~0,TX") "XXX") (test (format #f "X~,0TX~,0TX") "XXX") (test (format #f "~0D" 123) "123") (test (format #f "~0F" 123.123) "123.123000") (test (format #f "~,0D" 123) "123") (test (format #f "~,0F" 123.123) "123.0") (test (format #f "~,D" 123) "123") (test (format #f "~,F" 123.123) "123.123000") (test (format #f "~0,D" 123) "123") (test (format #f "~0,F" 123.123) "123.123000") (test (format #f "~0,0D" 123) "123") (test (format #f "~n,nD" 0 0 123) "123") (test (format #f "~0,0F" 123.123) "123.0") (test (format #f "~0,0,D" 123) 'error) (test (format #f "~n,n,D" 0 0 123) 'error) (test (format #f "~0,0,F" 123.123) 'error) (test (format #f "~,3F" 1+i) "1.000+1.000i") (test (format #f "~,nF" 3 1+i) "1.000+1.000i") (test (format #f "~,3G" 1+i) "1+1i") (test (format #f "~,3E" 1+i) "1.000e+00+1.000e+00i") (test (format #f "~,3F" 1-i) "1.000-1.000i") (test (format #f "~,3G" 1-i) "1-1i") (test (format #f "~,3E" 1-i) "1.000e+00-1.000e+00i") ;; not sure about these: (test (format #f "~X" 1-i) "1.0-1.0i") (test (format #f "~,3D" 1-i) "1.000e+00-1.000e+00i") (test (format #f "~A" 1-i) "1-1i") (test (format #f "~W" 3) "3") (test (format #f "~W" 3/4) "3/4") (test (format #f "~W" 3.4) "3.4") (if with-bignums (test (format #f "~W" pi) "3.141592653589793238462643383279502884195E0") (test (format #f "~W" pi) "3.141592653589793")) (test (format #f "~W" 3+4i) "3+4i") (test (format #f "~W" 3-4i) "3-4i") (if (not with-bignums) (let ((name (if pure-s7 'complex 'complex)) (func (if pure-s7 complex complex))) (test (format #f "~W" (func 1/0 0)) "nan.0") (test (format #f "~W" (func 1/0 1)) (format #f "(~S nan.0 1)" name)) (test (format #f "~W" (func inf.0 1/0)) (format #f "(~S inf.0 nan.0)" name)) (test (format #f "~W" (log 0)) (format #f "(~S -inf.0 3.141592653589793)" name)))) ;; see also object->string with :readable (test (format #f "~000000000000000000000000000000000000000000003F" 123.123456789) "123.123457") (test (format #f "~922337203685477580F" 123.123) 'error) ; numeric argument too large (test (format #f "~,922337203685477580F" 123.123) 'error) (test (format #f "~1,922337203685477580F" 123.123) 'error) (test (format #f "~1 ,2F" 123.456789) 'error) (test (format #f "~1, 2F" 123.456789) 'error) (test (format #f "~1, F" 123.456789) 'error) (if with-bignums (begin (test (format #f "~o" 1e19) "1.053071060221172E21") (test (format #f "~o" -1e19) "-1.053071060221172E21") (test (format #f "~x" 1e19) "8.ac7230489e8@15") (test (format #f "~b" 1e19) "1.00010101100011100100011000001001000100111101E63") (test (format #f "~o" 1e308) "1.071474702753621177617256074117252375235444E341") (test (format #f "~o" -1e308) "-1.071474702753621177617256074117252375235444E341") (test (format #f "~x" 1e308) "8.e679c2f5e44ff8f570f09eaa7ea7648@255") (test (format #f "~x" 9.22e18) "7.ff405267d1a@15") (test (format #f "~b" 1e308) "1.0001110011001111001110000101111010111100100010011111111100011110101011100001111000010011110101010100111111010100111011001001E1023") (test (format #f "~,791o" 1e308) "1.071474702753621177617256074117252375235444E341") (test (format #f "~1200,2g" 1e308) " 9.999999999999999999999999999999999999982E307") (test (format #f "~o" 1e19-1e20i) "1.053071060221172E21-1.2657072742654304E22i") (test (format #f "~x" 1e308+1e300i) "8.e679c2f5e44ff8f570f09eaa7ea7648@255+1.7e43c8800759ba59c08e14c7cd7aad86@249i")) (begin (test (format #f "~o" 1e19) "1.053071e21") (test (format #f "~o" -1e19) "-1.053071e21") (test (format #f "~x" 1e19) "8.ac723e15") (test (format #f "~b" 1e19) "1.000101e63") (test (format #f "~o" 1e308) "1.071474e341") (test (format #f "~o" -1e308) "-1.071474e341") (test (format #f "~x" 1e308) "8.e679c2e255") (test (or (string=? (format #f "~x" 9.22e18) "7ff405267d1a0000.0") (string=? (format #f "~x" 9.22e18) "7.ff4052e15")) #t) ; this depends on a cutoff point in s7.c, L8850, number_to_string_with_radix (test (format #f "~b" 1e308) "1.000111e1023") (test (format #f "~,791o" 1e308) "1.0714747027536212e341") (test (format #f "~1200,2g" 1e308) " 1e+308") (test (format #f "~o" 1e19-1e20i) "1.053071e21-1.265707e22i") (test (format #f "~x" 1e308+1e300i) "8.e679c2e255+1.7e43c8e249i"))) (test (= (length (substring (format #f "~%~10T.") 1)) (length (format #f "~10T."))) #t) (test (= (length (substring (format #f "~%-~10T.~%") 1)) (length (format #f "-~10T.~%"))) #t) (test (string=? (format #f "~%|0 1 2|~21T|5 8 3 2|~%~ |1 2 3| |0 1 2 3|~21T|8 14 8 6|~%~ |2 3 0| |1 2 3 0| = ~21T|3 8 13 6|~%~ |3 0 1| |2 3 0 1|~21T|2 6 6 10|~%") " |0 1 2| |5 8 3 2| |1 2 3| |0 1 2 3| |8 14 8 6| |2 3 0| |1 2 3 0| = |3 8 13 6| |3 0 1| |2 3 0 1| |2 6 6 10| ") #t) (if (not with-windows) (test (format #f "~S" '(+ 1/0 1/0)) "(+ nan.0 nan.0)")) ; !? (if (not with-windows) (test (format #f "~S" '(+ '1/0 1/0)) "(+ 'nan.0 nan.0)")) ; !? (test (format #f "~S" '(+ 1/0 1.0/0.0)) (format #f "~S" (list '+ '1/0 '1.0/0.0))) (test (format #f "~S" (quote (+ '1 1))) "(+ '1 1)") (test (format #f "~12,''D" 1) "'''''''''''1") (test (let ((str "~12,'xD")) (set! (str 5) #\space) (format #f str 1)) " 1") (test (format #f "~12,' D" 1) " 1") (test (format #f "~12,'\\D" 1) "\\\\\\\\\\\\\\\\\\\\\\1") (test (format #f "~12,'\"D" 1) "\"\"\"\"\"\"\"\"\"\"\"1") (test (format #f "~12,'~D" 1) "~~~~~~~~~~~1") (test (format #f "~12,',d" 1) ",,,,,,,,,,,1") (test (format #f "~12,',,d" 1) 'error) (test (format #f "~12,,d" 1) 'error) (test (format #f "~n,,d" 12 1) 'error) (test (string=? (format #f "~%~&" ) (string #\newline)) #t) (test (string=? (format #f "~%a~&" ) (string #\newline #\a #\newline)) #t) (test (string=? (format #f "~%~%") (string #\newline #\newline)) #t) (test (string=? (format #f "~10T~%~&~10T.") (format #f "~10T~&~&~10T.")) #t) (test (string=? (format #f "~10T~&~10T.") (format #f "~10T~%~&~&~&~&~10T.")) #t) (test (length (format #f "~%~&~%")) 2) (test (length (format #f "~%~&~&~&~&~%")) 2) (test (length (format #f "~&~%")) 1) (test (format #f "~2,1F" 0.5) "0.5") (test (format #f "~:2T") 'error) (test (format #f "~2,1,3F" 0.5) 'error) (test (format #f "~<~W~>" 'foo) 'error) (test (format #f "~{12") 'error) (test (format #f "~{}") 'error) (test (format #f "~{}" '(1 2)) 'error) (test (format #f "{~}" '(1 2)) 'error) (test (format #f "~{~{~}}" '(1 2)) 'error) (test (format #f "~}" ) 'error) ;(test (format #f "#|~|#|") 'error) ; ~| is ~^+ now (test (format #f "~1.5F" 1.5) 'error) (test (format #f "~1+iF" 1.5) 'error) (test (format #f "~1,1iF" 1.5) 'error) (test (format #f "~0" 1) 'error) (test (format #f "~1") 'error) (test (format #f "~^" 1) 'error) (test (format #f "~.0F" 1.0) 'error) (test (format #f "~1.0F" 1.0) 'error) (test (format #f "~-1F" 1.0) 'error) (test (format #f "~^") "") (test (format #f "~A ~A~|this is not printed" 1 2) "1 2") (test (format #f "~^~A~^~A~^this is not printed" 1 2) "12") (test (format #f "~|") "") (test (format #f "~D~" 9) 'error) (test (format #f "~&" 9) 'error) (test (format #f "~D~100T~D" 1 1) "1 1") (test (format #f ".~P." 1) "..") (test (format #f ".~P." 1.0) "..") (test (format #f ".~P." 1.2) ".s.") (test (format #f ".~P." 2/3) ".s.") (test (format #f ".~P." 2) ".s.") (test (format #f ".~p." 1) "..") (test (format #f ".~p." 1.0) "..") (test (format #f ".~p." 1.2) ".s.") (test (format #f ".~p." 2) ".s.") (test (format #f ".~@P." 1) ".y.") (test (format #f ".~@P." 1.0) ".y.") (test (format #f ".~@P." 1.2) ".ies.") (test (format #f ".~@P." 2) ".ies.") (test (format #f ".~@p." 1) ".y.") (test (format #f ".~@p." 1.0) ".y.") (test (format #f ".~@p." 1.2) ".ies.") (test (format #f ".~@p." 2) ".ies.") (test (format #f ".~P." 1.0+i) 'error) (test (format #f ".~P." 1/0) ".s.") (test (format #f "~P" 1) "") ; Clisp does this (if (not with-windows) (test (format #f ".~P." (real-part (log 0))) ".s.")) (test (format #f (string #\~ #\a) 1) "1") (test (format #f (format #f "~~a") 1) "1") (test (format #f (format #f "~~a") (format #f "~D" 1)) "1") (test (format #f "~A" (quasiquote quote)) "quote") (test (format #f "~f" (/ 1 3)) "1/3") ; hmmm -- should it call exact->inexact? (test (format #f "~f" 1) "1") (test (format #f "~F" most-positive-fixnum) "9223372036854775807") (if (not with-bignums) (begin (test (format #f "~,20F" 1e-20) "0.00000000000000000001") (test (format #f "~,40F" 1e-40) "0.0000000000000000000000000000000000000001"))) ;; if with bignums, these needs more bits ;;; the usual troubles here with big floats: ;;; (format #f "~F" 922337203685477580.9) -> "922337203685477632.000000" ;;; (format #f "~F" 9223372036854775.9) -> "9223372036854776.000000" ;;; (format #f "~F" 1e25) -> "10000000000000000905969664.000000" ;;; or small: ;;; (format #f "~,30F" 1e-1) -> "0.100000000000000005551115123126" (if with-bignums (begin (test (format #f "~A" -7043009959286724629649270926654940933664689003233793014518979272497911394287216967075767325693021717277238746020477538876750544587281879084559996466844417586093291189295867052594478662802691926547232838591510540917276694295393715934079679531035912244103731582711556740654671309980075069010778644542022/670550434139267031632063192770201289106737062379324644110801846820471752716238484923370056920388400273070254958650831435834503195629325418985020030706879602898158806736813101434594805676212779217311897830937606064579213895527844045511878668289820732425014254579493444623868748969110751636786165152601) "-7043009959286724629649270926654940933664689003233793014518979272497911394287216967075767325693021717277238746020477538876750544587281879084559996466844417586093291189295867052594478662802691926547232838591510540917276694295393715934079679531035912244103731582711556740654671309980075069010778644542022/670550434139267031632063192770201289106737062379324644110801846820471752716238484923370056920388400273070254958650831435834503195629325418985020030706879602898158806736813101434594805676212779217311897830937606064579213895527844045511878668289820732425014254579493444623868748969110751636786165152601") (test (format #f "~D" -7043009959286724629649270926654940933664689003233793014518979272497911394287216967075767325693021717277238746020477538876750544587281879084559996466844417586093291189295867052594478662802691926547232838591510540917276694295393715934079679531035912244103731582711556740654671309980075069010778644542022/670550434139267031632063192770201289106737062379324644110801846820471752716238484923370056920388400273070254958650831435834503195629325418985020030706879602898158806736813101434594805676212779217311897830937606064579213895527844045511878668289820732425014254579493444623868748969110751636786165152601) "-7043009959286724629649270926654940933664689003233793014518979272497911394287216967075767325693021717277238746020477538876750544587281879084559996466844417586093291189295867052594478662802691926547232838591510540917276694295393715934079679531035912244103731582711556740654671309980075069010778644542022/670550434139267031632063192770201289106737062379324644110801846820471752716238484923370056920388400273070254958650831435834503195629325418985020030706879602898158806736813101434594805676212779217311897830937606064579213895527844045511878668289820732425014254579493444623868748969110751636786165152601") )) (test (format #f "~@F" 1.23) 'error) (test (format #f "~{testing ~D ~C ~}" (list 0 #\( 1 #\) 2 #\* 3 #\+ 4 #\, 5 #\- 6 #\. 7 #\/ 8 #\0 9 #\1 10 #\2 11 #\3 12 #\4 13 #\5 14 #\6 15 #\7 16 #\8 17 #\9 18 #\: 19 #\; 20 #\< 21 #\= 22 #\> 23 #\? 24 #\@ 25 #\A 26 #\B 27 #\C 28 #\D 29 #\E 30 #\F 31 #\G 32 #\H 33 #\I 34 #\J 35 #\K 36 #\L 37 #\M 38 #\N 39 #\O 40 #\P 41 #\Q 42 #\R 43 #\S 44 #\T 45 #\U 46 #\V 47 #\W 48 #\X 49 #\Y 50 #\( 51 #\) 52 #\* 53 #\+ 54 #\, 55 #\- 56 #\. 57 #\/ 58 #\0 59 #\1 60 #\2 61 #\3 62 #\4 63 #\5 64 #\6 65 #\7 66 #\8 67 #\9 68 #\: 69 #\; 70 #\< 71 #\= 72 #\> 73 #\? 74 #\@ 75 #\A 76 #\B 77 #\C 78 #\D 79 #\E 80 #\F 81 #\G 82 #\H 83 #\I 84 #\J 85 #\K 86 #\L 87 #\M 88 #\N 89 #\O 90 #\P 91 #\Q 92 #\R 93 #\S 94 #\T 95 #\U 96 #\V 97 #\W 98 #\X 99 #\Y)) "testing 0 ( testing 1 ) testing 2 * testing 3 + testing 4 , testing 5 - testing 6 . testing 7 / testing 8 0 testing 9 1 testing 10 2 testing 11 3 testing 12 4 testing 13 5 testing 14 6 testing 15 7 testing 16 8 testing 17 9 testing 18 : testing 19 ; testing 20 < testing 21 = testing 22 > testing 23 ? testing 24 @ testing 25 A testing 26 B testing 27 C testing 28 D testing 29 E testing 30 F testing 31 G testing 32 H testing 33 I testing 34 J testing 35 K testing 36 L testing 37 M testing 38 N testing 39 O testing 40 P testing 41 Q testing 42 R testing 43 S testing 44 T testing 45 U testing 46 V testing 47 W testing 48 X testing 49 Y testing 50 ( testing 51 ) testing 52 * testing 53 + testing 54 , testing 55 - testing 56 . testing 57 / testing 58 0 testing 59 1 testing 60 2 testing 61 3 testing 62 4 testing 63 5 testing 64 6 testing 65 7 testing 66 8 testing 67 9 testing 68 : testing 69 ; testing 70 < testing 71 = testing 72 > testing 73 ? testing 74 @ testing 75 A testing 76 B testing 77 C testing 78 D testing 79 E testing 80 F testing 81 G testing 82 H testing 83 I testing 84 J testing 85 K testing 86 L testing 87 M testing 88 N testing 89 O testing 90 P testing 91 Q testing 92 R testing 93 S testing 94 T testing 95 U testing 96 V testing 97 W testing 98 X testing 99 Y ") (let ((old-len (*s7* 'print-length))) (let ((vect1 #3D(((1 2 3) (3 4 5)) ((5 6 1) (7 8 2)))) (vect2 #2d((1 2 3 4 5 6) (7 8 9 10 11 12))) (vect3 #(1 2 3 4 5 6 7 8 9 10 11 12 13 14)) (vect4 #3D(((1 2) (3 4) (5 6)) ((7 8) (9 10) (11 12))))) (do ((i 0 (+ i 2))) ((>= i 10)) (set! (*s7* 'print-length) i) (test (object->string vect1) (format #f "~A" vect1)) (test (object->string vect2) (format #f "~A" vect2)) (test (object->string vect3) (format #f "~A" vect3)) (test (object->string vect4) (format #f "~A" vect4)))) (set! (*s7* 'print-length) 0) (test (format #f "~A" #()) "#()") (set! (*s7* 'print-length) old-len)) (let ((old-pl (*s7* 'print-length))) (set! (*s7* 'print-length) 3) (let ((lst (list 1))) (set-car! lst lst) (let ((v (vector 1 1 1 1 1 1 1 1 1 lst))) (let ((str (format #f "~A" v))) (test (string=? str "#(1 1 1 ...)") #t)))) (set! (*s7* 'print-length) old-pl)) (test (format #f "~D" 123) "123") (test (format #f "~X" 123) "7b") (test (format #f "~B" 123) "1111011") (test (format #f "~O" 123) "173") (test (format #f "~10D" 123) " 123") (test (format #f "~nD" 10 123) " 123") (test (format #f "~10X" 123) " 7b") (test (format #f "~10B" 123) " 1111011") (test (format #f "~10O" 123) " 173") (test (format #f "~D" -123) "-123") (test (format #f "~X" -123) "-7b") (test (format #f "~B" -123) "-1111011") (test (format #f "~O" -123) "-173") (test (format #f "~10D" -123) " -123") (test (format #f "~10X" -123) " -7b") (test (format #f "~10B" -123) " -1111011") (test (format #f "~10O" -123) " -173") (test (format #f "~d" 123) "123") (test (format #f "~x" 123) "7b") (test (format #f "~b" 123) "1111011") (test (format #f "~o" 123) "173") (test (format #f "~10d" 123) " 123") (test (format #f "~10x" 123) " 7b") (test (format #f "~10b" 123) " 1111011") (test (format #f "~10o" 123) " 173") (test (format #f "~d" -123) "-123") (test (format #f "~x" -123) "-7b") (test (format #f "~b" -123) "-1111011") (test (format #f "~o" -123) "-173") (test (format #f "~10d" -123) " -123") (test (format #f "~10x" -123) " -7b") (test (format #f "~10b" -123) " -1111011") (test (format #f "~10o" -123) " -173") (test (format #f "~D" most-positive-fixnum) "9223372036854775807") (test (format #f "~D" (+ 1 most-negative-fixnum)) "-9223372036854775807") (test (format #f "~X" most-positive-fixnum) "7fffffffffffffff") (test (format #f "~X" (+ 1 most-negative-fixnum)) "-7fffffffffffffff") (test (format #f "~O" most-positive-fixnum) "777777777777777777777") (test (format #f "~O" (+ 1 most-negative-fixnum)) "-777777777777777777777") (test (format #f "~B" most-positive-fixnum) "111111111111111111111111111111111111111111111111111111111111111") (test (format #f "~B" (+ 1 most-negative-fixnum)) "-111111111111111111111111111111111111111111111111111111111111111") (num-test (inexact->exact most-positive-fixnum) most-positive-fixnum) (test (format #f "~0D" 123) "123") (test (format #f "~0X" 123) "7b") (test (format #f "~0B" 123) "1111011") (test (format #f "~0O" 123) "173") (test (format #f "" 1) 'error) (test (format #f "hiho" 1) 'error) (test (format #f "a~%" 1) 'error) ; some just ignore extra args (for-each (lambda (arg) (let ((result (catch #t (lambda () (format arg "hiho")) (lambda args 'error)))) (if (not (eq? result 'error)) (begin (display "(format ") (display arg) (display " \"hiho\")") (display " returned ") (display result) (display " but expected 'error") (newline))))) (list -1 #\a 1 #(1 2 3) 3.14 3/4 1.0+1.0i 'hi :hi # abs (lambda () 1) #(()) (list 1 2 3) '(1 . 2))) (for-each (lambda (arg) (let ((result (catch #t (lambda () (format #f arg)) (lambda args 'error)))) (if (not (eq? result 'error)) (begin (display "(format #f ") (display arg) (display ")") (display " returned ") (display result) (display " but expected 'error") (newline))))) (list -1 #\a 1 #f #t #(1 2 3) 3.14 3/4 1.0+1.0i () 'hi abs (lambda () 1) #(()) (list 1 2 3) '(1 . 2))) (test (format #f "hi ~A ho" 1 2) 'error) (test (format #f "hi ~A ho") 'error) (test (format #f "hi ~S ho") 'error) (test (format #f "hi ~S ho" 1 2) 'error) (test (format #f "~C" 1) 'error) (test (format #f "123 ~R 321" 1) 'error) (test (format #f "123 ~,3R 321" 1) 'error) (test (format #f "~,2,3,4D" 123) 'error) (test (format #f "hi ~Z ho") 'error) (test (format #f "hi ~+ ho") 'error) (test (format #f "hi ~# ho") 'error) (test (format #f "hi ~, ho") 'error) (test (format #f "hi ~} ho") 'error) (test (format #f "hi {ho~}") 'error) (test (format #f "asb~{~A asd" '(1 2 3)) 'error) (test (format #f "~{~A~}" 1 2 3) 'error) (test (format #f "asb~{~}asd" '(1 2 3)) 'error) (test (format #f "asb~{ ~}asd" '(1 2 3)) 'error) (test (format #f "asb~{ . ~}asd" '(1 2 3)) 'error) (test (format #f "asb~{ hiho~~~}asd" '(1 2 3)) 'error) (test (format #f "~12C" #\a) "aaaaaaaaaaaa") (test (format #f ".~0C." #\a) "..") (test (format #f "~10C" #\space) " ") (test (format #f "~12P" #\a) 'error) (test (format #f "~12*" #\a) 'error) (test (format #f "~12%" #\a) 'error) (test (format #f "~12^" #\a) 'error) (test (format #f "~12{" #\a) 'error) (test (format #f "~12,2A" #\a) 'error) (test (format #f "~12,A" #\a) 'error) ; s7 misses padding errors such as (format #f "~12,' A" #\a) ;;; I removed this feature 21-Jun-12 ;(test (format #f "~12A" "012345678901234567890") "012345678...") ;(test (format #f "~1A" "012345678901234567890") "0") ;(test (format #f "~40A" "012345678901234567890") "012345678901234567890") ;(test (format #f "~12s" "012345678901234567890") "\"0123456...\"") ; ;(let ((old-len (*s7* 'print-length))) ; (set! (*s7* 'print-length) 32) ; (test (let ((v (vector 1 2 3 4 5 6 7 8 9 10))) (format #f "~A" v)) "#(1 2 3 4 5 6 7 8 9 10)") ; (test (let ((v (vector 1 2 3 4 5 6 7 8 9 10))) (format #f "~10A" v)) "#(1 2 3...") ; (test (let ((v (vector 1 2 3 4 5 6 7 8 9 10))) (format #f "~20A" v)) "#(1 2 3 4 5 6 7 8...") ; (test (let ((v (vector 1 2 3 4 5 6 7 8 9 10))) (format #f "~30A" v)) "#(1 2 3 4 5 6 7 8 9 10)") ; (test (let ((v (vector 1 2 3 4 5 6 7 8 9 10))) (format #f "~-10A" v)) 'error) ; (test (let ((v (vector 1 2 3 4 5 6 7 8 9 10))) (format #f "~10.0A" v)) 'error) ; (test (let ((v (vector 1 2 3 4 5 6 7 8 9 10))) (format #f "~10,0A" v)) 'error) ; (test (let ((v (vector 1 2 3 4 5 6 7 8 9 10))) (format #f "~10,A" v)) "#(1 2 3...") ; (test (let ((v (vector 1 2 3 4 5 6 7 8 9 10))) (format #f "~10,,A" v)) 'error) ; (test (let ((v (vector 1 2 3 4 5 6 7 8 9 10))) (format #f "~,10A" v)) 'error) ; (set! (*s7* 'print-length) old-len)) ; ;(test (let ((v (hash-table '(a . 1) '(b . 2) '(c . 3) '(d . 4)))) (format #f "~20A" v)) "(hash-table '(a ....") ;(test (let ((v (hash-table '(a . 1) '(b . 2) '(c . 3) '(d . 4)))) (format #f "~40A" v)) "(hash-table '(a . 1) '(b . 2) '(c . 3)...") ; ;(test (let ((v (list 1 2 3 4 5 6 7 8 9 10))) (format #f "~20A" v)) "(1 2 3 4 5 6 7 8...") #| (let ((v (vector 1 2 3 4 5 6 7 8 9 10))) (do ((i 0 (+ i 1))) ((= i 30)) (let ((str (string-append "~" (number->string i) "A"))) (let ((nstr (format #f str v))) (format *stderr* "~D: ~A: ~D~%" i nstr (length nstr)))))) (let ((v (hash-table '(a . 1) '(b . 2) '(c . 3) '(d . 4)))) (do ((i 0 (+ i 1))) ((= i 50)) (let ((str (string-append "~" (number->string i) "A"))) (let ((nstr (format #f str v))) (format *stderr* "~D: ~A: ~D~%" i nstr (length nstr)))))) (let ((v (list 1 2 3 4 5 6 7 8 9 10))) (do ((i 0 (+ i 1))) ((= i 24)) (let ((str (string-append "~" (number->string i) "A"))) (let ((nstr (format #f str v))) (format *stderr* "~D: ~A: ~D~%" i nstr (length nstr)))))) (do ((i 0 (+ i 1))) ((= i 256)) (let ((chr (integer->char i))) (format-logged #t "~D: ~A ~A ~D~%" i (format #f "~S" (string chr)) (string chr) (length (format #f "~S" (string chr)))))) |# (for-each (lambda (arg) (test (format #f "~F" arg) 'error)) (list "hi" #\a 'a-symbol (make-vector 3) abs #f #t :hi (if #f #f) (lambda (a) (+ a 1)))) (for-each (lambda (arg) (test (format #f "~D" arg) 'error)) (list "hi" #\a 'a-symbol (make-vector 3) abs #f #t :hi (if #f #f) (lambda (a) (+ a 1)))) (for-each (lambda (arg) (test (format #f "~P" arg) 'error)) (list "hi" #\a 'a-symbol (make-vector 3) abs #f #t :hi (if #f #f) (lambda (a) (+ a 1)))) (for-each (lambda (arg) (test (format #f "~X" arg) 'error)) (list "hi" #\a 'a-symbol (make-vector 3) abs #f #t :hi (if #f #f) (lambda (a) (+ a 1)))) (for-each (lambda (arg) (test (format #f "~C" arg) 'error)) (list "hi" 1 1.0 1+i 2/3 'a-symbol (make-vector 3) abs #f #t :hi (if #f #f) (lambda (a) (+ a 1)))) (for-each (lambda (arg) (test (format #f arg 123) 'error)) (list 1 1.0 1+i 2/3 'a-symbol (make-vector 3) abs #f #t :hi (if #f #f) (lambda (a) (+ a 1)))) (test (format #f "~{~A ~A ~}" '(1 "hi" 2)) 'error) (for-each (lambda (arg) (let ((result (catch #t (lambda () (format #f "~F" arg)) (lambda args 'error)))) (if (not (eq? result 'error)) (begin (display "(format #f \"~F\" ") (display arg) (display ") returned ") (display result) (display " but expected 'error") (newline))))) (list #\a #(1 2 3) "hi" () 'hi abs (lambda () 1) #(()) (list 1 2 3) '(1 . 2))) (test (format #f "~D") 'error) (test (format () "hi") 'error) (test (format #f "~F" "hi") 'error) (test (format #f "~D" #\x) 'error) (test (format #f "~C" (list 1 2 3)) 'error) (test (format #f "~1/4F" 1.4) 'error) (test (format #f "~1.4F" 1.4) 'error) (test (format #f "~F" (real-part (log 0.0))) "-inf.0") (test (let ((val (format #f "~F" (/ (real-part (log 0.0)) (real-part (log 0.0)))))) (or (string=? val "nan.0") (string=? val "-nan.0"))) #t) (test (format #f "~1/4T~A" 1) 'error) (test (format #f "~T") "") (test (format #f "~@P~S" 1 '(1)) "y(1)") (test (format #f ".~A~*" 1 '(1)) ".1") (test (format #f "~*~*~T" 1 '(1)) "") (test (format #f "~A" 'AB\c) "(symbol \"AB\\\\c\")") (test (format #f "~S" 'AB\c) "(symbol \"AB\\\\c\")") (test (format #f "~A" '(AB\c () xyz)) "((symbol \"AB\\\\c\") () xyz)") (test (format #f "~,2f" 1234567.1234) "1234567.12") (test (format #f "~5D" 3) " 3") (test (format #f "~5,'0D" 3) "00003") (test (format #f "++~{-=~s=-~}++" (quote (1 2 3))) "++-=1=--=2=--=3=-++") (test (format) 'error) (for-each (lambda (arg) (test (format arg) 'error)) (list 1 1.0 1+i 2/3 'a-symbol (make-vector 3) '(1 2) (cons 1 2) abs #f #t :hi (if #f #f) (lambda (a) (+ a 1)))) (test (format "hi") "hi") ; !? (test (format "~A ~D" 1/3 2) "1/3 2") (test (format "") "") ;; from slib/formatst.scm (test (string=? (format #f "abc") "abc") #t) (test (string=? (format #f "~a" 10) "10") #t) (test (string=? (format #f "~a" -1.2) "-1.2") #t) (test (string=? (format #f "~a" 'a) "a") #t) (test (string=? (format #f "~a" #t) "#t") #t) (test (string=? (format #f "~a" #f) "#f") #t) (test (string=? (format #f "~a" "abc") "abc") #t) (test (string=? (format #f "~a" #(1 2 3)) "#(1 2 3)") #t) (test (string=? (format #f "~a" ()) "()") #t) (test (string=? (format #f "~a" '(a)) "(a)") #t) (test (string=? (format #f "~a" '(a b)) "(a b)") #t) (test (string=? (format #f "~a" '(a (b c) d)) "(a (b c) d)") #t) (test (string=? (format #f "~a" '(a . b)) "(a . b)") #t) (test (string=? (format #f "~a ~a" 10 20) "10 20") #t) (test (string=? (format #f "~a abc ~a def" 10 20) "10 abc 20 def") #t) (test (string=? (format #f "~d" 100) "100") #t) (test (string=? (format #f "~x" 100) "64") #t) (test (string=? (format #f "~o" 100) "144") #t) (test (string=? (format #f "~b" 100) "1100100") #t) (test (string=? (format #f "~10d" 100) " 100") #t) (test (string=? (format #f "~10,'*d" 100) "*******100") #t) (test (string=? (format #f "~c" #\a) "a") #t) (test (string=? (format #f "~c" #\space) " ") #t) (test (string=? (format #f "~C" #\x91) "\x91") #t) (test (string=? (format #f "~C" #\x9) "\x09") #t) (test (string=? (format #f "~C" #\~) "~") #t) (test (string=? (format #f "~A" #\x91) "\x91") #t) (test (string=? (format #f "~S" #\x91) "#\\x91") #t) (test (string=? (format #f "~A" (string->symbol "hi")) "hi") #t) (test (string=? (format #f "~S" (string->symbol "hi")) "hi") #t) (test (string=? (format #f "~A" (string->symbol ";\\\";")) "(symbol \";\\\\\\\";\")") #t) (test (string=? (format #f "~S" (string->symbol ";\\\";")) "(symbol \";\\\\\\\";\")") #t) (test (string=? (format #f "~A" (string->symbol (string #\, #\. #\# #\; #\" #\\ #\' #\`))) "(symbol \",.#;\\\"\\\\'`\")") #t) (test (string=? (format #f "~~~~") "~~") #t) (test (string=? (format #f "~s" "abc") "\"abc\"") #t) (test (string=? (format #f "~s" "abc \\ abc") "\"abc \\\\ abc\"") #t) (test (string=? (format #f "~a" "abc \\ abc") "abc \\ abc") #t) (test (string=? (format #f "~s" "abc \" abc") "\"abc \\\" abc\"") #t) (test (string=? (format #f "~a" "abc \" abc") "abc \" abc") #t) (test (string=? (format #f "~s" #\space) "#\\space") #t) (test (string=? (format #f "~s" #\newline) "#\\newline") #t) (test (string=? (format #f "~s" #\a) "#\\a") #t) (test (string=? (format #f "~a" '(a "b" c)) "(a \"b\" c)") #t) (test (string=? (format #f "abc~ 123") "abc123") #t) (test (string=? (format #f "abc~ 123") "abc123") #t) (test (string=? (format #f "abc~ ") "abc") #t) (test (string=? (format #f "~{ ~a ~}" '(a b c)) " a b c ") #t) (test (string=? (format #f "~{ ~a ~}" ()) "") #t) (test (string=? (format #f "~{ ~a ~}" "") "") #t) (test (string=? (format #f "~{ ~a ~}" #()) "") #t) (test (string=? (format #f "~{ ~a,~a ~}" '(a 1 b 2 c 3)) " a,1 b,2 c,3 ") #t) (test (string=? (format #f "abc ~^ xyz") "abc ") #t) (test (format (values #f "~A ~D" 1 2)) "1 2") (test (format #f "~A~^" 1) "1") ; clisp agrees here (test (format #f "~A~*~* ~A" (values 1 2 3 4)) "1 4") (test (format #f "~^~A~^~*~*~^ ~^~A~^" (values 1 2 3 4)) "1 4") (test (string=? (format #f "~B" 123) "1111011") #t) (test (string=? (format #f "~B" 123/25) "1111011/11001") #t) (test (string=? (format #f "~B" 123.25) "1111011.01") #t) (test (string=? (format #f "~B" 123+i) "1111011.0+1.0i") #t) (test (string=? (format #f "~D" 123) "123") #t) (test (string=? (format #f "~D" 123/25) "123/25") #t) (test (string=? (format #f "~O" 123) "173") #t) (test (string=? (format #f "~O" 123/25) "173/31") #t) (test (string=? (format #f "~O" 123.25) "173.2") #t) (test (string=? (format #f "~O" 123+i) "173.0+1.0i") #t) (test (string=? (format #f "~X" 123) "7b") #t) (test (string=? (format #f "~X" 123/25) "7b/19") #t) (test (string=? (format #f "~X" 123.25) "7b.4") #t) (test (string=? (format #f "~X" 123+i) "7b.0+1.0i") #t) (test (string=? (format #f "~A" "hi") (format #f "~S" "hi")) #f) (test (string=? (format #f "~A" #\a) (format #f "~S" #\a)) #f) (for-each (lambda (arg) (test (string=? (format #f "~A" arg) (format #f "~S" arg)) #t)) (list 1 1.0 #(1 2 3) '(1 2 3) '(1 . 2) () #f #t abs # # 'hi '\a)) (test (length (format #f "~S" (string #\\))) 4) ; "\"\\\\\"" (test (length (format #f "~S" (string #\a))) 3) ; "\"a\"" (test (length (format #f "~S" (string #\null))) 6) ; "\"\\x00\"" (test (length (format #f "~S" (string (integer->char #xf0)))) 3) ; "\"ð\"" (test (length (format #f "~S" (string #\"))) 4) ; "\"" (test (format #f "~F" 3.0) "3.000000") (test (format #f "~G" 3.0) "3.0") (test (format #f "~E" 3.0) (if (not with-windows) "3.000000e+00" "3.000000e+000")) (test (format #f "~F" 3.14159) "3.141590") (test (format #f "~G" 3.14159) "3.14159") (test (format #f "~E" 3.14159) (if (not with-windows) "3.141590e+00" "3.141590e+000")) (test (format #f "~,2F" 3.14159) "3.14") (test (format #f "~,2G" 3.14159) "3.1") (test (format #f "~,2E" 3.14159) (if (not with-windows) "3.14e+00" "3.14e+000")) (test (format #f "~12F" 3.14159) " 3.141590") (test (format #f "~12G" 3.14159) " 3.14159") (test (format #f "~12E" 3.14159) (if (not with-windows) "3.141590e+00" "3.141590e+000")) (test (format #f "~12,3F" 3.14159) " 3.142") (test (format #f "~n,nF" 12 3 3.14159) " 3.142") (test (format #f "~12,nF" 3 3.14159) " 3.142") (test (format #f "~12,3G" 3.14159) " 3.14") (test (format #f "~12,3E" 3.14159) (if (not with-windows) " 3.142e+00" " 3.142e+000")) (test (format #f "~12,'xD" 1) "xxxxxxxxxxx1") (test (format #f "~12,'xF" 3.14159) "xxxx3.141590") (test (format #f "~12,'xG" 3.14159) "xxxxx3.14159") (test (format #f "~12,'xE" 3.14159) (if (not with-windows) "3.141590e+00" "3.141590e+000")) (test (format #f "~12,'\\F" 3.14159) "\\\\\\\\3.141590") (test (format #f "~20,20G" 3.0) " 3.0") (test (format #f "~20,20F" 3.0) "3.00000000000000000000") (test (format #f "~20,20E" 3.0) (if (not with-windows) "3.00000000000000000000e+00" "3.00000000000000000000e+000")) (test (format #f "~,3B" 0.99999) "0.111") (test (format #f "~,3O" 0.99999) "0.777") (test (format #f "~,3F" 0.99999) "1.000") (test (format #f "~,3X" 0.99999) "0.fff") (test (format #f "~-2F" 0.0) 'error) (test (format #f "~,-2F" 0.0) 'error) (test (format #f "~2/3F" 0.0) 'error) (test (format #f "~2.3F" 0.0) 'error) (test (format #f "~2,1,3,4F" 0.0) 'error) (test (format #f "~'xF" 0.0) 'error) (test (format #f "~3,3" pi) 'error) (test (format #f "~3," pi) 'error) (test (format #f "~3" pi) 'error) (test (format #f "~," pi) 'error) (test (format #f "~'," pi) 'error) (test (format #f "~'" pi) 'error) (test (format #f "~*" 1.0) "") (test (format #f "~D" 1.0) (if (not with-windows) "1.000000e+00" "1.000000e+000")) (test (format #f "~O" 1.0) "1.0") (test (format #f "~P" 1.0) "") (test (format #f "~P" '(1 2 3)) 'error) (test (format #f "~\x00T") 'error) (test (format #f "~9,'(T") "((((((((") (test (format #f "~0F" 1+1i) "1.000000+1.000000i") (test (format #f "~9F" 1) " 1") (test (format #f "~,0F" 3.14) "3.0") (test (format #f "~,0F" 1+1i) "1+1i") (test (format #f "~,0X" 1+1i) "1.0+1.0i") (test (format #f "~,9g" 1+1i) "1+1i") (test (format #f "~,1e" 3.14) (if (not with-windows) "3.1e+00" "3.1e+000")) (test (format #f "~9,0F" 3.14) " 3.0") (test (format #f "~9,1F" 3.14) " 3.1") (test (format #f "~9,2F" 3.14) " 3.14") (test (format #f "~9,3F" 3.14) " 3.140") (test (format #f "~9,4F" 3.14) " 3.1400") (test (format #f "~n,4F" 9 3.14) " 3.1400") (test (format #f "~9,nF" 4 3.14) " 3.1400") (test (format #f "~n,nF" 9 4 3.14) " 3.1400") (test (format #f "~9,5F" 3.14) " 3.14000") (test (format #f "~9,6F" 3.14) " 3.140000") (test (format #f "~9,7F" 3.14) "3.1400000") (test (format #f "~9,8F" 3.14) "3.14000000") (test (format #f "~9,9F" 3.14) "3.140000000") (test (format #f "~9,9G" 1+1i) " 1+1i") (if (not with-windows) (begin (test (format #f "~9,0e" 1+1i) "1e+00+1e+00i") (test (format #f "~9,1e" 1+1i) "1.0e+00+1.0e+00i") (test (format #f "~9,2e" 1+1i) "1.00e+00+1.00e+00i") (test (format #f "~9,3e" 1+1i) "1.000e+00+1.000e+00i") (test (format #f "~9,4e" 1+1i) "1.0000e+00+1.0000e+00i") (test (format #f "~9,5e" 1+1i) "1.00000e+00+1.00000e+00i") (test (format #f "~9,6e" 1+1i) "1.000000e+00+1.000000e+00i") (test (format #f "~9,7e" 1+1i) "1.0000000e+00+1.0000000e+00i") (test (format #f "~9,8e" 1+1i) "1.00000000e+00+1.00000000e+00i") (test (format #f "~9,9e" 1+1i) "1.000000000e+00+1.000000000e+00i")) (begin (test (format #f "~9,0e" 1+1i) "1e+000+1e+000i") (test (format #f "~9,1e" 1+1i) "1.0e+000+1.0e+000i") (test (format #f "~9,2e" 1+1i) "1.00e+000+1.00e+000i") (test (format #f "~9,3e" 1+1i) "1.000e+000+1.000e+000i") (test (format #f "~9,4e" 1+1i) "1.0000e+000+1.0000e+000i") (test (format #f "~9,5e" 1+1i) "1.00000e+000+1.00000e+000i") (test (format #f "~9,6e" 1+1i) "1.000000e+000+1.000000e+000i") (test (format #f "~9,7e" 1+1i) "1.0000000e+000+1.0000000e+000i") (test (format #f "~9,8e" 1+1i) "1.00000000e+000+1.00000000e+000i") (test (format #f "~9,9e" 1+1i) "1.000000000e+000+1.000000000e+000i"))) (test (format #f "~9,0x" 3.14) " 3.0") (test (format #f "~9,1x" 3.14) " 3.2") (test (format #f "~9,2x" 3.14) " 3.23") (test (format #f "~9,3x" 3.14) " 3.23d") (test (format #f "~9,4x" 3.14) " 3.23d7") (test (format #f "~9,5x" 3.14) " 3.23d7") (test (format #f "~9,6x" 3.14) " 3.23d70a") (test (format #f "~9,7x" 3.14) "3.23d70a3") (test (format #f "~9,8x" 3.14) "3.23d70a3d") (test (format #f "~9,9x" 3.14) "3.23d70a3d7") (test (format #f "~9,0b" 3.14) " 11.0") (test (format #f "~9,1b" 3.14) " 11.0") (test (format #f "~9,2b" 3.14) " 11.0") (test (format #f "~9,3b" 3.14) " 11.001") (test (format #f "~9,4b" 3.14) " 11.001") (test (format #f "~9,5b" 3.14) " 11.001") (test (format #f "~9,6b" 3.14) " 11.001") (test (format #f "~9,7b" 3.14) "11.0010001") (test (format #f "~9,8b" 3.14) "11.00100011") (test (format #f "~9,9b" 3.14) "11.001000111") (test (format #f "~0,'xf" 1) "1") (test (format #f "~1,'xf" 1) "1") (test (format #f "~2,'xf" 1) "x1") (test (format #f "~3,'xf" 1) "xx1") (test (format #f "~4,'xf" 1) "xxx1") (test (format #f "~5,'xf" 1) "xxxx1") (test (format #f "~6,'xf" 1) "xxxxx1") (test (format #f "~7,'xf" 1) "xxxxxx1") (test (format #f "~8,'xf" 1) "xxxxxxx1") (test (format #f "~9,'xf" 1) "xxxxxxxx1") (test (format #f "~11,'xf" 3.14) "xxx3.140000") (test (format #f "~12,'xf" 3.14) "xxxx3.140000") (test (format #f "~13,'xf" 3.14) "xxxxx3.140000") (test (format #f "~14,'xf" 3.14) "xxxxxx3.140000") (test (format #f "~15,'xf" 3.14) "xxxxxxx3.140000") (test (format #f "~16,'xf" 3.14) "xxxxxxxx3.140000") (test (format #f "~17,'xf" 3.14) "xxxxxxxxx3.140000") (test (format #f "~18,'xf" 3.14) "xxxxxxxxxx3.140000") (test (format #f "~19,'xf" 3.14) "xxxxxxxxxxx3.140000") (test (format #f "~,f" 1.0) "1.000000") (test (format #f "~,,f" 1.0) 'error) (test (format #f "~p" '(1 2 3)) 'error) ; these are not errors in CL (test (format #f "~p" #(())) 'error) (test (format #f "~p" 'hi) 'error) (test (format #f "~p" abs) 'error) (test (format #f "~p" 1+i) 'error) (test (format #f "~@p" '(1 2 3)) 'error) (test (format #f "~@p" #(())) 'error) (test (format #f "~@p" 'hi) 'error) (test (format #f "~@p" abs) 'error) (let ((old-vp (*s7* 'print-length))) (set! (*s7* 'print-length) 3) (test (format #f "~{~A~| ~}" '(1 2 3 4 5 6)) "1 2 3 ...") (test (format #f "~{~A~| ~}" #(1 2 3 4 5 6)) "1 2 3 ...") (test (format #f "~{~A~| ~}" #(1 2)) "1 2") (test (format #f "~{~A~| ~}" #(1 2 3)) "1 2 3") (test (format #f "~{~A~| ~}" #(1 2 3 4)) "1 2 3 ...") (test (format #f "~{~A~| ~}" (inlet 'a 1 'b 2 'c 3 'd 4 'e 5)) "(a . 1) (b . 2) (c . 3) ...") (test (format #f "~{~{~A~| ~}~}" '((1 2 3 4 5 6))) "1 2 3 ...") (test (format #f "~{~{~A~| ~}~|~}" '((1 2) (3 4 5 6 7 8) (15) (16) ())) "1 23 4 5 ...15 ...") (test (format #f "~{~|~|~|~A ~}" '(1 2 3 4 5)) "1 2 3 ...") (test (format #f "~{~C~| ~}" "1234567") "1 2 3 ...") (test (format #f "~{~{~A~|~} ~}" '((1 2) (3 4))) "12 34 ") (test (format #f "~C ~^" #\a) "a ") (test (format #f "~{~{~{~A~| ~}~| ~}~}" '(((1 2) (3 4)))) "1 2 3 4") (test (format #f "~{~{~{~A~| ~}~| ~}~}" '((#(1 2) #(3 4)))) "1 2 3 4") (test (format #f "~{~{~{~A~| ~}~| ~}~}" #(((1 2) (3 4)))) "1 2 3 4") (test (format #f "~{~{~{~A~| ~}~| ~}~}" #(#((1 2) (3 4)))) "1 2 3 4") (test (format #f "~{~{~C~| ~}~| ~}" (list "hiho" "xxx")) "h i h ... x x x") (set! (*s7* 'print-length) old-vp)) (test (format #f "~{~{~A~^~} ~}" '((hi 1))) "hi1 ") (test (format #f "~{~{~A~^~} ~}" '((1 2) (3 4))) "12 34 ") (test (format #f "~{~{~A~} ~}" '((1 2) (3 4))) "12 34 ") (test (format #f "~{~{~A~} ~}" '(())) " ") (test (format #f "~{~{~A~} ~}" '((()))) "() ") (test (format #f "~{~{~F~} ~}" '(())) " ") (test (format #f "~{~{~C~} ~}" '(())) " ") (test (format #f "~{~C ~}" ()) "") (test (format #f "~C ~^" #\a) "a ") ; CL ignores pointless ~^ (test (format #f "~^~A" #f) "#f") (test (format #f "~^~^~A" #f) "#f") (test (format #f "~*~*~A~*" 1 2 3 4) "3") (test (format #f "~{~*~A~}" '(1 2 3 4)) "24") (test (let ((lst (list 1 2 3))) (set! (cdr (cddr lst)) lst) (format #f "~A" lst)) "#1=(1 2 3 . #1#)") (test (let ((lst (list 1 2 3))) (set! (cdr (cddr lst)) lst) (format #f "~{~A~}" lst)) 'error) (test (format #f "~{~A~}" (cons 1 2)) 'error) (test (format #f "~{~A~}" '(1 2 3 . 4)) 'error) (test (format #f "~20,vF" 3.14) 'error) (test (format #f "~{~C~^ ~}" "hiho") "h i h o") (test (format #f "~{~{~C~^ ~}~}" (list "hiho")) "h i h o") (test (format #f "~{~A ~}" #(1 2 3 4)) "1 2 3 4 ") (test (let ((v (vector 1))) (set! (v 0) v) (format #f "~A" v)) "#1=#(#1#)") (test (let ((v (vector 1))) (set! (v 0) v) (format #f "~{~A~}" v)) "#1=#(#1#)") (test (format #f "~{~{~{~A~^ ~}~^ ~}~}" '(((1 2) (3 4)))) "1 2 3 4") (test (format #f "~{~{~{~A~^ ~}~^ ~}~}" '((#(1 2) #(3 4)))) "1 2 3 4") (test (format #f "~{~{~{~A~^ ~}~^ ~}~}" #(((1 2) (3 4)))) "1 2 3 4") (test (format #f "~{~{~{~A~^ ~}~^ ~}~}" #(#((1 2) (3 4)))) "1 2 3 4") (test (format #f "~{~{~{~A~^ ~}~^ ~}~}" #(#(#(1 2) (3 4)))) "1 2 3 4") (test (format #f "~{~{~{~A~^ ~}~^ ~}~}" #(#(#(1 2) #(3 4)))) "1 2 3 4") (test (format #f "~{~{~C~^ ~}~^ ~}" (list "hiho" "xxx")) "h i h o x x x") (test (format #f "~{~{~A~}~}" '((1 . 2) (3 . 4))) 'error) (test (format #f "~{~A~^ ~}" '((1 . 2) (3 . 4))) "(1 . 2) (3 . 4)") (test (format #f "~{~A ~}" (hash-table)) "") (test (format #f "~{~^~S ~}" (make-iterator '(1 2 3))) "1 2 3 ") (test (format #f "~{~^~S ~}" (make-iterator (let ((lst (list 1))) (set-cdr! lst lst)))) "1 ") (test (format #f "~{~^~S ~}" (make-iterator "")) "") (test (format #f "~{~^~S ~}" (make-iterator #(1 2 3))) "1 2 3 ") (test (format #f "~10,'-T") "---------") (test (format #f "~10,'\\T") "\\\\\\\\\\\\\\\\\\") (test (format #f "~10,'\"T") "\"\"\"\"\"\"\"\"\"") (test (format #f "~10,'-T12345~20,'-T") "---------12345-----") (test (format #f "~10,')T") ")))))))))") (test (format #f "~,0F" 1.4) "1.0") (test (format #f "~,0F" 1.5) "2.0") (test (format #f "~,0F" 1.6) "2.0") (test (format #f "~,0F" 0.4) "0.0") (test (format #f "~,0F" 0.5) (if (not with-windows) "0.0" "1.0")) ; !! (test (format #f "~,0F" 0.6) "1.0") (test (format #f "~,-0F" 1.4) 'error) (test (format #f "~, 0F" 1.4) 'error) (test (format #f "~*1~*" 1) 'error) (test (format #f "~*1~A" 1) 'error) (let* ((str1 #t) (str2 (with-output-to-string (lambda () (set! str1 (format () "~D" 1)))))) (test (and (not str1) (equal? str2 "1")) #t)) (test (format #f "~,'") 'error) (if with-bignums (begin (test (format #f "~F" 1e300) "9.999999999999999999999999999999999999987E299") (test (format #f "~F" 1e308) "9.999999999999999999999999999999999999982E307") (test (format #f "~G" 1e308) "9.999999999999999999999999999999999999982E307") (test (format #f "~E" 1e308) "9.999999999999999999999999999999999999982E307") (test (format #f "~E" 1e308+1e308i) "9.999999999999999999999999999999999999982E307+9.999999999999999999999999999999999999982E307i") (test (format #f "~F" 1e308+1e308i) "9.999999999999999999999999999999999999982E307+9.999999999999999999999999999999999999982E307i") (test (format #f "~F" -1e308-1e308i) "-9.999999999999999999999999999999999999982E307-9.999999999999999999999999999999999999982E307i") (test (format #f "~,32f" (/ 1.0 most-positive-fixnum)) "1.084202172485504434125002235952170462235E-19") (test (format #f "~{~^~f ~}" (vector 1e308)) "9.999999999999999999999999999999999999982E307 ") (test (object->string (vector 1e308)) "#(9.999999999999999999999999999999999999982E307)")) (begin (test (format #f "~F" 1e300) "1000000000000000052504760255204420248704468581108159154915854115511802457988908195786371375080447864043704443832883878176942523235360430575644792184786706982848387200926575803737830233794788090059368953234970799945081119038967640880074652742780142494579258788820056842838115669472196386865459400540160.000000") (test (format #f "~F" 1e308) "100000000000000001097906362944045541740492309677311846336810682903157585404911491537163328978494688899061249669721172515611590283743140088328307009198146046031271664502933027185697489699588559043338384466165001178426897626212945177628091195786707458122783970171784415105291802893207873272974885715430223118336.000000") (test (format #f "~G" 1e308) "1e+308") (test (format #f "~E" 1e308) "1.000000e+308") (test (format #f "~E" 1e308+1e308i) "1.000000e+308+1.000000e+308i") (test (format #f "~F" 1e308+1e308i) "100000000000000001097906362944045541740492309677311846336810682903157585404911491537163328978494688899061249669721172515611590283743140088328307009198146046031271664502933027185697489699588559043338384466165001178426897626212945177628091195786707458122783970171784415105291802893207873272974885715430223118336.000000+100000000000000001097906362944045541740492309677311846336810682903157585404911491537163328978494688899061249669721172515611590283743140088328307009198146046031271664502933027185697489699588559043338384466165001178426897626212945177628091195786707458122783970171784415105291802893207873272974885715430223118336.000000i") (test (format #f "~F" -1e308-1e308i) "-100000000000000001097906362944045541740492309677311846336810682903157585404911491537163328978494688899061249669721172515611590283743140088328307009198146046031271664502933027185697489699588559043338384466165001178426897626212945177628091195786707458122783970171784415105291802893207873272974885715430223118336.000000-100000000000000001097906362944045541740492309677311846336810682903157585404911491537163328978494688899061249669721172515611590283743140088328307009198146046031271664502933027185697489699588559043338384466165001178426897626212945177628091195786707458122783970171784415105291802893207873272974885715430223118336.000000i") (test (format #f "~,32f" (/ 1.0 most-positive-fixnum)) "0.00000000000000000010842021724855") (test (format #f "~{~^~f ~}" (vector 1e308)) "100000000000000001097906362944045541740492309677311846336810682903157585404911491537163328978494688899061249669721172515611590283743140088328307009198146046031271664502933027185697489699588559043338384466165001178426897626212945177628091195786707458122783970171784415105291802893207873272974885715430223118336.000000 ") (test (object->string (vector 1e308)) "#(1e+308)"))) (when full-test (let () (define ctrl-chars (vector ;#\A #\S #\C #\F #\E #\G #\O #\D #\B #\X #\W #\, #\{ #\} #\@ #\P #\* #\< #\> #\a #\s #\c #\f #\e #\g #\o #\d #\b #\x #\p #\n #\w #\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9 #\~ #\T #\& #\% #\^ #\| #\~ #\~ #\~ #\~ #\, #\, #\, #\, #\" #\" #\\ #\' #\+ #\- #\@ #\. #\/ #\; #\: )) (define ctrl-chars-len (length ctrl-chars)) (define (test-chars) (do ((size 1 (+ size 1))) ((= size 7)) (let ((tries (* size size 10000))) (format *stderr* "~D " size) (let ((ctrl-str (make-string (+ size 1))) (x 12) (y '(1 2)) (z #\a)) (string-set! ctrl-str 0 #\~) (do ((i 0 (+ i 1))) ((= i tries)) (do ((j 1 (+ j 1))) ((> j size)) (string-set! ctrl-str j (vector-ref ctrl-chars (random ctrl-chars-len)))) ;(format *stderr* "~S " ctrl-str) ;(catch #t (lambda () (format *stderr* "~S: ~A~%" ctrl-str (format #f ctrl-str))) (lambda arg 'error)) ;(catch #t (lambda () (format *stderr* "~S ~A: ~A~%" ctrl-str x (format #f ctrl-str x))) (lambda arg 'error)) ;(catch #t (lambda () (format *stderr* "~S ~A: ~A~%" ctrl-str y (format #f ctrl-str y))) (lambda arg 'error)) ;(catch #t (lambda () (format *stderr* "~S ~A: ~A~%" ctrl-str z (format #f ctrl-str z))) (lambda arg 'error))))) (catch #t (lambda () (format #f ctrl-str)) (lambda arg 'error)) (catch #t (lambda () (format #f ctrl-str x)) (lambda arg 'error)) (catch #t (lambda () (format #f ctrl-str y)) (lambda arg 'error)) (catch #t (lambda () (format #f ctrl-str z)) (lambda arg 'error)) (catch #t (lambda () (format #f ctrl-str x x)) (lambda arg 'error)) (catch #t (lambda () (format #f ctrl-str x y)) (lambda arg 'error)) (catch #t (lambda () (format #f ctrl-str y z)) (lambda arg 'error)) (catch #t (lambda () (format #f ctrl-str x y z)) (lambda arg 'error))))) )) (test-chars))) (test (reverse (format #f "~{~A~}" '((1 2) (3 4)))) ")4 3()2 1(") (test (string->symbol (format #f "~A" '(1 2))) (symbol "(1 2)")) (test (string->number (format #f "~A" -1)) -1) (test (string->number (format #f "~S" -1)) -1) (test (string->number (format #f "~F" -1)) -1) (test (string->number (format #f "~D" -1)) -1) (test (string->number (format #f "~G" -1)) -1) (test (string->number (format #f "~E" -1)) -1) (test (string->number (format #f "~B" -1)) -1) (test (string->number (format #f "~X" -1)) -1) (test (string->number (format #f "~O" -1)) -1) (num-test (string->number (format #f "~A" 1.5)) 1.5) (num-test (string->number (format #f "~S" 1.5)) 1.5) (num-test (string->number (format #f "~F" 1.5)) 1.5) (num-test (string->number (format #f "~D" 1.5)) 1.5) (num-test (string->number (format #f "~G" 1.5)) 1.5) (num-test (string->number (format #f "~E" 1.5)) 1.5) (num-test (string->number (format #f "~B" 1.5)) 1.1) (num-test (string->number (format #f "~X" 1.5)) 1.8) (num-test (string->number (format #f "~O" 1.5)) 1.4) (num-test (string->number (format #f "~A" 1+1i)) 1+1i) (num-test (string->number (format #f "~S" 1+1i)) 1+1i) (num-test (string->number (format #f "~F" 1+1i)) 1+1i) (num-test (string->number (format #f "~D" 1+1i)) 1+1i) (num-test (string->number (format #f "~G" 1+1i)) 1+1i) (num-test (string->number (format #f "~E" 1+1i)) 1+1i) (num-test (string->number (format #f "~B" 1+1i)) 1+1i) (num-test (string->number (format #f "~X" 1+1i)) 1+1i) (num-test (string->number (format #f "~O" 1+1i)) 1+1i) (test (string->number (format #f "~A" 3/4)) 3/4) (test (string->number (format #f "~S" 3/4)) 3/4) (test (string->number (format #f "~F" 3/4)) 3/4) (test (string->number (format #f "~D" 3/4)) 3/4) (test (string->number (format #f "~G" 3/4)) 3/4) (test (string->number (format #f "~E" 3/4)) 3/4) (test (string->number (format #f "~B" 3/4)) 11/100) (test (string->number (format #f "~X" 3/4)) 3/4) (test (string->number (format #f "~O" 3/4)) 3/4) (num-test (string->number (format #f "~A" 0+1i)) 0+1i) (num-test (string->number (format #f "~S" 0+1i)) 0+1i) (num-test (string->number (format #f "~F" 0+1i)) 0+1i) (num-test (string->number (format #f "~D" 0+1i)) 0+1i) (num-test (string->number (format #f "~G" 0+1i)) 0+1i) (num-test (string->number (format #f "~E" 0+1i)) 0+1i) (num-test (string->number (format #f "~B" 0+1i)) 0+1i) (num-test (string->number (format #f "~X" 0+1i)) 0+1i) (num-test (string->number (format #f "~O" 0+1i)) 0+1i) (test (format "~G" 1e10) (if (not with-windows) "1e+10" "1e+010")) (test (format "~F" 1e10) "10000000000.000000") (test (format "~E" 1e10) (if (not with-windows) "1.000000e+10" "1.000000e+010")) (test (format "~A" 1e10) "10000000000.0") (test (format "~D" 1e10) (if (not with-windows) "1.000000e+10" "1.000000e+010")) (test (format #f "~P{T}'" 1) "{T}'") (test (format #f "~") 'error) (test (format #f "~B&B~X" 1.5 1.5) "1.1&B1.8") (test (format #f ",~~~A~*1" 1 1) ",~11") (test (format #f "~D~20B" 0 0) "0 0") (test (format #f "~D~20B" 1 1) "1 1") (test (format #f "~10B" 1) " 1") (test (format #f "~10B" 0) " 0") (test (format #f "~100B" 1) " 1") (test (length (format #f "~1000B" 1)) 1000) (test (format #f "~D~20D" 3/4 3/4) "3/4 3/4") (test (length (format #f "~20D" 3/4)) 20) (test (format #f "~20B" 3/4) " 11/100") (test (length (format #f "~20B" 3/4)) 20) (test (format #f "~D~20B" 3/4 3/4) "3/4 11/100") (test (format #f "~X~20X" 21/33 21/33) "7/b 7/b") (test (format #f "~D~20,'.B" 3/4 3/4) "3/4..............11/100") (test (format #f "~20g" 1+i) " 1+1i") (test (length (format #f "~20g" 1+i)) 20) (test (format #f "~20f" 1+i) " 1.000000+1.000000i") (test (length (format #f "~20f" 1+i)) 20) (test (format #f "~20x" 17+23i) " 11.0+17.0i") (test (length (format #f "~20x" 17+23i)) 20) (test (format #f "~{~{~A~^~} ~}" (hash-table '((a . 1) (b . 2)))) "(a . 1)(b . 2) ") (test (format #f "~{~{~A~^~}~^~}" (hash-table '((a . 1) (b . 2)))) "(a . 1)(b . 2)") (test (format #f "~{~{~A~^ ~}~^~}" (hash-table '((a . 1) (b . 2)))) "(a . 1) (b . 2)") (test (format #f "~{~{~{~A~^~} ~}~}" #(())) "") (test (format #f "~{~{~{~P~^~} ~}~}" '((()))) " ") (test (format #f "~{~{~{~P~^~}~}~}" '(((2 3 4)))) "sss") (test (apply format #f "~T~~{~{~{~*~~0~1~*~}~@~}" '(())) "~{") (test (format #f "~{~S}%~}" '(a b c)) "a}%b}%c}%") (test (format #f "~&~^%~F." 0) "%0.") (test (format #f "1~^2") "1") (test (apply format #f "~P~d~B~~" '(1 2 3)) "211~") (test (format #f "~T1~~^~P" 0) "1~^s") (test (format #f "~S~^~{~^" '(+ x 1)) "(+ x 1)") (test (format #f "1~^~{2") "1") (test (format #f "~A~{~0~g~@~B~}" () ()) "()") (test (format #f "1~^~^~^2") "1") (test (format #f "~{~{~~}~~,~}~*" '(()) '(())) "~,") (test (format #f "~~S~S~T~~C~g~~" 0 0) "~S0~C0~") (test (format #f "~{~~e~}~~{~*~~" "" "") "~{~") (let () (define* (clean-string e (precision 3)) (format #f (format #f "(~~{~~,~DF~~^ ~~})" precision) e)) (test (clean-string '(1.123123 -2.31231323 3.141592653589 4/3) 1) "(1.1 -2.3 3.1 4/3)") (test (clean-string '(1.123123 -2.31231323 3.141592653589 4/3)) "(1.123 -2.312 3.142 4/3)") (test (clean-string '(1.123123 -2.31231323 3.141592653589 4/3) 6) "(1.123123 -2.312313 3.141593 4/3)")) (if with-bignums (begin (test (format #f "~P" (bignum "1")) "") (test (format #f "~P" (bignum "1.0")) "") (test (format #f "~P" (bignum "2")) "s") (test (format #f "~P" (bignum "2.0")) "s") (test (format #f "~10,' D" (bignum "1")) " 1") (test (format #f "~10,' D" (bignum "3/4")) " 3/4") (test (format #f "~10,'.D" (bignum "3/4")) ".......3/4") (test (format #f "~10D" (bignum "3/4")) " 3/4") (test (length (format #f "~100D" (bignum "34"))) 100) (test (format #f "~50F" (bignum "12345678.7654321")) " 1.23456787654321E7") )) (call-with-output-file tmp-output-file (lambda (p) (format p "this ~A ~C test ~D" "is" #\a 3))) (let ((res (call-with-input-file tmp-output-file (lambda (p) (read-line p))))) (if (not (string=? res "this is a test 3")) (begin (display "call-with-input-file + format to \"tmp1.r5rs\" ... expected \"this is a test 3\", but got \"") (display res) (display "\"?") (newline)))) (let ((val (format #f "line 1~%line 2~%line 3"))) (with-input-from-string val (lambda () (let ((line1 (read-line))) (test (string=? line1 "line 1") #t)) (let ((line2 (read-line))) (test (string=? line2 "line 2") #t)) (let ((line3 (read-line))) (test (string=? line3 "line 3") #t)) (let ((eof (read-line))) (test (eof-object? eof) #t)) (let ((eof (read-line))) (test (eof-object? eof) #t))))) (let ((val (format #f "line 1~%line 2~%line 3"))) (call-with-input-string val (lambda (p) (let ((line1 (read-line p #t))) (test (string=? line1 (string-append "line 1" (string #\newline))) #t)) (let ((line2 (read-line p #t))) (test (string=? line2 (string-append "line 2" (string #\newline))) #t)) (let ((line3 (read-line p #t))) (test (string=? line3 "line 3") #t)) (let ((eof (read-line p #t))) (test (eof-object? eof) #t)) (let ((eof (read-line p #t))) (test (eof-object? eof) #t))))) (let ((res #f)) (let ((this-file (open-output-string))) (format this-file "this ~A ~C test ~D" "is" #\a 3) (set! res (get-output-string this-file)) (close-output-port this-file)) (if (not (string=? res "this is a test 3")) (begin (display "open-output-string + format ... expected \"this is a test 3\", but got \"") (display res) (display "\"?") (newline)))) (test (with-output-to-string (lambda () (display 123) (flush-output-port))) "123") (test (with-output-to-string (lambda () (display 123) (flush-output-port) (display 124))) "123124") (test (call-with-output-string (lambda (p) (write 1 p) (display 2 p) (format p "~D" 3) (write-byte (char->integer #\4) p) (write-char #\5 p) (write-string "6" p) (write 1 #f) (display 2 #f) (format #f "~D" 3) (write-byte (char->integer #\4) #f) (write-char #\5 #f) (write-string "6" #f))) "123456") (test (write-byte most-positive-fixnum #f) 'error) (test (write-byte -1 #f) 'error) (test (write-byte 256 #f) 'error) (let ((res #f)) (let ((this-file (open-output-string))) (format this-file "this is a test") (set! res (get-output-string this-file)) (if (not (string=? res "this is a test")) (format-logged #t "open-output-string + format expected \"this is a test\", but got ~S~%" res)) (flush-output-port this-file) (set! res (get-output-string this-file)) (if (not (string=? res "this is a test")) (format-logged #t "flush-output-port of string port expected \"this is a test\", but got ~S~%" res)) (format this-file "this is a test") (set! res (get-output-string this-file)) (if (not (string=? res "this is a testthis is a test")) (format-logged #t "open-output-string after flush expected \"this is a testthis is a test\", but got ~S~%" res)) (close-output-port this-file) (test (flush-output-port this-file) this-file))) (test (flush-output-port "hiho") 'error) (test (flush-output-port *stdin*) 'error) (call-with-output-file tmp-output-file (lambda (p) (format p "123456~%") (format p "67890~%") (flush-output-port p) (test (call-with-input-file tmp-output-file (lambda (p) (read-line p))) "123456") (close-output-port p))) (let ((res1 #f) (res2 #f) (res3 #f)) (let ((p1 (open-output-string))) (format p1 "~D" 0) (let ((p2 (open-output-string))) (format p2 "~D" 1) (let ((p3 (open-output-string))) (if (not (string=? (get-output-string p1) "0")) (format-logged #t ";format to nested ports, p1: ~S~%" (get-output-string p1))) (if (not (string=? (get-output-string p2) "1")) (format-logged #t ";format to nested ports, p2: ~S~%" (get-output-string p2))) (format p3 "~D" 2) (format p2 "~D" 3) (format p1 "~D" 4) (format p3 "~D" 5) (set! res3 (get-output-string p3)) (close-output-port p3) (if (not (string=? (get-output-string p1) "04")) (format-logged #t ";format to nested ports after close, p1: ~S~%" (get-output-string p1))) (if (not (string=? (get-output-string p2) "13")) (format-logged #t ";format to nested ports after close, p2: ~S~%" (get-output-string p2)))) (format (or p1 p3) "~D" 6) (format (and p1 p2) "~D" 7) (set! res1 (get-output-string p1)) (close-output-port p1) (if (not (string=? (get-output-string p2) "137")) (format-logged #t ";format to nested ports after 2nd close, p2: ~S~%" (get-output-string p2))) (format p2 "~D" 8) (set! res2 (get-output-string p2)) (test (get-output-string p1) 'error) (test (get-output-string p2 "hi") 'error) (close-output-port p2))) (if (not (string=? res1 "046")) (format-logged #t ";format to nested ports, res1: ~S~%" res1)) (if (not (string=? res2 "1378")) (format-logged #t ";format to nested ports, res2: ~S~%" res2)) (if (not (string=? res3 "25")) (format-logged #t ";format to nested ports, res3: ~S~%" res3))) (test (call/cc (lambda (return) (let ((val (format #f "line 1~%line 2~%line 3"))) (call-with-input-string val (lambda (p) (return "oops")))))) "oops") (test (get-output-string #f 64) 'error) ;(format-logged #t "format #t: ~D" 1) ;(format (current-output-port) " output-port: ~D! (this is testing output ports)~%" 2) (call-with-output-file tmp-output-file (lambda (p) (display 1 p) (write 2 p) (write-char #\3 p) (format p "~D" 4) (write-byte (char->integer #\5) p) (call-with-output-file "tmp2.r5rs" (lambda (p) (display 6 p) (write 7 p) (write-char #\8 p) (format p "~D" 9) (write-byte (char->integer #\0) p) (newline p))) (call-with-input-file "tmp2.r5rs" (lambda (pin) (display (read-line pin) p))) (newline p))) (test (call-with-input-file tmp-output-file (lambda (p) (read-line p))) "1234567890") (call-with-output-file tmp-output-file (lambda (p) (format p "12345~%") (format p "67890~%"))) (call-with-input-file tmp-output-file (lambda (p) (test (read-char p) #\1) (test (read-byte p) (char->integer #\2)) (test (peek-char p) #\3) (if (not pure-s7) (test (char-ready? p) #t)) (test (read-line p) "345") (test (read-line p) "67890"))) (call-with-output-file tmp-output-file (lambda (p) (write-string "123" p) (write-string "" p) (write-string "456\n789" p))) (call-with-input-file tmp-output-file (lambda (p) (test (read-line p) "123456") (test (read-char p) #\7) (test (read-char p) #\8) (test (read-char p) #\9) (test (eof-object? (read-char p)) #t))) (test (with-output-to-string (lambda () (write-string "123") (write-string "") (write-string "456"))) "123456") (test (with-output-to-string (lambda () (write-string "123" (current-output-port)) (write-string "" (current-output-port)) (write-string "456" (current-output-port)) (write-string "678" (current-output-port) 1) (write-string "679" (current-output-port) 2 3) (write-string "079" (current-output-port) 0 1) (write-string "123" (current-output-port) 0 3) (write-string "123" (current-output-port) 3 3) (write-string "" (current-output-port) 0 0) (write-string "1423" (current-output-port) 1 1) ; 1.3.3: end is exclusive, if start=end, empty result (write-string "1423" (current-output-port) 1 4/2) (write-string "5423" (current-output-port) -0 1))) "123456789012345") (test (write-string "12345" -1) 'error) (test (write-string "12345" 0 -1) 'error) (test (write-string "12345" 0 18) 'error) (test (write-string "12345" 18) 'error) (test (write-string "12345" 2 1) 'error) (test (write-string "12345" 5 5) 'error) (test (write-string "12345" 0.0 2) 'error) (test (write-string "12345" 0 2.0) 'error) (test (write-string "12345" 0 1+i) 'error) (test (write-string "12345" 0 2/3) 'error) (test (write-string "12345" 0 #\a) 'error) (test (write-string "12345" #\null) 'error) (test (write-string "12345" most-negative-fixnum) 'error) (test (write-string "12345" 0 most-positive-fixnum) 'error) (test (write-string "12345" 0 4294967296) 'error) (test (write-string "a" #f 1) "") (test (write-string "abc" #f 3) "") (test (write-string "ab" #f 1) "b") (test (write-string "ab" #f 2) "") (test (write-string "abc" #f 1 2) "b") (test (write-string "abc" #f 1 3) "bc") (test (with-input-from-string "12345" (lambda () (read-string 3))) "123") (test (with-input-from-string "" (lambda () (read-string 3))) #) (test (with-input-from-string "" (lambda () (read-string 0))) "") (test (with-input-from-string "1" (lambda () (read-string 0))) "") (test (with-input-from-string "1" (lambda () (read-string -1))) 'error) (test (with-input-from-string "1" (lambda () (read-string #f))) 'error) (test (with-input-from-string "123" (lambda () (read-string 10))) "123") (test (call-with-input-string "123" (lambda (p) (read-string 2 p))) "12") (test (call-with-input-string "123" (lambda (p) (read-string 2 #f))) 'error) (test (call-with-input-string "123" (lambda (p) (read-string 2 (current-output-port)))) 'error) (test (call-with-input-string "123" (lambda (p) (read-string 0 #))) 'error) (test (call-with-input-string "123" (lambda (p) (read-string 0 123))) 'error) (test (read-string most-positive-fixnum) 'error) (test (read-string -1) 'error) (test (read-string most-negative-fixnum) 'error) ;(test (read-string 0) "") ; (test (read-string 123) "") ; s7 considers this file (during load) to be the current-input-file, so the above read-string ruins the load ; the other choice is to hang (waiting for stdin) ; perhaps this choice should be documented since it is specifically contrary to r7rs (test (write 1 (current-input-port)) 'error) (test (write-char #\a (current-input-port)) 'error) (test (write-byte 0 (current-input-port)) 'error) (test (read (current-output-port)) 'error) (test (read-char (current-output-port)) 'error) (test (read-byte (current-output-port)) 'error) (test (read-line (current-output-port)) 'error) (test (display 3) 3) (test (display 3 #f) 3) (when (not pure-s7) (let ((op1 (set-current-output-port (open-output-file tmp-output-file)))) (display 1) (write 2) (write-char #\3) (format-logged #t "~D" 4) ; #t -> output port (write-byte (char->integer #\5)) (let ((op2 (set-current-output-port (open-output-file "tmp2.r5rs")))) (display 6) (write 7) (write-char #\8) (format-logged #t "~D" 9) (write-byte (char->integer #\0)) (newline) (close-output-port (current-output-port)) (set-current-output-port op2) (let ((ip1 (set-current-input-port (open-input-file "tmp2.r5rs")))) (display (read-line)) (close-input-port (current-input-port)) (set-current-input-port ip1)) (newline) (close-output-port (current-output-port))) (set-current-output-port #f) (test (string? (format #t "~%")) #t) (write "write: should not appear" #f) (newline #f) (display "display: should not appear" #f) (newline #f) (format #f "format: should not appear") (newline #f) (write-string "write-string: should not appear" #f) (newline #f) (write-char #\! #f) (write-byte 123 #f) (write "write: should not appear" (current-output-port)) (newline (current-output-port)) (display "display: should not appear" (current-output-port)) (newline (current-output-port)) (format (current-output-port) "format: should not appear") (newline (current-output-port)) (write-string "write-string: should not appear" (current-output-port)) (newline (current-output-port)) (write-char #\! (current-output-port)) (write-byte 123 (current-output-port)) (write "write: should not appear") (newline) (display "display: should not appear") (newline) (format #t "format: should not appear") (newline) (write-string "write-string: should not appear") (newline) (write-char #\!) (write-byte 123) (set-current-output-port op1)) (let ((old-op1 (current-output-port)) (op1 (open-output-file tmp-output-file))) (set! (current-output-port) op1) (display 1) (write 2) (write-char #\3) (format-logged #t "~D" 4) ; #t -> output port (write-byte (char->integer #\5)) (let ((old-op2 (current-output-port)) (op2 (open-output-file "tmp2.r5rs"))) (set! (current-output-port) op2) (display 6) (write 7) (write-char #\8) (format-logged #t "~D" 9) (write-byte (char->integer #\0)) (newline) (close-output-port (current-output-port)) (set! (current-output-port) old-op2) (let ((old-ip1 (current-input-port)) (ip1 (open-input-file "tmp2.r5rs"))) (set! (current-input-port) ip1) (display (read-line)) (close-input-port (current-input-port)) (set! (current-input-port) old-ip1)) (newline) (close-output-port (current-output-port)) (set! (current-output-port) old-op1))) (test (call-with-input-file tmp-output-file (lambda (p) (read-line p))) "1234567890")) (for-each (lambda (op) (for-each (lambda (arg) (test (op arg display) 'error)) (list 1 1.0 1+i 2/3 'a-symbol (make-vector 3) '(1 2) (cons 1 2) abs #f #t :hi (if #f #f) (lambda (a) (+ a 1))))) (list call-with-output-file call-with-input-file call-with-output-string call-with-input-string with-input-from-string with-input-from-file with-output-to-file)) (for-each (lambda (op) (for-each (lambda (arg) (test (op arg) 'error)) (list 1 1.0 1+i 2/3 'a-symbol (make-vector 3) '(1 2) (cons 1 2) abs #f #t :hi (if #f #f) (lambda (a) (+ a 1))))) (list open-output-file open-input-file open-input-string)) (for-each (lambda (op) (for-each (lambda (arg) (test (op "hi" arg) 'error)) (list "hi" 1 1.0 1+i 2/3 'a-symbol (make-vector 3) '(1 2) (cons 1 2) abs #t :hi (if #f #f) (lambda (a) (+ a 1))))) (list write display write-byte newline write-char read read-char read-byte peek-char char-ready? read-line)) (for-each (lambda (arg) (test (write-char arg) 'error) (test (write-byte arg) 'error) (test (read-char arg) 'error) (test (read-byte arg) 'error) (test (peek-char arg) 'error) (test (write-char #\a arg) 'error) (test (write-byte 1 arg) 'error)) (list "hi" 1.0 1+i 2/3 'a-symbol (make-vector 3) '(1 2) (cons 1 2) abs #t :hi (if #f #f) (lambda (a) (+ a 1)))) (test (write-byte -1) 'error) (test (write-byte most-positive-fixnum) 'error) (test (write-byte 300) 'error) (for-each (lambda (arg) (test (write-string arg) 'error) (test (write-string "hi" arg) 'error)) (list 1.0 1+i 2/3 'a-symbol (make-vector 3) '(1 2) (cons 1 2) abs #t :hi (if #f #f) (lambda (a) (+ a 1)))) (test (with-output-to-string (lambda () (newline #f))) "") (test (with-output-to-string (lambda () (write-byte 95 #f))) "") (test (with-output-to-string (lambda () (write-char #\a #f))) "") (test (with-output-to-string (lambda () (write-string "a" #f))) "") (test (with-output-to-string (lambda () (write "hiho" #f))) "") (test (with-output-to-string (lambda () (display "hiho" #f))) "") (test (with-output-to-string (lambda () (format #f "hiho"))) "") (when (not pure-s7) (test (with-output-to-string (lambda () (set! (current-output-port) #f) (newline (current-output-port)) (write-byte 95 (current-output-port)) (write-char #\a (current-output-port)) (write-string "a" (current-output-port)) (write "hiho" (current-output-port)) (display "hiho" (current-output-port)) (format (current-output-port) "hiho"))) "") (set! (current-output-port) *stdout*)) (for-each (lambda (op) (for-each (lambda (arg) (test (op arg) 'error)) (list "hi" 1 1.0 1+i 2/3 'a-symbol (make-vector 3) '(1 2) (cons 1 2) abs :hi (if #f #f) (lambda (a) (+ a 1))))) (list set-current-input-port set-current-error-port set-current-output-port close-input-port close-output-port)) (let ((hi (open-output-string))) (test (get-output-string hi) "") (close-output-port hi) (test (get-output-string hi) 'error)) (test (open-output-string "hiho") 'error) (test (with-output-to-string "hi") 'error) (test (call-with-output-string "hi") 'error) (test (get-output-string 1 2) 'error) (test (get-output-string) 'error) (for-each (lambda (arg) (test (get-output-string arg) 'error)) (list "hi" 1 1.0 1+i 2/3 'a-symbol (make-vector 3) '(1 2) (cons 1 2) abs :hi (if #f #f) (lambda (a) (+ a 1)))) (let ((p (open-output-string))) (write 123 p) (test (get-output-string p) "123") (write 124 p) (test (get-output-string p #t) "123124") (test (get-output-string p #t) "") (write 123 p) (test (get-output-string p) "123")) ;; since read of closed port will generate garbage, it needs to be an error, ;; so I guess write of closed port should also be an error (let ((hi (open-output-string))) (close-output-port hi) (for-each (lambda (op) (test-e (op hi) (object->string op) 'closed-port)) (list (lambda (p) (display 1 p)) (lambda (p) (write 1 p)) (lambda (p) (write-char #\a p)) (lambda (p) (write-byte 0 p)) (lambda (p) (format p "hiho")) (if pure-s7 newline set-current-output-port) (if pure-s7 newline set-current-input-port) set-current-error-port newline))) (let ((hi (open-input-string "hiho"))) (test (get-output-string hi) 'error) (close-input-port hi) (for-each (lambda (op) (test-e (op hi) (object->string op) 'closed-port)) (list read read-char read-byte peek-char read-line port-filename port-line-number (if pure-s7 read-line char-ready?) (if pure-s7 read-line set-current-output-port) (if pure-s7 read-line set-current-input-port) set-current-error-port ))) (test (close-output-port (open-input-string "hiho")) 'error) (test (close-input-port (open-output-string)) 'error) (test (set! (port-filename) "hiho") 'error) (test (set! (port-closed? (current-output-port)) "hiho") 'error) (test (begin (close-output-port *stderr*) (port-closed? *stderr*)) #f) (test (begin (close-output-port *stdout*) (port-closed? *stdout*)) #f) (test (begin (close-input-port *stdin*) (port-closed? *stdin*)) #f) (test (let ((str "")) (with-input-from-string "1234567890" (lambda () (with-input-from-string "1234567890" (lambda () (with-input-from-string "1234567890" (lambda () (with-input-from-string "1234567890" (lambda () (with-input-from-string "1234567890" (lambda () (with-input-from-string "1234567890" (lambda () (with-input-from-string "1234567890" (lambda () (set! str (string-append str (string (read-char)))))) (set! str (string-append str (string (read-char) (read-char)))))) (set! str (string-append str (string (read-char) (read-char) (read-char)))))) (set! str (string-append str (string (read-char) (read-char) (read-char) (read-char)))))) (set! str (string-append str (string (read-char) (read-char) (read-char) (read-char) (read-char)))))) (set! str (string-append str (string (read-char) (read-char) (read-char) (read-char) (read-char) (read-char)))))) (set! str (string-append str (string (read-char) (read-char) (read-char) (read-char) (read-char) (read-char) (read-char)))))) str) "1121231234123451234561234567") (let* ((new-error-port (open-output-string)) (old-error-port (set-current-error-port new-error-port))) (catch #t (lambda () (format #f "~R" 123)) (lambda args (format (current-error-port) "oops"))) (let ((str (get-output-string new-error-port))) (set-current-error-port old-error-port) (test str "oops"))) (let ((hi (open-input-string "hiho"))) (for-each (lambda (op) (test-e (op hi) (object->string op) 'input-port)) (list (lambda (p) (display 1 p)) (lambda (p) (write 1 p)) (lambda (p) (write-char #\a p)) (lambda (p) (write-byte 0 p)) (lambda (p) (format p "hiho")) newline)) (close-input-port hi)) (let ((hi (open-output-file tmp-output-file))) (write-byte 1 hi) (close-output-port hi) (test (write-byte 1 hi) 'error)) (let ((hi (open-output-string))) (for-each (lambda (op) (test-e (op hi) (object->string op) 'output-port)) (list read read-char read-byte peek-char char-ready? read-line)) (close-output-port hi)) (test (output-port? (current-error-port)) #t) (test (and (not (null? (current-error-port))) (input-port? (current-error-port))) #f) (call-with-output-file tmp-output-file (lambda (p) (test (get-output-string p) 'error) (do ((i 0 (+ i 1))) ((= i 256)) (write-byte i p)))) (call-with-input-file tmp-output-file (lambda (p) (test (get-output-string p) 'error) (call-with-exit (lambda (quit) (do ((i 0 (+ i 1))) ((= i 256)) (let ((b (read-byte p))) (if (or (not (number? b)) (not (= b i))) (begin (format-logged #t "read-byte got ~A, expected ~A~%" b i) (quit))))))) (let ((eof (read-byte p))) (if (not (eof-object? eof)) (format-logged #t "read-byte at end: ~A~%" eof))) (let ((eof (read-byte p))) (if (not (eof-object? eof)) (format-logged #t "read-byte at end: ~A~%" eof))))) (call-with-output-file tmp-output-file (lambda (p) (do ((i 0 (+ i 1))) ((= i 256)) (write-char (integer->char i) p)))) (define our-eof #f) (call-with-input-file tmp-output-file (lambda (p) (call-with-exit (lambda (quit) (do ((i 0 (+ i 1))) ((= i 256)) (let ((b (read-char p))) (if (or (not (char? b)) (not (char=? b (integer->char i)))) (begin (format-logged #t "read-char got ~A, expected ~A (~D: char? ~A)~%" b (integer->char i) i (char? (integer->char i))) (quit))))))) (let ((eof (read-char p))) (if (not (eof-object? eof)) (format-logged #t "read-char at end: ~A~%" eof)) (set! our-eof eof)) (let ((eof (read-char p))) (if (not (eof-object? eof)) (format-logged #t "read-char again at end: ~A~%" eof))))) (test (eof-object? (integer->char 255)) #f) (test (eof-object? our-eof) #t) (test (char->integer our-eof) 'error) (test (char? our-eof) #f) (test (eof-object? ((lambda () our-eof))) #t) (for-each (lambda (op) (test (op *stdout*) 'error) (test (op *stderr*) 'error) (test (op (current-output-port)) 'error) (test (op (current-error-port)) 'error) (test (op ()) 'error)) (list read read-line read-char read-byte peek-char char-ready?)) (for-each (lambda (op) (test (op #\a *stdin*) 'error) (test (op #\a (current-input-port)) 'error) (test (op #\a ()) 'error)) (list write display write-char)) (test (write-byte 0 *stdin*) 'error) (test (write-byte (char->integer #\space) *stdout*) (char->integer #\space)) (test (write-byte (char->integer #\space) *stderr*) (char->integer #\space)) (test (newline *stdin*) 'error) (test (format *stdin* "hiho") 'error) (test (port-filename *stdin*) "*stdin*") (test (port-filename *stdout*) "*stdout*") (test (port-filename *stderr*) "*stderr*") (test (input-port? *stdin*) #t) (test (output-port? *stdin*) #f) (test (port-closed? *stdin*) #f) (test (input-port? *stdout*) #f) (test (output-port? *stdout*) #t) (test (port-closed? *stdout*) #f) (test (input-port? *stderr*) #f) (test (output-port? *stderr*) #t) (test (port-closed? *stderr*) #f) (test (port-line-number *stdin*) 0) (test (port-line-number *stdout*) 'error) (test (port-line-number *stderr*) 'error) (test (open-input-file "[*not-a-file!*]-") 'error) (test (call-with-input-file "[*not-a-file!*]-" (lambda (p) p)) 'error) (test (with-input-from-file "[*not-a-file!*]-" (lambda () #f)) 'error) (test (open-input-file "") 'error) (test (call-with-input-file "" (lambda (p) p)) 'error) (test (with-input-from-file "" (lambda () #f)) 'error) ;(test (open-output-file "/bad-dir/badness/[*not-a-file!*]-") 'error) ;(test (call-with-output-file "/bad-dir/badness/[*not-a-file!*]-" (lambda (p) p)) 'error) ;(test (with-output-to-file "/bad-dir/badness/[*not-a-file!*]-" (lambda () #f)) 'error) (with-output-to-file "tmp.r5rs" (lambda () (write-char #\a) (with-output-to-file tmp-output-file (lambda () (format-logged #t "~C" #\b) (with-output-to-file "tmp2.r5rs" (lambda () (display #\c))) (display (with-input-from-file "tmp2.r5rs" (lambda () (read-char)))))) (with-input-from-file tmp-output-file (lambda () (write-byte (read-byte)) (write-char (read-char)))))) (with-input-from-file "tmp.r5rs" (lambda () (test (read-line) "abc"))) (with-input-from-file "tmp.r5rs" ; this assumes tmp.r5rs has "abc" as above (lambda () (test (read-char) #\a) (test (eval-string "(+ 1 2)") 3) (test (read-char) #\b) (with-input-from-string "(+ 3 4)" (lambda () (test (read) '(+ 3 4)))) (test (read-char) #\c))) (test (eval-string (object->string (with-input-from-string "(+ 1 2)" read))) 3) (test (eval (eval-string "(with-input-from-string \"(+ 1 2)\" read)")) 3) (test (eval-string "(eval (with-input-from-string \"(+ 1 2)\" read))") 3) (test (eval-string (object->string (eval-string (format #f "(+ 1 2)")))) 3) ;;; -------- test that we can plow past errors -------- (if (and (defined? 'file-exists?) ; (ifdef name ...)? (file-exists? "tests.data")) (delete-file "tests.data")) (call-with-output-file "tests.data" (lambda (p) (format p "start ") (catch #t (lambda () (format p "next ") (abs "hi") (format p "oops ")) (lambda args 'error)) (format p "done\n"))) (let ((str (call-with-input-file "tests.data" (lambda (p) (read-line p))))) (if (or (not (string? str)) (not (string=? str "start next done"))) (format-logged #t ";call-with-output-file + error -> ~S~%" str))) (let ((str (call-with-input-file "tests.data" (lambda (p) (catch #t (lambda () (read-char p) (abs "hi") (read-char p)) (lambda args "s")))))) (if (or (not (string? str)) (not (string=? str "s"))) (format-logged #t ";call-with-input-file + error -> ~S~%" str))) (if (and (defined? 'file-exists?) (file-exists? "tests.data")) (delete-file "tests.data")) (with-output-to-file "tests.data" (lambda () (format-logged #t "start ") (catch #t (lambda () (format-logged #t "next ") (abs "hi") (format-logged #t "oops ")) (lambda args 'error)) (format-logged #t "done\n"))) (let ((str (with-input-from-file "tests.data" (lambda () (read-line))))) (if (or (not (string? str)) (not (string=? str "start next done"))) (format-logged #t ";with-output-to-file + error -> ~S~%" str))) (let ((str (with-input-from-file "tests.data" (lambda () (catch #t (lambda () (read-char) (abs "hi") (read-char)) (lambda args "s")))))) (if (or (not (string? str)) (not (string=? str "s"))) (format-logged #t ";with-input-from-file + error -> ~S~%" str))) (test (call-with-output-string newline) (string #\newline)) (test (call-with-output-string append) "") (let ((str (call-with-output-string (lambda (p) (format p "start ") (catch #t (lambda () (format p "next ") (abs "hi") (format p "oops ")) (lambda args 'error)) (format p "done"))))) (if (or (not (string? str)) (not (string=? str "start next done"))) (format-logged #t ";call-with-output-string + error -> ~S~%" str))) (let ((str (with-output-to-string (lambda () (format-logged #t "start ") (catch #t (lambda () (format-logged #t "next ") (abs "hi") (format-logged #t "oops ")) (lambda args 'error)) (format-logged #t "done"))))) (if (or (not (string? str)) (not (string=? str "start next done"))) (format-logged #t ";with-output-to-string + error -> ~S~%" str))) (test (with-output-to-string (lambda () (format (current-output-port) "a test ~D" 123))) "a test 123") ;(test (with-output-to-string (lambda () (format *stdout* "a test ~D" 1234))) "a test 1234") (test (string=? (with-output-to-string (lambda () (write #\null))) "#\\null") #t) (test (string=? (with-output-to-string (lambda () (write #\space))) "#\\space") #t) (test (string=? (with-output-to-string (lambda () (write #\return))) "#\\return") #t) (test (string=? (with-output-to-string (lambda () (write #\escape))) "#\\escape") #t) (test (string=? (with-output-to-string (lambda () (write #\tab))) "#\\tab") #t) (test (string=? (with-output-to-string (lambda () (write #\newline))) "#\\newline") #t) (test (string=? (with-output-to-string (lambda () (write #\backspace))) "#\\backspace") #t) (test (string=? (with-output-to-string (lambda () (write #\alarm))) "#\\alarm") #t) (test (string=? (with-output-to-string (lambda () (write #\delete))) "#\\delete") #t) (test (string=? (with-output-to-string (lambda () (write-char #\space))) " ") #t) ; weird -- the name is backwards (test (string=? (with-output-to-string (lambda () (display #\space))) " ") #t) (let ((str (call-with-input-string "12345" (lambda (p) (catch #t (lambda () (read-char p) (abs "hi") (read-char p)) (lambda args "s")))))) (if (or (not (string? str)) (not (string=? str "s"))) (format-logged #t ";call-with-input-string + error -> ~S~%" str))) (let ((str (with-input-from-string "12345" (lambda () (catch #t (lambda () (read-char) (abs "hi") (read-char)) (lambda args "s")))))) (if (or (not (string? str)) (not (string=? str "s"))) (format-logged #t ";with-input-from-string + error -> ~S~%" str))) (for-each (lambda (arg) (test (port-line-number arg) 'error) (test (port-filename arg) 'error)) (list "hi" -1 0 #\a 'a-symbol #(1 2 3) '(1 . 2) '(1 2 3) 3.14 3/4 1.0+1.0i #t abs # # (lambda () 1))) (test (catch #t (lambda () (eval-string (port-filename))) (lambda args #f)) #f) (test (symbol? (string->symbol (port-filename))) #t) (for-each (lambda (arg) (test (with-input-from-string (format #f "~A" arg) (lambda () (read))) arg)) (list 1 3/4 '(1 2) #(1 2) :hi #f #t)) (num-test (with-input-from-string "3.14" read) 3.14) (num-test (with-input-from-string "3.14+2i" read) 3.14+2i) (num-test (with-input-from-string "#x2.1" read) 2.0625) (test (with-input-from-string "'hi" read) ''hi) (test (with-input-from-string "'(1 . 2)" read) ''(1 . 2)) (test (let ((cin #f) (cerr #f)) (catch #t (lambda () (with-input-from-string "123" (lambda () (set! cin (current-input-port)) (error 'testing "jump out")))) (lambda args (set! cerr #t))) (format #f "~A ~A" cin cerr)) " #t") ;;; old form: " #t") (test (let ((cp (current-output-port)) (cout #f) (cerr #f)) (catch #t (lambda () (with-output-to-string (lambda () (set! cout (current-output-port)) (error 'testing "jump out")))) (lambda args (set! cerr #t))) (format #f "~A ~A" cout cerr)) " #t") (if (not (eq? *stdout* old-stdout)) (format *stderr* ";~D: stdout clobbered~%" (port-line-number))) ;;; old form: " #t") (let ((port (open-input-file #u8(115 55 116 101 115 116 46 115 99 109 0) #u8(114 0 98)))) ; "s7test.scm" "r\x00b" (test (input-port? port) #t) ; ?? (close-input-port port)) (call-with-output-file tmp-output-file (lambda (p) (display "1" p) (newline p) (newline p) (display "2345" p) (newline p))) (call-with-input-file tmp-output-file (lambda (p) (test (read-line p) "1") (test (read-line p) "") (test (read-line p) "2345") (test (eof-object? (read-line p)) #t))) (let ((p (open-output-file tmp-output-file "a"))) (display "678" p) (newline p) (close-output-port p)) (if (not with-windows) ; "xyzzy" is legit in windows?? (begin (test (let ((p (open-output-file tmp-output-file "xyzzy"))) (close-output-port p)) 'error) (test (let ((p (open-input-file tmp-output-file "xyzzy"))) (close-input-port p)) 'error))) (call-with-input-file tmp-output-file (lambda (p) (test (read-line p) "1") (test (read-line p) "") (test (read-line p) "2345") (test (read-line p) "678") (test (eof-object? (read-line p)) #t))) (test (let ((a 1)) (define-macro (m1) `(set! a (read))) (with-input-from-string "123" m1) a) 123) (test (let ((a 1)) (define-macro (m3 p) `(set! a (read ,p))) (call-with-input-string "123" m3) a) 123) (test (let () (define-macro (m1) `(define a (read))) (with-input-from-string "123" m1) a) 123) (test (let () (define-macro (m3 p) `(define a (read ,p))) (call-with-input-string "123" m3) a) 123) (for-each (lambda (arg) (test (port-filename arg) 'error)) (list "hi" -1 #\a 1 0 'a-symbol #(1 2 3) 3.14 3/4 1.0+1.0i #f #t () (list 1 2 3) '(1 . 2))) (for-each (lambda (arg) (test (port-filename arg) 'error)) (list "hi" -1 #\a 1 0 'a-symbol #(1 2 3) 3.14 3/4 1.0+1.0i #f #t () (list 1 2 3) '(1 . 2))) (for-each (lambda (arg) (test (open-input-file "s7test.scm" arg) 'error) (test (open-output-file tmp-data-file arg) 'error)) (list -1 #\a 1 0 'a-symbol #(1 2 3) 3.14 3/4 1.0+1.0i #f #t () (list 1 2 3) '(1 . 2))) (test (current-input-port ()) 'error) (test (current-output-port ()) 'error) (test (current-error-port ()) 'error) (for-each (lambda (op) (let ((tag (catch #t (lambda () (op)) (lambda args 'error)))) (if (not (eq? tag 'error)) (format-logged #t ";(~A) -> ~A (expected 'error)~%" op tag)))) (list set-current-input-port set-current-error-port set-current-output-port close-input-port close-output-port write display write-byte write-char format ; newline ;read read-char read-byte peek-char char-ready? read-line ; these can default to current input call-with-output-file call-with-input-file call-with-output-string call-with-input-string with-input-from-string with-input-from-file with-output-to-file open-output-file open-input-file open-input-string)) (for-each (lambda (op) (let ((tag (catch #t (lambda () (op 1 2 3 4 5)) (lambda args 'error)))) (if (not (eq? tag 'error)) (format-logged #t ";(~A 1 2 3 4 5) -> ~A (expected 'error)~%" op tag)))) (list set-current-input-port set-current-error-port set-current-output-port close-input-port close-output-port write display write-byte write-char format newline read read-char read-byte peek-char char-ready? read-line call-with-output-file call-with-input-file call-with-output-string call-with-input-string with-input-from-string with-input-from-file with-output-to-file open-output-file open-input-file open-input-string)) ;;; (string-set! (with-input-from-string "\"1234\"" read) 1 #\a) (test (with-input-from-string "(+ 1 2)" read) '(+ 1 2)) (test (>= (length (with-output-to-string (lambda () (write (make-string 512 #\tab))))) 512) #t) (test (>= (length (with-output-to-string (lambda () (write (make-string 512 #\newline))))) 512) #t) (test (>= (length (with-output-to-string (lambda () (write (make-string 512 #\"))))) 512) #t) (test (>= (length (with-output-to-string (lambda () (write (make-string 512 #\x65))))) 512) #t) (if (and (defined? 'file-exists?) (file-exists? "/home/bil/test")) (let ((old-path *load-path*)) (set! *load-path* (cons "/home/bil/test" *load-path*)) (with-output-to-file "/home/bil/test/load-path-test.scm" (lambda () (format-logged #t "(define (load-path-test) *load-path*)~%"))) (load "load-path-test.scm") (if (or (not (defined? 'load-path-test)) (not (equal? *load-path* (load-path-test)))) (format-logged #t ";*load-path*: ~S, but ~S~%" *load-path* (load-path-test))) (set! *load-path* old-path))) ;;; function ports (when with-block (let ((p (function-open-output))) (write-char #\a p) (let ((val (function-get-output p))) (function-close-output p) (if (not (string=? val "a")) (format *stderr* ";function port write #\\a: ~S (~D, ~A)~%" val (length val) (string->vector val))))) (let ((p (function-open-output))) (display "123" p) (format p "4~D6" 5) (write-string "789" p) (write-byte (char->integer #\0) p) (newline p) (let ((val (function-get-output p))) (function-close-output p) (if (not (string=? val "1234567890\n")) (format *stderr* ";function port outputs: ~S (~D, ~A)~%" val (length val) (string->vector val))))) (let ((str "0123")) (let ((p (function-open-input str))) (let ((val (read-char p))) (if (not (char=? val #\0)) (format *stderr* ";function port read #\\0: ~S~%" val))))) (let ((str "0123\n45678")) (let ((p (function-open-input str))) (let ((val (read-line p))) (if (not (string=? val "0123")) (format *stderr* ";function port read-line: ~S~%" val)) (set! val (read-byte p)) (if (not (= val (char->integer #\4))) (format *stderr* ";function port read-byte: ~S~%" val)) (set! val (peek-char p)) (if (not (char=? val #\5)) (format *stderr* ";function port peek-char: ~S~%" val)) (set! val (read-string 2 p)) (if (not (string=? val "56")) (format *stderr* ";function port read-string: ~S~%" val)) (if (and (not pure-s7) (not (char-ready? p))) (format *stderr* ";function port has no char ready?~%")) (close-input-port p))))) ;;; -------- poke at the reader -------- (test (cdr '(1 ."a")) "a") (test (cadr '(1 .#d2)) '.#d2) (test '(1 .(2 3)) '(1 2 3)) (test '(1 .(2 3)) '(1 . (2 3))) (test (+ .(2 .(3))) 5) (test (cadr '(1 '0,)) ''0,) (test (equal? 3 ' 3) #t) (test (equal? ' 3 3) #t) (test (equal? '"hi" ' "hi") #t) (test (equal? '#\a ' #\a) #t) (test (let ((nam()e 1)) 1) 'error) (test (let ((nam""e 1)) nam""e) 'error) ; this was 1 originally (test (cadr '(1 ']x)) '']x) (test `1 1) (test (equal? '(1 .(1 .())) '(1 1)) #t) (test (equal? '("hi"."ho") ' ("hi" . "ho")) #t) (test (equal? '("hi""ho") '("hi" "ho")) #t) (test '("""""") '("" "" "")) (test '(#|;"();|#) ()) (test '(#||##\# #||##b1) '(#\# 1)) (test (#|s'!'|#*) 1) (test (#|==|#) ()) (test -#|==|#1 'error) ; unbound variable (test '((). '()) '(() quote ())) (test '(1. . .2) '(1.0 . 0.2)) (test (equal? '(().()) '(())) #t) (test (equal? '(()()) '(() ())) #t) (test (equal? '(()..()) '(() .. ())) #t) (test '((().()).()) '((()))) (test '(((().()).()).()) '(((())))) (test '((().(().())).()) '((() ()))) (test '((()().(().()))) '((() () ()))) (test '(1 .; 2) '(1 . 2)) (test (vector .(1 .(2))) #(1 2)) (test (vector 0. .(.1)) #(0.0 0.1)) (test '(a #|foo||# b) '(a b)) ; from bug-guile (test '(a #|foo|||# b) '(a b)) (test '(a #|foo||||# b) '(a b)) (test '(a #|foo|||||# b) '(a b)) (test (let () (define (f' x) (+ x x)) (f' 10)) 20) ; from /r/scheme (test (let () (define (f'' a'b) (+ a'b a'b)) (f'' 10)) 20) (test (symbol? 'a'b) #t) (test (char? #\#) #t) (test (eval-string "'#") 'error) (test (eval-string "'(#)") 'error) (test (car `(,.1e0)) .1) (test (car `(,.1E0)) .1) (test (let ((x "hi")) (set! x"asdf") x) "asdf") (test (let* ((x "hi") (y x)) (set! x "asdf") y) "hi") (test (let ((x 1)) (set! x(list 1 2)) x) '(1 2)) (num-test (let ((x 1)) (set!;" x;) 12.;( );#| x) 12.0) (test (let ((\x00}< 1) (@:\t{ 2)) (+ \x00}< @:\t{)) 3) (test (let ((| 1) (|| 2) (||| 3)) (+ || | |||)) 6) (test (let ((|a#||#b| 1)) |a#||#b|) 1) (test (let ((@,@'[1] 1) (\,| 2)) (+ @,@'[1] \,|)) 3) (test (list"0"0()#()#\a"""1"'x(list)+(cons"""")#f) (list "0" 0 () #() #\a "" "1" 'x (list) + '("" . "") #f)) (test (let ((x, 1)) x,) 1) (test (length (eval-string (string #\' #\( #\1 #\space #\. (integer->char 200) #\2 #\)))) 2) ; will be -1 if dot is for improper list, 3 if dot is a symbol (test (eval-string "(list \\\x001)") 'error) (test (eval-string "(list \\\x00 1)") 'error) (test (+ `,0(angle ```,`11)) 0) (test (map . (char->integer "123")) '(49 50 51)) (test (map .(values "0'1")) '(#\0 #\' #\1)) (test (map /""'(123)) ()) (num-test (+ 1 .()) 1) (test (let () (define (x .()) (list .())) (x)) ()) ;; how is ...#(... parsed? (test (eval-string "'(# (1))") 'error) (test (let ((lst (eval-string "'(#(1))"))) (and (= (length lst) 1) (vector? (car lst)))) #t) ; '(#(1)) (test (let ((lst (eval-string "'(-#(1))"))) (and (= (length lst) 2) (symbol? (car lst)) (pair? (cadr lst)))) #t) ; '(-# (1)) (test (let ((lst (eval-string "'(1#(1))"))) (and (= (length lst) 2) (symbol? (car lst)) (pair? (cadr lst)))) #t) ; '(1# (1)) (test (let ((lst (eval-string "'('#(1))"))) (and (= (length lst) 1) (vector? (cadar lst)))) #t) ; '((quote #(1))) (test (let ((lst (eval-string "'(()#())"))) (and (= (length lst) 2) (null? (car lst)) (vector? (cadr lst)))) #t) ; '(() #()) (test (let ((lst (eval-string "'(().())"))) (and (= (length lst) 1) (null? (car lst)))) #t) ; '(()) (test (let ((lst (eval-string "'(()-())"))) (and (= (length lst) 3) (null? (car lst)) (null? (caddr lst)))) #t) ; '(() - ()) (test (let ((lst (eval-string "'(().#())"))) (and (= (length lst) 3) (null? (car lst)) (null? (caddr lst)))) #t) ; '(() .# ()) (test (let ((lst (eval-string "'((). #())"))) (and (= (length lst) -1) (null? (car lst)) (vector? (cdr lst)))) #t) ; '(() . #()) (test (let ((lst (eval-string "'(\"\"#())"))) (and (= (length lst) 2) (string? (car lst)) (vector? (cadr lst)))) #t) ; '("" #()) (test (length (car '("#\\("))) 3) (test (length (car '("#\\\""))) 3) (test (char=? ((car '("#\\\"")) 2) #\") #t) (test (length '(()#\(())) 3) (test (length (eval-string "'(()#\\(())")) 3) (test (char=? ((eval-string "'(()#\\#())") 1) #\#) #t) (test (length (list""#t())) 3) (test (length (list""#())) 2) (test (length (eval-string "'(#xA(1))")) 2) (test (length '(#xA""#(1))) 3) (test (length (eval-string "'(#xA\"\"#(1))")) 3) (test (length (eval-string "'(1#f)")) 1) (test (eval-string "'(#f#())") 'error) (test (length '(#f())) 2) (test (length '(#f"")) 2) (test (eval-string "#F") 'error) (test (eval-string "'(##)") 'error) (test (eval-string "'(##())") 'error) (test (equal? '('#()) '(#())) #f) (test (equal? (list #()) '(#())) #t) (test (equal? '(#()) '(#())) #t) (test (equal? '('#()) '(`#())) #f) ; [guile agrees] (test (equal? '('()) '(`())) #f) ; ! quote != quasiquote [guile agrees] (test (equal? '('(1)) '(`(1))) #t) ; but lists are different? [guile says #f] (test (equal? '('#(1)) '(`#(1))) #f) ; [guile agrees] (test (equal? '('#()) '(#())) #f) (test (equal? '(`#()) '(`#())) #t) (test (equal? #() `#()) #t) (test (equal? (list #()) (list `#())) #t) (test (equal? (list #()) '(`#())) #t) (test (equal? '(`#()) '(#())) #t) (test (equal? `#() #()) #t) ; and also (1) () #(1) etc (test (equal? `#() '#()) #t) ; " (test (equal? '`#() ''#()) #f) ; it equals #() -- this is consistent -- see below (test (equal? '`#() ``#()) #t) (test (equal? '() '()) #t) (test (equal? (quote ()) '()) #t) (test (equal? '() (quote ())) #t) (test (equal? (quote ()) (quote ())) #t) (test (equal? `(1) '(1)) #t) (test (equal? (quasiquote (1)) '(1)) #t) (test (equal? `(1) (quote (1))) #t) (test (equal? (quasiquote (1)) (quote (1))) #t) (test (equal? ``''1 '``'1) #t) (test (equal? (quasiquote `(quote (quote 1))) '``'1) #t) (test (equal? ``''1 (quote ``(quote 1))) #t) (test (equal? (quasiquote `(quote (quote 1))) (quote ``(quote 1))) #t) (test (equal? '``'#f ```'#f) #t) (test (equal? (quote ``(quote #f)) ```'#f) #t) (test (equal? '``'#f (quasiquote ``(quote #f))) #t) (test (equal? (quote ``(quote #f)) (quasiquote ``(quote #f))) #t) ;;; etc: #| (equal? (quote `1) (quote (quasiquote 1))) -> #f the reader sees `1 and turns it into 1 in the 1st case, but does not collapse the 2nd case to 1 (who knows, quasiquote might have been redefined in context... but ` can't be redefined): :(define (` a) a) ;define: define a non-symbol? 'a ; (define ('a) a) this is different from guile which does not handle ` at read time except to expand it: guile> (quote `1) (quasiquote 1) :(quote `1) 1 so anything that quotes ` is not going to equal quote quasiquote (define (check-strs str1 str2) (for-each (lambda (arg) (let ((expr (format #f "(equal? ~A~A ~A~A)" str1 arg str2 arg))) (let ((val (catch #t (lambda () (eval-string expr)) (lambda args 'error)))) (format #t "--------~%~S -> ~S" expr val) (let* ((parens3 0) (parens4 0) (str3 (apply string-append (map (lambda (c) (if (char=? c #\`) (if (= parens3 0) (begin (set! parens3 (+ parens3 1)) "(quasiquote ") "`") (if (char=? c #\') (begin (set! parens3 (+ parens3 1)) "(quote ") (string c)))) str1))) (str4 (apply string-append (map (lambda (c) (if (char=? c #\`) (if (= parens4 0) (begin (set! parens4 (+ parens4 1)) "(quasiquote ") "`") (if (char=? c #\') (begin (set! parens4 (+ parens4 1)) "(quote ") (string c)))) str2)))) (let ((expr (format #f "(equal? ~A~A~A ~A~A)" str3 arg (make-string parens3 #\)) str2 arg))) (let* ((val1 (catch #t (lambda () (eval-string expr)) (lambda args 'error))) (trouble (and (not (eq? val1 'error)) (not (eq? val1 val))))) (if trouble (format #t "~%~8T~A~S -> ~S~A" bold-text expr val1 unbold-text) (format #t "~%~8T~S -> ~S" expr val1)))) (let ((expr (format #f "(equal? ~A~A ~A~A~A)" str1 arg str4 arg (make-string parens4 #\))))) (let* ((val1 (catch #t (lambda () (eval-string expr)) (lambda args 'error))) (trouble (and (not (eq? val1 'error)) (not (eq? val1 val))))) (if trouble (format #t "~%~8T~A~S -> ~S~A" bold-text expr val1 unbold-text) (format #t "~%~8T~S -> ~S" expr val1)))) (let ((expr (format #f "(equal? ~A~A~A ~A~A~A)" str3 arg (make-string parens3 #\)) str4 arg (make-string parens4 #\))))) (let* ((val1 (catch #t (lambda () (eval-string expr)) (lambda args 'error))) (trouble (and (not (eq? val1 'error)) (not (eq? val1 val))))) (if trouble (format #t "~%~8T~A~S -> ~S~A~%" bold-text expr val1 unbold-text) (format #t "~%~8T~S -> ~S~%" expr val1)))) )))) (list "()" "(1)" "#()" "#(1)" "1" "#f"))) ;; (list ",(+ 1 2)" "\"\"" "(())" "#\\1" "3/4" ",1") (check-strs "'" "'") (check-strs "`" "'") (check-strs "'" "`") (check-strs "`" "`") (let ((strs ())) (do ((i 0 (+ i 1))) ((= i 4)) (let ((c1 ((vector #\' #\` #\' #\`) i)) (c2 ((vector #\' #\' #\` #\`) i))) (do ((k 0 (+ k 1))) ((= k 4)) (let ((d1 ((vector #\' #\` #\' #\`) k)) (d2 ((vector #\' #\' #\` #\`) k))) (let ((str1 (string c1 c2)) (str2 (string d1 d2))) (if (not (member (list str1 str2) strs)) (begin (check-strs str1 str2) (set! strs (cons (list str1 str2) strs)) (set! strs (cons (list str2 str1) strs)))))))))) (let ((strs ())) (do ((i 0 (+ i 1))) ((= i 8)) (let ((c1 ((vector #\' #\` #\' #\` #\' #\` #\' #\`) i)) (c2 ((vector #\' #\' #\` #\` #\' #\' #\` #\`) i)) (c3 ((vector #\' #\' #\' #\' #\` #\` #\` #\`) i))) (do ((k 0 (+ k 1))) ((= k 8)) (let ((d1 ((vector #\' #\` #\' #\` #\' #\` #\' #\`) k)) (d2 ((vector #\' #\' #\` #\` #\' #\' #\` #\`) k)) (d3 ((vector #\' #\' #\' #\' #\` #\` #\` #\`) k))) (let ((str1 (string c1 c2 c3)) (str2 (string d1 d2 d3))) (if (not (member (list str1 str2) strs)) (begin (check-strs str1 str2) (set! strs (cons (list str1 str2) strs)) (set! strs (cons (list str2 str1) strs)))))))))) ;;; -------------------------------- (do ((i 0 (+ i 1))) ((= i 256)) (if (and (not (= i (char->integer #\)))) (not (= i (char->integer #\")))) (let ((str (string #\' #\( #\1 #\space #\. (integer->char i) #\2 #\)))) (catch #t (lambda () (let ((val (eval-string str))) (format #t "[~D] ~A -> ~S (~S ~S)~%" i str val (car val) (cdr val)))) (lambda args (format #t "[~D] ~A -> ~A~%" i str args)))))) (let ((chars (vector (integer->char 0) #\newline #\space #\tab #\. #\, #\@ #\= #\x #\b #\' #\` #\# #\] #\[ #\} #\{ #\( #\) #\1 #\i #\+ #\- #\e #\_ #\\ #\" #\: #\; #\> #\<))) (let ((nchars (vector-length chars))) (do ((len 2 (+ len 1))) ((= len 3)) (let ((str (make-string len)) (ctrs (make-vector len 0))) (do ((i 0 (+ i 1))) ((= i (expt nchars len))) (let ((carry #t)) (do ((k 0 (+ k 1))) ((or (= k len) (not carry))) (vector-set! ctrs k (+ 1 (vector-ref ctrs k))) (if (= (vector-ref ctrs k) nchars) (vector-set! ctrs k 0) (set! carry #f))) (do ((k 0 (+ k 1))) ((= k len)) (string-set! str k (vector-ref chars (vector-ref ctrs k))))) (format #t "~A -> " str) (catch #t (lambda () (let ((val (eval-string str))) (format #t " ~S -> ~S~%" str val))) (lambda args ;(format #t " ~A~%" args) #f ))))))) |# (let ((äåæéîå define) (ìåîçôè length) (äï do) (ìåô* let*) (éæ if) (áâó abs) (ìïç log) (óåô! set!)) (äåæéîå (óòã-äõòáôéïî Ã¥) (ìåô* ((ìåî (ìåîçôè Ã¥)) (åø0 (Ã¥ 0)) (åø1 (Ã¥ (- ìåî 2))) (áìì-ø (- åø1 åø0)) (äõò 0.0)) (äï ((é 0 (+ é 2))) ((>= é (- ìåî 2)) äõò) (ìåô* ((ø0 (Ã¥ é)) (ø1 (Ã¥ (+ é 2))) (ù0 (Ã¥ (+ é 1))) ; 1/ø ø ðïéîôó (ù1 (Ã¥ (+ é 3))) (áòåá (éæ (< (áâó (- ù0 ù1)) .0001) (/ (- ø1 ø0) (* ù0 áìì-ø)) (* (/ (- (ìïç ù1) (ìïç ù0)) (- ù1 ù0)) (/ (- ø1 ø0) áìì-ø))))) (óåô! äõò (+ äõò (áâó áòåá))))))) (num-test (óòã-äõòáôéïî (list 0 1 1 2)) 0.69314718055995) (num-test (óòã-äõòáôéïî (vector 0 1 1 2)) 0.69314718055995)) (test (let ((ÿa 1)) ÿa) 1) (test (+ (let ((!a 1)) !a) (let (($a 1)) $a) (let ((%a 1)) %a) (let ((&a 1)) &a) (let ((*a 1)) *a) (let ((+a 1)) +a) (let ((-a 1)) -a) (let ((.a 1)) .a) (let ((/a 1)) /a) (let ((0a 1)) 0a) (let ((1a 1)) 1a) (let ((2a 1)) 2a) (let ((3a 1)) 3a) (let ((4a 1)) 4a) (let ((5a 1)) 5a) (let ((6a 1)) 6a) (let ((7a 1)) 7a) (let ((8a 1)) 8a) (let ((9a 1)) 9a) (let ((a 1)) >a) (let ((?a 1)) ?a) (let ((@a 1)) @a) (let ((Aa 1)) Aa) (let ((Ba 1)) Ba) (let ((Ca 1)) Ca) (let ((Da 1)) Da) (let ((Ea 1)) Ea) (let ((Fa 1)) Fa) (let ((Ga 1)) Ga) (let ((Ha 1)) Ha) (let ((Ia 1)) Ia) (let ((Ja 1)) Ja) (let ((Ka 1)) Ka) (let ((La 1)) La) (let ((Ma 1)) Ma) (let ((Na 1)) Na) (let ((Oa 1)) Oa) (let ((Pa 1)) Pa) (let ((Qa 1)) Qa) (let ((Ra 1)) Ra) (let ((Sa 1)) Sa) (let ((Ta 1)) Ta) (let ((Ua 1)) Ua) (let ((Va 1)) Va) (let ((Wa 1)) Wa) (let ((Xa 1)) Xa) (let ((Ya 1)) Ya) (let ((Za 1)) Za) (let (([a 1)) [a) (let ((\a 1)) \a) (let ((]a 1)) ]a) (let ((^a 1)) ^a) (let ((_a 1)) _a) (let ((aa 1)) aa) (let ((ba 1)) ba) (let ((ca 1)) ca) (let ((da 1)) da) (let ((ea 1)) ea) (let ((fa 1)) fa) (let ((ga 1)) ga) (let ((ha 1)) ha) (let ((ia 1)) ia) (let ((ja 1)) ja) (let ((ka 1)) ka) (let ((la 1)) la) (let ((ma 1)) ma) (let ((na 1)) na) (let ((oa 1)) oa) (let ((pa 1)) pa) (let ((qa 1)) qa) (let ((ra 1)) ra) (let ((sa 1)) sa) (let ((ta 1)) ta) (let ((ua 1)) ua) (let ((va 1)) va) (let ((wa 1)) wa) (let ((xa 1)) xa) (let ((ya 1)) ya) (let ((za 1)) za) (let (({a 1)) {a) (let ((|a 1)) |a) (let ((}a 1)) }a) (let ((~a 1)) ~a) (let (( a 1))  a) (let ((¡a 1)) ¡a) (let ((¢a 1)) ¢a) (let ((£a 1)) £a) (let ((¤a 1)) ¤a) (let ((Â¥a 1)) Â¥a) (let ((¦a 1)) ¦a) (let ((§a 1)) §a) (let ((¨a 1)) ¨a) (let ((©a 1)) ©a) (let ((ªa 1)) ªa) (let ((«a 1)) «a) (let ((¬a 1)) ¬a) (let ((­a 1)) ­a) (let ((®a 1)) ®a) (let ((¯a 1)) ¯a) (let ((°a 1)) °a) (let ((±a 1)) ±a) (let ((²a 1)) ²a) (let ((³a 1)) ³a) (let ((´a 1)) ´a) (let ((µa 1)) µa) (let ((¶a 1)) ¶a) (let ((·a 1)) ·a) (let ((¸a 1)) ¸a) (let ((¹a 1)) ¹a) (let ((ºa 1)) ºa) (let ((»a 1)) »a) (let ((¼a 1)) ¼a) (let ((½a 1)) ½a) (let ((¾a 1)) ¾a) (let ((¿a 1)) ¿a) (let ((Àa 1)) Àa) (let ((Ãa 1)) Ãa) (let ((Âa 1)) Âa) (let ((Ãa 1)) Ãa) (let ((Äa 1)) Äa) (let ((Ã…a 1)) Ã…a) (let ((Æa 1)) Æa) (let ((Ça 1)) Ça) (let ((Èa 1)) Èa) (let ((Éa 1)) Éa) (let ((Êa 1)) Êa) (let ((Ëa 1)) Ëa) (let ((ÃŒa 1)) ÃŒa) (let ((Ãa 1)) Ãa) (let ((ÃŽa 1)) ÃŽa) (let ((Ãa 1)) Ãa) (let ((Ãa 1)) Ãa) (let ((Ña 1)) Ña) (let ((Ã’a 1)) Ã’a) (let ((Óa 1)) Óa) (let ((Ôa 1)) Ôa) (let ((Õa 1)) Õa) (let ((Öa 1)) Öa) (let ((×a 1)) ×a) (let ((Øa 1)) Øa) (let ((Ùa 1)) Ùa) (let ((Úa 1)) Úa) (let ((Ûa 1)) Ûa) (let ((Üa 1)) Üa) (let ((Ãa 1)) Ãa) (let ((Þa 1)) Þa) (let ((ßa 1)) ßa) (let ((àa 1)) àa) (let ((áa 1)) áa) (let ((âa 1)) âa) (let ((ãa 1)) ãa) (let ((äa 1)) äa) (let ((Ã¥a 1)) Ã¥a) (let ((æa 1)) æa) (let ((ça 1)) ça) (let ((èa 1)) èa) (let ((éa 1)) éa) (let ((êa 1)) êa) (let ((ëa 1)) ëa) (let ((ìa 1)) ìa) (let ((ía 1)) ía) (let ((îa 1)) îa) (let ((ïa 1)) ïa) (let ((ða 1)) ða) (let ((ña 1)) ña) (let ((òa 1)) òa) (let ((óa 1)) óa) (let ((ôa 1)) ôa) (let ((õa 1)) õa) (let ((öa 1)) öa) (let ((÷a 1)) ÷a) (let ((øa 1)) øa) (let ((ùa 1)) ùa) (let ((úa 1)) úa) (let ((ûa 1)) ûa) (let ((üa 1)) üa) (let ((ýa 1)) ýa) (let ((þa 1)) þa) (let ((ÿa 1)) ÿa)) 181) ;;; there are about 50 non-printing chars, some of which would probably work as well ;; (eval-string "(eval-string ...)") is not what it appears to be -- the outer call ;; still sees the full string when it evaluates, not the string that results from ;; the inner call. (let () ; from scheme bboard (define (maxlist list) (define (maxlist' l max) (if (null? l) max (if (> (car l) max) (maxlist' (cdr l) (car l)) (maxlist' (cdr l) max)))) (if (null? list) 'undef (maxlist' list (car list)))) (test (maxlist '(1 2 3)) 3) ; quote is ok in s7 if not the initial char (sort of like a number) (let ((h'a 3)) (test h'a 3)) (let ((1'2 32)) (test 1'2 32)) (let ((1'`'2 32)) (test 1'`'2 32)) (let ((1'`,@2 32)) (test 1'`,@2 32)) ; (test (define '3 32) 'error) ;define quote: syntactic keywords tend to behave badly if redefined ) (let ((|,``:,*|',## 1) (0,,&:@'>>.<# 2) (@.*0`#||\<,, 3) (*&:`&'>#,*<` 4) (*0,,`&|#*:`> 5) (>:|<*.<@:\|` 6) (*',>>:.'@,** 7) (0|.'@<<:,##< 8) (<>,\',\.>>#` 9) (@#.>|&#&,\0* 10) (0'.`&<','<<. 11) (&@@*<*\'&|., 12) (|0*&,':|0\** 13) (<:'*@<>*,<&` 14) (>@<@<|>,`&'. 15) (@#,00:<:@*.\ 16) (*&.`\>#&,&., 17) (0|0|`,,..<@, 18) (0@,'>\,,&.@# 19) (>@@>,000`\#< 20) (|>*'',<:&@., 21) (|>,0>0|,@'|. 22) (0,`'|'`,:`@` 23) (<>#'>,,\'.'& 24) (*..,|,.,&&@0 25)) (test (+ |,``:,*|',## 0,,&:@'>>.<# @.*0`#||\<,, *&:`&'>#,*<` *0,,`&|#*:`> >:|<*.<@:\|` *',>>:.'@,** 0|.'@<<:,##< <>,\',\.>>#` @#.>|&#&,\0* 0'.`&<','<<. &@@*<*\'&|., |0*&,':|0\** <:'*@<>*,<&` >@<@<|>,`&'. @#,00:<:@*.\ *&.`\>#&,&., 0|0|`,,..<@, 0@,'>\,,&.@# >@@>,000`\#< |>*'',<:&@., |>,0>0|,@'|. 0,`'|'`,:`@` <>#'>,,\'.'& *..,|,.,&&@0) 325)) (when full-test (let ((first-chars (list #\. #\0 #\@ #\! #\& #\| #\* #\< #\>)) (rest-chars (list #\. #\0 #\@ #\! #\| #\, #\# #\' #\\ #\` #\, #\: #\& #\* #\< #\>))) (let ((first-len (length first-chars)) (rest-len (length rest-chars))) (let ((n 100) (size 12)) (let ((str (make-string size #\space))) (do ((i 0 (+ i 1))) ((= i n)) (set! (str 0) (first-chars (random first-len))) (do ((k 1 (+ 1 k))) ((= k size)) (set! (str k) (rest-chars (random rest-len)))) (catch #t (lambda () (let ((val (eval-string (format #f "(let () (define ~A 3) ~A)" str str)))) (format #f "~A -> ~A~%" str val))) (lambda args (format #f "~A error: ~A~%" str args))))))))) (let ((List 1) (LIST 2) (lIsT 3) (-list 4) (_list 5) (+list 6)) (test (apply + (list List LIST lIsT -list _list +list)) 21)) (let () (define (\ arg) (+ arg 1)) (test (+ 1 (\ 2)) 4) (define (@\ arg) (+ arg 1)) (test (+ 1 (@\ 2)) 4) (define (@,\ arg) (+ arg 1)) (test (+ 1 (@,\ 2)) 4) (define (\,@\ arg) (+ arg 1)) (test (+ 1 (\,@\ 2)) 4) ) ;;; these are from the r7rs discussions (test (let ((a'b 3)) a'b) 3) ; allow variable names like "can't-go-on" or "don't-ask" (test (let () (define (f x y) (+ x y)) (let ((a 3) (b 4)) (f a, b))) 'error) ; unbound variable a, (test (let () (define (f x y) (+ x y)) (let ((a 3) (b 4)) (f a ,b))) 'error) ; unquote outside quasiquote (test (vector? (owlet 0. 3/4 #(reader-cond ))) 'error) (test (vector? #(reader-cond)) #t) (test ((cond-expand (string (integer->char 255)) (hash-table '(a . 2) 0 (abs (append (string (integer->char 255)) (make-block 32) (inlet 'value 1 '+ (lambda args 1)) (int-vector 1 2 3))))) cdddr) 'error) ;;; -------- object->string ;;; object->string (test (string=? (object->string 32) "32") #t) (test (string=? (object->string 32.5) "32.5") #t) (test (string=? (object->string 32/5) "32/5") #t) (test (object->string 1+i) "1+1i") (test (string=? (object->string "hiho") "\"hiho\"") #t) (test (string=? (object->string 'symb) "symb") #t) (test (string=? (object->string (list 1 2 3)) "(1 2 3)") #t) (test (string=? (object->string (cons 1 2)) "(1 . 2)") #t) (test (string=? (object->string #(1 2 3)) "#(1 2 3)") #t) (test (string=? (object->string +) "+") #t) (test (object->string (object->string (object->string "123"))) "\"\\\"\\\\\\\"123\\\\\\\"\\\"\"") (test (object->string #) "#") (test (object->string (if #f #f)) "#") (test (object->string #) "#") (test (object->string #f) "#f") (test (object->string #t) "#t") (test (object->string ()) "()") (test (object->string #()) "#()") (test (object->string "") "\"\"") (test (object->string abs) "abs") (test (object->string lambda) "lambda") (test (object->string (lambda () a)) "#") (test (object->string (lambda a a)) "#") (test (object->string (lambda (a) a)) "#") (test (object->string (lambda (a . b) a)) "#") (test (object->string (lambda (a b) a)) "#") (test (object->string (lambda (a b c) a)) "#") (test (object->string (lambda (a b . c) a)) "#") (test (object->string (lambda* (a :rest b) a)) "#") (test (object->string (lambda* (:rest a) a)) "#") (test (object->string (lambda* (a b :rest c) a)) "#") (let () (define-macro (mac a) a) (test (object->string mac) "mac")) (let ((m (define-macro (mac a) a))) (test (object->string m) "#")) (let ((m (define-macro* (mac a) a))) (test (object->string m) "#")) (let ((m (define-bacro (mac a) a))) (test (object->string m) "#")) (let ((m (define-bacro* (mac a) a))) (test (object->string m) "#")) (let ((_?_m (define-expansion (_?_mac a) a))) (test (object->string _?_m) "#")) (test (object->string +) "+") (test (object->string +) "+") (test (object->string '''2) "''2") (test (object->string (lambda () #f)) "#") ;"#" (test (call-with-exit (lambda (return) (object->string return))) "#") (test (call/cc (lambda (return) (object->string return))) "#") (test (let () (define-macro (hi a) `(+ 1 ,a)) (object->string hi)) "hi") (test (let () (define (hi a) (+ 1 a)) (object->string hi)) "hi") (test (let () (define* (hi a) (+ 1 a)) (object->string hi)) "hi") (test (object->string dynamic-wind) "dynamic-wind") (test (object->string (dilambda (lambda () 1) (lambda (val) val))) "#") ;"#" (test (object->string object->string) "object->string") (test (object->string 'if) "if") (test (object->string begin) "begin") (test (object->string let) "let") (test (object->string #\n #f) "n") (test (object->string #\n) "#\\n") (test (object->string #\r) "#\\r") (test (object->string #\r #f) "r") (test (object->string #\t #f) "t") (test (object->string #\t) "#\\t") (test (object->string "a\x00b" #t) "\"a\\x00b\"") (test (object->string "a\x00b" #f) "a\x00b") #| (do ((i 0 (+ i 1))) ((= i 256)) (let ((c (integer->char i))) (let ((str (object->string c))) (if (and (not (= (length str) 3)) ; "#\\a" (or (not (char=? (str 2) #\x)) (not (= (length str) 5)))) ; "#\\xee" (format-logged #t "(#t) ~C: ~S~%" c str)) (set! str (object->string c #f)) (if (not (= (length str) 1)) (format-logged #t "(#f) ~C: ~S~%" c str))))) this prints: (#t) : "#\\null" (#f) : "" (#t) : "#\\x1" (#t) : "#\\x2" (#t) : "#\\x3" (#t) : "#\\x4" (#t) : "#\\x5" (#t) : "#\\x6" (#t) : "#\\x7" (#t): "#\\x8" (#t) : "#\\tab" (#t) : "#\\newline" (#t) : "#\\xb" (#t) : "#\\xc" : "#\\return" (#t) : "#\\xe" (#t) : "#\\xf" (#t) : "#\\space" |# (test (object->string #\x30) "#\\0") (test (object->string #\x91) "#\\x91") (test (object->string #\x10) "#\\x10") (test (object->string #\xff) "#\\xff") (test (object->string #\x55) "#\\U") (test (object->string #\x7e) "#\\~") (test (object->string #\newline) "#\\newline") (test (object->string #\return) "#\\return") (test (object->string #\tab) "#\\tab") (test (object->string #\null) "#\\null") (test (object->string #\space) "#\\space") (test (object->string (integer->char 8)) "#\\backspace") (test (object->string ''#\a) "'#\\a") (test (object->string (list 1 '.' 2)) "(1 .' 2)") (test (object->string (quote (quote))) "(quote)") (test (object->string (quote quote)) "quote") (test (object->string (quote (quote (quote)))) "'(quote)") (test (object->string) 'error) (test (object->string 1 2) 'error) (test (object->string 1 #f #t) 'error) (test (object->string abs) "abs") (test(let ((val 0)) (cond (else (set! val (object->string else)) 1)) val) "else") (test (cond (else (object->string else))) "else") (test (object->string (string->symbol (string #\; #\" #\)))) "(symbol \";\\\")\")") (test (object->string "hi" #f) "hi") (test (object->string "h\\i" #f) "h\\i") (test (object->string -1.(list? -1e0)) "-1.0") (test (object->string catch) "catch") (test (object->string lambda) "lambda") (test (object->string dynamic-wind) "dynamic-wind") (test (object->string quasiquote) "quasiquote") ;(test (object->string else) "else") ; this depends on previous code (test (object->string do) "do") (for-each (lambda (arg) (test (object->string 1 arg) 'error) (test (object->string arg) (with-output-to-string (lambda () (write arg)))) (test (object->string arg #t) (with-output-to-string (lambda () (write arg)))) (test (object->string arg #f) (with-output-to-string (lambda () (display arg))))) (list "hi" -1 #\a 1 0 'a-symbol #(1 2 3) 3.14 3/4 1.0+1.0i () (list 1 2 3) '(1 . 2))) (test (string->symbol (object->string #(1 #\a (3)) #f)) (symbol "#(1 #\\a (3))")) (test (string->list (object->string #(1 2) #f)) '(#\# #\( #\1 #\space #\2 #\))) (test (string->list (object->string #(1 #\a (3)) #f)) '(#\# #\( #\1 #\space #\# #\\ #\a #\space #\( #\3 #\) #\))) (test (reverse (object->string #2D((1 2) (3 4)) #f)) "))4 3( )2 1((D2#") ;; write readably (this affects ~W in format as well) ;; :readable special things (for-each (lambda (n) (let ((str (object->string n :readable))) (let ((obj (with-input-from-string str (lambda () (eval (read)))))) (if (not (eq? n obj)) (format *stderr* "~A not eq? ~A (~S)~%" n obj str))))) (list # # # #t #f #true #false else () lambda lambda* begin case if do quote set! let let* letrec cond and or define define* define-constant define-macro define-macro* define-bacro define-bacro* with-baffle *stdin* *stdout* *stderr*)) ;; :readable characters (do ((i 0 (+ i 1))) ((= i 256)) (let ((c (integer->char i))) (let ((str (object->string c :readable))) (let ((nc (with-input-from-string str (lambda () (eval (read)))))) ; no need for eval here or in some other cases, but might as well be consistent (if (not (eq? c nc)) (format *stderr* "~C (~D) != ~C (~S)~%" c i nc str)))))) ;; :readable integers (for-each (lambda (n) (let ((str (object->string n :readable))) (let ((nn (with-input-from-string str (lambda () (eval (read)))))) (if (or (not (integer? n)) (not (integer? nn)) (not (= n nn))) (format *stderr* "~D != ~D (~S)~%" n nn str))))) (list 0 1 3 most-positive-fixnum -0 -1 -3 most-negative-fixnum -9223372036854775808 9223372036854775807)) ;; but unless gmp at read end we'll fail with most-positive-fixnum+1 ;; -> check *features* at start of read ;; :readable ratios (for-each (lambda (n) (let ((str (object->string n :readable))) (let ((nn (with-input-from-string str (lambda () (eval (read)))))) (if (or (not (rational? n)) (not (rational? nn)) (not (= n nn))) (format *stderr* "~A != ~A (~S)~%" n nn str))))) (list 1/2 -1/2 123456789/2 -2/123456789 2147483647/2147483646 312689/99532 -9223372036854775808/3 9223372036854775807/2 1/1428571428571429 1/1152921504606846976)) (when (not (provided? 'solaris)) ;; :readable reals (for-each (lambda (n) (let ((str (object->string n :readable))) (let ((nn (with-input-from-string str (lambda () (eval (read)))))) (if (or (not (real? n)) (not (real? nn)) (not (morally-equal? n nn))) (format *stderr* "~A != ~A (~S)~%" n nn str))))) (list 1.0 0.0 -0.0 pi 0.1 -0.1 0.9999999995 9007199254740993.1 (sqrt 2) 1/100000000000 1.5e-16 1.5e16 3.141592653589793238462643383279502884197169399375105820 1e-300 8.673617379884e-19 1/0 (- 1/0) (real-part (log 0)) (- (real-part (log 0))))) ;; :readable complex (for-each (lambda (n) (let ((str (object->string n :readable))) (let ((nn (with-input-from-string str (lambda () (eval (read)))))) (if (or (not (complex? n)) (not (complex? nn)) (not (morally-equal? n nn))) (format *stderr* "~A != ~A (~S)~%" n nn str))))) (list 0+i 0-i 1+i 1.4+i 3.0+1.5i (log 0) (- (log 0)) (complex 1/0 1.0) (complex 1/0 1/0) (complex 1.0 1/0) ; default: nan+1i nannani 1nani! (complex 1/0 (real-part (log 0))) (complex (real-part (log 0)) 1/0) 1e-14+1e14i 0+1e-16i (complex pi pi)))) ;; :readable strings/byte-vectors (for-each (lambda (n) (let ((str (object->string n :readable))) (let ((obj (with-input-from-string str (lambda () (eval (read)))))) (if (or (not (string? n)) (not (string? obj)) (not (string=? n obj)) (and (byte-vector? n) (not (byte-vector? obj)))) (format *stderr* "~S not string=? ~S (~S)~%" n obj str))))) (list "" "abc" (string #\newline) "#" "a\"b\"c" "a\\b\nc" "aBc" (let ((s (make-string 4 #\space))) (set! (s 3) #\null) s) ; writes as " \x00" "ab c" (string #\a #\b #\null #\c #\escape #\newline) (string #\x (integer->char #xf0) #\x) (string #\null) #u8() #u8(0 1 2 3) (let ((str (make-string 256 #\null))) (do ((i 0 (+ i 1))) ((= i 256) str) (set! (str i) (integer->char i)))))) ;; :readable symbols/keywords (for-each (lambda (n) (let ((str (object->string n :readable))) (let ((obj (with-input-from-string str (lambda () (eval (read)))))) (if (or (not (symbol? n)) (not (symbol? obj)) (not (eq? n obj))) (format *stderr* "~A not eq? ~A (~S)~%" n obj str))))) (list 'abc :abc abc: (symbol "a") (symbol "#<>") (gensym "|") (gensym "#<>") (gensym "}") :: ':abc (gensym "\\"))) ;; :readable environments (for-each (lambda (n) (let ((str (object->string n :readable))) (let ((obj (with-input-from-string str (lambda () (eval (read)))))) (if (or (not (let? n)) (not (let? obj)) (not (equal? n obj))) (format *stderr* "~A not equal?~%~A~% (~S)~%" n obj str))))) (list (inlet '(a . 1)) (inlet) (rootlet) (inlet (cons 't12 "12") (cons (symbol "#<") 12)) (inlet 'a 1 'a 2))) ;(test (object->string (list (owlet)) :readable) "(list (owlet))") ;; :readable hash-tables (for-each (lambda (n) (let ((str (object->string n :readable))) (let ((obj (with-input-from-string str (lambda () (eval (read)))))) (if (or (not (hash-table? n)) (not (hash-table? obj)) (not (equal? n obj))) (format *stderr* ";readable hash-tables, ~A not equal? ~A (~S)~%" n obj str))))) (list (hash-table '(a . 1)) (hash-table '(a . 1) (cons 'b "hi")) (let ((ht (make-hash-table 31))) (set! (ht 1) 321) (set! (ht 2) 123) ht) (let ((ht (make-hash-table))) (set! (ht 'b) 1) (set! (ht 'a) ht) ht) ;(let ((ht (make-hash-table))) (set! (ht ht) 123) ht) ;(let ((ht (make-hash-table))) (set! (ht ht) ht) ht) (hash-table))) ;; :readable vectors (let ((old-plen (*s7* 'print-length))) (for-each (lambda (p) (set! (*s7* 'print-length) p) (for-each (lambda (n) (let ((str (object->string n :readable))) (let ((obj (with-input-from-string str (lambda () (eval (read)))))) (if (or (not (vector? n)) (not (vector? obj)) (not (equal? n obj))) (format *stderr* ";readable vectors, ~A not equal? ~A (~S)~%" n obj str))))) (list #() #(1) #(1 #(2)) #2d((1 2) (3 4)) #3d(((1 2 3) (4 5 6) (7 8 9)) ((9 8 7) (6 5 4) (3 2 1))) #2d() #(1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0) (let ((v (vector 1 2 3))) (set! (v 1) v) v) (let ((v (vector 1 #(2) 3))) (set! ((v 1) 0) v) v) (let ((v #2d((1 2 3) (4 5 6)))) (set! (v 1 1) v) v) (make-vector 3 0 #t) (make-vector 3 0.0 #t) (make-vector '(2 3) 1 #t) ))) (list old-plen 8 2 1)) (set! (*s7* 'print-length) old-plen)) (test (object->string (vector 1 2 3) :readable) "(vector 1 2 3)") ;; :readable lists (circular, dotted) (for-each (lambda (n) (let ((str (object->string n :readable))) (let ((obj (with-input-from-string str (lambda () (eval (read)))))) (if (or (not (pair? n)) (not (pair? obj)) (not (equal? n obj))) (format *stderr* ";readable lists, ~A not equal? ~A (~S)~%" n obj str))))) (list '(1) '(1 . 2) '((1 ()) 3) '((1 2) (3 4)) '(1 2 . 3) '(1 2 3 . 4) '(()) (let ((lst (cons 1 2))) (set-cdr! lst lst) lst) (let ((lst (list 1 2 3))) (set-cdr! (cddr lst) lst) lst) (let ((lst (list 1 2 3))) (set-car! (cddr lst) lst) lst) )) ;; :readable macros (let () (define-macro (mac1) `(+ 1 2)) (test ((eval-string (object->string mac1 :readable))) 3) (define-macro (mac2 a) `(+ ,a 2)) (test ((eval-string (object->string mac2 :readable)) 1) 3) (define-macro* (mac3 (a 1)) `(+ ,a 2)) (test ((eval-string (object->string mac3 :readable))) 3) (define-macro (mac4 . a) `(+ ,@a 2)) (test ((eval-string (object->string mac4 :readable)) 1 3) 6) (define-macro (mac5 a b . c) `(+ ,a ,b ,@c 2)) (test ((eval-string (object->string mac5 :readable)) 1 5 3 4) 15) (define-macro (mac7 a) (let ((b (+ a 1))) `(+ ,b ,a))) (test ((eval-string (object->string mac7 :readable)) 2) 5) ) ;; :readable closures/functions/built-in (C) functions + the setters thereof (for-each (lambda (n) (let ((str (object->string n :readable))) (let ((obj (with-input-from-string str (lambda () (eval (read)))))) (if (or (not (procedure? n)) (not (procedure? obj)) (not (equal? (procedure-source n) (procedure-source obj)))) (format *stderr* "'~A not equal? '~A (~S)~%" n obj str))))) (list abs (lambda () 1) (lambda (a) (+ a 1)) (lambda args (display args) (cdr args)) (lambda* (a b) (or a b)) (let ((a 1)) (lambda (b) (+ a b))) (let ((b 2)) (let ((a 1)) (lambda* (c . d) (display (+ a b c) *stdout*) d))) (lambda* (:rest b) b) )) (for-each (lambda (n) (let ((str (object->string n :readable))) (test ((eval-string str) 21) (n 21)))) (list (lambda (a) (+ a 1)) (lambda args (cdr args)) (lambda* (a b) (or a b)) (let ((a 1)) (lambda (b) (+ a b))) (let ((b 2)) (let ((a 1)) (lambda* (c . d) (+ a b c)))) (lambda* (:rest b) b) )) (let () (define* (f1 a :allow-other-keys) (+ a 1)) (let ((str (object->string f1 :readable))) (let ((obj (with-input-from-string str (lambda () (eval (read)))))) (test (f1 2 :b 3) 3) (test (obj 2) 3) (test (obj 2 :b 3) 3)))) ; too many args ;; :readable ports (for-each (lambda (n) (let ((str (object->string n :readable))) (let ((obj (with-input-from-string str (lambda () (eval (read)))))) (if (or (not (input-port? n)) (not (input-port? obj)) (not (equal? (port-closed? n) (port-closed? obj)))) (format *stderr* "~A not equal? ~A (~S)~%" n obj str) (if (and (not (port-closed? n)) (not (eq? n *stdin*)) (not (eq? n (current-input-port)))) (let ((c1 (read-char n)) (c2 (read-char obj))) (if (not (equal? c1 c2)) (format *stderr* "read-char results ~A not equal? ~A (~S)~%" c1 c2 str))))) (if (and (not (eq? n *stdin*)) (not (eq? n (current-input-port)))) (begin (close-input-port n) (close-input-port obj)))))) (list *stdin* (open-input-string "a test") (call-with-input-string "a test" (lambda (p) p)) (let ((p (open-input-string "a test"))) (read-char p) p) (call-with-input-file "s7test.scm" (lambda (p) p)) (open-input-file "write.scm") (let ((p (open-input-file "write.scm"))) (read-char p) p))) ;; :readable environments (for-each (lambda (n) (let ((str (object->string n :readable))) (let ((obj (with-input-from-string str (lambda () (eval (read)))))) (if (or (not (let? n)) (not (let? obj)) (not (equal? n obj))) (format *stderr* "~A not equal? ~A (~S)~%" n obj str))))) (list (rootlet) (let ((a 1)) (curlet)) (let ((a 1) (b 2)) (curlet)))) (when with-block (let ((b (block 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0))) (test (format #f "~W" b) "(block 1.000 2.000 3.000 4.000 5.000 6.000 7.000 8.000)") (test (format #f "~A" b) "(block ...)"))) (test (object->string (define (ex1 a b) (+ a b)) :readable) "(lambda (a b) (+ a b))") (test (object->string (let ((c 3)) (define (ex1 a b) (+ a c b))) :readable) "(let ((c 3)) (lambda (a b) (+ a c b)))") (test (object->string (let ((c 3)) (define (ex1) (+ c 1))) :readable) "(let ((c 3)) (lambda () (+ c 1)))") (test (object->string (define* (ex1 a (b 0)) (+ a b)) :readable) "(lambda* (a (b 0)) (+ a b))") (test (object->string (define (ex1 a . b) (+ a b)) :readable) "(lambda (a . b) (+ a b))") (let ((oldpl (*s7* 'print-length))) (set! (*s7* 'print-length) 4) (define (f1) (vector-ref #(0 1 2 3 4 5 6 7 8) 2)) (test (object->string f1 :readable) "(lambda () (vector-ref #(0 1 2 3 4 5 6 7 8) 2))") (set! (*s7* 'print-length) oldpl)) (test (object->string (make-iterator #u8(12 41 2)) :readable) "(make-iterator #u8(12 41 2))") (test (object->string (inlet) :readable) "(inlet)") (test (object->string (inlet 'a 1) :readable) "(inlet 'a 1)") (test (object->string (inlet 'a 1 'b 2) :readable) "(inlet 'a 1 'b 2)") (test (object->string (inlet 'a #\1) :readable) "(inlet 'a #\\1)") (test (object->string (inlet 'a #\newline) :readable) "(inlet 'a #\\newline)") (test (object->string (inlet 'a #\null) :readable) "(inlet 'a #\\null)") (test (object->string (inlet 'a 3.0) :readable) "(inlet 'a 3.0)") (test (object->string (inlet 'a 1/2) :readable) "(inlet 'a 1/2)") (test (object->string (inlet 'a 1+i) :readable) "(inlet 'a 1+1i)") (test (object->string (inlet 'a (log 0)) :readable) (format #f "(inlet 'a (~S -inf.0 3.141592653589793))" (if pure-s7 'complex 'complex))) (test (object->string (inlet 'a 1/0) :readable) "(inlet 'a nan.0)") (test (object->string (inlet 'a "1") :readable) "(inlet 'a \"1\")") (test (object->string (inlet 'a "") :readable) "(inlet 'a \"\")") (test (object->string (inlet 'a #) :readable) "(inlet 'a #)") (test (object->string (inlet 'a #) :readable) "(inlet 'a #)") (test (object->string (inlet 'a #) :readable) "(inlet 'a (begin #))") (test (object->string (inlet 'a lambda) :readable) "(inlet 'a lambda)") (test (object->string (inlet 'a 'b) :readable) "(inlet 'a 'b)") (test (object->string (inlet 'a (symbol "( a b c )")) :readable) "(inlet 'a (symbol \"( a b c )\"))") (test (object->string (inlet 'a else) :readable) "(inlet 'a else)") (test (object->string (inlet 'a (cons 1 2)) :readable) "(inlet 'a (cons 1 2))") (test (object->string (inlet 'a (list 1 2)) :readable) "(inlet 'a (list 1 2))") (test (object->string (inlet 'a (list "hi")) :readable) "(inlet 'a (list \"hi\"))") (test (object->string (inlet 'a ()) :readable) "(inlet 'a ())") (test (object->string (inlet 'a '(1 2 . 3)) :readable) "(inlet 'a (cons 1 (cons 2 3)))") (test (object->string (inlet 'a #t) :readable) "(inlet 'a #t)") (test (object->string (inlet 'a #f) :readable) "(inlet 'a #f)") (test (object->string (inlet 'a :b) :readable) "(inlet 'a :b)") (test (object->string (inlet 'a (hash-table)) :readable) "(inlet 'a (hash-table))") (test (object->string (inlet 'a (hash-table* 'b 1)) :readable) "(inlet 'a (hash-table (cons 'b 1)))") (test (object->string (inlet 'a (hash-table* 'b "hi")) :readable) "(inlet 'a (hash-table (cons 'b \"hi\")))") (test (object->string (inlet 'a (hash-table* 'b "h\"i")) :readable) "(inlet 'a (hash-table (cons 'b \"h\\\"i\")))") (test (object->string (inlet 'a #()) :readable) "(inlet 'a #())") (test (object->string (inlet 'a #(1 2 3)) :readable) "(inlet 'a (vector 1 2 3))") (test (object->string (inlet 'a (vector "hi" #\a 'b)) :readable) "(inlet 'a (vector \"hi\" #\\a 'b))") (test (object->string (inlet 'a (float-vector 1 2 3)) :readable) "(inlet 'a (float-vector 1.0 2.0 3.0))") (test (object->string (inlet 'a (int-vector 1 2 3)) :readable) "(inlet 'a (int-vector 1 2 3))") (test (object->string (inlet 'a #2d((1 2 3) (4 5 6))) :readable) "(inlet 'a (make-shared-vector (vector 1 2 3 4 5 6) '(2 3)))") (test (object->string (inlet 'a abs) :readable) "(inlet 'a abs)") (test (object->string (inlet 'a (lambda (b) (+ b 1))) :readable) "(inlet 'a (lambda (b) (+ b 1)))") (test (object->string (inlet 'a (lambda b (list b 1))) :readable) "(inlet 'a (lambda b (list b 1)))") (test (object->string (inlet 'a (lambda (a . b) (list a b))) :readable) "(inlet 'a (lambda (a . b) (list a b)))") (test (object->string (inlet 'a (define-macro (_m_ b) `(+ ,b 1))) :readable) "(inlet 'a (define-macro (_m_ b) ({list} '+ b 1)))") (test (object->string (inlet 'a (define-bacro (_m_ b) `(+ ,b 1))) :readable) "(inlet 'a (define-bacro (_m_ b) ({list} '+ b 1)))") (test (object->string (inlet 'a (lambda* ((b 1)) (+ b 1))) :readable) "(inlet 'a (lambda* ((b 1)) (+ b 1)))") (test (object->string (inlet 'a (lambda* a (list a))) :readable) "(inlet 'a (lambda* a (list a)))") (test (object->string (inlet 'a (lambda* (a (b 1) c) (list a b c))) :readable) "(inlet 'a (lambda* (a (b 1) c) (list a b c)))") (test (object->string (inlet 'a (define-macro* (_m_ (b 1)) `(+ ,b 1))) :readable) "(inlet 'a (define-macro* (_m_ (b 1)) ({list} '+ b 1)))") (test (object->string (inlet 'a (define-bacro* (_m_ (b 1)) `(+ ,b 1))) :readable) "(inlet 'a (define-bacro* (_m_ (b 1)) ({list} '+ b 1)))") (when with-block (test (object->string (inlet 'a (block)) :readable) "(inlet 'a (block))") (test (object->string (inlet 'a blocks) :readable) "(inlet 'a blocks)") (test (object->string (inlet 'a (block 1 2 3)) :readable) "(inlet 'a (block 1.000 2.000 3.000))")) (test (object->string (inlet 'a (c-pointer 0)) :readable) "(inlet 'a (c-pointer 0))") (test (object->string (inlet 'a (c-pointer 1)) :readable) "(inlet 'a (c-pointer 1))") (test (object->string (inlet 'a quasiquote) :readable) "(inlet 'a quasiquote)") (test (object->string (inlet 'a (dilambda (lambda () 1) (lambda (x) x))) :readable) "(inlet 'a (dilambda (lambda () 1) (lambda (x) x)))") (test (object->string (inlet 'a (inlet 'b 1)) :readable) "(inlet 'a (inlet 'b 1))") (test (object->string (inlet 'a (let ((b 1)) (lambda () b))) :readable) "(inlet 'a (let ((b 1)) (lambda () b)))") (test (object->string (inlet 'a (let ((y 1)) (dilambda (lambda () y) (lambda (x) (set! y x))))) :readable) "(inlet 'a (let ((y 1)) (dilambda (lambda () y) (lambda (x) (set! y x)))))") (test (object->string (inlet 'a (open-input-string "123456")) :readable) "(inlet 'a (open-input-string \"123456\"))") (test (object->string (inlet 'a (let ((p (open-input-string "123456"))) (read-char p) p)) :readable) "(inlet 'a (open-input-string \"23456\"))") (test (object->string (inlet 'a (let ((p (open-input-string "1"))) (read-char p) p)) :readable) "(inlet 'a (open-input-string \"\"))") (test (object->string (inlet 'a (let ((p (open-input-string "1"))) (read-char p) (read-char p) p)) :readable) "(inlet 'a (open-input-string \"\"))") (test (object->string (inlet 'a (call-with-input-string "1" (lambda (p) p))) :readable) "(inlet 'a (call-with-input-string \"\" (lambda (p) p)))") (test (object->string (inlet 'a (let ((p (open-input-string "1"))) (close-input-port p) p)) :readable) "(inlet 'a (call-with-input-string \"\" (lambda (p) p)))") (test (object->string (inlet 'a *stdin*) :readable) "(inlet 'a *stdin*)") (test (object->string (inlet 'a *stdout*) :readable) "(inlet 'a *stdout*)") (test (object->string (inlet 'a *stderr*) :readable) "(inlet 'a *stderr*)") (test (object->string (inlet 'a (let ((p (open-output-string))) (close-output-port p) p)) :readable) "(inlet 'a (let ((p (open-output-string))) (close-output-port p) p))") (test (object->string (inlet 'a (open-output-string)) :readable) "(inlet 'a (let ((p (open-output-string))) p))") (test (object->string (inlet 'a (let ((p (open-output-string))) (display 32 p) p)) :readable) "(inlet 'a (let ((p (open-output-string))) (display \"32\" p) p))") (test (object->string (inlet 'a (open-output-file "test.test")) :readable) "(inlet 'a (open-output-file \"test.test\" \"a\"))") (test (object->string (inlet 'a (open-input-file "test.test")) :readable) "(inlet 'a (open-input-file \"test.test\"))") (test (object->string (inlet 'a (make-iterator "123")) :readable) "(inlet 'a (make-iterator \"123\"))") (test (object->string (inlet 'a (let ((iter (make-iterator "123"))) (iter) iter)) :readable) "(inlet 'a (make-iterator \"23\"))") (test (object->string (inlet 'a (make-iterator #(1 2 3))) :readable) "(inlet 'a (make-iterator (vector 1 2 3)))") (test (object->string (inlet 'a (make-iterator '(1 2 3))) :readable) "(inlet 'a (make-iterator (list 1 2 3)))") (test (object->string (inlet 'a (let ((iter (make-iterator (float-vector 1 2 3)))) (iter) iter)) :readable) "(inlet 'a (let ((iter (make-iterator (float-vector 1.0 2.0 3.0)))) (do ((i 0 (+ i 1))) ((= i 1) iter) (iterate iter))))") (test (object->string (let () (define (f1) (+ a 1)) (curlet)) :readable) "(inlet 'f1 (lambda () (+ a 1)))") (test (object->string (let () (define (f1) 1) (let () (define f2 f1) (curlet))) :readable) "(inlet 'f2 (lambda () 1))") (test (object->string (let ((a 1)) (define d (let ((b 1)) (lambda (c) (+ a b c)))) (curlet)) :readable) "(inlet 'a 1 'd (let ((b 1) (a 1)) (lambda (c) (+ a b c))))") (test (object->string (let () (define a (let ((b 1) (c 2)) (lambda (d) (+ b c d)))) (curlet)) :readable) "(inlet 'a (let ((c 2) (b 1)) (lambda (d) (+ b c d))))") (test (object->string (let ((a 1)) (define d (let ((b 1)) (let ((c b)) (lambda (e) (+ a b c e))))) (curlet)) :readable) "(inlet 'a 1 'd (let ((c 1) (b 1) (a 1)) (lambda (e) (+ a b c e))))") (test (object->string (inlet 'a (let ((b 1)) (lambda () (+ b c)))) :readable) "(inlet 'a (let ((b 1)) (lambda () (+ b c))))") (test (object->string (inlet 'a (let ((b 1)) (lambda () (+ b pi)))) :readable) "(inlet 'a (let ((b 1)) (lambda () (+ b pi))))") (test (object->string (let* ((a 1) (b a)) (curlet)) :readable) "(inlet 'b 1)") (test (object->string (let ((a 1)) (define (b c) (+ c a)) (curlet)) :readable) "(inlet 'a 1 'b (let ((a 1)) (lambda (c) (+ c a))))") ;;; ideally we'd catch the documentation setting (test (string? (object->string (let ((lst (list 1))) (set-cdr! lst lst) (make-iterator lst)) :readable)) #t) ;;; these are not readable: (test (object->string (inlet 'a (call-with-exit (lambda (return) return))) :readable) "(inlet 'a goto)") (test (object->string (inlet 'a (call/cc (lambda (return) return))) :readable) "(inlet 'a continuation)") ;;; these are incorrect: ;(test (object->string (let ((b 1)) (set! (symbol-access 'b) (lambda (val) val)) (curlet)) :readable) "(inlet 'b 1)") ;(test (object->string (let () (define-constant a 32) (curlet)) :readable) "(inlet 'a 32)") ;(test (object->string #('1)) "(vector '1)") ;(test (object->string (inlet 'a ''()) :readable) "(inlet 'a '())") (test (object->string (c-pointer 1234) :readable) "(c-pointer 1234)") (test (string? (object->string (*s7* 'gc-protected-objects) :readable)) #t) (test (string? (object->string (*s7* 'c-objects) :readable)) #t) (test (string? (object->string (*s7* 'file-names) :readable)) #t) (test (string? (object->string (*s7* 'c-types) :readable)) #t) (test (string? (object->string (*s7* 'cpu-time) :readable)) #t) (test (string? (object->string (*s7* 'catches) :readable)) #t) (test (string? (object->string (*s7* 'exits) :readable)) #t) (test (string? (object->string (*s7* 'stack) :readable)) #t) (let ((ht (hash-table* 'a 1)) (lt (inlet :b 1)) (lst (list 1))) (set! (ht 'a) lst) (set! (lst 0) lt) (set! (lt 'b) ht) (test (object->string ht) "#1=(hash-table '(a (inlet 'b #1#)))")) (let ((ht (hash-table* 'a 1))) (fill! ht ht) (test (object->string ht) "#1=(hash-table '(a . #1#))")) (let ((ht (hash-table* 'a 1))) (set! (ht 'a) ht) (fill! ht (list ht)) (test (object->string ht) "#1=(hash-table '(a #1#))")) (let ((ht (hash-table* 'a 1))) (let ((lt (curlet))) (set! (ht 'a) ht) (fill! ht (list lt)) (test (object->string ht) "#1=(hash-table '(a (inlet 'ht #1#)))"))) (if (not with-bignums) (begin (test (object->string (random-state 123 321)) "#") (test (object->string (random-state 9223372036854775807 9223372036854775807)) "#") (test (object->string (random-state 123 321) :readable) "(random-state 123 321)") (test (object->string (random-state 9223372036854775807 9223372036854775807) :readable) "(random-state 9223372036854775807 9223372036854775807)")) (begin (test (substring (object->string (random-state 9223372036854775807 9223372036854775807)) 0 6) "#string (random-state 9223372036854775807 9223372036854775807) :readable) "#"))) (if full-test (let () (define (testlet e) (let ((data (cons #f #f))) (let ((iter (make-iterator e data))) (do ((val (iterate iter) (iterate iter))) ((iterator-at-end? iter)) (let ((sym (car val)) (fnc (cdr val))) (if (procedure? fnc) (let ((sig (catch #t (lambda () (procedure-signature fnc)) (lambda args #f))) (doc (catch #t (lambda () (procedure-documentation fnc)) (lambda args #f))) (src (catch #t (lambda () (procedure-source fnc)) (lambda args #f))) (ari (catch #t (lambda () (arity fnc)) (lambda args #f)))) (let ((lst (list sym fnc sig doc src ari))) (object->string lst) (object->string lst :readable))) (begin (object->string val) (object->string val :readable)))))))) (testlet (rootlet)) (require libc.scm) (testlet *libc*) (require libm.scm) (when (defined? '*libm*) (testlet *libm*)) (when (provided? 'gtk) (testlet *gtk*)) (require libgsl.scm) (when (defined? '*libgsl*) (testlet *libgsl*)) (require libgdbm.scm) (when (defined? '*libgdbm*) (testlet *libgdbm*)) (require libdl.scm) (when (defined? '*libdl*) (testlet *libdl*)) (require libutf8proc.scm) (when (defined? '*libutf8proc*) (testlet *libutf8proc*)))) ;;; -------------------------------------------------------------------------------- ;;; CONTROL OPS ;;; -------------------------------------------------------------------------------- (define control-ops (list lambda define quote if begin set! let let* letrec cond case and or do call/cc eval apply for-each map values call-with-values dynamic-wind)) (for-each (lambda (op) (if (not (eq? op op)) (format-logged #t "~A not eq? to itself?~%" op))) control-ops) (for-each (lambda (op) (if (not (eqv? op op)) (format-logged #t "~A not eqv? to itself?~%" op))) control-ops) (for-each (lambda (op) (if (not (equal? op op)) (format-logged #t "~A not equal? to itself?~%" op))) control-ops) (define question-ops (list boolean? eof-object? string? number? integer? real? rational? complex? char? list? vector? pair? null?)) (for-each (lambda (ques) (for-each (lambda (op) (if (ques op) (format-logged #t ";(~A ~A) returned #t?~%" ques op))) control-ops)) question-ops) (let ((unspecified (if #f #f))) (for-each (lambda (op) (if (op unspecified) (format-logged #t ";(~A #) returned #t?~%" op))) question-ops)) (for-each (lambda (s) (if (not (symbol? s)) (format-logged #t ";(symbol? ~A returned #f?~%" s))) '(+ - ... !.. $.+ %.- &.! *.: /:. <-. =. >. ?. ~. _. ^.)) ;;; -------------------------------------------------------------------------------- ;;; if ;;; -------------------------------------------------------------------------------- (test ((if #f + *) 3 4) 12) (test (if (> 3 2) 'yes 'no) 'yes) (test (if (> 2 3) 'yes 'no) 'no) (test (if (> 3 2) (- 3 2) (+ 3 2)) 1) (test (if (> 3 2) 1) 1) (test (if '() 1 2) 1) (test (if 't 1 2) 1) (test (if #t 1 2) 1) (test (if #() 1 2) 1) (test (if 1 2 3) 2) (test (if 0 2 3) 2) (test (if (list) 2 3) 2) (test (if "" 2 3) 2) (test (eq? (if #f #f) (if #f #f)) #t) ; I assume there's only one #! (test (if . (1 2)) 2) (test (if (if #f #f) #f #t) #f) (test (if 1/0 0 1) 0) (test (let ((a #t) (b #f) (c #t) (d #f)) (if (if (if (if d d c) d b) d a) 'a 'd)) 'a) (test (let ((a #t) (b #f) (c #t) (d #f)) (if a (if b (if c (if d d c) c) 'b) 'a)) 'b) (test (let ((a #t) (b #f) (c #t) (d #f)) (if b (if a (if d 'gad) 'gad) (if d 'gad 'a))) 'a) (let ((a #t)) (for-each (lambda (arg) (test (if a arg 'gad) arg)) (list "hi" -1 #\a 1 'a-symbol #(1 2 3) 3.14 3/4 1.0+1.0i #f #t (list 1 2 3) '(1 . 2)))) (let ((a #t)) (for-each (lambda (arg) (test (if (not a) 'gad arg) arg)) (list "hi" -1 #\a 1 'a-symbol #(1 2 3) 3.14 3/4 1.0+1.0i #f #t (list 1 2 3) '(1 . 2)))) (test (let ((ctr 0) (a #t)) (if a (let ((b ctr)) (set! ctr (+ ctr 1)) (list b ctr)) (let ((c ctr)) (set! ctr (+ ctr 100)) (list c ctr)))) (list 0 1)) (test (if if if if) if) (test (((if if if) if if) if if 'gad) if) (test (if if (if if if) if) if) (test ((car (list if)) #t 0 1) 0) (test (symbol->string 'if) "if") (test (if (and if (if if if)) if 'gad) if) (test (let ((ctr 0)) (if (let () (set! ctr (+ ctr 1)) (= ctr 1)) 0 1)) 0) (test (let ((ctr 0)) (if (let () (set! ctr (+ ctr 1)) (if (= ctr 1) (> 3 2) (< 3 2))) 0 1)) 0) (test ( if (> 3 2) 1 2) 1) (test (let ((alist (list (list map 1) (list car 2) (list if 3) (list do 4)))) (assoc if alist)) (list if 3)) (test (let ((alist (list (list map 1) (list car 2) (list if 3) (list do 4)))) (assv if alist)) (list if 3)) (test (let ((alist (list (list map 1) (list car 2) (list if 3) (list do 4)))) (assq if alist)) (list if 3)) (test (let ((alist (list map car if do))) (member if alist)) (list if do)) (test (let ((alist (list map car if do))) (memv if alist)) (list if do)) (test (let ((alist (list map car if do))) (memq if alist)) (list if do)) (test ((vector-ref (vector if) 0) #t 1 2) 1) (test ((vector-ref (make-vector 1 if) 0) #t 1 2) 1) (test ((if #t + -) 3 4) 7) (test (list (if 0 1 2)) (list 1)) (test ((car (list if map)) #f 1 2) 2) (test (let ((ctr 0)) (if (= ctr 0) (let () (set! ctr (+ ctr 1)) (if (= ctr 1) 2 3)) (let () (set! ctr (+ ctr 1)) (if (= ctr 1) 4 5)))) 2) (test (let ((x (cons 1 2))) (set-cdr! x x) (if x 1 2)) 1) (test (let ((ctr 0)) (if (let ((ctr 123)) (set! ctr (+ ctr 1)) (= ctr 124)) (let () (set! ctr (+ ctr 100)) ctr) (let () (set! ctr (+ ctr 1000)) ctr)) ctr) 100) (test (let () (if #t (define (hi a) a)) (hi 1)) 1) (test (let () (if #f (define (hi a) (+ a 1)) (define (hi a) a)) (hi 1)) 1) (test (let ((oddp (lambda (a) (not (even? a))))) (define (hi a) (if (a 123) (a 321))) (hi oddp)) #t) (test (let ((ctr 0)) (call/cc (lambda (exit) (if (> 3 2) (let () (exit ctr) (set! ctr 100) ctr) #f)))) 0) (test (let ((ctr 0)) (call/cc (lambda (exit) (if (< 3 2) #f (let () (exit ctr) (set! ctr 100) ctr))))) 0) (test (let ((ctr 0)) (call/cc (lambda (exit) (if (let () (exit ctr) (set! ctr 100) ctr) 123 321)))) 0) (test (let ((ctr 0)) (if (> 3 2) (call/cc (lambda (exit) (set! ctr (+ ctr 1)) (exit ctr))) #f) ctr) 1) (test (let ((ctr 0)) (do ((x 0 (+ x 1))) ((= x 12)) (if (> x 0) (if (> x 1) (if (> x 2) (if (> x 3) (if (> x 4) (if (> x 5) (if (> x 6) (if (> x 7) (if (> x 8) (if (> x 9) (if (> x 10) (set! ctr (+ ctr 1000)) (set! ctr (- ctr 1))) (set! ctr (- ctr 2))) (set! ctr (- ctr 3))) (set! ctr (- ctr 4))) (set! ctr (- ctr 5))) (set! ctr (- ctr 6))) (set! ctr (- ctr 7))) (set! ctr (- ctr 8))) (set! ctr (- ctr 9))) (set! ctr (- ctr 10))) (set! ctr (- ctr 11)))) ctr) 934) (test (let ((ctr 0)) (do ((x 0 (+ x 1))) ((= x 12)) (if (> x 0) (if (> x 1) (if (> x 2) (if (> x 3) (if (> x 4) (if (> x 5) (if (> x 6) (if (> x 7) (if (> x 8) (if (> x 9) (if (> x 10) (set! ctr (+ ctr 1000)) (set! ctr (- ctr 1))) (set! ctr (- ctr 2))) (set! ctr (- ctr 3))) (set! ctr (- ctr 4)))))))) (set! ctr (- ctr 10))) (set! ctr (- ctr 11)))) ctr) 969) (test (if #f) 'error) (test (if (< 2 3)) 'error) (test (if #f 1 2 3) 'error) (test (if 1 2 3 4) 'error) (test (if #f 1 else 2) 'error) (test (if) 'error) (test ('+ '1 '2) 'error) (test (if 1 . 2) 'error) (test (if 1 2 . 3) 'error) (test (if . 1) 'error) (test (if _no_var_ 1) 'error) (test (if (values) (values) (values) 1) 'error) (num-test (+ 1 (if #t (values 3 4) (values 5 6)) 2) 10) (let () (define (bad a) (if a 1 2 3)) (test (bad #f) 'error) (test (bad #t) 'error)) ;;; when (test (when #f #f) #) (test (when #t #f) #f) (test (when) 'error) (test (when #t) 'error) (test (when . #t) 'error) (test (when #t . 1) 'error) (test (when when when) when) (test (symbol->string 'when) "when") (test (when #t 1 2 3) 3) (test (when #t (define a 1) (+ a 1)) 2) (test ((when #t +) 2 3) 5) (test (when #t (when #f #f)) #) (test (+ (when #t (values 2 3))) 5) (test (when (when #t #t) 2) 2) (test (apply when '(< 2 3) '((+ 2 1))) 3) (let ((x 0)) (define (t1 a) (when a (set! x (+ x 1)) x)) (test (t1 #t) 1) (test (t1 #f) #) (test (t1 #t) 2)) ;;; unless (test (unless #t #f) #) (test (unless #f #f) #f) (test (unless) 'error) (test (unless #f) 'error) (test (unless . #t) 'error) (test (unless #f . 1) 'error) (test (unless (not unless) unless) unless) (test (symbol->string 'unless) "unless") (test (unless #f 1 2 3) 3) (test (unless #f (define a 1) (+ a 1)) 2) (test ((unless #f +) 2 3) 5) (test (unless #f (unless #t #f)) #) (test (+ (unless #f (values 2 3))) 5) (test (unless (unless #f #f) 2) 2) (test (apply unless '(= 2 3) '((+ 2 1))) 3) (let ((x 0)) (define (t1 a) (unless a (set! x (+ x 1)) x)) (test (t1 #f) 1) (test (t1 #t) #) (test (t1 #f) 2)) (test (when (unless (= 2 3) #t) 1) 1) ;;; -------------------------------------------------------------------------------- ;;; quote ;;; -------------------------------------------------------------------------------- (test (quote a) 'a) (test 'a (quote a)) (test '1 1) (test '1/4 1/4) (test '(+ 2 3) '(+ 2 3)) (test '"hi" "hi") (test '#\a #\a) (test '#f #f) (test '#t #t) (test '#b1 1) (when (not pure-s7) (test (= 1/2 '#e#b1e-1) #t)) (test '() '()) (test '(1 . 2) (cons 1 2)) (test #(1 2) #(1 2)) (test (+ '1 '2) 3) (test (+ '1 '2) '3) (test (+ ' 1 ' 2) ' 3) (test (char? '#\a) #t) (test (string? '"hi") #t) (test (boolean? '#t) #t) (test (if '#f 2 3) 3) (test (if '#t 2 3) 2) (test (vector? #()) #t) (test (char? (quote #\a)) #t) (test (string? (quote "hi")) #t) (test (boolean? (quote #t)) #t) (test (if (quote #f) 2 3) 3) (test (if (quote #t) 2 3) 2) (test (vector? (quote #())) #t) (test (+ (quote 1) (quote 2)) (quote 3)) (test (list? (quote ())) #t) (test (pair? (quote (1 . 2))) #t) (test (+ '1.0 '2.0) 3.0) (test (+ '1/2 '3/2) 2) (test (+ '1.0+1.0i '-2.0) -1.0+1.0i) (test (let ((hi 2)) (equal? hi 'hi)) #f) (test ''1 (quote (quote 1))) (test ''a (quote (quote a))) (test (symbol? '#f) #f) (test (symbol? '.') #t) (test ''quote (quote (quote quote))) (test (+ (cadr ''3) (cadadr '''4) (cadr (cadr (cadr ''''5)))) 12) (test (+ (cadr ' ' 3) (cadadr ' ' ' 4)) 7) (test (+ '#| a comment |#2 3) 5) (test (+ ' #| a comment |# 2 3) 5) (test (eq? lambda 'lambda) #f) (test (equal? + '+) #f) (test (eq? '() ()) #t) ; s7 specific (test (quote) 'error) (test (quote . -1) 'error) (test (quote 1 1) 'error) (test (quote . 1) 'error) (test (quote . (1 2)) 'error) (test (quote 1 . 2) 'error) (test (symbol? '1'1) #t) (test (apply '+ (list 1 2)) 'error) (test ((quote . #\h) (2 . #\i)) 'error) (test ((quote "hi") 1) #\i) (test (equal? '(1 2 '(3 4)) '(1 2 (3 4))) #f) (test (equal? '(1 2 '(3 4)) (quote (list 1 2 (quote (list 3 4))))) #f) (test (equal? (list-ref '(1 2 '(3 4)) 2) '(3 4)) #f) (test (equal? '(1 2 '(3 4)) (list 1 2 (list 'quote (list 3 4)))) #t) (test (equal? '(1 2 ''(3 4)) (list 1 2 (list 'quote (list 'quote (list 3 4))))) #t) (test (equal? '('3 4) (list (list 'quote 3) 4)) #t) (test (equal? '('3 4) (list 3 4)) #f) (test (equal? '('() 4) (list (list 'quote '()) 4)) #t) (test (equal? '('('4)) (list (list quote (list (list quote 4))))) #f) (test (equal? '('('4)) (list (list 'quote (list (list 'quote 4))))) #t) (test (equal? '('('4)) '((quote ((quote 4))))) #t) (test (equal? '1 ''1) #f) (test (equal? ''1 ''1) #t) (test (equal? '(1 '(1 . 2)) (list 1 (cons 1 2))) #f) (test (equal? #(1 #(2 3)) '#(1 '#(2 3))) #f) (test (equal? #(1) #('1)) #f) (test (equal? #(()) #('())) #f) (test (equal? cons 'cons) #f) (test (eqv? #\a (quote #\a)) #t) (test (eqv? 1 (quote 1)) #t) (test (eqv? 0 (quote 0)) #t) (test (equal? #(1 2 3) (quote #(1 2 3))) #t) (test (eqv? 3.14 (quote 3.14)) #t) (test (eqv? 3/4 (quote 3/4)) #t) (test (eqv? 1+1i (quote 1+1i)) #t) (test (eq? #f (quote #f)) #t) (test (eq? #t (quote #t)) #t) (test (eq? '() (quote ())) #t) (test (equal? '(1 2 3) (quote (1 2 3))) #t) (test (equal? '(1 . 2) (quote (1 . 2))) #t) (test ('abs -1) 'error) (test ('"hi" 0) #\h) (test (''begin 1) 'begin) (test (''let ((x 1)) ('set! x 3) x) 'error) (test ('and #f) 'error) (test ('and 1 #f) 'error) (test ('begin 1) 'error) (test ('cond ('define '#f)) 'error) (test ('let ((x 1)) ('set! x 3) x) 'error) (test ('let* () ('define x 3) x) 'error) (test ('or #f) 'error) (test ('quote 3) 'error) (test ((copy quote) 1) 1) (test ((copy quote) quote) 'quote) (test ((lambda (q) (let ((x 1)) (q x))) quote) 'x) ; these two are strange -- not sure about them, but Guile 1.8 is the same (test ((lambda (s c) (s c)) quote #f) 'c) ;;; ((lambda (lambda) (lambda (else))) quote) -> '(else) (test ((quote and) #f) 'error) (test ((values quote) 1) 1) ;; see also quasiquote ;;; -------------------------------------------------------------------------------- ;;; for-each ;;; -------------------------------------------------------------------------------- (test (let ((v (make-vector 5))) (for-each (lambda (i) (vector-set! v i (* i i))) '(0 1 2 3 4)) v) #(0 1 4 9 16)) (test (let ((ctr 0) (v (make-vector 5))) (for-each (lambda (i) (vector-set! v ctr (* i i)) (set! ctr (+ ctr 1))) '(0 1 2 3 4)) v) #(0 1 4 9 16)) (for-each (lambda (x) (display "for-each should not have called this")) ()) (test (let ((ctr 0)) (for-each (lambda (x y) (if (= x y) (set! ctr (+ ctr 1)))) '(1 2 3 4 5 6) '(2 3 3 4 7 6)) ctr) 3) (test (let ((ctr 0)) (for-each (lambda (x y z) (set! ctr (+ ctr x y z))) '(0 1) '(2 3) '(4 5)) ctr) 15) (test (let ((ctr 0)) (for-each (lambda (x y z) (set! ctr (+ ctr x y z))) '(1) '(3) '(5)) ctr) 9) (test (let ((ctr 0)) (for-each (lambda (x y z) (set! ctr (+ ctr x y z))) () () ()) ctr) 0) (test (let () (for-each abs '(1 2)) 1) 1) (test (let ((ctr 0)) (for-each (lambda (a) (for-each (lambda (b) (set! ctr (+ ctr 1))) '(0 1))) '(2 3 4)) ctr) 6) (test (let ((sum 0)) (for-each (lambda args (set! sum (+ sum (apply + args)))) '(0 1 2) '(2 1 0) '(3 4 5) '(5 4 3) '(6 7 8) '(8 7 6)) sum) 72) (test (let ((sum 0)) (for-each (lambda (a b . args) (set! sum (+ sum a b (apply + args)))) '(0 1 2) '(2 1 0) '(3 4 5) '(5 4 3) '(6 7 8) '(8 7 6)) sum) 72) (test (let ((sum 0)) (for-each (lambda (a b . args) (set! sum (+ sum a b (apply + args)))) '(0 1 2) '(2 1 0)) sum) 6) (test (let () (for-each + '(0 1 2) '(2 1 0)) 0) 0) (test (let () () ()) ()) (test (for-each + ()) #) (test (let ((sum 0)) (for-each (lambda a (set! sum (+ sum (apply + a)))) '(1 2 3)) sum) 6) (test (let ((sum 0)) (for-each (lambda* ((a 1)) (set! sum (+ sum a))) '(1 2 3)) sum) 6) (test (let ((sum 0)) (for-each (lambda (a . b) (set! sum (+ sum a))) '(1 2 3)) sum) 6) (test (let ((sum 0) (lst (list 1 2 3))) (for-each (lambda (a b c) (set! sum (+ sum a b c))) lst lst lst) sum) 18) (test (let ((sum 0) (lst (vector 1 2 3))) (for-each (lambda (a b c) (set! sum (+ sum a b c))) lst lst lst) sum) 18) (test (let ((v (vector 1 2 3))) (for-each vector-set! (list v v v) (list 0 1 2) (list 32 33 34)) v) #(32 33 34)) (test (let () (define (hi) (for-each (lambda (x) (+ x 1)) (list 1 2 3))) (hi) (hi)) #) (test (let ((d 0)) (for-each (let ((a 0)) (for-each (lambda (b) (set! a (+ a b))) (list 1 2)) (lambda (c) (set! d (+ d c a)))) (list 3 4 5)) d) 21) (test (let ((d 0)) (for-each (lambda (c) (let ((a 0)) (for-each (lambda (b) (set! a (+ a b))) (list 1 2)) (set! d (+ d a c)))) (list 3 4 5)) d) 21) (test (let ((ctr 0)) (let ((val (call/cc (lambda (exit) (for-each (lambda (a) (if (> a 3) (exit a)) (set! ctr (+ ctr 1))) (list 0 1 2 3 4 5)))))) (list ctr val))) (list 4 4)) (test (call-with-current-continuation (lambda (exit) (for-each (lambda (x) (if (negative? x) (exit x))) '(54 0 37 -3 245 19)) #t)) -3) (test (let ((ctr 0) (cont #f) (lst ())) (let ((val (call/cc (lambda (exit) (for-each (lambda (a) (if (and (not cont) (= a 2)) (exit a)) (if (and cont (= a 5)) (exit a)) (call/cc (lambda (c) (set! cont c))) (set! lst (cons ctr lst)) (set! ctr (+ ctr 1))) (list 0 1 2 3 4 5)))))) (if (< val 5) (cont)) (list ctr val lst))) (list 5 5 (list 4 3 2 1 0))) (test (let ((lst ())) (for-each (lambda (a) (set! lst (cons a lst))) (let ((lst ())) (for-each (lambda (b) (set! lst (cons b lst))) (list 1 2 3)) lst)) lst) (list 1 2 3)) ;;; this is an infinite loop? ; (let ((cont #f)) (call/cc (lambda (x) (set! cont x))) (for-each cont (list 1 2 3))) (test (call/cc (lambda (x) (for-each x (list 1 2 3)))) 1) ; map also gives 1 ... perhaps not actually legal? (let ((args (list 0 1 2)) (xx (list 4))) (define (it1) (for-each (lambda (x) (catch #t (lambda () (set-car! xx x)) (lambda any 'error))) (cdr args)) (car xx)) (test (it1) 2)) (let ((args (list 0 1 2)) (xx (list 4))) (define (it1) (for-each (lambda (x) (catch #t (lambda () (set-car! xx x)) (lambda any 'error)) (set-car! xx (+ (car xx) 32))) (cdr args)) (car xx)) (test (it1) 34)) (test (let ((ctr 0)) (for-each (lambda (x) (for-each (lambda (x y) (for-each (lambda (x y z) (set! ctr (+ x y z))) (list x (+ x 1)) (list y (+ y 2)) (list (+ x y) (- x y)))) (list (+ x 3) (+ x 4) (+ x 5)) (list (- x 3) (- x 4) (- x 5)))) (list 1 2 3 4 5)) ctr) 23) (for-each (lambda (a) (if (not (string=? a "hi")) (format-logged #t "yow: ~S" a))) (list "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi")) ;; now some mixed cases (test (let ((sum 0)) (for-each (lambda (n m) (set! sum (+ sum n m))) (list 1 2) (vector 3 4)) sum) 10) (test (let ((sum 0)) (for-each (lambda (n m) (set! sum (+ sum n m))) (vector 1 2) (list 3 4)) sum) 10) (test (let ((sum 0)) (for-each (lambda (n m p) (set! sum (+ sum n m))) (vector 1 2) (list 3 4) (vector 5 6)) sum) 10) (test (let ((sum 0)) (for-each (lambda (n m p) (if (char=? p #\x) (set! sum (+ sum n m)))) (vector 1 2 3) (list 3 4 5) "xax") sum) 12) (test (let* ((x (list (list 1 2 3))) (y (apply for-each abs x))) x) '((1 2 3))) (test (for-each (lambda (x) (display "for-each should not have called this"))) 'error) (test (for-each (lambda () 1) ()) 'error) ; # (test (let ((ctr 0)) (for-each (lambda (x y z) (set! ctr (+ ctr x y z))) '(1) '(3) ()) ctr) 0) (test (let ((ctr 0)) (for-each (lambda (x y z) (set! ctr (+ ctr x y z))) '(0 1) '(2 3) '(4 5 6)) ctr) 15) (test (for-each (lambda (a b) (+ a b)) (list 1)) 'error) (test (for-each (lambda (a b) (+ a b)) (list 1) (list)) #) (test (for-each (lambda (a b) (+ a b)) (list 1)) 'error) (test (for-each (lambda (a b) (+ a b)) (list 1) (list 2) (list 3)) 'error) (test (for-each (lambda (a b) (+ a b)) (list 1) (list 1 2)) #) (test (for-each (lambda (a b) (+ a b)) (list 1 2) (list 1)) #) (test (for-each (lambda (a b) (+ a b)) (list 1 2) (list 1 2 3)) #) (test (for-each (lambda (a b) (+ a b)) (list 1 2) (list 1)) #) (test (for-each (lambda (a b) (+ a b)) (list 1 2) (list 1 2) (list)) 'error) ; # (test (for-each (lambda (a b) (+ a b)) (list 1 2) (list 1 2) (list 1 2)) 'error) (test (for-each (lambda (a b) (+ a b)) (list 1 2) (cons 1 2)) #) (test (for-each (lambda (a b) (+ a b)) (cons 1 2) (list 1 2)) #) (test (for-each (lambda (a) (+ a 1)) (list 1) (list 2)) 'error) (test (for-each (lambda (a) (+ a 1)) #\a) 'error) (test (for-each (lambda (a) (+ a 1)) (cons 1 2)) #) (test (for-each (lambda (x) x) (openlet (inlet 'make-iterator (lambda (v) v)))) 'error) (test (for-each (lambda (x) x) (openlet (inlet 'make-iterator (let ((iterator? #t)) (lambda (v) v))))) 'error) (test (let ((sum 0)) (for-each (lambda (a b . args) (set! sum (+ sum a b (apply + args)))) '(0 1 2)) sum) 'error) (test (for-each (lambda (a) a) '(1 2 . 3)) #) (test (for-each #(0 1 2) #(2 1 0)) #) (for-each (lambda (arg) (test (for-each arg (list 1)) #)) (list (list 1 2 3) #(1 2 3) "hi")) (for-each (lambda (op) (test (for-each op ()) 'error) (test (for-each op "") 'error) (test (for-each op #(1 2 3) ()) 'error) (test (for-each op #() (list) (string)) 'error)) (list 0 () #f #t 'a-symbol :hi #\a # # # 0.0 1+i 1/2 1/0 0/0 *stdout* (current-input-port))) (for-each (lambda (arg) (test (for-each arg (list 1)) 'error)) (list -1 #\a 1 'a-symbol 3.14 3/4 1.0+1.0i #f #t)) (for-each (lambda (arg) (test (for-each (lambda (n m) n) (list 1) arg) 'error)) (list -1 #\a 1 'a-symbol 3.14 3/4 1.0+1.0i #f #t)) (for-each (lambda (arg) (test (for-each (lambda (a) a) arg) 'error)) (list -1 #\a 1 'a-symbol 3.14 3/4 1.0+1.0i #f #t)) (test (for-each) 'error) (test (for-each #t) 'error) (test (for-each map #t) 'error) (test (for-each abs () abs) 'error) (test (for-each abs '(1) #(1)) 'error) (test (let ((vals ())) (for-each for-each (list (lambda (a) (set! vals (cons (abs a) vals)))) (list (list -1 -2))) vals) '(2 1)) (test (let ((c #f)) (for-each (lambda (x) (set! c x)) "a") c) #\a) (test (let ((c #f)) (for-each (lambda (x) (set! c x)) "") c) #f) (test (let ((c #f)) (for-each (lambda (x) (set! c x)) (string #\null)) c) #\null) (test (let ((L (list 1 2 3 4 5)) (sum 0)) (for-each (lambda (x) (set-cdr! (cddr L) 5) (set! sum (+ sum x))) L) sum) 6) ; map (below) has more tests along this line (test (let ((f #f)) (for-each (lambda (a) (if (eq? a 'a) (set! f (lambda () a)))) '(a b c)) (f)) 'a) (test (let ((i 0) (f (make-vector 3))) (for-each (lambda (b) (vector-set! f i b) (set! i (+ i 1))) '(a b c)) f) #(a b c)) (test (let ((i 0) (f (make-vector 3)) (lst '(a b c))) (define (hi) (for-each (lambda (b) (vector-set! f i b) (set! i (+ i 1))) lst)) (hi) f) #(a b c)) (test (let ((i 0) (f (make-vector 3)) (lst '(a b c))) (define (hi) (for-each (lambda (b) (let () (vector-set! f i b) (set! i (+ i 1)))) lst)) (hi) f) #(a b c)) (test (let ((i 0) (f (make-vector 3)) (lst (list 1 2 3))) (define (hi) (for-each (lambda (b) (vector-set! f i (let ((b (+ b 1))) b)) (set! i (+ i 1))) lst)) (hi) f) #(2 3 4)) (test (let ((i 0) (f (make-vector 3)) (lst (list 1 2 3))) (define (hi) (for-each (lambda (b) (let ((b (+ b 1))) (vector-set! f i (let ((b (+ b 1))) b)) (set! i (+ i 1)))) lst)) (hi) f) #(3 4 5)) (test (let ((f #f)) (define (hi) (for-each (lambda (a) (if (eq? a 'a) (set! f (lambda () (let () a))))) '(a b c))) (hi) (f)) 'a) (test (let ((lst '((a b c) (1 2 3)))) (define (hi) (for-each (lambda (a) a) (apply values lst))) (hi)) 'error) (test (let ((lst ())) (for-each (lambda args (set! lst (cons args lst))) (values (list 1 2 3) '(4 5 6) (list 7 8 9))) lst) '((3 6 9) (2 5 8) (1 4 7))) (test (for-each ="") 'error) ; # (test (for-each =""=) 'error) (test (for-each = "" 123) 'error) (test (for-each = () 123) 'error) (test (for-each =()=) 'error) (test (for-each abs "") #) (test (for-each null? () #() "") 'error) ; # (test (for-each null? () #() 0 "") 'error) (test (for-each define '(a) '(3)) #) (test (let () (for-each define '(a b c) '(1 2 3)) (list a b c)) '(1 2 3)) (test (let () (for-each define '(first second third fourth) '(car cadr caddr cadddr)) (third '(1 2 3 4 5))) 3) (test (for-each '(()) #()) #) (test (for-each '(1 2 . 3) '(1 . 2)) #) (test (for-each '(()) ()) #) (test (for-each #2D((1 2) (3 4)) '(1)) #) (test (for-each "a\x00b" #(1 2)) #) (test (for-each #(1 (3)) '(1)) #) (test (for-each '((1 (2)) (((3) 4))) '(1)) #) (test (for-each "hi" '(1)) #) (test (for-each #() #()) 'error) ; # (test (for-each '(1 . 2) #()) #) (test (let ((ht (hash-table '(a . 1) '(b . 2)))) (for-each ht ht)) #) (test (let ((ht (hash-table '(a . 1) '(b . 2)))) (let ((sum 0)) (for-each (lambda (c) (set! sum (+ sum (cdr c)))) ht) sum)) 3) (test (let ((ht (hash-table '(a . 1) '(b . 2)))) (for-each ht '(a b))) #) (test (for-each ''2 '(1)) #) (let ((os (*s7* 'safety))) (set! (*s7* 'safety) 1) (let ((lst (list 1 2))) (set! (cdr (cdr lst)) lst) (test (for-each lst lst) #)) ; 'error (let ((lst (list 1 2))) (set! (cdr (cdr lst)) lst) (test (for-each #() lst) 'error)) (set! (*s7* 'safety) os)) (test (for-each 1 "hi" ()) 'error) (test (for-each 0 #() ()) 'error) (test (for-each #\a #(1 2) '(3 4) "") 'error) (test (for-each '2 ()) 'error) (test (let ((a 1) (b 2)) (for-each apply (list set! set!) '(a b) '((12) (32))) (list a b)) '(12 32)) (test (let ((a 1) (b 2) (c 3)) (for-each apply (make-list 3 set!) '(a b c) '((12) (32) (0))) (list a b c)) '(12 32 0)) (test (let ((a 1) (b 2) (c 3)) (for-each set! '(a b c) '(12 32 0)) (list a b c)) '(12 32 0)) (let () (define (hi) (let ((lst '(1 2 3))) (for-each (lambda (x) (catch #t (lambda () (if (defined? 'local-x) (format-logged #t ";for-each catch local env not cleared: ~A~%" local-x)) (define local-x x) local-x) (lambda args #f))) lst))) (hi) (hi)) (let ((x 0)) (let ((p1 (dilambda (lambda (a) (set! x (+ x a))) (lambda (a b) (+ a b))))) (for-each p1 '(1 2 3)) (test x 6)) (set! x 0) (for-each (lambda args (set! x (+ x (car args)))) '(1 2 3)) (test x 6) (set! x 0) (for-each (lambda* (a (b 2)) (set! x (+ x a))) '(1 2 3)) (test x 6) (set! x 0) (for-each (lambda args (set! x (+ x (car args) (cadr args)))) '(1 2 3) '(3 2 1)) (test x 12) (set! x 0) (for-each (lambda* (a (b 2)) (set! x (+ x a b))) '(1 2 3) '(3 2 1)) (test x 12) (set! x 0) (for-each (lambda* (a (b 2)) (set! x (+ x a b))) '(1 2 3)) (test x 12)) (test (let ((lst '(1 2 3)) (sum 0)) (define-macro (hi a) `(set! sum (+ sum (+ 1 ,a)))) (for-each hi lst) sum) 9) (test (let ((lst '(1 2 3)) (sum 0)) (define-bacro (hi a) `(set! sum (+ sum (+ 1 ,a)))) (for-each hi lst) sum) 9) (let ((sum 0)) (define (and-for-each func . args) ;; apply func to first of each arg, stopping if func returns #f (call-with-exit (lambda (quit) (apply for-each (lambda arglist (if (not (apply func arglist)) (quit #))) args)))) (test (and-for-each (lambda (arg) (and (not (null? arg)) (set! sum (+ sum arg)))) (list 1 2 () 3 4)) #) (test sum 3) (set! sum 0) (and-for-each (lambda (arg) (and (not (null? arg)) (set! sum (+ sum arg)))) (list 1 2 3 4)) (test sum 10) (set! sum 0) (and-for-each (lambda (arg1 arg2) (and (not (null? arg1)) (not (null? arg2)) (set! sum (+ sum arg1 arg2)))) (list 1 2 3 4) (list 5 6 () 7 8)) (test sum 14)) (define (and-map func . args) (call-with-exit (lambda (quit) (let ((result ())) (apply for-each (lambda arglist (let ((val (apply func arglist))) (if (not val) (quit (reverse result)) (set! result (cons val result))))) args) (reverse result))))) (test (and-map even? '(0 2 4 5 6)) '(#t #t #t)) (define (find-if f . args) (call-with-exit (lambda (return) (apply for-each (lambda main-args (if (apply f main-args) (apply return main-args))) args)))) (test (find-if even? #(1 3 5 2)) 2) (test (* (find-if > #(1 3 5 2) '(2 2 2 3))) 6) (define (position-if f . args) (let ((pos 0)) (call-with-exit (lambda (return) (apply for-each (lambda main-args (if (apply f main-args) (return pos)) (set! pos (+ pos 1))) args))))) (test (position-if even? #(1 3 5 2)) 3) (test (position-if > #(1 3 5 2) '(2 2 2 3)) 1) (let ((summer (lambda (v) (let ((sum 0)) (do ((i 0 (+ i 1))) ((= i 10) sum) (set! sum (+ sum ((v i))))))))) (test (let ((saved-args (make-vector 10)) (i 0)) (for-each (lambda (arg) (set! (saved-args i) arg) (set! i (+ i 1))) (list 0 1 2 3 4 5 6 7 8 9)) (set! (saved-args 0) 32) saved-args) #(32 1 2 3 4 5 6 7 8 9)) (test (let ((f #f)) (for-each (lambda (i) (let () (define (x) i) (if (= i 1) (set! f x)))) (list 0 1 2 3)) (f)) 1) (test (let ((saved-args (make-vector 10)) (i 0)) (for-each (lambda (arg) (set! (saved-args i) (lambda () arg)) (set! i (+ i 1))) (list 0 1 2 3 4 5 6 7 8 9)) (summer saved-args)) 45) (test (let ((saved-args (make-list 10)) (i 0)) (for-each (lambda (arg) (list-set! saved-args i (lambda () arg)) (set! i (+ i 1))) (list 0 1 2 3 4 5 6 7 8 9)) (summer saved-args)) 45) ;;; these are the same but use map (test (let ((saved-args (make-vector 10)) (i 0)) (map (lambda (arg) (set! (saved-args i) arg) (set! i (+ i 1))) (list 0 1 2 3 4 5 6 7 8 9)) (set! (saved-args 0) 32) saved-args) #(32 1 2 3 4 5 6 7 8 9)) (test (let ((f #f)) (map (lambda (i) (let () (define (x) i) (if (= i 1) (set! f x)))) (list 0 1 2 3)) (f)) 1) (test (let ((saved-args (make-vector 10)) (i 0)) (map (lambda (arg) (set! (saved-args i) (lambda () arg)) (set! i (+ i 1))) (list 0 1 2 3 4 5 6 7 8 9)) (summer saved-args)) 45) ;; and again but with named let (test (let ((saved-args (make-vector 10))) (let runner ((arg 0)) (set! (saved-args arg) arg) (if (< arg 9) (runner (+ arg 1)))) (set! (saved-args 0) 32) saved-args) #(32 1 2 3 4 5 6 7 8 9)) (test (let ((f #f)) (let runner ((i 0)) (let () (define (x) i) (if (= i 1) (set! f x)) (if (< i 3) (runner (+ i 1))))) (f)) 1) (test (let ((saved-args (make-vector 10))) (let runner ((i 0)) (set! (saved-args i) (lambda () i)) (if (< i 9) (runner (+ i 1)))) (summer saved-args)) 45) ;;; and recursion (test (let ((saved-args (make-vector 10))) (define (runner arg) (set! (saved-args arg) arg) (if (< arg 9) (runner (+ arg 1)))) (runner 0) (set! (saved-args 0) 32) saved-args) #(32 1 2 3 4 5 6 7 8 9)) (test (let ((f #f)) (define (runner i) (let () (define (x) i) (if (= i 1) (set! f x)) (if (< i 3) (runner (+ i 1))))) (runner 0) (f)) 1) (test (let ((saved-args (make-vector 10))) (define (runner i) (set! (saved-args i) (lambda () i)) (if (< i 9) (runner (+ i 1)))) (runner 0) (summer saved-args)) 45) ;;; and member/assoc (test (let ((saved-args (make-vector 10))) (member 'a '(0 1 2 3 4 5 6 7 8 9) (lambda (a b) (set! (saved-args b) (lambda () b)) #f)) (summer saved-args)) 45) (test (let ((saved-args (make-vector 10))) (assoc 'a '((0 b) (1 b) (2 b) (3 b) (4 b) (5 b) (6 b) (7 b) (8 b) (9 b)) (lambda (a b) (set! (saved-args b) (lambda () b)) #f)) (summer saved-args)) 45) (test (let ((saved-args (make-vector 10 #f))) (sort! '(3 2 1 4 6 5 9 8 7 0) (lambda (a b) (if (not (saved-args b)) (set! (saved-args b) (lambda () b))) (< a b))) (summer saved-args)) 45) ;;; and do which has never worked in this way #| (test (let ((saved-args (make-vector 10))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (saved-args i) (lambda () i))) (summer saved-args)) 45) |# ) ;;; -------------------------------------------------------------------------------- ;;; map ;;; -------------------------------------------------------------------------------- (test (map cadr '((a b) (d e) (g h))) '(b e h)) (test (map (lambda (n) (expt n n)) '(1 2 3 4 5)) '(1 4 27 256 3125)) (test (map + '(1 2 3) '(4 5 6)) '(5 7 9)) (test (apply vector (map (lambda (i) (* i i)) '(0 1 2 3 4))) #(0 1 4 9 16)) (map (lambda (x) (display "map should not have called this")) ()) (test (let ((ctr 0)) (map (lambda (x y) (if (= x y) (set! ctr (+ ctr 1))) ctr) '(1 2 3 4 5 6) '(2 3 3 4 7 6))) (list 0 0 1 2 2 3)) (test (let ((ctr 0)) (map (lambda (x y z) (set! ctr (+ ctr x y z)) ctr) '(0 1) '(2 3) '(4 5))) (list 6 15)) (test (let ((ctr 0)) (map (lambda (x y z) (set! ctr (+ ctr x y z)) ctr) '(1) '(3) '(5))) (list 9)) (test (let ((ctr 0)) (map (lambda (x y z) (set! ctr (+ ctr x y z)) ctr) () () ())) ()) (test (map (lambda (a b) (+ a b)) (list 1 2) (list 1 2)) (list 2 4)) (test (map abs '(1 -2)) (list 1 2)) (test (map + '(0 1 2) '(2 1 0) '(3 4 5) '(5 4 3) '(6 7 8) '(8 7 6)) (list 24 24 24)) (test (map (lambda (a) (cons a (map (lambda (b) (+ b 1)) (list 0 1 2)))) (list 3 4 5)) '((3 1 2 3) (4 1 2 3) (5 1 2 3))) (test (map (lambda (a) (+ a 1)) (map (lambda (b) (+ b 1)) (map (lambda (c) (+ c 1)) (list 0 1 2)))) '(3 4 5)) (test (map (lambda args (apply + args)) '(0 1 2) '(3 4 5) '(6 7 8) '(9 10 11) '(12 13 14)) '(30 35 40)) (test (map (lambda (a b . args) (+ a b (apply + args))) '(0 1 2) '(3 4 5) '(6 7 8) '(9 10 11) '(12 13 14)) '(30 35 40)) (test (map (lambda (a b . args) (+ a b (apply + args))) '(0 1 2) '(3 4 5)) '(3 5 7)) (test (map (lambda args args) '(1 2 3)) '((1) (2) (3))) (test (map + () ()) ()) (test (map + (#(#() #()) 1)) ()) (test (map + #(1) #(1) #(1)) '(3)) (test (map list '(a b c)) '((a) (b) (c))) (test (map (lambda (a b) (- a b)) (list 1 2) (vector 3 4)) '(-2 -2)) (test (map (lambda (a b c) (if (char=? a #\a) (+ b c) (- b c))) "axa" (list 1 2 3) (vector 4 5 6)) '(5 -3 9)) (test (map vector (memv 1 (list 1 2 3))) '(#(1) #(2) #(3))) (test (map append #(1 2 3)) '(1 2 3)) (test (map eval '((+ 1 2) (* 3 4))) '(3 12)) (test (map (map + (list 1 2 3)) (list 0 1 2)) '(1 2 3)) (test (let ((a #t) (b #f) (c #t)) (map when '(a b c) '(12 32 0))) '(12 # 0)) (test (let ((a #t) (b #f)) (map if '(a b) '(1 2) '(3 4))) '(1 4)) (test (let ((a #t) (b #f)) (map unless '(a b) '(1 2))) '(# 2)) (test (let ((a #t) (b #f)) (list (map set! '(a b) '(1 2)) a b)) '((1 2) 1 2)) (test (let ((a #t) (b #f)) (map begin '(a b))) '(#t #f)) (test (let () (map apply (map lambda '(a b) '((car a) (car b))) '((2) (3)))) '(2 3)) (test (let () (map apply (map lambda* '(((a 1)) ((b 2))) '(a b)) '((3) ()))) '(3 2)) (test (map + '(1 2 3) '(4 5 6) '(7 8 9)) '(12 15 18)) (test (let* ((x (list (list 1 2 3))) (y (apply map abs x))) (list x y)) '(((1 2 3)) (1 2 3))) (test (let* ((x (quote ((1 2) (3 4)))) (y (apply map ash x))) (list x y)) '(((1 2) (3 4)) (8 32))) (test (let* ((x (quote ((1 2 3) (4 5 6) (7 8 9)))) (y (apply map + x))) (list x y)) '(((1 2 3) (4 5 6) (7 8 9)) (12 15 18))) (test (map * (map + '(1 2 3) '(4 5 6)) '(1 2 3)) '(5 14 27)) (test (apply map * (apply map + '(1 2 3) '((4 5 6))) '((1 2 3))) '(5 14 27)) (test (let* ((x (lambda () '(1 2 3))) (y (apply map - (list (x))))) (x)) '(1 2 3)) ;(test (map car (list (list 0) (list (values)) (list 2))) (map (lambda (x) (car x)) (list (list 0) (list (values)) (list 2)))) (test (apply append (map list '((a . 1) (b . 2) #))) '((a . 1) (b . 2) #)) (test (apply append (map list '(a b # d))) '(a b # d)) (test (map values (vector 1 2 # 3)) '(1 2 # 3)) (test (let ((d 0)) (map (let ((a 0)) (map (lambda (b) (set! a (+ a b))) (list 1 2)) (lambda (c) (set! d (+ d c a)) d)) (list 3 4 5))) (list 6 13 21)) (test (let ((d 0)) (map (lambda (c) (let ((a 0)) (map (lambda (b) (set! a (+ a b))) (list 1 2)) (set! d (+ d a c)) d)) (list 3 4 5))) (list 6 13 21)) (test (let ((ctr 0)) (let ((val (call/cc (lambda (exit) (map (lambda (a) (if (> a 3) (exit a)) (set! ctr (+ ctr 1)) ctr) (list 0 1 2 3 4 5)))))) (list ctr val))) (list 4 4)) (test (call-with-current-continuation (lambda (exit) (map (lambda (x) (if (negative? x) (exit x)) x) '(54 0 37 -3 245 19)))) -3) (test (let ((ctr 0) (cont #f) (lst ())) (let ((val (call/cc (lambda (exit) (map (lambda (a) (if (and (not cont) (= a 2)) (exit a)) (if (and cont (= a 5)) (exit a)) (call/cc (lambda (c) (set! cont c))) (set! lst (cons ctr lst)) (set! ctr (+ ctr 1)) ctr) (list 0 1 2 3 4 5)))))) (if (< val 5) (cont)) (list ctr val lst))) (list 5 5 (list 4 3 2 1 0))) (let () (define (tree-add x lst) (define (tree-add-1 lst-1) (map (lambda (a) (if (pair? a) (tree-add-1 a) (+ a x))) lst-1)) (tree-add-1 lst)) (test (tree-add 12 '((1 2) ((3)) 4 5)) '((13 14) ((15)) 16 17))) (test (map (lambda (a) a) (map (lambda (b) b) (list 1 2 3))) (list 1 2 3)) (test (map cons '(a b c) '(() () ())) '((a) (b) (c))) (test (map (lambda a (list a)) '(1 2 3)) '(((1)) ((2)) ((3)))) (test (map (lambda* a (list a)) '(1 2 3)) '(((1)) ((2)) ((3)))) (test (map (lambda* (a) (list a)) '(1 2 3)) '((1) (2) (3))) (test (map (lambda* ((a 0)) (list a)) '(1 2 3)) '((1) (2) (3))) (test (map (lambda* ((a 0) (b 1)) (list a)) '(1 2 3)) '((1) (2) (3))) (test (map (lambda (a . b) (list a)) '(1 2 3)) '((1) (2) (3))) (test (map list '(1 2 3)) '((1) (2) (3))) (test (map (lambda a (apply list a)) '(1 2 3)) '((1) (2) (3))) (test (map (lambda a (apply values a)) '(1 2 3)) '(1 2 3)) (test (map (lambda a (values a)) '(1 2 3)) '((1) (2) (3))) (test (map (lambda a (append a)) '(1 2 3)) '((1) (2) (3))) (test (map values '(1 2 3)) '(1 2 3)) ;(test ((lambda* ('a) quote) 1) 1) (test (procedure? (car (map lambda '(()) '((1))))) #t) (test (procedure? (car (map lambda '((x)) '(((+ x 1)))))) #t) (test (map #(0 1 2) #(2 1 0)) '(2 1 0)) ;(test (map quasiquote '((quasiquote 1) (quasiquote 2))) '(1 2)) -- this has changed (12-May-14) (test (map (lambda (a b) (a b)) (map lambda '((x) (y) (z)) '((+ x x) (* y y) (expt z z))) (list 1 2 3)) '(2 4 27)) (test (map apply (map lambda '((x) (y) (z)) '((+ x x) (* y y) (expt z z))) '((1) (2) (3))) '(2 4 27)) (test (let () (define (add-some x) (define (add-some x) (+ x 2)) (+ x 1)) (map add-some '(1 2 3 4))) '(2 3 4 5)) ; from some CL website -- kinda ridiculous (test (map gcd #(1 2)) '(1 2)) (test (apply vector (map values #(1 2) #(3 4))) #(1 3 2 4)) (test (map values '(1 2 3) '(4 5 6) '(7 8 9)) '(1 4 7 2 5 8 3 6 9)) (test (map eval (list (+ 1 2) (+ 3 4))) '(3 7)) (test (map apply (list + - * /) (list 1 2 3 4) '((5) (6) (7) (8))) '(6 -4 21 1/2)) ;;; (let ((val ())) (list (map (lambda a (set! val (cons a val)) a) '(1 2 3)) val)) -> ((#3=(1) #2=(2) #1=(3)) (#1# #2# #3#)) (test (map if '(#f #f #t) '(0 1 2) '(3 4 5)) '(3 4 2)) (test (map apply (map lambda '(() (a) (a b)) '(1 (+ a 1) (+ a b 1))) '(() (2) (3 4))) '(1 3 8)) (test (map values (list 1 2 3) (list 4 5 6)) '(1 4 2 5 3 6)) (test (map map (list values) '((1 2)) '((3 4))) '((1 3 2 4))) (test (map values '((1 2)) '((3 4))) '((1 2) (3 4))) (test (map map (list map) (list (list values)) '(((1 2))) '(((3 4)))) '(((1 3 2 4)))) (test (map apply (list values) '(((1 2))) '(((3 4)))) (apply map values '(((1 2))) '(((3 4))))) ; ! (test (let ((x '((1 2)))) (eval `(apply apply values x)) (object->string x)) "((1 2))") ; not "((values 1 2))" -- 24-Aug-12 (test (map (lambda (x) x) #u8(255)) (list 255)) (let () (define (shuffle . args) (apply map values args)) (test (shuffle '(1 2 3) #(4 5 6) '(7 8 9)) '(1 4 7 2 5 8 3 6 9)) (test (shuffle '(1 2 3)) '(1 2 3)) (test (shuffle '(1 2 3) '(4)) '(1 4)) (test (shuffle '(1 2 3) ()) ()) ) (test (map list "hi") '((#\h) (#\i))) (test (map string "hi") '("h" "i")) (test (map vector "hi") '(#(#\h) #(#\i))) (test (map char-upcase "hi") '(#\H #\I)) (test (map append #(#() #())) '(#() #())) (test (map abs () abs) 'error) (test (map (lambda (x) (display "map should not have called this"))) 'error) (test (let ((ctr 0)) (map (lambda (x y z) (set! ctr (+ ctr x y z)) ctr) '(1) '(3) ())) ()) (test (let ((ctr 0)) (map (lambda (x y z) (set! ctr (+ ctr x y z))) '(0 1) '(2 3) '(4 5 6))) '(6 15)) (test (map (lambda (a b) (+ a b)) (list 1)) 'error) (test (map (lambda (a b) (+ a b)) (list 1) (list)) ()) (test (map (lambda (a b) (+ a b)) (list 1) (list 2)) (list 3)) (test (map (lambda (a b) (+ a b)) (list 1)) 'error) (test (map (lambda (a b) (+ a b)) (list 1) (list 2) (list 3)) 'error) (test (map (lambda (a b) (+ a b)) (list 1) (list 1 2)) '(2)) (test (map (lambda (a b) (+ a b)) (list 1 2) (list 1)) '(2)) (test (map (lambda (a b) (+ a b)) (list 1 2) (list 1 2 3)) '(2 4)) (test (map (lambda (a b) (+ a b)) (list 1 2) (list 1)) '(2)) (test (map (lambda (a b) (+ a b)) (list 1 2) (list 1 2) (list)) 'error) ; () (test (map (lambda (a b) (+ a b)) (list 1 2) (list 1 2) (list 1 2)) 'error) (test (map (lambda (a b) (+ a b)) (list 1 2) (cons 1 2)) '(2)) (test (map (lambda* (x . args) args) '(1 2 3)) '(() () ())) (test (map (lambda (x . args) args) '(1 2 3)) '(() () ())) (test (map (lambda* (x . args) (list x args)) '(1 2 3)) '((1 ()) (2 ()) (3 ()))) (test (map (lambda (x . args) (list x args)) '(1 2 3)) '((1 ()) (2 ()) (3 ()))) (test (map (lambda args args) '(1 2 3)) '((1) (2) (3))) (test (map (lambda* args args) '(1 2 3)) '((1) (2) (3))) (test (map (lambda (x y . args) args) '(1 2 3)) 'error) (test (map (lambda* (x y . args) args) '(1 2 3)) '(() () ())) ; all args are optional in lambda* (test (map (lambda (x y . args) args) '(1 2 3) '(4 5 6)) '(() () ())) (test (map (lambda* (x y . args) args) '(1 2 3) '(4 5 6)) '(() () ())) (test (map (lambda (x y . args) (list x y args)) '(1 2 3) '(4 5 6)) '((1 4 ()) (2 5 ()) (3 6 ()))) (test (map (lambda* (x y . args) (list x y args)) '(1 2 3) '(4 5 6)) '((1 4 ()) (2 5 ()) (3 6 ()))) (test (map (lambda (x y . args) (list x y args)) '(1 2 3) '(4 5 6) '(7 8 9)) '((1 4 (7)) (2 5 (8)) (3 6 (9)))) (test (map (lambda* (x y . args) (list x y args)) '(1 2 3) '(4 5 6) '(7 8 9)) '((1 4 (7)) (2 5 (8)) (3 6 (9)))) (test (map (lambda* (x y :rest args) (list x y args)) '(1 2 3) '(4 5 6) '(7 8 9)) '((1 4 (7)) (2 5 (8)) (3 6 (9)))) (test (map (lambda . (x y z 8)) '(1 2 3)) 'error) ; (y unbound) but other schemes ignore unused args (test (map (lambda . (x 8)) '(1 2)) '(8 8)) (test (map (lambda (a) (+ a 1)) (list 1) (list 2)) 'error) (test (map (lambda (a) (+ a 1)) #\a) 'error) (test (map (lambda (a) (+ a 1)) (cons 1 2)) '(2)) (test (map (lambda (a b . args) (+ a b (apply + args))) '(0 1 2)) 'error) (test (map (lambda (a) a) '(1 2 . 3)) '(1 2)) (test (map) 'error) (test (map #t) 'error) (test (map set-cdr! '(1 2 3)) 'error) (test (map (lambda (a b) (set-cdr! a b) b) '((1) (2) (3)) '(4 5 6)) '(4 5 6)) (test (let ((str "0123")) (set! (str 2) #\null) (map append str)) '(#\0 #\1 #\null #\3)) (test (map ((lambda () abs)) '(-1 -2 -3)) '(1 2 3)) (test (apply map ((lambda () abs)) (list (list -1 -2 -3))) '(1 2 3)) (test (apply apply map ((lambda () abs)) (list (list (list -1 -2 -3)))) '(1 2 3)) (test (apply apply apply map ((lambda () abs)) '((((-1 -2 -3))))) '(1 2 3)) (test (apply apply apply (list (list map abs (list (list -1 -2 -3))))) '(1 2 3)) (test (apply apply list 1 '((1 2) (3 4))) '(1 (1 2) 3 4)) (test (apply + (apply apply apply (list (list map abs (list (list -1 -2 -3)))))) 6) (test (apply (apply apply lambda '(a) '(((+ a 1)))) '(14)) 15) (test (let ((a 14)) (apply apply quasiquote '(((+ ,a 1))))) '(+ 14 1)) (test (apply map vector (values (list (vector 1 2)))) '(#(1) #(2))) (test (apply map string (list "123")) '("1" "2" "3")) (test (apply map string '("123" "456")) '("14" "25" "36")) (test (apply map list '((1 2) (3 4))) '((1 3) (2 4))) ; matrix transpose ;;; Is (apply apply func arglist) the same as (apply func (apply values arglist)), ;;; or (leaving aside '(())), (func (apply values (apply values arglist)))? (test (apply apply + '((1 2 3))) (apply + (apply values '((1 2 3))))) (test (apply apply + '((1 2 3))) (+ (apply values (apply values '((1 2 3)))))) (test (map string "123") '("1" "2" "3")) (test (map "hi" '(0 1)) '(#\h #\i)) (test (map (list 2 3) '(0 1)) '(2 3)) (test (map #(2 3) '(1 0)) '(3 2)) (for-each (lambda (arg) (test (map arg (list 1)) 'error)) (list -1 #\a 1 'a-symbol 3.14 3/4 1.0+1.0i #f #t)) (for-each (lambda (arg) (test (map (lambda (n m) n) (list 1) arg) 'error)) (list -1 #\a 1 'a-symbol 3.14 3/4 1.0+1.0i #f #t)) (for-each (lambda (arg) (test (map (lambda (a) a) arg) 'error)) (list -1 #\a 1 'a-symbol 3.14 3/4 1.0+1.0i #f #t)) (let () (define (concatenate . args) (apply append (map (lambda (arg) (map values arg)) args))) (test (concatenate "hi" #(#\h #\o)) '(#\h #\i #\h #\o)) (test (let ((lst (concatenate '(1 2) (let ((a 2) (b 3)) (curlet)) (hash-table* 'c 4)))) (or (equal? lst '(1 2 (b . 3) (a . 2) (c . 4))) (equal? lst '(1 2 (a . 2) (b . 3) (c . 4))))) #t)) (test (map (lambda (a1 a2 a3 a4 a5 a6 a7 a8 a9 a10) (max a1 a2 a3 a4 a5 a6 a7 a8 a9 a10)) (list 6 7 8 9 10) (list 21 22 23 24 25) (list 16 17 18 19 20) (list 11 12 13 14 15) (list 26 27 28 29 30) (list 1 2 3 4 5) (list 36 37 38 39 40) (list 41 42 43 44 45) (list 46 47 48 49 50) (list 31 32 33 34 35)) (list 46 47 48 49 50)) (test (map (lambda (a1 a2 a3 a4 a5 a6 a7 a8 a9 . a10) (apply max a1 a2 a3 a4 a5 a6 a7 a8 a9 a10)) (list 6 7 8 9 10) (list 21 22 23 24 25) (list 16 17 18 19 20) (list 11 12 13 14 15) (list 26 27 28 29 30) (list 1 2 3 4 5) (list 36 37 38 39 40) (list 41 42 43 44 45) (list 46 47 48 49 50) (list 31 32 33 34 35)) (list 46 47 48 49 50)) (test (map (lambda* (a1 a2 a3 . a10) (apply max a1 a2 a3 a10)) (list 6 7 8 9 10) (list 21 22 23 24 25) (list 16 17 18 19 20) (list 11 12 13 14 15) (list 26 27 28 29 30) (list 1 2 3 4 5) (list 36 37 38 39 40) (list 41 42 43 44 45) (list 46 47 48 49 50) (list 31 32 33 34 35)) (list 46 47 48 49 50)) (test (map (lambda args (apply max args)) (list 6 7 8 9 10) (list 21 22 23 24 25) (list 16 17 18 19 20) (list 11 12 13 14 15) (list 26 27 28 29 30) (list 1 2 3 4 5) (list 36 37 38 39 40) (list 41 42 43 44 45) (list 46 47 48 49 50) (list 31 32 33 34 35)) (list 46 47 48 49 50)) (test (map map (list abs) (list (list -1))) '((1))) (test (map map (list map) (list (list abs)) (list (list (list -1)))) '(((1)))) (test (map map (list map) (list (list map)) (list (list (list abs))) (list (list (list (list -1 -3))))) '((((1 3))))) (test (map map (list lcm) (vector #(1 2))) '((1 2))) (test (map map (list integer?) (list (vector "hi" 1 2/3))) '((#f #t #f))) (test (map map (list char-lower-case?) (list "hAba")) '((#t #f #t #t))) (test (map map (list char-lower-case? char-upper-case?) (list "hAba" "HacDf")) '((#t #f #t #t) (#t #f #f #t #f))) (test (map map (list + -) (list (list 1 2) (list 3 4))) '((1 2) (-3 -4))) (test (map map (list map map) (list (list + -) (list - +)) '(((1 2) (3 4)) ((4 5) (6 7)))) '(((1 2) (-3 -4)) ((-4 -5) (6 7)))) (test (map member (list 1 2 3) (list (list 1 2 3) (list 1 3 4) (list 3 4 5))) '((1 2 3) #f (3 4 5))) (test (map - (list 1 2 3) (list 1 2 3) (list 1 3 4) (list 3 4 5)) '(-4 -7 -9)) (test (map - (list 1 2 3) (list 1 2 3 'hi) (list 1 3 4 #\a "hi") (list 3 4 5)) '(-4 -7 -9)) (test (let () (define (mrec a b) (if (<= b 0) (list a) (map mrec (list a) (list (- b 1))))) (mrec (list 1 2) 5)) '(((((((1 2)))))))) (test (map append '(3/4)) '(3/4)) (test (map list '(1.5)) '((1.5))) (test (map vector '("hi")) '(#("hi"))) (test (map object->string '(:hi (1 2) (()))) '(":hi" "(1 2)" "(())")) (test (map map (list for-each) (list (list abs)) (list (list (list 1 2 3)))) '((#))) (test (map map (list vector) '((#(1 #\a (3))))) '((#(#(1 #\a (3)))))) (test (apply map map (list cdr) '((((1 2) (3 4 5))))) '(((2) (4 5)))) (test (apply map map (list char-upcase) '(("hi"))) '((#\H #\I))) (test (apply map map (list *) '(((1 2)) ((3 4 5)))) '((3 8))) ; (* 1 3) (* 2 4) (test (map apply (list map) (list map) (list (list *)) '((((1 2)) ((3 4 5))))) '(((3 8)))) (test (map map (list magnitude) '((1 . 2))) '((1))) ; magnitude is called once with arg 1 (test (map magnitude '(1 . 2)) '(1)) (test (map call/cc (list (lambda (r1) 1) (lambda (r2) (r2 2 3)) (lambda (r3) (values 4 5)))) '(1 2 3 4 5)) (test (map call/cc (list number? continuation?)) '(#f #t)) ;; from scheme working group (test (let ((L (list 1 2 3 4 5))) (map (lambda (x) (set-cdr! (cddr L) 5) x) L)) '(1 2 3)) (test (let ((L (list 1 2))) (map (lambda (x) (set! (cdr (cdr L)) L) x) L)) '(1)) ;'(1 2) (test (let ((L (list 1 2))) (object->string (map (lambda (x) (set! (car (cdr L)) L) x) L))) "(1 #1=(1 #1#))") ;;;(test (let ((L (list 1 2))) (map (lambda (x) (set-cdr! L L) x) L)) '(1 2)) ;?? this depends on when we cdr? infinite loop in Guile ;;;(let ((L (list 1 2 3 4 5))) (map (lambda (x) (set-cdr! L ()) x) L)) ; another similar case -- s7 doesn't notice what happened ;;; does that mean a GC during this map would leave us accessing freed memory? ;;; I think not because the original list is held by map (eval) locals that are protected ;;; we simply stepped on something after looking at it, similar to: (test (let ((L (list 1 2 3 4 5))) (map (lambda (x) (set-car! L 123) x) L)) '(1 2 3 4 5)) (test (let ((L (list 1 2 3 4 5))) (map (lambda (x) (set-cdr! (cddr L) (list 6 7 8)) x) L)) '(1 2 3 6 7 8)) ;;; we could do something similar with strings: (test (let ((S "12345")) (map (lambda (x) (set! (S 2) #\null) x) S)) '(#\1 #\2 #\null #\4 #\5)) ;;; (length S) is still 5 even with the embedded null (test (let ((L (list 1 2 3))) (map (lambda (x) (set! L (list 6 7 8)) x) L)) '(1 2 3)) (test (let ((L1 (list 1 2 3)) (L2 (list 4 5 6 7))) (map (lambda (x1 x2) (set-cdr! (cdr L1) ()) (cons x1 x2)) L1 L2)) '((1 . 4) (2 . 5))) (test (let ((L (list 1 2 3))) (map (lambda (x) (set-car! (cddr L) 32) x) L)) '(1 2 32)) ;;; should these notice the increased length?: (test (let ((L1 (list 1 2)) (L2 (list 6 7 8 9))) (map (lambda (x y) (set-cdr! (cdr L1) (list 10 11 12 13 14)) (cons x y)) L1 L2)) '((1 . 6) (2 . 7) (10 . 8) (11 . 9))) (test (let ((L1 (list 1)) (L2 (list 6 7 8))) (map (lambda (x y) (set-cdr! L1 (list 10 11 12)) (cons x y)) L1 L2)) '((1 . 6))) (test (let ((L1 (list 1 2))) (map (lambda (x) (set-cdr! (cdr L1) (list 10 11 12)) x) L1)) '(1 2 10 11 12)) ;;; a similar case could be made from hash-tables (test (let ((H (hash-table '(a . 3) '(b . 4)))) (pair? (map (lambda (x) (set! (H 'c) 32) (cdr x)) H))) #t) (test (let ((H (hash-table '(a . 3) '(b . 4)))) (let ((L (map (lambda (x) (set! (H 'b) 32) (cdr x)) H))) (or (equal? L '(3 32)) (equal? L '(4 3))))) #t) ;; in that 1st example, the set-cdr! is not the problem (map supposedly can treat its args in any order), ;; any set! will do: (test (let ((x 0)) (map (lambda (y) (set! x (+ x y)) x) '(1 2 3 4))) '(1 3 6 10)) (test (map begin '(1 2 3)) '(1 2 3)) (let ((funcs (map (lambda (lst) (eval `(lambda ,@lst))) '((() #f) ((arg) (+ arg 1)))))) (test ((car funcs)) #f) (test ((cadr funcs) 2) 3)) (test (map = #() =) 'error) (test (map ="") 'error) (test (map abs ()) ()) (test (map abs "") ()) (test (map abs "123" "") 'error) (test (map abs "123" "" #f) 'error) (test (map null? () #() "") 'error) (test (map null? () #() 0 "") 'error) (test (map '(()) #()) ()) (test (map '(1 2 . 3) '(1 . 2)) '(2)) (test (map '(()) ()) ()) (test (map #2D((1 2) (3 4)) '(1)) '(#(3 4))) (test (map "a\x00b" #(1 2)) '(#\null #\b)) (test (map #(1 (3)) '(1)) '((3))) (test (map '((1 (2)) (((3) 4))) '(1)) '((((3) 4)))) (test (map "hi" '(1)) '(#\i)) (test (map #() #()) 'error) (test (map '(1 . 2) #()) ()) (test (map ''2 '(1)) '(2)) (test (((map lambda '((x)) '(1 2 . 3)) 0) 0) 1) (test (((map lambda '(()) #(1 2)) 0)) 1) (test (((map lambda '((x)) '((+ x 1))) 0) 32) 33) (test (map #() ()) 'error) (test (map () ()) 'error) (test (map "" "") 'error) (test (map (let ((lst (list 1 2))) (set! (cdr (cdr lst)) lst) lst) '(0)) '(1)) (let ((lst (list 1 2)) (os (*s7* 'safety))) (set! (*s7* 'safety) 1) (set! (cdr (cdr lst)) lst) (test (map lst lst) '(2)) (set! (*s7* 'safety) os)) (test (map 1 "hi" ()) 'error) (test (map 0 #() ()) 'error) (test (map #\a #(1 2) '(3 4) "") 'error) (test (map or '(1 2 . 3)) '(1 2)) (test (map or "a\x00b") '(#\a #\null #\b)) (test (map cond '((1 2) (3 4))) '(2 4)) ; (cond (1 2)) -> 2 (test (map begin "hi") '(#\h #\i)) (test (map quote "hi") '(#\h #\i)) (test (map quote '(a b c)) '(a b c)) ; when are (map quote ...) and (map values ...) different? (test (map (begin #(1 (3))) '(1)) '((3))) (test (map (''2 0) ''2) 'error) (test (map (apply lambda 'a '(-1)) '((1 2))) '(-1)) (test (map (apply lambda 'a '(-1)) '(1 2)) '(-1 -1)) (test (map do '(()) '((1 2))) '(2)) ; (list 2) because it's map, not just do (test (map case '(1) '(((-1 1) 2) 3)) '(2)) (test (map let '(()) "a\x00b") '(#\a)) (test (map "hi" '(0 1) '(0 1)) 'error) (test (map '((1 2) (3 4)) '(0 1) '(0 1)) '(1 4)) (test (map #2d((1 2) (3 4)) '(0 1) '(0 1)) '(1 4)) (test (map #2d((1 2) (3 4)) '(0 1)) '(#(1 2) #(3 4))) (let ((os (*s7* 'safety))) (set! (*s7* 'safety) 1) (let ((lst (list 1 2))) (set! (cdr (cdr lst)) lst) (test (map (lambda (a) a) lst) '(1))) (let ((lst (list 1 2))) (set! (cdr (cdr lst)) lst) (test (map (lambda (a) a) lst lst) 'error)) (set! (*s7* 'safety) os)) (test (map "hi" ('((1)) 0)) '(#\i)) (test (map "hi" ('((1 0)) 0)) '(#\i #\h)) (test (let ((ht (hash-table '(a . 1) '(b . 2)))) (map ht ht)) '(#f #f)) (test (let ((ht (hash-table '(a . 1) '(b . 2)))) (let ((lst (map (lambda (c) (cdr c)) ht))) (or (equal? lst '(1 2)) (equal? lst '(2 1))))) #t) (test (let ((ht (hash-table '(a . 1) '(b . 2)))) (map ht '(a b))) '(1 2)) (test (map '((1 2) (3 4)) #(1) #(1)) '(4)) (test (map (quasiquote ((1 2) (3 4))) #(1) #(1 2)) '(4)) (let ((pws (dilambda (lambda (a) a) (lambda (a b) b)))) (test (map append pws) 'error) (test (map pws '(1 2 3)) '(1 2 3))) (test (map abs '(1 2 . 3)) '(1 2)) ;; ?? Guile says wrong type arg here (test (map + '(1) '(1 2 . 3)) '(2)) (test (map abs '(1 . 2)) '(1)) ;; problematic because last thing is completely ignored: (test (map abs '(1 . "hi")) '(1)) (test (map floor '(1 . "hi")) '(1)) (for-each (lambda (op) (test (map op ()) 'error) (test (map op "") 'error) (test (map op #() (list) (string)) 'error)) (list 0 () #f #t 'a-symbol :hi #\a # # # 0.0 1+i 1/2 1/0 0/0 *stdout* (current-input-port))) (test (map append (make-vector (list 2 0))) ()) (let ((p1 (dilambda (lambda (a) (+ a 1)) (lambda (a b) (+ a b))))) (test (map p1 '(1 2 3)) '(2 3 4))) (test (map (lambda args (+ (car args) 1)) '(1 2 3)) '(2 3 4)) (test (map (lambda* (a (b 2)) (+ a 1)) '(1 2 3)) '(2 3 4)) (let ((p1 (dilambda (lambda (a b) (+ a b)) (lambda (a b c) (+ a b c))))) (test (map p1 '(1 2 3) '(3 2 1)) '(4 4 4))) (test (map (lambda args (+ (car args) (cadr args))) '(1 2 3) '(3 2 1)) '(4 4 4)) (test (map (lambda* (a (b 2)) (+ a b)) '(1 2 3) '(3 2 1)) '(4 4 4)) (test (map (lambda* (a (b 2)) (+ a b)) '(1 2 3)) '(3 4 5)) (test (map (lambda* ((a 1) (b (map (lambda (c) (+ c 1)) (list 1 2)))) (+ a (apply + b))) (list 4 5 6)) '(9 10 11)) (test (let ((lst (list 0 1 2))) (map (lambda* ((a 1) (b (for-each (lambda (c) (set! (lst c) (+ (lst c) 1))) (list 0 1 2)))) a) lst)) '(0 2 4)) (test (let ((lst '(1 2 3))) (define-macro (hiho a) `(+ 1 ,a)) (map hiho lst)) '(2 3 4)) (test (let ((lst '(1 2 3))) (define-bacro (hiho a) `(+ 1 ,a)) (map hiho lst)) '(2 3 4)) (test (let ((lst '(1 2 3))) (define-macro (hiho a b) `(+ 1 ,a (* 2 ,b))) (map hiho lst lst)) '(4 7 10)) (test (let ((lst '(1 2 3))) (define-macro (hi1 a) `(+ 1 ,a)) (define-macro (hiho a b) `(+ 1 ,a (* 2 ,b))) (map hiho lst (map hi1 lst))) '(6 9 12)) (test (let ((lst '(1 2 3))) (define-macro (hiho a b) `(+ 1 ,a (* 2 ,b))) (map hiho lst (map (define-macro (hi1 a) `(+ 1 ,a)) lst))) '(6 9 12)) (test (let ((lst '(1 2 3))) (define-macro (hi a) `(+ 1 ,a)) (define-macro (ho b) `(+ 1 (hi ,b))) (map ho lst)) '(3 4 5)) (test (let ((lst '(1 2 3))) (define-macro* (hi a (b 2)) `(+ 1 ,a (* 2 ,b))) (map hi lst)) '(6 7 8)) (test (let ((lst '(1 2 3))) (define-macro* (hi a (b 2)) `(+ 1 ,a (* 2 ,b))) (map hi lst (map hi lst))) '(14 17 20)) (let () (define (hi) (map (lambda (a) (a 0)) (list (vector 1 2 3) (string #\a #\b #\c) (list 'e 'f 'g)))) (test (hi) '(1 #\a e))) (let ((ctr -1)) (apply begin (map (lambda (symbol) (set! ctr (+ ctr 1)) (list 'define symbol ctr)) '(_zero_ _one_ _two_))) (+ _zero_ _one_ _two_)) (let () (define (map-with-exit func . args) ;; func takes escape thunk, then args (let* ((result ()) (escape-tag (gensym)) (escape (lambda () (throw escape-tag)))) (catch escape-tag (lambda () (let ((len (apply max (map length args)))) (do ((ctr 0 (+ ctr 1))) ((= ctr len) (reverse result)) ; return the full result if no throw (let ((val (apply func escape (map (lambda (x) (x ctr)) args)))) (set! result (cons val result)))))) (lambda args (reverse result))))) ; if we catch escape-tag, return the partial result (define (truncate-if func lst) (map-with-exit (lambda (escape x) (if (func x) (escape) x)) lst)) (test (truncate-if even? #(1 3 5 -1 4 6 7 8)) '(1 3 5 -1)) (test (truncate-if negative? (truncate-if even? #(1 3 5 -1 4 6 7 8))) '(1 3 5)) ) ;;; this is testing the one-liner unsafe closure optimizations (test (let () (define (fib n) (if (< n 2) n (+ (fib (- n 1)) (fib (- n 2))))) (let ((x 0) (ctr -1)) (map (lambda (f) (let ((z 1)) (set! ctr (+ ctr 1)) (case ctr ((0 1 2 3) (f z)) ((4 5) (f z z)) ((6 7) (values (f (+ 1)) (f (+ 2))))))) (list (lambda (i) (set! x (list i))) (lambda (i) (set! x (list i)) (set! x (list (+ i 1)))) (vector 1 2 3) (list 3 2 1) (lambda (a b) (+ a b)) (lambda (a b) (+ a b) (+ a b a)) (lambda (a) (if (< a 2) a (+ (fib (- a 1)) (fib (- a 2))))) (lambda (a) (if (zero? a) a (list a)) (list (+ a 10))) )))) '((1) (2) 2 2 2 3 1 1 (11) (12))) ;;; more along the same lines (test (let () (define (f2 a) (+ a 1)) (define (f1 a) (f2 a)) (define (f2 a) (- a)) (f1 12)) -12) (test (let () (define (f2 a) (+ a 1)) (define (f1 a) (f2 a 1)) (define (f2 a b) (- a b)) (f1 12)) 11) (test (let () (define (f2 a) (+ a 1)) (define (f1 a) (f2 a)) (define (f2 a) (- a 1)) (f1 12)) 11) (test (let () (define* (f2 a) (+ a 1)) (define (f1 a) (f2 a)) (define* (f2 a) (- a)) (f1 12)) -12) (test (let () (define* (f2 a) (+ a 1)) (define (f1 a) (f2 a 1)) (define* (f2 a b) (- a b)) (f1 12)) 11) (test (let () (define* (f2 a) (+ a 1)) (define (f1 a) (f2 a)) (define* (f2 a) (- a 1)) (f1 12)) 11) (test (map symbol->value (let ((lst (list 'integer? 'boolean?))) (set-cdr! (cdr lst) lst) lst)) (list integer?)) ;;; I think this depends on when the list iterator notices the cycle #| ;;; this is from the r6rs comment site (let ((resume #f) (results ())) (set! results (cons (map (lambda (x) (call/cc (lambda (k) (if (not resume) (set! resume k)) 0))) '(#f #f)) results )) (display results) (newline) (if resume (let ((resume* resume)) (set! resume #f) (resume* 1)))) With a careful implementation of MAP, a new list is returned every time, so that the displayed results are ((0 0)) ((1 0) (0 0)) ((1 1) (1 0) (0 0)) in s7: ((0 0)) ((1 0) (0 0)) ((0 . #1=(1 1)) #1# (0 0)) |# ;; from Doug Hoyte, Let Over Lambda (let () (define (batcher n) (let* ((network ()) (tee (ceiling (log n 2))) (p (ash 1 (- tee 1)))) (do () ((= p 0) (reverse network)) (let ((q (ash 1 (- tee 1))) (r 0) (d p)) (do () ((= d 0)) (do ((i 0 (+ i 1))) ((= i (- n d))) (if (= (logand i p) r) (set! network (cons (list i (+ i d)) network)))) (set! d (- q p)) (set! q (ash q -1)) (set! r p))) (set! p (ash p -1))))) (define-macro (sortf comparator . places) (let ((tmp (gensym)) (net (batcher (length places)))) `(begin ,@(map (lambda (a b) `(if (,comparator ,a ,b) ; we're ignoring the fancy CL getf|setf business (let ((,tmp ,a)) ; I suppose if it's a list, get procedure-setter? (set! ,a ,b) (set! ,b ,tmp)))) (map (lambda (ab) (places (car ab))) net) (map (lambda (ab) (places (cadr ab))) net))))) (test (let ((a 1) (b 3) (c 0)) (sortf > a b c) (list a b c)) '(0 1 3)) (test (let ((a 1) (b 3) (c 0)) (sortf < a b c) (list a b c)) '(3 1 0)) (test (let ((v #(1 3 2))) (sortf > (v 0) (v 1) (v 2)) v) #(1 2 3))) ;;; fftf? (let () (define-macro (shiftf . places) (let ((tmp (gensym))) `(let ((,tmp ,(car places))) ,@(map (lambda (a b) `(set! ,a ,b)) places (cdr places)) ,tmp))) (define-macro (rotatef . places) (let ((tmp (gensym)) (last (car (list-tail places (- (length places) 1))))) `(let ((,tmp ,(car places))) ,@(map (lambda (a b) `(set! ,a ,b)) places (cdr places)) (set! ,last ,tmp)))) (test (let ((a 1) (b 2) (c 3)) (rotatef a b c) (list a b c)) '(2 3 1)) (test (let ((a 1) (b 2) (c 3)) (rotatef a b c) (rotatef a b c) (list a b c)) '(3 1 2)) (test (let ((v #(1 3 2))) (rotatef (v 0) (v 1) (v 2)) v) #(3 2 1)) (test (let ((a 1) (b 2) (c 3)) (let ((d (shiftf a b c (+ 3 2)))) (list a b c d))) '(2 3 5 1)) (test (let ((a 1) (b 2) (c 3)) (let ((d (shiftf a b c (shiftf a b c)))) (list a b c d))) '(3 3 2 1)) ;; this expands to: ;; (let ((a 1) (b 2) (c 3)) ;; (let (({gensym}-22 a)) ;; (set! a b) ;; (set! b c) ;; (set! c (let (({gensym}-23 a)) ;; (set! a b) ;; (set! b c) ;; (set! c (* 2 3)) ;; {gensym}-23)) ;; (list a b c {gensym}-22))) (test (let ((v #(1 3 2))) (let ((d (shiftf (v 0) (v 1) (v 2) (* 4 3)))) (list d v))) '(1 #(3 2 12)))) ;;; -------------------------------------------------------------------------------- ;;; iterate ;;; make-iterator ;;; iterator? ;;; iterator-sequence ;;; iterator-at-end? ;;; -------------------------------------------------------------------------------- (test (iterate) 'error) (test (iterator?) 'error) (test (iterator-sequence) 'error) (test (iterator-at-end?) 'error) (test (make-iterator) 'error) (test (make-iterator "hi" "ho") 'error) (test (iterator? "hi" "ho") 'error) (test (iterator-sequence "hi" "ho") 'error) (test (iterator-at-end? "hi" "ho") 'error) (test (iterate "hi" "ho") 'error) (for-each (lambda (arg) (if (iterator? arg) (format-logged #t ";~A: (iterator? ~A) -> #t?~%" (port-line-number) arg))) (list "hi" '(1 2) (integer->char 65) 1 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #\f (lambda (a) (+ a 1)) :hi (if #f #f) # #)) (for-each (lambda (arg) (test (iterate arg) 'error) (test (iterator-sequence arg) 'error) (test (iterate-at-end? arg) 'error)) (list "hi" '(1 2) (integer->char 65) 1 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #\f (lambda (a) (+ a 1)) :hi (if #f #f) # #)) (for-each (lambda (arg) (test (make-iterator arg) 'error) (test (make-iterator #(1 2) arg) 'error)) (list 1 'a-symbol quasiquote macroexpand 3.14 3/4 1.0+1.0i #\f :hi (if #f #f) # #)) (let ((str "12345")) (let ((s1 (make-iterator str))) (test (iterator? s1) #t) (test (iterator? str) #f) (test (make-iterator s1) 'error) (test (iterator-sequence s1) str) (test (iterator-at-end? s1) #f) (test (iterate s1) #\1) (test (iterate s1 s1) 'error) (test (object->string s1) "#") (test (s1) #\2) (test (list (s1) (s1) (s1)) (list #\3 #\4 #\5)) (test (s1) #) (test (iterator-at-end? s1) #t) (let ((s2 (copy s1))) (test (equal? s1 s2) #t) (test (morally-equal? s1 s2) #t) (test (eq? s1 s2) #f) (test (eqv? s1 s2) #f)))) (let ((str "")) (let ((s1 (make-iterator str))) (let ((s2 (copy s1))) (test (equal? s1 s2) #t) (test (iterator? s1) #t) (test (iterator-sequence s1) str) (test (s1) #) (test (iterator-at-end? s1) #t) (test (iterator? s1) #t)))) (let ((s1 (make-iterator "1234"))) (test (iterator? s1) #t) (test (s1) #\1)) (let ((str (vector #\1 #\2 #\3 #\4 #\5))) (let ((s1 (make-iterator str))) (let ((s2 (copy s1))) (test (equal? s1 s2) #t) (test (iterator? s1) #t) (test (iterator? str) #f) (test (make-iterator s1) 'error) (test (iterator-sequence s1) str) (test (iterate s1) #\1) (test (object->string s1) "#") (test (equal? s1 s2) #f) (s2) (test (equal? s1 s2) #t) (test (iterate s1 s1) 'error) (test (s1) #\2) (test (list (s1) (s1) (s1)) (list #\3 #\4 #\5)) (test (s1) #)))) (let ((str #())) (let ((s1 (make-iterator str))) (test (iterator? s1) #t) (test (iterator-sequence s1) str) (test (s1) #) (test (iterator-at-end? s1) #t) (test (iterator? s1) #t))) (let ((str #2d((1 2) (3 4)))) (let ((s1 (make-iterator str))) (test (iterator-at-end? s1) #f) (test (s1) 1) (test (iterate s1) 2) (test (s1) 3))) (let ((str (float-vector 1.0 2.0 3.0 4.0))) (let ((s1 (make-iterator str))) (test (iterator? s1) #t) (test (iterator? str) #f) (test (iterator-sequence s1) str) (test (iterate s1) 1.0) (test (s1) 2.0) (test (list (s1) (s1)) (list 3.0 4.0)) (test (s1) #))) (let ((str (float-vector))) (let ((s1 (make-iterator str))) (test (iterator? s1) #t) (test (iterator-sequence s1) str) (test (s1) #) (test (iterator-at-end? s1) #t) (test (iterator? s1) #t))) (let ((str (make-vector 4 0 #t))) (do ((i 1 (+ i 1))) ((= i 4)) (set! (str i) i)) (let ((s1 (make-iterator str))) (test (iterator? s1) #t) (test (iterator-sequence s1) str) (test (iterate s1) 0) (test (s1) 1) (test (list (s1) (s1) (s1)) (list 2 3 #)) (test (s1) #))) (let ((str (list 0 1 2 3))) (let ((s1 (make-iterator str))) (test (iterator? s1) #t) (test (iterator-sequence s1) str) (test (iterate s1) 0) (test (s1) 1) (test (s1 0) 'error) (test (iterate s1 0) 'error) (test (list (s1) (s1) (s1)) (list 2 3 #)) (test (s1) #))) (let ((str ())) (test (make-iterator str) 'error)) (let ((str '((1 2) (3 4)))) (let ((s1 (make-iterator str))) (test (s1) '(1 2)) (test (iterate s1) '(3 4)) (test (s1) #))) (let ((str (list 0 1))) (set! (cdr (cdr str)) str) (let ((s1 (make-iterator str))) (test (iterator? s1) #t) (test (iterator-sequence s1) str) (test (iterate s1) 0) (test (s1) 1) (test (s1) #))) (let ((p (cons #f #f)) (h (hash-table* 'a 1 'b 2))) (let ((iter (make-iterator h p))) (let ((v (iter))) (test (pair? v) #t) (test (eq? v p) #t) (test (pair? (memq (car v) '(a b))) #t) (set! v (iter)) (test (pair? v) #t) (test (eq? v p) #t) (test (pair? (memq (car v) '(a b))) #t)))) ;; hash-table and let dealt with elsewhere (when with-block (let ((b (block 0.0 1.0 2.0))) (let ((b1 (make-iterator b))) (test (iterator? b1) #t) ;(test (iterator-sequence b1) b) ; this is now a function (test (b1) 0.0) (test (iterate b1) 1.0) (test (list (b1) (b1)) '(2.0 #))))) (let ((c1 (let ((iterator? #t) (a 0)) (lambda () (set! a (+ a 1)))))) (let ((iter (make-iterator c1))) (test (iterate iter) 1) (test (iterator? c1) #t) (test (iterator? iter) #t) (test (eq? (iterator-sequence iter) c1) #t))) (let () (define c1 #f) (let ((length (lambda (x) 3)) (iterator? #t) (x 0)) (set! c1 (openlet (lambda () (let ((res (* x 2))) (set! x (+ x 1)) res))))) (let ((c2 (make-iterator c1))) (test (iterator? c2) #t) (test (iterator-sequence c2) c1) (test (c2) 0) (test (c2) 2) (test (c2) 4))) (let ((lst (list 1))) (set-cdr! lst lst) (let ((i (make-iterator lst))) (test (map values i) '(1)))) (let ((lst (list 1 2))) (set-cdr! (cdr lst) lst) (let ((i (make-iterator lst))) (test (map values i) '(1 2)))) (let ((lst (list 1 2 3))) (set-cdr! (cddr lst) lst) (let ((i (make-iterator lst))) (test (> (length (map values i)) 2) #t))) ; '(1 2 3) ideally (let ((lst (list 1 2 3 4))) (set-cdr! (cdddr lst) lst) (let ((i (make-iterator lst))) (test (> (length (map values i)) 3) #t))) ; '(1 2 3 4)? (test (format #f "~{~{[~A ~A]~}~}" (make-iterator (let ((lst '((a . 1) (b . 2) (c . 2))) (iterator? #t)) (lambda () (if (pair? lst) (let ((res (list (caar lst) (cdar lst)))) (set! lst (cdr lst)) res) #))))) "[a 1][b 2][c 2]") (let () (define (make-diagonal-iterator matrix) (if (or (= (length (vector-dimensions matrix)) 1) (< (length matrix) 2)) (make-iterator matrix) (make-iterator (let ((inds (length (vector-dimensions matrix))) (len (apply min (vector-dimensions matrix)))) (let ((length (lambda (obj) len)) (iterator? #t) (pos 0)) (openlet (lambda () (if (>= pos len) # (let ((res (apply matrix (make-list inds pos)))) (set! pos (+ pos 1)) res))))))))) (define v #2d((1 2 3 4) (5 6 7 8))) (let ((iv (make-diagonal-iterator v))) (let ((vals (map values iv))) (test vals '(1 6))))) (test (let ((iter (make-iterator "123"))) (map values iter)) '(#\1 #\2 #\3)) (test (let ((iter (make-iterator '(1 2 3))) (str "456") (vals ())) (for-each (lambda (x y) (set! vals (cons (cons y x) vals))) iter str) vals) '((#\6 . 3) (#\5 . 2) (#\4 . 1))) (let () (define* (make-full-let-iterator lt (stop (rootlet))) (if (eq? stop lt) (make-iterator #()) (let ((iter (make-iterator lt))) (if (eq? stop (outlet lt)) iter (letrec ((iterloop (let ((iterator? #t)) (lambda () (let ((result (iter))) (if (and (eof-object? result) (iterator-at-end? iter)) (if (eq? stop (outlet (iterator-sequence iter))) result (begin (set! iter (make-iterator (outlet (iterator-sequence iter)))) (iterloop))) (if (not (char=? ((symbol->string (car result)) 0) #\_)) result (iterloop)))))))) (make-iterator iterloop)))))) (let ((stop #f)) (set! stop (curlet)) (test (let ((a 1)) (map values (make-full-let-iterator (curlet) stop))) '((a . 1)))) (let ((stop #f)) (set! stop (curlet)) (test (let ((b 2)) (let ((a 1)) (map values (make-full-let-iterator (curlet) stop)))) '((a . 1) (b . 2)))) (let ((stop #f)) (set! stop (curlet)) (test (let ((b 2) (c 3)) (let () (let ((a 1)) (map values (make-full-let-iterator (curlet) stop))))) '((a . 1) (c . 3) (b . 2)))) ) (let () (define (make-range lo hi) (make-iterator (let ((iterator? #t) (now lo)) (lambda () (if (> now hi) # (let ((result now)) (set! now (+ now 1)) result)))))) (test (map values (make-range 4 8)) '(4 5 6 7 8))) (let () (define (make-input-iterator port) (make-iterator (let ((iterator? #t)) (lambda () (read-char port))))) (test (let ((p (open-input-string "12345"))) (let ((ip (make-input-iterator p))) (let ((res (map values ip))) (close-input-port p) res))) '(#\1 #\2 #\3 #\4 #\5))) (let () (define (make-input-iterator port) (make-iterator (let ((iterator? #t)) (define-macro (_m_) `(read-char ,port))))) (test (let ((p (open-input-string "12345"))) (let ((ip (make-input-iterator p))) (let ((res (map values ip))) (close-input-port p) res))) '(#\1 #\2 #\3 #\4 #\5))) (let ((iter (make-iterator (let ((iterator? #t) (pos 0)) (lambda () (if (< pos 3) (let ((p pos)) (set! pos (+ pos 1)) (values p (* p 2))) ; ?? maybe this is inconsistent? #)))))) (test (map values iter) '(0 0 1 2 2 4))) (let () (define (make-row-iterator v) (make-iterator (let ((iterator? #t) (col 0)) (lambda () (if (< col (car (vector-dimensions v))) (let ((c col)) (set! col (+ col 1)) (make-shared-vector v (cadr (vector-dimensions v)) (* c (cadr (vector-dimensions v))))) #))))) (let ((v #2d((0 1 2) (4 5 6)))) (let ((iter (make-row-iterator v))) (test (map values iter) '(#(0 1 2) #(4 5 6)))))) (let () (define (make-semi-complete-iterator obj) (make-iterator (let ((iters ()) (iter (make-iterator obj))) (define (iterloop) (let ((result (iter))) (if (length result) ; i.e. result is a sequence (begin (set! iters (cons iter iters)) (set! iter (make-iterator result)) result) ; this returns the sequence before we descend into it ; we could also call iterloop here to skip that step (if (eof-object? result) (if (null? iters) result ; return # (begin (set! iter (car iters)) (set! iters (cdr iters)) (iterloop))) result)))) (let ((iterator? #t)) (lambda () (iterloop)))))) (test (let ((v '(1 2 (4 5)))) (let ((i (make-semi-complete-iterator v))) (map values i))) '(1 2 (4 5) 4 5)) (test (let ((v #(1 2 (4 5)))) (let ((i (make-semi-complete-iterator v))) (map values i))) '(1 2 (4 5) 4 5)) (test (let ((v '((1 2 (4 5))))) (let ((i (make-semi-complete-iterator v))) (map values i))) '((1 2 (4 5)) 1 2 (4 5) 4 5)) (test (let ((v '(1 2 #(4 5)))) (let ((i (make-semi-complete-iterator v))) (map values i))) '(1 2 #(4 5) 4 5)) (test (let ((v '(1 2 #(4 5) ("67")))) (let ((i (make-semi-complete-iterator v))) (map values i))) '(1 2 #(4 5) 4 5 ("67") "67" #\6 #\7))) (let () (define (make-settable-iterator obj) (make-iterator (let ((iterator? #t) (pos 0)) (dilambda (lambda () (let ((res (obj pos))) (set! pos (+ pos 1)) res)) (lambda (val) (set! (obj pos) val)))))) (test (procedure? (procedure-setter (make-settable-iterator (vector 1 2 3)))) #t) (let ((v (vector 1 2 3))) (let ((iter (make-settable-iterator v))) (set! (iter) 32) (test v #(32 2 3))))) (let () (define (make-circular-iterator obj) (let ((iter (make-iterator obj))) (make-iterator (let ((iterator? #t)) (lambda () (let ((result (iter))) (if (eof-object? result) ((set! iter (make-iterator obj))) result))))))) (let ((iter (make-circular-iterator '(1 2 3))) (lst ())) (do ((i 0 (+ i 1))) ((= i 10) (test (reverse lst) '(1 2 3 1 2 3 1 2 3 1))) (set! lst (cons (iter) lst)))) (let ((iter (make-circular-iterator (hash-table* :a 1 :b 2))) (lst ())) (do ((i 0 (+ i 1))) ((= i 4) (test (let ((r (reverse lst))) (or (equal? r '((:a . 1) (:b . 2) (:a . 1) (:b . 2))) (equal? r '((:b . 2) (:a . 1) (:b . 2) (:a . 1))))) #t)) (set! lst (cons (iter) lst))))) (test (procedure-setter (make-iterator "123")) #f) (test (procedure-setter (make-iterator #(1))) #f) (test (procedure-setter (make-iterator '(1))) #f) (test (procedure-setter (make-iterator (float-vector pi))) #f) (test (copy (make-iterator '(1 2 3)) (vector 1)) 'error) (let () (define (make-file-iterator file) ;; reads a text file, returning one word at a time (let* ((port (open-input-file file)) (line (read-line port #t)) (pos -1) (new-pos 0) (eol (string #\space #\tab #\newline #\linefeed))) (define (next-word) (set! pos (char-position eol line (+ pos 1))) (if (not pos) (begin (set! pos -1) (set! new-pos 0) (set! line (read-line port #t)) (if (eof-object? line) (begin (close-input-port port) line) (next-word))) (if (= new-pos pos) (next-word) (let ((start (do ((k new-pos (+ k 1))) ((or (= k pos) (char-alphabetic? (string-ref line k)) (char-numeric? (string-ref line k))) k)))) (if (< start pos) (let ((end (do ((k (- pos 1) (- k 1))) ((or (= k start) (char-alphabetic? (string-ref line k)) (char-numeric? (string-ref line k))) (+ k 1))))) (set! new-pos (+ pos 1)) (if (> end start) (substring line start end) (next-word))) (next-word)))))) (make-iterator (let ((iterator? #t)) (lambda* (p) (if (eq? p :eof) (begin (close-input-port port) #) (next-word))))))) (define iter (make-file-iterator "s7.c")) (test (iter) "s7") (test (iter) "a") (test (iter) "Scheme") (test (iter) "interpreter") (test ((iterator-sequence iter) :eof) #) ) ;;; -------------------------------------------------------------------------------- ;;; do ;;; -------------------------------------------------------------------------------- (test (do () (#t 1)) 1) (for-each (lambda (arg) (test (do () (#t arg)) arg)) (list "hi" -1 #\a 1 'a-symbol #(1 2 3) 3.14 3/4 1.0+1.0i #f #t (list 1 2 3) '(1 . 2))) (for-each (lambda (arg) (test (do ((i arg)) (#t i)) arg)) (list "hi" -1 #\a 1 'a-symbol #(1 2 3) 3.14 3/4 1.0+1.0i #f #t (list 1 2 3) '(1 . 2))) (test (do ((i 0 (+ i 1))) ((= i 3) #f)) #f) (test (do ((i 0 (+ i 1))) ((= i 3) i)) 3) (test (do ((i 1/2 (+ i 1/8))) ((= i 2) i)) 2) (test (do ((i 1/2 (+ i 1/8))) ((> i 2) i)) 17/8) (test (do ((vec (make-vector 5)) (i 0 (+ i 1))) ((= i 5) vec) (vector-set! vec i i)) #(0 1 2 3 4)) (test (let ((x '(1 3 5 7 9))) (do ((x x (cdr x)) (sum 0 (+ sum (car x)))) ((null? x) sum))) 25) (test (do ((i 4 (- i 1)) (a 1 (* a i))) ((zero? i) a)) 24) (test (do ((i 2 (+ i 1))) ((> i 0) 123)) 123) (test (do () (() ()) ()) ()) (test (do () ('() ())) ()) (test (do () ('())) ()) (test (do () (())) ()) (test (do) 'error) (test (let ((x 0) (y 0)) (set! y (do () (#t (set! x 32) 123))) (list x y)) (list 32 123)) (test (let ((i 32)) (do ((i 0 (+ i 1)) (j i (+ j 1))) ((> j 33) i))) 2) (test (let ((i 0)) (do () ((> i 1)) (set! i (+ i 1))) i) 2) (test (let ((i 0) (j 0)) (do ((k #\a)) (#t i) (set! i (char->integer k)) (set! j (+ j i)))) 0) (test (let ((i 0) (j 0)) (do ((k #\a)) ((> i 1) j) (set! i (char->integer k)) (set! j (+ j i)))) (char->integer #\a)) (test (let ((x 0)) (do ((i 0 (+ i 2)) (j 1 (* j 2))) ((= i 4) x) (set! x (+ x i j)))) 5) (test (let ((sum 0)) (do ((lst '(1 2 3 4) (cdr lst))) ((null? lst) sum) (set! sum (+ sum (car lst))))) 10) (test (do ((i 0 (+ 1 i))) ((= i 4) (do ((i 0 (+ i 2))) ((= i 10) i)))) 10) (test (let ((i 0)) (do ((i 1 (+ i 1))) ((= i 3) i))) 3) (test (let ((j 0)) (do ((i 0 (+ i 1))) ((= i 3) (+ i j)) (do ((j 0 (+ j i 1))) ((> j 3) j)))) 3) (test (let ((add1 (lambda (a) (+ a 1)))) (do ((i 0 (add1 i))) ((= i 10) (add1 i)))) 11) (test (do ((i 0 (do ((j 0 (+ j 1))) ((= j i) (+ i 1))))) ((= i 3) i)) 3) (test (do ((i 0 (do ((i 0 (+ i 1))) ((= i 3) i)))) ((= i 3) i)) 3) (test (let ((i 123)) (do ((i 0 (+ i 1)) (j i (+ j i))) ((> j 200) i))) 13) (test (do ((i 0 (+ i 1))) ((> i 3) i) (set! i (* i 10))) 11) (test (do ((i 123) (j 0 (+ j i))) ((= j 246) i)) 123) (test (do ((i 123 i) (j 0 (+ j i))) ((= j 246) i)) 123) (test (do ((i 0 i)) (i i)) 0) (test (do ((i 1 i)) (i i (+ i i) (+ i i i))) 3) (test (do ((i 1)) (#t 1) 123) 1) (test (do ((i 0 (+ i j)) (j 0 (+ j 1))) (#t 1)) 1) (test (do ((i 0 j) (j 0 (+ j 1))) ((= j 3) i)) 2) ; uh, lessee... lexical scoping... (test (do ((i 1 j) (j 0 k) (k 0 m) (m 0 (+ i j k))) ((> m 10) (list i j k m))) (list 4 5 8 11)) (test (let ((i 10) (j 11) (k 12)) (do ((i i j) (j j k) (k k m) (m (+ i j k) (+ i j k))) ((> m 100) (list i j k m)))) (list 33 56 78 122)) (test (let ((x 0) (i 3)) (do ((i i (+ i 1))) ((= i 6)) (do ((i i (+ i 1))) ((= i 7)) (set! x (+ x i)))) x) 44) (test (let () (define (hi) (let ((x 0) (i 3)) (do ((i i (+ i 1))) ((= i 6)) (do ((i i (+ i 1))) ((= i 7)) (set! x (+ x i)))) x)) (hi)) 44) (test (do ((i 0 (let () (set! j 3) (+ i 1))) (j 0 (+ j 1))) ((= i 3) j)) 4) (test (let ((i 0)) (do () ((= i 3) (* i 2)) (set! i (+ i 1)))) 6) (num-test (do ((i 0 (- i 1))) ((= i -3) i)) -3) (num-test (do ((i 1/2 (+ i 1/2))) ((> i 2) i)) 5/2) (num-test (do ((i 0.0 (+ i 0.1))) ((>= i 0.9999) i)) 1.0) (num-test (do ((i 0 (- i 1/2))) ((< i -2) i)) -5/2) (num-test (do ((i 0+i (+ i 0+i))) ((> (magnitude i) 2) i)) 0+3i) (test (let ((x 0)) (do ((i 0 (+ i 1))) ((> i 4) x) (set! x (+ x i)) (set! i (+ i 0.5)))) 4.5) (test (do ((i 0 1)) ((> i 0) i)) 1) (test (do ((i 1.0+i 3/4)) ((= i 3/4) i)) 3/4) (test (do ((i 0 "hi")) ((not (number? i)) i)) "hi") (test (do ((i "hi" 1)) ((number? i) i)) 1) (test (do ((i #\c "hi")) ((string? i) i)) "hi") (test (do ((i #\c +)) ((not (char? i)) i)) +) (test (let ((j 1)) (do ((i 0 j)) ((= i j) i))) 1) (test (let ((j 1)) (do ((i 0 j)) ((= i j) i) (set! j 2))) 2) (test (do ((j 1 2) (i 0 j)) ((= i j) i)) 2) (test (let ((old+ +) (j 0)) (do ((i 0 (old+ i 1))) ((or (< i -3) (> i 3))) (set! old+ -) (set! j (+ j i))) j) -6) (test (do ((i 0 (case i ((0) 1) ((1) "hi")))) ((string? i) i)) "hi") (test (do ((i if +)) ((equal? i +) i)) +) (test (let ((k 0)) (do ((j 0 (+ j 1)) (i 0 ((if (= i 0) + -) i 1))) ((= j 5)) (set! k (+ k i))) k) 2) (test (let ((j -10) (k 0)) (do ((i 0 (+ i j)) (j 2)) ((> i 4) k) (set! k (+ k i)))) 6) (test (let ((j -10) (k 0)) (do ((i j (+ i j)) (j 2)) ((> i 4) k) (set! k (+ k i)))) -24) (test (let ((j -10) (k 0)) (do ((i j (+ i j)) (j 2)) ((= i j) k) (set! k (+ k i)))) -30) (test (let ((j -10) (k 0)) (do ((i j (+ i j)) (j 2)) ((= i j) j) (set! k (+ k i)))) 2) (test (let ((equal =)) (do ((i 0 (+ i 1))) ((equal i 3) i))) 3) (test (let ((equal =)) (do ((i 0 (+ i 1))) ((equal i 3) i) (set! equal >))) 4) (test (do ((equal =) (i 0 (+ i 1))) ((equal i 3) i)) 3) (test (do ((equal = >) (i 0 (+ i 1))) ((equal i 3) i)) 4) (test (do ((j 0) (plus + -) (i 0 (plus i 1))) ((= i -1) j) (set! j (+ j 1))) 3) (test (let ((expr `(+ i 1))) (do ((j 0) (i 0 (eval expr))) ((= i 3) j) (set! j (+ j 1)))) 3) (test (let ((expr `(+ i 1))) (do ((j 0) (i 0 (eval expr))) ((= i -3) j) (set! j (+ j 1)) (if (= j 3) (set! expr `(- i 1))))) 7) (test (do ((i 0 (+ i 1))) ((or (= i 12) (not (number? i)) (> (expt 2 i) 32)) (expt 2 i))) 64) (test (let ((k 0)) (do ((i 0 (+ i 1))) ((let () (set! k (+ k 1)) (set! i (+ i 1)) (> k 3)) i))) 7) (num-test (do ((i 0 (+ i 1))) ((> i 3) i) (set! i (* .9 i))) 3.439) (test (let ((v #(0 0 0))) (do ((i 0 (+ i 1))) ((= i 3) v) (set! (v i) i))) #(0 1 2)) (test (let ((v (list 0 0 0))) (do ((i 0 (+ i 1))) ((= i 3) v) (set! (v i) i))) '(0 1 2)) (test (let ((sum 0)) ((do ((i 0 (+ i 1))) ((> i 64) (lambda () sum)) (set! sum (+ sum i))))) 2080) (test (do ((lst () (cons i lst)) (i 0 (+ i 1))) ((> i 6) (reverse lst))) '(0 1 2 3 4 5 6)) (let () (define (d1) (do ((i 0 (+ i 1))) ((= i 10) i))) (define (d2) (do ((i 0 (+ i 1))) ((= i 10) i) i)) (test (d1) 10) (test (d1) (d2))) (test (do () (1)) ()) (test (do () (1 2)) 2) (test (do () '2) 2) (test (do () (())) ()) (test (let ((x (do ((i 0 (+ i 1))) (#t)))) x) ()) ; guile: # (test (let ((lst '(1 2 3)) (v (vector 0 0 0))) (do ((l lst (map (lambda (a) (+ a 1)) (cdr l)))) ((null? l)) (set! (v (- (length l) 1)) (apply + l))) v) #(5 7 6)) (test (do ((i 0 (+ i 1)) (j 1 2)) ((= i 4) j) (set! j 3)) 2) (test (let ((lst '(1 2 3))) (map (lambda (a) (let ((! 1)) (do ((i 0 (+ i 1)) (sum 0)) ((= i a) sum) (set! sum (+ sum a))))) lst)) '(1 4 9)) (test (let ((sum 0)) (do ((i_0 0 (+ i_0 0))(i_1 1 (+ i_1 1))(i_2 2 (+ i_2 2))(i_3 3 (+ i_3 3))(i_4 4 (+ i_4 4))(i_5 5 (+ i_5 5))(i_6 6 (+ i_6 6))(i_7 7 (+ i_7 7))(i_8 8 (+ i_8 8))(i_9 9 (+ i_9 9))(i_10 10 (+ i_10 10))(i_11 11 (+ i_11 11))(i_12 12 (+ i_12 12))(i_13 13 (+ i_13 13))(i_14 14 (+ i_14 14))(i_15 15 (+ i_15 15))(i_16 16 (+ i_16 16))(i_17 17 (+ i_17 17))(i_18 18 (+ i_18 18))(i_19 19 (+ i_19 19))(i_20 20 (+ i_20 20))(i_21 21 (+ i_21 21))(i_22 22 (+ i_22 22))(i_23 23 (+ i_23 23))(i_24 24 (+ i_24 24))(i_25 25 (+ i_25 25))(i_26 26 (+ i_26 26))(i_27 27 (+ i_27 27))(i_28 28 (+ i_28 28))(i_29 29 (+ i_29 29))(i_30 30 (+ i_30 30))(i_31 31 (+ i_31 31))(i_32 32 (+ i_32 32))(i_33 33 (+ i_33 33))(i_34 34 (+ i_34 34))(i_35 35 (+ i_35 35))(i_36 36 (+ i_36 36))(i_37 37 (+ i_37 37))(i_38 38 (+ i_38 38))(i_39 39 (+ i_39 39))) ((= i_1 10) sum) (set! sum (+ sum i_0 i_1 i_2 i_3 i_4 i_5 i_6 i_7 i_8 i_9 i_10 i_11 i_12 i_13 i_14 i_15 i_16 i_17 i_18 i_19 i_20 i_21 i_22 i_23 i_24 i_25 i_26 i_27 i_28 i_29 i_30 i_31 i_32 i_33 i_34 i_35 i_36 i_37 i_38 i_39)))) 35100) (let () (define (jtest) (let ((j 0)) (do ((i 0 (+ i 1))) ((= i 10) j) (if (= i 3) (set! j i))))) (test (jtest) 3)) (let () (define (jtest1) (let ((j (vector 0))) (do ((i 0 (+ i 1))) ((= i 10) (j 0)) (if (= i 3) (set! (j 0) i))))) (test (jtest1) 3)) (let () (define (jtest2) (let ((j (vector 0))) (do ((i 0 (+ i 1))) ((= i 10) (j 0)) (if (= i 3) (vector-set! j 0 i))))) (test (jtest2) 3)) (let () (define (jtest3) (let ((j (vector 0))) (do ((i 0 (+ i 1))) ((= i 10) (j 0)) (if (= i 3) (set! (vector-ref j 0) i))))) (test (jtest3) 3)) (let () (define (jtest4) (let ((j (list 0))) (do ((i 0 (+ i 1))) ((= i 10) (j 0)) (if (= i 3) (set! (j 0) i))))) (test (jtest4) 3)) (let () (define (jtest5) (let ((j (list 0))) (do ((i 0 (+ i 1))) ((= i 10) (j 0)) (if (= i 3) (set! (car j) i))))) (test (jtest5) 3)) (let () (define (jtest6) (let ((j (list 0))) (do ((i 0 (+ i 1))) ((= i 10) (j 0)) (if (= i 3) (set-car! j i))))) (test (jtest6) 3)) (let () (define (jtest7) (let ((j (list 0))) (do ((i 0 (+ i 1))) ((= i 10) (j 0)) (if (= i 3) (list-set! j 0 i))))) (test (jtest7) 3)) (let () (define (jtest8) (let ((j #f)) (do ((i 0 (+ i 1))) ((= i 10) (car j)) (if (= i 3) (set! j (list i)))))) (test (jtest8) 3)) (let () (define (jtest9) (let ((j #f)) (do ((i 0 (+ i 1))) ((= i 10) (j 0)) (if (= i 3) (set! j (vector i)))))) (test (jtest9) 3)) (let () (define (jtest10) (let ((j (cons 1 2))) (do ((i 0 (+ i 1))) ((= i 10) j) (if (= i 3) (set-car! j i))))) (test (jtest10) '(3 . 2))) (let () (define (jtest10a) (let ((j (cons 1 2))) (do ((i 0 (+ i 1))) ((= i 10) j) (if (= i 3) (list-set! j 0 i))))) (test (jtest10a) '(3 . 2))) (let () (define (jtest11) (let ((j (cons 1 2))) (do ((i 0 (+ i 1))) ((= i 10) j) (if (= i 3) (set! j (cons 0 i)))))) (test (jtest11) '(0 . 3))) ;; (let ((f #f)) (define (jtest12) (do ((i 0 (+ i 1))) ((= i 10) (f)) (if (= i 3) (set! f (lambda () i))))) (test (jtest12) 3)) ;; this lambda business is a separate issue (s7 returns 10 here) ;; do_all_x: (let () (define (f1) (let ((v (vector 0 0 0))) (do ((i 0 (+ i 1))) ((= i 3) v) (vector-set! v i (abs i))))) (test (f1) #(0 1 2))) (let () (define (f1) (let ((v (vector 0 0 0)) (x #f)) (do ((i 0 (+ i 1))) ((= i 3) (set! x v) x) (vector-set! v i (abs i))))) (test (f1) #(0 1 2))) (let () (define (f1) (let ((end 3) (v (vector 0 0 0))) (vector (do ((i 0 (+ i 1))) ((= i end)) (vector-set! v i (abs i))) v))) (test (f1) #(() #(0 1 2)))) (let () (define (f1) (let ((v (vector 0 0 0))) (do ((i 0 (+ i 1))) ((= i 3) v) (display i #f) (vector-set! v i (abs i))))) (test (f1) #(0 1 2))) (let () (define (f1) (let ((v (vector 0 0 0))) (do ((i 0 (+ i 1))) ((= i 0) v) (vector-set! v i (abs i))))) (test (f1) #(0 0 0))) (let () (define (safe-do-all-x) (let ((v1 (vector 1 2 3 4 5 6)) (v2 (vector 10 11 12 13 14 15))) (do ((i 0 (+ i 1))) ((= i 3)) (vector-set! v1 i (vector-ref v2 (+ i 1)))) v1)) (test (safe-do-all-x) (vector 11 12 13 4 5 6))) (test (let () (define (step-it a) (+ a 1)) (define (hi) (do ((i 0 (step-it i))) ((= i 3) i))) (hi) (hi)) 3) (test (call-with-exit (lambda (return) (do () () (if #t (return 123))))) 123) (test (call-with-exit (lambda (return) (do () (#f) (if #t (return 123))))) 123) (test (call-with-exit (lambda (return) (do ((i 0 (+ i 1))) () (if (= i 100) (return 123))))) 123) (test (call-with-exit (lambda (return) (do () ((return 123))))) 123) (test (call-with-exit (lambda (return) (do () (#t (return 123))))) 123) (test (do () (/ 0)) 0) (test (do () (+)) ()) (test (do () (+ +) *) +) (if with-bignums (begin (num-test (do ((i 24444516448431392447461 (+ i 1)) (j 0 (+ j 1))) ((>= i 24444516448431392447471) j)) 10) (num-test (do ((i 0 (+ i 24444516448431392447461)) (j 0 (+ j 1))) ((>= i 244445164484313924474610) j)) 10) (num-test (do ((i 4096 (* i 2)) (j 0 (+ j 1))) ((= i 4722366482869645213696) j)) 60))) (test (do ((i 9223372036854775805 (+ i 1)) (j 0 (+ j 1))) ((>= i 9223372036854775807) j)) 2) (test (do ((i -9223372036854775805 (- i 1)) (j 0 (+ j 1))) ((<= i -9223372036854775808) j)) 3) (num-test (do ((x (list 1 2 3) (cdr x)) (j -1)) ((null? x) j) (set! j (car x))) 3) (test (let ((x 0)) (do ((i 0 (+ i 1))) ((= i (do ((j 0 (+ j 1))) ((= j 2) (+ j 1))))) (set! x (+ x i))) x) 3) (test (let ((x 0)) (do ((i 0 (+ i (do ((j 0 (+ j 1))) ((= j 2) 1))))) ((= i 3) x) (set! x (+ x i)))) 3) (test (let ((x 0)) (do ((i 0 (+ i (do ((j 0 (+ j 1))) ((= j 2) 1))))) ((= i 3) (do ((j 0 (+ j 1))) ((= j 5) x) (set! x j))) (set! x (+ x i)))) 4) (test (call-with-exit (lambda (exit) (do ((i 0 (+ i 1))) ((= i 100) i) (if (= i 2) (exit 321))))) 321) (test (call-with-exit (lambda (exit) (do ((i 0 (if (= i 3) (exit 321) (+ i 1)))) ((= i 100) i)))) 321) (test (call-with-exit (lambda (exit) (do ((i 0 (+ i 1))) ((= i 10) (exit 321))))) 321) (test (call-with-exit (lambda (exit) (do ((i 0 (+ i 1))) ((= i 10) i) (if (= i -2) (exit 321))))) 10) (test (do ((x 0 (+ x 1)) (y 0 (call/cc (lambda (c) c)))) ((> x 5) x) #f) 6) (test (let ((happy #f)) (do ((i 0 (+ i 1))) (happy happy) (if (> i 3) (set! happy i)))) 4) (test (+ (do ((i 0 (+ i 1))) ((= i 3) i)) (do ((j 0 (+ j 1))) ((= j 4) j))) 7) (test (do ((i (if #f #f))) (i i)) (if #f #f)) (test (do ((i (if #f #f)) (j #f i)) (j j)) (if #f #f)) (test (let ((cont #f) (j 0) (k 0)) (call/cc (lambda (exit) (do ((i 0 (+ i 1))) ((= i 100) i) (set! j i) (call/cc (lambda (r) (set! cont r))) (if (= j 2) (exit)) (set! k i)))) (if (= j 2) (begin (set! j 3) (cont)) (list j k))) (list 99 99)) (test (call/cc (lambda (r) (do () (#f) (r 1)))) 1) (test (let ((hi (lambda (x) (+ x 1)))) (do ((i 0 (hi i))) ((= i 3) i))) 3) (test (do ((i 0 (+ i 1))) (list 1) ((= i 3) #t)) 1) ; a typo originally -- Guile and Gauche are happy with it (test (do () (1 2) 3) 2) ;; from sacla tests (test (let ((rev (lambda (list) (do ((x list (cdr x)) (reverse () (cons (car x) reverse))) ((null? x) reverse))))) (and (null? (rev ())) (equal? (rev '(0 1 2 3 4)) '(4 3 2 1 0)))) #t) (test (let ((nrev (lambda (list) (do ((f1st (if (null? list) () (cdr list)) (if (null? f1st) () (cdr f1st))) (s2nd list f1st) (t3rd () s2nd)) ((null? s2nd) t3rd) (set-cdr! s2nd t3rd))))) (and (null? (nrev ())) (equal? (nrev (list 0 1 2 3 4)) '(4 3 2 1 0)))) #t) (test (do ((temp-one 1 (+ temp-one 1)) (temp-two 0 (- temp-two 1))) ((> (- temp-one temp-two) 5) temp-one)) 4) (test (do ((temp-one 1 (+ temp-one 1)) (temp-two 0 (+ temp-one 1))) ((= 3 temp-two) temp-one)) 3) (let ((vec (vector 0 1 2 3 4 5 6 7 8 9))) (test (do ((i 0 (+ 1 i)) (n #f) (j 9 (- j 1))) ((>= i j) vec) (set! n (vector-ref vec i)) (vector-set! vec i (vector-ref vec j)) (vector-set! vec j n)) #(9 8 7 6 5 4 3 2 1 0))) (test (do ((i 0 (+ i 1))) (#t i) (error "do evaluated its body?")) 0) (test (do '() (#t 1)) 'error) (test (do . 1) 'error) (test (do ((i i i)) (i i)) 'error) (test (do ((i 0 i (+ i 1))) (i i)) 'error) (test (do ((i)) (#t i)) 'error) (test (do ((i 0 (+ i 1))) #t) 'error) (test (do 123 (#t 1)) 'error) (test (do ((i 1)) (#t . 1) 1) 'error) (test (do ((i 1) . 1) (#t 1) 1) 'error) (test (do ((i 1) ()) (= i 1)) 'error) (test (do ((i 0 . 1)) ((= i 1)) i) 'error) (test (do ((i 0 (+ i 1))) ((= i 3)) (set! i "hiho")) 'error) (test (let ((do+ +)) (do ((i 0 (do+ i 1))) ((= i 3)) (set! do+ abs))) 'error) (test (do () . 1) 'error) (test (do ((i)) (1 2)) 'error) (test (do (((i))) (1 2)) 'error) (test (do ((i 1) ((j))) (1 2)) 'error) (test (do (((1))) (1 2)) 'error) (test (do ((pi 1 2)) (#t pi)) 'error) (test (do ((1+i 2 3)) (#t #t)) 'error) (test (do ((1.2 2 3)) (#t #t)) 'error) (test (do (((1 . 2) "hi" (1 2))) (#t 1)) 'error) (test (do ((() () ())) (#t #t)) 'error) (test (do (("hi" "hi")) ("hi")) 'error) (test (do ((:hi 1 2)) (#t :hi)) 'error) (test (do ((i 0 (abs ()))) ((not (= i 0)) i)) 'error) (test (do ((i j) (j i)) (i i)) 'error) (test (do ((i 0 0) . ((j 0 j))) (#t j)) 0) (test (do ((i 0 1 . 2)) (#t i)) 'error) (test (do ((i 0 "hi")) ((string? i) . i)) 'error) (test (do ((i 0 j)) (#t i)) 0) ; guile also -- (do ((i 0 (abs "hi"))) (#t i)) etc (do ((i 0 1)) (#t i) (abs "hi")) (test (do ((i 0 1) . (j 0 0)) ((= i 1) i) i) 'error) (test (do ((i 0 1) ((j 0 0)) ((= i 1) i)) i) 'error) (test (do #f) 'error) (test (do () #f) 'error) (test (do () #()) 'error) (test (do '((i 1)) ()) 'error) (test (do #() ()) 'error) (test (do ((#() 1)) ()) 'error) (test (do ((1)) ()) 'error) (test (do ((i 1) . #(a 1)) ()) 'error) (test (do () ((3 4))) 'error) (test (do ((i 1)) '()) ()) (test (do . (() (#t 1))) 1) (test (do () . ((#t 1))) 1) (test (do ((i 1 (+ i 1))) . ((() . ()))) ()) (test (do ((a . 1) (b . 2)) () a) 'error) (let () (define (d1) (do ((i 0 (+ i 1))) ((= i 3) . i) (display i))) (test (d1) 'error)) (let () (define (d1) (do ((i 0 (+ i 1))) ((= i 3) i) . i)) (test (d1) 'error)) (test (define-constant) 'error) (test (define-constant _asdf_ 2 3) 'error) (test (define-constant pi 3) 'error) ; except in Utah (test (define-constant pi . 3) 'error) (define-constant __do_step_var_check__ 1) (test (do ((__do_step_var_check__ 2 3)) (#t #t)) 'error) (test (let ((__do_step_var_check__ 2)) 1) 'error) (test (let () (set! __do_step_var_check__ 2)) 'error) (test (let ((__a_var__ 123)) (set! (symbol-access '__a_var__) (lambda (val sym) 0)) (set! __a_var__ -1123)) 0) (test (do ((hi #3d(((1 2) (3 4)) ((5 6) (7 8))) (hi 1))) ((equal? hi 8) hi)) 8) (test (do ((i 0 ('((1 2) (3 4)) 0 1))) ((not (= i 0)) i)) 2) (test (do () (#t (+ 1 2 3))) 6) (test (do ((f + *) (j 1 (+ j 1))) ((= j 2) (apply f (list j j)))) 4) (test (do ((f lambda) (j 1 (+ j 1))) ((= j 2) ((f (a) (+ a j)) 3))) 5) (let () (define-macro (add-1 x) `(+ ,x 1)) (test (do ((i 0 (add-1 i))) ((= i 3) i)) 3) (test (do ((i 0 (add-1 i))) ((= i 3) (add-1 i))) 4)) (test (let ((j #f)) (do ((i 0 (let ((x 0)) (dynamic-wind (lambda () (set! x i)) (lambda () (+ x 1)) (lambda () (if (> x 3) (set! j #t))))))) (j i))) 5) (test (let ((j 0)) (do ((i 0 (eval-string "(+ j 1)"))) ((= i 4) j) (set! j i))) 3) (test (do ((i (do ((i (do ((i 0 (+ i 1))) ((= i 3) (+ i 1))) (do ((j 0 (+ j 1))) ((= j 3)) (+ j i)))) ((> (do ((k 0 (+ k 1))) ((= k 2) (* k 4))) (do ((n 0 (+ n 1))) ((= n 3) n))) (do ((m 0 (+ m 1))) ((= m 3) (+ m i))))) i)) ((> i 6) i)) 7) (test (let ((L (list 1 2))) (do ((sum 0 (+ sum (car lst))) (i 0 (+ i 1)) (lst L (cdr lst))) ((or (null? lst) (> i 10)) sum) (set-cdr! (cdr L) L))) 16) ;;; optimizer checks (num-test (let ((x 0)) (do ((i 1.0 (+ i 1))) ((> i 3)) (set! x (+ x i))) x) 6.0) (num-test (let ((x 0)) (do ((i 1 4)) ((> i 3)) (set! x (+ x i))) x) 1) (num-test (let ((x 0)) (do ((i 1 ((if #t + -) i 1))) ((> i 3)) (set! x (+ x i))) x) 6) (num-test (let ((x 0)) (do ((i 1 (+))) ((> i 0)) (set! x (+ x i))) x) 0) (num-test (let ((x 0)) (do ((i 1 (+ 1))) ((> i 0)) (set! x (+ x i))) x) 0) (num-test (let ((x 0)) (do ((i 1 (+ 1 i 2))) ((> i 10)) (set! x (+ x i))) x) 22) (num-test (let ((x 0)) (do ((i 1 (+ 1.0 i))) ((> i 3)) (set! x (+ x i))) x) 6.0) (num-test (let ((x 0)) (do ((i 1 (+ 1 pi))) ((> i 2)) (set! x (+ x i))) x) 1) (num-test (do ((i 0 (+ 1 pi))) ((> i 2) i)) (+ pi 1.0)) (num-test (let ((x 0)) (do ((i 0 (+ i 8796093022208))) ((> i 0)) (set! x (+ x i))) x) 0) (num-test (let ((x 0)) (do ((i 0 (+ i 8796093022208))) ((> i 17592186044416)) (set! x (+ x i))) x) (+ (expt 2 44) (expt 2 43))) (num-test (let ((x 0)) (do ((i 1 (* i 2))) ((> i 10)) (set! x (+ x i))) x) 15) (num-test (do ((i 0 (+ i 1))) ((> i 2) i) (set! i (+ i 3.0))) 4.0) (num-test (let ((x 0)) (let ((add +)) (do ((i 0 (add i 1))) ((< i -2)) (set! add -) (set! x (+ x i)))) x) -3) (num-test (let ((equals =) (x 0)) (do ((i 0 (+ i 1))) ((equals i 3) x) (set! x (+ x i)))) 3) (num-test (let ((equals =) (x 0)) (do ((i 0 (+ i 1))) ((equals i 3) x) (set! x (+ x i)) (set! i (* i 1.0)))) 3.0) (num-test (let ((equals =) (x 0)) (do ((i 0 (+ i 1))) ((equals i 3) x) (set! x (+ x i)) (set! equals >))) 6) (num-test (let ((equals =) (x 0)) (do ((i 0 (+ i 1))) ((equals i 3) x) (set! x (+ x i)) (set! equals =))) 3) (num-test (let ((equals =) (x 0)) (do ((i 0 (+ i 1))) ((equals i 3) (set! x (+ x 1)) x) (set! x (+ x i)) (set! equals =))) 4) (num-test (do ((i 0 (+ i 1))) ((> i 3) i) (set! i (expt 2 60))) (+ 1 (expt 2 60))) (num-test (let ((x 0) (n 3)) (do ((i 0 (+ i 1))) ((= i n) x) (set! x (+ x i)))) 3) (num-test (let ((x 0) (n 3)) (do ((i 0 (+ i 1))) ((= 1 1) x) (set! x (+ x i)))) 0) (num-test (let ((x 0) (n (expt 2 50))) (do ((i 0 (+ i n))) ((= i (expt 2 51)) x) (set! x (+ x i)))) (expt 2 50)) (num-test (let ((x 0) (n 31.0)) (do ((i 0 (+ i 1))) ((= i n) x) (set! x (+ x i)) (set! n 3))) 3) (num-test (let ((x 0)) (do ((i 0 (+ i 1/2))) ((= i 3) x) (set! x (+ x i)))) 15/2) (num-test (let ((x 0)) (do ((i 0 (+ i 1+i))) ((> (magnitude i) 3) x) (set! x (+ x i)))) 3+3i) (num-test (call-with-exit (lambda (r) (do () () (r 1)))) 1) (num-test (call-with-exit (lambda (r) (do () (#t 10 14) (r 1)))) 14) (num-test (do ((i 0 (+ i 1))) (#t 10 12)) 12) (num-test (do ((i 0 (+ i 1))) ((= i 3) i)) 3) (num-test (do ((i 0 (+ i 1))) ((> i 3) i)) 4) (num-test (do ((i 0 (+ i 1))) ((< i 3) i)) 0) (num-test (do ((i 0 (+ i 1))) ((<= i 3) i)) 0) (num-test (do ((i 0 (+ i 1))) ((>= i 3) i)) 3) (num-test (do ((i 0 (+ i 1))) ((>= 3 i) i)) 0) (num-test (do ((i 0 (+ i 1))) ((> 3 i) i)) 0) (num-test (do ((i 0 (+ i 1))) ((< 3 i) i)) 4) (num-test (do ((i 0 (+ i 1))) ((<= 3 i) i)) 3) (num-test (let ((n 3)) (do ((i 0 (+ i 1))) ((> i n) i))) 4) (num-test (let ((n 3)) (do ((i 0 (+ i 1))) ((< n i) i))) 4) (num-test (do ((i 10 (- i 1))) ((= i 0) i)) 0) (num-test (do ((i 10 (- 1 i))) ((< i 0) i)) -9) (num-test (do ((i 10 (- i 3))) ((< i 0) i)) -2) (let () (define (hi) (do ((i 1 (+ 1 i))) ((= i 1) i))) (hi) (test (hi) 1)) (let () (define (hi) (do ((i 10 (+ i 1))) ((= i 10) i) (abs i))) (hi) (test (hi) 10)) (let ((sum 0)) (define (hi) (do ((i 10 (+ i 1))) ((= i 10) i) (set! sum (+ sum i)))) (hi) (test (hi) 10)) (let () (define (hi a) (do ((i a (+ i 1))) ((= i a) i) (+ a 1))) (hi 1) (test (hi 1) 1)) (let () (define (fx) (let ((iter (make-iterator #(1 2 3)))) (do () ((or (string? (iterate iter)) (iterator-at-end? iter)) (not (iterator-at-end? iter)))))) (test (fx) #f)) (let () (define (fx1) (let ((iter (make-iterator #(1 2 3)))) (do () ((or (= (iterate iter) 2) (iterator-at-end? iter)) (iterate iter))))) (test (fx1) 3)) (let () (define (fx2) (let ((iter (make-iterator #(1 2 3)))) (do () ((= (iterate iter) 2) (iterate iter))))) (test (fx2) 3)) (let () (define (fdo1) (let ((abs (lambda (x) (+ x 1))) (x '(1 2 3))) (do ((i 0 (+ i 1))) ((= i 1)) (if (not (equal? (map abs x) '(2 3 4))) (display "fdo1 map case"))) (do ((i 0 (+ i 1))) ((= i 1)) (if (not (equal? (for-each abs x) #)) (display "fdo1 for-each case"))))) (define (fdo2) (let ((abs (lambda (x y) (= x y))) (x '(1 2 3))) (do ((i 0 (+ i 1))) ((= i 1)) (if (not (member 2 x abs)) (display "fdo2 member case"))))) (define (fdo3) (let ((abs (lambda (x y) (= x y))) (x '((1 a) (2 b) (3 c)))) (do ((i 0 (+ i 1))) ((= i 1)) (if (not (assoc 2 x abs)) (display "fdo3 assoc case"))))) (define (fdo4) (let ((abs (lambda (x y) (> x y))) (x (list 1 2 3))) (do ((i 0 (+ i 1))) ((= i 1)) (if (not (equal? (sort! x abs) '(3 2 1))) (display "fdo4 sort! case"))))) (fdo1) (fdo2) (fdo3) (fdo4)) (let () (define (fdo5) (do ((si () '())) ((null? si) 'mi))) (test (fdo5) 'mi)) (let () (define (fdo5) (do ((si '() '())) ((null? si) 'mi))) (test (fdo5) 'mi)) (let () (define (fdo5) (do ((si () ())) ((null? si) 'mi))) (test (fdo5) 'mi)) (let () (define (fdo5) (do ((si () ())) ((null? si) 'mi))) (test (fdo5) 'mi)) ;;; check an optimizer bug (define _do_call_cc_end_ 1) (define (call-cc-do-test) (do ((i 0 (+ i 1))) ((= i _do_call_cc_end_)) (let ((ctr 0)) (call/cc (lambda (exit) (if (> 3 2) (let () (exit ctr) (set! ctr 100) ctr) #f))))) (do ((i 0 (+ 1 i))) ((= i _do_call_cc_end_)) (let ((ctr 0)) (call/cc (lambda (exit) (if (> 3 2) (let () (exit ctr) (set! ctr 100) ctr) #f)))))) (call-cc-do-test) ;;; and another (let() (define (hi) (let ((checker (lambda (nlst v) (let ((chr (car nlst))) (if (not (char-alphabetic? chr)) (if (not (char=? v chr)) (format-logged #t ";(char-downcase #\\~A) -> ~A" chr v)) (if (and (not (char=? chr v)) (not (char=? chr (char-upcase v)))) (format-logged #t ";(char-downcase #\\~A) -> ~A~%" chr v)))))) (result 0)) (let ((try 0)) (do ((i 0 (+ i 1))) ((> i 10)) (set! try i) (checker '(#\a) #\a) (checker '(#\a) #\a))))) (test (hi) ())) (define (__a-func__ a) (format-logged #t ";oops called first a-func by mistake: ~A~%" a) (if (> a 0) (__a-func__ (- a 1)))) (define (__a-func__ a) (if (> a 0) (__a-func__ (- a 1)))) (__a-func__ 3) (define (__c-func__ a) (format-logged #t ";oops called first __c-func__ by mistake: ~A~%" a) (if (> a 0) (__c-func__ (- a 1)))) (let () (define (__c-func__ a) (if (> a 0) (__c-func__ (- a 1)))) (__c-func__ 3)) ;;; more optimizer checks (let () (define (do-test-1) (do ((i 0 (+ i 1))) ((= i 10)) (display i))) (test (with-output-to-string (lambda () (do-test-1))) "0123456789")) (let () (define (do-test-2) (do ((i 0 (+ 1 i))) ((= i 10)) (display i))) (test (with-output-to-string (lambda () (do-test-2))) "0123456789")) (let ((start 0)) (define (do-test-3) (do ((i start (+ i 1))) ((= i 10)) (display i))) (test (with-output-to-string (lambda () (do-test-3))) "0123456789")) (let ((start 0) (end 10)) (define (do-test-4) (do ((i start (+ i 1))) ((= i end)) (display i))) (test (with-output-to-string (lambda () (do-test-4))) "0123456789")) (let ((start 0) (end 10)) (define (do-test-5) (do ((i start (+ i 1))) ((= end i)) (display i))) (test (with-output-to-string (lambda () (do-test-5))) "0123456789")) (let () (define (do-test-6) (do ((i 0 (+ i 1))) ((= i 10)) (let ((k i)) (display k)))) (test (with-output-to-string (lambda () (do-test-6))) "0123456789")) (let () (define (do-test-7) (do ((i 0 (+ i 2))) ((= i 20)) (display (/ i 2)))) (test (with-output-to-string (lambda () (do-test-7))) "0123456789")) (let () (define (do-test-8) (do ((i 0 (+ i 1))) ((= i 10)) (let ((a (+ 1 2))) (display #\0)))) (test (with-output-to-string (lambda () (do-test-8))) "0000000000")) (let () (define (do-test-9) (do ((i 0 (+ i 1))) ((= i 10)) (let ((j 0)) (set! j i) (display j)))) (test (with-output-to-string (lambda () (do-test-9))) "0123456789")) (let () (define (do-test-10) (do ((i 0 (+ i 1))) ((= i 10)) (let ((j 0)) (display i)))) (test (with-output-to-string (lambda () (do-test-10))) "0123456789")) (let () (define (do-test-11) (do ((i 0 (+ i 1))) ((= i 10)) (let ((j 0)) (set! j 32) (display i)))) (test (with-output-to-string (lambda () (do-test-11))) "0123456789")) (let () (define (do-test-12) (do ((i 0 (+ i 1))) ((= i 10)) (let ((j i)) (display j)))) (test (with-output-to-string (lambda () (do-test-12))) "0123456789")) (let () (define (do-test-13) (do ((i 0 (+ i 1))) ((= i 5)) (let ((j (+ i 1))) (let ((i j)) (display (- i 1)))))) (test (with-output-to-string (lambda () (do-test-13))) "01234")) (let () (define (do-test-14) (do ((i 0 (+ i 1))) ((= i 10)) (set! i (+ i 1)) (display i))) (test (with-output-to-string (lambda () (do-test-14))) "13579")) (let ((lst ())) (define (do-test-15) (set! lst ()) (do ((i 0 (+ i 1))) ((= i 10)) (set! lst (cons i lst))) lst) (test (do-test-15) '(9 8 7 6 5 4 3 2 1 0))) (let ((lst ())) (define (do-test-15a) (set! lst ()) (do ((i 0 (+ i 1))) ((= i 10)) (set! lst (append (list i) lst))) lst) (test (do-test-15a) '(9 8 7 6 5 4 3 2 1 0))) (let ((lst (list 9 8 7 6 5 4 3 2 1 0))) (define (do-test-16) (do ((i 0 (+ i 1))) ((= i 10)) (list-set! lst i i)) lst) (test (do-test-16) '(0 1 2 3 4 5 6 7 8 9))) (let ((lst ())) (define (do-test-17) (set! lst ()) (do ((i 0 (+ i 1))) ((= i 10)) (let ((j i)) (set! lst (cons j lst)))) lst) (test (do-test-17) '(9 8 7 6 5 4 3 2 1 0))) (let ((lst ())) (define (do-test-17a) (set! lst ()) (do ((i 0 (+ i 1))) ((= i 10)) (let ((j (min i 100))) (set! lst (cons j lst)))) lst) (test (do-test-17a) '(9 8 7 6 5 4 3 2 1 0))) (let () (define (do-test-18) (do ((i 0 (+ i 1)) (j 0)) ((= i 10) j) (if (= i 3) (set! j i)))) (test (do-test-18) 3)) (let ((end 10)) (define (do-test-19) (do ((i 0 (+ i 1))) ((= i end)) (display i))) (test (with-output-to-string (lambda () (do-test-19))) "0123456789")) (let ((end 10)) (define (do-test-19A) (do ((i 0 (+ 1 i))) ((= end i)) (display i))) (test (with-output-to-string (lambda () (do-test-19A))) "0123456789")) (let ((end 10)) (define (do-test-20) (do ((i 0 (+ i 1))) ((= i end)) (set! end 8) (display i))) (test (with-output-to-string (lambda () (do-test-20))) "01234567")) (let ((end 10)) (define (do-test-20A) (do ((i 0 (+ 1 i))) ((= end i)) (set! end 8) (display i))) (test (with-output-to-string (lambda () (do-test-20A))) "01234567")) (let () (define (do-test-21) (do ((i 0 (+ i 1))) ((= i 3)) (with-let (rootlet) (+ 1 2)))) (do-test-21)) (let ((v (vector 0 0 0))) (define (hi a) (do ((i 0 (+ i 1))) ((> i a)) (vector-set! v i 1))) (hi 2) (test v (vector 1 1 1))) (let () ; dotimes_c_c case can't involve set so we use write-char (define (hi a) (do ((i 0 (+ i 1))) ((= i a)) (write-char #\a))) (with-output-to-file tmp-output-file (lambda () (hi 3))) (let ((str (with-input-from-file tmp-output-file (lambda () (read-line))))) (test str "aaa"))) (let () (define (do-test-22) (do ((i 0 (+ i 1))) ((= i 10)) (display i))) (test (with-output-to-string (lambda () (do-test-22))) "0123456789")) (let ((v (make-list 10))) (define (do-test-23) (do ((i 0 (+ i 1))) ((= i 10)) (list-set! v i i))) (do-test-23) (test v '(0 1 2 3 4 5 6 7 8 9))) ;;; safe simple h_safe_c_s (let () (define (do-test-24) (do ((i 0 (+ i 1))) ((> i 10)) (display i))) (test (with-output-to-string (lambda () (do-test-24))) "012345678910")) ;;; safe simple h_safe_c_ss (let () (define (do-test-25 p) (do ((i 0 (+ i 1))) ((> i 10)) (display i p))) (test (call-with-output-string (lambda (p) (do-test-25 p))) "012345678910")) ;;; safe simple h_safe_c_c (let () (define (do-test-26) (do ((i 0 (+ i 1))) ((> i 10)) (display 0))) (test (with-output-to-string (lambda () (do-test-26))) "00000000000")) ;;; safe simple h_safe_c_opsq_s (let () (define (do-test-27 p) (do ((i 0 (+ i 1))) ((> i 10)) (display (- i) p))) (test (call-with-output-string (lambda (p) (do-test-27 p))) "0-1-2-3-4-5-6-7-8-9-10")) (let () (define (do-test-22 i o) (catch #t (lambda () (do () () (write-char (read-char i) o))) (lambda err (get-output-string o)))) (test (call-with-output-string (lambda (out) (call-with-input-string "0123" (lambda (in) (do-test-22 in out))))) "0123")) ;;; -------------------------------------------------------------------------------- ;;; set! ;;; -------------------------------------------------------------------------------- (test (let ((a 1)) (set! a 2) a) 2) (for-each (lambda (arg) (test (let ((a 0)) (set! a arg) a) arg)) (list "hi" -1 #\a 1 'a-symbol #(1 2 3) 3.14 3/4 1.0+1.0i #f #t (list 1 2 3) '(1 . 2))) (test (let ((a 1)) (call/cc (lambda (r) (set! a (let () (if (= a 1) (r 123)) 321)))) a) 1) (test (let ((a (lambda (b) (+ b 1)))) (set! a (lambda (b) (+ b 2))) (a 3)) 5) (test (let ((a (lambda (x) (set! x 3) x))) (a 1)) 3) (test (let ((x (vector 1 2 3))) (set! (x 1) 32) x) #(1 32 3)) (test (let* ((x (vector 1 2 3)) (y (lambda () x))) (set! ((y) 1) 32) x) #(1 32 3)) (test (let* ((x (vector 1 2 3)) (y (lambda () x)) (z (lambda () y))) (set! (((z)) 1) 32) x) #(1 32 3)) (test (let ((a 1)) (set! a)) 'error) (test (let ((a 1)) (set! a 2 3)) 'error) (test (let ((a 1)) (set! a . 2)) 'error) (test (let ((a 1)) (set! a 1 . 2)) 'error) (test (let ((a 1)) (set! a a) a) 1) (test (set! "hi" 1) 'error) (test (set! 'a 1) 'error) (test (set! 1 1) 'error) (test (set! (list 1 2) 1) 'error) (test (set! (let () 'a) 1) 'error) (test (set!) 'error) (test (set! #t #f) 'error) (test (set! () #f) 'error) (test (set! #(1 2 3) 1) 'error) (test (set! (call/cc (lambda (a) a)) #f) 'error) (test (set! 3 1) 'error) (test (set! 3/4 1) 'error) (test (set! 3.14 1) 'error) (test (set! #\a 12) 'error) (test (set! (1 2) #t) 'error) (test (set! _not_a_var_ 1) 'error) (test (set! (_not_a_pws_) 1) 'error) (test (let ((x 1)) (set! ((lambda () 'x)) 3) x) 'error) (test (let ((x '(1 2 3))) (set! (((lambda () 'x)) 0) 3) x) '(3 2 3)) (test (let ((x '(1 2 3))) (set! (((lambda () x)) 0) 3) x) '(3 2 3)) ; ?? (test (let ((x '(1 2 3))) (set! ('x 0) 3) x) '(3 2 3)) ; ??? I suppose that's similar to (test (let ((x '((1 2 3)))) (set! ((car x) 0) 3) x) '((3 2 3))) (test (let ((x '((1 2 3)))) (set! ('(1 2 3) 0) 32) x) '((1 2 3))) ; this still looks wrong... (expands to (list-set! '(1 2 3) 0 3) I guess) (test (let ((a (lambda (x) (set! a 3) x))) (list (a 1) a)) 'error) (test (let ((a (let ((b 1)) (set! a 3) b))) a) 'error) (test (let ((a (lambda () "hi"))) (set! (a) "ho")) 'error) (test (let ((a (let ((b 1)) (set! a 3) b))) a) 'error) (test (set! . -1) 'error) (test (set!) 'error) (test (let ((x 1)) (set! x x x)) 'error) (test (let ((x 1)) (set! x x) x) 1) (test (set! set! 123) 'error) (test (set! (cons 1 2) 3) 'error) (test (let ((var 1) (val 2)) (set! var set!) (var val 3) val) 3) (test (let ((var 1) (val 2)) (set! var +) (var val 3)) 5) (test (let ((sym0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 1) (sym0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456780 3)) (set! sym0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 2) sym0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789) 2) (test (let ((x '(1)) (y '(2))) (set! ((if #t x y) 0) 32) x) '(32)) (test (let ((hi 0)) (set! hi 32)) 32) (test (let ((hi 0)) ((set! hi ('((1 2) (3 4)) 0)) 0)) 1) (test (set! # 1) 'error) (test (set! # 1) 'error) (test (set! # 1) 'error) (test (let ((x 0)) (define-macro (hi) 'x) (set! (hi) 3) x) 'error) (test (set! ("hi" . 1) #\a) 'error) (test (set! (#(1 2) . 1) 0) 'error) (test (set! ((1 . 2)) 3) 'error) (test (let ((lst (list 1 2))) (set! (lst . 0) 3) lst) 'error) (test (let ((lst (list 1 2))) (set! (list-ref lst . 1) 2)) 'error) (test (let ((v #2d((1 2) (3 4)))) (set! (v 0 . 0) 2) v) 'error) (test (set! ('(1 2) . 0) 1) 'error) (test (set! ('(1 2) 0) 3) 3) (test (set! (''(1 . 2)) 3) 'error) (test (set! (''(1 2)) 3) 'error) (test (set! ('(1 . 2)) 3) 'error) (test (set! ('(1 2)) 3) 'error) (test (set! (''(1 2) 0 0) 3) 'error) (test (set! (#(1 2) 0 0) 3) 'error) (test (let ((x 1)) (set! (quasiquote . x) 2) x) 'error) (test (let ((x 1)) (set! (quasiquote x) 2) x) 'error) (test (set! `,(1) 3) 'error) (test (set! (1) 3) 'error) (test (set! `,@(1) 3) 'error) (test (let ((x 0)) (set! x 1 . 2)) 'error) (test (let ((x 0)) (apply set! x '(3))) 'error) ; ;set!: can't alter immutable object: 0 (test (let ((x 0)) (apply set! 'x '(3)) x) 3) (test (set! (#(a 0 (3)) 1) 0) 0) (test (set! ('(a 0) 1) 0) 0) (test (apply set! (apply list (list ''(1 2 3) 1)) '(32)) 32) (let () (define-macro (symbol-set! var val) `(apply set! ,var (list ,val))) ; but this evals twice (test (let ((x 32) (y 'x)) (symbol-set! y 123) (list x y)) '(123 x))) (let () (define-macro (symbol-set! var val) ; like CL's set `(apply set! ,var ',val ())) (test (let ((var '(+ 1 2)) (val 'var)) (symbol-set! val 3) (list var val)) '(3 var)) (test (let ((var '(+ 1 2)) (val 'var)) (symbol-set! val '(+ 1 3)) (list var val)) '((+ 1 3) var))) (test (set! ('(1 2) 1 . 2) 1) 'error) (test (set! ('((1 2) 1) () . 1) 1) 'error) (test (set! ('(1 1) () . 1) 1) 'error) (test (let () (define (hi) (let ((x 1000)) (set! x (+ x 1)) x)) (hi) (hi)) 1001) (test (let () (define (hi) (let ((x 1000.5)) (set! x (+ x 1)) x)) (hi) (hi)) 1001.5) (test (let () (define (hi) (let ((x 3/2)) (set! x (+ x 1)) x)) (hi) (hi)) 5/2) (test (let () (define (hi) (let ((x 3/2)) (set! x (- x 1)) x)) (hi) (hi)) 1/2) (test (let () (define (hi) (let ((x 3/2)) (set! x (- x 2)) x)) (hi) (hi)) -1/2) (test (let () (define (hi) (let ((x "asdf")) (set! x (+ x 1)) x)) (hi) (hi)) 'error) (let () ;; check an optimizer bug (define (bad-increment a b) (cons a b)) (define (use-bad-increment b) (let ((x ())) (set! x (bad-increment x b)) x)) (use-bad-increment 1) (use-bad-increment 1) (use-bad-increment 1)) ;;; -------------------------------------------------------------------------------- ;;; or ;;; -------------------------------------------------------------------------------- (test (or (= 2 2) (> 2 1)) #t) (test (or (= 2 2) (< 2 1)) #t) (test (or #f #f #f) #f) (test (or) #f) (test (or (memq 'b '(a b c)) (+ 3 0)) '(b c)) (test (or 3 9) 3) (test (or #f 3 asdf) 3) ; "evaluation stops immediately" (test (or 3 (/ 1 0) (display "or is about to exit!") (exit)) 3) (for-each (lambda (arg) (test (or arg) arg) (test (or #f arg) arg) (test (or arg (error "oops or ")) arg)) (list "hi" -1 #\a 1 'a-symbol #(1 2 3) 3.14 3/4 1.0+1.0i #t (list 1 2 3) # # '(1 . 2))) (test (call-with-input-file "s7test.scm" (lambda (p) (let ((loc 0)) (let loop ((val (read-char p))) (or (eof-object? val) (> loc 1000) ; try to avoid the read-error stuff (begin (set! loc (+ loc 1)) (loop (read-char p))))) (> loc 1000)))) #t) (test (or (and (or (> 3 2) (> 3 4)) (> 2 3)) 4) 4) (test (or or) or) (test (or (or (or))) #f) (test (or (or (or) (and))) #t) (test (let ((a 1)) (or (let () (set! a 2) #f) (= a 1) (let () (set! a 3) #f) (and (= a 3) a) (let () (set! a 4) #f) a)) 3) (test (or '#f ()) ()) (test (call/cc (lambda (r) (or #f (> 3 2) (r 123) 321))) #t) (test (call/cc (lambda (r) (or #f (< 3 2) (r 123) 321))) 123) (test (+ (or #f (not (null? ())) 3) (or (zero? 1) 2)) 5) (test (or 0) 0) (test (if (or) 1 2) 2) (test (or . 1) 'error) (test (or #f . 1) 'error) (test (or . (1 2)) 1) (test (or . ()) (or)) ; (test (or 1 . 2) 1) ; this fluctuates (test (let () (or (define (hi a) a)) (hi 1)) 1) (test (let () (or #t (define (hi a) a)) (hi 1)) 'error) (test (let () (and (define (hi a) a) (define (hi a) (+ a 1))) (hi 1)) 2) ; guile agrees with this (test ((lambda (arg) (arg #f 123)) or) 123) (test (let ((oar or)) (oar #f 43)) 43) (test (let ((oar #f)) (set! oar or) (oar #f #f 123)) 123) ;;; -------------------------------------------------------------------------------- ;;; and ;;; -------------------------------------------------------------------------------- (test (and (= 2 2) (> 2 1)) #t) (test (and (= 2 2) (< 2 1)) #f) (test (and 1 2 'c '(f g)) '(f g)) (test (and) #t) (test (and . ()) (and)) (test (and 3) 3) (test (and (memq 'b '(a b c)) (+ 3 0)) 3) (test (and 3 9) 9) (test (and #f 3 asdf) #f) ; "evaluation stops immediately" (test (and 3 (zero? 1) (/ 1 0) (display "and is about to exit!") (exit)) #f) (test (if (and) 1 2) 1) (test (if (+) 1 2) 1) (test (if (*) 1 2) 1) (test (and (if #f #f)) (if #f #f)) (test (let ((x '(1))) (eq? (and x) x)) #t) (for-each (lambda (arg) (test (and arg) arg) (test (and #t arg) arg) (test (and arg #t) #t)) (list "hi" -1 #\a 1 'a-symbol #(1 2 3) 3.14 3/4 1.0+1.0i #t (list 1 2 3) '(1 . 2))) (test (call-with-input-file "s7test.scm" (lambda (p) (let ((loc 0)) (let loop ((val (read-char p))) (and (not (eof-object? val)) (< loc 1000) (begin (set! loc (+ loc 1)) (loop (read-char p))))) (>= loc 1000)))) #t) (test (and (or (and (> 3 2) (> 3 4)) (> 2 3)) 4) #f) (test (and and) and) (test (and (and (and))) #t) (test (and (and (and (and (or))))) #f) (test (let ((a 1)) (and (let () (set! a 2) #t) (= a 1) (let () (set! a 3) #f) (and (= a 3) a) (let () (set! a 4) #f) a)) #f) (test (and '#t ()) ()) (test (call/cc (lambda (r) (and #t (> 3 2) (r 123) 321))) 123) (test (call/cc (lambda (r) (and #t (< 3 2) (r 123) 321))) #f) (test (+ (and (null? ()) 3) (and (zero? 0) 2)) 5) (test (and . #t) 'error) (test (and 1 . 2) 'error) (test (and . (1 2)) 2) (test (let () (and (define (hi a) a)) (hi 1)) 1) (test (let () (and #f (define (hi a) a)) (hi 1)) 'error) (test (+ 1 (and (define (hi a) a) (hi 2))) 3) ;;; from some net site (let () (define (fold fn accum list) (if (null? list) accum (fold fn (fn accum (car list)) (cdr list)))) (test (fold and #t '(#t #f #t #t)) #f)) (test (let ((and! and)) (and! #f (error "oops"))) #f) (test (let ((and! #f)) (set! and! and) (and! #f (error "oops"))) #f) (test (let () (define (try and!) (and! #f (error "oops"))) (try and)) #f) ;;; here are some tests from S. Lewis in the r7rs mailing list (let () (define myand and) (test (myand #t (+ 1 2 3)) 6) (define (return-op) and) (define myop (return-op)) (test (myop #t (+ 1 2 3)) 6) (test (and #t (+ 1 2 3)) 6) (test ((return-op) #t (+ 1 2 3)) 6) (test ((and and) #t (+ 1 2 3)) 6) (define ops `(,* ,and)) (test ((car ops) 2 3) 6) (test ((cadr ops) #t #f) #f) (test (and #f never) #f) (test (and #f and) #f) (test ((and #t and) #t (+ 1 2 3)) 6)) ;;; -------------------------------------------------------------------------------- ;;; cond ;;; -------------------------------------------------------------------------------- (test (cond ('a)) 'a) (test (cond (3)) 3) (test (cond (#f 'a) ('b)) 'b) (test (cond (#t 'a) (#t 'b)) 'a) (test (cond ((> 3 2) 'greater) ((< 3 2) 'less)) 'greater) (test (cond((> 3 2)'greater)((< 3 2)'less)) 'greater) (test (cond ((> 3 3) 'greater) ((< 3 3) 'less) (else 'equal)) 'equal) (test (cond ((assv 'b '((a 1) (b 2))) => cadr) (else #f)) 2) (test (cond (#f 2) (else 5)) 5) (test (cond (1 2) (else 5)) 2) (test (cond (1 => (lambda (x) (+ x 2))) (else 8)) 3) (test (cond ((+ 1 2))) 3) (test (cond ((zero? 1) 123) ((= 1 1) 321)) 321) (test (cond ('() 1)) 1) (test (let ((x 1)) (cond ((= 1 2) 3) (else (* x 2) (+ x 3)))) 4) (test (let((x 1))(cond((= 1 2)3)(else(* x 2)(+ x 3)))) 4) (test (let ((x 1)) (cond ((= x 1) (* x 2) (+ x 3)) (else 32))) 4) (test (let ((x 1)) (cond ((= x 1) (let () (set! x (* x 2))) (+ x 3)) (else 32))) 5) (test (let ((x 1)) (cond ((= x 2) (let () (set! x (* x 2))) (+ x 3)) (else 32))) 32) (test (let ((x 1)) (cond ((= x 2) 3) (else (let () (set! x (* x 2))) (+ x 3)))) 5) (test (cond ((= 1 2) 3) (else 4) (else 5)) 4) ; this should probably be an error (test (cond (1 2 3)) 3) (test (cond (1 2) (3 4)) 2) (test (cond ((= 1 2) 3) ((+ 3 4))) 7) (test (cond ((= 1 1) (abs -1) (+ 2 3) (* 10 2)) (else 123)) 20) (test (let ((a 1)) (cond ((= a 1) (set! a 2) (+ a 3)))) 5) (test (let ((a 1)) (cond ((= a 2) (+ a 2)) (else (set! a 3) (+ a 3)))) 6) (test (cond ((= 1 1))) #t) (test (cond ((= 1 2) #f) (#t)) #t) (test (cond ((+ 1 2))) 3) (test (cond ((cons 1 2))) '(1 . 2)) (test (cond (#f #t) ((string-append "hi" "ho"))) "hiho") (test (cond ('() 3) (#t 4)) 3) (test (cond ((list) 3) (#t 4)) 3) ;;; (cond (1 1) (asdf 3)) -- should this be an error? (test (cond (+ 0)) 0) (test (cond (lambda ())) ()) (test (cond . ((1 2) ((3 4)))) 2) (test (cond (define #f)) #f) (test (let () (cond ((> 2 1) (define x 32) x) (#t 1)) x) 32) ; ? a bit strange (test (let ((x 1)) (+ x (cond ((> x 0) (define x 32) x)) x)) 65) (test (cond (("hi" 1))) #\i) (test (cond (()())) ()) (test (let ((a 0)) (let ((b (lambda () (set! a 1) #f))) (cond ((> a 0) 3) ((b) 4) ((> a 0) 5) (#t 6)))) 5) (test (let ((a #t)) (let ((b (lambda () (set! a (not a)) a))) (cond ((b) 1) ((b) 2) (t 3)))) 2) (test (let ((otherwise else)) (cond ((= 1 2) 1) (otherwise 3))) 3) (test (let ((otherwise #t)) (cond ((= 1 2) 1) (otherwise 3))) 3) ; or actually anything... 12 for example (test (let ((else #f)) (cond ((= 1 2) 1) (else 3))) ()) (test (let ((else #f)) (cond ((= 1 2) 1) (#_else 3))) 3) (test (let ((else 1)) (let ((otherwise else)) (case 0 (otherwise 1)))) 'error) (for-each (lambda (arg) (test (cond ((or arg) => (lambda (x) x))) arg)) (list "hi" -1 #\a 1 'a-symbol #(1 2 3) 3.14 3/4 1.0+1.0i #t (list 1 2 3) '(1 . 2))) (test (cond ((+ 1 2) => (lambda (x) (+ 1 x)))) 4) (test (cond ((cons 1 2) => car)) 1) (test (cond ((values 1 2) => +)) 3) (test (cond (1 2 => +)) 'error) (test (cond ((begin 1 2) => +)) 2) (test (cond ((values -1) => abs)) 1) (test (cond ((= 1 2) => +) (#t => not)) #f) (test (cond ((* 2 3) => (let () -))) -6) (test (cond ((* 2 3) => (cond ((+ 3 4) => (lambda (a) (lambda (b) (+ b a))))))) 13) (test (let ((x 1)) ((cond ((let () (set! x 2) #f) => boolean?) (lambda => (lambda (a) (apply a '((b) (+ b 123)))))) x)) 125) (test (cond ((values 1 2 3) => '(1 (2 3 (4 5 6 7 8))))) 7) (test (cond ((values 1 2 3) => +)) 6) (test (cond ((values #f #f) => equal?)) #t) ; (values #f #f) is not #f (test (let () (cond (#t (define (hi a) a))) (hi 1)) 1) (test (let () (cond (#f (define (hi a) a))) (hi 1)) 'error) (test (let () (cond ((define (hi a) a) (hi 1)))) 1) (test (cond (else 1)) 1) (test (call/cc (lambda (r) (cond ((r 4) 3) (else 1)))) 4) (test (cond ((cond (#t 1)))) 1) (test (symbol? (cond (else else))) #f) (test (equal? else (cond (else else))) #t) (test (cond (#f 2) ((cond (else else)) 1)) 1) (test (let ((x #f) (y #t)) (cond (x 1) (y 2))) 2) (test (cond ((- 3 2)) ((< 2 3))) (or (- 3 2) (< 3 2))) ; (cond (e) ...)) is the same as (or e ...) (for-each (lambda (arg) (test (cond (#t arg)) arg)) (list "hi" -1 #\a 1 'a-symbol #(1 2 3) 3.14 3/4 1.0+1.0i #t (list 1 2 3) '(1 . 2))) (for-each (lambda (arg) (test (cond (arg)) arg)) (list "hi" -1 #\a 1 'a-symbol #(1 2 3) 3.14 3/4 1.0+1.0i #t (list 1 2 3) '(1 . 2))) (for-each (lambda (arg) (test (cond (#f 1) (else arg)) arg)) (list "hi" -1 #\a 1 'a-symbol #(1 2 3) 3.14 3/4 1.0+1.0i #t (list 1 2 3) '(1 . 2))) (for-each (lambda (arg) (test (cond (arg => (lambda (x) x))) arg)) (list "hi" -1 #\a 1 'a-symbol #(1 2 3) 3.14 3/4 1.0+1.0i #t (list 1 2 3) '(1 . 2))) (test (cond ((let () 1) => (let ((x 2)) (lambda (n) (+ n x))))) 3) (test (cond ((let () 1) => (let ((x 2)) (cond (3 => (let ((y 4)) (lambda (n) (lambda (m) (+ n m x y))))))))) 10) (test (let ((=> 3)) (cond (=> =>))) 3) (test (cond (cond 'cond)) 'cond) (test (cond (3 => (lambda args (car args)))) 3) (test (cond (3 => (lambda (a . b) a))) 3) (test (cond ((list 3 4) => (lambda (a . b) b))) ()) (test (cond) 'error) (test (let () (define-macro (mac x) `(+ ,x 1)) (cond (1 => mac))) 2) ;(test (cond ((= 1 2) 3) (else 4) (4 5)) 'error) ; trailing ignored (test (cond ((+ 1 2) => (lambda (a b) (+ a b)))) 'error) (test (equal? (cond (else)) else) #t) (test (cond (#t => 'ok)) 'error) (test (cond (else =>)) 'error) (test (cond ((values -1) => => abs)) 'error) (test (cond ((values -1) =>)) 'error) (test (cond (cond (#t 1))) 'error) (test (cond 1) 'error) (test (cond) 'error) (test (cond (1 . 2) (else 3)) 'error) (test (cond (#f 2) (else . 4)) 'error) (test (cond ((values 1 2) => (lambda (x y) #t))) #t) (test (cond #t) 'error) (test (cond 1 2) 'error) (test (cond 1 2 3) 'error) (test (cond 1 2 3 4) 'error) (test (cond (1 => (lambda (x y) #t))) 'error) (test (cond . 1) 'error) (test (cond ((1 2)) . 3) 'error) (test (cond (1 => + abs)) 'error) (test (cond (1 =>)) 'error) (test (cond ((values 1 2) => + abs)) 'error) (test (cond (else => symbol?)) #f) ; (symbol? else) -> #f (test (eq? (cond (else => or)) else) #t) (test (cond ((values #f 1) => or)) 1) (test (+ (cond ((values 1 2 3)))) 6) (test (let ((else 3)) (cond ((= else 3) 32) (#t 1))) 32) (test (let ((else #f)) (cond (else 32) (#t 1))) 1) (test (cond #((1 2))) 'error) (test (cond (/ 0)) 0) ; / is not #f, so return 0 (test (cond (string-ref 2)) 2) (test (let ((=> 3)) (cond (1 =>))) 3) (test (let ((=> 3)) (cond (1 => abs))) abs) (test (let ((=> 3) (else 4)) (cond (else => abs))) abs) (test (let ((=> 3)) (cond (1 => "hi"))) "hi") (test (let ((x 0)) (cond ((let ((y x)) (set! x 1) (= y 1)) 0) ((let ((y x)) (set! x 1) (= y 1)) 1) (#t 2))) 1) (let ((c1 #f) (x 1)) (let ((y (cond ((let () (call/cc (lambda (r) (set! c1 r) (r x)))) => (lambda (n) (+ n 3))) (#t 123)))) (if (= y 4) (begin (set! x 2) (c1 321))) (test (list x y) '(2 324)))) (let ((c1 #f) (x 1)) (let ((y (cond (x => (lambda (n) (call/cc (lambda (r) (set! c1 r) (r (+ 3 x)))))) (#t 123)))) (if (= y 4) (begin (set! x 2) (c1 321))) (test (list x y) '(2 321)))) ;;; -------- cond-expand -------- ;;; cond-expand (test (let () (cond-expand (guile ) (s7 (define (hi a) a))) (hi 1)) 1) (test (let ((x 0)) (cond-expand (guile (format-logged #t ";oops~%")) (else (set! x 32))) x) 32) (test (let () (cond-expand (guile (define (hi a) (+ a 1))) ((or common-lisp s7) (define (hi a) a))) (hi 1)) 1) (test (let () (cond-expand ((not guile) (define (hi a) a)) (else (define (hi a) (+ a 1)))) (hi 1)) 1) (test (let () (cond-expand ((and s7 dfls-exponents) (define (hi a) a)) (else (define (hi a) (+ a 1)))) (hi 1)) (if (provided? 'dfls-exponents) 1 2)) (test (let () (cond-expand ((or s7 guile) (define (hi a) a)) (else (define (hi a) (+ a 1)))) (hi 1)) 1) (test (let () (cond-expand ((and s7 dfls-exponents unlikely-feature) (define (hi a) a)) (else (define (hi a) (+ a 1)))) (hi 1)) 2) (test (let () (cond-expand ((and s7 (not s7)) 'oops) (else 1))) 1) (test (let () (cond-expand ("not a pair" 1) (2 2) (#t 3) ((1 . 2) 4) (() 6) (list 7) (else 5))) 'error) ;;; -------------------------------------------------------------------------------- ;;; case ;;; -------------------------------------------------------------------------------- (test (case (* 2 3) ((2 3 5 7) 'prime) ((1 4 6 8 9) 'composite)) 'composite) (test (case (car '(c d)) ((a e i o u) 'vowel) ((w y) 'semivowel) (else 'consonant)) 'consonant) (test (case 3.1 ((1.3 2.4) 1) ((4.1 3.1 5.4) 2) (else 3)) 2) (test (case 3/2 ((3/4 1/2) 1) ((3/2) 2) (else 3)) 2) (test (case 3 ((1) 1 2 3) ((2) 2 3 4) ((3) 3 4 5)) 5) (test (case 1+i ((1) 1) ((1/2) 1/2) ((1.0) 1.0) ((1+i) 1+i)) 1+i) (test (case 'abs ((car cdr) 1) ((+ cond) 2) ((abs) 3) (else 4)) 3) (test (case #\a ((#\b) 1) ((#\a) 2) ((#\c) 3)) 2) (test (case (boolean? 1) ((#t) 2) ((#f) 1) (else 0)) 1) (test (case 1 ((1 2 3) (case 2 ((1 2 3) 3)))) 3) (test (case 1 ((1 2) 1) ((3.14 2/3) 2)) 1) (test (case 1 ((1 2) 1) ((#\a) 2)) 1) (test (case 1 ((1 2) 1) ((#\a) 2) ((car cdr) 3) ((#f #t) 4)) 1) (test (case #f ((1 2) 1) ((#\a) 2) ((car cdr) 3) ((#f #t) 4)) 4) (test (case 1 ((#t) 2) ((#f) 1) (else 0)) 0) (test (let ((x 1)) (case x ((x) "hi") (else "ho"))) "ho") (test (let ((x 1)) (case x ((1) "hi") (else "ho"))) "hi") (test (let ((x 1)) (case x (('x) "hi") (else "ho"))) "ho") (test (let ((x 1)) (case 'x ((x) "hi") (else "ho"))) "hi") (test (case () ((()) 1)) 1) (test (case #() ((#()) 1) (else 2)) 2) (test (let ((x '(1))) (eval `(case ',x ((,x) 1) (else 0)))) 1) ; but we can overcome that! (also via apply) (test (let ((x #())) (eval `(case ',x ((,x) 1) (else 0)))) 1) (test (case ''2 (('2) 1) (else 0)) 0) (test (let ((otherwise else)) (case 1 ((0) 123) (otherwise 321))) 321) (test (case 1 ((0) 123) (#t 321)) 'error) (test (case else ((#f) 2) ((#t) 3) ((else) 4) (else 5)) 5) ; (eqv? 'else else) is #f (Guile says "unbound variable: else") (test (case #t ((#f) 2) ((else) 4) (else 5)) 5) ; else is a symbol here (test (equal? (case 0 ((0) else)) else) #t) (test (cond ((case 0 ((0) else)) 1)) 1) ;(test (let () (case (define b 3) ((b) b))) 3) ; changed define 25-Jul-14 (test (let ((x 1)) (case x ((2) 3) (else (* x 2) (+ x 3)))) 4) (test (let ((x 1)) (case x ((1) (* x 2) (+ x 3)) (else 32))) 4) (test (let ((x 1)) (case x ((1) (let () (set! x (* x 2))) (+ x 3)) (else 32))) 5) (test (let ((x 1)) (case x ((2) (let () (set! x (* x 2))) (+ x 3)) (else 32))) 32) (test (let ((x 1)) (case x ((2) 3) (else (let () (set! x (* x 2))) (+ x 3)))) 5) (test (let((x 1))(case x((2)3)(else(let()(set! x(* x 2)))(+ x 3)))) 5) (test (let ((x 1)) (case x ((2) 3) (else 4) (else 5))) 'error) (test (case () ((()) 2) (else 1)) 2) ; car: (), value: (), eqv: 1, null: 1 1 (test (case () (('()) 2) (else 1)) 1) ; car: (quote ()), value: (), eqv: 0, null: 0 1 (test (case () (('()) 2) (else 1)) 1) ; car: (quote ()), value: (), eqv: 0, null: 0 1 (test (case () ((()) 2) (else 1)) 2) ; car: (), value: (), eqv: 1, null: 1 1 ;;; this is a difference between () and () ? ;;; (eqv? () ()) -> #t and (eqv? () ()) is #t so it's the lack of evaluation in the search case whereas the index is evaluated ;;; equivalent to: (test (case 2 (('2) 3) (else 1)) 1) ; car: (quote 2), value: 2, eqv: 0, null: 0 0 (test (case '2 (('2) 3) (else 1)) 1) ; car: (quote 2), value: 2, eqv: 0, null: 0 0 (test (case '2 ((2) 3) (else 1)) 3) ; car: 2, value: 2, eqv: 1, null: 0 0 (test (case 2 ((2) 3) (else 1)) 3) ; car: 2, value: 2, eqv: 1, null: 0 0 (test (case '(()) ((()) 1) (((())) 2) (('()) 3) (('(())) 4) ((((()))) 5) (('((()))) 6) (else 7)) 7) ; (eqv? '(()) '(())) is #f (test (let ((x 1)) (case (+ 1 x) ((0 "hi" #f) 3/4) ((#\a 1+3i '(1 . 2)) "3") ((-1 'hi 2 2.0) #\f))) #\f) (test (case (case 1 ((0 2) 3) (else 2)) ((0 1) 2) ((4 2) 3) (else 45)) 3) (test (case 3/4 ((0 1.0 5/6) 1) (("hi" 'hi 3/4) 2) (else 3)) 2) (test (case (case (+ 1 2) (else 3)) ((3) (case (+ 2 2) ((2 3) 32) ((4) 33) ((5) 0)))) 33) (test (let ((x 1)) (case x ((0) (set! x 12)) ((2) (set! x 32))) x) 1) (test (case 1 (else #f)) #f) (test (let () (case 0 ((0) (define (hi a) a)) (else (define (hi a) (+ a 1)))) (hi 1)) 1) (test (let () (case 1 ((0) (define (hi a) a)) (else (define (hi a) (+ a 1)))) (hi 1)) 2) ;(test (let () (case (define (hi a) a) ((hi) (hi 1)))) 1) ; 25-Jul-14 (for-each (lambda (arg) (test (case 1 ((0) 'gad) ((1 2 3) arg) (else 'gad)) arg)) (list "hi" -1 #\a 1 'a-symbol #(1 2 3) 3.14 3/4 1.0+1.0i #t (list 1 2 3) '(1 . 2))) (for-each (lambda (arg) (test (case arg ((0) 'gad) ((1 2 3) arg) (else 'gad)) 'gad)) (list "hi" -1 #\a 0 'a-symbol #(1 2 3) 3.14 3/4 1.0+1.0i #t (list 1 2 3) '(1 . 2))) (test (call/cc (lambda (r) (case 1 ((1) (r 123) #t) (else #f)))) 123) (test (call/cc (lambda (r) (case 1 ((0) 0) (else (r 123) #f)))) 123) (test (case () ((1) 1) ('() 2)) 2) (test (case (list) ((1) 1) ('() 2)) 2) (test (case () ((1) 1) ((()) 2)) 2) (test (case (list) ((1) 1) ((()) 2)) 2) (test (case # ((#) 1)) 1) (test (case #\newline ((#\newline) 1)) 1) (test (case 'c (else => (lambda (x) (symbol? x)))) #t) (test (case 1.0 ((1e0) 3) ((1.0) 4) (else 5)) 3) (test (case 1.0 ((#i1) 2) ((1e0) 3) ((1.0) 4) (else 5)) 2) (test (case 1 ((#i1) 2) ((1e0) 3) ((1.0) 4) (else 5)) 5) (let () (define (c1 x) (case x ((3001) 1) ((12345) 2) ((8589934592) 3) (else 4))) (test (c1 3001) 1) (test (c1 12345) 2) (test (c1 8589934592) 3) (test (c1 -1) 4) (define (c2 x) (case x ((0 1 -1) 3) ((9223372036854775807 -9223372036854775808) 4) ((1.5) 5) ((2/3 1+i) 6))) (test (c2 -1) 3) (test (c2 most-positive-fixnum) 4) (test (c2 1.5) 5) (test (c2 2/3) 6) (test (c2 1+i) 6)) ; case uses eqv? -- why not case-equal? (test (case "" (("") 1)) #) (test (case abs ((abs) 1)) #) (test (case (if #f #f) ((1) 1) ((#) 2) (else 3)) 2) (test (case) 'error) (test (case 1) 'error) (test (case 1 . "hi") 'error) (test (case 1 ("hi")) 'error) (test (case 1 ("a" "b")) 'error) (test (case 1 (else #f) ((1) #t)) 'error) (test (case "hi" (("hi" "ho") 123) ("ha" 321)) 'error) (test (case) 'error) (test (case . 1) 'error) (test (case 1 . 1) 'error) (test (case 1 (#t #f) ((1) #t)) 'error) (test (case 1 (#t #f)) 'error) (test (case -1 ((-1) => abs)) 1) (test (case 1 (else =>)) 'error) (test (case 1 (else => + - *)) 'error) (test (case #t ((1 2) (3 4)) -1) 'error) (test (case 1 1) 'error) (test (case 1 ((2) 1) . 1) 'error) (test (case 1 (2 1) (1 1)) 'error) (test (case 1 (else)) 'error) (test (case () ((1 . 2) . 1) . 1) 'error) (test (case 1 ((1))) 'error) (test (case 1 ((else))) 'error) (test (case 1 ((2) 3) ((1))) 'error) (test (case 1 ((1)) 1 . 2) 'error) (test (case () ((()))) 'error) (test (case 1 (else 3) . 1) 'error) (test (case 1 ((1 2)) (else 3)) 'error) (test (case 1 ('(1 2) 3) (else 4)) 4) (test (case 1 (('1 2) 3) (else 4)) 4) (test (case 1 ((1 . 2) 3) (else 4)) 'error) ; ?? in guile it's an error (test (case 1 ((1 2 . 3) 3) (else 4)) 'error) (test (case 1 (('1 . 2) 3) (else 4)) 'error) (test (case 1 ((1 . (2)) 3) (else 4)) 3) (test (case 1 ((1 2) . (3)) (else 4)) 3) (test (case 1 ((2) 3) (else)) 'error) (test (case 1 ((2) 3) ()) 'error) (test (case 1 ((2) 3) (() 2)) 'error) ; ?? in Guile this is #; our error is confusing: ;case clause key list () is not a list or 'else' (test (case () ('() 2)) 2) ; ?? error?? (test (case () ((()) 2)) 2) (test (case 1 else) 'error) (test (case 1 (((1) 1) 2) (else 3)) 2) ; the (1) can't be matched -- should it be an error? (test (case 1 ((1) . (else 3))) 3) ; ?? guile says "unbound variable: else" (test (case . (1 ((2) 3) ((1) 2))) 2) (test (case 1 (#(1 2) 3)) 'error) (test (case 1 #((1 2) 3)) 'error) (test (case 1 ((2) 3) () ((1) 2)) 'error) (test (case 1 ((2) 3) (1 2) ((1) 2)) 'error) (test (case 1 ((2) 3) (1 . 2) ((1) 2)) 'error) (test (case 1 ((2) 3) (1) ((1) 2)) 'error) (test (case 1 ((2) 3) ((1)) ((1) 2)) 'error) (test (case 1 ((1) 2) ((1) 3)) 2) ; should this be an errror? (test (let () (define-macro (mac x) `(+ ,x 1)) (case 1 ((1) => mac))) 2) (let () (define (hi x) (case x ((a) 'a) ((b) 'b) (else 'c))) (test (hi 'a) 'a) (test (hi 'd) 'c)) (test (case 'case ((case) 1) ((cond) 3)) 1) (test (case 101 ((0 1 2) 200) ((3 4 5 6) 600) ((7) 700) ((8) 800) ((9 10 11 12 13) 1300) ((14 15 16) 1600) ((17 18 19 20) 2000) ((21 22 23 24 25) 2500) ((26 27 28 29) 2900) ((30 31 32) 3200) ((33 34 35) 3500) ((36 37 38 39) 3900) ((40) 4000) ((41 42) 4200) ((43) 4300) ((44 45 46) 4600) ((47 48 49 50 51) 5100) ((52 53 54) 5400) ((55) 5500) ((56 57) 5700) ((58 59 60) 6000) ((61 62) 6200) ((63 64 65) 6500) ((66 67 68 69) 6900) ((70 71 72 73) 7300) ((74 75 76 77) 7700) ((78 79 80) 8000) ((81) 8100) ((82 83) 8300) ((84 85 86 87) 8700) ((88 89 90 91 92) 9200) ((93 94 95) 9500) ((96 97 98) 9800) ((99) 9900) ((100 101 102) 10200) ((103 104 105 106 107) 10700) ((108 109) 10900) ((110 111) 11100) ((112 113 114 115) 11500) ((116) 11600) ((117) 11700) ((118) 11800) ((119 120) 12000) ((121 122 123 124 125) 12500) ((126 127) 12700) ((128) 12800) ((129 130) 13000) ((131 132) 13200) ((133 134 135 136) 13600) ((137 138) 13800)) 10200) (test (case most-positive-fixnum ((-1231234) 0) ((9223372036854775807) 1) (else 2)) 1) (test (case most-negative-fixnum ((123123123) 0) ((-9223372036854775808) 1) (else 2)) 1) (test (case 0 ((3/4 "hi" #t) 0) ((#f #() -1) 2) ((#\a 0 #t) 3) (else 4)) 3) (test (case 3/4 ((3/4 "hi" #t) 0) ((#f #() hi) 2) ((#\a 0 #t) 3) (else 4)) 0) (test (case 'hi ((3/4 "hi" #t) 0) ((#f #() hi) 2) ((#\a 0 #t) 3) (else 4)) 2) (test (case #f ((3/4 "hi" #t) 0) ((#f #() hi) 2) ((#\a 0 #t) 3) (else 4)) 2) (test (case 3 ((3/4 "hi" #t) 0) ((#f #() hi) 2) ((#\a 0 #t) 3) (else 4)) 4) (test (case 0 ((values 0 1) 2) (else 3)) 2) (test (let ((else 3)) (case 0 ((1) 2) (else 3))) 3) ; changed my mind about this -- else is not evaluated here unless it's some other symbol (test (let ((otherwise else)) (case 0 ((1) 2) (otherwise 3))) 3) ; maybe this isn't a great idea... (test (let ((else 3)) (case else ((3) else))) 3) (test (case 0 ((1) 2) (else (let ((else 3)) else))) 3) (test (case 0 ((1) #t) ((2 else 3) #f) ((0) 0)) 0) ; should this be an error? (it isn't in Guile) (test (case 0 ((1) #t) ((else) #f) ((0) 0)) 0) (test (apply case 1 '(((0) -1) ((1) 2))) 2) (test (let ((x #(1))) (apply case x (list (list (list #()) 1) (list (list #(1)) 2) (list (list x) 3) (list 'else 4)))) 3) (test (let ((x 0)) (let ((y (case 1 ((2) (set! x (+ x 3))) ((1) (set! x (+ x 4)) (+ x 2))))) (list x y))) '(4 6)) (let () (define (hi a) (case a ((0) 1) ((1) 2) (else 3))) (test (hi 1) 2) (test (hi 2) 3) (test (hi "hi") 3)) (if with-bignums (begin (test (case 8819522415901031498123 ((1) 2) ((8819522415901031498123) 3) (else 4)) 3) (test (case -9223372036854775809 ((1 9223372036854775807) 2) (else 3)) 3) )) ;;; one thing that will hang case I think: circular key list ;;; C-style case (define-macro (switch selector . clauses) `(call-with-exit (lambda (break) (case ,selector ,@(do ((clause clauses (cdr clause)) (new-clauses ())) ((null? clause) (reverse new-clauses)) (set! new-clauses (cons `(,(caar clause) ,@(cdar clause) ,@(map (lambda (nc) (apply values (cdr nc))) (if (pair? clause) (cdr clause) ()))) new-clauses))))))) (test (switch 1 ((1) (break 1)) ((2) 3) (else 4)) 1) (test (switch 2 ((1) (break 1)) ((2) 3) (else 4)) 4) (test (switch 4 ((1) (break 1)) ((2) 3) (else 4)) 4) (let () (call-with-output-file "test.scm" (lambda (p) (format p "(define (big-cond x)~%") (format p " (cond~%") (do ((i 0 (+ i 1))) ((= i 1000)) (format p " ((= x ~D) x)~%" i)) (format p " ))~%~%") (format p "(define (big-case x)~%") (format p " (case x~%") (do ((i 0 (+ i 1))) ((= i 1000)) (format p " ((~D) x)~%" i)) (format p " ))~%~%"))) (load "test.scm" (curlet)) (test (big-cond 541) 541) (test (big-case 541) 541)) ;;; -------------------------------------------------------------------------------- ;;; lambda ;;; -------------------------------------------------------------------------------- (test (procedure? (lambda (x) x)) #t) (test ((lambda (x) (+ x x)) 4) 8) (test (let ((reverse-subtract (lambda (x y) (- y x)))) (reverse-subtract 7 10)) 3) (test (let ((add4 (let ((x 4)) (lambda (y) (+ x y))))) (add4 6)) 10) (test ((lambda x x) 3 4 5 6) (list 3 4 5 6)) (test ((lambda (x y . z) z) 3 4 5 6) (list 5 6)) (test ((lambda (a b c d e f) (+ a b c d e f)) 1 2 3 4 5 6) 21) (test (let ((foo (lambda () 9))) (+ (foo) 1)) 10) (test (let ((a 1)) (let ((f (lambda (x) (set! a x) a))) (let ((c (f 123))) (list c a)))) (list 123 123)) (test (let ((a 1) (b (lambda (a) a))) (b 3)) 3) (test (let ((ctr 0)) (letrec ((f (lambda (x) (if (> x 0) (begin (set! ctr (+ ctr 1)) (f (- x 1))) 0)))) (f 10) ctr)) 10) (test (let ((f (lambda (x) (car x)))) (f '(4 5 6))) 4) (test ((lambda () ((lambda (x y) ((lambda (z) (* (car z) (cdr z))) (cons x y))) 3 4))) 12) (test (let ((ctr 0)) (define (f) (set! ctr (+ ctr 1)) ctr) (let ((x (f))) (let ((y (f))) (list x y ctr)))) (list 1 2 2)) (test (let ((x 5)) (define foo (lambda (y) (bar x y))) (define bar (lambda (a b) (+ (* a b) a))) (foo (+ x 3))) 45) (test (let ((x 5)) (letrec ((foo (lambda (y) (bar x y))) (bar (lambda (a b) (+ (* a b) a)))) (foo (+ x 3)))) 45) (num-test (let () (define compose (lambda (f g) (lambda args (f (apply g args))))) ((compose sqrt *) 12 75)) 30.0) (let () (define (compose . args) ; this just removes parens (if (procedure? (car args)) (if (null? (cdr args)) ((car args)) ((car args) (apply compose (cdr args)))) (apply values args))) (test (compose - + (lambda (a b c) (values a (* b c))) 2 3 4) -14) (test (- (+ ((lambda (a b c) (values a (* b c))) 2 3 4))) -14)) ; I prefer this (test (let ((f (lambda () (lambda (x y) (+ x y))))) ((f) 1 2)) 3) (test ((lambda (x) (define y 4) (+ x y)) 1) 5) (test ((lambda(x)(define y 4)(+ x y))1) 5) (test ((lambda () (define (y x) (+ x 1)) (y 1))) 2) (test ((lambda (x) 123 (let ((a (+ x 1))) a)) 2) 3) (test ((lambda (x) "documentation" (let ((a (+ x 1))) a)) 2) 3) (test ((lambda (x) (x 1)) (lambda (y) (+ y 1))) 2) (test (let ((a 1)) (let ((b (lambda (x) (define y 1) (define z 2) (define a 3) (+ x y z a)))) (b a))) 7) (test ((lambda (f x) (f x x)) + 11) 22) (test ((lambda () (+ 2 3))) 5) (test (let ((x (let () (lambda () (+ 1 2))))) (x)) 3) (test (cond (0 => (lambda (x) x))) 0) (test ((lambda () "hiho")) "hiho") (test ((lambda()()))()) (test (procedure-source (apply lambda (list) (list (list)))) '(lambda () ())) (test (letrec ((f (lambda (x) (g x))) (g (lambda (x) x))) (let ((top (f 1))) (set! g (lambda (x) (- x))) (+ top (f 1)))) 0) (for-each (lambda (arg) (test ((lambda (x) x) arg) arg)) (list "hi" -1 #\a 1 'a-symbol #(1 2 3) 3.14 3/4 1.0+1.0i #t (list 1 2 3) '(1 . 2))) (let ((list-length (lambda (obj) (call-with-current-continuation (lambda (return) (letrec ((r (lambda (obj) (cond ((null? obj) 0) ((pair? obj) (+ (r (cdr obj)) 1)) (else (return #f)))))) (r obj))))))) (test (list-length '(1 2 3 4)) 4) (test (list-length '(a b . c)) #f)) (test (let ((samples (vector 0 1 2 3 4 5 6 7 8 9 10))) (let ((make-scaler (lambda (start end) (letrec ((ctr start) (us (lambda (them) (vector-set! samples ctr (* 2 (vector-ref samples ctr))) (set! ctr (+ ctr 2)) (if (<= ctr end) (them us))))) us)))) ((make-scaler 0 11) (make-scaler 1 11))) samples) (vector 0 2 4 6 8 10 12 14 16 18 20)) (test ((lambda (x . y) y) 1 2 '(3 . 4)) '(2 (3 . 4))) (test ((lambda (x . y) y) 1) ()) (test ((lambda x x) ()) '(())) (test ((lambda x x)) ()) (test ((lambda (x) x) ()) ()) (test ((lambda (x) (+ x ((lambda (x) (+ x 1)) 2))) 3) 6) (test ((lambda (x) (define y 1) (+ x y)) 2) 3) (test ((lambda (a) "this is a doc string" a) 1) 1) ;;; ideally ((lambda (a) "hiho" (define x 1) x) 1) -> 1 but I'm not sure it's r5rs-ish (test (let ((g (lambda () '3))) (= (g) 3)) #t) (test ((((lambda () lambda)) () 1)) 1) (test (let () ; PLP Scott p168 (define A (lambda () (let* ((x 2) (C (lambda (P) (let ((x 4)) (P)))) (D (lambda () x)) (B (lambda () (let ((x 3)) (C D))))) (B)))) (A)) 2) #| ;;; here s7 "do" uses set! (test (let ((funcs (make-vector 3 #f))) (do ((i 0 (+ i 1))) ((= i 3)) (vector-set! funcs i (lambda () (+ i 1)))) (+ ((vector-ref funcs 0)) ((vector-ref funcs 1)) ((vector-ref funcs 2)))) 6) |# ;;; the equivalent named let version: (test (let ((funcs (make-vector 3 #f))) (let loop ((i 0)) (if (< i 3) (begin (vector-set! funcs i (lambda () (+ i 1))) (loop (+ i 1))))) (+ ((vector-ref funcs 0)) ((vector-ref funcs 1)) ((vector-ref funcs 2)))) 6) (test (let ((i 1)) (let ((func1 (lambda () i))) (let ((i 2)) (let ((func2 (lambda () i))) (+ (func1) (func2)))))) 3) (test (let ((funcs (make-vector 3 #f))) (map (lambda (i) (vector-set! funcs i (lambda () (+ i 1)))) (list 0 1 2)) (+ ((vector-ref funcs 0)) ((vector-ref funcs 1)) ((vector-ref funcs 2)))) 6) (test (let ((funcs (make-vector 3 #f))) (for-each (lambda (i) (vector-set! funcs i (lambda () (+ i 1)))) (list 0 1 2)) (+ ((vector-ref funcs 0)) ((vector-ref funcs 1)) ((vector-ref funcs 2)))) 6) (test (let ((funcs (make-vector 3 #f))) (sort! (list 0 1 2) (lambda (i j) (vector-set! funcs i (lambda () (+ i 1))) (> i j))) (+ ((vector-ref funcs 0)) ((vector-ref funcs 1)) ((vector-ref funcs 2)))) 6) (test (let ((funcs (make-vector 3 #f))) (member 4 (list 0 1 2) (lambda (j i) (vector-set! funcs i (lambda () (+ i 1))) #f)) (+ ((vector-ref funcs 0)) ((vector-ref funcs 1)) ((vector-ref funcs 2)))) 6) (test (let ((funcs (make-vector 3 #f))) (assoc 4 (list (cons 0 0) (cons 1 0) (cons 2 0)) (lambda (j i) (vector-set! funcs i (lambda () (+ i 1))) #f)) (+ ((vector-ref funcs 0)) ((vector-ref funcs 1)) ((vector-ref funcs 2)))) 6) (test (let ((func #f)) (define (func1 x) (set! func (lambda () (+ x 1)))) (func1 1) (+ (func) (let () (func1 2) (func)))) 5) (test (((lambda (x) (lambda () (+ x 1))) 32)) 33) (test (let ((func #f)) (define (func1 x) (set! func (lambda () (string-append x "-")))) (func1 "hi") (string-append (func) (let () (func1 "ho") (func)))) "hi-ho-") (test (let ((func1 #f) (func2 #f)) (let ((x 1)) (set! func1 (lambda () x)) (set! func2 (lambda (y) (set! x y) y))) (+ (func1) (let () (func2 32) (func1)))) 33) (test (let ((funcs (make-vector 3))) (let ((hi (lambda (a) (vector-set! funcs (- a 1) (lambda () a))))) (hi 1) (hi 2) (hi 3) (+ ((vector-ref funcs 0)) ((vector-ref funcs 1)) ((vector-ref funcs 2))))) 6) (test (let ((hi (lambda (a) (+ a 1))) (ho (lambda (a) (a 32)))) (+ (hi (hi (hi 1))) (ho hi))) 37) (test (let ((x 0) (b 4) (f1 #f) (f2 #f)) (let ((x 1)) (let ((x 2)) (set! f1 (lambda (a) (+ a b x))))) (let ((x 3)) (let ((b 5)) (set! f2 (lambda (a) (+ a b x))))) (+ (f1 10) (f2 100))) ; (+ 10 4 2) (+ 100 5 3) 124) (test ((if (> 3 2) + -) 3 2) 5) (test (let ((op +)) (op 3 2)) 5) (test (((lambda () +)) 3 2) 5) (test ((car (cons + -)) 3 2) 5) (test ((do ((i 0 (+ i 1))) ((= i 3) +) ) 3 2) 5) (test (((lambda (x) x) (lambda (x) x)) 3) 3) (test ((((lambda (x) x) (lambda (x) x)) (lambda (x) x)) 3) 3) (test (((lambda (x) (lambda (y) x)) 3) 4) 3) (test (((lambda (x) (lambda (x) x)) 3) 4) 4) (test (let ((x 32)) (((lambda (x) (lambda (y) x)) 3) x)) 3) (test ((call/cc (lambda (return) (return +))) 3 2) 5) (test ((call-with-values (lambda () (values +)) (lambda (x) x)) 3 2) 5) (test ((case '+ ((+) +)) 3 2) 5) (test ((case '+ ((-) -) (else +)) 3 2) 5) (test ((call/cc (lambda (return) (dynamic-wind (lambda () #f) (lambda () (return +)) (lambda () #f)))) 3 2) 5) (test (+ 1 ((call/cc (lambda (return) (dynamic-wind (lambda () #f) (lambda () (return +)) (lambda () #f)))) 3 2) 2) 8) (test (let ((lst (list + -))) ((car lst) 1 2 3)) 6) (test (let ((a +)) ((let ((b -)) (if (eq? a b) a *)) 2 3)) 6) (test ((list-ref (list + - * /) 0) 2 3) 5) (test (((if #t list-ref oops) (list + - * /) 0) 2 3) 5) (test ((((car (list car cdr)) (list car cdr)) (list + -)) 2 3) 5) (test (let () (define function lambda) (define hiho (function (a) (+ a 1))) (hiho 2)) 3) (test ((lambda (a b c d e f g h i j k l m n o p q r s t u v x y z) (+ a b c d e f g h i j k l m n o p q r s t u v x y z)) 1 2 3 4 5 6 7 8 9 11 12 13 14 15 16 17 18 19 21 22 23 24 25 26 27) 348) (test ((lambda (x) "a useless string" x) 32) 32) (test ((lambda (>< =0=? .arg.) (+ >< =0=? .arg.)) 1 2 3) 6) (test ((apply ((lambda () lambda)) ((lambda () (list 'a))) ((lambda () '((+ a 1))))) 3) 4) (define-constant (_?_3 a) #f) (let () (define (hi x) (_?_3 x)) (hi 1) (test (let ((x 1)) (hi x)) #f)) (let () (define (_?_4 x y) x) (define (hi x) (_?_4 x (* x x (+ 1 x)))) (hi 1) (test (let ((x 1)) (hi x)) 1)) (define-constant (_?_5 x) (if (zero? x) x (+ x (_?_5 (- x 1))))) (let () (define (hi x) (_?_5 x)) (hi 1) (test (let ((x 1)) (hi x)) 1)) (let () (define (hi x) (_?_5 (_?_5 1))) (hi 1) (test (hi 1) 1)) (let ((x 1)) (define (hi y) (set! x (* y y y))) (hi 1) (test (hi 1) 1)) (test (let () (begin (define f1 #f) (define f2 #f) (let ((lv 32)) (set! f1 (lambda (a) (+ a lv))) (set! f2 (lambda (a) (- a lv))))) (+ (f1 1) (f2 1))) 2) (test ((lambda () => abs)) 'error) (test ((lambda () => => 3)) 'error) ;; actually, both Guile and Gauche accept ;; ((lambda () + 3)) and (begin + 3) ;; but surely => is an undefined variable in this context? (test (lambda) 'error) (test (lambda (a) ) 'error) ;; should this be an error: (lambda (a) (define x 1)) ? (test (lambda . 1) 'error) (test ((lambda . (x 1))) 1) (test ((lambda . ((x . y) 2)) 1) 2) (test ((lambda (x) . (x)) 1) 1) (test ((lambda . ((x) . (x))) 1) 1) (test ((lambda . (x . (x))) 1) '(1)) (test ((lambda . ((x . ()) x)) 1) 1) (test (eval-string "((lambda . (x 1 . 3)) 1)") 'error) (test (lambda 1) 'error) (test (lambda (x 1) x) 'error) (test (lambda "hi" 1) 'error) (test (lambda (x x) x) 'error) (test ((lambda (x x) x) 1 2) 'error) (test (lambda (x "a")) 'error) (test ((lambda (x y) (+ x y a)) 1 2) 'error) (test ((lambda ())) 'error) (test (lambda (x (y)) x) 'error) (test ((lambda (x) x . 5) 2) 'error) (test (lambda (1) #f) 'error) (test (eval-string "(lambda (x . y z) x)") 'error) (test ((lambda () 1) 1) 'error) (test ((lambda (()) 1) 1) 'error) (test ((lambda (x) x) 1 2) 'error) (test ((lambda (x) x)) 'error) (test ((lambda ("x") x)) 'error) (test ((lambda "x" x)) 'error) (test ((lambda (x . "hi") x)) 'error) (test (lambda ((:hi . "hi") . "hi") 1) 'error) (test ((lambda (x) (* quote ((x . 1) . 2))) 1) 'error) (test ((lambda* (a (quote . -1)) a)) 'error) (test (let ((hi (lambda (a 0.0) (b 0.0) (+ a b)))) (hi)) 'error) (test (object->string ((lambda (arg) (list arg (list (quote quote) arg))) (quote (lambda (arg) (list arg (list (quote quote) arg)))))) "((lambda (arg) (list arg (list 'quote arg))) '(lambda (arg) (list arg (list 'quote arg))))") ;; was "(#1=(lambda (arg) (list arg (list 'quote arg))) '#1#)" (test ((apply lambda '((a) (+ a 1))) 2) 3) (test ((apply lambda '(() #f))) #f) (test ((apply lambda '(arg arg)) 3) '(3)) (test ((apply lambda* '((a (b 1)) (+ a b))) 3 4) 7) (test ((apply lambda* '((a (b 1)) (+ a b))) 3) 4) (let () (define-macro (progv vars vals . body) `(apply (apply lambda ,vars ',body) ,vals)) (test (let ((s '(one two)) (v '(1 2))) (progv s v (+ one two))) 3) (test (progv '(one two) '(1 2) (+ one two)) 3)) (test (lambda #(a b) a) 'error) (test (lambda* (#(a 1)) a) 'error) (test ((lambda (a) a) #) #) (test ((lambda () (let ((a #)) a))) #) (test (let () (define* (foo (a 0) (b (+ a 4)) (c (+ a 7))) (list a b c)) (foo :b 2 :a 60)) '(60 2 67)) (test (let () (define* (f1 (a 0) (b (* 2 a))) (+ a b)) (f1 2)) 6) ; this used to be 2 ;; one oddness: (test (let () (define* (f1 (a (* b 2)) (b 3)) (list a b)) (f1 :b 1)) '(2 1)) ;; (f1) however would be an error? or should we preset args if we can? (let () (define* (f1 (a (+ b 1)) (b (+ a 1))) (list a b)) (test (f1 1) '(1 2)) (test (f1 :b 1) '(2 1)) (test (f1 :b 0 :a 1) '(1 0)) (test (f1 :a 1) '(1 2)) (test (f1 2 3) '(2 3)) (test (f1) 'error)) (let () (define* (f1 (a (if (number? b) (+ b 1) 3)) (b (+ a 1))) (list a b)) (test (f1) '(3 4))) (let () (define* (f1 (a 1) (b (+ a 1))) (+ a b)) (define* (f2 (a (f1))) a) (test (f2) 3)) (let () (define* (f1 (a 1) (b (+ a 1))) (+ a b)) (define* (f2 (a (f1)) (b (f1 2))) (list a b)) (test (f2) '(3 5))) (let () (define-macro (define-f*xpr name-and-args . body) `(define ,(car name-and-args) (apply define-expansion (append (list (append (list (gensym)) ',(cdr name-and-args))) ',body)))) (define-f*xpr (quoth x) x) (test (quoth a) 'a) (test (quoth (+ 1 2)) '(+ 1 2)) (define-f*xpr (mac a) `(+ ,a 1)) (test (mac (* 2 3)) '(+ (* 2 3) 1)) (define-f*xpr (mac1 a . b) `(,@b ,a)) (test (mac1 1 2 3) '(2 3 1))) ;;; -------------------------------------------------------------------------------- ;;; begin ;;; -------------------------------------------------------------------------------- (test (begin) ()) ; I think Guile returns # here (test (begin (begin)) ()) (test ((lambda () (begin))) ()) (test (let () (begin) #f) #f) (test (let () (begin (begin (begin (begin)))) #f) #f) (test (let () (begin (define x 2) (define y 1)) (+ x y)) 3) (test (let () (begin (define x 0)) (begin (set! x 5) (+ x 1))) 6) (test (let () (begin (define first car)) (first '(1 2))) 1) (test (let () (begin (define x 3)) (begin (set! x 4) (+ x x))) 8) (test (let () (begin (define x 0) (define y x) (set! x 3) y)) 0) ; the let's block confusing global defines (test (let () (begin (define x 0) (define y x) (begin (define x 3) y))) 0) (test (let () (begin (define y x) (define x 3) y)) 'error) ; guile says 3 (test (let ((x 12)) (begin (define y x) (define x 3) y)) 12) ; guile says 3 which is letrec-style? (test (begin (define (x) y) (define y 4) (x)) 4) ;; (let ((x 12)) (begin (define y x) y)) is 12 (test (let ((x 3)) (begin x)) 3) (test (begin 3) 3) (test (begin . (1 2)) 2) (test (begin . ()) (begin)) (test (begin . 1) 'error) (test (begin 1 . 2) 'error) (test (begin ("hi" 1)) #\i) (if (equal? (begin 1) 1) (begin (test (let () (begin (define x 0)) (set! x (begin (begin 5))) (begin ((begin +) (begin x) (begin (begin 1))))) 6) (test (let ((x 5)) (begin (begin (begin) (begin (begin (begin) (define foo (lambda (y) (bar x y))) (begin))) (begin)) (begin) (begin) (begin (define bar (lambda (a b) (+ (* a b) a)))) (begin)) (begin) (begin (foo (+ x 3)))) 45) (for-each (lambda (arg) (test (begin arg) arg)) (list "hi" -1 #\a 1 'a-symbol #(1 2 3) 3.14 3/4 1.0+1.0i #t (list 1 2 3) '(1 . 2))) (test (if (= 1 1) (begin 2) (begin 3)) 2) )) (test ((lambda (x) (begin (set! x 1) (let ((a x)) (+ a 1)))) 2) 2) ;;; apparently these can be considered errors or not (guile says error, stklos and gauche do not) (test (begin (define x 0) (+ x 1)) 1) (test ((lambda () (begin (define x 0) (+ x 1)))) 1) (test (let ((f (lambda () (begin (define x 0) (+ x 1))))) (f)) 1) (test ((lambda () (begin (define x 0)) (+ x 1))) 1) (test (let ((f (lambda () (begin (define x 0)) (+ x 1)))) (f)) 1) (test (let ((x 32)) (begin (define x 3)) x) 3) (test ((lambda (x) (begin (define x 3)) x) 32) 3) (test (let* ((x 32) (y x)) (define x 3) y) 32) (test (let ((z 0)) (begin (define x 32)) (begin (define y x)) (set! z y) z) 32) (test (let((z 0))(begin(define x 32))(begin(define y x))(set! z y)z) 32) (test (let ((z 0)) (begin (define x 32) (define y x)) (set! z y) z) 32) (test (let () (begin (define b 1) (begin (define a b) (define b 3)) a)) 1) (test (let () (begin (begin (define a1 1) (begin (define a1 b1) (define b1 3))) a1)) 'error) (test (let () (begin (begin (define (a3) 1)) (begin (define (a3) b3) (define b3 3)) (a3))) 3) ; yow (test (let () (begin (begin (define (a) 1)) (a))) 1) (test (let ((a 1)) (begin (define a 2)) a) 2) (test (+ 1 (begin (values 2 3)) 4) 10) (test (+ 1 (begin (values 5 6) (values 2 3)) 4) 10) (test (let ((hi 0)) (begin (values (define (hi b) (+ b 1))) (hi 2))) 3) ;;; -------------------------------------------------------------------------------- ;;; apply ;;; -------------------------------------------------------------------------------- (test (apply (lambda (a b) (+ a b)) (list 3 4)) 7) (test (apply + 10 (list 3 4)) 17) (test (apply list ()) ()) (test (apply + '(1 2)) 3) (test (apply - '(1 2)) -1) (test (apply max 3 5 '(2 7 3)) 7) (test (apply cons '((+ 2 3) 4)) '((+ 2 3) . 4)) (test (apply + ()) 0) (test (apply + (list 3 4)) 7) (test (apply + ()) 0) (test (apply + 2 '(3)) 5) (test (apply + 2 3 ()) 5) (test (apply + '(2 3)) 5) (test (apply list 1 '(2 3)) (list 1 2 3)) (test (apply apply (list list 1 2 '(3))) (list 1 2 3)) (test (vector? (apply make-vector '(1))) #t) (test (apply make-vector '(1 1)) #(1)) (test (apply make-vector '((1) 1)) #(1)) (test (let ((f +)) (apply f '(1 2))) 3) (test (apply min '(1 2 3 5 4 0 9)) 0) (test (apply min 1 2 4 3 '(4 0 9)) 0) (test (apply vector 1 2 '(3)) #(1 2 3)) (test (apply vector ()) #()) (test (apply (lambda (x . y) x) (list 1 2 3)) 1) (test (apply * (list 2 (apply + 1 2 '(3)))) 12) (test (apply (if (> 3 2) + -) '(3 2)) 5) (test (let ((x (list 1 2))) (eq? x (append () x))) #t) ;; ?? guile says #t also (test (apply (lambda* args args) 1 2 3 '(4 5 6 (7))) '(1 2 3 4 5 6 (7))) ; from lisp bboard (test (apply (list 1 2) '(0)) 1) (test (apply (cons 1 2) '(0)) 1) ; ! (apply (cons 1 2) '(1)) is an error (test (procedure? apply) #t) (test (help apply) "(apply func ...) applies func to the rest of the arguments") (let ((lst (list 'values 'procedure? #t))) ; values rather than #t since (+ (apply values '(1 2))) -> 3 (set-cdr! (cddr lst) (cddr lst)) (test (equal? lst (procedure-signature apply)) #t)) (for-each (lambda (arg) (test (apply (lambda (x) x) (list arg)) arg)) (list "hi" -1 #\a 1 'a-symbol #(1 2 3) 3.14 3/4 1.0+1.0i #t (list 1 2 3) '(1 . 2))) (test (apply cadadr (list '''4)) 4) (test (apply string-ref "hi" '(0)) #\h) (test (let ((x (string-copy "hi"))) (apply string-set! x 0 '(#\c)) x) "ci") (test (apply apply (list + '(3 2))) 5) (test (apply apply apply apply (list (list (list + '(3 2))))) 5) (test (apply + 1 2 (list 3 4)) 10) (test ((apply cdr '((1 2) (3 4)) ()) 0) '(3 4)) (test ((apply car '((1 2) (3 4)) ()) 1) 2) (test ((apply cadr '((1 2) (3 4)) ()) 1) 4) (test (apply append ()) ()) (test (apply apply append ()) ()) (test (apply apply apply append '(())) ()) (test (apply apply + ()) 0) (test (apply apply * ()) 1) (test (apply apply not not () ()) #f) (test (apply apply apply eq? eq? eq? () () ()) #t) (test (apply apply apply list list list () () ()) (list list list)) (test (apply apply vector cons (list '1 '2) ()) (vector cons 1 2)) (test (let ((x '(((1 2)) ((3 4))))) (catch #t (lambda () (apply apply apply apply x)) (lambda args 'error)) x) '(((1 2)) ((3 4)))) (test (let ((x '((1 2) (3 4)))) (catch #t (lambda () (apply apply apply apply x)) (lambda args 'error)) x) '((1 2) (3 4))) (test (let ((x '((1 2) 3 4))) (catch #t (lambda () (apply apply apply x)) (lambda args 'error)) x) '((1 2) 3 4)) (test (let ((x '((1 2) (3 4)))) (catch #t (lambda () (apply apply apply not x)) (lambda args 'error)) x) '((1 2) (3 4))) (test (eq? (apply apply apply values '(())) #) #t) (test (eqv? (apply apply apply values '(())) #) #t) (test (equal? (apply apply apply values '(())) #) #t) (test (apply apply apply + '(((1)))) 1) (test (apply apply map + '(((1)))) '(1)) (test (apply apply map quote '(((1)))) '(1)) (test (apply apply map values '(((1)) ((2)))) '((1) 2)) (test (apply apply map append '(((1)) ((2)))) '((1 . 2))) (test (apply apply apply quote '(((1)))) 1) (test (apply map cdr '(((1 2) (3 4)))) '((2) (4))) (test (apply apply + '((1 2))) 3) (test (apply apply cons '(((1 2) (3 4)))) '((1 2) 3 4)) (test (apply apply append '(((1 2) (3 4)))) '(1 2 3 4)) (test (apply map + '((1 2) (3 4))) '(4 6)) (test (apply map reverse '(((1 2) (3 4)))) '((2 1) (4 3))) (test (apply apply map cons '(((1 2) (3 4)))) '((1 . 3) (2 . 4))) (test (apply apply map list-tail '(((1 2) (3 4))) '(((1)))) '(((3 4)))) (test (apply apply map reverse '((1 2) (3 4)) '(())) '((2 1) (4 3))) (test (apply apply map values '(((1)) ((2))) '(((1 2) (3 4)))) '(((1)) 1 3 ((2)) 2 4)) (test (apply apply map append '(((1 2) (3 4))) '(((1)) ((2)))) '(((1 2) (3 4) 1 . 2))) (test (apply apply map append '(()) '(((1)) ((2)))) '((1 . 2))) (test (apply apply map cdr '(((1 2) (3 4))) ()) '((2) (4))) (test (apply apply apply list-tail '((1 2) (3 4)) '(((1)))) '((3 4))) (test (apply apply apply reverse '(((1 2) (3 4))) '(())) '((3 4) (1 2))) (test (apply apply apply values '(1) '(())) 1) (test (apply apply apply values '(1) '((()))) '(1)) (test (apply apply apply values '((1)) ()) 1) (test (apply apply apply values '((1)) '(())) '(1)) (test (apply apply reverse '(((1 2) (3 4))) ()) '((3 4) (1 2))) (test (apply apply append () '(((1 2) (3 4)))) '(1 2 3 4)) (test (apply apply length '(()) ()) 0) (test (apply apply let () '((1))) 1) (test (apply apply apply apply + '((()))) 0) (test (apply apply apply map reverse '((1 2) (3 4)) '((()))) '((2 1) (4 3))) (test (apply apply apply map values '(((1 2) (3 4))) ()) '(1 3 2 4)) (test (apply apply apply apply + '(1) '((()))) 1) (test (apply apply apply append (reverse '(((1)) ((2))))) '((2) . 1)) (test (apply apply map append (reverse '(((1)) ((2))))) '((2 . 1))) (test (apply (apply apply lambda (quote '(1)))) 1) (test (apply quote (map reverse (reverse '((1 2))))) '(2 1)) (test (map quote (apply map + '((1 2) (3 4)))) '(4 6)) (test (map car (apply map quote '(((1 2) (3 4))))) '(1 3)) (test (apply length (apply map append '(((1)) ((2))) '((1)))) -1) (test (apply append (apply map list-tail '(((1 2) (3 4))) '((1)))) '((3 4))) (test (apply append (apply map values '(((1)) ((2))) '(((1 2) (3 4))))) '((1) 1 2 (2) 3 4)) (test (apply append (apply map values '((1 2) (3 4)) '(((1 2) (3 4))))) '(1 2 1 2 3 4 3 4)) (test (apply append '((1) () (2 3 4) (5 6) ())) '(1 2 3 4 5 6)) (test (apply append '((1) () (2 3 4) (5 6) 7)) '(1 2 3 4 5 6 . 7)) (test (apply +) 0) (test (apply + #f) 'error) (test (apply #f '(2 3)) 'error) (test (apply make-vector '(1 2 3)) 'error) (test (apply + 1) 'error) (test (apply) 'error) (test (apply 1) 'error) (test (apply . 1) 'error) (test (apply car ''foo) 'error) (test (apply + '(1 . 2)) 'error) (test (apply + '(1 2 . 3)) 'error) (test (apply () ()) 'error) (test (apply list '(1 . 2) ()) '((1 . 2))) (test (apply (lambda (x) x) _ht_ _null_ _c_obj_) 'error) (test (apply + #(1 2 3)) 'error) (test (apply (lambda (a b) (+ a b)) '(1 . 2)) 'error) (test (apply (lambda args (apply + args)) 1 2 3) 'error) (test (apply (lambda args (apply + args)) 1 2 #f) 'error) (test (apply (lambda args (apply list args)) 1 2 #f) 'error) (test (apply (lambda args (apply + args)) 1 2 ()) 3) (test (apply (lambda args (apply list args)) 1 2 ()) '(1 2)) (test (apply (lambda args (apply list args)) 1 '(2)) '(1 2)) (test (apply (lambda args (apply list args)) 1 '2) 'error) (test (apply (lambda args (apply list args)) 1 'abs) 'error) (test (apply (lambda args (apply list args)) 1 ''2) '(1 quote 2)) (test (apply (lambda args (apply list args)) () ()) '(())) (test (apply (lambda args (apply list args)) () (cons 1 2)) 'error) (test (apply (lambda args (apply list args)) (cons 1 2)) 'error) (test (apply "hi" '(1 2)) 'error) (test ("hi" 1 2) 'error) (test (apply '(1 2) '(1 2)) 'error) (test ((list 1 2 3) 1 2) 'error) (test (apply "hi" '(1)) #\i) (test ("hi" 1) #\i) (test (apply '(1 2) '(1)) 2) (test ((list 1 2 3) 1) 2) (for-each (lambda (arg) (test (apply arg '(1)) 'error) (test (apply abs arg) 'error)) (list -1 #\a 1 'a-symbol 3.14 3/4 1.0+1.0i #t)) (test (apply "hi" '(1)) #\i) (test (apply '(1 2 3) '(1)) 2) (test (apply #(1 2 3) '(2)) 3) (test (apply #2D((1 2) (3 4)) 0 0 ()) 1) (test (apply '((1 2) (3 4)) 1 0 ()) 3) (test (let ((ht (make-hash-table))) (set! (ht "hi") 32) (apply ht '("hi"))) 32) (test (let ((x (list 1 2))) (set-cdr! x x) (apply + x)) 'error) (test (apply + '(1 2 . 3)) 'error) (test (apply + '(1 2) (list 3 4)) 'error) (test (let () (define (mrec a b) (if (<= b 0) (list a) (apply mrec (list a) (list (- b 1))))) (mrec (list 1 2) 5)) '(((((((1 2)))))))) (let ((lst (list 1 2 3))) (set! (cdr (cddr lst)) lst) (test (apply + lst) 'error)) (test (let ((lst '(1 2 3))) (let ((lst1 (apply list lst))) (set! (car lst1) 21) lst)) '(1 2 3)) (test (let ((lst '(1 2))) (let ((lst1 (apply cons lst))) (set! (car lst1) 21) lst)) '(1 2)) (test (let* ((x '(1 2 3)) (y (apply list x))) (eq? x y)) #f) ; this was #t until 26-Sep-11 (test (apply values (values (cons 1 ()))) 1) (test (+ (apply values (values (list 1 2)))) 3) (test (port-filename) (apply port-filename (list))) (num-test (apply atan (#(1 #\a (3)) (max (values 1 2)))) 1.2490457723983) (test (apply #2D((1 2) (3 4)) (list (floor (acosh 1)))) #(1 2)) (test ((apply values (list + 1 2)) 3) 6) (if with-complex (num-test (* 0-2i (acosh (asin 0.0))) pi)) (test (apply truncate (lognot (min 1)) (list)) -2) (num-test (apply /(list 11 11)) 1) (test (apply dynamic-wind (list (lambda () #f) (lambda () 1) (lambda () #f))) 1) (test (apply call-with-exit (list (lambda (exit) 1))) 1) (test (apply call-with-exit (list (lambda (exit) (exit 1) 32))) 1) (test (apply catch (list #t (lambda () 1) (lambda args 'error))) 1) (test (apply eval '((+ 1 2))) 3) (test (apply eval ()) 'error) ; (eval) is an error -- should it be? (eval ()) is () so perhaps (following values), (eval) -> #? (test (apply eval '(())) ()) (test (apply eval-string '("(+ 1 2)")) 3) (test (let () (apply begin '((define x 1) (define y x) (+ x y)))) 2) (test (apply begin ()) (begin)) (test (apply if '(#f 1 2)) 2) (test (apply if '(#f)) 'error) (test (let ((x 1)) (apply set! '(x 3)) x) 3) (test (let ((x 3)) (apply set! (list (values 'x 32))) x) 32) (test (let ((x 1)) (apply cond '(((= x 2) 3) ((= x 1) 32)))) 32) (test (apply and '((= 1 1) (> 2 3))) #f) (test (apply and ()) (and)) (test (apply or '((= 1 1) (> 2 3))) #t) (test (apply or ()) (or)) (test (let () (apply define '(x 32)) x) 32) (test (let () (apply define* '((hi (a 1) (b 2)) (+ a b))) (hi 32)) 34) (test ((apply lambda '((n) (+ n 1))) 2) 3) (test ((apply lambda* '(((n 1)) (+ n 1)))) 2) (test (apply let '(((x 1)) (+ x 2))) 3) (test (apply let* '(((x 1) (y (* 2 x))) (+ x y))) 3) (test (equal? (apply let* '((a 2) (b (+ a 3))) '(list + a b) ()) (list + 2 5)) #t) (test (apply let 'func '((i 1) (j 2)) '((+ i j (if (> i 0) (func (- i 1) j) 0)))) 5) (test (let () (apply define-macro `((hiho a) `(+ ,a 1))) (hiho 2)) 3) (test (let () (apply defmacro `(hiho (a) `(+ ,a 1))) (hiho 2)) 3) (test (let () (apply defmacro* `(hiho ((a 2)) `(+ ,a 1))) (hiho)) 3) (test (let () (apply define-macro* `((hiho (a 2)) `(+ ,a 1))) (hiho)) 3) (test (apply do '(((i 0 (+ i 1))) ((= i 3) i))) 3) (test (apply case '(1 ((2 3) 4) ((1 5) 32))) 32) (test (+ (apply values '(1 2 3))) 6) (test (apply quote '(1)) 1) (test (apply quote ()) 'error) ; (quote) is an error (test (let () (apply letrec '(() (define x 9) x))) 9) (test ((lambda (n) (apply n '(((x 1)) (+ x 2)))) let) 3) (test ((apply lambda (list (apply let (list (list) (quote (list (apply case '(0 ((0 1) 'n))))))) (quasiquote (+ n 1)))) 2) 3) (test (apply let '((x 1)) '((+ x 1))) 2) (test ((apply dilambda (list (lambda (x) (+ x 1)) (lambda (x y) (+ x y)))) 23) 24) (test (apply (apply dilambda (list (lambda (x) (+ x 1)) (lambda (x y) (+ x y)))) '(23)) 24) (test (apply map list '((1 one) (2 two) (3 three))) '((1 2 3) (one two three))) ; from scheme bboard ;;; so (define (unzip l) (apply values (apply map list l))) (test (apply 'begin) 'error) (test (apply and) #t) (test (apply begin) ()) (test (apply if '((> 1 2) 3 4)) 4) (test (apply or) #f) (test (apply quote '(1)) 1) (let () (define (min-max arg . args) (if (null? args) (apply max arg) (min (apply max arg) (apply min-max args)))) (test (min-max '(1 2 3) '(0 -1 4)) 3) (test (min-max '(1 2 3) '(0 -1 4) '(1 2)) 2)) ;;; -------------------------------------------------------------------------------- ;;; define ;;; -------------------------------------------------------------------------------- ;;; trying to avoid top-level definitions here (let () (define x 2) (test (+ x 1) 3) (set! x 4) (test (+ x 1) 5) (let () (define (tprint x) #t) (test (tprint 56) #t) (let () (define first car) (test (first '(1 2)) 1) (let () (define foo (lambda () (define x 5) x)) (test (foo) 5) (let () (define (foo x) ((lambda () (define x 5) x)) x) (test (foo 88) 88)))))) (test (letrec ((foo (lambda (arg) (or arg (and (procedure? foo) (foo 99)))))) (define bar (foo #f)) (foo #f)) 99) (test (letrec ((foo 77) (bar #f) (retfoo (lambda () foo))) (define baz (retfoo)) (retfoo)) 77) (test (let () (define .. 1) ..) 1) (test (let () (define (hi a) (+ a 1)) (hi 2)) 3) (test (let () (define (hi a . b) (+ a (cadr b) 1)) (hi 2 3 4)) 7) (test (let () (define (hi) 1) (hi)) 1) (test (let () (define (hi . a) (apply + a)) (hi 1 2 3)) 6) (for-each (lambda (arg) (test (let () (define x arg) x) arg)) (list "hi" -1 #\a 1 'a-symbol #(1 2 3) 3.14 3/4 1.0+1.0i #t (list 1 2 3) '(1 . 2))) (test ((lambda (x) (define (hi a) (+ a 1)) (hi x)) 1) 2) (test (let ((x 2)) (define f (lambda (y) (+ y x))) (f 3)) 5) (begin (define r5rstest-plus (lambda (x y) (+ x y))) (define r5rstest-x 32)) (test (r5rstest-plus r5rstest-x 3) 35) (test (let ((x 2.0)) (define (hi a) (set! a 3.0)) (hi x) x) 2.0) (test (let () (define (asdf a) (define (asdf a) (+ a 1)) (+ a (asdf a))) (asdf 4)) 9) (test (let ((asdf 1)) (define (asdf a) (define (asdf a) (+ a 1)) (+ a (asdf a))) (asdf 4)) 9) (test (let () (define (a1 a) (define (a2 a) (define (a3 a) (define (a4 a) (+ a 1)) (+ (a4 a) 1)) (+ (a3 a) 1)) (+ (a2 a) 1)) (a1 0)) 4) (test (let () (define (hi1 a) (define (hi1 b) (+ b 1)) (hi1 a)) (hi1 1)) 2) (test (let () (define (hi1 a) (begin (define (hi1 b) (+ b 1))) (hi1 a)) (hi1 1)) 2) (test (let ((j 0) (k 0)) (define (hi1 a) (let ((hi1 (lambda (b) (set! k (+ k 1)) (hi1 (- b 1))))) (if (<= a 0) (list j k) (begin (set! j (+ j 1)) (hi1 (- a 1)))))) (hi1 3)) '(2 2)) (test (procedure? (let () (define (a) a) (a))) #t) (let ((oddp (lambda (a) (not (even? a))))) (define (hi a) (and (a 123) (a 321))) (test (hi oddp) #t)) (test (define) 'error) (test (define*) 'error) (test (define x) 'error) (test (define . x) 'error) (test (define x 1 2) 'error) (test (define x x) 'error) (test (define x x x) 'error) (test (define x x . x) 'error) (test (let ((x 0)) (define x (x . x))) 'error) (test (define (x x) . x) 'error) (test (eval-string "(define (x .) 1)") 'error) ; need eval-string else a read error that halts our tests (test (eval-string "(define (x) (+ 1 .))") 'error) (test (define (x x) x . x) 'error) (test (let () (define (x x) x) (x 0)) 0) (test (define (x 1)) 'error) (test (define (x)) 'error) (test (define 1 2) 'error) (test (define "hi" 2) 'error) (test (define :hi 2) 'error) (test (define x 1 2) 'error) (test (define x 1 . 2) 'error) (test (define x . 1) 'error) (test (define x (lambda ())) 'error) (test (define # 3) 'error) (test (define (#) 4) 'error) (test (define (:hi a) a) 'error) (test (define (hi: a) a) 'error) (test (define (#b1 a) a) 'error) (test (define (hi #b1) #b1) 'error) (test (define () 1) 'error) (test (let() (define #(hi a) a)) 'error) (test (let () (define hi (lambda args args)) (hi 1 . 2)) 'error) (test (let () (define . 1) 1) 'error) (test (let () (define func (do () (#t (lambda (y) 2)))) (func 1)) 2) (test (let () (define* x 3)) 'error) (test (let () (define (hi) 1 . 2)) 'error) (test (let () (define (hi) (1) . "hi")) 'error) (let () (define a#b 3) (define a'b 4) (define a,b 5) (define a[b 6) (define a@b 7) (define a\b 8) (define a|b 9) (test (+ a#b a'b a,b a[b a@b a\b a|b) 42)) (let () (define (make-func) (define (a-func a) (+ a 1))) (test (procedure? (make-func)) #t)) (let () (test (if (and (define x 3) (define y 4)) (+ x y)) 7)) (let () (test (if (not (and (define x 2) (define y 4))) (+ x y) (if (define x 3) x)) 3)) (let () (test (if (and (define x 2) (not (define y 4))) (+ x y) (- x y)) -2)) (test (let () (define (f a) (lambda () a)) (+ ((f 1)) ((f 2)))) 3) (test (let () (define (hi) (let ((a 1)) (set! a 2) (define (ho) a) (set! a 3) (ho))) (hi)) 3) ;;; (define-macro (make-lambda args . body) `(apply lambda* ',args '(,@body))): (make-lambda (a b) (+ a b)) ;; y combinator example from some CS website (let () (define Y (lambda (X) ((lambda (procedure) (X (lambda (arg) ((procedure procedure) arg)))) (lambda (procedure) (X (lambda (arg) ((procedure procedure) arg))))))) (define M (lambda (func-arg) (lambda (l) (if (null? l) 'no-list (if (null? (cdr l)) (car l) (max (car l) (func-arg (cdr l)))))))) (test ((Y M) '(4 5 6 3 4 8 6 2)) 8)) (test (((lambda (X) ((lambda (procedure) (X (lambda (arg) ((procedure procedure) arg)))) (lambda (procedure) (X (lambda (arg) ((procedure procedure) arg)))))) (lambda (func-arg) (lambda (n) (if (zero? n) 1 (* n (func-arg (- n 1))))))) 5) 120) ;;; from a paper by Mayer Goldberg (let () (define curry-fps (lambda fs (let ((xs (map (lambda (fi) (lambda xs (apply fi (map (lambda (xi) (lambda args (apply (apply xi xs) args))) xs)))) fs))) (map (lambda (xi) (apply xi xs)) xs)))) (define E (lambda (even? odd?) (lambda (n) (if (zero? n) #t ; return Boolean True (odd? (- n 1)))))) (define O (lambda (even? odd?) (lambda (n) (if (zero? n) #f ; return Boolean False (even? (- n 1)))))) (define list-even?-odd? (curry-fps E O)) (define new-even? (car list-even?-odd?)) (define new-odd? (cadr list-even?-odd?)) (test (new-even? 6) #t) (test (new-odd? 6) #f)) (let () (define (Cholesky:decomp P) ;; from Marco Maggi based on a Scheme bboard post ;; (Cholesky:decomp '((2 -2) (-2 5))) -> ((1.4142135623731 0) (-1.4142135623731 1.7320508075689)) (define (Cholesky:make-square L) (define (zero-vector n) (if (zero? n) () (cons 0 (zero-vector (- n 1))))) (map (lambda (v) (append v (zero-vector (- (length L) (length v))))) L)) (define (Cholesky:add-element P L i j) (define (Cholesky:smaller P) (if (null? (cdr P)) () (reverse (cdr (reverse P))))) (define (Cholesky:last-row L) (car (reverse L))) (define (matrix:element A i j) (list-ref (list-ref A i) j)) (define (Cholesky:make-element P L i j) (define (Cholesky:partial-sum L i j) (let loop ((k j)) (case k ((0) 0) ((1) (* (matrix:element L i 0) (matrix:element L j 0))) (else (+ (* (matrix:element L i k) (matrix:element L j k)) (loop (- k 1))))))) (let ((x (- (matrix:element P i j) (Cholesky:partial-sum L i j)))) (if (= i j) (sqrt x) (/ x (matrix:element L j j))))) (if (zero? j) (append L `((,(Cholesky:make-element P L i j)))) (append (Cholesky:smaller L) (list (append (Cholesky:last-row L) (list (Cholesky:make-element P L i j))))))) (Cholesky:make-square (let iter ((i 0) (j 0) (L ())) (if (>= i (length P)) L (iter (if (= i j) (+ 1 i) i) (if (= i j) 0 (+ 1 j)) (Cholesky:add-element P L i j)))))) (let* ((lst (Cholesky:decomp '((2 -2) (-2 5)))) (lst0 (car lst)) (lst1 (cadr lst))) (if (or (> (abs (- (car lst0) (sqrt 2))) .0001) (not (= (cadr lst0) 0)) (> (abs (+ (car lst1) (sqrt 2))) .0001) (> (abs (- (cadr lst1) (sqrt 3))) .0001)) (format-logged #t ";cholesky decomp: ~A~%" lst)))) (let () (define* (a1 (b (let () (define* (a1 (b 32)) b) (a1)))) b) (test (a1) 32) (test (a1 1) 1)) (test (let ((x 1)) (cond (else (define x 2))) x) 2) (test (let ((x 1)) (and (define x 2)) x) 2) (test (let () (begin 1)) 1) (test (let () (begin (define x 1) x)) 1) (test (let () (let ((lst (define abc 1))) #f) abc) 1) ; ?? (test (let () (let ((lst (define abc 1))) abc)) 1) ; abcd is in the outer let (test (let () (letrec ((lst (define abcd 1))) #f) abcd) 'error) ; abcd: unbound variable (test (let () (letrec ((lst (define abcd 1))) abcd)) 1) (test (let? (let () (letrec ((lst (define abcd 1))) (curlet)))) #t) (test (let () (letrec* ((lst (define abcd 1))) abcd)) 1) ; unproblematic because no pending value ;(test (let () (define (f a) (if (symbol? a) b 0)) (f (define b 3))) 3) ; 25-Jul-14 (test (let () (+ (define b 1) (* b 2))) 3) (test (let () (if (define b 3) b)) 3) (test (let () (do ((i (define b 3)) (j 0 (+ j 1))) ((= j 0) b))) 3) (test (let () (define* (f (a (define b 3))) a) (f) b) 'error) ; ?? where is b? (test (let () (define* (f (a (define b 3))) b) (f)) 3) ; inside the func apparently! 3 cases? let->outer letrec->cur, func->inner! ;(test (let () (define* (f (a (define a 3))) a) (f)) 'a) ; yow -- no duplicate id check! 25-Jul-14 (test (let () (define* (f (a 1) (b (define a 3))) a) (f 2)) 3) (test (let () (define-macro* (f (a 1) (b (define a 3))) a) (f 2)) 2) ; also bacro -- b is '(define a 3)! ;(test (let () (letrec ((a (define a 3))) a)) 'a) ; letrec is the same (it checks normally) 25-Jul-14 (test (let () (letrec ((a 1) (b (define a 3))) a)) 1) (test (let () (letrec* ((a 1) (b (define a 3))) a)) 3) ; same difference in let/let* (test (let () (letrec ((a 1) (b (set! a 3))) a)) 1) (test (let () (letrec* ((a 1) (b (set! a 3))) a)) 3) ; here the let case is an error, let* is 3 ;(test (let () (list (with-let (sublet (curlet) (cons 'b (define b 3))) b) ((curlet) 'b))) '(b 3)) ; 2 b's with 1 define ;(test (let () (list (with-let (varlet (curlet) (cons 'b (define b 3))) b) ((curlet) 'b))) '(b b)) (let () (define (f64 arg0 arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10 arg11 arg12 arg13 arg14 arg15 arg16 arg17 arg18 arg19 arg20 arg21 arg22 arg23 arg24 arg25 arg26 arg27 arg28 arg29 arg30 arg31 arg32 arg33 arg34 arg35 arg36 arg37 arg38 arg39 arg40 arg41 arg42 arg43 arg44 arg45 arg46 arg47 arg48 arg49 arg50 arg51 arg52 arg53 arg54 arg55 arg56 arg57 arg58 arg59 arg60 arg61 arg62 arg63 arg64) (+ arg0 arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10 arg11 arg12 arg13 arg14 arg15 arg16 arg17 arg18 arg19 arg20 arg21 arg22 arg23 arg24 arg25 arg26 arg27 arg28 arg29 arg30 arg31 arg32 arg33 arg34 arg35 arg36 arg37 arg38 arg39 arg40 arg41 arg42 arg43 arg44 arg45 arg46 arg47 arg48 arg49 arg50 arg51 arg52 arg53 arg54 arg55 arg56 arg57 arg58 arg59 arg60 arg61 arg62 arg63 arg64)) (test (f64 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64) 2080)) #| (let ((n 12)) (let ((nums (do ((lst () (cons i lst)) (i 0 (+ i 1))) ((> i n) (reverse lst))))) (format-logged #t "(let ((f~D (lambda (~{arg~D~^ ~})~% (+ ~{arg~D~^ ~}))))~% (f~D ~{~D~^ ~}))~%" n nums nums n nums))) |# (test (let ((f128 (lambda (arg128 arg127 arg126 arg125 arg124 arg123 arg122 arg121 arg120 arg119 arg118 arg117 arg116 arg115 arg114 arg113 arg112 arg111 arg110 arg109 arg108 arg107 arg106 arg105 arg104 arg103 arg102 arg101 arg100 arg99 arg98 arg97 arg96 arg95 arg94 arg93 arg92 arg91 arg90 arg89 arg88 arg87 arg86 arg85 arg84 arg83 arg82 arg81 arg80 arg79 arg78 arg77 arg76 arg75 arg74 arg73 arg72 arg71 arg70 arg69 arg68 arg67 arg66 arg65 arg64 arg63 arg62 arg61 arg60 arg59 arg58 arg57 arg56 arg55 arg54 arg53 arg52 arg51 arg50 arg49 arg48 arg47 arg46 arg45 arg44 arg43 arg42 arg41 arg40 arg39 arg38 arg37 arg36 arg35 arg34 arg33 arg32 arg31 arg30 arg29 arg28 arg27 arg26 arg25 arg24 arg23 arg22 arg21 arg20 arg19 arg18 arg17 arg16 arg15 arg14 arg13 arg12 arg11 arg10 arg9 arg8 arg7 arg6 arg5 arg4 arg3 arg2 arg1 arg0) (+ arg128 arg127 arg126 arg125 arg124 arg123 arg122 arg121 arg120 arg119 arg118 arg117 arg116 arg115 arg114 arg113 arg112 arg111 arg110 arg109 arg108 arg107 arg106 arg105 arg104 arg103 arg102 arg101 arg100 arg99 arg98 arg97 arg96 arg95 arg94 arg93 arg92 arg91 arg90 arg89 arg88 arg87 arg86 arg85 arg84 arg83 arg82 arg81 arg80 arg79 arg78 arg77 arg76 arg75 arg74 arg73 arg72 arg71 arg70 arg69 arg68 arg67 arg66 arg65 arg64 arg63 arg62 arg61 arg60 arg59 arg58 arg57 arg56 arg55 arg54 arg53 arg52 arg51 arg50 arg49 arg48 arg47 arg46 arg45 arg44 arg43 arg42 arg41 arg40 arg39 arg38 arg37 arg36 arg35 arg34 arg33 arg32 arg31 arg30 arg29 arg28 arg27 arg26 arg25 arg24 arg23 arg22 arg21 arg20 arg19 arg18 arg17 arg16 arg15 arg14 arg13 arg12 arg11 arg10 arg9 arg8 arg7 arg6 arg5 arg4 arg3 arg2 arg1 arg0)))) (f128 128 127 126 125 124 123 122 121 120 119 118 117 116 115 114 113 112 111 110 109 108 107 106 105 104 103 102 101 100 99 98 97 96 95 94 93 92 91 90 89 88 87 86 85 84 83 82 81 80 79 78 77 76 75 74 73 72 71 70 69 68 67 66 65 64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0)) 8256) (test (let ((f512 (lambda (arg0 arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10 arg11 arg12 arg13 arg14 arg15 arg16 arg17 arg18 arg19 arg20 arg21 arg22 arg23 arg24 arg25 arg26 arg27 arg28 arg29 arg30 arg31 arg32 arg33 arg34 arg35 arg36 arg37 arg38 arg39 arg40 arg41 arg42 arg43 arg44 arg45 arg46 arg47 arg48 arg49 arg50 arg51 arg52 arg53 arg54 arg55 arg56 arg57 arg58 arg59 arg60 arg61 arg62 arg63 arg64 arg65 arg66 arg67 arg68 arg69 arg70 arg71 arg72 arg73 arg74 arg75 arg76 arg77 arg78 arg79 arg80 arg81 arg82 arg83 arg84 arg85 arg86 arg87 arg88 arg89 arg90 arg91 arg92 arg93 arg94 arg95 arg96 arg97 arg98 arg99 arg100 arg101 arg102 arg103 arg104 arg105 arg106 arg107 arg108 arg109 arg110 arg111 arg112 arg113 arg114 arg115 arg116 arg117 arg118 arg119 arg120 arg121 arg122 arg123 arg124 arg125 arg126 arg127 arg128 arg129 arg130 arg131 arg132 arg133 arg134 arg135 arg136 arg137 arg138 arg139 arg140 arg141 arg142 arg143 arg144 arg145 arg146 arg147 arg148 arg149 arg150 arg151 arg152 arg153 arg154 arg155 arg156 arg157 arg158 arg159 arg160 arg161 arg162 arg163 arg164 arg165 arg166 arg167 arg168 arg169 arg170 arg171 arg172 arg173 arg174 arg175 arg176 arg177 arg178 arg179 arg180 arg181 arg182 arg183 arg184 arg185 arg186 arg187 arg188 arg189 arg190 arg191 arg192 arg193 arg194 arg195 arg196 arg197 arg198 arg199 arg200 arg201 arg202 arg203 arg204 arg205 arg206 arg207 arg208 arg209 arg210 arg211 arg212 arg213 arg214 arg215 arg216 arg217 arg218 arg219 arg220 arg221 arg222 arg223 arg224 arg225 arg226 arg227 arg228 arg229 arg230 arg231 arg232 arg233 arg234 arg235 arg236 arg237 arg238 arg239 arg240 arg241 arg242 arg243 arg244 arg245 arg246 arg247 arg248 arg249 arg250 arg251 arg252 arg253 arg254 arg255 arg256 arg257 arg258 arg259 arg260 arg261 arg262 arg263 arg264 arg265 arg266 arg267 arg268 arg269 arg270 arg271 arg272 arg273 arg274 arg275 arg276 arg277 arg278 arg279 arg280 arg281 arg282 arg283 arg284 arg285 arg286 arg287 arg288 arg289 arg290 arg291 arg292 arg293 arg294 arg295 arg296 arg297 arg298 arg299 arg300 arg301 arg302 arg303 arg304 arg305 arg306 arg307 arg308 arg309 arg310 arg311 arg312 arg313 arg314 arg315 arg316 arg317 arg318 arg319 arg320 arg321 arg322 arg323 arg324 arg325 arg326 arg327 arg328 arg329 arg330 arg331 arg332 arg333 arg334 arg335 arg336 arg337 arg338 arg339 arg340 arg341 arg342 arg343 arg344 arg345 arg346 arg347 arg348 arg349 arg350 arg351 arg352 arg353 arg354 arg355 arg356 arg357 arg358 arg359 arg360 arg361 arg362 arg363 arg364 arg365 arg366 arg367 arg368 arg369 arg370 arg371 arg372 arg373 arg374 arg375 arg376 arg377 arg378 arg379 arg380 arg381 arg382 arg383 arg384 arg385 arg386 arg387 arg388 arg389 arg390 arg391 arg392 arg393 arg394 arg395 arg396 arg397 arg398 arg399 arg400 arg401 arg402 arg403 arg404 arg405 arg406 arg407 arg408 arg409 arg410 arg411 arg412 arg413 arg414 arg415 arg416 arg417 arg418 arg419 arg420 arg421 arg422 arg423 arg424 arg425 arg426 arg427 arg428 arg429 arg430 arg431 arg432 arg433 arg434 arg435 arg436 arg437 arg438 arg439 arg440 arg441 arg442 arg443 arg444 arg445 arg446 arg447 arg448 arg449 arg450 arg451 arg452 arg453 arg454 arg455 arg456 arg457 arg458 arg459 arg460 arg461 arg462 arg463 arg464 arg465 arg466 arg467 arg468 arg469 arg470 arg471 arg472 arg473 arg474 arg475 arg476 arg477 arg478 arg479 arg480 arg481 arg482 arg483 arg484 arg485 arg486 arg487 arg488 arg489 arg490 arg491 arg492 arg493 arg494 arg495 arg496 arg497 arg498 arg499 arg500 arg501 arg502 arg503 arg504 arg505 arg506 arg507 arg508 arg509 arg510 arg511 arg512) (+ arg0 arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10 arg11 arg12 arg13 arg14 arg15 arg16 arg17 arg18 arg19 arg20 arg21 arg22 arg23 arg24 arg25 arg26 arg27 arg28 arg29 arg30 arg31 arg32 arg33 arg34 arg35 arg36 arg37 arg38 arg39 arg40 arg41 arg42 arg43 arg44 arg45 arg46 arg47 arg48 arg49 arg50 arg51 arg52 arg53 arg54 arg55 arg56 arg57 arg58 arg59 arg60 arg61 arg62 arg63 arg64 arg65 arg66 arg67 arg68 arg69 arg70 arg71 arg72 arg73 arg74 arg75 arg76 arg77 arg78 arg79 arg80 arg81 arg82 arg83 arg84 arg85 arg86 arg87 arg88 arg89 arg90 arg91 arg92 arg93 arg94 arg95 arg96 arg97 arg98 arg99 arg100 arg101 arg102 arg103 arg104 arg105 arg106 arg107 arg108 arg109 arg110 arg111 arg112 arg113 arg114 arg115 arg116 arg117 arg118 arg119 arg120 arg121 arg122 arg123 arg124 arg125 arg126 arg127 arg128 arg129 arg130 arg131 arg132 arg133 arg134 arg135 arg136 arg137 arg138 arg139 arg140 arg141 arg142 arg143 arg144 arg145 arg146 arg147 arg148 arg149 arg150 arg151 arg152 arg153 arg154 arg155 arg156 arg157 arg158 arg159 arg160 arg161 arg162 arg163 arg164 arg165 arg166 arg167 arg168 arg169 arg170 arg171 arg172 arg173 arg174 arg175 arg176 arg177 arg178 arg179 arg180 arg181 arg182 arg183 arg184 arg185 arg186 arg187 arg188 arg189 arg190 arg191 arg192 arg193 arg194 arg195 arg196 arg197 arg198 arg199 arg200 arg201 arg202 arg203 arg204 arg205 arg206 arg207 arg208 arg209 arg210 arg211 arg212 arg213 arg214 arg215 arg216 arg217 arg218 arg219 arg220 arg221 arg222 arg223 arg224 arg225 arg226 arg227 arg228 arg229 arg230 arg231 arg232 arg233 arg234 arg235 arg236 arg237 arg238 arg239 arg240 arg241 arg242 arg243 arg244 arg245 arg246 arg247 arg248 arg249 arg250 arg251 arg252 arg253 arg254 arg255 arg256 arg257 arg258 arg259 arg260 arg261 arg262 arg263 arg264 arg265 arg266 arg267 arg268 arg269 arg270 arg271 arg272 arg273 arg274 arg275 arg276 arg277 arg278 arg279 arg280 arg281 arg282 arg283 arg284 arg285 arg286 arg287 arg288 arg289 arg290 arg291 arg292 arg293 arg294 arg295 arg296 arg297 arg298 arg299 arg300 arg301 arg302 arg303 arg304 arg305 arg306 arg307 arg308 arg309 arg310 arg311 arg312 arg313 arg314 arg315 arg316 arg317 arg318 arg319 arg320 arg321 arg322 arg323 arg324 arg325 arg326 arg327 arg328 arg329 arg330 arg331 arg332 arg333 arg334 arg335 arg336 arg337 arg338 arg339 arg340 arg341 arg342 arg343 arg344 arg345 arg346 arg347 arg348 arg349 arg350 arg351 arg352 arg353 arg354 arg355 arg356 arg357 arg358 arg359 arg360 arg361 arg362 arg363 arg364 arg365 arg366 arg367 arg368 arg369 arg370 arg371 arg372 arg373 arg374 arg375 arg376 arg377 arg378 arg379 arg380 arg381 arg382 arg383 arg384 arg385 arg386 arg387 arg388 arg389 arg390 arg391 arg392 arg393 arg394 arg395 arg396 arg397 arg398 arg399 arg400 arg401 arg402 arg403 arg404 arg405 arg406 arg407 arg408 arg409 arg410 arg411 arg412 arg413 arg414 arg415 arg416 arg417 arg418 arg419 arg420 arg421 arg422 arg423 arg424 arg425 arg426 arg427 arg428 arg429 arg430 arg431 arg432 arg433 arg434 arg435 arg436 arg437 arg438 arg439 arg440 arg441 arg442 arg443 arg444 arg445 arg446 arg447 arg448 arg449 arg450 arg451 arg452 arg453 arg454 arg455 arg456 arg457 arg458 arg459 arg460 arg461 arg462 arg463 arg464 arg465 arg466 arg467 arg468 arg469 arg470 arg471 arg472 arg473 arg474 arg475 arg476 arg477 arg478 arg479 arg480 arg481 arg482 arg483 arg484 arg485 arg486 arg487 arg488 arg489 arg490 arg491 arg492 arg493 arg494 arg495 arg496 arg497 arg498 arg499 arg500 arg501 arg502 arg503 arg504 arg505 arg506 arg507 arg508 arg509 arg510 arg511 arg512)))) (f512 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512)) 131328) (let ((x 32)) (define (f1) x) (define x 33) (test (f1) 33)) (let () (define (c-2) (let ((v (vector 1 2 3))) (define (c-1 a b) (+ (vector-ref a 0) (* b 32))) (let ((c (c-1 v 1))) (test c 33) (set! c-1 vector-ref)) (let ((d (c-1 v 1))) (test d 2)))) (c-2)) (let () (define (c-2) (let ((v (vector 1 2 3))) (let () (define (c-1 a b) (+ (vector-ref a 0) (* b 32))) (let ((c (c-1 v 1))) (set! c-1 vector-ref))) (test (c-1 v 1) 'error))) (c-2)) (let () (define (f4 a b c d e) (list a b c d e)) (test (f4 1 2 3 4 5) '(1 2 3 4 5))) (define (redef-1 a) (+ a 1)) (define (use-redef-1 b) (+ (redef-1 b) 2)) ; [use-redef](+ [redef-1](+ b 1) 2) (test (use-redef-1 3) 6) ; b=6 (define (redef-1 a) (+ a 4)) (test (use-redef-1 3) 9) ; [use-redef-1](+ [redef-1](+ a 4) 2), a=3 (let () (define (use-redef-2 c) (+ (redef-1 c) 5)) ; [use-redef-2](+ [redef-1](+ a 4) 5) (test (use-redef-2 6) 15) ; a=6 (define (redef-1 a) (+ a 7)) ; so use-redef-1 is still [use-redef-1](+ [redef-1](+ a 4) 2) (test (use-redef-1 8) 14) ; a=8 -> 14 (test (use-redef-2 8) 20)) ; but use-redef-2 (same let as shadowing use-redef-1) is (+ [new redef-1](+ a 7) 5), a=8 -> 20 (test (let () (define (f1 x) (abs x)) (define (f2 x) (f1 x)) (f2 -1)) 1) ; just trying to hit a portion of the s7 code (when with-block (let () (define (f1) ((lambda (x) (cf11 x)) 3)) (f1) (define (f2) ((lambda () (cf21 3 4)))) (f2) (define (f3) ((lambda () (cf11 3)))) (f3) (define (f4) ((lambda (x) (cf11 'x)) 4)) (f4) (define (f5) ((lambda (x) (cf21 x 4)) 3)) (f5) (define (f6) ((lambda (x) (cf21 3 x)) 4)) (f6) (define (f7) ((lambda (x) (cf21 3 4)) 4)) (f7) (define (f8) ((lambda (x y) (cf21 x y)) 3 4)) (f8) (define (f9) ((lambda (x) (cf21 x 'y)) 'x)) (f9) (define (f10) ((lambda (x) (cf21 'y x)) 'x)) (f10) (define (f11) ((lambda (x) (cf21 'y 'x)) 'x)) (f11) (define (f12) ((lambda (x) (cf21 1 'x)) 'x)) (f12) (define (f13) ((lambda (x) (cf21 'x 1)) 'x)) (f13) (define (f14) ((lambda (x y z) (cf31 x y z)) 1 2 3)) (f14) (define (f15) ((lambda (x y z) (cf31 x 2 z)) 1 2 3)) (f15) (define (f16) ((lambda (x y z) (cf31 x y 2)) 1 2 3)) (f16) (define (f17) ((lambda (x y z) (cf31 2 y z)) 1 2 3)) (f17) (define (f18) ((lambda (w x y z) (cf41 w x y z)) 1 2 3 4)) (f18) (define (f19) ((lambda (x y z) (cf31 x 'y z)) 1 2 3)) (f19) (define (f20) ((lambda (x y z) (cf41 'q x y z)) 1 2 3)) (f20) (define (f21) ((lambda (x y) (cf31 x y (+ x 6))) 1 2)) (f21) (define (f22) ((lambda (x y) (cf31 1 y (+ x 6))) 1 2)) (f22) (define (f23) ((lambda (x y) (cf31 x 1 (+ x 6))) 1 2)) (f23) (define (f24) ((lambda (x y) (cf31 1 (+ x 6) y)) 1 2)) (f24) (define (f25) ((lambda (x) (cf11 (cf11 'x))) 1)) (f25) (define (f26) ((lambda (w x y z) (cf51 'q w x y z)) 1 2 3 4)) (f26) (define (f27) ((lambda (w x y) (cf21 (cf21 (cf11 w) (cf11 x)) (cf11 y))) 1 2 3)) (f27) (define (f28) ((lambda (w x y) (cf31 (cf21 w x) 2 y)) 1 2 3)) (f28) (define (f29) ((lambda () (cf11 (cf11 0))))) (f29) (define (f30) ((lambda (x) (cf11 (cf11 x))) 0)) (f30) (define (f31) ((lambda (x) (cf11 (cf10 x))) 0)) (f31) (define (f32) ((lambda (x) (cf11 (cf10 'x))) 1)) (f32) (define (f33) ((lambda (w x y) (cf31 (cf20 w x) 2 y)) 1 2 3)) (f33) (define (f34) ((lambda (w x y) (cf22 (cf21 (cf11 w) (cf11 x)) (cf10 y))) 1 2 3)) (f34) (define (f35) ((lambda (w x y) (cf21 (cf20 (cf11 w) (cf11 x)) (cf11 y))) 1 2 3)) (f35) (define (f36) ((lambda (w x y) (cf21 (cf21 (cf10 w) (cf11 x)) (cf11 y))) 1 2 3)) (f36) (define (f37) ((lambda (x y) (cf33 x y (cf20 x 6))) 1 2)) (f37) (define (f38) ((lambda (x y) (cf33 1 y (cf20 x 6))) 1 2)) (f38) (define (f39) ((lambda (x y) (cf33 x 1 (cf20 x 6))) 1 2)) (f39) (define (f40) ((lambda (x y) (cf32 1 (cf20 x 6) y)) 1 2)) (f40) (define (f41) ((lambda (x y) (cf11 (cf21 x y))) 1 2)) (f41) (define (f42) ((lambda (x y) (cf11 (cf21 x 2))) 1 2)) (f42) (define (f43) ((lambda (x y) (cf11 (cf21 1 x))) 1 2)) (f43) (define (f44) ((lambda (x y) (cf21 x (cf11 y))) 1 2)) (f44) (define (f45) ((lambda (x y) (cf21 (cf11 x) y)) 1 2)) (f45) (define (f46) ((lambda (x y) (cf21 (cf11 x) 2)) 1 2)) (f46) (define (f47) ((lambda (x y) (cf21 (cf11 x) (cf11 y))) 1 2)) (f47) (define (f48) ((lambda (x y) (cf11 (cf20 x y))) 1 2)) (f48) (define (f49) ((lambda (x y) (cf11 (cf20 x 2))) 1 2)) (f49) (define (f50) ((lambda (x y) (cf11 (cf20 1 x))) 1 2)) (f50) (define (f51) ((lambda (x y) (cf22 x (cf10 y))) 1 2)) (f51) (define (f52) ((lambda (x y) (cf21 (cf10 x) y)) 1 2)) (f52) (define (f53) ((lambda (x y) (cf21 (cf10 x) 2)) 1 2)) (f53) (define (f54) ((lambda (x y) (cf21 (cf10 x) (cf11 y))) 1 2)) (f54) (define (f55) ((lambda (x y) (cf22 (cf11 x) (cf10 y))) 1 2)) (f55) (define (f56) ((lambda (x y) (cf21 1 (cf11 y))) 1 2)) (f56) (define (f57) ((lambda (x y) (cf22 1 (cf10 y))) 1 2)) (f57) (define (f58) ((lambda (x y z) (cf21 x (cf21 y z))) 1 2 3)) (f58) (define (f59) ((lambda (x y z) (cf22 x (cf20 y z))) 1 2 3)) (f59) (define (f60) ((lambda (x y z) (cf21 x (cf21 2 z))) 1 2 3)) (f60) (define (f61) ((lambda (x y z) (cf22 x (cf20 2 z))) 1 2 3)) (f61) (define (f62) ((lambda (x y z) (cf21 x (cf21 y 3))) 1 2 3)) (f62) (define (f63) ((lambda (x y z) (cf22 x (cf20 y 3))) 1 2 3)) (f63) (define (f64) ((lambda (x y z) (cf21 1 (cf21 2 z))) 1 2 3)) (f64) (define (f65) ((lambda (x y z) (cf22 1 (cf20 2 z))) 1 2 3)) (f65) (define (f66) ((lambda (x y z) (cf21 1 (cf21 y 3))) 1 2 3)) (f66) (define (f67) ((lambda (x y z) (cf22 1 (cf20 y 3))) 1 2 3)) (f67) (define (f68) ((lambda (x) (cf21 (cf21 2 x) 3)) 1)) (f68) (define (f69) ((lambda (x) (cf21 (cf20 2 x) 3)) 1)) (f69) (define (f70) ((lambda (x y) (cf21 1 (cf21 x y))) 2 3)) (f70) (define (f71) ((lambda (x y) (cf22 1 (cf20 x y))) 2 3)) (f71) (define (f72) ((lambda (x y) (cf21 (cf21 x y) 3)) 1 2)) (f72) (define (f73) ((lambda (x y) (cf21 (cf20 x y) 3)) 1 2)) (f73) (define (f74) ((lambda (x) (cf11 (cf21 x 'y))) 1)) (f74) (define (f75) ((lambda (x) (cf11 (cf20 x 'y))) 1)) (f75) (define (f76) ((lambda (x) (cf21 x (cf11 2))) 1)) (f76) (define (f77) ((lambda (x) (cf22 x (cf10 2))) 1)) (f77) (define (f78) ((lambda (x) (cf21 1 (cf11 2))) 1)) (f78) (define (f79) ((lambda (x) (cf22 1 (cf10 2))) 1)) (f79) (define (f80) ((lambda (x) (cf21 (cf11 1) x)) 2)) (f80) (define (f81) ((lambda (x) (cf21 (cf10 1) x)) 2)) (f81) (define (f82) ((lambda (x y z) (cf21 (cf21 x y) z)) 1 2 3)) (f82) (define (f83) ((lambda (x y z) (cf21 (cf20 x y) z)) 1 2 3)) (f83) (define (f84) ((lambda (x y z) (cf21 (cf21 x 2) z)) 1 2 3)) (f84) (define (f85) ((lambda (x y z) (cf21 (cf20 x 2) z)) 1 2 3)) (f85) (define (f86) ((lambda (x y z) (cf21 (cf21 1 y) z)) 1 2 3)) (f86) (define (f87) ((lambda (x y z) (cf21 (cf20 1 y) z)) 1 2 3)) (f87) (define (f88) ((lambda (x y z) (cf21 (cf21 x 2) 3)) 1 2 3)) (f88) (define (f89) ((lambda (x y z) (cf21 (cf20 x 2) 3)) 1 2 3)) (f89) (define (f90) ((lambda (x) (cf21 (cf11 1) 2)) 2)) (f90) (define (f91) ((lambda (x) (cf21 (cf10 1) 2)) 2)) (f91) (define (f92) ((lambda (w x y z) (cf21 (cf21 w x) (cf21 y z))) 1 2 3 4)) (f92) (define (f93) ((lambda (w x y z) (cf22 (cf21 w x) (cf20 y z))) 1 2 3 4)) (f93) (define (f94) ((lambda (w x y z) (cf21 (cf20 w x) (cf21 y z))) 1 2 3 4)) (f94) (define (f95) ((lambda (w x y z) (cf21 (cf21 w 2) (cf21 y 4))) 1 2 3 4)) (f95) (define (f96) ((lambda (w x y z) (cf22 (cf21 w 2) (cf20 y 4))) 1 2 3 4)) (f96) (define (f97) ((lambda (w x y z) (cf21 (cf20 w 2) (cf21 y 4))) 1 2 3 4)) (f97) (define (f98) ((lambda (x y z) (cf21 (cf11 x) (cf21 y z))) 1 2 3)) (f98) (define (f99) ((lambda (x y z) (cf22 (cf11 x) (cf20 y z))) 1 2 3)) (f99) (define (f100) ((lambda (x y z) (cf21 (cf10 x) (cf21 y z))) 1 2 3)) (f100) (define (f101) ((lambda (x y z) (cf21 (cf21 x y) (cf11 z))) 1 2 3)) (f101) (define (f102) ((lambda (x y z) (cf22 (cf21 x y) (cf10 z))) 1 2 3)) (f102) (define (f103) ((lambda (x y z) (cf21 (cf20 x y) (cf11 z))) 1 2 3)) (f103) (define (f104) ((lambda (x y z) (cf21 (cf21 x y) (cf11 3))) 1 2 3)) (f104) (define (f105) ((lambda (x y z) (cf22 (cf21 x y) (cf10 3))) 1 2 3)) (f105) (define (f106) ((lambda (x y z) (cf21 (cf20 x y) (cf11 3))) 1 2 3)) (f106) (define (f107) ((lambda (x y z) (cf21 (cf11 1) (cf21 y z))) 1 2 3)) (f107) (define (f108) ((lambda (x y z) (cf22 (cf11 1) (cf20 y z))) 1 2 3)) (f108) (define (f109) ((lambda (x y z) (cf21 (cf10 1) (cf21 y z))) 1 2 3)) (f109) (define (f110) ((lambda () (cf21 (cf11 1) (cf11 2))))) (f110) (define (f111) ((lambda () (cf22 (cf11 1) (cf10 2))))) (f111) (define (f112) ((lambda () (cf21 (cf10 1) (cf11 2))))) (f112) (define (f113) ((lambda (x) (cf11 (cf11 (cf11 x)))) 1)) (f113) (define (f114) ((lambda (x) (cf11 (cf11 (cf10 x)))) 1)) (f114) (define (f115) ((lambda (x) (cf11 (cf10 (cf11 x)))) 1)) (f115) (define (f116) ((lambda (w x y z) (cf22 w (cf21 (cf21 x y) z))) 1 2 3 4)) (f116) (define (f117) ((lambda (w x y z) (cf22 w (cf20 (cf21 x y) z))) 1 2 3 4)) (f117) (define (f118) ((lambda (w x y z) (cf22 w (cf21 (cf20 x y) z))) 1 2 3 4)) (f118) (define (f119) ((lambda (w x y z) (cf22 w (cf22 x (cf21 y z)))) 1 2 3 4)) (f119) (define (f120) ((lambda (w x y z) (cf22 w (cf20 x (cf21 y z)))) 1 2 3 4)) (f120) (define (f121) ((lambda (w x y z) (cf22 w (cf22 x (cf20 y z)))) 1 2 3 4)) (f121) (define (f122) ((lambda (x y) (cf11 (cf32 1 (cf21 x y) 4))) 2 3)) (f122) ; c_z (define (f123) ((lambda (x y) (cf11 (cf32 1 (cf20 x y) 4))) 2 3)) (f123) (define (f124) ((lambda (x y) (cf11 (cf30 1 (cf21 x y) 4))) 2 3)) (f124) (define (f125) ((lambda (x y) (cf21 (cf11 (cf21 x y)) 3)) 1 2)) (f125) (define (f126) ((lambda (x y) (cf21 (cf10 (cf21 x y)) 3)) 1 2)) (f126) (define (f127) ((lambda (x y) (cf21 (cf11 (cf20 x y)) 3)) 1 2)) (f127) (define (f128) ((lambda (x) (cf22 1 (cf21 x (cf11 3)))) 2)) (f128) (define (f129) ((lambda (x) (cf22 1 (cf20 x (cf11 3)))) 2)) (f129) (define (f130) ((lambda (x) (cf22 1 (cf22 x (cf10 3)))) 2)) (f130) (define (f131) ((lambda (x y z) (cf22 x (cf21 (cf21 y z) (cf21 z y)))) 1 2 3)) (f131) (define (f132) ((lambda (x y z) (cf22 x (cf20 (cf21 y z) (cf21 z y)))) 1 2 3)) (f132) (define (f133) ((lambda (x y z) (cf22 x (cf21 (cf20 y z) (cf21 z y)))) 1 2 3)) (f133) (define (f134) ((lambda (x y z) (cf22 x (cf22 (cf21 y z) (cf20 z y)))) 1 2 3)) (f134) (define (f135) ((lambda (x y z) (cf21 (cf21 x y) (cf11 (cf21 y z)))) 1 2 3)) (f135) (define (f136) ((lambda (x y z) (cf21 (cf20 x y) (cf11 (cf21 y z)))) 1 2 3)) (f136) (define (f137) ((lambda (x y z) (cf22 (cf21 x y) (cf10 (cf21 y z)))) 1 2 3)) (f137) (define (f138) ((lambda (x y z) (cf22 (cf21 x y) (cf11 (cf20 y z)))) 1 2 3)) (f138) (define (f139) ((lambda (x y z) (cf21 (cf21 (cf21 x y) z) (cf21 y z))) 1 2 3)) (f139) (define (f140) ((lambda (x y z) (cf21 (cf20 (cf21 x y) z) (cf21 y z))) 1 2 3)) (f140) (define (f141) ((lambda (x y z) (cf21 (cf21 (cf20 x y) z) (cf21 y z))) 1 2 3)) (f141) (define (f142) ((lambda (x y z) (cf22 (cf21 (cf21 x y) z) (cf20 y z))) 1 2 3)) (f142) (define (f143) ((lambda (x y z) (cf22 x (cf21 (cf11 (cf21 x y)) (cf11 (cf21 y z))))) 1 2 3)) (f143) (define (f144) ((lambda (x y z) (cf22 x (cf20 (cf11 (cf21 x y)) (cf11 (cf21 y z))))) 1 2 3)) (f144) (define (f145) ((lambda (x y z) (cf22 x (cf21 (cf10 (cf21 x y)) (cf11 (cf21 y z))))) 1 2 3)) (f145) (define (f146) ((lambda (x y z) (cf22 x (cf21 (cf11 (cf20 x y)) (cf11 (cf21 y z))))) 1 2 3)) (f146) (define (f147) ((lambda (x y z) (cf22 x (cf22 (cf11 (cf21 x y)) (cf10 (cf21 y z))))) 1 2 3)) (f147) (define (f148) ((lambda (x y z) (cf22 x (cf22 (cf11 (cf21 x y)) (cf11 (cf20 y z))))) 1 2 3)) (f148) (define (f149) ((lambda (x y z) (cf22 x (cf31 (cf11 y) (cf11 z) (cf11 z)))) 1 2 3)) (f149) (define (f150) ((lambda (x y z) (cf22 x (cf30 (cf11 y) (cf11 z) (cf11 z)))) 1 2 3)) (f150) (define (f151) ((lambda (x y z) (cf22 x (cf31 (cf10 y) (cf11 z) (cf11 z)))) 1 2 3)) (f151) (define (f152) ((lambda (x y z) (cf22 x (cf32 (cf11 y) (cf10 z) (cf11 z)))) 1 2 3)) (f152) (define (f153) ((lambda (x y z) (cf22 x (cf33 (cf11 y) (cf11 z) (cf10 z)))) 1 2 3)) (f153) (define (f154) ((lambda (x y z) (cf21 (cf32 1 (cf21 x y) 4) (cf32 1 (cf21 y z) 4))) 1 2 3)) (f154) (define (f155) ((lambda (x y z) (cf21 (cf32 1 (cf20 x y) 4) (cf32 1 (cf21 y z) 4))) 1 2 3)) (f155) (define (f156) ((lambda (x y z) (cf22 (cf32 1 (cf21 x y) 4) (cf30 1 (cf21 y z) 4))) 1 2 3)) (f156) (define (f157) ((lambda (x y z) (cf22 x (cf32 1 (cf21 y z) 4))) 1 2 3)) (f157) (define (f158) ((lambda (x y z) (cf22 x (cf32 1 (cf20 y z) 4))) 1 2 3)) (f158) (define (f159) ((lambda (x y z) (cf21 (cf32 1 (cf21 y z) 4) x)) 1 2 3)) (f159) (define (f160) ((lambda (x y z) (cf21 (cf30 1 (cf20 y z) 4) x)) 1 2 3)) (f160) (define (f161) ((lambda (x y z) (cf22 1 (cf32 1 (cf21 y z) 4))) 1 2 3)) (f161) (define (f162) ((lambda (x y z) (cf22 1 (cf32 1 (cf20 y z) 4))) 1 2 3)) (f162) (define (f163) ((lambda (x y z) (cf21 (cf32 1 (cf21 y z) 4) x)) 1 2 3)) (f163) (define (f164) ((lambda (x y z) (cf21 (cf30 1 (cf20 y z) 4) x)) 1 2 3)) (f164) ;; -------- (test (f1) 3) (test (f2) 3) (test (f3) 3) (test (f4) 'x) (test (f5) 3) (test (f6) 3) (test (f7) 3) (test (f8) 3) (test (f9) 'x) (test (f10) 'y) (test (f11) 'y) (test (f12) 1) (test (f13) 'x) (test (f14) 1) (test (f15) 1) (test (f16) 1) (test (f17) 2) (test (f18) 1) (test (f19) 1) (test (f20) 'q) (test (f21) 1) (test (f22) 1) (test (f23) 1) (test (f24) 1) (test (f25) 'x) (test (f26) 'q) (test (f27) 1) (test (f28) 1) (test (f29) 0) (test (f30) 0) (test (f31) 0) (test (f32) 'x) (test (f33) 1) (test (f34) 3) (test (f35) 1) (test (f36) 1) (test (f37) 1) (test (f38) 1) (test (f39) 1) (test (f40) 1) (test (f41) 1) (test (f42) 1) (test (f43) 1) (test (f44) 1) (test (f45) 1) (test (f46) 1) (test (f47) 1) (test (f48) 1) (test (f49) 1) (test (f50) 1) (test (f51) 2) (test (f52) 1) (test (f53) 1) (test (f54) 1) (test (f55) 2) (test (f56) 1) (test (f57) 2) (test (f58) 1) (test (f59) 2) (test (f60) 1) (test (f61) 2) (test (f62) 1) (test (f63) 2) (test (f64) 1) (test (f65) 2) (test (f66) 1) (test (f67) 2) (test (f68) 2) (test (f69) 2) (test (f70) 1) (test (f71) 2) (test (f72) 1) (test (f73) 1) (test (f74) 1) (test (f75) 1) (test (f76) 1) (test (f77) 2) (test (f78) 1) (test (f79) 2) (test (f80) 1) (test (f81) 1) (test (f82) 1) (test (f83) 1) (test (f84) 1) (test (f85) 1) (test (f86) 1) (test (f87) 1) (test (f88) 1) (test (f89) 1) (test (f90) 1) (test (f91) 1) (test (f92) 1) (test (f93) 3) (test (f94) 1) (test (f95) 1) (test (f96) 3) (test (f97) 1) (test (f98) 1) (test (f99) 2) (test (f100) 1) (test (f101) 1) (test (f102) 3) (test (f103) 1) (test (f104) 1) (test (f105) 3) (test (f106) 1) (test (f107) 1) (test (f108) 2) (test (f109) 1) (test (f110) 1) (test (f111) 2) (test (f112) 1) (test (f113) 1) (test (f114) 1) (test (f115) 1) (test (f116) 2) (test (f117) 2) (test (f118) 2) (test (f119) 3) (test (f120) 2) (test (f121) 3) (test (f122) 2) (test (f123) 2) (test (f124) 1) (test (f125) 1) (test (f126) 1) (test (f127) 1) (test (f128) 2) (test (f129) 2) (test (f130) 3) (test (f131) 2) (test (f132) 2) (test (f133) 2) (test (f134) 3) (test (f135) 1) (test (f136) 1) (test (f137) 2) (test (f138) 2) (test (f139) 1) (test (f140) 1) (test (f141) 1) (test (f142) 2) (test (f143) 1) (test (f144) 1) (test (f145) 1) (test (f146) 1) (test (f147) 2) (test (f148) 2) (test (f149) 2) (test (f150) 2) (test (f151) 2) (test (f152) 3) (test (f153) 3) (test (f154) 1) (test (f155) 1) (test (f156) 1) (test (f157) 2) (test (f158) 2) (test (f159) 2) (test (f160) 1) (test (f161) 2) (test (f162) 2) (test (f163) 2) (test (f164) 1) )) (when with-block (let () (define (thunk1) 3) (define (thunk2) 4) (define (f1) ((lambda (x) (thunk1)) 0)) (f1) (test (f1) 3) (define thunk1 thunk2) (test (f1) 4) (define (thunk3) (*s7* 'max-stack-size) 5) (define (thunk4) (*s7* 'max-stack-size) 6) (define (f2) ((lambda (x) (thunk3)) 0)) (f2) (test (f2) 5) (define thunk3 thunk4) (test (f2) 6) (define (close1 x) (*s7* 'max-stack-size) (+ x 1)) (define (close2 x) (*s7* 'max-stack-size) (+ x 2)) (define (qclose1 x) (*s7* 'max-stack-size) (eq? x 'q)) (define (qclose2 x) (*s7* 'max-stack-size) (eq? x 'r)) (define (sclose1 x) (+ x 1)) (define (sclose2 x) (+ x 2)) (define (qsclose1 x) (eq? x 'q)) (define (qsclose2 x) (eq? x 'r)) (define* (s*close1 (x 1)) (+ x 1)) (define* (s*close2 (x 1)) (+ x 2)) (define* (u*close1 (x 1)) (*s7* 'max-stack-size) (+ x 1)) (define* (u*close2 (x 1)) (*s7* 'max-stack-size) (+ x 2)) (define (close3 x y) (*s7* 'max-stack-size) (+ x y)) (define (close4 x y) (*s7* 'max-stack-size) (+ x y 1)) (define (sclose3 x y) (+ x y)) (define (sclose4 x y) (+ x y 1)) (define* (s*close3 (x 1) (y 0.0)) (+ x y)) (define* (s*close4 (x 1) (y 0.0)) (+ x y 1)) (define* (u*close3 (x 1) (y 0)) (*s7* 'max-stack-size) (+ x y)) (define* (u*close4 (x 1) (y 0)) (*s7* 'max-stack-size) (+ x y 1)) (define (f3) (close1 1)) (f3) (define (f4) (sclose1 1)) (f4) (define (f5 x) (close1 x)) (f5 0) (define (f6 x) (sclose1 x)) (f6 0) (define (f7 x) (close1 ((lambda () (cs11 x))))) (f7 0) (define (f8 x) (sclose1 ((lambda () (cs11 x))))) (f8 0) (define (f9 x) (close1 ((lambda () (cs11 1))))) (f9 0) (define (f10 x) (sclose1 ((lambda () (cs11 1))))) (f10 0) (define (f11 x) (s*close1 x)) (f11 0) (define (f12 x) (s*close1)) (f12 0) (define (f13 x) (u*close1 x)) (f13 0) (define (f14 x) (u*close1)) (f14 0) (define (f15) (qclose1 'q)) (f15) (define (f16) (qsclose1 'q)) (f16) (define (f17 x) (close1 (cdr x))) (f17 '(0 . 0)) (define (f18) (close3 1 2)) (f18) (define (f19) (sclose3 1 2)) (f19) (define (f20) (s*close3 1 2)) (f20) (define (f21) (u*close3 1 2)) (f21) (define (f22 x) (close3 x 2)) (f22 0) (define (f23 x) (sclose3 x 2)) (f23 0) (define (f24 x) (s*close3 x 2)) (f24 0) (define (f25 x) (u*close3 x 2)) (f25 0) (define (f26 x) (close3 1 x)) (f26 0) (define (f27 x) (sclose3 1 x)) (f27 0) (define (f28 x) (s*close3 1 x)) (f28 0) (define (f29 x) (u*close3 1 x)) (f29 0) (define (f30 x y) (close3 x y)) (f30 0 0) (define (f31 x y) (sclose3 x y)) (f31 0 0) (define (f32 x y) (s*close3 x y)) (f32 0 0) (define (f33 x y) (u*close3 x y)) (f33 0 0) (test (f3) 2) (test (f4) 2) (test (f5 1) 2) (test (f6 1) 2) (test (f7 1) 2) (test (f8 1) 2) (test (f9 1) 2) (test (f10 1) 2) (test (f11 1) 2) (test (f12 1) 2) (test (f13 1) 2) (test (f14 1) 2) (test (f15) #t) (test (f16) #t) (test (f17 '(1 . 1)) 2) (test (f18) 3) (test (f19) 3) (test (f20) 3) (test (f21) 3) (test (f22 1) 3) (test (f23 1) 3) (test (f24 1) 3) (test (f25 1) 3) (test (f26 2) 3) (test (f27 2) 3) (test (f28 2) 3) (test (f29 2) 3) (test (f30 1 2) 3) (test (f31 1 2) 3) (test (f32 1 2) 3) (test (f33 1 2) 3) (define cs11 rs11) ;;;(test (f7 1) 3) (test (f8 1) 3) (test (f9 1) 3) (test (f10 1) 3) (define close1 close2) (define close3 close4) (define qclose1 qclose2) (define sclose1 sclose2) (define sclose3 sclose4) (define qsclose1 qsclose2) (define s*close1 s*close2) (define s*close3 s*close4) (define u*close1 u*close2) (define u*close3 u*close4) (define (f31 x y) (sclose3 x y)) (test (f3) 3) (test (f4) 3) (test (f5 1) 3) (test (f6 1) 3) ;;; (test (f7 -1) 2) (test (f8 -1) 2) (test (f9 -1) 4) (test (f10 -1) 4) (test (f11 1) 3) (test (f12 1) 3) (test (f13 1) 3) (test (f14 1) 3) (test (f15) #f) (test (f16) #f) (test (f17 '(1 . 1)) 3) (test (f18) 4) (test (f19) 4) (test (f20) 4) (test (f21) 4) (test (f22 1) 4) (test (f23 1) 4) (test (f24 1) 4) (test (f25 1) 4) (test (f26 2) 4) (test (f27 2) 4) (test (f28 2) 4) (test (f29 2) 4) (test (f30 1 2) 4) (test (f31 1 2) 4) (test (f32 1 2) 4) (test (f33 1 2) 4) )) ;;; global name opts (or lack thereof) ;;; the funny names used here must be nonce words ;;; op_unknown (thunk): (define *x1* #f) (define (test*x1*) (*x1*)) (define (set*x1* n) (set! *x1* (lambda () n))) (set*x1* 1) (test (test*x1*) 1) (set*x1* 2) (test (test*x1*) 2) (define *x2* #f) (define (test*x2*) (*x2*)) (define (set*x2* n) (set! *x2* (define* (_) n))) (set*x2* 1) (test (test*x2*) 1) (set*x2* 2) (test (test*x2*) 2) ;;; op_unknown_q: (define *x3* #f) (define (test*x3*) (*x3* 'a)) (define (set*x3* n) (set! *x3* (lambda (x) n))) (set*x3* 1) (test (test*x3*) 1) (set*x3* 2) (test (test*x3*) 2) ;;; op_unknown_s: (define *x4* #f) (define (test*x4* a) (*x4* a)) (define (set*x4* n) (set! *x4* (lambda (x) n))) (set*x4* 1) (test (test*x4* 0) 1) (set*x4* 2) (test (test*x4* 0) 2) (define *x5* #f) (define (test*x5* a) (*x5* a)) (define (set*x5* n) (set! *x5* (define* (_ __) n))) (set*x5* 1) (test (test*x5* 0) 1) (set*x5* 2) (test (test*x5* 0) 2) ;;; op_unknown_c: (define *x6* #f) (define (test*x6*) (*x6* 0)) (define (set*x6* n) (set! *x6* (lambda (x) n))) (set*x6* 1) (test (test*x6*) 1) (set*x6* 2) (test (test*x6*) 2) ;;; op_unknown_ss: (define *x7* #f) (define (test*x7* a b) (*x7* a b)) (define (set*x7* n) (set! *x7* (lambda (x y) n))) (set*x7* 1) (test (test*x7* 0 0) 1) (set*x7* 2) (test (test*x7* 0 0) 2) (define *x8* #f) (define (test*x8* a b) (*x8* a b)) (define (set*x8* n) (set! *x8* (define* (_ x y) n))) (set*x8* 1) (test (test*x8* 0 0) 1) (set*x8* 2) (test (test*x8* 0 0) 2) ;;; op_unknown_sc: (define *x9* #f) (define (test*x9* a b) (*x9* a 0)) (define (set*x9* n) (set! *x9* (lambda (x y) n))) (set*x9* 1) (test (test*x9* 0 0) 1) (set*x9* 2) (test (test*x9* 0 0) 2) (define *x10* #f) (define (test*x10* a b) (*x10* a 0)) (define (set*x10* n) (set! *x10* (define* (_ x y) n))) (set*x10* 1) (test (test*x10* 0 0) 1) (set*x10* 2) (test (test*x10* 0 0) 2) ;;; op_unknown_cs: (define *x11* #f) (define (test*x11* a b) (*x11* 0 b)) (define (set*x11* n) (set! *x11* (lambda (x y) n))) (set*x11* 1) (test (test*x11* 0 0) 1) (set*x11* 2) (test (test*x11* 0 0) 2) (define *x12* #f) (define (test*x12* a b) (*x12* 0 b)) (define (set*x12* n) (set! *x12* (define* (_ x y) n))) (set*x12* 1) (test (test*x12* 0 0) 1) (set*x12* 2) (test (test*x12* 0 0) 2) ;;; globals (test (let () (define (call-func func arg1 arg2) (define (call) (func arg1 arg2)) (call)) (call-func + 1 2.5) (call-func - 5 2)) 3) (test (let () (define (call-func arg1 arg2) (let ((func (if (= arg1 1) + -))) (define (call) (func arg1 arg2)) (call))) (call-func 1 2.5) (call-func 5 2)) 3) ;;; safe/unsafe troubles (let () (define (testit) (define (f1 x y z) (car z)) (define (f2 lst) (cond ((null? lst) ()) (else (f1 lst (f2 (cdr lst)) lst)))) (test (f2 '(abs -1)) 'abs)) (testit)) (let () (define (testit) (define (f1 x y z) (car z)) (define (f2 lst) (cond ((null? lst) ()) (else (f1 (f2 (cdr lst)) (f2 (cdr lst)) lst)))) (test (f2 '(abs -1)) 'abs)) (testit)) ;;; changing a function's environment (let () (let ((e (let ((a 1) (b 2)) (curlet)))) (define (f1 c) (+ a b c)) (set! (outlet (funclet f1)) e) (test (f1 4) 7)) (let ((e (let ((a 1) (b 2)) (curlet)))) (define f2 (let ((d 10)) (lambda (c) (+ a b c d)))) ;; (set! (outlet (funclet f2)) e) ; 'd unbound (set! (outlet (outlet (funclet f2))) e) (test (f2 4) 17)) (let ((e (let ((a 1) (b 2)) (curlet)))) (define f3 (with-let e (lambda (c) (+ a b c)))) (test (f3 4) 7))) ;;; -------------------------------------------------------------------------------- ;;; values ;;; call-with-values ;;; -------------------------------------------------------------------------------- (test (call-with-values (lambda () (values 1 2 3)) +) 6) (test (call-with-values (lambda () (values 4 5)) (lambda (a b) b)) 5) (test (call-with-values (lambda () (values 4 5)) (lambda (a b) (+ a b))) 9) (test (call-with-values * -) -1) ; yeah, right... (- (*)) (test (values 1) 1) (test (call-with-values (lambda () (values 1 2 3 4)) list) (list 1 2 3 4)) (test (+ (values 1) (values 2)) 3) (test (+ (values '1) (values '2)) 3) (test (if (values #t) 1 2) 1) (test (if (values '#t) 1 2) 1) (test (if (values #f) 1 2) 2) (test (if (values #f #f) 1 2) 1) (test (equal? (values #t #t)) #t) (test (call-with-values (lambda () 4) (lambda (x) x)) 4) (test (let () (values 1 2 3) 4) 4) (test (apply + (values ())) 0) (test (+ (values 1 2 3)) 6) (test (let ((f (lambda () (values 1 2 3)))) (+ (f))) 6) (num-test (log (values 8 2)) 3) (test (* (values 2 (values 3 4))) 24) (test (* (values (+ (values 1 2)) (- (values 3 4)))) -3) (test (list (values 1 2) (values 3) 4) '(1 2 3 4)) (test (let ((f1 (lambda (x) (values x (+ x 1)))) (f2 (lambda () (values 2)))) (+ (f1 3) (* 2 (f2)))) 11) (test (+ (let () (values 1 2)) 3) 6) (test (let () (values 1 2) 4) 4) (test (let () + (values 1 2) 4) 4) (test (string-ref (values "hiho" 2)) #\h) (test (vector-ref (values (vector 1 2 3)) 1) 2) (test (+ (values (+ 1 (values 2 3)) 4) 5 (values 6) (values 7 8 (+ (values 9 10) 11))) 66) (test (+ (if (values) (values 1 2) (values 3 4)) (if (null? (values)) (values 5 6) (values 7 8))) 18) ; (values) is now # (sort of) (test (+ (cond (#f (values 1 2)) (#t (values 3 4))) 5) 12) (test (+ (cond (#t (values 1 2)) (#f (values 3 4))) 5) 8) (test (apply + (list (values 1 2))) 3) (test (apply + (list ((lambda (n) (values n (+ n 1))) 1))) 3) (test (+ (do ((i 0 (+ i 1))) ((= i 3) (values i (+ i 1))))) 7) (test (+ (with-input-from-string "(values 1 2 3)" (lambda () (eval (read)))) 2) 8) (test (< (values 1 2 3)) #t) (test (apply (values + 1 2) '(3)) 6) (test (let () (define-macro (hi a) `(+ 1 ,a)) (hi (values 1 2 3))) 7) (test (+ 1 (eval-string "(values 2 3 4)")) 10) (test (+ 1 (eval '(values 2 3 4))) 10) (test (or (values #t) #f) #t) (test (and (values #t) #f) #f) (test (let ((x 1)) (set! x (values 32)) x) 32) (test (let ((x #(32 33))) ((values x) 0)) 32) (test (let ((x #(32 33))) (set! ((values x) 0) 123) x) #(123 33)) (test (list-ref '(1 (2 3)) (values 1 1)) 3) (test (list-ref (values '(1 (2 3)) 1 1)) 3) (test (list-ref ((lambda () (values '(1 (2 3)) 1 1)))) 3) (test (set! (values) 1) 'error) (test (+ (values (begin (values 1 2)) (let ((x 1)) (values x (+ x 1))))) 6) (test (vector 1 (values 2 3) 4) #(1 2 3 4)) (test (vector (values 1 (values 2 3) (values (values 4)))) #(1 2 3 4)) (test(+ 1 (values (values (values 2) 3) (values (values (values 4)) 5) 6) 7) 28) (test (map (values values #(1 2))) '(1 2)) (test ((values values) (values 0)) 0) (test (((values values values) 0)) 0) (test ((apply (values values values '((1 2))))) '(1 2)) (test (apply begin (values (list 1))) 1) (test (apply begin (values '(values "hi"))) (apply (values begin '(values "hi")))) (test ((object->string values) (abs 1)) #\a) (test (list? (values 1 2 3)) 'error) (test (list? (values 1)) #f) (test (list? (values (list 1 2 3))) #t) (test (let ((x 1)) (set! x (values)) x) #) (test ((lambda () (let ((x 1)) (set! x (boolean? (values)))))) #f) (test (let ((x 1)) (set! x (values 1 2 3)) x) 'error) (test (let ((x 1)) (set! x (values 2)) x) 2) (test (let ((x 1)) (set! (values x) 2) x) 'error) ; (no generalized set for values, so (values x) is not the same as x (test (let ((x #(0 1))) (set! (values x 0 32)) x) 'error) (test (let ((var (values 1 2 3))) var) 'error) (test (let* ((var (values 1 2 3))) var) 'error) (test (letrec ((var (values 1 2 3))) var) 'error) (test (let ((x ((lambda () (values 1 2))))) x) 'error) (test (+ 1 ((lambda () ((lambda () (values 2 3)))))) 6) (test (let () (define (hi) (symbol? (values 1 2 3))) (hi)) 'error) (test (let () (define (hi) (symbol? (values))) (hi)) #f) ; this is consistent with earlier such cases: (boolean? (values)) (test (let () (define (hi) (symbol? (values 'a))) (hi)) #t) (test (let () (define (hi) (symbol? (values 1))) (hi)) #f) (test (let () (define (hi a) (log (values 1 2) a)) (hi 2)) 'error) (test (let () (define (arg2 a) (let ((b 1)) (set! b (+ a b)) (values b a))) (define (hi c) (expt (abs c) (arg2 2))) (hi 2)) 'error) (test (let () (define (arg2 a) (let ((b 1)) (set! b (+ a b)) (values b))) (define (hi c) (expt (abs c) (arg2 2))) (hi 2)) 8) (test (let () (define (hi) (+ (values 1 2) (values 3 4))) (hi)) 10) (test (let ((str "hi")) (string-set! (values str 0 #\x)) str) "xi") (test (values if) if) (test (values quote) quote) (test ((values '(1 (2 3)) 1 1)) 3) (test (let ((x #(32 33))) ((values x 0))) 32) (test (+ 1 (apply values '(2 3 4))) 10) (test (eq? (values) (apply values ())) #t) (test (+ 1 ((lambda args (apply values args)) 2 3 4)) 10) (test (apply begin '(1 2 3)) 3) (test (let ((x 1)) ((values set!) x 32) x) 32) (let ((x 0)) (test (list (set! x 10)) (call-with-values (lambda () (set! x 10)) list))) ; from r7rs discussion (let () (define (curry function . args) (lambda more-args (function (apply values args) (apply values more-args)))) ; unfortunately this doesn't handle 0 args (test ((curry + 1 2) 3 4) 10)) (let () (define (curry function . args) (if (null? args) function (lambda more-args (if (null? more-args) (apply function args) (function (apply values args) (apply values more-args)))))) (test ((curry + 1 2) 3 4) 10) (test ((curry + 2) 3 4) 9) (test ((curry +) 3 4) 7) (test ((curry +)) 0) (test ((curry + 1 2)) 3) (test ((curry + 1)) 1) (test ((curry +) 1) 1)) (test (or (values #t #f) #f) #t) (test (or (values #f #f) #f) #f) (test (or (values #f #t) #f) #t) (test (or (values #f #f) #t) #t) (test (or (values 1 2) #f) 1) (test (+ 1 (or (values 2 3) 4)) 3) (test (+ 1 (and 2 (values 3 4)) 5) 13) (test (and (values) 1) 1) (test (and (values 1 2 #f) 4) #f) (test (and (values 1 2 3) 4) 4) (test (length (values ())) 0) (test (length (values #(1 2 3 4))) 4) (test (vector? (values #())) #t) (test (map + (values '(1 2 3) #(1 2 3))) '(2 4 6)) (test (map + (values '(1 2 3)) (values #(1 2 3))) '(2 4 6)) (test (map + (values '(1 2 3) #(4 5 6)) (values '(7 8 9))) '(12 15 18)) (test (let ((x 1)) (and (let () (set! x 2) #f) (let () (set! x 3) #f)) x) 2) (test (let ((x 1)) (and (values (let () (set! x 2) #f) (let () (set! x 3) #f))) x) 3) (test (+ (values 1 2) 3) 6) (test (+ (values 1 (values 2))) 3) (test (list (values 1 2)) '(1 2)) (test (+ 6 (values 1 (values 2 3) 4 ) 5) 21) (test (+ ((lambda (x) (values (+ 1 x))) 2) 3) 6) (test (list ((lambda (x) (values (+ 1 x))) 2)) '(3)) (test (+ (begin (values 1 2))) 3) (test (+ 1 (let () (values 1 2))) 4) (test (apply (values + 1 2) (list 3)) 6) (test ((lambda* ((a 1) (b 2)) (list a b)) (values :a 3)) '(3 2)) (test (+ (values (values 1 2) (values 4 5))) 12) (test (+ (begin 3 (values 1 2) 4)) 4) (test (map (lambda (x) (if #f x (values))) (list 1 2)) ()) (test (map (lambda (x) (if #f x (begin (values)))) (list 1 2)) ()) (test (map (lambda (x) (if (odd? x) (values x (* x 20)) (values))) (list 1 2 3 4)) '(1 20 3 60)) (test (map (lambda (x) (if (odd? x) (values x (* x 20)) (if #f #f))) (list 1 2 3 4)) '(1 20 # 3 60 #)) (test (map (lambda (x) (if (odd? x) (apply values '(1 2 3)) (values))) (list 1 2 3 4)) '(1 2 3 1 2 3)) (test (object->string (map (lambda (x) (if (odd? x) (values x (* x 20)) (values))) (list 1 2 3 4))) "(1 20 3 60)") ; make sure no "values" floats through (test (map (lambda (x) (if (odd? x) (values x (* x 20) (cons x (+ x 1))) (values))) (list 1 2 3 4 5 6)) '(1 20 (1 . 2) 3 60 (3 . 4) 5 100 (5 . 6))) (test (* 2 (case 1 ((2) (values 3 4)) ((1) (values 5 6)))) 60) (test (* 2 (case 1 ((2) (values 3 4)) (else (values 5 6)))) 60) (test (* 2 (case 1 ((1) (values 3 4)) (else (values 5 6)))) 24) (test (+ (values (* 3 2) (abs (values -1)))) 7) (test (+ (let ((x 1)) (values x (+ x 1))) (if #f #f (values 2 3))) 8) (test (let ((sum 0)) (for-each (lambda (n m p) (set! sum (+ sum n m p))) (values (list 1 2 3) (list 4 5 6) (list 7 8 9))) sum) 45) (test (map (lambda (n m p) (+ n m p)) (values (list 1 2 3) (list 4 5 6) (list 7 8 9))) '(12 15 18)) (test (string-append (values "123" "4" "5") "6" (values "78" "90")) "1234567890") (test (+ (dynamic-wind (lambda () #f) (lambda () (values 1 2 3)) (lambda () #f)) 4) 10) (for-each (lambda (arg) (test (values arg) arg)) (list "hi" -1 #\a 1 'a-symbol #(1 2 3) 3.14 3/4 1.0+1.0i #t (list 1 2 3) '(1 . 2))) (for-each (lambda (arg) (test (apply values arg) 'error) (test (apply values (list arg)) arg)) (list "hi" -1 #\a 1 'a-symbol #(1 2 3) 3.14 3/4 1.0+1.0i #t '(1 . 2))) (for-each (lambda (arg) (test (call-with-values (lambda () (values arg arg)) (lambda (a b) b)) arg)) (list "hi" -1 #\a 1 'a-symbol #(1 2 3) 3.14 3/4 1.0+1.0i #t (list 1 2 3) '(1 . 2))) (test (call-with-values (lambda () (values "hi" 1 3/2 'a)) (lambda (a b c d) (+ b c))) 5/2) ;(test (call-with-values values (lambda arg arg)) ()) (test (string-ref (values "hi") 1) #\i) (test ((lambda (a b) (+ a b)) ((lambda () (values 1 2)))) 3) (test (list (letrec ((split (lambda (ls) (if (or (null? ls) (null? (cdr ls))) (values ls ()) (call-with-values (lambda () (split (cddr ls))) (lambda (odds evens) (values (cons (car ls) odds) (cons (cadr ls) evens)))))))) (split '(a b c d e f)))) '((a c e) (b d f))) (let () (define (f1 . args) (apply values (+ (car args) (cadr args)) (cddr args))) (test (* (f1 2 3 4)) 20) (test (* (f1 2 3 4) (f1 1 2 3)) 180) (test (- (f1 2 3 4) (f1 1 2 3)) -5)) (test (call-with-values (lambda () (call/cc (lambda (k) (k 2 3)))) (lambda (x y) (list x y))) '(2 3)) (test (+ (call/cc (lambda (return) (return (values 1 2 3)))) 4) 10) (test (let ((values 3)) (+ 2 values)) 5) (test (let ((a (values 1))) a) 1) (test (call-with-values (lambda () 2) (lambda (x) x)) 2) (test (call-with-values (lambda () -1) abs) 1) (test (call-with-values (lambda () (values -1)) abs) 1) (test (call-with-values (lambda () (values -1)) (lambda (a) (abs a))) 1) (test (call-with-values (lambda () (values (call-with-values (lambda () (values 1 2 3)) +) (call-with-values (lambda () (values 1 2 3 4)) *))) (lambda (a b) (- a b))) -18) (test (call-with-values (lambda () (values (call-with-values (lambda () (values 1 2 3)) +) (call-with-values (lambda () (values 1 2 3 4)) *))) (lambda (a b) (+ (* a (call-with-values (lambda () (values 1 2 3)) +)) (* b (call-with-values (lambda () (values 1 2 3 4)) *))))) 612) (test (call-with-values (lambda (x) (+ x 1)) (lambda (y) y)) 'error) (test (+ (values . 1)) 'error) (for-each (lambda (arg) (test (call-with-values arg arg) 'error)) (list "hi" -1 #\a 1 'a-symbol 3.14 3/4 1.0+1.0i #t (list 1 2 3) '(1 . 2))) (test (call-with-values (lambda () (values -1 2)) abs) 'error) (test (multiple-value-bind (a b) (values 1 2) (+ a b)) 3) (test (multiple-value-bind (a) 1 a) 1) (test (multiple-value-bind (a . rest) (values 1 2 3) (+ a (apply + rest))) 6) (test (multiple-value-bind a (values 1 2 3) a) '(1 2 3)) (test (multiple-value-bind (x y z) (values 1 2 3) (list z y x)) '(3 2 1)) (test (multiple-value-bind (x y z) (values 1 2 3) (let ((x 4)) (list x y z))) '(4 2 3)) (test (multiple-value-bind (x y z) (values 1 2 3 4 5 6) (list x y z)) '(1 2 3)) (test (multiple-value-bind (x y z) (values 1 2) (list x y z)) '(1 2 #f)) (test (multiple-value-bind (x y z) (multiple-value-bind () (values 1 2) (values 'a 'b 'c)) (list x y z)) '(a b c)) (test (let ((a 1) (b 2)) (multiple-value-set! (a b) (values 32 64)) (+ a b)) 96) (test (let ((a 1) (b 2)) (multiple-value-set! (a b) (values 32 64) (set! a (+ b 1))) (+ a b)) 129) (test (let ((a 1) (b 2)) (multiple-value-set! (a b) (values 32 64 12)) (+ a b)) 96) (test (let ((a 1) (b 2)) (multiple-value-set! (a b) (values 32)) (cons a b)) '(32 . #f)) (test (multiple-value-set! #() "1234" #(0 1 2 3 4)) 'error) (test (multiple-value-set! "" #(0 1 2 3 4) :readable) 'error) (test (multiple-value-set! () #(0 1 2 3 4) :readable) 'error) (test (multiple-value-set! () ()) ()) (test (multiple-value-set! () () 1 2) 2) (test (let ((add (lambda (a b) (values (+ a 1) (+ b 1))))) (+ 1 (add 2 3))) 8) (test (min (values 1 2) (values 3 0)) 0) (test ((lambda* ((a 1) (b 2)) (list a b)) (values :b 231)) '(1 231)) (test (cons (values 1 2) (values 3 4)) 'error) (test (cond ((values) 3) (#t 4)) 3) ; an error in Guile "zero values returned" (test (cond ((values (values)) 3) (#t 4)) 3) ; same (test (+ (cond (#t (values 1 2)))) 3) ; 1 in guile (test (+ (cond ((values 3 4) => (lambda (a) a)))) 'error) (test (+ (cond ((values 3 4) => (lambda (a b) (values a b))))) 7) (test (+ 1 (cond ((values 2 3))) 4) 10) (test (+ 1 (values)) 'error) (test (case (values 1) ((1) 2) (else 3)) 2) (test (case (values 1 2) ((1) 2) (else 3)) 3) (test (case (values 1) (((values 1)) 2) (else 3)) 3) (test (case (values 1 2) (((values 1 2)) 2) (else 3)) 3) (test ((values) 0) 'error) (test ((values "hi") 1) #\i) (test (string-ref (values "hi") 0) #\h) (test (string-ref (values "hi" "ho") 0) 'error) (test (let ((str "hi")) (set! ((values str) 0) #\x) str) "xi") (test (let ((str "hi")) (string-set! (values str) 0 #\x) str) "xi") (test (let ((str "hi")) (set! (values str 0) #\x) str) 'error) (test (let ((str "hi")) (string-set! (values str 0) #\x) str) "xi") (test ((values 1 2 3) 0) 'error) (test ((values "hi" "ho") 1) 'error) (test ((values + 1 2 3)) 6) (test ((values + 1 2) 3) 6) (test ((values +) 1 2 3) 6) (test ((values "hi" 0)) #\h) (test ((values + 1) (values 2 3) 4) 10) (test ((values - 10)) -10) (test ((values - -10) 0) -10) ; looks odd but it's (- -10 0) that is (- a) != (- a 0) (test ((values - 2 3) 0) -1) (test ((values - 2 3) 1) -2) (test ((values - 2 3) 2) -3) ; it's actually (- 2 3 2) -> -3 (test (let ((str "hi")) (set! ((values str 0) 0) #\x) str) 'error) (test (let ((str "hi")) (set! ((values str) 0) #\x) str) "xi") (test (+ (let ((x 0)) (do ((i (values 0) (+ i 1))) (((values = i 10)) (values x 2 3)) (set! x (+ x i)))) 4) 54) (test (map values (list (values 1 2) (values 3 4))) '(1 2 3 4)) (test (let () (define-macro (hi a) `(+ 1 ,a)) (hi (values 2 3 4))) 10) (test (let () (+ 4 (let () (values 1 2 3)) 5)) 15) (test (let* () (+ 4 (let () (values 1 2 3)) 5)) 15) (test (let () (+ 4 (let* () (values 1 2 3)) 5)) 15) (test (letrec () (+ 4 (let () (values 1 2 3)) 5)) 15) (test (let () (+ 4 (letrec () (values 1 2 3)) 5)) 15) (test (letrec* () (+ 4 (let () (values 1 2 3)) 5)) 15) (test (let* () (+ 4 (letrec* () (values 1 2 3)) 5)) 15) (test (cons (values 1 2)) '(1 . 2)) (test (number->string (values 1 2)) "1") (test (object->string (values)) "#") (test (equal? (values) #) #t) (test (equal? (begin) (begin (values))) #f) ; () but # (test (map (lambda (x) (if #f x #)) (list 1 2)) '(# #)) (test (equal? (values) (if #f #f)) #t) (test (substring (values "hi") (values 1 2)) "i") (test (cond (call-with-exit (values "hi"))) "hi") (test (values (begin (values "hi"))) "hi") (test (< (values (values 1 2))) #t) (test (let ((lst (list 0))) (set-cdr! lst lst) (format (values #f "~A" lst))) "#1=(0 . #1#)") (let () (define (mv n) (define (mv-1 a) (values a (+ a 1))) (define (mv-2 b) (values b (* b 2))) (values n (mv-1 n) (mv-2 n))) (test (list (mv 2)) '(2 2 3 2 4)) (test (+ (mv 1) (mv 3)) 26)) (let () (define (fib n) (define (1st a b) a) (define (fib-1 n) (if (< n 3) (values 1 1) (values (+ (fib-1 (- n 1))) (1st (fib-1 (- n 1)))))) (1st (fib-1 n))) (test (fib 8) 21) (test (fib 13) 233)) (let () (define (fib n) (define (1st a b) a) (define (2nd a b) (values (+ a b) a)) (define (fib-1 n) (if (< n 3) (2nd 1 0) (2nd (fib-1 (- n 1))))) (1st (fib-1 n))) (define (real-fib n) (let ((phi (/ (+ 1 (sqrt 5)) 2))) (floor (real-part (/ (- (expt phi n) ; "floor" to return an integer, real-part to guard against epsilonic imag-parts from expt (expt (- 1 phi) n)) (sqrt 5)))))) (test (fib 8) (real-fib 8)) (test (fib 13) (real-fib 13))) (let () (define (cfib z) ; wikipedia "generalized fibonacci numbers" (let ((phi (/ (+ 1 (sqrt 5)) 2))) (/ (- (expt phi z) (* (expt phi (- z)) (cos (* pi z)))) (sqrt 5)))) (num-test (cfib 3) 2.0) (num-test (cfib 8) 21.0) (num-test (cfib 3+4i) -5248.5113072837-14195.962288353i)) (num-test (let ((f- -) (f+ +)) (define (fb n) (if (< n 2.0) n (f+ (fb (f- n 1.0)) (fb (f- n 2.0))))) (fb 12.0)) 144.0) (let () (define (flatten lst) ; flatten via values and map (define (flatten-1 lst) (cond ((null? lst) (values)) ((not (pair? lst)) lst) (#t (values (flatten-1 (car lst)) (flatten-1 (cdr lst)))))) (map values (list (flatten-1 lst)))) (test (flatten '(1 2 3)) '(1 2 3)) (test (flatten ()) ()) (test (flatten '((1) 2 (3 4) (6 (7)))) '(1 2 3 4 6 7)) (test (flatten '(1 ((((2)) 3)))) '(1 2 3)) (test (flatten '(1 () 2)) '(1 2)) (test (flatten '((1 () 2) ())) '(1 2)) (test (flatten '(() 1 ((2 (3)) () 4))) '(1 2 3 4)) (test (flatten '((1) 2 ((3 4) 5) ((())) (((6))) 7 8 ())) '(1 2 3 4 5 6 7 8)) (test (flatten '(() 1 () ((2 (1)) 4) (3 2) ())) '(1 2 1 4 3 2)) ) (let () (define (flatten! lst) ; in-place flatten (if (not (pair? lst)) lst (let loop ((L lst)) (if (pair? (car L)) (let ((end (cdr L)) (p (car L))) (set! (car L) (car p)) (set! (cdr L) (cdr p)) (set! (cdr (list-tail L (- (length p) 1))) end) (loop L)) (if (not (null? (cdr L))) (if (null? (car L)) (begin (set! (car L) (cadr L)) (set! (cdr L) (cddr L)) (loop L)) (loop (cdr L))))) (if (equal? lst '(())) () (let ((len (length lst))) (if (null? (car (list-tail lst (- len 1)))) (set! (cdr (list-tail lst (- len 2))) ())) lst))))) (test (flatten! '(1 2 3)) '(1 2 3)) (test (flatten! ()) ()) (test (flatten! '((1) 2 (3 4) (6 (7)))) '(1 2 3 4 6 7)) (test (flatten! '(1 ((((2)) 3)))) '(1 2 3)) (test (flatten! '(1 () 2)) '(1 2)) (test (flatten! '((1 () 2) ())) '(1 2)) (test (flatten! '(() 1 ((2 (3)) () 4))) '(1 2 3 4)) (test (flatten! '((1) 2 ((3 4) 5) ((())) (((6))) 7 8 ())) '(1 2 3 4 5 6 7 8)) (test (flatten! '(() 1 () ((2 (1)) 4) (3 2) ())) '(1 2 1 4 3 2)) ) (let () (define (flatten x) ; standard flatten (cond ((null? x) ()) ((not (pair? x)) (list x)) (#t (append (flatten (car x)) (flatten (cdr x)))))) (test (flatten '(1 2 3)) '(1 2 3)) (test (flatten ()) ()) (test (flatten '((1) 2 (3 4) (6 (7)))) '(1 2 3 4 6 7)) (test (flatten '(1 ((((2)) 3)))) '(1 2 3)) (test (flatten '(1 () 2)) '(1 2)) (test (flatten '((1 () 2) ())) '(1 2)) (test (flatten '(() 1 ((2 (3)) () 4))) '(1 2 3 4)) (test (flatten '((1) 2 ((3 4) 5) ((())) (((6))) 7 8 ())) '(1 2 3 4 5 6 7 8)) (test (flatten '(() 1 () ((2 (1)) 4) (3 2) ())) '(1 2 1 4 3 2)) ) (test (let () (define (hi a) (+ (abs a) (values 1 2 3))) (hi -4)) 10) (let () (define (hi a) (let ((x 0) (again #f)) (let ((y (+ (abs a) (call/cc (lambda (r) (set! again r) 1))))) (set! x (+ x y)) (if (< x 3) (again 1)) x))) (test (hi 0) 3)) (let () (define-macro (define-values vars . body) `(apply begin (map (lambda (var val) `(define ,var ,val)) ',vars (list (begin ,@body))))) (define-macro (let*-values vars . body) `(let () ,@(map (lambda (nvars . nbody) `(apply define-values ',nvars ',@nbody)) (map car vars) (map cdr vars)) ,@body)) (let () (define-values (a b) (values 3 2)) (test (* a b) 6)) (let () (test (let*-values (((a b) (values 3 2))) (* a b)) 6))) (define __p__ 123) (define current-rootlet (curlet)) (let ((__p__ 321)) (set! __p__ 432)) (if (not (= __p__ 123)) (format-logged #t "__p__: ~A~%" __p__)) (let () (define (args) (values __p__ (* __p__ 2))) (let ((__p__ 0) (q 1)) (call-with-values args (lambda (a b) (set! __p__ a) (set! q b))) (if (not (= __p__ 123)) (format-logged #t " local __p__: ~A~%" __p__)) (set! __p__ 432) (call-with-values args (lambda (__p__ q) (set! __p__ 321))) (if (not (= __p__ 432)) (format-logged #t " local __p__: ~A~%" __p__)))) (if (not (= __p__ 123)) (format-logged #t "__p__: ~A~%" __p__)) (let () (define-macro (args a b) `(values ,a ,b)) (define (sp a b) (set! a 121)) (define (pq __p__ q) (set! __p__ q)) (sp (args __p__ __p__)) (pq (args __p__ 567))) (if (not (= __p__ 123)) (format-logged #t "__p__: ~A~%" __p__)) (let ((__p__ 321)) (eval '(set! __p__ 432) current-rootlet) (if (not (= __p__ 321)) (format-logged #t " local __p__: ~A~%" __p__)) (eval '(set! __p__ 123)) (if (not (= __p__ 123)) (format-logged #t " local __p__: ~A~%" __p__))) (if (not (= __p__ 432)) (format-logged #t "__p__: ~A~%" __p__)) (let () (eval '(let ((__p__ 321)) (set! __p__ 456)) current-rootlet)) (if (not (= __p__ 432)) (format-logged #t "__p__: ~A~%" __p__)) (let ((__p__ (values __p__))) (if (not (= __p__ 432)) (format-logged #t " local __p__: ~A~%" __p__)) (set! __p__ 123)) (if (not (= __p__ 432)) (format-logged #t "__p__: ~A~%" __p__)) (let () (define (sp __p__ q) (values __p__ q)) (call-with-values (lambda () (sp __p__ (* __p__ 2))) (let ((__p__ 1)) (lambda (a b) (set! __p__ a))))) (if (not (= __p__ 432)) (format-logged #t "__p__: ~A~%" __p__)) (let ((lst (list __p__ (* __p__ 2)))) (define-macro (sp a) `(set! __p__ ,a)) (let ((__p__ 0) (q 1)) (define (pq a) (set! __p__ a)) (map sp (list __p__ q)) (if (not (= __p__ 1)) (format-logged #t " local __p__: ~A~%" __p__)) (for-each sp (list __p__ q)) (if (not (= __p__ 1)) (format-logged #t " local __p__: ~A~%" __p__)) (map sp lst) (if (not (= __p__ (* 432 2))) (format-logged #t " local __p__: ~A~%" __p__)) (for-each sp lst) (if (not (= __p__ (* 432 2))) (format-logged #t " local __p__: ~A~%" __p__)) (set! __p__ 0) (set! q 1) (map pq (list __p__ q)) (if (not (= __p__ 1)) (format-logged #t " local __p__: ~A~%" __p__)) (for-each pq (list __p__ q)) (if (not (= __p__ 1)) (format-logged #t " local __p__: ~A~%" __p__)) (map pq lst) (if (not (= __p__ (* 432 2))) (format-logged #t " local __p__: ~A~%" __p__)) (for-each pq lst) (if (not (= __p__ (* 432 2))) (format-logged #t " local __p__: ~A~%" __p__)))) (if (not (= __p__ 432)) (format-logged #t "__p__: ~A~%" __p__)) (if (eq? (curlet) (rootlet)) (begin (let ((__p__ 1)) (eval `(define (__p__ a) (+ a ,__p__)) current-rootlet) (if (not (= __p__ 1)) (format-logged #t " local __p__: ~A~%" __p__))) (if (not (procedure? __p__)) (format-logged #t "__p__: ~A~%" __p__)) (if (not (= (__p__ 2) 3)) (format-logged #t "(__p__ 2): ~A~%" (__p__ 2))) (let ((__p__ 1)) (eval `(define __p__ 32)) (if (not (= __p__ 32)) (format-logged #t " local __p__: ~A~%" __p__))) (if (not (procedure? __p__)) (format-logged #t "__p__: ~A~%" __p__)) (if (not (= (__p__ 2) 3)) (format-logged #t "(__p__ 2): ~A~%" (__p__ 2))) (let ((__p__ 1)) (eval `(define __p__ 32) (curlet)) (if (not (= __p__ 32)) (format-logged #t " local __p__: ~A~%" __p__))) (if (not (procedure? __p__)) (format-logged #t "__p__: ~A~%" __p__)) (if (not (= (__p__ 2) 3)) (format-logged #t "(__p__ 2): ~A~%" (__p__ 2))) )) (let () (define-macro (m1) (values)) (define-macro (m2) (values 2 3)) (define-macro (m3) (values '(+ 1 2) '(* 3 4))) (define-macro (m4) (values '(define a 1) '(define b 2))) (define-macro (m5 a b) (values `(define a ,a) `(define b (+ ,b 1)))) (test (begin (m1)) #) (test (+ (m2)) 5) (test (+ 1 (m3) 3) 19) (test (let () (m4) (+ a b)) 3) (test (let () (m5 1 2) (+ a b)) 4)) ;;; -------------------------------------------------------------------------------- ;;; let ;;; let* ;;; letrec ;;; letrec* ;;; -------------------------------------------------------------------------------- (test (let ((x 2) (y 3)) (* x y)) 6) (test (let ((x 32)) (let ((x 3) (y x)) y)) 32) (test (let ((x 32)) (let* ((x 3) (y x)) y)) 3) (test (let ((x 2) (y 3)) (let ((x 7) (z (+ x y))) (* z x))) 35) (test (let ((x 2) (y 3)) (let* ((x 7) (z (+ x y))) (* z x))) 70) (test (letrec ((is-even (lambda (n) (if (zero? n) #t (is-odd (- n 1))))) (is-odd (lambda (n) (if (zero? n) #f (is-even (- n 1)))))) (is-even 88)) #t) (test (let loop ((numbers '(3 -2 1 6 -5)) (nonneg ()) (neg ())) (cond ((null? numbers) (list nonneg neg)) ((>= (car numbers) 0) (loop (cdr numbers) (cons (car numbers) nonneg) neg)) ((< (car numbers) 0) (loop (cdr numbers) nonneg (cons (car numbers) neg))))) '((6 1 3) (-5 -2))) (test(let((i 1)(j 2))(+ i j))3) (test (let ((x 3)) (define x 5) x) 5) (test (let* () (define x 8) x) 8) (test (letrec () (define x 9) x) 9) (test (letrec ((x 3)) (define x 10) x) 10) (test (let foo () 1) 1) (test (let ((f -)) (let f ((n (f 1))) n)) -1) (test (let () 1 2 3 4) 4) (test (+ 3 (let () (+ 1 2))) 6) (test (let ((x 1)) (let ((x 32) (y x)) y)) 1) (test (let ((x 1)) (letrec ((y (if #f x 1)) (x 32)) 1)) 1) (test (let ((x 1)) (letrec ((y (lambda () (+ 1 x))) (x 32)) (y))) 33) (test (let ((x 1)) (letrec ((y (* 0 x)) (x 32)) y)) 'error) (test (let* ((x 1) (f (letrec ((y (lambda () (+ 1 x))) (x 32)) y))) (f)) 33) (test (letrec ((x 1) (y (let ((x 2)) x))) (+ x y)) 3) (test (letrec ((f (lambda () (+ x 3))) (x 2)) (f)) 5) (test (let* ((x 1) (x 2)) x) 2) (test (let* ((x 1) (y x)) y) 1) (test (let ((x 1)) (let ((x 32) (y x)) (+ x y))) 33) (test (let ((x 1)) (let* ((x 32) (y x)) (+ x y))) 64) (test (let ((x 'a) (y '(b c))) (cons x y)) '(a b c)) (test (let ((x 0) (y 1)) (let ((x y) (y x)) (list x y))) (list 1 0)) (test (let ((x 0) (y 1)) (let* ((x y) (y x)) (list x y))) (list 1 1)) (test (letrec ((sum (lambda (x) (if (zero? x) 0 (+ x (sum (- x 1))))))) (sum 5)) 15) (test (let ((divisors (lambda (n) (let f ((i 2)) (cond ((>= i n) ()) ((integer? (/ n i)) (cons i (f (+ i 1)))) (else (f (+ i 1)))))))) (divisors 32)) '(2 4 8 16)) (test (let ((a -1)) (let loop () (if (not (positive? a)) (begin (set! a (+ a 1)) (loop)))) a) 1) (test (let () (let () (let () ()))) ()) (test (let ((x 1)) (let ((y 0)) (begin (let ((x (* 2 x))) (set! y x))) y)) 2) (test (let* ((x 1) (x (+ x 1)) (x (+ x 2))) x) 4) (test (let ((.. 2) (.... 4) (..... +)) (..... .. ....)) 6) (test (let () (begin (define x 1)) x) 1) (test (let ((define 1)) define) 1) (test (let ((y 1)) (begin (define x 1)) (+ x y)) 2) (test (let ((: 0)) (- :)) 0) ;; this only works if we haven't called (string->symbol "") making : into a keyword (see also other cases below) ;; perhaps I should document this weird case -- don't use : as a variable name ;;; optimizer troubles (test (let () (define (f x) (let asd ())) (f 1)) 'error) (test (let () (define (f x) (let ())) (f 1)) 'error) (test (let ((pi 3)) pi) 'error) (test (let ((:key 1)) :key) 'error) (test (let ((:3 1)) 1) 'error) (test (let ((3 1)) 1) 'error) (test (let ((3: 1)) 1) 'error) (test (let ((optional: 1)) 1) 'error) (test (let ((x_x_x 32)) (let () (define-constant x_x_x 3) x_x_x) (set! x_x_x 31) x_x_x) 'error) (test (let ((x 1)) (+ (let ((a (begin (define x 2) x))) a) x)) 4) (test (let ((x 1)) (+ (letrec ((a (begin (define x 2) x))) a) x)) 3) (test (let ((a #)) (eof-object? a)) #t) (test (let ((a #)) (eq? a #)) #t) (test (let* ((x 1) (x (+ x 1))) x) 2) ; ?? (test (let _name_ ((x 1) (y (_name_ 2))) (+ x y)) 'error) (test (let* _name_ ((x 1) (y (_name_ 2))) (+ x y)) 'error) (let () (define (hi) (let* named-let ((i 0) (j (+ i 1))) j)) (hi) (test (hi) 1)) (test ((let ((x 2)) (let ((x 3)) (lambda (arg) (+ arg x)))) 1) 4) (test ((let ((x 2)) (define (inner arg) (+ arg x)) (let ((x 32)) (lambda (arg) (inner (+ arg x))))) 1) 35) (test ((let ((inner (lambda (arg) (+ arg 1)))) (let ((inner (lambda (arg) (inner (+ arg 2))))) inner)) 3) 6) (test ((let () (define (inner arg) (+ arg 1)) (let ((inner (lambda (arg) (inner (+ arg 2))))) inner)) 3) 6) (test ((let ((x 11)) (define (inner arg) (+ arg x)) (let ((inner (lambda (arg) (inner (+ (* 2 arg) x))))) inner)) 3) 28) (test ((let ((x 11)) (define (inner arg) (+ arg x)) (let ((x 2)) (lambda (arg) (inner (+ (* 2 arg) x))))) 3) 19) (test (let ((f1 (lambda (arg) (+ arg 1)))) (let ((f1 (lambda (arg) (f1 (+ arg 2))))) (f1 1))) 4) (test (let ((f1 (lambda (arg) (+ arg 1)))) (let* ((f1 (lambda (arg) (f1 (+ arg 2))))) (f1 1))) 4) (test (let ((f1 (lambda (arg) (+ arg 1)))) (let* ((x 32) (f1 (lambda (arg) (f1 (+ x arg))))) (f1 1))) 34) (test ((let ((x 11)) (define (inner arg) (+ arg x)) (let ((x 2) (inner (lambda (arg) (inner (+ (* 2 arg) x))))) inner)) 3) 28) (test ((let ((x 11)) (define (inner arg) (+ arg x)) (let* ((x 2) (inner (lambda (arg) (inner (+ (* 2 arg) x))))) inner)) 3) 19) (test (let ((x 1)) (let* ((f1 (lambda (arg) (+ x arg))) (x 32)) (f1 1))) 2) (test (let ((inner (lambda (arg) (+ arg 1)))) (let ((inner (lambda (arg) (+ (inner arg) 1)))) (inner 1))) 3) (test (let ((inner (lambda (arg) (+ arg 1)))) (let* ((inner (lambda (arg) (+ (inner arg) 1)))) (inner 1))) 3) (test (let ((caller #f)) (let ((inner (lambda (arg) (+ arg 1)))) (set! caller inner)) (caller 1)) 2) (test (let ((caller #f)) (let ((x 11)) (define (inner arg) (+ arg x)) (set! caller inner)) (caller 1)) 12) (test (let ((caller #f)) (let ((x 11)) (define (inner arg) (+ arg x)) (let ((y 12)) (let ((inner (lambda (arg) (+ (inner x) y arg)))) ; 11 + 11 + 12 + arg (set! caller inner)))) (caller 1)) 35) (test (let ((caller #f)) (let ((x 11)) (define (inner arg) (+ arg x)) (let* ((y 12) (inner (lambda (arg) (+ (inner x) y arg)))) ; 11 + 11 + 12 + arg (set! caller inner))) (caller 1)) 35) (test (let* ((f1 3) (f1 4)) f1) 4) (test (let ((f1 (lambda () 4))) (define (f1) 3) (f1)) 3) (test (let ((j -1) (k 0)) (do ((i 0 (+ i j)) (j 1)) ((= i 3) k) (set! k (+ k i)))) 3) (test (let ((j (lambda () -1)) (k 0)) (do ((i 0 (+ i (j))) (j (lambda () 1))) ((= i 3) k) (set! k (+ k i)))) 3) (test (let ((j (lambda () 0)) (k 0)) (do ((i (j) (j)) (j (lambda () 1) (lambda () (+ i 1)))) ((= i 3) k) (set! k (+ k i)))) 3) ; 6 in Guile which follows the spec (test (let ((k 0)) (do ((i 0 (+ i 1)) (j 0 (+ j i))) ((= i 3) k) (set! k (+ k j)))) 1) #| (test (let ((j (lambda () 0)) (i 2) (k 0)) (do ((i (j) (j)) (j (lambda () i) (lambda () (+ i 1)))) ((= i 3) k) (set! k (+ k i)))) 3) ; or 2? (test (let ((f #f)) (do ((i 0 (+ i 1))) ((= i 3)) (let () (define (x) i) (if (= i 1) (set! f x)))) (f)) 1) |# (test (let ((x 1)) (let () (define (f) x) (let ((x 0)) (define (g) (set! x 32) (f)) (g)))) 1) (test (let ((a 1)) (let () (if (> a 1) (begin (define a 2))) a)) 1) (test (let ((a 1)) (let () (if (= a 1) (begin (define a 2))) a)) 2) (let ((x 123)) (define (hi b) (+ b x)) (let ((x 321)) (test (hi 1) 124) (set! x 322) (test (hi 1) 124)) (set! x 124) (test (hi 1) 125) (let ((x 321) (y (hi 1))) (test y 125)) (let* ((x 321) (y (hi 1))) (test y 125)) (test (hi 1) 125)) (test (let ((j 0) (k 0)) (let xyz ((i 0)) (let xyz ((i 0)) (set! j (+ j 1)) (if (< i 3) (xyz (+ i 1)))) (set! k (+ k 1)) (if (< i 3) (xyz (+ i 1)))) (list j k)) (list 16 4)) (test (let ((x 123)) (begin (define x 0)) x) 0) ; this strikes me as weird, since (let ((x 123) (x 0)) x) is illegal, so... (test (let ((x 0)) (define x 1) (define x 2) x) 2) (test (let ((x 123)) (begin (define (hi a) (+ x a)) (define x 0)) (hi 1)) 1) ; is non-lexical reference? (test (let ((x 123)) (define (hi a) (+ x a)) (define x 0) (hi 1)) 1) (test (let ((x 123) (y 0)) (define (hi a) (+ y a)) (define y x) (define x 0) (hi 1)) 124) (for-each (lambda (arg) (test (let ((x arg)) x) arg)) (list "hi" -1 #\a "" () #() (current-output-port) 'a-symbol #(1 2 3) 3.14 3/4 1.0+1.0i #t abs (list 1 2 3) '(1 . 2))) (test (let ((x 1)) (= 1 (let ((y 2)) (set! x y) x)) (+ x 1)) 3) (test (let ((x 1)) (let ((xx (lambda (a) (set! x a) a))) (= 1 (xx 2))) (+ x 1)) 3) (test (let ((x 32)) (begin (define x 123) (define (hi a) (+ a 1))) (hi x)) 124) (test (let () (begin (define x 123) (define (hi a) (+ a 1))) (hi x)) 124) ;(let ((initial-chars "aA!$%&*/:<=>?^_~") ; (subsequent-chars "9aA!$%&*+-./:<=>?@^_~") ; (ctr 0)) ; (format-logged #t ";(let (") ; (do ((i 0 (+ i 1))) ; ((= i (string-length initial-chars))) ; (format-logged #t ";(~A ~D) " (string (string-ref initial-chars i)) ctr) ; (set! ctr (+ ctr 1))) ; ; (do ((i 0 (+ i 1))) ; ((= i (string-length initial-chars))) ; (do ((k 0 (+ k 1))) ; ((= k (string-length subsequent-chars))) ; (format-logged #t ";(~A ~D) " (string (string-ref initial-chars i) (string-ref subsequent-chars k)) ctr) ; (set! ctr (+ ctr 1)))) ; ; (format-logged #t ")~% (+ ") ; (do ((i 0 (+ i 1))) ; ((= i (string-length initial-chars))) ; (format-logged #t "~A " (string (string-ref initial-chars i)))) ; ; (do ((i 0 (+ i 1))) ; ((= i (string-length initial-chars))) ; (do ((k 0 (+ k 1))) ; ((= k (string-length subsequent-chars))) ; (format-logged #t "~A " (string (string-ref initial-chars i) (string-ref subsequent-chars k))))) ; ; (format-logged #t "))~%")) (num-test (let ((a 0) (A 1) (! 2) ($ 3) (% 4) (& 5) (| 8) (? 12) (^ 13) (_ 14) (~ 15) (a9 16) (aa 17) (aA 18) (a! 19) (a$ 20) (a% 21) (a& 22) (a* 23) (a+ 24) (a- 25) (a. 26) (a/ 27) (a| 28) (a< 29) (a= 30) (a> 31) (a? 32) (a@ 33) (a^ 34) (a_ 35) (a~ 36) (A9 37) (Aa 38) (AA 39) (A! 40) (A$ 41) (A% 42) (A& 43) (A* 44) (A+ 45) (A- 46) (A. 47) (A/ 48) (A| 49) (A< 50) (A= 51) (A> 52) (A? 53) (A@ 54) (A^ 55) (A_ 56) (A~ 57) (!9 58) (!a 59) (!A 60) (!! 61) (!$ 62) (!% 63) (!& 64) (!* 65) (!+ 66) (!- 67) (!. 68) (!/ 69) (!| 70) (!< 71) (!= 72) (!> 73) (!? 74) (!@ 75) (!^ 76) (!_ 77) (!~ 78) ($9 79) ($a 80) ($A 81) ($! 82) ($$ 83) ($% 84) ($& 85) ($* 86) ($+ 87) ($- 88) ($. 89) ($/ 90) ($| 91) ($< 92) ($= 93) ($> 94) ($? 95) ($@ 96) ($^ 97) ($_ 98) ($~ 99) (%9 100) (%a 101) (%A 102) (%! 103) (%$ 104) (%% 105) (%& 106) (%* 107) (%+ 108) (%- 109) (%. 110) (%/ 111) (%| 112) (%< 113) (%= 114) (%> 115) (%? 116) (%@ 117) (%^ 118) (%_ 119) (%~ 120) (&9 121) (&a 122) (&A 123) (&! 124) (&$ 125) (&% 126) (&& 127) (&* 128) (&+ 129) (&- 130) (&. 131) (&/ 132) (&| 133) (&< 134) (&= 135) (&> 136) (&? 137) (&@ 138) (&^ 139) (&_ 140) (&~ 141) (*9 142) (*a 143) (*A 144) (*! 145) (*$ 146) (*% 147) (*& 148) (** 149) (*+ 150) (*- 151) (*. 152) (*/ 153) (*| 154) (*< 155) (*= 156) (*> 157) (*? 158) (*@ 159) (*^ 160) (*_ 161) (*~ 162) (/9 163) (/a 164) (/A 165) (/! 166) (/$ 167) (/% 168) (/& 169) (/* 170) (/+ 171) (/- 172) (/. 173) (// 174) (/| 175) (/< 176) (/= 177) (/> 178) (/? 179) (/@ 180) (/^ 181) (/_ 182) (/~ 183) (|9 184) (ca 185) (CA 186) (|! 187) (|$ 188) (|% 189) (|& 190) (|* 191) (|+ 192) (|- 193) (|. 194) (|/ 195) (cc 196) (|< 197) (|= 198) (|> 199) (|? 200) (|@ 201) (|^ 202) (|_ 203) (|~ 204) (<9 205) ( 220) ( 241) (=? 242) (=@ 243) (=^ 244) (=_ 245) (=~ 246) (>9 247) (>a 248) (>A 249) (>! 250) (>$ 251) (>% 252) (>& 253) (>* 254) (>+ 255) (>- 256) (>. 257) (>/ 258) (>| 259) (>< 260) (>> 262) (>? 263) (>@ 264) (>^ 265) (>_ 266) (>~ 267) (?9 268) (?a 269) (?A 270) (?! 271) (?$ 272) (?% 273) (?& 274) (?* 275) (?+ 276) (?- 277) (?. 278) (?/ 279) (?| 280) (?< 281) (?= 282) (?> 283) (?? 284) (?@ 285) (?^ 286) (?_ 287) (?~ 288) (^9 289) (^a 290) (^A 291) (^! 292) (^$ 293) (^% 294) (^& 295) (^* 296) (^+ 297) (^- 298) (^. 299) (^/ 300) (^| 301) (^< 302) (^= 303) (^> 304) (^? 305) (^@ 306) (^^ 307) (^_ 308) (^~ 309) (_9 310) (_a 311) (_A 312) (_! 313) (_$ 314) (_% 315) (_& 316) (_* 317) (_+ 318) (_- 319) (_. 320) (_/ 321) (_| 322) (_< 323) (_= 324) (_> 325) (_? 326) (_@ 327) (_^ 328) (__ 329) (_~ 330) (~9 331) (~a 332) (~A 333) (~! 334) (~$ 335) (~% 336) (~& 337) (~* 338) (~+ 339) (~- 340) (~. 341) (~/ 342) (~| 343) (~< 344) (~= 345) (~> 346) (~? 347) (~@ 348) (~^ 349) (~_ 350) (~~ 351) ) (+ a A ! $ % & | ? ^ _ ~ a9 aa aA a! a$ a% a& a* a+ a- a. a/ a| a< a= a> a? a@ a^ a_ a~ A9 Aa AA A! A$ A% A& A* A+ A- A. A/ A| A< A= A> A? A@ A^ A_ A~ !9 !a !A !! !$ !% !& !* !+ !- !. !/ !| !< != !> !? !@ !^ !_ !~ $9 $a $A $! $$ $% $& $* $+ $- $. $/ $| $< $= $> $? $@ $^ $_ $~ %9 %a %A %! %$ %% %& %* %+ %- %. %/ %| %< %= %> %? %@ %^ %_ %~ &9 &a &A &! &$ &% && &* &+ &- &. &/ &| &< &= &> &? &@ &^ &_ &~ *9 *a *A *! *$ *% *& ** *+ *- *. */ *| *< *= *> *? *@ *^ *_ *~ /9 /a /A /! /$ /% /& /* /+ /- /. // /| /< /= /> /? /@ /^ /_ /~ |9 ca CA |! |$ |% |& |* |+ |- |. |/ cc |< |= |> |? |@ |^ |_ |~ <9 =? =@ =^ =_ =~ >9 >a >A >! >$ >% >& >* >+ >- >. >/ >| >< >> >? >@ >^ >_ >~ ?9 ?a ?A ?! ?$ ?% ?& ?* ?+ ?- ?. ?/ ?| ?< ?= ?> ?? ?@ ?^ ?_ ?~ ^9 ^a ^A ^! ^$ ^% ^& ^* ^+ ^- ^. ^/ ^| ^< ^= ^> ^? ^@ ^^ ^_ ^~ _9 _a _A _! _$ _% _& _* _+ _- _. _/ _| _< _= _> _? _@ _^ __ _~ ~9 ~a ~A ~! ~$ ~% ~& ~* ~+ ~- ~. ~/ ~| ~< ~= ~> ~? ~@ ~^ ~_ ~~ )) 61253) (test (let ()(+ (let ((x 0) (y 1) (z 2) )(+ x y (let ((x 3) )(+ x (let ()(+ (let () (+ (let ((x 0) (y 1) (z 2) )(+ x y z (let ((x 3) )(+ x (let ((x 4) (y 5) (z 6) ) (+ x y z (let ()(+ (let ((x 7) )(+ x (let ()(+ (let ((x 8) (y 9) ) (+ x (let ((x 10) (y 11) (z 12) )(+ x )))))))))))))))))))))))))) 50) (test (let* ((x 0) (y x) )(+ x y (let ()(+ (let ((x 2) )(+ x (let ()(+ (let ((x 4) ) (+ x (let ((x 5) )(+ x (let ((x 6) (y x) (z y) )(+ x (let ((x 7) (y x) ) (+ x (let ((x 8) (y x) )(+ x y (let ((x 9) (y x) (z y) )(+ x )))))))))))))))))))) 48) (test (let* ((x 0) (y x) )(+ x y (let* ()(+ (let* ((x 2) )(+ x (let* ()(+ (let* ((x 4) ) (+ x (let* ((x 5) )(+ x (let* ((x 6) (y x) (z y) )(+ x (let* ((x 7) (y x) ) (+ x (let* ((x 8) (y x) )(+ x y (let* ((x 9) (y x) (z y) )(+ x )))))))))))))))))))) 49) (test (let ((!@$%^&*~|}{?><.,/`_-+=:! 1)) (+ !@$%^&*~|}{?><.,/`_-+=:! 1)) 2) (test (let ((:hi 1)) :hi) 'error) (test (let ((:hi: 1)) :hi:) 'error) (test (let ((hi: 1)) hi) 'error) (let ((1.0+2j (lambda (a) (+ a 1.0+2i)))) (num-test (1.0+2j 3+i) 4.0+3i)) (test (let ((*1.11* 3)) *1.11*) 3) (test (let func ((a 1) (b 2)) (set! b a) (if (> b 0) (func (- a 1) b)) b) 1) (test (let func ((a 1) (b 2)) (set! b a) (if (> b 0) (func (- a 1) b) b)) 0) (test (let loop ((numbers '(3 -2 1 6 -5)) (nonneg ()) (neg ())) (cond ((null? numbers) (list nonneg neg)) ((>= (car numbers) 0) (loop (cdr numbers) (cons (car numbers) nonneg) neg)) ((< (car numbers) 0) (loop (cdr numbers) nonneg (cons (car numbers) neg))))) '((6 1 3) (-5 -2))) (test (let ((b '(1 2 3))) (let* ((a b) (b (cons 0 a))) (let b ((a b)) (if (null? a) 'done (b (cdr a)))))) 'done) (test (let lp ((x 100)) (if (positive? x) (lp (- x 1)) x)) 0) (test (let func ((a 1) (b 2) (c 3)) (+ a b c (if (> a 1) (func (- a 1) (- b 1) (- c 1)) 0))) 6) (test (let func ((a 1) (b 2) (c 3)) (+ a b c (if (> a 1) (func (- a 1) (- b 1)) 0))) 6) ; these work only because we don't try to call func -- maybe they should anyway? (test (let func ((a 1) (b 2) (c 3)) (+ a b c (if (> a 1) (func (- a 1)) 0))) 6) (test (let func ((a 1) (b 2) (c 3)) (+ a b c (if (> a 1) (func) 0))) 6) (test (let func ((a 1) (b 2) (c 3)) (+ a b c (if (> a 0) (func (- a 1) (- b 1) (- c 1)) 0))) 9) (test (let func ((a 1) (b 2) (c 3)) (+ a b c (if (> a 0) (func (- a 1) (- b 1)) 0))) 'error) (test (let func () 1) 1) (test (let ((a 1)) (let func () (if (> a 1) (begin (set! a (- a 1)) (func)) 0))) 0) (test (let func1 ((a 1)) (+ (let func2 ((a 2)) a) a)) 3) (test (let func1 ((a 1)) (+ (if (> a 0) (func1 (- a 1)) (let func2 ((a 2)) (if (> a 0) (func2 (- a 1)) 0))) a)) 1) (test (let func ((a (let func ((a 1)) a))) a) 1) (test (let ((i 3)) (let func () (set! i (- i 1)) (if (> i 0) (func))) i) 0) (test (let func ((a 1)) (define (func a) 2) (func 1)) 2) (test (let func ((a 1)) (define func (lambda (a) (func a))) (if (> a 1) (func (- a 1)) 0)) 0) (test (let loop ((i 0)) (let loop ((i 0)) (if (< i 1) (loop (+ i 1)))) i) 0) (test (let ((j 123)) (define (f g) (set! j 0) (g 0)) (let loop ((i 1)) (if (> i 0) (f loop))) j) 0) (test (procedure? (let loop () loop)) #t) (test (let loop1 ((func 0)) (let loop2 ((i 0)) (if (not (procedure? func)) (loop1 loop2)) func)) 0) (test (let ((k 0)) (let ((x (let xyz ((i 0)) (set! k (+ k 1)) xyz))) (x 0)) k) 2) (test (let ((hi' 3) (a'b 2)) (+ hi' a'b)) 5) (test (let ((hi''' 3) (a'''b 2)) (+ hi''' a'''b)) 5) (test (let ((f (let func ((i 0)) (if (= i 0) func (if (> i 1) (+ i (func (- i 1))) 1))))) (map f '(1 2 3))) '(1 3 6)) (test (let ((x 0)) (let ((f (lambda (a) (+ a x)))) (map (let () (set! x (+ x 1)) f) '(1 2 3)))) '(2 3 4)) (test (let x ((x (lambda (y) y))) (x 2)) 2) (test (let () (define (f4) (let loop ((i 0)) (set! loop 3) loop)) (f4)) 3) (test (let () (define (f5) (let loop ((i 0)) (set! loop (lambda () 2)) (loop))) (f5)) 2) (test (let () (define (f6) (let loop ((i 0)) (define (loop) 2) (loop))) (f6)) 2) (let ((enter 0) (exit 0) (inner 0)) (define (j1) (set! enter (+ enter 1)) (let ((result (let hiho ((i 0)) (set! inner (+ inner 1)) (if (< i 3) hiho i)))) (set! exit (+ exit 1)) result)) (let ((j2 (j1))) (test (and (procedure? j2) (= enter 1) (= exit 1) (= inner 1)) #t) (let ((result (j2 1))) (test (and (procedure? result) (= enter 1) (= exit 1) (= inner 2)) #t) (set! result (j2 3)) (test (and (= result 3) (= enter 1) (= exit 1) (= inner 3)) #t)))) (let () (define (block-comment-test a b c) (+ a b c)) (let ((val (block-comment-test #| a comment |# 1 #| this is a |# #| another comment |# 2 #| this is b |# 3))) (test val 6))) (test (letrec* ((p (lambda (x) (+ 1 (q (- x 1))))) (q (lambda (y) (if (zero? y) 0 (+ 1 (p (- y 1)))))) (x (p 5)) (y x)) y) 5) (test (letrec ((p (lambda (x) (+ 1 (q (- x 1))))) (q (lambda (y) (if (zero? y) 0 (+ 1 (p (- y 1)))))) (x (p 5)) (y x)) y) 'error) (test (let* ((p (lambda (x) (+ 1 (q (- x 1))))) (q (lambda (y) (if (zero? y) 0 (+ 1 (p (- y 1)))))) (x (p 5)) (y x)) y) 'error) (test (let ((x 1) ((y 2))) x) 'error) (test (let ((x 1 2 3)) x) 'error) (test (let ((+ 1 2)) 2) 'error) (test (let* ((x 1 2)) x) 'error) (test (letrec ((x 1 2)) x) 'error) (test (letrec* ((x 1 2)) x) 'error) (test (let ((x 1 . 2)) x) 'error) (test (let ((x 1 , 2)) x) 'error) (test (let ((x . 1)) x) 'error) (test (let* ((x . 1)) x) 'error) (test (letrec ((x . 1)) x) 'error) (test (letrec* ((x . 1)) x) 'error) (test (let hi ()) 'error) (test (let* ((x -1) 2) 3) 'error) (test (let ((x -1) 2) 3) 'error) (test (letrec ((x -1) 2) 3) 'error) (test (let ((pi 3)) pi) 'error) (test (let* ((pi 3)) pi) 'error) (test (letrec ((pi 3)) pi) 'error) (test (let ((a 1) (a 2)) a) 'error) (test (letrec ((a 1) (a 2)) a) 'error) (test (letrec* ((a 1) (a 2)) a) 'error) (test (let* ((a 1) (a (+ a 1))) a) 2) ; ?? (test (let hiho ((a 3) (hiho 4)) a) 3) (test (let hiho ((hiho 4)) hiho) 4) ; guile=4 (test (let hiho ((hiho hiho)) hiho) 'error) ; guile sez error (test (let ((hiho 4) (hiho 5)) hiho) 'error) ; guile sez error (test (let hiho ((a (hiho 1))) a) 'error) ; guile sez error (test (let hiho ((hiho 3)) (hiho hiho)) 'error) ; guile sez error (test (let) 'error) (test (let*) 'error) (test (letrec) 'error) (test (let . 1) 'error) (test (let* (x)) 'error) (test (let (x) 1) 'error) (test (let ((x)) 3) 'error) (test (let ((x 1) y) x) 'error) (test (let* x ()) 'error) (test (let* ((1 2)) 3) 'error) (test (let () ) 'error) (test (let '() 3) 'error) (test (let* ((x 1))) 'error) (test (let ((x 1)) (letrec ((x 32) (y x)) (+ 1 y))) 'error) ; # seems reasonable if not the 1+ (test (let ((x 1)) (letrec ((y x) (x 32)) (+ 1 y))) 'error) (test (let ((x 1)) (letrec ((y x) (x 32)) 1)) 1) (test (let ((x 1)) (letrec ((y (let () (+ x 1))) (x 32)) (+ 1 y))) 'error) (test (let ((x 1)) (letrec ((y (let ((xx (+ x 1))) xx)) (x 32)) (+ 1 y))) 'error) (test (let ((x 32)) (letrec ((y (apply list `(* ,x 2))) (x 1)) y)) '(* # 2)) (test (letrec) 'error) (test (letrec*) 'error) (test (let ((x . 1)) x) 'error) (test (letrec* ((and #2D((1 2) (3 4)) 3/4))) 'error) (test (letrec* ((hi "" #\a))) 'error) (test (let #((a 1)) a) 'error) (test (let* #((a 1)) a) 'error) (test (letrec #((a 1)) a) 'error) (test (letrec* #((a 1)) a) 'error) ;; (let *((a 1)) a) -> 1 ; * is named let name? (test (letrec *((a 1)) a) 'error) (test (letrec* *((a 1)) a) 'error) (test (letrec* (((a 1) 2)) a) 'error) (test (letrec* (#(a 1) 2) a) 'error) (test (letrec* ((a a)) a) #) ; hmm -- guile says Variable used before given a value: a (test (let . (((a 1)) a)) 1) (test (let '((a 1)) a) 'error) (test (let (((x 1)) 2) 3) 'error) (test (let ((#f 1)) #f) 'error) (test (let (()) #f) 'error) (test (let (lambda () ) #f) 'error) (test (let ((f1 3) (f1 4)) f1) 'error) ; not sure about this ;; (let () (define (f1) 3) (define (f1) 4) (f1)) (test (let ((asdf (lambda (a) (if (> a 0) (asdf (- a 1)) 0)))) (asdf 3)) 'error) (test (let* ((asdf (lambda (a) (if (> a 0) (asdf (- a 1)) 0)))) (asdf 3)) 'error) (test (let (('a 3)) 1) 'error) (test (let ((#\a 3)) #\a) 'error) ;; (test (let ((#z1 2)) 1) 'error) (test (let ('a 3) 1) 'error) (test (let 'a 1) 'error) (test (let* func ((a 1)) a) 1) (test (letrec func ((a 1)) a) 'error) (test (letrec* func ((a 1)) a) 'error) (test (let ((1 3)) 3) 'error) (test (let ((#t 3)) 3) 'error) (test (let ((() 3)) 3) 'error) (test (let ((#\c 3)) 3) 'error) (test (let (("hi" 3)) 3) 'error) (test (let ((:hi 3)) 3) 'error) (test (let 1 ((i 0)) i) 'error) (test (let #f ((i 0)) i) 'error) (test (let "hi" ((i 0)) i) 'error) (test (let #\c ((i 0)) i) 'error) (test (let :hi ((i 0)) i) 'error) (test (let pi () #f) 'error) (test (let func ((a 1) . b) a) 'error) (test (let func a . b) 'error) (test (let let func ((a 1)) func) 'error) (test (let func 1 ((x 1)) x) 'error) (test (let func ((a 1) . b) (if (> a 0) (func (- a 1) 2 3) b)) 'error) (test (let func ((a . 1)) a) 'error) (test (let func (a . 1) a) 'error) (test (let ((a 1) . b) a) 'error) (test (let* ((a 1) . b) a) 'error) (test (let func ((a func) (i 1)) i) 'error) (test (let func ((i 0)) (if (< i 1) (func))) 'error) (test (let func (let ((i 0)) (if (< i 1) (begin (set! i (+ i 1)) (func))))) 'error) (test (let ((x 0)) (set! x (+ x 1)) (begin (define y 1)) (+ x y)) 2) (test (let loop loop) 'error) (test (let loop (loop)) 'error) (test (let loop ((i 0) (loop 1)) i) 0) ; this used to be an error, Guile also returns 0 (test (letrec ((cons 1 (quote ())) . #(1)) 1) 'error) (test (letrec ((a 1) . 2) 1) 'error) (test (let* ((a 1) (b . 2) . 1) (())) 'error) (test (let "" 1) 'error) (test (let "hi" 1) 'error) (test (let #(1) 1) 'error) (test (let __hi__ #t) 'error) (test (letrec (1 2) #t) 'error) (test (letrec* (1 2) #t) 'error) (test (let hi (()) 1) 'error) (test (let hi a 1) 'error) ;;; named let* (test (let* hi #t) 'error) (test (let* "hi" () #f) 'error) (test (let* hi ()) 'error) (test (let* pi () #f) 'error) (test (let* hi x 1) 'error) (test (let* hi (c) 1) 'error) (test (let* hi ((x . 1)) #f) 'error) ;(test (let* hi . a 1) 'error) -- reader error in this context (test (let* hi ((a 1) . b) a) 'error) (test (let* hi ((a 1) :key b) a) 'error) (test (let* hi ((a 1) :allow-other-keys) a) 'error) (test (let* hi (a b) a) 'error) (test (let* hi () 1) 1) (test (let* func ((i 1) (j 2)) (+ i j (if (> i 0) (func (- i 1)) 0))) 5) (test (let* func ((i 1) (j 2) (k (+ j 1))) (+ i j k (if (> i 0) (func (- i 1)) 0))) 11) (test (let* func ((i 1) (j 2) (k (+ j 1))) (+ i j k (let () (set! j -123) (if (> i 0) (func (- i 1)) 0)))) 11) (test (let* func1 ((a 1) (b 2)) (+ a b (let* func2 ((a -1) (b (- a 1))) (if (< a 0) (func2 (+ a 1)) b)))) 2) ; 2nd b is -1 -- this changed 8-Jan-14 (test (procedure? (let* func ((i 1) (j 2) (k (+ j 1))) func)) #t) (test (let* func ((a 1) (b 2)) (+ a b (if (> a 0) (func (- a 1) (- b 1)) 0))) 4) (test (let* func ((a 1) (b 2)) (+ a b)) 3) (test (let* func ((a (+ 1 2)) (b (+ a 2))) (+ a b)) 8) (test (let* func ((a 1) (b 2)) (+ a b (if (> a 0) (func (- a 1) :b (- b 1)) 0))) 4) (test (let* func ((a 1) (b 2)) (+ a b (if (> a 0) (func :a (- a 1) :b (- b 1)) 0))) 4) (test (let* func ((a 1) (b 2)) (+ a b (if (> a 0) (func :b (- b 1) :a (- a 1)) 0))) 4) (test (let* func ((a 1) (b 2)) (+ a b (if (> a 0) (func :a (- a 1)) 0))) 5) ;;; these ought to work, but see s7.c under EVAL: (it's a speed issue) ;(test (let let ((i 0)) (if (< i 3) (let (+ i 1)) i)) 3) ;(test (let () (define (if a) a) (if 1)) 1) ;(test (let begin ((i 0)) (if (< i 3) (begin (+ i 1)) i)) 3) ;;; from the scheme wiki ;;; http://community.schemewiki.org/?sieve-of-eratosthenes (let ((results '(2))) (define (primes n) (let ((pvector (make-vector (+ 1 n) #t))) ; if slot k then 2k+1 is a prime (let loop ((p 3) ; Maintains invariant p = 2j + 1 (q 4) ; Maintains invariant q = 2j + 2jj (j 1) (k ()) (vec pvector)) (letrec ((lp (lambda (p q j k vec) (loop (+ 2 p) (+ q (- (* 2 (+ 2 p)) 2)) (+ 1 j) k vec))) (eradicate (lambda (q p vec) (if (<= q n) (begin (vector-set! vec q #f) (eradicate (+ q p) p vec)) vec)))) (if (<= j n) (if (eq? #t (vector-ref vec j)) (begin (set! results (cons p results)) (lp p q j q (eradicate q p vec))) (lp p q j k vec)) (reverse results)))))) (test (primes 10) '(2 3 5 7 11 13 17 19))) (test (let ((gvar 32)) (define (hi1 a) (+ a gvar)) (let ((gvar 0)) (hi1 2))) 34) (test (let ((gvar 32)) (define-macro (hi2 b) `(* gvar ,b)) (define (hi1 a) (+ (hi2 a) gvar)) (let ((gvar 0)) (hi1 2))) 96) (test (let ((gvar 32)) (define-macro (hi2 b) `(* gvar ,b)) (define (hi1 a) (+ a gvar)) (let ((gvar 0)) (hi1 (hi2 2)))) 32) (test (let ((gvar 32)) (define-macro (hi2 b) `(* gvar ,b)) (define (hi1 a) (+ (a 2) gvar)) (let ((gvar 0)) (define (hi2 a) (* a 2)) (hi1 hi2))) 36) (test (let ((gvar 32)) (define-macro (hi2 b) `(* gvar ,b)) (define (hi1 a) (+ (a 2) gvar)) (let ((gvar 0) (hi2 (lambda (a) (hi2 a)))) (hi1 hi2))) 96) (test (let ((gvar 32)) (define-macro (hi2 b) `(* gvar ,b)) (define (hi1 a) (+ (a 2) gvar)) (let* ((gvar 0) (hi2 (lambda (a) (hi2 a)))) (hi1 hi2))) 32) (test (let () ((let ((gvar 32)) (define-macro (hi2 b) `(* gvar ,b)) (define (hi1 a) (+ (hi2 2) gvar)) hi1) 2)) 96) (test (let ((gvar 0)) ((let ((gvar 1)) (define-macro (hi2 b) `(+ gvar ,b)) (define (hi1 a) (let ((gvar 2)) (hi2 a))) hi1) 2)) 4) (test (let ((gvar 0)) (define-macro (hi2 b) `(+ gvar ,b)) ((let ((gvar 1)) (define (hi1 a) (let ((gvar 2)) (a 2))) hi1) hi2)) 4) (test (let ((gvar 0)) (define-macro (hi2 b) `(+ gvar ,b)) ((let ((gvar 1)) (define (hi1 a) (a 2)) hi1) hi2)) 3) (test (let () (define-macro (hi2 b) `(+ gvar ,b)) ((let ((gvar 1)) (define (hi1 a) (a 2)) hi1) hi2)) 3) (test (let ((y 1) (x (let ((y 2) (x (let ((y 3) (x 4)) (+ x y)))) (+ x y)))) (+ x y)) 10) (test (let ((x 0)) (+ (let ((x 1) (y (+ x 1))) (+ (let ((x 2) (y (+ x 1))) (+ (let ((x 3) (y (+ x 1))) (+ (let ((x 4) (y (+ x 1))) (+ (let ((x 5) (y (+ x 1))) (+ (let ((x 6) (y (+ x 1))) (+ (let ((x 7) (y (+ x 1))) (+ x y)) x)) x)) x)) x)) x)) x)) x)) 35) (test (let loop ((lst (list 1 2)) (i 0) (sum 0)) (if (or (null? lst) (> i 10)) sum (begin (set-cdr! (cdr lst) lst) (loop (cdr lst) (+ i 1) (+ sum (car lst)))))) 16) ;;; these are confusing: ;(letrec ((if 0.0)) ((lambda () (if #t "hi")))) -> "hi" ;(let ((let 0)) let) -> 0 ;(let* ((lambda 0)) ((lambda () 1.5))) -> 1.5 ; syntax error in Guile ;(let* ((lambda 0)) lambda) -> 0 ;; from test-submodel.scm, from MIT I think (test (letrec ((factorial (lambda (n) (if (<= n 0) 1 (* n (factorial (- n 1))))))) (factorial 3)) 6) (test (letrec ((iter-fact (lambda (n) (letrec ((helper (lambda (n p) (if (<= n 0) p (helper (- n 1) (* n p)))))) (helper n 1))))) (iter-fact 3)) 6) (test (letrec ((y-factorial (lambda (n) (letrec ((y (lambda (f) ((lambda (x) (f (lambda (z) ((x x) z)))) (lambda (x) (f (lambda (z) ((x x) z))))))) (fact-def (lambda (fact) (lambda (n) (if (<= n 0) 1 (* n (fact (- n 1)))))))) ((y fact-def) n))))) (y-factorial 3)) 6) (test (let ((x 1)) (let ((x 0) (y x)) (cons x y))) '(0 . 1)) (test (let ((x 1)) (let* ((x 0) (y x)) (cons x y))) '(0 . 0)) (test (let ((x 1)) (letrec ((x 0) (y x)) (cons x y))) '(0 . #)) (test (let ((x 1)) (letrec* ((x 0) (y x)) (cons x y))) '(0 . 0)) (test (let ((x 1)) (let ((x 0) (y (let () (set! x 2) x))) (cons x y))) '(0 . 2)) (test (let ((x 1)) (letrec ((x 0) (y (let () (set! x 2) x))) (cons x y))) '(0 . 2)) (test (let ((x 1)) (let* ((x 0) (y (let () (set! x 2) x))) (cons x y))) '(2 . 2)) (test (let ((x 1)) (letrec* ((x 0) (y (let () (set! x 2) x))) (cons x y))) '(2 . 2)) (test (letrec ((x x)) x) #) ; weird (test (letrec ((x y) (y x)) x) #) (test (procedure? (letrec ((x (lambda () x))) x)) #t) (test (procedure? (letrec ((x (lambda () x))) (x))) #t) (test (letrec ((x (lambda () x))) (equal? x (x))) #t) ; ! (test (letrec ((x (lambda () x))) (equal? x ((x)))) #t) ; ! (test (letrec* ()) 'error) (test (letrec* ((x 1 x)) x) 'error) (test (letrec* ((x x)) x) #) ;?? (test (let ((x 1)) (letrec* ((x x)) x)) #) (test (letrec ((x x)) x) #) (test (let ((x 1)) (letrec ((x x)) x)) #) ;; here they are different: (test (let ((x 1)) (letrec* ((x 0) (y x)) y)) 0) (test (let ((x 1)) (letrec ((x 0) (y x)) y)) #) ;(test (letrec ((x (let () (set! y 1) y)) (y (let () (set! y (+ y 1)) y))) (list x y)) '(1 2)) ; ! this depends on letrec binding order (test (letrec ((x 1) (y x)) (list x y)) '(1 #)) ; guile says '(1 1) (test (letrec ((y x) (x 1)) (list x y)) '(1 #)) ; guile says '(1 1) (test (letrec ((x 1) (y (let () (set! x 2) x))) (list x y)) '(1 2)) (test (letrec ((history (list 9))) ((lambda (n) (begin (set! history (cons history n)) history)) 8)) '((9) . 8)) (test (((call/cc (lambda (k) k)) (lambda (x) x)) 'HEY!) 'HEY!) (let ((sequence ())) ((call-with-current-continuation (lambda (goto) (letrec ((start (lambda () (begin (set! sequence (cons 'start sequence)) (goto next)))) (froz (lambda () (begin (set! sequence (cons 'froz sequence)) (goto last)))) (next (lambda () (begin (set! sequence (cons 'next sequence)) (goto froz)))) (last (lambda () (begin (set! sequence (cons 'last sequence)) #f)))) start)))) (test (reverse sequence) '(start next froz last))) (let () (define thunk 'dummy-thunk) (define (make-fringe-thunk tree) (call-with-exit (lambda (return-to-repl) (cond ((pair? tree) (begin (make-fringe-thunk (car tree)) (make-fringe-thunk (cdr tree)))) ((null? tree) (begin (set! thunk (lambda () 'done)) 'null)) (else (call/cc (lambda (cc) (begin (set! thunk (lambda () (begin (display tree) (cc 'leaf)))) (return-to-repl 'thunk-set!))))))))) (define tr '(() () (((1 (( (() 2 (3 4)) (((5))) )) ))) )) (test (make-fringe-thunk tr) 'null) (test (thunk) 'done)) ;;; evaluation order matters, but in s7 it's always left -> right (test (let ((x 1)) (+ x (let () (define x 2) x))) 3) (test (let ((x 1)) (+ (begin (define x 2) x) x)) 4) (test (let ((x 1)) (+ x (begin (define x 2) x))) 3) (test (let ((x 1)) (+ x (begin (set! x 2) x))) 3) (test (let ((x 1)) (+ (begin (set! x 2) x) x)) 4) (test (let ((x 1)) ((if (= x 1) + -) x (begin (set! x 2) x))) 3) (let () (define-constant _letrec_x_ 32) (test (letrec ((_letrec_x_ 1)) _letrec_x_) 'error)) (let () (define-constant _let_x_ 32) (test (let ((_let_x_ 1)) _let_x_) 'error)) (let () (define-constant _let*_x_ 32) (test (let* ((_let*_x_ 1)) _let*_x_) 'error)) #| ;;; here is the old letrec* macro: (define-macro (letrec* bindings . body) (if (null? body) (error 'syntax-error "letrec* has no body") (if (not (list? bindings)) (error 'syntax-error "letrec* variables are messed up") `(let (,@(map (lambda (var&init) (list (car var&init) #)) bindings)) ,@(map (lambda (var&init) (if (not (null? (cddr var&init))) (error 'syntax-error "letrec* variable has more than one value")) (list 'set! (car var&init) (cadr var&init))) bindings) ,@body)))) |# ;;; -------------------------------------------------------------------------------- ;;; call/cc ;;; call-with-current-continuation ;;; -------------------------------------------------------------------------------- ;;; some of these were originally from Al Petrovsky, Scott G Miller, Matthias Radestock, J H Brown, Dorai Sitaram, ;;; and probably others. (let ((calls (make-vector 3 #f)) (travels (make-vector 5 0)) (ctr 0)) (set! (travels 0) (+ (travels 0) 1)) (call/cc (lambda (c0) (set! (calls 0) c0))) (set! (travels 1) (+ (travels 1) 1)) (call/cc (lambda (c1) (set! (calls 1) c1))) (set! (travels 2) (+ (travels 2) 1)) (call/cc (lambda (c2) (set! (calls 2) c2))) (set! (travels 3) (+ (travels 3) 1)) (let ((ctr1 ctr)) (set! ctr (+ ctr1 1)) (if (< ctr1 3) ((calls ctr1) ctr1))) (set! (travels 4) (+ (travels 4) 1)) (test travels #(1 2 3 4 1))) (let ((calls (make-vector 5 #f)) (travels (make-vector 5 0)) (ctr2 0)) (let loop ((ctr 0)) (if (< ctr 3) (begin (set! (travels ctr) (+ (travels ctr) 1)) (call/cc (lambda (c0) (set! (calls ctr) c0))) (loop (+ ctr 1))))) (set! (travels 3) (+ (travels 3) 1)) (let ((ctr1 ctr2)) (set! ctr2 (+ ctr1 1)) (if (< ctr1 3) ((calls ctr1) ctr1))) (set! (travels 4) (+ (travels 4) 1)) (test travels #(1 2 3 4 1))) (let ((c1 #f) (c2 #f) (c3 #f) (x0 0) (x1 0) (x2 0) (x3 0)) (let ((x (+ 1 (call/cc (lambda (r1) (set! c1 r1) (r1 2))) (call/cc (lambda (r2) (set! c2 r2) (r2 3))) (call/cc (lambda (r3) (set! c3 r3) (r3 4))) 5))) (if (= x0 0) (set! x0 x) (if (= x1 0) (set! x1 x) (if (= x2 0) (set! x2 x) (if (= x3 0) (set! x3 x))))) (if (= x 15) (c1 6)) (if (= x 19) (c2 7)) (if (= x 23) (c3 8)) (test (list x x0 x1 x2 x3) '(27 15 19 23 27)))) (let ((c1 #f) (c2 #f) (c3 #f) (x0 0) (x1 0) (x2 0) (x3 0) (y1 0) (z0 0) (z1 0) (z2 0) (z3 0)) (let* ((y 101) (x (+ y (call/cc (lambda (r1) (set! c1 r1) (r1 2))) (call/cc (lambda (r2) (set! c2 r2) (r2 3))) (call/cc (lambda (r3) (set! c3 r3) (r3 4))) 5)) (z (+ x y))) (set! y1 y) (if (= x0 0) (begin (set! x0 x) (set! z0 z)) (if (= x1 0) (begin (set! x1 x) (set! z1 z)) (if (= x2 0) (begin (set! x2 x) (set! z2 z)) (if (= x3 0) (begin (set! x3 x) (set! z3 z)))))) (if (= x 115) (c1 6)) (if (= x 119) (c2 7)) (if (= x 123) (c3 8)) (test (list x x0 x1 x2 x3 y1 z0 z1 z2 z3) '(127 115 119 123 127 101 216 220 224 228)))) (let ((c1 #f) (c2 #f) (c3 #f) (x0 0) (x1 0) (x2 0) (x3 0)) (let ((x (+ 1 (call/cc (lambda (r1) (set! c1 r1) (r1 2))) (call/cc (lambda (r2) (set! c2 r2) (r2 3))) (call/cc (lambda (r3) (set! c3 r3) (r3 4))) 5))) (if (= x0 0) (set! x0 x) (if (= x1 0) (set! x1 x) (if (= x2 0) (set! x2 x) (if (= x3 0) (set! x3 x))))) (if (= x 15) (c1 6 1)) (if (= x 20) (c2 7 2 3)) (if (= x 29) (c3 8 3 4 5)) (test (list x x0 x1 x2 x3) '(45 15 20 29 45)))) ;; 45 = (+ 1 6 1 7 2 3 8 3 4 5 5) (let ((x 0) (c1 #f) (results ())) (set! x (call/cc (lambda (r1) (set! c1 r1) (r1 2)))) (set! results (cons x results)) (if (= x 2) (c1 32)) (test results '(32 2))) (let ((x #(0)) (y #(0)) (c1 #f)) (set! ((call/cc (lambda (r1) (set! c1 r1) (r1 x))) 0) 32) (if (= (y 0) 0) (c1 y)) (test (and (equal? x #(32)) (equal? y #(32))) #t)) (test (call/cc (lambda (k) ((call/cc (lambda (top) (k (+ 1 (call/cc (lambda (inner) (top inner))))))) 2))) 3) (let* ((next-leaf-generator (lambda (obj eot) (letrec ((return #f) (cont (lambda (x) (recur obj) (set! cont (lambda (x) (return eot))) (cont #f))) (recur (lambda (obj) (if (pair? obj) (for-each recur obj) (call-with-current-continuation (lambda (c) (set! cont c) (return obj))))))) (lambda () (call-with-current-continuation (lambda (ret) (set! return ret) (cont #f))))))) (leaf-eq? (lambda (x y) (let* ((eot (list 'eot)) (xf (next-leaf-generator x eot)) (yf (next-leaf-generator y eot))) (letrec ((loop (lambda (x y) (cond ((not (eq? x y)) #f) ((eq? eot x) #t) (else (loop (xf) (yf))))))) (loop (xf) (yf))))))) (test (leaf-eq? '(a (b (c))) '((a) b c)) #t) (test (leaf-eq? '(a (b (c))) '((a) b c d)) #f)) (test (let ((r #f) (a #f) (b #f) (c #f) (i 0)) (let () (set! r (+ 1 (+ 2 (+ 3 (call/cc (lambda (k) (set! a k) 4)))) (+ 5 (+ 6 (call/cc (lambda (k) (set! b k) 7)))))) (if (not c) (set! c a)) (set! i (+ i 1)) (case i ((1) (a 5)) ((2) (b 8)) ((3) (a 6)) ((4) (c 4))) r)) 28) (test (let ((r #f) (a #f) (b #f) (c #f) (i 0)) (let () (set! r (+ 1 (+ 2 (+ 3 (call/cc (lambda (k) (set! a k) 4)))) (+ 5 (+ 6 (call/cc (lambda (k) (set! b k) 7)))))) (if (not c) (set! c a)) (set! i (+ i 1)) (case i ((1) (b 8)) ((2) (a 5)) ((3) (b 7)) ((4) (c 4))) r)) 28) (test (let ((k1 #f) (k2 #f) (k3 #f) (state 0)) (define (identity x) x) (define (fn) ((identity (if (= state 0) (call/cc (lambda (k) (set! k1 k) +)) +)) (identity (if (= state 0) (call/cc (lambda (k) (set! k2 k) 1)) 1)) (identity (if (= state 0) (call/cc (lambda (k) (set! k3 k) 2)) 2)))) (define (check states) (set! state 0) (let* ((res ()) (r (fn))) (set! res (cons r res)) (if (null? states) res (begin (set! state (car states)) (set! states (cdr states)) (case state ((1) (k3 4)) ((2) (k2 2)) ((3) (k1 -))))))) (map check '((1 2 3) (1 3 2) (2 1 3) (2 3 1) (3 1 2) (3 2 1)))) '((-1 4 5 3) (4 -1 5 3) (-1 5 4 3) (5 -1 4 3) (4 5 -1 3) (5 4 -1 3))) (let () ; Matt Might perhaps or maybe Paul Hollingsworth? (define (current-continuation) (call/cc (lambda (cc) (cc cc)))) (define fail-stack ()) (define (fail) (if (not (pair? fail-stack)) (error "back-tracking stack exhausted!") (begin (let ((back-track-point (car fail-stack))) (set! fail-stack (cdr fail-stack)) (back-track-point back-track-point))))) (define (amb choices) (let ((cc (current-continuation))) (cond ((null? choices) (fail)) ((pair? choices) (let ((choice (car choices))) (set! choices (cdr choices)) (set! fail-stack (cons cc fail-stack)) choice))))) (define (assert condition) (if (not condition) (fail) #t)) (let ((a (amb (list 1 2 3 4 5 6 7))) (b (amb (list 1 2 3 4 5 6 7))) (c (amb (list 1 2 3 4 5 6 7)))) (assert (= (* c c) (+ (* a a) (* b b)))) (assert (< b a)) (test (list a b c) (list 4 3 5)))) (let () ; a shorter version (define (current-continuation) (call/cc (lambda (cc) cc))) (define fail-stack ()) (define (fail) (if (not (pair? fail-stack)) (error "back-tracking stack exhausted!") (let ((back-track-point (car fail-stack))) (set! fail-stack (cdr fail-stack)) (back-track-point back-track-point)))) (define (amb choices) (let ((cc (current-continuation))) (if (null? choices) (fail) (let ((choice (car choices))) (set! choices (cdr choices)) (set! fail-stack (cons cc fail-stack)) choice)))) (define (assert condition) (or condition (fail))) (let ((a (amb (list 1 2 3 4 5 6 7))) (b (amb (list 1 2 3 4 5 6 7))) (c (amb (list 1 2 3 4 5 6 7)))) (assert (= (* c c) (+ (* a a) (* b b)))) (assert (< b a)) (test (list a b c) (list 4 3 5)))) (let ((c1 #f)) (let ((x ((call/cc (lambda (r1) (set! c1 r1) (r1 "hiho"))) 0))) (if (char=? x #\h) (c1 "asdf")) (test x #\a))) (test (let ((x ()) (y 0)) (call/cc (lambda (escape) (let* ((yin ((lambda (foo) (set! x (cons y x)) (if (= y 10) (escape x) (begin (set! y 0) foo))) (call/cc (lambda (bar) bar)))) (yang ((lambda (foo) (set! y (+ y 1)) foo) (call/cc (lambda (baz) baz))))) (yin yang))))) '(10 9 8 7 6 5 4 3 2 1 0)) (let () ;; taken from wikipedia (define readyList ()) (define (i-run) (if (not (null? readyList)) (let ((cont (car readyList))) (set! readyList (cdr readyList)) (cont ())))) (define (fork fn arg) (set! readyList (append readyList (cons (lambda (x) (fn arg) (i-run)) ())))) (define (yield) (call-with-current-continuation (lambda (thisCont) (set! readyList (append readyList (cons thisCont ()))) (let ((cont (car readyList))) (set! readyList (cdr readyList)) (cont ()))))) (define data (make-vector 10 0)) (define data-loc 0) (define (process arg) (if (< data-loc 10) (begin (set! (data data-loc) arg) (set! data-loc (+ data-loc 1)) (yield) (process (+ arg 1))) (i-run))) (fork process 0) (fork process 10) (fork process 20) (i-run) (test data #(0 10 20 1 11 21 2 12 22 3))) (test (let ((c #f)) (let ((r ())) (let ((w (let ((v 1)) (set! v (+ (call-with-current-continuation (lambda (c0) (set! c c0) v)) v)) (set! r (cons v r)) v))) (if (<= w 1024) (c w) r)))) '(2048 1024 512 256 128 64 32 16 8 4 2)) (test (let ((c #f)) (let ((r ())) (let ((w (let ((v 1)) (set! v (+ (values v (call-with-current-continuation (lambda (c0) (set! c c0) v))) v)) (set! r (cons v r)) v))) (if (<= w 1024) (c w) r)))) '(2047 1023 511 255 127 63 31 15 7 3)) ;;; the 1st v is 1, the 3rd reflects the previous call/cc which reflects the ;;; env+slot that had the subsequent set! -- weird. (test (let ((cc #f) (r ())) (let ((s (list 1 2 3 4 (call/cc (lambda (c) (set! cc c) 5)) 6 7 8))) (if (null? r) (begin (set! r s) (cc -1)) (list r s)))) '((1 2 3 4 5 6 7 8) (1 2 3 4 -1 6 7 8))) (test (let ((count 0)) (let ((first-time? #t) (k (call/cc values))) (if first-time? (begin (set! first-time? #f) (set! count (+ count 1)) (k values)) (void))) ; what is this? count) 2) (let ((c #f) (vals ())) (let ((val (+ 1 2 (call/cc (lambda (r) (set! c r) (r 3)))))) (set! vals (cons val vals)) (if (< val 20) (c (+ val 1))) (test vals '(22 18 14 10 6)))) (let ((c #f) (vals ())) (let ((val (+ 1 2 (call/cc (lambda (r) (set! c r) (r 3)))))) (set! vals (cons val vals)) (if (< val 20) (apply c vals)) (test vals '(36 18 9 6)))) (let ((c #f) (vals ())) (let ((val (+ 1 2 (call/cc (lambda (r) (set! c r) (r 3)))))) (set! vals (cons val vals)) (if (< val 20) (c (apply values vals))) (test vals '(36 18 9 6)))) (test (procedure? (call/cc call/cc)) #t) (test (call/cc (lambda (c) (0 (c 1)))) 1) (test (call/cc (lambda (k) (k "foo"))) "foo") (test (call/cc (lambda (k) "foo")) "foo") (test (call/cc (lambda (k) (k "foo") "oops")) "foo") (test (call/cc (lambda (return) (catch #t (lambda () (error 'hi "")) (lambda args (return "oops"))))) "oops") (test (call/cc (lambda (return) (catch #t (lambda () (return 1)) (lambda args (return "oops"))))) 1) (test (catch #t (lambda () (call/cc (lambda (return) (return "oops")))) (lambda arg 1)) "oops") (test (call/cc (if (< 2 1) (lambda (return) (return 1)) (lambda (return) (return 2) 3))) 2) (test (call/cc (let ((a 1)) (lambda (return) (set! a (+ a 1)) (return a)))) 2) (test (call/cc (lambda (return) (let ((hi return)) (hi 2) 3))) 2) (test (let () (define (hi) (call/cc func)) (define (func a) (a 1)) (hi)) 1) (test (((call/cc (call/cc call/cc)) call/cc) (lambda (a) 1)) 1) (test (+ 1 (eval-string "(+ 2 (call-with-exit (lambda (return) (return 3))) 4)") 5) 15) (test (+ 1 (eval '(+ 2 (call-with-exit (lambda (return) (return 3))) 4)) 5) 15) (test (call-with-exit) 'error) (test (call-with-exit s7-version s7-version) 'error) (test (call/cc) 'error) (test (call/cc s7-version s7-version) 'error) (test (call/cc (lambda () 1)) 'error) (test (call/cc (lambda (a b) (a 1))) 'error) (test (+ 1 (call/cc (lambda (k) (k #\a)))) 'error) (test (+ 1 (call-with-exit (lambda (k) (k #\a)))) 'error) (test ((call/cc (lambda (return) (call/cc (lambda (cont) (return cont))) list)) 1) '(1)) ; from Guile mailing list -- this strikes me as very strange (test (call/cc begin) 'error) (test (call/cc quote) 'error) (let ((p1 (dilambda (lambda (k) (k 3)) (lambda (k a) (k a))))) (test (call/cc p1) 3) (test (call-with-exit p1) 3)) ;;; guile/s7 accept: (call/cc (lambda (a . b) (a 1))) -> 1 ;;; same: (call/cc (lambda arg ((car arg) 1))) -> 1 (test (let ((listindex (lambda (e l) (call/cc (lambda (not_found) (letrec ((loop (lambda (l) (cond ((null? l) (not_found #f)) ((equal? e (car l)) 0) (else (+ 1 (loop (cdr l)))))))) (loop l))))))) (listindex 1 '(0 3 2 4 8))) #f) (test (let ((product (lambda (li) (call/cc (lambda (return) (let loop ((l li)) (cond ((null? l) 1) ((= (car l) 0) (return 0)) (else (* (car l) (loop (cdr l))))))))))) (product '(1 2 3 0 4 5 6))) 0) (test (let ((lst ())) ((call/cc (lambda (goto) (letrec ((start (lambda () (set! lst (cons "start" lst)) (goto next))) (next (lambda () (set! lst (cons "next" lst)) (goto last))) (last (lambda () (set! lst (cons "last" lst)) (reverse lst)))) start))))) '("start" "next" "last")) (test (let ((cont #f)) ; Al Petrovsky (letrec ((x (call-with-current-continuation (lambda (c) (set! cont c) 0))) (y (call-with-current-continuation (lambda (c) (set! cont c) 0)))) (if cont (let ((c cont)) (set! cont #f) (set! x 1) (set! y 1) (c 0)) (+ x y)))) 0) (test (letrec ((x (call-with-current-continuation (lambda (c) (list #t c))))) (if (car x) ((cadr x) (list #f (lambda () x))) (eq? x ((cadr x))))) #t) (test (call/cc (lambda (c) (0 (c 1)))) 1) (test (let ((member (lambda (x ls) (call/cc (lambda (return) (do ((ls ls (cdr ls))) ((null? ls) #f) (if (equal? x (car ls)) (return ls)))))))) (list (member 'd '(a b c)) (member 'b '(a b c)))) '(#f (b c))) ;;; call-with-exit (test (+ 2 (call/cc (lambda (k) (* 5 (k 4))))) 6) (test (+ 2 (call/cc (lambda (k) (* 5 (k 4 5 6))))) 17) (test (+ 2 (call/cc (lambda (k) (* 5 (k (values 4 5 6)))))) 17) (test (+ 2 (call/cc (lambda (k) (* 5 (k 1 (values 4 5 6)))))) 18) (test (+ 2 (call/cc (lambda (k) (* 5 (k 1 (values 4 5 6) 1))))) 19) (test (+ 2 (call-with-exit (lambda (k) (* 5 (k 4))))) 6) (test (+ 2 (call-with-exit (lambda (k) (* 5 (k 4 5 6))))) 17) (test (+ 2 (call-with-exit (lambda (k) (* 5 (k (values 4 5 6)))))) 17) (test (+ 2 (call-with-exit (lambda (k) (* 5 (k 1 (values 4 5 6)))))) 18) (test (+ 2 (call-with-exit (lambda (k) (* 5 (k 1 (values 4 5 6) 1))))) 19) (test (+ 2 (call-with-exit (lambda* ((hi 1)) (hi 1)))) 3) (test (call-with-exit (lambda (hi) (((hi 1)) #t))) 1) ; !! (jumps out of list evaluation) (test (call-with-exit (lambda* args ((car args) 1))) 1) (test ((call-with-exit (lambda (return) (return + 1 2 3)))) 6) (test ((call-with-exit (lambda (return) (apply return (list + 1 2 3))))) 6) (test ((call/cc (lambda (return) (return + 1 2 3)))) 6) (test (+ 2 (call-with-exit (lambda (return) (let ((rtn (copy return))) (* 5 (rtn 4)))))) 6) (test (let () (define (f1) (+ (call-with-exit (lambda (return) (define (f2) (+ 1 (return 2))) (f2))) 3)) (f1)) 5) (test (+ 2 (values 3 (call-with-exit (lambda (k1) (k1 4))) 5)) 14) (test (+ 2 (call-with-exit (lambda (k1) (values 3 (k1 4) 5))) 8) 14) (test (+ 2 (call-with-exit (lambda (k1) (values 3 (k1 4 -3) 5))) 8) 11) (test (call-with-exit (let () (lambda (k1) (k1 2)))) 2) (test (+ 2 (call/cc (let () (call/cc (lambda (k1) (k1 (lambda (k2) (k2 3)))))))) 5) (test (+ 2 (call/cc (call/cc (lambda (k1) (k1 (lambda (k2) (k2 3))))))) 5) (test (call-with-exit (lambda arg ((car arg) 32))) 32) (test (call-with-exit (lambda arg ((car arg) 32)) "oops!") 'error) (test (call-with-exit (lambda (a b) a)) 'error) (test (call-with-exit (lambda (return) (apply return '(3)))) 3) (test (call-with-exit (lambda (return) (apply return (list (cons 1 2))) (format-logged #t "; call-with-exit: we shouldn't be here!"))) (cons 1 2)) (test (call/cc (lambda (return) (apply return (list (cons 1 2))) (format-logged #t "; call/cc: we shouldn't be here!"))) (cons 1 2)) (test (procedure? (call-with-exit (lambda (return) (call-with-exit return)))) #t) (test (call-with-exit (lambda (return) #f) 1) 'error) (test (+ (call-with-exit ((lambda () (lambda (k) (k 1 2 3)))))) 6) (test (call-with-exit (lambda (a . b) (a 1))) 1) (test (call/cc (lambda (a . b) (a 1))) 1) (test (call-with-exit (lambda* (a b) (a 1))) 1) (test (call-with-exit (lambda (c) (0 (c 1)))) 1) (test (call-with-exit (lambda (k) (k "foo"))) "foo") (test (call-with-exit (lambda (k) "foo")) "foo") (test (call-with-exit (lambda (k) (k "foo") "oops")) "foo") (test (call-with-exit (lambda (x) (set! x abs) (x -1))) 1) (test (call/cc (lambda (x) (set! x abs) (x -1))) 1) (test (let ((memb (lambda (x ls) (call-with-exit (lambda (break) (do ((ls ls (cdr ls))) ((null? ls) #f) (if (equal? x (car ls)) (break ls)))))))) (list (memb 'd '(a b c)) (memb 'b '(a b c)))) '(#f (b c))) (let* ((sum 0) (val1 (call-with-exit (lambda (return) (set! sum (+ sum 1)) (let ((val2 (call-with-exit (lambda (return) (set! sum (+ sum 1)) (if #t (return sum)) 123)))) (set! sum (+ sum val2)) (return sum) 32))))) (test (list val1 sum) '(4 4))) (let () (define c #f) (define (yow f) (call-with-exit (lambda (return) (set! c return) (f)))) (test (yow (lambda () (c 32))) 32)) (let ((x 1)) (define y (call-with-exit (lambda (return) (set! x (return 32))))) (test (and (= x 1) (= y 32)) #t) (set! y (call-with-exit (lambda (return) ((lambda (a b c) (set! x a)) 1 2 (return 33))))) (test (and (= x 1) (= y 33)) #t) (set! y (call-with-exit (lambda (return) ((lambda (a b) (return a) (set! x b)) 2 3)))) (test (and (= x 1) (= y 2)) #t)) (test (let ((x 0)) (define (quit z1) (z1 1) (set! x 1)) (call-with-exit (lambda (z) (set! x 2) (quit z) (set! x 3))) x) 2) (test (let ((x (call/cc (lambda (k) k)))) (x (lambda (y) "hi"))) "hi") (test (((call/cc (lambda (k) k)) (lambda (x) x)) "hi") "hi") (test (let ((return #f) (lst ())) (let ((val (+ 1 (call/cc (lambda (cont) (set! return cont) 1))))) (set! lst (cons val lst))) (if (= (length lst) 1) (return 10) (if (= (length lst) 2) (return 20))) (reverse lst)) '(2 11 21)) (test (let ((r1 #f) (r2 #f) (lst ())) (define (somefunc x y) (+ (* 2 (expt x 2)) (* 3 y) 1)) (let ((val (somefunc (call/cc (lambda (c1) (set! r1 c1) (c1 1))) (call/cc (lambda (c2) (set! r2 c2) (c2 1)))))) (set! lst (cons val lst))) (if (= (length lst) 1) (r1 2) (if (= (length lst) 2) (r2 3))) (reverse lst)) '(6 12 18)) (let ((tree->generator (lambda (tree) (let ((caller '*)) (letrec ((generate-leaves (lambda () (let loop ((tree tree)) (cond ((null? tree) 'skip) ((pair? tree) (loop (car tree)) (loop (cdr tree))) (else (call/cc (lambda (rest-of-tree) (set! generate-leaves (lambda () (rest-of-tree 'resume))) (caller tree)))))) (caller ())))) (lambda () (call/cc (lambda (k) (set! caller k) (generate-leaves))))))))) (let ((same-fringe? (lambda (tree1 tree2) (let ((gen1 (tree->generator tree1)) (gen2 (tree->generator tree2))) (let loop () (let ((leaf1 (gen1)) (leaf2 (gen2))) (if (eqv? leaf1 leaf2) (if (null? leaf1) #t (loop)) #f))))))) (test (same-fringe? '(1 (2 3)) '((1 2) 3)) #t) (test (same-fringe? '(1 2 3) '(1 (3 2))) #f))) (let () (define (a-func) (call-with-exit (lambda (go) (lambda () (go + 32 1))))) (define (b-func) (call/cc (lambda (go) (lambda () (go + 32 1))))) (test ((a-func)) 'error) ;invalid-escape-function (test ((b-func)) 33)) (test ((call-with-exit (lambda (go) (lambda () (eval-string "(go + 32 1)"))))) 'error) ;;; (test ((call/cc (lambda (go) (lambda () (eval-string "(go + 32 1)"))))) 33) ;;; this is ok in the listener, but exits the load in this context (test ((call/cc (lambda (go-1) (call/cc (lambda (go) (lambda () (go (go-1 + 32 1)))))))) 33) (for-each (lambda (arg) (test (let ((ctr 0)) (let ((val (call/cc (lambda (exit) (do ((i 0 (+ i 1))) ((= i 10) 'gad) (set! ctr (+ ctr 1)) (if (= i 1) (exit arg))))))) (and (equal? val arg) (= ctr 2)))) #t)) (list "hi" -1 #\a 1 'a-symbol #(1 2 3) 3.14 3/4 1.0+1.0i #t (list 1 2 3) '(1 . 2))) (for-each (lambda (arg) (test (let ((ctr 0)) (let ((val (call/cc (lambda (exit) (do ((i 0 (+ i 1))) ((= i 10) arg) (set! ctr (+ ctr 1)) (if (= i 11) (exit 'gad))))))) (and (equal? val arg) (= ctr 10)))) #t)) (list "hi" -1 #\a 1 'a-symbol #(1 2 3) 3.14 3/4 1.0+1.0i #t (list 1 2 3) '(1 . 2))) (test (let ((c #f) (r (string-copy "testing-hiho"))) (let ((v (call/cc (lambda (c0) (set! c c0) (list #\a 0))))) (let ((chr (car v)) (index (cadr v))) (string-set! r index chr) (set! index (+ index 1)) (if (<= index 8) (c (list (integer->char (+ 1 (char->integer chr))) index)) r)))) "abcdefghiiho") (test (let ((x 0) (again #f)) (call/cc (lambda (r) (set! again r))) (set! x (+ x 1)) (if (< x 3) (again)) x) 3) (test (let* ((x 0) (again #f) (func (lambda (r) (set! again r)))) (call/cc func) (set! x (+ x 1)) (if (< x 3) (again)) x) 3) (test (let* ((x 0) (again #f)) (call/cc (let () (lambda (r) (set! again r)))) (set! x (+ x 1)) (if (< x 3) (again)) x) 3) (test (let ((x 0) (xx 0)) (let ((cont #f)) (call/cc (lambda (c) (set! xx x) (set! cont c))) (set! x (+ x 1)) (if (< x 3) (cont)) xx)) 0) (test (call/cc procedure?) #t) (test (procedure? (call/cc (lambda (a) a))) #t) (for-each (lambda (arg) (test (call/cc (lambda (a) arg)) arg)) (list "hi" -1 #\a 1 'a-symbol #(1 2 3) 3.14 3/4 1.0+1.0i #t (list 1 2 3) '(1 . 2))) (let ((a (call/cc (lambda (a) a)))) (test (eq? a a) #t) (test (eqv? a a) #t) (test (equal? a a) #t) (for-each (lambda (ques) (if (ques a) (format-logged #t ";(~A ~A) returned #t?~%" ques a))) question-ops)) (test (let ((conts (make-vector 4 #f))) (let ((lst ())) (set! lst (cons (+ (call/cc (lambda (a) (vector-set! conts 0 a) 0)) (call/cc (lambda (a) (vector-set! conts 1 a) 0)) (call/cc (lambda (a) (vector-set! conts 2 a) 0)) (call/cc (lambda (a) (vector-set! conts 3 a) 0))) lst)) (let ((len (length lst))) (if (< len 4) ((vector-ref conts (- len 1)) (+ len 1)) (reverse lst))))) '(0 2 5 9)) (test (let ((conts ())) (let ((lst ())) (set! lst (cons (+ (call/cc (lambda (a) (if (< (length conts) 4) (set! conts (cons a conts))) 1)) (* (call/cc (lambda (a) (if (< (length conts) 4) (set! conts (cons a conts))) 1)) (+ (call/cc (lambda (a) (if (< (length conts) 4) (set! conts (cons a conts))) 1)) (* (call/cc (lambda (a) (if (< (length conts) 4) (set! conts (cons a conts))) 1)) 2)))) lst)) (let ((len (length lst))) (if (<= len 4) ((list-ref conts (- len 1)) (+ len 1)) (reverse lst))))) ; (+ 1 (* 1 (+ 1 (* 1 2)))) to start ; (+ 1 ... 2 ) ; (+ 1 ... 3 [1] ) ; (+ 1 ...4 [1] ) ; (+ 5 [1] ) '(4 6 6 13 8)) (test (let ((conts (make-vector 4 #f))) (let ((lst ())) (set! lst (cons (+ (call/cc (lambda (a) (if (not (vector-ref conts 0)) (vector-set! conts 0 a)) 0)) (call/cc (lambda (a) (if (not (vector-ref conts 1)) (vector-set! conts 1 a)) 0)) (call/cc (lambda (a) (if (not (vector-ref conts 2)) (vector-set! conts 2 a)) 0)) (call/cc (lambda (a) (if (not (vector-ref conts 3)) (vector-set! conts 3 a)) 0))) lst)) (let ((len (length lst))) (if (< len 4) ((vector-ref conts (- len 1)) (+ len 1)) (reverse lst))))) '(0 2 3 4)) (test (let ((conts ())) (let ((lst ())) (set! lst (cons (+ (if (call/cc (lambda (a) (if (< (length conts) 4) (set! conts (cons a conts))) #f)) 1 0) (* (if (call/cc (lambda (a) (if (< (length conts) 4) (set! conts (cons a conts))) #f)) 2 1) (+ (if (call/cc (lambda (a) (if (< (length conts) 4) (set! conts (cons a conts))) #f)) 1 0) (* (if (call/cc (lambda (a) (if (< (length conts) 4) (set! conts (cons a conts))) #f)) 2 1) 2)))) lst)) (let ((len (length lst))) (if (<= len 4) ((list-ref conts (- len 1)) #t) (reverse lst))))) ; (+ 0 (* 1 (+ 0 (* 1 2)))) to start ; (+ 0 ... 2 ) ; (+ 0 ... 1 [1] ) ; (+ 0 ...2 [0] ) ; (+ 1 [1] ) '(2 4 3 4 3)) (test (let ((call/cc 2)) (+ call/cc 1)) 3) (test (+ 1 (call/cc (lambda (r) (r 2 3 4))) 5) 15) (test (string-ref (call/cc (lambda (s) (s "hiho" 1)))) #\i) (let ((r5rs-ratify (lambda (ux err) (if (= ux 0.0) 0 (let ((tt 1) (a1 0) (b2 0) (a2 1) (b1 1) (a 0) (b 0) (ctr 0) (x (/ 1 ux))) (call-with-current-continuation (lambda (return) (do () (#f) (set! a (+ (* a1 tt) a2)) (set! b (+ (* tt b1) b2)) ;(format-logged #t "~A ~A~%" a (- b a)) (if (or (<= (abs (- ux (/ a b))) err) (> ctr 1000)) (return (/ a b))) (set! ctr (+ 1 ctr)) (if (= x tt) (return)) (set! x (/ 1 (- x tt))) (set! tt (floor x)) (set! a2 a1) (set! b2 b1) (set! a1 a) (set! b1 b))))))))) (test (r5rs-ratify (/ (log 2.0) (log 3.0)) 1/10000000) 665/1054) (if (positive? 2147483648) (test (r5rs-ratify (/ (log 2.0) (log 3.0)) 1/100000000000) 190537/301994))) #| (let ((max-diff 0.0) (max-case 0.0) (err 0.01) (epsilon 1e-16)) (do ((i 1 (+ i 1))) ((= i 100)) (let ((x (/ i 100.))) (let ((vals (cr x err))) (if (not (= (car vals) (cadr vals))) (let ((r1 (car vals)) (r2 (cadr vals))) (let ((diff (abs (- r1 r2)))) (if (> diff max-diff) (begin (set! max-diff diff) (set! max-case x)))) (if (> (abs (- r1 x)) (+ err epsilon)) (format-logged #t "(rationalize ~A ~A) is off: ~A -> ~A~%" x err r1 (abs (- r1 x)))) (if (> (abs (- r2 x)) (+ err epsilon)) (format-logged #t "(ratify ~A ~A) is off: ~A -> ~A~%" x err r2 (abs (- r2 x)))) (if (< (denominator r2) (denominator r1)) (format-logged #t "(ratify ~A ~A) is simpler? ~A ~A~%" x err r1 r2))))))) (list max-case max-diff (cr max-case err))) |# (for-each (lambda (arg) (test (let ((ctr 0)) (let ((val (call/cc (lambda (exit) (for-each (lambda (a) (if (equal? a arg) (exit arg)) (set! ctr (+ ctr 1))) (list 0 1 2 3 arg 5)))))) (list ctr val))) (list 4 arg))) (list "hi" -1 #\a 11 'a-symbol #(1 2 3) 3.14 3/4 1.0+1.0i #f #t '(1 . 2))) (test (+ 2 (call/cc (lambda (rtn) (+ 1 (let () (begin (define x (+ 1 (rtn 3)))) x))))) 5) ;;; others from stackoverflow.com Paul Hollingsworth etc: (test (procedure? (call/cc (lambda (k) k))) #t) (test (call/cc (lambda (k) (+ 56 (k 3)))) 3) (test (apply (lambda (k i) (if (> i 5) i (k (list k (* 2 i))))) (call/cc (lambda (k) (list k 1)))) 8) (test (apply (lambda (k i n) (if (= i 0) n (k (list k (- i 1) (* i n))))) (call/cc (lambda (k) (list k 6 1)))) 720) (test (let* ((ka (call/cc (lambda (k) `(,k 1)))) (k (car ka)) (a (cadr ka))) (if (< a 5) (k `(,k ,(* 2 a))) a)) 8) (test (apply (lambda (k i n) (if (eq? i 0) n (k (list k (- i 1) (* i n))))) (call/cc (lambda (k) (list k 6 1)))) 720) (test ((call/cc (lambda (k) k)) (lambda (x) 5)) 5) (let () (define (generate-one-element-at-a-time a-list) (define (generator) (call/cc control-state)) (define (control-state return) (for-each (lambda (an-element-from-a-list) (set! return (call/cc (lambda (resume-here) (set! control-state resume-here) (return an-element-from-a-list))))) a-list) (return 'you-fell-off-the-end-of-the-list)) generator) (let ((gen (generate-one-element-at-a-time (list 3 2 1)))) (test (gen) 3) (test (gen) 2) (test (gen) 1) (test (gen) 'you-fell-off-the-end-of-the-list))) ;;; from Ferguson and Duego "call with current continuation patterns" (test (let () (define count-to-n (lambda (n) (let ((receiver (lambda (exit-procedure) (let ((count 0)) (letrec ((infinite-loop (lambda () (if (= count n) (exit-procedure count) (begin (set! count (+ count 1)) (infinite-loop)))))) (infinite-loop)))))) (call/cc receiver)))) (count-to-n 10)) 10) (test (let () (define product-list (lambda (nums) (let ((receiver (lambda (exit-on-zero) (letrec ((product (lambda (nums) (cond ((null? nums) 1) ((zero? (car nums)) (exit-on-zero 0)) (else (* (car nums) (product (cdr nums)))))))) (product nums))))) (call/cc receiver)))) (product-list '(1 2 3 0 4 5))) 0) (begin (define fact ((lambda (f) ((lambda (u) (u (lambda (x) (lambda (n) ((f (u x)) n))))) (call/cc (call/cc (call/cc (call/cc (call/cc (lambda (x) x)))))))) (lambda (f) (lambda (n) (if (<= n 0) 1 (* n (f (- n 1)))))))) (test (map fact '(5 6 7)) '(120 720 5040))) ;; http://okmij.org/ftp/Scheme/callcc-calc-page.html (test (let () (define product-list (lambda (nums) (let ((receiver (lambda (exit-on-zero) (letrec ((product (lambda (nums) (cond ((null? nums) 1) ((number? (car nums)) (if (zero? (car nums)) (exit-on-zero 0) (* (car nums) (product (cdr nums))))) (else (* (product (car nums)) (product (cdr nums)))))))) (product nums))))) (call/cc receiver)))) (product-list '(1 2 (3 4) ((5))))) 120) (test (call/cc (lambda () 0)) 'error) (test (call/cc (lambda (a) 0) 123) 'error) (test (call/cc (lambda (3) 9)) 'error) (test (call/cc (lambda arg 0)) 0) (test (call-with-exit (lambda arg 0)) 0) (test (call/cc) 'error) (test (call/cc abs) 'error) (for-each (lambda (arg) (test (call-with-exit arg) 'error) (test (call-with-current-continuation arg) 'error) (test (call/cc arg) 'error)) (list "hi" -1 () #(1 2) _ht_ _null_ _c_obj_ #\a 1 'a-symbol 3.14 3/4 1.0+1.0i #t (list 1 2 3) '(1 . 2))) (test (call/cc . 1) 'error) (test (call/cc abs) 'error) (test (+ 1 (call/cc (lambda (r1) (call/cc (lambda (r2) (r1 2 3))))) 4) 10) (test (+ 1 (call/cc (lambda (r1) (+ 5 (call/cc (lambda (r2) (r2 2 3)))))) 4) 15) ;;; from Andy Wingo's Guile blog (let () (define (test1 get) (let ((v (make-vector 2 #f))) (vector-set! v 0 (get 0)) (vector-set! v 1 (get 1)) v)) (define (test2 get) (let* ((a (get 0)) (b (get 1))) (vector a b))) (define (discriminate f) (let ((get-zero-cont #t) (first-result #f)) (define (get n) (if (zero? n) (call/cc (lambda (k) (set! get-zero-cont k)))) n) (let ((result (f get))) (cond (first-result (eq? result first-result)) (else (set! first-result result) (get-zero-cont)))))) (test (discriminate test1) #t) (test (discriminate test2) #f) (define (discriminate2 f) (let ((get-zero-cont #f) (escape #f)) (define (get n) (case n ((0) (call/cc (lambda (k) (set! get-zero-cont k) 0))) ((1) (if escape (escape) 1)))) (let ((result (f get))) (call/cc (lambda (k) (set! escape k) (get-zero-cont 42))) result))) (test (discriminate2 test1) #(42 1)) (test (discriminate2 test2) #(0 1))) #| ;;; from bug-guile (define k #f) (define result #f) (define results ()) (set! result (map (lambda (x) (if x x (call/cc (lambda (c) (set! k c) 1)))) '(#t #f))) (set! results (cons result results)) (write results) (newline) (if (< (cadr result) 5) (k (+ 1 (cadr result)))) (newline) the claim is that this should return ((#t 1)) ((#t 2) (#t 1)) ((#t 3) (#t 2) (#t 1)) ((#t 4) (#t 3) (#t 2) (#t 1)) ((#t 5) (#t 4) (#t 3) (#t 2) (#t 1)) but I think that depends on how we interpret the sequence of top-level statements. The test should be written: (let* ((k #f) (results ())) (let ((result (map (lambda (x) (if x x (call/cc (lambda (c) (set! k c) 1)))) '(#t #f)))) (set! results (cons result results)) (write results) (newline) (if (< (cadr result) 5) (k (+ 1 (cadr result)))) (newline))) and then s7 is not following r6rs because it stops at ((#t 1)) ((1 . #1=(#t 2)) #1#) saying cadr is not a number. I don't think this example is correct in any case -- who says the continuation has to restart the map from the top? |# (let ((cont #f)) (let ((x (* (call/cc (lambda (return) (set! cont return) (return 3 4)))))) (if (= x 12) (cont 5 6 7)) (test x 210))) ;; Guile handles this very differently (test (let ((cont #f)) (call-with-exit (lambda (return) (set! cont return))) (cont 1)) 'error) (test (let ((cont #f)) (call-with-exit (lambda (return) (set! cont return))) (apply cont)) 'error) (test (let ((cont #f)) (call-with-exit (lambda (return) (set! cont return) (cont 1))) (apply cont)) 'error) (test (let ((cont #f)) (call-with-exit (lambda (return) (set! cont return) (cont 1))) (cont 1)) 'error) (test (procedure? (call-with-exit append)) #t) (test (procedure? (call-with-exit values)) #t) (test (procedure? (car (call-with-exit list))) #t) (test (call-with-exit (call-with-exit append)) 'error) (test (continuation? (call/cc (call/cc append))) #t) (test (procedure? (call-with-exit call-with-exit)) #t) (test (vector? (call-with-exit vector)) #t) (test (call-with-exit ((lambda args procedure?))) #t) (test (call-with-exit (let ((x 3)) (define (return y) (y x)) return)) 3) (test (call-with-exit (lambda (return) (with-input-from-string "hi" return))) ()) ; because thunk? -- does it close the port? (test (call-with-exit (lambda (return) (call-with-input-string "hi" return))) 'error) (test (call-with-exit (lambda (return) (set! (procedure-setter return) abs))) 'error) (test (call-with-exit (lambda (return) (dynamic-wind return (lambda () 1) (lambda () (error "oops"))))) ()) (test (call-with-exit (lambda (return) (map return '(1 2 3)))) 1) (test (call-with-exit (lambda (return) (dynamic-wind (lambda () 2) (lambda () 1) return))) ()) ; ?? is this a bug? (test (call-with-exit (lambda (return) (dynamic-wind (lambda () 2) (lambda () 1) (lambda () (return 3))))) 3) ; I guess not (test (let ((c1 #f)) (call-with-exit (lambda (c2) (call-with-exit (lambda (c3) (set! c1 c3) (c2))))) (c1)) 'error) (test (let ((c1 #f)) (call/cc (lambda (c2) (call-with-exit (lambda (c3) (set! c1 c3) (c2))))) (c1)) 'error) (test (let ((cont #f)) (catch #t (lambda () (call-with-exit (lambda (return) (set! cont return) (error 'testing " a test")))) (lambda args 'error)) (apply cont)) 'error) (test (let ((cont #f)) (catch #t (lambda () (call-with-exit (lambda (return) (set! cont return) (error 'testing " a test")))) (lambda args 'error)) (cont 1)) 'error) (test (let ((e (call-with-exit (lambda (go) (lambda () (go 1)))))) (e)) 'error) (test (let ((cc #f) (doit #t) (ctr 0)) (let ((ok (call-with-exit (lambda (c3) (call/cc (lambda (ret) (set! cc ret))) (c3 (let ((res doit)) (set! ctr (+ ctr 1)) (set! doit #f) res)))))) (if ok (cc))) ctr) 2) (test (let ((val (call-with-exit (lambda (ret) (let ((ret1 ret)) (ret1 2) 3))))) val) 2) (test (call-with-exit (lambda (return) (sort! '(3 2 1) return))) 'error) ; "sort! argument 2, #, is a goto ..." ;;; this one from Rick (test (eval '(call/cc (lambda (go) (go 9) 0))) 9) (test (eval-string "(call/cc (lambda (go) (go 9) 0))") 9) (test (call-with-exit (lambda (return) (call/cc (lambda (go) (go 9) 0)) (return 1) 2)) 1) (num-test (/ 1 (call/cc (lambda (go) (go 9) 0))) 1/9) (test (call/cc (lambda (g) (call/cc (lambda (f) (f 1)) (g 2)))) 2) ; !! guile agrees! (evaluating the extraneous arg jumps) (test (call/cc (lambda (g) (abs -1 (g 2)))) 2) ; perhaps this should be an error (test (call/cc (lambda (g) (if #t #f #f (g 2)))) 'error) (test ((call-with-exit (lambda (go) (go go))) eval) 'error) (test ((call/cc (lambda (go) (go go))) eval) eval) (test (call-with-exit quasiquote) 'error) (test (call-with-exit (lambda (go) (if (go 1) (go 2) (go 3)))) 1) (test (call-with-exit (lambda (go) (set! (go 1) 2))) 'error) (test (call-with-exit (lambda (go) (let ((x 1) (y (go x))) #f))) 'error) (test (call-with-exit (lambda (go) (let* ((x 1) (y (go x))) #f))) 1) (test (call-with-exit (lambda (go) (letrec ((x 1) (y (go x))) #f))) #) (test (call-with-exit (lambda (go) (letrec* ((x 1) (y (go x))) #f))) 1) (test (call-with-exit (lambda (go) (case (go 1) ((go 2) 3) (else 4)))) 1) (test (call-with-exit (lambda (go) (case go ((go 2) 3) (else 4)))) 4) (test (call-with-exit (lambda (go) (case 2 ((go 2) 3) (else 4)))) 3) (test (call-with-exit (lambda (go) (eq? go go))) #t) (test (call-with-exit (lambda (go) (case 'go ((go 2) 3) (else 4)))) 3) (test (call-with-exit (lambda (go) (go (go (go 1))))) 1) (test (call-with-exit (lambda (go) (quasiquote (go 1)))) '(go 1)) ;; these tests were messed up -- I forgot the outer parens (test (call-with-exit (lambda (go) ((lambda* ((a (go 1))) a) (go 2) 3))) 2) (test (call-with-exit (lambda (go) ((lambda* ((a (go 1))) a)))) 1) (test (call-with-exit (lambda (go) ((lambda (go) go) 1))) 1) (test (call-with-exit (lambda (go) (quote (go 1)) 2)) 2) (test (call-with-exit (lambda (go) (and (go 1) #f))) 1) (test (call-with-exit (lambda (go) (dynamic-wind (lambda () (go 1) 11) (lambda () (go 2) 12) (lambda () (go 3) 13)))) 1) (test (eval '(call/cc (lambda (go) (if (go 1) (go 2) (go 3))))) 1) (test (eval '(call/cc (lambda (go) (set! (go 1) 2)))) 'error) (test (eval '(call/cc (lambda (go) (let ((x 1) (y (go x))) #f)))) 'error) (test (eval '(call/cc (lambda (go) (let* ((x 1) (y (go x))) #f)))) 1) (test (eval '(call/cc (lambda (go) (letrec ((x 1) (y (go x))) #f)))) #) (test (eval '(call/cc (lambda (go) (letrec* ((x 1) (y (go x))) #f)))) 1) (test (eval '(call/cc (lambda (go) (case (go 1) ((go 2) 3) (else 4))))) 1) (test (eval '(call/cc (lambda (go) (case go ((go 2) 3) (else 4))))) 4) (test (eval '(call/cc (lambda (go) (case 2 ((go 2) 3) (else 4))))) 3) (test (eval '(call/cc (lambda (go) (eq? go go)))) #t) (test (eval '(call/cc (lambda (go) (case 'go ((go 2) 3) (else 4))))) 3) (test (eval '(call/cc (lambda (go) (go (go (go 1)))))) 1) (test (eval '(call/cc (lambda (go) (quasiquote (go 1))))) '(go 1)) (test (eval '(call/cc (lambda (go) ((lambda* (a (go 1)) a) (go 2))))) 2) (test (eval '(call/cc (lambda (go) ((lambda* (a (go 1)) a) 2)))) 2) (test (eval '(call/cc (lambda (go) ((lambda* (a (go 1)) a))))) #f) (test (eval '(call/cc (lambda (go) ((lambda (go) go) 1)))) 1) (test (eval '(call/cc (lambda (go) (quote (go 1)) 2))) 2) (test (eval '(call/cc (lambda (go) (and (go 1) #f)))) 1) (test (eval '(call/cc (lambda (go) (dynamic-wind (lambda () (go 1) 11) (lambda () (go 2) 12) (lambda () (go 3) 13))))) 1) (test (call-with-exit (lambda (go) (eval '(go 1)) 2)) 1) (test (call-with-exit (lambda (go) (eval-string "(go 1)") 2)) 1) (test (call-with-exit (lambda (go) `(,(go 1) 2))) 1) ;;; (test (call-with-exit (lambda (go) `#(,(go 1) 2))) 'error) ; this is s7's choice -- read time #(...) (test (call-with-exit (lambda (go) (case 0 ((0) (go 1) (go 2))))) 1) (test (call-with-exit (lambda (go) (cond (1 => go)) 2)) 1) (test (call-with-exit (lambda (go) (((cond ((go 1) => go)) 2)))) 1) (test (call-with-exit (lambda (go) (cond (1 => (go 2))))) 2) (test (call-with-exit (lambda (go) (go (eval '(go 1))) 2)) 1) (test (+ 10 (call-with-exit (lambda (go) (go (eval '(go 1))) 2))) 11) (test (call-with-exit (lambda (go) (go (eval-string "(go 1)")) 2)) 1) (test (call-with-exit (lambda (go) (eval-string "(go 1)") 2)) 1) (test (call-with-exit (lambda (go) ((eval 'go) 1) 2)) 1) (test (eval-string "(call/cc (lambda (go) (if (go 1) (go 2) (go 3))))") 1) (test (call-with-exit (lambda (quit) ((lambda* ((a (quit 32))) a)))) 32) (test ((call-with-exit (lambda (go) (go quasiquote))) go) 'go) (test (let ((c #f)) (let ((val -1)) (set! val (call/cc (lambda (c1) (call-with-exit (lambda (c2) (call-with-exit (lambda (c3) (call/cc (lambda (c4) (set! c c4) (c1 (c2 0))))))))))) (if (= val 0) (c 5)) val)) 5) (let () (define-macro (while test . body) `(call-with-exit (lambda (break) (letrec ((continue (lambda () (if (let () ,test) (begin (let () ,@body) (continue)) (break))))) (continue))))) (test (let ((i 0) (sum 0) (break 32) (continue 48)) (while (begin (define break 10) (define continue 0) (< i (+ break continue))) (set! sum (+ sum 1)) (set! i (+ i 1)) (if (< i 5) (continue)) (set! sum (+ sum 10)) (if (> i 7) (break)) (set! sum (+ sum 100))) sum) 348)) ;;; (define-macro (while test . body) `(do () ((not ,test)) ,@body)) ? ;;; with-baffle (test (with-baffle) ()) ; ?? -- like begin I guess (test (with-baffle 0) 0) (test (+ 1 (with-baffle (values 2 3)) 4) 10) (test (with-baffle . 1) 'error) (test (with-baffle 1 2 . 3) 'error) (test (with-baffle (let ((x 0) (c1 #f) (results ())) (set! x (call/cc (lambda (r1) (set! c1 r1) (r1 2)))) (set! results (cons x results)) (if (= x 2) (c1 32)) results)) '(32 2)) (test (let ((x 0) (c1 #f) (results ())) (with-baffle (set! x (call/cc (lambda (r1) (set! c1 r1) (r1 2)))) (set! results (cons x results))) (if (= x 2) (c1 32)) results) 'error) (test (let ((what's-for-breakfast ()) (bad-dog 'fido)) ; bad-dog will try to sneak in (with-baffle ; the syntax is (with-baffle . body) (set! what's-for-breakfast (call/cc (lambda (biscuit?) (set! bad-dog biscuit?) ; bad-dog smells a biscuit! (biscuit? 'biscuit!))))) (if (eq? what's-for-breakfast 'biscuit!) (bad-dog 'biscuit!)) ; now, outside the baffled block, bad-dog tries to sneak back in results) ; but s7 says "No!": baffled! ("continuation can't jump across with-baffle") 'error) (test (+ (with-baffle (let ((c1 #f)) (call/cc (lambda (c2) (set! c1 c2) (c2 2))))) 1) 3) (test (+ (let ((c1 #f)) (with-baffle (call/cc (lambda (c2) (set! c1 c2) (c2 2)))) (c1 3)) 1) 'error) (test (let () (define (c3 a) (a 2)) (c3 (with-baffle (call/cc (lambda (c2) c2))))) 'error) (test (call-with-exit (lambda (return) (with-baffle (do () () (return 1))))) 1) (test (let () (define (hi) (null? (with-baffle))) (hi)) #t) ;;; -------------------------------------------------------------------------------- ;;; dynamic-wind ;;; -------------------------------------------------------------------------------- (test (let ((ctr1 0) (ctr2 0) (ctr3 0)) (let ((ctr4 (dynamic-wind (lambda () (set! ctr1 (+ ctr1 1))) (lambda () (set! ctr2 (+ ctr2 1)) (+ 1 ctr2)) (lambda () (set! ctr3 (+ ctr3 1)))))) (= ctr1 ctr2 ctr3 (- ctr4 1) 1))) #t) (test (let ((ctr1 0) (ctr2 0) (ctr3 0)) (let ((ctr4 (catch 'dw (lambda () (dynamic-wind (lambda () (set! ctr1 (+ ctr1 1))) (lambda () (set! ctr2 (+ ctr2 1)) (error 'dw "dw-error") ctr2) (lambda () (set! ctr3 (+ ctr3 1))))) (lambda args (car args))))) (and (eq? ctr4 'dw) (= ctr1 1) (= ctr2 1) (= ctr3 1)))) #t) (test (let ((ctr1 0) (ctr2 0) (ctr3 0)) (let ((ctr4 (catch 'dw (lambda () (dynamic-wind (lambda () (set! ctr1 (+ ctr1 1))) (lambda () (error 'dw "dw-error") (set! ctr2 (+ ctr2 1)) ctr2) (lambda () (set! ctr3 (+ ctr3 1))))) (lambda args (car args))))) (and (eq? ctr4 'dw) (= ctr1 1) (= ctr2 0) (= ctr3 1)))) #t) (test (let ((ctr1 0) (ctr2 0) (ctr3 0)) (let ((ctr4 (catch #t (lambda () (dynamic-wind (lambda () (set! ctr1 (+ ctr1 1)) (error 'dw-init "dw-error")) (lambda () (set! ctr2 (+ ctr2 1)) (error 'dw "dw-error") ctr2) (lambda () (set! ctr3 (+ ctr3 1))))) (lambda args (car args))))) (and (eq? ctr4 'dw-init) (= ctr1 1) (= ctr2 0) (= ctr3 0)))) #t) (test (let ((ctr1 0) (ctr2 0) (ctr3 0)) (let ((ctr4 (catch #t (lambda () (dynamic-wind (lambda () (set! ctr1 (+ ctr1 1))) (lambda () (set! ctr2 (+ ctr2 1)) ctr2) (lambda () (set! ctr3 (+ ctr3 1)) (error 'dw-final "dw-error")))) (lambda args (car args))))) (and (eq? ctr4 'dw-final) (= ctr1 1) (= ctr2 1) (= ctr3 1)))) #t) (test (let ((ctr1 0) (ctr2 0) (ctr3 0)) (let ((ctr4 (catch #t (lambda () (dynamic-wind (lambda () (set! ctr1 (+ ctr1 1))) (lambda () (set! ctr2 (+ ctr2 1)) ctr2) (lambda () (error 'dw-final "dw-error") (set! ctr3 (+ ctr3 1))))) (lambda args (car args))))) (and (eq? ctr4 'dw-final) (= ctr1 1) (= ctr2 1) (= ctr3 0)))) #t) (test (let ((ctr1 0) (ctr2 0) (ctr3 0)) (let ((ctr4 (call/cc (lambda (exit) (dynamic-wind (lambda () (set! ctr1 (+ ctr1 1))) (lambda () (exit ctr2) (set! ctr2 (+ ctr2 1)) ctr2) (lambda () (set! ctr3 (+ ctr3 1)) 123)))))) (and (= ctr1 ctr3 1) (= ctr2 ctr4 0)))) #t) (test (let ((ctr1 0) (ctr2 0) (ctr3 0)) (let ((ctr4 (call/cc (lambda (exit) (dynamic-wind (lambda () (exit ctr1) (set! ctr1 (+ ctr1 1))) (lambda () (set! ctr2 (+ ctr2 1)) ctr2) (lambda () (set! ctr3 (+ ctr3 1)))))))) (= ctr1 ctr2 ctr3 ctr4 0))) #t) (test (let ((ctr1 0) (ctr2 0) (ctr3 0)) (let ((ctr4 (call/cc (lambda (exit) (dynamic-wind (lambda () (set! ctr1 (+ ctr1 1))) (lambda () (set! ctr2 (+ ctr2 1)) ctr2) (lambda () (exit ctr3) (set! ctr3 (+ ctr3 1)))))))) (and (= ctr1 ctr2 1) (= ctr3 ctr4 0)))) #t) (test (let ((path ()) (c #f)) (let ((add (lambda (s) (set! path (cons s path))))) (dynamic-wind (lambda () (add 'connect)) (lambda () (add (call-with-current-continuation (lambda (c0) (set! c c0) 'talk1)))) (lambda () (add 'disconnect))) (if (< (length path) 4) (c 'talk2) (reverse path)))) '(connect talk1 disconnect connect talk2 disconnect)) (for-each (lambda (arg) (test (dynamic-wind (lambda () #f) (lambda () arg) (lambda () #f)) arg)) (list "hi" -1 #\a 1 'a-symbol #(1 2 3) 3.14 3/4 1.0+1.0i #t (list 1 2 3) '(1 . 2))) (test (dynamic-wind (lambda () #f) (lambda () #f) (lambda () #f)) #f) (test (+ 1 (dynamic-wind (lambda () #f) (lambda () (values 2 3 4)) (lambda () #f)) 5) 15) (test (let () (define-macro (makef val) `(lambda () ,val)) (dynamic-wind (lambda () #f) (makef 123) (lambda () #f))) 123) (test (dynamic-wind (lambda () #f) (define-macro (_m_) 32) (lambda () #f)) 32) (let () (define-macro (m) `(+ 1 2 3)) (test (dynamic-wind m m m) 6) (test (dynamic-wind m (lambda () 123) m) 123) (test (dynamic-wind (lambda () #f) m (lambda () #f)) 6) (test (dynamic-wind (lambda () #f) m m) 6)) ;;; so... dynamic-wind init load quit would place the loaded defs in the current env -- transparent dw (let () (define-macro* (m (a 1)) `(define __asdf__ ,a)) (dynamic-wind (lambda () #f) m (lambda () #f)) (test __asdf__ 1)) (test (let ((identity (lambda (a) a))) (let ((x ()) (c #f)) (dynamic-wind (lambda () (set! x (cons 'a x))) (lambda () (dynamic-wind (lambda () (set! x (cons 'b x))) (lambda () (dynamic-wind (lambda () (set! x (cons 'c x))) (lambda () (set! c (call/cc identity))) (lambda () (set! x (cons 'd x))))) (lambda () (set! x (cons 'e x)))) (dynamic-wind (lambda () (set! x (cons 'f x))) (lambda () (if c (c #f))) (lambda () (set! x (cons 'g x))))) (lambda () (set! x (cons 'h x)))) (reverse x))) '(a b c d e f g b c d e f g h)) (test (list (dynamic-wind (lambda () #f) (lambda () (values 'a 'b 'c)) (lambda () #f))) (list 'a 'b 'c)) (test (let ((ctr1 0) (ctr2 0) (ctr3 0)) (let ((val (dynamic-wind (lambda () #f) (lambda () (set! ctr1 1) (call/cc (lambda (exit) (exit 123) (set! ctr2 2) 321))) (lambda () (set! ctr3 3))))) (and (= ctr1 1) (= ctr2 0) (= ctr3 3) (= val 123)))) #t) (test (let ((ctr1 0)) (let ((val (dynamic-wind (let ((a 1)) (lambda () (set! ctr1 a))) (let ((a 10)) (lambda () (set! ctr1 (+ ctr1 a)) ctr1)) (let ((a 100)) (lambda () (set! ctr1 (+ ctr1 a))))))) (and (= ctr1 111) (= val 11)))) #t) (test (let ((ctr1 0)) (let ((val (+ 3 (dynamic-wind (let ((a 1)) (lambda () (set! ctr1 a))) (let ((a 10)) (lambda () (set! ctr1 (+ ctr1 a)) ctr1)) (let ((a 100)) (lambda () (set! ctr1 (+ ctr1 a))))) 1000))) (and (= ctr1 111) (= val 1014)))) #t) (test (let ((n 0)) (call-with-current-continuation (lambda (k) (dynamic-wind (lambda () (set! n (+ n 1)) (k)) (lambda () (set! n (+ n 2))) (lambda () (set! n (+ n 4)))))) n) 1) (test (let ((n 0)) (call-with-current-continuation (lambda (k) (dynamic-wind (lambda () #f) (lambda () (dynamic-wind (lambda () #f) (lambda () (set! n (+ n 1)) (k)) (lambda () (set! n (+ n 2)) ;(k) ))) (lambda () (set! n (+ n 4)))))) n) 7) (test (let ((n 0)) (call-with-current-continuation (lambda (k) (dynamic-wind (lambda () #f) (lambda () (dynamic-wind (lambda () #f) (lambda () (dynamic-wind (lambda () #f) (lambda () (set! n (+ n 1)) (k)) (lambda () (if (= n 1) (set! n (+ n 2)))))) (lambda () (if (= n 3) (set! n (+ n 4)))))) (lambda () (if (= n 7) (set! n (+ n 8))))))) n) 15) (test (dynamic-wind) 'error) (test (dynamic-wind (lambda () #f)) 'error) (test (dynamic-wind (lambda () #f) (lambda () #f)) 'error) (test (dynamic-wind (lambda (a) #f) (lambda () #f) (lambda () #f)) 'error) (test (dynamic-wind (lambda () #f) (lambda (a b) #f) (lambda () #f)) 'error) (test (dynamic-wind (lambda () #f) (lambda () #f) (lambda (a) #f)) 'error) (test (dynamic-wind (lambda () 1) #f (lambda () 2)) 'error) (test (dynamic-wind . 1) 'error) (test (dynamic-wind () () ()) 'error) (test (dynamic-wind () _ht_ _null_ _c_obj_ ()) 'error) (test (dynamic-wind + + +) 0) (test (dynamic-wind (values + + +)) 0) (test (dynamic-wind s7-version s7-version s7-version) (s7-version)) (test (+ (dynamic-wind (lambda () (values 1 2 3)) (lambda () (values 4 5 6)) (lambda () (values 7 8 9)))) 15) (for-each (lambda (arg) (test (dynamic-wind arg (lambda () #f) (lambda () #f)) 'error) (test (dynamic-wind (lambda () #f) arg (lambda () #f)) 'error) (test (dynamic-wind (lambda () #f) (lambda () #f) arg) 'error)) (list "hi" -1 #\a 1 'a-symbol #(1 2 3) 3.14 3/4 1.0+1.0i #t (list 1 2 3) '(1 . 2))) (test (dynamic-wind (let ((x 1)) (lambda () x)) ((lambda () (lambda () 2))) s7-version) 2) (test (let ((x 0)) (dynamic-wind (lambda () (set! x 1)) ((lambda () (set! x 32) (lambda () x))) (let () (set! x 44) (lambda () x)))) 1) (test (let ((x 0)) (dynamic-wind (lambda () (set! x (+ x 1))) ((lambda () (set! x 32) (lambda () x))) (let () (set! x 44) (lambda () x)))) 45) (test (let ((x 0)) (dynamic-wind (lambda () (set! x (+ x 1))) ((lambda () (set! x 32) (lambda () x))) (let () (lambda () x)))) 33) (test (let ((x 0)) (dynamic-wind (lambda () (set! x (+ x 1))) ((lambda () (set! x (+ x 32)) (lambda () x))) (let () (lambda () (set! x (+ x 100)) x)))) 33) (let () (define-macro (make-thunk val) `(lambda () ,val)) (test (dynamic-wind (make-thunk 0) (make-thunk 1) (make-thunk 2)) 1)) (let ((jumps 4)) (define (test1 f) (let ((c #f) (ctr 0)) (dynamic-wind (lambda () #f) (lambda () (when (not c) (call/cc (lambda (k) (set! c k)))) (set! ctr (+ ctr 1))) (lambda () #f)) (if (< ctr f) (c)) ctr)) (define (test2 f) (let ((c #f) (ctr 0)) (dynamic-wind (lambda () #f) (lambda () (with-baffle (when (not c) (call/cc (lambda (k) (set! c k)))) (set! ctr (+ ctr 1)))) (lambda () #f)) (if (< ctr f) (c)) ctr)) (test (catch #t (lambda () (test2 jumps)) (lambda args 'error)) 'error) (test (test1 jumps) 4) (define (test3 f) (let ((c #f) (ctr 0)) (dynamic-wind (lambda () #f) (lambda () #f) (lambda () (when (not c) (call/cc (lambda (k) (set! c k)))) (set! ctr (+ ctr 1)))) (if (< ctr f) (c)) ctr)) (define (test4 f) (let ((c #f) (ctr 0)) (dynamic-wind (lambda () #f) (lambda () #f) (lambda () (with-baffle (when (not c) (call/cc (lambda (k) (set! c k)))) (set! ctr (+ ctr 1))))) (if (< ctr f) (c)) ctr)) (test (catch #t (lambda () (test4 jumps)) (lambda args 'error)) 'error) (test (test3 jumps) 5) (define (test5 f) (let ((c #f) (ctr 0)) (dynamic-wind (lambda () (when (not c) (call/cc (lambda (k) (set! c k)))) (set! ctr (+ ctr 1))) ; this is a very bad idea! (infinite loop etc) (lambda () #f) (lambda () #f)) (if (< ctr f) (c)) ctr)) (define (test6 f) (let ((c #f) (ctr 0)) (dynamic-wind (lambda () (with-baffle (when (not c) (call/cc (lambda (k) (set! c k)))) (set! ctr (+ ctr 1)))) (lambda () #f) (lambda () #f)) (if (< ctr f) (c)) ctr)) (test (catch #t (lambda () (test6 jumps)) (lambda args 'error)) 'error) (test (test5 jumps) 5)) #| ;;; from scheme wiki ;;; http://community.schemewiki.org/?hose-the-repl ;;; jorgen-schafer (test (let loop () (call-with-exit (lambda (k) (dynamic-wind (lambda () #t) (lambda () (let loop () (loop))) k))) (loop)) 'error) ;; that example calls to mind a bunch like it: (test (call-with-exit (lambda (k) (dynamic-wind (lambda () #t) (lambda () (let loop () (loop))) k))) 'error) (test (call-with-exit (lambda (k) (dynamic-wind (lambda () #t) k (lambda () #t)))) 'error) (test (call-with-exit (lambda (k) (dynamic-wind k (lambda () #f) (lambda () #t)))) 'error) |# (test (call-with-exit (lambda (k) (procedure-documentation k))) "") (test (call-with-exit (lambda (k) (procedure-source k))) ()) (test (let ((pws (dilambda vector-ref vector-set!))) (let ((pws1 (dilambda pws vector-set!))) (let ((v (vector 1 2))) (set! (pws1 v 1) 32) (pws1 v 1)))) 32) (test (call-with-exit (lambda (k) (map k '(1 2 3)))) 1) (test (call-with-exit (lambda (k) (for-each k '(1 2 3)))) 1) (test (call-with-exit (lambda (k) (catch #t k k))) ()) ; was 'error until 14-May-14 (test (call-with-exit (lambda (k) (catch #t (lambda () #f) k))) #f) ;(test (call-with-exit (lambda (k) (catch #t (lambda () (error 'an-error)) k))) 'error) ; this seems like it could be either (test (procedure? (call-with-exit (lambda (return) (call-with-exit return)))) #t) (test (call-with-exit (lambda (k) (sort! '(1 2 3) k))) 'error) ; "sort! argument 2, #, is a goto" (test (sort! '(1 2 3) (lambda () #f)) 'error) (test (sort! '(1 2 3) (lambda (a) #f)) 'error) (test (sort! '(1 2 3) (lambda (a b c) #f)) 'error) ;(test (let () (define-macro (asdf a b) `(< ,a ,b)) (sort! '(1 2 3) asdf)) 'error) (test (let () (let asdf () (sort! '(1 2 3) asdf))) 'error) (test (let () (let asdf () (map asdf '(1 2 3)))) 'error) (test (let () (let asdf () (for-each asdf '(1 2 3)))) 'error) (test (dynamic-wind quasiquote s7-version s7-version) 'error) (test (sort! '(1 2 3) (define-macro (_m_ a b) `(> ,a ,b))) '(3 2 1)) (test (sort! '(2 1 3) (define-macro (_m_ a b) `(< ,a ,b))) '(1 2 3)) (test (let ((ctr 0)) (call-with-exit (lambda (exit) (let asdf () (set! ctr (+ ctr 1)) (if (> ctr 2) (exit ctr)) (dynamic-wind (lambda () #f) (lambda () #f) asdf))))) 3) (test (let ((ctr 0)) (dynamic-wind (lambda () #f) (lambda () (call-with-exit (lambda (exit) (catch #t (lambda () (error 'error)) (lambda args (exit 'error))) (set! ctr 1)))) (lambda () (set! ctr (+ ctr 2)))) ctr) 2) (test (call-with-exit (lambda (r1) (call-with-exit (lambda (r2) (call-with-exit (lambda (r3) (r1 12) (r2 1))) (r1 2))) 3)) 12) (test (call-with-exit (lambda (r1) (call-with-exit (lambda (r2) (call-with-exit (lambda (r3) (r2 12) (r2 1))) (r1 2))) 3)) 3) (test (call-with-exit (lambda (r1) (call-with-exit (lambda (r2) (call-with-exit (lambda (r3) (r3 12) (r2 1))) (r1 2))) 3)) 2) ;; make sure call-with-exit closes ports (test (let ((p (call-with-exit (lambda (return) (call-with-input-file tmp-output-file (lambda (port) (return port))))))) (port-closed? p)) #t) (test (let ((p (call-with-exit (lambda (return) (call-with-input-file tmp-output-file (lambda (port) (if (not (port-closed? port)) (return port)))))))) (port-closed? p)) #t) (test (let ((p (call-with-exit (lambda (return) (with-input-from-file tmp-output-file (lambda () (return (current-input-port)))))))) (port-closed? p)) #t) (test (let ((p (call-with-exit (lambda (return) (with-output-to-file "empty-file" (lambda () (return (current-output-port)))))))) (port-closed? p)) #t) (test (let ((p (call-with-exit (lambda (return) (call-with-output-file "empty-file" (lambda (port) (return port))))))) (port-closed? p)) #t) (test (let ((p (call-with-exit (lambda (return) (call-with-input-string "this is a test" (lambda (port) (return port))))))) (port-closed? p)) #t) (test (let ((p (call-with-exit (lambda (return) (call-with-output-string (lambda (port) (return port))))))) (port-closed? p)) #t) (let ((pws (dilambda < >))) (test (sort! '(2 3 1 4) pws) '(1 2 3 4))) (test (call-with-exit (lambda (k) (call-with-input-string "123" k))) 'error) (test (call-with-exit (lambda (k) (call-with-input-file tmp-output-file k))) 'error) (test (call-with-exit (lambda (k) (call-with-output-file tmp-output-file k))) 'error) (test (call-with-exit (lambda (k) (call-with-output-string k))) 'error) (test (call-with-output-string (hash-table* 'b 2)) "") ;?? (let ((pws (dilambda (lambda (a) (+ a 1)) (lambda (a b) b)))) (test (procedure? pws) #t) (test (map pws '(1 2 3)) '(2 3 4)) (test (apply pws '(1)) 2)) (test (let ((ctr 0)) (call-with-exit (lambda (top-exit) (set! ctr (+ ctr 1)) (call-with-exit top-exit) (set! ctr (+ ctr 16)))) ctr) 1) (test (let () (+ 5 (call-with-exit (lambda (return) (return 1 2 3) 4)))) 11) (test (+ 5 (call-with-exit (lambda (return) (return 1)))) 6) (test (+ 5 (call-with-exit (lambda (return) (return)))) 'error) (test (let ((cur ())) (define (step pos) (dynamic-wind (lambda () (set! cur (cons pos cur))) (lambda () (set! cur (cons (+ pos 1) cur)) (if (< pos 40) (step (+ pos 10))) (set! cur (cons (+ pos 2) cur)) cur) (lambda () (set! cur (cons (+ pos 3) cur))))) (reverse (step 0))) '(0 1 10 11 20 21 30 31 40 41 42 43 32 33 22 23 12 13 2)) (test (let ((cur ())) (define (step pos) (dynamic-wind (lambda () (set! cur (cons pos cur))) (lambda () (set! cur (cons (+ pos 1) cur)) (if (< pos 40) (step (+ pos 10)) (error 'all-done)) (set! cur (cons (+ pos 2) cur)) cur) (lambda () (set! cur (cons (+ pos 3) cur))))) (catch 'all-done (lambda () (reverse (step 0))) (lambda args (reverse cur)))) '(0 1 10 11 20 21 30 31 40 41 43 33 23 13 3)) (test (let ((cur ())) (define (step pos ret) (dynamic-wind (lambda () (set! cur (cons pos cur))) (lambda () (set! cur (cons (+ pos 1) cur)) (if (< pos 40) (step (+ pos 10) ret) (ret (reverse cur))) (set! cur (cons (+ pos 2) cur)) cur) (lambda () (set! cur (cons (+ pos 3) cur))))) (list (call-with-exit (lambda (ret) (step 0 ret))) (reverse cur))) '((0 1 10 11 20 21 30 31 40 41) (0 1 10 11 20 21 30 31 40 41 43 33 23 13 3))) (test (let () (catch #t (lambda () (eval-string "(error 'hi \"hi\")")) (lambda args 'error))) 'error) (test (let () (catch #t (lambda () (eval-string "(+ 1 #\\a)")) (lambda args 'oops))) 'oops) (test (let () (call-with-exit (lambda (return) (eval-string "(return 3)")))) 3) (test (let () (call-with-exit (lambda (return) (eval-string "(abs (+ 1 (if #t (return 3))))")))) 3) (test (let ((val (catch #t (lambda () (eval-string "(catch 'a (lambda () (+ 1 __asdf__)) (lambda args 'oops))")) (lambda args 'error)))) val) 'error) (test (let ((val (catch #t (lambda () (eval `(catch 'a (lambda () (+ 1 __asdf__)) (lambda args 'oops)))) (lambda args 'error)))) val) 'error) #| ;; this exits the s7test load (test (let () (call/cc (lambda (return) (eval-string "(return 3)")))) 3) |# (let ((x 0) (y 0) (z 0)) (define (dw1 a c) (dynamic-wind (lambda () (set! x (+ x 1))) (lambda () (set! y (+ y 1)) (or (and (>= a c) a) (dw1 (+ a 1) c))) (lambda () (set! z (+ z 1)) (set! y (- y 1))))) (let ((val (dw1 0 8))) (test (list val x y z) (list 8 9 0 9)))) (let ((x 0) (y 0) (z 0)) (define (dw1 a c) (catch #t (lambda () (dynamic-wind (lambda () (set! x (+ x 1))) (lambda () (set! y (+ y 1)) (or (and (>= a c) a) (dw1 (+ a 1) c))) (lambda () (set! z (+ z 1)) (set! y (= y 1))))) ; an error after the 1st call because we have (= #f 1) (lambda args 'error))) (let ((val (dw1 0 4))) (test val 'error))) (let ((x 0) (y 0) (z 0)) (define (dw1 a c) (catch #t (lambda () (dynamic-wind (lambda () (set! x (+ x 1))) (lambda () (set! y (= y 1)) ; an error after the 1st call because we have (= #f 1) (or (and (>= a c) a) (dw1 (+ a 1) c))) (lambda () (set! z (+ z 1)) (set! y (= y 1))))) (lambda args 'error))) (let ((val (dw1 0 4))) (test val 'error))) (let ((x 0) (y 0) (z 0)) (define (dw1 a c) (catch #t (lambda () (dynamic-wind (lambda () (set! x (= x 1))) ; an error after the 1st call because we have (= #f 1) (lambda () (set! y (= y 1)) (or (and (>= a c) a) (dw1 (+ a 1) c))) (lambda () (set! z (+ z 1)) (set! y (= y 1))))) (lambda args 'error))) (let ((val (dw1 0 4))) (test val 'error))) (let ((x 0) (y 0) (z 0)) (let ((val (call-with-exit (lambda (r) (catch #t (lambda () (dynamic-wind (lambda () (set! x (+ x 1))) (lambda () (set! y (+ y 1)) (r y)) (lambda () (set! z (+ z 1))))) (lambda args 'error)))))) (test (list val z) '(1 1)))) (let ((x 0) (y 0) (z 0)) (let ((val (catch #t (lambda () (dynamic-wind (lambda () (set! x (+ x 1))) (lambda () (call-with-exit (lambda (r) (set! y r) x))) (lambda () (set! z (+ z 1)) (y z)))) (lambda args 'error)))) (test val 'error))) (test (dynamic-wind (lambda () (eq? (let ((lst (cons 1 2))) (set-cdr! lst lst) lst) (call/cc (lambda (k) k)))) (lambda () #f) (lambda () #f)) #f) ;;; -------------------------------------------------------------------------------- ;;; quasiquote ;;; -------------------------------------------------------------------------------- (test `(1 2 3) '(1 2 3)) (test `() ()) (test `(list ,(+ 1 2) 4) '(list 3 4)) (test `(1 ,@(list 1 2) 4) '(1 1 2 4)) (test `(a ,(+ 1 2) ,@(map abs '(4 -5 6)) b) '(a 3 4 5 6 b)) (test `(a `(b ,(+ 1 2) ,(foo ,(+ 1 3) d) e) f) '(a `(b ,(+ 1 2) ,(foo 4 d) e) f)) (test (let ((name1 'x) (name2 'y)) `(a `(b ,,name1 ,',name2 d) e)) '(a `(b ,x ,'y d) e)) (test `(1 2 ,(* 9 9) 3 4) '(1 2 81 3 4)) (test `(1 ,(+ 1 1) 3) '(1 2 3)) (test `(,(+ 1 2)) '(3)) (test `(,'a . ,'b) (cons 'a 'b)) (test `(,@'() . foo) 'foo) (test `(1 , 2) '(1 2)) (test `(1 , @(list 2 3)) 'error) ; ?? this is an error in Guile and Clisp (test `(1 ,@ (list 2 3)) '(1 2 3)) ; seems a bit arbitrary (test `(1 ,@(list)) '(1)) (test `(1 ,@()) '(1)) (test `(1 ,@'()) '(1)) (test `(1 . ,()) '(1)) (test `(1 , #|a comment|# 2) '(1 2)) (test `(1 ,@ #|a comment|# (list 2 3)) '(1 2 3)) (test `(1 , ;a comment 2) '(1 2)) (test `(1 #||#,2) '(1 2)) (test `(1 #||#,@(list #||# 2 3 #||#)) '(1 2 3)) (test (eval ``(+ 1 ,@,@'('(2 3)))) '(+ 1 2 3)) (test (eval ``(+ 1 ,@ #||# ,@ '('(2 3)))) '(+ 1 2 3)) (test `(,1 ,1) '(1 1)) (test `(,1 ,`,1) '(1 1)) (test `(,1 ,`,@(list 1)) '(1 1)) (test `(,1 ,`,`,1) '(1 1)) (test `(,1 ,`,@'(1)) '(1 1)) (test `(,1 ,`,@`(1)) '(1 1)) (test `(,1 ,`,@`(,1)) '(1 1)) (test `(,1 ,@`,@(list (list 1))) '(1 1)) (test (eval ``(,,1 ,@,@(list (quote (list 1))))) '(1 1)) (test (eval ``(,,1 ,@,@(list `(list 1)))) '(1 1)) (test (eval (eval ```(,,,1 ,@,@,@(list '(list '(list 1)))))) '(1 1)) (test (+ 1 (eval (eval ```,@,,@(list ''(list 2 3))))) 6) (test (+ 1 (eval (eval (eval ````,@,,,@(list '''(list 2 3)))))) 6) (test (apply + `(1 ,@`(2 ,@(list 3)))) 6) (test (eval `(- ,@()',1)) -1) (test (eval `(,- ,@()'1)) -1) (test (eval (eval ``(- ,@,@'(,1())))) -1) (test (eval (eval ``(,@,@'(- ,1())))) -1) (test (eval (eval ``(,- ,@,@'(1())))) -1) (test (eval (eval ``(,- ,@'(,@()1)))) -1) (test (eval (eval ``(- ,@,@',().(1)))) -1) (test (quasiquote quote) 'quote) (test (eval (list quasiquote (list values #t))) (list values #t)) (test (eq? (cadr `(a, b, c,)) 'b,) #t) (test (eq? (cadr '(a, b, c,)) 'b,) #t) (test (let ((b, 32)) `(a , b, c,)) '(a 32 c,)) (test (let ((b, 32)) `(a, , b, c,)) '(a, 32 c,)) (if (not (provided? 'immutable-unquote)) (test (equal? (let ((b, 32)) '(a, , b, c,)) '(a, (unquote b,) c,)) #t)) ; comma by itself (no symbol) is an error (if (not (provided? 'immutable-unquote)) (test (equal? (let ((b, 32)) '(a, , , b, c,)) '(a, (unquote (unquote b,)) c,)) #t)) ;(test (equal? (let ((b 32)) (let ((b, b)) ``(a, , , b, c,))) '({list} 'a, 32 'c,)) #t) (if (not pure-s7) (test (let ((func abs)) (quasiquote (sym . (unquote func)))) (cons 'sym abs))) ; guile mailing list (test (eval ``(,@,@())) ()) (if (provided? 'immutable-unquote) (begin (test (let () (define* ,() (abs ))) 'error) (test (let (,'a) unquote) 'error) (test (let (, '1) unquote) 'error) (test (let (, (lambda (x) (+ x 1))) ,,,,'3) 'error) (test (let (,@ '(1)) unquote) 'error) (test (let (,@ ()) ,2) 'error) (test (let (' 1) quote) 1) ) (begin (test (let () (define* ,() (abs ))) 'error) (test (let (,'a) unquote) 'a) (test (let (, '1) unquote) 1) (test (let (, (lambda (x) (+ x 1))) ,,,,'3) 7) (test (let (,@ '(1)) unquote) 1) (test (let (,@ ()) ,2) 2) (test (let (' 1) quote) 1) )) ;; mostly from gauche ;;; the vector quasiquote comma-eval takes place in the global environment so ;;; (let ((x 0)) (let ((y `#(,(begin (define x 32) x)))) (list x y))) -> '(0 #(32)) and defines x=32 in the top level (if with-qq-vectors (begin (test `#(1 ,@(list 1 2) 4) #(1 1 2 4)) (if (eqv? 2 (sqrt 4)) (test `#(10 5 ,(sqrt 4) ,@(map sqrt '(16 9)) 8) #(10 5 2 4 3 8))) ; inexactness foolishness (test `#(,(cons 1 2) 3) #((1 . 2) 3)) ; (test `#(,quasi0 3) #(99 3)) ; and (let ((quasi0 99)) (quasiquote #(,quasi0 3))) -> #((unquote quasi0) 3) ; (test `#(,(+ quasi0 1) 3) #(100 3)) ; (test `#(3 ,quasi1) #(3 101)) ; (test `#(3 ,(+ quasi1 1)) #(3 102)) (test `#(1 ,@(list 2 3) 4) #(1 2 3 4)) (test `#(1 2 ,@(list 3 4)) #(1 2 3 4)) ; (test `#(,@quasi2 ,@quasi3) #(a b c d)) ; (test `#(,@quasi2 ,quasi3) #(a b (c d))) ; (test `#(,quasi2 ,@quasi3) #((a b) c d)) (test `#(,@(list)) #()) (test `#(,@(list 1 2) ,@(list 1 2)) #(1 2 1 2)) (test `#(,@(list 1 2) a ,@(list 1 2)) #(1 2 a 1 2)) (test `#(a ,@(list 1 2) ,@(list 1 2)) #(a 1 2 1 2)) (test `#(,@(list 1 2) ,@(list 1 2) a) #(1 2 1 2 a)) (test `#(,@(list 1 2) ,@(list 1 2) a b) #(1 2 1 2 a b)) ; (test `#(1 `(1 ,2 ,,(+ 1 2)) 1) #(1 `(1 ,2 ,3) 1)) ; (test `#(1 `(1 ,,quasi0 ,,quasi1) 1) #(1 `(1 ,99 ,101) 1)) (test `#(1 `(1 ,@2 ,@,(list 1 2))) #(1 `(1 ,@2 ,@(1 2)))) ; (test `#(1 `(1 ,@,quasi2 ,@,quasi3)) #(1 `(1 ,@(a b) ,@(c d)))) ; (test `#(1 `(1 ,(,@quasi2 x) ,(y ,@quasi3))) #(1 `(1 ,(a b x) ,(y c d)))) (test (eval-string "`#(1 2 3 unquote abs)") 'error) ; guile mailing list says it should work, but unquote is translated at the reader level ;; which does not know it's in a vector here, so s7 sees `#(1 2 3 . abs) which is indeed an error )) (let ((quasi0 99) (quasi1 101) (quasi2 '(a b)) (quasi3 '(c d))) (test `,quasi0 99) (test `,quasi1 101) (test `(,(cons 1 2)) '((1 . 2))) (test `(,(cons 1 2) 3) '((1 . 2) 3)) (test `(,quasi0 3) '(99 3)) (test `(3 ,quasi0) '(3 99)) (test `(,(+ quasi0 1) 3) '(100 3)) (test `(3 ,(+ quasi0 1)) '(3 100)) (test `(,quasi1 3) '(101 3)) (test `(3 ,quasi1) '(3 101)) (test `(,(+ quasi1 1) 3) '(102 3)) (test `(3 ,(+ quasi1 1)) '(3 102)) (test `(1 ,@(list 2 3) 4) '(1 2 3 4)) (test `(1 2 ,@(list 3 4)) '(1 2 3 4)) (test `(,@quasi2 ,@quasi3) '(a b c d)) (test `(1 2 . ,(list 3 4)) '(1 2 3 4)) (test `(,@quasi2 . ,quasi3) '(a b c d)) (test `#() #()) (test `(,@(list 1 2) ,@(list 1 2)) '(1 2 1 2)) (test `(,@(list 1 2) a ,@(list 1 2)) '(1 2 a 1 2)) (test `(a ,@(list 1 2) ,@(list 1 2)) '(a 1 2 1 2)) (test `(,@(list 1 2) ,@(list 1 2) a) '(1 2 1 2 a)) (test `(,@(list 1 2) ,@(list 1 2) a b) '(1 2 1 2 a b)) (test `(,@(list 1 2) ,@(list 1 2) . a) '(1 2 1 2 . a)) (test `(,@(list 1 2) ,@(list 1 2) . ,(cons 1 2)) '(1 2 1 2 1 . 2)) (test `(,@(list 1 2) ,@(list 1 2) . ,quasi2) '(1 2 1 2 a b)) (test `(,@(list 1 2) ,@(list 1 2) a . ,(cons 1 2)) '(1 2 1 2 a 1 . 2)) (test `(,@(list 1 2) ,@(list 1 2) a . ,quasi3) '(1 2 1 2 a c d)) ; (test `(1 `(1 ,2 ,,(+ 1 2)) 1) '(1 `(1 ,2 ,3) 1)) ; (test `(1 `(1 ,,quasi0 ,,quasi1) 1) '(1 `(1 ,99 ,101) 1)) (test `(1 `(1 ,@2 ,@,(list 1 2))) '(1 `(1 ,@2 ,@(1 2)))) (test `(1 `(1 ,@,quasi2 ,@,quasi3)) '(1 `(1 ,@(a b) ,@(c d)))) (test `(1 `(1 ,(,@quasi2 x) ,(y ,@quasi3))) '(1 `(1 ,(a b x) ,(y c d)))) ; (test `(1 `#(1 ,(,@quasi2 x) ,(y ,@quasi3))) '(1 `#(1 ,(a b x) ,(y c d)))) ) (if with-qq-vectors (begin (test `#2d((1 ,(* 3 2)) (,@(list 2) 3)) #2D((1 6) (2 3))) (test `#3d() #3D()) (test `#3D((,(list 1 2) (,(+ 1 2) 4)) (,@(list (list 5 6)) (7 8))) #3D(((1 2) (3 4)) ((5 6) (7 8)))))) (test (eval-string "`#2d(1 2)") 'error) (test (eval-string "`#2d((1) 2)") 'error) (test (eval-string "`#2d((1 2) (3 4) (5 6 7))") 'error) (test `#2d((1 2)) #2D((1 2))) (let ((x 3) (y '(a b c))) (test `(1 . ,2) '(1 . 2)) (test `(1 2 . ,3) '(1 2 . 3)) (test `(1 x . ,3) '(1 x . 3)) (test `(1 x . ,x) '(1 x . 3)) (test `(1 . ,(list 2 3)) '(1 2 3)) (test `(1 ,@(list 2 3)) '(1 2 3)) ;;; (test `(1 . ,@('(2 3))) '(1 2 3)) (test `(1 ,(list 2 3)) '(1 (2 3))) (test `(1 . (list 2 3)) '(1 list 2 3)) (test `(x . ,x) '(x . 3)) (test `(y . ,y) '(y a b c)) (test `(,x ,@y ,x) '(3 a b c 3)) (test `(,x ,@y . ,x) '(3 a b c . 3)) (test `(,y ,@y) '((a b c) a b c)) (test `(,@y . ,y) '(a b c a b c)) (test (object->string `(,y . ,y)) "((a b c) a b c)") ; was "(#1=(a b c) . #1#)" (test (object->string `(y ,y ,@y ,y . y)) "(y (a b c) a b c (a b c) . y)") ; was "(y #1=(a b c) a b c #1# . y)" (test (eval ``(1 . ,,2)) '(1 . 2)) (test (eval ``(y . ,,x)) '(y . 3)) (test (eval ``(,y . ,x)) '((a b c) . 3)) (test (eval ``(,@y . x)) '(a b c . x)) (test (eval ``(,x . ,y)) '(3 a b c)) (test (eval ``(,,x . y)) '(3 . y)) (test (eval ``(,,x ,@y)) '(3 a b c)) ;; in clisp `(,y . ,@(y)) -> *** - READ: the syntax `( ... . ,@form) is invalid ) (test (let ((.' '(1 2))) `(,@.')) '(1 2)) (test (let ((hi (lambda (a) `(+ 1 ,a)))) (hi 2)) '(+ 1 2)) (test (let ((hi (lambda (a) `(+ 1 ,@a)))) (hi (list 2 3))) '(+ 1 2 3)) (test (let ((hi (lambda (a) `(let ((b ,a)) ,(+ 1 a))))) (hi 3)) '(let ((b 3)) 4)) (test (let ((x '(a b c))) `(x ,x ,@x foo ,(cadr x) bar ,(cdr x) baz ,@(cdr x))) '(x (a b c) a b c foo b bar (b c) baz b c)) (test (let ((x '(a b c))) `(,(car `(,x)))) '((a b c))) (test (let ((x '(a b c))) `(,@(car `(,x)))) '(a b c)) (test (let ((x '(a b c))) `(,(car `(,@x)))) '(a)) (test (let ((x '(a b c))) ``,,x) '(a b c)) (test (let ((x '(a b c))) `,(car `,x)) 'a) (test (let ((x '(2 3))) `(1 ,@x 4)) '(1 2 3 4)) (if with-qq-vectors (begin (test `#(1 ,(/ 12 2)) #(1 6)) (test `#(,most-positive-fixnum 2) #(9223372036854775807 2)) (test ((lambda () `#(1 ,(/ 12 2)))) #(1 6)))) (test (let ((x '(2 3))) `(1 ,@(map (lambda (a) (+ a 1)) x))) '(1 3 4)) ;;; these are from the scheme bboard (test (let ((x '(1 2 3))) `(0 . ,x)) '(0 1 2 3)) (test (let ((x '(1 2 3))) `(0 ,x)) '(0 (1 2 3))) ;(test (let ((x '(1 2 3))) `#(0 ,x)) #(0 (1 2 3))) ; local var ;(test (let ((x '(1 2 3))) `#(0 . ,x)) #(0 1 2 3)) ; same ;; unbound variable x, but (let ((x '(1 2 3))) (quasiquote #(0 . ,x))) -> #(0 unquote x) ;; so ` and (quasiquote...) are not the same in the vector case (test (let () (define-macro (tryqv . lst) `(map abs ',lst)) (tryqv 1 2 3 -4 5)) '(1 2 3 4 5)) (test (let () (define-macro (tryqv . lst) `(map abs '(,@lst))) (tryqv 1 2 3 -4 5)) '(1 2 3 4 5)) (test (let () (define-macro (tryqv . lst) `(map abs (vector ,@lst))) (tryqv 1 2 3 -4 5)) '(1 2 3 4 5)) (for-each (lambda (str) (let ((val (catch #t (lambda () (eval-string str)) (lambda args 'error)))) (if (not (eqv? val -1)) (format-logged #t "~S = ~S?~%" str val)))) (list "( '(.1 -1)1)" "( - '`-00 1)" "( - .(,`1/1))" "( - .(`1) )" "( -(/ .(1)))" "( / 01 -1 )" "(' '` -1(/ ' 1))" "(' (-01 )0)" "(' `'`` -1 1 01)" "(''-1 .(1))" "('(, -1 )0)" "('(,-1)'000)" "('(,-1)00)" "('(-1 -.0)0)" "('(-1 '1`)0)" "('(-1 .-/-)0)" "('(-1()),0)" "('(-1) 0)" "('(10. -1 )1)" "(- '`1)" "(- `1 1 1)" "(- ' 1)" "(- ' 1)" "(- '1 .())" "(- '` ,``1)" "(- '` 1)" "(- '`, `1)" "(- '`,`1)" "(- '``1)" "(- (''1 1))" "(- (- ' 1 0))" "(- (-(- `1)))" "(- (` (1)0))" "(- ,`, `1)" "(- ,`1 . ,())" "(- . ( 0 1))" "(- . ( `001))" "(- .(', 01))" "(- .('`,1))" "(- .('``1))" "(- .(,,1))" "(- .(01))" "(- .(1))" "(- .(`,1))" "(- .(`,`1))" "(- .(`1))" "(- ` ,'1)" "(- ` -0 '1)" "(- ` 1 )" "(- ` `1)" "(- `, 1)" "(- `,1)" "(- `,`,1)" "(- `,`1)" "(- ``,,1)" "(- ``,1)" "(- ``1 )" "(- ```,1)" "(- ```1)" "(-( / 1))" "(-( - -1 ))" "(-( `,- 1 0))" "(-(' (1)0))" "(-('(,1)00))" "(-(- '`1) 0)" "(-(- -1))" "(-(/(/(/ 1))))" "(-(`'1 '1))" "(-(`(,1 )'0))" "(-(`,/ ,1))" "(/ '-1 '1 )" "(/ ,, `,-1)" "(/ ,11 -11)" "(/ 01 (- '1))" "(/ `1 '`-1)" "(/(- '1) )" "(/(- '1)1)" "(/(- 001)1)" "(/(- 1),,1)" "(/(/ -1))" "(` ,- 1)" "(` `,(-1)0)" "(`' , -1 1)" "(/(- -001(+)))" "(`' -1 '1/1)" "(`','-1 ,1)" "(`(,-1)-00)" "(`(-0 -1)1)" "(`(-1 -.')0)" "(`(-1 1')0)" "(`(` -1)'`0)" "(`, - 1)" "(`,- '1)" "(`,- .(1))" "(`,- 1 )" "(`,- `,1)" "(`,- `1)" "(`,/ . (-1))" "(``,,- `01)" "('''-1 '1 '1)" "(/ `-1 1)" "(/ .( -1))" "(-(+(+)0)1)" "(/ ,`,`-1/1)" "(-(*).())" "(*(- +1))" "(-(`,*))" "(-(+)'1)" "(+(-(*)))" "(-(+(*)))" "(-(+)(*))" "(-(/(*)))" "(*(-(*)))" "(-(*(*)))" "(/(-(*)))" "(-(+(*)))" "(/ .(-1))" "(-(*))" "(- 000(*))" "(-(*(+ 1)))" "(- .((*)))" "(- +0/10(*))" "(-(`,/ .(1)))" "(+ .(' -01))" "(-(''1 01))" "(- -1/1 +0)" "(- `,'0 `01)" "( - `,(+)'1)" "(+(- . (`1)))" "(* '`,``-1)" "(-(+ -0)1)" "(+ +0(-(*)))" "(+(- '+1 ))" "(+ '-01(+))" "(`, -(+)1)" "(`,+ 0 -1)" "(-(/(/(*))))" "(`,* .( -1))" "(-(*(*(*))))" "(`,@(list +)-1)" "(* (- 1) )" "(`, - (* ))" "(/(- (* 1)))" "(- -0/1(*))" "(`(,-1)0)" "(/(-(*).()))" "(* ````-1)" "(-(+(*)0))" "(-(* `,(*)))" "(- +1(*)1)" "(- (` ,* ))" "(/(-(+ )1))" "(`,* -1(*))" "(` ,- .(1))" "(+(`,-( *)))" "( /(`,- 1))" "(`(1 -1)1)" "(*( -(/(*))))" "(- -1(-(+)))" "(* ``,,-1)" "(-(+(+))1)" "( +(*(-(*))))" "(-(+)`0(*))" "(-(+(+(*))))" "(-(+ .(01)))" "(/(*(-(* ))))" "(/ (-(* 1)))" "( /(-(/(*))))" "(+ -1 0/1)" "(/(-( +(*))))" "(*( -(`,*)))" "(* 1(/ 1)-1)" "(+ 0(- ',01))" "(+(-(-(+ -1))))" "(- 0(/(+(* ))))" "(-(+)( *)0)" "(`,- '01/1)" "(`, - ',,1)" "(/ .(`-1 1))" "(- ``,,'`1)" "(- 10 0011)" "(-(- ``1 0))" "( -(/ 01/1))" "(-(- 1)`,0)" "(/(/ -1 .()))" "(/ ,,``-1)" "( `,`, - 1)" "(- .(`1/01 ))" "('(-1) ',``0)" "('( ,/ -1 )1)" "(- ,,`,`0 +1)" "(`(-1) `,0)" "(+(* (-(*))))" "(-(`,* ,,1))" "(+(+ 0)-1)" "(+(-(+ ,1)))" "(* ,`-01/1)" "(*(- '` `1))" "(-(*(* 1 1)))" "(-(*(/ .(1))))" "(-(- 1(*)-1))" "(- -00 (* 1))" "(- (*(+ ,01)))" "(-(*), +1(* ))" "(- `,@'(1))" "`,@`(-1)" "(`'`-1 1)" "',@*(-(*))" "`,@(list `,@`(-1))" )) #| (let ((chars (vector #\/ #\. #\0 #\1 #\- #\, #\( #\) #\' #\@ #\` #\space)) (size 14)) (let ((str (make-string size)) (clen (length chars))) (do ((i 0 (+ i 1))) ((= i 10000000)) (let ((parens 0)) (do ((k 0 (+ k 1))) ((= k size)) (set! (str k) (chars (random clen))) (if (char=? (str k) #\() (set! parens (+ parens 1)) (if (char=? (str k) #\)) (begin (set! parens (- parens 1)) (if (negative? parens) (begin (set! (str k) #\space) (set! parens 0))))))) (let ((str1 str) (happy (char=? (str (- size 1)) #\)))) (if (> parens 0) (begin (set! str1 (make-string (+ size parens) #\))) (set! happy #t) (do ((k 0 (+ k 1))) ((= k size)) (set! (str1 k) (str k))))) (set! (-s7-symbol-table-locked?) #t) (if (and happy (not (char=? (str1 1) #\)))) (catch #t (lambda () (let ((num (eval-string str1))) (if (and (number? num) (eqv? num -1)) (format *stderr* "~S ~%" str1)))) (lambda args 'error))) (set! (-s7-symbol-table-locked?) #f)))))) |# (test (= 1 '+1 `+1 '`1 `01 ``1) #t) (test (''- 1) '-) (test (`'- 1) '-) (test (``- 1) '-) (test ('`- 1) '-) (test (''1 '1) 1) (test ((quote (quote 1)) 1) 1) ; (quote (quote 1)) -> ''1 = (list 'quote 1), so ((list 'quote 1) 1) is 1! (test (list 'quote 1) ''1) ; guile says #t (test (list-ref ''1 1) 1) ; same (test (''1 ```1) 1) (test (cond `'1) 1) (test ```1 1) (test ('''1 1 1) 1) (test (`',1 1) 1) (test (- `,-1) 1) ;;; some weirder cases... (test (begin . `''1) ''1) ;(test (`,@''1) 1) ; (syntax-error ("attempt to apply the ~A ~S to ~S?" "symbol" quote (1))) ?? ; (({apply_values} ''values 1)) got error but expected 1 ;(test (`,@ `'1) 1) ; (({apply_values} ''values 1)) got error but expected 1 ;(test (`,@''.'.) '.'.) ; (({apply_values} ''values .'.)) got error but expected .'. (if with-qq-vectors (begin (test #(`,1) #(1)) (test `#(,@'(1)) #(1)) (test `#(,`,@''1) #(quote 1)) (test `#(,@'(1 2 3)) #(1 2 3)) (test `#(,`,@'(1 2 3)) #(1 2 3)) ; but #(`,@'(1 2 3)) -> #(({apply_values} '(1 2 3))) (test `#(,`#(1 2 3)) #(#(1 2 3))) (test `#(,`#(1 ,(+ 2 3))) #(#(1 5))) (test (quasiquote #(,`#(1 ,(+ 2 3)))) #(#(1 5))) (test `#(,`#(1 ,(+ `,@'(2 3)))) #(#(1 5))) (test `#(1 `,,(+ 2 3)) #(1 5)))) (test (apply . `''1) 'error) ; '(quote quote 1)) ; (apply {list} 'quote ({list} 'quote 1)) -> ;quote: too many arguments '1 (test (apply - 1( )) -1) ; (apply - 1 ()) (num-test (apply - 1.()) -1.0) (num-test (apply - .1()) -0.1) (num-test (apply - .1 .(())) -0.1) (num-test (apply - .1 .('(1))) -0.9) (test (apply - -1()) 1) ; (apply - -1 ()) (test (apply . `(())) ()) ; (apply {list} ()) (test (apply . ''(1)) 1) ; (apply quote '(1)) (test (apply . '`(1)) 1) ; (apply quote ({list} 1)) (test (apply . `(,())) ()) ; (apply {list} ()) (test (apply . `('())) ''()) ; (apply {list} ({list} 'quote ())) (test (apply . `(`())) ()) ; (apply {list} ()) (test (apply - `,1()) -1) ; (apply - 1 ()) (test (apply - ``1()) -1) ; (apply - 1 ()) (test (apply ''1 1()) 1) ; (apply ''1 1 ()) (test (apply .(- 1())) -1) ; (apply - 1 ()) (test (apply - .(1())) -1) ; (apply - 1 ()) (test (apply . `(1())) '(1)) ; (apply {list} 1 ()) (test (apply . ''(())) ()) (test (apply . `((()))) '(())) ;;; comp.lang.lisp (test (with-input-from-string "(a `(aaa ,(/ 0.9)))" read) '(a ({list} 'aaa (/ 0.9)))) ;; make sure the macro funcs really are constants (test (defined? '{list}) #t) (test (let () (set! {list} 2)) 'error) (test (let (({list} 2)) {list}) 'error) ;(test (defined? '{apply}) #t) ;(test (let () (set! {apply} 2)) 'error) ;(test (let (({apply} 2)) {apply}) 'error) (test (defined? '{append}) #t) (test (let () (set! {append} 2)) 'error) (test (let (({append} 2)) {append}) 'error) (test (defined? '{multivector}) #t) (test (let () (set! {multivector} 2)) 'error) (test (let (({multivector} 2)) {multivector}) 'error) (if with-qq-vectors (begin (test (+ 1 ((`#(,(lambda () 0) ,(lambda () 2) ,(lambda () 4)) 1))) 3) ; this calls vector each time, just like using vector directly (test `#(,@(list 1 2 3)) #(1 2 3)) ; but #(,@(list 1 2 3)) -> #((unquote ({apply_values} (list 1 2 3)))) (test (+ 1 ((`(,(lambda () 0) ,(lambda () 2) ,(lambda () 4)) 1))) 3))) (test (object->string (list 'quote 1 2)) "(quote 1 2)") (test (object->string (list 'quote 'quote 1)) "(quote quote 1)") (test (object->string (list 'quote 1 2 3)) "(quote 1 2 3)") (test (object->string (list 'quote 1)) "'1") ; confusing but this is (quote 1) (test (equal? (quote 1) '1) #t) (test (equal? (list 'quote 1) ''1) #t) (test (equal? (list 'quote 1) '''1) #f) ;;; see comment s7.c in list_to_c_string -- we're following Clisp here (test (object->string (cons 'quote 1)) "(quote . 1)") (test (object->string (list 'quote)) "(quote)") (let ((lst (list 'quote 1))) (set! (cdr (cdr lst)) lst) (test (object->string lst) "#1=(quote 1 . #1#)")) (let ((lst (list 'quote))) (set! (cdr lst) lst) (test (object->string lst) "#1=(quote . #1#)")) (test (object->string quasiquote) "quasiquote") ;; from Guile mailing list -- just a bit strange, even confuses emacs! (if (not with-windows) (test (let ((v '(\()))) (and (pair? v) (symbol? (car v)) ; \ -> ((symbol "\\") ()) (null? (cadr v)))) #t)) (test #(,1) #(1)) (test #(,,,1) #(1)) (test #(`'`1) #(''1)) (test (',- 1) '-) ; this is implicit indexing #| (',,= 1) -> (unquote =) (test (equal? (car (',,= 1)) 'unquote) #t) ; but that's kinda horrible (',@1 1) -> ({apply_values} 1) #(,@1) -> #((unquote ({apply_values} 1))) (quasiquote #(,@(list 1 2 3))) -> #((unquote ({apply_values} (list 1 2 3)))) (quote ,@(for-each)) -> (unquote ({apply_values} (for-each))) ;;; when is (quote ...) not '...? |# (test (quasiquote) 'error) (test (quasiquote 1 2 3) 'error) (let ((d 1)) (test (quasiquote (a b c ,d)) '(a b c 1))) (test (let ((a 2)) (quasiquote (a ,a))) (let ((a 2)) `(a ,a))) (test (quasiquote 4) 4) (if (not (provided? 'immutable-unquote)) (test (quasiquote (list (unquote (+ 1 2)) 4)) '(list 3 4))) (test (quasiquote (1 2 3)) '(1 2 3)) (test (quasiquote ()) ()) (test (quasiquote (list ,(+ 1 2) 4)) '(list 3 4)) (test (quasiquote (1 ,@(list 1 2) 4)) '(1 1 2 4)) (test (quasiquote (a ,(+ 1 2) ,@(map abs '(4 -5 6)) b)) '(a 3 4 5 6 b)) (test (quasiquote (1 2 ,(* 9 9) 3 4)) '(1 2 81 3 4)) (test (quasiquote (1 ,(+ 1 1) 3)) '(1 2 3)) (test (quasiquote (,(+ 1 2))) '(3)) (test (quasiquote (,@'() . foo)) 'foo) (test (quasiquote (1 , 2)) '(1 2)) (test (quasiquote (,1 ,1)) '(1 1)) (test (quasiquote (,1 ,(quasiquote ,1))) '(1 1)) (test (quasiquote (,1 ,(quasiquote ,@(list 1)))) '(1 1)) (test (quasiquote (,1 ,(quasiquote ,(quasiquote ,1)))) '(1 1)) (test (quasiquote (,1 ,(quasiquote ,@'(1)))) '(1 1)) (test (quasiquote (,1 ,(quasiquote ,@(quasiquote (1))))) '(1 1)) (test (quasiquote (,1 ,(quasiquote ,@(quasiquote (,1))))) '(1 1)) (test (quasiquote (,1 ,@(quasiquote ,@(list (list 1))))) '(1 1)) (test `(+ ,(apply values '(1 2))) '(+ 1 2)) (if (not (provided? 'immutable-unquote)) (test `(apply + (unquote '(1 2))) '(apply + (1 2)))) (test (eval (list (list quasiquote +) -1)) -1) (test (apply quasiquote '((1 2 3))) '(1 2 3)) (test (quasiquote (',,= 1)) 'error) (test (quasiquote (',,@(1 2) 1)) 'error) (test (quasiquote 1.1 . -0) 'error) (test `(1 ,@2) 'error) (test `(1 ,@(2 . 3)) 'error) (test `(1 ,@(2 3)) 'error) (test `(1 , @ (list 2 3)) 'error) ; unbound @ ! (guile also) (test (call-with-exit quasiquote) 'error) (test (call-with-output-string quasiquote) "") (test (map quasiquote '(1 2 3)) '(1 2 3)) ; changed 12-May-14 (test (for-each quasiquote '(1 2 3)) #) (test (sort! '(1 2 3) quasiquote) 'error) (test (quasiquote . 1) 'error) (test (let ((x 3)) (quasiquote . x)) 'error) (when (not pure-s7) (num-test `,#e.1 1/10)) (num-test `,,,-1 -1) (num-test `,``,1 1) (test (equal? ` 1 ' 1) #t) (test (+ ` 1 ` 2) ` 3) (test ` ( + ,(- 3 2) 2) '(+ 1 2)) (test (quasiquote #(1)) `#(1)) (test `(+ ,@(map sqrt '(1 4 9)) 2) '(+ 1 2 3 2)) (test `(+ ,(sqrt 9) 4) '(+ 3 4)) (test `(+ ,(apply values (map sqrt '(1 4 9))) 2) '(+ 1 2 3 2)) ;; here is the difference between ,@ and apply values: (test (let ((x ())) `(+ ,@x)) '(+)) (test (let ((x ())) (+ (apply values x))) 'error) ; ;+ argument, #, is untyped (test (let ((x ())) (list + (apply values x))) (list + (values))) ;; (apply + ({list} ({apply_values} ()))) -> 0 -- this is a special quasiquote list handling of ,@ that ;; is not the same as (apply + ({list} (apply values ()))) -> error. quasiquote turns list into {list} ;; and {list} treats (apply values...) specially. Maybe s7 should be less timid about (values). I used to ;; think (abs -1 (values)) had to be an error, but now it looks fine. ;; ;; (let ((x ())) `(+ ,@x)) -> (+) ;; via (+ (unquote ({apply_values} x))) -> ({list} '+ ({apply_values} x)) ;; ;; (let ((x ())) (list + (apply values x))) -> (+ #) ;; via (+ (apply values (unquote x))) -> ({list} '+ ({list} 'apply 'values x)) ;; because (values) -> # but everywhere else ,@x is the same as (apply values x) ;;; -------------------------------------------------------------------------------- ;;; keywords ;;; -------------------------------------------------------------------------------- ;;; keyword? ;;; make-keyword ;;; keyword->symbol ;;; symbol->keyword (for-each (lambda (arg) (test (keyword? arg) #f)) (list "hi" -1 #\a 1 'a-symbol #(1 2 3) 3.14 3/4 1.0+1.0i #t #f () #(()) (list 1 2 3) '(1 . 2))) (test (cond ((cond (())) ':)) ':) (test (keyword? :#t) #t) (test (eq? #t :#t) #f) ;(test (keyword? '#:t) #f) ; these 2 are fooled by the Guile-related #: business (which is still supported) ;(test (keyword? '#:#t) #f) ;#:1.0e8 is also a keyword(!) ;#:# is also, so #:#() is interpreted as #:# () (test (keyword? :-1) #t) (test (keyword? :0/0) #t) (test (keyword? :1+i) #t) (test (keyword? :1) #t) (test (keyword? 0/0:) #t) (test (keyword? 1+i:) #t) (test (keyword? 1:) #t) ;;; bizarre... (test (keyword? (symbol ":#(1 #\\a (3))")) #t) (test (keyword? (make-keyword (object->string #(1 #\a (3)) #f))) #t) (test (keyword? begin) #f) (test (keyword? if) #f) (let ((kw (make-keyword "hiho"))) (test (keyword? kw) #t) (test (keyword->symbol kw) 'hiho) (test (symbol->keyword 'hiho) kw) (test (keyword->symbol (symbol->keyword 'key)) 'key) (test (symbol->keyword (keyword->symbol (make-keyword "hi"))) :hi) (test (keyword? :a-key) #t) (test (keyword? ':a-key) #t) (test (keyword? ':a-key:) #t) (test (keyword? 'a-key:) #t) (test (symbol? (keyword->symbol :hi)) #t) (test (keyword? (keyword->symbol :hi)) #f) (test (symbol? (symbol->keyword 'hi)) #t) (test (equal? kw :hiho) #t) (test ((lambda (arg) (keyword? arg)) :hiho) #t) (test ((lambda (arg) (keyword? arg)) 'hiho) #f) (test ((lambda (arg) (keyword? arg)) kw) #t) (test ((lambda (arg) (keyword? arg)) (symbol->keyword 'hiho)) #t) (test (make-keyword "3") :3) (test (keyword? :3) #t) (test (keyword? ':3) #t) (test (eq? (keyword->symbol :hi) (keyword->symbol hi:)) #t) (test (equal? :3 3) #f) (test (equal? (keyword->symbol :3) 3) #f) (test (equal? (symbol->value (keyword->symbol :3)) 3) #f) ; 3 as a symbol has value # #| (let () (apply define (symbol "3") '(32)) (test (symbol->value (symbol "3")) 32) ; hmmm (apply define (list (symbol "3") (lambda () 32))) (test (symbol->value (symbol "3")) 32) (apply define (symbol ".") '(123)) (test (+ (symbol->value (symbol ".")) 321) 444)) |# (test (keyword? '3) #f) (test (keyword? ':) #f) (test (keyword? '::) #t) (test (keyword? ::) #t) (test (keyword? ::a) #t) (test (eq? ::a ::a) #t) (test (eq? (keyword->symbol ::a) :a) #t) (test (eq? (symbol->keyword :a) ::a) #t) ; ?? -- :a is already a keyword (test (symbol->string ::a) "::a") (test ((lambda* (:a 32) ::a) 0) 'error) ; :a is a constant (test (eq? :::a::: :::a:::) #t) (test (keyword? a::) #t) (test (keyword->symbol ::) ':) (test (symbol->string (keyword->symbol hi:)) "hi") (test (symbol->string (keyword->symbol :hi)) "hi") (test (keyword? (make-keyword (string #\x (integer->char 128) #\x))) #t) (test (keyword? (make-keyword (string #\x (integer->char 200) #\x))) #t) (test (keyword? (make-keyword (string #\x (integer->char 255) #\x))) #t) (test (make-keyword ":") ::) (test (make-keyword (string #\")) (symbol ":\"")) (test (keyword? (make-keyword (string #\"))) #t) (test (keyword->symbol (make-keyword (string #\"))) (symbol "\"")) ) (test (symbol->keyword 'begin) :begin) (test (symbol->keyword 'quote) :quote) (test (symbol->keyword if) 'error) (test (symbol->keyword quote) 'error) (test (symbol->keyword :a) ::a) (test (keyword->symbol ::a) :a) (test (symbol->keyword (symbol "(a)")) (symbol ":(a)")) (test (keyword? (symbol ":(a)")) #t) (test (let ((:hi 3)) :hi) 'error) (test (set! :hi 2) 'error) (test (define :hi 3) 'error) (let ((strlen 8)) (let ((str (make-string strlen))) (do ((i 0 (+ i 1))) ((= i 10)) (do ((k 0 (+ k 1))) ((= k strlen)) (set! (str k) (integer->char (+ 1 (random 255))))) (let ((key (make-keyword str))) (let ((newstr (symbol->string (keyword->symbol key)))) (if (not (string=? newstr str)) (format-logged #t ";make-keyword -> string: ~S -> ~A -> ~S~%" str key newstr))))))) (let () (define* (hi a b) (+ a b)) (test (hi 1 2) 3) (test (hi :b 3 :a 1) 4) (test (hi b: 3 a: 1) 4)) (for-each (lambda (arg) (test (make-keyword arg) 'error)) (list -1 #\a 1 'a-symbol #(1 2 3) 3.14 3/4 1.0+1.0i #t #f () #(()) (list 1 2 3) '(1 . 2))) (for-each (lambda (arg) (test (keyword->symbol arg) 'error)) (list "hi" -1 #\a 1 'a-symbol #(1 2 3) 3.14 3/4 1.0+1.0i #t #f () #(()) (list 1 2 3) '(1 . 2))) (for-each (lambda (arg) (test (symbol->keyword arg) 'error)) (list "hi" -1 #\a 1 #(1 2 3) 3.14 3/4 1.0+1.0i #t #f () #(()) (list 1 2 3) '(1 . 2))) (test (keyword?) 'error) (test (keyword? 1 2) 'error) (test (make-keyword) 'error) (test (make-keyword 'hi 'ho) 'error) (test (keyword->symbol) 'error) (test (keyword->symbol :hi :ho) 'error) (test (symbol->keyword) 'error) (test (symbol->keyword 'hi 'ho) 'error) ;;; -------------------------------------------------------------------------------- ;;; gensym (for-each (lambda (arg) (test (gensym arg) 'error)) (list -1 #\a 1 'hi _ht_ _null_ _c_obj_ #(1 2 3) 3.14 3/4 1.0+1.0i #t #f () #(()) (list 1 2 3) '(1 . 2))) (test (gensym "hi" "ho") 'error) (test (symbol? (gensym)) #t) (test (symbol? (gensym "temp")) #t) (test (eq? (gensym) (gensym)) #f) (test (eqv? (gensym) (gensym)) #f) (test (equal? (gensym) (gensym)) #f) (test (keyword? (gensym)) #f) (test (let* ((a (gensym)) (b a)) (eq? a b)) #t) (test (let* ((a (gensym)) (b a)) (eqv? a b)) #t) (test (keyword? (symbol->keyword (gensym))) #t) (test (let ((g (gensym))) (set! g 12) g) 12) (test (->byte-vector (substring (symbol->string (gensym #u8(124 255 127))) 0 5)) #u8(123 124 255 127 125)) (test (->byte-vector (substring (symbol->string (gensym #u8(124 0 127))) 0 3)) #u8(123 124 125)) ; nul->end of symbol string (let ((sym (gensym))) (test (eval `(let ((,sym 32)) (+ ,sym 1))) 33)) (let ((sym1 (gensym)) (sym2 (gensym))) (test (eval `(let ((,sym1 32) (,sym2 1)) (+ ,sym1 ,sym2))) 33)) (test (eval (let ((var (gensym "a b c"))) `(let ((,var 2)) (+ ,var 1)))) 3) (test (eval (let ((var (gensym ""))) `(let ((,var 2)) (+ ,var 1)))) 3) (test (eval (let ((var (gensym "."))) `(let ((,var 2)) (+ ,var 1)))) 3) (test (eval (let ((var (gensym "{"))) `(let ((,var 2)) (+ ,var 1)))) 3) (test (eval (let ((var (gensym "}"))) `(let ((,var 2)) (+ ,var 1)))) 3) (test (eval (let ((var (gensym (string #\newline)))) `(let ((,var 2)) (+ ,var 1)))) 3) (test (let ((hi (gensym))) (eq? hi (string->symbol (symbol->string hi)))) #t) (test (let () (define-macro (hi a) (let ((var (gensym ";"))) `(let ((,var ,a)) (+ 1 ,var)))) (hi 1)) 2) (test (let () (define-macro (hi a) (let ((funny-name (string->symbol (string #\;)))) `(let ((,funny-name ,a)) (+ 1 ,funny-name)))) (hi 1)) 2) (test (let () (define-macro (hi a) (let ((funny-name (string->symbol "| e t c |"))) `(let ((,funny-name ,a)) (+ 1 ,funny-name)))) (hi 2)) 3) (let ((funny-name (string->symbol "| e t c |"))) (define-macro (hi a) `(define* (,a (,funny-name 32)) (+ ,funny-name 1))) (hi func) (test (func) 33) (test (func 1) 2) ;(procedure-source func) '(lambda* ((| e t c | 32)) (+ | e t c | 1)) (test (apply func (list (symbol->keyword funny-name) 2)) 3) ) (let ((funny-name (string->symbol "| e t c |"))) (apply define* `((func (,funny-name 32)) (+ ,funny-name 1))) (test (apply func (list (symbol->keyword funny-name) 2)) 3)) ;;; gensym? (for-each (lambda (arg) (test (gensym? arg) #f)) (list -1 #\a 1 #(1 2 3) 3.14 3/4 1.0+1.0i () car abs (lambda () 1) #2d((1 2) (3 4)) _ht_ _null_ _c_obj_ #f 'hi #(()) (list 1 2 3) '(1 . 2) "hi")) (test (gensym?) 'error) (let ((g (gensym))) (test (gensym? g) #t) (test (gensym? g g) 'error)) ;;; -------------------------------------------------------------------------------- ;;; provided? ;;; provide (test (provided?) 'error) (test (or (null? *features*) (pair? *features*)) #t) (test (provided? 1 2 3) 'error) (provide 's7test) (test (provided? 's7test) #t) (test (provided? 'not-provided!) #f) (test (provided? 'begin) #f) (test (provided? if) 'error) (test (provided? quote) 'error) (test (provide quote) 'error) (test (provide 1 2 3) 'error) (test (provide) 'error) (test (provide lambda) 'error) (provide 's7test) ; should be a no-op (let ((count 0)) (for-each (lambda (p) (if (eq? p 's7test) (set! count (+ count 1))) (if (not (provided? p)) (format-logged #t ";~A is in *features* but not provided? ~A~%" p *features*))) *features*) (if (not (= count 1)) (format-logged #t ";*features* has ~D 's7test entries? ~A~%" count *features*))) (test (let ((*features* 123)) (provided? 's7)) #t) (for-each (lambda (arg) (test (provide arg) 'error)) (list -1 #\a 1 #(1 2 3) 3.14 3/4 1.0+1.0i #t #f () #(()) (list 1 2 3) '(1 . 2))) (for-each (lambda (arg) (test (provided? arg) 'error)) (list -1 #\a 1 #(1 2 3) 3.14 3/4 1.0+1.0i #t #f () #(()) (list 1 2 3) '(1 . 2))) (for-each (lambda (arg) (test (set! (*s7* 'gc-stats) arg) 'error)) (list #\a #(1 2 3) 3.14 3/4 1.0+1.0i () #(()) (list 1 2 3) '(1 . 2))) (test (*s7* 'gc-stats) 0) (let ((f (sort! (copy *features*) (lambda (a b) (stringstring a #f) (object->string b #f)))))) (let ((last 'not-in-*features*)) (for-each (lambda (p) (if (eq? p last) (format-logged #t ";*features has multiple ~A? ~A~%" p *features*)) (set! last p)) f))) (let () (provide 'locals) (test (provided? 'locals) #t) (test (defined? 'locals) #t)) (test (provided? 'locals) #f) (test (defined? 'locals) #f) (let () (require stuff.scm) (test (provided? 'stuff.scm) #t)) (test (provided? 'stuff.scm) #f) (let () (provide 'local-stuff) (call-with-output-file tmp-output-file (lambda (p) (format p "(provide 'tmp-output)~%(define (tmp-output-func a) a)~%"))) (load tmp-output-file) (test (provided? 'tmp-output) #t)) (test (provided? 'local-stuff) #f) (test (provided? 'tmp-output) #t) (for-each (lambda (arg) (test (set! (*s7* 'safety) arg) 'error) (test (set! *features* arg) 'error) (test (set! *load-path* arg) 'error) (test (set! *#readers* arg) 'error) ) (list #\a #(1 2 3) 3.14 3/4 1.0+1.0i abs 'hi #t #f #(()))) ;(test (let ((*features* 123)) *features*) 'error) ;(test (let (((*s7* 'safety) '(1 2 3))) (*s7* 'safety)) 'error) ;(test (let (((*s7* 'safety) 1)) 2) 'error) (test (set! *load-path* (list 1 2 3)) 'error) (set! *#readers* old-readers) ;;; (*s7* 'print-length) (test (integer? (*s7* 'print-length)) #t) (test (or (null? *#readers*) (pair? *#readers*)) #t) (test (or (null? *load-path*) (pair? *load-path*)) #t) (let ((old-len (*s7* 'print-length))) (for-each (lambda (arg) (test (set! (*s7* 'print-length) arg) 'error)) (list -1 #\a #(1 2 3) 3.14 3/4 1.0+1.0i abs 'hi () #t #f #(()) (list 1 2 3) '(1 . 2))) (set! (*s7* 'print-length) old-len)) (let ((old-vlen (*s7* 'print-length))) (set! (*s7* 'print-length) 0) (test (format #f "~A" #()) "#()") (test (format #f "~A" #(1 2 3 4)) "#(...)") (set! (*s7* 'print-length) 1) (test (format #f "~A" #()) "#()") (test (format #f "~A" #(1)) "#(1)") (test (format #f "~A" #(1 2 3 4)) "#(1 ...)") (set! (*s7* 'print-length) 2) (test (format #f "~A" #(1 2 3 4)) "#(1 2 ...)") (set! (*s7* 'print-length) old-vlen)) (if with-bignums (let ((old-vlen (*s7* 'print-length))) (set! (*s7* 'print-length) (bignum "0")) (test (format #f "~A" #()) "#()") (test (format #f "~A" #(1 2 3 4)) "#(1 ...)") (set! (*s7* 'print-length) (bignum "1")) (test (format #f "~A" #()) "#()") (test (format #f "~A" #(1)) "#(1)") (test (format #f "~A" #(1 2 3 4)) "#(1 ...)") (set! (*s7* 'print-length) (bignum "2")) (test (format #f "~A" #(1 2 3 4)) "#(1 ...)") (set! (*s7* 'print-length) old-vlen))) ;;; -------------------------------------------------------------------------------- ;;; sort! (test (sort! '(2 3) <) '(2 3)) (test (sort! '(3 2) <) '(2 3)) (test (sort! '(12 3) <) '(3 12)) (test (sort! '(1 2 3) <) '(1 2 3)) (test (sort! '(1 3 2) <) '(1 2 3)) (test (sort! '(2 1 3) <) '(1 2 3)) (test (sort! '(2 3 1) <) '(1 2 3)) (test (sort! '(3 1 2) <) '(1 2 3)) (test (sort! '(3 2 1) <) '(1 2 3)) (test (sort! '(1 2 3) (lambda (a b) (> a b))) '(3 2 1)) (test (sort! #(2 3) <) #(2 3)) (test (sort! #(12 3) <) #(3 12)) (test (sort! #(1 2 3) <) #(1 2 3)) (test (sort! #(1 3 2) <) #(1 2 3)) (test (sort! #(2 1 3) <) #(1 2 3)) (test (sort! #(2 3 1) <) #(1 2 3)) (test (sort! #(3 1 2) <) #(1 2 3)) (test (sort! #(3 2 1) <) #(1 2 3)) (test (sort! #(1 2 3 4) <) #(1 2 3 4)) (test (sort! #(1 2 4 3) <) #(1 2 3 4)) (test (sort! #(1 3 2 4) <) #(1 2 3 4)) (test (sort! #(1 3 4 2) <) #(1 2 3 4)) (test (sort! #(1 4 2 3) <) #(1 2 3 4)) (test (sort! #(1 4 3 2) <) #(1 2 3 4)) (test (sort! #(2 1 3 4) <) #(1 2 3 4)) (test (sort! #(2 1 4 3) <) #(1 2 3 4)) (test (sort! #(2 3 4 1) <) #(1 2 3 4)) (test (sort! #(2 3 1 4) <) #(1 2 3 4)) (test (sort! #(2 4 3 1) <) #(1 2 3 4)) (test (sort! #(2 4 1 3) <) #(1 2 3 4)) (test (sort! #(3 1 2 4) <) #(1 2 3 4)) (test (sort! #(3 1 4 2) <) #(1 2 3 4)) (test (sort! #(3 2 4 1) <) #(1 2 3 4)) (test (sort! #(3 2 1 4) <) #(1 2 3 4)) (test (sort! #(3 4 1 2) <) #(1 2 3 4)) (test (sort! #(3 4 2 1) <) #(1 2 3 4)) (test (sort! #(4 1 2 3) <) #(1 2 3 4)) (test (sort! #(4 1 3 2) <) #(1 2 3 4)) (test (sort! #(4 2 1 3) <) #(1 2 3 4)) (test (sort! #(4 2 3 1) <) #(1 2 3 4)) (test (sort! #(4 3 2 1) <) #(1 2 3 4)) (test (sort! #(4 3 1 2) <) #(1 2 3 4)) (let ((f (lambda (a b) (< (car a) (car b))))) (test (sort! (list (cons 1 "1") (cons 2 "2") (cons 3 "3") (cons 4 "4")) f) (list (cons 1 "1") (cons 2 "2") (cons 3 "3") (cons 4 "4"))) (test (sort! (list (cons 1 "1") (cons 2 "2") (cons 4 "4") (cons 3 "3")) f) (list (cons 1 "1") (cons 2 "2") (cons 3 "3") (cons 4 "4"))) (test (sort! (list (cons 1 "1") (cons 3 "3") (cons 2 "2") (cons 4 "4")) f) (list (cons 1 "1") (cons 2 "2") (cons 3 "3") (cons 4 "4"))) (test (sort! (list (cons 1 "1") (cons 3 "3") (cons 4 "4") (cons 2 "2")) f) (list (cons 1 "1") (cons 2 "2") (cons 3 "3") (cons 4 "4"))) (test (sort! (list (cons 1 "1") (cons 4 "4") (cons 2 "2") (cons 3 "3")) f) (list (cons 1 "1") (cons 2 "2") (cons 3 "3") (cons 4 "4"))) (test (sort! (list (cons 1 "1") (cons 4 "4") (cons 3 "3") (cons 2 "2")) f) (list (cons 1 "1") (cons 2 "2") (cons 3 "3") (cons 4 "4"))) (test (sort! (list (cons 2 "2") (cons 1 "1") (cons 3 "3") (cons 4 "4")) f) (list (cons 1 "1") (cons 2 "2") (cons 3 "3") (cons 4 "4"))) (test (sort! (list (cons 2 "2") (cons 1 "1") (cons 4 "4") (cons 3 "3")) f) (list (cons 1 "1") (cons 2 "2") (cons 3 "3") (cons 4 "4"))) (test (sort! (list (cons 2 "2") (cons 3 "3") (cons 4 "4") (cons 1 "1")) f) (list (cons 1 "1") (cons 2 "2") (cons 3 "3") (cons 4 "4"))) (test (sort! (list (cons 2 "2") (cons 3 "3") (cons 1 "1") (cons 4 "4")) f) (list (cons 1 "1") (cons 2 "2") (cons 3 "3") (cons 4 "4"))) (test (sort! (list (cons 2 "2") (cons 4 "4") (cons 3 "3") (cons 1 "1")) f) (list (cons 1 "1") (cons 2 "2") (cons 3 "3") (cons 4 "4"))) (test (sort! (list (cons 2 "2") (cons 4 "4") (cons 1 "1") (cons 3 "3")) f) (list (cons 1 "1") (cons 2 "2") (cons 3 "3") (cons 4 "4"))) (test (sort! (list (cons 3 "3") (cons 1 "1") (cons 2 "2") (cons 4 "4")) f) (list (cons 1 "1") (cons 2 "2") (cons 3 "3") (cons 4 "4"))) (test (sort! (list (cons 3 "3") (cons 1 "1") (cons 4 "4") (cons 2 "2")) f) (list (cons 1 "1") (cons 2 "2") (cons 3 "3") (cons 4 "4"))) (test (sort! (list (cons 3 "3") (cons 2 "2") (cons 4 "4") (cons 1 "1")) f) (list (cons 1 "1") (cons 2 "2") (cons 3 "3") (cons 4 "4"))) (test (sort! (list (cons 3 "3") (cons 2 "2") (cons 1 "1") (cons 4 "4")) f) (list (cons 1 "1") (cons 2 "2") (cons 3 "3") (cons 4 "4"))) (test (sort! (list (cons 3 "3") (cons 4 "4") (cons 1 "1") (cons 2 "2")) f) (list (cons 1 "1") (cons 2 "2") (cons 3 "3") (cons 4 "4"))) (test (sort! (list (cons 3 "3") (cons 4 "4") (cons 2 "2") (cons 1 "1")) f) (list (cons 1 "1") (cons 2 "2") (cons 3 "3") (cons 4 "4"))) (test (sort! (list (cons 4 "4") (cons 1 "1") (cons 2 "2") (cons 3 "3")) f) (list (cons 1 "1") (cons 2 "2") (cons 3 "3") (cons 4 "4"))) (test (sort! (list (cons 4 "4") (cons 1 "1") (cons 3 "3") (cons 2 "2")) f) (list (cons 1 "1") (cons 2 "2") (cons 3 "3") (cons 4 "4"))) (test (sort! (list (cons 4 "4") (cons 2 "2") (cons 1 "1") (cons 3 "3")) f) (list (cons 1 "1") (cons 2 "2") (cons 3 "3") (cons 4 "4"))) (test (sort! (list (cons 4 "4") (cons 2 "2") (cons 3 "3") (cons 1 "1")) f) (list (cons 1 "1") (cons 2 "2") (cons 3 "3") (cons 4 "4"))) (test (sort! (list (cons 4 "4") (cons 3 "3") (cons 2 "2") (cons 1 "1")) f) (list (cons 1 "1") (cons 2 "2") (cons 3 "3") (cons 4 "4"))) (test (sort! (list (cons 4 "4") (cons 3 "3") (cons 1 "1") (cons 2 "2")) f) (list (cons 1 "1") (cons 2 "2") (cons 3 "3") (cons 4 "4")))) (test (sort! #(5 1 2 3 4) <) #(1 2 3 4 5)) (test (sort! #(5 1 2 4 3) <) #(1 2 3 4 5)) (test (sort! #(5 1 3 2 4) <) #(1 2 3 4 5)) (test (sort! #(5 1 3 4 2) <) #(1 2 3 4 5)) (test (sort! #(5 1 4 2 3) <) #(1 2 3 4 5)) (test (sort! #(5 1 4 3 2) <) #(1 2 3 4 5)) (test (sort! #(5 2 1 3 4) <) #(1 2 3 4 5)) (test (sort! #(5 2 1 4 3) <) #(1 2 3 4 5)) (test (sort! #(5 2 3 4 1) <) #(1 2 3 4 5)) (test (sort! #(5 2 3 1 4) <) #(1 2 3 4 5)) (test (sort! #(5 2 4 3 1) <) #(1 2 3 4 5)) (test (sort! #(5 2 4 1 3) <) #(1 2 3 4 5)) (test (sort! #(5 3 1 2 4) <) #(1 2 3 4 5)) (test (sort! #(5 3 1 4 2) <) #(1 2 3 4 5)) (test (sort! #(5 3 2 4 1) <) #(1 2 3 4 5)) (test (sort! #(5 3 2 1 4) <) #(1 2 3 4 5)) (test (sort! #(5 3 4 1 2) <) #(1 2 3 4 5)) (test (sort! #(5 3 4 2 1) <) #(1 2 3 4 5)) (test (sort! #(5 4 1 2 3) <) #(1 2 3 4 5)) (test (sort! #(5 4 1 3 2) <) #(1 2 3 4 5)) (test (sort! #(5 4 2 1 3) <) #(1 2 3 4 5)) (test (sort! #(5 4 2 3 1) <) #(1 2 3 4 5)) (test (sort! #(5 4 3 2 1) <) #(1 2 3 4 5)) (test (sort! #(5 4 3 1 2) <) #(1 2 3 4 5)) (test (sort! #(1 5 2 3 4) <) #(1 2 3 4 5)) (test (sort! #(1 5 2 4 3) <) #(1 2 3 4 5)) (test (sort! #(1 5 3 2 4) <) #(1 2 3 4 5)) (test (sort! #(1 5 3 4 2) <) #(1 2 3 4 5)) (test (sort! #(1 5 4 2 3) <) #(1 2 3 4 5)) (test (sort! #(1 5 4 3 2) <) #(1 2 3 4 5)) (test (sort! #(2 5 1 3 4) <) #(1 2 3 4 5)) (test (sort! #(2 5 1 4 3) <) #(1 2 3 4 5)) (test (sort! #(2 5 3 4 1) <) #(1 2 3 4 5)) (test (sort! #(2 5 3 1 4) <) #(1 2 3 4 5)) (test (sort! #(2 5 4 3 1) <) #(1 2 3 4 5)) (test (sort! #(2 5 4 1 3) <) #(1 2 3 4 5)) (test (sort! #(3 5 1 2 4) <) #(1 2 3 4 5)) (test (sort! #(3 5 1 4 2) <) #(1 2 3 4 5)) (test (sort! #(3 5 2 4 1) <) #(1 2 3 4 5)) (test (sort! #(3 5 2 1 4) <) #(1 2 3 4 5)) (test (sort! #(3 5 4 1 2) <) #(1 2 3 4 5)) (test (sort! #(3 5 4 2 1) <) #(1 2 3 4 5)) (test (sort! #(4 5 1 2 3) <) #(1 2 3 4 5)) (test (sort! #(4 5 1 3 2) <) #(1 2 3 4 5)) (test (sort! #(4 5 2 1 3) <) #(1 2 3 4 5)) (test (sort! #(4 5 2 3 1) <) #(1 2 3 4 5)) (test (sort! #(4 5 3 2 1) <) #(1 2 3 4 5)) (test (sort! #(4 5 3 1 2) <) #(1 2 3 4 5)) (test (sort! #(1 2 5 3 4) <) #(1 2 3 4 5)) (test (sort! #(1 2 5 4 3) <) #(1 2 3 4 5)) (test (sort! #(1 3 5 2 4) <) #(1 2 3 4 5)) (test (sort! #(1 3 5 4 2) <) #(1 2 3 4 5)) (test (sort! #(1 4 5 2 3) <) #(1 2 3 4 5)) (test (sort! #(1 4 5 3 2) <) #(1 2 3 4 5)) (test (sort! #(2 1 5 3 4) <) #(1 2 3 4 5)) (test (sort! #(2 1 5 4 3) <) #(1 2 3 4 5)) (test (sort! #(2 3 5 4 1) <) #(1 2 3 4 5)) (test (sort! #(2 3 5 1 4) <) #(1 2 3 4 5)) (test (sort! #(2 4 5 3 1) <) #(1 2 3 4 5)) (test (sort! #(2 4 5 1 3) <) #(1 2 3 4 5)) (test (sort! #(3 1 5 2 4) <) #(1 2 3 4 5)) (test (sort! #(3 1 5 4 2) <) #(1 2 3 4 5)) (test (sort! #(3 2 5 4 1) <) #(1 2 3 4 5)) (test (sort! #(3 2 5 1 4) <) #(1 2 3 4 5)) (test (sort! #(3 4 5 1 2) <) #(1 2 3 4 5)) (test (sort! #(3 4 5 2 1) <) #(1 2 3 4 5)) (test (sort! #(4 1 5 2 3) <) #(1 2 3 4 5)) (test (sort! #(4 1 5 3 2) <) #(1 2 3 4 5)) (test (sort! #(4 2 5 1 3) <) #(1 2 3 4 5)) (test (sort! #(4 2 5 3 1) <) #(1 2 3 4 5)) (test (sort! #(4 3 5 2 1) <) #(1 2 3 4 5)) (test (sort! #(4 3 5 1 2) <) #(1 2 3 4 5)) (test (sort! #(1 2 3 5 4) <) #(1 2 3 4 5)) (test (sort! #(1 2 4 5 3) <) #(1 2 3 4 5)) (test (sort! #(1 3 2 5 4) <) #(1 2 3 4 5)) (test (sort! #(1 3 4 5 2) <) #(1 2 3 4 5)) (test (sort! #(1 4 2 5 3) <) #(1 2 3 4 5)) (test (sort! #(1 4 3 5 2) <) #(1 2 3 4 5)) (test (sort! #(2 1 3 5 4) <) #(1 2 3 4 5)) (test (sort! #(2 1 4 5 3) <) #(1 2 3 4 5)) (test (sort! #(2 3 4 5 1) <) #(1 2 3 4 5)) (test (sort! #(2 3 1 5 4) <) #(1 2 3 4 5)) (test (sort! #(2 4 3 5 1) <) #(1 2 3 4 5)) (test (sort! #(2 4 1 5 3) <) #(1 2 3 4 5)) (test (sort! #(3 1 2 5 4) <) #(1 2 3 4 5)) (test (sort! #(3 1 4 5 2) <) #(1 2 3 4 5)) (test (sort! #(3 2 4 5 1) <) #(1 2 3 4 5)) (test (sort! #(3 2 1 5 4) <) #(1 2 3 4 5)) (test (sort! #(3 4 1 5 2) <) #(1 2 3 4 5)) (test (sort! #(3 4 2 5 1) <) #(1 2 3 4 5)) (test (sort! #(4 1 2 5 3) <) #(1 2 3 4 5)) (test (sort! #(4 1 3 5 2) <) #(1 2 3 4 5)) (test (sort! #(4 2 1 5 3) <) #(1 2 3 4 5)) (test (sort! #(4 2 3 5 1) <) #(1 2 3 4 5)) (test (sort! #(4 3 2 5 1) <) #(1 2 3 4 5)) (test (sort! #(4 3 1 5 2) <) #(1 2 3 4 5)) (test (sort! #(1 2 3 4 5) <) #(1 2 3 4 5)) (test (sort! #(1 2 4 3 5) <) #(1 2 3 4 5)) (test (sort! #(1 3 2 4 5) <) #(1 2 3 4 5)) (test (sort! #(1 3 4 2 5) <) #(1 2 3 4 5)) (test (sort! #(1 4 2 3 5) <) #(1 2 3 4 5)) (test (sort! #(1 4 3 2 5) <) #(1 2 3 4 5)) (test (sort! #(2 1 3 4 5) <) #(1 2 3 4 5)) (test (sort! #(2 1 4 3 5) <) #(1 2 3 4 5)) (test (sort! #(2 3 4 1 5) <) #(1 2 3 4 5)) (test (sort! #(2 3 1 4 5) <) #(1 2 3 4 5)) (test (sort! #(2 4 3 1 5) <) #(1 2 3 4 5)) (test (sort! #(2 4 1 3 5) <) #(1 2 3 4 5)) (test (sort! #(3 1 2 4 5) <) #(1 2 3 4 5)) (test (sort! #(3 1 4 2 5) <) #(1 2 3 4 5)) (test (sort! #(3 2 4 1 5) <) #(1 2 3 4 5)) (test (sort! #(3 2 1 4 5) <) #(1 2 3 4 5)) (test (sort! #(3 4 1 2 5) <) #(1 2 3 4 5)) (test (sort! #(3 4 2 1 5) <) #(1 2 3 4 5)) (test (sort! #(4 1 2 3 5) <) #(1 2 3 4 5)) (test (sort! #(4 1 3 2 5) <) #(1 2 3 4 5)) (test (sort! #(4 2 1 3 5) <) #(1 2 3 4 5)) (test (sort! #(4 2 3 1 5) <) #(1 2 3 4 5)) (test (sort! #(4 3 2 1 5) <) #(1 2 3 4 5)) (test (sort! #(4 3 1 2 5) <) #(1 2 3 4 5)) (test (sort! #(3 1 2 1 4 1) <) #(1 1 1 2 3 4)) (test (sort! #(1 1 1) <) #(1 1 1)) (test (sort! #(1 2 3) (lambda (a b) (> a b))) #(3 2 1)) (test (equal? (sort! (list 3 4 8 2 0 1 5 9 7 6) <) (list 0 1 2 3 4 5 6 7 8 9)) #t) (test (equal? (sort! (list 3 4 8 2 0 1 5 9 7 6) (lambda (a b) (< a b))) (list 0 1 2 3 4 5 6 7 8 9)) #t) (test (equal? (sort! (list) <) ()) #t) (test (equal? (sort! (list 1) <) '(1)) #t) (test (equal? (sort! (list 1 1 1) <) '(1 1 1)) #t) (test (equal? (sort! (list 0 1 2 3 4 5 6 7 8 9) <) '(0 1 2 3 4 5 6 7 8 9)) #t) (test (equal? (sort! (list #\a #\l #\o #\h #\a) char) (reverse (list 0 1 2 3 4 5 6 7 8 9))) #t) (test (equal? (sort! '((3 . 1) (2 . 8) (5 . 9) (4 . 7) (6 . 0)) (lambda (a b) (< (car a) (car b)))) '((2 . 8) (3 . 1) (4 . 7) (5 . 9) (6 . 0))) #t) (test (equal? (sort! '((3 . 1) (2 . 8) (5 . 9) (4 . 7) (6 . 0)) (lambda (a b) (< (cdr a) (cdr b)))) '((6 . 0) (3 . 1) (4 . 7) (2 . 8) (5 . 9))) #t) (test (equal? (sort! (list (list 1 2) (list 4 3 2) (list) (list 1 2 3 4)) (lambda (a b) (> (length a) (length b)))) '((1 2 3 4) (4 3 2) (1 2) ())) #t) (test (equal? (sort! '((1 2 3) (4 5 6) (7 8 9)) (lambda (a b) (> (car a) (car b)))) '((7 8 9) (4 5 6) (1 2 3))) #t) (test (equal? (sort! (list #\b #\A #\B #\a #\c #\C) char) <) '(1 2 3)) #t) (test (sort! #2d((1 2) (3 4)) >) #2D((4 3) (2 1))) ; ?!? (test (sort! #2d((1 4) (3 2)) >) #2D((4 3) (2 1))) ; ??!!?? this is not what anyone would expect (test (sort! '(3 2 1) (lambda (a b c) #f)) 'error) (test (sort! '(3 2 1) (lambda* (a b c) (< a b))) '(1 2 3)) (test (sort! '(3 2 1) (lambda (a b . c) (< a b))) '(1 2 3)) (test (sort! '(3 2 1) (lambda (a) #f)) 'error) (test (sort! '(3 2 1) (lambda* (a) #f)) 'error) (test (sort! '(3 1 2 4) (lambda args (< (car args) (cadr args)))) '(1 2 3 4)) (test (sort! (rootlet) <) 'error) (test (sort! () #f) 'error) (test (equal? (sort! (vector 3 4 8 2 0 1 5 9 7 6) <) (vector 0 1 2 3 4 5 6 7 8 9)) #t) (test (equal? (sort! (make-vector 3 0 #t) (lambda* (a b) (< a b))) (make-vector 3 0 #t)) #t) (test (equal? (sort! (make-vector 3 1.0 #t) >) (float-vector 1.0 1.0 1.0)) #t) (test (morally-equal? (let ((v (make-vector 3 0 #t))) (set! (v 1) 3) (set! (v 2) -1) (sort! v <)) #(-1 0 3)) #t) (test (morally-equal? (let ((v (make-vector 3 0 #t))) (set! (v 1) 3) (set! (v 2) -1) (sort! v (lambda (a b) (< a b)))) #(-1 0 3)) #t) (test (morally-equal? (let ((v (make-vector 3 0 #t))) (set! (v 1) 3) (set! (v 2) -1) (sort! v (lambda* (a b) (< a b)))) #(-1 0 3)) #t) (test (equal? (sort! #() <) #()) #t) (test (sort! '(1 2 . 3) <) 'error) (test (sort! #(1 3 8 7 5 6 4 2) (lambda (a b) (if (even? a) (or (odd? b) (< a b)) (and (odd? b) (< a b))))) #(2 4 6 8 1 3 5 7)) (let ((ninf (real-part (log 0.0))) (pinf (- (real-part (log 0.0))))) (test (sort! (list pinf 0.0 ninf) <) (list ninf 0.0 pinf))) (test (sort! '(1 1 1) <) '(1 1 1)) (test (call/cc (lambda (return) (sort! '(1 2 3) (lambda (a b) (return "oops"))))) "oops") ; segfault outside s7test.scm?? (let ((p1 (dilambda (lambda (a b) (< a b)) (lambda (a b) (error 'oops))))) (test (sort! '(3 1 2 4) p1) '(1 2 3 4))) (let ((p1 (dilambda (lambda* (a (b 2)) (< a b)) (lambda (a b) (error 'oops))))) (test (sort! '(3 1 2 4) p1) '(1 2 3 4))) (let ((p1 (dilambda (lambda args (< (car args) (cadr args))) (lambda (a b) (error 'oops))))) (test (sort! '(3 1 2 4) p1) '(1 2 3 4))) (test (let ((v (make-float-vector 1000))) (do ((i 0 (+ i 1))) ((= i 1000)) (float-vector-set! v i (random 100.0))) (set! v (sort! v >)) (call-with-exit (lambda (return) (do ((i 0 (+ i 1))) ((= i 999) #t) (if (< (v i) (v (+ i 1))) (begin (format-logged #t "random vals after sort: ~A ~A~%" (v i) (v (+ i 1))) (return #f))))))) #t) (let ((v ())) (do ((i 0 (+ i 1))) ((= i 1000)) (set! v (cons (random 100.0) v))) (set! v (sort! v >)) (if (not (apply >= v)) (format-logged #t ";sort!: v not sorted by >: ~A~%" ))) (test (sort! (list 3 2 1) (lambda (m n) (let ((vals (sort! (list m n) <))) (< m n)))) '(1 2 3)) (test (let ((lst ())) (do ((i 0 (+ i 1))) ((= i 4)) (set! lst (cons (random 1.0) lst))) (let ((vals (sort! lst (lambda (m n) (let ((lst1 (list 1 2 3))) (sort! lst1 <)) (< m n))))) (apply < vals))) #t) (let ((v (make-vector 8))) (do ((i 0 (+ i 1))) ((= i 10)) (do ((k 0 (+ k 1))) ((= k 8)) (set! (v k) (- (random 1.0) 0.5))) (let ((v1 (copy v))) (sort! v <) (if (not (apply < (vector->list v))) (format-logged #t ";(sort! ~A <) -> ~A?" v1 v))))) (test (sort!) 'error) (test (sort! '(1 2 3) < '(3 2 1)) 'error) (test (sort! '(1 2 3)) 'error) (test (sort! '(1 2 3) 1) 'error) (test (sort! '(1 2 3) < <) 'error) (test (sort! (cons 3 2) <) 'error) (test (sort! (list 1 0+i) <) 'error) (test (sort! (list "hi" "ho") <) 'error) (test (sort! '(1 2 #t) <) 'error) (test (sort! '(1 2 . #t) <) 'error) (test (sort! '(#\c #\a #\b) <) 'error) (test (sort! (begin) if) 'error) (test (let ((v #(1 2 3))) (let ((v1 (sort! v >))) (eq? v v1))) #t) (test (let ((v (float-vector 1 2 3))) (let ((v1 (sort! v >))) (eq? v v1))) #t) (test (let ((v (make-vector 3 0 #t))) (let ((v1 (sort! v >))) (eq? v v1))) #t) (test (let ((v #u8(0 1 2))) (let ((v1 (sort! v >))) (eq? v v1))) #t) (test (let ((v (list 0 1 2))) (let ((v1 (sort! v >))) (eq? v v1))) #t) (test (let ((v "012")) (let ((v1 (sort! v char>?))) (eq? v v1))) #t) (test (let ((v "adcb")) (sort! v char>?) v) "dcba") (test (let ((v "adcb")) (sort! v <) v) 'error) (test (let ((v "adecb")) (sort! v char)) #u8(3 2 1 0)) (test (let ((v #u8(3 0 1 2))) (sort! v char>?) v) 'error) (test (let ((v #u8(3))) (sort! v >) v) #u8(3)) (test (let ((v #u8(3 1))) (sort! v <) v) #u8(1 3)) (test (let ((v #u8())) (sort! v <) v) #u8()) (test (let ((v #u8(1 4 3 2 0))) (sort! v (lambda (a b) (< a b)))) #u8(0 1 2 3 4)) (test (let ((v #("123" "321" "132" "432" "0103" "123"))) (sort! v string>?)) #("432" "321" "132" "123" "123" "0103")) (test (sort! (list) <) ()) (test (sort! (vector) <) #()) (test (sort! (list #\a) <) '(#\a)) ; I guess this is reasonable (test (sort! (list #("hi")) <) '(#("hi"))) (test (sort! (append (sort! (append (sort! () <) ()) <) ()) <) ()) (test (sort! (append (sort! (append (sort! '(1 2) <) '(1 2)) <) '(1 2)) <) '(1 1 1 2 2 2)) (test (let ((lst (list 3 1 12 4 1))) (sort! lst (lambda (a b) (let ((val (map (lambda (n) (+ n 1)) (list a b)))) (apply < val))))) '(1 1 3 4 12)) (test (sort! '(#\c #\a #\b) (lambda (a b) (string) (< a b))) ov) #(2 1 0)) (for-each (lambda (arg) (test (sort! arg <) 'error) (test (sort! () arg) 'error)) (list -1 #\a 1 0 "hiho" (make-hash-table) :hi 'a-symbol 3.14 3/4 1.0+1.0i #f #t)) (for-each (lambda (arg) (test (sort! '(1 2 3) arg) 'error)) (list -1 #\a 1 0 'a-symbol 3.14 3/4 1.0+1.0i #f #t #(1) '(1) "hi" abs :hi)) (test (sort! '(1 2 "hi" 3) <) 'error) (test (sort! '(1 -2 "hi" 3) (lambda (a b) (let ((a1 (if (number? a) a (length a))) (b1 (if (number? b) b (length b)))) (< a1 b1)))) '(-2 1 "hi" 3)) (let ((ok #f)) (catch #t (lambda () (dynamic-wind (lambda () #f) (lambda () (sort! '(1 2 "hi" 3) <)) (lambda () (set! ok #t)))) (lambda args 'error)) (if (not ok) (format-logged #t "dynamic-wind out of sort! skipped cleanup?~%"))) (test (let ((v (float-vector 1 2 3))) (sort! v (lambda (a b) (call-with-exit (lambda (r) (> a b))))) v) (float-vector 3 2 1)) (test (let ((v (int-vector 1 2 3))) (sort! v (lambda (a b) (call-with-exit (lambda (r) (> a b))))) v) (int-vector 3 2 1)) (test (let ((v (list 1 2 3))) (sort! v (lambda (a b) (call-with-exit (lambda (r) (> a b))))) v) (list 3 2 1)) (test (let ((v "123")) (sort! v (lambda (a b) (call-with-exit (lambda (r) (char>? a b))))) v) "321") (test (let ((v #u8(1 2 3))) (sort! v (lambda (a b) (call-with-exit (lambda (r) (> a b))))) v) #u8(3 2 1)) (let ((lst (list 1 2 3 9 8 7))) (let ((val (catch #t (lambda () (sort! (copy lst) (lambda (a b) (if (< a b) (error 'sort-error "a < b")) #t))) (lambda args (car args))))) (if (not (eq? val 'sort-error)) (format-logged #t ";sort! with error: ~A~%" val))) (let ((val (call-with-exit (lambda (return) (sort! (copy lst) (lambda (a b) (if (< a b) (return 'sort-error)) #t)))))) (if (not (eq? val 'sort-error)) (format-logged #t ";sort! call-with-exit: ~A~%" val))) (let ((val (call/cc (lambda (return) (sort! (copy lst) (lambda (a b) (if (< a b) (return 'sort-error)) #t)))))) (if (not (eq? val 'sort-error)) (format-logged #t ";sort! call/cc: ~A~%" val))) ) (let ((old-safety (*s7* 'safety))) (set! (*s7* 'safety) 1) (test (sort! #(1 2 3) (lambda (a b) (and #t (= a b)))) 'error) ;(test (* 524288 19073486328125) 'error) ; maybe someday... (set! (*s7* 'safety) old-safety)) ;;; -------------------------------------------------------------------------------- ;;; catch (define (catch-test sym) (let ((errs ())) (catch 'a1 (lambda () (catch 'a2 (lambda () (catch 'a3 (lambda () (catch 'a4 (lambda () (error sym "hit error!")) (lambda args (set! errs (cons 'a4 errs)) 'a4))) (lambda args (set! errs (cons 'a3 errs)) 'a3))) (lambda args (set! errs (cons 'a2 errs)) 'a2))) (lambda args (set! errs (cons 'a1 errs)) 'a1)) errs)) (test (catch-test 'a1) '(a1)) (test (catch-test 'a2) '(a2)) (test (catch-test 'a3) '(a3)) (test (catch-test 'a4) '(a4)) (define (catch-test-1 sym) (let ((errs ())) (catch 'a1 (lambda () (catch 'a2 (lambda () (catch 'a3 (lambda () (catch 'a4 (lambda () (error sym "hit error!")) (lambda args (set! errs (cons 'a4 errs)) (error 'a3) 'a4))) (lambda args (set! errs (cons 'a3 errs)) (error 'a2) 'a3))) (lambda args (set! errs (cons 'a2 errs)) (error 'a1) 'a2))) (lambda args (set! errs (cons 'a1 errs)) 'a1)) errs)) (test (catch-test-1 'a1) '(a1)) (test (catch-test-1 'a2) '(a1 a2)) (test (catch-test-1 'a3) '(a1 a2 a3)) (test (catch-test-1 'a4) '(a1 a2 a3 a4)) (test (catch #t (catch #t (lambda () (lambda () 1)) (lambda args 'oops)) (lambda args 'error)) 1) (test (catch #t (catch #t (lambda () (error 'oops)) (lambda args (lambda () 1))) (lambda args 'error)) 1) (test ((catch #t (lambda () (error 'oops)) (lambda args (lambda () 1)))) 1) (test ((catch #t (lambda () (error 'oops)) (catch #t (lambda () (lambda args (lambda () 1))) (lambda args 'error)))) 1) (test (catch #t (dynamic-wind (lambda () #f) (lambda () (lambda () 1)) (lambda () #f)) (lambda args 'error)) 1) (test (dynamic-wind (catch #t (lambda () (lambda () #f)) (lambda args 'error)) (lambda () 1) (lambda () #f)) 1) (test (dynamic-wind ((lambda () (lambda () #f))) (lambda () 1) (((lambda () (lambda () (lambda () #t)))))) 1) (test (catch #t ((lambda () (lambda () 1))) (lambda b a)) 1) (test (map (catch #t (lambda () abs) abs) '(-1 -2 -3)) '(1 2 3)) (test (catch + (((lambda () lambda)) () 1) +) 1) ;(test (catch #t + +) 'error) ; changed 12-May-14 (test (string? (catch + s7-version +)) #t) (test (string? (apply catch + s7-version (list +))) #t) (test (catch #t (lambda () (catch '#t (lambda () (error '#t)) (lambda args 1))) (lambda args 2)) 1) (test (catch #t (lambda () (catch "hi" (lambda () (error "hi")) (lambda args 1))) (lambda args 2)) 2) ; guile agrees with this (test (let ((str (list 1 2))) (catch #t (lambda () (catch str (lambda () (error str)) (lambda args 1))) (lambda args 2))) 1) (test (let () (abs (catch #t (lambda () -1) (lambda args 0)))) 1) ;(test (let ((e #f)) (catch #t (lambda () (+ 1 "asdf")) (lambda args (set! e (owlet)))) (eq? e (owlet))) #t) (test (+ (catch 'oops (lambda () (error 'oops)) (lambda args (values 1 2 3)))) 6) (test (catch #t (lambda () (error 1 2 3)) (lambda* ((a 2) (b 3) (c 4)) (list a b c))) '(1 (2 3) 4)) ;;; various catch macros from s7.html (let () (define-macro (catch-all . body) `(catch #t (lambda () ,@body) (lambda args args))) (let ((val (catch-all (+ 1 asdf)))) (test (car val) 'syntax-error) (let ((x 32)) (test (catch-all (set! x (+ x 1)) (* x 2)) 66) (test (car (catch-all (string=? x "hi"))) 'wrong-type-arg)))) (let () (define-macro (catch-case clauses . body) (let ((base `(lambda () ,@body))) (for-each (lambda (clause) (let ((tag (car clause))) (set! base `(lambda () (catch ',(if (eq? tag 'else) #t tag) ,base ,@(cdr clause)))))) clauses) (caddr base))) (test (catch-case ((wrong-type-arg (lambda args (format #t "got a bad arg~%") -1)) (division-by-zero (lambda args 0)) (else (lambda args 123))) (abs -1)) 1) (test (catch-case ((wrong-type-arg (lambda args (format #t "got a bad arg~%") -1)) (division-by-zero (lambda args 0)) (else (lambda args 123))) (let ((x 0)) (/ 32 x))) 0) (test (catch-case ((wrong-type-arg (lambda args -1)) (division-by-zero (lambda args 0)) (else (lambda args 123))) (abs "hi")) -1) (test (catch-case ((wrong-type-arg (lambda args (format #t "got a bad arg~%") -1)) (division-by-zero (lambda args 0)) (else (lambda args 123))) (throw 'oops -1)) 123)) (let () (define (catch-if test func err) (catch #t func (lambda args (if (test (car args)) (apply err args) (apply throw args))))) ; if not caught, re-raise the error (test (catch #t (lambda () (catch-if (lambda (tag) (eq? tag 'oops)) (lambda () (error 'oops 123)) (lambda args 32))) (lambda args 47)) 32) (test (catch #t (lambda () (catch-if (lambda (tag) (eq? tag 'oops)) (lambda () (error 'err 123)) (lambda args 32))) (lambda args (car args))) 'err) (define (catch-member lst func err) (catch-if (lambda (tag) (member tag lst)) func err)) (test (catch-member '(oops err) (lambda () (error 'oops)) (lambda args 47)) 47)) (let () (define-macro (catch* clauses . error) (define (builder lst) (if (null? lst) (apply values error) `(catch #t (lambda () ,(car lst)) (lambda args ,(builder (cdr lst)))))) (builder clauses)) (test (catch* ((+ 1 2) (- 3 4)) 'error) 3) (test (catch* ((+ 1 "hi") (- 3 4)) 'error) -1) (test (catch* ((+ 1 "hi") (- 3 #\a)) 'error) 'error)) (multiple-value-bind (err-type err-data) (call-with-exit (lambda (return) (catch #t (lambda () _asdf_) return))) (test err-type 'syntax-error) (test err-data '("~A: unbound variable" _asdf_))) (test (catch #t (lambda () _asdf_) "asdf") 'error) (when with-block (test (catch #t (lambda () _asdf_) blocks) '(syntax-error ("~A: unbound variable" _asdf_)))) ;;; since catch is a function, everything is evaluated: (test (catch (#(0 #t 1) 1) ((lambda (a) (lambda () (+ a "asdf"))) 1) ((lambda (b) (lambda args (format #f "got: ~A" b))) 2)) "got: 2") (let () (define (hi c) (catch c ((lambda (a) (lambda () (+ a "asdf"))) 1) ((lambda (b) (lambda args (format #f "got: ~A" b))) 2))) (test (hi #t) "got: 2")) (test (catch (#(0 #t 1) 1) (values ((lambda (a) (lambda () (+ a "asdf"))) 1) ((lambda (b) (lambda args (format #f "got: ~A" b))) 2))) "got: 2") (let ((x 0)) (catch #t (lambda () (catch #t (lambda () (+ 1 __asdf__)) (lambda args (set! x (+ x 1)) (+ 1 __asdf__)))) (lambda args (set! x (+ x 1)))) (test x 2)) (test (let ((x 0)) (catch 'a (lambda () (catch 'b (lambda () (catch 'a (lambda () (error 'a)) (lambda args (set! x 1)))) (lambda args (set! x 2)))) (lambda args (set! x 3))) x) 1) (test (+ (catch #t (lambda () (values 3 4)) (lambda args (values 1 2 3)))) 7) (test (catch) 'error) (test (catch s7-version) 'error) (test (catch #t s7-version) 'error) (test (catch #t s7-version + +) 'error) (let () (define* (f1 a) a) (define (f2 . args) args) (define* (f3) 1) (define* (f4 (a 1) (b 2)) a) (test (catch #t s7-version f2) (s7-version)) (test (catch #t f1 f2) #f) (test (catch #t f3 f2) 1) (test (catch #t f4 f2) 1) (define (f5 a) a) (test (catch #t f5 (lambda args 'local-error)) 'local-error)) (test (let () (define-macro (m) `(+ 1 2)) (catch #t m (lambda any any))) 3) ;(test (let () (define-macro (m) `(define __asdf__ 3)) (catch #t m (lambda any "__asdf__ must be a constant?"))) '__asdf__) ;25-Jul-14 (test (let () (define-macro* (m (a 1) (b 2)) `(define __asdf__ (+ ,a ,b))) (catch #t m (lambda any any)) __asdf__) 3) ;;; so this is useful where we want to call a macro that defines something in the current environment, ;;; but might hit some error that we want to catch. (test (let () (define-macro (m . args) `(display ,args)) (catch #t (lambda () #f) m)) #f) (test (let () (define-macro (m . args) (apply (car args) (cadr args))) (catch #t (lambda () (error abs -1)) m)) 1) (test (let () (define-macro (m . args) `(apply ,(car args) ',(cadr args))) (catch #t (lambda () (error abs -1)) m)) 1) ;;; throw (define (catch-test sym) (let ((errs ())) (catch 'a1 (lambda () (catch 'a2 (lambda () (catch 'a3 (lambda () (catch 'a4 (lambda () (throw sym "hit error!")) (lambda args (set! errs (cons 'a4 errs)) 'a4))) (lambda args (set! errs (cons 'a3 errs)) 'a3))) (lambda args (set! errs (cons 'a2 errs)) 'a2))) (lambda args (set! errs (cons 'a1 errs)) 'a1)) errs)) (test (catch-test 'a1) '(a1)) (test (catch-test 'a2) '(a2)) (test (catch-test 'a3) '(a3)) (test (catch-test 'a4) '(a4)) (define (catch-test-1 sym) (let ((errs ())) (catch 'a1 (lambda () (catch 'a2 (lambda () (catch 'a3 (lambda () (catch 'a4 (lambda () (throw sym "hit error!")) (lambda args (set! errs (cons 'a4 errs)) (throw 'a3) 'a4))) (lambda args (set! errs (cons 'a3 errs)) (throw 'a2) 'a3))) (lambda args (set! errs (cons 'a2 errs)) (throw 'a1) 'a2))) (lambda args (set! errs (cons 'a1 errs)) 'a1)) errs)) (test (catch-test-1 'a1) '(a1)) (test (catch-test-1 'a2) '(a1 a2)) (test (catch-test-1 'a3) '(a1 a2 a3)) (test (catch-test-1 'a4) '(a1 a2 a3 a4)) (test (catch #t (catch #t (lambda () (throw 'oops)) (lambda args (lambda () 1))) (lambda args 'error)) 1) (test ((catch #t (lambda () (throw 'oops)) (lambda args (lambda () 1)))) 1) (test ((catch #t (lambda () (throw 'oops)) (catch #t (lambda () (lambda args (lambda () 1))) (lambda args 'error)))) 1) (test (catch #t (lambda () (catch '#t (lambda () (throw '#t)) (lambda args 1))) (lambda args 2)) 1) (test (catch #t (lambda () (catch "hi" (lambda () (throw "hi")) (lambda args 1))) (lambda args 2)) 2) ; guile agrees with this (test (let ((str (list 1 2))) (catch #t (lambda () (catch str (lambda () (throw str)) (lambda args 1))) (lambda args 2))) 1) (test (throw) 'error) (test (catch #f (lambda () (throw #f 1 2 3)) (lambda args (cadr args))) '(1 2 3)) (for-each (lambda (arg) (catch #t (lambda () (test (catch arg (lambda () (throw arg 1 2 3)) (lambda args (cadr args))) '(1 2 3))) (lambda args (format-logged #t "~A not caught~%" (car args))))) (list #\a 'a-symbol #f #t abs #)) (test (let ((e #f)) (catch #t (lambda () (catch #t (lambda () (+ 1 "asdf")) (lambda args (set! e (let->list (owlet)))))) (lambda args #f)) (equal? e (let->list (owlet)))) #t) (let ((e 1)) (catch #t (lambda () (catch #t (lambda () (error 'an-error "an-error")) (lambda args (set! e (let->list (owlet))))) (throw #t "not an error")) (lambda args #f)) (test (equal? e (let->list (owlet))) #t)) (let () (define (t1 x) (catch #t (lambda () (throw x)) (lambda args (car args)))) (define (tt) (do ((i 0 (+ i 1))) ((= i 100) i) (t1 'a))) (test (tt) 100)) ;;; -------------------------------------------------------------------------------- ;;; error (test (catch #t (lambda () (error 'oops 1)) (let () (lambda args (caadr args)))) 1) (test (catch #t (lambda () (error 'oops 1)) (let ((x 3)) (lambda args (+ x (caadr args))))) 4) (test (catch #t (let () (lambda () (error 'oops 1))) (let ((x 3)) (lambda args (+ x (caadr args))))) 4) (test (catch #t (let ((x 2)) (lambda () (error 'oops x))) (let ((x 3)) (lambda args (+ x (caadr args))))) 5) (test (catch #t (let ((x 2)) ((lambda () (lambda () (error 'oops x))))) (let ((x 3)) (lambda args (+ x (caadr args))))) 5) (test (let ((pws (dilambda (lambda () (+ 1 2)) (lambda (a) (+ a 2))))) (catch #t pws (lambda (tag type) tag))) 3) (test (let ((pws (dilambda (lambda () (error 'pws 3) 4) (lambda (a) (+ a 2))))) (catch #t pws (lambda (tag type) tag))) 'pws) (test (let ((pws (dilambda (lambda (a b) a) (lambda (a b) (+ a 2))))) (catch #t (lambda () (error 'pws-error 3)) pws)) 'pws-error) (for-each (lambda (tag) (let ((val (catch tag (lambda () (error tag "an error") 123) (lambda args (car args))))) (if (not (equal? tag val)) (format-logged #t ";catch ~A -> ~A~%" tag val)))) (list :hi () #() # #f #t # car #\a 32 9/2)) (for-each (lambda (tag) (let ((val (catch #t (lambda () (error tag "an error") 123) (lambda args (car args))))) (if (not (equal? tag val)) (format-logged #t ";catch #t (~A) -> ~A~%" tag val)))) (list :hi () # #f #t # car #\a 32 9/2 '(1 2 3) '(1 . 2) #(1 2 3) #())) (for-each (lambda (tag) (test (catch #t tag (lambda args 'local-error)) 'local-error) (test (catch #t (lambda () #f) tag) 'error)) (list :hi () # #f #t # #\a 32 9/2)) ;'(1 2 3) '(1 . 2) #(1 2 3) #() ;; (error ...) throws 'no-catch which makes it harder to check (let ((val (catch #t (lambda () (error "hi") 123) (lambda args (car args))))) (if (not (eq? val 'no-catch)) (format-logged #t ";catch #t, tag is string -> ~A~%" val))) (for-each (lambda (tag) (let ((val (catch tag (lambda () (error #t "an error") 123) (lambda args (car args))))) (if (not (equal? #t val)) (format-logged #t ";catch ~A -> ~A (#t)~%" tag val)))) (list :hi () # #f #t # car #\a 32 9/2)) (let ((tag 'tag)) (test (catch (let () tag) (lambda () (set! tag 123) (error 'tag "tag") tag) (lambda args (car args))) 'tag)) (let () (define (check-reerror x) (catch #t (lambda () (define (our-func x) (case x ((0) (error 'zero)) ((1) (error 'one)) (else (error 'else)))) (catch #t (lambda () (our-func x)) (lambda args (if (eq? (car args) 'one) (our-func (+ x 1)) (apply error args))))) (lambda args (let ((type (car args))) (case type ((zero) 0) ((one) 1) (else 2)))))) (test (check-reerror 0) 0) (test (check-reerror 1) 2) (test (check-reerror 2) 2)) (test (catch 'hiho (lambda () (define (f1 a) (error 'hiho a)) (* 2 (catch 'hiho (lambda () (f1 3)) (lambda args (caadr args))))) (lambda args (caadr args))) 6) (test (let () (define (f1 a) (error 'hiho a)) (catch 'hiho (lambda () (* 2 (catch 'hiho (lambda () (f1 3)) (lambda args (caadr args))))) (lambda args (caadr args)))) 6) (test (catch 'hiho (lambda () (let ((f1 (catch 'hiho (lambda () (lambda (a) (error 'hiho 3))) (lambda args args)))) (f1 3))) (lambda args (caadr args))) 3) (test (error) 'error) (test (let ((x 1)) (let ((val (catch #\a (lambda () (set! x 0) (error #\a "an error") (set! x 2)) (lambda args (if (equal? (car args) #\a) (set! x (+ x 3))) x)))) (= x val 3))) #t) (test (let ((x 1)) (let ((val (catch 32 (lambda () (catch #\a (lambda () (set! x 0) (error #\a "an error: ~A" (error 32 "another error!")) (set! x 2)) (lambda args (if (equal? (car args) #\a) (set! x (+ x 3))) x))) (lambda args (if (equal? (car args) 32) (set! x (+ x 30))))))) (= x val 30))) #t) ;;; -------------------------------------------------------------------------------- (define (last-pair l) ; needed also by loop below (if (pair? (cdr l)) (last-pair (cdr l)) l)) (let () ;; from guile-user I think ;; (block LABEL FORMS...) ;; ;; Execute FORMS. Within FORMS, a lexical binding named LABEL is ;; visible that contains an escape function for the block. Calling ;; the function in LABEL with a single argument will immediatly stop ;; the execution of FORMS and return the argument as the value of the ;; block. If the function in LABEL is not invoked, the value of the ;; block is the value of the last form in FORMS. (define-macro (block label . forms) `(let ((body (lambda (,label) ,@forms)) (tag (gensym "return-"))) (catch tag (lambda () (body (lambda (val) (throw tag val)))) (lambda (tag val) val)))) ;; (with-return FORMS...) ;; ;; Equivalent to (block return FORMS...) (define-macro (with-return . forms) `(block return ,@forms)) ;; (tagbody TAGS-AND-FORMS...) ;; ;; TAGS-AND-FORMS is a list of either tags or forms. A TAG is a ;; symbol while a FORM is everything else. Normally, the FORMS are ;; executed sequentially. However, control can be transferred to the ;; forms following a TAG by invoking the tag as a function. That is, ;; within the FORMS, there is a lexical binding for each TAG with the ;; symbol that is the tag as its name. The bindings carry functions ;; that will execute the FORMS following the respective TAG. ;; ;; The value of a tagbody is always `#f'. (define (transform-tagbody forms) (let ((start-tag (gensym "start-")) (block-tag (gensym "block-"))) (let loop ((cur-tag start-tag) (cur-code ()) (tags-and-code ()) (forms forms)) (cond ((null? forms) `(block ,block-tag (letrec ,(reverse! (cons (list cur-tag `(lambda () ,@(reverse! (cons `(,block-tag #f) cur-code)))) tags-and-code)) (,start-tag)))) ((symbol? (car forms)) (loop (car forms) '() (cons (list cur-tag `(lambda () ,@(reverse! (cons `(,(car forms)) cur-code)))) tags-and-code) (cdr forms))) (else (loop cur-tag (cons (car forms) cur-code) tags-and-code (cdr forms))))))) (define-macro (tagbody . forms) (transform-tagbody forms)) (define (first_even l) (with-return (tagbody continue (if (not (not (null? l))) (break)) (let ((e (car l))) (if (not (number? e)) (break)) (if (even? e) (return e)) (set! l (cdr l))) (continue) break) (return #f))) (let ((val (first_even '(1 3 5 6 7 8 9)))) (if (not (equal? val (list 6))) (format-logged #t "first_even (tagbody, gensym, reverse!) (6): '~A~%" val))) ) #| so prog is something like (define-macro (prog vars . body) `(with-return (tagbody (let ,vars ,@body)))) or better (define-macro (prog vars . body) `(call-with-exit (lambda (return) (tagbody (let ,vars ,@body))))) |# ;;; -------------------------------------------------------------------------------- ;;; define* ;;; lambda* (let ((hi (lambda* (a) a))) (test (hi 1) 1) (test (hi) #f) ; all args are optional (test (hi :a 32) 32) ; all args are keywords (test (hi 1 2) 'error) ; extra args (for-each (lambda (arg) (test (hi arg) arg) (test (hi :a arg) arg)) (list -1 #\a 1 #(1 2 3) 3.14 3/4 1.0+1.0i () 'hi abs #(()) (list 1 2 3) '(1 . 2))) (test (hi :b 1) 'error)) (let ((hi (lambda* ((a 1)) a))) (test (hi 2) 2) (test (hi) 1) (test (hi :a 2) 2) (for-each (lambda (arg) (test (hi arg) arg) (test (hi :a arg) arg)) (list -1 #\a 1 #(1 2 3) 3.14 3/4 1.0+1.0i () 'hi abs #(()) (list 1 2 3) '(1 . 2)))) (let ((hi (lambda* (a (b "hi")) (list a b)))) (test (hi) (list #f "hi")) (test (hi 1) (list 1 "hi")) (test (hi 1 2) (list 1 2)) (test (hi :b 1) (list #f 1)) (test (hi :a 1) (list 1 "hi")) (test (hi 1 :b 2) (list 1 2)) (test (hi :b 3 :a 1) (list 1 3)) (test (hi :a 3 :b 1) (list 3 1)) (test (hi 1 :a 3) 'error) (test (hi 1 2 :a 3) 'error) ; trailing (extra) args (test (hi :a 2 :c 1) 'error) (test (hi 1 :c 2) 'error) (for-each (lambda (arg) (test (hi :a 1 :b arg) (list 1 arg)) (test (hi :a arg) (list arg "hi")) (test (hi :b arg) (list #f arg)) (test (hi arg arg) (list arg arg))) (list -1 #\a 1 #(1 2 3) 3.14 3/4 1.0+1.0i () 'hi abs #(()) (list 1 2 3) '(1 . 2)))) (let ((hi (lambda* (a (b 3) c) (list a b c)))) (test (hi) (list #f 3 #f)) (test (hi 1) (list 1 3 #f)) (test (hi :c 32) (list #f 3 32)) (test (hi :c 32 :b 43 :a 54) (list 54 43 32)) (test (hi 1 2 3) (list 1 2 3)) (test (hi :b 32) (list #f 32 #f)) (test (hi 1 2 :c 32) (list 1 2 32))) (let ((hi (lambda* (a :rest b) (list a b)))) (test (hi 1 2 3) (list 1 (list 2 3))) (test (hi) (list #f ())) (test (hi :a 2) (list 2 ())) (test (hi :b 3) (list #f 3))) (let ((hi (lambda* (a :rest b :rest c) (list a b c)))) (test (hi 1 2 3 4 5) (list 1 (list 2 3 4 5) (list 3 4 5)))) (let ((hi (lambda* ((a 3) (b #t) (c pi) :rest d) (list a b c d)))) (test (hi) (list 3 #t pi ())) (test (hi 1 2 3 4) (list 1 2 3 (list 4)))) (let ((hi (lambda* ((a 'hi)) (equal? a 'hi)))) (test (hi) #t) (test (hi 1) #f) (test (hi 'hi) #t) (test (hi :a 1) #f)) (let* ((x 32) (hi (lambda* (a (b x)) (list a b)))) (test (hi) (list #f 32)) (test (hi :a 1) (list 1 32))) (let ((hi (lambda* (a . b) (list a b)))) (test (hi 1 2 3) (list 1 (list 2 3))) (test (hi) (list #f ())) (test (hi :a 2) (list 2 ())) (test (hi :b 3) (list #f 3))) (let ((hi (lambda* ((a 0.0) (b 0.0)) (+ a b)))) (num-test (hi 1.0) 1.0) (num-test (hi 1.0 2.0) 3.0) (num-test (hi) 0.0) (num-test (+ (hi) (hi 1.0) (hi 1.0 2.0)) 4.0) (num-test (+ (hi 1.0) (hi) (hi 1.0 2.0)) 4.0) (num-test (+ (hi 1.0) (hi 1.0 2.0) (hi)) 4.0) (num-test (+ (hi 1.0 2.0) (hi) (hi 1.0)) 4.0)) (test (let ((hi (lambda*))) (hi)) 'error) (test (let ((hi (lambda* #f))) (hi)) 'error) (test (let ((hi (lambda* "hi" #f))) (hi)) 'error) (test (let ((hi (lambda* ("hi") #f))) (hi)) 'error) (test (let ((hi (lambda* (a 0.0) a))) (hi)) 'error) (test (let ((hi (lambda* (a . 0.0) a))) (hi)) 'error) (test (let ((hi (lambda* ((a . 0.0)) a))) (hi)) 'error) (test (let ((hi (lambda* ((a 0.0 "hi")) a))) (hi)) 'error) (test (let ((hi (lambda* ((a 0.0 . "hi")) a))) (hi)) 'error) (test (let ((hi (lambda* ((a)) a))) (hi)) 'error) (test (let ((hi (lambda* (a 0.0) (b 0.0) (+ a b)))) (hi)) 'error) (test (lambda (:key) 1) 'error) (test (let () (define hi (let ((x 1)) (lambda* ((y x)) y))) (hi)) 1) (test (let () (define hi (let ((x 1)) (lambda* ((y x)) y))) (let ((x 2)) (hi))) 1) (test ((lambda* (:key) 1)) 'error) (test (let ((akey :a) (bkey :b)) ((lambda* (a b) (list a b)) akey 32)) '(32 #f)) (test (let ((akey :a) (bkey :b)) ((lambda* (a b) (list a b)) bkey 12 akey 43)) '(43 12)) (test (let ((x 0)) (for-each (lambda* (a) (set! x (+ x a))) (list :a :a :a) (list 1 2 3)) x) 'error) (test (let () (define* (hi) 0) (hi)) 0) (test (let () (define* (hi) 0) (hi 1)) 'error) (test (let () (define* (hi a . b) b) (hi 1 2 3)) '(2 3)) (test (let () (define* (hi a . b) b) (hi :a 1 2 3)) '(2 3)) (test (let () (define* (hi a . b) b) (hi 1)) ()) (test (let () (define* (hi a . b) b) (hi :a 1)) ()) (test (let () (define* (hi a . b) b) (hi)) ()) (test (let () (define* (hi a . a) a) (hi)) 'error) (test (let () (define* (hi (a 1) . a) a) (hi)) 'error) (test (let () (define* (hi (a 1) . b) b) (hi 2 3 4)) '(3 4)) (test (let () (define* (hi a :rest b) b) (hi 1 2 3)) '(2 3)) (test (let () (define* (hi a :rest b) b) (hi :a 1 2 3)) '(2 3)) (test (let () (define* (hi a :rest b) b) (hi 1)) ()) (test (let () (define* (hi a :rest b) b) (hi :a 1)) ()) (test (let () (define* (hi a :rest b) b) (hi)) ()) (test (let () (define* (hi (a 1) . b) b) (hi 1 2 3)) '(2 3)) (test (let () (define* (hi a (b 22) . c) (list a b c)) (hi)) '(#f 22 ())) (test (let () (define* (hi a (b 22) . c) (list a b c)) (hi :a 1)) '(1 22 ())) (test (let () (define* (hi a (b 22) . c) (list a b c)) (hi :b 1)) '(#f 1 ())) (test (let () (define* (hi a (b 22) . c) (list a b c)) (hi :c 1)) '(#f 22 1)) (test (let () (define* (hi a (b 22) . c) (list a b c)) (hi :a 1 2)) '(1 2 ())) (test (let () (define* (hi a (b 22) . c) (list a b c)) (hi :b 1 2 3)) 'error) ; b set twice (test (let () (define* (hi a (b 22) . c) (list a b c)) (hi :c 1 2 3)) '(#f 2 (3))) (test (let () (define* (hi a (b 22) . c) (list a b c)) (hi :b 1 :a 2 3)) '(2 1 (3))) (test (let () (define* (hi (a 1) :allow-other-keys) a) (hi)) 1) (test (let () (define* (hi (a 1) :allow-other-keys) a) (hi :b :a :a 3)) 3) (test (let () (define* (hi (a 1) :allow-other-keys) a) (hi :b 3)) 1) (test (let () (define* (hi (a 1) :allow-other-keys) a) (hi :a 3)) 3) (test (let () (define* (hi (a 1) :allow-other-keys) a) (hi a: 3)) 3) (test (let () (define* (hi (a 1) :allow-other-keys) a) (hi 3)) 3) (test (let () (define* (hi (a 1) :allow-other-keys) a) (hi 3 :b 2)) 3) (test (let () (define* (hi (a 1) :allow-other-keys) a) (hi :c 1 :a 3 :b 2)) 3) (test (let () (define* (hi :rest a :allow-other-keys) a) (hi :c 1 :a 3 :b 2)) '(:c 1 :a 3 :b 2)) (test (let () (define* (hi (a 1) (b 2) :allow-other-keys :allow-other-keys) a)) 'error) (test (let () (define* (hi (a 1) :allow-other-keys) a) (hi :a 2 32)) 'error) (test (let () (define* (hi (a 1) :allow-other-keys) a) (hi 2 32)) 'error) (test (let () (define* (hi (a 1) :rest c :allow-other-keys) (list a c)) (hi :a 3 :b 2)) '(3 (:b 2))) (test (let () (define* (hi (a 1) :rest c) (list a c)) (hi :a 3 :b 2)) '(3 (:b 2))) (test (let () (define* (hi (a 1) (b 2) :allow-other-keys) (list a b)) (hi :c 21 :b 2)) '(1 2)) (test (let () (define hi (lambda* ((a 1) (b 2) :allow-other-keys) (list a b))) (hi :c 21 :b 2)) '(1 2)) (test (let () (define-macro* (hi (a 1) (b 2) :allow-other-keys) `(list ,a ,b)) (hi :c 21 :b 2)) '(1 2)) (test (let () (define* (f1 :allow-other-keys) 123) (f1 :a 1 :b 2)) 'error) (test (let ((f1 (lambda* (:allow-other-keys) 123))) (f1 :a 1 :b 2)) 'error) (let () (define* (f1 a :allow-other-keys) :allow-other-keys) (test (keyword? (f1 3)) #t) (test (eq? (f1) ':allow-other-keys) #t) (test (keyword? :allow-other-keys) #t)) (test (keyword? :allow-other-keys) #t) (test (eq? :allow-other-keys ':allow-other-keys) #t) (test (keyword? :rest) #t) (test (eq? :rest ':rest) #t) (test (let () (define* (f (a :b)) a) (list (f) (f 1) (f :c) (f :a :c) (f :a 1) (f))) '(:b 1 :c :c 1 :b)) (test (let () (define* (f a (b :c)) b) (f :b 1 :d)) 'error) (test ((lambda* (:rest (b 1)) b)) 'error) ; "lambda* :rest parameter can't have a default value." ? (test ((lambda* ((a 1) (b 2)) ((lambda* ((c (+ a (* b 3)))) c)))) 7) (test ((lambda* ((a 1) (b 2)) ((lambda* ((c (+ a (* b 3)))) c))) :b 3) 10) (test (let ((a 123)) ((lambda* ((a 1) (b 2)) ((lambda* ((c (+ a (* b 3)))) c))) :b a)) 370) (test (let ((a 123)) ((lambda* ((a 1) (b 2)) ((lambda* ((c (+ a (let ((a -2)) (* b a))))) c))))) -3) (test (let ((a 123)) ((lambda* ((a 1) (b 2)) ((lambda* ((c (+ (let ((a -2)) (* b a)) a))) c))))) -3) (test (let ((a 123)) ((lambda* ((a 1) (b 2)) ((lambda* ((c (+ (let ((a 0)) (/ b a)) a))) c))))) 'error) (test ((lambda* ((c (call/cc (lambda (return) (return 3))))) c)) 3) (test ((lambda* ((a (do ((i 0 (+ i 1)) (sum 0)) ((= i 3) sum) (set! sum (+ sum i))))) (+ a 100))) 103) (test ((lambda* ((a (do ((i 0 (+ i 1)) (sum 0)) ((= i 3) sum) (set! sum (+ sum i)))) b) (+ a b)) 1 2) 3) ;; some of these are questionable (test ((lambda* ((x (lambda () 1))) (x))) 1) (test ((lambda* ((x x) else) (+ x else)) 1 2) 3) ; this has fluctuated between 3 and 'error (unbound variable 'x) (test (symbol? ((lambda* ((y y)) y))) 'error) ; this used to be #t but now y is undefined (test ((lambda* (:allow-other-keys) 34) :a 32) 'error) (test ((lambda* ((y x) =>) (list y =>)) 1 2) '(1 2)) ; was also 'error (test ((lambda* (=> (y x)) (list y =>)) 1) 'error) ; used to be '(x 1)) (test ((lambda* ((y #2D((1 2) (3 4)))) (y 1 0))) 3) (test ((lambda* ((y (symbol "#(1 #\\a (3))")) x) -1)) -1) (test ((lambda* ((y (symbol "#(1 #\\a (3))")) x) y)) (symbol "#(1 #\\a (3))")) (test ((lambda* ((y #(1 #\a (3)))) (y 0))) 1) (test ((lambda* ((y ()) ()) y)) 'error) (test ((lambda* ((y ()) (x)) y)) 'error) (test ((lambda* ((=> "") else) else) else) #f) (test ((lambda* (x (y x)) y) 1) 1) ; was #f (test ((lambda* (x (y x)) (let ((x 32)) y)) 1) 1) ; was #f (test ((lambda* ((x 1) (y x)) y)) 1) (test ((lambda* ((x 1) (y (+ x 1))) y)) 2) (test ((lambda* ((x y) (y x)) y)) 'error) ; used to be 'y (test (let ((z 2)) ((lambda* ((x z) (y x)) y))) 2) ; hmmm (test (keyword? ((lambda* ((x :-)) x))) #t) (test ((apply lambda* (list (list (list (string->symbol "a") 1)) (string->symbol "a"))) (symbol->keyword (string->symbol "a")) 3) 3) (test ((lambda* (:allow-other-keys) 1) :a 321) 'error) (test ((lambda* (:rest (a 1)) a)) 'error) (test ((lambda* (:rest a) a)) ()) (test ((lambda* (:rest (a 1)) 1)) 'error) (test (let ((b 2)) ((lambda* (:rest (a (let () (set! b 3) 4))) b))) 'error) (test (let ((b 2)) ((lambda* ((a (let () (set! b 3) 4))) b))) 3) (test ((lambda* (:rest hi :allow-other-keys (x x)) x)) 'error) (test ((lambda* (:rest x y) (list x y)) 1 2 3) '((1 2 3) 2)) (test ((lambda* (:rest '((1 2) (3 4)) :rest (y 1)) 1)) 'error) (test ((lambda* (:rest (list (quote (1 2) (3 4))) :rest (y 1)) 1)) 'error) (test ((lambda* ((x ((list 1 2) 1))) x)) 2) (test ((lambda* ((y ("hi" 0))) y)) #\h) (test ((lambda* ((x ((lambda* ((x 1)) x)))) x)) 1) (test ((lambda* (:rest) 3)) 'error) (test ((lambda* (:rest 1) 3)) 'error) (test ((lambda* (:rest :rest) 3)) 'error) (test ((lambda* ((: 1)) :)) 1) (test ((lambda* ((: 1)) :) :: 21) 21) (test ((lambda* ((a 1)) a) a: 21) 21) (test ((lambda* ((a 1)) a) :a: 21) 'error) (test (let ((func (let ((a 3)) (lambda* ((b (+ a 1))) b)))) (let ((a 21)) (func))) 4) (test (let ((a 21)) (let ((func (lambda* ((b (+ a 1))) b))) (let ((a 3)) (func)))) 22) (test (let ((a 21)) (begin (define-macro* (func (b (+ a 1))) b) (let ((a 3)) (func)))) 4) (test ((lambda* (:rest x :allow-other-keys y) x) 1) 'error) (test ((lambda* (:allow-other-keys x) x) 1) 'error) (test ((lambda* (:allow-other-keys . x) x) 1 2) 'error) (test ((lambda* (:rest . (x)) x) 1 2) '(1 2)) (test ((lambda* (:rest . (x 1)) x) 1 2) 'error) (test ((lambda* (:rest . (x)) x)) ()) (test ((lambda* x x) 1) '(1)) (test (lambda* (((x) 1)) x) 'error) (test ((lambda* ((a: 3)) a:) :a: 4) 'error) (test ((lambda* ((a 3)) a) a: 4) 4) (test ((lambda* ((a (lambda* ((b 1)) (+ b 1)))) (a))) 2) ;(define hi (call-with-exit (lambda (return) (lambda* ((a (return "hey I need an argument"))) a)))) -> error call goto outside block? (test (let () (define hi (with-let (inlet 'a 3) (lambda (b) (+ a b)))) (hi 2)) 5) ; but this blocks the local env chain: ;(let ((y 2)) (define hi (with-let (inlet) (lambda (a) (+ a y)))) (hi 1)) -> error y unbound ;quick circular env: (define* (hi (a (curlet))) a) (hi) -- need a lambda equivalent of bacro for defargs (test (let () (define hi (do ((i 0 (+ i 1))) ((= i 3) (lambda (a) (+ a i))))) (hi 1)) 4) (test ((lambda* a (list a)) 1 2 3) '((1 2 3))) (test ((lambda* () #f) 1 2 3) 'error) (test ((lambda* (a ) (list a)) 1) '(1)) (test ((lambda* (a b ) (list a b)) 1 2) '(1 2)) (test ((lambda* (a b :allow-other-keys ) (list a b)) 1 2 :c 3) '(1 2)) (test ((lambda* (a . b ) (list a b)) 1 2 3) '(1 (2 3))) (test ((lambda* (a :rest b ) (list a b)) 1 2 3) '(1 (2 3))) (test ((lambda* (a :rest b :allow-other-keys ) (list a b)) 1 2 :c 3) '(1 (2 :c 3))) (test ((lambda* (a b :allow-other-keys ) (list a b)) 1) '(1 #f)) (test ((lambda* (a :allow-other-keys ) (list a)) :b 2) '(#f)) (test ((lambda* (:rest a ) (list a)) 1 2 3) '((1 2 3))) (test ((lambda* (:rest a b ) (list a b)) 1 2 3) '((1 2 3) 2)) (test ((lambda* (:rest a b :allow-other-keys ) (list a b)) :c 1 2 3) '((:c 1 2 3) 1)) ; seems inconsistent (test ((lambda* (:rest a . b ) (list a b)) 1 2 3) '((1 2 3) (2 3))) (test ((lambda* (:rest a :rest b ) (list a b)) 1 2 3) '((1 2 3) (2 3))) (test ((lambda* (:rest a :rest b :allow-other-keys ) (list a b)) 1 2 3) '((1 2 3) (2 3))) (test ((lambda* (:rest a :allow-other-keys ) (list a)) 1 2 3) '((1 2 3))) (test ((lambda* (:allow-other-keys ) (list)) :a 1 :c 3) 'error) (test ((lambda* (:rest a :rest b) (map + a b)) 1 2 3 4 5) '(3 5 7 9)) (test ((lambda* (:rest a c :rest b) (map (lambda (a b) (+ a b c)) a b)) 1 2 3 4 5) '(6 8 10)) (test ((lambda* (a :rest (b 2)) (list a b)) 1 2 3 4) 'error) (let () (define* (f1 (a 0) :allow-other-keys) (+ a 1)) (let ((f2 (copy f1))) (test (f2 :a 1) 2) (test (f2 :b 1) 1))) ;;; one place where :rest can't be handled by dotted list: (let () (define* (f1 :rest args :allow-other-keys) args) (test (f1 :a 1 :b 2) '(:a 1 :b 2))) ;;; but its :allow-other-keys isn't needed here anyway: (let () (define* (f1 . args) args) (test (f1 :a 1 :b 2) '(:a 1 :b 2))) ;;; but (let () (define* (f1 (c 0) . args) args) (test (f1 :a 1 :b 2) 'error) ; unknown key (test (f1 :c 1 :b 2) '(:b 2))) (define* (-nxy- gen (fm 0.0)) ; optimizer test (safe_closure_star_s0) (let-set! gen 'fm fm) (with-let gen fm)) (let ((g (inlet 'fm 1.0))) (test (-nxy- g) 0.0) (test (-nxy- g) 0.0) (test (-nxy- g 0.5) 0.5) (test (-nxy- g) 0.0)) #| (let ((choices (list "a " "b " " . " ":rest " ":allow-other-keys ")) (args (list "1 " ":a " ":b " ":c "))) (define-bacro (display-abc) `(format #f "~A ~A" (if (defined? 'a) (symbol->value 'a) '?) (if (defined? 'b) (symbol->value 'b) '?))) (define (next-arg str n) (let ((expr (string-append str ")"))) (catch #t (lambda () (let ((val (eval-string expr))) (format-logged #t "~A -> ~A~%" expr val))) (lambda args ;(format-logged #t " ~A: ~A~%" expr (apply format #f (cadr args))) 'error))) (if (< n 6) (for-each (lambda (arg) (next-arg (string-append str arg) (+ n 1))) args))) (define (next-choice str n) (next-arg (string-append str ") (display-abc)) ") 0) (if (< n 4) (for-each (lambda (choice) (next-choice (string-append str choice) (+ n 1))) choices))) (for-each (lambda (choice) (next-arg (string-append "((lambda* " choice "(display-abc)) ") 0)) choices) (next-choice "((lambda* (" 0)) |# (let () (define* (s0-test gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (+ fm 1.0))) (define (tst) (let ((g (inlet 'fm 0.0))) (num-test (s0-test g) 1.0)) (let ((g (inlet 'fm 0.0))) (num-test (s0-test g 0.0) 1.0))) (tst)) ;;; here be bugs... (test ((lambda* a a) :a) '(:a)) (test ((lambda* (a . b) (list a b)) :b 1) '(#f 1)) ; ??? why doesn't the 1st arg work this way? (test ((lambda* (a :rest b) (list a b)) :b 1) '(#f 1)) (test ((lambda* (:rest a) (list a)) :a 1) '((:a 1))) ; surely these are inconsistent (test ((lambda* (a . b ) (list a b)) :b 1 1) '(#f (1))) ; so if trailer, overwrite is not error? (test ((lambda* (:rest a b ) (list a b)) 1 1) '((1 1) 1)) (test ((lambda* (:rest a :rest b ) (list a b)) :a 1) '((:a 1) (1))) (test ((lambda* (:allow-other-keys) #f) :c 1) 'error) (test ((lambda* (a :allow-other-keys) a) :a) :a) (test ((lambda* (a) a) :a) :a) (test ((lambda* (a :allow-other-keys) a) :a 1 :a 2) 1) ; this is very tricky to catch (test ((lambda* (a :allow-other-keys) a) :c :c :c :c) #f) (test ((lambda* (a :allow-other-keys) a) :c) :c) (test ((lambda* (a b :allow-other-keys ) (list a b)) :b :a :c 1) '(#f :a)) (test ((lambda* (a :allow-other-keys ) a) :c 1 1) 1) ; ?? (test ((lambda* (:rest b (a 1)) (list a b))) '(1 ())) (test ((lambda* (:rest a b c) (list a b c)) 1 2 3 4) '((1 2 3 4) 2 3)) ;(test (let ((x 3)) (define* (f (x x)) x) (let ((x 32)) (f))) 3) (test (let ((x 3)) (define-macro* (f (x x)) `,x) (let ((x 32)) (f))) 32) ; ?? inconsistent with define* perhaps? (test (let () (define (x x) x) (x 1)) 1) (test (procedure? (let () (define* (x (x #t)) x) (x x))) #t) (test (procedure? (let () (define* (x (x x)) x) (x (x x)))) #t) ;(test (procedure? (let () (define* (x (x x)) x) (x))) #t) (test (apply + ((lambda* ((x (values 1 2 3))) x))) 6) (test ((lambda* ((x (lambda* ((y (+ 1 2))) y))) (x))) 3) ;;; define-macro ;;; define-macro* ;;; define-bacro ;;; define-bacro* (test (let ((x 0)) (define-macro* (hi (a (let () (set! x (+ x 1)) x))) `(+ 1 ,a)) (list (let ((x -1)) (list (hi) x)) x)) '((1 0) 0)) (test (let ((x 0)) (define-bacro* (hi (a (let () (set! x (+ x 1)) x))) `(+ 1 ,a)) (list (let ((x -1)) (list (hi) x)) x)) '((1 0) 0)) (test (let ((x 0)) (define-macro* (hi (a (let () (set! x (+ x 1)) x))) `(+ x ,a)) (list (let ((x -1)) (list (hi) x)) x)) '((-1 0) 0)) (test (let ((x 0)) (define-bacro* (hi (a (let () (set! x (+ x 1)) x))) `(+ x ,a)) (list (let ((x -1)) (list (hi) x)) x)) '((-1 0) 0)) (test (let ((x 0)) (define-macro* (hi (a (let () (set! x (+ x 1)) x))) `(let ((x -1)) (+ x ,a))) (list (hi) x)) '(-1 0)) (test (let ((x 0)) (let ((x -1)) (+ x (let () (set! x (+ x 1)) x)))) -1) (test (let ((x 0)) (define-macro (hi a) `(let ((x -1)) (+ x ,a))) (list (hi (let () (set! x (+ x 1)) x)) x)) '(-1 0)) (test (let () (define-macro (hi a) `(let ((b 1)) (+ ,a b))) (hi (+ 1 b))) 3) (test (let ((b 321)) (define-macro (hi a) `(let ((b 1)) (+ ,a b))) (hi b)) 2) (test (let ((b 321)) (define-macro* (hi (a b)) `(let ((b 1)) (+ ,a b))) (hi b)) 2) (test (let ((b 321)) (define-macro* (hi (a b)) `(let ((b 1)) (+ ,a b))) (hi)) 2) ; ??? (test (let ((x 0)) (define-macro* (hi (a (let () (set! x (+ x 1)) x))) `(+ ,a ,a)) (hi)) 3) ; ??? -- default val is substituted directly ;; but (let () (define-macro* (hi a (b a)) `(+ ,a ,b)) (hi 1)) -> "a: unbound variable" -- "a" itself is substituted, but does not exist at expansion(?) ;; can we implement bacros via define-macro* default args? ;; I don't think so -- macro arguments can't be evaluated in that environment because ;; only the default values have been set (on the previous parameters). ;; bacro ignores closure in expansion but macro does not: (test (let ((x 1)) (define-macro (ho a) `(+ ,x ,a)) (let ((x 32)) (ho 3))) 4) (test (let ((x 1)) (define-macro (ho a) `(+ x ,a)) (let ((x 32)) (ho 3))) 35) (test (let ((x 1)) (define-bacro (ho a) `(+ ,x ,a)) (let ((x 32)) (ho 3))) 35) (test (let ((x 1)) (define-bacro (ho a) `(+ x ,a)) (let ((x 32)) (ho 3))) 35) (test (let ((x 1)) (define-macro* (ho (a x)) `(+ ,x ,a)) (let ((x 32)) (ho))) 33) (test (let ((x 1)) (define-macro* (ho (a x)) `(+ x ,a)) (let ((x 32)) (ho))) 64) (test (let ((x 1)) (define-bacro* (ho (a x)) `(+ x ,a)) (let ((x 32)) (ho))) 64) (test (let ((x 1)) (define-bacro* (ho (a x)) `(+ ,x ,a)) (let ((x 32)) (ho))) 64) (test (let ((x 1)) (define-macro* (ho (a (+ x 0))) `(+ ,x ,a)) (let ((x 32)) (ho))) 33) ;; (+ 32 (+ x 0)) !?! macroexpand is confusing? (test (let ((x 1)) (define-macro* (ho (a (+ x 0))) `(+ x ,a)) (let ((x 32)) (ho))) 64) ;; (+ x (+ x 0)) (test (let ((x 1)) (define-bacro* (ho (a (+ x 0))) `(+ x ,a)) (let ((x 32)) (ho))) 64 ) (test (let ((x 1)) (define-bacro* (ho (a (+ x 0))) `(+ ,x ,a)) (let ((x 32)) (ho))) 64 ) (test (let () (define-macro* (hi :rest a) `(list ,@a)) (hi)) ()) (test (let () (define-macro* (hi :rest a) `(list ,@a)) (hi 1)) '(1)) (test (let () (define-macro* (hi :rest a) `(list ,@a)) (hi 1 2 3)) '(1 2 3)) (test (let () (define-macro* (hi a :rest b) `(list ,a ,@b)) (hi 1 2 3)) '(1 2 3)) (test (let () (define-macro* (hi (a 1) :rest b) `(list ,a ,@b)) (hi)) '(1)) (test (let () (define-macro* (hi (a 1) :rest b) `(list ,a ,@b)) (hi 2)) '(2)) (test (let () (define-macro* (hi (a 1) :rest b) `(list ,a ,@b)) (hi :a 2)) '(2)) (test (let () (define-macro* (hi (a 1) :rest b :allow-other-keys) `(list ,a ,@b)) (hi :a 2 :b 3)) '(2 :b 3)) (test (let () (define-macro* (mac1 a :rest b) `(,a ,@b)) (mac1 + 2 3 4)) 9) ; (test (let () (define-macro ,@a 23)) 'error) ; (test (let () (define-macro ,a 23)) 'error) ; maybe this isn't right (let () (define-macro (dw-fs x) `(values (lambda () #f) (lambda () ,x) (lambda () #f))) (test (dynamic-wind (dw-fs 3)) 3)) (let () (define-macro (flam . args) `(apply format #f "~{~A~^ ~}" '(,args))) (test (flam this is a test) "this is a test")) (test ((lambda* ((a 1) :allow-other-keys) a) :b 1 :a 3) 3) (test (let () (define-macro* (hi (a 1) :allow-other-keys) `(list ,a)) (hi :b 2 :a 3)) '(3)) (test ((lambda* ((a 1) :rest b :allow-other-keys) b) :c 1 :a 3) ()) (test ((lambda* ((a 1) :rest b :allow-other-keys) b) :b 1 :a 3) 'error) ;; that is the rest arg is not settable via a keyword and it's an error to try to ;; do so, even if :allow-other-keys -- ?? (test (let ((x 1)) (define* (hi (a x)) a) (let ((x 32)) (hi))) 1) (test (let ((x 1)) (define* (hi (a (+ x 0))) a) (let ((x 32)) (hi))) 1) (test (let ((x 1)) (define* (hi (a (+ x "hi"))) a) (let ((x 32)) (hi))) 'error) (test (let ((x 1)) (define-macro* (ho (a (+ x "hi"))) `(+ x ,a)) (let ((x 32)) (ho))) 'error) (test (let ((x 1)) (define-macro (f1) `(+ x 1)) (f1)) 2) (let () (define-macro (until test . body) `(do () (,test) ,@body)) (test (let ((i 0) (sum 0)) (until (= i 4) (set! sum (+ sum i)) (set! i (+ i 1))) sum) 6)) (let () (define-macro (glambda args) ; returns an anonymous macro that will return a function given a body `(define-macro (,(gensym) . body) `(lambda ,',args ,@body))) (test (let ((gf (glambda (a b)))) ; gf is now ready for any body that involves arguments 'a and 'b ((gf (+ a b)) 1 2)) ; apply (lambda (a b) (+ a b)) to '(1 2) 3)) (let () (define-macro (alambda pars . body) `(letrec ((self (lambda* ,pars ,@body))) self)) (test ((alambda (n) (if (<= n 0) () (cons n (self (- n 1))))) 9) '(9 8 7 6 5 4 3 2 1)) (define-macro* (aif test then (else #)) `(let ((it ,test)) (if it ,then ,else))) (test (aif (+ 3 2) it) 5) (test (aif (> 2 3) it) #) (test (aif (> 2 3) #f it) #f) ) (let () (define-macro (enum . args) `(for-each (let ((ctr -1)) (define-macro (m a) (set! ctr (+ ctr 1)) `(apply define ',a ,ctr ()))) ',args)) (enum a b c) (test b 1) (test (+ a b c) 3)) (let () (define-bacro* (m (a b)) a) (test (let ((b 2)) (m)) 2) (test (let ((b 2)) (let ((b 23)) (m))) 23)) (let () (let ((x 1) (y 2)) (define-bacro (bac1 a) `(+ ,x y ,a)) (let ((x 32) (y 64)) (test (bac1 3) 99))) (let ((x 1) (y 2)) (define-bacro (bac2 a) (with-let (sublet (funclet bac2) (cons 'a a)) `(+ ,x y ,a))) (let ((x 32) (y 64)) (test (bac2 3) 68))) (let ((x 1) (y 2)) (define-bacro (bac3 a) (with-let (sublet (funclet bac3) (cons 'a a)) (eval `(+ ,x y ,a)))) (let ((x 32) (y 64)) (test (bac3 3) 6))) (let ((x 1) (y 2)) (define-bacro (bac4 a) (eval `(+ ,x y ,a) (sublet (funclet bac4) (cons 'a a)))) (let ((x 32) (y 64)) (test (bac4 3) 37))) (let ((x 1) (y 2)) (define-bacro (bac1 a) `(+ ,x y ,a)) ; -> (+ 32 y x) (let ((x 32) (y 64)) (test (bac1 x) 128))) ; x=32 (let ((x 1) (y 2)) (define-bacro (bac2 a) (with-let (sublet (funclet bac2) (cons 'a a)) `(+ ,x y ,a))) ; (+ 1 y x) (let ((x 32) (y 64)) (test (bac2 x) 97))) ; x=32 (let ((x 1) (y 2)) (define-bacro (bac3 a) (with-let (sublet (funclet bac3) (cons 'a a)) (eval `(+ ,x y ,a)))) ; (eval (+ 1 2 1)) -> 4 (let ((x 32) (y 64)) (test (bac3 x) 4))) ; x=1 (let ((x 1) (y 2)) (define-bacro (bac4 a) (eval `(+ ,x y ,a) (sublet (funclet bac4) (cons 'a a)))) ; (eval (+ 32 2 1)) -> 35 (let ((x 32) (y 64)) (test (bac4 x) 35))) ; x=1 (let ((x 1) (y 2)) (define-bacro (bac3 a) (let ((e (with-let (sublet (funclet bac3) (cons 'a a)) `(+ ,x y ,a)))) `(with-let ,(sublet (funclet bac3) (cons 'a a)) ,e))) (let ((x 32) (y 64)) (test (bac3 3) 6))) (let ((x 1) (y 2)) (define-bacro (bac4 a) (let ((e `(+ ,x y ,a))) `(with-let ,(sublet (funclet bac4) (cons 'a a)) ,e))) (let ((x 32) (y 64)) (test (bac4 3) 37)))) (let () ; need this, else the define-macro below leaks into rootlet (let ((e (inlet 'mac (apply define-macro (list (list (gensym) 'a) '`(+ ,a 1)))))) (test ((e 'mac) 3) 4))) (let () (define-macro (swap a b) `(with-let (inlet :e (curlet) :tmp ,a) (set! (e ',a) (e ',b)) (set! (e ',b) tmp))) (let ((a 1) (b 2)) (swap b a) (test (list a b) '(2 1))) (let ((tmp 1) (b 2)) (swap b tmp) (test (list tmp b) '(2 1))) (let ((a 1) (tmp 2)) (swap a tmp) (test (list a tmp) '(2 1))) (let ((tmp 1) (b 2)) (swap tmp b) (test (list tmp b) '(2 1))) (let ((a 1) (tmp 2)) (swap tmp a) (test (list a tmp) '(2 1)))) (let () (define-macro (swap a b) `(set! ,b (with-let (inlet 'e (curlet) 'tmp ,a) (with-let e (set! ,a ,b)) tmp))) (test (let ((v (vector 1 2))) (swap (v 0) (v 1)) v) #(2 1)) (test (let ((tmp (cons 1 2))) (swap (car tmp) (cdr tmp)) tmp) '(2 . 1)) (define-macro (set-swap a b c) `(set! ,b ,c)) (set! (procedure-setter swap) set-swap) (test (let ((a 1) (b 2) (c 3) (d 4)) (swap a (swap b (swap c d))) (list a b c d)) '(2 3 4 1)) (define-macro (rotate . args) `(set! ,(args (- (length args) 1)) (with-let (inlet 'e (curlet) 'tmp ,(car args)) (with-let e ,@(map (lambda (a b) `(set! ,a ,b)) args (cdr args))) tmp))) (test (let ((a 1) (b 2) (c 3)) (rotate a b c) (list a b c)) '(2 3 1)) (define-macro (mac a) `(+ ,a 1)) (define-macro* (mac1 (a 32)) `(+ ,a 1)) (define-macro (fm form) (define (expand form) (if (pair? form) (if (and (symbol? (car form)) (macro? (symbol->value (car form)))) (expand (apply macroexpand (list form))) (if (and (eq? (car form) 'set!) (pair? (cdr form)) (pair? (cadr form)) (macro? (symbol->value (caadr form)))) (expand (apply (eval (procedure-source (procedure-setter (symbol->value (caadr form))))) (append (cdadr form) (cddr form)))) (cons (expand (car form)) (expand (cdr form))))) form)) (list 'quote (expand form))) (test (fm (mac 2)) '(+ 2 1)) (test (fm (mac x)) '(+ x 1)) (test (fm (mac1 2)) '(+ 2 1)) (test (fm (mac1)) '(+ 32 1)) (test (fm (mac (mac1))) '(+ (+ 32 1) 1)) (test (fm (+ (mac x) (mac1 y))) '(+ (+ x 1) (+ y 1))) (test (fm (swap a b)) '(set! b (with-let (inlet 'e (curlet) 'tmp a) (with-let e (set! a b)) tmp))) (test (fm (swap a (swap b c))) '(set! c (with-let (inlet 'e (curlet) 'tmp a) (with-let e (set! a (set! c (with-let (inlet 'e (curlet) 'tmp b) (with-let e (set! b c)) tmp)))) tmp))) (test (fm (rotate a b c)) '(set! c (with-let (inlet 'e (curlet) 'tmp a) (with-let e (set! a b) (set! b c)) tmp))) ) #| ;;; would this work in MIT-scheme? (define-macro (swap a b) `(set! ,b (eval `(let ((e ,(the-environment))) (eval `(set! ,',',a ,',',b) e) tmp) (let ((e (the-environment)) (tmp ,a)) (the-environment))))) |# (let () ;; how to protect a recursive macro call from being stepped on ;; (define-macro (mac a b) `(if (> ,b 0) (let ((,a (- ,b 1))) (mac ,a (- ,b 1))) ,b)) ;; (mac mac 1) ;; attempt to apply the integer 0 to (0 1)? ;; (mac mac 1) (define-macro (mac a b) (let ((gmac (gensym))) (set! gmac mac) `(if (> ,b 0) (let ((,a (- ,b 1))) (,gmac ,a (- ,b 1))) ,b))) (test (mac mac 10) 0)) (let () (define-bacro* (incf var (inc 1)) `(set! ,var (+ ,var ,inc))) (define-bacro* (decf var (inc 1)) `(set! ,var (- ,var ,inc))) (test (let ((x 0)) (incf x)) 1) (test (let ((x 1.5)) (incf x 2.5) x) 4.0) (test (let ((x 10)) (decf x (decf x 1)) x) 1) ;; ! -- left to right order I think (let ((x 10)) (set! x (- x (set! x (- x 1))))) so the 3rd x is 10 ;; Clisp and sbcl return 0: (let ((x 10)) (decf x (decf x (decf x))) x) is also 0 ;; but in clisp (let ((x 10)) (setf x (- x (setf x (- x 1)))) x) is 1 ;; I didn't know these cases were different ;; (let ((x 10)) (set! x (- x (let () (set! x (- x 1)) x))) x) 1, Guile also says 1 ;; cltl2 p 134ff is an unreadable discussion of this, but I think it says in this case CL goes right to left ;; weird! in CL (decf x (decf x)) != (setf x (- x (setf x (- x 1)))) ;; and (let ((x 10)) (let ((val (decf x))) (decf x val) x))? ;; so by adhering to one evaluation order, we lose "referential transparency"? (test (let ((x 1+i)) (decf x 0+i)) 1.0)) (let () ;; (define-bacro* (incf var (inc 1)) (set! var (+ (eval var) (eval inc)))) ;; this form does not actually set the incoming variable (it sets the argument) ;; at OP_SET we see set (var (+ (eval var) (eval inc))) ;; set1 var 1 ;; which leaves x unset ;; but below we see set (x 1) ;; set1 x 1 (define-bacro* (incf var (inc 1)) (apply set! var (+ (eval var) (eval inc)) ())) (define-bacro* (decf var (inc 1)) (apply set! var (- (eval var) (eval inc)) ())) (test (let ((x 0)) (incf x)) 1) (test (let ((x 1.5)) (incf x 2.5) x) 4.0) (test (let ((x 10)) (decf x (decf x 1)) x) 1) (test (let ((x 1+i)) (decf x 0+i)) 1.0)) (let () (define-macro (and-call function . args) ;; apply function to each arg, stopping if returned value is #f `(and ,@(map (lambda (arg) `(,function ,arg)) args))) (let ((lst ())) (and-call (lambda (a) (and a (set! lst (cons a lst)))) (+ 1 2) #\a #f (format-logged #t "oops!~%")) (test lst (list #\a 3)))) (let () (define-macro (add a . b) `(if (null? ',b) ,a (+ ,a (add ,@b)))) (test (add 1 2 3) 6) (test (add 1 (add 2 3) 4) 10)) (let () (define mac (let ((var (gensym))) (define-macro (mac-inner b) `(#_let ((,var 12)) (#_+ ,var ,b))) mac-inner)) (test (mac 1) 13) (test (let ((a 1)) (mac a)) 13)) (test (eq? call/cc #_call/cc) #t) (let ((val #f)) (define-macro (add-1 var) `(+ 1 (let () (set! val ',var) ,var))) (define (add-2 var) (set! val var) (+ 1 var)) (let ((free #t)) (let ((res ((if free add-1 add-2) (+ 1 2 3)))) (if (or (not (equal? val '(+ 1 2 3))) (not (= res 7))) (format-logged #t ";mac/proc[#t]: ~A ~A~%" val res))) (set! free #f) (let ((res ((if free add-1 add-2) (+ 1 2 3)))) (if (or (not (equal? val '6)) (not (= res 7))) (format-logged #t ";mac/proc[#f]: ~A ~A~%" val res))))) ;; define-macro* default arg expr does not see definition-time closure: (test (let ((mac #f)) (let ((a 32)) (define-macro* (hi (b (+ a 1))) `(+ ,b 2)) (set! mac hi)) (mac)) 'error) ; ";a: unbound variable, line 4" (test ((lambda* ((x (let () (define-macro (hi a) `(+ ,a 1)) (hi 2)))) (+ x 1))) 4) (test (let () (define-macro* (hi (x (let () (define-macro (hi a) `(+ ,a 1)) (hi 2)))) `(+ ,x 1)) (hi)) 4) (test (let () (define* (hi b) b) (procedure? hi)) #t) (test (let () (define (hi a) a) (let ((tag (catch #t (lambda () (hi 1 2 3)) (lambda args (car args))))) (eq? tag 'wrong-number-of-args))) #t) (test (let () (define (hi a) a) (let ((tag (catch #t (lambda () (hi)) (lambda args (car args))))) (eq? tag 'wrong-number-of-args))) #t) (test (let () (define* (hi a) a) (let ((tag (catch #t (lambda () (hi 1 2 3)) (lambda args (car args))))) (eq? tag 'wrong-number-of-args))) #t) (let () ;; shouldn't this be let-if or let-if-and, not if-let? ;; and why not add short-circuiting to it (at the variable bindings point)? ;; not pretty, but we could do this via and-call + sublet ;; maybe use and-let* instead (define-macro* (if-let bindings true false) (let* ((binding-list (if (and (pair? bindings) (symbol? (car bindings))) (list bindings) bindings)) (variables (map car binding-list))) `(let ,binding-list (if (and ,@variables) ,true ,false)))) (test (if-let ((a 1) (b 2)) (list a b) "oops") '(1 2))) (let () (defmacro old-and-let* (vars . body) ; from guile/1.8/ice-9/and-let-star.scm (define (expand vars body) (cond ((null? vars) (if (null? body) #t `(begin ,@body))) ((pair? vars) (let ((exp (car vars))) (cond ((pair? exp) (cond ((null? (cdr exp)) `(and ,(car exp) ,(expand (cdr vars) body))) (else (let ((var (car exp))) `(let (,exp) (and ,var ,(expand (cdr vars) body))))))) (else `(and ,exp ,(expand (cdr vars) body)))))) (else (error "not a proper list" vars)))) (expand vars body)) (test (old-and-let* ((hi 3) (ho #f)) (+ hi 1)) #f)) (let () (define-macro (and-let* vars . body) `(let () (and ,@(map (lambda (var) `(apply define ',var)) vars) (begin ,@body)))) (test (and-let* ((hi 3) (ho #f)) (+ hi 1)) #f) (test (and-let* ((hi 3) (ho #t)) (+ hi 1)) 4)) (let () ; from the pro CL mailing list (define-macro (do-leaves var tree . body) `(let () (define (rec ,var) (if (not (null? ,var)) (if (pair? ,var) (begin (rec (car ,var)) (rec (cdr ,var))) (begin ,@body)))) (rec ,tree))) (test (let ((lst ())) (do-leaves hiho '(+ 1 (* 2 3)) (set! lst (cons hiho lst))) (reverse lst)) '(+ 1 * 2 3))) (test (let () (define (hi :a) :a) (hi 1)) 'error) (test (let () (define* (hi :a) :a) (hi 1)) 'error) (test (let () (define* (hi (:a 2)) a) (hi 1)) 'error) (test (let () (define* (hi (a 1) (:a 2)) a) (hi 1)) 'error) (test (let () (define* (hi (pi 1)) pi) (hi 2)) 'error) (test (let () (define* (hi (:b 1) (:a 2)) a) (hi)) 'error) (test (let () (define* (hi (a 1) (a 2)) a) (hi 2)) 'error) (test (let () (define (hi a a) a) (hi 1 2)) 'error) (test (let () (define hi (lambda (a a) a)) (hi 1 1)) 'error) (test (let () (define hi (lambda* ((a 1) (a 2)) a)) (hi 1 2)) 'error) (test (let () (define (hi (a 1)) a) (hi 1)) 'error) (test (let ((_?_0 #f)) (set! (symbol-access '_?_0) (lambda args #f)) (define-macro (_?_0 a) `(+ ,a 1)) (_?_0 2)) 'error) (test (let ((_?_1 #f)) (set! (symbol-access '_?_1) (lambda args 'error)) (define-macro (_?_1 a) `(+ ,a 1)) (_?_1 2)) 'error) (test (let ((_?_2 #f)) (set! (symbol-access '_?_2) (lambda (s v) v)) (define-macro (_?_2 a) `(+ ,a 1)) (_?_2 2)) 3) (let () (define* (hi (a #2d((1 2) (3 4)))) (a 1 0)) (test (hi) 3) (test (hi #2d((7 8) (9 10))) 9)) (let () (define* (f :rest a) a) (test (f :a 1) '(:a 1))) (let () (define* (f :rest a :rest b) (list a b)) (test (f :a 1 :b 2) '((:a 1 :b 2) (1 :b 2)))) (test (lambda :hi 1) 'error) (test (lambda (:hi) 1) 'error) (test (lambda (:hi . :hi) 1) 'error) (test (lambda (i . i) 1 . 2) 'error) (test (lambda (i i i i) (i)) 'error) (test (lambda "hi" 1) 'error) (test (lambda* ((i 1) i i) i) 'error) (test (lambda* ((a 1 2)) a) 'error) (test (lambda* ((a . 1)) a) 'error) (test (lambda* ((0.0 1)) 0.0) 'error) (test ((lambda* ((b 3) :rest x (c 1)) (list b c x)) 32) '(32 1 ())) (test ((lambda* ((b 3) :rest x (c 1)) (list b c x)) 1 2 3 4 5) '(1 3 (2 3 4 5))) ;; these are in s7.html (test ((lambda* ((a 1) :rest b :rest c) (list a b c)) 1 2 3 4 5) '(1 (2 3 4 5) (3 4 5))) (test (let () (define-macro (hi a a) `(+ ,a 1)) (hi 1 2)) 'error) (test (let ((c 1)) (define* (a (b c)) b) (set! c 2) (a)) 2) (test (let ((c 1)) (define* (a (b c)) b) (let ((c 32)) (a))) 1) (test (let ((c 1)) (define* (a (b (+ c 1))) b) (set! c 2) (a)) 3) (test (let ((c 1)) (define* (a (b (+ c 1))) b) (set! c 2) (let ((c 123)) (a))) 3) (test (let* ((cc 1) (c (lambda () (set! cc (+ cc 1)) cc))) (define* (a (b (c))) b) (list cc (a) cc)) (list 1 2 2)) (let () (define* (func (val ((lambda (a) (+ a 1)) 2))) val) (test (func) 3) (test (func 1) 1)) (let () (define-macro (mac-free-x y) `(set! x ,y)) (define (mac-y1) (let ((x .1)) (do ((i 0 (+ i 1)) (y 0.5 (+ y x))) ((= i 10) y) (if (= i 2) (mac-free-x 1.1))))) (define (mac-y0) (let ((x .1)) (do ((i 0 (+ i 1)) (y 0.5 (+ y x))) ((= i 10) y) (if (= i 2) (set! x 1.1))))) (define-macro (mac-free-v) `(v 1)) (define-macro (set-mac-free-v z) `(vector-set! v 1 ,z)) (set! (procedure-setter mac-free-v) set-mac-free-v) (define (mac-y2) (let ((v (vector 1.0 0.1 1.2))) (do ((i 0 (+ i 1)) (y 0.5 (+ y (vector-ref v 1)))) ((= i 10) y) (if (= i 2) (set! (mac-free-v) 1.1))))) (define (mac-y3) (let ((v (vector 1.0 0.1 1.2))) (do ((i 0 (+ i 1)) (y 0.5 (+ y (vector-ref v 1)))) ((= i 10) y) (if (= i 2) (vector-set! v 1 1.1))))) (let ((y0 (mac-y0)) (y1 (mac-y1)) (y2 (mac-y2)) (y3 (mac-y3))) (if (not (morally-equal? y0 y1)) (format-logged #t "~A: ~A got ~S but expected ~S~%~%" (port-line-number) 'mac-y0 y0 y1)) (if (not (morally-equal? y2 y3)) (format-logged #t "~A: ~A got ~S but expected ~S~%~%" (port-line-number) 'mac-y2 y2 y3))) (let ((y (+ (mac-y0) (mac-y1) (mac-y2) (mac-y3)))) (if (> (abs (- y (* 4 9.5))) 1e-9) (format-logged #t "(2) ~A: ~A got ~S but expected ~S~%~%" (port-line-number) 'mac-y0 y (* 4 9.5))))) ;;; -------------------------------------------------------------------------------- ;;; aritable? (for-each (lambda (arg) (if (aritable? arg 0) (format-logged #t ";(aritable? ~A) -> #t?~%" arg))) (list :hi (integer->char 65) 1 #t 3.14 3/4 1.0+1.0i #\f # #)) (for-each (lambda (arg) (let ((val (catch #t (lambda () (aritable? abs arg)) (lambda args 'error)))) (if (not (eq? val 'error)) (format-logged #t ";(aritable? abs ~A) -> ~A?~%" arg val)))) (list :hi (integer->char 65) -1 most-negative-fixnum macroexpand quasiquote (lambda () #f) car #() "hi" (list 1 2) 3.14 3/4 1.0+1.0i #\f # #)) (test (aritable?) 'error) (test (aritable? abs) 'error) (test (aritable? car 0) #f) (test (aritable? car 1) #t) (test (aritable? car 2) #f) (test (aritable? car 3) #f) (test (aritable? car most-negative-fixnum) 'error) (test (aritable? car most-positive-fixnum) #f) (test (aritable? + most-positive-fixnum) #t) (test (aritable? + 0) #t) (test (aritable? log 2) #t) (test (aritable? catch 2) #f) (test (aritable? set! 0) #f) (test (aritable? begin 0) #t) (test (aritable? (random-state 123) 0) #f) ;;; more tests under arity (test (let () (define-macro (mac1 a b c) `(+ ,a ,b)) (aritable? mac1 2)) #f) (test (let () (define-macro (mac1 a b . c) `(+ ,a ,b)) (aritable? mac1 2)) #t) (test (let () (define-bacro (mac1 a b c) `(+ ,a ,b)) (aritable? mac1 1)) #f) (test (let () (define-bacro (mac1 a b . c) `(+ ,a ,b)) (aritable? mac1 3)) #t) (test (let () (defmacro mac1 (a b c) `(+ ,a ,b)) (aritable? mac1 4)) #f) (test (let () (defmacro mac1 (a b . c) `(+ ,a ,b)) (aritable? mac1 2)) #t) (test (let () (define-macro (mac1 a) `(+ 1 ,a)) (aritable? mac1 0)) #f) (test (let () (define-macro* (mac1 . a) `(+ ,a ,b)) (aritable? mac1 3)) #t) (test (let () (define-macro* (mac1 a) `(+ 1 ,a)) (aritable? mac1 0)) #t) (test (let () (define-macro* (mac1 a :rest b) `(+ 1 ,a)) (aritable? mac1 21)) #t) (test (let () (define-macro* (mac1 a . b) `(,a ,@b)) (aritable? mac1 4)) #t) (test (let () (define-macro* (mac1 a b c) `(+ ,a ,b)) (aritable? mac1 2)) #t) (test (aritable? "hiho" 0) #f) (test (aritable? "" 1) #f) (test (aritable? () 0) #f) (test (aritable? #() 1) #f) (test (aritable? #(1 2 3) 0) #f) (test (aritable? #(1 2 3) -1) 'error) (test (aritable? #(1 2 3) 1) #t) (test (aritable? #(1 2 3) 2) #f) (test (aritable? (hash-table '(a . 1)) 1) #t) (test (aritable? (hash-table '(a . 1)) 2) #f) (test (aritable? (curlet) 1) #t) (test (let () (call-with-exit (lambda (goto) (aritable? goto 1)))) #t) (test (aritable? (make-iterator (hash-table '(a . 1))) 0) #t) (test (aritable? (make-iterator (hash-table '(a . 1))) 1) #f) (test (aritable? "" 0) #f) (test (aritable? "12" 2) #f) (test (aritable? "12" 1) #t) (test (aritable? #() 0) #f) ; since (#() 0) or any other arg is an error (test (aritable? #2d((1 2) (3 4)) 0) #f) (test (aritable? #2d((1 2) (3 4)) 1) #t) (test (aritable? #2d((1 2) (3 4)) 2) #t) (test (aritable? #2d((1 2) (3 4)) 3) #f) (test (aritable? '((1 2) (3 4)) 2) #f) (test (aritable? '(1 2 . 3) 9223372036854775806) #f) (test (aritable? #2D((1 3) (2 4)) 9223372036854775807) #f) (test (aritable? '2 1) #f) (test (aritable? ''2 1) #t) ;;; -------------------------------------------------------------------------------- ;;; arity (test (arity) 'error) (test (arity abs 1) 'error) (for-each (lambda (arg) (if (arity arg) (format-logged #t ";(arity ~A) -> ~A?~%" arg (arity arg)))) (list :hi (integer->char 65) 1 #t 3.14 3/4 1.0+1.0i #\f # # # () 'a)) #| (let ((choices (list "a " "b " " . " ":rest " ":allow-other-keys "))) (define (next-arg expr) (catch #t (lambda () ;(format #t "expr: ~A~%" expr) (let ((func (eval-string expr))) (let ((min-max (arity func))) (format #t "(test (arity ~A) ~70T'~A)~%" expr min-max) (if (> (cdr min-max) 6) (set! (cdr min-max) 6)) (do ((i 0 (+ i 1))) ((= i (car min-max))) (if (aritable? func i) (format #t ";~A: arity: ~A, arg: ~A?~%" expr min-max i))) (do ((i (car min-max) (+ i 1))) ((> i (cdr min-max))) (if (not (aritable? func i)) (format #t ";~A: arity: ~A, arg: ~A?~%" expr min-max i))) (do ((i (+ 1 (cdr min-max)) (+ i 1))) ((>= i 6)) (if (aritable? func i) (format #t ";~A: arity: ~A, arg: ~A?~%" expr min-max i))) ))) (lambda args ;(format #t " ~A: ~A~%" expr (apply format #f (cadr args))) 'error))) (define (next-choice str n) (next-arg (string-append str ") #f)")) (if (< n 6) (for-each (lambda (choice) (next-choice (string-append str choice) (+ n 1))) choices))) (for-each (lambda (choice) (next-arg (string-append "(lambda* " choice "#f)"))) choices) (next-choice "(lambda* (" 0)) |# (test (arity (lambda a a)) (cons 0 *max-arity*)) (test (arity (define (_m_ . a) a)) (cons 0 *max-arity*)) (test (arity (lambda (a . b) a)) (cons 1 *max-arity*)) (test (arity (define (_m_ a . b) a)) (cons 1 *max-arity*)) (test (arity (lambda (a b . c) a)) (cons 2 *max-arity*)) (test (arity (define (_m_ a b . c) a)) (cons 2 *max-arity*)) (test (arity (define* (a b . c) a)) (cons 0 *max-arity*)) (test (arity (define-macro (_m_ a . b) a)) (cons 1 *max-arity*)) (test (arity (lambda* a #f)) (cons 0 *max-arity*)) (test (arity (lambda* () #f)) '(0 . 0)) (test (arity (lambda* (a ) #f)) '(0 . 1)) (test (arity (lambda* (a b ) #f)) '(0 . 2)) (test (arity (lambda* (a b :allow-other-keys ) #f)) (cons 0 *max-arity*)) (test (arity (lambda* (a . b ) #f)) (cons 0 *max-arity*)) (test (arity (lambda* (a :rest b ) #f)) (cons 0 *max-arity*)) (test (arity (lambda* (a :rest b :allow-other-keys ) #f)) (cons 0 *max-arity*)) (test (arity (lambda* (a :allow-other-keys ) #f)) (cons 0 *max-arity*)) (test (arity (lambda* (:rest a ) #f)) (cons 0 *max-arity*)) (test (arity (lambda* (:rest a b ) #f)) (cons 0 *max-arity*)) (test (arity (lambda* (:rest a b :allow-other-keys ) #f)) (cons 0 *max-arity*)) (test (arity (lambda* (:rest a . b ) #f)) (cons 0 *max-arity*)) (test (arity (lambda* (:rest a :rest b ) #f)) (cons 0 *max-arity*)) (test (arity (lambda* (:rest a :rest b :allow-other-keys ) #f)) (cons 0 *max-arity*)) (test (arity (lambda* (:rest a :allow-other-keys ) #f)) (cons 0 *max-arity*)) (test (arity (define* (__a_ . a) #f)) (cons 0 *max-arity*)) (test (arity (define* (__a_) #f)) '(0 . 0)) (test (arity (define* (__a_ a) #f)) '(0 . 1)) (test (arity (define* (__a_ a b) #f)) '(0 . 2)) (test (arity (define* (__a_ a b :allow-other-keys) #f)) (cons 0 *max-arity*)) (test (arity (define* (__a_ a . b) #f)) (cons 0 *max-arity*)) (test (arity (define* (__a_ a :rest b) #f)) (cons 0 *max-arity*)) (test (arity (define* (__a_ a :rest b :allow-other-keys) #f)) (cons 0 *max-arity*)) (test (arity (define* (__a_ a :allow-other-keys) #f)) (cons 0 *max-arity*)) (test (arity (define* (__a_ :rest a) #f)) (cons 0 *max-arity*)) (test (arity (define* (__a_ :rest a b) #f)) (cons 0 *max-arity*)) (test (arity (define* (__a_ :rest a b :allow-other-keys) #f)) (cons 0 *max-arity*)) (test (arity (define* (__a_ :rest a . b) #f)) (cons 0 *max-arity*)) (test (arity (define* (__a_ :rest a :rest b) #f)) (cons 0 *max-arity*)) (test (arity (define* (__a_ :rest a :rest b :allow-other-keys) #f)) (cons 0 *max-arity*)) (test (arity (define* (__a_ :rest a :allow-other-keys) #f)) (cons 0 *max-arity*)) #| (let ((st (symbol-table))) (for-each (lambda (sym) (if (defined? sym) (let ((func (symbol->value sym))) (catch #t (lambda () (let ((min-max (arity func))) (format-logged #t "(test (arity ~A) ~70T'~A)~%" sym min-max) (if min-max (begin (if (> (cdr min-max) 6) (set! (cdr min-max) 6)) (do ((i 0 (+ i 1))) ((= i (car min-max))) (if (aritable? func i) (format-logged #t ";~A: arity: ~A, arg: ~A?~%" sym min-max i))) (do ((i (car min-max) (+ i 1))) ((> i (cdr min-max))) (if (not (aritable? func i)) (format-logged #t ";~A: arity: ~A, arg: ~A?~%" sym min-max i))) (do ((i (+ 1 (cdr min-max)) (+ i 1))) ((>= i 6)) (if (aritable? func i) (format-logged #t ";~A: arity: ~A, arg: ~A?~%" sym min-max i))) )))) (lambda args (format-logged #t " ~A: ~A~%" sym (apply format #f (cadr args))) 'error))))) st)) |# (test (arity *) (cons 0 *max-arity*)) (test (arity +) (cons 0 *max-arity*)) (test (arity -) (cons 1 *max-arity*)) (test (arity /) (cons 1 *max-arity*)) (test (arity curlet) '(0 . 0)) (test (arity <) (cons 2 *max-arity*)) (test (arity =) (cons 2 *max-arity*)) (test (arity >) (cons 2 *max-arity*)) (test (arity lambda*) (cons 2 *max-arity*)) (test (arity unlet) '(0 . 0)) (test (arity call-with-output-file) '(2 . 2)) (test (arity round) '(1 . 1)) (test (arity keyword?) '(1 . 1)) (test (arity openlet) '(1 . 1)) (test (arity varlet) (cons 1 *max-arity*)) (test (arity quote) '(1 . 1)) (test (arity <=) (cons 2 *max-arity*)) (test (arity with-baffle) (cons 1 *max-arity*)) (test (arity >=) (cons 2 *max-arity*)) (test (arity sort!) '(2 . 2)) (test (arity let->list) '(1 . 1)) (test (arity cdaddr) '(1 . 1)) (test (arity do) (cons 2 *max-arity*)) (test (arity if) '(2 . 3)) (test (arity pi) '#f) (test (arity or) (cons 0 *max-arity*)) (test (arity *stdin*) '#f) (test (arity complex) '(2 . 2)) (test (arity values) (cons 0 *max-arity*)) (test (arity string->number) '(1 . 2)) (test (arity most-negative-fixnum) '#f) (test (arity char-downcase) '(1 . 1)) (test (arity char->integer) '(1 . 1)) (test (arity vector) (cons 0 *max-arity*)) (test (arity call/cc) '(1 . 1)) (when (not pure-s7) (test (arity set-current-input-port) '(1 . 1))) (test (arity current-input-port) '(0 . 0)) (test (arity write) '(1 . 2)) (test (arity zero?) '(1 . 1)) (test (arity charstring) '(1 . 2)) (test (arity string) (cons 0 *max-arity*)) (test (arity dynamic-wind) '(3 . 3)) (test (arity symbol-access) '(1 . 2)) (test (arity sublet) (cons 1 *max-arity*)) (test (arity vector-length) '(1 . 1)) (test (arity char-ready?) '(0 . 1)) (test (arity random-state->list) '(0 . 1)) (test (arity with-output-to-file) '(2 . 2)) (test (arity s7-version) '(0 . 0)) (test (arity peek-char) '(0 . 1)) (test (arity :rest) '#f) (test (arity aritable?) '(2 . 2)) (test (arity ceiling) '(1 . 1)) (test (arity define-bacro*) (cons 2 *max-arity*)) (test (arity :allow-other-keys) '#f) (test (arity call-with-exit) '(1 . 1)) (test (arity gensym) '(0 . 1)) (test (arity make-hash-table) '(0 . 2)) (test (arity multiple-value-bind) (cons 2 *max-arity*)) (test (arity procedure-setter) '(1 . 1)) (test (arity define-bacro) (cons 2 *max-arity*)) (test (arity string-append) (cons 0 *max-arity*)) (test (arity port-line-number) '(0 . 1)) (test (arity dilambda) '(2 . 2)) (test (arity letrec*) (cons 2 *max-arity*)) (test (arity multiple-value-set!) (cons 2 *max-arity*)) (test (arity make-iterator) '(1 . 2)) (test (arity random-state) '(1 . 2)) (test (arity format) (cons 1 *max-arity*)) (test (arity vector-ref) (cons 2 *max-arity*)) (test (arity with-input-from-file) '(2 . 2)) (test (arity cadr) '(1 . 1)) (test (arity cond-expand) (cons 0 *max-arity*)) (test (arity case) (cons 2 *max-arity*)) (test (arity string-set!) '(3 . 3)) (test (arity rationalize) '(1 . 2)) (test (arity atan) '(1 . 2)) (test (arity asin) '(1 . 1)) (test (arity assq) '(2 . 2)) (test (arity assv) '(2 . 2)) (test (arity cond) (cons 1 *max-arity*)) (test (arity cons) '(2 . 2)) (test (arity copy) '(1 . 4)) (test (arity else) '#f) (test (arity eqv?) '(2 . 2)) (test (arity define*) (cons 2 *max-arity*)) (test (arity eval) '(1 . 2)) (test (arity let*) (cons 2 *max-arity*)) (test (arity define-macro) (cons 2 *max-arity*)) (test (arity nan?) '(1 . 1)) (test (arity memq) '(2 . 2)) (test (arity memv) '(2 . 2)) (test (arity list) (cons 0 *max-arity*)) (test (arity load) '(1 . 2)) (test (arity for-each) (cons 2 *max-arity*)) (test (arity read) '(0 . 1)) (test (arity set!) '(2 . 2)) (test (arity lambda) (cons 2 *max-arity*)) (test (arity set-car!) '(2 . 2)) (test (arity set-cdr!) '(2 . 2)) (test (arity *features*) (cons 1 *max-arity*)) (test (arity *load-hook*) '(0 . 1)) (test (arity list-set!) (cons 3 *max-arity*)) (test (arity list-tail) '(2 . 2)) (test (arity *error-hook*) '(0 . 2)) (test (arity current-error-port) '(0 . 0)) (test (arity define-expansion) (cons 2 *max-arity*)) (test (arity symbol->value) '(1 . 2)) (test (arity letrec) (cons 2 *max-arity*)) (test (arity symbol->string) '(1 . 1)) (test (arity funclet) '(1 . 1)) (test (arity make-vector) '(1 . 3)) (test (arity member) '(2 . 3)) (unless pure-s7 (test (arity string-fill!) '(2 . 4))) (test (arity hook-functions) '(1 . 1)) (test (arity make-hook) (cons 0 *max-arity*)) (test (arity number->string) '(1 . 2)) (test (arity make-list) '(1 . 2)) (test (arity owlet) '(0 . 0)) (test (arity open-output-string) '(0 . 0)) (test (arity rational?) '(1 . 1)) (test (arity open-input-string) '(1 . 1)) (test (arity procedure-documentation) '(1 . 1)) (test (arity hash-table-set!) '(3 . 3)) (test (arity hash-table-ref) (cons 2 *max-arity*)) (test (arity call-with-values) '(2 . 2)) (test (arity logand) (cons 0 *max-arity*)) (test (arity logior) (cons 0 *max-arity*)) (test (arity lognot) '(1 . 1)) (test (arity logbit?) '(2 . 2)) (test (arity make-string) '(1 . 2)) (test (arity logxor) (cons 0 *max-arity*)) (test (arity vector-set!) (cons 3 *max-arity*)) (test (arity modulo) '(2 . 2)) (test (arity begin) (cons 0 *max-arity*)) (test (arity catch) '(3 . 3)) (test (arity apply) (cons 1 *max-arity*)) (test (arity denominator) '(1 . 1)) (test (arity arity) '(1 . 1)) (test (arity most-positive-fixnum) '#f) (test (arity with-output-to-string) '(1 . 1)) (test (arity assoc) '(2 . 3)) (test (arity call-with-input-file) '(2 . 2)) (test (arity quasiquote) '(1 . 1)) (test (arity fill!) '(2 . 4)) (test (arity newline) '(0 . 1)) (test (arity provided?) '(1 . 1)) (test (arity call-with-current-continuation) '(1 . 1)) (test (arity char-whitespace?) '(1 . 1)) (test (arity random) '(1 . 2)) (test (arity floor) '(1 . 1)) (test (arity read-char) '(0 . 1)) (test (arity even?) '(1 . 1)) (test (arity error) (cons 0 *max-arity*)) (test (arity defined?) '(1 . 3)) (test (arity read-byte) '(0 . 1)) (test (arity macroexpand) '(1 . 1)) (test (arity output-port?) '(1 . 1)) (test (arity substring) '(2 . 3)) (test (arity string-ref) '(2 . 2)) (test (arity *unbound-variable-hook*) '(0 . 1)) (test (arity display) '(1 . 2)) (test (arity read-line) '(0 . 2)) (test (arity define-macro*) (cons 2 *max-arity*)) (test (arity eval-string) '(1 . 2)) (test (arity port-filename) '(0 . 1)) (test (arity define-constant) (cons 2 *max-arity*)) (test (arity list?) '(1 . 1)) (test (arity open-output-file) '(1 . 2)) (test (arity rootlet) '(0 . 0)) (test (arity quotient) '(2 . 2)) (test (arity pair?) '(1 . 1)) (test (arity call-with-input-string) '(2 . 2)) (test (arity random-state?) '(1 . 1)) (test (arity with-input-from-string) '(2 . 2)) (test (arity null?) '(1 . 1)) (test (arity eof-object?) '(1 . 1)) (test (arity hash-table?) '(1 . 1)) (test (arity hash-table) (cons 0 *max-arity*)) (test (arity close-output-port) '(1 . 1)) (test (let () (define-macro (mac1 a b c) `(+ ,a ,b)) (arity mac1)) '(3 . 3)) (test (let () (define-macro (mac1 a b . c) `(+ ,a ,b)) (arity mac1)) (cons 2 *max-arity*)) (test (let () (define-bacro (mac1 a b c) `(+ ,a ,b)) (arity mac1)) '(3 . 3)) (test (let () (define-bacro (mac1 a b . c) `(+ ,a ,b)) (arity mac1)) (cons 2 *max-arity*)) (test (let () (defmacro mac1 (a b c) `(+ ,a ,b)) (arity mac1)) '(3 . 3)) (test (let () (defmacro mac1 (a b . c) `(+ ,a ,b)) (arity mac1)) (cons 2 *max-arity*)) (test (let () (define-macro (mac1 a) `(+ 1 ,a)) (arity mac1)) '(1 . 1)) (test (let () (define-macro* (mac1 . a) `(+ ,a ,b)) (arity mac1)) (cons 0 *max-arity*)) (test (let () (define-macro* (mac1 a) `(+ 1 ,a)) (arity mac1)) '(0 . 1)) (test (let () (define-macro* (mac1 a :rest b) `(+ 1 ,a)) (arity mac1)) (cons 0 *max-arity*)) (test (let () (define-macro* (mac1 a . b) `(,a ,@b)) (arity mac1)) (cons 0 *max-arity*)) (test (let () (define-macro* (mac1 a b c) `(+ ,a ,b)) (arity mac1)) '(0 . 3)) (test (arity "hiho") '(1 . 1)) (test (arity "") #f) (test (arity ()) #f) (test (arity #()) #f) (test (arity #(1 2 3)) (cons 1 *max-arity*)) (test (arity (hash-table '(a . 1))) (cons 1 *max-arity*)) (test (arity (curlet)) '(1 . 1)) (test (let () (call-with-exit (lambda (goto) (arity goto)))) (cons 0 *max-arity*)) (test (arity (make-iterator (hash-table '(a . 1)))) (cons 0 0)) (test (arity (let ((a 1)) (make-iterator (curlet)))) (cons 0 0)) (test (arity (random-state 123)) #f) (define (for-each-subset func args) (define (subset source dest len) (if (null? source) (if (aritable? func len) (apply func dest)) (begin (subset (cdr source) (cons (car source) dest) (+ len 1)) (subset (cdr source) dest len)))) (subset args () 0)) #| (define (for-each-subset func args) (let ((subsets ())) (define (subset source dest len) (if (null? source) (begin (if (member dest subsets) (format-logged #t ";got ~S twice in for-each-subset: ~S~%" dest args)) (set! subsets (cons dest subsets)) (if (aritable? func len) (apply func dest))) (begin (subset (cdr source) (cons (car source) dest) (+ len 1)) (subset (cdr source) dest len)))) (subset args () 0))) |# (test (let ((ctr 0)) (for-each-subset (lambda args (set! ctr (+ ctr 1))) '(1 2 3 4)) ctr) 16) (test (let ((ctr 0)) (for-each-subset (lambda (arg) (set! ctr (+ ctr 1))) '(1 2 3 4)) ctr) 4) (test (let ((ctr 0)) (for-each-subset (lambda (arg1 arg2 arg3) (set! ctr (+ ctr 1))) '(1 2 3 4)) ctr) 4) (test (let ((ctr 0)) (for-each-subset (lambda* (arg1 arg2 arg3) (set! ctr (+ ctr 1))) '(1 2 3 4)) ctr) 15) (test (let ((ctr 0)) (for-each-subset (lambda () (set! ctr (+ ctr 1))) '(1 2 3 4)) ctr) 1) ;; from stackoverflow scheme (define (power-set set) (if (null? set) '(()) (let ((power-set-of-rest (power-set (cdr set)))) (append power-set-of-rest (map (lambda (subset) (cons (car set) subset)) power-set-of-rest))))) (define (for-each-powerset f s) (for-each (lambda (lst) (apply f lst)) (power-set s))) (test (let ((sum 0)) (for-each-powerset (lambda args (set! sum (apply + sum args))) '(1)) sum) 1) (test (let ((sum 0)) (for-each-powerset (lambda args (set! sum (apply + sum args))) '(1 2)) sum) 6) (test (let ((sum 0)) (for-each-powerset (lambda args (set! sum (apply + sum args))) '(1 2 3)) sum) 24) (define (snarf func lst) "(snarf func lst) repeatedly applies func to as many elements of lst as func can take" (let ((arity (arity func))) (if (> (cdr arity) 100) (apply func lst) (let ((n (cdr arity)) (lst-len (length lst))) (if (< lst-len (car arity)) (error 'wrong-number-of-args ";snarf func requires ~A args, but got ~A, ~A" (car arity) lst-len lst) (if (<= lst-len n) (apply func lst) (if (not (zero? (modulo (length lst) n))) (error 'wrong-number-of-args ";snarf will take ~A args at a time, but got ~A in ~A" n lst-len lst) ;; ideally this would accept partial lists (i.e. left-over < req), ;; but then we also need to notice that case in the list-tail below (let () (define (snarf-1 len f args) (if (not (null? args)) (let* ((last (list-tail args (- len 1))) (rest (cdr last))) (dynamic-wind (lambda () (set! (cdr last) ())) (lambda () (apply func args)) (lambda () (set! (cdr last) rest))) (snarf-1 len f rest)))) (snarf-1 n func lst))))))))) (test (let ((lst '(1 2 3 4))) (catch #t (lambda () (snarf (lambda (a b) (format-logged #t "~A ~A~%" a b c)) lst)) (lambda args 'error)) lst) '(1 2 3 4)) (test (snarf (lambda (a b) (format-logged #t "~A ~A~%" a b)) '(1 2 3 4 5)) 'error) (test (snarf (lambda (a b) (format-logged #t "~A ~A~%" a b)) '(1)) 'error) (test (let ((x 0)) (snarf (lambda (a) (set! x (+ x a))) '(1 2 3)) x) 6) (test (let ((x 0)) (snarf (lambda (a b) (set! x (+ x a b))) '(1 2 3 4)) x) 10) (test (let ((x 0)) (snarf (lambda* (a b) (set! x (+ x a b))) '(1 2 3 4)) x) 10) (test (let ((x 0)) (snarf (lambda a (set! x (apply + a))) '(1 2 3 4)) x) 10) (test (let ((x 0)) (snarf (lambda* (a b (c 0)) (set! x (+ x a b c))) '(1 2)) x) 3) ;;; -------------------------------------------------------------------------------- ;;; procedure-source (for-each (lambda (arg) (eval-string (format #f "(define (func) ~S)" arg)) (let ((source (procedure-source func))) (let ((val (func))) (test val arg)))) (list -1 #\a 1 #(1 2 3) 3.14 3/4 1.0+1.0i #t #f () #(()) ':hi "hi")) (for-each (lambda (arg) (test (procedure-source arg) 'error)) (list -1 #\a 1 #(1 2 3) 3.14 3/4 1.0+1.0i () 'hi :hi #(()) (list 1 2 3) '(1 . 2) "hi")) (test (let ((hi (lambda (x) (+ x 1)))) (procedure-source hi)) '(lambda (x) (+ x 1))) (test (procedure-source) 'error) (test (procedure-source abs abs) 'error) (test (procedure-source quasiquote) ()) (test (procedure-source abs) ()) ;(test (let () (define-macro (hi a) `(+ 1 ,a)) (cadr (caddr (procedure-source hi)))) '(lambda (a) ({list} '+ 1 a))) (let () (define (hi a) (+ a x)) (test ((apply let '((x 32)) (list (procedure-source hi))) 12) 44)) ;; i.e. make a closure from (let ((x 32)) ) (let () (define (arg-info f n) ((procedure-source f) 1 n 1 0 2)) ; get the documentation string of f's n-th argument (define* (add-1 (arg ((lambda () "arg should be an integer" 0)))) (+ arg 1)) ; the default value of arg is 0 (test (add-1) 1) (test (add-1 1) 2) (test (arg-info add-1 0) "arg should be an integer")) ;;; -------------------------------------------------------------------------------- ;;; procedure-setter (test (procedure-setter) 'error) (test (procedure-setter car cons) 'error) (test (procedure-setter car) set-car!) (test (procedure-setter vector-ref) vector-set!) (test (procedure-setter make-string) #f) (test (procedure-setter quasiquote) #f) (test (procedure-setter cdr) set-cdr!) (test (procedure-setter hash-table-ref) hash-table-set!) (test (procedure-setter list-ref) list-set!) (test (procedure-setter string-ref) string-set!) (when (not pure-s7) (test (procedure-setter current-input-port) set-current-input-port) (test (procedure-setter current-output-port) set-current-output-port)) (test (procedure-setter current-error-port) set-current-error-port) (for-each (lambda (arg) (test (procedure-setter arg) 'error)) (list -1 #\a #f _ht_ 1 #(1 2 3) 3.14 3/4 1.0+1.0i () 'hi 'car "car" :hi #(()) (list 1 2 3) '(1 . 2) "hi")) (for-each (lambda (arg) (test (set! (procedure-setter abs) arg) 'error)) (list -1 #\a #t _ht_ 1 #(1 2 3) 3.14 3/4 1.0+1.0i () 'hi 'car "car" :hi #(()) (list 1 2 3) '(1 . 2) "hi")) (let () (define (hiho a) a) (define-macro (hiha a) `(+ 1 ,a)) (define-bacro* (hoha a) `(+ 1 ,a)) (define pws (dilambda (lambda () 1) (lambda (x) x))) (test (procedure-setter hiho) #f) (test (procedure-setter hiha) #f) (test (procedure-setter hoha) #f) (test (procedure? (procedure-setter pws)) #t) (test ((procedure-setter pws) 32) 32) ) (test (let ((v #(1 2 3))) ((procedure-setter vector-ref) v 0 32) v) #(32 2 3)) (test (let ((v #(1 2 3))) ((procedure-setter vector-ref) (let () v) 0 32) v) #(32 2 3)) (let () (define (vref v i) (vector-ref v i)) (set! (procedure-setter vref) vector-set!) (test (let ((v (vector 1 2 3))) (set! (vref v 1) 32) v) #(1 32 3))) (let ((old-setter (procedure-setter cadr))) (set! (procedure-setter cadr) (lambda (lst val) (set! (car (cdr lst)) val))) (test (let ((lst (list 1 2 3))) (set! (cadr lst) 4) lst) '(1 4 3)) (test (procedure? (procedure-setter cadr)) #t) (gc) (gc) ; lint.scm tests this exhaustively (test (procedure? (procedure-setter cadr)) #t) (if (not (procedure? (procedure-setter cadr))) (format *stderr* " setter: ~A~%" (procedure-setter cadr))) (set! (procedure-setter cadr) old-setter)) (let () (define-macro (vref v a) `(vector-ref ,v ,a)) (define-macro (vset! v a x) `(vector-set! ,v ,a ,x)) (set! (procedure-setter vref) vset!) (let ((v (vector 1 2 3))) (set! (vref v 1) 32) (test v #(1 32 3))) (define hi 0) (define-macro (xx) `hi) (define-macro (set-xx val) `(set! hi ,val)) (set! (procedure-setter xx) set-xx) (set! (xx) 32) (test hi 32)) (let () (set! (procedure-setter logbit?) (define-macro (m var index on) ; here we want to set "var", so we need a macro `(if ,on (set! ,var (logior ,var (ash 1 ,index))) (set! ,var (logand ,var (lognot (ash 1 ,index))))))) (test (let ((int #b1010)) (set! (logbit? int 0) #t) int) 11)) (let ((old-setter (procedure-setter <))) (set! (procedure-setter <) <) (test (set! (< 3 2) 3) #f) (test (set! (< 1) 2) #t) (set! (procedure-setter <) old-setter)) ;;; -------------------------------------------------------------------------------- ;;; procedure-documentation (test (let () (define hi (let ((documentation "this is a string")) (lambda () 1))) (procedure-documentation hi)) "this is a string") (test (let () (define hi (let ((documentation "this is a string")) (lambda () 1))) (help hi)) "this is a string") (test (let () (define hi (let ((documentation "this is a string")) (lambda () 1))) (#_help hi)) "this is a string") (test (let ((documentation "oops")) (let () (define hi (lambda () 1)) (help hi))) #f) (test (let ((documentation "oops")) (define hi (let () (lambda () 1))) (procedure-documentation hi)) "") (test (let () (define (hi) "this is a string") (hi)) "this is a string") (test (set! (procedure-documentation abs) "X the unknown") 'error) (test (let ((str (procedure-documentation abs))) (set! ((procedure-documentation abs) 1) #\x) (equal? str (procedure-documentation abs))) #t) (test (let ((str (procedure-documentation abs))) (fill! (procedure-documentation abs) #\x) (equal? str (procedure-documentation abs))) #t) (let () (define amac (let ((documentation "this is a string")) (define-macro (_ a) `(+ ,a 1)))) (test (procedure-documentation amac) "this is a string")) (let () (define amac (let ((documentation "this is a string")) (define-macro* (_ (a 1)) `(+ ,a 1)))) (test (procedure-documentation amac) "this is a string")) (let () (define amac (let ((documentation "this is a string")) (define-bacro (_ a) `(+ ,a 1)))) (test (procedure-documentation amac) "this is a string")) (let () (define amac (let ((documentation "this is a string")) (define-bacro* (_ (a 1)) `(+ ,a 1)))) (test (procedure-documentation amac) "this is a string")) (let () (define-macro (amac a) `(+ ,a 1)) (test (procedure-documentation amac) "")) (let () (define-bacro (amac a) ,a) (test (procedure-documentation amac) "")) (test (procedure-documentation abs) "(abs x) returns the absolute value of the real number x") (test (#_help abs) "(abs x) returns the absolute value of the real number x") (test (procedure-documentation 'abs) "(abs x) returns the absolute value of the real number x") (test (let ((hi (let ((documentation "this is a test")) (lambda (x) (+ x 1))))) (list (hi 1) (procedure-documentation hi))) (list 2 "this is a test")) (test (procedure-documentation (let ((documentation "docs")) (lambda* (a b) a))) "docs") (test (procedure-documentation (let ((documentation "")) (lambda* (a b) a))) "") (test (procedure-documentation (let ((documentation "args: (a b)")) (lambda* (a b) a))) "args: (a b)") (test (procedure-documentation (call-with-exit (lambda (c) c))) "") (test (procedure-documentation (call/cc (lambda (c) c))) "") (test (procedure-documentation) 'error) (test (procedure-documentation abs abs) 'error) (if (not (provided? 'snd)) (for-each (lambda (arg) (test (procedure-documentation arg) 'error) (test (help arg) #f)) (list -1 #\a #f _ht_ 1 #(1 2 3) 3.14 3/4 1.0+1.0i () 'hi #(()) (list 1 2 3) '(1 . 2) "hi" :hi))) (let ((p (dilambda (lambda (a) (+ a 1)) (lambda (a b) (+ a b))))) (test (object->string (procedure-source p)) "(lambda (a) (+ a 1))") (let ((p1 p) (p2 (dilambda (let ((documentation "pws doc")) (lambda (a) (+ a 1))) (lambda (a b) (+ a b))))) (test (equal? p p1) #t) (test (equal? p1 p2) #f) (test (procedure-documentation p2) "pws doc") (test (apply p2 '(2)) 3))) (let ((func (eval '(let ((documentation "this is from eval")) (lambda (a) (+ a 1)))))) (test (func 3) 4) (test (procedure-documentation func) "this is from eval")) (test (let ((e (inlet '(x . 3)))) (let ((func (eval '(lambda (a) (+ a x)) e))) (func 2))) 5) (let ((e (openlet (inlet 'help (lambda (obj) "this is helpful"))))) (test ((if (provided? 'snd) s7-help help) e) "this is helpful")) ;;; -------------------------------------------------------------------------------- ;;; procedure-signature (test (procedure-signature boolean?) '(boolean? #t)) (if (not with-bignums) (test (procedure-signature round) '(integer? real?))) (test (procedure-signature quasiquote) #f) (test (procedure-signature test) #f) (for-each (lambda (arg) (test (procedure-documentation arg) 'error)) (list -1 #\a #f _ht_ 1 #(1 2 3) 3.14 3/4 1.0+1.0i () 'hi #(()) (list 1 2 3) '(1 . 2) "hi" :hi)) (test (procedure-signature round abs) 'error) (test (procedure-signature) 'error) (let () (define f1 (let ((signature '(real? boolean?))) (lambda (x) (if x 1.0 2.0)))) (test (procedure-signature f1) '(real? boolean?))) (test (procedure-signature cddddr) '(#t pair?)) (test (procedure-signature *) (let ((L (list 'number?))) (set-cdr! L L) L)) (test (procedure-signature +) (let ((L (list 'number?))) (set-cdr! L L) L)) (test (procedure-signature -) (let ((L (list 'number?))) (set-cdr! L L) L)) (test (procedure-signature /) (let ((L (list 'number?))) (set-cdr! L L) L)) (test (procedure-signature <) (let ((L (list 'boolean? 'real?))) (set-cdr! (cdr L) (cdr L)) L)) (test (procedure-signature =) (let ((L (list 'boolean? 'number?))) (set-cdr! (cdr L) (cdr L)) L)) (test (procedure-signature >) (let ((L (list 'boolean? 'real?))) (set-cdr! (cdr L) (cdr L)) L)) (test (procedure-signature symbol->keyword) '(keyword? symbol?)) (test (procedure-signature close-input-port) '(#t input-port?)) (test (procedure-signature string-append) (let ((L (list 'string?))) (set-cdr! L L) L)) (test (procedure-signature caar) '(#t pair?)) (test (procedure-signature make-polar) '(number? real? real?)) (test (procedure-signature provided?) '(boolean? symbol?)) (test (procedure-signature make-byte-vector) (let ((L (list 'byte-vector? 'integer?))) (set-cdr! (cdr L) (cdr L)) L)) (test (procedure-signature string-copy) (let ((L (list 'string?))) (set-cdr! L L) L)) (test (procedure-signature append) (let ((L (list #t))) (set-cdr! L L) L)) (test (procedure-signature cosh) (let ((L (list 'number?))) (set-cdr! L L) L)) (test (procedure-signature positive?) '(boolean? real?)) (test (procedure-signature input-port?) '(boolean? #t)) (test (procedure-signature complex?) '(boolean? #t)) (test (procedure-signature lognot) (let ((L (list 'integer?))) (set-cdr! L L) L)) (test (procedure-signature logand) (let ((L (list 'integer?))) (set-cdr! L L) L)) (test (procedure-signature reverse!) '(sequence? sequence?)) (test (procedure-signature s7-version) (let ((L (list 'string?))) (set-cdr! L L) L)) (test (procedure-signature pair?) '(boolean? #t)) (test (procedure-signature write-byte) '(integer? integer? output-port?)) (test (procedure-signature delete-file) '(integer? string?)) (test (procedure-signature sequence?) '(boolean? #t)) (test (procedure-signature directory?) '(boolean? string?)) (test (procedure-signature cdar) '(#t pair?)) (test (procedure-signature hash-table-entries) '(integer? hash-table?)) (test (procedure-signature copy) (let ((L (list #t 'sequence? 'sequence? 'integer?))) (set-cdr! (cdddr L) (cdddr L)) L)) (test (procedure-signature char-ci>=?) (let ((L (list 'boolean? 'char?))) (set-cdr! (cdr L) (cdr L)) L)) (test (procedure-signature cadadr) '(#t pair?)) (test (procedure-signature openlet) (let ((L (list #t))) (set-cdr! L L) L)) (test (procedure-signature set-cdr!) '(#t pair? #t)) (test (procedure-signature rootlet) '(let?)) (test (procedure-signature object->string) '(string? #t (boolean? keyword?))) (test (procedure-signature stacktrace) '(string? integer? integer? integer? integer? boolean?)) (test (procedure-signature make-hook) #f) (test (procedure-signature string-length) '(integer? string?)) (test (procedure-signature char-whitespace?) '(boolean? char?)) (test (procedure-signature random) '(number? number? random-state?)) (test (procedure-signature hash-table*) (let ((L (list 'hash-table? #t))) (set-cdr! (cdr L) (cdr L)) L)) (test (procedure-signature string-ci<=?) (let ((L (list 'boolean? 'string?))) (set-cdr! (cdr L) (cdr L)) L)) (test (procedure-signature arity) (let ((L (list #t))) (set-cdr! L L) L)) (test (procedure-signature number?) '(boolean? #t)) (test (procedure-signature infinite?) '(boolean? number?)) (test (procedure-signature logbit?) (let ((L (list 'boolean? 'integer?))) (set-cdr! (cdr L) (cdr L)) L)) (test (procedure-signature cddadr) '(#t pair?)) (test (procedure-signature char-alphabetic?) '(boolean? char?)) (test (procedure-signature keyword->symbol) '(symbol? keyword?)) (test (procedure-signature random-state?) '(boolean? #t)) (test (procedure-signature expt) (let ((L (list 'number?))) (set-cdr! L L) L)) (test (procedure-signature logior) (let ((L (list 'integer?))) (set-cdr! L L) L)) (test (procedure-signature string=?) (let ((L (list 'boolean? 'string?))) (set-cdr! (cdr L) (cdr L)) L)) (test (procedure-signature <=) (let ((L (list 'boolean? 'real?))) (set-cdr! (cdr L) (cdr L)) L)) (test (procedure-signature >=) (let ((L (list 'boolean? 'real?))) (set-cdr! (cdr L) (cdr L)) L)) (test (procedure-signature throw) (let ((L (list #t))) (set-cdr! L L) L)) (test (procedure-signature string-ci>=?) (let ((L (list 'boolean? 'string?))) (set-cdr! (cdr L) (cdr L)) L)) (test (procedure-signature eqv?) (let ((L (list 'boolean? #t))) (set-cdr! (cdr L) (cdr L)) L)) (test (procedure-signature vector-ref) (let ((L (list #t 'vector? 'integer?))) (set-cdr! (cddr L) (cddr L)) L)) (test (procedure-signature float-vector-set!) (let ((L (list 'real? 'float-vector? 'integer? 'integer:real?))) (set-cdr! (cdddr L) (cdddr L)) L)) (test (procedure-signature procedure-signature) '((pair? boolean?) #t)) (test (procedure-signature hash-table-set!) '(#t hash-table? #t #t)) (test (procedure-signature round) '(integer? real?)) (test (procedure-signature char-position) '((integer? boolean?) (char? string?) string? integer?)) (test (procedure-signature make-iterator) '(iterator? sequence? pair?)) (test (procedure-signature complex) '(number? real? real?)) (test (procedure-signature tan) (let ((L (list 'number?))) (set-cdr! L L) L)) (test (procedure-signature eval-string) '(values string? let?)) (test (procedure-signature caadr) '(#t pair?)) (test (procedure-signature current-output-port) '(output-port?)) (test (procedure-signature null?) '(boolean? #t)) (test (procedure-signature caddar) '(#t pair?)) (test (procedure-signature let-ref) '(#t let? symbol?)) (test (procedure-signature nan?) '(boolean? number?)) (test (procedure-signature make-string) '(string? integer? char?)) (test (procedure-signature int-vector) (let ((L (list 'int-vector? 'integer?))) (set-cdr! (cdr L) (cdr L)) L)) (test (procedure-signature truncate) '(integer? real?)) (test (procedure-signature set-current-output-port) '(output-port? output-port?)) (test (procedure-signature list-ref) (let ((L (list #t 'pair? 'integer?))) (set-cdr! (cddr L) (cddr L)) L)) (test (procedure-signature char-cilist) '(pair? let?)) (test (procedure-signature stringlist) (let ((L (list 'list? 'string? 'integer?))) (set-cdr! (cddr L) (cddr L)) L)) (test (procedure-signature hash-table-size) (let ((L (list #t))) (set-cdr! L L) L)) (test (procedure-signature cdaar) '(#t pair?)) (test (procedure-signature set-car!) '(#t pair? #t)) (test (procedure-signature lcm) (let ((L (list 'rational?))) (set-cdr! L L) L)) (test (procedure-signature ->byte-vector) '(byte-vector? string?)) (test (procedure-signature magnitude) '(real? number?)) (test (procedure-signature cddaar) '(#t pair?)) (test (procedure-signature list-tail) '(list? pair? integer?)) (test (procedure-signature vector-length) '(integer? vector?)) (test (procedure-signature read) '(#t input-port?)) (test (procedure-signature vector-fill!) (let ((L (list #t 'vector? #t 'integer?))) (set-cdr! (cdddr L) (cdddr L)) L)) (test (procedure-signature for-each) (let ((L (list #t 'procedure? 'length))) (set-cdr! (cddr L) (cddr L)) L)) (test (procedure-signature memq) '(#t #t pair?)) (test (procedure-signature int-vector-set!) (let ((L (list 'integer? 'int-vector? 'integer?))) (set-cdr! (cddr L) (cddr L)) L)) (test (procedure-signature call-with-input-file) '(#t string? procedure?)) (test (procedure-signature call-with-input-string) '(#t string? procedure?)) (test (procedure-signature dilambda) #f) (test (procedure-signature hash-table?) '(boolean? #t)) (test (procedure-signature dilambda?) '(boolean? #t)) (test (procedure-signature not) '(boolean? #t)) (test (procedure-signature logxor) (let ((L (list 'integer?))) (set-cdr! L L) L)) (test (procedure-signature char-ci=?) (let ((L (list 'boolean? 'char?))) (set-cdr! (cdr L) (cdr L)) L)) (test (procedure-signature c-object?) '(boolean? #t)) (test (procedure-signature vector?) '(boolean? #t)) (test (procedure-signature length) (let ((L (list #t))) (set-cdr! L L) L)) (test (procedure-signature caaddr) '(#t pair?)) (test (procedure-signature vector) (let ((L (list 'vector? #t))) (set-cdr! (cdr L) (cdr L)) L)) (test (procedure-signature error) (let ((L (list #t))) (set-cdr! L L) L)) (test (procedure-signature eq?) (let ((L (list 'boolean? #t))) (set-cdr! (cdr L) (cdr L)) L)) (test (procedure-signature proper-list?) '(boolean? #t)) (test (procedure-signature char-upper-case?) '(boolean? char?)) (test (procedure-signature symbol->dynamic-value) '(#t symbol?)) (test (procedure-signature remainder) (let ((L (list 'real?))) (set-cdr! L L) L)) (test (procedure-signature format) (let ((L (list '(string? boolean?) #t))) (set-cdr! (cdr L) (cdr L)) L)) (test (procedure-signature hash-table) (let ((L (list 'hash-table? 'list?))) (set-cdr! (cdr L) (cdr L)) L)) (test (procedure-signature file-mtime) '(integer? string?)) (test (procedure-signature vector-append) (let ((L (list 'vector?))) (set-cdr! L L) L)) (test (procedure-signature constant?) '(boolean? #t)) (test (procedure-signature string-cilist) '(pair? random-state?)) (test (procedure-signature boolean?) '(boolean? #t)) (test (procedure-signature max) (let ((L (list 'real?))) (set-cdr! L L) L)) (test (procedure-signature cadr) '(#t pair?)) (test (procedure-signature cdaddr) '(#t pair?)) (test (procedure-signature string-ci=?) (let ((L (list 'boolean? 'string?))) (set-cdr! (cdr L) (cdr L)) L)) (test (procedure-signature car) '(#t pair?)) (test (procedure-signature integer->char) '(char? integer?)) (test (procedure-signature char>?) (let ((L (list 'boolean? 'char?))) (set-cdr! (cdr L) (cdr L)) L)) (test (procedure-signature asin) (let ((L (list 'number?))) (set-cdr! L L) L)) (test (procedure-signature current-error-port) '(output-port?)) (test (procedure-signature flush-output-port) '(#t output-port?)) (test (procedure-signature owlet) '(let?)) (test (procedure-signature c-pointer) '(c-pointer? integer?)) (test (procedure-signature string-ci>?) (let ((L (list 'boolean? 'string?))) (set-cdr! (cdr L) (cdr L)) L)) (test (procedure-signature with-output-to-string) '(string? procedure?)) (test (procedure-signature memv) '(#t #t pair?)) (test (procedure-signature char?) '(boolean? #t)) (test (procedure-signature ash) (let ((L (list 'integer?))) (set-cdr! L L) L)) (test (procedure-signature denominator) '(integer? rational?)) (test (procedure-signature string>=?) (let ((L (list 'boolean? 'string?))) (set-cdr! (cdr L) (cdr L)) L)) (test (procedure-signature make-float-vector) '(float-vector? (integer? pair?) real?)) (test (procedure-signature call-with-output-file) '(#t string? procedure?)) (test (procedure-signature call-with-output-string) '(string? procedure?)) (test (procedure-signature char<=?) (let ((L (list 'boolean? 'char?))) (set-cdr! (cdr L) (cdr L)) L)) (test (procedure-signature cddr) '(#t pair?)) (test (procedure-signature current-input-port) '(input-port?)) (test (procedure-signature open-input-string) '(input-port? string?)) (test (procedure-signature write) '(#t #t output-port?)) (test (procedure-signature cdr) '(#t pair?)) (test (procedure-signature list->string) '(string? proper-list?)) (test (procedure-signature catch) (let ((L (list 'values #t 'procedure?))) (set-cdr! (cddr L) (cddr L)) L)) (test (procedure-signature call/cc) '(values procedure?)) (test (procedure-signature port-filename) '(string? #t)) (test (procedure-signature caaadr) '(#t pair?)) (test (procedure-signature symbol?) '(boolean? #t)) (test (procedure-signature values) (let ((L (list 'values #t))) (set-cdr! (cdr L) (cdr L)) L)) (test (procedure-signature integer-length) (let ((L (list 'integer?))) (set-cdr! L L) L)) (test (procedure-signature symbol) '(symbol? string?)) (test (procedure-signature asinh) (let ((L (list 'number?))) (set-cdr! L L) L)) (test (procedure-signature pair-line-number) '(integer? pair?)) (test (procedure-signature load) '(values string? let?)) (test (procedure-signature cos) (let ((L (list 'number?))) (set-cdr! L L) L)) (test (procedure-signature iterate) '(#t iterator?)) (test (procedure-signature substring) (let ((L (list 'string? 'string? 'integer?))) (set-cdr! (cddr L) (cddr L)) L)) (test (procedure-signature tanh) (let ((L (list 'number?))) (set-cdr! L L) L)) (test (procedure-signature symbol-access) '(#t symbol? let?)) (test (procedure-signature provide) '(symbol? symbol?)) (test (procedure-signature rational?) '(boolean? #t)) (test (procedure-signature vector-set!) (let ((L (list #t 'vector? 'integer? 'integer:any?))) (set-cdr! (cdddr L) (cdddr L)) L)) (test (procedure-signature string-set!) '(char? string? integer? char?)) (test (procedure-signature assoc) '((pair? boolean?) #t list? procedure?)) (test (procedure-signature string-ref) '(char? string? integer?)) (test (procedure-signature float-vector?) '(boolean? #t)) (test (procedure-signature log) (let ((L (list 'number?))) (set-cdr! L L) L)) (test (procedure-signature char-ci>?) (let ((L (list 'boolean? 'char?))) (set-cdr! (cdr L) (cdr L)) L)) (test (procedure-signature fill!) (let ((L (list #t 'sequence? #t 'integer?))) (set-cdr! (cdddr L) (cdddr L)) L)) (test (procedure-signature cdaadr) '(#t pair?)) (test (procedure-signature even?) '(boolean? integer?)) (test (procedure-signature make-list) '(list? integer? #t)) (test (procedure-signature modulo) (let ((L (list 'real?))) (set-cdr! L L) L)) (test (procedure-signature defined?) '(boolean? symbol? let? boolean?)) (test (procedure-signature with-input-from-file) '(#t string? procedure?)) (test (procedure-signature with-input-from-string) '(#t string? procedure?)) (test (procedure-signature char-ci<=?) (let ((L (list 'boolean? 'char?))) (set-cdr! (cdr L) (cdr L)) L)) (test (procedure-signature real-part) '(real? number?)) (test (procedure-signature sqrt) (let ((L (list 'number?))) (set-cdr! L L) L)) (test (procedure-signature char-downcase) (let ((L (list 'char?))) (set-cdr! L L) L)) (test (procedure-signature symbol->value) '(#t symbol? let?)) (test (procedure-signature set-current-input-port) '(input-port? input-port?)) (test (procedure-signature assq) '((pair? boolean?) #t list?)) (test (procedure-signature make-vector) '(vector? (integer? pair?) #t boolean?)) (test (procedure-signature eval) '(values list? let?)) (test (procedure-signature caddr) '(#t pair?)) (test (procedure-signature cons) '(pair? #t #t)) (test (procedure-signature port-closed?) '(boolean? #t)) (test (procedure-signature char-upcase) (let ((L (list 'char?))) (set-cdr! L L) L)) (test (procedure-signature list->vector) '(vector? proper-list?)) (test (procedure-signature sort!) '(#t sequence? procedure?)) (test (procedure-signature write-string) (let ((L (list 'string? 'string? 'output-port? 'integer?))) (set-cdr! (cdddr L) (cdddr L)) L)) (test (procedure-signature char>=?) (let ((L (list 'boolean? 'char?))) (set-cdr! (cdr L) (cdr L)) L)) (test (procedure-signature caadar) '(#t pair?)) (test (procedure-signature file-exists?) '(boolean? string?)) (test (procedure-signature vector-dimensions) '(pair? vector?)) (test (procedure-signature exact?) '(boolean? number?)) (test (procedure-signature imag-part) '(real? number?)) (test (procedure-signature exact->inexact) (let ((L (list 'real?))) (set-cdr! L L) L)) (test (procedure-signature make-int-vector) '(int-vector? (integer? pair?) integer?)) (test (procedure-signature procedure-source) '(list? procedure?)) (test (procedure-signature zero?) '(boolean? number?)) (test (procedure-signature dynamic-wind) (let ((L (list 'values 'procedure?))) (set-cdr! (cdr L) (cdr L)) L)) (test (procedure-signature cdddr) '(#t pair?)) (test (procedure-signature list?) '(boolean? #t)) (test (procedure-signature string-downcase) (let ((L (list 'string?))) (set-cdr! L L) L)) (test (procedure-signature sinh) (let ((L (list 'number?))) (set-cdr! L L) L)) (test (procedure-signature get-output-string) '(string? output-port? boolean?)) (test (procedure-signature real?) '(boolean? #t)) (test (procedure-signature char->integer) '(integer? char?)) (test (procedure-signature numerator) '(integer? rational?)) (test (procedure-signature cdadar) '(#t pair?)) (test (procedure-signature assv) '((pair? boolean?) #t list?)) (test (procedure-signature read-line) '((string? eof-object?) input-port? boolean?)) (test (procedure-signature ceiling) '(integer? real?)) (test (procedure-signature char-lower-case?) '(boolean? char?)) (test (procedure-signature call-with-current-continuation) '(values procedure?)) (test (procedure-signature newline) '(#t output-port?)) (test (procedure-signature symbol-table) '(vector?)) (test (procedure-signature set-current-error-port) '(output-port? output-port?)) (test (procedure-signature char-numeric?) '(boolean? char?)) (test (procedure-signature string-upcase) (let ((L (list 'string?))) (set-cdr! L L) L)) (test (procedure-signature member) '(#t #t list? procedure?)) (test (procedure-signature close-output-port) '(#t output-port?)) (test (procedure-signature byte-vector) (let ((L (list 'byte-vector? 'integer?))) (set-cdr! (cdr L) (cdr L)) L)) (test (procedure-signature cadar) '(#t pair?)) (test (procedure-signature morally-equal?) (let ((L (list 'boolean? #t))) (set-cdr! (cdr L) (cdr L)) L)) (test (procedure-signature call-with-exit) '(values procedure?)) (test (procedure-signature funclet) '(let? procedure?)) (test (procedure-signature floor) '(integer? real?)) (test (procedure-signature let-set!) '(#t let? symbol? #t)) (test (procedure-signature system) '(#t string? boolean?)) (test (procedure-signature map) (let ((L (list 'list? 'procedure? 'length))) (set-cdr! (cddr L) (cddr L)) L)) (test (procedure-signature caaaar) '(#t pair?)) (test (procedure-signature port-line-number) '(integer? input-port?)) (test (procedure-signature c-pointer?) '(boolean? #t)) (test (procedure-signature int-vector-ref) (let ((L (list 'integer? 'int-vector? 'integer?))) (set-cdr! (cddr L) (cddr L)) L)) (test (procedure-signature gc) '(#t boolean?)) (test (procedure-signature angle) '(real? number?)) (test (procedure-signature coverlet) (let ((L (list #t))) (set-cdr! L L) L)) (test (procedure-signature float?) '(boolean? #t)) (test (procedure-signature cddar) '(#t pair?)) (test (procedure-signature atan) '(number? number? real?)) (test (procedure-signature varlet) (let ((L (list 'let? 'let? #t))) (set-cdr! (cddr L) (cddr L)) L)) (test (procedure-signature random-state) (let ((L (list 'random-state? 'integer?))) (set-cdr! (cdr L) (cdr L)) L)) (test (procedure-signature emergency-exit) (let ((L (list #t))) (set-cdr! L L) L)) (test (procedure-signature peek-char) '((char? eof-object?) input-port?)) (test (procedure-signature directory->list) '(pair? string?)) (test (procedure-signature cdaaar) '(#t pair?)) (test (procedure-signature string?) '(boolean? #t)) (test (procedure-signature negative?) '(boolean? real?)) (test (procedure-signature gcd) (let ((L (list 'rational?))) (set-cdr! L L) L)) (test (procedure-signature string) (let ((L (list 'string? 'char?))) (set-cdr! (cdr L) (cdr L)) L)) (test (procedure-signature string<=?) (let ((L (list 'boolean? 'string?))) (set-cdr! (cdr L) (cdr L)) L)) (test (procedure-signature cutlet) (let ((L (list 'let? 'let? 'symbol?))) (set-cdr! (cddr L) (cddr L)) L)) (test (procedure-signature outlet) '(let? let?)) (test (procedure-signature continuation?) '(boolean? #t)) (test (procedure-signature byte-vector?) '(boolean? #t)) (test (procedure-signature openlet?) '(boolean? #t)) (test (procedure-signature char=?) (let ((L (list 'boolean? 'char?))) (set-cdr! (cdr L) (cdr L)) L)) (test (procedure-signature cadddr) '(#t pair?)) (test (procedure-signature apply) (let ((L (list 'values 'procedure? #t))) (set-cdr! (cddr L) (cddr L)) L)) (test (procedure-signature inexact?) '(boolean? number?)) (test (procedure-signature open-output-file) '(output-port? string? string?)) (test (procedure-signature rationalize) '(rational? real? real?)) (test (procedure-signature inexact->exact) '(rational? real?)) (test (procedure-signature string>?) (let ((L (list 'boolean? 'string?))) (set-cdr! (cdr L) (cdr L)) L)) (test (procedure-signature iterator?) '(boolean? #t)) (test (procedure-signature string->symbol) '(symbol? string?)) (test (procedure-signature symbol->string) '(string? symbol?)) (test (procedure-signature read-string) '((string? eof-object?) integer? input-port?)) (test (procedure-signature vector->list) (let ((L (list 'list? 'vector? 'integer?))) (set-cdr! (cddr L) (cddr L)) L)) (test (procedure-signature odd?) '(boolean? integer?)) (test (procedure-signature atanh) (let ((L (list 'number?))) (set-cdr! L L) L)) (test (procedure-signature read-byte) '((integer? eof-object?) input-port?)) (test (procedure-signature procedure?) '(boolean? #t)) (test (procedure-signature sublet) (let ((L (list 'let? '(let? null?) #t))) (set-cdr! (cddr L) (cddr L)) L)) (test (procedure-signature list-set!) (let ((L (list #t 'pair? #t))) (set-cdr! (cddr L) (cddr L)) L)) (test (procedure-signature string->number) '((number? boolean?) string? integer?)) (test (procedure-signature number->string) '(string? number? integer?)) #| (define (show-cycle sig) (format *stderr* "(let ((L (list") (do ((L sig (cdr L)) (k 0 (+ k 1)) (done #f)) (done) (if (not (boolean? (car L))) (format *stderr* " '~A" (car L)) (format *stderr* " #t")) (let ((inner-done #f)) (do ((LL sig (cdr LL)) (i 0 (+ i 1))) (inner-done) (if (eq? LL (cdr L)) (begin (set! done #t) (set! inner-done #t) (format *stderr* "))) (set-cdr! ~A ~A) L)" (if (= k 0) "L" (format #f "(c~NCr L)" k #\d)) (if (= i 0) "L" (format #f "(c~NCr L)" i #\d)))) (if (eq? LL L) (set! inner-done #t))))))) (define (test-sym sym) (let ((f (symbol->value sym))) (when (procedure? f) (let ((sig (procedure-signature f))) (if (pair? sig) (if (infinite? (length sig)) (begin (format *stderr* "(test (procedure-signature ~A) " sym) (show-cycle sig) (format *stderr* ")~%")) (format *stderr* "(test (procedure-signature ~A) '~A)~%" sym sig)) (format *stderr* "(test (procedure-signature ~A) ~A)~%" sym sig)))))) (let ((st (symbol-table))) (for-each test-sym st)) |# ;;; -------------------------------------------------------------------------------- ;;; funclet (let ((f1 (lambda (a) (+ a 1))) (f2 (lambda* ((a 2)) (+ a 1)))) (define (hi a) (+ a 1)) (define* (ho (a 1)) (+ a 1)) (test (let? (funclet hi)) #t) (test (let? (funclet ho)) #t) (test (let? (funclet f1)) #t) (test (let? (funclet f2)) #t) (test (let? (funclet abs)) #t) (test (> (length (funclet abs)) 100) #t) (test (fill! (funclet abs) 0) 'error) (test (reverse (funclet abs)) 'error) (test (fill! (funclet ho) 0) 'error) (test (reverse (funclet ho)) 'error)) (test (funclet quasiquote) (rootlet)) (test (funclet lambda) 'error) (test (funclet abs) (rootlet)) (test (funclet cond-expand) (rootlet)) (let () (define func (let ((lst (list 1 2 3))) (lambda (a) (((funclet func) 'lst) a)))) (test (func 1) 2)) #| ;;; but: :(define func (let ((lst (list 1 2 3))) (lambda (a) ((funclet func) 'lst a)))) func :(func 1) ;environment as applicable object takes one argument: (lst 1) ; 'lst which seems inconsistent :(define func (let ((lst (list 1 2 3))) (lambda (a) ((list (funclet func)) 0 'lst)))) func :(func 1) (1 2 3) |# (for-each (lambda (arg) (test (funclet arg) 'error)) (list -1 #\a 1 #(1 2 3) 3.14 3/4 1.0+1.0i () 'hi #(()) (list 1 2 3) '(1 . 2) "hi")) (test (let () (define (hi a) (let ((func __func__)) (list (if (symbol? func) func (car func)) a))) (hi 1)) (list 'hi 1)) (set! (hook-functions *unbound-variable-hook*) ()) (catch #t (lambda () (let () (define (f1 e) (with-let e (hash-table-set! ht :a (abs x)))) (f1 (inlet :ht (make-hash-table) :x -1)) (f1 (inlet :ht (make-hash-table) :x -1)) (test (f1 (inlet :ht (make-hash-table))) 'error))) (lambda args #f)) (catch #t (lambda () (let () (let ((x 1)) (let ((ht (make-hash-table))) (define (f1) (hash-table-set! ht :a (abs x))) (f1) (set! (outlet (curlet)) (inlet)) (test (f1) 'error))))) (lambda args #f)) (let () (define (f1) (with-output-to-string (lambda () (do ((i 0 (+ i 1))) ((= i 3)) (with-let (inlet 'x 1) (display x)))))) (test (f1) "111")) (let () (define (f1 e) (do ((i 0 (+ i 1))) ((= i 3)) (with-let e (hash-table-set! ht :a (abs x))))) (f1 (inlet :ht (make-hash-table) :x -1)) (test (f1 (inlet :ht (make-hash-table) :x -1)) ())) (test (let () (define hi (let ((a 32)) (lambda (b) (+ a b)))) (define ho (with-let (funclet hi) (lambda (b) (+ a b)))) (list (hi 1) (ho 1))) (list 33 33)) (test (let () (define (hi a) (+ a 1)) (with-let (funclet hi) ((eval (procedure-source hi)) 2))) 3) (let () (define (where-is func) (let ((addr (with-let (funclet func) __func__))) (if (not (pair? addr)) "" (list (format #f "~A[~D]" (cadr addr) (caddr addr)) addr)))) (let ((e (where-is ok?))) (test (and (pair? (cadr e)) (< ((cadr e) 2) 1000)) ; this depends on where ok? is in this file #t) (test (and (pair? (cadr e)) (string=? (symbol->string (car (cadr e))) "ok?")) #t) (test (and (pair? (cadr e)) (let ((name (cadr (cadr e)))) (and (string? name) (call-with-exit (lambda (oops) (let ((len (length name))) (do ((i 0 (+ i 1))) ((= i len) #t) (if (and (not (char-alphabetic? (name i))) (not (char=? (name i) #\/)) (not (char=? (name i) #\\)) (not (char=? (name i) #\.)) (not (char=? (name i) #\-)) (not (char-numeric? (name i)))) (begin (format-logged #t "ok? file name: ~S~%" name) (oops #f)))))))))) #t))) (test (let () (define (f1 a) __func__) (f1 1)) 'f1) (test (let () (define (f1 a) (define (f2 b) __func__) (f2 a)) (f1 1)) 'f2) (test (let () (define (f1 a) (define (f2 b) (define (f3 c) __func__) (f3 b)) (f2 a)) (f1 2)) 'f3) (test (let () (define (f1 a) (define (f2 b) (define (f3 c) (define (f4 d) __func__) (f4 c)) (f3 b)) (f2 a)) (f1 1)) 'f4) (test (let () (define (f1 a) (let () (define (f2 b) __func__) (f2 a))) (f1 1)) 'f2) ;(test (with-let (funclet dilambda) __func__) 'dilambda) ; make-procedure-with-setter!? (test (with-let (funclet abs) __func__) #) (test (with-let (funclet quasiquote) __func__) #) (test (with-let (funclet reader-cond) __func__) #) (test (with-let (funclet *error-hook*) __func__) 'make-hook) (let () (define-macro (window func beg end . body) `(call-with-exit (lambda (quit) (do ((notes ',body (cdr notes))) ((null? notes)) (let* ((note (car notes)) (note-beg (cadr note))) (if (<= ,beg note-beg) (if (> note-beg (+ ,beg ,end)) (quit) (,func note)))))))) (test (let ((n 0)) (window (lambda (a-note) (set! n (+ n 1))) 0 1 (fm-violin 0 1 440 .1) (fm-violin .5 1 550 .1) (fm-violin 3 1 330 .1)) n) 2) (test (let ((notes 0) (env #f)) (set! env (curlet)) (window (with-let env (lambda (n) (set! notes (+ notes 1)))) 0 1 (fm-violin 0 1 440 .1) (fm-violin .5 1 550 .1) (fm-violin 3 1 330 .1)) notes) 2)) (test (let () (define-macro (window func beg end . body) `(let ((e (curlet))) (call-with-exit (lambda (quit) (do ((notes ',body (cdr notes))) ((null? notes)) (let* ((note (car notes)) (note-beg (cadr note))) (if (<= ,beg note-beg) (if (> note-beg (+ ,beg ,end)) (quit) ((with-let e ,func) note))))))))) (let ((notes 0)) (window (lambda (n) (set! notes (+ notes 1))) 0 1 (fm-violin 0 1 440 .1) (fm-violin .5 1 550 .1) (fm-violin 3 1 330 .1)) notes)) 2) ;;; this is version dependent ;;;(let ((a 32)) ;;; (define (hi x) (+ x a)) ;;; (test (defined? 'bbbbb (funclet hi)) #f) ;;; (let ((xdef (defined? 'x (funclet hi)))) ;;; (test xdef #t)) ;;; (test (symbol->value 'a (funclet hi)) 32)) (let () (let ((x 32)) (define (hi a) (+ a x)) (let ((xx ((funclet hi) 'x))) (test xx 32)) (let ((s7-version 321)) (test s7-version 321) (let ((xxx ((unlet) 'x))) (test xxx 32) (let ((str (with-let (unlet) (s7-version)))) (test (string? str) #t)))))) ;;; funclet is a mess but it's hard to test mainly because it's different in different versions of s7 ;;; and the test macro affects it ;;; ;;; (test (let () (define (func3 a b) (+ a b)) (let->list (funclet func3))) '((b) (a))) ;;; or is it ((__func__ . func3)) in context? ;;; ;;; ;;; troubles: ;;; (let ((func1 (lambda (a b) (+ a b)))) (symbol->value '__func__ (funclet func1))) -> # ;;; (let ((func1 (lambda (a b) (+ a b)))) (eq? (funclet func1) (rootlet))) -> #t ;;; ;;; (letrec ((func1 (lambda (a b) (+ a b)))) (eq? (funclet func1) (rootlet))) -> #f ;;; (letrec ((func1 (lambda (a b) (+ a b)))) (let->list (funclet func1))) -> ((func1 . #)) ;;; ;;; (let () (define* (func4 (a 1) b) (+ a b)) (let->list (funclet func4))) -> ((__func__ . func4)) ;;; (let () (define-macro (func4 a b) `(+ ,a ,b)) (let->list (funclet func4))) -> ((func4 . #)) ;;; ;;; (let () (let ((func2 (lambda (a b) (+ a b)))) (let->list (funclet func2)))) -> () ;;; ;;; (funclet #) -> (rootlet) ;;; (funclet #) -> (rootlet) ;;; and setter of pws is either global or () ;;; ;;; ;;; this returns #t because the fallback in g_procedure_environment is the global env ;;; (eq? (rootlet) ;;; (let ((a 32)) ;;; (call-with-exit ; or call/cc ;;; (lambda (return) ;;; (funclet return))))) ;;; ;;; (funclet values) -> global env! (like catch/dynamic-wind it's a procedure) ;;; this is also true of (funclet (lambda () 1)) ;;; ;;; :(funclet (float-vector 1 2)) ;;; (inlet) ;;; :(funclet (vector 1 2)) ;;; ;funclet argument, #(1 2), is a vector but should be a procedure or a macro ;;; ; (vector 1 2) ;;; ;;; :(let ((a 1)) (define-macro (m1 b) `(+ ,a ,b)) (let->list (funclet m1))) ;;; ((a . 1) (m1 . #)) ;;; :(let ((a 1)) (define (m1 b) (+ a b)) (let->list (funclet m1))) ;;; ((b)) ;;; :(let ((a 1)) (define (m1 b) (+ a b)) (let->list (outlet (funclet m1)))) ;;; ((__func__ . m1)) ;;; ;;; (procedure-documentation macroexpand) -> "" ; also cond-expand #| ;;; this checks existing procedures (let ((st (symbol-table)) (p (open-output-file "pinfo"))) (for-each (lambda (sym) (if (defined? sym) (let ((val (symbol->value sym))) (format p "---------------- ~A ----------------~%" sym) (catch #t (lambda () (let ((str (procedure-documentation val)) (sym-name (symbol->string sym))) (if (procedure? val) (if (= (length str) 0) (format p "~A: [no doc]~%" sym) (let ((pos (substring? sym-name str))) (if (and (not pos) (not (char-upper-case? (sym-name 0))) (not (char=? (sym-name 0) #\.)) (not (char=? (sym-name 0) #\[))) (format p "~A documentation [no matched name]: ~A~%" sym str)))) (if (> (length str) 0) (format p "~A (not a procedure) documentation: ~A~%" str))))) (lambda args (if (procedure? val) (format p "~A documentation: error: ~A~%" sym (apply format #f (cadr args)))))) (catch #t (lambda () (let ((lst (procedure-source val))) (if (not lst) (if (procedure? val) (format p "~A: [no source]~%" sym)) (if (and (not (pair? lst)) (not (null? lst))) (format p "~A source: ~A~%" sym lst))))) (lambda args (if (procedure? val) (format p "~A source: error: ~A~%" sym (apply format #f (cadr args)))))) (catch #t (lambda () (let ((pe (funclet val))) (if (not pe) (if (procedure? val) (format p "~A: [no environment]~%" sym)) (if (not (let? pe)) (format p "~A environment:~%" sym pe) (if (not (eq? (rootlet) pe)) (format p "~A env: ~A~%" sym (let->list pe))))))) (lambda args (if (procedure? val) (format p "~A environment: error: ~A~%" sym (apply format #f (cadr args)))))) ))) st) (close-output-port p)) |# ;;; -------------------------------------------------------------------------------- ;;; continuation? (for-each (lambda (arg) (test (continuation? arg) #f)) (list -1 #\a 1 #f _ht_ #(1 2 3) 3.14 3/4 1.0+1.0i () 'hi abs #(()) (list 1 2 3) '(1 . 2) "hi" (lambda () 1))) (test (let ((cont #f)) (and (call/cc (lambda (x) (set! cont x) (continuation? x))) (continuation? cont))) #t) (test (let ((cont #f)) (or (call-with-exit (lambda (x) (set! cont x) (continuation? x))) (continuation? cont))) #f) ; x is not a continuation (test (continuation?) 'error) (test (continuation? 1 2) 'error) ;;; -------------------------------------------------------------------------------- ;;; s7-version (test (string? (s7-version)) #t) (test (s7-version 1) 'error) (test (s7-version) (s7-version)) ;;; -------------------------------------------------------------------------------- ;;; eval ;;; eval-string (test (eval-string "(list #b)") 'error) (test (eval-string "(char? #\\spaces)") 'error) (test (eval-string "(car '( . 1))") 'error) (test (eval-string "(car '(. ))") 'error) (test (eval-string "(car '( . ))") 'error) (test (eval-string "(car '(. . . ))") 'error) (test (eval-string "#( . 1)") 'error) (test (eval-string "'(1 2 . )") 'error) (test (eval-string "#(1 2 . )") 'error) (test (eval-string "#'(1 2)") 'error) (test (eval-string "#`(1 2)") 'error) (test (eval-string "#,(1 2)") 'error) (test (eval-string "#`,(1 2)") 'error) (test (eval-string "#1(2)") 'error) (test (eval-string "(+ 1 . . )") 'error) (test (eval-string "(car '(1 . ))") 'error) (test (eval-string "(car '(1 . . 2))") 'error) (test (eval-string "#( . )") 'error) (test (eval-string "#(1 . )") 'error) (test (eval-string "#(. . . )") 'error) (test (eval-string "#(1 . . 2)") 'error) (test (eval-string "'(. 1)") 'error) (test (eval-string "#(. 1)") 'error) (test (eval-string "'(. )") 'error) (test (eval-string "#(. )") 'error) (test (eval-string "(list 1 . 2)") 'error) (test (eval-string "(+ 1 . 2)") 'error) (test (eval-string "(car '@#`')") 'error) (test (eval-string "(list . )") 'error) (test (eval-string "#( .)") 'error) (test (eval-string "(car '( .))") 'error) (test (eval-string "(let ((. 3)) .)") 'error) (test (eval-string "#0d()") 'error) (test (eval-string "`#0d()") 'error) (test (eval-string "'#t:") 'error) ; guile interprets this as #t : and complains unbound variable : (test (eval-string "#t1") 'error) ; similarly this is #t 1 in guile (test (eval-string "#(1 . 2)") 'error) (test (eval-string "#(1 2 . 3)") 'error) (test (eval-string "'#'") 'error) (test (eval-string "#b") 'error) (test (eval-string "(+ 123") 'error) (test (eval-string "(+ 123 0000000000") 'error) (test (eval-string "(+ 1 2)") 3) (test (eval '(+ 1 2)) 3) (test (eval `(,+ ,1 ,2)) 3) (test (eval (list + 1 2)) 3) (test (eval `(+ 1 (eval `(* 2 3)))) 7) (test (eval `(+ 1 (eval-string "(* 2 3)"))) 7) (test (eval-string "(+ 1 (eval-string \"(* 2 3)\"))") 7) (test (eval `(+ 1 2 . 3)) 'error) (test (eval-string) 'error) (test (eval) 'error) (test (eval-string "") #f) (test (eval ()) ()) (test (eval ()) ()) (test (eval-string "1" () ()) 'error) (test (eval () () ()) 'error) (test (eval "1") "1") (test (eval-string #t) 'error) (test (eval #(+ 1 2)) #(+ 1 2)) (test (+ 1 (values (eval-string "(catch #t (lambda () asdf) (lambda args 2))") (eval-string "(catch #t (lambda () asdf) (lambda args 3))"))) 6) (let () (define e1 (let ((a 10)) (curlet))) (test (eval 'a e1) 10)) ; from andy wingo (let () (define e1 (let ((a 10)) (curlet))) (eval '(set! a 32) e1) (test (eval 'a e1) 32)) (test (eval '(begin (define __eval_var__ 1) __eval_var__) (rootlet)) 1) (test (let () __eval_var__) 1) (test (eval-string "(begin (define __eval_var1__ 12) __eval_var1__)" (rootlet)) 12) (test (let () __eval_var1__) 12) (test (let () (eval '(begin (define __eval_var2__ 123) __eval_var__) (curlet)) __eval_var2__) 123) (test (let () __eval_var2__) 'error) ;; from scheme wg (let ((x (list 'cons 1 2)) (y (list (list 'quote 'cons) 1 2))) (set-car! x cons) (set-car! (cdar y) cons) (test (eval x) (eval y))) (test (eval (list 'cons 1 2)) (eval (list cons 1 2))) (let ((f (lambda (a) (+ a 1)))) (test (eval (list 'f 2)) (eval (list f 2)))) (test (apply "hi" 1 ()) #\i) (test (eval ("hi" 1)) #\i) (test (apply + 1 1 (cons 1 (quote ()))) 3) (test (eq? (eval (quote (quote ()))) ()) #t) (test (apply (cons (quote cons) (cons 1 (quote ((quote ()))))) 1 ()) 1) ; essentially ((list 'cons 1 ...) 1) => 1 (test (eval ((cons (quote cons) (cons 1 (quote ((quote ()))))) 1)) 1) (test (eval (eval (list '+ 1 2))) 3) (test (eval if) if) (test (eval quote) quote) (test (eval (eval (list define* #(1)))) 'error) (test (eval (eval (list lambda* ()))) 'error) (test (eval (eval (list letrec "hi"))) 'error) (test (eval (eval (cons define-macro 1))) 'error) (test (eval (eval (cons quote "hi"))) 'error) (test (eval (eval (list and "hi"))) "hi") (test (apply + (+ 1) ()) 1) (test (apply #(1) (+) ()) 1) (test (apply + (+) ()) 0) (test (eval #()) #()) (test (apply (lambda () #f)) #f) (test (eval '(if #f #f)) (if #f #f)) (test (let ((ho 32)) (symbol? (eval (eval (eval (eval '''''ho)))))) #t) (test (eval '(case 0 ((1) 2) ((0) 1))) 1) (test (eval '(cond ((= 1 2) 3) (#t 4))) 4) (test (eval-string (string-append "(list 1 2 3)" (string #\newline) (string #\newline))) (list 1 2 3)) (eval-string (string-append "(define evalstr_1 32)" (string #\newline) "(define evalstr_2 2)")) (test (eval-string "(+ evalstr_1 evalstr_2)") 34) (eval-string (string-append "(set! evalstr_1 3)" "(set! evalstr_2 12)")) (test (eval-string "(+ evalstr_1 evalstr_2)") 15) (test (+ (eval `(values 1 2 3)) 4) 10) (test (+ (eval-string "(values 1 2 3)") 4) 10) (test (+ 1 (eval-string "(+ 2 3)") 4) 10) (test ((eval-string "(lambda (a) (+ a 1))") 2) 3) (test (eval ((eval-string "(lambda (a) (list '+ a 1))") 2)) 3) (test (eval-string "(+ 1 (eval (list '+ 1 2)))") 4) (test (eq? (eval-string "else") else) #t) (test (eq? (with-input-from-string "else" read) else) #f) (test (eq? (with-input-from-string "lambda" read) lambda) #f) (test (eq? (eval-string "lambda") lambda) #t) (test (((eval-string "lambda") () (+ 1 2))) 3) (test (symbol? (eval-string "lambda")) #f) (test (symbol? (with-input-from-string "lambda" read)) #t) (test (eq? (with-input-from-string "else" (lambda () (eval (read)))) else) #t) (test (eval-string "'___a ; b") '___a) (test (eval-string "'___a #| b |#") '___a) (test (eval-string "'___a 1") 1) (test (eval-string "'___a ; 2\n3") 3) (for-each (lambda (arg) (test (eval-string arg) 'error)) (list -1 0 1 512 #\a #(1 2 3) 3.14 2/3 1.5+0.3i 1+i () 'hi :hi abs #(()) (list 1 2 3) '(1 . 2) (lambda () 1))) (for-each (lambda (arg) (test (eval-string "(+ 1 2)" arg) 'error)) (list -1 0 1 512 #\a #(1 2 3) 3.14 2/3 1.5+0.3i 1+i 'hi abs "hi" :hi #(()) (lambda () 1))) (test (let () (define-macro (hiho a) `(+ ,a 1)) (hiho 3)) 4) (test (let () (define-macro (hiho) `(+ 3 1)) (hiho)) 4) (test (let () (define-macro (hiho) `(+ 3 1)) (hiho 1)) 'error) (test (let () (define-macro (hi a) `(+ ,@a)) (hi (1 2 3))) 6) (test (let () (define-macro (hi a) `(+ ,a 1) #f) (hi 2)) #f) (test (let () (define-macro (mac1 a) `',a) (equal? (mac1 (+ 1 2)) '(+ 1 2))) #t) (test (let () (define-macro (hi . a) `,@a) (hi 1)) 1) (test (let () (define-macro (hi a) `(+ , a 1)) (hi 1)) 2) (test (let () (define-macro (hi a) `(eval `(+ ,,a 1))) (hi 1)) 2) (test (let () (define-macro (hi a) `(eval (let ((a 12)) `(+ ,,a 1)))) (hi 1)) 2) (test (let () (define-macro (hi a) `(eval (let ((a 12)) `(+ ,a 1)))) (hi 1)) 13) (test (let () (define-macro (hi a) `(eval (let ((a 12)) `(let ((a 100)) (+ ,a 1))))) (hi 1)) 13) (test (let () (define-macro (hi a) `(eval (let ((a 12)) `(let ((a 100)) (+ a 1))))) (hi 1)) 101) (test (let () (define-macro (hi q) ``(,,q)) (hi (* 2 3))) '(6)) (test (let () (define-macro (hi q) `(let ((q 32)) `(,,q))) (hi (* 2 3))) '(6)) (test (let () (define-macro (hi q) `(let ((q 32)) `(,q))) (hi (* 2 3))) '(32)) (test (let () (define-macro (hi q) `(let () ,@(list q))) (hi (* 2 3))) 6) (test (let () (define-macro (tst a) ``(+ 1 ,,a)) (tst 2)) '(+ 1 2)) (test (let () (define-macro (tst a) ```(+ 1 ,,,a)) (eval (tst 2))) '(+ 1 2)) (test (let () (define-macro (tst a) ``(+ 1 ,,a)) (tst (+ 2 3))) '(+ 1 5)) (test (let () (define-macro (tst a) ``(+ 1 ,@,a)) (tst '(2 3))) '(+ 1 2 3)) (test (let () (define-macro (tst a) ``(+ 1 ,,@a)) (tst (2 3))) '(+ 1 2 3)) (test (let () (define-macro (tst a) ```(+ 1 ,,,@a)) (eval (tst (2 3)))) '(+ 1 2 3)) (test (let () (define-macro (tst a) ```(+ 1 ,,@,@a)) (eval (tst ('(2 3))))) '(+ 1 2 3)) (test (let () (define-macro (tst a) ````(+ 1 ,,,,@a)) (eval (eval (eval (tst (2 3)))))) 6) (test (let () (define-macro (tst a) ``(+ 1 ,@,@a)) (tst ('(2 3)))) '(+ 1 2 3)) (test (let () (define-macro (tst a b) `(+ 1 ,a (apply * `(2 ,,@b)))) (tst 3 (4 5))) 44) (test (let () (define-macro (tst . a) `(+ 1 ,@a)) (tst 2 3)) 6) (test (let () (define-macro (tst . a) `(+ 1 ,@a (apply * `(2 ,,@a)))) (tst 2 3)) 18) (test (let () (define-macro (tst a) ```(+ 1 ,@,@,@a)) (eval (tst ('('(2 3)))))) '(+ 1 2 3)) (test (let () (define-macro (hi a) `(+ ,a 1)) (procedure? hi)) #f) (test (let () (define-macro (hi a) `(let ((@ 32)) (+ @ ,a))) (hi @)) 64) (test (let () (define-macro (hi @) `(+ 1 ,@@)) (hi (2 3))) 6) ; ,@ is ambiguous (test (let () (define-macro (tst a) `(+ 1 (if (> ,a 0) (tst (- ,a 1)) 0))) (tst 3)) 4) (test (let () (define-macro (hi a) (if (list? a) `(+ 1 ,@a) `(+ 1 ,a))) (* (hi 1) (hi (2 3)))) 12) (test (let ((x 1)) (eval `(+ 3 ,x))) 4) (test (let ((x 1)) (eval (eval `(let ((x 2)) `(+ 3 ,x ,,x))))) 6) (test (let ((x 1)) (eval (eval (eval `(let ((x 2)) `(let ((x 3)) `(+ 10 ,x ,,x ,,,x))))))) 16) (test (let ((x 1)) (eval (eval (eval (eval `(let ((x 2)) `(let ((x 3)) `(let ((x 30)) `(+ 100 ,x ,,x ,,,x ,,,,x))))))))) 136) (test (let () (define-bacro (hiho a) `(+ ,a 1)) (hiho 3)) 4) (test (let () (define-bacro (hiho) `(+ 3 1)) (hiho)) 4) (test (let () (define-bacro (hiho) `(+ 3 1)) (hiho 1)) 'error) (test (let () (define-bacro (hi a) `(+ ,@a)) (hi (1 2 3))) 6) (test (let () (define-bacro (hi a) `(+ ,a 1) #f) (hi 2)) #f) (test (let () (define-bacro (mac1 a) `',a) (equal? (mac1 (+ 1 2)) '(+ 1 2))) #t) (test (let () (define-bacro (tst a) ``(+ 1 ,,a)) (tst 2)) '(+ 1 2)) (test (let () (define-bacro (tst a) ```(+ 1 ,,,a)) (eval (tst 2))) '(+ 1 2)) (test (let () (define-bacro (tst a) ``(+ 1 ,,a)) (tst (+ 2 3))) '(+ 1 5)) (test (let () (define-bacro (tst a) ``(+ 1 ,@,a)) (tst '(2 3))) '(+ 1 2 3)) (test (let () (define-bacro (tst a) ``(+ 1 ,,@a)) (tst (2 3))) '(+ 1 2 3)) (test (let () (define-bacro (tst a) ```(+ 1 ,,,@a)) (eval (tst (2 3)))) '(+ 1 2 3)) (test (let () (define-bacro (tst a) ```(+ 1 ,,@,@a)) (eval (tst ('(2 3))))) '(+ 1 2 3)) (test (let () (define-bacro (tst a) ````(+ 1 ,,,,@a)) (eval (eval (eval (tst (2 3)))))) 6) (test (let () (define-bacro (tst a) ``(+ 1 ,@,@a)) (tst ('(2 3)))) '(+ 1 2 3)) (test (let () (define-bacro (tst a b) `(+ 1 ,a (apply * `(2 ,,@b)))) (tst 3 (4 5))) 44) (test (let () (define-bacro (tst . a) `(+ 1 ,@a)) (tst 2 3)) 6) (test (let () (define-bacro (tst . a) `(+ 1 ,@a (apply * `(2 ,,@a)))) (tst 2 3)) 18) (test (let () (define-bacro (tst a) ```(+ 1 ,@,@,@a)) (eval (tst ('('(2 3)))))) '(+ 1 2 3)) (test (let () (define-bacro (hi a) `(+ ,a 1)) (procedure? hi)) #f) (test (let () (define-bacro (hi a) `(let ((@ 32)) (+ @ ,a))) (hi @)) 64) (test (let () (define-bacro (hi @) `(+ 1 ,@@)) (hi (2 3))) 6) ; ,@ is ambiguous (test (let () (define-bacro (tst a) `(+ 1 (if (> ,a 0) (tst (- ,a 1)) 0))) (tst 3)) 4) (test (let () (define-bacro (hi a) (if (list? a) `(+ 1 ,@a) `(+ 1 ,a))) (* (hi 1) (hi (2 3)))) 12) (test (let () (define-bacro (hiho a) `(+ ,a 1)) (macro? hiho)) #t) (test (let () (define-bacro* (hiho (a 1)) `(+ ,a 1)) (macro? hiho)) #t) (test (let () (define-macro (hiho a) `(+ ,a 1)) (macro? hiho)) #t) (test (let () (define-macro* (hiho (a 1)) `(+ ,a 1)) (macro? hiho)) #t) #| (define-macro (when2 test . body) `((apply lambda (list '(test) '(if test (let () ,@body)))) ,test)) (define-macro (when2 test . body) `(if ,test (let () ,@body))) (define-macro (when2 test . body) `((lambda (test) (if test (let () ,@body))) ,test)) (define-macro (when2 test . body) `(let ((func (apply lambda `(() ,,@body)))) (if ,test (func)))) |# (test (define-macro) 'error) (test (define-macro 1) 'error) (test (define-macro . 1) 'error) (test (apply define-macro '(1)) 'error) (test (define-macro (1 2 3)) 'error) (test (define-macro (1 2) 3) 'error) (test (define-macro (a)) 'error) (test (define-macro (a)) 'error) (test (define-macro (a 1) 2) 'error) (test (define-macro . a) 'error) (test (define :hi 1) 'error) (test (define hi: 1) 'error) (test (define-macro (:hi a) `(+ ,a 1)) 'error) (test (define-macro (:hi a) `(+ ,a 1)) 'error) (test (define-macro (hi 1 . 2) 1) 'error) (test (define-macro (hi) 1 . 2) 'error) (test (define-macro (:) "" . #(1)) 'error) (test (defmacro : #(1) . :) 'error) (test (defmacro hi ()) 'error) (test (define-macro (mac . 1) 1) 'error) (test (define-macro (mac 1) 1) 'error) (test (define-macro (a #()) 1) 'error) (test (define-macro (i 1) => (j 2)) 'error) (test (define hi 1 . 2) 'error) (test (defmacro hi hi . hi) 'error) (test (define-macro (hi hi) . hi) 'error) (test (((lambda () (define-macro (hi a) `(+ 1 ,a)) hi)) 3) 4) (test (let () (define-macro (hi a b) `(list ,@a . ,@b)) (hi (1 2) ((2 3)))) '(1 2 2 3)) (test (let () (define-macro (hi a b) `(list ,@a . ,b)) (hi (1 2) (2 3))) '(1 2 2 3)) (test (let () (define-macro (hi a b) `(list ,@a ,@b)) (hi (1 2) (2 3))) '(1 2 2 3)) (let ((vals #(0 0))) #| (let () (define (hi a) (+ 1 a)) (define (use-hi b) (hi b)) (set! (vals 0) (use-hi 1)) (define (hi a) (+ 2 a)) (set! (vals 1) (use-hi 1)) (test vals #(2 3))) ; hmmm, or possibly #(2 2)... see comment above (line 13494 or thereabouts) |# (let () (define-macro (hi a) `(+ 1 ,a)) (define (use-hi b) (hi b)) (set! (vals 0) (use-hi 1)) (define-macro (hi a) `(+ 2 ,a)) (set! (vals 1) (use-hi 1)) (test vals #(2 3))) (let () (define (use-hi b) (hhi b)) (define-macro (hhi a) `(+ 1 ,a)) (set! (vals 0) (use-hi 1)) (define-macro (hhi a) `(+ 2 ,a)) (set! (vals 1) (use-hi 1)) (test vals #(2 3)))) (test (let () (define-macro (hanger name-and-args) `(define ,(car name-and-args) (+ ,@(map (lambda (arg) arg) (cdr name-and-args))))) (hanger (hi 1 2 3)) hi) 6) (test (let () (define-macro (hanger name-and-args) `(define-macro (,(car name-and-args)) `(+ ,@(map (lambda (arg) arg) (cdr ',name-and-args))))) (hanger (hi 1 2 3)) (hi)) 6) (let () ;; inspired by Doug Hoyte, "Let Over Lambda" (define (mcxr path lst) (define (cxr-1 path lst) (if (null? path) lst (if (char=? (car path) #\a) (cxr-1 (cdr path) (car lst)) (cxr-1 (cdr path) (cdr lst))))) (let ((p (string->list (symbol->string path)))) (if (char=? (car p) #\c) (set! p (cdr p))) (let ((p (reverse p))) (if (char=? (car p) #\r) (set! p (cdr p))) (cxr-1 p lst)))) (test (mcxr 'cr '(1 2 3)) '(1 2 3)) (test (mcxr 'cadddddddr '(1 2 3 4 5 6 7 8)) 8) (test (mcxr 'caadadadadadadadr '(1 (2 (3 (4 (5 (6 (7 (8))))))))) 8) (define-macro (cxr path lst) (let ((p (string->list (symbol->string path)))) (if (char=? (car p) #\c) (set! p (cdr p))) (let ((p (reverse p))) (if (char=? (car p) #\r) (set! p (cdr p))) (let ((func 'arg)) (for-each (lambda (f) (set! func (list (if (char=? f #\a) 'car 'cdr) func))) p) `((lambda (arg) ,func) ,lst))))) (test (cxr car '(1 2 3)) 1) (test (cxr cadddddddr '(1 2 3 4 5 6 7 8)) 8) (test (cxr caadadadadadadadr '(1 (2 (3 (4 (5 (6 (7 (8))))))))) 8) ) ;; this is the best of them! (let () (define-macro (c?r path) ;; here "path" is a list and "X" marks the spot in it that we are trying to access ;; (a (b ((c X)))) -- anything after the X is ignored, other symbols are just placeholders ;; c?r returns a function that gets X ;; maybe ... for cdr? (c?r (a ...); right now it's using dot: (c?r (a . X)) -> cdr ;; (c?r (a b X)) -> caddr, ;; (c?r (a (b X))) -> cadadr ;; ((c?r (a a a X)) '(1 2 3 4 5 6)) -> 4 ;; ((c?r (a (b c X))) '(1 (2 3 4))) -> 4 ;; ((c?r (((((a (b (c (d (e X)))))))))) '(((((1 (2 (3 (4 (5 6)))))))))) -> 6 ;; ((c?r (((((a (b (c (X (e f)))))))))) '(((((1 (2 (3 (4 (5 6)))))))))) -> 4 ;; (procedure-source (c?r (((((a (b (c (X (e f))))))))))) -> (lambda (lst) (car (car (cdr (car (cdr (car (cdr (car (car (car (car lst)))))))))))) (define (X-marks-the-spot accessor tree) (if (pair? tree) (or (X-marks-the-spot (cons 'car accessor) (car tree)) (X-marks-the-spot (cons 'cdr accessor) (cdr tree))) (if (eq? tree 'X) accessor #f))) (let ((accessor (X-marks-the-spot () path))) (if (not accessor) (error "can't find the spot! ~A" path) (let ((len (length accessor))) (if (< len 5) ; it's a built-in function (let ((name (make-string (+ len 2)))) (set! (name 0) #\c) (set! (name (+ len 1)) #\r) (do ((i 0 (+ i 1)) (a accessor (cdr a))) ((= i len)) (set! (name (+ i 1)) (if (eq? (car a) 'car) #\a #\d))) (string->symbol name)) (let ((body 'lst)) ; make a new function to find the spot (for-each (lambda (f) (set! body (list f body))) (reverse accessor)) `(lambda (lst) ,body))))))) (test ((c?r (a b X)) (list 1 2 3 4)) 3) (test ((c?r (a (b X))) '(1 (2 3) ((4)))) 3) (test ((c?r (a a a X)) '(1 2 3 4 5 6)) 4) (test ((c?r (a (b c X))) '(1 (2 3 4))) 4) (test ((c?r (((((a (b (c (d (e X)))))))))) '(((((1 (2 (3 (4 (5 6)))))))))) 6) (test ((c?r (((((a (b (c (X (e f)))))))))) '(((((1 (2 (3 (4 (5 6)))))))))) 4)) (let () (define-macro (nested-for-each args func . lsts) (let ((body `(,func ,@args))) (for-each (lambda (arg lst) (set! body `(for-each (lambda (,arg) ,body) ,lst))) args lsts) body)) ;;(nested-for-each (a b) + '(1 2) '(3 4)) -> ;; (for-each (lambda (b) (for-each (lambda (a) (+ a b)) '(1 2))) '(3 4)) (define-macro (nested-map args func . lsts) (let ((body `(,func ,@args))) (for-each (lambda (arg lst) (set! body `(map (lambda (,arg) ,body) ,lst))) args lsts) body)) ;;(nested-map (a b) + '(1 2) '(3 4)) ;; ((4 5) (5 6)) ;;(nested-map (a b) / '(1 2) '(3 4)) ;; ((1/3 2/3) (1/4 1/2)) (test (nested-map (a b) + '(1 2) '(3 4)) '((4 5) (5 6))) (test (nested-map (a b) / '(1 2) '(3 4)) '((1/3 2/3) (1/4 1/2))) ) (let () (define-macro (define-curried name-and-args . body) `(define ,@(let ((newlst `(begin ,@body))) (define (rewrap lst) (if (pair? (car lst)) (begin (set! newlst (cons 'lambda (cons (cdr lst) (list newlst)))) (rewrap (car lst))) (list (car lst) (list 'lambda (cdr lst) newlst)))) (rewrap name-and-args)))) (define-curried (((((f a) b) c) d) e) (* a b c d e)) (test (((((f 1) 2) 3) 4) 5) 120) (define-curried (((((f a b) c) d e) f) g) (* a b c d e f g)) (test (((((f 1 2) 3) 4 5) 6) 7) 5040) (define-curried (((foo)) x) (+ x 34)) (test (((foo)) 300) 334) (define-curried ((foo-1) x) (+ x 34)) (test ((foo-1) 200) 234) ) (test (let () (define (set-cadr! a b) (set-car! (cdr a) b) b) (let ((lst (list 1 2 3))) (set-cadr! lst 32) lst)) '(1 32 3)) ;;; macro? (test (macro? pi) #f) (test (macro? quasiquote) #t) ; s7_define_macro in s7.c (test (let ((m quasiquote)) (macro? m)) #t) (test (macro? macroexpand) #f) ; it's now syntactic (test (macro? cond) #f) (test (macro? letrec) #f) (for-each (lambda (arg) (test (macro? arg) #f)) (list -1 #\a 1 #(1 2 3) 3.14 3/4 1.0+1.0i () car abs (lambda () 1) #2d((1 2) (3 4)) _ht_ _null_ _c_obj_ #f 'hi #(()) (list 1 2 3) '(1 . 2) "hi")) (test (macro?) 'error) (define-macro (fully-expand form) (define (expand form) (if (pair? form) (if (and (symbol? (car form)) (macro? (symbol->value (car form)))) (expand (apply (eval (procedure-source (symbol->value (car form)))) (cdr form))) (cons (expand (car form)) (expand (cdr form)))) form)) (expand form)) ; use (list 'quote (expand form)) to get fully-macroexpand of s7.html (see below) (define fe1-called #f) (define-macro (fe1 a) (set! fe1-called #t) `(+ ,a 1)) (define fe2-called #f) (define-macro (fe2 b) (set! fe2-called #f) `(+ (fe1 ,b) 2)) (fully-expand (define (fe3 c) (+ (fe2 c) (fe1 (+ c 1))))) (set! fe1-called #f) (set! fe2-called #f) (let ((val (fe3 3))) (if (or (not (= val 11)) fe1-called fe2-called) (format-logged #t "fully-expand: ~A ~A ~A ~A~%" val (procedure-source fe3) fe1-called fe2-called))) (let () (define-macro (swap a b) `(set! ,b (with-let (inlet 'e (curlet) 'tmp ,a) (with-let e (set! ,a ,b)) tmp))) ;; this doesn't know when to use the setter (define-macro (fully-macroexpand form) (define (expand form) (if (pair? form) (if (and (symbol? (car form)) (macro? (symbol->value (car form)))) (expand (apply (eval (procedure-source (symbol->value (car form)))) (cdr form))) (cons (expand (car form)) (expand (cdr form)))) form)) (list 'quote (expand form))) (define-macro (define-with-macros name&args . body) `(apply define ',name&args (fully-macroexpand `(begin ,,@body)))) (define-with-macros (call3 x) (let ((a 1) (b x)) (swap a b) (list a b))) (test (call3 4) '(4 1))) #| ;;; here is the setter-aware form... (define-macro (fm1 form) (define (expand form) (if (pair? form) (if (and (symbol? (car form)) (macro? (symbol->value (car form)))) (expand (apply macroexpand (list form))) (if (and (eq? (car form) 'set!) (pair? (cdr form)) (pair? (cadr form)) (macro? (symbol->value (caadr form)))) (expand (apply (eval (procedure-source (procedure-setter (symbol->value (caadr form))))) (append (cdadr form) (cddr form)))) (cons (expand (car form)) (expand (cdr form))))) form)) (list 'quote (expand form))) ;this is broken (define-macro (define-safe-macro name&args . body) `(define-macro ,name&args (with-let (#_inlet (unlet) ,@(#_let ((rest (#_if (#_list? name&args) #f (#_list-tail name&args (#_abs (#_length name&args)))))) (#_append (#_map (#_lambda (b) `(#_cons ',b ,b)) (#_cdr name&args)) (#_if rest `((#_cons ',rest ,rest)) ())))) ,@body))) |# (test (let () (define-macro (pop sym) (let ((v (gensym "v"))) `(let ((,v (car ,sym))) (set! ,sym (cdr ,sym)) ,v))) (test (macro? pop) #t) (let ((lst (list 1 2 3))) (let ((val (pop lst))) (and (= val 1) (equal? lst (list 2 3)))))) #t) (define-macro (destructuring-bind lst expr . body) `(let ((ex ,expr)) (define (flatten lst) (cond ((null? lst) ()) ((pair? lst) (if (pair? (car lst)) (append (flatten (car lst)) (flatten (cdr lst))) (cons (car lst) (flatten (cdr lst))))) (#t lst))) (define (structures-equal? l1 l2) (if (pair? l1) (and (pair? l2) (structures-equal? (car l1) (car l2)) (structures-equal? (cdr l1) (cdr l2))) (not (pair? l2)))) (if (not (structures-equal? ',lst ex)) (error "~A and ~A do not match" ',lst ex)) (let ((names (flatten ',lst)) (vals (flatten ex))) (apply (eval (list 'lambda names ',@body)) vals)))) (test (destructuring-bind (a b) (list 1 2) (+ a b)) 3) (test (destructuring-bind ((a) b) (list (list 1) 2) (+ a b)) 3) (test (destructuring-bind (a (b c)) (list 1 (list 2 3)) (+ a b c)) 6) (test (let ((x 1)) (destructuring-bind (a b) (list x 2) (+ a b))) 3) #| (define-macro (destructuring-bind lst expr . body) `(let ,(letrec ((flatten (lambda (lst1 lst2 args) (cond ((null? lst1) args) ((not (pair? lst1)) (cons (list lst1 lst2) args)) (#t (flatten (car lst1) (car lst2) (flatten (cdr lst1) (cdr lst2) args))))))) (flatten lst expr ())) ,@body)) (format #t "~A~%" (destructuring-bind (a b) (1 2) (+ a b))) (format #t "~A~%" (destructuring-bind (a (b)) (1 (2)) (+ a b))) (format #t "~A~%" (destructuring-bind ((a b)) ((1 2)) (+ a b))) (format #t "~A~%" (destructuring-bind ((a (b c))) ((1 (2 1))) (+ a b))) (format #t "~A~%" (destructuring-bind (a b) (0 (+ 1 2)) (+ a b))) (format #t "~A~%" (destructuring-bind (a ((b))) ((+ 1 3) (((- 1 2)))) (+ a b))) (format #t "~A~%" (destructuring-bind (a ((b c)) d e) (1 ((2 3)) (+ 4 5) 6) (list a b c d e))) ;; CL version: (define-macro (destructuring-bind-1 lst expr . body) `(let ,(letrec ((flatten (lambda (lst1 lst2 args) (cond ((null? lst1) args) ((not (pair? lst1)) (cons (list lst1 (list 'quote lst2)) args)) (#t (flatten (car lst1) (car lst2) (flatten (cdr lst1) (cdr lst2) args))))))) (flatten lst (eval expr) ())) ,@body)) (format #t "~A~%" (destructuring-bind-1 (a b) '(1 2) (list a b))) (format #t "~A~%" (destructuring-bind-1 (a (b)) '(1 (2)) (list a b))) (format #t "~A~%" (destructuring-bind-1 ((a b)) '((1 2)) (list a b))) (format #t "~A~%" (destructuring-bind-1 ((a (b c))) '((1 (2 1))) (list a b))) (format #t "~A~%" (destructuring-bind-1 (a b) '(0 (+ 1 2)) (list a b))) (format #t "~A~%" (destructuring-bind-1 (a ((b))) '((+ 1 3) (((- 1 2)))) (list a b))) (format #t "~A~%" (destructuring-bind-1 (a ((b c)) d e) '(1 ((2 3)) (4 5) 6) (list a b c d e))) ;; CL version but values not quoted (I like this one) (define-macro (destructuring-bind-2 lst expr . body) `(let ,(letrec ((flatten (lambda (lst1 lst2 args) (cond ((null? lst1) args) ((not (pair? lst1)) (cons (list lst1 lst2) args)) (#t (flatten (car lst1) (car lst2) (flatten (cdr lst1) (cdr lst2) args))))))) (flatten lst (eval expr) ())) ,@body)) (format #t "~A~%" (destructuring-bind-2 (a b) (list 1 2) (+ a b))) (format #t "~A~%" (destructuring-bind-2 (a (b)) '(1 (2)) (+ a b))) (format #t "~A~%" (destructuring-bind-2 ((a b)) '((1 2)) (+ a b))) (format #t "~A~%" (destructuring-bind-2 ((a (b c))) '((1 (2 1))) (+ a b))) (format #t "~A~%" (destructuring-bind-2 (a b) '(0 (+ 1 2)) (+ a b))) (format #t "~A~%" (destructuring-bind-2 (a ((b))) '((+ 1 3) (((- 1 2)))) (+ a b))) (format #t "~A~%" (destructuring-bind-2 (a ((b c)) d e) '(1 ((2 3)) (+ 4 5) 6) (list a b c d e))) (format #t "~A~%" (let ((x 1)) (destructuring-bind-2 (a ((b))) '((+ x 3) (((- x 2)))) (+ a b)))) |# (define-macro (once-only names . body) (let ((gensyms (map (lambda (n) (gensym)) names))) `(let (,@(map (lambda (g) `(,g (gensym))) gensyms)) `(let (,,@(map (lambda (g n) ``(,,g ,,n)) gensyms names)) ,(let (,@(map (lambda (n g) `(,n ,g)) names gensyms)) ,@body))))) (let () (define-macro (hiho start end) (once-only (start end) `(list ,start ,end (+ 2 ,start) (+ ,end 2)))) (test (let ((ctr 0)) (let ((lst (hiho (let () (set! ctr (+ ctr 1)) ctr) (let () (set! ctr (+ ctr 1)) ctr)))) (list ctr lst))) '(2 (1 2 3 4)))) (define-macro (once-only-2 names . body) (let ((gensyms (map (lambda (n) (gensym)) names))) `(let (,@(map (lambda (g) (list g '(gensym))) gensyms)) `(let (,,@(map (lambda (g n) (list list g n)) gensyms names)) ,(let (,@(map (lambda (n g) (list n g)) names gensyms)) ,@body))))) (let () (define-macro (hiho start end) (once-only-2 (start end) `(list ,start ,end (+ 2 ,start) (+ ,end 2)))) (test (let ((ctr 0)) (let ((lst (hiho (let () (set! ctr (+ ctr 1)) ctr) (let () (set! ctr (+ ctr 1)) ctr)))) (list ctr lst))) '(2 (1 2 3 4)))) ;;; (define-bacro (once-only-1 names . body) ;;; `(let (,@(map (lambda (name) `(,name ,(eval name))) names)) ;;; ,@body)) ;;; can't be right: (let ((names 1)) (once-only (names) (+ names 1))) ;;; if define-macro used here: syntax-error ("~A: unbound variable" start) in the example below (define once-only-1 (let ((names (gensym)) (body (gensym))) (apply define-bacro `((once ,names . ,body) `(let (,@(map (lambda (name) `(,name ,(eval name))) ,names)) ,@,body))) once)) (let () (define-bacro (hiho start end) ; note the bacro! not a macro here (once-only-1 (start end) `(list ,start ,end (+ 2 ,start) (+ ,end 2)))) (test (let ((ctr 0)) (let ((lst (hiho (let () (set! ctr (+ ctr 1)) ctr) (let () (set! ctr (+ ctr 1)) ctr)))) (list ctr lst))) '(2 (1 2 3 4))) (test (let ((names 1)) (once-only-1 (names) (+ names 1))) 2) (test (let ((body 1)) (once-only-1 (body) (+ body 1))) 2) ; so body above also has to be gensym'd ) (define once-only-3 (let ((names (gensym)) (body (gensym))) (apply define-bacro `((,(gensym) ,names . ,body) `(let (,@(map (lambda (name) `(,name ,(eval name))) ,names)) ,@,body))))) (let () (define-bacro (hiho start end) ; note the bacro! not a macro here (once-only-3 (start end) `(list ,start ,end (+ 2 ,start) (+ ,end 2)))) (test (let ((ctr 0)) (let ((lst (hiho (let () (set! ctr (+ ctr 1)) ctr) (let () (set! ctr (+ ctr 1)) ctr)))) (list ctr lst))) '(2 (1 2 3 4))) (test (let ((names 1)) (once-only-3 (names) (+ names 1))) 2) (test (let ((body 1)) (once-only-3 (body) (+ body 1))) 2) ; so body above also has to be gensym'd ) (let () #| (define setf (let ((args (gensym))) (apply define-bacro `((setf-1 . ,args) (if (not (null? ,args)) (begin (apply set! (car ,args) (cadr ,args) ()) (apply setf (cddr ,args)))))) ; not setf-1 -- it's not defined except during the definition setf-1)) |# (define setf (let ((args (gensym)) (name (gensym))) (apply define-bacro `((,name . ,args) (unless (null? ,args) (apply set! (car ,args) (cadr ,args) ()) (apply setf (cddr ,args))))))) #| ;; the bad form: (define-bacro (setf . args) (if (not (null? args)) (begin (apply set! (car args) (eval (cadr args)) ()) (apply setf (cddr args))))) |# (define-macro (psetf . args) (let ((bindings ()) (settings ())) (do ((arglist args (cddr arglist))) ((null? arglist)) (let* ((g (gensym))) (set! bindings (cons (list g (cadr arglist)) bindings)) (set! settings (cons `(set! ,(car arglist) ,g) settings)))) `(let ,bindings ,@settings))) (test (let ((a 1) (b 2)) (setf a b b 3) (list a b)) '(2 3)) (test (let ((a 1) (b 2)) (setf a b b (+ a 3)) (list a b)) '(2 5)) (test (let ((a #(1)) (b 2)) (setf (a 0) b b (+ (a 0) 3)) (list a b)) '(#(2) 5)) (test (let ((a 1) (b 2)) (setf a b b a) (list a b)) '(2 2)) (test (let ((a 1) (b 2)) (setf a '(+ 1 2) b a) (list a b)) '((+ 1 2) (+ 1 2))) (test (let ((args 1) (arg 1)) (setf args 2 arg 3) (list args arg)) '(2 3)) (test (let ((args 1) (arg 1)) (setf args (+ 2 3) arg args) (list args arg)) '(5 5)) (test (let ((args 1) (arg 1)) (setf args '(+ 2 3) arg (car args)) (list args arg)) '((+ 2 3) +)) (test (let ((a 1) (b 2)) (psetf a b b a) (list a b)) '(2 1)) (test (let ((a #(1)) (b 2)) (psetf (a 0) b b (+ (a 0) 3)) (list a b)) '(#(2) 4)) (test (let ((a 1) (b 2)) (psetf a '(+ 1 2) b a) (list a b)) '((+ 1 2) 1)) (test (let ((new-args 1)) (psetf new-args (+ new-args 1)) new-args) 2) (test (let ((args 1) (arg 1)) (psetf args 2 arg 3) (list args arg)) '(2 3)) (test (let ((args 1) (arg 1)) (psetf args (+ 2 3) arg args) (list args arg)) '(5 1)) (test (let ((args 1) (arg 1)) (psetf args '(+ 2 3) arg (car args)) (list args arg)) 'error) (test (let ((args '(1 2)) (arg 1)) (psetf args '(+ 2 3) arg (car args)) (list args arg)) '((+ 2 3) 1)) ) (define-macro (with-gensyms names . body) `(let ,(map (lambda (n) `(,n (gensym))) names) ,@body)) (define-macro (define-clean-macro name-and-args . body) ;; the new backquote implementation breaks this slightly -- it's currently confused about unquoted nil in the original (let ((syms ())) (define (walk func lst) (if (and (func lst) (pair? lst)) (begin (walk func (car lst)) (walk func (cdr lst))))) (define (car-member sym lst) (if (null? lst) #f (if (eq? sym (caar lst)) (cdar lst) (car-member sym (cdr lst))))) (define (walker val) (if (pair? val) (if (eq? (car val) 'quote) (or (car-member (cadr val) syms) (and (pair? (cadr val)) (or (and (eq? (caadr val) 'quote) ; 'sym -> (quote (quote sym)) val) (append (list 'list) (walker (cadr val))))) (cadr val)) (cons (walker (car val)) (walker (cdr val)))) (or (car-member val syms) val))) (walk (lambda (val) (if (and (pair? val) (eq? (car val) 'quote) (symbol? (cadr val)) (not (car-member (cadr val) syms))) (set! syms (cons (cons (cadr val) (gensym (symbol->string (cadr val)))) syms))) (or (not (pair? val)) (not (eq? (car val) 'quote)) (not (pair? (cadr val))) (not (eq? (caadr val) 'quote)))) body) (let* ((new-body (walker body)) (new-syms (map (lambda (slot) (list (cdr slot) '(gensym))) syms)) (new-globals (let ((result ())) (for-each (lambda (slot) (if (defined? (car slot)) (set! result (cons (list 'set! (cdr slot) (car slot)) result)))) syms) result))) `(define-macro ,name-and-args (let ,new-syms ,@new-globals `(begin ,,@new-body)))))) (define-macro (define-immaculo name-and-args . body) (let* ((gensyms (map (lambda (g) (gensym)) (cdr name-and-args))) (args (cdr (copy name-and-args))) (name (car name-and-args)) (set-args (map (lambda (a g) `(list ',g ,a)) args gensyms)) (get-args (map (lambda (a g) `(quote (cons ',a ,g))) args gensyms)) (blocked-args (map (lambda (a) `(,a ',a)) args)) (new-body (list (apply let blocked-args body)))) `(define-macro ,name-and-args `(let ,(list ,@set-args) ,(list 'with-let (append (list 'sublet) (list (list 'funclet ,name)) (list ,@get-args)) ',@new-body))))) ;;; this is not perfect: if unquote is on expr involving an arg, it's going to be unhappy, ;;; but we can always move the unquote in, so it's purely stylistic. Another way would ;;; be to remove one level of unquotes throughout -- then the blocked-args and new-body ;;; would be unneeded. ;;; in fact, it's wrong -- in the body we need to make explicit let refs to avoid collisions ;;; these tests are pointless (test (let () (define-clean-macro (hi a) `(+ ,a 1)) (hi 1)) 2) (test (let () (define-immaculo (hi a) `(+ ,a 1)) (hi 1)) 2) (test (let () (define-immaculo (hi a) `(let ((b 23)) (+ b ,a))) (hi 2)) 25) (test (let () (define-immaculo (mac a b) `(let ((c (+ ,a ,b))) (let ((d 12)) (* ,a ,b c d)))) (mac 2 3)) 360) (test (let () (define-immaculo (mac a b) `(let ((c (+ ,a ,b))) (let ((d 12)) (* ,a ,b c d)))) (let ((c 2) (d 3)) (mac c d))) 360) (test (let () (define-clean-macro (mac a . body) `(+ ,a ,@body)) (mac 2 3 4)) 9) (test (let () (define-clean-macro (mac) (let ((a 1)) `(+ ,a 1))) (mac)) 2) (test (let () (define-immaculo (mac) (let ((a 1)) `(+ ,a 1))) (mac)) 2) (test (let () (define-immaculo (hi a) `(list 'a ,a)) (hi 1)) (list 'a 1)) (test (let () (define-macro (hi a) `(+ 1 (if ,(= a 0) 0 (hi ,(- a 1))))) (hi 3)) 4) (test (let () (define-macro (hi a) `(+ 1 ,a)) ((if #t hi abs) -3)) -2) (test (let () (apply define-macro '((m a) `(+ 1 ,a))) (m 2)) 3) (test (let () (apply (eval (apply define-macro '((m a) `(+ 1 ,a)))) '(3))) 4) (test (let () (apply (eval (apply define '((hi a) (+ a 1)))) '(2))) 3) (test (let () ((eval (apply define '((hi a) (+ a 1)))) 3)) 4) (test (let () ((eval (apply define-macro '((m a) `(+ 1 ,a)))) 3)) 4) (test (let () ((apply define '((hi a) (+ a 1))) 3)) 4) (test (let () ((apply define-macro '((m a) `(+ 1 ,a))) 3)) 4) (test (let () (define-macro (mu args . body) (let ((m (gensym))) `(apply define-macro '((,m ,@args) ,@body)))) ((mu (a) `(+ 1 ,a)) 3)) 4) (test (let () (define-macro (hi a) `(+ 1 ,a)) (map hi '(1 2 3))) '(2 3 4)) (test (let () (define-macro (hi a) `(+ ,a 1)) (apply hi '(4))) 5) (test (let () (define-macro (hi a) `(+ ,a 1)) (define (fmac mac) (apply mac '(4))) (fmac hi)) 5) (test (let () (define (make-mac) (define-macro (hi a) `(+ ,a 1)) hi) (let ((x (make-mac))) (x 2))) 3) (define-macro* (_mac1_) `(+ 1 2)) (test (_mac1_) 3) (define-macro* (_mac2_ a) `(+ ,a 2)) (test (_mac2_ 1) 3) (test (_mac2_ :a 2) 4) (define-macro* (_mac3_ (a 1)) `(+ ,a 2)) (test (_mac3_) 3) (test (_mac3_ 3) 5) (test (_mac3_ :a 0) 2) (define-macro* (_mac4_ (a 1) (b 2)) `(+ ,a ,b)) (test (_mac4_) 3) (test (_mac4_ :b 3) 4) (test (_mac4_ 2 :b 3) 5) (test (_mac4_ :b 10 :a 12) 22) (test (_mac4_ :a 4) 6) (define-bacro* (_mac21_) `(+ 1 2)) (test (_mac21_) 3) (define-bacro* (_mac22_ a) `(+ ,a 2)) (test (_mac22_ 1) 3) (test (_mac22_ :a 2) 4) (define-bacro* (_mac23_ (a 1)) `(+ ,a 2)) (test (_mac23_) 3) (test (_mac23_ 3) 5) (test (_mac23_ :a 0) 2) (define-bacro* (_mac24_ (a 1) (b 2)) `(+ ,a ,b)) (test (_mac24_) 3) (test (_mac24_ :b 3) 4) (test (_mac24_ 2 :b 3) 5) (test (_mac24_ :b 10 :a 12) 22) (test (_mac24_ :a 4) 6) (define-macro* (_mac11_) `(+ 1 2)) (test (_mac11_) 3) (define-macro* (_mac12_ a) `(+ ,a 2)) (test (_mac12_ 1) 3) (test (_mac12_ :a 2) 4) (define-macro* (_mac13_ (a 1)) `(+ ,a 2)) (test (_mac13_) 3) (test (_mac13_ 3) 5) (test (_mac13_ :a 0) 2) (define-macro* (_mac14_ (a 1) (b 2)) `(+ ,a ,b)) (test (_mac14_) 3) (test (_mac14_ :b 3) 4) (test (_mac14_ 2 :b 3) 5) (test (_mac14_ :b 10 :a 12) 22) (test (_mac14_ :a 4) 6) (define-bacro (symbol-set! var val) `(set! ,(symbol->value var) ,val)) (test (let ((x 32) (y 'x)) (symbol-set! y 123) (list x y)) '(123 x)) (define-bacro (symbol-eset! var val) `(set! ,(eval var) ,val)) (test (let ((x '(1 2 3)) (y `(x 1))) (symbol-eset! y 123) (list x y)) '((1 123 3) (x 1))) (test (let ((x #(1 2 3)) (y `(x 1))) (symbol-eset! y 123) (list x y)) '(#(1 123 3) (x 1))) (let () (define-macro (hi a) `````(+ ,,,,,a 1)) (test (eval (eval (eval (eval (hi 2))))) 3) (define-macro (hi a) `(+ ,@@a)) (test (hi (1 2 3)) 'error) (define-macro (hi @a) `(+ ,@@a)) (test (hi (1 2 3)) 6)) ;;; -------------------------------------------------------------------------------- ;;; # readers ;;; *#readers* ;;; ;;; #\; reader: (let ((old-readers *#readers*)) ;; testing *#readers* is slightly tricky because the reader runs before we evaluate the test expression ;; so in these cases, the new reader use is always in a string (set! *#readers* (list (cons #\s (lambda (str) 123)))) (let ((val (eval-string "(+ 1 #s1)"))) ; force this into the current reader (test val 124)) (set! *#readers* ()) (set! *#readers* (cons (cons #\t (lambda (str) (string->number (substring str 1) 12))) *#readers*)) (num-test (string->number "#tb") 11) (num-test (string->number "#t11.3") 13.25) (when (not pure-s7) (num-test (string->number "#e#t11.3") 53/4) (num-test (string->number "#t#e1.5") 17/12) (num-test (string->number "#i#t1a") 22.0) (num-test (string->number "#t#i1a") 22.0)) ; ??? this is analogous to #x#i1a = 26.0 (num-test (string->number "#t#t1a") 22.0) (num-test (string->number "#t#t#t1a") 22.0) (test (eval-string "#t") #t) (test (eval-string "#T1") 'error) (set! *#readers* (cons (cons #\. (lambda (str) (if (string=? str ".") (eval (read)) #f))) *#readers*)) (test (eval-string "'(1 2 #.(* 3 4) 5)") '(1 2 12 5)) (num-test (string->number "#t1a") 22) (test (eval-string "'(1 #t(2))") '(1 #t (2))) (test (string->number "#t1r") #f) (set! *#readers* (list (cons #\t (lambda (str) ;; in the duplicated case: "t#t..." (if (< (length str) 3) (string->number (substring str 1) 12) (and (not (char=? (str 1) #\#)) (not (char=? (str 2) #\t)) (string->number (substring str 1) 12))))))) (test (string->number "#t#t1a") #f) (set! *#readers* (cons (cons #\x (lambda (str) (or (if (< (length str) 3) (string->number (substring str 1) 7) (and (not (char=? (str 1) #\#)) (not (char=? (str 2) #\x)) (string->number (substring str 1) 7))) 'error))) *#readers*)) (num-test (string->number "#x12") 9) (num-test (string->number "#x-142.1e-1") -11.30612244898) (when (not pure-s7) (num-test (string->number "#e#x-142.1e-1") -554/49) (num-test (string->number "#e#ta.a") 65/6)) (num-test (string->number "#t460.88") 648.72222222222) (num-test (string->number "#x1") 1) (test (string->number "#te") #f) (num-test (string->number "#x10") 7) (test (string->number "#x17") #f) (num-test (string->number "#x106") 55) (test (string->number "#x#t1") #f) (let () (define (read-in-radix str radix) ;; no error checking, only integers (define (char->digit c) (cond ((char-numeric? c) (- (char->integer c) (char->integer #\0))) ((char-lower-case? c) (+ 10 (- (char->integer c) (char->integer #\a)))) (#t (+ 10 (- (char->integer c) (char->integer #\A)))))) (let* ((negative (char=? (str 0) #\-)) (len (length str)) (j (if (or negative (char=? (str 0) #\+)) 2 1))) ; 1st char is "z" (do ((sum (char->digit (str j)) (+ (* sum radix) (char->digit (str j))))) ((= j (- len 1)) sum) (set! j (+ j 1))))) (set! *#readers* (list (cons #\z (lambda (str) (read-in-radix str 32))))) (num-test (string->number "#z1p") 57) ) (let ((p1 (dilambda (lambda (str) (string->number (substring str 1) 12)) (lambda (a) a)))) (set! *#readers* (list (cons #\t p1))) (num-test (string->number "#ta") 10) (num-test (string->number "#t11.6") 13.5) (when (not pure-s7) (num-test (string->number "#e#t11.6") 27/2))) (set! *#readers* old-readers) (num-test (string->number "#x106") 262) (num-test (string->number "#x17") 23) ) (let ((old-readers *#readers*) (reader-file tmp-output-file)) ;; to test readers in a file, we need to write the file and load it, so here we go... (set! *#readers* ()) (define circular-list-reader (let ((known-vals #f) (top-n -1)) (lambda (str) (define (replace-syms lst) ;; walk through the new list, replacing our special keywords ;; with the associated locations (define (replace-sym tree getter) (if (keyword? (getter tree)) (let ((n (string->number (symbol->string (keyword->symbol (getter tree)))))) (if (integer? n) (let ((lst (assoc n known-vals))) (if lst (set! (getter tree) (cdr lst)) (format *stderr* "#~D# is not defined~%" n))))))) (define (walk-tree tree) (if (pair? tree) (begin (if (pair? (car tree)) (walk-tree (car tree)) (replace-sym tree car)) (if (pair? (cdr tree)) (walk-tree (cdr tree)) (replace-sym tree cdr)))) tree) (walk-tree (cdr lst))) ;; str is whatever followed the #, first char is a digit (let* ((len (length str)) (last-char (str (- len 1)))) (and (memq last-char '(#\= #\#)) ; is it #n= or #n#? (let ((n (string->number (substring str 0 (- len 1))))) (and (integer? n) (begin (if (not known-vals) (begin (set! known-vals ()) (set! top-n n))) (if (char=? last-char #\=) ; #n= (and (char=? (peek-char) #\() (let ((cur-val (assoc n known-vals))) ;; associate the number and the list it points to ;; if cur-val, perhaps complain? (#n# redefined) (let ((lst (catch #t (lambda () (read)) (lambda args ; a read error (set! known-vals #f) ; so clear our state (apply throw args))))) ; and pass the error on up (if (not cur-val) (set! known-vals (cons (set! cur-val (cons n lst)) known-vals)) (set! (cdr cur-val) lst))) (if (= n top-n) ; replace our special keywords (let ((result (replace-syms cur-val))) (set! known-vals #f) result) (cdr cur-val)))) ; #n=? ;; else it's #n# -- set a marker for now since we may not ;; have its associated value yet. We use a symbol name that ;; string->number accepts. (symbol->keyword (symbol (string-append (number->string n) (string #\null) " "))))))) ; #n? ))))) ; #n? (define (sharp-plus str) ;; str here is "+", we assume either a symbol or a expression involving symbols follows (let* ((e (if (string=? str "+") (read) ; must be #+(...) (string->symbol (substring str 1)))) ; #+feature (expr (read))) (if (symbol? e) (if (provided? e) expr (values)) (if (pair? e) (begin (define (traverse tree) (if (pair? tree) (cons (traverse (car tree)) (if (null? (cdr tree)) () (traverse (cdr tree)))) (if (memq tree '(and or not)) tree (and (symbol? tree) (provided? tree))))) (if (eval (traverse e)) expr (values))) (error "strange #+ chooser: ~S~%" e))))) (set! *#readers* (cons (cons #\+ sharp-plus) (cons (cons #\. (lambda (str) (if (string=? str ".") (eval (read)) #f))) (cons (cons #\; (lambda (str) (if (string=? str ";") (read)) (values))) *#readers*)))) (when pure-s7 (set! *#readers* (append *#readers* old-readers))) (do ((i 0 (+ i 1))) ((= i 10)) (set! *#readers* (cons (cons (integer->char (+ i (char->integer #\0))) circular-list-reader) *#readers*))) (call-with-output-file reader-file (lambda (port) (format port "(define x #.(+ 1 2 3))~%") (format port "(define xlst '(1 2 3 #.(* 2 2)))~%") (format port "(define y '#1=(2 . #1#))~%") (format port "(define y1 '#1=(2 #2=(3 #3=(#1#) . #3#) . #2#))~%") (format port "(define y2 #2D((1 2) (3 4)))~%") (format port "#+s7 (define z 32)~%#+asdf (define z 123)~%") (format port "#+(and complex-numbers (or snd s7)) (define z1 1)~%#+(and (not complex-numbers) (or asdf s7)) (define z1 123)~%") (format port "(define x2 (+ 1 #;(* 2 3) 4))~%") (format port "(define x3 (+ #;32 1 2))~%") (format port "(define x4 (+ #; 32 1 2))~%") (format port "(define y3 (+ 1 (car '#1=(2 . #1#))))~%") (format port "(define y4 #.(+ 1 (car '#1=(2 . #1#))))~%") (format port "(define y5 (+ 1 #.(* 2 3) #.(* 4 #.(+ 5 6))))~%") (format port "(define r1 '(1 #. #;(+ 2 3) 4))~%") (format port "(define r2 '(1 #. #;(+ 2 3) (* 2 4)))~%") (format port "(define r3 '(1 #; #.(+ 2 3) (* 2 4)))~%") (format port "(define r4 '(1 #. #1=(+ 2 3) (* 2 4)))~%") (format port "(define r5 '(1 #. #1=(+ 2 #. 3) (* 2 4)))~%") ;; but #.3 is ambiguous: '(1 #. #1=(+ 2 #.3) (* 2 4)) (format port "(define r6 '(1 #. #1=(+ 2 #+pi 3) (* 2 4)))~%") (format port "(define r7 '(1 #. #1=(+ 2 #+pi #1#) (* 2 4)))~%") (format port "(define r8 '(1 #+s7 #1=(1 2) 3))~%") (format port "(define r9 '(1 #+asdf #1=(1 2) 3))~%") (format port "(define r10 #. #1#)~%") (format port "(define r13 #+s7 #e0.0)~%") (format port "(define r14 #. #o1)~%") (format port "(define r15 #. #_-)~%") (format port "(define r16 (#+s7 #_- #d0))~%") (format port "(define r17 (#. #_- #o1))~%") (format port "(define r18 (#. #. #_+))~%") (format port "(define r19 (#. #+s7 #_+))~%") (format port "(define r20 (#+s7 #+s7 #_+))~%") (format port "(define r21 (#_-(#_+ 1 2)3))~%") (format port "(define r22 (#(#_+ 1 2)#o1))~%") (format port "(define r23 (+ #;#1.##+asdf ))~%") (format port "(define r24 (+ #. #;(#_+ 1 2)))~%") (format port "(define r25 (+ #;#1=#2=))~%") (format port "(define r26 (+ #;#2#(#_+ 1 2)))~%") (format port "(define r27 (+ #;#1=.))~%") (format port "(define r28 (+ #; #; #; ()))~%") (format port "(define r29 (+ 3(#_+ 1 2)#;#. ))~%") (format port "(define r30 (+ #;#2=#+asdf#+s7))~%") (format port "(define r31 (+ #;#f#=#\\))~%") (format port "(define r32 (#. + (#_-(#_+ 1 2))))~%") (format port "(define r33 (+ 1 #+asdf #\\a 2))~%") (format port "(define r34 (+ #++(#. #\\a)))~%") (format port "(define r35 (+ #+s7 #; (33)))~%") (format port "(define r36 (cos #. #. #. `(string->symbol \"pi\")))~%") )) (let () (load reader-file (curlet)) (if (not (= x 6)) (format-logged #t ";#.(+ 1 2 3) -> ~A~%" x)) (if (not (equal? xlst '(1 2 3 4))) (format-logged #t ";#.(* 2 2) -> ~A~%" xlst)) (if (not (equal? (object->string y) "#1=(2 . #1#)")) (format-logged #t ";'#1=(2 . #1#) -> ~S~%" (object->string y))) (if (not (equal? (object->string y1) "#1=(2 #3=(3 #2=(#1#) . #2#) . #3#)")) (format-logged #t ";'#1=(2 #2=(3 #3=(#1#) . #3#) . #2#) -> ~S~%" (object->string y1))) (if (not (equal? y2 #2d((1 2) (3 4)))) (format-logged #t ";#2d((1 2) (3 4)) -> ~A~%" y2)) (if (not (= z 32)) (format-logged #t ";#+asdf? -> ~A~%" z)) (if (not (= z1 1)) (format-logged #t ";#(or ... +asdf)? -> ~A~%" z1)) (if (not (= x2 5)) (format-logged #t ";(+ 1 #;(* 2 3) 4) -> ~A~%" x2)) (if (not (= x3 3)) (format-logged #t ";(+ #;32 1 2) -> ~A~%" x3)) (if (not (= x4 3)) (format-logged #t ";(+ #; 32 1 2) -> ~A~%" x4)) (if (not (= y3 3)) (format-logged #t ";(+ 1 (car '#1=(2 . #1#))) -> ~A~%" y3)) (if (not (= y4 3)) (format-logged #t ";#.(+ 1 (car '#1=(2 . #1#))) -> ~A~%" y4)) (if (not (= y5 51)) (format-logged #t ";(+ 1 #.(* 2 3) #.(* 4 #.(+ 5 6))) -> ~A~%" y5)) (if (not (equal? r1 '(1 4))) (format-logged #t ";'(1 #. #;(+ 2 3) 4) -> ~A~%" r1)) (if (not (equal? r2 '(1 (* 2 4)))) (format-logged #t ";'(1 #. #;(+ 2 3) (* 2 4)) -> ~A~%" r2)) (if (not (equal? r3 '(1 (* 2 4)))) (format-logged #t ";'(1 #; #.(+ 2 3) (* 2 4)) -> ~A~%" r3)) (if (not (equal? r4 '(1 5 (* 2 4)))) (format-logged #t ";'(1 #. #1=(+ 2 3) (* 2 4)) -> ~A~%" r4)) (if (not (equal? r5 '(1 5 (* 2 4)))) (format-logged #t ";'(1 #. #1=(+ 2 #. 3) (* 2 4)) -> ~A~%" r5)) (if (not (equal? r6 '(1 2 (* 2 4)))) (format-logged #t ";'(1 #. #1=(+ 2 #+pi 3) (* 2 4)) -> ~A~%" r6)) (if (not (equal? r7 '(1 2 (* 2 4)))) (format-logged #t ";'(1 #. #1=(+ 2 #+pi #1#) (* 2 4)) -> ~A~%" r7)) (if (not (equal? r8 '(1 (1 2) 3))) (format-logged #t ";'(1 #+s7 #1=(1 2) 3) -> ~A~%" r8)) (if (not (equal? r9 '(1 3))) (format-logged #t ";'(1 #+asdf #1=(1 2) 3)) -> ~A~%" r9)) (if (not (equal? r10 ':1)) (format-logged #t ";#. #1# -> ~A~%" r10)) (if (not (equal? r13 0)) (format-logged #t ";#+s7 #e0.0 -> ~A~%" r13)) (if (not (equal? r14 1)) (format-logged #t ";#. #o1 -> ~A~%" r14)) (if (not (equal? r15 -)) (format-logged #t ";#. #_- -> ~A~%" r15)) (if (not (equal? r16 0)) (format-logged #t ";(#+s7 #_- #d0) -> ~A~%" r16)) (if (not (equal? r17 -1)) (format-logged #t ";(#. #_- #o1) -> ~A~%" r17)) (if (not (equal? r18 0)) (format-logged #t ";(#. #. #_+) -> ~A~%" r18)) (if (not (equal? r19 0)) (format-logged #t ";(#. #+s7 #_+) -> ~A~%" r19)) (if (not (equal? r20 0)) (format-logged #t ";(#+s7 #+s7 #_+) -> ~A~%" r20)) (if (not (equal? r21 0)) (format-logged #t ";(#_-(#_+ 1 2)3) -> ~A~%" r21)) (if (not (equal? r22 1)) (format-logged #t ";(#(#_+ 1 2)#o1) -> ~A~%" r22)) (if (not (equal? r23 0)) (format-logged #t ";(+ #;#1.##+asdf ) -> ~A~%" r23)) (if (not (equal? r24 0)) (format-logged #t ";(+ #. #;(#_+ 1 2)) -> ~A~%" r24)) (if (not (equal? r25 0)) (format-logged #t ";(+ #;#1=#2=) -> ~A~%" r25)) (if (not (equal? r26 3)) (format-logged #t ";(+ #;#2#(#_+ 1 2)) -> ~A~%" r26)) (if (not (equal? r27 0)) (format-logged #t ";(+ #;#1=.) -> ~A~%" r27)) (if (not (equal? r28 0)) (format-logged #t ";(+ #; #; #; ()) -> ~A~%" r28)) (if (not (equal? r29 6)) (format-logged #t ";(+ 3(#_+ 1 2)#;#. ) -> ~A~%" r29)) (if (not (equal? r30 0)) (format-logged #t ";(+ #;#2=#+asdf#+s7) -> ~A~%" r30)) (if (not (equal? r31 0)) (format-logged #t ";(+ #;#f#=#\\) -> ~A~%" r31)) (if (not (equal? r32 -3)) (format-logged #t ";(#. + (#_-(#_+ 1 2))) -> ~A~%" r32)) (if (not (equal? r33 3)) (format-logged #t ";(+ 1 #+asdf #\\a 2) -> ~A~%" r33)) (if (not (equal? r34 0)) (format-logged #t ";(+ #++(#. #\\a)) -> ~A~%" r34)) (if (not (equal? r35 0)) (format-logged #t ";(+ #+s7 #; (33)) -> ~A~%" r35)) (if (not (morally-equal? r36 -1.0)) (format-logged #t ";(cos #. #. #. `(string->symbol \"pi\")) -> ~A~%" r36)) ) (set! *#readers* old-readers) ) ;;; -------------------------------------------------------------------------------- (begin (define-macro (hi a) `(+ ,a 1)) (test (hi 2) 3) (let () (define (ho b) (+ 1 (hi b))) (test (ho 1) 3)) (let ((hi 32)) (test (+ hi 1) 33)) (letrec ((hi (lambda (a) (if (= a 0) 0 (+ 2 (hi (- a 1))))))) (test (hi 3) 6)) (letrec* ((hi (lambda (a) (if (= a 0) 0 (+ 2 (hi (- a 1))))))) (test (hi 3) 6)) (test (equal? '(hi 1) (quote (hi 1))) #t) (test (list? '(hi 1)) #t) (test (list? '(((hi 1)))) #t) (test (equal? (vector (hi 1)) #(2)) #t) (test (symbol? (vector-ref #(hi) 0)) #t)) (define-macro (define-with-goto name-and-args . body) ;; run through the body collecting label accessors, (label name) ;; run through getting goto positions, (goto name) ;; tie all the goto's to their respective labels (via set-cdr! essentially) (define (find-accessor type) (let ((labels ())) (define (gather-labels accessor tree) (if (pair? tree) (if (equal? (car tree) type) (begin (set! labels (cons (cons (cadr tree) (let ((body 'lst)) (for-each (lambda (f) (set! body (list f body))) (reverse (cdr accessor))) (dilambda (apply lambda '(lst) (list body)) (apply lambda '(lst val) `((set! ,body val)))))) labels)) (gather-labels (cons 'cdr accessor) (cdr tree))) (begin (gather-labels (cons 'car accessor) (car tree)) (gather-labels (cons 'cdr accessor) (cdr tree)))))) (gather-labels () body) labels)) (let ((labels (find-accessor 'label)) (gotos (find-accessor 'goto))) (if (not (null? gotos)) (for-each (lambda (goto) (let* ((name (car goto)) (goto-accessor (cdr goto)) (label (assoc name labels)) (label-accessor (and label (cdr label)))) (if label-accessor (set! (goto-accessor body) (label-accessor body)) (error 'bad-goto "can't find label: ~S" name)))) gotos)) `(define ,name-and-args (let ((label (lambda (name) #f)) (goto (lambda (name) #f))) ,@body)))) (let () (define-with-goto (g1 a) (let ((x 1)) (if a (begin (set! x 2) (goto 'the-end) (set! x 3)) (set! x 4)) (label 'the-end) x)) (define-with-goto (g2 a) (let ((x a)) (label 'start) (if (< x 4) (begin (set! x (+ x 1)) (goto 'start))) x)) (test (g1 #f) 4) (test (g1 #t) 2) (test (g2 1) 4) (test (g2 32) 32)) (let ((sum 0)) (define-macro (define-with-goto-and-come-froms name-and-args . body) (let ((labels ()) (gotos ()) (come-froms ())) (define (collect-jumps tree) (when (pair? tree) (when (pair? (car tree)) (case (caar tree) ((label) (set! labels (cons tree labels))) ((goto) (set! gotos (cons tree gotos))) ((come-from) (set! come-froms (cons tree come-froms))) (else (collect-jumps (car tree))))) (collect-jumps (cdr tree)))) (collect-jumps body) (for-each (lambda (goto) (let* ((name (cadr (cadar goto))) (label (member name labels (lambda (a b) (eq? a (cadr (cadar b))))))) (if label (set-cdr! goto (car label)) (error 'bad-goto "can't find label: ~S" name)))) gotos) (for-each (lambda (from) (let* ((name (cadr (cadar from))) (label (member name labels (lambda (a b) (eq? a (cadr (cadar b))))))) (if label (set-cdr! (car label) from) (error 'bad-come-from "can't find label: ~S" name)))) come-froms) `(define ,name-and-args (let ((label (lambda (name) #f)) (goto (lambda (name) #f)) (come-from (lambda (name) #f))) ,@body)))) (define-with-goto-and-come-froms (hi) (set! sum (+ sum 1)) (goto 'the-end) (set! sum (+ sum 2)) (label 'the-end) (set! sum (+ sum 4)) (label 'not-done) (set! sum (+ sum 8)) (come-from 'not-done) (set! sum (+ sum 16)) (newline) sum) (test (hi) 21)) ;;; -------------------------------------------------------------------------------- ;;; symbol-access (let ((p (open-output-string))) (define e ; save environment for use below (let ((x 3) ; always an integer (y 3) ; always 3 (z 3)) ; report set! (set! (symbol-access 'x) (lambda (s v) (if (integer? v) v x))) (set! (symbol-access 'y) (lambda (s v) y)) (set! (symbol-access 'z) (lambda (s v) (format p "z ~A -> ~A~%" z v) v)) (set! x 3.3) (set! y 3.3) (set! z 3.3) (curlet))) (test (and (equal? (e 'x) 3) (equal? (e 'y) 3) (equal? (e 'z) 3.3) (string=? (get-output-string p) "z 3 -> 3.3\n")) #t) (close-output-port p)) (for-each (lambda (arg) (test (symbol-access arg) 'error) (test (set! (symbol-access _int_) arg) 'error) (let ((x 1)) (if (not (null? arg)) (test (set! (symbol-access 'x arg) (lambda (s v) 1)) 'error))) (let ((_x_ 1)) (set! (symbol-access '_x_) (lambda (s v) v)) (set! _x_ arg) (test _x_ arg))) (list -1 #\a 1 #(1 2 3) 3.14 3/4 1.0+1.0i () #(()) (list 1 2 3) '(1 . 2) "hi")) (let ((_x_ 1)) (set! (symbol-access '_x_) (lambda (s v) v)) (define _x_ 32) (test _x_ 32) (define (_x_) 32) (test (_x_) 32) (let ((_x_ 3)) (test _x_ 3)) (define (hi _x_) _x_) (test (hi 4) 4) (test (do ((_x_ 0 (+ _x_ 1))) ((= _x_ 2) _x_)) 2) (test ((inlet '_x_ -1) '_x_) -1) (set! _x_ 32) (test _x_ 32)) (let ((_x_ 1)) (set! (symbol-access '_x_) (lambda (s v) #f)) (define _x_ 32) (test _x_ #f) (test (set! _x_ 32) #f)) (test (symbol-access) 'error) (let ((xyzzy 1) (_int_ 'xyzzy)) (test (symbol-access 'xyzzy) #f) (test (set! (symbol-access _int_) ()) 'error) (test (set! (symbol-access _int_) '(#f)) 'error)) (let ((_x1_ #f)) (set! (symbol-access '_x1_) (lambda (x y) 'error)) (test (set! _x1_ 32) 'error)) (let ((x 1)) (set! (symbol-access 'x) (lambda (s v) x)) (let ((x 2)) (set! x 3) (test x 3) (set! (symbol-access 'x (curlet)) (lambda (s v) 32)) (set! x 1) (test x 32)) (test x 1) (set! x 2) (test x 1)) (let () (define (f1 x) (let ((a x) (b 2) (c 3)) (set! (symbol-access 'b) (lambda (s v) (set! a (+ v c)) v)) (set! (symbol-access 'c) (lambda (s v) (set! a (+ b v)) v)) (set! a (+ b c)) (set! b (+ b 1)) (set! c 5) a)) (f1 0) (test (f1 0) 8)) (test (symbol-access :rest) #f) (test (set! (symbol-access :allow-other-keys) #f) 'error) #| ;;; these tests are problematic -- they might not fail as hoped, or they might generate unwanted troubles (let ((bad-ideas " (define (bad-idea) (let ((lst '(1 2 3))) (let ((result (list-ref lst 1))) (list-set! lst 1 (* 2.0 16.6)) (gc) result))) (define (bad-idea-1) (let ((lst #(1 2 3))) (let ((result (vector-ref lst 1))) (vector-set! lst 1 (* 2.0 16.6)) (gc) result))) ")) (with-output-to-file tmp-output-file (lambda () (display bad-ideas))) (load tmp-output-file)) (num-test (bad-idea) 2) (let ((val (bad-idea))) (if (equal? val 33.2) (set! val (bad-idea))) (if (equal? val 33.2) (format-logged #t ";bad-idea 3rd time: ~A~%" val))) (num-test (bad-idea-1) 2) (let ((val (bad-idea-1))) (if (equal? val 33.2) (set! val (bad-idea-1))) (if (equal? val 33.2) (format-logged #t ";bad-idea-1 3rd time: ~A~%" val))) (set! (*s7* 'safety) 1) (load tmp-output-file) (num-test (bad-idea) 2) (num-test (bad-idea) 33.2) (num-test (bad-idea) 33.2) (num-test (bad-idea-1) 2) (num-test (bad-idea-1) 33.2) (num-test (bad-idea-1) 33.2) (set! (*s7* 'safety) 0) |# ;(test (quit 0) 'error) ;;; macroexpand (let () (define-macro (hi a) `(+ ,a 1)) (test (macroexpand (hi 2)) '(+ 2 1)) (test (macroexpand (hi (abs 2))) '(+ (abs 2) 1)) (define-macro (ho a) `(+ ,@a 1)) (test (macroexpand (ho (2 3 4))) '(+ 2 3 4 1)) (define-macro* (hi1 a (b 2)) `(+ ,a ,b)) (test (macroexpand (hi1 3)) '(+ 3 2)) (define-bacro* (hi2 a (b 2)) `(+ ,a ,b)) (test (macroexpand (hi2 3)) '(+ 3 2)) ) (let () (define-macro (Let vars . body) `(with-let (sublet (curlet) ,@(map (lambda (var) (values (symbol->keyword (car var)) (cadr var))) vars)) ,@body)) (test (Let ((c 4)) (Let ((a 2) (b (+ c 2))) (+ a b c))) 12) (test (macroexpand (Let ((a 2) (b (+ c 2))) (+ a b c))) '(with-let (sublet (curlet) :a 2 :b (+ c 2)) (+ a b c)))) (let () (define-macro (m1 . args) `(begin ,@args)) (test (macroexpand (m1 (display 1) (newline))) '(begin (display 1) (newline)))) (test (let ((a 3) (b (list 2 3 4))) (quasiquote (+ ,a 1 ,@b))) '(+ 3 1 2 3 4)) (test (let ((a 3) (b (list 2 3 4))) (macroexpand (quasiquote (+ ,a 1 ,@b)))) (list {list} ''+ 'a 1 (list {apply_values} 'b))) (let () (define-macro* (m2 (a 3) (b 2)) `(+ ,a ,b)) (test (macroexpand (m2)) '(+ 3 2)) (test (macroexpand ((symbol->value 'm2) (* 2 3))) '(+ (* 2 3) 2))) (let () (define-bacro (m3 b) `(+ ,a ,b)) (test (let ((a 3)) (macroexpand (m3 2))) '(+ 3 2))) (let () (define-macro (progv vars vals . body) `(apply (apply lambda ,vars ',body) ,vals)) (test (macroexpand (progv '(one two) '(1 2) (+ one two))) '(apply (apply lambda '(one two) '((+ one two))) '(1 2)))) (let () (define-macro (Letrec* bindings . body) (if (null? body) (error 'syntax-error "letrec* has no body") (if (not (list? bindings)) (error 'syntax-error "letrec* variables are messed up") `(let (,@(map (lambda (var&init) (list (car var&init) #)) bindings)) ,@(map (lambda (var&init) (if (not (null? (cddr var&init))) (error 'syntax-error "letrec* variable has more than one value")) (list 'set! (car var&init) (cadr var&init))) bindings) ,@body)))) (test (macroexpand (Letrec* ((p (lambda (x) (+ 1 (q (- x 1))))) (q (lambda (y) (if (zero? y) 0 (+ 1 (p (- y 1)))))) (x (p 5)) (y x)) y)) '(let ((p #) (q #) (x #) (y #)) (set! p (lambda (x) (+ 1 (q (- x 1))))) (set! q (lambda (y) (if (zero? y) 0 (+ 1 (p (- y 1)))))) (set! x (p 5)) (set! y x) y))) (let () (define-macro (m5 a) `(define-macro (m6 b) `(+ 1 ,b ,,a))) (test (macroexpand ((m5 3) 4)) '(+ 1 4 3))) (test (macroexpand) 'error) (test (macroexpand 1) 'error) (test (macroexpand . 1) 'error) (test (macroexpand (* 1 2)) 'error) (test (macroexpand (* 1 2) . 3) 'error) (test (macroexpand (* 1 2) 3) 'error) (test (macroexpand ((symbol->value 'abs) -1)) 'error) (test (macroexpand (1 2)) 'error) (let () (define-macro (rmac . args) (if (null? args) () (if (null? (cdr args)) `(display ',(car args)) (append (list 'begin `(display ',(car args))) (append (list (apply macroexpand (list (append '(rmac) (cdr args)))))))))) (test (with-output-to-string (lambda () (rmac a b c (+ 1 2) d))) "abc(+ 1 2)d")) ;;; define-expansion (define-expansion (_expansion_ a) `(+ ,a 1)) (test (_expansion_ 3) 4) (test (macroexpand (_expansion_ 3)) `(+ 3 1)) (test '(_expansion_ 3) (quote (_expansion_ 3))) (test (_expansion_ (+ (_expansion_ 1) 2)) 5) (test (let ((x _expansion_)) (x 3)) '(+ 3 1)) (test (let ((x 3)) (define (hi a) (a x)) (hi _expansion_)) '(+ x 1)) (define-expansion (whatever->zero . whatever) 0) (let ((val (+ 1 (whatever->zero 2 3) 4))) (if (not (= val 5)) (format *stderr* "whatever->zero: ~A?" val))) ;;; define-constant (test (let () (define-constant __c1__ 32) __c1__) 32) ;(test (let () __c1__) 'error) ; changed my mind here -- s7 treats define-constant as a global operation now (test (let ((__c1__ 3)) __c1__) 'error) (test (let* ((__c1__ 3)) __c1__) 'error) (test (letrec ((__c1__ 3)) __c1__) 'error) (test (let () (define (__c1__ a) a) (__c1__ 3)) 'error) (test (let () (set! __c1__ 3)) 'error) (let () (define (df1 a) (set! pi a)) (test (df1 3.0) 'error) (test (df1 #\a) 'error) (define (df2 a b) (set! pi (+ a b))) (test (df2 1.0 2.0) 'error) (define (df3 a) (set! pi (+ pi 1))) (test (df3 1) 'error) (test (set! pi (abs pi)) 'error) (test (set! pi pi) 'error) ; hmmm... (test (define-constant pi pi) pi) ; but this is ok -- define-constant can be a no-op (test (define-constant pi 3.0) 'error) (test (define pi 3.0) 'error) (test (define (pi a) a) 'error) (test (define (f1 pi) pi) 'error) (test (let ((pi 3.0)) pi) 'error) (test (let* ((pi 3.0)) pi) 'error) (test (letrec ((pi 3.0)) pi) 'error) (test (letrec* ((pi 3.0)) pi) 'error) (test (do ((pi 0 (+ pi 1))) ((= pi 3))) 'error) ) (let ((old-stdin *stdin*) (old-closed (port-closed? *stdin*))) (let ((tag (catch #t (lambda () (set! *stdin* #f)) (lambda args 'error)))) (if (or (not (eq? *stdin* old-stdin)) (not (eq? old-closed (port-closed? *stdin*)))) (format *stderr* ";*stdin* mutable?~%")) (if (not (eq? tag 'error)) (format *stderr* ";set! *stdin* no error? ~A~%" tag)))) (let ((old-stdout *stdout*) (old-closed (port-closed? *stdout*))) (let ((tag (catch #t (lambda () (set! *stdout* #f)) (lambda args 'error)))) (if (or (not (eq? *stdout* old-stdout)) (not (eq? old-closed (port-closed? *stdout*)))) (format *stderr* ";*stdout* mutable?~%")) (if (not (eq? tag 'error)) (format *stderr* ";set! *stdout* no error? ~A~%" tag)))) (let ((old-stderr *stderr*) (old-closed (port-closed? *stderr*))) (let ((tag (catch #t (lambda () (set! *stderr* #f)) (lambda args 'error)))) (if (or (not (eq? *stderr* old-stderr)) (not (eq? old-closed (port-closed? *stderr*)))) (format *stderr* ";*stderr* mutable?~%")) (if (not (eq? tag 'error)) (format *stderr* ";set! *stderr* no error? ~A~%" tag)))) (let ((old-pi pi)) (let ((tag (catch #t (lambda () (set! pi #f)) (lambda args 'error)))) (if (not (eq? pi old-pi)) (format pi ";pi mutable?~%")) (if (not (eq? tag 'error)) (format pi ";set! pi no error? ~A~%" tag)))) (let ((old-with-let with-let)) (let ((tag (catch #t (lambda () (set! with-let #f)) (lambda args 'error)))) (if (not (eq? with-let old-with-let)) (format with-let ";with-let mutable?~%")) (if (not (eq? tag 'error)) (format with-let ";set! with-let no error? ~A~%" tag)))) (let ((old-*s7* *s7*)) (let ((tag (catch #t (lambda () (set! *s7* #f)) (lambda args 'error)))) (if (not (eq? *s7* old-*s7*)) (format *s7* ";*s7* mutable?~%")) (if (not (eq? tag 'error)) (format *s7* ";set! *s7* no error? ~A~%" tag)))) ;;; -------------------------------------------------------------------------------- ;;; constant? (test (constant? '__c1__) #t) (test (constant? pi) #t) (test (constant? 'pi) #t) ; take that, Clisp! (test (constant? 12345) #t) (test (constant? 3.14) #t) (test (constant? :asdf) #t) (test (constant? 'asdf) #f) (test (constant? "hi") #t) (test (constant? #\a) #t) (test (constant? #f) #t) (test (constant? #t) #t) (test (constant? ()) #t) (test (constant? ()) #t) (test (constant? '(a)) #t) (test (constant? '*features*) #f) (test (let ((a 3)) (constant? 'a)) #f) (test (constant? 'abs) #f) (test (constant? abs) #t) (test (constant? most-positive-fixnum) #t) (test (constant? (/ (log 0))) #t) ; nan.0 is a constant as a number I guess (test (constant? 1/0) #t) (test (constant? (log 0)) #t) (test (constant?) 'error) (test (constant? 1 2) 'error) (test (constant? #) #t) ; ? (test (constant? '-) #f) (test (constant? ''-) #t) (test (constant? '''-) #t) (test (constant? '1) #t) (test (constant? 1/2) #t) (test (constant? 'with-let) #t) (test (constant? with-let) #t) ;; and some I wonder about -- in CL's terms, these always evaluate to the same thing, so they're constantp ;; but Clisp: ;; (constantp (cons 1 2)) ->NIL ;; (constantp #(1 2)) -> T ;; (constantp '(1 . 2)) -> NIL ;; etc -- what a mess! (test (constant? (cons 1 2)) #t) (test (constant? #(1 2)) #t) (test (constant? (list 1 2)) #t) (test (constant? (vector 1 2)) #t) (test (let ((v (vector 1 2))) (constant? v)) #t) ;!! ;; it's returning #t unless the arg is a symbol that is not a keyword or a defined constant ;; (it's seeing the value of v, not v): (test (let ((v (vector 1 2))) (constant? 'v)) #f) ;; that is something that can be set! is not a constant? (if with-bignums (begin (test (constant? 1624540914719833702142058941) #t) (test (constant? 1624540914719833702142058941.4) #t) (test (constant? 7151305879464824441563197685/828567267217721441067369971) #t))) (test (constant? lambda) #t) ; like abs? (test (constant? (lambda () 1)) #t) (test (constant? ''3) #t) (test (constant? (if #f #f)) #t) (test (constant? 'x) #f) (test (let ((x 'x)) (and (not (constant? x)) (equal? x (eval x)))) #t) (test (and (constant? (list + 1)) (not (equal? (list + 1) (eval (list + 1))))) #t) ;; not sure this is the right thing... ;; but CL makes no sense: ;; [3]> (constantp (vector 1)) ;; T ;; [4]> (constantp (cons 1 2)) ;; NIL ;; [5]> (constantp (list 1)) ;; NIL ;; [7]> (constantp "hi") ;; T ;; (setf (elt "hi" 1) #\a) ;; #\a ;; at least they finally agree that pi is a constant! (let () (define-constant __hi__ (vector 3 0)) (set! (__hi__ 1) 231) (test __hi__ #(3 231))) ;; that is, hi is the constant as a vector, not the vector elements ;;; -------------------------------------------------------------------------------- ;;; defined? (test (defined? 'pi) #t) (test (defined? 'pi (rootlet)) #t) (test (defined? 'abs (rootlet)) #t) (test (defined? 'abs (curlet)) #t) (test (let ((__c2__ 32)) (defined? '__c2__)) #t) (test (let ((__c2__ 32)) (defined? '__c2__ (curlet))) #t) (test (let ((__c2__ 32)) (defined? '__c3__ (curlet))) #f) (test (let ((__c2__ 32)) (defined? '__c2__ (rootlet))) #f) (test (let ((__c2__ 32)) (defined? '__c3__ (rootlet))) #f) (test (let ((ge (rootlet))) (ge 'abs)) abs) (test (let ((ge (rootlet))) (ge 'rootlet)) rootlet) (test (let ((ge (rootlet))) (ge 'define)) define) (test (let ((ge (rootlet))) (ge 'if)) if) (test (let ((ge (rootlet))) (let ((abc 1)) (ge 'abc))) #) (test (defined?) 'error) (test (defined? 'a 'b) 'error) (test (defined? 'abs (curlet)) #t) (test (defined? 'abs (curlet) #()) 'error) (test (defined? 'abs 0) 'error) (test (let () (defined? 'abs (curlet) #())) 'error) (for-each (lambda (arg) (test (defined? arg) 'error) (test (defined? 'abs arg) 'error)) (list -1 #\a 1 _ht_ _null_ _c_obj_ #(1 2 3) 3.14 3/4 1.0+1.0i () #f #(()) (list 1 2 3) '(1 . 2) "hi")) (test (defined? 'lambda car) 'error) (test (defined? lambda gensym) 'error) (test (defined? 'lambda defined?) 'error) (test (defined? 'define car) 'error) (test (defined? 'abs (sublet ())) #t) ; nil = global now (test (defined? lambda) 'error) (test (defined? 'lambda) #t) (test (defined? 'dynamic-wind) #t) (test (defined? 'asdaf) #f) ;(test (defined? ':asdaf) #f) ; keywords are defined in the sense that they evaluate to themselves ;(test (defined? :asdaf) #f) (test (defined? 'ok?) #t) (test (defined? 'test-t) #t) (test (defined? 'quasiquote) #t) (test (defined? (symbol "123")) #f) (test (defined? (symbol "+")) #t) (test (defined? ''+) 'error) (test (defined? 'if) #t) (test (defined? if) 'error) (test (defined? quote) 'error) (test (let () (defined? 'abs (curlet) #t)) #f) (test (let () (defined? 'abs (curlet))) #t) (test (let () (defined? 'abs (curlet) #f)) #t) (test (let ((b 2)) (let ((e (curlet))) (let ((a 1)) (if (defined? 'a e) (format #f "a: ~A in ~{~A ~}" (symbol->value 'a e) e))))) #) ; not "a: 1 in (b . 2)") (test (let ((b 2)) (let ((e (curlet))) (let ((a 1)) (format #f "~A: ~A" (defined? 'abs e) (eval '(abs -1) e))))) "#t: 1") ;;; -------------------------------------------------------------------------------- ;;; let? ;;; inlet ;;; rootlet ;;; curlet ;;; sublet ;;; with-let ;;; let->list ;;; outlet ;;; let-ref ;;; let-set! ;;; varlet ;;; cutlet ;;; coverlet ;;; openlet ;;; unlet (test (let () (length (curlet))) 0) (test (let ((a 1) (b 2) (c 3)) (length (curlet))) 3) (for-each (lambda (arg) (test (let? arg) #f)) (list -1 #\a 1 #(1 2 3) 3.14 3/4 1.0+1.0i () #f #(()) (list 1 2 3) '(1 . 2) "hi" '((a . 1)))) (let () (test (let? (unlet)) #t)) (test (let? (curlet)) #t) (test (let? (rootlet)) #t) (test (let? (sublet ())) #t) (test (let? (varlet ())) #t) (test (let? (sublet (sublet ()) '(a . 1))) #t) (test (let? (sublet () '(a . 1))) #t) (test (eq? abs ((rootlet) 'abs)) #t) (test (eq? abs #_abs) #t) (test (eq? abs (with-let (unlet) abs)) #t) (test ((sublet () '(asdf . 32)) 'asdf) 32) (test ((sublet () '(asdf . 32)) 'asd) #) (test (let? (sublet (curlet))) #t) ; no bindings is like (let () ...) (test (varlet (rootlet) '(quote . 1)) 'error) (test (eq? (curlet) (let ((a (curlet))) a)) #t) (test (eq? (curlet) (let* ((a (curlet))) a)) #t) (test (eq? (curlet) (letrec ((a (curlet))) a)) #f) (test (eq? (curlet) (letrec* ((a (curlet))) a)) #f) (test (let ((a (curlet))) (eq? a (curlet))) #f) (test (letrec ((a (curlet))) (eq? a (curlet))) #t) (test (let ((e (inlet 'e (inlet '+ -)))) (((e 'e) '+) 2 3)) -1) (test (let ((confused (inlet '+ -))) ((confused '+) 2 3)) -1) ;;; (with-let (inlet '+ -) (+ 2 3)) -> 5 ;;; (with-let (inlet '+ -) (((curlet) '+) 2 3)) -> -1 ;;; (with-let (inlet 'plus -) (plus 2 3)) -> -1 ;;; which is consistent, so to speak, with the (set! gcd +) example mentioned in s7.html (test (((let ((x (lambda (y) (+ y 1)))) (curlet)) 'x) 2) 3) (test (equal? (inlet 'a 1) (inlet 'a 1)) #t) (test (morally-equal? (inlet 'a 1) (inlet 'a 1)) #t) (test (equal? (inlet 'a 1) (inlet 'a 2 'a 1)) #t) (test (equal? (inlet 'a 3 'a 1) (inlet 'a 2 'a 1)) #t) (test (morally-equal? (inlet 'a 1) (inlet 'a 2 'a 1)) #t) (test (equal? (inlet 'a 1 'b "hi") (inlet 'a 1 'b "hi")) #t) (test (morally-equal? (inlet 'a 1 'b "hi") (inlet 'a 1 'b "hi")) #t) (test (equal? (inlet 'b "hi" 'a 1) (inlet 'a 1 'b "hi")) #t) (test (morally-equal? (inlet 'b "hi" 'a 1) (inlet 'a 1 'b "hi")) #t) (test (equal? (inlet 'a 2 'b "hi" 'a 1) (inlet 'b "hi" 'a 2 'a 1)) #t) (test (equal? (inlet 'a (vector 1.0)) (inlet 'a (float-vector 1.0))) #f) (test (morally-equal? (inlet 'a (vector 1.0)) (inlet 'a (float-vector 1.0))) #t) (test (equal? (inlet 'b "hi" 'a 1) (inlet 'b "hi" 'a 1.0)) #f) (test (morally-equal? (inlet 'b "hi" 'a 1) (inlet 'b "hi" 'a 1.0)) #t) (test (equal? (inlet 'b "hi" 'a 1) (inlet 'b "hi" 'a 1/2)) #f) (test (morally-equal? (inlet 'b "hi" 'a 1) (inlet 'b "hi" 'a 1/2)) #f) (test (equal? (inlet 'a 1) (inlet 'b "hi" 'a 1)) #f) (test (equal? (inlet 'a 1 'b "hi") (inlet 'a 1)) #f) (test (equal? (inlet 'a 1 'a 1) (inlet 'a 1)) #t) (test (equal? (inlet 'a (inlet 'b 1)) (inlet 'a (inlet 'b 1))) #t) (test (equal? (inlet 'a (inlet 'b 1)) (inlet 'a (inlet 'b 1))) #t) (test (equal? (inlet 'b (inlet 'b 1)) (inlet 'b (inlet 'b 1))) #t) (test (equal? (inlet) (inlet)) #t) (test (equal? (inlet 'a 1) (inlet)) #f) (test (equal? (inlet) (inlet 'a 1)) #f) (test (object->string (inlet 'a 1 'a 3)) "(inlet 'a 1 'a 3)") (test ((inlet 'a 1 'a 3) 'a) 3) ; so the print form follows the input order, but the earlier entries (as printed) are shadowed (test (equal? (inlet) (sublet (inlet))) #t) (test (equal? (inlet 'a 1) (inlet 'a 2)) #f) (test (equal? (inlet 'a 1) (inlet 'b 1)) #f) (test (equal? (inlet 'a 1) (inlet 'a 1 'b 1)) #f) (test (equal? (inlet 'a 1 'b 1) (inlet 'a 1 'c 1)) #f) (test (equal? (inlet 'a 1 'b 1) (inlet 'a 1 'b 1)) #t) (test (equal? (inlet 'a 1) (inlet 'a 1 'a 1)) #t) (test (equal? (inlet 'a 1) (inlet 'a 1 'a 2)) #f) (test (equal? (sublet (inlet 'a 1) 'b 2) (sublet (inlet 'a 1) 'b 2)) #t) (test (equal? (sublet (inlet 'a 1) 'b 2) (sublet (inlet 'a 2) 'b 2)) #f) (test (equal? (sublet (inlet 'a 1) 'b 2) (sublet (inlet 'a 1) 'b 1)) #f) (test (equal? (sublet (inlet 'a 1) 'b 2) (sublet (inlet 'a 1))) #f) (test (equal? (sublet (inlet 'a 1)) (sublet (inlet))) #f) (test (equal? (sublet (inlet 'a 1)) (inlet 'a 1)) #t) (test (equal? (sublet (sublet (inlet 'a 1))) (sublet (inlet 'a 1))) #t) (test (let ((e (inlet 'a 1))) (equal? (sublet e 'a 1) (sublet e 'a 1))) #t) (test (equal? (inlet 'a 1 'b 2 'c 3) (inlet 'c 3 'b 2 'a 1)) #t) (test (equal? (inlet 'a 1 'b 2 'c 3) (inlet 'c 3 'b 1 'a 1)) #f) (test (equal? (inlet 'a 1 'a 2) (inlet 'a 3 'a 2)) #t) (test (equal? (sublet (inlet 'a 1 'a 3) 'a 2) (sublet (inlet 'a 3) 'a 2)) #t) (test (equal? (inlet 'a 1) (inlet 'a 1 'b 2)) #f) (test (equal? (inlet 'a 1) (sublet (inlet 'a 1))) #t) (test (equal? (sublet (inlet 'a 1)) (inlet 'a 1)) #t) (test (let ((e (inlet 'a 1 'a 2))) (let ((c (copy e))) (list (e 'a) (c 'a)))) '(2 2)) (test (equal? (inlet 'a 1) (sublet (inlet 'a 1))) #t) (test (equal? (sublet (inlet 'a 1) 'b 2) (sublet (inlet 'a 1 'b 2) 'b 2)) #t) (test (equal? (sublet (inlet 'a 3) 'a 2) (sublet (inlet 'a 1) 'a 2)) #t) ; ((sublet (inlet 'a 1) 'a 2) 'a) -> 2 (test (equal? (sublet (inlet) 'a 2) (sublet (inlet 'a 1) 'a 2)) #t) (test (equal? (inlet 'a 1) (inlet 'a 3 'a 2 'a 1)) #t) (let ((f (inlet 'sym 'sam 'sam 'sym)) (g (inlet 'sam 'sym 'sym 'sam))) (test (f (g 'sym)) 'sym) (test (f (f 'sym)) 'sym) (test (g (f 'sam)) 'sam) (test (g (f (g (f (f 'sym))))) 'sam)) (test (apply inlet (map values (hash-table '(a . 1) '(b . 2)))) (inlet 'b 2 'a 1)) (test (apply hash-table (map values (inlet 'a 1 'b 2))) (hash-table '(a . 1) '(b . 2))) (let ((e (inlet 'a 1 'a 2))) (test (e 'a) ((copy e) 'a))) (let ((e1 (inlet 'a 1 'a 2))) (let ((e2 (copy e1))) (test (list (equal? e1 e2) (equal? (e1 'a) (e2 'a))) '(#t #t)))) (let () (define-bacro (let/ e . body) `(with-let (sublet (curlet) ,e) ,@body)) (test (let ((a 1)) (let/ (inlet 'b 2) (+ a b))) 3)) (let ((e (inlet 'a (inlet 'b 1 'c 2) 'b (inlet 'b 3 'c 4)))) (test (e 'a 'b) 1) (test (e 'b 'b) 3) (test (e 'b 'c) 4)) (let () (define (f1) (let ((e (inlet 'a 1))) (e '(1)))) (test (f1) 'error)) (test (equal? (inlet 'a 1) (cutlet (inlet 'a 1 'b 2) 'b)) #t) (test (equal? (inlet 'a 1) (inlet 'a 1 'b 2)) #f) (test (length (cutlet (inlet 'a 1 'b 2 'c 3) 'b 'a)) 1) (test (length (cutlet (inlet 'a 1 'b 2 'c 3) 'd)) 3) (test (let->list (cutlet (inlet 'a 1 'b 2 'c 3) 'b 'a)) '((c . 3))) (test ((cutlet (inlet 'a 1 'b 2) 'a) 'a) #) (test ((cutlet (inlet 'a 1 'b 2 'c 3) 'a) 'b) 2) (test ((cutlet (inlet 'a 1 'b 2) 'a) 'b) 2) (test ((cutlet (inlet 'a 1 'b 2 'c 3) 'a 'b 'c) 'a) #) (test ((cutlet (inlet 'a 1 'b 2 'c 3 'a 4) 'a) 'a) 1) ; shadowed in order added (define ___a 32) (cutlet (rootlet) '___a) (test ___a #) (test (cutlet (inlet)) (inlet)) (test (cutlet (inlet 'a 1) 'a) (inlet)) (test ((cutlet (inlet 'a 1 'a 2) 'a) 'a) 1) (test (let ((g (gensym))) (cutlet (inlet g '1) g)) (inlet)) (test (cutlet (sublet (inlet 'a 1) 'b 2) 'a) (sublet (inlet 'a 1) 'b 2)) (test (let ((b 2)) (cutlet (curlet) 'b) b) 'error) ; unbound variable (test (let ((b 1)) (let ((b 2)) (cutlet (curlet) 'b)) b) 1) (test (let ((#_+ 3)) #_+) 'error) (test (define #_+ 3) 'error) (test (set! #_+ 3) 'error) (let () (define hi (inlet 'x 12)) (let ((x 32) (y 1)) (let ((old-out (outlet hi))) (set! (outlet hi) (curlet)) (with-let hi ; x 12 y 1 (test (+ x y) 13)) (set! (outlet hi) old-out) ; x 32 y 1 (test (+ x y) 33) (with-let hi ; x 12 y # (test x 12) (test (defined? 'y) #f))))) (test (let () (with-let (curlet) (define hiho 43)) hiho) 43) (let () (define-macro (define! env . args) `(with-let ,env (define ,@args))) (test (let () (define! (curlet) (hiho x) (+ x 1)) (hiho 2)) 3)) (test (let () (with-let (curlet) (define (f3 a) (+ a 2))) (f3 1)) 3) (let () (with-let (rootlet) (define (this-is-global a) (+ a 1)))) (test (this-is-global 2) 3) (let () (with-let (inlet) (define (this-is-not-global a) (+ a 1)))) (test (this-is-not-global 2) 'error) (let () (apply varlet (curlet) (with-let (unlet) (let () (define (lognor n1 n2) (lognot (logior n1 n2))) (define (logit n1) n1) (map (lambda (binding) (cons (string->symbol (string-append "library:" (symbol->string (car binding)))) (cdr binding))) (curlet))))) (test (library:lognor 1 2) -4)) (let () (define (f1) (let ((a 0) (v (make-vector 3))) (do ((i 0 (+ i 1))) ((= i 3) v) (vector-set! v i a) (varlet (curlet) 'a i)))) (test (f1) #(0 0 1)) (define (f2) (let ((v (make-vector 3))) (do ((i 0 (+ i 1))) ((= i 3) v) (varlet (curlet) 'a i) (vector-set! v i a)))) (test (f2) #(0 1 2))) (test (null? (let->list (rootlet))) #f) (test (let? (inlet)) #t) (test (length (inlet)) 0) (test (length (inlet '(a . 2))) 1) (test (with-let (inlet '(a . 2)) a) 2) (test (with-let (inlet '(a . 2) '(b . 3)) (+ a b)) 5) (test (eq? (inlet) (rootlet)) #f) (test ((inlet (inlet '(a . 1))) 'a) 1) (test ((inlet (inlet '(a . 1)) '(b . 2)) 'b) 2) (test ((inlet '(b . 3) (inlet '(a . 1))) 'b) 3) (test (let ((a 1)) ((inlet (curlet)) 'a)) 1) (test (let ((a 1)) ((inlet '(b . 2)) 'a)) #) (test (let ((a (inlet 'b 2))) (set! (let-ref a 'b) 3) (a 'b)) 3) ; let-ref setter is let-set! (for-each (lambda (arg) (test (sublet arg) 'error) (test (varlet arg) 'error) (test (cutlet arg) 'error) (test (cutlet (curlet) arg) 'error)) (list -1 #\a 1 #(1 2 3) 3.14 3/4 1.0+1.0i pi abs macroexpand # # #f #(()) (list 1 2 3) '(1 . 2) "hi" '((a . 1)))) (test (let ((e (inlet '(a . 1)))) ((lambda (x) (x *)) e)) 'error) (test (let ((e (inlet '(a . 1)))) ((lambda (x) (x pi)) e)) 'error) (test (let () (inlet (cons pi 1))) 'error) (test (let () (inlet (cons "hi" 1))) 'error) (test (let? (inlet)) #t) (test (length (inlet)) 0) (test (length (inlet 'a 2)) 1) (test (with-let (inlet 'a 2) a) 2) (test (with-let (inlet 'a 2 'b 3) (+ a b)) 5) (test (eq? (inlet) (rootlet)) #f) (test ((inlet (inlet 'a 1)) 'a) 1) (test ((inlet (inlet 'a 1) '(b . 2)) 'b) 2) (for-each (lambda (arg) (test (inlet arg) 'error) (test (apply inlet arg) 'error)) (list -1 #\a 1 #(1 2 3) 3.14 3/4 1.0+1.0i pi abs macroexpand # # #f #(()) (list 1 2 3) '(1 . 2) "hi")) (test (inlet 'a) 'error) (test (inlet 1 2) 'error) (test (inlet 'a 2 'b) 'error) (test (with-let (inlet 'a (let ((p (open-output-string))) (display "32" p) p)) (get-output-string a)) "32") (for-each (lambda (arg) (test (let->list arg) 'error)) (list -1 #\a 1 #(1 2 3) 3.14 3/4 1.0+1.0i pi () #f #(()) (list 1 2 3) '(1 . 2) "hi" '((a . 1)))) (for-each (lambda (arg) (test (openlet arg) 'error) (test (coverlet arg) 'error)) (list -1 #\a 1 #(1 2 3) 3.14 3/4 1.0+1.0i pi abs macroexpand () # # #f #(()) (list 1 2 3) '(1 . 2) "hi" '((a . 1)))) (let () (let ((_xxx_ 0)) (let ((e (curlet))) (for-each (lambda (arg) (let-set! e '_xxx_ arg) (test (let-ref e '_xxx_) arg)) (list -1 #\a 1 #(1 2 3) 3.14 3/4 1.0+1.0i pi abs macroexpand () # # #f #(()) (list 1 2 3) '(1 . 2) "hi" '((a . 1))))))) (test (let-ref) 'error) (test (let-ref (curlet)) 'error) (test (let-ref a b c) 'error) (test (let-ref (sublet ()) '_asdf_) #) (test (let-ref (sublet () '(a . 3)) 'a) 3) (test (let-ref (sublet () '(a . 3)) 'A) #) (test (let-ref (rootlet) '+) +) (test (let-ref (rootlet) +) 'error) (test (let-ref () '+) 'error) (test (let-ref (funclet (let ((a 2)) (lambda (b) (+ a b)))) 'a) 2) (let ((etest (let ((a 2)) (lambda (b) (+ a b))))) (let-set! (funclet etest) 'a 32) (test (etest 1) 33)) (test (let-set!) 'error) (test (let-set! a b) 'error) (let ((e (inlet (cons 'a 1)))) (define (eref a) (e a)) (define (eset a b) (set! (e a) b)) (for-each (lambda (arg) (test (let-ref arg 'a) 'error) (test (let-set! arg 'a 1) 'error) (test (let-ref e arg) 'error) (test (let-set! e arg #f) 'error) (test (e arg) 'error) (test (set! (e arg) #f) 'error) (test (eref arg) 'error) (test (eset (e arg) #f) 'error)) (list -1 #\a 1 #(1 2 3) 3.14 3/4 1.0+1.0i pi abs macroexpand () # # #f #(()) (list 1 2 3) '(1 . 2) "hi" '((a . 1))))) (let () (define (ft) (let ((a (vector #f)) (b 0)) (*s7* (vector-ref a b)))) (test (ft) 'error)) (test (inlet :a 1) (inlet (cons 'a 1))) (test (inlet :a 1 :b 2) (inlet 'a 1 'b 2)) (test (inlet 'pi 3.0) 'error) (let ((e (inlet 'a 1))) (test (let-set! e :a 2) #) (test (let-ref e :a) #) (test (let-ref e 'a) 1)) (for-each (lambda (arg) (test (openlet? arg) #f)) (list -1 #\a 1 #(1 2 3) 3.14 3/4 1.0+1.0i () abs macroexpand # # #f #(()) (list 1 2 3) '(1 . 2) "hi" '((a . 1)))) (test (openlet) 'error) (test (openlet 1 2) 'error) (test (openlet?) 'error) (test (openlet? 1 2) 'error) (test (openlet (rootlet)) 'error) (let ((e (openlet (inlet 'a 1)))) (test (openlet? (sublet e '(b . 2))) #t)) (let ((f (lambda (x) (+ x 1)))) (test (openlet? f) #f) (openlet f) (test (openlet? f) #t) (coverlet f) (test (openlet? f) #f)) (let ((f (lambda* (x) (+ x 1)))) (test (openlet? f) #f) (openlet f) (test (openlet? f) #t) (coverlet f) (test (openlet? f) #f)) (let ((f (sublet ()))) (test (openlet? f) #f) (openlet f) (test (openlet? f) #t) (coverlet f) (test (openlet? f) #f)) (let ((e1 (openlet (inlet 'f1 (define-macro (f1 a) `(+ ,a 1)))))) (test ((e1 'f1) 3) 4)) (let () (define-macro (f x) `(+ ,x 1)) (test (openlet? f) #f) (test (openlet f) f) (test (openlet? f) #t) (test (coverlet f) f)) (let () (define-bacro* (f x) `(+ ,x 1)) (test (openlet? f) #f) (test (openlet f) f) (test (openlet? f) #t) (test (coverlet f) f)) (test (curlet 1) 'error) (test (rootlet 1) 'error) (test (unlet 1) 'error) (test (set! (curlet) 1) 'error) (test (set! (rootlet) 1) 'error) (test (set! (unlet) 1) 'error) (test (let () (set! unlet 2)) 'error) (test (let ((unlet 2)) unlet) 'error) (test (let ((e (sublet () '(a . 1)))) ((lambda (x) (x *)) e)) 'error) (test (let ((e (sublet () '(a . 1)))) ((lambda (x) (x pi)) e)) 'error) (test (let () (sublet () (cons pi 1))) 'error) (test (let () (sublet () (cons "hi" 1))) 'error) (test (let () (varlet () (cons pi 1))) 'error) (test (let () (varlet () (cons "hi" 1))) 'error) (test (let ((lt (openlet (inlet 'x (list 1 2 3) 'make-iterator (let ((iterator? #t)) (lambda (e) (#_make-iterator (e 'x)))))))) (format #f "~{~A~^ ~}" lt)) "1 2 3") (when (not pure-s7) (test (let ((lt (openlet (inlet 'x (list 1 2 3) 'let->list (lambda (e) (e 'x)))))) (format #f "~{~A~^ ~}" lt)) "1 2 3")) (test (eq? (rootlet) ()) #f) (test (eq? (rootlet) (rootlet)) #t) (test (eq? (rootlet) (unlet)) #f) (test (eqv? (rootlet) (rootlet)) #t) (test (eqv? (rootlet) (unlet)) #f) (test (equal? (rootlet) (rootlet)) #t) (test (equal? (rootlet) (unlet)) #f) ;(test (equal? (curlet) (unlet)) #f) (let ((e #f) (g #f)) (set! e (curlet)) (set! g (rootlet)) (if (not (equal? e (curlet))) ; test here introduces a new environment (format-logged #t ";(equal? e (curlet)) -> #f?~%")) (test g (rootlet)) (test (equal? e g) #f) (let () (if (not (equal? e (curlet))) (format-logged #t ";2nd case (equal? e (curlet)) -> #f?~%")))) (let () (define global-env (rootlet)) (test (equal? global-env (rootlet)) #t) (test (equal? (list global-env) (list (rootlet))) #t) (test (morally-equal? global-env (rootlet)) #t) (test (morally-equal? (list global-env) (list (rootlet))) #t)) (test (pair? (member (let ((a 1) (b 2)) (map cdr (curlet))) '((1 2) (2 1)))) #t) (test (let () (map cdr (curlet))) ()) (test (pair? (member (let ((vals ())) (let ((a 1) (b 2)) (for-each (lambda (slot) (set! vals (cons (cdr slot) vals))) (curlet))) vals) '((2 1) (1 2)))) #t) (test (let ((a '(1 2 3)) (b '(3 4 5)) (c '(6 7 8))) (map + a b c (apply values (map cdr (curlet))))) '(20 26 32)) (test (pair? (member (let ((a 1) (b 2) (c 3)) (map (lambda (a b) (+ a (cdr b))) (list 1 2 3) (curlet))) '((2 4 6) (4 4 4)))) #t) (test (let () (format #f "~A" (curlet))) "(inlet)") ;(test (let ((a 32) (b '(1 2 3))) (format #f "~A" (curlet))) "(inlet)") ;(test (let ((a 1)) (object->string (curlet))) "(inlet)") (test (let ((a 1)) (object->string (rootlet))) "(rootlet)") (test (format #f "~A" (rootlet)) "(rootlet)") (test (let ((a 32) (b #(1 2 3))) (format #f "~{~A~^ ~}" (curlet))) "(a . 32) (b . #(1 2 3))") (test (object->string (rootlet)) "(rootlet)") (test (let () (object->string (curlet))) "(inlet)") (test (let ((a 3)) (object->string (curlet))) "(inlet 'a 3)") (test (let ((a 3) (b "hi")) (object->string (curlet))) "(inlet 'a 3 'b \"hi\")") (test (let () (define (hi a b) (curlet)) (object->string (hi 3 4))) "(inlet 'a 3 'b 4)") (test (let () (varlet (unlet) (cons 'a 32)) (symbol->value 'a (unlet))) #) (test (let ((caar 123)) (+ caar (with-let (unlet) (caar '((2) 3))))) 125) (test (let () (+ (let ((caar 123)) (+ caar (with-let (unlet) (let ((val (caar '((2) 3)))) (set! caar -1) (+ val caar))))) ; 124 (let ((caar -123)) (+ caar (with-let (unlet) (let ((val (caar '((20) 3)))) (set! caar -2) (+ val caar))))) ; -105 (caar '((30) 3)))) ; 30 + 19 49) (test (let ((a 1)) (eval '(+ a b) (sublet (curlet) (cons 'b 32)))) 33) (test (let ((a 1)) (+ (eval '(+ a b) (sublet (curlet) (cons 'b 32))) a)) 34) (test (let ((a 1)) (+ (eval '(+ a b) (sublet (curlet) (cons 'b 32) (cons 'a 12))) a)) 45) (test (let ((a 2)) (eval '(+ a 1) (sublet (curlet)))) 3) (test (let ((a 1)) (+ (eval '(+ a b) (sublet (sublet (curlet) (cons 'b 32)) (cons 'a 12))) a)) 45) (test (eval (list + 'a (eval (list - 'b) (sublet (unlet) (cons 'b 1)))) (sublet (unlet) (cons 'a 2))) 1) (let ((e (openlet ; make it appear to be empty to the rest of s7 (inlet 'object->string (lambda args "(inlet)") 'map (lambda args ()) 'for-each (lambda args #) 'let->list (lambda args ()) 'length (lambda args 0) 'copy (lambda args (inlet)) 'open #t 'coverlet (lambda (e) (set! (e 'open) #f) e) 'openlet (lambda (e) (set! (e 'open) #t) e) 'openlet? (lambda (e) (e 'open)) ;; your secret data here 'secret 'gray-cat )))) (test (object->string e) "(inlet)") ;(test (map values e) ()) (when (not pure-s7) (test (let->list e) ())) (test (length e) 0) (test (object->string (copy e)) "(inlet)") (coverlet e) (test (object->string e) "(inlet)") (test (openlet? e) #f) (openlet e) (test (openlet? e) #t)) (let () (define (lets . args) (apply sublet () args)) (let ((e (lets '(a . 1) '(b . 2)))) (test (eval '(+ a b 3) e) 6))) ;(test (eval 'a (sublet () '(a . 1) '(a . 2))) 'error) ; no longer an error, mainly for repl's convenience ;(test (eval 'a (varlet () '(a . 1) '(a . 2))) 'error) (test (eval 'pi (sublet () '(pi . 1) '(a . 2))) 'error) (test (eval 'pi (varlet () '(pi . 1) '(a . 2))) 'error) (test (eval 'pi (sublet () (cons 'pi pi))) 'error) ; changed 25-Jun-14 (test (eval 'pi (varlet () (cons 'pi pi))) 'error) (test (map (sublet () '(asdf . 32) '(bsdf . 3)) '(bsdf asdf)) '(3 32)) (test (equal? (map (rootlet) '(abs cons car)) (list abs cons car)) #t) (test (with-let (sublet (inlet) '(a . 1)) a) 1) (test (with-let (sublet (inlet '(b . 2)) '(a . 1)) (+ a b)) 3) (test (with-let (sublet () (inlet) '(a . 1)) a) 1) (test (with-let (sublet () (inlet '(b . 2)) '(a . 1)) (+ a b)) 3) (test (with-let (sublet (inlet '(b . 2) '(c . 3)) '(a . 1)) (+ a b c)) 6) (let () (define (e1) (let ((e (curlet))) (with-let e 0))) (define (e2 a) (let ((e (curlet))) (with-let e a))) (define (e3) (let ((e (curlet))) (with-let e 1 . 2))) (define (e4) (let ((e (curlet))) (with-let e 0 1))) (define (e5) (let ((e (curlet))) (with-let e (+ 1 2) (+ 2 3)))) (test (e2 10) 10) (e1) (test (e1) (e2 0)) (test (e3) 'error) (e4) (test (e4) 1) (e5) (test (e5) 5)) (let () (define-constant _a_constant_ 32) (test (eval '_a_constant_ (sublet () (cons '_a_constant_ 1))) 'error) (test (eval '_a_constant_ (sublet () (cons '_a_constant_ 32))) 'error)) (test (let ((a 1)) (eval-string "(+ a b)" (sublet (curlet) (cons 'b 32)))) 33) (test (let ((a 1)) (+ (eval-string "(+ a b)" (sublet (curlet) (cons 'b 32))) a)) 34) (test (let ((a 1)) (+ (eval-string "(+ a b)" (sublet (curlet) (cons 'b 32) (cons 'a 12))) a)) 45) (test (let ((a 2)) (eval-string "(+ a 1)" (sublet (curlet)))) 3) (test (let ((a 1)) (+ (eval-string "(+ a b)" (sublet (sublet (curlet) (cons 'b 32)) (cons 'a 12))) a)) 45) (test (eval-string (string-append "(+ a " (number->string (eval (list - 'b) (sublet (unlet) (cons 'b 1)))) ")") (sublet (unlet) (cons 'a 2))) 1) (test (sublet) 'error) (for-each (lambda (arg) (test (sublet arg '(a . 32)) 'error) (test (varlet arg '(a . 32)) 'error)) (list -1 #\a 1 3.14 3/4 1.0+1.0i "hi" 'hi #() #f _ht_ _null_ _c_obj_)) (let ((e (sublet (curlet) (cons 'a 32) (cons 'b 12)))) (test (eval '(+ a b) e) 44) (test (eval '(+ a b c) (sublet e (cons 'c 3))) 47) (test (eval '(+ a b) (sublet e (cons 'b 3))) 35) (test (eval-string "(+ a b)" e) 44) (test (eval-string "(+ a b c)" (sublet e (cons 'c 3))) 47) (test (eval-string "(+ a b)" (sublet e (cons 'b 3))) 35) ) (test (with-let (sublet () '(a . 1)) (defined? 'a)) #t) (test (defined? 'a (sublet () '(a . 1))) #t) (test (defined? 'b (sublet () '(a . 1))) #f) (test (defined? 'a '((a . 1))) 'error) (test (defined? 'a '((a . 1) 2)) 'error) (test (defined? 'a (sublet ())) #f) (test (symbol->value 'a (sublet () '(a . 1))) 1) (test (symbol->value 'b (sublet () '(a . 1))) #) (test (symbol->value 'a '((a . 1))) 'error) (test (symbol->value 'a '((a . 1) 2)) 'error) (test (eval 'a (sublet () '(a . 1))) 1) (test (eval 'a (sublet () '(b . 1))) 'error) (test (eval 'a '((a . 1))) 'error) (test (eval 'a '((a . 1) 2)) 'error) (test (eval-string "a" (sublet () '(a . 1))) 1) (test (eval-string "a" (sublet () '(b . 1))) 'error) (test (eval-string "a" '((a . 1))) 'error) (test (eval-string "a" '((a . 1) 2)) 'error) (test (with-let (sublet () '(a . 1)) a) 1) (test (with-let (sublet ()) 1) 1) (test (with-let (sublet () '(b . 1)) a) 'error) (test (with-let '((a . 1)) a) 'error) (test (with-let '((a . 1) 2) a) 'error) (test (let ((a 1)) (set! ((curlet) 'a) 32) a) 32) (for-each (lambda (arg) (test (sublet (curlet) arg) 'error) (test (varlet (curlet) arg) 'error)) (list -1 #\a #(1 2 3) 3.14 3/4 1.0+1.0i 'hi "hi" abs #(()) (list 1 2 3) '(1 . 2) (lambda () 1))) (test (with-let (curlet) (let ((x 1)) x)) 1) (let ((old-safety (*s7* 'safety))) (set! (*s7* 'safety) 1) (define (hi) (let ((e (sublet (curlet) (cons 'abs (lambda (a) (- a 1)))))) (with-let e (abs -1)))) (test (hi) -2) (test (hi) -2) (test (let ((e (sublet (curlet) (cons 'abs (lambda (a) (- a 1)))))) (with-let e (abs -1))) -2) (set! (*s7* 'safety) old-safety)) (test (let ((x 12)) (let ((e (curlet))) (let ((x 32)) (with-let e (* x 2))))) 24) (test (let ((e #f)) (let ((x 2) (y 3)) (set! e (curlet))) (let ((x 0) (y 0)) (with-let e (+ x y)))) 5) (test (let ((e #f)) (let () (define (func a b) (set! e (curlet)) (+ a b)) (func 1 2)) (with-let e (+ a b))) 3) (test (let ((e #f) (f #f)) (let () (define (func a b) (set! e (curlet)) (+ a b)) (set! f func) (func 1 2)) (let ((val (with-let e (+ a b)))) (f 3 4) (list val (with-let e (+ a b))))) '(3 7)) (test (with-let) 'error) (test (with-let 1) 'error) (test (with-let () 1) 'error) (test (with-let (curlet)) 'error) ; ?? perhaps this should be # (test (outlet) 'error) (test (outlet (curlet) #f) 'error) (test (eq? (outlet (rootlet)) (rootlet)) #t) (test (set! (outlet (curlet)) #f) 'error) (test (set! (outlet) #f) 'error) (let () (test (let () (set! (outlet (curlet)) (let ((a 1) (b 2)) (set! (outlet (curlet)) (rootlet)) (curlet))) (+ a b)) 3)) ;; equivalent to (let ((a 1) (b 2)) (let () (curlet))) ;; that is, we've turned the let structure inside out (test (let () (set! (outlet (curlet)) (rootlet)) (eq? (outlet (curlet)) (rootlet))) #t) (test (let ((a 1)) (let ((b 2)) (set! (outlet (curlet)) (rootlet)) ((curlet) 'a))) #) (test (let ((a 1) (e #f)) (set! e (curlet)) (let ((b 2)) (let ((c 3)) (set! (outlet (curlet)) e) (and (equal? ((curlet) 'a) 1) (equal? ((curlet) 'b) #) (equal? ((curlet) 'c) 3) (equal? (outlet (curlet)) e))))) #t) (for-each (lambda (arg) (test (with-let arg #f) 'error) (test (outlet arg) 'error) (test (set! (outlet (curlet)) arg) 'error)) (list -1 #\a #(1 2 3) 3.14 3/4 1.0+1.0i () 'hi "hi" abs #(()) (list 1 2 3) '(1 . 2) (lambda () 1))) (test (with-let (sublet (sublet ()) '(a . 1)) 1) 1) (test (with-let (sublet (sublet ()) '(a . 1)) a) 1) (test (with-let (curlet) 1) 1) (test (let ((a 1)) (+ (with-let (sublet (curlet) (cons 'a 10)) a) a)) 11) (test (let ((a 1)) (+ (with-let (sublet (curlet) (cons 'a 10)) (+ a (with-let (sublet (curlet) (cons 'a 100)) a))) a)) 111) (test (let ((a 1)) (+ (with-let (sublet (curlet) (cons 'a 10)) (+ a (with-let (sublet (curlet) (cons 'b 100)) a))) a)) 21) (test (let ((a 1)) (let ((e (curlet))) (+ (with-let (sublet (curlet) (cons 'a 10)) (+ a (with-let e a))) a))) 12) (test (let ((a 1)) (let ((e (curlet))) (+ (with-let (varlet (sublet (curlet) (cons 'a 10)) (cons 'a 20)) (+ a (with-let e a))) a))) 22) (test (= ((inlet 'a 1 'a 2) 'a) (with-let (inlet 'a 1 'a 2) a)) #t) (test (= ((varlet (inlet 'a 1) 'a 2) 'a) (with-let (varlet (inlet 'a 1) 'a 2) a)) #t) (test (let ((a 1)) (+ (with-let (sublet (curlet) (cons 'a 10)) (+ (let ((b a)) (varlet (curlet) (cons 'a 20)) (+ a b)) a)) a)) 41) (test (let ((a 1)) (+ (let ((a 2)) (+ (let ((a 3)) a) a)) a)) 6) (test (let ((a 1)) (+ (let () (+ (let ((a 3)) (varlet (outlet (curlet)) '(a . 2)) a) a)) a)) 6) (test (let () (let ((a 1)) (varlet (outlet (curlet)) '(a . 2))) a) 2) (test (let ((a 1)) (let ((e (curlet))) (+ (with-let (sublet e (cons 'a 10)) (+ a (with-let e a))) a))) 'error) ; "e" is not in the curlet at the top, so it's not in the nested env (test (let ((x 3)) (varlet (curlet) (cons 'y 123)) (+ x y)) 126) #| ;; can't decide about these -- safe closures prebuild the funclet from the arglist so two of these fail (test (let () (define (hiho a) (+ a b)) (varlet (funclet hiho) (cons 'b 21)) (hiho 1)) 22) (test (let () (define hiho (let ((x 32)) (lambda (a) (+ a x b)))) (varlet (funclet hiho) (cons 'b 10) (cons 'x 100)) (hiho 1)) 111) (test (let () (define hiho (let ((x 32)) (lambda* (a) (+ a x b)))) (varlet (funclet hiho) (cons 'b 10) (cons 'x 100)) (hiho 1)) 111) (test (let () (define hiho (let () (define (hi b) (+ b 1)) (lambda (a) (hi a)))) (varlet (funclet hiho) (cons 'hi (lambda (b) (+ b 123)))) (hiho 2)) 125) |# (test (let () ; here's one way for multiple functions to share a normal scheme closure (define f1 (let ((x 23)) (lambda (a) (+ x a)))) (define f2 (with-let (funclet f1) (lambda (b) (+ b (* 2 x))))) (+ (f1 1) (f2 1))) 71) (test (varlet) 'error) (test (sublet 3) 'error) (test (varlet 3) 'error) (test (let ((e (curlet))) (let? e)) #t) (test (let ((f (lambda (x) (let? x)))) (f (curlet))) #t) (test (let ((e (varlet () '(a . 1)))) (let? e)) #t) (test (let ((e (varlet () '(a . 1)))) ((lambda (x) (let? x)) e)) #t) (test (let? ((lambda () (curlet)))) #t) (test (let? ((lambda (x) x) (curlet))) #t) (test (let ((e (let ((x 32)) (lambda (y) (let ((z 123)) (curlet)))))) (eval `(+ x y z) (e 1))) 156) (test (let ((e #f)) (set! e (let ((x 32)) (lambda (y) (let ((z 123)) (funclet e))))) (eval `(+ x 1) (e 1))) 33) (test (let () ((curlet) 'abs)) #) (test ((rootlet) 'abs) abs) (test (catch #t (lambda () (with-let (curlet) (error 'testing "a test") 32)) (lambda args (car args))) 'testing) (test (call-with-exit (lambda (go) (with-let (curlet) (go 1) 32))) 1) (test (let ((x 0)) (call-with-exit (lambda (go) (with-let (varlet (curlet) (cons 'x 123)) (go 1)))) x) 0) (test (let ((x 1)) (+ x (call-with-exit (lambda (go) (with-let (varlet (curlet) (cons 'x 123)) (go x)))) x)) 125) (test (let ((x 0)) (catch #t (lambda () (with-let (varlet (curlet) (cons 'x 123)) (error 'oops) x)) (lambda args x))) 0) (let ((a 1)) (test ((curlet) 'a) 1) (set! ((curlet) 'a) 32) (test ((curlet) 'a) 32)) (let () (test (equal? (curlet) (rootlet)) #f)) (test (let ((a 1)) (let ((e (curlet))) (set! (e 'a) 2)) a) 2) (let () (define (hi e) (set! (e 'a) 2)) (test (let ((a 1)) (hi (curlet)) a) 2)) (let () (define (hi) (let ((a 1)) (let ((e (curlet)) (i 'a)) (set! (e i) #\a)) a)) (hi) (hi) (test (hi) #\a)) (test (let ((a 1)) (let ((e (curlet))) (e :hi))) #) ; global env is not searched in this case (let ((e1 #f) (e2 #f)) (let ((a 1)) (set! e1 (curlet))) (let ((a 1)) (set! e2 (curlet))) (test (equal? e1 e2) #t) (test (eqv? e1 e2) #f)) (let ((e1 #f) (e2 #f)) (let ((a 1)) (set! e1 (curlet))) (let ((a 2)) (set! e2 (curlet))) (test (equal? e1 e2) #f)) (let ((e1 #f) (e2 #f)) (let ((a 1)) (set! e1 (curlet))) (let ((a 1) (b 2)) (set! e2 (curlet))) (test (equal? e1 e2) #f)) (let ((e1 #f) (e2 #f)) (let ((a 1) (b 2)) (set! e1 (curlet))) (let ((a 1) (b 2)) (set! e2 (curlet))) (test (equal? e1 e2) #t)) (let ((e1 #f) (e2 #f)) (let () (set! e1 (curlet))) (let ((a 1)) (set! e2 (curlet))) (test (equal? e1 e2) #f)) (test (let ((a #(1 2 3))) ((curlet) 'a 1)) 2) (test (let ((a #(1 2 3))) (let ((e (curlet))) ((curlet) 'e 'a 1))) 2) (let ((x (openlet (inlet 'let-ref-fallback (lambda args args))))) (test (x) (list x #f)) ; let-ref expects 2 args (test (x 1) (list x 1))) (let ((x (openlet (inlet 'let-set!-fallback (lambda args args))))) ; (test (set! (x) 1) (list x 1)) ; doesn't work yet (test (set! (x 1) 2) (list x 1 2))) (let () (define (f1) (let ((v (vector #f)) (X 0)) (do ((i 0 (+ i 1))) ((= i 1) v) (vector-set! v 0 (let-ref X 'a))))) (test (f1) 'error)) (let ((x '(a))) (let ((x '(c))) x) (let ((x '(b))) (define (transparent-memq sym var e) (let ((val (symbol->value var e))) (or (and (pair? val) (memq sym val)) (and (not (eq? e (rootlet))) (transparent-memq sym var (outlet e)))))) (let ((ce (curlet))) (test (list (transparent-memq 'a 'x ce) (transparent-memq 'b 'x ce) (transparent-memq 'c 'x ce)) '((a) (b) #f))))) (test (let-set! (rootlet) :rest #f) 'error) (test (make-iterator) 'error) (test (make-iterator (curlet) 1) 'error) (test (iterator?) 'error) (test (iterator? 1 2) 'error) (test (arity make-iterator) '(1 . 2)) (for-each (lambda (arg) (test (iterator? arg) #f)) (list "hi" () -1 #\a 1 'a-symbol #(1 2 3) 3.14 3/4 1.0+1.0i #t (list 1 2 3) '(1 . 2))) (let ((a 1)) (let ((lti (make-iterator (curlet)))) (test (cdr (lti)) 1) (test (lti) #) (test (lti) #))) (let () (let ((lti (make-iterator (curlet)))) (test (lti) #))) (let ((lti (make-iterator (inlet 'a 1 'b 2)))) ;(test (length lti) #f) (test (reverse lti) 'error) (test (iterator? lti) #t) (test (lti) '(b . 2)) (test (lti) '(a . 1)) (test (lti) #) (test (set! (lti) 32) 'error)) (let ((lti (make-iterator (rootlet)))) (test (defined? (car (lti))) #t) (test (let ((b (lti))) (equal? (symbol->value (car b)) (cdr b))) #t)) ;;; make-type ---------------- (let () (define (make-type . args) (let* ((type (gensym "make-type type")) ; built-in type and value slots have gensym'd names (value (gensym "make-type value")) (obj (openlet (sublet () (cons type type) (cons value #))))) ;; load up any methods/slots (do ((arg args (cddr arg))) ((null? arg)) (varlet obj (cons (keyword->symbol (car arg)) (cadr arg)))) ;; return a list of '(? make ref) funcs (list (lambda (x) (and (let? x) (eq? (x type) type))) (lambda* (new-value) (let ((new-obj (copy obj))) (set! (new-obj value) new-value) new-obj)) (lambda (x) (x value))))) (define special-value (let ((type (make-type))) ((cadr type) 'special))) (test (eq? special-value special-value) #t) (test (eqv? special-value special-value) #t) (test (equal? special-value special-value) #t) (test (procedure? special-value) #f) (for-each (lambda (arg) (test (or (eq? arg special-value) (eqv? arg special-value) (equal? arg special-value)) #f)) (list "hi" -1 #\a 1 'special 3.14 3/4 1.0+1.0i #f #t '(1 . 2) # #)) (test (let ((obj ((cadr (make-type :type "hi" :value 123)) 0))) (list (obj 'type) (obj 'value))) '("hi" 123)) (test (let ((obj ((cadr (make-type :type "hi" :value 123))))) (list (obj 'type) (obj 'value))) '("hi" 123)) (test (let* ((rec-type (make-type)) (? (car rec-type)) (make (cadr rec-type)) (ref (caddr rec-type))) (let ((val-1 (make "hi"))) (let ((val-2 (make val-1))) (let ((val-3 (make val-2))) (ref (ref (ref val-3))))))) "hi") (test (let* ((rec1-type (make-type)) (?1 (car rec1-type)) (make1 (cadr rec1-type)) (ref1 (caddr rec1-type))) (let* ((rec2-type (make-type)) (?2 (car rec2-type)) (make2 (cadr rec2-type)) (ref2 (caddr rec2-type))) (let ((val-1 (make1 "hi"))) (let ((val-2 (make2 "hi"))) (let ((val-3 (make1 val-2))) (and (string=? (ref2 (ref1 val-3)) "hi") (not (equal? val-1 val-2)) (?1 val-1) (?2 val-2) (not (?2 val-3)))))))) #t) (test (let* ((rec1-type (make-type)) (make1 (cadr rec1-type)) (ref1 (caddr rec1-type))) (let* ((rec2-type (make-type)) (make2 (cadr rec2-type))) (let ((val-1 (make1 "hi"))) (let ((val-2 (make2 val-1))) (ref1 val-2))))) #) (test (make-type (make-type)) 'error) (let ((t (make-type))) (let ((t? (car t)) (make-t (cadr t)) (t-ref (caddr t))) (test (make-t 1 2) 'error) (test (t? (make-t)) #t) (test (t-ref (make-t)) #f) (test (t? 1 2) 'error) (test (t?) 'error) (test (t-ref) 'error) (test (t-ref 1 2) 'error) (for-each (lambda (arg) (test (t-ref arg) 'error)) (list #\a 'a-symbol 1.0+1.0i #t #(1 2) () 3/4 3.14 #() "hi" :hi 1 #f #t '(1 . 2))))) (begin (define rec? #f) (define make-rec #f) (define rec-a #f) (define rec-b #f) (let* ((rec-type (make-type)) (? (car rec-type)) (make (cadr rec-type)) (ref (caddr rec-type))) (set! make-rec (lambda* ((a 1) (b 2)) (make (vector a b)))) (set! rec? (lambda (obj) (? obj))) (set! rec-a (dilambda (lambda (obj) (and (rec? obj) (vector-ref (ref obj) 0))) (lambda (obj val) (if (rec? obj) (vector-set! (ref obj) 0 val))))) (set! rec-b (dilambda (lambda (obj) (and (rec? obj) (vector-ref (ref obj) 1))) (lambda (obj val) (if (rec? obj) (vector-set! (ref obj) 1 val))))))) (let ((hi (make-rec 32 '(1 2)))) (test (rec? hi) #t) (test (equal? hi hi) #t) (test (rec? 32) #f) (test (rec-a hi) 32) (test (rec-b hi) '(1 2)) (set! (rec-b hi) 123) (test (rec-b hi) 123) (let ((ho (make-rec 32 '(1 2)))) (test (eq? hi ho) #f) (test (eqv? hi ho) #f) (test (equal? hi ho) #f) (set! (rec-b ho) 123) (test (equal? hi ho) #t)) (let ((ho (make-rec 123 ()))) (test (eq? hi ho) #f) (test (eqv? hi ho) #f) (test (equal? hi ho) #f)) (test (equal? (copy hi) hi) #t) (test (fill! hi 1) 'error) ;(test (object->string hi) "(inlet)") (test (length hi) 2) (test (reverse hi) 'error) (test (for-each abs hi) 'error) (test (map abs hi) 'error) (test (hi 1) 'error) (test (set! (hi 1) 2) 'error) ) (let ((rec3? (car (make-type))) (rec4? (car (make-type :value 21)))) (for-each (lambda (arg) (test (rec3? arg) #f) (test (rec4? arg) #f)) (list "hi" -1 #\a 1 'a-symbol 3.14 3/4 1.0+1.0i #f #t '(1 . 2)))) ) ;;; pfloat-vector (let () (begin (define pfloat-vector? #f) (define make-pfloat-vector #f) (let ((type (gensym)) (->float (lambda (x) (if (real? x) (* x 1.0) (error 'wrong-type-arg "pfloat-vector new value is not a real: ~A" x))))) (varlet (curlet) (cons 'length (lambda (p) ((funclet p) 'len))) (cons 'object->string (lambda* (p (use-write #t)) "#")) (cons 'vector? (lambda (p) #t)) (cons 'vector-length (lambda (p) ((funclet p) 'len))) (cons 'vector-dimensions (lambda (p) (list ((funclet p) 'len)))) (cons 'vector-ref (lambda (p ind) (#_vector-ref ((funclet p) 'obj) ind))) (cons 'vector-set! (lambda (p ind val) (#_vector-set! ((funclet p) 'obj) ind (->float val)))) (cons 'vector-fill! (lambda (p val) (#_vector-fill! ((funclet p) 'obj) (->float val)))) (cons 'fill! (lambda (p val) (#_vector-fill! ((funclet p) 'obj) (->float val)))) (cons 'vector->list (lambda (p) (#_vector->list ((funclet p) 'obj)))) (cons 'equal? (lambda (x y) (#_equal? ((funclet x) 'obj) ((funclet y) 'obj)))) (cons 'morally-equal? (lambda (x y) (#_morally-equal? ((funclet x) 'obj) ((funclet y) 'obj)))) (cons 'reverse (lambda (p) (vector->pfloat-vector (#_reverse ((funclet p) 'obj))))) (cons 'copy (lambda (p) (vector->pfloat-vector ((funclet p) 'obj)))) (cons 'sort! (lambda (p f) (vector->pfloat-vector (#_sort! ((funclet p) 'obj) f)))) ) (set! make-pfloat-vector (lambda* (len (init 0.0)) (let ((obj (make-vector len (->float init)))) (openlet (dilambda (lambda (i) (#_vector-ref obj i)) (lambda (i val) (#_vector-set! obj i (->float val)))))))) (set! pfloat-vector? (lambda (obj) (and (procedure? obj) (eq? ((funclet obj) 'type) type)))))) (define pfloat-vector (lambda args (let* ((len (length args)) (v (make-pfloat-vector len))) (do ((i 0 (+ i 1)) (arg args (cdr arg))) ((= i len) v) (set! (v i) (car arg)))))) (define (vector->pfloat-vector v) (let* ((len (length v)) (fv (make-pfloat-vector len))) (do ((i 0 (+ i 1))) ((= i len)) (set! (fv i) (v i))) fv)) (let ((v (make-pfloat-vector 3 0.0))) (test (length v) 3) (set! (v 1) 32.0) (test (v 0) 0.0) (test (v 1) 32.0) (test (eq? v v) #t) (test (eq? v (pfloat-vector 0.0 32.0 0.0)) #f) (test (equal? v (pfloat-vector 0.0 32.0 0.0)) #t) (test (morally-equal? v (pfloat-vector 0.0 32.0 0.0)) #t) (test (reverse (pfloat-vector 1.0 2.0 3.0)) (pfloat-vector 3.0 2.0 1.0)) (test (copy (pfloat-vector 1.0 2.0 3.0)) (pfloat-vector 1.0 2.0 3.0)) (test (let () (fill! v 1.0) v) (pfloat-vector 1.0 1.0 1.0)) (test (object->string v) "#") (test (let ((v (pfloat-vector 1.0 2.0 3.0))) (map v (list 2 1 0))) '(3.0 2.0 1.0)) (test (v -1) 'error) (test (v 32) 'error) (for-each (lambda (arg) (test (v arg) 'error)) (list #\a 'a-symbol 1.0+1.0i #f #t abs #(1 2) () 3/4 3.14 '(1 . 2))) (test (set! (v 0) "hi") 'error) (test (set! (v -1) "hi") 'error) (test (set! (v 32) "hi") 'error) (for-each (lambda (arg) (test (set! (v 0) arg) 'error)) (list #\a 'a-symbol 1.0+1.0i #f #t abs #(1 2) () '(1 . 2))) (test (length v) 3) ) (let ((v1 (pfloat-vector 3 1 4 8 2))) (let ((v2 (sort! v1 <)) (one 1)) (test (equal? v2 (pfloat-vector 1 2 3 4 8)) #t) (test (vector? v1) #t) (test (pfloat-vector? v1) #t) (test (vector-length v1) 5) (if (not pure-s7) (test (vector->list v1) '(1.0 2.0 3.0 4.0 8.0))) (test (vector-ref v1 one) 2.0) (test (vector-set! v1 1 3/2) 1.5) (test (vector-ref v1 1) 1.5) (test (vector-dimensions v1) '(5)) (fill! v1 32) (test v1 (pfloat-vector 32.0 32.0 32.0 32.0 32.0)) (test (pfloat-vector? #(1 2 3)) #f) (for-each (lambda (arg) (test (pfloat-vector? arg) #f)) (list -1 #\a 1 #(1 2 3) 3.14 3/4 1.0+1.0i () #f #(()) (list 1 2 3) '(1 . 2) "hi" '((a . 1)))) (for-each (lambda (arg) (test (make-pfloat-vector arg) 'error)) (list -1 #\a #(1 2 3) 3.14 3/4 1.0+1.0i () #f #(()) '(1 . 2) "hi" '((a . 1)))) (for-each (lambda (arg) (test (make-pfloat-vector 3 arg) 'error)) (list #\a #(1 2 3) 1.0+1.0i () #f #(()) (list 1 2 3) '(1 . 2) "hi" '((a . 1)))) (for-each (lambda (arg) (test (pfloat-vector (list arg)) 'error)) (list #\a #(1 2 3) 1.0+1.0i () #f #(()) (list 1 2 3) '(1 . 2) "hi" '((a . 1)))) ))) ;;; environments as objects (define-bacro* (define-class class-name inherited-classes (slots ()) (methods ())) ;; a bacro is needed so that the calling environment is accessible via outlet ;; we could also use the begin/let shuffle, but it's too embarrassing `(let ((outer-env (outlet (curlet))) (new-methods ()) (new-slots ()) (new-type (gensym "define-class"))) (for-each (lambda (class) ;; each class is a set of nested environments, the innermost (first in the list) ;; holds the local slots which are copied each time an instance is created, ;; the next holds the class slots (global to all instances, not copied); ;; these hold the class name and other such info. The remaining environments ;; hold the methods, with the localmost method first. So in this loop, we ;; are gathering the local slots and all the methods of the inherited ;; classes, and will splice them together below as a new class. (set! new-slots (append (let->list class) new-slots)) (do ((e (outlet (outlet class)) (outlet e))) ((or (not (let? e)) (eq? e (rootlet)))) (set! new-methods (append (let->list e) new-methods)))) ,inherited-classes) (let ((remove-duplicates (lambda (lst) ; if multiple local slots with same name, take the localmost (letrec ((rem-dup (lambda (lst nlst) (cond ((null? lst) nlst) ((assq (caar lst) nlst) (rem-dup (cdr lst) nlst)) (else (rem-dup (cdr lst) (cons (car lst) nlst))))))) (reverse (rem-dup lst ())))))) (set! new-slots (remove-duplicates (append (map (lambda (slot) (if (pair? slot) (cons (car slot) (cadr slot)) (cons slot #f))) ,slots) ; the incoming new slots, #f is the default value new-slots)))) ; the inherited slots (set! new-methods (append (map (lambda (method) (if (pair? method) (cons (car method) (cadr method)) (cons method #f))) ,methods) ; the incoming new methods ;; add an object->string method for this class. (list (cons 'object->string (lambda* (obj (port #f)) (format port "#<~A: ~{~A~^ ~}>" ',class-name (map (lambda (slot) (list (car slot) (cdr slot))) obj))))) (reverse! new-methods))) ; the inherited methods, shadowed automatically (let ((new-class (openlet (apply sublet ; the local slots (sublet ; the global slots (apply sublet () ; the methods (reverse new-methods)) (cons 'class-name ',class-name) ; class-name slot (cons 'class-type new-type) ; save a unique type identifier (unneeded if class-names are unique) (cons 'inherited ,inherited-classes) (cons 'inheritors ())) ; classes that inherit from this class new-slots)))) (varlet outer-env (cons ',class-name new-class) ; define the class as class-name in the calling environment ;; define class-name? type check (cons (string->symbol (string-append (symbol->string ',class-name) "?")) (lambda (obj) (and (let? obj) (eq? (obj 'class-type) new-type))))) (varlet outer-env ;; define the make-instance function for this class. ;; Each slot is a keyword argument to the make function. (cons (string->symbol (string-append "make-" (symbol->string ',class-name))) (apply lambda* (map (lambda (slot) (if (pair? slot) (list (car slot) (cdr slot)) (list slot #f))) new-slots) `((let ((new-obj (copy ,,class-name))) ,@(map (lambda (slot) `(set! (new-obj ',(car slot)) ,(car slot))) new-slots) new-obj))))) ;; save inheritance info for this class for subsequent define-method (letrec ((add-inheritor (lambda (class) (for-each add-inheritor (class 'inherited)) (if (not (memq new-class (class 'inheritors))) (set! (class 'inheritors) (cons new-class (class 'inheritors))))))) (for-each add-inheritor ,inherited-classes)) ',class-name))) (define-macro (define-generic name) `(define ,name (lambda args (apply ((car args) ',name) args)))) (define-macro (define-slot-accessor name slot) `(define ,name (dilambda (lambda (obj) (obj ',slot)) (lambda (obj val) (set! (obj ',slot) val))))) (define-bacro (define-method name-and-args . body) `(let* ((outer-env (outlet (curlet))) (method-name (car ',name-and-args)) (method-args (cdr ',name-and-args)) (object (caar method-args)) (class (symbol->value (cadar method-args))) (old-method (class method-name)) (method (apply lambda* method-args ',body))) ;; define the method as a normal-looking function ;; s7test.scm has define-method-with-next-method that implements call-next-method here ;; it also has make-instance (varlet outer-env (cons method-name (apply lambda* method-args `(((,object ',method-name) ,@(map (lambda (arg) (if (pair? arg) (car arg) arg)) method-args)))))) ;; add the method to the class (varlet (outlet (outlet class)) (cons method-name method)) ;; if there are inheritors, add it to them as well, but not if they have a shadowing version (for-each (lambda (inheritor) (if (not (eq? (inheritor method-name) #)) ; defined? goes to the global env (if (eq? (inheritor method-name) old-method) (set! (inheritor method-name) method)) (varlet (outlet (outlet inheritor)) (cons method-name method)))) (class 'inheritors)) method-name)) (define (all-methods obj method) ;; for arbitrary method combinations: this returns a list of all the methods of a given name ;; in obj's class and the classes it inherits from (see example below) (let* ((base-method (obj method)) (methods (if (procedure? base-method) (list base-method) ()))) (for-each (lambda (ancestor) (let ((next-method (ancestor method))) (if (and (procedure? next-method) (not (memq next-method methods))) (set! methods (cons next-method methods))))) (obj 'inherited)) (reverse methods))) (define (make-instance class . args) (let* ((cls (if (symbol? class) (symbol->value class) class)) (make (symbol->value (string->symbol (string-append "make-" (symbol->string (cls 'class-name))))))) (apply make args))) (define-bacro (define-method-with-next-method name-and-args . body) `(let* ((outer-env (outlet (curlet))) (method-name (car ',name-and-args)) (method-args (cdr ',name-and-args)) (object (caar method-args)) (class (symbol->value (cadar method-args))) (old-method (class method-name)) (arg-names (map (lambda (arg) (if (pair? arg) (car arg) arg)) method-args)) (next-class (and (pair? (class 'inherited)) (car (class 'inherited)))) ; or perhaps the last member of this list? (nwrap-body (if next-class `((let ((call-next-method (lambda new-args (apply (,next-class ',method-name) (or new-args ,arg-names))))) ,@',body)) ',body)) (method (apply lambda* method-args nwrap-body))) ;; define the method as a normal-looking function (varlet outer-env (cons method-name (apply lambda* method-args `(((,object ',method-name) ,@arg-names))))) ;; add the method to the class (varlet (outlet (outlet class)) (cons method-name method)) ;; if there are inheritors, add it to them as well, but not if they have a shadowing version (for-each (lambda (inheritor) (if (not (eq? (inheritor method-name) #)) ; defined? goes to the global env (if (eq? (inheritor method-name) old-method) (set! (inheritor method-name) method)) (varlet (outlet (outlet inheritor)) (cons method-name method)))) (class 'inheritors)) method-name)) (let () (define-class class-1 () '((a 1) (b 2)) (list (list 'add (lambda (obj) (with-let obj (+ a b)))))) (define-slot-accessor slot-a a) (let () (test (let? (outlet (curlet))) #t) (test (class-1? class-1) #t) (test (class-1 'a) 1) (test (class-1 'b) 2) (test (class-1 'class-name) 'class-1) (test (class-1 'divide) #) (test (class-1 'inheritors) ()) (test ((class-1 'add) class-1) 3) (test (pair? (member (object->string class-1) '("#" "#"))) #t) (test (format #f "~{~A~^ ~}" class-1) "(a . 1) (b . 2)")) (let ((v (make-class-1))) (test (class-1? v) #t) (test (v 'a) 1) (test (v 'b) 2) (test (v 'class-name) 'class-1) (test (v 'inheritors) ()) (test ((v 'add) v) 3) (test (pair? (member (object->string v) '("#" "#"))) #t) (test (format #f "~{~A~^ ~}" v) "(a . 1) (b . 2)") (set! (v 'a) 32) (test ((v 'add) v) 34) (test (equal? v v) #t) (test (equal? v (make-class-1 :a 32)) #t) (test (slot-a v) 32) (set! (slot-a v) 1) (test (slot-a v) 1) (test (pair? (member (map cdr v) '((1 2) (2 1)))) #t)) (let ((v (make-class-1 :a 32)) (v1 (make-class-1)) (v2 (make-class-1 :a 32))) (test (class-1? v) #t) (test (v 'a) 32) (test (v 'b) 2) (test (v 'class-name) 'class-1) (test (v 'inheritors) ()) (test ((v 'add) v) 34) (test (pair? (member (object->string v) '("#" "#"))) #t) (test (eq? v v) #t) (test (eq? v v1) #f) (test (eqv? v v) #t) (test (eqv? v v1) #f) (test (eqv? v v2) #f) (test (equal? v v) #t) (test (equal? v v1) #f) (test (equal? v v2) #t)) (let ((v (make-class-1 32 3))) (test (class-1? v) #t) (test (v 'a) 32) (test (v 'b) 3) (test (v 'class-name) 'class-1) (test (v 'inheritors) ()) (test ((v 'add) v) 35) (test (pair? (member (object->string v) '("#" "#"))) #t)) (define-generic add) (let () (test (add class-1) 3) (test (add (make-class-1 :b 0)) 1) (test (add 2) 'error)) (define-class class-2 (list class-1) '((c 3)) (list (list 'multiply (lambda (obj) (with-let obj (* a b c)))))) (let ((v (make-class-2 :a 32))) (test (class-1? v) #f) (test (class-2? v) #t) (test (equal? v (make-class-1 :a 32)) #f) (test (equal? v (make-class-2 :a 32)) #t) (test (v 'a) 32) (test (v 'b) 2) (test (v 'c) 3) (test (v 'class-name) 'class-2) (test (v 'inheritors) ()) (test (class-1 'inheritors) (list class-2)) (test ((v 'add) v) 34) (test (pair? (member (object->string v) '("#" "#"))) #t) (test ((v 'multiply) v) 192) (test (add v) 34)) (let ((v1 (make-class-1)) (v2 (make-class-1))) (test (add v1) 3) (test (add v2) 3) (varlet v2 (cons 'add (lambda (obj) (with-let obj (+ 1 a (* 2 b)))))) (test (add v1) 3) (test (add v2) 6)) (define-class class-3 (list class-2) () (list (list 'multiply (lambda (obj num) (* num ((class-2 'multiply) obj) (add obj)))))) (let ((v (make-class-3))) (test (class-1? v) #f) (test (class-2? v) #f) (test (class-3? v) #t) (test (v 'a) 1) (test (v 'b) 2) (test (v 'c) 3) (test (v 'class-name) 'class-3) (test (v 'inheritors) ()) (test (class-1 'inheritors) (list class-3 class-2)) (test (class-2 'inheritors) (list class-3)) (test ((v 'add) v) 3) (test (pair? (member (object->string v) '("#" "#"))) #t) (test ((v 'multiply) v) 'error) (test ((v 'multiply) v 4) (* 4 6 3)) (test (add v) 3)) (define-method (subtract (obj class-1)) (with-let obj (- a b))) (let ((v1 (make-class-1)) (v2 (make-class-2)) (v3 (make-class-3))) (test (subtract v1) -1) (test (subtract v2) -1) (test (subtract v3) -1)) ;; class-2|3 have their own multiply so... (define-method (multiply (obj class-1)) (with-let obj (* a b 100))) (let ((v1 (make-class-1)) (v2 (make-class-2)) (v3 (make-class-3))) (test (multiply v1) 200) (test (multiply v2) 6) (test (multiply v3) 'error)) (define-method-with-next-method (add-1 (obj class-1)) (+ (obj 'a) 1)) (define-method-with-next-method (add-1 (obj class-2)) (+ 1 (call-next-method))) (define-method-with-next-method (add-1 (obj class-3)) (+ 1 (call-next-method obj))) (test (add-1 (make-class-1)) 2) (test (add-1 (make-class-2)) 3) (test (add-1 (make-class-3)) 4) (test ((make-instance class-1) 'class-name) 'class-1) (test ((make-instance 'class-1) 'class-name) 'class-1) (test ((make-instance class-2) 'class-name) 'class-2) (test ((make-instance class-1 :a 123) 'class-name) 'class-1) (test ((make-instance class-1) 'b) 2) (test ((make-instance 'class-1) 'b) 2) (test ((make-instance class-1 :b 12 :a 123) 'b) 12) (test ((make-instance 'class-3 :a "hi" :c 21) 'c) 21) ) ;;; -------------------------------------------------------------------------------- ;;; owlet (test (vector? (owlet)) #f) (test (let? (owlet)) #t) (test (let () (set! (owlet) 2)) 'error) (test (owlet 123) 'error) (let ((val (catch #t (lambda () (/ 1 0.0)) (lambda args args)))) (with-let (owlet) (test error-type 'division-by-zero) (test (equal? error-code '(/ 1 0.0)) #t) (test (list? error-data) #t) (test (string? error-file) #t) (test (integer? error-line) #t) (test ((owlet) 'error-file) error-file) )) ;;; stacktrace (test (string? (stacktrace)) #t) ;(test (stacktrace 123) 'error) (let ((str "")) (define testtrace (lambda () (set! str (stacktrace 3)))) (define (hi1 a) (testtrace)) (define (hi2 b) (string-append (hi1 b) "")) (define (hi3 c) (string-append (hi2 c) "")) (define (hi4 d) (string-append (hi3 d) "")) (define (hi5 e) (string-append (hi4 e) "")) (define (hi6 f) (string-append (hi5 f) "")) (hi6 12) (test str "hi2: (string-append (hi1 b) \"\") ; b: 12 hi3: (string-append (hi2 c) \"\") ; c: 12 hi4: (string-append (hi3 d) \"\") ; d: 12 ")) (let ((str "")) (define testtrace (lambda () (set! str (stacktrace 5)))) (define (hi1 a) (testtrace)) (define (hi2 b) (string-append (hi1 b) "")) (define (hi3 c) (string-append (hi2 c) "")) (define (hi4 d) (string-append (hi3 d) "")) (define (hi5 e) (string-append (hi4 e) "")) (define (hi6 f) (string-append (hi5 f) "")) (hi6 12) (test str "hi2: (string-append (hi1 b) \"\") ; b: 12 hi3: (string-append (hi2 c) \"\") ; c: 12 hi4: (string-append (hi3 d) \"\") ; d: 12 hi5: (string-append (hi4 e) \"\") ; e: 12 hi6: (string-append (hi5 f) \"\") ; f: 12 ")) (let ((str "")) (define testtrace (lambda () (set! str (stacktrace 5 20 40 20)))) (define (hi1 a) (testtrace)) (define (hi2 b) (string-append (hi1 b) "")) (define (hi3 c) (string-append (hi2 c) "")) (define (hi4 d) (string-append (hi3 d) "")) (define (hi5 e) (string-append (hi4 e) "")) (define (hi6 f) (string-append (hi5 f) "")) (hi6 12) (test str "hi2: (string-app... ; b: 12 hi3: (string-app... ; c: 12 hi4: (string-app... ; d: 12 hi5: (string-app... ; e: 12 hi6: (string-app... ; f: 12 ")) (let ((str "")) (define testtrace (lambda () (set! str (stacktrace 5 20 40 8)))) (define (hi1 a) (testtrace)) (define (hi2 b) (string-append (hi1 b) "")) (define (hi3 c) (string-append (hi2 c) "")) (define (hi4 d) (string-append (hi3 d) "")) (define (hi5 e) (string-append (hi4 e) "")) (define (hi6 f) (string-append (hi5 f) "")) (hi6 12) (test str "hi2: (string-app... ; b: 12 hi3: (string-app... ; c: 12 hi4: (string-app... ; d: 12 hi5: (string-app... ; e: 12 hi6: (string-app... ; f: 12 ")) (let ((str "")) (define testtrace (lambda () (set! str (stacktrace 5 20 40 8 #t)))) (define (hi1 a) (testtrace)) (define (hi2 b) (string-append (hi1 b) "")) (define (hi3 c) (string-append (hi2 c) "")) (define (hi4 d) (string-append (hi3 d) "")) (define (hi5 e) (string-append (hi4 e) "")) (define (hi6 f) (string-append (hi5 f) "")) (hi6 12) (test str "; hi2: (string-app... ; b: 12 ; hi3: (string-app... ; c: 12 ; hi4: (string-app... ; d: 12 ; hi5: (string-app... ; e: 12 ; hi6: (string-app... ; f: 12 ")) (let ((str "")) (define testtrace (lambda () (set! str (stacktrace 5 40 80 8 #t)))) (define (hi1 a) (testtrace)) (define (hi2 b) (string-append (hi1 b) "")) (define (hi3 c) (string-append (hi2 c) "")) (define (hi4 d) (string-append (hi3 d) "")) (define (hi5 e) (string-append (hi4 e) "")) (define (hi6 f) (string-append (hi5 f) "")) (hi6 12) (test str "; hi2: (string-append (hi1 b) \"\") ; b: 12 ; hi3: (string-append (hi2 c) \"\") ; c: 12 ; hi4: (string-append (hi3 d) \"\") ; d: 12 ; hi5: (string-append (hi4 e) \"\") ; e: 12 ; hi6: (string-append (hi5 f) \"\") ; f: 12 ")) (test (set! (*s7* 'max-stack-size) -1) 'error) (test (set! (*s7* 'max-stack-size) 0) 'error) (test (set! (*s7* 'max-stack-size) 32) 'error) ; this depends on INITIAL_STACK_SIZE (512) (test (set! (*s7* 'max-stack-size) #\a) 'error) (test (set! (*s7* 'max-stack-size) 3/4) 'error) (test (set! (*s7* 'max-stack-size) 123123.123) 'error) (test (integer? (*s7* 'max-stack-size)) #t) ;;; -------------------------------------------------------------------------------- ;;; dilambda (when with-block (test (dilambda-test) #f) (test (set! (dilambda-test) 32) 32) (let () (define (hi) (set! (dilambda-test) 32)) (hi) (test (hi) 32))) (test (let ((local 123)) (define pws-test (dilambda (lambda () local) (lambda (val) (set! local val)))) (pws-test)) 123) (test (let ((local 123)) (define pws-test (dilambda (lambda () local) (lambda (val) (set! local val)))) (pws-test 32)) 'error) (test (let ((local 123)) (define pws-test (dilambda (lambda () local) (lambda (val) (set! local val)))) (set! (pws-test 32) 123)) 'error) (let () (define-constant -dl1- (let ((x 1)) (dilambda (lambda () x) (lambda (y) (set! x y))))) (test (-dl1-) 1) (set! (-dl1-) 3) (test (-dl1-) 3) (define (f1) (set! (-dl1-) 32) (-dl1-)) (test (f1) 32)) (test (call-with-exit (lambda (return) (let ((local 123)) (define pws-test (dilambda (lambda () (return "oops")) (lambda (val) (set! local val)))) (pws-test)))) "oops") (test (call-with-exit (lambda (return) (let ((local 123)) (define pws-test (dilambda (lambda () 123) (lambda (val) (return "oops")))) (set! (pws-test) 1)))) "oops") (test (let ((local 123)) (define pws-test (dilambda (lambda () local) (lambda (val) (set! local val)))) (set! (pws-test) 321) (pws-test)) 321) (test (let ((v (vector 1 2 3))) (define vset (dilambda (lambda (loc) (vector-ref v loc)) (lambda (loc val) (vector-set! v loc val)))) (let ((lst (list vset))) (let ((val (vset 1))) (set! (vset 1) 32) (let ((val1 (vset 1))) (set! ((car lst) 1) 3) (list val val1 (vset 1)))))) (list 2 32 3)) (let ((local 123)) (define pws-test (dilambda (lambda () local) (lambda (val) (set! local val)))) (test (dilambda? pws-test) #t) (test (pws-test) 123) (set! (pws-test) 32) (test (pws-test) 32) (set! (pws-test) 0) (test (pws-test) 0)) (let ((local 123)) (define pws-test (dilambda (lambda (val) (+ local val)) (lambda (val new-val) (set! local new-val) (+ local val)))) (test (pws-test 1) 124) (set! (pws-test 1) 32) (test (pws-test 2) 34) (set! (pws-test 3) 0) (test (pws-test 3) 3)) (let ((ho (dilambda (lambda* ((a 1)) a) (lambda* (a (b 2)) (set! a b) a)))) (test (ho) 1) (test (ho 3) 3) (test (set! (ho) 32) 2) (test (set! (ho 3) 32) 32)) (test (dilambda) 'error) (test (dilambda abs) 'error) (test (dilambda 1 2) 'error) (test (dilambda (lambda () 1) (lambda (a) a) (lambda () 2)) 'error) (test (dilambda (lambda () 1) 2) 'error) (test (call-with-exit (lambda (return) (let ((g (dilambda return (lambda (s v) s)))) (g 0)))) 'error) (test (call-with-exit (lambda (return) (let ((g (dilambda (lambda (s) s) return))) (g 0)))) 0) ; ?? (test (+ (call-with-exit (lambda (return) (let ((g (dilambda (lambda (s) s) return))) (set! (g 1) 2))))) 3) ; ?? (for-each (lambda (arg) (test (dilambda arg (lambda () #f)) 'error) (test (dilambda (lambda () #f) arg) 'error)) (list "hi" -1 #\a 1 'a-symbol #(1 2 3) 3.14 3/4 1.0+1.0i #t (list 1 2 3) '(1 . 2))) (for-each (lambda (arg) (test (dilambda? arg) #f)) (list -1 #\a 1 #(1 2 3) 3.14 3/4 1.0+1.0i () 'hi "hi" #(()) abs (lambda () #f) (list (lambda () #f) (lambda (val) val)) (list 1 2 3) '(1 . 2) # # #)) (let ((pws (dilambda vector-ref vector-set!))) (let ((v (vector 1 2 3))) (test (dilambda? pws) #t) (test (dilambda? pws pws) 'error) (test (pws v 1) 2) (set! (pws v 1) 32) (test (pws v 1) 32))) (test (dilambda?) 'error) (let () (define macfun (dilambda (define-macro (_m_ a) `(+ ,a 1)) (define-macro (_m_ a b) `(- ,a 1)))) (test (macfun (+ 2 3)) 6) (test (set! (macfun (+ 2 3)) 3) 4)) (let () ; reality check... (set! (procedure-setter logbit?) (define-macro (_m_ var index on) `(if ,on (set! ,var (logior ,var (ash 1 ,index))) (set! ,var (logand ,var (lognot (ash 1 ,index))))))) (define (mingle a b) (let ((r 0)) (do ((i 0 (+ i 1))) ((= i 31) r) (set! (logbit? r (* 2 i)) (logbit? a i)) (set! (logbit? r (+ (* 2 i) 1)) (logbit? b i))))) (test (mingle 6 3) 30) (set! (procedure-setter logbit?) #f)) (let () (dilambda logbit? (define-macro (_m_ var index on) `(if ,on (set! ,var (logior ,var (ash 1 ,index))) (set! ,var (logand ,var (lognot (ash 1 ,index))))))) (define (mingle a b) (let ((r 0)) (do ((i 0 (+ i 1))) ((= i 31) r) (set! (logbit? r (* 2 i)) (logbit? a i)) (set! (logbit? r (+ (* 2 i) 1)) (logbit? b i))))) (test (mingle 6 3) 30) (set! (procedure-setter logbit?) #f)) #| (let () (define pws-args (dilambda (lambda args args) (lambda args (set-car! args 0) args))) (let ((lst (list 1 2 3))) (let ((l1 (apply pws-args lst))) (test l1 '(1 2 3)) (set-car! l1 32) (test lst '(1 2 3)) (set! (pws-args l1) 3) (test l1 '(32 2 3)) (test lst '(1 2 3)) (let () (define (pws1) (pws-args lst)) (let ((l2 (pws1))) (set! l2 (pws1)) (test lst '(1 2 3))))))) |# (test (call-with-exit (lambda (return) (dilambda? return))) #f) (test (dilambda? quasiquote) #f) (test (dilambda? -s7-symbol-table-locked?) #t) ;; (test (dilambda? '-s7-symbol-table-locked?) #f) ; this parallels (procedure? 'abs) -> #f but seems inconsistent with other *? funcs (test (let ((pws (dilambda (lambda args (apply + args)) (lambda args (apply * args))))) (pws 2 3 4)) 9) (test (let ((pws (dilambda (lambda args (apply + args)) (lambda args (apply * args))))) (set! (pws 2 3 4) 5)) 120) (let ((x 0)) (let ((pws (dilambda (let ((y 1)) ((lambda () (set! x (+ x y)) (lambda () x)))) (let ((y 2)) ((lambda () (set! x (* x y)) (lambda (z) (set! x (+ x z))))))))) (test x 2) (set! (pws) 3) (test x 5))) (let ((p1 (dilambda (lambda () 1) (lambda (a) a)))) (let ((p2 (dilambda p1 p1))) (test (p2) 1))) (test ((dilambda call-with-exit call/cc) (lambda (a) (a 1))) 1) (test (length (dilambda < >)) #f) (let ((p1 (dilambda (lambda (a) (+ a 1)) (lambda (a b) (+ a b))))) (let ((p2 (dilambda p1 p1))) (test (p2 1) 2))) (let () (define sf1 (let ((val 0)) (dilambda (let ((signature '(integer?)) (documentation "getter help")) (lambda () val)) (let ((signature '(integer? integer?)) (documentation "setter help")) (lambda (new-val) (if (integer? new-val) (set! val new-val) (error 'wrong-type-arg ";sf1 new value should be an integer: ~A" new-val))))))) (test (procedure-documentation sf1) "getter help") (test (procedure-documentation (procedure-setter sf1)) "setter help") (test (procedure-signature sf1) '(integer?)) (test (procedure-signature (procedure-setter sf1)) '(integer? integer?))) ;;; -------------------------------------------------------------------------------- ;;; copy (test (copy 3) 3) (test (copy 3/4) 3/4) (test (copy "hi") "hi") (test (copy 'hi) 'hi) (test (copy (list 1 2 3)) (list 1 2 3)) (test (copy (vector 0.0)) (vector 0.0)) (test (copy #\f) #\f) (test (copy (list 1 (list 2 3))) (list 1 (list 2 3))) (test (copy (cons 1 2)) (cons 1 2)) (test (let ((x (list 1 2 3))) (eq? (copy x) x)) #f) (test (let ((x (list 1 2 3))) (equal? (copy x) x)) #t) (test (let ((x #(1 2 3))) (eq? (copy x) x)) #f) (test (let ((x #(1 2 3))) (equal? (copy x) x)) #t) (test (let ((x "hi")) (eq? (copy x) x)) #f) (test (let ((x "hi")) (equal? (copy x) x)) #t) (test (copy '(1 2 . 3)) '(1 2 . 3)) (test (copy (+)) 0) (test (copy +) +) (test (copy (#(#() #()) 1)) #()) (test (copy #f) #f) (test (copy ()) ()) (test (copy #()) #()) (test (copy #2d((1 2) (3 4))) #2d((1 2) (3 4))) (test (let ((f (lambda () 1))) ((copy f))) 1) (test (let ((f (lambda () 1))) (eq? (copy f) f)) #f) (test (let ((f (lambda* ((a 2)) (+ a 1)))) ((copy f))) 3) (test (let ((f (lambda* ((a 2)) (+ a 1)))) (eq? (copy f) f)) #f) (test (copy 1.0) 1.0) (test (copy 1.0+i) 1.0+i) (test (copy "") "") (test (copy #t) #t) (test (copy (string #\a #\null #\b)) "a\x00b") (test (copy #) #) (test ((copy abs) -123) 123) (test (copy ''1) ''1) (test (copy '''1) '''1) (test (copy not) not) (test (copy "a\x00b") "a\x00b") (test (infinite? (copy (log 0.0))) #t) (test (nan? (copy 1/0)) #t) (test (copy if) if) (test (copy quote) quote) (test (let ((a 1) (b 2)) (equal? (copy (curlet)) (curlet))) #t) (test (copy (rootlet)) (rootlet)) (test (copy (funclet abs)) (rootlet)) (test (copy (funclet quasiquote)) (rootlet)) (test (eval '(+ a 1) (copy (sublet (curlet) '(a . 2)))) 3) (test (copy (list 1 2 (list 3 4))) '(1 2 (3 4))) (test (copy (cons 1 2)) '(1 . 2)) (test (copy '(1 2 (3 4) . 5)) '(1 2 (3 4) . 5)) (test (copy ()) ()) (test (copy) 'error) (test (copy () () ()) 'error) (test (copy (make-hash-table) pi) 'error) (test (copy 1 3) 'error) (test (copy #() abs) 'error) ;;; 2 arg version of copy (test (copy (list 1 2) (vector 0 0)) #(1 2)) (test (copy (list 1 2) (vector 0)) #(1)) (test (copy (list 1 2) (vector)) #()) (test (copy (list) (vector)) #()) (test (copy (list 1 2) (vector 0 0 3 4)) #(1 2 3 4)) ; should (copy 1 2) be an error? (test (copy #2d((1 2) (3 4)) (vector 0 0 0 0 0)) #(1 2 3 4 0)) (test (copy (vector 0 0 0 0 0) #2d((1 2) (3 4))) #2d((0 0) (0 0))) (test (copy (vector 1 2 3 4 5) #2d((0 0) (0 0))) #2d((1 2) (3 4))) (test (copy "12345" (make-list 5)) '(#\1 #\2 #\3 #\4 #\5)) (test (copy (list #\0 #\1 #\2) (make-string 3)) "012") (test (copy '(0 1 2 3) (list 4 3 2 1)) '(0 1 2 3)) (test (copy #(0 1 2 3) (vector 4 3 2 1)) #(0 1 2 3)) (test (copy "12345" (make-string 5)) "12345") (test (copy '(4 3 2 1) '(1 . 2)) '(4 . 2)) (test (copy (string (integer->char 255)) (vector 0)) #(#\xff)) (test (copy (vector (integer->char 255)) (string #\a)) (string (integer->char 255))) (test (copy #() "") "") (test (copy "" #()) #()) (test (copy #() (vector 1 2 3)) #(1 2 3)) (test (copy (make-vector 3 0.0 #t)) (make-vector 3 0.0 #t)) (test (copy (make-vector 3 0 #t)) (make-vector 3 0 #t)) (test (copy (make-vector '(2 3) 0 #t)) (make-vector '(2 3) 0 #t)) (test (eq? (copy 1) 1) #f) (test (eq? (copy 1.0) 1.0) #f) (test (eq? (copy 2/3) 2/3) #f) (test (eq? (copy "") "") #f) (test (copy #u8(101 102) (vector 1 2)) #(101 102)) (when with-block (let ((b (copy (block 1 2 3 4)))) (test b (block 1 2 3 4)) (fill! b 0 1 3) (test b (block 1 0 0 4)) (let ((b1 (block 1 1 1 1 1))) (copy b b1) (test b1 (block 1 0 0 4 1))) (let ((b2 (block 1 2 3))) (let ((b3 (copy b b2))) (test (eq? b2 b3) #t) (test b3 (block 1 0 0)))) (let ((b4 (block 5 6 7 8))) (copy b4 b 1) (test b (block 6 7 8 4))))) (let ((lst (list 1 2 3))) (set! (cdr (cddr lst)) lst) (test (copy lst lst) lst) (test (copy lst (make-list 15 5)) '(1 2 3 5 5 5 5 5 5 5 5 5 5 5 5))) ; was going around twice (let ((v (vector 1 2 3))) (test (copy v v) v) (test (copy v v 1 3) #(2 3 3))) (test (copy #(1 2 3 4 5 6) (make-list 3) 0 3) '(1 2 3)) (test (copy #(1 2 3 4 5 6) (make-list 3) 0) '(1 2 3)) (test (copy #(1 2 3 4 5 6) (make-list 3) 1) '(2 3 4)) (test (copy #(1 2 3 4 5 6) (make-list 3 0) 5) '(6 0 0)) (test (copy #(1 2 3 4 5 6) (make-list 3)) '(1 2 3)) (test (copy #(1 2 3 4 5 6) (make-list 3) 1 4) '(2 3 4)) (test (copy #(1 2 3 4 5 6) (make-list 3 #f) 1 2) '(2 #f #f)) (test (copy #(1 2 3 4 5 6) (make-list 3 #f) 1 1) '(#f #f #f)) (test (copy #(1 2 3 4 5 6) (make-list 3 #f) -1 1) 'error) (test (copy #(1 2 3 4 5 6) (make-list 3 #f) 1 7) 'error) (test (copy #(1 2 3 4 5 6) (make-list 3 #f) 1 0) 'error) (test (copy #(1 2 3 4 5 6) () 1 2) ()) (test (copy #(1 2 3 4 5 6) ()) ()) (test (copy #(1 2 3 4 5 6) (make-list 6 #f) 2) '(3 4 5 6 #f #f)) (test (copy #(1 2 3 4 5 6) '(0 0 0 . 3)) '(1 2 3 . 3)) (let ((lst (list 7 8 9))) (set! (cdr (cddr lst)) lst) (copy #(1 2 3 4 5 6) lst 0 1) (test (car lst) 1) (copy #(1 2 3 4 5 6) lst 1 5) (test (car lst) 2)) (test (copy #(#\a #\b #\c) (make-string 2) 1) "bc") (test (copy '(#\a #\b #\c) (make-string 2) 1) "bc") (test (copy "abc" (make-string 2) 1) "bc") (test (copy "abc" (make-vector 2) 1) #(#\b #\c)) (test (copy "abc" (make-list 2) 1) '(#\b #\c)) (test (copy '(1 2 3) (make-list 2) 1) '(2 3)) (test (copy '(1 2 3) (make-vector 2) 1) #(2 3)) (test (copy #(1 2 3) (make-vector 2) 1) #(2 3)) (test (copy #(1 2 3) (make-list 2) 1) '(2 3)) (test (copy (make-vector 3 0 #t)) (make-vector 3 0 #t)) (let ((orig "0123456789")) (let ((iv (copy (->byte-vector orig) (make-int-vector 10)))) (test (copy iv (make-string 10)) orig))) (test (copy "0123456789" (make-float-vector 10)) (float-vector 48 49 50 51 52 53 54 55 56 57)) (test (let ((e (inlet 'a 1 'b 2 'c 3)) (f (inlet 'd 4))) (copy e f)) (inlet 'd 4 'c 3 'b 2 'a 1)) (test (let ((e (inlet 'a 1 'b 2 'c 3)) (f (inlet 'd 4))) (copy e f 0)) (inlet 'd 4 'c 3 'b 2 'a 1)) (test (let ((e (inlet 'a 1 'b 2 'c 3)) (f (inlet 'd 4))) (copy e f 1)) (inlet 'd 4 'b 2 'a 1)) (test (let ((e (inlet 'a 1 'b 2 'c 3)) (f (inlet 'd 4))) (copy e f 1 2)) (inlet 'd 4 'b 2)) (test (let ((e (inlet 'a 1 'b 2 'c 3)) (f (inlet 'd 4))) (copy f e)) (inlet 'a 1 'b 2 'c 3 'd 4)) ;; printout is confusing (is this a reversal in this slot list, or a let-id side-effect?) (test (let ((e (inlet 'a 1 'b 2 'c 3)) (f (inlet 'a 100 'b 200 'c 300 'd 400))) ((copy e f) 'a)) 1) (test (let ((e (inlet 'a 1 'b 2 'c 3)) (f (inlet 'a 100 'b 200 'c 300 'd 400))) (copy e f)) (inlet 'a 100 'b 200 'c 300 'd 400 'c 3 'b 2 'a 1)) (let ((e1 (inlet 'a 1 'b 2)) (e2 (inlet 'a 3 'c 3)) (v1 (vector 1 2)) (v2 (vector 3 4)) (i1 (int-vector 5 6)) (i2 (int-vector 7 8)) (h1 (hash-table* 'd 4 'e 5)) (h2 (hash-table* 'f 6 'e 7)) (f1 (float-vector 9 10)) (f2 (float-vector 11 12)) (p1 (list 13 14)) (p2 (list 15 16)) (b1 (if with-block (block 17 18) (vector 17 18))) (b2 (if with-block (block 19 20) (vector 19 20))) (s1 (make-string 2 #\a)) (s2 (make-string 2 #\b))) (test (copy e1 e2) (inlet 'a 3 'c 3 'b 2 'a 1)) (test (copy e1 v2) #((b . 2) (a . 1))) (test (copy e1 i2) 'error) (test (copy e1 f2) 'error) (test (copy e1 h2) (hash-table '(a . 1) '(b . 2) '(e . 7) '(f . 6))) (test (copy e1 p2) '((b . 2) (a . 1))) (test (copy e1 b2) 'error) (test (copy e1 s2) 'error) (test (copy v1 e2) 'error) (test (copy v1 v2) #(1 2)) (test (copy v1 i2) (int-vector 1 2)) (test (copy v1 f2) (float-vector 1.0 2.0)) (test (copy v1 h2) 'error) (test (copy v1 p2) '(1 2)) (test (copy v1 b2) (block 1.000 2.000)) (test (copy v1 s2) 'error) (test (copy i1 e2) 'error) (test (copy i1 v2) #(5 6)) (test (copy i1 i2) (int-vector 5 6)) (test (copy i1 f2) (float-vector 5.0 6.0)) (test (copy i1 h2) 'error) (test (copy i1 p2) '(5 6)) (test (copy i1 b2) (block 5.000 6.000)) (test (copy i1 s2) "\x05\x06") (test (copy f1 e2) 'error) (test (copy f1 v2) #(9.0 10.0)) (test (copy f1 i2) (int-vector 9 10)) (test (copy f1 f2) (float-vector 9.0 10.0)) (test (copy f1 h2) 'error) (test (copy f1 p2) '(9.0 10.0)) (test (copy f1 b2) (block 9.000 10.000)) (test (copy f1 s2) 'error) (test (copy h1 e2) (inlet 'a 3 'c 3 'b 2 'a 1 'd 4 'e 5)) (test (let ((h (copy h1 v2))) (or (equal? h #((d . 4) (e . 5))) (equal? h #((e . 5) (d . 4))))) #t) (test (copy h1 i2) 'error) (test (copy h1 f2) 'error) (test (copy h1 h2) (hash-table '(a . 1) '(b . 2) '(d . 4) '(e . 5) '(f . 6))) (test (let ((p (copy h1 p2))) (or (equal? p '((d . 4) (e . 5))) (equal? p '((e . 5) (d . 4))))) #t) (test (copy h1 b2) 'error) (test (copy h1 s2) 'error) (test (copy p1 e2) 'error) (test (copy p1 v2) #(13 14)) (test (copy p1 i2) (int-vector 13 14)) (test (copy p1 f2) (float-vector 13.0 14.0)) (test (copy p1 h2) 'error) (test (copy p1 p2) '(13 14)) (test (copy p1 b2) (block 13.000 14.000)) (test (copy p1 s2) 'error) (test (copy b1 e2) 'error) (test (copy b1 v2) #(17.0 18.0)) (test (copy b1 i2) (int-vector 17 18)) (test (copy b1 f2) (float-vector 17.0 18.0)) (test (copy b1 h2) 'error) (test (copy b1 p2) '(17.0 18.0)) (test (copy b1 b2) (block 17.000 18.000)) (test (copy b1 s2) 'error) (test (copy s1 e2) 'error) (test (copy s1 v2) #(#\a #\a)) (test (copy s1 i2) (int-vector 97 97)) (test (copy s1 f2) (float-vector 97.0 97.0)) (test (copy s1 h2) 'error) (test (copy s1 p2) '(#\a #\a)) (test (copy s1 b2) 'error) (test (copy s1 s2) "aa")) (let ((e1 (inlet 'a 1 'b 2)) (e2 (inlet 'a 3 'c 3)) (v1 (vector 1 2)) (v2 (vector 3 4)) (i1 (int-vector 5 6)) (i2 (int-vector 7 8)) (h1 (hash-table* 'd 4 'e 5)) (h2 (hash-table* 'f 6 'e 7)) (f1 (float-vector 9 10)) (f2 (float-vector 11 12)) (p1 (list 13 14)) (p2 (list 15 16)) (b1 (if with-block (block 17 18) (vector 17 18))) (b2 (if with-block (block 19 20) (vector 19 20))) (s1 (make-string 2 #\a)) (s2 (make-string 2 #\b))) (test (copy e1 e2 1) (inlet 'a 3 'c 3 'a 1)) (test (copy e1 v2 1) #((a . 1) 4)) (test (copy e1 i2 1) 'error) (test (copy e1 f2 1) 'error) (test (copy e1 h2 1) (hash-table '(a . 1) '(e . 7) '(f . 6))) (test (copy e1 p2 1) '((a . 1) 16)) (test (copy e1 b2 1) 'error) (test (copy e1 s2 1) 'error) (test (copy v1 e2 1) 'error) (test (copy v1 v2 1) #(2 4)) (test (copy v1 i2 1) (int-vector 2 8)) (test (copy v1 f2 1) (float-vector 2.0 12.0)) (test (copy v1 h2 1) 'error) (test (copy v1 p2 1) '(2 16)) (test (copy v1 b2 1) (block 2.000 20.000)) (test (copy v1 s2 1) 'error) (test (copy i1 e2 1) 'error) (test (copy i1 v2 1) #(6 4)) (test (copy i1 i2 1) (int-vector 6 8)) (test (copy i1 f2 1) (float-vector 6.0 12.0)) (test (copy i1 h2 1) 'error) (test (copy i1 p2 1) '(6 16)) (test (copy i1 b2 1) (block 6.000 20.000)) (test (copy i1 s2 1) "\x06b") (test (copy f1 e2 1) 'error) (test (copy f1 v2 1) #(10.0 4)) (test (copy f1 i2 1) (int-vector 10 8)) (test (copy f1 f2 1) (float-vector 10.0 12.0)) (test (copy f1 h2 1) 'error) (test (copy f1 p2 1) '(10.0 16)) (test (copy f1 b2 1) (block 10.000 20.000)) (test (copy f1 s2 1) 'error) (test (let ((e (copy h1 e2 1))) (or (equal? e (inlet 'a 3 'c 3 'a 1 'e 5)) (equal? e (inlet 'a 3 'c 3 'a 1 'd 4)))) #t) (test (let ((v (copy h1 v2 1))) (or (equal? v #((e . 5) 4)) (equal? v #((d . 4) 4)))) #t) (test (copy h1 i2 1) 'error) (test (copy h1 f2 1) 'error) (test (let ((h (copy h1 h2 1))) (or (equal? h (hash-table '(a . 1) '(e . 5) '(f . 6))) (equal? h (hash-table '(e . 7) '(a . 1) '(f . 6) '(d . 4))))) ; ?? #t) (test (let ((p (copy h1 p2 1))) (or (equal? p '((e . 5) 16)) (equal? p '((d . 4) 16)))) #t) (test (copy h1 b2 1) 'error) (test (copy h1 s2 1) 'error) (test (copy p1 e2 1) 'error) (test (copy p1 v2 1) #(14 4)) (test (copy p1 i2 1) (int-vector 14 8)) (test (copy p1 f2 1) (float-vector 14.0 12.0)) (test (copy p1 h2 1) 'error) (test (copy p1 p2 1) '(14 16)) (test (copy p1 b2 1) (block 14.000 20.000)) (test (copy p1 s2 1) 'error) (test (copy b1 e2 1) 'error) (test (copy b1 v2 1) #(18.0 4)) (test (copy b1 i2 1) (int-vector 18 8)) (test (copy b1 f2 1) (float-vector 18.0 12.0)) (test (copy b1 h2 1) 'error) (test (copy b1 p2 1) '(18.0 16)) (test (copy b1 b2 1) (block 18.000 20.000)) (test (copy b1 s2 1) 'error) (test (copy s1 e2 1) 'error) (test (copy s1 v2 1) #(#\a 4)) (test (copy s1 i2 1) (int-vector 97 8)) (test (copy s1 f2 1) (float-vector 97.0 12.0)) (test (copy s1 h2 1) 'error) (test (copy s1 p2 1) '(#\a 16)) (test (copy s1 b2 1) 'error) (test (copy s1 s2 1) "ab")) #| (let ((e1 (inlet 'a 1 'b 2)) (e2 (inlet 'a 3 'c 3)) (v1 (vector 1 2)) (v2 (vector 3 4)) (i1 (int-vector 5 6)) (i2 (int-vector 7 8)) (h1 (hash-table* 'd 4 'e 5)) (h2 (hash-table* 'f 6 'e 7)) (f1 (float-vector 9 10)) (f2 (float-vector 11 12)) (p1 (list 13 14)) (p2 (list 15 16)) (b1 (if with-block (block 17 18) (vector 17 18))) (b2 (if with-block (block 19 20) (vector 19 20))) (s1 (make-string 2 #\a)) (s2 (make-string 2 #\b))) (for-each (lambda (o1 o1name) (for-each (lambda (o2 o2name) (let ((val (catch #t (lambda () (copy o1 o2)) (lambda any 'error)))) (format *stderr* "(test (copy ~S ~S) '~S)~%" o1name o2name val))) (list e2 v2 i2 f2 h2 p2 b2 s2) (list 'e2 'v2 'i2 'f2 'h2 'p2 'b2 's2))) (list e1 v1 i1 f1 h1 p1 b1 s1) (list 'e1 'v1 'i1 'f1 'h1 'p1 'b1 's1))) |# (let () (define* (copy-1 s d start end) (let ((dend (length d)) (send (or end (length s)))) (if (not end) (set! end (length s))) (do ((i (or start 0) (+ i 1)) (j 0 (+ j 1))) ((or (= i end) (= j dend)) d) (set! (d j) (s i))))) (for-each (lambda (s1 s2) (for-each (lambda (start) (for-each (lambda (end) (for-each (lambda (d1 d2) (catch #t (lambda () (if end (copy s1 d1 (or start 0) end) (if start (copy s1 d1 start) (copy s1 d1))) (copy-1 s2 d2 start end) (if (not (equal? d1 d2)) (format *stderr* "(copy ~A ~A ~A) -> ~A ~A?~%" s1 start end d1 d2))) (lambda args 'error))) (list (vector 0 0 0) (make-vector 2 1 #t) (make-vector 2 0.0 #t) (string #\a #\b #\c #\d #\e) (string) (list) (vector) (if with-block (block 1.0 1.0) (float-vector 1.0 1.0)) (cons 1 2)) (list (vector 0 0 0) (make-vector 2 1 #t) (make-vector 2 0.0 #t) (string #\a #\b #\c #\d #\e) (string) (list) (vector) (if with-block (block 1.0 1.0) (float-vector 1.0 1.0)) (cons 1 2)))) (list #f 0 1 3))) (list #f 0 1 2))) (list (vector 1 2 3 4) (let ((v (make-vector 3 0 #t))) (set! (v 0) 32) (set! (v 1) 16) (set! (v 2) 8) v) (list 1 2 3 4 5) (string #\a #\b) (string) (list) (vector) (cons 1 (cons 2 3)) (if with-block (block 1.0 2.0 3.0 4.0) (float-vector 1.0 2.0 3.0 4.0))) (list (vector 1 2 3 4) (let ((v (make-vector 3 0 #t))) (set! (v 0) 32) (set! (v 1) 16) (set! (v 2) 8) v) (list 1 2 3 4 5) (string #\a #\b) (string) (list) (vector) (cons 1 (cons 2 3)) (if with-block (block 1.0 2.0 3.0 4.0) (float-vector 1.0 2.0 3.0 4.0))))) (test (copy -1 6) 'error) (for-each (lambda (arg) (test (copy arg #(1 2 3)) 'error) (test (copy #(1 2 3) arg) 'error)) (list -1 #\a 3.14 3/4 1.0+1.0i 'hi abs (lambda () #f) # # #)) (let ((ht (hash-table (cons 'a 1)))) (test (copy ht (make-vector 3 #f)) #((a . 1) #f #f)) (let ((e (inlet))) (copy ht e) (test (eval '(+ a 2) e) 3) (test (copy e #(1 2 3)) #((a . 1) 2 3)) (copy (list (cons 'b 2)) ht) (test (ht 'b) 2))) (let ((ht1 (hash-table* 'a 1)) (ht2 (hash-table* 123 2))) (copy ht2 ht1) (test (ht1 123) 2) (copy ht1 ht2) (test (ht2 'a) 1) (test (hash-table-entries ht2) 2) (test (let ((str (object->string ht2))) (or (string=? str "(hash-table '(a . 1) '(123 . 2))") (string=? str "(hash-table '(123 . 2) '(a . 1))"))) #t) (test (equal? ht1 ht2) #t)) (let ((ht1 (hash-table* 'a 1)) (ht2 (make-hash-table))) (copy ht1 ht2) (test (= (hash-table-entries ht1) (hash-table-entries ht2)) #t) (test (equal? ht1 ht2) #t)) (let ((ht1 (hash-table* 'a 1 'b 2 'c 3)) (ht2 (make-hash-table))) (copy ht1 ht2) (test (= (hash-table-entries ht1) (hash-table-entries ht2)) #t) (test (equal? ht1 ht2) #t)) (let ((ht1 (hash-table* 'a 1 'b 2 'c 3)) (ht2 (make-hash-table))) (copy ht1 ht2 0 3) (test (= (hash-table-entries ht1) (hash-table-entries ht2)) #t) (test (equal? ht1 ht2) #t)) (let ((ht1 (hash-table* 'a 1 'b 2 'c 3)) (ht2 (make-hash-table))) (copy ht1 ht2 1) ; either can be skipped here (test (= (hash-table-entries ht1) (+ (hash-table-entries ht2) 1)) #t) (test (equal? ht1 ht2) #f) (test (ht1 'a) 1) (test (ht1 'c) 3)) (let ((ht1 (hash-table* 'a 1 'b 2 'c 3)) (ht2 (make-hash-table))) (copy ht1 ht2 1 2) (test (= (hash-table-entries ht1) (+ (hash-table-entries ht2) 2)) #t) (test (equal? ht1 ht2) #f) (test (ht1 'a) 1) (test (ht1 'c) 3)) (let ((ht1 (hash-table* 'a 1)) (ht2 (hash-table* "a" 2))) (copy ht1 ht2) (test (= (hash-table-entries ht1) (hash-table-entries ht2)) #f) (test (equal? ht1 ht2) #f) (test (ht2 "a") 2) (test (ht2 'a) 1) (test (hash-table-entries ht2) 2)) (let ((ht1 (hash-table* 'a 1 "a" 3)) (ht2 (hash-table* "a" 2))) (copy ht1 ht2) (test (= (hash-table-entries ht1) (hash-table-entries ht2)) #t) (test (equal? ht1 ht2) #t) (test (ht2 "a") 3) (test (ht2 'a) 1) (test (hash-table-entries ht2) 2)) (if with-bignums (begin (test (let ((x (bignum "1"))) (eq? x (copy x))) #f) (test (let ((x (bignum "1/2"))) (eq? x (copy x))) #f) (test (let ((x (bignum "1.0"))) (eq? x (copy x))) #f) (test (let ((x (bignum "1+i"))) (eq? x (copy x))) #f))) (test (let ((x 1)) (eq? x (copy x))) #f) (test (= 1 (copy 1)) #t) (test (= 1.5 (copy 1.5)) #t) (test (= 1/2 (copy 1/2)) #t) (test (= 1+i (copy 1+i)) #t) (test (let ((x "str")) (eq? x (copy x))) #f) (if (not (provided? 'gmp)) (let ((r1 (random-state 1234))) (random 1.0 r1) (let ((r2 (copy r1))) (let ((v1 (random 1.0 r1)) (v2 (random 1.0 r2))) (test (= v1 v2) #t) (let ((v3 (random 1.0 r1))) (random 1.0 r1) (random 1.0 r1) (let ((v4 (random 1.0 r2))) (test (= v3 v4) #t))))))) (if (provided? 'gmp) (let ((i (copy (bignum "1"))) (r (copy (bignum "3/4"))) (f (copy (bignum "1.5"))) (c (copy (bignum "1.0+1.0i")))) (test (= i (bignum "1")) #t) (test (= r (bignum "3/4")) #t) (test (= f (bignum "1.5")) #t) (test (= c (bignum "1.0+1.0i")) #t))) (let () (define (f1 a) (+ a 1)) (define f2 (copy f1)) (test (f1 1) (f2 1)) (define* (f3 (a 2)) (* a 2)) (define f4 (copy f3)) (test (f3 3) (f4 3)) (test (f3) (f4)) (define-macro (f5 a) `(+ ,a 1)) (define f6 (copy f5)) (test (f5 2) (f6 2))) (let () (define (engulph form) (let ((body `(let ((L ())) (do ((i 0 (+ i 1))) ((= i 10) (reverse L)) (set! L (cons ,form L)))))) (define function (apply lambda () (list (copy body :readable)))) ; an optimizable no-macro macro? (function))) (test (engulph '(+ i 1)) '(1 2 3 4 5 6 7 8 9 10))) ;;; -------- (let ((c1 #f)) (call/cc (lambda (c) (test (reverse c) 'error) (test (fill! c) 'error) (test (length c) #f) (test (eq? c c) #t) ; is this the norm? (test (equal? c c) #t) (test (equal? c (copy c)) #t) (set! c1 c))) (test (continuation? c1) #t)) (let ((c1 #f)) (call-with-exit (lambda (c) (test (reverse c) 'error) (test (fill! c) 'error) (test (length c) #f) (test (eq? c c) #t) (test (equal? c c) #t) (test (equal? c (copy c)) #t) (set! c1 c))) (test (procedure? c1) #t)) ;;; length (test (length (list 1 2)) 2) (test (length "hiho") 4) (test (length (vector 1 2)) 2) (test (>= (length (make-hash-table 7)) 7) #t) (test (length ()) 0) (test (length (#(#() #()) 1)) 0) (test (length abs) #f) (when with-block (test (length (block 1.0 2.0 3.0)) 3)) (test (length (make-iterator "123")) 3) ; this is not completely correct in all cases ;;; -------------------------------------------------------------------------------- ;;; fill! (let ((str (string #\1 #\2 #\3))) (fill! str #\x) (test str "xxx")) (let ((v (vector 1 2 3))) (fill! v 0.0) (test v (vector 0.0 0.0 0.0))) (let ((lst (list 1 2 (list (list 3) 4)))) (fill! lst 100) (test lst '(100 100 100))) (let ((cn (cons 1 2))) (fill! cn 100) (test cn (cons 100 100))) (test (fill! 1 0) 'error) (test (fill! 'hi 0) 'error) (test (let ((x (cons 1 2))) (fill! x 3) x) '(3 . 3)) (test (let ((x "")) (fill! x #\c) x) "") (test (let ((x ())) (fill! x #\c) x) ()) (test (let ((x #())) (fill! x #\c) x) #()) (test (let ((x #(0 1))) (fill! x -1) (set! (x 0) -2) x) #(-2 -1)) (test (let ((x #(0 0))) (fill! x #(1)) (object->string x)) "#(#(1) #(1))") ; was "#(#1=#(1) #1#)" (test (let ((lst (list "hi" "hi" "hi"))) (fill! lst "hi") (equal? lst '("hi" "hi" "hi"))) #t) (test (let ((lst (list "hi" "hi"))) (fill! lst "hi") (equal? lst '("hi" "hi"))) #t) (test (let ((lst (list 1 2 3 4))) (fill! lst "hi") (equal? lst '("hi" "hi" "hi" "hi"))) #t) (test (let ((lst (list 1 2 3))) (fill! lst lst) (object->string lst)) "#1=(#1# #1# #1#)") (test (let ((lst (vector 1 2 3))) (fill! lst lst) (object->string lst)) "#1=#(#1# #1# #1#)") (test (let ((lst #2d((1) (1)))) (fill! lst lst) (object->string lst)) "#1=#2D((#1#) (#1#))") (test (let ((lst '(1 2 3))) (fill! lst (cons 1 2)) (set! (car (car lst)) 3) (caadr lst)) 3) (test (let ((lst (list))) (fill! lst 0) lst) ()) (test (let ((lst (list 1))) (fill! lst 0) lst) '(0)) (test (let ((lst (list 1 2))) (fill! lst 0) lst) '(0 0)) (test (let ((lst (list 1 (list 2 3)))) (fill! lst 0) lst) '(0 0)) (test (let ((lst (cons 1 2))) (fill! lst 0) lst) '(0 . 0)) (test (let ((lst (cons 1 (cons 2 3)))) (fill! lst 0) lst) '(0 0 . 0)) (let ((lst (make-list 3))) (fill! lst lst) (test lst (lst 0)) (set! (lst 1) 32) (test ((lst 0) 1) 32)) (when with-block (let ((b (make-block 4))) (fill! b 32.0) (test b (block 32.0 32.0 32.0 32.0)))) (test (fill!) 'error) (test (fill! '"hi") 'error) (test (fill! (begin) if) if) (test (fill! (rootlet) 3) 'error) (test (fill! (curlet) 3) 'error) (test (fill! "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" #f) 'error) (let ((v (make-vector 3 0 #t))) (fill! v 32) (test v (make-vector 3 32 #t))) (for-each (lambda (arg) (test (fill! arg 1) 'error)) (list (integer->char 65) #f 'a-symbol abs quasiquote macroexpand 1/0 (log 0) # # # (lambda (a) (+ a 1)) 3.14 3/4 1.0+1.0i #\f #t :hi (if #f #f) (lambda (a) (+ a 1)))) (for-each (lambda (arg) (let ((str (string #\a #\b))) (test (fill! str arg) 'error))) (list "hi" '(1 2 3) #() #f 'a-symbol abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #t :hi (if #f #f) (lambda (a) (+ a 1)))) (let ((ht (hash-table* :a 1))) (for-each (lambda (arg) (test (fill! ht arg) arg) (test (ht :a) arg)) (list "hi" '(1 2 3) #() 'a-symbol abs _ht_ _null_ _c_obj_ quasiquote macroexpand (log 0) 3.14 3/4 1.0+1.0i #t :hi (if #f #f) (lambda (a) (+ a 1)) #f))) (let ((str (make-string 10 #\a))) (fill! str #\b 0 2) (test str "bbaaaaaaaa") (fill! str #\c 8) (test str "bbaaaaaacc") (test (fill! str #\d -1) 'error) (test (fill! str #\d 1 0) 'error) (fill! str #\d 4 4) (test str "bbaaaaaacc")) (let ((v (vector 1 2 3 4))) (fill! v 5 2 3) (test v #(1 2 5 4)) (fill! v 6 2) (test v #(1 2 6 6))) (let ((v (float-vector 1.0 2.0 3.0))) (test (fill! v 0.0 0 4) 'error) (test (fill! v 0.0 4 4) 'error) (fill! v 0.0 1) (test v (float-vector 1.0 0.0 0.0))) (let ((v (int-vector 1 2 3))) (test (fill! v 0 0 4) 'error) (test (fill! v 0 4 4) 'error) (fill! v 0 1) (test v (int-vector 1 0 0))) (let ((p (list 0 1 2 3 4))) (fill! p 5 3) (test p (list 0 1 2 5 5)) (fill! p 6 0 3) (test p (list 6 6 6 5 5))) (let ((p (cons 1 2))) (fill! p 3 0) (test p (cons 3 3)) (set! p (cons 0 (cons 1 2))) (fill! p 4 0 1) ; "end" is ambiguous here (test p '(4 1 . 2)) (fill! p 5 1) (test p '(4 5 . 5))) ;; generic for-each/map (test (let ((sum 0)) (for-each (lambda (n) (set! sum (+ sum n))) (vector 1 2 3)) sum) 6) (test (map (lambda (n) (+ n 1)) (vector 1 2 3)) '(2 3 4)) (test (map (lambda (a b) (/ a b)) (list 1 2 3) (list 4 5 6)) '(1/4 2/5 1/2)) (when with-block (let ((b (block 1.0 2.0 3.0))) (test (map (lambda (x) (floor x)) b) '(1 2 3)) (let ((sum 0)) (for-each (lambda (x) (set! sum (+ sum (floor x)))) b) (test sum 6)))) ;; try some applicable stuff (test (let ((lst (list 1 2 3))) (set! (lst 1) 32) (list (lst 0) (lst 1))) (list 1 32)) (test (let ((hash (make-hash-table))) (set! (hash 'hi) 32) (hash 'hi)) 32) (test (let ((str (string #\1 #\2 #\3))) (set! (str 1) #\a) (str 1)) #\a) (test (let ((v (vector 1 2 3))) (set! (v 1) 0) (v 1)) 0) (let () (define (hiho a) __func__) (test (or (equal? (hiho 1) 'hiho) (equal? (car (hiho 1)) 'hiho)) #t)) ;;; gc (for-each (lambda (arg) (test (gc arg) 'error)) (list "hi" '(1 2 3) #() 'a-symbol abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i 1 () "" :hi (if #f #f) (lambda (a) (+ a 1)))) (test (gc #f #t) 'error) ;;; -------------------------------------------------------------------------------- ;;; tail recursion tests (let ((max-stack 0)) (define (tc-1 a c) (let ((b (+ a 1))) (if (> (-s7-stack-top-) max-stack) (set! max-stack (-s7-stack-top-))) (if (< b c) (tc-1 b c)))) (tc-1 0 32) (if (> max-stack 10) (format-logged #t "tc-1 max: ~D~%" max-stack))) ; 18 here and below in repl.scm (let ((max-stack 0)) (define (tc-1 a c) (if (> (-s7-stack-top-) max-stack) (set! max-stack (-s7-stack-top-))) (if (< a c) (tc-2 (+ a 1) c))) (define (tc-2 a c) (if (> (-s7-stack-top-) max-stack) (set! max-stack (-s7-stack-top-))) (if (< a c) (tc-1 (+ a 1) c))) (tc-1 0 32) (if (> max-stack 10) (format-logged #t "tc-1-1 max: ~D~%" max-stack))) (let ((max-stack 0)) (define (tc-2 a c) (let ((b (+ a 1))) (if (> (-s7-stack-top-) max-stack) (set! max-stack (-s7-stack-top-))) (if (= b c) #f (tc-2 b c)))) (tc-2 0 32) (if (> max-stack 10) (format-logged #t "tc-2 max: ~D~%" max-stack))) (let ((max-stack 0)) (define (tc-2 a c) (let ((b (+ a 1))) (if (> (-s7-stack-top-) max-stack) (set! max-stack (-s7-stack-top-))) (if (< b c) (tc-2 b c) #f))) (tc-2 0 32) (if (> max-stack 10) (format-logged #t "tc-2-1 max: ~D~%" max-stack))) (let ((max-stack 0)) (define (tc-3 a c) (let ((b (+ a 1))) (if (> (-s7-stack-top-) max-stack) (set! max-stack (-s7-stack-top-))) (cond ((= b c) #f) ((< b c) (tc-3 b c))))) (tc-3 0 32) (if (> max-stack 10) (format-logged #t "tc-3 max: ~D~%" max-stack))) (let ((max-stack 0)) (define (tc-4 a c) (let ((b (+ a 1))) (if (> (-s7-stack-top-) max-stack) (set! max-stack (-s7-stack-top-))) (cond ((= b c) #f) (else (tc-4 b c))))) (tc-4 0 32) (if (> max-stack 10) (format-logged #t "tc-4 max: ~D~%" max-stack))) (let ((max-stack 0)) (define (tc-5 a c) (let ((b (+ a 1))) (if (> (-s7-stack-top-) max-stack) (set! max-stack (-s7-stack-top-))) (case b ((32) #f) (else (tc-5 b c))))) (tc-5 0 32) (if (> max-stack 10) (format-logged #t "tc-5 max: ~D~%" max-stack))) (let ((max-stack 0)) (define (tc-6 a c) (let ((b (+ a 1))) (if (> (-s7-stack-top-) max-stack) (set! max-stack (-s7-stack-top-))) (case b ((17) #f) ((0 1 2 3 4 5 6 7 8) (tc-6 b c)) ((9 10 11 12 13 14 15 16) (tc-6 b c))))) (tc-6 0 32) (if (> max-stack 10) (format-logged #t "tc-6 max: ~D~%" max-stack))) (let ((max-stack 0)) (define (tc-7 a c) (let ((b (+ a 1))) (if (> (-s7-stack-top-) max-stack) (set! max-stack (-s7-stack-top-))) (or (>= b c) (tc-7 b c)))) (tc-7 0 32) (if (> max-stack 10) (format-logged #t "tc-7 max: ~D~%" max-stack))) (let ((max-stack 0)) (define (tc-8 a c) (let ((b (+ a 1))) (if (> (-s7-stack-top-) max-stack) (set! max-stack (-s7-stack-top-))) (and (< b c) (tc-8 b c)))) (tc-8 0 32) (if (> max-stack 10) (format-logged #t "tc-8 max: ~D~%" max-stack))) (let ((max-stack 0)) (define (tc-9 a c) (let tc-9a ((b a)) (if (> (-s7-stack-top-) max-stack) (set! max-stack (-s7-stack-top-))) (if (< b c) (tc-9a (+ b 1))))) (tc-9 0 32) (if (> max-stack 10) (format-logged #t "tc-9 max: ~D~%" max-stack))) (let ((max-stack 0)) (define (tc-10 a c) (let* ((b (+ a 1))) (if (> (-s7-stack-top-) max-stack) (set! max-stack (-s7-stack-top-))) (and (< b c) (tc-10 b c)))) (tc-10 0 32) (if (> max-stack 10) (format-logged #t "tc-10 max: ~D~%" max-stack))) (let ((max-stack 0)) (define (tc-11 a c) (letrec ((b (+ a 1))) (if (> (-s7-stack-top-) max-stack) (set! max-stack (-s7-stack-top-))) (and (< b c) (tc-11 b c)))) (tc-11 0 32) (if (> max-stack 10) (format-logged #t "tc-11 max: ~D~%" max-stack))) (let ((max-stack 0)) (define (tc-12 a c) (if (< a c) (begin (if (> (-s7-stack-top-) max-stack) (set! max-stack (-s7-stack-top-))) (tc-12 (+ a 1) c)))) (tc-12 0 32) (if (> max-stack 10) (format-logged #t "tc-12 max: ~D~%" max-stack))) (let ((max-stack 0)) (define (tc-13 a c) (if (> (-s7-stack-top-) max-stack) (set! max-stack (-s7-stack-top-))) (cond ((= a c) #f) ((< a c) (if (> a c) (display "oops")) (tc-13 (+ a 1) c)))) (tc-13 0 32) (if (> max-stack 10) (format-logged #t "tc-13 max: ~D~%" max-stack))) (let ((max-stack 0)) (define (tc-14 a c) (if (> (-s7-stack-top-) max-stack) (set! max-stack (-s7-stack-top-))) (cond ((>= a c) #f) ((values (+ a 1) c) => tc-14))) (tc-14 0 32) (if (> max-stack 10) (format-logged #t "tc-14 max: ~D~%" max-stack))) (let ((max-stack 0)) (define (tc-15 a c) (if (> (-s7-stack-top-) max-stack) (set! max-stack (-s7-stack-top-))) (or (>= a c) (apply tc-15 (list (+ a 1) c)))) (tc-15 0 32) (if (> max-stack 10) (format-logged #t "tc-15 max: ~D~%" max-stack))) (let ((max-stack 0) (e #f)) (set! e (curlet)) (define (tc-17 a c) (if (> (-s7-stack-top-) max-stack) (set! max-stack (-s7-stack-top-))) (or (and (>= a c) a) (eval `(tc-17 (+ ,a 1) ,c) e))) (let ((val (tc-17 0 32))) (test (and (= val 32) (< max-stack 28)) #t))) #| (let ((max-stack 0)) (define (tc-19 a c) (if (> (-s7-stack-top-) max-stack) (set! max-stack (-s7-stack-top-))) (call/cc (lambda (r) (if (>= a c) (r a)) (tc-19 (+ a 1) c)))) (let ((val (tc-19 0 16))) (test (and (= val 16) (< max-stack 8)) #t))) |# (let ((max-stack 0)) (define (tc-21 a) (if (< a 32) (do ((i (- a 1) (+ i 1))) ((= i a) (tc-21 (+ a 1))) (if (> (-s7-stack-top-) max-stack) (set! max-stack (-s7-stack-top-)))) a)) (let ((val (tc-21 0))) (if (> max-stack 10) (format-logged #t "tc-21 max: ~D~%" max-stack)) (if (not (= val 32)) (format-logged #t "tc-21 returned: ~A~%" val)))) (let ((max-stack 0)) (define (tc-env a c) (with-let (sublet (curlet) (cons 'b (+ a 1))) (if (> (-s7-stack-top-) max-stack) (set! max-stack (-s7-stack-top-))) (if (< b c) (tc-env b c)))) (tc-env 0 32) (if (> max-stack 10) (format-logged #t "tc-env max: ~D~%" max-stack))) (let ((max-stack 0)) (define (tc-env-1 a) (if (> (-s7-stack-top-) max-stack) (set! max-stack (-s7-stack-top-))) (if (> a 0) (with-let (curlet) (tc-env-1 (- a 1))))) (tc-env-1 32) (if (> max-stack 10) (format-logged #t "tc-env-1 max: ~D~%" max-stack))) ;;; make sure for-each and map aren't messed up (let ((max-stack 0)) (for-each (lambda (a) (if (> (-s7-stack-top-) max-stack) (set! max-stack (-s7-stack-top-))) (if (not (= a 1)) (error 'wrong-type-arg ";for-each arg is ~A" a))) (make-list 100 1)) (test (< max-stack 20) #t)) ; 10 is not snd-test (and below) (let ((max-stack 0)) (map (lambda (a) (if (> (-s7-stack-top-) max-stack) (set! max-stack (-s7-stack-top-))) (if (not (= a 1)) (error 'wrong-type-arg ";map arg is ~A" a))) (make-list 100 1)) (test (< max-stack 20) #t)) ;;; the next 3 are not tail-recursive ;;; ;;; eval-string pushes stack markers to catch multiple statements ;;; OP_DEACTIVATE_GOTO in call-with-exit ;;; OP_DYNAMIC_WIND in the dynamic-wind case (let ((max-stack 0) (e #f)) (set! e (curlet)) (define (tc-17 a c) (if (> (-s7-stack-top-) max-stack) (set! max-stack (-s7-stack-top-))) (or (and (>= a c) a) (eval-string (format #f "(tc-17 (+ ~A 1) ~A)" a c) e))) (let ((val (tc-17 0 32))) (test (and (= val 32) (< max-stack 28)) #f))) (let ((max-stack 0)) (define (tc-16 a c) (if (> (-s7-stack-top-) max-stack) (set! max-stack (-s7-stack-top-))) (call-with-exit (lambda (r) (if (>= a c) (r a)) (tc-16 (+ a 1) c)))) (let ((val (tc-16 0 32))) (test (and (= val 32) (> max-stack 28)) #t))) (let ((max-stack 0)) (define (tc-18 a c) (dynamic-wind (lambda () (if (> (-s7-stack-top-) max-stack) (set! max-stack (-s7-stack-top-)))) (lambda () (or (and (>= a c) a) (tc-18 (+ a 1) c))) (lambda () #f))) (let ((val (tc-18 0 32))) (test (and (= val 32) (> max-stack 28)) #t))) (test (let ((f #f)) (let tr ((i 10)) (if (= i 3) (set! f (lambda () i))) (if (> i 0) (tr (- i 1)))) (f)) 3) (test (let ((f ())) (let tr ((i 4)) (set! f (cons i f)) (if (> i 0) (tr (- i 1)))) f) '(0 1 2 3 4)) ;;; -------- miscellaneous amusements (test ((number->string -1) 0) #\-) (test ((reverse '(1 2)) 0) 2) (test ((append begin) list) list) (test ((begin object->string) car) "car") (test ((and abs) -1) 1) (test (((values begin) object->string) car) "car") (test (((values (begin begin)) object->string) car) "car") (test ((((values append) begin) object->string) car) "car") (test ((((((values and) or) append) begin) object->string) car) "car") (test (((((((values values) and) or) append) begin) object->string) car) "car") (test (((append s7-version)) 0) #\s) (test ((values (lambda hi #()))) #()) (test (((((lambda () (lambda () (lambda () (lambda () 1)))))))) 1) (test (((cond (cond => cond)) (cond)) ((cond (#t #t)))) #t) (test ((object->string #f) (ceiling 3/4)) #\f) (test (procedure? ((((((lambda* ((x (lambda () x))) x))))))) #t) (test (procedure? ((((((letrec ((x (lambda () x))) x))))))) #t) (test (procedure? ((((((letrec ((x (lambda () y)) (y (lambda () x))) x))))))) #t) (test (procedure? ((((((let x () x))))))) #t) (test (procedure? ((((((lambda (x) (set! x (lambda () x))) (lambda () x))))))) #t) (test (procedure? ````,,,,((((let x () x))))) #t) (test ((do ((i 0 (+ i 1))) ((= i 1) (lambda () 3)))) 3) (test (dynamic-wind s7-version s7-version s7-version) (s7-version)) (num-test ((list .(log 0)) 1) 0) (num-test (((cons .(log 0)) 0) 1) 0.0) (test (+ (+) (*)) 1) (test (modulo (lcm) (gcd)) 1) (test (max (+) (*)) 1) (test (min (gcd) (lcm)) 0) (test (symbol->value (gensym) (rootlet)) #) (test (string-ref (s7-version) (*)) #\7) (test (string>=? (string-append) (string)) #t) (test (substring (string-append) (+)) "") (test (ash (*) (+)) 1) (test (> (*) (+)) #t) (test ((or #f list)) ()) (test ((or #f lcm)) 1) (test ((or begin symbol?)) ()) (test ((or begin make-polar)) ()) (test ((and #t begin)) ()) (test (begin) ()) (test ((or #f lcm) 2 3) 6) (test ((or and) #f #t) #f) (test ((and or) #f #t) #t) (test (or (or) (and)) #t) (test ((car '((1 2) (3 4))) 0) 1) (test ((or apply) lcm) 1) (test (- ((or *))) -1) (test ((car (list lcm))) 1) (test ((or (cond (lcm)))) 1) (test ((cond (asin floor *))) 1) (test (logior (#(1 #\a (3)) 0) (truncate 1.5)) 1) (test (real? (*)) #t) (test (- (lcm)) -1) (test (* (*)) 1) (test (+ (+) (+ (+)) (+ (+ (+)))) 0) (test (+(*(+))(*)(+(+)(+)(*))) 2) (num-test (+(-(*).(+1))(*(+).(-1))(*(+).(-10))(*(-(+)0)1.)(-(+)(*).01)(*(-(+)).01)(-(+)(*)1.0)(-(*(+))1.0)(*(-(+))1.0)(-(+(*)1).0))-2.01) (num-test (+(-(*).(+1.0))(*(+).(-1.0))(-(+)1.(*)0.)(-(*(+)0.)1.)(-(+(*)1.)0.)(+(-(*)0.)1.))1.0) ;; float comparison so can't use direct '=' here (test (nan? (asinh (cos (real-part (log 0.0))))) #t) (num-test(cos(sin(log(tan(*))))) 0.90951841537482) (num-test (asinh (- 9223372036854775807)) -44.361419555836) (num-test (imag-part (asin -9223372036854775808)) 44.361419555836) (if (provided? 'dfls-exponents) (begin ;; proof that these exponents should be disallowed (num-test (string->number "1l1") 10.0) (num-test (string->number "1l1+1l1i") 10+10i) (num-test (string->number "1l11+11l1i") 100000000000+110i) (num-test (string->number "#d1d1") 10.0) (num-test (string->number "#d0001d0001") 10.0))) (test (#|#<|# = #|#f#|# #o#e0 #|#>|# #e#o0 #|#t#|#) #t) (num-test (apply * (map (lambda (r) (sin (* pi (/ r 130)))) (list 1 67 69 73 81 97))) (/ 1.0 64)) (num-test (max 0(+)(-(*))1) 1) (test ((call-with-exit object->string) 0) #\#) ; # (test ((begin begin) 1) 1) (test ((values begin) 1) 1) (test ((provide or) 3/4) 'error) (test (string? cond) #f) (test (list? or) #f) (test (pair? define) #f) (test (number? lambda*) #f) (test ((s7-version) (rationalize 0)) #\s) (test (cond (((values '(1 2) '(3 4)) 0 0))) 'error) (test (cond (((#2d((1 2) (3 4)) 0) 0) 32)) 32) (test (cond ((apply < '(1 2)))) #t) (test (dynamic-wind lcm gcd *) 0) ; was 'error but Peter Bex tells me this is normal (test (case 0 ((> 0 1) 32)) 32) (test (char-downcase (char-downcase #\newline)) #\newline) (test (and (and) (and (and)) (and (and (and (or))))) #f) (test ((values begin #\a 1)) 1) (test ((values and 1 3)) 3) (test ((((lambda () begin)) (values begin 1))) 1) (test (+ (((lambda* () values)) 1 2 3)) 6) (test ((values ('((1 2) (3 4)) 1) (abs -1))) 4) (test ((apply lambda () '(() ()))) ()) (test ((lambda* ((symbol "#(1 #\\a (3))")) #t)) #t) (test (apply if ('((1 2) (3 4)) 1)) 4) (test (((lambda #\newline gcd))) 'error) (test (symbol? (let () (define (hi) (+ 1 2)))) #f) (test (symbol? (begin (define (x y) y) (x (define (x y) y)))) #f) (test (symbol? (do () ((define (x) 1) (define (y) 2)))) #f) (test (cond (0 (define (x) 3) (x))) 3) (test (let ((x (lambda () 3))) (if (define (x) 4) (x) 0)) 4) (test (and (define (x) 4) (+ (x) 1)) 5) (test (do ((x (lambda () 3) (lambda () 4))) ((= (x) 4) (define (x) 5) (x))) 5) (test (begin (if (define (x) 3) (define (x) 4) (define (x) 5)) (x)) 4) (test (let ((1,1 3) (1'1 4) (1|1 5) (1#1 6) (1\1 7) (1?1 8)) (+ 1,1 1'1 1|1 1#1 1\1 1?1)) 33) (test (let ((,a 3)) ,a) 'error) (test (let ((@a 3)) @a) 3) (test (let (("a" 3)) "a") 'error) (test (let ((`a 3)) `a) 'error) (test (let (('a 3)) 'a) 'error) (test (let ((a`!@#$%^&*~.,<>?/'{}[]\|+=_-a 3)) a`!@#$%^&*~.,<>?/'{}[]\|+=_-a) 3) (test (set! ((quote (1 2)) 0) #t) #t) (test (set! (((lambda () (list 1 2))) 0) 2) 2) (test (let ((x (list 1 2))) (set! (((lambda () x)) 0) 3) x) '(3 2)) (test (let ((x (list 1 2))) (set! (((vector x) 0) 1) 32) x) '(1 32)) (test (let ((x (list 1 2))) (set! ((((lambda () (vector x))) 0) 0) 3) x) '(3 2)) (test (let ((x (list 1 2))) (set! ((((lambda () (list x))) 0) 0) 3) x) '(3 2)) (test (let ((x (list 1 2))) (set! ((set! x (list 4 3)) 0) 32) x) '(32 3)) (test (let ((x (list 1 2))) (list-set! (set! x (list 4 3)) 0 32) x) '(32 3)) (test (let ((x (list 1 2))) (set! ((list-set! x 0 (list 4 3)) 0) 32) x) '((32 3) 2)) (test (let ((x (list 1 2))) (list-set! (list-set! x 0 (list 4 3)) 0 32) x) '((32 3) 2)) (test (set! (('((0 2) (3 4)) 0) 0) 0) 0) (test (set! ((map abs '(1 2)) 1) 0) 0) (test (let () (set! ((define x #(1 2)) 0) 12) x) #(12 2)) (test (let ((x (list 1 2))) (set! ((call-with-exit (lambda (k) (k x))) 0) 12) x) '(12 2)) (test (let ((x #2d((1 2) (3 4)))) (set! (((values x) 0) 1) 12) x) #2D((1 12) (3 4))) (test (let ((x 0)) (set! ((dilambda (lambda () x) (lambda (y) (set! x y)))) 12) x) 12) (test (let ((x 0) (str "hiho")) (string-set! (let () (set! x 32) str) 0 #\x) (list x str)) '(32 "xiho")) (test (let ((x "hi") (y "ho")) (set! ((set! x y) 0) #\x) (list x y)) '("xo" "xo")) (test (let ((x "hi") (y "ho")) (set! x y) (set! (y 0) #\x) (list x y)) '("xo" "xo")) ; Guile gets the same result (test (let ((x (lambda (a) (a z 1) z))) (x define)) 1) ; ! (test (let ((x (lambda (a) (a z (lambda (b) (+ b 1))) (z 2)))) (x define)) 3) (test (let ((x (lambda (a b c) (apply a (list b c))))) (x let () 3)) 3) (test (let ((x (lambda (a b c) (apply a (list b c))))) (x let '((y 2)) '(+ y 1))) 3) (let () (test ((values let '((x 1))) '(+ x 1)) 2)) ; ! (let () (test ((values begin '(define x 32)) '(+ x 1)) 33)) (let () (test (((values lambda '(x) '(+ x 1))) 32) 33)) (let () (test (let ((arg '(x)) (body '(+ x 1))) (((values lambda arg body)) 32)) 33)) (let () (test (let ((arg '(x)) (body '(+ x 1))) ((apply lambda arg (list body)) 32)) 33)) (let () (test (let ((x 12)) ((apply lambda '(x) (list (list '+ 1 x 'x))) 3)) 16)) (let () (test (let* ((x 3) (arg '(x)) (body `((+ ,x x 1)))) ((apply lambda arg body) 12)) 16)) (let () (define (bcase start end func) (let ((body ())) (do ((i start (+ i 1))) ((= i end)) (set! body (cons `((,i) ,(func i)) body))) (lambda (i) (apply case i body)))) (test ((bcase 0 3 abs) 1) 1)) ;;; ------ CLisms ------------------------------------------------------------------------ (let () ;; ********************************************************************** ;; ;; Copyright (C) 2002 Heinrich Taube (taube@uiuc.edu) ;; ;; This program is free software; you can redistribute it and/or ;; modify it under the terms of the GNU General Public License ;; as published by the Free Software Foundation; either version 2 ;; of the License, or (at your option) any later version. ;; ;; This program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; ;; ********************************************************************** ;; $Name: $ ;; $Revision: 1.6 $ ;; $Date: 2005/11/17 13:29:37 $ ;; ;; Implementation of the CLTL2 loop macro. The following ;; non Rev 5 definitions need to be in effect before the file ;; is loaded: ;; ;; (define-macro (name . args) ...) ;; (error string) ;; (gensym string) ;; ; (define-macro (when test . forms) ; `(if ,test (begin ,@forms))) (define-macro (loop . args) (let () (define-macro (push val sym) `(begin (set! ,sym (cons ,val ,sym)) ,sym)) (define-macro (pop sym) (let ((v (gensym "v"))) `(let ((,v (car ,sym))) (set! ,sym (cdr ,sym)) ,v))) ;; this next one is a no-op but i need it as a marker for my cltl2 ;; translator. (define-macro (function sym) sym) ;; getters and setters for the loop-clause "struct" (define (loop-operator c) (vector-ref c 0)) (define (loop-operator-set! c x) (vector-set! c 0 x)) (define (loop-bindings c) (vector-ref c 1)) (define (loop-bindings-set! c x) (vector-set! c 1 x)) (define (loop-collectors c) (vector-ref c 2)) (define (loop-collectors-set! c x) (vector-set! c 2 x)) (define (loop-initially c) (vector-ref c 3)) (define (loop-initially-set! c x) (vector-set! c 3 x)) (define (loop-end-tests c) (vector-ref c 4)) (define (loop-end-tests-set! c x) (vector-set! c 4 x)) (define (loop-looping c) (vector-ref c 5)) (define (loop-looping-set! c x) (vector-set! c 5 x)) (define (loop-stepping c) (vector-ref c 6)) (define (loop-stepping-set! c x) (vector-set! c 6 x)) (define (loop-finally c) (vector-ref c 7)) (define (loop-finally-set! c x) (vector-set! c 7 x)) (define (loop-returning c) (vector-ref c 8)) (define (loop-returning-set! c x) (vector-set! c 8 x)) (define (make-loop-clause . args) (let ((v (vector #f () () () () () () () ()))) (if (null? args) v (do ((a args (cddr a))) ((null? a) v) (case (car a) ((operator) (loop-operator-set! v (cadr a))) ((bindings) (loop-bindings-set! v (cadr a))) ((collectors) (loop-collectors-set! v (cadr a))) ((initially) (loop-initially-set! v (cadr a))) ((end-tests) (loop-end-tests-set! v (cadr a))) ((looping) (loop-looping-set! v (cadr a))) ((stepping) (loop-stepping-set! v (cadr a))) ((finally) (loop-finally-set! v (cadr a))) ((returning) (loop-returning-set! v (cadr a)))))))) (define (gather-clauses caller clauses) ;; nconc all clausal expressions into one structure (let ((gather-clause (lambda (clauses accessor) ;; append data from clauses (do ((l ())) ((null? clauses) l) (set! l (append l (accessor (car clauses)))) (set! clauses (cdr clauses)))))) (make-loop-clause 'operator caller 'bindings (gather-clause clauses (function loop-bindings)) 'collectors (gather-clause clauses (function loop-collectors)) 'initially (gather-clause clauses (function loop-initially)) 'end-tests (gather-clause clauses (function loop-end-tests)) 'looping (gather-clause clauses (function loop-looping)) 'stepping (gather-clause clauses (function loop-stepping)) 'finally (gather-clause clauses (function loop-finally)) 'returning (gather-clause clauses (function loop-returning))))) (define (loop-op? x ops) (assoc x ops)) (define (loop-variable? x) (symbol? x)) (define (make-binding var val) (list var val)) (define (loop-error ops forms . args) ;; all error messages include error context. (let ((loop-context (lambda (lst ops) ;; return tail of expr up to next op in cdr of tail (do ((h lst) (l ())) ((or (null? lst) ;; ignore op if in front. (and (not (eq? h lst)) (loop-op? (car lst) ops))) (reverse l)) (set! l (cons (car lst) l)) (set! lst (cdr lst)))))) (let ((forms (loop-context forms ops))) (newline) (display "LOOP ERROR: ") (do ((tail args (cdr tail))) ((null? tail) #f) (display (car tail))) (newline) (display "clause context: ") (if (null? forms) (display "()") (do ((tail forms (cdr tail))) ((null? tail) #f) (if (eq? tail forms) (display "'")) (display (car tail)) (display (if (null? (cdr tail)) "'" " ")))) (newline) (error "illegal loop syntax")))) (define (parse-for forms clauses ops) ;; forms is (FOR ...) (let ((op (loop-op? (car forms) ops))) (if (null? (cdr forms)) (loop-error ops forms "Variable expected but source code ran out." ) (let ((var (cadr forms))) (if (loop-variable? var) (if (null? (cddr forms)) (loop-error ops forms "'for' clause expected but source code ran out.") ;; find the iteration path in the op (let ((path (assoc (caddr forms) (cdddr op)))) ;; path is ( ) (if (not path) (loop-error ops forms "'" (caddr forms) "'" " is not valid with 'for'.") ( (cadr path) forms clauses ops)))) (loop-error ops forms "Found '" (cadr forms) "' where a variable expected.")))))) (define (parse-numerical-for forms clauses ops) ;; forms is (FOR ...) ;; where is guaranteed to be one of: FROM TO BELOW ABOVE DOWNTO ;; (bil) clauses (let ((var (cadr forms)) (tail (cddr forms)) (bind ()) (from #f) (head #f) (last #f) (stop #f) (step #f) (test #f) (incr #f)) (do ((next #f)) ((or (null? tail) (loop-op? (car tail) ops))) (set! next (pop tail)) (if (null? tail) (loop-error ops forms "Expected expression but source code ran out.")) (case next ((from downfrom) (if head (loop-error ops forms "Found '" next "' when '" head "' in effect.")) (set! head next) (set! from (pop tail))) ((below) (if last (loop-error ops forms "Found '" next "' when '" last "' in effect.")) (set! stop (pop tail)) (set! last next)) ((to) (if last (loop-error ops forms "Found '" next "' when '" last "' in effect.")) (set! stop (pop tail) ) (set! last next)) ((above ) (if last (loop-error ops forms "Found '" next "' when '" last "' in effect.")) (set! stop (pop tail)) (set! last next)) ((downto ) (if last (loop-error ops forms "Found '" next "' when '" last "' in effect.")) (set! stop (pop tail)) (set! last next)) ((by) (if step (loop-error ops forms "Found duplicate 'by'.")) (set! step (pop tail))) (else (loop-error ops forms "'" next "' is not valid with 'for'.")))) (if (not head) (set! head 'from)) (if (or (eq? head 'downfrom) (eq? last 'downto) (eq? last 'above)) (begin (set! incr '-) (if (eq? last 'above) (set! test '<=) (set! test '<))) ; allow to for downto (begin (set! incr '+) (if (eq? last 'below) (set! test '>=) (set! test '>)))) ;; add binding for initial value (push (make-binding var (or from 0)) bind) ;; add binding for non-constant stepping values. (if (not step) (set! step 1) (if (not (number? step)) (let ((var (gensym "v"))) (push (make-binding var step) bind) (set! step var)))) (set! step `(set! ,var (,incr ,var ,step))) (if stop (let ((end (gensym "v"))) (push (make-binding end stop) bind) (set! stop (list test var end)))) (values (make-loop-clause 'operator 'for 'bindings (reverse bind) 'stepping (list step) 'end-tests (if (not stop) () (list stop))) tail))) (define (parse-repeat forms clauses ops) ;; forms is (REPEAT
...) (if (null? (cdr forms)) (loop-error ops forms "'repeat' clause expected but source code ran out." ) (call-with-values (lambda () (parse-numerical-for (list 'for (gensym "v") 'below (cadr forms)) clauses ops)) (lambda (clause ignore) ignore (values clause (cddr forms)))))) (define (parse-sequence-iteration forms clauses ops) ;; tail is (FOR ...) ;; is guaranteed to be one of: IN ON ACROSS ;; (bil) clauses (let ((head forms) (var (cadr forms)) (seq (gensym "v")) (tail (cddr forms)) (bind ()) (data #f) (init ()) (loop ()) (incr #f) (stop ()) (step ()) (type #f)) (do ((next #f)) ((or (null? tail) (loop-op? (car tail) ops))) (set! next (pop tail)) (when (null? tail) (loop-error ops head "Expression expected but source code ran out." )) (case next ((in on across) (if type (loop-error ops head "Extraneous '" next "' when '" type "' in effect.")) (set! type next) (set! data (pop tail))) ((by ) (if incr (loop-error ops head "Duplicate 'by'." ) (if (eq? type 'across) (loop-error ops head "'by' is invalid with 'across'." ) (set! incr (pop tail))))) (else (loop-error ops head "'" next "' is not valid with 'for'.")))) ; add bindings for stepping var and source (push (make-binding var #f) bind) (push (make-binding seq data) bind) (if (eq? type 'across) (let ((pos (gensym "v")) (mx (gensym "v"))) (push (make-binding pos 0) bind) (push (make-binding mx #f) bind) (push `(set! ,mx (vector-length ,seq)) init) (push `(set! ,pos (+ 1 ,pos)) step) (push `(set! ,var (vector-ref ,seq ,pos)) loop) (push `(>= ,pos ,mx) stop)) (begin (if incr (if (and (list? incr) (eq? (car incr) 'quote)) (push `(set! ,seq (,(cadr incr) ,seq)) step) (push `(set! ,seq (,incr ,seq)) step)) (push `(set! ,seq (cdr ,seq)) step)) (push (if (eq? type 'in) `(set! ,var (car ,seq)) `(set! ,var ,seq)) loop) (push `(null? ,seq) stop))) (values (make-loop-clause 'operator 'for 'bindings (reverse bind) 'end-tests stop 'initially init 'looping loop 'stepping step) tail))) (define (parse-general-iteration forms clauses ops) ;; forms is (FOR = ...) ;; (bil) clauses (let ((head forms) (var (cadr forms)) (tail (cddr forms)) (init #f) (type #f) (loop #f) (step #f)) (do ((next #f)) ((or (null? tail) (loop-op? (car tail) ops))) (set! next (pop tail)) (if (null? tail) (loop-error ops head "Expression expected but source code ran out.")) (case next ((= ) (if type (loop-error ops head "Duplicate '='.")) (set! loop `(set! ,var ,(pop tail))) (set! type next)) ((then ) (if init (loop-error ops head "Duplicate 'then'.")) (set! init loop) (set! loop #f) (set! step `(set! ,var ,(pop tail))) (set! type next)) (else (loop-error ops head "'" next "' is not valid with 'for'.")))) (values (make-loop-clause 'operator 'for 'bindings (list (make-binding var #f)) 'initially (if init (list init) ()) 'looping (if loop (list loop) ()) 'stepping (if step (list step) ())) tail))) (define (parse-with forms clauses ops) ;; forms is (WITH = ...) ;; (bil) clauses (let ((head forms) (tail (cdr forms)) (var #f) (expr #f) (and? #f) (bind ()) (init ())) (do ((need #t) (next #f)) ((or (null? tail) (loop-op? (car tail) ops))) (set! next (pop tail)) (cond ((and (loop-variable? next) need) (if var (loop-error ops head "Found '" next "' where 'and' expected.")) (if expr (loop-error ops head "Found '" next "' where 'and' expected.")) (set! var next) (set! expr #f) (set! and? #f) (set! need #f)) ((eq? next 'and) (if and? (loop-error ops head "Duplicate 'and'.") (if var (if expr (begin (push (make-binding var #f) bind) (push `(set! ,var ,expr) init)) (push (make-binding var #f) bind)) (loop-error ops head "Extraneous 'and'."))) (set! var #f) (set! expr #f) (set! and? #t) (set! need #t)) ((eq? next '=) (if expr (loop-error ops head "Found '=' where 'and' expected.") (set! expr (pop tail)))) (else (if need (loop-error ops head "Found '" next "' where variable expected.") (loop-error ops head "Found '" next "' where '=' or 'and' expected."))))) (if and? (loop-error ops head "Extraneous 'and'.") (if var (if expr (begin (push (make-binding var #f) bind) (push `(set! ,var ,expr) init)) (push (make-binding var #f) bind)))) (values (make-loop-clause 'operator 'with 'bindings (reverse bind) 'initially (reverse init)) tail))) (define (parse-do forms clauses ops) ;; (bil) clauses (let ((head forms) (oper (pop forms)) (body ())) (do () ((or (null? forms) (loop-op? (car forms) ops)) (if (null? body) (loop-error ops head "Missing '" oper "' expression.") (set! body (reverse body)))) (push (car forms) body) (set! forms (cdr forms))) (values (make-loop-clause 'operator oper 'looping body) forms))) (define (parse-finally forms clauses ops) ;; (bil) clauses (let ((oper (pop forms)) (expr #f)) (if (null? forms) (loop-error ops forms "Missing '" oper "' expression.")) (set! expr (pop forms)) (values (make-loop-clause 'operator oper 'finally (list expr)) forms))) (define (parse-initially forms clauses ops) ;; (bil) clauses (let ((oper (pop forms)) (expr #f)) (if (null? forms) (loop-error ops forms "Missing '" oper "' expression.")) (set! expr (pop forms)) (values (make-loop-clause 'operator oper 'initially (list expr)) forms))) (define (lookup-collector var clauses) ;; collector is list: ( ) ;; returns the clause where the collect variable VAR is ;; actually bound or nil if var hasn't already been bound ;; if var is nil only the single system allocated collecter ;; is possibly returned. (let ((checkthem (lambda (var lis) (do ((a #f)) ((or (null? lis) a) a) (if (eq? var (car (car lis))) ;collector-var (set! a (car lis))) (set! lis (cdr lis)))))) (do ((c #f)) ((or (null? clauses) c) c) (set! c (checkthem var (loop-collectors (car clauses)))) (set! clauses (cdr clauses))))) (define (compatible-accumulation? typ1 typ2) (let ((l1 '(collect append nconc)) (l2 '(never always)) (l3 '(minimize maximize))) (or (eq? typ1 typ2) (and (member typ1 l1) (member typ2 l1)) (and (member typ1 l2) (member typ2 l2)) (and (member typ1 l3) (member typ2 l3))))) (define (parse-accumulation forms clauses ops) ;; forms is ( form ...) ;; where is collect append nconc (let ((save forms) (oper (pop forms)) (make-collector (lambda (var type acc head) (list var type acc head))) ;; removed because noop ;;(collector-var (lambda (col) (car col))) (collector-type (lambda (col) (cadr col))) (collector-acc (lambda (col) (caddr col))) (collector-head (lambda (col) (cadddr col))) (expr #f) (coll #f) (new? #f) (into #f) (loop ()) (bind ()) (init ()) (tests ()) (return ())) (if (null? forms) (loop-error ops forms "Missing '" oper "' expression.")) (set! expr (pop forms)) (if (not (null? forms)) (if (eq? (car forms) 'into) (begin (if (null? (cdr forms)) (loop-error ops save "Missing 'into' variable.")) (if (loop-variable? (cadr forms)) (begin (set! into (cadr forms)) (set! forms (cddr forms))) (loop-error ops save "Found '" (car forms) "' where 'into' variable expected."))))) ;; search for a clause that already binds either the user specified ;; accumulator (into) or a system allocated one if no into. ;; system collectors ;; o only one allowed, all accumuations must be compatible ;; o returns value ;; value collector: (nil <#:acc>) ;; list collector: (nil <#:tail> <#:head>) ;; into collectors ;; o any number allowed ;; o returns nothing. ;; value collector: ( ) ;; list collector: ( <#:tail> <#:head>) (set! coll (lookup-collector into clauses)) (if (not coll) (set! new? #t) ;; accumulator already established by earlier clause ;; check to make sure clauses are compatible. (if (not (compatible-accumulation? oper (collector-type coll))) (loop-error ops save "'" (collector-type coll) "' and '" oper "' are incompatible accumulators."))) (case oper ((sum count) (let ((acc #f)) (if new? (begin (set! acc (or into (gensym "v"))) (push (make-binding acc 0) bind) ;; coll= (nil <#:acc>) or ( ) (set! coll (make-collector into oper acc #f)) ;; only add a return value if new collector isnt into (if (not into) (push acc return))) (set! acc (collector-acc coll))) (if (eq? oper 'sum) (push `(set! ,acc (+ ,acc ,expr)) loop) (push `(if ,expr (set! ,acc (+ ,acc 1))) loop)))) ((minimize maximize) (let ((var (gensym "v")) (opr (if (eq? oper 'minimize) '< '>)) (acc #f)) (if new? (begin (set! acc (or into (gensym "v"))) (push (make-binding acc #f) bind) ;; coll= (nil <#:acc>) or ( ) (set! coll (make-collector into oper acc #f)) ;; only add a return value if new collector isnt into (if (not into) (push `(or ,acc 0) return))) (set! acc (collector-acc coll))) (push (make-binding var #f) bind) (push `(begin (set! ,var ,expr) (if (or (not ,acc) (,opr ,var ,acc)) (set! ,acc ,var))) loop))) ((append collect nconc) ;; for list accumulation a pointer to the tail of the list ;; is updated and the head of the list is returned. any ;; into variable is set to the head inside the loop. (let ((head #f) (tail #f)) (if (not new?) (begin (set! tail (collector-acc coll)) (set! head (collector-head coll))) (begin (if into (push (make-binding into '(list)) bind)) (set! tail (gensym "v")) ;; allocate a pointer to the head of list (set! head (gensym "v")) (push (make-binding head '(list #f)) bind) (push (make-binding tail #f) bind) ;; initialize tail to head (push `(set! ,tail ,head) init) (set! coll (make-collector into oper tail head)) ;; only add a return value if new collector isnt into (if (not into) (push `(cdr ,head) return)))) ;; add loop accumulation forms (if (eq? oper 'append) (begin (push `(set-cdr! ,tail (append ,expr (list))) loop) (push `(set! ,tail (last-pair ,tail)) loop)) (if (eq? oper 'collect) (begin (push `(set-cdr! ,tail (list ,expr)) loop) (push `(set! ,tail (cdr ,tail)) loop)) (begin (push `(set-cdr! ,tail ,expr) loop) (push `(set! ,tail (last-pair ,tail)) loop)))) ;; update user into variable inside the main loop ;; regardless of whether its a new collector or not (if into (push `(set! ,into (cdr ,head)) loop))))) (values (make-loop-clause 'operator oper 'bindings (reverse bind) 'initially (reverse init) 'looping (reverse loop) 'returning (reverse return) 'collectors (if new? (list coll) ()) 'end-tests (reverse tests)) forms))) ;(define (loop-stop expr) ; `(%done% ,expr)) (define (loop-return expr) `(return ,expr)) (define (parse-while-until forms clauses ops) ;; (bil) clauses (let ((head forms) (oper (pop forms)) (test #f) (stop '(go #t))) ; :done (if (null? forms) (loop-error ops head "Missing '" oper "' expression.")) (case oper ((until ) (set! test (pop forms))) ((while ) (set! test `(not ,(pop forms))))) ;; calls the DONE continuation. (values (make-loop-clause 'operator oper 'looping (list `(if ,test ,stop))) forms))) (define (parse-thereis forms clauses ops) ;; (bil) clauses (let ((oper (car forms)) (expr #f) (bool #f) (func #f)) (if (null? (cdr forms)) (loop-error ops forms "Missing '" (car forms) "' expression." )) (set! expr (cadr forms)) ;; fourth element of operator definition must be ;; a function that returns the stop expression. (set! func (cadddr (loop-op? oper ops) )) (case oper ((thereis ) ;; return true as soon as expr is true or false at end (set! bool #f)) ((always ) ;; return false as soon as expr is false, or true at end (set! expr `(not ,expr)) (set! bool #t)) ((never ) ;; return false as soon as expr is true, or true at end (set! bool #t))) (set! forms (cddr forms)) ;; this calls the RETURN continuation (values (make-loop-clause 'operator 'thereis 'looping (list `(if ,expr ,(func (not bool)))) 'returning (list bool)) forms))) (define (parse-return forms clauses ops) ;; (bil) clauses (let ((oper (car forms)) (expr #f) (func #f)) (if (null? (cdr forms)) (loop-error ops forms "Missing '" (car forms) "' expression.")) (set! expr (cadr forms)) (set! forms (cddr forms)) ;; fourth element of operator definition must be ;; a function that returns the stop expression. (set! func (cadddr (loop-op? oper ops) )) ;; this calls the RETURN continuation (values (make-loop-clause 'operator 'return 'looping `(,(func expr))) forms))) (define (legal-in-conditional? x ops) ;; FIXED (member (loop-operator...)) (let ((op (loop-op? x ops))) (if (and op (not (null? (cddr op))) (eq? (caddr op) 'task) (not (member (car op) '(thereis never always)))) op #f))) (define (parse-then-else-dependents forms clauses ops) (let ((previous forms) (stop? #f) (parsed ())) (do ((op #f) (clause #f) (remains #f)) ((or (null? forms) stop?)) (set! op (legal-in-conditional? (car forms) ops)) (if (not op) (loop-error ops previous "'" (car forms) "' is not conditional operator.")) ;(multiple-value-setq ; (clause remains) ; ( (cadr op) forms (append clauses parsed) ops)) (call-with-values (lambda () ( (cadr op) forms (append clauses parsed) ops)) (lambda (a b) (set! clause a) (set! remains b))) ;(format-logged #t "~%after call clause=~s forms=~S" clause forms) (set! parsed (append parsed (list clause))) (set! previous forms) (set! forms remains) (if (not (null? forms)) (if (eq? (car forms) 'and) (begin (set! forms (cdr forms)) (if (null? forms) (loop-error ops previous "Missing 'and' clause."))) (if (eq? (car forms) 'else) (set! stop? #t) (if (loop-op? (car forms) ops) (set! stop? #t)))))) (values parsed forms))) (define (parse-conditional forms clauses ops) (let ((ops (cons '(else ) ops)) (save forms) (oper (car forms)) (loop (list)) ; avoid () because of acl bug (expr (list)) (then (list)) (else (list))) (if (null? (cdr forms)) (loop-error ops save "Missing '" oper "' expression.")) (set! forms (cdr forms)) (set! expr (pop forms)) (if (null? forms) (loop-error ops forms "Missing conditional clause.")) (if (eq? oper 'unless) (set! expr (list 'not expr))) (call-with-values (lambda () (parse-then-else-dependents forms clauses ops)) (lambda (a b) (set! then a) (set! forms b))) ;; combine dependant clauses if more than one (if (not (null? (cdr then))) (set! then (gather-clauses (list) then)) (set! then (car then))) (loop-operator-set! then 'if) ;; this (if ...) is hacked so that it is a newly ;; allocated list. otherwise acl and clisp have a ;; nasty structure sharing problem. (set! loop (list 'if expr (append `(begin ,@(loop-looping then)) (list)) #f)) (if (and (not (null? forms)) (eq? (car forms) 'else)) (begin (set! forms (cdr forms)) (when (null? forms) (loop-error ops save "Missing 'else' clause.")) (call-with-values (lambda () (parse-then-else-dependents forms (append clauses (list then)) ops)) (lambda (a b) (set! else a) (set! forms b))) (if (not (null? (cdr else))) (set! else (gather-clauses () else)) (set! else (car else))) (set-car! (cdddr loop) `(begin ,@(loop-looping else))) ;; flush loop forms so we dont gather actions. (loop-looping-set! then ()) (loop-looping-set! else ()) (set! then (gather-clauses 'if (list then else))))) (loop-looping-set! then (list loop)) (values then forms))) (define (parse-clauses forms cond? ops) (if (or (null? forms) (not (symbol? (car forms)))) (list (make-loop-clause 'operator 'do 'looping forms)) (let ((op-type? (lambda (op type) (and (not (null? (cddr op))) (eq? (caddr op) type))))) (let ((previous forms) (clauses ())) (do ((op #f) (clause #f) (remains ()) (body ()) ) ((null? forms)) (if (and cond? (eq? (car forms) 'and)) (pop forms)) (set! op (loop-op? (car forms) ops)) (if (not op) (loop-error ops previous "Found '" (car forms) "' where operator expected.")) ;(multiple-value-setq (clause remains) ; ((cadr op) forms clauses ops)) (call-with-values (lambda () ( (cadr op) forms clauses ops)) (lambda (a b) (set! clause a) (set! remains b))) (if (op-type? op 'task) (set! body op) (if (op-type? op 'iter) (if (not (null? body)) (loop-error ops previous "'" (car op) "' clause cannot follow '" (car body) "'.")))) (set! previous forms) (set! forms remains) (set! clauses (append clauses (list clause)))) clauses)))) (define (parse-iteration caller forms ops) (gather-clauses caller (parse-clauses forms () ops))) ;; ;; loop implementation ;; (define *loop-operators* ;; each clause is ( . ) (list (list 'with (function parse-with) #f) (list 'initially (function parse-initially) #f) (list 'repeat (function parse-repeat) 'iter) (list 'for (function parse-for) 'iter (list 'from (function parse-numerical-for)) (list 'downfrom (function parse-numerical-for)) (list 'below (function parse-numerical-for)) (list 'to (function parse-numerical-for)) (list 'above (function parse-numerical-for)) (list 'downto (function parse-numerical-for)) (list 'in (function parse-sequence-iteration)) (list 'on (function parse-sequence-iteration)) (list 'across (function parse-sequence-iteration)) (list '= (function parse-general-iteration))) (list 'as (function parse-for) 'iter) (list 'do (function parse-do) 'task) (list 'collect (function parse-accumulation) 'task) (list 'append (function parse-accumulation) 'task) (list 'nconc (function parse-accumulation) 'task) (list 'sum (function parse-accumulation) 'task) (list 'count (function parse-accumulation) 'task) (list 'minimize (function parse-accumulation) 'task) (list 'maximize (function parse-accumulation) 'task) (list 'thereis (function parse-thereis) 'task (function loop-return)) (list 'always (function parse-thereis) 'task (function loop-return)) (list 'never (function parse-thereis) 'task (function loop-return)) (list 'return (function parse-return) 'task (function loop-return)) (list 'while (function parse-while-until) #f ) (list 'until (function parse-while-until) #f ) (list 'when (function parse-conditional) 'task) (list 'unless (function parse-conditional) 'task) (list 'if (function parse-conditional) 'task) (list 'finally (function parse-finally) #f))) ;; ;; loop expansions for scheme and cltl2 ;; (define (scheme-loop forms) (let ((name (gensym "v")) (parsed (parse-iteration 'loop forms *loop-operators*)) (end-test ()) (done '(go #t)) ; :done (return #f)) ;(write (list :parsed-> parsed)) ;; cltl2's loop needs a way to stop iteration from with the run ;; block (the done form) and/or immediately return a value ;; (the return form). scheme doesnt have a block return or a ;; go/tagbody mechanism these conditions are implemented using ;; continuations. The forms that done and return expand to are ;; not hardwired into the code because this utility is also used ;; by CM's 'process' macro. Instead, the done and return forms ;; are returned by functions assocated with the relevant operator ;; data. For example, the function that returns the return form ;; is stored as the fourth element in the return operator data. ;; and the done function is stored in the while and until op data. ;; the cadddr of the RETURN operator is a function that ;; provides the form for immediately returning a value ;; from the iteration. (let ((returnfn (cadddr (assoc 'return *loop-operators*)))) (set! return (returnfn (if (null? (loop-returning parsed)) #f (car (loop-returning parsed)))))) ;; combine any end-tests into a single IF expression ;; that calls the (done) continuation if true. multiple ;; tests are OR'ed togther (set! end-test (let ((ends (loop-end-tests parsed))) (if (null? ends) () (list `(if ,(if (null? (cdr ends)) (car ends) (cons 'or ends)) ;; calls the done continuation ,done #f))))) `(let (,@ (loop-bindings parsed)) ,@(loop-initially parsed) (call-with-exit (lambda (return) ; <- (return) returns from this lambda (call-with-exit (lambda (go) ; <- (go #t) returns from this lambda ;; a named let provides the actual looping mechanism. ;; the various tests and actions may exit via the ;; (done) or (return) continuations. (let ,name () ,@end-test ,@(loop-looping parsed) ,@(loop-stepping parsed) (,name)))) ;; this is the lexical point for (go #t) continuation. ,@(loop-finally parsed) ;; invoke the RETURN continuation with loop value or #f ,return))))) (scheme-loop args))) ;; ;; loop tests. ;; (test (loop for i below 10 collect i) '(0 1 2 3 4 5 6 7 8 9)) (test (loop for i to 10 sum i) 55) (test (loop for i downto -10 count (even? i)) 6) (test (loop for x in '(0 1 2 3 4 5 6 7 8 9) by 'cddr collect x) '(0 2 4 6 8)) (test (loop for x on '(0 1 2 3) by 'cddr collect x) '((0 1 2 3) (2 3))) (test (loop for x in '(0 1 2 3 4 5 6 7 8 9) thereis (= x 4)) #t) (test (loop for x in '(0 1 2 3 4 5 6 7 8 9) never (= x 4)) #f) (test (loop for x in '(0 1 2 3 4 5 6 7 8 9) never (= x 40)) #t) (test (loop for x in '(0 2 3 4 5 6 7 8 9) always (< x 40)) #t) (test (loop repeat 10 with x = 0 collect x do (set! x (+ x 1))) '(0 1 2 3 4 5 6 7 8 9)) (test (loop repeat 10 for x = #t then (not x) collect x) '(#t #f #t #f #t #f #t #f #t #f)) (test (loop repeat 10 count #t) 10) (test (loop repeat 10 count #f) 0) (test (loop for i to 10 collect i collect (* 2 i)) '(0 0 1 2 2 4 3 6 4 8 5 10 6 12 7 14 8 16 9 18 10 20)) (test (loop for i from -10 to 10 by 2 nconc (list i (- i))) '(-10 10 -8 8 -6 6 -4 4 -2 2 0 0 2 -2 4 -4 6 -6 8 -8 10 -10)) (test (loop for i from -10 downto 10 by -1 collect i) ()) (test (loop for i downfrom 10 downto -10 by 2 collect i) '(10 8 6 4 2 0 -2 -4 -6 -8 -10)) (test (loop for i from 10 to -10 by 1 collect i) ()) (test (loop for i to 10 for j downfrom 10 collect i collect j) '(0 10 1 9 2 8 3 7 4 6 5 5 6 4 7 3 8 2 9 1 10 0)) (test (loop for i below 0 collect i into foo finally (return foo)) ()) (test (loop for i below 0 sum i into foo finally (return foo)) 0) (test (loop for i below 0 maximize i into foo finally (return foo)) #f) (test (loop with a and b = 'x and c = 2 repeat 10 for x = 1 then 'fred collect (list x a b c)) '((1 #f x 2) (fred #f x 2) (fred #f x 2) (fred #f x 2) (fred #f x 2) (fred #f x 2) (fred #f x 2) (fred #f x 2) (fred #f x 2) (fred #f x 2))) (test (loop for i across #(0 1 2 3) append (list i (expt 2 i))) '(0 1 1 2 2 4 3 8)) (test (loop with a = 0 and b = -1 while (< a 10) sum a into foo do (set! a (+ a 1)) finally (return (list foo b))) '(45 -1)) (test (loop for i from 0 until (> i 9) collect i) '(0 1 2 3 4 5 6 7 8 9)) (test (loop for i from 0 while (< i 9) when (even? i) collect i) '(0 2 4 6 8)) (test (loop with l = (list 0) for s in spec for k = s then (+ k s) do (push k l) finally (return l)) 'error) (test (loop with l = (list (encode-interval 'p 1)) for s in spec for k = (interval s) then (transpose k (interval s)) do (push k l) finally (return l)) 'error) ;; end loop ;; more macros from Rick's stuff (define-macro (dolist spec . body) ;; spec = (var list . return) (let ((v (gensym))) `(do ((,v ,(cadr spec) (cdr ,v)) (,(car spec) #f)) ((null? ,v) ,@(cddr spec)) (set! ,(car spec) (car ,v)) ,@body))) (test (let ((sum 0)) (dolist (v (list 1 2 3) sum) (set! sum (+ sum v)))) 6) (define-macro (dotimes spec . body) ;; spec = (var end . return) (let ((e (gensym)) (n (car spec))) `(do ((,e ,(cadr spec)) (,n 0 (+ ,n 1))) ((>= ,n ,e) ,@(cddr spec)) ,@body))) (test (let ((sum 0)) (dotimes (i 3 sum) (set! sum (+ sum i)))) 3) (define-macro (do* spec end . body) `(let* (,@(map (lambda (var) (list (car var) (cadr var))) spec)) (do () ,end ,@body ,@(map (lambda (var) (if (pair? (cddr var)) `(set! ,(car var) ,(caddr var)) (values))) spec)))) (define (1+ x) (+ x 1)) (test (let ((sum 0)) (do* ((i 0 (+ i 1)) (j i (+ i 1))) ((= i 3) sum) (set! sum (+ sum j)))) 5) (test (do* ((a 1 (+ a 1)) (b a)) ((> a 9) b)) 1) (test (let ((a 0)) (do* ((a 1 (+ a 1)) (b a)) ((> a 9) a)) a) 0) (test (do* ((i 0 (1+ i))) ((>= i 10) i)) 10) (test (do* ((i 0 (1+ j)) (j 0 (1+ i))) ((>= i 10) (+ i j))) 23) (test (let ((x ())) (do* ((i 0 (1+ i))) ((>= i 10) x) (set! x (cons i x)))) '(9 8 7 6 5 4 3 2 1 0)) (test (call-with-exit (lambda (return) (do* ((i 0 (1+ i))) () (when (> i 10) (return i))))) 11) (test (do* ((i 0 (+ i 10))) ((> i -1) i) (error 'bad)) 0) (test (do* ((i 0 (1+ i)) (x ())) ((>= i 10) x) (set! x (cons 'a x))) '(a a a a a a a a a a)) (test (let ((i 0)) (do* () ((>= i 10) i) (set! i (+ i 1)))) 10) (test (do* ((i 0 (1+ i))) ((> i 10) (values))) #) (test (+ 1 (do* ((i 0 (1+ i))) ((> i 10) (values i (1+ i))))) 24) (test (do* ((i 0 (1+ i))) ((> i 10) (set! i (+ i 1)) (set! i (+ i 1)) i)) 13) (test (do* ((i 0 (1+ i))) ((> i 10))) ()) (test (map (lambda (f) (f)) (let ((x ())) (do* ((i 0 (+ i 1))) ((= i 5) x) (set! x (cons (lambda () i) x))))) '(5 5 5 5 5)) (test (do* ((lst (list 0 1 2 3 4 5 6 7 8 9) (cdr lst)) (elm (car lst) (and (pair? lst) (car lst))) (n 0 (+ n (or elm 0)))) ((null? lst) n)) 45) (test (do* ((lst (list 0 1 2 3 4 5 6 7 8 9) (cdr lst)) (elm (car lst) (and (pair? lst) (car lst))) (n 0)) ((null? lst) n) (set! n (+ n elm))) 45) (test (let ((vec (vector 0 1 2 3 4 5 6 7 8 9))) (and (null? (do* ((n #f) (i 0 (+ i 1)) (j (- 9 i) (- 9 i))) ((>= i j)) (set! n (vec i)) (set! (vec i) (vec j)) (set! (vec j) n))) (equal? vec #(9 8 7 6 5 4 3 2 1 0)))) #t) (define-macro (fluid-let xexe . body) ;; taken with changes from Teach Yourself Scheme (let ((xx (map car xexe)) (ee (map cadr xexe)) (old-xx (map (lambda (ig) (gensym)) xexe))) `(let ,(map (lambda (old-x x) `(,old-x ,x)) old-xx xx) (dynamic-wind (lambda () #f) (lambda () ,@(map (lambda (x e) `(set! ,x ,e)) xx ee) (let () ,@body)) (lambda () ,@(map (lambda (x old-x) `(set! ,x ,old-x)) xx old-xx)))))) (test (let ((x 32) (y 0)) (define (gx) x) (fluid-let ((x 12)) (set! y (gx))) (list x y)) '(32 12)) (test (let ((x "hi") (y 0) (z '(1 2 3))) (define (gx) (+ x z)) (fluid-let ((x 32) (z (+ 123 (car z)))) (set! y (gx))) (list x y z)) '("hi" 156 (1 2 3))) (test (let ((x 32) (y 0)) (define (gx) x) (call-with-exit (lambda (return) (fluid-let ((x 12)) (set! y (gx)) (return)))) (list x y)) '(32 12)) (test (let ((x 32) (y 0)) (define (gx) x) (let ((x 100)) (fluid-let ((x 12)) (set! y (gx)))) (list x y)) '(32 32)) ;; oops! fluid-let doesn't actually work ;; in CL: (defvar x 32) (let ((y 0)) (defun gx () x) (let ((x 12)) (setf y (gx))) (list x y)) -> '(32 12) ;; (let ((y 0)) (defun gx () x) (let ((x 100)) (let ((x 12)) (setf y (gx)))) (list x y)) -> '(32 12) ;; (let ((y 0)) (defun gx () x) (let ((x 100)) (let ((x 12)) (setf y (gx)) (setf x 123)) (list x y))) -> '(100 12) ! ;; (the defvar makes x dynamic) ;; define** treats args before :optional as required args (define-macro (define** declarations . forms) (let ((name (car declarations)) (args (cdr declarations))) (define (position thing lst count) (if (or (null? lst) (not (pair? (cdr lst)))) #f (if (eq? thing (car lst)) count (position thing (cdr lst) (+ count 1))))) (define (no-opt old-args new-args) (if (null? old-args) (reverse new-args) (no-opt (cdr old-args) (if (eq? (car old-args) :optional) new-args (cons (car old-args) new-args))))) (let ((required-args (position :optional args 0))) (if required-args `(define* (,name . func-args) (if (< (length func-args) ,required-args) (error "~A requires ~D argument~A: ~A" ',name ,required-args (if (> ,required-args 1) "s" "") func-args) (apply (lambda* ,(no-opt args ()) ,@forms) func-args))) `(define* ,declarations ,@forms))))) (let () (define** (f1 a :optional b) (+ a (or b 1))) (test (f1 1) 2) (test (f1 1 2) 3) (test (f1) 'error)) ;; Rick's with-optkeys (define-macro (with-optkeys spec . body) ( (lambda (user rawspec body) (define (string->keyword str) (symbol->keyword (string->symbol str))) (define (key-parse-clause info mode args argn user) ;; return a cond clause that parses one keyword. info for each ;; var is: ( ) (let* ((got (car info)) (var (cadr info)) (key (string->keyword (symbol->string var)))) `((eq? (car ,args) ,key ) (if ,got (error "duplicate keyword: ~S" , key)) (set! ,var (if (null? (cdr ,args)) (error "missing value for keyword: ~S" , user) (cadr ,args))) (set! ,got #t) ; mark that we have a value for this param (set! ,mode #t) ; mark that we are now parsing keywords (set! ,argn (+ ,argn 1)) (set! ,args (cddr ,args))))) (define (pos-parse-clause info mode args argn I) ;; return a cond clause that parses one positional. info for ;; each var is: ( ) (let ((got (car info)) (var (cadr info))) `((= ,argn ,I) (set! ,var (car ,args)) (set! ,got #t) ; mark that we have a value for this param (set! ,argn (+ ,argn 1)) (set! ,args (cdr ,args))))) (let* ((otherkeys? (member '&allow-other-keys rawspec)) ;; remove &allow-other-keys from spec (spec (if otherkeys? (reverse (cdr (reverse rawspec))) rawspec)) (data (map (lambda (v) ;; for each optkey variable v return a list ;; ( ) where the ;; variable indicates that has been ;; set, is the optkey variable itself ;; and is its default value (if (pair? v) (cons (gensym (symbol->string (car v))) v) (list (gensym (symbol->string v)) v #f))) spec)) (args (gensym "args")) ; holds arg data as its parsed (argn (gensym "argn")) (SIZE (length data)) (mode (gensym "keyp")) ; true if parsing keywords ;; keyc are cond clauses that parse valid keyword (keyc (map (lambda (d) (key-parse-clause d mode args argn user)) data)) (posc (let lup ((tail data) (I 0)) (if (null? tail) (list) (cons (pos-parse-clause (car tail) mode args argn I) (lup (cdr tail) (+ I 1)))))) (bindings (map cdr data)) ; optkey variable bindings ) (if otherkeys? (set! bindings (cons '(&allow-other-keys (list)) bindings))) `(let* ,bindings ; bind all the optkey variables with default values ;; bind status and parsing vars (let ,(append (map (lambda (i) (list (car i) #f)) data) `((,args ,user) (,argn 0) (,mode #f))) ;; iterate arglist and set opt/key values (do () ((null? ,args) #f) (cond ;; add valid keyword clauses first ,@ keyc ;; a keyword in (car args) is now either added to ;; &allow-other-keys or an error , (if otherkeys? `((keyword? (car ,args)) (if (not (pair? (cdr ,args))) (error "missing value for keyword ~S" (car ,args))) (set! &allow-other-keys (append &allow-other-keys (list (car ,args) (cadr ,args)))) (set! ,mode #t) ; parsing keys now... (set! ,args (cddr ,args)) ) `((keyword? (car ,args)) ;(and ,mode (keyword? (car ,args))) (error "invalid keyword: ~S" (car ,args)) ) ) ;; positional clauses illegal if keywords have happened (,mode (error "positional after keywords: ~S" (car ,args))) ;; too many value specified ((not (< ,argn ,SIZE)) (error "too many args: ~S" , args)) ;; add the valid positional clauses ,@ posc )) ,@ body)) )) (car spec) (cdr spec) body )) (test (let ((args '(1 2 3))) (with-optkeys (args a b c) (list a b c))) '(1 2 3)) (test (let ((args '(1 2 3 4))) (with-optkeys (args a b c) (list a b c))) 'error) (test (let ((args '(1 2))) (with-optkeys (args a b (c 33)) (list a b c))) '(1 2 33)) (test (let ((args ())) (with-optkeys (args a b (c 33)) (list a b c))) '(#f #f 33)) (test (let ((args '(:b 22))) (with-optkeys (args a b (c 33)) (list a b c))) '(#f 22 33)) (test (let ((args '(-1 :z 22))) (with-optkeys (args a b (c 33)) (list a b c))) 'error) (test (let ((args '(:b 99 :z 22))) (with-optkeys (args a b (c 33)) (list a b c))) 'error) (test (let ((args '(:z 22))) (with-optkeys (args a b (c 33) &allow-other-keys) (list a b c &allow-other-keys))) '(#f #f 33 (:z 22))) (test (let ((args '(:id "0" :inst "flute" :name "Flute"))) (with-optkeys (args id inst &allow-other-keys) (list id inst &allow-other-keys))) '("0" "flute" (:name "Flute"))) (test (let ((args '(:inst "flute" :id "0" :name "Flute"))) (with-optkeys (args id inst &allow-other-keys) (list id inst &allow-other-keys))) '("0" "flute" (:name "Flute"))) (test (let ((args '(:id "0" :name "Flute" :inst "flute"))) (with-optkeys (args id inst &allow-other-keys) (list id inst &allow-other-keys))) '("0" "flute" (:name "Flute"))) (test (let ((args '(:name "Flute" :inst "flute" :id "0"))) (with-optkeys (args id inst &allow-other-keys) (list id inst &allow-other-keys))) '("0" "flute" (:name "Flute"))) (let () ;; some common lispisms ;; where names are the same, but functions are different (abs for example), ;; I'll prepend "cl-" to the CL version; otherwise we end up redefining ;; map and member, for example, which can only cause confusion. ;; ;; also I'm omitting the test-if-not and test-not args which strike me as ridiculous. ;; If CLtL2 says something is deprecated, it's not included. ;; Series and generators are ignored. ;; ;; ... later ... I've run out of gas. ;(define-macro (progn . body) `(let () ,@body)) (define (null obj) (or (not obj) (null? obj))) (define t #t) (define nil ()) (define eq eq?) (define eql eqv?) (define equal equal?) (define (equalp x y) (or (equal x y) (and (char? x) (char? y) (char-ci=? x y)) (and (number? x) (number? y) (= x y)) (and (string? x) (string? y) (string-ci=? x y)))) (define (identity x) x) (define (complement fn) (lambda args (not (apply fn args)))) ;; -------- numbers (define (conjugate z) (complex (real-part z) (- (imag-part z)))) (define zerop zero?) (define oddp odd?) (define evenp even?) (define plusp positive?) (define minusp negative?) (define realpart real-part) (define imagpart imag-part) (define* (float x ignore) (* 1.0 x)) (define rational rationalize) (define mod modulo) (define rem remainder) (define (logtest i1 i2) (not (zero? (logand i1 i2)))) (define (logbitp index integer) (logbit? integer index)) ;(logtest (expt 2 index) integer)) (define (lognand n1 n2) (lognot (logand n1 n2))) (define (lognor n1 n2) (lognot (logior n1 n2))) (define (logandc1 n1 n2) (logand (lognot n1) n2)) (define (logandc2 n1 n2) (logand n1 (lognot n2))) (define (logorc1 n1 n2) (logior (lognot n1) n2)) (define (logorc2 n1 n2) (logior n1 (logior n2))) (define (logeqv . ints) (lognot (apply logxor ints))) ;; from slib (define (logcount n) (define bitwise-bit-count (letrec ((logcnt (lambda (n tot) (if (zero? n) tot (logcnt (quotient n 16) (+ (vector-ref #(0 1 1 2 1 2 2 3 1 2 2 3 2 3 3 4) (modulo n 16)) tot)))))) (lambda (n) (cond ((negative? n) (lognot (logcnt (lognot n) 0))) ((positive? n) (logcnt n 0)) (else 0))))) (cond ((negative? n) (bitwise-bit-count (lognot n))) (else (bitwise-bit-count n)))) (define-constant boole-clr 0) (define-constant boole-set 1) (define-constant boole-1 2) (define-constant boole-2 3) (define-constant boole-c1 4) (define-constant boole-c2 5) (define-constant boole-and 6) (define-constant boole-ior 7) (define-constant boole-xor 8) (define-constant boole-eqv 9) (define-constant boole-nand 10) (define-constant boole-nor 11) (define-constant boole-andc1 12) (define-constant boole-andc2 13) (define-constant boole-orc1 14) (define-constant boole-orc2 15) (define (boole op int1 int2) (cond ((= op boole-clr) 0) ((= op boole-set) -1) ;; all ones -- "always 1" is misleading ((= op boole-1) int1) ((= op boole-2) int2) ((= op boole-c1) (lognot int1)) ((= op boole-c2) (lognot int2)) ((= op boole-and) (logand int1 int2)) ((= op boole-ior) (logior int1 int2)) ((= op boole-xor) (logxor int1 int2)) ((= op boole-eqv) (logeqv int1 int2)) ((= op boole-nand) (lognot (logand int1 int2))) ((= op boole-nor) (lognot (logior int1 int2))) ((= op boole-andc1) (logand (lognot int1) int2)) ((= op boole-andc2) (logand int1 (lognot int2))) ((= op boole-orc1) (logior (lognot int1) int2)) ((= op boole-orc2) (logior int1 (lognot int2))))) ;; from Rick (define (byte siz pos) ;; cache size, position and mask. (list siz pos (ash (- (ash 1 siz) 1) pos))) (define byte-size car) (define byte-position cadr) (define byte-mask caddr) (define (ldb bytespec integer) (ash (logand integer (byte-mask bytespec)) (- (byte-position bytespec)))) (define (dpb integer bytespec into) (logior (ash (logand integer (- (ash 1 (byte-size bytespec)) 1)) (byte-position bytespec)) (logand into (lognot (byte-mask bytespec))))) (define (ldb-test byte int) (not (zero? (ldb byte int)))) (define (mask-field byte int) (logand int (dpb -1 byte 0))) (define (deposit-field byte spec int) (logior (logand byte (byte-mask spec)) (logand int (lognot (byte-mask spec))))) (define (scale-float x k) (* x (expt 2.0 k))) ;; from clisp -- can't see any point to most of these (define-constant double-float-epsilon 1.1102230246251568e-16) (define-constant double-float-negative-epsilon 5.551115123125784e-17) (define-constant least-negative-double-float -2.2250738585072014e-308) (define-constant least-negative-long-float -5.676615526003731344e-646456994) (define-constant least-negative-normalized-double-float -2.2250738585072014e-308) (define-constant least-negative-normalized-long-float -5.676615526003731344e-646456994) (define-constant least-negative-normalized-short-float -1.1755e-38) (define-constant least-negative-normalized-single-float -1.1754944e-38) (define-constant least-negative-short-float -1.1755e-38) (define-constant least-negative-single-float -1.1754944e-38) (define-constant least-positive-double-float 2.2250738585072014e-308) (define-constant least-positive-long-float 5.676615526003731344e-646456994) (define-constant least-positive-normalized-double-float 2.2250738585072014e-308) (define-constant least-positive-normalized-long-float 5.676615526003731344e-646456994) (define-constant least-positive-normalized-short-float 1.1755e-38) (define-constant least-positive-normalized-single-float 1.1754944e-38) (define-constant least-positive-short-float 1.1755e-38) (define-constant least-positive-single-float 1.1754944e-38) (define-constant long-float-epsilon 5.4210108624275221706e-20) (define-constant long-float-negative-epsilon 2.7105054312137610853e-20) (define-constant most-negative-double-float -1.7976931348623157e308) ;; most-negative-fixnum (define-constant most-negative-long-float -8.8080652584198167656e646456992) (define-constant most-negative-short-float -3.4028e38) (define-constant most-negative-single-float -3.4028235e38) (define-constant most-positive-double-float 1.7976931348623157e308) ;; most-positive-fixnum (define-constant most-positive-long-float 8.8080652584198167656e646456992) (define-constant most-positive-short-float 3.4028e38) (define-constant most-positive-single-float 3.4028235e38) (define-constant short-float-epsilon 7.6295e-6) (define-constant short-float-negative-epsilon 3.81476e-6) (define-constant single-float-epsilon 5.960465e-8) (define-constant single-float-negative-epsilon 2.9802326e-8) (define (lisp-implementation-type) "s7") (define lisp-implementation-version s7-version) (define (software-type) "s7") (define software-version s7-version) (define (machine-version) (if (and (defined? 'file-exists?) (file-exists? "/proc/cpuinfo")) (call-with-input-file "/proc/cpuinfo" (lambda (cpufile) (do ((line (read-line cpufile) (read-line cpufile))) ((or (eof-object? line) (string=? (substring line 0 10) "model name")) (if (string? line) (string-trim " " (substring line (+ 1 (position #\: line)))) "unknown"))))) "unknown")) ;; = < <= > >= are the same, also min max + - * / lcm gcd exp expt log sqrt ;; sin cos tan acos asin atan pi sinh cosh tanh asinh acosh atanh ;; numerator denominator logior logxor logand ash integer-length random ;; slightly different: floor ceiling truncate round and the ff cases thereof ;; abs of complex -> magnitude (define (cl-abs x) (if (not (zero? (imag-part x))) (magnitude x) (abs x))) ;; these actually return multiple values (define* (cl-floor x (divisor 1)) (floor (/ x divisor))) (define* (cl-ceiling x (divisor 1)) (ceiling (/ x divisor))) (define* (cl-truncate x (divisor 1)) (truncate (/ x divisor))) (define* (cl-round x (divisor 1)) (round (/ x divisor))) (define* (ffloor x divisor) (* 1.0 (cl-floor x divisor))) (define* (fceling x divisor) (* 1.0 (cl-ceiling x divisor))) (define* (ftruncate x divisor) (* 1.0 (cl-truncate x divisor))) (define* (fround x divisor) (* 1.0 (cl-round x divisor))) (define (/= . args) (if (null? (cdr args)) #t (if (member (car args) (cdr args)) #f (apply /= (cdr args))))) (define (1- x) (- x 1)) (define (isqrt x) (floor (sqrt x))) (define phase angle) (define* (complex rl (im 0.0)) (complex rl im)) (define (signum x) (if (zerop x) x (/ x (abs x)))) (define (cis x) (exp (complex 0.0 x))) ;; -------- characters (define char-code-limit 256) (define alpha-char-p char-alphabetic?) (define upper-case-p char-upper-case?) (define lower-case-p char-lower-case?) (define* (digit-char-p c (radix 10)) (string->number (string c) radix)) (define (alphanumericp c) (or (char-alphabetic? c) (char-numeric? c))) (define* (char= . args) (or (< (length args) 2) (apply char=? args))) (define* (char< . args) (or (< (length args) 2) (apply char . args) (or (< (length args) 2) (apply char>? args))) (define* (char>= . args) (or (< (length args) 2) (apply char>=? args))) (define* (char-equal . args) (or (< (length args) 2) (apply char-ci=? args))) (define* (char-lessp . args) (or (< (length args) 2) (apply char-ci? args))) (define* (char-not-lessp . args) (or (< (length args) 2) (apply char-ci>=? args))) (define* (char-not-greaterp . args) (or (< (length args) 2) (apply char-ci<=? args))) (define (char/= . args) (if (null? (cdr args)) #t (if (member (car args) (cdr args)) #f (apply char/= (cdr args))))) (define (char-not-equal . args) (if (null? (cdr args)) #t (if (or (member (char-upcase (car args)) (cdr args)) (member (char-downcase (car args)) (cdr args))) #f (apply char-not-equal (cdr args))))) (define char-code char->integer) (define code-char integer->char) (define (character c) (if (char? c) c (if (integer? c) (integer->char c) (if (string? c) (c 0) (if (symbol? c) ((symbol->string c) 0)))))) ;; char-upcase and char-downcase are ok (define char-int char->integer) (define int-char integer->char) (define* (digit-char w (radix 10)) (let ((str (number->string w radix))) (and str (= (length str) 1) (str 0)))) (define (both-case-p c) "unimplemented") (define (standard-char-p c) "unimplemented") (define (char-name c) "unimplemented") (define (name-char s) "unimplemented") ;; -------- (define terpri newline) ;; -------- types (define vectorp vector?) (define simple-vector-p vector?) (define symbolp symbol?) (define (atom obj) (not (pair? obj))) (define consp pair?) (define (listp obj) (or (null? obj) (pair? obj))) (define numberp number?) (define integerp integer?) (define rationalp rational?) (define (floatp l) (and (number? l) (not (rational? l)) (zero? (imag-part l)))) ; clisp (define (complexp l) (and (complex? l) (not (real? l)))) (define realp real?) (define characterp char?) (define stringp string?) (define simple-string-p string?) (define arrayp vector?) (define simple-bit-vector-p vector?) (define keywordp keyword?) (define functionp procedure?) (define symbol-value symbol->value) (define symbol-function symbol->value) (define fdefinition symbol->value) (define boundp defined?) (define fboundp defined?) (define (funcall fn . arguments) (apply fn arguments)) (define-constant call-arguments-limit 65536) ;; -------- (define progn begin) (define-macro (prog1 first . body) (let ((result (gensym))) `(let ((,result ,first)) ,@body ,result))) (define-macro (prog2 first second . body) `(prog1 (progn ,first ,second) ,@body)) (define-macro (the type form) form) (define-macro (defvar var . args) `(define ,var (or ,(and (not (null? args)) (car args)) #f))) (define-macro* (incf sym (inc 1)) `(set! ,sym (+ ,sym ,inc))) (define-macro* (decf sym (dec 1)) `(set! ,sym (- ,sym ,dec))) ;; the simple version seems to work ok, but just for lafs: (define incf-b (let ((arg (gensym)) (inc (gensym)) (name (gensym))) (apply define-bacro* `((,name ,arg (,inc 1)) `(set! ,,arg (+ ,,arg ,,inc)))))) (define-macro (push val sym) `(setf ,sym (cons ,val ,sym))) (define-macro (pop sym) (let ((v (gensym))) `(let ((,v (car ,sym))) (setf ,sym (cdr ,sym)) ,v))) (define-macro* (pushnew val sym (test equal?) (key identity)) (let ((g (gensym)) (k (if (procedure? key) key identity))) ; can be explicit nil! `(let ((,g ,val)) (if (null? (cl-member (,k ,g) ,sym ,test ,k)) (push ,g ,sym)) ,sym))) (define-macro (declare . args) #f) (define-macro (set a b) `(set! ,(symbol->value a) ,b)) (define-macro (setf . pairs) (if (not (even? (length pairs))) (error "setf has odd number of args")) `(let () ,@(let ((var #f)) (map (lambda (p) (if var (let ((val (if (pair? var) (if (member (car var) '(aref svref elt char schar)) (list 'set! (cdr var) p) (if (eq? (car var) 'car) (list 'set-car! (cadr var) p) (if (eq? (car var) 'cdr) (list 'set-cdr! (cadr var) p) (if (eq? (car var) 'nth) (list 'set! (list (caddr var) (cadr var)) p) (list 'set! var p) )))) (list 'set! var p)))) (set! var #f) val) (begin (set! var p) ()))) pairs)))) (define-macro (setq . pairs) (if (not (even? (length pairs))) (error "setq has odd number of args")) `(let () ,@(let ((var #f)) (map (lambda (p) (if var (let ((val (list 'set! var p))) (set! var #f) val) (begin (set! var p) ()))) pairs)))) (define-macro (psetq . pairs) (let ((vals ()) (vars ())) (do ((var-val pairs (cddr var-val))) ((null? var-val)) (let ((interval (gensym))) (set! vals (cons (list interval (cadr var-val)) vals)) (set! vars (cons (list 'set! (car var-val) interval) vars)))) `(let ,(reverse vals) ,@vars))) (define (mapcar func . lists) ;; not scheme's map because lists can be different lengths ;; and args can be any sequence type (all mixed together) (define (mapcar-seqs func seqs) (if (null? seqs) () (cons (func (car seqs)) (mapcar-seqs func (cdr seqs))))) (define (mapcar-1 index lens func seqs) (if (member index lens) () (cons (apply func (mapcar-seqs (lambda (obj) (obj index)) seqs)) (mapcar-1 (+ index 1) lens func seqs)))) (let ((lens (map length lists))) (mapcar-1 0 lens func lists))) ;; (define (mapcar func . lists) ;; not scheme's map because lists can be different lengths ;; (if (member () lists) () (cons (apply func (map car lists)) (apply mapcar func (map cdr lists))))) (define (maplist function . lists) (if (member () lists) () (cons (apply function lists) (apply maplist function (map cdr lists))))) (define (mapc function . lists) (define (mapc-1 function . lists) (if (not (member () lists)) (begin (apply function (map car lists)) (apply mapc-1 function (map cdr lists))))) (apply mapc-1 function lists) (car lists)) (define (mapl function . lists) (define (mapl-1 function . lists) (if (not (member () lists)) (begin (apply function lists) (apply mapl-1 function (map cdr lists))))) (apply mapl-1 function lists) (car lists)) (define (mapcon function . lists) (apply nconc (apply maplist function lists))) (define (mapcan function . lists) (apply nconc (apply mapcar function lists))) (define* (map-into result-sequence function . sequences) (if (or (null? result-sequence) (null? sequences)) result-sequence (let* ((vals (apply mapcar function sequences)) (len (min (length vals) (length result-sequence)))) (do ((i 0 (+ i 1))) ((= i len)) (set! (result-sequence i) (vals i))) result-sequence))) (define input-stream-p input-port?) (define output-stream-p output-port?) ;; -------- vectors ;; vector is ok (define svref vector-ref) (define aref vector-ref) (define array-dimensions vector-dimensions) (define array-total-size vector-length) (define (array-dimension array num) (list-ref (vector-dimensions array) num)) (define-constant array-dimension-limit 16777215) (define-constant array-rank-limit 4096) (define-constant array-total-size-limit 16777215) (define* (make-array dimensions element-type initial-element initial-contents adjustable fill-pointer displaced-to displaced-index-offset) (if (eq? element-type 'character) (or (and initial-contents (string-copy initial-contents)) (cl-make-string dimensions initial-element)) (make-vector (or dimensions 1) initial-element))) (define (array-in-bounds-p array . subscripts) (define (in-bounds dims subs) (or (null? subs) (null? dims) (and (< (car subs) (car dims)) (in-bounds (cdr dims) (cdr subs))))) (in-bounds (vector-dimensions array) subscripts)) (define (row-major-index array . subscripts) (apply + (maplist (lambda (x y) (* (car x) (apply * (cdr y)))) subscripts (vector-dimensions array)))) ;; -------- lists ;; in CL (cdr ()) is nil (define (first l) (if (not (null? l)) (list-ref l 0) ())) (define (second l) (if (> (length l) 1) (list-ref l 1) ())) (define (third l) (if (> (length l) 2) (list-ref l 2) ())) (define (fourth l) (if (> (length l) 3) (list-ref l 3) ())) (define (fifth l) (if (> (length l) 4) (list-ref l 4) ())) (define (sixth l) (if (> (length l) 5) (list-ref l 5) ())) (define (seventh l) (if (> (length l) 6) (list-ref l 6) ())) (define (eighth l) (if (> (length l) 7) (list-ref l 7) ())) (define (ninth l) (if (> (length l) 8) (list-ref l 8) ())) (define (tenth l) (if (> (length l) 9) (list-ref l 9) ())) (define (nth n l) (if (< n (length l)) (list-ref l n) ())) (define (endp val) (if (null? val) #t (if (pair? val) #f (error "bad arg to endp")))) (define rest cdr) (define list-length length) (define* (cl-make-list size (initial-element ())) (make-list size initial-element)) (define (copy-list lis) (if (not (pair? lis)) lis (cons (car lis) (copy-list (cdr lis))))) (define (rplaca x y) (set-car! x y) x) (define (rplacd x y) (set-cdr! x y) x) (define (copy-tree lis) (if (pair? lis) (cons (copy-tree (car lis)) (copy-tree (cdr lis))) lis)) (define* (butlast lis (n 1)) (let ((len (length lis))) (if (<= len n) () (let ((result ())) (do ((i 0 (+ i 1)) (lst lis (cdr lst))) ((= i (- len n)) (reverse result)) (set! result (cons (car lst) result))))))) (define* (last lst (n 1)) (let ((len (length lst))) (do ((i 0 (+ i 1)) (l lst (cdr l))) ((or (null? l) (>= i (- len n))) l)))) (define (nthcdr n lst) (do ((i n (- i 1)) (result lst (cdr result))) ((or (null? result) (zero? i)) result))) (define* (tree-equal a b (test eql)) (define (teq a b) (if (not (pair? a)) (and (not (pair? b)) (test a b)) (and (pair? b) (teq (car a) (car b)) (teq (cdr a) (cdr b))))) (teq a b)) (define (acons key datum alist) (cons (cons key datum) alist)) (define (list* obj1 . objs) (define (list-1 obj) (if (null? (cdr obj)) (car obj) (cons (car obj) (list-1 (cdr obj))))) (if (null? objs) obj1 (cons obj1 (list-1 objs)))) (define* (assoc-if predicate alist (key car)) (if (null? alist) () (if (and (not (null? (car alist))) (predicate (key (car alist)))) (car alist) (assoc-if predicate (cdr alist) key)))) (define* (assoc-if-not predicate alist (key car)) (assoc-if (lambda (obj) (not (predicate obj))) alist key)) (define* (cl-assoc item alist (test eql) (key car)) (assoc-if (lambda (obj) (test item obj)) alist key)) (define* (rassoc-if predicate alist (key cdr)) (if (null? alist) () (if (and (pair? (car alist)) (predicate (key (car alist)))) (car alist) (rassoc-if predicate (cdr alist) key)))) (define* (rassoc-if-not predicate alist (key cdr)) (rassoc-if (lambda (obj) (not (predicate obj))) alist key)) (define* (rassoc item alist (test eql) (key cdr)) (rassoc-if (lambda (obj) (test item obj)) alist key)) (define (copy-alist alist) (if (null? alist) () (cons (if (pair? (car alist)) (cons (caar alist) (cdar alist)) (car alist)) (copy-alist (cdr alist))))) (define (revappend x y) (append (reverse x) y)) (define* (pairlis keys data alist) (if (not (= (length keys) (length data))) (error "pairlis keys and data lists should have the same length")) (let ((lst (or alist ()))) (if (null? keys) lst (do ((key keys (cdr key)) (datum data (cdr datum))) ((null? key) lst) (set! lst (cons (cons (car key) (car datum)) lst)))))) (define* (sublis alist tree (test eql) (key car)) (let ((val (cl-assoc tree alist test key))) (if (not (null? val)) (cdr val) (if (not (pair? tree)) tree (cons (sublis alist (car tree) test key) (sublis alist (cdr tree) test key)))))) (define* (nsublis alist tree (test eql) (key car)) ; sacla (define (sub subtree) (let ((ac (cl-assoc subtree alist test key))) (if (not (null? ac)) (cdr ac) (if (not (pair? subtree)) subtree (let () (set-car! subtree (sub (car subtree))) (set-cdr! subtree (sub (cdr subtree))) subtree))))) (sub tree)) (let () (define* (subst-if new test tree (key identity)) (if (test (key tree)) new (if (not (pair? tree)) tree (cons (subst-if new test (car tree) key) (subst-if new test (cdr tree) key))))) (define* (subst-if-not new test tree (key identity)) (subst-if new (lambda (obj) (not (test obj))) tree key)) (define* (subst new old tree (test eql) (key identity)) (subst-if new (lambda (obj) (test old obj)) tree key)) (define* (nsubst-if new predicate tree (key identity)) ; sacla (define (sub subtree) (if (predicate (key subtree)) new (if (not (pair? subtree)) subtree (let () (set-car! subtree (sub (car subtree))) (set-cdr! subtree (sub (cdr subtree))) subtree)))) (sub tree)) (define* (nsubst-if-not new predicate tree (key identity)) (nsubst-if new (lambda (obj) (not (predicate obj))) tree key)) (define* (nsubst new old tree (test eql) (key identity)) (nsubst-if new (lambda (obj) (test old obj)) tree key)) (test-t (let ((tree '(old (old) ((old))))) (equal (subst 'new 'old tree) '(new (new) ((new)))))) (test-t (eq (subst 'new 'old 'old) 'new)) (test-t (eq (subst 'new 'old 'not-old) 'not-old)) (test-t (equal (subst 'new '(b) '(a ((b))) :test equal) '(a (new)))) (test-t (equal (subst 'x 3 '(1 (1 2) (1 2 3) (1 2 3 4)) :key (lambda (y) (and (listp y) (third y)))) '(1 (1 2) x x))) (test-t (equal (subst 'x "D" '("a" ("a" "b") ("a" "b" "c") ("a" "b" "c" "d")) :test equalp :key (lambda (y) (and (listp y) (fourth y)))) '("a" ("a" "b") ("a" "b" "c") x))) (test-t (equal (subst-if 'new (lambda (x) (eq x 'old)) '(old old)) '(new new))) (test-t (eq (subst-if 'new (lambda (x) (eq x 'old)) 'old) 'new)) (test-t (equal (subst-if 'x (lambda (x) (eql x 3)) '(1 (1 2) (1 2 3) (1 2 3 4)) :key (lambda (y) (and (listp y) (third y)))) '(1 (1 2) x x))) (test-t (let ((tree '(old (old) ((old))))) (equal (subst-if 'new (lambda (x) (eq x 'old)) tree) '(new (new) ((new)))))) (test-t (eq (subst-if 'new (lambda (x) (eq x 'old)) 'old) 'new)) (test-t (eq (subst-if 'new (lambda (x) (eq x 'old)) 'not-old) 'not-old)) (test-t (equal (subst-if 'new (lambda (x) (equal x '(b))) '(a ((b)))) '(a (new)))) (test-t (equal (subst-if 'x (lambda (x) (eql x 3)) '(1 (1 2) (1 2 3) (1 2 3 4)) :key (lambda (y) (and (listp y) (third y)))) '(1 (1 2) x x))) (test-t (equal (subst-if 'x (lambda (x) (equalp x "D")) '("a" ("a" "b") ("a" "b" "c") ("a" "b" "c" "d")) :key (lambda (y) (and (listp y) (fourth y)))) '("a" ("a" "b") ("a" "b" "c") x))) (test-t (equal (subst-if-not 'new (lambda (x) (not (eq x 'old))) '(old old)) '(new new))) (test-t (eq (subst-if-not 'new (lambda (x) (not (eq x 'old))) 'old) 'new)) (test-t (equal (subst-if-not 'x (lambda (x) (not (eql x 3))) '(1 (1 2) (1 2 3) (1 2 3 4)) :key (lambda (y) (and (listp y) (third y)))) '(1 (1 2) x x))) (test-t (let ((tree '(old (old) ((old))))) (equal (subst-if-not 'new (lambda (x) (not (eq x 'old))) tree) '(new (new) ((new)))))) (test-t (eq (subst-if-not 'new (lambda (x) (not (eq x 'old))) 'old) 'new)) (test-t (eq (subst-if-not 'new (lambda (x) (not (eq x 'old))) 'not-old) 'not-old)) (test-t (equal (subst-if-not 'new (lambda (x) (not (equal x '(b)))) '(a ((b)))) '(a (new)))) (test-t (equal (subst-if-not 'x (lambda (x) (not (eql x 3))) '(1 (1 2) (1 2 3) (1 2 3 4)) :key (lambda (y) (and (listp y) (third y)))) '(1 (1 2) x x))) (test-t (equal (subst-if-not 'x (lambda (x) (not (equalp x "D"))) '("a" ("a" "b") ("a" "b" "c") ("a" "b" "c" "d")) :key (lambda (y) (and (listp y) (fourth y)))) '("a" ("a" "b") ("a" "b" "c") x))) (test-t (let ((tree '(old (old) ((old))))) (equal (nsubst 'new 'old (copy-tree tree)) '(new (new) ((new)))))) (test-t (let* ((tree (copy-tree '(old (old) ((old))))) (new-tree (nsubst 'new 'old tree))) (and (eq tree new-tree) (equal tree '(new (new) ((new))))))) (test-t (eq (nsubst 'new 'old 'old) 'new)) (test-t (eq (nsubst 'new 'old 'not-old) 'not-old)) (test-t (equal (nsubst 'new '(b) (copy-tree '(a ((b)))) :test equal) '(a (new)))) (test-t (equal (nsubst 'x 3 (copy-tree '(1 (1 2) (1 2 3) (1 2 3 4))) :key (lambda (y) (and (listp y) (third y)))) '(1 (1 2) x x))) (test-t (equal (nsubst 'x "D" (copy-tree '("a" ("a" "b") ("a" "b" "c") ("a" "b" "c" "d"))) :test equalp :key (lambda (y) (and (listp y) (fourth y)))) '("a" ("a" "b") ("a" "b" "c") x))) (test-t (equal (nsubst-if 'new (lambda (x) (eq x 'old)) (list 'old 'old)) '(new new))) (test-t (eq (nsubst-if 'new (lambda (x) (eq x 'old)) 'old) 'new)) (test-t (let* ((x (copy-tree '(old (old) ((old)) (old) old))) (y (nsubst-if 'new (lambda (x) (eq x 'old)) x))) (and (eq x y) (equal x '(new (new) ((new)) (new) new))))) (test-t (equal (nsubst-if 'x (lambda (x) (eql x 3)) (copy-tree '(1 (1 2) (1 2 3) (1 2 3 4))) :key (lambda (y) (and (listp y) (third y)))) '(1 (1 2) x x))) (test-t (let ((tree '(old (old) ((old))))) (equal (nsubst-if 'new (lambda (x) (eq x 'old)) (copy-tree tree)) '(new (new) ((new)))))) (test-t (eq (nsubst-if 'new (lambda (x) (eq x 'old)) 'old) 'new)) (test-t (eq (nsubst-if 'new (lambda (x) (eq x 'old)) 'not-old) 'not-old)) (test-t (equal (nsubst-if 'new (lambda (x) (equal x '(b))) (copy-tree '(a ((b))))) '(a (new)))) (test-t (equal (nsubst-if 'x (lambda (x) (eql x 3)) (copy-tree '(1 (1 2) (1 2 3) (1 2 3 4))) :key (lambda (y) (and (listp y) (third y)))) '(1 (1 2) x x))) (test-t (equal (nsubst-if 'x (lambda (x) (equalp x "D")) (copy-tree '("a" ("a" "b") ("a" "b" "c") ("a" "b" "c" "d"))) :key (lambda (y) (and (listp y) (fourth y)))) '("a" ("a" "b") ("a" "b" "c") x))) (test-t (equal (nsubst-if-not 'new (lambda (x) (not (eq x 'old))) (list 'old 'old)) '(new new))) (test-t (eq (nsubst-if-not 'new (lambda (x) (not (eq x 'old))) 'old) 'new)) (test-t (let* ((x (copy-tree '(old (old) ((old)) (old) old))) (y (nsubst-if-not 'new (lambda (x) (not (eq x 'old))) x))) (and (eq x y) (equal x '(new (new) ((new)) (new) new))))) (test-t (equal (nsubst-if-not 'x (lambda (x) (not (eql x 3))) (copy-tree '(1 (1 2) (1 2 3) (1 2 3 4))) :key (lambda (y) (and (listp y) (third y)))) '(1 (1 2) x x))) (test-t (let ((tree '(old (old) ((old))))) (equal (nsubst-if-not 'new (lambda (x) (not (eq x 'old))) (copy-tree tree)) '(new (new) ((new)))))) (test-t (eq (nsubst-if-not 'new (lambda (x) (not (eq x 'old))) 'old) 'new)) (test-t (eq (nsubst-if-not 'new (lambda (x) (not (eq x 'old))) 'not-old) 'not-old)) (test-t (equal (nsubst-if-not 'new (lambda (x) (not (equal x '(b)))) (copy-tree '(a ((b))))) '(a (new)))) (test-t (equal (nsubst-if-not 'x (lambda (x) (not (eql x 3))) (copy-tree '(1 (1 2) (1 2 3) (1 2 3 4))) :key (lambda (y) (and (listp y) (third y)))) '(1 (1 2) x x))) (test-t (equal (nsubst-if-not 'x (lambda (x) (not (equalp x "D"))) (copy-tree '("a" ("a" "b") ("a" "b" "c") ("a" "b" "c" "d"))) :key (lambda (y) (and (listp y) (fourth y)))) '("a" ("a" "b") ("a" "b" "c") x))) ) (define (ldiff lst object) ; sacla (if (not (eqv? lst object)) (let* ((result (list (car lst))) (splice result)) (call-with-exit (lambda (return) (do ((l (cdr lst) (cdr l))) ((not (pair? l)) (if (eql l object) (set-cdr! splice ())) result) (if (eqv? l object) (return result) (set! splice (cdr (rplacd splice (list (car l)))))))))) ())) (define* (member-if predicate list (key identity)) (if (null? list) () (if (predicate (key (car list))) list (member-if predicate (cdr list) key)))) (define* (member-if-not predicate list (key identity)) (member-if (lambda (obj) (not (predicate obj))) list key)) (define* (cl-member item list (test eql) (key identity)) (if (null? list) () (if (test item (key (car list))) list (cl-member item (cdr list) test key)))) (define* (adjoin item list (test eql) (key identity)) (if (not (null? (cl-member (key item) list test key))) list (cons item list))) (define (tailp sublist list) (or (eq? sublist list) (and (not (null? list)) (tailp sublist (cdr list))))) (define* (nbutlast list (n 1)) ; sacla (if (null? list) () (let ((length (do ((p (cdr list) (cdr p)) (i 1 (+ i 1))) ((not (pair? p)) i)))) (if (> length n) (do ((1st (cdr list) (cdr 1st)) (2nd list 1st) (count (- length n 1) (- count 1))) ((zero? count) (set-cdr! 2nd ()) list)) ())))) (define (nconc . lists) ; sacla sort of (let ((ls (let () (define (strip-nulls lst) (if (null? lst) () (if (null? (car lst)) (strip-nulls (cdr lst)) lst))) (strip-nulls lists)))) (if (null? ls) () (let* ((top (car ls)) (splice top)) (do ((here (cdr ls) (cdr here))) ((null? here) top) (set-cdr! (last splice) (car here)) (if (not (null? (car here))) (set! splice (car here)))))))) (define (nreconc x y) (nconc (nreverse x) y)) ;; -------- sequences (define-macro (with-iterator it . body) `(let ((,(car it) (let ((f (make-iterator ,(cadr it))) (iterator? #t)) (lambda () (let ((val (f))) (and val (values #t (car val) (cdr val)))))))) ,@body)) (define hash-table-p hash-table?) (define* (gethash k h (d ())) (or (hash-table-ref k h) d)) (define maphash map) (define clrhash fill!) (define hash-table-count hash-table-entries) (let () (define* (count-if predicate sequence from-end (start 0) end (key identity)) (let* ((counts 0) (len (length sequence)) (nd (or (and (number? end) end) len))) ; up to but not including end (if (< nd start) (error "count-if :start ~A is greater than ~A ~A" start (if end ":end" "length") nd)) (if (not from-end) (do ((i start (+ i 1))) ((= i nd)) (if (predicate (key (sequence i))) (set! counts (+ counts 1)))) (do ((i (- nd 1) (- i 1))) ((< i start)) (if (predicate (key (sequence i))) (set! counts (+ counts 1))))) counts)) (define* (count-if-not predicate sequence from-end (start 0) end (key identity)) (count-if (lambda (obj) (not (predicate obj))) sequence from-end start end key)) (define* (count item sequence from-end (test eql) (start 0) end (key identity)) (count-if (lambda (arg) (test item arg)) sequence from-end start end key)) (test-t (eql (count-if-not oddp '((1) (2) (3) (4)) :key car) 2)) (test-t (eql (count-if upper-case-p "The Crying of Lot 49" :start 4) 2)) ;(test-t (eql (count #\a (concatenate 'list "how many A's are there in here?")) 2)) (test-t (eql (count-if alpha-char-p "-a-b-c-0-1-2-3-4-") 3)) (test-t (eql (count-if alphanumericp "-a-b-c-0-1-2-3-4-") 8)) (test-t (eql (count nil (list t nil t nil t nil)) 3)) (test-t (eql (count nil (vector t nil t nil t nil)) 3)) (test-t (zerop (count 9 '(0 1 2 3 4)))) (test-t (zerop (count 'a '(0 1 2 3 4)))) (test-t (eql (count 0 '(0 0 0 0 0) :start 1) 4)) (test-t (eql (count 0 '(0 0 0 0 0) :start 1 :end nil) 4)) (test-t (eql (count 0 '(0 0 0 0 0) :start 2) 3)) (test-t (zerop (count 0 '(0 0 0 0) :start 0 :end 0))) (test-t (zerop (count 0 '(0 0 0 0) :start 2 :end 2))) (test-t (zerop (count 0 '(0 0 0 0) :start 4 :end 4))) (test-t (eql (count 0 '(0 0 0 0) :start 2 :end 3) 1)) (test-t (eql (count #\a "abcABC" :test equalp) 2)) (test-t (eql (count #\a "abcABC" :test char-equal) 2)) (test-t (eql (count '(a) '((x) (y) (z) (a) (b) (c)) :test equalp) 1)) (test-t (eql (count 'a '((x) (y) (z) (a) (b) (c)) :key car :test eq) 1)) (test-t (eql (count nil '((x . x) (y) (z . z) (a) (b . b) (c)) :key cdr :test eq) 3)) (test-t (let ((list nil)) (and (eql (count 'a '(a b c d) :test (lambda (a b) (setq list (cons b list)) (eq a b))) 1) (equal list '(d c b a))))) (test-t (let ((list nil)) (and (eql (count 'a '(a b c d) :test (lambda (a b) (setq list (cons b list)) (eq a b)) :from-end t) 1) (equal list '(a b c d))))) (test-t (zerop (count 9 #(0 1 2 3 4)))) (test-t (zerop (count 'a #(0 1 2 3 4)))) (test-t (eql (count 0 #(0 0 0 0 0) :start 1) 4)) (test-t (eql (count 0 #(0 0 0 0 0) :start 1 :end nil) 4)) (test-t (eql (count 0 #(0 0 0 0 0) :start 2) 3)) (test-t (zerop (count 0 #(0 0 0 0) :start 0 :end 0))) (test-t (zerop (count 0 #(0 0 0 0) :start 2 :end 2))) (test-t (zerop (count 0 #(0 0 0 0) :start 4 :end 4))) (test-t (eql (count 0 #(0 0 0 0) :start 2 :end 3) 1)) (test-t (eql (count '(a) #((x) (y) (z) (a) (b) (c)) :test equalp) 1)) (test-t (eql (count 'a #((x) (y) (z) (a) (b) (c)) :key car :test eq) 1)) (test-t (eql (count nil #((x . x) (y) (z . z) (a) (b . b) (c)) :key cdr :test eq) 3)) (test-t (let ((list nil)) (and (eql (count 'a #(a b c d) :test (lambda (a b) (setq list (cons b list)) (eq a b))) 1) (equal list '(d c b a))))) (test-t (let ((list nil)) (and (eql (count 'a #(a b c d) :test (lambda (a b) (setq list (cons b list)) (eq a b)) :from-end t) 1) (equal list '(a b c d))))) (test-t (eql (count-if null (list t nil t nil t nil)) 3)) (test-t (zerop (count-if (lambda (x) (eql x 9)) #(0 1 2 3 4)))) (test-t (zerop (count-if (lambda (a) (eq 'x a)) #(0 1 2 3 4)))) (test-t (eql (count-if zerop '(0 0 0 0 0) :start 1) 4)) (test-t (eql (count-if zerop '(0 0 0 0 0) :start 1 :end nil) 4)) (test-t (eql (count-if zerop '(0 0 0 0 0) :start 2) 3)) (test-t (zerop (count-if zerop '(0 0 0 0) :start 0 :end 0))) (test-t (zerop (count-if zerop '(0 0 0 0) :start 2 :end 2))) (test-t (zerop (count-if zerop '(0 0 0 0) :start 4 :end 4))) (test-t (eql (count-if zerop '(0 0 0 0) :start 2 :end 3) 1)) (test-t (eql (count-if (lambda (x) (equalp #\a x)) "abcABC") 2)) (test-t (eql (count-if (lambda (x) (char-equal #\a x)) "abcABC") 2)) (test-t (eql (count-if (lambda (x) (equal x '(a))) '((x) (y) (z) (a) (b) (c))) 1)) (test-t (eql (count-if (lambda (x) (eq x 'a)) '((x) (y) (z) (a) (b) (c)) :key car) 1)) (test-t (eql (count-if null '((x . x) (y) (z . z) (a) (b . b) (c)) :key cdr) 3)) (test-t (eql (count-if (lambda (x) (equal x '(a))) '((x) (y) (z) (a) (b) (c))) 1)) (test-t (eql (count-if (lambda (x) (eq x 'a)) '((x) (y) (z) (a) (b) (c)) :key car) 1)) (test-t (eql (count-if null '((x . x) (y) (z . z) (a) (b . b) (c)) :key cdr) 3)) (test-t (let ((list nil)) (and (eql (count-if (lambda (x) (setq list (cons x list)) (eq x 'a)) '(a b c d)) 1) (equal list '(d c b a))))) (test-t (let ((list nil)) (and (eql (count-if (lambda (x) (setq list (cons x list)) (eq x 'a)) '(a b c d) :from-end t) 1) (equal list '(a b c d))))) (test-t (eql (count-if null (vector t nil t nil t nil)) 3)) (test-t (eql (count-if zerop #(0 0 0 0 0) :start 1) 4)) (test-t (eql (count-if zerop #(0 0 0 0 0) :start 1 :end nil) 4)) (test-t (eql (count-if zerop #(0 0 0 0 0) :start 2) 3)) (test-t (zerop (count-if zerop #(0 0 0 0) :start 0 :end 0))) (test-t (zerop (count-if zerop #(0 0 0 0) :start 2 :end 2))) (test-t (zerop (count-if zerop #(0 0 0 0) :start 4 :end 4))) (test-t (eql (count-if zerop #(0 0 0 0) :start 2 :end 3) 1)) (test-t (eql (count-if (lambda (x) (equal x '(a))) #((x) (y) (z) (a) (b) (c))) 1)) (test-t (eql (count-if (lambda (x) (eq x 'a)) #((x) (y) (z) (a) (b) (c)) :key car) 1)) (test-t (eql (count-if null #((x . x) (y) (z . z) (a) (b . b) (c)) :key cdr) 3)) (test-t (eql (count-if (lambda (x) (equal x '(a))) #((x) (y) (z) (a) (b) (c))) 1)) (test-t (eql (count-if (lambda (x) (eq x 'a)) #((x) (y) (z) (a) (b) (c)) :key car) 1)) (test-t (eql (count-if null #((x . x) (y) (z . z) (a) (b . b) (c)) :key cdr) 3)) (test-t (let ((list nil)) (and (eql (count-if (lambda (x) (setq list (cons x list)) (eq x 'a)) #(a b c d)) 1) (equal list '(d c b a))))) (test-t (let ((list nil)) (and (eql (count-if (lambda (x) (setq list (cons x list)) (eq x 'a)) #(a b c d) :from-end t) 1) (equal list '(a b c d))))) (test-t (eql (count-if-not (complement null) (list t nil t nil t nil)) 3)) (test-t (zerop (count-if-not (lambda (x) (not (eql x 9))) #(0 1 2 3 4)))) (test-t (zerop (count-if-not (lambda (a) (not (eq 'x a))) #(0 1 2 3 4)))) (test-t (eql (count-if-not (complement zerop) '(0 0 0 0 0) :start 1) 4)) (test-t (eql (count-if-not (complement zerop) '(0 0 0 0 0) :start 1 :end nil) 4)) (test-t (eql (count-if-not (complement zerop) '(0 0 0 0 0) :start 2) 3)) (test-t (zerop (count-if-not (complement zerop) '(0 0 0 0) :start 0 :end 0))) (test-t (zerop (count-if-not (complement zerop) '(0 0 0 0) :start 2 :end 2))) (test-t (zerop (count-if-not (complement zerop) '(0 0 0 0) :start 4 :end 4))) (test-t (eql (count-if-not (complement zerop) '(0 0 0 0) :start 2 :end 3) 1)) (test-t (eql (count-if-not (lambda (x) (not (equalp #\a x))) "abcABC") 2)) (test-t (eql (count-if-not (lambda (x) (not (char-equal #\a x))) "abcABC") 2)) (test-t (eql (count-if-not (lambda (x) (not (equal x '(a)))) '((x) (y) (z) (a) (b) (c))) 1)) (test-t (eql (count-if-not (lambda (x) (not (eq x 'a))) '((x) (y) (z) (a) (b) (c)) :key car) 1)) (test-t (eql (count-if-not (complement null) '((x . x) (y) (z . z) (a) (b . b) (c)) :key cdr) 3)) (test-t (eql (count-if-not (lambda (x) (not (equal x '(a)))) '((x) (y) (z) (a) (b) (c))) 1)) (test-t (eql (count-if-not (lambda (x) (not (eq x 'a))) '((x) (y) (z) (a) (b) (c)) :key car) 1)) (test-t (eql (count-if-not (complement null) '((x . x) (y) (z . z) (a) (b . b) (c)) :key cdr) 3)) (test-t (let ((list nil)) (and (eql (count-if-not (lambda (x) (setq list (cons x list)) (not (eq x 'a))) '(a b c d)) 1) (equal list '(d c b a))))) (test-t (let ((list nil)) (and (eql (count-if-not (lambda (x) (setq list (cons x list)) (not (eq x 'a))) '(a b c d) :from-end t) 1) (equal list '(a b c d))))) (test-t (eql (count-if-not (complement null) (vector t nil t nil t nil)) 3)) (test-t (eql (count-if-not (complement zerop) #(0 0 0 0 0) :start 1) 4)) (test-t (eql (count-if-not (complement zerop) #(0 0 0 0 0) :start 1 :end nil) 4)) (test-t (eql (count-if-not (complement zerop) #(0 0 0 0 0) :start 2) 3)) (test-t (zerop (count-if-not (complement zerop) #(0 0 0 0) :start 0 :end 0))) (test-t (zerop (count-if-not (complement zerop) #(0 0 0 0) :start 2 :end 2))) (test-t (zerop (count-if-not (complement zerop) #(0 0 0 0) :start 4 :end 4))) (test-t (eql (count-if-not (complement zerop) #(0 0 0 0) :start 2 :end 3) 1)) (test-t (eql (count-if-not (lambda (x) (not (equal x '(a)))) #((x) (y) (z) (a) (b) (c))) 1)) (test-t (eql (count-if-not (lambda (x) (not (eq x 'a))) #((x) (y) (z) (a) (b) (c)) :key car) 1)) (test-t (eql (count-if-not (complement null) #((x . x) (y) (z . z) (a) (b . b) (c)) :key cdr) 3)) (test-t (eql (count-if-not (lambda (x) (not (equal x '(a)))) #((x) (y) (z) (a) (b) (c))) 1)) (test-t (eql (count-if-not (lambda (x) (not (eq x 'a))) #((x) (y) (z) (a) (b) (c)) :key car) 1)) (test-t (eql (count-if-not (complement null) #((x . x) (y) (z . z) (a) (b . b) (c)) :key cdr) 3)) (test-t (let ((list nil)) (and (eql (count-if-not (lambda (x) (setq list (cons x list)) (not (eq x 'a))) #(a b c d)) 1) (equal list '(d c b a))))) (test-t (let ((list nil)) (and (eql (count-if-not (lambda (x) (setq list (cons x list)) (not (eq x 'a))) #(a b c d) :from-end t) 1) (equal list '(a b c d))))) (test (count-if zero? '(0 1 2 0)) 2) (test (count-if-not zero? '(0 1 2 0 3)) 3) (test (count-if zero? #(0 1 2 0)) 2) (test (count-if zero? '((0 1) (1 0) (2 3) (0 1)) :key car) 2) (test (count-if zero? '(0 1 2 0) :from-end #t) 2) (test (count-if zero? '(0 1 2 0) :start 1) 1) (test (count-if zero? '(0 1 2 0) :start 1 :end 3) 0) (test (count-if zero? '(0 1 2 0) :end 3) 1) (test (count-if zero? '(0 1 2 0) :end 4) 2) (test (count-if zero? '(0 1 2 0) :end 4 :from-end #t) 2) (test-t (eql (count #\a "how many A's are there in here?") 2)) ) (define* (find-if predicate sequence from-end (start 0) end (key identity)) (let* ((len (length sequence)) (nd (or (and (number? end) end) len))) ; up to but not including end (if (< nd start) (error "~A :start ~A is greater than ~A ~A" __func__ start (if end ":end" "length") nd)) (call-with-exit (lambda (return) (if (not from-end) (do ((i start (+ i 1))) ((= i nd) #f) (if (predicate (key (sequence i))) (return (sequence i)))) (do ((i (- nd 1) (- i 1))) ((< i start) #f) (if (predicate (key (sequence i))) (return (sequence i))))))))) (define* (find item sequence from-end (test eql) (start 0) end (key identity)) (find-if (lambda (arg) (test item arg)) sequence from-end start end key)) (let () (define* (find-if-not predicate sequence from-end (start 0) end (key identity)) (find-if (lambda (obj) (not (predicate obj))) sequence from-end start end key)) (test-t (eq (find-if-not (lambda (x) (not (eq x 'a))) '(a b c)) 'a)) (test-t (eq (find-if-not (lambda (x) (not (eq x 'b))) '(a b c)) 'b)) (test-t (eq (find-if-not (lambda (x) (not (eq x 'c))) '(a b c)) 'c)) (test-t (null (find-if-not (lambda (arg) (not (eq arg 'x))) '(a b c)))) (test-t (null (find-if-not (lambda (x) (not (eq x 'a))) '(a b c) :start 1))) (test-t (null (find-if-not (lambda (x) (not (eq x 'b))) '(a b c) :start 2))) (test-t (null (find-if-not (lambda (x) (not (eq x 'c))) '(a b c) :start 3))) (test-t (null (find-if-not (lambda (x) (not (eq x 'a))) '(a b c) :start 0 :end 0))) (test-t (null (find-if-not (lambda (x) (not (eq x 'a))) '(a b c) :start 0 :end 0 :from-end t))) (test-t (null (find-if-not (lambda (x) (not (eq x 'a))) '(a b c) :start 1 :end 1))) (test-t (null (find-if-not (lambda (x) (not (eq x 'a))) '(a b c) :start 1 :end 1 :from-end t))) (test-t (null (find-if-not (lambda (x) (not (eq x 'a))) '(a b c) :start 2 :end 2))) (test-t (null (find-if-not (lambda (x) (not (eq x 'a))) '(a b c) :start 2 :end 2 :from-end t))) (test-t (null (find-if-not (lambda (x) (not (eq x 'a))) '(a b c) :start 3 :end 3))) (test-t (null (find-if-not (lambda (x) (not (eq x 'a))) '(a b c) :start 3 :end 3 :from-end t))) (test-t (eq (find-if-not (lambda (x) (not (eq x 'a))) '(a b c) :end nil) 'a)) (test-t (eq (find-if-not (lambda (x) (not (eq x 'b))) '(a b c) :end nil) 'b)) (test-t (eq (find-if-not (lambda (x) (not (eq x 'c))) '(a b c) :end nil) 'c)) (test-t (eq (find-if-not (lambda (x) (not (eq x 'a))) '(a b c) :end 1) 'a)) (test-t (eq (find-if-not (lambda (x) (not (eq x 'b))) '(a b c) :end 2) 'b)) (test-t (eq (find-if-not (lambda (x) (not (eq x 'c))) '(a b c) :end 3) 'c)) (test-t (null (find-if-not (lambda (x) (not (eq x 'a))) '(a b c) :end 0))) (test-t (null (find-if-not (lambda (x) (not (eq x 'b))) '(a b c) :end 1))) (test-t (null (find-if-not (lambda (x) (not (eq x 'c))) '(a b c) :end 2))) (test-t (null (find-if-not (lambda (x) (not (eq x 'a))) '((a) (b) (c))))) (test-t (equal (find-if-not (lambda (x) (not (eq x 'a))) '((a) (b) (c)) :key car) '(a))) (test-t (equal (find-if-not (lambda (x) (not (eq x 'b))) '((a) (b) (c)) :key car) '(b))) (test-t (equal (find-if-not (lambda (x) (not (eq x 'c))) '((a) (b) (c)) :key car) '(c))) (test-t (null (find-if-not (lambda (x) (not (eq x 'z))) '((a) (b) (c)) :key car))) (test-t (let ((list '((a) (b) (c)))) (and (eq (find-if-not (lambda (x) (not (eq x 'a))) list :key car) (car list)) (eq (find-if-not (lambda (x) (not (eq x 'b))) list :key car) (cadr list)) (eq (find-if-not (lambda (x) (not (eq x 'c))) list :key car) (caddr list)) (null (find-if-not (lambda (x) (not (eq x 'z))) list :key car))))) (test-t (equal (find-if-not (lambda (x) (not (eq x 'a))) '((a) (b) (c) (a a) (b b) (c c)) :key car) '(a))) (test-t (equal (find-if-not (lambda (x) (not (eq x 'a))) '((a) (b) (c) (a a) (b b) (c c)) :key car :from-end t) '(a a))) (test-t (equal (find-if-not (lambda (x) (not (eq x 'b))) '((a) (b) (c) (a a) (b b) (c c)) :key car) '(b))) (test-t (equal (find-if-not (lambda (x) (not (eq x 'b))) '((a) (b) (c) (a a) (b b) (c c)) :key car :from-end t) '(b b))) (test-t (equal (find-if-not (lambda (x) (not (eq x 'c))) '((a) (b) (c) (a a) (b b) (c c)) :key car) '(c))) (test-t (equal (find-if-not (lambda (x) (not (eq x 'c))) '((a) (b) (c) (a a) (b b) (c c)) :key car :from-end t) '(c c))) (test-t (null (find-if-not (lambda (x) (not (eq x 'z))) '((a) (b) (c) (a a) (b b) (c c)) :key car))) (test-t (null (find-if-not (lambda (x) (not (eq x 'z))) '((a) (b) (c) (a a) (b b) (c c)) :key car :from-end t))) (test-t (equal (find-if-not (lambda (x) (not (eq x 'a))) '((a) (b) (c) (a a) (b b) (c c) (a a a)) :key car :from-end t) '(a a a))) (test-t (equal (find-if-not (lambda (x) (not (eq x 'a))) '((a) (b) (c) (a a) (b b) (c c) (a a a)) :key car :from-end t :end nil) '(a a a))) (test-t (equal (find-if-not (lambda (x) (not (eq x 'a))) '((a) (b) (c) (a a) (b b) (c c) (a a a)) :key car :from-end t :end 6) '(a a))) (test-t (null (find-if-not (lambda (x) (not (eq x 'a))) '((a) (b) (c) (a a) (b b) (c c) (a a a)) :key car :from-end t :start 1 :end 3))) (test-t (eq (find-if-not (lambda (x) (not (eq x 'a))) #(a b c)) 'a)) (test-t (eq (find-if-not (lambda (x) (not (eq x 'b))) #(a b c)) 'b)) (test-t (eq (find-if-not (lambda (x) (not (eq x 'c))) #(a b c)) 'c)) (test-t (null (find-if-not (lambda (arg) (not (eq arg 'x))) #(a b c)))) (test-t (null (find-if-not (lambda (x) (not (eq x 'a))) #(a b c) :start 1))) (test-t (null (find-if-not (lambda (x) (not (eq x 'b))) #(a b c) :start 2))) (test-t (null (find-if-not (lambda (x) (not (eq x 'c))) #(a b c) :start 3))) (test-t (null (find-if-not (lambda (x) (not (eq x 'a))) #(a b c) :start 0 :end 0))) (test-t (null (find-if-not (lambda (x) (not (eq x 'a))) #(a b c) :start 0 :end 0 :from-end t))) (test-t (null (find-if-not (lambda (x) (not (eq x 'a))) #(a b c) :start 1 :end 1))) (test-t (null (find-if-not (lambda (x) (not (eq x 'a))) #(a b c) :start 1 :end 1 :from-end t))) (test-t (null (find-if-not (lambda (x) (not (eq x 'a))) #(a b c) :start 2 :end 2))) (test-t (null (find-if-not (lambda (x) (not (eq x 'a))) #(a b c) :start 2 :end 2 :from-end t))) (test-t (null (find-if-not (lambda (x) (not (eq x 'a))) #(a b c) :start 3 :end 3))) (test-t (null (find-if-not (lambda (x) (not (eq x 'a))) #(a b c) :start 3 :end 3 :from-end t))) (test-t (eq (find-if-not (lambda (x) (not (eq x 'a))) #(a b c) :end nil) 'a)) (test-t (eq (find-if-not (lambda (x) (not (eq x 'b))) #(a b c) :end nil) 'b)) (test-t (eq (find-if-not (lambda (x) (not (eq x 'c))) #(a b c) :end nil) 'c)) (test-t (eq (find-if-not (lambda (x) (not (eq x 'a))) #(a b c) :end 1) 'a)) (test-t (eq (find-if-not (lambda (x) (not (eq x 'b))) #(a b c) :end 2) 'b)) (test-t (eq (find-if-not (lambda (x) (not (eq x 'c))) #(a b c) :end 3) 'c)) (test-t (null (find-if-not (lambda (x) (not (eq x 'a))) #(a b c) :end 0))) (test-t (null (find-if-not (lambda (x) (not (eq x 'b))) #(a b c) :end 1))) (test-t (null (find-if-not (lambda (x) (not (eq x 'c))) #(a b c) :end 2))) (test-t (null (find-if-not (lambda (x) (not (eq x 'a))) #((a) (b) (c))))) (test-t (equal (find-if-not (lambda (x) (not (eq x 'a))) #((a) (b) (c)) :key car) '(a))) (test-t (equal (find-if-not (lambda (x) (not (eq x 'b))) #((a) (b) (c)) :key car) '(b))) (test-t (equal (find-if-not (lambda (x) (not (eq x 'c))) #((a) (b) (c)) :key car) '(c))) (test-t (null (find-if-not (lambda (x) (not (eq x 'z))) #((a) (b) (c)) :key car))) (test-t (let ((vector #((a) (b) (c)))) (and (eq (find-if-not (lambda (x) (not (eq x 'a))) vector :key car) (aref vector 0)) (eq (find-if-not (lambda (x) (not (eq x 'b))) vector :key car) (aref vector 1)) (eq (find-if-not (lambda (x) (not (eq x 'c))) vector :key car) (aref vector 2)) (null (find-if-not (lambda (x) (not (eq x 'z))) vector :key car))))) (test-t (equal (find-if-not (lambda (x) (not (eq x 'a))) #((a) (b) (c) (a a) (b b) (c c)) :key car) '(a))) (test-t (equal (find-if-not (lambda (x) (not (eq x 'a))) #((a) (b) (c) (a a) (b b) (c c)) :key car :from-end t) '(a a))) (test-t (equal (find-if-not (lambda (x) (not (eq x 'b))) #((a) (b) (c) (a a) (b b) (c c)) :key car) '(b))) (test-t (equal (find-if-not (lambda (x) (not (eq x 'b))) #((a) (b) (c) (a a) (b b) (c c)) :key car :from-end t) '(b b))) (test-t (equal (find-if-not (lambda (x) (not (eq x 'c))) #((a) (b) (c) (a a) (b b) (c c)) :key car) '(c))) (test-t (equal (find-if-not (lambda (x) (not (eq x 'c))) #((a) (b) (c) (a a) (b b) (c c)) :key car :from-end t) '(c c))) (test-t (null (find-if-not (lambda (x) (not (eq x 'z))) #((a) (b) (c) (a a) (b b) (c c)) :key car))) (test-t (null (find-if-not (lambda (x) (not (eq x 'z))) #((a) (b) (c) (a a) (b b) (c c)) :key car :from-end t))) (test-t (equal (find-if-not (lambda (x) (not (eq x 'a))) #((a) (b) (c) (a a) (b b) (c c) (a a a)) :key car :from-end t) '(a a a))) (test-t (equal (find-if-not (lambda (x) (not (eq x 'a))) #((a) (b) (c) (a a) (b b) (c c) (a a a)) :key car :from-end t :end nil) '(a a a))) (test-t (equal (find-if-not (lambda (x) (not (eq x 'a))) #((a) (b) (c) (a a) (b b) (c c) (a a a)) :key car :from-end t :end 6) '(a a))) (test-t (null (find-if-not (lambda (x) (not (eq x 'a))) #((a) (b) (c) (a a) (b b) (c c) (a a a)) :key car :from-end t :start 1 :end 3))) ) (let () (define* (position-if predicate sequence from-end (start 0) end (key identity)) (let* ((len (length sequence)) (nd (or (and (number? end) end) len))) ; up to but not including end (if (< nd start) (error "~A :start ~A is greater than ~A ~A" __func__ start (if end ":end" "length") nd)) (call-with-exit (lambda (return) (if (not from-end) (do ((i start (+ i 1))) ((= i nd) #f) (if (predicate (key (sequence i))) (return i))) (do ((i (- nd 1) (- i 1))) ((< i start) #f) (if (predicate (key (sequence i))) (return i)))))))) (define* (position-if-not predicate sequence from-end (start 0) end (key identity)) (position-if (lambda (obj) (not (predicate obj))) sequence from-end start end key)) (define* (position item sequence from-end (test eql) (start 0) end (key identity)) (position-if (lambda (arg) (test item arg)) sequence from-end start end key)) (test-t (eql (position #\a "baobab" :from-end t) 4)) (test-t (eql (position-if oddp '((1) (2) (3) (4)) :start 1 :key car) 2)) (test-t (null (position 595 ()))) (test-t (eql (position-if-not integerp '(1 2 3 4 5.0)) 4)) (test-t (eql (position 'a '(a b c)) 0)) (test-t (eql (position 'b '(a b c)) 1)) (test-t (eql (position 'c '(a b c)) 2)) (test-t (null (position 'x '(a b c)))) (test-t (null (position 'a '(a b c) :start 1))) (test-t (null (position 'b '(a b c) :start 2))) (test-t (null (position 'c '(a b c) :start 3))) (test-t (null (position 'a '(a b c) :start 0 :end 0))) (test-t (null (position 'a '(a b c) :start 0 :end 0 :from-end t))) (test-t (null (position 'a '(a b c) :start 1 :end 1))) (test-t (null (position 'a '(a b c) :start 1 :end 1 :from-end t))) (test-t (null (position 'a '(a b c) :start 2 :end 2))) (test-t (null (position 'a '(a b c) :start 2 :end 2 :from-end t))) (test-t (null (position 'a '(a b c) :start 3 :end 3))) (test-t (null (position 'a '(a b c) :start 3 :end 3 :from-end t))) (test-t (eql (position 'a '(a b c) :end nil) '0)) (test-t (eql (position 'b '(a b c) :end nil) '1)) (test-t (eql (position 'c '(a b c) :end nil) '2)) (test-t (eql (position 'a '(a b c) :end 1) '0)) (test-t (eql (position 'b '(a b c) :end 2) '1)) (test-t (eql (position 'c '(a b c) :end 3) '2)) (test-t (null (position 'a '(a b c) :end 0))) (test-t (null (position 'b '(a b c) :end 1))) (test-t (null (position 'c '(a b c) :end 2))) (test-t (null (position 'a '((a) (b) (c))))) (test-t (eql (position 'a '((a) (b) (c)) :key car) 0)) (test-t (eql (position 'b '((a) (b) (c)) :key car) 1)) (test-t (eql (position 'c '((a) (b) (c)) :key car) 2)) (test-t (null (position 'z '((a) (b) (c)) :key car))) (test-t (null (position '(a) '((a) (b) (c))))) (test-t (eql (position '(a) '((a) (b) (c)) :test equal) 0)) (test-t (null (position '("a") '(("a") ("b") ("c"))))) (test-t (eql (position 3 '(0 1 2 3 4 5)) 3)) (test-t (eql (position 3 '(0 1 2 3 4 5) :test <) 4)) (test-t (eql (position 3 '(0 1 2 3 4 5) :test >) 0)) (test-t (eql (position 'a '((a) (b) (c) (a a) (b b) (c c)) :key car) 0)) (test-t (eql (position 'a '((a) (b) (c) (a a) (b b) (c c)) :key car :from-end t) 3)) (test-t (eql (position 'b '((a) (b) (c) (a a) (b b) (c c)) :key car) 1)) (test-t (eql (position 'b '((a) (b) (c) (a a) (b b) (c c)) :key car :from-end t) 4)) (test-t (eql (position 'c '((a) (b) (c) (a a) (b b) (c c)) :key car) 2)) (test-t (eql (position 'c '((a) (b) (c) (a a) (b b) (c c)) :key car :from-end t) 5)) (test-t (null (position 'z '((a) (b) (c) (a a) (b b) (c c)) :key car))) (test-t (null (position 'z '((a) (b) (c) (a a) (b b) (c c)) :key car :from-end t))) (test-t (eql (position 'a '((a) (b) (c) (a a) (b b) (c c) (a a a)) :key car :from-end t) 6)) (test-t (eql (position 'a '((a) (b) (c) (a a) (b b) (c c) (a a a)) :key car :from-end t :end nil) 6)) (test-t (eql (position 'a '((a) (b) (c) (a a) (b b) (c c) (a a a)) :key car :from-end t :end 6) 3)) (test-t (null (position 'a '((a) (b) (c) (a a) (b b) (c c) (a a a)) :key car :from-end t :start 1 :end 3))) (test-t (eql (position 'a #(a b c)) 0)) (test-t (eql (position 'b #(a b c)) 1)) (test-t (eql (position 'c #(a b c)) 2)) (test-t (null (position 'x #(a b c)))) (test-t (null (position 'a #(a b c) :start 1))) (test-t (null (position 'b #(a b c) :start 2))) (test-t (null (position 'c #(a b c) :start 3))) (test-t (null (position 'a #(a b c) :start 0 :end 0))) (test-t (null (position 'a #(a b c) :start 0 :end 0 :from-end t))) (test-t (null (position 'a #(a b c) :start 1 :end 1))) (test-t (null (position 'a #(a b c) :start 1 :end 1 :from-end t))) (test-t (null (position 'a #(a b c) :start 2 :end 2))) (test-t (null (position 'a #(a b c) :start 2 :end 2 :from-end t))) (test-t (null (position 'a #(a b c) :start 3 :end 3))) (test-t (null (position 'a #(a b c) :start 3 :end 3 :from-end t))) (test-t (eql (position 'a #(a b c) :end nil) 0)) (test-t (eql (position 'b #(a b c) :end nil) 1)) (test-t (eql (position 'c #(a b c) :end nil) 2)) (test-t (eql (position 'a #(a b c) :end 1) 0)) (test-t (eql (position 'b #(a b c) :end 2) 1)) (test-t (eql (position 'c #(a b c) :end 3) 2)) (test-t (null (position 'a #(a b c) :end 0))) (test-t (null (position 'b #(a b c) :end 1))) (test-t (null (position 'c #(a b c) :end 2))) (test-t (null (position 'a #((a) (b) (c))))) (test-t (eql (position 'a #((a) (b) (c)) :key car) 0)) (test-t (eql (position 'b #((a) (b) (c)) :key car) 1)) (test-t (eql (position 'c #((a) (b) (c)) :key car) 2)) (test-t (null (position 'z #((a) (b) (c)) :key car))) (test-t (null (position '(a) #((a) (b) (c))))) (test-t (eql (position '(a) #((a) (b) (c)) :test equal) 0)) (test-t (null (position '("a") #(("a") ("b") ("c"))))) (test-t (eql (position 3 #(0 1 2 3 4 5)) 3)) (test-t (eql (position 3 #(0 1 2 3 4 5) :test <) 4)) (test-t (eql (position 3 #(0 1 2 3 4 5) :test >) 0)) (test-t (eql (position 'a #((a) (b) (c) (a a) (b b) (c c)) :key car) 0)) (test-t (eql (position 'a #((a) (b) (c) (a a) (b b) (c c)) :key car :from-end t) 3)) (test-t (eql (position 'b #((a) (b) (c) (a a) (b b) (c c)) :key car) 1)) (test-t (eql (position 'b #((a) (b) (c) (a a) (b b) (c c)) :key car :from-end t) 4)) (test-t (eql (position 'c #((a) (b) (c) (a a) (b b) (c c)) :key car) 2)) (test-t (eql (position 'c #((a) (b) (c) (a a) (b b) (c c)) :key car :from-end t) 5)) (test-t (null (position 'z #((a) (b) (c) (a a) (b b) (c c)) :key car))) (test-t (null (position 'z #((a) (b) (c) (a a) (b b) (c c)) :key car :from-end t))) (test-t (eql (position 'a #((a) (b) (c) (a a) (b b) (c c) (a a a)) :key car :from-end t) 6)) (test-t (eql (position 'a #((a) (b) (c) (a a) (b b) (c c) (a a a)) :key car :from-end t :end nil) 6)) (test-t (eql (position 'a #((a) (b) (c) (a a) (b b) (c c) (a a a)) :key car :from-end t :end 6) 3)) (test-t (null (position 'a #((a) (b) (c) (a a) (b b) (c c) (a a a)) :key car :from-end t :start 1 :end 3))) (test-t (null (position #\z "abcABC"))) (test-t (eql (position #\a "abcABC") 0)) (test-t (eql (position #\A "abcABC") 3)) (test-t (eql (position #\A "abcABC" :test char-equal) 0)) (test-t (eql (position #\A "abcABC" :test char-equal :from-end t) 3)) (test-t (eql (position #\a "abcABC" :test char-equal :from-end t) 3)) (test-t (eql (position #\a "abcABC" :test char-equal :from-end t :end 4) 3)) (test-t (eql (position #\a "abcABC" :test char-equal :from-end t :end 3) 0)) (test-t (eql (position-if (lambda (x) (eq x 'a)) '(a b c)) 0)) (test-t (eql (position-if (lambda (x) (eq x 'b)) '(a b c)) 1)) (test-t (eql (position-if (lambda (x) (eq x 'c)) '(a b c)) 2)) (test-t (null (position-if (lambda (arg) (eq arg 'x)) '(a b c)))) (test-t (null (position-if (lambda (x) (eq x 'a)) '(a b c) :start 1))) (test-t (null (position-if (lambda (x) (eq x 'b)) '(a b c) :start 2))) (test-t (null (position-if (lambda (x) (eq x 'c)) '(a b c) :start 3))) (test-t (null (position-if (lambda (x) (eq x 'a)) '(a b c) :start 0 :end 0))) (test-t (null (position-if (lambda (x) (eq x 'a)) '(a b c) :start 0 :end 0 :from-end t))) (test-t (null (position-if (lambda (x) (eq x 'a)) '(a b c) :start 1 :end 1))) (test-t (null (position-if (lambda (x) (eq x 'a)) '(a b c) :start 1 :end 1 :from-end t))) (test-t (null (position-if (lambda (x) (eq x 'a)) '(a b c) :start 2 :end 2))) (test-t (null (position-if (lambda (x) (eq x 'a)) '(a b c) :start 2 :end 2 :from-end t))) (test-t (null (position-if (lambda (x) (eq x 'a)) '(a b c) :start 3 :end 3))) (test-t (null (position-if (lambda (x) (eq x 'a)) '(a b c) :start 3 :end 3 :from-end t))) (test-t (eql (position-if (lambda (x) (eq x 'a)) '(a b c) :end nil) 0)) (test-t (eql (position-if (lambda (x) (eq x 'b)) '(a b c) :end nil) 1)) (test-t (eql (position-if (lambda (x) (eq x 'c)) '(a b c) :end nil) 2)) (test-t (eql (position-if (lambda (x) (eq x 'a)) '(a b c) :end 1) 0)) (test-t (eql (position-if (lambda (x) (eq x 'b)) '(a b c) :end 2) 1)) (test-t (eql (position-if (lambda (x) (eq x 'c)) '(a b c) :end 3) 2)) (test-t (null (position-if (lambda (x) (eq x 'a)) '(a b c) :end 0))) (test-t (null (position-if (lambda (x) (eq x 'b)) '(a b c) :end 1))) (test-t (null (position-if (lambda (x) (eq x 'c)) '(a b c) :end 2))) (test-t (null (position-if (lambda (x) (eq x 'a)) '((a) (b) (c))))) (test-t (eql (position-if (lambda (x) (eq x 'a)) '((a) (b) (c)) :key car) 0)) (test-t (eql (position-if (lambda (x) (eq x 'b)) '((a) (b) (c)) :key car) 1)) (test-t (eql (position-if (lambda (x) (eq x 'c)) '((a) (b) (c)) :key car) 2)) (test-t (null (position-if (lambda (x) (eq x 'z)) '((a) (b) (c)) :key car))) (test-t (eql (position-if (lambda (x) (eq x 'a)) '((a) (b) (c) (a a) (b b) (c c)) :key car) 0)) (test-t (eql (position-if (lambda (x) (eq x 'a)) '((a) (b) (c) (a a) (b b) (c c)) :key car :from-end t) 3)) (test-t (eql (position-if (lambda (x) (eq x 'b)) '((a) (b) (c) (a a) (b b) (c c)) :key car) 1)) (test-t (eql (position-if (lambda (x) (eq x 'b)) '((a) (b) (c) (a a) (b b) (c c)) :key car :from-end t) 4)) (test-t (eql (position-if (lambda (x) (eq x 'c)) '((a) (b) (c) (a a) (b b) (c c)) :key car) 2)) (test-t (eql (position-if (lambda (x) (eq x 'c)) '((a) (b) (c) (a a) (b b) (c c)) :key car :from-end t) 5)) (test-t (null (position-if (lambda (x) (eq x 'z)) '((a) (b) (c) (a a) (b b) (c c)) :key car))) (test-t (null (position-if (lambda (x) (eq x 'z)) '((a) (b) (c) (a a) (b b) (c c)) :key car :from-end t))) (test-t (eql (position-if (lambda (x) (eq x 'a)) '((a) (b) (c) (a a) (b b) (c c) (a a a)) :key car :from-end t) 6)) (test-t (eql (position-if (lambda (x) (eq x 'a)) '((a) (b) (c) (a a) (b b) (c c) (a a a)) :key car :from-end t :end nil) 6)) (test-t (eql (position-if (lambda (x) (eq x 'a)) '((a) (b) (c) (a a) (b b) (c c) (a a a)) :key car :from-end t :end 6) 3)) (test-t (null (position-if (lambda (x) (eq x 'a)) '((a) (b) (c) (a a) (b b) (c c) (a a a)) :key car :from-end t :start 1 :end 3))) (test-t (eql (position-if (lambda (x) (eq x 'a)) #(a b c)) 0)) (test-t (eql (position-if (lambda (x) (eq x 'b)) #(a b c)) 1)) (test-t (eql (position-if (lambda (x) (eq x 'c)) #(a b c)) 2)) (test-t (null (position-if (lambda (arg) (eq arg 'x)) #(a b c)))) (test-t (null (position-if (lambda (x) (eq x 'a)) #(a b c) :start 1))) (test-t (null (position-if (lambda (x) (eq x 'b)) #(a b c) :start 2))) (test-t (null (position-if (lambda (x) (eq x 'c)) #(a b c) :start 3))) (test-t (null (position-if (lambda (x) (eq x 'a)) #(a b c) :start 0 :end 0))) (test-t (null (position-if (lambda (x) (eq x 'a)) #(a b c) :start 0 :end 0 :from-end t))) (test-t (null (position-if (lambda (x) (eq x 'a)) #(a b c) :start 1 :end 1))) (test-t (null (position-if (lambda (x) (eq x 'a)) #(a b c) :start 1 :end 1 :from-end t))) (test-t (null (position-if (lambda (x) (eq x 'a)) #(a b c) :start 2 :end 2))) (test-t (null (position-if (lambda (x) (eq x 'a)) #(a b c) :start 2 :end 2 :from-end t))) (test-t (null (position-if (lambda (x) (eq x 'a)) #(a b c) :start 3 :end 3))) (test-t (null (position-if (lambda (x) (eq x 'a)) #(a b c) :start 3 :end 3 :from-end t))) (test-t (eql (position-if (lambda (x) (eq x 'a)) #(a b c) :end nil) 0)) (test-t (eql (position-if (lambda (x) (eq x 'b)) #(a b c) :end nil) 1)) (test-t (eql (position-if (lambda (x) (eq x 'c)) #(a b c) :end nil) 2)) (test-t (eql (position-if (lambda (x) (eq x 'a)) #(a b c) :end 1) 0)) (test-t (eql (position-if (lambda (x) (eq x 'b)) #(a b c) :end 2) 1)) (test-t (eql (position-if (lambda (x) (eq x 'c)) #(a b c) :end 3) 2)) (test-t (null (position-if (lambda (x) (eq x 'a)) #(a b c) :end 0))) (test-t (null (position-if (lambda (x) (eq x 'b)) #(a b c) :end 1))) (test-t (null (position-if (lambda (x) (eq x 'c)) #(a b c) :end 2))) (test-t (null (position-if (lambda (x) (eq x 'a)) #((a) (b) (c))))) (test-t (eql (position-if (lambda (x) (eq x 'a)) #((a) (b) (c)) :key car) 0)) (test-t (eql (position-if (lambda (x) (eq x 'b)) #((a) (b) (c)) :key car) 1)) (test-t (eql (position-if (lambda (x) (eq x 'c)) #((a) (b) (c)) :key car) 2)) (test-t (null (position-if (lambda (x) (eq x 'z)) #((a) (b) (c)) :key car))) (test-t (eql (position-if (lambda (x) (eq x 'a)) #((a) (b) (c) (a a) (b b) (c c)) :key car) 0)) (test-t (eql (position-if (lambda (x) (eq x 'a)) #((a) (b) (c) (a a) (b b) (c c)) :key car :from-end t) 3)) (test-t (eql (position-if (lambda (x) (eq x 'b)) #((a) (b) (c) (a a) (b b) (c c)) :key car) 1)) (test-t (eql (position-if (lambda (x) (eq x 'b)) #((a) (b) (c) (a a) (b b) (c c)) :key car :from-end t) 4)) (test-t (eql (position-if (lambda (x) (eq x 'c)) #((a) (b) (c) (a a) (b b) (c c)) :key car) 2)) (test-t (eql (position-if (lambda (x) (eq x 'c)) #((a) (b) (c) (a a) (b b) (c c)) :key car :from-end t) 5)) (test-t (null (position-if (lambda (x) (eq x 'z)) #((a) (b) (c) (a a) (b b) (c c)) :key car))) (test-t (null (position-if (lambda (x) (eq x 'z)) #((a) (b) (c) (a a) (b b) (c c)) :key car :from-end t))) (test-t (eql (position-if (lambda (x) (eq x 'a)) #((a) (b) (c) (a a) (b b) (c c) (a a a)) :key car :from-end t) 6)) (test-t (eql (position-if (lambda (x) (eq x 'a)) #((a) (b) (c) (a a) (b b) (c c) (a a a)) :key car :from-end t :end nil) 6)) (test-t (eql (position-if (lambda (x) (eq x 'a)) #((a) (b) (c) (a a) (b b) (c c) (a a a)) :key car :from-end t :end 6) 3)) (test-t (null (position-if (lambda (x) (eq x 'a)) #((a) (b) (c) (a a) (b b) (c c) (a a a)) :key car :from-end t :start 1 :end 3))) (test-t (eql (position-if-not (lambda (x) (not (eq x 'a))) '(a b c)) 0)) (test-t (eql (position-if-not (lambda (x) (not (eq x 'b))) '(a b c)) 1)) (test-t (eql (position-if-not (lambda (x) (not (eq x 'c))) '(a b c)) 2)) (test-t (null (position-if-not (lambda (arg) (not (eq arg 'x))) '(a b c)))) (test-t (null (position-if-not (lambda (x) (not (eq x 'a))) '(a b c) :start 1))) (test-t (null (position-if-not (lambda (x) (not (eq x 'b))) '(a b c) :start 2))) (test-t (null (position-if-not (lambda (x) (not (eq x 'c))) '(a b c) :start 3))) (test-t (null (position-if-not (lambda (x) (not (eq x 'a))) '(a b c) :start 0 :end 0))) (test-t (null (position-if-not (lambda (x) (not (eq x 'a))) '(a b c) :start 0 :end 0 :from-end t))) (test-t (null (position-if-not (lambda (x) (not (eq x 'a))) '(a b c) :start 1 :end 1))) (test-t (null (position-if-not (lambda (x) (not (eq x 'a))) '(a b c) :start 1 :end 1 :from-end t))) (test-t (null (position-if-not (lambda (x) (not (eq x 'a))) '(a b c) :start 2 :end 2))) (test-t (null (position-if-not (lambda (x) (not (eq x 'a))) '(a b c) :start 2 :end 2 :from-end t))) (test-t (null (position-if-not (lambda (x) (not (eq x 'a))) '(a b c) :start 3 :end 3))) (test-t (null (position-if-not (lambda (x) (not (eq x 'a))) '(a b c) :start 3 :end 3 :from-end t))) (test-t (eql (position-if-not (lambda (x) (not (eq x 'a))) '(a b c) :end nil) 0)) (test-t (eql (position-if-not (lambda (x) (not (eq x 'b))) '(a b c) :end nil) 1)) (test-t (eql (position-if-not (lambda (x) (not (eq x 'c))) '(a b c) :end nil) 2)) (test-t (eql (position-if-not (lambda (x) (not (eq x 'a))) '(a b c) :end 1) 0)) (test-t (eql (position-if-not (lambda (x) (not (eq x 'b))) '(a b c) :end 2) 1)) (test-t (eql (position-if-not (lambda (x) (not (eq x 'c))) '(a b c) :end 3) 2)) (test-t (null (position-if-not (lambda (x) (not (eq x 'a))) '(a b c) :end 0))) (test-t (null (position-if-not (lambda (x) (not (eq x 'b))) '(a b c) :end 1))) (test-t (null (position-if-not (lambda (x) (not (eq x 'c))) '(a b c) :end 2))) (test-t (null (position-if-not (lambda (x) (not (eq x 'a))) '((a) (b) (c))))) (test-t (eql (position-if-not (lambda (x) (not (eq x 'a))) '((a) (b) (c)) :key car) 0)) (test-t (eql (position-if-not (lambda (x) (not (eq x 'b))) '((a) (b) (c)) :key car) 1)) (test-t (eql (position-if-not (lambda (x) (not (eq x 'c))) '((a) (b) (c)) :key car) 2)) (test-t (null (position-if-not (lambda (x) (not (eq x 'z))) '((a) (b) (c)) :key car))) (test-t (eql (position-if-not (lambda (x) (not (eq x 'a))) '((a) (b) (c) (a a) (b b) (c c)) :key car) 0)) (test-t (eql (position-if-not (lambda (x) (not (eq x 'a))) '((a) (b) (c) (a a) (b b) (c c)) :key car :from-end t) 3)) (test-t (eql (position-if-not (lambda (x) (not (eq x 'b))) '((a) (b) (c) (a a) (b b) (c c)) :key car) 1)) (test-t (eql (position-if-not (lambda (x) (not (eq x 'b))) '((a) (b) (c) (a a) (b b) (c c)) :key car :from-end t) 4)) (test-t (eql (position-if-not (lambda (x) (not (eq x 'c))) '((a) (b) (c) (a a) (b b) (c c)) :key car) 2)) (test-t (eql (position-if-not (lambda (x) (not (eq x 'c))) '((a) (b) (c) (a a) (b b) (c c)) :key car :from-end t) 5)) (test-t (null (position-if-not (lambda (x) (not (eq x 'z))) '((a) (b) (c) (a a) (b b) (c c)) :key car))) (test-t (null (position-if-not (lambda (x) (not (eq x 'z))) '((a) (b) (c) (a a) (b b) (c c)) :key car :from-end t))) (test-t (eql (position-if-not (lambda (x) (not (eq x 'a))) '((a) (b) (c) (a a) (b b) (c c) (a a a)) :key car :from-end t) 6)) (test-t (eql (position-if-not (lambda (x) (not (eq x 'a))) '((a) (b) (c) (a a) (b b) (c c) (a a a)) :key car :from-end t :end nil) 6)) (test-t (eql (position-if-not (lambda (x) (not (eq x 'a))) '((a) (b) (c) (a a) (b b) (c c) (a a a)) :key car :from-end t :end 6) 3)) (test-t (null (position-if-not (lambda (x) (not (eq x 'a))) '((a) (b) (c) (a a) (b b) (c c) (a a a)) :key car :from-end t :start 1 :end 3))) (test-t (eql (position-if-not (lambda (x) (not (eq x 'a))) #(a b c)) 0)) (test-t (eql (position-if-not (lambda (x) (not (eq x 'b))) #(a b c)) 1)) (test-t (eql (position-if-not (lambda (x) (not (eq x 'c))) #(a b c)) 2)) (test-t (null (position-if-not (lambda (arg) (not (eq arg 'x))) #(a b c)))) (test-t (null (position-if-not (lambda (x) (not (eq x 'a))) #(a b c) :start 1))) (test-t (null (position-if-not (lambda (x) (not (eq x 'b))) #(a b c) :start 2))) (test-t (null (position-if-not (lambda (x) (not (eq x 'c))) #(a b c) :start 3))) (test-t (null (position-if-not (lambda (x) (not (eq x 'a))) #(a b c) :start 0 :end 0))) (test-t (null (position-if-not (lambda (x) (not (eq x 'a))) #(a b c) :start 0 :end 0 :from-end t))) (test-t (null (position-if-not (lambda (x) (not (eq x 'a))) #(a b c) :start 1 :end 1))) (test-t (null (position-if-not (lambda (x) (not (eq x 'a))) #(a b c) :start 1 :end 1 :from-end t))) (test-t (null (position-if-not (lambda (x) (not (eq x 'a))) #(a b c) :start 2 :end 2))) (test-t (null (position-if-not (lambda (x) (not (eq x 'a))) #(a b c) :start 2 :end 2 :from-end t))) (test-t (null (position-if-not (lambda (x) (not (eq x 'a))) #(a b c) :start 3 :end 3))) (test-t (null (position-if-not (lambda (x) (not (eq x 'a))) #(a b c) :start 3 :end 3 :from-end t))) (test-t (eql (position-if-not (lambda (x) (not (eq x 'a))) #(a b c) :end nil) 0)) (test-t (eql (position-if-not (lambda (x) (not (eq x 'b))) #(a b c) :end nil) 1)) (test-t (eql (position-if-not (lambda (x) (not (eq x 'c))) #(a b c) :end nil) 2)) (test-t (eql (position-if-not (lambda (x) (not (eq x 'a))) #(a b c) :end 1) 0)) (test-t (eql (position-if-not (lambda (x) (not (eq x 'b))) #(a b c) :end 2) 1)) (test-t (eql (position-if-not (lambda (x) (not (eq x 'c))) #(a b c) :end 3) 2)) (test-t (null (position-if-not (lambda (x) (not (eq x 'a))) #(a b c) :end 0))) (test-t (null (position-if-not (lambda (x) (not (eq x 'b))) #(a b c) :end 1))) (test-t (null (position-if-not (lambda (x) (not (eq x 'c))) #(a b c) :end 2))) (test-t (null (position-if-not (lambda (x) (not (eq x 'a))) #((a) (b) (c))))) (test-t (eql (position-if-not (lambda (x) (not (eq x 'a))) #((a) (b) (c)) :key car) 0)) (test-t (eql (position-if-not (lambda (x) (not (eq x 'b))) #((a) (b) (c)) :key car) 1)) (test-t (eql (position-if-not (lambda (x) (not (eq x 'c))) #((a) (b) (c)) :key car) 2)) (test-t (null (position-if-not (lambda (x) (not (eq x 'z))) #((a) (b) (c)) :key car))) (test-t (eql (position-if-not (lambda (x) (not (eq x 'a))) #((a) (b) (c) (a a) (b b) (c c)) :key car) 0)) (test-t (eql (position-if-not (lambda (x) (not (eq x 'a))) #((a) (b) (c) (a a) (b b) (c c)) :key car :from-end t) 3)) (test-t (eql (position-if-not (lambda (x) (not (eq x 'b))) #((a) (b) (c) (a a) (b b) (c c)) :key car) 1)) (test-t (eql (position-if-not (lambda (x) (not (eq x 'b))) #((a) (b) (c) (a a) (b b) (c c)) :key car :from-end t) 4)) (test-t (eql (position-if-not (lambda (x) (not (eq x 'c))) #((a) (b) (c) (a a) (b b) (c c)) :key car) 2)) (test-t (eql (position-if-not (lambda (x) (not (eq x 'c))) #((a) (b) (c) (a a) (b b) (c c)) :key car :from-end t) 5)) (test-t (null (position-if-not (lambda (x) (not (eq x 'z))) #((a) (b) (c) (a a) (b b) (c c)) :key car))) (test-t (null (position-if-not (lambda (x) (not (eq x 'z))) #((a) (b) (c) (a a) (b b) (c c)) :key car :from-end t))) (test-t (eql (position-if-not (lambda (x) (not (eq x 'a))) #((a) (b) (c) (a a) (b b) (c c) (a a a)) :key car :from-end t) 6)) (test-t (eql (position-if-not (lambda (x) (not (eq x 'a))) #((a) (b) (c) (a a) (b b) (c c) (a a a)) :key car :from-end t :end nil) 6)) (test-t (eql (position-if-not (lambda (x) (not (eq x 'a))) #((a) (b) (c) (a a) (b b) (c c) (a a a)) :key car :from-end t :end 6) 3)) (test-t (null (position-if-not (lambda (x) (not (eq x 'a))) #((a) (b) (c) (a a) (b b) (c c) (a a a)) :key car :from-end t :start 1 :end 3))) ) (define copy-seq copy) ;; -------- strings (define char string-ref) (define schar string-ref) (define* (cl-make-string size (initial-element #\null)) (make-string size initial-element)) (define (cl-string x) (if (string? x) x (if (char? x) (string x) (if (symbol? x) (symbol->string x) (error "string ~A?" x))))) (define* (string= str-1 str-2 (start1 0) end1 (start2 0) end2) (let* ((str1 (cl-string str-1)) (str2 (cl-string str-2)) (nd1 (if (number? end1) end1 (length str1))) (nd2 (if (number? end2) end2 (length str2)))) (if (and (not end1) (not end2) (= start1 0) (= start2 0)) (string=? str1 str2) (string=? (subseq str1 start1 nd1) (subseq str2 start2 nd2))))) (define* (string-equal str-1 str-2 (start1 0) end1 (start2 0) end2) (let* ((str1 (cl-string str-1)) (str2 (cl-string str-2)) (nd1 (if (number? end1) end1 (length str1))) (nd2 (if (number? end2) end2 (length str2)))) (if (and (not end1) (not end2) (= start1 0) (= start2 0)) (string-ci=? str1 str2) (string-ci=? (subseq str1 start1 nd1) (subseq str2 start2 nd2))))) (define (string-prefixes-equal str1 str2 start1 nd1 start2 nd2) (do ((i start1 (+ i 1)) (j start2 (+ j 1))) ((or (= i nd1) (= j nd2) (not (char=? (str1 i) (str2 j)))) i))) (define (string-prefixes-equal-ci str1 str2 start1 nd1 start2 nd2) (do ((i start1 (+ i 1)) (j start2 (+ j 1))) ((or (= i nd1) (= j nd2) (not (char-ci=? (str1 i) (str2 j)))) i))) (define* (string< str-1 str-2 (start1 0) end1 (start2 0) end2) (let* ((str1 (cl-string str-1)) (str2 (cl-string str-2)) (nd1 (if (number? end1) end1 (length str1))) (nd2 (if (number? end2) end2 (length str2))) (val (if (and (not end1) (not end2) (= start1 0) (= start2 0)) (string str-1 str-2 (start1 0) end1 (start2 0) end2) (let* ((str1 (cl-string str-1)) (str2 (cl-string str-2)) (nd1 (if (number? end1) end1 (length str1))) (nd2 (if (number? end2) end2 (length str2))) (val (if (and (not end1) (not end2) (= start1 0) (= start2 0)) (string>? str1 str2) (string>? (subseq str1 start1 nd1) (subseq str2 start2 nd2))))) (and val (string-prefixes-equal str1 str2 start1 nd1 start2 nd2)))) (define* (string-greaterp str-1 str-2 (start1 0) end1 (start2 0) end2) (let* ((str1 (cl-string str-1)) (str2 (cl-string str-2)) (nd1 (if (number? end1) end1 (length str1))) (nd2 (if (number? end2) end2 (length str2))) (val (if (and (not end1) (not end2) (= start1 0) (= start2 0)) (string-ci>? str1 str2) (string-ci>? (subseq str1 start1 nd1) (subseq str2 start2 nd2))))) (and val (string-prefixes-equal-ci str1 str2 start1 nd1 start2 nd2)))) (define* (string>= str-1 str-2 (start1 0) end1 (start2 0) end2) (let* ((str1 (cl-string str-1)) (str2 (cl-string str-2)) (nd1 (if (number? end1) end1 (length str1))) (nd2 (if (number? end2) end2 (length str2))) (val (if (and (not end1) (not end2) (= start1 0) (= start2 0)) (string>=? str1 str2) (string>=? (subseq str1 start1 nd1) (subseq str2 start2 nd2))))) (and val (string-prefixes-equal str1 str2 start1 nd1 start2 nd2)))) (define* (string-not-lessp str-1 str-2 (start1 0) end1 (start2 0) end2) (let* ((str1 (cl-string str-1)) (str2 (cl-string str-2)) (nd1 (if (number? end1) end1 (length str1))) (nd2 (if (number? end2) end2 (length str2))) (val (if (and (not end1) (not end2) (= start1 0) (= start2 0)) (string-ci>=? str1 str2) (string-ci>=? (subseq str1 start1 nd1) (subseq str2 start2 nd2))))) (and val (string-prefixes-equal-ci str1 str2 start1 nd1 start2 nd2)))) (define* (string/= str-1 str-2 (start1 0) end1 (start2 0) end2) (let* ((str1 (cl-string str-1)) (str2 (cl-string str-2)) (nd1 (if (number? end1) end1 (length str1))) (nd2 (if (number? end2) end2 (length str2))) (val (if (and (not end1) (not end2) (= start1 0) (= start2 0)) (not (string=? str1 str2)) (not (string=? (subseq str1 start1 nd1) (subseq str2 start2 nd2)))))) (and val (string-prefixes-equal str1 str2 start1 nd1 start2 nd2)))) (define* (string-not-equal str-1 str-2 (start1 0) end1 (start2 0) end2) (let* ((str1 (cl-string str-1)) (str2 (cl-string str-2)) (nd1 (if (number? end1) end1 (length str1))) (nd2 (if (number? end2) end2 (length str2))) (val (if (and (not end1) (not end2) (= start1 0) (= start2 0)) (not (string-ci=? str1 str2)) (not (string-ci=? (subseq str1 start1 nd1) (subseq str2 start2 nd2)))))) (and val (string-prefixes-equal-ci str1 str2 start1 nd1 start2 nd2)))) (define (string-left-trim bag str-1) (let ((str (cl-string str-1))) (if (string? bag) (set! bag (string->list bag))) (let ((len (length str))) (do ((i 0 (+ i 1))) ((or (= i len) (not (member (str i) bag))) (if (= i 0) str (subseq str i))))))) (define (string-right-trim bag str-1) (let ((str (cl-string str-1))) (if (string? bag) (set! bag (string->list bag))) (let ((len (length str))) (do ((i (- len 1) (- i 1))) ((or (< i 0) (not (member (str i) bag))) (if (= i (- len 1)) str (subseq str 0 (+ i 1)))))))) (define (string-trim bag str) (string-right-trim bag (string-left-trim bag str))) (define* (nstring-upcase str (start 0) end) (let ((nd (if (number? end) end (length str)))) (do ((i start (+ i 1))) ((= i nd) str) (set! (str i) (char-upcase (str i)))))) (define* (cl-string-upcase str-1 (start 0) end) (let ((str (cl-string str-1))) (nstring-upcase (copy str) start end))) (define* (nstring-downcase str (start 0) end) (let ((nd (if (number? end) end (length str)))) (do ((i start (+ i 1))) ((= i nd) str) (set! (str i) (char-downcase (str i)))))) (define* (cl-string-downcase str-1 (start 0) end) (let ((str (cl-string str-1))) (nstring-downcase (copy str) start end))) (define* (nstring-capitalize str-1 (start 0) end) (define (alpha? c) (or (char-alphabetic? c) (char-numeric? c))) (let ((str (cl-string str-1))) (let ((nd (if (number? end) end (length str)))) (do ((i start (+ i 1))) ((= i nd) str) (if (alpha? (str i)) (if (or (= i 0) (not (alpha? (str (- i 1))))) (set! (str i) (char-upcase (str i))) (set! (str i) (char-downcase (str i))))))))) (define* (string-capitalize str-1 (start 0) end) (let ((str (cl-string str-1))) (nstring-capitalize (copy str) start end))) (let () (define* (union list1 list2 (test eql) (key identity)) (let ((new-list (copy list1))) (do ((obj list2 (cdr obj))) ((null? obj) new-list) (set! new-list (adjoin (car obj) new-list test key))))) (define nunion union) ; this is not required to be destructive (define* (intersection list1 list2 (test eql) (key identity)) (let ((new-list ())) (do ((obj list1 (cdr obj))) ((null? obj) new-list) (if (not (null? (cl-member (key (car obj)) list2 test key))) (set! new-list (adjoin (car obj) new-list test key)))))) (define nintersection intersection) (define* (set-difference list1 list2 (test eql) (key identity)) (let ((new-list ())) (do ((obj list1 (cdr obj))) ((null? obj) new-list) (if (null? (cl-member (key (car obj)) list2 test key)) (set! new-list (adjoin (car obj) new-list test key)))))) (define nset-difference set-difference) (define* (set-exclusive-or list1 list2 (test eql) (key identity)) (let ((new-list ())) (do ((obj list1 (cdr obj))) ((null? obj)) (if (null? (cl-member (key (car obj)) list2 test key)) (set! new-list (adjoin (car obj) new-list test key)))) (do ((obj list2 (cdr obj))) ((null? obj) new-list) (if (null? (cl-member (key (car obj)) list1 test key)) (set! new-list (adjoin (car obj) new-list test key)))))) (define nset-exclusive-or set-exclusive-or) (define* (subsetp list1 list2 (test eql) (key identity)) (call-with-exit (lambda (return) (do ((obj list1 (cdr obj))) ((null? obj) #t) (if (null? (cl-member (key (car obj)) list2 test key)) (return nil)))))) (test-t (subsetp '(1 2 3) '(1 2 3))) (test-t (subsetp '(1 2 3) '(3 2 1))) (test-t (subsetp '(1 2 3) '(2 1 3))) (test-t (null (subsetp '(1 2 3 4) '(2 1 3)))) (test-t (subsetp '(1) '(2 1 3))) (test-t (subsetp '(1 2) '(1 2 3 4 5 6 7 8))) (test-t (subsetp '(1 2 3 4 5) '(8 7 6 5 4 3 2 1))) (test-t (null (subsetp '("car" "ship" "airplane" "submarine") '("car" "ship" "horse" "airplane" "submarine" "camel")))) (test-t (subsetp '("car" "ship" "airplane" "submarine") '("car" "ship" "horse" "airplane" "submarine" "camel") :test equal)) (test-t (subsetp '("CAR" "SHIP" "AIRPLANE" "SUBMARINE") '("car" "ship" "horse" "airplane" "submarine" "camel") :test equalp)) (test-t (subsetp '(("car") ("ship") ("airplane") ("submarine")) '(("car") ("ship") ("horse") ("airplane") ("submarine") ("camel")) :test string= :key car)) (test-t (null (union () ()))) (test-t (null (nunion () ()))) (test-t (null (set-difference (union '(1 2 3) '(2 3 4)) '(1 2 3 4)))) (test-t (null (set-difference (nunion (list 1 2 3) (list 2 3 4)) '(1 2 3 4)))) (test-t (null (set-difference (union '(1 2 3) '(1 2 3)) '(1 2 3)))) (test-t (null (set-difference (nunion (list 1 2 3) (list 1 2 3)) '(1 2 3)))) (test-t (null (set-difference (union '(1) '(3 2 1)) '(1 2 3)))) (test-t (null (set-difference (nunion (list 1) (list 3 2 1)) '(1 2 3)))) (test-t (null (set-difference (union '(1 2 3) ()) '(1 2 3)))) (test-t (null (set-difference (nunion (list 1 2 3) ()) '(1 2 3)))) (test-t (null (set-difference (union () '(1 2 3)) '(1 2 3)))) (test-t (null (set-difference (nunion () (list 1 2 3)) '(1 2 3)))) (test-t (null (set-difference (union '(1 2 3) '(2)) '(1 2 3)))) (test-t (null (set-difference (nunion (list 1 2 3) (list 2)) '(1 2 3)))) (let ((list1 (list 1 1 2 3 4 'a 'b 'c "A" "B" "C" "d")) (list2 (list 1 4 5 'b 'c 'd "a" "B" "c" "D"))) (test-t (null (set-exclusive-or (intersection list1 list2) '(c b 4 1 1)))) (test-t (null (set-exclusive-or (intersection list1 list2 :test equal) '("B" c b 4 1 1) :test equal))) (test-t (null (set-exclusive-or (intersection list1 list2 :test equalp) '("d" "C" "B" "A" c b 4 1 1) :test equalp)))) (test-t (null (intersection '(0 1 2) ()))) (test-t (null (intersection () ()))) (test-t (null (intersection () '(0 1 2)))) (test-t (equal (intersection '(0) '(0)) '(0))) (test-t (equal (intersection '(0 1 2 3) '(2)) '(2))) (test-t (cl-member 0 (intersection '(0 0 0 0 0) '(0 1 2 3 4 5)))) (test-t (null (set-exclusive-or (intersection '(0 1 2 3 4) '(4 3 2 1 0)) '(4 3 2 1 0)))) (test-t (null (set-exclusive-or (intersection '(0 1 2 3 4) '(0 1 2 3 4)) '(0 1 2 3 4)))) (test-t (null (set-exclusive-or (intersection '(0 1 2 3 4) '(4 3 2 1 0)) '(0 1 2 3 4)))) (test-t (let ((list1 (list "A" "B" "C" "d" "e" "F" "G" "h")) (list2 (list "a" "B" "c" "D" "E" "F" "g" "h"))) (null (set-exclusive-or (intersection list1 list2 :test char= :key (lambda (x) (char x 0))) '("B" "F" "h") :test char= :key (lambda (x) (char x 0)))))) (test-t (let ((list1 (list "A" "B" "C" "d" "e" "F" "G" "h")) (list2 (list "a" "B" "c" "D" "E" "F" "g" "h"))) (null (set-exclusive-or (intersection list1 list2 :test char-equal :key (lambda (x) (char x 0))) '("A" "B" "C" "d" "e" "F" "G" "h") :test char-equal :key (lambda (x) (char x 0)))))) (test-t (let ((list1 (list "A" "B" "C" "d")) (list2 (list "D" "E" "F" "g" "h"))) (null (set-exclusive-or (intersection list1 list2 :test char-equal :key (lambda (x) (char x 0))) '("d") :test char-equal :key (lambda (x) (char x 0)))))) (let ((list1 (list 1 1 2 3 4 'a 'b 'c "A" "B" "C" "d")) (list2 (list 1 4 5 'b 'c 'd "a" "B" "c" "D"))) (test-t (null (set-exclusive-or (nintersection (copy-list list1) list2) '(c b 4 1 1)))) (test-t (null (set-exclusive-or (nintersection (copy-list list1) list2 :test equal) '("B" c b 4 1 1) :test equal))) (test-t (null (set-exclusive-or (nintersection (copy-list list1) list2 :test equalp) '("d" "C" "B" "A" c b 4 1 1) :test equalp)))) (test-t (null (nintersection (list 0 1 2) ()))) (test-t (null (nintersection () ()))) (test-t (null (nintersection () '(0 1 2)))) (test-t (equal (nintersection (list 0) '(0)) '(0))) (test-t (equal (nintersection (list 0 1 2 3) '(2)) '(2))) (test-t (cl-member 0 (nintersection (list 0 0 0 0 0) '(0 1 2 3 4 5)))) (test-t (null (set-exclusive-or (nintersection (list 0 1 2 3 4) '(4 3 2 1 0)) '(4 3 2 1 0)))) (test-t (null (set-exclusive-or (nintersection (list 0 1 2 3 4) '(0 1 2 3 4)) '(0 1 2 3 4)))) (test-t (null (set-exclusive-or (nintersection (list 0 1 2 3 4) '(4 3 2 1 0)) '(0 1 2 3 4)))) (test-t (let ((list1 (list "A" "B" "C" "d" "e" "F" "G" "h")) (list2 (list "a" "B" "c" "D" "E" "F" "g" "h"))) (null (set-exclusive-or (nintersection list1 list2 :test char= :key (lambda (x) (char x 0))) '("B" "F" "h") :test char= :key (lambda (x) (char x 0)))))) (test-t (let ((list1 (list "A" "B" "C" "d" "e" "F" "G" "h")) (list2 (list "a" "B" "c" "D" "E" "F" "g" "h"))) (null (set-exclusive-or (nintersection list1 list2 :test char-equal :key (lambda (x) (char x 0))) '("A" "B" "C" "d" "e" "F" "G" "h") :test char-equal :key (lambda (x) (char x 0)))))) (test-t (let ((list1 (list "A" "B" "C" "d")) (list2 (list "D" "E" "F" "g" "h"))) (null (set-exclusive-or (nintersection list1 list2 :test char-equal :key (lambda (x) (char x 0))) '("d") :test char-equal :key (lambda (x) (char x 0)))))) (test-t (null (set-difference (set-difference '(1 2 3 4 5 6 7 8 9) '(2 4 6 8)) '(1 3 5 7 9)))) (test-t (null (nset-difference (set-difference (list 1 2 3 4 5 6 7 8 9) '(2 4 6 8)) '(1 3 5 7 9)))) (test-t (null (set-difference () ()))) (test-t (null (set-difference () () :test equal :key 'identity))) (test-t (null (nset-difference () ()))) (test-t (null (set-difference () '(1 2 3)))) (test-t (null (set-difference () '(1 2 3) :test equal :key 'identity))) (test-t (null (nset-difference () '(1 2 3)))) (test-t (null (set-difference '(1 2 3 4) '(4 3 2 1)))) (test-t (null (nset-difference (list 1 2 3 4) '(4 3 2 1)))) (test-t (null (set-difference '(1 2 3 4) '(2 4 3 1)))) (test-t (null (nset-difference (list 1 2 3 4) '(2 4 3 1)))) (test-t (null (set-difference '(1 2 3 4) '(1 3 4 2)))) (test-t (null (nset-difference (list 1 2 3 4) '(1 3 4 2)))) (test-t (null (set-difference '(1 2 3 4) '(1 3 2 4)))) (test-t (null (nset-difference (list 1 2 3 4) '(1 3 2 4)))) (test-t (eq (set-difference (set-difference '(1 2 3) ()) '(1 2 3)) ())) (test-t (eq (nset-difference (nset-difference (list 1 2 3) ()) '(1 2 3)) ())) (test-t (eq (set-difference (set-difference '(1 2 3) '(1)) '(2 3)) ())) (test-t (eq (nset-difference (nset-difference (list 1 2 3) '(1)) '(2 3)) ())) (test-t (eq (set-difference (set-difference '(1 2 3) '(1 2)) '(3)) ())) (test-t (eq (nset-difference (nset-difference (list 1 2 3) '(1 2)) '(3)) ())) (test-t (null (set-exclusive-or (set-exclusive-or '(1 2 3) '(2 3 4)) '(1 4)))) (test-t (null (nset-exclusive-or (nset-exclusive-or (list 1 2 3) '(2 3 4)) '(1 4)))) (test-t (null (set-exclusive-or (set-exclusive-or '(1 2 3) '(1 3)) '(2)))) (test-t (null (nset-exclusive-or (nset-exclusive-or (list 1 2 3) '(1 3)) '(2)))) (test-t (null (set-exclusive-or () ()))) (test-t (null (nset-exclusive-or () ()))) (test-t (null (set-exclusive-or '(1 2 3) '(3 2 1)))) (test-t (null (nset-exclusive-or (list 1 2 3) '(3 2 1)))) (test-t (null (set-exclusive-or '(1 2 3) '(2 3 1)))) (test-t (null (nset-exclusive-or (list 1 2 3) '(2 3 1)))) (test-t (null (set-exclusive-or '(1 2 3) '(1 3 2)))) (test-t (null (nset-exclusive-or (list 1 2 3) '(1 3 2)))) (test-t (null (set-exclusive-or (set-exclusive-or '(1 2 3) ()) '(3 2 1)))) (test-t (null (nset-exclusive-or (nset-exclusive-or (list 1 2 3) ()) '(3 2 1)))) (test-t (null (set-exclusive-or (set-exclusive-or () '(1 2 3)) '(2 1 3)))) (test-t (null (nset-exclusive-or (nset-exclusive-or () '(1 2 3)) '(2 1 3)))) (test-t (null (set-exclusive-or '("car" "ship" "airplane" "submarine") '("car" "ship" "airplane" "submarine") :test equal))) (test-t (null (nset-exclusive-or (copy-list '("car" "ship" "airplane" "submarine")) '("car" "ship" "airplane" "submarine") :test equal))) (test-t (null (set-exclusive-or '("car" "ship" "airplane" "submarine") '("CAR" "SHIP" "AIRPLANE" "SUBMARINE") :test equalp))) (test-t (null (nset-exclusive-or (copy-list '("car" "ship" "airplane" "submarine")) '("CAR" "SHIP" "AIRPLANE" "SUBMARINE") :test equalp))) (test-t (null (set-exclusive-or '(("car") ("ship") ("airplane") ("submarine")) '(("car") ("ship") ("airplane") ("submarine")) :test string= :key car))) (test-t (null (nset-exclusive-or (copy-tree '(("car") ("ship") ("airplane") ("submarine"))) '(("car") ("ship") ("airplane") ("submarine")) :test string= :key car))) ) (let () (define* (nsubstitute-if new-item test sequence from-end (start 0) end count (key identity)) (if (and (number? count) (not (positive? count))) sequence (let* ((len (length sequence)) (nd (or (and (number? end) end) len))) ; up to but not including end (if (< nd start) (error "~A :start ~A is greater than ~A ~A" __func__ start (if end ":end" "length") nd)) (let ((cur-count 0)) (if (not (number? count)) (set! count len)) (if (not from-end) (do ((i start (+ i 1))) ((or (= cur-count count) (= i nd)) sequence) (if (test (key (sequence i))) (begin (set! cur-count (+ cur-count 1)) (set! (sequence i) new-item)))) (do ((i (- nd 1) (- i 1))) ((or (= cur-count count) (< i start)) sequence) (if (test (key (sequence i))) (begin (set! cur-count (+ cur-count 1)) (set! (sequence i) new-item))))))))) (define* (nsubstitute-if-not new-item test sequence from-end (start 0) end count (key identity)) (nsubstitute-if new-item (lambda (obj) (not (test obj))) sequence from-end start end count key)) (define* (nsubstitute new-item old-item sequence from-end (test eql) (start 0) end count (key identity)) (nsubstitute-if new-item (lambda (arg) (test old-item arg)) sequence from-end start end count key)) (define* (substitute-if new-item test sequence from-end (start 0) end count (key identity)) (nsubstitute-if new-item test (copy sequence) from-end start end count key)) (define* (substitute-if-not new-item test sequence from-end (start 0) end count (key identity)) (substitute-if new-item (lambda (obj) (not (test obj))) (copy sequence) from-end start end count key)) (define* (substitute new-item old-item sequence from-end (test eql) (start 0) end count (key identity)) (nsubstitute new-item old-item (copy sequence) from-end test start end count key)) (test-t (equal (substitute #\. #\space "0 2 4 6") "0.2.4.6")) (test-t (equal (substitute 9 4 '(1 2 4 1 3 4 5)) '(1 2 9 1 3 9 5))) (test-t (equal (substitute 9 4 '(1 2 4 1 3 4 5) :count 1) '(1 2 9 1 3 4 5))) (test-t (equal (substitute 9 4 '(1 2 4 1 3 4 5) :count 1 :from-end t) '(1 2 4 1 3 9 5))) (test-t (equal (substitute 9 3 '(1 2 4 1 3 4 5) :test >) '(9 9 4 9 3 4 5))) (test-t (equal (substitute-if 0 evenp '((1) (2) (3) (4)) :start 2 :key car) '((1) (2) (3) 0))) (test-t (equal (substitute-if 9 oddp '(1 2 4 1 3 4 5)) '(9 2 4 9 9 4 9))) (test-t (equal (substitute-if 9 evenp '(1 2 4 1 3 4 5) :count 1 :from-end t) '(1 2 4 1 3 9 5))) (test-t (let ((some-things (list 'a 'car 'b 'cdr 'c))) (and (equal (nsubstitute-if "function was here" fboundp some-things :count 1 :from-end t) '(a car b "function was here" c)) (equal some-things '(a car b "function was here" c))))) (test-t (let ((alpha-tester (copy-seq "ab "))) (and (equal (nsubstitute-if-not #\z alpha-char-p alpha-tester) "abz") (equal alpha-tester "abz")))) (test-t (equal (substitute 'a 'x '(x y z)) '(a y z))) (test-t (equal (substitute 'b 'y '(x y z)) '(x b z))) (test-t (equal (substitute 'c 'z '(x y z)) '(x y c))) (test-t (equal (substitute 'a 'p '(x y z)) '(x y z))) (test-t (equal (substitute 'a 'x ()) ())) (test-t (equal (substitute #\x #\b '(#\a #\b #\c #\d #\e) :test char<) '(#\a #\b #\x #\x #\x))) (test-t (equal (substitute '(a) 'x '((x) (y) (z)) :key car) '((a) (y) (z)))) (test-t (equal (substitute 'c 'b '(a b a b a b a b)) '(a c a c a c a c))) (test-t (equal (substitute 'a 'b '(b b b)) '(a a a))) (test-t (equal (substitute 'z 'x '(a x b x c x d x e x f)) '(a z b z c z d z e z f))) (test-t (equal (substitute 'z 'x '(a x b x c x d x e x f) :count nil) '(a z b z c z d z e z f))) (test-t (equal (substitute 'z 'x '(a x b x c x d x e x f) :count 0) '(a x b x c x d x e x f))) (test-t (equal (substitute 'z 'x '(a x b x c x d x e x f) :count -100) '(a x b x c x d x e x f))) (test-t (equal (substitute 'z 'x '(a x b x c x d x e x f) :count 1) '(a z b x c x d x e x f))) (test-t (equal (substitute 'z 'x '(a x b x c x d x e x f) :count 2) '(a z b z c x d x e x f))) (test-t (equal (substitute 'z 'x '(a x b x c x d x e x f) :count 3) '(a z b z c z d x e x f))) (test-t (equal (substitute 'z 'x '(a x b x c x d x e x f) :count 4) '(a z b z c z d z e x f))) (test-t (equal (substitute 'z 'x '(a x b x c x d x e x f) :count 5) '(a z b z c z d z e z f))) (test-t (equal (substitute 'z 'x '(a x b x c x d x e x f) :count 6) '(a z b z c z d z e z f))) (test-t (equal (substitute 'z 'x '(a x b x c x d x e x f) :count 7) '(a z b z c z d z e z f))) (test-t (equal (substitute 'z 'x '(a x b x c x d x e x f) :count nil :from-end t) '(a z b z c z d z e z f))) (test-t (equal (substitute 'z 'x '(a x b x c x d x e x f) :count 0 :from-end t) '(a x b x c x d x e x f))) (test-t (equal (substitute 'z 'x '(a x b x c x d x e x f) :count -100 :from-end t) '(a x b x c x d x e x f))) (test-t (equal (substitute 'z 'x '(a x b x c x d x e x f) :count 1 :from-end t) '(a x b x c x d x e z f))) (test-t (equal (substitute 'z 'x '(a x b x c x d x e x f) :count 2 :from-end t) '(a x b x c x d z e z f))) (test-t (equal (substitute 'z 'x '(a x b x c x d x e x f) :count 3 :from-end t) '(a x b x c z d z e z f))) (test-t (equal (substitute 'z 'x '(a x b x c x d x e x f) :count 4 :from-end t) '(a x b z c z d z e z f))) (test-t (equal (substitute 'z 'x '(a x b x c x d x e x f) :count 5 :from-end t) '(a z b z c z d z e z f))) (test-t (equal (substitute 'z 'x '(a x b x c x d x e x f) :count 6 :from-end t) '(a z b z c z d z e z f))) (test-t (equal (substitute 'z 'x '(a x b x c x d x e x f) :count 7 :from-end t) '(a z b z c z d z e z f))) (test-t (equal (substitute 'z 'x '(a x b x c x d x e x f) :start 2 :count 1) '(a x b z c x d x e x f))) (test-t (equal (substitute 'z 'x '(a x b x c x d x e x f) :start 2 :end nil :count 1) '(a x b z c x d x e x f))) (test-t (equal (substitute 'z 'x '(a x b x c x d x e x f) :start 2 :end 6 :count 100) '(a x b z c z d x e x f))) (test-t (equal (substitute 'z 'x '(a x b x c x d x e x f) :start 2 :end 11 :count 100) '(a x b z c z d z e z f))) (test-t (equal (substitute 'z 'x '(a x b x c x d x e x f) :start 2 :end 8 :count 10) '(a x b z c z d z e x f))) (test-t (equal (substitute 'z 'x '(a x b x c x d x e x f) :start 2 :end 8 :count 2 :from-end t) '(a x b x c z d z e x f))) (test-t (equal (substitute #\z #\c '(#\a #\b #\c #\d #\e #\f) :test char<) '(#\a #\b #\c #\z #\z #\z))) (test-t (equal (substitute "peace" "war" '("war" "War" "WAr" "WAR") :test string-equal) '("peace" "peace" "peace" "peace"))) (test-t (equal (substitute "peace" "WAR" '("war" "War" "WAr" "WAR") :test string=) '("war" "War" "WAr" "peace"))) (test-t (equal (substitute "peace" "WAR" '("war" "War" "WAr" "WAR") :test string= :key cl-string-upcase) '("peace" "peace" "peace" "peace"))) (test-t (equal (substitute "peace" "WAR" '("war" "War" "WAr" "WAR") :start 1 :end 2 :test string= :key cl-string-upcase) '("war" "peace" "WAr" "WAR"))) (test-t (equal (substitute "peace" "WAR" '("war" "War" "WAr" "WAR") :start 1 :end nil :test string= :key cl-string-upcase) '("war" "peace" "peace" "peace"))) (test-t (equal (substitute "peace" "war" '("war" "War" "WAr" "WAR") :test string= :key cl-string-upcase) '("war" "War" "WAr" "WAR"))) (test-t (equalp (substitute 'a 'x #(x y z)) #(a y z))) (test-t (equalp (substitute 'b 'y #(x y z)) #(x b z))) (test-t (equalp (substitute 'c 'z #(x y z)) #(x y c))) (test-t (equalp (substitute 'a 'p #(x y z)) #(x y z))) (test-t (equalp (substitute 'a 'x #()) #())) (test-t (equalp (substitute #\x #\b #(#\a #\b #\c #\d #\e) :test char<) #(#\a #\b #\x #\x #\x))) (test-t (equalp (substitute '(a) 'x #((x) (y) (z)) :key car) #((a) (y) (z)))) (test-t (equalp (substitute 'c 'b #(a b a b a b a b)) #(a c a c a c a c))) (test-t (equalp (substitute 'a 'b #(b b b)) #(a a a))) (test-t (equalp (substitute 'z 'x #(a x b x c x d x e x f)) #(a z b z c z d z e z f))) (test-t (equalp (substitute 'z 'x #(a x b x c x d x e x f) :count nil) #(a z b z c z d z e z f))) (test-t (equalp (substitute 'z 'x #(a x b x c x d x e x f) :count 0) #(a x b x c x d x e x f))) (test-t (equalp (substitute 'z 'x #(a x b x c x d x e x f) :count -100) #(a x b x c x d x e x f))) (test-t (equalp (substitute 'z 'x #(a x b x c x d x e x f) :count 1) #(a z b x c x d x e x f))) (test-t (equalp (substitute 'z 'x #(a x b x c x d x e x f) :count 2) #(a z b z c x d x e x f))) (test-t (equalp (substitute 'z 'x #(a x b x c x d x e x f) :count 3) #(a z b z c z d x e x f))) (test-t (equalp (substitute 'z 'x #(a x b x c x d x e x f) :count 4) #(a z b z c z d z e x f))) (test-t (equalp (substitute 'z 'x #(a x b x c x d x e x f) :count 5) #(a z b z c z d z e z f))) (test-t (equalp (substitute 'z 'x #(a x b x c x d x e x f) :count 6) #(a z b z c z d z e z f))) (test-t (equalp (substitute 'z 'x #(a x b x c x d x e x f) :count 7) #(a z b z c z d z e z f))) (test-t (equalp (substitute 'z 'x #(a x b x c x d x e x f) :count nil :from-end t) #(a z b z c z d z e z f))) (test-t (equalp (substitute 'z 'x #(a x b x c x d x e x f) :count 0 :from-end t) #(a x b x c x d x e x f))) (test-t (equalp (substitute 'z 'x #(a x b x c x d x e x f) :count -100 :from-end t) #(a x b x c x d x e x f))) (test-t (equalp (substitute 'z 'x #(a x b x c x d x e x f) :count 1 :from-end t) #(a x b x c x d x e z f))) (test-t (equalp (substitute 'z 'x #(a x b x c x d x e x f) :count 2 :from-end t) #(a x b x c x d z e z f))) (test-t (equalp (substitute 'z 'x #(a x b x c x d x e x f) :count 3 :from-end t) #(a x b x c z d z e z f))) (test-t (equalp (substitute 'z 'x #(a x b x c x d x e x f) :count 4 :from-end t) #(a x b z c z d z e z f))) (test-t (equalp (substitute 'z 'x #(a x b x c x d x e x f) :count 5 :from-end t) #(a z b z c z d z e z f))) (test-t (equalp (substitute 'z 'x #(a x b x c x d x e x f) :count 6 :from-end t) #(a z b z c z d z e z f))) (test-t (equalp (substitute 'z 'x #(a x b x c x d x e x f) :count 7 :from-end t) #(a z b z c z d z e z f))) (test-t (equalp (substitute 'z 'x #(a x b x c x d x e x f) :start 2 :count 1) #(a x b z c x d x e x f))) (test-t (equalp (substitute 'z 'x #(a x b x c x d x e x f) :start 2 :end nil :count 1) #(a x b z c x d x e x f))) (test-t (equalp (substitute 'z 'x #(a x b x c x d x e x f) :start 2 :end 6 :count 100) #(a x b z c z d x e x f))) (test-t (equalp (substitute 'z 'x #(a x b x c x d x e x f) :start 2 :end 11 :count 100) #(a x b z c z d z e z f))) (test-t (equalp (substitute 'z 'x #(a x b x c x d x e x f) :start 2 :end 8 :count 10) #(a x b z c z d z e x f))) (test-t (equalp (substitute 'z 'x #(a x b x c x d x e x f) :start 2 :end 8 :count 2 :from-end t) #(a x b x c z d z e x f))) (test-t (equalp (substitute #\z #\c #(#\a #\b #\c #\d #\e #\f) :test char<) #(#\a #\b #\c #\z #\z #\z))) (test-t (equalp (substitute "peace" "war" #("love" "hate" "war" "peace") :test equal) #("love" "hate" "peace" "peace"))) (test-t (equalp (substitute "peace" "war" #("war" "War" "WAr" "WAR") :test string-equal) #("peace" "peace" "peace" "peace"))) (test-t (equalp (substitute "peace" "WAR" #("war" "War" "WAr" "WAR") :test string=) #("war" "War" "WAr" "peace"))) (test-t (equalp (substitute "peace" "WAR" #("war" "War" "WAr" "WAR") :test string= :key cl-string-upcase) #("peace" "peace" "peace" "peace"))) (test-t (equalp (substitute "peace" "WAR" #("war" "War" "WAr" "WAR") :start 1 :end 2 :test string= :key cl-string-upcase) #("war" "peace" "WAr" "WAR"))) (test-t (equalp (substitute "peace" "WAR" #("war" "War" "WAr" "WAR") :start 1 :end nil :test string= :key cl-string-upcase) #("war" "peace" "peace" "peace"))) (test-t (equalp (substitute "peace" "war" #("war" "War" "WAr" "WAR") :test string= :key cl-string-upcase) #("war" "War" "WAr" "WAR"))) (test-t (string= (substitute #\A #\a "abcabc") "AbcAbc")) (test-t (string= (substitute #\A #\a "") "")) (test-t (string= (substitute #\A #\a "xyz") "xyz")) (test-t (string= (substitute #\A #\a "aaaaaaaaaa" :start 5 :end nil) "aaaaaAAAAA")) (test-t (string= (substitute #\x #\5 "0123456789" :test char<) "012345xxxx")) (test-t (string= (substitute #\x #\5 "0123456789" :test char>) "xxxxx56789")) (test-t (string= (substitute #\x #\D "abcdefg" :key char-upcase :test char>) "xxxdefg")) (test-t (string= (substitute #\x #\D "abcdefg" :start 1 :end 2 :key char-upcase :test char>) "axcdefg")) (test-t (string= (substitute #\A #\a "aaaaaaaaaa" :count 2) "AAaaaaaaaa")) (test-t (string= (substitute #\A #\a "aaaaaaaaaa" :count -1) "aaaaaaaaaa")) (test-t (string= (substitute #\A #\a "aaaaaaaaaa" :count 0) "aaaaaaaaaa")) (test-t (string= (substitute #\A #\a "aaaaaaaaaa" :count nil) "AAAAAAAAAA")) (test-t (string= (substitute #\A #\a "aaaaaaaaaa" :count 100) "AAAAAAAAAA")) (test-t (string= (substitute #\A #\a "aaaaaaaaaa" :count 9) "AAAAAAAAAa")) (test-t (string= (substitute #\A #\a "aaaaaaaaaa" :count 9 :from-end t) "aAAAAAAAAA")) (test-t (string= (substitute #\A #\a "aaaaaaaaaa" :start 2 :end 8 :count 3) "aaAAAaaaaa")) (test-t (string= (substitute #\A #\a "aaaaaaaaaa" :start 2 :end 8 :from-end t :count 3) "aaaaaAAAaa")) (test-t (string= (substitute #\x #\A "aaaaaaaaaa" :start 2 :end 8 :from-end t :count 3) "aaaaaaaaaa")) (test-t (string= (substitute #\X #\A "aaaaaaaaaa" :start 2 :end 8 :from-end t :key char-upcase :count 3) "aaaaaXXXaa")) (test-t (string= (substitute #\X #\D "abcdefghij" :start 2 :end 8 :from-end t :key char-upcase :test char< :count 3) "abcdeXXXij")) (test-t (equal (substitute-if 'a (lambda (arg) (eq arg 'x)) '(x y z)) '(a y z))) (test-t (equal (substitute-if 'b (lambda (arg) (eq arg 'y)) '(x y z)) '(x b z))) (test-t (equal (substitute-if 'c (lambda (arg) (eq arg 'z)) '(x y z)) '(x y c))) (test-t (equal (substitute-if 'a (lambda (arg) (eq arg 'p)) '(x y z)) '(x y z))) (test-t (equal (substitute-if 'a (lambda (arg) (eq arg 'x)) ()) ())) (test-t (equal (substitute-if #\x (lambda (arg) (char< #\b arg)) '(#\a #\b #\c #\d #\e)) '(#\a #\b #\x #\x #\x))) (test-t (equal (substitute-if '(a) (lambda (arg) (eq arg 'x)) '((x) (y) (z)) :key car) '((a) (y) (z)))) (test-t (equal (substitute-if 'c (lambda (arg) (eq arg 'b)) '(a b a b a b a b)) '(a c a c a c a c))) (test-t (equal (substitute-if 'a (lambda (arg) (eq arg 'b)) '(b b b)) '(a a a))) (test-t (equal (substitute-if 'z (lambda (arg) (eq arg 'x)) '(a x b x c x d x e x f)) '(a z b z c z d z e z f))) (test-t (equal (substitute-if 'z (lambda (arg) (eq arg 'x)) '(a x b x c x d x e x f) :count nil) '(a z b z c z d z e z f))) (test-t (equal (substitute-if 'z (lambda (arg) (eq arg 'x)) '(a x b x c x d x e x f) :count 0) '(a x b x c x d x e x f))) (test-t (equal (substitute-if 'z (lambda (arg) (eq arg 'x)) '(a x b x c x d x e x f) :count -100) '(a x b x c x d x e x f))) (test-t (equal (substitute-if 'z (lambda (arg) (eq arg 'x)) '(a x b x c x d x e x f) :count 1) '(a z b x c x d x e x f))) (test-t (equal (substitute-if 'z (lambda (arg) (eq arg 'x)) '(a x b x c x d x e x f) :count 2) '(a z b z c x d x e x f))) (test-t (equal (substitute-if 'z (lambda (arg) (eq arg 'x)) '(a x b x c x d x e x f) :count 3) '(a z b z c z d x e x f))) (test-t (equal (substitute-if 'z (lambda (arg) (eq arg 'x)) '(a x b x c x d x e x f) :count 4) '(a z b z c z d z e x f))) (test-t (equal (substitute-if 'z (lambda (arg) (eq arg 'x)) '(a x b x c x d x e x f) :count 5) '(a z b z c z d z e z f))) (test-t (equal (substitute-if 'z (lambda (arg) (eq arg 'x)) '(a x b x c x d x e x f) :count 6) '(a z b z c z d z e z f))) (test-t (equal (substitute-if 'z (lambda (arg) (eq arg 'x)) '(a x b x c x d x e x f) :count 7) '(a z b z c z d z e z f))) (test-t (equal (substitute-if 'z (lambda (arg) (eq arg 'x)) '(a x b x c x d x e x f) :count nil :from-end t) '(a z b z c z d z e z f))) (test-t (equal (substitute-if 'z (lambda (arg) (eq arg 'x)) '(a x b x c x d x e x f) :count 0 :from-end t) '(a x b x c x d x e x f))) (test-t (equal (substitute-if 'z (lambda (arg) (eq arg 'x)) '(a x b x c x d x e x f) :count -100 :from-end t) '(a x b x c x d x e x f))) (test-t (equal (substitute-if 'z (lambda (arg) (eq arg 'x)) '(a x b x c x d x e x f) :count 1 :from-end t) '(a x b x c x d x e z f))) (test-t (equal (substitute-if 'z (lambda (arg) (eq arg 'x)) '(a x b x c x d x e x f) :count 2 :from-end t) '(a x b x c x d z e z f))) (test-t (equal (substitute-if 'z (lambda (arg) (eq arg 'x)) '(a x b x c x d x e x f) :count 3 :from-end t) '(a x b x c z d z e z f))) (test-t (equal (substitute-if 'z (lambda (arg) (eq arg 'x)) '(a x b x c x d x e x f) :count 4 :from-end t) '(a x b z c z d z e z f))) (test-t (equal (substitute-if 'z (lambda (arg) (eq arg 'x)) '(a x b x c x d x e x f) :count 5 :from-end t) '(a z b z c z d z e z f))) (test-t (equal (substitute-if 'z (lambda (arg) (eq arg 'x)) '(a x b x c x d x e x f) :count 6 :from-end t) '(a z b z c z d z e z f))) (test-t (equal (substitute-if 'z (lambda (arg) (eq arg 'x)) '(a x b x c x d x e x f) :count 7 :from-end t) '(a z b z c z d z e z f))) (test-t (equal (substitute-if 'z (lambda (arg) (eq arg 'x)) '(a x b x c x d x e x f) :start 2 :count 1) '(a x b z c x d x e x f))) (test-t (equal (substitute-if 'z (lambda (arg) (eq arg 'x)) '(a x b x c x d x e x f) :start 2 :end nil :count 1) '(a x b z c x d x e x f))) (test-t (equal (substitute-if 'z (lambda (arg) (eq arg 'x)) '(a x b x c x d x e x f) :start 2 :end 6 :count 100) '(a x b z c z d x e x f))) (test-t (equal (substitute-if 'z (lambda (arg) (eq arg 'x)) '(a x b x c x d x e x f) :start 2 :end 11 :count 100) '(a x b z c z d z e z f))) (test-t (equal (substitute-if 'z (lambda (arg) (eq arg 'x)) '(a x b x c x d x e x f) :start 2 :end 8 :count 10) '(a x b z c z d z e x f))) (test-t (equal (substitute-if 'z (lambda (arg) (eq arg 'x)) '(a x b x c x d x e x f) :start 2 :end 8 :count 2 :from-end t) '(a x b x c z d z e x f))) (test-t (equal (substitute-if #\z (lambda (arg) (char< #\c arg)) '(#\a #\b #\c #\d #\e #\f)) '(#\a #\b #\c #\z #\z #\z))) (test-t (equal (substitute-if "peace" (lambda (arg) (equal "war" arg)) '("love" "hate" "war" "peace")) '("love" "hate" "peace" "peace"))) (test-t (equal (substitute-if "peace" (lambda (arg) (string-equal "war" arg)) '("war" "War" "WAr" "WAR")) '("peace" "peace" "peace" "peace"))) (test-t (equal (substitute-if "peace" (lambda (arg) (string= "WAR" arg)) '("war" "War" "WAr" "WAR") :key cl-string-upcase) '("peace" "peace" "peace" "peace"))) (test-t (equal (substitute-if "peace" (lambda (arg) (string= "WAR" arg)) '("war" "War" "WAr" "WAR") :start 1 :end 2 :key string-upcase) '("war" "peace" "WAr" "WAR"))) (test-t (equal (substitute-if "peace" (lambda (arg) (string= "WAR" arg)) '("war" "War" "WAr" "WAR") :start 1 :end nil :key string-upcase) '("war" "peace" "peace" "peace"))) (test-t (equal (substitute-if "peace" (lambda (arg) (string= "war" arg)) '("war" "War" "WAr" "WAR") :key string-upcase) '("war" "War" "WAr" "WAR"))) (test-t (equal (substitute-if "peace" (lambda (arg) (string= "WAR" arg)) '("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR") :start 1 :end 7 :count 1 :key string-upcase) '("war" "peace" "WAr" "WAR" "war" "War" "WAr" "WAR"))) (test-t (equal (substitute-if "peace" (lambda (arg) (string= "WAR" arg)) '("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR") :start 1 :end 7 :count 2 :key string-upcase) '("war" "peace" "peace" "WAR" "war" "War" "WAr" "WAR"))) (test-t (equal (substitute-if "peace" (lambda (arg) (string= "WAR" arg)) '("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR") :start 1 :end 7 :count 2 :from-end t :key string-upcase) '("war" "War" "WAr" "WAR" "war" "peace" "peace" "WAR"))) (test-t (equal (substitute-if "peace" (lambda (arg) (string= "WAR" arg)) '("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR") :start 1 :end 7 :count 0 :from-end t :key string-upcase) '("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR"))) (test-t (equal (substitute-if "peace" (lambda (arg) (string= "WAR" arg)) '("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR") :start 1 :end 7 :count -2 :from-end t :key string-upcase) '("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR"))) (test-t (equal (substitute-if "peace" (lambda (arg) (string= "WAR" arg)) '("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR") :start 1 :end 7 :count nil :from-end t :key string-upcase) '("war" "peace" "peace" "peace" "peace" "peace" "peace" "WAR"))) (test-t (equal (substitute-if "peace" (lambda (arg) (string= "WAR" arg)) '("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR") :start 1 :end 7 :count 6 :from-end t :key string-upcase) '("war" "peace" "peace" "peace" "peace" "peace" "peace" "WAR"))) (test-t (equal (substitute-if "peace" (lambda (arg) (string= "WAR" arg)) '("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR") :start 1 :end 7 :count 7 :from-end t :key string-upcase) '("war" "peace" "peace" "peace" "peace" "peace" "peace" "WAR"))) (test-t (equal (substitute-if "peace" (lambda (arg) (string= "WAR" arg)) '("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR") :start 1 :end 7 :count 100 :from-end t :key string-upcase) '("war" "peace" "peace" "peace" "peace" "peace" "peace" "WAR"))) (test-t (equalp (substitute-if 'a (lambda (arg) (eq arg 'x)) #(x y z)) #(a y z))) (test-t (equalp (substitute-if 'b (lambda (arg) (eq arg 'y)) #(x y z)) #(x b z))) (test-t (equalp (substitute-if 'c (lambda (arg) (eq arg 'z)) #(x y z)) #(x y c))) (test-t (equalp (substitute-if 'a (lambda (arg) (eq arg 'p)) #(x y z)) #(x y z))) (test-t (equalp (substitute-if 'a (lambda (arg) (eq arg 'x)) #()) #())) (test-t (equalp (substitute-if #\x (lambda (arg) (char< #\b arg)) #(#\a #\b #\c #\d #\e)) #(#\a #\b #\x #\x #\x))) (test-t (equalp (substitute-if '(a) (lambda (arg) (eq arg 'x)) #((x) (y) (z)) :key car) #((a) (y) (z)))) (test-t (equalp (substitute-if 'c (lambda (arg) (eq arg 'b)) #(a b a b a b a b)) #(a c a c a c a c))) (test-t (equalp (substitute-if 'a (lambda (arg) (eq arg 'b)) #(b b b)) #(a a a))) (test-t (equalp (substitute-if 'z (lambda (arg) (eq arg 'x)) #(a x b x c x d x e x f)) #(a z b z c z d z e z f))) (test-t (equalp (substitute-if 'z (lambda (arg) (eq arg 'x)) #(a x b x c x d x e x f) :count nil) #(a z b z c z d z e z f))) (test-t (equalp (substitute-if 'z (lambda (arg) (eq arg 'x)) #(a x b x c x d x e x f) :count 0) #(a x b x c x d x e x f))) (test-t (equalp (substitute-if 'z (lambda (arg) (eq arg 'x)) #(a x b x c x d x e x f) :count -100) #(a x b x c x d x e x f))) (test-t (equalp (substitute-if 'z (lambda (arg) (eq arg 'x)) #(a x b x c x d x e x f) :count 1) #(a z b x c x d x e x f))) (test-t (equalp (substitute-if 'z (lambda (arg) (eq arg 'x)) #(a x b x c x d x e x f) :count 2) #(a z b z c x d x e x f))) (test-t (equalp (substitute-if 'z (lambda (arg) (eq arg 'x)) #(a x b x c x d x e x f) :count 3) #(a z b z c z d x e x f))) (test-t (equalp (substitute-if 'z (lambda (arg) (eq arg 'x)) #(a x b x c x d x e x f) :count 4) #(a z b z c z d z e x f))) (test-t (equalp (substitute-if 'z (lambda (arg) (eq arg 'x)) #(a x b x c x d x e x f) :count 5) #(a z b z c z d z e z f))) (test-t (equalp (substitute-if 'z (lambda (arg) (eq arg 'x)) #(a x b x c x d x e x f) :count 6) #(a z b z c z d z e z f))) (test-t (equalp (substitute-if 'z (lambda (arg) (eq arg 'x)) #(a x b x c x d x e x f) :count 7) #(a z b z c z d z e z f))) (test-t (equalp (substitute-if 'z (lambda (arg) (eq arg 'x)) #(a x b x c x d x e x f) :count nil :from-end t) #(a z b z c z d z e z f))) (test-t (equalp (substitute-if 'z (lambda (arg) (eq arg 'x)) #(a x b x c x d x e x f) :count 0 :from-end t) #(a x b x c x d x e x f))) (test-t (equalp (substitute-if 'z (lambda (arg) (eq arg 'x)) #(a x b x c x d x e x f) :count -100 :from-end t) #(a x b x c x d x e x f))) (test-t (equalp (substitute-if 'z (lambda (arg) (eq arg 'x)) #(a x b x c x d x e x f) :count 1 :from-end t) #(a x b x c x d x e z f))) (test-t (equalp (substitute-if 'z (lambda (arg) (eq arg 'x)) #(a x b x c x d x e x f) :count 2 :from-end t) #(a x b x c x d z e z f))) (test-t (equalp (substitute-if 'z (lambda (arg) (eq arg 'x)) #(a x b x c x d x e x f) :count 3 :from-end t) #(a x b x c z d z e z f))) (test-t (equalp (substitute-if 'z (lambda (arg) (eq arg 'x)) #(a x b x c x d x e x f) :count 4 :from-end t) #(a x b z c z d z e z f))) (test-t (equalp (substitute-if 'z (lambda (arg) (eq arg 'x)) #(a x b x c x d x e x f) :count 5 :from-end t) #(a z b z c z d z e z f))) (test-t (equalp (substitute-if 'z (lambda (arg) (eq arg 'x)) #(a x b x c x d x e x f) :count 6 :from-end t) #(a z b z c z d z e z f))) (test-t (equalp (substitute-if 'z (lambda (arg) (eq arg 'x)) #(a x b x c x d x e x f) :count 7 :from-end t) #(a z b z c z d z e z f))) (test-t (equalp (substitute-if 'z (lambda (arg) (eq arg 'x)) #(a x b x c x d x e x f) :start 2 :count 1) #(a x b z c x d x e x f))) (test-t (equalp (substitute-if 'z (lambda (arg) (eq arg 'x)) #(a x b x c x d x e x f) :start 2 :end nil :count 1) #(a x b z c x d x e x f))) (test-t (equalp (substitute-if 'z (lambda (arg) (eq arg 'x)) #(a x b x c x d x e x f) :start 2 :end 6 :count 100) #(a x b z c z d x e x f))) (test-t (equalp (substitute-if 'z (lambda (arg) (eq arg 'x)) #(a x b x c x d x e x f) :start 2 :end 11 :count 100) #(a x b z c z d z e z f))) (test-t (equalp (substitute-if 'z (lambda (arg) (eq arg 'x)) #(a x b x c x d x e x f) :start 2 :end 8 :count 10) #(a x b z c z d z e x f))) (test-t (equalp (substitute-if 'z (lambda (arg) (eq arg 'x)) #(a x b x c x d x e x f) :start 2 :end 8 :count 2 :from-end t) #(a x b x c z d z e x f))) (test-t (equalp (substitute-if #\z (lambda (arg) (char< #\c arg)) #(#\a #\b #\c #\d #\e #\f)) #(#\a #\b #\c #\z #\z #\z))) (test-t (equalp (substitute-if "peace" (lambda (arg) (equal "war" arg)) #("love" "hate" "war" "peace")) #("love" "hate" "peace" "peace"))) (test-t (equalp (substitute-if "peace" (lambda (arg) (string-equal "war" arg)) #("war" "War" "WAr" "WAR")) #("peace" "peace" "peace" "peace"))) (test-t (equalp (substitute-if "peace" (lambda (arg) (string= "WAR" arg)) #("war" "War" "WAr" "WAR") :key string-upcase) #("peace" "peace" "peace" "peace"))) (test-t (equalp (substitute-if "peace" (lambda (arg) (string= "WAR" arg)) #("war" "War" "WAr" "WAR") :start 1 :end 2 :key string-upcase) #("war" "peace" "WAr" "WAR"))) (test-t (equalp (substitute-if "peace" (lambda (arg) (string= "WAR" arg)) #("war" "War" "WAr" "WAR") :start 1 :end nil :key string-upcase) #("war" "peace" "peace" "peace"))) (test-t (equalp (substitute-if "peace" (lambda (arg) (string= "war" arg)) #("war" "War" "WAr" "WAR") :key string-upcase) #("war" "War" "WAr" "WAR"))) (test-t (equalp (substitute-if "peace" (lambda (arg) (string= "WAR" arg)) #("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR") :start 1 :end 7 :count 1 :key string-upcase) #("war" "peace" "WAr" "WAR" "war" "War" "WAr" "WAR"))) (test-t (equalp (substitute-if "peace" (lambda (arg) (string= "WAR" arg)) #("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR") :start 1 :end 7 :count 2 :key string-upcase) #("war" "peace" "peace" "WAR" "war" "War" "WAr" "WAR"))) (test-t (equalp (substitute-if "peace" (lambda (arg) (string= "WAR" arg)) #("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR") :start 1 :end 7 :count 2 :from-end t :key string-upcase) #("war" "War" "WAr" "WAR" "war" "peace" "peace" "WAR"))) (test-t (equalp (substitute-if "peace" (lambda (arg) (string= "WAR" arg)) #("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR") :start 1 :end 7 :count 0 :from-end t :key string-upcase) #("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR"))) (test-t (equalp (substitute-if "peace" (lambda (arg) (string= "WAR" arg)) #("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR") :start 1 :end 7 :count -2 :from-end t :key string-upcase) #("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR"))) (test-t (equalp (substitute-if "peace" (lambda (arg) (string= "WAR" arg)) #("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR") :start 1 :end 7 :count nil :from-end t :key string-upcase) #("war" "peace" "peace" "peace" "peace" "peace" "peace" "WAR"))) (test-t (equalp (substitute-if "peace" (lambda (arg) (string= "WAR" arg)) #("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR") :start 1 :end 7 :count 6 :from-end t :key string-upcase) #("war" "peace" "peace" "peace" "peace" "peace" "peace" "WAR"))) (test-t (equalp (substitute-if "peace" (lambda (arg) (string= "WAR" arg)) #("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR") :start 1 :end 7 :count 7 :from-end t :key string-upcase) #("war" "peace" "peace" "peace" "peace" "peace" "peace" "WAR"))) (test-t (equalp (substitute-if "peace" (lambda (arg) (string= "WAR" arg)) #("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR") :start 1 :end 7 :count 100 :from-end t :key string-upcase) #("war" "peace" "peace" "peace" "peace" "peace" "peace" "WAR"))) (test-t (string= (substitute-if #\A (lambda (arg) (eql #\a arg)) "abcabc") "AbcAbc")) (test-t (string= (substitute-if #\A (lambda (arg) (eql #\a arg)) "") "")) (test-t (string= (substitute-if #\A (lambda (arg) (eql #\a arg)) "xyz") "xyz")) (test-t (string= (substitute-if #\A (lambda (arg) (eql #\a arg)) "aaaaaaaaaa" :start 5 :end nil) "aaaaaAAAAA")) (test-t (string= (substitute-if #\x (lambda (arg) (char< #\5 arg)) "0123456789") "012345xxxx")) (test-t (string= (substitute-if #\x (lambda (arg) (char> #\5 arg)) "0123456789") "xxxxx56789")) (test-t (string= (substitute-if #\x (lambda (arg) (char> #\D arg)) "abcdefg" :key char-upcase) "xxxdefg")) (test-t (string= (substitute-if #\x (lambda (arg) (char> #\D arg)) "abcdefg" :start 1 :end 2 :key char-upcase) "axcdefg")) (test-t (string= (substitute-if #\A (lambda (arg) (eql #\a arg)) "aaaaaaaaaa" :count 2) "AAaaaaaaaa")) (test-t (string= (substitute-if #\A (lambda (arg) (eql #\a arg)) "aaaaaaaaaa" :count -1) "aaaaaaaaaa")) (test-t (string= (substitute-if #\A (lambda (arg) (eql #\a arg)) "aaaaaaaaaa" :count 0) "aaaaaaaaaa")) (test-t (string= (substitute-if #\A (lambda (arg) (eql #\a arg)) "aaaaaaaaaa" :count nil) "AAAAAAAAAA")) (test-t (string= (substitute-if #\A (lambda (arg) (eql #\a arg)) "aaaaaaaaaa" :count 100) "AAAAAAAAAA")) (test-t (string= (substitute-if #\A (lambda (arg) (eql #\a arg)) "aaaaaaaaaa" :count 9) "AAAAAAAAAa")) (test-t (string= (substitute-if #\A (lambda (arg) (eql #\a arg)) "aaaaaaaaaa" :count 9 :from-end t) "aAAAAAAAAA")) (test-t (string= (substitute-if #\A (lambda (arg) (eql #\a arg)) "aaaaaaaaaa" :start 2 :end 8 :count 3) "aaAAAaaaaa")) (test-t (string= (substitute-if #\A (lambda (arg) (eql #\a arg)) "aaaaaaaaaa" :start 2 :end 8 :from-end t :count 3) "aaaaaAAAaa")) (test-t (string= (substitute-if #\x (lambda (arg) (eql #\A arg)) "aaaaaaaaaa" :start 2 :end 8 :from-end t :count 3) "aaaaaaaaaa")) (test-t (string= (substitute-if #\X (lambda (arg) (eql #\A arg)) "aaaaaaaaaa" :start 2 :end 8 :from-end t :key char-upcase :count 3) "aaaaaXXXaa")) (test-t (string= (substitute-if #\X (lambda (arg) (char< #\D arg)) "abcdefghij" :start 2 :end 8 :from-end t :key char-upcase :count 3) "abcdeXXXij")) (test-t (equal (substitute-if-not 'a (lambda (arg) (not (eq arg 'x))) '(x y z)) '(a y z))) (test-t (equal (substitute-if-not 'b (lambda (arg) (not (eq arg 'y))) '(x y z)) '(x b z))) (test-t (equal (substitute-if-not 'c (lambda (arg) (not (eq arg 'z))) '(x y z)) '(x y c))) (test-t (equal (substitute-if-not 'a (lambda (arg) (not (eq arg 'p))) '(x y z)) '(x y z))) (test-t (equal (substitute-if-not 'a (lambda (arg) (not (eq arg 'x))) ()) ())) (test-t (equal (substitute-if-not #\x (lambda (arg) (not (char< #\b arg))) '(#\a #\b #\c #\d #\e)) '(#\a #\b #\x #\x #\x))) (test-t (equal (substitute-if-not '(a) (lambda (arg) (not (eq arg 'x))) '((x) (y) (z)) :key car) '((a) (y) (z)))) (test-t (equal (substitute-if-not 'c (lambda (arg) (not (eq arg 'b))) '(a b a b a b a b)) '(a c a c a c a c))) (test-t (equal (substitute-if-not 'a (lambda (arg) (not (eq arg 'b))) '(b b b)) '(a a a))) (test-t (equal (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) '(a x b x c x d x e x f)) '(a z b z c z d z e z f))) (test-t (equal (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) '(a x b x c x d x e x f) :count nil) '(a z b z c z d z e z f))) (test-t (equal (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) '(a x b x c x d x e x f) :count 0) '(a x b x c x d x e x f))) (test-t (equal (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) '(a x b x c x d x e x f) :count -100) '(a x b x c x d x e x f))) (test-t (equal (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) '(a x b x c x d x e x f) :count 1) '(a z b x c x d x e x f))) (test-t (equal (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) '(a x b x c x d x e x f) :count 2) '(a z b z c x d x e x f))) (test-t (equal (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) '(a x b x c x d x e x f) :count 3) '(a z b z c z d x e x f))) (test-t (equal (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) '(a x b x c x d x e x f) :count 4) '(a z b z c z d z e x f))) (test-t (equal (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) '(a x b x c x d x e x f) :count 5) '(a z b z c z d z e z f))) (test-t (equal (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) '(a x b x c x d x e x f) :count 6) '(a z b z c z d z e z f))) (test-t (equal (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) '(a x b x c x d x e x f) :count 7) '(a z b z c z d z e z f))) (test-t (equal (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) '(a x b x c x d x e x f) :count nil :from-end t) '(a z b z c z d z e z f))) (test-t (equal (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) '(a x b x c x d x e x f) :count 0 :from-end t) '(a x b x c x d x e x f))) (test-t (equal (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) '(a x b x c x d x e x f) :count -100 :from-end t) '(a x b x c x d x e x f))) (test-t (equal (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) '(a x b x c x d x e x f) :count 1 :from-end t) '(a x b x c x d x e z f))) (test-t (equal (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) '(a x b x c x d x e x f) :count 2 :from-end t) '(a x b x c x d z e z f))) (test-t (equal (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) '(a x b x c x d x e x f) :count 3 :from-end t) '(a x b x c z d z e z f))) (test-t (equal (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) '(a x b x c x d x e x f) :count 4 :from-end t) '(a x b z c z d z e z f))) (test-t (equal (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) '(a x b x c x d x e x f) :count 5 :from-end t) '(a z b z c z d z e z f))) (test-t (equal (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) '(a x b x c x d x e x f) :count 6 :from-end t) '(a z b z c z d z e z f))) (test-t (equal (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) '(a x b x c x d x e x f) :count 7 :from-end t) '(a z b z c z d z e z f))) (test-t (equal (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) '(a x b x c x d x e x f) :start 2 :count 1) '(a x b z c x d x e x f))) (test-t (equal (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) '(a x b x c x d x e x f) :start 2 :end nil :count 1) '(a x b z c x d x e x f))) (test-t (equal (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) '(a x b x c x d x e x f) :start 2 :end 6 :count 100) '(a x b z c z d x e x f))) (test-t (equal (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) '(a x b x c x d x e x f) :start 2 :end 11 :count 100) '(a x b z c z d z e z f))) (test-t (equal (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) '(a x b x c x d x e x f) :start 2 :end 8 :count 10) '(a x b z c z d z e x f))) (test-t (equal (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) '(a x b x c x d x e x f) :start 2 :end 8 :count 2 :from-end t) '(a x b x c z d z e x f))) (test-t (equal (substitute-if-not #\z (lambda (arg) (not (char< #\c arg))) '(#\a #\b #\c #\d #\e #\f)) '(#\a #\b #\c #\z #\z #\z))) (test-t (equal (substitute-if-not "peace" (lambda (arg) (not (equal "war" arg))) '("love" "hate" "war" "peace")) '("love" "hate" "peace" "peace"))) (test-t (equal (substitute-if-not "peace" (lambda (arg) (not (string-equal "war" arg))) '("war" "War" "WAr" "WAR")) '("peace" "peace" "peace" "peace"))) (test-t (equal (substitute-if-not "peace" (lambda (arg) (not (string= "WAR" arg))) '("war" "War" "WAr" "WAR") :key string-upcase) '("peace" "peace" "peace" "peace"))) (test-t (equal (substitute-if-not "peace" (lambda (arg) (not (string= "WAR" arg))) '("war" "War" "WAr" "WAR") :start 1 :end 2 :key string-upcase) '("war" "peace" "WAr" "WAR"))) (test-t (equal (substitute-if-not "peace" (lambda (arg) (not (string= "WAR" arg))) '("war" "War" "WAr" "WAR") :start 1 :end nil :key string-upcase) '("war" "peace" "peace" "peace"))) (test-t (equal (substitute-if-not "peace" (lambda (arg) (not (string= "war" arg))) '("war" "War" "WAr" "WAR") :key string-upcase) '("war" "War" "WAr" "WAR"))) (test-t (equal (substitute-if-not "peace" (lambda (arg) (not (string= "WAR" arg))) '("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR") :start 1 :end 7 :count 1 :key string-upcase) '("war" "peace" "WAr" "WAR" "war" "War" "WAr" "WAR"))) (test-t (equal (substitute-if-not "peace" (lambda (arg) (not (string= "WAR" arg))) '("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR") :start 1 :end 7 :count 2 :key string-upcase) '("war" "peace" "peace" "WAR" "war" "War" "WAr" "WAR"))) (test-t (equal (substitute-if-not "peace" (lambda (arg) (not (string= "WAR" arg))) '("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR") :start 1 :end 7 :count 2 :from-end t :key string-upcase) '("war" "War" "WAr" "WAR" "war" "peace" "peace" "WAR"))) (test-t (equal (substitute-if-not "peace" (lambda (arg) (not (string= "WAR" arg))) '("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR") :start 1 :end 7 :count 0 :from-end t :key string-upcase) '("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR"))) (test-t (equal (substitute-if-not "peace" (lambda (arg) (not (string= "WAR" arg))) '("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR") :start 1 :end 7 :count -2 :from-end t :key string-upcase) '("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR"))) (test-t (equal (substitute-if-not "peace" (lambda (arg) (not (string= "WAR" arg))) '("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR") :start 1 :end 7 :count nil :from-end t :key string-upcase) '("war" "peace" "peace" "peace" "peace" "peace" "peace" "WAR"))) (test-t (equal (substitute-if-not "peace" (lambda (arg) (not (string= "WAR" arg))) '("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR") :start 1 :end 7 :count 6 :from-end t :key string-upcase) '("war" "peace" "peace" "peace" "peace" "peace" "peace" "WAR"))) (test-t (equal (substitute-if-not "peace" (lambda (arg) (not (string= "WAR" arg))) '("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR") :start 1 :end 7 :count 7 :from-end t :key string-upcase) '("war" "peace" "peace" "peace" "peace" "peace" "peace" "WAR"))) (test-t (equal (substitute-if-not "peace" (lambda (arg) (not (string= "WAR" arg))) '("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR") :start 1 :end 7 :count 100 :from-end t :key string-upcase) '("war" "peace" "peace" "peace" "peace" "peace" "peace" "WAR"))) (test-t (equalp (substitute-if-not 'a (lambda (arg) (not (eq arg 'x))) #(x y z)) #(a y z))) (test-t (equalp (substitute-if-not 'b (lambda (arg) (not (eq arg 'y))) #(x y z)) #(x b z))) (test-t (equalp (substitute-if-not 'c (lambda (arg) (not (eq arg 'z))) #(x y z)) #(x y c))) (test-t (equalp (substitute-if-not 'a (lambda (arg) (not (eq arg 'p))) #(x y z)) #(x y z))) (test-t (equalp (substitute-if-not 'a (lambda (arg) (not (eq arg 'x))) #()) #())) (test-t (equalp (substitute-if-not #\x (lambda (arg) (not (char< #\b arg))) #(#\a #\b #\c #\d #\e)) #(#\a #\b #\x #\x #\x))) (test-t (equalp (substitute-if-not '(a) (lambda (arg) (not (eq arg 'x))) #((x) (y) (z)) :key car) #((a) (y) (z)))) (test-t (equalp (substitute-if-not 'c (lambda (arg) (not (eq arg 'b))) #(a b a b a b a b)) #(a c a c a c a c))) (test-t (equalp (substitute-if-not 'a (lambda (arg) (not (eq arg 'b))) #(b b b)) #(a a a))) (test-t (equalp (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) #(a x b x c x d x e x f)) #(a z b z c z d z e z f))) (test-t (equalp (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) #(a x b x c x d x e x f) :count nil) #(a z b z c z d z e z f))) (test-t (equalp (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) #(a x b x c x d x e x f) :count 0) #(a x b x c x d x e x f))) (test-t (equalp (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) #(a x b x c x d x e x f) :count -100) #(a x b x c x d x e x f))) (test-t (equalp (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) #(a x b x c x d x e x f) :count 1) #(a z b x c x d x e x f))) (test-t (equalp (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) #(a x b x c x d x e x f) :count 2) #(a z b z c x d x e x f))) (test-t (equalp (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) #(a x b x c x d x e x f) :count 3) #(a z b z c z d x e x f))) (test-t (equalp (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) #(a x b x c x d x e x f) :count 4) #(a z b z c z d z e x f))) (test-t (equalp (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) #(a x b x c x d x e x f) :count 5) #(a z b z c z d z e z f))) (test-t (equalp (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) #(a x b x c x d x e x f) :count 6) #(a z b z c z d z e z f))) (test-t (equalp (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) #(a x b x c x d x e x f) :count 7) #(a z b z c z d z e z f))) (test-t (equalp (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) #(a x b x c x d x e x f) :count nil :from-end t) #(a z b z c z d z e z f))) (test-t (equalp (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) #(a x b x c x d x e x f) :count 0 :from-end t) #(a x b x c x d x e x f))) (test-t (equalp (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) #(a x b x c x d x e x f) :count -100 :from-end t) #(a x b x c x d x e x f))) (test-t (equalp (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) #(a x b x c x d x e x f) :count 1 :from-end t) #(a x b x c x d x e z f))) (test-t (equalp (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) #(a x b x c x d x e x f) :count 2 :from-end t) #(a x b x c x d z e z f))) (test-t (equalp (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) #(a x b x c x d x e x f) :count 3 :from-end t) #(a x b x c z d z e z f))) (test-t (equalp (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) #(a x b x c x d x e x f) :count 4 :from-end t) #(a x b z c z d z e z f))) (test-t (equalp (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) #(a x b x c x d x e x f) :count 5 :from-end t) #(a z b z c z d z e z f))) (test-t (equalp (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) #(a x b x c x d x e x f) :count 6 :from-end t) #(a z b z c z d z e z f))) (test-t (equalp (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) #(a x b x c x d x e x f) :count 7 :from-end t) #(a z b z c z d z e z f))) (test-t (equalp (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) #(a x b x c x d x e x f) :start 2 :count 1) #(a x b z c x d x e x f))) (test-t (equalp (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) #(a x b x c x d x e x f) :start 2 :end nil :count 1) #(a x b z c x d x e x f))) (test-t (equalp (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) #(a x b x c x d x e x f) :start 2 :end 6 :count 100) #(a x b z c z d x e x f))) (test-t (equalp (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) #(a x b x c x d x e x f) :start 2 :end 11 :count 100) #(a x b z c z d z e z f))) (test-t (equalp (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) #(a x b x c x d x e x f) :start 2 :end 8 :count 10) #(a x b z c z d z e x f))) (test-t (equalp (substitute-if-not 'z (lambda (arg) (not (eq arg 'x))) #(a x b x c x d x e x f) :start 2 :end 8 :count 2 :from-end t) #(a x b x c z d z e x f))) (test-t (equalp (substitute-if-not #\z (lambda (arg) (not (char< #\c arg))) #(#\a #\b #\c #\d #\e #\f)) #(#\a #\b #\c #\z #\z #\z))) (test-t (equalp (substitute-if-not "peace" (lambda (arg) (not (equal "war" arg))) #("love" "hate" "war" "peace")) #("love" "hate" "peace" "peace"))) (test-t (equalp (substitute-if-not "peace" (lambda (arg) (not (string-equal "war" arg))) #("war" "War" "WAr" "WAR")) #("peace" "peace" "peace" "peace"))) (test-t (equalp (substitute-if-not "peace" (lambda (arg) (not (string= "WAR" arg))) #("war" "War" "WAr" "WAR") :key string-upcase) #("peace" "peace" "peace" "peace"))) (test-t (equalp (substitute-if-not "peace" (lambda (arg) (not (string= "WAR" arg))) #("war" "War" "WAr" "WAR") :start 1 :end 2 :key string-upcase) #("war" "peace" "WAr" "WAR"))) (test-t (equalp (substitute-if-not "peace" (lambda (arg) (not (string= "WAR" arg))) #("war" "War" "WAr" "WAR") :start 1 :end nil :key string-upcase) #("war" "peace" "peace" "peace"))) (test-t (equalp (substitute-if-not "peace" (lambda (arg) (not (string= "war" arg))) #("war" "War" "WAr" "WAR") :key string-upcase) #("war" "War" "WAr" "WAR"))) (test-t (equalp (substitute-if-not "peace" (lambda (arg) (not (string= "WAR" arg))) #("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR") :start 1 :end 7 :count 1 :key string-upcase) #("war" "peace" "WAr" "WAR" "war" "War" "WAr" "WAR"))) (test-t (equalp (substitute-if-not "peace" (lambda (arg) (not (string= "WAR" arg))) #("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR") :start 1 :end 7 :count 2 :key string-upcase) #("war" "peace" "peace" "WAR" "war" "War" "WAr" "WAR"))) (test-t (equalp (substitute-if-not "peace" (lambda (arg) (not (string= "WAR" arg))) #("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR") :start 1 :end 7 :count 2 :from-end t :key string-upcase) #("war" "War" "WAr" "WAR" "war" "peace" "peace" "WAR"))) (test-t (equalp (substitute-if-not "peace" (lambda (arg) (not (string= "WAR" arg))) #("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR") :start 1 :end 7 :count 0 :from-end t :key string-upcase) #("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR"))) (test-t (equalp (substitute-if-not "peace" (lambda (arg) (not (string= "WAR" arg))) #("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR") :start 1 :end 7 :count -2 :from-end t :key string-upcase) #("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR"))) (test-t (equalp (substitute-if-not "peace" (lambda (arg) (not (string= "WAR" arg))) #("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR") :start 1 :end 7 :count nil :from-end t :key string-upcase) #("war" "peace" "peace" "peace" "peace" "peace" "peace" "WAR"))) (test-t (equalp (substitute-if-not "peace" (lambda (arg) (not (string= "WAR" arg))) #("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR") :start 1 :end 7 :count 6 :from-end t :key string-upcase) #("war" "peace" "peace" "peace" "peace" "peace" "peace" "WAR"))) (test-t (equalp (substitute-if-not "peace" (lambda (arg) (not (string= "WAR" arg))) #("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR") :start 1 :end 7 :count 7 :from-end t :key string-upcase) #("war" "peace" "peace" "peace" "peace" "peace" "peace" "WAR"))) (test-t (equalp (substitute-if-not "peace" (lambda (arg) (not (string= "WAR" arg))) #("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR") :start 1 :end 7 :count 100 :from-end t :key string-upcase) #("war" "peace" "peace" "peace" "peace" "peace" "peace" "WAR"))) (test-t (string= (substitute-if-not #\A (lambda (arg) (not (eql #\a arg))) "abcabc") "AbcAbc")) (test-t (string= (substitute-if-not #\A (lambda (arg) (not (eql #\a arg))) "") "")) (test-t (string= (substitute-if-not #\A (lambda (arg) (not (eql #\a arg))) "xyz") "xyz")) (test-t (string= (substitute-if-not #\A (lambda (arg) (not (eql #\a arg))) "aaaaaaaaaa" :start 5 :end nil) "aaaaaAAAAA")) (test-t (string= (substitute-if-not #\x (lambda (arg) (not (char< #\5 arg))) "0123456789") "012345xxxx")) (test-t (string= (substitute-if-not #\x (lambda (arg) (not (char> #\5 arg))) "0123456789") "xxxxx56789")) (test-t (string= (substitute-if-not #\x (lambda (arg) (not (char> #\D arg))) "abcdefg" :key char-upcase) "xxxdefg")) (test-t (string= (substitute-if-not #\x (lambda (arg) (not (char> #\D arg))) "abcdefg" :start 1 :end 2 :key char-upcase) "axcdefg")) (test-t (string= (substitute-if-not #\A (lambda (arg) (not (eql #\a arg))) "aaaaaaaaaa" :count 2) "AAaaaaaaaa")) (test-t (string= (substitute-if-not #\A (lambda (arg) (not (eql #\a arg))) "aaaaaaaaaa" :count -1) "aaaaaaaaaa")) (test-t (string= (substitute-if-not #\A (lambda (arg) (not (eql #\a arg))) "aaaaaaaaaa" :count 0) "aaaaaaaaaa")) (test-t (string= (substitute-if-not #\A (lambda (arg) (not (eql #\a arg))) "aaaaaaaaaa" :count nil) "AAAAAAAAAA")) (test-t (string= (substitute-if-not #\A (lambda (arg) (not (eql #\a arg))) "aaaaaaaaaa" :count 100) "AAAAAAAAAA")) (test-t (string= (substitute-if-not #\A (lambda (arg) (not (eql #\a arg))) "aaaaaaaaaa" :count 9) "AAAAAAAAAa")) (test-t (string= (substitute-if-not #\A (lambda (arg) (not (eql #\a arg))) "aaaaaaaaaa" :count 9 :from-end t) "aAAAAAAAAA")) (test-t (string= (substitute-if-not #\A (lambda (arg) (not (eql #\a arg))) "aaaaaaaaaa" :start 2 :end 8 :count 3) "aaAAAaaaaa")) (test-t (string= (substitute-if-not #\A (lambda (arg) (not (eql #\a arg))) "aaaaaaaaaa" :start 2 :end 8 :from-end t :count 3) "aaaaaAAAaa")) (test-t (string= (substitute-if-not #\x (lambda (arg) (not (eql #\A arg))) "aaaaaaaaaa" :start 2 :end 8 :from-end t :count 3) "aaaaaaaaaa")) (test-t (string= (substitute-if-not #\X (lambda (arg) (not (eql #\A arg))) "aaaaaaaaaa" :start 2 :end 8 :from-end t :key char-upcase :count 3) "aaaaaXXXaa")) (test-t (string= (substitute-if-not #\X (lambda (arg) (not (char< #\D arg))) "abcdefghij" :start 2 :end 8 :from-end t :key char-upcase :count 3) "abcdeXXXij")) (test-t (equal (nsubstitute 'a 'x (copy-seq '(x y z))) '(a y z))) (test-t (equal (nsubstitute 'b 'y (copy-seq '(x y z))) '(x b z))) (test-t (equal (nsubstitute 'c 'z (copy-seq '(x y z))) '(x y c))) (test-t (equal (nsubstitute 'a 'p (copy-seq '(x y z))) '(x y z))) (test-t (equal (nsubstitute 'a 'x (copy-seq ())) ())) (test-t (equal (nsubstitute #\x #\b (copy-seq '(#\a #\b #\c #\d #\e)) :test char<) '(#\a #\b #\x #\x #\x))) (test-t (equal (nsubstitute '(a) 'x (copy-seq '((x) (y) (z))) :key car) '((a) (y) (z)))) (test-t (equal (nsubstitute 'c 'b (copy-seq '(a b a b a b a b))) '(a c a c a c a c))) (test-t (equal (nsubstitute 'a 'b (copy-seq '(b b b))) '(a a a))) (test-t (equal (nsubstitute 'z 'x (copy-seq '(a x b x c x d x e x f))) '(a z b z c z d z e z f))) (test-t (equal (nsubstitute 'z 'x (copy-seq '(a x b x c x d x e x f)) :count nil) '(a z b z c z d z e z f))) (test-t (equal (nsubstitute 'z 'x (copy-seq '(a x b x c x d x e x f)) :count 0) '(a x b x c x d x e x f))) (test-t (equal (nsubstitute 'z 'x (copy-seq '(a x b x c x d x e x f)) :count -100) '(a x b x c x d x e x f))) (test-t (equal (nsubstitute 'z 'x (copy-seq '(a x b x c x d x e x f)) :count 1) '(a z b x c x d x e x f))) (test-t (equal (nsubstitute 'z 'x (copy-seq '(a x b x c x d x e x f)) :count 2) '(a z b z c x d x e x f))) (test-t (equal (nsubstitute 'z 'x (copy-seq '(a x b x c x d x e x f)) :count 3) '(a z b z c z d x e x f))) (test-t (equal (nsubstitute 'z 'x (copy-seq '(a x b x c x d x e x f)) :count 4) '(a z b z c z d z e x f))) (test-t (equal (nsubstitute 'z 'x (copy-seq '(a x b x c x d x e x f)) :count 5) '(a z b z c z d z e z f))) (test-t (equal (nsubstitute 'z 'x (copy-seq '(a x b x c x d x e x f)) :count 6) '(a z b z c z d z e z f))) (test-t (equal (nsubstitute 'z 'x (copy-seq '(a x b x c x d x e x f)) :count 7) '(a z b z c z d z e z f))) (test-t (equal (nsubstitute 'z 'x (copy-seq '(a x b x c x d x e x f)) :count nil :from-end t) '(a z b z c z d z e z f))) (test-t (equal (nsubstitute 'z 'x (copy-seq '(a x b x c x d x e x f)) :count 0 :from-end t) '(a x b x c x d x e x f))) (test-t (equal (nsubstitute 'z 'x (copy-seq '(a x b x c x d x e x f)) :count -100 :from-end t) '(a x b x c x d x e x f))) (test-t (equal (nsubstitute 'z 'x (copy-seq '(a x b x c x d x e x f)) :count 1 :from-end t) '(a x b x c x d x e z f))) (test-t (equal (nsubstitute 'z 'x (copy-seq '(a x b x c x d x e x f)) :count 2 :from-end t) '(a x b x c x d z e z f))) (test-t (equal (nsubstitute 'z 'x (copy-seq '(a x b x c x d x e x f)) :count 3 :from-end t) '(a x b x c z d z e z f))) (test-t (equal (nsubstitute 'z 'x (copy-seq '(a x b x c x d x e x f)) :count 4 :from-end t) '(a x b z c z d z e z f))) (test-t (equal (nsubstitute 'z 'x (copy-seq '(a x b x c x d x e x f)) :count 5 :from-end t) '(a z b z c z d z e z f))) (test-t (equal (nsubstitute 'z 'x (copy-seq '(a x b x c x d x e x f)) :count 6 :from-end t) '(a z b z c z d z e z f))) (test-t (equal (nsubstitute 'z 'x (copy-seq '(a x b x c x d x e x f)) :count 7 :from-end t) '(a z b z c z d z e z f))) (test-t (equal (nsubstitute 'z 'x (copy-seq '(a x b x c x d x e x f)) :start 2 :count 1) '(a x b z c x d x e x f))) (test-t (equal (nsubstitute 'z 'x (copy-seq '(a x b x c x d x e x f)) :start 2 :end nil :count 1) '(a x b z c x d x e x f))) (test-t (equal (nsubstitute 'z 'x (copy-seq '(a x b x c x d x e x f)) :start 2 :end 6 :count 100) '(a x b z c z d x e x f))) (test-t (equal (nsubstitute 'z 'x (copy-seq '(a x b x c x d x e x f)) :start 2 :end 11 :count 100) '(a x b z c z d z e z f))) (test-t (equal (nsubstitute 'z 'x (copy-seq '(a x b x c x d x e x f)) :start 2 :end 8 :count 10) '(a x b z c z d z e x f))) (test-t (equal (nsubstitute 'z 'x (copy-seq '(a x b x c x d x e x f)) :start 2 :end 8 :count 2 :from-end t) '(a x b x c z d z e x f))) (test-t (equal (nsubstitute #\z #\c (copy-seq '(#\a #\b #\c #\d #\e #\f)) :test char<) '(#\a #\b #\c #\z #\z #\z))) (test-t (equal (nsubstitute "peace" "war" (copy-seq '("love" "hate" "war" "peace")) :test equal) '("love" "hate" "peace" "peace"))) (test-t (equal (nsubstitute "peace" "war" (copy-seq '("war" "War" "WAr" "WAR")) :test string-equal) '("peace" "peace" "peace" "peace"))) (test-t (equal (nsubstitute "peace" "WAR" (copy-seq '("war" "War" "WAr" "WAR")) :test string=) '("war" "War" "WAr" "peace"))) (test-t (equal (nsubstitute "peace" "WAR" (copy-seq '("war" "War" "WAr" "WAR")) :test string= :key string-upcase) '("peace" "peace" "peace" "peace"))) (test-t (equal (nsubstitute "peace" "WAR" (copy-seq '("war" "War" "WAr" "WAR")) :start 1 :end 2 :test string= :key string-upcase) '("war" "peace" "WAr" "WAR"))) (test-t (equalp (nsubstitute 'a 'x (copy-seq #(x y z))) #(a y z))) (test-t (equalp (nsubstitute 'b 'y (copy-seq #(x y z))) #(x b z))) (test-t (equalp (nsubstitute 'c 'z (copy-seq #(x y z))) #(x y c))) (test-t (equalp (nsubstitute 'a 'p (copy-seq #(x y z))) #(x y z))) (test-t (equalp (nsubstitute 'a 'x (copy-seq #())) #())) (test-t (equalp (nsubstitute #\x #\b (copy-seq #(#\a #\b #\c #\d #\e)) :test char<) #(#\a #\b #\x #\x #\x))) (test-t (equalp (nsubstitute '(a) 'x (copy-seq #((x) (y) (z))) :key car) #((a) (y) (z)))) (test-t (equalp (nsubstitute 'c 'b (copy-seq #(a b a b a b a b))) #(a c a c a c a c))) (test-t (equalp (nsubstitute 'a 'b (copy-seq #(b b b))) #(a a a))) (test-t (equalp (nsubstitute 'z 'x (copy-seq #(a x b x c x d x e x f))) #(a z b z c z d z e z f))) (test-t (equalp (nsubstitute 'z 'x (copy-seq #(a x b x c x d x e x f)) :count nil) #(a z b z c z d z e z f))) (test-t (equalp (nsubstitute 'z 'x (copy-seq #(a x b x c x d x e x f)) :count 0) #(a x b x c x d x e x f))) (test-t (equalp (nsubstitute 'z 'x (copy-seq #(a x b x c x d x e x f)) :count -100) #(a x b x c x d x e x f))) (test-t (equalp (nsubstitute 'z 'x (copy-seq #(a x b x c x d x e x f)) :count 1) #(a z b x c x d x e x f))) (test-t (equalp (nsubstitute 'z 'x (copy-seq #(a x b x c x d x e x f)) :count 2) #(a z b z c x d x e x f))) (test-t (equalp (nsubstitute 'z 'x (copy-seq #(a x b x c x d x e x f)) :count 3) #(a z b z c z d x e x f))) (test-t (equalp (nsubstitute 'z 'x (copy-seq #(a x b x c x d x e x f)) :count 4) #(a z b z c z d z e x f))) (test-t (equalp (nsubstitute 'z 'x (copy-seq #(a x b x c x d x e x f)) :count 5) #(a z b z c z d z e z f))) (test-t (equalp (nsubstitute 'z 'x (copy-seq #(a x b x c x d x e x f)) :count 6) #(a z b z c z d z e z f))) (test-t (equalp (nsubstitute 'z 'x (copy-seq #(a x b x c x d x e x f)) :count 7) #(a z b z c z d z e z f))) (test-t (equalp (nsubstitute 'z 'x (copy-seq #(a x b x c x d x e x f)) :count nil :from-end t) #(a z b z c z d z e z f))) (test-t (equalp (nsubstitute 'z 'x (copy-seq #(a x b x c x d x e x f)) :count 0 :from-end t) #(a x b x c x d x e x f))) (test-t (equalp (nsubstitute 'z 'x (copy-seq #(a x b x c x d x e x f)) :count -100 :from-end t) #(a x b x c x d x e x f))) (test-t (equalp (nsubstitute 'z 'x (copy-seq #(a x b x c x d x e x f)) :count 1 :from-end t) #(a x b x c x d x e z f))) (test-t (equalp (nsubstitute 'z 'x (copy-seq #(a x b x c x d x e x f)) :count 2 :from-end t) #(a x b x c x d z e z f))) (test-t (equalp (nsubstitute 'z 'x (copy-seq #(a x b x c x d x e x f)) :count 3 :from-end t) #(a x b x c z d z e z f))) (test-t (equalp (nsubstitute 'z 'x (copy-seq #(a x b x c x d x e x f)) :count 4 :from-end t) #(a x b z c z d z e z f))) (test-t (equalp (nsubstitute 'z 'x (copy-seq #(a x b x c x d x e x f)) :count 5 :from-end t) #(a z b z c z d z e z f))) (test-t (equalp (nsubstitute 'z 'x (copy-seq #(a x b x c x d x e x f)) :count 6 :from-end t) #(a z b z c z d z e z f))) (test-t (equalp (nsubstitute 'z 'x (copy-seq #(a x b x c x d x e x f)) :count 7 :from-end t) #(a z b z c z d z e z f))) (test-t (equalp (nsubstitute 'z 'x (copy-seq #(a x b x c x d x e x f)) :start 2 :count 1) #(a x b z c x d x e x f))) (test-t (equalp (nsubstitute 'z 'x (copy-seq #(a x b x c x d x e x f)) :start 2 :end nil :count 1) #(a x b z c x d x e x f))) (test-t (equalp (nsubstitute 'z 'x (copy-seq #(a x b x c x d x e x f)) :start 2 :end 6 :count 100) #(a x b z c z d x e x f))) (test-t (equalp (nsubstitute 'z 'x (copy-seq #(a x b x c x d x e x f)) :start 2 :end 11 :count 100) #(a x b z c z d z e z f))) (test-t (equalp (nsubstitute 'z 'x (copy-seq #(a x b x c x d x e x f)) :start 2 :end 8 :count 10) #(a x b z c z d z e x f))) (test-t (equalp (nsubstitute 'z 'x (copy-seq #(a x b x c x d x e x f)) :start 2 :end 8 :count 2 :from-end t) #(a x b x c z d z e x f))) (test-t (equalp (nsubstitute #\z #\c (copy-seq #(#\a #\b #\c #\d #\e #\f)) :test char<) #(#\a #\b #\c #\z #\z #\z))) (test-t (equalp (nsubstitute "peace" "war" (copy-seq #("love" "hate" "war" "peace")) :test equal) #("love" "hate" "peace" "peace"))) (test-t (equalp (nsubstitute "peace" "war" (copy-seq #("war" "War" "WAr" "WAR")) :test string-equal) #("peace" "peace" "peace" "peace"))) (test-t (equalp (nsubstitute "peace" "WAR" (copy-seq #("war" "War" "WAr" "WAR")) :test string=) #("war" "War" "WAr" "peace"))) (test-t (equalp (nsubstitute "peace" "WAR" (copy-seq #("war" "War" "WAr" "WAR")) :test string= :key string-upcase) #("peace" "peace" "peace" "peace"))) (test-t (equalp (nsubstitute "peace" "WAR" (copy-seq #("war" "War" "WAr" "WAR")) :start 1 :end 2 :test string= :key string-upcase) #("war" "peace" "WAr" "WAR"))) (test-t (equalp (nsubstitute "peace" "WAR" (copy-seq #("war" "War" "WAr" "WAR")) :start 1 :end nil :test string= :key cl-string-upcase) #("war" "peace" "peace" "peace"))) (test-t (string= (nsubstitute #\A #\a (copy-seq "abcabc")) "AbcAbc")) (test-t (string= (nsubstitute #\A #\a (copy-seq "")) "")) (test-t (string= (nsubstitute #\A #\a (copy-seq "xyz")) "xyz")) (test-t (string= (nsubstitute #\A #\a (copy-seq "aaaaaaaaaa") :start 5 :end nil) "aaaaaAAAAA")) (test-t (string= (nsubstitute #\x #\5 (copy-seq "0123456789") :test char<) "012345xxxx")) (test-t (string= (nsubstitute #\x #\5 (copy-seq "0123456789") :test char>) "xxxxx56789")) (test-t (string= (nsubstitute #\x #\D (copy-seq "abcdefg") :key char-upcase :test char>) "xxxdefg")) (test-t (string= (nsubstitute #\x #\D (copy-seq "abcdefg") :start 1 :end 2 :key char-upcase :test char>) "axcdefg")) (test-t (string= (nsubstitute #\A #\a (copy-seq "aaaaaaaaaa") :count 2) "AAaaaaaaaa")) (test-t (string= (nsubstitute #\A #\a (copy-seq "aaaaaaaaaa") :count -1) "aaaaaaaaaa")) (test-t (string= (nsubstitute #\A #\a (copy-seq "aaaaaaaaaa") :count 0) "aaaaaaaaaa")) (test-t (string= (nsubstitute #\A #\a (copy-seq "aaaaaaaaaa") :count nil) "AAAAAAAAAA")) (test-t (string= (nsubstitute #\A #\a (copy-seq "aaaaaaaaaa") :count 100) "AAAAAAAAAA")) (test-t (string= (nsubstitute #\A #\a (copy-seq "aaaaaaaaaa") :count 9) "AAAAAAAAAa")) (test-t (string= (nsubstitute #\A #\a (copy-seq "aaaaaaaaaa") :count 9 :from-end t) "aAAAAAAAAA")) (test-t (string= (nsubstitute #\A #\a (copy-seq "aaaaaaaaaa") :start 2 :end 8 :count 3) "aaAAAaaaaa")) (test-t (string= (nsubstitute #\A #\a (copy-seq "aaaaaaaaaa") :start 2 :end 8 :from-end t :count 3) "aaaaaAAAaa")) (test-t (string= (nsubstitute #\x #\A (copy-seq "aaaaaaaaaa") :start 2 :end 8 :from-end t :count 3) "aaaaaaaaaa")) (test-t (string= (nsubstitute #\X #\A (copy-seq "aaaaaaaaaa") :start 2 :end 8 :from-end t :key char-upcase :count 3) "aaaaaXXXaa")) (test-t (string= (nsubstitute #\X #\D (copy-seq "abcdefghij") :start 2 :end 8 :from-end t :key char-upcase :test char< :count 3) "abcdeXXXij")) (test-t (equal (nsubstitute-if 'a (lambda (arg) (eq arg 'x)) (copy-seq '(x y z))) '(a y z))) (test-t (equal (nsubstitute-if 'b (lambda (arg) (eq arg 'y)) (copy-seq '(x y z))) '(x b z))) (test-t (equal (nsubstitute-if 'c (lambda (arg) (eq arg 'z)) (copy-seq '(x y z))) '(x y c))) (test-t (equal (nsubstitute-if 'a (lambda (arg) (eq arg 'p)) (copy-seq '(x y z))) '(x y z))) (test-t (equal (nsubstitute-if 'a (lambda (arg) (eq arg 'x)) (copy-seq ())) ())) (test-t (equal (nsubstitute-if #\x (lambda (arg) (char< #\b arg)) (copy-seq '(#\a #\b #\c #\d #\e))) '(#\a #\b #\x #\x #\x))) (test-t (equal (nsubstitute-if '(a) (lambda (arg) (eq arg 'x)) (copy-seq '((x) (y) (z))) :key car) '((a) (y) (z)))) (test-t (equal (nsubstitute-if 'c (lambda (arg) (eq arg 'b)) (copy-seq '(a b a b a b a b))) '(a c a c a c a c))) (test-t (equal (nsubstitute-if 'a (lambda (arg) (eq arg 'b)) (copy-seq '(b b b))) '(a a a))) (test-t (equal (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq '(a x b x c x d x e x f))) '(a z b z c z d z e z f))) (test-t (equal (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq '(a x b x c x d x e x f)) :count nil) '(a z b z c z d z e z f))) (test-t (equal (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq '(a x b x c x d x e x f)) :count 0) '(a x b x c x d x e x f))) (test-t (equal (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq '(a x b x c x d x e x f)) :count -100) '(a x b x c x d x e x f))) (test-t (equal (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq '(a x b x c x d x e x f)) :count 1) '(a z b x c x d x e x f))) (test-t (equal (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq '(a x b x c x d x e x f)) :count 2) '(a z b z c x d x e x f))) (test-t (equal (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq '(a x b x c x d x e x f)) :count 3) '(a z b z c z d x e x f))) (test-t (equal (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq '(a x b x c x d x e x f)) :count 4) '(a z b z c z d z e x f))) (test-t (equal (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq '(a x b x c x d x e x f)) :count 5) '(a z b z c z d z e z f))) (test-t (equal (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq '(a x b x c x d x e x f)) :count 6) '(a z b z c z d z e z f))) (test-t (equal (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq '(a x b x c x d x e x f)) :count 7) '(a z b z c z d z e z f))) (test-t (equal (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq '(a x b x c x d x e x f)) :count nil :from-end t) '(a z b z c z d z e z f))) (test-t (equal (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq '(a x b x c x d x e x f)) :count 0 :from-end t) '(a x b x c x d x e x f))) (test-t (equal (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq '(a x b x c x d x e x f)) :count -100 :from-end t) '(a x b x c x d x e x f))) (test-t (equal (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq '(a x b x c x d x e x f)) :count 1 :from-end t) '(a x b x c x d x e z f))) (test-t (equal (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq '(a x b x c x d x e x f)) :count 2 :from-end t) '(a x b x c x d z e z f))) (test-t (equal (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq '(a x b x c x d x e x f)) :count 3 :from-end t) '(a x b x c z d z e z f))) (test-t (equal (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq '(a x b x c x d x e x f)) :count 4 :from-end t) '(a x b z c z d z e z f))) (test-t (equal (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq '(a x b x c x d x e x f)) :count 5 :from-end t) '(a z b z c z d z e z f))) (test-t (equal (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq '(a x b x c x d x e x f)) :count 6 :from-end t) '(a z b z c z d z e z f))) (test-t (equal (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq '(a x b x c x d x e x f)) :count 7 :from-end t) '(a z b z c z d z e z f))) (test-t (equal (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq '(a x b x c x d x e x f)) :start 2 :count 1) '(a x b z c x d x e x f))) (test-t (equal (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq '(a x b x c x d x e x f)) :start 2 :end nil :count 1) '(a x b z c x d x e x f))) (test-t (equal (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq '(a x b x c x d x e x f)) :start 2 :end 6 :count 100) '(a x b z c z d x e x f))) (test-t (equal (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq '(a x b x c x d x e x f)) :start 2 :end 11 :count 100) '(a x b z c z d z e z f))) (test-t (equal (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq '(a x b x c x d x e x f)) :start 2 :end 8 :count 10) '(a x b z c z d z e x f))) (test-t (equal (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq '(a x b x c x d x e x f)) :start 2 :end 8 :count 2 :from-end t) '(a x b x c z d z e x f))) (test-t (equal (nsubstitute-if #\z (lambda (arg) (char< #\c arg)) (copy-seq '(#\a #\b #\c #\d #\e #\f))) '(#\a #\b #\c #\z #\z #\z))) (test-t (equal (nsubstitute-if "peace" (lambda (arg) (equal "war" arg)) (copy-seq '("love" "hate" "war" "peace"))) '("love" "hate" "peace" "peace"))) (test-t (equal (nsubstitute-if "peace" (lambda (arg) (string-equal "war" arg)) (copy-seq '("war" "War" "WAr" "WAR"))) '("peace" "peace" "peace" "peace"))) (test-t (equal (nsubstitute-if "peace" (lambda (arg) (string= "WAR" arg)) (copy-seq '("war" "War" "WAr" "WAR")) :key string-upcase) '("peace" "peace" "peace" "peace"))) (test-t (equal (nsubstitute-if "peace" (lambda (arg) (string= "WAR" arg)) (copy-seq '("war" "War" "WAr" "WAR")) :start 1 :end 2 :key string-upcase) '("war" "peace" "WAr" "WAR"))) (test-t (equal (nsubstitute-if "peace" (lambda (arg) (string= "WAR" arg)) (copy-seq '("war" "War" "WAr" "WAR")) :start 1 :end nil :key string-upcase) '("war" "peace" "peace" "peace"))) (test-t (equal (nsubstitute-if "peace" (lambda (arg) (string= "war" arg)) (copy-seq '("war" "War" "WAr" "WAR")) :key string-upcase) '("war" "War" "WAr" "WAR"))) (test-t (equal (nsubstitute-if "peace" (lambda (arg) (string= "WAR" arg)) (copy-seq '("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR")) :start 1 :end 7 :count 1 :key string-upcase) '("war" "peace" "WAr" "WAR" "war" "War" "WAr" "WAR"))) (test-t (equal (nsubstitute-if "peace" (lambda (arg) (string= "WAR" arg)) (copy-seq '("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR")) :start 1 :end 7 :count 2 :key string-upcase) '("war" "peace" "peace" "WAR" "war" "War" "WAr" "WAR"))) (test-t (equal (nsubstitute-if "peace" (lambda (arg) (string= "WAR" arg)) (copy-seq '("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR")) :start 1 :end 7 :count 2 :from-end t :key string-upcase) '("war" "War" "WAr" "WAR" "war" "peace" "peace" "WAR"))) (test-t (equal (nsubstitute-if "peace" (lambda (arg) (string= "WAR" arg)) (copy-seq '("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR")) :start 1 :end 7 :count 0 :from-end t :key string-upcase) '("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR"))) (test-t (equal (nsubstitute-if "peace" (lambda (arg) (string= "WAR" arg)) (copy-seq '("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR")) :start 1 :end 7 :count -2 :from-end t :key string-upcase) '("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR"))) (test-t (equal (nsubstitute-if "peace" (lambda (arg) (string= "WAR" arg)) (copy-seq '("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR")) :start 1 :end 7 :count nil :from-end t :key string-upcase) '("war" "peace" "peace" "peace" "peace" "peace" "peace" "WAR"))) (test-t (equal (nsubstitute-if "peace" (lambda (arg) (string= "WAR" arg)) (copy-seq '("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR")) :start 1 :end 7 :count 6 :from-end t :key string-upcase) '("war" "peace" "peace" "peace" "peace" "peace" "peace" "WAR"))) (test-t (equal (nsubstitute-if "peace" (lambda (arg) (string= "WAR" arg)) (copy-seq '("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR")) :start 1 :end 7 :count 7 :from-end t :key string-upcase) '("war" "peace" "peace" "peace" "peace" "peace" "peace" "WAR"))) (test-t (equal (nsubstitute-if "peace" (lambda (arg) (string= "WAR" arg)) (copy-seq '("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR")) :start 1 :end 7 :count 100 :from-end t :key string-upcase) '("war" "peace" "peace" "peace" "peace" "peace" "peace" "WAR"))) (test-t (equalp (nsubstitute-if 'a (lambda (arg) (eq arg 'x)) (copy-seq #(x y z))) #(a y z))) (test-t (equalp (nsubstitute-if 'b (lambda (arg) (eq arg 'y)) (copy-seq #(x y z))) #(x b z))) (test-t (equalp (nsubstitute-if 'c (lambda (arg) (eq arg 'z)) (copy-seq #(x y z))) #(x y c))) (test-t (equalp (nsubstitute-if 'a (lambda (arg) (eq arg 'p)) (copy-seq #(x y z))) #(x y z))) (test-t (equalp (nsubstitute-if 'a (lambda (arg) (eq arg 'x)) (copy-seq #())) #())) (test-t (equalp (nsubstitute-if #\x (lambda (arg) (char< #\b arg)) (copy-seq #(#\a #\b #\c #\d #\e))) #(#\a #\b #\x #\x #\x))) (test-t (equalp (nsubstitute-if '(a) (lambda (arg) (eq arg 'x)) (copy-seq #((x) (y) (z))) :key car) #((a) (y) (z)))) (test-t (equalp (nsubstitute-if 'c (lambda (arg) (eq arg 'b)) (copy-seq #(a b a b a b a b))) #(a c a c a c a c))) (test-t (equalp (nsubstitute-if 'a (lambda (arg) (eq arg 'b)) (copy-seq #(b b b))) #(a a a))) (test-t (equalp (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq #(a x b x c x d x e x f))) #(a z b z c z d z e z f))) (test-t (equalp (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq #(a x b x c x d x e x f)) :count nil) #(a z b z c z d z e z f))) (test-t (equalp (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq #(a x b x c x d x e x f)) :count 0) #(a x b x c x d x e x f))) (test-t (equalp (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq #(a x b x c x d x e x f)) :count -100) #(a x b x c x d x e x f))) (test-t (equalp (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq #(a x b x c x d x e x f)) :count 1) #(a z b x c x d x e x f))) (test-t (equalp (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq #(a x b x c x d x e x f)) :count 2) #(a z b z c x d x e x f))) (test-t (equalp (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq #(a x b x c x d x e x f)) :count 3) #(a z b z c z d x e x f))) (test-t (equalp (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq #(a x b x c x d x e x f)) :count 4) #(a z b z c z d z e x f))) (test-t (equalp (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq #(a x b x c x d x e x f)) :count 5) #(a z b z c z d z e z f))) (test-t (equalp (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq #(a x b x c x d x e x f)) :count 6) #(a z b z c z d z e z f))) (test-t (equalp (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq #(a x b x c x d x e x f)) :count 7) #(a z b z c z d z e z f))) (test-t (equalp (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq #(a x b x c x d x e x f)) :count nil :from-end t) #(a z b z c z d z e z f))) (test-t (equalp (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq #(a x b x c x d x e x f)) :count 0 :from-end t) #(a x b x c x d x e x f))) (test-t (equalp (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq #(a x b x c x d x e x f)) :count -100 :from-end t) #(a x b x c x d x e x f))) (test-t (equalp (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq #(a x b x c x d x e x f)) :count 1 :from-end t) #(a x b x c x d x e z f))) (test-t (equalp (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq #(a x b x c x d x e x f)) :count 2 :from-end t) #(a x b x c x d z e z f))) (test-t (equalp (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq #(a x b x c x d x e x f)) :count 3 :from-end t) #(a x b x c z d z e z f))) (test-t (equalp (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq #(a x b x c x d x e x f)) :count 4 :from-end t) #(a x b z c z d z e z f))) (test-t (equalp (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq #(a x b x c x d x e x f)) :count 5 :from-end t) #(a z b z c z d z e z f))) (test-t (equalp (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq #(a x b x c x d x e x f)) :count 6 :from-end t) #(a z b z c z d z e z f))) (test-t (equalp (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq #(a x b x c x d x e x f)) :count 7 :from-end t) #(a z b z c z d z e z f))) (test-t (equalp (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq #(a x b x c x d x e x f)) :start 2 :count 1) #(a x b z c x d x e x f))) (test-t (equalp (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq #(a x b x c x d x e x f)) :start 2 :end nil :count 1) #(a x b z c x d x e x f))) (test-t (equalp (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq #(a x b x c x d x e x f)) :start 2 :end 6 :count 100) #(a x b z c z d x e x f))) (test-t (equalp (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq #(a x b x c x d x e x f)) :start 2 :end 11 :count 100) #(a x b z c z d z e z f))) (test-t (equalp (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq #(a x b x c x d x e x f)) :start 2 :end 8 :count 10) #(a x b z c z d z e x f))) (test-t (equalp (nsubstitute-if 'z (lambda (arg) (eq arg 'x)) (copy-seq #(a x b x c x d x e x f)) :start 2 :end 8 :count 2 :from-end t) #(a x b x c z d z e x f))) (test-t (equalp (nsubstitute-if #\z (lambda (arg) (char< #\c arg)) (copy-seq #(#\a #\b #\c #\d #\e #\f))) #(#\a #\b #\c #\z #\z #\z))) (test-t (equalp (nsubstitute-if "peace" (lambda (arg) (equal "war" arg)) (copy-seq #("love" "hate" "war" "peace"))) #("love" "hate" "peace" "peace"))) (test-t (equalp (nsubstitute-if "peace" (lambda (arg) (string-equal "war" arg)) (copy-seq #("war" "War" "WAr" "WAR"))) #("peace" "peace" "peace" "peace"))) (test-t (equalp (nsubstitute-if "peace" (lambda (arg) (string= "WAR" arg)) (copy-seq #("war" "War" "WAr" "WAR")) :key string-upcase) #("peace" "peace" "peace" "peace"))) (test-t (equalp (nsubstitute-if "peace" (lambda (arg) (string= "WAR" arg)) (copy-seq #("war" "War" "WAr" "WAR")) :start 1 :end 2 :key string-upcase) #("war" "peace" "WAr" "WAR"))) (test-t (equalp (nsubstitute-if "peace" (lambda (arg) (string= "WAR" arg)) (copy-seq #("war" "War" "WAr" "WAR")) :start 1 :end nil :key string-upcase) #("war" "peace" "peace" "peace"))) (test-t (equalp (nsubstitute-if "peace" (lambda (arg) (string= "war" arg)) (copy-seq #("war" "War" "WAr" "WAR")) :key string-upcase) #("war" "War" "WAr" "WAR"))) (test-t (equalp (nsubstitute-if "peace" (lambda (arg) (string= "WAR" arg)) (copy-seq #("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR")) :start 1 :end 7 :count 1 :key string-upcase) #("war" "peace" "WAr" "WAR" "war" "War" "WAr" "WAR"))) (test-t (equalp (nsubstitute-if "peace" (lambda (arg) (string= "WAR" arg)) (copy-seq #("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR")) :start 1 :end 7 :count 2 :key string-upcase) #("war" "peace" "peace" "WAR" "war" "War" "WAr" "WAR"))) (test-t (equalp (nsubstitute-if "peace" (lambda (arg) (string= "WAR" arg)) (copy-seq #("war" "War" "WAr" "WAR" "war" "War" "WAr" "WAR")) :start 1 :end 7 :count 2 :from-end t :key string-upcase) #("war" "War" "WAr" "WAR" "war" "peace" "peace" "WAR"))) (test-t (string= (nsubstitute-if #\A (lambda (arg) (eql #\a arg)) (copy-seq "abcabc")) "AbcAbc")) (test-t (string= (nsubstitute-if #\A (lambda (arg) (eql #\a arg)) (copy-seq "")) "")) (test-t (string= (nsubstitute-if #\A (lambda (arg) (eql #\a arg)) (copy-seq "xyz")) "xyz")) (test-t (string= (nsubstitute-if #\A (lambda (arg) (eql #\a arg)) (copy-seq "aaaaaaaaaa") :start 5 :end nil) "aaaaaAAAAA")) (test-t (string= (nsubstitute-if #\x (lambda (arg) (char< #\5 arg)) (copy-seq "0123456789")) "012345xxxx")) (test-t (string= (nsubstitute-if #\x (lambda (arg) (char> #\5 arg)) (copy-seq "0123456789")) "xxxxx56789")) (test-t (string= (nsubstitute-if #\x (lambda (arg) (char> #\D arg)) (copy-seq "abcdefg") :key char-upcase) "xxxdefg")) (test-t (string= (nsubstitute-if #\x (lambda (arg) (char> #\D arg)) (copy-seq "abcdefg") :start 1 :end 2 :key char-upcase) "axcdefg")) (test-t (string= (nsubstitute-if #\A (lambda (arg) (eql #\a arg)) (copy-seq "aaaaaaaaaa") :count 2) "AAaaaaaaaa")) (test-t (string= (nsubstitute-if #\A (lambda (arg) (eql #\a arg)) (copy-seq "aaaaaaaaaa") :count -1) "aaaaaaaaaa")) (test-t (string= (nsubstitute-if #\A (lambda (arg) (eql #\a arg)) (copy-seq "aaaaaaaaaa") :count 0) "aaaaaaaaaa")) (test-t (string= (nsubstitute-if #\A (lambda (arg) (eql #\a arg)) (copy-seq "aaaaaaaaaa") :count nil) "AAAAAAAAAA")) (test-t (string= (nsubstitute-if #\A (lambda (arg) (eql #\a arg)) (copy-seq "aaaaaaaaaa") :count 100) "AAAAAAAAAA")) (test-t (string= (nsubstitute-if #\A (lambda (arg) (eql #\a arg)) (copy-seq "aaaaaaaaaa") :count 9) "AAAAAAAAAa")) (test-t (string= (nsubstitute-if #\A (lambda (arg) (eql #\a arg)) (copy-seq "aaaaaaaaaa") :count 9 :from-end t) "aAAAAAAAAA")) (test-t (equal (nsubstitute-if-not 'a (lambda (arg) (not (eq arg 'x))) (copy-seq '(x y z))) '(a y z))) (test-t (equal (nsubstitute-if-not 'b (lambda (arg) (not (eq arg 'y))) (copy-seq '(x y z))) '(x b z))) (test-t (equal (nsubstitute-if-not 'c (lambda (arg) (not (eq arg 'z))) (copy-seq '(x y z))) '(x y c))) (test-t (equal (nsubstitute-if-not 'a (lambda (arg) (not (eq arg 'p))) (copy-seq '(x y z))) '(x y z))) (test-t (equal (nsubstitute-if-not 'a (lambda (arg) (not (eq arg 'x))) (copy-seq ())) ())) (test-t (equal (nsubstitute-if-not #\x (lambda (arg) (not (char< #\b arg))) (copy-seq '(#\a #\b #\c #\d #\e))) '(#\a #\b #\x #\x #\x))) (test-t (equal (nsubstitute-if-not '(a) (lambda (arg) (not (eq arg 'x))) (copy-seq '((x) (y) (z))) :key car) '((a) (y) (z)))) (test-t (equal (nsubstitute-if-not 'c (lambda (arg) (not (eq arg 'b))) (copy-seq '(a b a b a b a b))) '(a c a c a c a c))) (test-t (equal (nsubstitute-if-not 'a (lambda (arg) (not (eq arg 'b))) (copy-seq '(b b b))) '(a a a))) (test-t (equal (nsubstitute-if-not 'z (lambda (arg) (not (eq arg 'x))) (copy-seq '(a x b x c x d x e x f))) '(a z b z c z d z e z f))) (test-t (equal (nsubstitute-if-not 'z (lambda (arg) (not (eq arg 'x))) (copy-seq '(a x b x c x d x e x f)) :count nil) '(a z b z c z d z e z f))) (test-t (equal (nsubstitute-if-not 'z (lambda (arg) (not (eq arg 'x))) (copy-seq '(a x b x c x d x e x f)) :count 0) '(a x b x c x d x e x f))) (test-t (equal (nsubstitute-if-not 'z (lambda (arg) (not (eq arg 'x))) (copy-seq '(a x b x c x d x e x f)) :count -100) '(a x b x c x d x e x f))) (test-t (equal (nsubstitute-if-not 'z (lambda (arg) (not (eq arg 'x))) (copy-seq '(a x b x c x d x e x f)) :count 1) '(a z b x c x d x e x f))) (test-t (equal (nsubstitute-if-not 'z (lambda (arg) (not (eq arg 'x))) (copy-seq '(a x b x c x d x e x f)) :count 2) '(a z b z c x d x e x f))) (test-t (equal (nsubstitute-if-not 'z (lambda (arg) (not (eq arg 'x))) (copy-seq '(a x b x c x d x e x f)) :count 3) '(a z b z c z d x e x f))) (test-t (equal (nsubstitute-if-not 'z (lambda (arg) (not (eq arg 'x))) (copy-seq '(a x b x c x d x e x f)) :count 4) '(a z b z c z d z e x f))) (test-t (equal (nsubstitute-if-not 'z (lambda (arg) (not (eq arg 'x))) (copy-seq '(a x b x c x d x e x f)) :count 5) '(a z b z c z d z e z f))) (test-t (equal (nsubstitute-if-not 'z (lambda (arg) (not (eq arg 'x))) (copy-seq '(a x b x c x d x e x f)) :count 6) '(a z b z c z d z e z f))) (test-t (equal (nsubstitute-if-not 'z (lambda (arg) (not (eq arg 'x))) (copy-seq '(a x b x c x d x e x f)) :count 7) '(a z b z c z d z e z f))) ) (let () (define* (reduce function sequence from-end (start 0) end initial-value (key identity)) (let* ((slen (length sequence)) (nd (or (and (number? end) end) slen)) (len (min slen (- nd start)))) (if (< nd start) (error "~A :start ~A is greater than ~A ~A" __func__ start (if end ":end" "length") nd)) (if (not (positive? len)) (or initial-value (function)) (if (and (= len 1) (not initial-value)) (sequence start) (if (and (not from-end) (not (null? from-end))) (let* ((first-arg (or initial-value (key (sequence start)))) (second-arg (if initial-value (key (sequence start)) (key (sequence (+ start 1))))) (val (function first-arg second-arg))) (do ((i (if initial-value (+ start 1) (+ start 2)) (+ i 1))) ((= i nd) val) (set! val (function val (key (sequence i)))))) (let* ((second-arg (or initial-value (key (sequence (- nd 1))))) (first-arg (if initial-value (key (sequence (- nd 1))) (key (sequence (- nd 2))))) (val (function first-arg second-arg))) (do ((i (if initial-value (- nd 2) (- nd 3)) (- i 1))) ((< i start) val) (set! val (function (key (sequence i)) val))))))))) (test-t (eql (reduce * '(1 2 3 4 5)) 120)) (test-t (equal (reduce append '((1) (2)) :initial-value '(i n i t)) '(i n i t 1 2))) (test-t (equal (reduce append '((1) (2)) :from-end t :initial-value '(i n i t)) '(1 2 i n i t))) (test-t (eql (reduce - '(1 2 3 4)) -8)) (test-t (eql (reduce - '(1 2 3 4) :from-end t) -2)) (test-t (eql (reduce + ()) 0)) (test-t (eql (reduce + '(3)) 3)) (test-t (eq (reduce + '(foo)) 'foo)) (test-t (equal (reduce list '(1 2 3 4)) '(((1 2) 3) 4))) (test-t (equal (reduce list '(1 2 3 4) :from-end t) '(1 (2 (3 4))))) (test-t (equal (reduce list '(1 2 3 4) :initial-value 'foo) '((((foo 1) 2) 3) 4))) (test-t (equal (reduce list '(1 2 3 4) :from-end t :initial-value 'foo) '(1 (2 (3 (4 foo)))))) (test-t (equal (reduce list '(0 1 2 3)) '(((0 1) 2) 3))) (test-t (equal (reduce list '(0 1 2 3) :start 1) '((1 2) 3))) (test-t (equal (reduce list '(0 1 2 3) :start 1 :end nil) '((1 2) 3))) (test-t (equal (reduce list '(0 1 2 3) :start 2) '(2 3))) (test-t (eq (reduce list '(0 1 2 3) :start 0 :end 0) ())) (test-t (eq (reduce list '(0 1 2 3) :start 0 :end 0 :initial-value 'initial-value) 'initial-value)) (test-t (eq (reduce list '(0 1 2 3) :start 2 :end 2) ())) (test-t (eq (reduce list '(0 1 2 3) :start 2 :end 2 :initial-value 'initial-value) 'initial-value)) (test-t (eq (reduce list '(0 1 2 3) :start 4 :end 4) ())) (test-t (eq (reduce list '(0 1 2 3) :start 4 :end 4 :initial-value 'initial-value) 'initial-value)) (test-t (eql (reduce list '(0 1 2 3) :start 2 :end 3) 2)) (test-t (equal (reduce list '(0 1 2 3) :start 2 :end 3 :initial-value 'initial-value) '(initial-value 2))) (test-t (eql (reduce + '(0 1 2 3 4 5 6 7 8 9)) 45)) (test-t (eql (reduce - '(0 1 2 3 4 5 6 7 8 9)) -45)) (test-t (eql (reduce - '(0 1 2 3 4 5 6 7 8 9) :from-end t) -5)) (test-t (equal (reduce list '(0 1 2 3) :initial-value 'initial-value) '((((initial-value 0) 1) 2) 3))) (test-t (equal (reduce list '(0 1 2 3) :from-end t) '(0 (1 (2 3))))) (test-t (equal (reduce list '((1) (2) (3) (4)) :key car) '(((1 2) 3) 4))) ;(test-t (equal (reduce list '((1) (2) (3) (4)) :key car :from-end nil) '(((1 2) 3) 4))) (test-t (equal (reduce list '((1) (2) (3) (4)) :key car :initial-value 0) '((((0 1) 2) 3) 4))) (test-t (equal (reduce list '((1) (2) (3) (4)) :key car :from-end t) '(1 (2 (3 4))))) (test-t (equal (reduce list '((1) (2) (3) (4)) :key car :from-end t :initial-value 5) '(1 (2 (3 (4 5)))))) (test-t (equal (reduce list #(0 1 2 3)) '(((0 1) 2) 3))) (test-t (equal (reduce list #(0 1 2 3) :start 1) '((1 2) 3))) (test-t (equal (reduce list #(0 1 2 3) :start 1 :end nil) '((1 2) 3))) (test-t (equal (reduce list #(0 1 2 3) :start 2) '(2 3))) (test-t (eq (reduce list #(0 1 2 3) :start 0 :end 0) ())) (test-t (eq (reduce list #(0 1 2 3) :start 0 :end 0 :initial-value 'initial-value) 'initial-value)) (test-t (eq (reduce list #(0 1 2 3) :start 2 :end 2) ())) (test-t (eq (reduce list #(0 1 2 3) :start 2 :end 2 :initial-value 'initial-value) 'initial-value)) (test-t (eq (reduce list #(0 1 2 3) :start 4 :end 4) ())) (test-t (eq (reduce list #(0 1 2 3) :start 4 :end 4 :initial-value 'initial-value) 'initial-value)) (test-t (eql (reduce list #(0 1 2 3) :start 2 :end 3) 2)) (test-t (equal (reduce list #(0 1 2 3) :start 2 :end 3 :initial-value 'initial-value) '(initial-value 2))) (test-t (eql (reduce + #(0 1 2 3 4 5 6 7 8 9)) 45)) (test-t (eql (reduce - #(0 1 2 3 4 5 6 7 8 9)) -45)) (test-t (eql (reduce - #(0 1 2 3 4 5 6 7 8 9) :from-end t) -5)) (test-t (equal (reduce list #(0 1 2 3) :initial-value 'initial-value) '((((initial-value 0) 1) 2) 3))) (test-t (equal (reduce list #(0 1 2 3) :from-end t) '(0 (1 (2 3))))) (test-t (equal (reduce list #((1) (2) (3) (4)) :key car) '(((1 2) 3) 4))) ;(test-t (equal (reduce list #((1) (2) (3) (4)) :key car :from-end nil) '(((1 2) 3) 4))) (test-t (equal (reduce list #((1) (2) (3) (4)) :key car :initial-value 0) '((((0 1) 2) 3) 4))) (test-t (equal (reduce list #((1) (2) (3) (4)) :key car :from-end t) '(1 (2 (3 4))))) (test-t (equal (reduce list #((1) (2) (3) (4)) :key car :from-end t :initial-value 5) '(1 (2 (3 (4 5)))))) ) (define (nreverse sequence) (let ((len (length sequence))) (do ((i 0 (+ i 1)) (j (- len 1) (- j 1))) ((>= i j) sequence) (let ((tmp (sequence i))) (set! (sequence i) (sequence j)) (set! (sequence j) tmp))))) (define (cl-reverse sequence) (nreverse (copy sequence))) (define (elt sequence index) (sequence index)) ;; length is ok (define* (some predicate . sequences) (call-with-exit (lambda (return) (apply for-each (lambda args (let ((val (apply predicate args))) (if val (return val)))) sequences) #f))) (define* (notany predicate . sequences) (not (apply some predicate sequences))) (define* (every predicate . sequences) (call-with-exit (lambda (return) (apply for-each (lambda args (if (not (apply predicate args)) (return #f))) sequences) #t))) (define* (notevery predicate . sequences) (not (apply every predicate sequences))) (define* (cl-fill sequence item (start 0) end) ; actuall "fill" doesn't collide, but it's confusing (let ((nd (or (and (not (null? end)) end) (length sequence)))) (if (and (= start 0) (= nd (length sequence))) (fill! sequence item) (do ((i start (+ i 1))) ((= i nd)) (set! (sequence i) item))) sequence)) ;; many of the sequence functions return a different length sequence, but ;; for user-defined sequence types, we can't use the 'type kludge (or ;; at least it's ugly), so we need either (make obj size initial-value) ;; where obj is a representative of the desired type, or another ;; arg to copy giving the new object's size. For now, I'll cobble up ;; something explicit. ;; ;; perhaps the extended type could give its type symbol as well as the make function? (define (make obj size) (cond ((vector? obj) (make-vector size)) ((list? obj) (make-list size)) ((string? obj) (make-string size)) ((hash-table? obj) (make-hash-table size)))) ; does this make any sense? (define* (make-sequence type size initial-element) (case type ((vector bit-vector simple-vector) (make-vector size initial-element)) ((hash-table) (make-hash-table size)) ((string) (cl-make-string size (or initial-element #\null))) ; not #f! ((list) (cl-make-list size initial-element)) (else ()))) (define (cl-map type func . lists) (let* ((vals (apply mapcar func lists)) (len (length vals))) (let ((obj (make-sequence (or type 'list) len))) (if (> (length obj) 0) (do ((i 0 (+ i 1))) ((= i len)) (set! (obj i) (vals i)))) obj))) (define* (subseq sequence start end) (let* ((len (length sequence)) (nd (or (and (number? end) end) len)) (size (- nd start)) (obj (make sequence size))) (do ((i start (+ i 1)) (j 0 (+ j 1))) ((= i nd) obj) (set! (obj j) (sequence i))))) (define (concatenate type . sequences) (let* ((len (apply + (map length sequences))) (new-obj (make-sequence type len)) (ctr 0)) (for-each (lambda (sequence) (for-each (lambda (obj) (set! (new-obj ctr) obj) (set! ctr (+ ctr 1))) sequence)) sequences) new-obj)) ;; :(concatenate 'list "hiho" #(1 2)) -> (#\h #\i #\h #\o 1 2) (define* (replace seq1 seq2 (start1 0) end1 (start2 0) end2) (let* ((len1 (length seq1)) (len2 (length seq2)) (nd1 (or (and (number? end1) end1) len1)) (nd2 (or (and (number? end2) end2) len2))) (if (and (eq? seq1 seq2) (> start1 start2)) (let ((offset (- start1 start2))) (do ((i (- nd1 1) (- i 1))) ((< i start1) seq1) (set! (seq1 i) (seq1 (- i offset))))) (do ((i start1 (+ i 1)) (j start2 (+ j 1))) ((or (= i nd1) (= j nd2)) seq1) (set! (seq1 i) (seq2 j)))))) (let () (define* (remove-if predicate sequence from-end (start 0) end count (key identity)) (let* ((len (length sequence)) (nd (or (and (number? end) end) len)) (num (if (number? count) count len)) (changed 0)) (if (not (positive? num)) sequence (let ((result ())) (if (null from-end) (do ((i 0 (+ i 1))) ((= i len)) (if (or (< i start) (>= i nd) (>= changed num) (not (predicate (key (sequence i))))) (set! result (cons (sequence i) result)) (set! changed (+ changed 1)))) (do ((i (- len 1) (- i 1))) ((< i 0)) (if (or (< i start) (>= i nd) (>= changed num) (not (predicate (key (sequence i))))) (set! result (cons (sequence i) result)) (set! changed (+ changed 1))))) (let* ((len (length result)) (obj (make sequence len)) (vals (if (null from-end) (reverse result) result))) (do ((i 0 (+ i 1))) ((= i len)) (set! (obj i) (vals i))) obj))))) (define* (remove-if-not predicate sequence from-end (start 0) end count (key identity)) (remove-if (lambda (obj) (not (predicate obj))) sequence from-end start end count key)) (define* (remove item sequence from-end (test eql) (start 0) end count (key identity)) (remove-if (lambda (arg) (test item arg)) sequence from-end start end count key)) (define-macro* (delete-if predicate sequence from-end (start 0) end count (key identity)) `(let ((obj (remove-if ,predicate ,sequence ,from-end ,start ,end ,count ,key))) (if (symbol? ',sequence) (set! ,sequence obj)) obj)) (define-macro* (delete-if-not predicate sequence from-end (start 0) end count (key identity)) `(let ((obj (remove-if-not ,predicate ,sequence ,from-end ,start ,end ,count ,key))) (if (symbol? ',sequence) (set! ,sequence obj)) obj)) (define-macro* (delete item sequence from-end (test eql) (start 0) end count (key identity)) `(let ((obj (remove ,item ,sequence ,from-end ,test ,start ,end ,count ,key))) (if (symbol? ',sequence) (set! ,sequence obj)) obj)) (define* (remove-duplicates sequence from-end (test eql) (start 0) end (key identity)) (let* ((result ()) (start-seq (+ start 1)) (len (length sequence)) (nd (if (number? end) end len))) (do ((i start (+ i 1))) ((= i nd)) (let* ((orig-obj (sequence i)) (obj (key orig-obj))) (if (null from-end) (begin (if (not (find obj sequence :start start-seq :end nd :test test :key key)) (set! result (cons orig-obj result))) (set! start-seq (+ start-seq 1))) (if (not (find obj result :test test :key key)) (set! result (cons orig-obj result)))))) (let* ((res (reverse result)) (new-len (+ (length result) start (- len nd))) (new-seq (make sequence new-len))) (let ((n 0)) (do ((i 0 (+ i 1))) ((= i len) new-seq) (if (or (< i start) (>= i nd)) (begin (set! (new-seq n) (sequence i)) (set! n (+ n 1))) (if (not (null? res)) (begin (set! (new-seq n) (car res)) (set! res (cdr res)) (set! n (+ n 1)))))))))) (define-macro* (delete-duplicates sequence from-end (test eql) (start 0) end (key identity)) `(let ((obj (remove-duplicates ,sequence ,from-end ,test ,start ,end ,key))) (if (symbol? ,sequence) (set! ,sequence obj)) obj)) (test-t (equal (remove 4 '(1 3 4 5 9)) '(1 3 5 9))) (test-t (equal (remove 4 '(1 2 4 1 3 4 5)) '(1 2 1 3 5))) (test-t (equal (remove 4 '(1 2 4 1 3 4 5) :count 1) '(1 2 1 3 4 5))) (test-t (equal (remove 4 '(1 2 4 1 3 4 5) :count 1 :from-end t) '(1 2 4 1 3 5))) (test-t (equal (remove 3 '(1 2 4 1 3 4 5) :test >) '(4 3 4 5))) (test-t (let* ((lst '(list of four elements)) (lst2 (copy-seq lst)) (lst3 (delete 'four lst))) (and (equal lst3 '(list of elements)) (not (equal lst lst2))))) (test-t (equal (remove-if oddp '(1 2 4 1 3 4 5)) '(2 4 4))) (test-t (equal (remove-if evenp '(1 2 4 1 3 4 5) :count 1 :from-end t) '(1 2 4 1 3 5))) (test-t (equal (remove-if-not evenp '(1 2 3 4 5 6 7 8 9) :count 2 :from-end t) '(1 2 3 4 5 6 8))) (test-t (equal (delete 4 (list 1 2 4 1 3 4 5)) '(1 2 1 3 5))) (test-t (equal (delete 4 (list 1 2 4 1 3 4 5) :count 1) '(1 2 1 3 4 5))) (test-t (equal (delete 4 (list 1 2 4 1 3 4 5) :count 1 :from-end t) '(1 2 4 1 3 5))) (test-t (equal (delete 3 (list 1 2 4 1 3 4 5) :test >) '(4 3 4 5))) (test-t (equal (delete-if oddp (list 1 2 4 1 3 4 5)) '(2 4 4))) (test-t (equal (delete-if evenp (list 1 2 4 1 3 4 5) :count 1 :from-end t) '(1 2 4 1 3 5))) (test-t (equal (delete-if evenp (list 1 2 3 4 5 6)) '(1 3 5))) (test-t (let* ((list0 (list 0 1 2 3 4)) (list (remove 3 list0))) (and (not (eq list0 list)) (equal list0 '(0 1 2 3 4)) (equal list '(0 1 2 4))))) (test-t (equal (remove 'a (list 'a 'b 'c 'a 'b 'c)) '(b c b c))) (test-t (equal (remove 'b (list 'a 'b 'c 'a 'b 'c)) '(a c a c))) (test-t (equal (remove 'c (list 'a 'b 'c 'a 'b 'c)) '(a b a b))) (test-t (equal (remove 'a (list 'a 'a 'a)) ())) (test-t (equal (remove 'z (list 'a 'b 'c)) '(a b c))) (test-t (equal (remove 'a ()) ())) (test-t (equal (remove 'a (list 'a 'b 'c 'a 'b 'c) :count 0) '(a b c a b c))) (test-t (equal (remove 'a (list 'a 'b 'c 'a 'b 'c) :count 1) '(b c a b c))) (test-t (equal (remove 'a (list 'a 'b 'c 'a 'b 'c) :count 1 :from-end t) '(a b c b c))) (test-t (equal (remove 'a (list 'a 'b 'c 'a 'b 'c) :count 2) '(b c b c))) (test-t (equal (remove 'a (list 'a 'b 'c 'a 'b 'c) :count 2 :from-end t) '(b c b c))) (test-t (equal (remove 'a (list 'a 'b 'c 'a 'b 'c) :count 3) '(b c b c))) (test-t (equal (remove 'a (list 'a 'b 'c 'a 'b 'c) :count 3 :from-end t) '(b c b c))) (test-t (equal (remove 'a (list 'a 'b 'c 'a 'b 'c) :count 4) '(b c b c))) (test-t (equal (remove 'a (list 'a 'b 'c 'a 'b 'c) :count 4 :from-end t) '(b c b c))) (test-t (equal (remove 'a (list 'a 'b 'c 'a 'b 'c) :count -1) '(a b c a b c))) (test-t (equal (remove 'a (list 'a 'b 'c 'a 'b 'c) :count -10) '(a b c a b c))) (test-t (equal (remove 'a (list 'a 'b 'c 'a 'b 'c) :count -100) '(a b c a b c))) (test-t (equal (remove 'a (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1) '(a b c b c b c b c))) (test-t (equal (remove 'a (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :count 1) '(a b c b c a b c a b c))) (test-t (equal (remove 'a (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :count 2) '(a b c b c b c a b c))) (test-t (equal (remove 'a (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end nil :count 2) '(a b c b c b c a b c))) (test-t (equal (remove 'a (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8) '(a b c b c b c a b c))) (test-t (equal (remove 'a (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8 :count 1) '(a b c b c a b c a b c))) (test-t (equal (remove 'a (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8 :count 1 :from-end t) '(a b c a b c b c a b c))) (test-t (equal (remove 'a (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8 :count 0 :from-end t) '(a b c a b c a b c a b c))) (test-t (equal (remove 'a (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8 :count -100 :from-end t) '(a b c a b c a b c a b c))) (test-t (equal (remove 'a (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 1) '(a b c a b c a b c a b c))) (test-t (equal (remove 'a (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 2 :end 2) '(a b c a b c a b c a b c))) (test-t (equal (remove 'a (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 12 :end 12) '(a b c a b c a b c a b c))) (test-t (equal (remove 'a (list '(a) '(b) '(c) '(a) '(b) '(c)) :key car) '((b) (c) (b) (c)))) (test-t (equal (remove 'a (list '(a . b) '(b . c) '(c . a) '(a . b) '(b . c) '(c . a)) :key cdr) '((a . b) (b . c) (a . b) (b . c)))) (test-t (equal (remove "love" (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car) '(("Love") ("LOve") ("LOVe") ("LOVE")))) (test-t (equal (remove "love" (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count -10) '(("Love") ("LOve") ("LOVe") ("LOVE")))) (test-t (equal (remove "love" (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :test string-equal) ())) (test-t (equal (remove "love" (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :test string-equal :count 1) '(("LOve") ("LOVe") ("LOVE")))) (test-t (equal (remove "love" (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :test string-equal :count 1 :from-end t) '(("Love") ("LOve") ("LOVe")))) (test-t (equal (remove "love" (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :test string-equal :count 2 :from-end t) '(("Love") ("LOve")))) (test-t (equal (remove "love" (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :test string-equal :start 1 :end 3) '(("Love") ("LOVE")))) (test-t (equal (remove "love" (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :test string-equal :count 1 :start 1 :end 3) '(("Love") ("LOVe") ("LOVE")))) (test-t (equal (remove "love" (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :test string-equal :count 1 :from-end t :start 1 :end 3) '(("Love") ("LOve") ("LOVE")))) (test-t (equal (remove "love" (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :test string-equal :count 10 :from-end t :start 1 :end 3) '(("Love") ("LOVE")))) (test-t (let* ((vector0 (vector 0 1 2 3 4)) (vector (remove 3 vector0))) (and (not (eq vector0 vector)) (equalp vector0 #(0 1 2 3 4)) (equalp vector #(0 1 2 4))))) (test-t (equalp (remove 'a (vector 'a 'b 'c 'a 'b 'c)) #(b c b c))) (test-t (equalp (remove 'b (vector 'a 'b 'c 'a 'b 'c)) #(a c a c))) (test-t (equalp (remove 'c (vector 'a 'b 'c 'a 'b 'c)) #(a b a b))) (test-t (equalp (remove 'a (vector 'a 'a 'a)) #())) (test-t (equalp (remove 'z (vector 'a 'b 'c)) #(a b c))) (test-t (equalp (remove 'a #()) #())) (test-t (equalp (remove 'a (vector 'a 'b 'c 'a 'b 'c) :count 0) #(a b c a b c))) (test-t (equalp (remove 'a (vector 'a 'b 'c 'a 'b 'c) :count 1) #(b c a b c))) (test-t (equalp (remove 'a (vector 'a 'b 'c 'a 'b 'c) :count 1 :from-end t) #(a b c b c))) (test-t (equalp (remove 'a (vector 'a 'b 'c 'a 'b 'c) :count 2) #(b c b c))) (test-t (equalp (remove 'a (vector 'a 'b 'c 'a 'b 'c) :count 2 :from-end t) #(b c b c))) (test-t (equalp (remove 'a (vector 'a 'b 'c 'a 'b 'c) :count 3) #(b c b c))) (test-t (equalp (remove 'a (vector 'a 'b 'c 'a 'b 'c) :count 3 :from-end t) #(b c b c))) (test-t (equalp (remove 'a (vector 'a 'b 'c 'a 'b 'c) :count 4) #(b c b c))) (test-t (equalp (remove 'a (vector 'a 'b 'c 'a 'b 'c) :count 4 :from-end t) #(b c b c))) (test-t (equalp (remove 'a (vector 'a 'b 'c 'a 'b 'c) :count -1) #(a b c a b c))) (test-t (equalp (remove 'a (vector 'a 'b 'c 'a 'b 'c) :count -10) #(a b c a b c))) (test-t (equalp (remove 'a (vector 'a 'b 'c 'a 'b 'c) :count -100) #(a b c a b c))) (test-t (equalp (remove 'a (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1) #(a b c b c b c b c))) (test-t (equalp (remove 'a (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :count 1) #(a b c b c a b c a b c))) (test-t (equalp (remove 'a (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :count 2) #(a b c b c b c a b c))) (test-t (equalp (remove 'a (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end nil :count 2) #(a b c b c b c a b c))) (test-t (equalp (remove 'a (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8) #(a b c b c b c a b c))) (test-t (equalp (remove 'a (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8 :count 1) #(a b c b c a b c a b c))) (test-t (equalp (remove 'a (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8 :count 1 :from-end t) #(a b c a b c b c a b c))) (test-t (equalp (remove 'a (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8 :count 0 :from-end t) #(a b c a b c a b c a b c))) (test-t (equalp (remove 'a (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8 :count -100 :from-end t) #(a b c a b c a b c a b c))) (test-t (equalp (remove 'a (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 1) #(a b c a b c a b c a b c))) (test-t (equalp (remove 'a (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 2 :end 2) #(a b c a b c a b c a b c))) (test-t (equalp (remove 'a (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 12 :end 12) #(a b c a b c a b c a b c))) (test-t (equalp (remove 'a (vector '(a) '(b) '(c) '(a) '(b) '(c)) :key car) #((b) (c) (b) (c)))) (test-t (equalp (remove 'a (vector '(a . b) '(b . c) '(c . a) '(a . b) '(b . c) '(c . a)) :key cdr) #((a . b) (b . c) (a . b) (b . c)))) (test-t (equalp (remove "love" (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car) #(("Love") ("LOve") ("LOVe") ("LOVE")))) (test-t (equalp (remove "love" (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count -10) #(("Love") ("LOve") ("LOVe") ("LOVE")))) (test-t (equalp (remove "love" (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :test string-equal) #())) (test-t (equalp (remove "love" (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :test string-equal :count 1) #(("LOve") ("LOVe") ("LOVE")))) (test-t (equalp (remove "love" (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :test string-equal :count 1 :from-end t) #(("Love") ("LOve") ("LOVe")))) (test-t (equalp (remove "love" (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :test string-equal :count 2 :from-end t) #(("Love") ("LOve")))) (test-t (equalp (remove "love" (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :test string-equal :start 1 :end 3) #(("Love") ("LOVE")))) (test-t (equalp (remove "love" (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :test string-equal :count 1 :start 1 :end 3) #(("Love") ("LOVe") ("LOVE")))) (test-t (equalp (remove "love" (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :test string-equal :count 1 :from-end t :start 1 :end 3) #(("Love") ("LOve") ("LOVE")))) (test-t (equalp (remove "love" (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :test string-equal :count 10 :from-end t :start 1 :end 3) #(("Love") ("LOVE")))) (test-t (string= (remove #\a (copy-seq "abcabc")) "bcbc")) (test-t (string= (remove #\a (copy-seq "")) "")) (test-t (string= (remove #\a (copy-seq "xyz")) "xyz")) (test-t (string= (remove #\a (copy-seq "ABCABC")) "ABCABC")) (test-t (string= (remove #\a (copy-seq "ABCABC") :key char-downcase) "BCBC")) (test-t (string= (remove #\a (copy-seq "abcabc") :count 1) "bcabc")) (test-t (string= (remove #\a (copy-seq "abcabc") :count 1 :from-end t) "abcbc")) (test-t (string= (remove #\a (copy-seq "abcabc") :count 0) "abcabc")) (test-t (string= (remove #\a (copy-seq "abcabc") :count -10) "abcabc")) (test-t (let* ((str0 (copy-seq "abc")) (str (remove #\a str0))) (and (not (eq str0 str)) (string= str0 "abc") (string= str "bc")))) (test-t (string= (remove #\a (copy-seq "abcabc") :count 0) "abcabc")) (test-t (string= (remove #\a (copy-seq "abcabc")) "bcbc")) (test-t (string= (remove #\b (copy-seq "abcabc")) "acac")) (test-t (string= (remove #\c (copy-seq "abcabc")) "abab")) (test-t (string= (remove #\a (copy-seq "abcabc") :count 0) "abcabc")) (test-t (string= (remove #\a (copy-seq "abcabc") :count 1) "bcabc")) (test-t (string= (remove #\a (copy-seq "abcabc") :count 1 :from-end t) "abcbc")) (test-t (string= (remove #\a (copy-seq "abcabc") :count 2) "bcbc")) (test-t (string= (remove #\a (copy-seq "abcabc") :count 2 :from-end t) "bcbc")) (test-t (string= (remove #\a (copy-seq "abcabc") :count 3) "bcbc")) (test-t (string= (remove #\a (copy-seq "abcabc") :count 3 :from-end t) "bcbc")) (test-t (string= (remove #\a (copy-seq "abcabc") :count 4) "bcbc")) (test-t (string= (remove #\a (copy-seq "abcabc") :count 4 :from-end t) "bcbc")) (test-t (string= (remove #\a (copy-seq "abcabc") :count -1) "abcabc")) (test-t (string= (remove #\a (copy-seq "abcabc") :count -10) "abcabc")) (test-t (string= (remove #\a (copy-seq "abcabc") :count -100) "abcabc")) (test-t (string= (remove #\a (copy-seq "abcabcabcabc") :start 1) "abcbcbcbc")) (test-t (string= (remove #\a (copy-seq "abcabcabcabc") :start 1 :count 1) "abcbcabcabc")) (test-t (string= (remove #\a (copy-seq "abcabcabcabc") :start 1 :count 2) "abcbcbcabc")) (test-t (string= (remove #\a (copy-seq "abcabcabcabc") :start 1 :end nil :count 2) "abcbcbcabc")) (test-t (string= (remove #\a (copy-seq "abcabcabcabc") :start 1 :end 8) "abcbcbcabc")) (test-t (string= (remove #\a (copy-seq "abcabcabcabc") :start 1 :end 8 :count 1) "abcbcabcabc")) (test-t (string= (remove #\a (copy-seq "abcabcabcabc") :start 1 :end 8 :count 1 :from-end t) "abcabcbcabc")) (test-t (string= (remove #\a (copy-seq "abcabcabcabc") :start 1 :end 8 :count 0 :from-end t) "abcabcabcabc")) (test-t (string= (remove #\a (copy-seq "abcabcabcabc") :start 1 :end 8 :count -100 :from-end t) "abcabcabcabc")) (test-t (string= (remove #\a (copy-seq "abcabcabcabc") :start 1 :end 1) "abcabcabcabc")) (test-t (string= (remove #\a (copy-seq "abcabcabcabc") :start 2 :end 2) "abcabcabcabc")) (test-t (string= (remove #\a (copy-seq "abcabcabcabc") :start 12 :end 12) "abcabcabcabc")) (test-t (let* ((list0 (list 0 1 2 3 4)) (list (remove-if (lambda (arg) (eql arg 3)) list0))) (and (not (eq list0 list)) (equal list0 '(0 1 2 3 4)) (equal list '(0 1 2 4))))) (test-t (equal (remove-if (lambda (arg) (eql arg 'a)) (list 'a 'b 'c 'a 'b 'c)) '(b c b c))) (test-t (equal (remove-if (lambda (arg) (eql arg 'b)) (list 'a 'b 'c 'a 'b 'c)) '(a c a c))) (test-t (equal (remove-if (lambda (arg) (eql arg 'c)) (list 'a 'b 'c 'a 'b 'c)) '(a b a b))) (test-t (equal (remove-if (lambda (arg) (eql arg 'a)) (list 'a 'a 'a)) ())) (test-t (equal (remove-if (lambda (arg) (eql arg 'z)) (list 'a 'b 'c)) '(a b c))) (test-t (equal (remove-if (lambda (arg) (eql arg 'a)) ()) ())) (test-t (equal (remove-if (lambda (arg) (eql arg 'a)) (list 'a 'b 'c 'a 'b 'c) :count 0) '(a b c a b c))) (test-t (equal (remove-if (lambda (arg) (eql arg 'a)) (list 'a 'b 'c 'a 'b 'c) :count 1) '(b c a b c))) (test-t (equal (remove-if (lambda (arg) (eql arg 'a)) (list 'a 'b 'c 'a 'b 'c) :count 1 :from-end t) '(a b c b c))) (test-t (equal (remove-if (lambda (arg) (eql arg 'a)) (list 'a 'b 'c 'a 'b 'c) :count 2) '(b c b c))) (test-t (equal (remove-if (lambda (arg) (eql arg 'a)) (list 'a 'b 'c 'a 'b 'c) :count 2 :from-end t) '(b c b c))) (test-t (equal (remove-if (lambda (arg) (eql arg 'a)) (list 'a 'b 'c 'a 'b 'c) :count 3) '(b c b c))) (test-t (equal (remove-if (lambda (arg) (eql arg 'a)) (list 'a 'b 'c 'a 'b 'c) :count 3 :from-end t) '(b c b c))) (test-t (equal (remove-if (lambda (arg) (eql arg 'a)) (list 'a 'b 'c 'a 'b 'c) :count 4) '(b c b c))) (test-t (equal (remove-if (lambda (arg) (eql arg 'a)) (list 'a 'b 'c 'a 'b 'c) :count 4 :from-end t) '(b c b c))) (test-t (equal (remove-if (lambda (arg) (eql arg 'a)) (list 'a 'b 'c 'a 'b 'c) :count -1) '(a b c a b c))) (test-t (equal (remove-if (lambda (arg) (eql arg 'a)) (list 'a 'b 'c 'a 'b 'c) :count -10) '(a b c a b c))) (test-t (equal (remove-if (lambda (arg) (eql arg 'a)) (list 'a 'b 'c 'a 'b 'c) :count -100) '(a b c a b c))) (test-t (equal (remove-if (lambda (arg) (eql arg 'a)) (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1) '(a b c b c b c b c))) (test-t (equal (remove-if (lambda (arg) (eql arg 'a)) (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :count 1) '(a b c b c a b c a b c))) (test-t (equal (remove-if (lambda (arg) (eql arg 'a)) (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :count 2) '(a b c b c b c a b c))) (test-t (equal (remove-if (lambda (arg) (eql arg 'a)) (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end nil :count 2) '(a b c b c b c a b c))) (test-t (equal (remove-if (lambda (arg) (eql arg 'a)) (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8) '(a b c b c b c a b c))) (test-t (equal (remove-if (lambda (arg) (eql arg 'a)) (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8 :count 1) '(a b c b c a b c a b c))) (test-t (equal (remove-if (lambda (arg) (eql arg 'a)) (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8 :count 1 :from-end t) '(a b c a b c b c a b c))) (test-t (equal (remove-if (lambda (arg) (eql arg 'a)) (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8 :count 0 :from-end t) '(a b c a b c a b c a b c))) (test-t (equal (remove-if (lambda (arg) (eql arg 'a)) (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8 :count -100 :from-end t) '(a b c a b c a b c a b c))) (test-t (equal (remove-if (lambda (arg) (eql arg 'a)) (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 1) '(a b c a b c a b c a b c))) (test-t (equal (remove-if (lambda (arg) (eql arg 'a)) (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 2 :end 2) '(a b c a b c a b c a b c))) (test-t (equal (remove-if (lambda (arg) (eql arg 'a)) (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 12 :end 12) '(a b c a b c a b c a b c))) (test-t (equal (remove-if (lambda (arg) (eql arg 'a)) (list '(a) '(b) '(c) '(a) '(b) '(c)) :key car) '((b) (c) (b) (c)))) (test-t (equal (remove-if (lambda (arg) (eql arg 'a)) (list '(a . b) '(b . c) '(c . a) '(a . b) '(b . c) '(c . a)) :key cdr) '((a . b) (b . c) (a . b) (b . c)))) (test-t (equal (remove-if (lambda (arg) (eql arg "love")) (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car) '(("Love") ("LOve") ("LOVe") ("LOVE")))) (test-t (equal (remove-if (lambda (arg) (eql arg "love")) (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count -10) '(("Love") ("LOve") ("LOVe") ("LOVE")))) (test-t (equal (remove-if (lambda (arg) (string-equal arg "love")) (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car) ())) (test-t (equal (remove-if (lambda (arg) (string-equal arg "love")) (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 1) '(("LOve") ("LOVe") ("LOVE")))) (test-t (equal (remove-if (lambda (arg) (string-equal arg "love")) (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 1 :from-end t) '(("Love") ("LOve") ("LOVe")))) (test-t (equal (remove-if (lambda (arg) (string-equal arg "love")) (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 2 :from-end t) '(("Love") ("LOve")))) (test-t (equal (remove-if (lambda (arg) (string-equal arg "love")) (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :start 1 :end 3) '(("Love") ("LOVE")))) (test-t (equal (remove-if (lambda (arg) (string-equal arg "love")) (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 1 :start 1 :end 3) '(("Love") ("LOVe") ("LOVE")))) (test-t (equal (remove-if (lambda (arg) (string-equal arg "love")) (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 1 :from-end t :start 1 :end 3) '(("Love") ("LOve") ("LOVE")))) (test-t (equal (remove-if (lambda (arg) (string-equal arg "love")) (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 10 :from-end t :start 1 :end 3) '(("Love") ("LOVE")))) (test-t (let* ((vector0 (vector 0 1 2 3 4)) (vector (remove-if (lambda (arg) (eql arg 3)) vector0))) (and (not (eq vector0 vector)) (equalp vector0 #(0 1 2 3 4)) (equalp vector #(0 1 2 4))))) (test-t (equalp (remove-if (lambda (arg) (eql arg 'a)) (vector 'a 'b 'c 'a 'b 'c)) #(b c b c))) (test-t (equalp (remove-if (lambda (arg) (eql arg 'b)) (vector 'a 'b 'c 'a 'b 'c)) #(a c a c))) (test-t (equalp (remove-if (lambda (arg) (eql arg 'c)) (vector 'a 'b 'c 'a 'b 'c)) #(a b a b))) (test-t (equalp (remove-if (lambda (arg) (eql arg 'a)) (vector 'a 'a 'a)) #())) (test-t (equalp (remove-if (lambda (arg) (eql arg 'z)) (vector 'a 'b 'c)) #(a b c))) (test-t (equalp (remove-if (lambda (arg) (eql arg 'a)) #()) #())) (test-t (equalp (remove-if (lambda (arg) (eql arg 'a)) (vector 'a 'b 'c 'a 'b 'c) :count 0) #(a b c a b c))) (test-t (equalp (remove-if (lambda (arg) (eql arg 'a)) (vector 'a 'b 'c 'a 'b 'c) :count 1) #(b c a b c))) (test-t (equalp (remove-if (lambda (arg) (eql arg 'a)) (vector 'a 'b 'c 'a 'b 'c) :count 1 :from-end t) #(a b c b c))) (test-t (equalp (remove-if (lambda (arg) (eql arg 'a)) (vector 'a 'b 'c 'a 'b 'c) :count 2) #(b c b c))) (test-t (equalp (remove-if (lambda (arg) (eql arg 'a)) (vector 'a 'b 'c 'a 'b 'c) :count 2 :from-end t) #(b c b c))) (test-t (equalp (remove-if (lambda (arg) (eql arg 'a)) (vector 'a 'b 'c 'a 'b 'c) :count 3) #(b c b c))) (test-t (equalp (remove-if (lambda (arg) (eql arg 'a)) (vector 'a 'b 'c 'a 'b 'c) :count 3 :from-end t) #(b c b c))) (test-t (equalp (remove-if (lambda (arg) (eql arg 'a)) (vector 'a 'b 'c 'a 'b 'c) :count 4) #(b c b c))) (test-t (equalp (remove-if (lambda (arg) (eql arg 'a)) (vector 'a 'b 'c 'a 'b 'c) :count 4 :from-end t) #(b c b c))) (test-t (equalp (remove-if (lambda (arg) (eql arg 'a)) (vector 'a 'b 'c 'a 'b 'c) :count -1) #(a b c a b c))) (test-t (equalp (remove-if (lambda (arg) (eql arg 'a)) (vector 'a 'b 'c 'a 'b 'c) :count -10) #(a b c a b c))) (test-t (equalp (remove-if (lambda (arg) (eql arg 'a)) (vector 'a 'b 'c 'a 'b 'c) :count -100) #(a b c a b c))) (test-t (equalp (remove-if (lambda (arg) (eql arg 'a)) (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1) #(a b c b c b c b c))) (test-t (equalp (remove-if (lambda (arg) (eql arg 'a)) (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :count 1) #(a b c b c a b c a b c))) (test-t (equalp (remove-if (lambda (arg) (eql arg 'a)) (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :count 2) #(a b c b c b c a b c))) (test-t (equalp (remove-if (lambda (arg) (eql arg 'a)) (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end nil :count 2) #(a b c b c b c a b c))) (test-t (equalp (remove-if (lambda (arg) (eql arg 'a)) (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8) #(a b c b c b c a b c))) (test-t (equalp (remove-if (lambda (arg) (eql arg 'a)) (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8 :count 1) #(a b c b c a b c a b c))) (test-t (equalp (remove-if (lambda (arg) (eql arg 'a)) (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8 :count 1 :from-end t) #(a b c a b c b c a b c))) (test-t (equalp (remove-if (lambda (arg) (eql arg 'a)) (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8 :count 0 :from-end t) #(a b c a b c a b c a b c))) (test-t (equalp (remove-if (lambda (arg) (eql arg 'a)) (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8 :count -100 :from-end t) #(a b c a b c a b c a b c))) (test-t (equalp (remove-if (lambda (arg) (eql arg 'a)) (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 1) #(a b c a b c a b c a b c))) (test-t (equalp (remove-if (lambda (arg) (eql arg 'a)) (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 2 :end 2) #(a b c a b c a b c a b c))) (test-t (equalp (remove-if (lambda (arg) (eql arg 'a)) (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 12 :end 12) #(a b c a b c a b c a b c))) (test-t (equalp (remove-if (lambda (arg) (eql arg 'a)) (vector '(a) '(b) '(c) '(a) '(b) '(c)) :key car) #((b) (c) (b) (c)))) (test-t (equalp (remove-if (lambda (arg) (eql arg 'a)) (vector '(a . b) '(b . c) '(c . a) '(a . b) '(b . c) '(c . a)) :key cdr) #((a . b) (b . c) (a . b) (b . c)))) (test-t (equalp (remove-if (lambda (arg) (eql arg "love")) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car) #(("Love") ("LOve") ("LOVe") ("LOVE")))) (test-t (equalp (remove-if (lambda (arg) (eql arg "love")) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count -10) #(("Love") ("LOve") ("LOVe") ("LOVE")))) (test-t (equalp (remove-if (lambda (arg) (string-equal arg "love")) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car) #())) (test-t (equalp (remove-if (lambda (arg) (string-equal arg "love")) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car) #())) (test-t (equalp (remove-if (lambda (arg) (string-equal arg "love")) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 1) #(("LOve") ("LOVe") ("LOVE")))) (test-t (equalp (remove-if (lambda (arg) (string-equal arg "love")) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 1) #(("LOve") ("LOVe") ("LOVE")))) (test-t (equalp (remove-if (lambda (arg) (string-equal arg "love")) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 1 :from-end t) #(("Love") ("LOve") ("LOVe")))) (test-t (equalp (remove-if (lambda (arg) (string-equal arg "love")) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 1 :from-end t) #(("Love") ("LOve") ("LOVe")))) (test-t (equalp (remove-if (lambda (arg) (string-equal arg "love")) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 2 :from-end t) #(("Love") ("LOve")))) (test-t (equalp (remove-if (lambda (arg) (string-equal arg "love")) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 2 :from-end t) #(("Love") ("LOve")))) (test-t (equalp (remove-if (lambda (arg) (string-equal arg "love")) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :start 1 :end 3) #(("Love") ("LOVE")))) (test-t (equalp (remove-if (lambda (arg) (string-equal arg "love")) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 1 :start 1 :end 3) #(("Love") ("LOVe") ("LOVE")))) (test-t (equalp (remove-if (lambda (arg) (string-equal arg "love")) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 1 :from-end t :start 1 :end 3) #(("Love") ("LOve") ("LOVE")))) (test-t (equalp (remove-if (lambda (arg) (string-equal arg "love")) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 10 :from-end t :start 1 :end 3) #(("Love") ("LOVE")))) (test-t (string= (remove-if (lambda (arg) (string-equal arg #\a)) (copy-seq "abcabc")) "bcbc")) (test-t (string= (remove-if (lambda (arg) (string-equal arg #\a)) (copy-seq "")) "")) (test-t (string= (remove-if (lambda (arg) (string-equal arg #\a)) (copy-seq "xyz")) "xyz")) (test-t (string= (remove-if (lambda (arg) (string-equal arg #\a)) (copy-seq "ABCABC") :key char-downcase) "BCBC")) (test-t (string= (remove-if (lambda (arg) (string-equal arg #\a)) (copy-seq "abcabc") :count 1) "bcabc")) (test-t (string= (remove-if (lambda (arg) (string-equal arg #\a)) (copy-seq "abcabc") :count 1 :from-end t) "abcbc")) (test-t (string= (remove-if (lambda (arg) (string-equal arg #\a)) (copy-seq "abcabc") :count 0) "abcabc")) (test-t (string= (remove-if (lambda (arg) (string-equal arg #\a)) (copy-seq "abcabc") :count -10) "abcabc")) (test-t (let* ((str0 (copy-seq "abc")) (str (remove-if (lambda (arg) (string-equal arg #\a)) str0))) (and (not (eq str0 str)) (string= str0 "abc") (string= str "bc")))) (test-t (string= (remove-if (lambda (arg) (string-equal arg #\a)) (copy-seq "abcabc") :count 0) "abcabc")) (test-t (string= (remove-if (lambda (arg) (string-equal arg #\a)) (copy-seq "abcabc")) "bcbc")) (test-t (string= (remove-if (lambda (arg) (string-equal arg #\b)) (copy-seq "abcabc")) "acac")) (test-t (string= (remove-if (lambda (arg) (string-equal arg #\c)) (copy-seq "abcabc")) "abab")) (test-t (string= (remove-if (lambda (arg) (string-equal arg #\a)) (copy-seq "abcabc") :count 0) "abcabc")) (test-t (string= (remove-if (lambda (arg) (string-equal arg #\a)) (copy-seq "abcabc") :count 1) "bcabc")) (test-t (string= (remove-if (lambda (arg) (string-equal arg #\a)) (copy-seq "abcabc") :count 1 :from-end t) "abcbc")) (test-t (string= (remove-if (lambda (arg) (string-equal arg #\a)) (copy-seq "abcabc") :count 2) "bcbc")) (test-t (string= (remove-if (lambda (arg) (string-equal arg #\a)) (copy-seq "abcabc") :count 2 :from-end t) "bcbc")) (test-t (string= (remove-if (lambda (arg) (string-equal arg #\a)) (copy-seq "abcabc") :count 3) "bcbc")) (test-t (string= (remove-if (lambda (arg) (string-equal arg #\a)) (copy-seq "abcabc") :count 3 :from-end t) "bcbc")) (test-t (string= (remove-if (lambda (arg) (string-equal arg #\a)) (copy-seq "abcabc") :count 4) "bcbc")) (test-t (string= (remove-if (lambda (arg) (string-equal arg #\a)) (copy-seq "abcabc") :count 4 :from-end t) "bcbc")) (test-t (string= (remove-if (lambda (arg) (string-equal arg #\a)) (copy-seq "abcabc") :count -1) "abcabc")) (test-t (string= (remove-if (lambda (arg) (string-equal arg #\a)) (copy-seq "abcabc") :count -10) "abcabc")) (test-t (string= (remove-if (lambda (arg) (string-equal arg #\a)) (copy-seq "abcabc") :count -100) "abcabc")) (test-t (string= (remove-if (lambda (arg) (string-equal arg #\a)) (copy-seq "abcabcabcabc") :start 1) "abcbcbcbc")) (test-t (string= (remove-if (lambda (arg) (string-equal arg #\a)) (copy-seq "abcabcabcabc") :start 1 :count 1) "abcbcabcabc")) (test-t (string= (remove-if (lambda (arg) (eql arg #\a)) (copy-seq "abcabcabcabc") :start 1 :count 2) "abcbcbcabc")) (test-t (string= (remove-if (lambda (arg) (eql arg #\a)) (copy-seq "abcabcabcabc") :start 1 :end nil :count 2) "abcbcbcabc")) (test-t (string= (remove-if (lambda (arg) (eql arg #\a)) (copy-seq "abcabcabcabc") :start 1 :end 8) "abcbcbcabc")) (test-t (string= (remove-if (lambda (arg) (eql arg #\a)) (copy-seq "abcabcabcabc") :start 1 :end 8 :count 1) "abcbcabcabc")) (test-t (string= (remove-if (lambda (arg) (eql arg #\a)) (copy-seq "abcabcabcabc") :start 1 :end 8 :count 1 :from-end t) "abcabcbcabc")) (test-t (string= (remove-if (lambda (arg) (eql arg #\a)) (copy-seq "abcabcabcabc") :start 1 :end 8 :count 0 :from-end t) "abcabcabcabc")) (test-t (string= (remove-if (lambda (arg) (eql arg #\a)) (copy-seq "abcabcabcabc") :start 1 :end 8 :count -100 :from-end t) "abcabcabcabc")) (test-t (string= (remove-if (lambda (arg) (eql arg #\a)) (copy-seq "abcabcabcabc") :start 1 :end 1) "abcabcabcabc")) (test-t (string= (remove-if (lambda (arg) (eql arg #\a)) (copy-seq "abcabcabcabc") :start 2 :end 2) "abcabcabcabc")) (test-t (string= (remove-if (lambda (arg) (eql arg #\a)) (copy-seq "abcabcabcabc") :start 12 :end 12) "abcabcabcabc")) (test-t (let* ((list0 (list 0 1 2 3 4)) (list (remove-if-not (lambda (arg) (not (eql arg 3))) list0))) (and (not (eq list0 list)) (equal list0 '(0 1 2 3 4)) (equal list '(0 1 2 4))))) (test-t (equal (remove-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'b 'c 'a 'b 'c)) '(b c b c))) (test-t (equal (remove-if-not (lambda (arg) (not (eql arg 'b))) (list 'a 'b 'c 'a 'b 'c)) '(a c a c))) (test-t (equal (remove-if-not (lambda (arg) (not (eql arg 'c))) (list 'a 'b 'c 'a 'b 'c)) '(a b a b))) (test-t (equal (remove-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'a 'a)) ())) (test-t (equal (remove-if-not (lambda (arg) (not (eql arg 'z))) (list 'a 'b 'c)) '(a b c))) (test-t (equal (remove-if-not (lambda (arg) (not (eql arg 'a))) ()) ())) (test-t (equal (remove-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'b 'c 'a 'b 'c) :count 0) '(a b c a b c))) (test-t (equal (remove-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'b 'c 'a 'b 'c) :count 1) '(b c a b c))) (test-t (equal (remove-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'b 'c 'a 'b 'c) :count 1 :from-end t) '(a b c b c))) (test-t (equal (remove-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'b 'c 'a 'b 'c) :count 2) '(b c b c))) (test-t (equal (remove-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'b 'c 'a 'b 'c) :count 2 :from-end t) '(b c b c))) (test-t (equal (remove-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'b 'c 'a 'b 'c) :count 3) '(b c b c))) (test-t (equal (remove-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'b 'c 'a 'b 'c) :count 3 :from-end t) '(b c b c))) (test-t (equal (remove-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'b 'c 'a 'b 'c) :count 4) '(b c b c))) (test-t (equal (remove-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'b 'c 'a 'b 'c) :count 4 :from-end t) '(b c b c))) (test-t (equal (remove-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'b 'c 'a 'b 'c) :count -1) '(a b c a b c))) (test-t (equal (remove-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'b 'c 'a 'b 'c) :count -10) '(a b c a b c))) (test-t (equal (remove-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'b 'c 'a 'b 'c) :count -100) '(a b c a b c))) (test-t (equal (remove-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1) '(a b c b c b c b c))) (test-t (equal (remove-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :count 1) '(a b c b c a b c a b c))) (test-t (equal (remove-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :count 2) '(a b c b c b c a b c))) (test-t (equal (remove-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end nil :count 2) '(a b c b c b c a b c))) (test-t (equal (remove-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8) '(a b c b c b c a b c))) (test-t (equal (remove-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8 :count 1) '(a b c b c a b c a b c))) (test-t (equal (remove-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8 :count 1 :from-end t) '(a b c a b c b c a b c))) (test-t (equal (remove-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8 :count 0 :from-end t) '(a b c a b c a b c a b c))) (test-t (equal (remove-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8 :count -100 :from-end t) '(a b c a b c a b c a b c))) (test-t (equal (remove-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 1) '(a b c a b c a b c a b c))) (test-t (equal (remove-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 2 :end 2) '(a b c a b c a b c a b c))) (test-t (equal (remove-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 12 :end 12) '(a b c a b c a b c a b c))) (test-t (equal (remove-if-not (lambda (arg) (not (eql arg 'a))) (list '(a) '(b) '(c) '(a) '(b) '(c)) :key car) '((b) (c) (b) (c)))) (test-t (equal (remove-if-not (lambda (arg) (not (eql arg 'a))) (list '(a . b) '(b . c) '(c . a) '(a . b) '(b . c) '(c . a)) :key cdr) '((a . b) (b . c) (a . b) (b . c)))) (test-t (equal (remove-if-not (lambda (arg) (not (eql arg "love"))) (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car) '(("Love") ("LOve") ("LOVe") ("LOVE")))) (test-t (equal (remove-if-not (lambda (arg) (not (eql arg "love"))) (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count -10) '(("Love") ("LOve") ("LOVe") ("LOVE")))) (test-t (equal (remove-if-not (lambda (arg) (not (string-equal arg "love"))) (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car) ())) (test-t (equal (remove-if-not (lambda (arg) (not (string-equal arg "love"))) (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 1) '(("LOve") ("LOVe") ("LOVE")))) (test-t (equal (remove-if-not (lambda (arg) (not (string-equal arg "love"))) (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 1 :from-end t) '(("Love") ("LOve") ("LOVe")))) (test-t (equal (remove-if-not (lambda (arg) (not (string-equal arg "love"))) (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 2 :from-end t) '(("Love") ("LOve")))) (test-t (equal (remove-if-not (lambda (arg) (not (string-equal arg "love"))) (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :start 1 :end 3) '(("Love") ("LOVE")))) (test-t (equal (remove-if-not (lambda (arg) (not (string-equal arg "love"))) (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 1 :start 1 :end 3) '(("Love") ("LOVe") ("LOVE")))) (test-t (equal (remove-if-not (lambda (arg) (not (string-equal arg "love"))) (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 1 :from-end t :start 1 :end 3) '(("Love") ("LOve") ("LOVE")))) (test-t (equal (remove-if-not (lambda (arg) (not (string-equal arg "love"))) (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 10 :from-end t :start 1 :end 3) '(("Love") ("LOVE")))) (test-t (let* ((vector0 (vector 0 1 2 3 4)) (vector (remove-if-not (lambda (arg) (not (eql arg 3))) vector0))) (and (not (eq vector0 vector)) (equalp vector0 #(0 1 2 3 4)) (equalp vector #(0 1 2 4))))) (test-t (equalp (remove-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'b 'c 'a 'b 'c)) #(b c b c))) (test-t (equalp (remove-if-not (lambda (arg) (not (eql arg 'b))) (vector 'a 'b 'c 'a 'b 'c)) #(a c a c))) (test-t (equalp (remove-if-not (lambda (arg) (not (eql arg 'c))) (vector 'a 'b 'c 'a 'b 'c)) #(a b a b))) (test-t (equalp (remove-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'a 'a)) #())) (test-t (equalp (remove-if-not (lambda (arg) (not (eql arg 'z))) (vector 'a 'b 'c)) #(a b c))) (test-t (equalp (remove-if-not (lambda (arg) (not (eql arg 'a))) #()) #())) (test-t (equalp (remove-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'b 'c 'a 'b 'c) :count 0) #(a b c a b c))) (test-t (equalp (remove-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'b 'c 'a 'b 'c) :count 1) #(b c a b c))) (test-t (equalp (remove-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'b 'c 'a 'b 'c) :count 1 :from-end t) #(a b c b c))) (test-t (equalp (remove-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'b 'c 'a 'b 'c) :count 2) #(b c b c))) (test-t (equalp (remove-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'b 'c 'a 'b 'c) :count 2 :from-end t) #(b c b c))) (test-t (equalp (remove-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'b 'c 'a 'b 'c) :count 3) #(b c b c))) (test-t (equalp (remove-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'b 'c 'a 'b 'c) :count 3 :from-end t) #(b c b c))) (test-t (equalp (remove-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'b 'c 'a 'b 'c) :count 4) #(b c b c))) (test-t (equalp (remove-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'b 'c 'a 'b 'c) :count 4 :from-end t) #(b c b c))) (test-t (equalp (remove-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'b 'c 'a 'b 'c) :count -1) #(a b c a b c))) (test-t (equalp (remove-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'b 'c 'a 'b 'c) :count -10) #(a b c a b c))) (test-t (equalp (remove-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'b 'c 'a 'b 'c) :count -100) #(a b c a b c))) (test-t (equalp (remove-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1) #(a b c b c b c b c))) (test-t (equalp (remove-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :count 1) #(a b c b c a b c a b c))) (test-t (equalp (remove-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :count 2) #(a b c b c b c a b c))) (test-t (equalp (remove-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end nil :count 2) #(a b c b c b c a b c))) (test-t (equalp (remove-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8) #(a b c b c b c a b c))) (test-t (equalp (remove-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8 :count 1) #(a b c b c a b c a b c))) (test-t (equalp (remove-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8 :count 1 :from-end t) #(a b c a b c b c a b c))) (test-t (equalp (remove-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8 :count 0 :from-end t) #(a b c a b c a b c a b c))) (test-t (equalp (remove-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8 :count -100 :from-end t) #(a b c a b c a b c a b c))) (test-t (equalp (remove-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 1) #(a b c a b c a b c a b c))) (test-t (equalp (remove-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 2 :end 2) #(a b c a b c a b c a b c))) (test-t (equalp (remove-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 12 :end 12) #(a b c a b c a b c a b c))) (test-t (equalp (remove-if-not (lambda (arg) (not (eql arg 'a))) (vector '(a) '(b) '(c) '(a) '(b) '(c)) :key car) #((b) (c) (b) (c)))) (test-t (equalp (remove-if-not (lambda (arg) (not (eql arg 'a))) (vector '(a . b) '(b . c) '(c . a) '(a . b) '(b . c) '(c . a)) :key cdr) #((a . b) (b . c) (a . b) (b . c)))) (test-t (equalp (remove-if-not (lambda (arg) (not (eql arg "love"))) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car) #(("Love") ("LOve") ("LOVe") ("LOVE")))) (test-t (equalp (remove-if-not (lambda (arg) (not (eql arg "love"))) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count -10) #(("Love") ("LOve") ("LOVe") ("LOVE")))) (test-t (equalp (remove-if-not (lambda (arg) (not (string-equal arg "love"))) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car) #())) (test-t (equalp (remove-if-not (lambda (arg) (not (string-equal arg "love"))) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car) #())) (test-t (equalp (remove-if-not (lambda (arg) (not (string-equal arg "love"))) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 1) #(("LOve") ("LOVe") ("LOVE")))) (test-t (equalp (remove-if-not (lambda (arg) (not (string-equal arg "love"))) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 1) #(("LOve") ("LOVe") ("LOVE")))) (test-t (equalp (remove-if-not (lambda (arg) (not (string-equal arg "love"))) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 1 :from-end t) #(("Love") ("LOve") ("LOVe")))) (test-t (equalp (remove-if-not (lambda (arg) (not (string-equal arg "love"))) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 1 :from-end t) #(("Love") ("LOve") ("LOVe")))) (test-t (equalp (remove-if-not (lambda (arg) (not (string-equal arg "love"))) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 2 :from-end t) #(("Love") ("LOve")))) (test-t (equalp (remove-if-not (lambda (arg) (not (string-equal arg "love"))) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 2 :from-end t) #(("Love") ("LOve")))) (test-t (equalp (remove-if-not (lambda (arg) (not (string-equal arg "love"))) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :start 1 :end 3) #(("Love") ("LOVE")))) (test-t (equalp (remove-if-not (lambda (arg) (not (string-equal arg "love"))) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 1 :start 1 :end 3) #(("Love") ("LOVe") ("LOVE")))) (test-t (equalp (remove-if-not (lambda (arg) (not (string-equal arg "love"))) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 1 :from-end t :start 1 :end 3) #(("Love") ("LOve") ("LOVE")))) (test-t (equalp (remove-if-not (lambda (arg) (not (string-equal arg "love"))) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 10 :from-end t :start 1 :end 3) #(("Love") ("LOVE")))) (test-t (string= (remove-if-not (lambda (arg) (not (string-equal arg #\a))) (copy-seq "abcabc")) "bcbc")) (test-t (string= (remove-if-not (lambda (arg) (not (string-equal arg #\a))) (copy-seq "")) "")) (test-t (string= (remove-if-not (lambda (arg) (not (string-equal arg #\a))) (copy-seq "xyz")) "xyz")) (test-t (string= (remove-if-not (lambda (arg) (not (string-equal arg #\a))) (copy-seq "ABCABC") :key char-downcase) "BCBC")) (test-t (string= (remove-if-not (lambda (arg) (not (string-equal arg #\a))) (copy-seq "abcabc") :count 1) "bcabc")) (test-t (string= (remove-if-not (lambda (arg) (not (string-equal arg #\a))) (copy-seq "abcabc") :count 1 :from-end t) "abcbc")) (test-t (string= (remove-if-not (lambda (arg) (not (string-equal arg #\a))) (copy-seq "abcabc") :count 0) "abcabc")) (test-t (string= (remove-if-not (lambda (arg) (not (string-equal arg #\a))) (copy-seq "abcabc") :count -10) "abcabc")) (test-t (let* ((str0 (copy-seq "abc")) (str (remove-if-not (lambda (arg) (not (string-equal arg #\a))) str0))) (and (not (eq str0 str)) (string= str0 "abc") (string= str "bc")))) (test-t (string= (remove-if-not (lambda (arg) (not (string-equal arg #\a))) (copy-seq "abcabc") :count 0) "abcabc")) (test-t (string= (remove-if-not (lambda (arg) (not (string-equal arg #\a))) (copy-seq "abcabc")) "bcbc")) (test-t (string= (remove-if-not (lambda (arg) (not (string-equal arg #\b))) (copy-seq "abcabc")) "acac")) (test-t (string= (remove-if-not (lambda (arg) (not (string-equal arg #\c))) (copy-seq "abcabc")) "abab")) (test-t (string= (remove-if-not (lambda (arg) (not (string-equal arg #\a))) (copy-seq "abcabc") :count 0) "abcabc")) (test-t (string= (remove-if-not (lambda (arg) (not (string-equal arg #\a))) (copy-seq "abcabc") :count 1) "bcabc")) (test-t (string= (remove-if-not (lambda (arg) (not (string-equal arg #\a))) (copy-seq "abcabc") :count 1 :from-end t) "abcbc")) (test-t (string= (remove-if-not (lambda (arg) (not (string-equal arg #\a))) (copy-seq "abcabc") :count 2) "bcbc")) (test-t (string= (remove-if-not (lambda (arg) (not (string-equal arg #\a))) (copy-seq "abcabc") :count 2 :from-end t) "bcbc")) (test-t (string= (remove-if-not (lambda (arg) (not (string-equal arg #\a))) (copy-seq "abcabc") :count 3) "bcbc")) (test-t (string= (remove-if-not (lambda (arg) (not (string-equal arg #\a))) (copy-seq "abcabc") :count 3 :from-end t) "bcbc")) (test-t (string= (remove-if-not (lambda (arg) (not (string-equal arg #\a))) (copy-seq "abcabc") :count 4) "bcbc")) (test-t (string= (remove-if-not (lambda (arg) (not (string-equal arg #\a))) (copy-seq "abcabc") :count 4 :from-end t) "bcbc")) (test-t (string= (remove-if-not (lambda (arg) (not (string-equal arg #\a))) (copy-seq "abcabc") :count -1) "abcabc")) (test-t (string= (remove-if-not (lambda (arg) (not (string-equal arg #\a))) (copy-seq "abcabc") :count -10) "abcabc")) (test-t (string= (remove-if-not (lambda (arg) (not (string-equal arg #\a))) (copy-seq "abcabc") :count -100) "abcabc")) (test-t (string= (remove-if-not (lambda (arg) (not (string-equal arg #\a))) (copy-seq "abcabcabcabc") :start 1) "abcbcbcbc")) (test-t (string= (remove-if-not (lambda (arg) (not (string-equal arg #\a))) (copy-seq "abcabcabcabc") :start 1 :count 1) "abcbcabcabc")) (test-t (string= (remove-if-not (lambda (arg) (not (eql arg #\a))) (copy-seq "abcabcabcabc") :start 1 :count 2) "abcbcbcabc")) (test-t (string= (remove-if-not (lambda (arg) (not (eql arg #\a))) (copy-seq "abcabcabcabc") :start 1 :end nil :count 2) "abcbcbcabc")) (test-t (string= (remove-if-not (lambda (arg) (not (eql arg #\a))) (copy-seq "abcabcabcabc") :start 1 :end 8) "abcbcbcabc")) (test-t (string= (remove-if-not (lambda (arg) (not (eql arg #\a))) (copy-seq "abcabcabcabc") :start 1 :end 8 :count 1) "abcbcabcabc")) (test-t (string= (remove-if-not (lambda (arg) (not (eql arg #\a))) (copy-seq "abcabcabcabc") :start 1 :end 8 :count 1 :from-end t) "abcabcbcabc")) (test-t (string= (remove-if-not (lambda (arg) (not (eql arg #\a))) (copy-seq "abcabcabcabc") :start 1 :end 8 :count 0 :from-end t) "abcabcabcabc")) (test-t (string= (remove-if-not (lambda (arg) (not (eql arg #\a))) (copy-seq "abcabcabcabc") :start 1 :end 8 :count -100 :from-end t) "abcabcabcabc")) (test-t (string= (remove-if-not (lambda (arg) (not (eql arg #\a))) (copy-seq "abcabcabcabc") :start 1 :end 1) "abcabcabcabc")) (test-t (string= (remove-if-not (lambda (arg) (not (eql arg #\a))) (copy-seq "abcabcabcabc") :start 2 :end 2) "abcabcabcabc")) (test-t (string= (remove-if-not (lambda (arg) (not (eql arg #\a))) (copy-seq "abcabcabcabc") :start 12 :end 12) "abcabcabcabc")) (test-t (equal (delete 'a (list 'a 'b 'c 'a 'b 'c)) '(b c b c))) (test-t (equal (delete 'b (list 'a 'b 'c 'a 'b 'c)) '(a c a c))) (test-t (equal (delete 'c (list 'a 'b 'c 'a 'b 'c)) '(a b a b))) (test-t (equal (delete 'a (list 'a 'a 'a)) ())) (test-t (equal (delete 'z (list 'a 'b 'c)) '(a b c))) (test-t (equal (delete 'a ()) ())) (test-t (equal (delete 'a (list 'a 'b 'c 'a 'b 'c) :count 0) '(a b c a b c))) (test-t (equal (delete 'a (list 'a 'b 'c 'a 'b 'c) :count 1) '(b c a b c))) (test-t (equal (delete 'a (list 'a 'b 'c 'a 'b 'c) :count 1 :from-end t) '(a b c b c))) (test-t (equal (delete 'a (list 'a 'b 'c 'a 'b 'c) :count 2) '(b c b c))) (test-t (equal (delete 'a (list 'a 'b 'c 'a 'b 'c) :count 2 :from-end t) '(b c b c))) (test-t (equal (delete 'a (list 'a 'b 'c 'a 'b 'c) :count 3) '(b c b c))) (test-t (equal (delete 'a (list 'a 'b 'c 'a 'b 'c) :count 3 :from-end t) '(b c b c))) (test-t (equal (delete 'a (list 'a 'b 'c 'a 'b 'c) :count 4) '(b c b c))) (test-t (equal (delete 'a (list 'a 'b 'c 'a 'b 'c) :count 4 :from-end t) '(b c b c))) (test-t (equal (delete 'a (list 'a 'b 'c 'a 'b 'c) :count -1) '(a b c a b c))) (test-t (equal (delete 'a (list 'a 'b 'c 'a 'b 'c) :count -10) '(a b c a b c))) (test-t (equal (delete 'a (list 'a 'b 'c 'a 'b 'c) :count -100) '(a b c a b c))) (test-t (equal (delete 'a (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1) '(a b c b c b c b c))) (test-t (equal (delete 'a (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :count 1) '(a b c b c a b c a b c))) (test-t (equal (delete 'a (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :count 2) '(a b c b c b c a b c))) (test-t (equal (delete 'a (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end nil :count 2) '(a b c b c b c a b c))) (test-t (equal (delete 'a (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8) '(a b c b c b c a b c))) (test-t (equal (delete 'a (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8 :count 1) '(a b c b c a b c a b c))) (test-t (equal (delete 'a (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8 :count 1 :from-end t) '(a b c a b c b c a b c))) (test-t (equal (delete 'a (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8 :count 0 :from-end t) '(a b c a b c a b c a b c))) (test-t (equal (delete 'a (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8 :count -100 :from-end t) '(a b c a b c a b c a b c))) (test-t (equal (delete 'a (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 1) '(a b c a b c a b c a b c))) (test-t (equal (delete 'a (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 2 :end 2) '(a b c a b c a b c a b c))) (test-t (equal (delete 'a (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 12 :end 12) '(a b c a b c a b c a b c))) (test-t (equal (delete 'a (list '(a) '(b) '(c) '(a) '(b) '(c)) :key car) '((b) (c) (b) (c)))) (test-t (equal (delete 'a (list '(a . b) '(b . c) '(c . a) '(a . b) '(b . c) '(c . a)) :key cdr) '((a . b) (b . c) (a . b) (b . c)))) (test-t (equal (delete "love" (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car) '(("Love") ("LOve") ("LOVe") ("LOVE")))) (test-t (equal (delete "love" (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count -10) '(("Love") ("LOve") ("LOVe") ("LOVE")))) (test-t (equal (delete "love" (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :test string-equal) ())) (test-t (equal (delete "love" (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :test string-equal :count 1) '(("LOve") ("LOVe") ("LOVE")))) (test-t (equal (delete "love" (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :test string-equal :count 1 :from-end t) '(("Love") ("LOve") ("LOVe")))) (test-t (equal (delete "love" (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :test string-equal :count 2 :from-end t) '(("Love") ("LOve")))) (test-t (equal (delete "love" (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :test string-equal :start 1 :end 3) '(("Love") ("LOVE")))) (test-t (equal (delete "love" (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :test string-equal :count 1 :start 1 :end 3) '(("Love") ("LOVe") ("LOVE")))) (test-t (equal (delete "love" (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :test string-equal :count 1 :from-end t :start 1 :end 3) '(("Love") ("LOve") ("LOVE")))) (test-t (equal (delete "love" (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :test string-equal :count 10 :from-end t :start 1 :end 3) '(("Love") ("LOVE")))) (test-t (equalp (delete 'a (vector 'a 'b 'c 'a 'b 'c)) #(b c b c))) (test-t (equalp (delete 'b (vector 'a 'b 'c 'a 'b 'c)) #(a c a c))) (test-t (equalp (delete 'c (vector 'a 'b 'c 'a 'b 'c)) #(a b a b))) (test-t (equalp (delete 'a (vector 'a 'a 'a)) #())) (test-t (equalp (delete 'z (vector 'a 'b 'c)) #(a b c))) (test-t (equalp (delete 'a #()) #())) (test-t (equalp (delete 'a (vector 'a 'b 'c 'a 'b 'c) :count 0) #(a b c a b c))) (test-t (equalp (delete 'a (vector 'a 'b 'c 'a 'b 'c) :count 1) #(b c a b c))) (test-t (equalp (delete 'a (vector 'a 'b 'c 'a 'b 'c) :count 1 :from-end t) #(a b c b c))) (test-t (equalp (delete 'a (vector 'a 'b 'c 'a 'b 'c) :count 2) #(b c b c))) (test-t (equalp (delete 'a (vector 'a 'b 'c 'a 'b 'c) :count 2 :from-end t) #(b c b c))) (test-t (equalp (delete 'a (vector 'a 'b 'c 'a 'b 'c) :count 3) #(b c b c))) (test-t (equalp (delete 'a (vector 'a 'b 'c 'a 'b 'c) :count 3 :from-end t) #(b c b c))) (test-t (equalp (delete 'a (vector 'a 'b 'c 'a 'b 'c) :count 4) #(b c b c))) (test-t (equalp (delete 'a (vector 'a 'b 'c 'a 'b 'c) :count 4 :from-end t) #(b c b c))) (test-t (equalp (delete 'a (vector 'a 'b 'c 'a 'b 'c) :count -1) #(a b c a b c))) (test-t (equalp (delete 'a (vector 'a 'b 'c 'a 'b 'c) :count -10) #(a b c a b c))) (test-t (equalp (delete 'a (vector 'a 'b 'c 'a 'b 'c) :count -100) #(a b c a b c))) (test-t (equalp (delete 'a (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1) #(a b c b c b c b c))) (test-t (equalp (delete 'a (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :count 1) #(a b c b c a b c a b c))) (test-t (equalp (delete 'a (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :count 2) #(a b c b c b c a b c))) (test-t (equalp (delete 'a (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end nil :count 2) #(a b c b c b c a b c))) (test-t (equalp (delete 'a (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8) #(a b c b c b c a b c))) (test-t (equalp (delete 'a (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8 :count 1) #(a b c b c a b c a b c))) (test-t (equalp (delete 'a (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8 :count 1 :from-end t) #(a b c a b c b c a b c))) (test-t (equalp (delete 'a (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8 :count 0 :from-end t) #(a b c a b c a b c a b c))) (test-t (equalp (delete 'a (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8 :count -100 :from-end t) #(a b c a b c a b c a b c))) (test-t (equalp (delete 'a (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 1) #(a b c a b c a b c a b c))) (test-t (equalp (delete 'a (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 2 :end 2) #(a b c a b c a b c a b c))) (test-t (equalp (delete 'a (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 12 :end 12) #(a b c a b c a b c a b c))) (test-t (equalp (delete 'a (vector '(a) '(b) '(c) '(a) '(b) '(c)) :key car) #((b) (c) (b) (c)))) (test-t (equalp (delete 'a (vector '(a . b) '(b . c) '(c . a) '(a . b) '(b . c) '(c . a)) :key cdr) #((a . b) (b . c) (a . b) (b . c)))) (test-t (equalp (delete "love" (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car) #(("Love") ("LOve") ("LOVe") ("LOVE")))) (test-t (equalp (delete "love" (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count -10) #(("Love") ("LOve") ("LOVe") ("LOVE")))) (test-t (equalp (delete "love" (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :test string-equal) #())) (test-t (equalp (delete "love" (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :test string-equal :count 1) #(("LOve") ("LOVe") ("LOVE")))) (test-t (equalp (delete "love" (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :test string-equal :count 1 :from-end t) #(("Love") ("LOve") ("LOVe")))) (test-t (equalp (delete "love" (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :test string-equal :count 2 :from-end t) #(("Love") ("LOve")))) (test-t (equalp (delete "love" (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :test string-equal :start 1 :end 3) #(("Love") ("LOVE")))) (test-t (equalp (delete "love" (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :test string-equal :count 1 :start 1 :end 3) #(("Love") ("LOVe") ("LOVE")))) (test-t (equalp (delete "love" (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :test string-equal :count 1 :from-end t :start 1 :end 3) #(("Love") ("LOve") ("LOVE")))) (test-t (equalp (delete "love" (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :test string-equal :count 10 :from-end t :start 1 :end 3) #(("Love") ("LOVE")))) (test-t (string= (delete #\a (copy-seq "abcabc")) "bcbc")) (test-t (string= (delete #\a (copy-seq "")) "")) (test-t (string= (delete #\a (copy-seq "xyz")) "xyz")) (test-t (string= (delete #\a (copy-seq "ABCABC")) "ABCABC")) (test-t (string= (delete #\a (copy-seq "ABCABC") :key char-downcase) "BCBC")) (test-t (string= (delete #\a (copy-seq "abcabc") :count 1) "bcabc")) (test-t (string= (delete #\a (copy-seq "abcabc") :count 1 :from-end t) "abcbc")) (test-t (string= (delete #\a (copy-seq "abcabc") :count 0) "abcabc")) (test-t (string= (delete #\a (copy-seq "abcabc") :count -10) "abcabc")) (test-t (string= (delete #\a (copy-seq "abcabc") :count 0) "abcabc")) (test-t (string= (delete #\a (copy-seq "abcabc")) "bcbc")) (test-t (string= (delete #\b (copy-seq "abcabc")) "acac")) (test-t (string= (delete #\c (copy-seq "abcabc")) "abab")) (test-t (string= (delete #\a (copy-seq "abcabc") :count 0) "abcabc")) (test-t (string= (delete #\a (copy-seq "abcabc") :count 1) "bcabc")) (test-t (string= (delete #\a (copy-seq "abcabc") :count 1 :from-end t) "abcbc")) (test-t (string= (delete #\a (copy-seq "abcabc") :count 2) "bcbc")) (test-t (string= (delete #\a (copy-seq "abcabc") :count 2 :from-end t) "bcbc")) (test-t (string= (delete #\a (copy-seq "abcabc") :count 3) "bcbc")) (test-t (string= (delete #\a (copy-seq "abcabc") :count 3 :from-end t) "bcbc")) (test-t (string= (delete #\a (copy-seq "abcabc") :count 4) "bcbc")) (test-t (string= (delete #\a (copy-seq "abcabc") :count 4 :from-end t) "bcbc")) (test-t (string= (delete #\a (copy-seq "abcabc") :count -1) "abcabc")) (test-t (string= (delete #\a (copy-seq "abcabc") :count -10) "abcabc")) (test-t (string= (delete #\a (copy-seq "abcabc") :count -100) "abcabc")) (test-t (string= (delete #\a (copy-seq "abcabcabcabc") :start 1) "abcbcbcbc")) (test-t (string= (delete #\a (copy-seq "abcabcabcabc") :start 1 :count 1) "abcbcabcabc")) (test-t (string= (delete #\a (copy-seq "abcabcabcabc") :start 1 :count 2) "abcbcbcabc")) (test-t (string= (delete #\a (copy-seq "abcabcabcabc") :start 1 :end nil :count 2) "abcbcbcabc")) (test-t (string= (delete #\a (copy-seq "abcabcabcabc") :start 1 :end 8) "abcbcbcabc")) (test-t (string= (delete #\a (copy-seq "abcabcabcabc") :start 1 :end 8 :count 1) "abcbcabcabc")) (test-t (string= (delete #\a (copy-seq "abcabcabcabc") :start 1 :end 8 :count 1 :from-end t) "abcabcbcabc")) (test-t (string= (delete #\a (copy-seq "abcabcabcabc") :start 1 :end 8 :count 0 :from-end t) "abcabcabcabc")) (test-t (string= (delete #\a (copy-seq "abcabcabcabc") :start 1 :end 8 :count -100 :from-end t) "abcabcabcabc")) (test-t (string= (delete #\a (copy-seq "abcabcabcabc") :start 1 :end 1) "abcabcabcabc")) (test-t (string= (delete #\a (copy-seq "abcabcabcabc") :start 2 :end 2) "abcabcabcabc")) (test-t (string= (delete #\a (copy-seq "abcabcabcabc") :start 12 :end 12) "abcabcabcabc")) (test-t (equal (delete-if (lambda (arg) (eql arg 'a)) (list 'a 'b 'c 'a 'b 'c)) '(b c b c))) (test-t (equal (delete-if (lambda (arg) (eql arg 'b)) (list 'a 'b 'c 'a 'b 'c)) '(a c a c))) (test-t (equal (delete-if (lambda (arg) (eql arg 'c)) (list 'a 'b 'c 'a 'b 'c)) '(a b a b))) (test-t (equal (delete-if (lambda (arg) (eql arg 'a)) (list 'a 'a 'a)) ())) (test-t (equal (delete-if (lambda (arg) (eql arg 'z)) (list 'a 'b 'c)) '(a b c))) (test-t (equal (delete-if (lambda (arg) (eql arg 'a)) ()) ())) (test-t (equal (delete-if (lambda (arg) (eql arg 'a)) (list 'a 'b 'c 'a 'b 'c) :count 0) '(a b c a b c))) (test-t (equal (delete-if (lambda (arg) (eql arg 'a)) (list 'a 'b 'c 'a 'b 'c) :count 1) '(b c a b c))) (test-t (equal (delete-if (lambda (arg) (eql arg 'a)) (list 'a 'b 'c 'a 'b 'c) :count 1 :from-end t) '(a b c b c))) (test-t (equal (delete-if (lambda (arg) (eql arg 'a)) (list 'a 'b 'c 'a 'b 'c) :count 2) '(b c b c))) (test-t (equal (delete-if (lambda (arg) (eql arg 'a)) (list 'a 'b 'c 'a 'b 'c) :count 2 :from-end t) '(b c b c))) (test-t (equal (delete-if (lambda (arg) (eql arg 'a)) (list 'a 'b 'c 'a 'b 'c) :count 3) '(b c b c))) (test-t (equal (delete-if (lambda (arg) (eql arg 'a)) (list 'a 'b 'c 'a 'b 'c) :count 3 :from-end t) '(b c b c))) (test-t (equal (delete-if (lambda (arg) (eql arg 'a)) (list 'a 'b 'c 'a 'b 'c) :count 4) '(b c b c))) (test-t (equal (delete-if (lambda (arg) (eql arg 'a)) (list 'a 'b 'c 'a 'b 'c) :count 4 :from-end t) '(b c b c))) (test-t (equal (delete-if (lambda (arg) (eql arg 'a)) (list 'a 'b 'c 'a 'b 'c) :count -1) '(a b c a b c))) (test-t (equal (delete-if (lambda (arg) (eql arg 'a)) (list 'a 'b 'c 'a 'b 'c) :count -10) '(a b c a b c))) (test-t (equal (delete-if (lambda (arg) (eql arg 'a)) (list 'a 'b 'c 'a 'b 'c) :count -100) '(a b c a b c))) (test-t (equal (delete-if (lambda (arg) (eql arg 'a)) (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1) '(a b c b c b c b c))) (test-t (equal (delete-if (lambda (arg) (eql arg 'a)) (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :count 1) '(a b c b c a b c a b c))) (test-t (equal (delete-if (lambda (arg) (eql arg 'a)) (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :count 2) '(a b c b c b c a b c))) (test-t (equal (delete-if (lambda (arg) (eql arg 'a)) (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end nil :count 2) '(a b c b c b c a b c))) (test-t (equal (delete-if (lambda (arg) (eql arg 'a)) (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8) '(a b c b c b c a b c))) (test-t (equal (delete-if (lambda (arg) (eql arg 'a)) (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8 :count 1) '(a b c b c a b c a b c))) (test-t (equal (delete-if (lambda (arg) (eql arg 'a)) (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8 :count 1 :from-end t) '(a b c a b c b c a b c))) (test-t (equal (delete-if (lambda (arg) (eql arg 'a)) (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8 :count 0 :from-end t) '(a b c a b c a b c a b c))) (test-t (equal (delete-if (lambda (arg) (eql arg 'a)) (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8 :count -100 :from-end t) '(a b c a b c a b c a b c))) (test-t (equal (delete-if (lambda (arg) (eql arg 'a)) (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 1) '(a b c a b c a b c a b c))) (test-t (equal (delete-if (lambda (arg) (eql arg 'a)) (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 2 :end 2) '(a b c a b c a b c a b c))) (test-t (equal (delete-if (lambda (arg) (eql arg 'a)) (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 12 :end 12) '(a b c a b c a b c a b c))) (test-t (equal (delete-if (lambda (arg) (eql arg 'a)) (list '(a) '(b) '(c) '(a) '(b) '(c)) :key car) '((b) (c) (b) (c)))) (test-t (equal (delete-if (lambda (arg) (eql arg 'a)) (list '(a . b) '(b . c) '(c . a) '(a . b) '(b . c) '(c . a)) :key cdr) '((a . b) (b . c) (a . b) (b . c)))) (test-t (equal (delete-if (lambda (arg) (eql arg "love")) (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car) '(("Love") ("LOve") ("LOVe") ("LOVE")))) (test-t (equal (delete-if (lambda (arg) (eql arg "love")) (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count -10) '(("Love") ("LOve") ("LOVe") ("LOVE")))) (test-t (equal (delete-if (lambda (arg) (string-equal arg "love")) (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car) ())) (test-t (equal (delete-if (lambda (arg) (string-equal arg "love")) (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 1) '(("LOve") ("LOVe") ("LOVE")))) (test-t (equal (delete-if (lambda (arg) (string-equal arg "love")) (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 1 :from-end t) '(("Love") ("LOve") ("LOVe")))) (test-t (equal (delete-if (lambda (arg) (string-equal arg "love")) (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 2 :from-end t) '(("Love") ("LOve")))) (test-t (equal (delete-if (lambda (arg) (string-equal arg "love")) (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :start 1 :end 3) '(("Love") ("LOVE")))) (test-t (equal (delete-if (lambda (arg) (string-equal arg "love")) (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 1 :start 1 :end 3) '(("Love") ("LOVe") ("LOVE")))) (test-t (equal (delete-if (lambda (arg) (string-equal arg "love")) (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 1 :from-end t :start 1 :end 3) '(("Love") ("LOve") ("LOVE")))) (test-t (equal (delete-if (lambda (arg) (string-equal arg "love")) (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 10 :from-end t :start 1 :end 3) '(("Love") ("LOVE")))) (test-t (equalp (delete-if (lambda (arg) (eql arg 'a)) (vector 'a 'b 'c 'a 'b 'c)) #(b c b c))) (test-t (equalp (delete-if (lambda (arg) (eql arg 'b)) (vector 'a 'b 'c 'a 'b 'c)) #(a c a c))) (test-t (equalp (delete-if (lambda (arg) (eql arg 'c)) (vector 'a 'b 'c 'a 'b 'c)) #(a b a b))) (test-t (equalp (delete-if (lambda (arg) (eql arg 'a)) (vector 'a 'a 'a)) #())) (test-t (equalp (delete-if (lambda (arg) (eql arg 'z)) (vector 'a 'b 'c)) #(a b c))) (test-t (equalp (delete-if (lambda (arg) (eql arg 'a)) #()) #())) (test-t (equalp (delete-if (lambda (arg) (eql arg 'a)) (vector 'a 'b 'c 'a 'b 'c) :count 0) #(a b c a b c))) (test-t (equalp (delete-if (lambda (arg) (eql arg 'a)) (vector 'a 'b 'c 'a 'b 'c) :count 1) #(b c a b c))) (test-t (equalp (delete-if (lambda (arg) (eql arg 'a)) (vector 'a 'b 'c 'a 'b 'c) :count 1 :from-end t) #(a b c b c))) (test-t (equalp (delete-if (lambda (arg) (eql arg 'a)) (vector 'a 'b 'c 'a 'b 'c) :count 2) #(b c b c))) (test-t (equalp (delete-if (lambda (arg) (eql arg 'a)) (vector 'a 'b 'c 'a 'b 'c) :count 2 :from-end t) #(b c b c))) (test-t (equalp (delete-if (lambda (arg) (eql arg 'a)) (vector 'a 'b 'c 'a 'b 'c) :count 3) #(b c b c))) (test-t (equalp (delete-if (lambda (arg) (eql arg 'a)) (vector 'a 'b 'c 'a 'b 'c) :count 3 :from-end t) #(b c b c))) (test-t (equalp (delete-if (lambda (arg) (eql arg 'a)) (vector 'a 'b 'c 'a 'b 'c) :count 4) #(b c b c))) (test-t (equalp (delete-if (lambda (arg) (eql arg 'a)) (vector 'a 'b 'c 'a 'b 'c) :count 4 :from-end t) #(b c b c))) (test-t (equalp (delete-if (lambda (arg) (eql arg 'a)) (vector 'a 'b 'c 'a 'b 'c) :count -1) #(a b c a b c))) (test-t (equalp (delete-if (lambda (arg) (eql arg 'a)) (vector 'a 'b 'c 'a 'b 'c) :count -10) #(a b c a b c))) (test-t (equalp (delete-if (lambda (arg) (eql arg 'a)) (vector 'a 'b 'c 'a 'b 'c) :count -100) #(a b c a b c))) (test-t (equalp (delete-if (lambda (arg) (eql arg 'a)) (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1) #(a b c b c b c b c))) (test-t (equalp (delete-if (lambda (arg) (eql arg 'a)) (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :count 1) #(a b c b c a b c a b c))) (test-t (equalp (delete-if (lambda (arg) (eql arg 'a)) (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :count 2) #(a b c b c b c a b c))) (test-t (equalp (delete-if (lambda (arg) (eql arg 'a)) (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end nil :count 2) #(a b c b c b c a b c))) (test-t (equalp (delete-if (lambda (arg) (eql arg 'a)) (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8) #(a b c b c b c a b c))) (test-t (equalp (delete-if (lambda (arg) (eql arg 'a)) (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8 :count 1) #(a b c b c a b c a b c))) (test-t (equalp (delete-if (lambda (arg) (eql arg 'a)) (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8 :count 1 :from-end t) #(a b c a b c b c a b c))) (test-t (equalp (delete-if (lambda (arg) (eql arg 'a)) (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8 :count 0 :from-end t) #(a b c a b c a b c a b c))) (test-t (equalp (delete-if (lambda (arg) (eql arg 'a)) (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8 :count -100 :from-end t) #(a b c a b c a b c a b c))) (test-t (equalp (delete-if (lambda (arg) (eql arg 'a)) (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 1) #(a b c a b c a b c a b c))) (test-t (equalp (delete-if (lambda (arg) (eql arg 'a)) (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 2 :end 2) #(a b c a b c a b c a b c))) (test-t (equalp (delete-if (lambda (arg) (eql arg 'a)) (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 12 :end 12) #(a b c a b c a b c a b c))) (test-t (equalp (delete-if (lambda (arg) (eql arg 'a)) (vector '(a) '(b) '(c) '(a) '(b) '(c)) :key car) #((b) (c) (b) (c)))) (test-t (equalp (delete-if (lambda (arg) (eql arg 'a)) (vector '(a . b) '(b . c) '(c . a) '(a . b) '(b . c) '(c . a)) :key cdr) #((a . b) (b . c) (a . b) (b . c)))) (test-t (equalp (delete-if (lambda (arg) (eql arg "love")) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car) #(("Love") ("LOve") ("LOVe") ("LOVE")))) (test-t (equalp (delete-if (lambda (arg) (eql arg "love")) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count -10) #(("Love") ("LOve") ("LOVe") ("LOVE")))) (test-t (equalp (delete-if (lambda (arg) (string-equal arg "love")) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car) #())) (test-t (equalp (delete-if (lambda (arg) (string-equal arg "love")) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car) #())) (test-t (equalp (delete-if (lambda (arg) (string-equal arg "love")) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 1) #(("LOve") ("LOVe") ("LOVE")))) (test-t (equalp (delete-if (lambda (arg) (string-equal arg "love")) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 1) #(("LOve") ("LOVe") ("LOVE")))) (test-t (equalp (delete-if (lambda (arg) (string-equal arg "love")) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 1 :from-end t) #(("Love") ("LOve") ("LOVe")))) (test-t (equalp (delete-if (lambda (arg) (string-equal arg "love")) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 1 :from-end t) #(("Love") ("LOve") ("LOVe")))) (test-t (equalp (delete-if (lambda (arg) (string-equal arg "love")) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 2 :from-end t) #(("Love") ("LOve")))) (test-t (equalp (delete-if (lambda (arg) (string-equal arg "love")) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 2 :from-end t) #(("Love") ("LOve")))) (test-t (equalp (delete-if (lambda (arg) (string-equal arg "love")) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :start 1 :end 3) #(("Love") ("LOVE")))) (test-t (equalp (delete-if (lambda (arg) (string-equal arg "love")) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 1 :start 1 :end 3) #(("Love") ("LOVe") ("LOVE")))) (test-t (equalp (delete-if (lambda (arg) (string-equal arg "love")) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 1 :from-end t :start 1 :end 3) #(("Love") ("LOve") ("LOVE")))) (test-t (equalp (delete-if (lambda (arg) (string-equal arg "love")) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 10 :from-end t :start 1 :end 3) #(("Love") ("LOVE")))) (test-t (string= (delete-if (lambda (arg) (string-equal arg #\a)) (copy-seq "abcabc")) "bcbc")) (test-t (string= (delete-if (lambda (arg) (string-equal arg #\a)) (copy-seq "")) "")) (test-t (string= (delete-if (lambda (arg) (string-equal arg #\a)) (copy-seq "xyz")) "xyz")) (test-t (string= (delete-if (lambda (arg) (string-equal arg #\a)) (copy-seq "ABCABC") :key char-downcase) "BCBC")) (test-t (string= (delete-if (lambda (arg) (string-equal arg #\a)) (copy-seq "abcabc") :count 1) "bcabc")) (test-t (string= (delete-if (lambda (arg) (string-equal arg #\a)) (copy-seq "abcabc") :count 1 :from-end t) "abcbc")) (test-t (string= (delete-if (lambda (arg) (string-equal arg #\a)) (copy-seq "abcabc") :count 0) "abcabc")) (test-t (string= (delete-if (lambda (arg) (string-equal arg #\a)) (copy-seq "abcabc") :count -10) "abcabc")) (test-t (string= (delete-if (lambda (arg) (string-equal arg #\a)) (copy-seq "abcabc") :count 0) "abcabc")) (test-t (string= (delete-if (lambda (arg) (string-equal arg #\a)) (copy-seq "abcabc")) "bcbc")) (test-t (string= (delete-if (lambda (arg) (string-equal arg #\b)) (copy-seq "abcabc")) "acac")) (test-t (string= (delete-if (lambda (arg) (string-equal arg #\c)) (copy-seq "abcabc")) "abab")) (test-t (string= (delete-if (lambda (arg) (string-equal arg #\a)) (copy-seq "abcabc") :count 0) "abcabc")) (test-t (string= (delete-if (lambda (arg) (string-equal arg #\a)) (copy-seq "abcabc") :count 1) "bcabc")) (test-t (string= (delete-if (lambda (arg) (string-equal arg #\a)) (copy-seq "abcabc") :count 1 :from-end t) "abcbc")) (test-t (string= (delete-if (lambda (arg) (string-equal arg #\a)) (copy-seq "abcabc") :count 2) "bcbc")) (test-t (string= (delete-if (lambda (arg) (string-equal arg #\a)) (copy-seq "abcabc") :count 2 :from-end t) "bcbc")) (test-t (string= (delete-if (lambda (arg) (string-equal arg #\a)) (copy-seq "abcabc") :count 3) "bcbc")) (test-t (string= (delete-if (lambda (arg) (string-equal arg #\a)) (copy-seq "abcabc") :count 3 :from-end t) "bcbc")) (test-t (string= (delete-if (lambda (arg) (string-equal arg #\a)) (copy-seq "abcabc") :count 4) "bcbc")) (test-t (string= (delete-if (lambda (arg) (string-equal arg #\a)) (copy-seq "abcabc") :count 4 :from-end t) "bcbc")) (test-t (string= (delete-if (lambda (arg) (string-equal arg #\a)) (copy-seq "abcabc") :count -1) "abcabc")) (test-t (string= (delete-if (lambda (arg) (string-equal arg #\a)) (copy-seq "abcabc") :count -10) "abcabc")) (test-t (string= (delete-if (lambda (arg) (string-equal arg #\a)) (copy-seq "abcabc") :count -100) "abcabc")) (test-t (string= (delete-if (lambda (arg) (string-equal arg #\a)) (copy-seq "abcabcabcabc") :start 1) "abcbcbcbc")) (test-t (string= (delete-if (lambda (arg) (string-equal arg #\a)) (copy-seq "abcabcabcabc") :start 1 :count 1) "abcbcabcabc")) (test-t (string= (delete-if (lambda (arg) (eql arg #\a)) (copy-seq "abcabcabcabc") :start 1 :count 2) "abcbcbcabc")) (test-t (string= (delete-if (lambda (arg) (eql arg #\a)) (copy-seq "abcabcabcabc") :start 1 :end nil :count 2) "abcbcbcabc")) (test-t (string= (delete-if (lambda (arg) (eql arg #\a)) (copy-seq "abcabcabcabc") :start 1 :end 8) "abcbcbcabc")) (test-t (string= (delete-if (lambda (arg) (eql arg #\a)) (copy-seq "abcabcabcabc") :start 1 :end 8 :count 1) "abcbcabcabc")) (test-t (string= (delete-if (lambda (arg) (eql arg #\a)) (copy-seq "abcabcabcabc") :start 1 :end 8 :count 1 :from-end t) "abcabcbcabc")) (test-t (string= (delete-if (lambda (arg) (eql arg #\a)) (copy-seq "abcabcabcabc") :start 1 :end 8 :count 0 :from-end t) "abcabcabcabc")) (test-t (string= (delete-if (lambda (arg) (eql arg #\a)) (copy-seq "abcabcabcabc") :start 1 :end 8 :count -100 :from-end t) "abcabcabcabc")) (test-t (string= (delete-if (lambda (arg) (eql arg #\a)) (copy-seq "abcabcabcabc") :start 1 :end 1) "abcabcabcabc")) (test-t (string= (delete-if (lambda (arg) (eql arg #\a)) (copy-seq "abcabcabcabc") :start 2 :end 2) "abcabcabcabc")) (test-t (string= (delete-if (lambda (arg) (eql arg #\a)) (copy-seq "abcabcabcabc") :start 12 :end 12) "abcabcabcabc")) (test-t (equal (delete-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'b 'c 'a 'b 'c)) '(b c b c))) (test-t (equal (delete-if-not (lambda (arg) (not (eql arg 'b))) (list 'a 'b 'c 'a 'b 'c)) '(a c a c))) (test-t (equal (delete-if-not (lambda (arg) (not (eql arg 'c))) (list 'a 'b 'c 'a 'b 'c)) '(a b a b))) (test-t (equal (delete-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'a 'a)) ())) (test-t (equal (delete-if-not (lambda (arg) (not (eql arg 'z))) (list 'a 'b 'c)) '(a b c))) (test-t (equal (delete-if-not (lambda (arg) (not (eql arg 'a))) ()) ())) (test-t (equal (delete-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'b 'c 'a 'b 'c) :count 0) '(a b c a b c))) (test-t (equal (delete-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'b 'c 'a 'b 'c) :count 1) '(b c a b c))) (test-t (equal (delete-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'b 'c 'a 'b 'c) :count 1 :from-end t) '(a b c b c))) (test-t (equal (delete-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'b 'c 'a 'b 'c) :count 2) '(b c b c))) (test-t (equal (delete-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'b 'c 'a 'b 'c) :count 2 :from-end t) '(b c b c))) (test-t (equal (delete-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'b 'c 'a 'b 'c) :count 3) '(b c b c))) (test-t (equal (delete-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'b 'c 'a 'b 'c) :count 3 :from-end t) '(b c b c))) (test-t (equal (delete-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'b 'c 'a 'b 'c) :count 4) '(b c b c))) (test-t (equal (delete-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'b 'c 'a 'b 'c) :count 4 :from-end t) '(b c b c))) (test-t (equal (delete-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'b 'c 'a 'b 'c) :count -1) '(a b c a b c))) (test-t (equal (delete-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'b 'c 'a 'b 'c) :count -10) '(a b c a b c))) (test-t (equal (delete-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'b 'c 'a 'b 'c) :count -100) '(a b c a b c))) (test-t (equal (delete-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1) '(a b c b c b c b c))) (test-t (equal (delete-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :count 1) '(a b c b c a b c a b c))) (test-t (equal (delete-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :count 2) '(a b c b c b c a b c))) (test-t (equal (delete-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end nil :count 2) '(a b c b c b c a b c))) (test-t (equal (delete-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8) '(a b c b c b c a b c))) (test-t (equal (delete-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8 :count 1) '(a b c b c a b c a b c))) (test-t (equal (delete-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8 :count 1 :from-end t) '(a b c a b c b c a b c))) (test-t (equal (delete-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8 :count 0 :from-end t) '(a b c a b c a b c a b c))) (test-t (equal (delete-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8 :count -100 :from-end t) '(a b c a b c a b c a b c))) (test-t (equal (delete-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 1) '(a b c a b c a b c a b c))) (test-t (equal (delete-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 2 :end 2) '(a b c a b c a b c a b c))) (test-t (equal (delete-if-not (lambda (arg) (not (eql arg 'a))) (list 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 12 :end 12) '(a b c a b c a b c a b c))) (test-t (equal (delete-if-not (lambda (arg) (not (eql arg 'a))) (list '(a) '(b) '(c) '(a) '(b) '(c)) :key car) '((b) (c) (b) (c)))) (test-t (equal (delete-if-not (lambda (arg) (not (eql arg 'a))) (list '(a . b) '(b . c) '(c . a) '(a . b) '(b . c) '(c . a)) :key cdr) '((a . b) (b . c) (a . b) (b . c)))) (test-t (equal (delete-if-not (lambda (arg) (not (eql arg "love"))) (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car) '(("Love") ("LOve") ("LOVe") ("LOVE")))) (test-t (equal (delete-if-not (lambda (arg) (not (eql arg "love"))) (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count -10) '(("Love") ("LOve") ("LOVe") ("LOVE")))) (test-t (equal (delete-if-not (lambda (arg) (not (string-equal arg "love"))) (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car) ())) (test-t (equal (delete-if-not (lambda (arg) (not (string-equal arg "love"))) (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 1) '(("LOve") ("LOVe") ("LOVE")))) (test-t (equal (delete-if-not (lambda (arg) (not (string-equal arg "love"))) (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 1 :from-end t) '(("Love") ("LOve") ("LOVe")))) (test-t (equal (delete-if-not (lambda (arg) (not (string-equal arg "love"))) (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 2 :from-end t) '(("Love") ("LOve")))) (test-t (equal (delete-if-not (lambda (arg) (not (string-equal arg "love"))) (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :start 1 :end 3) '(("Love") ("LOVE")))) (test-t (equal (delete-if-not (lambda (arg) (not (string-equal arg "love"))) (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 1 :start 1 :end 3) '(("Love") ("LOVe") ("LOVE")))) (test-t (equal (delete-if-not (lambda (arg) (not (string-equal arg "love"))) (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 1 :from-end t :start 1 :end 3) '(("Love") ("LOve") ("LOVE")))) (test-t (equal (delete-if-not (lambda (arg) (not (string-equal arg "love"))) (list '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 10 :from-end t :start 1 :end 3) '(("Love") ("LOVE")))) (test-t (equalp (delete-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'b 'c 'a 'b 'c)) #(b c b c))) (test-t (equalp (delete-if-not (lambda (arg) (not (eql arg 'b))) (vector 'a 'b 'c 'a 'b 'c)) #(a c a c))) (test-t (equalp (delete-if-not (lambda (arg) (not (eql arg 'c))) (vector 'a 'b 'c 'a 'b 'c)) #(a b a b))) (test-t (equalp (delete-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'a 'a)) #())) (test-t (equalp (delete-if-not (lambda (arg) (not (eql arg 'z))) (vector 'a 'b 'c)) #(a b c))) (test-t (equalp (delete-if-not (lambda (arg) (not (eql arg 'a))) #()) #())) (test-t (equalp (delete-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'b 'c 'a 'b 'c) :count 0) #(a b c a b c))) (test-t (equalp (delete-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'b 'c 'a 'b 'c) :count 1) #(b c a b c))) (test-t (equalp (delete-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'b 'c 'a 'b 'c) :count 1 :from-end t) #(a b c b c))) (test-t (equalp (delete-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'b 'c 'a 'b 'c) :count 2) #(b c b c))) (test-t (equalp (delete-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'b 'c 'a 'b 'c) :count 2 :from-end t) #(b c b c))) (test-t (equalp (delete-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'b 'c 'a 'b 'c) :count 3) #(b c b c))) (test-t (equalp (delete-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'b 'c 'a 'b 'c) :count 3 :from-end t) #(b c b c))) (test-t (equalp (delete-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'b 'c 'a 'b 'c) :count 4) #(b c b c))) (test-t (equalp (delete-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'b 'c 'a 'b 'c) :count 4 :from-end t) #(b c b c))) (test-t (equalp (delete-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'b 'c 'a 'b 'c) :count -1) #(a b c a b c))) (test-t (equalp (delete-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'b 'c 'a 'b 'c) :count -10) #(a b c a b c))) (test-t (equalp (delete-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'b 'c 'a 'b 'c) :count -100) #(a b c a b c))) (test-t (equalp (delete-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1) #(a b c b c b c b c))) (test-t (equalp (delete-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :count 1) #(a b c b c a b c a b c))) (test-t (equalp (delete-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :count 2) #(a b c b c b c a b c))) (test-t (equalp (delete-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end nil :count 2) #(a b c b c b c a b c))) (test-t (equalp (delete-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8) #(a b c b c b c a b c))) (test-t (equalp (delete-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8 :count 1) #(a b c b c a b c a b c))) (test-t (equalp (delete-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8 :count 1 :from-end t) #(a b c a b c b c a b c))) (test-t (equalp (delete-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8 :count 0 :from-end t) #(a b c a b c a b c a b c))) (test-t (equalp (delete-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 8 :count -100 :from-end t) #(a b c a b c a b c a b c))) (test-t (equalp (delete-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 1 :end 1) #(a b c a b c a b c a b c))) (test-t (equalp (delete-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 2 :end 2) #(a b c a b c a b c a b c))) (test-t (equalp (delete-if-not (lambda (arg) (not (eql arg 'a))) (vector 'a 'b 'c 'a 'b 'c 'a 'b 'c 'a 'b 'c) :start 12 :end 12) #(a b c a b c a b c a b c))) (test-t (equalp (delete-if-not (lambda (arg) (not (eql arg 'a))) (vector '(a) '(b) '(c) '(a) '(b) '(c)) :key car) #((b) (c) (b) (c)))) (test-t (equalp (delete-if-not (lambda (arg) (not (eql arg 'a))) (vector '(a . b) '(b . c) '(c . a) '(a . b) '(b . c) '(c . a)) :key cdr) #((a . b) (b . c) (a . b) (b . c)))) (test-t (equalp (delete-if-not (lambda (arg) (not (eql arg "love"))) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car) #(("Love") ("LOve") ("LOVe") ("LOVE")))) (test-t (equalp (delete-if-not (lambda (arg) (not (eql arg "love"))) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count -10) #(("Love") ("LOve") ("LOVe") ("LOVE")))) (test-t (equalp (delete-if-not (lambda (arg) (not (string-equal arg "love"))) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car) #())) (test-t (equalp (delete-if-not (lambda (arg) (not (string-equal arg "love"))) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car) #())) (test-t (equalp (delete-if-not (lambda (arg) (not (string-equal arg "love"))) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 1) #(("LOve") ("LOVe") ("LOVE")))) (test-t (equalp (delete-if-not (lambda (arg) (not (string-equal arg "love"))) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 1) #(("LOve") ("LOVe") ("LOVE")))) (test-t (equalp (delete-if-not (lambda (arg) (not (string-equal arg "love"))) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 1 :from-end t) #(("Love") ("LOve") ("LOVe")))) (test-t (equalp (delete-if-not (lambda (arg) (not (string-equal arg "love"))) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 1 :from-end t) #(("Love") ("LOve") ("LOVe")))) (test-t (equalp (delete-if-not (lambda (arg) (not (string-equal arg "love"))) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 2 :from-end t) #(("Love") ("LOve")))) (test-t (equalp (delete-if-not (lambda (arg) (not (string-equal arg "love"))) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 2 :from-end t) #(("Love") ("LOve")))) (test-t (equalp (delete-if-not (lambda (arg) (not (string-equal arg "love"))) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :start 1 :end 3) #(("Love") ("LOVE")))) (test-t (equalp (delete-if-not (lambda (arg) (not (string-equal arg "love"))) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 1 :start 1 :end 3) #(("Love") ("LOVe") ("LOVE")))) (test-t (equalp (delete-if-not (lambda (arg) (not (string-equal arg "love"))) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 1 :from-end t :start 1 :end 3) #(("Love") ("LOve") ("LOVE")))) (test-t (equalp (delete-if-not (lambda (arg) (not (string-equal arg "love"))) (vector '("Love") '("LOve") '("LOVe") '("LOVE")) :key car :count 10 :from-end t :start 1 :end 3) #(("Love") ("LOVE")))) (test-t (string= (delete-if-not (lambda (arg) (not (string-equal arg #\a))) (copy-seq "abcabc")) "bcbc")) (test-t (string= (delete-if-not (lambda (arg) (not (string-equal arg #\a))) (copy-seq "")) "")) (test-t (string= (delete-if-not (lambda (arg) (not (string-equal arg #\a))) (copy-seq "xyz")) "xyz")) (test-t (string= (delete-if-not (lambda (arg) (not (string-equal arg #\a))) (copy-seq "ABCABC") :key char-downcase) "BCBC")) (test-t (string= (delete-if-not (lambda (arg) (not (string-equal arg #\a))) (copy-seq "abcabc") :count 1) "bcabc")) (test-t (string= (delete-if-not (lambda (arg) (not (string-equal arg #\a))) (copy-seq "abcabc") :count 1 :from-end t) "abcbc")) (test-t (string= (delete-if-not (lambda (arg) (not (string-equal arg #\a))) (copy-seq "abcabc") :count 0) "abcabc")) (test-t (string= (delete-if-not (lambda (arg) (not (string-equal arg #\a))) (copy-seq "abcabc") :count -10) "abcabc")) (test-t (string= (delete-if-not (lambda (arg) (not (string-equal arg #\a))) (copy-seq "abcabc") :count 0) "abcabc")) (test-t (string= (delete-if-not (lambda (arg) (not (string-equal arg #\a))) (copy-seq "abcabc")) "bcbc")) (test-t (string= (delete-if-not (lambda (arg) (not (string-equal arg #\b))) (copy-seq "abcabc")) "acac")) (test-t (string= (delete-if-not (lambda (arg) (not (string-equal arg #\c))) (copy-seq "abcabc")) "abab")) (test-t (string= (delete-if-not (lambda (arg) (not (string-equal arg #\a))) (copy-seq "abcabc") :count 0) "abcabc")) (test-t (string= (delete-if-not (lambda (arg) (not (string-equal arg #\a))) (copy-seq "abcabc") :count 1) "bcabc")) (test-t (string= (delete-if-not (lambda (arg) (not (string-equal arg #\a))) (copy-seq "abcabc") :count 1 :from-end t) "abcbc")) (test-t (string= (delete-if-not (lambda (arg) (not (string-equal arg #\a))) (copy-seq "abcabc") :count 2) "bcbc")) (test-t (string= (delete-if-not (lambda (arg) (not (string-equal arg #\a))) (copy-seq "abcabc") :count 2 :from-end t) "bcbc")) (test-t (string= (delete-if-not (lambda (arg) (not (string-equal arg #\a))) (copy-seq "abcabc") :count 3) "bcbc")) (test-t (string= (delete-if-not (lambda (arg) (not (string-equal arg #\a))) (copy-seq "abcabc") :count 3 :from-end t) "bcbc")) (test-t (string= (delete-if-not (lambda (arg) (not (string-equal arg #\a))) (copy-seq "abcabc") :count 4) "bcbc")) (test-t (string= (delete-if-not (lambda (arg) (not (string-equal arg #\a))) (copy-seq "abcabc") :count 4 :from-end t) "bcbc")) (test-t (string= (delete-if-not (lambda (arg) (not (string-equal arg #\a))) (copy-seq "abcabc") :count -1) "abcabc")) (test-t (string= (delete-if-not (lambda (arg) (not (string-equal arg #\a))) (copy-seq "abcabc") :count -10) "abcabc")) (test-t (string= (delete-if-not (lambda (arg) (not (string-equal arg #\a))) (copy-seq "abcabc") :count -100) "abcabc")) (test-t (string= (delete-if-not (lambda (arg) (not (string-equal arg #\a))) (copy-seq "abcabcabcabc") :start 1) "abcbcbcbc")) (test-t (string= (delete-if-not (lambda (arg) (not (string-equal arg #\a))) (copy-seq "abcabcabcabc") :start 1 :count 1) "abcbcabcabc")) (test-t (string= (delete-if-not (lambda (arg) (not (eql arg #\a))) (copy-seq "abcabcabcabc") :start 1 :count 2) "abcbcbcabc")) (test-t (string= (delete-if-not (lambda (arg) (not (eql arg #\a))) (copy-seq "abcabcabcabc") :start 1 :end nil :count 2) "abcbcbcabc")) (test-t (string= (delete-if-not (lambda (arg) (not (eql arg #\a))) (copy-seq "abcabcabcabc") :start 1 :end 8) "abcbcbcabc")) (test-t (string= (delete-if-not (lambda (arg) (not (eql arg #\a))) (copy-seq "abcabcabcabc") :start 1 :end 8 :count 1) "abcbcabcabc")) (test-t (string= (delete-if-not (lambda (arg) (not (eql arg #\a))) (copy-seq "abcabcabcabc") :start 1 :end 8 :count 1 :from-end t) "abcabcbcabc")) (test-t (string= (delete-if-not (lambda (arg) (not (eql arg #\a))) (copy-seq "abcabcabcabc") :start 1 :end 8 :count 0 :from-end t) "abcabcabcabc")) (test-t (string= (delete-if-not (lambda (arg) (not (eql arg #\a))) (copy-seq "abcabcabcabc") :start 1 :end 8 :count -100 :from-end t) "abcabcabcabc")) (test-t (string= (delete-if-not (lambda (arg) (not (eql arg #\a))) (copy-seq "abcabcabcabc") :start 1 :end 1) "abcabcabcabc")) (test-t (string= (delete-if-not (lambda (arg) (not (eql arg #\a))) (copy-seq "abcabcabcabc") :start 2 :end 2) "abcabcabcabc")) (test-t (string= (delete-if-not (lambda (arg) (not (eql arg #\a))) (copy-seq "abcabcabcabc") :start 12 :end 12) "abcabcabcabc")) (test-t (equal (remove-duplicates "aBcDAbCd" :test char-equal :from-end t) "aBcD")) (test-t (equal (remove-duplicates '(a b c b d d e)) '(a c b d e))) (test-t (equal (remove-duplicates '(a b c b d d e) :from-end t) '(a b c d e))) (test-t (let* ((list0 (list 0 1 2 3 4 5 6)) (list (delete-duplicates list0 :key oddp :start 1 :end 6))) (equal list '(0 4 5 6)))) (test-t (let* ((list0 (list 2 1 0 1 0 1 2)) (list (remove-duplicates list0))) (and (not (eq list0 list)) (equal list0 '(2 1 0 1 0 1 2)) (equal list '(0 1 2))))) (test-t (let* ((vector0 (vector 2 1 0 1 0 1 2)) (vector (remove-duplicates vector0))) (and (not (eq vector0 vector)) (equalp vector0 #(2 1 0 1 0 1 2)) (equalp vector #(0 1 2))))) (test-t (equal (remove-duplicates (list 0 1 2 2 3 3 3)) '(0 1 2 3))) (test-t (equal (remove-duplicates (list 0 0 0 2 0 1 1 2 2 2 1 1 1 1 2)) '(0 1 2))) (test-t (equal (remove-duplicates (list 'a 'a 'b 'c 'c)) '(a b c))) (test-t (equal (remove-duplicates (list 0 1 2)) '(0 1 2))) (test-t (equal (remove-duplicates (list 2 0 2 1 1 1 0 0 0 1 2)) '(0 1 2))) (test-t (equal (remove-duplicates (list)) ())) (test-t (equal (remove-duplicates (list '(x . 0) '(y . 1) '(z . 2) '(a . 0) '(b . 1) '(c . 2)) :key cdr) '((a . 0) (b . 1) (c . 2)))) (test-t (equal (remove-duplicates (list '(x . 0) '(y . 1) '(z . 2) '(a . 0) '(b . 1) '(c . 2)) :key cdr :test (lambda (a b) (and (oddp a) (oddp b)))) '((x . 0) (z . 2) (a . 0) (b . 1) (c . 2)))) (test-t (equal (remove-duplicates (list '(x . 0) '(y . 1) '(z . 2) '(a . 0) '(b . 1) '(c . 2)) :key cdr :test (lambda (a b) (and (evenp a) (evenp b)))) '((y . 1) (b . 1) (c . 2)))) (test-t (equal (remove-duplicates (list 0 1 2 0 1 2 0 1 2 0 1 2) :start 3 :end 9) '(0 1 2 0 1 2 0 1 2))) (test-t (equal (remove-duplicates (list '(0 . 0) '(1 . 1) '(2 . 2) '(0 . 3) '(1 . 4) '(2 . 5) '(0 . 6) '(1 . 7) '(2 . 8) '(0 . 9) '(1 . 10) '(2 . 11))) (list '(0 . 0) '(1 . 1) '(2 . 2) '(0 . 3) '(1 . 4) '(2 . 5) '(0 . 6) '(1 . 7) '(2 . 8) '(0 . 9) '(1 . 10) '(2 . 11)))) (test-t (equal (remove-duplicates (list '(0 . 0) '(1 . 1) '(2 . 2) '(0 . 3) '(1 . 4) '(2 . 5) '(0 . 6) '(1 . 7) '(2 . 8) '(0 . 9) '(1 . 10) '(2 . 11)) :key car) '((0 . 9) (1 . 10) (2 . 11)))) (test-t (equal (remove-duplicates (list '(0 . 0) '(1 . 1) '(2 . 2) '(0 . 3) '(1 . 4) '(2 . 5) '(0 . 6) '(1 . 7) '(2 . 8) '(0 . 9) '(1 . 10) '(2 . 11)) :key car :from-end t) (list '(0 . 0) '(1 . 1) '(2 . 2)))) (test-t (equal (remove-duplicates (list '(0 . 0) '(1 . 1) '(2 . 2) '(0 . 3) '(1 . 4) '(2 . 5) '(0 . 6) '(1 . 7) '(2 . 8) '(0 . 9) '(1 . 10) '(2 . 11)) :start 3 :key car) (list '(0 . 0) '(1 . 1) '(2 . 2) '(0 . 9) '(1 . 10) '(2 . 11)))) (test-t (equal (remove-duplicates (list '(0 . 0) '(1 . 1) '(2 . 2) '(0 . 3) '(1 . 4) '(2 . 5) '(0 . 6) '(1 . 7) '(2 . 8) '(0 . 9) '(1 . 10) '(2 . 11)) :start 3 :key car :from-end t) (list '(0 . 0) '(1 . 1) '(2 . 2) '(0 . 3) '(1 . 4) '(2 . 5)))) (test-t (equal (remove-duplicates (list '(0 . 0) '(1 . 1) '(2 . 2) '(0 . 3) '(1 . 4) '(2 . 5) '(0 . 6) '(1 . 7) '(2 . 8) '(0 . 9) '(1 . 10) '(2 . 11)) :start 3 :end nil :key car) (list '(0 . 0) '(1 . 1) '(2 . 2) '(0 . 9) '(1 . 10) '(2 . 11)))) (test-t (equal (remove-duplicates (list '(0 . 0) '(1 . 1) '(2 . 2) '(0 . 3) '(1 . 4) '(2 . 5) '(0 . 6) '(1 . 7) '(2 . 8) '(0 . 9) '(1 . 10) '(2 . 11)) :start 3 :end 9 :key car) '((0 . 0) (1 . 1) (2 . 2) (0 . 6) (1 . 7) (2 . 8) (0 . 9) (1 . 10) (2 . 11)))) (test-t (equal (remove-duplicates (list '(0 . 0) '(1 . 1) '(2 . 2) '(0 . 3) '(1 . 4) '(2 . 5) '(0 . 6) '(1 . 7) '(2 . 8) '(0 . 9) '(1 . 10) '(2 . 11)) :start 3 :end 9 :key car :from-end t) (list '(0 . 0) '(1 . 1) '(2 . 2) '(0 . 3) '(1 . 4) '(2 . 5) '(0 . 9) '(1 . 10) '(2 . 11)))) (test-t (equal (remove-duplicates (list "Monday" "Tuesday" "Wednesday" "Thursday" "Friday" "Saturday" "Sunday") :key length) (list "Tuesday" "Wednesday" "Saturday" "Sunday"))) (test-t (equal (remove-duplicates (list "Monday" "Tuesday" "Wednesday" "Thursday" "Friday" "Saturday" "Sunday") :key (lambda (arg) (char arg 0)) :test char=) (list "Monday" "Wednesday" "Thursday" "Friday" "Sunday"))) (test-t (equal (remove-duplicates (list #\a #\b #\c #\A #\B #\C) :key char-upcase) '(#\A #\B #\C))) (test-t (equal (remove-duplicates (list #\a #\b #\c #\A #\B #\C) :key char-upcase :from-end t) '(#\a #\b #\c))) (test-t (equal (remove-duplicates (list #\a #\b #\c #\A #\B #\C) :test char=) (list #\a #\b #\c #\A #\B #\C))) (test-t (equal (remove-duplicates (list #\a #\b #\c #\A #\B #\C) :test char-equal) (list #\A #\B #\C))) (test-t (equal (remove-duplicates (list #\a #\b #\c #\A #\B #\C) :test char-equal :from-end t) (list #\a #\b #\c))) (test-t (equal (remove-duplicates (list #\a #\1 #\b #\1 #\2 #\c #\0 #\A #\0 #\B #\C #\9) :key alpha-char-p) (list #\C #\9))) (test-t (equal (remove-duplicates (list #\a #\1 #\b #\1 #\2 #\c #\0 #\A #\0 #\B #\C #\9) :key alphanumericp) (list #\9))) (test-t (equal (remove-duplicates (list '(#\A . 0) '(#\b . 1) '(#\C . 2) '(#\a . 3) '(#\B . 4) '(#\c . 5) '(#\A . 6) '(#\b . 7) '(#\C . 8) '(#\a . 9) '(#\B . 10) '(#\c . 11))) (list '(#\A . 0) '(#\b . 1) '(#\C . 2) '(#\a . 3) '(#\B . 4) '(#\c . 5) '(#\A . 6) '(#\b . 7) '(#\C . 8) '(#\a . 9) '(#\B . 10) '(#\c . 11)))) (test-t (equal (remove-duplicates (list '(#\A . 0) '(#\b . 1) '(#\C . 2) '(#\a . 3) '(#\B . 4) '(#\c . 5) '(#\A . 6) '(#\b . 7) '(#\C . 8) '(#\a . 9) '(#\B . 10) '(#\c . 11)) :key car) (list '(#\A . 6) '(#\b . 7) '(#\C . 8) '(#\a . 9) '(#\B . 10) '(#\c . 11)))) (test-t (equal (remove-duplicates (list '(#\A . 0) '(#\b . 1) '(#\C . 2) '(#\a . 3) '(#\B . 4) '(#\c . 5) '(#\A . 6) '(#\b . 7) '(#\C . 8) '(#\a . 9) '(#\B . 10) '(#\c . 11)) :key car :start 3 :end 9) (list '(#\A . 0) '(#\b . 1) '(#\C . 2) '(#\a . 3) '(#\B . 4) '(#\c . 5) '(#\A . 6) '(#\b . 7) '(#\C . 8) '(#\a . 9) '(#\B . 10) '(#\c . 11)))) (test-t (equal (remove-duplicates (list '(#\A . 0) '(#\b . 1) '(#\C . 2) '(#\a . 3) '(#\B . 4) '(#\c . 5) '(#\A . 6) '(#\b . 7) '(#\C . 8) '(#\a . 9) '(#\B . 10) '(#\c . 11)) :key car :start 3 :end 9 :test char-equal) (list '(#\A . 0) '(#\b . 1) '(#\C . 2) '(#\A . 6) '(#\b . 7) '(#\C . 8) '(#\a . 9) '(#\B . 10) '(#\c . 11)))) (test-t (equal (remove-duplicates (list '(#\A . 0) '(#\b . 1) '(#\C . 2) '(#\a . 3) '(#\B . 4) '(#\c . 5) '(#\A . 6) '(#\b . 7) '(#\C . 8) '(#\a . 9) '(#\B . 10) '(#\c . 11)) :key car :start 3 :end 9 :test char-equal :from-end t) (list '(#\A . 0) '(#\b . 1) '(#\C . 2) '(#\a . 3) '(#\B . 4) '(#\c . 5) '(#\a . 9) '(#\B . 10) '(#\c . 11)))) (test-t (equal (remove-duplicates (list '(#\A . 0) '(#\b . 1) '(#\C . 2) '(#\a . 3) '(#\B . 4) '(#\c . 5) '(#\A . 6) '(#\b . 7) '(#\C . 8) '(#\a . 9) '(#\B . 10) '(#\c . 11)) :key car :start 3) (list '(#\A . 0) '(#\b . 1) '(#\C . 2) '(#\A . 6) '(#\b . 7) '(#\C . 8) '(#\a . 9) '(#\B . 10) '(#\c . 11)))) (test-t (equal (remove-duplicates (list '(#\A . 0) '(#\b . 1) '(#\C . 2) '(#\a . 3) '(#\B . 4) '(#\c . 5) '(#\A . 6) '(#\b . 7) '(#\C . 8) '(#\a . 9) '(#\B . 10) '(#\c . 11)) :key car :start 3 :end nil) (list '(#\A . 0) '(#\b . 1) '(#\C . 2) '(#\A . 6) '(#\b . 7) '(#\C . 8) '(#\a . 9) '(#\B . 10) '(#\c . 11)))) (test-t (equal (remove-duplicates (list '(#\A . 0) '(#\b . 1) '(#\C . 2) '(#\a . 3) '(#\B . 4) '(#\c . 5) '(#\A . 6) '(#\b . 7) '(#\C . 8) '(#\a . 9) '(#\B . 10) '(#\c . 11)) :key car :start 3 :from-end t) (list '(#\A . 0) '(#\b . 1) '(#\C . 2) '(#\a . 3) '(#\B . 4) '(#\c . 5) '(#\A . 6) '(#\b . 7) '(#\C . 8)))) (test-t (equal (remove-duplicates (list '(#\A . 0) '(#\b . 1) '(#\C . 2) '(#\a . 3) '(#\B . 4) '(#\c . 5) '(#\A . 6) '(#\b . 7) '(#\C . 8) '(#\a . 9) '(#\B . 10) '(#\c . 11)) :key car :end 9) (list '(#\a . 3) '(#\B . 4) '(#\c . 5) '(#\A . 6) '(#\b . 7) '(#\C . 8) '(#\a . 9) '(#\B . 10) '(#\c . 11)))) (test-t (equalp (remove-duplicates (vector 0 1 2 2 3 3 3)) #(0 1 2 3))) (test-t (equalp (remove-duplicates (vector 0 0 0 2 0 1 1 2 2 2 1 1 1 1 2)) #(0 1 2))) (test-t (equalp (remove-duplicates (vector 'a 'a 'b 'c 'c)) #(a b c))) (test-t (equalp (remove-duplicates (vector 0 1 2)) #(0 1 2))) (test-t (equalp (remove-duplicates (vector 2 0 2 1 1 1 0 0 0 1 2)) #(0 1 2))) (test-t (equalp (remove-duplicates (vector)) #())) (test-t (equalp (remove-duplicates (vector '(x . 0) '(y . 1) '(z . 2) '(a . 0) '(b . 1) '(c . 2)) :key cdr) #((a . 0) (b . 1) (c . 2)))) (test-t (equalp (remove-duplicates (vector 0 1 2 0 1 2 0 1 2 0 1 2) :start 3 :end 9) #(0 1 2 0 1 2 0 1 2))) (test-t (equalp (remove-duplicates (vector "Monday" "Tuesday" "Wednesday" "Thursday" "Friday" "Saturday" "Sunday") :key length) (vector "Tuesday" "Wednesday" "Saturday" "Sunday"))) (test-t (equalp (remove-duplicates (vector #\a #\b #\c #\A #\B #\C) :key char-upcase) #(#\A #\B #\C))) (test-t (equalp (remove-duplicates (vector #\a #\b #\c #\A #\B #\C) :key char-upcase :from-end t) #(#\a #\b #\c))) (test-t (equalp (remove-duplicates (vector #\a #\b #\c #\A #\B #\C) :test char=) (vector #\a #\b #\c #\A #\B #\C))) (test-t (equalp (remove-duplicates (vector #\a #\b #\c #\A #\B #\C) :test char-equal) (vector #\A #\B #\C))) (test-t (equalp (remove-duplicates (vector #\a #\b #\c #\A #\B #\C) :test char-equal :from-end t) (vector #\a #\b #\c))) (test-t (equalp (remove-duplicates (vector #\a #\1 #\b #\1 #\2 #\c #\0 #\A #\0 #\B #\C #\9) :key alpha-char-p) (vector #\C #\9))) (test-t (equalp (remove-duplicates (vector #\a #\1 #\b #\1 #\2 #\c #\0 #\A #\0 #\B #\C #\9) :key alphanumericp) (vector #\9))) (test-t (string= (remove-duplicates (copy-seq "")) "")) (test-t (string= (remove-duplicates (copy-seq "abc")) "abc")) (test-t (string= (remove-duplicates (copy-seq "abcabc")) "abc")) (test-t (string= (remove-duplicates (copy-seq "cbaabc")) "abc")) (test-t (string= (remove-duplicates (copy-seq "cbaabc") :from-end t) "cba")) (test-t (string= (remove-duplicates (copy-seq "cbaabcABCCBA")) "abcCBA")) (test-t (string= (remove-duplicates (copy-seq "cbaabcABCCBA") :from-end t) "cbaABC")) (test-t (string= (remove-duplicates (copy-seq "cbaabcABCCBA") :key char-downcase) "CBA")) (test-t (string= (remove-duplicates (copy-seq "cbaabcABCCBA") :key char-downcase :from-end t) "cba")) (test-t (string= (remove-duplicates (copy-seq "cbaabcABCCBA") :start 3) "cbaabcCBA")) (test-t (string= (remove-duplicates (copy-seq "cbaabcABCCBA") :start 3 :from-end t) "cbaabcABC")) (test-t (string= (remove-duplicates (copy-seq "cbaabcABCCBA") :start 3 :end 9) "cbaabcABCCBA")) (test-t (string= (remove-duplicates (copy-seq "cbaabcABCCBA") :start 3 :end 9 :key char-upcase) "cbaABCCBA")) (test-t (string= (remove-duplicates (copy-seq "cbaabcABCCBA") :start 3 :end 9 :key char-upcase :from-end t) "cbaabcCBA")) (test-t (string= (remove-duplicates (copy-seq "cbaabcABCCBA") :start 3 :end 9 :test char-equal :from-end t) "cbaabcCBA")) (test-t (string= (remove-duplicates (copy-seq "cbaabcABCCBA") :start 3 :end 9 :key upper-case-p :test eq) "cbacCCBA")) (test-t (string= (remove-duplicates (copy-seq "cbaabcABCCBA") :start 3 :end 9 :key upper-case-p :test eq :from-end t) "cbaaACBA")) ) (let () (define* (merge result-type seq1 seq2 predicate (key identity)) (let* ((len1 (length seq1)) (len2 (length seq2)) (size (+ len1 len2)) (obj (make-sequence result-type size)) (i 0) (j 0)) (do ((n 0 (+ n 1))) ((or (= i len1) (= j len2)) (if (< i len1) (do ((k i (+ k 1))) ((= k len1) obj) (set! (obj n) (seq1 k)) (set! n (+ n 1))) (if (< j len2) (do ((k j (+ k 1))) ((= k len2) obj) (set! (obj n) (seq2 k)) (set! n (+ n 1))) obj))) (if (null (predicate (key (seq1 i)) (key (seq2 j)))) (begin (set! (obj n) (seq2 j)) (set! j (+ j 1))) (begin (set! (obj n) (seq1 i)) (set! i (+ i 1))))))) (test-t (let ((test1 (list 1 3 4 6 7)) (test2 (list 2 5 8))) (equal (merge 'list test1 test2 <) '(1 2 3 4 5 6 7 8)))) (test-t (let ((test1 (vector '(red . 1) '(blue . 4))) (test2 (vector '(yellow . 2) '(green . 7)))) (equalp (merge 'vector test1 test2 < :key cdr) #((red . 1) (yellow . 2) (blue . 4) (green . 7))))) (test-t (equal (merge 'list (list 1 3 5 7 9) (list 0 2 4 6 8) <) '(0 1 2 3 4 5 6 7 8 9))) (test-t (equal (merge 'list (list 0 1 2) nil <) '(0 1 2))) (test-t (equal (merge 'list nil (list 0 1 2) <) '(0 1 2))) (test-t (equal (merge 'list nil nil <) nil)) (test-t (equal (merge 'list (list '(1 1) '(2 1) '(3 1)) (list '(1 2) '(2 2) '(3 2)) <= :key car) '((1 1) (1 2) (2 1) (2 2) (3 1) (3 2)))) (test-t (equal (merge 'list (list '(1 1) '(2 1) '(2 1 1) '(3 1)) (list '(1 2) '(2 2) '(3 2)) <= :key car) '((1 1) (1 2) (2 1) (2 1 1) (2 2) (3 1) (3 2)))) (test-t (equal (merge 'list (list '(1 1) '(2 1) '(2 1 1) '(3 1)) (list '(1 2) '(2 2) '(3 2) '(3 2 2)) <= :key car) '((1 1) (1 2) (2 1) (2 1 1) (2 2) (3 1) (3 2) (3 2 2)))) (test-t (equal (merge 'list (list 3 1 9 5 7) (list 8 6 0 2 4) <) '(3 1 8 6 0 2 4 9 5 7))) (test-t (equal (merge 'list (vector 1 3 5 7 9) (list 0 2 4 6 8) <) '(0 1 2 3 4 5 6 7 8 9))) (test-t (equal (merge 'list (vector 0 1 2) nil <) '(0 1 2))) (test-t (equal (merge 'list #() (list 0 1 2) <) '(0 1 2))) (test-t (equal (merge 'list #() #() <) nil)) (test-t (equal (merge 'list (vector '(1 1) '(2 1) '(3 1)) (list '(1 2) '(2 2) '(3 2)) <= :key car) '((1 1) (1 2) (2 1) (2 2) (3 1) (3 2)))) (test-t (equal (merge 'list (vector '(1 1) '(2 1) '(2 1 1) '(3 1)) (list '(1 2) '(2 2) '(3 2)) <= :key car) '((1 1) (1 2) (2 1) (2 1 1) (2 2) (3 1) (3 2)))) (test-t (equal (merge 'list (vector '(1 1) '(2 1) '(2 1 1) '(3 1)) (list '(1 2) '(2 2) '(3 2) '(3 2 2)) <= :key car) '((1 1) (1 2) (2 1) (2 1 1) (2 2) (3 1) (3 2) (3 2 2)))) (test-t (equal (merge 'list (vector 3 1 9 5 7) (list 8 6 0 2 4) <) '(3 1 8 6 0 2 4 9 5 7))) (test-t (equal (merge 'list (list 1 3 5 7 9) (vector 0 2 4 6 8) <) '(0 1 2 3 4 5 6 7 8 9))) (test-t (equal (merge 'list (list 0 1 2) #() <) '(0 1 2))) (test-t (equal (merge 'list nil (vector 0 1 2) <) '(0 1 2))) (test-t (equal (merge 'list nil #() <) nil)) (test-t (equal (merge 'list (list '(1 1) '(2 1) '(3 1)) (vector '(1 2) '(2 2) '(3 2)) <= :key car) '((1 1) (1 2) (2 1) (2 2) (3 1) (3 2)))) (test-t (equal (merge 'list (list '(1 1) '(2 1) '(2 1 1) '(3 1)) (vector '(1 2) '(2 2) '(3 2)) <= :key car) '((1 1) (1 2) (2 1) (2 1 1) (2 2) (3 1) (3 2)))) (test-t (equal (merge 'list (list '(1 1) '(2 1) '(2 1 1) '(3 1)) (vector '(1 2) '(2 2) '(3 2) '(3 2 2)) <= :key car) '((1 1) (1 2) (2 1) (2 1 1) (2 2) (3 1) (3 2) (3 2 2)))) (test-t (equal (merge 'list (list 3 1 9 5 7) (vector 8 6 0 2 4) <) '(3 1 8 6 0 2 4 9 5 7))) (test-t (equal (merge 'list (vector 1 3 5 7 9) (vector 0 2 4 6 8) <) '(0 1 2 3 4 5 6 7 8 9))) (test-t (equal (merge 'list (vector 0 1 2) #() <) '(0 1 2))) (test-t (equal (merge 'list #() (vector 0 1 2) <) '(0 1 2))) (test-t (equal (merge 'list #() #() <) nil)) (test-t (equal (merge 'list (vector '(1 1) '(2 1) '(3 1)) (vector '(1 2) '(2 2) '(3 2)) <= :key car) '((1 1) (1 2) (2 1) (2 2) (3 1) (3 2)))) (test-t (equal (merge 'list (vector '(1 1) '(2 1) '(2 1 1) '(3 1)) (vector '(1 2) '(2 2) '(3 2)) <= :key car) '((1 1) (1 2) (2 1) (2 1 1) (2 2) (3 1) (3 2)))) (test-t (equal (merge 'list (vector '(1 1) '(2 1) '(2 1 1) '(3 1)) (vector '(1 2) '(2 2) '(3 2) '(3 2 2)) <= :key car) '((1 1) (1 2) (2 1) (2 1 1) (2 2) (3 1) (3 2) (3 2 2)))) (test-t (equal (merge 'list (vector 3 1 9 5 7) (vector 8 6 0 2 4) <) '(3 1 8 6 0 2 4 9 5 7))) (test-t (equalp (merge 'vector (list 1 3 5 7 9) (list 0 2 4 6 8) <) #(0 1 2 3 4 5 6 7 8 9))) (test-t (equalp (merge 'vector (list 1 3 5 7 9) (list 0 2 4 6 8) <) #(0 1 2 3 4 5 6 7 8 9))) (test-t (equalp (merge 'vector (list 0 1 2) nil <) #(0 1 2))) (test-t (equalp (merge 'vector nil (list 0 1 2) <) #(0 1 2))) (test-t (equalp (merge 'vector nil nil <) #())) (test-t (equalp (merge 'vector (list '(1 1) '(2 1) '(3 1)) (list '(1 2) '(2 2) '(3 2)) <= :key car) #((1 1) (1 2) (2 1) (2 2) (3 1) (3 2)))) (test-t (equalp (merge 'vector (list '(1 1) '(2 1) '(2 1 1) '(3 1)) (list '(1 2) '(2 2) '(3 2)) <= :key car) #((1 1) (1 2) (2 1) (2 1 1) (2 2) (3 1) (3 2)))) (test-t (equalp (merge 'vector (list '(1 1) '(2 1) '(2 1 1) '(3 1)) (list '(1 2) '(2 2) '(3 2) '(3 2 2)) <= :key car) #((1 1) (1 2) (2 1) (2 1 1) (2 2) (3 1) (3 2) (3 2 2)))) (test-t (equalp (merge 'vector (list 3 1 9 5 7) (list 8 6 0 2 4) <) #(3 1 8 6 0 2 4 9 5 7))) (test-t (equalp (merge 'vector (vector 1 3 5 7 9) (list 0 2 4 6 8) <) #(0 1 2 3 4 5 6 7 8 9))) (test-t (equalp (merge 'vector (vector 1 3 5 7 9) (list 0 2 4 6 8) <) #(0 1 2 3 4 5 6 7 8 9))) (test-t (equalp (merge 'vector (vector 0 1 2) nil <) #(0 1 2))) (test-t (equalp (merge 'vector #() (list 0 1 2) <) #(0 1 2))) (test-t (equalp (merge 'vector #() #() <) #())) (test-t (equalp (merge 'vector (vector '(1 1) '(2 1) '(3 1)) (list '(1 2) '(2 2) '(3 2)) <= :key car) #((1 1) (1 2) (2 1) (2 2) (3 1) (3 2)))) (test-t (equalp (merge 'vector (vector '(1 1) '(2 1) '(2 1 1) '(3 1)) (list '(1 2) '(2 2) '(3 2)) <= :key car) #((1 1) (1 2) (2 1) (2 1 1) (2 2) (3 1) (3 2)))) (test-t (equalp (merge 'vector (vector '(1 1) '(2 1) '(2 1 1) '(3 1)) (list '(1 2) '(2 2) '(3 2) '(3 2 2)) <= :key car) #((1 1) (1 2) (2 1) (2 1 1) (2 2) (3 1) (3 2) (3 2 2)))) (test-t (equalp (merge 'vector (vector 3 1 9 5 7) (list 8 6 0 2 4) <) #(3 1 8 6 0 2 4 9 5 7))) (test-t (equalp (merge 'vector (list 1 3 5 7 9) (vector 0 2 4 6 8) <) #(0 1 2 3 4 5 6 7 8 9))) (test-t (equalp (merge 'vector (list 1 3 5 7 9) (vector 0 2 4 6 8) <) #(0 1 2 3 4 5 6 7 8 9))) (test-t (equalp (merge 'vector (list 0 1 2) #() <) #(0 1 2))) (test-t (equalp (merge 'vector nil (vector 0 1 2) <) #(0 1 2))) (test-t (equalp (merge 'vector nil #() <) #())) (test-t (equalp (merge 'vector (list '(1 1) '(2 1) '(3 1)) (vector '(1 2) '(2 2) '(3 2)) <= :key car) #((1 1) (1 2) (2 1) (2 2) (3 1) (3 2)))) (test-t (equalp (merge 'vector (list '(1 1) '(2 1) '(2 1 1) '(3 1)) (vector '(1 2) '(2 2) '(3 2)) <= :key car) #((1 1) (1 2) (2 1) (2 1 1) (2 2) (3 1) (3 2)))) (test-t (equalp (merge 'vector (list '(1 1) '(2 1) '(2 1 1) '(3 1)) (vector '(1 2) '(2 2) '(3 2) '(3 2 2)) <= :key car) #((1 1) (1 2) (2 1) (2 1 1) (2 2) (3 1) (3 2) (3 2 2)))) (test-t (equalp (merge 'vector (list 3 1 9 5 7) (vector 8 6 0 2 4) <) #(3 1 8 6 0 2 4 9 5 7))) (test-t (equalp (merge 'vector (vector 1 3 5 7 9) (vector 0 2 4 6 8) <) #(0 1 2 3 4 5 6 7 8 9))) (test-t (equalp (merge 'vector (vector 0 1 2) #() <) #(0 1 2))) (test-t (equalp (merge 'vector #() (vector 0 1 2) <) #(0 1 2))) (test-t (equalp (merge 'vector #() #() <) #())) (test-t (equalp (merge 'vector (vector '(1 1) '(2 1) '(3 1)) (vector '(1 2) '(2 2) '(3 2)) <= :key car) #((1 1) (1 2) (2 1) (2 2) (3 1) (3 2)))) (test-t (equalp (merge 'vector (vector '(1 1) '(2 1) '(2 1 1) '(3 1)) (vector '(1 2) '(2 2) '(3 2)) <= :key car) #((1 1) (1 2) (2 1) (2 1 1) (2 2) (3 1) (3 2)))) (test-t (equalp (merge 'vector (vector '(1 1) '(2 1) '(2 1 1) '(3 1)) (vector '(1 2) '(2 2) '(3 2) '(3 2 2)) <= :key car) #((1 1) (1 2) (2 1) (2 1 1) (2 2) (3 1) (3 2) (3 2 2)))) (test-t (equalp (merge 'vector (vector 3 1 9 5 7) (vector 8 6 0 2 4) <) #(3 1 8 6 0 2 4 9 5 7))) (test-t (string= (merge 'string (list #\a #\c #\e) (list #\b #\d #\f) char<) "abcdef")) (test-t (string= (merge 'string (list #\a #\b #\c) (list #\d #\e #\f) char<) "abcdef")) (test-t (string= (merge 'string (list #\a #\b #\c) () char<) "abc")) (test-t (string= (merge 'string () (list #\a #\b #\c) char<) "abc")) (test-t (string= (merge 'string (list #\a #\b #\c) (copy-seq "") char<) "abc")) (test-t (string= (merge 'string (list #\a #\b #\z) #(#\c #\x #\y) char<) "abcxyz")) ) (let () (define* (search seq1 seq2 from-end (test eql) (key identity) (start1 0) (start2 0) end1 end2) (let* ((len1 (length seq1)) (len2 (length seq2)) (nd1 (or (and (number? end1) end1) len1)) (nd2 (or (and (number? end2) end2) len2))) (set! len1 (min len1 (- nd1 start1))) (set! len2 (min len2 (- nd2 start2))) (if (or (= len2 0) (> len1 len2)) () (call-with-exit (lambda (return) (if (or (not from-end) (null? from-end)) (do ((i start2 (+ i 1))) ((> i (- nd2 len1)) ()) (do ((j start1 (+ j 1)) (k i (+ k 1))) ((or (= j nd1) (not (test (key (seq1 j)) (key (seq2 k))))) (if (= j nd1) (return i))))) (do ((i (- nd2 len1) (- i 1))) ((< i start2) ()) (do ((j start1 (+ j 1)) (k i (+ k 1))) ((or (= j nd1) (not (test (key (seq1 j)) (key (seq2 k))))) (if (= j nd1) (return i))))))))))) (define* (mismatch seq1 seq2 from-end (test eql) (key identity) (start1 0) (start2 0) end1 end2) (let* ((nd1 (or (and (number? end1) end1) (length seq1))) (nd2 (or (and (number? end2) end2) (length seq2)))) (if (not from-end) (do ((i start1 (+ i 1)) (j start2 (+ j 1))) ((or (= i nd1) (= j nd2) (not (test (key (seq1 i)) (key (seq2 j))))) (if (and (= i nd1) (= j nd2)) () i))) (do ((i (- nd1 1) (- i 1)) (j (- nd2 1) (- j 1))) ((or (< i start1) (< j start2) (not (test (key (seq1 i)) (key (seq2 j))))) (if (and (< i start1) (< j start2)) () (+ i 1))))))) (test-t (eql (search "dog" "it's a dog's life") 7)) (test-t (eql (search '(0 1) '(2 4 6 1 3 5) :key oddp) 2)) (test-t (null (search '(a b c) '(x y z)))) (test-t (eql (search () '(x y z)) 0)) (test-t (eql (search '(a) '(a)) 0)) (test-t (eql (search '(a b c) '(a b c x y z)) 0)) (test-t (eql (search '(a b c) '(x a b c y z)) 1)) (test-t (eql (search '(a b c) '(x y a b c z)) 2)) (test-t (eql (search '(a b c) '(x y z a b c)) 3)) (test-t (eql (search '(a b c) '(a b c a b c) :start2 1) 3)) (test-t (eql (search '(a b c) '(a b c a b c) :start2 1 :end2 nil) 3)) (test-t (eql (search '(a b c) '(a b c a b c) :start1 1 :start2 1 :end2 nil) 1)) (test-t (eql (search '(a b c) '(a b c a b c) :start1 1 :end1 nil :start2 1 :end2 nil) 1)) (test-t (null (search '(a b c) '(a b c a b c) :start2 0 :end2 0))) (test-t (null (search '(a b c) '(a b c a b c) :start2 1 :end2 1))) (test-t (null (search '(a b c) '(a b c a b c) :start2 2 :end2 2))) (test-t (null (search '(a b c) '(a b c a b c) :start2 3 :end2 3))) (test-t (null (search '(a b c) '(a b c a b c) :start2 4 :end2 4))) (test-t (null (search '(a b c) '(a b c a b c) :start2 5 :end2 5))) (test-t (null (search '(a b c) '(a b c a b c) :start2 6 :end2 6))) (test-t (eql (search '(a b c) '(a b c a b c)) 0)) (test-t (eql (search '(a b c) '(a b c a b c) :from-end t) 3)) (test-t (eql (search '(a b c) '(a b c a b c) :start2 3 :end2 6) 3)) (test-t (eql (search '(a b c) '(a b c a b c) :start2 3 :end2 6 :from-end t) 3)) (test-t (eql (search '(a b c) '(a b c a b c) :start1 0 :end1 2 :start2 0 :end2 6) 0)) (test-t (eql (search '(a b c) '(a b c a b c) :start1 0 :end1 2 :start2 0 :end2 6 :from-end t) 3)) (test-t (null (search '(#\a #\b #\c) '(#\A #\B #\C)))) (test-t (eql (search '(#\a #\b #\c) '(#\A #\B #\C) :test char-equal) 0)) (test-t (eql (search '(#\a #\b) '(#\a #\b #\x #\y #\z)) 0)) (test-t (eql (search '(#\a #\b) '(#\a #\b #\x #\y #\z) :test char<) 1)) (test-t (null (search '((a) (b)) '((x) (y) (z) (a) (b) (c))))) (test-t (eql (search '((a) (b)) '((x) (y) (z) (a) (b) (c)) :key car) 3)) (test-t (eql (search '((a) (b)) '((a) (b) (c) (x) (y) (z) (a) (b) (c)) :key car) 0)) (test-t (eql (search '((a) (b)) '((a) (b) (c) (x) (y) (z) (a) (b) (c)) :key car :from-end t) 6)) (test-t (eql (search '((a a) (b b)) '((a) (b) (c) (x) (y) (z) (a) (b) (c)) :key car) 0)) (test-t (eql (search '((a a) (b b)) '((a nil) (b t) (c nil) (x) (y) (z) (a 0) (b 1) (c 2)) :key car :from-end t) 6)) (test-t (eql (search '(("a" a) ("b" b)) '(("a" nil) ("b" t) ("c" nil) ("x") ("y") ("z") ("A" 0) ("B" 1) ("C" 2)) :start1 1 :end1 2 :start2 3 :end2 nil :key car :test string-equal :from-end t) 7)) (test-t (null (search #(a b c) '(x y z)))) (test-t (eql (search #() '(x y z)) 0)) (test-t (eql (search #(a) '(a)) 0)) (test-t (eql (search #(a b c) '(a b c x y z)) 0)) (test-t (eql (search #(a b c) '(x a b c y z)) 1)) (test-t (eql (search #(a b c) '(x y a b c z)) 2)) (test-t (eql (search #(a b c) '(x y z a b c)) 3)) (test-t (eql (search #(a b c) '(a b c a b c) :start2 1) 3)) (test-t (eql (search #(a b c) '(a b c a b c) :start2 1 :end2 nil) 3)) (test-t (eql (search #(a b c) '(a b c a b c) :start1 1 :start2 1 :end2 nil) 1)) (test-t (eql (search #(a b c) '(a b c a b c) :start1 1 :end1 nil :start2 1 :end2 nil) 1)) (test-t (null (search #(a b c) '(a b c a b c) :start2 0 :end2 0))) (test-t (null (search #(a b c) '(a b c a b c) :start2 1 :end2 1))) (test-t (null (search #(a b c) '(a b c a b c) :start2 2 :end2 2))) (test-t (null (search #(a b c) '(a b c a b c) :start2 3 :end2 3))) (test-t (null (search #(a b c) '(a b c a b c) :start2 4 :end2 4))) (test-t (null (search #(a b c) '(a b c a b c) :start2 5 :end2 5))) (test-t (null (search #(a b c) '(a b c a b c) :start2 6 :end2 6))) (test-t (eql (search #(a b c) '(a b c a b c)) 0)) (test-t (eql (search #(a b c) '(a b c a b c) :from-end t) 3)) (test-t (eql (search #(a b c) '(a b c a b c) :start2 3 :end2 6) 3)) (test-t (eql (search #(a b c) '(a b c a b c) :start2 3 :end2 6 :from-end t) 3)) (test-t (eql (search #(a b c) '(a b c a b c) :start1 0 :end1 2 :start2 0 :end2 6) 0)) (test-t (eql (search #(a b c) '(a b c a b c) :start1 0 :end1 2 :start2 0 :end2 6 :from-end t) 3)) (test-t (null (search #(#\a #\b #\c) '(#\A #\B #\C)))) (test-t (eql (search #(#\a #\b #\c) '(#\A #\B #\C) :test char-equal) 0)) (test-t (eql (search #(#\a #\b) '(#\a #\b #\x #\y #\z)) 0)) (test-t (eql (search #(#\a #\b) '(#\a #\b #\x #\y #\z) :test char<) 1)) (test-t (null (search #((a) (b)) '((x) (y) (z) (a) (b) (c))))) (test-t (eql (search #((a) (b)) '((x) (y) (z) (a) (b) (c)) :key car) 3)) (test-t (eql (search #((a) (b)) '((a) (b) (c) (x) (y) (z) (a) (b) (c)) :key car) 0)) (test-t (eql (search #((a) (b)) '((a) (b) (c) (x) (y) (z) (a) (b) (c)) :key car :from-end t) 6)) (test-t (eql (search #((a a) (b b)) '((a) (b) (c) (x) (y) (z) (a) (b) (c)) :key car) 0)) (test-t (eql (search #((a a) (b b)) '((a nil) (b t) (c nil) (x) (y) (z) (a 0) (b 1) (c 2)) :key car :from-end t) 6)) (test-t (eql (search #(("a" a) ("b" b)) '(("a" nil) ("b" t) ("c" nil) ("x") ("y") ("z") ("A" 0) ("B" 1) ("C" 2)) :start1 1 :end1 2 :start2 3 :end2 nil :key car :test string-equal :from-end t) 7)) (test-t (null (search '(a b c) #(x y z)))) (test-t (eql (search () #(x y z)) 0)) (test-t (eql (search '(a) #(a)) 0)) (test-t (eql (search '(a b c) #(a b c x y z)) 0)) (test-t (eql (search '(a b c) #(x a b c y z)) 1)) (test-t (eql (search '(a b c) #(x y a b c z)) 2)) (test-t (eql (search '(a b c) #(x y z a b c)) 3)) (test-t (eql (search '(a b c) #(a b c a b c) :start2 1) 3)) (test-t (eql (search '(a b c) #(a b c a b c) :start2 1 :end2 nil) 3)) (test-t (eql (search '(a b c) #(a b c a b c) :start1 1 :start2 1 :end2 nil) 1)) (test-t (eql (search '(a b c) #(a b c a b c) :start1 1 :end1 nil :start2 1 :end2 nil) 1)) (test-t (null (search '(a b c) #(a b c a b c) :start2 0 :end2 0))) (test-t (null (search '(a b c) #(a b c a b c) :start2 1 :end2 1))) (test-t (null (search '(a b c) #(a b c a b c) :start2 2 :end2 2))) (test-t (null (search '(a b c) #(a b c a b c) :start2 3 :end2 3))) (test-t (null (search '(a b c) #(a b c a b c) :start2 4 :end2 4))) (test-t (null (search '(a b c) #(a b c a b c) :start2 5 :end2 5))) (test-t (null (search '(a b c) #(a b c a b c) :start2 6 :end2 6))) (test-t (eql (search '(a b c) #(a b c a b c)) 0)) (test-t (eql (search '(a b c) #(a b c a b c) :from-end t) 3)) (test-t (eql (search '(a b c) #(a b c a b c) :start2 3 :end2 6) 3)) (test-t (eql (search '(a b c) #(a b c a b c) :start2 3 :end2 6 :from-end t) 3)) (test-t (eql (search '(a b c) #(a b c a b c) :start1 0 :end1 2 :start2 0 :end2 6) 0)) (test-t (eql (search '(a b c) #(a b c a b c) :start1 0 :end1 2 :start2 0 :end2 6 :from-end t) 3)) (test-t (null (search '(#\a #\b #\c) #(#\A #\B #\C)))) (test-t (eql (search '(#\a #\b #\c) #(#\A #\B #\C) :test char-equal) 0)) (test-t (eql (search '(#\a #\b) #(#\a #\b #\x #\y #\z)) 0)) (test-t (eql (search '(#\a #\b) #(#\a #\b #\x #\y #\z) :test char<) 1)) (test-t (null (search '((a) (b)) #((x) (y) (z) (a) (b) (c))))) (test-t (eql (search '((a) (b)) #((x) (y) (z) (a) (b) (c)) :key car) 3)) (test-t (eql (search '((a) (b)) #((a) (b) (c) (x) (y) (z) (a) (b) (c)) :key car) 0)) (test-t (eql (search '((a) (b)) #((a) (b) (c) (x) (y) (z) (a) (b) (c)) :key car :from-end t) 6)) (test-t (eql (search '((a a) (b b)) #((a) (b) (c) (x) (y) (z) (a) (b) (c)) :key car) 0)) (test-t (eql (search '((a a) (b b)) #((a nil) (b t) (c nil) (x) (y) (z) (a 0) (b 1) (c 2)) :key car :from-end t) 6)) (test-t (eql (search '(("a" a) ("b" b)) #(("a" nil) ("b" t) ("c" nil) ("x") ("y") ("z") ("A" 0) ("B" 1) ("C" 2)) :start1 1 :end1 2 :start2 3 :end2 nil :key car :test string-equal :from-end t) 7)) (test-t (null (search #(a b c) #(x y z)))) (test-t (eql (search #() #(x y z)) 0)) (test-t (eql (search #(a) #(a)) 0)) (test-t (eql (search #(a b c) #(a b c x y z)) 0)) (test-t (eql (search #(a b c) #(x a b c y z)) 1)) (test-t (eql (search #(a b c) #(x y a b c z)) 2)) (test-t (eql (search #(a b c) #(x y z a b c)) 3)) (test-t (eql (search #(a b c) #(a b c a b c) :start2 1) 3)) (test-t (eql (search #(a b c) #(a b c a b c) :start2 1 :end2 nil) 3)) (test-t (eql (search #(a b c) #(a b c a b c) :start1 1 :start2 1 :end2 nil) 1)) (test-t (eql (search #(a b c) #(a b c a b c) :start1 1 :end1 nil :start2 1 :end2 nil) 1)) (test-t (null (search #(a b c) #(a b c a b c) :start2 0 :end2 0))) (test-t (null (search #(a b c) #(a b c a b c) :start2 1 :end2 1))) (test-t (null (search #(a b c) #(a b c a b c) :start2 2 :end2 2))) (test-t (null (search #(a b c) #(a b c a b c) :start2 3 :end2 3))) (test-t (null (search #(a b c) #(a b c a b c) :start2 4 :end2 4))) (test-t (null (search #(a b c) #(a b c a b c) :start2 5 :end2 5))) (test-t (null (search #(a b c) #(a b c a b c) :start2 6 :end2 6))) (test-t (eql (search #(a b c) #(a b c a b c)) 0)) (test-t (eql (search #(a b c) #(a b c a b c) :from-end t) 3)) (test-t (eql (search #(a b c) #(a b c a b c) :start2 3 :end2 6) 3)) (test-t (eql (search #(a b c) #(a b c a b c) :start2 3 :end2 6 :from-end t) 3)) (test-t (eql (search #(a b c) #(a b c a b c) :start1 0 :end1 2 :start2 0 :end2 6) 0)) (test-t (eql (search #(a b c) #(a b c a b c) :start1 0 :end1 2 :start2 0 :end2 6 :from-end t) 3)) (test-t (null (search #(#\a #\b #\c) #(#\A #\B #\C)))) (test-t (eql (search #(#\a #\b #\c) #(#\A #\B #\C) :test char-equal) 0)) (test-t (eql (search #(#\a #\b) #(#\a #\b #\x #\y #\z)) 0)) (test-t (eql (search #(#\a #\b) #(#\a #\b #\x #\y #\z) :test char<) 1)) (test-t (null (search #((a) (b)) #((x) (y) (z) (a) (b) (c))))) (test-t (eql (search #((a) (b)) #((x) (y) (z) (a) (b) (c)) :key car) 3)) (test-t (eql (search #((a) (b)) #((a) (b) (c) (x) (y) (z) (a) (b) (c)) :key car) 0)) (test-t (eql (search #((a) (b)) #((a) (b) (c) (x) (y) (z) (a) (b) (c)) :key car :from-end t) 6)) (test-t (eql (search #((a a) (b b)) #((a) (b) (c) (x) (y) (z) (a) (b) (c)) :key car) 0)) (test-t (eql (search #((a a) (b b)) #((a nil) (b t) (c nil) (x) (y) (z) (a 0) (b 1) (c 2)) :key car :from-end t) 6)) (test-t (eql (search #(("a" a) ("b" b)) #(("a" nil) ("b" t) ("c" nil) ("x") ("y") ("z") ("A" 0) ("B" 1) ("C" 2)) :start1 1 :end1 2 :start2 3 :end2 nil :key car :test string-equal :from-end t) 7)) (test-t (null (search "peace" "LOVE&PEACE"))) (test-t (eql (search "peace" "LOVE&PEACE" :test char-equal) 5)) (test-t (null (search "PeAcE" "LoVe&pEaCe"))) (test-t (eql (search "PeAcE" "LoVe&pEaCe" :key char-upcase) 5)) (test-t (eql (search "abc" "abc xyz abc" :from-end t) 8)) (test-t (eql (search "abc" "abc xyz abc xyz abc xyz abc" :start2 8 :end2 19) 8)) (test-t (eql (search "abc" "abc xyz abc xyz abc xyz abc" :from-end t :start2 8 :end2 19) 16)) (test-t (eql (mismatch "abcd" "ABCDE" :test char-equal) 4)) (test-t (eql (mismatch '(3 2 1 1 2 3) '(1 2 3) :from-end t) 3)) (test-t (null (mismatch '(1 2 3 4 5 6) '(3 4 5 6 7) :start1 2 :end2 4))) (test-t (null (mismatch () ()))) (test-t (eql (mismatch '(a b c) '(x y z)) 0)) (test-t (eql (mismatch () '(x y z)) 0)) (test-t (eql (mismatch '(x y z) ()) 0)) (test-t (null (mismatch '(a) '(a)))) (test-t (eql (mismatch '(a b c x y z) '(a b c)) 3)) (test-t (null (mismatch '(a b c) '(a b c)))) (test-t (eql (mismatch '(a b c d e f) '(a b c)) 3)) (test-t (eql (mismatch '(a b c) '(a b c d e f)) 3)) (test-t (eql (mismatch '(a b c) '(a b x)) 2)) (test-t (eql (mismatch '(a b c) '(a x c)) 1)) (test-t (eql (mismatch '(a b c) '(x b c)) 0)) (test-t (eql (mismatch '(x y z a b c x y z) '(a b c) :start1 3) 6)) (test-t (eql (mismatch '(x y z a b c x y z) '(a b c) :start1 3 :end1 nil) 6)) (test-t (eql (mismatch '(x y z a b c x y z) '(a b c) :start1 3 :end1 4) 4)) (test-t (eql (mismatch '(x y z a b c x y z) '(a b c) :start1 3 :end1 3) 3)) (test-t (null (mismatch '(x y z) () :start1 0 :end1 0))) (test-t (null (mismatch '(x y z) () :start1 1 :end1 1))) (test-t (null (mismatch '(x y z) () :start1 2 :end1 2))) (test-t (null (mismatch '(x y z) () :start1 3 :end1 3))) (test-t (null (mismatch '(x y z) () :start1 0 :end1 0 :start2 0 :end2 0))) (test-t (null (mismatch '(x y z) () :start1 1 :end1 1 :start2 1 :end2 1))) (test-t (null (mismatch '(x y z) () :start1 2 :end1 2 :start2 2 :end2 2))) (test-t (null (mismatch '(x y z) () :start1 3 :end1 3 :start2 3 :end2 3))) (test-t (null (mismatch '(x y z) () :start1 0 :end1 0 :start2 3 :end2 3))) (test-t (null (mismatch '(x y z) () :start1 1 :end1 1 :start2 2 :end2 2))) (test-t (null (mismatch '(x y z) () :start1 2 :end1 2 :start2 1 :end2 1))) (test-t (null (mismatch '(x y z) () :start1 3 :end1 3 :start2 0 :end2 0))) (test-t (eql (mismatch '(x y z) '(a b c) :start1 0 :end1 0) 0)) (test-t (eql (mismatch '(x y z) '(a b c) :start1 1 :end1 1) 1)) (test-t (eql (mismatch '(x y z) '(a b c) :start1 2 :end1 2) 2)) (test-t (eql (mismatch '(x y z) '(a b c) :start1 3 :end1 3) 3)) (test-t (eql (mismatch '(x y z) '(x y z) :start1 0 :end1 1) 1)) (test-t (eql (mismatch '(x y z) '(x y z) :start1 0 :end1 2) 2)) (test-t (eql (mismatch '(x y z) '(x y z Z) :start1 0 :end1 3) 3)) (test-t (null (mismatch '(x y z) '(x y z) :start1 0 :end1 3))) (test-t (eql (mismatch '(a b c x y z) '(x y z a b c)) 0)) (test-t (eql (mismatch '(a b c x y z) '(x y z a b c) :start1 3) 6)) (test-t (eql (mismatch '(a b c x y z a b c) '(x y z a b c x y z) :start1 3) 9)) (test-t (eql (mismatch '(a b c x y z a b c) '(x y z a b c x y z) :start1 6) 6)) (test-t (eql (mismatch '(a b c x y z a b c) '(x y z a b c x y z) :start1 6 :start2 3) 9)) (test-t (eql (mismatch '(a b c x y z a b c) '(x y z a b c x y z) :start1 0 :start2 3) 6)) (test-t (eql (mismatch '(a b c) '(a b c x y z)) 3)) (test-t (eql (mismatch '(a b c) '(x a b c y z)) 0)) (test-t (eql (mismatch '(a b c) '(x a b c y z) :start2 1) 3)) (test-t (eql (mismatch '(a b c) '(x a b c y z) :start2 1 :end2 nil) 3)) (test-t (null (mismatch '(a b c) '(x a b c y z) :start2 1 :end2 4))) (test-t (eql (mismatch '(a b c d e) '(c d)) 0)) (test-t (eql (mismatch '(a b c d e) '(c d) :start1 2) 4)) (test-t (eql (mismatch '(a b c d e) '(c d) :start1 2 :end1 3) 3)) (test-t (eql (mismatch '(a b c d e) '(c d) :start1 2 :start2 1) 2)) (test-t (eql (mismatch '(a b c d e) '(c d) :start1 3 :start2 1) 4)) (test-t (eql (mismatch '(a b c d e) '(c d) :start1 2 :end2 1) 3)) (test-t (null (mismatch '(a b c d) '(a b c d) :start1 1 :end1 2 :start2 1 :end2 2))) (test-t (null (mismatch '(a b c d) '(a b c d) :start1 1 :end1 3 :start2 1 :end2 3))) (test-t (null (mismatch '(a b c d) '(a b c d) :start1 1 :end1 4 :start2 1 :end2 4))) (test-t (eql (mismatch '(a b c d) '(a b c d) :start1 1 :end1 nil :start2 1 :end2 1) 1)) (test-t (eql (mismatch '(a b c d) '(a b c d) :start1 1 :end1 nil :start2 1 :end2 2) 2)) (test-t (eql (mismatch '(a b c d) '(a b c d) :start1 1 :end1 nil :start2 1 :end2 3) 3)) (test-t (null (mismatch '(a b c d) '(a b c d) :start1 1 :end1 nil :start2 1 :end2 4))) (test-t (eql (mismatch '(a b c d) '(a b c d) :start1 1 :end1 1 :start2 1) 1)) (test-t (eql (mismatch '(a b c d) '(a b c d) :start1 1 :end1 2 :start2 1) 2)) (test-t (eql (mismatch '(a b c d) '(a b c d) :start1 1 :end1 3 :start2 1) 3)) (test-t (null (mismatch '(a b c d) '(a b c d) :start1 1 :end1 4 :start2 1))) (test-t (null (mismatch '(a b c) '(a b c) :from-end t))) (test-t (eql (mismatch '(a b c d) '(a b c) :from-end t) 4)) (test-t (eql (mismatch '(a b c) '(c) :from-end t) 2)) (test-t (eql (mismatch '(a b c) '(z a b c) :from-end t) 0)) (test-t (eql (mismatch '(a b c) '(x y z a b c) :from-end t) 0)) (test-t (eql (mismatch '(x y z a b c) '(a b c) :from-end t) 3)) (test-t (eql (mismatch '(x y z a b c) '(a b c) :end1 3 :from-end t) 3)) (test-t (eql (mismatch '(x y z a b c) '(a b c) :end1 5 :from-end t) 5)) (test-t (eql (mismatch '(x y z a b c x y z) '(a b c) :end1 6 :from-end t) 3)) (test-t (eql (mismatch '(x y z a b c x y z) '(a b c) :start1 2 :end1 6 :from-end t) 3)) (test-t (eql (mismatch '(x y z a b c x y z) '(a b c) :from-end t :start1 2 :end1 5 :start2 1 :end2 2 ) 4)) (test-t (eql (mismatch '(x y z a b c x y z) '(a b c) :start1 2 :end1 5 :start2 1 :end2 2 ) 2)) (test-t (eql (mismatch '((a) (b) (c)) '((a) (b) (c))) 0)) (test-t (null (mismatch '((a) (b) (c)) '((a) (b) (c)) :key car))) (test-t (null (mismatch '((a) (b) (c)) '((a) (b) (c)) :test equal))) (test-t (eql (mismatch '(#(a) #(b) #(c)) '(#(a) #(b) #(c))) 0)) (test-t (null (mismatch '(#(a) #(b) #(c)) '(#(a) #(b) #(c)) :test equalp))) (test-t (eql (mismatch '((a) (b) (c) (d)) '((a) (b) (c)) :key car) 3)) (test-t (eql (mismatch '((a) (b) (c)) '((a) (b) (c) (d)) :key car) 3)) (test-t (eql (mismatch '(#\a #\b #\c) '(#\A #\B #\C)) 0)) (test-t (null (mismatch '(#\a #\b #\c) '(#\A #\B #\C) :key char-upcase))) (test-t (null (mismatch '(#\a #\b #\c) '(#\A #\B #\C) :key char-downcase))) (test-t (null (mismatch '(#\a #\b #\c) '(#\A #\B #\C) :key char-upcase :start1 1 :end1 2 :start2 1 :end2 2))) (test-t (null (mismatch '(#\a #\b #\c) '(#\A #\B #\C) :key char-upcase :start1 2 :start2 2))) (test-t (eql (mismatch '((a b c) (b c d) (d e f)) '((b b c) (c c d) (e e f))) 0)) (test-t (eql (mismatch '((a b c) (b c d) (d e f)) '((b b c) (c c d) (e e f)) :key cdr) 0)) (test-t (null (mismatch '((a b c) (b c d) (d e f)) '((b b c) (c c d) (e e f)) :key cdr :test equal))) (test-t (eql (mismatch '((a b c) (b c d) (d e f) (e f g)) '((b b c) (c c d) (e e f)) :key cdr :test equal) 3)) (test-t (eql (mismatch '((a b c) (b c d) (d e f) (e f g)) '((b b c) (c c d) (e e f)) :key cdr :test equal :from-end t) 4)) (test-t (eql (mismatch '((a a a) (a b c) (b c d) (d e f)) '((b b c) (c c d) (e e f)) :key cdr :test equal :from-end t) 1)) (test-t (null (mismatch '((a a a) (a b c) (b c d) (d e f) (e f g)) '((b b c) (c c d) (e e f)) :key cdr :test equal :from-end t :start1 1 :end1 4))) (test-t (eql (mismatch '((a a a) (a b c) (b c d) (d e f) (e f g)) '((b b c) (c c d) (e e f)) :key cdr :test equal :from-end t :start1 1) 5)) (test-t (eql (mismatch '((a a a) (a b c) (b c d) (d e f) (e f g)) '((b b c) (c c d) (e e f)) :key cdr :test equal :from-end t :end1 3 :start2 1 :end2 2) 2)) (test-t (null (mismatch #() ()))) (test-t (eql (mismatch #(a b c) '(x y z)) 0)) (test-t (eql (mismatch #() '(x y z)) 0)) (test-t (eql (mismatch #(x y z) ()) 0)) (test-t (null (mismatch #(a) '(a)))) (test-t (eql (mismatch #(a b c x y z) '(a b c)) 3)) (test-t (null (mismatch #(a b c) '(a b c)))) (test-t (eql (mismatch #(a b c d e f) '(a b c)) 3)) (test-t (eql (mismatch #(a b c) '(a b c d e f)) 3)) (test-t (eql (mismatch #(a b c) '(a b x)) 2)) (test-t (eql (mismatch #(a b c) '(a x c)) 1)) (test-t (eql (mismatch #(a b c) '(x b c)) 0)) (test-t (eql (mismatch #(x y z a b c x y z) '(a b c) :start1 3) 6)) (test-t (eql (mismatch #(x y z a b c x y z) '(a b c) :start1 3 :end1 nil) 6)) (test-t (eql (mismatch #(x y z a b c x y z) '(a b c) :start1 3 :end1 4) 4)) (test-t (eql (mismatch #(x y z a b c x y z) '(a b c) :start1 3 :end1 3) 3)) (test-t (null (mismatch #(x y z) () :start1 0 :end1 0))) (test-t (null (mismatch #(x y z) () :start1 1 :end1 1))) (test-t (null (mismatch #(x y z) () :start1 2 :end1 2))) (test-t (null (mismatch #(x y z) () :start1 3 :end1 3))) (test-t (eql (mismatch #(x y z) '(a b c) :start1 0 :end1 0) 0)) (test-t (eql (mismatch #(x y z) '(a b c) :start1 1 :end1 1) 1)) (test-t (eql (mismatch #(x y z) '(a b c) :start1 2 :end1 2) 2)) (test-t (eql (mismatch #(x y z) '(a b c) :start1 3 :end1 3) 3)) (test-t (eql (mismatch #(x y z) '(x y z) :start1 0 :end1 1) 1)) (test-t (eql (mismatch #(x y z) '(x y z) :start1 0 :end1 2) 2)) (test-t (eql (mismatch #(x y z) '(x y z Z) :start1 0 :end1 3) 3)) (test-t (null (mismatch #(x y z) '(x y z) :start1 0 :end1 3))) (test-t (eql (mismatch #(a b c x y z) '(x y z a b c)) 0)) (test-t (eql (mismatch #(a b c x y z) '(x y z a b c) :start1 3) 6)) (test-t (eql (mismatch #(a b c x y z a b c) '(x y z a b c x y z) :start1 3) 9)) (test-t (eql (mismatch #(a b c x y z a b c) '(x y z a b c x y z) :start1 6) 6)) (test-t (eql (mismatch #(a b c x y z a b c) '(x y z a b c x y z) :start1 6 :start2 3) 9)) (test-t (eql (mismatch #(a b c x y z a b c) '(x y z a b c x y z) :start1 0 :start2 3) 6)) (test-t (eql (mismatch #(a b c) '(a b c x y z)) 3)) (test-t (eql (mismatch #(a b c) '(x a b c y z)) 0)) (test-t (eql (mismatch #(a b c) '(x a b c y z) :start2 1) 3)) (test-t (eql (mismatch #(a b c) '(x a b c y z) :start2 1 :end2 nil) 3)) (test-t (null (mismatch #(a b c) '(x a b c y z) :start2 1 :end2 4))) (test-t (eql (mismatch #(a b c d e) '(c d)) 0)) (test-t (eql (mismatch #(a b c d e) '(c d) :start1 2) 4)) (test-t (eql (mismatch #(a b c d e) '(c d) :start1 2 :end1 3) 3)) (test-t (eql (mismatch #(a b c d e) '(c d) :start1 2 :start2 1) 2)) (test-t (eql (mismatch #(a b c d e) '(c d) :start1 3 :start2 1) 4)) (test-t (eql (mismatch #(a b c d e) '(c d) :start1 2 :end2 1) 3)) (test-t (null (mismatch #(a b c d) '(a b c d) :start1 1 :end1 2 :start2 1 :end2 2))) (test-t (null (mismatch #(a b c d) '(a b c d) :start1 1 :end1 3 :start2 1 :end2 3))) (test-t (null (mismatch #(a b c d) '(a b c d) :start1 1 :end1 4 :start2 1 :end2 4))) (test-t (eql (mismatch #(a b c d) '(a b c d) :start1 1 :end1 nil :start2 1 :end2 1) 1)) (test-t (eql (mismatch #(a b c d) '(a b c d) :start1 1 :end1 nil :start2 1 :end2 2) 2)) (test-t (eql (mismatch #(a b c d) '(a b c d) :start1 1 :end1 nil :start2 1 :end2 3) 3)) (test-t (null (mismatch #(a b c d) '(a b c d) :start1 1 :end1 nil :start2 1 :end2 4))) (test-t (eql (mismatch #(a b c d) '(a b c d) :start1 1 :end1 1 :start2 1) 1)) (test-t (eql (mismatch #(a b c d) '(a b c d) :start1 1 :end1 2 :start2 1) 2)) (test-t (eql (mismatch #(a b c d) '(a b c d) :start1 1 :end1 3 :start2 1) 3)) (test-t (null (mismatch #(a b c d) '(a b c d) :start1 1 :end1 4 :start2 1))) (test-t (null (mismatch #(a b c) '(a b c) :from-end t))) (test-t (eql (mismatch #(a b c d) '(a b c) :from-end t) 4)) (test-t (eql (mismatch #(a b c) '(c) :from-end t) 2)) (test-t (eql (mismatch #(a b c) '(z a b c) :from-end t) 0)) (test-t (eql (mismatch #(a b c) '(x y z a b c) :from-end t) 0)) (test-t (eql (mismatch #(x y z a b c) '(a b c) :from-end t) 3)) (test-t (eql (mismatch #(x y z a b c) '(a b c) :end1 3 :from-end t) 3)) (test-t (eql (mismatch #(x y z a b c) '(a b c) :end1 5 :from-end t) 5)) (test-t (eql (mismatch #(x y z a b c x y z) '(a b c) :end1 6 :from-end t) 3)) (test-t (eql (mismatch #(x y z a b c x y z) '(a b c) :start1 2 :end1 6 :from-end t) 3)) (test-t (eql (mismatch #(x y z a b c x y z) '(a b c) :from-end t :start1 2 :end1 5 :start2 1 :end2 2 ) 4)) (test-t (eql (mismatch #(x y z a b c x y z) '(a b c) :start1 2 :end1 5 :start2 1 :end2 2 ) 2)) (test-t (eql (mismatch #((a) (b) (c)) '((a) (b) (c))) 0)) (test-t (null (mismatch #((a) (b) (c)) '((a) (b) (c)) :key car))) (test-t (null (mismatch #((a) (b) (c)) '((a) (b) (c)) :test equal))) (test-t (eql (mismatch #(#(a) #(b) #(c)) '(#(a) #(b) #(c))) 0)) (test-t (null (mismatch #(#(a) #(b) #(c)) '(#(a) #(b) #(c)) :test equalp))) (test-t (eql (mismatch #((a) (b) (c) (d)) '((a) (b) (c)) :key car) 3)) (test-t (eql (mismatch #((a) (b) (c)) '((a) (b) (c) (d)) :key car) 3)) (test-t (eql (mismatch #(#\a #\b #\c) '(#\A #\B #\C)) 0)) (test-t (null (mismatch #(#\a #\b #\c) '(#\A #\B #\C) :key char-upcase))) (test-t (null (mismatch #(#\a #\b #\c) '(#\A #\B #\C) :key char-downcase))) (test-t (null (mismatch #(#\a #\b #\c) '(#\A #\B #\C) :key char-upcase :start1 1 :end1 2 :start2 1 :end2 2))) (test-t (null (mismatch #(#\a #\b #\c) '(#\A #\B #\C) :key char-upcase :start1 2 :start2 2))) (test-t (eql (mismatch #((a b c) (b c d) (d e f)) '((b b c) (c c d) (e e f))) 0)) (test-t (eql (mismatch #((a b c) (b c d) (d e f)) '((b b c) (c c d) (e e f)) :key cdr) 0)) (test-t (null (mismatch #((a b c) (b c d) (d e f)) '((b b c) (c c d) (e e f)) :key cdr :test equal))) (test-t (eql (mismatch #((a b c) (b c d) (d e f) (e f g)) '((b b c) (c c d) (e e f)) :key cdr :test equal) 3)) (test-t (eql (mismatch #((a b c) (b c d) (d e f) (e f g)) '((b b c) (c c d) (e e f)) :key cdr :test equal :from-end t) 4)) (test-t (eql (mismatch #((a a a) (a b c) (b c d) (d e f)) '((b b c) (c c d) (e e f)) :key cdr :test equal :from-end t) 1)) (test-t (null (mismatch #((a a a) (a b c) (b c d) (d e f) (e f g)) '((b b c) (c c d) (e e f)) :key cdr :test equal :from-end t :start1 1 :end1 4))) (test-t (eql (mismatch #((a a a) (a b c) (b c d) (d e f) (e f g)) '((b b c) (c c d) (e e f)) :key cdr :test equal :from-end t :start1 1) 5)) (test-t (eql (mismatch #((a a a) (a b c) (b c d) (d e f) (e f g)) '((b b c) (c c d) (e e f)) :key cdr :test equal :from-end t :end1 3 :start2 1 :end2 2) 2)) (test-t (null (mismatch () #()))) (test-t (eql (mismatch '(a b c) #(x y z)) 0)) (test-t (eql (mismatch () #(x y z)) 0)) (test-t (eql (mismatch '(x y z) #()) 0)) (test-t (null (mismatch '(a) #(a)))) (test-t (eql (mismatch '(a b c x y z) #(a b c)) 3)) (test-t (null (mismatch '(a b c) #(a b c)))) (test-t (eql (mismatch '(a b c d e f) #(a b c)) 3)) (test-t (eql (mismatch '(a b c) #(a b c d e f)) 3)) (test-t (eql (mismatch '(a b c) #(a b x)) 2)) (test-t (eql (mismatch '(a b c) #(a x c)) 1)) (test-t (eql (mismatch '(a b c) #(x b c)) 0)) (test-t (eql (mismatch '(x y z a b c x y z) #(a b c) :start1 3) 6)) (test-t (eql (mismatch '(x y z a b c x y z) #(a b c) :start1 3 :end1 nil) 6)) (test-t (eql (mismatch '(x y z a b c x y z) #(a b c) :start1 3 :end1 4) 4)) (test-t (eql (mismatch '(x y z a b c x y z) #(a b c) :start1 3 :end1 3) 3)) (test-t (null (mismatch '(x y z) #() :start1 0 :end1 0))) (test-t (null (mismatch '(x y z) #() :start1 1 :end1 1))) (test-t (null (mismatch '(x y z) #() :start1 2 :end1 2))) (test-t (null (mismatch '(x y z) #() :start1 3 :end1 3))) (test-t (eql (mismatch '(x y z) #(a b c) :start1 0 :end1 0) 0)) (test-t (eql (mismatch '(x y z) #(a b c) :start1 1 :end1 1) 1)) (test-t (eql (mismatch '(x y z) #(a b c) :start1 2 :end1 2) 2)) (test-t (eql (mismatch '(x y z) #(a b c) :start1 3 :end1 3) 3)) (test-t (eql (mismatch '(x y z) #(x y z) :start1 0 :end1 1) 1)) (test-t (eql (mismatch '(x y z) #(x y z) :start1 0 :end1 2) 2)) (test-t (eql (mismatch '(x y z) #(x y z Z) :start1 0 :end1 3) 3)) (test-t (null (mismatch '(x y z) #(x y z) :start1 0 :end1 3))) (test-t (eql (mismatch '(a b c x y z) #(x y z a b c)) 0)) (test-t (eql (mismatch '(a b c x y z) #(x y z a b c) :start1 3) 6)) (test-t (eql (mismatch '(a b c x y z a b c) #(x y z a b c x y z) :start1 3) 9)) (test-t (eql (mismatch '(a b c x y z a b c) #(x y z a b c x y z) :start1 6) 6)) (test-t (eql (mismatch '(a b c x y z a b c) #(x y z a b c x y z) :start1 6 :start2 3) 9)) (test-t (eql (mismatch '(a b c x y z a b c) #(x y z a b c x y z) :start1 0 :start2 3) 6)) (test-t (eql (mismatch '(a b c) #(a b c x y z)) 3)) (test-t (eql (mismatch '(a b c) #(x a b c y z)) 0)) (test-t (eql (mismatch '(a b c) #(x a b c y z) :start2 1) 3)) (test-t (eql (mismatch '(a b c) #(x a b c y z) :start2 1 :end2 nil) 3)) (test-t (null (mismatch '(a b c) #(x a b c y z) :start2 1 :end2 4))) (test-t (eql (mismatch '(a b c d e) #(c d)) 0)) (test-t (eql (mismatch '(a b c d e) #(c d) :start1 2) 4)) (test-t (eql (mismatch '(a b c d e) #(c d) :start1 2 :end1 3) 3)) (test-t (eql (mismatch '(a b c d e) #(c d) :start1 2 :start2 1) 2)) (test-t (eql (mismatch '(a b c d e) #(c d) :start1 3 :start2 1) 4)) (test-t (eql (mismatch '(a b c d e) #(c d) :start1 2 :end2 1) 3)) (test-t (null (mismatch '(a b c d) #(a b c d) :start1 1 :end1 2 :start2 1 :end2 2))) (test-t (null (mismatch '(a b c d) #(a b c d) :start1 1 :end1 3 :start2 1 :end2 3))) (test-t (null (mismatch '(a b c d) #(a b c d) :start1 1 :end1 4 :start2 1 :end2 4))) (test-t (eql (mismatch '(a b c d) #(a b c d) :start1 1 :end1 nil :start2 1 :end2 1) 1)) (test-t (eql (mismatch '(a b c d) #(a b c d) :start1 1 :end1 nil :start2 1 :end2 2) 2)) (test-t (eql (mismatch '(a b c d) #(a b c d) :start1 1 :end1 nil :start2 1 :end2 3) 3)) (test-t (null (mismatch '(a b c d) #(a b c d) :start1 1 :end1 nil :start2 1 :end2 4))) (test-t (eql (mismatch '(a b c d) #(a b c d) :start1 1 :end1 1 :start2 1) 1)) (test-t (eql (mismatch '(a b c d) #(a b c d) :start1 1 :end1 2 :start2 1) 2)) (test-t (eql (mismatch '(a b c d) #(a b c d) :start1 1 :end1 3 :start2 1) 3)) (test-t (null (mismatch '(a b c d) #(a b c d) :start1 1 :end1 4 :start2 1))) (test-t (null (mismatch '(a b c) #(a b c) :from-end t))) (test-t (eql (mismatch '(a b c d) #(a b c) :from-end t) 4)) (test-t (eql (mismatch '(a b c) #(c) :from-end t) 2)) (test-t (eql (mismatch '(a b c) #(z a b c) :from-end t) 0)) (test-t (eql (mismatch '(a b c) #(x y z a b c) :from-end t) 0)) (test-t (eql (mismatch '(x y z a b c) #(a b c) :from-end t) 3)) (test-t (eql (mismatch '(x y z a b c) #(a b c) :end1 3 :from-end t) 3)) (test-t (eql (mismatch '(x y z a b c) #(a b c) :end1 5 :from-end t) 5)) (test-t (eql (mismatch '(x y z a b c x y z) #(a b c) :end1 6 :from-end t) 3)) (test-t (eql (mismatch '(x y z a b c x y z) #(a b c) :start1 2 :end1 6 :from-end t) 3)) (test-t (eql (mismatch '(x y z a b c x y z) #(a b c) :from-end t :start1 2 :end1 5 :start2 1 :end2 2 ) 4)) (test-t (eql (mismatch '(x y z a b c x y z) #(a b c) :start1 2 :end1 5 :start2 1 :end2 2 ) 2)) (test-t (eql (mismatch '((a) (b) (c)) #((a) (b) (c))) 0)) (test-t (null (mismatch '((a) (b) (c)) #((a) (b) (c)) :key car))) (test-t (null (mismatch '((a) (b) (c)) #((a) (b) (c)) :test equal))) (test-t (eql (mismatch '(#(a) #(b) #(c)) #(#(a) #(b) #(c))) 0)) (test-t (null (mismatch '(#(a) #(b) #(c)) #(#(a) #(b) #(c)) :test equalp))) (test-t (eql (mismatch '((a) (b) (c) (d)) #((a) (b) (c)) :key car) 3)) (test-t (eql (mismatch '((a) (b) (c)) #((a) (b) (c) (d)) :key car) 3)) (test-t (eql (mismatch '(#\a #\b #\c) #(#\A #\B #\C)) 0)) (test-t (null (mismatch '(#\a #\b #\c) #(#\A #\B #\C) :key char-upcase))) (test-t (null (mismatch '(#\a #\b #\c) #(#\A #\B #\C) :key char-downcase))) (test-t (null (mismatch '(#\a #\b #\c) #(#\A #\B #\C) :key char-upcase :start1 1 :end1 2 :start2 1 :end2 2))) (test-t (null (mismatch '(#\a #\b #\c) #(#\A #\B #\C) :key char-upcase :start1 2 :start2 2))) (test-t (eql (mismatch '((a b c) (b c d) (d e f)) #((b b c) (c c d) (e e f))) 0)) (test-t (eql (mismatch '((a b c) (b c d) (d e f)) #((b b c) (c c d) (e e f)) :key cdr) 0)) (test-t (null (mismatch '((a b c) (b c d) (d e f)) #((b b c) (c c d) (e e f)) :key cdr :test equal))) (test-t (eql (mismatch '((a b c) (b c d) (d e f) (e f g)) #((b b c) (c c d) (e e f)) :key cdr :test equal) 3)) (test-t (eql (mismatch '((a b c) (b c d) (d e f) (e f g)) #((b b c) (c c d) (e e f)) :key cdr :test equal :from-end t) 4)) (test-t (eql (mismatch '((a a a) (a b c) (b c d) (d e f)) #((b b c) (c c d) (e e f)) :key cdr :test equal :from-end t) 1)) (test-t (null (mismatch '((a a a) (a b c) (b c d) (d e f) (e f g)) #((b b c) (c c d) (e e f)) :key cdr :test equal :from-end t :start1 1 :end1 4))) (test-t (eql (mismatch '((a a a) (a b c) (b c d) (d e f) (e f g)) #((b b c) (c c d) (e e f)) :key cdr :test equal :from-end t :start1 1) 5)) (test-t (eql (mismatch '((a a a) (a b c) (b c d) (d e f) (e f g)) #((b b c) (c c d) (e e f)) :key cdr :test equal :from-end t :end1 3 :start2 1 :end2 2) 2)) (test-t (null (mismatch #() #()))) (test-t (eql (mismatch #(a b c) #(x y z)) 0)) (test-t (eql (mismatch #() #(x y z)) 0)) (test-t (eql (mismatch #(x y z) #()) 0)) (test-t (null (mismatch #(a) #(a)))) (test-t (eql (mismatch #(a b c x y z) #(a b c)) 3)) (test-t (null (mismatch #(a b c) #(a b c)))) (test-t (eql (mismatch #(a b c d e f) #(a b c)) 3)) (test-t (eql (mismatch #(a b c) #(a b c d e f)) 3)) (test-t (eql (mismatch #(a b c) #(a b x)) 2)) (test-t (eql (mismatch #(a b c) #(a x c)) 1)) (test-t (eql (mismatch #(a b c) #(x b c)) 0)) (test-t (eql (mismatch #(x y z a b c x y z) #(a b c) :start1 3) 6)) (test-t (eql (mismatch #(x y z a b c x y z) #(a b c) :start1 3 :end1 nil) 6)) (test-t (eql (mismatch #(x y z a b c x y z) #(a b c) :start1 3 :end1 4) 4)) (test-t (eql (mismatch #(x y z a b c x y z) #(a b c) :start1 3 :end1 3) 3)) (test-t (null (mismatch #(x y z) #() :start1 0 :end1 0))) (test-t (null (mismatch #(x y z) #() :start1 1 :end1 1))) (test-t (null (mismatch #(x y z) #() :start1 2 :end1 2))) (test-t (null (mismatch #(x y z) #() :start1 3 :end1 3))) (test-t (eql (mismatch #(x y z) #(a b c) :start1 0 :end1 0) 0)) (test-t (eql (mismatch #(x y z) #(a b c) :start1 1 :end1 1) 1)) (test-t (eql (mismatch #(x y z) #(a b c) :start1 2 :end1 2) 2)) (test-t (eql (mismatch #(x y z) #(a b c) :start1 3 :end1 3) 3)) (test-t (eql (mismatch #(x y z) #(x y z) :start1 0 :end1 1) 1)) (test-t (eql (mismatch #(x y z) #(x y z) :start1 0 :end1 2) 2)) (test-t (eql (mismatch #(x y z) #(x y z Z) :start1 0 :end1 3) 3)) (test-t (null (mismatch #(x y z) #(x y z) :start1 0 :end1 3))) (test-t (eql (mismatch #(a b c x y z) #(x y z a b c)) 0)) (test-t (eql (mismatch #(a b c x y z) #(x y z a b c) :start1 3) 6)) (test-t (eql (mismatch #(a b c x y z a b c) #(x y z a b c x y z) :start1 3) 9)) (test-t (eql (mismatch #(a b c x y z a b c) #(x y z a b c x y z) :start1 6) 6)) (test-t (eql (mismatch #(a b c x y z a b c) #(x y z a b c x y z) :start1 6 :start2 3) 9)) (test-t (eql (mismatch #(a b c x y z a b c) #(x y z a b c x y z) :start1 0 :start2 3) 6)) (test-t (eql (mismatch #(a b c) #(a b c x y z)) 3)) (test-t (eql (mismatch #(a b c) #(x a b c y z)) 0)) (test-t (eql (mismatch #(a b c) #(x a b c y z) :start2 1) 3)) (test-t (eql (mismatch #(a b c) #(x a b c y z) :start2 1 :end2 nil) 3)) (test-t (null (mismatch #(a b c) #(x a b c y z) :start2 1 :end2 4))) (test-t (eql (mismatch #(a b c d e) #(c d)) 0)) (test-t (eql (mismatch #(a b c d e) #(c d) :start1 2) 4)) (test-t (eql (mismatch #(a b c d e) #(c d) :start1 2 :end1 3) 3)) (test-t (eql (mismatch #(a b c d e) #(c d) :start1 2 :start2 1) 2)) (test-t (eql (mismatch #(a b c d e) #(c d) :start1 3 :start2 1) 4)) (test-t (eql (mismatch #(a b c d e) #(c d) :start1 2 :end2 1) 3)) (test-t (null (mismatch #(a b c d) #(a b c d) :start1 1 :end1 2 :start2 1 :end2 2))) (test-t (null (mismatch #(a b c d) #(a b c d) :start1 1 :end1 3 :start2 1 :end2 3))) (test-t (null (mismatch #(a b c d) #(a b c d) :start1 1 :end1 4 :start2 1 :end2 4))) (test-t (eql (mismatch #(a b c d) #(a b c d) :start1 1 :end1 nil :start2 1 :end2 1) 1)) (test-t (eql (mismatch #(a b c d) #(a b c d) :start1 1 :end1 nil :start2 1 :end2 2) 2)) (test-t (eql (mismatch #(a b c d) #(a b c d) :start1 1 :end1 nil :start2 1 :end2 3) 3)) (test-t (null (mismatch #(a b c d) #(a b c d) :start1 1 :end1 nil :start2 1 :end2 4))) (test-t (eql (mismatch #(a b c d) #(a b c d) :start1 1 :end1 1 :start2 1) 1)) (test-t (eql (mismatch #(a b c d) #(a b c d) :start1 1 :end1 2 :start2 1) 2)) (test-t (eql (mismatch #(a b c d) #(a b c d) :start1 1 :end1 3 :start2 1) 3)) (test-t (null (mismatch #(a b c d) #(a b c d) :start1 1 :end1 4 :start2 1))) (test-t (null (mismatch #(a b c) #(a b c) :from-end t))) (test-t (eql (mismatch #(a b c d) #(a b c) :from-end t) 4)) (test-t (eql (mismatch #(a b c) #(c) :from-end t) 2)) (test-t (eql (mismatch #(a b c) #(z a b c) :from-end t) 0)) (test-t (eql (mismatch #(a b c) #(x y z a b c) :from-end t) 0)) (test-t (eql (mismatch #(x y z a b c) #(a b c) :from-end t) 3)) (test-t (eql (mismatch #(x y z a b c) #(a b c) :end1 3 :from-end t) 3)) (test-t (eql (mismatch #(x y z a b c) #(a b c) :end1 5 :from-end t) 5)) (test-t (eql (mismatch #(x y z a b c x y z) #(a b c) :end1 6 :from-end t) 3)) (test-t (eql (mismatch #(x y z a b c x y z) #(a b c) :start1 2 :end1 6 :from-end t) 3)) (test-t (eql (mismatch #(x y z a b c x y z) #(a b c) :from-end t :start1 2 :end1 5 :start2 1 :end2 2 ) 4)) (test-t (eql (mismatch #(x y z a b c x y z) #(a b c) :start1 2 :end1 5 :start2 1 :end2 2 ) 2)) (test-t (eql (mismatch #((a) (b) (c)) #((a) (b) (c))) 0)) (test-t (null (mismatch #((a) (b) (c)) #((a) (b) (c)) :key car))) (test-t (null (mismatch #((a) (b) (c)) #((a) (b) (c)) :test equal))) (test-t (eql (mismatch #(#(a) #(b) #(c)) #(#(a) #(b) #(c))) 0)) (test-t (null (mismatch #(#(a) #(b) #(c)) #(#(a) #(b) #(c)) :test equalp))) (test-t (eql (mismatch #((a) (b) (c) (d)) #((a) (b) (c)) :key car) 3)) (test-t (eql (mismatch #((a) (b) (c)) #((a) (b) (c) (d)) :key car) 3)) (test-t (eql (mismatch #(#\a #\b #\c) #(#\A #\B #\C)) 0)) (test-t (null (mismatch #(#\a #\b #\c) #(#\A #\B #\C) :key char-upcase))) (test-t (null (mismatch #(#\a #\b #\c) #(#\A #\B #\C) :key char-downcase))) (test-t (null (mismatch #(#\a #\b #\c) #(#\A #\B #\C) :key char-upcase :start1 1 :end1 2 :start2 1 :end2 2))) (test-t (null (mismatch #(#\a #\b #\c) #(#\A #\B #\C) :key char-upcase :start1 2 :start2 2))) (test-t (eql (mismatch #((a b c) (b c d) (d e f)) #((b b c) (c c d) (e e f))) 0)) (test-t (eql (mismatch #((a b c) (b c d) (d e f)) #((b b c) (c c d) (e e f)) :key cdr) 0)) (test-t (null (mismatch #((a b c) (b c d) (d e f)) #((b b c) (c c d) (e e f)) :key cdr :test equal))) (test-t (eql (mismatch #((a b c) (b c d) (d e f) (e f g)) #((b b c) (c c d) (e e f)) :key cdr :test equal) 3)) (test-t (eql (mismatch #((a b c) (b c d) (d e f) (e f g)) #((b b c) (c c d) (e e f)) :key cdr :test equal :from-end t) 4)) (test-t (eql (mismatch #((a a a) (a b c) (b c d) (d e f)) #((b b c) (c c d) (e e f)) :key cdr :test equal :from-end t) 1)) (test-t (null (mismatch #((a a a) (a b c) (b c d) (d e f) (e f g)) #((b b c) (c c d) (e e f)) :key cdr :test equal :from-end t :start1 1 :end1 4))) (test-t (eql (mismatch #((a a a) (a b c) (b c d) (d e f) (e f g)) #((b b c) (c c d) (e e f)) :key cdr :test equal :from-end t :start1 1) 5)) (test-t (eql (mismatch #((a a a) (a b c) (b c d) (d e f) (e f g)) #((b b c) (c c d) (e e f)) :key cdr :test equal :from-end t :end1 3 :start2 1 :end2 2) 2)) (test-t (eql (mismatch "abc" "xyz") 0)) (test-t (null (mismatch "" ""))) (test-t (null (mismatch "a" "a"))) (test-t (null (mismatch "abc" "abc"))) (test-t (null (mismatch "abc" "ABC" :key char-downcase))) (test-t (null (mismatch "abc" "ABC" :test char-equal))) (test-t (eql (mismatch "abcde" "abc") 3)) (test-t (eql (mismatch "abc" "abcde") 3)) (test-t (eql (mismatch "abc" "abxyz") 2)) (test-t (eql (mismatch "abcde" "abx") 2)) (test-t (null (mismatch "abc" "abc" :from-end t))) (test-t (eql (mismatch "abcxyz" "xyzxyz" :from-end t) 3)) (test-t (eql (mismatch "abcxyz" "xyz" :from-end t) 3)) (test-t (eql (mismatch "xyz" "abcxyz" :from-end t) 0)) (test-t (eql (mismatch "ayz" "abcxyz" :from-end t) 1)) (test-t (null (mismatch "abc" "xyz" :test char<))) (test-t (eql (mismatch "abc" "xyz" :test char>) 0)) (test-t (eql (mismatch "abcxyz" "abcdefg") 3)) (test-t (eql (mismatch "1xyz" "22xyz" :from-end t) 1)) ) ;; -------- defstruct (defmacro defstruct (struct-name . fields) (let* ((name (if (list? struct-name) (car struct-name) struct-name)) (sname (if (string? name) name (symbol->string name))) (fsname (if (list? struct-name) (let ((cname (assoc :conc-name (cdr struct-name)))) (if cname (symbol->string (cadr cname)) sname)) sname)) (make-name (if (list? struct-name) (let ((cname (assoc :constructor (cdr struct-name)))) (if cname (cadr cname) (string->symbol (string-append "make-" sname)))) (string->symbol (string-append "make-" sname)))) (copy-name (if (list? struct-name) (let ((cname (assoc :copier (cdr struct-name)))) (if cname (cadr cname) (string->symbol (string-append "copy-" sname)))) (string->symbol (string-append "copy-" sname)))) (field-names (map (lambda (n) (symbol->string (if (list? n) (car n) n))) fields)) (field-types (map (lambda (field) (if (list? field) (apply (lambda* (val type read-only) type) (cdr field)) #f)) fields)) (field-read-onlys (map (lambda (field) (if (list? field) (apply (lambda* (val type read-only) read-only) (cdr field)) #f)) fields))) `(begin (define ,(string->symbol (string-append sname "?")) (lambda (obj) (and (vector? obj) (eq? (obj 0) ',(string->symbol sname))))) (define* (,make-name ,@(map (lambda (n) (if (and (list? n) (>= (length n) 2)) (list (car n) (cadr n)) (list n #f))) fields)) (vector ',(string->symbol sname) ,@(map string->symbol field-names))) (define ,copy-name copy) ,@(map (let ((ctr 1)) (lambda (n type read-only) (let ((val (if read-only `(define ,(string->symbol (string-append fsname "-" n)) (lambda (arg) (arg ,ctr))) `(define ,(string->symbol (string-append fsname "-" n)) (dilambda (lambda (arg) (arg ,ctr)) (lambda (arg val) (set! (arg ,ctr) val))))))) (set! ctr (+ 1 ctr)) val))) field-names field-types field-read-onlys)))) ;; not yet implemented: :print-function :include :named :type :initial-offset ;; also the explicit constructor business (define-macro (enum . args) ; (enum zero one two) `(begin ,@(let ((names ())) (do ((arg args (cdr arg)) (i 0 (+ i 1))) ((null? arg) names) (set! names (cons `(define ,(car arg) ,i) names)))))) (define-macro (let*-values vals . body) (let ((args ()) (exprs ())) (for-each (lambda (arg+expr) (set! args (cons (car arg+expr) args)) (set! exprs (cons (cadr arg+expr) exprs))) vals) (let ((form `((lambda ,(car args) ,@body) ,(car exprs)))) (if (not (null? (cdr args))) (for-each (lambda (arg expr) (set! form `((lambda ,arg ,form) ,expr))) (cdr args) (cdr exprs))) form))) (let () ;; this is the nbody computer shootout benchmark taken from mzscheme (define +days-per-year+ 365.24) (define +solar-mass+ (* 4 pi pi)) (defstruct body x y z vx vy vz mass) (define *sun* (make-body 0.0 0.0 0.0 0.0 0.0 0.0 +solar-mass+)) (define *jupiter* (make-body 4.84143144246472090 -1.16032004402742839 -1.03622044471123109e-1 (* 1.66007664274403694e-3 +days-per-year+) (* 7.69901118419740425e-3 +days-per-year+) (* -6.90460016972063023e-5 +days-per-year+) (* 9.54791938424326609e-4 +solar-mass+))) (define *saturn* (make-body 8.34336671824457987 4.12479856412430479 -4.03523417114321381e-1 (* -2.76742510726862411e-3 +days-per-year+) (* 4.99852801234917238e-3 +days-per-year+) (* 2.30417297573763929e-5 +days-per-year+) (* 2.85885980666130812e-4 +solar-mass+))) (define *uranus* (make-body 1.28943695621391310e1 -1.51111514016986312e1 -2.23307578892655734e-1 (* 2.96460137564761618e-03 +days-per-year+) (* 2.37847173959480950e-03 +days-per-year+) (* -2.96589568540237556e-05 +days-per-year+) (* 4.36624404335156298e-05 +solar-mass+))) (define *neptune* (make-body 1.53796971148509165e+01 -2.59193146099879641e+01 1.79258772950371181e-01 (* 2.68067772490389322e-03 +days-per-year+) (* 1.62824170038242295e-03 +days-per-year+) (* -9.51592254519715870e-05 +days-per-year+) (* 5.15138902046611451e-05 +solar-mass+))) (define (offset-momentum system) (let loop-i ((i system) (px 0.0) (py 0.0) (pz 0.0)) (if (null? i) (begin (set! (body-vx (car system)) (/ (- px) +solar-mass+)) (set! (body-vy (car system)) (/ (- py) +solar-mass+)) (set! (body-vz (car system)) (/ (- pz) +solar-mass+))) (loop-i (cdr i) (+ px (* (body-vx (car i)) (body-mass (car i)))) (+ py (* (body-vy (car i)) (body-mass (car i)))) (+ pz (* (body-vz (car i)) (body-mass (car i)))))))) (define (energy system) (let loop-o ((o system) (e 0.0)) (if (null? o) e (let ((e (+ e (* 0.5 (body-mass (car o)) (+ (* (body-vx (car o)) (body-vx (car o))) (* (body-vy (car o)) (body-vy (car o))) (* (body-vz (car o)) (body-vz (car o)))))))) (let loop-i ((i (cdr o)) (e e)) (if (null? i) (loop-o (cdr o) e) (let* ((dx (- (body-x (car o)) (body-x (car i)))) (dy (- (body-y (car o)) (body-y (car i)))) (dz (- (body-z (car o)) (body-z (car i)))) (distance (sqrt (+ (* dx dx) (* dy dy) (* dz dz))))) (let ((e (- e (/ (* (body-mass (car o)) (body-mass (car i))) distance)))) (loop-i (cdr i) e))))))))) (define (advance system dt) (let loop-o ((o system)) (unless (null? o) (let loop-i ((i (cdr o))) (unless (null? i) (let* ((o1 (car o)) (i1 (car i)) (dx (- (body-x o1) (body-x i1))) (dy (- (body-y o1) (body-y i1))) (dz (- (body-z o1) (body-z i1))) (distance (sqrt (+ (* dx dx) (* dy dy) (* dz dz)))) (mag (/ dt (* distance distance distance))) (dxmag (* dx mag)) (dymag (* dy mag)) (dzmag (* dz mag)) (om (body-mass o1)) (im (body-mass i1))) (set! (body-vx o1) (- (body-vx o1) (* dxmag im))) (set! (body-vy o1) (- (body-vy o1) (* dymag im))) (set! (body-vz o1) (- (body-vz o1) (* dzmag im))) (set! (body-vx i1) (+ (body-vx i1) (* dxmag om))) (set! (body-vy i1) (+ (body-vy i1) (* dymag om))) (set! (body-vz i1) (+ (body-vz i1) (* dzmag om))) (loop-i (cdr i))))) (loop-o (cdr o)))) (let loop-o ((o system)) (unless (null? o) (let ((o1 (car o))) (set! (body-x o1) (+ (body-x o1) (* dt (body-vx o1)))) (set! (body-y o1) (+ (body-y o1) (* dt (body-vy o1)))) (set! (body-z o1) (+ (body-z o1) (* dt (body-vz o1)))) (loop-o (cdr o)))))) ;; (define (nbody-test) (let ((n 10) ;(n 1000) ; (command-line #:args (n) (string->number n))) (system (list *sun* *jupiter* *saturn* *uranus* *neptune*))) (offset-momentum system) (let ((initial (energy system))) (do ((i 1 (+ i 1))) ((< n i)) (advance system 0.01)) (let ((final (energy system))) (num-test initial -0.16907516382852) (num-test final -0.16908760523461) ;(list initial final))))) ; (-0.16907516382852 -0.16908760523461) )))) ;;; ---------------- ;;; some of these tests are taken (with modifications) from sacla which has ;;; the following copyright notice: ;;; ;; Copyright (C) 2002-2004, Yuji Minejima ;; ALL RIGHTS RESERVED. ;; ;; Redistribution and use in source and binary forms, with or without ;; modification, are permitted provided that the following conditions ;; are met: ;; ;; * Redistributions of source code must retain the above copyright ;; notice, this list of conditions and the following disclaimer. ;; * Redistributions in binary form must reproduce the above copyright ;; notice, this list of conditions and the following disclaimer in ;; the documentation and/or other materials provided with the ;; distribution. ;; ;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ;; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ;; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ;; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ;; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ;; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ;; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ;; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ;; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ;; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ;; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (test-t (equal 'a 'a)) (test-t (not (equal 'a 'b))) (test-t (equal 'abc 'abc)) (test-t (equal 1 1)) (test-t (equal 2 2)) (test-t (equal 0.1 0.1)) (test-t (equal 1/3 1/3)) (test-t (not (equal 0 1))) (test-t (not (equal 1 1.0))) (test-t (not (equal 1/3 1/4))) (test-t (equal #\a #\a)) (test-t (equal #\b #\b)) (test-t (not (equal #\b #\B))) (test-t (not (equal #\C #\c))) (test-t (equal '(0) '(0))) (test-t (equal '(0 #\a) '(0 #\a))) (test-t (equal '(0 #\a x) '(0 #\a x))) (test-t (equal '(0 #\a x (0)) '(0 #\a x (0)))) (test-t (eql (identity 101) 101)) (test-t (eq (identity 'x) 'x)) ;; chars (test-t (char= #\d #\d)) (test-t (not (char= #\A #\a))) (test-t (not (char= #\d #\x))) (test-t (not (char= #\d #\D))) (test-t (not (char/= #\d #\d))) (test-t (char/= #\d #\x)) (test-t (char/= #\d #\D)) (test-t (char= #\d #\d #\d #\d)) (test-t (not (char/= #\d #\d #\d #\d))) (test-t (not (char= #\d #\d #\x #\d))) (test-t (not (char/= #\d #\d #\x #\d))) (test-t (not (char= #\d #\y #\x #\c))) (test-t (char/= #\d #\y #\x #\c)) (test-t (not (char= #\d #\c #\d))) (test-t (not (char/= #\d #\c #\d))) (test-t (char< #\d #\x)) (test-t (char<= #\d #\x)) (test-t (not (char< #\d #\d))) (test-t (char<= #\d #\d)) (test-t (char< #\a #\e #\y #\z)) (test-t (char<= #\a #\e #\y #\z)) (test-t (not (char< #\a #\e #\e #\y))) (test-t (char<= #\a #\e #\e #\y)) (test-t (char> #\e #\d)) (test-t (char>= #\e #\d)) (test-t (char> #\d #\c #\b #\a)) (test-t (char>= #\d #\c #\b #\a)) (test-t (not (char> #\d #\d #\c #\a))) (test-t (char>= #\d #\d #\c #\a)) (test-t (not (char> #\e #\d #\b #\c #\a))) (test-t (not (char>= #\e #\d #\b #\c #\a))) (test-t (char-equal #\A #\a)) (test-t (char= #\a)) (test-t (char= #\a #\a)) (test-t (char= #\a #\a #\a)) (test-t (char= #\a #\a #\a #\a)) (test-t (char= #\a #\a #\a #\a #\a)) (test-t (char= #\a #\a #\a #\a #\a #\a)) (test-t (let ((c #\z)) (and (eq c c) (char= c c)))) (test-t (not (char= #\Z #\z))) (test-t (not (char= #\z #\z #\z #\a))) (test-t (not (char= #\a #\z #\z #\z #\a))) (test-t (not (char= #\z #\i #\z #\z))) (test-t (not (char= #\z #\z #\Z #\z))) (test-t (char/= #\a)) (test-t (char/= #\a #\b)) (test-t (char/= #\a #\b #\c)) (test-t (char/= #\a #\b #\c #\d)) (test-t (char/= #\a #\b #\c #\d #\e)) (test-t (char/= #\a #\b #\c #\d #\e #\f)) (test-t (let ((c #\z)) (and (eq c c) (not (char/= c c))))) (test-t (char/= #\Z #\z)) (test-t (not (char/= #\z #\z #\z #\a))) (test-t (not (char= #\a #\z #\z #\z #\a))) (test-t (not (char= #\z #\i #\z #\z))) (test-t (not (char= #\z #\z #\Z #\z))) (test-t (not (char/= #\a #\a #\b #\c))) (test-t (not (char/= #\a #\b #\a #\c))) (test-t (not (char/= #\a #\b #\c #\a))) (test-t (char< #\a)) (test-t (char< #\a #\z)) (test-t (char< #\a #\b #\c #\d #\e #\f #\g #\h #\i #\j #\k #\l #\m #\n #\o #\p #\q #\r #\s #\t #\u #\v #\w #\x #\y #\z)) (test-t (not (char< #\z #\y #\x #\w #\v #\u #\t #\s #\r #\q #\p #\o #\n #\m #\l #\k #\j #\i #\h #\g #\f #\e #\d #\c #\b #\a))) (test-t (char< #\A #\B #\C #\D #\E #\F #\G #\H #\I #\J #\K #\L #\M #\N #\O #\P #\Q #\R #\S #\T #\U #\V #\W #\X #\Y #\Z)) (test-t (not (char< #\Z #\Y #\X #\W #\V #\U #\T #\S #\R #\Q #\P #\O #\N #\M #\L #\K #\J #\I #\H #\G #\F #\E #\D #\C #\B #\A))) (test-t (char< #\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9)) (test-t (not (char< #\9 #\8 #\7 #\6 #\5 #\4 #\3 #\2 #\1 #\0))) (test-t (or (char< #\9 #\A) (char< #\Z #\0))) (test-t (or (char< #\9 #\a) (char< #\z #\0))) (test-t (not (char< #\a #\a #\b #\c))) (test-t (not (char< #\a #\b #\a #\c))) (test-t (not (char< #\a #\b #\c #\a))) (test-t (not (char< #\9 #\0))) (test-t (char> #\a)) (test-t (not (char> #\a #\z))) (test-t (char> #\z #\a)) (test-t (not (char> #\a #\b #\c #\d #\e #\f #\g #\h #\i #\j #\k #\l #\m #\n #\o #\p #\q #\r #\s #\t #\u #\v #\w #\x #\y #\z))) (test-t (char> #\z #\y #\x #\w #\v #\u #\t #\s #\r #\q #\p #\o #\n #\m #\l #\k #\j #\i #\h #\g #\f #\e #\d #\c #\b #\a)) (test-t (not (char> #\A #\B #\C #\D #\E #\F #\G #\H #\I #\J #\K #\L #\M #\N #\O #\P #\Q #\R #\S #\T #\U #\V #\W #\X #\Y #\Z))) (test-t (char> #\Z #\Y #\X #\W #\V #\U #\T #\S #\R #\Q #\P #\O #\N #\M #\L #\K #\J #\I #\H #\G #\F #\E #\D #\C #\B #\A)) (test-t (not (char> #\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9))) (test-t (char> #\9 #\8 #\7 #\6 #\5 #\4 #\3 #\2 #\1 #\0)) (test-t (or (char> #\A #\9) (char> #\0 #\Z))) (test-t (or (char> #\a #\9) (char> #\0 #\z))) (test-t (not (char> #\a #\a #\b #\c))) (test-t (not (char> #\a #\b #\a #\c))) (test-t (not (char> #\a #\b #\c #\a))) (test-t (char> #\9 #\0)) (test-t (char<= #\a)) (test-t (char<= #\a #\z)) (test-t (char<= #\a #\a)) (test-t (char<= #\Z #\Z)) (test-t (char<= #\a #\b #\c #\d #\e #\f #\g #\h #\i #\j #\k #\l #\m #\n #\o #\p #\q #\r #\s #\t #\u #\v #\w #\x #\y #\z)) (test-t (char<= #\a #\a #\b #\b #\c #\c #\d #\d #\e #\e #\f #\f #\g #\g #\h #\h #\i #\i #\j #\j #\k #\k #\l #\l #\m #\m #\n #\n #\o #\o #\p #\p #\q #\q #\r #\r #\s #\s #\t #\t #\u #\u #\v #\v #\w #\w #\x #\x #\y #\y #\z #\z)) (test-t (not (char<= #\z #\y #\x #\w #\v #\u #\t #\s #\r #\q #\p #\o #\n #\m #\l #\k #\j #\i #\h #\g #\f #\e #\d #\c #\b #\a))) (test-t (char<= #\A #\B #\C #\D #\E #\F #\G #\H #\I #\J #\K #\L #\M #\N #\O #\P #\Q #\R #\S #\T #\U #\V #\W #\X #\Y #\Z)) (test-t (char<= #\A #\B #\B #\C #\D #\E #\E #\F #\G #\H #\I #\I #\J #\K #\L #\M #\N #\N #\O #\P #\Q #\R #\S #\T #\T #\U #\V #\W #\X #\Y #\Z)) (test-t (not (char<= #\Z #\Y #\X #\W #\V #\U #\T #\S #\R #\Q #\P #\O #\N #\M #\L #\K #\J #\I #\H #\G #\F #\E #\D #\C #\B #\A))) (test-t (char<= #\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9)) (test-t (char<= #\0 #\1 #\2 #\2 #\3 #\3 #\3 #\3 #\4 #\5 #\6 #\7 #\8 #\9 #\9)) (test-t (not (char<= #\9 #\8 #\7 #\6 #\5 #\4 #\3 #\2 #\1 #\0))) (test-t (or (char<= #\9 #\A) (char<= #\Z #\0))) (test-t (or (char<= #\9 #\a) (char<= #\z #\0))) (test-t (char<= #\a #\a #\b #\c)) (test-t (not (char<= #\a #\b #\a #\c))) (test-t (not (char<= #\a #\b #\c #\a))) (test-t (not (char<= #\9 #\0))) (test-t (char>= #\a)) (test-t (not (char>= #\a #\z))) (test-t (char>= #\z #\a)) (test-t (char>= #\a #\a)) (test-t (char>= #\Z #\Z)) (test-t (not (char>= #\a #\b #\c #\d #\e #\f #\g #\h #\i #\j #\k #\l #\m #\n #\o #\p #\q #\r #\s #\t #\u #\v #\w #\x #\y #\z))) (test-t (char>= #\z #\y #\x #\w #\v #\u #\t #\s #\r #\q #\p #\o #\n #\m #\l #\k #\j #\i #\h #\g #\f #\e #\d #\c #\b #\a)) (test-t (char>= #\z #\z #\y #\x #\w #\v #\u #\t #\s #\r #\q #\p #\o #\n #\n #\m #\m #\l #\k #\j #\i #\h #\g #\f #\e #\d #\c #\b #\a #\a)) (test-t (not (char>= #\A #\B #\C #\D #\E #\F #\G #\H #\I #\J #\K #\L #\M #\N #\O #\P #\Q #\R #\S #\T #\U #\V #\W #\X #\Y #\Z))) (test-t (char>= #\Z #\Y #\X #\W #\V #\U #\T #\S #\R #\Q #\P #\O #\N #\M #\L #\K #\J #\I #\H #\G #\F #\E #\D #\C #\B #\A)) (test-t (char>= #\Z #\Y #\X #\W #\V #\U #\U #\T #\T #\S #\S #\R #\Q #\P #\O #\N #\M #\L #\K #\J #\I #\H #\H #\G #\G #\F #\F #\E #\D #\C #\B #\A)) (test-t (not (char>= #\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9))) (test-t (char>= #\9 #\8 #\7 #\6 #\5 #\4 #\3 #\2 #\1 #\0)) (test-t (char>= #\9 #\8 #\8 #\8 #\7 #\6 #\5 #\4 #\3 #\3 #\3 #\2 #\1 #\0)) (test-t (or (char>= #\A #\9) (char>= #\0 #\Z))) (test-t (or (char>= #\a #\9) (char>= #\0 #\z))) (test-t (char>= #\c #\b #\a #\a)) (test-t (not (char>= #\c #\b #\a #\a #\b #\c))) (test-t (not (char>= #\c #\b #\a #\c))) (test-t (not (char>= #\c #\b #\c #\a))) (test-t (char>= #\9 #\0)) (test-t (not (char>= #\0 #\9))) (test-t (char-equal #\a)) (test-t (char-equal #\a #\a)) (test-t (char-equal #\a #\a #\a)) (test-t (char-equal #\a #\a #\a #\a)) (test-t (char-equal #\a #\a #\a #\a #\a)) (test-t (char-equal #\a #\a #\a #\a #\a #\a)) (test-t (char-equal #\a #\A)) (test-t (char-equal #\a #\A #\a)) (test-t (char-equal #\a #\a #\A #\a)) (test-t (char-equal #\a #\a #\a #\A #\a)) (test-t (char-equal #\a #\a #\a #\a #\A #\a)) (test-t (let ((c #\z)) (and (eq c c) (char-equal c c)))) (test-t (char-equal #\Z #\z)) (test-t (not (char-equal #\z #\z #\z #\a))) (test-t (not (char-equal #\a #\z #\z #\z #\a))) (test-t (not (char-equal #\z #\i #\z #\z))) (test-t (char-equal #\z #\z #\Z #\z)) (test-t (char-equal #\a #\A #\a #\A #\a #\A #\a #\A #\a #\A)) (test-t (char-not-equal #\a)) (test-t (char-not-equal #\a #\b)) (test-t (char-not-equal #\a #\b #\c)) (test-t (char-not-equal #\a #\b #\c #\d)) (test-t (char-not-equal #\a #\b #\c #\d #\e)) (test-t (char-not-equal #\a #\b #\c #\d #\e #\f)) (test-t (let ((c #\z)) (and (eq c c) (not (char-not-equal c c))))) (test-t (not (char-not-equal #\Z #\z))) (test-t (not (char-not-equal #\z #\z #\z #\a))) (test-t (not (char= #\a #\z #\z #\z #\a))) (test-t (not (char= #\z #\i #\z #\z))) (test-t (not (char= #\z #\z #\Z #\z))) (test-t (not (char-not-equal #\a #\a #\b #\c))) (test-t (not (char-not-equal #\a #\b #\a #\c))) (test-t (not (char-not-equal #\a #\b #\c #\a))) (test-t (not (char-not-equal #\a #\A #\a #\A))) (test-t (char-lessp #\a)) (test-t (char-lessp #\a #\z)) (test-t (char-lessp #\a #\b #\c #\d #\e #\f #\g #\h #\i #\j #\k #\l #\m #\n #\o #\p #\q #\r #\s #\t #\u #\v #\w #\x #\y #\z)) (test-t (not (char-lessp #\z #\y #\x #\w #\v #\u #\t #\s #\r #\q #\p #\o #\n #\m #\l #\k #\j #\i #\h #\g #\f #\e #\d #\c #\b #\a))) (test-t (char-lessp #\A #\B #\C #\D #\E #\F #\G #\H #\I #\J #\K #\L #\M #\N #\O #\P #\Q #\R #\S #\T #\U #\V #\W #\X #\Y #\Z)) (test-t (not (char-lessp #\Z #\Y #\X #\W #\V #\U #\T #\S #\R #\Q #\P #\O #\N #\M #\L #\K #\J #\I #\H #\G #\F #\E #\D #\C #\B #\A))) (test-t (char-lessp #\a #\B #\c #\D #\e #\F #\g #\H #\i #\J #\k #\L #\m #\N #\o #\P #\q #\R #\s #\T #\u #\V #\w #\X #\y #\Z)) (test-t (char-lessp #\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9)) (test-t (not (char-lessp #\9 #\8 #\7 #\6 #\5 #\4 #\3 #\2 #\1 #\0))) (test-t (or (char-lessp #\9 #\A) (char-lessp #\Z #\0))) (test-t (or (char-lessp #\9 #\a) (char-lessp #\z #\0))) (test-t (not (char-lessp #\a #\a #\b #\c))) (test-t (not (char-lessp #\a #\b #\a #\c))) (test-t (not (char-lessp #\a #\b #\c #\a))) (test-t (not (char-lessp #\9 #\0))) (test-t (and (char-lessp #\a #\Z) (char-lessp #\A #\z))) (test-t (char-greaterp #\a)) (test-t (not (char-greaterp #\a #\z))) (test-t (char-greaterp #\z #\a)) (test-t (not (char-greaterp #\a #\b #\c #\d #\e #\f #\g #\h #\i #\j #\k #\l #\m #\n #\o #\p #\q #\r #\s #\t #\u #\v #\w #\x #\y #\z))) (test-t (char-greaterp #\z #\y #\x #\w #\v #\u #\t #\s #\r #\q #\p #\o #\n #\m #\l #\k #\j #\i #\h #\g #\f #\e #\d #\c #\b #\a)) (test-t (not (char-greaterp #\A #\B #\C #\D #\E #\F #\G #\H #\I #\J #\K #\L #\M #\N #\O #\P #\Q #\R #\S #\T #\U #\V #\W #\X #\Y #\Z))) (test-t (char-greaterp #\Z #\Y #\X #\W #\V #\U #\T #\S #\R #\Q #\P #\O #\N #\M #\L #\K #\J #\I #\H #\G #\F #\E #\D #\C #\B #\A)) (test-t (char-greaterp #\z #\Y #\x #\W #\v #\U #\t #\S #\r #\Q #\p #\O #\n #\M #\l #\K #\j #\I #\h #\G #\f #\E #\d #\C #\b #\A)) (test-t (not (char-greaterp #\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9))) (test-t (char-greaterp #\9 #\8 #\7 #\6 #\5 #\4 #\3 #\2 #\1 #\0)) (test-t (or (char-greaterp #\A #\9) (char-greaterp #\0 #\Z))) (test-t (or (char-greaterp #\a #\9) (char-greaterp #\0 #\z))) (test-t (not (char-greaterp #\a #\a #\b #\c))) (test-t (not (char-greaterp #\a #\b #\a #\c))) (test-t (not (char-greaterp #\a #\b #\c #\a))) (test-t (char-greaterp #\9 #\0)) (test-t (and (char-greaterp #\z #\A) (char-greaterp #\Z #\a))) (test-t (char-not-greaterp #\a)) (test-t (char-not-greaterp #\a #\z)) (test-t (char-not-greaterp #\a #\a)) (test-t (char-not-greaterp #\Z #\Z)) (test-t (char-not-greaterp #\a #\b #\c #\d #\e #\f #\g #\h #\i #\j #\k #\l #\m #\n #\o #\p #\q #\r #\s #\t #\u #\v #\w #\x #\y #\z)) (test-t (char-not-greaterp #\a #\a #\b #\b #\c #\c #\d #\d #\e #\e #\f #\f #\g #\g #\h #\h #\i #\i #\j #\j #\k #\k #\l #\l #\m #\m #\n #\n #\o #\o #\p #\p #\q #\q #\r #\r #\s #\s #\t #\t #\u #\u #\v #\v #\w #\w #\x #\x #\y #\y #\z #\z)) (test-t (char-not-greaterp #\a #\A #\b #\B #\c #\C #\d #\D #\e #\E #\f #\F #\g #\G #\h #\H #\i #\I #\j #\J #\k #\K #\l #\L #\m #\M #\n #\N #\o #\O #\p #\P #\q #\Q #\r #\R #\s #\S #\t #\T #\u #\U #\v #\V #\w #\W #\x #\X #\y #\Y #\z #\z)) (test-t (not (char-not-greaterp #\z #\y #\x #\w #\v #\u #\t #\s #\r #\q #\p #\o #\n #\m #\l #\k #\j #\i #\h #\g #\f #\e #\d #\c #\b #\a))) (test-t (char-not-greaterp #\A #\B #\C #\D #\E #\F #\G #\H #\I #\J #\K #\L #\M #\N #\O #\P #\Q #\R #\S #\T #\U #\V #\W #\X #\Y #\Z)) (test-t (char-not-greaterp #\A #\B #\B #\C #\D #\E #\E #\F #\G #\H #\I #\I #\J #\K #\L #\M #\N #\N #\O #\P #\Q #\R #\S #\T #\T #\U #\V #\W #\X #\Y #\Z)) (test-t (not (char-not-greaterp #\Z #\Y #\X #\W #\V #\U #\T #\S #\R #\Q #\P #\O #\N #\M #\L #\K #\J #\I #\H #\G #\F #\E #\D #\C #\B #\A))) (test-t (char-not-greaterp #\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9)) (test-t (char-not-greaterp #\0 #\1 #\2 #\2 #\3 #\3 #\3 #\3 #\4 #\5 #\6 #\7 #\8 #\9 #\9)) (test-t (not (char-not-greaterp #\9 #\8 #\7 #\6 #\5 #\4 #\3 #\2 #\1 #\0))) (test-t (or (char-not-greaterp #\9 #\A) (char-not-greaterp #\Z #\0))) (test-t (or (char-not-greaterp #\9 #\a) (char-not-greaterp #\z #\0))) (test-t (char-not-greaterp #\a #\a #\b #\c)) (test-t (not (char-not-greaterp #\a #\b #\a #\c))) (test-t (not (char-not-greaterp #\a #\b #\c #\a))) (test-t (not (char-not-greaterp #\9 #\0))) (test-t (and (char-not-greaterp #\A #\z) (char-not-greaterp #\a #\Z))) (test-t (char-not-lessp #\a)) (test-t (not (char-not-lessp #\a #\z))) (test-t (char-not-lessp #\z #\a)) (test-t (char-not-lessp #\a #\a)) (test-t (char-not-lessp #\Z #\Z)) (test-t (not (char-not-lessp #\a #\b #\c #\d #\e #\f #\g #\h #\i #\j #\k #\l #\m #\n #\o #\p #\q #\r #\s #\t #\u #\v #\w #\x #\y #\z))) (test-t (char-not-lessp #\z #\y #\x #\w #\v #\u #\t #\s #\r #\q #\p #\o #\n #\m #\l #\k #\j #\i #\h #\g #\f #\e #\d #\c #\b #\a)) (test-t (char-not-lessp #\z #\z #\y #\x #\w #\v #\u #\t #\s #\r #\q #\p #\o #\n #\n #\m #\m #\l #\k #\j #\i #\h #\g #\f #\e #\d #\c #\b #\a #\a)) (test-t (not (char-not-lessp #\A #\B #\C #\D #\E #\F #\G #\H #\I #\J #\K #\L #\m #\N #\O #\P #\Q #\R #\S #\T #\U #\V #\W #\X #\Y #\Z))) (test-t (char-not-lessp #\Z #\Y #\X #\W #\V #\U #\T #\S #\R #\Q #\P #\O #\N #\M #\L #\K #\J #\I #\H #\G #\F #\E #\D #\C #\B #\A)) (test-t (char-not-lessp #\Z #\Y #\X #\W #\V #\U #\U #\T #\T #\S #\S #\R #\Q #\P #\O #\N #\M #\L #\K #\J #\I #\H #\H #\G #\G #\F #\F #\E #\D #\C #\B #\A)) (test-t (char-not-lessp #\z #\Z #\y #\x #\w #\V #\v #\u #\t #\s #\r #\q #\p #\o #\n #\n #\m #\M #\l #\k #\K #\j #\i #\h #\g #\f #\e #\d #\c #\b #\A #\a)) (test-t (not (char-not-lessp #\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9))) (test-t (char-not-lessp #\9 #\8 #\7 #\6 #\5 #\4 #\3 #\2 #\1 #\0)) (test-t (char-not-lessp #\9 #\8 #\8 #\8 #\7 #\6 #\5 #\4 #\3 #\3 #\3 #\2 #\1 #\0)) (test-t (or (char-not-lessp #\A #\9) (char-not-lessp #\0 #\Z))) (test-t (or (char-not-lessp #\a #\9) (char-not-lessp #\0 #\z))) (test-t (char-not-lessp #\c #\b #\a #\a)) (test-t (not (char-not-lessp #\c #\b #\a #\a #\b #\c))) (test-t (not (char-not-lessp #\c #\b #\a #\c))) (test-t (not (char-not-lessp #\c #\b #\c #\a))) (test-t (char-not-lessp #\9 #\0)) (test-t (not (char-not-lessp #\0 #\9))) (test-t (and (char-not-lessp #\z #\A) (char-not-lessp #\Z #\a))) (test-t (char= (character #\a) #\a)) (test-t (char= (character #\b) #\b)) ; (test-t (char= (character #\Space) #\Space)) (test-t (char= (character "a") #\a)) (test-t (char= (character "X") #\X)) (test-t (char= (character "z") #\z)) (test-t (char= (character 'a) #\a)) ; (test-t (char= (character '\a) #\a)) (test-t (alpha-char-p #\a)) (test-t (every alpha-char-p '(#\a #\b #\c #\d #\e #\f #\g #\h #\i #\j #\k #\l #\m #\n #\o #\p #\q #\r #\s #\t #\u #\v #\w #\x #\y #\z))) (test-t (every alpha-char-p '(#\A #\B #\C #\D #\E #\F #\G #\H #\I #\J #\K #\L #\M #\N #\O #\P #\Q #\R #\S #\T #\U #\V #\W #\X #\Y #\Z))) (test-t (notany alpha-char-p '(#\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9))) ; (test-t (not (alpha-char-p #\Newline))) (test-t (alphanumericp #\Z)) (test-t (alphanumericp #\9)) (test-t (every alphanumericp '(#\a #\b #\c #\d #\e #\f #\g #\h #\i #\j #\k #\l #\m #\n #\o #\p #\q #\r #\s #\t #\u #\v #\w #\x #\y #\z))) (test-t (every alphanumericp '(#\A #\B #\C #\D #\E #\F #\G #\H #\I #\J #\K #\L #\M #\N #\O #\P #\Q #\R #\S #\T #\U #\V #\W #\X #\Y #\Z))) (test-t (every alphanumericp '(#\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9))) ; (test-t (not (alphanumericp #\Newline))) (test-t (not (alphanumericp #\#))) (test-t (char= (digit-char 0) #\0)) ; (test-t (char= (digit-char 10 11) #\A)) (test-t (null (digit-char 10 10))) (test-t (char= (digit-char 7) #\7)) (test-t (null (digit-char 12))) ; (test-t (char= (digit-char 12 16) #\C)) (test-t (null (digit-char 6 2))) (test-t (char= (digit-char 1 2) #\1)) ; (test-t (char= (digit-char 35 36) #\Z)) (test-t (= (digit-char-p #\0) 0)) (test-t (= (digit-char-p #\5) 5)) (test-t (not (digit-char-p #\5 2))) (test-t (not (digit-char-p #\A))) (test-t (not (digit-char-p #\a))) ; (test-t (= (digit-char-p #\A 11) 10)) (test-t (= (digit-char-p #\a 11) 10)) ; (test-t (standard-char-p #\a)) ; (test-t (standard-char-p #\z)) ; (test-t (standard-char-p #\Newline)) ; (test-t (every standard-char-p " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_'abcdefghijklmnopqrstuvwxyz{|}~")) (test-t (char= (char-upcase #\a) #\A)) (test-t (char= (char-upcase #\A) #\A)) (test-t (char= (char-upcase #\-) #\-)) (test-t (char= (char-downcase #\A) #\a)) (test-t (char= (char-downcase #\a) #\a)) (test-t (char= (char-downcase #\-) #\-)) (test-t (not (upper-case-p #\a))) (test-t (upper-case-p #\A)) (test-t (not (upper-case-p #\-))) (test-t (not (lower-case-p #\A))) (test-t (lower-case-p #\a)) (test-t (not (lower-case-p #\-))) ; (test-t (char= #\Space (name-char (char-name #\Space)))) ; (test-t (char= #\Newline (name-char (char-name #\Newline)))) (test-t (simple-string-p "")) (test-t (simple-string-p "abc")) (test-t (not (simple-string-p 'not-a-string))) (test-t (char= (char "abc" 0) #\a)) (test-t (char= (char "abc" 1) #\b)) (test-t (char= (char "abc" 2) #\c)) (test-t (char= (schar "abc" 0) #\a)) (test-t (char= (schar "abc" 1) #\b)) (test-t (char= (schar "abc" 2) #\c)) (test-t (string= (cl-string "") "")) (test-t (string= (cl-string "abc") "abc")) (test-t (string= (cl-string "a") "a")) (test-t (string= (cl-string 'abc) "abc")) (test-t (string= (cl-string 'a) "a")) (test-t (string= (cl-string #\a) "a")) (test-t (string= (cl-string-upcase "abcde") "ABCDE")) (test-t (string= (cl-string-upcase "Dr. Livingston, I presume?") "DR. LIVINGSTON, I PRESUME?")) (test-t (string= (cl-string-upcase "Dr. Livingston, I presume?" :start 6 :end 10) "Dr. LiVINGston, I presume?")) (test-t (string= (cl-string-upcase 'Kludgy-HASH-Search) "KLUDGY-HASH-SEARCH")) (test-t (string= (cl-string-upcase "abcde" :start 2 :end nil) "abCDE")) (test-t (string= (cl-string-downcase "Dr. Livingston, I presume?") "dr. livingston, i presume?")) (test-t (string= (cl-string-downcase 'Kludgy-HASH-Search) "kludgy-hash-search")) (test-t (string= (cl-string-downcase "A FOOL" :start 2 :end nil) "A fool")) (test-t (string= (string-capitalize "elm 13c arthur;fig don't") "Elm 13c Arthur;Fig Don'T")) (test-t (string= (string-capitalize " hello ") " Hello ")) (test-t (string= (string-capitalize "occlUDeD cASEmenTs FOreSTAll iNADVertent DEFenestraTION") "Occluded Casements Forestall Inadvertent Defenestration")) (test-t (string= (string-capitalize 'kludgy-hash-search) "Kludgy-Hash-Search")) (test-t (string= (string-capitalize "DON'T!") "Don'T!")) (test-t (string= (string-capitalize "pipe 13a, foo16c") "Pipe 13a, Foo16c")) (test-t (string= (string-capitalize "a fool" :start 2 :end nil) "a Fool")) (test-t (let ((str (copy-seq "0123ABCD890a"))) (and (string= (nstring-downcase str :start 5 :end 7) "0123AbcD890a") (string= str "0123AbcD890a")))) (test-t (let* ((str0 (copy-seq "abcde")) (str (nstring-upcase str0))) (and (eq str0 str) (string= str "ABCDE")))) (test-t (let* ((str0 (copy-seq "Dr. Livingston, I presume?")) (str (nstring-upcase str0))) (and (eq str0 str) (string= str "DR. LIVINGSTON, I PRESUME?")))) (test-t (let* ((str0 (copy-seq "Dr. Livingston, I presume?")) (str (nstring-upcase str0 :start 6 :end 10))) (and (eq str0 str) (string= str "Dr. LiVINGston, I presume?")))) (test-t (let* ((str0 (copy-seq "abcde")) (str (nstring-upcase str0 :start 2 :end nil))) (string= str "abCDE"))) (test-t (let* ((str0 (copy-seq "Dr. Livingston, I presume?")) (str (nstring-downcase str0))) (and (eq str0 str) (string= str "dr. livingston, i presume?")))) (test-t (let* ((str0 (copy-seq "ABCDE")) (str (nstring-downcase str0 :start 2 :end nil))) (string= str "ABcde"))) (test-t (let* ((str0 (copy-seq "elm 13c arthur;fig don't")) (str (nstring-capitalize str0))) (and (eq str0 str) (string= str "Elm 13c Arthur;Fig Don'T")))) (test-t (let* ((str0 (copy-seq " hello ")) (str (nstring-capitalize str0))) (and (eq str0 str) (string= str " Hello ")))) (test-t (let* ((str0 (copy-seq "occlUDeD cASEmenTs FOreSTAll iNADVertent DEFenestraTION")) (str (nstring-capitalize str0))) (and (eq str0 str) (string= str "Occluded Casements Forestall Inadvertent Defenestration")))) (test-t (let* ((str0 (copy-seq "DON'T!")) (str (nstring-capitalize str0))) (and (eq str0 str) (string= str "Don'T!")))) (test-t (let* ((str0 (copy-seq "pipe 13a, foo16c")) (str (nstring-capitalize str0))) (and (eq str0 str) (string= str "Pipe 13a, Foo16c")))) (test-t (let* ((str0 (copy-seq "a fool")) (str (nstring-capitalize str0 :start 2 :end nil))) (string= str "a Fool"))) (test-t (string= (string-trim "abc" "abcaakaaakabcaaa") "kaaak")) (test-t (string= (string-trim '(#\space) " garbanzo beans ") "garbanzo beans")) (test-t (string= (string-trim " (*)" " ( *three (silly) words* ) ") "three (silly) words")) (test-t (string= (string-left-trim "abc" "labcabcabc") "labcabcabc")) (test-t (string= (string-left-trim " (*)" " ( *three (silly) words* ) ") "three (silly) words* ) ")) (test-t (string= (string-right-trim " (*)" " ( *three (silly) words* ) ") " ( *three (silly) words")) (test-t (string= (string-trim "ABC" "abc") "abc")) (test-t (string= (string-trim "AABBCC" "abc") "abc")) (test-t (string= (string-trim "" "abc") "abc")) (test-t (string= (string-trim "ABC" "") "")) (test-t (string= (string-trim "cba" "abc") "")) (test-t (string= (string-trim "cba" "abccba") "")) (test-t (string= (string-trim "ccbbba" "abccba") "")) (test-t (string= (string-trim "cba" "abcxabc") "x")) (test-t (string= (string-trim "xyz" "xxyabcxyyz") "abc")) (test-t (string= (string-trim "a" #\a) "")) (test-t (string= (string-left-trim "ABC" "abc") "abc")) (test-t (string= (string-left-trim "" "abc") "abc")) (test-t (string= (string-left-trim "ABC" "") "")) (test-t (string= (string-left-trim "cba" "abc") "")) (test-t (string= (string-left-trim "cba" "abccba") "")) (test-t (string= (string-left-trim "cba" "abcxabc") "xabc")) (test-t (string= (string-left-trim "xyz" "xxyabcxyz") "abcxyz")) (test-t (string= (string-left-trim "a" #\a) "")) (test-t (string= (string-right-trim "ABC" "abc") "abc")) (test-t (string= (string-right-trim "" "abc") "abc")) (test-t (string= (string-right-trim "ABC" "") "")) (test-t (string= (string-right-trim "cba" "abc") "")) (test-t (string= (string-right-trim "cba" "abccba") "")) (test-t (string= (string-right-trim "cba" "abcxabc") "abcx")) (test-t (string= (string-right-trim "xyz" "xxyabcxyz") "xxyabc")) (test-t (string= (string-right-trim "a" #\a) "")) (test-t (string= (cl-string "already a string") "already a string")) (test-t (string= (cl-string #\c) "c")) (test-t (string= "foo" "foo")) (test-t (not (string= "foo" "Foo"))) (test-t (not (string= "foo" "bar"))) (test-t (string= "together" "frog" :start1 1 :end1 3 :start2 2)) (test-t (string-equal "foo" "Foo")) (test-t (string= "abcd" "01234abcd9012" :start2 5 :end2 9)) (test-t (eql (string< "aaaa" "aaab") 3)) (test-t (eql (string>= "aaaaa" "aaaa") 4)) (test-t (eql (string-not-greaterp "Abcde" "abcdE") 5)) (test-t (eql (string-lessp "012AAAA789" "01aaab6" :start1 3 :end1 7 :start2 2 :end2 6) 6)) (test-t (not (string-not-equal "AAAA" "aaaA"))) (test-t (string= "" "")) (test-t (not (string= "abc" ""))) (test-t (not (string= "" "abc"))) (test-t (not (string= "A" "a"))) (test-t (string= "abc" "xyz" :start1 3 :start2 3)) (test-t (string= "abc" "xyz" :start1 1 :end1 1 :start2 0 :end2 0)) (test-t (string= "axyza" "xyz" :start1 1 :end1 4)) (test-t (string= "axyza" "xyz" :start1 1 :end1 4 :start2 0 :end2 nil)) (test-t (string= "abxyz" "xyabz" :end1 2 :start2 2 :end2 4)) (test-t (not (string= "love" "hate"))) (test-t (string= 'love 'love)) (test-t (not (string= 'love "hate"))) (test-t (string= #\a #\a)) (test-t (not (string/= "" ""))) (test-t (eql (string/= "abc" "") 0)) (test-t (eql (string/= "" "abc") 0)) (test-t (eql (string/= "A" "a") 0)) (test-t (not (string/= "abc" "xyz" :start1 3 :start2 3))) (test-t (not (string/= "abc" "xyz" :start1 1 :end1 1 :start2 0 :end2 0))) (test-t (not (string/= "axyza" "xyz" :start1 1 :end1 4))) (test-t (not (string/= "axyza" "xyz" :start1 1 :end1 4 :start2 0 :end2 nil))) (test-t (not (string/= "abxyz" "xyabz" :end1 2 :start2 2 :end2 4))) (test-t (eql (string/= "love" "hate") 0)) (test-t (eql (string/= "love" "loVe") 2)) (test-t (not (string/= "life" "death" :start1 3 :start2 1 :end2 2))) (test-t (eql (string/= "abcxyz" "ABCxyZ" :start1 3 :start2 3) 5)) (test-t (eql (string/= "abcxyz" "ABCxyZ" :start1 3 :end1 nil :start2 3 :end2 nil) 5)) (test-t (eql (string/= "abcxyz" "ABCxyZ" :end1 nil :start2 3 :end2 3) 0)) (test-t (eql (string/= "abc" "abcxyz") 3)) (test-t (eql (string/= "abcxyz" "abc") 3)) (test-t (eql (string/= "abcxyz" "") 0)) (test-t (eql (string/= "AbcDef" "cdef" :start1 2) 3)) (test-t (eql (string/= "cdef" "AbcDef" :start2 2) 1)) (test-t (= (string/= 'love "hate") 0)) (test-t (not (string/= 'love 'love))) (test-t (not (string/= #\a #\a))) (test-t (= (string/= #\a #\b) 0)) (test-t (not (string< "" ""))) (test-t (not (string< "dog" "dog"))) (test-t (not (string< " " " "))) (test-t (not (string< "abc" ""))) (test-t (eql (string< "" "abc") 0)) (test-t (eql (string< "ab" "abc") 2)) (test-t (not (string< "abc" "ab"))) (test-t (eql (string< "aaa" "aba") 1)) (test-t (not (string< "aba" "aaa"))) (test-t (not (string< "my cat food" "your dog food" :start1 6 :start2 8))) (test-t (not (string< "cat food 2 dollars" "dog food 3 dollars" :start1 3 :end1 9 :start2 3 :end2 9))) (test-t (eql (string< "xyzabc" "abcd" :start1 3) 6)) (test-t (eql (string< "abc" "abc" :end1 1) 1)) (test-t (eql (string< "xyzabc" "abc" :start1 3 :end1 5) 5)) (test-t (eql (string< "xyz" "abcxyzXYZ" :start2 3) 3)) (test-t (not (string< "abc" "abcxyz" :end2 3))) (test-t (eql (string< "xyz" "abcxyz" :end1 2 :start2 3) 2)) (test-t (not (string< "xyzabc" "abcdef" :start1 3 :end2 3))) (test-t (eql (string< "aaaa" "z") 0)) (test-t (eql (string< "pppTTTaTTTqqq" "pTTTxTTT" :start1 3 :start2 1) 6)) (test-t (eql (string< "pppTTTaTTTqqq" "pTTTxTTT" :start1 6 :end1 7 :start2 4 :end2 5) 6)) (test-t (not (string< 'love 'hate))) (test-t (= (string< 'peace 'war) 0)) (test-t (not (string< 'love 'love))) (test-t (not (string< #\a #\a))) (test-t (= (string< #\a #\b) 0)) (test-t (not (string> "" ""))) (test-t (not (string> "dog" "dog"))) (test-t (not (string> " " " "))) (test-t (eql (string> "abc" "") 0)) (test-t (not (string> "" "abc"))) (test-t (not (string> "ab" "abc"))) (test-t (eql (string> "abc" "ab") 2)) (test-t (eql (string> "aba" "aaa") 1)) (test-t (not (string> "aaa" "aba"))) (test-t (not (string> "my cat food" "your dog food" :start1 6 :start2 8))) (test-t (not (string> "cat food 2 dollars" "dog food 3 dollars" :start1 3 :end1 9 :start2 3 :end2 9))) (test-t (eql (string> "xyzabcde" "abcd" :start1 3) 7)) (test-t (not (string> "abc" "abc" :end1 1))) (test-t (eql (string> "xyzabc" "a" :start1 3 :end1 5) 4)) (test-t (eql (string> "xyzXYZ" "abcxyz" :start2 3) 3)) (test-t (eql (string> "abcxyz" "abcxyz" :end2 3) 3)) (test-t (not (string> "xyzXYZ" "abcxyz" :end1 2 :start2 3))) (test-t (not (string> "xyzabc" "abcdef" :start1 3 :end2 3))) (test-t (eql (string> "z" "aaaa") 0)) (test-t (eql (string> "pTTTxTTTqqq" "pppTTTaTTT" :start1 1 :start2 3) 4)) (test-t (eql (string> "pppTTTxTTTqqq" "pTTTaTTT" :start1 6 :end1 7 :start2 4 :end2 5) 6)) (test-t (= (string> 'love 'hate) 0)) (test-t (not (string> 'peace 'war))) (test-t (not (string> 'love 'love))) (test-t (not (string> #\a #\a))) (test-t (not (string> #\a #\b))) (test-t (= (string> #\z #\a) 0)) (test-t (eql (string<= "" "") 0)) (test-t (eql (string<= "dog" "dog") 3)) (test-t (eql (string<= " " " ") 1)) (test-t (not (string<= "abc" ""))) (test-t (eql (string<= "ab" "abc") 2)) (test-t (eql (string<= "aaa" "aba") 1)) (test-t (not (string<= "aba" "aaa"))) (test-t (eql (string<= "my cat food" "your dog food" :start1 6 :start2 8) 11)) (test-t (eql (string<= "cat food 2 dollars" "dog food 3 dollars" :start1 3 :end1 9 :start2 3 :end2 9) 9)) (test-t (eql (string<= "xyzabc" "abcd" :start1 3) 6)) (test-t (eql (string<= "abc" "abc" :end1 1) 1)) (test-t (eql (string<= "xyzabc" "abc" :start1 3 :end1 5) 5)) (test-t (eql (string<= "xyz" "abcxyzXYZ" :start2 3) 3)) (test-t (eql (string<= "abc" "abcxyz" :end2 3) 3)) (test-t (eql (string<= "xyz" "abcxyz" :end1 2 :start2 3) 2)) (test-t (eql (string<= "xyzabc" "abcdef" :start1 3 :end2 3) 6)) (test-t (eql (string<= "aaaa" "z") 0)) (test-t (eql (string<= "pppTTTaTTTqqq" "pTTTxTTT" :start1 3 :start2 1) 6)) (test-t (eql (string<= "pppTTTaTTTqqq" "pTTTxTTT" :start1 6 :end1 7 :start2 4 :end2 5) 6)) (test-t (not (string<= 'love 'hate))) (test-t (= (string<= 'peace 'war) 0)) (test-t (= (string<= 'love 'love) 4)) (test-t (= (string<= #\a #\a) 1)) (test-t (= (string<= #\a #\b) 0)) (test-t (not (string<= #\z #\a))) (test-t (eql (string>= "" "") 0)) (test-t (eql (string>= "dog" "dog") 3)) (test-t (eql (string>= " " " ") 1)) (test-t (eql (string>= "abc" "") 0)) (test-t (not (string>= "" "abc"))) (test-t (not (string>= "ab" "abc"))) (test-t (eql (string>= "abc" "ab") 2)) (test-t (eql (string>= "aba" "aaa") 1)) (test-t (not (string>= "aaa" "aba"))) (test-t (eql (string>= "my cat food" "your dog food" :start1 6 :start2 8) 11)) (test-t (eql (string>= "cat food 2 dollars" "dog food 3 dollars" :start1 3 :end1 9 :start2 3 :end2 9) 9)) (test-t (eql (string>= "xyzabcde" "abcd" :start1 3) 7)) (test-t (not (string>= "abc" "abc" :end1 1))) (test-t (eql (string>= "xyzabc" "a" :start1 3 :end1 5) 4)) (test-t (eql (string>= "xyzXYZ" "abcxyz" :start2 3) 3)) (test-t (eql (string>= "abcxyz" "abcxyz" :end2 3) 3)) (test-t (not (string>= "xyzXYZ" "abcxyz" :end1 2 :start2 3))) (test-t (eql (string>= "xyzabc" "abcdef" :start1 3 :end2 3) 6)) (test-t (eql (string>= "z" "aaaa") 0)) (test-t (eql (string>= "pTTTxTTTqqq" "pppTTTaTTT" :start1 1 :start2 3) 4)) (test-t (eql (string>= "pppTTTxTTTqqq" "pTTTaTTT" :start1 6 :end1 7 :start2 4 :end2 5) 6)) (test-t (= (string>= 'love 'hate) 0)) (test-t (not (string>= 'peace 'war))) (test-t (= (string>= 'love 'love) 4)) (test-t (= (string>= #\a #\a) 1)) (test-t (not (string>= #\a #\b))) (test-t (= (string>= #\z #\a) 0)) (test-t (string-equal "" "")) (test-t (not (string-equal "abc" ""))) (test-t (not (string-equal "" "abc"))) (test-t (string-equal "A" "a")) (test-t (string-equal "abc" "xyz" :start1 3 :start2 3)) (test-t (string-equal "abc" "xyz" :start1 1 :end1 1 :start2 0 :end2 0)) (test-t (string-equal "axyza" "xyz" :start1 1 :end1 4)) (test-t (string-equal "axyza" "xyz" :start1 1 :end1 4 :start2 0 :end2 nil)) (test-t (string-equal "abxyz" "xyabz" :end1 2 :start2 2 :end2 4)) (test-t (not (string-equal "love" "hate"))) (test-t (string-equal "xyz" "XYZ")) (test-t (not (string-equal 'love 'hate))) (test-t (not (string-equal 'peace 'war))) (test-t (string-equal 'love 'love)) (test-t (string-equal #\a #\a)) (test-t (not (string-equal #\a #\b))) (test-t (not (string-equal #\z #\a))) (test-t (not (string-not-equal "" ""))) (test-t (eql (string-not-equal "abc" "") 0)) (test-t (eql (string-not-equal "" "abc") 0)) (test-t (not (string-not-equal "A" "a"))) (test-t (not (string-not-equal "abc" "xyz" :start1 3 :start2 3))) (test-t (not (string-not-equal "abc" "xyz" :start1 1 :end1 1 :start2 0 :end2 0))) (test-t (not (string-not-equal "axyza" "xyz" :start1 1 :end1 4))) (test-t (not (string-not-equal "axyza" "xyz" :start1 1 :end1 4 :start2 0 :end2 nil))) (test-t (not (string-not-equal "abxyz" "xyabz" :end1 2 :start2 2 :end2 4))) (test-t (eql (string-not-equal "love" "hate") 0)) (test-t (not (string-not-equal "love" "loVe"))) (test-t (not (string-not-equal "life" "death" :start1 3 :start2 1 :end2 2))) (test-t (not (string-not-equal "abcxyz" "ABCxyZ" :start1 3 :start2 3))) (test-t (not (string-not-equal "abcxyz" "ABCxyZ" :start1 3 :end1 nil :start2 3 :end2 nil))) (test-t (eql (string-not-equal "abcxyz" "ABCxyZ" :end1 nil :start2 3 :end2 3) 0)) (test-t (eql (string-not-equal "abc" "abcxyz") 3)) (test-t (eql (string-not-equal "abcxyz" "abc") 3)) (test-t (eql (string-not-equal "abcxyz" "") 0)) (test-t (not (string-not-equal "AbcDef" "cdef" :start1 2))) (test-t (not (string-not-equal "cdef" "AbcDef" :start2 2))) (test-t (not (string-not-equal "ABC" "abc"))) (test-t (= (string-not-equal 'love 'hate) 0)) (test-t (= (string-not-equal 'peace 'war) 0)) (test-t (not (string-not-equal 'love 'love))) (test-t (not (string-not-equal #\a #\a))) (test-t (= (string-not-equal #\a #\b) 0)) (test-t (= (string-not-equal #\z #\a) 0)) (test-t (not (string-lessp "" ""))) (test-t (not (string-lessp "dog" "dog"))) (test-t (not (string-lessp " " " "))) (test-t (not (string-lessp "abc" ""))) (test-t (eql (string-lessp "" "abc") 0)) (test-t (eql (string-lessp "ab" "abc") 2)) (test-t (not (string-lessp "abc" "ab"))) (test-t (eql (string-lessp "aaa" "aba") 1)) (test-t (not (string-lessp "aba" "aaa"))) (test-t (not (string-lessp "my cat food" "your dog food" :start1 6 :start2 8))) (test-t (not (string-lessp "cat food 2 dollars" "dog food 3 dollars" :start1 3 :end1 9 :start2 3 :end2 9))) (test-t (eql (string-lessp "xyzabc" "abcd" :start1 3) 6)) (test-t (eql (string-lessp "abc" "abc" :end1 1) 1)) (test-t (eql (string-lessp "xyzabc" "abc" :start1 3 :end1 5) 5)) (test-t (eql (string-lessp "xyz" "abcxyzXYZ" :start2 3) 3)) (test-t (not (string-lessp "abc" "abcxyz" :end2 3))) (test-t (eql (string-lessp "xyz" "abcxyz" :end1 2 :start2 3) 2)) (test-t (not (string-lessp "xyzabc" "abcdef" :start1 3 :end2 3))) (test-t (eql (string-lessp "aaaa" "z") 0)) (test-t (eql (string-lessp "pppTTTaTTTqqq" "pTTTxTTT" :start1 3 :start2 1) 6)) (test-t (eql (string-lessp "pppTTTaTTTqqq" "pTTTxTTT" :start1 6 :end1 7 :start2 4 :end2 5) 6)) (test-t (and (not (string-lessp "abc" "ABC")) (not (string-lessp "ABC" "abc")))) (test-t (not (string-lessp 'love 'hate))) (test-t (= (string-lessp 'peace 'war) 0)) (test-t (not (string-lessp 'love 'love))) (test-t (not (string-lessp #\a #\a))) (test-t (= (string-lessp #\a #\b) 0)) (test-t (not (string-lessp #\z #\a))) (test-t (not (string-greaterp "" ""))) (test-t (not (string-greaterp "dog" "dog"))) (test-t (not (string-greaterp " " " "))) (test-t (eql (string-greaterp "abc" "") 0)) (test-t (not (string-greaterp "" "abc"))) (test-t (not (string-greaterp "ab" "abc"))) (test-t (eql (string-greaterp "abc" "ab") 2)) (test-t (eql (string-greaterp "aba" "aaa") 1)) (test-t (not (string-greaterp "aaa" "aba"))) (test-t (not (string-greaterp "my cat food" "your dog food" :start1 6 :start2 8))) (test-t (not (string-greaterp "cat food 2 dollars" "dog food 3 dollars" :start1 3 :end1 9 :start2 3 :end2 9))) (test-t (eql (string-greaterp "xyzabcde" "abcd" :start1 3) 7)) (test-t (not (string-greaterp "abc" "abc" :end1 1))) (test-t (eql (string-greaterp "xyzabc" "a" :start1 3 :end1 5) 4)) (test-t (eql (string-greaterp "xyzXYZ" "abcxyz" :start2 3) 3)) (test-t (eql (string-greaterp "abcxyz" "abcxyz" :end2 3) 3)) (test-t (not (string-greaterp "xyzXYZ" "abcxyz" :end1 2 :start2 3))) (test-t (not (string-greaterp "xyzabc" "abcdef" :start1 3 :end2 3))) (test-t (eql (string-greaterp "z" "aaaa") 0)) (test-t (eql (string-greaterp "pTTTxTTTqqq" "pppTTTaTTT" :start1 1 :start2 3) 4)) (test-t (eql (string-greaterp "pppTTTxTTTqqq" "pTTTaTTT" :start1 6 :end1 7 :start2 4 :end2 5) 6)) (test-t (and (not (string-greaterp "abc" "ABC")) (not (string-greaterp "ABC" "abc")))) (test-t (= (string-greaterp 'love 'hate) 0)) (test-t (not (string-greaterp 'peace 'war))) (test-t (not (string-greaterp 'love 'love))) (test-t (not (string-greaterp #\a #\a))) (test-t (not (string-greaterp #\a #\b))) (test-t (= (string-greaterp #\z #\a) 0)) (test-t (eql (string-not-greaterp "" "") 0)) (test-t (eql (string-not-greaterp "dog" "dog") 3)) (test-t (eql (string-not-greaterp " " " ") 1)) (test-t (not (string-not-greaterp "abc" ""))) (test-t (eql (string-not-greaterp "ab" "abc") 2)) (test-t (eql (string-not-greaterp "aaa" "aba") 1)) (test-t (not (string-not-greaterp "aba" "aaa"))) (test-t (eql (string-not-greaterp "my cat food" "your dog food" :start1 6 :start2 8) 11)) (test-t (eql (string-not-greaterp "cat food 2 dollars" "dog food 3 dollars" :start1 3 :end1 9 :start2 3 :end2 9) 9)) (test-t (eql (string-not-greaterp "xyzabc" "abcd" :start1 3) 6)) (test-t (eql (string-not-greaterp "abc" "abc" :end1 1) 1)) (test-t (eql (string-not-greaterp "xyzabc" "abc" :start1 3 :end1 5) 5)) (test-t (eql (string-not-greaterp "xyz" "abcxyzXYZ" :start2 3) 3)) (test-t (eql (string-not-greaterp "abc" "abcxyz" :end2 3) 3)) (test-t (eql (string-not-greaterp "xyz" "abcxyz" :end1 2 :start2 3) 2)) (test-t (eql (string-not-greaterp "xyzabc" "abcdef" :start1 3 :end2 3) 6)) (test-t (eql (string-not-greaterp "aaaa" "z") 0)) (test-t (eql (string-not-greaterp "pppTTTaTTTqqq" "pTTTxTTT" :start1 3 :start2 1) 6)) (test-t (eql (string-not-greaterp "pppTTTaTTTqqq" "pTTTxTTT" :start1 6 :end1 7 :start2 4 :end2 5) 6)) (test-t (and (eql (string-not-greaterp "abc" "ABC") 3) (eql (string-not-greaterp "ABC" "abc") 3))) (test-t (not (string-not-greaterp 'love 'hate))) (test-t (= (string-not-greaterp 'peace 'war) 0)) (test-t (= (string-not-greaterp 'love 'love) 4)) (test-t (= (string-not-greaterp #\a #\a) 1)) (test-t (= (string-not-greaterp #\a #\b) 0)) (test-t (not (string-not-greaterp #\z #\a))) (test-t (eql (string-not-lessp "" "") 0)) (test-t (eql (string-not-lessp "dog" "dog") 3)) (test-t (eql (string-not-lessp " " " ") 1)) (test-t (eql (string-not-lessp "abc" "") 0)) (test-t (not (string-not-lessp "" "abc"))) (test-t (not (string-not-lessp "ab" "abc"))) (test-t (eql (string-not-lessp "abc" "ab") 2)) (test-t (eql (string-not-lessp "aba" "aaa") 1)) (test-t (not (string-not-lessp "aaa" "aba"))) (test-t (eql (string-not-lessp "my cat food" "your dog food" :start1 6 :start2 8) 11)) (test-t (eql (string-not-lessp "cat food 2 dollars" "dog food 3 dollars" :start1 3 :end1 9 :start2 3 :end2 9) 9)) (test-t (eql (string-not-lessp "xyzabcde" "abcd" :start1 3) 7)) (test-t (not (string-not-lessp "abc" "abc" :end1 1))) (test-t (eql (string-not-lessp "xyzabc" "a" :start1 3 :end1 5) 4)) (test-t (eql (string-not-lessp "xyzXYZ" "abcxyz" :start2 3) 3)) (test-t (eql (string-not-lessp "abcxyz" "abcxyz" :end2 3) 3)) (test-t (not (string-not-lessp "xyzXYZ" "abcxyz" :end1 2 :start2 3))) (test-t (eql (string-not-lessp "xyzabc" "abcdef" :start1 3 :end2 3) 6)) (test-t (eql (string-not-lessp "z" "aaaa") 0)) (test-t (eql (string-not-lessp "pTTTxTTTqqq" "pppTTTaTTT" :start1 1 :start2 3) 4)) (test-t (eql (string-not-lessp "pppTTTxTTTqqq" "pTTTaTTT" :start1 6 :end1 7 :start2 4 :end2 5) 6)) (test-t (and (eql (string-not-lessp "abc" "ABC") 3) (eql (string-not-lessp "ABC" "abc") 3))) (test-t (= (string-not-lessp 'love 'hate) 0)) (test-t (not (string-not-lessp 'peace 'war))) (test-t (= (string-not-lessp 'love 'love) 4)) (test-t (= (string-not-lessp #\a #\a) 1)) (test-t (not (string-not-lessp #\a #\b))) (test-t (= (string-not-lessp #\z #\a) 0)) (test-t (stringp "aaaaaa")) (test-t (not (stringp #\a))) (test-t (not (stringp 'a))) (test-t (not (stringp '(string)))) (test-t (string= (cl-make-string 3 :initial-element #\a) "aaa")) (test-t (string= (cl-make-string 1 :initial-element #\space) " ")) (test-t (string= (cl-make-string 0) "")) (test-t (null (dotimes (i 10)))) (test-t (= (dotimes (temp-one 10 temp-one)) 10)) (test-t (let ((temp-two 0)) (and (eq t (dotimes (temp-one 10 t) (incf temp-two))) (eql temp-two 10)))) (test-t (let ((count 0)) (eql (dotimes (i 5 count) (incf count)) 5))) (test-t (let ((count 0)) (eql (dotimes (i 1 count) (incf count)) 1))) (test-t (let ((count 0)) (zerop (dotimes (i 0 count) (incf count))))) (test-t (let ((count 0)) (zerop (dotimes (i -1 count) (incf count))))) (test-t (let ((count 0)) (zerop (dotimes (i -100 count) (incf count))))) (test-t (eql (dotimes (i 3 i)) 3)) (test-t (eql (dotimes (i 2 i)) 2)) (test-t (eql (dotimes (i 1 i)) 1)) (test-t (eql (dotimes (i 0 i)) 0)) (test-t (eql (dotimes (i -1 i)) 0)) (test-t (eql (dotimes (i -2 i)) 0)) (test-t (eql (dotimes (i -10 i)) 0)) (test-t (let ((list nil)) (and (eq (dotimes (i 10 t) (push i list)) t) (equal list '(9 8 7 6 5 4 3 2 1 0))))) (test-t (let ((list nil)) (equal (dotimes (i 10 (push i list)) (push i list)) '(10 9 8 7 6 5 4 3 2 1 0)))) (test-t (let ((list nil)) (equal (dotimes (i '10 (push i list)) (push i list)) '(10 9 8 7 6 5 4 3 2 1 0)))) (test-t (let ((list nil)) (equal (dotimes (i (/ 100 10) (push i list)) (push i list)) '(10 9 8 7 6 5 4 3 2 1 0)))) (test-t (= 3 (let ((i 3)) (dotimes (i i i) )))) (test-t (= 3 (let ((x 0)) (dotimes (i 3 x) (incf x))))) (test-t (= 3 (dotimes (i 3 i) ))) (test-t (= 3 (let ((x 0)) (dotimes (i 3 x) (declare (fixnum i)) (incf x))))) (test-t (null (dolist (x ())))) (test-t (null (dolist (x '(a))))) (test-t (eq t (dolist (x nil t)))) (test-t (= 6 (let ((sum 0)) (dolist (x '(0 1 2 3) sum) (incf sum x))))) (test-t (let ((temp-two ())) (equal (dolist (temp-one '(1 2 3 4) temp-two) (push temp-one temp-two)) '(4 3 2 1)))) (test-t (let ((temp-two 0)) (and (null (dolist (temp-one '(1 2 3 4)) (incf temp-two))) (eql temp-two 4)))) (test-t (null (dolist (var nil var)))) (test-t (let ((list nil)) (equal (dolist (var '(0 1 2 3) list) (push var list)) '(3 2 1 0)))) (test-t (null (dolist (var '(0 1 2 3))))) (test-t (eql (do ((temp-one 1 (1+ temp-one)) (temp-two 0 (1- temp-two))) ((> (- temp-one temp-two) 5) temp-one)) 4)) (test-t (eql (do ((temp-one 1 (1+ temp-one)) (temp-two 0 (1+ temp-one))) ((= 3 temp-two) temp-one)) 3)) (test-t (eql (do* ((temp-one 1 (1+ temp-one)) (temp-two 0 (1+ temp-one))) ((= 3 temp-two) temp-one)) 2)) (test-t (let ((a-vector (vector 1 nil 3 nil))) (do ((i 0 (+ i 1)) (n (array-dimension a-vector 0))) ((= i n)) (when (null (aref a-vector i)) (setf (aref a-vector i) 0))) (equalp a-vector #(1 0 3 0)))) (test-t (let ((vec (vector 0 1 2 3 4 5 6 7 8 9))) (equalp (do ((i 0 (1+ i)) (n #f) (j 9 (1- j))) ((>= i j) vec) (setq n (aref vec i)) (setf (aref vec i) (aref vec j)) (setf (aref vec j) n)) #(9 8 7 6 5 4 3 2 1 0)))) (test-t (let ((vec (vector 0 1 2 3 4 5 6 7 8 9))) (and (null (do ((i 0 (1+ i)) (n #f) (j 9 (1- j))) ((>= i j)) (setq n (aref vec i)) (setf (aref vec i) (aref vec j)) (setf (aref vec j) n))) (equalp vec #(9 8 7 6 5 4 3 2 1 0))))) (test-t (let ((vec (vector 0 1 2 3 4 5 6 7 8 9))) (and (null (do ((i 0 (1+ i)) (n #f) (j 9 (1- j))) ((>= i j)) (setq n (aref vec i)) (setf (aref vec i) (aref vec j)) (setf (aref vec j) n))) (equalp vec #(9 8 7 6 5 4 3 2 1 0))))) (test-t (let ((vec (vector 0 1 2 3 4 5 6 7 8 9))) (and (null (do ((i 0 (1+ i)) (n #f) (j 9 (1- j))) ((>= i j)) (setq n (aref vec i)) (setf (aref vec i) (aref vec j)) (setf (aref vec j) n))) (equalp vec #(9 8 7 6 5 4 3 2 1 0))))) (test-t (let ((vec (vector 0 1 2 3 4 5 6 7 8 9))) (and (null (do ((n #f) (i 0 (1+ i)) (j 9 (1- j))) ((>= i j)) (setq n (aref vec i)) (setf (aref vec i) (aref vec j)) (setf (aref vec j) n))) (equalp vec #(9 8 7 6 5 4 3 2 1 0))))) (test-t (let ((vec (vector 0 1 2 3 4 5 6 7 8 9))) (and (null (do ((i 0 (1+ i)) (j 9 (1- j)) (n #f)) ((>= i j)) (setq n (aref vec i)) (setf (aref vec i) (aref vec j)) (setf (aref vec j) n))) (equalp vec #(9 8 7 6 5 4 3 2 1 0))))) (test-t (= (funcall (lambda (x) (+ x 3)) 4) 7)) (test-t (= (funcall (lambda args (apply + args)) 1 2 3 4) 10)) (test-t (functionp (lambda args (apply + args)))) (test-t (consp (cons 'a 'b))) (test-t (consp '(1 . 2))) (test-t (consp (list nil))) (test-t (not (consp 'a))) (test-t (not (consp nil))) (test-t (not (consp 1))) (test-t (not (consp #\a))) (test-t (let ((a (cons 1 2))) (and (eql (car a) 1) (eql (cdr a) 2)))) (test-t (equal (cons 1 nil) '(1))) (test-t (equal (cons nil nil) '(()))) (test-t (equal (cons 'a (cons 'b (cons 'c ()))) '(a b c))) (test-t (atom 'a)) (test-t (atom nil)) (test-t (atom 1)) (test-t (atom #\a)) (test-t (not (atom (cons 1 2)))) (test-t (not (atom '(a . b)))) (test-t (not (atom (list nil)))) (test-t (listp nil)) (test-t (listp '(a b c))) (test-t (listp '(a . b))) (test-t (listp (cons 'a 'b))) (test-t (not (listp 1))) (test-t (not (listp 't))) (test-t (null ())) (test-t (null nil)) (test-t (not (null t))) (test-t (null (cdr '(a)))) (test-t (not (null (cdr '(1 . 2))))) (test-t (not (null 'a))) (test-t (endp ())) (test-t (not (endp '(1)))) (test-t (not (endp '(1 2)))) (test-t (not (endp '(1 2 3)))) (test-t (not (endp (cons 1 2)))) (test-t (endp (cddr '(1 2)))) (test-t (let ((a (cons 1 2))) (and (eq (rplaca a 0) a) (equal a '(0 . 2))))) (test-t (let ((a (list 1 2 3))) (and (eq (rplaca a 0) a) (equal a '(0 2 3))))) (test-t (let ((a (cons 1 2))) (and (eq (rplacd a 0) a) (equal a '(1 . 0))))) (test-t (let ((a (list 1 2 3))) (and (eq (rplacd a 0) a) (equal a '(1 . 0))))) (test-t (eq (car '(a . b)) 'a)) (test-t (let ((a (cons 1 2))) (eq (car (list a)) a))) (test-t (eq (cdr '(a . b)) 'b)) (test-t (eq (rest '(a . b)) 'b)) (test-t (let ((a (cons 1 2))) (eq (cdr (cons 1 a)) a))) (test-t (let ((a (cons 1 2))) (eq (rest (cons 1 a)) a))) (test-t (eq (caar '((a) b c)) 'a)) (test-t (eq (cadr '(a b c)) 'b)) (test-t (eq (cdar '((a . aa) b c)) 'aa)) (test-t (eq (cddr '(a b . c)) 'c)) (test-t (eq (caaar '(((a)) b c)) 'a)) (test-t (eq (caadr '(a (b) c)) 'b)) (test-t (eq (cadar '((a aa) b c)) 'aa)) (test-t (eq (caddr '(a b c)) 'c)) (test-t (eq (cdaar '(((a . aa)) b c)) 'aa)) (test-t (eq (cdadr '(a (b . bb) c)) 'bb)) (test-t (eq (cddar '((a aa . aaa) b c)) 'aaa)) (test-t (eq (cdddr '(a b c . d)) 'd)) (test-t (eq (caaaar '((((a))) b c)) 'a)) (test-t (eq (caaadr '(a ((b)) c)) 'b)) (test-t (eq (caadar '((a (aa)) b c)) 'aa)) (test-t (eq (caaddr '(a b (c))) 'c)) (test-t (eq (cadaar '(((a aa)) b c)) 'aa)) (test-t (eq (cadadr '(a (b bb) c)) 'bb)) (test-t (eq (caddar '((a aa aaa) b c)) 'aaa)) (test-t (eq (cadddr '(a b c d)) 'd)) (test-t (eq (cdaaar '((((a . aa))) b c)) 'aa)) (test-t (eq (cdaadr '(a ((b . bb)) c)) 'bb)) (test-t (eq (cdadar '((a (aa . aaa)) b c)) 'aaa)) (test-t (eq (cdaddr '(a b (c . cc))) 'cc)) (test-t (eq (cddaar '(((a aa . aaa)) b c)) 'aaa)) (test-t (eq (cddadr '(a (b bb . bbb) c)) 'bbb)) (test-t (eq (cdddar '((a aa aaa . aaaa) b c)) 'aaaa)) (test-t (eq (cddddr '(a b c d . e)) 'e)) (test-t (eq (copy-tree nil) nil)) (test-t (let* ((a (list 'a)) (b (list 'b)) (c (list 'c)) (x3 (cons c nil)) (x2 (cons b x3)) (x (cons a x2)) (y (copy-tree x))) (and (not (eq x y)) (not (eq (car x) (car y))) (not (eq (cdr x) (cdr y))) (not (eq (cadr x) (cadr y))) (not (eq (cddr x) (cddr y))) (not (eq (caddr x) (caddr y))) (eq (cdddr x) (cdddr y)) (equal x y) (eq (car x) a) (eq (car a) 'a) (eq (cdr a) nil) (eq (cdr x) x2) (eq (car x2) b) (eq (car b) 'b) (eq (cdr b) nil) (eq (cdr x2) x3) (eq (car x3) c) (eq (car c) 'c) (eq (cdr c) nil) (eq (cdr x3) nil)))) (test-t (let* ((x (list (list 'a 1) (list 'b 2) (list 'c 3))) (y (copy-tree x))) (and (not (eq (car x) (car y))) (not (eq (cadr x) (cadr y))) (not (eq (caddr x) (caddr y)))))) (test-t (let* ((x (list (list (list 1)))) (y (copy-tree x))) (and (not (eq x y)) (not (eq (car x) (car y))) (not (eq (caar x) (caar y)))))) (test-t (let ((x (list 'a 'b 'c 'd))) (and (equal (sublis '((a . 1) (b . 2) (c . 3)) x) '(1 2 3 d)) (equal x '(a b c d))))) (test-t (eq (sublis () ()) ())) (test-t (equal (sublis () '(1 2 3)) '(1 2 3))) (test-t (eq (sublis '((a . 1) (b . 2)) ()) nil)) (test-t (equal (sublis '((a . 1) (b . 2) (c . 3)) '(((a)) (b) c)) '(((1)) (2) 3))) (test-t (equal (sublis '(((a) . 1) ((b) . 2) ((c) . 3)) '((((a))) ((b)) (c))) '((((a))) ((b)) (c)))) (test-t (equal (sublis '(((a) . 1) ((b) . 2) ((c) . 3)) '((((a))) ((b)) (c)) :test equal) '(((1)) (2) 3))) (test-t (equal (nsublis '((a . 1) (b . 2) (c . 3)) (list 'a 'b 'c 'd)) '(1 2 3 d))) (test-t (let* ((x (list 'a 'b 'c 'd)) (y (nsublis '((a . 1) (b . 2) (c . 3)) x))) (and (eq x y) (equal x '(1 2 3 d))))) (test-t (let ((x (list 'l 'm 'n))) (and (eq (nsublis '((a . 1) (b . 2) (c . 3)) x) x) (equal x '(l m n))))) (test-t (let* ((n (cons 'n nil)) (m (cons 'm n)) (l (cons 'l m)) (x (nsublis '((a . 1) (b . 2) (c . 3)) l))) (and (eq x l) (eq (car l) 'l) (eq (cdr l) m) (eq (car m) 'm) (eq (cdr m) n) (eq (car n) 'n) (eq (cdr n) nil)))) (test-t (eq (nsublis () ()) ())) (test-t (equal (nsublis () '(1 2 3)) '(1 2 3))) (test-t (eq (nsublis '((a . 1) (b . 2)) ()) nil)) (test-t (equal (nsublis '((a b c) (b c d) (c d e)) (list 'a 'b 'c)) '((b c) (c d) (d e)))) (test-t (equal (nsublis '((a . 1) (b . 2) (c . 3)) (copy-tree '(((a)) (b) c))) '(((1)) (2) 3))) (test-t (equal (nsublis '(((a) . 1) ((b) . 2) ((c) . 3)) (copy-tree '((((a))) ((b)) (c)))) '((((a))) ((b)) (c)))) (test-t (equal (nsublis '(((a) . 1) ((b) . 2) ((c) . 3)) (copy-tree '((((a))) ((b)) (c))) :test equal) '(((1)) (2) 3))) (test-t (tree-equal 'a 'a)) (test-t (not (tree-equal 'a 'b))) (test-t (tree-equal '(a (b (c))) '(a (b (c))))) (test-t (tree-equal '(a (b (c))) '(a (b (c))) :test eq)) (test-t (not (tree-equal '("a" ("b" ("c"))) '("a" ("b" ("c")))))) (test-t (tree-equal '("a" ("b" ("c"))) '("a" ("b" ("c"))) :test equal)) (test-t (not (tree-equal '(a b) '(a (b))))) (test-t (eq (copy-list ()) ())) (test-t (equal (copy-list '(a b c)) '(a b c))) (test-t (equal (copy-list '(a . b)) '(a . b))) (test-t (let* ((x '(a b c)) (y (copy-list x))) (and (equal x y) (not (eq x y))))) (test-t (let* ((a (list 'a)) (b (list 'b)) (c (list 'c)) (x (list a b c)) (y (copy-list x))) (and (equal x y) (not (eq x y)) (eq (car x) (car y)) (eq (cadr x) (cadr y)) (eq (caddr x) (caddr y)) (eq (caar x) 'a) (eq (caadr x) 'b) (eq (caaddr x) 'c)))) (test-t (null (list))) (test-t (equal (list 1) '(1))) (test-t (equal (list 1 2 3) '(1 2 3))) (test-t (equal (list* 1 2 '(3)) '(1 2 3))) (test-t (equal (list* 1 2 'x) '(1 2 . x))) (test-t (equal (list* 1 2 '(3 4)) '(1 2 3 4))) (test-t (eq (list* 'x) 'x)) (test-t (eql (list-length ()) 0)) (test-t (eql (list-length '(1)) 1)) (test-t (eql (list-length '(1 2)) 2)) (test-t (equal (cl-make-list 5) '(() () () () ()))) (test-t (equal (cl-make-list 3 :initial-element 'rah) '(rah rah rah))) (test-t (equal (cl-make-list 2 :initial-element '(1 2 3)) '((1 2 3) (1 2 3)))) (test-t (null (cl-make-list 0))) (test-t (null (cl-make-list 0 :initial-element 'new-element))) (test-t (let ((place nil)) (and (equal (push 0 place) '(0)) (equal place '(0))))) (test-t (let ((place (list 1 2 3))) (and (equal (push 0 place) '(0 1 2 3)) (equal place '(0 1 2 3))))) (test-t (let ((a (list (list 1 2 3) 9))) (and (equal (push 0 (car a)) '(0 1 2 3)) (equal a '((0 1 2 3) 9))))) (test-t (let ((place (list 1 2 3))) (and (eql (pop place) 1) (equal place '(2 3))))) (test-t (let ((a (list (list 1 2 3) 9))) (and (eql (pop (car a)) 1) (equal a '((2 3) 9))))) (test-t (let ((x (list 'a 'b 'c))) (and (eq (pop (cdr x)) 'b) (equal x '(a c))))) (test-t (eq (first '(a . b)) 'a)) (test-t (null (first nil))) (test-t (let ((a (cons 1 2))) (eq (first (list a)) a))) (test-t (eql (first '(1 2 3)) '1)) (test-t (eql (second '(1 2 3)) '2)) (test-t (eql (third '(1 2 3)) '3)) (test-t (eql (fourth '(1 2 3 4)) '4)) (test-t (eql (fifth '(1 2 3 4 5)) '5)) (test-t (eql (sixth '(1 2 3 4 5 6)) '6)) (test-t (eql (seventh '(1 2 3 4 5 6 7)) '7)) (test-t (eql (eighth '(1 2 3 4 5 6 7 8)) '8)) (test-t (eql (ninth '(1 2 3 4 5 6 7 8 9)) '9)) (test-t (eql (tenth '(1 2 3 4 5 6 7 8 9 10)) '10)) (test-t (let ((x '(a b c))) (eq (nthcdr 0 x) x))) (test-t (let ((x '(a b c))) (eq (nthcdr 1 x) (cdr x)))) (test-t (let ((x '(a b c))) (eq (nthcdr 2 x) (cddr x)))) (test-t (let ((x '(a b c))) (eq (nthcdr 2 x) (cddr x)))) (test-t (let ((x '(a b c))) (eq (nthcdr 3 x) (cdddr x)))) (test-t (equal (nthcdr 0 '(0 1 2)) '(0 1 2))) (test-t (equal (nthcdr 1 '(0 1 2)) '(1 2))) (test-t (equal (nthcdr 2 '(0 1 2)) '(2))) (test-t (equal (nthcdr 3 '(0 1 2)) ())) (test-t (eql (nthcdr 1 '(0 . 1)) 1)) (test-t (eql (nth 0 '(a b c)) 'a)) (test-t (eql (nth 1 '(a b c)) 'b)) (test-t (eql (nth 2 '(a b c)) 'c)) (test-t (eql (nth 3 '(a b c)) ())) (test-t (eql (nth 4 '(a b c)) ())) (test-t (eql (nth 5 '(a b c)) ())) (test-t (eql (nth 6 '(a b c)) ())) (test-t (let ((x (list 'a 'b 'c))) (and (eq (setf (nth 0 x) 'z) 'z) (equal x '(z b c))))) (test-t (let ((x (list 'a 'b 'c))) (and (eq (setf (nth 1 x) 'z) 'z) (equal x '(a z c))))) (test-t (let ((x (list 'a 'b 'c))) (and (eq (setf (nth 2 x) 'z) 'z) (equal x '(a b z))))) (test-t (let ((0-to-3 (list 0 1 2 3))) (and (equal (setf (nth 2 0-to-3) "two") "two") (equal 0-to-3 '(0 1 "two" 3))))) (test-t (let* ((x (list 'a 'b 'c))) (eq (nconc x) x))) (test-t (let* ((x (list 'a 'b 'c)) (y (list 'd 'e 'f)) (list (nconc x y))) (and (eq list x) (eq (nthcdr 3 list) y) (equal list '(a b c d e f))))) (test-t (let* ((x (list 'a)) (y (list 'b)) (z (list 'c)) (list (nconc x y z))) (and (eq x list) (eq (first list) 'a) (eq y (cdr list)) (eq (second list) 'b) (eq z (cddr list)) (eq (third list) 'c)))) (test-t (equal (append '(a b) () '(c d) '(e f)) '(a b c d e f))) (test-t (null (append))) (test-t (null (append ()))) (test-t (null (append () ()))) (test-t (eq (append 'a) 'a)) (test-t (eq (append () 'a) 'a)) (test-t (eq (append () () 'a) 'a)) (test-t (equal (append '(a b) 'c) '(a b . c))) (test-t (let* ((x '(a b c)) (y '(d e f)) (z (append x y))) (and (equal z '(a b c d e f)) (eq (nthcdr 3 z) y) (not (eq x z))))) (test-t (equal (revappend '(a b c) '(d e f)) '(c b a d e f))) (test-t (let* ((x '(a b c)) (y '(d e f)) (z (revappend x y))) (and (equal z '(c b a d e f)) (not (eq x z)) (eq (nthcdr 3 z) y)))) (test-t (let ((x '(a b c))) (eq (revappend () x) x))) (test-t (null (revappend () ()))) (test-t (eq (revappend () 'a) 'a)) (test-t (equal (revappend '(a) 'b) '(a . b))) (test-t (equal (revappend '(a) ()) '(a))) (test-t (equal (revappend '(1 2 3) ()) '(3 2 1))) (test-t (equal (nreconc (list 'a 'b 'c) '(d e f)) '(c b a d e f))) (test-t (let* ((x (list 'a 'b 'c)) (y '(d e f)) (z (nreconc x y))) (and (equal z '(c b a d e f)) (eq (nthcdr 3 z) y)))) (test-t (equal (nreconc (list 'a) 'b) '(a . b))) (test-t (equal (nreconc (list 'a) ()) '(a))) (test-t (equal (nreconc (list 1 2 3) ()) '(3 2 1))) (test-t (null (butlast nil))) (test-t (null (butlast nil 1))) (test-t (null (butlast nil 2))) (test-t (null (butlast nil 3))) (test-t (equal (butlast '(1 2 3 4 5)) '(1 2 3 4))) (test-t (equal (butlast '(1 2 3 4 5) 1) '(1 2 3 4))) (test-t (equal (butlast '(1 2 3 4 5) 2) '(1 2 3))) (test-t (equal (butlast '(1 2 3 4 5) 3) '(1 2))) (test-t (equal (butlast '(1 2 3 4 5) 4) '(1))) (test-t (equal (butlast '(1 2 3 4 5) 5) ())) (test-t (equal (butlast '(1 2 3 4 5) 6) ())) (test-t (equal (butlast '(1 2 3 4 5) 7) ())) (test-t (let ((a '(1 2 3 4 5))) (equal (butlast a 3) '(1 2)) (equal a '(1 2 3 4 5)))) (test-t (null (nbutlast nil))) (test-t (null (nbutlast nil 1))) (test-t (null (nbutlast nil 2))) (test-t (null (nbutlast nil 3))) (test-t (equal (nbutlast (list 1 2 3 4 5)) '(1 2 3 4))) (test-t (equal (nbutlast (list 1 2 3 4 5) 1) '(1 2 3 4))) (test-t (equal (nbutlast (list 1 2 3 4 5) 2) '(1 2 3))) (test-t (equal (nbutlast (list 1 2 3 4 5) 3) '(1 2))) (test-t (equal (nbutlast (list 1 2 3 4 5) 4) '(1))) (test-t (equal (nbutlast (list 1 2 3 4 5) 5) ())) (test-t (equal (nbutlast (list 1 2 3 4 5) 6) ())) (test-t (equal (nbutlast (list 1 2 3 4 5) 7) ())) (test-t (equal (nbutlast (list* 1 2 3 4 5 6)) '(1 2 3 4))) (test-t (equal (nbutlast (list* 1 2 3 4 5 6) 1) '(1 2 3 4))) (test-t (equal (nbutlast (list* 1 2 3 4 5 6) 2) '(1 2 3))) (test-t (equal (nbutlast (list* 1 2 3 4 5 6) 3) '(1 2))) (test-t (equal (nbutlast (list* 1 2 3 4 5 6) 4) '(1))) (test-t (equal (nbutlast (list* 1 2 3 4 5 6) 5) ())) (test-t (equal (nbutlast (list* 1 2 3 4 5 6) 6) ())) (test-t (equal (nbutlast (list* 1 2 3 4 5 6) 7) ())) (test-t (let* ((a '(1 2 3 4 5)) (b (nbutlast a 3))) (and (eq a b) (equal a '(1 2))))) (test-t (let ((x '(0 1 2 3 4 5 6 7 8 9))) (eq (last x) (nthcdr 9 x)))) (test-t (let ((x '(0 1 2 3 4))) (eq (last x 0) nil))) (test-t (let ((x '(0 1 2 3 4))) (eq (last x) (nthcdr 4 x)))) (test-t (let ((x '(0 1 2 3 4))) (eq (last x 1) (nthcdr 4 x)))) (test-t (let ((x '(0 1 2 3 4))) (eq (last x 2) (cdddr x)))) (test-t (let ((x '(0 1 2 3 4))) (eq (last x 3) (cddr x)))) (test-t (let ((x '(0 1 2 3 4))) (eq (last x 4) (cdr x)))) (test-t (let ((x '(0 1 2 3 4))) (eq (last x 5) x))) (test-t (let ((x '(0 1 2 3 4))) (eq (last x 6) x))) (test-t (let ((x '(0 1 2 3 4))) (eq (last x 7) x))) (test-t (let ((x '(0 1 2 3 4))) (eq (last x 8) x))) (test-t (tailp () ())) (test-t (tailp () '(1))) (test-t (tailp () '(1 2 3 4 5 6 7 8 9))) (test-t (let ((x '(1 2 3))) (and (tailp x x) (tailp (cdr x) x) (tailp (cddr x) x) (tailp (cdddr x) x)))) (test-t (let ((x '(1 . 2))) (and (tailp x x) (tailp (cdr x) x)))) (test-t (not (tailp 'x '(1 2 3 4 5 6)))) (test-t (not (tailp (list 1 2 3) '(1 2 3)))) (test-t (define (ldiff . args) #f)) (test-t (null (ldiff () ()))) (test-t (equal (ldiff '(1 . 2) 2) '(1))) (test-t (equal (ldiff '(1 2 3 4 5 6 7 8 9) ()) '(1 2 3 4 5 6 7 8 9))) (test-t (let ((x '(1 2 3))) (and (null (ldiff x x)) (equal (ldiff x (cdr x)) '(1)) (equal (ldiff x (cddr x)) '(1 2)) (equal (ldiff x (cdddr x)) '(1 2 3))))) (test-t (let* ((x '(1 2 3)) (y '(a b c)) (z (ldiff x y))) (and (not (eq x z)) (equal z '(1 2 3))))) (test-t (equal (cl-member 'a '(a b c d)) '(a b c d))) (test-t (equal (cl-member 'b '(a b c d)) '(b c d))) (test-t (equal (cl-member 'c '(a b c d)) '(c d))) (test-t (equal (cl-member 'd '(a b c d)) '(d))) (test-t (equal (cl-member 'e '(a b c d)) ())) (test-t (equal (cl-member 'f '(a b c d)) ())) (test-t (let ((x '(a b c d))) (eq (cl-member 'a x) x) (eq (cl-member 'b x) (cdr x)) (eq (cl-member 'c x) (cddr x)) (eq (cl-member 'd x) (cdddr x)) (eq (cl-member 'e x) nil))) (test-t (equal (cl-member 'a '(a b c d) :test eq) '(a b c d))) (test-t (equal (cl-member 'b '(a b c d) :test eq) '(b c d))) (test-t (equal (cl-member 'c '(a b c d) :test eq) '(c d))) (test-t (equal (cl-member 'd '(a b c d) :test eq) '(d))) (test-t (equal (cl-member 'e '(a b c d) :test eq) ())) (test-t (equal (cl-member 'f '(a b c d) :test eq) ())) (test-t (null (cl-member 'a ()))) (test-t (let* ((x '((1 . a) (2 . b) (3 . c) (4 . d) (5 . e))) (y (cl-member 'd x :key cdr :test eq))) (and (equal y '((4 . d) (5 . e))) (eq y (nthcdr 3 x))))) (test-t (let* ((x '((1 . a) (2 . b) (3 . c) (4 . d) (5 . e))) (y (cl-member 'd x :key cdr))) (and (equal y '((4 . d) (5 . e))) (eq y (nthcdr 3 x))))) (test-t (equal (member-if (lambda (x) (eql x 'a)) '(a b c d)) '(a b c d))) (test-t (equal (member-if (lambda (x) (eql x 'b)) '(a b c d)) '(b c d))) (test-t (equal (member-if (lambda (x) (eql x 'c)) '(a b c d)) '(c d))) (test-t (equal (member-if (lambda (x) (eql x 'd)) '(a b c d)) '(d))) (test-t (equal (member-if (lambda (x) (eql x 'e)) '(a b c d)) ())) (test-t (equal (member-if (lambda (x) (eql x 'f)) '(a b c d)) ())) (test-t (null (member-if (lambda (x) (eql x 'a)) ()))) (test-t (let* ((x '((1 . a) (2 . b) (3 . c) (4 . d) (5 . e))) (y (member-if (lambda (p) (eq p 'd)) x :key cdr))) (and (equal y '((4 . d) (5 . e))) (eq y (nthcdr 3 x))))) (test-t (null (member-if zerop '(7 8 9)))) (test-t (equal (member-if-not (lambda (x) (not (eql x 'a))) '(a b c d)) '(a b c d))) (test-t (equal (member-if-not (lambda (x) (not (eql x 'b))) '(a b c d)) '(b c d))) (test-t (equal (member-if-not (lambda (x) (not (eql x 'c))) '(a b c d)) '(c d))) (test-t (equal (member-if-not (lambda (x) (not (eql x 'd))) '(a b c d)) '(d))) (test-t (equal (member-if-not (lambda (x) (not (eql x 'e))) '(a b c d)) ())) (test-t (equal (member-if-not (lambda (x) (not (eql x 'f))) '(a b c d)) ())) (test-t (null (member-if-not (lambda (x) (not (eql x 'a))) ()))) (test-t (let* ((x '((1 . a) (2 . b) (3 . c) (4 . d) (5 . e))) (y (member-if-not (lambda (p) (not (eq p 'd))) x :key cdr))) (and (equal y '((4 . d) (5 . e))) (eq y (nthcdr 3 x))))) (test-t (let ((dummy nil) (list-1 '(1 2 3 4))) (and (eq (mapc (lambda x (setq dummy (append dummy x))) list-1 '(a b c d e) '(x y z)) list-1) (equal dummy '(1 a x 2 b y 3 c z))))) (test-t (let* ((x '(0 1 2 3)) (y nil) (z (mapc (lambda (a b c) (push (list a b c) y)) x '(1 2 3 4) '(2 3 4 5)))) (and (eq z x) (equal y '((3 4 5) (2 3 4) (1 2 3) (0 1 2)))))) (test-t (let* ((x '(0 1 2 3)) (y nil) (z (mapc (lambda (a b c) (push (list a b c) y)) nil x '(1 2 3 4) '(2 3 4 5)))) (and (null z) (null y)))) (test-t (let ((sum 0)) (mapc (lambda rest (setq sum (+ sum (apply + rest)))) '(0 1 2) '(1 2 0) '(2 0 1)) (eql sum 9))) (test-t (let ((result 'initial-value) (list-1 nil)) (and (eq (mapc (lambda (a b) (setq result (cons (cons a b) result))) list-1) list-1) (eq result 'initial-value)))) (test-t (let ((result 'initial-value) (list-1 nil)) (and (eq (mapc (lambda (a b) (setq result (cons (cons a b) result))) list-1 '(1 2 3)) list-1) (eq result 'initial-value)))) (test-t (let ((result 'initial-value) (list-1 '(1 2 3))) (and (eq (mapc (lambda (a b) (setq result (cons (cons a b) result))) list-1 ()) list-1) (eq result 'initial-value)))) (test-t (equal (mapcar car '((1 2) (2 3) (3 4) (4 5))) '(1 2 3 4))) (test-t (null (mapcar identity ()))) (test-t (equal (mapcar list '(0 1 2 3) '(a b c d) '(w x y z)) '((0 a w) (1 b x) (2 c y) (3 d z)))) (test-t (null (mapcar list () '(0 1 2 3) '(1 2 3 4) '(2 3 4 5)))) (test-t (null (mapcar list '(0 1 2 3) () '(1 2 3 4) '(2 3 4 5)))) (test-t (null (mapcar list '(0 1 2 3) '(1 2 3 4) () '(2 3 4 5)))) (test-t (null (mapcar list '(0 1 2 3) '(1 2 3 4) '(2 3 4 5) ()))) (test-t (equal (mapcar list '(0) '(a b) '(x y z)) '((0 a x)))) (test-t (equal (mapcar list '(a b) '(0) '(x y z)) '((a 0 x)))) (test-t (equal (mapcar list '(a b) '(x y z) '(0)) '((a x 0)))) (test-t (equal (mapcar cons '(a b c) '(1 2 3)) '((a . 1) (b . 2) (c . 3)))) (test-t (equal (mapcan cdr (copy-tree '((1 2) (2 3) (3 4) (4 5)))) '(2 3 4 5))) (test-t (equal (mapcan append '((1 2 3) (4 5 6) (7 8 9)) '((a) (b c) (d e f)) (list (list 'x 'y 'z) (list 'y 'z) (list 'z))) '(1 2 3 a x y z 4 5 6 b c y z 7 8 9 d e f z))) (test-t (null (mapcan append '((1 2 3) (4 5 6) (7 8 9)) '((a) (b c)) ()))) (test-t (null (mapcan append '((1 2 3) (4 5 6) (7 8 9)) () '((a) (b c))))) (test-t (null (mapcan append () '((1 2 3) (4 5 6) (7 8 9)) '((a) (b c))))) (test-t (equal (mapcan list (list 1 2 3 4 5) (list 2 3 4 5 6) (list 3 4 5 6 7) (list 4 5 6 7 8)) '(1 2 3 4 2 3 4 5 3 4 5 6 4 5 6 7 5 6 7 8))) (test-t (equal (mapcan (lambda (x y) (if (null x) () (list x y))) '(() () () d e) '(1 2 3 4 5 6)) '(d 4 e 5))) (test-t (equal (mapcan (lambda (x) (if (numberp x) (list x) ())) '(a 1 b c 3 4 d 5)) '(1 3 4 5))) (test-t (equal (maplist identity '(a b c d)) '((a b c d) (b c d) (c d) (d)))) (test-t (equal (maplist car '((1 2) (2 3) (3 4) (4 5))) '((1 2) (2 3) (3 4) (4 5)))) (test-t (equal (maplist list '(a b c) '(b c d) '(c d e)) '(((a b c) (b c d) (c d e)) ((b c) (c d) (d e)) ((c) (d) (e))))) (test-t (equal (maplist append '(a b c) '(b c d) '(c d e)) '((a b c b c d c d e) (b c c d d e) (c d e)))) (test-t (equal (maplist append '(a b c) '(b c) '(c)) '((a b c b c c)))) (test-t (null (maplist append () '(a b c) '(b c) '(c)))) (test-t (null (maplist append '(a b c) () '(b c) '(c)))) (test-t (null (maplist append '(a b c) '(b c) '(c) ()))) (test-t (let ((x '((1 2) (2 3) (3 4) (4 5))) (y nil)) (and (eq (mapl (lambda (a) (push (car a) y)) x) x) (equal y '((4 5) (3 4) (2 3) (1 2)))))) (test-t (let ((x nil)) (and (null (mapl (lambda rest (push rest x)) () '(0) '(0 1))) (null x)))) (test-t (let ((x nil)) (and (equal (mapl (lambda rest (push rest x)) '(0) () '(0 1)) '(0)) (null x)))) (test-t (let ((x nil)) (and (equal (mapl (lambda rest (push rest x)) '(0) '(0 1) ()) '(0)) (null x)))) (test-t (equal (mapcon car (copy-tree '((1 2) (2 3) (3 4) (4 5)))) '(1 2 2 3 3 4 4 5))) (test-t (equal (mapcon list '(0 1 2 3) '(1 2 3 4) '(2 3 4 5) '(3 4 5 6)) '((0 1 2 3) (1 2 3 4) (2 3 4 5) (3 4 5 6) (1 2 3) (2 3 4) (3 4 5) (4 5 6) (2 3) (3 4) (4 5) (5 6) (3) (4) (5) (6)))) (test-t (null (mapcon list () '(0 1 2 3) '(1 2 3 4) '(2 3 4 5) '(3 4 5 6)))) (test-t (null (mapcon list '(0 1 2 3) () '(1 2 3 4) '(2 3 4 5) '(3 4 5 6)))) (test-t (null (mapcon list '(0 1 2 3) '(1 2 3 4) () '(2 3 4 5) '(3 4 5 6)))) (test-t (null (mapcon list '(0 1 2 3) '(1 2 3 4) '(2 3 4 5) () '(3 4 5 6)))) (test-t (null (mapcon list '(0 1 2 3) '(1 2 3 4) '(2 3 4 5) '(3 4 5 6) ()))) (test-t (let* ((x '((apple . 1) (orange . 2) (grapes . 3))) (y (acons 'plum 9 x))) (and (equal y '((plum . 9) (apple . 1) (orange . 2) (grapes . 3))) (eq x (cdr y))))) (test-t (equal (acons 'a '0 nil) '((a . 0)))) (test-t (equal (acons 'apple 1 (acons 'orange 2 (acons 'grapes '3 nil))) '((apple . 1) (orange . 2) (grapes . 3)))) (test-t (equal (acons () () ()) '((())))) (test-t (let ((alist '((x . 100) (y . 200) (z . 50)))) (eq (cl-assoc 'y alist) (cadr alist)))) (test-t (null (cl-assoc 'no-such-key '((x . 100) (y . 200) (z . 50))))) (test-t (let ((alist '((x . 100) (y . 200) (z . 50)))) (eq (cl-assoc 'y alist :test eq) (cadr alist)))) (test-t (null (cl-assoc 'key ()))) (test-t (null (cl-assoc () '(())))) (test-t (null (cl-assoc () '(() ())))) (test-t (let ((alist '(() () () (x . 100) (y . 200) (z . 50)))) (eq (cl-assoc 'y alist) (car (cddddr alist))))) (test-t (let ((alist '((1 . a) () (2 . b) (())))) (eq (cl-assoc () alist) (cadddr alist)))) (test-t (let ((alist '((x . 100) (y . 200) (x . 100) (z . 50)))) (eq (cl-assoc 'y alist) (cadr alist)))) (test-t (let ((alist '((x . 100) (y . 200) (z . 50)))) (eq (assoc-if (lambda (arg) (eq arg 'y)) alist) (cadr alist)))) (test-t (null (assoc-if consp '((x . 100) (y . 200) (z . 50))))) (test-t (null (assoc-if (lambda (x) (eq x 'key)) ()))) (test-t (null (assoc-if identity '(())))) (test-t (null (assoc-if identity '(() ())))) (test-t (let ((alist '(() () () (x . 100) (y . 200) (z . 50)))) (eq (assoc-if (lambda (arg) (eq arg 'y)) alist) (car (cddddr alist))))) (test-t (let ((alist '((1 . a) () (2 . b) (())))) (eq (assoc-if (lambda (arg) (null arg)) alist) (cadddr alist)))) (test-t (let ((alist '((x . 100) (y . 200) (z . 50)))) (eq (assoc-if-not (lambda (arg) (not (eq arg 'y))) alist) (cadr alist)))) (test-t (null (assoc-if-not (complement consp) '((x . 100) (y . 200) (z . 50))))) (test-t (null (assoc-if-not (lambda (x) (not (eq x 'key))) ()))) (test-t (null (assoc-if-not identity '(())))) (test-t (null (assoc-if-not identity '(() ())))) (test-t (let ((alist '(() () () (x . 100) (y . 200) (z . 50)))) (eq (assoc-if-not (lambda (arg) (not (eq arg 'y))) alist) (car (cddddr alist))))) (test-t (equal (copy-alist '((a . 10) (b . 100) (c . 1000))) '((a . 10) (b . 100) (c . 1000)))) (test-t (let* ((alist '((a . 10) (b . 100) (c . 1000))) (copy (copy-alist alist))) (and (not (eq alist copy)) (not (eq (cdr alist) (cdr copy))) (not (eq (cddr alist) (cddr copy))) (not (eq (car alist) (car copy))) (not (eq (cadr alist) (cadr copy))) (not (eq (caddr alist) (caddr copy)))))) (test-t (let* ((alist '((a 10 x) (b 100 y) (c 1000 z))) (copy (copy-alist alist))) (and (not (eq alist copy)) (not (eq (cdr alist) (cdr copy))) (not (eq (cddr alist) (cddr copy))) (not (eq (car alist) (car copy))) (not (eq (cadr alist) (cadr copy))) (not (eq (caddr alist) (caddr copy))) (eq (cdar alist) (cdar copy)) (eq (cdadr alist) (cdadr copy)) (eq (cdaddr alist) (cdaddr copy))))) (test-t (let* ((alist (pairlis '(x y z) '(xx yy zz) '((a . aa) (b . bb))))) (and (equal (cl-assoc 'x alist) '(x . xx)) (equal (cl-assoc 'y alist) '(y . yy)) (equal (cl-assoc 'z alist) '(z . zz)) (equal (cl-assoc 'a alist) '(a . aa)) (equal (cl-assoc 'b alist) '(b . bb)) (null (cl-assoc 'key alist))))) (test-t (let* ((alist (pairlis '(x y z) '(xx yy zz)))) (and (equal (cl-assoc 'x alist) '(x . xx)) (equal (cl-assoc 'y alist) '(y . yy)) (equal (cl-assoc 'z alist) '(z . zz)) (null (cl-assoc 'key alist))))) (test-t (let ((alist '((x . 100) (y . 200) (z . 50)))) (eq (rassoc '200 alist) (cadr alist)))) (test-t (null (rassoc 'no-such-datum '((x . 100) (y . 200) (z . 50))))) (test-t (let ((alist '((x . 100) (y . 200) (z . 50)))) (eq (rassoc '200 alist :test =) (cadr alist)))) (test-t (null (rassoc 'key ()))) (test-t (null (rassoc () '(())))) (test-t (null (rassoc () '(() ())))) (test-t (let ((alist '(() () () (x . 100) (y . 200) (z . 50)))) (eq (rassoc '200 alist) (car (cddddr alist))))) (test-t (let ((alist '((1 . a) () (2 . b) (())))) (eq (rassoc () alist) (cadddr alist)))) (test-t (let ((alist '((x . 100) (y . 200) (x . 100) (z . 50)))) (eq (rassoc '200 alist) (cadr alist)))) (test-t (let ((alist '((x . 100) (y . 200) (z . 50)))) (eq (rassoc-if (lambda (arg) (= arg 200)) alist) (cadr alist)))) (test-t (null (rassoc-if consp '((x . 100) (y . 200) (z . 50))))) (test-t (null (rassoc-if (lambda (x) (eq x 'key)) ()))) (test-t (null (rassoc-if identity '(())))) (test-t (null (rassoc-if identity '(() ())))) (test-t (let ((alist '(() () () (x . 100) (y . 200) (z . 50)))) (eq (rassoc-if (lambda (arg) (= arg 200)) alist) (car (cddddr alist))))) (test-t (let ((alist '((1 . a) () (2 . b) (())))) (eq (rassoc-if (lambda (arg) (null arg)) alist) (cadddr alist)))) (test-t (let ((alist '((x . 100) (y . 200) (z . 50)))) (eq (rassoc-if-not (lambda (arg) (not (= arg 200))) alist) (cadr alist)))) (test-t (null (rassoc-if-not (complement consp) '((x . 100) (y . 200) (z . 50))))) (test-t (null (rassoc-if-not (lambda (x) (not (eq x 'key))) ()))) (test-t (null (rassoc-if-not identity '(())))) (test-t (null (rassoc-if-not identity '(() ())))) (test-t (let ((alist '(() () () (x . 100) (y . 200) (z . 50)))) (eq (rassoc-if-not (lambda (arg) (not (= arg 200))) alist) (car (cddddr alist))))) (test-t (let ((set '(a b c))) (eq (adjoin 'a set) set))) (test-t (let* ((set '(a b c)) (new-set (adjoin 'x set))) (and (equal new-set '(x a b c)) (eq set (cdr new-set))))) (test-t (equal (adjoin 1 nil) '(1))) (test-t (let ((set '((test-item 1)))) (equal (adjoin '(test-item 1) set) '((test-item 1) (test-item 1))))) (test-t (let ((set '((test-item 1)))) (equal (adjoin '(test-item 1) set) '((test-item 1) (test-item 1))))) (test-t (let ((set '((test-item 1)))) (eq (adjoin '(test-item 1) set :test equal) set))) (test-t (let ((set '((test-item 1)))) (eq (adjoin '(test-item) set :key car) set))) (test-t (let ((set '((test-item 1)))) (eq (adjoin '(test-item) set :key car :test eq) set))) (test-t (let ((set '(("test-item" 1)))) (eq (adjoin '("test-item") set :key car :test equal) set))) (test-t (let ((place nil)) (and (equal (pushnew 'a place) '(a)) (equal place '(a))))) (test-t (let ((place nil)) (and (equal (pushnew 'a place) '(a)) (equal place '(a))))) (test-t (let ((place '("love" "peace"))) (equal (pushnew "war" place :test equal) '("war" "love" "peace")))) (test-t (let ((place '("love" "peace"))) (and (eq (pushnew "peace" place :test equal) place) (equal place '("love" "peace"))))) (test-t (let ((place '(("love" . l) ("peace" . p)))) (equal (pushnew '("war" . w) place :test equal :key car) '(("war" . w) ("love" . l) ("peace" . p))))) (test-t (let ((place '(("love" . l) ("peace" . p)))) (and (eq (pushnew '("love" . l) place :test equal :key car) place) (equal place '(("love" . l) ("peace" . p)))))) (test-t (let* ((list '((1) (1 2) (1 2 3))) (original list)) (and (equal (pushnew '(1) list :test equal) '((1) (1 2) (1 2 3))) (eq list original)))) (test-t (let* ((list '((1) (1 2) (1 2 3))) (original list)) (and (equal (pushnew '(1) list :test equal :key nil) '((1) (1 2) (1 2 3))) (eq list original)))) (test-t (eql (length "abc") 3)) (test-t (zerop (length ""))) (test-t (zerop (length #()))) (test-t (zerop (length ()))) (test-t (eql (length '(0)) 1)) (test-t (eql (length '(0 1)) 2)) (test-t (eql (length '(0 1 2)) 3)) (test-t (eql (length '(0 1 2 3)) 4)) (test-t (eql (length '(0 1 2 3 4)) 5)) (test-t (eql (length '(0 1 2 3 4 5)) 6)) (test-t (eql (length '(0 1 2 3 4 5 6)) 7)) (test-t (eql (length #(0)) 1)) (test-t (eql (length #(0 1)) 2)) (test-t (eql (length #(0 1 2)) 3)) (test-t (eql (length #(0 1 2 3)) 4)) (test-t (eql (length #(0 1 2 3 4)) 5)) (test-t (eql (length #(0 1 2 3 4 5)) 6)) (test-t (eql (length #(0 1 2 3 4 5 6)) 7)) (test-t (eql (length (make-array 100)) 100)) (test-t (eql (length (make-sequence 'list 20)) 20)) (test-t (eql (length (make-sequence 'string 10)) 10)) (test-t (eql (length (make-sequence 'bit-vector 3)) 3)) (test-t (eql (length (make-sequence 'bit-vector 64)) 64)) (test-t (eql (length (make-sequence 'simple-vector 64)) 64)) (test-t (string= (copy-seq "love") "love")) (test-t (equalp (copy-seq #(a b c d)) #(a b c d))) (test-t (equal (copy-seq '(love)) '(love))) (test-t (equal (copy-seq '(love hate war peace)) '(love hate war peace))) (test-t (null (copy-seq nil))) (test-t (string= (copy-seq "") "")) (test-t (let* ((seq0 "love&peace") (seq (copy-seq seq0))) (and (not (eq seq0 seq)) (string= seq0 seq)))) (test-t (let* ((seq0 (list 'love 'and 'peace)) (seq (copy-seq seq0))) (and (not (eq seq0 seq)) (equal seq0 seq)))) (test-t (let* ((c0 (list 'love)) (c1 (list 'peace)) (seq (copy-seq (list c0 c1)))) (and (equal seq '((love) (peace))) (eq (car seq) c0) (eq (cadr seq) c1)))) (test-t (let* ((seq0 #(t nil t nil)) (seq (copy-seq seq0))) (and (not (eq seq0 seq)) (equalp seq seq0)))) (test-t (vectorp (copy-seq (vector)))) (test-t (simple-vector-p (copy-seq (vector)))) (test-t (simple-vector-p (copy-seq (vector 0 1)))) (test-t (simple-string-p (copy-seq "xyz"))) (test-t (char= (elt "0123456789" 6) #\6)) (test-t (eq (elt #(a b c d e f g) 0) 'a)) (test-t (eq (elt '(a b c d e f g) 4) 'e)) (test-t (let ((str (copy-seq "0123456789"))) (and (char= (elt str 6) #\6) (setf (elt str 0) #\#) (string= str "#123456789")))) (test-t (let ((list (list 0 1 2 3))) (and (= (elt list 2) 2) (setf (elt list 1) 9) (= (elt list 1) 9) (equal list '(0 9 2 3))))) (test-t (let ((vec (vector 'a 'b 'c))) (and (eq (elt vec 0) 'a) (eq (elt vec 1) 'b) (eq (elt vec 2) 'c)))) (test-t (let ((list (list 0 1 2 3))) (and (eq (cl-fill list nil) list) (every null list)))) (test-t (let ((vector (vector 'x 'y 'z))) (and (eq (cl-fill vector 'a) vector) (every (lambda (arg) (eq arg 'a)) vector)))) (test-t (let ((list (list 0 1 2 3))) (and (eq (cl-fill list '9 :start 2) list) (equal list '(0 1 9 9))))) (test-t (let ((list (list 0 1 2 3))) (and (eq (cl-fill list '9 :start 1 :end 3) list) (equal list '(0 9 9 3))))) (test-t (let ((list (list 0 1 2 3))) (and (eq (cl-fill list '9 :start 1 :end nil) list) (equal list '(0 9 9 9))))) (test-t (let ((list (list 0 1 2 3))) (and (eq (cl-fill list '9 :end 1) list) (equal list '(9 1 2 3))))) (test-t (let ((vector (vector 0 1 2 3))) (and (eq (cl-fill vector 't :start 3) vector) (equalp vector #(0 1 2 t))))) (test-t (let ((vector (vector 0 1 2 3))) (and (eq (cl-fill vector 't :start 2 :end 4) vector) (equalp vector #(0 1 t t))))) (test-t (let ((vector (vector 0 1 2 3))) (and (eq (cl-fill vector 't :start 2 :end nil) vector) (equalp vector #(0 1 t t))))) (test-t (let ((vector (vector 0 1 2 3))) (and (eq (cl-fill vector 't :end 3) vector) (equalp vector #(t t t 3))))) (test-t (null (make-sequence 'list 0))) (test-t (string= (make-sequence 'string 26 :initial-element #\.) "..........................")) (test-t (equal (make-sequence 'list 3 :initial-element 'a) '(a a a))) (test-t (null (make-sequence 'null 0 :initial-element 'a))) (test-t (equalp (make-sequence 'vector 3 :initial-element 'z) #(z z z))) (test-t (string= (make-sequence 'string 4 :initial-element '#\z) "zzzz")) (test-t (vectorp (make-sequence 'vector 10))) (test-t (string= (subseq "012345" 2) "2345")) (test-t (string= (subseq "012345" 3 5) "34")) (test-t (equal (subseq '(0 1 2 3) 0) '(0 1 2 3))) (test-t (equal (subseq '(0 1 2 3) 1) '(1 2 3))) (test-t (equal (subseq '(0 1 2 3) 2) '(2 3))) (test-t (equal (subseq '(0 1 2 3) 3) '(3))) (test-t (equal (subseq '(0 1 2 3) 4) ())) (test-t (equalp (subseq #(a b c d) 0) #(a b c d))) (test-t (equalp (subseq #(a b c d) 1) #(b c d))) (test-t (equalp (subseq #(a b c d) 2) #(c d))) (test-t (equalp (subseq #(a b c d) 3) #(d))) (test-t (equalp (subseq #(a b c d) 4) #())) (test-t (string= (subseq "0123" 0) "0123")) (test-t (string= (subseq "0123" 1) "123")) (test-t (string= (subseq "0123" 2) "23")) (test-t (string= (subseq "0123" 3) "3")) (test-t (string= (subseq "0123" 4) "")) (test-t (equal (subseq '(0 1 2 3) 0 4) '(0 1 2 3))) (test-t (equal (subseq '(0 1 2 3) 0 nil) '(0 1 2 3))) (test-t (let* ((list0 '(0 1 2 3)) (list (subseq list0 0 4))) (and (not (eq list0 list)) (equal list0 list)))) (test-t (let* ((list0 '(0 1 2 3)) (list (subseq list0 0 nil))) (and (not (eq list0 list)) (equal list0 list)))) (test-t (equal (subseq '(0 1 2 3) 1 3) '(1 2))) (test-t (equal (subseq '(0 1 2 3) 2 2) ())) (test-t (equal (subseq '(0 1 2 3) 0 0) ())) (test-t (equal (subseq '(0 1 2 3) 1 1) ())) (test-t (equal (subseq '(0 1 2 3) 2 2) ())) (test-t (equal (subseq '(0 1 2 3) 3 3) ())) (test-t (equal (subseq '(0 1 2 3) 4 4) ())) (test-t (equalp (subseq #(0 1 2 3) 0 4) #(0 1 2 3))) (test-t (equalp (subseq #(0 1 2 3) 0 nil) #(0 1 2 3))) (test-t (let* ((vec0 #(0 1 2 3)) (vec (subseq vec0 0 4))) (and (not (eq vec0 vec)) (equalp vec0 vec)))) (test-t (let* ((vec0 #(0 1 2 3)) (vec (subseq vec0 0 nil))) (and (not (eq vec0 vec)) (equalp vec0 vec)))) (test-t (equalp (subseq #(0 1 2 3) 1 3) #(1 2))) (test-t (equalp (subseq #(0 1 2 3) 2 2) #())) (test-t (equalp (subseq #(0 1 2 3) 0 0) #())) (test-t (equalp (subseq #(0 1 2 3) 1 1) #())) (test-t (equalp (subseq #(0 1 2 3) 2 2) #())) (test-t (equalp (subseq #(0 1 2 3) 3 3) #())) (test-t (equalp (subseq #(0 1 2 3) 4 4) #())) (test-t (string= (cl-map 'string (lambda (x y) (char "01234567890ABCDEF" (mod (+ x y) 16))) '(1 2 3 4) '(10 9 8 7)) "AAAA")) (test-t (equal (cl-map 'list - '(1 2 3 4)) '(-1 -2 -3 -4))) (test-t (string= (cl-map 'string (lambda (x) (if (oddp x) #\1 #\0)) '(1 2 3 4)) "1010")) (test-t (equal (cl-map 'list + '(0 1) '(1 0)) '(1 1))) (test-t (equal (cl-map 'list - '(0 1) '(1 0)) '(-1 1))) (test-t (every null (list (cl-map 'list + ()) (cl-map 'list + () ()) (cl-map 'list + () () ()) (cl-map 'list + () () () ()) (cl-map 'list + () () () () ())))) (test-t (equal (cl-map 'list + '(0 1 2)) '(0 1 2))) (test-t (equal (cl-map 'list + '(0 1 2) '(1 2 3)) '(1 3 5))) (test-t (equal (cl-map 'list + '(0 1 2) '(1 2 3) '(2 3 4)) '(3 6 9))) (test-t (equal (cl-map 'list + '(0 1 2) '(1 2 3) '(2 3 4) '(3 4 5)) '(6 10 14))) (test-t (equal (cl-map 'list + '(1 2) '(1 2 3)) '(2 4))) (test-t (equal (cl-map 'list + '(0 1 2) '(2 3) '(2 3 4)) '(4 7))) (test-t (equal (cl-map 'list + '(0 1 2) '(1 2 3) '(2) '(3 4 5)) '(6))) (test-t (equal (cl-map 'list + '(0 1 2) '(1 2 3) '(2 3 4) '(3 4 5) ()) ())) (test-t (null (cl-map 'null + ()))) (test-t (equalp (cl-map 'vector + #()) #())) (test-t (equalp (cl-map 'vector + #() #()) #())) (test-t (equalp (cl-map 'vector + #() #() #()) #())) (test-t (equalp (cl-map 'vector + #() #() #() #()) #())) (test-t (equalp (cl-map 'vector + #() #() #() #() #()) #())) (test-t (equalp (cl-map 'vector + () #()) #())) (test-t (equalp (cl-map 'vector + () #() "") #())) (test-t (equalp (cl-map 'vector + '(0 1 2)) #(0 1 2))) (test-t (equalp (cl-map 'vector + '(0 1 2) #(1 2 3)) #(1 3 5))) (test-t (equalp (cl-map 'vector + #(0 1 2) '(1 2 3) #(2 3 4)) #(3 6 9))) (test-t (equalp (cl-map 'vector + '(0 1 2) #(1 2 3) '(2 3 4) #(3 4 5)) #(6 10 14))) (test-t (equalp (cl-map 'vector + '(1 2) '(1 2 3)) #(2 4))) (test-t (equalp (cl-map 'vector + '(0 1 2) '(2 3) '(2 3 4)) #(4 7))) (test-t (equalp (cl-map 'vector + '(0 1 2) '(1 2 3) '(2) '(3 4 5)) #(6))) (test-t (equalp (cl-map 'vector + '(0 1 2) '(1 2 3) '(2 3 4) '(3 4 5) ()) #())) (test-t (equalp (cl-map 'vector + #(1 2) #(1 2 3)) #(2 4))) (test-t (equalp (cl-map 'vector + #(0 1 2) #(2 3) #(2 3 4)) #(4 7))) (test-t (equalp (cl-map 'vector + #(0 1 2) '(1 2 3) #(2) '(3 4 5)) #(6))) (test-t (equalp (cl-map 'vector + '(0 1 2) #(1 2 3) '(2 3 4) '(3 4 5) ()) #())) (test-t (string= (cl-map 'string (lambda rest (char-upcase (car rest))) "") "")) (test-t (string= (cl-map 'string (lambda rest (char-upcase (car rest))) "" "") "")) (test-t (string= (cl-map 'string (lambda rest (char-upcase (car rest))) "" "" "") "")) (test-t (string= (cl-map 'string (lambda rest (char-upcase (car rest))) "" "" "" "") "")) (test-t (string= (cl-map 'string (lambda rest (char-upcase (car rest))) "" "" "" "" "") "")) (test-t (string= (cl-map 'string (lambda rest (char-upcase (car rest))) "") "")) (test-t (string= (cl-map 'string (lambda rest (char-upcase (car rest))) "" ()) "")) (test-t (string= (cl-map 'string (lambda rest (char-upcase (car rest))) "" #() ()) "")) (test-t (string= (cl-map 'string (lambda rest (char-upcase (car rest))) () () "" "") "")) (test-t (string= (cl-map 'string (lambda rest (char-upcase (car rest))) #() #() #() #() #()) "")) (test-t (string= (cl-map 'string (lambda (a b) (if (char< a b) b a)) "axbycz" "xaybzc") "xxyyzz")) (test-t (string= (cl-map 'string (lambda (a b) (if (char< a b) b a)) "axbycz" "xayb") "xxyy")) (test-t (let ((list ())) (and (null (cl-map nil (lambda rest (setq list (cons (apply + rest) list))) '(0 1 2 3) '(1 2 3 4))) (equal list '(7 5 3 1))))) (test-t (let ((list ())) (and (null (cl-map nil (lambda rest (setq list (cons (apply + rest) list))) '(0 1 2 3) '(1 2 3 4) '(2 3 4 5))) (equal list (cl-reverse '(3 6 9 12)))))) (test-t (let ((list ())) (and (null (cl-map nil (lambda rest (setq list (cons (apply + rest) list))) '(0 1 2 3) '(1) '(2 3 4 5))) (equal list '(3))))) (test-t (string= (cl-map 'string char-upcase "abc") "ABC")) (test-t (let ((a (list 1 2 3 4)) (b (list 10 10 10 10))) (and (equal (map-into a + a b) '(11 12 13 14)) (equal a '(11 12 13 14)) (equal b '(10 10 10 10))))) (test-t (let ((a '(11 12 13 14)) (k '(one two three))) (equal (map-into a cons k a) '((one . 11) (two . 12) (three . 13) 14)))) (test-t (null (map-into nil identity))) (test-t (null (map-into nil identity))) (test-t (null (map-into nil identity ()))) (test-t (null (map-into nil identity '(0 1 2) '(9 8 7)))) (test-t (let ((list (list 0 1 2))) (and (eq (map-into list identity) list) (equal list '(0 1 2))))) (test-t (let ((list (list 0 1 2))) (and (eq (map-into list identity ()) list) (equal list '(0 1 2))))) (test-t (let ((vec (vector 0 1 2))) (and (eq (map-into vec identity) vec) (equalp vec #(0 1 2))))) (test-t (let ((vec (vector 0 1 2))) (and (eq (map-into vec identity #()) vec) (equalp vec #(0 1 2))))) (test-t (let ((vec (vector 0 1 2))) (and (eq (map-into vec + #() () #()) vec) (equalp vec #(0 1 2))))) (test-t (equal (map-into (list nil nil) + '(0 1) '(1 0)) '(1 1))) (test-t (equal (map-into (list nil nil) - '(0 1) '(1 0)) '(-1 1))) (test-t (let ((list (cl-make-list 3 :initial-element nil))) (and (eq (map-into list + '(0 1 2)) list) (equal list '(0 1 2))))) (test-t (let ((list (cl-make-list 3 :initial-element nil))) (and (eq (map-into list + '(0 1 2) '(1 2 3)) list) (equal list '(1 3 5))))) (test-t (let ((list (cl-make-list 3 :initial-element nil))) (and (eq (map-into list + '(0 1 2) '(1 2 3) '(2 3 4)) list) (equal list '(3 6 9))))) (test-t (let ((list (cl-make-list 3 :initial-element nil))) (and (eq (map-into list + '(1 2) '(1 2 3)) list) (equal list '(2 4 ()))))) (test-t (let ((list (cl-make-list 1 :initial-element nil))) (and (eq (map-into list + '(1 2 3) '(1 2 3)) list) (equal list '(2))))) (test-t (let ((list (cl-make-list 3 :initial-element nil))) (and (eq (map-into list + '(1 2 3 4) '(1 2 3) '(0)) list) (equal list '(2 () ()))))) (test-t (let ((vec (make-sequence 'vector 3 :initial-element nil))) (and (eq (map-into vec + '(0 1 2)) vec) (equalp vec #(0 1 2))))) (test-t (let ((vec (make-sequence 'vector 3 :initial-element nil))) (and (eq (map-into vec + '(0 1 2) #(1 2 3)) vec) (equalp vec #(1 3 5))))) (test-t (let ((vec (make-sequence 'vector 3 :initial-element nil))) (and (eq (map-into vec + '(0 1 2) '(1 2 3) #(2 3 4)) vec) (equalp vec #(3 6 9))))) (test-t (let ((vec (make-sequence 'vector 3 :initial-element nil))) (and (eq (map-into vec + '(1 2) #(1 2 3)) vec) (equalp vec #(2 4 ()))))) (test-t (let ((vec (make-sequence 'vector 1 :initial-element nil))) (and (eq (map-into vec + '(1 2) #(1 2 3)) vec) (equalp vec #(2))))) (test-t (let ((vec (make-sequence 'vector 3 :initial-element nil))) (and (eq (map-into vec + '(1 2 3 4) #(1 2 3) '(0)) vec) (equalp vec #(2 () ()))))) (test-t (null (cl-reverse nil))) (test-t (string= (cl-reverse "") "")) (test-t (equalp (cl-reverse #()) #())) (test-t (equal (cl-reverse '(0 1 2 3)) '(3 2 1 0))) (test-t (string= (cl-reverse "0123") "3210")) (test-t (equalp (cl-reverse #(a b c d)) #(d c b a))) (test-t (null (nreverse nil))) (test-t (string= (nreverse (copy-seq "")) "")) (test-t (equalp (nreverse (copy-seq #())) #())) (test-t (equal (nreverse (list 0 1 2 3)) '(3 2 1 0))) (test-t (string= (nreverse (copy-seq "0123")) "3210")) (test-t (equalp (cl-reverse (copy-seq #(a b c d))) #(d c b a))) (test-t (char= (find #\d "edcba" :test char>) #\c)) (test-t (eql (find-if oddp '(1 2 3 4 5) :end 3 :from-end t) 3)) (test-t (eq (find 'a '(a b c)) 'a)) (test-t (eq (find 'b '(a b c)) 'b)) (test-t (eq (find 'c '(a b c)) 'c)) (test-t (null (find 'x '(a b c)))) (test-t (null (find 'a '(a b c) :start 1))) (test-t (null (find 'b '(a b c) :start 2))) (test-t (null (find 'c '(a b c) :start 3))) (test-t (null (find 'a '(a b c) :start 0 :end 0))) (test-t (null (find 'a '(a b c) :start 0 :end 0 :from-end t))) (test-t (null (find 'a '(a b c) :start 1 :end 1))) (test-t (null (find 'a '(a b c) :start 1 :end 1 :from-end t))) (test-t (null (find 'a '(a b c) :start 2 :end 2))) (test-t (null (find 'a '(a b c) :start 2 :end 2 :from-end t))) (test-t (null (find 'a '(a b c) :start 3 :end 3))) (test-t (null (find 'a '(a b c) :start 3 :end 3 :from-end t))) (test-t (eq (find 'a '(a b c) :end nil) 'a)) (test-t (eq (find 'b '(a b c) :end nil) 'b)) (test-t (eq (find 'c '(a b c) :end nil) 'c)) (test-t (eq (find 'a '(a b c) :end 1) 'a)) (test-t (eq (find 'b '(a b c) :end 2) 'b)) (test-t (eq (find 'c '(a b c) :end 3) 'c)) (test-t (null (find 'a '(a b c) :end 0))) (test-t (null (find 'b '(a b c) :end 1))) (test-t (null (find 'c '(a b c) :end 2))) (test-t (null (find 'a '((a) (b) (c))))) (test-t (equal (find 'a '((a) (b) (c)) :key car) '(a))) (test-t (equal (find 'b '((a) (b) (c)) :key car) '(b))) (test-t (equal (find 'c '((a) (b) (c)) :key car) '(c))) (test-t (null (find 'z '((a) (b) (c)) :key car))) (test-t (let ((list '((a) (b) (c)))) (and (eq (find 'a list :key car) (car list)) (eq (find 'b list :key car) (cadr list)) (eq (find 'c list :key car) (caddr list)) (null (find 'z list :key car))))) (test-t (null (find '(a) '((a) (b) (c))))) (test-t (equal (find '(a) '((a) (b) (c)) :test equal) '(a))) (test-t (null (find '("a") '(("a") ("b") ("c"))))) (test-t (null (find '("a") '(("A") ("B") ("c")) :test equal))) (test-t (eql (find 3 '(0 1 2 3 4 5)) 3)) (test-t (eql (find 3 '(0 1 2 3 4 5) :test <) 4)) (test-t (eql (find 3 '(0 1 2 3 4 5) :test >) 0)) (test-t (equal (find 'a '((a) (b) (c) (a a) (b b) (c c)) :key car) '(a))) (test-t (equal (find 'a '((a) (b) (c) (a a) (b b) (c c)) :key car :from-end t) '(a a))) (test-t (equal (find 'b '((a) (b) (c) (a a) (b b) (c c)) :key car) '(b))) (test-t (equal (find 'b '((a) (b) (c) (a a) (b b) (c c)) :key car :from-end t) '(b b))) (test-t (equal (find 'c '((a) (b) (c) (a a) (b b) (c c)) :key car) '(c))) (test-t (equal (find 'c '((a) (b) (c) (a a) (b b) (c c)) :key car :from-end t) '(c c))) (test-t (null (find 'z '((a) (b) (c) (a a) (b b) (c c)) :key car))) (test-t (null (find 'z '((a) (b) (c) (a a) (b b) (c c)) :key car :from-end t))) (test-t (equal (find 'a '((a) (b) (c) (a a) (b b) (c c) (a a a)) :key car :from-end t) '(a a a))) (test-t (equal (find 'a '((a) (b) (c) (a a) (b b) (c c) (a a a)) :key car :from-end t :end nil) '(a a a))) (test-t (equal (find 'a '((a) (b) (c) (a a) (b b) (c c) (a a a)) :key car :from-end t :end 6) '(a a))) (test-t (null (find 'a '((a) (b) (c) (a a) (b b) (c c) (a a a)) :key car :from-end t :start 1 :end 3))) (test-t (null (find #\c '("abc" "bcd" "cde")))) (test-t (string= (find #\c '("abc" "bcd" "cde") :key (lambda (arg) (char arg 0)) :test char=) "cde")) (test-t (eq (find 'a #(a b c)) 'a)) (test-t (eq (find 'b #(a b c)) 'b)) (test-t (eq (find 'c #(a b c)) 'c)) (test-t (null (find 'x #(a b c)))) (test-t (null (find 'a #(a b c) :start 1))) (test-t (null (find 'b #(a b c) :start 2))) (test-t (null (find 'c #(a b c) :start 3))) (test-t (null (find 'a #(a b c) :start 0 :end 0))) (test-t (null (find 'a #(a b c) :start 0 :end 0 :from-end t))) (test-t (null (find 'a #(a b c) :start 1 :end 1))) (test-t (null (find 'a #(a b c) :start 1 :end 1 :from-end t))) (test-t (null (find 'a #(a b c) :start 2 :end 2))) (test-t (null (find 'a #(a b c) :start 2 :end 2 :from-end t))) (test-t (null (find 'a #(a b c) :start 3 :end 3))) (test-t (null (find 'a #(a b c) :start 3 :end 3 :from-end t))) (test-t (eq (find 'a #(a b c) :end nil) 'a)) (test-t (eq (find 'b #(a b c) :end nil) 'b)) (test-t (eq (find 'c #(a b c) :end nil) 'c)) (test-t (eq (find 'a #(a b c) :end 1) 'a)) (test-t (eq (find 'b #(a b c) :end 2) 'b)) (test-t (eq (find 'c #(a b c) :end 3) 'c)) (test-t (null (find 'a #(a b c) :end 0))) (test-t (null (find 'b #(a b c) :end 1))) (test-t (null (find 'c #(a b c) :end 2))) (test-t (null (find 'a #((a) (b) (c))))) (test-t (equal (find 'a #((a) (b) (c)) :key car) '(a))) (test-t (equal (find 'b #((a) (b) (c)) :key car) '(b))) (test-t (equal (find 'c #((a) (b) (c)) :key car) '(c))) (test-t (null (find 'z #((a) (b) (c)) :key car))) (test-t (let ((vector #((a) (b) (c)))) (and (eq (find 'a vector :key car) (aref vector 0)) (eq (find 'b vector :key car) (aref vector 1)) (eq (find 'c vector :key car) (aref vector 2)) (null (find 'z vector :key car))))) (test-t (null (find '(a) #((a) (b) (c))))) (test-t (equal (find '(a) #((a) (b) (c)) :test equal) '(a))) (test-t (null (find '("a") #(("a") ("b") ("c"))))) (test-t (null (find '("a") #(("A") ("B") ("c")) :test equal))) (test-t (eql (find 3 #(0 1 2 3 4 5)) 3)) (test-t (eql (find 3 #(0 1 2 3 4 5) :test <) 4)) (test-t (eql (find 3 #(0 1 2 3 4 5) :test >) 0)) (test-t (equal (find 'a #((a) (b) (c) (a a) (b b) (c c)) :key car) '(a))) (test-t (equal (find 'a #((a) (b) (c) (a a) (b b) (c c)) :key car :from-end t) '(a a))) (test-t (equal (find 'b #((a) (b) (c) (a a) (b b) (c c)) :key car) '(b))) (test-t (equal (find 'b #((a) (b) (c) (a a) (b b) (c c)) :key car :from-end t) '(b b))) (test-t (equal (find 'c #((a) (b) (c) (a a) (b b) (c c)) :key car) '(c))) (test-t (equal (find 'c #((a) (b) (c) (a a) (b b) (c c)) :key car :from-end t) '(c c))) (test-t (null (find 'z #((a) (b) (c) (a a) (b b) (c c)) :key car))) (test-t (null (find 'z #((a) (b) (c) (a a) (b b) (c c)) :key car :from-end t))) (test-t (equal (find 'a #((a) (b) (c) (a a) (b b) (c c) (a a a)) :key car :from-end t) '(a a a))) (test-t (equal (find 'a #((a) (b) (c) (a a) (b b) (c c) (a a a)) :key car :from-end t :end nil) '(a a a))) (test-t (equal (find 'a #((a) (b) (c) (a a) (b b) (c c) (a a a)) :key car :from-end t :end 6) '(a a))) (test-t (null (find 'a #((a) (b) (c) (a a) (b b) (c c) (a a a)) :key car :from-end t :start 1 :end 3))) (test-t (null (find #\c #("abc" "bcd" "cde")))) (test-t (null (find #\z "abcABC"))) (test-t (eql (find #\a "abcABC") #\a)) (test-t (eql (find #\A "abcABC") #\A)) (test-t (eql (find #\A "abcABC" :test char-equal) #\a)) (test-t (eql (find #\A "abcABC" :test char-equal :from-end t) #\A)) (test-t (eql (find #\a "abcABC" :test char-equal :from-end t) #\A)) (test-t (eql (find #\a "abcABC" :test char-equal :from-end t :end 4) #\A)) (test-t (eql (find #\a "abcABC" :test char-equal :from-end t :end 3) #\a)) (test-t (eq (find-if (lambda (x) (eq x 'a)) '(a b c)) 'a)) (test-t (eq (find-if (lambda (x) (eq x 'b)) '(a b c)) 'b)) (test-t (eq (find-if (lambda (x) (eq x 'c)) '(a b c)) 'c)) (test-t (null (find-if (lambda (arg) (eq arg 'x)) '(a b c)))) (test-t (null (find-if (lambda (x) (eq x 'a)) '(a b c) :start 1))) (test-t (null (find-if (lambda (x) (eq x 'b)) '(a b c) :start 2))) (test-t (null (find-if (lambda (x) (eq x 'c)) '(a b c) :start 3))) (test-t (null (find-if (lambda (x) (eq x 'a)) '(a b c) :start 0 :end 0))) (test-t (null (find-if (lambda (x) (eq x 'a)) '(a b c) :start 0 :end 0 :from-end t))) (test-t (null (find-if (lambda (x) (eq x 'a)) '(a b c) :start 1 :end 1))) (test-t (null (find-if (lambda (x) (eq x 'a)) '(a b c) :start 1 :end 1 :from-end t))) (test-t (null (find-if (lambda (x) (eq x 'a)) '(a b c) :start 2 :end 2))) (test-t (null (find-if (lambda (x) (eq x 'a)) '(a b c) :start 2 :end 2 :from-end t))) (test-t (null (find-if (lambda (x) (eq x 'a)) '(a b c) :start 3 :end 3))) (test-t (null (find-if (lambda (x) (eq x 'a)) '(a b c) :start 3 :end 3 :from-end t))) (test-t (eq (find-if (lambda (x) (eq x 'a)) '(a b c) :end nil) 'a)) (test-t (eq (find-if (lambda (x) (eq x 'b)) '(a b c) :end nil) 'b)) (test-t (eq (find-if (lambda (x) (eq x 'c)) '(a b c) :end nil) 'c)) (test-t (eq (find-if (lambda (x) (eq x 'a)) '(a b c) :end 1) 'a)) (test-t (eq (find-if (lambda (x) (eq x 'b)) '(a b c) :end 2) 'b)) (test-t (eq (find-if (lambda (x) (eq x 'c)) '(a b c) :end 3) 'c)) (test-t (null (find-if (lambda (x) (eq x 'a)) '(a b c) :end 0))) (test-t (null (find-if (lambda (x) (eq x 'b)) '(a b c) :end 1))) (test-t (null (find-if (lambda (x) (eq x 'c)) '(a b c) :end 2))) (test-t (null (find-if (lambda (x) (eq x 'a)) '((a) (b) (c))))) (test-t (equal (find-if (lambda (x) (eq x 'a)) '((a) (b) (c)) :key car) '(a))) (test-t (equal (find-if (lambda (x) (eq x 'b)) '((a) (b) (c)) :key car) '(b))) (test-t (equal (find-if (lambda (x) (eq x 'c)) '((a) (b) (c)) :key car) '(c))) (test-t (null (find-if (lambda (x) (eq x 'z)) '((a) (b) (c)) :key car))) (test-t (let ((list '((a) (b) (c)))) (and (eq (find-if (lambda (x) (eq x 'a)) list :key car) (car list)) (eq (find-if (lambda (x) (eq x 'b)) list :key car) (cadr list)) (eq (find-if (lambda (x) (eq x 'c)) list :key car) (caddr list)) (null (find-if (lambda (x) (eq x 'z)) list :key car))))) (test-t (equal (find-if (lambda (x) (eq x 'a)) '((a) (b) (c) (a a) (b b) (c c)) :key car) '(a))) (test-t (equal (find-if (lambda (x) (eq x 'a)) '((a) (b) (c) (a a) (b b) (c c)) :key car :from-end t) '(a a))) (test-t (equal (find-if (lambda (x) (eq x 'b)) '((a) (b) (c) (a a) (b b) (c c)) :key car) '(b))) (test-t (equal (find-if (lambda (x) (eq x 'b)) '((a) (b) (c) (a a) (b b) (c c)) :key car :from-end t) '(b b))) (test-t (equal (find-if (lambda (x) (eq x 'c)) '((a) (b) (c) (a a) (b b) (c c)) :key car) '(c))) (test-t (equal (find-if (lambda (x) (eq x 'c)) '((a) (b) (c) (a a) (b b) (c c)) :key car :from-end t) '(c c))) (test-t (null (find-if (lambda (x) (eq x 'z)) '((a) (b) (c) (a a) (b b) (c c)) :key car))) (test-t (null (find-if (lambda (x) (eq x 'z)) '((a) (b) (c) (a a) (b b) (c c)) :key car :from-end t))) (test-t (equal (find-if (lambda (x) (eq x 'a)) '((a) (b) (c) (a a) (b b) (c c) (a a a)) :key car :from-end t) '(a a a))) (test-t (equal (find-if (lambda (x) (eq x 'a)) '((a) (b) (c) (a a) (b b) (c c) (a a a)) :key car :from-end t :end nil) '(a a a))) (test-t (equal (find-if (lambda (x) (eq x 'a)) '((a) (b) (c) (a a) (b b) (c c) (a a a)) :key car :from-end t :end 6) '(a a))) (test-t (null (find-if (lambda (x) (eq x 'a)) '((a) (b) (c) (a a) (b b) (c c) (a a a)) :key car :from-end t :start 1 :end 3))) (test-t (eq (find-if (lambda (x) (eq x 'a)) #(a b c)) 'a)) (test-t (eq (find-if (lambda (x) (eq x 'b)) #(a b c)) 'b)) (test-t (eq (find-if (lambda (x) (eq x 'c)) #(a b c)) 'c)) (test-t (null (find-if (lambda (arg) (eq arg 'x)) #(a b c)))) (test-t (null (find-if (lambda (x) (eq x 'a)) #(a b c) :start 1))) (test-t (null (find-if (lambda (x) (eq x 'b)) #(a b c) :start 2))) (test-t (null (find-if (lambda (x) (eq x 'c)) #(a b c) :start 3))) (test-t (null (find-if (lambda (x) (eq x 'a)) #(a b c) :start 0 :end 0))) (test-t (null (find-if (lambda (x) (eq x 'a)) #(a b c) :start 0 :end 0 :from-end t))) (test-t (null (find-if (lambda (x) (eq x 'a)) #(a b c) :start 1 :end 1))) (test-t (null (find-if (lambda (x) (eq x 'a)) #(a b c) :start 1 :end 1 :from-end t))) (test-t (null (find-if (lambda (x) (eq x 'a)) #(a b c) :start 2 :end 2))) (test-t (null (find-if (lambda (x) (eq x 'a)) #(a b c) :start 2 :end 2 :from-end t))) (test-t (null (find-if (lambda (x) (eq x 'a)) #(a b c) :start 3 :end 3))) (test-t (null (find-if (lambda (x) (eq x 'a)) #(a b c) :start 3 :end 3 :from-end t))) (test-t (eq (find-if (lambda (x) (eq x 'a)) #(a b c) :end nil) 'a)) (test-t (eq (find-if (lambda (x) (eq x 'b)) #(a b c) :end nil) 'b)) (test-t (eq (find-if (lambda (x) (eq x 'c)) #(a b c) :end nil) 'c)) (test-t (eq (find-if (lambda (x) (eq x 'a)) #(a b c) :end 1) 'a)) (test-t (eq (find-if (lambda (x) (eq x 'b)) #(a b c) :end 2) 'b)) (test-t (eq (find-if (lambda (x) (eq x 'c)) #(a b c) :end 3) 'c)) (test-t (null (find-if (lambda (x) (eq x 'a)) #(a b c) :end 0))) (test-t (null (find-if (lambda (x) (eq x 'b)) #(a b c) :end 1))) (test-t (null (find-if (lambda (x) (eq x 'c)) #(a b c) :end 2))) (test-t (null (find-if (lambda (x) (eq x 'a)) #((a) (b) (c))))) (test-t (equal (find-if (lambda (x) (eq x 'a)) #((a) (b) (c)) :key car) '(a))) (test-t (equal (find-if (lambda (x) (eq x 'b)) #((a) (b) (c)) :key car) '(b))) (test-t (equal (find-if (lambda (x) (eq x 'c)) #((a) (b) (c)) :key car) '(c))) (test-t (null (find-if (lambda (x) (eq x 'z)) #((a) (b) (c)) :key car))) (test-t (let ((vector #((a) (b) (c)))) (and (eq (find-if (lambda (x) (eq x 'a)) vector :key car) (aref vector 0)) (eq (find-if (lambda (x) (eq x 'b)) vector :key car) (aref vector 1)) (eq (find-if (lambda (x) (eq x 'c)) vector :key car) (aref vector 2)) (null (find-if (lambda (x) (eq x 'z)) vector :key car))))) (test-t (equal (find-if (lambda (x) (eq x 'a)) #((a) (b) (c) (a a) (b b) (c c)) :key car) '(a))) (test-t (equal (find-if (lambda (x) (eq x 'a)) #((a) (b) (c) (a a) (b b) (c c)) :key car :from-end t) '(a a))) (test-t (equal (find-if (lambda (x) (eq x 'b)) #((a) (b) (c) (a a) (b b) (c c)) :key car) '(b))) (test-t (equal (find-if (lambda (x) (eq x 'b)) #((a) (b) (c) (a a) (b b) (c c)) :key car :from-end t) '(b b))) (test-t (equal (find-if (lambda (x) (eq x 'c)) #((a) (b) (c) (a a) (b b) (c c)) :key car) '(c))) (test-t (equal (find-if (lambda (x) (eq x 'c)) #((a) (b) (c) (a a) (b b) (c c)) :key car :from-end t) '(c c))) (test-t (null (find-if (lambda (x) (eq x 'z)) #((a) (b) (c) (a a) (b b) (c c)) :key car))) (test-t (null (find-if (lambda (x) (eq x 'z)) #((a) (b) (c) (a a) (b b) (c c)) :key car :from-end t))) (test-t (equal (find-if (lambda (x) (eq x 'a)) #((a) (b) (c) (a a) (b b) (c c) (a a a)) :key car :from-end t) '(a a a))) (test-t (equal (find-if (lambda (x) (eq x 'a)) #((a) (b) (c) (a a) (b b) (c c) (a a a)) :key car :from-end t :end nil) '(a a a))) (test-t (equal (find-if (lambda (x) (eq x 'a)) #((a) (b) (c) (a a) (b b) (c c) (a a a)) :key car :from-end t :end 6) '(a a))) (test-t (null (find-if (lambda (x) (eq x 'a)) #((a) (b) (c) (a a) (b b) (c c) (a a a)) :key car :from-end t :start 1 :end 3))) (test-t (let ((lst (copy-seq "012345678"))) (and (equal (replace lst lst :start1 2 :start2 0) "010123456") (equal lst "010123456")))) (test-t (let* ((list0 (list 'a 'b 'c 'd 'e)) (list (replace list0 '(x y z)))) (and (eq list0 list) (equal list0 '(x y z d e))))) (test-t (let* ((list0 (list 'a 'b 'c 'd 'e)) (list (replace list0 '(x y z) :start1 1))) (and (eq list0 list) (equal list0 '(a x y z e))))) (test-t (let* ((list0 (list 'a 'b 'c 'd 'e)) (list (replace list0 '(x y z) :start1 1 :end1 nil))) (and (eq list0 list) (equal list0 '(a x y z e))))) (test-t (let* ((list0 (list 'a 'b 'c 'd 'e)) (list (replace list0 '(x y z) :start1 1 :start2 1))) (and (eq list0 list) (equal list0 '(a y z d e))))) (test-t (let* ((list0 (list 'a 'b 'c 'd 'e)) (list (replace list0 '(x y z) :start1 1 :start2 1 :end2 nil))) (and (eq list0 list) (equal list0 '(a y z d e))))) (test-t (let* ((list0 (list 'a 'b 'c 'd 'e)) (list (replace list0 '(x y z) :start1 1 :end1 nil :start2 1 :end2 nil))) (and (eq list0 list) (equal list0 '(a y z d e))))) (test-t (let* ((list0 (list 'a 'b 'c 'd 'e)) (list (replace list0 '(x y z) :start1 1 :end1 2 :start2 1))) (and (eq list0 list) (equal list0 '(a y c d e))))) (test-t (let* ((list0 (list 'a 'b 'c 'd 'e)) (list (replace list0 '(x y z) :start1 1 :end1 1))) (and (eq list0 list) (equal list0 '(a b c d e))))) (test-t (let* ((list0 (list 'a 'b 'c 'd 'e)) (list (replace list0 '(x y z) :start1 2 :end1 2))) (and (eq list0 list) (equal list0 '(a b c d e))))) (test-t (let* ((list0 (list 'a 'b 'c 'd 'e)) (list (replace list0 '(x y z) :start1 3 :end1 3))) (and (eq list0 list) (equal list0 '(a b c d e))))) (test-t (let* ((list0 (list 'a 'b 'c 'd 'e)) (list (replace list0 '(x y z) :start1 4 :end1 4))) (and (eq list0 list) (equal list0 '(a b c d e))))) (test-t (let* ((list0 (list 'a 'b 'c 'd 'e)) (list (replace list0 '(x y z) :start1 5 :end1 5))) (and (eq list0 list) (equal list0 '(a b c d e))))) (test-t (null (replace nil nil))) (test-t (null (replace nil '(a b c)))) (test-t (let* ((list0 (list 'a 'b 'c)) (list (replace list0 ()))) (and (eq list0 list) (equal list0 '(a b c))))) (test-t (let* ((list0 (list 'a 'b 'c 'd 'e)) (list (replace list0 list0))) (and (eq list0 list) (equal list0 '(a b c d e))))) (test-t (let* ((list0 (list 'a 'b 'c 'd 'e)) (list (replace list0 list0 :start1 3))) (and (eq list0 list) (equal list0 '(a b c a b))))) (test-t (let* ((list0 (list 'a 'b 'c 'd 'e)) (list (replace list0 list0 :start1 1))) (and (eq list0 list) (equal list0 '(a a b c d))))) (test-t (let* ((list0 (list 'a 'b 'c 'd 'e)) (list (replace list0 list0 :start1 1 :end1 3))) (and (eq list0 list) (equal list0 '(a a b d e))))) (test-t (let* ((list0 (list 'a 'b 'c)) (list (replace list0 '(x y z)))) (and (eq list0 list) (equal list0 '(x y z))))) (test-t (let* ((vector0 (vector 'a 'b 'c 'd 'e)) (vector (replace vector0 '(x y z)))) (and (eq vector0 vector) (equalp vector0 #(x y z d e))))) (test-t (let* ((vector0 (vector 'a 'b 'c 'd 'e)) (vector (replace vector0 '(x y z) :start1 1))) (and (eq vector0 vector) (equalp vector0 #(a x y z e))))) (test-t (let* ((vector0 (vector 'a 'b 'c 'd 'e)) (vector (replace vector0 '(x y z) :start1 1 :end1 nil))) (and (eq vector0 vector) (equalp vector0 #(a x y z e))))) (test-t (let* ((vector0 (vector 'a 'b 'c 'd 'e)) (vector (replace vector0 '(x y z) :start1 1 :start2 1))) (and (eq vector0 vector) (equalp vector0 #(a y z d e))))) (test-t (let* ((vector0 (vector 'a 'b 'c 'd 'e)) (vector (replace vector0 '(x y z) :start1 1 :start2 1 :end2 nil))) (and (eq vector0 vector) (equalp vector0 #(a y z d e))))) (test-t (let* ((vector0 (vector 'a 'b 'c 'd 'e)) (vector (replace vector0 '(x y z) :start1 1 :end1 nil :start2 1 :end2 nil))) (and (eq vector0 vector) (equalp vector0 #(a y z d e))))) (test-t (let* ((vector0 (vector 'a 'b 'c 'd 'e)) (vector (replace vector0 '(x y z) :start1 1 :end1 2 :start2 1))) (and (eq vector0 vector) (equalp vector0 #(a y c d e))))) (test-t (let* ((vector0 (vector 'a 'b 'c 'd 'e)) (vector (replace vector0 '(x y z) :start1 1 :end1 1))) (and (eq vector0 vector) (equalp vector0 #(a b c d e))))) (test-t (let* ((vector0 (vector 'a 'b 'c 'd 'e)) (vector (replace vector0 '(x y z) :start1 2 :end1 2))) (and (eq vector0 vector) (equalp vector0 #(a b c d e))))) (test-t (let* ((vector0 (vector 'a 'b 'c 'd 'e)) (vector (replace vector0 '(x y z) :start1 3 :end1 3))) (and (eq vector0 vector) (equalp vector0 #(a b c d e))))) (test-t (let* ((vector0 (vector 'a 'b 'c 'd 'e)) (vector (replace vector0 '(x y z) :start1 4 :end1 4))) (and (eq vector0 vector) (equalp vector0 #(a b c d e))))) (test-t (let* ((vector0 (vector 'a 'b 'c 'd 'e)) (vector (replace vector0 '(x y z) :start1 5 :end1 5))) (and (eq vector0 vector) (equalp vector0 #(a b c d e))))) (test-t (null (replace nil #()))) (test-t (null (replace nil #(a b c)))) (test-t (let* ((vector0 (vector 'a 'b 'c)) (vector (replace vector0 ()))) (and (eq vector0 vector) (equalp vector0 #(a b c))))) (test-t (let* ((vector0 (vector 'a 'b 'c 'd 'e)) (vector (replace vector0 vector0))) (and (eq vector0 vector) (equalp vector0 #(a b c d e))))) (test-t (let* ((vector0 (vector 'a 'b 'c 'd 'e)) (vector (replace vector0 vector0 :start1 3))) (and (eq vector0 vector) (equalp vector0 #(a b c a b))))) (test-t (let* ((vector0 (vector 'a 'b 'c 'd 'e)) (vector (replace vector0 vector0 :start1 1))) (and (eq vector0 vector) (equalp vector0 #(a a b c d))))) (test-t (let* ((vector0 (vector 'a 'b 'c 'd 'e)) (vector (replace vector0 vector0 :start1 1 :end1 3))) (and (eq vector0 vector) (equalp vector0 #(a a b d e))))) (test-t (let* ((vector0 (vector 'a 'b 'c)) (vector (replace vector0 '(x y z)))) (and (eq vector0 vector) (equalp vector0 #(x y z))))) (test-t (let* ((vector0 (vector 'a 'b 'c 'd 'e)) (vector (replace vector0 #(x y z)))) (and (eq vector0 vector) (equalp vector0 #(x y z d e))))) (test-t (let* ((vector0 (vector 'a 'b 'c 'd 'e)) (vector (replace vector0 #(x y z) :start1 1))) (and (eq vector0 vector) (equalp vector0 #(a x y z e))))) (test-t (let* ((vector0 (vector 'a 'b 'c 'd 'e)) (vector (replace vector0 #(x y z) :start1 1 :end1 nil))) (and (eq vector0 vector) (equalp vector0 #(a x y z e))))) (test-t (let* ((vector0 (vector 'a 'b 'c 'd 'e)) (vector (replace vector0 #(x y z) :start1 1 :start2 1))) (and (eq vector0 vector) (equalp vector0 #(a y z d e))))) (test-t (let* ((vector0 (vector 'a 'b 'c 'd 'e)) (vector (replace vector0 #(x y z) :start1 1 :start2 1 :end2 nil))) (and (eq vector0 vector) (equalp vector0 #(a y z d e))))) (test-t (let* ((vector0 (vector 'a 'b 'c 'd 'e)) (vector (replace vector0 #(x y z) :start1 1 :end1 nil :start2 1 :end2 nil))) (and (eq vector0 vector) (equalp vector0 #(a y z d e))))) (test-t (let* ((vector0 (vector 'a 'b 'c 'd 'e)) (vector (replace vector0 #(x y z) :start1 1 :end1 2 :start2 1))) (and (eq vector0 vector) (equalp vector0 #(a y c d e))))) (test-t (let* ((vector0 (vector 'a 'b 'c 'd 'e)) (vector (replace vector0 #(x y z) :start1 1 :end1 1))) (and (eq vector0 vector) (equalp vector0 #(a b c d e))))) (test-t (let* ((vector0 (vector 'a 'b 'c 'd 'e)) (vector (replace vector0 #(x y z) :start1 2 :end1 2))) (and (eq vector0 vector) (equalp vector0 #(a b c d e))))) (test-t (let* ((vector0 (vector 'a 'b 'c 'd 'e)) (vector (replace vector0 #(x y z) :start1 3 :end1 3))) (and (eq vector0 vector) (equalp vector0 #(a b c d e))))) (test-t (let* ((vector0 (vector 'a 'b 'c 'd 'e)) (vector (replace vector0 #(x y z) :start1 4 :end1 4))) (and (eq vector0 vector) (equalp vector0 #(a b c d e))))) (test-t (let* ((vector0 (vector 'a 'b 'c 'd 'e)) (vector (replace vector0 #(x y z) :start1 5 :end1 5))) (and (eq vector0 vector) (equalp vector0 #(a b c d e))))) (test-t (null (replace nil #()))) (test-t (null (replace nil #(a b c)))) (test-t (let* ((vector0 (vector 'a 'b 'c)) (vector (replace vector0 #()))) (and (eq vector0 vector) (equalp vector0 #(a b c))))) (test-t (let* ((vector0 (vector 'a 'b 'c 'd 'e)) (vector (replace vector0 vector0))) (and (eq vector0 vector) (equalp vector0 #(a b c d e))))) (test-t (let* ((vector0 (vector 'a 'b 'c 'd 'e)) (vector (replace vector0 vector0 :start1 3))) (and (eq vector0 vector) (equalp vector0 #(a b c a b))))) (test-t (let* ((vector0 (vector 'a 'b 'c 'd 'e)) (vector (replace vector0 vector0 :start1 1))) (and (eq vector0 vector) (equalp vector0 #(a a b c d))))) (test-t (let* ((vector0 (vector 'a 'b 'c 'd 'e)) (vector (replace vector0 vector0 :start1 1 :end1 3))) (and (eq vector0 vector) (equalp vector0 #(a a b d e))))) (test-t (let* ((vector0 (vector 'a 'b 'c)) (vector (replace vector0 #(x y z)))) (and (eq vector0 vector) (equalp vector0 #(x y z))))) (test-t (let* ((str0 (copy-seq "abc")) (str (replace str0 "xyz"))) (and (eq str0 str) (equalp str0 "xyz")))) (test-t (let* ((str0 (copy-seq "")) (str (replace str0 ""))) (and (eq str0 str) (equalp str0 "")))) (test-t (let* ((str0 (copy-seq "")) (str (replace str0 "xyz"))) (and (eq str0 str) (equalp str0 "")))) (test-t (let* ((str0 (copy-seq "abc")) (str (replace str0 ""))) (and (eq str0 str) (equalp str0 "abc")))) (test-t (let* ((str0 (copy-seq "abcdef")) (str (replace str0 "xyz" :start1 3))) (and (eq str0 str) (equalp str0 "abcxyz")))) (test-t (let* ((str0 (copy-seq "abcdef")) (str (replace str0 "xyz" :start1 4 :start2 1))) (and (eq str0 str) (equalp str0 "abcdyz")))) (test-t (let* ((str0 (copy-seq "abcdef")) (str (replace str0 "xyz" :start1 1 :end1 2 :start2 1))) (and (eq str0 str) (equalp str0 "aycdef")))) (test-t (let* ((str0 (copy-seq "abcdef")) (str (replace str0 "xyz" :start1 1 :start2 1 :end2 2))) (and (eq str0 str) (equalp str0 "aycdef")))) (test-t (let* ((str0 (copy-seq "abcdef")) (str (replace str0 str0 :start1 1))) (and (eq str0 str) (equalp str0 "aabcde")))) (test-t (string= (concatenate 'string "all" " " "together" " " "now") "all together now")) (test-t (equal (concatenate 'list () '(a b c) '(x y z)) '(a b c x y z))) (test-t (equal (concatenate 'list '(a) #(b) '(c) #(x y) '(z)) '(a b c x y z))) (test-t (null (concatenate 'list))) (test-t (let* ((list0 '(a b c)) (list (concatenate 'list list0))) (and (not (eq list0 list)) (equal list list0) (equal list '(a b c))))) (test-t (equalp (concatenate 'vector () '(a b c) '(x y z)) #(a b c x y z))) (test-t (equalp (concatenate 'vector '(a) #(b) '(c) #(x y) '(z)) #(a b c x y z))) (test-t (equalp (concatenate 'vector) #())) (test-t (let* ((vector0 #(a b c)) (vector (concatenate 'vector vector0))) (and (not (eq vector0 vector)) (equalp vector vector0) (equalp vector #(a b c))))) (test-t (string= (concatenate 'string "abc" "def" "ghi" "jkl" "mno" "pqr") "abcdefghijklmnopqr")) (test-t (string= (concatenate 'string "" "abc" "" "def" "" "ghi" "" "" "jkl" "" "mno" "" "pqr" "" "") "abcdefghijklmnopqr")) (test-t (string= (concatenate 'string) "")) (test-t (string= (concatenate 'string "abc" '(#\d #\e #\f #\g) #(#\h #\i #\j #\k #\l)) "abcdefghijkl")) ;; ;; ----------------------------------- end sacla --------------------------------------------- ;; (let ((boole-n-vector (vector boole-clr boole-and boole-andc1 boole-2 boole-andc2 boole-1 boole-xor boole-ior boole-nor boole-eqv boole-c1 boole-orc1 boole-c2 boole-orc2 boole-nand boole-set))) (do ((n 0 (+ n 1))) ((= n 16)) (if (not (= n (logand (boole (boole-n-vector n) #b0101 #b0011) #b1111))) (format-logged #t "~A: ~A ~A~%" n (boole-n-vector n) (logand (boole (boole-n-vector n) #b0101 #b0011) #b1111)))) (let ((lst ())) (do ((n #b0000 (+ n 1))) ((> n #b1111)) (set! lst (cons (boole (boole-n-vector n) 5 3) lst))) (if (not (equal? (reverse lst) (list 0 1 2 3 4 5 6 7 -8 -7 -6 -5 -4 -3 -2 -1))) (format-logged #t ";boole: ~A~%" (reverse lst))))) (test (digit-char-p #\a) #f) (test (digit-char-p #\a 16) 10) (test (let ((v (vector 1 2 3 4 5))) (cl-fill v 32 :start 2 :end 3)) #(1 2 32 4 5)) (test (let ((v (vector 1 2 3 4 5))) (cl-fill v 32 :start 2)) #(1 2 32 32 32)) (test (let ((v (vector 1 2 3))) (cl-fill v 32)) #(32 32 32)) (test (let ((lst (list 1 2 3))) (cl-fill lst "hi")) '("hi" "hi" "hi")) (test (some zero? '(1 2 3)) #f) (test (some zero? '(1 0 3)) #t) (test (some (lambda args (apply > args)) #(1 2 3) #(2 3 4)) #f) (test (some (lambda args (apply > args)) #(1 2 3) #(2 3 1)) #t) (test (some (lambda (a) (and (positive? a) a)) '(0 -3 1 2)) 1) (test (notany zero? '(1 2 3)) #t) (test (notany zero? '(1 0 3)) #f) (test (notany (lambda args (apply > args)) #(1 2 3) #(2 3 4)) #t) (test (notany (lambda args (apply > args)) #(1 2 3) #(2 3 1)) #f) (test (notany (lambda (a) (and (positive? a) a)) '(0 -3 1 2)) #f) (test (every zero? '(1 2 3)) #f) (test (every zero? '(0 0)) #t) (test (every (lambda args (apply < args)) #(1 2 3) #(2 3 4)) #t) (test (every (lambda args (apply < args)) #(1 2 3) #(2 3 1)) #f) (test (notevery zero? '(1 2 3)) #t) (test (notevery zero? '(0 0)) #f) (test (notevery (lambda args (apply < args)) #(1 2 3) #(2 3 4)) #f) (test (notevery (lambda args (apply < args)) #(1 2 3) #(2 3 1)) #t) (test ((complement >) 1 2 3) #t) (test (cl-abs -1) 1) (test (cl-abs 1.0) 1.0) (test (cl-abs 1+i) (magnitude 1+i)) (test (signum 3) 1) (test (signum 0) 0) (test (signum -3) -1) (test (signum 3.0) 1.0) (test (isqrt 12) 3) (test (1+ 1) 2) (test (1- 1) 0) (test (/= 0 0) #f) (test (/= 1 2 3) #t) (test (/= 3 45 3) #f) (test (zerop 0) #t) (test (zerop 1) #f) (test (minusp -1) #t) (test (minusp 1) #f) (test (plusp 1) #t) (test (plusp -1) #f) (test (oddp 3) #t) (test (oddp 4) #f) (test (evenp 3) #f) (test (evenp 4) #t) (test (conjugate 1+i) 1-i) (test (conjugate 3.7) 3.7) (test (ldb (byte 8 8) #x123) 1) (test (ldb (byte 8 0) #x123) #x23) (test (ldb (byte 4 4) #x123) 2) (test (ldb (byte 1 4) #x123) 0) (test (ldb (byte 1 5) #x123) 1) (test (ldb (byte 16 16) -1) 65535) (test (ldb (byte 12 18) #x12345678) 1165) (test (dpb 1 (byte 8 0) #x100) #x101) (test (dpb #x22 (byte 8 1) #x100) #x44) ;! (test (dpb #x22 (byte 8 8) #x100) #x2200) ; not #x2300 (test (dpb #x1001 (byte 16 0) -1) -61439) (test (dpb #x1 (byte 8 8) #xffffff) #xff01ff) (test (dpb #x1 (byte 8 16) #xffffff) #x1ffff) (test (dpb #x1 (byte 8 16) #xffffffff) #xff01ffff) (test (dpb -1 (byte 8 0) 0) 255) (test (dpb -1 (byte 8 2) 0) 1020) (test (dpb 0 (byte 16 16) #xffffffff) 65535) (test (mask-field (byte 8 8) #xfffffff) #xff00) (test (mask-field (byte 1 8) #xfffffff) #x100) (test (ldb-test (byte 1 8) #xfffffff) #t) (test (ldb-test (byte 1 8) #x10ff) #f) (test (deposit-field #xabcdef (byte 8 8) 0) #xcd00) (test (deposit-field #xabcdef (byte 8 4) 0) #xde0) (test (deposit-field #xabcdef (byte 8 8) #xffffffff) #xffffcdff) (test (identity 1) 1) (test (stringp "hi") #t) (test (stringp #\h) #f) (test (characterp #\a) #t) (test (characterp "a") #f) (test (realp 1) #t) (test (realp 3.14) #t) (test (realp 1.0+i) #f) (test (complexp 1) #f) (test (complexp 1.0+i) #t) (test (floatp 1) #f) (test (floatp 3.14) #t) (test (rationalp 1) #t) (test (rationalp 1.12) #f) (test (rationalp 3/4) #t) (test (rationalp "hiho") #f) (test (integerp "hiho") #f) (test (integerp 3.14) #f) (test (integerp 3) #t) (test (numberp 3) #t) (test (numberp "hiho") #f) (test (consp ()) #f) (test (consp '(1 2)) #t) (test (consp 3) #f) (test (atom 3) #t) (test (atom ()) #t) (test (atom '(1 2 3)) #f) (test (vectorp #(1 2 3)) #t) (test (vectorp "hiho") #f) (test (symbolp 'hi) #t) (test (symbolp "hiho") #f) (test (last '(1 2 3)) '(3)) (test (last ()) ()) (test (tree-equal () ()) #t) (test (tree-equal (list 1 2 (list 3 5) 5) (list 1 2 (list 3 4) 5)) #f) (test (tree-equal (list 1 2 (list 3 4) 5) (list 1 2 (list 3 4) 5)) #t) (test (nthcdr 0 '(1 2 3)) '(1 2 3)) (test (nthcdr 2 '(1 2 3)) '(3)) (test (nthcdr 4 '(1 2 3)) ()) (test (listp ()) #t) (test (listp 3) #f) (test (listp '(1 . 2)) #t) (test (listp (list 1 2)) #t) (test (null ()) #t) (test (null '(1 2 3)) #f) (test (butlast '(1 2 3 4)) '(1 2 3)) (test (butlast '((1 2) (3 4))) '((1 2))) (test (butlast '(1)) ()) (test (butlast ()) ()) (test (copy-list ()) ()) (test (copy-list '(1 2 3)) '(1 2 3)) (test (copy-tree '(1 (2 3) 4)) '(1 (2 3) 4)) (test (rest '(1 2 3)) '(2 3)) (test (let ((i1 1) (i2 2)) (setf i1 3) (list i1 i2)) (list 3 2)) (test (let ((i1 1) (i2 2)) (setf i1 123 i2 32) (list i1 i2)) (list 123 32)) (test (let ((hi (vector 1 2 3))) (setf (hi 0) (+ 1 2) (hi 2) (* 2 3)) hi) (vector 3 2 6)) (test (let ((val 0)) (progn (+ val 1))) 1) (test (let ((val 0)) (prog1 (+ val 1) (+ val 2))) 1) (test (let ((val 0)) (prog2 (+ val 1) (+ val 2) (+ val 3))) 2) (test (let ((lst (list 1))) (push 2 lst)) (list 2 1)) (test (let ((lst (list 1 2 3))) (list (pop lst) lst)) (list 1 (list 2 3))) (test (let ((x 0)) (incf x) x) 1) (test (let ((x 0)) (incf x 2) x) 2) (test (let ((x 0)) (decf x) x) -1) (test (let ((x 0)) (decf x 2) x) -2) (test (let ((lst (list 1 2))) (pushnew 1 lst)) (list 1 2)) (test (let ((lst (list 1 2))) (pushnew 3 lst)) (list 3 1 2)) (test (let ((a 1) (b 2)) (psetq a b b a) (list a b)) '(2 1)) (test (let ((a 1) (b 2) (c 3)) (psetq a (+ b c) b (+ a c) c (+ a b)) (list a b c)) '(5 4 3)) (test (let ((val #f)) (unless val 1)) 1) (test (let ((val (list 1 2 3 4 5 6 7 8 9 10))) (first val)) 1) (test (let ((val (list 1 2 3 4 5 6 7 8 9 10))) (second val)) 2) (test (let ((val (list 1 2 3 4 5 6 7 8 9 10))) (third val)) 3) (test (let ((val (list 1 2 3 4 5 6 7 8 9 10))) (fourth val)) 4) (test (let ((val (list 1 2 3 4 5 6 7 8 9 10))) (fifth val)) 5) (test (let ((val (list 1 2 3 4 5 6 7 8 9 10))) (sixth val)) 6) (test (let ((val (list 1 2 3 4 5 6 7 8 9 10))) (seventh val)) 7) (test (let ((val (list 1 2 3 4 5 6 7 8 9 10))) (eighth val)) 8) (test (let ((val (list 1 2 3 4 5 6 7 8 9 10))) (ninth val)) 9) (test (let ((val (list 1 2 3 4 5 6 7 8 9 10))) (tenth val)) 10) (test (let ((val (list 1 2 3 4 5 6 7 8 9 10))) (nth 7 val)) 8) (test (let ((val (list 1 2 3 4 5 6 7 8 9 10))) (nth 17 val)) ()) (test (let*-values (((x) (values 1))) x) 1) (test (let*-values ((x (values 1))) x) '(1)) (test (let*-values (((x) (values 1)) ((y) (values 2))) (list x y)) '(1 2)) (test (let*-values (((x) (values 1)) ((y) (values (+ x 1)))) (list x y)) '(1 2)) (test (let () (enum one two three) (list one two three)) '(0 1 2)) (test (let () (defstruct x1 a b c) (let ((xx1 (make-x1 1 2 3))) (list (x1-a xx1) (x1-b xx1) (x1-c xx1) (x1? xx1)))) '(1 2 3 #t)) (test (let () (defstruct x1 a (b "hi") (c 3/4)) (let ((xx1 (make-x1 1))) (list (x1-a xx1) (x1-b xx1) (x1-c xx1) (x1? xx1)))) '(1 "hi" 3/4 #t)) (test (let () (defstruct x1 a (b "hi") (c 3/4)) (let ((xx1 (make-x1 :b 1))) (list (x1-a xx1) (x1-b xx1) (x1-c xx1) (x1? xx1)))) '(#f 1 3/4 #t)) (test (let () (defstruct x1 a b c) (let ((xx1 (make-x1 1 2 3))) (set! (x1-a xx1) 32) (list (x1-a xx1) (x1-b xx1) (x1-c xx1)))) '(32 2 3)) (let () (defstruct ship (x 0.0) (y 0.0 :type 'real)) (test (let ((s1 (make-ship 1.0 2.0))) (let ((s2 (copy-ship s1))) (list (ship-x s2) (ship-y s2)))) '(1.0 2.0)) (test (let ((s3 (make-ship :y 1.0 :x 2.0))) (list (ship-x s3) (ship-y s3))) '(2.0 1.0))) (let() (defstruct ship1 x y) (let ((s1 (make-ship1 "hi" (list 1 2 3)))) (let ((s2 (copy-ship1 s1))) (test (list (ship1-x s2) (ship1-y s2)) '("hi" (1 2 3)))))) (let () (defstruct ship2 (x 0.0) (y 1.0 :read-only #t)) (let ((s1 (make-ship2))) (test (let ((tag (catch #t (lambda () (set! (ship2-y s1) 123.0)) (lambda args (car args))))) tag) 'syntax-error) (set! (ship2-x s1) 123.0) (test (ship2-x s1) 123.0))) (let () (defstruct (ship3 (:conc-name hi)) (x 0.0) (y 1.0 :read-only #t)) (let ((s1 (make-ship3 :x 3.0))) (test (list (hi-x s1) (hi-y s1)) '(3.0 1.0)))) (let () (defstruct (ship4 (:constructor new-ship)) (x 0.0) (y 1.0 :read-only #t)) (let ((s1 (new-ship 1.0 2.0))) (test (list (ship4-x s1) (ship4-y s1)) '(1.0 2.0)))) ) ) ; end CL (if (not (eq? else #_else)) (set! else #_else)) ; loop sets else! ;;; -------------------------------------------------------------------------------- ;;; NUMBERS ;;; -------------------------------------------------------------------------------- (test (let () (set! most-positive-fixnum 2)) 'error) (test (let ((most-positive-fixnum 2)) most-positive-fixnum) 'error) (test (let () (set! most-negative-fixnum 2)) 'error) (test (let ((most-negative-fixnum 2)) most-negative-fixnum) 'error) (test (let () (set! pi 2)) 'error) (test (let ((pi 2)) pi) 'error) ;;; already a constant now (define-constant nan.0 (string->number "nan.0")) (test (constant? nan.0) #t) (if (not (nan? nan.0)) (format-logged #t ";(string->number \"nan.0\") returned ~A~%" nan.0)) (if (infinite? nan.0) (format-logged #t ";nan.0 is infinite?~%")) (define-constant +inf.0 (string->number "+inf.0")) (if (not (infinite? +inf.0)) (format-logged #t ";(string->number \"+inf.0\") returned ~A~%" +inf.0)) (if (nan? +inf.0) (format-logged #t ";+inf.0 is NaN?~%")) (test (constant? -inf.0) #t) ;;; (define-constant -inf.0 (string->number "-inf.0")) (if (not (infinite? -inf.0)) (format-logged #t ";(string->number \"-inf.0\") returned ~A~%" -inf.0)) (if (nan? -inf.0) (format-logged #t ";-inf.0 is NaN?~%")) ;;; (define-constant inf.0 +inf.0) (define-constant inf+infi (complex inf.0 inf.0)) (define-constant nan+nani (complex nan.0 nan.0)) (define-constant 0+infi (complex 0 inf.0)) (define-constant 0+nani (complex 0 nan.0)) (test (equal? +inf.0 inf.0) #t) (test (equal? +inf.0 -inf.0) #f) (test (equal? nan.0 inf.0) #f) (test (= nan.0 nan.0) #f) (test (equal? inf.0 nan.0) #f) ; (test (equal? nan.0 nan.0) (eqv? nan.0 nan.0)) ; these are confusing: (equal? 0/0 0/0) is a different case ;;; -------------------------------------------------------------------------------- ;;; number? ;;; -------------------------------------------------------------------------------- ;;; (synonym for complex?) (test (number? -) #f) (test (number? +) #f) (test (number? 12) #t) (test (number? 3) #t ) (test (number? (expt 2 130)) #t) (test (number? 5/3+7.2i) #t) (test (number? #f) #f) (test (number? (cons 1 2)) #f) (test (number? 2.5-.5i) #t) (test (number? most-negative-fixnum) #t) (test (number? 1e-308) #t) (test (number? 1e308) #t) (test (number? 0+0i) #t) (test (number? (log 0)) #t) (test (number? (real-part (log 0))) #t) (test (number? '-1-i) #t) (test (number? -1.797693134862315699999999999999999999998E308) #t) (test (number? -2.225073858507201399999999999999999999996E-308) #t) (test (number? -9223372036854775808) #t) (test (number? 1.110223024625156799999999999999999999997E-16) #t) (test (number? 9223372036854775807) #t) (test (number? +inf.0) #t) (test (number? -inf.0) #t) (test (number? nan.0) #t) (test (number? inf+infi) #t) (test (number? nan+nani) #t) (test (number? 0+infi) #t) (test (number? 0+nani) #t) (test (number? pi) #t) (test (number? 0/0) #t) (test (number? 1/-4) 'error) (for-each (lambda (n) (let ((nb (catch #t (lambda () (number? n)) (lambda args 'error)))) (if (not nb) (format-logged #t ";(number? ~A) -> #f?~%" n)))) (list '1e311 '1e-311 '0e311 '2.1e40000)) (if with-bignums (begin (test (number? 1234567891234567890/1234567) #t) (test (number? 9223372036854775808) #t) (test (number? 9223372036854775808.1) #t) (test (number? 9223372036854775808.1+1.5i) #t) (test (number? 9223372036854775808/3) #t))) (test (number?) 'error) (test (number? 1 2) 'error) (for-each (lambda (op opname) (for-each (lambda (arg) (if (op arg) (format-logged #t ";(~A ~A) -> #t?~%" op arg))) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #))) (list number? complex? real? rational? integer? float?) (list 'number? 'complex? 'real? 'rational? 'integer? float?)) ;;; -------------------------------------------------------------------------------- ;;; complex? ;;; -------------------------------------------------------------------------------- (test (complex? 1/2) #t) (test (complex? 2) #t) (test (complex? (sqrt 2)) #t) (test (complex? 1.0) #t) (test (complex? 1+i) #t) (test (complex? most-negative-fixnum) #t) (test (complex? 1/0) #t) ; nan is complex?? I guess so -- it's a "real"... (test (complex? (log 0.0)) #t) (test (complex? 0/0) #t) (test (complex? 1+0/0i) #t) (test (complex? -1.797693134862315699999999999999999999998E308) #t) (test (complex? -2.225073858507201399999999999999999999996E-308) #t) (test (complex? -9223372036854775808) #t) (test (complex? 1.110223024625156799999999999999999999997E-16) #t) (test (complex? 9223372036854775807) #t) (test (complex? 3) #t ) (test (complex? +inf.0) #t) (test (complex? -inf.0) #t) (test (complex? nan.0) #t) ; this should be #f (test (complex? pi) #t) (for-each (lambda (arg) (if (not (complex? arg)) (format-logged #t ";(complex? ~A) -> #f?~%" arg))) (list 1 1.0 1.0+0.5i 1/2)) (if with-bignums (begin (test (complex? 1234567891234567890/1234567) #t) (test (complex? 9223372036854775808) #t) (test (complex? 9223372036854775808.1) #t) (test (complex? 9223372036854775808.1+1.5i) #t) (test (complex? 0+92233720368547758081.0i) #t) (test (complex? 9223372036854775808/3) #t) )) (test (complex?) 'error) (test (complex? 1 2) 'error) ;;; -------------------------------------------------------------------------------- ;;; real? ;;; -------------------------------------------------------------------------------- (test (real? 1) #t) (test (real? most-negative-fixnum) #t) (test (real? 1/2) #t) (test (real? 1.0) #t) (test (real? (+ 1+i 1-i)) #t) (test (real? (- 1+i 1+i)) #t) (test (real? (+ 1+i -1-i)) #t) (test (real? (/ 1+i 1+i)) #t) (test (real? (* 0+i 0+i)) #t) (test (real? (magnitude 1+i)) #t) (test (real? (string->number "1+0i")) #t) (test (real? (complex 1 0)) #t) (test (real? (complex 0 0)) #t) (test (real? (complex 1 0.0)) #t) (test (real? (complex 0.0 -0.0)) #t) (test (real? (make-polar 0 0)) #t) (test (real? (make-polar 1 0)) #t) (test (real? (angle 1+i)) #t) (test (real? (real-part 1+i)) #t) (test (real? (imag-part 1+i)) #t) (test (real? (expt 0+i 0+i)) #t) (test (real? (log 0)) #f) (test (real? (real-part (log 0))) #t) (test (real? +inf.0) #t) (test (real? -inf.0) #t) (test (real? nan.0) #t) ; see below (test (real? pi) #t) (test (real? 0+i) #f) (test (real? 1.0-0.1i) #f) (test (real? (sqrt 2)) #t) (test (real? 1+i) #f) (test (real? 1e9-0i) #t) (test (real? 0+0i) #t) (test (real? 1.0+0i) #t) (test (real? 1.0+0.0i) #t) (test (real? 1+0.0i) #t) (test (real? 1-0.0i) #t) (test (real? 1+0i) #t) (test (real? -0+1e22i) #f) (test (real? -0+1e-22i) #f) (test (real? 0+1e-322i) #f) (test (real? 1+0/0i) #f) ; bignum direct 1+0/0i -> 1.0 (test (real? 1.0000000000000000000000000000+0.0000000000000000000000000000i) #t) (test (real? 1.0+0.0000000000000000000000000000i) #t) (test (real? 1.0000000000000000000000000000+0.0i) #t) (test (real? 1.0000000000000000000000000000+0e10i) #t) (test (real? 1.0+0.0000000000000000000000000000e10i) #t) (test (real? 1.0000000000000000000000000000+0.0e10i) #t) (test (real? 0+00000000000000000000000000000000/123456789012345678901234567890i) #t) (test (real? -1.797693134862315699999999999999999999998E308) #t) (test (real? -2.225073858507201399999999999999999999996E-308) #t) (test (real? -9223372036854775808) #t) (test (real? 1.110223024625156799999999999999999999997E-16) #t) (test (real? 9223372036854775807) #t) (when with-bignums (test (real? 9.92209574402351949043519108941671096176E-1726-4.788930572030484370393069119625570107346E-1726i) #f) (test (real? 1234567891234567890/1234567) #t) (test (real? 9223372036854775808) #t) (test (real? 9223372036854775808.1) #t) (test (real? 9223372036854775808.1+1.5i) #f) (test (real? 9223372036854775808/3) #t)) (test (real? case) #f) (test (real?) 'error) (test (real? 1 2) 'error) (test (real? (real-part (log 0.0))) #t) ; -inf (test (real? (/ (real-part (log 0.0)) (real-part (log 0.0)))) #t) ; nan -- I think this should be #f (test (real? (real-part (log 0))) #t) ;;; float? (test (float? 1) #f) (test (float? 1/2) #f) (test (float? 1.4) #t) (test (float? 1+i) #f) (test (float?) 'error) (test (float? 1.0 1.0) 'error) (test (float? #\a) #f) (test (float? (real-part (log 0.0))) #t) (test (float? 1/0) #t) (when (not with-bignums) (test (float? pi) #t) (test (float? 1e-308) #t)) ;;; -------------------------------------------------------------------------------- ;;; rational? ;;; -------------------------------------------------------------------------------- (test (rational? 3) #t) (test (rational? 1/2) #t) (test (rational? 2) #t) (test (rational? (sqrt 2)) #f) (test (rational? 1.0) #f) (test (rational? 1+i) #f) (test (rational? most-negative-fixnum) #t) (test (rational? 0/0) #f) ; I like this (test (rational? 1/0) #f) (test (rational? (/ 1 2)) #t) (test (rational? (/ 1 2/3)) #t) (test (rational? (/ 2/5 2/3)) #t) (test (rational? (/ 2/5 -3)) #t) (test (rational? (/ -4 4)) #t) (test (rational? (/ 1.0 2)) #f) (test (rational? 1/2+i) #f) (test (rational? -1.797693134862315699999999999999999999998E308) #f) (test (rational? -2.225073858507201399999999999999999999996E-308) #f) (test (rational? -9223372036854775808) #t) (test (rational? 1.110223024625156799999999999999999999997E-16) #f) (test (rational? 9223372036854775807) #t) (test (rational? +inf.0) #f) (test (rational? -inf.0) #f) (test (rational? nan.0) #f) ; guile says #t! (test (rational? pi) #f) (test (rational? 9223372036854775806/9223372036854775807) #t) (test (rational? 1+0i) #f) ; ?? (test (rational? 1+0.0i) #f) ; ?? see integer? (if with-bignums (begin (test (rational? 1234567891234567890/1234567) #t) (test (rational? 9223372036854775808) #t) (test (rational? 9223372036854775808.1) #f) (test (rational? 9223372036854775808.1+1.5i) #f) (test (rational? 9223372036854775808/3) #t) )) (test (rational?) 'error) (test (rational? 1 2) 'error) ;;; -------------------------------------------------------------------------------- ;;; integer? ;;; -------------------------------------------------------------------------------- (test (integer? 0.0) #f) (test (integer? 3) #t) (test (integer? 1/2) #f) (test (integer? 1/1) #t) (test (integer? 2) #t) (test (integer? (sqrt 2)) #f) (test (integer? 1.0) #f) (test (integer? 1+i) #f) (test (integer? most-negative-fixnum) #t) (test (integer? 250076005727/500083) #t) (test (integer? 1+0i) #f) ; hmmm -- guile says #t, but it thinks 1.0 is an integer (test (integer? 0/0) #f) (test (integer? 1/0) #f) (test (integer? #e.1e010) #t) (test (integer? (/ 2 1)) #t) (test (integer? (/ 2 1.0)) #f) (test (integer? -1.797693134862315699999999999999999999998E308) #f) (test (integer? -2.225073858507201399999999999999999999996E-308) #f) (test (integer? -9223372036854775808) #t) (test (integer? 1.110223024625156799999999999999999999997E-16) #f) (test (integer? 9223372036854775807) #t) (test (integer? (expt 2.3 54)) #f) (test (integer? 10000000000000000.5) #f) (test (integer? (expt 2 54)) #t) (test (integer? (expt 2.0 54)) #f) (test (integer? most-positive-fixnum) #t) (test (integer? (/ most-positive-fixnum most-positive-fixnum)) #t) (test (integer? +inf.0) #f) (test (integer? -inf.0) #f) (test (integer? nan.0) #f) (test (integer? pi) #f) (test (integer? 9223372036854775806/9223372036854775807) #f) (test (integer? 1+0.0i) #f) (if with-bignums (begin (test (integer? 1234567891234567890/1234567) #f) (test (integer? 9223372036854775808) #t) (test (integer? 9223372036854775808.1) #f) (test (integer? 9223372036854775808.1+1.5i) #f) (test (integer? 9223372036854775808/3) #f) (test (integer? 9223372036854775808/9223372036854775808) #t) (test (integer? 21345678912345678912345678913456789123456789123456789) #t) )) (test (integer?) 'error) (test (integer? 1 2) 'error) ;;; -------------------------------------------------------------------------------- ;;; infinite? ;;; -------------------------------------------------------------------------------- ;;; (define (infinite? x) (and (number? x) (or (= x inf.0) (= x -inf.0)))) but this misses complex cases ;;; ;;; a number can be both NaN and infinite...: (test (nan? (complex 0/0 (real-part (log 0)))) #t) (test (infinite? (complex 0/0 (real-part (log 0)))) #t) ;;; maybe we should restrict nan? and infinite? to reals? (test (infinite? 0) #f) (test (infinite? 1.0) #f) (test (infinite? 1/2) #f) (test (infinite? 1+i) #f) (test (infinite? most-positive-fixnum) #f) (test (infinite? +inf.0) #t) (test (infinite? -inf.0) #t) (test (infinite? nan.0) #f) (test (infinite? pi) #f) (test (infinite? (imag-part (sinh (log 0.0)))) #t) (test (infinite? (complex -inf.0 inf.0)) #t) (test (infinite? (+ (complex 1 inf.0))) #t) (test (infinite? most-negative-fixnum) #f) (test (infinite? -1.797693134862315699999999999999999999998E308) #f) (test (infinite? -2.225073858507201399999999999999999999996E-308) #f) (test (infinite? (real-part inf+infi)) #t) (test (infinite? (real-part 0+infi)) #f) (test (infinite? (imag-part inf+infi)) #t) (test (infinite? (imag-part 0+infi)) #t) (test (infinite? (imag-part (complex 0.0 (real-part (log 0))))) #t) (test (infinite? (real-part (complex 0.0 (real-part (log 0))))) #f) (test (infinite? (complex 0.0 (real-part (log 0)))) #t) (test (infinite? (real-part (complex (real-part (log 0)) 1.0))) #t) (test (infinite? (imag-part (complex (real-part (log 0)) 1.0))) #f) (test (infinite? (complex (real-part (log 0)) 1.0)) #t) (test (infinite? (imag-part (complex (real-part (log 0)) (real-part (log 0))))) #t) (test (infinite? (real-part (complex (real-part (log 0)) (real-part (log 0))))) #t) (test (infinite? (complex (real-part (log 0)) (real-part (log 0)))) #t) ;; if mpc version > 0.8.2 ;; (test (infinite? (sin 1+1e10i)) #t) ;; this hangs in earlier versions (if with-bignums (begin (test (infinite? (log (bignum "0.0"))) #t) (test (infinite? 1e310) #f) (test (infinite? 1e400) #f) (test (infinite? 1.695681258519314941339000000000000000003E707) #f) (test (infinite? 7151305879464824441563197685/828567267217721441067369971) #f) )) (test (infinite?) 'error) (test (infinite? 1 2) 'error) ;;; -------------------------------------------------------------------------------- ;;; nan? ;;; -------------------------------------------------------------------------------- ;;; (define (nan? x) (and (number? x) (not (= x x)))) (test (nan? +inf.0) #f) (test (nan? -inf.0) #f) (test (nan? nan.0) #t) (test (nan? pi) #f) (test (nan? (imag-part 0+0/0i)) #t) (test (nan? (imag-part (sinh 0+0/0i))) #t) (test (nan? (imag-part (sinh 1-0/0i))) #t) (test (nan? (log 10 0/0)) #t) (test (nan? (* 0 inf.0)) #t) (test (nan? (real-part nan+nani)) #t) (test (nan? (imag-part nan+nani)) #t) (test (nan? (real-part 0+nani)) #f) (test (nan? (imag-part 0+nani)) #t) (if with-bignums (begin (test (nan? (bignum "1/0")) #t) (test (nan? 7151305879464824441563197685/828567267217721441067369971) #f) (test (nan? 1624540914719833702142058941.4) #f) )) (test (nan?) 'error) (test (nan? 1 2) 'error) #| (define digits (vector #\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9)) (do ((i 0 (+ i 1))) ((= i 10000)) (let ((int-digits (random 80)) (frac-digits (random 80)) (exp-digits (+ 1 (random 5))) (signed (> (random 10) 5)) (signed-exponent (> (random 10) 5))) (let ((str (make-string (+ 1 int-digits 1 frac-digits 2 exp-digits) #\space)) (j 0)) (if signed (begin (set! (str j) #\-) (set! j (+ j 1)))) (do ((k 0 (+ k 1))) ((= k int-digits)) (set! (str j) (digits (random 10))) (set! j (+ j 1))) (set! (str j) #\.) (set! j (+ j 1)) (do ((k 0 (+ k 1))) ((= k frac-digits)) (set! (str j) (digits (random 10))) (set! j (+ j 1))) (set! (str j) #\e) (set! j (+ j 1)) (if signed-exponent (begin (set! (str j) #\-) (set! j (+ j 1)))) (do ((k 0 (+ k 1))) ((= k exp-digits)) (if (< k 3) (set! (str j) (digits (random 10))) (set! (str j) (digits (random 4)))) (set! j (+ j 1))) (let ((num (string->number (substring str 0 j)))) (if (or (nan? num) (infinite? num)) (format-logged #t "~A: ~S -> ~A~%" (if (infinite? num) 'inf 'nan) str num))) ))) |# ;;; these all relate to inf/nan (if (not with-bignums) (begin (test (* 1e12000 1e12000) inf.0) (test (<= 0 inf.0 nan.0) #f) (test (<= 1 nan.0) #f) (test (<= nan.0 1) #f) (test (<= nan.0 inf.0) #f) (test (<= nan.0 nan.0) #f) (test (>= 1 nan.0) #f) (test (>= nan.0 1) #f) (test (>= nan.0 inf.0) #f) (test (>= nan.0 nan.0) #f) (test (floor inf.0) 'error) (test (inexact->exact (complex 1 inf.0)) 'error) (test (nan? (expt 0 nan.0)) #t) (test (nan? (expt 1 nan.0)) #t) (test (nan? (expt nan.0 inf.0)) #t) (test (nan? (expt nan.0 nan.0)) #t) (test (rationalize 1e19) 'error) (test (round inf.0) 'error) (test (truncate inf.0) 'error) )) (num-test (/ -1 -inf.0 -9223372036854775808) 0.0) (num-test (angle -inf.0) pi) (num-test (angle inf.0) 0.0) (num-test (atan inf.0) 1.5707963267949) (num-test (atanh inf.0) 0+1.5707963267949i) (num-test (tanh -inf.0) -1.0) (num-test (tanh inf.0) 1.0) (test (* -inf.0 inf.0) -inf.0) (test (* inf.0) inf.0) (test (+ 0 inf.0) inf.0) (test (+ inf.0) inf.0) (test (- -inf.0 inf.0) -inf.0) (test (- 0 inf.0) -inf.0) (test (- inf.0) -inf.0) (test (/ 0 inf.0) 0.0) (test (/ inf.0) 0.0) (test (/ nan.0 0) 'error) (test (< -inf.0 0.0) #t) (test (< -inf.0 inf.0) #t) (test (< -inf.0 inf.0) #t) (test (< 0 inf.0 -inf.0) #f) (test (< 0 inf.0) #t) (test (< inf.0 -inf.0) #f) (test (< nan.0 inf.0) #f) (test (< nan.0 nan.0) #f) (test (<= -inf.0 0.0 inf.0 inf.0) #t) (test (<= -inf.0 inf.0) #t) (test (<= 0 inf.0 -inf.0) #f) (test (<= 0 inf.0) #t) (test (= (* (+ inf.0 inf.0) -inf.0) -inf.0) #t) (test (= (* -3.4 -inf.0) inf.0) #t) (test (= (* -inf.0 -inf.0) inf.0) #t) (test (= (* inf.0 -inf.0) -inf.0) #t) (test (= (* inf.0 inf.0) inf.0) #t) (test (= (+ 1 inf.0) inf.0) #t) (test (= (+ inf.0 inf.0) inf.0) #t) (test (= (- -inf.0) inf.0) #t) (test (= (- 0.0 inf.0) -inf.0) #t) (test (= (- inf.0) -inf.0) #t) (test (= (/ 0.0 inf.0) 0.0) #t) (test (= (abs -inf.0) inf.0) #t) (test (= (abs inf.0) inf.0) #t) (test (= (exp -inf.0) 0.0) #t) (test (= (exp inf.0) inf.0) #t) (test (= (exp most-negative-fixnum) 0.0) #t) (test (= (exp most-positive-fixnum) inf.0) #t) (test (= (expt -inf.0 0) 1.0) #t) (test (= (expt 0.0 inf.0) 0.0) #t) (test (= (expt 1 -inf.0) 1.0) #t) (test (= (expt 1 inf.0) 1.0) #t) (test (= (expt 2 -inf.0) 0.0) #t) (test (= (expt inf.0 0) 1.0) #t) (test (= (log inf.0) inf.0) #t) (test (= (magnitude -inf.0) inf.0) #t) (test (= (magnitude inf.0) inf.0) #t) (if (not (provided? 'pure-s7)) (test (= (make-polar inf.0 0) inf.0) #t)) (test (= (complex 0 inf.0) (sqrt -inf.0)) #t) ; (sqrt -inf.0) -> 0+infi ! (test (= (complex inf.0 0) inf.0) #t) (test (= (max -inf.0 inf.0) inf.0) #t) (test (= (min -inf.0 inf.0) -inf.0) #t) (test (= (sqrt inf.0) inf.0) #t) (test (infinite? (imag-part (sqrt -inf.0))) #t) (test (= -inf.0 -inf.0) #t) (test (= -inf.0 inf.0) #f) (test (= -inf.0 inf.0) #f) (test (= 0 inf.0 -inf.0) #f) (test (= 0 inf.0) #f) (test (= 0.0 nan.0) #f) (test (= inf.0 0.0) #f) (test (= inf.0 inf.0) #t) (test (= inf.0 most-positive-fixnum) #f) (test (= inf.0 nan.0) #f) (test (nan? (real-part nan+nani)) #t) (test (= nan.0 inf.0) #f) (test (nan? nan+nani) #t) (test (nan? nan.0) #t) (test (> -inf.0 inf.0) #f) (test (> 0 inf.0 -inf.0) #f) (test (> 0 inf.0) #f) (test (> inf.0 0.0) #t) (test (> inf.0 1.0e308) #t) (test (> inf.0 most-positive-fixnum) #t) (test (> nan.0 inf.0) #f) (test (> nan.0 nan.0) #f) (test (>= -inf.0 inf.0) #f) (test (>= 0 inf.0) #f) (test (>= inf.0 -inf.0 0.0) #f) (test (abs inf.0) inf.0) (test (acosh inf.0) inf.0) (test (angle inf.0) 0.0) (test (ash -inf.0 inf.0) 'error) (test (ash nan.0 inf.0) 'error) (test (ash nan.0 nan.0) 'error) (test (asinh inf.0) inf.0) (test (ceiling inf.0) 'error) (test (ceiling nan.0) 'error) (test (complex? nan+nani) #t) (test (cosh inf.0) inf.0) (test (even? inf.0) 'error) (test (exact? (complex 1 inf.0)) #f) (test (exp inf.0) inf.0) (test (expt nan.0) 'error) (test (floor inf.0) 'error) (test (floor nan.0) 'error) (test (gcd -inf.0 inf.0) 'error) (test (gcd nan.0 inf.0) 'error) (test (gcd nan.0 nan.0) 'error) (test (imag-part (complex 1 inf.0)) inf.0) (test (imag-part nan.0) 0.0) (test (inexact? (complex 1 inf.0)) #t) (test (infinite? 1 2) 'error) (test (infinite?) 'error) (test (lcm -inf.0 inf.0) 'error) (test (lcm nan.0 inf.0) 'error) (test (lcm nan.0 nan.0) 'error) (test (lcm nan.0) 'error) (test (log 8.0 inf.0) 0.0) (test (log inf.0) inf.0) (test (logand -inf.0 inf.0) 'error) (test (logand nan.0 inf.0) 'error) (test (logand nan.0 nan.0) 'error) (test (logior -inf.0 inf.0) 'error) (test (logior nan.0 inf.0) 'error) (test (logior nan.0 nan.0) 'error) (test (lognot -inf.0) 'error) (test (lognot nan.0) 'error) (test (logbit? -inf.0 inf.0) 'error) (test (logbit? nan.0 inf.0) 'error) (test (logbit? nan.0 nan.0) 'error) (test (logxor -inf.0 inf.0) 'error) (test (logxor nan.0 inf.0) 'error) (test (logxor nan.0 nan.0) 'error) (test (magnitude inf.0) inf.0) (test (random-state inf.0) 'error) (test (random-state nan.0) 'error) (test (max -inf.0 inf.0) inf.0) (test (max 0 inf.0 -inf.0) inf.0) (test (max 0 inf.0) inf.0) (test (max inf.0) inf.0) (test (min -inf.0 inf.0) -inf.0) (test (min 0 inf.0 -inf.0) -inf.0) (test (min 0 inf.0) 0) (test (min inf.0) inf.0) (test (nan? (* 0 nan.0)) #t) (test (nan? (+ (values inf.0 -inf.0) inf.0)) #t) (test (nan? (- -inf.0 -inf.0)) #t) (test (nan? (- inf.0 inf.0)) #t) (test (nan? (- nan.0 nan.0)) #t) (test (nan? (- nan.0)) #t) (test (nan? (* 0 (log 0))) #t) (test (nan? (/ -1 nan.0 -inf.0)) #t) (test (nan? (/ -inf.0 -inf.0)) #t) (test (nan? (/ 0 nan.0)) #t) ;(test (nan? (/ 0 (log 0))) #t) ;why not just 0.0? (test (nan? (/ inf.0 -inf.0)) #t) (test (nan? (/ inf.0 inf.0)) #t) (test (nan? (/ inf.0 nan.0)) #t) (test (nan? (/ nan.0 inf.0)) #t) (test (nan? (/ nan.0 nan.0)) #t) (test (nan? (/ nan.0)) #t) (test (nan? (abs nan.0)) #t) ;(test (nan? (acos inf.0)) #t) (test (nan? (angle nan.0)) #t) ;(test (nan? (asin inf.0)) #t) (test (nan? (asin nan.0)) #t) (test (nan? (exp nan.0)) #t) (test (nan? (imag-part (complex 0 nan.0))) #t) (test (nan? (imag-part nan+nani)) #t) (test (nan? (imag-part nan+nani)) #t) (test (nan? (log 8.0 nan.0)) #t) (test (nan? (log nan.0 nan.0)) #t) (test (nan? (magnitude nan+nani)) #t) (test (nan? (magnitude nan.0)) #t) (test (nan? (make-polar -inf.0 inf.0)) #t) (test (nan? (make-polar nan.0 0)) #t) (test (nan? (complex nan.0 0)) #t) (test (nan? (max 0 inf.0 nan.0)) #t) (test (nan? (max 1 nan.0)) #t) (test (nan? (min 0 inf.0 nan.0)) #t) (test (nan? (min 1 nan.0)) #t) ;(test (nan? (modulo 1 inf.0)) #t) ;(test (nan? (modulo 1 nan.0)) #t) ;(test (nan? (modulo inf.0 1)) #t) ;(test (nan? (modulo nan.0 1)) #t) (test (nan? (random nan.0)) #t) (test (nan? (real-part (exp nan+nani))) #t) (test (nan? (real-part (log nan+nani))) #t) (test (nan? (real-part (log nan.0))) #t) (test (nan? (real-part (complex -inf.0 0))) #f) (test (nan? (real-part (sqrt nan.0))) #t) (test (nan? (real-part nan+nani)) #t) (test (nan? (sin -inf.0)) #t) (test (nan? (sin inf.0)) #t) (test (nan? (sin nan.0)) #t) (test (nan? (string->number "nan.0")) #t) (test (nan? -inf.0) #f) (test (nan? 1 2) 'error) (test (nan? inf.0) #f) (test (nan? most-negative-fixnum) #f) (test (nan? most-positive-fixnum) #f) (test (nan?) 'error) (test (negative? (/ (real-part (log 0.0)) (real-part (log 0.0)))) #f) ; and yet it prints as -nan.0 (test (number? nan+nani) #t) (test (quotient 1 nan.0) 'error) (test (quotient nan.0 1) 'error) (test (random nan.0 inf.0) 'error) (test (rationalize -inf.0) 'error) (test (rationalize 0.5 inf.0) 0) (test (rationalize 178978.5 -inf.0) 0) (test (rationalize 178987.5 nan.0) 'error) (test (rationalize 198797.5 inf.0) 0) (test (rationalize inf.0) 'error) (test (rationalize inf.0) 'error) (test (rationalize nan.0 nan.0) 'error) (test (rationalize nan.0) 'error) (test (rationalize nan.0) 'error) (test (real-part (complex 1 inf.0)) 1.0) (test (real? nan+nani) #f) (test (remainder 1 nan.0) 'error) (test (remainder nan.0 1) 'error) (test (round inf.0) 'error) (test (round nan.0)'error) (test (sinh inf.0) inf.0) (test (sqrt inf.0) inf.0) (test (tanh inf.0) 1.0) (test (truncate inf.0) 'error) (test (truncate nan.0) 'error) (test (zero? (complex 1 inf.0)) #f) (test (zero? (real-part (complex 0 -inf.0))) #t) (test (zero? 0/0) #f) (test (zero? inf.0) #f) (test (zero? nan.0) #f) ;; (test (nan? (angle nan.0)) #t) ;; but (* 0 (expt 10 310)) -> -nan if not GMP -- is this a bug? ;;(atanh -inf.0) 0+1.5707963267949i ;;(test (/ 0 inf.0 -inf.0) 0.0) ;;(test (= (expt 1 nan+nani) 1) #t) ; or maybe NaN? ;;(test (= (expt 1 nan.0) 1) #t) ;;(test (= (expt 2 inf.0) inf.0) #t) ;;(test (= (expt inf.0 -inf.0) 0.0) #t) ;;(test (= (expt inf.0 inf.0) inf.0) #t) ;;(test (= (expt nan.0 0) 1.0) #t) ;hmmm ;;(test (= (expt nan.0 nan.0) 0) #t) ;;(test (>= 0 inf.0 -inf.0) #t) ;;(test (angle (complex 1 inf.0)) 1.5707963267949) ;;(test (atanh (complex 1 inf.0)) -0+1.5707963267949i) ;;(test (nan? (atan -inf.0 inf.0)) #t) ; ?? ;;(test (nan? (expt 0 inf.0)) #t) ;;(test (nan? (quotient -inf.0 inf.0)) #t) ;;(test (nan? (quotient 1 nan.0)) #t) ;;(test (nan? (quotient nan.0 1)) #t) ;;(test (nan? (quotient nan.0 inf.0)) #t) ;;(test (nan? (quotient nan.0 nan.0)) #t) ;;(test (tan (complex 1 inf.0)) 0+1i) ;;(log nan.0 0) (log 0 inf.0) (log 0 -inf.0) (for-each (lambda (x) (test (infinite? x) 'error) (test (nan? x) 'error)) (list #\a "hi" #f #(1 2) () '(1 . 2) _ht_ _null_ _c_obj_ 'hi abs # #)) (for-each (lambda (n) (test (infinite? n) #f) (test (nan? n) #f)) (list 0.0 -0.0 .1 1+i 0-i 1/10)) (for-each (lambda (op) (test (number? (op inf.0)) #t) (test (number? (op -inf.0)) #t) (test (number? (op nan.0)) #t)) (list magnitude abs exp angle sin cos tan sinh cosh tanh atan sqrt log asinh acosh atanh acos asin real-part imag-part exact->inexact)) (for-each (lambda (op) (test (op inf.0) 'error) (test (op -inf.0) 'error) (test (op nan.0) 'error)) (list floor ceiling truncate round)) (for-each (lambda (op) (test (number? (op inf.0 inf.0)) #t) (test (number? (op nan.0 -inf.0)) #t)) (list + - * / expt complex make-polar)) (for-each (lambda (op) (test (boolean? (op inf.0)) #t) (test (boolean? (op nan.0)) #t) (test (op) 'error)) (list number? integer? real? complex? rational? zero? positive? negative? inexact? exact?)) (for-each (lambda (op) (test (boolean? (op inf.0 -inf.0)) #t) (test (boolean? (op nan.0 -inf.0)) #t)) (list = < > <= >=)) (for-each (lambda (op) (test (op inf.0) 'error) (test (op nan.0) 'error)) (list even? odd? numerator denominator lcm gcd inexact->exact logior logxor logand lognot logbit? ash integer-length)) (let ((d1 1e-312) (d2 1e-316) (d3 1e-320)) (if (not (zero? d3)) (begin (when (not with-bignums) (test (= d1 d2 d3) #f) (test (not (= d2 (* 2 d1))) #t)) (test (< d1 d2 d3) #f) (test (> d1 d2 d3) #t) (test (rationalize d1) 0) (test (rationalize d3) 0) (test (rationalize (- d1)) 0) (num-test (string->number (number->string d1)) d1) (test (< (sin d3) (sin d2) (sin d1)) #t) (test (< (log d3) (log d2) (log d1)) #t) (test (< (abs d3) (abs d2) (abs d1)) #t) (test (< (sqrt d3) (sqrt d2) (sqrt d1)) #t) (test (<= (exp d3) (exp d2) (exp d3)) #t) ; all might be 1.0 ))) ;;; -------------------------------------------------------------------------------- ;;; zero? ;;; -------------------------------------------------------------------------------- (test (zero? 0) #t ) (test (zero? 0/1) #t ) (test (zero? -0) #t ) (test (zero? -0.0) #t ) (test (zero? 0.0) #t ) (test (zero? 1) #f ) (test (zero? -1) #f ) (test (zero? -100) #f ) (test (zero? -0/4) #t) (test (zero? 0+0i) #t) (test (zero?) 'error) (test (zero? "hi") 'error) (test (zero? 1.0+23.0i 1.0+23.0i) 'error) (test (zero? 0+i) #f) (test (zero? 0-0i) #t) (test (zero? 0.0-0.0i) #t) (test (zero? +0.0) #t) (test (zero? 1e-20) #f) (test (zero? -1.797693134862315699999999999999999999998E308) #f) (test (zero? -2.225073858507201399999999999999999999996E-308) #f) (test (zero? 2.2250738585072012e-308) #f) ; gauche says one of these can hang (test (zero? 2.2250738585072013e-308) #f) (test (zero? 2.2250738585072014e-308) #f) (test (zero? 2.2250738585072015e-308) #f) (test (zero? 2.2250738585072011e-308) #f) (test (zero? 2.2250738585072010e-308) #f) (test (zero? 2.2250738585072010e-309) #f) (test (zero? 2.2250738585072010e-310) #f) (test (zero? -9223372036854775808) #f) (test (zero? 1.110223024625156799999999999999999999997E-16) #f) (test (zero? 9223372036854775807) #f) (test (zero? +inf.0) #f) (test (zero? -inf.0) #f) (test (zero? nan.0) #f) (test (zero? pi) #f) (test (zero? -1/9223372036854775807) #f) (test (zero? 1/2) #f) (test (zero? 0-i) #f) (test (zero? 0.00001) #f) (test (zero? most-negative-fixnum) #f) (test (zero? most-positive-fixnum) #f) (test (zero? 18446744073709551616) #f) (test (zero? (* 0 most-positive-fixnum most-positive-fixnum)) #t) (test (zero? (* 0.0 most-positive-fixnum most-positive-fixnum)) #t) (test (zero? (* most-positive-fixnum most-negative-fixnum 0)) #t) (test (zero? (* most-positive-fixnum most-negative-fixnum 0.0)) #t) (test (zero? 1000000000000000000000000000000000) #f) (test (zero? 000000000000000000000000000000000) #t) (if with-bignums (begin (test (zero? (- (expt 2.3 54) (floor (expt 2.3 54)))) #f) (test (zero? 1e-600) #f) (test (zero? 9.92209574402351949043519108941671096176E-1726) #f) (test (zero? 12345678901234567890) #f) (test (zero? 9223372036854775808) #f) (test (zero? 9223372036854775808.1) #f) (test (zero? 9223372036854775808.1+1.5i) #f) (test (zero? 9223372036854775808/3) #f) )) (test (zero?) 'error) (test (zero? 1 2) 'error) (test (zero? 0.@2211) #t) (test (zero? 0@0) #t) ; ?? (expt 0 0) -> 1 but 0@0 -> 0.0 because (expt 0.0 0) -> 0.0? (for-each (lambda (arg) (test (zero? arg) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) ;;; -------------------------------------------------------------------------------- ;;; positive? ;;; -------------------------------------------------------------------------------- (test (positive? 4/3) #t ) (test (positive? 4) #t ) (test (positive? -4) #f ) (test (positive? -4/3) #f ) (test (positive? 0) #f ) (test (positive? 0.0) #f ) (test (positive? -0) #f ) (test (positive? 1-0.0i) #t) (test (positive? 1.0) #t) (test (positive? -1.797693134862315699999999999999999999998E308) #f) (test (positive? -2.225073858507201399999999999999999999996E-308) #f) (test (positive? -9223372036854775808) #f) (test (positive? 1.110223024625156799999999999999999999997E-16) #t) (test (positive? 9223372036854775807) #t) (test (positive? most-negative-fixnum) #f) (test (positive? most-positive-fixnum) #t) (test (positive? +inf.0) #t) (test (positive? -inf.0) #f) (test (positive? nan.0) #f) (for-each (lambda (n) (if (not (positive? n)) (format-logged #t ";(positive? ~A) -> #f?~%") n)) (list 1 123 123456123 1.4 0.001 1/2 124124124.2)) (for-each (lambda (n) (if (positive? n) (format-logged #t ";(positive? ~A) -> #t?~%" n))) (list -1 -123 -123456123 -3/2 -0.00001 -1.4 -123124124.1)) (if with-bignums (begin (test (positive? 1000000000000000000000000000000000) #t) (test (positive? -1000000000000000000000000000000000) #f) (test (positive? 9.92209574402351949043519108941671096176E-1726) #t) (test (positive? 12345678901234567890) #t) (test (positive? -12345678901234567890) #f) (test (positive? 9223372036854775808) #t) (test (positive? 9223372036854775808.1) #t) (test (positive? 9223372036854775808/3) #t) (test (positive? (/ most-positive-fixnum most-negative-fixnum)) #f) (test (positive? 0+92233720368547758081.0i) 'error) )) (test (positive? 1.23+1.0i) 'error) (test (positive? 1.23 1.23) 'error) (test (positive?) 'error) (test (positive? 1 2) 'error) (for-each (lambda (arg) (test (positive? arg) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) ;;; -------------------------------------------------------------------------------- ;;; negative? ;;; -------------------------------------------------------------------------------- (test (negative? 4) #f ) (test (negative? 4/3) #f ) (test (negative? -4) #t ) (test (negative? -4/3) #t ) (test (negative? -0/4) #f) (test (negative? 0) #f ) (test (negative? -0) #f ) (test (negative? 0.0) #f ) (test (negative? -0.0) #f ) (test (negative? (- 0.0)) #f ) (test (negative? (expt -0.0 1)) #f) (test (negative? (/ -0.0 1.0)) #f) (test (negative? (* -0.0 1.0)) #f) (test (negative?) 'error) (test (negative? 1-0i) #f) (test (negative? -1.797693134862315699999999999999999999998E308) #t) (test (negative? -2.225073858507201399999999999999999999996E-308) #t) (test (negative? -9223372036854775808) #t) (test (negative? 1.110223024625156799999999999999999999997E-16) #f) (test (negative? 9223372036854775807) #f) (test (negative? most-negative-fixnum) #t) (test (negative? most-positive-fixnum) #f) (test (negative? +inf.0) #f) (test (negative? -inf.0) #t) (test (negative? nan.0) #f) (test (negative? most-negative-fixnum) #t) (test (negative? most-positive-fixnum) #f) ;; (negative? -1/0): #f? (positive? 1/0) is also #f, but (negative? -nan.0): #f (guile agrees) -- so what's the point of -nan.0?? ;; chibi says (negative? -nan.0) #t, but (positive? +nan.0) #f?? (for-each (lambda (n) (if (negative? n) (format-logged #t ";(negative? ~A) -> #t?~%" n))) (list 1 123 123456123 1.4 0.001 1/2 12341243124.2)) (for-each (lambda (n) (if (not (negative? n)) (format-logged #t ";(negative? ~A) -> #f?~%" n))) (list -1 -123 -123456123 -2/3 -0.00001 -1.4 -123124124.1)) (let ((val1 (catch #t (lambda () (negative? 0.0)) (lambda args 'error))) (val2 (catch #t (lambda () (negative? -0.0)) (lambda args 'error)))) (test (equal? val1 val2) #t)) (if with-bignums (begin (test (negative? 1000000000000000000000000000000000) #f) (test (negative? -1000000000000000000000000000000000) #t) (test (negative? -9.92209574402351949043519108941671096176E-1726) #t) (test (negative? 12345678901234567890) #f) (test (negative? -12345678901234567890) #t) (test (negative? 9223372036854775808) #f) (test (negative? 9223372036854775808.1) #f) (test (negative? 9223372036854775808/3) #f) (test (negative? 0+92233720368547758081.0i) 'error) )) (test (negative? -1-i) 'error) (test (negative? 1.23+1.0i) 'error) (test (negative? 1.23 1.23) 'error) (test (negative?) 'error) (test (negative? 1 2) 'error) (for-each (lambda (arg) (test (negative? arg) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) ;;; -------------------------------------------------------------------------------- ;;; odd? ;;; -------------------------------------------------------------------------------- (test (odd? 3) #t ) (test (odd? 2) #f ) (test (odd? -4) #f ) (test (odd? -1) #t ) (test (odd? 0) #f) (test (odd? -0) #f) (test (odd? -9223372036854775808) #f) (test (odd? 9223372036854775807) #t) (test (odd? most-positive-fixnum) #t) (test (odd? most-negative-fixnum) #f) (test (odd? -2147483647) #t) (test (odd? -2147483648) #f) (test (odd? -2147483649) #t) (test (odd? 2147483647) #t) (test (odd? 2147483648) #f) (test (odd? 2147483649) #t) (for-each (lambda (n) (if (odd? n) (format-logged #t ";(odd? ~A) -> #t?~%" n))) (list 0 2 1234 -4 -10000002 1000000006)) (for-each (lambda (n) (if (not (odd? n)) (format-logged #t ";(odd? ~A) -> #f?~%" n))) (list 1 -1 31 50001 543321)) (if with-bignums (begin (test (odd? 12345678901234567891) #t) (test (odd? 12345678901234567890) #f) (test (odd? -1231234567891234567891) #t) (test (odd? -1231234567891234567891) #t) (test (odd? -1239223372036854775808) #f) (test (odd? -9223372036854775808) #f) (test (odd? 1231234567891234567891) #t) (test (odd? 1234567891234567891) #t) (test (odd? 1239223372036854775808) #f) (test (odd? 9223372036854775808) #f) (test (odd? 9223372036854775808/9223372036854775807) 'error) (test (odd? 0+92233720368547758081.0i) 'error) )) (test (odd?) 'error) (test (odd? 1.23) 'error) (test (odd? 1.0) 'error) (test (odd? 1+i) 'error) (test (odd? 123 123) 'error) (test (odd? inf.0) 'error) (test (odd? nan.0) 'error) (test (odd? 1/2) 'error) (for-each (lambda (arg) (test (odd? arg) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) ;;; -------------------------------------------------------------------------------- ;;; even? ;;; -------------------------------------------------------------------------------- (test (even? 3) #f ) (test (even? 2) #t ) (test (even? -4) #t ) (test (even? -1) #f ) (test (even? -0) #t) (test (even? -9223372036854775808) #t) (test (even? 9223372036854775807) #f) (test (even? most-positive-fixnum) #f) (test (even? most-negative-fixnum) #t) (test (even? -2147483647) #f) (test (even? -2147483648) #t) (test (even? -2147483649) #f) (test (even? 2147483647) #f) (test (even? 2147483648) #t) (test (even? 2147483649) #f) (for-each (lambda (n) (if (not (even? n)) (format-logged #t ";(even? ~A) -> #f?~%" n))) (list 0 2 1234 -4 -10000002 1000000006)) (for-each (lambda (n) (if (even? n) (format-logged #t ";(even? ~A) -> #t?~%" n))) (list 1 -1 31 50001 543321)) (let ((top-exp 60)) (let ((happy #t)) (do ((i 2 (+ i 1))) ((or (not happy) (> i top-exp))) (let* ((val1 (+ 2 (inexact->exact (expt 2 i)))) (val2 (- val1 1)) (ev1 (even? val1)) (ov1 (odd? val1)) (ev2 (even? val2)) (ov2 (odd? val2))) (if (not ev1) (begin (set! happy #f) (display "not (even? ") (display val1) (display ")?") (newline))) (if ev2 (begin (set! happy #f) (display "(even? ") (display val2) (display ")?") (newline))) (if ov1 (begin (set! happy #f) (display "(odd? ") (display val1) (display ")?") (newline))) (if (not ov2) (begin (set! happy #f) (display "not (odd? ") (display val2) (display ")?") (newline))))))) (if with-bignums (begin (test (even? 12345678901234567890) #t) (test (even? 12345678901234567891) #f) (test (even? -1231234567891234567891) #f) (test (even? -1234567891234567891) #f) (test (even? -1239223372036854775808) #t) (test (even? -9223372036854775808) #t) (test (even? 1231234567891234567891) #f) (test (even? 1234567891234567891) #f) (test (even? 1239223372036854775808) #t) (test (even? 9223372036854775808) #t) (test (even? 9223372036854775808/9223372036854775807) 'error) (test (even? 0+92233720368547758081.0i) 'error) )) (test (even?) 'error) (test (even? 1.23) 'error) (test (even? 1.0) 'error) (test (even? 123 123) 'error) (test (even? 1+i) 'error) (test (even? 1+0i) 'error) (test (even? inf.0) 'error) (test (even? nan.0) 'error) (test (even? 1/2) 'error) (for-each (lambda (arg) (test (even? arg) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) ;;; -------------------------------------------------------------------------------- ;;; exact? ;;; -------------------------------------------------------------------------------- (test (exact? 1/0) #f) (test (exact? '0/1) #t) (test (exact? (/ 1 2)) #t) (test (exact? -0) #t) (test (exact? -1.797693134862315699999999999999999999998E308) #f) (test (exact? -2.225073858507201399999999999999999999996E-308) #f) (test (exact? -9223372036854775808) #t) (test (exact? 0/0) #f) (test (exact? 0/1) #t) (test (exact? 1.0) #f) (test (exact? 1.110223024625156799999999999999999999997E-16) #f) (test (exact? 1.5+0.123i) #f) (test (exact? 1/2) #t) (test (exact? 3) #t ) (test (exact? 3.123) #f) (test (exact? 9223372036854775807) #t) (test (exact? most-positive-fixnum) #t) (test (exact? pi) #f) (test (exact? +inf.0) #f) (test (exact? -inf.0) #f) (test (exact? nan.0) #f) (test (exact? (imag-part 1+0i)) #f) (test (exact? (imag-part 1+0.0i)) #f) (test (exact? (imag-part 1+1i)) #f) (if with-bignums (begin (test (exact? 12345678901234567890) #t) (test (exact? 9223372036854775808.1) #f) (test (exact? 9223372036854775808) #t) (test (exact? 9223372036854775808/3) #t) (test (exact? 9223372036854775808.1+1.0i) #f) )) (test (exact?) 'error) (test (exact? "hi") 'error) (test (exact? 1.0+23.0i 1.0+23.0i) 'error) (for-each (lambda (arg) (test (exact? arg) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) ;;; -------------------------------------------------------------------------------- ;;; inexact? ;;; -------------------------------------------------------------------------------- (test (inexact? -1) #f) (test (inexact? -1.797693134862315699999999999999999999998E308) #t) (test (inexact? -2.225073858507201399999999999999999999996E-308) #t) (test (inexact? -9223372036854775808) #f) (test (inexact? 1.0) #t) (test (inexact? 1.110223024625156799999999999999999999997E-16) #t) (test (inexact? 1.5+0.123i) #t) (test (inexact? 1/2) #f) (test (inexact? 3) #f) (test (inexact? 3.123) #t) (test (inexact? 9223372036854775807) #f) (test (inexact? +inf.0) #t) (test (inexact? -inf.0) #t) (test (inexact? nan.0) #t) (if with-bignums (begin (test (inexact? 12345678901234567890) #f) (test (inexact? 9223372036854775808.1) #t) (test (inexact? 9223372036854775808) #f) (test (inexact? 9223372036854775808/3) #f) (test (inexact? 9223372036854775808.1+1.0i) #t) )) (test (inexact? "hi") 'error) (test (inexact? 1.0+23.0i 1.0+23.0i) 'error) (test (inexact?) 'error) (for-each (lambda (arg) (test (inexact? arg) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) ;;; -------------------------------------------------------------------------------- ;;; exact->inexact ;;; -------------------------------------------------------------------------------- (num-test (exact->inexact 0+1.5i) 0+1.5i) (num-test (exact->inexact 1) 1.0) (num-test (exact->inexact 1.0) 1.0) (num-test (exact->inexact 3/2) 1.5) (num-test (exact->inexact -3/2) -1.5) (test (infinite? (exact->inexact inf.0)) #t) (test (nan? (exact->inexact nan.0)) #t) (num-test (exact->inexact most-positive-fixnum) 9.223372036854775807E18) (num-test (exact->inexact most-negative-fixnum) -9.223372036854775808E18) (num-test (exact->inexact 17/12) 1.416666666666666666666666666666666666665E0) (num-test (exact->inexact 41/29) 1.413793103448275862068965517241379310344E0) (num-test (exact->inexact 99/70) 1.414285714285714285714285714285714285714E0) (num-test (exact->inexact 577/408) 1.414215686274509803921568627450980392157E0) (num-test (exact->inexact 1393/985) 1.414213197969543147208121827411167512692E0) (num-test (exact->inexact 3363/2378) 1.414213624894869638351555929352396972245E0) (num-test (exact->inexact 19601/13860) 1.414213564213564213564213564213564213564E0) (num-test (exact->inexact 47321/33461) 1.414213562057320462628134245838438779476E0) (num-test (exact->inexact 114243/80782) 1.414213562427273402490653858532841474586E0) (num-test (exact->inexact 275807/195025) 1.414213562363799512882963722599666709396E0) (num-test (exact->inexact 1607521/1136689) 1.414213562372821413772808569450394962913E0) (num-test (exact->inexact 3880899/2744210) 1.414213562373141997150363856993451667326E0) (num-test (exact->inexact 9369319/6625109) 1.414213562373086993738518113437831739826E0) (num-test (exact->inexact 54608393/38613965) 1.414213562373094811682768138418315757008E0) (num-test (exact->inexact 131836323/93222358) 1.414213562373095089484863706193743779791E0) (num-test (exact->inexact 318281039/225058681) 1.414213562373095041821559418096829599746E0) (num-test (exact->inexact 1855077841/1311738121) 1.414213562373095048596212902163571413046E0) (num-test (exact->inexact 4478554083/3166815962) 1.414213562373095048836942801793292211529E0) (num-test (exact->inexact -1.797693134862315699999999999999999999998E308) -1.797693134862315699999999999999999999998E308) (num-test (exact->inexact -2.225073858507201399999999999999999999996E-308) -2.225073858507201399999999999999999999996E-308) (num-test (exact->inexact -9223372036854775808) -9.223372036854775808E18) (num-test (exact->inexact 1.110223024625156799999999999999999999997E-16) 1.110223024625156799999999999999999999997E-16) (num-test (exact->inexact 9223372036854775807) 9.223372036854775807E18) (num-test (exact->inexact 9007199254740991) 9.007199254740991E15) (test (= (exact->inexact 9007199254740992) (exact->inexact 9007199254740991)) #f) (if with-bignums (begin (num-test (truncate (exact->inexact most-positive-fixnum)) 9223372036854775807) (test (= (exact->inexact 9007199254740993) (exact->inexact 9007199254740992)) #f) (num-test (exact->inexact 73786976294838206464) (expt 2.0 66)) (num-test (exact->inexact (bignum "0+1.5i")) 0+1.5i) (test (< (abs (- (expt 2 66.5) (exact->inexact 19459393535087060477929284/186481))) 1e-9) #t) (test (< (abs (- (exact->inexact -186198177976134811212136169603791619/103863) (- (expt 2 100.5)))) 1e-9) #t) )) (test (exact->inexact "hi") 'error) (test (exact->inexact 1.0+23.0i 1.0+23.0i) 'error) (test (exact->inexact) 'error) (for-each (lambda (arg) (test (exact->inexact arg) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) (test (integer? (* 0 1.0)) #f) ; s7.html check -- we want 0.0 here, not 0 [for exact->inexact replacement code] (test (rational? (* 1.0 0)) #f) ;;; -------------------------------------------------------------------------------- ;;; inexact->exact ;;; -------------------------------------------------------------------------------- (num-test (inexact->exact 0.0) 0) (num-test (inexact->exact 1) 1) (num-test (inexact->exact 1.0) 1) (num-test (inexact->exact 1.5) 3/2) (test (inexact->exact most-negative-fixnum) most-negative-fixnum) (num-test (inexact->exact 1.0000000000000000000000000000+0.0000000000000000000000000000i) 1) (num-test (inexact->exact 1.0+0.0000000000000000000000000000i) 1) (num-test (inexact->exact 1.0000000000000000000000000000+0.0i) 1) (num-test (inexact->exact 1.0000000000000000000000000000+0e10i) 1) (num-test (inexact->exact 1.0+0.0000000000000000000000000000e10i) 1) (num-test (inexact->exact 1.0000000000000000000000000000+0.0e10i) 1) (num-test (inexact->exact -2.225073858507201399999999999999999999996E-308) 0) (num-test (inexact->exact -9223372036854775808) -9223372036854775808) (num-test (inexact->exact 1.110223024625156799999999999999999999997E-16) 0) (num-test (inexact->exact 9223372036854775807) 9223372036854775807) (num-test (inexact->exact -2305843009213693952/4611686018427387903) -2305843009213693952/4611686018427387903) ;(num-test (inexact->exact 9007199254740995.0) 9007199254740995) ;this can't work in the non-gmp case -- see s7.c under BIGNUM_PLUS ;#e4611686018427388404.0 -> 4611686018427387904 (if with-bignums (begin (num-test (inexact->exact .1e20) 10000000000000000000) (num-test (inexact->exact 1e19) 10000000000000000000) (num-test (inexact->exact 1e20) 100000000000000000000) (num-test (inexact->exact 9007199254740995.0) 9007199254740995) (num-test (inexact->exact 4611686018427388404.0) 4611686018427388404) (num-test #e9007199254740995.0 9007199254740995) (num-test #e4611686018427388404.0 4611686018427388404) (test (inexact->exact (bignum "0+1.5i")) 'error) )) (if (not with-bignums) (begin (test (inexact->exact 1.1e54) 'error) (test (inexact->exact 1.1e564) 'error) (test (inexact->exact .1e20) 'error) (test (inexact->exact 1e19) 'error) (test (inexact->exact 1e20) 'error) )) (test (inexact->exact inf.0) 'error) (test (inexact->exact nan.0) 'error) (test (inexact->exact "hi") 'error) (test (inexact->exact 0+1.5i) 'error) (test (inexact->exact 1+i) 'error) (test (inexact->exact 1.0+23.0i 1.0+23.0i) 'error) (test (inexact->exact) 'error) (for-each (lambda (arg) (test (inexact->exact arg) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) ;;; -------------------------------------------------------------------------------- ;;; numerator ;;; -------------------------------------------------------------------------------- (num-test (numerator (/ 8 -6)) -4) (num-test (numerator -1/10) -1) (num-test (numerator -1/1234000000) -1) (num-test (numerator -1/2) -1) (num-test (numerator -1/362880) -1) (num-test (numerator -10/1) -10) (num-test (numerator -10/1234) -5) (num-test (numerator -10/3) -10) (num-test (numerator -10/500029) -10) (num-test (numerator -1234/10) -617) (num-test (numerator -1234/1234000000) -1) (num-test (numerator -1234/2) -617) (num-test (numerator -1234/362880) -617) (num-test (numerator -1234000000/1) -1234000000) (num-test (numerator -1234000000/1234) -1000000) (num-test (numerator -1234000000/3) -1234000000) (num-test (numerator -1234000000/500029) -1234000000) (num-test (numerator -2/1) -2) (num-test (numerator -2/1234) -1) (num-test (numerator -2/3) -2) (num-test (numerator -2/500029) -2) (num-test (numerator -2/6) -1) (num-test (numerator -3/10) -3) (num-test (numerator -3/1234000000) -3) (num-test (numerator -3/2) -3) (num-test (numerator -3/362880) -1) (num-test (numerator -362880/1) -362880) (num-test (numerator -362880/1234) -181440) (num-test (numerator -362880/3) -120960) (num-test (numerator -362880/500029) -362880) (num-test (numerator -500029/10) -500029) (num-test (numerator -500029/1234000000) -500029) (num-test (numerator -500029/2) -500029) (num-test (numerator -500029/362880) -500029) (num-test (numerator 0/1) 0) (num-test (numerator 0/10) 0) (num-test (numerator 0/1234) 0) (num-test (numerator 0/1234000000) 0) (num-test (numerator 0/2) 0) (num-test (numerator 0/3) 0) (num-test (numerator 0/362880) 0) (num-test (numerator 0/500029) 0) (num-test (numerator 1) 1) (num-test (numerator 1/1) 1) (num-test (numerator 1/1234) 1) (num-test (numerator 1/3) 1) (num-test (numerator 1/500029) 1) (num-test (numerator 10/10) 1) (num-test (numerator 10/1234000000) 1) (num-test (numerator 10/2) 5) (num-test (numerator 10/362880) 1) (num-test (numerator 12/6000996) 1) (num-test (numerator 1234/1) 1234) (num-test (numerator 1234/1234) 1) (num-test (numerator 1234/3) 1234) (num-test (numerator 1234/500029) 1234) (num-test (numerator 1234000000/10) 123400000) (num-test (numerator 1234000000/1234000000) 1) (num-test (numerator 1234000000/2) 617000000) (num-test (numerator 1234000000/362880) 1928125) (num-test (numerator 2/10) 1) (num-test (numerator 2/1234000000) 1) (num-test (numerator 2/2) 1) (num-test (numerator 2/3) 2) (num-test (numerator 2/362880) 1) (num-test (numerator 2/4) 1) (num-test (numerator 3/1) 3) (num-test (numerator 3/1234) 3) (num-test (numerator 3/3) 1) (num-test (numerator 3/500029) 3) (num-test (numerator 362880/10) 36288) (num-test (numerator 362880/1234000000) 567) (num-test (numerator 362880/2) 181440) (num-test (numerator 362880/362880) 1) (num-test (numerator 5/2) 5) (num-test (numerator 500029/1) 500029) (num-test (numerator 500029/1234) 500029) (num-test (numerator 500029/3) 500029) (num-test (numerator 500029/500029) 1) (num-test (numerator -9223372036854775808) -9223372036854775808) (num-test (numerator 9223372036854775807) 9223372036854775807) (num-test (numerator (/ 2 -1)) -2) (num-test (numerator (/ most-positive-fixnum 2)) most-positive-fixnum) (num-test (numerator (/ most-negative-fixnum 3)) most-negative-fixnum) (num-test (numerator (/ most-negative-fixnum most-positive-fixnum)) most-negative-fixnum) (if with-bignums (begin (num-test (numerator 1195068768795265792518361315725116351898245581/48889032896862784894921) 24444516448431392447461) (num-test (numerator 24444516448431392447461/1195068768795265792518361315725116351898245581) 1) (num-test (numerator -46116860184273879035/27670116110564327424) -46116860184273879035) (num-test (numerator (/ 9223372036854775808 -9223372036854775807)) -9223372036854775808) (num-test (numerator 1234567891234567890/1234567) 1234567891234567890) (num-test (numerator 9223372036854775808/9223372036854775807) 9223372036854775808) (test (numerator 0+92233720368547758081.0i) 'error) )) (test (numerator 0.0) 'error) ; guile thinks this is ok (test (numerator 1.23 1.23) 'error) (test (numerator 1.23+1.0i) 'error) (test (numerator) 'error) (test (numerator inf.0) 'error) (test (numerator nan.0) 'error) (test (numerator "hi") 'error) (test (numerator 1+i) 'error) (test (numerator 2.3+0.5i) 'error) (for-each (lambda (arg) (test (numerator arg) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) ;;; -------------------------------------------------------------------------------- ;;; denominator ;;; -------------------------------------------------------------------------------- (num-test (denominator (/ 8 -6)) 3) (num-test (denominator -1/10) 10) (num-test (denominator -1/1234000000) 1234000000) (num-test (denominator -1/2) 2) (num-test (denominator -1/362880) 362880) (num-test (denominator -10/1) 1) (num-test (denominator -10/1234) 617) (num-test (denominator -10/3) 3) (num-test (denominator -10/500029) 500029) (num-test (denominator -1234/10) 5) (num-test (denominator -1234/1234000000) 1000000) (num-test (denominator -1234/2) 1) (num-test (denominator -1234/362880) 181440) (num-test (denominator -1234000000/1) 1) (num-test (denominator -1234000000/1234) 1) (num-test (denominator -1234000000/3) 3) (num-test (denominator -1234000000/500029) 500029) (num-test (denominator -2/1) 1) (num-test (denominator -2/1234) 617) (num-test (denominator -2/3) 3) (num-test (denominator -2/500029) 500029) (num-test (denominator -2/6) 3) (num-test (denominator -3/10) 10) (num-test (denominator -3/1234000000) 1234000000) (num-test (denominator -3/2) 2) (num-test (denominator -3/362880) 120960) (num-test (denominator -362880/1) 1) (num-test (denominator -362880/1234) 617) (num-test (denominator -362880/3) 1) (num-test (denominator -362880/500029) 500029) (num-test (denominator -500029/10) 10) (num-test (denominator -500029/1234000000) 1234000000) (num-test (denominator -500029/2) 2) (num-test (denominator -500029/362880) 362880) (num-test (denominator 0) 1) (num-test (denominator 0/1) 1) (num-test (denominator 0/10) 1) (num-test (denominator 0/1234) 1) (num-test (denominator 0/1234000000) 1) (num-test (denominator 0/2) 1) (num-test (denominator 0/3) 1) (num-test (denominator 0/362880) 1) (num-test (denominator 0/500029) 1) (num-test (denominator 1) 1) (num-test (denominator 1/1) 1) (num-test (denominator 1/1234) 1234) (num-test (denominator 1/3) 3) (num-test (denominator 1/500029) 500029) (num-test (denominator 10/10) 1) (num-test (denominator 10/1234000000) 123400000) (num-test (denominator 10/2) 1) (num-test (denominator 10/362880) 36288) (num-test (denominator 12/6000996) 500083) (num-test (denominator 1234/1) 1) (num-test (denominator 1234/1234) 1) (num-test (denominator 1234/3) 3) (num-test (denominator 1234/500029) 500029) (num-test (denominator 1234000000/10) 1) (num-test (denominator 1234000000/1234000000) 1) (num-test (denominator 1234000000/2) 1) (num-test (denominator 1234000000/362880) 567) (num-test (denominator 2/10) 5) (num-test (denominator 2/1234000000) 617000000) (num-test (denominator 2/2) 1) (num-test (denominator 2/3) 3) (num-test (denominator 2/362880) 181440) (num-test (denominator 2/4) 2) (num-test (denominator 3/1) 1) (num-test (denominator 3/1234) 1234) (num-test (denominator 3/3) 1) (num-test (denominator 3/500029) 500029) (num-test (denominator 362880/10) 1) (num-test (denominator 362880/1234000000) 1928125) (num-test (denominator 362880/2) 1) (num-test (denominator 362880/362880) 1) (num-test (denominator 5/2) 2) (num-test (denominator 500029/1) 1) (num-test (denominator 500029/1234) 1234) (num-test (denominator 500029/3) 3) (num-test (denominator 500029/500029) 1) (num-test (denominator -9223372036854775808) 1) (num-test (denominator 9223372036854775807) 1) (num-test (denominator (/ 2 -1)) 1) (num-test (denominator (/ 1 most-positive-fixnum)) most-positive-fixnum) (num-test (denominator (/ most-negative-fixnum most-positive-fixnum)) most-positive-fixnum) (if with-bignums (begin (num-test (denominator 1195068768795265792518361315725116351898245581/48889032896862784894921) 1) (num-test (denominator 24444516448431392447461/1195068768795265792518361315725116351898245581) 48889032896862784894921) (num-test (denominator -46116860184273879035/27670116110564327424) 27670116110564327424) (num-test (denominator (/ 9223372036854775808 -9223372036854775807)) 9223372036854775807) (num-test (denominator 1234567891234567890/1234567) 1234567) (num-test (denominator 9223372036854775808/9223372036854775807) 9223372036854775807) (test (denominator 0+92233720368547758081.0i) 'error) )) (test (denominator 0.0) 'error) (test (denominator 1.23 1.23) 'error) (test (denominator 1.23+1.0i) 'error) (test (denominator) 'error) (test (denominator inf.0) 'error) (test (denominator nan.0) 'error) (test (denominator "hi") 'error) (test (denominator 1+i) 'error) (test (denominator 2.3+0.5i) 'error) (for-each (lambda (arg) (test (denominator arg) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) ;;; -------------------------------------------------------------------------------- ;;; real-part ;;; -------------------------------------------------------------------------------- (num-test (real-part -0.0+0.00000001i) 0.0) (num-test (real-part -0.0+1234.0i) 0.0) (num-test (real-part -0.0-3.14159265358979i) 0.0) (num-test (real-part -0.00000001+1.0i) -0.00000001) (num-test (real-part -0.00000001+1234000000.0i) -0.00000001) (num-test (real-part -0.00000001-0.0i) -0.00000001) (num-test (real-part -0.00000001-2.71828182845905i) -0.00000001) (num-test (real-part -1.0+3.14159265358979i) -1.0) (num-test (real-part -1.0-0.00000001i) -1.0) (num-test (real-part -1.0-1234.0i) -1.0) (num-test (real-part -1234.0+1.0i) -1234.0) (num-test (real-part -1234.0+1234000000.0i) -1234.0) (num-test (real-part -1234.0-0.0i) -1234.0) (num-test (real-part -1234.0-2.71828182845905i) -1234.0) (num-test (real-part -1234000000.0+3.14159265358979i) -1234000000.0) (num-test (real-part -1234000000.0-0.00000001i) -1234000000.0) (num-test (real-part -1234000000.0-1234.0i) -1234000000.0) (num-test (real-part -2.71828182845905+0.00000001i) -2.71828182845905) (num-test (real-part -2.71828182845905+1234.0i) -2.71828182845905) (num-test (real-part -2.71828182845905-3.14159265358979i) -2.71828182845905) (num-test (real-part -3.14159265358979+0.0i) -3.14159265358979) (num-test (real-part -3.14159265358979+2.71828182845905i) -3.14159265358979) (num-test (real-part -3.14159265358979-1.0i) -3.14159265358979) (num-test (real-part -3.14159265358979-1234000000.0i) -3.14159265358979) (num-test (real-part 0.0+0.0i) 0.0) (num-test (real-part 0.0+2.71828182845905i) 0.0) (num-test (real-part 0.0-1.0i) 0.0) (num-test (real-part 0.0-1234000000.0i) 0.0) (num-test (real-part 0.00000001+0.00000001i) 0.00000001) (num-test (real-part 0.00000001+1234.0i) 0.00000001) (num-test (real-part 0.00000001-3.14159265358979i) 0.00000001) (num-test (real-part 1) 1) (num-test (real-part 1.0+1.0i) 1.0) (num-test (real-part 1.0+1234000000.0i) 1.0) (num-test (real-part 1.0-0.0i) 1.0) (num-test (real-part 1.0-2.71828182845905i) 1.0) (num-test (real-part 1.4+0.0i) 1.4) (num-test (real-part 1234.0+0.00000001i) 1234.0) (num-test (real-part 1234.0+1234.0i) 1234.0) (num-test (real-part 1234.0-3.14159265358979i) 1234.0) (num-test (real-part 1234000000.0+1.0i) 1234000000.0) (num-test (real-part 1234000000.0+1234000000.0i) 1234000000.0) (num-test (real-part 1234000000.0-0.0i) 1234000000.0) (num-test (real-part 1234000000.0-2.71828182845905i) 1234000000.0) (num-test (real-part 2.0) 2.0) (num-test (real-part 2.71828182845905+0.0i) 2.71828182845905) (num-test (real-part 2.71828182845905+2.71828182845905i) 2.71828182845905) (num-test (real-part 2.71828182845905-1.0i) 2.71828182845905) (num-test (real-part 2.71828182845905-1234000000.0i) 2.71828182845905) (num-test (real-part 2/3) 2/3) (num-test (real-part 3.14159265358979+3.14159265358979i) 3.14159265358979) (num-test (real-part 3.14159265358979-0.00000001i) 3.14159265358979) (num-test (real-part 3.14159265358979-1234.0i) 3.14159265358979) (num-test (real-part 3/4+1/2i) 0.75) (num-test (real-part 5) 5) (num-test (real-part -1.797693134862315699999999999999999999998E308) -1.797693134862315699999999999999999999998E308) (num-test (real-part -2.225073858507201399999999999999999999996E-308) -2.225073858507201399999999999999999999996E-308) (num-test (real-part -9223372036854775808) -9223372036854775808) (num-test (real-part 1.110223024625156799999999999999999999997E-16) 1.110223024625156799999999999999999999997E-16) (num-test (real-part 9223372036854775807) 9223372036854775807) (test (real-part inf.0) inf.0) (num-test (real-part (+ 2 0+1/0i)) 2) (if with-bignums (begin (num-test (real-part 0+1e400i) 0.0) (num-test (real-part 0+9223372036854775808.0i) 0.0) (num-test (real-part 1.5+9223372036854775808.0i) 1.5) (num-test (real-part 9223372036854775808.0) 9223372036854775808.0) (num-test (real-part 9223372036854775808.0+1.5i) 9.223372036854775808E18) )) (test (denominator (real-part 3/4+1/2i)) 'error) (num-test (denominator (real-part 01/100)) 100) (test (real-part "hi") 'error) (test (real-part 1.0+23.0i 1.0+23.0i) 'error) (test (real-part) 'error) (for-each (lambda (arg) (test (real-part arg) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) ;;; -------------------------------------------------------------------------------- ;;; imag-part ;;; -------------------------------------------------------------------------------- (num-test (imag-part -0.0+0.00000001i) 0.00000001) (num-test (imag-part -0.0+1234.0i) 1234.0) (num-test (imag-part -0.0-3.14159265358979i) -3.14159265358979) (num-test (imag-part -0.00000001+1.0i) 1.0) (num-test (imag-part -0.00000001+1234000000.0i) 1234000000.0) (num-test (imag-part -0.00000001-0.0i) 0.0) (num-test (imag-part -0.00000001-2.71828182845905i) -2.71828182845905) (num-test (imag-part -1.0+3.14159265358979i) 3.14159265358979) (num-test (imag-part -1.0-0.00000001i) -0.00000001) (num-test (imag-part -1.0-1234.0i) -1234.0) (num-test (imag-part -1234.0+1.0i) 1.0) (num-test (imag-part -1234.0+1234000000.0i) 1234000000.0) (num-test (imag-part -1234.0-0.0i) 0.0) (num-test (imag-part -1234.0-2.71828182845905i) -2.71828182845905) (num-test (imag-part -1234000000.0+3.14159265358979i) 3.14159265358979) (num-test (imag-part -1234000000.0-0.00000001i) -0.00000001) (num-test (imag-part -1234000000.0-1234.0i) -1234.0) (num-test (imag-part -2.0) 0.0) (num-test (imag-part -2.71828182845905+0.00000001i) 0.00000001) (num-test (imag-part -2.71828182845905+1234.0i) 1234.0) (num-test (imag-part -2.71828182845905-3.14159265358979i) -3.14159265358979) (num-test (imag-part -3.14159265358979+0.0i) 0.0) (num-test (imag-part -3.14159265358979+2.71828182845905i) 2.71828182845905) (num-test (imag-part -3.14159265358979-1.0i) -1.0) (num-test (imag-part -3.14159265358979-1234000000.0i) -1234000000.0) (num-test (imag-part 0+i) 1.0) (num-test (imag-part 0.0+0.0i) 0.0) (num-test (imag-part 0.0+2.71828182845905i) 2.71828182845905) (num-test (imag-part 0.0-1.0i) -1.0) (num-test (imag-part 0.0-1234000000.0i) -1234000000.0) (num-test (imag-part 0.00000001+0.00000001i) 0.00000001) (num-test (imag-part 0.00000001+1234.0i) 1234.0) (num-test (imag-part 0.00000001-3.14159265358979i) -3.14159265358979) (num-test (imag-part 1) 0.0) (num-test (imag-part 1+i) 1.0) (num-test (imag-part 1-i) -1.0) (num-test (imag-part 1.0+1.0i) 1.0) (num-test (imag-part 1.0+1234000000.0i) 1234000000.0) (num-test (imag-part 1.0-0.0i) 0.0) (num-test (imag-part 1.0-2.71828182845905i) -2.71828182845905) (num-test (imag-part 1.4+0.0i) 0.0) (num-test (imag-part 1234.0+0.00000001i) 0.00000001) (num-test (imag-part 1234.0+1234.0i) 1234.0) (num-test (imag-part 1234.0-3.14159265358979i) -3.14159265358979) (num-test (imag-part 1234000000.0+1.0i) 1.0) (num-test (imag-part 1234000000.0+1234000000.0i) 1234000000.0) (num-test (imag-part 1234000000.0-0.0i) 0.0) (num-test (imag-part 1234000000.0-2.71828182845905i) -2.71828182845905) (num-test (imag-part 2.71828182845905+0.0i) 0.0) (num-test (imag-part 2.71828182845905+2.71828182845905i) 2.71828182845905) (num-test (imag-part 2.71828182845905-1.0i) -1.0) (num-test (imag-part 2.71828182845905-1234000000.0i) -1234000000.0) (num-test (imag-part 2/3) 0.0) (num-test (imag-part 3.14159265358979+3.14159265358979i) 3.14159265358979) (num-test (imag-part 3.14159265358979-0.00000001i) -0.00000001) (num-test (imag-part 3.14159265358979-1234.0i) -1234.0) (num-test (imag-part 5) 0.0) (num-test (imag-part -1.797693134862315699999999999999999999998E308) 0.0) (num-test (imag-part -2.225073858507201399999999999999999999996E-308) 0.0) (num-test (imag-part -9223372036854775808) 0) (num-test (imag-part 1.110223024625156799999999999999999999997E-16) 0.0) (num-test (imag-part 9223372036854775807) 0) (if (not with-bignums) (test (nan? (imag-part (+ 2 0+1/0i))) #t)) (num-test (imag-part 0/0+0i) 0.0) (num-test (imag-part 1/0) 0.0) ;(num-test (imag-part (log 1/0)) pi) ; hmmm -- I could imagine other choices here and below ;(num-test (imag-part (sqrt 1/0)) 0.0) ;(test (nan? (imag-part (sqrt (log 1/0)))) #t) (if with-bignums (begin (num-test (imag-part 0+1e400i) 1e400) (num-test (imag-part 0+9223372036854775808.0i) 9223372036854775808.0) (num-test (imag-part 1.5+9223372036854775808.0i) 9.223372036854775808E18) (num-test (imag-part 9223372036854775808.0) 0) (num-test (imag-part 9223372036854775808.0+1.5i) 1.5) )) (test (imag-part "hi") 'error) (test (imag-part 1.0+23.0i 1.0+23.0i) 'error) (test (imag-part) 'error) (for-each (lambda (arg) (test (imag-part arg) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) ;;; -------------------------------------------------------------------------------- ;;; complex ;;; -------------------------------------------------------------------------------- (num-test (complex -0 -1) -0.0-1.0i) (num-test (complex -0 -10) -0.0-10.0i) (num-test (complex -0 -1234) -0.0-1234.0i) (num-test (complex -0 -1234000000) -0.0-1234000000.0i) (num-test (complex -0 -2) -0.0-2.0i) (num-test (complex -0 -3) -0.0-3.0i) (num-test (complex -0 -362880) -0.0-362880.0i) (num-test (complex -0 -500029) -0.0-500029.0i) (num-test (complex -0 1) -0.0+1.0i) (num-test (complex -0 10) -0.0+10.0i) (num-test (complex -0 1234) -0.0+1234.0i) (num-test (complex -0 1234000000) -0.0+1234000000.0i) (num-test (complex -0 2) -0.0+2.0i) (num-test (complex -0 3) -0.0+3.0i) (num-test (complex -0 362880) -0.0+362880.0i) (num-test (complex -0 500029) -0.0+500029.0i) (num-test (complex -0.0 -0.00000001) -0.0-0.00000001i) (num-test (complex -0.0 -1.0) -0.0-1.0i) (num-test (complex -0.0 -1234.0) -0.0-1234.0i) (num-test (complex -0.0 -1234000000.0) -0.0-1234000000.0i) (num-test (complex -0.0 -2.71828182845905) -0.0-2.71828182845905i) (num-test (complex -0.0 -3.14159265358979) -0.0-3.14159265358979i) (num-test (complex -0.0 0.00000001) -0.0+0.00000001i) (num-test (complex -0.0 1.0) -0.0+1.0i) (num-test (complex -0.0 1234.0) -0.0+1234.0i) (num-test (complex -0.0 1234000000.0) -0.0+1234000000.0i) (num-test (complex -0.0 2.71828182845905) -0.0+2.71828182845905i) (num-test (complex -0.0 pi) -0.0+3.14159265358979i) (num-test (complex -0.00000001 -0.00000001) -0.00000001-0.00000001i) (num-test (complex -0.00000001 -1.0) -0.00000001-1.0i) (num-test (complex -0.00000001 -1234.0) -0.00000001-1234.0i) (num-test (complex -0.00000001 -1234000000.0) -0.00000001-1234000000.0i) (num-test (complex -0.00000001 -2.71828182845905) -0.00000001-2.71828182845905i) (num-test (complex -0.00000001 -3.14159265358979) -0.00000001-3.14159265358979i) (num-test (complex -0.00000001 0.00000001) -0.00000001+0.00000001i) (num-test (complex -0.00000001 1.0) -0.00000001+1.0i) (num-test (complex -0.00000001 1234.0) -0.00000001+1234.0i) (num-test (complex -0.00000001 1234000000.0) -0.00000001+1234000000.0i) (num-test (complex -0.00000001 2.71828182845905) -0.00000001+2.71828182845905i) (num-test (complex -0.00000001 pi) -0.00000001+3.14159265358979i) (num-test (complex -1 -1) -1.0-1.0i) (num-test (complex -1 -10) -1.0-10.0i) (num-test (complex -1 -1234) -1.0-1234.0i) (num-test (complex -1 -1234000000) -1.0-1234000000.0i) (num-test (complex -1 -2) -1.0-2.0i) (num-test (complex -1 -3) -1.0-3.0i) (num-test (complex -1 -362880) -1.0-362880.0i) (num-test (complex -1 -500029) -1.0-500029.0i) (num-test (complex -1 1) -1.0+1.0i) (num-test (complex -1 10) -1.0+10.0i) (num-test (complex -1 1234) -1.0+1234.0i) (num-test (complex -1 1234000000) -1.0+1234000000.0i) (num-test (complex -1 2) -1.0+2.0i) (num-test (complex -1 3) -1.0+3.0i) (num-test (complex -1 362880) -1.0+362880.0i) (num-test (complex -1 500029) -1.0+500029.0i) (num-test (complex -1.0 -0.00000001) -1.0-0.00000001i) (num-test (complex -1.0 -1.0) -1.0-1.0i) (num-test (complex -1.0 -1234.0) -1.0-1234.0i) (num-test (complex -1.0 -1234000000.0) -1.0-1234000000.0i) (num-test (complex -1.0 -2.71828182845905) -1.0-2.71828182845905i) (num-test (complex -1.0 -3.14159265358979) -1.0-3.14159265358979i) (num-test (complex -1.0 0.00000001) -1.0+0.00000001i) (num-test (complex -1.0 1.0) -1.0+1.0i) (num-test (complex -1.0 1234.0) -1.0+1234.0i) (num-test (complex -1.0 1234000000.0) -1.0+1234000000.0i) (num-test (complex -1.0 2.71828182845905) -1.0+2.71828182845905i) (num-test (complex -1.0 pi) -1.0+3.14159265358979i) (num-test (complex -10 -1) -10.0-1.0i) (num-test (complex -10 -10) -10.0-10.0i) (num-test (complex -10 -1234) -10.0-1234.0i) (num-test (complex -10 -1234000000) -10.0-1234000000.0i) (num-test (complex -10 -2) -10.0-2.0i) (num-test (complex -10 -3) -10.0-3.0i) (num-test (complex -10 -362880) -10.0-362880.0i) (num-test (complex -10 -500029) -10.0-500029.0i) (num-test (complex -10 1) -10.0+1.0i) (num-test (complex -10 10) -10.0+10.0i) (num-test (complex -10 1234) -10.0+1234.0i) (num-test (complex -10 1234000000) -10.0+1234000000.0i) (num-test (complex -10 2) -10.0+2.0i) (num-test (complex -10 3) -10.0+3.0i) (num-test (complex -10 362880) -10.0+362880.0i) (num-test (complex -10 500029) -10.0+500029.0i) (num-test (complex -1234 -1) -1234.0-1.0i) (num-test (complex -1234 -10) -1234.0-10.0i) (num-test (complex -1234 -1234) -1234.0-1234.0i) (num-test (complex -1234 -1234000000) -1234.0-1234000000.0i) (num-test (complex -1234 -2) -1234.0-2.0i) (num-test (complex -1234 -3) -1234.0-3.0i) (num-test (complex -1234 -362880) -1234.0-362880.0i) (num-test (complex -1234 -500029) -1234.0-500029.0i) (num-test (complex -1234 1) -1234.0+1.0i) (num-test (complex -1234 10) -1234.0+10.0i) (num-test (complex -1234 1234) -1234.0+1234.0i) (num-test (complex -1234 1234000000) -1234.0+1234000000.0i) (num-test (complex -1234 2) -1234.0+2.0i) (num-test (complex -1234 3) -1234.0+3.0i) (num-test (complex -1234 362880) -1234.0+362880.0i) (num-test (complex -1234 500029) -1234.0+500029.0i) (num-test (complex -1234.0 -0.00000001) -1234.0-0.00000001i) (num-test (complex -1234.0 -1.0) -1234.0-1.0i) (num-test (complex -1234.0 -1234.0) -1234.0-1234.0i) (num-test (complex -1234.0 -1234000000.0) -1234.0-1234000000.0i) (num-test (complex -1234.0 -2.71828182845905) -1234.0-2.71828182845905i) (num-test (complex -1234.0 -3.14159265358979) -1234.0-3.14159265358979i) (num-test (complex -1234.0 0.00000001) -1234.0+0.00000001i) (num-test (complex -1234.0 1.0) -1234.0+1.0i) (num-test (complex -1234.0 1234.0) -1234.0+1234.0i) (num-test (complex -1234.0 1234000000.0) -1234.0+1234000000.0i) (num-test (complex -1234.0 2.71828182845905) -1234.0+2.71828182845905i) (num-test (complex -1234.0 pi) -1234.0+3.14159265358979i) (num-test (complex -1234000000 -1) -1234000000.0-1.0i) (num-test (complex -1234000000 -10) -1234000000.0-10.0i) (num-test (complex -1234000000 -1234) -1234000000.0-1234.0i) (num-test (complex -1234000000 -1234000000) -1234000000.0-1234000000.0i) (num-test (complex -1234000000 -2) -1234000000.0-2.0i) (num-test (complex -1234000000 -3) -1234000000.0-3.0i) (num-test (complex -1234000000 -362880) -1234000000.0-362880.0i) (num-test (complex -1234000000 -500029) -1234000000.0-500029.0i) (num-test (complex -1234000000 1) -1234000000.0+1.0i) (num-test (complex -1234000000 10) -1234000000.0+10.0i) (num-test (complex -1234000000 1234) -1234000000.0+1234.0i) (num-test (complex -1234000000 1234000000) -1234000000.0+1234000000.0i) (num-test (complex -1234000000 2) -1234000000.0+2.0i) (num-test (complex -1234000000 3) -1234000000.0+3.0i) (num-test (complex -1234000000 362880) -1234000000.0+362880.0i) (num-test (complex -1234000000 500029) -1234000000.0+500029.0i) (num-test (complex -1234000000.0 -0.00000001) -1234000000.0-0.00000001i) (num-test (complex -1234000000.0 -1.0) -1234000000.0-1.0i) (num-test (complex -1234000000.0 -1234.0) -1234000000.0-1234.0i) (num-test (complex -1234000000.0 -1234000000.0) -1234000000.0-1234000000.0i) (num-test (complex -1234000000.0 -2.71828182845905) -1234000000.0-2.71828182845905i) (num-test (complex -1234000000.0 -3.14159265358979) -1234000000.0-3.14159265358979i) (num-test (complex -1234000000.0 0.00000001) -1234000000.0+0.00000001i) (num-test (complex -1234000000.0 1.0) -1234000000.0+1.0i) (num-test (complex -1234000000.0 1234.0) -1234000000.0+1234.0i) (num-test (complex -1234000000.0 1234000000.0) -1234000000.0+1234000000.0i) (num-test (complex -1234000000.0 2.71828182845905) -1234000000.0+2.71828182845905i) (num-test (complex -1234000000.0 pi) -1234000000.0+3.14159265358979i) (num-test (complex -2 -1) -2.0-1.0i) (num-test (complex -2 -10) -2.0-10.0i) (num-test (complex -2 -1234) -2.0-1234.0i) (num-test (complex -2 -1234000000) -2.0-1234000000.0i) (num-test (complex -2 -2) -2.0-2.0i) (num-test (complex -2 -3) -2.0-3.0i) (num-test (complex -2 -362880) -2.0-362880.0i) (num-test (complex -2 -500029) -2.0-500029.0i) (num-test (complex -2 1) -2.0+1.0i) (num-test (complex -2 10) -2.0+10.0i) (num-test (complex -2 1234) -2.0+1234.0i) (num-test (complex -2 1234000000) -2.0+1234000000.0i) (num-test (complex -2 2) -2.0+2.0i) (num-test (complex -2 3) -2.0+3.0i) (num-test (complex -2 362880) -2.0+362880.0i) (num-test (complex -2 500029) -2.0+500029.0i) (num-test (complex -2.71828182845905 -0.00000001) -2.71828182845905-0.00000001i) (num-test (complex -2.71828182845905 -1.0) -2.71828182845905-1.0i) (num-test (complex -2.71828182845905 -1234.0) -2.71828182845905-1234.0i) (num-test (complex -2.71828182845905 -1234000000.0) -2.71828182845905-1234000000.0i) (num-test (complex -2.71828182845905 -2.71828182845905) -2.71828182845905-2.71828182845905i) (num-test (complex -2.71828182845905 -3.14159265358979) -2.71828182845905-3.14159265358979i) (num-test (complex -2.71828182845905 0.00000001) -2.71828182845905+0.00000001i) (num-test (complex -2.71828182845905 1.0) -2.71828182845905+1.0i) (num-test (complex -2.71828182845905 1234.0) -2.71828182845905+1234.0i) (num-test (complex -2.71828182845905 1234000000.0) -2.71828182845905+1234000000.0i) (num-test (complex -2.71828182845905 2.71828182845905) -2.71828182845905+2.71828182845905i) (num-test (complex -2.71828182845905 pi) -2.71828182845905+3.14159265358979i) (num-test (complex -3 -1) -3.0-1.0i) (num-test (complex -3 -10) -3.0-10.0i) (num-test (complex -3 -1234) -3.0-1234.0i) (num-test (complex -3 -1234000000) -3.0-1234000000.0i) (num-test (complex -3 -2) -3.0-2.0i) (num-test (complex -3 -3) -3.0-3.0i) (num-test (complex -3 -362880) -3.0-362880.0i) (num-test (complex -3 -500029) -3.0-500029.0i) (num-test (complex -3 1) -3.0+1.0i) (num-test (complex -3 10) -3.0+10.0i) (num-test (complex -3 1234) -3.0+1234.0i) (num-test (complex -3 1234000000) -3.0+1234000000.0i) (num-test (complex -3 2) -3.0+2.0i) (num-test (complex -3 3) -3.0+3.0i) (num-test (complex -3 362880) -3.0+362880.0i) (num-test (complex -3 500029) -3.0+500029.0i) (num-test (complex -3.14159265358979 -0.00000001) -3.14159265358979-0.00000001i) (num-test (complex -3.14159265358979 -1.0) -3.14159265358979-1.0i) (num-test (complex -3.14159265358979 -1234.0) -3.14159265358979-1234.0i) (num-test (complex -3.14159265358979 -1234000000.0) -3.14159265358979-1234000000.0i) (num-test (complex -3.14159265358979 -2.71828182845905) -3.14159265358979-2.71828182845905i) (num-test (complex -3.14159265358979 -3.14159265358979) -3.14159265358979-3.14159265358979i) (num-test (complex -3.14159265358979 0.00000001) -3.14159265358979+0.00000001i) (num-test (complex -3.14159265358979 1.0) -3.14159265358979+1.0i) (num-test (complex -3.14159265358979 1234.0) -3.14159265358979+1234.0i) (num-test (complex -3.14159265358979 1234000000.0) -3.14159265358979+1234000000.0i) (num-test (complex -3.14159265358979 2.71828182845905) -3.14159265358979+2.71828182845905i) (num-test (complex -3.14159265358979 pi) -3.14159265358979+3.14159265358979i) (num-test (complex -362880 -1) -362880.0-1.0i) (num-test (complex -362880 -10) -362880.0-10.0i) (num-test (complex -362880 -1234) -362880.0-1234.0i) (num-test (complex -362880 -1234000000) -362880.0-1234000000.0i) (num-test (complex -362880 -2) -362880.0-2.0i) (num-test (complex -362880 -3) -362880.0-3.0i) (num-test (complex -362880 -362880) -362880.0-362880.0i) (num-test (complex -362880 -500029) -362880.0-500029.0i) (num-test (complex -362880 1) -362880.0+1.0i) (num-test (complex -362880 10) -362880.0+10.0i) (num-test (complex -362880 1234) -362880.0+1234.0i) (num-test (complex -362880 1234000000) -362880.0+1234000000.0i) (num-test (complex -362880 2) -362880.0+2.0i) (num-test (complex -362880 3) -362880.0+3.0i) (num-test (complex -362880 362880) -362880.0+362880.0i) (num-test (complex -362880 500029) -362880.0+500029.0i) (num-test (complex -500029 -1) -500029.0-1.0i) (num-test (complex -500029 -10) -500029.0-10.0i) (num-test (complex -500029 -1234) -500029.0-1234.0i) (num-test (complex -500029 -1234000000) -500029.0-1234000000.0i) (num-test (complex -500029 -2) -500029.0-2.0i) (num-test (complex -500029 -3) -500029.0-3.0i) (num-test (complex -500029 -362880) -500029.0-362880.0i) (num-test (complex -500029 -500029) -500029.0-500029.0i) (num-test (complex -500029 1) -500029.0+1.0i) (num-test (complex -500029 10) -500029.0+10.0i) (num-test (complex -500029 1234) -500029.0+1234.0i) (num-test (complex -500029 1234000000) -500029.0+1234000000.0i) (num-test (complex -500029 2) -500029.0+2.0i) (num-test (complex -500029 3) -500029.0+3.0i) (num-test (complex -500029 362880) -500029.0+362880.0i) (num-test (complex -500029 500029) -500029.0+500029.0i) (num-test (complex 0 -1) 0.0-1.0i) (num-test (complex 0 -10) 0.0-10.0i) (num-test (complex 0 -1234) 0.0-1234.0i) (num-test (complex 0 -1234000000) 0.0-1234000000.0i) (num-test (complex 0 -2) 0.0-2.0i) (num-test (complex 0 -3) 0.0-3.0i) (num-test (complex 0 -362880) 0.0-362880.0i) (num-test (complex 0 -500029) 0.0-500029.0i) (num-test (complex 0 0) 0) (num-test (complex 0 1) 0.0+1.0i) (num-test (complex 0 10) 0.0+10.0i) (num-test (complex 0 1234) 0.0+1234.0i) (num-test (complex 0 1234000000) 0.0+1234000000.0i) (num-test (complex 0 2) 0.0+2.0i) (num-test (complex 0 3) 0.0+3.0i) (num-test (complex 0 362880) 0.0+362880.0i) (num-test (complex 0 500029) 0.0+500029.0i) (num-test (complex 0.0 -0.00000001) 0.0-0.00000001i) (num-test (complex 0.0 -1.0) 0.0-1.0i) (num-test (complex 0.0 -1234.0) 0.0-1234.0i) (num-test (complex 0.0 -1234000000.0) 0.0-1234000000.0i) (num-test (complex 0.0 -2.71828182845905) 0.0-2.71828182845905i) (num-test (complex 0.0 -3.14159265358979) 0.0-3.14159265358979i) (num-test (complex 0.0 0.0) 0.0) (num-test (complex 0.0 0.00000001) 0.0+0.00000001i) (num-test (complex 0.0 1.0) 0.0+1.0i) (num-test (complex 0.0 1234.0) 0.0+1234.0i) (num-test (complex 0.0 1234000000.0) 0.0+1234000000.0i) (num-test (complex 0.0 2.71828182845905) 0.0+2.71828182845905i) (num-test (complex 0.0 pi) 0.0+3.14159265358979i) (num-test (complex 0.00000001 -0.00000001) 0.00000001-0.00000001i) (num-test (complex 0.00000001 -1.0) 0.00000001-1.0i) (num-test (complex 0.00000001 -1234.0) 0.00000001-1234.0i) (num-test (complex 0.00000001 -1234000000.0) 0.00000001-1234000000.0i) (num-test (complex 0.00000001 -2.71828182845905) 0.00000001-2.71828182845905i) (num-test (complex 0.00000001 -3.14159265358979) 0.00000001-3.14159265358979i) (num-test (complex 0.00000001 0.00000001) 0.00000001+0.00000001i) (num-test (complex 0.00000001 1.0) 0.00000001+1.0i) (num-test (complex 0.00000001 1234.0) 0.00000001+1234.0i) (num-test (complex 0.00000001 1234000000.0) 0.00000001+1234000000.0i) (num-test (complex 0.00000001 2.71828182845905) 0.00000001+2.71828182845905i) (num-test (complex 0.00000001 pi) 0.00000001+3.14159265358979i) (num-test (complex 1 -1) 1.0-1.0i) (num-test (complex 1 -10) 1.0-10.0i) (num-test (complex 1 -1234) 1.0-1234.0i) (num-test (complex 1 -1234000000) 1.0-1234000000.0i) (num-test (complex 1 -2) 1.0-2.0i) (num-test (complex 1 -3) 1.0-3.0i) (num-test (complex 1 -362880) 1.0-362880.0i) (num-test (complex 1 -500029) 1.0-500029.0i) (num-test (complex 1 1) 1.0+1.0i) (num-test (complex 1 10) 1.0+10.0i) (num-test (complex 1 1234) 1.0+1234.0i) (num-test (complex 1 1234000000) 1.0+1234000000.0i) (num-test (complex 1 2) 1.0+2.0i) (num-test (complex 1 3) 1.0+3.0i) (num-test (complex 1 362880) 1.0+362880.0i) (num-test (complex 1 500029) 1.0+500029.0i) (num-test (complex 1.0 -0.00000001) 1.0-0.00000001i) (num-test (complex 1.0 -1.0) 1.0-1.0i) (num-test (complex 1.0 -1234.0) 1.0-1234.0i) (num-test (complex 1.0 -1234000000.0) 1.0-1234000000.0i) (num-test (complex 1.0 -2.71828182845905) 1.0-2.71828182845905i) (num-test (complex 1.0 -3.14159265358979) 1.0-3.14159265358979i) (num-test (complex 1.0 0.00000001) 1.0+0.00000001i) (num-test (complex 1.0 1.0) 1.0+1.0i) (num-test (complex 1.0 1234.0) 1.0+1234.0i) (num-test (complex 1.0 1234000000.0) 1.0+1234000000.0i) (num-test (complex 1.0 2.71828182845905) 1.0+2.71828182845905i) (num-test (complex 1.0 pi) 1.0+3.14159265358979i) (num-test (complex 10 -1) 10.0-1.0i) (num-test (complex 10 -10) 10.0-10.0i) (num-test (complex 10 -1234) 10.0-1234.0i) (num-test (complex 10 -1234000000) 10.0-1234000000.0i) (num-test (complex 10 -2) 10.0-2.0i) (num-test (complex 10 -3) 10.0-3.0i) (num-test (complex 10 -362880) 10.0-362880.0i) (num-test (complex 10 -500029) 10.0-500029.0i) (num-test (complex 10 1) 10.0+1.0i) (num-test (complex 10 10) 10.0+10.0i) (num-test (complex 10 1234) 10.0+1234.0i) (num-test (complex 10 1234000000) 10.0+1234000000.0i) (num-test (complex 10 2) 10.0+2.0i) (num-test (complex 10 3) 10.0+3.0i) (num-test (complex 10 362880) 10.0+362880.0i) (num-test (complex 10 500029) 10.0+500029.0i) (num-test (complex 1234 -1) 1234.0-1.0i) (num-test (complex 1234 -10) 1234.0-10.0i) (num-test (complex 1234 -1234) 1234.0-1234.0i) (num-test (complex 1234 -1234000000) 1234.0-1234000000.0i) (num-test (complex 1234 -2) 1234.0-2.0i) (num-test (complex 1234 -3) 1234.0-3.0i) (num-test (complex 1234 -362880) 1234.0-362880.0i) (num-test (complex 1234 -500029) 1234.0-500029.0i) (num-test (complex 1234 1) 1234.0+1.0i) (num-test (complex 1234 10) 1234.0+10.0i) (num-test (complex 1234 1234) 1234.0+1234.0i) (num-test (complex 1234 1234000000) 1234.0+1234000000.0i) (num-test (complex 1234 2) 1234.0+2.0i) (num-test (complex 1234 3) 1234.0+3.0i) (num-test (complex 1234 362880) 1234.0+362880.0i) (num-test (complex 1234 500029) 1234.0+500029.0i) (num-test (complex 1234.0 -0.00000001) 1234.0-0.00000001i) (num-test (complex 1234.0 -1.0) 1234.0-1.0i) (num-test (complex 1234.0 -1234.0) 1234.0-1234.0i) (num-test (complex 1234.0 -1234000000.0) 1234.0-1234000000.0i) (num-test (complex 1234.0 -2.71828182845905) 1234.0-2.71828182845905i) (num-test (complex 1234.0 -3.14159265358979) 1234.0-3.14159265358979i) (num-test (complex 1234.0 0.00000001) 1234.0+0.00000001i) (num-test (complex 1234.0 1.0) 1234.0+1.0i) (num-test (complex 1234.0 1234.0) 1234.0+1234.0i) (num-test (complex 1234.0 1234000000.0) 1234.0+1234000000.0i) (num-test (complex 1234.0 2.71828182845905) 1234.0+2.71828182845905i) (num-test (complex 1234.0 pi) 1234.0+3.14159265358979i) (num-test (complex 1234000000 -1) 1234000000.0-1.0i) (num-test (complex 1234000000 -10) 1234000000.0-10.0i) (num-test (complex 1234000000 -1234) 1234000000.0-1234.0i) (num-test (complex 1234000000 -1234000000) 1234000000.0-1234000000.0i) (num-test (complex 1234000000 -2) 1234000000.0-2.0i) (num-test (complex 1234000000 -3) 1234000000.0-3.0i) (num-test (complex 1234000000 -362880) 1234000000.0-362880.0i) (num-test (complex 1234000000 -500029) 1234000000.0-500029.0i) (num-test (complex 1234000000 1) 1234000000.0+1.0i) (num-test (complex 1234000000 10) 1234000000.0+10.0i) (num-test (complex 1234000000 1234) 1234000000.0+1234.0i) (num-test (complex 1234000000 1234000000) 1234000000.0+1234000000.0i) (num-test (complex 1234000000 2) 1234000000.0+2.0i) (num-test (complex 1234000000 3) 1234000000.0+3.0i) (num-test (complex 1234000000 362880) 1234000000.0+362880.0i) (num-test (complex 1234000000 500029) 1234000000.0+500029.0i) (num-test (complex 1234000000.0 -0.00000001) 1234000000.0-0.00000001i) (num-test (complex 1234000000.0 -1.0) 1234000000.0-1.0i) (num-test (complex 1234000000.0 -1234.0) 1234000000.0-1234.0i) (num-test (complex 1234000000.0 -1234000000.0) 1234000000.0-1234000000.0i) (num-test (complex 1234000000.0 -2.71828182845905) 1234000000.0-2.71828182845905i) (num-test (complex 1234000000.0 -3.14159265358979) 1234000000.0-3.14159265358979i) (num-test (complex 1234000000.0 0.00000001) 1234000000.0+0.00000001i) (num-test (complex 1234000000.0 1.0) 1234000000.0+1.0i) (num-test (complex 1234000000.0 1234.0) 1234000000.0+1234.0i) (num-test (complex 1234000000.0 1234000000.0) 1234000000.0+1234000000.0i) (num-test (complex 1234000000.0 2.71828182845905) 1234000000.0+2.71828182845905i) (num-test (complex 1234000000.0 pi) 1234000000.0+3.14159265358979i) (num-test (complex 2 -1) 2.0-1.0i) (num-test (complex 2 -10) 2.0-10.0i) (num-test (complex 2 -1234) 2.0-1234.0i) (num-test (complex 2 -1234000000) 2.0-1234000000.0i) (num-test (complex 2 -2) 2.0-2.0i) (num-test (complex 2 -3) 2.0-3.0i) (num-test (complex 2 -362880) 2.0-362880.0i) (num-test (complex 2 -500029) 2.0-500029.0i) (num-test (complex 2 1) 2.0+1.0i) (num-test (complex 2 10) 2.0+10.0i) (num-test (complex 2 1234) 2.0+1234.0i) (num-test (complex 2 1234000000) 2.0+1234000000.0i) (num-test (complex 2 2) 2.0+2.0i) (num-test (complex 2 3) 2.0+3.0i) (num-test (complex 2 362880) 2.0+362880.0i) (num-test (complex 2 500029) 2.0+500029.0i) (num-test (complex 2.71828182845905 -0.00000001) 2.71828182845905-0.00000001i) (num-test (complex 2.71828182845905 -1.0) 2.71828182845905-1.0i) (num-test (complex 2.71828182845905 -1234.0) 2.71828182845905-1234.0i) (num-test (complex 2.71828182845905 -1234000000.0) 2.71828182845905-1234000000.0i) (num-test (complex 2.71828182845905 -2.71828182845905) 2.71828182845905-2.71828182845905i) (num-test (complex 2.71828182845905 -3.14159265358979) 2.71828182845905-3.14159265358979i) (num-test (complex 2.71828182845905 0.00000001) 2.71828182845905+0.00000001i) (num-test (complex 2.71828182845905 1.0) 2.71828182845905+1.0i) (num-test (complex 2.71828182845905 1234.0) 2.71828182845905+1234.0i) (num-test (complex 2.71828182845905 1234000000.0) 2.71828182845905+1234000000.0i) (num-test (complex 2.71828182845905 2.71828182845905) 2.71828182845905+2.71828182845905i) (num-test (complex 2.71828182845905 pi) 2.71828182845905+3.14159265358979i) (num-test (complex 3 -1) 3.0-1.0i) (num-test (complex 3 -10) 3.0-10.0i) (num-test (complex 3 -1234) 3.0-1234.0i) (num-test (complex 3 -1234000000) 3.0-1234000000.0i) (num-test (complex 3 -2) 3.0-2.0i) (num-test (complex 3 -3) 3.0-3.0i) (num-test (complex 3 -362880) 3.0-362880.0i) (num-test (complex 3 -500029) 3.0-500029.0i) (num-test (complex 3 1) 3.0+1.0i) (num-test (complex 3 10) 3.0+10.0i) (num-test (complex 3 1234) 3.0+1234.0i) (num-test (complex 3 1234000000) 3.0+1234000000.0i) (num-test (complex 3 2) 3.0+2.0i) (num-test (complex 3 3) 3.0+3.0i) (num-test (complex 3 362880) 3.0+362880.0i) (num-test (complex 3 500029) 3.0+500029.0i) (num-test (complex 3.14159265358979 -0.00000001) 3.14159265358979-0.00000001i) (num-test (complex 3.14159265358979 -1.0) 3.14159265358979-1.0i) (num-test (complex 3.14159265358979 -1234.0) 3.14159265358979-1234.0i) (num-test (complex 3.14159265358979 -1234000000.0) 3.14159265358979-1234000000.0i) (num-test (complex 3.14159265358979 -2.71828182845905) 3.14159265358979-2.71828182845905i) (num-test (complex 3.14159265358979 -3.14159265358979) 3.14159265358979-3.14159265358979i) (num-test (complex 3.14159265358979 0.00000001) 3.14159265358979+0.00000001i) (num-test (complex 3.14159265358979 1.0) 3.14159265358979+1.0i) (num-test (complex 3.14159265358979 1234.0) 3.14159265358979+1234.0i) (num-test (complex 3.14159265358979 1234000000.0) 3.14159265358979+1234000000.0i) (num-test (complex 3.14159265358979 2.71828182845905) 3.14159265358979+2.71828182845905i) (num-test (complex 3.14159265358979 pi) 3.14159265358979+3.14159265358979i) (num-test (complex 362880 -1) 362880.0-1.0i) (num-test (complex 362880 -10) 362880.0-10.0i) (num-test (complex 362880 -1234) 362880.0-1234.0i) (num-test (complex 362880 -1234000000) 362880.0-1234000000.0i) (num-test (complex 362880 -2) 362880.0-2.0i) (num-test (complex 362880 -3) 362880.0-3.0i) (num-test (complex 362880 -362880) 362880.0-362880.0i) (num-test (complex 362880 -500029) 362880.0-500029.0i) (num-test (complex 362880 1) 362880.0+1.0i) (num-test (complex 362880 10) 362880.0+10.0i) (num-test (complex 362880 1234) 362880.0+1234.0i) (num-test (complex 362880 1234000000) 362880.0+1234000000.0i) (num-test (complex 362880 2) 362880.0+2.0i) (num-test (complex 362880 3) 362880.0+3.0i) (num-test (complex 362880 362880) 362880.0+362880.0i) (num-test (complex 362880 500029) 362880.0+500029.0i) (num-test (complex 500029 -1) 500029.0-1.0i) (num-test (complex 500029 -10) 500029.0-10.0i) (num-test (complex 500029 -1234) 500029.0-1234.0i) (num-test (complex 500029 -1234000000) 500029.0-1234000000.0i) (num-test (complex 500029 -2) 500029.0-2.0i) (num-test (complex 500029 -3) 500029.0-3.0i) (num-test (complex 500029 -362880) 500029.0-362880.0i) (num-test (complex 500029 -500029) 500029.0-500029.0i) (num-test (complex 500029 1) 500029.0+1.0i) (num-test (complex 500029 10) 500029.0+10.0i) (num-test (complex 500029 1234) 500029.0+1234.0i) (num-test (complex 500029 1234000000) 500029.0+1234000000.0i) (num-test (complex 500029 2) 500029.0+2.0i) (num-test (complex 500029 3) 500029.0+3.0i) (num-test (complex 500029 362880) 500029.0+362880.0i) (num-test (complex 500029 500029) 500029.0+500029.0i) (num-test (complex 1/2 0) 1/2) (num-test (complex 1/2 1/2) 0.5+0.5i) (num-test (complex 0 1/2) 0+0.5i) (test (nan? (complex nan.0 nan.0)) #t) (test (nan? (complex nan.0 inf.0)) #t) (if with-bignums (begin (test (nan? (complex (bignum "0/0") 0)) #t) (test (nan? (complex 0 (bignum "0/0"))) #t) (num-test (complex 0 (* 2 most-positive-fixnum)) 0.0+1.8446744073709551614E19i) (num-test (- (complex 2e20 (* 2 most-positive-fixnum)) 0+1.8446744073709551614E19i) 2e20) (num-test (imag-part (complex 1.0 1180591620717411303424/717897987691852588770249)) 1.644511672909387396372163624382128338027E-3) (test (complex 0.0 0+92233720368547758081.0i) 'error) )) (test (complex 0 0+0/0i) 'error) (test (complex 0+0/0i 0) 'error) (test (complex 1.23 1.23 1.23) 'error) (test (complex 1.23) 'error) (test (complex 1.23+1.0i 1.23+1.0i) 'error) (test (complex) 'error) (test (complex 1.0 1.0+0.1i) 'error) (test (complex 1.0+0.1i 1.0) 'error) (for-each (lambda (x) (test (complex x 0-i) 'error)) (list 0 1 1/2 1.0 0.0 0+i)) (for-each (lambda (x) (test (complex 0-i x) 'error)) (list 0 1 pi (- pi) 1/2 0.0 1.0 0+i)) (for-each (lambda (arg) (test (complex arg 0.0) 'error) (test (complex 0.0 arg) 'error) (test (complex arg nan.0) 'error) (test (complex nan.0 arg) 'error) (test (complex arg inf.0) 'error) (test (complex inf.0 arg) 'error) (test (complex 1 arg) 'error) (test (complex 1/2 arg) 'error) (test (complex 1+i arg) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) ;;; -------------------------------------------------------------------------------- ;;; make-polar ;;; -------------------------------------------------------------------------------- (num-test (make-polar -0 -1) 0) (num-test (make-polar -0 -10) 0) (num-test (make-polar -0 -1234) 0) (num-test (make-polar -0 -1234000000) 0) (num-test (make-polar -0 -2) 0) (num-test (make-polar -0 -3) 0) (num-test (make-polar -0 -362880) 0) (num-test (make-polar -0 -500029) 0) (num-test (make-polar -0 1) 0) (num-test (make-polar -0 10) 0) (num-test (make-polar -0 1234) 0) (num-test (make-polar -0 1234000000) 0) (num-test (make-polar -0 2) 0) (num-test (make-polar -0 3) 0) (num-test (make-polar -0 362880) 0) (num-test (make-polar -0 500029) 0) (num-test (make-polar -0.0 -0.00000001) 0.0) (num-test (make-polar -0.0 -1.0) 0.0) (num-test (make-polar -0.0 -1234.0) 0.0) (num-test (make-polar -0.0 -1234000000.0) 0.0) (num-test (make-polar -0.0 -2.71828182845905) 0.0) (num-test (make-polar -0.0 -3.14159265358979) 0.0) (num-test (make-polar -0.0 0.00000001) 0.0) (num-test (make-polar -0.0 1.0) 0.0) (num-test (make-polar -0.0 1234.0) 0.0) (num-test (make-polar -0.0 1234000000.0) 0.0) (num-test (make-polar -0.0 2.71828182845905) 0.0) (num-test (make-polar -0.0 pi) 0.0) (num-test (make-polar -0.00000001 -0.00000001) -0.00000001+1e-16i) (num-test (make-polar -0.00000001 -1.0) -0.00000000540302+0.00000000841471i) (num-test (make-polar -0.00000001 -1234.0) 0.00000000798551+0.00000000601928i) (num-test (make-polar -0.00000001 -1234000000.0) -0.00000000158909-0.00000000987293i) (num-test (make-polar -0.00000001 -2.71828182845905) 0.00000000911734+0.00000000410781i) (num-test (make-polar -0.00000001 (- pi)) 0.00000001) (num-test (make-polar -0.00000001 0.00000001) -0.00000001-1e-16i) (num-test (make-polar -0.00000001 1.0) -0.00000000540302-0.00000000841471i) (num-test (make-polar -0.00000001 1234.0) 0.00000000798551-0.00000000601928i) (num-test (make-polar -0.00000001 1234000000.0) -0.00000000158909+0.00000000987293i) (num-test (make-polar -0.00000001 2.71828182845905) 0.00000000911734-0.00000000410781i) (num-test (make-polar -0.00000001 pi) 0.00000001-0.0i) (num-test (make-polar -1 -1) -0.54030230586814+0.84147098480790i) (num-test (make-polar -1 -10) 0.83907152907645-0.54402111088937i) (num-test (make-polar -1 -1234) 0.79855062358758+0.60192765476250i) (num-test (make-polar -1 -1234000000) -0.15890913095152-0.98729321283003i) (num-test (make-polar -1 -2) 0.41614683654714+0.90929742682568i) (num-test (make-polar -1 -3) 0.98999249660045+0.14112000805987i) (num-test (make-polar -1 -362880) -0.60918079547638+0.79303137291204i) (num-test (make-polar -1 -500029) -0.85414905629947+0.52002825848479i) (num-test (make-polar -1 1) -0.54030230586814-0.84147098480790i) (num-test (make-polar -1 10) 0.83907152907645+0.54402111088937i) (num-test (make-polar -1 1234) 0.79855062358758-0.60192765476250i) (num-test (make-polar -1 1234000000) -0.15890913095152+0.98729321283003i) (num-test (make-polar -1 2) 0.41614683654714-0.90929742682568i) (num-test (make-polar -1 3) 0.98999249660045-0.14112000805987i) (num-test (make-polar -1 362880) -0.60918079547638-0.79303137291204i) (num-test (make-polar -1 500029) -0.85414905629947-0.52002825848479i) (num-test (make-polar -1.0 -0.00000001) -1.0+0.00000001i) (num-test (make-polar -1.0 -1.0) -0.54030230586814+0.84147098480790i) (num-test (make-polar -1.0 -1234.0) 0.79855062358758+0.60192765476250i) (num-test (make-polar -1.0 -1234000000.0) -0.15890913095152-0.98729321283003i) (num-test (make-polar -1.0 -2.71828182845905) 0.91173391478697+0.41078129050291i) (num-test (make-polar -1.0 (- pi)) 1.0) (num-test (make-polar -1.0 0.00000001) -1.0-0.00000001i) (num-test (make-polar -1.0 1.0) -0.54030230586814-0.84147098480790i) (num-test (make-polar -1.0 1234.0) 0.79855062358758-0.60192765476250i) (num-test (make-polar -1.0 1234000000.0) -0.15890913095152+0.98729321283003i) (num-test (make-polar -1.0 2.71828182845905) 0.91173391478697-0.41078129050291i) (num-test (make-polar -1.0 pi) 1.0-0.0i) (num-test (make-polar -10 -1) -5.40302305868140+8.41470984807897i) (num-test (make-polar -10 -10) 8.39071529076452-5.44021110889370i) (num-test (make-polar -10 -1234) 7.98550623587584+6.01927654762497i) (num-test (make-polar -10 -1234000000) -1.58909130951517-9.87293212830025i) (num-test (make-polar -10 -2) 4.16146836547142+9.09297426825682i) (num-test (make-polar -10 -3) 9.89992496600445+1.41120008059867i) (num-test (make-polar -10 -362880) -6.09180795476385+7.93031372912042i) (num-test (make-polar -10 -500029) -8.54149056299473+5.20028258484786i) (num-test (make-polar -10 1) -5.40302305868140-8.41470984807897i) (num-test (make-polar -10 10) 8.39071529076452+5.44021110889370i) (num-test (make-polar -10 1234) 7.98550623587584-6.01927654762497i) (num-test (make-polar -10 1234000000) -1.58909130951517+9.87293212830025i) (num-test (make-polar -10 2) 4.16146836547142-9.09297426825682i) (num-test (make-polar -10 3) 9.89992496600445-1.41120008059867i) (num-test (make-polar -10 362880) -6.09180795476385-7.93031372912042i) (num-test (make-polar -10 500029) -8.54149056299473-5.20028258484786i) (num-test (make-polar -1234 -1) -666.73304544128450+1038.37519525294420i) (num-test (make-polar -1234 -10) 1035.41426688034221-671.32205083748227i) (num-test (make-polar -1234 -1234) 985.41146950707912+742.77872597692169i) (num-test (make-polar -1234 -1234000000) -196.09386759417183-1218.31982463225131i) (num-test (make-polar -1234 -2) 513.52519629917379+1122.07302470289119i) (num-test (make-polar -1234 -3) 1221.65074080494969+174.14208994587614i) (num-test (make-polar -1234 -362880) -751.72910161785899+978.60071417346035i) (num-test (make-polar -1234 -500029) -1054.01993547355005+641.71487097022577i) (num-test (make-polar -1234 1) -666.73304544128450-1038.37519525294420i) (num-test (make-polar -1234 10) 1035.41426688034221+671.32205083748227i) (num-test (make-polar -1234 1234) 985.41146950707912-742.77872597692169i) (num-test (make-polar -1234 1234000000) -196.09386759417183+1218.31982463225131i) (num-test (make-polar -1234 2) 513.52519629917379-1122.07302470289119i) (num-test (make-polar -1234 3) 1221.65074080494969-174.14208994587614i) (num-test (make-polar -1234 362880) -751.72910161785899-978.60071417346035i) (num-test (make-polar -1234 500029) -1054.01993547355005-641.71487097022577i) (num-test (make-polar -1234.0 -0.00000001) -1234.0+0.00001234000000i) (num-test (make-polar -1234.0 -1.0) -666.73304544128450+1038.37519525294420i) (num-test (make-polar -1234.0 -1234.0) 985.41146950707912+742.77872597692169i) (num-test (make-polar -1234.0 -1234000000.0) -196.09386759417183-1218.31982463225131i) (num-test (make-polar -1234.0 -2.71828182845905) 1125.07965084711486+506.90411248058950i) (num-test (make-polar -1234.0 (- pi)) 1234.0+0.00000000000015i) (num-test (make-polar -1234.0 0.00000001) -1234.0-0.00001234000000i) (num-test (make-polar -1234.0 1.0) -666.73304544128450-1038.37519525294420i) (num-test (make-polar -1234.0 1234.0) 985.41146950707912-742.77872597692169i) (num-test (make-polar -1234.0 1234000000.0) -196.09386759417183+1218.31982463225131i) (num-test (make-polar -1234.0 2.71828182845905) 1125.07965084711486-506.90411248058950i) (num-test (make-polar -1234.0 pi) 1234.0-0.00000000000015i) (num-test (make-polar -1234000000 -1) -666733045.44128441810608+1038375195.25294423103333i) (num-test (make-polar -1234000000 -10) 1035414266.88034236431122-671322050.83748233318329i) (num-test (make-polar -1234000000 -1234) 985411469.50707900524139+742778725.97692167758942i) (num-test (make-polar -1234000000 -1234000000) -196093867.59417182207108-1218319824.63225126266479i) (num-test (make-polar -1234000000 -2) 513525196.29917371273041+1122073024.70289111137390i) (num-test (make-polar -1234000000 -3) 1221650740.80494976043701+174142089.94587615132332i) (num-test (make-polar -1234000000 -362880) -751729101.61785900592804+978600714.17346036434174i) (num-test (make-polar -1234000000 -500029) -1054019935.47354996204376+641714870.97022569179535i) (num-test (make-polar -1234000000 1) -666733045.44128441810608-1038375195.25294423103333i) (num-test (make-polar -1234000000 10) 1035414266.88034236431122+671322050.83748233318329i) (num-test (make-polar -1234000000 1234) 985411469.50707900524139-742778725.97692167758942i) (num-test (make-polar -1234000000 1234000000) -196093867.59417182207108+1218319824.63225126266479i) (num-test (make-polar -1234000000 2) 513525196.29917371273041-1122073024.70289111137390i) (num-test (make-polar -1234000000 3) 1221650740.80494976043701-174142089.94587615132332i) (num-test (make-polar -1234000000 362880) -751729101.61785900592804-978600714.17346036434174i) (num-test (make-polar -1234000000 500029) -1054019935.47354996204376-641714870.97022569179535i) (num-test (make-polar -1234000000.0 -0.00000001) -1234000000.0+12.34000000000000i) (num-test (make-polar -1234000000.0 -1.0) -666733045.44128441810608+1038375195.25294423103333i) (num-test (make-polar -1234000000.0 -1234.0) 985411469.50707900524139+742778725.97692167758942i) (num-test (make-polar -1234000000.0 -1234000000.0) -196093867.59417182207108-1218319824.63225126266479i) (num-test (make-polar -1234000000.0 -2.71828182845905) 1125079650.84711480140686+506904112.48058950901031i) (num-test (make-polar -1234000000.0 (- pi)) 1234000000.0+0.00000015111642i) (num-test (make-polar -1234000000.0 0.00000001) -1234000000.0-12.34000000000000i) (num-test (make-polar -1234000000.0 1.0) -666733045.44128441810608-1038375195.25294423103333i) (num-test (make-polar -1234000000.0 1234.0) 985411469.50707900524139-742778725.97692167758942i) (num-test (make-polar -1234000000.0 1234000000.0) -196093867.59417182207108+1218319824.63225126266479i) (num-test (make-polar -1234000000.0 2.71828182845905) 1125079650.84711480140686-506904112.48058950901031i) (num-test (make-polar -1234000000.0 pi) 1234000000.0-0.00000015111642i) (num-test (make-polar -2 -1) -1.08060461173628+1.68294196961579i) (num-test (make-polar -2 -10) 1.67814305815290-1.08804222177874i) (num-test (make-polar -2 -1234) 1.59710124717517+1.20385530952499i) (num-test (make-polar -2 -1234000000) -0.31781826190303-1.97458642566005i) (num-test (make-polar -2 -2) 0.83229367309428+1.81859485365136i) (num-test (make-polar -2 -3) 1.97998499320089+0.28224001611973i) (num-test (make-polar -2 -362880) -1.21836159095277+1.58606274582408i) (num-test (make-polar -2 -500029) -1.70829811259895+1.04005651696957i) (num-test (make-polar -2 1) -1.08060461173628-1.68294196961579i) (num-test (make-polar -2 10) 1.67814305815290+1.08804222177874i) (num-test (make-polar -2 1234) 1.59710124717517-1.20385530952499i) (num-test (make-polar -2 1234000000) -0.31781826190303+1.97458642566005i) (num-test (make-polar -2 2) 0.83229367309428-1.81859485365136i) (num-test (make-polar -2 3) 1.97998499320089-0.28224001611973i) (num-test (make-polar -2 362880) -1.21836159095277-1.58606274582408i) (num-test (make-polar -2 500029) -1.70829811259895-1.04005651696957i) (num-test (make-polar -2.71828182845905 -0.00000001) -2.71828182845905+0.00000002718282i) (num-test (make-polar -2.71828182845905 -1.0) -1.46869393991589+2.28735528717884i) (num-test (make-polar -2.71828182845905 -1234.0) 2.17068564920277+1.63620900598787i) (num-test (make-polar -2.71828182845905 -1234000000.0) -0.43195980304173-2.68374119979681i) (num-test (make-polar -2.71828182845905 -2.71828182845905) 2.47834973295523+1.11661931744501i) (num-test (make-polar -2.71828182845905 -3.14159265358979) 2.71828182845905) (num-test (make-polar -2.71828182845905 0.00000001) -2.71828182845905-0.00000002718282i) (num-test (make-polar -2.71828182845905 1.0) -1.46869393991589-2.28735528717884i) (num-test (make-polar -2.71828182845905 1234.0) 2.17068564920277-1.63620900598787i) (num-test (make-polar -2.71828182845905 1234000000.0) -0.43195980304173+2.68374119979681i) (num-test (make-polar -2.71828182845905 2.71828182845905) 2.47834973295523-1.11661931744501i) (num-test (make-polar -2.71828182845905 pi) 2.71828182845905-0.0i) (num-test (make-polar -3 -1) -1.62090691760442+2.52441295442369i) (num-test (make-polar -3 -10) 2.51721458722936-1.63206333266811i) (num-test (make-polar -3 -1234) 2.39565187076275+1.80578296428749i) (num-test (make-polar -3 -1234000000) -0.47672739285455-2.96187963849008i) (num-test (make-polar -3 -2) 1.24844050964143+2.72789228047704i) (num-test (make-polar -3 -3) 2.96997748980134+0.42336002417960i) (num-test (make-polar -3 -362880) -1.82754238642915+2.37909411873613i) (num-test (make-polar -3 -500029) -2.56244716889842+1.56008477545436i) (num-test (make-polar -3 1) -1.62090691760442-2.52441295442369i) (num-test (make-polar -3 10) 2.51721458722936+1.63206333266811i) (num-test (make-polar -3 1234) 2.39565187076275-1.80578296428749i) (num-test (make-polar -3 1234000000) -0.47672739285455+2.96187963849008i) (num-test (make-polar -3 2) 1.24844050964143-2.72789228047704i) (num-test (make-polar -3 3) 2.96997748980134-0.42336002417960i) (num-test (make-polar -3 362880) -1.82754238642915-2.37909411873613i) (num-test (make-polar -3 500029) -2.56244716889842-1.56008477545436i) (num-test (make-polar -3.14159265358979 -0.00000001) -3.14159265358979+0.00000003141593i) (num-test (make-polar -3.14159265358979 -1.0) -1.69740975483297+2.64355906408146i) (num-test (make-polar -3.14159265358979 -1234.0) 2.50872077258230+1.89101149819439i) (num-test (make-polar -3.14159265358979 -1234000000.0) -0.49922775838562-3.10167310436587i) (num-test (make-polar -3.14159265358979 -2.71828182845905) 2.86429656872339+1.29050748447607i) (num-test (make-polar -3.14159265358979 -3.14159265358979) 3.14159265358979) (num-test (make-polar -3.14159265358979 0.00000001) -3.14159265358979-0.00000003141593i) (num-test (make-polar -3.14159265358979 1.0) -1.69740975483297-2.64355906408146i) (num-test (make-polar -3.14159265358979 1234.0) 2.50872077258230-1.89101149819439i) (num-test (make-polar -3.14159265358979 1234000000.0) -0.49922775838562+3.10167310436587i) (num-test (make-polar -3.14159265358979 2.71828182845905) 2.86429656872339-1.29050748447607i) (num-test (make-polar -3.14159265358979 pi) 3.14159265358979-0.0i) (num-test (make-polar -362880 -1) -196064.90075343055651+305352.99096708948491i) (num-test (make-polar -362880 -10) 304482.27647126308875-197414.38071953449980i) (num-test (make-polar -362880 -1234) 289778.05028746259632+218427.50736021503690i) (num-test (make-polar -362880 -1234000000) -57664.94543968644575-358268.96107175957877i) (num-test (make-polar -362880 -2) 151011.36404622704140+329965.85024650336709i) (num-test (make-polar -362880 -3) 359248.47716636961559+51209.62852476461558i) (num-test (make-polar -362880 -362880) -221059.52706247055903+287775.22460232191952i) (num-test (make-polar -362880 -500029) -309953.60954995284555+188707.85443895909702i) (num-test (make-polar -362880 1) -196064.90075343055651-305352.99096708948491i) (num-test (make-polar -362880 10) 304482.27647126308875+197414.38071953449980i) (num-test (make-polar -362880 1234) 289778.05028746259632-218427.50736021503690i) (num-test (make-polar -362880 1234000000) -57664.94543968644575+358268.96107175957877i) (num-test (make-polar -362880 2) 151011.36404622704140-329965.85024650336709i) (num-test (make-polar -362880 3) 359248.47716636961559-51209.62852476461558i) (num-test (make-polar -362880 362880) -221059.52706247055903-287775.22460232191952i) (num-test (make-polar -362880 500029) -309953.60954995284555-188707.85443895909702i) (num-test (make-polar -500029 -1) -270166.82170094008325+420759.89506250765407i) (num-test (make-polar -500029 -10) 419560.09761256945785-272026.33205690066097i) (num-test (make-polar -500029 -1234) 399298.46976187621476+300981.28328323678579i) (num-test (make-polar -500029 -1234000000) -79459.17384055603179-493675.23791818472091i) (num-test (make-polar -500029 -2) 208085.48653183106217+454675.08303821878508i) (num-test (make-polar -500029 -3) 495024.95808262412902+70564.09651016735006i) (num-test (make-polar -500029 -362880) -304608.06398126127897+396538.68436583562288i) (num-test (make-polar -500029 -500029) -427099.29847236932255+260029.21006188896718i) (num-test (make-polar -500029 1) -270166.82170094008325-420759.89506250765407i) (num-test (make-polar -500029 10) 419560.09761256945785+272026.33205690066097i) (num-test (make-polar -500029 1234) 399298.46976187621476-300981.28328323678579i) (num-test (make-polar -500029 1234000000) -79459.17384055603179+493675.23791818472091i) (num-test (make-polar -500029 2) 208085.48653183106217-454675.08303821878508i) (num-test (make-polar -500029 3) 495024.95808262412902-70564.09651016735006i) (num-test (make-polar -500029 362880) -304608.06398126127897-396538.68436583562288i) (num-test (make-polar -500029 500029) -427099.29847236932255-260029.21006188896718i) (num-test (make-polar 0 -1) 0) (num-test (make-polar 0 -10) 0) (num-test (make-polar 0 -1234) 0) (num-test (make-polar 0 -1234000000) 0) (num-test (make-polar 0 -2) 0) (num-test (make-polar 0 -3) 0) (num-test (make-polar 0 -362880) 0) (num-test (make-polar 0 -500029) 0) (num-test (make-polar 0 0) 0) (num-test (make-polar 0 1) 0) (num-test (make-polar 0 10) 0) (num-test (make-polar 0 1234) 0) (num-test (make-polar 0 1234000000) 0) (num-test (make-polar 0 2) 0) (num-test (make-polar 0 3) 0) (num-test (make-polar 0 362880) 0) (num-test (make-polar 0 500029) 0) (num-test (make-polar 0 922337203685477) 0) (num-test (make-polar 0 1/922337203685477) 0) (num-test (make-polar 0.0 -0.00000001) 0.0) (num-test (make-polar 0.0 -1.0) 0.0) (num-test (make-polar 0.0 -1234.0) 0.0) (num-test (make-polar 0.0 -1234000000.0) 0.0) (num-test (make-polar 0.0 -2.71828182845905) 0.0) (num-test (make-polar 0.0 -3.14159265358979) 0.0) (num-test (make-polar 0.0 0.0) 0.0) (num-test (make-polar 0.0 0.00000001) 0.0) (num-test (make-polar 0.0 1.0) 0.0) (num-test (make-polar 0.0 1234.0) 0.0) (num-test (make-polar 0.0 1234000000.0) 0.0) (num-test (make-polar 0.0 2.71828182845905) 0.0) (num-test (make-polar 0.0 pi) 0.0) (num-test (make-polar 0.00000001 -0.00000001) 0.00000001-1e-16i) (num-test (make-polar 0.00000001 -1.0) 0.00000000540302-0.00000000841471i) (num-test (make-polar 0.00000001 -1234.0) -0.00000000798551-0.00000000601928i) (num-test (make-polar 0.00000001 -1234000000.0) 0.00000000158909+0.00000000987293i) (num-test (make-polar 0.00000001 -2.71828182845905) -0.00000000911734-0.00000000410781i) (num-test (make-polar 0.00000001 -3.14159265358979) -0.00000001-0.0i) (num-test (make-polar 0.00000001 0.00000001) 0.00000001+1e-16i) (num-test (make-polar 0.00000001 1.0) 0.00000000540302+0.00000000841471i) (num-test (make-polar 0.00000001 1234.0) -0.00000000798551+0.00000000601928i) (num-test (make-polar 0.00000001 1234000000.0) 0.00000000158909-0.00000000987293i) (num-test (make-polar 0.00000001 2.71828182845905) -0.00000000911734+0.00000000410781i) (num-test (make-polar 0.00000001 pi) -0.00000001) (num-test (make-polar 1 -1) 0.54030230586814-0.84147098480790i) (num-test (make-polar 1 -10) -0.83907152907645+0.54402111088937i) (num-test (make-polar 1 -1234) -0.79855062358758-0.60192765476250i) (num-test (make-polar 1 -1234000000) 0.15890913095152+0.98729321283003i) (num-test (make-polar 1 -2) -0.41614683654714-0.90929742682568i) (num-test (make-polar 1 -3) -0.98999249660045-0.14112000805987i) (num-test (make-polar 1 -362880) 0.60918079547638-0.79303137291204i) (num-test (make-polar 1 -500029) 0.85414905629947-0.52002825848479i) (num-test (make-polar 1 1) 0.54030230586814+0.84147098480790i) (num-test (make-polar 1 10) -0.83907152907645-0.54402111088937i) (num-test (make-polar 1 1234) -0.79855062358758+0.60192765476250i) (num-test (make-polar 1 1234000000) 0.15890913095152-0.98729321283003i) (num-test (make-polar 1 2) -0.41614683654714+0.90929742682568i) (num-test (make-polar 1 3) -0.98999249660045+0.14112000805987i) (num-test (make-polar 1 362880) 0.60918079547638+0.79303137291204i) (num-test (make-polar 1 500029) 0.85414905629947+0.52002825848479i) (num-test (make-polar 1.0 -0.00000001) 1.0-0.00000001i) (num-test (make-polar 1.0 -1.0) 0.54030230586814-0.84147098480790i) (num-test (make-polar 1.0 -1234.0) -0.79855062358758-0.60192765476250i) (num-test (make-polar 1.0 -1234000000.0) 0.15890913095152+0.98729321283003i) (num-test (make-polar 1.0 -2.71828182845905) -0.91173391478697-0.41078129050291i) (num-test (make-polar 1.0 -3.14159265358979) -1.0-0.0i) (num-test (make-polar 1.0 0.00000001) 1.0+0.00000001i) (num-test (make-polar 1.0 1.0) 0.54030230586814+0.84147098480790i) (num-test (make-polar 1.0 1234.0) -0.79855062358758+0.60192765476250i) (num-test (make-polar 1.0 1234000000.0) 0.15890913095152-0.98729321283003i) (num-test (make-polar 1.0 2.71828182845905) -0.91173391478697+0.41078129050291i) (num-test (make-polar 1.0 pi) -1.0) (num-test (make-polar 10 -1) 5.40302305868140-8.41470984807897i) (num-test (make-polar 10 -10) -8.39071529076452+5.44021110889370i) (num-test (make-polar 10 -1234) -7.98550623587584-6.01927654762497i) (num-test (make-polar 10 -1234000000) 1.58909130951517+9.87293212830025i) (num-test (make-polar 10 -2) -4.16146836547142-9.09297426825682i) (num-test (make-polar 10 -3) -9.89992496600445-1.41120008059867i) (num-test (make-polar 10 -362880) 6.09180795476385-7.93031372912042i) (num-test (make-polar 10 -500029) 8.54149056299473-5.20028258484786i) (num-test (make-polar 10 1) 5.40302305868140+8.41470984807897i) (num-test (make-polar 10 10) -8.39071529076452-5.44021110889370i) (num-test (make-polar 10 1234) -7.98550623587584+6.01927654762497i) (num-test (make-polar 10 1234000000) 1.58909130951517-9.87293212830025i) (num-test (make-polar 10 2) -4.16146836547142+9.09297426825682i) (num-test (make-polar 10 3) -9.89992496600445+1.41120008059867i) (num-test (make-polar 10 362880) 6.09180795476385+7.93031372912042i) (num-test (make-polar 10 500029) 8.54149056299473+5.20028258484786i) (num-test (make-polar 1234 -1) 666.73304544128450-1038.37519525294420i) (num-test (make-polar 1234 -10) -1035.41426688034221+671.32205083748227i) (num-test (make-polar 1234 -1234) -985.41146950707912-742.77872597692169i) (num-test (make-polar 1234 -1234000000) 196.09386759417183+1218.31982463225131i) (num-test (make-polar 1234 -2) -513.52519629917379-1122.07302470289119i) (num-test (make-polar 1234 -3) -1221.65074080494969-174.14208994587614i) (num-test (make-polar 1234 -362880) 751.72910161785899-978.60071417346035i) (num-test (make-polar 1234 -500029) 1054.01993547355005-641.71487097022577i) (num-test (make-polar 1234 1) 666.73304544128450+1038.37519525294420i) (num-test (make-polar 1234 10) -1035.41426688034221-671.32205083748227i) (num-test (make-polar 1234 1234) -985.41146950707912+742.77872597692169i) (num-test (make-polar 1234 1234000000) 196.09386759417183-1218.31982463225131i) (num-test (make-polar 1234 2) -513.52519629917379+1122.07302470289119i) (num-test (make-polar 1234 3) -1221.65074080494969+174.14208994587614i) (num-test (make-polar 1234 362880) 751.72910161785899+978.60071417346035i) (num-test (make-polar 1234 500029) 1054.01993547355005+641.71487097022577i) (num-test (make-polar 1234.0 -0.00000001) 1234.0-0.00001234000000i) (num-test (make-polar 1234.0 -1.0) 666.73304544128450-1038.37519525294420i) (num-test (make-polar 1234.0 -1234.0) -985.41146950707912-742.77872597692169i) (num-test (make-polar 1234.0 -1234000000.0) 196.09386759417183+1218.31982463225131i) (num-test (make-polar 1234.0 -2.71828182845905) -1125.07965084711486-506.90411248058950i) (num-test (make-polar 1234.0 -3.14159265358979) -1234.0-0.00000000000015i) (num-test (make-polar 1234.0 0.00000001) 1234.0+0.00001234000000i) (num-test (make-polar 1234.0 1.0) 666.73304544128450+1038.37519525294420i) (num-test (make-polar 1234.0 1234.0) -985.41146950707912+742.77872597692169i) (num-test (make-polar 1234.0 1234000000.0) 196.09386759417183-1218.31982463225131i) (num-test (make-polar 1234.0 2.71828182845905) -1125.07965084711486+506.90411248058950i) (num-test (make-polar 1234.0 pi) -1234.0+0.00000000000015i) (num-test (make-polar 1234000000 -1) 666733045.44128441810608-1038375195.25294423103333i) (num-test (make-polar 1234000000 -10) -1035414266.88034236431122+671322050.83748233318329i) (num-test (make-polar 1234000000 -1234) -985411469.50707900524139-742778725.97692167758942i) (num-test (make-polar 1234000000 -1234000000) 196093867.59417182207108+1218319824.63225126266479i) (num-test (make-polar 1234000000 -2) -513525196.29917371273041-1122073024.70289111137390i) (num-test (make-polar 1234000000 -3) -1221650740.80494976043701-174142089.94587615132332i) (num-test (make-polar 1234000000 -362880) 751729101.61785900592804-978600714.17346036434174i) (num-test (make-polar 1234000000 -500029) 1054019935.47354996204376-641714870.97022569179535i) (num-test (make-polar 1234000000 1) 666733045.44128441810608+1038375195.25294423103333i) (num-test (make-polar 1234000000 10) -1035414266.88034236431122-671322050.83748233318329i) (num-test (make-polar 1234000000 1234) -985411469.50707900524139+742778725.97692167758942i) (num-test (make-polar 1234000000 1234000000) 196093867.59417182207108-1218319824.63225126266479i) (num-test (make-polar 1234000000 2) -513525196.29917371273041+1122073024.70289111137390i) (num-test (make-polar 1234000000 3) -1221650740.80494976043701+174142089.94587615132332i) (num-test (make-polar 1234000000 362880) 751729101.61785900592804+978600714.17346036434174i) (num-test (make-polar 1234000000 500029) 1054019935.47354996204376+641714870.97022569179535i) (num-test (make-polar 1234000000.0 -0.00000001) 1234000000.0-12.34000000000000i) (num-test (make-polar 1234000000.0 -1.0) 666733045.44128441810608-1038375195.25294423103333i) (num-test (make-polar 1234000000.0 -1234.0) -985411469.50707900524139-742778725.97692167758942i) (num-test (make-polar 1234000000.0 -1234000000.0) 196093867.59417182207108+1218319824.63225126266479i) (num-test (make-polar 1234000000.0 -2.71828182845905) -1125079650.84711480140686-506904112.48058950901031i) (num-test (make-polar 1234000000.0 -3.14159265358979) -1234000000.0-0.00000015111642i) (num-test (make-polar 1234000000.0 0.00000001) 1234000000.0+12.34000000000000i) (num-test (make-polar 1234000000.0 1.0) 666733045.44128441810608+1038375195.25294423103333i) (num-test (make-polar 1234000000.0 1234.0) -985411469.50707900524139+742778725.97692167758942i) (num-test (make-polar 1234000000.0 1234000000.0) 196093867.59417182207108-1218319824.63225126266479i) (num-test (make-polar 1234000000.0 2.71828182845905) -1125079650.84711480140686+506904112.48058950901031i) (num-test (make-polar 1234000000.0 pi) -1234000000.0+0.00000015111642i) (num-test (make-polar 2 -1) 1.08060461173628-1.68294196961579i) (num-test (make-polar 2 -10) -1.67814305815290+1.08804222177874i) (num-test (make-polar 2 -1234) -1.59710124717517-1.20385530952499i) (num-test (make-polar 2 -1234000000) 0.31781826190303+1.97458642566005i) (num-test (make-polar 2 -2) -0.83229367309428-1.81859485365136i) (num-test (make-polar 2 -3) -1.97998499320089-0.28224001611973i) (num-test (make-polar 2 -362880) 1.21836159095277-1.58606274582408i) (num-test (make-polar 2 -500029) 1.70829811259895-1.04005651696957i) (num-test (make-polar 2 1) 1.08060461173628+1.68294196961579i) (num-test (make-polar 2 10) -1.67814305815290-1.08804222177874i) (num-test (make-polar 2 1234) -1.59710124717517+1.20385530952499i) (num-test (make-polar 2 1234000000) 0.31781826190303-1.97458642566005i) (num-test (make-polar 2 2) -0.83229367309428+1.81859485365136i) (num-test (make-polar 2 3) -1.97998499320089+0.28224001611973i) (num-test (make-polar 2 362880) 1.21836159095277+1.58606274582408i) (num-test (make-polar 2 500029) 1.70829811259895+1.04005651696957i) (num-test (make-polar 2.71828182845905 -0.00000001) 2.71828182845905-0.00000002718282i) (num-test (make-polar 2.71828182845905 -1.0) 1.46869393991589-2.28735528717884i) (num-test (make-polar 2.71828182845905 -1234.0) -2.17068564920277-1.63620900598787i) (num-test (make-polar 2.71828182845905 -1234000000.0) 0.43195980304173+2.68374119979681i) (num-test (make-polar 2.71828182845905 -2.71828182845905) -2.47834973295523-1.11661931744501i) (num-test (make-polar 2.71828182845905 -3.14159265358979) -2.71828182845905-0.0i) (num-test (make-polar 2.71828182845905 0.00000001) 2.71828182845905+0.00000002718282i) (num-test (make-polar 2.71828182845905 1.0) 1.46869393991589+2.28735528717884i) (num-test (make-polar 2.71828182845905 1234.0) -2.17068564920277+1.63620900598787i) (num-test (make-polar 2.71828182845905 1234000000.0) 0.43195980304173-2.68374119979681i) (num-test (make-polar 2.71828182845905 2.71828182845905) -2.47834973295523+1.11661931744501i) (num-test (make-polar 2.71828182845905 pi) -2.71828182845905) (num-test (make-polar 3 -1) 1.62090691760442-2.52441295442369i) (num-test (make-polar 3 -10) -2.51721458722936+1.63206333266811i) (num-test (make-polar 3 -1234) -2.39565187076275-1.80578296428749i) (num-test (make-polar 3 -1234000000) 0.47672739285455+2.96187963849008i) (num-test (make-polar 3 -2) -1.24844050964143-2.72789228047704i) (num-test (make-polar 3 -3) -2.96997748980134-0.42336002417960i) (num-test (make-polar 3 -362880) 1.82754238642915-2.37909411873613i) (num-test (make-polar 3 -500029) 2.56244716889842-1.56008477545436i) (num-test (make-polar 3 1) 1.62090691760442+2.52441295442369i) (num-test (make-polar 3 10) -2.51721458722936-1.63206333266811i) (num-test (make-polar 3 1234) -2.39565187076275+1.80578296428749i) (num-test (make-polar 3 1234000000) 0.47672739285455-2.96187963849008i) (num-test (make-polar 3 2) -1.24844050964143+2.72789228047704i) (num-test (make-polar 3 3) -2.96997748980134+0.42336002417960i) (num-test (make-polar 3 362880) 1.82754238642915+2.37909411873613i) (num-test (make-polar 3 500029) 2.56244716889842+1.56008477545436i) (num-test (make-polar 3.14159265358979 -0.00000001) 3.14159265358979-0.00000003141593i) (num-test (make-polar 3.14159265358979 -1.0) 1.69740975483297-2.64355906408146i) (num-test (make-polar 3.14159265358979 -1234.0) -2.50872077258230-1.89101149819439i) (num-test (make-polar 3.14159265358979 -1234000000.0) 0.49922775838562+3.10167310436587i) (num-test (make-polar 3.14159265358979 -2.71828182845905) -2.86429656872339-1.29050748447607i) (num-test (make-polar 3.14159265358979 -3.14159265358979) -3.14159265358979-0.0i) (num-test (make-polar 3.14159265358979 0.00000001) 3.14159265358979+0.00000003141593i) (num-test (make-polar 3.14159265358979 1.0) 1.69740975483297+2.64355906408146i) (num-test (make-polar 3.14159265358979 1234.0) -2.50872077258230+1.89101149819439i) (num-test (make-polar 3.14159265358979 1234000000.0) 0.49922775838562-3.10167310436587i) (num-test (make-polar 3.14159265358979 2.71828182845905) -2.86429656872339+1.29050748447607i) (num-test (make-polar 3.14159265358979 pi) -3.14159265358979) (num-test (make-polar 362880 -1) 196064.90075343055651-305352.99096708948491i) (num-test (make-polar 362880 -10) -304482.27647126308875+197414.38071953449980i) (num-test (make-polar 362880 -1234) -289778.05028746259632-218427.50736021503690i) (num-test (make-polar 362880 -1234000000) 57664.94543968644575+358268.96107175957877i) (num-test (make-polar 362880 -2) -151011.36404622704140-329965.85024650336709i) (num-test (make-polar 362880 -3) -359248.47716636961559-51209.62852476461558i) (num-test (make-polar 362880 -362880) 221059.52706247055903-287775.22460232191952i) (num-test (make-polar 362880 -500029) 309953.60954995284555-188707.85443895909702i) (num-test (make-polar 362880 1) 196064.90075343055651+305352.99096708948491i) (num-test (make-polar 362880 10) -304482.27647126308875-197414.38071953449980i) (num-test (make-polar 362880 1234) -289778.05028746259632+218427.50736021503690i) (num-test (make-polar 362880 1234000000) 57664.94543968644575-358268.96107175957877i) (num-test (make-polar 362880 2) -151011.36404622704140+329965.85024650336709i) (num-test (make-polar 362880 3) -359248.47716636961559+51209.62852476461558i) (num-test (make-polar 362880 362880) 221059.52706247055903+287775.22460232191952i) (num-test (make-polar 362880 500029) 309953.60954995284555+188707.85443895909702i) (num-test (make-polar 500029 -1) 270166.82170094008325-420759.89506250765407i) (num-test (make-polar 500029 -10) -419560.09761256945785+272026.33205690066097i) (num-test (make-polar 500029 -1234) -399298.46976187621476-300981.28328323678579i) (num-test (make-polar 500029 -1234000000) 79459.17384055603179+493675.23791818472091i) (num-test (make-polar 500029 -2) -208085.48653183106217-454675.08303821878508i) (num-test (make-polar 500029 -3) -495024.95808262412902-70564.09651016735006i) (num-test (make-polar 500029 -362880) 304608.06398126127897-396538.68436583562288i) (num-test (make-polar 500029 -500029) 427099.29847236932255-260029.21006188896718i) (num-test (make-polar 500029 1) 270166.82170094008325+420759.89506250765407i) (num-test (make-polar 500029 10) -419560.09761256945785-272026.33205690066097i) (num-test (make-polar 500029 1234) -399298.46976187621476+300981.28328323678579i) (num-test (make-polar 500029 1234000000) 79459.17384055603179-493675.23791818472091i) (num-test (make-polar 500029 2) -208085.48653183106217+454675.08303821878508i) (num-test (make-polar 500029 3) -495024.95808262412902+70564.09651016735006i) (num-test (make-polar 500029 362880) 304608.06398126127897+396538.68436583562288i) (num-test (make-polar 500029 500029) 427099.29847236932255+260029.21006188896718i) (num-test (angle (make-polar 1.0 4.0)) (- 4 (* 2 pi))) (num-test (make-polar 1/2 0) 1/2) (num-test (make-polar 1/2 pi) -1/2) (num-test (make-polar 1 0) 1) (num-test (make-polar 1 1/2) 0.87758256189037+0.4794255386042i) (num-test (make-polar 0 1/2) 0.0) (test (nan? (make-polar 0 0/0)) #t) (test (nan? (make-polar nan.0 nan.0)) #t) (num-test (make-polar 1.0 (* 200 pi)) 1.0) (num-test (make-polar 1.0 (* 2000000 pi)) 1.0) (num-test (make-polar 1.0 (* 2000000000 pi)) 1.0) (let ((val1 (catch #t (lambda () (make-polar 1.0 0.0)) (lambda args 'error))) (val2 (catch #t (lambda () (make-polar 1.0 -0.0)) (lambda args 'error)))) (test (equal? val1 val2) #t)) (if with-bignums (begin (test (nan? (make-polar (bignum "0/0") 0)) #t) (test (nan? (make-polar 0 (bignum "0/0"))) #t) (num-test (make-polar (bignum "1.0") (bignum "0.0")) 1.0) (num-test (make-polar 1000000000000000000000000.0 0.0) 1e24) (num-test (make-polar 1000000000000000000000000.0 pi) -1e24) (num-test (angle (make-polar 1000000000000000000000000.0 4.0)) (- 4 (* 2 pi))) (num-test (make-polar 1000000000000000000000000.0 4.0) -6.536436208636119146391681830977503814246E23-7.568024953079282513726390945118290941345E23i) (num-test (make-polar 1000000000000000000000000.0 -4.0) -6.536436208636119146391681830977503814246E23+7.568024953079282513726390945118290941345E23i) (num-test (magnitude (make-polar 1e24 (* 1e19 pi))) 1e24) (num-test (magnitude (make-polar 100000000000000000000000000000000000000.0 (* 1.5 pi))) 1e38) (num-test (magnitude (make-polar 100000000000000000000000000000000000000.0 .01)) 1e38) (num-test (angle (make-polar 100000000000000000000000000000000000000.0 (* 100 pi))) 0.0) (test (make-polar 0.0 0+92233720368547758081.0i) 'error) )) (test (make-polar 0 0+0/0i) 'error) (test (make-polar 0+0/0i 0) 'error) (test (make-polar 1.23 1.23 1.23) 'error) (test (make-polar 1.23) 'error) (test (make-polar 1.23+1.0i 1.23+1.0i) 'error) (test (make-polar) 'error) (test (make-polar 1.0 1.0+0.1i) 'error) (test (make-polar 1.0+0.1i 0.0) 'error) (for-each (lambda (x) (test (make-polar x 0-i) 'error)) (list 0 1 1/2 1.0 0.0 0+i)) (for-each (lambda (x) (test (make-polar 0-i x) 'error)) (list 0 1 1/2 pi (- pi) 0.0 1.0 0+i)) (for-each (lambda (arg) (test (make-polar arg 0.0) 'error) (test (make-polar 0.0 arg) 'error) (test (make-polar 1 arg) 'error) (test (make-polar 1/2 arg) 'error) (test (make-polar 1+i arg) 'error) (test (make-polar arg nan.0) 'error) (test (make-polar nan.0 arg) 'error) (test (make-polar arg inf.0) 'error) (test (make-polar inf.0 arg) 'error)) (list "hi" () (integer->char 65) #f #t 0+i '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) ;;; -------------------------------------------------------------------------------- ;;; abs ;;; -------------------------------------------------------------------------------- (num-test (abs -0) 0) (num-test (abs -0.0) 0.0) (num-test (abs -0.00000001) 0.00000001) (num-test (abs -0/1) 0/1) (num-test (abs -0/10) 0/10) (num-test (abs -0/1234) 0/1234) (num-test (abs -0/1234000000) 0/1234000000) (num-test (abs -0/2) 0/2) (num-test (abs -0/3) 0/3) (num-test (abs -0/362880) 0/362880) (num-test (abs -0/500029) 0/500029) (num-test (abs -1) 1) (num-test (abs -1.0) 1.0) (num-test (abs -1/1) 1/1) (num-test (abs -1/10) 1/10) (num-test (abs -1/1234) 1/1234) (num-test (abs -1/1234000000) 1/1234000000) (num-test (abs -1/2) 1/2) (num-test (abs -1/3) 1/3) (num-test (abs -1/362880) 1/362880) (num-test (abs -1/500029) 1/500029) (num-test (abs -1/9223372036854775807) 1/9223372036854775807) (num-test (abs -10) 10) (num-test (abs -10/1) 10/1) (num-test (abs -10/10) 10/10) (num-test (abs -10/1234) 10/1234) (num-test (abs -10/1234000000) 10/1234000000) (num-test (abs -10/2) 10/2) (num-test (abs -10/3) 10/3) (num-test (abs -10/362880) 10/362880) (num-test (abs -10/500029) 10/500029) (num-test (abs -1234) 1234) (num-test (abs -1234.0) 1234.0) (num-test (abs -1234/1) 1234/1) (num-test (abs -1234/10) 1234/10) (num-test (abs -1234/1234) 1234/1234) (num-test (abs -1234/1234000000) 1234/1234000000) (num-test (abs -1234/2) 1234/2) (num-test (abs -1234/3) 1234/3) (num-test (abs -1234/362880) 1234/362880) (num-test (abs -1234/500029) 1234/500029) (num-test (abs -1234000000) 1234000000) (num-test (abs -1234000000.0) 1234000000.0) (num-test (abs -1234000000/1) 1234000000/1) (num-test (abs -1234000000/10) 1234000000/10) (num-test (abs -1234000000/1234) 1234000000/1234) (num-test (abs -1234000000/1234000000) 1234000000/1234000000) (num-test (abs -1234000000/2) 1234000000/2) (num-test (abs -1234000000/3) 1234000000/3) (num-test (abs -1234000000/362880) 1234000000/362880) (num-test (abs -1234000000/500029) 1234000000/500029) (num-test (abs -123456789) 123456789) (num-test (abs -1234567890) 1234567890) (num-test (abs -2) 2) (num-test (abs -2.71828182845905) 2.71828182845905) (num-test (abs -2/1) 2/1) (num-test (abs -2/10) 2/10) (num-test (abs -2/1234) 2/1234) (num-test (abs -2/1234000000) 2/1234000000) (num-test (abs -2/2) 2/2) (num-test (abs -2/3) 2/3) (num-test (abs -2/362880) 2/362880) (num-test (abs -2/500029) 2/500029) (num-test (abs -3) 3) (num-test (abs -3.14159265358979) pi) (num-test (abs -3/1) 3/1) (num-test (abs -3/10) 3/10) (num-test (abs -3/1234) 3/1234) (num-test (abs -3/1234000000) 3/1234000000) (num-test (abs -3/2) 3/2) (num-test (abs -3/3) 3/3) (num-test (abs -3/362880) 3/362880) (num-test (abs -3/500029) 3/500029) (num-test (abs -362880) 362880) (num-test (abs -362880/1) 362880/1) (num-test (abs -362880/10) 362880/10) (num-test (abs -362880/1234) 362880/1234) (num-test (abs -362880/1234000000) 362880/1234000000) (num-test (abs -362880/2) 362880/2) (num-test (abs -362880/3) 362880/3) (num-test (abs -362880/362880) 362880/362880) (num-test (abs -362880/500029) 362880/500029) (num-test (abs -500029) 500029) (num-test (abs -500029/1) 500029/1) (num-test (abs -500029/10) 500029/10) (num-test (abs -500029/1234) 500029/1234) (num-test (abs -500029/1234000000) 500029/1234000000) (num-test (abs -500029/2) 500029/2) (num-test (abs -500029/3) 500029/3) (num-test (abs -500029/362880) 500029/362880) (num-test (abs -500029/500029) 500029/500029) (num-test (abs -6) 6) (num-test (abs -7) 7) (num-test (abs 0) 0) (num-test (abs 0.0) 0.0) (num-test (abs 0.00000001) 0.00000001) (num-test (abs 0/1) 0/1) (num-test (abs 0/10) 0/10) (num-test (abs 0/1234) 0/1234) (num-test (abs 0/1234000000) 0/1234000000) (num-test (abs 0/2) 0/2) (num-test (abs 0/3) 0/3) (num-test (abs 0/362880) 0/362880) (num-test (abs 0/500029) 0/500029) (num-test (abs 1) 1) (num-test (abs 1.0) 1.0) (num-test (abs 1/1) 1/1) (num-test (abs 1/10) 1/10) (num-test (abs 1/1234) 1/1234) (num-test (abs 1/1234000000) 1/1234000000) (num-test (abs 1/2) 1/2) (num-test (abs 1/3) 1/3) (num-test (abs 1/362880) 1/362880) (num-test (abs 1/500029) 1/500029) (num-test (abs 10) 10) (num-test (abs 10/1) 10/1) (num-test (abs 10/10) 10/10) (num-test (abs 10/1234) 10/1234) (num-test (abs 10/1234000000) 10/1234000000) (num-test (abs 10/2) 10/2) (num-test (abs 10/3) 10/3) (num-test (abs 10/362880) 10/362880) (num-test (abs 10/500029) 10/500029) (num-test (abs 1234) 1234) (num-test (abs 1234.0) 1234.0) (num-test (abs 1234/1) 1234/1) (num-test (abs 1234/10) 1234/10) (num-test (abs 1234/1234) 1234/1234) (num-test (abs 1234/1234000000) 1234/1234000000) (num-test (abs 1234/2) 1234/2) (num-test (abs 1234/3) 1234/3) (num-test (abs 1234/362880) 1234/362880) (num-test (abs 1234/500029) 1234/500029) (num-test (abs 1234000000) 1234000000) (num-test (abs 1234000000.0) 1234000000.0) (num-test (abs 1234000000/1) 1234000000/1) (num-test (abs 1234000000/10) 1234000000/10) (num-test (abs 1234000000/1234) 1234000000/1234) (num-test (abs 1234000000/1234000000) 1234000000/1234000000) (num-test (abs 1234000000/2) 1234000000/2) (num-test (abs 1234000000/3) 1234000000/3) (num-test (abs 1234000000/362880) 1234000000/362880) (num-test (abs 1234000000/500029) 1234000000/500029) (num-test (abs 2) 2) (num-test (abs 2.71828182845905) 2.71828182845905) (num-test (abs 2/1) 2/1) (num-test (abs 2/10) 2/10) (num-test (abs 2/1234) 2/1234) (num-test (abs 2/1234000000) 2/1234000000) (num-test (abs 2/2) 2/2) (num-test (abs 2/3) 2/3) (num-test (abs 2/362880) 2/362880) (num-test (abs 2/500029) 2/500029) (num-test (abs 3) 3) (num-test (abs 3/1) 3/1) (num-test (abs 3/10) 3/10) (num-test (abs 3/1234) 3/1234) (num-test (abs 3/1234000000) 3/1234000000) (num-test (abs 3/2) 3/2) (num-test (abs 3/3) 3/3) (num-test (abs 3/362880) 3/362880) (num-test (abs 3/500029) 3/500029) (num-test (abs 362880) 362880) (num-test (abs 362880/1) 362880/1) (num-test (abs 362880/10) 362880/10) (num-test (abs 362880/1234) 362880/1234) (num-test (abs 362880/1234000000) 362880/1234000000) (num-test (abs 362880/2) 362880/2) (num-test (abs 362880/3) 362880/3) (num-test (abs 362880/362880) 362880/362880) (num-test (abs 362880/500029) 362880/500029) (num-test (abs 500029) 500029) (num-test (abs 500029/1) 500029/1) (num-test (abs 500029/10) 500029/10) (num-test (abs 500029/1234) 500029/1234) (num-test (abs 500029/1234000000) 500029/1234000000) (num-test (abs 500029/2) 500029/2) (num-test (abs 500029/3) 500029/3) (num-test (abs 500029/362880) 500029/362880) (num-test (abs 500029/500029) 500029/500029) (num-test (abs 6) 6) (num-test (abs 7) 7) (num-test (abs pi) pi) (num-test (abs -2.225073858507201399999999999999999999996E-308) 2.225073858507201399999999999999999999996E-308) (num-test (abs -9223372036854775808) (if with-bignums 9223372036854775808 9223372036854775807)) ; changed 28-Apr-15 (num-test (abs 1.110223024625156799999999999999999999997E-16) 1.110223024625156799999999999999999999997E-16) (num-test (abs 9223372036854775807) 9223372036854775807) (test (= (abs (+ most-negative-fixnum 1)) most-positive-fixnum) #t) (test (abs most-positive-fixnum) most-positive-fixnum) (num-test (abs -922337203685477580) 922337203685477580) (for-each (lambda (num-and-val) (let ((num (car num-and-val)) (val (cadr num-and-val))) (num-test-1 'abs num (abs num) val))) (vector (list 0 0) (list 1 1) (list 2 2) (list 3 3) (list -1 1) (list -2 2) (list -3 3) (list 9223372036854775807 9223372036854775807) (list 1/2 1/2) (list 1/3 1/3) (list -1/2 1/2) (list -1/3 1/3) (list 1/9223372036854775807 1/9223372036854775807) (list 0.0 0.0) (list 1.0 1.0) (list 2.0 2.0) (list -2.0 2.0) (list 1.000000000000000000000000000000000000002E-309 1.000000000000000000000000000000000000002E-309) (list 1e+16 1e+16) )) (if with-bignums (begin (num-test (abs -1e310) 1e310) (num-test (abs -.1e310) 1e309) (num-test (abs -.00001e309) 1e304) (num-test (abs most-negative-fixnum) 9223372036854775808) (num-test (abs -.1e-400) 1.000000000000000000000000000000000000001E-401) (num-test (abs -1.797693134862315699999999999999999999998E308) 1.797693134862315699999999999999999999998E308) (num-test (abs -12345678901234567890) 12345678901234567890) (num-test (abs 12345678901234567890) 12345678901234567890) (num-test (abs 9223372036854775808.0) 9223372036854775808.0) (num-test (abs -9223372036854775808.0) 9223372036854775808.0) (num-test (abs 9223372036854775808/3) 9223372036854775808/3) (num-test (abs -9223372036854775808/3) 9223372036854775808/3) (num-test (abs 9223372036854775808) 9223372036854775808) (num-test (abs -9223372036854775808) 9223372036854775808) (num-test (abs 1231234567891234567895/4924938271564938271564) 1231234567891234567895/4924938271564938271564) (num-test (abs -1231234567891234567895/4924938271564938271564) 1231234567891234567895/4924938271564938271564) (num-test (abs 5/4924938271564938271564) 5/4924938271564938271564) (num-test (abs -5/4924938271564938271564) 5/4924938271564938271564) (num-test (abs 1231234567891234567895.4924938271564938271564) 1231234567891234567895.4924938271564938271564) (num-test (abs -1231234567891234567895.4924938271564938271564) 1231234567891234567895.4924938271564938271564) (test (< (abs (- 217307123869033896670383722255101771944951615456222473725950809456844385078286527901170732595082536915607499776643486838126400154358628745576030002134993982282420557293291331398770482226850626076965834765751024210059623687394545134173058036837172944503241193618487196846261991269480351798163386073355597133702428176134419602160051931823812274538708325328119629419660293102211559158897247464223430070715316610068188075169995173607390273159413073729599663002285391560133032803005324145809498542320942319/69171005865679080805116192745197553936743146778127491628445014149228719516632195993428601364184241694325570308897501794466504355763015991674090032275753543906386364041957503000266249940077862458146827521257517440768326138892186263673940157476537922438310169667984623997354774657585797547359740040386280140433453254961653602051204994301868729700341678413408419088335979860854285428030584998257285624659397393914631805389952520897186723117920856639645035858695810847480593484518166856238091362466500961 pi)) 1e-30) #t) (test (< (abs (- 86506249226122124054607019515040072569389309675677090446756879032293209564976057920114008345082990143050895371432654098617595803586181179031736344131661104245709204440599410618785461104070923873664766537405043170624321277708803595336768044461421851475181966244993926088957647640608814315524675779027527947452743019231877030652479460288601395608061537360792381908211008391170537372395545350366754911899795085297260398105485029514527793853213999006311528934617756311568188335120606938078206683552323219/31823870623143321794788842272907994994917601540780651644441590671647399038540853367332145707942720183928541015066510539504636213034857780420049324239395126123695561521079512763516656025946557452382852551302156382716241918690232497805575429042492016743374932252325803315778289435501557305339709678335435100310171257145989526559485407857600325792028152511795618358674583299689136950642929744615564346477399823659926550178426308547711386364571735861738189405232059295317994009776897697526162381026548407 (exp 1.0))) 1e-10) #t) (test (< (abs (- 394372834342725903069943709807632345074473102456264/125532772013612015195543173729505082616186012726141 pi)) 1e-100) #t) (test (< (abs (- 37263594917349868210957473113622483286895975031882232950275573404793068492510874215659862655765029385/11861370656940517106115970314230542917832783292279765360251185207749769595904108589726721941267812387 pi)) 1e-200) #t) (test (< (abs (- 9723120205746844213570925835953968530586731050832362731080980958991370971563630998369876152193644009314571826202389376113741653418445346223192649145551112347805140423409409719828584948506325652698166338315337526327656688617124164275819596889301942895/3094965286042593318538169915190725425595617454610327314732861344227207817775353866654459841280603529756895813991351842180977260125352058245398197717632118060786828996125027995519815695529226138848308047979443033939320415958110104195587441744710374021 pi)) 1e-500) #t) (test (< (abs (- 217307123869033896670383722255101771944951615456222473725950809456844385078286527901170732595082536915607499776643486838126400154358628745576030002134993982282420557293291331398770482226850626076965834765751024210059623687394545134173058036837172944503241193618487196846261991269480351798163386073355597133702428176134419602160051931823812274538708325328119629419660293102211559158897247464223430070715316610068188075169995173607390273159413073729599663002285391560133032803005324145809498542320942319/69171005865679080805116192745197553936743146778127491628445014149228719516632195993428601364184241694325570308897501794466504355763015991674090032275753543906386364041957503000266249940077862458146827521257517440768326138892186263673940157476537922438310169667984623997354774657585797547359740040386280140433453254961653602051204994301868729700341678413408419088335979860854285428030584998257285624659397393914631805389952520897186723117920856639645035858695810847480593484518166856238091362466500961 pi)) 1e-1000) #t) (test (< (abs (- 86506249226122124054607019515040072569389309675677090446756879032293209564976057920114008345082990143050895371432654098617595803586181179031736344131661104245709204440599410618785461104070923873664766537405043170624321277708803595336768044461421851475181966244993926088957647640608814315524675779027527947452743019231877030652479460288601395608061537360792381908211008391170537372395545350366754911899795085297260398105485029514527793853213999006311528934617756311568188335120606938078206683552323219/31823870623143321794788842272907994994917601540780651644441590671647399038540853367332145707942720183928541015066510539504636213034857780420049324239395126123695561521079512763516656025946557452382852551302156382716241918690232497805575429042492016743374932252325803315778289435501557305339709678335435100310171257145989526559485407857600325792028152511795618358674583299689136950642929744615564346477399823659926550178426308547711386364571735861738189405232059295317994009776897697526162381026548407 (exp (bignum "1.0")))) 1e-1000) #t) )) (test (abs 0+0i) 0.0) (test (abs 1.23 1.23) 'error) (test (abs 1.23+1.0i) 'error) (test (abs) 'error) (test (nan? (abs 1/0)) #t) (test (positive? (abs (real-part (log 0.0)))) #t) (if (not pure-s7) (test (abs 1.0+0.1i) 'error)) ;; an optimizer bug (let () (define (t1) (let ((a 1+i) (b 0+i)) (abs (- a b)))) (num-test (t1) 1.0)) (for-each (lambda (arg) (test (abs arg) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) ;;; -------------------------------------------------------------------------------- ;;; magnitude ;;; -------------------------------------------------------------------------------- (num-test (magnitude (complex (expt 2 62) (expt 2 62))) 6.521908912666391106174785903126254184439E18) (num-test (magnitude (complex most-positive-fixnum most-negative-fixnum)) 1.30438178253327822116424650250659608445E19) (num-test (magnitude (complex most-positive-fixnum most-positive-fixnum)) 1.304381782533278221093535824387941332006E19) (num-test (magnitude -0) 0) (num-test (magnitude -0.0) 0.0) (num-test (magnitude -0.0+0.00000001i) 0.00000001) (num-test (magnitude -0.0+1.0i) 1.0) (num-test (magnitude -0.0+1234.0i) 1234.0) (num-test (magnitude -0.0+1234000000.0i) 1234000000.0) (num-test (magnitude -0.0+2.71828182845905i) 2.71828182845905) (num-test (magnitude -0.0+3.14159265358979i) 3.14159265358979) (num-test (magnitude -0.0-0.00000001i) 0.00000001) (num-test (magnitude -0.0-1.0i) 1.0) (num-test (magnitude -0.0-1234.0i) 1234.0) (num-test (magnitude -0.0-1234000000.0i) 1234000000.0) (num-test (magnitude -0.0-2.71828182845905i) 2.71828182845905) (num-test (magnitude -0.0-3.14159265358979i) 3.14159265358979) (num-test (magnitude -0.00000001) 0.00000001) (num-test (magnitude -0.00000001+0.00000001i) 0.00000001414214) (num-test (magnitude -0.00000001+1.0i) 1.0) (num-test (magnitude -0.00000001+1234.0i) 1234.0) (num-test (magnitude -0.00000001+1234000000.0i) 1234000000.0) (num-test (magnitude -0.00000001+2.71828182845905i) 2.71828182845905) (num-test (magnitude -0.00000001+3.14159265358979i) pi) (num-test (magnitude -0.00000001-0.00000001i) 0.00000001414214) (num-test (magnitude -0.00000001-1.0i) 1.0) (num-test (magnitude -0.00000001-1234.0i) 1234.0) (num-test (magnitude -0.00000001-1234000000.0i) 1234000000.0) (num-test (magnitude -0.00000001-2.71828182845905i) 2.71828182845905) (num-test (magnitude -0.00000001-3.14159265358979i) pi) (num-test (magnitude -0/1) 0/1) (num-test (magnitude -0/10) 0/10) (num-test (magnitude -0/1234) 0/1234) (num-test (magnitude -0/1234000000) 0/1234000000) (num-test (magnitude -0/2) 0/2) (num-test (magnitude -0/3) 0/3) (num-test (magnitude -0/362880) 0/362880) (num-test (magnitude -0/500029) 0/500029) (num-test (magnitude -1) 1) (num-test (magnitude -1.0) 1.0) (num-test (magnitude -1.0+0.00000001i) 1.0) (num-test (magnitude -1.0+1.0i) 1.41421356237310) (num-test (magnitude -1.0+1234.0i) 1234.00040518631931) (num-test (magnitude -1.0+1234000000.0i) 1234000000.0) (num-test (magnitude -1.0+2.71828182845905i) 2.89638673159001) (num-test (magnitude -1.0+3.14159265358979i) 3.29690830947562) (num-test (magnitude -1.0-0.00000001i) 1.0) (num-test (magnitude -1.0-1.0i) 1.41421356237310) (num-test (magnitude -1.0-1234.0i) 1234.00040518631931) (num-test (magnitude -1.0-1234000000.0i) 1234000000.0) (num-test (magnitude -1.0-2.71828182845905i) 2.89638673159001) (num-test (magnitude -1.0-3.14159265358979i) 3.29690830947562) (num-test (magnitude -1.0e+00+0.0e+00i) 1e0) (num-test (magnitude -1.0e+00+1.0e+00i) 1.4142135623730950488e0) (num-test (magnitude -1.0e+00+1.19209289550781250e-07i) 1.0000000000000071054e0) (num-test (magnitude -1.0e+00+2.0e+00i) 2.2360679774997896964e0) (num-test (magnitude -1.0e+00+5.0e-01i) 1.1180339887498948482e0) (num-test (magnitude -1.0e+00+8.3886080e+06i) 8.3886080000000596046e6) (num-test (magnitude -1.0e+00-1.0e+00i) 1.4142135623730950488e0) (num-test (magnitude -1.0e+00-1.19209289550781250e-07i) 1.0000000000000071054e0) (num-test (magnitude -1.0e+00-2.0e+00i) 2.2360679774997896964e0) (num-test (magnitude -1.0e+00-5.0e-01i) 1.1180339887498948482e0) (num-test (magnitude -1.0e+00-8.3886080e+06i) 8.3886080000000596046e6) (num-test (magnitude -1.19209289550781250e-07+0.0e+00i) 1.1920928955078125e-7) (num-test (magnitude -1.19209289550781250e-07+1.0e+00i) 1.0000000000000071054e0) (num-test (magnitude -1.19209289550781250e-07+1.19209289550781250e-07i) 1.6858739404357612715e-7) (num-test (magnitude -1.19209289550781250e-07+2.0e+00i) 2.0000000000000035527e0) (num-test (magnitude -1.19209289550781250e-07+5.0e-01i) 5.0000000000001421085e-1) (num-test (magnitude -1.19209289550781250e-07+8.3886080e+06i) 8.3886080e6) (num-test (magnitude -1.19209289550781250e-07-1.0e+00i) 1.0000000000000071054e0) (num-test (magnitude -1.19209289550781250e-07-1.19209289550781250e-07i) 1.6858739404357612715e-7) (num-test (magnitude -1.19209289550781250e-07-2.0e+00i) 2.0000000000000035527e0) (num-test (magnitude -1.19209289550781250e-07-5.0e-01i) 5.0000000000001421085e-1) (num-test (magnitude -1.19209289550781250e-07-8.3886080e+06i) 8.3886080e6) (num-test (magnitude -1/1) 1/1) (num-test (magnitude -1/10) 1/10) (num-test (magnitude -1/1234) 1/1234) (num-test (magnitude -1/1234000000) 1/1234000000) (num-test (magnitude -1/2) 1/2) (num-test (magnitude -1/3) 1/3) (num-test (magnitude -1/362880) 1/362880) (num-test (magnitude -1/500029) 1/500029) (num-test (magnitude -10) 10) (num-test (magnitude -10/1) 10/1) (num-test (magnitude -10/10) 10/10) (num-test (magnitude -10/1234) 10/1234) (num-test (magnitude -10/1234000000) 10/1234000000) (num-test (magnitude -10/2) 10/2) (num-test (magnitude -10/3) 10/3) (num-test (magnitude -10/362880) 10/362880) (num-test (magnitude -10/500029) 10/500029) (num-test (magnitude -1234) 1234) (num-test (magnitude -1234.0) 1234.0) (num-test (magnitude -1234.0+0.00000001i) 1234.0) (num-test (magnitude -1234.0+1.0i) 1234.00040518631931) (num-test (magnitude -1234.0+1234.0i) 1745.13953596839929) (num-test (magnitude -1234.0+1234000000.0i) 1234000000.00061702728271) (num-test (magnitude -1234.0+2.71828182845905i) 1234.00299394130275) (num-test (magnitude -1234.0+3.14159265358979i) 1234.00399902285608) (num-test (magnitude -1234.0-0.00000001i) 1234.0) (num-test (magnitude -1234.0-1.0i) 1234.00040518631931) (num-test (magnitude -1234.0-1234.0i) 1745.13953596839929) (num-test (magnitude -1234.0-1234000000.0i) 1234000000.00061702728271) (num-test (magnitude -1234.0-2.71828182845905i) 1234.00299394130275) (num-test (magnitude -1234.0-3.14159265358979i) 1234.00399902285608) (num-test (magnitude -1234/1) 1234/1) (num-test (magnitude -1234/10) 1234/10) (num-test (magnitude -1234/1234) 1234/1234) (num-test (magnitude -1234/1234000000) 1234/1234000000) (num-test (magnitude -1234/2) 1234/2) (num-test (magnitude -1234/3) 1234/3) (num-test (magnitude -1234/362880) 1234/362880) (num-test (magnitude -1234/500029) 1234/500029) (num-test (magnitude -1234000000) 1234000000) (num-test (magnitude -1234000000.0) 1234000000.0) (num-test (magnitude -1234000000.0+0.00000001i) 1234000000.0) (num-test (magnitude -1234000000.0+1.0i) 1234000000.0) (num-test (magnitude -1234000000.0+1234.0i) 1234000000.00061702728271) (num-test (magnitude -1234000000.0+1234000000.0i) 1745139535.96839928627014) (num-test (magnitude -1234000000.0+2.71828182845905i) 1234000000.0) (num-test (magnitude -1234000000.0+3.14159265358979i) 1234000000.0) (num-test (magnitude -1234000000.0-0.00000001i) 1234000000.0) (num-test (magnitude -1234000000.0-1.0i) 1234000000.0) (num-test (magnitude -1234000000.0-1234.0i) 1234000000.00061702728271) (num-test (magnitude -1234000000.0-1234000000.0i) 1745139535.96839928627014) (num-test (magnitude -1234000000.0-2.71828182845905i) 1.23400000000000000299394493473690280451E9) (num-test (magnitude -1234000000.0-3.14159265358979i) 1.234000000000000003999029335935712420981E9) (num-test (magnitude -1234000000/1) 1234000000/1) (num-test (magnitude -1234000000/10) 1234000000/10) (num-test (magnitude -1234000000/1234) 1234000000/1234) (num-test (magnitude -1234000000/1234000000) 1234000000/1234000000) (num-test (magnitude -1234000000/2) 1234000000/2) (num-test (magnitude -1234000000/3) 1234000000/3) (num-test (magnitude -1234000000/362880) 1234000000/362880) (num-test (magnitude -1234000000/500029) 1234000000/500029) (num-test (magnitude -2) 2) (num-test (magnitude -2.0e+00+0.0e+00i) 2e0) (num-test (magnitude -2.0e+00+1.0e+00i) 2.2360679774997896964e0) (num-test (magnitude -2.0e+00+1.19209289550781250e-07i) 2.0000000000000035527e0) (num-test (magnitude -2.0e+00+2.0e+00i) 2.8284271247461900976e0) (num-test (magnitude -2.0e+00+5.0e-01i) 2.0615528128088302749e0) (num-test (magnitude -2.0e+00+8.3886080e+06i) 8.3886080000002384186e6) (num-test (magnitude -2.0e+00-1.0e+00i) 2.2360679774997896964e0) (num-test (magnitude -2.0e+00-1.19209289550781250e-07i) 2.0000000000000035527e0) (num-test (magnitude -2.0e+00-2.0e+00i) 2.8284271247461900976e0) (num-test (magnitude -2.0e+00-5.0e-01i) 2.0615528128088302749e0) (num-test (magnitude -2.0e+00-8.3886080e+06i) 8.3886080000002384186e6) (num-test (magnitude -2.71828182845905) 2.71828182845905) (num-test (magnitude -2.71828182845905+0.00000001i) 2.71828182845905) (num-test (magnitude -2.71828182845905+1.0i) 2.89638673159001) (num-test (magnitude -2.71828182845905+1234.0i) 1234.00299394130275) (num-test (magnitude -2.71828182845905+1234000000.0i) 1234000000.0) (num-test (magnitude -2.71828182845905+2.71828182845905i) 3.84423102815912) (num-test (magnitude -2.71828182845905+3.14159265358979i) 4.15435440231331) (num-test (magnitude -2.71828182845905+3.14159265358979i) 4.15435440231331) (num-test (magnitude -2.71828182845905-0.00000001i) 2.71828182845905) (num-test (magnitude -2.71828182845905-1.0i) 2.89638673159001) (num-test (magnitude -2.71828182845905-1234.0i) 1234.00299394130275) (num-test (magnitude -2.71828182845905-1234000000.0i) 1234000000.0) (num-test (magnitude -2.71828182845905-2.71828182845905i) 3.84423102815912) (num-test (magnitude -2.71828182845905-3.14159265358979i) 4.15435440231331) (num-test (magnitude -2/1) 2/1) (num-test (magnitude -2/10) 2/10) (num-test (magnitude -2/1234) 2/1234) (num-test (magnitude -2/1234000000) 2/1234000000) (num-test (magnitude -2/2) 2/2) (num-test (magnitude -2/3) 2/3) (num-test (magnitude -2/362880) 2/362880) (num-test (magnitude -2/500029) 2/500029) (num-test (magnitude -3) 3) (num-test (magnitude -3.14159265358979) pi) (num-test (magnitude -3.14159265358979+0.00000001i) pi) (num-test (magnitude -3.14159265358979+1.0i) 3.29690830947562) (num-test (magnitude -3.14159265358979+1234.0i) 1234.00399902285608) (num-test (magnitude -3.14159265358979+1234000000.0i) 1234000000.0) (num-test (magnitude -3.14159265358979+2.71828182845905i) 4.15435440231331) (num-test (magnitude -3.14159265358979+3.14159265358979i) 4.44288293815837) (num-test (magnitude -3.14159265358979-0.00000001i) pi) (num-test (magnitude -3.14159265358979-1.0i) 3.29690830947562) (num-test (magnitude -3.14159265358979-1234.0i) 1234.00399902285608) (num-test (magnitude -3.14159265358979-1234000000.0i) 1234000000.0) (num-test (magnitude -3.14159265358979-2.71828182845905i) 4.15435440231331) (num-test (magnitude -3.14159265358979-3.14159265358979i) 4.44288293815837) (num-test (magnitude -3/1) 3/1) (num-test (magnitude -3/10) 3/10) (num-test (magnitude -3/1234) 3/1234) (num-test (magnitude -3/1234000000) 3/1234000000) (num-test (magnitude -3/2) 3/2) (num-test (magnitude -3/3) 3/3) (num-test (magnitude -3/362880) 3/362880) (num-test (magnitude -3/500029) 3/500029) (num-test (magnitude -362880) 362880) (num-test (magnitude -362880/1) 362880/1) (num-test (magnitude -362880/10) 362880/10) (num-test (magnitude -362880/1234) 362880/1234) (num-test (magnitude -362880/1234000000) 362880/1234000000) (num-test (magnitude -362880/2) 362880/2) (num-test (magnitude -362880/3) 362880/3) (num-test (magnitude -362880/362880) 362880/362880) (num-test (magnitude -362880/500029) 362880/500029) (num-test (magnitude -5.0e-01+0.0e+00i) 5e-1) (num-test (magnitude -5.0e-01+1.0e+00i) 1.1180339887498948482e0) (num-test (magnitude -5.0e-01+1.19209289550781250e-07i) 5.0000000000001421085e-1) (num-test (magnitude -5.0e-01+2.0e+00i) 2.0615528128088302749e0) (num-test (magnitude -5.0e-01+5.0e-01i) 7.0710678118654752440e-1) (num-test (magnitude -5.0e-01+8.3886080e+06i) 8.3886080000000149012e6) (num-test (magnitude -5.0e-01-1.0e+00i) 1.1180339887498948482e0) (num-test (magnitude -5.0e-01-1.19209289550781250e-07i) 5.0000000000001421085e-1) (num-test (magnitude -5.0e-01-2.0e+00i) 2.0615528128088302749e0) (num-test (magnitude -5.0e-01-5.0e-01i) 7.0710678118654752440e-1) (num-test (magnitude -5.0e-01-8.3886080e+06i) 8.3886080000000149012e6) (num-test (magnitude -500029) 500029) (num-test (magnitude -500029/1) 500029/1) (num-test (magnitude -500029/10) 500029/10) (num-test (magnitude -500029/1234) 500029/1234) (num-test (magnitude -500029/1234000000) 500029/1234000000) (num-test (magnitude -500029/2) 500029/2) (num-test (magnitude -500029/3) 500029/3) (num-test (magnitude -500029/362880) 500029/362880) (num-test (magnitude -500029/500029) 500029/500029) (num-test (magnitude -8.3886080e+06+0.0e+00i) 8.388608e6) (num-test (magnitude -8.3886080e+06+1.0e+00i) 8.3886080000000596046e6) (num-test (magnitude -8.3886080e+06+1.19209289550781250e-07i) 8.3886080e6) (num-test (magnitude -8.3886080e+06+2.0e+00i) 8.3886080000002384186e6) (num-test (magnitude -8.3886080e+06+5.0e-01i) 8.3886080000000149012e6) (num-test (magnitude -8.3886080e+06+8.3886080e+06i) 1.1863283203031444111e7) (num-test (magnitude -8.3886080e+06-1.0e+00i) 8.3886080000000596046e6) (num-test (magnitude -8.3886080e+06-1.19209289550781250e-07i) 8.3886080e6) (num-test (magnitude -8.3886080e+06-2.0e+00i) 8.3886080000002384186e6) (num-test (magnitude -8.3886080e+06-5.0e-01i) 8.3886080000000149012e6) (num-test (magnitude -8.3886080e+06-8.3886080e+06i) 1.1863283203031444111e7) (num-test (magnitude .1e-18-.1e-18i) 1.4142135623731e-19) (num-test (magnitude .1e200+.1e200i) 1.4142135623731e+199) (num-test (magnitude 0) 0) (num-test (magnitude 0.0) 0.0) (num-test (magnitude 0.0+0.00000001i) 0.00000001) (num-test (magnitude 0.0+0.00000001i) 0.00000001) (num-test (magnitude 0.0+1.0i) 1.0) (num-test (magnitude 0.0+1234.0i) 1234.0) (num-test (magnitude 0.0+1234000000.0i) 1234000000.0) (num-test (magnitude 0.0+2.71828182845905i) 2.71828182845905) (num-test (magnitude 0.0+3.14159265358979i) 3.14159265358979) (num-test (magnitude 0.0-0.00000001i) 0.00000001) (num-test (magnitude 0.0-1.0i) 1.0) (num-test (magnitude 0.0-1234.0i) 1234.0) (num-test (magnitude 0.0-1234000000.0i) 1234000000.0) (num-test (magnitude 0.0-2.71828182845905i) 2.71828182845905) (num-test (magnitude 0.0-3.14159265358979i) 3.14159265358979) (num-test (magnitude 0.00000001) 0.00000001) (num-test (magnitude 0.00000001+0.00000001i) 0.00000001414214) (num-test (magnitude 0.00000001+1.0i) 1.0) (num-test (magnitude 0.00000001+1234.0i) 1234.0) (num-test (magnitude 0.00000001+1234000000.0i) 1234000000.0) (num-test (magnitude 0.00000001+2.71828182845905i) 2.71828182845905) (num-test (magnitude 0.00000001+3.14159265358979i) pi) (num-test (magnitude 0.00000001-0.00000001i) 0.00000001414214) (num-test (magnitude 0.00000001-1.0i) 1.0) (num-test (magnitude 0.00000001-1234.0i) 1234.0) (num-test (magnitude 0.00000001-1234000000.0i) 1234000000.0) (num-test (magnitude 0.00000001-2.71828182845905i) 2.71828182845905) (num-test (magnitude 0.00000001-3.14159265358979i) pi) (num-test (magnitude 0.0e+00+0.0e+00i) 0e0) (num-test (magnitude 0.0e+00+1.0e+00i) 1e0) (num-test (magnitude 0.0e+00+1.19209289550781250e-07i) 1.1920928955078125e-7) (num-test (magnitude 0.0e+00+2.0e+00i) 2e0) (num-test (magnitude 0.0e+00+5.0e-01i) 5e-1) (num-test (magnitude 0.0e+00+8.3886080e+06i) 8.388608e6) (num-test (magnitude 0.0e+00-1.0e+00i) 1e0) (num-test (magnitude 0.0e+00-1.19209289550781250e-07i) 1.1920928955078125e-7) (num-test (magnitude 0.0e+00-2.0e+00i) 2e0) (num-test (magnitude 0.0e+00-5.0e-01i) 5e-1) (num-test (magnitude 0.0e+00-8.3886080e+06i) 8.388608e6) (num-test (magnitude 0/1) 0/1) (num-test (magnitude 0/10) 0/10) (num-test (magnitude 0/1234) 0/1234) (num-test (magnitude 0/1234000000) 0/1234000000) (num-test (magnitude 0/2) 0/2) (num-test (magnitude 0/3) 0/3) (num-test (magnitude 0/362880) 0/362880) (num-test (magnitude 0/500029) 0/500029) (num-test (magnitude 1) 1) (num-test (magnitude 1.0) 1.0) (num-test (magnitude 1.0+0.00000001i) 1.0) (num-test (magnitude 1.0+1.0i) 1.41421356237310) (num-test (magnitude 1.0+1.0i) 1.41421356237310) (num-test (magnitude 1.0+1234.0i) 1234.00040518631931) (num-test (magnitude 1.0+1234000000.0i) 1234000000.0) (num-test (magnitude 1.0+2.71828182845905i) 2.89638673159001) (num-test (magnitude 1.0+3.14159265358979i) 3.29690830947562) (num-test (magnitude 1.0-0.00000001i) 1.0) (num-test (magnitude 1.0-1.0i) 1.41421356237310) (num-test (magnitude 1.0-1234.0i) 1234.00040518631931) (num-test (magnitude 1.0-1234000000.0i) 1234000000.0) (num-test (magnitude 1.0-2.71828182845905i) 2.89638673159001) (num-test (magnitude 1.0-3.14159265358979i) 3.29690830947562) (num-test (magnitude 1.0e+00+0.0e+00i) 1e0) (num-test (magnitude 1.0e+00+1.0e+00i) 1.4142135623730950488e0) (num-test (magnitude 1.0e+00+1.19209289550781250e-07i) 1.0000000000000071054e0) (num-test (magnitude 1.0e+00+2.0e+00i) 2.2360679774997896964e0) (num-test (magnitude 1.0e+00+5.0e-01i) 1.1180339887498948482e0) (num-test (magnitude 1.0e+00+8.3886080e+06i) 8.3886080000000596046e6) (num-test (magnitude 1.0e+00-1.0e+00i) 1.4142135623730950488e0) (num-test (magnitude 1.0e+00-1.19209289550781250e-07i) 1.0000000000000071054e0) (num-test (magnitude 1.0e+00-2.0e+00i) 2.2360679774997896964e0) (num-test (magnitude 1.0e+00-5.0e-01i) 1.1180339887498948482e0) (num-test (magnitude 1.0e+00-8.3886080e+06i) 8.3886080000000596046e6) (num-test (magnitude 1.19209289550781250e-07+0.0e+00i) 1.1920928955078125e-7) (num-test (magnitude 1.19209289550781250e-07+1.0e+00i) 1.0000000000000071054e0) (num-test (magnitude 1.19209289550781250e-07+1.19209289550781250e-07i) 1.6858739404357612715e-7) (num-test (magnitude 1.19209289550781250e-07+2.0e+00i) 2.0000000000000035527e0) (num-test (magnitude 1.19209289550781250e-07+5.0e-01i) 5.0000000000001421085e-1) (num-test (magnitude 1.19209289550781250e-07+8.3886080e+06i) 8.3886080e6) (num-test (magnitude 1.19209289550781250e-07-1.0e+00i) 1.0000000000000071054e0) (num-test (magnitude 1.19209289550781250e-07-1.19209289550781250e-07i) 1.6858739404357612715e-7) (num-test (magnitude 1.19209289550781250e-07-2.0e+00i) 2.0000000000000035527e0) (num-test (magnitude 1.19209289550781250e-07-5.0e-01i) 5.0000000000001421085e-1) (num-test (magnitude 1.19209289550781250e-07-8.3886080e+06i) 8.3886080e6) (num-test (magnitude 1/1) 1/1) (num-test (magnitude 1/10) 1/10) (num-test (magnitude 1/1234) 1/1234) (num-test (magnitude 1/1234000000) 1/1234000000) (num-test (magnitude 1/2) 1/2) (num-test (magnitude 1/3) 1/3) (num-test (magnitude 1/362880) 1/362880) (num-test (magnitude 1/500029) 1/500029) (num-test (magnitude 10) 10) (num-test (magnitude 10/1) 10/1) (num-test (magnitude 10/10) 10/10) (num-test (magnitude 10/1234) 10/1234) (num-test (magnitude 10/1234000000) 10/1234000000) (num-test (magnitude 10/2) 10/2) (num-test (magnitude 10/3) 10/3) (num-test (magnitude 10/362880) 10/362880) (num-test (magnitude 10/500029) 10/500029) (num-test (magnitude 1234) 1234) (num-test (magnitude 1234.0) 1234.0) (num-test (magnitude 1234.0+0.00000001i) 1234.0) (num-test (magnitude 1234.0+1.0i) 1234.00040518631931) (num-test (magnitude 1234.0+1234.0i) 1745.13953596839929) (num-test (magnitude 1234.0+1234000000.0i) 1234000000.00061702728271) (num-test (magnitude 1234.0+2.71828182845905i) 1234.00299394130275) (num-test (magnitude 1234.0+3.14159265358979i) 1234.00399902285608) (num-test (magnitude 1234.0-0.00000001i) 1234.0) (num-test (magnitude 1234.0-1.0i) 1234.00040518631931) (num-test (magnitude 1234.0-1234.0i) 1745.13953596839929) (num-test (magnitude 1234.0-1234000000.0i) 1234000000.00061702728271) (num-test (magnitude 1234.0-2.71828182845905i) 1234.00299394130275) (num-test (magnitude 1234.0-3.14159265358979i) 1234.00399902285608) (num-test (magnitude 1234/1) 1234/1) (num-test (magnitude 1234/10) 1234/10) (num-test (magnitude 1234/1234) 1234/1234) (num-test (magnitude 1234/1234000000) 1234/1234000000) (num-test (magnitude 1234/2) 1234/2) (num-test (magnitude 1234/3) 1234/3) (num-test (magnitude 1234/362880) 1234/362880) (num-test (magnitude 1234/500029) 1234/500029) (num-test (magnitude 1234000000) 1234000000) (num-test (magnitude 1234000000.0) 1234000000.0) (num-test (magnitude 1234000000.0+0.00000001i) 1234000000.0) (num-test (magnitude 1234000000.0+1.0i) 1234000000.0) (num-test (magnitude 1234000000.0+1234.0i) 1234000000.00061702728271) (num-test (magnitude 1234000000.0+1234000000.0i) 1745139535.96839928627014) (num-test (magnitude 1234000000.0+2.71828182845905i) 1234000000.0) (num-test (magnitude 1234000000.0-0.00000001i) 1234000000.0) (num-test (magnitude 1234000000.0-1.0i) 1234000000.0) (num-test (magnitude 1234000000.0-1234.0i) 1234000000.00061702728271) (num-test (magnitude 1234000000.0-1234000000.0i) 1745139535.96839928627014) (num-test (magnitude 1234000000.0-2.71828182845905i) 1234000000.0) (num-test (magnitude 1234000000.0-3.14159265358979i) 1234000000.0) (num-test (magnitude 1234000000/1) 1234000000/1) (num-test (magnitude 1234000000/10) 1234000000/10) (num-test (magnitude 1234000000/1234) 1234000000/1234) (num-test (magnitude 1234000000/1234000000) 1234000000/1234000000) (num-test (magnitude 1234000000/2) 1234000000/2) (num-test (magnitude 1234000000/3) 1234000000/3) (num-test (magnitude 1234000000/362880) 1234000000/362880) (num-test (magnitude 1234000000/500029) 1234000000/500029) (num-test (magnitude 1e18+1e18i) 1.414213562373095048801688724209698078569E18) (num-test (magnitude 2) 2) (num-test (magnitude 2.0e+00+0.0e+00i) 2e0) (num-test (magnitude 2.0e+00+1.0e+00i) 2.2360679774997896964e0) (num-test (magnitude 2.0e+00+1.19209289550781250e-07i) 2.0000000000000035527e0) (num-test (magnitude 2.0e+00+2.0e+00i) 2.8284271247461900976e0) (num-test (magnitude 2.0e+00+5.0e-01i) 2.0615528128088302749e0) (num-test (magnitude 2.0e+00+8.3886080e+06i) 8.3886080000002384186e6) (num-test (magnitude 2.0e+00-1.0e+00i) 2.2360679774997896964e0) (num-test (magnitude 2.0e+00-1.19209289550781250e-07i) 2.0000000000000035527e0) (num-test (magnitude 2.0e+00-2.0e+00i) 2.8284271247461900976e0) (num-test (magnitude 2.0e+00-5.0e-01i) 2.0615528128088302749e0) (num-test (magnitude 2.0e+00-8.3886080e+06i) 8.3886080000002384186e6) (num-test (magnitude 2.71828182845905) 2.71828182845905) (num-test (magnitude 2.71828182845905+0.00000001i) 2.71828182845905) (num-test (magnitude 2.71828182845905+1.0i) 2.89638673159001) (num-test (magnitude 2.71828182845905+1234.0i) 1234.00299394130275) (num-test (magnitude 2.71828182845905+1234000000.0i) 1234000000.0) (num-test (magnitude 2.71828182845905+2.71828182845905i) 3.84423102815912) (num-test (magnitude 2.71828182845905+3.14159265358979i) 4.15435440231331) (num-test (magnitude 2.71828182845905+3.14159265358979i) 4.15435440231331) (num-test (magnitude 2.71828182845905-0.00000001i) 2.71828182845905) (num-test (magnitude 2.71828182845905-1.0i) 2.89638673159001) (num-test (magnitude 2.71828182845905-1234.0i) 1234.00299394130275) (num-test (magnitude 2.71828182845905-1234000000.0i) 1234000000.0) (num-test (magnitude 2.71828182845905-2.71828182845905i) 3.84423102815912) (num-test (magnitude 2.71828182845905-3.14159265358979i) 4.15435440231331) (num-test (magnitude 2/1) 2/1) (num-test (magnitude 2/10) 2/10) (num-test (magnitude 2/1234) 2/1234) (num-test (magnitude 2/1234000000) 2/1234000000) (num-test (magnitude 2/2) 2/2) (num-test (magnitude 2/3) 2/3) (num-test (magnitude 2/362880) 2/362880) (num-test (magnitude 2/500029) 2/500029) (num-test (magnitude 3) 3) (num-test (magnitude 3.14159265358979+0.00000001i) pi) (num-test (magnitude 3.14159265358979+1.0i) 3.29690830947562) (num-test (magnitude 3.14159265358979+1234.0i) 1234.00399902285608) (num-test (magnitude 3.14159265358979+1234000000.0i) 1234000000.0) (num-test (magnitude 3.14159265358979+2.71828182845905i) 4.15435440231331) (num-test (magnitude 3.14159265358979+3.14159265358979i) 4.44288293815837) (num-test (magnitude 3.14159265358979-0.00000001i) pi) (num-test (magnitude 3.14159265358979-1.0i) 3.29690830947562) (num-test (magnitude 3.14159265358979-1234.0i) 1234.00399902285608) (num-test (magnitude 3.14159265358979-1234000000.0i) 1234000000.0) (num-test (magnitude 3.14159265358979-2.71828182845905i) 4.15435440231331) (num-test (magnitude 3.14159265358979-3.14159265358979i) 4.44288293815837) (num-test (magnitude 3/1) 3/1) (num-test (magnitude 3/10) 3/10) (num-test (magnitude 3/1234) 3/1234) (num-test (magnitude 3/1234000000) 3/1234000000) (num-test (magnitude 3/2) 3/2) (num-test (magnitude 3/3) 3/3) (num-test (magnitude 3/362880) 3/362880) (num-test (magnitude 3/500029) 3/500029) (num-test (magnitude 362880) 362880) (num-test (magnitude 362880/1) 362880/1) (num-test (magnitude 362880/10) 362880/10) (num-test (magnitude 362880/1234) 362880/1234) (num-test (magnitude 362880/1234000000) 362880/1234000000) (num-test (magnitude 362880/2) 362880/2) (num-test (magnitude 362880/3) 362880/3) (num-test (magnitude 362880/362880) 362880/362880) (num-test (magnitude 362880/500029) 362880/500029) (num-test (magnitude 5.0e-01+0.0e+00i) 5e-1) (num-test (magnitude 5.0e-01+1.0e+00i) 1.1180339887498948482e0) (num-test (magnitude 5.0e-01+1.19209289550781250e-07i) 5.0000000000001421085e-1) (num-test (magnitude 5.0e-01+2.0e+00i) 2.0615528128088302749e0) (num-test (magnitude 5.0e-01+5.0e-01i) 7.0710678118654752440e-1) (num-test (magnitude 5.0e-01+8.3886080e+06i) 8.3886080000000149012e6) (num-test (magnitude 5.0e-01-1.0e+00i) 1.1180339887498948482e0) (num-test (magnitude 5.0e-01-1.19209289550781250e-07i) 5.0000000000001421085e-1) (num-test (magnitude 5.0e-01-2.0e+00i) 2.0615528128088302749e0) (num-test (magnitude 5.0e-01-5.0e-01i) 7.0710678118654752440e-1) (num-test (magnitude 5.0e-01-8.3886080e+06i) 8.3886080000000149012e6) (num-test (magnitude 500029) 500029) (num-test (magnitude 500029/1) 500029/1) (num-test (magnitude 500029/10) 500029/10) (num-test (magnitude 500029/1234) 500029/1234) (num-test (magnitude 500029/1234000000) 500029/1234000000) (num-test (magnitude 500029/2) 500029/2) (num-test (magnitude 500029/3) 500029/3) (num-test (magnitude 500029/362880) 500029/362880) (num-test (magnitude 500029/500029) 500029/500029) (num-test (magnitude 8.3886080e+06+0.0e+00i) 8.388608e6) (num-test (magnitude 8.3886080e+06+1.0e+00i) 8.3886080000000596046e6) (num-test (magnitude 8.3886080e+06+1.19209289550781250e-07i) 8.3886080e6) (num-test (magnitude 8.3886080e+06+2.0e+00i) 8.3886080000002384186e6) (num-test (magnitude 8.3886080e+06+5.0e-01i) 8.3886080000000149012e6) (num-test (magnitude 8.3886080e+06+8.3886080e+06i) 1.1863283203031444111e7) (num-test (magnitude 8.3886080e+06-1.0e+00i) 8.3886080000000596046e6) (num-test (magnitude 8.3886080e+06-1.19209289550781250e-07i) 8.3886080e6) (num-test (magnitude 8.3886080e+06-2.0e+00i) 8.3886080000002384186e6) (num-test (magnitude 8.3886080e+06-5.0e-01i) 8.3886080000000149012e6) (num-test (magnitude 8.3886080e+06-8.3886080e+06i) 1.1863283203031444111e7) (num-test (magnitude most-positive-fixnum) most-positive-fixnum) (num-test (magnitude pi) pi) (num-test (magnitude -2.225073858507201399999999999999999999996E-308) 2.225073858507201399999999999999999999996E-308) (if (not with-bignums) (num-test (magnitude -9223372036854775808) 9223372036854775807)) ; changed 28-Apr-15 (num-test (magnitude 1.110223024625156799999999999999999999997E-16) 1.110223024625156799999999999999999999997E-16) (num-test (magnitude 9223372036854775807) 9223372036854775807) (for-each (lambda (num-and-val) (let ((num (car num-and-val)) (val (cadr num-and-val))) (num-test-1 'magnitude num (magnitude num) val))) (vector (list 0 0) (list 1 1) (list 2 2) (list 3 3) (list -1 1) (list -2 2) (list -3 3) (list 9223372036854775807 9223372036854775807) (list 1/2 1/2) (list 1/3 1/3) (list -1/2 1/2) (list -1/3 1/3) (list 1/9223372036854775807 1/9223372036854775807) (list 0.0 0.0) (list 1.0 1.0) (list 2.0 2.0) (list -2.0 2.0) (list 1.000000000000000000000000000000000000002E-309 1.000000000000000000000000000000000000002E-309) (list 1e+16 1e+16) (list 0+1i 1.0) (list 0+2i 2.0) (list 0-1i 1.0) (list 1+1i 1.4142135623731) (list 1-1i 1.4142135623731) (list -1+1i 1.4142135623731) (list -1-1i 1.4142135623731) (list 0.1+0.1i 0.14142135623731) (list 1e+16+1e+16i 1.4142135623731e+16) (list 1e-16+1e-16i 1.4142135623731e-16) )) (if with-bignums (begin (num-test (magnitude (complex (expt 2 63) (expt 2 63))) 1.304381782533278221234957180625250836888E19) (num-test (magnitude most-negative-fixnum) 9223372036854775808) (num-test (magnitude 1e400+1e400i) 1.414213562373095048801688724209698078569E400) (num-test (magnitude .1e400+.1e400i) 1.41421356237309504880168872420969807857E399) (num-test (magnitude .001e310+.001e310i) 1.414213562373095048801688724209698078572E307) (num-test (magnitude 1e-310+1e-310i) 1.414213562373095048801688724209698078569E-310) (num-test (magnitude 1e-400+1e-400i) 1.414213562373095048801688724209698078568E-400) (num-test (magnitude -1.797693134862315699999999999999999999998E308) 1.797693134862315699999999999999999999998E308) (num-test (magnitude 9223372036854775808.1) 9223372036854775808.1) (num-test (magnitude 9223372036854775808) 9223372036854775808) (num-test (magnitude 9223372036854775808/3) 9223372036854775808/3) (num-test (magnitude 9223372036854775808.1+1.0e19i) 1.360406526484765934746566522678055771386E19) (num-test (magnitude 1.0e19+9223372036854775808.1i) 1.360406526484765934746566522678055771386E19) (num-test (magnitude 14142135623730950488.0168872420969+14142135623730950488.0168872420969i) 1.9999999999999999999999999999999885751772054578776001965575456E19) )) (test (magnitude "hi") 'error) (test (magnitude 1.0+23.0i 1.0+23.0i) 'error) (test (magnitude) 'error) (for-each (lambda (arg) (test (magnitude arg) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) ;;; (magnitude -9223372036854775808) -> -9223372036854775808? ;;; -------------------------------------------------------------------------------- ;;; angle ;;; -------------------------------------------------------------------------------- (num-test (angle (make-polar 1.0 (+ pi .0001))) (- .0001 pi)) (num-test (angle (make-polar 1.0 (- pi .0001))) (- pi .0001)) (num-test (angle -0) 0) (num-test (angle -0.0+0.00000001i) 1.57079632679490) (num-test (angle -0.0+1.0i) 1.57079632679490) (num-test (angle -0.0+1234.0i) 1.57079632679490) (num-test (angle -0.0+1234000000.0i) 1.57079632679490) (num-test (angle -0.0+2.71828182845905i) 1.57079632679490) (num-test (angle -0.0+3.14159265358979i) 1.57079632679490) (num-test (angle -0.0-0.00000001i) -1.57079632679490) (num-test (angle -0.0-1.0i) -1.57079632679490) (num-test (angle -0.0-1234.0i) -1.57079632679490) (num-test (angle -0.0-1234000000.0i) -1.57079632679490) (num-test (angle -0.0-2.71828182845905i) -1.57079632679490) (num-test (angle -0.0-3.14159265358979i) -1.57079632679490) (num-test (angle -0.00000001) pi) (num-test (angle -0.00000001+0.00000001i) 2.35619449019234) (num-test (angle -0.00000001+1.0i) 1.57079633679490) (num-test (angle -0.00000001+1234.0i) 1.57079632680300) (num-test (angle -0.00000001+1234000000.0i) 1.57079632679490) (num-test (angle -0.00000001+2.71828182845905i) 1.57079633047369) (num-test (angle -0.00000001+3.14159265358979i) 1.57079632997800) (num-test (angle -0.00000001-0.00000001i) -2.35619449019234) (num-test (angle -0.00000001-1.0i) -1.57079633679490) (num-test (angle -0.00000001-1234.0i) -1.57079632680300) (num-test (angle -0.00000001-1234000000.0i) -1.57079632679490) (num-test (angle -0.00000001-2.71828182845905i) -1.57079633047369) (num-test (angle -0.00000001-3.14159265358979i) -1.57079632997800) (num-test (angle -1) pi) (num-test (angle -1.0) pi) (num-test (angle -1.0+0.00000001i) 3.14159264358979) (num-test (angle -1.0+1.0i) 2.35619449019234) (num-test (angle -1.0+1234.0i) 1.57160669938898) (num-test (angle -1.0+1234000000.0i) 1.57079632760527) (num-test (angle -1.0+2.71828182845905i) 1.92330974857252) (num-test (angle -1.0+3.14159265358979i) 1.87896539791088) (num-test (angle -1.0-0.00000001i) -3.14159264358979) (num-test (angle -1.0-1.0i) -2.35619449019234) (num-test (angle -1.0-1234.0i) -1.57160669938898) (num-test (angle -1.0-1234000000.0i) -1.57079632760527) (num-test (angle -1.0-2.71828182845905i) -1.92330974857252) (num-test (angle -1.0-3.14159265358979i) -1.87896539791088) (num-test (angle -1.0e+00+0.0e+00i) 3.1415926535897932385e0) (num-test (angle -1.0e+00+1.0e+00i) 2.3561944901923449288e0) (num-test (angle -1.0e+00+1.19209289550781250e-07i) 3.1415925343805036877e0) (num-test (angle -1.0e+00+2.0e+00i) 2.0344439357957027354e0) (num-test (angle -1.0e+00+5.0e-01i) 2.6779450445889871222e0) (num-test (angle -1.0e+00+8.3886080e+06i) 1.570796446004186170e0) (num-test (angle -1.0e+00-1.0e+00i) -2.3561944901923449288e0) (num-test (angle -1.0e+00-1.19209289550781250e-07i) -3.1415925343805036877e0) (num-test (angle -1.0e+00-2.0e+00i) -2.0344439357957027354e0) (num-test (angle -1.0e+00-5.0e-01i) -2.6779450445889871222e0) (num-test (angle -1.0e+00-8.3886080e+06i) -1.570796446004186170e0) (num-test (angle -1.19209289550781250e-07+0.0e+00i) 3.1415926535897932385e0) (num-test (angle -1.19209289550781250e-07+1.0e+00i) 1.570796446004186170e0) (num-test (angle -1.19209289550781250e-07+1.19209289550781250e-07i) 2.3561944901923449288e0) (num-test (angle -1.19209289550781250e-07+2.0e+00i) 1.5707963863995413946e0) (num-test (angle -1.19209289550781250e-07+5.0e-01i) 1.5707965652134757208e0) (num-test (angle -1.19209289550781250e-07+8.3886080e+06i) 1.5707963267949108301e0) (num-test (angle -1.19209289550781250e-07-1.0e+00i) -1.570796446004186170e0) (num-test (angle -1.19209289550781250e-07-1.19209289550781250e-07i) -2.3561944901923449288e0) (num-test (angle -1.19209289550781250e-07-2.0e+00i) -1.5707963863995413946e0) (num-test (angle -1.19209289550781250e-07-5.0e-01i) -1.5707965652134757208e0) (num-test (angle -1.19209289550781250e-07-8.3886080e+06i) -1.5707963267949108301e0) (num-test (angle -1/1) pi) (num-test (angle -1/10) pi) (num-test (angle -1/1234) pi) (num-test (angle -1/1234000000) pi) (num-test (angle -1/2) pi) (num-test (angle -1/3) pi) (num-test (angle -1/362880) pi) (num-test (angle -1/500029) pi) (num-test (angle -10) pi) (num-test (angle -10/1) pi) (num-test (angle -10/10) pi) (num-test (angle -10/1234) pi) (num-test (angle -10/1234000000) pi) (num-test (angle -10/2) pi) (num-test (angle -10/3) pi) (num-test (angle -10/362880) pi) (num-test (angle -10/500029) pi) (num-test (angle -1234) pi) (num-test (angle -1234.0) pi) (num-test (angle -1234.0+0.00000001i) 3.14159265358169) (num-test (angle -1234.0+1.0i) 3.14078228099571) (num-test (angle -1234.0+1234.0i) 2.35619449019234) (num-test (angle -1234.0+1234000000.0i) 1.57079732679490) (num-test (angle -1234.0+2.71828182845905i) 3.13938983557381) (num-test (angle -1234.0+3.14159265358979i) 3.13904679794449) (num-test (angle -1234.0-0.00000001i) -3.14159265358169) (num-test (angle -1234.0-1.0i) -3.14078228099571) (num-test (angle -1234.0-1234.0i) -2.35619449019234) (num-test (angle -1234.0-1234000000.0i) -1.57079732679490) (num-test (angle -1234.0-2.71828182845905i) -3.13938983557381) (num-test (angle -1234.0-3.14159265358979i) -3.13904679794449) (num-test (angle -1234/1) pi) (num-test (angle -1234/10) pi) (num-test (angle -1234/1234) pi) (num-test (angle -1234/1234000000) pi) (num-test (angle -1234/2) pi) (num-test (angle -1234/3) pi) (num-test (angle -1234/362880) pi) (num-test (angle -1234/500029) pi) (num-test (angle -1234000000) pi) (num-test (angle -1234000000.0) pi) (num-test (angle -1234000000.0+0.00000001i) pi) (num-test (angle -1234000000.0+1.0i) 3.14159265277942) (num-test (angle -1234000000.0+1234.0i) 3.14159165358979) (num-test (angle -1234000000.0+1234000000.0i) 2.35619449019234) (num-test (angle -1234000000.0+2.71828182845905i) 3.14159265138697) (num-test (angle -1234000000.0+3.14159265358979i) 3.14159265104393) (num-test (angle -1234000000.0-0.00000001i) -3.14159265358979) (num-test (angle -1234000000.0-1.0i) -3.14159265277942) (num-test (angle -1234000000.0-1234.0i) -3.14159165358979) (num-test (angle -1234000000.0-1234000000.0i) -2.35619449019234) (num-test (angle -1234000000.0-2.71828182845905i) -3.14159265138697) (num-test (angle -1234000000.0-3.14159265358979i) -3.14159265104393) (num-test (angle -1234000000/1) pi) (num-test (angle -1234000000/10) pi) (num-test (angle -1234000000/1234) pi) (num-test (angle -1234000000/1234000000) pi) (num-test (angle -1234000000/2) pi) (num-test (angle -1234000000/3) pi) (num-test (angle -1234000000/362880) pi) (num-test (angle -1234000000/500029) pi) (num-test (angle -2) pi) (num-test (angle -2.0e+00+0.0e+00i) 3.1415926535897932385e0) (num-test (angle -2.0e+00+1.0e+00i) 2.6779450445889871222e0) (num-test (angle -2.0e+00+1.19209289550781250e-07i) 3.1415925939851484631e0) (num-test (angle -2.0e+00+2.0e+00i) 2.3561944901923449288e0) (num-test (angle -2.0e+00+5.0e-01i) 2.8966139904629290843e0) (num-test (angle -2.0e+00+8.3886080e+06i) 1.5707965652134757208e0) (num-test (angle -2.0e+00-1.0e+00i) -2.6779450445889871222e0) (num-test (angle -2.0e+00-1.19209289550781250e-07i) -3.1415925939851484631e0) (num-test (angle -2.0e+00-2.0e+00i) -2.3561944901923449288e0) (num-test (angle -2.0e+00-5.0e-01i) -2.8966139904629290843e0) (num-test (angle -2.0e+00-8.3886080e+06i) -1.5707965652134757208e0) (num-test (angle -2.225073858507201399999999999999999999996E-308) 3.141592653589793238462643383279502884195E0) (num-test (angle -2.71828182845905) pi) (num-test (angle -2.71828182845905+0.00000001i) 3.14159264991100) (num-test (angle -2.71828182845905+1.0i) 2.78907923181217) (num-test (angle -2.71828182845905+1234.0i) 1.57299914481088) (num-test (angle -2.71828182845905+1234000000.0i) 1.57079632899772) (num-test (angle -2.71828182845905+2.71828182845905i) 2.35619449019234) (num-test (angle -2.71828182845905+3.14159265358979i) 2.28408086723395) (num-test (angle -2.71828182845905-0.00000001i) -3.14159264991100) (num-test (angle -2.71828182845905-1.0i) -2.78907923181217) (num-test (angle -2.71828182845905-1234.0i) -1.57299914481088) (num-test (angle -2.71828182845905-1234000000.0i) -1.57079632899772) (num-test (angle -2.71828182845905-2.71828182845905i) -2.35619449019234) (num-test (angle -2.71828182845905-3.14159265358979i) -2.28408086723395) (num-test (angle -2/1) pi) (num-test (angle -2/10) pi) (num-test (angle -2/1234) pi) (num-test (angle -2/1234000000) pi) (num-test (angle -2/2) pi) (num-test (angle -2/3) pi) (num-test (angle -2/362880) pi) (num-test (angle -2/500029) pi) (num-test (angle -3) pi) (num-test (angle -3.14159265358979) pi) (num-test (angle -3.14159265358979+0.00000001i) 3.14159265040669) (num-test (angle -3.14159265358979+1.0i) 2.83342358247381) (num-test (angle -3.14159265358979+1234.0i) 1.57334218244020) (num-test (angle -3.14159265358979+1234000000.0i) 1.57079632934076) (num-test (angle -3.14159265358979+2.71828182845905i) 2.42830811315074) (num-test (angle -3.14159265358979+3.14159265358979i) 2.35619449019234) (num-test (angle -3.14159265358979-0.00000001i) -3.14159265040669) (num-test (angle -3.14159265358979-1.0i) -2.83342358247381) (num-test (angle -3.14159265358979-1234.0i) -1.57334218244020) (num-test (angle -3.14159265358979-1234000000.0i) -1.57079632934076) (num-test (angle -3.14159265358979-2.71828182845905i) -2.42830811315074) (num-test (angle -3.14159265358979-3.14159265358979i) -2.35619449019234) (num-test (angle -3/1) pi) (num-test (angle -3/10) pi) (num-test (angle -3/1234) pi) (num-test (angle -3/1234000000) pi) (num-test (angle -3/2) pi) (num-test (angle -3/3) pi) (num-test (angle -3/362880) pi) (num-test (angle -3/500029) pi) (num-test (angle -362880) pi) (num-test (angle -362880/1) pi) (num-test (angle -362880/10) pi) (num-test (angle -362880/1234) pi) (num-test (angle -362880/1234000000) pi) (num-test (angle -362880/2) pi) (num-test (angle -362880/3) pi) (num-test (angle -362880/362880) pi) (num-test (angle -362880/500029) pi) (num-test (angle -5.0e-01+0.0e+00i) 3.1415926535897932385e0) (num-test (angle -5.0e-01+1.0e+00i) 2.0344439357957027354e0) (num-test (angle -5.0e-01+1.19209289550781250e-07i) 3.1415924151712141369e0) (num-test (angle -5.0e-01+2.0e+00i) 1.8157749899217607734e0) (num-test (angle -5.0e-01+5.0e-01i) 2.3561944901923449288e0) (num-test (angle -5.0e-01+8.3886080e+06i) 1.5707963863995413946e0) (num-test (angle -5.0e-01-1.0e+00i) -2.0344439357957027354e0) (num-test (angle -5.0e-01-1.19209289550781250e-07i) -3.1415924151712141369e0) (num-test (angle -5.0e-01-2.0e+00i) -1.8157749899217607734e0) (num-test (angle -5.0e-01-5.0e-01i) -2.3561944901923449288e0) (num-test (angle -5.0e-01-8.3886080e+06i) -1.5707963863995413946e0) (num-test (angle -500029) pi) (num-test (angle -500029/1) pi) (num-test (angle -500029/10) pi) (num-test (angle -500029/1234) pi) (num-test (angle -500029/1234000000) pi) (num-test (angle -500029/2) pi) (num-test (angle -500029/3) pi) (num-test (angle -500029/362880) pi) (num-test (angle -500029/500029) pi) (num-test (angle -8.3886080e+06+0.0e+00i) 3.1415926535897932385e0) (num-test (angle -8.3886080e+06+1.0e+00i) 3.1415925343805036877e0) (num-test (angle -8.3886080e+06+1.19209289550781250e-07i) 3.1415926535897790276e0) (num-test (angle -8.3886080e+06+2.0e+00i) 3.1415924151712141369e0) (num-test (angle -8.3886080e+06+5.0e-01i) 3.1415925939851484631e0) (num-test (angle -8.3886080e+06+8.3886080e+06i) 2.3561944901923449288e0) (num-test (angle -8.3886080e+06-1.0e+00i) -3.1415925343805036877e0) (num-test (angle -8.3886080e+06-1.19209289550781250e-07i) -3.1415926535897790276e0) (num-test (angle -8.3886080e+06-2.0e+00i) -3.1415924151712141369e0) (num-test (angle -8.3886080e+06-5.0e-01i) -3.1415925939851484631e0) (num-test (angle -8.3886080e+06-8.3886080e+06i) -2.3561944901923449288e0) (num-test (angle -9223372036854775808) 3.141592653589793238462643383279502884195E0) (num-test (angle 0) 0) (num-test (angle 0.0) 0.0) (num-test (angle 0.0+0.00000001i) 1.57079632679490) (num-test (angle 0.0+1.0i) 1.57079632679490) (num-test (angle 0.0+1234.0i) 1.57079632679490) (num-test (angle 0.0+1234000000.0i) 1.57079632679490) (num-test (angle 0.0+2.71828182845905i) 1.57079632679490) (num-test (angle 0.0+3.14159265358979i) 1.57079632679490) (num-test (angle 0.0-0.00000001i) -1.57079632679490) (num-test (angle 0.0-1.0i) -1.57079632679490) (num-test (angle 0.0-1234.0i) -1.57079632679490) (num-test (angle 0.0-1234000000.0i) -1.57079632679490) (num-test (angle 0.0-2.71828182845905i) -1.57079632679490) (num-test (angle 0.0-3.14159265358979i) -1.57079632679490) (num-test (angle 0.00000001) 0.0) (num-test (angle 0.00000001+0.00000001i) 0.78539816339745) (num-test (angle 0.00000001+1.0i) 1.57079631679490) (num-test (angle 0.00000001+1234.0i) 1.57079632678679) (num-test (angle 0.00000001+1234000000.0i) 1.57079632679490) (num-test (angle 0.00000001+2.71828182845905i) 1.57079632311610) (num-test (angle 0.00000001+3.14159265358979i) 1.57079632361180) (num-test (angle 0.00000001-0.00000001i) -0.78539816339745) (num-test (angle 0.00000001-1.0i) -1.57079631679490) (num-test (angle 0.00000001-1234.0i) -1.57079632678679) (num-test (angle 0.00000001-1234000000.0i) -1.57079632679490) (num-test (angle 0.00000001-2.71828182845905i) -1.57079632311610) (num-test (angle 0.00000001-3.14159265358979i) -1.57079632361180) (num-test (angle 0.0e+00+0.0e+00i) 0e0) (num-test (angle 0.0e+00+1.0e+00i) 1.5707963267948966192e0) (num-test (angle 0.0e+00+1.19209289550781250e-07i) 1.5707963267948966192e0) (num-test (angle 0.0e+00+2.0e+00i) 1.5707963267948966192e0) (num-test (angle 0.0e+00+5.0e-01i) 1.5707963267948966192e0) (num-test (angle 0.0e+00+8.3886080e+06i) 1.5707963267948966192e0) (num-test (angle 0.0e+00-1.0e+00i) -1.5707963267948966192e0) (num-test (angle 0.0e+00-1.19209289550781250e-07i) -1.5707963267948966192e0) (num-test (angle 0.0e+00-2.0e+00i) -1.5707963267948966192e0) (num-test (angle 0.0e+00-5.0e-01i) -1.5707963267948966192e0) (num-test (angle 0.0e+00-8.3886080e+06i) -1.5707963267948966192e0) (num-test (angle 1) 0) (num-test (angle 1.0) 0.0) (num-test (angle 1.0+0.00000001i) 0.00000001) (num-test (angle 1.0+1.0i) 0.78539816339745) (num-test (angle 1.0+1234.0i) 1.56998595420081) (num-test (angle 1.0+1234000000.0i) 1.57079632598452) (num-test (angle 1.0+2.71828182845905i) 1.21828290501728) (num-test (angle 1.0+3.14159265358979i) 1.26262725567891) (num-test (angle 1.0-0.00000001i) -0.00000001) (num-test (angle 1.0-1.0i) -0.78539816339745) (num-test (angle 1.0-1234.0i) -1.56998595420081) (num-test (angle 1.0-1234000000.0i) -1.57079632598452) (num-test (angle 1.0-2.71828182845905i) -1.21828290501728) (num-test (angle 1.0-3.14159265358979i) -1.26262725567891) (num-test (angle 1.0e+00+0.0e+00i) 0e0) (num-test (angle 1.0e+00+1.0e+00i) 7.8539816339744830962e-1) (num-test (angle 1.0e+00+1.19209289550781250e-07i) 1.1920928955078068531e-7) (num-test (angle 1.0e+00+2.0e+00i) 1.1071487177940905030e0) (num-test (angle 1.0e+00+5.0e-01i) 4.6364760900080611621e-1) (num-test (angle 1.0e+00+8.3886080e+06i) 1.5707962075856070685e0) (num-test (angle 1.0e+00-1.0e+00i) -7.8539816339744830962e-1) (num-test (angle 1.0e+00-1.19209289550781250e-07i) -1.1920928955078068531e-7) (num-test (angle 1.0e+00-2.0e+00i) -1.1071487177940905030e0) (num-test (angle 1.0e+00-5.0e-01i) -4.6364760900080611621e-1) (num-test (angle 1.0e+00-8.3886080e+06i) -1.5707962075856070685e0) (num-test (angle 1.110223024625156799999999999999999999997E-16) 0.0) (num-test (angle 1.19209289550781250e-07+0.0e+00i) 0e0) (num-test (angle 1.19209289550781250e-07+1.0e+00i) 1.5707962075856070685e0) (num-test (angle 1.19209289550781250e-07+1.19209289550781250e-07i) 7.8539816339744830962e-1) (num-test (angle 1.19209289550781250e-07+2.0e+00i) 1.5707962671902518438e0) (num-test (angle 1.19209289550781250e-07+5.0e-01i) 1.5707960883763175177e0) (num-test (angle 1.19209289550781250e-07+8.3886080e+06i) 1.5707963267948824084e0) (num-test (angle 1.19209289550781250e-07-1.0e+00i) -1.5707962075856070685e0) (num-test (angle 1.19209289550781250e-07-1.19209289550781250e-07i) -7.8539816339744830962e-1) (num-test (angle 1.19209289550781250e-07-2.0e+00i) -1.5707962671902518438e0) (num-test (angle 1.19209289550781250e-07-5.0e-01i) -1.5707960883763175177e0) (num-test (angle 1.19209289550781250e-07-8.3886080e+06i) -1.5707963267948824084e0) (num-test (angle 1/1) 0) (num-test (angle 1/10) 0) (num-test (angle 1/1234) 0) (num-test (angle 1/1234000000) 0) (num-test (angle 1/2) 0) (num-test (angle 1/3) 0) (num-test (angle 1/362880) 0) (num-test (angle 1/500029) 0) (num-test (angle 10) 0) (num-test (angle 10/1) 0) (num-test (angle 10/10) 0) (num-test (angle 10/1234) 0) (num-test (angle 10/1234000000) 0) (num-test (angle 10/2) 0) (num-test (angle 10/3) 0) (num-test (angle 10/362880) 0) (num-test (angle 10/500029) 0) (num-test (angle 1234) 0) (num-test (angle 1234.0) 0.0) (num-test (angle 1234.0+0.00000001i) 0.00000000000810) (num-test (angle 1234.0+1.0i) 0.00081037259408) (num-test (angle 1234.0+1234.0i) 0.78539816339745) (num-test (angle 1234.0+1234000000.0i) 1.57079532679490) (num-test (angle 1234.0+2.71828182845905i) 0.00220281801598) (num-test (angle 1234.0+3.14159265358979i) 0.00254585564530) (num-test (angle 1234.0-0.00000001i) -0.00000000000810) (num-test (angle 1234.0-1.0i) -0.00081037259408) (num-test (angle 1234.0-1234.0i) -0.78539816339745) (num-test (angle 1234.0-1234000000.0i) -1.57079532679490) (num-test (angle 1234.0-2.71828182845905i) -0.00220281801598) (num-test (angle 1234.0-3.14159265358979i) -0.00254585564530) (num-test (angle 1234/1) 0) (num-test (angle 1234/10) 0) (num-test (angle 1234/1234) 0) (num-test (angle 1234/1234000000) 0) (num-test (angle 1234/2) 0) (num-test (angle 1234/3) 0) (num-test (angle 1234/362880) 0) (num-test (angle 1234/500029) 0) (num-test (angle 1234000000) 0) (num-test (angle 1234000000.0) 0.0) (num-test (angle 1234000000.0+0.00000001i) 0.0) (num-test (angle 1234000000.0+1.0i) 0.00000000081037) (num-test (angle 1234000000.0+1234.0i) 0.00000100000000) (num-test (angle 1234000000.0+1234000000.0i) 0.78539816339745) (num-test (angle 1234000000.0+2.71828182845905i) 0.00000000220282) (num-test (angle 1234000000.0+3.14159265358979i) 0.00000000254586) (num-test (angle 1234000000.0-0.00000001i) 0.0) (num-test (angle 1234000000.0-1.0i) -0.00000000081037) (num-test (angle 1234000000.0-1234.0i) -0.00000100000000) (num-test (angle 1234000000.0-1234000000.0i) -0.78539816339745) (num-test (angle 1234000000.0-2.71828182845905i) -0.00000000220282) (num-test (angle 1234000000.0-3.14159265358979i) -0.00000000254586) (num-test (angle 1234000000/1) 0) (num-test (angle 1234000000/10) 0) (num-test (angle 1234000000/1234) 0) (num-test (angle 1234000000/1234000000) 0) (num-test (angle 1234000000/2) 0) (num-test (angle 1234000000/3) 0) (num-test (angle 1234000000/362880) 0) (num-test (angle 1234000000/500029) 0) (num-test (angle 2) 0) (num-test (angle 2.0e+00+0.0e+00i) 0e0) (num-test (angle 2.0e+00+1.0e+00i) 4.6364760900080611621e-1) (num-test (angle 2.0e+00+1.19209289550781250e-07i) 5.9604644775390554414e-8) (num-test (angle 2.0e+00+2.0e+00i) 7.8539816339744830962e-1) (num-test (angle 2.0e+00+5.0e-01i) 2.4497866312686415417e-1) (num-test (angle 2.0e+00+8.3886080e+06i) 1.5707960883763175177e0) (num-test (angle 2.0e+00-1.0e+00i) -4.6364760900080611621e-1) (num-test (angle 2.0e+00-1.19209289550781250e-07i) -5.9604644775390554414e-8) (num-test (angle 2.0e+00-2.0e+00i) -7.8539816339744830962e-1) (num-test (angle 2.0e+00-5.0e-01i) -2.4497866312686415417e-1) (num-test (angle 2.0e+00-8.3886080e+06i) -1.5707960883763175177e0) (num-test (angle 2.71828182845905) 0.0) (num-test (angle 2.71828182845905+0.00000001i) 0.00000000367879) (num-test (angle 2.71828182845905+1.0i) 0.35251342177762) (num-test (angle 2.71828182845905+1234.0i) 1.56859350877892) (num-test (angle 2.71828182845905+1234000000.0i) 1.57079632459208) (num-test (angle 2.71828182845905+2.71828182845905i) 0.78539816339745) (num-test (angle 2.71828182845905+3.14159265358979i) 0.85751178635585) (num-test (angle 2.71828182845905-0.00000001i) -0.00000000367879) (num-test (angle 2.71828182845905-1.0i) -0.35251342177762) (num-test (angle 2.71828182845905-1234.0i) -1.56859350877892) (num-test (angle 2.71828182845905-1234000000.0i) -1.57079632459208) (num-test (angle 2.71828182845905-2.71828182845905i) -0.78539816339745) (num-test (angle 2.71828182845905-3.14159265358979i) -0.85751178635585) (num-test (angle 2/1) 0) (num-test (angle 2/10) 0) (num-test (angle 2/1234) 0) (num-test (angle 2/1234000000) 0) (num-test (angle 2/2) 0) (num-test (angle 2/3) 0) (num-test (angle 2/362880) 0) (num-test (angle 2/500029) 0) (num-test (angle 3) 0) (num-test (angle 3.14159265358979+0.00000001i) 0.00000000318310) (num-test (angle 3.14159265358979+1.0i) 0.30816907111598) (num-test (angle 3.14159265358979+1234.0i) 1.56825047114960) (num-test (angle 3.14159265358979+1234000000.0i) 1.57079632424904) (num-test (angle 3.14159265358979+2.71828182845905i) 0.71328454043905) (num-test (angle 3.14159265358979+3.14159265358979i) 0.78539816339745) (num-test (angle 3.14159265358979-0.00000001i) -0.00000000318310) (num-test (angle 3.14159265358979-1.0i) -0.30816907111598) (num-test (angle 3.14159265358979-1234.0i) -1.56825047114960) (num-test (angle 3.14159265358979-1234000000.0i) -1.57079632424904) (num-test (angle 3.14159265358979-2.71828182845905i) -0.71328454043905) (num-test (angle 3.14159265358979-3.14159265358979i) -0.78539816339745) (num-test (angle 3/1) 0) (num-test (angle 3/10) 0) (num-test (angle 3/1234) 0) (num-test (angle 3/1234000000) 0) (num-test (angle 3/2) 0) (num-test (angle 3/3) 0) (num-test (angle 3/362880) 0) (num-test (angle 3/500029) 0) (num-test (angle 362880) 0) (num-test (angle 362880/1) 0) (num-test (angle 362880/10) 0) (num-test (angle 362880/1234) 0) (num-test (angle 362880/1234000000) 0) (num-test (angle 362880/2) 0) (num-test (angle 362880/3) 0) (num-test (angle 362880/362880) 0) (num-test (angle 362880/500029) 0) (num-test (angle 5.0e-01+0.0e+00i) 0.0) (num-test (angle 5.0e-01+1.0e+00i) 1.1071487177940905030e0) (num-test (angle 5.0e-01+1.19209289550781250e-07i) 2.3841857910155798249e-7) (num-test (angle 5.0e-01+2.0e+00i) 1.3258176636680324651e0) (num-test (angle 5.0e-01+5.0e-01i) 7.8539816339744830962e-1) (num-test (angle 5.0e-01+8.3886080e+06i) 1.5707962671902518438e0) (num-test (angle 5.0e-01-1.0e+00i) -1.1071487177940905030e0) (num-test (angle 5.0e-01-1.19209289550781250e-07i) -2.3841857910155798249e-7) (num-test (angle 5.0e-01-2.0e+00i) -1.3258176636680324651e0) (num-test (angle 5.0e-01-5.0e-01i) -7.8539816339744830962e-1) (num-test (angle 5.0e-01-8.3886080e+06i) -1.5707962671902518438e0) (num-test (angle 500029) 0) (num-test (angle 500029/1) 0) (num-test (angle 500029/10) 0) (num-test (angle 500029/1234) 0) (num-test (angle 500029/1234000000) 0) (num-test (angle 500029/2) 0) (num-test (angle 500029/3) 0) (num-test (angle 500029/362880) 0) (num-test (angle 500029/500029) 0) (num-test (angle 8.3886080e+06+0.0e+00i) 0e0) (num-test (angle 8.3886080e+06+1.0e+00i) 1.1920928955078068531e-7) (num-test (angle 8.3886080e+06+1.19209289550781250e-07i) 1.4210854715202003717e-14) (num-test (angle 8.3886080e+06+2.0e+00i) 2.3841857910155798249e-7) (num-test (angle 8.3886080e+06+5.0e-01i) 5.9604644775390554414e-8) (num-test (angle 8.3886080e+06+8.3886080e+06i) 7.8539816339744830962e-1) (num-test (angle 8.3886080e+06-1.0e+00i) -1.1920928955078068531e-7) (num-test (angle 8.3886080e+06-1.19209289550781250e-07i) -1.4210854715202003717e-14) (num-test (angle 8.3886080e+06-2.0e+00i) -2.3841857910155798249e-7) (num-test (angle 8.3886080e+06-5.0e-01i) -5.9604644775390554414e-8) (num-test (angle 8.3886080e+06-8.3886080e+06i) -7.8539816339744830962e-1) (num-test (angle 9223372036854775807) 0) (num-test (angle pi) 0.0) (let ((val1 (catch #t (lambda () (angle 0.0)) (lambda args 'error))) (val2 (catch #t (lambda () (angle -0.0)) (lambda args 'error)))) (test (equal? val1 val2) #t)) (if with-bignums (begin (num-test (angle -1.797693134862315699999999999999999999998E308) 3.141592653589793238462643383279502884195E0) (num-test (angle (complex 1.0 1.0)) (angle (complex (expt 2 70) (expt 2 70)))) (num-test (angle (make-polar 1000000000000000000000000.0 (* .1 pi))) (* .1 pi)) (num-test (angle (complex most-positive-fixnum most-positive-fixnum)) 7.853981633974483096156608458198757210488E-1) )) (test (angle) 'error) (test (angle "hi") 'error) (test (angle 1.0+23.0i 1.0+23.0i) 'error) (for-each (lambda (arg) (test (angle arg) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) ;;; -------------------------------------------------------------------------------- ;;; integer-length ;;; -------------------------------------------------------------------------------- ;;; integer-length (num-test (integer-length 0) 0) (num-test (integer-length 1) 1) (num-test (integer-length 2) 2) (num-test (integer-length 3) 2) (num-test (integer-length 4) 3) (num-test (integer-length 7) 3) (num-test (integer-length 8) 4) (num-test (integer-length 21) 5) (num-test (integer-length 215) 8) (num-test (integer-length 12341234) 24) (num-test (integer-length -1) 0) (num-test (integer-length -2) 1) (num-test (integer-length -3) 2) (num-test (integer-length -4) 2) (num-test (integer-length -7) 3) (num-test (integer-length -8) 3) (num-test (integer-length -9) 4) (num-test (integer-length -21) 5) (num-test (integer-length -215) 8) (num-test (integer-length -12341234) 24) (num-test (integer-length 127) 7) (num-test (integer-length 128) 8) (num-test (integer-length 129) 8) (num-test (integer-length -127) 7) (num-test (integer-length -128) 7) (num-test (integer-length -129) 8) (when (or (not with-bignums) (not pure-s7)) (num-test (integer-length most-negative-fixnum) 63) (num-test (integer-length -9223372036854775808) 63)) (num-test (integer-length most-positive-fixnum) 63) (num-test (integer-length 9223372036854775807) 63) (test (integer-length) 'error) (test (integer-length 1 2) 'error) (test (integer-length 1/2) 'error) (test (integer-length 1.2) 'error) (test (integer-length 1+2i) 'error) (test (integer-length 1/0) 'error) (test (integer-length (log 0)) 'error) (if with-bignums (begin (test (integer-length (bignum "100000000000000000000000000000000000")) (ceiling (log (bignum "100000000000000000000000000000000000") 2))) (num-test (integer-length (+ (expt 2 48) (expt 2 46))) 49) (num-test (integer-length (ash 1 64)) 65) (num-test (integer-length 9223372036854775808) 64) ; ?? (num-test (integer-length (* 4 most-positive-fixnum)) 65) (num-test (integer-length (* most-positive-fixnum most-positive-fixnum)) 126) (test (integer-length 0+92233720368547758081.0i) 'error) (test (integer-length 92233720368547758081.0) 'error) )) (for-each (lambda (arg) (test (integer-length arg) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) ;;; -------------------------------------------------------------------------------- ;;; integer-decode-float ;;; -------------------------------------------------------------------------------- (let () (define (idf-test val1 val2) (test (cadr val1) (cadr val2)) (test (caddr val1) (caddr val2)) (test (< (abs (- (car val1) (car val2))) 1000) #t)) (idf-test (integer-decode-float 0.0) '(0 0 1)) (idf-test (integer-decode-float -0.0) '(0 0 1)) (idf-test (integer-decode-float 1.0) '(4503599627370496 -52 1)) (idf-test (integer-decode-float -1.0) '(4503599627370496 -52 -1)) (idf-test (integer-decode-float 0.2) '(7205759403792794 -55 1)) (idf-test (integer-decode-float -0.2) '(7205759403792794 -55 -1)) (idf-test (integer-decode-float 3.0) '(6755399441055744 -51 1)) (idf-test (integer-decode-float -3.0) '(6755399441055744 -51 -1)) (idf-test (integer-decode-float 0.04) '(5764607523034235 -57 1)) (idf-test (integer-decode-float -0.04) '(5764607523034235 -57 -1)) (idf-test (integer-decode-float 50.0) '(7036874417766400 -47 1)) (idf-test (integer-decode-float -50.0) '(7036874417766400 -47 -1)) (idf-test (integer-decode-float 0.006) '(6917529027641082 -60 1)) (idf-test (integer-decode-float -0.006) '(6917529027641082 -60 -1)) (idf-test (integer-decode-float 7000.0) '(7696581394432000 -40 1)) (idf-test (integer-decode-float -7000.0) '(7696581394432000 -40 -1)) (idf-test (integer-decode-float 0.0008) '(7378697629483821 -63 1)) (idf-test (integer-decode-float -0.0008) '(7378697629483821 -63 -1)) (idf-test (integer-decode-float 90000.0) '(6184752906240000 -36 1)) (idf-test (integer-decode-float -90000.0) '(6184752906240000 -36 -1)) (idf-test (integer-decode-float 0.00001) '(5902958103587057 -69 1)) (idf-test (integer-decode-float 1.0e-6) '(4722366482869645 -72 1)) (idf-test (integer-decode-float 1.0e-8) '(6044629098073146 -79 1)) (idf-test (integer-decode-float 1.0e-12) '(4951760157141521 -92 1)) (idf-test (integer-decode-float 1.0e-16) '(8112963841460668 -106 1)) (idf-test (integer-decode-float 1.0e-17) '(6490371073168535 -109 1)) (idf-test (integer-decode-float 1.0e-18) '(5192296858534828 -112 1)) (idf-test (integer-decode-float 1.0e-19) '(8307674973655724 -116 1)) (idf-test (integer-decode-float 1.0e-25) '(8711228593176025 -136 1)) (idf-test (integer-decode-float 1.0e6) '(8589934592000000 -33 1)) (idf-test (integer-decode-float 1.0e12) '(8192000000000000 -13 1)) (idf-test (integer-decode-float 1.0e17) '(6250000000000000 4 1)) (idf-test (integer-decode-float 1.0e18) '(7812500000000000 7 1)) (idf-test (integer-decode-float 1.0e19) '(4882812500000000 11 1)) (idf-test (integer-decode-float 1.0e20) '(6103515625000000 14 1)) (idf-test (integer-decode-float 1.0e-100) '(7880401239278896 -385 1)) (idf-test (integer-decode-float 1.0e100) '(5147557589468029 280 1)) (idf-test (integer-decode-float 1.0e200) '(5883593420661338 612 1)) (idf-test (integer-decode-float 1.0e-200) '(6894565328877484 -717 1)) (idf-test (integer-decode-float 1.0e307) '(8016673440035891 967 1)) ) (let ((val (integer-decode-float 1.0e-307))) (if (and (not (equal? val '(5060056332682765 -1072 1))) (not (equal? val '(5060056332682766 -1072 1)))) (format-logged #t ";(integer-decode-float 1.0e-307) got ~A?~%" val))) (test (integer-decode-float (/ 1.0e-307 100.0e0)) '(4706001880677807 -1075 1)) ; denormal (test (integer-decode-float (/ (log 0.0))) '(6755399441055744 972 -1)) ; nan (test (integer-decode-float (- (real-part (log 0.0)))) '(4503599627370496 972 1)) ; +inf (test (integer-decode-float (real-part (log 0.0))) '(4503599627370496 972 -1)) ; -inf (test (integer-decode-float 1.797e308) '(9003726357340310 971 1)) (test (integer-decode-float 1.0e-322) '(4503599627370516 -1075 1)) (test (integer-decode-float (expt 2.0 31)) (list #x10000000000000 -21 1)) (test (integer-decode-float (expt 2.0 52)) (list #x10000000000000 0 1)) (test (integer-decode-float 1e23) '(5960464477539062 24 1)) (if with-bignums (begin (test (integer-decode-float 2.225e-308) '(9007049763458157 -1075 1)) (test (integer-decode-float (bignum "3.1")) (integer-decode-float 3.1)) (test (integer-decode-float (bignum "1E430")) '(4503599627370496 972 1)) (test (integer-decode-float (bignum "1E310")) '(4503599627370496 972 1)) (test (integer-decode-float (bignum "-1E310")) '(4503599627370496 972 -1)) (test (integer-decode-float 0+92233720368547758081.0i) 'error) (test (integer-decode-float 92233720368547758081/123) 'error) ) (begin (test (integer-decode-float 1/0) '(6755399441055744 972 1)) ; nan (test (integer-decode-float (real-part (log 0))) '(4503599627370496 972 -1)) ; -inf (test (integer-decode-float (- (real-part (log 0)))) '(4503599627370496 972 1)) ; inf (test (integer-decode-float (/ (real-part (log 0)) (real-part (log 0)))) '(6755399441055744 972 -1)) ; -nan (test (integer-decode-float (- (/ (real-part (log 0)) (real-part (log 0))))) '(6755399441055744 972 1)) ; nan )) (do ((i 0 (+ i 1))) ((= i 100)) (let ((val (- 1.0e6 (random 2.0e6)))) (let* ((data (integer-decode-float val)) (signif (car data)) (expon (cadr data)) (sign (caddr data))) (num-test (* sign signif (expt 2.0 expon)) val)))) (test (integer-decode-float) 'error) (for-each (lambda (arg) (test (integer-decode-float arg) 'error)) (list -1 0 #\a #(1 2 3) 2/3 1.5+0.3i 1+i () 'hi abs "hi" #(()) (list 1 2 3) '(1 . 2) (lambda () 1))) (test (integer-decode-float 1.0 1.0) 'error) ;;; -------------------------------------------------------------------------------- ;;; lognot ;;; -------------------------------------------------------------------------------- (for-each (lambda (op) (for-each (lambda (arg) (let ((val (catch #t (lambda () (op arg)) (lambda args 'error)))) (if (not (equal? val 'error)) (format-logged #t ";(~A ~A) -> ~A?~%" op arg val)))) (list "hi" _ht_ _null_ _c_obj_ () '(1 2) #f (integer->char 65) 'a-symbol (make-vector 3) 3.14 3/4 3.1+i abs #\f (lambda (a) (+ a 1))))) (list logior logand lognot logxor logbit? ash integer-length)) (for-each (lambda (op) (for-each (lambda (arg) (let ((val (catch #t (lambda () (op 1 arg)) (lambda args 'error)))) (if (not (equal? val 'error)) (format-logged #t ";(~A ~A) -> ~A?~%" op arg val)))) (list "hi" _ht_ _null_ _c_obj_ () '(1 2) #f (integer->char 65) 'a-symbol (make-vector 3) 3.14 -1/2 1+i abs #\f (lambda (a) (+ a 1))))) (list logior logand logxor lognot logbit?)) (num-test (lognot 0) -1) (num-test (lognot -1) 0) (num-test (lognot 1) -2) (num-test (lognot #b101) -6) (num-test (lognot -6) #b101) (num-test (lognot 12341234) -12341235) (num-test (lognot #b-101) 4) (num-test (lognot (+ 1 (lognot 1000))) 999) (num-test (lognot #e10e011) -1000000000001) (num-test (lognot -9223372036854775808) 9223372036854775807) (num-test (lognot 9223372036854775807) -9223372036854775808) (num-test (lognot most-positive-fixnum) most-negative-fixnum) (if with-bignums (begin (test (lognot 9223372036854775808) -9223372036854775809) (test (lognot 618970019642690137449562111) (- (expt 2 89))) (num-test (lognot (+ (expt 2 48) (expt 2 46))) -351843720888321) (test (lognot 0+92233720368547758081.0i) 'error) (test (lognot 92233720368547758081.0) 'error) )) (test (lognot) 'error) (test (lognot 1.0) 'error) (test (lognot 1+i) 'error) (test (lognot 1/2) 'error) (test (lognot #f) 'error) (test (lognot 1/1) -2) ;;; -------------------------------------------------------------------------------- ;;; logior ;;; -------------------------------------------------------------------------------- ;;; logior (num-test (logior 0 1) 1) (num-test (logior #b101 #b10001) 21) (num-test (logior 1 3 6) 7) (num-test (logior -6 1) -5) (num-test (logior -6 3) -5) (num-test (logior #b1 #b11 #b111 #b1111) #b1111) (num-test (logior -1 0 -1 -1) -1) (num-test (logior 3 3 3 3) 3) (num-test (logior 1) 1) (num-test (logior -1) -1) (num-test (logior 12341234 10001111) 12378103) (num-test (logior 1 2 4 8) 15) (num-test (logior 0 1/1) 1) (num-test (logior 1/1 0) 1) (num-test (logior -1 1 0) -1) (num-test (logior 1 2 3 4) 7) (num-test (logior 1 3 5 7) 7) (num-test (logior -9223372036854775808 -9223372036854775808) -9223372036854775808) (num-test (logior -9223372036854775808 9223372036854775807 -9223372036854775808) -1) (num-test (logior 9223372036854775807 -9223372036854775808) -1) (num-test (logior 9223372036854775807 9223372036854775807) 9223372036854775807) (num-test (logior) 0) (if with-bignums (begin (test (logior (expt 2 63) (expt 2 75)) (+ (expt 2 63) (expt 2 75))) (num-test (logior (+ (expt 2 48) (expt 2 46)) (expt 2 48)) 351843720888320) (test (logior 0+92233720368547758081.0i) 'error) (test (logior 92233720368547758081.0) 'error) )) (test (logior 0 1.0) 'error) (test (logior 0 1/2) 'error) (test (logior 1.0 0) 'error) (test (logior 1/2 0) 'error) (test (logior 1+i) 'error) (test (logior -1 #\a) 'error) (test (logior -1 "hi") 'error) (test (logior #f "hi") 'error) ;;; -------------------------------------------------------------------------------- ;;; logand ;;; -------------------------------------------------------------------------------- (num-test (logand 0 1) 0) (num-test (logand 0 -1) 0) (num-test (logand #b101 #b10001) 1) (num-test (logand 1 3 6) 0) (num-test (logand -1 3 6) 2) (num-test (logand -6 1) 0) (num-test (logand -6 3) 2) (num-test (logand #b1 #b11 #b111 #b1111) #b1) (num-test (logand -1 0 -1 -1) 0) (num-test (logand 3 3 3 3) 3) (num-test (logand 0) 0) (num-test (logand -1) -1) (num-test (logand 12341234 10001111) 9964242) (num-test (logand -1 1) 1) (num-test (logand -1 -1) -1) (num-test (logand 1 -1) 1) (num-test (logand 1 1) 1) (num-test (logand 16 31) 16) (num-test (logand 0 1/1) 0) (num-test (logand 1/1 0) 0) (num-test (logand 1 -1 -1) 1) (num-test (logand 1 2 3 4) 0) (num-test (logand 1 3 5 7) 1) (num-test (logand -9223372036854775808 -1) -9223372036854775808) (num-test (logand -9223372036854775808 -9223372036854775808) -9223372036854775808) (num-test (logand -9223372036854775808 1) 0) (num-test (logand -9223372036854775808 9223372036854775807 -9223372036854775808) 0) (num-test (logand 9223372036854775807 -1) 9223372036854775807) (num-test (logand 9223372036854775807 -9223372036854775808) 0) (num-test (logand 9223372036854775807 1) 1) (num-test (logand 9223372036854775807 9223372036854775807) 9223372036854775807) (num-test (logand) -1) (if with-bignums (begin (test (logand 9223372036854775808 -9223372036854775809) 0) (test (logand 618970019642690137449562111 (expt 2 88)) (expt 2 88)) (num-test (logand (+ (expt 2 48) (expt 2 46)) (expt 2 48)) 281474976710656) (test (logand 0+92233720368547758081.0i) 'error) (test (logand 92233720368547758081.0) 'error) )) (test (logand 0 1.0) 'error) (test (logand 1+i) 'error) (test (logand 0 1/2) 'error) (test (logand 1.0 0) 'error) (test (logand 1/2 0) 'error) (test (logand 0 #\a) 'error) (test (logand 0 "hi") 'error) (test (logand #f ()) 'error) ;;; -------------------------------------------------------------------------------- ;;; logxor ;;; -------------------------------------------------------------------------------- (num-test (logxor 0 1) 1) (num-test (logxor #b101 #b10001) 20) (num-test (logxor 1 3 6) 4) (num-test (logxor -6 1) -5) (num-test (logxor -6 3) -7) (num-test (logxor #b1 #b11 #b111 #b1111) #b1010) (num-test (logxor 12341234 10001111) 2413861) (num-test (logxor 1 3 7 15) 10) (num-test (logxor 0 1/1) 1) (num-test (logxor 1/1 0) 1) (num-test (logxor 0 1 -1) -2) (num-test (logxor -1 -1 -1) -1) ;; to get the bits that are on in just 1 argument? (logxor (logxor a b c) (logand a b c)) (num-test (logxor 1 2 3 4) 4) (num-test (logxor 1 3 5 7) 0) (num-test (logxor -1 8 8) -1) (num-test (logxor 8 8 8) 8) (num-test (logxor -1 most-positive-fixnum) most-negative-fixnum) (num-test (logxor most-negative-fixnum most-positive-fixnum) -1) (num-test (logxor -100 -100 -100) -100) (num-test (logxor -100 -100 -100 -1) 99) (num-test (logxor -100 -100 -100 -1 -1) -100) (num-test (logxor 4/2 11/11) 3) (num-test (logxor -9223372036854775808 -9223372036854775808) 0) (num-test (logxor -9223372036854775808 9223372036854775807 -9223372036854775808) 9223372036854775807) (num-test (logxor 9223372036854775807 -9223372036854775808) -1) (num-test (logxor 9223372036854775807 9223372036854775807) 0) (num-test (logxor) 0) (if with-bignums (begin (test (logxor 37788155234994016485376 (+ (expt 2 63) 1)) (+ 1 (expt 2 75))) (num-test (logxor (+ (expt 2 48) (expt 2 46)) (expt 2 48)) 70368744177664) (test (logxor 0+92233720368547758081.0i) 'error) (test (logxor 92233720368547758081.0) 'error) )) (test (logxor 0 1.0) 'error) (test (logxor 0 1/2) 'error) (test (logxor 1.0 0) 'error) (test (logxor 1/2 0) 'error) ;;; log-n-of (let ((top-checked-bit (if with-bignums 64 63))) (define (log-none-of . ints) ; bits on in none of ints (lognot (apply logior ints))) (define (log-all-of . ints) ; bits on in all of ints (apply logand ints)) (define (log-any-of . ints) ; bits on in at least 1 of ints (apply logior ints)) (define (log-1-of . ints) ; bits on in exactly 1 of ints (let ((len (length ints))) (cond ((= len 0) 0) ((= len 1) (car ints)) ((= len 2) (apply logxor ints)) ((= len 3) (logxor (apply logxor ints) (apply logand ints))) (#t (do ((iors ()) (i 0 (+ i 1))) ((= i len) (apply logior iors)) (let ((cur (ints i))) (set! (ints i) 0) (set! iors (cons (logand cur (lognot (apply logior ints))) iors)) (set! (ints i) cur))))))) (test (log-1-of 1 1) 0) (test (log-1-of 1 2) 3) (test (log-1-of 1 2 2) 1) (test (log-1-of 1 2 2 1) 0) (test (log-1-of 1 2 3 4 8 9) 4) (test (log-1-of -1 1 2 3) -4) (test (log-1-of 1 2 3 5) 4) (test (log-1-of -6 -31 -19 -9) 0) (test (log-1-of -45 -15 -7 -3) 6) (test (log-1-of -1 most-positive-fixnum -1) 0) (test (log-1-of -1 most-negative-fixnum -1) 0) (test (log-1-of 1 most-negative-fixnum 1) most-negative-fixnum) (test (log-1-of 31 11 27 -38) -60) (test (log-1-of -254) #b-11111110) ; (-254) (test (log-1-of 406 26 439 -361 -133 -480 312) #b1000000) ; (64) (test (log-1-of 47 110) #b1000001) ; (65) (test (log-1-of) 0) (test (log-1-of -52 108 97 48) #b-1101111) ; (-111) (test (log-1-of -113 -391 -129 -58 -374 -297 -498) #b0) ; (0) (test (log-1-of -251 138 418 494 -300 -224) #b10001) ; (17) (test (log-1-of 385 364 372) #b10011001) ; (153) (test (log-1-of -221 -56 173) #b1000110) ; (70) (test (log-1-of 31 -309 244 -478 396 -352 162 -479 -500) #b100000000) ; (256) (test (log-1-of -152 495 80 -403 -439 387) #b10000) ; (16) (test (log-1-of 115 71 110 568 10 382 124 378 23) #b1000000000) ; (512) (test (log-1-of 766 332 285 280 489 229) #b1000000010) ; (514) (test (log-1-of 424 935) #b1000001111) ; (527) (test (log-1-of 788 268 388) #b1010011000) ; (664) (test (log-1-of 389 237 398 530) #b1001110000) ; (624) (test (log-1-of 554 550 215 44 892 668) #b100000001) ; (257) (test (log-1-of 562 171 772 480 6 211 542 678) #b0) ; (0) (do ((i 0 (+ i 1))) ((= i 10)) (let ((len (+ 1 (random 10))) (ints ())) (do ((k 0 (+ k 1))) ((= k len)) (set! ints (cons (- (random 1000) 500) ints))) (let ((result (apply log-1-of ints))) ;;(format-logged #t "(test (log-1-of ~{~D~^ ~}) #b~B) ; (~D)~%" ints result result) (do ((b 0 (+ b 1))) ((= b top-checked-bit)) (let ((counts 0)) (for-each (lambda (int) (if (logbit? int b) ;(not (zero? (logand int (ash 1 b)))) (set! counts (+ counts 1)))) ints) (if (logbit? result b) ;(not (zero? (logand result (ash 1 b)))) (if (not (= counts 1)) (format-logged #t ";(log-1-of ~{~D~^ ~}) -> ~A, [#b~B, counts: ~D but we're on]~%" ints result (ash 1 b) counts)) (if (= counts 1) (format-logged #t ";(log-1-of ~{~D~^ ~}) -> ~A, [#b~B, counts = 1 but we're off]~%" ints result (ash 1 b))))))))) (define (log-n-1-of . ints) ; bits on in exactly n-1 of ints (let ((len (length ints))) (cond ((= len 0) 0) ((= len 1) 0) ((= len 2) (apply logxor ints)) ((= len 3) (logand (lognot (apply logxor ints)) (apply logior ints))) (#t (do ((iors ()) (i 0 (+ i 1))) ((= i len) (apply logior iors)) (let ((cur (ints i))) (set! (ints i) -1) (set! iors (cons (logand (lognot cur) (apply logand ints)) iors)) (set! (ints i) cur))))))) (test (log-n-1-of 1 1) 0) (test (log-n-1-of 1 2) 3) (test (log-n-1-of 1 2 2) 2) (test (log-n-1-of 1 2 2 3) 2) (test (log-n-1-of -336 -225 275) #b-11111101) ; (-253) (test (log-n-1-of -35 32 -17 -310 256 -360 171 -370) #b0) ; (0) (test (log-n-1-of 311 237) #b111011010) ; (474) (test (log-n-1-of 32 348 -340 147) #b0) ; (0) (test (log-n-1-of -334 -267 -478 -93 239 423 18 496) #b100000) ; (32) (test (log-n-1-of -347 149 135 107 -436) #b101) ; (5) (test (log-n-1-of -181 406 480 390 207 13 0) #b0) ; (0) (test (log-n-1-of 348) #b0) ; (0) (test (log-n-1-of -498 226) #b-100010100) ; (-276) (test (log-n-1-of 259 -171 146 -344 63 -240 290 -418) #b0) ; (0) (test (log-n-1-of 86 -74 61 -138 215 -277 358) #b110) ; (6) (test (log-n-1-of -144 425 -356 -341 211 -390) #b0) ; (0) (test (log-n-1-of -223 390 195 265) #b100000001) ; (257) (test (log-n-1-of 103 263 -92 -7) #b100100101) ; (293) (test (log-n-1-of -78 -199 68 218 -98 -464 307 301) #b0) ; (0) (test (log-n-1-of -355 258 -134 -371 211) #b0) ; (0) (test (log-n-1-of -222 -39 408 -50 -207 58) #b100000000) ; (256) (test (log-n-1-of 66 93 484) #b100) ; (4) (test (log-n-1-of 36 -384 3 49 359 -284 -284 -133 268) #b0) ; (0) (test (log-n-1-of -339 -50 243 -159 -159) #b-110011111) ; (-415) (test (log-n-1-of 154 -260 -219 400 -196 -236 421 -277 375 -67) #b0) ; (0) (test (log-n-1-of 45 112) #b1011101) ; (93) (test (log-n-1-of -493 131 48 45 311 197 491 -86 164) #b0) ; (0) (test (log-n-1-of 371 -75 -107 -348 -9 7 -129) #b101) ; (5) (test (log-n-1-of 349 -219 -160) #b-110011011) ; (-411) (test (log-n-1-of 412 456 407 -13 352 467 327 147) #b100000000) ; (256) (test (log-n-1-of 133 -133 -471 -284 -58 -266) #b-1000000000) ; (-512) (test (log-n-1-of 43 -339 22 150 49 259) #b0) ; (0) (test (log-n-1-of 258 -138 185 400 -476 -312 69 380) #b0) ; (0) (test (log-n-1-of 260 -85 -208 -21) #b-111100000) ; (-480) (test (log-n-1-of -294 177 -78) #b-111011110) ; (-478) (test (log-n-1-of -40 81 445 -300) #b11000000) ; (192) (test (log-n-1-of -325 -393 411 -441 -221 -43 -231 -283 -223) #b-1000000000) ; (-512) (test (log-n-1-of 18 -36 -351 -160 211 412) #b0) ; (0) (do ((i 0 (+ i 1))) ((= i 10)) (let ((len (+ 1 (random 10))) (ints ())) (do ((k 0 (+ k 1))) ((= k len)) (set! ints (cons (- (random 1000) 500) ints))) (let ((result (apply log-n-1-of ints))) ;;(format-logged #t "(test (log-n-1-of ~{~D~^ ~}) #b~B) ; (~D)~%" ints result result) (do ((b 0 (+ b 1))) ((= b top-checked-bit)) (let ((counts 0)) (for-each (lambda (int) (if (logbit? int b) ;(not (zero? (logand int (ash 1 b)))) (set! counts (+ counts 1)))) ints) (if (logbit? result b) ;(not (zero? (logand result (ash 1 b)))) (if (not (= counts (- len 1))) (format-logged #t ";(log-n-1-of ~{~D~^ ~}) -> ~A, [#b~B, counts: ~D but we're on]~%" ints result (ash 1 b) counts)) (if (and (> len 1) (= counts (- len 1))) (format-logged #t ";(log-n-1-of ~{~D~^ ~}) -> ~A, [#b~B, counts: ~D but we're off]~%" ints result (ash 1 b) counts)))))))) (define (log-n-of n . ints) ; bits on in exactly n of ints (let ((len (length ints))) (cond ((= len 0) (if (= n 0) -1 0)) ((= n 0) (apply log-none-of ints)) ((= n len) (apply log-all-of ints)) ((> n len) 0) ((= n 1) (apply log-1-of ints)) ((= n (- len 1)) (apply log-n-1-of ints)) ;; now n is between 2 and len-2, and len is 3 or more ;; I think it would be less inefficient here to choose either this or the n-1 case based on n<=len/2 (#t (do ((1s ()) (prev ints) (i 0 (+ i 1))) ((= i len) (apply logior 1s)) (let ((cur (ints i))) (if (= i 0) (set! 1s (cons (logand cur (apply log-n-of (- n 1) (cdr ints))) 1s)) (let* ((mid (cdr prev)) (nxt (if (= i (- len 1)) () (cdr mid)))) (set! (cdr prev) nxt) (set! 1s (cons (logand cur (apply log-n-of (- n 1) ints)) 1s)) (set! (cdr prev) mid) (set! prev mid))))))))) (test (log-n-of 1) 0) (test (log-n-of 0) -1) (test (log-n-of 0 -2) 1) (test (log-n-of 0 92 -451 317 -269 -300 245 461 -64) #b0) (test (log-n-of 0 287) #b-100100000) ; (-288) (test (log-n-of 0 -180 441 -487) #b10) ; (2) (test (log-n-of 0 274 150) #b-110010111) ; (-407) (test (log-n-of 0 140 -307 8 216 -392 8 -486 147 -469) #b100000000) ; (256) (test (log-n-of 1 1 1) 0) (test (log-n-of 1 1 2) 3) (test (log-n-of 2 1 2) 0) (test (log-n-of 2 2 2) 2) (test (log-n-of 2 2 2 2) 0) (test (log-n-of 3 2 2 2) 2) (test (log-n-of 3 2 2 3) 2) (test (log-n-of 3 2 1 3 3) 3) (test (log-n-of 1 158 172 -4 432 147 497 -236 85 -454 -447) #b0) ; (0) (test (log-n-of 1 377 -232 295) #b-110111010) ; (-442) (test (log-n-of 1 -110) #b-1101110) ; (-110) (test (log-n-of 1 304 -36 64 -140 -165 -85) #b0) ; (0) (test (log-n-of 1 226 -135 -392 55 -358 260 -447) #b0) ; (0) (test (log-n-of 1 -241 454 178 107 312) #b-1000000000) ; (-512) (test (log-n-of 1 -122 419 -121) #b100000) ; (32) (test (log-n-of 1 378 -233 -332 -308) #b1) ; (1) (test (log-n-of 1 -381 44 -99 -161 338) #b100000) ; (32) (test (log-n-of 2 6 -45 331 339 156 207 -308) #b-1000000000) ; (-512) (test (log-n-of 2 -483) #b0) ; (0) (test (log-n-of 2 -113 75 465 -434 -164 291) #b10010000) ; (144) (test (log-n-of 2 -95 -314 187 40) #b-111110101) ; (-501) (test (log-n-of 2 126 -254) #b10) ; (2) (test (log-n-of 2 -228) #b0) ; (0) (test (log-n-of 2 -472 163 6 -185 -208 -481 -60 -331 479) #b0) ; (0) (test (log-n-of 2 357 -468 490 -423 33) #b-11111100) ; (-252) (test (log-n-of 2 13 343 -276 148 -425 -116 361 -305 344 -361) #b100000) ; (32) (test (log-n-of 2 -79) #b0) ; (0) (test (log-n-of 3 268 134 46 -207 414) #b100001010) ; (266) (test (log-n-of 3 455 -138 58 -225 -250) #b-111110000) ; (-496) (test (log-n-of 3 -267 154 -217 468 -455 43 307 364) #b-101000000) ; (-320) (test (log-n-of 3 14 197 65 -327 -86 -438) #b-100111101) ; (-317) (test (log-n-of 3 229 452 434 -75 -405 440 -420 40) #b-111111111) ; (-511) (test (log-n-of 3 -24 -450 437 -467 -487 -479 14 394 -433 53) #b110000000) ; (384) (test (log-n-of 3 474 442 303 -203 -59) #b10111111) ; (191) (test (log-n-of 3 -401 104 66) #b1000000) ; (64) (test (log-n-of 3 -129 79 215 -272 -259) #b-101010110) ; (-342) (test (log-n-of 3 -139 36 -489 352 -364 498 -11) #b10000001) ; (129) (test (log-n-of 4 23) #b0) ; (0) (test (log-n-of 4 407 225 417 269 -174 181 -332) #b100110100) ; (308) (test (log-n-of 4 439 480 -278 168 189) #b0) ; (0) (test (log-n-of 4 -206 295) #b0) ; (0) (test (log-n-of 4 -260 24 -320) #b0) ; (0) (test (log-n-of 4 354 -463 -66 137 -364) #b0) ; (0) (test (log-n-of 4 -117 -68 -343 -285) #b-110000000) ; (-384) (test (log-n-of 4 -206 -449 118 -211 -125 391 232) #b-11111011) ; (-251) (test (log-n-of 4 -164 -499 -291 325 -143 -268 135 103) #b10000) ; (16) (do ((i 0 (+ i 1))) ((= i 10)) (let ((len (+ 1 (random 10))) (ints ()) (n (random 5))) (do ((k 0 (+ k 1))) ((= k len)) (set! ints (cons (- (random 1000) 500) ints))) (let ((result (apply log-n-of n ints))) ;;(format-logged #t "(test (log-n-of ~D ~{~D~^ ~}) #b~B) ; (~D)~%" n ints result result) (do ((b 0 (+ b 1))) ((= b top-checked-bit)) (let ((counts 0)) (for-each (lambda (int) (if (logbit? int b) ;(not (zero? (logand int (ash 1 b)))) (set! counts (+ counts 1)))) ints) (if (logbit? result b) ;(not (zero? (logand result (ash 1 b)))) (if (not (= counts n)) (format-logged #t ";(log-n-of ~D ~{~D~^ ~}) -> ~A, [#b~B, counts: ~D but we're on]~%" n ints result (ash 1 b) counts)) (if (and (> len 1) (= counts n)) (format-logged #t ";(log-n-of ~D ~{~D~^ ~}) -> ~A, [#b~B, counts: ~D but we're off]~%" n ints result (ash 1 b) counts)))))))) (define (simple-log-n-of n . ints) ; bits on in exactly n of ints (let ((len (length ints))) (cond ((= len 0) (if (= n 0) -1 0)) ((= n 0) (lognot (apply logior ints))) ((= n len) (apply logand ints)) ((> n len) 0) (#t (do ((1s 0) (prev ints) (i 0 (+ i 1))) ((= i len) 1s) (let ((cur (ints i))) (if (= i 0) (set! 1s (logior 1s (logand cur (apply simple-log-n-of (- n 1) (cdr ints))))) (let* ((mid (cdr prev)) (nxt (if (= i (- len 1)) () (cdr mid)))) (set! (cdr prev) nxt) (set! 1s (logior 1s (logand cur (apply simple-log-n-of (- n 1) ints)))) (set! (cdr prev) mid) (set! prev mid))))))))) (num-test (simple-log-n-of 1 0 0 -1 0) -1) (num-test (simple-log-n-of 1 0 -1 -1 0) 0) (num-test (simple-log-n-of 2 0 -1 -1 0) -1) (num-test (simple-log-n-of 2 0 -1 -1 -1) 0) (num-test (simple-log-n-of 3 0 -1 -1 -1) -1) (num-test (simple-log-n-of 4 0 -1 -1 -1) 0) (do ((i 0 (+ i 1))) ((= i 10)) (let ((len (+ 1 (random 10))) (ints ()) (n (random 5))) (do ((k 0 (+ k 1))) ((= k len)) (set! ints (cons (- (random 1000) 500) ints))) (let ((result (apply simple-log-n-of n ints))) (do ((b 0 (+ b 1))) ((= b top-checked-bit)) (let ((counts 0)) (for-each (lambda (int) (if (logbit? int b) ;(not (zero? (logand int (ash 1 b)))) (set! counts (+ counts 1)))) ints) (if (logbit? result b) ;(not (zero? (logand result (ash 1 b)))) (if (not (= counts n)) (format-logged #t ";(simple-log-n-of ~D ~{~D~^ ~}) -> ~A, [#b~B, counts: ~D but we're on]~%" n ints result (ash 1 b) counts)) (if (and (> len 1) (= counts n)) (format-logged #t ";(simple-log-n-of ~D ~{~D~^ ~}) -> ~A, [#b~B, counts: ~D but we're off]~%" n ints result (ash 1 b) counts))))))))) (let () ; from sbcl/contrib/sb-rotate-byte (define (rotate-byte count bytespec integer) ; logrot? (let* ((size (car bytespec)) (count (- count (* (round (/ count size)) size))) (mask (ash (- (ash 1 size) 1) (cdr bytespec))) (field (logand mask integer))) (logior (logand integer (lognot mask)) (logand mask (logior (ash field count) (ash field ((if (positive? count) - +) count size))))))) (test (rotate-byte 6 (cons 8 0) -3) -129) (test (rotate-byte 3 (cons 32 0) 3) 24) (test (rotate-byte 3 (cons 16 0) 3) 24) (test (rotate-byte 5 (cons 32 0) 5) 160) (test (rotate-byte 5 (cons 32 0) (ash 1 26)) (ash 1 31))) ;;; -------------------------------------------------------------------------------- ;;; logbit? ;;; -------------------------------------------------------------------------------- (test (logbit? 0 1) #f) (test (logbit? 0 0) #f) (test (logbit? 0 -1) 'error) (test (logbit? #b101 1) #f) (test (logbit? #b101 0) #t) (test (logbit? 1 3 6) 'error) (test (logbit? -1 3) #t) (test (logbit? -1 0) #t) (test (logbit? -6 0) #f) (test (logbit? -6 3) #t) (test (logbit? 4 1) #f) (test (logbit? 1 1) #f) (test (logbit? 1 0) #t) (test (logbit? -9223372036854775808 1) #f) (test (logbit? most-positive-fixnum 31) #t) (test (logbit? most-positive-fixnum 68) #f) (test (logbit? most-positive-fixnum 63) #f) (test (logbit? most-positive-fixnum 62) #t) (test (logbit? (ash 1 12) 12) #t) (test (logbit? (ash 1 12) 11) #f) (test (logbit? (ash 1 32) 32) #t) (test (logbit? (ash 1 31) 31) #t) (test (logbit? (ash 1 31) 30) #f) (test (logbit? (ash 1 31) 32) #f) (test (logbit? (ash 1 32) 31) #f) (test (logbit? (ash 1 62) 62) #t) (test (logbit? (ash 1 62) 61) #f) (test (logbit? -1 most-negative-fixnum) 'error) (test (logbit? most-negative-fixnum 63) #t) (test (logbit? most-negative-fixnum 62) #f) (test (logbit? -31 63) #t) (test (logbit? 1 most-positive-fixnum) #f) (test (logbit? 0 most-positive-fixnum) #f) (test (logbit? -1 most-positive-fixnum) #t) (test (logbit? -1 64) #t) (test (logbit? 1 64) #f) ;;; (test (logbit? most-negative-fixnum most-positive-fixnum) #t) ;?? (test (logbit? most-negative-fixnum most-negative-fixnum) 'error) (test (logbit? most-positive-fixnum most-positive-fixnum) #f) (test (logbit? (ash most-negative-fixnum 1) 1) #f) (if with-bignums (begin (test (logbit? (ash 1 64) 64) #t) (test (logbit? (ash 1 64) 63) #f) (test (logbit? most-negative-fixnum 63) #t) (test (logbit? (bignum "-1") 64) #t) )) (test (logbit? 0 1.0) 'error) (test (logbit? 1+i) 'error) (test (logbit? 1+i 0) 'error) (test (logbit? 0 1/2) 'error) (test (logbit? 1.0 0) 'error) (test (logbit? 1/2 0) 'error) (test (logbit? -1/2 0) 'error) (test (logbit? 1/2 123123123) 'error) (test (logbit? 0 #\a) 'error) (test (logbit? 0 "hi") 'error) (test (logbit? #f ()) 'error) (test (logbit?) 'error) (test (logbit? 0) 'error) (test (logbit? -1/9223372036854775807 7) 'error) (test (logbit? -1/9223372036854775807 123123123) 'error) (test (logbit? 1/0 123123123) 'error) (test (logbit? (c-pointer 0) 123123123) 'error) (do ((i 0 (+ i 1))) ((= i 100)) (let ((x (random most-positive-fixnum)) ; or most-negative-fixnum (index (random 63))) (let ((on? (logbit? x index)) (ash? (not (zero? (logand x (ash 1 index)))))) (if (not (eq? on? ash?)) (format-logged #t "(logbit? ~A ~A): ~A ~A~%" x index on? ash?))))) ;;; -------------------------------------------------------------------------------- ;;; ash ;;; -------------------------------------------------------------------------------- (num-test (ash #b-1100 -2) -3) (num-test (ash #b-1100 2) -48) (num-test (ash (ash 1 31) -31) 1) (num-test (ash (expt 2 31) (- (expt 2 31))) 0) (num-test (ash -0 -10) 0) (num-test (ash -1 -12) -1) (num-test (ash -1 -3) -1) (num-test (ash -1 -8) -1) (num-test (ash -1 0) -1) (num-test (ash -1 30) -1073741824) (num-test (ash -1 8) -256) (num-test (ash -129876 -1026) -1) (num-test (ash -2 -3) -1) (num-test (ash -3 -3) -1) (num-test (ash -3 3) -24) (num-test (ash -31 -100) -1) (num-test (ash -31 -20) -1) (num-test (ash -31 -60) -1) (num-test (ash -31 -70) -1) (num-test (ash -31 most-negative-fixnum) -1) (num-test (ash 0 (expt 2 32)) 0) (num-test (ash 0 -10) 0) (num-test (ash 0 0) 0) (num-test (ash 0 1) 0) (num-test (ash 0 100) 0) (num-test (ash 1 (- (expt 2 31))) 0) (num-test (ash 1 (- (expt 2 32))) 0) (num-test (ash 1 -1) 0) (num-test (ash 1 -100) 0) (num-test (ash 1 10) 1024) (num-test (ash 1 31) 2147483648) (num-test (ash 1 32) 4294967296) (num-test (ash 1/1 10) 1024) (num-test (ash 1024 -8) 4) (num-test (ash 123 0) 123) (num-test (ash 1234 -6) 19) (num-test (ash 1234 6) 78976) (num-test (ash 12341234 -16) 188) (num-test (ash 12341234 6) 789838976) (num-test (ash 2 -1) 1) (num-test (ash 2 -2) 0) (test (> (ash 1 30) 1) #t) (test (> (ash 1 62) 1) #t) (test (ash most-positive-fixnum -2) 2305843009213693951) (test (ash most-positive-fixnum -62) 1) (test (ash (ash most-negative-fixnum -2) 2) most-negative-fixnum) ;; (test (ash most-positive-fixnum 2) 'error) if not bignums? (num-test (ash 1000000000 -100000000000) 0) (do ((i 0 (+ i 1))) ((= i 15)) (test (= (expt (ash 1 i) 2) (ash 1 (* 2 i)) (expt 2 (* 2 i)) (* (- (expt 2 i)) (- (ash 1 i))) (ash 2 (- (* i 2) 1))) #t)) (if with-bignums (begin (num-test (ash 1 48) 281474976710656) (num-test (ash most-positive-fixnum 2) 36893488147419103228) (num-test (ash 281474976710656 -48) 1) (num-test (ash -100000000000000000000000000000000 -100) -79) ;; (floor (/ -100000000000000000000000000000000 (expt 2 100))) = -79 (num-test (ash -100000000000000000000000000000000 -200) -1) (num-test (ash 1 63) 9223372036854775808) (num-test (ash 1 64) 18446744073709551616) (num-test (ash 1 100) 1267650600228229401496703205376) (num-test (ash 18446744073709551616 -63) 2) (num-test (ash 1267650600228229401496703205376 -100) 1) (test (ash 1 89) (expt 2 89)) (test (ash 1 0+92233720368547758081.0i) 'error) (test (ash 1 92233720368547758081.0) 'error) (test (ash 0+92233720368547758081.0i -1) 'error) (test (ash 92233720368547758081.0 1) 'error) (num-test (ash 9223372036854775807 1) 18446744073709551614) (num-test (ash -9223372036854775807 1) -18446744073709551614) )) (test (ash 1 (expt 2 32)) 'error) (test (ash) 'error) (test (ash 1) 'error) (test (ash 1 2 3) 'error) (for-each (lambda (arg) (test (ash 1 arg) 'error) (test (ash arg 1) 'error)) (list #\a #f _ht_ _null_ _c_obj_ #(1 2 3) 3.14 2/3 1.5+0.3i 1+i () 'hi abs "hi" #(()) (list 1 2 3) '(1 . 2) (lambda () 1))) (let () ;; fails if x=0: (define (2^n? x) (zero? (logand x (- x 1)))) (define (2^n? x) (and (not (zero? x)) (zero? (logand x (- x 1))))) (define (2^n-1? x) (zero? (logand x (+ x 1)))) (define (x+y x y) (- x (lognot y) 1)) (define (0? x) (negative? (logand (lognot x) (- x 1)))) (define (<=0? x) (negative? (logior x (- x 1)))) (define (>=0? x) (negative? (lognot x))) (define (>0? x) (negative? (logand (- x) (lognot x)))) (define-macro (<=> x y) `(begin (set! ,x (logxor ,x ,y)) (set! ,y (logxor ,y ,x)) (set! ,x (logxor ,x ,y)))) (test (2^n? 32) #t) (test (2^n? 0) #f) (test (2^n? 2305843009213693952) #t) (test (2^n? 2305843009213693950) #f) (test (2^n? 17) #f) (test (2^n? 1) #t) (test (2^n-1? 31) #t) (test (2^n-1? 32) #f) (test (2^n-1? 18014398509481985) #f) (test (2^n-1? 18014398509481983) #t) (test (x+y 41 3) 44) (test (0? 0) #t) (test (0? 123) #f) (test (<=0? 0) #t) (test (<=0? -2) #t) (test (<=0? 2) #f) (test (>=0? -1) #f) (test (>0? 1) #t) (test (let ((x 1) (y 321)) (<=> x y) (list x y)) (list 321 1)) ) (let () (define (bit-reverse int) ;; from "Hacker's Delight" Henry Warren p101, but 64 bit (let ((x int)) (set! x (logior (ash (logand x #x5555555555555555) 1) (ash (logand x #xAAAAAAAAAAAAAAAA) -1))) (set! x (logior (ash (logand x #x3333333333333333) 2) (ash (logand x #xCCCCCCCCCCCCCCCC) -2))) (set! x (logior (ash (logand x #x0F0F0F0F0F0F0F0F) 4) (ash (logand x #xF0F0F0F0F0F0F0F0) -4))) (set! x (logior (ash (logand x #x00FF00FF00FF00FF) 8) (ash (logand x #xFF00FF00FF00FF00) -8))) (set! x (logior (ash (logand x #x0000FFFF0000FFFF) 16) (ash (logand x #xFFFF0000FFFF0000) -16))) (logior (ash (logand x #x00000000FFFFFFFF) 32) (ash (logand x #xFFFFFFFF00000000) -32)))) ;(let ((x (ash (bit-reverse #x01234566) -32))) (num-test x 1721943168)) ) ;; from CL spec (test (let ((str "")) (let ((show (lambda (m x y) (set! str (string-append str (format #f "[m = #o~6,'0O, x = #o~6,'0O, y = #o~6,'0O] " m x y)))))) (let ((m #o007750) (x #o452576) (y #o317407)) (show m x y) (let ((z (logand (logxor x y) m))) (set! x (logxor z x)) (set! y (logxor z y)) (show m x y)))) str) "[m = #o007750, x = #o452576, y = #o317407] [m = #o007750, x = #o457426, y = #o312557] ") #| (DEFUN HAULONG (ARG) (INTEGER-LENGTH (ABS ARG))) (DEFUN HAIPART (X N) (SETQ X (ABS X)) (IF (MINUSP N) (LOGAND X (- (ASH 1 (- N)) 1)) (ASH X (MIN (- N (HAULONG X)) 0)))) |# ;;; -------------------------------------------------------------------------------- ;;; truncate ;;; -------------------------------------------------------------------------------- (num-test (truncate (- (+ 1 -1/123400000))) 0) (num-test (truncate (- 1 1/123400000)) 0) (num-test (truncate (/ (- most-positive-fixnum 1) most-positive-fixnum)) 0) (num-test (truncate (/ -1 most-positive-fixnum)) 0) (num-test (truncate (/ 1 most-positive-fixnum)) 0) (num-test (truncate (/ most-negative-fixnum most-positive-fixnum)) -1) (num-test (truncate (/ most-positive-fixnum (- most-positive-fixnum 1))) 1) (num-test (truncate -0) 0) (num-test (truncate -0.0) 0) (num-test (truncate -0.1) 0) (num-test (truncate -0.9) 0) (num-test (truncate -1) -1) (num-test (truncate -1.1) -1) (num-test (truncate -1.9) -1) (num-test (truncate -1/10) 0) (num-test (truncate -1/123400000) 0) (num-test (truncate -1/2) 0) (num-test (truncate -100/3) -33) (num-test (truncate -11/10) -1) (num-test (truncate -17/2) -8) (num-test (truncate -19/10) -1) (num-test (truncate -2.225073858507201399999999999999999999996E-308) 0) (num-test (truncate -2/3) 0) (num-test (truncate -200/3) -66) (num-test (truncate -3/2) -1) (num-test (truncate -9/10) 0) (num-test (truncate -9223372036854775808) -9223372036854775808) (num-test (truncate 0) 0) (num-test (truncate 0.0) 0) (num-test (truncate 0.1) 0) (num-test (truncate 0.9) 0) (num-test (truncate 1) 1) (num-test (truncate 1.1) 1) (num-test (truncate 1.110223024625156799999999999999999999997E-16) 0) (num-test (truncate 1.9) 1) (num-test (truncate 1/10) 0) (num-test (truncate 1/123400000) 0) (num-test (truncate 1/2) 0) (num-test (truncate 100/3) 33) (num-test (truncate 11/10) 1) (num-test (truncate 17.3) 17) (num-test (truncate 19) 19) (num-test (truncate 19/10) 1) (num-test (truncate 2.4) 2) (num-test (truncate 2.5) 2) (num-test (truncate 2.6) 2) (num-test (truncate 2/3) 0) (num-test (truncate 200/3) 66) (num-test (truncate 3/2) 1) (num-test (truncate 9/10) 0) (num-test (truncate 9223372036854775807) 9223372036854775807) (num-test (truncate most-negative-fixnum) most-negative-fixnum) (num-test (truncate most-positive-fixnum) most-positive-fixnum) (num-test (truncate 1+0i) 1) (if with-bignums (begin (num-test (truncate 8388608.9999999995) 8388608) (num-test (truncate -8388609.0000000005) -8388609) (num-test (truncate -8388609.9999999995) -8388609))) (test (= (truncate (* 111738283365989051/177100989030047175 1.0)) (truncate 130441933147714940/206745572560704147)) #t) (test (= (truncate (* 114243/80782 114243/80782 1.0)) (truncate (* 275807/195025 275807/195025))) #f) (test (= (truncate (* 131836323/93222358 131836323/93222358 1.0)) (truncate (* 318281039/225058681 318281039/225058681))) #f) (test (= (truncate (* 1393/985 1393/985 1.0)) (truncate (* 3363/2378 3363/2378))) #f) (test (= (truncate (* 1607521/1136689 1607521/1136689 1.0)) (truncate (* 3880899/2744210 3880899/2744210))) #f) (if with-bignums (test (= (truncate (* 1855077841/1311738121 1855077841/1311738121 1.0)) (truncate (* 4478554083/3166815962 4478554083/3166815962))) #f)) (test (= (truncate (* 19601/13860 19601/13860 1.0)) (truncate (* 47321/33461 47321/33461))) #f) (test (= (truncate (* 275807/195025 275807/195025 1.0)) (truncate (* 1607521/1136689 1607521/1136689))) #t) (if with-bignums (test (= (truncate (* 318281039/225058681 318281039/225058681 1.0)) (truncate (* 1855077841/1311738121 1855077841/1311738121))) #t)) (test (= (truncate (* 3363/2378 3363/2378 1.0)) (truncate (* 19601/13860 19601/13860))) #t) (test (= (truncate (* 3880899/2744210 3880899/2744210 1.0)) (truncate (* 9369319/6625109 9369319/6625109))) #f) (test (= (truncate (* 47321/33461 47321/33461 1.0)) (truncate (* 114243/80782 114243/80782))) #f) (test (= (truncate (* 54608393/38613965 54608393/38613965 1.0)) (truncate (* 131836323/93222358 131836323/93222358))) #f) (test (= (truncate (* 9369319/6625109 9369319/6625109 1.0)) (truncate (* 54608393/38613965 54608393/38613965))) #t) (if with-bignums (begin (num-test (truncate (+ (expt 2.0 62) 512)) 4611686018427388416) (num-test (truncate (+ (expt 2.0 62) 513)) 4611686018427388417) (num-test (truncate (exact->inexact most-negative-fixnum)) most-negative-fixnum) (test (truncate (exact->inexact most-positive-fixnum)) most-positive-fixnum) (num-test (truncate 1e19) 10000000000000000000) (num-test (truncate 1e32) 100000000000000000000000000000000) (num-test (truncate -1e19) -10000000000000000000) (num-test (truncate -1e32) -100000000000000000000000000000000) (num-test (truncate 100000000000000000000000000000000/3) 33333333333333333333333333333333) (num-test (truncate -100000000000000000000000000000000/3) -33333333333333333333333333333333) (num-test (truncate 200000000000000000000000000000000/3) 66666666666666666666666666666666) (num-test (truncate -200000000000000000000000000000000/3) -66666666666666666666666666666666) (let ((old-prec (*s7* 'bignum-precision))) (set! (*s7* 'bignum-precision) 512) (test (= (truncate (* 111760107268250945908601/79026329715516201199301 111760107268250945908601/79026329715516201199301 1.0)) (truncate (* 269812766699283348307203/190786436983767147107902 269812766699283348307203/190786436983767147107902))) #f) (test (= (truncate (* 1180872205318713601/835002744095575440 1180872205318713601/835002744095575440 1.0)) (truncate (* 2850877693509864481/2015874949414289041 2850877693509864481/2015874949414289041))) #f) (test (= (truncate (* 1362725501650887306817/963592443113182178088 1362725501650887306817/963592443113182178088 1.0)) (truncate (* 3289910387877251662993/2326317944764069484905 3289910387877251662993/2326317944764069484905))) #f) (test (= (truncate (* 14398739476117879/10181446324101389 14398739476117879/10181446324101389 1.0)) (truncate (* 34761632124320657/24580185800219268 34761632124320657/24580185800219268))) #f) (test (= (truncate (* 1572584048032918633353217/1111984844349868137938112 1572584048032918633353217/1111984844349868137938112 1.0)) (truncate (* 3796553736732654909229441/2684568892382786771291329 3796553736732654909229441/2684568892382786771291329))) #f) (test (= (truncate (* 16616132878186749607/11749380235262596085 16616132878186749607/11749380235262596085 1.0)) (truncate (* 40114893348711941777/28365513113449345692 40114893348711941777/28365513113449345692))) #f) (test (= (truncate (* 19175002942688032928599/13558774610046711780701 19175002942688032928599/13558774610046711780701 1.0)) (truncate (* 46292552162781456490001/32733777552734744709300 46292552162781456490001/32733777552734744709300))) #f) (test (= (truncate (* 202605639573839043/143263821649299118 202605639573839043/143263821649299118 1.0)) (truncate (* 489133282872437279/345869461223138161 489133282872437279/345869461223138161))) #f) (test (= (truncate (* 269812766699283348307203/190786436983767147107902 269812766699283348307203/190786436983767147107902 1.0)) (truncate (* 1572584048032918633353217/1111984844349868137938112 1572584048032918633353217/1111984844349868137938112))) #t) (test (= (truncate (* 2850877693509864481/2015874949414289041 2850877693509864481/2015874949414289041 1.0)) (truncate (* 16616132878186749607/11749380235262596085 16616132878186749607/11749380235262596085))) #t) (test (= (truncate (* 3289910387877251662993/2326317944764069484905 3289910387877251662993/2326317944764069484905 1.0)) (truncate (* 19175002942688032928599/13558774610046711780701 19175002942688032928599/13558774610046711780701))) #t) (test (= (truncate (* 34761632124320657/24580185800219268 34761632124320657/24580185800219268 1.0)) (truncate (* 202605639573839043/143263821649299118 202605639573839043/143263821649299118))) #t) (test (= (truncate (* 46292552162781456490001/32733777552734744709300 46292552162781456490001/32733777552734744709300 1.0)) (truncate (* 111760107268250945908601/79026329715516201199301 111760107268250945908601/79026329715516201199301))) #f) (test (= (truncate (* 489133282872437279/345869461223138161 489133282872437279/345869461223138161 1.0)) (truncate (* 1180872205318713601/835002744095575440 1180872205318713601/835002744095575440))) #f) (test (= (truncate (* 564459384575477049359/399133058537705128729 564459384575477049359/399133058537705128729 1.0)) (truncate (* 1362725501650887306817/963592443113182178088 1362725501650887306817/963592443113182178088))) #f) (test (= (truncate (* 5964153172084899/4217293152016490 5964153172084899/4217293152016490 1.0)) (truncate (* 14398739476117879/10181446324101389 14398739476117879/10181446324101389))) #f) (set! (*s7* 'bignum-precision) old-prec)) )) (test (truncate) 'error) (test (truncate 1.23+1.0i) 'error) (for-each (lambda (arg) (test (truncate arg) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) ;;; -------------------------------------------------------------------------------- ;;; floor ;;; -------------------------------------------------------------------------------- (num-test (floor (+ 1 (expt 2 30))) 1073741825) (num-test (floor (- (+ 1 -1/123400000))) -1) (num-test (floor (- 1 1/123400000)) 0) (num-test (floor (/ (- most-positive-fixnum 1) most-positive-fixnum)) 0) (num-test (floor (/ -1 most-positive-fixnum)) -1) (num-test (floor (/ 1 most-positive-fixnum)) 0) (num-test (floor (/ most-negative-fixnum most-positive-fixnum)) -2) (num-test (floor -0) 0) (num-test (floor -0.0) 0) (num-test (floor -0.1) -1) (num-test (floor -0.9) -1) (num-test (floor -1) -1) (num-test (floor -1.1) -2) (num-test (floor -1.9) -2) (num-test (floor -1/10) -1) (num-test (floor -1/123400000) -1) (num-test (floor -1/2) -1) (num-test (floor -100/3) -34) (num-test (floor -11/10) -2) (num-test (floor -17/2) -9) (num-test (floor -19/10) -2) (num-test (floor -2.225073858507201399999999999999999999996E-308) -1) (num-test (floor -2/3) -1) (num-test (floor -200/3) -67) (num-test (floor -3/2) -2) (num-test (floor -9/10) -1) (num-test (floor -9223372036854775808) -9223372036854775808) (num-test (floor 0) 0) (num-test (floor 0.0) 0) (num-test (floor 0.1) 0) (num-test (floor 0.9) 0) (num-test (floor 1) 1) (num-test (floor 1.0-00.i) 1) (num-test (floor 1.1) 1) (num-test (floor 1.110223024625156799999999999999999999997E-16) 0) (num-test (floor 1.9) 1) (num-test (floor 1/10) 0) (num-test (floor 1/123400000) 0) (num-test (floor 1/2) 0) (num-test (floor 100/3) 33) (num-test (floor 11/10) 1) (num-test (floor 17.3) 17) (num-test (floor 19) 19) (num-test (floor 19/10) 1) (num-test (floor 2.5) 2) (num-test (floor 2.6) 2) (num-test (floor 2/3) 0) (num-test (floor 200/3) 66) (num-test (floor 3/2) 1) (num-test (floor 9/10) 0) (num-test (floor 9223372036854775807) 9223372036854775807) (num-test (floor most-negative-fixnum) most-negative-fixnum) (num-test (floor most-positive-fixnum) most-positive-fixnum) (num-test (floor (+ 0.7 8388608.0)) 8388608) (if with-bignums (begin (num-test (floor 8388608.9999999995) 8388608) (num-test (floor 8388607.9999999995) 8388607) (num-test (floor 8388608.0000000005) 8388608) (num-test (floor 9007199254740992.95) 9007199254740992) (num-test (floor 9007199254740990.95) 9007199254740990) (num-test (floor 9007199254740993.95) 9007199254740993) (num-test (floor (+ 0.995 (expt 2.0 46))) 70368744177664) (num-test (floor (+ 0.9995 (expt 2.0 45))) 35184372088832) ) (begin (test (floor 1e308) 'error) (test (floor 1e19) 'error) (test (floor -1e308) 'error) (test (floor -1e19) 'error))) (test (= (floor (* 111738283365989051/177100989030047175 1.0)) (floor 130441933147714940/206745572560704147)) #t) (test (= (floor (* 114243/80782 114243/80782 1.0)) (floor (* 275807/195025 275807/195025))) #f) (test (= (floor (* 131836323/93222358 131836323/93222358 1.0)) (floor (* 318281039/225058681 318281039/225058681))) #f) (test (= (floor (* 1393/985 1393/985 1.0)) (floor (* 3363/2378 3363/2378))) #f) (test (= (floor (* 1607521/1136689 1607521/1136689 1.0)) (floor (* 3880899/2744210 3880899/2744210))) #f) (if with-bignums (test (= (floor (* 1855077841/1311738121 1855077841/1311738121 1.0)) (floor (* 4478554083/3166815962 4478554083/3166815962))) #f)) (test (= (floor (* 19601/13860 19601/13860 1.0)) (floor (* 47321/33461 47321/33461))) #f) (test (= (floor (* 275807/195025 275807/195025 1.0)) (floor (* 1607521/1136689 1607521/1136689))) #t) (if with-bignums (test (= (floor (* 318281039/225058681 318281039/225058681 1.0)) (floor (* 1855077841/1311738121 1855077841/1311738121))) #t)) (test (= (floor (* 3363/2378 3363/2378 1.0)) (floor (* 19601/13860 19601/13860))) #t) (test (= (floor (* 3880899/2744210 3880899/2744210 1.0)) (floor (* 9369319/6625109 9369319/6625109))) #f) (test (= (floor (* 47321/33461 47321/33461 1.0)) (floor (* 114243/80782 114243/80782))) #f) (test (= (floor (* 54608393/38613965 54608393/38613965 1.0)) (floor (* 131836323/93222358 131836323/93222358))) #f) (test (= (floor (* 9369319/6625109 9369319/6625109 1.0)) (floor (* 54608393/38613965 54608393/38613965))) #t) (if with-bignums (begin (num-test (floor (+ (expt 2.0 62) 512)) 4611686018427388416) (num-test (floor (+ (expt 2.0 62) 513)) 4611686018427388417) (num-test (floor (exact->inexact most-negative-fixnum)) most-negative-fixnum) (test (floor (exact->inexact most-positive-fixnum)) most-positive-fixnum) (num-test (floor 1e19) 10000000000000000000) (num-test (floor 1e32) 100000000000000000000000000000000) (num-test (floor -1e19) -10000000000000000000) (num-test (floor -1e32) -100000000000000000000000000000000) (num-test (floor 100000000000000000000000000000000/3) 33333333333333333333333333333333) (num-test (floor -100000000000000000000000000000000/3) -33333333333333333333333333333334) (num-test (floor 200000000000000000000000000000000/3) 66666666666666666666666666666666) (num-test (floor -200000000000000000000000000000000/3) -66666666666666666666666666666667) (test (= (floor (* 1180872205318713601/835002744095575440 1180872205318713601/835002744095575440 1.0)) (floor (* 2850877693509864481/2015874949414289041 2850877693509864481/2015874949414289041))) #f) (test (= (floor (* 1362725501650887306817/963592443113182178088 1362725501650887306817/963592443113182178088 1.0)) (floor (* 3289910387877251662993/2326317944764069484905 3289910387877251662993/2326317944764069484905))) #f) (test (= (floor (* 14398739476117879/10181446324101389 14398739476117879/10181446324101389 1.0)) (floor (* 34761632124320657/24580185800219268 34761632124320657/24580185800219268))) #f) (test (= (floor (* 202605639573839043/143263821649299118 202605639573839043/143263821649299118 1.0)) (floor (* 489133282872437279/345869461223138161 489133282872437279/345869461223138161))) #f) (test (= (floor (* 2850877693509864481/2015874949414289041 2850877693509864481/2015874949414289041 1.0)) (floor (* 16616132878186749607/11749380235262596085 16616132878186749607/11749380235262596085))) #t) (test (= (floor (* 34761632124320657/24580185800219268 34761632124320657/24580185800219268 1.0)) (floor (* 202605639573839043/143263821649299118 202605639573839043/143263821649299118))) #t) (test (= (floor (* 40114893348711941777/28365513113449345692 40114893348711941777/28365513113449345692 1.0)) (floor (* 96845919575610633161/68480406462161287469 96845919575610633161/68480406462161287469))) #f) (test (= (floor (* 46292552162781456490001/32733777552734744709300 46292552162781456490001/32733777552734744709300 1.0)) (floor (* 111760107268250945908601/79026329715516201199301 111760107268250945908601/79026329715516201199301))) #f) (test (= (floor (* 489133282872437279/345869461223138161 489133282872437279/345869461223138161 1.0)) (floor (* 1180872205318713601/835002744095575440 1180872205318713601/835002744095575440))) #f) (test (= (floor (* 5964153172084899/4217293152016490 5964153172084899/4217293152016490 1.0)) (floor (* 14398739476117879/10181446324101389 14398739476117879/10181446324101389))) #f) )) (let ((val1 (catch #t (lambda () (floor 0.0)) (lambda args 'error))) (val2 (catch #t (lambda () (floor -0.0)) (lambda args 'error)))) (test (equal? val1 val2) #t)) (test (floor) 'error) (test (floor 1.23+1.0i) 'error) (test (floor 1.23 1.23) 'error) (let () (define (f1 x) (floor (/ x 3))) (test (f1 6) 2) (test (f1 7) 2) (test (f1 7.3) 2)) (for-each (lambda (arg) (test (floor arg) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) ;;; -------------------------------------------------------------------------------- ;;; ceiling ;;; -------------------------------------------------------------------------------- (num-test (ceiling #e-01-0i ) -1) (num-test (ceiling (- (+ 1 -1/123400000))) 0) (num-test (ceiling (- 1 1/123400000)) 1) (num-test (ceiling (/ (- most-positive-fixnum 1) most-positive-fixnum)) 1) (num-test (ceiling (/ -1 most-positive-fixnum)) 0) (num-test (ceiling (/ 1 most-positive-fixnum)) 1) (num-test (ceiling (/ most-negative-fixnum most-positive-fixnum)) -1) (num-test (ceiling (/ most-positive-fixnum (- most-positive-fixnum 1))) 2) (num-test (ceiling -.0001) 0) (num-test (ceiling -0) 0) (num-test (ceiling -0.0) 0) (num-test (ceiling -0.1) 0) (num-test (ceiling -0.9) 0) (num-test (ceiling -1) -1) (num-test (ceiling -1.1) -1) (num-test (ceiling -1.9) -1) (num-test (ceiling -1/10) 0) (num-test (ceiling -1/123400000) 0) (num-test (ceiling -1/2) 0) (num-test (ceiling -100/3) -33) (num-test (ceiling -11/10) -1) (num-test (ceiling -17/2) -8) (num-test (ceiling -19/10) -1) (num-test (ceiling -2.225073858507201399999999999999999999996E-308) 0) (num-test (ceiling -2/3) 0) (num-test (ceiling -200/3) -66) (num-test (ceiling -2147483647.8) -2147483647) (num-test (ceiling -3/2) -1) (num-test (ceiling -9/10) 0) (num-test (ceiling -9223372036854775808) -9223372036854775808) (num-test (ceiling .0001) 1) (num-test (ceiling 0) 0) (num-test (ceiling 0.0) 0) (num-test (ceiling 0.1) 1) (num-test (ceiling 0.9) 1) (num-test (ceiling 1) 1) (num-test (ceiling 1.01e-123) 1) (num-test (ceiling 1.1) 2) (num-test (ceiling 1.110223024625156799999999999999999999997E-16) 1) (num-test (ceiling 1.9) 2) (num-test (ceiling 1/10) 1) (num-test (ceiling 1/123400000) 1) (num-test (ceiling 1/2) 1) (num-test (ceiling 100/3) 34) (num-test (ceiling 11/10) 2) (num-test (ceiling 17.3) 18) (num-test (ceiling 19) 19) (num-test (ceiling 19/10) 2) (num-test (ceiling 2.4) 3) (num-test (ceiling 2.5) 3) (num-test (ceiling 2.6) 3) (num-test (ceiling 2/3) 1) (num-test (ceiling 200/3) 67) (num-test (ceiling 2147483646.8) 2147483647) (num-test (ceiling 3/2) 2) (num-test (ceiling 9/10) 1) (num-test (ceiling 9223372036854775807) 9223372036854775807) (num-test (ceiling most-negative-fixnum) most-negative-fixnum) (num-test (ceiling most-positive-fixnum) most-positive-fixnum) (num-test (ceiling 8922337203685477.9) 8922337203685478) (if with-bignums (begin (num-test (ceiling 8388608.0000000005) 8388609) (num-test (ceiling 8388609.0000000005) 8388610) (num-test (ceiling 8388607.9999999995) 8388608) (num-test (ceiling 9223372036854775806.9) 9223372036854775807) ) (begin (test (ceiling 1e308) 'error) (test (ceiling 1e19) 'error) (test (ceiling -1e308) 'error) (test (ceiling -1e19) 'error) ;; but unfortunately (ceiling 9223372036854775806.9) => -9223372036854775808 ;; (ceiling 922337203685477580.9) => 922337203685477632 ;; (ceiling 9223372036854770.9) => 9223372036854770 )) (test (= (ceiling (* 111738283365989051/177100989030047175 1.0)) (ceiling 130441933147714940/206745572560704147)) #t) (test (= (ceiling (* 114243/80782 114243/80782 1.0)) (ceiling (* 275807/195025 275807/195025))) #f) (if with-bignums (test (= (ceiling (* 131836323/93222358 131836323/93222358 1.0)) (ceiling (* 318281039/225058681 318281039/225058681))) #f)) (test (= (ceiling (* 1393/985 1393/985 1.0)) (ceiling (* 3363/2378 3363/2378))) #f) (test (= (ceiling (* 1607521/1136689 1607521/1136689 1.0)) (ceiling (* 3880899/2744210 3880899/2744210))) #f) (if with-bignums (test (= (ceiling (* 1855077841/1311738121 1855077841/1311738121 1.0)) (ceiling (* 4478554083/3166815962 4478554083/3166815962))) #f)) (test (= (ceiling (* 19601/13860 19601/13860 1.0)) (ceiling (* 47321/33461 47321/33461))) #f) (test (= (ceiling (* 275807/195025 275807/195025 1.0)) (ceiling (* 1607521/1136689 1607521/1136689))) #t) (test (= (ceiling (* 318281039/225058681 318281039/225058681 1.0)) (ceiling (* 1855077841/1311738121 1855077841/1311738121))) #t) (test (= (ceiling (* 3363/2378 3363/2378 1.0)) (ceiling (* 19601/13860 19601/13860))) #t) (test (= (ceiling (* 3880899/2744210 3880899/2744210 1.0)) (ceiling (* 9369319/6625109 9369319/6625109))) #f) (test (= (ceiling (* 47321/33461 47321/33461 1.0)) (ceiling (* 114243/80782 114243/80782))) #f) (test (= (ceiling (* 54608393/38613965 54608393/38613965 1.0)) (ceiling (* 131836323/93222358 131836323/93222358))) #f) (test (= (ceiling (* 9369319/6625109 9369319/6625109 1.0)) (ceiling (* 54608393/38613965 54608393/38613965))) #t) (if with-bignums (begin (num-test (ceiling (+ (expt 2.0 62) 512)) 4611686018427388416) (num-test (ceiling (+ (expt 2.0 62) 513)) 4611686018427388417) (num-test (ceiling (exact->inexact most-negative-fixnum)) most-negative-fixnum) (test (ceiling (exact->inexact most-positive-fixnum)) most-positive-fixnum) (num-test (ceiling 123456789012345678901234567890.1) 123456789012345678901234567891) (num-test (ceiling -123456789012345678901234567890.1) -123456789012345678901234567890) (num-test (ceiling 9223372036854775806.7) 9223372036854775807) (num-test (ceiling -9223372036854775807.9) -9223372036854775807) (num-test (ceiling -1e19) -10000000000000000000) (num-test (ceiling -1e32) -100000000000000000000000000000000) (num-test (ceiling 100000000000000000000000000000000/3) 33333333333333333333333333333334) (num-test (ceiling -100000000000000000000000000000000/3) -33333333333333333333333333333333) (num-test (ceiling 200000000000000000000000000000000/3) 66666666666666666666666666666667) (num-test (ceiling -200000000000000000000000000000000/3) -66666666666666666666666666666666) (test (= (ceiling (* 1180872205318713601/835002744095575440 1180872205318713601/835002744095575440 1.0)) (ceiling (* 2850877693509864481/2015874949414289041 2850877693509864481/2015874949414289041))) #f) ; (test (= (ceiling (* 1362725501650887306817/963592443113182178088 1362725501650887306817/963592443113182178088 1.0)) ; (ceiling (* 3289910387877251662993/2326317944764069484905 3289910387877251662993/2326317944764069484905))) #f) ;;; this requires much more precision (2048 bits) (test (= (ceiling (* 1362725501650887306817/963592443113182178088 1362725501650887306817/963592443113182178088)) (ceiling (* 3289910387877251662993/2326317944764069484905 3289910387877251662993/2326317944764069484905))) #f) (test (= (ceiling (* 14398739476117879/10181446324101389 14398739476117879/10181446324101389 1.0)) (ceiling (* 34761632124320657/24580185800219268 34761632124320657/24580185800219268))) #f) (test (= (ceiling (* 16616132878186749607/11749380235262596085 16616132878186749607/11749380235262596085 1.0)) (ceiling (* 40114893348711941777/28365513113449345692 40114893348711941777/28365513113449345692))) #f) (test (= (ceiling (* 19175002942688032928599/13558774610046711780701 19175002942688032928599/13558774610046711780701 1.0)) (ceiling (* 46292552162781456490001/32733777552734744709300 46292552162781456490001/32733777552734744709300))) #f) (test (= (ceiling (* 202605639573839043/143263821649299118 202605639573839043/143263821649299118 1.0)) (ceiling (* 489133282872437279/345869461223138161 489133282872437279/345869461223138161))) #f) (test (= (ceiling (* 2850877693509864481/2015874949414289041 2850877693509864481/2015874949414289041 1.0)) (ceiling (* 16616132878186749607/11749380235262596085 16616132878186749607/11749380235262596085))) #t) (test (= (ceiling (* 34761632124320657/24580185800219268 34761632124320657/24580185800219268 1.0)) (ceiling (* 202605639573839043/143263821649299118 202605639573839043/143263821649299118))) #t) (test (= (ceiling (* 489133282872437279/345869461223138161 489133282872437279/345869461223138161 1.0)) (ceiling (* 1180872205318713601/835002744095575440 1180872205318713601/835002744095575440))) #f) (test (= (ceiling (* 564459384575477049359/399133058537705128729 564459384575477049359/399133058537705128729 1.0)) (ceiling (* 1362725501650887306817/963592443113182178088 1362725501650887306817/963592443113182178088))) #f) (test (= (ceiling (* 5964153172084899/4217293152016490 5964153172084899/4217293152016490 1.0)) (ceiling (* 14398739476117879/10181446324101389 14398739476117879/10181446324101389))) #f) (test (= (ceiling (* 96845919575610633161/68480406462161287469 96845919575610633161/68480406462161287469 1.0)) (ceiling (* 564459384575477049359/399133058537705128729 564459384575477049359/399133058537705128729))) #t) )) (let ((val1 (catch #t (lambda () (ceiling 0.0)) (lambda args 'error))) (val2 (catch #t (lambda () (ceiling -0.0)) (lambda args 'error)))) (test (equal? val1 val2) #t)) (test (ceiling) 'error) (test (ceiling 1.23+1.0i) 'error) (test (ceiling 1.23 1.23) 'error) (for-each (lambda (arg) (test (ceiling arg) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) ;;; -------------------------------------------------------------------------------- ;;; round ;;; -------------------------------------------------------------------------------- (num-test (round (- (+ 1 -1/123400000))) -1) (num-test (round (- 1 1/123400000)) 1) (num-test (round (/ (- most-positive-fixnum 1) most-positive-fixnum)) 1) (num-test (round (/ -1 most-positive-fixnum)) 0) (num-test (round (/ 1 most-positive-fixnum)) 0) (num-test (round (/ most-negative-fixnum most-positive-fixnum)) -1) (num-test (round -0) 0) (num-test (round -0.0) 0) (num-test (round -0.1) 0) (num-test (round -0.9) -1) (num-test (round -1) -1) (num-test (round -1.1) -1) (num-test (round -1.9) -2) (num-test (round -1/10) 0) (num-test (round -1/123400000) 0) (num-test (round -1/2) 0) (num-test (round -100/3) -33) (num-test (round -11/10) -1) (num-test (round -17/2) -8) (num-test (round -19/10) -2) (num-test (round -2.225073858507201399999999999999999999996E-308) 0) (num-test (round -2/3) -1) (num-test (round -200/3) -67) (num-test (round -3/2) -2) (num-test (round -9/10) -1) (num-test (round -9223372036854775808) -9223372036854775808) (num-test (round 0) 0) (num-test (round 0.0) 0) (num-test (round 0.1) 0) (num-test (round 0.9) 1) (num-test (round 1) 1) (num-test (round 1.1) 1) (num-test (round 1.110223024625156799999999999999999999997E-16) 0) (num-test (round 1.9) 2) (num-test (round 1/10) 0) (num-test (round 1/123400000) 0) (num-test (round 1/2) 0) (num-test (round 100/3) 33) (num-test (round 11/10) 1) (num-test (round 17.3) 17) (num-test (round 19) 19) (num-test (round 19/10) 2) (num-test (round 2.4) 2) (num-test (round 2.5) 2) (num-test (round 2.5) 2) (num-test (round 2.6) 3) (num-test (round 2/3) 1) (num-test (round 200/3) 67) (num-test (round 3.5) 4) (num-test (round 3/2) 2) (num-test (round 9/10) 1) (num-test (round 9223372036854775807) 9223372036854775807) (num-test (round most-negative-fixnum) most-negative-fixnum) (num-test (round most-positive-fixnum) most-positive-fixnum) (num-test (round (+ 8388608 .1)) 8388608) (num-test (round (+ 8388608 .9)) 8388609) (num-test (round (- 8388608 .1)) 8388608) (num-test (round (- 8388608 .9)) 8388607) (num-test (round 9007199254740990.501) 9007199254740991) (num-test (round 9007199254740990.499) 9007199254740990) (if with-bignums (begin (num-test (round 9007199254740992.51) 9007199254740993) (num-test (round 9007199254740993.99) 9007199254740994)) (begin (test (round 1e308) 'error) (test (round 1e19) 'error) (test (round -1e308) 'error) (test (round -1e19) 'error))) (test (= (round (* 111738283365989051/177100989030047175 1.0)) (round 130441933147714940/206745572560704147)) #t) (test (= (round (* 114243/80782 114243/80782 1.0)) (round (* 275807/195025 275807/195025))) #t) (test (= (round (* 131836323/93222358 131836323/93222358 1.0)) (round (* 318281039/225058681 318281039/225058681))) #t) (test (= (round (* 1393/985 1393/985 1.0)) (round (* 3363/2378 3363/2378))) #t) (test (= (round (* 1607521/1136689 1607521/1136689 1.0)) (round (* 3880899/2744210 3880899/2744210))) #t) (test (= (round (* 1855077841/1311738121 1855077841/1311738121 1.0)) (round (* 4478554083/3166815962 4478554083/3166815962))) #t) (test (= (round (* 19601/13860 19601/13860 1.0)) (round (* 47321/33461 47321/33461))) #t) (test (= (round (* 275807/195025 275807/195025 1.0)) (round (* 1607521/1136689 1607521/1136689))) #t) (test (= (round (* 318281039/225058681 318281039/225058681 1.0)) (round (* 1855077841/1311738121 1855077841/1311738121))) #t) (test (= (round (* 3363/2378 3363/2378 1.0)) (round (* 19601/13860 19601/13860))) #t) (test (= (round (* 3880899/2744210 3880899/2744210 1.0)) (round (* 9369319/6625109 9369319/6625109))) #t) (test (= (round (* 47321/33461 47321/33461 1.0)) (round (* 114243/80782 114243/80782))) #t) (test (= (round (* 54608393/38613965 54608393/38613965 1.0)) (round (* 131836323/93222358 131836323/93222358))) #t) (test (= (round (* 9369319/6625109 9369319/6625109 1.0)) (round (* 54608393/38613965 54608393/38613965))) #t) (test (round 1.23 1.23) 'error) (test (round 1.23+1.0i) 'error) (test (round) 'error) (for-each (lambda (arg) (test (round arg) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) (num-test (round 400000000000000000/800000000000000001) 0) (num-test (round 400000000000000000/799999999999999999) 1) (if with-bignums (begin (num-test (round (+ (expt 2.0 62) 512)) 4611686018427388416) (num-test (round (+ (expt 2.0 62) 513)) 4611686018427388417) (num-test (round (exact->inexact most-negative-fixnum)) most-negative-fixnum) (test (round (exact->inexact most-positive-fixnum)) most-positive-fixnum) (num-test (round -1e19) -10000000000000000000) (num-test (round -1e32) -100000000000000000000000000000000) (num-test (round 100000000000000000000000000000000/3) 33333333333333333333333333333333) (num-test (round -100000000000000000000000000000000/3) -33333333333333333333333333333333) (num-test (round 200000000000000000000000000000000/3) 66666666666666666666666666666667) (num-test (round -200000000000000000000000000000000/3) -66666666666666666666666666666667) (test (= (round (* 1180872205318713601/835002744095575440 1180872205318713601/835002744095575440 1.0)) (round (* 2850877693509864481/2015874949414289041 2850877693509864481/2015874949414289041))) #t) (test (= (round (* 1362725501650887306817/963592443113182178088 1362725501650887306817/963592443113182178088 1.0)) (round (* 3289910387877251662993/2326317944764069484905 3289910387877251662993/2326317944764069484905))) #t) (test (= (round (* 14398739476117879/10181446324101389 14398739476117879/10181446324101389 1.0)) (round (* 34761632124320657/24580185800219268 34761632124320657/24580185800219268))) #t) (test (= (round (* 16616132878186749607/11749380235262596085 16616132878186749607/11749380235262596085 1.0)) (round (* 40114893348711941777/28365513113449345692 40114893348711941777/28365513113449345692))) #t) (test (= (round (* 202605639573839043/143263821649299118 202605639573839043/143263821649299118 1.0)) (round (* 489133282872437279/345869461223138161 489133282872437279/345869461223138161))) #t) (test (= (round (* 2850877693509864481/2015874949414289041 2850877693509864481/2015874949414289041 1.0)) (round (* 16616132878186749607/11749380235262596085 16616132878186749607/11749380235262596085))) #t) (test (= (round (* 34761632124320657/24580185800219268 34761632124320657/24580185800219268 1.0)) (round (* 202605639573839043/143263821649299118 202605639573839043/143263821649299118))) #t) (test (= (round (* 40114893348711941777/28365513113449345692 40114893348711941777/28365513113449345692 1.0)) (round (* 96845919575610633161/68480406462161287469 96845919575610633161/68480406462161287469))) #t) (test (= (round (* 489133282872437279/345869461223138161 489133282872437279/345869461223138161 1.0)) (round (* 1180872205318713601/835002744095575440 1180872205318713601/835002744095575440))) #t) (test (= (round (* 5964153172084899/4217293152016490 5964153172084899/4217293152016490 1.0)) (round (* 14398739476117879/10181446324101389 14398739476117879/10181446324101389))) #t) (test (= (round (* 96845919575610633161/68480406462161287469 96845919575610633161/68480406462161287469 1.0)) (round (* 564459384575477049359/399133058537705128729 564459384575477049359/399133058537705128729))) #t) )) (test (equal? (let ((vals ())) (do ((k 1/3 (+ k 1/3))) ((> k 2) (reverse vals)) (set! vals (cons (round k) vals)))) (list 0 1 1 1 2 2)) #t) (test (equal? (let ((vals ())) (do ((k 1/3 (+ k 1/3))) ((> k 2) (reverse vals)) (set! vals (cons (round (- k)) vals)))) (list 0 -1 -1 -1 -2 -2)) #t) (test (equal? (let ((vals ())) (do ((k 1/2 (+ k 1/2))) ((> k 3) (reverse vals)) (set! vals (cons (round k) vals)))) (list 0 1 2 2 2 3)) #t) (test (equal? (let ((vals ())) (do ((k 1/2 (+ k 1/2))) ((> k 3) (reverse vals)) (set! vals (cons (round (- k)) vals)))) (list 0 -1 -2 -2 -2 -3)) #t) (let ((top-exp 60)) (if with-bignums (set! top-exp 150)) (let ((happy #t)) (do ((i 2 (+ i 1))) ((or (not happy) (> i top-exp))) (let* ((val1 (/ (- (expt 2 i) 1) 2)) (val2 (expt 2 (- i 1))) (fv (floor val1)) (rv (round val1)) (cv (ceiling val1)) (tv (truncate val1))) (if (not (= fv (- val2 1))) (begin (set! happy #f) (format-logged #t ";(floor ~S) = ~S?~%" val1 fv))) (if (not (= cv val2)) (begin (set! happy #f) (format-logged #t ";(ceiling ~S) = ~S?~%" val1 cv))) (if (not (= tv (- val2 1))) (begin (set! happy #f) (format-logged #t ";(truncate ~S) = ~S?~%" val1 tv))) (if (not (= rv val2)) (begin (set! happy #f) (format-logged #t ";(round ~S) = ~S?~%" val1 rv)))))) (let ((happy #t)) (do ((i 2 (+ i 1))) ((or (not happy) (> i top-exp))) (let* ((val1 (/ (+ (expt 2 i) 1) 2)) (val2 (expt 2 (- i 1))) (fv (floor val1)) (rv (round val1)) (cv (ceiling val1)) (tv (truncate val1))) (if (not (= fv val2)) (begin (set! happy #f) (format-logged #t ";(floor ~S) = ~S?~%" val1 fv))) (if (not (= cv (+ val2 1))) (begin (set! happy #f) (format-logged #t ";(ceiling ~S) = ~S?~%" val1 cv))) (if (not (= tv val2)) (begin (set! happy #f) (format-logged #t ";(truncate ~S) = ~S?~%" val1 tv))) (if (not (= rv val2)) (begin (set! happy #f) (format-logged #t ";(round ~S) = ~S?~%" val1 rv)))))) (let ((happy #t)) (do ((i 2 (+ i 1))) ((or (not happy) (> i top-exp))) (let* ((val1 (expt 2 i)) (val2 (- val1 1))) (if (= (floor val1) (floor val2)) (begin (set! happy #f) (format-logged #t ";(floor ~S) = (floor ~S)?~%" val1 val2))) (if (= (ceiling val1) (ceiling val2)) (begin (set! happy #f) (format-logged #t ";(ceiling ~S) = (ceiling ~S)?~%" val1 val2))) (if (= (truncate val1) (truncate val2)) (begin (set! happy #f) (format-logged #t ";(truncate ~S) = (truncate ~S)?~%" val1 val2))) (if (= (round val1) (round val2)) (begin (set! happy #f) (format-logged #t ";(round ~S) = (round ~S)?~%" val1 val2)))))) (let ((happy #t)) (do ((i 2 (+ i 1))) ((or (not happy) (> i top-exp))) (let* ((val1 (/ (- (expt 2 i) 1) 2)) (val2 (/ (- (expt 2 i) 3) 2))) (if (= (floor val1) (floor val2)) (begin (set! happy #f) (format-logged #t ";(floor ~S) = (floor ~S)?~%" val1 val2))) (if (= (ceiling val1) (ceiling val2)) (begin (set! happy #f) (format-logged #t ";(ceiling ~S) = (ceiling ~S)?~%" val1 val2))) (if (= (truncate val1) (truncate val2)) (begin (set! happy #f) (format-logged #t ";(truncate ~S) = (truncate ~S)?~%" val1 val2))) (if (= (round val1) (round val2)) (begin (set! happy #f) (format-logged #t ";(round ~S) = (round ~S)?~%" val1 val2)))))) (let ((happy #t) (off-by 1/3)) (do ((i 2 (+ i 1))) ((or (not happy) (>= i top-exp))) (let* ((val1 (/ (expt 2 i) 3)) (fv (floor val1)) (cv (ceiling val1)) (tv (truncate val1)) (rv (round val1))) (if (not (= fv (- val1 off-by))) (begin (set! happy #f) (format-logged #t ";(floor ~S) = ~S?~%" val1 fv))) (if (not (= cv (+ val1 (- 1 off-by)))) (begin (set! happy #f) (format-logged #t ";(ceiling ~S) = ~S?~%" val1 cv))) (if (not (= tv (- val1 off-by))) (begin (set! happy #f) (format-logged #t ";(truncate ~S) = ~S?~%" val1 tv))) (if (= off-by 1/3) (if (not (= rv (- val1 off-by))) (begin (set! happy #f) (format-logged #t ";(round ~S) = ~S?~%" val1 rv))) (if (not (= rv (+ val1 (- 1 off-by)))) (begin (set! happy #f) (format-logged #t ";(round ~S) = ~S?~%" val1 rv)))) (if (= off-by 1/3) (set! off-by 2/3) (set! off-by 1/3))))) (let ((happy #t)) (do ((i 2 (+ i 1))) ((or (not happy) (> i top-exp))) (let* ((val1 (- (/ (- (expt 2 i) 1) 2))) (val2 (- (expt 2 (- i 1)))) (fv (floor val1)) (rv (round val1)) (cv (ceiling val1)) (tv (truncate val1))) (if (not (= fv val2)) (begin (set! happy #f) (format-logged #t ";(floor ~S) = ~S?~%" val1 fv))) (if (not (= cv (+ val2 1))) (begin (set! happy #f) (format-logged #t ";(ceiling ~S) = ~S?~%" val1 cv))) (if (not (= tv (+ val2 1))) (begin (set! happy #f) (format-logged #t ";(truncate ~S) = ~S?~%" val1 tv))) (if (not (= rv val2)) (begin (set! happy #f) (format-logged #t ";(round ~S) = ~S?~%" val1 rv)))))) (let ((happy #t)) (do ((i 2 (+ i 1))) ((or (not happy) (> i top-exp))) (let* ((val1 (- (/ (+ (expt 2 i) 1) 2))) (val2 (- (expt 2 (- i 1)))) (fv (floor val1)) (rv (round val1)) (cv (ceiling val1)) (tv (truncate val1))) (if (not (= fv (- val2 1))) (begin (set! happy #f) (format-logged #t ";(floor ~S) = ~S?~%" val1 fv))) (if (not (= cv val2)) (begin (set! happy #f) (format-logged #t ";(ceiling ~S) = ~S?~%" val1 cv))) (if (not (= tv val2)) (begin (set! happy #f) (format-logged #t ";(truncate ~S) = ~S?~%" val1 tv))) (if (not (= rv val2)) (begin (set! happy #f) (format-logged #t ";(round ~S) = ~S?~%" val1 rv)))))) (let ((happy #t)) (do ((i 2 (+ i 1))) ((or (not happy) (> i top-exp))) (let* ((val1 (- (expt 2 i))) (val2 (+ val1 1))) (if (= (floor val1) (floor val2)) (begin (set! happy #f) (format-logged #t ";(floor ~S) = (floor ~S)?~%" val1 val2))) (if (= (ceiling val1) (ceiling val2)) (begin (set! happy #f) (format-logged #t ";(ceiling ~S) = (ceiling ~S)?~%" val1 val2))) (if (= (truncate val1) (truncate val2)) (begin (set! happy #f) (format-logged #t ";(truncate ~S) = (truncate ~S)?~%" val1 val2))) (if (= (round val1) (round val2)) (begin (set! happy #f) (format-logged #t ";(round ~S) = (round ~S)?~%" val1 val2)))))) (let ((happy #t)) (do ((i 2 (+ i 1))) ((or (not happy) (> i top-exp))) (let* ((val1 (- (/ (- (expt 2 i) 1) 2))) (val2 (- (/ (- (expt 2 i) 3) 2)))) (if (= (floor val1) (floor val2)) (begin (set! happy #f) (format-logged #t ";(floor ~S) = (floor ~S)?~%" val1 val2))) (if (= (ceiling val1) (ceiling val2)) (begin (set! happy #f) (format-logged #t ";(ceiling ~S) = (ceiling ~S)?~%" val1 val2))) (if (= (truncate val1) (truncate val2)) (begin (set! happy #f) (format-logged #t ";(truncate ~S) = (truncate ~S)?~%" val1 val2))) (if (= (round val1) (round val2)) (begin (set! happy #f) (format-logged #t ";(round ~S) = (round ~S)?~%" val1 val2)))))) (let ((happy #t) (off-by 2/3)) (do ((i 2 (+ i 1))) ((or (not happy) (>= i top-exp))) (let* ((val1 (- (/ (expt 2 i) 3))) (fv (floor val1)) (cv (ceiling val1)) (tv (truncate val1)) (rv (round val1))) (if (not (= fv (- val1 off-by))) (begin (set! happy #f) (format-logged #t ";(floor ~S) = ~S?~%" val1 fv))) (if (not (= cv (+ val1 (- 1 off-by)))) (begin (set! happy #f) (format-logged #t ";(ceiling ~S) = ~S?~%" val1 cv))) (if (not (= tv (+ val1 (- 1 off-by)))) (begin (set! happy #f) (format-logged #t ";(truncate ~S) = ~S?~%" val1 tv))) (if (= off-by 1/3) (if (not (= rv (- val1 off-by))) (begin (set! happy #f) (format-logged #t ";(round ~S) = ~S?~%" val1 rv))) (if (not (= rv (+ val1 (- 1 off-by)))) (begin (set! happy #f) (format-logged #t ";(round ~S) = ~S?~%" val1 rv)))) (if (= off-by 1/3) (set! off-by 2/3) (set! off-by 1/3))))) ) ;;; -------------------------------------------------------------------------------- ;;; modulo ;;; -------------------------------------------------------------------------------- ;;; (modulo x 0) -> x? I seem to be getting errors instead; maxima returns x and refers to Section 3.4, of "Concrete Mathematics," by Graham, Knuth, and Patashnik ;;; (mod x 1.0) = sawtooth (num-test (modulo (/ (expt 2 61)) (/ (expt 3 10))) 1/2305843009213693952) (num-test (modulo (/ (expt 2 61)) (/ (expt 3 20))) 1/2305843009213693952) (num-test (modulo (/ (expt 2 61)) 1/512) 1/2305843009213693952) (num-test (modulo -0.5 -1) -0.5) (num-test (modulo -1 -1) 0) (num-test (modulo -1 -10) -1) (num-test (modulo -1 -1234) -1) (num-test (modulo -1 -1234000000) -1) (num-test (modulo -1 -2) -1) (num-test (modulo -1 -3) -1) (num-test (modulo -1 -362880) -1) (num-test (modulo -1 -500029) -1) (num-test (modulo -1 1) 0) (num-test (modulo -1 10) 9) (num-test (modulo -1 1234) 1233) (num-test (modulo -1 1234000000) 1233999999) (num-test (modulo -1 2) 1) (num-test (modulo -1 3) 2) (num-test (modulo -1 362880) 362879) (num-test (modulo -1 500029) 500028) (num-test (modulo -1.5 -2) -1.5) (num-test (modulo -1.5 2) 0.5) (num-test (modulo -1/2 -1) -1/2) (num-test (modulo -1/2 -1.0) -0.5) (num-test (modulo -1/2 2) 3/2) (num-test (modulo -1/9223372036854775807 -1/3) -1/9223372036854775807) (num-test (modulo -10 -1) 0) (num-test (modulo -10 -10) 0) (num-test (modulo -10 -1234) -10) (num-test (modulo -10 -1234000000) -10) (num-test (modulo -10 -2) 0) (num-test (modulo -10 -3) -1) (num-test (modulo -10 -362880) -10) (num-test (modulo -10 -500029) -10) (num-test (modulo -10 1) 0) (num-test (modulo -10 10) 0) (num-test (modulo -10 1234) 1224) (num-test (modulo -10 1234000000) 1233999990) (num-test (modulo -10 2) 0) (num-test (modulo -10 3) 2) (num-test (modulo -10 362880) 362870) (num-test (modulo -10 500029) 500019) (num-test (modulo -1234 -1) 0) (num-test (modulo -1234 -10) -4) (num-test (modulo -1234 -1234) 0) (num-test (modulo -1234 -1234000000) -1234) (num-test (modulo -1234 -2) 0) (num-test (modulo -1234 -3) -1) (num-test (modulo -1234 -362880) -1234) (num-test (modulo -1234 -500029) -1234) (num-test (modulo -1234 1) 0) (num-test (modulo -1234 10) 6) (num-test (modulo -1234 1234) 0) (num-test (modulo -1234 1234000000) 1233998766) (num-test (modulo -1234 2) 0) (num-test (modulo -1234 3) 2) (num-test (modulo -1234 362880) 361646) (num-test (modulo -1234 500029) 498795) (num-test (modulo -1234000000 -1) 0) (num-test (modulo -1234000000 -10) 0) (num-test (modulo -1234000000 -1234) 0) (num-test (modulo -1234000000 -1234000000) 0) (num-test (modulo -1234000000 -2) 0) (num-test (modulo -1234000000 -3) -1) (num-test (modulo -1234000000 -362880) -208000) (num-test (modulo -1234000000 -500029) -428457) (num-test (modulo -1234000000 1) 0) (num-test (modulo -1234000000 10) 0) (num-test (modulo -1234000000 1234) 0) (num-test (modulo -1234000000 1234000000) 0) (num-test (modulo -1234000000 2) 0) (num-test (modulo -1234000000 3) 2) (num-test (modulo -1234000000 362880) 154880) (num-test (modulo -1234000000 500029) 71572) (num-test (modulo -13 -4) -1) (num-test (modulo -13 4) 3) (num-test (modulo -13 4) 3) (num-test (modulo -2 -1) 0) (num-test (modulo -2 -10) -2) (num-test (modulo -2 -1234) -2) (num-test (modulo -2 -1234000000) -2) (num-test (modulo -2 -2) 0) (num-test (modulo -2 -3) -2) (num-test (modulo -2 -362880) -2) (num-test (modulo -2 -500029) -2) (num-test (modulo -2 1) 0) (num-test (modulo -2 10) 8) (num-test (modulo -2 1234) 1232) (num-test (modulo -2 1234000000) 1233999998) (num-test (modulo -2 2) 0) (num-test (modulo -2 3) 1) (num-test (modulo -2 362880) 362878) (num-test (modulo -2 500029) 500027) (num-test (modulo -2/9223372036854775807 -2/3) -2/9223372036854775807) (num-test (modulo -3 -1) 0) (num-test (modulo -3 -10) -3) (num-test (modulo -3 -1234) -3) (num-test (modulo -3 -1234000000) -3) (num-test (modulo -3 -2) -1) (num-test (modulo -3 -3) 0) (num-test (modulo -3 -362880) -3) (num-test (modulo -3 -500029) -3) (num-test (modulo -3 1) 0) (num-test (modulo -3 1) 0) (num-test (modulo -3 10) 7) (num-test (modulo -3 1234) 1231) (num-test (modulo -3 1234000000) 1233999997) (num-test (modulo -3 2) 1) (num-test (modulo -3 3) 0) (num-test (modulo -3 362880) 362877) (num-test (modulo -3 500029) 500026) (num-test (modulo -3.1 -2.0) -1.1) (num-test (modulo -3.1 2.0) 0.9) ; parallels (modulo -3 2) -> 1 (num-test (modulo -3.1 2.5) 1.9) (num-test (modulo -3.5 1.5) 1.0) (num-test (modulo -3/2 -2) -3/2) (num-test (modulo -3/2 2) 1/2) (num-test (modulo -362880 -1) 0) (num-test (modulo -362880 -10) 0) (num-test (modulo -362880 -1234) -84) (num-test (modulo -362880 -1234000000) -362880) (num-test (modulo -362880 -2) 0) (num-test (modulo -362880 -3) 0) (num-test (modulo -362880 -362880) 0) (num-test (modulo -362880 -500029) -362880) (num-test (modulo -362880 1) 0) (num-test (modulo -362880 10) 0) (num-test (modulo -362880 1234) 1150) (num-test (modulo -362880 1234000000) 1233637120) (num-test (modulo -362880 2) 0) (num-test (modulo -362880 3) 0) (num-test (modulo -362880 362880) 0) (num-test (modulo -362880 500029) 137149) (num-test (modulo -500029 -1) 0) (num-test (modulo -500029 -10) -9) (num-test (modulo -500029 -1234) -259) (num-test (modulo -500029 -1234000000) -500029) (num-test (modulo -500029 -2) -1) (num-test (modulo -500029 -3) -1) (num-test (modulo -500029 -362880) -137149) (num-test (modulo -500029 -500029) 0) (num-test (modulo -500029 1) 0) (num-test (modulo -500029 10) 1) (num-test (modulo -500029 1234) 975) (num-test (modulo -500029 1234000000) 1233499971) (num-test (modulo -500029 2) 1) (num-test (modulo -500029 3) 2) (num-test (modulo -500029 362880) 225731) (num-test (modulo -500029 500029) 0) (num-test (modulo 0 -1) 0) (num-test (modulo 0 -1) 0) (num-test (modulo 0 -10) 0) (num-test (modulo 0 -10) 0) (num-test (modulo 0 -1234) 0) (num-test (modulo 0 -1234) 0) (num-test (modulo 0 -1234000000) 0) (num-test (modulo 0 -1234000000) 0) (num-test (modulo 0 -2) 0) (num-test (modulo 0 -2) 0) (num-test (modulo 0 -3) 0) (num-test (modulo 0 -3) 0) (num-test (modulo 0 -362880) 0) (num-test (modulo 0 -362880) 0) (num-test (modulo 0 -500029) 0) (num-test (modulo 0 -500029) 0) (num-test (modulo 0 -86400) 0) (num-test (modulo 0 1) 0) (num-test (modulo 0 1) 0) (num-test (modulo 0 10) 0) (num-test (modulo 0 10) 0) (num-test (modulo 0 1234) 0) (num-test (modulo 0 1234) 0) (num-test (modulo 0 1234000000) 0) (num-test (modulo 0 1234000000) 0) (num-test (modulo 0 2) 0) (num-test (modulo 0 2) 0) (num-test (modulo 0 3) 0) (num-test (modulo 0 3) 0) (num-test (modulo 0 362880) 0) (num-test (modulo 0 362880) 0) (num-test (modulo 0 500029) 0) (num-test (modulo 0 500029) 0) (num-test (modulo 0 86400) 0) (num-test (modulo 0.5 -2) -1.5) (num-test (modulo 0.5 -2.0) -1.5) (num-test (modulo 0.5 2.0) 0.5) (num-test (modulo 1 -1) 0) (num-test (modulo 1 -10) -9) (num-test (modulo 1 -1234) -1233) (num-test (modulo 1 -1234000000) -1233999999) (num-test (modulo 1 -2) -1) (num-test (modulo 1 -3) -2) (num-test (modulo 1 -362880) -362879) (num-test (modulo 1 -4) -3) (num-test (modulo 1 -500029) -500028) (num-test (modulo 1 1) 0) (num-test (modulo 1 10) 1) (num-test (modulo 1 1234) 1) (num-test (modulo 1 1234000000) 1) (num-test (modulo 1 2) 1) (num-test (modulo 1 3) 1) (num-test (modulo 1 362880) 1) (num-test (modulo 1 500029) 1) (num-test (modulo 1.5 1/3) 0.16666666666667) (num-test (modulo 1.5 1/4) 0.0) (num-test (modulo 1/2 -2) -3/2) (num-test (modulo 1/2 2) 1/2) (num-test (modulo 1/2305843009213693952 1/4) 1/2305843009213693952) (num-test (modulo 1/9223372036854775807 1/2) 1/9223372036854775807) (num-test (modulo 1/9223372036854775807 1/3) 1/9223372036854775807) (num-test (modulo 10 -1) 0) (num-test (modulo 10 -10) 0) (num-test (modulo 10 -1234) -1224) (num-test (modulo 10 -1234000000) -1233999990) (num-test (modulo 10 -2) 0) (num-test (modulo 10 -3) -2) (num-test (modulo 10 -362880) -362870) (num-test (modulo 10 -500029) -500019) (num-test (modulo 10 1) 0) (num-test (modulo 10 10) 0) (num-test (modulo 10 1234) 10) (num-test (modulo 10 1234000000) 10) (num-test (modulo 10 2) 0) (num-test (modulo 10 3) 1) (num-test (modulo 10 362880) 10) (num-test (modulo 10 500029) 10) (num-test (modulo 11/9223372036854775807 3/9223372036854775807) 2/9223372036854775807) (num-test (modulo 1234 -1) 0) (num-test (modulo 1234 -10) -6) (num-test (modulo 1234 -1234) 0) (num-test (modulo 1234 -1234000000) -1233998766) (num-test (modulo 1234 -2) 0) (num-test (modulo 1234 -3) -2) (num-test (modulo 1234 -362880) -361646) (num-test (modulo 1234 -500029) -498795) (num-test (modulo 1234 1) 0) (num-test (modulo 1234 10) 4) (num-test (modulo 1234 1234) 0) (num-test (modulo 1234 1234000000) 1234) (num-test (modulo 1234 2) 0) (num-test (modulo 1234 3) 1) (num-test (modulo 1234 362880) 1234) (num-test (modulo 1234 500029) 1234) (num-test (modulo 1234000000 -1) 0) (num-test (modulo 1234000000 -10) 0) (num-test (modulo 1234000000 -1234) 0) (num-test (modulo 1234000000 -1234000000) 0) (num-test (modulo 1234000000 -2) 0) (num-test (modulo 1234000000 -3) -2) (num-test (modulo 1234000000 -362880) -154880) (num-test (modulo 1234000000 -500029) -71572) (num-test (modulo 1234000000 1) 0) (num-test (modulo 1234000000 10) 0) (num-test (modulo 1234000000 1234) 0) (num-test (modulo 1234000000 1234000000) 0) (num-test (modulo 1234000000 2) 0) (num-test (modulo 1234000000 3) 1) (num-test (modulo 1234000000 362880) 208000) (num-test (modulo 1234000000 500029) 428457) (num-test (modulo 13 -4) -3) (num-test (modulo 13 4) 1) (num-test (modulo 13 4) 1) (num-test (modulo 19439282 4409.5) 2206.0) (num-test (modulo 2 -1) 0) (num-test (modulo 2 -10) -8) (num-test (modulo 2 -1234) -1232) (num-test (modulo 2 -1234000000) -1233999998) (num-test (modulo 2 -2) 0) (num-test (modulo 2 -3) -1) (num-test (modulo 2 -362880) -362878) (num-test (modulo 2 -500029) -500027) (num-test (modulo 2 1) 0) (num-test (modulo 2 10) 2) (num-test (modulo 2 1234) 2) (num-test (modulo 2 1234000000) 2) (num-test (modulo 2 2) 0) (num-test (modulo 2 3) 2) (num-test (modulo 2 362880) 2) (num-test (modulo 2 500029) 2) (num-test (modulo 2/9223372036854775807 2/3) 2/9223372036854775807) (num-test (modulo 3 -1) 0) (num-test (modulo 3 -1) 0) (num-test (modulo 3 -10) -7) (num-test (modulo 3 -1234) -1231) (num-test (modulo 3 -1234000000) -1233999997) (num-test (modulo 3 -2) -1) (num-test (modulo 3 -3) 0) (num-test (modulo 3 -362880) -362877) (num-test (modulo 3 -500029) -500026) (num-test (modulo 3 1) 0) (num-test (modulo 3 1) 0) (num-test (modulo 3 10) 3) (num-test (modulo 3 1234) 3) (num-test (modulo 3 1234000000) 3) (num-test (modulo 3 2) 1) (num-test (modulo 3 2.5) 0.5) (num-test (modulo 3 3) 0) (num-test (modulo 3 362880) 3) (num-test (modulo 3 500029) 3) (num-test (modulo 3.1 -2.0) -0.9) (num-test (modulo 3.1 2) 1.1) (num-test (modulo 3.1 2.0) 1.1) (num-test (modulo 3.5 1.5) 0.5) (num-test (modulo 3/2 1/3) 1/6) (num-test (modulo 3/2 1/4) 0) (num-test (modulo 3/2 3/10) 0) (num-test (modulo 3/3037000501 2/3037000501) 1/3037000501) (num-test (modulo 3/9223372036854775807 2/9223372036854775807) 1/9223372036854775807) (num-test (modulo 362880 -1) 0) (num-test (modulo 362880 -10) 0) (num-test (modulo 362880 -1234) -1150) (num-test (modulo 362880 -1234000000) -1233637120) (num-test (modulo 362880 -2) 0) (num-test (modulo 362880 -3) 0) (num-test (modulo 362880 -362880) 0) (num-test (modulo 362880 -500029) -137149) (num-test (modulo 362880 1) 0) (num-test (modulo 362880 10) 0) (num-test (modulo 362880 1234) 84) (num-test (modulo 362880 1234000000) 362880) (num-test (modulo 362880 2) 0) (num-test (modulo 362880 3) 0) (num-test (modulo 362880 362880) 0) (num-test (modulo 362880 500029) 362880) (num-test (modulo 500029 -1) 0) (num-test (modulo 500029 -10) -1) (num-test (modulo 500029 -1234) -975) (num-test (modulo 500029 -1234000000) -1233499971) (num-test (modulo 500029 -2) -1) (num-test (modulo 500029 -3) -2) (num-test (modulo 500029 -362880) -225731) (num-test (modulo 500029 -500029) 0) (num-test (modulo 500029 1) 0) (num-test (modulo 500029 10) 9) (num-test (modulo 500029 1234) 259) (num-test (modulo 500029 1234000000) 500029) (num-test (modulo 500029 2) 1) (num-test (modulo 500029 3) 1) (num-test (modulo 500029 362880) 137149) (num-test (modulo 500029 500029) 0) (num-test (modulo 922337203685477 1/3) 0) (num-test (modulo 9223372036854775 1/3) 0) (num-test (modulo 92233720368547758 1/3) 0) (num-test (modulo 92233720368547758/23 1/3) 1/69) (num-test (modulo 922337203685477580 1/3) 0) (num-test (modulo 2755 13) 12) (num-test (modulo 56 2) 0) (num-test (modulo 148665 2) 1) (num-test (modulo 71862 203) 0) (num-test (modulo 21568911 41) 0) (num-test (modulo 15295874 111) 74) (num-test (modulo 20430054 41) 0) (num-test (modulo 248255254 767) 364) (num-test (modulo 510104442 5453) 3557) (num-test (modulo 242162410 41) 10) (num-test (modulo 660070972 74) 0) (num-test (modulo 6542405452 117) 37) (num-test (modulo 629448534 2) 0) (num-test (modulo 163873565922 155) 62) (num-test (modulo 1563464979842 442) 272) (num-test (modulo 3712337724 576173) 55085) (num-test (modulo 4380921044390 5) 0) (num-test (modulo 4097970629150 86) 16) (num-test (modulo 2090198664 1118) 398) (num-test (modulo 5275411661289 31857) 10521) (num-test (modulo 38602581835881 19) 8) (num-test (modulo 82578867500655 319) 174) (num-test (modulo 363169800 20) 0) (num-test (modulo 2033404107084 23374) 16730) (num-test (modulo 7438317458260 31213) 22165) (num-test (modulo 390609000 11) 1) (num-test (modulo 406117800 57) 39) (num-test (modulo 1008217762344 4403) 3922) (num-test (modulo 136581511784536 67022) 19220) (num-test (modulo 43293168048 1344610) 759878) (num-test (modulo 608503422693864 47) 0) (num-test (modulo 6945109296864 779) 722) (num-test (modulo 1346702251365156 435) 261) (num-test (modulo 1388225063690465 644) 525) (num-test (modulo 1200780158492850 91686) 60534) (num-test (modulo 1551193257090906 2656731) 2347158) (num-test (modulo 386512944051107445 17) 0) (num-test (modulo 1111364125679340 6) 0) (num-test (modulo 15858537083857314 21793) 0) (num-test (modulo 44179338013272 280645) 48872) (num-test (modulo 64149298745840 43808357) 20657028) (num-test (modulo 4412914630225794 515823) 281358) (num-test (modulo 169216424701305960 17) 14) (num-test (modulo 178335507754891305 817) 0) (num-test (modulo -9223372036854775808 -9223372036854775808) 0) (num-test (modulo 1.110223024625156799999999999999999999997E-16 -9223372036854775808) -9.223372036854775807999999999999999888978E18) (num-test (modulo 5.551115123125783999999999999999999999984E-17 1.110223024625156799999999999999999999997E-16) 5.551115123125783999999999999999999999984E-17) (num-test (modulo 9223372036854775807 -9223372036854775808) -1) (num-test (modulo 9223372036854775807 9223372036854775807) 0) (num-test (modulo 8/3 3/2) 7/6) (num-test (modulo 37/8 17/12) 3/8) (num-test (modulo 12/19 41/29) 12/19) (num-test (modulo 389/84 99/70) 163/420) (num-test (modulo 1456/401 577/408) 65647/81804) (num-test (modulo 9097/1054 1393/985) 151213/1038190) (num-test (modulo 53963/20511 3363/2378) 59345521/48775158) (num-test (modulo 163963/24727 19601/13860) 83457868/85679055) (num-test (modulo 456564/125743 47321/33461) 3376518998/4207486523) (num-test (modulo 794525/301994 114243/80782) 7420654502/6098919827) (num-test (modulo 75261245/11350029 275807/195025) 2156154512513/2213539405725) (num-test (modulo 92819835/16483927 1607521/1136689) 26012508981414/18737098497703) (num-test (modulo 44957104/17087915 3880899/2744210) 11411052426451/9378565444430) (num-test (modulo 53715833/85137581 9369319/6625109) 53715833/85137581) (num-test (modulo 171928773/272500658 54608393/38613965) 171928773/272500658) (num-test (modulo 4178406761/630138897 131836323/93222358) 28610075152269757/29371516922929563) (num-test (modulo 1/9223372036 9223372036) 1/9223372036) (num-test (modulo 1/9223372036854775807 9223372036854775807) 1/9223372036854775807) (num-test (modulo 3/2 most-positive-fixnum) 3/2) (num-test (modulo most-negative-fixnum -1) 0) (if (not with-bignums) (num-test (modulo 3/2 most-negative-fixnum) 'error)) (if with-bignums (begin (num-test (modulo 3/2 most-negative-fixnum) -18446744073709551613/2) (num-test (modulo (+ 2 (* 3 499127 495037 490459 468803)) (* 499127 495037 490459 468803)) 2) (num-test (modulo -9223372036854775808 5.551115123125783999999999999999999999984E-17) 3.258027528318940824192395666614174842834E-17) (num-test (modulo 12345678901234567890 12345678901234567) 890) (num-test (modulo 12345678901234567890 3123) 1071) (num-test (modulo 460683358924445799142 518) 0) (num-test (modulo 113021475230160 74635) 67850) (num-test (modulo 74228340534140364 363909) 357201) (num-test (modulo 69242022961311060 48305942) 17170072) (num-test (modulo 286967952870300 2273388) 2067312) (num-test (modulo 302822258393413362492399 29) 0) (num-test (modulo 10491072879382200 133) 0) (num-test (modulo 167206737423420464 609) 539) (num-test (modulo 72212583812867784 4888799) 1883149) (num-test (modulo 4170116471639397292390 1798025) 1078815) (num-test (modulo 83910330283522050 35224) 9282) (num-test (modulo 275373383775647594346 66884092) 19813626) (num-test (modulo 14656657495570695990 37) 7) (num-test (modulo 95470974177676509874110 1219) 0) (num-test (modulo 619506317623001424 5957) 3304) (num-test (modulo 11268171656665155960 9858) 372) (num-test (modulo 6172860073826160 5167394) 906830) (num-test (modulo 26457493095663264 1491412) 1103724) (num-test (modulo 8481384175941103284 313836405) 93136149) (num-test (modulo 60356595775749199080 176098815946) 156894620552) (num-test (modulo 611492274956002440 37) 0) (num-test (modulo 164614611843685080 1711) 177) (num-test (modulo 93177516542679418720 62197) 37333) (num-test (modulo 938959746797519770440 127558) 0) (num-test (modulo 137670522526899326250 200) 50) (num-test (modulo 852063402206742880 41643478) 23771242) (num-test (modulo 55947291202307909360 188546228) 125937196) (num-test (modulo 12877971214039423262680 9832253830) 8120608300) (num-test (modulo 192158415774146059920 53) 0) (num-test (modulo 902814024155808960 1829) 434) (num-test (modulo 1265864304573235487120 4921) 1295) (num-test (modulo 14172662463567665400 95817) 38076) (num-test (modulo 32171996211745702482324 2368555) 459984) (num-test (modulo 971324258606045826300 4576748) 342908) (num-test (modulo 2400649320046378377000 1704690) 165540) (num-test (modulo 953233796456393760 18342152493) 178603257) (num-test (modulo 28906333140964843080 236206740) 140736420) (num-test (modulo 775403093708557121609032 41) 0) (num-test (modulo 12587009808135760402860 2491) 1410) (num-test (modulo 510685807527370566909720 76) 44) (num-test (modulo 9842598153710524682146590 10089) 3363) (num-test (modulo 44936631038618189620242012 30740) 24592) (num-test (modulo 934589372977008750144 373650) 202194) (num-test (modulo 33027125273398900134069150 840577803) 0) (num-test (modulo 4428219127938822420288 1695783782) 1071746452) (num-test (modulo 29316428815807608915440 560764380) 415244720) (num-test (modulo 1364397376360544429904 19) 0) (num-test (modulo 4991450791697293128313385277 329) 133) (num-test (modulo 75448279792981695149550 3009) 2385) (num-test (modulo 181031604499464166188731133 3364) 1641) (num-test (modulo 405831142402606479845286 2746214) 1938504) (num-test (modulo 89170366469003867207160 25337230) 23157930) (num-test (modulo 13523725766340619200 1490114045) 621483730) (num-test (modulo 104705939487154940255412 192200052) 48253032) (num-test (modulo 7232591421499800642000 16584679460) 4668328860) (num-test (modulo 14043796716396386984750160 33382708236) 717907704) (num-test (modulo 13894638105872256412416 23) 0) (num-test (modulo 147611447155643499428400 118) 68) (num-test (modulo 13356594697070649024 4558) 1802) (num-test (modulo 15089731174706036171537760 90) 60) (num-test (modulo 307230141273924828960 1971507) 1430805) (num-test (modulo 2582563944548247741930009096 22873474) 3518996) (num-test (modulo 1074296602920111687342072 146235518) 73672588) (num-test (modulo 774058642832724262993980 407557010) 187324340) (num-test (modulo 291091930213008490369569480 13412544348) 10762778160) (num-test (modulo 2089068565149831833568 7302038455228) 470177842332) (num-test (modulo 1064437567441124038217970656 5) 1) (num-test (modulo 142557826750459447787460 1333) 527) (num-test (modulo 311779340580033594160200 23693) 0) (num-test (modulo 29314187023691666530559664 110143) 0) (num-test (modulo 222003853016244177637944900 857463) 0) (num-test (modulo 6247776111945111006243552 77976501) 12576855) (num-test (modulo 1140058514761397155259712 5530338) 502758) (num-test (modulo 580962736822969724865449808 55686036) 13545252) (num-test (modulo 4100502596989506786787500 45333475410) 13925822190) (num-test (modulo 1497378750311599979536944 262630276090) 236984817664) (num-test (modulo 105637634198318524045536 2633013240) 452166936) (num-test (modulo 11415822547029425161364106595632 7) 3) (num-test (modulo 198305933339312916107438448 177) 15) (num-test (modulo 3127415425979879537134790928 3335) 2668) (num-test (modulo 589703503861221139260034914750 13209) 4641) (num-test (modulo 3108579252052448504121792 14322) 12936) (num-test (modulo 636976201153021006473464400 66264077) 55801328) (num-test (modulo 9544425315508129998909285900 1488396) 850512) (num-test (modulo 458100280193857502802977376 260747103934) 17656078468) (num-test (modulo 114208186302155358124900650 22076867505) 6602131305) (num-test (modulo 90107067439719108194114160 28566806069714) 24735629596458) (num-test (modulo 2976572787365723002218245484 110104803958578) 49695655366500) (num-test (modulo 53453375725613238735360 17) 7) (num-test (modulo 888822833524306124874229800 106) 0) (num-test (modulo 21275338550698297089687698855820 3021) 0) (num-test (modulo 417525245705449941528380320750068 5828) 0) (num-test (modulo 1954871230146370370001829871352 22765249) 0) (num-test (modulo 903057827710908645847577520 648545995) 631903275) (num-test (modulo 6002846634833433581621040 28493572159) 8965596645) (num-test (modulo 26428903214964558277189300080 100428856) 20778384) (num-test (modulo 470486531607553676511206181180 28495896) 23264436) (num-test (modulo 483599554429365539310928369206620 5577334078910) 3472679709510) (num-test (modulo 134511400157705323668887400 1285071093558916) 114037248705380) (num-test (modulo 25897125642468049125349982599216 1183846707540) 999692775256) (num-test (modulo 1118034209930460291955200 3) 0) (num-test (modulo 16297594064835666104344589410644 413) 0) (num-test (modulo 536762539932642345554192060100 1378) 0) (num-test (modulo 933250179448203335817687635834340 58029) 55821) (num-test (modulo 65573457048202714607131200 486115) 32895) (num-test (modulo 85664559165674439863772868932 322014) 0) (num-test (modulo 7232817686074320060728552759760 11307940) 0) (num-test (modulo 78400098291720425971762131120 5646921093) 0) (num-test (modulo 345445746644065669842240 19727989065) 1869036660) (num-test (modulo 627854758484491743169777558200 750371721805653) 32673867918264) (num-test (modulo 788233263079483492974876830792850 7170146100) 1202847750) (num-test (modulo 18378856389802641496737518160 6247594493140) 1385698158460) (num-test (modulo 9620902642431357480148667659080 59) 0) (num-test (modulo 16008524600631853118144316000 629) 620) (num-test (modulo 4342138447708715023205684275423920 53041) 5133) (num-test (modulo 2431833161592653384508687244500 47541) 0) (num-test (modulo 39424620224103957589082132160 1671734) 0) (num-test (modulo 652830233576052788654372406432 552231327) 231166602) (num-test (modulo 6892963340916411083970414000 3662431431) 935088876) (num-test (modulo 29102758215190063506219566460000 10565720) 0) (num-test (modulo 21253900104556838003127171970777418412 1182797770) 1026303562) (num-test (modulo 3964268932242030284914943132662620 21244177854110) 13576270590290) (num-test (modulo 6070388091189460078138338240 40809131994181213) 6560348180153677) (num-test (modulo 9685989954133695108793384134000 964113514382876) 108668324726468) (num-test (modulo 56468122001858834917195045500 429400787158167902) 411466139739284938) (num-test (modulo 18843408973202596901221568364900 47) 0) (num-test (modulo 7800980538292163259967028613764250 6) 0) (num-test (modulo 270433907726619219545089642715200 3422) 3132) (num-test (modulo 45771666919597903071546708768 2342359) 1698374) (num-test (modulo 47198294949461301503537593835384892 314502) 130548) (num-test (modulo 3165335901519110207943908102359110 14953473) 10646010) (num-test (modulo 189219585097956261544520863361400 35605794) 0) (num-test (modulo 38532137569034426600955256933810890813 1341358608707) 100754920326) (num-test (modulo 1396277868664090735481380981225896 312520860) 187512516) (num-test (modulo 864038349500762576564773759109700 714136202724) 614489290716) (num-test (modulo 12514185871591242579049167322464 10706997440178) 749897068284) (num-test (modulo 1981802660405609330969478067056636 33312289752) 27681419124) (num-test (modulo 979313401024175219420658240 125278417383795) 92954907481995) (num-test (modulo 4074026154111369481048033354344 29) 0) (num-test (modulo 599666571180604695702511920885005100 129) 0) (num-test (modulo 5703263639326551702474610108800 1978) 0) (num-test (modulo 134137932950214683609064669163440 190619) 115401) (num-test (modulo 344735091370772631136645455600 1048985) 0) (num-test (modulo 6759508339299085316106145385400 4969610) 1763410) (num-test (modulo 700334422308861928135313594400 228529587) 194401350) (num-test (modulo 10277417891211405957191810814198480 2516552038) 1372664748) (num-test (modulo 490099971577877358878082782880 9282588354) 7843699422) (num-test (modulo 1954558750269048828645390249600 5575829490) 2295929790) (num-test (modulo 1360588454560018295496656378989200 7868178296420) 3049105010900) (num-test (modulo 4337552841738910859248770564912480 17722936528737830) 1203686858124400) (num-test (modulo 215913068853045803981566931862756 7009479781500) 1803638466756) (num-test (modulo 44890707654126305940250882318870941900 18329973480720) 7637488950300) (num-test (modulo 28579720891831355496720656680837200 3) 0) (num-test (modulo 29332703209780553199747293473184160 1711) 551) (num-test (modulo 3648979393315349438003046604440000 186) 0) (num-test (modulo 1159760236369472473822068077011807878780 25714) 0) (num-test (modulo 158186359726371025615685433600 31395) 17940) (num-test (modulo 331091450443070201468559735703944 28424) 0) (num-test (modulo 9734443639363161342241553023288200 1961348207) 1708271019) (num-test (modulo 701896612128009033011419603540080 51300) 47880) (num-test (modulo 86169288128517384618860929451245320 5032162527446) 925322642976) (num-test (modulo 64828800524794653881296183831741773624 4645294472) 311380888) (num-test (modulo 49068907706533938991402184550000 268183371225) 262983139650) (num-test (modulo 1708602980304476478496020543612288 4083128544) 131713824) (num-test (modulo 17608179287674151740172985536160 980399424528) 962337263616) (num-test (modulo 43194437079731225735521919644800 178119261126453036) 70796157206439912) (num-test (modulo 817555977437791699707628651571149344 59) 0) (num-test (modulo 19062946261334997559157066059536 533) 287) (num-test (modulo 6533849124840489114353090499099000 598) 130) (num-test (modulo 427663965127849896842400211428345149025 234) 117) (num-test (modulo 352395507261316174741530450071590608 154734) 26418) (num-test (modulo 391579493632653867660919800000 9221565) 1166160) (num-test (modulo 2618798923882923048581401148931738000 681876) 419616) (num-test (modulo 174712575449141140214591110997980800 233260339838) 37341839152) (num-test (modulo 88598141227372995032227898284800 1929763976) 1797148024) (num-test (modulo 210110141308655567793064872567302676320 720390430628) 523536832148) (num-test (modulo 668425085137718599277317523827419000 19898594339442) 17330916357006) (num-test (modulo 89533471731097208414073727453200 4173840860670546) 1611748174428756) (num-test (modulo 113987439157802480362236410675251462620 21548296273949445) 20414175417425790) (num-test (modulo 48129335993995093308894209644253760 1009442888504820) 947047755795120) (num-test (modulo 3497836376962291922989777163497680 138736290091634664) 23686683674181528) (num-test (modulo 11371924962562208722154622794880 3) 0) (num-test (modulo 9451631862008339290824315653784000 703) 171) (num-test (modulo 16869347753325980368094612370435598560 806) 0) (num-test (modulo 4701845646467068759127854100132739552 3198) 504) (num-test (modulo 1029865193584911347147121232800485280 1005771) 24531) (num-test (modulo 10657125216930337802109861408000 2415138) 2210802) (num-test (modulo 14382707743772734802155022983680 247913634) 7969170) (num-test (modulo 60134748581470366378101904574533857248 54828228) 9878960) (num-test (modulo 214830664120540781167218700750596000 505665810) 223433730) (num-test (modulo 48933004118344447687599112101802800 6263883444) 849340128) (num-test (modulo 5498670161558110606435630054129739400 262699548132) 255270333864) (num-test (modulo 35941673649029587182509620977230062500 25622409466332) 7911836749404) (num-test (modulo 1592802602494326390643157055239113248 736377633395508) 260180363298804) (num-test (modulo 4043816553144402557587143272522043028314 5011466158645380) 1781651263267134) (num-test (modulo 7171921165220830707276631005512550 1765284492289500) 1588756043060550) (num-test (modulo 2402189359210218692854826119405968750 23) 22) (num-test (modulo 26149068753160488131648964110990162400 1147) 868) (num-test (modulo 556184059176863945810376239306506311552 4089) 0) (num-test (modulo 67871323087036310486238021899264593800 13395) 0) (num-test (modulo 12750401179065252879838440979200 7177173) 0) (num-test (modulo 278110245000092733617125071646080 17748) 0) (num-test (modulo 13408203364935178481017292708752000 50619404) 13680920) (num-test (modulo 124271828931784534297423756437875067000 8839796595) 1143112215) (num-test (modulo 11893442806922081156953529319100769836176 972789007267) 210492262442) (num-test (modulo 352581052555284857902053030133344488264100 923561430099) 488944286523) (num-test (modulo 6108908012714804315575319947340956346976 31944833628092) 28158060036920) (num-test (modulo 67475643422116264959949054821520228800 22515435540) 8157766500) (num-test (modulo 470601888939348535946408832 5135943991060962937) 4475576385383445628) (num-test (modulo 110759232155568113345545635903016614000 30159198663300) 0) (num-test (modulo 146100914712024458707469587112300146320 26868173101560) 24880219882560) (num-test (modulo 12173192708601511002951184416658091200 466645866900785428350) 288583529752854077950) (num-test (modulo 5784684831478746253226687170890240 13) 0) (num-test (modulo 35042260655085685815432622412891903767500 667) 0) (num-test (modulo 2903871349270676921837488659419545120987500 530) 0) (num-test (modulo 630123969240840167098426767919876491188000 77691) 51794) (num-test (modulo 33192703032132982013024959634241667249800 4684718) 4051648) (num-test (modulo 4731525733734729472809717145544850000 90706055) 0) (num-test (modulo 214011009809686092216200126896120006823232 50400042) 45006552) (num-test (modulo 5854250735296111435541950856160000 24357777002) 2121729090) (num-test (modulo 35348208247612761916374738259136697649608 156806713508) 8948839908) (num-test (modulo 612558317420289618714916924536521515286100 2377007388) 375316956) (num-test (modulo 181857299802925368992522029882739454720 21606337755618) 0) (num-test (modulo 4731635341196946327443020710970699860000 58092526675092) 44387995860156) (num-test (modulo 22081740554432638182773611616166588288192 61419768950540) 49135815160432) (num-test (modulo 125627844706077784535328068665849312000 30482033400) 19356933400) (num-test (modulo 1225504716872819103560254268197955520 510813364186125) 233201076344145) (num-test (modulo 5209185280578468690281136425214396728400 2327880739319250103818) 518788605323339989776) (num-test (modulo 230425011604643097634961294406535254400 31) 0) (num-test (modulo 13222608481676137093434201748083744000 893) 0) (num-test (modulo 13348198818240350339028224064019716678960 651) 117) (num-test (modulo 7236172685650198160266777676385295337308176 23426) 14144) (num-test (modulo 756264162229440667711265021676693350760 28899) 0) (num-test (modulo 40915062421030872924283823601517905600 36345062) 0) (num-test (modulo 1174590526522170015825602834292923520 4991486258) 1554170940) (num-test (modulo 2891892862328155581145450075391651333218020 35138529818) 0) (num-test (modulo 1993335355070485984559797658834121810059400 535644500) 433741400) (num-test (modulo 6324295450641455215591954662726515160 367472693133) 134441229195) (num-test (modulo 6576388154814679090356195121505112000 15901952377630) 3827367890390) (num-test (modulo 117828556355409428513249595788296238400 565992666495795) 106570976318730) (num-test (modulo 592831716700236607285748949860604000 139641978135660) 133123065151440) (num-test (modulo 106766839071170184723986891291602032000 1584924526628112) 785519540106048) (num-test (modulo 21677148858122146832326483307664860804937400 247815827510760) 183567279637600) (num-test (modulo 14079549844487257384278196623697173813600 160967604100961853832) 160644118308938243512) (num-test (modulo 2696480372014145687016224877963234647656980 2219319031453896088860) 1749775073012430835800) (num-test (modulo 13545431257849875145060979241270859310160 29) 0) (num-test (modulo 137485634482479300158725199474868559498162500 329) 188) (num-test (modulo 529252417743761759027305009539254400 3243) 0) (num-test (modulo 133897419738958073238580385894509887148800 330455) 0) (num-test (modulo 3896215507210178905244623173635584334007288624 1005238) 0) (num-test (modulo 17654511984514518592175290794029073043800 1060530) 511980) (num-test (modulo 16470780256339082688310222474503880382858400 913836) 0) (num-test (modulo 57267105834722825210001789897760395576000 2958974018) 2329405078) (num-test (modulo 521977833444747522001426544601807810543216 1066521690) 625031316) (num-test (modulo 1699559962174727325529414216960251941390400 25883611479) 16915574049) (num-test (modulo 10654036597801063717295948399628964800 317449894126222) 116812646389120) (num-test (modulo 381902381115592200811990304316262139150724960 4640335440216) 0) (num-test (modulo 425968526187959807410151867411382902838703889232 1882826315615025) 1191718303295157) (num-test (modulo 174609167728518272531601927200939868792000 1712923655178450) 541648883945400) (num-test (modulo 3325168366561555458817274989681612518000 1699726139891780) 1568977975284720) (num-test (modulo 11429650426242566426919762928176000 7414967839104) 1771142792832) (num-test (modulo 2104794191230056678355480848036599377844400 16946684823025584) 9111120872594400) (num-test (modulo 11894522530167763519415142641640874994880 7) 0) (num-test (modulo 5906329981690378696996009087718418780000 185) 0) (num-test (modulo 3056294774178096513474941936265025440000 658) 0) (num-test (modulo 10491907660880423349353457742257185280 123369) 0) (num-test (modulo 673239479595593149777212259021965839229225628776 15470) 12376) (num-test (modulo 1506608574369860432616005754109397877696 1474070) 1179256) (num-test (modulo 4849814041048623250005708880379694793905000 2172220582) 0) (num-test (modulo 21154344928580705924176101470087564940000 5023204186) 0) (num-test (modulo 346448039376394135288065831861806112294000 776147372) 25037012) (num-test (modulo 2339009760844587560470606952218133142645504 194201967414) 78730527330) (num-test (modulo 2242982161480922111384667548175169152 21419749763490) 17054708275722) (num-test (modulo 4717315265246821759830981157482117120 45609714193992) 45557259088536) (num-test (modulo 16628111321698075419789804224660024289936 4643626415880804) 3203755070835528) (num-test (modulo 115557531507210992033160068979962880 88406536976058378) 13997397131802546) (num-test (modulo 21059511907771200155093927745003762840000 180298981648603620) 88715511648941760) (num-test (modulo 2124921015128697258800067298086064536000 2282525112298516782924) 1050493715522523120240) (num-test (modulo 16015671538624533047089928322348864000 49817926936366875) 31511531988217125) (num-test (modulo 166517667014186289390514558017250969134523800 43413708621878528404068) 4443969735426840626952) (num-test (modulo 2780796292789128359666429021610464935722000 47) 0) (num-test (modulo 21297913114430245153455383503409684916193317960 58) 0) (num-test (modulo 1516745257039775143654568869485529015398000 6293) 0) (num-test (modulo 8447692776411453120390905608381515479808 2030) 518) (num-test (modulo 958876033949638283967045624731391031146081240 9834415) 9667730) (num-test (modulo 4731349833403602529573388098680617532624192 14868) 0) (num-test (modulo 6375001358038970462026761077388061675464000 430513678) 0) (num-test (modulo 254088526608579040642428151389718385042344800 4799428101) 294233472) (num-test (modulo 21140490542258031885408065086507444825621023648 164778747198) 63851269926) (num-test (modulo 34214837305812460226811046733375808000 4312787868) 2681970660) (num-test (modulo 11450197571956515037245443769386989035470896800 75585518430279) 69771247781796) (num-test (modulo 1211397915863796187148880114197307052796506376580 538601201880) 128795939580) (num-test (modulo 5454139401260819402160859765169199667337088 30452838731872) 22996976784800) (num-test (modulo 744935981632690384026127091216926530879171660 1032747922358460) 630836297950320) (num-test (modulo 324574326062026951443376280715122947502400 103751223626207988025) 7552030128655111125) (num-test (modulo 15272163751269260921486082393684080908800 6484309049057400) 4436632507249800) (num-test (modulo 386527546655781220813671331401971490218262720 3481571963427119100) 243571263764902920) (num-test (modulo 3189682029126430413458911948222943640000 6724598925622907976570) 2607219061590696572250) (num-test (modulo 709403542855323660533377490060722241678400 7) 0) (num-test (modulo 139803787314578422635552652090095842837312147438904 123) 0) (num-test (modulo 171985399350431759069945935900956183322827030835560 18241) 0) (num-test (modulo 33090522521924986387051477884789600000 26187) 25578) (num-test (modulo 1733723010009930088165729903139785699319986530 372945) 23805) (num-test (modulo 56408303994570817306318494803635460247582000 5761730) 3307860) (num-test (modulo 25845509336769185412951159262424903513866295760 64371378271) 0) (num-test (modulo 624970361450506104794172455132584603069611058500 108222780) 0) (num-test (modulo 82823962548382643645255524843049561752323600 135325929794) 123023572540) (num-test (modulo 170620453449723034746079844571491973300000 9460614789626) 4845680745906) (num-test (modulo 125144597811313015929871740675462711600000 12764411911636) 5714078712188) (num-test (modulo 257193319319332344553297882967977761077115600 6510126541380) 1111485019260) (num-test (modulo 879624546681838385457288074812140664728758550 10045784120501316) 5303606126868522) (num-test (modulo 18300938860777100857669855248554588369659200 118088077425391892) 94617840861501464) (num-test (modulo 8394780474625841647581984803260010511075000 746584618179400) 91432008031000) (num-test (modulo 146802334713757872619395774222116859916800 718775571956687400) 62390745247132200) (num-test (modulo 240155883351717999820072393833707008014911556000 1350921510529331832) 1096988895768179232) (num-test (modulo 918942437243241528855354123800826649596480 74343962238703160850) 1608809218075839780) (num-test (modulo 1361069299753299783990135442290762165844800 8281085446358585640) 7375208194228544280) (num-test (modulo 1/9223372036854775807 -1/3) -9223372036854775804/27670116110564327421) (num-test (modulo -1/9223372036854775807 1/3) 9223372036854775804/27670116110564327421) (num-test (modulo 9223372036854775807 1/3) 0) (num-test (modulo (/ (expt 3 10)) (/ (expt 2 61))) 1991/136157723851059414171648) (num-test (modulo (/ (expt 3 20)) (/ (expt 2 61))) 487228559/2009994358920301836855410688) (num-test (modulo -2/9223372036854775807 2/3) 18446744073709551608/27670116110564327421) (num-test (modulo 2/9223372036854775807 -2/3) -18446744073709551608/27670116110564327421) (num-test (modulo 57473596068/6659027209 318281039/225058681) 218279130532125402/1498671880400651329) (num-test (modulo 25808688679/9809721694 1855077841/1311738121) 15656443452349049505/12867785902420496974) (num-test (modulo 17026679261/10439860591 4478554083/3166815962) 7164879387815321029/33061117160633553542) (num-test (modulo 480544481373/103768467013 10812186007/7645370045) 308048482161795610512/793348329316760825585) (num-test (modulo 137528045312/217976794617 63018038201/44560482149) 137528045312/217976794617) (num-test (modulo 1591258440050/975675645481 152139002499/107578520350) 22746909008980882960481/104961742282377144038350) (num-test (modulo 6721373040371/1193652440098 367296043199/259717522849) 430386901580727488556473/310012454884916918799202) (num-test (modulo 56850567176297/8573543875303 886731088897/627013566048) 1309091318011705591580273/1343932079730680866628136) (num-test (modulo 176638380405175/18340740190704 5168247530883/3654502875938) 38394278980353599950554679/33513143886879715286440176) (num-test (modulo 551230231989018/83130157078217 12477253282759/8822750406821) 714422652331325234782048966/733436627180932669467318157) (num-test (modulo 1360510821127147/517121682660006 30122754096401/21300003689580) 2233626037506212134611298309/1835782291436657618117489580) (num-test (modulo 5849200401628882/766512153894657 175568277047523/124145519261542) 53275930148683942294955132989/95159049365535186345899381094) (num-test (modulo 15914407453568626/6048967074079039 423859315570607/299713796309065) 2205856429990054302964180188017/1812958885520765991472282188535) (num-test (modulo 25997605614346611/9881527843552324 1023286908188737/723573111879672) 127934269420347558776141264953/105147174292423231311078293496) (num-test (modulo 1528546195606366451/177100989030047175 5964153172084899/4217293152016490) 10878285025401489444908608411504/74688678825176546867355107791575) (num-test (modulo 1991152086194052263/206745572560704147 14398739476117879/10181446324101389) 2411554265852820467970218680028029/2104968949772418231181062860760183) (num-test (modulo 1657796840421716313/630118245525664765 34761632124320657/24580185800219268) 18845015710796719738302110345968279/15488423551129023359673258461692020) (num-test (modulo 30769194397037159797/5464318637170278738 202605639573839043/143263821649299118) 271701765358086704077048080811413961/195709792667626007806640474599388271) (num-test (modulo 63477669249275110720/7354673373747273033 489133282872437279/345869461223138161) 370494072414302426447989361648602678/2543756917250129165517177396348512313) (num-test (modulo 275806591309589148297/36143248623210700400 1180872205318713601/835002744095575440) 9600268203288030825290513354903593/17147563511880433985428780967862600) (num-test (modulo 1e19 10) 0.0) (num-test (modulo .1e20 10) 0.0) (num-test (modulo 1e20 10) 0.0) (num-test (modulo 1e21 10) 0.0) (num-test (modulo 1e19 -1) 0.0) (num-test (modulo 1e19 1) 0.0) (num-test (modulo .1e20 1) 0.0) (num-test (modulo 1e20 1) 0.0) (num-test (modulo 10000000000000000000 1) 0) (num-test (modulo 100000000000000000000 1) 0) (num-test (modulo 10000000000000000000 10) 0) (num-test (modulo 100000000000000000000 10) 0) (test (modulo 1361069299753299783990135442290762165844800+i 8281085446358585640) 'error) )) (test (modulo 123 123 123) 'error) (test (modulo 123) 'error) (test (modulo) 'error) (test (mod 2 0) 'error) (test (modulo 2.3 1.0+0.1i) 'error) (test (modulo 3.0+2.3i 3) 'error) (for-each (lambda (arg) (test (modulo arg nan.0) 'error) (test (modulo nan.0 arg) 'error) (test (modulo arg inf.0) 'error) (test (modulo inf.0 arg) 'error) (test (modulo arg 2) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) (for-each (lambda (arg) (test (modulo 2 arg) 'error) (test (modulo 1/2 arg) 'error) (test (modulo 2.0 arg) 'error) (test (modulo 2+i arg) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) ;; check an optimizer bug (test (let () (define (f x) (modulo x 12)) (f 3/4)) 3/4) ;;; -------------------------------------------------------------------------------- ;;; quotient ;;; -------------------------------------------------------------------------------- (num-test (quotient -0.5 -1) 0) (num-test (quotient -1 -1) 1) (num-test (quotient -1 -10) 0) (num-test (quotient -1 -1234) 0) (num-test (quotient -1 -1234000000) 0) (num-test (quotient -1 -2) 0) (num-test (quotient -1 -3) 0) (num-test (quotient -1 -362880) 0) (num-test (quotient -1 -500029) 0) (num-test (quotient -1 1) -1) (num-test (quotient -1 10) 0) (num-test (quotient -1 1234) 0) (num-test (quotient -1 1234000000) 0) (num-test (quotient -1 2) 0) (num-test (quotient -1 3) 0) (num-test (quotient -1 362880) 0) (num-test (quotient -1 500029) 0) (num-test (quotient -1.5 -2) 0) (num-test (quotient -1.5 2) 0) (num-test (quotient -1/2 -1) 0) (num-test (quotient -1/2 -1.0) 0) (num-test (quotient -10 -1) 10) (num-test (quotient -10 -10) 1) (num-test (quotient -10 -1234) 0) (num-test (quotient -10 -1234000000) 0) (num-test (quotient -10 -2) 5) (num-test (quotient -10 -3) 3) (num-test (quotient -10 -362880) 0) (num-test (quotient -10 -500029) 0) (num-test (quotient -10 1) -10) (num-test (quotient -10 10) -1) (num-test (quotient -10 1234) 0) (num-test (quotient -10 1234000000) 0) (num-test (quotient -10 2) -5) (num-test (quotient -10 3) -3) (num-test (quotient -10 362880) 0) (num-test (quotient -10 500029) 0) (num-test (quotient -1234 -1) 1234) (num-test (quotient -1234 -10) 123) (num-test (quotient -1234 -1234) 1) (num-test (quotient -1234 -1234000000) 0) (num-test (quotient -1234 -2) 617) (num-test (quotient -1234 -3) 411) (num-test (quotient -1234 -362880) 0) (num-test (quotient -1234 -500029) 0) (num-test (quotient -1234 1) -1234) (num-test (quotient -1234 10) -123) (num-test (quotient -1234 1234) -1) (num-test (quotient -1234 1234000000) 0) (num-test (quotient -1234 2) -617) (num-test (quotient -1234 3) -411) (num-test (quotient -1234 362880) 0) (num-test (quotient -1234 500029) 0) (num-test (quotient -1234000000 -1) 1234000000) (num-test (quotient -1234000000 -10) 123400000) (num-test (quotient -1234000000 -1234) 1000000) (num-test (quotient -1234000000 -1234000000) 1) (num-test (quotient -1234000000 -2) 617000000) (num-test (quotient -1234000000 -3) 411333333) (num-test (quotient -1234000000 -362880) 3400) (num-test (quotient -1234000000 -500029) 2467) (num-test (quotient -1234000000 1) -1234000000) (num-test (quotient -1234000000 10) -123400000) (num-test (quotient -1234000000 1234) -1000000) (num-test (quotient -1234000000 1234000000) -1) (num-test (quotient -1234000000 2) -617000000) (num-test (quotient -1234000000 3) -411333333) (num-test (quotient -1234000000 362880) -3400) (num-test (quotient -1234000000 500029) -2467) (num-test (quotient -2 -1) 2) (num-test (quotient -2 -10) 0) (num-test (quotient -2 -1234) 0) (num-test (quotient -2 -1234000000) 0) (num-test (quotient -2 -2) 1) (num-test (quotient -2 -3) 0) (num-test (quotient -2 -362880) 0) (num-test (quotient -2 -500029) 0) (num-test (quotient -2 1) -2) (num-test (quotient -2 10) 0) (num-test (quotient -2 1234) 0) (num-test (quotient -2 1234000000) 0) (num-test (quotient -2 2) -1) (num-test (quotient -2 3) 0) (num-test (quotient -2 362880) 0) (num-test (quotient -2 500029) 0) (num-test (quotient -3 -1) 3) (num-test (quotient -3 -10) 0) (num-test (quotient -3 -1234) 0) (num-test (quotient -3 -1234000000) 0) (num-test (quotient -3 -2) 1) (num-test (quotient -3 -3) 1) (num-test (quotient -3 -362880) 0) (num-test (quotient -3 -500029) 0) (num-test (quotient -3 1) -3) (num-test (quotient -3 10) 0) (num-test (quotient -3 1234) 0) (num-test (quotient -3 1234000000) 0) (num-test (quotient -3 2) -1) (num-test (quotient -3 3) -1) (num-test (quotient -3 362880) 0) (num-test (quotient -3 500029) 0) (num-test (quotient -3.1 -2.0) 1) (num-test (quotient -3.1 2.0) -1) (num-test (quotient -3.1 2.5) -1) (num-test (quotient -3/2 -2) 0) (num-test (quotient -3/2 2) 0) (num-test (quotient -35 -7) 5) (num-test (quotient -35 7) -5) (num-test (quotient -362880 -1) 362880) (num-test (quotient -362880 -10) 36288) (num-test (quotient -362880 -1234) 294) (num-test (quotient -362880 -1234000000) 0) (num-test (quotient -362880 -2) 181440) (num-test (quotient -362880 -3) 120960) (num-test (quotient -362880 -362880) 1) (num-test (quotient -362880 -500029) 0) (num-test (quotient -362880 1) -362880) (num-test (quotient -362880 10) -36288) (num-test (quotient -362880 1234) -294) (num-test (quotient -362880 1234000000) 0) (num-test (quotient -362880 2) -181440) (num-test (quotient -362880 3) -120960) (num-test (quotient -362880 362880) -1) (num-test (quotient -362880 500029) 0) (num-test (quotient -500029 -1) 500029) (num-test (quotient -500029 -10) 50002) (num-test (quotient -500029 -1234) 405) (num-test (quotient -500029 -1234000000) 0) (num-test (quotient -500029 -2) 250014) (num-test (quotient -500029 -3) 166676) (num-test (quotient -500029 -362880) 1) (num-test (quotient -500029 -500029) 1) (num-test (quotient -500029 1) -500029) (num-test (quotient -500029 10) -50002) (num-test (quotient -500029 1234) -405) (num-test (quotient -500029 1234000000) 0) (num-test (quotient -500029 2) -250014) (num-test (quotient -500029 3) -166676) (num-test (quotient -500029 362880) -1) (num-test (quotient -500029 500029) -1) (num-test (quotient 0 -1) 0) (num-test (quotient 0 -1) 0) (num-test (quotient 0 -10) 0) (num-test (quotient 0 -10) 0) (num-test (quotient 0 -1234) 0) (num-test (quotient 0 -1234) 0) (num-test (quotient 0 -1234000000) 0) (num-test (quotient 0 -1234000000) 0) (num-test (quotient 0 -2) 0) (num-test (quotient 0 -2) 0) (num-test (quotient 0 -3) 0) (num-test (quotient 0 -3) 0) (num-test (quotient 0 -362880) 0) (num-test (quotient 0 -362880) 0) (num-test (quotient 0 -500029) 0) (num-test (quotient 0 -500029) 0) (num-test (quotient 0 1) 0) (num-test (quotient 0 1) 0) (num-test (quotient 0 10) 0) (num-test (quotient 0 10) 0) (num-test (quotient 0 1234) 0) (num-test (quotient 0 1234) 0) (num-test (quotient 0 1234000000) 0) (num-test (quotient 0 1234000000) 0) (num-test (quotient 0 2) 0) (num-test (quotient 0 2) 0) (num-test (quotient 0 3) 0) (num-test (quotient 0 3) 0) (num-test (quotient 0 362880) 0) (num-test (quotient 0 362880) 0) (num-test (quotient 0 500029) 0) (num-test (quotient 0 500029) 0) (num-test (quotient 0.5 -2) 0) (num-test (quotient 0.5 -2.0) 0) (num-test (quotient 0.5 2.0) 0) (num-test (quotient 1 -1) -1) (num-test (quotient 1 -10) 0) (num-test (quotient 1 -1234) 0) (num-test (quotient 1 -1234000000) 0) (num-test (quotient 1 -2) 0) (num-test (quotient 1 -3) 0) (num-test (quotient 1 -362880) 0) (num-test (quotient 1 -4) 0) (num-test (quotient 1 -500029) 0) (num-test (quotient 1 1) 1) (num-test (quotient 1 10) 0) (num-test (quotient 1 1234) 0) (num-test (quotient 1 1234000000) 0) (num-test (quotient 1 2) 0) (num-test (quotient 1 3) 0) (num-test (quotient 1 362880) 0) (num-test (quotient 1 500029) 0) (num-test (quotient 1.5 1/3) 4) (num-test (quotient 1.5 1/4) 6) (num-test (quotient 1/2 -2) 0) (num-test (quotient 1/2 2) 0) (num-test (quotient 1/9223372036854775807 1/3) 0) (num-test (quotient 10 -1) -10) (num-test (quotient 10 -10) -1) (num-test (quotient 10 -1234) 0) (num-test (quotient 10 -1234000000) 0) (num-test (quotient 10 -2) -5) (num-test (quotient 10 -3) -3) (num-test (quotient 10 -362880) 0) (num-test (quotient 10 -500029) 0) (num-test (quotient 10 1) 10) (num-test (quotient 10 10) 1) (num-test (quotient 10 1234) 0) (num-test (quotient 10 1234000000) 0) (num-test (quotient 10 2) 5) (num-test (quotient 10 3) 3) (num-test (quotient 10 362880) 0) (num-test (quotient 10 500029) 0) (num-test (quotient 11/9223372036854775807 3/9223372036854775807) 3) (num-test (quotient 1234 -1) -1234) (num-test (quotient 1234 -10) -123) (num-test (quotient 1234 -1234) -1) (num-test (quotient 1234 -1234000000) 0) (num-test (quotient 1234 -2) -617) (num-test (quotient 1234 -3) -411) (num-test (quotient 1234 -362880) 0) (num-test (quotient 1234 -500029) 0) (num-test (quotient 1234 1) 1234) (num-test (quotient 1234 10) 123) (num-test (quotient 1234 1234) 1) (num-test (quotient 1234 1234000000) 0) (num-test (quotient 1234 2) 617) (num-test (quotient 1234 3) 411) (num-test (quotient 1234 362880) 0) (num-test (quotient 1234 500029) 0) (num-test (quotient 1234000000 -1) -1234000000) (num-test (quotient 1234000000 -10) -123400000) (num-test (quotient 1234000000 -1234) -1000000) (num-test (quotient 1234000000 -1234000000) -1) (num-test (quotient 1234000000 -2) -617000000) (num-test (quotient 1234000000 -3) -411333333) (num-test (quotient 1234000000 -362880) -3400) (num-test (quotient 1234000000 -500029) -2467) (num-test (quotient 1234000000 1) 1234000000) (num-test (quotient 1234000000 10) 123400000) (num-test (quotient 1234000000 1234) 1000000) (num-test (quotient 1234000000 1234000000) 1) (num-test (quotient 1234000000 2) 617000000) (num-test (quotient 1234000000 3) 411333333) (num-test (quotient 1234000000 362880) 3400) (num-test (quotient 1234000000 500029) 2467) (num-test (quotient 19439282 4409.5) 4408) (num-test (quotient 2 -1) -2) (num-test (quotient 2 -10) 0) (num-test (quotient 2 -1234) 0) (num-test (quotient 2 -1234000000) 0) (num-test (quotient 2 -2) -1) (num-test (quotient 2 -3) 0) (num-test (quotient 2 -362880) 0) (num-test (quotient 2 -500029) 0) (num-test (quotient 2 1) 2) (num-test (quotient 2 10) 0) (num-test (quotient 2 1234) 0) (num-test (quotient 2 1234000000) 0) (num-test (quotient 2 2) 1) (num-test (quotient 2 3) 0) (num-test (quotient 2 362880) 0) (num-test (quotient 2 500029) 0) (num-test (quotient 3 -1) -3) (num-test (quotient 3 -10) 0) (num-test (quotient 3 -1234) 0) (num-test (quotient 3 -1234000000) 0) (num-test (quotient 3 -2) -1) (num-test (quotient 3 -3) -1) (num-test (quotient 3 -362880) 0) (num-test (quotient 3 -500029) 0) (num-test (quotient 3 1) 3) (num-test (quotient 3 10) 0) (num-test (quotient 3 1234) 0) (num-test (quotient 3 1234000000) 0) (num-test (quotient 3 2) 1) (num-test (quotient 3 2.5) 1) (num-test (quotient 3 3) 1) (num-test (quotient 3 362880) 0) (num-test (quotient 3 500029) 0) (num-test (quotient 3.1 -2.0) -1) (num-test (quotient 3.1 2) 1) (num-test (quotient 3.1 2.0) 1) (num-test (quotient 3/2 1/3) 4) (num-test (quotient 3/2 1/4) 6) (num-test (quotient 3/2 3/10) 5) (num-test (quotient 3/9223372036854775807 -2/9223372036854775807) -1) (num-test (quotient 3/9223372036854775807 1/9223372036854775807) 3) (num-test (quotient 35 -7) -5) (num-test (quotient 35 7) 5 ) (num-test (quotient 362880 -1) -362880) (num-test (quotient 362880 -10) -36288) (num-test (quotient 362880 -1234) -294) (num-test (quotient 362880 -1234000000) 0) (num-test (quotient 362880 -2) -181440) (num-test (quotient 362880 -3) -120960) (num-test (quotient 362880 -362880) -1) (num-test (quotient 362880 -500029) 0) (num-test (quotient 362880 1) 362880) (num-test (quotient 362880 10) 36288) (num-test (quotient 362880 1234) 294) (num-test (quotient 362880 1234000000) 0) (num-test (quotient 362880 2) 181440) (num-test (quotient 362880 3) 120960) (num-test (quotient 362880 362880) 1) (num-test (quotient 362880 500029) 0) (num-test (quotient 500029 -1) -500029) (num-test (quotient 500029 -10) -50002) (num-test (quotient 500029 -1234) -405) (num-test (quotient 500029 -1234000000) 0) (num-test (quotient 500029 -2) -250014) (num-test (quotient 500029 -3) -166676) (num-test (quotient 500029 -362880) -1) (num-test (quotient 500029 -500029) -1) (num-test (quotient 500029 1) 500029) (num-test (quotient 500029 10) 50002) (num-test (quotient 500029 1234) 405) (num-test (quotient 500029 1234000000) 0) (num-test (quotient 500029 2) 250014) (num-test (quotient 500029 3) 166676) (num-test (quotient 500029 362880) 1) (num-test (quotient 500029 500029) 1) (num-test (quotient 512/1350851717672992089 512/4052555153018976267) 3) (num-test (quotient 9223372036854775 1/3) 27670116110564325) (num-test (quotient 9223372036854775807/2 9223372036854775807/8) 4) (num-test (quotient 9223372036854775807/8 9223372036854775807/2) 0) (num-test (quotient -9223372036854775808 -9223372036854775808) 1) (num-test (quotient 1.110223024625156799999999999999999999997E-16 -9223372036854775808) 0) (num-test (quotient 5.551115123125783999999999999999999999984E-17 1.110223024625156799999999999999999999997E-16) 0) (num-test (quotient 9223372036854775807 -9223372036854775808) 0) (num-test (quotient 9223372036854775807 9223372036854775807) 1) (if (not with-bignums) (test (quotient most-negative-fixnum -1) 'error) (num-test (quotient most-negative-fixnum -1) 9223372036854775808)) (num-test (quotient 3 1.5) 2) (num-test (quotient 3 1.75) 1) (num-test (quotient pi 1) 3) (num-test (quotient pi 1.5) 2) (num-test (quotient pi 1.6) 1) (num-test (quotient pi 3.0) 1) (num-test (quotient pi 4.0) 0) (num-test (quotient 0.0 1) 0) (num-test (quotient 0.0 2) 0) (num-test (quotient 0.0 3) 0) (num-test (quotient 0.0 4) 0) (num-test (quotient 0.0 pi) 0) (num-test (quotient 0.0 2.5) 0) (num-test (quotient 0.0 4.0) 0) (num-test (quotient 0.0 1000.1) 0) (num-test (quotient pi 1) 3) (num-test (quotient pi 2) 1) (num-test (quotient pi 3) 1) (num-test (quotient pi 4) 0) (num-test (quotient pi pi) 1) (num-test (quotient pi 2.5) 1) (num-test (quotient pi 4.0) 0) (num-test (quotient pi 1000.1) 0) (num-test (quotient 1.5 1) 1) (num-test (quotient 1.5 2) 0) (num-test (quotient 1.5 3) 0) (num-test (quotient 1.5 4) 0) (num-test (quotient 1.5 pi) 0) (num-test (quotient 1.5 2.5) 0) (num-test (quotient 1.5 4.0) 0) (num-test (quotient 1.5 1000.1) 0) (num-test (quotient -1.5 1) -1) (num-test (quotient -1.5 2) 0) (num-test (quotient -1.5 3) 0) (num-test (quotient -1.5 4) 0) (num-test (quotient -1.5 pi) 0) (num-test (quotient -1.5 2.5) 0) (num-test (quotient -1.5 4.0) 0) (num-test (quotient -1.5 1000.1) 0) (num-test (quotient 3.0 1) 3) (num-test (quotient 3.0 2) 1) (num-test (quotient 3.0 3) 1) (num-test (quotient 3.0 4) 0) (num-test (quotient 3.0 pi) 0) (num-test (quotient 3.0 2.5) 1) (num-test (quotient 3.0 4.0) 0) (num-test (quotient 3.0 1000.1) 0) (num-test (quotient 110.123 1) 110) (num-test (quotient 110.123 2) 55) (num-test (quotient 110.123 3) 36) (num-test (quotient 110.123 4) 27) (num-test (quotient 110.123 pi) 35) (num-test (quotient 110.123 2.5) 44) (num-test (quotient 110.123 4.0) 27) (num-test (quotient 110.123 1000.1) 0) (num-test (quotient 1e+18 8) 125000000000000000) (num-test (quotient 1/9223372036854775807 -1/9223372036854775807) -1) (num-test (quotient -4611686018427387904 1/2) -9223372036854775808) (test (= (quotient (* 99/70 99/70) 2) (quotient (* 577/408 577/408) 2)) #t) (test (= (quotient 2.0 (* 99/70 99/70)) (quotient (* 577/408 577/408) 2.0)) #f) (test (= (quotient 99/70 577/408) (floor (/ 99/70 577/408))) #t) (test (= (quotient (* 577/408 577/408) 2) (quotient (* 1393/985 1393/985) 2)) #f) (test (= (quotient 2.0 (* 577/408 577/408)) (quotient (* 1393/985 1393/985) 2.0)) #t) (test (= (quotient 577/408 1393/985) (floor (/ 577/408 1393/985))) #t) (test (= (quotient (* 3363/2378 3363/2378) 2) (quotient (* 19601/13860 19601/13860) 2)) #t) (test (= (quotient 2.0 (* 3363/2378 3363/2378)) (quotient (* 19601/13860 19601/13860) 2.0)) #f) (test (= (quotient 3363/2378 19601/13860) (floor (/ 3363/2378 19601/13860))) #t) (test (= (quotient (* 47321/33461 47321/33461) 2) (quotient (* 114243/80782 114243/80782) 2)) #f) (test (= (quotient 2.0 (* 47321/33461 47321/33461)) (quotient (* 114243/80782 114243/80782) 2.0)) #t) (test (= (quotient 47321/33461 114243/80782) (floor (/ 47321/33461 114243/80782))) #t) (test (= (quotient (* 275807/195025 275807/195025) 2) (quotient (* 1607521/1136689 1607521/1136689) 2)) #t) (test (= (quotient 2.0 (* 275807/195025 275807/195025)) (quotient (* 1607521/1136689 1607521/1136689) 2.0)) #f) (test (= (quotient 275807/195025 1607521/1136689) (floor (/ 275807/195025 1607521/1136689))) #t) (test (= (quotient (* 3880899/2744210 3880899/2744210) 2) (quotient (* 9369319/6625109 9369319/6625109) 2)) #f) (test (= (quotient 2.0 (* 3880899/2744210 3880899/2744210)) (quotient (* 9369319/6625109 9369319/6625109) 2.0)) #t) (test (= (quotient 3880899/2744210 9369319/6625109) (floor (/ 3880899/2744210 9369319/6625109))) #t) (test (= (quotient (* 54608393/38613965 54608393/38613965) 2) (quotient (* 131836323/93222358 131836323/93222358) 2)) #f) (test (= (quotient 2.0 (* 54608393/38613965 54608393/38613965)) (quotient (* 131836323/93222358 131836323/93222358) 2.0)) #t) (test (= (quotient 54608393/38613965 131836323/93222358) (floor (/ 54608393/38613965 131836323/93222358))) #t) (test (= (quotient (* 131836323/93222358 131836323/93222358) 2) (quotient (* 318281039/225058681 318281039/225058681) 2)) #f) ;(if with-bignums (test (= (quotient 2.0 (* 131836323/93222358 131836323/93222358)) ; this should be 1 I think ; (quotient (* 318281039/225058681 318281039/225058681) 2.0)) #f)) (test (= (quotient 131836323/93222358 318281039/225058681) (floor (/ 131836323/93222358 318281039/225058681))) #t) (if with-bignums (test (= (quotient (* 318281039/225058681 318281039/225058681) 2) (quotient (* 1855077841/1311738121 1855077841/1311738121) 2)) #t)) (if with-bignums (test (= (quotient 2.0 (* 318281039/225058681 318281039/225058681)) (quotient (* 1855077841/1311738121 1855077841/1311738121) 2.0)) #f)) (test (= (quotient 318281039/225058681 1855077841/1311738121) (floor (/ 318281039/225058681 1855077841/1311738121))) #t) (if with-bignums (test (= (quotient (* 1855077841/1311738121 1855077841/1311738121) 2) (quotient (* 4478554083/3166815962 4478554083/3166815962) 2)) #f)) (test (= (quotient 2.0 (* 1855077841/1311738121 1855077841/1311738121)) (quotient (* 4478554083/3166815962 4478554083/3166815962) 2.0)) #t) (test (= (quotient 1855077842/1311738121 4478554083/3166815962) (floor (/ 1855077842/1311738121 4478554083/3166815962))) #t) ;;; there's one really dumb problem here: ;;; (quotient 1e-12 1E-16) -> 9999 ;;; (quotient 1.0000000000000e-12 1E-16) -> 9999 but ;;; (quotient 1.00000000000000e-12 1E-16) -> 10000 ;;; for 1e-14 however, there is no number of zeros that will work, but you can set precision to 1024 ;;; or you can spell it out: (quotient 0.0000000000001 0.00000000000000001) -> 10000 ;;; (quotient 1e+18 3/4) -> 1333333333333333248 ;;; which should be 333 at the end of course ;;; (quotient 1e+15 3/4) -> 1333333333333333 (num-test (quotient 1e16 1e14) 100) (if with-bignums (begin (num-test (quotient 1.00000000000000e-12 1E-16) 10000) (num-test (quotient -1.797693134862315699999999999999999999998E308 -9223372036854775808) 19490628022799995908501125008172039088075481712089442747863503837260448050616338003410135413043522984719682345909025832711116783129727902847513862872544943321023332545672815506523677443663683097294005030046422806743414556504424564204282517830151319186021046775247332737488676655598816722944) (num-test (quotient -9223372036854775808 5.551115123125783999999999999999999999984E-17) -166153499473114445265356059994784304) (num-test (quotient 295147905149568077200 34359738366) 8589934591) (num-test (quotient 696898287454081973170944403677937368733396 1180591620717411303422) 590295810358705651711) (num-test (quotient 1e19 10) 1000000000000000000) (num-test (quotient .1e20 10) 1000000000000000000) (num-test (quotient 1e20 10) 10000000000000000000) (num-test (quotient 1e21 10) 100000000000000000000) (num-test (quotient 1e19 -1) -10000000000000000000) (num-test (quotient 1e19 1) 10000000000000000000) (num-test (quotient .1e20 1) 10000000000000000000) (num-test (quotient 1e20 1) 100000000000000000000) (num-test (quotient 10000000000000000000 1) 10000000000000000000) (num-test (quotient 100000000000000000000 1) 100000000000000000000) (num-test (quotient 10000000000000000000 10) 1000000000000000000) (num-test (quotient 100000000000000000000 10) 10000000000000000000) (num-test (quotient 1 1/9223372036854775807) 9223372036854775807) (num-test (quotient 9223372036854775807 2/3) 13835058055282163710) (test (quotient 1361069299753299783990135442290762165844800+i 8281085446358585640) 'error) (test (quotient 1231231231231231232123 0.0) 'error) (test (quotient 1231231231231231232123 0) 'error) ;; the tests that multiply by 2.0 may be on the edge of the 128 bit default precision (test (= (quotient (* 4478554083/3166815962 4478554083/3166815962) 2) (quotient (* 10812186007/7645370045 10812186007/7645370045) 2)) #f) (test (= (quotient 2.0 (* 4478554083/3166815962 4478554083/3166815962)) (quotient (* 10812186007/7645370045 10812186007/7645370045) 2.0)) #t) (test (= (quotient 4478554083/3166815962 10812186007/7645370045) (floor (/ 4478554083/3166815962 10812186007/7645370045))) #t) (test (= (quotient (* 63018038201/44560482149 63018038201/44560482149) 2) (quotient (* 152139002499/107578520350 152139002499/107578520350) 2)) #f) (test (= (quotient 2.0 (* 63018038201/44560482149 63018038201/44560482149)) (quotient (* 152139002499/107578520350 152139002499/107578520350) 2.0)) #t) (test (= (quotient 63018038201/44560482149 152139002499/107578520350) (floor (/ 63018038201/44560482149 152139002499/107578520350))) #t) (test (= (quotient (* 367296043199/259717522849 367296043199/259717522849) 2) (quotient (* 886731088897/627013566048 886731088897/627013566048) 2)) #f) (test (= (quotient 2.0 (* 367296043199/259717522849 367296043199/259717522849)) (quotient (* 886731088897/627013566048 886731088897/627013566048) 2.0)) #t) (test (= (quotient 367296043199/259717522849 886731088897/627013566048) (floor (/ 367296043199/259717522849 886731088897/627013566048))) #t) (test (= (quotient (* 5168247530883/3654502875938 5168247530883/3654502875938) 2) (quotient (* 12477253282759/8822750406821 12477253282759/8822750406821) 2)) #f) (test (= (quotient 2.0 (* 5168247530883/3654502875938 5168247530883/3654502875938)) (quotient (* 12477253282759/8822750406821 12477253282759/8822750406821) 2.0)) #t) (test (= (quotient 5168247530883/3654502875938 12477253282759/8822750406821) (floor (/ 5168247530883/3654502875938 12477253282759/8822750406821))) #t) (test (= (quotient (* 30122754096401/21300003689580 30122754096401/21300003689580) 2) (quotient (* 175568277047523/124145519261542 175568277047523/124145519261542) 2)) #t) (test (= (quotient 2.0 (* 30122754096401/21300003689580 30122754096401/21300003689580)) (quotient (* 175568277047523/124145519261542 175568277047523/124145519261542) 2.0)) #f) (test (= (quotient 30122754096401/21300003689580 175568277047523/124145519261542) (floor (/ 30122754096401/21300003689580 175568277047523/124145519261542))) #t) (test (= (quotient (* 423859315570607/299713796309065 423859315570607/299713796309065) 2) (quotient (* 1023286908188737/723573111879672 1023286908188737/723573111879672) 2)) #f) (test (= (quotient 423859315570607/299713796309065 1023286908188737/723573111879672) (floor (/ 423859315570607/299713796309065 1023286908188737/723573111879672))) #t) (test (= (quotient (* 1023286908188737/723573111879672 1023286908188737/723573111879672) 2) (quotient (* 5964153172084899/4217293152016490 5964153172084899/4217293152016490) 2)) #t) (test (= (quotient (* 3289910387877251662993/2326317944764069484905 3289910387877251662993/2326317944764069484905) 2) (quotient (* 19175002942688032928599/13558774610046711780701 19175002942688032928599/13558774610046711780701) 2)) #t) (test (= (quotient 3289910387877251662993/2326317944764069484905 19175002942688032928599/13558774610046711780701) (floor (/ 3289910387877251662993/2326317944764069484905 19175002942688032928599/13558774610046711780701))) #t) (test (= (quotient (* 46292552162781456490001/32733777552734744709300 46292552162781456490001/32733777552734744709300) 2) (quotient (* 111760107268250945908601/79026329715516201199301 111760107268250945908601/79026329715516201199301) 2)) #f) (test (= (quotient 46292552162781456490001/32733777552734744709300 111760107268250945908601/79026329715516201199301) (floor (/ 46292552162781456490001/32733777552734744709300 111760107268250945908601/79026329715516201199301))) #t) (test (= (quotient (* 269812766699283348307203/190786436983767147107902 269812766699283348307203/190786436983767147107902) 2) (quotient (* 1572584048032918633353217/1111984844349868137938112 1572584048032918633353217/1111984844349868137938112) 2)) #t) (test (= (quotient 269812766699283348307203/190786436983767147107902 1572584048032918633353217/1111984844349868137938112) (floor (/ 269812766699283348307203/190786436983767147107902 1572584048032918633353217/1111984844349868137938112))) #t) (test (= (quotient (* 1572584048032918633353217/1111984844349868137938112 1572584048032918633353217/1111984844349868137938112) 2) (quotient (* 3796553736732654909229441/2684568892382786771291329 3796553736732654909229441/2684568892382786771291329) 2)) #f) (test (= (quotient 1572584048032918633353217/1111984844349868137938112 3796553736732654909229441/2684568892382786771291329) (floor (/ 1572584048032918633353217/1111984844349868137938112 3796553736732654909229441/2684568892382786771291329))) #t) )) (test (quotient 123 123 123) 'error) (test (quotient 123) 'error) (test (quotient 3 0) 'error) (test (quotient) 'error) (test (quotient 3 1+i) 'error) (test (quotient 3 0.0) 'error) (for-each (lambda (arg) (test (quotient arg nan.0) 'error) (test (quotient nan.0 arg) 'error) (test (quotient arg inf.0) 'error) (test (quotient inf.0 arg) 'error) (test (quotient arg 2) 'error)) (list "hi" () (integer->char 65) #f #t 0+i '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) (for-each (lambda (arg) (test (quotient 2 arg) 'error) (test (quotient 1/2 arg) 'error) (test (quotient 2.0 arg) 'error) (test (quotient 2+i arg) 'error)) (list "hi" () (integer->char 65) #f #t 0 0.0 0+i '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) ;;; -------------------------------------------------------------------------------- ;;; remainder ;;; -------------------------------------------------------------------------------- (num-test (remainder -0.5 -1) -0.5) (num-test (remainder -1 -1) 0) (num-test (remainder -1 -10) -1) (num-test (remainder -1 -1234) -1) (num-test (remainder -1 -1234000000) -1) (num-test (remainder -1 -2) -1) (num-test (remainder -1 -3) -1) (num-test (remainder -1 -362880) -1) (num-test (remainder -1 -500029) -1) (num-test (remainder -1 1) 0) (num-test (remainder -1 10) -1) (num-test (remainder -1 1234) -1) (num-test (remainder -1 1234000000) -1) (num-test (remainder -1 2) -1) (num-test (remainder -1 3) -1) (num-test (remainder -1 362880) -1) (num-test (remainder -1 500029) -1) (num-test (remainder -1.5 -2) -1.5) (num-test (remainder -1.5 2) -1.5) (num-test (remainder -1/2 -1) -1/2) (num-test (remainder -1/2 -1.0) -0.5) (num-test (remainder -10 -1) 0) (num-test (remainder -10 -10) 0) (num-test (remainder -10 -1234) -10) (num-test (remainder -10 -1234000000) -10) (num-test (remainder -10 -2) 0) (num-test (remainder -10 -3) -1) (num-test (remainder -10 -362880) -10) (num-test (remainder -10 -500029) -10) (num-test (remainder -10 1) 0) (num-test (remainder -10 10) 0) (num-test (remainder -10 1234) -10) (num-test (remainder -10 1234000000) -10) (num-test (remainder -10 2) 0) (num-test (remainder -10 3) -1) (num-test (remainder -10 362880) -10) (num-test (remainder -10 500029) -10) (num-test (remainder -1234 -1) 0) (num-test (remainder -1234 -10) -4) (num-test (remainder -1234 -1234) 0) (num-test (remainder -1234 -1234000000) -1234) (num-test (remainder -1234 -2) 0) (num-test (remainder -1234 -3) -1) (num-test (remainder -1234 -362880) -1234) (num-test (remainder -1234 -500029) -1234) (num-test (remainder -1234 1) 0) (num-test (remainder -1234 10) -4) (num-test (remainder -1234 1234) 0) (num-test (remainder -1234 1234000000) -1234) (num-test (remainder -1234 2) 0) (num-test (remainder -1234 3) -1) (num-test (remainder -1234 362880) -1234) (num-test (remainder -1234 500029) -1234) (num-test (remainder -1234000000 -1) 0) (num-test (remainder -1234000000 -10) 0) (num-test (remainder -1234000000 -1234) 0) (num-test (remainder -1234000000 -1234000000) 0) (num-test (remainder -1234000000 -2) 0) (num-test (remainder -1234000000 -3) -1) (num-test (remainder -1234000000 -362880) -208000) (num-test (remainder -1234000000 -500029) -428457) (num-test (remainder -1234000000 1) 0) (num-test (remainder -1234000000 10) 0) (num-test (remainder -1234000000 1234) 0) (num-test (remainder -1234000000 1234000000) 0) (num-test (remainder -1234000000 2) 0) (num-test (remainder -1234000000 3) -1) (num-test (remainder -1234000000 362880) -208000) (num-test (remainder -1234000000 500029) -428457) (num-test (remainder -13 -4) -1) (num-test (remainder -13 4) -1) (num-test (remainder -2 -1) 0) (num-test (remainder -2 -10) -2) (num-test (remainder -2 -1234) -2) (num-test (remainder -2 -1234000000) -2) (num-test (remainder -2 -2) 0) (num-test (remainder -2 -3) -2) (num-test (remainder -2 -362880) -2) (num-test (remainder -2 -500029) -2) (num-test (remainder -2 1) 0) (num-test (remainder -2 10) -2) (num-test (remainder -2 1234) -2) (num-test (remainder -2 1234000000) -2) (num-test (remainder -2 2) 0) (num-test (remainder -2 3) -2) (num-test (remainder -2 362880) -2) (num-test (remainder -2 500029) -2) (num-test (remainder -3 -1) 0) (num-test (remainder -3 -10) -3) (num-test (remainder -3 -1234) -3) (num-test (remainder -3 -1234000000) -3) (num-test (remainder -3 -2) -1) (num-test (remainder -3 -3) 0) (num-test (remainder -3 -362880) -3) (num-test (remainder -3 -500029) -3) (num-test (remainder -3 1) 0) (num-test (remainder -3 10) -3) (num-test (remainder -3 1234) -3) (num-test (remainder -3 1234000000) -3) (num-test (remainder -3 2) -1) (num-test (remainder -3 3) 0) (num-test (remainder -3 362880) -3) (num-test (remainder -3 500029) -3) (num-test (remainder -3.1 -2.0) -1.1) (num-test (remainder -3.1 2.0) -1.1) (num-test (remainder -3.1 2.5) -0.6) (num-test (remainder -3/2 -2) -3/2) (num-test (remainder -3/2 2) -3/2) (num-test (remainder -362880 -1) 0) (num-test (remainder -362880 -10) 0) (num-test (remainder -362880 -1234) -84) (num-test (remainder -362880 -1234000000) -362880) (num-test (remainder -362880 -2) 0) (num-test (remainder -362880 -3) 0) (num-test (remainder -362880 -362880) 0) (num-test (remainder -362880 -500029) -362880) (num-test (remainder -362880 1) 0) (num-test (remainder -362880 10) 0) (num-test (remainder -362880 1234) -84) (num-test (remainder -362880 1234000000) -362880) (num-test (remainder -362880 2) 0) (num-test (remainder -362880 3) 0) (num-test (remainder -362880 362880) 0) (num-test (remainder -362880 500029) -362880) (num-test (remainder -500029 -1) 0) (num-test (remainder -500029 -10) -9) (num-test (remainder -500029 -1234) -259) (num-test (remainder -500029 -1234000000) -500029) (num-test (remainder -500029 -2) -1) (num-test (remainder -500029 -3) -1) (num-test (remainder -500029 -362880) -137149) (num-test (remainder -500029 -500029) 0) (num-test (remainder -500029 1) 0) (num-test (remainder -500029 10) -9) (num-test (remainder -500029 1234) -259) (num-test (remainder -500029 1234000000) -500029) (num-test (remainder -500029 2) -1) (num-test (remainder -500029 3) -1) (num-test (remainder -500029 362880) -137149) (num-test (remainder -500029 500029) 0) (num-test (remainder 0 -1) 0) (num-test (remainder 0 -1) 0) (num-test (remainder 0 -10) 0) (num-test (remainder 0 -10) 0) (num-test (remainder 0 -1234) 0) (num-test (remainder 0 -1234) 0) (num-test (remainder 0 -1234000000) 0) (num-test (remainder 0 -1234000000) 0) (num-test (remainder 0 -2) 0) (num-test (remainder 0 -2) 0) (num-test (remainder 0 -3) 0) (num-test (remainder 0 -3) 0) (num-test (remainder 0 -362880) 0) (num-test (remainder 0 -362880) 0) (num-test (remainder 0 -500029) 0) (num-test (remainder 0 -500029) 0) (num-test (remainder 0 1) 0) (num-test (remainder 0 1) 0) (num-test (remainder 0 10) 0) (num-test (remainder 0 10) 0) (num-test (remainder 0 1234) 0) (num-test (remainder 0 1234) 0) (num-test (remainder 0 1234000000) 0) (num-test (remainder 0 1234000000) 0) (num-test (remainder 0 2) 0) (num-test (remainder 0 2) 0) (num-test (remainder 0 3) 0) (num-test (remainder 0 3) 0) (num-test (remainder 0 362880) 0) (num-test (remainder 0 362880) 0) (num-test (remainder 0 500029) 0) (num-test (remainder 0 500029) 0) (num-test (remainder 0.5 -2) 0.5) (num-test (remainder 0.5 -2.0) 0.5) (num-test (remainder 0.5 2.0) 0.5) (num-test (remainder 1 -1) 0) (num-test (remainder 1 -10) 1) (num-test (remainder 1 -1234) 1) (num-test (remainder 1 -1234000000) 1) (num-test (remainder 1 -2) 1) (num-test (remainder 1 -3) 1) (num-test (remainder 1 -362880) 1) (num-test (remainder 1 -4) 1) (num-test (remainder 1 -500029) 1) (num-test (remainder 1 1) 0) (num-test (remainder 1 10) 1) (num-test (remainder 1 1234) 1) (num-test (remainder 1 1234000000) 1) (num-test (remainder 1 2) 1) (num-test (remainder 1 3) 1) (num-test (remainder 1 362880) 1) (num-test (remainder 1 500029) 1) (num-test (remainder 1.5 1/3) 0.16666666666667) (num-test (remainder 1.5 1/4) 0.0) (num-test (remainder 1/2 -2) 1/2) (num-test (remainder 1/2 2) 1/2) (num-test (remainder 1/9223372036854775807 1/3) 1/9223372036854775807) (num-test (remainder 10 -1) 0) (num-test (remainder 10 -10) 0) (num-test (remainder 10 -1234) 10) (num-test (remainder 10 -1234000000) 10) (num-test (remainder 10 -2) 0) (num-test (remainder 10 -3) 1) (num-test (remainder 10 -362880) 10) (num-test (remainder 10 -500029) 10) (num-test (remainder 10 1) 0) (num-test (remainder 10 10) 0) (num-test (remainder 10 1234) 10) (num-test (remainder 10 1234000000) 10) (num-test (remainder 10 2) 0) (num-test (remainder 10 3) 1) (num-test (remainder 10 362880) 10) (num-test (remainder 10 500029) 10) (num-test (remainder 11/9223372036854775807 3/9223372036854775807) 2/9223372036854775807) (num-test (remainder 1234 -1) 0) (num-test (remainder 1234 -10) 4) (num-test (remainder 1234 -1234) 0) (num-test (remainder 1234 -1234000000) 1234) (num-test (remainder 1234 -2) 0) (num-test (remainder 1234 -3) 1) (num-test (remainder 1234 -362880) 1234) (num-test (remainder 1234 -500029) 1234) (num-test (remainder 1234 1) 0) (num-test (remainder 1234 10) 4) (num-test (remainder 1234 1234) 0) (num-test (remainder 1234 1234000000) 1234) (num-test (remainder 1234 2) 0) (num-test (remainder 1234 3) 1) (num-test (remainder 1234 362880) 1234) (num-test (remainder 1234 500029) 1234) (num-test (remainder 1234000000 -1) 0) (num-test (remainder 1234000000 -10) 0) (num-test (remainder 1234000000 -1234) 0) (num-test (remainder 1234000000 -1234000000) 0) (num-test (remainder 1234000000 -2) 0) (num-test (remainder 1234000000 -3) 1) (num-test (remainder 1234000000 -362880) 208000) (num-test (remainder 1234000000 -500029) 428457) (num-test (remainder 1234000000 1) 0) (num-test (remainder 1234000000 10) 0) (num-test (remainder 1234000000 1234) 0) (num-test (remainder 1234000000 1234000000) 0) (num-test (remainder 1234000000 2) 0) (num-test (remainder 1234000000 3) 1) (num-test (remainder 1234000000 362880) 208000) (num-test (remainder 1234000000 500029) 428457) (num-test (remainder 13 -4) 1) (num-test (remainder 13 4) 1) (num-test (remainder 19439282 4409.5) 2206.0) (num-test (remainder 2 -1) 0) (num-test (remainder 2 -10) 2) (num-test (remainder 2 -1234) 2) (num-test (remainder 2 -1234000000) 2) (num-test (remainder 2 -2) 0) (num-test (remainder 2 -3) 2) (num-test (remainder 2 -362880) 2) (num-test (remainder 2 -500029) 2) (num-test (remainder 2 1) 0) (num-test (remainder 2 10) 2) (num-test (remainder 2 1234) 2) (num-test (remainder 2 1234000000) 2) (num-test (remainder 2 2) 0) (num-test (remainder 2 3) 2) (num-test (remainder 2 362880) 2) (num-test (remainder 2 500029) 2) (num-test (remainder 3 -1) 0) (num-test (remainder 3 -10) 3) (num-test (remainder 3 -1234) 3) (num-test (remainder 3 -1234000000) 3) (num-test (remainder 3 -2) 1) (num-test (remainder 3 -3) 0) (num-test (remainder 3 -362880) 3) (num-test (remainder 3 -500029) 3) (num-test (remainder 3 1) 0) (num-test (remainder 3 10) 3) (num-test (remainder 3 1234) 3) (num-test (remainder 3 1234000000) 3) (num-test (remainder 3 2) 1) (num-test (remainder 3 2.5) 0.5) (num-test (remainder 3 3) 0) (num-test (remainder 3 362880) 3) (num-test (remainder 3 500029) 3) (num-test (remainder 3.1 -2.0) 1.1) (num-test (remainder 3.1 2) 1.1) (num-test (remainder 3.1 2.0) 1.1) (num-test (remainder 3/2 1/3) 1/6) (num-test (remainder 3/2 1/4) 0) (num-test (remainder 3/2 3/10) 0) (num-test (remainder 362880 -1) 0) (num-test (remainder 362880 -10) 0) (num-test (remainder 362880 -1234) 84) (num-test (remainder 362880 -1234000000) 362880) (num-test (remainder 362880 -2) 0) (num-test (remainder 362880 -3) 0) (num-test (remainder 362880 -362880) 0) (num-test (remainder 362880 -500029) 362880) (num-test (remainder 362880 1) 0) (num-test (remainder 362880 10) 0) (num-test (remainder 362880 1234) 84) (num-test (remainder 362880 1234000000) 362880) (num-test (remainder 362880 2) 0) (num-test (remainder 362880 3) 0) (num-test (remainder 362880 362880) 0) (num-test (remainder 362880 500029) 362880) (num-test (remainder 500029 -1) 0) (num-test (remainder 500029 -10) 9) (num-test (remainder 500029 -1234) 259) (num-test (remainder 500029 -1234000000) 500029) (num-test (remainder 500029 -2) 1) (num-test (remainder 500029 -3) 1) (num-test (remainder 500029 -362880) 137149) (num-test (remainder 500029 -500029) 0) (num-test (remainder 500029 1) 0) (num-test (remainder 500029 10) 9) (num-test (remainder 500029 1234) 259) (num-test (remainder 500029 1234000000) 500029) (num-test (remainder 500029 2) 1) (num-test (remainder 500029 3) 1) (num-test (remainder 500029 362880) 137149) (num-test (remainder 500029 500029) 0) (num-test (remainder -9223372036854775808 -9223372036854775808) 0) (num-test (remainder 1.110223024625156799999999999999999999997E-16 -9223372036854775808) 1.110223024625156799999999999999999999997E-16) (num-test (remainder 5.551115123125783999999999999999999999984E-17 1.110223024625156799999999999999999999997E-16) 5.551115123125783999999999999999999999984E-17) (num-test (remainder 9223372036854775807 -9223372036854775808) 9223372036854775807) (num-test (remainder 9223372036854775807 9223372036854775807) 0) (num-test (remainder 0.0 1) 0.0) (num-test (remainder 0.0 2) 0.0) (num-test (remainder 0.0 3) 0.0) (num-test (remainder 0.0 4) 0.0) (num-test (remainder 0.0 pi) 0.0) (num-test (remainder 0.0 2.5) 0.0) (num-test (remainder 0.0 4.0) 0.0) (num-test (remainder 0.0 1000.1) 0.0) (num-test (remainder pi 1) 1.415926535897932384626433832795028841953E-1) (num-test (remainder pi 2) 1.141592653589793238462643383279502884195E0) (num-test (remainder pi 3) 1.415926535897932384626433832795028841953E-1) (num-test (remainder pi 4) pi) (num-test (remainder pi pi) 0.0) (num-test (remainder pi 2.5) 6.415926535897932384626433832795028841953E-1) (num-test (remainder pi 4.0) pi) (num-test (remainder pi 1000.1) pi) (num-test (remainder 1.5 1) 0.5) (num-test (remainder 1.5 2) 1.5) (num-test (remainder 1.5 3) 1.5) (num-test (remainder 1.5 4) 1.5) (num-test (remainder 1.5 pi) 1.500E0) (num-test (remainder 1.5 2.5) 1.5) (num-test (remainder 1.5 4.0) 1.5) (num-test (remainder 1.5 1000.1) 1.5) (num-test (remainder -1.5 1) -0.5) (num-test (remainder -1.5 2) -1.5) (num-test (remainder -1.5 3) -1.5) (num-test (remainder -1.5 4) -1.5) (num-test (remainder -1.5 pi) -1.50E0) (num-test (remainder -1.5 2.5) -1.5) (num-test (remainder -1.5 4.0) -1.5) (num-test (remainder -1.5 1000.1) -1.5) (num-test (remainder 3.0 1) 0.0) (num-test (remainder 3.0 2) 1.0) (num-test (remainder 3.0 3) 0.0) (num-test (remainder 3.0 4) 3.0) (num-test (remainder 3.0 pi) 3.000E0) (num-test (remainder 3.0 2.5) 0.5) (num-test (remainder 3.0 4.0) 3.0) (num-test (remainder 3.0 1000.1) 3.0) (num-test (remainder 110.123 1) 0.123) (num-test (remainder 110.123 2) 0.123) (num-test (remainder 110.123 3) 2.123) (num-test (remainder 110.123 4) 2.123) (num-test (remainder 110.123 pi) 1.672571243572413149678281714746183675874E-1) (num-test (remainder 110.123 2.5) 0.123) (num-test (remainder 110.123 4.0) 2.123) (num-test (remainder 110.123 1000.1) 110.123) (num-test (remainder 3/2 most-negative-fixnum) 3/2) (num-test (remainder 3/2 most-positive-fixnum) 3/2) (num-test (remainder most-negative-fixnum -1) 0) (test (= (remainder (* 577/408 577/408) 2) (remainder (* 1393/985 1393/985) 2)) #f) (test (= (remainder 2.0 (* 577/408 577/408)) (remainder (* 1393/985 1393/985) 2.0)) #f) (test (= (remainder 577/408 1393/985) (floor (/ 577/408 1393/985))) #f) (test (= (remainder (* 3363/2378 3363/2378) 2) (remainder (* 19601/13860 19601/13860) 2)) #f) (test (= (remainder 2.0 (* 47321/33461 47321/33461)) (remainder (* 114243/80782 114243/80782) 2.0)) #f) (test (= (remainder 47321/33461 114243/80782) (floor (/ 47321/33461 114243/80782))) #f) (test (= (remainder (* 275807/195025 275807/195025) 2) (remainder (* 1607521/1136689 1607521/1136689) 2)) #f) (test (= (remainder 2.0 (* 275807/195025 275807/195025)) (remainder (* 1607521/1136689 1607521/1136689) 2.0)) #f) (test (= (remainder 275807/195025 1607521/1136689) (floor (/ 275807/195025 1607521/1136689))) #f) (test (= (remainder (* 3880899/2744210 3880899/2744210) 2) (remainder (* 9369319/6625109 9369319/6625109) 2)) #f) (test (= (remainder 2.0 (* 3880899/2744210 3880899/2744210)) (remainder (* 9369319/6625109 9369319/6625109) 2.0)) #f) (test (= (remainder 3880899/2744210 9369319/6625109) (floor (/ 3880899/2744210 9369319/6625109))) #f) (test (= (remainder (* 54608393/38613965 54608393/38613965) 2) (remainder (* 131836323/93222358 131836323/93222358) 2)) #f) (test (= (remainder 2.0 (* 54608393/38613965 54608393/38613965)) (remainder (* 131836323/93222358 131836323/93222358) 2.0)) #f) (test (= (remainder 54608393/38613965 131836323/93222358) (floor (/ 54608393/38613965 131836323/93222358))) #f) (if with-bignums (test (= (remainder (* 318281039/225058681 318281039/225058681) 2) (remainder (* 1855077841/1311738121 1855077841/1311738121) 2)) #f)) (if with-bignums (test (= (remainder 2.0 (* 318281039/225058681 318281039/225058681)) (remainder (* 1855077841/1311738121 1855077841/1311738121) 2.0)) #f)) (if with-bignums (test (= (remainder 318281039/225058681 1855077841/1311738121) (floor (/ 318281039/225058681 1855077841/1311738121))) #f)) (num-test (+ (remainder 23/3 3/2) (* 3/2 (quotient 23/3 3/2))) 23/3) (num-test (+ (remainder 29/8 17/12) (* 17/12 (quotient 29/8 17/12))) 29/8) (num-test (+ (remainder 164/19 41/29) (* 41/29 (quotient 164/19 41/29))) 164/19) (num-test (+ (remainder 725/84 99/70) (* 99/70 (quotient 725/84 99/70))) 725/84) (num-test (+ (remainder 3862/401 577/408) (* 577/408 (quotient 3862/401 577/408))) 3862/401) (num-test (+ (remainder 4881/1054 1393/985) (* 1393/985 (quotient 4881/1054 1393/985))) 4881/1054) (num-test (+ (remainder 53963/20511 3363/2378) (* 3363/2378 (quotient 53963/20511 3363/2378))) 53963/20511) (num-test (+ (remainder 188690/24727 19601/13860) (* 19601/13860 (quotient 188690/24727 19601/13860))) 188690/24727) (num-test (+ (remainder 959536/125743 47321/33461) (* 47321/33461 (quotient 959536/125743 47321/33461))) 959536/125743) (num-test (+ (remainder 2606489/301994 114243/80782) (* 114243/80782 (quotient 2606489/301994 114243/80782))) 2606489/301994) (num-test (+ (remainder 97961303/11350029 275807/195025) (* 275807/195025 (quotient 97961303/11350029 275807/195025))) 97961303/11350029) (num-test (+ (remainder 109303762/16483927 1607521/1136689) (* 1607521/1136689 (quotient 109303762/16483927 1607521/1136689))) 109303762/16483927) (num-test (+ (remainder 27869189/17087915 3880899/2744210) (* 3880899/2744210 (quotient 27869189/17087915 3880899/2744210))) 27869189/17087915) (num-test (+ (remainder 564541319/85137581 9369319/6625109) (* 9369319/6625109 (quotient 564541319/85137581 9369319/6625109))) 564541319/85137581) (num-test (+ (remainder 2351934037/272500658 54608393/38613965) (* 54608393/38613965 (quotient 2351934037/272500658 54608393/38613965))) 2351934037/272500658) (num-test (+ (remainder 1657851173/630138897 131836323/93222358) (* 131836323/93222358 (quotient 1657851173/630138897 131836323/93222358))) 1657851173/630138897) (if with-bignums (begin (num-test (remainder -9223372036854775808 5.551115123125783999999999999999999999984E-17) -2.295798100238055639010781305842101573944E-17) (num-test (remainder 295147905149568077200 34359738366) 21754858894) (num-test (remainder 696898287454081973170944403677937368733396 1180591620717411303422) 314390899110894278354) (num-test (remainder 1e19 10) 0.0) (num-test (remainder .1e20 10) 0.0) (num-test (remainder 1e20 10) 0.0) (num-test (remainder 1e21 10) 0.0) (num-test (remainder 1e19 -1) 0.0) (num-test (remainder 1e19 1) 0.0) (num-test (remainder .1e20 1) 0.0) (num-test (remainder 1e20 1) 0.0) (num-test (remainder 10000000000000000000 1) 0) (num-test (remainder 100000000000000000000 1) 0) (num-test (remainder 10000000000000000000 10) 0) (num-test (remainder 100000000000000000000 10) 0) (num-test (remainder 9223372036854775807 1/3) 0) (num-test (remainder 9223372036854775807 2/3) 1/3) (num-test (remainder 922337203685477580 1/3) 0) (test (remainder 1361069299753299783990135442290762165844800+i 8281085446358585640) 'error) (test (remainder 1231231231231231232123 0.0) 'error) (test (remainder 1231231231231231232123 0) 'error) (test (= (remainder (* 4478554083/3166815962 4478554083/3166815962) 2) (remainder (* 10812186007/7645370045 10812186007/7645370045) 2)) #f) (test (= (remainder 2.0 (* 4478554083/3166815962 4478554083/3166815962)) (remainder (* 10812186007/7645370045 10812186007/7645370045) 2.0)) #f) (test (= (remainder 367296043199/259717522849 886731088897/627013566048) (floor (/ 367296043199/259717522849 886731088897/627013566048))) #f) (test (= (remainder (* 5168247530883/3654502875938 5168247530883/3654502875938) 2) (remainder (* 12477253282759/8822750406821 12477253282759/8822750406821) 2)) #f) (test (= (remainder 2.0 (* 423859315570607/299713796309065 423859315570607/299713796309065)) (remainder (* 1023286908188737/723573111879672 1023286908188737/723573111879672) 2.0)) #f) (test (= (remainder 2.0 (* 34761632124320657/24580185800219268 34761632124320657/24580185800219268)) (remainder (* 202605639573839043/143263821649299118 202605639573839043/143263821649299118) 2.0)) #f) (test (= (remainder 34761632124320657/24580185800219268 202605639573839043/143263821649299118) (floor (/ 34761632124320657/24580185800219268 202605639573839043/143263821649299118))) #f) (test (= (remainder (* 489133282872437279/345869461223138161 489133282872437279/345869461223138161) 2) (remainder (* 1180872205318713601/835002744095575440 1180872205318713601/835002744095575440) 2)) #f) (test (= (remainder (* 2850877693509864481/2015874949414289041 2850877693509864481/2015874949414289041) 2) (remainder (* 16616132878186749607/11749380235262596085 16616132878186749607/11749380235262596085) 2)) #f) (test (= (remainder (* 564459384575477049359/399133058537705128729 564459384575477049359/399133058537705128729) 2) (remainder (* 1362725501650887306817/963592443113182178088 1362725501650887306817/963592443113182178088) 2)) #f) (test (= (remainder 564459384575477049359/399133058537705128729 1362725501650887306817/963592443113182178088) (floor (/ 564459384575477049359/399133058537705128729 1362725501650887306817/963592443113182178088))) #f) (test (= (remainder (* 3289910387877251662993/2326317944764069484905 3289910387877251662993/2326317944764069484905) 2) (remainder (* 19175002942688032928599/13558774610046711780701 19175002942688032928599/13558774610046711780701) 2)) #f) (test (= (remainder (* 46292552162781456490001/32733777552734744709300 46292552162781456490001/32733777552734744709300) 2) (remainder (* 111760107268250945908601/79026329715516201199301 111760107268250945908601/79026329715516201199301) 2)) #f) (test (= (remainder 46292552162781456490001/32733777552734744709300 111760107268250945908601/79026329715516201199301) (floor (/ 46292552162781456490001/32733777552734744709300 111760107268250945908601/79026329715516201199301))) #f) (test (= (remainder (* 269812766699283348307203/190786436983767147107902 269812766699283348307203/190786436983767147107902) 2) (remainder (* 1572584048032918633353217/1111984844349868137938112 1572584048032918633353217/1111984844349868137938112) 2)) #f) (test (= (remainder 269812766699283348307203/190786436983767147107902 1572584048032918633353217/1111984844349868137938112) (floor (/ 269812766699283348307203/190786436983767147107902 1572584048032918633353217/1111984844349868137938112))) #f) (num-test (+ (remainder 37496514441/6659027209 318281039/225058681) (* 318281039/225058681 (quotient 37496514441/6659027209 318281039/225058681))) 37496514441/6659027209) (num-test (+ (remainder 74857297149/9809721694 1855077841/1311738121) (* 1855077841/1311738121 (quotient 74857297149/9809721694 1855077841/1311738121))) 74857297149/9809721694) (num-test (+ (remainder 48346261034/10439860591 4478554083/3166815962) (* 4478554083/3166815962 (quotient 48346261034/10439860591 4478554083/3166815962))) 48346261034/10439860591) (num-test (+ (remainder 584312948386/103768467013 10812186007/7645370045) (* 10812186007/7645370045 (quotient 584312948386/103768467013 10812186007/7645370045))) 584312948386/103768467013) (num-test (+ (remainder 1663365607631/217976794617 63018038201/44560482149) (* 63018038201/44560482149 (quotient 1663365607631/217976794617 63018038201/44560482149))) 1663365607631/217976794617) (num-test (+ (remainder 4518285376493/975675645481 152139002499/107578520350) (* 152139002499/107578520350 (quotient 4518285376493/975675645481 152139002499/107578520350))) 4518285376493/975675645481) (num-test (+ (remainder 10302330360665/1193652440098 367296043199/259717522849) (* 367296043199/259717522849 (quotient 10302330360665/1193652440098 367296043199/259717522849))) 10302330360665/1193652440098) (num-test (+ (remainder 73997654926903/8573543875303 886731088897/627013566048) (* 886731088897/627013566048 (quotient 73997654926903/8573543875303 886731088897/627013566048))) 73997654926903/8573543875303) (num-test (+ (remainder 176638380405175/18340740190704 5168247530883/3654502875938) (* 5168247530883/3654502875938 (quotient 176638380405175/18340740190704 5168247530883/3654502875938))) 176638380405175/18340740190704) (num-test (+ (remainder 468100074910801/83130157078217 12477253282759/8822750406821) (* 12477253282759/8822750406821 (quotient 468100074910801/83130157078217 12477253282759/8822750406821))) 468100074910801/83130157078217) (num-test (+ (remainder 843389138467141/517121682660006 30122754096401/21300003689580) (* 30122754096401/21300003689580 (quotient 843389138467141/517121682660006 30122754096401/21300003689580))) 843389138467141/517121682660006) (num-test (+ (remainder 1250127478260940/766512153894657 175568277047523/124145519261542) (* 175568277047523/124145519261542 (quotient 1250127478260940/766512153894657 175568277047523/124145519261542))) 1250127478260940/766512153894657) (num-test (+ (remainder 21963374527647665/6048967074079039 423859315570607/299713796309065) (* 423859315570607/299713796309065 (quotient 21963374527647665/6048967074079039 423859315570607/299713796309065))) 21963374527647665/6048967074079039) (num-test (+ (remainder 45760661301451259/9881527843552324 1023286908188737/723573111879672) (* 1023286908188737/723573111879672 (quotient 45760661301451259/9881527843552324 1023286908188737/723573111879672))) 45760661301451259/9881527843552324) (num-test (+ (remainder 1528546195606366451/177100989030047175 5964153172084899/4217293152016490) (* 5964153172084899/4217293152016490 (quotient 1528546195606366451/177100989030047175 5964153172084899/4217293152016490))) 1528546195606366451/177100989030047175) (num-test (+ (remainder 543933078269123234/206745572560704147 14398739476117879/10181446324101389) (* 14398739476117879/10181446324101389 (quotient 543933078269123234/206745572560704147 14398739476117879/10181446324101389))) 543933078269123234/206745572560704147) (num-test (+ (remainder 4808388068050040138/630118245525664765 34761632124320657/24580185800219268) (* 34761632124320657/24580185800219268 (quotient 4808388068050040138/630118245525664765 34761632124320657/24580185800219268))) 4808388068050040138/630118245525664765) )) (test (remainder 123 123 123) 'error) (test (remainder 123) 'error) (test (remainder 3 0) 'error) (test (remainder) 'error) (test (remainder 2.3 1.0+0.1i) 'error) (test (remainder 3.0+2.3i 3) 'error) (test (remainder 3 0.0) 'error) (for-each (lambda (arg) (test (remainder arg nan.0) 'error) (test (remainder nan.0 arg) 'error) (test (remainder arg inf.0) 'error) (test (remainder inf.0 arg) 'error) (test (remainder arg 2) 'error)) (list "hi" () (integer->char 65) 0+i #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) (for-each (lambda (arg) (test (remainder 2 arg) 'error) (test (remainder 2.0 arg) 'error) (test (remainder 1/2 arg) 'error) (test (remainder 2+i arg) 'error)) (list "hi" () (integer->char 65) #f #t 0 0+i '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) (if with-bignums (let ((top-exp 60)) (let ((happy #t)) (do ((i 2 (+ i 1))) ((or (not happy) (> i top-exp))) (let* ((val1 (inexact->exact (expt 2 i))) (val2 (+ val1 1)) (mv (modulo val2 2)) (qv (quotient val2 2)) (rv (remainder val2 2))) (if (not (= mv 1)) (begin (set! happy #f) (display "(modulo ") (display val2) (display " 2) = ") (display mv) (display "?") (newline))) (if (not (= qv (/ val1 2))) (begin (set! happy #f) (display "(quotient ") (display val2) (display " 2) = ") (display qv) (display "?") (newline))) (if (not (= rv 1)) (begin (set! happy #f) (display "(remainder ") (display val2) (display " 2) = ") (display rv) (display "?") (newline)))))) (let ((happy #t)) (do ((i 2 (+ i 1))) ((or (not happy) (> i top-exp))) (let* ((val1 (inexact->exact (expt 2 i))) (val2 (/ (+ val1 1) 2)) (mv (modulo val2 2)) (qv (quotient val2 2)) (rv (remainder val2 2))) (if (not (= mv 1/2)) (begin (set! happy #f) (display "(modulo ") (display val2) (display " 2) = ") (display mv) (display "?") (newline))) (if (not (= qv (/ val1 4))) (begin (set! happy #f) (display "(quotient ") (display val2) (display " 2) = ") (display qv) (display "?") (newline))) (if (not (= rv 1/2)) (begin (set! happy #f) (display "(remainder ") (display val2) (display " 2) = ") (display rv) (display "?") (newline)))))))) (if (not with-bignums) (begin ; (test (modulo 1e20 10) 'error) (test (remainder 1e20 10) 'error) (test (quotient 1e20 10) 'error))) ;;; -------------------------------------------------------------------------------- ;;; gcd ;;; -------------------------------------------------------------------------------- (num-test (gcd (* 512 500057) (* 128 500057) (* 2048 500057)) 64007296) (num-test (gcd (- (expt 2 11) 1) (- (expt 2 19) 1)) (- (expt 2 (gcd 11 19)) 1)) (num-test (gcd (- (expt 2 11) 1) (- (expt 2 22) 1)) (- (expt 2 (gcd 11 22)) 1)) (num-test (gcd (- (expt 2 12) 1) (- (expt 2 18) 1)) (- (expt 2 (gcd 12 18)) 1)) (num-test (gcd (- (expt 2 52) 1) (- (expt 2 39) 1)) (- (expt 2 (gcd 52 39)) 1)) (num-test (gcd (numerator 7/9) (denominator 7/9)) 1) (num-test (gcd -1 -1) 1) (num-test (gcd -1 -10) 1) (num-test (gcd -1 -1234) 1) (num-test (gcd -1 -1234000000) 1) (num-test (gcd -1 -2) 1) (num-test (gcd -1 -3) 1) (num-test (gcd -1 -362880) 1) (num-test (gcd -1 -500029) 1) (num-test (gcd -1 0) 1) (num-test (gcd -1 1) 1) (num-test (gcd -1 10) 1) (num-test (gcd -1 1234) 1) (num-test (gcd -1 1234000000) 1) (num-test (gcd -1 2) 1) (num-test (gcd -1 3) 1) (num-test (gcd -1 362880) 1) (num-test (gcd -1 500029) 1) (num-test (gcd -1) 1) (num-test (gcd -10 -1) 1) (num-test (gcd -10 -10) 10) (num-test (gcd -10 -1234) 2) (num-test (gcd -10 -1234000000) 10) (num-test (gcd -10 -2) 2) (num-test (gcd -10 -3) 1) (num-test (gcd -10 -362880) 10) (num-test (gcd -10 -500029) 1) (num-test (gcd -10 0) 10) (num-test (gcd -10 1) 1) (num-test (gcd -10 10) 10) (num-test (gcd -10 1234) 2) (num-test (gcd -10 1234000000) 10) (num-test (gcd -10 2) 2) (num-test (gcd -10 3) 1) (num-test (gcd -10 362880) 10) (num-test (gcd -10 500029) 1) (num-test (gcd -10) 10) (num-test (gcd -1234 -1) 1) (num-test (gcd -1234 -10) 2) (num-test (gcd -1234 -1234) 1234) (num-test (gcd -1234 -1234000000) 1234) (num-test (gcd -1234 -2) 2) (num-test (gcd -1234 -3) 1) (num-test (gcd -1234 -362880) 2) (num-test (gcd -1234 -500029) 1) (num-test (gcd -1234 0) 1234) (num-test (gcd -1234 1) 1) (num-test (gcd -1234 10) 2) (num-test (gcd -1234 1234) 1234) (num-test (gcd -1234 1234000000) 1234) (num-test (gcd -1234 2) 2) (num-test (gcd -1234 3) 1) (num-test (gcd -1234 362880) 2) (num-test (gcd -1234 500029) 1) (num-test (gcd -1234) 1234) (num-test (gcd -1234000000 -1) 1) (num-test (gcd -1234000000 -10) 10) (num-test (gcd -1234000000 -1234) 1234) (num-test (gcd -1234000000 -1234000000) 1234000000) (num-test (gcd -1234000000 -2) 2) (num-test (gcd -1234000000 -3) 1) (num-test (gcd -1234000000 -362880) 640) (num-test (gcd -1234000000 -500029) 1) (num-test (gcd -1234000000 0) 1234000000) (num-test (gcd -1234000000 1) 1) (num-test (gcd -1234000000 10) 10) (num-test (gcd -1234000000 1234) 1234) (num-test (gcd -1234000000 1234000000) 1234000000) (num-test (gcd -1234000000 2) 2) (num-test (gcd -1234000000 3) 1) (num-test (gcd -1234000000 362880) 640) (num-test (gcd -1234000000 500029) 1) (num-test (gcd -1234000000) 1234000000) (num-test (gcd -2 -1) 1) (num-test (gcd -2 -10) 2) (num-test (gcd -2 -1234) 2) (num-test (gcd -2 -1234000000) 2) (num-test (gcd -2 -2) 2) (num-test (gcd -2 -3) 1) (num-test (gcd -2 -362880) 2) (num-test (gcd -2 -500029) 1) (num-test (gcd -2 0) 2) (num-test (gcd -2 1) 1) (num-test (gcd -2 10) 2) (num-test (gcd -2 1234) 2) (num-test (gcd -2 1234000000) 2) (num-test (gcd -2 2) 2) (num-test (gcd -2 3) 1) (num-test (gcd -2 362880) 2) (num-test (gcd -2 500029) 1) (num-test (gcd -2) 2) (num-test (gcd -3 -1) 1) (num-test (gcd -3 -10) 1) (num-test (gcd -3 -1234) 1) (num-test (gcd -3 -1234000000) 1) (num-test (gcd -3 -2) 1) (num-test (gcd -3 -3) 3) (num-test (gcd -3 -362880) 3) (num-test (gcd -3 -500029) 1) (num-test (gcd -3 0) 3) (num-test (gcd -3 1) 1) (num-test (gcd -3 10) 1) (num-test (gcd -3 1234) 1) (num-test (gcd -3 1234000000) 1) (num-test (gcd -3 2) 1) (num-test (gcd -3 3) 3) (num-test (gcd -3 362880) 3) (num-test (gcd -3 500029) 1) (num-test (gcd -3) 3) (num-test (gcd -362880 -1) 1) (num-test (gcd -362880 -10) 10) (num-test (gcd -362880 -1234) 2) (num-test (gcd -362880 -1234000000) 640) (num-test (gcd -362880 -2) 2) (num-test (gcd -362880 -3) 3) (num-test (gcd -362880 -362880) 362880) (num-test (gcd -362880 -500029) 1) (num-test (gcd -362880 0) 362880) (num-test (gcd -362880 0) 362880) (num-test (gcd -362880 1) 1) (num-test (gcd -362880 10) 10) (num-test (gcd -362880 1234) 2) (num-test (gcd -362880 1234000000) 640) (num-test (gcd -362880 2) 2) (num-test (gcd -362880 3) 3) (num-test (gcd -362880 362880) 362880) (num-test (gcd -362880 500029) 1) (num-test (gcd -362880) 362880) (num-test (gcd -4 0) 4 ) (num-test (gcd -500029 -1) 1) (num-test (gcd -500029 -10) 1) (num-test (gcd -500029 -1234) 1) (num-test (gcd -500029 -1234000000) 1) (num-test (gcd -500029 -2) 1) (num-test (gcd -500029 -3) 1) (num-test (gcd -500029 -362880) 1) (num-test (gcd -500029 -500029) 500029) (num-test (gcd -500029 0) 500029) (num-test (gcd -500029 0) 500029) (num-test (gcd -500029 1) 1) (num-test (gcd -500029 10) 1) (num-test (gcd -500029 1234) 1) (num-test (gcd -500029 1234000000) 1) (num-test (gcd -500029 2) 1) (num-test (gcd -500029 3) 1) (num-test (gcd -500029 362880) 1) (num-test (gcd -500029 500029) 500029) (num-test (gcd -500029) 500029) (num-test (gcd 0 -1) 1) (num-test (gcd 0 -10) 10) (num-test (gcd 0 -1234) 1234) (num-test (gcd 0 -1234000000) 1234000000) (num-test (gcd 0 -2) 2) (num-test (gcd 0 -3) 3) (num-test (gcd 0 -362880) 362880) (num-test (gcd 0 -500029) 500029) (num-test (gcd 0 0 0 10) 10) (num-test (gcd 0 0) 0) (num-test (gcd 0 1 -1 362880) 1) (num-test (gcd 0 1) 1) (num-test (gcd 0 10 10 1234) 2) (num-test (gcd 0 10) 10) (num-test (gcd 0 1234 -1234 10) 2) (num-test (gcd 0 1234) 1234) (num-test (gcd 0 1234000000 1234000000 -3) 1) (num-test (gcd 0 1234000000) 1234000000) (num-test (gcd 0 2 2 -500029) 1) (num-test (gcd 0 2) 2) (num-test (gcd 0 2) 2) (num-test (gcd 0 3 -3 -1234000000) 1) (num-test (gcd 0 3) 3) (num-test (gcd 0 362880 362880 1) 1) (num-test (gcd 0 362880) 362880) (num-test (gcd 0 4) 4 ) (num-test (gcd 0 500029 -500029 -2) 1) (num-test (gcd 0 500029) 500029) (num-test (gcd 0) 0) (num-test (gcd 1 -1) 1) (num-test (gcd 1 -10) 1) (num-test (gcd 1 -1234) 1) (num-test (gcd 1 -1234000000) 1) (num-test (gcd 1 -2) 1) (num-test (gcd 1 -3) 1) (num-test (gcd 1 -362880) 1) (num-test (gcd 1 -500029) 1) (num-test (gcd 1 0 -1 1) 1) (num-test (gcd 1 0) 1) (num-test (gcd 1 1 2 -10) 1) (num-test (gcd 1 1) 1) (num-test (gcd 1 10 -1234 1234000000) 1) (num-test (gcd 1 10) 1) (num-test (gcd 1 1234 1234000000 -1234) 1) (num-test (gcd 1 1234) 1) (num-test (gcd 1 1234000000 -500029 -10) 1) (num-test (gcd 1 1234000000) 1) (num-test (gcd 1 2 -3 -362880) 1) (num-test (gcd 1 2) 1) (num-test (gcd 1 3 10 500029) 1) (num-test (gcd 1 3) 1) (num-test (gcd 1 362880 0 2) 1) (num-test (gcd 1 362880) 1) (num-test (gcd 1 500029 362880 3) 1) (num-test (gcd 1 500029) 1) (num-test (gcd 1) 1) (num-test (gcd 1/10 1/1000000000) 1/1000000000) (num-test (gcd 1/1024 1/9765625) 1/10000000000) (num-test (gcd 1/131072 1/762939453125) 1/100000000000000000) (num-test (gcd 1/2 1/3) 1/6) (num-test (gcd 1/2 2) 1/2) (num-test (gcd 1/262144 1/3814697265625) 1/1000000000000000000) (num-test (gcd 1/3 1/6 5/12 2) 1/12) (num-test (gcd 1/3 1/6 5/12) 1/12) (num-test (gcd 1/3 2/3) 1/3) (num-test (gcd 1/3 3/4 5/8) 1/24) (num-test (gcd 1/3 3/4) 1/12) (num-test (gcd 10 -1) 1) (num-test (gcd 10 -10) 10) (num-test (gcd 10 -1234) 2) (num-test (gcd 10 -1234000000) 10) (num-test (gcd 10 -2) 2) (num-test (gcd 10 -3) 1) (num-test (gcd 10 -362880) 10) (num-test (gcd 10 -500029) 1) (num-test (gcd 10 0 10 10) 10) (num-test (gcd 10 0) 10) (num-test (gcd 10 1 -1234 3) 1) (num-test (gcd 10 1) 1) (num-test (gcd 10 10 362880 10) 10) (num-test (gcd 10 10) 10) (num-test (gcd 10 1234 0 362880) 2) (num-test (gcd 10 1234) 2) (num-test (gcd 10 1234000000 1 -500029) 1) (num-test (gcd 10 1234000000) 10) (num-test (gcd 10 2 1234000000 -2) 2) (num-test (gcd 10 2) 2) (num-test (gcd 10 3 -500029 -1) 1) (num-test (gcd 10 3) 1) (num-test (gcd 10 362880 3 1234) 1) (num-test (gcd 10 362880) 10) (num-test (gcd 10 500029 -2 -1234000000) 1) (num-test (gcd 10 500029) 1) (num-test (gcd 10) 10) (num-test (gcd 1008217762344 4403) 37) (num-test (gcd 1111364125679340 6) 6) (num-test (gcd 1200780158492850 91686) 354) (num-test (gcd 1234 -1) 1) (num-test (gcd 1234 -10) 2) (num-test (gcd 1234 -1234) 1234) (num-test (gcd 1234 -1234000000) 1234) (num-test (gcd 1234 -2) 2) (num-test (gcd 1234 -3) 1) (num-test (gcd 1234 -362880) 2) (num-test (gcd 1234 -500029) 1) (num-test (gcd 1234 0 -1234 1234) 1234) (num-test (gcd 1234 0) 1234) (num-test (gcd 1234 1 1234000000 -10) 1) (num-test (gcd 1234 1) 1) (num-test (gcd 1234 10 0 1) 1) (num-test (gcd 1234 10) 2) (num-test (gcd 1234 1234 1 -10) 1) (num-test (gcd 1234 1234) 1234) (num-test (gcd 1234 1234000000 -2 -362880) 2) (num-test (gcd 1234 1234000000) 1234) (num-test (gcd 1234 2 -500029 -3) 1) (num-test (gcd 1234 2) 2) (num-test (gcd 1234 3 362880 2) 1) (num-test (gcd 1234 3) 1) (num-test (gcd 1234 362880 -10 1234000000) 2) (num-test (gcd 1234 362880) 2) (num-test (gcd 1234 500029 3 500029) 1) (num-test (gcd 1234 500029) 1) (num-test (gcd 1234) 1234) (num-test (gcd 1234000000 -1) 1) (num-test (gcd 1234000000 -10) 10) (num-test (gcd 1234000000 -1234) 1234) (num-test (gcd 1234000000 -1234000000) 1234000000) (num-test (gcd 1234000000 -2) 2) (num-test (gcd 1234000000 -3) 1) (num-test (gcd 1234000000 -362880) 640) (num-test (gcd 1234000000 -500029) 1) (num-test (gcd 1234000000 0 1234000000 -1234000000) 1234000000) (num-test (gcd 1234000000 0) 1234000000) (num-test (gcd 1234000000 1 -500029 -1234) 1) (num-test (gcd 1234000000 1) 1) (num-test (gcd 1234000000 10 1 -2) 1) (num-test (gcd 1234000000 10) 10) (num-test (gcd 1234000000 1234 -2 -1) 1) (num-test (gcd 1234000000 1234) 1234) (num-test (gcd 1234000000 1234000000 3 10) 1) (num-test (gcd 1234000000 1234000000) 1234000000) (num-test (gcd 1234000000 2 362880 10) 2) (num-test (gcd 1234000000 2) 2) (num-test (gcd 1234000000 3 0 3) 1) (num-test (gcd 1234000000 3) 1) (num-test (gcd 1234000000 362880 1234 -500029) 1) (num-test (gcd 1234000000 362880) 640) (num-test (gcd 1234000000 500029 -10 362880) 1) (num-test (gcd 1234000000 500029) 1) (num-test (gcd 1234000000) 1234000000) (num-test (gcd 1346702251365156 435) 87) (num-test (gcd 136581511784536 67022) 62) (num-test (gcd 1388225063690465 644) 7) (num-test (gcd 15295874 111) 37) (num-test (gcd 1551193257090906 2656731) 1749) (num-test (gcd 1563464979842 442) 34) (num-test (gcd 15858537083857314 21793) 21793) (num-test (gcd 163873565922 155) 31) (num-test (gcd 178335507754891305 817) 817) (num-test (gcd 2 -1) 1) (num-test (gcd 2 -10) 2) (num-test (gcd 2 -1234) 2) (num-test (gcd 2 -1234000000) 2) (num-test (gcd 2 -2) 2) (num-test (gcd 2 -3) 1) (num-test (gcd 2 -362880) 2) (num-test (gcd 2 -500029) 1) (num-test (gcd 2 0 2 -2) 2) (num-test (gcd 2 0) 2) (num-test (gcd 2 1 -3 -1) 1) (num-test (gcd 2 1) 1) (num-test (gcd 2 10 1234000000 -500029) 1) (num-test (gcd 2 10) 2) (num-test (gcd 2 1234 -500029 -1234000000) 1) (num-test (gcd 2 1234) 2) (num-test (gcd 2 1234000000 362880 1234) 2) (num-test (gcd 2 1234000000) 2) (num-test (gcd 2 2 10 10) 2) (num-test (gcd 2 2) 2) (num-test (gcd 2 3 -1234 362880) 1) (num-test (gcd 2 3) 1) (num-test (gcd 2 3/4) 1/4) (num-test (gcd 2 362880 1 -3) 1) (num-test (gcd 2 362880) 2) (num-test (gcd 2 500029 0 10) 1) (num-test (gcd 2 500029) 1) (num-test (gcd 2) 2) (num-test (gcd 2033404107084 23374) 2) (num-test (gcd 20430054 41) 41) (num-test (gcd 2090198664 1118) 2) (num-test (gcd 21568911 41) 41) (num-test (gcd 248255254 767) 13) (num-test (gcd 2755 13) 1) (num-test (gcd 3 -1) 1) (num-test (gcd 3 -10) 1) (num-test (gcd 3 -1234) 1) (num-test (gcd 3 -1234000000) 1) (num-test (gcd 3 -2) 1) (num-test (gcd 3 -3) 3) (num-test (gcd 3 -362880) 3) (num-test (gcd 3 -500029) 1) (num-test (gcd 3 0 -3 -3) 3) (num-test (gcd 3 0) 3) (num-test (gcd 3 1 10 2) 1) (num-test (gcd 3 1) 1) (num-test (gcd 3 10 -500029 -362880) 1) (num-test (gcd 3 10) 1) (num-test (gcd 3 1234 362880 500029) 1) (num-test (gcd 3 1234) 1) (num-test (gcd 3 1234000000 0 1234000000) 1) (num-test (gcd 3 1234000000) 1) (num-test (gcd 3 2 -1234 1) 1) (num-test (gcd 3 2) 1) (num-test (gcd 3 3 1234000000 -10) 1) (num-test (gcd 3 3) 3) (num-test (gcd 3 362880 -2 -10) 1) (num-test (gcd 3 362880) 3) (num-test (gcd 3 500029 1 -1234) 1) (num-test (gcd 3 500029) 1) (num-test (gcd 3) 3) (num-test (gcd 3/4 2) 1/4) (num-test (gcd 32 -36) 4 ) (num-test (gcd 323 28747 27113) 19) (num-test (gcd 3333 -33 1002001) 11) (num-test (gcd 3333 -33 101) 1) (num-test (gcd 362880 -1) 1) (num-test (gcd 362880 -10) 10) (num-test (gcd 362880 -1234) 2) (num-test (gcd 362880 -1234000000) 640) (num-test (gcd 362880 -2) 2) (num-test (gcd 362880 -3) 3) (num-test (gcd 362880 -362880) 362880) (num-test (gcd 362880 -500029) 1) (num-test (gcd 362880 0 362880 362880) 362880) (num-test (gcd 362880 0) 362880) (num-test (gcd 362880 1 0 500029) 1) (num-test (gcd 362880 1) 1) (num-test (gcd 362880 10 3 10) 1) (num-test (gcd 362880 10) 10) (num-test (gcd 362880 1234 -10 3) 1) (num-test (gcd 362880 1234) 2) (num-test (gcd 362880 1234000000 1234 -2) 2) (num-test (gcd 362880 1234000000) 640) (num-test (gcd 362880 2 1 -1234000000) 1) (num-test (gcd 362880 2) 2) (num-test (gcd 362880 3 -2 -1234) 1) (num-test (gcd 362880 3) 3) (num-test (gcd 362880 362880 500029 10) 1) (num-test (gcd 362880 362880) 362880) (num-test (gcd 362880 500029 -1234000000 -1) 1) (num-test (gcd 362880 500029) 1) (num-test (gcd 362880) 362880) (num-test (gcd 363169800 20) 20) (num-test (gcd 3712337724 576173) 23) (num-test (gcd 386512944051107445 17) 17) (num-test (gcd 406117800 57) 3) (num-test (gcd 4097970629150 86) 2) (num-test (gcd 4294967298 3) 3) (num-test (gcd 43293168048 1344610) 2) (num-test (gcd 4380921044390 5) 5) (num-test (gcd 4412914630225794 515823) 46893) (num-test (gcd 44179338013272 280645) 41) (num-test (gcd 500029 -1) 1) (num-test (gcd 500029 -10) 1) (num-test (gcd 500029 -1234) 1) (num-test (gcd 500029 -1234000000) 1) (num-test (gcd 500029 -2) 1) (num-test (gcd 500029 -3) 1) (num-test (gcd 500029 -362880) 1) (num-test (gcd 500029 -500029) 500029) (num-test (gcd 500029 0 -500029 -500029) 500029) (num-test (gcd 500029 0) 500029) (num-test (gcd 500029 0) 500029) (num-test (gcd 500029 1 362880 1234000000) 1) (num-test (gcd 500029 1) 1) (num-test (gcd 500029 10 -2 -3) 1) (num-test (gcd 500029 10) 1) (num-test (gcd 500029 1234 3 2) 1) (num-test (gcd 500029 1234) 1) (num-test (gcd 500029 1234000000 -10 1) 1) (num-test (gcd 500029 1234000000) 1) (num-test (gcd 500029 2 0 1234) 1) (num-test (gcd 500029 2) 1) (num-test (gcd 500029 3 1 -10) 1) (num-test (gcd 500029 3) 1) (num-test (gcd 500029 362880 -1234000000 -362880) 1) (num-test (gcd 500029 362880) 1) (num-test (gcd 500029 500029 1234 -10) 1) (num-test (gcd 500029 500029) 500029) (num-test (gcd 500029) 500029) (num-test (gcd 510104442 5453) 1) (num-test (gcd 524288/5 19073486328125/2) 1/10) (num-test (gcd 5275411661289 31857) 21) (num-test (gcd 56 2) 2) (num-test (gcd 60 42) 6) (num-test (gcd 608503422693864 47) 47) (num-test (gcd 629448534 2) 2) (num-test (gcd 63 -42 35) 7) (num-test (gcd 64149298745840 43808357) 35131) (num-test (gcd 660070972 74) 74) (num-test (gcd 6945109296864 779) 19) (num-test (gcd 71862 203) 203) (num-test (gcd 7438317458260 31213) 13) (num-test (gcd 77874422 32223899) 1) (num-test (gcd 82578867500655 319) 29) (num-test (gcd 91 -49) 7) (num-test (gcd 91 -49) 7) (num-test (gcd) 0 ) (num-test (gcd) 0) (num-test (gcd 9223372036854775807 -9223372036854775808) 1) (num-test (gcd 10400200/16483927 1607521/1136689) 1/18737098497703) (num-test (gcd 10781274/17087915 3880899/2744210) 3/9378565444430) (num-test (gcd 12/19 41/29) 1/551) (num-test (gcd 12941/20511 3363/2378) 1/48775158) (num-test (gcd 15601/24727 19601/13860) 1/342716220) (num-test (gcd 171928773/272500658 54608393/38613965) 1/10522330870488970) (num-test (gcd 190537/301994 114243/80782) 1/12197839654) (num-test (gcd 2/3 3/2) 1/6) (num-test (gcd 253/401 577/408) 1/163608) (num-test (gcd 397573379/630138897 131836323/93222358) 1/58743033845859126) (num-test (gcd 4201378396/6659027209 318281039/225058681) 1/1498671880400651329) (num-test (gcd 5/8 17/12) 1/24) (num-test (gcd 53/84 99/70) 1/420) (num-test (gcd 53715833/85137581 9369319/6625109) 1/564045754121329) (num-test (gcd 665/1054 1393/985) 7/1038190) (num-test (gcd 7161071/11350029 275807/195025) 1/2213539405725) (num-test (gcd 79335/125743 47321/33461) 1/4207486523) (num-test (gcd -2305843009213693952/4611686018427387903) 2305843009213693952/4611686018427387903) (test (gcd 0 "hi") 'error) (test (gcd 1 "hi") 'error) (test (gcd 3 5 #\a) 'error) (test (gcd 1.4 2.3) 'error) (test (gcd 1.0) 'error) (test (gcd 0/0) 'error) (test (gcd 2 1.0+0.5i) 'error) (for-each (lambda (arg) (test (gcd arg nan.0) 'error) (test (gcd nan.0 arg) 'error) (test (gcd arg inf.0) 'error) (test (gcd inf.0 arg) 'error) (test (gcd arg 2) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) (for-each (lambda (arg) (test (gcd 2 arg) 'error) (test (gcd 1/2 arg) 'error) (test (gcd 2.0 arg) 'error) (test (gcd 2+i arg) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) (if with-bignums (begin (num-test (gcd -9223372036854775808 -9223372036854775808) 9223372036854775808) (num-test (gcd -9223372036854775808 9223372036854775807 -9223372036854775808) 1) (num-test (gcd 12345678901234567890 12345) 15) (num-test (gcd 2155967190204955525121 -12850565775361 93458656690177) 557057) (num-test (gcd 2155967190204955525121 0) 2155967190204955525121) (num-test (gcd 2155967190204955525121 12850565775361 93458656690177) 557057) (num-test (gcd 2346026393680644703525505657 17293822570713318399) 11) (num-test (gcd 974507656412513757857315037382926980395082974811562770185617915360 -1539496810360685510909469177732386446833404488164283) 1) (num-test (gcd 460683358924445799142 518) 518) (num-test (gcd 113021475230160 74635) 6785) (num-test (gcd 74228340534140364 363909) 1677) (num-test (gcd 69242022961311060 48305942) 60458) (num-test (gcd -286967952870300 2273388) 156) (num-test (gcd 302822258393413362492399 29) 29) (num-test (gcd 10491072879382200 133) 133) (num-test (gcd 167206737423420464 609) 7) (num-test (gcd 72212583812867784 4888799) 47) (num-test (gcd 4170116471639397292390 1798025) 359605) (num-test (gcd 83910330283522050 35224) 238) (num-test (gcd 275373383775647594346 66884092) 104834) (num-test (gcd 14656657495570695990 37) 1) (num-test (gcd 95470974177676509874110 1219) 1219) (num-test (gcd 619506317623001424 -5957) 7) (num-test (gcd 11268171656665155960 9858) 186) (num-test (gcd 6172860073826160 5167394) 3074) (num-test (gcd 26457493095663264 1491412) 3956) (num-test (gcd -8481384175941103284 313836405) 51) (num-test (gcd 60356595775749199080 -176098815946) 1716346) (num-test (gcd 611492274956002440 37) 37) (num-test (gcd 164614611843685080 1711) 59) (num-test (gcd 93177516542679418720 62197) 37) (num-test (gcd 938959746797519770440 127558) 127558) (num-test (gcd 137670522526899326250 200) 50) (num-test (gcd 852063402206742880 41643478) 58406) (num-test (gcd 55947291202307909360 188546228) 6364) (num-test (gcd 12877971214039423262680 9832253830) 121730) (num-test (gcd 192158415774146059920 53) 53) (num-test (gcd 902814024155808960 1829) 31) (num-test (gcd 1265864304573235487120 4921) 259) (num-test (gcd -14172662463567665400 95817) 57) (num-test (gcd 32171996211745702482324 2368555) 259) (num-test (gcd 971324258606045826300 4576748) 236) (num-test (gcd 2400649320046378377000 1704690) 930) (num-test (gcd 953233796456393760 18342152493) 574287) (num-test (gcd 28906333140964843080 236206740) 823020) (num-test (gcd 775403093708557121609032 41) 41) (num-test (gcd 12587009808135760402860 2491) 47) (num-test (gcd 510685807527370566909720 76) 4) (num-test (gcd 9842598153710524682146590 10089) 3363) (num-test (gcd 44936631038618189620242012 30740) 6148) (num-test (gcd 934589372977008750144 373650) 282) (num-test (gcd 33027125273398900134069150 840577803) 840577803) (num-test (gcd 4428219127938822420288 1695783782) 12502) (num-test (gcd 29316428815807608915440 560764380) 153340) (num-test (gcd 1364397376360544429904 19) 19) (num-test (gcd 4991450791697293128313385277 329) 7) (num-test (gcd 75448279792981695149550 3009) 3) (num-test (gcd 181031604499464166188731133 3364) 1) (num-test (gcd 405831142402606479845286 2746214) 161542) (num-test (gcd 89170366469003867207160 25337230) 11470) (num-test (gcd 13523725766340619200 1490114045) 28595) (num-test (gcd 104705939487154940255412 192200052) 26196) (num-test (gcd 7232591421499800642000 16584679460) 7820) (num-test (gcd 14043796716396386984750160 -33382708236) 358953852) (num-test (gcd 13894638105872256412416 23) 23) (num-test (gcd 147611447155643499428400 118) 2) (num-test (gcd 13356594697070649024 4558) 106) (num-test (gcd 15089731174706036171537760 90) 30) (num-test (gcd 307230141273924828960 1971507) 1581) (num-test (gcd 2582563944548247741930009096 22873474) 1759498) (num-test (gcd 1074296602920111687342072 146235518) 21758) (num-test (gcd 774058642832724262993980 -407557010) 2531410) (num-test (gcd 291091930213008490369569480 13412544348) 26508) (num-test (gcd 2089068565149831833568 7302038455228) 68171356) (num-test (gcd 1064437567441124038217970656 5) 1) (num-test (gcd 142557826750459447787460 1333) 31) (num-test (gcd 311779340580033594160200 23693) 23693) (num-test (gcd 29314187023691666530559664 110143) 110143) (num-test (gcd 222003853016244177637944900 857463) 857463) (num-test (gcd 6247776111945111006243552 77976501) 2515371) (num-test (gcd 1140058514761397155259712 5530338) 502758) (num-test (gcd 580962736822969724865449808 55686036) 1505028) (num-test (gcd 4100502596989506786787500 45333475410) 563730) (num-test (gcd 1497378750311599979536944 262630276090) 361046) (num-test (gcd 105637634198318524045536 2633013240) 150072) (num-test (gcd 11415822547029425161364106595632 7) 1) (num-test (gcd 198305933339312916107438448 177) 3) (num-test (gcd 3127415425979879537134790928 3335) 667) (num-test (gcd 589703503861221139260034914750 13209) 357) (num-test (gcd 3108579252052448504121792 14322) 462) (num-test (gcd 636976201153021006473464400 66264077) 3487583) (num-test (gcd 9544425315508129998909285900 1488396) 212628) (num-test (gcd 458100280193857502802977376 260747103934) 6212554) (num-test (gcd 114208186302155358124900650 22076867505) 6342105) (num-test (gcd 90107067439719108194114160 28566806069714) 3408519994) (num-test (gcd 2976572787365723002218245484 -110104803958578) 2966904798) (num-test (gcd 53453375725613238735360 17) 1) (num-test (gcd 888822833524306124874229800 106) 106) (num-test (gcd 21275338550698297089687698855820 3021) 3021) (num-test (gcd 417525245705449941528380320750068 5828) 5828) (num-test (gcd 1954871230146370370001829871352 22765249) 22765249) (num-test (gcd 903057827710908645847577520 648545995) 520085) (num-test (gcd 6002846634833433581621040 28493572159) 27869) (num-test (gcd 26428903214964558277189300080 100428856) 3463064) (num-test (gcd 470486531607553676511206181180 28495896) 2964) (num-test (gcd 483599554429365539310928369206620 5577334078910) 105232718470) (num-test (gcd 134511400157705323668887400 -1285071093558916) 340069628) (num-test (gcd -25897125642468049125349982599216 1183846707540) 26307704612) (num-test (gcd 1118034209930460291955200 3) 3) (num-test (gcd 16297594064835666104344589410644 413) 413) (num-test (gcd 536762539932642345554192060100 1378) 1378) (num-test (gcd 933250179448203335817687635834340 58029) 69) (num-test (gcd 65573457048202714607131200 486115) 3655) (num-test (gcd 85664559165674439863772868932 322014) 322014) (num-test (gcd 7232817686074320060728552759760 11307940) 11307940) (num-test (gcd 78400098291720425971762131120 5646921093) 5646921093) (num-test (gcd 345445746644065669842240 19727989065) 2193705) (num-test (gcd 627854758484491743169777558200 -750371721805653) 156322329) (num-test (gcd 788233263079483492974876830792850 7170146100) 5867550) (num-test (gcd 18378856389802641496737518160 6247594493140) 824329660) (num-test (gcd 9620902642431357480148667659080 59) 59) (num-test (gcd 16008524600631853118144316000 629) 1) (num-test (gcd 4342138447708715023205684275423920 53041) 1711) (num-test (gcd 2431833161592653384508687244500 47541) 47541) (num-test (gcd 39424620224103957589082132160 1671734) 1671734) (num-test (gcd 652830233576052788654372406432 552231327) 12842589) (num-test (gcd 6892963340916411083970414000 3662431431) 77924073) (num-test (gcd 29102758215190063506219566460000 10565720) 10565720) (num-test (gcd 21253900104556838003127171970777418412 1182797770) 62698) (num-test (gcd 3964268932242030284914943132662620 21244177854110) 18521515130) (num-test (gcd 6070388091189460078138338240 40809131994181213) 274113073169) (num-test (gcd 9685989954133695108793384134000 964113514382876) 169529367748) (num-test (gcd 56468122001858834917195045500 -429400787158167902) 2090772606538) (num-test (gcd 18843408973202596901221568364900 47) 47) (num-test (gcd 7800980538292163259967028613764250 6) 6) (num-test (gcd 270433907726619219545089642715200 3422) 58) (num-test (gcd 45771666919597903071546708768 2342359) 2183) (num-test (gcd 47198294949461301503537593835384892 314502) 5934) (num-test (gcd 3165335901519110207943908102359110 14953473) 207) (num-test (gcd 189219585097956261544520863361400 35605794) 35605794) (num-test (gcd -38532137569034426600955256933810890813 -1341358608707) 6436369) (num-test (gcd 1396277868664090735481380981225896 312520860) 62504172) (num-test (gcd -864038349500762576564773759109700 714136202724) 16607818668) (num-test (gcd 12514185871591242579049167322464 10706997440178) 200614518) (num-test (gcd 1981802660405609330969478067056636 33312289752) 14779188) (num-test (gcd 979313401024175219420658240 125278417383795) 1551032145) (num-test (gcd 4074026154111369481048033354344 29) 29) (num-test (gcd 599666571180604695702511920885005100 129) 129) (num-test (gcd 5703263639326551702474610108800 1978) 1978) (num-test (gcd 134137932950214683609064669163440 190619) 143) (num-test (gcd 344735091370772631136645455600 1048985) 1048985) (num-test (gcd 6759508339299085316106145385400 4969610) 160310) (num-test (gcd 700334422308861928135313594400 228529587) 432003) (num-test (gcd 10277417891211405957191810814198480 2516552038) 228777458) (num-test (gcd 490099971577877358878082782880 9282588354) 17547426) (num-test (gcd 1954558750269048828645390249600 5575829490) 327989970) (num-test (gcd 1360588454560018295496656378989200 7868178296420) 14873682980) (num-test (gcd 4337552841738910859248770564912480 17722936528737830) 338114285990) (num-test (gcd 215913068853045803981566931862756 7009479781500) 2930844) (num-test (gcd 44890707654126305940250882318870941900 18329973480720) 1527497790060) (num-test (gcd 28579720891831355496720656680837200 3) 3) (num-test (gcd 29332703209780553199747293473184160 1711) 29) (num-test (gcd 3648979393315349438003046604440000 186) 186) (num-test (gcd 1159760236369472473822068077011807878780 25714) 25714) (num-test (gcd 158186359726371025615685433600 31395) 4485) (num-test (gcd 331091450443070201468559735703944 28424) 28424) (num-test (gcd 9734443639363161342241553023288200 1961348207) 63269297) (num-test (gcd 701896612128009033011419603540080 51300) 3420) (num-test (gcd 86169288128517384618860929451245320 5032162527446) 180164066) (num-test (gcd 64828800524794653881296183831741773624 4645294472) 6354712) (num-test (gcd 49068907706533938991402184550000 268183371225) 742890225) (num-test (gcd 1708602980304476478496020543612288 4083128544) 131713824) (num-test (gcd 17608179287674151740172985536160 980399424528) 91686096) (num-test (gcd 43194437079731225735521919644800 -178119261126453036) 80633436453804) (num-test (gcd 817555977437791699707628651571149344 59) 59) (num-test (gcd 19062946261334997559157066059536 533) 41) (num-test (gcd 6533849124840489114353090499099000 598) 26) (num-test (gcd 427663965127849896842400211428345149025 234) 117) (num-test (gcd 352395507261316174741530450071590608 154734) 3774) (num-test (gcd 391579493632653867660919800000 9221565) 645) (num-test (gcd 2618798923882923048581401148931738000 681876) 52452) (num-test (gcd 174712575449141140214591110997980800 233260339838) 126154862) (num-test (gcd 88598141227372995032227898284800 1929763976) 155288) (num-test (gcd 210110141308655567793064872567302676320 720390430628) 468699044) (num-test (gcd 668425085137718599277317523827419000 19898594339442) 58711254) (num-test (gcd 89533471731097208414073727453200 4173840860670546) 2257350384354) (num-test (gcd 113987439157802480362236410675251462620 21548296273949445) 1134120856523655) (num-test (gcd 48129335993995093308894209644253760 1009442888504820) 84891337020) (num-test (gcd -3497836376962291922989777163497680 138736290091634664) 3383811953454504) (num-test (gcd 11371924962562208722154622794880 3) 3) (num-test (gcd 9451631862008339290824315653784000 703) 19) (num-test (gcd 16869347753325980368094612370435598560 806) 806) (num-test (gcd 4701845646467068759127854100132739552 3198) 6) (num-test (gcd 1029865193584911347147121232800485280 1005771) 24531) (num-test (gcd 10657125216930337802109861408000 2415138) 2838) (num-test (gcd 14382707743772734802155022983680 247913634) 144894) (num-test (gcd 60134748581470366378101904574533857248 54828228) 493948) (num-test (gcd 214830664120540781167218700750596000 505665810) 11759670) (num-test (gcd 48933004118344447687599112101802800 6263883444) 106167516) (num-test (gcd 5498670161558110606435630054129739400 262699548132) 1346604) (num-test (gcd 35941673649029587182509620977230062500 25622409466332) 525598668) (num-test (gcd 1592802602494326390643157055239113248 736377633395508) 960075141324) (num-test (gcd 4043816553144402557587143272522043028314 5011466158645380) 366067652202) (num-test (gcd 7171921165220830707276631005512550 1765284492289500) 176528449228950) (num-test (gcd 2402189359210218692854826119405968750 23) 1) (num-test (gcd 26149068753160488131648964110990162400 1147) 31) (num-test (gcd 556184059176863945810376239306506311552 4089) 4089) (num-test (gcd 67871323087036310486238021899264593800 13395) 13395) (num-test (gcd 12750401179065252879838440979200 -7177173) 7177173) (num-test (gcd 278110245000092733617125071646080 17748) 17748) (num-test (gcd 13408203364935178481017292708752000 50619404) 1368092) (num-test (gcd 124271828931784534297423756437875067000 -8839796595) 4068015) (num-test (gcd 11893442806922081156953529319100769836176 972789007267) 983608703) (num-test (gcd 352581052555284857902053030133344488264100 923561430099) 54327142947) (num-test (gcd 6108908012714804315575319947340956346976 31944833628092) 97096758748) (num-test (gcd 67475643422116264959949054821520228800 22515435540) 326310660) (num-test (gcd 470601888939348535946408832 5135943991060962937) 36905011) (num-test (gcd -110759232155568113345545635903016614000 30159198663300) 30159198663300) (num-test (gcd 146100914712024458707469587112300146320 26868173101560) 10304280) (num-test (gcd 12173192708601511002951184416658091200 466645866900785428350) 1496624001041650) (num-test (gcd 5784684831478746253226687170890240 13) 13) (num-test (gcd 35042260655085685815432622412891903767500 667) 667) (num-test (gcd 2903871349270676921837488659419545120987500 530) 530) (num-test (gcd 630123969240840167098426767919876491188000 77691) 25897) (num-test (gcd 33192703032132982013024959634241667249800 4684718) 126614) (num-test (gcd 4731525733734729472809717145544850000 90706055) 90706055) (num-test (gcd 214011009809686092216200126896120006823232 50400042) 258) (num-test (gcd 5854250735296111435541950856160000 24357777002) 817622) (num-test (gcd 35348208247612761916374738259136697649608 156806713508) 8596388) (num-test (gcd 612558317420289618714916924536521515286100 2377007388) 125105652) (num-test (gcd 181857299802925368992522029882739454720 21606337755618) 21606337755618) (num-test (gcd 4731635341196946327443020710970699860000 58092526675092) 776108892) (num-test (gcd 22081740554432638182773611616166588288192 61419768950540) 12283953790108) (num-test (gcd 125627844706077784535328068665849312000 30482033400) 32200) (num-test (gcd 1225504716872819103560254268197955520 510813364186125) 168863922045) (num-test (gcd 5209185280578468690281136425214396728400 2327880739319250103818) 829166238) (num-test (gcd 230425011604643097634961294406535254400 31) 31) (num-test (gcd 13222608481676137093434201748083744000 893) 893) (num-test (gcd 13348198818240350339028224064019716678960 651) 3) (num-test (gcd 7236172685650198160266777676385295337308176 23426) 442) (num-test (gcd 756264162229440667711265021676693350760 28899) 28899) (num-test (gcd 40915062421030872924283823601517905600 36345062) 36345062) (num-test (gcd 1174590526522170015825602834292923520 4991486258) 145114) (num-test (gcd 2891892862328155581145450075391651333218020 35138529818) 35138529818) (num-test (gcd 1993335355070485984559797658834121810059400 535644500) 2612900) (num-test (gcd 6324295450641455215591954662726515160 367472693133) 8962748613) (num-test (gcd 6576388154814679090356195121505112000 15901952377630) 969690370) (num-test (gcd 117828556355409428513249595788296238400 565992666495795) 33126555) (num-test (gcd 592831716700236607285748949860604000 139641978135660) 343100683380) (num-test (gcd 106766839071170184723986891291602032000 1584924526628112) 1983635202288) (num-test (gcd 21677148858122146832326483307664860804937400 247815827510760) 9178363981880) (num-test (gcd 14079549844487257384278196623697173813600 160967604100961853832) 42959600534344) (num-test (gcd 2696480372014145687016224877963234647656980 -2219319031453896088860) 1258830987778727220) (num-test (gcd 13545431257849875145060979241270859310160 29) 29) (num-test (gcd 137485634482479300158725199474868559498162500 329) 47) (num-test (gcd 529252417743761759027305009539254400 3243) 3243) (num-test (gcd 133897419738958073238580385894509887148800 330455) 330455) (num-test (gcd 3896215507210178905244623173635584334007288624 1005238) 1005238) (num-test (gcd 17654511984514518592175290794029073043800 1060530) 36570) (num-test (gcd 16470780256339082688310222474503880382858400 913836) 913836) (num-test (gcd 57267105834722825210001789897760395576000 2958974018) 62956894) (num-test (gcd 521977833444747522001426544601807810543216 1066521690) 4960566) (num-test (gcd 1699559962174727325529414216960251941390400 25883611479) 30924267) (num-test (gcd 10654036597801063717295948399628964800 317449894126222) 19212606314) (num-test (gcd 381902381115592200811990304316262139150724960 4640335440216) 4640335440216) (num-test (gcd 425968526187959807410151867411382902838703889232 1882826315615025) 4430179566153) (num-test (gcd 174609167728518272531601927200939868792000 1712923655178450) 6189150) (num-test (gcd 3325168366561555458817274989681612518000 1699726139891780) 130748164607060) (num-test (gcd 11429650426242566426919762928176000 7414967839104) 5416338816) (num-test (gcd 2104794191230056678355480848036599377844400 -16946684823025584) 182222417451888) (num-test (gcd 11894522530167763519415142641640874994880 7) 7) (num-test (gcd 5906329981690378696996009087718418780000 185) 185) (num-test (gcd 3056294774178096513474941936265025440000 658) 658) (num-test (gcd 10491907660880423349353457742257185280 123369) 123369) (num-test (gcd 673239479595593149777212259021965839229225628776 15470) 3094) (num-test (gcd 1506608574369860432616005754109397877696 1474070) 294814) (num-test (gcd 4849814041048623250005708880379694793905000 2172220582) 2172220582) (num-test (gcd 21154344928580705924176101470087564940000 5023204186) 5023204186) (num-test (gcd 346448039376394135288065831861806112294000 776147372) 25037012) (num-test (gcd 2339009760844587560470606952218133142645504 194201967414) 5248701822) (num-test (gcd 2242982161480922111384667548175169152 21419749763490) 2316901002) (num-test (gcd 4717315265246821759830981157482117120 45609714193992) 26227552728) (num-test (gcd 16628111321698075419789804224660024289936 4643626415880804) 1653124391556) (num-test (gcd 115557531507210992033160068979962880 88406536976058378) 36546728803662) (num-test (gcd 21059511907771200155093927745003762840000 180298981648603620) 191197223381340) (num-test (gcd 2124921015128697258800067298086064536000 2282525112298516782924) 15103625661372) (num-test (gcd 16015671538624533047089928322348864000 49817926936366875) 69075001125) (num-test (gcd 166517667014186289390514558017250969134523800 -43413708621878528404068) 1188862957578074004) (num-test (gcd -2780796292789128359666429021610464935722000 47) 47) (num-test (gcd 21297913114430245153455383503409684916193317960 58) 58) (num-test (gcd 1516745257039775143654568869485529015398000 6293) 6293) (num-test (gcd 8447692776411453120390905608381515479808 2030) 14) (num-test (gcd 958876033949638283967045624731391031146081240 9834415) 166685) (num-test (gcd 4731349833403602529573388098680617532624192 14868) 14868) (num-test (gcd 6375001358038970462026761077388061675464000 430513678) 430513678) (num-test (gcd 254088526608579040642428151389718385042344800 4799428101) 255411) (num-test (gcd 21140490542258031885408065086507444825621023648 164778747198) 13189686) (num-test (gcd 34214837305812460226811046733375808000 4312787868) 746028) (num-test (gcd 11450197571956515037245443769386989035470896800 75585518430279) 5814270648483) (num-test (gcd 1211397915863796187148880114197307052796506376580 538601201880) 11708721780) (num-test (gcd 5454139401260819402160859765169199667337088 30452838731872) 48414687968) (num-test (gcd 744935981632690384026127091216926530879171660 1032747922358460) 60868033380) (num-test (gcd 324574326062026951443376280715122947502400 103751223626207988025) 3334229637375325) (num-test (gcd 15272163751269260921486082393684080908800 6484309049057400) 341279423634600) (num-test (gcd 386527546655781220813671331401971490218262720 3481571963427119100) 1915440648660) (num-test (gcd 3189682029126430413458911948222943640000 -6724598925622907976570) 829921474949490) (num-test (gcd -709403542855323660533377490060722241678400 7) 7) (num-test (gcd 139803787314578422635552652090095842837312147438904 123) 123) (num-test (gcd 171985399350431759069945935900956183322827030835560 18241) 18241) (num-test (gcd 33090522521924986387051477884789600000 26187) 609) (num-test (gcd 1733723010009930088165729903139785699319986530 372945) 7935) (num-test (gcd 56408303994570817306318494803635460247582000 5761730) 10810) (num-test (gcd 25845509336769185412951159262424903513866295760 64371378271) 64371378271) (num-test (gcd 624970361450506104794172455132584603069611058500 108222780) 108222780) (num-test (gcd 82823962548382643645255524843049561752323600 135325929794) 12302357254) (num-test (gcd 170620453449723034746079844571491973300000 9460614789626) 230746702186) (num-test (gcd 125144597811313015929871740675462711600000 12764411911636) 12726233212) (num-test (gcd 257193319319332344553297882967977761077115600 6510126541380) 158783574180) (num-test (gcd 879624546681838385457288074812140664728758550 10045784120501316) 80757786714) (num-test (gcd 18300938860777100857669855248554588369659200 118088077425391892) 1433647093268) (num-test (gcd 8394780474625841647581984803260010511075000 746584618179400) 11198041400) (num-test (gcd 146802334713757872619395774222116859916800 718775571956687400) 854667743111400) (num-test (gcd 240155883351717999820072393833707008014911556000 -1350921510529331832) 10157304590446104) (num-test (gcd -918942437243241528855354123800826649596480 -74343962238703160850) 3476056267530) (num-test (gcd 1361069299753299783990135442290762165844800 8281085446358585640) 8546011812547560) (num-test (gcd 111738283365989051/177100989030047175 5964153172084899/4217293152016490) 1/149377357650353093734710215583150) (num-test (gcd 11571718688839/18340740190704 5168247530883/3654502875938) 1/33513143886879715286440176) (num-test (gcd 130441933147714940/206745572560704147 14398739476117879/10181446324101389) 1/2104968949772418231181062860760183) (num-test (gcd 137528045312/217976794617 63018038201/44560482149) 1/9713151065427067791933) (num-test (gcd 205632218873398596256/325919355854421968365 16616132878186749607/11749380235262596085) 1/5590292610168557896833020882635974965) (num-test (gcd 22803850947114245497/36143248623210700400 1180872205318713601/835002744095575440) 1/34295127023760867970857561935725200) (num-test (gcd 326267455807135/517121682660006 30122754096401/21300003689580) 1/1835782291436657618117489580) (num-test (gcd 3447601211185766107/5464318637170278738 202605639573839043/143263821649299118) 1/391419585335252015613280949198776542) (num-test (gcd 3816473305410548/6048967074079039 423859315570607/299713796309065) 313/1812958885520765991472282188535) (num-test (gcd 397560349370386783/630118245525664765 34761632124320657/24580185800219268) 17/15488423551129023359673258461692020) (num-test (gcd 4640282259296926456/7354673373747273033 489133282872437279/345869461223138161) 1/2543756917250129165517177396348512313) (num-test (gcd 483615324366283/766512153894657 175568277047523/124145519261542) 1/95159049365535186345899381094) (num-test (gcd 50247984153525417450/79641170620168673833 2850877693509864481/2015874949414289041) 1/160546640795227287934843564657515364153) (num-test (gcd 5409303924479/8573543875303 886731088897/627013566048) 1/5375728318922723466512544) (num-test (gcd 5680010011095224105765/9002602871306688466954 40114893348711941777/28365513113449345692) 1/127681724900613301985499022520606932131084) (num-test (gcd 615582794569/975675645481 152139002499/107578520350) 19/104961742282377144038350) (num-test (gcd 6189245291/9809721694 1855077841/1311738121) 1/12867785902420496974) (num-test (gcd 6234549927241963/9881527843552324 1023286908188737/723573111879672) 1/105147174292423231311078293496) (num-test (gcd 65470613321/103768467013 10812186007/7645370045) 1/793348329316760825585) (num-test (gcd 6586818670/10439860591 4478554083/3166815962) 1/33061117160633553542) (num-test (gcd 7530699980955811472069/11935877073996486182239 96845919575610633161/68480406462161287469) 1/817373713509671731923053344199644801063091) (num-test (gcd 753110839881/1193652440098 367296043199/259717522849) 1/310012454884916918799202) )) ;;; -------------------------------------------------------------------------------- ;;; lcm ;;; -------------------------------------------------------------------------------- (num-test (lcm (* 512 500057) (* 128 500057) (* 2048 500057)) 1024116736) (num-test (lcm (/ (expt 2 10)) (/ (expt 3 10))) 1) (num-test (lcm (/ (expt 2 57) 3) (/ 63 11)) 9079256848778919936) (num-test (lcm (/ 3 (expt 2 10)) (/ 2 (expt 3 10))) 6) (num-test (lcm (/ 3 (expt 2 40)) (/ 2 (expt 3 10))) 6) (num-test (lcm (/ 3 (expt 2 60)) (/ 2 (expt 2 30))) 3/536870912) (num-test (lcm (/ 3 (expt 2 60)) (/ 2 (expt 3 30))) 6) (num-test (lcm -1 -1) 1) (num-test (lcm -1 -10) 10) (num-test (lcm -1 -1234) 1234) (num-test (lcm -1 -1234000000) 1234000000) (num-test (lcm -1 -2) 2) (num-test (lcm -1 -3) 3) (num-test (lcm -1 -362880) 362880) (num-test (lcm -1 -500029) 500029) (num-test (lcm -1 0) 0) (num-test (lcm -1 1) 1) (num-test (lcm -1 10) 10) (num-test (lcm -1 1234) 1234) (num-test (lcm -1 1234000000) 1234000000) (num-test (lcm -1 2) 2) (num-test (lcm -1 3) 3) (num-test (lcm -1 362880) 362880) (num-test (lcm -1 500029) 500029) (num-test (lcm -1) 1) (num-test (lcm -1/2 -2) 2) (num-test (lcm -10 -1) 10) (num-test (lcm -10 -10) 10) (num-test (lcm -10 -1234) 6170) (num-test (lcm -10 -1234000000) 1234000000) (num-test (lcm -10 -2) 10) (num-test (lcm -10 -3) 30) (num-test (lcm -10 -362880) 362880) (num-test (lcm -10 -500029) 5000290) (num-test (lcm -10 0) 0) (num-test (lcm -10 1) 10) (num-test (lcm -10 10) 10) (num-test (lcm -10 1234) 6170) (num-test (lcm -10 1234000000) 1234000000) (num-test (lcm -10 2) 10) (num-test (lcm -10 3) 30) (num-test (lcm -10 362880) 362880) (num-test (lcm -10 500029) 5000290) (num-test (lcm -10) 10) (num-test (lcm -1234 -1) 1234) (num-test (lcm -1234 -10) 6170) (num-test (lcm -1234 -1234) 1234) (num-test (lcm -1234 -1234000000) 1234000000) (num-test (lcm -1234 -2) 1234) (num-test (lcm -1234 -3) 3702) (num-test (lcm -1234 -362880) 223896960) (num-test (lcm -1234 -500029) 617035786) (num-test (lcm -1234 0) 0) (num-test (lcm -1234 1) 1234) (num-test (lcm -1234 10) 6170) (num-test (lcm -1234 1234) 1234) (num-test (lcm -1234 1234000000) 1234000000) (num-test (lcm -1234 2) 1234) (num-test (lcm -1234 3) 3702) (num-test (lcm -1234 362880) 223896960) (num-test (lcm -1234 500029) 617035786) (num-test (lcm -1234) 1234) (num-test (lcm -1234000000 -1) 1234000000) (num-test (lcm -1234000000 -10) 1234000000) (num-test (lcm -1234000000 -1234) 1234000000) (num-test (lcm -1234000000 -1234000000) 1234000000) (num-test (lcm -1234000000 -2) 1234000000) (num-test (lcm -1234000000 -3) 3702000000) (num-test (lcm -1234000000 -362880) 699678000000) (num-test (lcm -1234000000 -500029) 617035786000000) (num-test (lcm -1234000000 0) 0) (num-test (lcm -1234000000 1) 1234000000) (num-test (lcm -1234000000 10) 1234000000) (num-test (lcm -1234000000 1234) 1234000000) (num-test (lcm -1234000000 1234000000) 1234000000) (num-test (lcm -1234000000 2) 1234000000) (num-test (lcm -1234000000 3) 3702000000) (num-test (lcm -1234000000 362880) 699678000000) (num-test (lcm -1234000000 500029) 617035786000000) (num-test (lcm -1234000000) 1234000000) (num-test (lcm -2 -1) 2) (num-test (lcm -2 -10) 10) (num-test (lcm -2 -1234) 1234) (num-test (lcm -2 -1234000000) 1234000000) (num-test (lcm -2 -2) 2) (num-test (lcm -2 -3) 6) (num-test (lcm -2 -362880) 362880) (num-test (lcm -2 -500029) 1000058) (num-test (lcm -2 0) 0) (num-test (lcm -2 1) 2) (num-test (lcm -2 10) 10) (num-test (lcm -2 1234) 1234) (num-test (lcm -2 1234000000) 1234000000) (num-test (lcm -2 2) 2) (num-test (lcm -2 3) 6) (num-test (lcm -2 362880) 362880) (num-test (lcm -2 500029) 1000058) (num-test (lcm -2) 2) (num-test (lcm -3 -1) 3) (num-test (lcm -3 -10) 30) (num-test (lcm -3 -1234) 3702) (num-test (lcm -3 -1234000000) 3702000000) (num-test (lcm -3 -2) 6) (num-test (lcm -3 -3) 3) (num-test (lcm -3 -362880) 362880) (num-test (lcm -3 -500029) 1500087) (num-test (lcm -3 0) 0) (num-test (lcm -3 1) 3) (num-test (lcm -3 10) 30) (num-test (lcm -3 1234) 3702) (num-test (lcm -3 1234000000) 3702000000) (num-test (lcm -3 2) 6) (num-test (lcm -3 3) 3) (num-test (lcm -3 362880) 362880) (num-test (lcm -3 500029) 1500087) (num-test (lcm -3) 3) (num-test (lcm -362880 -1) 362880) (num-test (lcm -362880 -10) 362880) (num-test (lcm -362880 -1234) 223896960) (num-test (lcm -362880 -1234000000) 699678000000) (num-test (lcm -362880 -2) 362880) (num-test (lcm -362880 -3) 362880) (num-test (lcm -362880 -362880) 362880) (num-test (lcm -362880 -500029) 181450523520) (num-test (lcm -362880 0) 0) (num-test (lcm -362880 1) 362880) (num-test (lcm -362880 10) 362880) (num-test (lcm -362880 1234) 223896960) (num-test (lcm -362880 1234000000) 699678000000) (num-test (lcm -362880 2) 362880) (num-test (lcm -362880 3) 362880) (num-test (lcm -362880 362880) 362880) (num-test (lcm -362880 500029) 181450523520) (num-test (lcm -362880) 362880) (num-test (lcm -500029 -1) 500029) (num-test (lcm -500029 -10) 5000290) (num-test (lcm -500029 -1234) 617035786) (num-test (lcm -500029 -1234000000) 617035786000000) (num-test (lcm -500029 -2) 1000058) (num-test (lcm -500029 -3) 1500087) (num-test (lcm -500029 -362880) 181450523520) (num-test (lcm -500029 -500029) 500029) (num-test (lcm -500029 0) 0) (num-test (lcm -500029 1) 500029) (num-test (lcm -500029 10) 5000290) (num-test (lcm -500029 1234) 617035786) (num-test (lcm -500029 1234000000) 617035786000000) (num-test (lcm -500029 2) 1000058) (num-test (lcm -500029 3) 1500087) (num-test (lcm -500029 362880) 181450523520) (num-test (lcm -500029 500029) 500029) (num-test (lcm -500029) 500029) (num-test (lcm 0 -1) 0) (num-test (lcm 0 -10) 0) (num-test (lcm 0 -1234) 0) (num-test (lcm 0 -1234000000) 0) (num-test (lcm 0 -2) 0) (num-test (lcm 0 -3) 0) (num-test (lcm 0 -362880) 0) (num-test (lcm 0 -500029) 0) (num-test (lcm 0 0 0 10) 0) (num-test (lcm 0 0) 0) (num-test (lcm 0 1) 0) (num-test (lcm 0 10 10 1234) 0) (num-test (lcm 0 10) 0) (num-test (lcm 0 1234 -1234 10) 0) (num-test (lcm 0 1234) 0) (num-test (lcm 0 1234000000) 0) (num-test (lcm 0 2) 0) (num-test (lcm 0 3) 0) (num-test (lcm 0 362880) 0) (num-test (lcm 0 500029) 0) (num-test (lcm 0) 0) (num-test (lcm 1 -1) 1) (num-test (lcm 1 -10) 10) (num-test (lcm 1 -1234) 1234) (num-test (lcm 1 -1234000000) 1234000000) (num-test (lcm 1 -2) 2) (num-test (lcm 1 -3) 3) (num-test (lcm 1 -362880) 362880) (num-test (lcm 1 -500029) 500029) (num-test (lcm 1 0 -1 1) 0) (num-test (lcm 1 0) 0) (num-test (lcm 1 1 2 -10) 10) (num-test (lcm 1 1) 1) (num-test (lcm 1 10) 10) (num-test (lcm 1 1234) 1234) (num-test (lcm 1 1234000000) 1234000000) (num-test (lcm 1 2) 2) (num-test (lcm 1 3) 3) (num-test (lcm 1 362880) 362880) (num-test (lcm 1 500029) 500029) (num-test (lcm 1) 1) (num-test (lcm 1/2 -2) 2) (num-test (lcm 1/2 2) 2) (num-test (lcm 1/21 1/33) 1/3) (num-test (lcm 1/3 1/6 5/12 2) 10) (num-test (lcm 1/3 1/6 5/12) 5/3) (num-test (lcm 1/3 2/3) 2/3) (num-test (lcm 1/3 3/4 5/8) 15) (num-test (lcm 1/3 3/4) 3) (num-test (lcm 10 -1) 10) (num-test (lcm 10 -10) 10) (num-test (lcm 10 -1234) 6170) (num-test (lcm 10 -1234000000) 1234000000) (num-test (lcm 10 -2) 10) (num-test (lcm 10 -3) 30) (num-test (lcm 10 -362880) 362880) (num-test (lcm 10 -500029) 5000290) (num-test (lcm 10 0 10 10) 0) (num-test (lcm 10 0) 0) (num-test (lcm 10 1 -1234 3) 18510) (num-test (lcm 10 1) 10) (num-test (lcm 10 10) 10) (num-test (lcm 10 1234) 6170) (num-test (lcm 10 1234000000) 1234000000) (num-test (lcm 10 2) 10) (num-test (lcm 10 3) 30) (num-test (lcm 10 362880) 362880) (num-test (lcm 10 500029) 5000290) (num-test (lcm 10) 10) (num-test (lcm 1024 9765625) 10000000000) (num-test (lcm 1234 -1) 1234) (num-test (lcm 1234 -10) 6170) (num-test (lcm 1234 -1234) 1234) (num-test (lcm 1234 -1234000000) 1234000000) (num-test (lcm 1234 -2) 1234) (num-test (lcm 1234 -3) 3702) (num-test (lcm 1234 -362880) 223896960) (num-test (lcm 1234 -500029) 617035786) (num-test (lcm 1234 0 -1234 1234) 0) (num-test (lcm 1234 0) 0) (num-test (lcm 1234 1) 1234) (num-test (lcm 1234 10 0 1) 0) (num-test (lcm 1234 10) 6170) (num-test (lcm 1234 1234 1 -10) 6170) (num-test (lcm 1234 1234) 1234) (num-test (lcm 1234 1234000000) 1234000000) (num-test (lcm 1234 2) 1234) (num-test (lcm 1234 3) 3702) (num-test (lcm 1234 362880) 223896960) (num-test (lcm 1234 500029) 617035786) (num-test (lcm 1234) 1234) (num-test (lcm 1234000000 -1) 1234000000) (num-test (lcm 1234000000 -10) 1234000000) (num-test (lcm 1234000000 -1234) 1234000000) (num-test (lcm 1234000000 -1234000000) 1234000000) (num-test (lcm 1234000000 -2) 1234000000) (num-test (lcm 1234000000 -3) 3702000000) (num-test (lcm 1234000000 -362880) 699678000000) (num-test (lcm 1234000000 -500029) 617035786000000) (num-test (lcm 1234000000 0) 0) (num-test (lcm 1234000000 1) 1234000000) (num-test (lcm 1234000000 10) 1234000000) (num-test (lcm 1234000000 1234) 1234000000) (num-test (lcm 1234000000 1234000000) 1234000000) (num-test (lcm 1234000000 2) 1234000000) (num-test (lcm 1234000000 3) 3702000000) (num-test (lcm 1234000000 362880) 699678000000) (num-test (lcm 1234000000 500029) 617035786000000) (num-test (lcm 1234000000) 1234000000) (num-test (lcm 131072 762939453125) 100000000000000000) (num-test (lcm 14 35) 70) (num-test (lcm 1741 2063 3137 3797 3251 3 19) 7927658615618708709) (num-test (lcm 2 -1) 2) (num-test (lcm 2 -10) 10) (num-test (lcm 2 -1234) 1234) (num-test (lcm 2 -1234000000) 1234000000) (num-test (lcm 2 -2) 2) (num-test (lcm 2 -3) 6) (num-test (lcm 2 -362880) 362880) (num-test (lcm 2 -500029) 1000058) (num-test (lcm 2 0 2 -2) 0) (num-test (lcm 2 0) 0) (num-test (lcm 2 1 -3 -1) 6) (num-test (lcm 2 1) 2) (num-test (lcm 2 10) 10) (num-test (lcm 2 1234) 1234) (num-test (lcm 2 1234000000) 1234000000) (num-test (lcm 2 2 10 10) 10) (num-test (lcm 2 2) 2) (num-test (lcm 2 3) 6) (num-test (lcm 2 3/4) 6) (num-test (lcm 2 362880) 362880) (num-test (lcm 2 500029) 1000058) (num-test (lcm 2) 2) (num-test (lcm 262144 3814697265625) 1000000000000000000) (num-test (lcm 3 -1) 3) (num-test (lcm 3 -10) 30) (num-test (lcm 3 -1234) 3702) (num-test (lcm 3 -1234000000) 3702000000) (num-test (lcm 3 -2) 6) (num-test (lcm 3 -3) 3) (num-test (lcm 3 -362880) 362880) (num-test (lcm 3 -500029) 1500087) (num-test (lcm 3 0 -3 -3) 0) (num-test (lcm 3 0) 0) (num-test (lcm 3 1 10 2) 30) (num-test (lcm 3 1) 3) (num-test (lcm 3 10) 30) (num-test (lcm 3 1234) 3702) (num-test (lcm 3 1234000000) 3702000000) (num-test (lcm 3 2 -1234 1) 3702) (num-test (lcm 3 2) 6) (num-test (lcm 3 3) 3) (num-test (lcm 3 362880) 362880) (num-test (lcm 3 500029) 1500087) (num-test (lcm 3) 3) (num-test (lcm 3/4 2) 6) (num-test (lcm 32 -36) 288 ) (num-test (lcm 323 28747 27113) 41021969) (num-test (lcm 362880 -1) 362880) (num-test (lcm 362880 -10) 362880) (num-test (lcm 362880 -1234) 223896960) (num-test (lcm 362880 -1234000000) 699678000000) (num-test (lcm 362880 -2) 362880) (num-test (lcm 362880 -3) 362880) (num-test (lcm 362880 -362880) 362880) (num-test (lcm 362880 -500029) 181450523520) (num-test (lcm 362880 0) 0) (num-test (lcm 362880 1) 362880) (num-test (lcm 362880 10) 362880) (num-test (lcm 362880 1234) 223896960) (num-test (lcm 362880 1234000000) 699678000000) (num-test (lcm 362880 2) 362880) (num-test (lcm 362880 362880) 362880) (num-test (lcm 362880 500029) 181450523520) (num-test (lcm 362880) 362880) (num-test (lcm 4242884/3 1907348632815/7) 8092658996592638460) (num-test (lcm 500029 -1) 500029) (num-test (lcm 500029 -10) 5000290) (num-test (lcm 500029 -1234) 617035786) (num-test (lcm 500029 -1234000000) 617035786000000) (num-test (lcm 500029 -2) 1000058) (num-test (lcm 500029 -3) 1500087) (num-test (lcm 500029 -362880) 181450523520) (num-test (lcm 500029 -500029) 500029) (num-test (lcm 500029 0) 0) (num-test (lcm 500029 1) 500029) (num-test (lcm 500029 10) 5000290) (num-test (lcm 500029 1234) 617035786) (num-test (lcm 500029 1234000000) 617035786000000) (num-test (lcm 500029 2) 1000058) (num-test (lcm 500029 3) 1500087) (num-test (lcm 500029 362880) 181450523520) (num-test (lcm 500029 500029) 500029) (num-test (lcm 500029) 500029) (num-test (lcm 524288 -17500000000001) 9175040000000524288) (num-test (lcm 524288 17500000000001) 9175040000000524288) (num-test (lcm 524288/3 1907348632815/7) 1000000000001310720) (num-test (lcm) 1 ) (num-test (lcm) 1) (num-test (lcm 2755 13) 35815) (num-test (lcm 56 2) 56) (num-test (lcm 148665 2) 297330) (num-test (lcm 71862 203) 71862) (num-test (lcm 21568911 41) 21568911) (num-test (lcm 15295874 111) 45887622) (num-test (lcm 20430054 41) 20430054) (num-test (lcm 248255254 767) 14647059986) (num-test (lcm 510104442 5453) 2781599522226) (num-test (lcm 242162410 41) 9928658810) (num-test (lcm 660070972 74) 660070972) (num-test (lcm 6542405452 117) 765461437884) (num-test (lcm 629448534 2) 629448534) (num-test (lcm 163873565922 155) 819367829610) (num-test (lcm 1563464979842 442) 20325044737946) (num-test (lcm 3712337724 576173) 92997772323924) (num-test (lcm 4380921044390 5) 4380921044390) (num-test (lcm 4097970629150 86) 176212737053450) (num-test (lcm 2090198664 1118) 1168421053176) (num-test (lcm 5275411661289 31857) 8002799490175413) (num-test (lcm 38602581835881 19) 733449054881739) (num-test (lcm 82578867500655 319) 908367542507205) (num-test (lcm 363169800 20) 363169800) (num-test (lcm 2033404107084 23374) 23764393799490708) (num-test (lcm 7438317458260 31213) 17859400217282260) (num-test (lcm 390609000 11) 4296699000) (num-test (lcm 406117800 57) 7716238200) (num-test (lcm 1008217762344 4403) 119977913718936) (num-test (lcm 136581511784536 67022) 147644614239083416) (num-test (lcm 43293168048 1344610) 29106213344510640) (num-test (lcm 608503422693864 47) 608503422693864) (num-test (lcm 6945109296864 779) 284749481171424) (num-test (lcm 1346702251365156 435) 6733511256825780) (num-test (lcm 1388225063690465 644) 127716705859522780) (num-test (lcm 1200780158492850 91686) 311002061049648150) (num-test (lcm 1551193257090906 2656731) 2356262557521086214) (num-test (lcm 386512944051107445 17) 386512944051107445) (num-test (lcm 1111364125679340 6) 1111364125679340) (num-test (lcm 15858537083857314 21793) 15858537083857314) (num-test (lcm 44179338013272 280645) 302407568700846840) (num-test (lcm 64149298745840 43808357) 79994175536062480) (num-test (lcm 4412914630225794 515823) 48542060932483734) (num-test (lcm 169216424701305960 17) 2876679219922201320) (num-test (lcm 178335507754891305 817) 178335507754891305) (num-test (lcm 10400200/16483927 1607521/1136689) (/ (* 10400200/16483927 1607521/1136689) (gcd 10400200/16483927 1607521/1136689))) (num-test (lcm 10781274/17087915 3880899/2744210) (/ (* 10781274/17087915 3880899/2744210) (gcd 10781274/17087915 3880899/2744210))) (num-test (lcm 12/19 41/29) (/ (* 12/19 41/29) (gcd 12/19 41/29))) (num-test (lcm 12941/20511 3363/2378) (/ (* 12941/20511 3363/2378) (gcd 12941/20511 3363/2378))) (num-test (lcm 15601/24727 19601/13860) (/ (* 15601/24727 19601/13860) (gcd 15601/24727 19601/13860))) (num-test (lcm 171928773/272500658 54608393/38613965) (/ (* 171928773/272500658 54608393/38613965) (gcd 171928773/272500658 54608393/38613965))) (num-test (lcm 190537/301994 114243/80782) (/ (* 190537/301994 114243/80782) (gcd 190537/301994 114243/80782))) (num-test (lcm 2/3 3/2) (/ (* 2/3 3/2) (gcd 2/3 3/2))) (num-test (lcm 253/401 577/408) (/ (* 253/401 577/408) (gcd 253/401 577/408))) (num-test (lcm 397573379/630138897 131836323/93222358) (/ (* 397573379/630138897 131836323/93222358) (gcd 397573379/630138897 131836323/93222358))) (num-test (lcm 4201378396/6659027209 318281039/225058681) (/ (* 4201378396/6659027209 318281039/225058681) (gcd 4201378396/6659027209 318281039/225058681))) (num-test (lcm 5/8 17/12) (/ (* 5/8 17/12) (gcd 5/8 17/12))) (num-test (lcm 53/84 99/70) (/ (* 53/84 99/70) (gcd 53/84 99/70))) (num-test (lcm 53715833/85137581 9369319/6625109) (/ (* 53715833/85137581 9369319/6625109) (gcd 53715833/85137581 9369319/6625109))) (num-test (lcm 665/1054 1393/985) (/ (* 665/1054 1393/985) (gcd 665/1054 1393/985))) (num-test (lcm 7161071/11350029 275807/195025) (/ (* 7161071/11350029 275807/195025) (gcd 7161071/11350029 275807/195025))) (num-test (lcm 79335/125743 47321/33461) (/ (* 79335/125743 47321/33461) (gcd 79335/125743 47321/33461))) (num-test (lcm -2305843009213693951/4611686018427387903) 2305843009213693951/4611686018427387903) (let () (define (flcm n) (if (<= n 1) 1 (lcm n (flcm (- n 1))))) (num-test (flcm 9) 2520) (num-test (flcm 40) 5342931457063200) (if with-bignums (num-test (flcm 100) 69720375229712477164533808935312303556800))) (if with-bignums (begin (num-test (let ((n 1)) (do ((i 2 (+ i 1))) ((= i 100)) (set! n (lcm n i))) n) 69720375229712477164533808935312303556800) (num-test (lcm -9223372036854775808 -9223372036854775808) 9223372036854775808) (num-test (lcm -9223372036854775808 9223372036854775807 -9223372036854775808) 85070591730234615856620279821087277056) (num-test (lcm 1/21 1/2432902008176640001) 1) (num-test (lcm 132120577 33292289 260046847) 1143841133453061178785791) (num-test (lcm 132120577 33292289) 4398596432330753) (num-test (lcm 132120577/12 33292289/6 260046847/4) 1143841133453061178785791/2) (num-test (lcm 2/132120577 3/33292289 4/260046847) 12) (num-test (lcm 21 2432902008176640001) 51090942171709440021) (num-test (lcm 2353913150770005286438421033702874906038383291674012942337 9641628265553941653251772554046975615133217962696757011808257) 22695555569123220026272727097682721551725929819788097280747860983024240452040931523149698041303750665450606153441476609) (num-test (lcm 2432902008176640001 21) 51090942171709440021) (num-test (lcm 2432902008176640001/21 21/2432902008176640001) 51090942171709440021) (num-test (lcm 557057 23068673 167772161) 2155967190204955525121) (num-test (lcm 9223372036854775807 -9223372036854775808) 85070591730234615856620279821087277056) (num-test (lcm 524288 19073486328125) 10000000000000000000) (num-test (lcm 2147483648 4656612873077392578125) 10000000000000000000000000000000) (num-test (lcm (/ (expt 2 57) 3) (/ 65 11)) 9367487224930631680) (num-test (lcm 460683358924445799142 518) 460683358924445799142) (num-test (lcm 113021475230160 74635) 1243236227531760) (num-test (lcm 74228340534140364 363909) 16107549895908458988) (num-test (lcm 69242022961311060 48305942) 55324376346087536940) (num-test (lcm 286967952870300 2273388) 4181983977178881900) (num-test (lcm 302822258393413362492399 29) 302822258393413362492399) (num-test (lcm 10491072879382200 133) 10491072879382200) (num-test (lcm 167206737423420464 609) 14546986155837580368) (num-test (lcm 72212583812867784 4888799) 7511336330463068288328) (num-test (lcm 4170116471639397292390 1798025) 20850582358196986461950) (num-test (lcm 83910330283522050 35224) 12418728881961263400) (num-test (lcm 275373383775647594346 66884092) 175688218848863165192748) (num-test (lcm 14656657495570695990 37) 542296327336115751630) (num-test (lcm 95470974177676509874110 1219) 95470974177676509874110) (num-test (lcm 619506317623001424 5957) 527199876297174211824) (num-test (lcm 11268171656665155960 9858) 597213097803253265880) (num-test (lcm 6172860073826160 5167394) 10376577784101774960) (num-test (lcm 26457493095663264 1491412) 9974474897065050528) (num-test (lcm 8481384175941103284 313836405) 52191512141200849929103020) (num-test (lcm 60356595775749199080 176098815946) 6192647083187643574807080) (num-test (lcm 611492274956002440 37) 611492274956002440) (num-test (lcm 164614611843685080 1711) 4773823743466867320) (num-test (lcm 93177516542679418720 62197) 156631405308244102868320) (num-test (lcm 938959746797519770440 127558) 938959746797519770440) (num-test (lcm 137670522526899326250 200) 550682090107597305000) (num-test (lcm 852063402206742880 41643478) 607521205773407673440) (num-test (lcm 55947291202307909360 188546228) 1657550396450776430608720) (num-test (lcm 12877971214039423262680 9832253830) 1040166612929178256349926280) (num-test (lcm 192158415774146059920 53) 192158415774146059920) (num-test (lcm 902814024155808960 1829) 53266027425192728640) (num-test (lcm 1265864304573235487120 4921) 24051421786891474255280) (num-test (lcm 14172662463567665400 95817) 23824245601257245537400) (num-test (lcm 32171996211745702482324 2368555) 294212905356414449200852980) (num-test (lcm 971324258606045826300 4576748) 18836891347147046709435900) (num-test (lcm 2400649320046378377000 1704690) 4400390203645011565041000) (num-test (lcm 953233796456393760 18342152493) 30445334225020760300640) (num-test (lcm 28906333140964843080 236206740) 8296117611456909963960) (num-test (lcm 775403093708557121609032 41) 775403093708557121609032) (num-test (lcm 12587009808135760402860 2491) 667111519831195301351580) (num-test (lcm 510685807527370566909720 76) 9703030343020040771284680) (num-test (lcm 9842598153710524682146590 10089) 29527794461131574046439770) (num-test (lcm 44936631038618189620242012 30740) 224683155193090948101210060) (num-test (lcm 934589372977008750144 373650) 1238330919194536593940800) (num-test (lcm 33027125273398900134069150 840577803) 33027125273398900134069150) (num-test (lcm 4428219127938822420288 1695783782) 600648070732749811910284608) (num-test (lcm 29316428815807608915440 560764380) 107210180179408425803764080) (num-test (lcm 1364397376360544429904 19) 1364397376360544429904) (num-test (lcm 4991450791697293128313385277 329) 234598187209772777030729108019) (num-test (lcm 75448279792981695149550 3009) 75674624632360640234998650) (num-test (lcm 181031604499464166188731133 3364) 608990317536197455058891531412) (num-test (lcm 405831142402606479845286 2746214) 6899129420844310157369862) (num-test (lcm 89170366469003867207160 25337230) 196977339530029542660616440) (num-test (lcm 13523725766340619200 1490114045) 704734873409776007131200) (num-test (lcm 104705939487154940255412 192200052) 768227478017255796653957844) (num-test (lcm 7232591421499800642000 16584679460) 15338901584491041700955526000) (num-test (lcm 14043796716396386984750160 33382708236) 1306073094624863989581764880) (num-test (lcm 13894638105872256412416 23) 13894638105872256412416) (num-test (lcm 147611447155643499428400 118) 8709075382182966466275600) (num-test (lcm 13356594697070649024 4558) 574333571974037908032) (num-test (lcm 15089731174706036171537760 90) 45269193524118108514613280) (num-test (lcm 307230141273924828960 1971507) 383115986168584261713120) (num-test (lcm 2582563944548247741930009096 22873474) 33573331279127220645090118248) (num-test (lcm 1074296602920111687342072 146235518) 7220347468226070650626065912) (num-test (lcm 774058642832724262993980 407557010) 124623441496068606342030780) (num-test (lcm 291091930213008490369569480 13412544348) 147286985941108248965685135059880) (num-test (lcm 2089068565149831833568 7302038455228) 223766401218893937188969184) (num-test (lcm 1064437567441124038217970656 5) 5322187837205620191089853280) (num-test (lcm 142557826750459447787460 1333) 6129986550269756254860780) (num-test (lcm 311779340580033594160200 23693) 311779340580033594160200) (num-test (lcm 29314187023691666530559664 110143) 29314187023691666530559664) (num-test (lcm 222003853016244177637944900 857463) 222003853016244177637944900) (num-test (lcm 6247776111945111006243552 77976501) 193681059470298441193550112) (num-test (lcm 1140058514761397155259712 5530338) 12540643662375368707856832) (num-test (lcm 580962736822969724865449808 55686036) 21495621262449879820021642896) (num-test (lcm 4100502596989506786787500 45333475410) 329750117342105167273090387500) (num-test (lcm 1497378750311599979536944 262630276090) 1089215763657912499114866119760) (num-test (lcm 105637634198318524045536 2633013240) 1853412292009498504378929120) (num-test (lcm 11415822547029425161364106595632 7) 79910757829205976129548746169424) (num-test (lcm 198305933339312916107438448 177) 11700050067019462050338868432) (num-test (lcm 3127415425979879537134790928 3335) 15637077129899397685673954640) (num-test (lcm 589703503861221139260034914750 13209) 21819029642865182152621291845750) (num-test (lcm 3108579252052448504121792 14322) 96365956813625903627775552) (num-test (lcm 636976201153021006473464400 66264077) 12102547821907399122995823600) (num-test (lcm 9544425315508129998909285900 1488396) 66810977208556909992365001300) (num-test (lcm 458100280193857502802977376 260747103934) 19226926860016393250143763448096) (num-test (lcm 114208186302155358124900650 22076867505) 397558696517802801632779162650) (num-test (lcm 90107067439719108194114160 28566806069714) 755187332212285845774870774960) (num-test (lcm 2976572787365723002218245484 110104803958578) 110463592711929346335321308156724) (num-test (lcm 53453375725613238735360 17) 908707387335425058501120) (num-test (lcm 888822833524306124874229800 106) 888822833524306124874229800) (num-test (lcm 21275338550698297089687698855820 3021) 21275338550698297089687698855820) (num-test (lcm 417525245705449941528380320750068 5828) 417525245705449941528380320750068) (num-test (lcm 1954871230146370370001829871352 22765249) 1954871230146370370001829871352) (num-test (lcm 903057827710908645847577520 648545995) 1126113111155503081371929167440) (num-test (lcm 6002846634833433581621040 28493572159) 6137376430766685661618749127440) (num-test (lcm 26428903214964558277189300080 100428856) 766438193233972190038489702320) (num-test (lcm 470486531607553676511206181180 28495896) 4523257514875021045978736225864520) (num-test (lcm 483599554429365539310928369206620 5577334078910) 25630776384756373583479203567950860) (num-test (lcm 134511400157705323668887400 1285071093558916) 508298000951744289230204144827800) (num-test (lcm 25897125642468049125349982599216 1183846707540) 1165370653911062210640749216964720) (num-test (lcm 1118034209930460291955200 3) 1118034209930460291955200) (num-test (lcm 16297594064835666104344589410644 413) 16297594064835666104344589410644) (num-test (lcm 536762539932642345554192060100 1378) 536762539932642345554192060100) (num-test (lcm 933250179448203335817687635834340 58029) 784863400915939005422675301736679940) (num-test (lcm 65573457048202714607131200 486115) 8721269787410961042748449600) (num-test (lcm 85664559165674439863772868932 322014) 85664559165674439863772868932) (num-test (lcm 7232817686074320060728552759760 11307940) 7232817686074320060728552759760) (num-test (lcm 78400098291720425971762131120 5646921093) 78400098291720425971762131120) (num-test (lcm 345445746644065669842240 19727989065) 3106593599570082568891264320) (num-test (lcm 627854758484491743169777558200 750371721805653) 3013801413922642432418609934436637400) (num-test (lcm 788233263079483492974876830792850 7170146100) 963221047483128828415299487228862700) (num-test (lcm 18378856389802641496737518160 6247594493140) 139293352578314219903773650134640) (num-test (lcm 9620902642431357480148667659080 59) 9620902642431357480148667659080) (num-test (lcm 16008524600631853118144316000 629) 10069361973797435611312774764000) (num-test (lcm 4342138447708715023205684275423920 53041) 134606291878970165719376212538141520) (num-test (lcm 2431833161592653384508687244500 47541) 2431833161592653384508687244500) (num-test (lcm 39424620224103957589082132160 1671734) 39424620224103957589082132160) (num-test (lcm 652830233576052788654372406432 552231327) 28071700043770269912138013476576) (num-test (lcm 6892963340916411083970414000 3662431431) 323969277023071320946609458000) (num-test (lcm 29102758215190063506219566460000 10565720) 29102758215190063506219566460000) (num-test (lcm 21253900104556838003127171970777418412 1182797770) 400954825472464748928994099228715998342380) (num-test (lcm 3964268932242030284914943132662620 21244177854110) 4547016465281608736797439773164025140) (num-test (lcm 6070388091189460078138338240 40809131994181213) 903741167852013248053001382156480) (num-test (lcm 9685989954133695108793384134000 964113514382876) 55084224869158324083707975570058000) (num-test (lcm 56468122001858834917195045500 429400787158167902) 11597366428619765656458601249744500) (num-test (lcm 18843408973202596901221568364900 47) 18843408973202596901221568364900) (num-test (lcm 7800980538292163259967028613764250 6) 7800980538292163259967028613764250) (num-test (lcm 270433907726619219545089642715200 3422) 15955600555870533953160288920196800) (num-test (lcm 45771666919597903071546708768 2342359) 49112998604728549995769618508064) (num-test (lcm 47198294949461301503537593835384892 314502) 2501509632321448979687492473275399276) (num-test (lcm 3165335901519110207943908102359110 14953473) 228660700189839002311659977406319747290) (num-test (lcm 189219585097956261544520863361400 35605794) 189219585097956261544520863361400) (num-test (lcm 38532137569034426600955256933810890813 1341358608707) 8030213065799481606918878410776991078101639) (num-test (lcm 1396277868664090735481380981225896 312520860) 6981389343320453677406904906129480) (num-test (lcm 864038349500762576564773759109700 714136202724) 37153649028532790792285271641717100) (num-test (lcm 12514185871591242579049167322464 10706997440178) 667894614152696207686433109167226144) (num-test (lcm 1981802660405609330969478067056636 33312289752) 4466983196554243432005203563145657544) (num-test (lcm 979313401024175219420658240 125278417383795) 79100122714123656647825986703040) (num-test (lcm 4074026154111369481048033354344 29) 4074026154111369481048033354344) (num-test (lcm 599666571180604695702511920885005100 129) 599666571180604695702511920885005100) (num-test (lcm 5703263639326551702474610108800 1978) 5703263639326551702474610108800) (num-test (lcm 134137932950214683609064669163440 190619) 178805864622636173250883203994865520) (num-test (lcm 344735091370772631136645455600 1048985) 344735091370772631136645455600) (num-test (lcm 6759508339299085316106145385400 4969610) 209544758518271644799290506947400) (num-test (lcm 700334422308861928135313594400 228529587) 370476909401387959983580891437600) (num-test (lcm 10277417891211405957191810814198480 2516552038) 113051596803325465529109918956183280) (num-test (lcm 490099971577877358878082782880 9282588354) 259262884964697122846505792143520) (num-test (lcm 1954558750269048828645390249600 5575829490) 33227498754573830086971634243200) (num-test (lcm 1360588454560018295496656378989200 7868178296420) 719751292462249678317731224485286800) (num-test (lcm 4337552841738910859248770564912480 17722936528737830) 227361507305428490509242806701017464160) (num-test (lcm 215913068853045803981566931862756 7009479781500) 516383093295665670947415013416263818500) (num-test (lcm 44890707654126305940250882318870941900 18329973480720) 538688491849515671283010587826451302800) (num-test (lcm 28579720891831355496720656680837200 3) 28579720891831355496720656680837200) (num-test (lcm 29332703209780553199747293473184160 1711) 1730629489377052638785090314917865440) (num-test (lcm 3648979393315349438003046604440000 186) 3648979393315349438003046604440000) (num-test (lcm 1159760236369472473822068077011807878780 25714) 1159760236369472473822068077011807878780) (num-test (lcm 158186359726371025615685433600 31395) 1107304518084597179309798035200) (num-test (lcm 331091450443070201468559735703944 28424) 331091450443070201468559735703944) (num-test (lcm 9734443639363161342241553023288200 1961348207) 301767752820258001609488143721934200) (num-test (lcm 701896612128009033011419603540080 51300) 10528449181920135495171294053101200) (num-test (lcm 86169288128517384618860929451245320 5032162527446) 2406794386717619069789404620502733032920) (num-test (lcm 64828800524794653881296183831741773624 4645294472) 47389853183624891987227510381003236519144) (num-test (lcm 49068907706533938991402184550000 268183371225) 17713875682058751975896188622550000) (num-test (lcm 1708602980304476478496020543612288 4083128544) 52966692389438770833376636851980928) (num-test (lcm 17608179287674151740172985536160 980399424528) 188284261123099704557669734338158880) (num-test (lcm 43194437079731225735521919644800 178119261126453036) 95416511509126277649767920495363200) (num-test (lcm 817555977437791699707628651571149344 59) 817555977437791699707628651571149344) (num-test (lcm 19062946261334997559157066059536 533) 247818301397354968269041858773968) (num-test (lcm 6533849124840489114353090499099000 598) 150278529871331249630121081479277000) (num-test (lcm 427663965127849896842400211428345149025 234) 855327930255699793684800422856690298050) (num-test (lcm 352395507261316174741530450071590608 154734) 14448215797713963164402748452935214928) (num-test (lcm 391579493632653867660919800000 9221565) 5598412020466052345948170380600000) (num-test (lcm 2618798923882923048581401148931738000 681876) 34044386010477999631558214936112594000) (num-test (lcm 174712575449141140214591110997980800 233260339838) 323043552005461968256778964235266499200) (num-test (lcm 88598141227372995032227898284800 1929763976) 1101009101032564209265496091985209600) (num-test (lcm 210110141308655567793064872567302676320 720390430628) 322939287191403607697940709135944213503840) (num-test (lcm 668425085137718599277317523827419000 19898594339442) 226544635130131000822866287128160329737000) (num-test (lcm 89533471731097208414073727453200 4173840860670546) 165547389230798738357622322060966800) (num-test (lcm 113987439157802480362236410675251462620 21548296273949445) 2165761343998247126882491802829777789780) (num-test (lcm 48129335993995093308894209644253760 1009442888504820) 572305934304595654536061046879821460160) (num-test (lcm 3497836376962291922989777163497680 138736290091634664) 143411291455453968842580863703404880) (num-test (lcm 11371924962562208722154622794880 3) 11371924962562208722154622794880) (num-test (lcm 9451631862008339290824315653784000 703) 349710378894308553760499679190008000) (num-test (lcm 16869347753325980368094612370435598560 806) 16869347753325980368094612370435598560) (num-test (lcm 4701845646467068759127854100132739552 3198) 2506083729566947648615146235370750181216) (num-test (lcm 1029865193584911347147121232800485280 1005771) 42224472936981365233031970544819896480) (num-test (lcm 10657125216930337802109861408000 2415138) 9069213559607717469595492058208000) (num-test (lcm 14382707743772734802155022983680 247913634) 24608812949595149246487244325076480) (num-test (lcm 60134748581470366378101904574533857248 54828228) 6674957092543210667969311407773258154528) (num-test (lcm 214830664120540781167218700750596000 505665810) 9237718557183253590190404132275628000) (num-test (lcm 48933004118344447687599112101802800 6263883444) 2887047242982322413568347614006365200) (num-test (lcm 5498670161558110606435630054129739400 262699548132) 1072697071127240891435282017849791951370200) (num-test (lcm 35941673649029587182509620977230062500 25622409466332) 1752120648716543345560161513018988316812500) (num-test (lcm 1592802602494326390643157055239113248 736377633395508) 1221679596113148341623301461368399861216) (num-test (lcm 4043816553144402557587143272522043028314 5011466158645380) 55359848612546871013367991400826769057618660) (num-test (lcm 7171921165220830707276631005512550 1765284492289500) 71719211652208307072766310055125500) (num-test (lcm 2402189359210218692854826119405968750 23) 55250355261835029935661000746337281250) (num-test (lcm 26149068753160488131648964110990162400 1147) 967515543866938060871011672106636008800) (num-test (lcm 556184059176863945810376239306506311552 4089) 556184059176863945810376239306506311552) (num-test (lcm 67871323087036310486238021899264593800 13395) 67871323087036310486238021899264593800) (num-test (lcm 12750401179065252879838440979200 7177173) 12750401179065252879838440979200) (num-test (lcm 278110245000092733617125071646080 17748) 278110245000092733617125071646080) (num-test (lcm 13408203364935178481017292708752000 50619404) 496103524502601603797639830223824000) (num-test (lcm 124271828931784534297423756437875067000 8839796595) 270042684268767793028301822739502520591000) (num-test (lcm 11893442806922081156953529319100769836176 972789007267) 11762614936045938264227040496590661367978064) (num-test (lcm 352581052555284857902053030133344488264100 923561430099) 5993877893439842584334901512266856300489700) (num-test (lcm 6108908012714804315575319947340956346976 31944833628092) 2009830736183170619824280262675174638155104) (num-test (lcm 67475643422116264959949054821520228800 22515435540) 4655819396126022282236484782684895787200) (num-test (lcm 470601888939348535946408832 5135943991060962937) 65492053197870222825732159796881558144) (num-test (lcm 110759232155568113345545635903016614000 30159198663300) 110759232155568113345545635903016614000) (num-test (lcm 146100914712024458707469587112300146320 26868173101560) 380954774790565399517176676594819048626034640) (num-test (lcm 12173192708601511002951184416658091200 466645866900785428350) 3795589313349242529209176349929576178068800) (num-test (lcm 5784684831478746253226687170890240 13) 5784684831478746253226687170890240) (num-test (lcm 35042260655085685815432622412891903767500 667) 35042260655085685815432622412891903767500) (num-test (lcm 2903871349270676921837488659419545120987500 530) 2903871349270676921837488659419545120987500) (num-test (lcm 630123969240840167098426767919876491188000 77691) 1890371907722520501295280303759629473564000) (num-test (lcm 33192703032132982013024959634241667249800 4684718) 1228130012188920334481923506466941688242600) (num-test (lcm 4731525733734729472809717145544850000 90706055) 4731525733734729472809717145544850000) (num-test (lcm 214011009809686092216200126896120006823232 50400042) 41806836755312368428342478589030147212911547968) (num-test (lcm 5854250735296111435541950856160000 24357777002) 174403983655206455776230257955862560000) (num-test (lcm 35348208247612761916374738259136697649608 156806713508) 644786666644704390116591600584912501826499528) (num-test (lcm 612558317420289618714916924536521515286100 2377007388) 11638608030985502755583421566193908790435900) (num-test (lcm 181857299802925368992522029882739454720 21606337755618) 181857299802925368992522029882739454720) (num-test (lcm 4731635341196946327443020710970699860000 58092526675092) 354167636923932629555437543236867855220860000) (num-test (lcm 22081740554432638182773611616166588288192 61419768950540) 110408702772163190913868058080832941440960) (num-test (lcm 125627844706077784535328068665849312000 30482033400) 118925222307474416497014710218320253656864000) (num-test (lcm 1225504716872819103560254268197955520 510813364186125) 3707151768540277788269769161298815448000) (num-test (lcm 5209185280578468690281136425214396728400 2327880739319250103818) 14624765850878700374498228867533344237423825059372400) (num-test (lcm 230425011604643097634961294406535254400 31) 230425011604643097634961294406535254400) (num-test (lcm 13222608481676137093434201748083744000 893) 13222608481676137093434201748083744000) (num-test (lcm 13348198818240350339028224064019716678960 651) 2896559143558156023569124621892278519334320) (num-test (lcm 7236172685650198160266777676385295337308176 23426) 383517152339460502494139216848420652877333328) (num-test (lcm 756264162229440667711265021676693350760 28899) 756264162229440667711265021676693350760) (num-test (lcm 40915062421030872924283823601517905600 36345062) 40915062421030872924283823601517905600) (num-test (lcm 1174590526522170015825602834292923520 4991486258) 40402390340783082034353260691173690317440) (num-test (lcm 2891892862328155581145450075391651333218020 35138529818) 2891892862328155581145450075391651333218020) (num-test (lcm 1993335355070485984559797658834121810059400 535644500) 408633747789449626834758520060994971062177000) (num-test (lcm 6324295450641455215591954662726515160 367472693133) 259296113476299663839270141171787121560) (num-test (lcm 6576388154814679090356195121505112000 15901952377630) 107846189350805922402751243797562331688000) (num-test (lcm 117828556355409428513249595788296238400 565992666495795) 2013191495492007395999396032982202432871329600) (num-test (lcm 592831716700236607285748949860604000 139641978135660) 241282508696996299165299822593265828000) (num-test (lcm 106766839071170184723986891291602032000 1584924526628112) 85306704417864977594465526141990023568000) (num-test (lcm 21677148858122146832326483307664860804937400 247815827510760) 585283019169297964472815049306951241733309800) (num-test (lcm 14079549844487257384278196623697173813600 160967604100961853832) 52755411528451062517793341673751996512389960800) (num-test (lcm 2696480372014145687016224877963234647656980 2219319031453896088860) 4753894895860938846209604459849182683819255740) (num-test (lcm 13545431257849875145060979241270859310160 29) 13545431257849875145060979241270859310160) (num-test (lcm 137485634482479300158725199474868559498162500 329) 962399441377355101111076396324079916487137500) (num-test (lcm 529252417743761759027305009539254400 3243) 529252417743761759027305009539254400) (num-test (lcm 133897419738958073238580385894509887148800 330455) 133897419738958073238580385894509887148800) (num-test (lcm 3896215507210178905244623173635584334007288624 1005238) 3896215507210178905244623173635584334007288624) (num-test (lcm 17654511984514518592175290794029073043800 1060530) 511980847550921039173083433026843118270200) (num-test (lcm 16470780256339082688310222474503880382858400 913836) 16470780256339082688310222474503880382858400) (num-test (lcm 57267105834722825210001789897760395576000 2958974018) 2691553974231972784870084125194738592072000) (num-test (lcm 521977833444747522001426544601807810543216 1066521690) 112225234190620717230306707089388679266791440) (num-test (lcm 1699559962174727325529414216960251941390400 25883611479) 1422531688340246771468119699595730874943764800) (num-test (lcm 10654036597801063717295948399628964800 317449894126222) 176036646705466975800880955407069385390400) (num-test (lcm 381902381115592200811990304316262139150724960 4640335440216) 381902381115592200811990304316262139150724960) (num-test (lcm 425968526187959807410151867411382902838703889232 1882826315615025) 181036623629882918149314543649837733706449152923600) (num-test (lcm 174609167728518272531601927200939868792000 1712923655178450) 48325242369824705024158690915447549888986499656000) (num-test (lcm 3325168366561555458817274989681612518000 1699726139891780) 43227188765300220964624574865860962734000) (num-test (lcm 11429650426242566426919762928176000 7414967839104) 15647191433526073438453155448672944000) (num-test (lcm 2104794191230056678355480848036599377844400 16946684823025584) 195745859784395271087059718867403742139529200) (num-test (lcm 11894522530167763519415142641640874994880 7) 11894522530167763519415142641640874994880) (num-test (lcm 5906329981690378696996009087718418780000 185) 5906329981690378696996009087718418780000) (num-test (lcm 3056294774178096513474941936265025440000 658) 3056294774178096513474941936265025440000) (num-test (lcm 10491907660880423349353457742257185280 123369) 10491907660880423349353457742257185280) (num-test (lcm 673239479595593149777212259021965839229225628776 15470) 3366197397977965748886061295109829196146128143880) (num-test (lcm 1506608574369860432616005754109397877696 1474070) 7533042871849302163080028770546989388480) (num-test (lcm 4849814041048623250005708880379694793905000 2172220582) 4849814041048623250005708880379694793905000) (num-test (lcm 21154344928580705924176101470087564940000 5023204186) 21154344928580705924176101470087564940000) (num-test (lcm 346448039376394135288065831861806112294000 776147372) 10739889220668218193930040787715989481114000) (num-test (lcm 2339009760844587560470606952218133142645504 194201967414) 86543361151249739737412457232070926277883648) (num-test (lcm 2242982161480922111384667548175169152 21419749763490) 20736370082891124919751251482879438810240) (num-test (lcm 4717315265246821759830981157482117120 45609714193992) 8203411246264223040346076232861401671680) (num-test (lcm 16628111321698075419789804224660024289936 4643626415880804) 46708364702649893854189560067070008230430224) (num-test (lcm 115557531507210992033160068979962880 88406536976058378) 279533668715943389728214206862530206720) (num-test (lcm 21059511907771200155093927745003762840000 180298981648603620) 19859119729028241746253573863538548358120000) (num-test (lcm 2124921015128697258800067298086064536000 2282525112298516782924) 321127237090271040335932409977291910220921912000) (num-test (lcm 16015671538624533047089928322348864000 49817926936366875) 11550742548729092601556962655002835949760000) (num-test (lcm 166517667014186289390514558017250969134523800 43413708621878528404068) 6080725646357040729673420115115953639885405604600) (num-test (lcm 2780796292789128359666429021610464935722000 47) 2780796292789128359666429021610464935722000) (num-test (lcm 21297913114430245153455383503409684916193317960 58) 21297913114430245153455383503409684916193317960) (num-test (lcm 1516745257039775143654568869485529015398000 6293) 1516745257039775143654568869485529015398000) (num-test (lcm 8447692776411453120390905608381515479808 2030) 1224915452579660702456681313215319744572160) (num-test (lcm 958876033949638283967045624731391031146081240 9834415) 56573686003028658754055691859152070837618793160) (num-test (lcm 4731349833403602529573388098680617532624192 14868) 4731349833403602529573388098680617532624192) (num-test (lcm 6375001358038970462026761077388061675464000 430513678) 6375001358038970462026761077388061675464000) (num-test (lcm 254088526608579040642428151389718385042344800 4799428101) 4774577503501808752711867392764198173330701136800) (num-test (lcm 21140490542258031885408065086507444825621023648 164778747198) 264108148344429592344402957125737508206483448434464) (num-test (lcm 34214837305812460226811046733375808000 4312787868) 197795974464901832571194661165645546048000) (num-test (lcm 11450197571956515037245443769386989035470896800 75585518430279) 148852568435434695484190769002030857461121658400) (num-test (lcm 1211397915863796187148880114197307052796506376580 538601201880) 55724304129734624608848485253076124428639293322680) (num-test (lcm 5454139401260819402160859765169199667337088 30452838731872) 3430653683393055403959180792291426590755028352) (num-test (lcm 744935981632690384026127091216926530879171660 1032747922358460) 12639328800361857745771298356677592449426905555220) (num-test (lcm 324574326062026951443376280715122947502400 103751223626207988025) 10099779304072092648063539727012480757432180800) (num-test (lcm 15272163751269260921486082393684080908800 6484309049057400) 290171111274115957508235565479997537267200) (num-test (lcm 386527546655781220813671331401971490218262720 3481571963427119100) 702565997265680899293657490452822449622871959067200) (num-test (lcm 3189682029126430413458911948222943640000 6724598925622907976570) 25845014249628523826120631630482407871222520000) (num-test (lcm 709403542855323660533377490060722241678400 7) 709403542855323660533377490060722241678400) (num-test (lcm 139803787314578422635552652090095842837312147438904 123) 139803787314578422635552652090095842837312147438904) (num-test (lcm 171985399350431759069945935900956183322827030835560 18241) 171985399350431759069945935900956183322827030835560) (num-test (lcm 33090522521924986387051477884789600000 26187) 1422892468442774414643213549045952800000) (num-test (lcm 1733723010009930088165729903139785699319986530 372945) 81484981470466714143789305447569927868039366910) (num-test (lcm 56408303994570817306318494803635460247582000 5761730) 30065626029106245624267757730337700311961206000) (num-test (lcm 25845509336769185412951159262424903513866295760 64371378271) 25845509336769185412951159262424903513866295760) (num-test (lcm 624970361450506104794172455132584603069611058500 108222780) 624970361450506104794172455132584603069611058500) (num-test (lcm 82823962548382643645255524843049561752323600 135325929794) 911063588032209080097810773273545179275559600) (num-test (lcm 170620453449723034746079844571491973300000 9460614789626) 6995438591438644424589273627431170905300000) (num-test (lcm 125144597811313015929871740675462711600000 12764411911636) 125520031604746954977661355897489099734800000) (num-test (lcm 257193319319332344553297882967977761077115600 6510126541380) 10544926092092626126685213201687088204161739600) (num-test (lcm 879624546681838385457288074812140664728758550 10045784120501316) 109420015859940604120573892778181425848269191068700) (num-test (lcm 18300938860777100857669855248554588369659200 118088077425391892) 1507430033023349020545408306968192889420458644800) (num-test (lcm 8394780474625841647581984803260010511075000 746584618179400) 559688409023779488485938508818148160783881325000) (num-test (lcm 146802334713757872619395774222116859916800 718775571956687400) 123460763494270370872911846120800279190028800) (num-test (lcm 240155883351717999820072393833707008014911556000 1350921510529331832) 31940732485778493976069628379883032065983236948000) (num-test (lcm 918942437243241528855354123800826649596480 74343962238703160850) 19653830834705779820109799278313370922778988193600) (num-test (lcm 1361069299753299783990135442290762165844800 8281085446358585640) 1318876151460947490686441243579748538703611200) (num-test (lcm 111738283365989051/177100989030047175 5964153172084899/4217293152016490) (/ (* 111738283365989051/177100989030047175 5964153172084899/4217293152016490) (gcd 111738283365989051/177100989030047175 5964153172084899/4217293152016490))) (num-test (lcm 11571718688839/18340740190704 5168247530883/3654502875938) (/ (* 11571718688839/18340740190704 5168247530883/3654502875938) (gcd 11571718688839/18340740190704 5168247530883/3654502875938))) (num-test (lcm 130441933147714940/206745572560704147 14398739476117879/10181446324101389) (/ (* 130441933147714940/206745572560704147 14398739476117879/10181446324101389) (gcd 130441933147714940/206745572560704147 14398739476117879/10181446324101389))) (num-test (lcm 137528045312/217976794617 63018038201/44560482149) (/ (* 137528045312/217976794617 63018038201/44560482149) (gcd 137528045312/217976794617 63018038201/44560482149))) (num-test (lcm 326267455807135/517121682660006 30122754096401/21300003689580) (/ (* 326267455807135/517121682660006 30122754096401/21300003689580) (gcd 326267455807135/517121682660006 30122754096401/21300003689580))) (num-test (lcm 3816473305410548/6048967074079039 423859315570607/299713796309065) (/ (* 3816473305410548/6048967074079039 423859315570607/299713796309065) (gcd 3816473305410548/6048967074079039 423859315570607/299713796309065))) (num-test (lcm 397560349370386783/630118245525664765 34761632124320657/24580185800219268) (/ (* 397560349370386783/630118245525664765 34761632124320657/24580185800219268) (gcd 397560349370386783/630118245525664765 34761632124320657/24580185800219268))) (num-test (lcm 483615324366283/766512153894657 175568277047523/124145519261542) (/ (* 483615324366283/766512153894657 175568277047523/124145519261542) (gcd 483615324366283/766512153894657 175568277047523/124145519261542))) (num-test (lcm 52449289519716/83130157078217 12477253282759/8822750406821) (/ (* 52449289519716/83130157078217 12477253282759/8822750406821) (gcd 52449289519716/83130157078217 12477253282759/8822750406821))) (num-test (lcm 5409303924479/8573543875303 886731088897/627013566048) (/ (* 5409303924479/8573543875303 886731088897/627013566048) (gcd 5409303924479/8573543875303 886731088897/627013566048))) (num-test (lcm 615582794569/975675645481 152139002499/107578520350) (/ (* 615582794569/975675645481 152139002499/107578520350) (gcd 615582794569/975675645481 152139002499/107578520350))) (num-test (lcm 6189245291/9809721694 1855077841/1311738121) (/ (* 6189245291/9809721694 1855077841/1311738121) (gcd 6189245291/9809721694 1855077841/1311738121))) (num-test (lcm 65470613321/103768467013 10812186007/7645370045) (/ (* 65470613321/103768467013 10812186007/7645370045) (gcd 65470613321/103768467013 10812186007/7645370045))) (num-test (lcm 6586818670/10439860591 4478554083/3166815962) (/ (* 6586818670/10439860591 4478554083/3166815962) (gcd 6586818670/10439860591 4478554083/3166815962))) (num-test (lcm 7530699980955811472069/11935877073996486182239 96845919575610633161/68480406462161287469) (/ (* 7530699980955811472069/11935877073996486182239 96845919575610633161/68480406462161287469) (gcd 7530699980955811472069/11935877073996486182239 96845919575610633161/68480406462161287469))) (num-test (lcm 753110839881/1193652440098 367296043199/259717522849) (/ (* 753110839881/1193652440098 367296043199/259717522849) (gcd 753110839881/1193652440098 367296043199/259717522849))) )) (test (lcm 0 "hi") 'error) (test (lcm 0 1 "hi") 'error) (test (lcm 1 ' #e1.(logior )) 0) ; (lcm 1 1 0) (test (lcm 1.4 2.3) 'error) (test (lcm 2 1.0+0.5i) 'error) (for-each (lambda (arg) (test (lcm arg nan.0) 'error) (test (lcm nan.0 arg) 'error) (test (lcm arg inf.0) 'error) (test (lcm inf.0 arg) 'error) (test (lcm 2 arg) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) (for-each (lambda (arg) (test (lcm arg 2) 'error) (test (lcm arg 1/2) 'error) (test (lcm arg 2.0) 'error) (test (lcm arg 2+i) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) ;;; -------------------------------------------------------------------------------- ;;; rationalize ;;; -------------------------------------------------------------------------------- (num-test (rationalize 0.0 1.0001) 0) (num-test (rationalize -0.0 1.0001) 0) (num-test (rationalize 0.0 0.50000000000000) 0) (num-test (rationalize -0.0 0.50000000000000) 0) (num-test (rationalize 0.0 0.1) 0) (num-test (rationalize -0.0 0.1) 0) (num-test (rationalize 0.0 0.001) 0) (num-test (rationalize -0.0 0.001) 0) (num-test (rationalize 0.0 0.00300000000000) 0) (num-test (rationalize -0.0 0.00300000000000) 0) (num-test (rationalize 0.0 0.00002000000000) 0) (num-test (rationalize -0.0 0.00002000000000) 0) (num-test (rationalize 0.0 0.00000001) 0) (num-test (rationalize -0.0 0.00000001) 0) (num-test (rationalize 0.00000001 1.0) 0) (num-test (rationalize -0.00000001 1.0) 0) (num-test (rationalize 0.00000001 0.50000000000000) 0) (num-test (rationalize -0.00000001 0.50000000000000) 0) (num-test (rationalize 0.00000001 0.1) 0) (num-test (rationalize -0.00000001 0.1) 0) (num-test (rationalize 0.00000001 0.001) 0) (num-test (rationalize -0.00000001 0.001) 0) (num-test (rationalize 0.00000001 0.00300000000000) 0) (num-test (rationalize -0.00000001 0.00300000000000) 0) (num-test (rationalize 0.00000001 0.00002000000000) 0) (num-test (rationalize -0.00000001 0.00002000000000) 0) (num-test (rationalize 0.00000001 0.000000011) 0) (num-test (rationalize -0.00000001 0.000000011) 0) (num-test (rationalize 1.0 1.0001) 0) (num-test (rationalize -1.0 1.0001) 0) (num-test (rationalize 1.0 0.999) 1) (num-test (rationalize -1.0 0.999) -1) (num-test (rationalize 1.0 0.50000000000000) 1) (num-test (rationalize -1.0 0.50000000000000) -1) (num-test (rationalize 1.0 0.1) 1) (num-test (rationalize -1.0 0.1) -1) (num-test (rationalize 1.0 0.001) 1) (num-test (rationalize -1.0 0.001) -1) (num-test (rationalize 1.0 0.00300000000000) 1) (num-test (rationalize -1.0 0.00300000000000) -1) (num-test (rationalize 1.0 0.00002000000000) 1) (num-test (rationalize -1.0 0.00002000000000) -1) (num-test (rationalize 1.0 0.00000001) 1) (num-test (rationalize -1.0 0.00000001) -1) (num-test (rationalize 3.14159265358979 1.0) 3) (num-test (rationalize -3.14159265358979 1.0) -3) (num-test (rationalize 3.14159265358979 0.50000000000000) 3) (num-test (rationalize -3.14159265358979 0.50000000000000) -3) (num-test (rationalize 3.14159265358979 0.1) 16/5) (num-test (rationalize -3.14159265358979 0.1) -16/5) (num-test (rationalize 3.14159265358979 0.001) 201/64) (num-test (rationalize -3.14159265358979 0.001) -201/64) (num-test (rationalize 3.14159265358979 0.00300000000000) 22/7) (num-test (rationalize -3.14159265358979 0.00300000000000) -22/7) (num-test (rationalize 3.14159265358979 0.00002000000000) 355/113) (num-test (rationalize -3.14159265358979 0.00002000000000) -355/113) (num-test (rationalize 3.14159265358979 0.00000001) 100798/32085) (num-test (rationalize -3.14159265358979 0.00000001) -100798/32085) (num-test (rationalize 2.71828182845905 1.0) 2) (num-test (rationalize -2.71828182845905 1.0) -2) (num-test (rationalize 2.71828182845905 0.50000000000000) 3) (num-test (rationalize -2.71828182845905 0.50000000000000) -3) (num-test (rationalize 2.71828182845905 0.1) 8/3) (num-test (rationalize -2.71828182845905 0.1) -8/3) (num-test (rationalize 2.71828182845905 0.001) 87/32) (num-test (rationalize -2.71828182845905 0.001) -87/32) (num-test (rationalize 2.71828182845905 0.00300000000000) 68/25) (num-test (rationalize -2.71828182845905 0.00300000000000) -68/25) (num-test (rationalize 2.71828182845905 0.00002000000000) 878/323) (num-test (rationalize -2.71828182845905 0.00002000000000) -878/323) (num-test (rationalize 2.71828182845905 0.00000001) 23225/8544) (num-test (rationalize -2.71828182845905 0.00000001) -23225/8544) (num-test (rationalize 1234.12339999999995 1.0) 1234) (num-test (rationalize -1234.12339999999995 1.0) -1234) (num-test (rationalize 1234.12339999999995 0.50000000000000) 1234) (num-test (rationalize -1234.12339999999995 0.50000000000000) -1234) (num-test (rationalize 1234.12339999999995 0.1) 6171/5) (num-test (rationalize -1234.12339999999995 0.1) -6171/5) (num-test (rationalize 1234.12339999999995 0.001) 60472/49) (num-test (rationalize -1234.12339999999995 0.001) -60472/49) (num-test (rationalize 1234.12339999999995 0.00300000000000) 9873/8) (num-test (rationalize -1234.12339999999995 0.00300000000000) -9873/8) (num-test (rationalize 1234.12339999999995 0.00002000000000) 290019/235) (num-test (rationalize -1234.12339999999995 0.00002000000000) -290019/235) (num-test (rationalize 1234.12339999999995 0.00000001) 6170617/5000) (num-test (rationalize -1234.12339999999995 0.00000001) -6170617/5000) (num-test (rationalize 1234000000.01234006881714 1.0) 1234000000/1) (num-test (rationalize -1234000000.01234006881714 1.0) -1234000000/1) (num-test (rationalize 1234000000.01234006881714 0.50000000000000) 1234000000/1) (num-test (rationalize -1234000000.01234006881714 0.50000000000000) -1234000000/1) (num-test (rationalize 1234000000.01234006881714 0.1) 1234000000/1) (num-test (rationalize -1234000000.01234006881714 0.1) -1234000000/1) (num-test (rationalize 1234000000.01234006881714 0.001) 92550000001/75) (num-test (rationalize -1234000000.01234006881714 0.001) -92550000001/75) (num-test (rationalize 1234000000.01234006881714 0.00300000000000) 81444000001/66) (num-test (rationalize -1234000000.01234006881714 0.00300000000000) -81444000001/66) (num-test (rationalize 1234000000.01234006881714 0.00002000000000) 99954000001/81) (num-test (rationalize -1234000000.01234006881714 0.00002000000000) -99954000001/81) (num-test (rationalize 1234000000.01234006881714 0.000001) 2400130000024/1945) (num-test (rationalize -1234000000.01234006881714 0.000001) -2400130000024/1945) (num-test (rationalize 0.33 1.0) 0) (num-test (rationalize -0.33 1.0) 0) (num-test (rationalize 0.33 0.50000000000000) 0) (num-test (rationalize -0.33 0.50000000000000) 0) (num-test (rationalize 0.33 0.1) 1/3) (num-test (rationalize -0.33 0.1) -1/3) (num-test (rationalize 0.33 0.001) 26/79) (num-test (rationalize -0.33 0.001) -26/79) (num-test (rationalize 0.33 0.00300000000000) 18/55) (num-test (rationalize -0.33 0.00300000000000) -18/55) (num-test (rationalize 0.33 0.00002000000000) 33/100) (num-test (rationalize -0.33 0.00002000000000) -33/100) (num-test (rationalize 0.33 0.00000001) 33/100) (num-test (rationalize -0.33 0.00000001) -33/100) (num-test (rationalize 0.99990 1.0) 0) (num-test (rationalize -0.99990 1.0) 0) (num-test (rationalize 0.99990 0.50000000000000) 1) (num-test (rationalize -0.99990 0.50000000000000) -1) (num-test (rationalize 0.99990 0.1) 1) (num-test (rationalize -0.99990 0.1) -1) (num-test (rationalize 0.99990 0.001) 1) (num-test (rationalize -0.99990 0.001) -1) (num-test (rationalize 0.99990 0.00300000000000) 1) (num-test (rationalize -0.99990 0.00300000000000) -1) (num-test (rationalize 0.99990 0.00002000000000) 8333/8334) (num-test (rationalize -0.99990 0.00002000000000) -8333/8334) (num-test (rationalize 0.99990 0.00000001) 9999/10000) (num-test (rationalize -0.99990 0.00000001) -9999/10000) (num-test (rationalize 0.5010 1.0) 0) (num-test (rationalize -0.5010 1.0) 0) (num-test (rationalize 0.5010 0.50000000000000) 1) (num-test (rationalize -0.5010 0.50000000000000) -1) (num-test (rationalize 0.5010 0.1) 1/2) (num-test (rationalize -0.5010 0.1) -1/2) (num-test (rationalize 0.5010 0.00099) 127/253) (num-test (rationalize -0.5010 0.00099) -127/253) (num-test (rationalize 0.5010 0.00300000000000) 1/2) (num-test (rationalize -0.5010 0.00300000000000) -1/2) (num-test (rationalize 0.5010 0.00002000000000) 246/491) (num-test (rationalize -0.5010 0.00002000000000) -246/491) (num-test (rationalize 0.5010 0.00000001) 501/1000) (num-test (rationalize -0.5010 0.00000001) -501/1000) (num-test (rationalize 0.499 1.0) 0) (num-test (rationalize -0.499 1.0) 0) (num-test (rationalize 0.499 0.50000000000000) 0) (num-test (rationalize -0.499 0.50000000000000) 0) (num-test (rationalize 0.499 0.1) 1/2) (num-test (rationalize -0.499 0.1) -1/2) (num-test (rationalize 0.499 0.00099) 126/253) (num-test (rationalize -0.499 0.00099) -126/253) (num-test (rationalize 0.499 0.00300000000000) 1/2) (num-test (rationalize -0.499 0.00300000000000) -1/2) (num-test (rationalize 0.499 0.00002000000000) 245/491) (num-test (rationalize -0.499 0.00002000000000) -245/491) (num-test (rationalize 0.499 0.00000001) 499/1000) (num-test (rationalize -0.499 0.00000001) -499/1000) (num-test (rationalize 1.501 1.0) 1) (num-test (rationalize -1.501 1.0) -1) (num-test (rationalize 1.501 0.50000000000000) 2) (num-test (rationalize -1.501 0.50000000000000) -2) (num-test (rationalize 1.501 0.1) 3/2) (num-test (rationalize -1.501 0.1) -3/2) (num-test (rationalize 1.501 0.01) 3/2) (num-test (rationalize -1.501 0.01) -3/2) (num-test (rationalize 1.501 0.00300000000000) 3/2) (num-test (rationalize -1.501 0.00300000000000) -3/2) (num-test (rationalize 1.501 0.00002000000000) 737/491) (num-test (rationalize -1.501 0.00002000000000) -737/491) (num-test (rationalize 1.501 0.00000001) 1501/1000) (num-test (rationalize -1.501 0.00000001) -1501/1000) (num-test (rationalize 1.499 1.0) 1) (num-test (rationalize -1.499 1.0) -1) (num-test (rationalize 1.499 0.50000000000000) 1) (num-test (rationalize -1.499 0.50000000000000) -1) (num-test (rationalize 1.499 0.1) 3/2) (num-test (rationalize -1.499 0.1) -3/2) (num-test (rationalize 1.499 0.001) 3/2) (num-test (rationalize -1.499 0.001) -3/2) (num-test (rationalize 1.499 0.00300000000000) 3/2) (num-test (rationalize -1.499 0.00300000000000) -3/2) (num-test (rationalize 1.499 0.00002000000000) 736/491) (num-test (rationalize -1.499 0.00002000000000) -736/491) (num-test (rationalize 1.499 0.00000001) 1499/1000) (num-test (rationalize -1.499 0.00000001) -1499/1000) (num-test (rationalize 1.16 .2) 1) (num-test (rationalize 1.16 .1) 5/4) (num-test (rationalize 1.16 .041) 6/5) (num-test (rationalize 1.16 .039) 7/6) (num-test (rationalize 1.16 .007) 7/6) (num-test (rationalize 1.16 .006) 22/19) (num-test (rationalize 1.16 .0022) 22/19) (num-test (rationalize 1.16 .002) 29/25) (num-test (rationalize 1.16 .0000001) 29/25) (num-test (rationalize .1 .1) 0) (num-test (rationalize .1 .0999) 1/6) (num-test (rationalize .1 .065) 1/7) (num-test (rationalize .1 .067) 1/6) (num-test (rationalize .1 .04) 1/8) (num-test (rationalize .1 .02) 1/9) (num-test (rationalize .1 .01) 1/10) (num-test (rationalize 23.1 22.0) 2) (num-test (rationalize 23.1 22) 2) (num-test (rationalize 23.1 .5) 23) (num-test (rationalize 23.1 1/2) 23) (num-test (rationalize 1/2 3/4) 0) (num-test (rationalize 1/2 1/4) 1/2) (num-test (rationalize 1 3) 0) (num-test (rationalize 11/10 1/5) 1) (num-test (rationalize 3/4 1/2) 1) (num-test (rationalize 1/4 1/3) 0) (num-test (rationalize 1/4 1/6) 1/3) (num-test (rationalize 2/3 1/4) 1/2) (num-test (rationalize 1/3 1/3) 0) (num-test (rationalize 1/3 1/4) 1/2) (num-test (rationalize 3/10 1/10) 1/3) (num-test (rationalize 1/4 1/11) 1/3) (num-test (rationalize 1/4 1/12) 1/4) (num-test (rationalize pi 1/10) 16/5) (num-test (rationalize pi 1/100) 22/7) (num-test (rationalize pi 1/10000) 333/106) ;; currently (rationalize pi 0) -> 245850922/78256779, but should it return the actual (float-style) ratio? (num-test (rationalize 1 .1) 1) (num-test (rationalize 1 1) 0) (num-test (rationalize 1 1/2) 1) (num-test (rationalize 1 0) 1) (num-test (rationalize 0 -.1) 0) (num-test (rationalize 0 1) 0) (num-test (rationalize 0 0) 0) (num-test (rationalize -1 .1) -1) (num-test (rationalize -1 -1) 0) (num-test (rationalize (exact->inexact 1/2) 3/4) 0) (num-test (rationalize (exact->inexact 1/2) 1/4) 1/2) (num-test (rationalize (exact->inexact 1) 3) 0) (num-test (rationalize (exact->inexact 11/10) 1/5) 1) (num-test (rationalize (exact->inexact 3/4) 1/2) 1) (num-test (rationalize (exact->inexact 1/4) 1/3) 0) (num-test (rationalize (exact->inexact 1/4) 1/6) 1/3) (num-test (rationalize (exact->inexact 2/3) 1/4) 1/2) (num-test (rationalize (exact->inexact 1/3) 1/4) 1/2) (num-test (rationalize (exact->inexact 3/10) 1/10) 1/3) (num-test (rationalize 1/2 (exact->inexact 3/4)) 0) (num-test (rationalize 1/2 (exact->inexact 1/4)) 1/2) (num-test (rationalize 1 (exact->inexact 3)) 0) (num-test (rationalize 11/10 (exact->inexact 1/5)) 1) (num-test (rationalize 3/4 (exact->inexact 1/2)) 1) (num-test (rationalize 1/4 (exact->inexact 1/3)) 0) (num-test (rationalize 1/4 (exact->inexact 1/6)) 1/3) (num-test (rationalize 2/3 (exact->inexact 1/4)) 1/2) (num-test (rationalize 1/3 (exact->inexact 1/4)) 1/2) (num-test (rationalize 3/10 (exact->inexact 1/10)) 1/3) (num-test (rationalize (exact->inexact 1/2) (exact->inexact 3/4)) 0) (num-test (rationalize (exact->inexact 1/2) (exact->inexact 1/4)) 1/2) (num-test (rationalize (exact->inexact 1) (exact->inexact 3)) 0) (num-test (rationalize (exact->inexact 11/10) (exact->inexact 1/5)) 1) (num-test (rationalize (exact->inexact 3/4) (exact->inexact 1/2)) 1) (num-test (rationalize (exact->inexact 1/4) (exact->inexact 1/3)) 0) (num-test (rationalize (exact->inexact 1/4) (exact->inexact 1/6)) 1/3) (num-test (rationalize (exact->inexact 2/3) (exact->inexact 1/4)) 1/2) (num-test (rationalize (exact->inexact 1/3) (exact->inexact 1/4)) 1/2) (num-test (rationalize (exact->inexact 3/10) (exact->inexact 1/10)) 1/3) (num-test (rationalize -1/2 3/4) 0) (num-test (rationalize -1/2 1/4) -1/2) (num-test (rationalize -1 3) 0) (num-test (rationalize -11/10 1/5) -1) (num-test (rationalize -3/4 1/2) -1) (num-test (rationalize -1/4 1/3) 0) (num-test (rationalize -1/4 1/6) -1/3) (num-test (rationalize -2/3 1/4) -1/2) (num-test (rationalize -1/3 1/4) -1/2) (num-test (rationalize -1/3 1/3) 0) (num-test (rationalize -3/10 1/10) -1/3) (num-test (rationalize .0999 .1) 0) (num-test (rationalize -.0999 .1) 0) (num-test (rationalize 1.0999 .1) 1) (num-test (rationalize -1.0999 .1) -1) (num-test (rationalize .239 .0005) 11/46) ;baseball of course... the average .001 is the hardest to get: 1/667 (num-test (rationalize .001 .0005) 1/667) (num-test (rationalize .334 .0005) 96/287) (num-test (rationalize 1.0000001 0.00000001) 9090911/9090910) (num-test (rationalize 0.000000015 0.0000000009999999) 1/62500001) (num-test (rationalize 0.00000001 1e-16) 1/100000000) (num-test (rationalize 0.1 0) (if with-bignums 3602879701896397/36028797018963968 1/10)) (num-test (rationalize 0.1 .00000000000000001) 1/10) (num-test (/ 0.(rationalize .1)) 0.0) (when (not with-bignums) (num-test (rationalize .1 0) 1/10) ;; but (rationalize 0.1 0) -> 1526457681181556/15264576811815559? independent of precision ;; and (rationalize 0.1000000000000000 0) -> 1/10 so once again it's either the idiotic reader or the bignum promotion process ;; (rationalize 0.00000001 0) 3022314549036573/302231454903657293676544? (num-test (rationalize 1e-3 0) 1/1000) (num-test (rationalize 1e-12 0) 1/1000000000000) (num-test (rationalize 1e-15 0) 1/1000000000000000) (num-test (rationalize (+ 1e2 1e-2) 0) 10001/100)) (num-test (rationalize -1 -1) 0) ;; spec says "differs by no more than", but that seems to imply a comparison ;; on either side, so a negative error doesn't change the result?? (num-test (rationalize 1/4 -1/6) 1/3) (num-test (rationalize -3/10 -1/10) -1/3) (num-test (rationalize (exact->inexact 1/3) (exact->inexact -1/4)) 1/2) (num-test (rationalize 0.5 0.02) 1/2) (num-test (rationalize 1073741824 1) 1073741823) ; perverse (num-test (rationalize -2.225073858507201399999999999999999999996E-308) 0) (num-test (rationalize -9223372036854775808) -9223372036854775808) (num-test (rationalize 1.110223024625156799999999999999999999997E-16) 0) (num-test (rationalize 9223372036854775807) 9223372036854775807) (num-test (rationalize -3037000503.0 -3037000500.0) -3) (num-test (rationalize 33309123021416.7508179322803e-25 1e-20) 1/300218050279) (num-test (rationalize 33309123021416.7508179322803e-25 1e-12) 1/230898233499) (num-test (rationalize 33309123021416.7508179322803e-25 1e-23) 1/300218051179) (num-test (rationalize 9223372036854775807 0) 9223372036854775807) (num-test (rationalize 9223372036854775807 -1) 9223372036854775806) (num-test (rationalize 9223372036854775807 -1/2) 9223372036854775807) (num-test (rationalize 9223372036854775807 1/2) 9223372036854775807) (num-test (rationalize 9223372036854775807 3/2) 9223372036854775806) (num-test (rationalize 9223372036854775807 -3/2) 9223372036854775806) (num-test (rationalize 9223372036854775807 1) 9223372036854775806) (num-test (rationalize 9223372036854775807 inf.0) 0) (test (rationalize (/ pi) 1e-8) 24288/76303) (test (rationalize (/ pi) 1e-10) 33102/103993) (num-test (rationalize 1e8 1e9) 0) (num-test (rationalize 1e16 most-positive-fixnum) 0) (num-test (rationalize most-positive-fixnum 1e20) 0) (num-test (rationalize most-positive-fixnum most-positive-fixnum) 0) (num-test (rationalize (/ 1 most-positive-fixnum) 0) (/ 1 most-positive-fixnum)) (num-test (rationalize 1e20 -1e21) 0) (num-test (rationalize -1e20 1e21) 0) (num-test (rationalize 1e20 inf.0) 0) (num-test (rationalize (/ (expt 2 60) (expt 3 20)) .01) 2314582608/7) (num-test (rationalize (/ (expt 2 60) (expt 3 20)) .001) 8266366457/25) (num-test (rationalize 33309123021416.7508179322803e-25 1e-23) 1/300218051179) (num-test (rationalize 11/30 .1) 1/3) (num-test (rationalize 11/30 .2) 1/2) (num-test (rationalize 11/30 .365) 1/2) (num-test (rationalize 11/30 .367) 0) ;; these differ from the ratify result (num-test (rationalize 0.02 .01) 1/34) (num-test (rationalize 0.05 .01) 1/17) (num-test (rationalize 0.06 .01) 1/15) (num-test (rationalize 0.07 .01) 1/13) (num-test (rationalize 0.32 .01) 5/16) (num-test (rationalize 0.35 .01) 5/14) (num-test (rationalize 0.39 .01) 2/5) (num-test (rationalize 0.47 .01) 6/13) (num-test (rationalize 0.48 .01) 8/17) (num-test (rationalize 0.52 .01) 9/17) (num-test (rationalize 0.53 .01) 7/13) (num-test (rationalize 0.61 .01) 3/5) (num-test (rationalize 0.65 .01) 9/14) (num-test (rationalize 0.68 .01) 11/16) (num-test (rationalize 0.93 .01) 12/13) (num-test (rationalize 0.94 .01) 14/15) (num-test (rationalize 0.95 .01) 16/17) (num-test (rationalize 0.96 .01) 19/20) (num-test (rationalize 0.97 .01) 24/25) (num-test (rationalize 0.98 .01) 33/34) (num-test (rationalize 0.01 .001) 1/91) (num-test (rationalize 0.02 .001) 1/48) (num-test (rationalize 0.06 .001) 2/33) (num-test (rationalize 0.11 .001) 6/55) (num-test (rationalize 0.14 .001) 6/43) (num-test (rationalize 0.17 .001) 7/41) (num-test (rationalize 0.18 .001) 7/39) (num-test (rationalize 0.33 .001) 26/79) (num-test (rationalize 0.34 .001) 15/44) (num-test (rationalize 0.43 .001) 28/65) (num-test (rationalize 0.46 .001) 17/37) (num-test (rationalize 0.49 .001) 23/47) (num-test (rationalize 0.51 .001) 24/47) (num-test (rationalize 0.57 .001) 37/65) (num-test (rationalize 0.58 .001) 18/31) (num-test (rationalize 0.66 .001) 29/44) (num-test (rationalize 0.67 .001) 53/79) (num-test (rationalize 0.83 .001) 34/41) (num-test (rationalize 0.86 .001) 37/43) (num-test (rationalize 0.89 .001) 49/55) (num-test (rationalize 0.94 .001) 31/33) (num-test (rationalize 0.98 .001) 47/48) (num-test (rationalize 0.99 .001) 90/91) (num-test (rationalize 0.1001 .1) 1/5) (num-test (rationalize 0.101 .1) 1/5) (num-test (rationalize 0.451 .0010001) 9/20) (num-test (rationalize 0.9876 .0001) 80/81) (num-test (rationalize (expt 2 1/3) (expt 10 -10)) 96389/76504) (num-test (rationalize (expt 2 1/3) (expt 10 -15)) 15240955/12096754) (for-each (lambda (num-and-val) (let ((num (car num-and-val)) (val (cadr num-and-val))) (num-test-1 'rationalize num (rationalize num) val))) (vector (list 0 0) (list 1 1) (list 2 2) (list 3 3) (list -1 -1) (list -2 -2) (list -3 -3) (list 9223372036854775807 9223372036854775807) (list -9223372036854775808 -9223372036854775808) (list 1/2 1/2) (list 1/3 1/3) (list -1/2 -1/2) (list -1/3 -1/3) (list 1/9223372036854775807 0) (list 0.0 0) (list 1.0 1) (list 2.0 2) (list -2.0 -2) (list 1.000000000000000000000000000000000000002E-309 0))) (if (not with-bignums) (begin (test (< (abs (- (rationalize (/ pi) 1e-17) (/ pi))) 1e-10) #t) ; make sure we don't hang! (test (< (abs (- (rationalize (/ pi) 1e-18) (/ pi))) 1e-10) #t) (test (< (abs (- (rationalize (/ pi) 1e-20) (/ pi))) 1e-10) #t) (num-test (rationalize 1e-19 1e-21) 0) (num-test (rationalize 1e-19 1e-30) 0) (num-test (rationalize 1e-19 1e-50) 0) (num-test (rationalize 1e-19 0.0) 0) (num-test (rationalize 1e-19 1e-19) 0) (num-test (rationalize 1e-30 0.0) 0) (num-test (rationalize (+ .1 1e-18) 1e-17) 1/10) (num-test (rationalize (- .1 1e-18) 1e-17) 1/10) ) (begin (test (rationalize (/ pi) 1e-17) 78256779/245850922) (test (rationalize (/ pi) 1e-18) 340262731/1068966896) (test (rationalize (/ pi) 1e-20) 1963319607/6167950454) (test (rationalize (/ pi) 1e-30) 136308121570117/428224593349304) (num-test (rationalize (/ 1 most-negative-fixnum) 0) (/ 1 most-negative-fixnum)) (num-test (rationalize 1e-19 1e-21) 1/9900990099009900991) (num-test (rationalize 1e-19 1e-30) 1/9999999999900000001) (num-test (rationalize 1e-30 0.0) 1/1000000000000000000000000000000) (num-test (rationalize (+ .1 1e-18) 0) 1894333982346309985/18943339823463098609) (num-test (rationalize (+ .1 1e-18) 1e-20) 1524131159466061/15241311594660609) (num-test (rationalize (- .1 1e-18) 1e-20) 2192446305355891/21924463053558909) (num-test (rationalize 1e18 1e19) 0) (num-test (rationalize 1180591620717411303424) 1180591620717411303424) (num-test (rationalize 1180591620717411303424 .9) 1180591620717411303424) (num-test (rationalize -1180591620717411303424 1.9) -1180591620717411303423) (test (rationalize -1180591620717411303424 nan.0) 'error) (num-test (rationalize -1180591620717411303424 inf.0) 0) (num-test (rationalize most-negative-fixnum 1) (+ most-negative-fixnum 1)) (num-test (rationalize (/ 3.0 most-positive-fixnum) 1e-50) 3/9223372036854775807) (num-test (rationalize (/ 3.0 most-positive-fixnum) 1e-38) 3/9223372036854775807) (num-test (rationalize (expt 2 1/3) (expt 10 -20)) 11952836413/9486972548) (num-test (rationalize (expt 2 1/3) (expt 10 -30)) 2566462403285413/2037002559406049) (test (< (abs (- (expt (rationalize (expt 2 1/3) (expt 10 -30)) 3.0) 2)) 1e-29) #t) (test (rationalize 3796553736732654909229441/2684568892382786771291329) 1607521/1136689) ; default error? (test (< (abs (- (rationalize 3796553736732654909229441/2684568892382786771291329)3796553736732654909229441/2684568892382786771291329)) 1e-12) #t) (num-test (rationalize 3796553736732654909229441/2684568892382786771291329 1) 1) (let ((old-prec (*s7* 'bignum-precision))) (set! (*s7* 'bignum-precision) 1024) (num-test (rationalize (expt 2 1/3) 1e-40) 77270484057362988877/61329623839374997455) (num-test (rationalize 3796553736732654909229441/2684568892382786771291329 0) 3796553736732654909229441/2684568892382786771291329) (set! (*s7* 'bignum-precision) old-prec)) )) (let () (define (check-rationalize val n) (call-with-exit (lambda (return) (let* ((diffs (make-vector n 0.0)) (ratios (make-vector n 0))) (do ((i 0 (+ i 1))) ((= i n)) (let* ((err (expt 2 (- (+ i 1)))) (rat (rationalize val err)) (diff (abs (- rat val)))) (vector-set! ratios i rat) (vector-set! diffs i diff) (if (> diff err) (begin (format-logged #t "|~A - ~A| = ~A > ~A (2^~A -> 2^~A)?~%" val rat diff err (log diff 2) (log err 2)) (return #f))))) (and (apply >= (vector->list diffs)) (apply <= (map denominator ratios))))))) (for-each (lambda (val) (test (check-rationalize val 40) #t)) (list pi (/ pi) (- pi) (- (/ pi)) (* 10 pi) (* -1000 pi) (exp 1.0) (exp -1.0) (exp 4.0) (exp -4.0))) (do ((i 0 (+ i 1))) ((= i 100)) (let ((val (- (random 2.0) 1.0))) (let ((rat (check-rationalize val 40))) (if (not rat) (format-logged #t "rationalize trouble with ~A~%" val))))) (if with-bignums (let ((old-prec (*s7* 'bignum-precision))) (set! (*s7* 'bignum-precision) 4096) (test (*s7* 'bignum-precision) 4096) (test (check-rationalize pi 100) #t) (test (check-rationalize (/ pi) 100) #t) (for-each (lambda (arg) (test (set! (*s7* 'bignum-precision) arg) 'error)) (list "hi" #\a 'a-symbol #(1 2 3) -1 0 1 3.14 3/4 1.0+1.0i #t abs # # (lambda () 1))) (test (bignum-precision 213) 'error) (test (set! (bignum-precision 213) 123) 'error) (set! (*s7* 'bignum-precision) 2) (test (*s7* 'bignum-precision) 2) (test (object->string pi) "3.0E0") (set! (*s7* 'bignum-precision) old-prec)))) (test (rationalize) 'error) (test (rationalize 1.23+1.0i 1.23+1.0i) 'error) (test (rationalize 1.23 1.23 1.23) 'error) (test (rationalize 0 nan.0) 'error) ; ?? (test (rationalize 1 nan.0) 'error) (test (rationalize (expt 2 60) -) 'error) (for-each (lambda (arg) (test (rationalize arg 0.1) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) (for-each (lambda (arg) (test (rationalize arg nan.0) 'error) (test (rationalize nan.0 arg) 'error) (test (rationalize arg inf.0) 'error) (test (rationalize inf.0 arg) 'error) (test (rationalize 0.1 arg) 'error) (test (rationalize 1 arg) 'error) (test (rationalize 1/2 arg) 'error) (test (rationalize 0+i arg) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) (if with-bignums (begin (num-test (rationalize .1e20) 10000000000000000000) (num-test (rationalize 1e19) 10000000000000000000) (num-test (rationalize 1e20) 100000000000000000000)) (begin (num-test (rationalize .1e20) 'error) (num-test (rationalize 1e19) 'error) (num-test (rationalize 1e20) 'error))) (call-with-exit (lambda (done) (do ((k -6 (- k 1))) ((= k -17)) (call-with-exit (lambda (ok) (let ((fraction (rationalize (expt 10.0 k) 1e-18))) (do ((i 0 (+ i 1))) ((= i 100)) (if (not (zero? (random fraction))) (ok)))) (format-logged #t ";random of small ratios is always 0 below ca. ~A~%" (expt 10.0 k)) (done)))))) ;;; Bill Gosper's farint: (let () (define* (farint x (err 1/1000000)) ; this err term is not the same as the s7 rationalize error term (define* (farint-1 x nhi dhi (ln 0) (ld 1) (hn 1) (hd 0)) (if (> (+ ln hn) (* (+ ld hd) x)) (let* ((m (min (if (= 0 ln) nhi (floor (/ (- nhi hn) ln))) (floor (/ (- dhi hd) ld)))) (d (- (* x ld) ln)) (k (if (= 0 d) m (ceiling (/ (- hn (* x hd)) d))))) (if (< k m) (let ((hn1 (+ (* k ln) hn)) (hd1 (+ (* k ld) hd))) (farint-1 x nhi dhi hn1 hd1 (- hn1 ln) (- hd1 ld))) (let* ((n (+ (* m ln) hn)) (d (+ (* m ld) hd))) (if (< (* 2 d ld x) (+ (* ld n) (* ln d))) (/ ln ld) (/ n d))))) (let* ((m (min (floor (/ (- nhi ln) hn)) (if (= 0 hd) dhi (floor (/ (- dhi ld) hd))))) (d (- hn (* x hd))) (k (if (= 0 d) m (ceiling (/ (- (* x ld) ln) d))))) (if (< k m) (let ((ln1 (+ (* k hn) ln)) (ld1 (+ (* k hd) ld))) (farint-1 x nhi dhi (- ln1 hn) (- ld1 hd) ln1 ld1)) (let* ((n (+ (* m hn) ln)) (d (+ (* m hd) ld))) (if (< (* 2 d hd x) (+ (* hd n) (* hn d))) (/ n d) (/ hn hd))))))) (farint-1 x (/ err) (/ err))) (num-test (farint .1) 1/10)) ;;; -------------------------------------------------------------------------------- ;;; min ;;; -------------------------------------------------------------------------------- (num-test (min -0.0) 0.0) (num-test (min -1 -1/2) -1) (num-test (min -1 1/2) -1) (num-test (min -1.0) -1.0) (num-test (min -1.797693134862315699999999999999999999998E308 -9223372036854775808) -1.797693134862315699999999999999999999998E308) (num-test (min -1/2 -1) -1) (num-test (min -1/2 1) -1/2) (num-test (min -10) -10) (num-test (min -10/3) -10/3) (num-test (min -1234000000) -1234000000) (num-test (min -1234000000.0) -1234000000.0) (num-test (min -1234000000/10) -1234000000/10) (num-test (min -2 3 0 7) -2) (num-test (min -2) -2) (num-test (min -2.71828182845905) -2.71828182845905) (num-test (min -2/2) -2/2) (num-test (min -3/2 -1/2) -3/2) (num-test (min -3/2 -6/5) -3/2) (num-test (min -3/2 1/2) -3/2) (num-test (min -3/2 6/5) -3/2) (num-test (min -362880) -362880) (num-test (min -362880/1234) -362880/1234) (num-test (min -6 -12) -12) (num-test (min -9223372036854775808 -9223372036854775808) -9223372036854775808) (num-test (min -9223372036854775808 5.551115123125783999999999999999999999984E-17) -9.223372036854775808E18) (num-test (min -9223372036854775808 9223372036854775807 -9223372036854775808) -9223372036854775808) (num-test (min 0 1 1) 0) (num-test (min 0 1 1.0) 0.0) (num-test (min 0 1 1/1) 0) (num-test (min 0 1 123.4) 0.0) (num-test (min 0 1 1234) 0) (num-test (min 0 1 1234/11) 0) (num-test (min 0 1) 0) (num-test (min 0 1.0 1) 0.0) (num-test (min 0 1.0 1.0) 0.0) (num-test (min 0 1.0 1/1) 0.0) (num-test (min 0 1.0 123.4) 0.0) (num-test (min 0 1.0 1234) 0.0) (num-test (min 0 1.0 1234/11) 0.0) (num-test (min 0 1.0) 0.0) (num-test (min 0 1/1) 0) (num-test (min 0 123.4 1) 0.0) (num-test (min 0 123.4 1.0) 0.0) (num-test (min 0 123.4 1/1) 0.0) (num-test (min 0 123.4 123.4) 0.0) (num-test (min 0 123.4 1234) 0.0) (num-test (min 0 123.4 1234/11) 0.0) (num-test (min 0 123.4) 0.0) (num-test (min 0 1234 1) 0) (num-test (min 0 1234 1.0) 0.0) (num-test (min 0 1234 1/1) 0) (num-test (min 0 1234 123.4) 0.0) (num-test (min 0 1234 1234) 0) (num-test (min 0 1234 1234/11) 0) (num-test (min 0 1234) 0) (num-test (min 0 1234/11 1) 0) (num-test (min 0 1234/11 1.0) 0.0) (num-test (min 0 1234/11 1/1) 0) (num-test (min 0 1234/11 123.4) 0.0) (num-test (min 0 1234/11 1234) 0) (num-test (min 0 1234/11 1234/11) 0) (num-test (min 0 1234/11) 0) (num-test (min 0) 0) (num-test (min 0.0 1 1) 0.0) (num-test (min 0.0 1 1.0) 0.0) (num-test (min 0.0 1 1/1) 0.0) (num-test (min 0.0 1 123.4) 0.0) (num-test (min 0.0 1 1234) 0.0) (num-test (min 0.0 1 1234/11) 0.0) (num-test (min 0.0 1) 0.0) (num-test (min 0.0 1.0 1) 0.0) (num-test (min 0.0 1.0 1.0) 0.0) (num-test (min 0.0 1.0 1/1) 0.0) (num-test (min 0.0 1.0 123.4) 0.0) (num-test (min 0.0 1.0 1234) 0.0) (num-test (min 0.0 1.0 1234/11) 0.0) (num-test (min 0.0 1.0) 0.0) (num-test (min 0.0 1/1) 0.0) (num-test (min 0.0 123.4 1) 0.0) (num-test (min 0.0 123.4 1.0) 0.0) (num-test (min 0.0 123.4 1/1) 0.0) (num-test (min 0.0 123.4 123.4) 0.0) (num-test (min 0.0 123.4 1234) 0.0) (num-test (min 0.0 123.4 1234/11) 0.0) (num-test (min 0.0 123.4) 0.0) (num-test (min 0.0 1234 1) 0.0) (num-test (min 0.0 1234 1.0) 0.0) (num-test (min 0.0 1234 1/1) 0.0) (num-test (min 0.0 1234 123.4) 0.0) (num-test (min 0.0 1234 1234) 0.0) (num-test (min 0.0 1234 1234/11) 0.0) (num-test (min 0.0 1234) 0.0) (num-test (min 0.0 1234/11 1) 0.0) (num-test (min 0.0 1234/11 1.0) 0.0) (num-test (min 0.0 1234/11 1/1) 0.0) (num-test (min 0.0 1234/11 123.4) 0.0) (num-test (min 0.0 1234/11 1234) 0.0) (num-test (min 0.0 1234/11 1234/11) 0.0) (num-test (min 0.0 1234/11) 0.0) (num-test (min 0.0) 0.0) (num-test (min 0/1) 0/1) (num-test (min 0/1) 0/1) (num-test (min 1 -1/2) -1/2) (num-test (min 1 1 1) 1) (num-test (min 1 1 1.0) 1.0) (num-test (min 1 1 1/1) 1) (num-test (min 1 1 123.4) 1.0) (num-test (min 1 1 1234) 1) (num-test (min 1 1 1234/11) 1) (num-test (min 1 1) 1) (num-test (min 1 1.0 1) 1.0) (num-test (min 1 1.0 1.0) 1.0) (num-test (min 1 1.0 1/1) 1.0) (num-test (min 1 1.0 123.4) 1.0) (num-test (min 1 1.0 1234) 1.0) (num-test (min 1 1.0 1234/11) 1.0) (num-test (min 1 1.0) 1.0) (num-test (min 1 1/1) 1) (num-test (min 1 1/2) 1/2) (num-test (min 1 123.4 1) 1.0) (num-test (min 1 123.4 1.0) 1.0) (num-test (min 1 123.4 1/1) 1.0) (num-test (min 1 123.4 123.4) 1.0) (num-test (min 1 123.4 1234) 1.0) (num-test (min 1 123.4 1234/11) 1.0) (num-test (min 1 123.4) 1.0) (num-test (min 1 1234 1) 1) (num-test (min 1 1234 1.0) 1.0) (num-test (min 1 1234 1/1) 1) (num-test (min 1 1234 123.4) 1.0) (num-test (min 1 1234 1234) 1) (num-test (min 1 1234 1234/11) 1) (num-test (min 1 1234) 1) (num-test (min 1 1234/11 1) 1) (num-test (min 1 1234/11 1.0) 1.0) (num-test (min 1 1234/11 1/1) 1) (num-test (min 1 1234/11 123.4) 1.0) (num-test (min 1 1234/11 1234) 1) (num-test (min 1 1234/11 1234/11) 1) (num-test (min 1 1234/11) 1) (num-test (min 1 3 2 -7) -7) (num-test (min 1.0 1 1) 1.0) (num-test (min 1.0 1 1.0) 1.0) (num-test (min 1.0 1 1/1) 1.0) (num-test (min 1.0 1 123.4) 1.0) (num-test (min 1.0 1 1234) 1.0) (num-test (min 1.0 1 1234/11) 1.0) (num-test (min 1.0 1) 1.0) (num-test (min 1.0 1.0 1) 1.0) (num-test (min 1.0 1.0 1.0) 1.0) (num-test (min 1.0 1.0 1/1) 1.0) (num-test (min 1.0 1.0 123.4) 1.0) (num-test (min 1.0 1.0 1234) 1.0) (num-test (min 1.0 1.0 1234/11) 1.0) (num-test (min 1.0 1.0) 1.0) (num-test (min 1.0 1/1) 1.0) (num-test (min 1.0 123.4 1) 1.0) (num-test (min 1.0 123.4 1.0) 1.0) (num-test (min 1.0 123.4 1/1) 1.0) (num-test (min 1.0 123.4 123.4) 1.0) (num-test (min 1.0 123.4 1234) 1.0) (num-test (min 1.0 123.4 1234/11) 1.0) (num-test (min 1.0 123.4) 1.0) (num-test (min 1.0 1234 1) 1.0) (num-test (min 1.0 1234 1.0) 1.0) (num-test (min 1.0 1234 1/1) 1.0) (num-test (min 1.0 1234 123.4) 1.0) (num-test (min 1.0 1234 1234) 1.0) (num-test (min 1.0 1234 1234/11) 1.0) (num-test (min 1.0 1234) 1.0) (num-test (min 1.0 1234/11 1) 1.0) (num-test (min 1.0 1234/11 1.0) 1.0) (num-test (min 1.0 1234/11 1/1) 1.0) (num-test (min 1.0 1234/11 123.4) 1.0) (num-test (min 1.0 1234/11 1234) 1.0) (num-test (min 1.0 1234/11 1234/11) 1.0) (num-test (min 1.0 1234/11) 1.0) (num-test (min 1.0) 1.0) (num-test (min 1.110223024625156799999999999999999999997E-16 -9223372036854775808) -9.223372036854775808E18) (num-test (min 1.110223024625156799999999999999999999997E-16 5.551115123125783999999999999999999999984E-17 5.42101086242752217060000000000000000001E-20) 5.42101086242752217060000000000000000001E-20) (num-test (min 1/2 -1) -1) (num-test (min 1/2 1) 1/2) (num-test (min 1/46116860184273883 1/46116860184273879) 1/46116860184273883) (num-test (min 1/9223372036854775807 1/9223372036854775300) 1/9223372036854775807) (num-test (min 1/9223372036854775807 2/9223372036854775807) 1/9223372036854775807) (num-test (min 10) 10) (num-test (min 10/3) 10/3) (num-test (min 1010-0.i) 1010.0) (num-test (min 123.4 1 1) 1.0) (num-test (min 123.4 1 1.0) 1.0) (num-test (min 123.4 1 1/1) 1.0) (num-test (min 123.4 1 123.4) 1.0) (num-test (min 123.4 1 1234) 1.0) (num-test (min 123.4 1 1234/11) 1.0) (num-test (min 123.4 1) 1.0) (num-test (min 123.4 1.0 1) 1.0) (num-test (min 123.4 1.0 1.0) 1.0) (num-test (min 123.4 1.0 1/1) 1.0) (num-test (min 123.4 1.0 123.4) 1.0) (num-test (min 123.4 1.0 1234) 1.0) (num-test (min 123.4 1.0 1234/11) 1.0) (num-test (min 123.4 1.0) 1.0) (num-test (min 123.4 1/1) 1.0) (num-test (min 123.4 123.4 1) 1.0) (num-test (min 123.4 123.4 1.0) 1.0) (num-test (min 123.4 123.4 1/1) 1.0) (num-test (min 123.4 123.4 123.4) 123.4) (num-test (min 123.4 123.4 1234) 123.4) (num-test (min 123.4 123.4 1234/11) 112.18181818181819) (num-test (min 123.4 123.4) 123.4) (num-test (min 123.4 1234 1) 1.0) (num-test (min 123.4 1234 1.0) 1.0) (num-test (min 123.4 1234 1/1) 1.0) (num-test (min 123.4 1234 123.4) 123.4) (num-test (min 123.4 1234 1234) 123.4) (num-test (min 123.4 1234 1234/11) 112.18181818181819) (num-test (min 123.4 1234) 123.4) (num-test (min 123.4 1234/11 1) 1.0) (num-test (min 123.4 1234/11 1.0) 1.0) (num-test (min 123.4 1234/11 1/1) 1.0) (num-test (min 123.4 1234/11 123.4) 112.18181818181819) (num-test (min 123.4 1234/11 1234) 112.18181818181819) (num-test (min 123.4 1234/11 1234/11) 112.18181818181819) (num-test (min 123.4 1234/11) 112.18181818181819) (num-test (min 1234 1 1) 1) (num-test (min 1234 1 1.0) 1.0) (num-test (min 1234 1 1/1) 1) (num-test (min 1234 1 123.4) 1.0) (num-test (min 1234 1 1234) 1) (num-test (min 1234 1 1234/11) 1) (num-test (min 1234 1) 1) (num-test (min 1234 1.0 1) 1.0) (num-test (min 1234 1.0 1.0) 1.0) (num-test (min 1234 1.0 1/1) 1.0) (num-test (min 1234 1.0 123.4) 1.0) (num-test (min 1234 1.0 1234) 1.0) (num-test (min 1234 1.0 1234/11) 1.0) (num-test (min 1234 1.0) 1.0) (num-test (min 1234 1/1) 1) (num-test (min 1234 123.4 1) 1.0) (num-test (min 1234 123.4 1.0) 1.0) (num-test (min 1234 123.4 1/1) 1.0) (num-test (min 1234 123.4 123.4) 123.4) (num-test (min 1234 123.4 1234) 123.4) (num-test (min 1234 123.4 1234/11) 112.18181818181819) (num-test (min 1234 123.4) 123.4) (num-test (min 1234 1234 1) 1) (num-test (min 1234 1234 1.0) 1.0) (num-test (min 1234 1234 1/1) 1) (num-test (min 1234 1234 123.4) 123.4) (num-test (min 1234 1234 1234) 1234) (num-test (min 1234 1234 1234/11) 1234/11) (num-test (min 1234 1234) 1234) (num-test (min 1234 1234/11 1) 1) (num-test (min 1234 1234/11 1.0) 1.0) (num-test (min 1234 1234/11 1/1) 1) (num-test (min 1234 1234/11 123.4) 112.18181818181819) (num-test (min 1234 1234/11 1234) 1234/11) (num-test (min 1234 1234/11 1234/11) 1234/11) (num-test (min 1234 1234/11) 1234/11) (num-test (min 1234/11 1 1) 1) (num-test (min 1234/11 1 1.0) 1.0) (num-test (min 1234/11 1 1/1) 1) (num-test (min 1234/11 1 123.4) 1.0) (num-test (min 1234/11 1 1234) 1) (num-test (min 1234/11 1 1234/11) 1) (num-test (min 1234/11 1) 1) (num-test (min 1234/11 1.0 1) 1.0) (num-test (min 1234/11 1.0 1.0) 1.0) (num-test (min 1234/11 1.0 1/1) 1.0) (num-test (min 1234/11 1.0 123.4) 1.0) (num-test (min 1234/11 1.0 1234) 1.0) (num-test (min 1234/11 1.0 1234/11) 1.0) (num-test (min 1234/11 1.0) 1.0) (num-test (min 1234/11 1/1) 1) (num-test (min 1234/11 123.4 1) 1.0) (num-test (min 1234/11 123.4 1.0) 1.0) (num-test (min 1234/11 123.4 1/1) 1.0) (num-test (min 1234/11 123.4 123.4) 112.18181818181819) (num-test (min 1234/11 123.4 1234) 112.18181818181819) (num-test (min 1234/11 123.4 1234/11) 112.18181818181819) (num-test (min 1234/11 123.4) 112.18181818181819) (num-test (min 1234/11 1234 1) 1) (num-test (min 1234/11 1234 1.0) 1.0) (num-test (min 1234/11 1234 1/1) 1) (num-test (min 1234/11 1234 123.4) 112.18181818181819) (num-test (min 1234/11 1234 1234) 1234/11) (num-test (min 1234/11 1234 1234/11) 1234/11) (num-test (min 1234/11 1234) 1234/11) (num-test (min 1234/11 1234/11 1) 1) (num-test (min 1234/11 1234/11 1.0) 1.0) (num-test (min 1234/11 1234/11 1/1) 1) (num-test (min 1234/11 1234/11 123.4) 112.18181818181819) (num-test (min 1234/11 1234/11 1234) 1234/11) (num-test (min 1234/11 1234/11 1234/11) 1234/11) (num-test (min 1234/11 1234/11) 1234/11) (num-test (min 1234000000) 1234000000) (num-test (min 1234000000.0) 1234000000.0) (num-test (min 1234000000/10) 1234000000/10) (num-test (min 2 1+0i) 1.0) (num-test (min 2) 2) (num-test (min 2.71828182845905) 2.71828182845905) (num-test (min 2/2) 2/2) (num-test (min 2/9223372036854775807 1/9223372036854775807) 1/9223372036854775807) (num-test (min 3 5 5 330 4 -24) -24 ) (num-test (min 3) 3) (num-test (min 3.0 7 1) 1.0) (num-test (min 3/2 -1/2) -1/2) (num-test (min 3/2 -6/5) -6/5) (num-test (min 3/2 1/2) 1/2) (num-test (min 3/2 6/5) 6/5) (num-test (min 362880) 362880) (num-test (min 362880/1234) 362880/1234) (num-test (min 5.0 2) 2.0) ; why not 2? (num-test (min 5.551115123125783999999999999999999999984E-17 1.110223024625156799999999999999999999997E-16) 5.551115123125783999999999999999999999984E-17) (num-test (min 6 12) 6) (num-test (min 92233720368547758/9223372036854775807 92233720368547757/9223372036854775807) 92233720368547757/9223372036854775807) (num-test (min 9223372036854775807 -9223372036854775808) -9223372036854775808) (if with-bignums (begin (num-test (min 12345678901234567890 12345678901234567891) 12345678901234567890) (num-test (min 2.168404344971008681816600431489558149231E-17 2.168404344971008869895696563055543437233E-17) 2.168404344971008681816600431489558149231E-17) (num-test (min 2.168404344971008869895696563055543437233E-17 2.168404344971008681816600431489558149231E-17 ) 2.168404344971008681816600431489558149231E-17) (num-test (min 2.168404344971008681816600431489558149231E-17 1/46116860184273879) 2.168404344971008681816600431489558149231E-17) (num-test (min 1/46116860184273883 2.168404344971008869895696563055543437233E-17) 2.168404344971008681816600431489558149231E-17) (num-test (let ((n (list 2.0 (bignum "3")))) (eval `(let () (define (f1) (min ,@n)) (f1)))) 2.0) (num-test (let ((n (list 2.0 (bignum "0")))) (eval `(let () (define (f1) (min ,@n)) (f1)))) 0) (num-test (let ((n (list 2.0 (bignum "3")))) (eval `(let () (define (f1) (max ,@n)) (f1)))) 3) (num-test (let ((n (list 2.0 (bignum "0")))) (eval `(let () (define (f1) (max ,@n)) (f1)))) 2.0) )) (test (min 1.23+1.0i) 'error) (test (min) 'error) (test (min 1234000000.0+2.71828182845905i) 'error) (test (min 2.71828182845905+3.14159265358979i) 'error) (test (min 1.0+1.0i) 'error) (test (min 0.0+0.00000001i) 'error) (test (min -0.0+0.00000001i) 'error) (test (min -1.0+1.0i) 'error) (test (min -1234000000.0+2.71828182845905i) 'error) (test (min -2.71828182845905+3.14159265358979i) 'error) (test (min nan.0 1+i) 'error) (test (min nan.0 1 1+i) 'error) (test (min 1 nan.0 2 1+i) 'error) (test (min inf.0 1+i) 'error) (test (min inf.0 nan.0 0-i 1) 'error) (test (nan? (min 3/4 1/0)) #t) (test (nan? (min 3/4 nan.0)) #t) (test (min 3/4 nan.0 #\a) 'error) (for-each (lambda (arg) (test (min arg nan.0) 'error) (test (min nan.0 arg) 'error) (test (min arg inf.0) 'error) (test (min inf.0 arg) 'error) (test (min 0 arg) 'error) (test (min 0.0 arg) 'error) (test (min 1/2 arg) 'error) (test (min 1+i arg) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) ;;; -------------------------------------------------------------------------------- ;;; max ;;; -------------------------------------------------------------------------------- (num-test (max -0.0) 0.0) (num-test (max -1 -1/2) -1/2) (num-test (max -1 1/2) 1/2) (num-test (max -1.0) -1.0) (num-test (max -1.797693134862315699999999999999999999998E308 -9223372036854775808) -9.223372036854775808E18) (num-test (max -1/2 -1) -1/2) (num-test (max -1/2 1) 1) (num-test (max -10) -10) (num-test (max -10/3) -10/3) (num-test (max -1234000000) -1234000000) (num-test (max -1234000000.0) -1234000000.0) (num-test (max -1234000000/10) -1234000000/10) (num-test (max -2 3 0 7) 7) (num-test (max -2) -2) (num-test (max -2.71828182845905) -2.71828182845905) (num-test (max -2/2) -2/2) (num-test (max -3/2 -1/2) -1/2) (num-test (max -3/2 -6/5) -6/5) (num-test (max -3/2 1/2) 1/2) (num-test (max -3/2 6/5) 6/5) (num-test (max -362880) -362880) (num-test (max -362880/1234) -362880/1234) (num-test (max -6 -12) -6) (num-test (max -9223372036854775808 -9223372036854775808) -9223372036854775808) (num-test (max -9223372036854775808 5.551115123125783999999999999999999999984E-17) 5.551115123125783999999999999999999999984E-17) (num-test (max -9223372036854775808 9223372036854775807 -9223372036854775808) 9223372036854775807) (num-test (max 0 1 1) 1) (num-test (max 0 1 1.0) 1.0) (num-test (max 0 1 1/1) 1) (num-test (max 0 1 123.4) 123.4) (num-test (max 0 1 1234) 1234) (num-test (max 0 1 1234/11) 1234/11) (num-test (max 0 1) 1) (num-test (max 0 1.0 1) 1.0) (num-test (max 0 1.0 1.0) 1.0) (num-test (max 0 1.0 1/1) 1.0) (num-test (max 0 1.0 123.4) 123.4) (num-test (max 0 1.0 1234) 1234.0) (num-test (max 0 1.0 1234/11) 112.18181818181819) (num-test (max 0 1.0) 1.0) (num-test (max 0 1/1) 1) (num-test (max 0 123.4 1) 123.4) (num-test (max 0 123.4 1.0) 123.4) (num-test (max 0 123.4 1/1) 123.4) (num-test (max 0 123.4 123.4) 123.4) (num-test (max 0 123.4 1234) 1234.0) (num-test (max 0 123.4 1234/11) 123.4) (num-test (max 0 123.4) 123.4) (num-test (max 0 1234 1) 1234) (num-test (max 0 1234 1.0) 1234.0) (num-test (max 0 1234 1/1) 1234) (num-test (max 0 1234 123.4) 1234.0) (num-test (max 0 1234 1234) 1234) (num-test (max 0 1234 1234/11) 1234) (num-test (max 0 1234) 1234) (num-test (max 0 1234/11 1) 1234/11) (num-test (max 0 1234/11 1.0) 112.18181818181819) (num-test (max 0 1234/11 1/1) 1234/11) (num-test (max 0 1234/11 123.4) 123.4) (num-test (max 0 1234/11 1234) 1234) (num-test (max 0 1234/11 1234/11) 1234/11) (num-test (max 0 1234/11) 1234/11) (num-test (max 0) 0) (num-test (max 0.0 1 1) 1.0) (num-test (max 0.0 1 1.0) 1.0) (num-test (max 0.0 1 1/1) 1.0) (num-test (max 0.0 1 123.4) 123.4) (num-test (max 0.0 1 1234) 1234.0) (num-test (max 0.0 1 1234/11) 112.18181818181819) (num-test (max 0.0 1) 1.0) (num-test (max 0.0 1.0 1) 1.0) (num-test (max 0.0 1.0 1.0) 1.0) (num-test (max 0.0 1.0 1/1) 1.0) (num-test (max 0.0 1.0 123.4) 123.4) (num-test (max 0.0 1.0 1234) 1234.0) (num-test (max 0.0 1.0 1234/11) 112.18181818181819) (num-test (max 0.0 1.0) 1.0) (num-test (max 0.0 1/1) 1.0) (num-test (max 0.0 123.4 1) 123.4) (num-test (max 0.0 123.4 1.0) 123.4) (num-test (max 0.0 123.4 1/1) 123.4) (num-test (max 0.0 123.4 123.4) 123.4) (num-test (max 0.0 123.4 1234) 1234.0) (num-test (max 0.0 123.4 1234/11) 123.4) (num-test (max 0.0 123.4) 123.4) (num-test (max 0.0 1234 1) 1234.0) (num-test (max 0.0 1234 1.0) 1234.0) (num-test (max 0.0 1234 1/1) 1234.0) (num-test (max 0.0 1234 123.4) 1234.0) (num-test (max 0.0 1234 1234) 1234.0) (num-test (max 0.0 1234 1234/11) 1234.0) (num-test (max 0.0 1234) 1234.0) (num-test (max 0.0 1234/11 1) 112.18181818181819) (num-test (max 0.0 1234/11 1.0) 112.18181818181819) (num-test (max 0.0 1234/11 1/1) 112.18181818181819) (num-test (max 0.0 1234/11 123.4) 123.4) (num-test (max 0.0 1234/11 1234) 1234.0) (num-test (max 0.0 1234/11 1234/11) 112.18181818181819) (num-test (max 0.0 1234/11) 112.18181818181819) (num-test (max 0.0) 0.0) (num-test (max 0/1) 0/1) (num-test (max 0/1) 0/1) (num-test (max 1 -1/2) 1) (num-test (max 1 1 1) 1) (num-test (max 1 1 1.0) 1.0) (num-test (max 1 1 1/1) 1) (num-test (max 1 1 123.4) 123.4) (num-test (max 1 1 1234) 1234) (num-test (max 1 1 1234/11) 1234/11) (num-test (max 1 1) 1) (num-test (max 1 1.0 1) 1.0) (num-test (max 1 1.0 1.0) 1.0) (num-test (max 1 1.0 1/1) 1.0) (num-test (max 1 1.0 123.4) 123.4) (num-test (max 1 1.0 1234) 1234.0) (num-test (max 1 1.0 1234/11) 112.18181818181819) (num-test (max 1 1.0) 1.0) (num-test (max 1 1/1) 1) (num-test (max 1 1/2) 1) (num-test (max 1 123.4 1) 123.4) (num-test (max 1 123.4 1.0) 123.4) (num-test (max 1 123.4 1/1) 123.4) (num-test (max 1 123.4 123.4) 123.4) (num-test (max 1 123.4 1234) 1234.0) (num-test (max 1 123.4 1234/11) 123.4) (num-test (max 1 123.4) 123.4) (num-test (max 1 1234 1) 1234) (num-test (max 1 1234 1.0) 1234.0) (num-test (max 1 1234 1/1) 1234) (num-test (max 1 1234 123.4) 1234.0) (num-test (max 1 1234 1234) 1234) (num-test (max 1 1234 1234/11) 1234) (num-test (max 1 1234) 1234) (num-test (max 1 1234/11 1) 1234/11) (num-test (max 1 1234/11 1.0) 112.18181818181819) (num-test (max 1 1234/11 1/1) 1234/11) (num-test (max 1 1234/11 123.4) 123.4) (num-test (max 1 1234/11 1234) 1234) (num-test (max 1 1234/11 1234/11) 1234/11) (num-test (max 1 1234/11) 1234/11) (num-test (max 1 3 2 -7) 3) (num-test (max 1 3 2 -7) 3) (num-test (max 1.0 1 1) 1.0) (num-test (max 1.0 1 1.0) 1.0) (num-test (max 1.0 1 1/1) 1.0) (num-test (max 1.0 1 123.4) 123.4) (num-test (max 1.0 1 1234) 1234.0) (num-test (max 1.0 1 1234/11) 112.18181818181819) (num-test (max 1.0 1) 1.0) (num-test (max 1.0 1.0 1) 1.0) (num-test (max 1.0 1.0 1.0) 1.0) (num-test (max 1.0 1.0 1/1) 1.0) (num-test (max 1.0 1.0 123.4) 123.4) (num-test (max 1.0 1.0 1234) 1234.0) (num-test (max 1.0 1.0 1234/11) 112.18181818181819) (num-test (max 1.0 1.0) 1.0) (num-test (max 1.0 1/1) 1.0) (num-test (max 1.0 123.4 1) 123.4) (num-test (max 1.0 123.4 1.0) 123.4) (num-test (max 1.0 123.4 1/1) 123.4) (num-test (max 1.0 123.4 123.4) 123.4) (num-test (max 1.0 123.4 1234) 1234.0) (num-test (max 1.0 123.4 1234/11) 123.4) (num-test (max 1.0 123.4) 123.4) (num-test (max 1.0 1234 1) 1234.0) (num-test (max 1.0 1234 1.0) 1234.0) (num-test (max 1.0 1234 1/1) 1234.0) (num-test (max 1.0 1234 123.4) 1234.0) (num-test (max 1.0 1234 1234) 1234.0) (num-test (max 1.0 1234 1234/11) 1234.0) (num-test (max 1.0 1234) 1234.0) (num-test (max 1.0 1234/11 1) 112.18181818181819) (num-test (max 1.0 1234/11 1.0) 112.18181818181819) (num-test (max 1.0 1234/11 1/1) 112.18181818181819) (num-test (max 1.0 1234/11 123.4) 123.4) (num-test (max 1.0 1234/11 1234) 1234.0) (num-test (max 1.0 1234/11 1234/11) 112.18181818181819) (num-test (max 1.0 1234/11) 112.18181818181819) (num-test (max 1.0) 1.0) (num-test (max 1.110223024625156799999999999999999999997E-16 -9223372036854775808) 1.110223024625156799999999999999999999997E-16) (num-test (max 1.110223024625156799999999999999999999997E-16 5.551115123125783999999999999999999999984E-17 5.42101086242752217060000000000000000001E-20) 1.110223024625156799999999999999999999997E-16) (num-test (max 1/2 -1) 1/2) (num-test (max 1/2 1) 1) (num-test (max 1/461168601842738841 1/461168601842738790) 1/461168601842738790) (num-test (max 1/4611686018427388416 1/4611686018427387904) 1/4611686018427387904) (num-test (max 1/461168601842738848 1/461168601842738790) 1/461168601842738790) (num-test (max 1/9223372036854775300 1/9223372036854775807) 1/9223372036854775300) (num-test (max 1/9223372036854775807 1/9223372036854775300) 1/9223372036854775300) (num-test (max 1/9223372036854775807 1/9223372036854775806) 1/9223372036854775806) (num-test (max 1/9223372036854775807 2/9223372036854775807) 2/9223372036854775807) (num-test (max 10) 10) (num-test (max 10/3) 10/3) (num-test (max 123.4 1 1) 123.4) (num-test (max 123.4 1 1.0) 123.4) (num-test (max 123.4 1 1/1) 123.4) (num-test (max 123.4 1 123.4) 123.4) (num-test (max 123.4 1 1234) 1234.0) (num-test (max 123.4 1 1234/11) 123.4) (num-test (max 123.4 1) 123.4) (num-test (max 123.4 1.0 1) 123.4) (num-test (max 123.4 1.0 1.0) 123.4) (num-test (max 123.4 1.0 1/1) 123.4) (num-test (max 123.4 1.0 123.4) 123.4) (num-test (max 123.4 1.0 1234) 1234.0) (num-test (max 123.4 1.0 1234/11) 123.4) (num-test (max 123.4 1.0) 123.4) (num-test (max 123.4 1/1) 123.4) (num-test (max 123.4 123.4 1) 123.4) (num-test (max 123.4 123.4 1.0) 123.4) (num-test (max 123.4 123.4 1/1) 123.4) (num-test (max 123.4 123.4 123.4) 123.4) (num-test (max 123.4 123.4 1234) 1234.0) (num-test (max 123.4 123.4 1234/11) 123.4) (num-test (max 123.4 123.4) 123.4) (num-test (max 123.4 1234 1) 1234.0) (num-test (max 123.4 1234 1.0) 1234.0) (num-test (max 123.4 1234 1/1) 1234.0) (num-test (max 123.4 1234 123.4) 1234.0) (num-test (max 123.4 1234 1234) 1234.0) (num-test (max 123.4 1234 1234/11) 1234.0) (num-test (max 123.4 1234) 1234.0) (num-test (max 123.4 1234/11 1) 123.4) (num-test (max 123.4 1234/11 1.0) 123.4) (num-test (max 123.4 1234/11 1/1) 123.4) (num-test (max 123.4 1234/11 123.4) 123.4) (num-test (max 123.4 1234/11 1234) 1234.0) (num-test (max 123.4 1234/11 1234/11) 123.4) (num-test (max 123.4 1234/11) 123.4) (num-test (max 1234 1 1) 1234) (num-test (max 1234 1 1.0) 1234.0) (num-test (max 1234 1 1/1) 1234) (num-test (max 1234 1 123.4) 1234.0) (num-test (max 1234 1 1234) 1234) (num-test (max 1234 1 1234/11) 1234) (num-test (max 1234 1) 1234) (num-test (max 1234 1.0 1) 1234.0) (num-test (max 1234 1.0 1.0) 1234.0) (num-test (max 1234 1.0 1/1) 1234.0) (num-test (max 1234 1.0 123.4) 1234.0) (num-test (max 1234 1.0 1234) 1234.0) (num-test (max 1234 1.0 1234/11) 1234.0) (num-test (max 1234 1.0) 1234.0) (num-test (max 1234 1/1) 1234) (num-test (max 1234 123.4 1) 1234.0) (num-test (max 1234 123.4 1.0) 1234.0) (num-test (max 1234 123.4 1/1) 1234.0) (num-test (max 1234 123.4 123.4) 1234.0) (num-test (max 1234 123.4 1234) 1234.0) (num-test (max 1234 123.4 1234/11) 1234.0) (num-test (max 1234 123.4) 1234.0) (num-test (max 1234 1234 1) 1234) (num-test (max 1234 1234 1.0) 1234.0) (num-test (max 1234 1234 1/1) 1234) (num-test (max 1234 1234 123.4) 1234.0) (num-test (max 1234 1234 1234) 1234) (num-test (max 1234 1234 1234/11) 1234) (num-test (max 1234 1234) 1234) (num-test (max 1234 1234/11 1) 1234) (num-test (max 1234 1234/11 1.0) 1234.0) (num-test (max 1234 1234/11 1/1) 1234) (num-test (max 1234 1234/11 123.4) 1234.0) (num-test (max 1234 1234/11 1234) 1234) (num-test (max 1234 1234/11 1234/11) 1234) (num-test (max 1234 1234/11) 1234) (num-test (max 1234/11 1 1) 1234/11) (num-test (max 1234/11 1 1.0) 112.18181818181819) (num-test (max 1234/11 1 1/1) 1234/11) (num-test (max 1234/11 1 123.4) 123.4) (num-test (max 1234/11 1 1234) 1234) (num-test (max 1234/11 1 1234/11) 1234/11) (num-test (max 1234/11 1) 1234/11) (num-test (max 1234/11 1.0 1) 112.18181818181819) (num-test (max 1234/11 1.0 1.0) 112.18181818181819) (num-test (max 1234/11 1.0 1/1) 112.18181818181819) (num-test (max 1234/11 1.0 123.4) 123.4) (num-test (max 1234/11 1.0 1234) 1234.0) (num-test (max 1234/11 1.0 1234/11) 112.18181818181819) (num-test (max 1234/11 1.0) 112.18181818181819) (num-test (max 1234/11 1/1) 1234/11) (num-test (max 1234/11 123.4 1) 123.4) (num-test (max 1234/11 123.4 1.0) 123.4) (num-test (max 1234/11 123.4 1/1) 123.4) (num-test (max 1234/11 123.4 123.4) 123.4) (num-test (max 1234/11 123.4 1234) 1234.0) (num-test (max 1234/11 123.4 1234/11) 123.4) (num-test (max 1234/11 123.4) 123.4) (num-test (max 1234/11 1234 1) 1234) (num-test (max 1234/11 1234 1.0) 1234.0) (num-test (max 1234/11 1234 1/1) 1234) (num-test (max 1234/11 1234 123.4) 1234.0) (num-test (max 1234/11 1234 1234) 1234) (num-test (max 1234/11 1234 1234/11) 1234) (num-test (max 1234/11 1234) 1234) (num-test (max 1234/11 1234/11 1) 1234/11) (num-test (max 1234/11 1234/11 1.0) 112.18181818181819) (num-test (max 1234/11 1234/11 1/1) 1234/11) (num-test (max 1234/11 1234/11 123.4) 123.4) (num-test (max 1234/11 1234/11 1234) 1234) (num-test (max 1234/11 1234/11 1234/11) 1234/11) (num-test (max 1234/11 1234/11) 1234/11) (num-test (max 1234000000) 1234000000) (num-test (max 1234000000.0) 1234000000.0) (num-test (max 1234000000/10) 1234000000/10) (num-test (max 1e+16 9223372036854775807 1e+17) 9223372036854775807) (num-test (max 2 1+0i) 2) (num-test (max 2) 2) (num-test (max 2.71828182845905) 2.71828182845905) (num-test (max 2/2) 2/2) (num-test (max 2/9223372036854775807 1/9223372036854775807) 2/9223372036854775807) (num-test (max 3) 3) (num-test (max 3.0 7 1) 7.0) (num-test (max 3/2 -1/2) 3/2) (num-test (max 3/2 -6/5) 3/2) (num-test (max 3/2 1/2) 3/2) (num-test (max 3/2 6/5) 3/2) (num-test (max 34 5 7 38 6) 38 ) (num-test (max 362880) 362880) (num-test (max 362880/1234) 362880/1234) (num-test (max 5.0 2) 5.0) (num-test (max 5.551115123125783999999999999999999999984E-17 1.110223024625156799999999999999999999997E-16) 1.110223024625156799999999999999999999997E-16) (num-test (max 6 12) 12) (num-test (max 92233720368547758/9223372036854775807 92233720368547757/9223372036854775807) 13176245766935394/1317624576693539401) (num-test (max 9223372036854775805/9223372036854775807 9223372036854775806/9223372036854775807) 9223372036854775806/9223372036854775807) (num-test (max 9223372036854775806/9223372036854775807 9223372036854775805/9223372036854775807) 9223372036854775806/9223372036854775807) (num-test (max 9223372036854775807 -9223372036854775808) 9223372036854775807) (num-test (max 92233720368547757/9223372036854775807 92233720368547758/9223372036854775807) 13176245766935394/1317624576693539401) ;; after reduction this is 13176245766935394/1317624576693539401 and 92233720368547757/9223372036854775807 -> ;; 9.999999999999999992410584792601468961145E-3 ;; 9.999999999999999883990367544051025548645E-3 ;; but in doubles-land, they're exactly the same, so we have to hope long doubles work in the non-gmp case (num-test (max 9223372036854776/9223372036854775807 9223372036854775/9223372036854775807) 9223372036854776/9223372036854775807) (num-test (max 9223372036854776/9223372036854775807 9223372036854775/922337203685477500) 1/100) (num-test (max 9223372036854775/922337203685477500 9223372036854776/9223372036854775807) 1/100) (num-test (max 9223372036854776/9223372036854775807 9223372036854775/9223372036854774806) 9223372036854775/9223372036854774806) (num-test (max 9223372036854775/9223372036854774806 9223372036854776/9223372036854775807) 9223372036854775/9223372036854774806) (num-test (max 9223372036854776/9223372036854775807 9223372036854775/9223372036854775000) 9223372036854776/9223372036854775807) ;; mpfr says the 1st fraction is 1.000000000000000020925101928970235578612E-3 (num-test (max 1e18 most-positive-fixnum) most-positive-fixnum) ; in bignum case there's type confusion here I think (hence num-test) (if with-bignums (begin (num-test (max 12345678901234567890 12345678901234567891) 12345678901234567891) (num-test (max 9223372036854776/9223372036854775807 #i9223372036854775/9223372036854775000) 1.000000000000000020925101928970235578612E-3) (num-test (max #i9223372036854776/9223372036854775807 9223372036854775/9223372036854775000) 1.000000000000000020925101928970235578612E-3) (num-test (max #i92233720368547757/9223372036854775807 92233720368547758/9223372036854775807) 9.999999999999999992410584792601468961145E-3) (num-test (max 92233720368547757/9223372036854775807 #i92233720368547758/9223372036854775807) 9.999999999999999992410584792601468961145E-3) ;; in these cases, the non-gmp s7 can't win: ;; :(max 9223372036854776/9223372036854775807 #i9223372036854775/9223372036854775000) ;; 9223372036854776/9223372036854775807 ;; :(max #i9223372036854776/9223372036854775807 9223372036854775/9223372036854775000) ;; 0.001 ;; :(max #i92233720368547757/9223372036854775807 92233720368547758/9223372036854775807) ;; 0.01 ;; :(max 92233720368547757/9223372036854775807 #i92233720368547758/9223372036854775807) ;; 92233720368547757/9223372036854775807 )) (test (max) 'error) (test (max 1.23+1.0i) 'error) (test (max -0.0+0.00000001i) 'error) (test (max -1.0+1.0i) 'error) (test (max -1234000000.0+2.71828182845905i) 'error) (test (max -2.71828182845905+3.14159265358979i) 'error) (test (max 0.0+0.00000001i) 'error) (test (max 1.0+1.0i) 'error) (test (max 1234000000.0+2.71828182845905i) 'error) (test (max 2.71828182845905+3.14159265358979i) 'error) (test (max nan.0 1+i) 'error) (test (max nan.0 1 1+i) 'error) (test (max 1 nan.0 2 1+i) 'error) (test (max inf.0 1+i) 'error) (test (max inf.0 nan.0 0-i 1) 'error) (test (nan? (max 3/4 1/0)) #t) (test (nan? (max 3/4 nan.0)) #t) (test (max 3/4 nan.0 #\a) 'error) (for-each (lambda (arg) (test (max arg nan.0) 'error) (test (max nan.0 arg) 'error) (test (max arg inf.0) 'error) (test (max inf.0 arg) 'error) (test (max 0 arg) 'error) (test (max 0.0 arg) 'error) (test (max 1/2 arg) 'error) (test (max 0+i arg) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) (let ((top-exp 60)) (let ((happy #t)) (do ((i 2 (+ i 1))) ((or (not happy) (> i top-exp))) (let* ((val1 (+ 2 (expt 2 i))) (val2 (- val1 1))) (if (not (= val1 (max val1 val2))) (begin (set! happy #f) (display "(max ") (display val1) (display " ") (display val2) (display ") -> ") (display (max val1 val2)) (display "?") (newline))) (if (not (= val2 (min val1 val2))) (begin (set! happy #f) (display "(min ") (display val1) (display " ") (display val2) (display ") -> ") (display (min val1 val2)) (display "?") (newline)))))) (let ((happy #t)) (do ((i 2 (+ i 1))) ((or (not happy) (> i top-exp))) (let* ((val1 (/ (expt 2 i) 3)) (val2 (/ (+ 1 (expt 2 i)) 3))) (if (not (= val2 (max val1 val2))) (begin (set! happy #f) (display "(max ") (display val1) (display " ") (display val2) (display ") -> ") (display (max val1 val2)) (display "?") (newline))) (if (not (= val2 (max val2 val1))) (begin (set! happy #f) (display "(max ") (display val1) (display " ") (display val2) (display ") -> ") (display (max val2 val1)) (display "?") (newline))) (if (not (= val1 (min val1 val2))) (begin (set! happy #f) (display "(min ") (display val1) (display " ") (display val2) (display ") -> ") (display (min val1 val2)) (display "?") (newline))) (if (not (= val1 (min val2 val1))) (begin (set! happy #f) (display "(min ") (display val1) (display " ") (display val2) (display ") -> ") (display (min val2 val1)) (display "?") (newline))) )))) ;;; -------------------------------------------------------------------------------- ;;; < ;;; -------------------------------------------------------------------------------- (test (< 0 1 1) #f) (test (< 0 1 1.0) #f) (test (< 0 1 1/1) #f) (test (< 0 1 123.4) #t) (test (< 0 1 1234) #t) (test (< 0 1 1234/11) #t) (test (< 0 1) #t) (test (< 0 1.0 1) #f) (test (< 0 1.0 1.0) #f) (test (< 0 1.0 1/1) #f) (test (< 0 1.0 123.4) #t) (test (< 0 1.0 1234) #t) (test (< 0 1.0 1234/11) #t) (test (< 0 1.0) #t) (test (< 0 123.4) #t) (test (< 0 1234) #t) (test (< 0 1234/11) #t) (test (< 0.0 1 1.0) #f) (test (< 0.0 1 1/1) #f) (test (< 0.0 1 123.4) #t) (test (< 0.0 1 1234) #t) (test (< 0.0 1 1234/11) #t) (test (< 0.0 1) #t) (test (< 0.0 1.0 1) #f) (test (< 0.0 1.0 1.0) #f) (test (< 0.0 1.0 1/1) #f) (test (< 0.0 1.0 123.4) #t) (test (< 0.0 1.0 1234) #t) (test (< 0.0 1.0 1234/11) #t) (test (< 0.0 1.0) #t) (test (< 0.0 123.4 1) #f) (test (< 0.0 123.4 1.0) #f) (test (< 0.0 123.4 1/1) #f) (test (< 0.0 123.4 123.4) #f) (test (< 0.0 123.4 1234) #t) (test (< 0.0 123.4 1234/11) #f) (test (< 0.0 123.4) #t) (test (< 0.0 1234 1) #f) (test (< 0.0 1234 1.0) #f) (test (< 0.0 1234 1/1) #f) (test (< 0.0 1234 123.4) #f) (test (< 0.0 1234 1234) #f) (test (< 0.0 1234 1234/11) #f) (test (< 0.0 1234) #t) (test (< 0.0 1234/11 1) #f) (test (< 0.0 1234/11 1.0) #f) (test (< 0.0 1234/11 1/1) #f) (test (< 0.0 1234/11 123.4) #t) (test (< 0.0 1234/11 1234) #t) (test (< 0.0 1234/11 1234/11) #f) (test (< 0.0 1234/11) #t) (test (< 1 1 1) #f) (test (< 1 1 1.0) #f) (test (< 1 1 1/1) #f) (test (< 1 1 123.4) #f) (test (< 1 1 1234) #f) (test (< 1 1 1234/11) #f) (test (< 1 1) #f) (test (< 1 1.0 1) #f) (test (< 1 1.0 1.0) #f) (test (< 1 1.0 1/1) #f) (test (< 1 1.0 123.4) #f) (test (< 1 1.0 1234) #f) (test (< 1 1.0 1234/11) #f) (test (< 1 1.0) #f) (test (< 1 1/1) #f) (test (< 1 123.4) #t) (test (< 1 1234) #t) (test (< 1 1234/11) #t) (test (< 1.0 1 1) #f) (test (< 1.0 1 1.0) #f) (test (< 1.0 1 1/1) #f) (test (< 1.0 1 123.4) #f) (test (< 1.0 1 1234) #f) (test (< 1.0 1 1234/11) #f) (test (< 1.0 1) #f) (test (< 1.0 1.0 1) #f) (test (< 1.0 1.0 1.0) #f) (test (< 1.0 1.0 1/1) #f) (test (< 1.0 1.0 123.4) #f) (test (< 1.0 1.0 1234) #f) (test (< 1.0 1.0 1234/11) #f) (test (< 1.0 1.0) #f) (test (< 1.0 123.4 1) #f) (test (< 1.0 123.4 1.0) #f) (test (< 1.0 123.4 1/1) #f) (test (< 1.0 123.4 123.4) #f) (test (< 1.0 123.4 1234) #t) (test (< 1.0 123.4 1234/11) #f) (test (< 1.0 123.4) #t) (test (< 1.0 1234 1) #f) (test (< 1.0 1234 1.0) #f) (test (< 1.0 1234 1/1) #f) (test (< 1.0 1234 123.4) #f) (test (< 1.0 1234 1234) #f) (test (< 1.0 1234 1234/11) #f) (test (< 1.0 1234) #t) (test (< 1.0 1234/11 1) #f) (test (< 1.0 1234/11 1.0) #f) (test (< 1.0 1234/11 1/1) #f) (test (< 1.0 1234/11 123.4) #t) (test (< 1.0 1234/11 1234) #t) (test (< 1.0 1234/11 1234/11) #f) (test (< 1.0 1234/11) #t) (test (< 123.4 1 1) #f) (test (< 123.4 1 1.0) #f) (test (< 123.4 1 1/1) #f) (test (< 123.4 1 123.4) #f) (test (< 123.4 1 1234) #f) (test (< 123.4 1 1234/11) #f) (test (< 123.4 1) #f) (test (< 123.4 1.0 1) #f) (test (< 123.4 1.0 1.0) #f) (test (< 123.4 1.0 1/1) #f) (test (< 123.4 1.0 123.4) #f) (test (< 123.4 1.0 1234) #f) (test (< 123.4 1.0 1234/11) #f) (test (< 123.4 1.0) #f) (test (< 123.4 123.4 1) #f) (test (< 123.4 123.4 1.0) #f) (test (< 123.4 123.4 1/1) #f) (test (< 123.4 123.4 123.4) #f) (test (< 123.4 123.4 1234) #f) (test (< 123.4 123.4 1234/11) #f) (test (< 123.4 123.4) #f) (test (< 123.4 1234 1) #f) (test (< 123.4 1234 1.0) #f) (test (< 123.4 1234 1/1) #f) (test (< 123.4 1234 123.4) #f) (test (< 123.4 1234 1234) #f) (test (< 123.4 1234 1234/11) #f) (test (< 123.4 1234) #t) (test (< 123.4 1234/11 1) #f) (test (< 123.4 1234/11 1.0) #f) (test (< 123.4 1234/11 1/1) #f) (test (< 123.4 1234/11 123.4) #f) (test (< 123.4 1234/11 1234) #f) (test (< 123.4 1234/11 1234/11) #f) (test (< 123.4 1234/11) #f) (test (< 1234 1) #f) (test (< 1234 1.0) #f) (test (< 1234 1/1) #f) (test (< 1234 123.4) #f) (test (< 1234 1234) #f) (test (< 1234 1234/11) #f) (test (< 1234/11 1) #f) (test (< 1234/11 1.0) #f) (test (< 1234/11 1/1) #f) (test (< 1234/11 123.4) #t) (test (< 1234/11 1234) #t) (test (< 1234/11 1234/11) #f) (test (< -0 0) #f) (test (< -0.0 0.0) #f) (test (< -1 2 3 4 4 5 6 7) #f ) (test (< -1 2 3 4 5 6 7 8) #t ) (test (< 0 -0) #f) (test (< 0.0 -0.0) #f) (test (< 1 0+i) 'error) (test (< 1 0-i) 'error) (test (< 1 1 2) #f) (test (< 1 3 2) #f ) (test (< 1+i 0+i) 'error) (test (< 1+i 0-i) 'error) (test (< 2 1 #\a) 'error) (test (< nan.0 1+i) 'error) (test (< nan.0 1 1+i) 'error) (test (< 1 nan.0 1+i) 'error) (test (< inf.0 1+i) 'error) (test (< inf.0 nan.0 0-i 1) 'error) (test (< 2 1+0/2i) #f) (test (< 2 1+0i) #f) (test (< 2 1-0i) #f) (test (< -5 -4 -2 0 4 5) #t) (test (< 0 3 4 4 6) #f) (test (< 0 3 4 6 7) #t) (test (< 0) 'error) (test (<) 'error) (test (< 0.0) 'error) (test (< 0.0+0.00000001i) 'error) (test (< 0/1) 'error) (test (< 1.0) 'error) (test (< 1.0+1.0i) 'error) (test (< 10/3) 'error) (test (< 1234000000.0+2.71828182845905i) 'error) (test (< 2 1 #\a) 'error) (test (< 2 1 1.0+1.0i) 'error) (test (< 2) 'error) (test (< 2.71828182845905+3.14159265358979i) 'error) (test (< 3 -5) #f) (test (< 3 3) #f) (test (< 3 3.0 3 3.0+1.0i) 'error) (test (< 3 5) #t) (test (< 3.0 3) #f) (for-each (lambda (arg) (test (< arg nan.0) 'error) (test (< nan.0 arg) 'error) (test (< arg inf.0) 'error) (test (< inf.0 arg) 'error) (test (< 1 0 arg) 'error) (test (< 1 arg) 'error) (test (< 1.0 arg) 'error) (test (< 1/2 arg) 'error) (test (< arg 1) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) (test (< 1/123400000000 .000000000001) #f) (test (< -1/9223372036854775807 -1/9223372036854775806) #f) (test (< -10/3147483647 -40/12345678901) #f) (test (< -101/3147483647 40/12345678901) #t) (test (< -1047483646/11111111111111 -1234567890213/12345678901123123) #f) (test (< -1047483646/11111111111111 1234567890213/12345678901123123) #t) (test (< -11/3147483647 -40/12345678901) #t) (test (< -1282469252763/12824692526603504 -1234567890213/12345678901123123) #f) (test (< -1282469252763/12824692526603504 1234567890213/12345678901123123) #t) (test (< -1282469252765/12824692526603504 -1234567890213/12345678901123123) #t) (test (< -1282469252765/12824692526603504 1234567890213/12345678901123123) #t) (test (< -2/3 -3147483547123/4) #f) (test (< -2/3 3147483547123/4) #t) (test (< -2/3147483547 -3147483547/3) #f) (test (< -2/3147483547 3147483547/3) #t) (test (< -2147483646/11111111111111 -1234567890213/12345678901123123) #t) (test (< -2147483646/11111111111111 1234567890213/12345678901123123) #t) (test (< -3147483547/2 -3/3147483547) #t) (test (< -3147483547/2 -3147483547/3) #t) (test (< -3147483547/2 3/3147483547) #t) (test (< -3147483547/2 3147483547/3) #t) (test (< -3147483646/11 -12345678901/40) #f) (test (< -3147483646/11 -1234567890213/12345678901123123) #t) (test (< -3147483646/11 -40/12345678901) #t) (test (< -3147483646/11 12345678901/40) #t) (test (< -3147483646/11 1234567890213/12345678901123123) #t) (test (< -3147483646/11 40/12345678901) #t) (test (< -3147483646/11111111111111 -1234567890213/12345678901123123) #t) (test (< -3147483646/11111111111111 1234567890213/12345678901123123) #t) (test (< -3147483646/111111111111111 -1234567890213/12345678901123123) #f) (test (< -3147483646/111111111111111 1234567890213/12345678901123123) #t) (test (< 1/9223372036854775807 1/9223372036854775806) #t) (test (< 10/3147483647 40/12345678901) #t) (test (< 100000000000000.0 100000000000001.0) #t) (test (< 100000000000000/3 100000000000001/3) #t) (test (< 1000000000000000000/3 1000000000000000001/3) #t) (test (< 1047483646/11111111111111 -1234567890213/12345678901123123) #f) (test (< 1047483646/11111111111111 1234567890213/12345678901123123) #t) (test (< 11/3147483647 40/12345678901) #f) (test (< 1282469252763/12824692526603504 -1234567890213/12345678901123123) #f) (test (< 1282469252763/12824692526603504 1234567890213/12345678901123123) #t) (test (< 1282469252765/12824692526603504 -1234567890213/12345678901123123) #f) (test (< 1282469252765/12824692526603504 1234567890213/12345678901123123) #f) (test (< 2/3 -3147483547123/4) #f) (test (< 2/3 3147483547123/4) #t) (test (< 2/3147483547 -3147483547/3) #f) (test (< 2/3147483547 3147483547/3) #t) (test (< 2147483646/11111111111111 -1234567890213/12345678901123123) #f) (test (< 2147483646/11111111111111 1234567890213/12345678901123123) #f) (test (< 3/147483647 40/3) #t) (test (< 3/3147483647 -40/12345678901) #f) (test (< 3/3147483647 40/12345678901) #t) (test (< 3/3147483647 40/3) #t) (test (< 3147483547/2 -3/3147483547) #f) (test (< 3147483547/2 -3147483547/3) #f) (test (< 3147483547/2 3/3147483547) #f) (test (< 3147483547/2 3147483547/3) #f) (test (< 3147483646/11 -12345678901/40) #f) (test (< 3147483646/11 -1234567890213/12345678901123123) #f) (test (< 3147483646/11 -40/12345678901) #f) (test (< 3147483646/11 12345678901/40) #t) (test (< 3147483646/11 1234567890213/12345678901123123) #f) (test (< 3147483646/11 40/12345678901) #f) (test (< 3147483646/11111111111111 -1234567890213/12345678901123123) #f) (test (< 3147483646/11111111111111 1234567890213/12345678901123123) #f) (test (< 3147483646/111111111111111 -1234567890213/12345678901123123) #f) (test (< 3147483646/111111111111111 1234567890213/12345678901123123) #t) (test (< -1.797693134862315699999999999999999999998E308 -9223372036854775808) #t) (test (< -9223372036854775808 -9223372036854775808) #f) (test (< -9223372036854775808 5.551115123125783999999999999999999999984E-17) #t) (test (< -9223372036854775808 9223372036854775807 -9223372036854775808) #f) (test (< 1.110223024625156799999999999999999999997E-16 -9223372036854775808) #f) (test (< 1.110223024625156799999999999999999999997E-16 5.551115123125783999999999999999999999984E-17 5.42101086242752217060000000000000000001E-20) #f) (test (< 5.551115123125783999999999999999999999984E-17 1.110223024625156799999999999999999999997E-16) #t) (test (< 9223372036854775807 -9223372036854775808) #f) (test (< 9223372036854775807 9223372036854775807) #f) (test (< (- 1237940039285380274899124223 1237940039285380000000000000) (- 1.2379400392853803e+27 1237940039285380000000000000) (- 1237940039285380274899124225 1237940039285380000000000000)) #f) (test (< 0 most-negative-fixnum) #f) (test (< 0 most-positive-fixnum) #t) (test (< 1 3 . 2) 'error) (test (< 1237940039285380274899124223 1.2379400392853803e+27 1237940039285380274899124225) #f) (test (< 274899124223 3.0E11 274899124225) #f) (test (< most-negative-fixnum (real-part (log 0.0))) #f) (test (< most-negative-fixnum 0) #t) (test (< most-negative-fixnum most-positive-fixnum) #t) (test (< most-positive-fixnum (- (real-part (log 0.0)))) #t) (test (< most-positive-fixnum 0) #f) (test (< most-positive-fixnum most-negative-fixnum) #f) (test (< -1 1/9223372036854775807 9223372036854775807) #t) (test (< -9223372036854775807 -1/9223372036854775807 1) #t) (test (< -9223372036854775807 -1/9223372036854775807) #t) (test (< 1 9223372036 1/9223372036 1.0) #f) (test (< 1 9223372036 1/9223372036) #f) (test (< 1 922337203685 1/922337203685 1.0) #f) (test (< 1 922337203685 1/922337203685) #f) (test (< 1.0 9223372036 1/9223372036 1) #f) (test (< 1.0 9223372036 1/9223372036) #f) (test (< 1.0 922337203685 1/922337203685 1) #f) (test (< 1.0 922337203685 1/922337203685) #f) (test (< 1/9223372036 9223372036) #t) (test (< 1/922337203685 922337203685) #t) (test (< 1/9223372036854775807 9223372036854775807) #t) (test (< 9223372036 1/9223372036 1) #f) (test (< 9223372036 1/9223372036 1.0) #f) (test (< 9223372036 1/9223372036) #f) (test (< 922337203685 1/922337203685 1) #f) (test (< 922337203685 1/922337203685 1.0) #f) (test (< 922337203685 1/922337203685) #f) (test (< 1.0 9223372036854775807/9223372036854775806) #t) (test (< 9223372036854775806/9223372036854775807 1.0 9223372036854775807/9223372036854775806) #t) (test (< 9223372036854775806/9223372036854775807 1.0) #t) ;;; there are cases that look innocuous that the non-gmp version can't get right: ;;; (< 21053343141/6701487259 3587785776203/1142027682075) ;;; I'll put a few of these in the bignum section (test (< (* 10400200/16483927 1.0) (* 10781274/17087915 1.0)) #f) (test (< (* 10400200/16483927 1.0) 10781274/17087915) #f) (test (< (* 10781274/17087915 1.0) (* 53715833/85137581 1.0)) #t) (test (< (* 10781274/17087915 1.0) 53715833/85137581) #t) (test (< (* 12/19 1.0) (* 53/84 1.0)) #f) (test (< (* 12/19 1.0) 53/84) #f) (test (< (* 12941/20511 1.0) (* 15601/24727 1.0)) #t) (test (< (* 12941/20511 1.0) 15601/24727) #t) (test (< (* 15601/24727 1.0) (* 79335/125743 1.0)) #t) (test (< (* 15601/24727 1.0) 79335/125743) #t) ;;; (if with-bignums (test (< (* 171928773/272500658 1.0) (* 397573379/630138897 1.0)) #t)) ;;; this requires more precision than 128 bits (test (negative? (- 171928773/272500658 397573379/630138897)) #t) ; so the first is less ;; clisp, sbcl, guile, non-gmp s7 all say #f for the < comparison of reals (test (< 171928773/272500658 397573379/630138897) #t) ;;; (= (* 171928773/272500658 1.0D0) (* 397573379/630138897 1.0D0)) -- clisp, sbcl, non-gmp s7, and guile say true (test (< (* 171928773/272500658 1.0) 397573379/630138897) #t) (test (< (* 190537/301994 1.0) (* 7161071/11350029 1.0)) #t) (test (< (* 190537/301994 1.0) 7161071/11350029) #t) (test (< (* 2/3 1.0) (* 5/8 1.0)) #f) (test (< (* 2/3 1.0) 5/8) #f) (test (< (* 253/401 1.0) (* 665/1054 1.0)) #t) (test (< (* 253/401 1.0) 665/1054) #t) (if with-bignums (test (< (* 397573379/630138897 1.0) (* 4201378396/6659027209 1.0)) #t)) ;;; fraction -> double troubles -- this is ok if s7_double is long double in s7.h (test (< (* 397573379/630138897 1.0) 4201378396/6659027209) #t) (test (< (* 4201378396/6659027209 1.0) (* 6189245291/9809721694 1.0)) #f) (if with-bignums (test (< (* 4201378396/6659027209 1.0) 6189245291/9809721694) #f)) (test (< (* 5/8 1.0) (* 12/19 1.0)) #t) (test (< (* 5/8 1.0) 12/19) #t) (test (< (* 53/84 1.0) (* 253/401 1.0)) #f) (test (< (* 53/84 1.0) 253/401) #f) (test (< (* 53715833/85137581 1.0) (* 171928773/272500658 1.0)) #f) ;;; (if with-bignums (test (< (* 53715833/85137581 1.0) 171928773/272500658) #f)) -- needs more than 128 bits (test (< 53715833/85137581 171928773/272500658) #f) (test (< (* 665/1054 1.0) (* 12941/20511 1.0)) #f) (test (< (* 665/1054 1.0) 12941/20511) #f) (test (< (* 7161071/11350029 1.0) (* 10400200/16483927 1.0)) #f) (test (< (* 7161071/11350029 1.0) 10400200/16483927) #f) (test (< (* 79335/125743 1.0) (* 190537/301994 1.0)) #t) (test (< (* 79335/125743 1.0) 190537/301994) #t) (test (< 10400200/16483927 10781274/17087915) #f) (test (< 10781274/17087915 53715833/85137581) #t) (test (< 12/19 53/84) #f) (test (< 12941/20511 15601/24727) #t) (test (< 15601/24727 79335/125743) #t) (test (< 171928773/272500658 397573379/630138897) #t) (test (< 190537/301994 7161071/11350029) #t) (test (< 2/3 5/8) #f) (test (< 253/401 665/1054) #t) (test (< 397573379/630138897 4201378396/6659027209) #t) (test (< 4201378396/6659027209 6189245291/9809721694) #f) (test (< 5/8 12/19) #t) (test (< 53/84 253/401) #f) (test (< 53715833/85137581 171928773/272500658) #f) (test (< 665/1054 12941/20511) #f) (test (< 7161071/11350029 10400200/16483927) #f) (test (< 79335/125743 190537/301994) #t) (test (< 131836323/93222358 110442295/78088974 125383891/88652904 61328902/43362679 138113653/97653429 254989762/180290825 393920845/278522218 100728653/71220318 175072959/123785551 278215191/196712393 ) #t) (test (< 10812186007/7645370045 18338419250/12967220607 13343405959/9435212837 11079453630/7834356793 6071445385/4293160203 14707776949/10399968816 22357396263/15809066506 77901127500/55084415513 2284381030/1615301317 10340752226/7312016021 ) #t) (test (< 886731088897/627013566048 1534756075495/1085236428449 244625906708/172976637487 1462171251759/1033911207374 1743861030874/1233095960377 954593412651/674999475361 ) #t) (test (< 10651773591371/984771132841 1.081649758092772603273242802490196379734E1 22691355773217/2095909383391 1.082649668092772603273242802490196379733E1 11269199657045/1040794570824 1.08274965909277260327324280249019637973E1 ) #t) (test (< 11320859/1046629 1.081649758092772603273242802490196379734E1 10021556/926421 1.081749668092772603273242802490196379733E1 12893515/1191902 1.08175965909277260327324280249019637973E1 ) #t) (test (< 11320859/1046629 1.081649659092772603273242802490196379732E1 6398591/591558 1.081650658192772603273242802490196379729E1 14562686/1346339 1.081650758102772603273242802490196379731E1 ) #t) (test (< 11320859/1046629 1.081649658102772603273242802490196379729E1 8517115/787419 1.081649668093772603273242802490196379735E1 9667298/893755 1.081649669092872603273242802490196379734E1 ) #t) (test (< 1109328651/102558961 1.08164965809278260327324280249019637973E1 1412995811/130633408 1.081649658102773603273242802490196379729E1 753823853/69692053 1.081649658103772703273242802490196379731E1 ) #t) (if with-bignums (begin (test (< 12345678901234567890 12345678901234567891) #t) (test (< -9223372036854775808 -9223372036854775809) #f) (test (< -9223372036854775809 -9223372036854775808) #t) (test (< 9223372036854775808 9223372036854775807) #f) (test (< 9223372036854775808 1e19) #t) (test (< 9223372036854775807 85070591730234615865843651857942052865/9223372036854775807) #t) (test (< 1.000e19 1267650600228229401496703205376 1e20) #f) (test (< 4272943/1360120 21053343141/6701487259 3587785776203/1142027682075 2646693125139304345/842468587426513207) #t) (test (< 4272943/1360120 21053343141/6701487259 3587785776203/1142027682075) #t) (test (< 4272943/1360120 21053343141/6701487259 3587785776203/1142027682075 355/113) #t) (test (< 21053343141/6701487259 3587785776203/1142027682075 355/113) #t) (test (< 4272943/1360120 21053343141/6701487259 3587785776203/1142027682075) #t) (test (< 21053343141/6701487259 3587785776203/1142027682075) #t) (test (< 886731088897/627013566048 1534756075495/1085236428449 244625906708/172976637487 1462171251759/1033911207374 1743861030874/1233095960377 954593412651/674999475361 902779846866/638361751637 2968095823096/2098760683721 1684058273173/1190809024873 2947786590277/2084399887474 ) #t) (test (< 1023286908188737/723573111879672 1763020673688684/1246643873737343 1430528867885681/1011536663165079 2711447141769903/1917282660774379 575142878279173/406687429382352 935610884438753/661576800938585 2339755998541282/1654457332890441 1443730843578617/1020871869702614 478219565475493/338152297643805 2026075188260327/1432651504812687 ) #t) (test (< 1267650600228229401496703205376) 'error) (test (< 1.0 1267650600228229401496703205376+i) 'error) )) ;;; -------------------------------------------------------------------------------- ;;; <= ;;; -------------------------------------------------------------------------------- (test (<= 0 1 1) #t) (test (<= 0 1 1.0) #t) (test (<= 0 1 1/1) #t) (test (<= 0 1 123.4) #t) (test (<= 0 1 1234) #t) (test (<= 0 1 1234/11) #t) (test (<= 0 1) #t) (test (<= 0 1.0 1) #t) (test (<= 0 1.0 1.0) #t) (test (<= 0 1.0 1/1) #t) (test (<= 0 1.0 123.4) #t) (test (<= 0 1.0 1234) #t) (test (<= 0 1.0 1234/11) #t) (test (<= 0 1.0) #t) (test (<= 0 123.4) #t) (test (<= 0 1234) #t) (test (<= 0 1234/11) #t) (test (<= 0.0 1 1.0) #t) (test (<= 0.0 1 1/1) #t) (test (<= 0.0 1 123.4) #t) (test (<= 0.0 1 1234) #t) (test (<= 0.0 1 1234/11) #t) (test (<= 0.0 1) #t) (test (<= 0.0 1.0 1) #t) (test (<= 0.0 1.0 1.0) #t) (test (<= 0.0 1.0 1/1) #t) (test (<= 0.0 1.0 123.4) #t) (test (<= 0.0 1.0 1234) #t) (test (<= 0.0 1.0 1234/11) #t) (test (<= 0.0 1.0) #t) (test (<= 0.0 123.4 1) #f) (test (<= 0.0 123.4 1.0) #f) (test (<= 0.0 123.4 1/1) #f) (test (<= 0.0 123.4 123.4) #t) (test (<= 0.0 123.4 1234) #t) (test (<= 0.0 123.4 1234/11) #f) (test (<= 0.0 123.4) #t) (test (<= 0.0 1234 1) #f) (test (<= 0.0 1234 1.0) #f) (test (<= 0.0 1234 1/1) #f) (test (<= 0.0 1234 123.4) #f) (test (<= 0.0 1234 1234) #t) (test (<= 0.0 1234 1234/11) #f) (test (<= 0.0 1234) #t) (test (<= 0.0 1234/11 1) #f) (test (<= 0.0 1234/11 1.0) #f) (test (<= 0.0 1234/11 1/1) #f) (test (<= 0.0 1234/11 123.4) #t) (test (<= 0.0 1234/11 1234) #t) (test (<= 0.0 1234/11 1234/11) #t) (test (<= 0.0 1234/11) #t) (test (<= 1 1 1) #t) (test (<= 1 1 1.0) #t) (test (<= 1 1 1/1) #t) (test (<= 1 1 123.4) #t) (test (<= 1 1 1234) #t) (test (<= 1 1 1234/11) #t) (test (<= 1 1) #t) (test (<= 1 1.0 1) #t) (test (<= 1 1.0 1.0) #t) (test (<= 1 1.0 1/1) #t) (test (<= 1 1.0 123.4) #t) (test (<= 1 1.0 1234) #t) (test (<= 1 1.0 1234/11) #t) (test (<= 1 1.0) #t) (test (<= 1 123.4) #t) (test (<= 1 1234) #t) (test (<= 1 1234/11) #t) (test (<= 1.0 1 1) #t) (test (<= 1.0 1 1.0) #t) (test (<= 1.0 1 1/1) #t) (test (<= 1.0 1 123.4) #t) (test (<= 1.0 1 1234) #t) (test (<= 1.0 1 1234/11) #t) (test (<= 1.0 1) #t) (test (<= 1.0 1.0 1) #t) (test (<= 1.0 1.0 1.0) #t) (test (<= 1.0 1.0 1/1) #t) (test (<= 1.0 1.0 123.4) #t) (test (<= 1.0 1.0 1234) #t) (test (<= 1.0 1.0 1234/11) #t) (test (<= 1.0 1.0) #t) (test (<= 1.0 123.4 1) #f) (test (<= 1.0 123.4 1.0) #f) (test (<= 1.0 123.4 1/1) #f) (test (<= 1.0 123.4 123.4) #t) (test (<= 1.0 123.4 1234) #t) (test (<= 1.0 123.4 1234/11) #f) (test (<= 1.0 123.4) #t) (test (<= 1.0 1234 1) #f) (test (<= 1.0 1234 1.0) #f) (test (<= 1.0 1234 1/1) #f) (test (<= 1.0 1234 123.4) #f) (test (<= 1.0 1234 1234) #t) (test (<= 1.0 1234 1234/11) #f) (test (<= 1.0 1234) #t) (test (<= 1.0 1234/11 1) #f) (test (<= 1.0 1234/11 1.0) #f) (test (<= 1.0 1234/11 1/1) #f) (test (<= 1.0 1234/11 123.4) #t) (test (<= 1.0 1234/11 1234) #t) (test (<= 1.0 1234/11 1234/11) #t) (test (<= 1.0 1234/11) #t) (test (<= 123.4 1 1) #f) (test (<= 123.4 1 1.0) #f) (test (<= 123.4 1 1/1) #f) (test (<= 123.4 1 123.4) #f) (test (<= 123.4 1 1234) #f) (test (<= 123.4 1 1234/11) #f) (test (<= 123.4 1) #f) (test (<= 123.4 1.0 1) #f) (test (<= 123.4 1.0 1.0) #f) (test (<= 123.4 1.0 1/1) #f) (test (<= 123.4 1.0 123.4) #f) (test (<= 123.4 1.0 1234) #f) (test (<= 123.4 1.0 1234/11) #f) (test (<= 123.4 1.0) #f) (test (<= 123.4 123.4 1) #f) (test (<= 123.4 123.4 1.0) #f) (test (<= 123.4 123.4 1/1) #f) (test (<= 123.4 123.4 123.4) #t) (test (<= 123.4 123.4 1234) #t) (test (<= 123.4 123.4 1234/11) #f) (test (<= 123.4 123.4) #t) (test (<= 123.4 1234 1) #f) (test (<= 123.4 1234 1.0) #f) (test (<= 123.4 1234 1/1) #f) (test (<= 123.4 1234 123.4) #f) (test (<= 123.4 1234 1234) #t) (test (<= 123.4 1234 1234/11) #f) (test (<= 123.4 1234) #t) (test (<= 123.4 1234/11 1) #f) (test (<= 123.4 1234/11 1.0) #f) (test (<= 123.4 1234/11 1/1) #f) (test (<= 123.4 1234/11 123.4) #f) (test (<= 123.4 1234/11 1234) #f) (test (<= 123.4 1234/11 1234/11) #f) (test (<= 123.4 1234/11) #f) (test (<= 1234 1) #f) (test (<= 1234 1.0) #f) (test (<= 1234 1/1) #f) (test (<= 1234 123.4) #f) (test (<= 1234 1234) #t) (test (<= 1234 1234/11) #f) (test (<= 1234/11 1) #f) (test (<= 1234/11 1.0) #f) (test (<= 1234/11 1/1) #f) (test (<= 1234/11 123.4) #t) (test (<= 1234/11 1234) #t) (test (<= 1234/11 1234/11) #t) (test (<= -1 2 3 4 4 5 6 7) #t ) (test (<= -1 2 3 4 5 6 7 8) #t ) (test (<= 1 0+i) 'error) (test (<= 1 0-i) 'error) (test (<= 1+i 0+i) 'error) (test (<= 1+i 0-i) 'error) (test (<= 2 1 #\a) 'error) (test (<= 2 1+0/2i) #f) (test (<= 2 1+0i) #f) (test (<= 2 1-0i) #f) (test (<= 2 2 1) #f) (test (<= 0 3 4 4 6) #t) (test (<= 0 3 4 6 7) #t) (test (<= 0) 'error) (test (<=) 'error) (test (<= 0.0) 'error) (test (<= 0.0+0.00000001i) 'error) (test (<= 0/1) 'error) (test (<= 1 3 3 2 5) #f) (test (<= 1.0) 'error) (test (<= 1.0+1.0i) 'error) (test (<= nan.0 1+i) 'error) (test (<= nan.0 1 1+i) 'error) (test (<= 1 nan.0 1+i) 'error) (test (<= inf.0 1+i) 'error) (test (<= inf.0 nan.0 0-i 1) 'error) (test (<= 10/3) 'error) (test (<= 1234000000.0+2.71828182845905i) 'error) (test (<= 2 1 #\a) 'error) (test (<= 2 1 1.0+1.0i) 'error) (test (<= 2) 'error) (test (<= 2.71828182845905+3.14159265358979i) 'error) (test (<= 3 -5) #f) (test (<= 3 3) #t) (test (<= 3 3) #t) (test (<= 3 5) #t) (test (<= 3.0 3) #t) (test (<= 5/2 2.5) #t) (test (<= -1.797693134862315699999999999999999999998E308 -9223372036854775808) #t) (test (<= -9223372036854775808 -9223372036854775808) #t) (test (<= -9223372036854775808 5.551115123125783999999999999999999999984E-17) #t) (test (<= -9223372036854775808 9223372036854775807 -9223372036854775808) #f) (test (<= 1.110223024625156799999999999999999999997E-16 -9223372036854775808) #f) (test (<= 1.110223024625156799999999999999999999997E-16 5.551115123125783999999999999999999999984E-17 5.42101086242752217060000000000000000001E-20) #f) (test (<= 5.551115123125783999999999999999999999984E-17 1.110223024625156799999999999999999999997E-16) #t) (test (<= 9223372036854775807 -9223372036854775808) #f) (test (<= 9223372036854775807 9223372036854775807) #t) (test (<= -1 -1/9223372036854775807 -9223372036854775807 1) #f) (test (<= -1 -1/9223372036854775807 -9223372036854775807) #f) (test (<= -1 1 9223372036854775807 1/9223372036854775807) #f) (test (<= -1 9223372036854775807 1/9223372036854775807 1) #f) (test (<= -1 9223372036854775807 1/9223372036854775807) #f) (test (<= -1/9223372036854775807 -9223372036854775807 -1 1) #f) (test (<= -1/9223372036854775807 -9223372036854775807 -1) #f) (test (<= -1/9223372036854775807 -9223372036854775807 1) #f) (test (<= -1/9223372036854775807 -9223372036854775807) #f) (test (<= 1 1.0 9223372036 1/9223372036) #f) (test (<= 1 1.0 922337203685 1/922337203685) #f) (test (<= 1 9223372036 1/9223372036 1.0) #f) (test (<= 1 9223372036 1/9223372036) #f) (test (<= 1 922337203685 1/922337203685 1.0) #f) (test (<= 1 922337203685 1/922337203685) #f) (test (<= 1 9223372036854775807 1/9223372036854775807) #f) (test (<= 1.0 1 9223372036 1/9223372036) #f) (test (<= 1.0 1 922337203685 1/922337203685) #f) (test (<= 1.0 9223372036 1/9223372036 1) #f) (test (<= 1.0 9223372036 1/9223372036) #f) (test (<= 1.0 922337203685 1/922337203685 1) #f) (test (<= 1.0 922337203685 1/922337203685) #f) (test (<= 1/9223372036 9223372036) #t) (test (<= 1/922337203685 922337203685) #t) (test (<= 9223372036 1/9223372036 1 1.0) #f) (test (<= 9223372036 1/9223372036 1) #f) (test (<= 9223372036 1/9223372036 1.0 1) #f) (test (<= 9223372036 1/9223372036 1.0) #f) (test (<= 9223372036 1/9223372036) #f) (test (<= 922337203685 1/922337203685 1 1.0) #f) (test (<= 922337203685 1/922337203685 1) #f) (test (<= 922337203685 1/922337203685 1.0 1) #f) (test (<= 922337203685 1/922337203685 1.0) #f) (test (<= 922337203685 1/922337203685) #f) (test (<= 9223372036854775807 1/9223372036854775807 1) #f) (test (<= 9223372036854775807 1/9223372036854775807) #f) (test (<= 1 1.0 9223372036854775806/9223372036854775807 9223372036854775807/9223372036854775806) #f) (test (<= 1 1.0 9223372036854775806/9223372036854775807) #f) (test (<= 1 9223372036854775807/9223372036854775806 1.0 9223372036854775806/9223372036854775807) #f) (test (<= 1 9223372036854775807/9223372036854775806 1.0) #f) (test (<= 1.0 9223372036854775806/9223372036854775807 1 9223372036854775807/9223372036854775806) #f) (test (<= 1.0 9223372036854775806/9223372036854775807 1) #f) (test (<= 1.0 9223372036854775806/9223372036854775807 9223372036854775807/9223372036854775806) #f) (test (<= 1.0 9223372036854775806/9223372036854775807) #f) (test (<= 9223372036854775806/9223372036854775807 1 9223372036854775807/9223372036854775806 1.0) #f) (test (<= 9223372036854775806/9223372036854775807 9223372036854775807/9223372036854775806 1.0 1) #f) (test (<= 9223372036854775806/9223372036854775807 9223372036854775807/9223372036854775806 1.0) #f) (test (<= 9223372036854775807/9223372036854775806 1.0 1) #f) (test (<= 9223372036854775807/9223372036854775806 1.0 9223372036854775806/9223372036854775807 1) #f) (test (<= 9223372036854775807/9223372036854775806 1.0 9223372036854775806/9223372036854775807) #f) (test (<= 9223372036854775807/9223372036854775806 1.0) #f) (if with-bignums (begin (test (<= 12345678901234567890 12345678901234567891) #t) (test (<= 4272943/1360120 21053343141/6701487259 2646693125139304345/842468587426513207 3587785776203/1142027682075) #f) (test (<= 4272943/1360120 3587785776203/1142027682075 21053343141/6701487259 2646693125139304345/842468587426513207) #f) (test (<= 4272943/1360120 3587785776203/1142027682075 21053343141/6701487259) #f) (test (<= 4272943/1360120 2646693125139304345/842468587426513207 3587785776203/1142027682075) #f) (test (<= 21053343141/6701487259 2646693125139304345/842468587426513207 3587785776203/1142027682075) #f) (test (<= 3587785776203/1142027682075 21053343141/6701487259 2646693125139304345/842468587426513207) #f) (test (<= 3587785776203/1142027682075 21053343141/6701487259) #f) (test (<= 2646693125139304345/842468587426513207 21053343141/6701487259) #f) (test (<= 4272943/1360120 3587785776203/1142027682075 21053343141/6701487259 355/113) #f) (test (<= 3587785776203/1142027682075 21053343141/6701487259 355/113) #f) (test (<= 4272943/1360120 3587785776203/1142027682075 21053343141/6701487259) #f) (test (<= 3587785776203/1142027682075 21053343141/6701487259) #f) (test (<= 1267650600228229401496703205376) 'error) )) (for-each (lambda (arg) (test (<= arg nan.0) 'error) (test (<= nan.0 arg) 'error) (test (<= arg inf.0) 'error) (test (<= inf.0 arg) 'error) (test (<= 1 0 arg) 'error) (test (<= 1 arg) 'error) (test (<= 1.0 arg) 'error) (test (<= 1/2 arg) 'error) (test (<= arg 1) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) ;;; -------------------------------------------------------------------------------- ;;; = ;;; -------------------------------------------------------------------------------- (test (= -1.0+1.0i -1.0+1.0i) #t) (test (= -1.0+1.0i 0.0+1.0i) #f) (test (= -1.0+1.0i 1) #f) (test (= -1.0+1.0i 1.0) #f) (test (= -1.0+1.0i 1.0+1.0i) #f) (test (= -1.0+1.0i 1.234+1.234i) #f) (test (= -1.0+1.0i 1/1) #f) (test (= -1.0+1.0i 123.4) #f) (test (= -1.0+1.0i 1234) #f) (test (= -1.0+1.0i 1234/11) #f) (test (= 0 -1.0+1.0i) #f) (test (= 0 0.0+1.0i) #f) (test (= 0 1 -1.0+1.0i) #f) (test (= 0 1 0.0+1.0i) #f) (test (= 0 1 1) #f) (test (= 0 1 1.0) #f) (test (= 0 1 1.0+1.0i) #f) (test (= 0 1 1.234+1.234i) #f) (test (= 0 1 1/1) #f) (test (= 0 1 123.4) #f) (test (= 0 1 1234) #f) (test (= 0 1 1234/11) #f) (test (= 0 1) #f) (test (= 0 -0) #t) (test (= 0 1.0 -1.0+1.0i) #f) (test (= 0 1.0 0.0+1.0i) #f) (test (= 0 1.0 1) #f) (test (= 0 1.0 1.0) #f) (test (= 0 1.0 1.0+1.0i) #f) (test (= 0 1.0 1.234+1.234i) #f) (test (= 0 1.0 1/1) #f) (test (= 0 1.0 123.4) #f) (test (= 0 1.0 1234) #f) (test (= 0 1.0 1234/11) #f) (test (= 0 1.0) #f) (test (= 0 1.0+1.0i -1.0+1.0i) #f) (test (= 0 1.0+1.0i 0.0+1.0i) #f) (test (= 0 1.0+1.0i 1) #f) (test (= 0 1.0+1.0i 1.0) #f) (test (= 0 1.0+1.0i 1.0+1.0i) #f) (test (= 0 1.0+1.0i 1.234+1.234i) #f) (test (= 0 1.0+1.0i 1/1) #f) (test (= 0 1.0+1.0i 123.4) #f) (test (= 0 1.0+1.0i 1234) #f) (test (= 0 1.0+1.0i 1234/11) #f) (test (= 0 1.0+1.0i) #f) (test (= 0 1.234+1.234i) #f) (test (= 0 123.4) #f) (test (= 0 1234) #f) (test (= 0 1234/11) #f) (test (= 0.0 -1.0+1.0i -1.0+1.0i) #f) (test (= 0.0 -1.0+1.0i 0.0+1.0i) #f) (test (= 0.0 -1.0+1.0i 1) #f) (test (= 0.0 -1.0+1.0i 1.0) #f) (test (= 0.0 -1.0+1.0i 1.0+1.0i) #f) (test (= 0.0 -1.0+1.0i 1.234+1.234i) #f) (test (= 0.0 -1.0+1.0i 1/1) #f) (test (= 0.0 -1.0+1.0i 123.4) #f) (test (= 0.0 -1.0+1.0i 1234) #f) (test (= 0.0 -1.0+1.0i 1234/11) #f) (test (= 0.0 -1.0+1.0i) #f) (test (= 0.0 0.0+1.0i -1.0+1.0i) #f) (test (= 0.0 0.0+1.0i 0.0+1.0i) #f) (test (= 0.0 0.0+1.0i 1) #f) (test (= 0.0 0.0+1.0i 1.0) #f) (test (= 0.0 0.0+1.0i 1.0+1.0i) #f) (test (= 0.0 0.0+1.0i 1.234+1.234i) #f) (test (= 0.0 0.0+1.0i 1/1) #f) (test (= 0.0 0.0+1.0i 123.4) #f) (test (= 0.0 0.0+1.0i 1234) #f) (test (= 0.0 0.0+1.0i 1234/11) #f) (test (= 0.0 0.0+1.0i) #f) (test (= 0.0 1 -1.0+1.0i) #f) (test (= 0.0 1 0.0+1.0i) #f) (test (= 0.0 1 1.0) #f) (test (= 0.0 1 1.0+1.0i) #f) (test (= 0.0 1 1.234+1.234i) #f) (test (= 0.0 1 1/1) #f) (test (= 0.0 1 123.4) #f) (test (= 0.0 1 1234) #f) (test (= 0.0 1 1234/11) #f) (test (= 0.0 1) #f) (test (= 0.0 1.0 -1.0+1.0i) #f) (test (= 0.0 1.0 0.0+1.0i) #f) (test (= 0.0 1.0 1) #f) (test (= 0.0 1.0 1.0) #f) (test (= 0.0 1.0 1.0+1.0i) #f) (test (= 0.0 1.0 1.234+1.234i) #f) (test (= 0.0 1.0 1/1) #f) (test (= 0.0 1.0 123.4) #f) (test (= 0.0 1.0 1234) #f) (test (= 0.0 1.0 1234/11) #f) (test (= 0.0 1.0) #f) (test (= 0.0 1.0+1.0i -1.0+1.0i) #f) (test (= 0.0 1.0+1.0i 0.0+1.0i) #f) (test (= 0.0 1.0+1.0i 1) #f) (test (= 0.0 1.0+1.0i 1.0) #f) (test (= 0.0 1.0+1.0i 1.0+1.0i) #f) (test (= 0.0 1.0+1.0i 1.234+1.234i) #f) (test (= 0.0 1.0+1.0i 1/1) #f) (test (= 0.0 1.0+1.0i 123.4) #f) (test (= 0.0 1.0+1.0i 1234) #f) (test (= 0.0 1.0+1.0i 1234/11) #f) (test (= 0.0 1.0+1.0i) #f) (test (= 0.0 1.234+1.234i -1.0+1.0i) #f) (test (= 0.0 1.234+1.234i 0.0+1.0i) #f) (test (= 0.0 1.234+1.234i 1) #f) (test (= 0.0 1.234+1.234i 1.0) #f) (test (= 0.0 1.234+1.234i 1.0+1.0i) #f) (test (= 0.0 1.234+1.234i 1.234+1.234i) #f) (test (= 0.0 1.234+1.234i 1/1) #f) (test (= 0.0 1.234+1.234i 123.4) #f) (test (= 0.0 1.234+1.234i 1234) #f) (test (= 0.0 1.234+1.234i 1234/11) #f) (test (= 0.0 1.234+1.234i) #f) (test (= 0.0 123.4 -1.0+1.0i) #f) (test (= 0.0 123.4 0.0+1.0i) #f) (test (= 0.0 123.4 1) #f) (test (= 0.0 123.4 1.0) #f) (test (= 0.0 123.4 1.0+1.0i) #f) (test (= 0.0 123.4 1.234+1.234i) #f) (test (= 0.0 123.4 1/1) #f) (test (= 0.0 123.4 123.4) #f) (test (= 0.0 123.4 1234) #f) (test (= 0.0 123.4 1234/11) #f) (test (= 0.0 123.4) #f) (test (= 0.0 1234 -1.0+1.0i) #f) (test (= 0.0 1234 0.0+1.0i) #f) (test (= 0.0 1234 1) #f) (test (= 0.0 1234 1.0) #f) (test (= 0.0 1234 1.0+1.0i) #f) (test (= 0.0 1234 1.234+1.234i) #f) (test (= 0.0 1234 1/1) #f) (test (= 0.0 1234 123.4) #f) (test (= 0.0 1234 1234) #f) (test (= 0.0 1234 1234/11) #f) (test (= 0.0 1234) #f) (test (= 0.0 1234/11 -1.0+1.0i) #f) (test (= 0.0 1234/11 0.0+1.0i) #f) (test (= 0.0 1234/11 1) #f) (test (= 0.0 1234/11 1.0) #f) (test (= 0.0 1234/11 1.0+1.0i) #f) (test (= 0.0 1234/11 1.234+1.234i) #f) (test (= 0.0 1234/11 1/1) #f) (test (= 0.0 1234/11 123.4) #f) (test (= 0.0 1234/11 1234) #f) (test (= 0.0 1234/11 1234/11) #f) (test (= 0.0 1234/11) #f) (test (= 0.0+1.0i -1.0+1.0i) #f) (test (= 0.0+1.0i 0.0+1.0i) #t) (test (= 0.0+1.0i 1) #f) (test (= 0.0+1.0i 1.0) #f) (test (= 0.0+1.0i 1.0+1.0i) #f) (test (= 0.0+1.0i 1.234+1.234i) #f) (test (= 0.0+1.0i 1/1) #f) (test (= 0.0+1.0i 123.4) #f) (test (= 0.0+1.0i 1234) #f) (test (= 0.0+1.0i 1234/11) #f) (test (= 1 -1) #f) (test (= 1 -1.0+1.0i) #f) (test (= 1 -2) #f) (test (= 1 0.0+1.0i) #f) (test (= 1 1 -1.0+1.0i) #f) (test (= 1 1 0.0+1.0i) #f) (test (= 1 1 1) #t) (test (= 1 1 1.0) #t) (test (= 1 1 1.0+1.0i) #f) (test (= 1 1 1.234+1.234i) #f) (test (= 1 1 1/1) #t) (test (= 1 1 123.4) #f) (test (= 1 1 1234) #f) (test (= 1 1 1234/11) #f) (test (= 1 1) #t) (test (= 1 1.0 -1.0+1.0i) #f) (test (= 1 1.0 0.0+1.0i) #f) (test (= 1 1.0 1) #t) (test (= 1 1.0 1.0) #t) (test (= 1 1.0 1.0+1.0i) #f) (test (= 1 1.0 1.234+1.234i) #f) (test (= 1 1.0 1/1) #t) (test (= 1 1.0 123.4) #f) (test (= 1 1.0 1234) #f) (test (= 1 1.0 1234/11) #f) (test (= 1 1.0) #t) (test (= 1 1.0+1.0i -1.0+1.0i) #f) (test (= 1 1.0+1.0i 0.0+1.0i) #f) (test (= 1 1.0+1.0i 1) #f) (test (= 1 1.0+1.0i 1.0) #f) (test (= 1 1.0+1.0i 1.0+1.0i) #f) (test (= 1 1.0+1.0i 1.234+1.234i) #f) (test (= 1 1.0+1.0i 1/1) #f) (test (= 1 1.0+1.0i 123.4) #f) (test (= 1 1.0+1.0i 1234) #f) (test (= 1 1.0+1.0i 1234/11) #f) (test (= 1 1.0+1.0i) #f) (test (= 1 1.234+1.234i) #f) (test (= 1 123.4) #f) (test (= 1 1234) #f) (test (= 1 1234/11) #f) (test (= 1.0 -1.0) #f) (test (= 1.0 -1.0+1.0i -1.0+1.0i) #f) (test (= 1.0 -1.0+1.0i 0.0+1.0i) #f) (test (= 1.0 -1.0+1.0i 1) #f) (test (= 1.0 -1.0+1.0i 1.0) #f) (test (= 1.0 -1.0+1.0i 1.0+1.0i) #f) (test (= 1.0 -1.0+1.0i 1.234+1.234i) #f) (test (= 1.0 -1.0+1.0i 1/1) #f) (test (= 1.0 -1.0+1.0i 123.4) #f) (test (= 1.0 -1.0+1.0i 1234) #f) (test (= 1.0 -1.0+1.0i 1234/11) #f) (test (= 1.0 -1.0+1.0i) #f) (test (= 1.0 0.0+1.0i -1.0+1.0i) #f) (test (= 1.0 0.0+1.0i 0.0+1.0i) #f) (test (= 1.0 0.0+1.0i 1) #f) (test (= 1.0 0.0+1.0i 1.0) #f) (test (= 1.0 0.0+1.0i 1.0+1.0i) #f) (test (= 1.0 0.0+1.0i 1.234+1.234i) #f) (test (= 1.0 0.0+1.0i 1/1) #f) (test (= 1.0 0.0+1.0i 123.4) #f) (test (= 1.0 0.0+1.0i 1234) #f) (test (= 1.0 0.0+1.0i 1234/11) #f) (test (= 1.0 0.0+1.0i) #f) (test (= 1.0 1 -1.0+1.0i) #f) (test (= 1.0 1 0.0+1.0i) #f) (test (= 1.0 1 1) #t) (test (= 1.0 1 1.0) #t) (test (= 1.0 1 1.0+1.0i) #f) (test (= 1.0 1 1.234+1.234i) #f) (test (= 1.0 1 1/1) #t) (test (= 1.0 1 123.4) #f) (test (= 1.0 1 1234) #f) (test (= 1.0 1 1234/11) #f) (test (= 1.0 1) #t) (test (= 1.0 1.0 -1.0+1.0i) #f) (test (= 1.0 1.0 0.0+1.0i) #f) (test (= 1.0 1.0 1) #t) (test (= 1.0 1.0 1.0) #t) (test (= 1.0 1.0 1.0+1.0i) #f) (test (= 1.0 1.0 1.234+1.234i) #f) (test (= 1.0 1.0 1/1) #t) (test (= 1.0 1.0 123.4) #f) (test (= 1.0 1.0 1234) #f) (test (= 1.0 1.0 1234/11) #f) (test (= 1.0 1.0) #t) (test (= 1.0 1.0+1.0i -1.0+1.0i) #f) (test (= 1.0 1.0+1.0i 0.0+1.0i) #f) (test (= 1.0 1.0+1.0i 1) #f) (test (= 1.0 1.0+1.0i 1.0) #f) (test (= 1.0 1.0+1.0i 1.0+1.0i) #f) (test (= 1.0 1.0+1.0i 1.234+1.234i) #f) (test (= 1.0 1.0+1.0i 1/1) #f) (test (= 1.0 1.0+1.0i 123.4) #f) (test (= 1.0 1.0+1.0i 1234) #f) (test (= 1.0 1.0+1.0i 1234/11) #f) (test (= 1.0 1.0+1.0i) #f) (test (= 1.0 1.234+1.234i -1.0+1.0i) #f) (test (= 1.0 1.234+1.234i 0.0+1.0i) #f) (test (= 1.0 1.234+1.234i 1) #f) (test (= 1.0 1.234+1.234i 1.0) #f) (test (= 1.0 1.234+1.234i 1.0+1.0i) #f) (test (= 1.0 1.234+1.234i 1.234+1.234i) #f) (test (= 1.0 1.234+1.234i 1/1) #f) (test (= 1.0 1.234+1.234i 123.4) #f) (test (= 1.0 1.234+1.234i 1234) #f) (test (= 1.0 1.234+1.234i 1234/11) #f) (test (= 1.0 1.234+1.234i) #f) (test (= 1.0 123.4 -1.0+1.0i) #f) (test (= 1.0 123.4 0.0+1.0i) #f) (test (= 1.0 123.4 1) #f) (test (= 1.0 123.4 1.0) #f) (test (= 1.0 123.4 1.0+1.0i) #f) (test (= 1.0 123.4 1.234+1.234i) #f) (test (= 1.0 123.4 1/1) #f) (test (= 1.0 123.4 123.4) #f) (test (= 1.0 123.4 1234) #f) (test (= 1.0 123.4 1234/11) #f) (test (= 1.0 123.4) #f) (test (= 1.0 1234 -1.0+1.0i) #f) (test (= 1.0 1234 0.0+1.0i) #f) (test (= 1.0 1234 1) #f) (test (= 1.0 1234 1.0) #f) (test (= 1.0 1234 1.0+1.0i) #f) (test (= 1.0 1234 1.234+1.234i) #f) (test (= 1.0 1234 1/1) #f) (test (= 1.0 1234 123.4) #f) (test (= 1.0 1234 1234) #f) (test (= 1.0 1234 1234/11) #f) (test (= 1.0 1234) #f) (test (= 1.0 1234/11 -1.0+1.0i) #f) (test (= 1.0 1234/11 0.0+1.0i) #f) (test (= 1.0 1234/11 1) #f) (test (= 1.0 1234/11 1.0) #f) (test (= 1.0 1234/11 1.0+1.0i) #f) (test (= 1.0 1234/11 1.234+1.234i) #f) (test (= 1.0 1234/11 1/1) #f) (test (= 1.0 1234/11 123.4) #f) (test (= 1.0 1234/11 1234) #f) (test (= 1.0 1234/11 1234/11) #f) (test (= 1.0 1234/11) #f) (test (= 1.0+1.0i -1.0+1.0i -1.0+1.0i) #f) (test (= 1.0+1.0i -1.0+1.0i 0.0+1.0i) #f) (test (= 1.0+1.0i -1.0+1.0i 1) #f) (test (= 1.0+1.0i -1.0+1.0i 1.0) #f) (test (= 1.0+1.0i -1.0+1.0i 1.0+1.0i) #f) (test (= 1.0+1.0i -1.0+1.0i 1.234+1.234i) #f) (test (= 1.0+1.0i -1.0+1.0i 1/1) #f) (test (= 1.0+1.0i -1.0+1.0i 123.4) #f) (test (= 1.0+1.0i -1.0+1.0i 1234) #f) (test (= 1.0+1.0i -1.0+1.0i 1234/11) #f) (test (= 1.0+1.0i -1.0+1.0i) #f) (test (= 1.0+1.0i 0.0+1.0i -1.0+1.0i) #f) (test (= 1.0+1.0i 0.0+1.0i 0.0+1.0i) #f) (test (= 1.0+1.0i 0.0+1.0i 1) #f) (test (= 1.0+1.0i 0.0+1.0i 1.0) #f) (test (= 1.0+1.0i 0.0+1.0i 1.0+1.0i) #f) (test (= 1.0+1.0i 0.0+1.0i 1.234+1.234i) #f) (test (= 1.0+1.0i 0.0+1.0i 1/1) #f) (test (= 1.0+1.0i 0.0+1.0i 123.4) #f) (test (= 1.0+1.0i 0.0+1.0i 1234) #f) (test (= 1.0+1.0i 0.0+1.0i 1234/11) #f) (test (= 1.0+1.0i 0.0+1.0i) #f) (test (= 1.0+1.0i 1 -1.0+1.0i) #f) (test (= 1.0+1.0i 1 0.0+1.0i) #f) (test (= 1.0+1.0i 1 1) #f) (test (= 1.0+1.0i 1 1.0) #f) (test (= 1.0+1.0i 1 1.0+1.0i) #f) (test (= 1.0+1.0i 1 1.234+1.234i) #f) (test (= 1.0+1.0i 1 1/1) #f) (test (= 1.0+1.0i 1 123.4) #f) (test (= 1.0+1.0i 1 1234) #f) (test (= 1.0+1.0i 1 1234/11) #f) (test (= 1.0+1.0i 1) #f) (test (= 1.0+1.0i 1.0 -1.0+1.0i) #f) (test (= 1.0+1.0i 1.0 0.0+1.0i) #f) (test (= 1.0+1.0i 1.0 1) #f) (test (= 1.0+1.0i 1.0 1.0) #f) (test (= 1.0+1.0i 1.0 1.0+1.0i) #f) (test (= 1.0+1.0i 1.0 1.234+1.234i) #f) (test (= 1.0+1.0i 1.0 1/1) #f) (test (= 1.0+1.0i 1.0 123.4) #f) (test (= 1.0+1.0i 1.0 1234) #f) (test (= 1.0+1.0i 1.0 1234/11) #f) (test (= 1.0+1.0i 1.0) #f) (test (= 1.0+1.0i 1.0+1.0i -1.0+1.0i) #f) (test (= 1.0+1.0i 1.0+1.0i 0.0+1.0i) #f) (test (= 1.0+1.0i 1.0+1.0i 1) #f) (test (= 1.0+1.0i 1.0+1.0i 1.0) #f) (test (= 1.0+1.0i 1.0+1.0i 1.0+1.0i) #t) (test (= 1.0+1.0i 1.0+1.0i 1.234+1.234i) #f) (test (= 1.0+1.0i 1.0+1.0i 1/1) #f) (test (= 1.0+1.0i 1.0+1.0i 123.4) #f) (test (= 1.0+1.0i 1.0+1.0i 1234) #f) (test (= 1.0+1.0i 1.0+1.0i 1234/11) #f) (test (= 1.0+1.0i 1.0+1.0i) #t) (test (= 1.0+1.0i 1.234+1.234i -1.0+1.0i) #f) (test (= 1.0+1.0i 1.234+1.234i 0.0+1.0i) #f) (test (= 1.0+1.0i 1.234+1.234i 1) #f) (test (= 1.0+1.0i 1.234+1.234i 1.0) #f) (test (= 1.0+1.0i 1.234+1.234i 1.0+1.0i) #f) (test (= 1.0+1.0i 1.234+1.234i 1.234+1.234i) #f) (test (= 1.0+1.0i 1.234+1.234i 1/1) #f) (test (= 1.0+1.0i 1.234+1.234i 123.4) #f) (test (= 1.0+1.0i 1.234+1.234i 1234) #f) (test (= 1.0+1.0i 1.234+1.234i 1234/11) #f) (test (= 1.0+1.0i 1.234+1.234i) #f) (test (= 1.0+1.0i 123.4 -1.0+1.0i) #f) (test (= 1.0+1.0i 123.4 0.0+1.0i) #f) (test (= 1.0+1.0i 123.4 1) #f) (test (= 1.0+1.0i 123.4 1.0) #f) (test (= 1.0+1.0i 123.4 1.0+1.0i) #f) (test (= 1.0+1.0i 123.4 1.234+1.234i) #f) (test (= 1.0+1.0i 123.4 1/1) #f) (test (= 1.0+1.0i 123.4 123.4) #f) (test (= 1.0+1.0i 123.4 1234) #f) (test (= 1.0+1.0i 123.4 1234/11) #f) (test (= 1.0+1.0i 123.4) #f) (test (= 1.0+1.0i 1234 -1.0+1.0i) #f) (test (= 1.0+1.0i 1234 0.0+1.0i) #f) (test (= 1.0+1.0i 1234 1) #f) (test (= 1.0+1.0i 1234 1.0) #f) (test (= 1.0+1.0i 1234 1.0+1.0i) #f) (test (= 1.0+1.0i 1234 1.234+1.234i) #f) (test (= 1.0+1.0i 1234 1/1) #f) (test (= 1.0+1.0i 1234 123.4) #f) (test (= 1.0+1.0i 1234 1234) #f) (test (= 1.0+1.0i 1234 1234/11) #f) (test (= 1.0+1.0i 1234) #f) (test (= 1.0+1.0i 1234/11 -1.0+1.0i) #f) (test (= 1.0+1.0i 1234/11 0.0+1.0i) #f) (test (= 1.0+1.0i 1234/11 1) #f) (test (= 1.0+1.0i 1234/11 1.0) #f) (test (= 1.0+1.0i 1234/11 1.0+1.0i) #f) (test (= 1.0+1.0i 1234/11 1.234+1.234i) #f) (test (= 1.0+1.0i 1234/11 1/1) #f) (test (= 1.0+1.0i 1234/11 123.4) #f) (test (= 1.0+1.0i 1234/11 1234) #f) (test (= 1.0+1.0i 1234/11 1234/11) #f) (test (= 1.0+1.0i 1234/11) #f) (test (= 1.234+1.234i -1.0+1.0i) #f) (test (= 1.234+1.234i 0.0+1.0i) #f) (test (= 1.234+1.234i 1) #f) (test (= 1.234+1.234i 1.0) #f) (test (= 1.234+1.234i 1.0+1.0i) #f) (test (= 1.234+1.234i 1.234+1.234i) #t) (test (= 1.234+1.234i 1/1) #f) (test (= 1.234+1.234i 123.4) #f) (test (= 1.234+1.234i 1234) #f) (test (= 1.234+1.234i 1234/11) #f) (test (= 123.4 -1.0+1.0i -1.0+1.0i) #f) (test (= 123.4 -1.0+1.0i 0.0+1.0i) #f) (test (= 123.4 -1.0+1.0i 1) #f) (test (= 123.4 -1.0+1.0i 1.0) #f) (test (= 123.4 -1.0+1.0i 1.0+1.0i) #f) (test (= 123.4 -1.0+1.0i 1.234+1.234i) #f) (test (= 123.4 -1.0+1.0i 1/1) #f) (test (= 123.4 -1.0+1.0i 123.4) #f) (test (= 123.4 -1.0+1.0i 1234) #f) (test (= 123.4 -1.0+1.0i 1234/11) #f) (test (= 123.4 -1.0+1.0i) #f) (test (= 123.4 0.0+1.0i -1.0+1.0i) #f) (test (= 123.4 0.0+1.0i 0.0+1.0i) #f) (test (= 123.4 0.0+1.0i 1) #f) (test (= 123.4 0.0+1.0i 1.0) #f) (test (= 123.4 0.0+1.0i 1.0+1.0i) #f) (test (= 123.4 0.0+1.0i 1.234+1.234i) #f) (test (= 123.4 0.0+1.0i 1/1) #f) (test (= 123.4 0.0+1.0i 123.4) #f) (test (= 123.4 0.0+1.0i 1234) #f) (test (= 123.4 0.0+1.0i 1234/11) #f) (test (= 123.4 0.0+1.0i) #f) (test (= 123.4 1 -1.0+1.0i) #f) (test (= 123.4 1 0.0+1.0i) #f) (test (= 123.4 1 1) #f) (test (= 123.4 1 1.0) #f) (test (= 123.4 1 1.0+1.0i) #f) (test (= 123.4 1 1.234+1.234i) #f) (test (= 123.4 1 1/1) #f) (test (= 123.4 1 123.4) #f) (test (= 123.4 1 1234) #f) (test (= 123.4 1 1234/11) #f) (test (= 123.4 1) #f) (test (= 123.4 1.0 -1.0+1.0i) #f) (test (= 123.4 1.0 0.0+1.0i) #f) (test (= 123.4 1.0 1) #f) (test (= 123.4 1.0 1.0) #f) (test (= 123.4 1.0 1.0+1.0i) #f) (test (= 123.4 1.0 1.234+1.234i) #f) (test (= 123.4 1.0 1/1) #f) (test (= 123.4 1.0 123.4) #f) (test (= 123.4 1.0 1234) #f) (test (= 123.4 1.0 1234/11) #f) (test (= 123.4 1.0) #f) (test (= 123.4 1.0+1.0i -1.0+1.0i) #f) (test (= 123.4 1.0+1.0i 0.0+1.0i) #f) (test (= 123.4 1.0+1.0i 1) #f) (test (= 123.4 1.0+1.0i 1.0) #f) (test (= 123.4 1.0+1.0i 1.0+1.0i) #f) (test (= 123.4 1.0+1.0i 1.234+1.234i) #f) (test (= 123.4 1.0+1.0i 1/1) #f) (test (= 123.4 1.0+1.0i 123.4) #f) (test (= 123.4 1.0+1.0i 1234) #f) (test (= 123.4 1.0+1.0i 1234/11) #f) (test (= 123.4 1.0+1.0i) #f) (test (= 123.4 1.234+1.234i -1.0+1.0i) #f) (test (= 123.4 1.234+1.234i 0.0+1.0i) #f) (test (= 123.4 1.234+1.234i 1) #f) (test (= 123.4 1.234+1.234i 1.0) #f) (test (= 123.4 1.234+1.234i 1.0+1.0i) #f) (test (= 123.4 1.234+1.234i 1.234+1.234i) #f) (test (= 123.4 1.234+1.234i 1/1) #f) (test (= 123.4 1.234+1.234i 123.4) #f) (test (= 123.4 1.234+1.234i 1234) #f) (test (= 123.4 1.234+1.234i 1234/11) #f) (test (= 123.4 1.234+1.234i) #f) (test (= 123.4 123.4 -1.0+1.0i) #f) (test (= 123.4 123.4 0.0+1.0i) #f) (test (= 123.4 123.4 1) #f) (test (= 123.4 123.4 1.0) #f) (test (= 123.4 123.4 1.0+1.0i) #f) (test (= 123.4 123.4 1.234+1.234i) #f) (test (= 123.4 123.4 1/1) #f) (test (= 123.4 123.4 123.4) #t) (test (= 123.4 123.4 1234) #f) (test (= 123.4 123.4 1234/11) #f) (test (= 123.4 123.4) #t) (test (= 123.4 1234 -1.0+1.0i) #f) (test (= 123.4 1234 0.0+1.0i) #f) (test (= 123.4 1234 1) #f) (test (= 123.4 1234 1.0) #f) (test (= 123.4 1234 1.0+1.0i) #f) (test (= 123.4 1234 1.234+1.234i) #f) (test (= 123.4 1234 1/1) #f) (test (= 123.4 1234 123.4) #f) (test (= 123.4 1234 1234) #f) (test (= 123.4 1234 1234/11) #f) (test (= 123.4 1234) #f) (test (= 123.4 1234/11 -1.0+1.0i) #f) (test (= 123.4 1234/11 0.0+1.0i) #f) (test (= 123.4 1234/11 1) #f) (test (= 123.4 1234/11 1.0) #f) (test (= 123.4 1234/11 1.0+1.0i) #f) (test (= 123.4 1234/11 1.234+1.234i) #f) (test (= 123.4 1234/11 1/1) #f) (test (= 123.4 1234/11 123.4) #f) (test (= 123.4 1234/11 1234) #f) (test (= 123.4 1234/11 1234/11) #f) (test (= 123.4 1234/11) #f) (test (= 1234 -1.0+1.0i) #f) (test (= 1234 0.0+1.0i) #f) (test (= 1234 1) #f) (test (= 1234 1.0) #f) (test (= 1234 1.0+1.0i) #f) (test (= 1234 1.234+1.234i) #f) (test (= 1234 1/1) #f) (test (= 1234 123.4) #f) (test (= 1234 1234) #t) (test (= 1234 1234/11) #f) (test (= 1234/11 -1.0+1.0i) #f) (test (= 1234/11 0.0+1.0i) #f) (test (= 1234/11 1) #f) (test (= 1234/11 1.0) #f) (test (= 1234/11 1.0+1.0i) #f) (test (= 1234/11 1.234+1.234i) #f) (test (= 1234/11 1/1) #f) (test (= 1234/11 123.4) #f) (test (= 1234/11 1234) #f) (test (= 1234/11 1234/11) #t) (test (= 2 -1) #f) (test (= 2 -2) #f) (test (= #i3/5 #i3/5) #t) (test (= -0 0) #t) (test (= -0-0i 0.0) #t) (test (= -0.0 0.0) #t) (test (= -0.0-0.0i 0.0) #t) (test (= .6 .6) #t) (test (= 0.11 0.11) #t) (test (= 0.18 0.18) #t) (test (= 0.3 0.3) #t) (test (= 0.333 0.333) #t) (test (= 0.60 0.60) #t) (test (= 0.999 0.999) #t) (test (= 1 2 #\a) 'error) (test (= 1+0i 1-0i) #t) (test (= 1+i 0+i) #f) (test (= 1+i 0-i) #f) (test (= 1/2 1/2+0i) #t) ; gmp reads 1/2+0i as 1.0 (test (= 100.000 100.000) #t) (test (= 1e10 1e10) #t) (test (= 22 22 22) #t ) (test (= 22 22) #t ) (test (= 34 34 35) #f ) (test (= 34 35) #f ) (test (= 60e-2 60e-2) #t) (test (= 0 0.0) #t) (test (= 0 1 "hi") 'error) (test (= 0) 'error) (test (=) 'error) (test (= 0.0 0.0) #t) (test (= 0.0 1.0 "hi") 'error) (test (= 0.0) 'error) (test (= 0.0+0.00000001i) 'error) (test (= 0/1) 'error) (test (= 1.0) 'error) (test (= 1.0+1.0i) 'error) (test (= 1 lambda) 'error) (test (= 10/3) 'error) (test (= 1234000000.0+2.71828182845905i) 'error) (test (= 2) 'error) (test (= 2.5 5/2) #t) (test (= 2.5+0.0i 5/2) #t) (test (= 2.5+1.0i 5/2) #f) (test (= 2.71828182845905+3.14159265358979i) 'error) (test (= pi '(1)) 'error) ; for gmp (test (= 3 2 3) #f) (test (= 3 3 3 3) #t) (test (= 3 3 5 3) #f) (test (= 3 3) #t) (test (= 3 3.0) #t) (test (= 3 5) #f) (test (= 3 6 5 2) #f) (test (= 3.0 3.0+0.0i) #t) (test (= 5/2 2.5) #t) (test (= 5/2 2.5) #t) (test (= 5/2 2.5+0.0i) #t) (test (= 5/2 2.5+1.0i) #f) (for-each (lambda (arg) (test (= arg nan.0) 'error) (test (= nan.0 arg) 'error) (test (= arg inf.0) 'error) (test (= inf.0 arg) 'error) (test (= 1 0 arg) 'error) (test (= 1 arg) 'error) (test (= 1.0 arg) 'error) (test (= 1/2 arg) 'error) (test (= 1+i arg) 'error) (test (= arg 1) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) (test (= +0 -0 0/100 00 -0/9223372036854775807) #t) (test (= +1/2 1/2) #t) (test (= 0 0) #t) (test (= 0.0 0.0+0.0i +0.0 -0.0 +.0 -.0 +0. -0. 0. .0 0.e1 0e1 0e+1 +0.0e+1+0.0e+1i 0-0i) #t) (test (= 1.0 1.0+0.0i +1.0 1. 1e0 1-0i) #t) (test (= 0.0+0.0i 0.0+0.0i) #t) (test (= 1+1i 1+1i) #t) (test (= 1.0+1.0i 1.0+1.0i) #t) (test (= 1.0+1i 1.0+1.0i) #t) (test (= 100000000000000.0 100000000000001.0) #f) (test (= -1.797693134862315699999999999999999999998E308 -9223372036854775808) #f) (test (= -9223372036854775808 -9223372036854775808) #t) (test (= -9223372036854775808 5.551115123125783999999999999999999999984E-17) #f) (test (= -9223372036854775808 9223372036854775807 -9223372036854775808) #f) (test (= 1.110223024625156799999999999999999999997E-16 -9223372036854775808) #f) (test (= 1.110223024625156799999999999999999999997E-16 5.551115123125783999999999999999999999984E-17 5.42101086242752217060000000000000000001E-20) #f) (test (= 5.551115123125783999999999999999999999984E-17 1.110223024625156799999999999999999999997E-16) #f) (test (= 9223372036854775807 -9223372036854775808) #f) (test (= 9223372036854775807 9223372036854775807) #t) (test (= (* most-negative-fixnum 1) (- (* -1 most-positive-fixnum) 1)) #t) (test (= (* most-positive-fixnum -1) (+ most-negative-fixnum 1)) #t) (test (= (+ most-negative-fixnum 1) (- most-positive-fixnum)) #t) (test (= (+ most-negative-fixnum most-positive-fixnum) -1) #t) (test (= (- most-negative-fixnum (- most-positive-fixnum)) -1) #t) (test (= 0 1/0 0/0) #f) (test (= 0/1 -0/1) #t) (test (= 1/0 (log 0)) #f) (test (= 1/0 -1/0) #f) (test (= 1e100 1e+100) #t) (test (= most-negative-fixnum (/ (log 0) (log 0))) #f) (test (= most-negative-fixnum 0/0) #f) (test (= most-negative-fixnum 0/0+0/0i) #f) (test (= most-negative-fixnum 1/0) #f) (test (= most-positive-fixnum (/ (log 0) (log 0))) #f) (test (= most-positive-fixnum 0/0) #f) (test (= most-positive-fixnum 0/0+0/0i) #f) (test (= most-positive-fixnum 1/0) #f) (test (= most-positive-fixnum most-negative-fixnum) #f) (test (= most-positive-fixnum most-positive-fixnum) #t) ;; these are a mess -- they depend on optimizer choices, etc (test (= 9223372036854775807/9223372036854775806 1.0 9223372036854775806/9223372036854775807) #f) (test (= 9223372036854775806/9223372036854775807 1.0 9223372036854775807/9223372036854775806) #f) (test (= 1 1.0 9223372036854775806/9223372036854775807) #f) (test (= 9223372036854775806/9223372036854775807 1.0 1) #f) (test (= 9223372036854775806/9223372036854775807 1.0) #f) (test (= 1.0 9223372036854775806/9223372036854775807) #f) (test (= 1 1.0 9223372036854775807/9223372036854775806) #f) (test (= 9223372036854775807/9223372036854775806 1.0 1) #f) (test (= 9223372036854775807/9223372036854775806 1.0) #f) (test (= 1.0 9223372036854775807/9223372036854775806) #f) ;(test (= 1.0 9223372036854775807/9223372036854775806) (= 9223372036854775807/9223372036854775806 1.0)) ;(test (= (* 397573379/630138897 1.0) 4201378396/6659027209) (= 4201378396/6659027209 (* 397573379/630138897 1.0))) (test (= (* 10400200/16483927 1.0) (* 10781274/17087915 1.0)) #f) (test (= (* 10400200/16483927 1.0) 10781274/17087915) #f) (test (= (* 10781274/17087915 1.0) (* 53715833/85137581 1.0)) #f) (test (= (* 10781274/17087915 1.0) 53715833/85137581) #f) (test (= (* 12/19 1.0) (* 53/84 1.0)) #f) (test (= (* 12/19 1.0) 53/84) #f) (test (= (* 12941/20511 1.0) (* 15601/24727 1.0)) #f) (test (= (* 12941/20511 1.0) 15601/24727) #f) (test (= (* 15601/24727 1.0) (* 79335/125743 1.0)) #f) (test (= (* 15601/24727 1.0) 79335/125743) #f) ;;; (if with-bignums (test (= (* 171928773/272500658 1.0) (* 397573379/630138897 1.0)) #f)) -- needs more bits ;;; (test (= (* 171928773/272500658 1.0) 397573379/630138897) #f) (test (= (* 190537/301994 1.0) (* 7161071/11350029 1.0)) #f) (test (= (* 190537/301994 1.0) 7161071/11350029) #f) (test (= (* 2/3 1.0) (* 5/8 1.0)) #f) (test (= (* 2/3 1.0) 5/8) #f) (test (= (* 253/401 1.0) (* 665/1054 1.0)) #f) (test (= (* 253/401 1.0) 665/1054) #f) (if with-bignums (test (= (* 397573379/630138897 1.0) (* 4201378396/6659027209 1.0)) #f)) (test (= (* 397573379/630138897 1.0) 4201378396/6659027209) #f) (if with-bignums (test (= (* 4201378396/6659027209 1.0) (* 6189245291/9809721694 1.0)) #f)) (test (= (* 4201378396/6659027209 1.0) 6189245291/9809721694) #f) (test (= (* 5/8 1.0) (* 12/19 1.0)) #f) (test (= (* 5/8 1.0) 12/19) #f) (test (= (* 53/84 1.0) (* 253/401 1.0)) #f) (test (= (* 53/84 1.0) 253/401) #f) ;;; (if with-bignums (test (= (* 53715833/85137581 1.0) (* 171928773/272500658 1.0)) #f)) -- more bits ;;; (if with-bignums (test (= (* 53715833/85137581 1.0) 171928773/272500658) #f)) (test (= (* 665/1054 1.0) (* 12941/20511 1.0)) #f) (test (= (* 665/1054 1.0) 12941/20511) #f) (test (= (* 7161071/11350029 1.0) (* 10400200/16483927 1.0)) #f) (test (= (* 7161071/11350029 1.0) 10400200/16483927) #f) (test (= (* 79335/125743 1.0) (* 190537/301994 1.0)) #f) (test (= (* 79335/125743 1.0) 190537/301994) #f) (test (= 10400200/16483927 10781274/17087915) #f) (test (= 10781274/17087915 53715833/85137581) #f) (test (= 12/19 53/84) #f) (test (= 12941/20511 15601/24727) #f) (test (= 15601/24727 79335/125743) #f) (test (= 171928773/272500658 397573379/630138897) #f) (test (= 190537/301994 7161071/11350029) #f) (test (= 2/3 5/8) #f) (test (= 253/401 665/1054) #f) (test (= 397573379/630138897 4201378396/6659027209) #f) (test (= 4201378396/6659027209 6189245291/9809721694) #f) (test (= 5/8 12/19) #f) (test (= 53/84 253/401) #f) (test (= 53715833/85137581 171928773/272500658) #f) (test (= 665/1054 12941/20511) #f) (test (= 7161071/11350029 10400200/16483927) #f) (test (= 79335/125743 190537/301994) #f) (test (= 10.000000000 10.000000000000001) #f) (if with-bignums (begin (test (= 10.000000000 10.0000000000000001) #f) (test (= 8388608.9999999995 8388609) #f) (test (= (* 1.0 16743730547042864/1996007985) 8388609) #f) (test (= (* 1.0 13981015002796202/1666666667) 8388609) #f) (test (= (string->number "#e.1e20") 1e19) #t) (test (= (bignum "3") 1/0) #f) (test (= 12345678901234567890 12345678901234567891) #f) (test (= most-positive-fixnum (- (/ most-negative-fixnum -1) 1)) #t) (test (= 1267650600228229401496703205376) 'error) )) ;;; non-gmp strangeness: ;;; (zero? (- (sqrt 2) 5964153172084899/4217293152016490)) -> #t, but ;;; (= (sqrt 2) 5964153172084899/4217293152016490) -> #f (test (= 0 '(1 . 2) . 3) 'error) (test (append 0 '(1 . 2) . 3) 'error) (test (= 0 ''0 . 0) 'error) (test (= . 0) 'error) (test (= 0 . (0)) #t) ;;; -------------------------------------------------------------------------------- ;;; > ;;; -------------------------------------------------------------------------------- (test (> 0 1 1) #f) (test (> 0 1 1.0) #f) (test (> 0 1 1/1) #f) (test (> 0 1 123.4) #f) (test (> 0 1 1234) #f) (test (> 0 1 1234/11) #f) (test (> 0 1) #f) (test (> 0 1.0 1) #f) (test (> 0 1.0 1.0) #f) (test (> 0 1.0 1/1) #f) (test (> 0 1.0 123.4) #f) (test (> 0 1.0 1234) #f) (test (> 0 1.0 1234/11) #f) (test (> 0 1.0) #f) (test (> 0 123.4) #f) (test (> 0 1234) #f) (test (> 0 1234/11) #f) (test (> 0.0 1 1.0) #f) (test (> 0.0 1 1/1) #f) (test (> 0.0 1 123.4) #f) (test (> 0.0 1 1234) #f) (test (> 0.0 1 1234/11) #f) (test (> 0.0 1) #f) (test (> 0.0 1.0 1) #f) (test (> 0.0 1.0 1.0) #f) (test (> 0.0 1.0 1/1) #f) (test (> 0.0 1.0 123.4) #f) (test (> 0.0 1.0 1234) #f) (test (> 0.0 1.0 1234/11) #f) (test (> 0.0 1.0) #f) (test (> 0.0 123.4 1) #f) (test (> 0.0 123.4 1.0) #f) (test (> 0.0 123.4 1/1) #f) (test (> 0.0 123.4 123.4) #f) (test (> 0.0 123.4 1234) #f) (test (> 0.0 123.4 1234/11) #f) (test (> 0.0 123.4) #f) (test (> 0.0 1234 1) #f) (test (> 0.0 1234 1.0) #f) (test (> 0.0 1234 1/1) #f) (test (> 0.0 1234 123.4) #f) (test (> 0.0 1234 1234) #f) (test (> 0.0 1234 1234/11) #f) (test (> 0.0 1234) #f) (test (> 0.0 1234/11 1) #f) (test (> 0.0 1234/11 1.0) #f) (test (> 0.0 1234/11 1/1) #f) (test (> 0.0 1234/11 123.4) #f) (test (> 0.0 1234/11 1234) #f) (test (> 0.0 1234/11 1234/11) #f) (test (> 0.0 1234/11) #f) (test (> 1 1 1) #f) (test (> 1 1 1.0) #f) (test (> 1 1 1/1) #f) (test (> 1 1 123.4) #f) (test (> 1 1 1234) #f) (test (> 1 1 1234/11) #f) (test (> 1 1) #f) (test (> 1 1.0 1) #f) (test (> 1 1.0 1.0) #f) (test (> 1 1.0 1/1) #f) (test (> 1 1.0 123.4) #f) (test (> 1 1.0 1234) #f) (test (> 1 1.0 1234/11) #f) (test (> 1 1.0) #f) (test (> 1 123.4) #f) (test (> 1 1234) #f) (test (> 1 1234/11) #f) (test (> 1.0 1 1) #f) (test (> 1.0 1 1.0) #f) (test (> 1.0 1 1/1) #f) (test (> 1.0 1 123.4) #f) (test (> 1.0 1 1234) #f) (test (> 1.0 1 1234/11) #f) (test (> 1.0 1) #f) (test (> 1.0 1.0 1) #f) (test (> 1.0 1.0 1.0) #f) (test (> 1.0 1.0 1/1) #f) (test (> 1.0 1.0 123.4) #f) (test (> 1.0 1.0 1234) #f) (test (> 1.0 1.0 1234/11) #f) (test (> 1.0 1.0) #f) (test (> 1.0 123.4 1) #f) (test (> 1.0 123.4 1.0) #f) (test (> 1.0 123.4 1/1) #f) (test (> 1.0 123.4 123.4) #f) (test (> 1.0 123.4 1234) #f) (test (> 1.0 123.4 1234/11) #f) (test (> 1.0 123.4) #f) (test (> 1.0 1234 1) #f) (test (> 1.0 1234 1.0) #f) (test (> 1.0 1234 1/1) #f) (test (> 1.0 1234 123.4) #f) (test (> 1.0 1234 1234) #f) (test (> 1.0 1234 1234/11) #f) (test (> 1.0 1234) #f) (test (> 1.0 1234/11 1) #f) (test (> 1.0 1234/11 1.0) #f) (test (> 1.0 1234/11 1/1) #f) (test (> 1.0 1234/11 123.4) #f) (test (> 1.0 1234/11 1234) #f) (test (> 1.0 1234/11 1234/11) #f) (test (> 1.0 1234/11) #f) (test (> 123.4 1 1) #f) (test (> 123.4 1 1.0) #f) (test (> 123.4 1 1/1) #f) (test (> 123.4 1 123.4) #f) (test (> 123.4 1 1234) #f) (test (> 123.4 1 1234/11) #f) (test (> 123.4 1) #t) (test (> 123.4 1.0 1) #f) (test (> 123.4 1.0 1.0) #f) (test (> 123.4 1.0 1/1) #f) (test (> 123.4 1.0 123.4) #f) (test (> 123.4 1.0 1234) #f) (test (> 123.4 1.0 1234/11) #f) (test (> 123.4 1.0) #t) (test (> 123.4 123.4 1) #f) (test (> 123.4 123.4 1.0) #f) (test (> 123.4 123.4 1/1) #f) (test (> 123.4 123.4 123.4) #f) (test (> 123.4 123.4 1234) #f) (test (> 123.4 123.4 1234/11) #f) (test (> 123.4 123.4) #f) (test (> 123.4 1234 1) #f) (test (> 123.4 1234 1.0) #f) (test (> 123.4 1234 1/1) #f) (test (> 123.4 1234 123.4) #f) (test (> 123.4 1234 1234) #f) (test (> 123.4 1234 1234/11) #f) (test (> 123.4 1234) #f) (test (> 123.4 1234/11 1) #t) (test (> 123.4 1234/11 1.0) #t) (test (> 123.4 1234/11 1/1) #t) (test (> 123.4 1234/11 123.4) #f) (test (> 123.4 1234/11 1234) #f) (test (> 123.4 1234/11 1234/11) #f) (test (> 123.4 1234/11) #t) (test (> 1234 1) #t) (test (> 1234 1.0) #t) (test (> 1234 1/1) #t) (test (> 1234 123.4) #t) (test (> 1234 1234) #f) (test (> 1234 1234/11) #t) (test (> 1234/11 1) #t) (test (> 1234/11 1.0) #t) (test (> 1234/11 1/1) #t) (test (> 1234/11 123.4) #f) (test (> 1234/11 1234) #f) (test (> 1234/11 1234/11) #f) (test (> 1 0+i) 'error) (test (> 1 0-i) 'error) (test (> 1 2 #\a) 'error) (test (> 1+i 0+i) 'error) (test (> 1+i 0-i) 'error) (test (> nan.0 1+i) 'error) (test (> nan.0 1 1+i) 'error) (test (> 1 nan.0 1+i) 'error) (test (> inf.0 1+i) 'error) (test (> inf.0 nan.0 0-i 1) 'error) (test (> 2 1+0/2i) #t) (test (> 2 1+0i) #t) (test (> 2 1-0i) #t) (test (> 2 2 1) #f) (test (> 3 -6246) #t ) (test (> 9 9 -2424) #f ) (test (> quote if) 'error) (test (> 0) 'error) (test (> 0.0 0.0) #f) (test (> 0.0) 'error) (test (>) 'error) (test (> 0.0+0.00000001i) 'error) (test (> 0/1) 'error) (test (> 1 2 #\a) 'error) (test (> 1 2 1.0+1.0i) 'error) (test (> 1.0) 'error) (test (> 1.0+1.0i) 'error) (test (> 10/3) 'error) (test (> 1234000000.0+2.71828182845905i) 'error) (test (> 2) 'error) (test (> 2.71828182845905+3.14159265358979i) 'error) (test (> 3 3.0 3 3.0+1.0i) 'error) (test (> 4 3 1 2 0) #f) (test (> 4 3 2 1 0) #t) (test (> 4 3 3 2 0) #f) (test (> 4 3) #t) (test (> 8 7 6 5 4) #t) (test (> -10/3147483647 -40/12345678901) #t) (test (> -101/3147483647 40/12345678901) #f) (test (> -11/3147483647 -40/12345678901) #f) (test (> 1/9223372036854775807 1/9223372036854775806) #f) (test (> 10/3147483647 40/12345678901) #f) (test (> 1047483646/11111111111111 1234567890213/12345678901123123) #f) (test (> 11/3147483647 40/12345678901) #t) (test (> 1282469252763/12824692526603504 1234567890213/12345678901123123) #f) (test (> 1282469252765/12824692526603504 1234567890213/12345678901123123) #t) (test (> 2/3 3147483547123/4) #f) (test (> 2/3147483547 3147483547/3) #f) (test (> 2147483646/11111111111111 1234567890213/12345678901123123) #t) (test (> 3/147483647 40/3) #f) (test (> 3/3147483647 -40/12345678901) #t) (test (> 3/3147483647 40/12345678901) #f) (test (> 3/3147483647 40/3) #f) (test (> 3147483547/2 3/3147483547) #t) (test (> 3147483547/2 3147483547/3) #t) (test (> 3147483646/11 12345678901/40) #f) (test (> 3147483646/11 1234567890213/12345678901123123) #t) (test (> 3147483646/11 40/12345678901) #t) (test (> 3147483646/11111111111111 1234567890213/12345678901123123) #t) (test (> 3147483646/111111111111111 1234567890213/12345678901123123) #f) (test (> -1.797693134862315699999999999999999999998E308 -9223372036854775808) #f) (test (> -9223372036854775808 -9223372036854775808) #f) (test (> -9223372036854775808 5.551115123125783999999999999999999999984E-17) #f) (test (> -9223372036854775808 9223372036854775807 -9223372036854775808) #f) (test (> 1.110223024625156799999999999999999999997E-16 -9223372036854775808) #t) (test (> 1.110223024625156799999999999999999999997E-16 5.551115123125783999999999999999999999984E-17 5.42101086242752217060000000000000000001E-20) #t) (test (> 5.551115123125783999999999999999999999984E-17 1.110223024625156799999999999999999999997E-16) #f) (test (> 9223372036854775807 -9223372036854775808) #t) (test (> 9223372036854775807 9223372036854775807) #f) (test (> 0 most-negative-fixnum) #t) (test (> 0 most-positive-fixnum) #f) (test (> 1e18 most-positive-fixnum) #f) (test (> 9007199254740992.0 9007199254740991.0) #t) (test (> most-negative-fixnum (real-part (log 0.0))) #t) (test (> most-negative-fixnum 0) #f) (test (> most-negative-fixnum most-positive-fixnum) #f) (test (> most-positive-fixnum (- (real-part (log 0.0)))) #f) (test (> most-positive-fixnum 0) #t) (test (> most-positive-fixnum most-negative-fixnum) #t) (test (> most-positive-fixnum most-negative-fixnum) #t) (num-test (> 1/123400000000 .000000000001) #t) ; these can go either way I guess -- 1/0 might be NaN? ;(test (< most-positive-fixnum 1/0) #t) ;(test (> most-positive-fixnum 1/0) #f) (test (> 10.000000000 9.99999999999999) #t) (test (> -1/9223372036854775807 -9223372036854775807) #t) (test (> 1 -1/9223372036854775807 -9223372036854775807) #t) (test (> 1 1/9223372036 9223372036 1.0) #f) (test (> 1 1/9223372036 9223372036) #f) (test (> 1 1/922337203685 922337203685 1.0) #f) (test (> 1 1/922337203685 922337203685) #f) (test (> 1.0 1/9223372036 9223372036 1) #f) (test (> 1.0 1/9223372036 9223372036) #f) (test (> 1.0 1/922337203685 922337203685 1) #f) (test (> 1.0 1/922337203685 922337203685) #f) (test (> 1/9223372036 9223372036 1) #f) (test (> 1/9223372036 9223372036 1.0) #f) (test (> 1/9223372036 9223372036) #f) (test (> 1/922337203685 922337203685 1) #f) (test (> 1/922337203685 922337203685 1.0) #f) (test (> 1/922337203685 922337203685) #f) (test (> 9223372036 1/9223372036) #t) (test (> 922337203685 1/922337203685) #t) (test (> 9223372036854775807 1/9223372036854775807 -1) #t) (test (> 9223372036854775807 1/9223372036854775807) #t) (test (> 1.0 9223372036854775806/9223372036854775807) #t) (test (> 9223372036854775807/9223372036854775806 1.0 9223372036854775806/9223372036854775807) #t) (test (> 9223372036854775807/9223372036854775806 1.0) #t) (test (> (* 10400200/16483927 1.0) (* 10781274/17087915 1.0)) #t) (test (> (* 10400200/16483927 1.0) 10781274/17087915) #t) (test (> (* 10781274/17087915 1.0) (* 53715833/85137581 1.0)) #f) (test (> (* 10781274/17087915 1.0) 53715833/85137581) #f) (test (> (* 12/19 1.0) (* 53/84 1.0)) #t) (test (> (* 12/19 1.0) 53/84) #t) (test (> (* 12941/20511 1.0) (* 15601/24727 1.0)) #f) (test (> (* 12941/20511 1.0) 15601/24727) #f) (test (> (* 15601/24727 1.0) (* 79335/125743 1.0)) #f) (test (> (* 15601/24727 1.0) 79335/125743) #f) (test (> (* 171928773/272500658 1.0) (* 397573379/630138897 1.0)) #f) (test (> (* 171928773/272500658 1.0) 397573379/630138897) #f) (test (> (* 190537/301994 1.0) (* 7161071/11350029 1.0)) #f) (test (> (* 190537/301994 1.0) 7161071/11350029) #f) (test (> (* 2/3 1.0) (* 5/8 1.0)) #t) (test (> (* 2/3 1.0) 5/8) #t) (test (> (* 253/401 1.0) (* 665/1054 1.0)) #f) (test (> (* 253/401 1.0) 665/1054) #f) (test (> (* 397573379/630138897 1.0) (* 4201378396/6659027209 1.0)) #f) (test (> (* 397573379/630138897 1.0) 4201378396/6659027209) #f) (test (> (* 5/8 1.0) (* 12/19 1.0)) #f) (test (> (* 5/8 1.0) 12/19) #f) (test (> (* 53/84 1.0) (* 253/401 1.0)) #t) (test (> (* 53/84 1.0) 253/401) #t) (test (> (abs (- .1 .2)) .3) #f) (test (> (abs (- .1 .2)) .03) #t) ;;; (if with-bignums (test (> (* 53715833/85137581 1.0) (* 171928773/272500658 1.0)) #t)) -- more bits ;;; (if with-bignums (test (> (* 53715833/85137581 1.0) 171928773/272500658) #t)) (test (> 53715833/85137581 171928773/272500658) #t) (test (> (* 665/1054 1.0) (* 12941/20511 1.0)) #t) (test (> (* 665/1054 1.0) 12941/20511) #t) (test (> (* 7161071/11350029 1.0) (* 10400200/16483927 1.0)) #t) (test (> (* 7161071/11350029 1.0) 10400200/16483927) #t) (test (> (* 79335/125743 1.0) (* 190537/301994 1.0)) #f) (test (> (* 79335/125743 1.0) 190537/301994) #f) (test (> 10400200/16483927 10781274/17087915) #t) (test (> 10781274/17087915 53715833/85137581) #f) (test (> 12/19 53/84) #t) (test (> 12941/20511 15601/24727) #f) (test (> 15601/24727 79335/125743) #f) (test (> 171928773/272500658 397573379/630138897) #f) (test (> 190537/301994 7161071/11350029) #f) (test (> 2/3 5/8) #t) (test (> 253/401 665/1054) #f) (test (> 397573379/630138897 4201378396/6659027209) #f) (test (> 4201378396/6659027209 6189245291/9809721694) #t) (test (> 5/8 12/19) #f) (test (> 53/84 253/401) #t) (test (> 53715833/85137581 171928773/272500658) #t) (test (> 665/1054 12941/20511) #t) (test (> 7161071/11350029 10400200/16483927) #t) (test (> 79335/125743 190537/301994) #f) (if with-bignums (begin (test (> (* 4201378396/6659027209 1.0) (* 6189245291/9809721694 1.0)) #t) (test (> (* 4201378396/6659027209 1.0) 6189245291/9809721694) #t) (test (> 10.000000000 9.999999999999999) #t) (test (> 12345678901234567890 12345678901234567891) #f) (test (> 9007199254740993.0 9007199254740992.0) #t) (test (> 1267650600228229401496703205376) 'error) (test (> 355/113 3587785776203/1142027682075 21053343141/6701487259) #t) (test (> 3587785776203/1142027682075 21053343141/6701487259 4272943/1360120) #t) (test (> 22/7 2646693125139304345/842468587426513207 21053343141/6701487259) #t) (test (> 2646693125139304345/842468587426513207 21053343141/6701487259 4272943/1360120) #t) (test (> 2646693125139304345/842468587426513207 3587785776203/1142027682075 21053343141/6701487259 4272943/1360120) #t) (test (> 3587785776203/1142027682075 21053343141/6701487259 4272943/1360120) #t) (test (> 2646693125139304345/842468587426513207 21053343141/6701487259 4272943/1360120) #t) (test (> 2646693125139304345/842468587426513207 3587785776203/1142027682075 21053343141/6701487259) #t) (test (> 3587785776203/1142027682075 21053343141/6701487259) #t) (test (> 2646693125139304345/842468587426513207 21053343141/6701487259) #t) )) (for-each (lambda (arg) (test (> arg nan.0) 'error) (test (> nan.0 arg) 'error) (test (> arg inf.0) 'error) (test (> inf.0 arg) 'error) (test (> 0 1 arg) 'error) (test (> 1 arg) 'error) (test (> 1/2 arg) 'error) (test (> 1.0 arg) 'error) (test (> 1+i arg) 'error) (test (> arg 1) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) ;;; -------------------------------------------------------------------------------- ;;; >= ;;; -------------------------------------------------------------------------------- (test (>= 0 1 1) #f) (test (>= 0 1 1.0) #f) (test (>= 0 1 1/1) #f) (test (>= 0 1 123.4) #f) (test (>= 0 1 1234) #f) (test (>= 0 1 1234/11) #f) (test (>= 0 1) #f) (test (>= 0 1.0 1) #f) (test (>= 0 1.0 1.0) #f) (test (>= 0 1.0 1/1) #f) (test (>= 0 1.0 123.4) #f) (test (>= 0 1.0 1234) #f) (test (>= 0 1.0 1234/11) #f) (test (>= 0 1.0) #f) (test (>= 0 123.4) #f) (test (>= 0 1234) #f) (test (>= 0 1234/11) #f) (test (>= 0.0 1 1) #f) (test (>= 0.0 1 1.0) #f) (test (>= 0.0 1 1/1) #f) (test (>= 0.0 1 123.4) #f) (test (>= 0.0 1 1234) #f) (test (>= 0.0 1 1234/11) #f) (test (>= 0.0 1) #f) (test (>= 0.0 1.0 1) #f) (test (>= 0.0 1.0 1.0) #f) (test (>= 0.0 1.0 1/1) #f) (test (>= 0.0 1.0 123.4) #f) (test (>= 0.0 1.0 1234) #f) (test (>= 0.0 1.0 1234/11) #f) (test (>= 0.0 1.0) #f) (test (>= 0.0 123.4 1) #f) (test (>= 0.0 123.4 1.0) #f) (test (>= 0.0 123.4 1/1) #f) (test (>= 0.0 123.4 123.4) #f) (test (>= 0.0 123.4 1234) #f) (test (>= 0.0 123.4 1234/11) #f) (test (>= 0.0 123.4) #f) (test (>= 0.0 1234 1) #f) (test (>= 0.0 1234 1.0) #f) (test (>= 0.0 1234 1/1) #f) (test (>= 0.0 1234 123.4) #f) (test (>= 0.0 1234 1234) #f) (test (>= 0.0 1234 1234/11) #f) (test (>= 0.0 1234) #f) (test (>= 0.0 1234/11 1) #f) (test (>= 0.0 1234/11 1.0) #f) (test (>= 0.0 1234/11 1/1) #f) (test (>= 0.0 1234/11 123.4) #f) (test (>= 0.0 1234/11 1234) #f) (test (>= 0.0 1234/11 1234/11) #f) (test (>= 0.0 1234/11) #f) (test (>= 1 1 1) #t) (test (>= 1 1 1.0) #t) (test (>= 1 1 1/1) #t) (test (>= 1 1 123.4) #f) (test (>= 1 1 1234) #f) (test (>= 1 1 1234/11) #f) (test (>= 1 1) #t) (test (>= 1 1.0 1) #t) (test (>= 1 1.0 1.0) #t) (test (>= 1 1.0 1/1) #t) (test (>= 1 1.0 123.4) #f) (test (>= 1 1.0 1234) #f) (test (>= 1 1.0 1234/11) #f) (test (>= 1 1.0) #t) (test (>= 1 123.4) #f) (test (>= 1 1234) #f) (test (>= 1 1234/11) #f) (test (>= 1.0 1 1) #t) (test (>= 1.0 1 1.0) #t) (test (>= 1.0 1 1/1) #t) (test (>= 1.0 1 123.4) #f) (test (>= 1.0 1 1234) #f) (test (>= 1.0 1 1234/11) #f) (test (>= 1.0 1) #t) (test (>= 1.0 1.0 1) #t) (test (>= 1.0 1.0 1.0) #t) (test (>= 1.0 1.0 1/1) #t) (test (>= 1.0 1.0 123.4) #f) (test (>= 1.0 1.0 1234) #f) (test (>= 1.0 1.0 1234/11) #f) (test (>= 1.0 1.0) #t) (test (>= 1.0 1/1 1) #t) (test (>= 1.0 123.4 1) #f) (test (>= 1.0 123.4 1.0) #f) (test (>= 1.0 123.4 1/1) #f) (test (>= 1.0 123.4 123.4) #f) (test (>= 1.0 123.4 1234) #f) (test (>= 1.0 123.4 1234/11) #f) (test (>= 1.0 123.4) #f) (test (>= 1.0 1234 1) #f) (test (>= 1.0 1234 1.0) #f) (test (>= 1.0 1234 1/1) #f) (test (>= 1.0 1234 123.4) #f) (test (>= 1.0 1234 1234) #f) (test (>= 1.0 1234 1234/11) #f) (test (>= 1.0 1234) #f) (test (>= 1.0 1234/11 1) #f) (test (>= 1.0 1234/11 1.0) #f) (test (>= 1.0 1234/11 1/1) #f) (test (>= 1.0 1234/11 123.4) #f) (test (>= 1.0 1234/11 1234) #f) (test (>= 1.0 1234/11 1234/11) #f) (test (>= 1.0 1234/11) #f) (test (>= 123.4 1 1) #t) (test (>= 123.4 1 1.0) #t) (test (>= 123.4 1 1/1) #t) (test (>= 123.4 1 123.4) #f) (test (>= 123.4 1 1234) #f) (test (>= 123.4 1 1234/11) #f) (test (>= 123.4 1) #t) (test (>= 123.4 1.0 1) #t) (test (>= 123.4 1.0 1.0) #t) (test (>= 123.4 1.0 1/1) #t) (test (>= 123.4 1.0 123.4) #f) (test (>= 123.4 1.0 1234) #f) (test (>= 123.4 1.0 1234/11) #f) (test (>= 123.4 1.0) #t) (test (>= 123.4 123.4 1) #t) (test (>= 123.4 123.4 1.0) #t) (test (>= 123.4 123.4 1/1) #t) (test (>= 123.4 123.4 123.4) #t) (test (>= 123.4 123.4 1234) #f) (test (>= 123.4 123.4 1234/11) #t) (test (>= 123.4 123.4) #t) (test (>= 123.4 1234 1) #f) (test (>= 123.4 1234 1.0) #f) (test (>= 123.4 1234 1/1) #f) (test (>= 123.4 1234 123.4) #f) (test (>= 123.4 1234 1234) #f) (test (>= 123.4 1234 1234/11) #f) (test (>= 123.4 1234) #f) (test (>= 123.4 1234/11 1) #t) (test (>= 123.4 1234/11 1.0) #t) (test (>= 123.4 1234/11 1/1) #t) (test (>= 123.4 1234/11 123.4) #f) (test (>= 123.4 1234/11 1234) #f) (test (>= 123.4 1234/11 1234/11) #t) (test (>= 123.4 1234/11) #t) (test (>= 1234 1) #t) (test (>= 1234 1.0) #t) (test (>= 1234 1/1) #t) (test (>= 1234 123.4) #t) (test (>= 1234 1234) #t) (test (>= 1234 1234/11) #t) (test (>= 1234/11 1) #t) (test (>= 1234/11 1.0) #t) (test (>= 1234/11 1/1) #t) (test (>= 1234/11 123.4) #f) (test (>= 1234/11 1234) #f) (test (>= 1234/11 1234/11) #t) (test (>= 0+i 0+i) 'error) ;?? (test (>= 1 0+i) 'error) (test (>= 1 0-i) 'error) (test (>= 1 1 2) #f) (test (>= 1 2 #\a) 'error) (test (>= 1 3 2) #f ) (test (>= 1+i 0+i) 'error) (test (>= 1+i 0-i) 'error) (test (>= nan.0 1+i) 'error) (test (>= nan.0 1 1+i) 'error) (test (>= 1 nan.0 1+i) 'error) (test (>= inf.0 1+i) 'error) (test (>= inf.0 nan.0 0-i 1) 'error) (test (>= 2 1+0/2i) #t) (test (>= 2 1+0i) #t) (test (>= 2 1-0i) #t) (test (>= 3 -4 -6246) #t ) (test (>= 8 9) #f ) (test (>= 9 9) #t ) (test (>= -5 -4 -2 0 4 5) #f) (test (>= 0) 'error) (test (>=) 'error) (test (>= 0.0) 'error) (test (>= 0.0+0.00000001i) 'error) (test (>= 0/1) 'error) (test (>= 1 2 #\a) 'error) (test (>= 1 2 1.0+1.0i) 'error) (test (>= 1.0) 'error) (test (>= 1.0+1.0i) 'error) (test (>= 10/3) 'error) (test (>= 1234000000.0+2.71828182845905i) 'error) (test (>= 2) 'error) (test (>= 2.71828182845905+3.14159265358979i) 'error) (test (>= 4 3 1 2 0) #f) (test (>= 4 3 2 1 0) #t) (test (>= 4 3 3 2 0) #t) (test (>= 4 3) #t) (test (>= -1.797693134862315699999999999999999999998E308 -9223372036854775808) #f) (test (>= -9223372036854775808 -9223372036854775808) #t) (test (>= -9223372036854775808 5.551115123125783999999999999999999999984E-17) #f) (test (>= -9223372036854775808 9223372036854775807 -9223372036854775808) #f) (test (>= 1.110223024625156799999999999999999999997E-16 -9223372036854775808) #t) (test (>= 1.110223024625156799999999999999999999997E-16 5.551115123125783999999999999999999999984E-17 5.42101086242752217060000000000000000001E-20) #t) (test (>= 5.551115123125783999999999999999999999984E-17 1.110223024625156799999999999999999999997E-16) #f) (test (>= 9223372036854775807 -9223372036854775808) #t) (test (>= 9223372036854775807 9223372036854775807) #t) (test (>= -1 -9223372036854775807 -1/9223372036854775807) #f) (test (>= -9223372036854775807 -1/9223372036854775807 -1) #f) (test (>= -9223372036854775807 -1/9223372036854775807) #f) (test (>= 1 -1 -9223372036854775807 -1/9223372036854775807) #f) (test (>= 1 -9223372036854775807 -1/9223372036854775807 -1) #f) (test (>= 1 -9223372036854775807 -1/9223372036854775807) #f) (test (>= 1 1.0 1/9223372036 9223372036) #f) (test (>= 1 1.0 1/922337203685 922337203685) #f) (test (>= 1 1/9223372036 9223372036 1.0) #f) (test (>= 1 1/9223372036 9223372036) #f) (test (>= 1 1/922337203685 922337203685 1.0) #f) (test (>= 1 1/922337203685 922337203685) #f) (test (>= 1 1/9223372036854775807 9223372036854775807 -1) #f) (test (>= 1 1/9223372036854775807 9223372036854775807) #f) (test (>= 1.0 1 1/9223372036 9223372036) #f) (test (>= 1.0 1 1/922337203685 922337203685) #f) (test (>= 1.0 1/9223372036 9223372036 1) #f) (test (>= 1.0 1/9223372036 9223372036) #f) (test (>= 1.0 1/922337203685 922337203685 1) #f) (test (>= 1.0 1/922337203685 922337203685) #f) (test (>= 1/9223372036 9223372036 1 1.0) #f) (test (>= 1/9223372036 9223372036 1) #f) (test (>= 1/9223372036 9223372036 1.0 1) #f) (test (>= 1/9223372036 9223372036 1.0) #f) (test (>= 1/9223372036 9223372036) #f) (test (>= 1/922337203685 922337203685 1 1.0) #f) (test (>= 1/922337203685 922337203685 1) #f) (test (>= 1/922337203685 922337203685 1.0 1) #f) (test (>= 1/922337203685 922337203685 1.0) #f) (test (>= 1/922337203685 922337203685) #f) (test (>= 1/9223372036854775807 9223372036854775807 -1) #f) (test (>= 1/9223372036854775807 9223372036854775807 1 -1) #f) (test (>= 1/9223372036854775807 9223372036854775807 1) #f) (test (>= 1/9223372036854775807 9223372036854775807) #f) (test (>= 9223372036 1/9223372036) #t) (test (>= 922337203685 1/922337203685) #t) (test (>= 1 1.0 9223372036854775807/9223372036854775806 9223372036854775806/9223372036854775807) #f) (test (>= 1 1.0 9223372036854775807/9223372036854775806) #f) (test (>= 1 9223372036854775806/9223372036854775807 1.0 9223372036854775807/9223372036854775806) #f) (test (>= 1 9223372036854775806/9223372036854775807 1.0) #f) (test (>= 1.0 9223372036854775807/9223372036854775806 1 9223372036854775806/9223372036854775807) #f) (test (>= 1.0 9223372036854775807/9223372036854775806 1) #f) (test (>= 1.0 9223372036854775807/9223372036854775806 9223372036854775806/9223372036854775807) #f) (test (>= 1.0 9223372036854775807/9223372036854775806) #f) (test (>= 9223372036854775806/9223372036854775807 1.0 1) #f) (test (>= 9223372036854775806/9223372036854775807 1.0 9223372036854775807/9223372036854775806 1) #f) (test (>= 9223372036854775806/9223372036854775807 1.0 9223372036854775807/9223372036854775806) #f) (test (>= 9223372036854775806/9223372036854775807 1.0) #f) (test (>= 9223372036854775807/9223372036854775806 1 9223372036854775806/9223372036854775807 1.0) #f) (test (>= 9223372036854775807/9223372036854775806 9223372036854775806/9223372036854775807 1.0 1) #f) (test (>= 9223372036854775807/9223372036854775806 9223372036854775806/9223372036854775807 1.0) #f) (if with-bignums (begin (test (>= 12345678901234567890 12345678901234567891) #f) (test (>= 1267650600228229401496703205376) 'error) (test (>= 21053343141/6701487259 2646693125139304345/842468587426513207 3587785776203/1142027682075 4272943/1360120) #f) (test (>= 21053343141/6701487259 3587785776203/1142027682075 4272943/1360120) #f) (test (>= 3587785776203/1142027682075 2646693125139304345/842468587426513207 4272943/1360120) #f) (test (>= 21053343141/6701487259 2646693125139304345/842468587426513207 3587785776203/1142027682075) #f) (test (>= 21053343141/6701487259 3587785776203/1142027682075 2646693125139304345/842468587426513207) #f) (test (>= 21053343141/6701487259 3587785776203/1142027682075) #f) (test (>= 21053343141/6701487259 2646693125139304345/842468587426513207) #f) (test (>= 3587785776203/1142027682075 2646693125139304345/842468587426513207) #f) (test (>= 22/7 21053343141/6701487259 2646693125139304345/842468587426513207 4272943/1360120) #f) (test (>= 21053343141/6701487259 2646693125139304345/842468587426513207 4272943/1360120) #f) (test (>= 21053343141/6701487259 2646693125139304345/842468587426513207) #f) (test (>= 355/113 21053343141/6701487259 3587785776203/1142027682075) #f) (test (>= 21053343141/6701487259 3587785776203/1142027682075 4272943/1360120) #f) )) (test (>= - 1 2) 'error) (test (>=- 1 2) 'error) (for-each (lambda (arg) (test (>= arg nan.0) 'error) (test (>= nan.0 arg) 'error) (test (>= arg inf.0) 'error) (test (>= inf.0 arg) 'error) (test (>= 0 1 arg) 'error) (test (>= 1 arg) 'error) (test (>= 1/2 arg) 'error) (test (>= 1.0 arg) 'error) (test (>= 1+i arg) 'error) (test (>= arg 1) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) (for-each (lambda (op) (for-each (lambda (arg1) (test (op arg1) 'error) (test (op 0 arg1) 'error) (test (op 0.0 arg1) 'error) (for-each (lambda (arg2) (test (op arg1 arg2) 'error)) (list "hi" () 1 1.5 3/2 1+i (cons 1 2) (list 1 2) #\a 'a-symbol #(1) abs #f (lambda (a) (+ a 1)) # :hi # #))) (list "hi" () (cons 1 2) (list 1 2) #\a 'a-symbol #(1) abs #f (lambda (a) (+ a 1)) # :hi # #))) (list + - * / > < >= <= )) (for-each (lambda (op) (let ((val1 (catch #t (lambda () (op 1.0)) (lambda args 'error))) (val2 (catch #t (lambda () (op 1.0+0i)) (lambda args 'error)))) (if (not (morally-equal? val1 val2)) ; ignore nans (format-logged #t ";(~A 1) != (~A 1+0i)? (~A ~A)~%" op op val1 val2)))) (list magnitude angle rationalize abs exp log sin cos tan asin acos atan sinh cosh tanh asinh acosh atanh sqrt floor ceiling truncate round + - * / max min number? integer? real? complex? rational? even? odd? zero? positive? negative? real-part imag-part numerator denominator)) ;;; -------------------------------------------------------------------------------- ;;; sin ;;; -------------------------------------------------------------------------------- (num-test (sin -0.0+0.00000001i) 0.0+0.00000001i) (num-test (sin -0.0+0.0i) 0.0) (num-test (sin -0.0+1.0i) 0.0+1.17520119364380i) (num-test (sin -0.0+2.71828182845905i) 0.0+7.54413710281697i) (num-test (sin -0.0+3.14159265358979i) 0.0+11.54873935725775i) (num-test (sin -0.0-0.00000001i) -0.0-0.00000001i) (num-test (sin -0.0-0.0i) 0.0) (num-test (sin -0.0-1.0i) -0.0-1.17520119364380i) (num-test (sin -0.0-2.71828182845905i) -0.0-7.54413710281697i) (num-test (sin -0.0-3.14159265358979i) -0.0-11.54873935725775i) (num-test (sin -0.00000001) -0.00000001) (num-test (sin -0.00000001+0.00000001i) -0.00000001+0.00000001i) (num-test (sin -0.00000001+0.0i) -0.00000001) (num-test (sin -0.00000001+1.0i) -0.00000001543081+1.17520119364380i) (num-test (sin -0.00000001+2.71828182845905i) -0.00000007610125+7.54413710281697i) (num-test (sin -0.00000001+3.14159265358979i) -0.00000011591953+11.54873935725775i) (num-test (sin -0.00000001-0.00000001i) -0.00000001-0.00000001i) (num-test (sin -0.00000001-0.0i) -0.00000001) (num-test (sin -0.00000001-1.0i) -0.00000001543081-1.17520119364380i) (num-test (sin -0.00000001-2.71828182845905i) -0.00000007610125-7.54413710281697i) (num-test (sin -0.00000001-3.14159265358979i) -0.00000011591953-11.54873935725775i) (num-test (sin -1) -0.84147098480790) (num-test (sin -1.0) -0.84147098480790) (num-test (sin -1.0+0.00000001i) -0.84147098480790+0.00000000540302i) (num-test (sin -1.0+0.0i) -0.84147098480790) (num-test (sin -1.0+1.0i) -1.29845758141598+0.63496391478474i) (num-test (sin -1.0+2.71828182845905i) -6.40369949494148+4.07611467243740i) (num-test (sin -1.0+3.14159265358979i) -9.75429233860021+6.23981050459650i) (num-test (sin -1.0-0.00000001i) -0.84147098480790-0.00000000540302i) (num-test (sin -1.0-0.0i) -0.84147098480790) (num-test (sin -1.0-1.0i) -1.29845758141598-0.63496391478474i) (num-test (sin -1.0-2.71828182845905i) -6.40369949494148-4.07611467243740i) (num-test (sin -1.0-3.14159265358979i) -9.75429233860021-6.23981050459650i) (num-test (sin -1.57045105981189525579e+00+0.0e+00i) -9.9999994039535581669e-1) (num-test (sin -1.57045105981189525579e+00+1.0e+00i) -1.5430805428404715942e0+4.0575816248730593018e-4i) (num-test (sin -1.57045105981189525579e+00+1.19209289550781250e-07i) -9.9999994039536292211e-1+4.1159030931177815679e-11i) (num-test (sin -1.57045105981189525579e+00+2.0e+00i) -3.7621954668392959445e0+1.2522351259047577385e-3i) (num-test (sin -1.57045105981189525579e+00+5.0e-01i) -1.1276258979946363572e0+1.7991700040937027667e-4i) (num-test (sin -1.57045105981189525579e+00-1.0e+00i) -1.5430805428404715942e0-4.0575816248730593018e-4i) (num-test (sin -1.57045105981189525579e+00-1.19209289550781250e-07i) -9.9999994039536292211e-1-4.1159030931177815679e-11i) (num-test (sin -1.57045105981189525579e+00-2.0e+00i) -3.7621954668392959445e0-1.2522351259047577385e-3i) (num-test (sin -1.57045105981189525579e+00-5.0e-01i) -1.1276258979946363572e0-1.7991700040937027667e-4i) (num-test (sin -1.57114159377789786021e+00+0.0e+00i) -9.9999994039535581673e-1) (num-test (sin -1.57114159377789786021e+00+1.0e+00i) -1.5430805428404715942e0-4.0575816248716200955e-4i) (num-test (sin -1.57114159377789786021e+00+1.19209289550781250e-07i) -9.9999994039536292216e-1-4.1159030931163216752e-11i) (num-test (sin -1.57114159377789786021e+00+2.0e+00i) -3.7621954668392959447e0-1.2522351259043135762e-3i) (num-test (sin -1.57114159377789786021e+00+5.0e-01i) -1.1276258979946363573e0-1.7991700040930646090e-4i) (num-test (sin -1.57114159377789786021e+00-1.0e+00i) -1.5430805428404715942e0+4.0575816248716200955e-4i) (num-test (sin -1.57114159377789786021e+00-1.19209289550781250e-07i) -9.9999994039536292216e-1+4.1159030931163216752e-11i) (num-test (sin -1.57114159377789786021e+00-2.0e+00i) -3.7621954668392959447e0+1.2522351259043135762e-3i) (num-test (sin -1.57114159377789786021e+00-5.0e-01i) -1.1276258979946363573e0+1.7991700040930646090e-4i) (num-test (sin -1/1) -0.84147098480790) (num-test (sin -1/10) -0.09983341664683) (num-test (sin -1/1234) -0.00081037268278) (num-test (sin -1/1234000000) -0.00000000081037) (num-test (sin -1/2) -0.47942553860420) (num-test (sin -1/3) -0.32719469679615) (num-test (sin -1/362880) -0.00000275573192) (num-test (sin -1/500029) -0.00000199988401) (num-test (sin -10/1234) -0.00810363901920) (num-test (sin -10/1234000000) -0.00000000810373) (num-test (sin -10/362880) -0.00002755731922) (num-test (sin -10/500029) -0.00001999884007) (num-test (sin -1234/1234000000) -0.00000100000000) (num-test (sin -1234/362880) -0.00340056663826) (num-test (sin -1234/500029) -0.00246785435930) (num-test (sin -1234000000/1234000000) -0.84147098480790) (num-test (sin -2) -0.90929742682568) (num-test (sin -2.225073858507201399999999999999999999996E-308) -2.225073858507201399999999999999999999996E-308) (num-test (sin -2/1) -0.90929742682568) (num-test (sin -2/10) -0.19866933079506) (num-test (sin -2/1234) -0.00162074483338) (num-test (sin -2/1234000000) -0.00000000162075) (num-test (sin -2/3) -0.61836980306974) (num-test (sin -2/362880) -0.00000551146384) (num-test (sin -2/500029) -0.00000399976801) (num-test (sin -3.14124738660679181379e+00+0.0e+00i) -3.4526697614158608860e-4) (num-test (sin -3.14124738660679181379e+00+1.0e+00i) -5.3277478472529828958e-4-1.1752011235963524659e0i) (num-test (sin -3.14124738660679181379e+00+1.19209289550781250e-07i) -3.4526697614158854187e-4-1.1920928244535424532e-7i) (num-test (sin -3.14124738660679181379e+00+2.0e+00i) -1.2989619299133501696e-3-3.6268601916692946553e0i) (num-test (sin -3.14124738660679181379e+00+5.0e-01i) -3.8933200722554445944e-4-5.2109527443404709206e-1i) (num-test (sin -3.14124738660679181379e+00-1.0e+00i) -5.3277478472529828958e-4+1.1752011235963524659e0i) (num-test (sin -3.14124738660679181379e+00-1.19209289550781250e-07i) -3.4526697614158854187e-4+1.1920928244535424532e-7i) (num-test (sin -3.14124738660679181379e+00-2.0e+00i) -1.2989619299133501696e-3+3.6268601916692946553e0i) (num-test (sin -3.14124738660679181379e+00-5.0e-01i) -3.8933200722554445944e-4+5.2109527443404709206e-1i) (num-test (sin -3.14193792057279441821e+00+0.0e+00i) 3.4526697614134115926e-4) (num-test (sin -3.14193792057279441821e+00+1.0e+00i) 5.3277478472492034385e-4-1.1752011235963524660e0i) (num-test (sin -3.14193792057279441821e+00+1.19209289550781250e-07i) 3.4526697614134361253e-4-1.1920928244535424533e-7i) (num-test (sin -3.14193792057279441821e+00+2.0e+00i) 1.2989619299124286975e-3-3.6268601916692946556e0i) (num-test (sin -3.14193792057279441821e+00+5.0e-01i) 3.8933200722526827075e-4-5.2109527443404709211e-1i) (num-test (sin -3.14193792057279441821e+00-1.0e+00i) 5.3277478472492034385e-4+1.1752011235963524660e0i) (num-test (sin -3.14193792057279441821e+00-1.19209289550781250e-07i) 3.4526697614134361253e-4+1.1920928244535424533e-7i) (num-test (sin -3.14193792057279441821e+00-2.0e+00i) 1.2989619299124286975e-3+3.6268601916692946556e0i) (num-test (sin -3.14193792057279441821e+00-5.0e-01i) 3.8933200722526827075e-4+5.2109527443404709211e-1i) (num-test (sin -3.45266983001243932001e-04+0.0e+00i) -3.4526697614140534807e-4) (num-test (sin -3.45266983001243932001e-04+1.0e+00i) -5.3277478472501939236e-4+1.1752011235963524660e0i) (num-test (sin -3.45266983001243932001e-04+1.19209289550781250e-07i) -3.4526697614140780134e-4+1.1920928244535424533e-7i) (num-test (sin -3.45266983001243932001e-04+2.0e+00i) -1.2989619299126701883e-3+3.6268601916692946556e0i) (num-test (sin -3.45266983001243932001e-04+5.0e-01i) -3.8933200722534065172e-4+5.2109527443404709209e-1i) (num-test (sin -3.45266983001243932001e-04-1.0e+00i) -5.3277478472501939236e-4-1.1752011235963524660e0i) (num-test (sin -3.45266983001243932001e-04-1.19209289550781250e-07i) -3.4526697614140780134e-4-1.1920928244535424533e-7i) (num-test (sin -3.45266983001243932001e-04-2.0e+00i) -1.2989619299126701883e-3-3.6268601916692946556e0i) (num-test (sin -3.45266983001243932001e-04-5.0e-01i) -3.8933200722534065172e-4-5.2109527443404709209e-1i) (num-test (sin -3/10) -0.29552020666134) (num-test (sin -3/1234) -0.00243111591964) (num-test (sin -3/1234000000) -0.00000000243112) (num-test (sin -3/2) -0.99749498660405) (num-test (sin -3/362880) -0.00000826719577) (num-test (sin -3/500029) -0.00000599965202) (num-test (sin -362880/1234000000) -0.00029406806707) (num-test (sin -4.71204371340168837179e+00+0.0e+00i) 9.9999994039535581664e-1) (num-test (sin -4.71204371340168837179e+00+1.0e+00i) 1.5430805428404715941e0-4.0575816248744985081e-4i) (num-test (sin -4.71204371340168837179e+00+1.19209289550781250e-07i) 9.9999994039536292207e-1-4.1159030931192414605e-11i) (num-test (sin -4.71204371340168837179e+00+2.0e+00i) 3.7621954668392959444e0-1.2522351259052019007e-3i) (num-test (sin -4.71204371340168837179e+00+5.0e-01i) 1.1276258979946363572e0-1.7991700040943409243e-4i) (num-test (sin -4.71204371340168837179e+00-1.0e+00i) 1.5430805428404715941e0+4.0575816248744985081e-4i) (num-test (sin -4.71204371340168837179e+00-1.19209289550781250e-07i) 9.9999994039536292207e-1+4.1159030931192414605e-11i) (num-test (sin -4.71204371340168837179e+00-2.0e+00i) 3.7621954668392959444e0+1.2522351259052019007e-3i) (num-test (sin -4.71204371340168837179e+00-5.0e-01i) 1.1276258979946363572e0+1.7991700040943409243e-4i) (num-test (sin -4.71273424736769097620e+00+0.0e+00i) 9.9999994039535581677e-1) (num-test (sin -4.71273424736769097620e+00+1.0e+00i) 1.5430805428404715943e0+4.0575816248701808892e-4i) (num-test (sin -4.71273424736769097620e+00+1.19209289550781250e-07i) 9.9999994039536292220e-1+4.1159030931148617825e-11i) (num-test (sin -4.71273424736769097620e+00+2.0e+00i) 3.7621954668392959448e0+1.2522351259038694139e-3i) (num-test (sin -4.71273424736769097620e+00+5.0e-01i) 1.1276258979946363573e0+1.7991700040924264514e-4i) (num-test (sin -4.71273424736769097620e+00-1.0e+00i) 1.5430805428404715943e0-4.0575816248701808892e-4i) (num-test (sin -4.71273424736769097620e+00-1.19209289550781250e-07i) 9.9999994039536292220e-1-4.1159030931148617825e-11i) (num-test (sin -4.71273424736769097620e+00-2.0e+00i) 3.7621954668392959448e0-1.2522351259038694139e-3i) (num-test (sin -4.71273424736769097620e+00-5.0e-01i) 1.1276258979946363573e0-1.7991700040924264514e-4i) (num-test (sin -500029/1234000000) -0.00040520987546) (num-test (sin -500029/362880) -0.98146191370834) (num-test (sin -6.28284004019658492979e+00+0.0e+00i) 3.4526697614170855328e-4) (num-test (sin -6.28284004019658492979e+00+1.0e+00i) 5.3277478472548726245e-4+1.1752011235963524659e0i) (num-test (sin -6.28284004019658492979e+00+1.19209289550781250e-07i) 3.4526697614171100655e-4+1.1920928244535424532e-7i) (num-test (sin -6.28284004019658492979e+00+2.0e+00i) 1.2989619299138109057e-3+3.6268601916692946552e0i) (num-test (sin -6.28284004019658492979e+00+5.0e-01i) 3.8933200722568255379e-4+5.2109527443404709204e-1i) (num-test (sin -6.28284004019658492979e+00-1.0e+00i) 5.3277478472548726245e-4-1.1752011235963524659e0i) (num-test (sin -6.28284004019658492979e+00-1.19209289550781250e-07i) 3.4526697614171100655e-4-1.1920928244535424532e-7i) (num-test (sin -6.28284004019658492979e+00-2.0e+00i) 1.2989619299138109057e-3-3.6268601916692946552e0i) (num-test (sin -6.28284004019658492979e+00-5.0e-01i) 3.8933200722568255379e-4-5.2109527443404709204e-1i) (num-test (sin -6.28353057416258753420e+00+0.0e+00i) -3.4526697614121869459e-4) (num-test (sin -6.28353057416258753420e+00+1.0e+00i) -5.3277478472473137099e-4+1.1752011235963524661e0i) (num-test (sin -6.28353057416258753420e+00+1.19209289550781250e-07i) -3.4526697614122114786e-4+1.1920928244535424534e-7i) (num-test (sin -6.28353057416258753420e+00+2.0e+00i) -1.2989619299119679614e-3+3.6268601916692946558e0i) (num-test (sin -6.28353057416258753420e+00+5.0e-01i) -3.8933200722513017641e-4+5.2109527443404709213e-1i) (num-test (sin -6.28353057416258753420e+00-1.0e+00i) -5.3277478472473137099e-4-1.1752011235963524661e0i) (num-test (sin -6.28353057416258753420e+00-1.19209289550781250e-07i) -3.4526697614122114786e-4-1.1920928244535424534e-7i) (num-test (sin -6.28353057416258753420e+00-2.0e+00i) -1.2989619299119679614e-3-3.6268601916692946558e0i) (num-test (sin -6.28353057416258753420e+00-5.0e-01i) -3.8933200722513017641e-4-5.2109527443404709213e-1i) (num-test (sin -9.42443269378637893396e+00+0.0e+00i) -3.4526697614094283958e-4) (num-test (sin -9.42443269378637893396e+00+1.0e+00i) -5.3277478472430570447e-4-1.1752011235963524662e0i) (num-test (sin -9.42443269378637893396e+00+1.19209289550781250e-07i) -3.4526697614094529285e-4-1.1920928244535424535e-7i) (num-test (sin -9.42443269378637893396e+00+2.0e+00i) -1.2989619299109301409e-3-3.6268601916692946561e0i) (num-test (sin -9.42443269378637893396e+00+5.0e-01i) -3.8933200722481911514e-4-5.2109527443404709218e-1i) (num-test (sin -9.42443269378637893396e+00-1.0e+00i) -5.3277478472430570447e-4+1.1752011235963524662e0i) (num-test (sin -9.42443269378637893396e+00-1.19209289550781250e-07i) -3.4526697614094529285e-4+1.1920928244535424535e-7i) (num-test (sin -9.42443269378637893396e+00-2.0e+00i) -1.2989619299109301409e-3+3.6268601916692946561e0i) (num-test (sin -9.42443269378637893396e+00-5.0e-01i) -3.8933200722481911514e-4+5.2109527443404709218e-1i) (num-test (sin -9.42512322775237976202e+00+0.0e+00i) 3.4526697614020805155e-4) (num-test (sin -9.42512322775237976202e+00+1.0e+00i) 5.3277478472317186729e-4-1.1752011235963524665e0i) (num-test (sin -9.42512322775237976202e+00+1.19209289550781250e-07i) 3.4526697614021050482e-4-1.1920928244535424538e-7i) (num-test (sin -9.42512322775237976202e+00+2.0e+00i) 1.2989619299081657245e-3-3.6268601916692946571e0i) (num-test (sin -9.42512322775237976202e+00+5.0e-01i) 3.8933200722399054908e-4-5.2109527443404709231e-1i) (num-test (sin -9.42512322775237976202e+00-1.0e+00i) 5.3277478472317186729e-4+1.1752011235963524665e0i) (num-test (sin -9.42512322775237976202e+00-1.19209289550781250e-07i) 3.4526697614021050482e-4+1.1920928244535424538e-7i) (num-test (sin -9.42512322775237976202e+00-2.0e+00i) 1.2989619299081657245e-3+3.6268601916692946571e0i) (num-test (sin -9.42512322775237976202e+00-5.0e-01i) 3.8933200722399054908e-4+5.2109527443404709231e-1i) (num-test (sin 0) 0.0) (num-test (sin 0.0) 0.0) (num-test (sin 0.0+0.00000001i) 0.0+0.00000001i) (num-test (sin 0.0+0.0i) 0.0) (num-test (sin 0.0+1.0i) 0.0+1.17520119364380i) (num-test (sin 0.0+2.71828182845905i) 0.0+7.54413710281697i) (num-test (sin 0.0+3.14159265358979i) 0.0+11.54873935725775i) (num-test (sin 0.0-0.00000001i) 0.0-0.00000001i) (num-test (sin 0.0-0.0i) 0.0) (num-test (sin 0.0-1.0i) 0.0-1.17520119364380i) (num-test (sin 0.0-2.71828182845905i) 0.0-7.54413710281697i) (num-test (sin 0.0-3.14159265358979i) 0.0-11.54873935725775i) (num-test (sin 0.00000001) 0.00000001) (num-test (sin 0.00000001+0.00000001i) 0.00000001+0.00000001i) (num-test (sin 0.00000001+0.0i) 0.00000001) (num-test (sin 0.00000001+1.0i) 0.00000001543081+1.17520119364380i) (num-test (sin 0.00000001+2.71828182845905i) 0.00000007610125+7.54413710281697i) (num-test (sin 0.00000001+3.14159265358979i) 0.00000011591953+11.54873935725775i) (num-test (sin 0.00000001-0.00000001i) 0.00000001-0.00000001i) (num-test (sin 0.00000001-0.0i) 0.00000001) (num-test (sin 0.00000001-1.0i) 0.00000001543081-1.17520119364380i) (num-test (sin 0.00000001-2.71828182845905i) 0.00000007610125-7.54413710281697i) (num-test (sin 0.00000001-3.14159265358979i) 0.00000011591953-11.54873935725775i) (num-test (sin 0/1) 0.0) (num-test (sin 0/1234000000) 0.0) (num-test (sin 0/500029) 0.0) (num-test (sin 1) 0.84147098480790) (num-test (sin 1.0) 0.84147098480790) (num-test (sin 1.0+0.00000001i) 0.84147098480790+0.00000000540302i) (num-test (sin 1.0+0.0i) 0.84147098480790) (num-test (sin 1.0+1.0i) 1.29845758141598+0.63496391478474i) (num-test (sin 1.0+2.71828182845905i) 6.40369949494148+4.07611467243740i) (num-test (sin 1.0+3.14159265358979i) 9.75429233860021+6.23981050459650i) (num-test (sin 1.0-0.00000001i) 0.84147098480790-0.00000000540302i) (num-test (sin 1.0-0.0i) 0.84147098480790) (num-test (sin 1.0-1.0i) 1.29845758141598-0.63496391478474i) (num-test (sin 1.0-2.71828182845905i) 6.40369949494148-4.07611467243740i) (num-test (sin 1.0-3.14159265358979i) 9.75429233860021-6.23981050459650i) (num-test (sin 1.110223024625156799999999999999999999997E-16) 1.11022302462515679999999999999999771924E-16) (num-test (sin 1.57045105981189525579e+00+0.0e+00i) 9.9999994039535581669e-1) (num-test (sin 1.57045105981189525579e+00+1.0e+00i) 1.5430805428404715942e0+4.0575816248730593018e-4i) (num-test (sin 1.57045105981189525579e+00+1.19209289550781250e-07i) 9.9999994039536292211e-1+4.1159030931177815679e-11i) (num-test (sin 1.57045105981189525579e+00+2.0e+00i) 3.7621954668392959445e0+1.2522351259047577385e-3i) (num-test (sin 1.57045105981189525579e+00+5.0e-01i) 1.1276258979946363572e0+1.7991700040937027667e-4i) (num-test (sin 1.57045105981189525579e+00-1.0e+00i) 1.5430805428404715942e0-4.0575816248730593018e-4i) (num-test (sin 1.57045105981189525579e+00-1.19209289550781250e-07i) 9.9999994039536292211e-1-4.1159030931177815679e-11i) (num-test (sin 1.57045105981189525579e+00-2.0e+00i) 3.7621954668392959445e0-1.2522351259047577385e-3i) (num-test (sin 1.57045105981189525579e+00-5.0e-01i) 1.1276258979946363572e0-1.7991700040937027667e-4i) (num-test (sin 1.57114159377789786021e+00+0.0e+00i) 9.9999994039535581673e-1) (num-test (sin 1.57114159377789786021e+00+1.0e+00i) 1.5430805428404715942e0-4.0575816248716200955e-4i) (num-test (sin 1.57114159377789786021e+00+1.19209289550781250e-07i) 9.9999994039536292216e-1-4.1159030931163216752e-11i) (num-test (sin 1.57114159377789786021e+00+2.0e+00i) 3.7621954668392959447e0-1.2522351259043135762e-3i) (num-test (sin 1.57114159377789786021e+00+5.0e-01i) 1.1276258979946363573e0-1.7991700040930646090e-4i) (num-test (sin 1.57114159377789786021e+00-1.0e+00i) 1.5430805428404715942e0+4.0575816248716200955e-4i) (num-test (sin 1.57114159377789786021e+00-1.19209289550781250e-07i) 9.9999994039536292216e-1+4.1159030931163216752e-11i) (num-test (sin 1.57114159377789786021e+00-2.0e+00i) 3.7621954668392959447e0+1.2522351259043135762e-3i) (num-test (sin 1.57114159377789786021e+00-5.0e-01i) 1.1276258979946363573e0+1.7991700040930646090e-4i) (num-test (sin 1/1) 0.84147098480790) (num-test (sin 1/10) 0.09983341664683) (num-test (sin 1/1234) 0.00081037268278) (num-test (sin 1/1234000000) 0.00000000081037) (num-test (sin 1/2) 0.47942553860420) (num-test (sin 1/3) 0.32719469679615) (num-test (sin 1/362880) 0.00000275573192) (num-test (sin 1/500029) 0.00000199988401) (num-test (sin 10/1234) 0.00810363901920) (num-test (sin 10/1234000000) 0.00000000810373) (num-test (sin 10/3) -0.1905679628754527) (num-test (sin 10/362880) 0.00002755731922) (num-test (sin 10/500029) 0.00001999884007) (num-test (sin 1234.0+0.00000001i) .6019276547624973-7.985506235875843E-9i) (num-test (sin 1234.0+12.0i) 48983.30495194942-64983.97008730317i) (num-test (sin 1234.0+2.71828182845905i) 4.58074477716391-6.024375387884452i) (num-test (sin 1234.0+3.14159265358979i) 6.977517249251167-9.222253015388718i) (num-test (sin 1234/10) -0.7693905459455223) (num-test (sin 1234/1234000000) 0.00000100000000) (num-test (sin 1234/3) 0.213644699569724) (num-test (sin 1234/362880) 0.00340056663826) (num-test (sin 1234/500029) 0.00246785435930) (num-test (sin 1234000000.0+0.00000001i) -0.9872932128398908+1.5890913089022285E-9i) (num-test (sin 1234000000.0+2.71828182845905i) -7.513424898263172+1.198832270325275i) (num-test (sin 1234000000.0+3.14159265358979i) -11.44465679247962+1.835200134139553i) (num-test (sin 1234000000/1234000000) 0.84147098480790) (num-test (sin 1234000000/3) 9.98585468017658e-1) (num-test (sin 1234000000/362880) .9798963032808383) (num-test (sin 1234000000/500029) -0.9907886154453116) (num-test (sin 2) 0.90929742682568) (num-test (sin 2.71828182845905) .4107812905029501) (num-test (sin 2.71828182845905+0.00000001i) .4107812905029501-9.117339147869465E-9i) (num-test (sin 2.71828182845905+0.0i) .4107812905029501) (num-test (sin 2.71828182845905+1.0i) .6338686545195173-1.071470784943156i) (num-test (sin 2.71828182845905+2.71828182845905i) 3.126097025348496-6.878245654440458i) (num-test (sin 2.71828182845905+3.14159265358979i) 4.761757525968664-10.52937734504676i) (num-test (sin 2/10) 0.19866933079506) (num-test (sin 2/1234) 0.00162074483338) (num-test (sin 2/1234000000) 0.00000000162075) (num-test (sin 2/3) 0.61836980306974) (num-test (sin 2/362880) 0.00000551146384) (num-test (sin 2/500029) 0.00000399976801) (num-test (sin 3.14124738660679181379e+00+0.0e+00i) 3.4526697614158608860e-4) (num-test (sin 3.14124738660679181379e+00+1.0e+00i) 5.3277478472529828958e-4-1.1752011235963524659e0i) (num-test (sin 3.14124738660679181379e+00+1.19209289550781250e-07i) 3.4526697614158854187e-4-1.1920928244535424532e-7i) (num-test (sin 3.14124738660679181379e+00+2.0e+00i) 1.2989619299133501696e-3-3.6268601916692946553e0i) (num-test (sin 3.14124738660679181379e+00+5.0e-01i) 3.8933200722554445944e-4-5.2109527443404709206e-1i) (num-test (sin 3.14124738660679181379e+00-1.0e+00i) 5.3277478472529828958e-4+1.1752011235963524659e0i) (num-test (sin 3.14124738660679181379e+00-1.19209289550781250e-07i) 3.4526697614158854187e-4+1.1920928244535424532e-7i) (num-test (sin 3.14124738660679181379e+00-2.0e+00i) 1.2989619299133501696e-3+3.6268601916692946553e0i) (num-test (sin 3.14124738660679181379e+00-5.0e-01i) 3.8933200722554445944e-4+5.2109527443404709206e-1i) (num-test (sin 3.14159265358979+0.00000001i) -6.982889851335445E-15-1.0E-8i) (num-test (sin 3.14159265358979+0.0i) -6.982889851335445E-15) (num-test (sin 3.14159265358979+1.0i) -1.077516210464362E-14-1.175201193643801i) (num-test (sin 3.14159265358979+2.71828182845905i) -5.314066559815525E-14-7.54413710281663i) (num-test (sin 3.14159265358979+3.14159265358979i) -8.094533288479446E-14-11.54873935725783i) (num-test (sin 3.14193792057279441821e+00+0.0e+00i) -3.4526697614134115926e-4) (num-test (sin 3.14193792057279441821e+00+1.0e+00i) -5.3277478472492034385e-4-1.1752011235963524660e0i) (num-test (sin 3.14193792057279441821e+00+1.19209289550781250e-07i) -3.4526697614134361253e-4-1.1920928244535424533e-7i) (num-test (sin 3.14193792057279441821e+00+2.0e+00i) -1.2989619299124286975e-3-3.6268601916692946556e0i) (num-test (sin 3.14193792057279441821e+00+5.0e-01i) -3.8933200722526827075e-4-5.2109527443404709211e-1i) (num-test (sin 3.14193792057279441821e+00-1.0e+00i) -5.3277478472492034385e-4+1.1752011235963524660e0i) (num-test (sin 3.14193792057279441821e+00-1.19209289550781250e-07i) -3.4526697614134361253e-4+1.1920928244535424533e-7i) (num-test (sin 3.14193792057279441821e+00-2.0e+00i) -1.2989619299124286975e-3+3.6268601916692946556e0i) (num-test (sin 3.14193792057279441821e+00-5.0e-01i) -3.8933200722526827075e-4+5.2109527443404709211e-1i) (num-test (sin 3.45266983001243932001e-04+0.0e+00i) 3.4526697614140534807e-4) (num-test (sin 3.45266983001243932001e-04+1.0e+00i) 5.3277478472501939236e-4+1.1752011235963524660e0i) (num-test (sin 3.45266983001243932001e-04+1.19209289550781250e-07i) 3.4526697614140780134e-4+1.1920928244535424533e-7i) (num-test (sin 3.45266983001243932001e-04+2.0e+00i) 1.2989619299126701883e-3+3.6268601916692946556e0i) (num-test (sin 3.45266983001243932001e-04+5.0e-01i) 3.8933200722534065172e-4+5.2109527443404709209e-1i) (num-test (sin 3.45266983001243932001e-04-1.0e+00i) 5.3277478472501939236e-4-1.1752011235963524660e0i) (num-test (sin 3.45266983001243932001e-04-1.19209289550781250e-07i) 3.4526697614140780134e-4-1.1920928244535424533e-7i) (num-test (sin 3.45266983001243932001e-04-2.0e+00i) 1.2989619299126701883e-3-3.6268601916692946556e0i) (num-test (sin 3.45266983001243932001e-04-5.0e-01i) 3.8933200722534065172e-4-5.2109527443404709209e-1i) (num-test (sin 3/10) 0.29552020666134) (num-test (sin 3/1234) 0.00243111591964) (num-test (sin 3/1234000000) 0.00000000243112) (num-test (sin 3/2) 0.99749498660405) (num-test (sin 3/362880) 0.00000826719577) (num-test (sin 3/500029) 0.00000599965202) (num-test (sin 362880/1234) -0.9463147870254296) (num-test (sin 362880/1234000000) 0.00029406806707) (num-test (sin 362880/500029) 0.66367262572318) (num-test (sin 4.71204371340168837179e+00+0.0e+00i) -9.9999994039535581664e-1) (num-test (sin 4.71204371340168837179e+00+1.0e+00i) -1.5430805428404715941e0-4.0575816248744985081e-4i) (num-test (sin 4.71204371340168837179e+00+1.19209289550781250e-07i) -9.9999994039536292207e-1-4.1159030931192414605e-11i) (num-test (sin 4.71204371340168837179e+00+2.0e+00i) -3.7621954668392959444e0-1.2522351259052019007e-3i) (num-test (sin 4.71204371340168837179e+00+5.0e-01i) -1.1276258979946363572e0-1.7991700040943409243e-4i) (num-test (sin 4.71204371340168837179e+00-1.0e+00i) -1.5430805428404715941e0+4.0575816248744985081e-4i) (num-test (sin 4.71204371340168837179e+00-1.19209289550781250e-07i) -9.9999994039536292207e-1+4.1159030931192414605e-11i) (num-test (sin 4.71204371340168837179e+00-2.0e+00i) -3.7621954668392959444e0+1.2522351259052019007e-3i) (num-test (sin 4.71204371340168837179e+00-5.0e-01i) -1.1276258979946363572e0+1.7991700040943409243e-4i) (num-test (sin 4.71273424736769097620e+00+0.0e+00i) -9.9999994039535581677e-1) (num-test (sin 4.71273424736769097620e+00+1.0e+00i) -1.5430805428404715943e0+4.0575816248701808892e-4i) (num-test (sin 4.71273424736769097620e+00+1.19209289550781250e-07i) -9.9999994039536292220e-1+4.1159030931148617825e-11i) (num-test (sin 4.71273424736769097620e+00+2.0e+00i) -3.7621954668392959448e0+1.2522351259038694139e-3i) (num-test (sin 4.71273424736769097620e+00+5.0e-01i) -1.1276258979946363573e0+1.7991700040924264514e-4i) (num-test (sin 4.71273424736769097620e+00-1.0e+00i) -1.5430805428404715943e0-4.0575816248701808892e-4i) (num-test (sin 4.71273424736769097620e+00-1.19209289550781250e-07i) -9.9999994039536292220e-1-4.1159030931148617825e-11i) (num-test (sin 4.71273424736769097620e+00-2.0e+00i) -3.7621954668392959448e0-1.2522351259038694139e-3i) (num-test (sin 4.71273424736769097620e+00-5.0e-01i) -1.1276258979946363573e0-1.7991700040924264514e-4i) (num-test (sin 500029/10) .9665258739436294) (num-test (sin 500029/1234) .05553717596791147) (num-test (sin 500029/1234000000) 0.00040520987546) (num-test (sin 500029/2) 0.270047165973401) (num-test (sin 500029/3) 7.610322596690986e-1) (num-test (sin 500029/362880) 0.98146191370834) (num-test (sin 6.28284004019658492979e+00+0.0e+00i) -3.4526697614170855328e-4) (num-test (sin 6.28284004019658492979e+00+1.0e+00i) -5.3277478472548726245e-4+1.1752011235963524659e0i) (num-test (sin 6.28284004019658492979e+00+1.19209289550781250e-07i) -3.4526697614171100655e-4+1.1920928244535424532e-7i) (num-test (sin 6.28284004019658492979e+00+2.0e+00i) -1.2989619299138109057e-3+3.6268601916692946552e0i) (num-test (sin 6.28284004019658492979e+00+5.0e-01i) -3.8933200722568255379e-4+5.2109527443404709204e-1i) (num-test (sin 6.28284004019658492979e+00-1.0e+00i) -5.3277478472548726245e-4-1.1752011235963524659e0i) (num-test (sin 6.28284004019658492979e+00-1.19209289550781250e-07i) -3.4526697614171100655e-4-1.1920928244535424532e-7i) (num-test (sin 6.28284004019658492979e+00-2.0e+00i) -1.2989619299138109057e-3-3.6268601916692946552e0i) (num-test (sin 6.28284004019658492979e+00-5.0e-01i) -3.8933200722568255379e-4-5.2109527443404709204e-1i) (num-test (sin 6.28353057416258753420e+00+0.0e+00i) 3.4526697614121869459e-4) (num-test (sin 6.28353057416258753420e+00+1.0e+00i) 5.3277478472473137099e-4+1.1752011235963524661e0i) (num-test (sin 6.28353057416258753420e+00+1.19209289550781250e-07i) 3.4526697614122114786e-4+1.1920928244535424534e-7i) (num-test (sin 6.28353057416258753420e+00+2.0e+00i) 1.2989619299119679614e-3+3.6268601916692946558e0i) (num-test (sin 6.28353057416258753420e+00+5.0e-01i) 3.8933200722513017641e-4+5.2109527443404709213e-1i) (num-test (sin 6.28353057416258753420e+00-1.0e+00i) 5.3277478472473137099e-4-1.1752011235963524661e0i) (num-test (sin 6.28353057416258753420e+00-1.19209289550781250e-07i) 3.4526697614122114786e-4-1.1920928244535424534e-7i) (num-test (sin 6.28353057416258753420e+00-2.0e+00i) 1.2989619299119679614e-3-3.6268601916692946558e0i) (num-test (sin 6.28353057416258753420e+00-5.0e-01i) 3.8933200722513017641e-4-5.2109527443404709213e-1i) (num-test (sin 9.42443269378637893396e+00+0.0e+00i) 3.4526697614094283958e-4) (num-test (sin 9.42443269378637893396e+00+1.0e+00i) 5.3277478472430570447e-4-1.1752011235963524662e0i) (num-test (sin 9.42443269378637893396e+00+1.19209289550781250e-07i) 3.4526697614094529285e-4-1.1920928244535424535e-7i) (num-test (sin 9.42443269378637893396e+00+2.0e+00i) 1.2989619299109301409e-3-3.6268601916692946561e0i) (num-test (sin 9.42443269378637893396e+00+5.0e-01i) 3.8933200722481911514e-4-5.2109527443404709218e-1i) (num-test (sin 9.42443269378637893396e+00-1.0e+00i) 5.3277478472430570447e-4+1.1752011235963524662e0i) (num-test (sin 9.42443269378637893396e+00-1.19209289550781250e-07i) 3.4526697614094529285e-4+1.1920928244535424535e-7i) (num-test (sin 9.42443269378637893396e+00-2.0e+00i) 1.2989619299109301409e-3+3.6268601916692946561e0i) (num-test (sin 9.42443269378637893396e+00-5.0e-01i) 3.8933200722481911514e-4+5.2109527443404709218e-1i) (num-test (sin 9.42512322775237976202e+00+0.0e+00i) -3.4526697614020805155e-4) (num-test (sin 9.42512322775237976202e+00+1.0e+00i) -5.3277478472317186729e-4-1.1752011235963524665e0i) (num-test (sin 9.42512322775237976202e+00+1.19209289550781250e-07i) -3.4526697614021050482e-4-1.1920928244535424538e-7i) (num-test (sin 9.42512322775237976202e+00+2.0e+00i) -1.2989619299081657245e-3-3.6268601916692946571e0i) (num-test (sin 9.42512322775237976202e+00+5.0e-01i) -3.8933200722399054908e-4-5.2109527443404709231e-1i) (num-test (sin 9.42512322775237976202e+00-1.0e+00i) -5.3277478472317186729e-4+1.1752011235963524665e0i) (num-test (sin 9.42512322775237976202e+00-1.19209289550781250e-07i) -3.4526697614021050482e-4+1.1920928244535424538e-7i) (num-test (sin 9.42512322775237976202e+00-2.0e+00i) -1.2989619299081657245e-3+3.6268601916692946571e0i) (num-test (sin 9.42512322775237976202e+00-5.0e-01i) -3.8933200722399054908e-4+5.2109527443404709231e-1i) (num-test (sin pi) -6.982889851335445E-15) (num-test (sin 32767.) 1.8750655394138942394239E-1) (num-test (sin 8388607.) 9.9234509376961249835628E-1) (num-test (sin 2147483647.) -7.2491655514455639054829E-1) (num-test (sin 80143857.0000000149) 1.283143758817470627530994988383551176295E-10) (num-test (sin (- (/ pi 2) (* 0+i (log (/ (+ 1 (sqrt 5)) 2))))) (/ (sqrt 5) 2)) (num-test (sin (/ pi 10)) (/ (- (sqrt 5) 1) 4)) (num-test (sin (/ pi 12)) (* (/ (sqrt 2) 4) (- (sqrt 3) 1))) (num-test (sin (/ pi 12)) (/ (- (sqrt 6) (sqrt 2)) 4)) (num-test (sin (/ pi 15)) (/ (sqrt (- 7 (sqrt 5) (sqrt (- 30 (* 6 (sqrt 5)))))) 4)) (num-test (sin (/ pi 16)) (/ (sqrt (- 2 (sqrt (+ 2 (sqrt 2))))) 2)) (num-test (sin (/ pi 20)) (/ (sqrt (- 8 (* 2 (sqrt (+ 10 (* 2 (sqrt 5))))))) 4)) (num-test (sin (/ pi 24)) (/ (sqrt (- 2 (sqrt (+ 2 (sqrt 3))))) 2)) (num-test (sin (/ pi 3)) (/ (sqrt 3) 2)) (num-test (sin (/ pi 3)) (/ (sqrt 3) 2)) (num-test (sin (/ pi 30)) (/ (+ -1 (- (sqrt 5)) (sqrt (- 30 (* 6 (sqrt 5))))) 8)) (num-test (sin (/ pi 32)) (/ (sqrt (- 2 (sqrt (+ 2 (sqrt (+ 2 (sqrt 2))))))) 2)) (num-test (sin (/ pi 4)) (/ (sqrt 2) 2)) (num-test (sin (/ pi 5)) (/ (sqrt (- 10 (* 2 (sqrt 5)))) 4)) (num-test (sin (/ pi 6)) 1/2) (num-test (sin (/ pi 8)) (/ (sqrt (- 2 (sqrt 2))) 2)) (num-test (* (sin (/ pi 11)) (sin (/ (* 2 pi) 11)) (sin (/ (* 3 pi) 11)) (sin (/ (* 4 pi) 11)) (sin (/ (* 5 pi) 11))) (sqrt (/ 11 1024))) (num-test (* (sin (/ pi 7)) (sin (/ (* 2 pi) 7)) (sin (/ (* 3 pi) 7))) (/ (sqrt 7) 8)) (num-test (* (sin (/ pi 9)) (sin (/ (* 2 pi) 9)) (sin (/ (* 4 pi) 9))) (/ (sqrt 3) 8)) (num-test (* pi (+ 1.0 (atan (tan (acos (cos (asin (sin (/ 1.0 (/ 1.0 pi)))))))))) pi) (num-test (+ (* (sin 0.1) (sin 0.1)) (* (cos 0.1) (cos 0.1))) 1.0) (num-test (/ (- (sqrt 5) 1) 2) (/ (sin (* pi 1/5)) (sin (* pi 2/5)))) (let ((val1 (sin (/ pi 60))) (val2 (* 1/16 (- (* (+ (sqrt 6) (sqrt 2)) (- (sqrt 5) 1)) (* 2 (- (sqrt 3) 1) (sqrt (+ 5 (sqrt 5)))))))) (num-test (- val1 val2) 0.0)) (let ((val1 (sin (/ (* 4 pi) 15))) (val2 (* 1/8 (+ (sqrt (+ 10 (* 2 (sqrt 5)))) (sqrt 15) (- (sqrt 3)))))) (num-test (- val1 val2) 0.0)) (num-test (sin 22) -8.851309290403875921690256815772332463307E-3) (if with-bignums (begin (num-test (sin 1e22) -8.522008497671888017727058937530293682616E-1) (num-test (sin 1+100i) 1.130986289301505745599509129978056149094E43+7.261979450834655624032117190441273726075E42i) (num-test (sin 0+100i) 0.0+1.34405857090806772420631277579000679368E43i) (num-test (sin 0+1000i) 0.0+9.850355570085234969444396761216615626576E433i) (num-test (sin 1+1000i) 8.288788402267571487966465808315066740252E433+5.322169828138126401369949836048836144292E433i) (num-test (sin 1e-100+1e-100i) 9.999999999999999999999999999999999999992E-101+9.999999999999999999999999999999999999992E-101i) )) ;; not even close if not bignums: 0.4626130407646 ;; we start to lose around 1e18 -- running out of bits of fraction? (test (>= 0.0000001 (sin 0.0000001)) #t) (test (>= 0.000000001 (sin 0.000000001)) #t) ;(test (>= 0.0000001 (sin (+ (* 2 pi) 0.0000001))) #t) ; this fails because "pi" is inaccurate? (num-test (sin 31415926.0) -0.5106132968486) (num-test (sin (+ (* 200 pi) 0.001)) 9.999998333333416874831395573527051109993E-4) (test (< (abs (- (sin (+ (* 200 pi) 0.001)) (- (sin (- (* 200 pi) 0.001))))) 5e-13) #t) (for-each (lambda (num-and-val) (let ((num (car num-and-val)) (val (cadr num-and-val))) (num-test-1 'sin num (sin num) val))) (vector (list 0 0) (list 1 0.8414709848079) (list 2 0.90929742682568) (list 3 0.14112000805987) (list -1 -0.8414709848079) (list -2 -0.90929742682568) (list -3 -0.14112000805987) (list 1/2 0.4794255386042) (list 1/3 0.32719469679615) (list -1/2 -0.4794255386042) (list -1/3 -0.32719469679615) (list 1/9223372036854775807 1.0842021724855e-19) (list 0.0 0.0) (list 1.0 0.8414709848079) (list 2.0 0.90929742682568) (list -2.0 -0.90929742682568) (list 1.000000000000000000000000000000000000002E-309 1.000000000000000000000000000000000000002E-309) (list 0+1i 0+1.1752011936438i) (list 0+2i 0+3.626860407847i) (list 0-1i 0-1.1752011936438i) (list 1+1i 1.298457581416+0.63496391478474i) (list 1-1i 1.298457581416-0.63496391478474i) (list -1+1i -1.298457581416+0.63496391478474i) (list -1-1i -1.298457581416-0.63496391478474i) (list 0.1+0.1i 0.10033299984131+0.099666333492108i) (list 1e-16+1e-16i 1e-16+1e-16i) )) (test (sin) 'error) (test (sin "hi") 'error) (test (sin 1.0+23.0i 1.0+23.0i) 'error) (test (sin 0 1) 'error) (for-each (lambda (arg) (test (sin arg) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) (if with-bignums (letrec ((sin-m*pi/n (lambda (m1 n1) ;; this returns an expression giving the exact value of sin(m*pi/n), m and n integer ;; if we can handle n -- currently it can be anything of the form 2^a 3^b 5^c 7^d 11^h 13^e 17^f 257^g ;; so (sin-m*pi/n 1 60) returns an exact expression for sin(pi/60). (let ((m (numerator (/ m1 n1))) (n (denominator (/ m1 n1)))) (set! m (modulo m (* 2 n))) ;; now it's in lowest terms without extra factors of 2*pi (cond ((zero? m) 0) ((zero? n) (error "divide by zero (sin-m*pi/n n = 0)")) ((= n 1) 0) ((negative? n) (let ((val (sin-m*pi/n m (- n)))) (and val `(- ,val)))) ((> m n) (let ((val (sin-m*pi/n (- m n) n))) (and val `(- ,val)))) ((= n 2) (if (= m 0) 0 1)) ((= n 3) `(sqrt 3/4)) ((> m 1) (let ((m1 (sin-m*pi/n (- m 1) n)) (n1 (sin-m*pi/n 1 n)) (m2 (sin-m*pi/n (- m 2) n))) (and m1 m2 n1 `(- (* 2 ,m1 (sqrt (- 1 (* ,n1 ,n1)))) ,m2)))) ((= n 5) `(/ (sqrt (- 10 (* 2 (sqrt 5)))) 4)) ((= n 7) `(let ((A1 (expt (+ -7/3456 (sqrt -49/442368)) 1/3)) (A2 (expt (- -7/3456 (sqrt -49/442368)) 1/3))) (sqrt (+ 7/12 (* -1/2 (+ A1 A2)) (* 1/2 0+i (sqrt 3) (- A1 A2)))))) ((= n 17) `(let* ((A1 (sqrt (- 17 (sqrt 17)))) (A2 (sqrt (+ 17 (sqrt 17)))) (A3 (sqrt (+ 34 (* 6 (sqrt 17)) (* (sqrt 2) (- (sqrt 17) 1) A1) (* -8 (sqrt 2) A2))))) (* 1/8 (sqrt 2) (sqrt (- 17 (sqrt 17) (* (sqrt 2) (+ A1 A3))))))) ((= n 11) `(let* ((SQRT5 (* 1/2 (- (sqrt 5) 1))) (B5 (sqrt (+ 2 (* 1/2 (+ (sqrt 5) 1))))) (B6 (+ SQRT5 (* 0+i B5))) (B6_2 (* B6 B6)) (B6_3 (* B6 B6 B6)) (B6_4 (* B6 B6 B6 B6)) (D1 (+ 6 (* 3/2 B6) (* 3/4 B6_2))) (D2 (+ SQRT5 (* 0+i B5) (* 1/4 B6_2))) (D3 (* 1/2 (- (+ 1 (* 0+i (sqrt 11)))))) (D4 (* 1/2 (- (* 0+i (sqrt 11)) 1))) (D6 (+ 1 (* 1/4 B6_2) (* 1/8 B6_3))) (D7 (+ (* 1/2 B6) (* 1/16 B6_4))) (D8 (+ 2 (* 1/2 B6))) (D9 (+ 13 (* 21 B6) (* 67/4 B6_2) (* 21/4 B6_3) (* 2 B6_4))) (D11 (+ 129 (* 109/2 B6) (* 59/4 B6_2) (* 9/8 B6_3) (* 9/16 B6_4))) (D13 (+ (* 3 B6) B6_2)) (D14 (+ (* 3 B6) (* 3/4 B6_2) (* 3/8 B6_3))) (D15 (+ 79 (* 27 B6) (* 39/4 B6_2) (* 37/4 B6_3) (* 21/4 B6_4))) (D16 (+ D11 (* D3 D9) (* D4 D15))) (D17 (+ D11 (* D4 D9) (* D3 D15))) (D30 (/ (* B6_2 (+ (* D3 D6) (* D4 D7))) (* 4 (expt D17 1/5)))) (D32 (* 1/2 (+ 1 (* 0+i (sqrt 11))))) (D33 (/ (* B6_3 (+ (* D4 D6) (* D3 D7))) (* 8 (expt D16 1/5)))) (D34 (* 1/4 B6_2 (expt D16 1/5))) (D35 (+ 2 (* 1/8 B6_4) (* 1/2 B6 D8) (* 1/8 B6_3 D2))) (D36 (+ SQRT5 (* 0+i B5) (* 1/2 B6_2) (* 1/4 B6_3) (* 1/2 B6 D2) (* 1/4 B6_2 (+ (* 1/4 B6_3) (* 1/16 B6_4))))) (D38 (* 1/2 (+ -1 (* 0+i (sqrt 11))))) (D39 (* 1/8 B6_3 (expt D17 1/5))) (D40 (+ 3 (* 3/2 B6) (* 9/4 B6_2) (* 7/8 B6_3) (* 3/16 B6_4) (* 1/2 B6 (+ 6 (* 2 B6))) (* 1/16 B6_4 D1) (* 1/4 B6_2 D13) (* 1/8 B6_3 (+ 3 (* 3/4 B6_3) (* 3/16 B6_4))))) (D41 (+ (* 1/4 B6_2 D1) (* 1/8 B6_3 D13) (* 1/16 B6_4 D14) (* 1/2 B6 (+ 4 (* 3/8 B6_4))))) (D42 (+ 3 (* 3/4 B6_3) (* 3/16 B6_4) (* 1/8 B6_3 D1) (* 1/4 B6_2 D14) (* 1/2 B6 (+ (* 3/2 B6_2) (* 3/8 B6_3) (* 3/16 B6_4))) (* 1/16 B6_4 (+ 3 (* 3/2 B6) (* 3/8 B6_4))))) (D43 (+ (* 1/4 B6_3) (* 1/16 B6_4) (* 1/8 B6_3 D8) (* 1/4 B6_2 D2) (* 1/2 B6 (+ (* 1/2 B6_2) (* 1/8 B6_3))) (* 1/16 B6_4 (+ 1 (* 1/8 B6_4))))) (D44 (/ (* B6_4 (+ D42 (* D4 D40) (* D3 D41))) (* 16 (expt D16 3/5)))) (D45 (/ (* B6 (+ D42 (* D3 D40) (* D4 D41))) (* 2 (expt D17 3/5)))) (D48 (/ (* B6 (+ D43 (* D3 D35) (* D4 D36))) (* 2 (expt D16 2/5)))) (D49 (/ (* B6_4 (+ D43 (* D4 D35) (* D3 D36))) (* 16 (expt D17 2/5))))) (* -1/2 0+i (+ (* 1/5 (- D32 D33 D34 D48 D44)) (* 1/5 (+ D38 D30 D39 D49 D45)))))) ((= n 13) `(let* ((A1 (/ (- -1 (sqrt 13)) 2)) (A2 (/ (+ -1 (sqrt 13)) 2)) (A3 (/ (+ -1 (* 0+i (sqrt 3))) 2)) (A4 (+ -1 (* 0+i (sqrt 3)))) (A5 (* 0+i (sqrt (+ 7 (sqrt 13) A2)))) (A6 (* 0+i (sqrt (+ 7 (- (sqrt 13)) A1)))) (A8 (* 1/2 (- A2 A6))) (A9 (* 1/2 (+ A1 A5))) (A11 (* 1/2 (+ A2 A6))) (A12 (* 1/2 (- A1 A5))) (A13 (* 3/2 A4 A8)) (A14 (* 3/2 A4 A11)) (A15 (* 3/4 A4 A4 A11)) (A16 (* 3/4 A4 A4 A8)) (A17 (+ A3 (* 1/4 A4 A4)))) (* -1/6 0+i (+ (- A9 A12) (* A4 (+ (/ (+ A8 (* A17 A12)) (* 2 (expt (+ 6 A13 A15 A9) 1/3))) (/ (+ A11 (* A17 A9)) (* -2 (expt (+ 6 A16 A14 A12) 1/3))) (* 1/4 A4 (- (expt (+ 6 A13 A15 A9) 1/3) (expt (+ 6 A16 A14 A12) 1/3))))))))) ((= n 257) `(let* ((A1 (sqrt (- 514 (* 2 (sqrt 257))))) (A2 (- 257 (* 15 (sqrt 257)))) (A3 (+ 257 (* 15 (sqrt 257)))) (A4 (- 257 (sqrt 257))) (A5 (+ (sqrt 257) 257)) (A7 (+ 257 (* 9 (sqrt 257)))) (A8 (- 514 (* 18 (sqrt 257)))) (AA (sqrt (* 2 A5))) (A9 (sqrt (+ A2 (* 8 A1) (* -7 AA)))) (A10 (sqrt (+ A2 (* -8 A1) (* 7 AA)))) (A11 (sqrt (+ A3 (* 7 A1) (* 8 AA)))) (A12 (sqrt (+ A3 (* -7 A1) (* -8 AA)))) (A13 (sqrt (+ A8 (* 6 A1) (* 8 A9) (* -24 A10) (* 12 A11)))) (A14 (* 4 (sqrt (+ A8 (* 6 A1) (* -8 A9) (* 24 A10) (* -12 A11))))) (A15 (* 4 (sqrt (+ A8 (* -6 A1) (* -12 A12) (* 24 A9) (* 8 A10))))) (A16 (* 4 (sqrt (* 2 (+ (- 257 (* 9 (sqrt 257))) (* -3 A1) (* 6 A12) (* -12 A9) (* -4 A10)))))) (A17 (sqrt (* 2 (+ A7 (* -3 AA) (* -4 A12) (* 6 A9) (* 12 A11))))) (A18 (sqrt (* 2 (+ A7 (* 3 AA) (* 12 A12) (* -6 A10) (* 4 A11))))) (A19 (* 4 (sqrt (* 2 (+ A7 (* 3 AA) (* -12 A12) (* 6 A10) (* -4 A11)))))) (A20 (* 4 (sqrt (* 2 (+ A7 (* -3 AA) (* 4 A12) (* -6 A9) (* -12 A11)))))) (A22 (+ A4 (* 3 A1) (* -4 AA) (* -4 A12) (* 4 A9) (* -4 A10) (* 2 A11))) (A23 (+ A5 (* -4 A1) (* -3 AA) (* -4 A12) (* 2 A9) (* 4 A10) (* 4 A11))) (A24 (+ A5 (* 4 A1) (* 3 AA) (* 4 A12) (* 4 A9) (* -2 A10) (* 4 A11))) (A26 (sqrt (+ A22 (+ (- A16) (- A19) (* 4 A17) (* -6 A13))))) (A27 (sqrt (+ A22 (+ A16 A19 (* -4 A17) (* 6 A13))))) (A28 (+ 257 (* 7 (sqrt 257)) (* 3 A1) (* -4 A9) (* 4 A10) (* 6 A11))) (A29 (* 8 (sqrt (+ A24 A15 (- A20) (* -6 A18) (* -4 A13))))) (A30 (+ A28 (* -4 A18) (* -4 A17) (* -2 A13))) (A31 (+ (* 8 (sqrt (+ A23 A15 A14 (* 4 A18) (* -6 A17)))) (* 4 A26) A29 (* -8 A27)))) (* 1/16 (sqrt (* 1/2 (+ A4 (- A1) (* -2 A11) (* -2 A13) (* -4 A26) (* -4 (sqrt (* 2 (+ A30 (- A31))))) (* -8 (sqrt (+ A4 (- A1) (* -2 A11) (* 6 A13) (* -4 A26) (* -8 A27) (* 4 (sqrt (* 2 (+ A30 A31)))) (* -8 (sqrt (* 2 (+ A28 (* 4 A18) (* 4 A17) (* 2 A13) (* -8 A26) (* -4 A27) (* -8 (sqrt (+ A23 (- A15) (- A14) (* -4 A18) (* 6 A17)))) (* -8 (sqrt (+ A24 (- A15) A20 (* 6 A18) (* 4 A13))))))))))))))))) ((or (= (modulo n 2) 0) (= (modulo n 3) 0) (= (modulo n 5) 0) (= (modulo n 7) 0) (= (modulo n 17) 0) (= (modulo n 13) 0) (= (modulo n 257) 0) (= (modulo n 11) 0)) (let ((divisor (if (= (modulo n 2) 0) 2 (if (= (modulo n 3) 0) 3 (if (= (modulo n 5) 0) 5 (if (= (modulo n 7) 0) 7 (if (= (modulo n 17) 0) 17 (if (= (modulo n 13) 0) 13 (if (= (modulo n 11) 0) 11 257))))))))) (let ((val (sin-m*pi/n 1 (/ n divisor)))) (and val `(let ((ex ,val)) (/ (- (expt (+ (sqrt (- 1 (* ex ex))) (* 0+i ex)) (/ 1 ,divisor)) (expt (- (sqrt (- 1 (* ex ex))) (* 0+i ex)) (/ 1 ,divisor))) 0+2i)))))) (else #f)))))) (let ((maxerr 0.0) (max-case #f) (cases 0)) (do ((n 1 (+ n 1))) ((= n 100)) (do ((m 1 (+ m 1))) ((= m 4)) (letrec ((bigify (lambda (lst) (if (pair? lst) (cons (if (number? (car lst)) (list 'bignum (number->string (car lst))) (bigify (car lst))) (bigify (cdr lst))) lst)))) (let ((val (sin (/ (* m pi) n))) (expr (bigify (sin-m*pi/n m n)))) (if expr (let ((err (magnitude (- val (eval expr))))) (set! cases (+ cases 1)) (if (> err maxerr) (begin (set! max-case (/ m n)) (set! maxerr err))))))))) (if (> maxerr 1e-35) (format-logged #t "sin-m*pi/n (~A cases) max err ~A at ~A~%" cases maxerr max-case)))) ) (let ((sins (list 0.00000000000000000000000000000000000000000000000000000000000000000000 0.09983341664682815230681419841062202698991538801798225999276686156165 0.19866933079506121545941262711838975037020672954020540398639599139797 0.29552020666133957510532074568502737367783211174261844850153103617326 0.38941834230865049166631175679570526459306018344395889511584896585734 0.47942553860420300027328793521557138808180336794060067518861661312553 0.56464247339503535720094544565865790710988808499415177102426589426735 0.64421768723769105367261435139872018306581384457368964474396308809382 0.71735609089952276162717461058138536619278523779142282098968252068287 0.78332690962748338846138231571354862314014792572030960356048515256195 0.84147098480789650665250232163029899962256306079837106567275170999191 0.89120736006143533995180257787170353831890931945282652766035329176720 0.93203908596722634967013443549482599541507058820873073536659789445024 0.96355818541719296470134863003955481534204849131773911795564922309212 0.98544972998846018065947457880609751735626167234736563194021894560084 0.99749498660405443094172337114148732270665142592211582194997482405934 0.99957360304150516434211382554623417197949791475491995534260751586102 0.99166481045246861534613339864787565240681957116712372532710249102330 0.97384763087819518653237317884335760670293947136523395566725825917196 0.94630008768741448848970961163495776211399866559491176443047155279581 0.90929742682568169539601986591174484270225497144789026837897301153096 0.86320936664887377068075931326902458492047242489508107697183045949721 0.80849640381959018430403691041611906515855960597557707903336060873485 0.74570521217672017738540621164349953894264877802047425750762828050000 0.67546318055115092656577152534128337425336495789352584226890212866520 0.59847214410395649405185470218616227170359717157722357330262703263874 0.51550137182146423525772693520936824389387858775426312126259173008382 0.42737988023382993455605308585788064749647642266670256499017776070511 0.33498815015590491954385375271242210603030652888358671068410107309479 0.23924932921398232818425691873957537221555293029961877411621026588071 0.14112000805986722210074480280811027984693326425226558415188264123242 0.04158066243329057919469827159667310055461342296380675064800900076588 -0.05837414342757990913721741461909518512512509908292656970935025422273))) (let ((mxerr 0.0)) (do ((i 0 (+ i 1)) (x 0.0 (+ x 0.1))) ((= i 32)) (let ((err (abs (- (sin x) (list-ref sins i))))) (if (> err mxerr) (set! mxerr err)))) (if (> mxerr 1e-12) (format-logged #t "sin err: ~A~%" mxerr)))) (if with-bignums (let ((old-prec (*s7* 'bignum-precision))) (set! (*s7* 'bignum-precision) 500) (let ((sin-vals (list ;arprec mathtool table[Sin[k/10], {k, 0, 30}] "0.00000000000000000000000000000000000000000000000000000000000000000000" "0.09983341664682815230681419841062202698991538801798225999276686156165" "0.19866933079506121545941262711838975037020672954020540398639599139797" "0.29552020666133957510532074568502737367783211174261844850153103617326" "0.38941834230865049166631175679570526459306018344395889511584896585734" "0.47942553860420300027328793521557138808180336794060067518861661312553" "0.56464247339503535720094544565865790710988808499415177102426589426735" "0.64421768723769105367261435139872018306581384457368964474396308809382" "0.71735609089952276162717461058138536619278523779142282098968252068287" "0.78332690962748338846138231571354862314014792572030960356048515256195" "0.84147098480789650665250232163029899962256306079837106567275170999191" "0.89120736006143533995180257787170353831890931945282652766035329176720" "0.93203908596722634967013443549482599541507058820873073536659789445024" "0.96355818541719296470134863003955481534204849131773911795564922309212" "0.98544972998846018065947457880609751735626167234736563194021894560084" "0.99749498660405443094172337114148732270665142592211582194997482405934" "0.99957360304150516434211382554623417197949791475491995534260751586102" "0.99166481045246861534613339864787565240681957116712372532710249102330" "0.97384763087819518653237317884335760670293947136523395566725825917196" "0.94630008768741448848970961163495776211399866559491176443047155279581" "0.90929742682568169539601986591174484270225497144789026837897301153096" "0.86320936664887377068075931326902458492047242489508107697183045949721" "0.80849640381959018430403691041611906515855960597557707903336060873485" "0.74570521217672017738540621164349953894264877802047425750762828050000" "0.67546318055115092656577152534128337425336495789352584226890212866520" "0.59847214410395649405185470218616227170359717157722357330262703263874" "0.51550137182146423525772693520936824389387858775426312126259173008382" "0.42737988023382993455605308585788064749647642266670256499017776070511" "0.33498815015590491954385375271242210603030652888358671068410107309479" "0.23924932921398232818425691873957537221555293029961877411621026588071" "0.14112000805986722210074480280811027984693326425226558415188264123242"))) (do ((k 2 (+ k 1))) ((= k 30)) (let ((sin-val-2 (number->string (sin (/ k (bignum "10")))))) (if (not (string=? (substring (list-ref sin-vals k) 3 60) (substring sin-val-2 2 59))) (format-logged #t ";(sin (/ ~A 10)) mp: ~A does not match~%~A~%" k (substring (list-ref sin-vals k) 3 60) (substring sin-val-2 2 59)))))) (let ((sin-vals (list ;arprec mathtool table[Sin[k/10], {k, 0, 30}] 0.00000000000000000000000000000000000000000000000000000000000000000000 0.09983341664682815230681419841062202698991538801798225999276686156165 0.19866933079506121545941262711838975037020672954020540398639599139797 0.29552020666133957510532074568502737367783211174261844850153103617326 0.38941834230865049166631175679570526459306018344395889511584896585734 0.47942553860420300027328793521557138808180336794060067518861661312553 0.56464247339503535720094544565865790710988808499415177102426589426735 0.64421768723769105367261435139872018306581384457368964474396308809382 0.71735609089952276162717461058138536619278523779142282098968252068287 0.78332690962748338846138231571354862314014792572030960356048515256195 0.84147098480789650665250232163029899962256306079837106567275170999191 0.89120736006143533995180257787170353831890931945282652766035329176720 0.93203908596722634967013443549482599541507058820873073536659789445024 0.96355818541719296470134863003955481534204849131773911795564922309212 0.98544972998846018065947457880609751735626167234736563194021894560084 0.99749498660405443094172337114148732270665142592211582194997482405934 0.99957360304150516434211382554623417197949791475491995534260751586102 0.99166481045246861534613339864787565240681957116712372532710249102330 0.97384763087819518653237317884335760670293947136523395566725825917196 0.94630008768741448848970961163495776211399866559491176443047155279581 0.90929742682568169539601986591174484270225497144789026837897301153096 0.86320936664887377068075931326902458492047242489508107697183045949721 0.80849640381959018430403691041611906515855960597557707903336060873485 0.74570521217672017738540621164349953894264877802047425750762828050000 0.67546318055115092656577152534128337425336495789352584226890212866520 0.59847214410395649405185470218616227170359717157722357330262703263874 0.51550137182146423525772693520936824389387858775426312126259173008382 0.42737988023382993455605308585788064749647642266670256499017776070511 0.33498815015590491954385375271242210603030652888358671068410107309479 0.23924932921398232818425691873957537221555293029961877411621026588071 0.14112000805986722210074480280811027984693326425226558415188264123242)) (mxerr 0.0)) (do ((x 0 (+ x 1))) ((= x 20)) (let ((phase (* 2 pi (expt 10 x)))) (do ((k 0 (+ k 1))) ((= k 30)) (let ((sin-val-2 (sin (+ phase (/ k (bignum "10")))))) (let ((err (magnitude (- sin-val-2 (list-ref sin-vals k))))) (if (> err mxerr) (set! mxerr err))))))) (if (> mxerr 1e-35) (format-logged #t ";(sin big-angle) max error: ~A" mxerr))) (set! (*s7* 'bignum-precision) old-prec))) ;;; -------------------------------------------------------------------------------- ;;; cos ;;; -------------------------------------------------------------------------------- (num-test (cos 0) 1.0) (num-test (cos 1) 0.54030230586814) (num-test (cos 2) -0.41614683654714) (num-test (cos 3) -0.98999249660045) (num-test (cos 0/1) 1.0) (num-test (cos 0/2) 1.0) (num-test (cos 0/3) 1.0) (num-test (cos 0/10) 1.0) (num-test (cos 0/1234) 1.0) (num-test (cos 0/1234000000) 1.0) (num-test (cos 0/500029) 1.0) (num-test (cos 0/362880) 1.0) (num-test (cos 1/1) 0.54030230586814) (num-test (cos 1/2) 0.87758256189037) (num-test (cos -1/2) 0.87758256189037) (num-test (cos 1/3) 0.94495694631474) (num-test (cos -1/3) 0.94495694631474) (num-test (cos 1/10) 0.99500416527803) (num-test (cos -1/10) 0.99500416527803) (num-test (cos 1/1234) 0.99999967164800) (num-test (cos -1/1234) 0.99999967164800) (num-test (cos 1/1234000000) 1.0) (num-test (cos -1/1234000000) 1.0) (num-test (cos 1/500029) 0.99999999999800) (num-test (cos -1/500029) 0.99999999999800) (num-test (cos 1/362880) 0.99999999999620) (num-test (cos -1/362880) 0.99999999999620) (num-test (cos 2/1) -0.41614683654714) (num-test (cos 2/2) 0.54030230586814) (num-test (cos 2/3) 0.78588726077695) (num-test (cos 2/10) 0.98006657784124) (num-test (cos -2/10) 0.98006657784124) (num-test (cos 2/1234) 0.99999868659223) (num-test (cos -2/1234) 0.99999868659223) (num-test (cos 2/1234000000) 1.0) (num-test (cos -2/1234000000) 1.0) (num-test (cos 2/500029) 0.99999999999200) (num-test (cos -2/500029) 0.99999999999200) (num-test (cos 2/362880) 0.99999999998481) (num-test (cos -2/362880) 0.99999999998481) (num-test (cos 3/1) -0.98999249660045) (num-test (cos 3/2) 0.07073720166770) (num-test (cos 3/3) 0.54030230586814) (num-test (cos 3/10) 0.95533648912561) (num-test (cos -3/10) 0.95533648912561) (num-test (cos 3/1234) 0.99999704483333) (num-test (cos -3/1234) 0.99999704483333) (num-test (cos 3/1234000000) 1.0) (num-test (cos -3/1234000000) 1.0) (num-test (cos 3/500029) 0.99999999998200) (num-test (cos -3/500029) 0.99999999998200) (num-test (cos 3/362880) 0.99999999996583) (num-test (cos -3/362880) 0.99999999996583) (num-test (cos 10/3) -0.98167400471108) (num-test (cos 10/10) 0.54030230586814) (num-test (cos 10/1234) 0.99996716497825) (num-test (cos -10/1234) 0.99996716497825) (num-test (cos 10/1234000000) 1.0) (num-test (cos -10/1234000000) 1.0) (num-test (cos 10/500029) 0.99999999980002) (num-test (cos -10/500029) 0.99999999980002) (num-test (cos 10/362880) 0.99999999962030) (num-test (cos -10/362880) 0.99999999962030) (num-test (cos 1234/1234) 0.54030230586814) (num-test (cos 1234/1234000000) 0.99999999999950) (num-test (cos -1234/1234000000) 0.99999999999950) (num-test (cos 1234/500029) 0.99999695484279) (num-test (cos -1234/500029) 0.99999695484279) (num-test (cos 1234/362880) 0.99999421805655) (num-test (cos -1234/362880) 0.99999421805655) (num-test (cos 1234000000/1234000000) 0.54030230586814) (num-test (cos 500029/1234000000) 0.99999991790247) (num-test (cos -500029/1234000000) 0.99999991790247) (num-test (cos 500029/500029) 0.54030230586814) (num-test (cos 500029/362880) 0.19165727729458) (num-test (cos 362880/1234000000) 0.99999995676199) (num-test (cos -362880/1234000000) 0.99999995676199) (num-test (cos 362880/500029) 0.74802315864263) (num-test (cos 362880/362880) 0.54030230586814) (num-test (cos 0.0) 1.0) (num-test (cos 0.00000001) 1.0) (num-test (cos -0.00000001) 1.0) (num-test (cos 1.0) 0.54030230586814) (num-test (cos pi) -1.0) (num-test (cos 2.71828182845905) -0.91173391478697) (num-test (cos 0.0+0.0i) 1.0) (num-test (cos -0.0+0.0i) 1.0) (num-test (cos 0.0-0.0i) 1.0) (num-test (cos -0.0-0.0i) 1.0) (num-test (cos 0.0+0.00000001i) 1.0) (num-test (cos -0.0+0.00000001i) 1.0) (num-test (cos 0.0-0.00000001i) 1.0) (num-test (cos -0.0-0.00000001i) 1.0) (num-test (cos 0.0+1.0i) 1.54308063481524) (num-test (cos -0.0+1.0i) 1.54308063481524) (num-test (cos 0.0-1.0i) 1.54308063481524) (num-test (cos 0.0+3.14159265358979i) 11.59195327552152) (num-test (cos -0.0+3.14159265358979i) 11.59195327552152) (num-test (cos 0.0-3.14159265358979i) 11.59195327552152) (num-test (cos 0.0+2.71828182845905i) 7.61012513866229) (num-test (cos -0.0+2.71828182845905i) 7.61012513866229) (num-test (cos 0.0-2.71828182845905i) 7.61012513866229) (num-test (cos 0.00000001+0.0i) 1.0) (num-test (cos -0.00000001+0.0i) 1.0) (num-test (cos 0.00000001-0.0i) 1.0) (num-test (cos -0.00000001-0.0i) 1.0) (num-test (cos 0.00000001+0.00000001i) 1.0-1e-16i) ; maxima (num-test (cos -0.00000001+0.00000001i) 1.0+1e-16i) (num-test (cos 0.00000001-0.00000001i) 1.0+1e-16i) (num-test (cos -0.00000001-0.00000001i) 1.0-1e-16i) (num-test (cos 0.00000001+1.0i) 1.54308063481524-0.00000001175201i) (num-test (cos 0.00000001-1.0i) 1.54308063481524+0.00000001175201i) (num-test (cos 0.00000001+3.14159265358979i) 11.59195327552152-0.00000011548739i) (num-test (cos 0.00000001-3.14159265358979i) 11.59195327552152+0.00000011548739i) (num-test (cos 0.00000001+2.71828182845905i) 7.61012513866229-0.00000007544137i) (num-test (cos 0.00000001-2.71828182845905i) 7.61012513866229+0.00000007544137i) (num-test (cos 1.0+0.0i) 0.54030230586814) (num-test (cos 1.0-0.0i) 0.54030230586814) (num-test (cos 1.0+0.00000001i) 0.54030230586814-0.00000000841471i) (num-test (cos 1.0-0.00000001i) 0.54030230586814+0.00000000841471i) (num-test (cos 1.0+1.0i) 0.83373002513115-0.98889770576287i) (num-test (cos 1.0-1.0i) 0.83373002513115+0.98889770576287i) (num-test (cos 1.0+3.14159265358979i) 6.26315908428001-9.71792908024139i) (num-test (cos 1.0-3.14159265358979i) 6.26315908428001+9.71792908024139i) (num-test (cos 1.0+2.71828182845905i) 4.11176816036433-6.34817247743319i) (num-test (cos 1.0-2.71828182845905i) 4.11176816036433+6.34817247743319i) (num-test (cos 3.14159265358979+0.0i) -1.0) (num-test (cos 3.14159265358979-0.0i) -1.0) (num-test (cos 3.14159265358979+0.00000001i) -1.0-3.23121723694911E-23i) ; maxima (num-test (cos 3.14159265358979-0.00000001i) -1.0+3.23121723694911E-23i) ; maxima (num-test (cos 3.14159265358979+1.0i) -1.54308063481524) (num-test (cos 3.14159265358979-1.0i) -1.54308063481524) (num-test (cos 3.14159265358979+3.14159265358979i) -11.5919532755216+8.064357485351393E-14i) ; maxima (num-test (cos 3.14159265358979-3.14159265358979i) -11.59195327552152+3.73164856762037E-14i) (num-test (cos 3.14159265358979+2.71828182845905i) -7.61012513866229-2.437674584452965E-14i) (num-test (cos 3.14159265358979-2.71828182845905i) -7.61012513866229+2.437674584452965E-14i) (num-test (cos 2.71828182845905+0.0i) -0.91173391478697) (num-test (cos 2.71828182845905-0.0i) -0.91173391478697) (num-test (cos 2.71828182845905+0.00000001i) -0.91173391478697-0.00000000410781i) (num-test (cos 2.71828182845905-0.00000001i) -0.91173391478697+0.00000000410781i) (num-test (cos 2.71828182845905+1.0i) -1.40687894801206-0.48275066292556i) (num-test (cos 2.71828182845905-1.0i) -1.40687894801206+0.48275066292556i) (num-test (cos 2.71828182835905+3.14159265358979i) -10.56877693991882-4.74400605685607i) (num-test (cos 2.71828182845905-3.14159265358979i) -10.56877693991882+4.74400605685607i) (num-test (cos 2.71828182845905+2.71828182845905i) -6.93840918469126-3.09899037482603i) (num-test (cos 2.71828182845905-2.71828182845905i) -6.93840918469126+3.09899037482603i) (num-test (cos -2/3) .7858872607769459) (num-test (cos -3/2) 0.0707372016677029) (num-test (cos -10/3) -0.9816740047110853) (num-test (cos 1234/3) -0.9769114301438807) (num-test (cos 1234/10) -0.6387786688749486) (num-test (cos 1234000000/3) -5.317013319482049e-2) (num-test (cos 1234000000/500029) .1354175745756898) (num-test (cos 1234000000/362880) .1995074806029773) (num-test (cos 500029/2) 0.962847094896035) (num-test (cos 500029/3) -0.6487140328750399) (num-test (cos 500029/10) .2565691622107056) (num-test (cos 500029/1234) -0.9984566200318916) (num-test (cos -500029/362880) .1916572772946199) (num-test (cos 362880/1234) .3232465372699541) (num-test (cos -362880/500029) .7480231586426291) (num-test (cos -3.14159265358979) -1.0) (num-test (cos -2.71828182845905) -0.9117339147869464) (num-test (cos 0.0+3.14159265358979i) 11.5919532755216) (num-test (cos 0.0+2.71828182845905i) 7.610125138661946) (num-test (cos 0.00000001+1.0i) 1.543080634815244-1.1752011936438014E-8i) (num-test (cos 0.00000001+3.14159265358979i) 11.5919532755216-1.154873935725783E-7i) (num-test (cos 0.00000001+2.71828182845905i) 7.610125138661945-7.54413710281663E-8i) (num-test (cos 1.0+0.00000001i) .5403023058681398-8.414709848078964E-9i) (num-test (cos 1.0+3.14159265358979i) 6.263159084280057-9.71792908024146i) (num-test (cos 1.0+2.71828182845905i) 4.111768160364146-6.348172477432901i) (num-test (cos 3.14159265358979+0.0i) -1.0) (num-test (cos 3.14159265358979+0.00000001i) -1.0+6.982889851335445E-23i) (num-test (cos 3.14159265358979+1.0i) -1.543080634815244+8.206300488372603E-15i) (num-test (cos 3.14159265358979+3.14159265358979i) -11.5919532755216+8.064357485351393E-14i) (num-test (cos 3.14159265358979+2.71828182845905i) -7.610125138661946+5.267987841234144E-14i) (num-test (cos 2.71828182845905+0.0i) -0.9117339147869464) (num-test (cos 2.71828182845905+0.00000001i) -0.9117339147869464-4.1078129050295015E-9i) (num-test (cos 2.71828182845905+1.0i) -1.406878948012029-0.4827506629256081i) (num-test (cos 2.71828182845905+3.14159265358979i) -10.56877693991868-4.744006056856582i) (num-test (cos 2.71828182845905+2.71828182845905i) -6.93840918469081-3.098990374826203i) (num-test (cos 1234.0+0.00000001i) -0.7985506235875843-6.019276547624973E-9i) (num-test (cos 1234.0+3.14159265358979i) -9.256761516765916-6.951505596777556i) (num-test (cos 1234.0+2.71828182845905i) -6.077070175058048-4.541024753505155i) (num-test (cos 1234000000.0+0.00000001i) +0.1589091308902228+9.872932128398908E-9i) (num-test (cos 1234000000.0+3.14159265358979i) +1.84206722033321+11.40199198427758i) (num-test (cos 1234000000.0+2.71828182845905i) +1.209318371750606+7.448275358344457i) (num-test (cos 1234.0+12.0i) -64983.97009220963-48983.30494825104i) (num-test (cos -3.45266983001243932001e-04+0.0e+00i) 9.9999994039535581673e-1) (num-test (cos 3.45266983001243932001e-04+0.0e+00i) 9.9999994039535581673e-1) (num-test (cos -3.45266983001243932001e-04+1.19209289550781250e-07i) 9.9999994039536292216e-1+4.1159030931163569191e-11i) (num-test (cos -3.45266983001243932001e-04-1.19209289550781250e-07i) 9.9999994039536292216e-1-4.1159030931163569191e-11i) (num-test (cos 3.45266983001243932001e-04+1.19209289550781250e-07i) 9.9999994039536292216e-1-4.1159030931163569191e-11i) (num-test (cos 3.45266983001243932001e-04-1.19209289550781250e-07i) 9.9999994039536292216e-1+4.1159030931163569191e-11i) (num-test (cos -3.45266983001243932001e-04+5.0e-01i) 1.1276258979946363573e0+1.7991700040930800151e-4i) (num-test (cos -3.45266983001243932001e-04-5.0e-01i) 1.1276258979946363573e0-1.7991700040930800151e-4i) (num-test (cos 3.45266983001243932001e-04+5.0e-01i) 1.1276258979946363573e0-1.7991700040930800151e-4i) (num-test (cos 3.45266983001243932001e-04-5.0e-01i) 1.1276258979946363573e0+1.7991700040930800151e-4i) (num-test (cos -3.45266983001243932001e-04+1.0e+00i) 1.5430805428404715942e0+4.057581624871654840e-4i) (num-test (cos -3.45266983001243932001e-04-1.0e+00i) 1.5430805428404715942e0-4.057581624871654840e-4i) (num-test (cos 3.45266983001243932001e-04+1.0e+00i) 1.5430805428404715942e0-4.057581624871654840e-4i) (num-test (cos 3.45266983001243932001e-04-1.0e+00i) 1.5430805428404715942e0+4.057581624871654840e-4i) (num-test (cos -3.45266983001243932001e-04+2.0e+00i) 3.7621954668392959447e0+1.2522351259043242989e-3i) (num-test (cos -3.45266983001243932001e-04-2.0e+00i) 3.7621954668392959447e0-1.2522351259043242989e-3i) (num-test (cos 3.45266983001243932001e-04+2.0e+00i) 3.7621954668392959447e0-1.2522351259043242989e-3i) (num-test (cos 3.45266983001243932001e-04-2.0e+00i) 3.7621954668392959447e0+1.2522351259043242989e-3i) (num-test (cos 1.57045105981189525579e+00+0.0e+00i) 3.4526697614152485627e-4) (num-test (cos -1.57045105981189525579e+00+0.0e+00i) 3.4526697614152485627e-4) (num-test (cos 1.57045105981189525579e+00+1.19209289550781250e-07i) 3.4526697614152730954e-4-1.1920928244535424532e-7i) (num-test (cos 1.57045105981189525579e+00-1.19209289550781250e-07i) 3.4526697614152730954e-4+1.1920928244535424532e-7i) (num-test (cos -1.57045105981189525579e+00+1.19209289550781250e-07i) 3.4526697614152730954e-4+1.1920928244535424532e-7i) (num-test (cos -1.57045105981189525579e+00-1.19209289550781250e-07i) 3.4526697614152730954e-4-1.1920928244535424532e-7i) (num-test (cos 1.57045105981189525579e+00+5.0e-01i) 3.8933200722547541227e-4-5.2109527443404709207e-1i) (num-test (cos 1.57045105981189525579e+00-5.0e-01i) 3.8933200722547541227e-4+5.2109527443404709207e-1i) (num-test (cos -1.57045105981189525579e+00+5.0e-01i) 3.8933200722547541227e-4+5.2109527443404709207e-1i) (num-test (cos -1.57045105981189525579e+00-5.0e-01i) 3.8933200722547541227e-4-5.2109527443404709207e-1i) (num-test (cos 1.57045105981189525579e+00+1.0e+00i) 5.3277478472520380315e-4-1.1752011235963524659e0i) (num-test (cos 1.57045105981189525579e+00-1.0e+00i) 5.3277478472520380315e-4+1.1752011235963524659e0i) (num-test (cos -1.57045105981189525579e+00+1.0e+00i) 5.3277478472520380315e-4+1.1752011235963524659e0i) (num-test (cos -1.57045105981189525579e+00-1.0e+00i) 5.3277478472520380315e-4-1.1752011235963524659e0i) (num-test (cos 1.57045105981189525579e+00+2.0e+00i) 1.2989619299131198016e-3-3.6268601916692946554e0i) (num-test (cos 1.57045105981189525579e+00-2.0e+00i) 1.2989619299131198016e-3+3.6268601916692946554e0i) (num-test (cos -1.57045105981189525579e+00+2.0e+00i) 1.2989619299131198016e-3+3.6268601916692946554e0i) (num-test (cos -1.57045105981189525579e+00-2.0e+00i) 1.2989619299131198016e-3-3.6268601916692946554e0i) (num-test (cos 1.57114159377789786021e+00+0.0e+00i) -3.4526697614140239160e-4) (num-test (cos -1.57114159377789786021e+00+0.0e+00i) -3.4526697614140239160e-4) (num-test (cos 1.57114159377789786021e+00+1.19209289550781250e-07i) -3.4526697614140484486e-4-1.1920928244535424533e-7i) (num-test (cos 1.57114159377789786021e+00-1.19209289550781250e-07i) -3.4526697614140484486e-4+1.1920928244535424533e-7i) (num-test (cos -1.57114159377789786021e+00+1.19209289550781250e-07i) -3.4526697614140484486e-4+1.1920928244535424533e-7i) (num-test (cos -1.57114159377789786021e+00-1.19209289550781250e-07i) -3.4526697614140484486e-4-1.1920928244535424533e-7i) (num-test (cos 1.57114159377789786021e+00+5.0e-01i) -3.8933200722533731792e-4-5.2109527443404709209e-1i) (num-test (cos 1.57114159377789786021e+00-5.0e-01i) -3.8933200722533731792e-4+5.2109527443404709209e-1i) (num-test (cos -1.57114159377789786021e+00+5.0e-01i) -3.8933200722533731792e-4+5.2109527443404709209e-1i) (num-test (cos -1.57114159377789786021e+00-5.0e-01i) -3.8933200722533731792e-4-5.2109527443404709209e-1i) (num-test (cos 1.57114159377789786021e+00+1.0e+00i) -5.3277478472501483029e-4-1.1752011235963524660e0i) (num-test (cos 1.57114159377789786021e+00-1.0e+00i) -5.3277478472501483029e-4+1.1752011235963524660e0i) (num-test (cos -1.57114159377789786021e+00+1.0e+00i) -5.3277478472501483029e-4+1.1752011235963524660e0i) (num-test (cos -1.57114159377789786021e+00-1.0e+00i) -5.3277478472501483029e-4-1.1752011235963524660e0i) (num-test (cos 1.57114159377789786021e+00+2.0e+00i) -1.2989619299126590655e-3-3.6268601916692946556e0i) (num-test (cos 1.57114159377789786021e+00-2.0e+00i) -1.2989619299126590655e-3+3.6268601916692946556e0i) (num-test (cos -1.57114159377789786021e+00+2.0e+00i) -1.2989619299126590655e-3+3.6268601916692946556e0i) (num-test (cos -1.57114159377789786021e+00-2.0e+00i) -1.2989619299126590655e-3-3.6268601916692946556e0i) (num-test (cos 3.14124738660679181379e+00+0.0e+00i) -9.9999994039535581667e-1) (num-test (cos -3.14124738660679181379e+00+0.0e+00i) -9.9999994039535581667e-1) (num-test (cos 3.14124738660679181379e+00+1.19209289550781250e-07i) -9.9999994039536292209e-1-4.1159030931185115142e-11i) (num-test (cos 3.14124738660679181379e+00-1.19209289550781250e-07i) -9.9999994039536292209e-1+4.1159030931185115142e-11i) (num-test (cos -3.14124738660679181379e+00+1.19209289550781250e-07i) -9.9999994039536292209e-1+4.1159030931185115142e-11i) (num-test (cos -3.14124738660679181379e+00-1.19209289550781250e-07i) -9.9999994039536292209e-1-4.1159030931185115142e-11i) (num-test (cos 3.14124738660679181379e+00+5.0e-01i) -1.1276258979946363572e0-1.7991700040940218455e-4i) (num-test (cos 3.14124738660679181379e+00-5.0e-01i) -1.1276258979946363572e0+1.7991700040940218455e-4i) (num-test (cos -3.14124738660679181379e+00+5.0e-01i) -1.1276258979946363572e0+1.7991700040940218455e-4i) (num-test (cos -3.14124738660679181379e+00-5.0e-01i) -1.1276258979946363572e0-1.7991700040940218455e-4i) (num-test (cos 3.14124738660679181379e+00+1.0e+00i) -1.5430805428404715941e0-4.0575816248737789049e-4i) (num-test (cos 3.14124738660679181379e+00-1.0e+00i) -1.5430805428404715941e0+4.0575816248737789049e-4i) (num-test (cos -3.14124738660679181379e+00+1.0e+00i) -1.5430805428404715941e0+4.0575816248737789049e-4i) (num-test (cos -3.14124738660679181379e+00-1.0e+00i) -1.5430805428404715941e0-4.0575816248737789049e-4i) (num-test (cos 3.14124738660679181379e+00+2.0e+00i) -3.7621954668392959444e0-1.2522351259049798196e-3i) (num-test (cos 3.14124738660679181379e+00-2.0e+00i) -3.7621954668392959444e0+1.2522351259049798196e-3i) (num-test (cos -3.14124738660679181379e+00+2.0e+00i) -3.7621954668392959444e0+1.2522351259049798196e-3i) (num-test (cos -3.14124738660679181379e+00-2.0e+00i) -3.7621954668392959444e0-1.2522351259049798196e-3i) (num-test (cos 3.14193792057279441821e+00+0.0e+00i) -9.9999994039535581675e-1) (num-test (cos -3.14193792057279441821e+00+0.0e+00i) -9.9999994039535581675e-1) (num-test (cos 3.14193792057279441821e+00+1.19209289550781250e-07i) -9.9999994039536292218e-1+4.1159030931155917289e-11i) (num-test (cos 3.14193792057279441821e+00-1.19209289550781250e-07i) -9.9999994039536292218e-1-4.1159030931155917289e-11i) (num-test (cos -3.14193792057279441821e+00+1.19209289550781250e-07i) -9.9999994039536292218e-1-4.1159030931155917289e-11i) (num-test (cos -3.14193792057279441821e+00-1.19209289550781250e-07i) -9.9999994039536292218e-1+4.1159030931155917289e-11i) (num-test (cos 3.14193792057279441821e+00+5.0e-01i) -1.1276258979946363573e0+1.7991700040927455302e-4i) (num-test (cos 3.14193792057279441821e+00-5.0e-01i) -1.1276258979946363573e0-1.7991700040927455302e-4i) (num-test (cos -3.14193792057279441821e+00+5.0e-01i) -1.1276258979946363573e0-1.7991700040927455302e-4i) (num-test (cos -3.14193792057279441821e+00-5.0e-01i) -1.1276258979946363573e0+1.7991700040927455302e-4i) (num-test (cos 3.14193792057279441821e+00+1.0e+00i) -1.5430805428404715943e0+4.0575816248709004923e-4i) (num-test (cos 3.14193792057279441821e+00-1.0e+00i) -1.5430805428404715943e0-4.0575816248709004923e-4i) (num-test (cos -3.14193792057279441821e+00+1.0e+00i) -1.5430805428404715943e0-4.0575816248709004923e-4i) (num-test (cos -3.14193792057279441821e+00-1.0e+00i) -1.5430805428404715943e0+4.0575816248709004923e-4i) (num-test (cos 3.14193792057279441821e+00+2.0e+00i) -3.7621954668392959448e0+1.2522351259040914950e-3i) (num-test (cos 3.14193792057279441821e+00-2.0e+00i) -3.7621954668392959448e0-1.2522351259040914950e-3i) (num-test (cos -3.14193792057279441821e+00+2.0e+00i) -3.7621954668392959448e0-1.2522351259040914950e-3i) (num-test (cos -3.14193792057279441821e+00-2.0e+00i) -3.7621954668392959448e0+1.2522351259040914950e-3i) (num-test (cos 4.71204371340168837179e+00+0.0e+00i) -3.4526697614164732094e-4) (num-test (cos -4.71204371340168837179e+00+0.0e+00i) -3.4526697614164732094e-4) (num-test (cos 4.71204371340168837179e+00+1.19209289550781250e-07i) -3.4526697614164977421e-4+1.1920928244535424532e-7i) (num-test (cos 4.71204371340168837179e+00-1.19209289550781250e-07i) -3.4526697614164977421e-4-1.1920928244535424532e-7i) (num-test (cos -4.71204371340168837179e+00+1.19209289550781250e-07i) -3.4526697614164977421e-4-1.1920928244535424532e-7i) (num-test (cos -4.71204371340168837179e+00-1.19209289550781250e-07i) -3.4526697614164977421e-4+1.1920928244535424532e-7i) (num-test (cos 4.71204371340168837179e+00+5.0e-01i) -3.8933200722561350661e-4+5.2109527443404709205e-1i) (num-test (cos 4.71204371340168837179e+00-5.0e-01i) -3.8933200722561350661e-4-5.2109527443404709205e-1i) (num-test (cos -4.71204371340168837179e+00+5.0e-01i) -3.8933200722561350661e-4-5.2109527443404709205e-1i) (num-test (cos -4.71204371340168837179e+00-5.0e-01i) -3.8933200722561350661e-4+5.2109527443404709205e-1i) (num-test (cos 4.71204371340168837179e+00+1.0e+00i) -5.3277478472539277601e-4+1.1752011235963524659e0i) (num-test (cos 4.71204371340168837179e+00-1.0e+00i) -5.3277478472539277601e-4-1.1752011235963524659e0i) (num-test (cos -4.71204371340168837179e+00+1.0e+00i) -5.3277478472539277601e-4-1.1752011235963524659e0i) (num-test (cos -4.71204371340168837179e+00-1.0e+00i) -5.3277478472539277601e-4+1.1752011235963524659e0i) (num-test (cos 4.71204371340168837179e+00+2.0e+00i) -1.2989619299135805376e-3+3.6268601916692946552e0i) (num-test (cos 4.71204371340168837179e+00-2.0e+00i) -1.2989619299135805376e-3-3.6268601916692946552e0i) (num-test (cos -4.71204371340168837179e+00+2.0e+00i) -1.2989619299135805376e-3-3.6268601916692946552e0i) (num-test (cos -4.71204371340168837179e+00-2.0e+00i) -1.2989619299135805376e-3+3.6268601916692946552e0i) (num-test (cos 4.71273424736769097620e+00+0.0e+00i) 3.4526697614127992692e-4) (num-test (cos -4.71273424736769097620e+00+0.0e+00i) 3.4526697614127992692e-4) (num-test (cos 4.71273424736769097620e+00+1.19209289550781250e-07i) 3.4526697614128238019e-4+1.1920928244535424533e-7i) (num-test (cos 4.71273424736769097620e+00-1.19209289550781250e-07i) 3.4526697614128238019e-4-1.1920928244535424533e-7i) (num-test (cos -4.71273424736769097620e+00+1.19209289550781250e-07i) 3.4526697614128238019e-4-1.1920928244535424533e-7i) (num-test (cos -4.71273424736769097620e+00-1.19209289550781250e-07i) 3.4526697614128238019e-4+1.1920928244535424533e-7i) (num-test (cos 4.71273424736769097620e+00+5.0e-01i) 3.8933200722519922358e-4+5.2109527443404709212e-1i) (num-test (cos 4.71273424736769097620e+00-5.0e-01i) 3.8933200722519922358e-4-5.2109527443404709212e-1i) (num-test (cos -4.71273424736769097620e+00+5.0e-01i) 3.8933200722519922358e-4-5.2109527443404709212e-1i) (num-test (cos -4.71273424736769097620e+00-5.0e-01i) 3.8933200722519922358e-4+5.2109527443404709212e-1i) (num-test (cos 4.71273424736769097620e+00+1.0e+00i) 5.3277478472482585742e-4+1.1752011235963524660e0i) (num-test (cos 4.71273424736769097620e+00-1.0e+00i) 5.3277478472482585742e-4-1.1752011235963524660e0i) (num-test (cos -4.71273424736769097620e+00+1.0e+00i) 5.3277478472482585742e-4-1.1752011235963524660e0i) (num-test (cos -4.71273424736769097620e+00-1.0e+00i) 5.3277478472482585742e-4+1.1752011235963524660e0i) (num-test (cos 4.71273424736769097620e+00+2.0e+00i) 1.2989619299121983294e-3+3.6268601916692946557e0i) (num-test (cos 4.71273424736769097620e+00-2.0e+00i) 1.2989619299121983294e-3-3.6268601916692946557e0i) (num-test (cos -4.71273424736769097620e+00+2.0e+00i) 1.2989619299121983294e-3-3.6268601916692946557e0i) (num-test (cos -4.71273424736769097620e+00-2.0e+00i) 1.2989619299121983294e-3+3.6268601916692946557e0i) (num-test (cos 6.28284004019658492979e+00+0.0e+00i) 9.9999994039535581662e-1) (num-test (cos -6.28284004019658492979e+00+0.0e+00i) 9.9999994039535581662e-1) (num-test (cos 6.28284004019658492979e+00+1.19209289550781250e-07i) 9.9999994039536292205e-1+4.1159030931199714069e-11i) (num-test (cos 6.28284004019658492979e+00-1.19209289550781250e-07i) 9.9999994039536292205e-1-4.1159030931199714069e-11i) (num-test (cos -6.28284004019658492979e+00+1.19209289550781250e-07i) 9.9999994039536292205e-1-4.1159030931199714069e-11i) (num-test (cos -6.28284004019658492979e+00-1.19209289550781250e-07i) 9.9999994039536292205e-1+4.1159030931199714069e-11i) (num-test (cos 6.28284004019658492979e+00+5.0e-01i) 1.1276258979946363572e0+1.7991700040946600032e-4i) (num-test (cos 6.28284004019658492979e+00-5.0e-01i) 1.1276258979946363572e0-1.7991700040946600032e-4i) (num-test (cos -6.28284004019658492979e+00+5.0e-01i) 1.1276258979946363572e0-1.7991700040946600032e-4i) (num-test (cos -6.28284004019658492979e+00-5.0e-01i) 1.1276258979946363572e0+1.7991700040946600032e-4i) (num-test (cos 6.28284004019658492979e+00+1.0e+00i) 1.5430805428404715941e0+4.0575816248752181112e-4i) (num-test (cos 6.28284004019658492979e+00-1.0e+00i) 1.5430805428404715941e0-4.0575816248752181112e-4i) (num-test (cos -6.28284004019658492979e+00+1.0e+00i) 1.5430805428404715941e0-4.0575816248752181112e-4i) (num-test (cos -6.28284004019658492979e+00-1.0e+00i) 1.5430805428404715941e0+4.0575816248752181112e-4i) (num-test (cos 6.28284004019658492979e+00+2.0e+00i) 3.7621954668392959443e0+1.2522351259054239819e-3i) (num-test (cos 6.28284004019658492979e+00-2.0e+00i) 3.7621954668392959443e0-1.2522351259054239819e-3i) (num-test (cos -6.28284004019658492979e+00+2.0e+00i) 3.7621954668392959443e0-1.2522351259054239819e-3i) (num-test (cos -6.28284004019658492979e+00-2.0e+00i) 3.7621954668392959443e0+1.2522351259054239819e-3i) (num-test (cos 6.28353057416258753420e+00+0.0e+00i) 9.9999994039535581679e-1) (num-test (cos -6.28353057416258753420e+00+0.0e+00i) 9.9999994039535581679e-1) (num-test (cos 6.28353057416258753420e+00+1.19209289550781250e-07i) 9.9999994039536292222e-1-4.1159030931141318362e-11i) (num-test (cos 6.28353057416258753420e+00-1.19209289550781250e-07i) 9.9999994039536292222e-1+4.1159030931141318362e-11i) (num-test (cos -6.28353057416258753420e+00+1.19209289550781250e-07i) 9.9999994039536292222e-1+4.1159030931141318362e-11i) (num-test (cos -6.28353057416258753420e+00-1.19209289550781250e-07i) 9.9999994039536292222e-1-4.1159030931141318362e-11i) (num-test (cos 6.28353057416258753420e+00+5.0e-01i) 1.1276258979946363574e0-1.7991700040921073725e-4i) (num-test (cos 6.28353057416258753420e+00-5.0e-01i) 1.1276258979946363574e0+1.7991700040921073725e-4i) (num-test (cos -6.28353057416258753420e+00+5.0e-01i) 1.1276258979946363574e0+1.7991700040921073725e-4i) (num-test (cos -6.28353057416258753420e+00-5.0e-01i) 1.1276258979946363574e0-1.7991700040921073725e-4i) (num-test (cos 6.28353057416258753420e+00+1.0e+00i) 1.5430805428404715943e0-4.0575816248694612861e-4i) (num-test (cos 6.28353057416258753420e+00-1.0e+00i) 1.5430805428404715943e0+4.0575816248694612861e-4i) (num-test (cos -6.28353057416258753420e+00+1.0e+00i) 1.5430805428404715943e0+4.0575816248694612861e-4i) (num-test (cos -6.28353057416258753420e+00-1.0e+00i) 1.5430805428404715943e0-4.0575816248694612861e-4i) (num-test (cos 6.28353057416258753420e+00+2.0e+00i) 3.7621954668392959449e0-1.2522351259036473328e-3i) (num-test (cos 6.28353057416258753420e+00-2.0e+00i) 3.7621954668392959449e0+1.2522351259036473328e-3i) (num-test (cos -6.28353057416258753420e+00+2.0e+00i) 3.7621954668392959449e0+1.2522351259036473328e-3i) (num-test (cos -6.28353057416258753420e+00-2.0e+00i) 3.7621954668392959449e0-1.2522351259036473328e-3i) (num-test (cos 9.42443269378637893396e+00+0.0e+00i) -9.9999994039535581689e-1) (num-test (cos -9.42443269378637893396e+00+0.0e+00i) -9.9999994039535581689e-1) (num-test (cos 9.42443269378637893396e+00+1.19209289550781250e-07i) -9.9999994039536292231e-1-4.1159030931108433883e-11i) (num-test (cos 9.42443269378637893396e+00-1.19209289550781250e-07i) -9.9999994039536292231e-1+4.1159030931108433883e-11i) (num-test (cos -9.42443269378637893396e+00+1.19209289550781250e-07i) -9.9999994039536292231e-1+4.1159030931108433883e-11i) (num-test (cos -9.42443269378637893396e+00-1.19209289550781250e-07i) -9.9999994039536292231e-1-4.1159030931108433883e-11i) (num-test (cos 9.42443269378637893396e+00+5.0e-01i) -1.1276258979946363575e0-1.7991700040906699050e-4i) (num-test (cos 9.42443269378637893396e+00-5.0e-01i) -1.1276258979946363575e0+1.7991700040906699050e-4i) (num-test (cos -9.42443269378637893396e+00+5.0e-01i) -1.1276258979946363575e0+1.7991700040906699050e-4i) (num-test (cos -9.42443269378637893396e+00-5.0e-01i) -1.1276258979946363575e0-1.7991700040906699050e-4i) (num-test (cos 9.42443269378637893396e+00+1.0e+00i) -1.5430805428404715945e0-4.0575816248662194348e-4i) (num-test (cos 9.42443269378637893396e+00-1.0e+00i) -1.5430805428404715945e0+4.0575816248662194348e-4i) (num-test (cos -9.42443269378637893396e+00+1.0e+00i) -1.5430805428404715945e0+4.0575816248662194348e-4i) (num-test (cos -9.42443269378637893396e+00-1.0e+00i) -1.5430805428404715945e0-4.0575816248662194348e-4i) (num-test (cos 9.42443269378637893396e+00+2.0e+00i) -3.7621954668392959453e0-1.2522351259026468452e-3i) (num-test (cos 9.42443269378637893396e+00-2.0e+00i) -3.7621954668392959453e0+1.2522351259026468452e-3i) (num-test (cos -9.42443269378637893396e+00+2.0e+00i) -3.7621954668392959453e0+1.2522351259026468452e-3i) (num-test (cos -9.42443269378637893396e+00-2.0e+00i) -3.7621954668392959453e0-1.2522351259026468452e-3i) (num-test (cos 9.42512322775237976202e+00+0.0e+00i) -9.9999994039535581714e-1) (num-test (cos -9.42512322775237976202e+00+0.0e+00i) -9.9999994039535581714e-1) (num-test (cos 9.42512322775237976202e+00+1.19209289550781250e-07i) -9.9999994039536292257e-1+4.1159030931020840323e-11i) (num-test (cos 9.42512322775237976202e+00-1.19209289550781250e-07i) -9.9999994039536292257e-1-4.1159030931020840323e-11i) (num-test (cos -9.42512322775237976202e+00+1.19209289550781250e-07i) -9.9999994039536292257e-1-4.1159030931020840323e-11i) (num-test (cos -9.42512322775237976202e+00-1.19209289550781250e-07i) -9.9999994039536292257e-1+4.1159030931020840323e-11i) (num-test (cos 9.42512322775237976202e+00+5.0e-01i) -1.1276258979946363577e0+1.7991700040868409591e-4i) (num-test (cos 9.42512322775237976202e+00-5.0e-01i) -1.1276258979946363577e0-1.7991700040868409591e-4i) (num-test (cos -9.42512322775237976202e+00+5.0e-01i) -1.1276258979946363577e0-1.7991700040868409591e-4i) (num-test (cos -9.42512322775237976202e+00-5.0e-01i) -1.1276258979946363577e0+1.7991700040868409591e-4i) (num-test (cos 9.42512322775237976202e+00+1.0e+00i) -1.5430805428404715949e0+4.0575816248575841970e-4i) (num-test (cos 9.42512322775237976202e+00-1.0e+00i) -1.5430805428404715949e0-4.0575816248575841970e-4i) (num-test (cos -9.42512322775237976202e+00+1.0e+00i) -1.5430805428404715949e0-4.0575816248575841970e-4i) (num-test (cos -9.42512322775237976202e+00-1.0e+00i) -1.5430805428404715949e0+4.0575816248575841970e-4i) (num-test (cos 9.42512322775237976202e+00+2.0e+00i) -3.7621954668392959462e0+1.2522351258999818715e-3i) (num-test (cos 9.42512322775237976202e+00-2.0e+00i) -3.7621954668392959462e0-1.2522351258999818715e-3i) (num-test (cos -9.42512322775237976202e+00+2.0e+00i) -3.7621954668392959462e0-1.2522351258999818715e-3i) (num-test (cos -9.42512322775237976202e+00-2.0e+00i) -3.7621954668392959462e0+1.2522351258999818715e-3i) (num-test (cos 0) 1.0) (num-test (cos -2.225073858507201399999999999999999999996E-308) 1.000E0) (num-test (cos 1.110223024625156799999999999999999999997E-16) 9.999999999999999999999999999999938370242E-1) (num-test (cos 22) -9.999608263946371264541747392126937741354E-1) (num-test (cos 32767.) 9.8226335176928229845654E-1) (num-test (cos 8388607.) -1.2349580912475928183718E-1) (num-test (cos 2147483647.) -6.8883669187794383467976E-1) (num-test (cos (* pi (cos (* pi (cos (log (+ pi 20))))))) -1.0) ; actually there's a 3.93216e-35 imag part (num-test (cos (/ pi 10)) (/ (sqrt (+ 10 (* 2 (sqrt 5)))) 4)) (num-test (cos (/ pi 12)) (* (/ (sqrt 2) 4) (+ (sqrt 3) 1))) (num-test (cos (/ pi 12)) (/ (+ (sqrt 6) (sqrt 2)) 4)) (num-test (cos (/ pi 128)) (* 1/2 (sqrt (+ 2 (sqrt (+ 2 (sqrt (+ 2 (sqrt (+ 2 (sqrt (+ 2 (sqrt 2))))))))))))) (num-test (cos (/ pi 15)) (/ (+ (sqrt (+ 30 (* 6 (sqrt 5)))) (sqrt 5) -1) 8)) (num-test (cos (/ pi 16)) (/ (sqrt (+ 2 (sqrt (+ 2 (sqrt 2))))) 2)) (num-test (cos (/ pi 20)) (/ (sqrt (+ 8 (* 2 (sqrt (+ 10 (* 2 (sqrt 5))))))) 4)) (num-test (cos (/ pi 24)) (/ (sqrt (+ 2 (sqrt (+ 2 (sqrt 3))))) 2)) (num-test (cos (/ pi 3)) 1/2) (num-test (cos (/ pi 3)) 1/2) (num-test (cos (/ pi 30)) (/ (sqrt (+ 7 (sqrt 5) (sqrt (* 6 (+ 5 (sqrt 5)))))) 4)) (num-test (cos (/ pi 32)) (/ (sqrt (+ 2 (sqrt (+ 2 (sqrt (+ 2 (sqrt 2))))))) 2)) (num-test (cos (/ pi 4)) (/ (sqrt 2) 2)) (num-test (cos (/ pi 5)) (/ (+ 1 (sqrt 5)) 4)) (num-test (cos (/ pi 6)) (/ (sqrt 3) 2)) (num-test (cos (/ pi 64)) (* 1/2 (sqrt (+ 2 (sqrt (+ 2 (sqrt (+ 2 (sqrt (+ 2 (sqrt 2))))))))))) (num-test (cos (/ pi 8)) (/ (sqrt (+ 2 (sqrt 2))) 2)) (num-test (cos (log (+ pi 20))) -0.99999999924368) (num-test (* (cos (/ pi 11)) (cos (/ (* 2 pi) 11)) (cos (/ (* 3 pi) 11)) (cos (/ (* 4 pi) 11)) (cos (/ (* 5 pi) 11))) 1/32) (num-test (* (cos (/ pi 7)) (cos (/ (* 2 pi) 7)) (cos (/ (* 3 pi) 7))) 1/8) (num-test (* (cos (/ pi 9)) (cos (/ (* 2 pi) 9)) (cos (/ (* 4 pi) 9))) 1/8) (num-test (* (cos (/ pi 9)) (cos (/ (* 2 pi) 9)) (cos (/ (* 4 pi) 9))) 1/8) (num-test (do ((i 1 (+ i 1)) (sum 0.0 (+ sum (cos (/ (* 2 pi i) 11))))) ((= i 6) sum)) -0.5) (num-test (let ((a (/ (* 2 pi) 13))) (* 8 (+ (cos a) (cos (* 5 a))) (+ (cos (* 2 a)) (cos (* 3 a))) (+ (cos (* 4 a)) (cos (* 6 a))))) -1.0) (for-each (lambda (num-and-val) (let ((num (car num-and-val)) (val (cadr num-and-val))) (num-test-1 'cos num (cos num) val))) (vector (list 0 1) (list 1 0.54030230586814) (list 2 -0.41614683654714) (list 3 -0.98999249660045) (list -1 0.54030230586814) (list -2 -0.41614683654714) (list -3 -0.98999249660045) (list 1/2 0.87758256189037) (list 1/3 0.94495694631474) (list -1/2 0.87758256189037) (list -1/3 0.94495694631474) (list 1/9223372036854775807 1.0) (list 0.0 1.0) (list 1.0 0.54030230586814) (list 2.0 -0.41614683654714) (list -2.0 -0.41614683654714) (list 1.000000000000000000000000000000000000002E-309 1.000E0) (list 0+1i 1.5430806348152) (list 0+2i 3.7621956910836) (list 0-1i 1.5430806348152) (list 1+1i 0.83373002513115-0.98889770576287i) (list 1-1i 0.83373002513115+0.98889770576287i) (list -1+1i 0.83373002513115+0.98889770576287i) (list -1-1i 0.83373002513115-0.98889770576287i) (list 0.1+0.1i 0.9999833333373-0.0099999888888898i) (list 1e-16+1e-16i 1-1e-32i) )) ;; these are from the error analysis package from ETH, Gaston H. Gonnet (num-test (cos -1.79424124483688191e-11) 9.999999999999999999998390349177663098196E-1) (num-test (sqrt 3.63861067050296029e-308) 1.907514264822929257351751954551699751189E-154) (if with-bignums (num-test (tan 10526671570.5) 1.140653720398103887405511659009364634384E12)) (if with-bignums (num-test (tan (modulo 10526671570.5 (* 2 pi))) 1.140653720398103899436689297531030608688E12)) (num-test (modulo 10526671570.5 (* 2 pi)) 4.712388980383813167439843967777959731718E0) ;; this is so sensitive because (cos 4.712388980383813167439843967777959731718E0) = -8.766902541211071412945944658266052999824E-13 ;; unfair! (test (cos) 'error) (test (cos "hi") 'error) (test (cos 1.0+23.0i 1.0+23.0i) 'error) (test (cos 0 1) 'error) (for-each (lambda (arg) (test (cos arg) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) (let* ((angle 0.0) (z 1.18) (result (* z (cos angle)))) (do ((k 0 (+ 1 k))) ((= k 1000)) (set! result (* z (cos result)))) ;;result: 0.81194462369499 ;;(let ((x 0.0)) ;; (do ((i 0 (+ 1 i))) ;; ((= i 10000)) ;; (set! x (+ x (* (expt -1 i) ;; (/ (bes-jn (+ 1 (* 2 i)) (* z (+ 1 (* 2 i)))) ;; (+ 1 (* 2 i))))))) ;; (* 2 x)) ;; 0.81194498071946 (let ((x (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos 0.0)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) ;; 47? calls here so we're at around .812 (oscillating around .8119) (test (< (abs (- x result)) .001) #t))) (when full-test (let () ; this is trying to cause a stack overflow (define (f1 z) (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos (* z (cos 0.0))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) (num-test (f1 0.5) 0.4501836112948736) (let ((c #f) (i 0)) (call/cc (lambda (c1) (set! c c1))) (set! i (+ i 1)) (let ((result (f1 0.5))) (if (< i 2) (c)) (num-test result 0.4501836112948736))))) (let () (define (dht data) ;; the Hartley transform of 'data' (let* ((len (vector-length data)) (arr (make-vector len 0.0)) (w (/ (* 2.0 pi) len))) (do ((i 0 (+ 1 i))) ((= i len)) (do ((j 0 (+ 1 j))) ((= j len)) (vector-set! arr i (+ (vector-ref arr i) (* (vector-ref data j) (+ (cos (* i j w)) (sin (* i j w)))))))) arr)) (let ((data (list->vector '(0.9196 0.9457 0.0268 0.0839 0.1974 0.1060 0.1463 0.3513 0.0391 0.6310 0.9556 0.6259 0.9580 0.8848 0.0104 0.1440 0.0542 0.3001 0.1844 0.3781 0.9641 0.6051 0.3319 0.6143 0.1828 0.2290 0.4026 0.5990 0.7906 0.0403 0.7882 0.1591))) (saved-data (make-vector 32 0.0))) (do ((i 0 (+ i 1))) ((= i 32)) (vector-set! saved-data i (vector-ref data i))) (dht data) (dht data) (let ((mx 0.0)) (do ((i 0 (+ i 1))) ((= i 32)) (let ((err (abs (- (vector-ref data i) (vector-ref saved-data i))))) (if (> err mx) (set! mx err)))) (if (> mx 1e-6) (format-logged #t "dht error: ~A~%" mx))))) (let ((coss (list 1.00000000000000000000000000000000000000000000000000000000000000000000 0.99500416527802576609556198780387029483857622541508403595935274468526 0.98006657784124163112419651674816887739352436080656799405254829012618 0.95533648912560601964231022756804989824421408263203767451761361222758 0.92106099400288508279852673205180161402585956931985044561508926713514 0.87758256189037271611628158260382965199164519710974405299761086831595 0.82533561490967829724095249895537603887809103918847038136974977367156 0.76484218728448842625585999019186490926821055037370335607293245825206 0.69670670934716542092074998164232492610178601370806078363714489414924 0.62160996827066445648471615140713350872176136659123900757638348453897 0.54030230586813971740093660744297660373231042061792222767009725538110 0.45359612142557738777137005178471612212146729566259504745593805541880 0.36235775447667357763837335562307602033994778557664862648774972093613 0.26749882862458740699798410929287135927592992167912966191725336742182 0.16996714290024093861674803520364980292818392102853430898236521149464 0.07073720166770291008818985143426870908509102756334686942264541719092 -0.02919952230128872620577046294649852444486472109384694500313007908245 -0.12884449429552468408764285733487351410164007964520297633178213994289 -0.22720209469308705531667430653058073247695158653826107158496911100681 -0.32328956686350342227883369508031017459419076544223959990115436505106 -0.41614683654714238699756822950076218976600077107554489075514997378196 -0.50484610459985745162093852371916747040702337674136205964819622353659 -0.58850111725534570852414261265492841629376036669872798974753517400616 -0.66627602127982419331788057116601723016327537100376988865266957182167 -0.73739371554124549960882222733478290843301289199228479878436568873073 -0.80114361554693371483350279046735166442856784876782013507459799166202 -0.85688875336894723379770215164520111235392263823324404910501242714241 -0.90407214201706114798252728194333012633184973516362471104126694868604 -0.94222234066865815258678811736615401246341423446824662018098201995710 -0.97095816514959052178110666934553217911761475942423954213867099245327 -0.98999249660044545727157279473126130239367909661558832881408593292832 -0.99913515027327946449237605454146626283664166994794274354471598254947 -0.99829477579475308466166072228358269144701258595166016759508002045139))) (let ((mxerr 0.0)) (do ((i 0 (+ i 1)) (x 0.0 (+ x 0.1))) ((= i 32)) (let ((err (abs (- (cos x) (list-ref coss i))))) (if (> err mxerr) (set! mxerr err)))) (if (> mxerr 1e-12) (format-logged #t "cos err: ~A~%" mxerr)))) (if with-bignums (begin (num-test (cos 100000000000000000000000000000000) -9.207313839241906875982573440296245746235E-1) (num-test (cos 100000000000000000000000000000000.0) -9.207313839241906875982573440296245746235E-1) )) (if with-bignums (let ((old-prec (*s7* 'bignum-precision))) (set! (*s7* 'bignum-precision) 500) (let ((cos-vals (list ; arprec mathtool table[Cos[k/20], {k, 0, 30}] "1.00000000000000000000000000000000000000000000000000000000000000000000" "0.99875026039496624656287081115652109495898026202467575301500996478674" "0.99500416527802576609556198780387029483857622541508403595935274468526" "0.98877107793604228673498099865433895791835001710693704356129574806756" "0.98006657784124163112419651674816887739352436080656799405254829012618" "0.96891242171064478414459544949418919980413419028744283114812812428894" "0.95533648912560601964231022756804989824421408263203767451761361222758" "0.93937271284737892003503235730366558297406104641303414382897205809282" "0.92106099400288508279852673205180161402585956931985044561508926713514" "0.90044710235267692166884061148644643975762309272876915613354673932299" "0.87758256189037271611628158260382965199164519710974405299761086831595" "0.85252452205950574280498179761777305104031900079223767166865534849083" "0.82533561490967829724095249895537603887809103918847038136974977367156" "0.79608379854905582891760457067990587351049589381429244823834230313846" "0.76484218728448842625585999019186490926821055037370335607293245825206" "0.73168886887382088631183875300008454384054127605077248250768322022075" "0.69670670934716542092074998164232492610178601370806078363714489414924" "0.65998314588498217039541602946146607363862433893076798146474793887138" "0.62160996827066445648471615140713350872176136659123900757638348453897" "0.58168308946388349416618097376045571713934034193760200851355170750073" "0.54030230586813971740093660744297660373231042061792222767009725538110" "0.49757104789172699029084957281210067725147811164693171708781576506313" "0.45359612142557738777137005178471612212146729566259504745593805541880" "0.40848744088415729815257671880991853998462713510786075458328732035938" "0.36235775447667357763837335562307602033994778557664862648774972093613" "0.31532236239526866544753855243803801372798570798275680751499914045328" "0.26749882862458740699798410929287135927592992167912966191725336742182" "0.21900668709304158142002217301062666089672421266400567061594451723594" "0.16996714290024093861674803520364980292818392102853430898236521149464" "0.12050276936736657053286662724801883979155423770384722087315404654227" "0.07073720166770291008818985143426870908509102756334686942264541719092"))) (do ((k 1 (+ k 1))) ((= k 30)) (let ((cos-val-2 (number->string (cos (/ k (bignum "20")))))) (if (not (string=? (substring (list-ref cos-vals k) 3 60) (substring cos-val-2 2 59))) (format-logged #t ";(cos (/ ~A 20)) mp: ~A does not match~%~A~%" k (substring (list-ref cos-vals k) 3 60) (substring cos-val-2 2 59)))))) (set! (*s7* 'bignum-precision) old-prec))) ;;; -------------------------------------------------------------------------------- ;;; tan ;;; -------------------------------------------------------------------------------- (num-test (tan 0) 0.0) (num-test (tan 1) 1.55740772465490) (num-test (tan -1) -1.55740772465490) (num-test (tan 0/1) 0.0) (num-test (tan 0/2) 0.0) (num-test (tan 0/3) 0.0) (num-test (tan 0/10) 0.0) (num-test (tan 0/1234) 0.0) (num-test (tan 0/1234000000) 0.0) (num-test (tan 0/500029) 0.0) (num-test (tan 0/362880) 0.0) (num-test (tan 1/1) 1.55740772465490) (num-test (tan -1/1) -1.55740772465490) (num-test (tan 1/2) 0.54630248984379) (num-test (tan -1/2) -0.54630248984379) (num-test (tan 1/3) 0.34625354951058) (num-test (tan -1/3) -0.34625354951058) (num-test (tan 1/10) 0.10033467208545) (num-test (tan -1/10) -0.10033467208545) (num-test (tan 1/1234) 0.00081037294887) (num-test (tan -1/1234) -0.00081037294887) (num-test (tan 1/1234000000) 0.00000000081037) (num-test (tan -1/1234000000) -0.00000000081037) (num-test (tan 1/500029) 0.00000199988401) (num-test (tan -1/500029) -0.00000199988401) (num-test (tan 1/362880) 0.00000275573192) (num-test (tan -1/362880) -0.00000275573192) (num-test (tan 2/2) 1.55740772465490) (num-test (tan -2/2) -1.55740772465490) (num-test (tan 2/3) 0.78684288947298) (num-test (tan -2/3) -0.78684288947298) (num-test (tan 2/10) 0.20271003550867) (num-test (tan -2/10) -0.20271003550867) (num-test (tan 2/1234) 0.00162074696208) (num-test (tan -2/1234) -0.00162074696208) (num-test (tan 2/1234000000) 0.00000000162075) (num-test (tan -2/1234000000) -0.00000000162075) (num-test (tan 2/500029) 0.00000399976801) (num-test (tan -2/500029) -0.00000399976801) (num-test (tan 2/362880) 0.00000551146384) (num-test (tan -2/362880) -0.00000551146384) (num-test (tan 3/2) 14.10141994717166) (num-test (tan -3/2) -14.10141994717166) (num-test (tan 3/3) 1.55740772465490) (num-test (tan -3/3) -1.55740772465490) (num-test (tan 3/10) 0.30933624960962) (num-test (tan -3/10) -0.30933624960962) (num-test (tan 3/1234) 0.00243112310401) (num-test (tan -3/1234) -0.00243112310401) (num-test (tan 3/1234000000) 0.00000000243112) (num-test (tan -3/1234000000) -0.00000000243112) (num-test (tan 3/500029) 0.00000599965202) (num-test (tan -3/500029) -0.00000599965202) (num-test (tan 3/362880) 0.00000826719577) (num-test (tan -3/362880) -0.00000826719577) (num-test (tan 10/10) 1.55740772465490) (num-test (tan -10/10) -1.55740772465490) (num-test (tan 10/1234) 0.00810390511110) (num-test (tan -10/1234) -0.00810390511110) (num-test (tan 10/1234000000) 0.00000000810373) (num-test (tan -10/1234000000) -0.00000000810373) (num-test (tan 10/500029) 0.00001999884007) (num-test (tan -10/500029) -0.00001999884007) (num-test (tan 10/362880) 0.00002755731923) (num-test (tan -10/362880) -0.00002755731923) (num-test (tan 1234/1234) 1.55740772465490) (num-test (tan -1234/1234) -1.55740772465490) (num-test (tan 1234/1234000000) 0.00000100000000) (num-test (tan -1234/1234000000) -0.00000100000000) (num-test (tan 1234/500029) 0.00246786187432) (num-test (tan -1234/500029) -0.00246786187432) (num-test (tan 1234/362880) 0.00340058630026) (num-test (tan -1234/362880) -0.00340058630026) (num-test (tan 1234000000/1234000000) 1.55740772465490) (num-test (tan -1234000000/1234000000) -1.55740772465490) (num-test (tan 500029/1234000000) 0.00040520990873) (num-test (tan -500029/1234000000) -0.00040520990873) (num-test (tan 500029/500029) 1.55740772465490) (num-test (tan -500029/500029) -1.55740772465490) (num-test (tan 500029/362880) 5.12092171798848) (num-test (tan -500029/362880) -5.12092171798848) (num-test (tan 362880/1234000000) 0.00029406807979) (num-test (tan -362880/1234000000) -0.00029406807979) (num-test (tan 362880/500029) 0.88723539913856) (num-test (tan -362880/500029) -0.88723539913856) (num-test (tan 362880/362880) 1.55740772465490) (num-test (tan -362880/362880) -1.55740772465490) (num-test (tan 0.0) 0.0) (num-test (tan 0.00000001) 0.00000001) (num-test (tan -0.00000001) -0.00000001) (num-test (tan 1.0) 1.55740772465490) (num-test (tan -1.0) -1.55740772465490) (num-test (tan 0.0+0.0i) 0.0) (num-test (tan -0.0+0.0i) 0.0) (num-test (tan 0.0-0.0i) 0.0) (num-test (tan -0.0-0.0i) 0.0) (num-test (tan 0.0+0.00000001i) 0.0+0.00000001i) (num-test (tan -0.0+0.00000001i) 0.0+0.00000001i) (num-test (tan 0.0-0.00000001i) 0.0-0.00000001i) (num-test (tan -0.0-0.00000001i) -0.0-0.00000001i) (num-test (tan 0.0+1.0i) 0.0+0.76159415595576i) (num-test (tan -0.0+1.0i) 0.0+0.76159415595576i) (num-test (tan 0.0-1.0i) 0.0-0.76159415595576i) (num-test (tan -0.0-1.0i) -0.0-0.76159415595576i) (num-test (tan 0.0+3.14159265358979i) 0.0+0.99627207622075i) (num-test (tan -0.0+3.14159265358979i) 0.0+0.99627207622075i) (num-test (tan 0.0-3.14159265358979i) 0.0-0.99627207622075i) (num-test (tan -0.0-3.14159265358979i) -0.0-0.99627207622075i) (num-test (tan 0.0+2.71828182845905i) 0.0+0.99132891580060i) (num-test (tan -0.0+2.71828182845905i) 0.0+0.99132891580060i) (num-test (tan 0.0-2.71828182845905i) 0.0-0.99132891580060i) (num-test (tan -0.0-2.71828182845905i) -0.0-0.99132891580060i) (num-test (tan 0.00000001+0.0i) 0.00000001) (num-test (tan -0.00000001+0.0i) -0.00000001) (num-test (tan 0.00000001-0.0i) 0.00000001) (num-test (tan -0.00000001-0.0i) -0.00000001) (num-test (tan 0.00000001+0.00000001i) 0.00000001+0.00000001i) (num-test (tan -0.00000001+0.00000001i) -0.00000001+0.00000001i) (num-test (tan 0.00000001-0.00000001i) 0.00000001-0.00000001i) (num-test (tan -0.00000001-0.00000001i) -0.00000001-0.00000001i) (num-test (tan 0.00000001+1.0i) 0.00000000419974+0.76159415595576i) (num-test (tan -0.00000001+1.0i) -0.00000000419974+0.76159415595576i) (num-test (tan 0.00000001-1.0i) 0.00000000419974-0.76159415595576i) (num-test (tan -0.00000001-1.0i) -0.00000000419974-0.76159415595576i) (num-test (tan 0.00000001+3.14159265358979i) 0.00000000007442+0.99627207622075i) (num-test (tan -0.00000001+3.14159265358979i) -0.00000000007442+0.99627207622075i) (num-test (tan 0.00000001-3.14159265358979i) 0.00000000007442-0.99627207622075i) (num-test (tan -0.00000001-3.14159265358979i) -0.00000000007442-0.99627207622075i) (num-test (tan 0.00000001+2.71828182845905i) 0.00000000017267+0.99132891580060i) (num-test (tan -0.00000001+2.71828182845905i) -0.00000000017267+0.99132891580060i) (num-test (tan 0.00000001-2.71828182845905i) 0.00000000017267-0.99132891580060i) (num-test (tan -0.00000001-2.71828182845905i) -0.00000000017267-0.99132891580060i) (num-test (tan 1.0+0.0i) 1.55740772465490) (num-test (tan -1.0+0.0i) -1.55740772465490) (num-test (tan 1.0-0.0i) 1.55740772465490) (num-test (tan -1.0-0.0i) -1.55740772465490) (num-test (tan 1.0+0.00000001i) 1.55740772465490+0.00000003425519i) (num-test (tan -1.0+0.00000001i) -1.55740772465490+0.00000003425519i) (num-test (tan 1.0-0.00000001i) 1.55740772465490-0.00000003425519i) (num-test (tan -1.0-0.00000001i) -1.55740772465490-0.00000003425519i) (num-test (tan 1.0+1.0i) 0.27175258531951+1.08392332733869i) (num-test (tan -1.0+1.0i) -0.27175258531951+1.08392332733869i) (num-test (tan 1.0-1.0i) 0.27175258531951-1.08392332733869i) (num-test (tan -1.0-1.0i) -0.27175258531951-1.08392332733869i) (num-test (tan 1.0+3.14159265358979i) 0.00340139653674+1.00154968930275i) (num-test (tan -1.0+3.14159265358979i) -0.00340139653674+1.00154968930275i) (num-test (tan 1.0-3.14159265358979i) 0.00340139653674-1.00154968930275i) (num-test (tan -1.0-3.14159265358979i) -0.00340139653674-1.00154968930275i) (num-test (tan 1.0+2.71828182845905i) 0.00794757997665+1.00359921084211i) (num-test (tan -1.0+2.71828182845905i) -0.00794757997665+1.00359921084211i) (num-test (tan 1.0-2.71828182845905i) 0.00794757997665-1.00359921084211i) (num-test (tan -1.0-2.71828182845905i) -0.00794757997665-1.00359921084211i) (num-test (tan 1234.0+1234.0i) 2.7e-20+1.0i) (num-test (tan 1234.0-1234.0i) 2.7e-20-1.0i) (num-test (tan 10/3) .1941255059835657) (num-test (tan 1234/3) -0.2186940320047828) (num-test (tan 1234/10) 1.204471256531804) (num-test (tan 1234000000/3) -1.878094815124064721190472976913242128538E1) ; the ratio->float computation is inaccurate here I think (num-test (tan 1234000000/500029) -7.31654379832009) (num-test (tan 1234000000/362880) 4.911576750502133) (num-test (tan 500029/2) .2804673425353792) (num-test (tan 500029/3) -1.173139817032177) (num-test (tan 500029/10) 3.767116303516932) (num-test (tan 500029/1234) -0.05562302342803592) (num-test (tan 362880/1234) -2.927532635052267) (num-test (tan pi) 6.982889851335445E-15) (num-test (tan 2.71828182845905) -0.4505495340698621) (num-test (tan 0.00000001+1234.0i) +8.077935669463161E-28+1.0i) (num-test (tan 0.00000001+1234000000.0i) 0.0+1.0i) (num-test (tan 3.14159265358979+0.0i) 6.982889851335445E-15) (num-test (tan 3.14159265358979+0.00000001i) +6.982889851335444E-15+1.0E-8i) (num-test (tan 3.14159265358979+1.0i) +2.932634567877868E-15+0.7615941559557649i) (num-test (tan 3.14159265358979+3.14159265358979i) +5.196631812627532E-17+0.99627207622075i) (num-test (tan 3.14159265358979+2.71828182845905i) +1.205734242765375E-16+0.991328915800599i) (num-test (tan 3.14159265358979+1234.0i) 0.0+1.0i) (num-test (tan 3.14159265358979+1234000000.0i) -7.703719777548943E-34+1.0i) (num-test (tan 2.71828182845905+0.0i) -0.4505495340698621) (num-test (tan 2.71828182845905+0.00000001i) -0.4505495340698621+1.2029948826505699E-8i) (num-test (tan 2.71828182845905+1.0i) -0.1692870118766369+0.8196826057997404i) (num-test (tan 2.71828182845905+3.14159265358979i) -0.002790687681003331+0.9975247319761639i) (num-test (tan 2.71828182845905+2.71828182845905i) -0.00648578276962794+0.9942257438545914i) (num-test (tan 2.71828182845905+1234.0i) +2.710505431213761E-20+1.0i) (num-test (tan 2.71828182845905+1234000000.0i) +2.710505431213761E-20+1.0i) (num-test (tan 1234.0+0.00000001i) -0.7537751984442328+1.5681770497896427E-8i) (num-test (tan 1234.0+3.14159265358979i) -0.003586791196867043+0.9989656315245496i) (num-test (tan 1234.0+2.71828182845905i) -0.008351965390936033+0.9975698313220817i) (num-test (tan 1234000000.0+0.00000001i) -6.212941995900324+3.9600648244422054E-7i) (num-test (tan 1234000000.0+3.14159265358979i) -0.001176098307980411+1.003551866736695i) (num-test (tan 1234000000.0+2.71828182845905i) -0.002755390838840499+1.008299558244272i) ;(num-test (tan 1.5707963259845+2.0630965522972e-18i) 1.234000079689074E+9+3.141593059344448i) (num-test (tan -3.45266983001243932001e-04+0.0e+00i) -3.4526699672092183585e-4) (num-test (tan 3.45266983001243932001e-04+0.0e+00i) 3.4526699672092183585e-4) (num-test (tan -3.45266983001243932001e-04+1.19209289550781250e-07i) -3.4526699672091692931e-4+1.1920930376163652989e-7i) (num-test (tan -3.45266983001243932001e-04-1.19209289550781250e-07i) -3.4526699672091692931e-4-1.1920930376163652989e-7i) (num-test (tan 3.45266983001243932001e-04+1.19209289550781250e-07i) 3.4526699672091692931e-4+1.1920930376163652989e-7i) (num-test (tan 3.45266983001243932001e-04-1.19209289550781250e-07i) 3.4526699672091692931e-4-1.1920930376163652989e-7i) (num-test (tan -3.45266983001243932001e-04+5.0e-01i) -2.7153443992655805934e-4+4.6211720058436229979e-1i) (num-test (tan -3.45266983001243932001e-04-5.0e-01i) -2.7153443992655805934e-4-4.6211720058436229979e-1i) (num-test (tan 3.45266983001243932001e-04+5.0e-01i) 2.7153443992655805934e-4+4.6211720058436229979e-1i) (num-test (tan 3.45266983001243932001e-04-5.0e-01i) 2.7153443992655805934e-4-4.6211720058436229979e-1i) (num-test (tan -3.45266983001243932001e-04+1.0e+00i) -1.4500326960274960880e-4+7.6159419408485704836e-1i) (num-test (tan -3.45266983001243932001e-04-1.0e+00i) -1.4500326960274960880e-4-7.6159419408485704836e-1i) (num-test (tan 3.45266983001243932001e-04+1.0e+00i) 1.4500326960274960880e-4+7.6159419408485704836e-1i) (num-test (tan 3.45266983001243932001e-04-1.0e+00i) 1.4500326960274960880e-4-7.6159419408485704836e-1i) (num-test (tan -3.45266983001243932001e-04+2.0e+00i) -2.4393395410435306874e-5+9.6402758819508310556e-1i) (num-test (tan -3.45266983001243932001e-04-2.0e+00i) -2.4393395410435306874e-5-9.6402758819508310556e-1i) (num-test (tan 3.45266983001243932001e-04+2.0e+00i) 2.4393395410435306874e-5+9.6402758819508310556e-1i) (num-test (tan 3.45266983001243932001e-04-2.0e+00i) 2.4393395410435306874e-5-9.6402758819508310556e-1i) (num-test (tan 1.57045105981189525579e+00+0.0e+00i) 2.8963092606501007060e3) (num-test (tan -1.57045105981189525579e+00+0.0e+00i) -2.8963092606501007060e3) (num-test (tan 1.57045105981189525579e+00+1.19209289550781250e-07i) 2.8963089153831588642e3+9.9999992052646305569e-1i) (num-test (tan 1.57045105981189525579e+00-1.19209289550781250e-07i) 2.8963089153831588642e3-9.9999992052646305569e-1i) (num-test (tan -1.57045105981189525579e+00+1.19209289550781250e-07i) -2.8963089153831588642e3+9.9999992052646305569e-1i) (num-test (tan -1.57045105981189525579e+00-1.19209289550781250e-07i) -2.8963089153831588642e3-9.9999992052646305569e-1i) (num-test (tan 1.57045105981189525579e+00+5.0e-01i) 1.2715121175455623363e-3+2.1639524637389325996e0i) (num-test (tan 1.57045105981189525579e+00-5.0e-01i) 1.2715121175455623363e-3-2.1639524637389325996e0i) (num-test (tan -1.57045105981189525579e+00+5.0e-01i) -1.2715121175455623363e-3+2.1639524637389325996e0i) (num-test (tan -1.57045105981189525579e+00-5.0e-01i) -1.2715121175455623363e-3-2.1639524637389325996e0i) (num-test (tan 1.57045105981189525579e+00+1.0e+00i) 2.4999454374276273814e-4+1.3130351721648674823e0i) (num-test (tan 1.57045105981189525579e+00-1.0e+00i) 2.4999454374276273814e-4-1.3130351721648674823e0i) (num-test (tan -1.57045105981189525579e+00+1.0e+00i) -2.4999454374276273814e-4+1.3130351721648674823e0i) (num-test (tan -1.57045105981189525579e+00-1.0e+00i) -2.4999454374276273814e-4-1.3130351721648674823e0i) (num-test (tan 1.57045105981189525579e+00+2.0e+00i) 2.6247825506572821595e-5+1.0373147113268752620e0i) (num-test (tan 1.57045105981189525579e+00-2.0e+00i) 2.6247825506572821595e-5-1.0373147113268752620e0i) (num-test (tan -1.57045105981189525579e+00+2.0e+00i) -2.6247825506572821595e-5+1.0373147113268752620e0i) (num-test (tan -1.57045105981189525579e+00-2.0e+00i) -2.6247825506572821595e-5-1.0373147113268752620e0i) (num-test (tan 1.57114159377789786021e+00+0.0e+00i) -2.8963092606511280143e3) (num-test (tan -1.57114159377789786021e+00+0.0e+00i) 2.8963092606511280143e3) (num-test (tan 1.57114159377789786021e+00+1.19209289550781250e-07i) -2.8963089153841861720e3+9.9999992052717244672e-1i) (num-test (tan 1.57114159377789786021e+00-1.19209289550781250e-07i) -2.8963089153841861720e3-9.9999992052717244672e-1i) (num-test (tan -1.57114159377789786021e+00+1.19209289550781250e-07i) 2.8963089153841861720e3+9.9999992052717244672e-1i) (num-test (tan -1.57114159377789786021e+00-1.19209289550781250e-07i) 2.8963089153841861720e3-9.9999992052717244672e-1i) (num-test (tan 1.57114159377789786021e+00+5.0e-01i) -1.2715121175451113370e-3+2.1639524637389326002e0i) (num-test (tan 1.57114159377789786021e+00-5.0e-01i) -1.2715121175451113370e-3-2.1639524637389326002e0i) (num-test (tan -1.57114159377789786021e+00+5.0e-01i) 1.2715121175451113370e-3+2.1639524637389326002e0i) (num-test (tan -1.57114159377789786021e+00-5.0e-01i) 1.2715121175451113370e-3-2.1639524637389326002e0i) (num-test (tan 1.57114159377789786021e+00+1.0e+00i) -2.4999454374267406620e-4+1.3130351721648674824e0i) (num-test (tan 1.57114159377789786021e+00-1.0e+00i) -2.4999454374267406620e-4-1.3130351721648674824e0i) (num-test (tan -1.57114159377789786021e+00+1.0e+00i) 2.4999454374267406620e-4+1.3130351721648674824e0i) (num-test (tan -1.57114159377789786021e+00-1.0e+00i) 2.4999454374267406620e-4-1.3130351721648674824e0i) (num-test (tan 1.57114159377789786021e+00+2.0e+00i) -2.6247825506563511609e-5+1.0373147113268752620e0i) (num-test (tan 1.57114159377789786021e+00-2.0e+00i) -2.6247825506563511609e-5-1.0373147113268752620e0i) (num-test (tan -1.57114159377789786021e+00+2.0e+00i) 2.6247825506563511609e-5+1.0373147113268752620e0i) (num-test (tan -1.57114159377789786021e+00-2.0e+00i) 2.6247825506563511609e-5-1.0373147113268752620e0i) (num-test (tan 3.14124738660679181379e+00+0.0e+00i) -3.4526699672110257641e-4) (num-test (tan -3.14124738660679181379e+00+0.0e+00i) 3.4526699672110257641e-4) (num-test (tan 3.14124738660679181379e+00+1.19209289550781250e-07i) -3.4526699672109766987e-4+1.1920930376163652991e-7i) (num-test (tan 3.14124738660679181379e+00-1.19209289550781250e-07i) -3.4526699672109766987e-4-1.1920930376163652991e-7i) (num-test (tan -3.14124738660679181379e+00+1.19209289550781250e-07i) 3.4526699672109766987e-4+1.1920930376163652991e-7i) (num-test (tan -3.14124738660679181379e+00-1.19209289550781250e-07i) 3.4526699672109766987e-4-1.1920930376163652991e-7i) (num-test (tan 3.14124738660679181379e+00+5.0e-01i) -2.7153443992670020234e-4+4.6211720058436229984e-1i) (num-test (tan 3.14124738660679181379e+00-5.0e-01i) -2.7153443992670020234e-4-4.6211720058436229984e-1i) (num-test (tan -3.14124738660679181379e+00+5.0e-01i) 2.7153443992670020234e-4+4.6211720058436229984e-1i) (num-test (tan -3.14124738660679181379e+00-5.0e-01i) 2.7153443992670020234e-4-4.6211720058436229984e-1i) (num-test (tan 3.14124738660679181379e+00+1.0e+00i) -1.4500326960282551519e-4+7.6159419408485704840e-1i) (num-test (tan 3.14124738660679181379e+00-1.0e+00i) -1.4500326960282551519e-4-7.6159419408485704840e-1i) (num-test (tan -3.14124738660679181379e+00+1.0e+00i) 1.4500326960282551519e-4+7.6159419408485704840e-1i) (num-test (tan -3.14124738660679181379e+00-1.0e+00i) 1.4500326960282551519e-4-7.6159419408485704840e-1i) (num-test (tan 3.14124738660679181379e+00+2.0e+00i) -2.4393395410448076340e-5+9.6402758819508310557e-1i) (num-test (tan 3.14124738660679181379e+00-2.0e+00i) -2.4393395410448076340e-5-9.6402758819508310557e-1i) (num-test (tan -3.14124738660679181379e+00+2.0e+00i) 2.4393395410448076340e-5+9.6402758819508310557e-1i) (num-test (tan -3.14124738660679181379e+00-2.0e+00i) 2.4393395410448076340e-5-9.6402758819508310557e-1i) (num-test (tan 3.14193792057279441821e+00+0.0e+00i) 3.4526699672085764703e-4) (num-test (tan -3.14193792057279441821e+00+0.0e+00i) -3.4526699672085764703e-4) (num-test (tan 3.14193792057279441821e+00+1.19209289550781250e-07i) 3.4526699672085274049e-4+1.1920930376163652989e-7i) (num-test (tan 3.14193792057279441821e+00-1.19209289550781250e-07i) 3.4526699672085274049e-4-1.1920930376163652989e-7i) (num-test (tan -3.14193792057279441821e+00+1.19209289550781250e-07i) -3.4526699672085274049e-4+1.1920930376163652989e-7i) (num-test (tan -3.14193792057279441821e+00-1.19209289550781250e-07i) -3.4526699672085274049e-4-1.1920930376163652989e-7i) (num-test (tan 3.14193792057279441821e+00+5.0e-01i) 2.7153443992650757820e-4+4.6211720058436229978e-1i) (num-test (tan 3.14193792057279441821e+00-5.0e-01i) 2.7153443992650757820e-4-4.6211720058436229978e-1i) (num-test (tan -3.14193792057279441821e+00+5.0e-01i) -2.7153443992650757820e-4+4.6211720058436229978e-1i) (num-test (tan -3.14193792057279441821e+00-5.0e-01i) -2.7153443992650757820e-4-4.6211720058436229978e-1i) (num-test (tan 3.14193792057279441821e+00+1.0e+00i) 1.4500326960272265115e-4+7.6159419408485704835e-1i) (num-test (tan 3.14193792057279441821e+00-1.0e+00i) 1.4500326960272265115e-4-7.6159419408485704835e-1i) (num-test (tan -3.14193792057279441821e+00+1.0e+00i) -1.4500326960272265115e-4+7.6159419408485704835e-1i) (num-test (tan -3.14193792057279441821e+00-1.0e+00i) -1.4500326960272265115e-4-7.6159419408485704835e-1i) (num-test (tan 3.14193792057279441821e+00+2.0e+00i) 2.4393395410430771882e-5+9.6402758819508310556e-1i) (num-test (tan 3.14193792057279441821e+00-2.0e+00i) 2.4393395410430771882e-5-9.6402758819508310556e-1i) (num-test (tan -3.14193792057279441821e+00+2.0e+00i) -2.4393395410430771882e-5+9.6402758819508310556e-1i) (num-test (tan -3.14193792057279441821e+00-2.0e+00i) -2.4393395410430771882e-5-9.6402758819508310556e-1i) (num-test (tan 4.71204371340168837179e+00+0.0e+00i) 2.8963092606490733978e3) (num-test (tan -4.71204371340168837179e+00+0.0e+00i) -2.8963092606490733978e3) (num-test (tan 4.71204371340168837179e+00+1.19209289550781250e-07i) 2.8963089153821315563e3+9.9999992052575366466e-1i) (num-test (tan 4.71204371340168837179e+00-1.19209289550781250e-07i) 2.8963089153821315563e3-9.9999992052575366466e-1i) (num-test (tan -4.71204371340168837179e+00+1.19209289550781250e-07i) -2.8963089153821315563e3+9.9999992052575366466e-1i) (num-test (tan -4.71204371340168837179e+00-1.19209289550781250e-07i) -2.8963089153821315563e3-9.9999992052575366466e-1i) (num-test (tan 4.71204371340168837179e+00+5.0e-01i) 1.2715121175460133355e-3+2.1639524637389325989e0i) (num-test (tan 4.71204371340168837179e+00-5.0e-01i) 1.2715121175460133355e-3-2.1639524637389325989e0i) (num-test (tan -4.71204371340168837179e+00+5.0e-01i) -1.2715121175460133355e-3+2.1639524637389325989e0i) (num-test (tan -4.71204371340168837179e+00-5.0e-01i) -1.2715121175460133355e-3-2.1639524637389325989e0i) (num-test (tan 4.71204371340168837179e+00+1.0e+00i) 2.4999454374285141007e-4+1.3130351721648674822e0i) (num-test (tan 4.71204371340168837179e+00-1.0e+00i) 2.4999454374285141007e-4-1.3130351721648674822e0i) (num-test (tan -4.71204371340168837179e+00+1.0e+00i) -2.4999454374285141007e-4+1.3130351721648674822e0i) (num-test (tan -4.71204371340168837179e+00-1.0e+00i) -2.4999454374285141007e-4-1.3130351721648674822e0i) (num-test (tan 4.71204371340168837179e+00+2.0e+00i) 2.6247825506582131582e-5+1.0373147113268752620e0i) (num-test (tan 4.71204371340168837179e+00-2.0e+00i) 2.6247825506582131582e-5-1.0373147113268752620e0i) (num-test (tan -4.71204371340168837179e+00+2.0e+00i) -2.6247825506582131582e-5+1.0373147113268752620e0i) (num-test (tan -4.71204371340168837179e+00-2.0e+00i) -2.6247825506582131582e-5-1.0373147113268752620e0i) (num-test (tan 4.71273424736769097620e+00+0.0e+00i) -2.8963092606521553225e3) (num-test (tan -4.71273424736769097620e+00+0.0e+00i) 2.8963092606521553225e3) (num-test (tan 4.71273424736769097620e+00+1.19209289550781250e-07i) -2.8963089153852134799e3+9.9999992052788183776e-1i) (num-test (tan 4.71273424736769097620e+00-1.19209289550781250e-07i) -2.8963089153852134799e3-9.9999992052788183776e-1i) (num-test (tan -4.71273424736769097620e+00+1.19209289550781250e-07i) 2.8963089153852134799e3+9.9999992052788183776e-1i) (num-test (tan -4.71273424736769097620e+00-1.19209289550781250e-07i) 2.8963089153852134799e3-9.9999992052788183776e-1i) (num-test (tan 4.71273424736769097620e+00+5.0e-01i) -1.2715121175446603377e-3+2.1639524637389326009e0i) (num-test (tan 4.71273424736769097620e+00-5.0e-01i) -1.2715121175446603377e-3-2.1639524637389326009e0i) (num-test (tan -4.71273424736769097620e+00+5.0e-01i) 1.2715121175446603377e-3+2.1639524637389326009e0i) (num-test (tan -4.71273424736769097620e+00-5.0e-01i) 1.2715121175446603377e-3-2.1639524637389326009e0i) (num-test (tan 4.71273424736769097620e+00+1.0e+00i) -2.4999454374258539427e-4+1.3130351721648674825e0i) (num-test (tan 4.71273424736769097620e+00-1.0e+00i) -2.4999454374258539427e-4-1.3130351721648674825e0i) (num-test (tan -4.71273424736769097620e+00+1.0e+00i) 2.4999454374258539427e-4+1.3130351721648674825e0i) (num-test (tan -4.71273424736769097620e+00-1.0e+00i) 2.4999454374258539427e-4-1.3130351721648674825e0i) (num-test (tan 4.71273424736769097620e+00+2.0e+00i) -2.6247825506554201622e-5+1.0373147113268752620e0i) (num-test (tan 4.71273424736769097620e+00-2.0e+00i) -2.6247825506554201622e-5-1.0373147113268752620e0i) (num-test (tan -4.71273424736769097620e+00+2.0e+00i) 2.6247825506554201622e-5+1.0373147113268752620e0i) (num-test (tan -4.71273424736769097620e+00-2.0e+00i) 2.6247825506554201622e-5-1.0373147113268752620e0i) (num-test (tan 6.28284004019658492979e+00+0.0e+00i) -3.4526699672122504111e-4) (num-test (tan -6.28284004019658492979e+00+0.0e+00i) 3.4526699672122504111e-4) (num-test (tan 6.28284004019658492979e+00+1.19209289550781250e-07i) -3.4526699672122013457e-4+1.1920930376163652992e-7i) (num-test (tan 6.28284004019658492979e+00-1.19209289550781250e-07i) -3.4526699672122013457e-4-1.1920930376163652992e-7i) (num-test (tan -6.28284004019658492979e+00+1.19209289550781250e-07i) 3.4526699672122013457e-4+1.1920930376163652992e-7i) (num-test (tan -6.28284004019658492979e+00-1.19209289550781250e-07i) 3.4526699672122013457e-4-1.1920930376163652992e-7i) (num-test (tan 6.28284004019658492979e+00+5.0e-01i) -2.7153443992679651442e-4+4.6211720058436229987e-1i) (num-test (tan 6.28284004019658492979e+00-5.0e-01i) -2.7153443992679651442e-4-4.6211720058436229987e-1i) (num-test (tan -6.28284004019658492979e+00+5.0e-01i) 2.7153443992679651442e-4+4.6211720058436229987e-1i) (num-test (tan -6.28284004019658492979e+00-5.0e-01i) 2.7153443992679651442e-4-4.6211720058436229987e-1i) (num-test (tan 6.28284004019658492979e+00+1.0e+00i) -1.4500326960287694721e-4+7.6159419408485704843e-1i) (num-test (tan 6.28284004019658492979e+00-1.0e+00i) -1.4500326960287694721e-4-7.6159419408485704843e-1i) (num-test (tan -6.28284004019658492979e+00+1.0e+00i) 1.4500326960287694721e-4+7.6159419408485704843e-1i) (num-test (tan -6.28284004019658492979e+00-1.0e+00i) 1.4500326960287694721e-4-7.6159419408485704843e-1i) (num-test (tan 6.28284004019658492979e+00+2.0e+00i) -2.4393395410456728569e-5+9.6402758819508310558e-1i) (num-test (tan 6.28284004019658492979e+00-2.0e+00i) -2.4393395410456728569e-5-9.6402758819508310558e-1i) (num-test (tan -6.28284004019658492979e+00+2.0e+00i) 2.4393395410456728569e-5+9.6402758819508310558e-1i) (num-test (tan -6.28284004019658492979e+00-2.0e+00i) 2.4393395410456728569e-5-9.6402758819508310558e-1i) (num-test (tan 6.28353057416258753420e+00+0.0e+00i) 3.4526699672073518233e-4) (num-test (tan -6.28353057416258753420e+00+0.0e+00i) -3.4526699672073518233e-4) (num-test (tan 6.28353057416258753420e+00+1.19209289550781250e-07i) 3.4526699672073027579e-4+1.1920930376163652988e-7i) (num-test (tan 6.28353057416258753420e+00-1.19209289550781250e-07i) 3.4526699672073027579e-4-1.1920930376163652988e-7i) (num-test (tan -6.28353057416258753420e+00+1.19209289550781250e-07i) -3.4526699672073027579e-4+1.1920930376163652988e-7i) (num-test (tan -6.28353057416258753420e+00-1.19209289550781250e-07i) -3.4526699672073027579e-4-1.1920930376163652988e-7i) (num-test (tan 6.28353057416258753420e+00+5.0e-01i) 2.7153443992641126612e-4+4.6211720058436229974e-1i) (num-test (tan 6.28353057416258753420e+00-5.0e-01i) 2.7153443992641126612e-4-4.6211720058436229974e-1i) (num-test (tan -6.28353057416258753420e+00+5.0e-01i) -2.7153443992641126612e-4+4.6211720058436229974e-1i) (num-test (tan -6.28353057416258753420e+00-5.0e-01i) -2.7153443992641126612e-4-4.6211720058436229974e-1i) (num-test (tan 6.28353057416258753420e+00+1.0e+00i) 1.4500326960267121913e-4+7.6159419408485704832e-1i) (num-test (tan 6.28353057416258753420e+00-1.0e+00i) 1.4500326960267121913e-4-7.6159419408485704832e-1i) (num-test (tan -6.28353057416258753420e+00+1.0e+00i) -1.4500326960267121913e-4+7.6159419408485704832e-1i) (num-test (tan -6.28353057416258753420e+00-1.0e+00i) -1.4500326960267121913e-4-7.6159419408485704832e-1i) (num-test (tan 6.28353057416258753420e+00+2.0e+00i) 2.4393395410422119654e-5+9.6402758819508310555e-1i) (num-test (tan 6.28353057416258753420e+00-2.0e+00i) 2.4393395410422119654e-5-9.6402758819508310555e-1i) (num-test (tan -6.28353057416258753420e+00+2.0e+00i) -2.4393395410422119654e-5+9.6402758819508310555e-1i) (num-test (tan -6.28353057416258753420e+00-2.0e+00i) -2.4393395410422119654e-5-9.6402758819508310555e-1i) (num-test (tan 9.42443269378637893396e+00+0.0e+00i) -3.4526699672045932728e-4) (num-test (tan -9.42443269378637893396e+00+0.0e+00i) 3.4526699672045932728e-4) (num-test (tan 9.42443269378637893396e+00+1.19209289550781250e-07i) -3.4526699672045442074e-4+1.1920930376163652985e-7i) (num-test (tan 9.42443269378637893396e+00-1.19209289550781250e-07i) -3.4526699672045442074e-4-1.1920930376163652985e-7i) (num-test (tan -9.42443269378637893396e+00+1.19209289550781250e-07i) 3.4526699672045442074e-4+1.1920930376163652985e-7i) (num-test (tan -9.42443269378637893396e+00-1.19209289550781250e-07i) 3.4526699672045442074e-4-1.1920930376163652985e-7i) (num-test (tan 9.42443269378637893396e+00+5.0e-01i) -2.7153443992619432056e-4+4.6211720058436229968e-1i) (num-test (tan 9.42443269378637893396e+00-5.0e-01i) -2.7153443992619432056e-4-4.6211720058436229968e-1i) (num-test (tan -9.42443269378637893396e+00+5.0e-01i) 2.7153443992619432056e-4+4.6211720058436229968e-1i) (num-test (tan -9.42443269378637893396e+00-5.0e-01i) 2.7153443992619432056e-4-4.6211720058436229968e-1i) (num-test (tan 9.42443269378637893396e+00+1.0e+00i) -1.4500326960255536711e-4+7.6159419408485704826e-1i) (num-test (tan 9.42443269378637893396e+00-1.0e+00i) -1.4500326960255536711e-4-7.6159419408485704826e-1i) (num-test (tan -9.42443269378637893396e+00+1.0e+00i) 1.4500326960255536711e-4+7.6159419408485704826e-1i) (num-test (tan -9.42443269378637893396e+00-1.0e+00i) 1.4500326960255536711e-4-7.6159419408485704826e-1i) (num-test (tan 9.42443269378637893396e+00+2.0e+00i) -2.4393395410402630273e-5+9.6402758819508310554e-1i) (num-test (tan 9.42443269378637893396e+00-2.0e+00i) -2.4393395410402630273e-5-9.6402758819508310554e-1i) (num-test (tan -9.42443269378637893396e+00+2.0e+00i) 2.4393395410402630273e-5+9.6402758819508310554e-1i) (num-test (tan -9.42443269378637893396e+00-2.0e+00i) 2.4393395410402630273e-5-9.6402758819508310554e-1i) (num-test (tan 9.42512322775237976202e+00+0.0e+00i) 3.4526699671972453911e-4) (num-test (tan -9.42512322775237976202e+00+0.0e+00i) -3.4526699671972453911e-4) (num-test (tan 9.42512322775237976202e+00+1.19209289550781250e-07i) 3.4526699671971963257e-4+1.1920930376163652979e-7i) (num-test (tan 9.42512322775237976202e+00-1.19209289550781250e-07i) 3.4526699671971963257e-4-1.1920930376163652979e-7i) (num-test (tan -9.42512322775237976202e+00+1.19209289550781250e-07i) -3.4526699671971963257e-4+1.1920930376163652979e-7i) (num-test (tan -9.42512322775237976202e+00-1.19209289550781250e-07i) -3.4526699671971963257e-4-1.1920930376163652979e-7i) (num-test (tan 9.42512322775237976202e+00+5.0e-01i) 2.7153443992561644811e-4+4.6211720058436229949e-1i) (num-test (tan 9.42512322775237976202e+00-5.0e-01i) 2.7153443992561644811e-4-4.6211720058436229949e-1i) (num-test (tan -9.42512322775237976202e+00+5.0e-01i) -2.7153443992561644811e-4+4.6211720058436229949e-1i) (num-test (tan -9.42512322775237976202e+00-5.0e-01i) -2.7153443992561644811e-4-4.6211720058436229949e-1i) (num-test (tan 9.42512322775237976202e+00+1.0e+00i) 1.450032696022467750e-4+7.6159419408485704810e-1i) (num-test (tan 9.42512322775237976202e+00-1.0e+00i) 1.450032696022467750e-4-7.6159419408485704810e-1i) (num-test (tan -9.42512322775237976202e+00+1.0e+00i) -1.450032696022467750e-4+7.6159419408485704810e-1i) (num-test (tan -9.42512322775237976202e+00-1.0e+00i) -1.450032696022467750e-4-7.6159419408485704810e-1i) (num-test (tan 9.42512322775237976202e+00+2.0e+00i) 2.439339541035071690e-5+9.6402758819508310550e-1i) (num-test (tan 9.42512322775237976202e+00-2.0e+00i) 2.439339541035071690e-5-9.6402758819508310550e-1i) (num-test (tan -9.42512322775237976202e+00+2.0e+00i) -2.439339541035071690e-5+9.6402758819508310550e-1i) (num-test (tan -9.42512322775237976202e+00-2.0e+00i) -2.439339541035071690e-5-9.6402758819508310550e-1i) (num-test (tan 32767.) 1.9089234430221485740826E-1) (num-test (tan 8388607.) -8.0354556223613614748329E0) (num-test (tan 2147483647.) 1.0523779637351339136698E0) (num-test (tan -2.225073858507201399999999999999999999996E-308) -2.225073858507201399999999999999999999996E-308) (num-test (tan 1.110223024625156799999999999999999999997E-16) 1.110223024625156800000000000000004561517E-16) (num-test (tan (* 1/4 (atan 4))) (* 2 (+ (cos (/ (* 6 pi) 17)) (cos (/ (* 10 pi) 17))))) (num-test (tan (/ pi 10)) (/ (sqrt (- 25 (* 10 (sqrt 5)))) 5)) (num-test (tan (/ pi 12)) (- 2 (sqrt 3))) (num-test (tan (/ pi 12)) (- 2 (sqrt 3))) (num-test (tan (/ pi 16)) (- (sqrt (+ 4 (* 2 (sqrt 2)))) (sqrt 2) 1)) (num-test (tan (/ pi 20)) (+ 1 (sqrt 5) (- (sqrt (+ 5 (* 2 (sqrt 5))))))) (num-test (tan (/ pi 24)) (+ -2 (sqrt 2) (- (sqrt 3)) (sqrt 6))) (num-test (tan (/ pi 3)) (sqrt 3)) (num-test (tan (/ pi 3)) (sqrt 3)) (num-test (tan (/ pi 30)) (sqrt (- 7 (* 2 (sqrt 5)) (* 2 (sqrt (- 15 (* 6 (sqrt 5)))))))) (num-test (tan (/ pi 4)) 1) (num-test (tan (/ pi 4)) 1.0) (num-test (tan (/ pi 4)) 1.0) (num-test (tan (/ pi 5)) (sqrt (- 5 (* 2 (sqrt 5))))) (num-test (tan (/ pi 6)) (/ (sqrt 3) 3)) (num-test (tan (/ pi 6)) (/ (sqrt 3))) (num-test (tan (/ pi 8)) (- (sqrt 2) 1)) (num-test (* (tan (/ pi 11)) (tan (/ (* 2 pi) 11)) (tan (/ (* 3 pi) 11)) (tan (/ (* 4 pi) 11)) (tan (/ (* 5 pi) 11))) (sqrt 11)) (num-test (* (tan (/ pi 9)) (tan (/ (* 2 pi) 9)) (tan (/ (* 4 pi) 9))) (sqrt 3)) (if with-bignums (begin (letrec ((sum-cot (lambda (n) (let ((sum 0.0)) (do ((k 1 (+ k 1))) ((= k n) sum) (set! sum (+ sum (sin (/ (* k pi) n))))))))) (let ((mxerr 0.0) (mxcase 0)) (do ((i 2 (+ i 1))) ((= i 100)) (let ((val1 (sum-cot i)) (val2 (/ 1.0 (tan (/ pi (* 2 i)))))) (let ((err (magnitude (- val1 val2)))) (if (> err mxerr) (begin (set! mxerr err) (set! mxcase i)))))) (if (> mxerr 1e-35) (format-logged #t "sum-cot max error ~A at ~A~%" mxerr mxcase)))) )) (for-each (lambda (num-and-val) (let ((num (car num-and-val)) (val (cadr num-and-val))) (num-test-1 'tan num (tan num) val))) (vector (list 0 0) (list 1 1.5574077246549) (list 2 -2.1850398632615) (list 3 -0.14254654307428) (list -1 -1.5574077246549) (list -2 2.1850398632615) (list -3 0.14254654307428) (list 1/2 0.54630248984379) (list 1/3 0.34625354951058) (list -1/2 -0.54630248984379) (list -1/3 -0.34625354951058) (list 1/9223372036854775807 1.0842021724855e-19) (list 0.0 0.0) (list 1.0 1.5574077246549) (list 2.0 -2.1850398632615) (list -2.0 2.1850398632615) (list 1.000000000000000000000000000000000000002E-309 1.000000000000000000000000000000000000002E-309) (list 0+1i 0+0.76159415595576i) (list 0+2i 0+0.96402758007582i) (list 0-1i 0-0.76159415595576i) (list 1+1i 0.27175258531951+1.0839233273387i) (list 1-1i 0.27175258531951-1.0839233273387i) (list -1+1i -0.27175258531951+1.0839233273387i) (list -1-1i -0.27175258531951-1.0839233273387i) (list 0.1+0.1i 0.099328043521656+0.10066129051146i) (list 1e+16+1e+16i 0+1i) (list 1e-16+1e-16i 1e-16+1e-16i) )) (if with-bignums (let ((old-prec (*s7* 'bignum-precision))) (set! (*s7* 'bignum-precision) 500) (let ((tans (list ; table[Tan[k/10], {k, 0, 30}] 0.00000000000000000000000000000000000000000000000000000000000000000000e0 0.10033467208545054505808004578111153681900480457644204002220806579803 0.20271003550867248332135827164753448262687566965163133004781996689038 0.30933624960962323303530367969829466725781590680046134075142272636569 0.42279321873816176198163542716529033394198977271569358984733094139266 0.54630248984379051325517946578028538329755172017979124616409138593290 0.68413680834169231707092541746333574524265408075678204603738401651742 0.84228838046307944812813500221293771718722125080419899879692251366850 1.02963855705036401274636117282036528416821960677230780766895721581894 1.26015821755033913713457548539574847783362583439629440734976898386523 1.55740772465490223050697480745836017308725077238152003838394660569886 1.96475965724865195093092278177937824371908489378986426895526379547792 2.57215162212631893540999423603336395652940930604338927922563726223880 3.60210244796797815123114551507651373970302582865487479569579648938869 5.79788371548288964370772024360369904599369751893967972517934732424182 14.10141994717171938764608365198775644565954357723586186612326758608969 -34.23253273555741705801487543047619090177569941115323597430813746321248 -7.69660213945915841412819296829866091636528991430764756294574142318097 -4.28626167462806352545188895228026668020736003385824824436108662437549 -2.92709751467777270368689918927087330066328793602580283437505670792996 -2.18503986326151899164330610231368254343201774622766316456295586996677 -1.70984654290450774834778079380390375776090098123394621314534682027235 -1.37382305676879516014003676333346987430263329223370049420804295416122 -1.11921364173413217123235669407622790313829418580200248125375565107236 -0.91601428967341051273086324750810579399364554997699617941685909082222 -0.74702229723866027935535268782527455790411695688301127906659308970027 -0.60159661308975872273608189269127978293417758666969145078057164875561 -0.47272762910303750795198918126389516105797171531608327694222778882857 -0.35552983165117587757735260363543503816953711960914396739605909199266 -0.24640539397196625534356707388530576476208894415934539659747894722272 -0.14254654307427780529563541053391349322609228490180464763323897668885))) (do ((i 0 (+ i 1))) ((= i 30)) (let ((val (tan (/ i (bignum "10"))))) (if (> (magnitude (- val (list-ref tans i))) 1e-35) (format-logged #t ";(tan ~A) -> ~A ~A~%[~A]~%" (/ i 10) val (list-ref tans i) (magnitude (- val (list-ref tans i)))))))) (set! (*s7* 'bignum-precision) old-prec))) (test (tan) 'error) (test (tan "hi") 'error) (test (tan 1.0+23.0i 1.0+23.0i) 'error) (test (tan 0 1) 'error) (for-each (lambda (arg) (test (tan arg) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) ;;; -------------------------------------------------------------------------------- ;;; asin ;;; -------------------------------------------------------------------------------- (num-test (asin 0) 0.0) (num-test (asin 1) 1.57079632679490) (num-test (asin -1) -1.57079632679490) (num-test (asin 2) 1.57079632679490+1.31695789692482i) (num-test (asin -2) -1.57079632679490+1.31695789692482i) (num-test (asin 3) 1.57079632679490+1.76274717403909i) (num-test (asin -3) -1.57079632679490+1.76274717403909i) (num-test (asin 10) 1.57079632679490+2.99322284612638i) (num-test (asin -10) -1.57079632679490+2.99322284612638i) (num-test (asin 1234) 1.57079632679490+7.81116322068415i) (num-test (asin -1234) -1.57079632679490+7.81116322068415i) (num-test (asin 0/1) 0.0) (num-test (asin 0/2) 0.0) (num-test (asin 0/3) 0.0) (num-test (asin 0/10) 0.0) (num-test (asin 0/1234) 0.0) (num-test (asin 0/1234000000) 0.0) (num-test (asin 0/500029) 0.0) (num-test (asin 0/362880) 0.0) (num-test (asin 1/1) 1.57079632679490) (num-test (asin -1/1) -1.57079632679490) (num-test (asin 1/2) 0.52359877559830) (num-test (asin -1/2) -0.52359877559830) (num-test (asin 1/3) 0.33983690945412) (num-test (asin -1/3) -0.33983690945412) (num-test (asin 1/10) 0.10016742116156) (num-test (asin -1/10) -0.10016742116156) (num-test (asin 1/1234) 0.00081037286017) (num-test (asin -1/1234) -0.00081037286017) (num-test (asin 1/1234000000) 0.00000000081037) (num-test (asin -1/1234000000) -0.00000000081037) (num-test (asin 1/500029) 0.00000199988401) (num-test (asin -1/500029) -0.00000199988401) (num-test (asin 1/362880) 0.00000275573192) (num-test (asin -1/362880) -0.00000275573192) (num-test (asin 2/1) 1.57079632679490+1.31695789692482i) (num-test (asin -2/1) -1.57079632679490+1.31695789692482i) (num-test (asin 2/2) 1.57079632679490) (num-test (asin -2/2) -1.57079632679490) (num-test (asin 2/3) 0.72972765622697) (num-test (asin -2/3) -0.72972765622697) (num-test (asin 2/10) 0.20135792079033) (num-test (asin -2/10) -0.20135792079033) (num-test (asin 2/1234) 0.00162074625252) (num-test (asin -2/1234) -0.00162074625252) (num-test (asin 2/1234000000) 0.00000000162075) (num-test (asin -2/1234000000) -0.00000000162075) (num-test (asin 2/500029) 0.00000399976801) (num-test (asin -2/500029) -0.00000399976801) (num-test (asin 2/362880) 0.00000551146384) (num-test (asin -2/362880) -0.00000551146384) (num-test (asin 3/1) 1.57079632679490+1.76274717403909i) (num-test (asin -3/1) -1.57079632679490+1.76274717403909i) (num-test (asin 3/2) 1.57079632679490+0.96242365011921i) (num-test (asin -3/2) -1.57079632679490+0.96242365011921i) (num-test (asin 3/3) 1.57079632679490) (num-test (asin -3/3) -1.57079632679490) (num-test (asin 3/10) 0.30469265401540) (num-test (asin -3/10) -0.30469265401540) (num-test (asin 3/1234) 0.00243112070922) (num-test (asin -3/1234) -0.00243112070922) (num-test (asin 3/1234000000) 0.00000000243112) (num-test (asin -3/1234000000) -0.00000000243112) (num-test (asin 3/500029) 0.00000599965202) (num-test (asin -3/500029) -0.00000599965202) (num-test (asin 3/362880) 0.00000826719577) (num-test (asin -3/362880) -0.00000826719577) (num-test (asin 10/1) 1.57079632679490+2.99322284612638i) (num-test (asin -10/1) -1.57079632679490+2.99322284612638i) (num-test (asin 10/2) 1.57079632679490+2.29243166956117i) (num-test (asin -10/2) -1.57079632679490+2.29243166956117i) (num-test (asin 10/3) 1.57079632679490+1.87382024252741i) (num-test (asin -10/3) -1.57079632679490+1.87382024252741i) (num-test (asin 10/10) 1.57079632679490) (num-test (asin -10/10) -1.57079632679490) (num-test (asin 10/1234) 0.00810381641321) (num-test (asin -10/1234) -0.00810381641321) (num-test (asin 10/1234000000) 0.00000000810373) (num-test (asin -10/1234000000) -0.00000000810373) (num-test (asin 10/500029) 0.00001999884007) (num-test (asin -10/500029) -0.00001999884007) (num-test (asin 10/362880) 0.00002755731923) (num-test (asin -10/362880) -0.00002755731923) (num-test (asin 1234/1) 1.57079632679490+7.81116322068415i) (num-test (asin -1234/1) -1.57079632679490+7.81116322068415i) (num-test (asin 1234/2) 1.57079632679490+7.11801554770806i) (num-test (asin -1234/2) -1.57079632679490+7.11801554770806i) (num-test (asin 1234/3) 1.57079632679490+6.71254961876657i) (num-test (asin -1234/3) -1.57079632679490+6.71254961876657i) (num-test (asin 1234/10) 1.57079632679490+5.50856187402751i) (num-test (asin -1234/10) -1.57079632679490+5.50856187402751i) (num-test (asin 1234/1234) 1.57079632679490) (num-test (asin -1234/1234) -1.57079632679490) (num-test (asin 1234/1234000000) 0.00000100000000) (num-test (asin -1234/1234000000) -0.00000100000000) (num-test (asin 1234/500029) 0.00246785936931) (num-test (asin -1234/500029) -0.00246785936931) (num-test (asin 1234/362880) 0.00340057974625) (num-test (asin -1234/362880) -0.00340057974625) (num-test (asin 1234000000/1234000000) 1.57079632679490) (num-test (asin -1234000000/1234000000) -1.57079632679490) (num-test (asin 1234000000/500029) 1.57079632679490+8.50425252675189i) (num-test (asin -1234000000/500029) -1.57079632679490+8.50425252675189i) (num-test (asin 1234000000/362880) 1.57079632679490+8.82484644053502i) (num-test (asin -1234000000/362880) -1.57079632679490+8.82484644053502i) (num-test (asin 500029/3) 1.570796326794897-12.71695626760523i) (num-test (asin -500029/3) -1.570796326794897+12.71695626760523i) (num-test (asin 500029/10) 1.570796326794897-1.151298346318831e1i) (num-test (asin -500029/10) -1.57079632679490+1.151298346318831e1i) (num-test (asin 500029/1234) 1.57079632679490+6.69755082925184i) (num-test (asin -500029/1234) -1.57079632679490+6.69755082925184i) (num-test (asin 500029/1234000000) 0.00040520989764) (num-test (asin -500029/1234000000) -0.00040520989764) (num-test (asin 500029/500029) 1.57079632679490) (num-test (asin -500029/500029) -1.57079632679490) (num-test (asin 500029/362880) 1.57079632679490+0.84413377868249i) (num-test (asin -500029/362880) -1.57079632679490+0.84413377868249i) (num-test (asin 362880/2) 1.570796326794896619231321691639751442098E0-1.280182748007387555277950474671339683536E1i) (num-test (asin -362880/2) -1.570796326794897+12.80182748007388i) (num-test (asin 362880/3) 1.570796326794896619231321691639751442098E0-1.239636237195621859776598192721440899765E1i) (num-test (asin -362880/3) -1.570796326794897+12.39636237195622i) (num-test (asin 362880/10) 1.570796326794897-1.119238956745752e1i) (num-test (asin -362880/10) -1.57079632679490+1.119238956745752e1i) (num-test (asin 362880/1234) 1.57079632679490+6.37695556516894i) (num-test (asin -362880/1234) -1.57079632679490+6.37695556516894i) (num-test (asin 362880/1234000000) 0.00029406807555) (num-test (asin -362880/1234000000) -0.00029406807555) (num-test (asin 362880/500029) 0.81207730383580) (num-test (asin -362880/500029) -0.81207730383580) (num-test (asin 362880/362880) 1.57079632679490) (num-test (asin -362880/362880) -1.57079632679490) (num-test (asin 0.0) 0.0) (num-test (asin 0.00000001) 0.00000001) (num-test (asin -0.00000001) -0.00000001) (num-test (asin 1.0) 1.57079632679490) (num-test (asin -1.0) -1.57079632679490) (num-test (asin pi) 1.57079632679490+1.81152627246085i) (num-test (asin -3.14159265358979) -1.57079632679490+1.81152627246085i) (num-test (asin 2.71828182845905) 1.57079632679490+1.65745445415308i) (num-test (asin -2.71828182845905) -1.57079632679490+1.65745445415308i) (num-test (asin 1234.0) 1.57079632679490+7.81116322068415i) (num-test (asin -1234.0) -1.57079632679490+7.81116322068415i) (num-test (asin 0.0+0.0i) 0.0) (num-test (asin -0.0+0.0i) 0.0) (num-test (asin 0.0-0.0i) 0.0) (num-test (asin -0.0-0.0i) 0.0) (num-test (asin 0.0+0.00000001i) 0.0+0.00000001i) (num-test (asin -0.0+0.00000001i) 0.0+0.00000001i) (num-test (asin 0.0-0.00000001i) 0.0-0.00000001i) (num-test (asin -0.0-0.00000001i) -0.0-0.00000001i) (num-test (asin 0.0+1.0i) 0.0+0.88137358701954i) (num-test (asin -0.0+1.0i) 0.0+0.88137358701954i) (num-test (asin 0.0-1.0i) 0.0-0.88137358701954i) (num-test (asin -0.0-1.0i) -0.0-0.88137358701954i) (num-test (asin 0.0+3.14159265358979i) 0.0+1.86229574331085i) (num-test (asin -0.0+3.14159265358979i) 0.0+1.86229574331085i) (num-test (asin 0.0-3.14159265358979i) 0.0-1.86229574331085i) (num-test (asin -0.0-3.14159265358979i) -0.0-1.86229574331085i) (num-test (asin 0.0+2.71828182845905i) 0.0+1.72538255885232i) (num-test (asin -0.0+2.71828182845905i) 0.0+1.72538255885232i) (num-test (asin 0.0-2.71828182845905i) 0.0-1.72538255885231i) (num-test (asin -0.0-2.71828182845905i) -0.0-1.72538255885231i) (num-test (asin 0.0+1234.0i) 0.0+7.81116354896171i) (num-test (asin -0.0+1234.0i) 0.0+7.81116354896171i) (num-test (asin 0.0-1234.0i) 0.0-7.81116354920125i) (num-test (asin -0.0-1234.0i) -0.0-7.81116354920125i) (num-test (asin 0.0-1234000000.0i) 0.0-21.62667394298955i) (num-test (asin -0.0-1234000000.0i) -0.0-21.62667394298955i) (num-test (asin 0.00000001+0.0i) 0.00000001) (num-test (asin -0.00000001+0.0i) -0.00000001) (num-test (asin 0.00000001-0.0i) 0.00000001) (num-test (asin -0.00000001-0.0i) -0.00000001) (num-test (asin 0.00000001+0.00000001i) 0.00000001+0.00000001i) (num-test (asin -0.00000001+0.00000001i) -0.00000001+0.00000001i) (num-test (asin 0.00000001-0.00000001i) 0.00000001-0.00000001i) (num-test (asin -0.00000001-0.00000001i) -0.00000001-0.00000001i) (num-test (asin 0.00000001+1.0i) 0.00000000707107+0.88137358701954i) (num-test (asin -0.00000001+1.0i) -0.00000000707107+0.88137358701954i) (num-test (asin 0.00000001-1.0i) 0.00000000707107-0.88137358701954i) (num-test (asin -0.00000001-1.0i) -0.00000000707107-0.88137358701954i) (num-test (asin 0.00000001+3.14159265358979i) 0.00000000303314+1.86229574331085i) (num-test (asin -0.00000001+3.14159265358979i) -0.00000000303314+1.86229574331085i) (num-test (asin 0.00000001-3.14159265358979i) 0.00000000303314-1.86229574331085i) (num-test (asin -0.00000001-3.14159265358979i) -0.00000000303314-1.86229574331085i) (num-test (asin 0.00000001+2.71828182845905i) 0.00000000345258+1.72538255885232i) (num-test (asin -0.00000001+2.71828182845905i) -0.00000000345258+1.72538255885232i) (num-test (asin 0.00000001-2.71828182845905i) 0.00000000345258-1.72538255885231i) (num-test (asin -0.00000001-2.71828182845905i) -0.00000000345258-1.72538255885231i) (num-test (asin 0.00000001+1234.0i) 0.00000000000810+7.81116354896171i) (num-test (asin -0.00000001+1234.0i) -0.00000000000810+7.81116354896171i) (num-test (asin 0.00000001-1234.0i) 0.00000000000810-7.81116354920125i) (num-test (asin -0.00000001-1234.0i) -0.00000000000810-7.81116354920125i) (num-test (asin 0.00000001-1234000000.0i) 0.0-21.62667394298955i) (num-test (asin -0.00000001-1234000000.0i) -0.0-21.62667394298955i) (num-test (asin 1.0+0.0i) 1.57079632679490) (num-test (asin -1.0+0.0i) -1.57079632679490) (num-test (asin 1.0-0.0i) 1.57079632679490) (num-test (asin -1.0-0.0i) -1.57079632679490) (num-test (asin 1.0+0.00000001i) 1.57069632679498+0.00010000000008i) (num-test (asin -1.0+0.00000001i) -1.57069632679498+0.00010000000008i) (num-test (asin 1.0-0.00000001i) 1.57069632679498-0.00010000000008i) (num-test (asin -1.0-0.00000001i) -1.57069632679498-0.00010000000008i) (num-test (asin 1.0+1.0i) 0.66623943249252+1.06127506190504i) (num-test (asin -1.0+1.0i) -0.66623943249252+1.06127506190504i) (num-test (asin 1.0-1.0i) 0.66623943249252-1.06127506190504i) (num-test (asin -1.0-1.0i) -0.66623943249252-1.06127506190504i) (num-test (asin 1.0+3.14159265358979i) 0.29558503421163+1.90462768697066i) (num-test (asin -1.0+3.14159265358979i) -0.29558503421163+1.90462768697066i) (num-test (asin 1.0-3.14159265358979i) 0.29558503421163-1.90462768697066i) (num-test (asin -1.0-3.14159265358979i) -0.29558503421163-1.90462768697066i) (num-test (asin 1.0+2.71828182845905i) 0.33444277187637+1.77905438385935i) (num-test (asin -1.0+2.71828182845905i) -0.33444277187637+1.77905438385935i) (num-test (asin 1.0-2.71828182845905i) 0.33444277187637-1.77905438385935i) (num-test (asin -1.0-2.71828182845905i) -0.33444277187637-1.77905438385935i) (num-test (asin 1.0+1234.0i) 0.00081037232806+7.81116387772663i) (num-test (asin -1.0+1234.0i) -0.00081037232806+7.81116387772663i) (num-test (asin 1.0-1234.0i) 0.00081037232800-7.81116387755283i) (num-test (asin -1.0-1234.0i) -0.00081037232800-7.81116387755283i) (num-test (asin 1.0-1234000000.0i) 0.00000000081037-21.62667394298955i) (num-test (asin -1.0-1234000000.0i) -0.00000000081037-21.62667394298955i) (num-test (asin 3.14159265358979+0.0i) 1.57079632679490+1.81152627246085i) (num-test (asin -3.14159265358979+0.0i) -1.57079632679490+1.81152627246085i) (num-test (asin 3.14159265358979-0.0i) 1.57079632679490+1.81152627246085i) (num-test (asin -3.14159265358979-0.0i) -1.57079632679490+1.81152627246085i) (num-test (asin 3.14159265358979+0.00000001i) 1.57079632343715+1.81152627246085i) (num-test (asin -3.14159265358979+0.00000001i) -1.57079632343715+1.81152627246085i) (num-test (asin 3.14159265358979-0.00000001i) 1.57079632343715-1.81152627246085i) (num-test (asin -3.14159265358979-0.00000001i) -1.57079632343715-1.81152627246085i) (num-test (asin 3.14159265358979+1.0i) 1.24854303281344+1.86711439316026i) (num-test (asin -3.14159265358979+1.0i) -1.24854303281344+1.86711439316026i) (num-test (asin 3.14159265358979-1.0i) 1.24854303281344-1.86711439316026i) (num-test (asin -3.14159265358979-1.0i) -1.24854303281344-1.86711439316026i) (num-test (asin 3.14159265358979+3.14159265358979i) 0.77273977912748+2.18469104082751i) (num-test (asin -3.14159265358979+3.14159265358979i) -0.77273977912748+2.18469104082751i) (num-test (asin 3.14159265358979-3.14159265358979i) 0.77273977912748-2.18469104082751i) (num-test (asin -3.14159265358979-3.14159265358979i) -0.77273977912748-2.18469104082751i) (num-test (asin 3.14159265358979+2.71828182845905i) 0.84309656416035+2.11552790803290i) (num-test (asin -3.14159265358979+2.71828182845905i) -0.84309656416035+2.11552790803290i) (num-test (asin 3.14159265358979-2.71828182845905i) 0.84309656416035-2.11552790803290i) (num-test (asin -3.14159265358979-2.71828182845905i) -0.84309656416035-2.11552790803290i) (num-test (asin 3.14159265358979+1234.0i) 0.00254585480900+7.81116678966949i) (num-test (asin -3.14159265358979+1234.0i) -0.00254585480900+7.81116678966949i) (num-test (asin 3.14159265358979-1234.0i) 0.00254585480937-7.81116678989204i) (num-test (asin -3.14159265358979-1234.0i) -0.00254585480937-7.81116678989204i) (num-test (asin 3.14159265358979-1234000000.0i) 0.00000000254586-21.62667394298955i) (num-test (asin -3.14159265358979-1234000000.0i) -0.00000000254586-21.62667394298955i) (num-test (asin 2.71828182845905+0.0i) 1.57079632679490+1.65745445415308i) (num-test (asin -2.71828182845905+0.0i) -1.57079632679490+1.65745445415308i) (num-test (asin 2.71828182845905-0.0i) 1.57079632679490+1.65745445415308i) (num-test (asin -2.71828182845905-0.0i) -1.57079632679490+1.65745445415308i) (num-test (asin 2.71828182845905+0.00000001i) 1.57079632283867+1.65745445415308i) (num-test (asin -2.71828182845905+0.00000001i) -1.57079632283867+1.65745445415308i) (num-test (asin 2.71828182845905-0.00000001i) 1.57079632283867-1.65745445415308i) (num-test (asin -2.71828182845905-0.00000001i) -1.57079632283867-1.65745445415308i) (num-test (asin 2.71828182845905+1.0i) 1.19757808518581+1.73375471569385i) (num-test (asin -2.71828182845905+1.0i) -1.19757808518581+1.73375471569385i) (num-test (asin 2.71828182845905-1.0i) 1.19757808518581-1.73375471569385i) (num-test (asin -2.71828182845905-1.0i) -1.19757808518581-1.73375471569385i) (num-test (asin 2.71828182845905+3.14159265358979i) 0.69904796994656+2.11968336368048i) (num-test (asin -2.71828182845905+3.14159265358979i) -0.69904796994656+2.11968336368048i) (num-test (asin 2.71828182845905-3.14159265358979i) 0.69904796994655-2.11968336368048i) (num-test (asin -2.71828182845905-3.14159265358979i) -0.69904796994655-2.11968336368048i) (num-test (asin 2.71828182845905+2.71828182845905i) 0.76849735588475+2.04014932880026i) (num-test (asin -2.71828182845905+2.71828182845905i) -0.76849735588475+2.04014932880026i) (num-test (asin 2.71828182845905-2.71828182845905i) 0.76849735588475-2.04014932880026i) (num-test (asin -2.71828182845905-2.71828182845905i) -0.76849735588475-2.04014932880026i) (num-test (asin 2.71828182845905+1234.0i) 0.00220281729236+7.81116597510553i) (num-test (asin -2.71828182845905+1234.0i) -0.00220281729236+7.81116597510553i) (num-test (asin 2.71828182845905-1234.0i) 0.00220281729269-7.81116597540442i) (num-test (asin -2.71828182845905-1234.0i) -0.00220281729269-7.81116597540442i) (num-test (asin 2.71828182845905-1234000000.0i) 0.00000000220282-21.62667394298955i) (num-test (asin -2.71828182845905-1234000000.0i) -0.00000000220282-21.62667394298955i) (num-test (asin 1234.0+0.0i) 1.57079632679490+7.81116322068415i) (num-test (asin -1234.0+0.0i) -1.57079632679490+7.81116322068415i) (num-test (asin 1234.0-0.0i) 1.57079632679490+7.81116322068415i) (num-test (asin -1234.0-0.0i) -1.57079632679490+7.81116322068415i) (num-test (asin 1234.0+0.00000001i) 1.57079632678679+7.81116322068415i) (num-test (asin -1234.0+0.00000001i) -1.57079632678679+7.81116322068415i) (num-test (asin 1234.0-0.00000001i) 1.57079632678679-7.81116322084923i) (num-test (asin -1234.0-0.00000001i) -1.57079632678679-7.81116322084923i) (num-test (asin 1234.0+1.0i) 1.56998595393442+7.81116354944842i) (num-test (asin -1234.0+1.0i) -1.56998595393442+7.81116354944842i) (num-test (asin 1234.0-1.0i) 1.56998595393473-7.81116354920146i) (num-test (asin -1234.0-1.0i) -1.56998595393473-7.81116354920146i) (num-test (asin 1234.0+3.14159265358979i) 1.56825047031506+7.81116646138554i) (num-test (asin -1234.0+3.14159265358979i) -1.56825047031506+7.81116646138554i) (num-test (asin 1234.0-3.14159265358979i) 1.56825047031367-7.81116646154641i) (num-test (asin -1234.0-3.14159265358979i) -1.56825047031367-7.81116646154641i) (num-test (asin 1234.0+2.71828182845905i) 1.56859350805543+7.81116564738434i) (num-test (asin -1234.0+2.71828182845905i) -1.56859350805543+7.81116564738434i) (num-test (asin 1234.0-2.71828182845905i) 1.56859350805562-7.81116564705719i) (num-test (asin -1234.0-2.71828182845905i) -1.56859350805562-7.81116564705719i) (num-test (asin 1234.0+1234.0i) 0.78539808146835+8.15773697538346i) (num-test (asin -1234.0+1234.0i) -0.78539808146835+8.15773697538346i) (num-test (asin 1234.0-1234.0i) 0.78539808130944-8.15773697530526i) (num-test (asin -1234.0-1234.0i) -0.78539808130944-8.15773697530526i) (num-test (asin 1234.0-1234000000.0i) 0.00000100000000-21.62667394299005i) (num-test (asin -1234.0-1234000000.0i) -0.00000100000000-21.62667394299005i) (num-test (asin 1234000000.0-0.00000001i) 1.57079632679490-21.62667394298955i) (num-test (asin -1234000000.0-0.00000001i) -1.57079632679490-21.62667394298955i) (num-test (asin 1234000000.0-1.0i) 1.57079632598452-21.62667394298955i) (num-test (asin -1234000000.0-1.0i) -1.57079632598452-21.62667394298955i) (num-test (asin 1234000000.0-3.14159265358979i) 1.57079632424904-21.62667394298955i) (num-test (asin -1234000000.0-3.14159265358979i) -1.57079632424904-21.62667394298955i) (num-test (asin 1234000000.0-2.71828182845905i) 1.57079632459208-21.62667394298955i) (num-test (asin -1234000000.0-2.71828182845905i) -1.57079632459208-21.62667394298955i) (num-test (asin 1234000000.0-1234.0i) 1.57079532679490-21.62667394299005i) (num-test (asin -1234000000.0-1234.0i) -1.57079532679490-21.62667394299005i) (num-test (asin 1234000000.0-1234000000.0i) 0.78539816339745-21.97324753326953i) (num-test (asin -1234000000.0-1234000000.0i) -0.78539816339745-21.97324753326953i) (num-test (asin 8.2729394e-17) 8.2729394e-17) (num-test (asin 1.821832e-231) 1.821832e-231) (num-test (asin 48983.30495194942-64983.97008730317i) 0.6459128607940432-12i) (num-test (asin 1234000000/3) 1.570796326794897-20.52806165432143i) (num-test (asin 500029/2) 1.570796326794897-13.12242137571839i) (num-test (asin 0.00000001+1234000000.0i) +8.103725052149596E-18+21.62667380877375i) (num-test (asin 3.14159265358979+1234000000.0i) +2.545860611523387E-9+21.62667380877375i) (num-test (asin 2.71828182845905+1234000000.0i) +2.2028207814967068E-9+21.62667380877375i) (num-test (asin 1234000000.0+0.00000001i) +1.570796327200083+21.62667394298955i) (num-test (asin 1234000000.0+3.14159265358979i) +1.570796327200083+21.62667394298955i) (num-test (asin 0.0e+00+0.0e+00i) 0e0+0.0i) (num-test (asin 0.0e+00+1.19209289550781250e-07i) 0+1.1920928955078096766e-7i) (num-test (asin 0.0e+00-1.19209289550781250e-07i) 0-1.1920928955078096766e-7i) (num-test (asin 0.0e+00+5.0e-01i) 0+4.8121182505960344750e-1i) (num-test (asin 0.0e+00-5.0e-01i) 0-4.8121182505960344750e-1i) (num-test (asin 0.0e+00+1.0e+00i) 0+8.8137358701954302523e-1i) (num-test (asin 0.0e+00-1.0e+00i) 0-8.8137358701954302523e-1i) (num-test (asin 0.0e+00+2.0e+00i) 0+1.4436354751788103425e0i) (num-test (asin 0.0e+00-2.0e+00i) 0-1.4436354751788103425e0i) (num-test (asin 0.0e+00+8.3886080e+06i) 0+1.6635532333438690979e1i) (num-test (asin 0.0e+00-8.3886080e+06i) 0-1.6635532333438690979e1i) (num-test (asin 1.19209289550781250e-07+0.0e+00i) 1.1920928955078153234e-7) (num-test (asin -1.19209289550781250e-07+0.0e+00i) -1.1920928955078153234e-7) (num-test (asin 1.19209289550781250e-07+1.19209289550781250e-07i) 1.1920928955078068531e-7+1.1920928955078181469e-7i) (num-test (asin 1.19209289550781250e-07-1.19209289550781250e-07i) 1.1920928955078068531e-7-1.1920928955078181469e-7i) (num-test (asin -1.19209289550781250e-07+1.19209289550781250e-07i) -1.1920928955078068531e-7+1.1920928955078181469e-7i) (num-test (asin -1.19209289550781250e-07-1.19209289550781250e-07i) -1.1920928955078068531e-7-1.1920928955078181469e-7i) (num-test (asin 1.19209289550781250e-07+5.0e-01i) 1.0662402999400097805e-7+4.8121182505960598961e-1i) (num-test (asin 1.19209289550781250e-07-5.0e-01i) 1.0662402999400097805e-7-4.8121182505960598961e-1i) (num-test (asin -1.19209289550781250e-07+5.0e-01i) -1.0662402999400097805e-7+4.8121182505960598961e-1i) (num-test (asin -1.19209289550781250e-07-5.0e-01i) -1.0662402999400097805e-7-4.8121182505960598961e-1i) (num-test (asin 1.19209289550781250e-07+1.0e+00i) 8.4293697021788013662e-8+8.8137358701954553738e-1i) (num-test (asin 1.19209289550781250e-07-1.0e+00i) 8.4293697021788013662e-8-8.8137358701954553738e-1i) (num-test (asin -1.19209289550781250e-07+1.0e+00i) -8.4293697021788013662e-8+8.8137358701954553738e-1i) (num-test (asin -1.19209289550781250e-07-1.0e+00i) -8.4293697021788013662e-8-8.8137358701954553738e-1i) (num-test (asin 1.19209289550781250e-07+2.0e+00i) 5.3312014997000413263e-8+1.4436354751788116136e0i) (num-test (asin 1.19209289550781250e-07-2.0e+00i) 5.3312014997000413263e-8-1.4436354751788116136e0i) (num-test (asin -1.19209289550781250e-07+2.0e+00i) -5.3312014997000413263e-8+1.4436354751788116136e0i) (num-test (asin -1.19209289550781250e-07-2.0e+00i) -5.3312014997000413263e-8-1.4436354751788116136e0i) (num-test (asin 1.19209289550781250e-07+8.3886080e+06i) 1.4210854715201902743e-14+1.6635532333438690979e1i) (num-test (asin 1.19209289550781250e-07-8.3886080e+06i) 1.4210854715201902743e-14-1.6635532333438690979e1i) (num-test (asin -1.19209289550781250e-07+8.3886080e+06i) -1.4210854715201902743e-14+1.6635532333438690979e1i) (num-test (asin -1.19209289550781250e-07-8.3886080e+06i) -1.4210854715201902743e-14-1.6635532333438690979e1i) (num-test (asin 5.0e-01+0.0e+00i) 5.2359877559829887308e-1) (num-test (asin -5.0e-01+0.0e+00i) -5.2359877559829887308e-1) (num-test (asin 5.0e-01+1.19209289550781250e-07i) 5.2359877559829340332e-1+1.3765103082409432364e-7i) (num-test (asin 5.0e-01-1.19209289550781250e-07i) 5.2359877559829340332e-1-1.3765103082409432364e-7i) (num-test (asin -5.0e-01+1.19209289550781250e-07i) -5.2359877559829340332e-1+1.3765103082409432364e-7i) (num-test (asin -5.0e-01-1.19209289550781250e-07i) -5.2359877559829340332e-1-1.3765103082409432364e-7i) (num-test (asin 5.0e-01+5.0e-01i) 4.5227844715119068206e-1+5.3063753095251782602e-1i) (num-test (asin 5.0e-01-5.0e-01i) 4.5227844715119068206e-1-5.3063753095251782602e-1i) (num-test (asin -5.0e-01+5.0e-01i) -4.5227844715119068206e-1+5.3063753095251782602e-1i) (num-test (asin -5.0e-01-5.0e-01i) -4.5227844715119068206e-1-5.3063753095251782602e-1i) (num-test (asin 5.0e-01+1.0e+00i) 3.4943906285721329363e-1+9.2613303135018242455e-1i) (num-test (asin 5.0e-01-1.0e+00i) 3.4943906285721329363e-1-9.2613303135018242455e-1i) (num-test (asin -5.0e-01+1.0e+00i) -3.4943906285721329363e-1+9.2613303135018242455e-1i) (num-test (asin -5.0e-01-1.0e+00i) -3.4943906285721329363e-1-9.2613303135018242455e-1i) (num-test (asin 5.0e-01+2.0e+00i) 2.2101863562288385890e-1+1.4657153519472905218e0i) (num-test (asin 5.0e-01-2.0e+00i) 2.2101863562288385890e-1-1.4657153519472905218e0i) (num-test (asin -5.0e-01+2.0e+00i) -2.2101863562288385890e-1+1.4657153519472905218e0i) (num-test (asin -5.0e-01-2.0e+00i) -2.2101863562288385890e-1-1.4657153519472905218e0i) (num-test (asin 5.0e-01+8.3886080e+06i) 5.9604644775390130897e-8+1.6635532333438692755e1i) (num-test (asin 5.0e-01-8.3886080e+06i) 5.9604644775390130897e-8-1.6635532333438692755e1i) (num-test (asin -5.0e-01+8.3886080e+06i) -5.9604644775390130897e-8+1.6635532333438692755e1i) (num-test (asin -5.0e-01-8.3886080e+06i) -5.9604644775390130897e-8-1.6635532333438692755e1i) (num-test (asin 1.0e+00+0.0e+00i) 1.5707963267948966192e0) (num-test (asin -1.0e+00+0.0e+00i) -1.5707963267948966192e0) (num-test (asin 1.0e+00+1.19209289550781250e-07i) 1.5704510598153252947e0+3.4526698643116312881e-4i) (num-test (asin 1.0e+00-1.19209289550781250e-07i) 1.5704510598153252947e0-3.4526698643116312881e-4i) (num-test (asin -1.0e+00+1.19209289550781250e-07i) -1.5704510598153252947e0+3.4526698643116312881e-4i) (num-test (asin -1.0e+00-1.19209289550781250e-07i) -1.5704510598153252947e0-3.4526698643116312881e-4i) (num-test (asin 1.0e+00+5.0e-01i) 8.9590748120889023907e-1+7.3285767597364526089e-1i) (num-test (asin 1.0e+00-5.0e-01i) 8.9590748120889023907e-1-7.3285767597364526089e-1i) (num-test (asin -1.0e+00+5.0e-01i) -8.9590748120889023907e-1+7.3285767597364526089e-1i) (num-test (asin -1.0e+00-5.0e-01i) -8.9590748120889023907e-1-7.3285767597364526089e-1i) (num-test (asin 1.0e+00+1.0e+00i) 6.6623943249251525510e-1+1.0612750619050356520e0i) (num-test (asin 1.0e+00-1.0e+00i) 6.6623943249251525510e-1-1.0612750619050356520e0i) (num-test (asin -1.0e+00+1.0e+00i) -6.6623943249251525510e-1+1.0612750619050356520e0i) (num-test (asin -1.0e+00-1.0e+00i) -6.6623943249251525510e-1-1.0612750619050356520e0i) (num-test (asin 1.0e+00+2.0e+00i) 4.2707858639247612548e-1+1.5285709194809981613e0i) (num-test (asin 1.0e+00-2.0e+00i) 4.2707858639247612548e-1-1.5285709194809981613e0i) (num-test (asin -1.0e+00+2.0e+00i) -4.2707858639247612548e-1+1.5285709194809981613e0i) (num-test (asin -1.0e+00-2.0e+00i) -4.2707858639247612548e-1-1.5285709194809981613e0i) (num-test (asin 1.0e+00+8.3886080e+06i) 1.1920928955077983828e-7+1.6635532333438698084e1i) (num-test (asin 1.0e+00-8.3886080e+06i) 1.1920928955077983828e-7-1.6635532333438698084e1i) (num-test (asin -1.0e+00+8.3886080e+06i) -1.1920928955077983828e-7+1.6635532333438698084e1i) (num-test (asin -1.0e+00-8.3886080e+06i) -1.1920928955077983828e-7-1.6635532333438698084e1i) (num-test (asin 2.0e+00+0.0e+00i) 1.5707963267948966192e0-1.3169578969248167086e0i) (num-test (asin -2.0e+00+0.0e+00i) -1.5707963267948966192e0+1.3169578969248167086e0i) (num-test (asin 2.0e+00+1.19209289550781250e-07i) 1.5707962579693812072e0+1.3169578969248194435e0i) (num-test (asin 2.0e+00-1.19209289550781250e-07i) 1.5707962579693812072e0-1.3169578969248194435e0i) (num-test (asin -2.0e+00+1.19209289550781250e-07i) -1.5707962579693812072e0+1.3169578969248194435e0i) (num-test (asin -2.0e+00-1.19209289550781250e-07i) -1.5707962579693812072e0-1.3169578969248194435e0i) (num-test (asin 2.0e+00+5.0e-01i) 1.2930420702371826591e0+1.3618009008578457882e0i) (num-test (asin 2.0e+00-5.0e-01i) 1.2930420702371826591e0-1.3618009008578457882e0i) (num-test (asin -2.0e+00+5.0e-01i) -1.2930420702371826591e0+1.3618009008578457882e0i) (num-test (asin -2.0e+00-5.0e-01i) -1.2930420702371826591e0-1.3618009008578457882e0i) (num-test (asin 2.0e+00+1.0e+00i) 1.0634400235777520562e0+1.4693517443681852733e0i) (num-test (asin 2.0e+00-1.0e+00i) 1.0634400235777520562e0-1.4693517443681852733e0i) (num-test (asin -2.0e+00+1.0e+00i) -1.0634400235777520562e0+1.4693517443681852733e0i) (num-test (asin -2.0e+00-1.0e+00i) -1.0634400235777520562e0-1.4693517443681852733e0i) (num-test (asin 2.0e+00+2.0e+00i) 7.5424914469804604071e-1+1.7343245214879664480e0i) (num-test (asin 2.0e+00-2.0e+00i) 7.5424914469804604071e-1-1.7343245214879664480e0i) (num-test (asin -2.0e+00+2.0e+00i) -7.5424914469804604071e-1+1.7343245214879664480e0i) (num-test (asin -2.0e+00-2.0e+00i) -7.5424914469804604071e-1-1.7343245214879664480e0i) (num-test (asin 2.0e+00+8.3886080e+06i) 2.3841857910155628843e-7+1.663553233343871940e1i) (num-test (asin 2.0e+00-8.3886080e+06i) 2.3841857910155628843e-7-1.663553233343871940e1i) (num-test (asin -2.0e+00+8.3886080e+06i) -2.3841857910155628843e-7+1.663553233343871940e1i) (num-test (asin -2.0e+00-8.3886080e+06i) -2.3841857910155628843e-7-1.663553233343871940e1i) (num-test (asin 8.3886080e+06+0.0e+00i) 1.5707963267948966192e0-1.6635532333438683873e1i) (num-test (asin -8.3886080e+06+0.0e+00i) -1.5707963267948966192e0+1.6635532333438683873e1i) (num-test (asin 8.3886080e+06+1.19209289550781250e-07i) 1.5707963267948824084e0+1.6635532333438683873e1i) (num-test (asin 8.3886080e+06-1.19209289550781250e-07i) 1.5707963267948824084e0-1.6635532333438683873e1i) (num-test (asin -8.3886080e+06+1.19209289550781250e-07i) -1.5707963267948824084e0+1.6635532333438683873e1i) (num-test (asin -8.3886080e+06-1.19209289550781250e-07i) -1.5707963267948824084e0-1.6635532333438683873e1i) (num-test (asin 8.3886080e+06+5.0e-01i) 1.5707962671902518438e0+1.6635532333438685650e1i) (num-test (asin 8.3886080e+06-5.0e-01i) 1.5707962671902518438e0-1.6635532333438685650e1i) (num-test (asin -8.3886080e+06+5.0e-01i) -1.5707962671902518438e0+1.6635532333438685650e1i) (num-test (asin -8.3886080e+06-5.0e-01i) -1.5707962671902518438e0-1.6635532333438685650e1i) (num-test (asin 8.3886080e+06+1.0e+00i) 1.5707962075856070684e0+1.6635532333438690979e1i) (num-test (asin 8.3886080e+06-1.0e+00i) 1.5707962075856070684e0-1.6635532333438690979e1i) (num-test (asin -8.3886080e+06+1.0e+00i) -1.5707962075856070684e0+1.6635532333438690979e1i) (num-test (asin -8.3886080e+06-1.0e+00i) -1.5707962075856070684e0-1.6635532333438690979e1i) (num-test (asin 8.3886080e+06+2.0e+00i) 1.5707960883763175177e0+1.6635532333438712295e1i) (num-test (asin 8.3886080e+06-2.0e+00i) 1.5707960883763175177e0-1.6635532333438712295e1i) (num-test (asin -8.3886080e+06+2.0e+00i) -1.5707960883763175177e0+1.6635532333438712295e1i) (num-test (asin -8.3886080e+06-2.0e+00i) -1.5707960883763175177e0-1.6635532333438712295e1i) (num-test (asin 8.3886080e+06+8.3886080e+06i) 7.8539816339744653326e-1+1.6982105923718660081e1i) (num-test (asin 8.3886080e+06-8.3886080e+06i) 7.8539816339744653326e-1-1.6982105923718660081e1i) (num-test (asin -8.3886080e+06+8.3886080e+06i) -7.8539816339744653326e-1+1.6982105923718660081e1i) (num-test (asin -8.3886080e+06-8.3886080e+06i) -7.8539816339744653326e-1-1.6982105923718660081e1i) (num-test (asin -1.0e+01) -1.5707963267948966192e0+2.9932228461263808979e0i) (num-test (asin -2.0e+00) -1.5707963267948966192e0+1.3169578969248167086e0i) (num-test (asin -1.0e+00) -1.5707963267948966192e0) (num-test (asin -7.50e-01) -8.4806207898148100805e-1) (num-test (asin -5.0e-01) -5.2359877559829887308e-1) (num-test (asin -1.250e-01) -1.2532783116806539687e-1) (num-test (asin -3.45266983001243932001e-04) -3.4526698986108292481e-4) (num-test (asin -1.19209289550781250e-07) -1.1920928955078153234e-7) (num-test (asin 0.0e+00) 0e0) (num-test (asin 1.19209289550781250e-07) 1.1920928955078153234e-7) (num-test (asin 3.45266983001243932001e-04) 3.4526698986108292481e-4) (num-test (asin 1.250e-01) 1.2532783116806539687e-1) (num-test (asin 5.0e-01) 5.2359877559829887308e-1) (num-test (asin 7.50e-01) 8.4806207898148100805e-1) (num-test (asin 1.0e+00) 1.5707963267948966192e0) (num-test (asin 2.0e+00) 1.5707963267948966192e0-1.3169578969248167086e0i) (num-test (asin 1.0e+01) 1.5707963267948966192e0-2.9932228461263808979e0i) (num-test (asin 0) 0.0) (num-test (asin 2) 1.570796326794897-1.316957896924817i) (num-test (asin 3.0+70000000i) 4.2857142400327436E-8+18.7571529895002i) (num-test (asin 70000000+3i) 1.570796279536826+18.75715298057358i) (num-test (asin 3.0-70000000i) 4.2857142400327436E-8-18.7571529895002i) (num-test (asin -70000000+3i) -1.570796279536826+18.75715298057358i) (num-test (asin 1e17+1e17i) 0.78539816339745+40.183667351739i) (num-test (asin 1+1e17i) 1e-17+39.837093761459i) (num-test (asin -2.225073858507201399999999999999999999996E-308) -2.225073858507201399999999999999999999996E-308) (num-test (asin 1.110223024625156799999999999999999999997E-16) 1.110223024625156800000000000000002280754E-16) (num-test (asin (/ (sqrt 2) 2)) (/ pi 4)) (num-test (asin (/ (sqrt 3) -2)) (/ pi -3)) (num-test (* 10 (asin (/ (- (sqrt 5) 1) 4))) pi) (num-test (* 2 (asin 1)) pi) (for-each (lambda (num-and-val) (let ((num (car num-and-val)) (val (cadr num-and-val))) (num-test-1 'asin num (asin num) val))) (vector (list 0 0) (list 1 1.5707963267949) (list 2 1.5707963267949-1.3169578969248i) (list 3 1.5707963267949-1.7627471740391i) (list -1 -1.5707963267949) (list -2 -1.5707963267949+1.3169578969248i) (list -3 -1.5707963267949+1.7627471740391i) (list 9223372036854775807 1.5707963267949-44.361419555836i) (list -9223372036854775808 -1.5707963267949+44.361419555836i) (list 1/2 0.5235987755983) (list 1/3 0.33983690945412) (list -1/2 -0.5235987755983) (list -1/3 -0.33983690945412) (list 1/9223372036854775807 1.0842021724855e-19) (list 0.0 0.0) (list 1.0 1.5707963267949) (list 2.0 1.5707963267949-1.3169578969248i) (list -2.0 -1.5707963267949+1.3169578969248i) (list 1.000000000000000000000000000000000000002E-309 1.000000000000000000000000000000000000002E-309) (list 1e+16 1.5707963267949-37.534508668465i) (list 0+1i 0+0.88137358701954i) (list 0+2i 0+1.4436354751788i) (list 0-1i 0-0.88137358701954i) (list 1+1i 0.66623943249252+1.061275061905i) (list 1-1i 0.66623943249252-1.061275061905i) (list -1+1i -0.66623943249252+1.061275061905i) (list -1-1i -0.66623943249252-1.061275061905i) (list 0.1+0.1i 0.099663702859795+0.10033029811221i) (list 1e+16+1e+16i 0.78539816339745+37.881082258745i) (list 1e-16+1e-16i 1e-16+1.1102230246252e-16i) )) (let ((err 0.0) (mx 0.0)) (do ((i 0 (+ i 1)) (x -10.0 (+ x .1))) ((= i 200)) (let ((y (magnitude (- x (sin (asin x)))))) (if (> y err) (begin (set! mx x) (set! err y))))) (if (> err 1e-12) (format-logged #t ";(sin (asin ~A)) error: ~A~%" mx err))) (let ((err 0.0) (mx 0.0)) (do ((i 0 (+ i 1)) (x 1.0-i (+ x -.1+i))) ((= i 100)) (let ((y (magnitude (- x (sin (asin x)))))) (if (> y err) (begin (set! mx x) (set! err y))))) (if (> err 1e-9) (format-logged #t ";(sin (asin ~A)) error: ~A~%" mx err))) (test (asin) 'error) (test (asin "hi") 'error) (test (asin 1.0+23.0i 1.0+23.0i) 'error) (test (asin 0 1) 'error) (for-each (lambda (arg) (test (asin arg) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) (let ((asins (list 0.00000000000000000000000000000000000000000000000000000000000000000000 0.02500260489936113599406838915349107150195748368840710160729904233944 0.05002085680577001466274438682046411497780608049468789272874398055703 0.07507049107671654265775143572317089898194705496817785120910161299955 0.10016742116155979634552317945269331856867597222962954139102385503640 0.12532783116806539687456698635708471804814772683867237523396403098649 0.15056827277668602642326030146739539047425784470580485344319902595849 0.17590576816371628737774199743846051972730948209298253171964068749984 0.20135792079033079145512555221762341024003808140222838625725124345560 0.22694303617851994909359260763689579636930963064761339672521677581090 0.25268025514207865348565743699371097225219373309683819363392377874057 0.27858970239165058217050815183568882129133935843106227203280647300877 0.30469265401539750797200296122752916695456003170677638739297794874647 0.33101172808929452771961639961139035858195303667932389628972377319123 0.35757110364551028671483849232064256784674132498948776325141270863037 0.38439677449563908303819487296704697375277948430656504155058375479079 0.41151684606748801938473789761733560485570113512702585178394678070009 0.43896188560976067483321619602147236009843505358239561712817387552271 0.46676533904729636185033976030413712126156503909241369925276357159851 0.49496403171689461363027991615293072605447706550005723007748628111125 0.52359877559829887307710723054658381403286156656251763682915743205130 0.55271511309678317285035596261806027710654731438452549350875265730232 0.58236423786874344183204729090997636797897358751436418853659347126034 0.61260414804862246566851988030718610964520075565860642564808142300476 0.64350110879328438680280922871732263804151059111531238286560611871351 0.67513153293703164720905626529438801420418535124967921737841984904557 0.70758443672535557545286474430459468476197717933193633785448106190261 0.74096470220302000164595109317351452207440076171206748884906746063949 0.77539749661075306374035335271498711355578873864116199359771996373272 0.81103439428758154765966499519016990220446846078107874166646027112837 0.84806207898148100805294433899841808007336621326311264286071816357020 0.88671509499956738294114522105877020358977872696702934222169938478807 0.92729521800161223242851246292242880405707410857224052762186617744039 0.97020219992884564627294507144637975649395034794671876838355202607208 1.01598529381482513116231792163105149400316379682053508778250056579494 1.06543581651073931226000681765232949759419723349387652321962473867275 1.11976951499863418668667705584539961589516218640330288237568186391443 1.18103559399742179696187441797151603545275866323114802494551011137296 1.25323589750337525873710391866600599574114067342736145636046515573871 1.34672104149307735953151290762049740983950868154764854526693662237423 1.57079632679489661923132169163975144209858469968755291048747229615390))) (let ((mxerr 0.0)) (do ((i 0 (+ i 1)) (x 0.0 (+ x (/ 1.0 40.0)))) ((= i 40)) (let ((err (abs (- (asin x) (list-ref asins i))))) (if (> err mxerr) (set! mxerr err)))) (if (> mxerr 1e-12) (format-logged #t "asin err: ~A~%" mxerr)))) (if with-bignums (let ((old-prec (*s7* 'bignum-precision))) (set! (*s7* 'bignum-precision) 500) (let ((asins (list ; table[Arcsin[k/30], {k, 0, 30}] 0.00000000000000000000000000000000000000000000000000000000000000000000e0 0.03333950926130208699143488077083860917565937855129663393680393744362 0.06671614841022525954540510327036927409184944434654403274652597117428 0.10016742116155979634552317945269331856867597222962954139102385503640 0.13373158940994152865632332716309743011405498274444165545458875924377 0.16744807921968933055327460604363822091495716231623832046578730373329 0.20135792079033079145512555221762341024003808140222838625725124345560 0.23550423672079979129288448393723556648106234259531297814541683051663 0.26993279583340344442461498978851864365647337427020501782962042633379 0.30469265401539750797200296122752916695456003170677638739297794874647 0.33983690945412193709639251339176406638824469033245807143192396248991 0.37542360798103940368516545708214708494670535320625397496008012654413 0.41151684606748801938473789761733560485570113512702585178394678070009 0.44818813597943128994043756304906477118029918046343080720212217855713 0.48551812229559116327223435902482444763168509494201196125953547218486 0.52359877559829887307710723054658381403286156656251763682915743205130 0.56253624454385561973132565694853319169977493405170278279550382560769 0.60245463338499055124863378781466897272136400811697167837514413874507 0.64350110879328438680280922871732263804151059111531238286560611871351 0.68585296461871075596328071793021108476903703940127104404158318225766 0.72972765622696636345479665981332069539650591404771369070894949146181 0.77539749661075306374035335271498711355578873864116199359771996373272 0.82321197712587582143797706006235798228453830885144107684904792594002 0.87363319315266432351068180914720023973456695459982111043494836254140 0.92729521800161223242851246292242880405707410857224052762186617744039 0.98511078333774565961356415316223367589822363251591140783691296893264 1.04848150498884799670722286578404816608970376214442109090268484725633 1.11976951499863418668667705584539961589516218640330288237568186391443 1.20358830623705947672584877793852613585139977949919656045114461770445 1.31187478478867540346593147633958737932614651512288222488818316043445 1.57079632679489661923132169163975144209858469968755291048747229615390))) (do ((i 0 (+ i 1))) ((= i 30)) (let ((val (asin (/ i (bignum "30"))))) (if (> (magnitude (- val (list-ref asins i))) 1e-36) (format-logged #t ";(asin ~A) -> ~A ~A~%[~A]~%" (/ i 30) val (list-ref asins i) (magnitude (- val (list-ref asins i)))))))) (set! (*s7* 'bignum-precision) old-prec))) ;;;-------------------------------------------------------------------------------- ;;; acos ;;; -------------------------------------------------------------------------------- (num-test (acos 0) 1.57079632679490) (num-test (acos 1) 0.0) (num-test (acos -1) pi) (num-test (acos 2) 0.0-1.31695789692482i) (num-test (acos -2) 3.14159265358979-1.31695789692482i) (num-test (acos 3) 0.0-1.76274717403909i) (num-test (acos -3) 3.14159265358979-1.76274717403909i) (num-test (acos 10) 0.0-2.99322284612638i) (num-test (acos -10) 3.14159265358979-2.99322284612638i) (num-test (acos 1234) 0.0-7.81116322068415i) (num-test (acos -1234) 3.14159265358979-7.81116322068415i) (num-test (acos 0/1) 1.57079632679490) (num-test (acos 0/2) 1.57079632679490) (num-test (acos 0/3) 1.57079632679490) (num-test (acos 0/10) 1.57079632679490) (num-test (acos 0/1234) 1.57079632679490) (num-test (acos 0/1234000000) 1.57079632679490) (num-test (acos 0/500029) 1.57079632679490) (num-test (acos 0/362880) 1.57079632679490) (num-test (acos 1/1) 0.0) (num-test (acos -1/1) pi) (num-test (acos 1/2) 1.04719755119660) (num-test (acos -1/2) 2.09439510239320) (num-test (acos 1/3) 1.23095941734077) (num-test (acos -1/3) 1.91063323624902) (num-test (acos 1/10) 1.47062890563334) (num-test (acos -1/10) 1.67096374795646) (num-test (acos 1/1234) 1.56998595393473) (num-test (acos -1/1234) 1.57160669965507) (num-test (acos 1/1234000000) 1.57079632598452) (num-test (acos -1/1234000000) 1.57079632760527) (num-test (acos 1/500029) 1.57079432691089) (num-test (acos -1/500029) 1.57079832667890) (num-test (acos 1/362880) 1.57079357106297) (num-test (acos -1/362880) 1.57079908252682) (num-test (acos 2/1) 0.0-1.31695789692482i) (num-test (acos -2/1) 3.14159265358979-1.31695789692482i) (num-test (acos 2/2) 0.0) (num-test (acos -2/2) pi) (num-test (acos 2/3) 0.84106867056793) (num-test (acos -2/3) 2.30052398302186) (num-test (acos 2/10) 1.36943840600457) (num-test (acos -2/10) 1.77215424758523) (num-test (acos 2/1234) 1.56917558054238) (num-test (acos -2/1234) 1.57241707304741) (num-test (acos 2/1234000000) 1.57079632517415) (num-test (acos -2/1234000000) 1.57079632841564) (num-test (acos 2/500029) 1.57079232702688) (num-test (acos -2/500029) 1.57080032656291) (num-test (acos 2/362880) 1.57079081533105) (num-test (acos -2/362880) 1.57080183825874) (num-test (acos 3/1) 0.0-1.76274717403909i) (num-test (acos -3/1) 3.14159265358979-1.76274717403909i) (num-test (acos 3/2) 0.0-0.96242365011921i) (num-test (acos -3/2) 3.14159265358979-0.96242365011921i) (num-test (acos 3/3) 0.0) (num-test (acos -3/3) pi) (num-test (acos 3/10) 1.26610367277950) (num-test (acos -3/10) 1.87548898081029) (num-test (acos 3/1234) 1.56836520608568) (num-test (acos -3/1234) 1.57322744750412) (num-test (acos 3/1234000000) 1.57079632436378) (num-test (acos -3/1234000000) 1.57079632922601) (num-test (acos 3/500029) 1.57079032714288) (num-test (acos -3/500029) 1.57080232644692) (num-test (acos 3/362880) 1.57078805959913-0.0i) (num-test (acos -3/362880) 1.57080459399066-0.0i) (num-test (acos 10/1) 0.0-2.99322284612638i) (num-test (acos -10/1) 3.14159265358979-2.99322284612638i) (num-test (acos 10/2) 0.0-2.29243166956117i) (num-test (acos -10/2) 3.14159265358979-2.29243166956117i) (num-test (acos 10/3) 0.0-1.87382024252741i) (num-test (acos -10/3) 3.14159265358979-1.87382024252741i) (num-test (acos 10/10) 0.0) (num-test (acos -10/10) pi) (num-test (acos 10/1234) 1.56269251038168) (num-test (acos -10/1234) 1.57890014320811) (num-test (acos 10/1234000000) 1.57079631869117) (num-test (acos -10/1234000000) 1.57079633489862) (num-test (acos 10/500029) 1.57077632795483) (num-test (acos -10/500029) 1.57081632563497) (num-test (acos 10/362880) 1.57076876947567) (num-test (acos -10/362880) 1.57082388411412) (num-test (acos 1234/1) 0.0-7.81116322068415i) (num-test (acos -1234/1) 3.14159265358979-7.81116322068415i) (num-test (acos 1234/2) 0.0-7.11801554770806i) (num-test (acos -1234/2) 3.14159265358979-7.11801554770806i) (num-test (acos 1234/3) 0.0-6.71254961876657i) (num-test (acos -1234/3) 3.14159265358979-6.71254961876657i) (num-test (acos 1234/10) 0.0-5.50856187402751i) (num-test (acos -1234/10) 3.14159265358979-5.50856187402751i) (num-test (acos 1234/1234) 0.0) (num-test (acos -1234/1234) pi) (num-test (acos 1234/1234000000) 1.57079532679490) (num-test (acos -1234/1234000000) 1.57079732679490) (num-test (acos 1234/500029) 1.56832846742558) (num-test (acos -1234/500029) 1.57326418616421) (num-test (acos 1234/362880) 1.56739574704864) (num-test (acos -1234/362880) 1.57419690654115) (num-test (acos 1234000000/1234000000) 0.0) (num-test (acos -1234000000/1234000000) pi) (num-test (acos 1234000000/500029) 0.0-8.50425252675189i) (num-test (acos -1234000000/500029) 3.14159265358979-8.50425252675189i) (num-test (acos 1234000000/362880) 0.0-8.82484644053502i) (num-test (acos -1234000000/362880) 3.14159265358979-8.82484644053502i) (num-test (acos 500029/3) 0+12.7169561400958i) (num-test (acos -500029/3) 3.14159265358979-12.7169561400958i) (num-test (acos 500029/10) 0.0+11.51298346318831i) ; maxima (num-test (acos -500029/10) 3.14159265358979-11.51298333576987i) (num-test (acos 500029/1234) 0.0-6.69755082925184i) (num-test (acos -500029/1234) 3.14159265358979-6.69755082925184i) (num-test (acos 500029/1234000000) 1.57039111689726) (num-test (acos -500029/1234000000) 1.57120153669253) (num-test (acos 500029/500029) 0.0) (num-test (acos -500029/500029) pi) (num-test (acos 500029/362880) 0.0-0.84413377868249i) (num-test (acos -500029/362880) 3.14159265358979-0.84413377868249i) (num-test (acos 362880/2) 0.0+1.280182724631953e1i) (num-test (acos -362880/2) 3.141592653589793-12.80182748007388i) (num-test (acos 362880/3) 0.0+12.39636237195622i) (num-test (acos -362880/3) 3.141592653589793-12.39636237195622i) (num-test (acos 362880/10) 0.0-11.19238956745752i) (num-test (acos -362880/10) 3.14159265358979-11.19238956745752i) (num-test (acos 362880/1234) 0.0-6.37695556516894i) (num-test (acos -362880/1234) 3.14159265358979-6.37695556516894i) (num-test (acos 362880/1234000000) 1.57050225871935) (num-test (acos -362880/1234000000) 1.57109039487045) (num-test (acos 362880/500029) 0.75871902295910) (num-test (acos -362880/500029) 2.38287363063069) (num-test (acos 362880/362880) 0.0) (num-test (acos -362880/362880) pi) (num-test (acos 0.0) 1.57079632679490) (num-test (acos 0.00000001) 1.57079631679490) (num-test (acos -0.00000001) 1.57079633679490) (num-test (acos 1.0) 0.0) (num-test (acos -1.0) pi) (num-test (acos pi) 0.0-1.81152627246085i) (num-test (acos -3.14159265358979) 3.14159265358979-1.81152627246085i) (num-test (acos 2.71828182845905) 0.0-1.65745445415308i) (num-test (acos -2.71828182845905) 3.14159265358979-1.65745445415308i) (num-test (acos 1234.0) 0.0-7.81116322068415i) (num-test (acos -1234.0) 3.14159265358979-7.81116322068415i) (num-test (acos 0.0+0.0i) 1.57079632679490) (num-test (acos -0.0+0.0i) 1.57079632679490) (num-test (acos 0.0-0.0i) 1.57079632679490) (num-test (acos -0.0-0.0i) 1.57079632679490) (num-test (acos 0.0+0.00000001i) 1.57079632679490-0.00000001i) (num-test (acos -0.0+0.00000001i) 1.57079632679490-0.00000001i) (num-test (acos 0.0-0.00000001i) 1.57079632679490+0.00000001i) (num-test (acos -0.0-0.00000001i) 1.57079632679490+0.00000001i) (num-test (acos 0.0+1.0i) 1.57079632679490-0.88137358701954i) (num-test (acos -0.0+1.0i) 1.57079632679490-0.88137358701954i) (num-test (acos 0.0-1.0i) 1.57079632679490+0.88137358701954i) (num-test (acos -0.0-1.0i) 1.57079632679490+0.88137358701954i) (num-test (acos 0.0+3.14159265358979i) 1.57079632679490-1.86229574331085i) (num-test (acos -0.0+3.14159265358979i) 1.57079632679490-1.86229574331085i) (num-test (acos 0.0-3.14159265358979i) 1.57079632679490+1.86229574331085i) (num-test (acos -0.0-3.14159265358979i) 1.57079632679490+1.86229574331085i) (num-test (acos 0.0+2.71828182845905i) 1.57079632679490-1.72538255885232i) (num-test (acos -0.0+2.71828182845905i) 1.57079632679490-1.72538255885232i) (num-test (acos 0.0-2.71828182845905i) 1.57079632679490+1.72538255885231i) (num-test (acos -0.0-2.71828182845905i) 1.57079632679490+1.72538255885231i) (num-test (acos 0.0+1234.0i) 1.57079632679490-7.81116354896171i) (num-test (acos -0.0+1234.0i) 1.57079632679490-7.81116354896171i) (num-test (acos 0.0-1234.0i) 1.57079632679490+7.81116354920125i) (num-test (acos -0.0-1234.0i) 1.57079632679490+7.81116354920125i) (num-test (acos 0.0-1234000000.0i) 1.57079632679490+21.62667394298955i) (num-test (acos -0.0-1234000000.0i) 1.57079632679490+21.62667394298955i) (num-test (acos 0.00000001+0.0i) 1.57079631679490) (num-test (acos -0.00000001+0.0i) 1.57079633679490) (num-test (acos 0.00000001-0.0i) 1.57079631679490) (num-test (acos -0.00000001-0.0i) 1.57079633679490) (num-test (acos 0.00000001+0.00000001i) 1.57079631679490-0.00000001i) (num-test (acos -0.00000001+0.00000001i) 1.57079633679490-0.00000001i) (num-test (acos 0.00000001-0.00000001i) 1.57079631679490+0.00000001i) (num-test (acos -0.00000001-0.00000001i) 1.57079633679490+0.00000001i) (num-test (acos 0.00000001+1.0i) 1.57079631972383-0.88137358701954i) (num-test (acos -0.00000001+1.0i) 1.57079633386596-0.88137358701954i) (num-test (acos 0.00000001-1.0i) 1.57079631972383+0.88137358701954i) (num-test (acos -0.00000001-1.0i) 1.57079633386596+0.88137358701954i) (num-test (acos 0.00000001+3.14159265358979i) 1.57079632376175-1.86229574331085i) (num-test (acos -0.00000001+3.14159265358979i) 1.57079632982804-1.86229574331085i) (num-test (acos 0.00000001-3.14159265358979i) 1.57079632376175+1.86229574331085i) (num-test (acos -0.00000001-3.14159265358979i) 1.57079632982804+1.86229574331085i) (num-test (acos 0.00000001+2.71828182845905i) 1.57079632334232-1.72538255885232i) (num-test (acos -0.00000001+2.71828182845905i) 1.57079633024747-1.72538255885232i) (num-test (acos 0.00000001-2.71828182845905i) 1.57079632334232+1.72538255885231i) (num-test (acos -0.00000001-2.71828182845905i) 1.57079633024747+1.72538255885231i) (num-test (acos 0.00000001+1234.0i) 1.57079632678679-7.81116354896171i) (num-test (acos -0.00000001+1234.0i) 1.57079632680300-7.81116354896171i) (num-test (acos 0.00000001-1234.0i) 1.57079632678679+7.81116354920125i) (num-test (acos -0.00000001-1234.0i) 1.57079632680300+7.81116354920125i) (num-test (acos 0.00000001-1234000000.0i) 1.57079632679490+21.62667394298955i) (num-test (acos -0.00000001-1234000000.0i) 1.57079632679490+21.62667394298955i) (num-test (acos 1.0+0.0i) 0.0) (num-test (acos -1.0+0.0i) pi) (num-test (acos 1.0-0.0i) 0.0) (num-test (acos -1.0-0.0i) pi) (num-test (acos 1.0+0.00000001i) 0.00009999999992-0.00010000000008i) (num-test (acos -1.0+0.00000001i) 3.14149265358988-0.00010000000008i) (num-test (acos 1.0-0.00000001i) 0.00009999999992+0.00010000000008i) (num-test (acos -1.0-0.00000001i) 3.14149265358988+0.00010000000008i) (num-test (acos 1.0+1.0i) 0.90455689430238-1.06127506190504i) (num-test (acos -1.0+1.0i) 2.23703575928741-1.06127506190504i) (num-test (acos 1.0-1.0i) 0.90455689430238+1.06127506190504i) (num-test (acos -1.0-1.0i) 2.23703575928741+1.06127506190504i) (num-test (acos 1.0+3.14159265358979i) 1.27521129258327-1.90462768697066i) (num-test (acos -1.0+3.14159265358979i) 1.86638136100653-1.90462768697066i) (num-test (acos 1.0-3.14159265358979i) 1.27521129258327+1.90462768697066i) (num-test (acos -1.0-3.14159265358979i) 1.86638136100653+1.90462768697066i) (num-test (acos 1.0+2.71828182845905i) 1.23635355491853-1.77905438385935i) (num-test (acos -1.0+2.71828182845905i) 1.90523909867127-1.77905438385935i) (num-test (acos 1.0-2.71828182845905i) 1.23635355491853+1.77905438385935i) (num-test (acos -1.0-2.71828182845905i) 1.90523909867127+1.77905438385935i) (num-test (acos 1.0+1234.0i) 1.56998595446684-7.81116387772663i) (num-test (acos -1.0+1234.0i) 1.57160669912296-7.81116387772663i) (num-test (acos 1.0-1234.0i) 1.56998595446690+7.81116387755283i) (num-test (acos -1.0-1234.0i) 1.57160669912289+7.81116387755283i) (num-test (acos 1.0-1234000000.0i) 1.57079632598452+21.62667394298955i) (num-test (acos -1.0-1234000000.0i) 1.57079632760527+21.62667394298955i) (num-test (acos 3.14159265358979+0.0i) 0.0-1.81152627246085i) (num-test (acos -3.14159265358979+0.0i) 3.14159265358979-1.81152627246085i) (num-test (acos 3.14159265358979-0.0i) 0.0-1.81152627246085i) (num-test (acos -3.14159265358979-0.0i) 3.14159265358979-1.81152627246085i) (num-test (acos 3.14159265358979+0.00000001i) 0.00000000335775-1.81152627246085i) (num-test (acos -3.14159265358979+0.00000001i) 3.14159265023205-1.81152627246085i) (num-test (acos 3.14159265358979-0.00000001i) 0.00000000335775+1.81152627246085i) (num-test (acos -3.14159265358979-0.00000001i) 3.14159265023205+1.81152627246085i) (num-test (acos 3.14159265358979+1.0i) 0.32225329398146-1.86711439316026i) (num-test (acos -3.14159265358979+1.0i) 2.81933935960833-1.86711439316026i) (num-test (acos 3.14159265358979-1.0i) 0.32225329398146+1.86711439316026i) (num-test (acos -3.14159265358979-1.0i) 2.81933935960833+1.86711439316026i) (num-test (acos 3.14159265358979+3.14159265358979i) 0.79805654766741-2.18469104082751i) (num-test (acos -3.14159265358979+3.14159265358979i) 2.34353610592238-2.18469104082751i) (num-test (acos 3.14159265358979-3.14159265358979i) 0.79805654766741+2.18469104082751i) (num-test (acos -3.14159265358979-3.14159265358979i) 2.34353610592238+2.18469104082751i) (num-test (acos 3.14159265358979+2.71828182845905i) 0.72769976263454-2.11552790803290i) (num-test (acos -3.14159265358979+2.71828182845905i) 2.41389289095525-2.11552790803290i) (num-test (acos 3.14159265358979-2.71828182845905i) 0.72769976263454+2.11552790803290i) (num-test (acos -3.14159265358979-2.71828182845905i) 2.41389289095525+2.11552790803290i) (num-test (acos 3.14159265358979+1234.0i) 1.56825047198589-7.81116678966949i) (num-test (acos -3.14159265358979+1234.0i) 1.57334218160390-7.81116678966949i) (num-test (acos 3.14159265358979-1234.0i) 1.56825047198552+7.81116678989204i) (num-test (acos -3.14159265358979-1234.0i) 1.57334218160427+7.81116678989204i) (num-test (acos 3.14159265358979-1234000000.0i) 1.57079632424904+21.62667394298955i) (num-test (acos -3.14159265358979-1234000000.0i) 1.57079632934076+21.62667394298955i) (num-test (acos 2.71828182845905+0.0i) 0.0-1.65745445415308i) (num-test (acos -2.71828182845905+0.0i) 3.14159265358979-1.65745445415308i) (num-test (acos 2.71828182845905-0.0i) 0.0-1.65745445415308i) (num-test (acos -2.71828182845905-0.0i) 3.14159265358979-1.65745445415308i) (num-test (acos 2.71828182845905+0.00000001i) 0.00000000395623-1.65745445415308i) (num-test (acos -2.71828182845905+0.00000001i) 3.14159264963356-1.65745445415308i) (num-test (acos 2.71828182845905-0.00000001i) 0.00000000395623+1.65745445415308i) (num-test (acos -2.71828182845905-0.00000001i) 3.14159264963356+1.65745445415308i) (num-test (acos 2.71828182845905+1.0i) 0.37321824160908-1.73375471569385i) (num-test (acos -2.71828182845905+1.0i) 2.76837441198071-1.73375471569385i) (num-test (acos 2.71828182845905-1.0i) 0.37321824160908+1.73375471569385i) (num-test (acos -2.71828182845905-1.0i) 2.76837441198071+1.73375471569385i) (num-test (acos 2.71828182835905+3.14159265358979i) 0.87174835684834-2.11968336368048i) (num-test (acos -2.71828182845905+3.14159265358979i) 2.26984429674145-2.11968336368048i) (num-test (acos 2.71828182845905-3.14159265358979i) 0.87174835684834+2.11968336368048i) (num-test (acos -2.71828182845905-3.14159265358979i) 2.26984429674145+2.11968336368048i) (num-test (acos 2.71828182845905+2.71828182845905i) 0.80229897091015-2.04014932880026i) (num-test (acos -2.71828182845905+2.71828182845905i) 2.33929368267965-2.04014932880026i) (num-test (acos 2.71828182845905-2.71828182845905i) 0.80229897091014+2.04014932880026i) (num-test (acos -2.71828182845905-2.71828182845905i) 2.33929368267965+2.04014932880026i) (num-test (acos 2.71828182845905+1234.0i) 1.56859350950254-7.81116597510553i) (num-test (acos -2.71828182845905+1234.0i) 1.57299914408725-7.81116597510553i) (num-test (acos 2.71828182845905-1234.0i) 1.56859350950221+7.81116597540442i) (num-test (acos -2.71828182845905-1234.0i) 1.57299914408758+7.81116597540442i) (num-test (acos 2.71828182845905-1234000000.0i) 1.57079632459208+21.62667394298955i) (num-test (acos -2.71828182845905-1234000000.0i) 1.57079632899772+21.62667394298955i) (num-test (acos 1234.0+0.0i) 0.0-7.81116322068415i) (num-test (acos -1234.0+0.0i) 3.14159265358979-7.81116322068415i) (num-test (acos 1234.0-0.0i) 0.0-7.81116322068415i) (num-test (acos -1234.0-0.0i) 3.14159265358979-7.81116322068415i) (num-test (acos 1234.0+0.00000001i) 0.00000000000810-7.81116322068415i) (num-test (acos -1234.0+0.00000001i) 3.14159265358169-7.81116322068415i) (num-test (acos 1234.0-0.00000001i) 0.00000000000810+7.81116322084923i) (num-test (acos -1234.0-0.00000001i) 3.14159265358169+7.81116322084923i) (num-test (acos 1234.0+1.0i) 0.00081037286048-7.81116354944842i) (num-test (acos -1234.0+1.0i) 3.14078228072931-7.81116354944842i) (num-test (acos 1234.0-1.0i) 0.00081037286017+7.81116354920146i) (num-test (acos -1234.0-1.0i) 3.14078228072962+7.81116354920146i) (num-test (acos 1234.0+3.14159265358979i) 0.00254585647983-7.81116646138554i) (num-test (acos -1234.0+3.14159265358979i) 3.13904679710996-7.81116646138554i) (num-test (acos 1234.0-3.14159265358979i) 0.00254585648123+7.81116646154641i) (num-test (acos -1234.0-3.14159265358979i) 3.13904679710856+7.81116646154641i) (num-test (acos 1234.0+2.71828182845905i) 0.00220281873947-7.81116564738434i) (num-test (acos -1234.0+2.71828182845905i) 3.13938983485033-7.81116564738434i) (num-test (acos 1234.0-2.71828182845905i) 0.00220281873928+7.81116564705719i) (num-test (acos -1234.0-2.71828182845905i) 3.13938983485052+7.81116564705719i) (num-test (acos 1234.0+1234.0i) 0.78539824532655-8.15773697538346i) (num-test (acos -1234.0+1234.0i) 2.35619440826324-8.15773697538346i) (num-test (acos 1234.0-1234.0i) 0.78539824548545+8.15773697530526i) (num-test (acos -1234.0-1234.0i) 2.35619440810434+8.15773697530526i) (num-test (acos 1234.0-1234000000.0i) 1.57079532679490+21.62667394299005i) (num-test (acos -1234.0-1234000000.0i) 1.57079732679490+21.62667394299005i) (num-test (acos 1234000000.0-0.00000001i) 0.0+21.62667394298955i) (num-test (acos -1234000000.0-0.00000001i) 3.14159265358979+21.62667394298955i) (num-test (acos 1234000000.0-1.0i) 0.00000000081037+21.62667394298955i) (num-test (acos -1234000000.0-1.0i) 3.14159265277942+21.62667394298955i) (num-test (acos 1234000000.0-3.14159265358979i) 0.00000000254586+21.62667394298955i) (num-test (acos -1234000000.0-3.14159265358979i) 3.14159265104393+21.62667394298955i) (num-test (acos 1234000000.0-2.71828182845905i) 0.00000000220282+21.62667394298955i) (num-test (acos -1234000000.0-2.71828182845905i) 3.14159265138697+21.62667394298955i) (num-test (acos 1234000000.0-1234.0i) 0.00000100000000+21.62667394299005i) (num-test (acos -1234000000.0-1234.0i) 3.14159165358979+21.62667394299005i) (num-test (acos 1234000000.0-1234000000.0i) 0.78539816339745+21.97324753326953i) (num-test (acos -1234000000.0-1234000000.0i) 2.35619449019234+21.97324753326953i) (num-test (acos -2.0) 3.141592653589793-1.316957896924817i) (num-test (acos 3.0+70000000i) 1.570796283937754-18.7571529895002i) ; C breaks near here (num-test (acos 70000000+3i) 4.725807101202406E-8-18.75715298057358i) (num-test (acos 3.0-70000000i) 1.570796283937754+18.7571529895002i) (num-test (acos -70000000+3i) 3.141592606331722-18.75715298057358i) (num-test (acos 1.5) 0.0+0.9624236501192069i) (num-test (acos -1.5) 3.141592653589793-0.9624236501192069i) (num-test (acos -1.0e+01) 3.1415926535897932385e0-2.9932228461263808979e0i) (num-test (acos -2.0e+00) 3.1415926535897932385e0-1.3169578969248167086e0i) (num-test (acos -1.0e+00) 3.1415926535897932385e0) (num-test (acos -7.50e-01) 2.4188584057763776273e0) (num-test (acos -5.0e-01) 2.0943951023931954923e0) (num-test (acos -1.250e-01) 1.6961241579629620161e0) (num-test (acos -3.45266983001243932001e-04) 1.5711415937847577022e0) (num-test (acos -1.19209289550781250e-07) 1.570796446004186170e0) (num-test (acos 0.0e+00) 1.5707963267948966192e0) (num-test (acos 1.19209289550781250e-07) 1.5707962075856070684e0) (num-test (acos 3.45266983001243932001e-04) 1.5704510598050355363e0) (num-test (acos 1.250e-01) 1.4454684956268312224e0) (num-test (acos 5.0e-01) 1.0471975511965977462e0) (num-test (acos 7.50e-01) 7.2273424781341561118e-1) (num-test (acos 1.0e+00) 0e0) (num-test (acos 2.0e+00) 0+1.3169578969248167086e0i) (num-test (acos 1.0e+01) 0+2.9932228461263808979e0i) (num-test (acos 0.0e+00+0.0e+00i) 1.5707963267948966192e0) (num-test (acos 0.0e+00+1.19209289550781250e-07i) 1.5707963267948966192e0-1.1920928955078096766e-7i) (num-test (acos 0.0e+00-1.19209289550781250e-07i) 1.5707963267948966192e0+1.1920928955078096766e-7i) (num-test (acos 0.0e+00+5.0e-01i) 1.5707963267948966192e0-4.8121182505960344750e-1i) (num-test (acos 0.0e+00-5.0e-01i) 1.5707963267948966192e0+4.8121182505960344750e-1i) (num-test (acos 0.0e+00+1.0e+00i) 1.5707963267948966192e0-8.8137358701954302523e-1i) (num-test (acos 0.0e+00-1.0e+00i) 1.5707963267948966192e0+8.8137358701954302523e-1i) (num-test (acos 0.0e+00+2.0e+00i) 1.5707963267948966192e0-1.4436354751788103425e0i) (num-test (acos 0.0e+00-2.0e+00i) 1.5707963267948966192e0+1.4436354751788103425e0i) (num-test (acos 0.0e+00+8.3886080e+06i) 1.5707963267948966192e0-1.6635532333438690979e1i) (num-test (acos 0.0e+00-8.3886080e+06i) 1.5707963267948966192e0+1.6635532333438690979e1i) (num-test (acos 1.19209289550781250e-07+0.0e+00i) 1.5707962075856070684e0) (num-test (acos -1.19209289550781250e-07+0.0e+00i) 1.570796446004186170e0) (num-test (acos 1.19209289550781250e-07+1.19209289550781250e-07i) 1.5707962075856070685e0-1.1920928955078181469e-7i) (num-test (acos 1.19209289550781250e-07-1.19209289550781250e-07i) 1.5707962075856070685e0+1.1920928955078181469e-7i) (num-test (acos -1.19209289550781250e-07+1.19209289550781250e-07i) 1.570796446004186170e0-1.1920928955078181469e-7i) (num-test (acos -1.19209289550781250e-07-1.19209289550781250e-07i) 1.570796446004186170e0+1.1920928955078181469e-7i) (num-test (acos 1.19209289550781250e-07+5.0e-01i) 1.5707962201708666252e0-4.8121182505960598961e-1i) (num-test (acos 1.19209289550781250e-07-5.0e-01i) 1.5707962201708666252e0+4.8121182505960598961e-1i) (num-test (acos -1.19209289550781250e-07+5.0e-01i) 1.5707964334189266132e0-4.8121182505960598961e-1i) (num-test (acos -1.19209289550781250e-07-5.0e-01i) 1.5707964334189266132e0+4.8121182505960598961e-1i) (num-test (acos 1.19209289550781250e-07+1.0e+00i) 1.5707962425011995974e0-8.8137358701954553738e-1i) (num-test (acos 1.19209289550781250e-07-1.0e+00i) 1.5707962425011995974e0+8.8137358701954553738e-1i) (num-test (acos -1.19209289550781250e-07+1.0e+00i) 1.5707964110885936410e0-8.8137358701954553738e-1i) (num-test (acos -1.19209289550781250e-07-1.0e+00i) 1.5707964110885936410e0+8.8137358701954553738e-1i) (num-test (acos 1.19209289550781250e-07+2.0e+00i) 1.5707962734828816222e0-1.4436354751788116136e0i) (num-test (acos 1.19209289550781250e-07-2.0e+00i) 1.5707962734828816222e0+1.4436354751788116136e0i) (num-test (acos -1.19209289550781250e-07+2.0e+00i) 1.5707963801069116162e0-1.4436354751788116136e0i) (num-test (acos -1.19209289550781250e-07-2.0e+00i) 1.5707963801069116162e0+1.4436354751788116136e0i) (num-test (acos 1.19209289550781250e-07+8.3886080e+06i) 1.5707963267948824084e0-1.6635532333438690979e1i) (num-test (acos 1.19209289550781250e-07-8.3886080e+06i) 1.5707963267948824084e0+1.6635532333438690979e1i) (num-test (acos -1.19209289550781250e-07+8.3886080e+06i) 1.5707963267949108301e0-1.6635532333438690979e1i) (num-test (acos -1.19209289550781250e-07-8.3886080e+06i) 1.5707963267949108301e0+1.6635532333438690979e1i) (num-test (acos 5.0e-01+0.0e+00i) 1.0471975511965977462e0) (num-test (acos -5.0e-01+0.0e+00i) 2.0943951023931954923e0) (num-test (acos 5.0e-01+1.19209289550781250e-07i) 1.0471975511966032159e0-1.3765103082409432364e-7i) (num-test (acos 5.0e-01-1.19209289550781250e-07i) 1.0471975511966032159e0+1.3765103082409432364e-7i) (num-test (acos -5.0e-01+1.19209289550781250e-07i) 2.0943951023931900225e0-1.3765103082409432364e-7i) (num-test (acos -5.0e-01-1.19209289550781250e-07i) 2.0943951023931900225e0+1.3765103082409432364e-7i) (num-test (acos 5.0e-01+5.0e-01i) 1.1185178796437059372e0-5.3063753095251782602e-1i) (num-test (acos 5.0e-01-5.0e-01i) 1.1185178796437059372e0+5.3063753095251782602e-1i) (num-test (acos -5.0e-01+5.0e-01i) 2.0230747739460873013e0-5.3063753095251782602e-1i) (num-test (acos -5.0e-01-5.0e-01i) 2.0230747739460873013e0+5.3063753095251782602e-1i) (num-test (acos 5.0e-01+1.0e+00i) 1.2213572639376833256e0-9.2613303135018242455e-1i) (num-test (acos 5.0e-01-1.0e+00i) 1.2213572639376833256e0+9.2613303135018242455e-1i) (num-test (acos -5.0e-01+1.0e+00i) 1.9202353896521099129e0-9.2613303135018242455e-1i) (num-test (acos -5.0e-01-1.0e+00i) 1.9202353896521099129e0+9.2613303135018242455e-1i) (num-test (acos 5.0e-01+2.0e+00i) 1.3497776911720127603e0-1.4657153519472905218e0i) (num-test (acos 5.0e-01-2.0e+00i) 1.3497776911720127603e0+1.4657153519472905218e0i) (num-test (acos -5.0e-01+2.0e+00i) 1.7918149624177804781e0-1.4657153519472905218e0i) (num-test (acos -5.0e-01-2.0e+00i) 1.7918149624177804781e0+1.4657153519472905218e0i) (num-test (acos 5.0e-01+8.3886080e+06i) 1.5707962671902518438e0-1.6635532333438692755e1i) (num-test (acos 5.0e-01-8.3886080e+06i) 1.5707962671902518438e0+1.6635532333438692755e1i) (num-test (acos -5.0e-01+8.3886080e+06i) 1.5707963863995413946e0-1.6635532333438692755e1i) (num-test (acos -5.0e-01-8.3886080e+06i) 1.5707963863995413946e0+1.6635532333438692755e1i) (num-test (acos 1.0e+00+0.0e+00i) 0e0) (num-test (acos -1.0e+00+0.0e+00i) 3.1415926535897932385e0) (num-test (acos 1.0e+00+1.19209289550781250e-07i) 3.4526697957132450399e-4-3.4526698643116312881e-4i) (num-test (acos 1.0e+00-1.19209289550781250e-07i) 3.4526697957132450399e-4+3.4526698643116312881e-4i) (num-test (acos -1.0e+00+1.19209289550781250e-07i) 3.1412473866102219140e0-3.4526698643116312881e-4i) (num-test (acos -1.0e+00-1.19209289550781250e-07i) 3.1412473866102219140e0+3.4526698643116312881e-4i) (num-test (acos 1.0e+00+5.0e-01i) 6.7488884558600638016e-1-7.3285767597364526089e-1i) (num-test (acos 1.0e+00-5.0e-01i) 6.7488884558600638016e-1+7.3285767597364526089e-1i) (num-test (acos -1.0e+00+5.0e-01i) 2.4667038080037868583e0-7.3285767597364526089e-1i) (num-test (acos -1.0e+00-5.0e-01i) 2.4667038080037868583e0+7.3285767597364526089e-1i) (num-test (acos 1.0e+00+1.0e+00i) 9.0455689430238136413e-1-1.0612750619050356520e0i) (num-test (acos 1.0e+00-1.0e+00i) 9.0455689430238136413e-1+1.0612750619050356520e0i) (num-test (acos -1.0e+00+1.0e+00i) 2.2370357592874118743e0-1.0612750619050356520e0i) (num-test (acos -1.0e+00-1.0e+00i) 2.2370357592874118743e0+1.0612750619050356520e0i) (num-test (acos 1.0e+00+2.0e+00i) 1.1437177404024204938e0-1.5285709194809981613e0i) (num-test (acos 1.0e+00-2.0e+00i) 1.1437177404024204938e0+1.5285709194809981613e0i) (num-test (acos -1.0e+00+2.0e+00i) 1.9978749131873727447e0-1.5285709194809981613e0i) (num-test (acos -1.0e+00-2.0e+00i) 1.9978749131873727447e0+1.5285709194809981613e0i) (num-test (acos 1.0e+00+8.3886080e+06i) 1.5707962075856070685e0-1.6635532333438698084e1i) (num-test (acos 1.0e+00-8.3886080e+06i) 1.5707962075856070685e0+1.6635532333438698084e1i) (num-test (acos -1.0e+00+8.3886080e+06i) 1.570796446004186170e0-1.6635532333438698084e1i) (num-test (acos -1.0e+00-8.3886080e+06i) 1.570796446004186170e0+1.6635532333438698084e1i) (num-test (acos 2.0e+00+0.0e+00i) 0+1.3169578969248167086e0i) (num-test (acos -2.0e+00+0.0e+00i) 3.1415926535897932385e0-1.3169578969248167086e0i) (num-test (acos 2.0e+00+1.19209289550781250e-07i) 6.8825515412047433504e-8-1.3169578969248194435e0i) (num-test (acos 2.0e+00-1.19209289550781250e-07i) 6.8825515412047433504e-8+1.3169578969248194435e0i) (num-test (acos -2.0e+00+1.19209289550781250e-07i) 3.1415925847642778264e0-1.3169578969248194435e0i) (num-test (acos -2.0e+00-1.19209289550781250e-07i) 3.1415925847642778264e0+1.3169578969248194435e0i) (num-test (acos 2.0e+00+5.0e-01i) 2.7775425655771396018e-1-1.3618009008578457882e0i) (num-test (acos 2.0e+00-5.0e-01i) 2.7775425655771396018e-1+1.3618009008578457882e0i) (num-test (acos -2.0e+00+5.0e-01i) 2.8638383970320792783e0-1.3618009008578457882e0i) (num-test (acos -2.0e+00-5.0e-01i) 2.8638383970320792783e0+1.3618009008578457882e0i) (num-test (acos 2.0e+00+1.0e+00i) 5.0735630321714456304e-1-1.4693517443681852733e0i) (num-test (acos 2.0e+00-1.0e+00i) 5.0735630321714456304e-1+1.4693517443681852733e0i) (num-test (acos -2.0e+00+1.0e+00i) 2.6342363503726486754e0-1.4693517443681852733e0i) (num-test (acos -2.0e+00-1.0e+00i) 2.6342363503726486754e0+1.4693517443681852733e0i) (num-test (acos 2.0e+00+2.0e+00i) 8.1654718209685057852e-1-1.7343245214879664480e0i) (num-test (acos 2.0e+00-2.0e+00i) 8.1654718209685057852e-1+1.7343245214879664480e0i) (num-test (acos -2.0e+00+2.0e+00i) 2.3250454714929426599e0-1.7343245214879664480e0i) (num-test (acos -2.0e+00-2.0e+00i) 2.3250454714929426599e0+1.7343245214879664480e0i) (num-test (acos 2.0e+00+8.3886080e+06i) 1.5707960883763175177e0-1.663553233343871940e1i) (num-test (acos 2.0e+00-8.3886080e+06i) 1.5707960883763175177e0+1.663553233343871940e1i) (num-test (acos -2.0e+00+8.3886080e+06i) 1.5707965652134757208e0-1.663553233343871940e1i) (num-test (acos -2.0e+00-8.3886080e+06i) 1.5707965652134757208e0+1.663553233343871940e1i) (num-test (acos 8.3886080e+06+0.0e+00i) 0+1.6635532333438683873e1i) (num-test (acos -8.3886080e+06+0.0e+00i) 3.1415926535897932385e0-1.6635532333438683873e1i) (num-test (acos 8.3886080e+06+1.19209289550781250e-07i) 1.4210854715202104692e-14-1.6635532333438683873e1i) (num-test (acos 8.3886080e+06-1.19209289550781250e-07i) 1.4210854715202104692e-14+1.6635532333438683873e1i) (num-test (acos -8.3886080e+06+1.19209289550781250e-07i) 3.1415926535897790276e0-1.6635532333438683873e1i) (num-test (acos -8.3886080e+06-1.19209289550781250e-07i) 3.1415926535897790276e0+1.6635532333438683873e1i) (num-test (acos 8.3886080e+06+5.0e-01i) 5.9604644775390977930e-8-1.6635532333438685650e1i) (num-test (acos 8.3886080e+06-5.0e-01i) 5.9604644775390977930e-8+1.6635532333438685650e1i) (num-test (acos -8.3886080e+06+5.0e-01i) 3.1415925939851484631e0-1.6635532333438685650e1i) (num-test (acos -8.3886080e+06-5.0e-01i) 3.1415925939851484631e0+1.6635532333438685650e1i) (num-test (acos 8.3886080e+06+1.0e+00i) 1.1920928955078153234e-7-1.6635532333438690979e1i) (num-test (acos 8.3886080e+06-1.0e+00i) 1.1920928955078153234e-7+1.6635532333438690979e1i) (num-test (acos -8.3886080e+06+1.0e+00i) 3.1415925343805036877e0-1.6635532333438690979e1i) (num-test (acos -8.3886080e+06-1.0e+00i) 3.1415925343805036877e0+1.6635532333438690979e1i) (num-test (acos 8.3886080e+06+2.0e+00i) 2.3841857910155967656e-7-1.6635532333438712295e1i) (num-test (acos 8.3886080e+06-2.0e+00i) 2.3841857910155967656e-7+1.6635532333438712295e1i) (num-test (acos -8.3886080e+06+2.0e+00i) 3.1415924151712141369e0-1.6635532333438712295e1i) (num-test (acos -8.3886080e+06-2.0e+00i) 3.1415924151712141369e0+1.6635532333438712295e1i) (num-test (acos 8.3886080e+06+8.3886080e+06i) 7.8539816339745008597e-1-1.6982105923718660081e1i) (num-test (acos 8.3886080e+06-8.3886080e+06i) 7.8539816339745008597e-1+1.6982105923718660081e1i) (num-test (acos -8.3886080e+06+8.3886080e+06i) 2.3561944901923431525e0-1.6982105923718660081e1i) (num-test (acos -8.3886080e+06-8.3886080e+06i) 2.3561944901923431525e0+1.6982105923718660081e1i) (num-test (acos 1234000000/3) 0+20.52806165432143i) (num-test (acos 0.00000001+1234000000.0i) 1.570796326794897-21.62667380877375i) (num-test (acos 3.14159265358979+1234000000.0i) 1.570796324249036-21.62667380877375i) (num-test (acos 2.71828182845905+1234000000.0i) 1.570796324592076-21.62667380877375i) (num-test (acos 1234000000.0+0.00000001i) -4.051865509779873E-10-21.62667394298955i) (num-test (acos 1234000000.0+3.14159265358979i) -4.051865509779873E-10-21.62667394298955i) (num-test (acos 1234000000.0+2.71828182845905i) -4.051865509779873E-10-21.62667394298955i) (num-test (acos -64983.97009220963-48983.30494825104i) 2.495679792792491+12.0i) (num-test (acos -2.225073858507201399999999999999999999996E-308) 1.570796326794896619231321691639751442098E0) (num-test (acos 1.110223024625156799999999999999999999997E-16) 1.570796326794896508209019229124071442098E0) (num-test (acos (/ (sqrt 2) 2)) (/ pi 4)) (num-test (acos (/ (sqrt 3) -2)) (- pi (/ pi 6))) (num-test (acos 1.00001) 0.0+0.004472132228240686i) (for-each (lambda (num-and-val) (let ((num (car num-and-val)) (val (cadr num-and-val))) (num-test-1 'acos num (acos num) val))) (vector (list 0 1.5707963267949) (list 1 0) (list 2 0+1.3169578969248i) (list 3 0+1.7627471740391i) (list -1 3.1415926535898) (list -2 3.1415926535898-1.3169578969248i) (list -3 3.1415926535898-1.7627471740391i) (list 9223372036854775807 0+44.361419555836i) (list -9223372036854775808 3.1415926535898-44.361419555836i) (list 1/2 1.0471975511966) (list 1/3 1.2309594173408) (list -1/2 2.0943951023932) (list -1/3 1.910633236249) (list 1/9223372036854775807 1.5707963267949) (list 0.0 1.5707963267949) (list 1.0 0.0) (list 2.0 0+1.3169578969248i) (list -2.0 3.1415926535898-1.3169578969248i) (list 1.000000000000000000000000000000000000002E-309 1.570796326794896619231321691639751442098E0) (list 1e+16 0+37.534508668465i) (list 0+1i 1.5707963267949-0.88137358701954i) (list 0+2i 1.5707963267949-1.4436354751788i) (list 0-1i 1.5707963267949+0.88137358701954i) (list 1+1i 0.90455689430238-1.061275061905i) (list 1-1i 0.90455689430238+1.061275061905i) (list -1+1i 2.2370357592874-1.061275061905i) (list -1-1i 2.2370357592874+1.061275061905i) (list 0.1+0.1i 1.4711326239351-0.10033029811221i) (list 1e+16+1e+16i 0.78539816339745-37.881082258745i) (list 1e-16+1e-16i 1.5707963267949-1.1102230246252e-16i) )) (let ((err 0.0) (mx 0.0)) (do ((i 0 (+ i 1)) (x -10.0 (+ x .1))) ((= i 200)) (let ((y (magnitude (- x (cos (acos x)))))) (if (> y err) (begin (set! mx x) (set! err y))))) (if (> err 1e-12) (format-logged #t ";(cos (acos ~A)) error: ~A~%" mx err))) (let ((err 0.0) (mx 0.0)) (do ((i 0 (+ i 1)) (x 1.0-i (+ x -0.1+0.1i))) ((= i 200)) (let ((y (magnitude (- x (cos (acos x)))))) (if (> y err) (begin (set! mx x) (set! err y))))) (if (> err 1e-10) (format-logged #t ";(cos (acos ~A)) error: ~A~%" mx err))) (test (acos) 'error) (test (acos "hi") 'error) (test (acos 1.0+23.0i 1.0+23.0i) 'error) (test (acos 0 1) 'error) (for-each (lambda (arg) (test (acos arg) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) (if with-bignums (let ((old-prec (*s7* 'bignum-precision))) (set! (*s7* 'bignum-precision) 500) (let ((acoss (list ; table[Arccos[k/30], {k, 0, 30}] 1.57079632679489661923132169163975144209858469968755291048747229615390 1.53745681753359453223988681086891283292292532113625627655066835871028 1.50408017838467135968591658836938216800673525534100887774094632497961 1.47062890563333682288579851218705812352990872745792336909644844111750 1.43706473738495509057499836447665401198452971694311125503288353691013 1.40334824757520728867804708559611322118362753737131459002168499242061 1.36943840600456582777619613942212803185854661828532452423022105269829 1.33529209007409682793843720770251587561752235709223993234205546563727 1.30086353096149317480670670185123279844211132541734789265785186982011 1.26610367277949911125931873041222227514402466798077652309449434740743 1.23095941734077468213492917824798737571034000935509483905554833366399 1.19537271881385721554615623455760435715187934648129893552739216960977 1.15927948072740859984658379402241583724288356456052705870352551545381 1.12260819081546532929088412859068667091828551922412210328535011759677 1.08527820449930545595908733261492699446689960474554094922793682396904 1.04719755119659774615421446109316762806572313312503527365831486410260 1.00826008225104099949999603469121825039880976563585012769196847054621 0.96834169340990606798268790382508246937722069157058123211232815740883 0.92729521800161223242851246292242880405707410857224052762186617744039 0.88494336217618586326804097370954035732954766028628186644588911389624 0.84106867056793025577652503182643074670207878563983921977852280469208 0.79539883018414355549096833892476432854279596104639091688975233242118 0.74758434966902079779334463157739345981404639083611183363842437021388 0.69716313364223229572063988249255120236401774508773180005252393361250 0.64350110879328438680280922871732263804151059111531238286560611871351 0.58568554345715095961775753847751776620036106717164150265055932722126 0.52231482180604862252409882585570327600888093754313181958478744889757 0.45102681179626243254464463579435182620342251328425002811179043223947 0.36720802055783714250547291370122530624718492018835635003632767844945 0.25892154200622121576539021530016406277243818456467068559928913571945 0.00000000000000000000000000000000000000000000000000000000000000000000e0))) (do ((i 0 (+ i 1))) ((= i 30)) (let ((val (acos (/ i (bignum "30"))))) (if (> (magnitude (- val (list-ref acoss i))) 1e-36) (format-logged #t ";(acos ~A) -> ~A ~A~%[~A]~%" (/ i 30) val (list-ref acoss i) (magnitude (- val (list-ref acoss i)))))))) (set! (*s7* 'bignum-precision) old-prec))) ;;; -------------------------------------------------------------------------------- ;;; atan ;;; -------------------------------------------------------------------------------- (num-test (atan 0) 0.0) (num-test (atan 1) 0.78539816339745) (num-test (atan -1) -0.78539816339745) (num-test (atan 2) 1.10714871779409) (num-test (atan -2) -1.10714871779409) (num-test (atan 3) 1.24904577239825) (num-test (atan -3) -1.24904577239825) (num-test (atan 10) 1.47112767430373) (num-test (atan -10) -1.47112767430373) (num-test (atan 1234) 1.56998595420081) (num-test (atan -1234) -1.56998595420081) (num-test (atan 0/1) 0.0) (num-test (atan 0/2) 0.0) (num-test (atan 0/3) 0.0) (num-test (atan 0/10) 0.0) (num-test (atan 0/1234) 0.0) (num-test (atan 0/1234000000) 0.0) (num-test (atan 0/500029) 0.0) (num-test (atan 0/362880) 0.0) (num-test (atan 1/1) 0.78539816339745) (num-test (atan -1/1) -0.78539816339745) (num-test (atan 1/2) 0.46364760900081) (num-test (atan -1/2) -0.46364760900081) (num-test (atan 1/3) 0.32175055439664) (num-test (atan -1/3) -0.32175055439664) (num-test (atan 1/10) 0.09966865249116) (num-test (atan -1/10) -0.09966865249116) (num-test (atan 1/1234) 0.00081037259408) (num-test (atan -1/1234) -0.00081037259408) (num-test (atan 1/1234000000) 0.00000000081037) (num-test (atan -1/1234000000) -0.00000000081037) (num-test (atan 1/500029) 0.00000199988401) (num-test (atan -1/500029) -0.00000199988401) (num-test (atan 1/362880) 0.00000275573192) (num-test (atan -1/362880) -0.00000275573192) (num-test (atan 2/1) 1.10714871779409) (num-test (atan -2/1) -1.10714871779409) (num-test (atan 2/2) 0.78539816339745) (num-test (atan -2/2) -0.78539816339745) (num-test (atan 2/3) 0.58800260354757) (num-test (atan -2/3) -0.58800260354757) (num-test (atan 2/10) 0.19739555984988) (num-test (atan -2/10) -0.19739555984988) (num-test (atan 2/1234) 0.00162074412382) (num-test (atan -2/1234) -0.00162074412382) (num-test (atan 2/1234000000) 0.00000000162075) (num-test (atan -2/1234000000) -0.00000000162075) (num-test (atan 2/500029) 0.00000399976801) (num-test (atan -2/500029) -0.00000399976801) (num-test (atan 2/362880) 0.00000551146384) (num-test (atan -2/362880) -0.00000551146384) (num-test (atan 3/1) 1.24904577239825) (num-test (atan -3/1) -1.24904577239825) (num-test (atan 3/2) 0.98279372324733) (num-test (atan -3/2) -0.98279372324733) (num-test (atan 3/3) 0.78539816339745) (num-test (atan -3/3) -0.78539816339745) (num-test (atan 3/10) 0.29145679447787) (num-test (atan -3/10) -0.29145679447787) (num-test (atan 3/1234) 0.00243111352487) (num-test (atan -3/1234) -0.00243111352487) (num-test (atan 3/1234000000) 0.00000000243112) (num-test (atan -3/1234000000) -0.00000000243112) (num-test (atan 3/500029) 0.00000599965202) (num-test (atan -3/500029) -0.00000599965202) (num-test (atan 3/362880) 0.00000826719577) (num-test (atan -3/362880) -0.00000826719577) (num-test (atan 10/1) 1.47112767430373) (num-test (atan -10/1) -1.47112767430373) (num-test (atan 10/2) 1.37340076694502) (num-test (atan -10/2) -1.37340076694502) (num-test (atan 10/3) 1.27933953231703) (num-test (atan -10/3) -1.27933953231703) (num-test (atan 10/10) 0.78539816339745) (num-test (atan -10/10) -0.78539816339745) (num-test (atan 10/1234) 0.00810355033005) (num-test (atan -10/1234) -0.00810355033005) (num-test (atan 10/1234000000) 0.00000000810373) (num-test (atan -10/1234000000) -0.00000000810373) (num-test (atan 10/500029) 0.00001999884006) (num-test (atan -10/500029) -0.00001999884006) (num-test (atan 10/362880) 0.00002755731922) (num-test (atan -10/362880) -0.00002755731922) (num-test (atan 1234/1) 1.56998595420081) (num-test (atan -1234/1) -1.56998595420081) (num-test (atan 1234/2) 1.56917558267108) (num-test (atan -1234/2) -1.56917558267108) (num-test (atan 1234/3) 1.56836521327003) (num-test (atan -1234/3) -1.56836521327003) (num-test (atan 1234/10) 1.56269277646485) (num-test (atan -1234/10) -1.56269277646485) (num-test (atan 1234/1234) 0.78539816339745) (num-test (atan -1234/1234) -0.78539816339745) (num-test (atan 1234/1234000000) 0.00000100000000) (num-test (atan -1234/1234000000) -0.00000100000000) (num-test (atan 1234/500029) 0.00246785185431) (num-test (atan -1234/500029) -0.00246785185431) (num-test (atan 1234/362880) 0.00340056008437) (num-test (atan -1234/362880) -0.00340056008437) (num-test (atan 1234000000/1234000000) 0.78539816339745) (num-test (atan -1234000000/1234000000) -0.78539816339745) (num-test (atan 1234000000/500029) 1.57039111693053) (num-test (atan -1234000000/500029) -1.57039111693053) (num-test (atan 1234000000/362880) 1.57050225873206) (num-test (atan -1234000000/362880) -1.57050225873206) (num-test (atan 500029/2) 1.57079232702688) (num-test (atan -500029/2) -1.57079232702688) (num-test (atan 500029/3) 1.57079032714288) (num-test (atan -500029/3) -1.57079032714288) (num-test (atan 500029/10) 1.57077632795483) (num-test (atan -500029/10) -1.57077632795483) (num-test (atan 500029/1234) 1.56832847494059) (num-test (atan -500029/1234) -1.56832847494059) (num-test (atan 500029/1234000000) 0.00040520986437) (num-test (atan -500029/1234000000) -0.00040520986437) (num-test (atan 500029/500029) 0.78539816339745) (num-test (atan -500029/500029) -0.78539816339745) (num-test (atan 500029/362880) 0.94301772831206) (num-test (atan -500029/362880) -0.94301772831206) (num-test (atan 362880/2) 1.57079081533105) (num-test (atan -362880/2) -1.57079081533105) (num-test (atan 362880/3) 1.57078805959913) (num-test (atan -362880/3) -1.57078805959913) (num-test (atan 362880/10) 1.57076876947568) (num-test (atan -362880/10) -1.57076876947568) (num-test (atan 362880/1234) 1.56739576671053) (num-test (atan -362880/1234) -1.56739576671053) (num-test (atan 362880/1234000000) 0.00029406806284) (num-test (atan -362880/1234000000) -0.00029406806284) (num-test (atan 362880/500029) 0.62777859848283) (num-test (atan -362880/500029) -0.62777859848283) (num-test (atan 362880/362880) 0.78539816339745) (num-test (atan -362880/362880) -0.78539816339745) (num-test (atan 0.0) 0.0) (num-test (atan 0.00000001) 0.00000001) (num-test (atan -0.00000001) -0.00000001) (num-test (atan 1.0) 0.78539816339745) (num-test (atan -1.0) -0.78539816339745) (num-test (atan pi) 1.26262725567891) (num-test (atan -3.14159265358979) -1.26262725567891) (num-test (atan 2.71828182845905) 1.21828290501728) (num-test (atan -2.71828182845905) -1.21828290501728) (num-test (atan 1234.0) 1.56998595420081) (num-test (atan -1234.0) -1.56998595420081) (num-test (atan 0.0+0.0i) 0.0) (num-test (atan -0.0+0.0i) 0.0) (num-test (atan 0.0-0.0i) 0.0) (num-test (atan -0.0-0.0i) 0.0) (num-test (atan 0.0+0.00000001i) 0.0+0.00000001i) (num-test (atan -0.0+0.00000001i) 0.0+0.00000001i) (num-test (atan 0.0-0.00000001i) 0.0-0.00000001i) (num-test (atan -0.0-0.00000001i) -0.0-0.00000001i) (num-test (atan 0.0+3.14159265358979i) 1.57079632679490+0.32976531495670i) (num-test (atan -0.0+3.14159265358979i) 1.57079632679490+0.32976531495670i) (num-test (atan 0.0-3.14159265358979i) 1.57079632679490-0.32976531495670i) (num-test (atan -0.0-3.14159265358979i) -1.57079632679490-0.32976531495670i) (num-test (atan 0.0+2.71828182845905i) 1.57079632679490+0.38596841645265i) (num-test (atan -0.0+2.71828182845905i) 1.57079632679490+0.38596841645265i) (num-test (atan 0.0-2.71828182845905i) 1.57079632679490-0.38596841645265i) (num-test (atan -0.0-2.71828182845905i) -1.57079632679490-0.38596841645265i) (num-test (atan 0.0+1234.0i) 1.57079632679490+0.00081037294887i) (num-test (atan -0.0+1234.0i) 1.57079632679490+0.00081037294887i) (num-test (atan 0.0-1234.0i) 1.57079632679490-0.00081037294887i) (num-test (atan -0.0-1234.0i) -1.57079632679490-0.00081037294887i) (num-test (atan 0.00000001+0.0i) 0.00000001) (num-test (atan -0.00000001+0.0i) -0.00000001) (num-test (atan 0.00000001-0.0i) 0.00000001) (num-test (atan -0.00000001-0.0i) -0.00000001) (num-test (atan 0.00000001+0.00000001i) 0.00000001+0.00000001i) (num-test (atan -0.00000001+0.00000001i) -0.00000001+0.00000001i) (num-test (atan 0.00000001-0.00000001i) 0.00000001-0.00000001i) (num-test (atan -0.00000001-0.00000001i) -0.00000001-0.00000001i) (num-test (atan 0.00000001+1.0i) 0.78539816589789+9.55691396225616i) (num-test (atan -0.00000001+1.0i) -0.78539816589789+9.55691396225616i) (num-test (atan 0.00000001-1.0i) 0.78539816589789-9.55691396225616i) (num-test (atan -0.00000001-1.0i) -0.78539816589789-9.55691396225616i) (num-test (atan 0.00000001+3.14159265358979i) 1.57079632566745+0.32976531495670i) (num-test (atan -0.00000001+3.14159265358979i) -1.57079632566745+0.32976531495670i) (num-test (atan 0.00000001-3.14159265358979i) 1.57079632566745-0.32976531495670i) (num-test (atan -0.00000001-3.14159265358979i) -1.57079632566745-0.32976531495670i) (num-test (atan 0.00000001+2.71828182845905i) 1.57079632522972+0.38596841645265i) (num-test (atan -0.00000001+2.71828182845905i) -1.57079632522972+0.38596841645265i) (num-test (atan 0.00000001-2.71828182845905i) 1.57079632522972-0.38596841645265i) (num-test (atan -0.00000001-2.71828182845905i) -1.57079632522972-0.38596841645265i) (num-test (atan 0.00000001+1234.0i) 1.57079632679489+0.00081037294887i) (num-test (atan -0.00000001+1234.0i) -1.57079632679489+0.00081037294887i) (num-test (atan 0.00000001-1234.0i) 1.57079632679489-0.00081037294887i) (num-test (atan -0.00000001-1234.0i) -1.57079632679489-0.00081037294887i) (num-test (atan 1.0+0.0i) 0.78539816339745) (num-test (atan -1.0+0.0i) -0.78539816339745) (num-test (atan 1.0-0.0i) 0.78539816339745) (num-test (atan -1.0-0.0i) -0.78539816339745) (num-test (atan 1.0+0.00000001i) 0.78539816339745+0.00000000500000i) (num-test (atan -1.0+0.00000001i) -0.78539816339745+0.00000000500000i) (num-test (atan 1.0-0.00000001i) 0.78539816339745-0.00000000500000i) (num-test (atan -1.0-0.00000001i) -0.78539816339745-0.00000000500000i) (num-test (atan 1.0+1.0i) 1.01722196789785+0.40235947810853i) (num-test (atan -1.0+1.0i) -1.01722196789785+0.40235947810853i) (num-test (atan 1.0-1.0i) 1.01722196789785-0.40235947810853i) (num-test (atan -1.0-1.0i) -1.01722196789785-0.40235947810853i) (num-test (atan 1.0+3.14159265358979i) 1.47082882591946+0.29462144034086i) (num-test (atan -1.0+3.14159265358979i) -1.47082882591946+0.29462144034086i) (num-test (atan 1.0-3.14159265358979i) 1.47082882591946-0.29462144034086i) (num-test (atan -1.0-3.14159265358979i) -1.47082882591946-0.29462144034086i) (num-test (atan 1.0+2.71828182845905i) 1.43862796047891+0.33050259272341i) (num-test (atan -1.0+2.71828182845905i) -1.43862796047891+0.33050259272341i) (num-test (atan 1.0-2.71828182845905i) 1.43862796047891-0.33050259272341i) (num-test (atan -1.0-2.71828182845905i) -1.43862796047891-0.33050259272341i) (num-test (atan 1.0+1234.0i) 1.57079567009087+0.00081037241669i) (num-test (atan -1.0+1234.0i) -1.57079567009087+0.00081037241669i) (num-test (atan 1.0-1234.0i) 1.57079567009087-0.00081037241669i) (num-test (atan -1.0-1234.0i) -1.57079567009087-0.00081037241669i) (num-test (atan 3.14159265358979+0.0i) 1.26262725567891) (num-test (atan -3.14159265358979+0.0i) -1.26262725567891) (num-test (atan 3.14159265358979-0.0i) 1.26262725567891) (num-test (atan -3.14159265358979-0.0i) -1.26262725567891) (num-test (atan 3.14159265358979+0.00000001i) 1.26262725567891+0.00000000092000i) (num-test (atan -3.14159265358979+0.00000001i) -1.26262725567891+0.00000000092000i) (num-test (atan 3.14159265358979-0.00000001i) 1.26262725567891-0.00000000092000i) (num-test (atan -3.14159265358979-0.00000001i) -1.26262725567891-0.00000000092000i) (num-test (atan 3.14159265358979+1.0i) 1.28734057432439+0.08505998507745i) (num-test (atan -3.14159265358979+1.0i) -1.28734057432439+0.08505998507745i) (num-test (atan 3.14159265358979-1.0i) 1.28734057432439-0.08505998507745i) (num-test (atan -3.14159265358979-1.0i) -1.28734057432439-0.08505998507745i) (num-test (atan 3.14159265358979+3.14159265358979i) 1.40903828502376+0.15638868878130i) (num-test (atan -3.14159265358979+3.14159265358979i) -1.40903828502376+0.15638868878130i) (num-test (atan 3.14159265358979-3.14159265358979i) 1.40903828502376-0.15638868878130i) (num-test (atan -3.14159265358979-3.14159265358979i) -1.40903828502376-0.15638868878130i) (num-test (atan 3.14159265358979+2.71828182845905i) 1.38641010899673+0.15352587926173i) (num-test (atan -3.14159265358979+2.71828182845905i) -1.38641010899673+0.15352587926173i) (num-test (atan 3.14159265358979-2.71828182845905i) 1.38641010899673-0.15352587926173i) (num-test (atan -3.14159265358979-2.71828182845905i) -1.38641010899673-0.15352587926173i) (num-test (atan 3.14159265358979+1234.0i) 1.57079426371036+0.00081036769654i) (num-test (atan -3.14159265358979+1234.0i) -1.57079426371036+0.00081036769654i) (num-test (atan 3.14159265358979-1234.0i) 1.57079426371036-0.00081036769654i) (num-test (atan -3.14159265358979-1234.0i) -1.57079426371036-0.00081036769654i) (num-test (atan 2.71828182845905+0.0i) 1.21828290501728) (num-test (atan -2.71828182845905+0.0i) -1.21828290501728) (num-test (atan 2.71828182845905-0.0i) 1.21828290501728) (num-test (atan -2.71828182845905-0.0i) -1.21828290501728) (num-test (atan 2.71828182845905+0.00000001i) 1.21828290501728+0.00000000119203i) (num-test (atan -2.71828182845905+0.00000001i) -1.21828290501728+0.00000000119203i) (num-test (atan 2.71828182845905-0.00000001i) 1.21828290501728-0.00000000119203i) (num-test (atan -2.71828182845905-0.00000001i) -1.21828290501728-0.00000000119203i) (num-test (atan 2.71828182845905+1.0i) 1.25363416718071+0.10816322574795i) (num-test (atan -2.71828182845905+1.0i) -1.25363416718071+0.10816322574795i) (num-test (atan 2.71828182845905-1.0i) 1.25363416718071-0.10816322574795i) (num-test (atan -2.71828182845905-1.0i) -1.25363416718071-0.10816322574795i) (num-test (atan 2.71828182845905+3.14159265358979i) 1.40945039787275+0.17937970703436i) (num-test (atan -2.71828182845905+3.14159265358979i) -1.40945039787275+0.17937970703436i) (num-test (atan 2.71828182845905-3.14159265358979i) 1.40945039787275-0.17937970703436i) (num-test (atan -2.71828182845905-3.14159265358979i) -1.40945039787275-0.17937970703436i) (num-test (atan 2.71828182845905+2.71828182845905i) 1.38288382352616+0.17963089485802i) (num-test (atan -2.71828182845905+2.71828182845905i) -1.38288382352616+0.17963089485802i) (num-test (atan 2.71828182845905-2.71828182845905i) 1.38288382352616-0.17963089485802i) (num-test (atan -2.71828182845905-2.71828182845905i) -1.38288382352616-0.17963089485802i) (num-test (atan 2.71828182845905+1234.0i) 1.57079454169576+0.00081036901661i) (num-test (atan -2.71828182845905+1234.0i) -1.57079454169576+0.00081036901661i) (num-test (atan 2.71828182845905-1234.0i) 1.57079454169576-0.00081036901661i) (num-test (atan -2.71828182845905-1234.0i) -1.57079454169576-0.00081036901661i) (num-test (atan 1234.0+0.0i) 1.56998595420081) (num-test (atan -1234.0+0.0i) -1.56998595420081) (num-test (atan 1234.0-0.0i) 1.56998595420081) (num-test (atan -1234.0-0.0i) -1.56998595420081) (num-test (atan 1234.0+0.00000001i) 1.56998595420081+0.00000000000001i) (num-test (atan -1234.0+0.00000001i) -1.56998595420081+0.00000000000001i) (num-test (atan 1234.0-0.00000001i) 1.56998595420081-0.00000000000001i) (num-test (atan -1234.0-0.00000001i) -1.56998595420081-0.00000000000001i) (num-test (atan 1234.0+1.0i) 1.56998595473299+0.00000065670317i) (num-test (atan -1234.0+1.0i) -1.56998595473299+0.00000065670317i) (num-test (atan 1234.0-1.0i) 1.56998595473299-0.00000065670317i) (num-test (atan -1234.0-1.0i) -1.56998595473299-0.00000065670317i) (num-test (atan 1234.0+3.14159265358979i) 1.56998595945313+0.00000206308183i) (num-test (atan -1234.0+3.14159265358979i) -1.56998595945313+0.00000206308183i) (num-test (atan 1234.0-3.14159265358979i) 1.56998595945313-0.00000206308183i) (num-test (atan -1234.0-3.14159265358979i) -1.56998595945313-0.00000206308183i) (num-test (atan 1234.0+2.71828182845905i) 1.56998595813306+0.00000178509679i) (num-test (atan -1234.0+2.71828182845905i) -1.56998595813306+0.00000178509679i) (num-test (atan 1234.0-2.71828182845905i) 1.56998595813306-0.00000178509679i) (num-test (atan -1234.0-2.71828182845905i) -1.56998595813306-0.00000178509679i) (num-test (atan 1234.0+1234.0i) 1.57039114036481+0.00040518634139i) (num-test (atan -1234.0+1234.0i) -1.57039114036481+0.00040518634139i) (num-test (atan 1234.0-1234.0i) 1.57039114036481-0.00040518634139i) (num-test (atan -1234.0-1234.0i) -1.57039114036481-0.00040518634139i) (num-test (atan 6.9279836e-17) 6.9279836e-17) (num-test (atan 1.7976931e+308) 1.5707963267949) (num-test (atan 0 0) 0.0) (num-test (atan 0 1.0) 0.0) (num-test (atan 0 -1.0) pi) (num-test (atan 1.0 0) (/ pi 2)) (num-test (atan -1.0 0) (/ pi -2)) (num-test (atan 0.0 0.0) 0.0) (num-test (atan 0.0 0.00000001) 0.0) (num-test (atan 0.0 1.0) 0.0) (num-test (atan 0.0 pi) 0.0) (num-test (atan 0.0 2.71828182845905) 0.0) (num-test (atan 0.0 1234.0) 0.0) (num-test (atan 0.0 1234000000.0) 0.0) (num-test (atan 0.00000001 0.0) 1.57079632679490) (num-test (atan 0.00000001 0.00000001) 0.78539816339745) (num-test (atan 0.00000001 1.0) 0.00000001) (num-test (atan 0.00000001 pi) 0.00000000318310) (num-test (atan 0.00000001 2.71828182845905) 0.00000000367879) (num-test (atan 0.00000001 1234.0) 0.00000000000810) (num-test (atan 0.00000001 1234000000.0) 0.0) (num-test (atan 1.0 0.0) 1.57079632679490) (num-test (atan 1.0 0.00000001) 1.57079631679490) (num-test (atan 1.0 1.0) 0.78539816339745) (num-test (atan 1.0 pi) 0.30816907111598) (num-test (atan 1.0 2.71828182845905) 0.35251342177762) (num-test (atan 1.0 1234.0) 0.00081037259408) (num-test (atan 1.0 1234000000.0) 0.00000000081037) (num-test (atan 3.14159265358979 0.0) 1.57079632679490) (num-test (atan 3.14159265358979 0.00000001) 1.57079632361180) (num-test (atan 3.14159265358979 1.0) 1.26262725567891) (num-test (atan 3.14159265358979 pi) 0.78539816339745) (num-test (atan 3.14159265358979 2.71828182845905) 0.85751178635585) (num-test (atan 3.14159265358979 1234.0) 0.00254585564530) (num-test (atan 3.14159265358979 1234000000.0) 0.00000000254586) (num-test (atan 2.71828182845905 0.0) 1.57079632679490) (num-test (atan 2.71828182845905 0.00000001) 1.57079632311610) (num-test (atan 2.71828182845905 1.0) 1.21828290501728) (num-test (atan 2.71828182845905 pi) 0.71328454043905) (num-test (atan 2.71828182845905 2.71828182845905) 0.78539816339745) (num-test (atan 2.71828182845905 1234.0) 0.00220281801598) (num-test (atan 2.71828182845905 1234000000.0) 0.00000000220282) (num-test (atan 1234.0 0.0) 1.57079632679490) (num-test (atan 1234.0 0.00000001) 1.57079632678679) (num-test (atan 1234.0 1.0) 1.56998595420081) (num-test (atan 1234.0 pi) 1.56825047114960) (num-test (atan 1234.0 2.71828182845905) 1.56859350877892) (num-test (atan 1234.0 1234.0) 0.78539816339745) (num-test (atan 1234.0 1234000000.0) 0.00000100000000) (num-test (atan 1234000000.0 0.0) 1.57079632679490) (num-test (atan 1234000000.0 0.00000001) 1.57079632679490) (num-test (atan 1234000000.0 1.0) 1.57079632598452) (num-test (atan 1234000000.0 pi) 1.57079632424904) (num-test (atan 1234000000.0 2.71828182845905) 1.57079632459208) (num-test (atan 1234000000.0 1234.0) 1.57079532679490) (num-test (atan 1234000000.0 1234000000.0) 0.78539816339745) (num-test (atan 1234000000/3) 1.570796324363778) (num-test (atan 0.00000001+1234000000.0i) +1.570796326794897+8.103727714748784E-10i) (num-test (atan 3.14159265358979+1234000000.0i) +1.570796326794897+8.103727714748784E-10i) (num-test (atan 2.71828182845905+1234000000.0i) +1.570796326794897+8.103727714748784E-10i) (num-test (atan 1234000000.0+0.00000001i) +1.570796325984524+6.567040287478756E-27i) (num-test (atan 1234000000.0+3.14159265358979i) +1.570796325984524+2.063096552297151E-18i) (num-test (atan 1234000000.0+2.71828182845905i) +1.570796325984524+1.785106628021167E-18i) (num-test (atan 1) 0.7853981633974483) (num-test (atan 0.0e+00+0.0e+00i) 0e0) (num-test (atan 0.0e+00+1.19209289550781250e-07i) 0+1.1920928955078181469e-7i) (num-test (atan 0.0e+00-1.19209289550781250e-07i) 0-1.1920928955078181469e-7i) (num-test (atan 0.0e+00+5.0e-01i) 0+5.4930614433405484570e-1i) (num-test (atan 0.0e+00-5.0e-01i) 0-5.4930614433405484570e-1i) (num-test (atan 0.0e+00+2.0e+00i) 1.5707963267948966192e0+5.4930614433405484570e-1i) (num-test (atan 0.0e+00-2.0e+00i) -1.5707963267948966192e0-5.4930614433405484570e-1i) (num-test (atan 0.0e+00+8.3886080e+06i) 1.5707963267948966192e0+1.1920928955078181469e-7i) (num-test (atan 0.0e+00-8.3886080e+06i) -1.5707963267948966192e0-1.1920928955078181469e-7i) (num-test (atan 1.19209289550781250e-07+0.0e+00i) 1.1920928955078068531e-7) (num-test (atan -1.19209289550781250e-07+0.0e+00i) -1.1920928955078068531e-7) (num-test (atan 1.19209289550781250e-07+1.19209289550781250e-07i) 1.1920928955078237938e-7+1.1920928955078012062e-7i) (num-test (atan 1.19209289550781250e-07-1.19209289550781250e-07i) 1.1920928955078237938e-7-1.1920928955078012062e-7i) (num-test (atan -1.19209289550781250e-07+1.19209289550781250e-07i) -1.1920928955078237938e-7+1.1920928955078012062e-7i) (num-test (atan -1.19209289550781250e-07-1.19209289550781250e-07i) -1.1920928955078237938e-7-1.1920928955078012062e-7i) (num-test (atan 1.19209289550781250e-07+5.0e-01i) 1.5894571940103932425e-7+5.4930614433404221383e-1i) (num-test (atan 1.19209289550781250e-07-5.0e-01i) 1.5894571940103932425e-7-5.4930614433404221383e-1i) (num-test (atan -1.19209289550781250e-07+5.0e-01i) -1.5894571940103932425e-7+5.4930614433404221383e-1i) (num-test (atan -1.19209289550781250e-07-5.0e-01i) -1.5894571940103932425e-7-5.4930614433404221383e-1i) (num-test (atan 1.19209289550781250e-07+1.0e+00i) 7.8539819319977069731e-1+8.3177661667193446012e0i) (num-test (atan 1.19209289550781250e-07-1.0e+00i) 7.8539819319977069731e-1-8.3177661667193446012e0i) (num-test (atan -1.19209289550781250e-07+1.0e+00i) -7.8539819319977069731e-1+8.3177661667193446012e0i) (num-test (atan -1.19209289550781250e-07-1.0e+00i) -7.8539819319977069731e-1-8.3177661667193446012e0i) (num-test (atan 1.19209289550781250e-07+2.0e+00i) 1.5707962870584667690e0+5.4930614433405168773e-1i) (num-test (atan 1.19209289550781250e-07-2.0e+00i) 1.5707962870584667690e0-5.4930614433405168773e-1i) (num-test (atan -1.19209289550781250e-07+2.0e+00i) -1.5707962870584667690e0+5.4930614433405168773e-1i) (num-test (atan -1.19209289550781250e-07-2.0e+00i) -1.5707962870584667690e0-5.4930614433405168773e-1i) (num-test (atan 1.19209289550781250e-07+8.3886080e+06i) 1.5707963267948966192e0+1.1920928955078181469e-7i) (num-test (atan 1.19209289550781250e-07-8.3886080e+06i) 1.5707963267948966192e0-1.1920928955078181469e-7i) (num-test (atan -1.19209289550781250e-07+8.3886080e+06i) -1.5707963267948966192e0+1.1920928955078181469e-7i) (num-test (atan -1.19209289550781250e-07-8.3886080e+06i) -1.5707963267948966192e0-1.1920928955078181469e-7i) (num-test (atan 5.0e-01+0.0e+00i) 4.6364760900080611621e-1) (num-test (atan -5.0e-01+0.0e+00i) -4.6364760900080611621e-1) (num-test (atan 5.0e-01+1.19209289550781250e-07i) 4.6364760900081066369e-1+9.5367431640625072280e-8i) (num-test (atan 5.0e-01-1.19209289550781250e-07i) 4.6364760900081066369e-1-9.5367431640625072280e-8i) (num-test (atan -5.0e-01+1.19209289550781250e-07i) -4.6364760900081066369e-1+9.5367431640625072280e-8i) (num-test (atan -5.0e-01-1.19209289550781250e-07i) -4.6364760900081066369e-1-9.5367431640625072280e-8i) (num-test (atan 5.0e-01+5.0e-01i) 5.5357435889704525151e-1+4.0235947810852509365e-1i) (num-test (atan 5.0e-01-5.0e-01i) 5.5357435889704525151e-1-4.0235947810852509365e-1i) (num-test (atan -5.0e-01+5.0e-01i) -5.5357435889704525151e-1+4.0235947810852509365e-1i) (num-test (atan -5.0e-01-5.0e-01i) -5.5357435889704525151e-1-4.0235947810852509365e-1i) (num-test (atan 5.0e-01+1.0e+00i) 9.0788749496088038670e-1+7.0830333601405402006e-1i) (num-test (atan 5.0e-01-1.0e+00i) 9.0788749496088038670e-1-7.0830333601405402006e-1i) (num-test (atan -5.0e-01+1.0e+00i) -9.0788749496088038670e-1+7.0830333601405402006e-1i) (num-test (atan -5.0e-01-1.0e+00i) -9.0788749496088038670e-1-7.0830333601405402006e-1i) (num-test (atan 5.0e-01+2.0e+00i) 1.4215468610018069803e0+5.0037000005253101744e-1i) (num-test (atan 5.0e-01-2.0e+00i) 1.4215468610018069803e0-5.0037000005253101744e-1i) (num-test (atan -5.0e-01+2.0e+00i) -1.4215468610018069803e0+5.0037000005253101744e-1i) (num-test (atan -5.0e-01-2.0e+00i) -1.4215468610018069803e0-5.0037000005253101744e-1i) (num-test (atan 5.0e-01+8.3886080e+06i) 1.5707963267948895138e0+1.1920928955078139117e-7i) (num-test (atan 5.0e-01-8.3886080e+06i) 1.5707963267948895138e0-1.1920928955078139117e-7i) (num-test (atan -5.0e-01+8.3886080e+06i) -1.5707963267948895138e0+1.1920928955078139117e-7i) (num-test (atan -5.0e-01-8.3886080e+06i) -1.5707963267948895138e0-1.1920928955078139117e-7i) (num-test (atan 1.0e+00+0.0e+00i) 7.8539816339744830962e-1) (num-test (atan -1.0e+00+0.0e+00i) -7.8539816339744830962e-1) (num-test (atan 1.0e+00+1.19209289550781250e-07i) 7.8539816339745186233e-1+5.9604644775390483828e-8i) (num-test (atan 1.0e+00-1.19209289550781250e-07i) 7.8539816339745186233e-1-5.9604644775390483828e-8i) (num-test (atan -1.0e+00+1.19209289550781250e-07i) -7.8539816339745186233e-1+5.9604644775390483828e-8i) (num-test (atan -1.0e+00-1.19209289550781250e-07i) -7.8539816339745186233e-1-5.9604644775390483828e-8i) (num-test (atan 1.0e+00+5.0e-01i) 8.4757566067082902713e-1+2.3887786125685909036e-1i) (num-test (atan 1.0e+00-5.0e-01i) 8.4757566067082902713e-1-2.3887786125685909036e-1i) (num-test (atan -1.0e+00+5.0e-01i) -8.4757566067082902713e-1+2.3887786125685909036e-1i) (num-test (atan -1.0e+00-5.0e-01i) -8.4757566067082902713e-1-2.3887786125685909036e-1i) (num-test (atan 1.0e+00+1.0e+00i) 1.0172219678978513677e0+4.0235947810852509365e-1i) (num-test (atan 1.0e+00-1.0e+00i) 1.0172219678978513677e0-4.0235947810852509365e-1i) (num-test (atan -1.0e+00+1.0e+00i) -1.0172219678978513677e0+4.0235947810852509365e-1i) (num-test (atan -1.0e+00-1.0e+00i) -1.0172219678978513677e0-4.0235947810852509365e-1i) (num-test (atan 1.0e+00+2.0e+00i) 1.3389725222944935611e0+4.0235947810852509365e-1i) (num-test (atan 1.0e+00-2.0e+00i) 1.3389725222944935611e0-4.0235947810852509365e-1i) (num-test (atan -1.0e+00+2.0e+00i) -1.3389725222944935611e0+4.0235947810852509365e-1i) (num-test (atan -1.0e+00-2.0e+00i) -1.3389725222944935611e0-4.0235947810852509365e-1i) (num-test (atan 1.0e+00+8.3886080e+06i) 1.5707963267948824084e0+1.1920928955078012062e-7i) (num-test (atan 1.0e+00-8.3886080e+06i) 1.5707963267948824084e0-1.1920928955078012062e-7i) (num-test (atan -1.0e+00+8.3886080e+06i) -1.5707963267948824084e0+1.1920928955078012062e-7i) (num-test (atan -1.0e+00-8.3886080e+06i) -1.5707963267948824084e0-1.1920928955078012062e-7i) (num-test (atan 2.0e+00+0.0e+00i) 1.1071487177940905030e0) (num-test (atan -2.0e+00+0.0e+00i) -1.1071487177940905030e0) (num-test (atan 2.0e+00+1.19209289550781250e-07i) 1.1071487177940916399e0+2.3841857910156200307e-8i) (num-test (atan 2.0e+00-1.19209289550781250e-07i) 1.1071487177940916399e0-2.3841857910156200307e-8i) (num-test (atan -2.0e+00+1.19209289550781250e-07i) -1.1071487177940916399e0+2.3841857910156200307e-8i) (num-test (atan -2.0e+00-1.19209289550781250e-07i) -1.1071487177940916399e0-2.3841857910156200307e-8i) (num-test (atan 2.0e+00+5.0e-01i) 1.1265564408348223487e0+9.6415620202996167238e-2i) (num-test (atan 2.0e+00-5.0e-01i) 1.1265564408348223487e0-9.6415620202996167238e-2i) (num-test (atan -2.0e+00+5.0e-01i) -1.1265564408348223487e0+9.6415620202996167238e-2i) (num-test (atan -2.0e+00-5.0e-01i) -1.1265564408348223487e0-9.6415620202996167238e-2i) (num-test (atan 2.0e+00+1.0e+00i) 1.1780972450961724644e0+1.7328679513998632735e-1i) (num-test (atan 2.0e+00-1.0e+00i) 1.1780972450961724644e0-1.7328679513998632735e-1i) (num-test (atan -2.0e+00+1.0e+00i) -1.1780972450961724644e0+1.7328679513998632735e-1i) (num-test (atan -2.0e+00-1.0e+00i) -1.1780972450961724644e0-1.7328679513998632735e-1i) (num-test (atan 2.0e+00+2.0e+00i) 1.3112232696716351433e0+2.3887786125685909036e-1i) (num-test (atan 2.0e+00-2.0e+00i) 1.3112232696716351433e0-2.3887786125685909036e-1i) (num-test (atan -2.0e+00+2.0e+00i) -1.3112232696716351433e0+2.3887786125685909036e-1i) (num-test (atan -2.0e+00-2.0e+00i) -1.3112232696716351433e0-2.3887786125685909036e-1i) (num-test (atan 2.0e+00+8.3886080e+06i) 1.5707963267948681975e0+1.1920928955077503843e-7i) (num-test (atan 2.0e+00-8.3886080e+06i) 1.5707963267948681975e0-1.1920928955077503843e-7i) (num-test (atan -2.0e+00+8.3886080e+06i) -1.5707963267948681975e0+1.1920928955077503843e-7i) (num-test (atan -2.0e+00-8.3886080e+06i) -1.5707963267948681975e0-1.1920928955077503843e-7i) (num-test (atan 8.3886080e+06+0.0e+00i) 1.5707962075856070685e0) (num-test (atan -8.3886080e+06+0.0e+00i) -1.5707962075856070685e0) (num-test (atan 8.3886080e+06+1.19209289550781250e-07i) 1.5707962075856070685e0+1.6940658945085766040e-21i) (num-test (atan 8.3886080e+06-1.19209289550781250e-07i) 1.5707962075856070685e0-1.6940658945085766040e-21i) (num-test (atan -8.3886080e+06+1.19209289550781250e-07i) -1.5707962075856070685e0+1.6940658945085766040e-21i) (num-test (atan -8.3886080e+06-1.19209289550781250e-07i) -1.5707962075856070685e0-1.6940658945085766040e-21i) (num-test (atan 8.3886080e+06+5.0e-01i) 1.5707962075856070685e0+7.1054273576008756410e-15i) (num-test (atan 8.3886080e+06-5.0e-01i) 1.5707962075856070685e0-7.1054273576008756410e-15i) (num-test (atan -8.3886080e+06+5.0e-01i) -1.5707962075856070685e0+7.1054273576008756410e-15i) (num-test (atan -8.3886080e+06-5.0e-01i) -1.5707962075856070685e0-7.1054273576008756410e-15i) (num-test (atan 8.3886080e+06+1.0e+00i) 1.5707962075856070685e0+1.4210854715201599821e-14i) (num-test (atan 8.3886080e+06-1.0e+00i) 1.5707962075856070685e0-1.4210854715201599821e-14i) (num-test (atan -8.3886080e+06+1.0e+00i) -1.5707962075856070685e0+1.4210854715201599821e-14i) (num-test (atan -8.3886080e+06-1.0e+00i) -1.5707962075856070685e0-1.4210854715201599821e-14i) (num-test (atan 8.3886080e+06+2.0e+00i) 1.5707962075856070685e0+2.8421709430401987951e-14i) (num-test (atan 8.3886080e+06-2.0e+00i) 1.5707962075856070685e0-2.8421709430401987951e-14i) (num-test (atan -8.3886080e+06+2.0e+00i) -1.5707962075856070685e0+2.8421709430401987951e-14i) (num-test (atan -8.3886080e+06-2.0e+00i) -1.5707962075856070685e0-2.8421709430401987951e-14i) (num-test (atan 8.3886080e+06+8.3886080e+06i) 1.5707962671902518438e0+5.9604644775390483828e-8i) (num-test (atan 8.3886080e+06-8.3886080e+06i) 1.5707962671902518438e0-5.9604644775390483828e-8i) (num-test (atan -8.3886080e+06+8.3886080e+06i) -1.5707962671902518438e0+5.9604644775390483828e-8i) (num-test (atan -8.3886080e+06-8.3886080e+06i) -1.5707962671902518438e0-5.9604644775390483828e-8i) (num-test (atan -2.225073858507201399999999999999999999996E-308) -2.225073858507201399999999999999999999996E-308) (num-test (atan 1.110223024625156799999999999999999999997E-16) 1.110223024625156799999999999999995438476E-16) (num-test (/ pi 2) (+ (* 2 (atan (/ (sqrt 2)))) (atan (/ (sqrt 8))))) (num-test (/ pi 4) (+ (* 12 (atan (/ 18))) (* 8 (atan (/ 57))) (* -5 (atan (/ 239))))) (num-test (/ pi 4) (+ (* 2 (atan 1/3)) (atan 1/7))) (num-test (/ pi 4) (+ (* 5 (atan 1/7)) (* 2 (atan 3/79)))) (num-test (/ pi 4) (+ (atan 1/2) (atan 1/3))) (num-test (/ pi 4) (- (* 2 (atan 1/2)) (atan 1/7))) (num-test (/ pi 4) (- (* 4 (atan (/ 1 5))) (atan (/ 1 239)))) (num-test (* 4 (+ (* 3 (atan 1/4)) (atan 1/20) (atan 1/1985))) pi) (num-test (+ (* 176 (atan (/ 57))) (* 28 (atan (/ 239))) (* -48 (atan (/ 682))) (* 96 (atan (/ 12943)))) pi) (num-test (+ (* 2 (atan (/ (sqrt 2)))) (atan (/ (sqrt 8)))) (/ pi 2)) (num-test (+ (* 48 (atan (/ 49))) (* 128 (atan (/ 57))) (* -20 (atan (/ 239))) (* 48 (atan (/ 110443)))) pi) (num-test (/ (+ (atan (/ 239)) (atan (/ 70)) (- (atan (/ 99)))) 2) (+ (atan (/ 408)) (atan (/ 577)))) (num-test (atan (/ -1 (sqrt 3))) (/ pi -6)) (num-test (atan (sqrt 3)) (/ pi 3)) (num-test (atan 1/2 1/2) 0.78539816339745) (for-each (lambda (num-and-val) (let ((num (car num-and-val)) (val (cadr num-and-val))) (num-test-1 'atan num (atan num) val))) (vector (list 0 0) (list 1 0.78539816339745) (list 2 1.1071487177941) (list 3 1.2490457723983) (list -1 -0.78539816339745) (list -2 -1.1071487177941) (list -3 -1.2490457723983) (list 9223372036854775807 1.5707963267949) (list -9223372036854775808 -1.5707963267949) (list 1/2 0.46364760900081) (list 1/3 0.32175055439664) (list -1/2 -0.46364760900081) (list -1/3 -0.32175055439664) (list 1/9223372036854775807 1.0842021724855e-19) (list 0.0 0.0) (list 1.0 0.78539816339745) (list 2.0 1.1071487177941) (list -2.0 -1.1071487177941) (list 1.000000000000000000000000000000000000002E-309 1.000000000000000000000000000000000000002E-309) (list 1e+16 1.5707963267949) (list inf.0 1.5707963267949) (list -inf.0 -1.5707963267949) (list 0+2i 1.5707963267949+0.54930614433405i) (list 1+1i 1.0172219678979+0.40235947810853i) (list 1-1i 1.0172219678979-0.40235947810853i) (list -1+1i -1.0172219678979+0.40235947810853i) (list -1-1i -1.0172219678979-0.40235947810853i) (list 0.1+0.1i 0.10065855418732+0.099325449367251i) (list 1e+16+1e+16i 1.5707963267949+5.5511151231258e-17i) (list 1e-16+1e-16i 1e-16+1.1102230246252e-16i) )) ;; the x=0 cases are errors in clisp (num-test (atan 0 0) 0.0) (num-test (atan 0 0.0) 0.0) (num-test (atan 0 1) 0.0) (num-test (atan 0 -1) pi) (num-test (atan 0 2) 0.0) (num-test (atan 0 -2) pi) (num-test (atan 0 1.5) 0.0) (num-test (atan 0 -1.5) pi) (num-test (atan 0 3.0) 0.0) (num-test (atan 0 -3.0) pi) (num-test (atan 0 4.0) 0.0) (num-test (atan 0 -4.0) pi) (num-test (atan 0 pi) 0.0) (num-test (atan 0 (- pi)) pi) (num-test (atan 0.0 0) 0.0) (num-test (atan 0.0 0.0) 0.0) (num-test (atan 0.0 1) 0.0) (num-test (atan 0.0 -1) pi) (num-test (atan 0.0 2) 0.0) (num-test (atan 0.0 -2) pi) (num-test (atan 0.0 1.5) 0.0) (num-test (atan 0.0 -1.5) pi) (num-test (atan 0.0 3.0) 0.0) (num-test (atan 0.0 -3.0) pi) (num-test (atan 0.0 4.0) 0.0) (num-test (atan 0.0 -4.0) pi) (num-test (atan 0.0 pi) 0.0) (num-test (atan 0.0 (- pi)) pi) (num-test (atan 1 0) 1.5707963267949) (num-test (atan 1 0.0) 1.5707963267949) (num-test (atan 1 1) 0.78539816339745) (num-test (atan 1 -1) 2.3561944901923) (num-test (atan 1 2) 0.46364760900081) (num-test (atan 1 -2) 2.677945044589) (num-test (atan 1 1.5) 0.58800260354757) (num-test (atan 1 -1.5) 2.5535900500422) (num-test (atan 1 3.0) 0.32175055439664) (num-test (atan 1 -3.0) 2.8198420991932) (num-test (atan 1 4.0) 0.24497866312686) (num-test (atan 1 -4.0) 2.8966139904629) (num-test (atan 1 pi) 3.081690711159849357869996080340530985905E-1) (num-test (atan 1 (- pi)) 2.833423582473808302675643775245449785612E0) (num-test (atan -1 0) -1.5707963267949) (num-test (atan -1 0.0) -1.5707963267949) (num-test (atan -1 1) -0.78539816339745) (num-test (atan -1 -1) -2.3561944901923) (num-test (atan -1 2) -0.46364760900081) (num-test (atan -1 -2) -2.677945044589) (num-test (atan -1 1.5) -0.58800260354757) (num-test (atan -1 -1.5) -2.5535900500422) (num-test (atan -1 3.0) -0.32175055439664) (num-test (atan -1 -3.0) -2.8198420991932) (num-test (atan -1 4.0) -0.24497866312686) (num-test (atan -1 -4.0) -2.8966139904629) (num-test (atan -1 pi) -3.081690711159849357869996080340530985905E-1) (num-test (atan -1 (- pi)) -2.833423582473808302675643775245449785612E0) (num-test (atan 2 0) 1.5707963267949) (num-test (atan 2 0.0) 1.5707963267949) (num-test (atan 2 1) 1.1071487177941) (num-test (atan 2 -1) 2.0344439357957) (num-test (atan 2 2) 0.78539816339745) (num-test (atan 2 -2) 2.3561944901923) (num-test (atan 2 1.5) 0.92729521800161) (num-test (atan 2 -1.5) 2.2142974355882) (num-test (atan 2 3.0) 0.58800260354757) (num-test (atan 2 -3.0) 2.5535900500422) (num-test (atan 2 4.0) 0.46364760900081) (num-test (atan 2 -4.0) 2.677945044589) (num-test (atan 2 pi) 5.669115049410094050828977467226191538068E-1) (num-test (atan 2 (- pi)) 2.574681148648783833379745636556883730391E0) (num-test (atan -2 0) -1.5707963267949) (num-test (atan -2 0.0) -1.5707963267949) (num-test (atan -2 1) -1.1071487177941) (num-test (atan -2 -1) -2.0344439357957) (num-test (atan -2 2) -0.78539816339745) (num-test (atan -2 -2) -2.3561944901923) (num-test (atan -2 1.5) -0.92729521800161) (num-test (atan -2 -1.5) -2.2142974355882) (num-test (atan -2 3.0) -0.58800260354757) (num-test (atan -2 -3.0) -2.5535900500422) (num-test (atan -2 4.0) -0.46364760900081) (num-test (atan -2 -4.0) -2.677945044589) (num-test (atan -2 pi) -5.669115049410094050828977467226191538068E-1) (num-test (atan -2 (- pi)) -2.574681148648783833379745636556883730391E0) (num-test (atan 1.5 0) 1.5707963267949) (num-test (atan 1.5 0.0) 1.5707963267949) (num-test (atan 1.5 1) 0.98279372324733) (num-test (atan 1.5 -1) 2.1587989303425) (num-test (atan 1.5 2) 0.64350110879328) (num-test (atan 1.5 -2) 2.4980915447965) (num-test (atan 1.5 1.5) 0.78539816339745) (num-test (atan 1.5 -1.5) 2.3561944901923) (num-test (atan 1.5 3.0) 0.46364760900081) (num-test (atan 1.5 -3.0) 2.677945044589) (num-test (atan 1.5 4.0) 0.35877067027057) (num-test (atan 1.5 -4.0) 2.7828219833192) (num-test (atan 1.5 pi) 4.454574939105981596935303215574368401686E-1) (num-test (atan 1.5 (- pi)) 2.696135159679195078769113061722066044025E0) (num-test (atan -1.5 0) -1.5707963267949) (num-test (atan -1.5 0.0) -1.5707963267949) (num-test (atan -1.5 1) -0.98279372324733) (num-test (atan -1.5 -1) -2.1587989303425) (num-test (atan -1.5 2) -0.64350110879328) (num-test (atan -1.5 -2) -2.4980915447965) (num-test (atan -1.5 1.5) -0.78539816339745) (num-test (atan -1.5 -1.5) -2.3561944901923) (num-test (atan -1.5 3.0) -0.46364760900081) (num-test (atan -1.5 -3.0) -2.677945044589) (num-test (atan -1.5 4.0) -0.35877067027057) (num-test (atan -1.5 -4.0) -2.7828219833192) (num-test (atan -1.5 pi) -4.454574939105981596935303215574368401686E-1) (num-test (atan -1.5 (- pi)) -2.696135159679195078769113061722066044025E0) (num-test (atan 3.0 0) 1.5707963267949) (num-test (atan 3.0 0.0) 1.5707963267949) (num-test (atan 3.0 1) 1.2490457723983) (num-test (atan 3.0 -1) 1.8925468811915) (num-test (atan 3.0 2) 0.98279372324733) (num-test (atan 3.0 -2) 2.1587989303425) (num-test (atan 3.0 1.5) 1.1071487177941) (num-test (atan 3.0 -1.5) 2.0344439357957) (num-test (atan 3.0 3.0) 0.78539816339745) (num-test (atan 3.0 -3.0) 2.3561944901923) (num-test (atan 3.0 4.0) 0.64350110879328) (num-test (atan 3.0 -4.0) 2.4980915447965) (num-test (atan 3.0 pi) 7.623475341648745879175385302461797760774E-1) (num-test (atan 3.0 (- pi)) 2.379245119424918650545104853033323108118E0) (num-test (atan -3.0 0) -1.5707963267949) (num-test (atan -3.0 0.0) -1.5707963267949) (num-test (atan -3.0 1) -1.2490457723983) (num-test (atan -3.0 -1) -1.8925468811915) (num-test (atan -3.0 2) -0.98279372324733) (num-test (atan -3.0 -2) -2.1587989303425) (num-test (atan -3.0 1.5) -1.1071487177941) (num-test (atan -3.0 -1.5) -2.0344439357957) (num-test (atan -3.0 3.0) -0.78539816339745) (num-test (atan -3.0 -3.0) -2.3561944901923) (num-test (atan -3.0 4.0) -0.64350110879328) (num-test (atan -3.0 -4.0) -2.4980915447965) (num-test (atan -3.0 pi) -7.623475341648745879175385302461797760774E-1) (num-test (atan -3.0 (- pi)) -2.379245119424918650545104853033323108118E0) (num-test (atan 4.0 0) 1.5707963267949) (num-test (atan 4.0 0.0) 1.5707963267949) (num-test (atan 4.0 1) 1.325817663668) (num-test (atan 4.0 -1) 1.8157749899218) (num-test (atan 4.0 2) 1.1071487177941) (num-test (atan 4.0 -2) 2.0344439357957) (num-test (atan 4.0 1.5) 1.2120256565243) (num-test (atan 4.0 -1.5) 1.9295669970655) (num-test (atan 4.0 3.0) 0.92729521800161) (num-test (atan 4.0 -3.0) 2.2142974355882) (num-test (atan 4.0 4.0) 0.78539816339745) (num-test (atan 4.0 -4.0) 2.3561944901923) (num-test (atan 4.0 pi) 9.050225767665427556408039831275762329032E-1) (num-test (atan 4.0 (- pi)) 2.236570076823250482821839400151926651295E0) (num-test (atan -4.0 0) -1.5707963267949) (num-test (atan -4.0 0.0) -1.5707963267949) (num-test (atan -4.0 1) -1.325817663668) (num-test (atan -4.0 -1) -1.8157749899218) (num-test (atan -4.0 2) -1.1071487177941) (num-test (atan -4.0 -2) -2.0344439357957) (num-test (atan -4.0 1.5) -1.2120256565243) (num-test (atan -4.0 -1.5) -1.9295669970655) (num-test (atan -4.0 3.0) -0.92729521800161) (num-test (atan -4.0 -3.0) -2.2142974355882) (num-test (atan -4.0 4.0) -0.78539816339745) (num-test (atan -4.0 -4.0) -2.3561944901923) (num-test (atan -4.0 pi) -9.050225767665427556408039831275762329032E-1) (num-test (atan -4.0 (- pi)) -2.236570076823250482821839400151926651295E0) (num-test (atan pi 0) 1.570796326794896619231321691639751442098E0) (num-test (atan pi 0.0) 1.570796326794896619231321691639751442098E0) (num-test (atan pi 1) 1.262627255678911683444322083605698343509E0) (num-test (atan pi -1) 1.878965397910881555018321299673804540687E0) (num-test (atan pi 2) 1.003884821853887214148423944917132288294E0) (num-test (atan pi -2) 2.137707831735906024314219438362370595907E0) (num-test (atan pi 1.5) 1.125338832884298459537791370082314601928E0) (num-test (atan pi -1.5) 2.016253820705494778924852013197188282274E0) (num-test (atan pi 3.0) 8.084487926300220313137831613935716660202E-1) (num-test (atan pi -3.0) 2.333143860959771207148860221885931218181E0) (num-test (atan pi 4.0) 6.657737500283538635905177085121752091944E-1) (num-test (atan pi -4.0) 2.475818903561439374872125674767327675004E0) (num-test (atan pi pi) 7.853981633974483096156608458198757210488E-1) (num-test (atan pi (- pi)) 2.356194490192344928846982537459627163149E0) (num-test (atan (- pi) 0) -1.570796326794896619231321691639751442098E0) (num-test (atan (- pi) 0.0) -1.570796326794896619231321691639751442098E0) (num-test (atan (- pi) 1) -1.262627255678911683444322083605698343509E0) (num-test (atan (- pi) -1) -1.878965397910881555018321299673804540687E0) (num-test (atan (- pi) 2) -1.003884821853887214148423944917132288294E0) (num-test (atan (- pi) -2) -2.137707831735906024314219438362370595907E0) (num-test (atan (- pi) 1.5) -1.125338832884298459537791370082314601928E0) (num-test (atan (- pi) -1.5) -2.016253820705494778924852013197188282274E0) (num-test (atan (- pi) 3.0) -8.084487926300220313137831613935716660202E-1) (num-test (atan (- pi) -3.0) -2.333143860959771207148860221885931218181E0) (num-test (atan (- pi) 4.0) -6.657737500283538635905177085121752091944E-1) (num-test (atan (- pi) -4.0) -2.475818903561439374872125674767327675004E0) (num-test (atan (- pi) pi) -7.853981633974483096156608458198757210488E-1) (num-test (atan (- pi) (- pi)) -2.356194490192344928846982537459627163149E0) (num-test (atan 3037000500 1/3037000500) 1.570796326794896619122901474392911039606E0) (num-test (atan most-positive-fixnum) 1.570796326794896619122901474391200998685E0) (num-test (atan 1/3037000500 3037000500) 1.084202172468404024919078833314741441372E-19) (test (atan) 'error) (test (atan "hi") 'error) (test (atan 1.0+23.0i 1.0+23.0i) 'error) (test (atan 0 1 2) 'error) (test (atan 0 0-i) 'error) (test (atan 1+i 0-i) 'error) (test (atan 1 0-i) 'error) (for-each (lambda (arg) (test (atan arg) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) (for-each (lambda (arg) (test (atan arg nan.0) 'error) (test (atan nan.0 arg) 'error) (test (atan arg inf.0) 'error) (test (atan inf.0 arg) 'error) (test (atan 1 arg) 'error) (test (atan 1.0 arg) 'error) (test (atan 1/2 arg) 'error) (test (atan 1+i arg) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) (for-each (lambda (arg) (test (atan arg 1) 'error) (test (atan arg 1/2) 'error) (test (atan arg 1.0) 'error) (test (atan arg 1+i) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) (let ((formulas '((1/4 (1 1)) (1/4 (1 2) (1 3)) (1/4 (2 2) (-1 7)) (1/4 (2 3) (1 7)) (1/4 (4 5) (-1 239)) (1/4 (1 2) (1 4) (1 13)) (1/4 (1 2) (1 5) (1 8)) (1/4 (1 2) (2 6) (-1 117)) (1/4 (1 3) (2 4) (-1 38)) (1/4 (2 2) (-2 12) (1 41)) (1/4 (2 2) (-2 14) (1 1393)) (1/4 (2 2) (-2 17) (-1 41)) (1/4 (2 2) (-1 5) (1 18)) (1/4 (2 2) (-1 6) (1 43)) (1/4 (2 2) (-1 8) (-1 57)) (1/4 (2 2) (-1 9) (-1 32)) (1/4 (2 2) (-1 12) (-1 17)) (1/4 (2 3) (1 5) (-1 18)) (1/4 (2 3) (1 6) (-1 43)) (1/4 (2 3) (1 8) (1 57)) (1/4 (2 3) (1 9) (1 32)) (1/4 (2 3) (1 12) (1 17)) (1/4 (2 3) (2 12) (-1 41)) (1/4 (2 3) (2 14) (-1 1393)) (1/4 (2 3) (2 17) (1 41)) (1/4 (2 4) (1 7) (2 13)) (1/4 (2 5) (1 7) (2 8)) (1/4 (2 5) (3 7) (-2 57)) (1/4 (2 5) (3 8) (1 57)) (1/4 (2 6) (3 7) (2 68)) (1/4 (2 7) (4 8) (1 239)) (1/4 (3 3) (-2 11) (1 682)) (1/4 (3 3) (-2 13) (-1 38)) (1/4 (3 3) (-1 5) (1 57)) (1/4 (3 3) (-1 6) (-1 68)) (1/4 (3 3) (-1 8) (-1 18)) (1/4 (3 4) (1 13) (-1 38)) (1/4 (3 4) (1 20) (1 1985)) (1/4 (3 5) (2 8) (-1 18)) (1/4 (3 7) (2 8) (2 18)) (1/4 (3 7) (4 11) (-2 682)) (1/4 (3 7) (4 13) (2 38)) (1/4 (4 3) (-4 8) (-1 239)) (1/4 (4 4) (-1 7) (-2 38)) (1/4 (4 4) (-4 21) (-1 239)) (1/4 (4 5) (-2 408) (1 1393)) (1/4 (4 5) (-2 478) (1 54608393)) (1/4 (4 5) (-2 577) (-1 1393)) (1/4 (4 5) (-1 41) (2 99)) (1/4 (4 5) (-1 70) (1 99)) (1/4 (4 5) (-1 213) (1 1958)) (1/4 (4 5) (-1 226) (1 4155)) (1/4 (4 5) (-1 237) (1 28322)) (1/4 (4 5) (-1 238) (1 56883)) (1/4 (4 5) (-1 240) (-1 57361)) (1/4 (4 5) (-1 241) (-1 28800)) (1/4 (4 5) (-1 252) (-1 4633)) (1/4 (4 5) (-1 265) (-1 2436)) (1/4 (4 5) (-1 408) (-1 577)) (1/4 (4 5) (1 41) (-2 70)) (1/4 (4 6) (1 7) (-2 117)) (1/4 (4 6) (4 31) (-1 239)) (1/4 (4 7) (4 18) (-1 239)) (1/4 (5 5) (-3 18) (-2 57)) (1/4 (5 6) (-1 43) (-2 117)) (1/4 (5 6) (-1 68) (-3 117)) (1/4 (-29 239) (256 378) (200 829) (244 882) (-388 993) (324 2943) (-144 18543)) (1/4 (-4 307) (394 577) (163 1393) (-12 12238) (-24 58911) (-68 1999509) (-68 11653127)) (1/4 (7 10) (2 50) (4 100) (1 682) (4 1000) (3 1303) (-4 90109)) (1/4 (7 10) (8 100) (1 682) (4 1000) (3 1303) (-4 90109) (-2 500150)) (1/4 (12 18) (8 307) (46 577) (19 1393) (-8 2827807) (-16 11653127) (-8 16480443)) (1/4 (17 23) (11 882) (24 931) (10 1143) (-2 34208) (-8 44179) (-13 485298)) (1/4 (29 268) (198 378) (142 829) (186 882) (-301 993) (237 2943) (-115 18543)) (1/4 (43 57) (22 746) (-2 1568) (1 4662) (28 12943) (14 32807) (11 157318)) (1/4 (44 515) (95 538) (127 682) (176 782) (95 1068) (88 4030) (17 12943)) (1/4 (76 682) (190 746) (271 882) (315 2917) (-132 9466) (295 12943) (-95 19703)) (1/4 (83 107) (17 4443) (68 11343) (-5 113568) (-34 595667) (-5 23481902) (5 168925949733307)) (1/4 (83 107) (17 4443) (68 11343) (-5 111693) (-34 595667) (5 9503057) (5 232633636378307)) (1/4 (95 418) (171 682) (176 882) (315 2917) (-132 9466) (105 12943) (95 16693)) (1/4 (100 437) (254 577) (127 1393) (44 2072) (24 2943) (-12 16432) (-100 28800)) (1/4 (122 162) (22 568) (-29 1432) (83 5087) (-7 6107) (-10 27493) (-29 30027)) (1/4 (122 183) (108 1177) (29 1393) (22 4443) (54 5087) (-64 7078) (-10 27493)) (1/4 (122 418) (237 557) (29 1068) (144 3458) (-61 5087) (122 16452) (105 27493)) (1/4 (127 239) (100 343) (-56 2072) (-76 2943) (100 7983) (-12 16432) (100 28322)) (1/4 (127 239) (212 1068) (-144 2072) (188 2309) (-200 6105) (376 6807) (288 13637)) (1/4 (127 239) (400 1068) (44 2072) (-376 2943) (-200 6105) (100 13637) (188 16432)) (1/4 (127 682) (227 788) (227 843) (44 2072) (51 2943) (-27 12943) (88 16432)) (1/4 (127 682) (454 818) (271 1303) (-403 2943) (-44 6118) (-254 12943) (-183 3014557)) (1/4 (171 239) (68 788) (-56 1744) (36 2943) (44 6613) (-112 13603) (144 28322)) (1/4 (171 239) (68 993) (-20 2943) (56 4443) (-44 13252) (-112 17088) (156 28322)) (1/4 (171 239) (124 993) (-56 1252) (56 2855) (-76 2943) (-100 13252) (100 28322)) (1/4 (171 682) (183 788) (227 843) (95 2943) (44 6613) (-115 12943) (88 28322)) (1/4 (171 682) (271 882) (95 993) (315 2917) (95 2943) (-227 9466) (200 12943)) (1/4 (171 682) (366 1068) (139 2436) (271 5357) (315 5507) (227 6962) (-71 12943)) (1/4 (176 463) (32 682) (241 798) (241 3141) (-58 5357) (-122 12943) (-51 390112)) (1/4 (176 557) (244 757) (90 1068) (61 1393) (22 3458) (122 11018) (44 27493)) (1/4 (179 239) (44 5357) (80 5507) (156 12943) (8 17923) (48 32807) (-40 157318)) (1/4 (179 239) (120 4662) (4 5357) (116 12943) (-32 17923) (88 32807) (40 390112)) (1/4 (179 233) (120 4662) (4 5357) (-63 12943) (-32 17923) (-91 32807) (40 390112)) (1/4 (183 239) (32 682) (-88 1143) (132 2673) (68 12943) (-132 34208) (-44 44179)) (1/4 (183 239) (32 1023) (-68 5832) (12 111693) (-100 6826318) (-12 9503057) (-12 232633636378307)) (1/4 (183 239) (32 1023) (-68 5832) (12 112068) (-100 6826318) (-12 13288972) (-12 49541920807)) (1/4 (183 239) (32 1023) (-68 5832) (12 113568) (-100 6826318) (12 23476958) (-12 111432033307)) (1/4 (183 239) (32 1023) (-68 5832) (12 113568) (-100 6826318) (12 23481005) (-12 612463280182)) (1/4 (183 239) (32 1023) (-68 5832) (12 113568) (-100 6826318) (12 23463218) (-12 29483238307)) (1/4 (183 239) (32 1023) (-68 5832) (12 113568) (-100 6826318) (12 23481902) (-12 168925949733307)) (1/4 (183 294) (44 905) (115 1292) (88 3957) (-32 12238) (68 12943) (51 114483)) (1/4 (183 307) (32 682) (95 1143) (132 2673) (68 12943) (51 34208) (139 44179)) (1/4 (183 378) (115 557) (29 1068) (122 2943) (144 3458) (-244 14318) (44 27493)) (1/4 (183 378) (144 606) (86 1772) (122 2943) (-115 6118) (-71 14318) (-71 27493)) (1/4 (183 378) (144 905) (115 1057) (151 2943) (-29 3957) (-100 14318) (-100 27493)) (1/4 (183 378) (215 682) (44 1432) (51 2943) (-315 5257) (-71 12943) (44 13043)) (1/4 (183 538) (215 682) (51 1068) (44 2309) (88 2673) (88 3039) (17 12943)) (1/4 (183 568) (215 682) (278 1636) (-139 6107) (112 12943) (-234 19703) (132 32807)) (1/4 (186 307) (41 378) (27 829) (-13 1713) (122 2943) (42 12238) (71 58911)) (1/4 (190 577) (76 682) (176 882) (95 1393) (220 2917) (-132 9466) (200 12943)) (1/4 (198 577) (200 606) (127 1393) (-20 2943) (112 3740) (-44 6118) (56 11018)) (1/4 (199 233) (-60 1393) (-76 5357) (-43 12943) (-152 17923) (9 32807) (120 1049433)) (1/4 (215 233) (-216 1568) (12 4662) (-64 6898) (113 12943) (-51 32807) (-32 534568)) (1/4 (215 239) (-248 1568) (76 4662) (296 12943) (132 32807) (64 83270) (32 1493208)) (1/4 (160 200) (-1 239) (-4 515) (-8 4030) (-16 50105) (-16 62575) (-32 500150) (-80 4000300)) (1/4 (215 682) (644 1568) (227 5767) (366 6898) (-532 12943) (227 24331) (-51 32807) (183 534568)) (1/4 (295 4193) (3767 5507) (593 18543) (-1228 39307) (2068 55603) (-962 211050) (-708 390112) (-1587 2867938)) (1/4 (537 1393) (1118 5357) (952 12943) (3032 17923) (-1384 32807) (-1194 157318) (-1870 1049433) (796 21638297)) (1/4 (581 1023) (183 4443) (664 5832) (732 11343) (-171 110443) (-366 595667) (171 4841182) (83 6826318)) (1/4 (581 1252) (764 4853) (1030 5832) (-398 58898) (-764 97232) (195 110443) (537 4841182) (266 6826318)) (1/4 (581 1252) (764 5593) (1030 5827) (366 58898) (195 110443) (537 4841182) (-764 6826318) (-1030 1561886607)) (1/4 (581 1252) (764 5618) (1030 5832) (366 58898) (195 110443) (764 1256859) (537 4841182) (266 6826318)) (1/4 (581 1252) (764 5593) (1030 5832) (366 69051) (195 110443) (366 369957) (171 4841182) (266 6826318)) (1/4 (581 1252) (764 5593) (1030 11557) (1030 11773) (366 58898) (195 110443) (537 4841182) (266 6826318)) (1/4 (581 1252) (1030 5507) (764 5593) (366 58898) (-1030 98821) (195 110443) (537 4841182) (266 6826318)) (1/4 (764 1068) (298 5832) (581 26307) (-183 78813) (-171 110443) (215 314982) (171 4841182) (83 6826318)) (1/4 (808 1477) (1308 2436) (-1635 5283) (-417 5507) (593 6962) (632 390112) (-561 2733307) (266 23747457)) (1/4 (1074 1568) (840 5357) (-779 12943) (625 17923) (-1106 32807) (657 198505) (-259 390112) (657 24185182)) (1/4 (1074 4246) (1257 5357) (1731 6107) (295 12943) (625 19703) (-481 32807) (-1042 39307) (398 390112)) (1/4 (1484 4693) (2097 4831) (366 18543) (1189 49457) (-227 123093) (-879 128643) (481 27872057) (-266 31895807)) (1/4 (1738 4193) (1699 4246) (144 6687) (-1443 32318) (-266 39307) (337 235318) (-227 390112) (-481 2282363)) (1/4 (2363 4557) (1218 5507) (1850 18543) (-266 39307) (-2658 49457) (1257 123093) (-1484 390112) (481 27872057)) (1/4 (-31739656 201229582) (38819595 231373438) (110380200 284862638) (122355452 312322593) (-134055653 496651953) (5301720 509435077) (63861353 543644509) (68679613 934981432) (130575087 1845907403) (-32548340 2189376182) (-71616726 2539791558) (98822066 4732978887) (119051879 7804016832) (48482068 9233371207) (-99832073 41734246913) (-99143267 66492889557) (-25601898 73276714818) (-79323772 579766497643)) (1/4 (16106659 103224943) (48702787 196047454) (18674705 199762118) (8786524 201229582) (-16824928 244653118) (-9582339 261221282) (33092716 266981905) (50379909 270684757) (24748365 909140573) (31675677 1770638022) (1576733 2189376182) (-4742586 2701984943) (-34586991 5475957057) (10864048 14033378718) (-13079131 18986886768) (22266057 25220059245) (17791526 34840696582) (-12650410 193100304493)) (1/4 (154370374 124845505) (-90941691 193788912) (64454803 196047454) (-82996236 201229582) (109691394 244653118) (-15562779 462333568) (6518215 553806443) (-169821027 1134156517) (-244516782 1222853176) (100563577 2154947322) (-47118309 2189376182) (-35713908 4006581229) (60656646 5475957057) (-4001125 18986886768) (-68810571 37093513413) (-20888958 100083704193) (16990004 250645741818) (-62587614 5142102426318)) (1/4 (-119375678 193788912) (61799442 201229582) (-19991865 272525023) (20438744 321390012) (88331413 331905423) (103467976 343841922) (88464202 378026293) (138122046 600536193) (44232101 653023206) (115219328 846974497) (-81969855 1033937133) (-63521464 1454097393) (-118694678 2189376182) (117332455 2322170807) (-26482877 6884660047) (-18702052 29546599818) (7415308 250645741818) (166718050 512223806648)) (1/4 (-85386445 101859193) (4420755 112519818) (43555859 193788912) (15003774 194195097) (108912996 201229582) (61225652 231373438) (16824928 262992072) (73421340 284862638) (123118321 1057929843) (-10593254 2189376182) (40618746 2539791558) (73863237 2616939213) (-30947737 14811180432) (58354910 41734246913) (19908612 66492889557) (5345839 73276714818) (-90280386 120563046313) (61328880 579766497643)) (1/4 (-75143577 193788912) (17567341 201229582) (64670845 321390012) (88331413 331905423) (103467976 343841922) (68472337 372954564) (49657844 600536193) (115219328 846974497) (24240236 1012047353) (-81969855 1033937133) (24942738 1454097393) (-118694678 2189376182) (73100354 2322170807) (-88464202 4549886677) (-26482877 6884660047) (-18702052 29546599818) (7415308 250645741818) (34021747 512223806648)) (1/4 (-9761163 108220762) (13910116 144252856) (12032992 157157432) (55358773 167207057) (6697039 168623905) (-28651627 193788912) (1825738 201229582) (67020547 215266693) (-1575761 216260702) (45238607 284862638) (10024910 934981432) (20338355 2189376182) (-450675 4832545807) (-27703534 4935283579) (-25688998 7804016832) (-58020549 18986886768) (-28330426 120563046313) (-20446387 69971515635443)) (1/4 (-9719634 193788912) (17567341 201229582) (70452403 204415882) (12270610 244653118) (18184957 313467682) (44573394 426775692) (3945487 600536193) (33076315 892642643) (62731148 919331002) (18631836 1012047353) (58964485 1454097393) (32836016 2032914193) (-3430506 2189376182) (-19017973 5475957057) (60427493 6884660047) (-9222216 16406542707) (25467476 22827763470) (-8020348 29546599818)) (1/4 (-7707046 100457781) (102467557 168623905) (-37989469 201229582) (-19264491 216904033) (74130709 231373438) (9117882 262992072) (61898132 284862638) (-26046661 314198789) (20721724 327012132) (-6893934 1111885489) (-40541219 1183092682) (-40255386 2189376182) (82347539 2296713307) (31354293 12988236682) (27538131 18221678207) (-68243977 41734246913) (12646329 73276714818) (-45544955 193100304493)) (1/4 (-6829481 193788912) (49141523 227661182) (80561462 231373438) (12671730 244653118) (29897458 284862638) (-73630486 355671793) (58626712 398795108) (62468573 509435077) (24454447 543644509) (-19908612 657922943) (28905471 1057929843) (35237534 1845907403) (26678061 2189376182) (-117350972 4866438247) (-61240161 5475957057) (23212961 9075730623) (-20886351 9233371207) (-65421299 60402345333)) (1/4 (-6249813 193788912) (56771042 201229582) (28076746 231373438) (-19468648 262992072) (30639871 266981905) (19911270 284862638) (130457979 532399876) (96830507 672554667) (-25661007 1057929843) (13459441 1111885489) (-45480502 1183092682) (5693286 1770638022) (-21577251 2170952313) (-67486342 2189376182) (2925523 2701984943) (27538131 18221678207) (-7198038 193100304493) (36293576 307026452057)) (1/4 (-60656646 143846482) (38271221 144309885) (138138220 157565949) (35739707 193788912) (-42115413 201229582) (-49270023 231373438) (94471578 278263393) (-68287996 398795108) (87062724 462333568) (-21411533 593897943) (-13257608 1057929843) (-106971336 1206519637) (34427295 2189376182) (166256019 4006581229) (111296506 4832545807) (58999250 18986886768) (100563577 373139596292) (100694535 5142102426318)) (1/4 (-5621437 103224943) (81294931 115811807) (23943179 193788912) (33709426 199762118) (-2077524 201229582) (-31310435 261221282) (4978864 266981905) (-15147806 282218776) (-1688365 909140573) (20050974 1047764193) (-18279356 1770638022) (-1777511 2189376182) (19200593 2701984943) (-21507860 5475957057) (30332696 34840696582) (26011854 48312162432) (7938525 193100304493) (9186926 250645741818)) (1/4 (-5497394 101057042) (65180148 144309885) (53832596 193788912) (48554212 201229582) (52075350 447821668) (-105963621 539290393) (-8554603 2060228568) (7313117 2112819717) (-57858314 2189376182) (-3891660 2572149874) (7518287 3261365450) (-19908612 4044044333) (12568802 4866438247) (-83992146 5494891577) (-68408704 9233371207) (6071631 20336334426) (26993421 45384196187) (-20080982 71617196968)) (1/4 (-52897653 193788912) (17567341 201229582) (88637360 214539684) (16824928 329492391) (87365276 426775692) (89084239 434859193) (64670845 478798161) (-60879340 600536193) (51820567 706366957) (25661007 1033937133) (-7721255 1119211358) (-11874055 1454097393) (-46608525 2189376182) (-7415308 2674664693) (38361126 6884660047) (-54246761 29546599818) (29095538 42354792693) (55834766 512223806648)) (1/4 (-51730315 193788912) (50509639 201229582) (-2925523 224497457) (34338149 231373438) (56651725 266981905) (88974774 284862638) (6009207 367829623) (44851350 532399876) (77361859 672554667) (-36293576 1047764193) (19819495 1057929843) (-26011854 1695830317) (-10691678 1770638022) (-51609424 2170952313) (-31380534 2189376182) (21276728 18221678207) (9186926 250645741818) (-16384964 4125516427007)) (1/4 (-50738726 193788912) (95363435 196047454) (69453144 225823278) (69510447 227661182) (22432893 244653118) (-32772323 266981905) (-17689880 284862638) (-25151223 657922943) (45597610 672554667) (-15126313 934981432) (76492809 1770638022) (84039104 2189376182) (-104948381 4832545807) (-85627080 5475957057) (-40656362 5684017953) (-5242611 7804016832) (-197723175 18986886768) (42533486 25220059245)) (1/4 (-28765620 120868561) (44046442 160007778) (67427201 167207057) (37325093 191800592) (70499068 270090468) (-57543499 289008998) (17519675 361632045) (-4374603 747769833) (-52576452 2674664693) (-7666625 2971354082) (83775059 3069221943) (44136928 4549886677) (-7704241 4832545807) (109211041 4935283579) (43406332 5271470807) (-4967047 8815417307) (24253605 14033378718) (72936300 69392205693)) (1/4 (-19504206 100457781) (24986381 107793452) (26438497 121042733) (40255386 160007778) (28377269 168623905) (23815821 314198789) (-2374068 361632045) (25057307 672554667) (-9351768 773302059) (11008080 1479406293) (574237 2296713307) (-3020779 2701984943) (17648998 4038832337) (-9422284 12139595709) (27538131 12957904393) (20007517 12988236682) (23727647 18710140581) (-4711783 120563046313)) (1/4 (-42543389 193788912) (74917830 201229582) (28076746 231373438) (16824928 262992072) (30639871 266981905) (74351634 284862638) (21577251 640348873) (78683719 672554667) (-25661007 1057929843) (-4687347 1111885489) (-27333714 1183092682) (5693286 1770638022) (8531273 2189376182) (-76017615 2674664693) (2925523 2701984943) (-39724039 4309606382) (27538131 18221678207) (68819577 193100304493)) (1/4 (-41665661 138884933) (61863206 168623905) (-24923249 201229582) (1860735 231373438) (152322833 244685917) (16824928 262992072) (45004160 284862638) (6816407 306903943) (-25731933 2189376182) (-2937113 2539791558) (-80514719 4100676432) (-30142453 5157407572) (88702086 17249711432) (10077565 18986886768) (-34456033 41734246913) (19908612 66492889557) (66436029 73276714818) (-10644159 579766497643)) (1/4 (-39775463 119742462) (20197545 168623905) (93476735 201229582) (1860735 231373438) (58490589 262992072) (86669821 284862638) (-4706801 437768635) (41665661 1258140850) (-35068662 1396533757) (-56669435 1624720807) (61079955 2189376182) (69090409 2539791558) (-73253757 3712239557) (42278290 41734246913) (-46591870 52254287493) (59684075 66492889557) (-12188492 73276714818) (-15350960 579766497643)) (1/4 (-3944315 103224943) (48706548 136899993) (18362609 186695067) (14767496 193788912) (-25501467 201229582) (-15136563 244653118) (29933522 261221282) (30079929 266981905) (117267526 480808760) (-30911261 1012047353) (40320881 1770638022) (53656250 2189376182) (20888958 2701984943) (-63283169 5475957057) (-32599626 37093513413) (-43463674 43917943025) (-64759288 193100304493) (21735578 5142102426318)) (1/4 (-3908713 100351813) (64565359 115453918) (26685223 201229582) (-8153925 214539684) (96935488 385231007) (15853328 459637173) (-19281720 539290393) (-48760063 883337939) (62688235 909140573) (-67639108 1282794079) (-5891323 1304967682) (-10583319 2189376182) (34749426 2572149874) (-55437542 3508373380) (-90085473 4427365493) (-35842901 5494891577) (-35317011 18986886768) (-22926686 45119420807)) (1/4 (-36515828 110175338) (5722932 193788912) (17567341 201229582) (83804410 203283777) (85603231 244653118) (79850836 273202197) (68353757 345311195) (-87424385 549758463) (-63893191 1454097393) (-111387800 1459933093) (69893108 1725455932) (-61767440 2189376182) (-19017973 5475957057) (102875038 6930719818) (47464799 16406542707) (21866697 29546599818) (-15003774 37093513413) (-46223313 5142102426318)) (1/4 (-36293576 132095062) (57870827 168623905) (-42543389 193788912) (35193791 201229582) (-8216830 231373438) (53118504 262992072) (30639871 266981905) (128791998 284862638) (60536931 672554667) (-25661007 1057929843) (49753017 1111885489) (-45480502 1183092682) (-30600290 1770638022) (-9615515 2189376182) (-69661629 2701984943) (63831707 18221678207) (29095538 193100304493) (-36293576 5142102426318)) (1/4 (-35775309 107793452) (-7119735 111530944) (127376638 115811807) (66649464 193788912) (-21949674 201229582) (-43413311 244653118) (-45561148 261221282) (49941099 266981905) (-9186926 396134107) (-886843 1770638022) (73138594 2189376182) (-39140796 2296713307) (61906878 2701984943) (-3565489 5458840213) (-21696619 5475957057) (-7498561 55237647473) (75356069 193100304493) (-1877124 579766497643)) (1/4 (-35368492 144309885) (-13432309 201229582) (124560353 231373438) (-8671679 284862638) (3303573 398795108) (141414744 509435077) (203277950 543644509) (-124589816 1845907403) (-32548340 2189376182) (-53309379 2539791558) (115883211 4732978887) (68679613 9075730623) (-1890198 9233371207) (19219806 41734246913) (19908612 66492889557) (60138860 73276714818) (-53675839 102428655030) (-10644159 579766497643)) (1/4 (-35368492 110911039) (50372266 113561432) (3303573 168623905) (-16735882 201229582) (74188087 231373438) (30000386 284862638) (106046252 509435077) (99229845 543644509) (-89221324 1845907403) (-67916832 2189376182) (-53309379 2539791558) (-15003774 3658567505) (65510945 4732978887) (-16893972 9233371207) (-19452259 41734246913) (-30463654 66492889557) (75142634 73276714818) (-10644159 579766497643)) (1/4 (-34897469 115453918) (87164915 118708522) (27407173 168623905) (87908983 193788912) (-27111639 201229582) (25214128 284862638) (-104763374 426775692) (55687060 600536193) (-49901243 909140573) (3434531 975229968) (-44950370 1454097393) (75180138 2189376182) (27482161 3508373380) (-68146942 4866438247) (-85620582 6884660047) (15583442 9233371207) (30725109 29546599818) (2193045 1442060060693)) (1/4 (-32461025 169937257) (42456472 193788912) (60136529 201229582) (45652872 230845763) (-11582317 231373438) (-12390325 448235443) (44415233 539290393) (59855124 595484173) (64938439 1057929843) (30600290 1500534537) (71357041 2189376182) (45920466 2616939213) (48826263 2701984943) (27854052 5494891577) (22522061 7193374037) (-21720539 11115923863) (1241486 14811180432) (-44678980 58240834569)) (1/4 (-30911476 193788912) (17567341 201229582) (68472337 272525023) (64670845 321390012) (88331413 331905423) (15003774 343841922) (5425743 600536193) (70987227 846974497) (-37737754 1033937133) (69174839 1454097393) (-30230476 2189376182) (28868253 2322170807) (-26482877 6884660047) (-44232101 24139206772) (-18702052 29546599818) (-44232101 50443911578) (7415308 250645741818) (-10210354 512223806648)) (1/4 (-30692741 227661182) (12504894 231373438) (-39446702 244653118) (114600079 262992072) (92590873 284862638) (113856011 314198789) (86140179 346369967) (-22467890 355671793) (-141382552 398795108) (59415160 657922943) (-7326899 1620933557) (-1037771 2189376182) (-79323772 8895085098) (-27205340 17997844652) (-10574983 41734246913) (-27904591 60402345333) (-79821190 73276714818) (16893972 102428655030)) (1/4 (-30361861 113561432) (85628068 168623905) (20493345 231373438) (53783788 262992072) (46894358 284862638) (65430523 1172624874) (36958860 1258140850) (-16893972 1624720807) (21304492 2189376182) (-1046915 2539791558) (-16436052 3658567505) (20222978 3712239557) (18632610 9549201618) (-27859034 41734246913) (-6816407 52254287493) (50270473 66492889557) (22880170 73276714818) (-10644159 579766497643)) (1/4 (-29735286 115453918) (-1890198 149299093) (12010178 168623905) (30661691 195053432) (7109402 201229582) (55743030 213255960) (32522426 231373438) (65751551 262992072) (35890388 284862638) (40220018 687606629) (-29216048 909140573) (-63654586 2189376182) (44099312 2539791558) (-33529628 41734246913) (-20830644 66492889557) (26660566 73276714818) (28204899 579766497643) (-48926623 1197009532318)) (1/2 (94283734 231373438) (147962666 262992072) (211308992 284862638) (-26800082 318942476) (-69173113 610076381) (-137945216 1111885489) (126007473 1183092682) (333203505 2189376182) (-250903561 2296713307) (248078871 2539791558) (-379960570 5458840213) (-73879914 18221678207) (132652425 30446482737) (68447160 41734246913) (-28954879 66492889557) (35907922 73276714818) (124495078 193100304493) (118351969 579766497643) (18339615 69971515635443)) (1/4 (-177112869 1047764193) (690072825 1057929843) (94777525 1082548618) (102841728 1770638022) (254740469 1845907403) (-7897447 2189376182) (-276135745 4866438247) (382919489 8634733487) (364832031 9233371207) (-255036003 18221678207) (-47281269 30446482737) (-14754756 31147706551) (145805470 35587716432) (-60553945 41734246913) (275062833 73276714818) (130937707 73745675437) (225667081 91140429801) (-58222931 120563046313) (217205407 250645741818) (-335335373 69971515635443)) (1/4 (48554212 1047764193) (-8064203 1695830317) (273129107 1845907403) (256152120 2060228568) (387484239 2170952313) (522262813 2189376182) (139928940 2426435870) (35269543 6249781117) (-116987170 9233371207) (-153310392 14885462059) (243523167 16346803247) (-191276069 18221678207) (-114320902 30446482737) (430509851 31147706551) (-62448154 35587716432) (118676670 41734246913) (-206756368 73276714818) (103732367 73745675437) (887580 250645741818) (-42628659 69971515635443)) (1/4 (59529729 1111885489) (411801489 1183092682) (-11697838 1770638022) (-10217933 2189376182) (178183864 2420845318) (481604223 2674664693) (200815307 2701984943) (18311409 4309606382) (-54066665 5684017953) (391091355 9566096322) (433050011 14033378718) (155959834 14474950443) (123563452 18221678207) (-322558047 18986886768) (-187246484 41734246913) (182267620 73276714818) (70949047 120563046313) (85657566 134237866432) (150508360 193100304493) (16824928 804006285737)) (1/4 (79674619 1057929843) (430112898 1183092682) (103029535 1770638022) (419995354 1845907403) (161719567 2189376182) (25897285 2701984943) (-165526275 3651666474) (-450635225 4866438247) (418811986 5684017953) (520079918 9233371207) (-370946465 11079391432) (11498734 14033378718) (1575319 15548138481) (-17734177 18221678207) (310673925 18986886768) (179773324 91140429801) (10643092 193100304493) (158038974 250645741818) (-165442692 804006285737) (119720378 11484937157318)) (1/4 (210413195 1047764193) (49034748 1057929843) (129893399 1111885489) (920835218 1222853176) (-367170458 1770638022) (-460082449 2154947322) (471386290 2189376182) (-4742586 2701984943) (-385386694 3651666474) (239038662 5684017953) (399473027 12988236682) (-298167989 14033378718) (111903950 15548138481) (-327400900 18221678207) (-789934617 18986886768) (-490722320 34352737807) (-639330225 193100304493) (-182267620 250645741818) (264670206 804006285737) (460026972 11484937157318)) (1/4 (245117311 1057929843) (-441536832 1111885489) (694624721 1183092682) (357582197 1845907403) (993878808 2189376182) (-264511823 2296713307) (279266579 2701984943) (-1351244216 4866438247) (255211890 9233371207) (142361641 10855443178) (-647040605 11079391432) (-55648319 15548138481) (-29232911 18221678207) (533067633 35587716432) (34223580 41734246913) (165442692 73276714818) (-215957611 91140429801) (786436927 120563046313) (939525243 193100304493) (311982932 250645741818)) (1/4 (290087814 1057929843) (129893399 1111885489) (189059832 1183092682) (312611694 1770638022) (-177755991 2189376182) (30639871 2539791558) (236310480 2701984943) (285108950 3651666474) (-530648699 5458840213) (208398791 5684017953) (381614163 14033378718) (81264079 15548138481) (-679782152 17249711432) (321741381 18221678207) (130900601 18986886768) (210413195 66492889557) (250865122 193100304493) (28145575 250645741818) (44970503 804006285737) (-460808246 11484937157318)) (1/4 (719865552 1057929843) (-120111015 1111885489) (-210078035 1183092682) (62607280 1770638022) (322252837 2189376182) (486314894 2701984943) (254469079 3651666474) (149133453 4832545807) (-401152271 5684017953) (491057480 7804016832) (-30639871 8995467682) (-328807860 14033378718) (392548235 15548138481) (-311284156 17058320068) (-669324927 18221678207) (-180383555 18986886768) (-60419034 193100304493) (278149989 250645741818) (325614788 804006285737) (-180163961 11484937157318)) (1/4 (764256596 1183092682) (340757269 1770638022) (82030807 2189376182) (-651971659 2296713307) (188678845 2539791558) (371182743 2701984943) (-541133952 5458840213) (282350263 5684017953) (261942239 9566096322) (414738602 14033378718) (-578034328 17249711432) (219993557 18221678207) (-126062774 18986886768) (-58097368 41734246913) (129149116 66492889557) (53118504 73276714818) (-68972608 120563046313) (210038089 193100304493) (285108950 579766497643) (16824928 804006285737)) (1/2 (-389355483 1111885489) (-85198635 1770638022) (942772580 2189376182) (860225796 2296713307) (958295292 2439473093) (1701938869 2701984943) (570217900 3651666474) (-653171089 5684017953) (1290597651 9566096322) (632981931 14033378718) (-258298232 15548138481) (-716081542 18221678207) (-448620821 18986886768) (-1711424041 41734246913) (1131248413 73276714818) (1650144299 120563046313) (1441452520 193100304493) (766713173 250645741818) (800363029 804006285737) (-1590316151 11484937157318)) (1/2 (-383575951 1082548618) (367447545 1695830317) (470326860 1845907403) (302791880 2060228568) (1332608020 2170952313) (1886585069 2189376182) (-562201563 2426435870) (610170129 2539791558) (-707278553 4732978887) (-215928441 6249781117) (-232950527 9233371207) (201602620 16346803247) (172870593 31147706551) (-125920121 35587716432) (696860645 41734246913) (207464734 66492889557) (-412488923 73276714818) (689924269 250645741818) (305596971 579766497643) (199162583 69971515635443)) (1/2 (468218462 2189376182) (1818521088 2439473093) (1312583386 2701984943) (121856072 5684017953) (-1109476277 6327662603) (570217900 8634733487) (1720710549 9566096322) (718180566 14033378718) (601927564 15548138481) (-1921221601 18221678207) (-59265338 18986886768) (1164382644 30446482737) (-936396880 41734246913) (701135515 73276714818) (1205140059 73745675437) (875117138 120563046313) (236312461 193100304493) (336600275 250645741818) (715164394 804006285737) (-815288990 11484937157318) (-860225796 69971515635443)) ))) (for-each (lambda (formula) (let ((r (/ 1 (car formula))) (sum 0.0)) (for-each (lambda (arg) (set! sum (+ sum (* (car arg) (atan (/ 1 (cadr arg))))))) (cdr formula)) (if (> (abs (- (* r sum) pi)) 1e-12) (begin (display formula) (display " = ") (display (* r sum)) (newline))))) formulas) (if with-bignums (let ((mxerr 0.0)) (for-each (lambda (formula) (let ((r (/ (bignum "1") (car formula))) (sum (bignum "0.0"))) (for-each (lambda (arg) (set! sum (+ sum (* (car arg) (atan (/ (bignum "1") (cadr arg))))))) (cdr formula)) (let ((err (abs (- (* r sum) (* 4 (atan (bignum "1.0") 1.0)))))) (if (> err mxerr) (set! mxerr err))))) formulas) (if (> mxerr 1e-30) (format-logged #t "big max error: ~A~%" mxerr))))) (let ((atans (list 0.00000000000000000000000000000000000000000000000000000000000000000000 0.04995839572194276141000628703484488149127708042350717441085345482998 0.09966865249116202737844611987802059024327832250431464801550877681002 0.14888994760949725058653039165586728099052584656913639751654183508627 0.19739555984988075837004976519479029344758510378785210151768894024103 0.24497866312686415417208248121127581091414409838118406712737591466735 0.29145679447786709199560462143289119350316759901206541927220608308729 0.33667481938672718139669863134176645842796861176681965716976593102220 0.38050637711236488630358791681043310449740571365810083757630562232420 0.42285392613294071296648279098114197360332058559089653470801277782477 0.46364760900080611621425623146121440202853705428612026381093308872019 0.50284321092786082733088202924527755577645581499776483101147435179592 0.54041950027058415544357836460859991013514825146259238811636023340959 0.57637522059118368022757047839377004593402018294846332167674413471879 0.61072596438920861654375887649023609381850306612882761584286773000023 0.64350110879328438680280922871732263804151059111531238286560611871351 0.67474094222355266305652097360981361507400625484071242312092170496930 0.70449406424221771665748034078199625698360683805607748632242138272858 0.73281510178650659164079207273428025198575567935825608631050693192821 0.75976275487577082892296119539998182400552294838843900175686400378812 0.78539816339744830961566084581987572104929234984377645524373614807695 0.80978357257016684662414585801888523310377327237135123533486105150550 0.83298126667443170541769356183636123851585134443710842085342312250327 0.85505273712601651097815432807058769283799489703232752323972864020297 0.87605805059819342311404752112834133907534524616033200346065614838499 0.89605538457134395617480071802993782702457844484684048736655059118459 0.91510070055336041656680197245527296654755880944161873770852665151657 0.93324752865620386989366255071265925262560793377140310475404520234906 0.95054684081207514789478913546381917504767901030880427426177057808809 0.96704699339746024466331914650201513140746494542545306371969751473184 0.98279372324732906798571061101466601449687745363162855676142508831798 0.99783018390619045494496187944270463542510496590550026609871776901127 1.01219701145133418325981347523809017175213711715353810435383625801215 1.02593241134335292660599590143869494280346122674543977431139573494988 1.03907225953609102762125033790727884531233378855364699989530509706554 1.05165021254837366745986731208629982963024430034204461753698029655611 1.06369782240255966094389111605254547856256296541932752568273985366635 1.07524465330906808242086208732184320752064516718532174460312177009311 1.08631839775787341806397958192567762897580047046812780208748680606431 1.09694499030013626798639002132512259906130967805041989207206852796014 1.10714871779409050301706546017853704007004764540143264667653920743371))) (let ((mxerr 0.0)) (do ((i 0 (+ i 1)) (x 0.0 (+ x 0.05))) ((= i 40)) (let ((err (abs (- (atan x) (list-ref atans i))))) (if (> err mxerr) (set! mxerr err)))) (if (> mxerr 1e-12) (format-logged #t "atan err: ~A~%" mxerr)))) (if with-bignums (let ((old-prec (*s7* 'bignum-precision))) (set! (*s7* 'bignum-precision) 500) (let ((atans (list ; table[Arctan[k/10], {k, 0, 30}] 0.00000000000000000000000000000000000000000000000000000000000000000000e0 0.09966865249116202737844611987802059024327832250431464801550877681002 0.19739555984988075837004976519479029344758510378785210151768894024103 0.29145679447786709199560462143289119350316759901206541927220608308729 0.38050637711236488630358791681043310449740571365810083757630562232420 0.46364760900080611621425623146121440202853705428612026381093308872019 0.54041950027058415544357836460859991013514825146259238811636023340959 0.61072596438920861654375887649023609381850306612882761584286773000023 0.67474094222355266305652097360981361507400625484071242312092170496930 0.73281510178650659164079207273428025198575567935825608631050693192821 0.78539816339744830961566084581987572104929234984377645524373614807695 0.83298126667443170541769356183636123851585134443710842085342312250327 0.87605805059819342311404752112834133907534524616033200346065614838499 0.91510070055336041656680197245527296654755880944161873770852665151657 0.95054684081207514789478913546381917504767901030880427426177057808809 0.98279372324732906798571061101466601449687745363162855676142508831798 1.01219701145133418325981347523809017175213711715353810435383625801215 1.03907225953609102762125033790727884531233378855364699989530509706554 1.06369782240255966094389111605254547856256296541932752568273985366635 1.08631839775787341806397958192567762897580047046812780208748680606431 1.10714871779409050301706546017853704007004764540143264667653920743371 1.12637711689379770989641767275145325372112241040085015241064879177491 1.14416883366802053001158090974633622082626800572469223488413501483165 1.16066898625340562678011092078453217718605394084134102434206195147540 1.17600520709513510249122216125017085520341449211184870745209441567184 1.19028994968253173292773377482931833760117898602945207291116667382970 1.20362249297667741080683267484687578339840429857832439350850411338551 1.21609067478395630285892632134113779481025954203667431449700610948231 1.22777238637419322215779309222594182541102155201281262388880100298534 1.23873685925201114137796025438808735907407693977120210817129118165791 1.24904577239825442582991707728109012307782940412989671905466923679715))) (do ((i 0 (+ i 1))) ((= i 30)) (let ((val (atan (/ i (bignum "10"))))) (if (> (magnitude (- val (list-ref atans i))) 1e-36) (format-logged #t ";(atan ~A) -> ~A ~A~%[~A]~%" (/ i 10) val (list-ref atans i) (magnitude (- val (list-ref atans i)))))))) (set! (*s7* 'bignum-precision) old-prec))) ;;; -------------------------------------------------------------------------------- ;;; sinh ;;; -------------------------------------------------------------------------------- (num-test (sinh 0) 0.0) (num-test (sinh 1) 1.17520119364380) (num-test (sinh -1) -1.17520119364380) (num-test (sinh 2) 3.62686040784702) (num-test (sinh -2) -3.62686040784702) (num-test (sinh 3) 10.01787492740990) (num-test (sinh -3) -10.01787492740990) (num-test (sinh 10) 11013.23287470339346) (num-test (sinh -10) -11013.23287470339346) (num-test (sinh 0/1) 0.0) (num-test (sinh 0/2) 0.0) (num-test (sinh 0/3) 0.0) (num-test (sinh 0/10) 0.0) (num-test (sinh 0/1234) 0.0) (num-test (sinh 0/1234000000) 0.0) (num-test (sinh 0/500029) 0.0) (num-test (sinh 0/362880) 0.0) (num-test (sinh 1/1) 1.17520119364380) (num-test (sinh -1/1) -1.17520119364380) (num-test (sinh 1/2) 0.52109530549375) (num-test (sinh -1/2) -0.52109530549375) (num-test (sinh 1/3) 0.33954055725615) (num-test (sinh -1/3) -0.33954055725615) (num-test (sinh 1/10) 0.10016675001984) (num-test (sinh -1/10) -0.10016675001984) (num-test (sinh 1/1234) 0.00081037286017) (num-test (sinh -1/1234) -0.00081037286017) (num-test (sinh 1/1234000000) 0.00000000081037) (num-test (sinh -1/1234000000) -0.00000000081037) (num-test (sinh 1/500029) 0.00000199988401) (num-test (sinh -1/500029) -0.00000199988401) (num-test (sinh 1/362880) 0.00000275573192) (num-test (sinh -1/362880) -0.00000275573192) (num-test (sinh 2/1) 3.62686040784702) (num-test (sinh -2/1) -3.62686040784702) (num-test (sinh 2/2) 1.17520119364380) (num-test (sinh -2/2) -1.17520119364380) (num-test (sinh 2/3) 0.71715846101104) (num-test (sinh -2/3) -0.71715846101104) (num-test (sinh 2/10) 0.20133600254109) (num-test (sinh -2/10) -0.20133600254109) (num-test (sinh 2/1234) 0.00162074625252) (num-test (sinh -2/1234) -0.00162074625252) (num-test (sinh 2/1234000000) 0.00000000162075) (num-test (sinh -2/1234000000) -0.00000000162075) (num-test (sinh 2/500029) 0.00000399976801) (num-test (sinh -2/500029) -0.00000399976801) (num-test (sinh 2/362880) 0.00000551146384) (num-test (sinh -2/362880) -0.00000551146384) (num-test (sinh 3/1) 10.01787492740990) (num-test (sinh -3/1) -10.01787492740990) (num-test (sinh 3/2) 2.12927945509482) (num-test (sinh -3/2) -2.12927945509482) (num-test (sinh 3/3) 1.17520119364380) (num-test (sinh -3/3) -1.17520119364380) (num-test (sinh 3/10) 0.30452029344714) (num-test (sinh -3/10) -0.30452029344714) (num-test (sinh 3/1234) 0.00243112070921) (num-test (sinh -3/1234) -0.00243112070921) (num-test (sinh 3/1234000000) 0.00000000243112) (num-test (sinh -3/1234000000) -0.00000000243112) (num-test (sinh 3/500029) 0.00000599965202) (num-test (sinh -3/500029) -0.00000599965202) (num-test (sinh 3/362880) 0.00000826719577) (num-test (sinh -3/362880) -0.00000826719577) (num-test (sinh 10/1) 11013.23287470339346) (num-test (sinh -10/1) -11013.23287470339346) (num-test (sinh 10/2) 74.20321057778875) (num-test (sinh -10/2) -74.20321057778875) (num-test (sinh 10/3) 13.99797545058944) (num-test (sinh -10/3) -13.99797545058944) (num-test (sinh 10/10) 1.17520119364380) (num-test (sinh -10/10) -1.17520119364380) (num-test (sinh 10/1234) 0.00810381641088) (num-test (sinh -10/1234) -0.00810381641088) (num-test (sinh 10/1234000000) 0.00000000810373) (num-test (sinh -10/1234000000) -0.00000000810373) (num-test (sinh 10/500029) 0.00001999884007) (num-test (sinh -10/500029) -0.00001999884007) (num-test (sinh 10/362880) 0.00002755731923) (num-test (sinh -10/362880) -0.00002755731923) (num-test (sinh 1234/1234) 1.17520119364380) (num-test (sinh -1234/1234) -1.17520119364380) (num-test (sinh 1234/1234000000) 0.00000100000000) (num-test (sinh -1234/1234000000) -0.00000100000000) (num-test (sinh 1234/500029) 0.00246785936931) (num-test (sinh -1234/500029) -0.00246785936931) (num-test (sinh 1234/362880) 0.00340057974622) (num-test (sinh -1234/362880) -0.00340057974622) (num-test (sinh 1234000000/1234000000) 1.17520119364380) (num-test (sinh -1234000000/1234000000) -1.17520119364380) (num-test (sinh 500029/1234000000) 0.00040520989764) (num-test (sinh -500029/1234000000) -0.00040520989764) (num-test (sinh 500029/500029) 1.17520119364380) (num-test (sinh -500029/500029) -1.17520119364380) (num-test (sinh 500029/362880) 1.85732460755603) (num-test (sinh -500029/362880) -1.85732460755603) (num-test (sinh 362880/1234000000) 0.00029406807555) (num-test (sinh -362880/1234000000) -0.00029406807555) (num-test (sinh 362880/500029) 0.79111846340564) (num-test (sinh -362880/500029) -0.79111846340564) (num-test (sinh 362880/362880) 1.17520119364380) (num-test (sinh -362880/362880) -1.17520119364380) (num-test (sinh 0.0) 0.0) (num-test (sinh 0.00000001) 0.00000001) (num-test (sinh -0.00000001) -0.00000001) (num-test (sinh 1.0) 1.17520119364380) (num-test (sinh -1.0) -1.17520119364380) (num-test (sinh pi) 11.54873935725775) (num-test (sinh -3.14159265358979) -11.54873935725775) (num-test (sinh 2.71828182845905) 7.54413710281697) (num-test (sinh -2.71828182845905) -7.54413710281697) (num-test (sinh 0.0+0.0i) 0.0) (num-test (sinh -0.0+0.0i) 0.0) (num-test (sinh 0.0-0.0i) 0.0) (num-test (sinh -0.0-0.0i) 0.0) (num-test (sinh 0.0+0.00000001i) 0.0+0.00000001i) (num-test (sinh -0.0+0.00000001i) 0.0+0.00000001i) (num-test (sinh 0.0-0.00000001i) 0.0-0.00000001i) (num-test (sinh -0.0-0.00000001i) -0.0-0.00000001i) (num-test (sinh 0.0+1.0i) 0.0+0.84147098480790i) (num-test (sinh -0.0+1.0i) 0.0+0.84147098480790i) (num-test (sinh 0.0-1.0i) 0.0-0.84147098480790i) (num-test (sinh -0.0-1.0i) -0.0-0.84147098480790i) (num-test (sinh 0.00000001+0.0i) 0.00000001) (num-test (sinh -0.00000001+0.0i) -0.00000001) (num-test (sinh 0.00000001-0.0i) 0.00000001) (num-test (sinh -0.00000001-0.0i) -0.00000001) (num-test (sinh 0.00000001+0.00000001i) 0.00000001+0.00000001i) (num-test (sinh -0.00000001+0.00000001i) -0.00000001+0.00000001i) (num-test (sinh 0.00000001-0.00000001i) 0.00000001-0.00000001i) (num-test (sinh -0.00000001-0.00000001i) -0.00000001-0.00000001i) (num-test (sinh 0.00000001+1.0i) 0.00000000540302+0.84147098480790i) (num-test (sinh -0.00000001+1.0i) -0.00000000540302+0.84147098480790i) (num-test (sinh 0.00000001-1.0i) 0.00000000540302-0.84147098480790i) (num-test (sinh -0.00000001-1.0i) -0.00000000540302-0.84147098480790i) (num-test (sinh 1.0+0.0i) 1.17520119364380) (num-test (sinh -1.0+0.0i) -1.17520119364380) (num-test (sinh 1.0-0.0i) 1.17520119364380) (num-test (sinh -1.0-0.0i) -1.17520119364380) (num-test (sinh 1.0+0.00000001i) 1.17520119364380+0.00000001543081i) (num-test (sinh -1.0+0.00000001i) -1.17520119364380+0.00000001543081i) (num-test (sinh 1.0-0.00000001i) 1.17520119364380-0.00000001543081i) (num-test (sinh -1.0-0.00000001i) -1.17520119364380-0.00000001543081i) (num-test (sinh 1.0+1.0i) 0.63496391478474+1.29845758141598i) (num-test (sinh -1.0+1.0i) -0.63496391478474+1.29845758141598i) (num-test (sinh 1.0-1.0i) 0.63496391478474-1.29845758141598i) (num-test (sinh -1.0-1.0i) -0.63496391478474-1.29845758141598i) (num-test (sinh 3.14159265358979+0.0i) 11.54873935725775) (num-test (sinh -3.14159265358979+0.0i) -11.54873935725775) (num-test (sinh 3.14159265358979-0.0i) 11.54873935725775) (num-test (sinh -3.14159265358979-0.0i) -11.54873935725775) (num-test (sinh 3.14159265358979+0.00000001i) 11.54873935725775+0.00000011591953i) (num-test (sinh -3.14159265358979+0.00000001i) -11.54873935725775+0.00000011591953i) (num-test (sinh 3.14159265358979-0.00000001i) 11.54873935725775-0.00000011591953i) (num-test (sinh -3.14159265358979-0.00000001i) -11.54873935725775-0.00000011591953i) (num-test (sinh 3.14159265358979+1.0i) 6.23981050459650+9.75429233860021i) (num-test (sinh -3.14159265358979+1.0i) -6.23981050459650+9.75429233860021i) (num-test (sinh 3.14159265358979-1.0i) 6.23981050459650-9.75429233860021i) (num-test (sinh -3.14159265358979-1.0i) -6.23981050459650-9.75429233860021i) (num-test (sinh 2.71828182845905+0.0i) 7.54413710281697) (num-test (sinh -2.71828182845905+0.0i) -7.54413710281697) (num-test (sinh 2.71828182845905-0.0i) 7.54413710281697) (num-test (sinh -2.71828182845905-0.0i) -7.54413710281697) (num-test (sinh 2.71828182845905+0.00000001i) 7.54413710281697+0.00000007610125i) (num-test (sinh -2.71828182845905+0.00000001i) -7.54413710281697+0.00000007610125i) (num-test (sinh 2.71828182845905-0.00000001i) 7.54413710281697-0.00000007610125i) (num-test (sinh -2.71828182845905-0.00000001i) -7.54413710281697-0.00000007610125i) (num-test (sinh 2.71828182845905+1.0i) 4.07611467243740+6.40369949494148i) (num-test (sinh -2.71828182845905+1.0i) -4.07611467243740+6.40369949494148i) (num-test (sinh 2.71828182845905-1.0i) 4.07611467243740-6.40369949494148i) (num-test (sinh -2.71828182845905-1.0i) -4.07611467243740-6.40369949494148i) (num-test (sinh 1234/3) 2.18155865313939E+178) (num-test (sinh 1234/10) 1.953930316004457E+53) (num-test (sinh 0.0+3.14159265358979i) 0.0-6.982889851335445E-15i) (num-test (sinh 0.0+2.71828182845905i) 0.0+0.4107812905029501i) (num-test (sinh 0.00000001+3.14159265358979i) -1.00000000000000003758922749678992050291E-8+3.231089148865173792463232707134864571569E-15i) (num-test (sinh 0.00000001+2.71828182845905i) -9.117339147869465E-9+0.4107812905029501i) (num-test (sinh 0.00000001+1234.0i) -7.985506235875843E-9+0.6019276547624973i) (num-test (sinh 0.00000001+1234000000.0i) 1.5890913089022285E-9-0.9872932128398908i) (num-test (sinh 1.0+3.14159265358979i) -1.175201193643801-1.077516210464362E-14i) (num-test (sinh 1.0+2.71828182845905i) -1.071470784943156+0.6338686545195173i) (num-test (sinh 3.14159265358979+3.14159265358979i) -11.54873935725783-8.094533288479446E-14i) (num-test (sinh 3.14159265358979+2.71828182845905i) -10.52937734504676+4.761757525968664i) (num-test (sinh 3.14159265358979+1234.0i) -9.222253015388718+6.977517249251167i) (num-test (sinh 3.14159265358979+1234000000.0i) 1.835200134139553-11.44465679247962i) (num-test (sinh 2.71828182845905+3.14159265358979i) -7.54413710281663-5.314066559815525E-14i) (num-test (sinh 2.71828182845905+2.71828182845905i) -6.878245654440458+3.126097025348496i) (num-test (sinh 2.71828182845905+1234.0i) -6.024375387884452+4.58074477716391i) (num-test (sinh 2.71828182845905+1234000000.0i) 1.198832270325275-7.513424898263172i) (num-test (sinh 0.0e+00-3.45266983001243932001e-04i) 0-3.4526697614140534807e-4i) (num-test (sinh 0.0e+00+3.45266983001243932001e-04i) 0+3.4526697614140534807e-4i) (num-test (sinh 0.0e+00+1.57045105981189525579e+00i) 0+9.9999994039535581669e-1i) (num-test (sinh 0.0e+00-1.57045105981189525579e+00i) 0-9.9999994039535581669e-1i) (num-test (sinh 0.0e+00+1.57114159377789786021e+00i) 0+9.9999994039535581673e-1i) (num-test (sinh 0.0e+00-1.57114159377789786021e+00i) 0-9.9999994039535581673e-1i) (num-test (sinh 0.0e+00+3.14124738660679181379e+00i) 0+3.4526697614158608860e-4i) (num-test (sinh 0.0e+00-3.14124738660679181379e+00i) 0-3.4526697614158608860e-4i) (num-test (sinh 0.0e+00+3.14193792057279441821e+00i) 0-3.4526697614134115926e-4i) (num-test (sinh 0.0e+00-3.14193792057279441821e+00i) 0+3.4526697614134115926e-4i) (num-test (sinh 0.0e+00+4.71204371340168837179e+00i) 0-9.9999994039535581664e-1i) (num-test (sinh 0.0e+00-4.71204371340168837179e+00i) 0+9.9999994039535581664e-1i) (num-test (sinh 0.0e+00+4.71273424736769097620e+00i) 0-9.9999994039535581677e-1i) (num-test (sinh 0.0e+00-4.71273424736769097620e+00i) 0+9.9999994039535581677e-1i) (num-test (sinh 0.0e+00+6.28284004019658492979e+00i) 0-3.4526697614170855328e-4i) (num-test (sinh 0.0e+00-6.28284004019658492979e+00i) 0+3.4526697614170855328e-4i) (num-test (sinh 0.0e+00+6.28353057416258753420e+00i) 0+3.4526697614121869459e-4i) (num-test (sinh 0.0e+00-6.28353057416258753420e+00i) 0-3.4526697614121869459e-4i) (num-test (sinh 0.0e+00+9.42443269378637893396e+00i) 0+3.4526697614094283958e-4i) (num-test (sinh 0.0e+00-9.42443269378637893396e+00i) 0-3.4526697614094283958e-4i) (num-test (sinh 0.0e+00+9.42512322775237976202e+00i) 0-3.4526697614020805155e-4i) (num-test (sinh 0.0e+00-9.42512322775237976202e+00i) 0+3.4526697614020805155e-4i) (num-test (sinh 1.19209289550781250e-07-3.45266983001243932001e-04i) 1.1920928244535424533e-7-3.4526697614140780134e-4i) (num-test (sinh 1.19209289550781250e-07+3.45266983001243932001e-04i) 1.1920928244535424533e-7+3.4526697614140780134e-4i) (num-test (sinh -1.19209289550781250e-07-3.45266983001243932001e-04i) -1.1920928244535424533e-7-3.4526697614140780134e-4i) (num-test (sinh -1.19209289550781250e-07+3.45266983001243932001e-04i) -1.1920928244535424533e-7+3.4526697614140780134e-4i) (num-test (sinh 1.19209289550781250e-07+1.57045105981189525579e+00i) 4.1159030931177815679e-11+9.9999994039536292211e-1i) (num-test (sinh 1.19209289550781250e-07-1.57045105981189525579e+00i) 4.1159030931177815679e-11-9.9999994039536292211e-1i) (num-test (sinh -1.19209289550781250e-07+1.57045105981189525579e+00i) -4.1159030931177815679e-11+9.9999994039536292211e-1i) (num-test (sinh -1.19209289550781250e-07-1.57045105981189525579e+00i) -4.1159030931177815679e-11-9.9999994039536292211e-1i) (num-test (sinh 1.19209289550781250e-07+1.57114159377789786021e+00i) -4.1159030931163216752e-11+9.9999994039536292216e-1i) (num-test (sinh 1.19209289550781250e-07-1.57114159377789786021e+00i) -4.1159030931163216752e-11-9.9999994039536292216e-1i) (num-test (sinh -1.19209289550781250e-07+1.57114159377789786021e+00i) 4.1159030931163216752e-11+9.9999994039536292216e-1i) (num-test (sinh -1.19209289550781250e-07-1.57114159377789786021e+00i) 4.1159030931163216752e-11-9.9999994039536292216e-1i) (num-test (sinh 1.19209289550781250e-07+3.14124738660679181379e+00i) -1.1920928244535424532e-7+3.4526697614158854187e-4i) (num-test (sinh 1.19209289550781250e-07-3.14124738660679181379e+00i) -1.1920928244535424532e-7-3.4526697614158854187e-4i) (num-test (sinh -1.19209289550781250e-07+3.14124738660679181379e+00i) 1.1920928244535424532e-7+3.4526697614158854187e-4i) (num-test (sinh -1.19209289550781250e-07-3.14124738660679181379e+00i) 1.1920928244535424532e-7-3.4526697614158854187e-4i) (num-test (sinh 1.19209289550781250e-07+3.14193792057279441821e+00i) -1.1920928244535424533e-7-3.4526697614134361253e-4i) (num-test (sinh 1.19209289550781250e-07-3.14193792057279441821e+00i) -1.1920928244535424533e-7+3.4526697614134361253e-4i) (num-test (sinh -1.19209289550781250e-07+3.14193792057279441821e+00i) 1.1920928244535424533e-7-3.4526697614134361253e-4i) (num-test (sinh -1.19209289550781250e-07-3.14193792057279441821e+00i) 1.1920928244535424533e-7+3.4526697614134361253e-4i) (num-test (sinh 1.19209289550781250e-07+4.71204371340168837179e+00i) -4.1159030931192414605e-11-9.9999994039536292207e-1i) (num-test (sinh 1.19209289550781250e-07-4.71204371340168837179e+00i) -4.1159030931192414605e-11+9.9999994039536292207e-1i) (num-test (sinh -1.19209289550781250e-07+4.71204371340168837179e+00i) 4.1159030931192414605e-11-9.9999994039536292207e-1i) (num-test (sinh -1.19209289550781250e-07-4.71204371340168837179e+00i) 4.1159030931192414605e-11+9.9999994039536292207e-1i) (num-test (sinh 1.19209289550781250e-07+4.71273424736769097620e+00i) 4.1159030931148617825e-11-9.9999994039536292220e-1i) (num-test (sinh 1.19209289550781250e-07-4.71273424736769097620e+00i) 4.1159030931148617825e-11+9.9999994039536292220e-1i) (num-test (sinh -1.19209289550781250e-07+4.71273424736769097620e+00i) -4.1159030931148617825e-11-9.9999994039536292220e-1i) (num-test (sinh -1.19209289550781250e-07-4.71273424736769097620e+00i) -4.1159030931148617825e-11+9.9999994039536292220e-1i) (num-test (sinh 1.19209289550781250e-07+6.28284004019658492979e+00i) 1.1920928244535424532e-7-3.4526697614171100655e-4i) (num-test (sinh 1.19209289550781250e-07-6.28284004019658492979e+00i) 1.1920928244535424532e-7+3.4526697614171100655e-4i) (num-test (sinh -1.19209289550781250e-07+6.28284004019658492979e+00i) -1.1920928244535424532e-7-3.4526697614171100655e-4i) (num-test (sinh -1.19209289550781250e-07-6.28284004019658492979e+00i) -1.1920928244535424532e-7+3.4526697614171100655e-4i) (num-test (sinh 1.19209289550781250e-07+6.28353057416258753420e+00i) 1.1920928244535424534e-7+3.4526697614122114786e-4i) (num-test (sinh 1.19209289550781250e-07-6.28353057416258753420e+00i) 1.1920928244535424534e-7-3.4526697614122114786e-4i) (num-test (sinh -1.19209289550781250e-07+6.28353057416258753420e+00i) -1.1920928244535424534e-7+3.4526697614122114786e-4i) (num-test (sinh -1.19209289550781250e-07-6.28353057416258753420e+00i) -1.1920928244535424534e-7-3.4526697614122114786e-4i) (num-test (sinh 1.19209289550781250e-07+9.42443269378637893396e+00i) -1.1920928244535424535e-7+3.4526697614094529285e-4i) (num-test (sinh 1.19209289550781250e-07-9.42443269378637893396e+00i) -1.1920928244535424535e-7-3.4526697614094529285e-4i) (num-test (sinh -1.19209289550781250e-07+9.42443269378637893396e+00i) 1.1920928244535424535e-7+3.4526697614094529285e-4i) (num-test (sinh -1.19209289550781250e-07-9.42443269378637893396e+00i) 1.1920928244535424535e-7-3.4526697614094529285e-4i) (num-test (sinh 1.19209289550781250e-07+9.42512322775237976202e+00i) -1.1920928244535424538e-7-3.4526697614021050482e-4i) (num-test (sinh 1.19209289550781250e-07-9.42512322775237976202e+00i) -1.1920928244535424538e-7+3.4526697614021050482e-4i) (num-test (sinh -1.19209289550781250e-07+9.42512322775237976202e+00i) 1.1920928244535424538e-7-3.4526697614021050482e-4i) (num-test (sinh -1.19209289550781250e-07-9.42512322775237976202e+00i) 1.1920928244535424538e-7+3.4526697614021050482e-4i) (num-test (sinh 5.0e-01-3.45266983001243932001e-04i) 5.2109527443404709209e-1-3.8933200722534065172e-4i) (num-test (sinh 5.0e-01+3.45266983001243932001e-04i) 5.2109527443404709209e-1+3.8933200722534065172e-4i) (num-test (sinh -5.0e-01-3.45266983001243932001e-04i) -5.2109527443404709209e-1-3.8933200722534065172e-4i) (num-test (sinh -5.0e-01+3.45266983001243932001e-04i) -5.2109527443404709209e-1+3.8933200722534065172e-4i) (num-test (sinh 5.0e-01+1.57045105981189525579e+00i) 1.7991700040937027667e-4+1.1276258979946363572e0i) (num-test (sinh 5.0e-01-1.57045105981189525579e+00i) 1.7991700040937027667e-4-1.1276258979946363572e0i) (num-test (sinh -5.0e-01+1.57045105981189525579e+00i) -1.7991700040937027667e-4+1.1276258979946363572e0i) (num-test (sinh -5.0e-01-1.57045105981189525579e+00i) -1.7991700040937027667e-4-1.1276258979946363572e0i) (num-test (sinh 5.0e-01+1.57114159377789786021e+00i) -1.7991700040930646090e-4+1.1276258979946363573e0i) (num-test (sinh 5.0e-01-1.57114159377789786021e+00i) -1.7991700040930646090e-4-1.1276258979946363573e0i) (num-test (sinh -5.0e-01+1.57114159377789786021e+00i) 1.7991700040930646090e-4+1.1276258979946363573e0i) (num-test (sinh -5.0e-01-1.57114159377789786021e+00i) 1.7991700040930646090e-4-1.1276258979946363573e0i) (num-test (sinh 5.0e-01+3.14124738660679181379e+00i) -5.2109527443404709206e-1+3.8933200722554445944e-4i) (num-test (sinh 5.0e-01-3.14124738660679181379e+00i) -5.2109527443404709206e-1-3.8933200722554445944e-4i) (num-test (sinh -5.0e-01+3.14124738660679181379e+00i) 5.2109527443404709206e-1+3.8933200722554445944e-4i) (num-test (sinh -5.0e-01-3.14124738660679181379e+00i) 5.2109527443404709206e-1-3.8933200722554445944e-4i) (num-test (sinh 5.0e-01+3.14193792057279441821e+00i) -5.2109527443404709211e-1-3.8933200722526827075e-4i) (num-test (sinh 5.0e-01-3.14193792057279441821e+00i) -5.2109527443404709211e-1+3.8933200722526827075e-4i) (num-test (sinh -5.0e-01+3.14193792057279441821e+00i) 5.2109527443404709211e-1-3.8933200722526827075e-4i) (num-test (sinh -5.0e-01-3.14193792057279441821e+00i) 5.2109527443404709211e-1+3.8933200722526827075e-4i) (num-test (sinh 5.0e-01+4.71204371340168837179e+00i) -1.7991700040943409243e-4-1.1276258979946363572e0i) (num-test (sinh 5.0e-01-4.71204371340168837179e+00i) -1.7991700040943409243e-4+1.1276258979946363572e0i) (num-test (sinh -5.0e-01+4.71204371340168837179e+00i) 1.7991700040943409243e-4-1.1276258979946363572e0i) (num-test (sinh -5.0e-01-4.71204371340168837179e+00i) 1.7991700040943409243e-4+1.1276258979946363572e0i) (num-test (sinh 5.0e-01+4.71273424736769097620e+00i) 1.7991700040924264514e-4-1.1276258979946363573e0i) (num-test (sinh 5.0e-01-4.71273424736769097620e+00i) 1.7991700040924264514e-4+1.1276258979946363573e0i) (num-test (sinh -5.0e-01+4.71273424736769097620e+00i) -1.7991700040924264514e-4-1.1276258979946363573e0i) (num-test (sinh -5.0e-01-4.71273424736769097620e+00i) -1.7991700040924264514e-4+1.1276258979946363573e0i) (num-test (sinh 5.0e-01+6.28284004019658492979e+00i) 5.2109527443404709204e-1-3.8933200722568255379e-4i) (num-test (sinh 5.0e-01-6.28284004019658492979e+00i) 5.2109527443404709204e-1+3.8933200722568255379e-4i) (num-test (sinh -5.0e-01+6.28284004019658492979e+00i) -5.2109527443404709204e-1-3.8933200722568255379e-4i) (num-test (sinh -5.0e-01-6.28284004019658492979e+00i) -5.2109527443404709204e-1+3.8933200722568255379e-4i) (num-test (sinh 5.0e-01+6.28353057416258753420e+00i) 5.2109527443404709213e-1+3.8933200722513017641e-4i) (num-test (sinh 5.0e-01-6.28353057416258753420e+00i) 5.2109527443404709213e-1-3.8933200722513017641e-4i) (num-test (sinh -5.0e-01+6.28353057416258753420e+00i) -5.2109527443404709213e-1+3.8933200722513017641e-4i) (num-test (sinh -5.0e-01-6.28353057416258753420e+00i) -5.2109527443404709213e-1-3.8933200722513017641e-4i) (num-test (sinh 5.0e-01+9.42443269378637893396e+00i) -5.2109527443404709218e-1+3.8933200722481911514e-4i) (num-test (sinh 5.0e-01-9.42443269378637893396e+00i) -5.2109527443404709218e-1-3.8933200722481911514e-4i) (num-test (sinh -5.0e-01+9.42443269378637893396e+00i) 5.2109527443404709218e-1+3.8933200722481911514e-4i) (num-test (sinh -5.0e-01-9.42443269378637893396e+00i) 5.2109527443404709218e-1-3.8933200722481911514e-4i) (num-test (sinh 5.0e-01+9.42512322775237976202e+00i) -5.2109527443404709231e-1-3.8933200722399054908e-4i) (num-test (sinh 5.0e-01-9.42512322775237976202e+00i) -5.2109527443404709231e-1+3.8933200722399054908e-4i) (num-test (sinh -5.0e-01+9.42512322775237976202e+00i) 5.2109527443404709231e-1-3.8933200722399054908e-4i) (num-test (sinh -5.0e-01-9.42512322775237976202e+00i) 5.2109527443404709231e-1+3.8933200722399054908e-4i) (num-test (sinh 1.0e+00-3.45266983001243932001e-04i) 1.1752011235963524660e0-5.3277478472501939236e-4i) (num-test (sinh 1.0e+00+3.45266983001243932001e-04i) 1.1752011235963524660e0+5.3277478472501939236e-4i) (num-test (sinh -1.0e+00-3.45266983001243932001e-04i) -1.1752011235963524660e0-5.3277478472501939236e-4i) (num-test (sinh -1.0e+00+3.45266983001243932001e-04i) -1.1752011235963524660e0+5.3277478472501939236e-4i) (num-test (sinh 1.0e+00+1.57045105981189525579e+00i) 4.0575816248730593018e-4+1.5430805428404715942e0i) (num-test (sinh 1.0e+00-1.57045105981189525579e+00i) 4.0575816248730593018e-4-1.5430805428404715942e0i) (num-test (sinh -1.0e+00+1.57045105981189525579e+00i) -4.0575816248730593018e-4+1.5430805428404715942e0i) (num-test (sinh -1.0e+00-1.57045105981189525579e+00i) -4.0575816248730593018e-4-1.5430805428404715942e0i) (num-test (sinh 1.0e+00+1.57114159377789786021e+00i) -4.0575816248716200955e-4+1.5430805428404715942e0i) (num-test (sinh 1.0e+00-1.57114159377789786021e+00i) -4.0575816248716200955e-4-1.5430805428404715942e0i) (num-test (sinh -1.0e+00+1.57114159377789786021e+00i) 4.0575816248716200955e-4+1.5430805428404715942e0i) (num-test (sinh -1.0e+00-1.57114159377789786021e+00i) 4.0575816248716200955e-4-1.5430805428404715942e0i) (num-test (sinh 1.0e+00+3.14124738660679181379e+00i) -1.1752011235963524659e0+5.3277478472529828958e-4i) (num-test (sinh 1.0e+00-3.14124738660679181379e+00i) -1.1752011235963524659e0-5.3277478472529828958e-4i) (num-test (sinh -1.0e+00+3.14124738660679181379e+00i) 1.1752011235963524659e0+5.3277478472529828958e-4i) (num-test (sinh -1.0e+00-3.14124738660679181379e+00i) 1.1752011235963524659e0-5.3277478472529828958e-4i) (num-test (sinh 1.0e+00+3.14193792057279441821e+00i) -1.1752011235963524660e0-5.3277478472492034385e-4i) (num-test (sinh 1.0e+00-3.14193792057279441821e+00i) -1.1752011235963524660e0+5.3277478472492034385e-4i) (num-test (sinh -1.0e+00+3.14193792057279441821e+00i) 1.1752011235963524660e0-5.3277478472492034385e-4i) (num-test (sinh -1.0e+00-3.14193792057279441821e+00i) 1.1752011235963524660e0+5.3277478472492034385e-4i) (num-test (sinh 1.0e+00+4.71204371340168837179e+00i) -4.0575816248744985081e-4-1.5430805428404715941e0i) (num-test (sinh 1.0e+00-4.71204371340168837179e+00i) -4.0575816248744985081e-4+1.5430805428404715941e0i) (num-test (sinh -1.0e+00+4.71204371340168837179e+00i) 4.0575816248744985081e-4-1.5430805428404715941e0i) (num-test (sinh -1.0e+00-4.71204371340168837179e+00i) 4.0575816248744985081e-4+1.5430805428404715941e0i) (num-test (sinh 1.0e+00+4.71273424736769097620e+00i) 4.0575816248701808892e-4-1.5430805428404715943e0i) (num-test (sinh 1.0e+00-4.71273424736769097620e+00i) 4.0575816248701808892e-4+1.5430805428404715943e0i) (num-test (sinh -1.0e+00+4.71273424736769097620e+00i) -4.0575816248701808892e-4-1.5430805428404715943e0i) (num-test (sinh -1.0e+00-4.71273424736769097620e+00i) -4.0575816248701808892e-4+1.5430805428404715943e0i) (num-test (sinh 1.0e+00+6.28284004019658492979e+00i) 1.1752011235963524659e0-5.3277478472548726245e-4i) (num-test (sinh 1.0e+00-6.28284004019658492979e+00i) 1.1752011235963524659e0+5.3277478472548726245e-4i) (num-test (sinh -1.0e+00+6.28284004019658492979e+00i) -1.1752011235963524659e0-5.3277478472548726245e-4i) (num-test (sinh -1.0e+00-6.28284004019658492979e+00i) -1.1752011235963524659e0+5.3277478472548726245e-4i) (num-test (sinh 1.0e+00+6.28353057416258753420e+00i) 1.1752011235963524661e0+5.3277478472473137099e-4i) (num-test (sinh 1.0e+00-6.28353057416258753420e+00i) 1.1752011235963524661e0-5.3277478472473137099e-4i) (num-test (sinh -1.0e+00+6.28353057416258753420e+00i) -1.1752011235963524661e0+5.3277478472473137099e-4i) (num-test (sinh -1.0e+00-6.28353057416258753420e+00i) -1.1752011235963524661e0-5.3277478472473137099e-4i) (num-test (sinh 1.0e+00+9.42443269378637893396e+00i) -1.1752011235963524662e0+5.3277478472430570447e-4i) (num-test (sinh 1.0e+00-9.42443269378637893396e+00i) -1.1752011235963524662e0-5.3277478472430570447e-4i) (num-test (sinh -1.0e+00+9.42443269378637893396e+00i) 1.1752011235963524662e0+5.3277478472430570447e-4i) (num-test (sinh -1.0e+00-9.42443269378637893396e+00i) 1.1752011235963524662e0-5.3277478472430570447e-4i) (num-test (sinh 1.0e+00+9.42512322775237976202e+00i) -1.1752011235963524665e0-5.3277478472317186729e-4i) (num-test (sinh 1.0e+00-9.42512322775237976202e+00i) -1.1752011235963524665e0+5.3277478472317186729e-4i) (num-test (sinh -1.0e+00+9.42512322775237976202e+00i) 1.1752011235963524665e0-5.3277478472317186729e-4i) (num-test (sinh -1.0e+00-9.42512322775237976202e+00i) 1.1752011235963524665e0+5.3277478472317186729e-4i) (num-test (sinh 2.0e+00-3.45266983001243932001e-04i) 3.6268601916692946556e0-1.2989619299126701883e-3i) (num-test (sinh 2.0e+00+3.45266983001243932001e-04i) 3.6268601916692946556e0+1.2989619299126701883e-3i) (num-test (sinh -2.0e+00-3.45266983001243932001e-04i) -3.6268601916692946556e0-1.2989619299126701883e-3i) (num-test (sinh -2.0e+00+3.45266983001243932001e-04i) -3.6268601916692946556e0+1.2989619299126701883e-3i) (num-test (sinh 2.0e+00+1.57045105981189525579e+00i) 1.2522351259047577385e-3+3.7621954668392959445e0i) (num-test (sinh 2.0e+00-1.57045105981189525579e+00i) 1.2522351259047577385e-3-3.7621954668392959445e0i) (num-test (sinh -2.0e+00+1.57045105981189525579e+00i) -1.2522351259047577385e-3+3.7621954668392959445e0i) (num-test (sinh -2.0e+00-1.57045105981189525579e+00i) -1.2522351259047577385e-3-3.7621954668392959445e0i) (num-test (sinh 2.0e+00+1.57114159377789786021e+00i) -1.2522351259043135762e-3+3.7621954668392959447e0i) (num-test (sinh 2.0e+00-1.57114159377789786021e+00i) -1.2522351259043135762e-3-3.7621954668392959447e0i) (num-test (sinh -2.0e+00+1.57114159377789786021e+00i) 1.2522351259043135762e-3+3.7621954668392959447e0i) (num-test (sinh -2.0e+00-1.57114159377789786021e+00i) 1.2522351259043135762e-3-3.7621954668392959447e0i) (num-test (sinh 2.0e+00+3.14124738660679181379e+00i) -3.6268601916692946553e0+1.2989619299133501696e-3i) (num-test (sinh 2.0e+00-3.14124738660679181379e+00i) -3.6268601916692946553e0-1.2989619299133501696e-3i) (num-test (sinh -2.0e+00+3.14124738660679181379e+00i) 3.6268601916692946553e0+1.2989619299133501696e-3i) (num-test (sinh -2.0e+00-3.14124738660679181379e+00i) 3.6268601916692946553e0-1.2989619299133501696e-3i) (num-test (sinh 2.0e+00+3.14193792057279441821e+00i) -3.6268601916692946556e0-1.2989619299124286975e-3i) (num-test (sinh 2.0e+00-3.14193792057279441821e+00i) -3.6268601916692946556e0+1.2989619299124286975e-3i) (num-test (sinh -2.0e+00+3.14193792057279441821e+00i) 3.6268601916692946556e0-1.2989619299124286975e-3i) (num-test (sinh -2.0e+00-3.14193792057279441821e+00i) 3.6268601916692946556e0+1.2989619299124286975e-3i) (num-test (sinh 2.0e+00+4.71204371340168837179e+00i) -1.2522351259052019007e-3-3.7621954668392959444e0i) (num-test (sinh 2.0e+00-4.71204371340168837179e+00i) -1.2522351259052019007e-3+3.7621954668392959444e0i) (num-test (sinh -2.0e+00+4.71204371340168837179e+00i) 1.2522351259052019007e-3-3.7621954668392959444e0i) (num-test (sinh -2.0e+00-4.71204371340168837179e+00i) 1.2522351259052019007e-3+3.7621954668392959444e0i) (num-test (sinh 2.0e+00+4.71273424736769097620e+00i) 1.2522351259038694139e-3-3.7621954668392959448e0i) (num-test (sinh 2.0e+00-4.71273424736769097620e+00i) 1.2522351259038694139e-3+3.7621954668392959448e0i) (num-test (sinh -2.0e+00+4.71273424736769097620e+00i) -1.2522351259038694139e-3-3.7621954668392959448e0i) (num-test (sinh -2.0e+00-4.71273424736769097620e+00i) -1.2522351259038694139e-3+3.7621954668392959448e0i) (num-test (sinh 2.0e+00+6.28284004019658492979e+00i) 3.6268601916692946552e0-1.2989619299138109057e-3i) (num-test (sinh 2.0e+00-6.28284004019658492979e+00i) 3.6268601916692946552e0+1.2989619299138109057e-3i) (num-test (sinh -2.0e+00+6.28284004019658492979e+00i) -3.6268601916692946552e0-1.2989619299138109057e-3i) (num-test (sinh -2.0e+00-6.28284004019658492979e+00i) -3.6268601916692946552e0+1.2989619299138109057e-3i) (num-test (sinh 2.0e+00+6.28353057416258753420e+00i) 3.6268601916692946558e0+1.2989619299119679614e-3i) (num-test (sinh 2.0e+00-6.28353057416258753420e+00i) 3.6268601916692946558e0-1.2989619299119679614e-3i) (num-test (sinh -2.0e+00+6.28353057416258753420e+00i) -3.6268601916692946558e0+1.2989619299119679614e-3i) (num-test (sinh -2.0e+00-6.28353057416258753420e+00i) -3.6268601916692946558e0-1.2989619299119679614e-3i) (num-test (sinh 2.0e+00+9.42443269378637893396e+00i) -3.6268601916692946561e0+1.2989619299109301409e-3i) (num-test (sinh 2.0e+00-9.42443269378637893396e+00i) -3.6268601916692946561e0-1.2989619299109301409e-3i) (num-test (sinh -2.0e+00+9.42443269378637893396e+00i) 3.6268601916692946561e0+1.2989619299109301409e-3i) (num-test (sinh -2.0e+00-9.42443269378637893396e+00i) 3.6268601916692946561e0-1.2989619299109301409e-3i) (num-test (sinh 2.0e+00+9.42512322775237976202e+00i) -3.6268601916692946571e0-1.2989619299081657245e-3i) (num-test (sinh 2.0e+00-9.42512322775237976202e+00i) -3.6268601916692946571e0+1.2989619299081657245e-3i) (num-test (sinh -2.0e+00+9.42512322775237976202e+00i) 3.6268601916692946571e0-1.2989619299081657245e-3i) (num-test (sinh -2.0e+00-9.42512322775237976202e+00i) 3.6268601916692946571e0+1.2989619299081657245e-3i) (num-test (sinh 0) 0.0) (num-test (sinh 0+i) (* 0+i (sin 1))) (num-test (sinh -2.225073858507201399999999999999999999996E-308) -2.225073858507201399999999999999999999996E-308) (num-test (sinh 1.110223024625156799999999999999999999997E-16) 1.110223024625156800000000000000002280754E-16) (num-test (sinh 1/9223372036854775807) 1.084202172485504434125002235952170462235E-19) (for-each (lambda (num-and-val) (let ((num (car num-and-val)) (val (cadr num-and-val))) (num-test-1 'sinh num (sinh num) val))) (vector (list 0 0) (list 1 1.1752011936438) (list 2 3.626860407847) (list 3 10.01787492741) (list -1 -1.1752011936438) (list -2 -3.626860407847) (list -3 -10.01787492741) (list 1/2 0.52109530549375) (list 1/3 0.33954055725615) (list -1/2 -0.52109530549375) (list -1/3 -0.33954055725615) (list 1/9223372036854775807 1.0842021724855e-19) (list 0.0 0.0) (list 1.0 1.1752011936438) (list 2.0 3.626860407847) (list -2.0 -3.626860407847) (list 1.000000000000000000000000000000000000002E-309 1.000000000000000000000000000000000000002E-309) (list 0+1i 0+0.8414709848079i) (list 0+2i -0+0.90929742682568i) (list 0-1i 0-0.8414709848079i) (list 1+1i 0.63496391478474+1.298457581416i) (list 1-1i 0.63496391478474-1.298457581416i) (list -1+1i -0.63496391478474+1.298457581416i) (list -1-1i -0.63496391478474-1.298457581416i) (list 0.1+0.1i 0.099666333492108+0.10033299984131i) (list 1e-16+1e-16i 1e-16+1e-16i) )) (test (sinh) 'error) (test (sinh "hi") 'error) (test (sinh 1.0+23.0i 1.0+23.0i) 'error) (test (sinh 0 1) 'error) (for-each (lambda (arg) (test (sinh arg) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) ;;; -------------------------------------------------------------------------------- ;;; cosh ;;; -------------------------------------------------------------------------------- (num-test (cosh 0) 1.0) (num-test (cosh 1) 1.54308063481524) (num-test (cosh 2) 3.76219569108363) (num-test (cosh 3) 10.06766199577777) (num-test (cosh 10) 11013.23292010332261) (num-test (cosh 0/1) 1.0) (num-test (cosh 0/2) 1.0) (num-test (cosh 0/3) 1.0) (num-test (cosh 0/10) 1.0) (num-test (cosh 0/1234) 1.0) (num-test (cosh 0/1234000000) 1.0) (num-test (cosh 0/500029) 1.0) (num-test (cosh 0/362880) 1.0) (num-test (cosh 1/1) 1.54308063481524) (num-test (cosh 1/2) 1.12762596520638) (num-test (cosh -1/2) 1.12762596520638) (num-test (cosh 1/3) 1.05607186782994) (num-test (cosh -1/3) 1.05607186782994) (num-test (cosh 1/10) 1.00500416805580) (num-test (cosh -1/10) 1.00500416805580) (num-test (cosh 1/1234) 1.00000032835203) (num-test (cosh -1/1234) 1.00000032835203) (num-test (cosh 1/1234000000) 1.0) (num-test (cosh -1/1234000000) 1.0) (num-test (cosh 1/500029) 1.00000000000200) (num-test (cosh -1/500029) 1.00000000000200) (num-test (cosh 1/362880) 1.00000000000380) (num-test (cosh -1/362880) 1.00000000000380) (num-test (cosh 2/1) 3.76219569108363) (num-test (cosh 2/2) 1.54308063481524) (num-test (cosh 2/3) 1.23057558004363) (num-test (cosh 2/10) 1.02006675561908) (num-test (cosh -2/10) 1.02006675561908) (num-test (cosh 2/1234) 1.00000131340834) (num-test (cosh -2/1234) 1.00000131340834) (num-test (cosh 2/1234000000) 1.0) (num-test (cosh -2/1234000000) 1.0) (num-test (cosh 2/500029) 1.00000000000800) (num-test (cosh -2/500029) 1.00000000000800) (num-test (cosh 2/362880) 1.00000000001519) (num-test (cosh -2/362880) 1.00000000001519) (num-test (cosh 3/1) 10.06766199577777) (num-test (cosh 3/2) 2.35240961524325) (num-test (cosh 3/3) 1.54308063481524) (num-test (cosh 3/10) 1.04533851412886) (num-test (cosh -3/10) 1.04533851412886) (num-test (cosh 3/1234) 1.00000295516958) (num-test (cosh -3/1234) 1.00000295516958) (num-test (cosh 3/1234000000) 1.0) (num-test (cosh -3/1234000000) 1.0) (num-test (cosh 3/500029) 1.00000000001800) (num-test (cosh -3/500029) 1.00000000001800) (num-test (cosh 3/362880) 1.00000000003417) (num-test (cosh -3/362880) 1.00000000003417) (num-test (cosh 10/1) 11013.23292010332261) (num-test (cosh 10/2) 74.20994852478785) (num-test (cosh 10/3) 14.03364944393670) (num-test (cosh 10/10) 1.54308063481524) (num-test (cosh 10/1234) 1.00003283538113) (num-test (cosh -10/1234) 1.00003283538113) (num-test (cosh 10/1234000000) 1.0) (num-test (cosh -10/1234000000) 1.0) (num-test (cosh 10/500029) 1.00000000019998) (num-test (cosh -10/500029) 1.00000000019998) (num-test (cosh 10/362880) 1.00000000037970) (num-test (cosh -10/362880) 1.00000000037970) (num-test (cosh 1234/1234) 1.54308063481524) (num-test (cosh 1234/1234000000) 1.00000000000050) (num-test (cosh -1234/1234000000) 1.00000000000050) (num-test (cosh 1234/500029) 1.00000304516030) (num-test (cosh -1234/500029) 1.00000304516030) (num-test (cosh 1234/362880) 1.00000578195459) (num-test (cosh -1234/362880) 1.00000578195459) (num-test (cosh 1234000000/1234000000) 1.54308063481524) (num-test (cosh 500029/1234000000) 1.00000008209753) (num-test (cosh -500029/1234000000) 1.00000008209753) (num-test (cosh 500029/500029) 1.54308063481524) (num-test (cosh 500029/362880) 2.10942046492234) (num-test (cosh 362880/1234000000) 1.00000004323802) (num-test (cosh -362880/1234000000) 1.00000004323802) (num-test (cosh 362880/500029) 1.27509545648210) (num-test (cosh 362880/362880) 1.54308063481524) (num-test (cosh 0.0) 1.0) (num-test (cosh 0.00000001) 1.0) (num-test (cosh -0.00000001) 1.0) (num-test (cosh 1.0) 1.54308063481524) (num-test (cosh pi) 11.59195327552152) (num-test (cosh 2.71828182845905) 7.61012513866229) (num-test (cosh 0.0+0.0i) 1.0) (num-test (cosh -0.0+0.0i) 1.0) (num-test (cosh 0.0-0.0i) 1.0) (num-test (cosh -0.0-0.0i) 1.0) (num-test (cosh 0.0+0.00000001i) 1.0) (num-test (cosh -0.0+0.00000001i) 1.0) (num-test (cosh 0.0-0.00000001i) 1.0) (num-test (cosh -0.0-0.00000001i) 1.0) (num-test (cosh 0.0+1.0i) 0.54030230586814) (num-test (cosh -0.0+1.0i) 0.54030230586814) (num-test (cosh 0.0-1.0i) 0.54030230586814) (num-test (cosh 0.0+3.14159265358979i) -1.0) (num-test (cosh -0.0+3.14159265358979i) -1.0) (num-test (cosh 0.0-3.14159265358979i) -1.0) (num-test (cosh 0.0+2.71828182845905i) -0.91173391478697) (num-test (cosh -0.0+2.71828182845905i) -0.91173391478697) (num-test (cosh 0.0-2.71828182845905i) -0.91173391478697) (num-test (cosh 0.00000001+0.0i) 1.0) (num-test (cosh -0.00000001+0.0i) 1.0) (num-test (cosh 0.00000001-0.0i) 1.0) (num-test (cosh -0.00000001-0.0i) 1.0) (num-test (cosh 0.00000001+0.00000001i) 1.0+1e-16i) ; maxima (num-test (cosh -0.00000001+0.00000001i) 1.0-1e-16i) (num-test (cosh 0.00000001-0.00000001i) 1.0-1e-16i) (num-test (cosh -0.00000001-0.00000001i) 1.0+1e-16i) (num-test (cosh 0.00000001+1.0i) 0.54030230586814+0.00000000841471i) (num-test (cosh 0.00000001-1.0i) 0.54030230586814-0.00000000841471i) (num-test (cosh 0.00000001+3.14159265358979i) -1.0-6.982889851335445E-23i) ;maxima -- stopped here (num-test (cosh 0.00000001-3.14159265358979i) -1.0-0.0i) (num-test (cosh 0.00000001+2.71828182845905i) -0.91173391478697+0.00000000410781i) (num-test (cosh 0.00000001-2.71828182845905i) -0.91173391478697-0.00000000410781i) (num-test (cosh 1.0+0.0i) 1.54308063481524) (num-test (cosh 1.0-0.0i) 1.54308063481524) (num-test (cosh 1.0+0.00000001i) 1.54308063481524+0.00000001175201i) (num-test (cosh 1.0-0.00000001i) 1.54308063481524-0.00000001175201i) (num-test (cosh 1.0+1.0i) 0.83373002513115+0.98889770576287i) (num-test (cosh 1.0-1.0i) 0.83373002513115-0.98889770576287i) (num-test (cosh 1.0+3.14159265358979i) -1.54308063481524+0.0i) (num-test (cosh 1.0-3.14159265358979i) -1.54308063481524-0.0i) (num-test (cosh 1.0+2.71828182845905i) -1.40687894801206+0.48275066292556i) (num-test (cosh 1.0-2.71828182845905i) -1.40687894801206-0.48275066292556i) (num-test (cosh 3.14159265358979+0.0i) 11.59195327552152) (num-test (cosh 3.14159265358979-0.0i) 11.59195327552152) (num-test (cosh 3.14159265358979+0.00000001i) 11.59195327552152+0.00000011548739i) (num-test (cosh 3.14159265358979-0.00000001i) 11.59195327552152-0.00000011548739i) (num-test (cosh 3.14159265358979+1.0i) 6.26315908428001+9.71792908024139i) (num-test (cosh 3.14159265358979-1.0i) 6.26315908428001-9.71792908024139i) (num-test (cosh 3.14159265358979+3.14159265358979i) -11.59195327552152+0.0i) (num-test (cosh 3.14159265358979-3.14159265358979i) -11.59195327552152-0.0i) (num-test (cosh 3.14159265358979+2.71828182845905i) -10.56877693991882+4.74400605685607i) (num-test (cosh 3.14159265358979-2.71828182845905i) -10.56877693991882-4.74400605685607i) (num-test (cosh 2.71828182845905+0.0i) 7.61012513866229) (num-test (cosh 2.71828182845905-0.0i) 7.61012513866229) (num-test (cosh 2.71828182845905+0.00000001i) 7.61012513866229+0.00000007544137i) (num-test (cosh 2.71828182845905-0.00000001i) 7.61012513866229-0.00000007544137i) (num-test (cosh 2.71828182845905+1.0i) 4.11176816036433+6.34817247743319i) (num-test (cosh 2.71828182845905-1.0i) 4.11176816036433-6.34817247743319i) (num-test (cosh 2.71828182835905+3.14159265358979i) -7.61012513866229+0.0i) (num-test (cosh 2.71828182845905-3.14159265358979i) -7.61012513866229-0.0i) (num-test (cosh 2.71828182845905+2.71828182845905i) -6.93840918469126+3.09899037482603i) (num-test (cosh 2.71828182845905-2.71828182845905i) -6.93840918469126-3.09899037482603i) (num-test (cosh -2/3) 1.230575580043636) (num-test (cosh -3/2) 2.352409615243247) (num-test (cosh -10/3) 14.03364944393623) (num-test (cosh 1234/3) 2.18155865313939E+178) (num-test (cosh 1234/10) 1.953930316004457E+53) (num-test (cosh 500029/1234) 4.77955809407816E+175) (num-test (cosh -500029/362880) 2.109420464922257) (num-test (cosh 362880/1234) 2.57697781296564E+127) (num-test (cosh -362880/500029) 1.275095456482107) (num-test (cosh -3.14159265358979) 11.5919532755216) (num-test (cosh -2.71828182845905) 7.610125138661946) (num-test (cosh 0.0+3.14159265358979i) -1.0) (num-test (cosh 0.0+2.71828182845905i) -0.9117339147869464) (num-test (cosh 0.00000001+1.0i) +0.5403023058681398+8.414709848078964E-9i) (num-test (cosh 0.00000001+3.14159265358979i) -1.0-6.982889851335445E-23i) (num-test (cosh 0.00000001+2.71828182845905i) -0.9117339147869464+4.1078129050295015E-9i) (num-test (cosh 0.00000001+1234.0i) -0.7985506235875843+6.019276547624973E-9i) (num-test (cosh 0.00000001+1234000000.0i) .1589091308902228-9.872932128398908E-9i) (num-test (cosh 1.0+0.00000001i) +1.543080634815244+1.1752011936438014E-8i) (num-test (cosh 1.0+3.14159265358979i) -1.543080634815244-8.206300488372603E-15i) (num-test (cosh 1.0+2.71828182845905i) -1.406878948012029+0.4827506629256081i) (num-test (cosh 3.14159265358979+0.0i) 11.5919532755216) (num-test (cosh 3.14159265358979+0.00000001i) +11.5919532755216+1.154873935725783E-7i) (num-test (cosh 3.14159265358979+1.0i) +6.263159084280057+9.71792908024146i) (num-test (cosh 3.14159265358979+3.14159265358979i) -11.5919532755216-8.064357485351393E-14i) (num-test (cosh 3.14159265358979+2.71828182845905i) -10.56877693991868+4.744006056856582i) (num-test (cosh 3.14159265358979+1234.0i) -9.256761516765916+6.951505596777556i) (num-test (cosh 3.14159265358979+1234000000.0i) 1.84206722033321-11.40199198427758i) (num-test (cosh 2.71828182845905+0.0i) 7.610125138661946) (num-test (cosh 2.71828182845905+0.00000001i) +7.610125138661945+7.54413710281663E-8i) (num-test (cosh 2.71828182845905+1.0i) +4.111768160364146+6.348172477432901i) (num-test (cosh 2.71828182845905+3.14159265358979i) -7.610125138661946-5.267987841234144E-14i) (num-test (cosh 2.71828182845905+2.71828182845905i) -6.93840918469081+3.098990374826203i) (num-test (cosh 2.71828182845905+1234.0i) -6.077070175058048+4.541024753505155i) (num-test (cosh 2.71828182845905+1234000000.0i) 1.209318371750606-7.448275358344457i) (num-test (cosh 0.0e+00-3.45266983001243932001e-04i) 9.9999994039535581673e-1+0.0i) (num-test (cosh 0.0e+00+3.45266983001243932001e-04i) 9.9999994039535581673e-1+0.0i) (num-test (cosh 0.0e+00+1.57045105981189525579e+00i) 3.4526697614152485627e-4+0.0i) (num-test (cosh 0.0e+00-1.57045105981189525579e+00i) 3.4526697614152485627e-4+0.0i) (num-test (cosh 0.0e+00+1.57114159377789786021e+00i) -3.4526697614140239160e-4+0.0i) (num-test (cosh 0.0e+00-1.57114159377789786021e+00i) -3.4526697614140239160e-4+0.0i) (num-test (cosh 0.0e+00+3.14124738660679181379e+00i) -9.9999994039535581667e-1+0.0i) (num-test (cosh 0.0e+00-3.14124738660679181379e+00i) -9.9999994039535581667e-1+0.0i) (num-test (cosh 0.0e+00+3.14193792057279441821e+00i) -9.9999994039535581675e-1+0.0i) (num-test (cosh 0.0e+00-3.14193792057279441821e+00i) -9.9999994039535581675e-1+0.0i) (num-test (cosh 0.0e+00+4.71204371340168837179e+00i) -3.4526697614164732094e-4+0.0i) (num-test (cosh 0.0e+00-4.71204371340168837179e+00i) -3.4526697614164732094e-4+0.0i) (num-test (cosh 0.0e+00+4.71273424736769097620e+00i) 3.4526697614127992692e-4+0.0i) (num-test (cosh 0.0e+00-4.71273424736769097620e+00i) 3.4526697614127992692e-4+0.0i) (num-test (cosh 0.0e+00+6.28284004019658492979e+00i) 9.9999994039535581662e-1+0.0i) (num-test (cosh 0.0e+00-6.28284004019658492979e+00i) 9.9999994039535581662e-1+0.0i) (num-test (cosh 0.0e+00+6.28353057416258753420e+00i) 9.9999994039535581679e-1+0.0i) (num-test (cosh 0.0e+00-6.28353057416258753420e+00i) 9.9999994039535581679e-1+0.0i) (num-test (cosh 0.0e+00+9.42443269378637893396e+00i) -9.9999994039535581689e-1+0.0i) (num-test (cosh 0.0e+00-9.42443269378637893396e+00i) -9.9999994039535581689e-1+0.0i) (num-test (cosh 0.0e+00+9.42512322775237976202e+00i) -9.9999994039535581714e-1+0.0i) (num-test (cosh 0.0e+00-9.42512322775237976202e+00i) -9.9999994039535581714e-1+0.0i) (num-test (cosh 1.19209289550781250e-07-3.45266983001243932001e-04i) 9.9999994039536292216e-1-4.1159030931163569191e-11i) (num-test (cosh 1.19209289550781250e-07+3.45266983001243932001e-04i) 9.9999994039536292216e-1+4.1159030931163569191e-11i) (num-test (cosh -1.19209289550781250e-07-3.45266983001243932001e-04i) 9.9999994039536292216e-1+4.1159030931163569191e-11i) (num-test (cosh -1.19209289550781250e-07+3.45266983001243932001e-04i) 9.9999994039536292216e-1-4.1159030931163569191e-11i) (num-test (cosh 1.19209289550781250e-07+1.57045105981189525579e+00i) 3.4526697614152730954e-4+1.1920928244535424532e-7i) (num-test (cosh 1.19209289550781250e-07-1.57045105981189525579e+00i) 3.4526697614152730954e-4-1.1920928244535424532e-7i) (num-test (cosh -1.19209289550781250e-07+1.57045105981189525579e+00i) 3.4526697614152730954e-4-1.1920928244535424532e-7i) (num-test (cosh -1.19209289550781250e-07-1.57045105981189525579e+00i) 3.4526697614152730954e-4+1.1920928244535424532e-7i) (num-test (cosh 1.19209289550781250e-07+1.57114159377789786021e+00i) -3.4526697614140484486e-4+1.1920928244535424533e-7i) (num-test (cosh 1.19209289550781250e-07-1.57114159377789786021e+00i) -3.4526697614140484486e-4-1.1920928244535424533e-7i) (num-test (cosh -1.19209289550781250e-07+1.57114159377789786021e+00i) -3.4526697614140484486e-4-1.1920928244535424533e-7i) (num-test (cosh -1.19209289550781250e-07-1.57114159377789786021e+00i) -3.4526697614140484486e-4+1.1920928244535424533e-7i) (num-test (cosh 1.19209289550781250e-07+3.14124738660679181379e+00i) -9.9999994039536292209e-1+4.1159030931185115142e-11i) (num-test (cosh 1.19209289550781250e-07-3.14124738660679181379e+00i) -9.9999994039536292209e-1-4.1159030931185115142e-11i) (num-test (cosh -1.19209289550781250e-07+3.14124738660679181379e+00i) -9.9999994039536292209e-1-4.1159030931185115142e-11i) (num-test (cosh -1.19209289550781250e-07-3.14124738660679181379e+00i) -9.9999994039536292209e-1+4.1159030931185115142e-11i) (num-test (cosh 1.19209289550781250e-07+3.14193792057279441821e+00i) -9.9999994039536292218e-1-4.1159030931155917289e-11i) (num-test (cosh 1.19209289550781250e-07-3.14193792057279441821e+00i) -9.9999994039536292218e-1+4.1159030931155917289e-11i) (num-test (cosh -1.19209289550781250e-07+3.14193792057279441821e+00i) -9.9999994039536292218e-1+4.1159030931155917289e-11i) (num-test (cosh -1.19209289550781250e-07-3.14193792057279441821e+00i) -9.9999994039536292218e-1-4.1159030931155917289e-11i) (num-test (cosh 1.19209289550781250e-07+4.71204371340168837179e+00i) -3.4526697614164977421e-4-1.1920928244535424532e-7i) (num-test (cosh 1.19209289550781250e-07-4.71204371340168837179e+00i) -3.4526697614164977421e-4+1.1920928244535424532e-7i) (num-test (cosh -1.19209289550781250e-07+4.71204371340168837179e+00i) -3.4526697614164977421e-4+1.1920928244535424532e-7i) (num-test (cosh -1.19209289550781250e-07-4.71204371340168837179e+00i) -3.4526697614164977421e-4-1.1920928244535424532e-7i) (num-test (cosh 1.19209289550781250e-07+4.71273424736769097620e+00i) 3.4526697614128238019e-4-1.1920928244535424533e-7i) (num-test (cosh 1.19209289550781250e-07-4.71273424736769097620e+00i) 3.4526697614128238019e-4+1.1920928244535424533e-7i) (num-test (cosh -1.19209289550781250e-07+4.71273424736769097620e+00i) 3.4526697614128238019e-4+1.1920928244535424533e-7i) (num-test (cosh -1.19209289550781250e-07-4.71273424736769097620e+00i) 3.4526697614128238019e-4-1.1920928244535424533e-7i) (num-test (cosh 1.19209289550781250e-07+6.28284004019658492979e+00i) 9.9999994039536292205e-1-4.1159030931199714069e-11i) (num-test (cosh 1.19209289550781250e-07-6.28284004019658492979e+00i) 9.9999994039536292205e-1+4.1159030931199714069e-11i) (num-test (cosh -1.19209289550781250e-07+6.28284004019658492979e+00i) 9.9999994039536292205e-1+4.1159030931199714069e-11i) (num-test (cosh -1.19209289550781250e-07-6.28284004019658492979e+00i) 9.9999994039536292205e-1-4.1159030931199714069e-11i) (num-test (cosh 1.19209289550781250e-07+6.28353057416258753420e+00i) 9.9999994039536292222e-1+4.1159030931141318362e-11i) (num-test (cosh 1.19209289550781250e-07-6.28353057416258753420e+00i) 9.9999994039536292222e-1-4.1159030931141318362e-11i) (num-test (cosh -1.19209289550781250e-07+6.28353057416258753420e+00i) 9.9999994039536292222e-1-4.1159030931141318362e-11i) (num-test (cosh -1.19209289550781250e-07-6.28353057416258753420e+00i) 9.9999994039536292222e-1+4.1159030931141318362e-11i) (num-test (cosh 1.19209289550781250e-07+9.42443269378637893396e+00i) -9.9999994039536292231e-1+4.1159030931108433883e-11i) (num-test (cosh 1.19209289550781250e-07-9.42443269378637893396e+00i) -9.9999994039536292231e-1-4.1159030931108433883e-11i) (num-test (cosh -1.19209289550781250e-07+9.42443269378637893396e+00i) -9.9999994039536292231e-1-4.1159030931108433883e-11i) (num-test (cosh -1.19209289550781250e-07-9.42443269378637893396e+00i) -9.9999994039536292231e-1+4.1159030931108433883e-11i) (num-test (cosh 1.19209289550781250e-07+9.42512322775237976202e+00i) -9.9999994039536292257e-1-4.1159030931020840323e-11i) (num-test (cosh 1.19209289550781250e-07-9.42512322775237976202e+00i) -9.9999994039536292257e-1+4.1159030931020840323e-11i) (num-test (cosh -1.19209289550781250e-07+9.42512322775237976202e+00i) -9.9999994039536292257e-1+4.1159030931020840323e-11i) (num-test (cosh -1.19209289550781250e-07-9.42512322775237976202e+00i) -9.9999994039536292257e-1-4.1159030931020840323e-11i) (num-test (cosh 5.0e-01-3.45266983001243932001e-04i) 1.1276258979946363573e0-1.7991700040930800151e-4i) (num-test (cosh 5.0e-01+3.45266983001243932001e-04i) 1.1276258979946363573e0+1.7991700040930800151e-4i) (num-test (cosh -5.0e-01-3.45266983001243932001e-04i) 1.1276258979946363573e0+1.7991700040930800151e-4i) (num-test (cosh -5.0e-01+3.45266983001243932001e-04i) 1.1276258979946363573e0-1.7991700040930800151e-4i) (num-test (cosh 5.0e-01+1.57045105981189525579e+00i) 3.8933200722547541227e-4+5.2109527443404709207e-1i) (num-test (cosh 5.0e-01-1.57045105981189525579e+00i) 3.8933200722547541227e-4-5.2109527443404709207e-1i) (num-test (cosh -5.0e-01+1.57045105981189525579e+00i) 3.8933200722547541227e-4-5.2109527443404709207e-1i) (num-test (cosh -5.0e-01-1.57045105981189525579e+00i) 3.8933200722547541227e-4+5.2109527443404709207e-1i) (num-test (cosh 5.0e-01+1.57114159377789786021e+00i) -3.8933200722533731792e-4+5.2109527443404709209e-1i) (num-test (cosh 5.0e-01-1.57114159377789786021e+00i) -3.8933200722533731792e-4-5.2109527443404709209e-1i) (num-test (cosh -5.0e-01+1.57114159377789786021e+00i) -3.8933200722533731792e-4-5.2109527443404709209e-1i) (num-test (cosh -5.0e-01-1.57114159377789786021e+00i) -3.8933200722533731792e-4+5.2109527443404709209e-1i) (num-test (cosh 5.0e-01+3.14124738660679181379e+00i) -1.1276258979946363572e0+1.7991700040940218455e-4i) (num-test (cosh 5.0e-01-3.14124738660679181379e+00i) -1.1276258979946363572e0-1.7991700040940218455e-4i) (num-test (cosh -5.0e-01+3.14124738660679181379e+00i) -1.1276258979946363572e0-1.7991700040940218455e-4i) (num-test (cosh -5.0e-01-3.14124738660679181379e+00i) -1.1276258979946363572e0+1.7991700040940218455e-4i) (num-test (cosh 5.0e-01+3.14193792057279441821e+00i) -1.1276258979946363573e0-1.7991700040927455302e-4i) (num-test (cosh 5.0e-01-3.14193792057279441821e+00i) -1.1276258979946363573e0+1.7991700040927455302e-4i) (num-test (cosh -5.0e-01+3.14193792057279441821e+00i) -1.1276258979946363573e0+1.7991700040927455302e-4i) (num-test (cosh -5.0e-01-3.14193792057279441821e+00i) -1.1276258979946363573e0-1.7991700040927455302e-4i) (num-test (cosh 5.0e-01+4.71204371340168837179e+00i) -3.8933200722561350661e-4-5.2109527443404709205e-1i) (num-test (cosh 5.0e-01-4.71204371340168837179e+00i) -3.8933200722561350661e-4+5.2109527443404709205e-1i) (num-test (cosh -5.0e-01+4.71204371340168837179e+00i) -3.8933200722561350661e-4+5.2109527443404709205e-1i) (num-test (cosh -5.0e-01-4.71204371340168837179e+00i) -3.8933200722561350661e-4-5.2109527443404709205e-1i) (num-test (cosh 5.0e-01+4.71273424736769097620e+00i) 3.8933200722519922358e-4-5.2109527443404709212e-1i) (num-test (cosh 5.0e-01-4.71273424736769097620e+00i) 3.8933200722519922358e-4+5.2109527443404709212e-1i) (num-test (cosh -5.0e-01+4.71273424736769097620e+00i) 3.8933200722519922358e-4+5.2109527443404709212e-1i) (num-test (cosh -5.0e-01-4.71273424736769097620e+00i) 3.8933200722519922358e-4-5.2109527443404709212e-1i) (num-test (cosh 5.0e-01+6.28284004019658492979e+00i) 1.1276258979946363572e0-1.7991700040946600032e-4i) (num-test (cosh 5.0e-01-6.28284004019658492979e+00i) 1.1276258979946363572e0+1.7991700040946600032e-4i) (num-test (cosh -5.0e-01+6.28284004019658492979e+00i) 1.1276258979946363572e0+1.7991700040946600032e-4i) (num-test (cosh -5.0e-01-6.28284004019658492979e+00i) 1.1276258979946363572e0-1.7991700040946600032e-4i) (num-test (cosh 5.0e-01+6.28353057416258753420e+00i) 1.1276258979946363574e0+1.7991700040921073725e-4i) (num-test (cosh 5.0e-01-6.28353057416258753420e+00i) 1.1276258979946363574e0-1.7991700040921073725e-4i) (num-test (cosh -5.0e-01+6.28353057416258753420e+00i) 1.1276258979946363574e0-1.7991700040921073725e-4i) (num-test (cosh -5.0e-01-6.28353057416258753420e+00i) 1.1276258979946363574e0+1.7991700040921073725e-4i) (num-test (cosh 5.0e-01+9.42443269378637893396e+00i) -1.1276258979946363575e0+1.7991700040906699050e-4i) (num-test (cosh 5.0e-01-9.42443269378637893396e+00i) -1.1276258979946363575e0-1.7991700040906699050e-4i) (num-test (cosh -5.0e-01+9.42443269378637893396e+00i) -1.1276258979946363575e0-1.7991700040906699050e-4i) (num-test (cosh -5.0e-01-9.42443269378637893396e+00i) -1.1276258979946363575e0+1.7991700040906699050e-4i) (num-test (cosh 5.0e-01+9.42512322775237976202e+00i) -1.1276258979946363577e0-1.7991700040868409591e-4i) (num-test (cosh 5.0e-01-9.42512322775237976202e+00i) -1.1276258979946363577e0+1.7991700040868409591e-4i) (num-test (cosh -5.0e-01+9.42512322775237976202e+00i) -1.1276258979946363577e0+1.7991700040868409591e-4i) (num-test (cosh -5.0e-01-9.42512322775237976202e+00i) -1.1276258979946363577e0-1.7991700040868409591e-4i) (num-test (cosh 1.0e+00-3.45266983001243932001e-04i) 1.5430805428404715942e0-4.057581624871654840e-4i) (num-test (cosh 1.0e+00+3.45266983001243932001e-04i) 1.5430805428404715942e0+4.057581624871654840e-4i) (num-test (cosh -1.0e+00-3.45266983001243932001e-04i) 1.5430805428404715942e0+4.057581624871654840e-4i) (num-test (cosh -1.0e+00+3.45266983001243932001e-04i) 1.5430805428404715942e0-4.057581624871654840e-4i) (num-test (cosh 1.0e+00+1.57045105981189525579e+00i) 5.3277478472520380315e-4+1.1752011235963524659e0i) (num-test (cosh 1.0e+00-1.57045105981189525579e+00i) 5.3277478472520380315e-4-1.1752011235963524659e0i) (num-test (cosh -1.0e+00+1.57045105981189525579e+00i) 5.3277478472520380315e-4-1.1752011235963524659e0i) (num-test (cosh -1.0e+00-1.57045105981189525579e+00i) 5.3277478472520380315e-4+1.1752011235963524659e0i) (num-test (cosh 1.0e+00+1.57114159377789786021e+00i) -5.3277478472501483029e-4+1.1752011235963524660e0i) (num-test (cosh 1.0e+00-1.57114159377789786021e+00i) -5.3277478472501483029e-4-1.1752011235963524660e0i) (num-test (cosh -1.0e+00+1.57114159377789786021e+00i) -5.3277478472501483029e-4-1.1752011235963524660e0i) (num-test (cosh -1.0e+00-1.57114159377789786021e+00i) -5.3277478472501483029e-4+1.1752011235963524660e0i) (num-test (cosh 1.0e+00+3.14124738660679181379e+00i) -1.5430805428404715941e0+4.0575816248737789049e-4i) (num-test (cosh 1.0e+00-3.14124738660679181379e+00i) -1.5430805428404715941e0-4.0575816248737789049e-4i) (num-test (cosh -1.0e+00+3.14124738660679181379e+00i) -1.5430805428404715941e0-4.0575816248737789049e-4i) (num-test (cosh -1.0e+00-3.14124738660679181379e+00i) -1.5430805428404715941e0+4.0575816248737789049e-4i) (num-test (cosh 1.0e+00+3.14193792057279441821e+00i) -1.5430805428404715943e0-4.0575816248709004923e-4i) (num-test (cosh 1.0e+00-3.14193792057279441821e+00i) -1.5430805428404715943e0+4.0575816248709004923e-4i) (num-test (cosh -1.0e+00+3.14193792057279441821e+00i) -1.5430805428404715943e0+4.0575816248709004923e-4i) (num-test (cosh -1.0e+00-3.14193792057279441821e+00i) -1.5430805428404715943e0-4.0575816248709004923e-4i) (num-test (cosh 1.0e+00+4.71204371340168837179e+00i) -5.3277478472539277601e-4-1.1752011235963524659e0i) (num-test (cosh 1.0e+00-4.71204371340168837179e+00i) -5.3277478472539277601e-4+1.1752011235963524659e0i) (num-test (cosh -1.0e+00+4.71204371340168837179e+00i) -5.3277478472539277601e-4+1.1752011235963524659e0i) (num-test (cosh -1.0e+00-4.71204371340168837179e+00i) -5.3277478472539277601e-4-1.1752011235963524659e0i) (num-test (cosh 1.0e+00+4.71273424736769097620e+00i) 5.3277478472482585742e-4-1.1752011235963524660e0i) (num-test (cosh 1.0e+00-4.71273424736769097620e+00i) 5.3277478472482585742e-4+1.1752011235963524660e0i) (num-test (cosh -1.0e+00+4.71273424736769097620e+00i) 5.3277478472482585742e-4+1.1752011235963524660e0i) (num-test (cosh -1.0e+00-4.71273424736769097620e+00i) 5.3277478472482585742e-4-1.1752011235963524660e0i) (num-test (cosh 1.0e+00+6.28284004019658492979e+00i) 1.5430805428404715941e0-4.0575816248752181112e-4i) (num-test (cosh 1.0e+00-6.28284004019658492979e+00i) 1.5430805428404715941e0+4.0575816248752181112e-4i) (num-test (cosh -1.0e+00+6.28284004019658492979e+00i) 1.5430805428404715941e0+4.0575816248752181112e-4i) (num-test (cosh -1.0e+00-6.28284004019658492979e+00i) 1.5430805428404715941e0-4.0575816248752181112e-4i) (num-test (cosh 1.0e+00+6.28353057416258753420e+00i) 1.5430805428404715943e0+4.0575816248694612861e-4i) (num-test (cosh 1.0e+00-6.28353057416258753420e+00i) 1.5430805428404715943e0-4.0575816248694612861e-4i) (num-test (cosh -1.0e+00+6.28353057416258753420e+00i) 1.5430805428404715943e0-4.0575816248694612861e-4i) (num-test (cosh -1.0e+00-6.28353057416258753420e+00i) 1.5430805428404715943e0+4.0575816248694612861e-4i) (num-test (cosh 1.0e+00+9.42443269378637893396e+00i) -1.5430805428404715945e0+4.0575816248662194348e-4i) (num-test (cosh 1.0e+00-9.42443269378637893396e+00i) -1.5430805428404715945e0-4.0575816248662194348e-4i) (num-test (cosh -1.0e+00+9.42443269378637893396e+00i) -1.5430805428404715945e0-4.0575816248662194348e-4i) (num-test (cosh -1.0e+00-9.42443269378637893396e+00i) -1.5430805428404715945e0+4.0575816248662194348e-4i) (num-test (cosh 1.0e+00+9.42512322775237976202e+00i) -1.5430805428404715949e0-4.0575816248575841970e-4i) (num-test (cosh 1.0e+00-9.42512322775237976202e+00i) -1.5430805428404715949e0+4.0575816248575841970e-4i) (num-test (cosh -1.0e+00+9.42512322775237976202e+00i) -1.5430805428404715949e0+4.0575816248575841970e-4i) (num-test (cosh -1.0e+00-9.42512322775237976202e+00i) -1.5430805428404715949e0-4.0575816248575841970e-4i) (num-test (cosh 2.0e+00-3.45266983001243932001e-04i) 3.7621954668392959447e0-1.2522351259043242989e-3i) (num-test (cosh 2.0e+00+3.45266983001243932001e-04i) 3.7621954668392959447e0+1.2522351259043242989e-3i) (num-test (cosh -2.0e+00-3.45266983001243932001e-04i) 3.7621954668392959447e0+1.2522351259043242989e-3i) (num-test (cosh -2.0e+00+3.45266983001243932001e-04i) 3.7621954668392959447e0-1.2522351259043242989e-3i) (num-test (cosh 2.0e+00+1.57045105981189525579e+00i) 1.2989619299131198016e-3+3.6268601916692946554e0i) (num-test (cosh 2.0e+00-1.57045105981189525579e+00i) 1.2989619299131198016e-3-3.6268601916692946554e0i) (num-test (cosh -2.0e+00+1.57045105981189525579e+00i) 1.2989619299131198016e-3-3.6268601916692946554e0i) (num-test (cosh -2.0e+00-1.57045105981189525579e+00i) 1.2989619299131198016e-3+3.6268601916692946554e0i) (num-test (cosh 2.0e+00+1.57114159377789786021e+00i) -1.2989619299126590655e-3+3.6268601916692946556e0i) (num-test (cosh 2.0e+00-1.57114159377789786021e+00i) -1.2989619299126590655e-3-3.6268601916692946556e0i) (num-test (cosh -2.0e+00+1.57114159377789786021e+00i) -1.2989619299126590655e-3-3.6268601916692946556e0i) (num-test (cosh -2.0e+00-1.57114159377789786021e+00i) -1.2989619299126590655e-3+3.6268601916692946556e0i) (num-test (cosh 2.0e+00+3.14124738660679181379e+00i) -3.7621954668392959444e0+1.2522351259049798196e-3i) (num-test (cosh 2.0e+00-3.14124738660679181379e+00i) -3.7621954668392959444e0-1.2522351259049798196e-3i) (num-test (cosh -2.0e+00+3.14124738660679181379e+00i) -3.7621954668392959444e0-1.2522351259049798196e-3i) (num-test (cosh -2.0e+00-3.14124738660679181379e+00i) -3.7621954668392959444e0+1.2522351259049798196e-3i) (num-test (cosh 2.0e+00+3.14193792057279441821e+00i) -3.7621954668392959448e0-1.2522351259040914950e-3i) (num-test (cosh 2.0e+00-3.14193792057279441821e+00i) -3.7621954668392959448e0+1.2522351259040914950e-3i) (num-test (cosh -2.0e+00+3.14193792057279441821e+00i) -3.7621954668392959448e0+1.2522351259040914950e-3i) (num-test (cosh -2.0e+00-3.14193792057279441821e+00i) -3.7621954668392959448e0-1.2522351259040914950e-3i) (num-test (cosh 2.0e+00+4.71204371340168837179e+00i) -1.2989619299135805376e-3-3.6268601916692946552e0i) (num-test (cosh 2.0e+00-4.71204371340168837179e+00i) -1.2989619299135805376e-3+3.6268601916692946552e0i) (num-test (cosh -2.0e+00+4.71204371340168837179e+00i) -1.2989619299135805376e-3+3.6268601916692946552e0i) (num-test (cosh -2.0e+00-4.71204371340168837179e+00i) -1.2989619299135805376e-3-3.6268601916692946552e0i) (num-test (cosh 2.0e+00+4.71273424736769097620e+00i) 1.2989619299121983294e-3-3.6268601916692946557e0i) (num-test (cosh 2.0e+00-4.71273424736769097620e+00i) 1.2989619299121983294e-3+3.6268601916692946557e0i) (num-test (cosh -2.0e+00+4.71273424736769097620e+00i) 1.2989619299121983294e-3+3.6268601916692946557e0i) (num-test (cosh -2.0e+00-4.71273424736769097620e+00i) 1.2989619299121983294e-3-3.6268601916692946557e0i) (num-test (cosh 2.0e+00+6.28284004019658492979e+00i) 3.7621954668392959443e0-1.2522351259054239819e-3i) (num-test (cosh 2.0e+00-6.28284004019658492979e+00i) 3.7621954668392959443e0+1.2522351259054239819e-3i) (num-test (cosh -2.0e+00+6.28284004019658492979e+00i) 3.7621954668392959443e0+1.2522351259054239819e-3i) (num-test (cosh -2.0e+00-6.28284004019658492979e+00i) 3.7621954668392959443e0-1.2522351259054239819e-3i) (num-test (cosh 2.0e+00+6.28353057416258753420e+00i) 3.7621954668392959449e0+1.2522351259036473328e-3i) (num-test (cosh 2.0e+00-6.28353057416258753420e+00i) 3.7621954668392959449e0-1.2522351259036473328e-3i) (num-test (cosh -2.0e+00+6.28353057416258753420e+00i) 3.7621954668392959449e0-1.2522351259036473328e-3i) (num-test (cosh -2.0e+00-6.28353057416258753420e+00i) 3.7621954668392959449e0+1.2522351259036473328e-3i) (num-test (cosh 2.0e+00+9.42443269378637893396e+00i) -3.7621954668392959453e0+1.2522351259026468452e-3i) (num-test (cosh 2.0e+00-9.42443269378637893396e+00i) -3.7621954668392959453e0-1.2522351259026468452e-3i) (num-test (cosh -2.0e+00+9.42443269378637893396e+00i) -3.7621954668392959453e0-1.2522351259026468452e-3i) (num-test (cosh -2.0e+00-9.42443269378637893396e+00i) -3.7621954668392959453e0+1.2522351259026468452e-3i) (num-test (cosh 2.0e+00+9.42512322775237976202e+00i) -3.7621954668392959462e0-1.2522351258999818715e-3i) (num-test (cosh 2.0e+00-9.42512322775237976202e+00i) -3.7621954668392959462e0+1.2522351258999818715e-3i) (num-test (cosh -2.0e+00+9.42512322775237976202e+00i) -3.7621954668392959462e0+1.2522351258999818715e-3i) (num-test (cosh -2.0e+00-9.42512322775237976202e+00i) -3.7621954668392959462e0-1.2522351258999818715e-3i) (num-test (cosh (log (/ (+ 1 (sqrt 5)) 2))) (/ (sqrt 5) 2)) (num-test (/ (+ (cos (/ 10)) (cosh (/ 10)) (* 2 (cos (/ (sqrt 2) 20)) (cosh (/ (sqrt 2) 20)))) 4) 1.0000000000002480) (num-test (cosh 0) 1.0) (num-test (cosh -2.225073858507201399999999999999999999996E-308) 1.000E0) (num-test (cosh 1.110223024625156799999999999999999999997E-16) 1.000000000000000000000000000000006162976E0) (for-each (lambda (num-and-val) (let ((num (car num-and-val)) (val (cadr num-and-val))) (num-test-1 'cosh num (cosh num) val))) (vector (list 0 1) (list 1 1.5430806348152) (list 2 3.7621956910836) (list 3 10.067661995778) (list -1 1.5430806348152) (list -2 3.7621956910836) (list -3 10.067661995778) (list 1/2 1.1276259652064) (list 1/3 1.0560718678299) (list -1/2 1.1276259652064) (list -1/3 1.0560718678299) (list 1/9223372036854775807 1.0) (list 0.0 1.0) (list 1.0 1.5430806348152) (list 2.0 3.7621956910836) (list -2.0 3.7621956910836) (list 1.000000000000000000000000000000000000002E-309 1.000E0) (list 0+1i 0.54030230586814) (list 0+2i -0.41614683654714) (list 0-1i 0.54030230586814) (list 1+1i 0.83373002513115+0.98889770576287i) (list 1-1i 0.83373002513115-0.98889770576287i) (list -1+1i 0.83373002513115-0.98889770576287i) (list -1-1i 0.83373002513115+0.98889770576287i) (list 0.1+0.1i 0.9999833333373+0.0099999888888898i) (list 1e-16+1e-16i 1+1e-32i) )) (if with-bignums (begin (let ((max-s-error 0.0) (max-s-error-case 0) (max-sh-error 0.0) (max-sh-error-case 0)) (do ((x 0.10000000000000000000000 (+ x 0.1000000000000000000000))) ((> x (* 2 pi))) (let ((s (sin x)) (sh (sinh x)) (c (cos x)) (ch (cosh x))) (let ((err (magnitude (- (+ (* s s) (* c c)) 1)))) (if (> err max-s-error) (begin (set! max-s-error err) (set! max-s-error-case x)))) (let ((err (magnitude (+ (- (* sh sh) (* ch ch)) 1)))) (if (> err max-sh-error) (begin (set! max-sh-error err) (set! max-sh-error-case x)))))) (if (> max-s-error 1e-35) (format-logged #t "s^2 + c^2 error: ~A at ~A~%" max-s-error max-s-error-case)) (if (> max-sh-error 1e-33) (format-logged #t "sh^2 + ch^2 error: ~A at ~A~%" max-sh-error max-sh-error-case))) (num-test (sinh 1000.0) 9.850355570085234969444396761216615626576E433) (num-test (cosh 1000.0) 9.850355570085234969444396761216615626576E433) )) (test (cosh) 'error) (test (cosh "hi") 'error) (test (cosh 1.0+23.0i 1.0+23.0i) 'error) (test (cosh 0 1) 'error) (num-test (cosh 1/9223372036854775807) 1.000000000000000000000000000000000000006E0) (for-each (lambda (arg) (test (cosh arg) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) ;;; -------------------------------------------------------------------------------- ;;; tanh ;;; -------------------------------------------------------------------------------- (num-test (tanh 0) 0.0) (num-test (tanh 1) 0.76159415595576) (num-test (tanh -1) -0.76159415595576) (num-test (tanh 2) 0.96402758007582) (num-test (tanh -2) -0.96402758007582) (num-test (tanh 3) 0.99505475368673) (num-test (tanh -3) -0.99505475368673) (num-test (tanh 10) 0.99999999587769) (num-test (tanh -10) -0.99999999587769) (num-test (tanh 0/1) 0.0) (num-test (tanh 0/2) 0.0) (num-test (tanh 0/3) 0.0) (num-test (tanh 0/10) 0.0) (num-test (tanh 0/1234) 0.0) (num-test (tanh 0/1234000000) 0.0) (num-test (tanh 0/500029) 0.0) (num-test (tanh 0/362880) 0.0) (num-test (tanh 1/1) 0.76159415595576) (num-test (tanh -1/1) -0.76159415595576) (num-test (tanh 1/2) 0.46211715726001) (num-test (tanh -1/2) -0.46211715726001) (num-test (tanh 1/3) 0.32151273753163) (num-test (tanh -1/3) -0.32151273753163) (num-test (tanh 1/10) 0.09966799462496) (num-test (tanh -1/10) -0.09966799462496) (num-test (tanh 1/1234) 0.00081037259408) (num-test (tanh -1/1234) -0.00081037259408) (num-test (tanh 1/1234000000) 0.00000000081037) (num-test (tanh -1/1234000000) -0.00000000081037) (num-test (tanh 1/500029) 0.00000199988401) (num-test (tanh -1/500029) -0.00000199988401) (num-test (tanh 1/362880) 0.00000275573192) (num-test (tanh -1/362880) -0.00000275573192) (num-test (tanh 2/1) 0.96402758007582) (num-test (tanh -2/1) -0.96402758007582) (num-test (tanh 2/2) 0.76159415595576) (num-test (tanh -2/2) -0.76159415595576) (num-test (tanh 2/3) 0.58278294534791) (num-test (tanh -2/3) -0.58278294534791) (num-test (tanh 2/10) 0.19737532022490) (num-test (tanh -2/10) -0.19737532022490) (num-test (tanh 2/1234) 0.00162074412382) (num-test (tanh -2/1234) -0.00162074412382) (num-test (tanh 2/1234000000) 0.00000000162075) (num-test (tanh -2/1234000000) -0.00000000162075) (num-test (tanh 2/500029) 0.00000399976801) (num-test (tanh -2/500029) -0.00000399976801) (num-test (tanh 2/362880) 0.00000551146384) (num-test (tanh -2/362880) -0.00000551146384) (num-test (tanh 3/1) 0.99505475368673) (num-test (tanh -3/1) -0.99505475368673) (num-test (tanh 3/2) 0.90514825364487) (num-test (tanh -3/2) -0.90514825364487) (num-test (tanh 3/3) 0.76159415595576) (num-test (tanh -3/3) -0.76159415595576) (num-test (tanh 3/10) 0.29131261245159) (num-test (tanh -3/10) -0.29131261245159) (num-test (tanh 3/1234) 0.00243111352486) (num-test (tanh -3/1234) -0.00243111352486) (num-test (tanh 3/1234000000) 0.00000000243112) (num-test (tanh -3/1234000000) -0.00000000243112) (num-test (tanh 3/500029) 0.00000599965202) (num-test (tanh -3/500029) -0.00000599965202) (num-test (tanh 3/362880) 0.00000826719577) (num-test (tanh -3/362880) -0.00000826719577) (num-test (tanh 10/1) 0.99999999587769) (num-test (tanh -10/1) -0.99999999587769) (num-test (tanh 10/2) 0.99990920426260) (num-test (tanh -10/2) -0.99990920426260) (num-test (tanh 10/3) 0.99745796747384) (num-test (tanh -10/3) -0.99745796747384) (num-test (tanh 10/10) 0.76159415595576) (num-test (tanh -10/10) -0.76159415595576) (num-test (tanh 10/1234) 0.00810355032772) (num-test (tanh -10/1234) -0.00810355032772) (num-test (tanh 10/1234000000) 0.00000000810373) (num-test (tanh -10/1234000000) -0.00000000810373) (num-test (tanh 10/500029) 0.00001999884006) (num-test (tanh -10/500029) -0.00001999884006) (num-test (tanh 10/362880) 0.00002755731922) (num-test (tanh -10/362880) -0.00002755731922) (num-test (tanh 1234/10) 1.0) (num-test (tanh -1234/10) -1.0) (num-test (tanh 1234/1234) 0.76159415595576) (num-test (tanh -1234/1234) -0.76159415595576) (num-test (tanh 1234/1234000000) 0.00000100000000) (num-test (tanh -1234/1234000000) -0.00000100000000) (num-test (tanh 1234/500029) 0.00246785185430) (num-test (tanh -1234/500029) -0.00246785185430) (num-test (tanh 1234/362880) 0.00340056008434) (num-test (tanh -1234/362880) -0.00340056008434) (num-test (tanh 1234000000/1234000000) 0.76159415595576) (num-test (tanh -1234000000/1234000000) -0.76159415595576) (num-test (tanh 500029/1234000000) 0.00040520986437) (num-test (tanh -500029/1234000000) -0.00040520986437) (num-test (tanh 500029/500029) 0.76159415595576) (num-test (tanh -500029/500029) -0.76159415595576) (num-test (tanh 500029/362880) 0.88049046571870) (num-test (tanh -500029/362880) -0.88049046571870) (num-test (tanh 362880/1234) 1.0) (num-test (tanh -362880/1234) -1.0) (num-test (tanh 362880/1234000000) 0.00029406806284) (num-test (tanh -362880/1234000000) -0.00029406806284) (num-test (tanh 362880/500029) 0.62043861844530) (num-test (tanh -362880/500029) -0.62043861844530) (num-test (tanh 362880/362880) 0.76159415595576) (num-test (tanh -362880/362880) -0.76159415595576) (num-test (tanh 0.0) 0.0) (num-test (tanh 0.00000001) 0.00000001) (num-test (tanh -0.00000001) -0.00000001) (num-test (tanh 1.0) 0.76159415595576) (num-test (tanh -1.0) -0.76159415595576) (num-test (tanh pi) 0.99627207622075) (num-test (tanh -3.14159265358979) -0.99627207622075) (num-test (tanh 2.71828182845905) 0.99132891580060) (num-test (tanh -2.71828182845905) -0.99132891580060) (num-test (tanh 0.0+0.0i) 0.0) (num-test (tanh -0.0+0.0i) 0.0) (num-test (tanh 0.0-0.0i) 0.0) (num-test (tanh -0.0-0.0i) 0.0) (num-test (tanh 0.0+0.00000001i) 0.0+0.00000001i) (num-test (tanh -0.0+0.00000001i) 0.0+0.00000001i) (num-test (tanh 0.0-0.00000001i) 0.0-0.00000001i) (num-test (tanh -0.0-0.00000001i) -0.0-0.00000001i) (num-test (tanh 0.0+1.0i) 0.0+1.55740772465490i) (num-test (tanh -0.0+1.0i) 0.0+1.55740772465490i) (num-test (tanh 0.0-1.0i) 0.0-1.55740772465490i) (num-test (tanh -0.0-1.0i) -0.0-1.55740772465490i) (num-test (tanh 0.00000001+0.0i) 0.00000001) (num-test (tanh -0.00000001+0.0i) -0.00000001) (num-test (tanh 0.00000001-0.0i) 0.00000001) (num-test (tanh -0.00000001-0.0i) -0.00000001) (num-test (tanh 0.00000001+0.00000001i) 0.00000001+0.00000001i) (num-test (tanh -0.00000001+0.00000001i) -0.00000001+0.00000001i) (num-test (tanh 0.00000001-0.00000001i) 0.00000001-0.00000001i) (num-test (tanh -0.00000001-0.00000001i) -0.00000001-0.00000001i) (num-test (tanh 0.00000001+1.0i) 0.00000003425519+1.55740772465490i) (num-test (tanh -0.00000001+1.0i) -0.00000003425519+1.55740772465490i) (num-test (tanh 0.00000001-1.0i) 0.00000003425519-1.55740772465490i) (num-test (tanh -0.00000001-1.0i) -0.00000003425519-1.55740772465490i) (num-test (tanh 1.0+0.0i) 0.76159415595576) (num-test (tanh -1.0+0.0i) -0.76159415595576) (num-test (tanh 1.0-0.0i) 0.76159415595576) (num-test (tanh -1.0-0.0i) -0.76159415595576) (num-test (tanh 1.0+0.00000001i) 0.76159415595576+0.00000000419974i) (num-test (tanh -1.0+0.00000001i) -0.76159415595576+0.00000000419974i) (num-test (tanh 1.0-0.00000001i) 0.76159415595576-0.00000000419974i) (num-test (tanh -1.0-0.00000001i) -0.76159415595576-0.00000000419974i) (num-test (tanh 1.0+1.0i) 1.08392332733869+0.27175258531951i) (num-test (tanh -1.0+1.0i) -1.08392332733869+0.27175258531951i) (num-test (tanh 1.0-1.0i) 1.08392332733869-0.27175258531951i) (num-test (tanh -1.0-1.0i) -1.08392332733869-0.27175258531951i) (num-test (tanh 3.14159265358979+0.0i) 0.99627207622075) (num-test (tanh -3.14159265358979+0.0i) -0.99627207622075) (num-test (tanh 3.14159265358979-0.0i) 0.99627207622075) (num-test (tanh -3.14159265358979-0.0i) -0.99627207622075) (num-test (tanh 3.14159265358979+0.00000001i) 0.99627207622075+0.00000000007442i) (num-test (tanh -3.14159265358979+0.00000001i) -0.99627207622075+0.00000000007442i) (num-test (tanh 3.14159265358979-0.00000001i) 0.99627207622075-0.00000000007442i) (num-test (tanh -3.14159265358979-0.00000001i) -0.99627207622075-0.00000000007442i) (num-test (tanh 3.14159265358979+1.0i) 1.00154968930275+0.00340139653674i) (num-test (tanh -3.14159265358979+1.0i) -1.00154968930275+0.00340139653674i) (num-test (tanh 3.14159265358979-1.0i) 1.00154968930275-0.00340139653674i) (num-test (tanh -3.14159265358979-1.0i) -1.00154968930275-0.00340139653674i) (num-test (tanh 2.71828182845905+0.0i) 0.99132891580060) (num-test (tanh -2.71828182845905+0.0i) -0.99132891580060) (num-test (tanh 2.71828182845905-0.0i) 0.99132891580060) (num-test (tanh -2.71828182845905-0.0i) -0.99132891580060) (num-test (tanh 2.71828182845905+0.00000001i) 0.99132891580060+0.00000000017267i) (num-test (tanh -2.71828182845905+0.00000001i) -0.99132891580060+0.00000000017267i) (num-test (tanh 2.71828182845905-0.00000001i) 0.99132891580060-0.00000000017267i) (num-test (tanh -2.71828182845905-0.00000001i) -0.99132891580060-0.00000000017267i) (num-test (tanh 2.71828182845905+1.0i) 1.00359921084211+0.00794757997665i) (num-test (tanh -2.71828182845905+1.0i) -1.00359921084211+0.00794757997665i) (num-test (tanh 2.71828182845905-1.0i) 1.00359921084211-0.00794757997665i) (num-test (tanh -2.71828182845905-1.0i) -1.00359921084211-0.00794757997665i) (num-test (tanh 1234/3) 1.0) (num-test (tanh 1234000000/3) 1.0) (num-test (tanh 1234000000/500029) 1.0) (num-test (tanh 1234000000/362880) 1.0) (num-test (tanh 500029/2) 1.0) (num-test (tanh 500029/3) 1.0) (num-test (tanh 500029/10) 1.0) (num-test (tanh 500029/1234) 1.0) (num-test (tanh 0.0+3.14159265358979i) 0.0+6.982889851335445E-15i) (num-test (tanh 0.0+2.71828182845905i) 0.0-0.4505495340698621i) (num-test (tanh 0.00000001+3.14159265358979i) 1.0e-8+6.982889851335444E-15i) (num-test (tanh 0.00000001+2.71828182845905i) 1.2029948826505699E-8-0.4505495340698621i) (num-test (tanh 0.00000001+1234.0i) 1.5681770497896427E-8-0.7537751984442328i) (num-test (tanh 0.00000001+1234000000.0i) 3.9600648244422054E-7-6.212941995900324i) (num-test (tanh 1.0+3.14159265358979i) +0.7615941559557649+2.932634567877868E-15i) (num-test (tanh 1.0+2.71828182845905i) .8196826057997404-0.1692870118766369i) (num-test (tanh 3.14159265358979+3.14159265358979i) +0.99627207622075+5.196631812627532E-17i) (num-test (tanh 3.14159265358979+2.71828182845905i) .9975247319761639-0.002790687681003331i) (num-test (tanh 3.14159265358979+1234.0i) .9989656315245496-0.003586791196867043i) (num-test (tanh 3.14159265358979+1234000000.0i) 1.003551866736695-0.001176098307980411i) (num-test (tanh 2.71828182845905+3.14159265358979i) +0.991328915800599+1.205734242765375E-16i) (num-test (tanh 2.71828182845905+2.71828182845905i) .9942257438545914-0.00648578276962794i) (num-test (tanh 2.71828182845905+1234.0i) .9975698313220817-0.008351965390936033i) (num-test (tanh 2.71828182845905+1234000000.0i) 1.008299558244272-0.002755390838840499i) (num-test (tanh 1234.0+0.00000001i) +1.0+8.077935669463161E-28i) (num-test (tanh 1234.0+3.14159265358979i) 1.0) (num-test (tanh 1234.0+2.71828182845905i) +1.0+2.710505431213761E-20i) (num-test (tanh 1234000000.0+0.00000001i) 1.0) (num-test (tanh 1234000000.0+3.14159265358979i) 1.0-7.703719777548943E-34i) (num-test (tanh 1234000000.0+2.71828182845905i) +1.0+2.710505431213761E-20i) (num-test (tanh 0.0e+00-3.45266983001243932001e-04i) 0-3.4526699672092183585e-4i) (num-test (tanh 0.0e+00+3.45266983001243932001e-04i) 0+3.4526699672092183585e-4i) (num-test (tanh 0.0e+00+1.57045105981189525579e+00i) 0+2.8963092606501007060e3i) (num-test (tanh 0.0e+00-1.57045105981189525579e+00i) 0-2.8963092606501007060e3i) (num-test (tanh 0.0e+00+1.57114159377789786021e+00i) 0-2.8963092606511280143e3i) (num-test (tanh 0.0e+00-1.57114159377789786021e+00i) 0+2.8963092606511280143e3i) (num-test (tanh 0.0e+00+3.14124738660679181379e+00i) 0-3.4526699672110257641e-4i) (num-test (tanh 0.0e+00-3.14124738660679181379e+00i) 0+3.4526699672110257641e-4i) (num-test (tanh 0.0e+00+3.14193792057279441821e+00i) 0+3.4526699672085764703e-4i) (num-test (tanh 0.0e+00-3.14193792057279441821e+00i) 0-3.4526699672085764703e-4i) (num-test (tanh 0.0e+00+4.71204371340168837179e+00i) 0+2.8963092606490733978e3i) (num-test (tanh 0.0e+00-4.71204371340168837179e+00i) 0-2.8963092606490733978e3i) (num-test (tanh 0.0e+00+4.71273424736769097620e+00i) 0-2.8963092606521553225e3i) (num-test (tanh 0.0e+00-4.71273424736769097620e+00i) 0+2.8963092606521553225e3i) (num-test (tanh 0.0e+00+6.28284004019658492979e+00i) 0-3.4526699672122504111e-4i) (num-test (tanh 0.0e+00-6.28284004019658492979e+00i) 0+3.4526699672122504111e-4i) (num-test (tanh 0.0e+00+6.28353057416258753420e+00i) 0+3.4526699672073518233e-4i) (num-test (tanh 0.0e+00-6.28353057416258753420e+00i) 0-3.4526699672073518233e-4i) (num-test (tanh 0.0e+00+9.42443269378637893396e+00i) 0-3.4526699672045932728e-4i) (num-test (tanh 0.0e+00-9.42443269378637893396e+00i) 0+3.4526699672045932728e-4i) (num-test (tanh 0.0e+00+9.42512322775237976202e+00i) 0+3.4526699671972453911e-4i) (num-test (tanh 0.0e+00-9.42512322775237976202e+00i) 0-3.4526699671972453911e-4i) (num-test (tanh 1.19209289550781250e-07-3.45266983001243932001e-04i) 1.1920930376163652989e-7-3.4526699672091692931e-4i) (num-test (tanh 1.19209289550781250e-07+3.45266983001243932001e-04i) 1.1920930376163652989e-7+3.4526699672091692931e-4i) (num-test (tanh -1.19209289550781250e-07-3.45266983001243932001e-04i) -1.1920930376163652989e-7-3.4526699672091692931e-4i) (num-test (tanh -1.19209289550781250e-07+3.45266983001243932001e-04i) -1.1920930376163652989e-7+3.4526699672091692931e-4i) (num-test (tanh 1.19209289550781250e-07+1.57045105981189525579e+00i) 9.9999992052646305569e-1+2.8963089153831588642e3i) (num-test (tanh 1.19209289550781250e-07-1.57045105981189525579e+00i) 9.9999992052646305569e-1-2.8963089153831588642e3i) (num-test (tanh -1.19209289550781250e-07+1.57045105981189525579e+00i) -9.9999992052646305569e-1+2.8963089153831588642e3i) (num-test (tanh -1.19209289550781250e-07-1.57045105981189525579e+00i) -9.9999992052646305569e-1-2.8963089153831588642e3i) (num-test (tanh 1.19209289550781250e-07+1.57114159377789786021e+00i) 9.9999992052717244672e-1-2.8963089153841861720e3i) (num-test (tanh 1.19209289550781250e-07-1.57114159377789786021e+00i) 9.9999992052717244672e-1+2.8963089153841861720e3i) (num-test (tanh -1.19209289550781250e-07+1.57114159377789786021e+00i) -9.9999992052717244672e-1-2.8963089153841861720e3i) (num-test (tanh -1.19209289550781250e-07-1.57114159377789786021e+00i) -9.9999992052717244672e-1+2.8963089153841861720e3i) (num-test (tanh 1.19209289550781250e-07+3.14124738660679181379e+00i) 1.1920930376163652991e-7-3.4526699672109766987e-4i) (num-test (tanh 1.19209289550781250e-07-3.14124738660679181379e+00i) 1.1920930376163652991e-7+3.4526699672109766987e-4i) (num-test (tanh -1.19209289550781250e-07+3.14124738660679181379e+00i) -1.1920930376163652991e-7-3.4526699672109766987e-4i) (num-test (tanh -1.19209289550781250e-07-3.14124738660679181379e+00i) -1.1920930376163652991e-7+3.4526699672109766987e-4i) (num-test (tanh 1.19209289550781250e-07+3.14193792057279441821e+00i) 1.1920930376163652989e-7+3.4526699672085274049e-4i) (num-test (tanh 1.19209289550781250e-07-3.14193792057279441821e+00i) 1.1920930376163652989e-7-3.4526699672085274049e-4i) (num-test (tanh -1.19209289550781250e-07+3.14193792057279441821e+00i) -1.1920930376163652989e-7+3.4526699672085274049e-4i) (num-test (tanh -1.19209289550781250e-07-3.14193792057279441821e+00i) -1.1920930376163652989e-7-3.4526699672085274049e-4i) (num-test (tanh 1.19209289550781250e-07+4.71204371340168837179e+00i) 9.9999992052575366466e-1+2.8963089153821315563e3i) (num-test (tanh 1.19209289550781250e-07-4.71204371340168837179e+00i) 9.9999992052575366466e-1-2.8963089153821315563e3i) (num-test (tanh -1.19209289550781250e-07+4.71204371340168837179e+00i) -9.9999992052575366466e-1+2.8963089153821315563e3i) (num-test (tanh -1.19209289550781250e-07-4.71204371340168837179e+00i) -9.9999992052575366466e-1-2.8963089153821315563e3i) (num-test (tanh 1.19209289550781250e-07+4.71273424736769097620e+00i) 9.9999992052788183776e-1-2.8963089153852134799e3i) (num-test (tanh 1.19209289550781250e-07-4.71273424736769097620e+00i) 9.9999992052788183776e-1+2.8963089153852134799e3i) (num-test (tanh -1.19209289550781250e-07+4.71273424736769097620e+00i) -9.9999992052788183776e-1-2.8963089153852134799e3i) (num-test (tanh -1.19209289550781250e-07-4.71273424736769097620e+00i) -9.9999992052788183776e-1+2.8963089153852134799e3i) (num-test (tanh 1.19209289550781250e-07+6.28284004019658492979e+00i) 1.1920930376163652992e-7-3.4526699672122013457e-4i) (num-test (tanh 1.19209289550781250e-07-6.28284004019658492979e+00i) 1.1920930376163652992e-7+3.4526699672122013457e-4i) (num-test (tanh -1.19209289550781250e-07+6.28284004019658492979e+00i) -1.1920930376163652992e-7-3.4526699672122013457e-4i) (num-test (tanh -1.19209289550781250e-07-6.28284004019658492979e+00i) -1.1920930376163652992e-7+3.4526699672122013457e-4i) (num-test (tanh 1.19209289550781250e-07+6.28353057416258753420e+00i) 1.1920930376163652988e-7+3.4526699672073027579e-4i) (num-test (tanh 1.19209289550781250e-07-6.28353057416258753420e+00i) 1.1920930376163652988e-7-3.4526699672073027579e-4i) (num-test (tanh -1.19209289550781250e-07+6.28353057416258753420e+00i) -1.1920930376163652988e-7+3.4526699672073027579e-4i) (num-test (tanh -1.19209289550781250e-07-6.28353057416258753420e+00i) -1.1920930376163652988e-7-3.4526699672073027579e-4i) (num-test (tanh 1.19209289550781250e-07+9.42443269378637893396e+00i) 1.1920930376163652985e-7-3.4526699672045442074e-4i) (num-test (tanh 1.19209289550781250e-07-9.42443269378637893396e+00i) 1.1920930376163652985e-7+3.4526699672045442074e-4i) (num-test (tanh -1.19209289550781250e-07+9.42443269378637893396e+00i) -1.1920930376163652985e-7-3.4526699672045442074e-4i) (num-test (tanh -1.19209289550781250e-07-9.42443269378637893396e+00i) -1.1920930376163652985e-7+3.4526699672045442074e-4i) (num-test (tanh 1.19209289550781250e-07+9.42512322775237976202e+00i) 1.1920930376163652979e-7+3.4526699671971963257e-4i) (num-test (tanh 1.19209289550781250e-07-9.42512322775237976202e+00i) 1.1920930376163652979e-7-3.4526699671971963257e-4i) (num-test (tanh -1.19209289550781250e-07+9.42512322775237976202e+00i) -1.1920930376163652979e-7+3.4526699671971963257e-4i) (num-test (tanh -1.19209289550781250e-07-9.42512322775237976202e+00i) -1.1920930376163652979e-7-3.4526699671971963257e-4i) (num-test (tanh 5.0e-01-3.45266983001243932001e-04i) 4.6211720058436229979e-1-2.7153443992655805934e-4i) (num-test (tanh 5.0e-01+3.45266983001243932001e-04i) 4.6211720058436229979e-1+2.7153443992655805934e-4i) (num-test (tanh -5.0e-01-3.45266983001243932001e-04i) -4.6211720058436229979e-1-2.7153443992655805934e-4i) (num-test (tanh -5.0e-01+3.45266983001243932001e-04i) -4.6211720058436229979e-1+2.7153443992655805934e-4i) (num-test (tanh 5.0e-01+1.57045105981189525579e+00i) 2.1639524637389325996e0+1.2715121175455623363e-3i) (num-test (tanh 5.0e-01-1.57045105981189525579e+00i) 2.1639524637389325996e0-1.2715121175455623363e-3i) (num-test (tanh -5.0e-01+1.57045105981189525579e+00i) -2.1639524637389325996e0+1.2715121175455623363e-3i) (num-test (tanh -5.0e-01-1.57045105981189525579e+00i) -2.1639524637389325996e0-1.2715121175455623363e-3i) (num-test (tanh 5.0e-01+1.57114159377789786021e+00i) 2.1639524637389326002e0-1.2715121175451113370e-3i) (num-test (tanh 5.0e-01-1.57114159377789786021e+00i) 2.1639524637389326002e0+1.2715121175451113370e-3i) (num-test (tanh -5.0e-01+1.57114159377789786021e+00i) -2.1639524637389326002e0-1.2715121175451113370e-3i) (num-test (tanh -5.0e-01-1.57114159377789786021e+00i) -2.1639524637389326002e0+1.2715121175451113370e-3i) (num-test (tanh 5.0e-01+3.14124738660679181379e+00i) 4.6211720058436229984e-1-2.7153443992670020234e-4i) (num-test (tanh 5.0e-01-3.14124738660679181379e+00i) 4.6211720058436229984e-1+2.7153443992670020234e-4i) (num-test (tanh -5.0e-01+3.14124738660679181379e+00i) -4.6211720058436229984e-1-2.7153443992670020234e-4i) (num-test (tanh -5.0e-01-3.14124738660679181379e+00i) -4.6211720058436229984e-1+2.7153443992670020234e-4i) (num-test (tanh 5.0e-01+3.14193792057279441821e+00i) 4.6211720058436229978e-1+2.7153443992650757820e-4i) (num-test (tanh 5.0e-01-3.14193792057279441821e+00i) 4.6211720058436229978e-1-2.7153443992650757820e-4i) (num-test (tanh -5.0e-01+3.14193792057279441821e+00i) -4.6211720058436229978e-1+2.7153443992650757820e-4i) (num-test (tanh -5.0e-01-3.14193792057279441821e+00i) -4.6211720058436229978e-1-2.7153443992650757820e-4i) (num-test (tanh 5.0e-01+4.71204371340168837179e+00i) 2.1639524637389325989e0+1.2715121175460133355e-3i) (num-test (tanh 5.0e-01-4.71204371340168837179e+00i) 2.1639524637389325989e0-1.2715121175460133355e-3i) (num-test (tanh -5.0e-01+4.71204371340168837179e+00i) -2.1639524637389325989e0+1.2715121175460133355e-3i) (num-test (tanh -5.0e-01-4.71204371340168837179e+00i) -2.1639524637389325989e0-1.2715121175460133355e-3i) (num-test (tanh 5.0e-01+4.71273424736769097620e+00i) 2.1639524637389326009e0-1.2715121175446603377e-3i) (num-test (tanh 5.0e-01-4.71273424736769097620e+00i) 2.1639524637389326009e0+1.2715121175446603377e-3i) (num-test (tanh -5.0e-01+4.71273424736769097620e+00i) -2.1639524637389326009e0-1.2715121175446603377e-3i) (num-test (tanh -5.0e-01-4.71273424736769097620e+00i) -2.1639524637389326009e0+1.2715121175446603377e-3i) (num-test (tanh 5.0e-01+6.28284004019658492979e+00i) 4.6211720058436229987e-1-2.7153443992679651442e-4i) (num-test (tanh 5.0e-01-6.28284004019658492979e+00i) 4.6211720058436229987e-1+2.7153443992679651442e-4i) (num-test (tanh -5.0e-01+6.28284004019658492979e+00i) -4.6211720058436229987e-1-2.7153443992679651442e-4i) (num-test (tanh -5.0e-01-6.28284004019658492979e+00i) -4.6211720058436229987e-1+2.7153443992679651442e-4i) (num-test (tanh 5.0e-01+6.28353057416258753420e+00i) 4.6211720058436229974e-1+2.7153443992641126612e-4i) (num-test (tanh 5.0e-01-6.28353057416258753420e+00i) 4.6211720058436229974e-1-2.7153443992641126612e-4i) (num-test (tanh -5.0e-01+6.28353057416258753420e+00i) -4.6211720058436229974e-1+2.7153443992641126612e-4i) (num-test (tanh -5.0e-01-6.28353057416258753420e+00i) -4.6211720058436229974e-1-2.7153443992641126612e-4i) (num-test (tanh 5.0e-01+9.42443269378637893396e+00i) 4.6211720058436229968e-1-2.7153443992619432056e-4i) (num-test (tanh 5.0e-01-9.42443269378637893396e+00i) 4.6211720058436229968e-1+2.7153443992619432056e-4i) (num-test (tanh -5.0e-01+9.42443269378637893396e+00i) -4.6211720058436229968e-1-2.7153443992619432056e-4i) (num-test (tanh -5.0e-01-9.42443269378637893396e+00i) -4.6211720058436229968e-1+2.7153443992619432056e-4i) (num-test (tanh 5.0e-01+9.42512322775237976202e+00i) 4.6211720058436229949e-1+2.7153443992561644811e-4i) (num-test (tanh 5.0e-01-9.42512322775237976202e+00i) 4.6211720058436229949e-1-2.7153443992561644811e-4i) (num-test (tanh -5.0e-01+9.42512322775237976202e+00i) -4.6211720058436229949e-1+2.7153443992561644811e-4i) (num-test (tanh -5.0e-01-9.42512322775237976202e+00i) -4.6211720058436229949e-1-2.7153443992561644811e-4i) (num-test (tanh 1.0e+00-3.45266983001243932001e-04i) 7.6159419408485704836e-1-1.4500326960274960880e-4i) (num-test (tanh 1.0e+00+3.45266983001243932001e-04i) 7.6159419408485704836e-1+1.4500326960274960880e-4i) (num-test (tanh -1.0e+00-3.45266983001243932001e-04i) -7.6159419408485704836e-1-1.4500326960274960880e-4i) (num-test (tanh -1.0e+00+3.45266983001243932001e-04i) -7.6159419408485704836e-1+1.4500326960274960880e-4i) (num-test (tanh 1.0e+00+1.57045105981189525579e+00i) 1.3130351721648674823e0+2.4999454374276273814e-4i) (num-test (tanh 1.0e+00-1.57045105981189525579e+00i) 1.3130351721648674823e0-2.4999454374276273814e-4i) (num-test (tanh -1.0e+00+1.57045105981189525579e+00i) -1.3130351721648674823e0+2.4999454374276273814e-4i) (num-test (tanh -1.0e+00-1.57045105981189525579e+00i) -1.3130351721648674823e0-2.4999454374276273814e-4i) (num-test (tanh 1.0e+00+1.57114159377789786021e+00i) 1.3130351721648674824e0-2.4999454374267406620e-4i) (num-test (tanh 1.0e+00-1.57114159377789786021e+00i) 1.3130351721648674824e0+2.4999454374267406620e-4i) (num-test (tanh -1.0e+00+1.57114159377789786021e+00i) -1.3130351721648674824e0-2.4999454374267406620e-4i) (num-test (tanh -1.0e+00-1.57114159377789786021e+00i) -1.3130351721648674824e0+2.4999454374267406620e-4i) (num-test (tanh 1.0e+00+3.14124738660679181379e+00i) 7.6159419408485704840e-1-1.4500326960282551519e-4i) (num-test (tanh 1.0e+00-3.14124738660679181379e+00i) 7.6159419408485704840e-1+1.4500326960282551519e-4i) (num-test (tanh -1.0e+00+3.14124738660679181379e+00i) -7.6159419408485704840e-1-1.4500326960282551519e-4i) (num-test (tanh -1.0e+00-3.14124738660679181379e+00i) -7.6159419408485704840e-1+1.4500326960282551519e-4i) (num-test (tanh 1.0e+00+3.14193792057279441821e+00i) 7.6159419408485704835e-1+1.4500326960272265115e-4i) (num-test (tanh 1.0e+00-3.14193792057279441821e+00i) 7.6159419408485704835e-1-1.4500326960272265115e-4i) (num-test (tanh -1.0e+00+3.14193792057279441821e+00i) -7.6159419408485704835e-1+1.4500326960272265115e-4i) (num-test (tanh -1.0e+00-3.14193792057279441821e+00i) -7.6159419408485704835e-1-1.4500326960272265115e-4i) (num-test (tanh 1.0e+00+4.71204371340168837179e+00i) 1.3130351721648674822e0+2.4999454374285141007e-4i) (num-test (tanh 1.0e+00-4.71204371340168837179e+00i) 1.3130351721648674822e0-2.4999454374285141007e-4i) (num-test (tanh -1.0e+00+4.71204371340168837179e+00i) -1.3130351721648674822e0+2.4999454374285141007e-4i) (num-test (tanh -1.0e+00-4.71204371340168837179e+00i) -1.3130351721648674822e0-2.4999454374285141007e-4i) (num-test (tanh 1.0e+00+4.71273424736769097620e+00i) 1.3130351721648674825e0-2.4999454374258539427e-4i) (num-test (tanh 1.0e+00-4.71273424736769097620e+00i) 1.3130351721648674825e0+2.4999454374258539427e-4i) (num-test (tanh -1.0e+00+4.71273424736769097620e+00i) -1.3130351721648674825e0-2.4999454374258539427e-4i) (num-test (tanh -1.0e+00-4.71273424736769097620e+00i) -1.3130351721648674825e0+2.4999454374258539427e-4i) (num-test (tanh 1.0e+00+6.28284004019658492979e+00i) 7.6159419408485704843e-1-1.4500326960287694721e-4i) (num-test (tanh 1.0e+00-6.28284004019658492979e+00i) 7.6159419408485704843e-1+1.4500326960287694721e-4i) (num-test (tanh -1.0e+00+6.28284004019658492979e+00i) -7.6159419408485704843e-1-1.4500326960287694721e-4i) (num-test (tanh -1.0e+00-6.28284004019658492979e+00i) -7.6159419408485704843e-1+1.4500326960287694721e-4i) (num-test (tanh 1.0e+00+6.28353057416258753420e+00i) 7.6159419408485704832e-1+1.4500326960267121913e-4i) (num-test (tanh 1.0e+00-6.28353057416258753420e+00i) 7.6159419408485704832e-1-1.4500326960267121913e-4i) (num-test (tanh -1.0e+00+6.28353057416258753420e+00i) -7.6159419408485704832e-1+1.4500326960267121913e-4i) (num-test (tanh -1.0e+00-6.28353057416258753420e+00i) -7.6159419408485704832e-1-1.4500326960267121913e-4i) (num-test (tanh 1.0e+00+9.42443269378637893396e+00i) 7.6159419408485704826e-1-1.4500326960255536711e-4i) (num-test (tanh 1.0e+00-9.42443269378637893396e+00i) 7.6159419408485704826e-1+1.4500326960255536711e-4i) (num-test (tanh -1.0e+00+9.42443269378637893396e+00i) -7.6159419408485704826e-1-1.4500326960255536711e-4i) (num-test (tanh -1.0e+00-9.42443269378637893396e+00i) -7.6159419408485704826e-1+1.4500326960255536711e-4i) (num-test (tanh 1.0e+00+9.42512322775237976202e+00i) 7.6159419408485704810e-1+1.450032696022467750e-4i) (num-test (tanh 1.0e+00-9.42512322775237976202e+00i) 7.6159419408485704810e-1-1.450032696022467750e-4i) (num-test (tanh -1.0e+00+9.42512322775237976202e+00i) -7.6159419408485704810e-1+1.450032696022467750e-4i) (num-test (tanh -1.0e+00-9.42512322775237976202e+00i) -7.6159419408485704810e-1-1.450032696022467750e-4i) (num-test (tanh 2.0e+00-3.45266983001243932001e-04i) 9.6402758819508310556e-1-2.4393395410435306874e-5i) (num-test (tanh 2.0e+00+3.45266983001243932001e-04i) 9.6402758819508310556e-1+2.4393395410435306874e-5i) (num-test (tanh -2.0e+00-3.45266983001243932001e-04i) -9.6402758819508310556e-1-2.4393395410435306874e-5i) (num-test (tanh -2.0e+00+3.45266983001243932001e-04i) -9.6402758819508310556e-1+2.4393395410435306874e-5i) (num-test (tanh 2.0e+00+1.57045105981189525579e+00i) 1.0373147113268752620e0+2.6247825506572821595e-5i) (num-test (tanh 2.0e+00-1.57045105981189525579e+00i) 1.0373147113268752620e0-2.6247825506572821595e-5i) (num-test (tanh -2.0e+00+1.57045105981189525579e+00i) -1.0373147113268752620e0+2.6247825506572821595e-5i) (num-test (tanh -2.0e+00-1.57045105981189525579e+00i) -1.0373147113268752620e0-2.6247825506572821595e-5i) (num-test (tanh 2.0e+00+1.57114159377789786021e+00i) 1.0373147113268752620e0-2.6247825506563511609e-5i) (num-test (tanh 2.0e+00-1.57114159377789786021e+00i) 1.0373147113268752620e0+2.6247825506563511609e-5i) (num-test (tanh -2.0e+00+1.57114159377789786021e+00i) -1.0373147113268752620e0-2.6247825506563511609e-5i) (num-test (tanh -2.0e+00-1.57114159377789786021e+00i) -1.0373147113268752620e0+2.6247825506563511609e-5i) (num-test (tanh 2.0e+00+3.14124738660679181379e+00i) 9.6402758819508310557e-1-2.4393395410448076340e-5i) (num-test (tanh 2.0e+00-3.14124738660679181379e+00i) 9.6402758819508310557e-1+2.4393395410448076340e-5i) (num-test (tanh -2.0e+00+3.14124738660679181379e+00i) -9.6402758819508310557e-1-2.4393395410448076340e-5i) (num-test (tanh -2.0e+00-3.14124738660679181379e+00i) -9.6402758819508310557e-1+2.4393395410448076340e-5i) (num-test (tanh 2.0e+00+3.14193792057279441821e+00i) 9.6402758819508310556e-1+2.4393395410430771882e-5i) (num-test (tanh 2.0e+00-3.14193792057279441821e+00i) 9.6402758819508310556e-1-2.4393395410430771882e-5i) (num-test (tanh -2.0e+00+3.14193792057279441821e+00i) -9.6402758819508310556e-1+2.4393395410430771882e-5i) (num-test (tanh -2.0e+00-3.14193792057279441821e+00i) -9.6402758819508310556e-1-2.4393395410430771882e-5i) (num-test (tanh 2.0e+00+4.71204371340168837179e+00i) 1.0373147113268752620e0+2.6247825506582131582e-5i) (num-test (tanh 2.0e+00-4.71204371340168837179e+00i) 1.0373147113268752620e0-2.6247825506582131582e-5i) (num-test (tanh -2.0e+00+4.71204371340168837179e+00i) -1.0373147113268752620e0+2.6247825506582131582e-5i) (num-test (tanh -2.0e+00-4.71204371340168837179e+00i) -1.0373147113268752620e0-2.6247825506582131582e-5i) (num-test (tanh 2.0e+00+4.71273424736769097620e+00i) 1.0373147113268752620e0-2.6247825506554201622e-5i) (num-test (tanh 2.0e+00-4.71273424736769097620e+00i) 1.0373147113268752620e0+2.6247825506554201622e-5i) (num-test (tanh -2.0e+00+4.71273424736769097620e+00i) -1.0373147113268752620e0-2.6247825506554201622e-5i) (num-test (tanh -2.0e+00-4.71273424736769097620e+00i) -1.0373147113268752620e0+2.6247825506554201622e-5i) (num-test (tanh 2.0e+00+6.28284004019658492979e+00i) 9.6402758819508310558e-1-2.4393395410456728569e-5i) (num-test (tanh 2.0e+00-6.28284004019658492979e+00i) 9.6402758819508310558e-1+2.4393395410456728569e-5i) (num-test (tanh -2.0e+00+6.28284004019658492979e+00i) -9.6402758819508310558e-1-2.4393395410456728569e-5i) (num-test (tanh -2.0e+00-6.28284004019658492979e+00i) -9.6402758819508310558e-1+2.4393395410456728569e-5i) (num-test (tanh 2.0e+00+6.28353057416258753420e+00i) 9.6402758819508310555e-1+2.4393395410422119654e-5i) (num-test (tanh 2.0e+00-6.28353057416258753420e+00i) 9.6402758819508310555e-1-2.4393395410422119654e-5i) (num-test (tanh -2.0e+00+6.28353057416258753420e+00i) -9.6402758819508310555e-1+2.4393395410422119654e-5i) (num-test (tanh -2.0e+00-6.28353057416258753420e+00i) -9.6402758819508310555e-1-2.4393395410422119654e-5i) (num-test (tanh 2.0e+00+9.42443269378637893396e+00i) 9.6402758819508310554e-1-2.4393395410402630273e-5i) (num-test (tanh 2.0e+00-9.42443269378637893396e+00i) 9.6402758819508310554e-1+2.4393395410402630273e-5i) (num-test (tanh -2.0e+00+9.42443269378637893396e+00i) -9.6402758819508310554e-1-2.4393395410402630273e-5i) (num-test (tanh -2.0e+00-9.42443269378637893396e+00i) -9.6402758819508310554e-1+2.4393395410402630273e-5i) (num-test (tanh 2.0e+00+9.42512322775237976202e+00i) 9.6402758819508310550e-1+2.439339541035071690e-5i) (num-test (tanh 2.0e+00-9.42512322775237976202e+00i) 9.6402758819508310550e-1-2.439339541035071690e-5i) (num-test (tanh -2.0e+00+9.42512322775237976202e+00i) -9.6402758819508310550e-1+2.439339541035071690e-5i) (num-test (tanh -2.0e+00-9.42512322775237976202e+00i) -9.6402758819508310550e-1-2.439339541035071690e-5i) (num-test (tanh 50) 1.0) (num-test (tanh -2.225073858507201399999999999999999999996E-308) -2.225073858507201399999999999999999999996E-308) (num-test (tanh 1.110223024625156799999999999999999999997E-16) 1.110223024625156799999999999999995438476E-16) (if (provided? 'dfls-exponents) (begin (num-test (tanh 1s13) 1s0) (num-test (tanh 1s3) 1s0) (num-test (tanh 1s2) 1s0) (num-test (tanh 1s1) 1s0) (num-test (tanh 1l0) 0.7615941559557648881L0) (num-test (tanh 1l1) 0.9999999958776927636L0) (num-test (tanh 1l100) 1L0) (num-test (tanh 1f10) 1f0) (num-test (tanh 1L-10) 1L-10) (num-test (tanh 1L-17) 1L-17) (num-test (tanh 1L-47) 1L-47))) (test (nan? (tanh 1/0)) #t) ;(test (nan? (tanh 1/0+i)) #t) ;(test (nan? (tanh 1/0+1/0i)) #t) (test (nan? (tanh 1+1/0i)) #t) (test (nan? (tanh 0+1/0i)) #t) ;(test (nan? (tanh 1/0+0i)) #t) (for-each (lambda (num-and-val) (let ((num (car num-and-val)) (val (cadr num-and-val))) (num-test-1 'tanh num (tanh num) val))) (vector (list 0 0) (list 1 0.76159415595576) (list 2 0.96402758007582) (list 3 0.99505475368673) (list -1 -0.76159415595576) (list -2 -0.96402758007582) (list -3 -0.99505475368673) (list 9223372036854775807 1.0) (list -9223372036854775808 -1.0) (list 1/2 0.46211715726001) (list 1/3 0.32151273753163) (list -1/2 -0.46211715726001) (list -1/3 -0.32151273753163) (list 1/9223372036854775807 1.0842021724855e-19) (list 0.0 0.0) (list 1.0 0.76159415595576) (list 2.0 0.96402758007582) (list -2.0 -0.96402758007582) (list 1.000000000000000000000000000000000000002E-309 1.000000000000000000000000000000000000002E-309) (list 1e+16 1.0) (list inf.0 1.0) (list -inf.0 -1.0) (list 0+1i 0+1.5574077246549i) (list 0+2i 0-2.1850398632615i) (list 0-1i 0-1.5574077246549i) (list 1+1i 1.0839233273387+0.27175258531951i) (list 1-1i 1.0839233273387-0.27175258531951i) (list -1+1i -1.0839233273387+0.27175258531951i) (list -1-1i -1.0839233273387-0.27175258531951i) (list 0.1+0.1i 0.10066129051146+0.099328043521656i) (list 1e+16+1e+16i 1.0) (list 1e-16+1e-16i 1e-16+1e-16i) )) (test (tanh) 'error) (test (tanh "hi") 'error) (test (tanh 1.0+23.0i 1.0+23.0i) 'error) (test (tanh 0 1) 'error) (for-each (lambda (arg) (test (tanh arg) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) ;;; -------------------------------------------------------------------------------- ;;; asinh ;;; -------------------------------------------------------------------------------- (num-test (asinh 0) 0.0) (num-test (asinh 1) 0.88137358701954) (num-test (asinh -1) -0.88137358701954) (num-test (asinh 2) 1.44363547517881) (num-test (asinh -2) -1.44363547517881) (num-test (asinh 3) 1.81844645923207) (num-test (asinh -3) -1.81844645923207) (num-test (asinh 10) 2.99822295029797) (num-test (asinh -10) -2.99822295029798) (num-test (asinh 1234) 7.81116354920125) (num-test (asinh -1234) -7.81116354896171) (num-test (asinh 1234000000) 21.62667394298955) (num-test (asinh 500029) 13.81556855628334) (num-test (asinh 362880) 13.49497466064331) (num-test (asinh 0/1) 0.0) (num-test (asinh 0/2) 0.0) (num-test (asinh 0/3) 0.0) (num-test (asinh 0/10) 0.0) (num-test (asinh 0/1234) 0.0) (num-test (asinh 0/1234000000) 0.0) (num-test (asinh 0/500029) 0.0) (num-test (asinh 0/362880) 0.0) (num-test (asinh 1/1) 0.88137358701954) (num-test (asinh -1/1) -0.88137358701954) (num-test (asinh 1/2) 0.48121182505960) (num-test (asinh -1/2) -0.48121182505960) (num-test (asinh 1/3) 0.32745015023726) (num-test (asinh -1/3) -0.32745015023726) (num-test (asinh 1/10) 0.09983407889921) (num-test (asinh -1/10) -0.09983407889921) (num-test (asinh 1/1234) 0.00081037268278) (num-test (asinh -1/1234) -0.00081037268278) (num-test (asinh 1/1234000000) 0.00000000081037) (num-test (asinh -1/1234000000) -0.00000000081037) (num-test (asinh 1/500029) 0.00000199988401) (num-test (asinh -1/500029) -0.00000199988401) (num-test (asinh 1/362880) 0.00000275573192) (num-test (asinh -1/362880) -0.00000275573192) (num-test (asinh 2/1) 1.44363547517881) (num-test (asinh -2/1) -1.44363547517881) (num-test (asinh 2/2) 0.88137358701954) (num-test (asinh -2/2) -0.88137358701954) (num-test (asinh 2/3) 0.62514511725042) (num-test (asinh -2/3) -0.62514511725042) (num-test (asinh 2/10) 0.19869011034924) (num-test (asinh -2/10) -0.19869011034924) (num-test (asinh 2/1234) 0.00162074483338) (num-test (asinh -2/1234) -0.00162074483338) (num-test (asinh 2/1234000000) 0.00000000162075) (num-test (asinh -2/1234000000) -0.00000000162075) (num-test (asinh 2/500029) 0.00000399976801) (num-test (asinh -2/500029) -0.00000399976801) (num-test (asinh 2/362880) 0.00000551146384) (num-test (asinh -2/362880) -0.00000551146384) (num-test (asinh 3/1) 1.81844645923207) (num-test (asinh -3/1) -1.81844645923207) (num-test (asinh 3/2) 1.19476321728711) (num-test (asinh -3/2) -1.19476321728711) (num-test (asinh 3/3) 0.88137358701954) (num-test (asinh -3/3) -0.88137358701954) (num-test (asinh 3/10) 0.29567304756342) (num-test (asinh -3/10) -0.29567304756342) (num-test (asinh 3/1234) 0.00243111591964) (num-test (asinh -3/1234) -0.00243111591964) (num-test (asinh 3/1234000000) 0.00000000243112) (num-test (asinh -3/1234000000) -0.00000000243112) (num-test (asinh 3/500029) 0.00000599965202) (num-test (asinh -3/500029) -0.00000599965202) (num-test (asinh 3/362880) 0.00000826719577) (num-test (asinh -3/362880) -0.00000826719577) (num-test (asinh 10/1) 2.99822295029797) (num-test (asinh -10/1) -2.99822295029798) (num-test (asinh 10/2) 2.31243834127275) (num-test (asinh -10/2) -2.31243834127276) (num-test (asinh 10/3) 1.91889647209853) (num-test (asinh -10/3) -1.91889647209853) (num-test (asinh 10/10) 0.88137358701954) (num-test (asinh -10/10) -0.88137358701954) (num-test (asinh 10/1234) 0.00810363902153) (num-test (asinh -10/1234) -0.00810363902153) (num-test (asinh 10/1234000000) 0.00000000810373) (num-test (asinh -10/1234000000) -0.00000000810373) (num-test (asinh 10/500029) 0.00001999884007) (num-test (asinh -10/500029) -0.00001999884007) (num-test (asinh 10/362880) 0.00002755731922) (num-test (asinh -10/362880) -0.00002755731922) (num-test (asinh 1234/1) 7.81116354920125) (num-test (asinh -1234/1) -7.81116354896171) (num-test (asinh 1234/2) 7.11801686116871) (num-test (asinh -1234/2) -7.11801686109890) (num-test (asinh 1234/3) 6.71255257393796) (num-test (asinh -1234/3) -6.71255257391934) (num-test (asinh 1234/10) 5.50859470922766) (num-test (asinh -1234/10) -5.50859470922637) (num-test (asinh 1234/1234) 0.88137358701954) (num-test (asinh -1234/1234) -0.88137358701954) (num-test (asinh 1234/1234000000) 0.00000100000000) (num-test (asinh -1234/1234000000) -0.00000100000000) (num-test (asinh 1234/500029) 0.00246785435930) (num-test (asinh -1234/500029) -0.00246785435930) (num-test (asinh 1234/362880) 0.00340056663829) (num-test (asinh -1234/362880) -0.00340056663829) (num-test (asinh 1234000000/1) 21.62667394298955) (num-test (asinh 1234000000/2) 20.93352676242961) (num-test (asinh 1234000000/3) 20.52806165432144) (num-test (asinh 1234000000/10) 19.32408884999551) (num-test (asinh 1234000000/1234) 14.50865773852447) (num-test (asinh 1234000000/1234000000) 0.88137358701954) (num-test (asinh -1234000000/1234000000) -0.88137358701954) (num-test (asinh 1234000000/500029) 8.50425260831592) (num-test (asinh -1234000000/500029) -8.50425260755399) (num-test (asinh 1234000000/362880) 8.82484648452709) (num-test (asinh -1234000000/362880) -8.82484648383427) (num-test (asinh 500029/1) 13.81556855628334) (num-test (asinh 500029/2) 13.12242137572639) (num-test (asinh 500029/3) 12.71695626762323) (num-test (asinh -500029/3) -12.71695626762323) (num-test (asinh 500029/10) 11.51298346338828) (num-test (asinh -500029/10) -11.51298333576987) (num-test (asinh 500029/1234) 6.69755387439290) (num-test (asinh -500029/1234) -6.69755387437470) (num-test (asinh 500029/1234000000) 0.00040520987546) (num-test (asinh -500029/1234000000) -0.00040520987546) (num-test (asinh 500029/500029) 0.88137358701954) (num-test (asinh -500029/500029) -0.88137358701954) (num-test (asinh 500029/362880) 1.12509614482188) (num-test (asinh -500029/362880) -1.12509614482188) (num-test (asinh 362880/1) 13.49497466064331) (num-test (asinh 362880/2) 12.80182748008906) (num-test (asinh -362880/2) -12.80182748008906) (num-test (asinh 362880/3) 12.39636237199039) (num-test (asinh -362880/3) -12.39636125811213) (num-test (asinh 362880/10) 11.19238956783722) (num-test (asinh -362880/10) -11.19238933388543) (num-test (asinh 362880/1234) 6.37696134713805) (num-test (asinh -362880/1234) -6.37696134714268) (num-test (asinh 362880/1234000000) 0.00029406806707) (num-test (asinh -362880/1234000000) -0.00029406806707) (num-test (asinh 362880/500029) 0.67360821551802) (num-test (asinh -362880/500029) -0.67360821551802) (num-test (asinh 362880/362880) 0.88137358701954) (num-test (asinh -362880/362880) -0.88137358701954) (num-test (asinh 0.0) 0.0) (num-test (asinh 0.00000001) 0.00000001) (num-test (asinh -0.00000001) -0.00000001) (num-test (asinh 1.0) 0.88137358701954) (num-test (asinh -1.0) -0.88137358701954) (num-test (asinh pi) 1.86229574331085) (num-test (asinh -3.14159265358979) -1.86229574331085) (num-test (asinh 2.71828182845905) 1.72538255885231) (num-test (asinh -2.71828182845905) -1.72538255885232) (num-test (asinh 1234.0) 7.81116354920125) (num-test (asinh -1234.0) -7.81116354896171) (num-test (asinh 1234000000.0) 21.62667394298955) (num-test (asinh 0.0+0.0i) 0.0) (num-test (asinh -0.0+0.0i) 0.0) (num-test (asinh 0.0-0.0i) 0.0) (num-test (asinh -0.0-0.0i) 0.0) (num-test (asinh 0.0+0.00000001i) 0.0+0.00000001i) (num-test (asinh -0.0+0.00000001i) 0.0+0.00000001i) (num-test (asinh 0.0-0.00000001i) 0.0-0.00000001i) (num-test (asinh -0.0-0.00000001i) 0.0-0.00000001i) (num-test (asinh 0.0+1.0i) 0.0+1.57079632679490i) (num-test (asinh -0.0+1.0i) 0.0+1.57079632679490i) (num-test (asinh 0.0-1.0i) 0.0-1.57079632679490i) (num-test (asinh -0.0-1.0i) 0.0-1.57079632679490i) (num-test (asinh 0.0+3.14159265358979i) 1.81152627246085+1.57079632679490i) (num-test (asinh -0.0+3.14159265358979i) 1.81152627246085+1.57079632679490i) (num-test (asinh 0.0-3.14159265358979i) 1.81152627246085-1.57079632679490i) (num-test (asinh -0.0-3.14159265358979i) -1.81152627246085-1.57079632679490i) (num-test (asinh 0.0+2.71828182845905i) 1.65745445415308+1.57079632679490i) (num-test (asinh -0.0+2.71828182845905i) 1.65745445415308+1.57079632679490i) (num-test (asinh 0.0-2.71828182845905i) 1.65745445415308-1.57079632679490i) (num-test (asinh -0.0-2.71828182845905i) -1.65745445415308-1.57079632679490i) (num-test (asinh 0.0+1234.0i) 7.81116322084923+1.57079632679490i) (num-test (asinh -0.0+1234.0i) 7.81116322084923+1.57079632679490i) (num-test (asinh 0.0-1234.0i) 7.81116322084923-1.57079632679490i) (num-test (asinh -0.0-1234.0i) -7.81116322068415-1.57079632679490i) (num-test (asinh 0.0+1234000000.0i) 21.62667394298955+1.57079632679490i) (num-test (asinh -0.0+1234000000.0i) 21.62667394298955+1.57079632679490i) (num-test (asinh 0.0-1234000000.0i) 21.62667394298955-1.57079632679490i) (num-test (asinh 0.00000001+0.0i) 0.00000001) (num-test (asinh -0.00000001+0.0i) -0.00000001) (num-test (asinh 0.00000001-0.0i) 0.00000001) (num-test (asinh -0.00000001-0.0i) -0.00000001) (num-test (asinh 0.00000001+0.00000001i) 0.00000001+0.00000001i) (num-test (asinh -0.00000001+0.00000001i) -0.00000001+0.00000001i) (num-test (asinh 0.00000001-0.00000001i) 0.00000001-0.00000001i) (num-test (asinh -0.00000001-0.00000001i) -0.00000001-0.00000001i) (num-test (asinh 0.00000001+1.0i) 0.00010000000008+1.57069632679498i) (num-test (asinh -0.00000001+1.0i) -0.00010000000008+1.57069632679498i) (num-test (asinh 0.00000001-1.0i) 0.00010000000008-1.57069632679498i) (num-test (asinh -0.00000001-1.0i) -0.00010000000008-1.57069632679498i) (num-test (asinh 0.00000001+3.14159265358979i) 1.81152627246085+1.57079632343715i) (num-test (asinh -0.00000001+3.14159265358979i) -1.81152627246085+1.57079632343715i) (num-test (asinh 0.00000001-3.14159265358979i) 1.81152627246085-1.57079632343715i) (num-test (asinh -0.00000001-3.14159265358979i) -1.81152627246085-1.57079632343715i) (num-test (asinh 0.00000001+2.71828182845905i) 1.65745445415308+1.57079632283867i) (num-test (asinh -0.00000001+2.71828182845905i) -1.65745445415308+1.57079632283867i) (num-test (asinh 0.00000001-2.71828182845905i) 1.65745445415308-1.57079632283867i) (num-test (asinh -0.00000001-2.71828182845905i) -1.65745445415308-1.57079632283867i) (num-test (asinh 0.00000001+1234.0i) 7.81116322084923+1.57079632678679i) (num-test (asinh -0.00000001+1234.0i) -7.81116322068415+1.57079632678679i) (num-test (asinh 0.00000001-1234.0i) 7.81116322084923-1.57079632678679i) (num-test (asinh -0.00000001-1234.0i) -7.81116322068415-1.57079632678679i) (num-test (asinh 0.00000001+1234000000.0i) 21.62667394298955+1.57079632679490i) (num-test (asinh 0.00000001-1234000000.0i) 21.62667394298955-1.57079632679490i) (num-test (asinh 1.0+0.0i) 0.88137358701954) (num-test (asinh -1.0+0.0i) -0.88137358701954) (num-test (asinh 1.0-0.0i) 0.88137358701954) (num-test (asinh -1.0-0.0i) -0.88137358701954) (num-test (asinh 1.0+0.00000001i) 0.88137358701954+0.00000000707107i) (num-test (asinh -1.0+0.00000001i) -0.88137358701954+0.00000000707107i) (num-test (asinh 1.0-0.00000001i) 0.88137358701954-0.00000000707107i) (num-test (asinh -1.0-0.00000001i) -0.88137358701954-0.00000000707107i) (num-test (asinh 1.0+1.0i) 1.06127506190504+0.66623943249252i) (num-test (asinh -1.0+1.0i) -1.06127506190504+0.66623943249252i) (num-test (asinh 1.0-1.0i) 1.06127506190504-0.66623943249252i) (num-test (asinh -1.0-1.0i) -1.06127506190504-0.66623943249252i) (num-test (asinh 1.0+3.14159265358979i) 1.86711439316026+1.24854303281344i) (num-test (asinh -1.0+3.14159265358979i) -1.86711439316026+1.24854303281344i) (num-test (asinh 1.0-3.14159265358979i) 1.86711439316026-1.24854303281344i) (num-test (asinh -1.0-3.14159265358979i) -1.86711439316026-1.24854303281344i) (num-test (asinh 1.0+2.71828182845905i) 1.73375471569385+1.19757808518581i) (num-test (asinh -1.0+2.71828182845905i) -1.73375471569385+1.19757808518581i) (num-test (asinh 1.0-2.71828182845905i) 1.73375471569385-1.19757808518581i) (num-test (asinh -1.0-2.71828182845905i) -1.73375471569385-1.19757808518581i) (num-test (asinh 1.0+1234.0i) 7.81116354920146+1.56998595393473i) (num-test (asinh -1.0+1234.0i) -7.81116354944842+1.56998595393442i) (num-test (asinh 1.0-1234.0i) 7.81116354920146-1.56998595393473i) (num-test (asinh -1.0-1234.0i) -7.81116354944842-1.56998595393442i) (num-test (asinh 1.0+1234000000.0i) 21.62667394298955+1.57079632598452i) (num-test (asinh 1.0-1234000000.0i) 21.62667394298955-1.57079632598452i) (num-test (asinh 3.14159265358979+0.0i) 1.86229574331085) (num-test (asinh -3.14159265358979+0.0i) -1.86229574331085) (num-test (asinh 3.14159265358979-0.0i) 1.86229574331085) (num-test (asinh -3.14159265358979-0.0i) -1.86229574331085) (num-test (asinh 3.14159265358979+0.00000001i) 1.86229574331085+0.00000000303314i) (num-test (asinh -3.14159265358979+0.00000001i) -1.86229574331085+0.00000000303314i) (num-test (asinh 3.14159265358979-0.00000001i) 1.86229574331085-0.00000000303314i) (num-test (asinh -3.14159265358979-0.00000001i) -1.86229574331085-0.00000000303314i) (num-test (asinh 3.14159265358979+1.0i) 1.90462768697066+0.29558503421163i) (num-test (asinh -3.14159265358979+1.0i) -1.90462768697066+0.29558503421163i) (num-test (asinh 3.14159265358979-1.0i) 1.90462768697066-0.29558503421163i) (num-test (asinh -3.14159265358979-1.0i) -1.90462768697066-0.29558503421163i) (num-test (asinh 3.14159265358979+3.14159265358979i) 2.18469104082751+0.77273977912748i) (num-test (asinh -3.14159265358979+3.14159265358979i) -2.18469104082751+0.77273977912748i) (num-test (asinh 3.14159265358979-3.14159265358979i) 2.18469104082751-0.77273977912748i) (num-test (asinh -3.14159265358979-3.14159265358979i) -2.18469104082751-0.77273977912748i) (num-test (asinh 3.14159265358979+2.71828182845905i) 2.11968336368048+0.69904796994655i) (num-test (asinh -3.14159265358979+2.71828182845905i) -2.11968336368048+0.69904796994656i) (num-test (asinh 3.14159265358979-2.71828182845905i) 2.11968336368048-0.69904796994655i) (num-test (asinh -3.14159265358979-2.71828182845905i) -2.11968336368048-0.69904796994656i) (num-test (asinh 3.14159265358979+1234.0i) 7.81116646154641+1.56825047031367i) (num-test (asinh -3.14159265358979+1234.0i) -7.81116646138554+1.56825047031506i) (num-test (asinh 3.14159265358979-1234.0i) 7.81116646154641-1.56825047031367i) (num-test (asinh -3.14159265358979-1234.0i) -7.81116646138554-1.56825047031506i) (num-test (asinh 3.14159265358979+1234000000.0i) 21.62667394298955+1.57079632424904i) (num-test (asinh 3.14159265358979-1234000000.0i) 21.62667394298955-1.57079632424904i) (num-test (asinh 2.71828182845905+0.0i) 1.72538255885231) (num-test (asinh -2.71828182845905+0.0i) -1.72538255885232) (num-test (asinh 2.71828182845905-0.0i) 1.72538255885231) (num-test (asinh -2.71828182845905-0.0i) -1.72538255885232) (num-test (asinh 2.71828182845905+0.00000001i) 1.72538255885231+0.00000000345258i) (num-test (asinh -2.71828182845905+0.00000001i) -1.72538255885232+0.00000000345258i) (num-test (asinh 2.71828182845905-0.00000001i) 1.72538255885231-0.00000000345258i) (num-test (asinh -2.71828182845905-0.00000001i) -1.72538255885232-0.00000000345258i) (num-test (asinh 2.71828182845905+1.0i) 1.77905438385935+0.33444277187637i) (num-test (asinh -2.71828182845905+1.0i) -1.77905438385935+0.33444277187637i) (num-test (asinh 2.71828182845905-1.0i) 1.77905438385935-0.33444277187637i) (num-test (asinh -2.71828182845905-1.0i) -1.77905438385935-0.33444277187637i) (num-test (asinh 2.71828182845905+3.14159265358979i) 2.11552790803290+0.84309656416035i) (num-test (asinh -2.71828182845905+3.14159265358979i) -2.11552790803290+0.84309656416035i) (num-test (asinh 2.71828182845905-3.14159265358979i) 2.11552790803290-0.84309656416035i) (num-test (asinh -2.71828182845905-3.14159265358979i) -2.11552790803290-0.84309656416035i) (num-test (asinh 2.71828182845905+2.71828182845905i) 2.04014932880026+0.76849735588475i) (num-test (asinh -2.71828182845905+2.71828182845905i) -2.04014932880026+0.76849735588475i) (num-test (asinh 2.71828182845905-2.71828182845905i) 2.04014932880026-0.76849735588475i) (num-test (asinh -2.71828182845905-2.71828182845905i) -2.04014932880026-0.76849735588475i) (num-test (asinh 2.71828182845905+1234.0i) 7.81116564705719+1.56859350805562i) (num-test (asinh -2.71828182845905+1234.0i) -7.81116564738434+1.56859350805543i) (num-test (asinh 2.71828182845905-1234.0i) 7.81116564705719-1.56859350805562i) (num-test (asinh -2.71828182845905-1234.0i) -7.81116564738434-1.56859350805543i) (num-test (asinh 2.71828182845905+1234000000.0i) 21.62667394298955+1.57079632459208i) (num-test (asinh 2.71828182845905-1234000000.0i) 21.62667394298955-1.57079632459208i) (num-test (asinh 1234.0+0.0i) 7.81116354920125) (num-test (asinh -1234.0+0.0i) -7.81116354896171) (num-test (asinh 1234.0-0.0i) 7.81116354920125) (num-test (asinh -1234.0-0.0i) -7.81116354896171) (num-test (asinh 1234.0+0.00000001i) 7.81116354920125+0.00000000000810i) (num-test (asinh -1234.0+0.00000001i) -7.81116354896171+0.00000000000810i) (num-test (asinh 1234.0-0.00000001i) 7.81116354920125-0.00000000000810i) (num-test (asinh -1234.0-0.00000001i) -7.81116354896171-0.00000000000810i) (num-test (asinh 1234.0+1.0i) 7.81116387755283+0.00081037232800i) (num-test (asinh -1234.0+1.0i) -7.81116387772663+0.00081037232806i) (num-test (asinh 1234.0-1.0i) 7.81116387755283-0.00081037232800i) (num-test (asinh -1234.0-1.0i) -7.81116387772663-0.00081037232806i) (num-test (asinh 1234.0+3.14159265358979i) 7.81116678989204+0.00254585480937i) (num-test (asinh -1234.0+3.14159265358979i) -7.81116678966949+0.00254585480900i) (num-test (asinh 1234.0-3.14159265358979i) 7.81116678989204-0.00254585480937i) (num-test (asinh -1234.0-3.14159265358979i) -7.81116678966949-0.00254585480900i) (num-test (asinh 1234.0+2.71828182845905i) 7.81116597540442+0.00220281729269i) (num-test (asinh -1234.0+2.71828182845905i) -7.81116597510553+0.00220281729236i) (num-test (asinh 1234.0-2.71828182845905i) 7.81116597540442-0.00220281729269i) (num-test (asinh -1234.0-2.71828182845905i) -7.81116597510553-0.00220281729236i) (num-test (asinh 1234.0+1234.0i) 8.15773697530526+0.78539808130944i) (num-test (asinh -1234.0+1234.0i) -8.15773697538346+0.78539808146835i) (num-test (asinh 1234.0-1234.0i) 8.15773697530526-0.78539808130944i) (num-test (asinh -1234.0-1234.0i) -8.15773697538346-0.78539808146835i) (num-test (asinh 1234.0+1234000000.0i) 21.62667394299005+1.57079532679490i) (num-test (asinh 1234.0-1234000000.0i) 21.62667394299005-1.57079532679490i) (num-test (asinh 1234000000.0+0.0i) 21.62667394298955) (num-test (asinh 1234000000.0-0.0i) 21.62667394298955) (num-test (asinh 1234000000.0+0.00000001i) 21.62667394298955+0.0i) (num-test (asinh 1234000000.0-0.00000001i) 21.62667394298955-0.0i) (num-test (asinh 1234000000.0+1.0i) 21.62667394298955+0.00000000081037i) (num-test (asinh 1234000000.0-1.0i) 21.62667394298955-0.00000000081037i) (num-test (asinh 1234000000.0+3.14159265358979i) 21.62667394298955+0.00000000254586i) (num-test (asinh 1234000000.0-3.14159265358979i) 21.62667394298955-0.00000000254586i) (num-test (asinh 1234000000.0+2.71828182845905i) 21.62667394298955+0.00000000220282i) (num-test (asinh 1234000000.0-2.71828182845905i) 21.62667394298955-0.00000000220282i) (num-test (asinh 1234000000.0+1234.0i) 21.62667394299005+0.00000100000000i) (num-test (asinh 1234000000.0-1234.0i) 21.62667394299005-0.00000100000000i) (num-test (asinh 1234000000.0+1234000000.0i) 21.97324753326953+0.78539816339745i) (num-test (asinh 1234000000.0-1234000000.0i) 21.97324753326953-0.78539816339745i) (num-test (asinh -1234000000/3) -20.52806165432143) (num-test (asinh -500029/2) -13.12242137572639) (num-test (asinh 0.00000001+1234000000.0i) +21.62667394298955+1.570796327200083i) (num-test (asinh 3.14159265358979+1234000000.0i) +21.62667394298955+1.570796327200083i) (num-test (asinh 2.71828182845905+1234000000.0i) +21.62667394298955+1.570796327200083i) (num-test (asinh 1234000000.0+0.00000001i) 2.162667394298955253710416065681969812992E1+8.103727714748784607732648425887640725255E-18i) (num-test (asinh 1234000000.0+2.71828182845905i) 2.162667394298955253953037211122561608564E1+2.202821578978160449522443825215175823101E-9i) (num-test (asinh 0.0e+00+0.0e+00i) 0e0+0.0i) (num-test (asinh 0.0e+00+1.19209289550781250e-07i) 0+1.1920928955078153234e-7i) (num-test (asinh 0.0e+00-1.19209289550781250e-07i) 0-1.1920928955078153234e-7i) (num-test (asinh 0.0e+00+5.0e-01i) 0+5.2359877559829887308e-1i) (num-test (asinh 0.0e+00-5.0e-01i) 0-5.2359877559829887308e-1i) (num-test (asinh 0.0e+00+1.0e+00i) 0+1.5707963267948966192e0i) (num-test (asinh 0.0e+00-1.0e+00i) 0-1.5707963267948966192e0i) (num-test (asinh 0.0e+00+2.0e+00i) 1.3169578969248167086e0+1.5707963267948966192e0i) (num-test (asinh 0.0e+00-2.0e+00i) -1.3169578969248167086e0-1.5707963267948966192e0i) (num-test (asinh 0.0e+00+8.3886080e+06i) 1.6635532333438683873e1+1.5707963267948966192e0i) (num-test (asinh 0.0e+00-8.3886080e+06i) -1.6635532333438683873e1-1.5707963267948966192e0i) (num-test (asinh 1.19209289550781250e-07+0.0e+00i) 1.1920928955078096766e-7+0.0i) (num-test (asinh -1.19209289550781250e-07+0.0e+00i) -1.1920928955078096766e-7+0.0i) (num-test (asinh 1.19209289550781250e-07+1.19209289550781250e-07i) 1.1920928955078181469e-7+1.1920928955078068531e-7i) (num-test (asinh 1.19209289550781250e-07-1.19209289550781250e-07i) 1.1920928955078181469e-7-1.1920928955078068531e-7i) (num-test (asinh -1.19209289550781250e-07+1.19209289550781250e-07i) -1.1920928955078181469e-7+1.1920928955078068531e-7i) (num-test (asinh -1.19209289550781250e-07-1.19209289550781250e-07i) -1.1920928955078181469e-7-1.1920928955078068531e-7i) (num-test (asinh 1.19209289550781250e-07+5.0e-01i) 1.3765103082409432364e-7+5.2359877559829340332e-1i) (num-test (asinh 1.19209289550781250e-07-5.0e-01i) 1.3765103082409432364e-7-5.2359877559829340332e-1i) (num-test (asinh -1.19209289550781250e-07+5.0e-01i) -1.3765103082409432364e-7+5.2359877559829340332e-1i) (num-test (asinh -1.19209289550781250e-07-5.0e-01i) -1.3765103082409432364e-7-5.2359877559829340332e-1i) (num-test (asinh 1.19209289550781250e-07+1.0e+00i) 3.4526698643116312881e-4+1.5704510598153252947e0i) (num-test (asinh 1.19209289550781250e-07-1.0e+00i) 3.4526698643116312881e-4-1.5704510598153252947e0i) (num-test (asinh -1.19209289550781250e-07+1.0e+00i) -3.4526698643116312881e-4+1.5704510598153252947e0i) (num-test (asinh -1.19209289550781250e-07-1.0e+00i) -3.4526698643116312881e-4-1.5704510598153252947e0i) (num-test (asinh 1.19209289550781250e-07+2.0e+00i) 1.3169578969248194435e0+1.5707962579693812072e0i) (num-test (asinh 1.19209289550781250e-07-2.0e+00i) 1.3169578969248194435e0-1.5707962579693812072e0i) (num-test (asinh -1.19209289550781250e-07+2.0e+00i) -1.3169578969248194435e0+1.5707962579693812072e0i) (num-test (asinh -1.19209289550781250e-07-2.0e+00i) -1.3169578969248194435e0-1.5707962579693812072e0i) (num-test (asinh 1.19209289550781250e-07+8.3886080e+06i) 1.6635532333438683873e1+1.5707963267948824084e0i) (num-test (asinh 1.19209289550781250e-07-8.3886080e+06i) 1.6635532333438683873e1-1.5707963267948824084e0i) (num-test (asinh -1.19209289550781250e-07+8.3886080e+06i) -1.6635532333438683873e1+1.5707963267948824084e0i) (num-test (asinh -1.19209289550781250e-07-8.3886080e+06i) -1.6635532333438683873e1-1.5707963267948824084e0i) (num-test (asinh 5.0e-01+0.0e+00i) 4.8121182505960344750e-1+0.0i) (num-test (asinh -5.0e-01+0.0e+00i) -4.8121182505960344750e-1+0.0i) (num-test (asinh 5.0e-01+1.19209289550781250e-07i) 4.8121182505960598961e-1+1.0662402999400097805e-7i) (num-test (asinh 5.0e-01-1.19209289550781250e-07i) 4.8121182505960598961e-1-1.0662402999400097805e-7i) (num-test (asinh -5.0e-01+1.19209289550781250e-07i) -4.8121182505960598961e-1+1.0662402999400097805e-7i) (num-test (asinh -5.0e-01-1.19209289550781250e-07i) -4.8121182505960598961e-1-1.0662402999400097805e-7i) (num-test (asinh 5.0e-01+5.0e-01i) 5.3063753095251782602e-1+4.5227844715119068206e-1i) (num-test (asinh 5.0e-01-5.0e-01i) 5.3063753095251782602e-1-4.5227844715119068206e-1i) (num-test (asinh -5.0e-01+5.0e-01i) -5.3063753095251782602e-1+4.5227844715119068206e-1i) (num-test (asinh -5.0e-01-5.0e-01i) -5.3063753095251782602e-1-4.5227844715119068206e-1i) (num-test (asinh 5.0e-01+1.0e+00i) 7.3285767597364526089e-1+8.9590748120889023907e-1i) (num-test (asinh 5.0e-01-1.0e+00i) 7.3285767597364526089e-1-8.9590748120889023907e-1i) (num-test (asinh -5.0e-01+1.0e+00i) -7.3285767597364526089e-1+8.9590748120889023907e-1i) (num-test (asinh -5.0e-01-1.0e+00i) -7.3285767597364526089e-1-8.9590748120889023907e-1i) (num-test (asinh 5.0e-01+2.0e+00i) 1.3618009008578457882e0+1.2930420702371826591e0i) (num-test (asinh 5.0e-01-2.0e+00i) 1.3618009008578457882e0-1.2930420702371826591e0i) (num-test (asinh -5.0e-01+2.0e+00i) -1.3618009008578457882e0+1.2930420702371826591e0i) (num-test (asinh -5.0e-01-2.0e+00i) -1.3618009008578457882e0-1.2930420702371826591e0i) (num-test (asinh 5.0e-01+8.3886080e+06i) 1.6635532333438685650e1+1.5707962671902518438e0i) (num-test (asinh 5.0e-01-8.3886080e+06i) 1.6635532333438685650e1-1.5707962671902518438e0i) (num-test (asinh -5.0e-01+8.3886080e+06i) -1.6635532333438685650e1+1.5707962671902518438e0i) (num-test (asinh -5.0e-01-8.3886080e+06i) -1.6635532333438685650e1-1.5707962671902518438e0i) (num-test (asinh 1.0e+00+0.0e+00i) 8.8137358701954302523e-1+0.0i) (num-test (asinh -1.0e+00+0.0e+00i) -8.8137358701954302523e-1+0.0i) (num-test (asinh 1.0e+00+1.19209289550781250e-07i) 8.8137358701954553738e-1+8.4293697021788013662e-8i) (num-test (asinh 1.0e+00-1.19209289550781250e-07i) 8.8137358701954553738e-1-8.4293697021788013662e-8i) (num-test (asinh -1.0e+00+1.19209289550781250e-07i) -8.8137358701954553738e-1+8.4293697021788013662e-8i) (num-test (asinh -1.0e+00-1.19209289550781250e-07i) -8.8137358701954553738e-1-8.4293697021788013662e-8i) (num-test (asinh 1.0e+00+5.0e-01i) 9.2613303135018242455e-1+3.4943906285721329363e-1i) (num-test (asinh 1.0e+00-5.0e-01i) 9.2613303135018242455e-1-3.4943906285721329363e-1i) (num-test (asinh -1.0e+00+5.0e-01i) -9.2613303135018242455e-1+3.4943906285721329363e-1i) (num-test (asinh -1.0e+00-5.0e-01i) -9.2613303135018242455e-1-3.4943906285721329363e-1i) (num-test (asinh 1.0e+00+1.0e+00i) 1.0612750619050356520e0+6.6623943249251525510e-1i) (num-test (asinh 1.0e+00-1.0e+00i) 1.0612750619050356520e0-6.6623943249251525510e-1i) (num-test (asinh -1.0e+00+1.0e+00i) -1.0612750619050356520e0+6.6623943249251525510e-1i) (num-test (asinh -1.0e+00-1.0e+00i) -1.0612750619050356520e0-6.6623943249251525510e-1i) (num-test (asinh 1.0e+00+2.0e+00i) 1.4693517443681852733e0+1.0634400235777520562e0i) (num-test (asinh 1.0e+00-2.0e+00i) 1.4693517443681852733e0-1.0634400235777520562e0i) (num-test (asinh -1.0e+00+2.0e+00i) -1.4693517443681852733e0+1.0634400235777520562e0i) (num-test (asinh -1.0e+00-2.0e+00i) -1.4693517443681852733e0-1.0634400235777520562e0i) (num-test (asinh 1.0e+00+8.3886080e+06i) 1.6635532333438690979e1+1.5707962075856070684e0i) (num-test (asinh 1.0e+00-8.3886080e+06i) 1.6635532333438690979e1-1.5707962075856070684e0i) (num-test (asinh -1.0e+00+8.3886080e+06i) -1.6635532333438690979e1+1.5707962075856070684e0i) (num-test (asinh -1.0e+00-8.3886080e+06i) -1.6635532333438690979e1-1.5707962075856070684e0i) (num-test (asinh 2.0e+00+0.0e+00i) 1.4436354751788103425e0+0.0i) (num-test (asinh -2.0e+00+0.0e+00i) -1.4436354751788103425e0+0.0i) (num-test (asinh 2.0e+00+1.19209289550781250e-07i) 1.4436354751788116136e0+5.3312014997000413263e-8i) (num-test (asinh 2.0e+00-1.19209289550781250e-07i) 1.4436354751788116136e0-5.3312014997000413263e-8i) (num-test (asinh -2.0e+00+1.19209289550781250e-07i) -1.4436354751788116136e0+5.3312014997000413263e-8i) (num-test (asinh -2.0e+00-1.19209289550781250e-07i) -1.4436354751788116136e0-5.3312014997000413263e-8i) (num-test (asinh 2.0e+00+5.0e-01i) 1.4657153519472905218e0+2.2101863562288385890e-1i) (num-test (asinh 2.0e+00-5.0e-01i) 1.4657153519472905218e0-2.2101863562288385890e-1i) (num-test (asinh -2.0e+00+5.0e-01i) -1.4657153519472905218e0+2.2101863562288385890e-1i) (num-test (asinh -2.0e+00-5.0e-01i) -1.4657153519472905218e0-2.2101863562288385890e-1i) (num-test (asinh 2.0e+00+1.0e+00i) 1.5285709194809981613e0+4.2707858639247612548e-1i) (num-test (asinh 2.0e+00-1.0e+00i) 1.5285709194809981613e0-4.2707858639247612548e-1i) (num-test (asinh -2.0e+00+1.0e+00i) -1.5285709194809981613e0+4.2707858639247612548e-1i) (num-test (asinh -2.0e+00-1.0e+00i) -1.5285709194809981613e0-4.2707858639247612548e-1i) (num-test (asinh 2.0e+00+2.0e+00i) 1.7343245214879664480e0+7.5424914469804604071e-1i) (num-test (asinh 2.0e+00-2.0e+00i) 1.7343245214879664480e0-7.5424914469804604071e-1i) (num-test (asinh -2.0e+00+2.0e+00i) -1.7343245214879664480e0+7.5424914469804604071e-1i) (num-test (asinh -2.0e+00-2.0e+00i) -1.7343245214879664480e0-7.5424914469804604071e-1i) (num-test (asinh 2.0e+00+8.3886080e+06i) 1.6635532333438712295e1+1.5707960883763175177e0i) (num-test (asinh 2.0e+00-8.3886080e+06i) 1.6635532333438712295e1-1.5707960883763175177e0i) (num-test (asinh -2.0e+00+8.3886080e+06i) -1.6635532333438712295e1+1.5707960883763175177e0i) (num-test (asinh -2.0e+00-8.3886080e+06i) -1.6635532333438712295e1-1.5707960883763175177e0i) (num-test (asinh 8.3886080e+06+0.0e+00i) 1.6635532333438690979e1+0.0i) (num-test (asinh -8.3886080e+06+0.0e+00i) -1.6635532333438690979e1+0.0i) (num-test (asinh 8.3886080e+06+1.19209289550781250e-07i) 1.6635532333438690979e1+1.4210854715201902743e-14i) (num-test (asinh 8.3886080e+06-1.19209289550781250e-07i) 1.6635532333438690979e1-1.4210854715201902743e-14i) (num-test (asinh -8.3886080e+06+1.19209289550781250e-07i) -1.6635532333438690979e1+1.4210854715201902743e-14i) (num-test (asinh -8.3886080e+06-1.19209289550781250e-07i) -1.6635532333438690979e1-1.4210854715201902743e-14i) (num-test (asinh 8.3886080e+06+5.0e-01i) 1.6635532333438692755e1+5.9604644775390130897e-8i) (num-test (asinh 8.3886080e+06-5.0e-01i) 1.6635532333438692755e1-5.9604644775390130897e-8i) (num-test (asinh -8.3886080e+06+5.0e-01i) -1.6635532333438692755e1+5.9604644775390130897e-8i) (num-test (asinh -8.3886080e+06-5.0e-01i) -1.6635532333438692755e1-5.9604644775390130897e-8i) (num-test (asinh 8.3886080e+06+1.0e+00i) 1.6635532333438698084e1+1.1920928955077983828e-7i) (num-test (asinh 8.3886080e+06-1.0e+00i) 1.6635532333438698084e1-1.1920928955077983828e-7i) (num-test (asinh -8.3886080e+06+1.0e+00i) -1.6635532333438698084e1+1.1920928955077983828e-7i) (num-test (asinh -8.3886080e+06-1.0e+00i) -1.6635532333438698084e1-1.1920928955077983828e-7i) (num-test (asinh 8.3886080e+06+2.0e+00i) 1.663553233343871940e1+2.3841857910155628843e-7i) (num-test (asinh 8.3886080e+06-2.0e+00i) 1.663553233343871940e1-2.3841857910155628843e-7i) (num-test (asinh -8.3886080e+06+2.0e+00i) -1.663553233343871940e1+2.3841857910155628843e-7i) (num-test (asinh -8.3886080e+06-2.0e+00i) -1.663553233343871940e1-2.3841857910155628843e-7i) (num-test (asinh 8.3886080e+06+8.3886080e+06i) 1.6982105923718660081e1+7.8539816339744653326e-1i) (num-test (asinh 8.3886080e+06-8.3886080e+06i) 1.6982105923718660081e1-7.8539816339744653326e-1i) (num-test (asinh -8.3886080e+06+8.3886080e+06i) -1.6982105923718660081e1+7.8539816339744653326e-1i) (num-test (asinh -8.3886080e+06-8.3886080e+06i) -1.6982105923718660081e1-7.8539816339744653326e-1i) (num-test (asinh -2.225073858507201399999999999999999999996E-308) -2.225073858507201399999999999999999999996E-308) (num-test (asinh 1.110223024625156799999999999999999999997E-16) 1.11022302462515679999999999999999771924E-16) (for-each (lambda (num-and-val) (let ((num (car num-and-val)) (val (cadr num-and-val))) (num-test-1 'asinh num (asinh num) val))) (vector (list 0 0) (list 1 0.88137358701954) (list 2 1.4436354751788) (list 3 1.8184464592321) (list -1 -0.88137358701954) (list -2 -1.4436354751788) (list -3 -1.8184464592321) (list 9223372036854775807 44.361419555836) (list -9223372036854775808 -44.361419555836) (list 1/2 0.4812118250596) (list 1/3 0.32745015023726) (list -1/2 -0.4812118250596) (list -1/3 -0.32745015023726) (list 1/9223372036854775807 1.0842021724855e-19) (list 0.0 0.0) (list 1.0 0.88137358701954) (list 2.0 1.4436354751788) (list -2.0 -1.4436354751788) (list 1.000000000000000000000000000000000000002E-309 1.000000000000000000000000000000000000002E-309) (list 1e+16 37.534508668465) (list 0+1i 0+1.5707963267949i) (list 0+2i 1.3169578969248+1.5707963267949i) (list 0-1i 0-1.5707963267949i) (list 1+1i 1.061275061905+0.66623943249252i) (list 1-1i 1.061275061905-0.66623943249252i) (list -1+1i -1.061275061905+0.66623943249252i) (list -1-1i -1.061275061905-0.66623943249252i) (list 0.1+0.1i 0.10033029811221+0.099663702859795i) (list 1e+16+1e+16i 37.881082258745+0.78539816339745i) (list 1e-16+1e-16i 0+1e-16i) )) (test (asinh) 'error) (test (asinh "hi") 'error) (test (asinh 1.0+23.0i 1.0+23.0i) 'error) (test (asinh 0 1) 'error) (for-each (lambda (arg) (test (asinh arg) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) ;;; -------------------------------------------------------------------------------- ;;; acosh ;;; -------------------------------------------------------------------------------- (num-test (acosh 0) 0.0+1.57079632679490i) (num-test (acosh 1) 0.0) (num-test (acosh -1) 0.0+3.14159265358979i) (num-test (acosh 2) 1.31695789692482) (num-test (acosh -2) 1.31695789692482+3.14159265358979i) (num-test (acosh 3) 1.76274717403909) (num-test (acosh -3) 1.76274717403909+3.14159265358979i) (num-test (acosh 10) 2.99322284612638) (num-test (acosh -10) 2.99322284612638+3.14159265358979i) (num-test (acosh 1234) 7.81116322084923) (num-test (acosh -1234) 7.81116322084923+3.14159265358979i) (num-test (acosh 1234000000) 21.62667394298955) (num-test (acosh -1234000000) 21.62667394298955+3.14159265358979i) (num-test (acosh 500029) 13.81556855628134) (num-test (acosh -500029) 13.81556855628134+3.14159265358979i) (num-test (acosh 362880) 13.49497466063952) (num-test (acosh -362880) 13.49497466063952+3.14159265358979i) (num-test (acosh 0/1) 0.0+1.57079632679490i) (num-test (acosh 0/2) 0.0+1.57079632679490i) (num-test (acosh 0/3) 0.0+1.57079632679490i) (num-test (acosh 0/10) 0.0+1.57079632679490i) (num-test (acosh 0/1234) 0.0+1.57079632679490i) (num-test (acosh 0/1234000000) 0.0+1.57079632679490i) (num-test (acosh 0/500029) 0.0+1.57079632679490i) (num-test (acosh 0/362880) 0.0+1.57079632679490i) (num-test (acosh 1/1) 0.0) (num-test (acosh -1/1) 0.0+3.14159265358979i) (num-test (acosh 1/2) 0.0+1.04719755119660i) (num-test (acosh -1/2) 0.0+2.09439510239320i) (num-test (acosh 1/3) 0.0+1.23095941734077i) (num-test (acosh -1/3) 0.0+1.91063323624902i) (num-test (acosh 1/10) 0.0+1.47062890563334i) (num-test (acosh -1/10) 0.0+1.67096374795646i) (num-test (acosh 1/1234) 0.0+1.56998595393473i) (num-test (acosh -1/1234) 0.0+1.57160669965507i) (num-test (acosh 1/1234000000) 0.0+1.57079632598452i) (num-test (acosh -1/1234000000) 0.0+1.57079632760527i) (num-test (acosh 1/500029) 0.0+1.57079432691089i) (num-test (acosh -1/500029) 0.0+1.57079832667890i) (num-test (acosh 1/362880) 0.0+1.57079357106297i) (num-test (acosh -1/362880) 0.0+1.57079908252682i) (num-test (acosh 2/1) 1.31695789692482) (num-test (acosh -2/1) 1.31695789692482+3.14159265358979i) (num-test (acosh 2/2) 0.0) (num-test (acosh -2/2) 0.0+3.14159265358979i) (num-test (acosh 2/3) 0.0+0.84106867056793i) (num-test (acosh -2/3) 0.0+2.30052398302186i) (num-test (acosh 2/10) 0.0+1.36943840600457i) (num-test (acosh -2/10) 0.0+1.77215424758523i) (num-test (acosh 2/1234) 0.0+1.56917558054238i) (num-test (acosh -2/1234) 0.0+1.57241707304741i) (num-test (acosh 2/1234000000) 0.0+1.57079632517415i) (num-test (acosh -2/1234000000) 0.0+1.57079632841564i) (num-test (acosh 2/500029) 0.0+1.57079232702688i) (num-test (acosh -2/500029) 0.0+1.57080032656291i) (num-test (acosh 2/362880) 0.0+1.57079081533105i) (num-test (acosh -2/362880) 0.0+1.57080183825874i) (num-test (acosh 3/1) 1.76274717403909) (num-test (acosh -3/1) 1.76274717403909+3.14159265358979i) (num-test (acosh 3/2) 0.96242365011921) (num-test (acosh -3/2) 0.96242365011921+3.14159265358979i) (num-test (acosh 3/3) 0.0) (num-test (acosh -3/3) 0.0+3.14159265358979i) (num-test (acosh 3/10) 0.0+1.26610367277950i) (num-test (acosh -3/10) 0.0+1.87548898081029i) (num-test (acosh 3/1234) 0.0+1.56836520608568i) (num-test (acosh -3/1234) 0.0+1.57322744750412i) (num-test (acosh 3/1234000000) 0.0+1.57079632436378i) (num-test (acosh -3/1234000000) 0.0+1.57079632922601i) (num-test (acosh 3/500029) 0.0+1.57079032714288i) (num-test (acosh -3/500029) 0.0+1.57080232644692i) (num-test (acosh 3/362880) 0.0-1.57078805959913i) (num-test (acosh -3/362880) 0.0-1.57080459399066i) (num-test (acosh 10/1) 2.99322284612638) (num-test (acosh -10/1) 2.99322284612638+3.14159265358979i) (num-test (acosh 10/2) 2.29243166956118) (num-test (acosh -10/2) 2.29243166956118+3.14159265358979i) (num-test (acosh 10/3) 1.87382024252741) (num-test (acosh -10/3) 1.87382024252741+3.14159265358979i) (num-test (acosh 10/10) 0.0) (num-test (acosh -10/10) 0.0+3.14159265358979i) (num-test (acosh 10/1234) 0.0+1.56269251038168i) (num-test (acosh -10/1234) 0.0+1.57890014320811i) (num-test (acosh 10/1234000000) 0.0+1.57079631869117i) (num-test (acosh -10/1234000000) 0.0+1.57079633489862i) (num-test (acosh 10/500029) 0.0+1.57077632795483i) (num-test (acosh -10/500029) 0.0+1.57081632563497i) (num-test (acosh 10/362880) 0.0+1.57076876947567i) (num-test (acosh -10/362880) 0.0+1.57082388411412i) (num-test (acosh 1234/1) 7.81116322084923) (num-test (acosh -1234/1) 7.81116322084923+3.14159265358979i) (num-test (acosh 1234/2) 7.11801554776066) (num-test (acosh -1234/2) 7.11801554776066+3.14159265358979i) (num-test (acosh 1234/3) 6.71254961876983) (num-test (acosh -1234/3) 6.71254961876983+3.14159265358979i) (num-test (acosh 1234/10) 5.50856187402619) (num-test (acosh -1234/10) 5.50856187402619+3.14159265358979i) (num-test (acosh 1234/1234) 0.0) (num-test (acosh -1234/1234) 0.0+3.14159265358979i) (num-test (acosh 1234/1234000000) 0.0+1.57079532679490i) (num-test (acosh -1234/1234000000) 0.0+1.57079732679490i) (num-test (acosh 1234/500029) 0.0+1.56832846742558i) (num-test (acosh -1234/500029) 0.0+1.57326418616421i) (num-test (acosh 1234/362880) 0.0+1.56739574704864i) (num-test (acosh -1234/362880) 0.0+1.57419690654115i) (num-test (acosh 1234000000/1) 21.62667394298955) (num-test (acosh -1234000000/1) 21.62667394298955+3.14159265358979i) (num-test (acosh 1234000000/2) 20.93352676242961) (num-test (acosh -1234000000/2) 20.93352676242961+3.14159265358979i) (num-test (acosh 1234000000/3) 20.52806165432144) (num-test (acosh -1234000000/3) 20.52806165432144+3.14159265358979i) (num-test (acosh 1234000000/10) 19.32408884999551) (num-test (acosh -1234000000/10) 19.32408884999551+3.14159265358979i) (num-test (acosh 1234000000/1234) 14.50865773852397) (num-test (acosh -1234000000/1234) 14.50865773852397+3.14159265358979i) (num-test (acosh 1234000000/1234000000) 0.0) (num-test (acosh -1234000000/1234000000) 0.0+3.14159265358979i) (num-test (acosh 1234000000/500029) 8.50425252621839) (num-test (acosh -1234000000/500029) 8.50425252621839+3.14159265358979i) (num-test (acosh 1234000000/362880) 8.82484644128907) (num-test (acosh -1234000000/362880) 8.82484644128907+3.14159265358979i) (num-test (acosh 500029/1) 13.81556855628134) (num-test (acosh -500029/1) 13.81556855628134+3.14159265358979i) (num-test (acosh 500029/2) 13.12242137571839) (num-test (acosh -500029/2) 13.12242137571839+3.14159265358979i) (num-test (acosh 500029/3) 12.71695626760523) (num-test (acosh -500029/3) 12.71695626760523+3.14159265358979i) (num-test (acosh 500029/10) 11.51298346318831) (num-test (acosh -500029/10) 11.51298346318831+3.14159265358979i) (num-test (acosh 500029/1234) 6.69755082923415) (num-test (acosh -500029/1234) 6.69755082923415+3.14159265358979i) (num-test (acosh 500029/1234000000) 0.0+1.57039111689726i) (num-test (acosh -500029/1234000000) 0.0+1.57120153669253i) (num-test (acosh 500029/500029) 0.0) (num-test (acosh -500029/500029) 0.0+3.14159265358979i) (num-test (acosh 500029/362880) 0.84413377868249) (num-test (acosh -500029/362880) 0.84413377868249+3.14159265358979i) (num-test (acosh 362880/1) 13.49497466063952) (num-test (acosh -362880/1) 13.49497466063952+3.14159265358979i) (num-test (acosh 362880/2) 12.80182748007388) (num-test (acosh -362880/2) 12.80182748007388+3.14159265358979i) (num-test (acosh 362880/3) 12.39636237195622) (num-test (acosh -362880/3) 12.39636237195622+3.14159265358979i) (num-test (acosh 362880/10) 11.19238956745752) (num-test (acosh -362880/10) 11.19238956745752+3.14159265358979i) (num-test (acosh 362880/1234) 6.37695556518904) (num-test (acosh -362880/1234) 6.37695556518904+3.14159265358979i) (num-test (acosh 362880/1234000000) 0.0+1.57050225871935i) (num-test (acosh -362880/1234000000) 0.0+1.57109039487045i) (num-test (acosh 362880/500029) 0.0+0.75871902295910i) (num-test (acosh -362880/500029) 0.0+2.38287363063069i) (num-test (acosh 362880/362880) 0.0) (num-test (acosh -362880/362880) 0.0+3.14159265358979i) (num-test (acosh 0.0) 0.0+1.57079632679490i) (num-test (acosh 0.00000001) 0.0+1.57079631679490i) (num-test (acosh -0.00000001) 0.0+1.57079633679490i) (num-test (acosh 1.0) 0.0) (num-test (acosh -1.0) 0.0+3.14159265358979i) (num-test (acosh pi) 1.81152627246085) (num-test (acosh -3.14159265358979) 1.81152627246085+3.14159265358979i) (num-test (acosh 2.71828182845905) 1.65745445415308) (num-test (acosh -2.71828182845905) 1.65745445415308+3.14159265358979i) (num-test (acosh 1234.0) 7.81116322084923) (num-test (acosh -1234.0) 7.81116322084923+3.14159265358979i) (num-test (acosh 1234000000.0) 21.62667394298955) (num-test (acosh -1234000000.0) 21.62667394298955+3.14159265358979i) (num-test (acosh 0.0+0.0i) 0.0+1.57079632679490i) (num-test (acosh -0.0+0.0i) 0.0+1.57079632679490i) (num-test (acosh 0.0-0.0i) 0.0+1.57079632679490i) (num-test (acosh -0.0-0.0i) 0.0+1.57079632679490i) (num-test (acosh 0.0+0.00000001i) 0.00000001+1.57079632679490i) (num-test (acosh -0.0+0.00000001i) 0.00000001+1.57079632679490i) (num-test (acosh 0.0-0.00000001i) 0.00000001-1.57079632679490i) (num-test (acosh -0.0-0.00000001i) 0.00000001-1.57079632679490i) (num-test (acosh 0.0+1.0i) 0.88137358701954+1.57079632679490i) (num-test (acosh -0.0+1.0i) 0.88137358701954+1.57079632679490i) (num-test (acosh 0.0-1.0i) 0.88137358701954-1.57079632679490i) (num-test (acosh -0.0-1.0i) 0.88137358701954-1.57079632679490i) (num-test (acosh 0.0+3.14159265358979i) 1.86229574331085+1.57079632679490i) (num-test (acosh -0.0+3.14159265358979i) 1.86229574331085+1.57079632679490i) (num-test (acosh 0.0-3.14159265358979i) 1.86229574331085-1.57079632679490i) (num-test (acosh -0.0-3.14159265358979i) 1.86229574331085-1.57079632679490i) (num-test (acosh 0.0+2.71828182845905i) 1.72538255885231+1.57079632679490i) (num-test (acosh -0.0+2.71828182845905i) 1.72538255885231+1.57079632679490i) (num-test (acosh 0.0-2.71828182845905i) 1.72538255885231-1.57079632679490i) (num-test (acosh -0.0-2.71828182845905i) 1.72538255885232-1.57079632679490i) (num-test (acosh 0.0+1234.0i) 7.81116354920125+1.57079632679490i) (num-test (acosh -0.0+1234.0i) 7.81116354920125+1.57079632679490i) (num-test (acosh 0.0-1234.0i) 7.81116354920125-1.57079632679490i) (num-test (acosh -0.0-1234.0i) 7.81116354896171-1.57079632679490i) (num-test (acosh 0.0+1234000000.0i) 21.62667394298955+1.57079632679490i) (num-test (acosh -0.0+1234000000.0i) 21.62667394298955+1.57079632679490i) (num-test (acosh 0.0-1234000000.0i) 21.62667394298955-1.57079632679490i) (num-test (acosh 0.00000001+0.0i) 0.0+1.57079631679490i) (num-test (acosh -0.00000001+0.0i) 0.0+1.57079633679490i) (num-test (acosh 0.00000001-0.0i) 0.0+1.57079631679490i) (num-test (acosh -0.00000001-0.0i) 0.0+1.57079633679490i) (num-test (acosh 0.00000001+0.00000001i) 0.00000001+1.57079631679490i) (num-test (acosh -0.00000001+0.00000001i) 0.00000001+1.57079633679490i) (num-test (acosh 0.00000001-0.00000001i) 0.00000001-1.57079631679490i) (num-test (acosh -0.00000001-0.00000001i) 0.00000001-1.57079633679490i) (num-test (acosh 0.00000001+1.0i) 0.88137358701954+1.57079631972383i) (num-test (acosh -0.00000001+1.0i) 0.88137358701954+1.57079633386596i) (num-test (acosh 0.00000001-1.0i) 0.88137358701954-1.57079631972383i) (num-test (acosh -0.00000001-1.0i) 0.88137358701954-1.57079633386596i) (num-test (acosh 0.00000001+3.14159265358979i) 1.86229574331085+1.57079632376175i) (num-test (acosh -0.00000001+3.14159265358979i) 1.86229574331085+1.57079632982804i) (num-test (acosh 0.00000001-3.14159265358979i) 1.86229574331085-1.57079632376175i) (num-test (acosh -0.00000001-3.14159265358979i) 1.86229574331085-1.57079632982804i) (num-test (acosh 0.00000001+2.71828182845905i) 1.72538255885231+1.57079632334232i) (num-test (acosh -0.00000001+2.71828182845905i) 1.72538255885231+1.57079633024747i) (num-test (acosh 0.00000001-2.71828182845905i) 1.72538255885231-1.57079632334232i) (num-test (acosh -0.00000001-2.71828182845905i) 1.72538255885231-1.57079633024747i) (num-test (acosh 0.00000001+1234.0i) 7.81116354920125+1.57079632678679i) (num-test (acosh -0.00000001+1234.0i) 7.81116354920125+1.57079632680300i) (num-test (acosh 0.00000001-1234.0i) 7.81116354920125-1.57079632678679i) (num-test (acosh -0.00000001-1234.0i) 7.81116354920125-1.57079632680300i) (num-test (acosh 0.00000001+1234000000.0i) 21.62667394298955+1.57079632679490i) (num-test (acosh -0.00000001+1234000000.0i) 21.62667394298955+1.57079632679490i) (num-test (acosh 0.00000001-1234000000.0i) 21.62667394298955-1.57079632679490i) (num-test (acosh -0.00000001-1234000000.0i) 21.62667394298955-1.57079632679490i) (num-test (acosh 1.0+0.0i) 0.0) (num-test (acosh -1.0+0.0i) 0.0+3.14159265358979i) (num-test (acosh 1.0-0.0i) 0.0) (num-test (acosh -1.0-0.0i) 0.0+3.14159265358979i) (num-test (acosh 1.0+0.00000001i) 0.00010000000008+0.00009999999992i) (num-test (acosh -1.0+0.00000001i) 0.00010000000008+3.14149265358988i) (num-test (acosh 1.0-0.00000001i) 0.00010000000008-0.00009999999992i) (num-test (acosh -1.0-0.00000001i) 0.00010000000008-3.14149265358988i) (num-test (acosh 1.0+1.0i) 1.06127506190504+0.90455689430238i) (num-test (acosh -1.0+1.0i) 1.06127506190504+2.23703575928741i) (num-test (acosh 1.0-1.0i) 1.06127506190504-0.90455689430238i) (num-test (acosh -1.0-1.0i) 1.06127506190504-2.23703575928741i) (num-test (acosh 1.0+3.14159265358979i) 1.90462768697066+1.27521129258327i) (num-test (acosh -1.0+3.14159265358979i) 1.90462768697066+1.86638136100653i) (num-test (acosh 1.0-3.14159265358979i) 1.90462768697066-1.27521129258327i) (num-test (acosh -1.0-3.14159265358979i) 1.90462768697066-1.86638136100653i) (num-test (acosh 1.0+2.71828182845905i) 1.77905438385935+1.23635355491853i) (num-test (acosh -1.0+2.71828182845905i) 1.77905438385935+1.90523909867127i) (num-test (acosh 1.0-2.71828182845905i) 1.77905438385935-1.23635355491853i) (num-test (acosh -1.0-2.71828182845905i) 1.77905438385935-1.90523909867127i) (num-test (acosh 1.0+1234.0i) 7.81116387755283+1.56998595446690i) (num-test (acosh -1.0+1234.0i) 7.81116387755283+1.57160669912289i) (num-test (acosh 1.0-1234.0i) 7.81116387755283-1.56998595446690i) (num-test (acosh -1.0-1234.0i) 7.81116387755283-1.57160669912289i) (num-test (acosh 1.0+1234000000.0i) 21.62667394298955+1.57079632598452i) (num-test (acosh -1.0+1234000000.0i) 21.62667394298955+1.57079632760527i) (num-test (acosh 1.0-1234000000.0i) 21.62667394298955-1.57079632598452i) (num-test (acosh -1.0-1234000000.0i) 21.62667394298955-1.57079632760527i) (num-test (acosh 3.14159265358979+0.0i) 1.81152627246085) (num-test (acosh -3.14159265358979+0.0i) 1.81152627246085+3.14159265358979i) (num-test (acosh 3.14159265358979-0.0i) 1.81152627246085) (num-test (acosh -3.14159265358979-0.0i) 1.81152627246085+3.14159265358979i) (num-test (acosh 3.14159265358979+0.00000001i) 1.81152627246085+0.00000000335775i) (num-test (acosh -3.14159265358979+0.00000001i) 1.81152627246085+3.14159265023205i) (num-test (acosh 3.14159265358979-0.00000001i) 1.81152627246085-0.00000000335775i) (num-test (acosh -3.14159265358979-0.00000001i) 1.81152627246085-3.14159265023205i) (num-test (acosh 3.14159265358979+1.0i) 1.86711439316026+0.32225329398146i) (num-test (acosh -3.14159265358979+1.0i) 1.86711439316026+2.81933935960833i) (num-test (acosh 3.14159265358979-1.0i) 1.86711439316026-0.32225329398146i) (num-test (acosh -3.14159265358979-1.0i) 1.86711439316026-2.81933935960833i) (num-test (acosh 3.14159265358979+3.14159265358979i) 2.18469104082751+0.79805654766741i) (num-test (acosh -3.14159265358979+3.14159265358979i) 2.18469104082751+2.34353610592238i) (num-test (acosh 3.14159265358979-3.14159265358979i) 2.18469104082751-0.79805654766741i) (num-test (acosh -3.14159265358979-3.14159265358979i) 2.18469104082751-2.34353610592238i) (num-test (acosh 3.14159265358979+2.71828182845905i) 2.11552790803290+0.72769976263454i) (num-test (acosh -3.14159265358979+2.71828182845905i) 2.11552790803290+2.41389289095525i) (num-test (acosh 3.14159265358979-2.71828182845905i) 2.11552790803290-0.72769976263454i) (num-test (acosh -3.14159265358979-2.71828182845905i) 2.11552790803290-2.41389289095525i) (num-test (acosh 3.14159265358979+1234.0i) 7.81116678989204+1.56825047198552i) (num-test (acosh -3.14159265358979+1234.0i) 7.81116678989204+1.57334218160427i) (num-test (acosh 3.14159265358979-1234.0i) 7.81116678989204-1.56825047198552i) (num-test (acosh -3.14159265358979-1234.0i) 7.81116678989204-1.57334218160427i) (num-test (acosh 3.14159265358979+1234000000.0i) 21.62667394298955+1.57079632424904i) (num-test (acosh -3.14159265358979+1234000000.0i) 21.62667394298955+1.57079632934076i) (num-test (acosh 3.14159265358979-1234000000.0i) 21.62667394298955-1.57079632424904i) (num-test (acosh -3.14159265358979-1234000000.0i) 21.62667394298955-1.57079632934076i) (num-test (acosh 2.71828182845905+0.0i) 1.65745445415308) (num-test (acosh -2.71828182845905+0.0i) 1.65745445415308+3.14159265358979i) (num-test (acosh 2.71828182845905-0.0i) 1.65745445415308) (num-test (acosh -2.71828182845905-0.0i) 1.65745445415308+3.14159265358979i) (num-test (acosh 2.71828182845905+0.00000001i) 1.65745445415308+0.00000000395623i) (num-test (acosh -2.71828182845905+0.00000001i) 1.65745445415308+3.14159264963356i) (num-test (acosh 2.71828182845905-0.00000001i) 1.65745445415308-0.00000000395623i) (num-test (acosh -2.71828182845905-0.00000001i) 1.65745445415308-3.14159264963356i) (num-test (acosh 2.71828182845905+1.0i) 1.73375471569385+0.37321824160908i) (num-test (acosh -2.71828182845905+1.0i) 1.73375471569385+2.76837441198071i) (num-test (acosh 2.71828182845905-1.0i) 1.73375471569385-0.37321824160908i) (num-test (acosh -2.71828182845905-1.0i) 1.73375471569385-2.76837441198071i) (num-test (acosh 2.71828182845905+3.14159265358979i) 2.11968336368048+0.87174835684834i) (num-test (acosh -2.71828182845905+3.14159265358979i) 2.11968336368048+2.26984429674145i) (num-test (acosh 2.71828182845905-3.14159265358979i) 2.11968336368048-0.87174835684834i) (num-test (acosh -2.71828182845905-3.14159265358979i) 2.11968336368048-2.26984429674145i) (num-test (acosh 2.71828182845905+2.71828182845905i) 2.04014932880026+0.80229897091014i) (num-test (acosh -2.71828182845905+2.71828182845905i) 2.04014932880026+2.33929368267965i) (num-test (acosh 2.71828182845905-2.71828182845905i) 2.04014932880026-0.80229897091014i) (num-test (acosh -2.71828182845905-2.71828182845905i) 2.04014932880026-2.33929368267965i) (num-test (acosh 2.71828182845905+1234.0i) 7.81116597540442+1.56859350950221i) (num-test (acosh -2.71828182845905+1234.0i) 7.81116597540442+1.57299914408758i) (num-test (acosh 2.71828182845905-1234.0i) 7.81116597540442-1.56859350950221i) (num-test (acosh -2.71828182845905-1234.0i) 7.81116597540442-1.57299914408758i) (num-test (acosh 2.71828182845905+1234000000.0i) 21.62667394298955+1.57079632459208i) (num-test (acosh -2.71828182845905+1234000000.0i) 21.62667394298955+1.57079632899772i) (num-test (acosh 2.71828182845905-1234000000.0i) 21.62667394298955-1.57079632459208i) (num-test (acosh -2.71828182845905-1234000000.0i) 21.62667394298955-1.57079632899772i) (num-test (acosh 1234.0+0.0i) 7.81116322084923) (num-test (acosh -1234.0+0.0i) 7.81116322084923+3.14159265358979i) (num-test (acosh 1234.0-0.0i) 7.81116322084923) (num-test (acosh -1234.0-0.0i) 7.81116322084923+3.14159265358979i) (num-test (acosh 1234.0+0.00000001i) 7.81116322084923+0.00000000000810i) (num-test (acosh -1234.0+0.00000001i) 7.81116322084923+3.14159265358169i) (num-test (acosh 1234.0-0.00000001i) 7.81116322084923-0.00000000000810i) (num-test (acosh -1234.0-0.00000001i) 7.81116322084923-3.14159265358169i) (num-test (acosh 1234.0+1.0i) 7.81116354920146+0.00081037286017i) (num-test (acosh -1234.0+1.0i) 7.81116354920146+3.14078228072962i) (num-test (acosh 1234.0-1.0i) 7.81116354920146-0.00081037286017i) (num-test (acosh -1234.0-1.0i) 7.81116354920146-3.14078228072962i) (num-test (acosh 1234.0+3.14159265358979i) 7.81116646154641+0.00254585648123i) (num-test (acosh -1234.0+3.14159265358979i) 7.81116646154641+3.13904679710856i) (num-test (acosh 1234.0-3.14159265358979i) 7.81116646154641-0.00254585648123i) (num-test (acosh -1234.0-3.14159265358979i) 7.81116646154641-3.13904679710856i) (num-test (acosh 1234.0+2.71828182845905i) 7.81116564705719+0.00220281873928i) (num-test (acosh -1234.0+2.71828182845905i) 7.81116564705719+3.13938983485052i) (num-test (acosh 1234.0-2.71828182845905i) 7.81116564705719-0.00220281873928i) (num-test (acosh -1234.0-2.71828182845905i) 7.81116564705719-3.13938983485052i) (num-test (acosh 1234.0+1234.0i) 8.15773697530526+0.78539824548545i) (num-test (acosh -1234.0+1234.0i) 8.15773697530526+2.35619440810434i) (num-test (acosh 1234.0-1234.0i) 8.15773697530526-0.78539824548545i) (num-test (acosh -1234.0-1234.0i) 8.15773697530526-2.35619440810434i) (num-test (acosh 1234.0+1234000000.0i) 21.62667394299005+1.57079532679490i) (num-test (acosh -1234.0+1234000000.0i) 21.62667394299005+1.57079732679490i) (num-test (acosh 1234.0-1234000000.0i) 21.62667394299005-1.57079532679490i) (num-test (acosh -1234.0-1234000000.0i) 21.62667394299005-1.57079732679490i) (num-test (acosh 1234000000.0+0.0i) 21.62667394298955) (num-test (acosh -1234000000.0+0.0i) 21.62667394298955+3.14159265358979i) (num-test (acosh 1234000000.0-0.0i) 21.62667394298955) (num-test (acosh -1234000000.0-0.0i) 21.62667394298955+3.14159265358979i) (num-test (acosh 1234000000.0+0.00000001i) 21.62667394298955+0.0i) (num-test (acosh -1234000000.0+0.00000001i) 21.62667394298955+3.14159265358979i) (num-test (acosh 1234000000.0-0.00000001i) 21.62667394298955-0.0i) (num-test (acosh -1234000000.0-0.00000001i) 21.62667394298955-3.14159265358979i) (num-test (acosh 1234000000.0+1.0i) 21.62667394298955+0.00000000081037i) (num-test (acosh -1234000000.0+1.0i) 21.62667394298955+3.14159265277942i) (num-test (acosh 1234000000.0-1.0i) 21.62667394298955-0.00000000081037i) (num-test (acosh -1234000000.0-1.0i) 21.62667394298955-3.14159265277942i) (num-test (acosh 1234000000.0+3.14159265358979i) 21.62667394298955+0.00000000254586i) (num-test (acosh -1234000000.0+3.14159265358979i) 21.62667394298955+3.14159265104393i) (num-test (acosh 1234000000.0-3.14159265358979i) 21.62667394298955-0.00000000254586i) (num-test (acosh -1234000000.0-3.14159265358979i) 21.62667394298955-3.14159265104393i) (num-test (acosh 1234000000.0+2.71828182845905i) 21.62667394298955+0.00000000220282i) (num-test (acosh -1234000000.0+2.71828182845905i) 21.62667394298955+3.14159265138697i) (num-test (acosh 1234000000.0-2.71828182845905i) 21.62667394298955-0.00000000220282i) (num-test (acosh -1234000000.0-2.71828182845905i) 21.62667394298955-3.14159265138697i) (num-test (acosh 1234000000.0+1234.0i) 21.62667394299005+0.00000100000000i) (num-test (acosh -1234000000.0+1234.0i) 21.62667394299005+3.14159165358979i) (num-test (acosh 1234000000.0-1234.0i) 21.62667394299005-0.00000100000000i) (num-test (acosh -1234000000.0-1234.0i) 21.62667394299005-3.14159165358979i) (num-test (acosh 1234000000.0+1234000000.0i) 21.97324753326953+0.78539816339745i) (num-test (acosh -1234000000.0+1234000000.0i) 21.97324753326953+2.35619449019234i) (num-test (acosh 1234000000.0-1234000000.0i) 21.97324753326953-0.78539816339745i) (num-test (acosh -1234000000.0-1234000000.0i) 21.97324753326953-2.35619449019234i) (num-test (acosh 0) 0+1.570796326794897i) (num-test (acosh 1) 0) (num-test (acosh -1) 0+3.141592653589793i) (num-test (acosh -1.0e+01) 2.9932228461263808979e0+3.1415926535897932385e0i) (num-test (acosh -2.0e+00) 1.3169578969248167086e0+3.1415926535897932385e0i) (num-test (acosh -1.0e+00) 0+3.1415926535897932385e0i) (num-test (acosh -7.50e-01) 0+2.4188584057763776273e0i) (num-test (acosh -5.0e-01) 0+2.0943951023931954923e0i) (num-test (acosh -1.250e-01) 0+1.6961241579629620161e0i) (num-test (acosh -3.45266983001243932001e-04) 0+1.5711415937847577022e0i) (num-test (acosh -1.19209289550781250e-07) 0+1.570796446004186170e0i) (num-test (acosh 0.0e+00) 0+1.5707963267948966192e0i) (num-test (acosh 1.19209289550781250e-07) 0+1.5707962075856070684e0i) (num-test (acosh 3.45266983001243932001e-04) 0+1.5704510598050355363e0i) (num-test (acosh 1.250e-01) 0+1.4454684956268312224e0i) (num-test (acosh 5.0e-01) 0+1.0471975511965977462e0i) (num-test (acosh 7.50e-01) 0+7.2273424781341561118e-1i) (num-test (acosh 1.0e+00) 0e0+0.0i) (num-test (acosh 2.0e+00) 1.3169578969248167086e0+0.0i) (num-test (acosh 1.0e+01) 2.9932228461263808979e0+0.0i) (num-test (acosh 0.0e+00+0.0e+00i) 0+1.5707963267948966192e0i) (num-test (acosh 0.0e+00+1.19209289550781250e-07i) 1.1920928955078096766e-7+1.5707963267948966192e0i) (num-test (acosh 0.0e+00-1.19209289550781250e-07i) 1.1920928955078096766e-7-1.5707963267948966192e0i) (num-test (acosh 0.0e+00+5.0e-01i) 4.8121182505960344750e-1+1.5707963267948966192e0i) (num-test (acosh 0.0e+00-5.0e-01i) 4.8121182505960344750e-1-1.5707963267948966192e0i) (num-test (acosh 0.0e+00+1.0e+00i) 8.8137358701954302523e-1+1.5707963267948966192e0i) (num-test (acosh 0.0e+00-1.0e+00i) 8.8137358701954302523e-1-1.5707963267948966192e0i) (num-test (acosh 0.0e+00+2.0e+00i) 1.4436354751788103425e0+1.5707963267948966192e0i) (num-test (acosh 0.0e+00-2.0e+00i) 1.4436354751788103425e0-1.5707963267948966192e0i) (num-test (acosh 0.0e+00+8.3886080e+06i) 1.6635532333438690979e1+1.5707963267948966192e0i) (num-test (acosh 0.0e+00-8.3886080e+06i) 1.6635532333438690979e1-1.5707963267948966192e0i) (num-test (acosh 1.19209289550781250e-07+0.0e+00i) 0+1.5707962075856070684e0i) (num-test (acosh -1.19209289550781250e-07+0.0e+00i) 0+1.570796446004186170e0i) (num-test (acosh 1.19209289550781250e-07+1.19209289550781250e-07i) 1.1920928955078181469e-7+1.5707962075856070685e0i) (num-test (acosh 1.19209289550781250e-07-1.19209289550781250e-07i) 1.1920928955078181469e-7-1.5707962075856070685e0i) (num-test (acosh -1.19209289550781250e-07+1.19209289550781250e-07i) 1.1920928955078181469e-7+1.570796446004186170e0i) (num-test (acosh -1.19209289550781250e-07-1.19209289550781250e-07i) 1.1920928955078181469e-7-1.570796446004186170e0i) (num-test (acosh 1.19209289550781250e-07+5.0e-01i) 4.8121182505960598961e-1+1.5707962201708666252e0i) (num-test (acosh 1.19209289550781250e-07-5.0e-01i) 4.8121182505960598961e-1-1.5707962201708666252e0i) (num-test (acosh -1.19209289550781250e-07+5.0e-01i) 4.8121182505960598961e-1+1.5707964334189266132e0i) (num-test (acosh -1.19209289550781250e-07-5.0e-01i) 4.8121182505960598961e-1-1.5707964334189266132e0i) (num-test (acosh 1.19209289550781250e-07+1.0e+00i) 8.8137358701954553738e-1+1.5707962425011995974e0i) (num-test (acosh 1.19209289550781250e-07-1.0e+00i) 8.8137358701954553738e-1-1.5707962425011995974e0i) (num-test (acosh -1.19209289550781250e-07+1.0e+00i) 8.8137358701954553738e-1+1.5707964110885936410e0i) (num-test (acosh -1.19209289550781250e-07-1.0e+00i) 8.8137358701954553738e-1-1.5707964110885936410e0i) (num-test (acosh 1.19209289550781250e-07+2.0e+00i) 1.4436354751788116136e0+1.5707962734828816222e0i) (num-test (acosh 1.19209289550781250e-07-2.0e+00i) 1.4436354751788116136e0-1.5707962734828816222e0i) (num-test (acosh -1.19209289550781250e-07+2.0e+00i) 1.4436354751788116136e0+1.5707963801069116162e0i) (num-test (acosh -1.19209289550781250e-07-2.0e+00i) 1.4436354751788116136e0-1.5707963801069116162e0i) (num-test (acosh 1.19209289550781250e-07+8.3886080e+06i) 1.6635532333438690979e1+1.5707963267948824084e0i) (num-test (acosh 1.19209289550781250e-07-8.3886080e+06i) 1.6635532333438690979e1-1.5707963267948824084e0i) (num-test (acosh -1.19209289550781250e-07+8.3886080e+06i) 1.6635532333438690979e1+1.5707963267949108301e0i) (num-test (acosh -1.19209289550781250e-07-8.3886080e+06i) 1.6635532333438690979e1-1.5707963267949108301e0i) (num-test (acosh 5.0e-01+0.0e+00i) 0+1.0471975511965977462e0i) (num-test (acosh -5.0e-01+0.0e+00i) 0+2.0943951023931954923e0i) (num-test (acosh 5.0e-01+1.19209289550781250e-07i) 1.3765103082409432364e-7+1.0471975511966032159e0i) (num-test (acosh 5.0e-01-1.19209289550781250e-07i) 1.3765103082409432364e-7-1.0471975511966032159e0i) (num-test (acosh -5.0e-01+1.19209289550781250e-07i) 1.3765103082409432364e-7+2.0943951023931900225e0i) (num-test (acosh -5.0e-01-1.19209289550781250e-07i) 1.3765103082409432364e-7-2.0943951023931900225e0i) (num-test (acosh 5.0e-01+5.0e-01i) 5.3063753095251782602e-1+1.1185178796437059372e0i) (num-test (acosh 5.0e-01-5.0e-01i) 5.3063753095251782602e-1-1.1185178796437059372e0i) (num-test (acosh -5.0e-01+5.0e-01i) 5.3063753095251782602e-1+2.0230747739460873013e0i) (num-test (acosh -5.0e-01-5.0e-01i) 5.3063753095251782602e-1-2.0230747739460873013e0i) (num-test (acosh 5.0e-01+1.0e+00i) 9.2613303135018242455e-1+1.2213572639376833256e0i) (num-test (acosh 5.0e-01-1.0e+00i) 9.2613303135018242455e-1-1.2213572639376833256e0i) (num-test (acosh -5.0e-01+1.0e+00i) 9.2613303135018242455e-1+1.9202353896521099129e0i) (num-test (acosh -5.0e-01-1.0e+00i) 9.2613303135018242455e-1-1.9202353896521099129e0i) (num-test (acosh 5.0e-01+2.0e+00i) 1.4657153519472905218e0+1.3497776911720127603e0i) (num-test (acosh 5.0e-01-2.0e+00i) 1.4657153519472905218e0-1.3497776911720127603e0i) (num-test (acosh -5.0e-01+2.0e+00i) 1.4657153519472905218e0+1.7918149624177804781e0i) (num-test (acosh -5.0e-01-2.0e+00i) 1.4657153519472905218e0-1.7918149624177804781e0i) (num-test (acosh 5.0e-01+8.3886080e+06i) 1.6635532333438692755e1+1.5707962671902518438e0i) (num-test (acosh 5.0e-01-8.3886080e+06i) 1.6635532333438692755e1-1.5707962671902518438e0i) (num-test (acosh -5.0e-01+8.3886080e+06i) 1.6635532333438692755e1+1.5707963863995413946e0i) (num-test (acosh -5.0e-01-8.3886080e+06i) 1.6635532333438692755e1-1.5707963863995413946e0i) (num-test (acosh 1.0e+00+0.0e+00i) 0e0+0.0i) (num-test (acosh -1.0e+00+0.0e+00i) 0+3.1415926535897932385e0i) (num-test (acosh 1.0e+00+1.19209289550781250e-07i) 3.4526698643116312881e-4+3.4526697957132450399e-4i) (num-test (acosh 1.0e+00-1.19209289550781250e-07i) 3.4526698643116312881e-4-3.4526697957132450399e-4i) (num-test (acosh -1.0e+00+1.19209289550781250e-07i) 3.4526698643116312881e-4+3.1412473866102219140e0i) (num-test (acosh -1.0e+00-1.19209289550781250e-07i) 3.4526698643116312881e-4-3.1412473866102219140e0i) (num-test (acosh 1.0e+00+5.0e-01i) 7.3285767597364526089e-1+6.7488884558600638016e-1i) (num-test (acosh 1.0e+00-5.0e-01i) 7.3285767597364526089e-1-6.7488884558600638016e-1i) (num-test (acosh -1.0e+00+5.0e-01i) 7.3285767597364526089e-1+2.4667038080037868583e0i) (num-test (acosh -1.0e+00-5.0e-01i) 7.3285767597364526089e-1-2.4667038080037868583e0i) (num-test (acosh 1.0e+00+1.0e+00i) 1.0612750619050356520e0+9.0455689430238136413e-1i) (num-test (acosh 1.0e+00-1.0e+00i) 1.0612750619050356520e0-9.0455689430238136413e-1i) (num-test (acosh -1.0e+00+1.0e+00i) 1.0612750619050356520e0+2.2370357592874118743e0i) (num-test (acosh -1.0e+00-1.0e+00i) 1.0612750619050356520e0-2.2370357592874118743e0i) (num-test (acosh 1.0e+00+2.0e+00i) 1.5285709194809981613e0+1.1437177404024204938e0i) (num-test (acosh 1.0e+00-2.0e+00i) 1.5285709194809981613e0-1.1437177404024204938e0i) (num-test (acosh -1.0e+00+2.0e+00i) 1.5285709194809981613e0+1.9978749131873727447e0i) (num-test (acosh -1.0e+00-2.0e+00i) 1.5285709194809981613e0-1.9978749131873727447e0i) (num-test (acosh 1.0e+00+8.3886080e+06i) 1.6635532333438698084e1+1.5707962075856070685e0i) (num-test (acosh 1.0e+00-8.3886080e+06i) 1.6635532333438698084e1-1.5707962075856070685e0i) (num-test (acosh -1.0e+00+8.3886080e+06i) 1.6635532333438698084e1+1.570796446004186170e0i) (num-test (acosh -1.0e+00-8.3886080e+06i) 1.6635532333438698084e1-1.570796446004186170e0i) (num-test (acosh 2.0e+00+0.0e+00i) 1.3169578969248167086e0+0.0i) (num-test (acosh -2.0e+00+0.0e+00i) 1.3169578969248167086e0+3.1415926535897932385e0i) (num-test (acosh 2.0e+00+1.19209289550781250e-07i) 1.3169578969248194435e0+6.8825515412047433504e-8i) (num-test (acosh 2.0e+00-1.19209289550781250e-07i) 1.3169578969248194435e0-6.8825515412047433504e-8i) (num-test (acosh -2.0e+00+1.19209289550781250e-07i) 1.3169578969248194435e0+3.1415925847642778264e0i) (num-test (acosh -2.0e+00-1.19209289550781250e-07i) 1.3169578969248194435e0-3.1415925847642778264e0i) (num-test (acosh 2.0e+00+5.0e-01i) 1.3618009008578457882e0+2.7775425655771396018e-1i) (num-test (acosh 2.0e+00-5.0e-01i) 1.3618009008578457882e0-2.7775425655771396018e-1i) (num-test (acosh -2.0e+00+5.0e-01i) 1.3618009008578457882e0+2.8638383970320792783e0i) (num-test (acosh -2.0e+00-5.0e-01i) 1.3618009008578457882e0-2.8638383970320792783e0i) (num-test (acosh 2.0e+00+1.0e+00i) 1.4693517443681852733e0+5.0735630321714456304e-1i) (num-test (acosh 2.0e+00-1.0e+00i) 1.4693517443681852733e0-5.0735630321714456304e-1i) (num-test (acosh -2.0e+00+1.0e+00i) 1.4693517443681852733e0+2.6342363503726486754e0i) (num-test (acosh -2.0e+00-1.0e+00i) 1.4693517443681852733e0-2.6342363503726486754e0i) (num-test (acosh 2.0e+00+2.0e+00i) 1.7343245214879664480e0+8.1654718209685057852e-1i) (num-test (acosh 2.0e+00-2.0e+00i) 1.7343245214879664480e0-8.1654718209685057852e-1i) (num-test (acosh -2.0e+00+2.0e+00i) 1.7343245214879664480e0+2.3250454714929426599e0i) (num-test (acosh -2.0e+00-2.0e+00i) 1.7343245214879664480e0-2.3250454714929426599e0i) (num-test (acosh 2.0e+00+8.3886080e+06i) 1.663553233343871940e1+1.5707960883763175177e0i) (num-test (acosh 2.0e+00-8.3886080e+06i) 1.663553233343871940e1-1.5707960883763175177e0i) (num-test (acosh -2.0e+00+8.3886080e+06i) 1.663553233343871940e1+1.5707965652134757208e0i) (num-test (acosh -2.0e+00-8.3886080e+06i) 1.663553233343871940e1-1.5707965652134757208e0i) (num-test (acosh 8.3886080e+06+0.0e+00i) 1.6635532333438683873e1+0.0i) (num-test (acosh -8.3886080e+06+0.0e+00i) 1.6635532333438683873e1+3.1415926535897932385e0i) (num-test (acosh 8.3886080e+06+1.19209289550781250e-07i) 1.6635532333438683873e1+1.4210854715202104692e-14i) (num-test (acosh 8.3886080e+06-1.19209289550781250e-07i) 1.6635532333438683873e1-1.4210854715202104692e-14i) (num-test (acosh -8.3886080e+06+1.19209289550781250e-07i) 1.6635532333438683873e1+3.1415926535897790276e0i) (num-test (acosh -8.3886080e+06-1.19209289550781250e-07i) 1.6635532333438683873e1-3.1415926535897790276e0i) (num-test (acosh 8.3886080e+06+5.0e-01i) 1.6635532333438685650e1+5.9604644775390977930e-8i) (num-test (acosh 8.3886080e+06-5.0e-01i) 1.6635532333438685650e1-5.9604644775390977930e-8i) (num-test (acosh -8.3886080e+06+5.0e-01i) 1.6635532333438685650e1+3.1415925939851484631e0i) (num-test (acosh -8.3886080e+06-5.0e-01i) 1.6635532333438685650e1-3.1415925939851484631e0i) (num-test (acosh 8.3886080e+06+1.0e+00i) 1.6635532333438690979e1+1.1920928955078153234e-7i) (num-test (acosh 8.3886080e+06-1.0e+00i) 1.6635532333438690979e1-1.1920928955078153234e-7i) (num-test (acosh -8.3886080e+06+1.0e+00i) 1.6635532333438690979e1+3.1415925343805036877e0i) (num-test (acosh -8.3886080e+06-1.0e+00i) 1.6635532333438690979e1-3.1415925343805036877e0i) (num-test (acosh 8.3886080e+06+2.0e+00i) 1.6635532333438712295e1+2.3841857910155967656e-7i) (num-test (acosh 8.3886080e+06-2.0e+00i) 1.6635532333438712295e1-2.3841857910155967656e-7i) (num-test (acosh -8.3886080e+06+2.0e+00i) 1.6635532333438712295e1+3.1415924151712141369e0i) (num-test (acosh -8.3886080e+06-2.0e+00i) 1.6635532333438712295e1-3.1415924151712141369e0i) (num-test (acosh 8.3886080e+06+8.3886080e+06i) 1.6982105923718660081e1+7.8539816339745008597e-1i) (num-test (acosh 8.3886080e+06-8.3886080e+06i) 1.6982105923718660081e1-7.8539816339745008597e-1i) (num-test (acosh -8.3886080e+06+8.3886080e+06i) 1.6982105923718660081e1+2.3561944901923431525e0i) (num-test (acosh -8.3886080e+06-8.3886080e+06i) 1.6982105923718660081e1-2.3561944901923431525e0i) (num-test (acosh -2.225073858507201399999999999999999999996E-308) 0.0+1.570796326794896619231321691639751442098E0i) (num-test (acosh 1.110223024625156799999999999999999999997E-16) 0.0+1.570796326794896508209019229124071442098E0i) (for-each (lambda (num-and-val) (let ((num (car num-and-val)) (val (cadr num-and-val))) (num-test-1 'acosh num (acosh num) val))) (vector (list 0 0+1.5707963267949i) (list 1 0) (list 2 1.3169578969248) (list 3 1.7627471740391) (list -1 0+3.1415926535898i) (list -2 1.3169578969248+3.1415926535898i) (list -3 1.7627471740391+3.1415926535898i) (list 9223372036854775807 44.361419555836) (list -9223372036854775808 44.361419555836+3.1415926535898i) (list 1/2 0+1.0471975511966i) (list 1/3 0+1.2309594173408i) (list -1/2 0+2.0943951023932i) (list -1/3 0+1.910633236249i) (list 1/9223372036854775807 0+1.5707963267949i) (list 0.0 0+1.5707963267949i) (list 1.0 0.0) (list 2.0 1.3169578969248) (list -2.0 1.3169578969248+3.1415926535898i) (list 1.000000000000000000000000000000000000002E-309 0.0+1.570796326794896619231321691639751442098E0i) (list 1e+16 37.534508668465) (list 0+1i 0.88137358701954+1.5707963267949i) (list 0+2i 1.4436354751788+1.5707963267949i) (list 0-1i 0.88137358701954-1.5707963267949i) (list 1+1i 1.061275061905+0.90455689430238i) (list 1-1i 1.061275061905-0.90455689430238i) (list -1+1i 1.061275061905+2.2370357592874i) (list -1-1i 1.061275061905-2.2370357592874i) (list 0.1+0.1i 0.10033029811221+1.4711326239351i) (list 1e+16+1e+16i 37.881082258745+0.78539816339745i) (list 1e-16+1e-16i 0+1.5707963267949i) )) (test (acosh) 'error) (test (acosh "hi") 'error) (test (acosh 1.0+23.0i 1.0+23.0i) 'error) (test (acosh 0 1) 'error) (for-each (lambda (arg) (test (acosh arg) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) ;;; -------------------------------------------------------------------------------- ;;; atanh ;;; -------------------------------------------------------------------------------- (num-test (atanh 0) 0.0) (num-test (atanh 2) 0.54930614433405+1.57079632679490i) (num-test (atanh -2) -0.54930614433405+1.57079632679490i) (num-test (atanh 3) 0.34657359027997+1.57079632679490i) (num-test (atanh -3) -0.34657359027997+1.57079632679490i) (num-test (atanh 10) 0.10033534773108+1.57079632679490i) (num-test (atanh -10) -0.10033534773108+1.57079632679490i) (num-test (atanh 1234) 0.00081037294887+1.57079632679490i) (num-test (atanh -1234) -0.00081037294887+1.57079632679490i) (num-test (atanh 500029) 0.00000199988401+1.57079632679490i) (num-test (atanh -500029) -0.00000199988401+1.57079632679490i) (num-test (atanh 362880) 0.00000275573192+1.57079632679490i) (num-test (atanh -362880) -0.00000275573192+1.57079632679490i) (num-test (atanh 0/1) 0.0) (num-test (atanh 0/2) 0.0) (num-test (atanh 0/3) 0.0) (num-test (atanh 0/10) 0.0) (num-test (atanh 0/1234) 0.0) (num-test (atanh 0/1234000000) 0.0) (num-test (atanh 0/500029) 0.0) (num-test (atanh 0/362880) 0.0) (num-test (atanh 1/2) 0.54930614433405) (num-test (atanh -1/2) -0.54930614433405) (num-test (atanh 1/3) 0.34657359027997) (num-test (atanh -1/3) -0.34657359027997) (num-test (atanh 1/10) 0.10033534773108) (num-test (atanh -1/10) -0.10033534773108) (num-test (atanh 1/1234) 0.00081037294887) (num-test (atanh -1/1234) -0.00081037294887) (num-test (atanh 1/1234000000) 0.00000000081037) (num-test (atanh -1/1234000000) -0.00000000081037) (num-test (atanh 1/500029) 0.00000199988401) (num-test (atanh -1/500029) -0.00000199988401) (num-test (atanh 1/362880) 0.00000275573192) (num-test (atanh -1/362880) -0.00000275573192) (num-test (atanh 2/1) 0.54930614433405+1.57079632679490i) (num-test (atanh -2/1) -0.54930614433405+1.57079632679490i) (num-test (atanh 2/3) 0.80471895621705) (num-test (atanh -2/3) -0.80471895621705) (num-test (atanh 2/10) 0.20273255405408) (num-test (atanh -2/10) -0.20273255405408) (num-test (atanh 2/1234) 0.00162074696209) (num-test (atanh -2/1234) -0.00162074696209) (num-test (atanh 2/1234000000) 0.00000000162075) (num-test (atanh -2/1234000000) -0.00000000162075) (num-test (atanh 2/500029) 0.00000399976801) (num-test (atanh -2/500029) -0.00000399976801) (num-test (atanh 2/362880) 0.00000551146384) (num-test (atanh -2/362880) -0.00000551146384) (num-test (atanh 3/1) 0.34657359027997+1.57079632679490i) (num-test (atanh -3/1) -0.34657359027997+1.57079632679490i) (num-test (atanh 3/2) 0.80471895621705+1.57079632679490i) (num-test (atanh -3/2) -0.80471895621705+1.57079632679490i) (num-test (atanh 3/10) 0.30951960420311) (num-test (atanh -3/10) -0.30951960420311) (num-test (atanh 3/1234) 0.00243112310402) (num-test (atanh -3/1234) -0.00243112310402) (num-test (atanh 3/1234000000) 0.00000000243112) (num-test (atanh -3/1234000000) -0.00000000243112) (num-test (atanh 3/500029) 0.00000599965202) (num-test (atanh -3/500029) -0.00000599965202) (num-test (atanh 3/362880) 0.00000826719577) (num-test (atanh -3/362880) -0.00000826719577) (num-test (atanh 10/1) 0.10033534773108+1.57079632679490i) (num-test (atanh -10/1) -0.10033534773108+1.57079632679490i) (num-test (atanh 10/2) 0.20273255405408+1.57079632679490i) (num-test (atanh -10/2) -0.20273255405408+1.57079632679490i) (num-test (atanh 10/3) 0.30951960420311+1.57079632679490i) (num-test (atanh -10/3) -0.30951960420311+1.57079632679490i) (num-test (atanh 10/1234) 0.00810390511343) (num-test (atanh -10/1234) -0.00810390511343) (num-test (atanh 10/1234000000) 0.00000000810373) (num-test (atanh -10/1234000000) -0.00000000810373) (num-test (atanh 10/500029) 0.00001999884007) (num-test (atanh -10/500029) -0.00001999884007) (num-test (atanh 10/362880) 0.00002755731923) (num-test (atanh -10/362880) -0.00002755731923) (num-test (atanh 1234/1) 0.00081037294887+1.57079632679490i) (num-test (atanh -1234/1) -0.00081037294887+1.57079632679490i) (num-test (atanh 1234/2) 0.00162074696209+1.57079632679490i) (num-test (atanh -1234/2) -0.00162074696209+1.57079632679490i) (num-test (atanh 1234/3) 0.00243112310402+1.57079632679490i) (num-test (atanh -1234/3) -0.00243112310402+1.57079632679490i) (num-test (atanh 1234/10) 0.00810390511343+1.57079632679490i) (num-test (atanh -1234/10) -0.00810390511343+1.57079632679490i) (num-test (atanh 1234/1234000000) 0.00000100000000) (num-test (atanh -1234/1234000000) -0.00000100000000) (num-test (atanh 1234/500029) 0.00246786187433) (num-test (atanh -1234/500029) -0.00246786187433) (num-test (atanh 1234/362880) 0.00340058630029) (num-test (atanh -1234/362880) -0.00340058630029) (num-test (atanh 1234000000/1234) 0.00000100000000+1.57079632679490i) (num-test (atanh -1234000000/1234) -0.00000100000000+1.57079632679490i) (num-test (atanh 1234000000/500029) 0.00040520990873+1.57079632679490i) (num-test (atanh -1234000000/500029) -0.00040520990873+1.57079632679490i) (num-test (atanh 1234000000/362880) 0.00029406807979+1.57079632679490i) (num-test (atanh -1234000000/362880) -0.00029406807979+1.57079632679490i) (num-test (atanh 500029/1) 0.00000199988401+1.57079632679490i) (num-test (atanh -500029/1) -0.00000199988401+1.57079632679490i) (num-test (atanh 500029/2) 0.00000399976801+1.57079632679490i) (num-test (atanh -500029/2) -0.00000399976801+1.57079632679490i) (num-test (atanh 500029/3) 0.00000599965202+1.57079632679490i) (num-test (atanh -500029/3) -0.00000599965202+1.57079632679490i) (num-test (atanh 500029/10) 0.00001999884007+1.57079632679490i) (num-test (atanh -500029/10) -0.00001999884007+1.57079632679490i) (num-test (atanh 500029/1234) 0.00246786187433+1.57079632679490i) (num-test (atanh -500029/1234) -0.00246786187433+1.57079632679490i) (num-test (atanh 500029/1234000000) 0.00040520990873) (num-test (atanh -500029/1234000000) -0.00040520990873) (num-test (atanh 500029/362880) 0.91962065666764+1.57079632679490i) (num-test (atanh -500029/362880) -0.91962065666764+1.57079632679490i) (num-test (atanh 362880/1) 0.00000275573192+1.57079632679490i) (num-test (atanh -362880/1) -0.00000275573192+1.57079632679490i) (num-test (atanh 362880/2) 0.00000551146384+1.57079632679490i) (num-test (atanh -362880/2) -0.00000551146385+1.57079632679490i) (num-test (atanh 362880/3) 0.00000826719577+1.57079632679490i) (num-test (atanh -362880/3) -0.00000826719577+1.57079632679490i) (num-test (atanh 362880/10) 0.00002755731923+1.57079632679490i) (num-test (atanh -362880/10) -0.00002755731923+1.57079632679490i) (num-test (atanh 362880/1234) 0.00340058630029+1.57079632679490i) (num-test (atanh -362880/1234) -0.00340058630029+1.57079632679490i) (num-test (atanh 362880/1234000000) 0.00029406807979) (num-test (atanh -362880/1234000000) -0.00029406807979) (num-test (atanh 362880/500029) 0.91962065666764) (num-test (atanh -362880/500029) -0.91962065666764) (num-test (atanh 0.0) 0.0) (num-test (atanh 0.00000001) 0.00000001) (num-test (atanh -0.00000001) -0.00000001) (num-test (atanh pi) 0.32976531495670+1.57079632679490i) (num-test (atanh -3.14159265358979) -0.32976531495670+1.57079632679490i) (num-test (atanh 2.71828182845905) 0.38596841645265+1.57079632679490i) (num-test (atanh -2.71828182845905) -0.38596841645265+1.57079632679490i) (num-test (atanh 1234.0) 0.00081037294887+1.57079632679490i) (num-test (atanh -1234.0) -0.00081037294887+1.57079632679490i) (num-test (atanh 0.0+0.0i) 0.0) (num-test (atanh -0.0+0.0i) 0.0) (num-test (atanh 0.0-0.0i) 0.0) (num-test (atanh -0.0-0.0i) 0.0) (num-test (atanh 0.0+0.00000001i) 0.0+0.00000001i) (num-test (atanh -0.0+0.00000001i) 0.0+0.00000001i) (num-test (atanh 0.0-0.00000001i) 0.0-0.00000001i) (num-test (atanh -0.0-0.00000001i) 0.0-0.00000001i) (num-test (atanh 0.0+1.0i) -0.0+0.78539816339745i) (num-test (atanh -0.0+1.0i) -0.0+0.78539816339745i) (num-test (atanh 0.0-1.0i) -0.0-0.78539816339745i) (num-test (atanh -0.0-1.0i) -0.0-0.78539816339745i) (num-test (atanh 0.0+3.14159265358979i) -0.0+1.26262725567891i) (num-test (atanh -0.0+3.14159265358979i) -0.0+1.26262725567891i) (num-test (atanh 0.0-3.14159265358979i) -0.0-1.26262725567891i) (num-test (atanh -0.0-3.14159265358979i) -0.0-1.26262725567891i) (num-test (atanh 0.0+2.71828182845905i) -0.0+1.21828290501728i) (num-test (atanh -0.0+2.71828182845905i) -0.0+1.21828290501728i) (num-test (atanh 0.0-2.71828182845905i) -0.0-1.21828290501728i) (num-test (atanh -0.0-2.71828182845905i) -0.0-1.21828290501728i) (num-test (atanh 0.0+1234.0i) 0.0+1.56998595420081i) (num-test (atanh -0.0+1234.0i) 0.0+1.56998595420081i) (num-test (atanh 0.0-1234.0i) 0.0-1.56998595420081i) (num-test (atanh -0.0-1234.0i) 0.0-1.56998595420081i) (num-test (atanh 0.00000001+0.0i) 0.00000001) (num-test (atanh -0.00000001+0.0i) -0.00000001) (num-test (atanh 0.00000001-0.0i) 0.00000001) (num-test (atanh -0.00000001-0.0i) -0.00000001) (num-test (atanh 0.00000001+0.00000001i) 0.00000001+0.00000001i) (num-test (atanh -0.00000001+0.00000001i) -0.00000001+0.00000001i) (num-test (atanh 0.00000001-0.00000001i) 0.00000001-0.00000001i) (num-test (atanh -0.00000001-0.00000001i) -0.00000001-0.00000001i) (num-test (atanh 0.00000001+1.0i) 0.00000000500000+0.78539816339745i) (num-test (atanh -0.00000001+1.0i) -0.00000000500000+0.78539816339745i) (num-test (atanh 0.00000001-1.0i) 0.00000000500000-0.78539816339745i) (num-test (atanh -0.00000001-1.0i) -0.00000000500000-0.78539816339745i) (num-test (atanh 0.00000001+3.14159265358979i) 0.00000000092000+1.26262725567891i) (num-test (atanh -0.00000001+3.14159265358979i) -0.00000000092000+1.26262725567891i) (num-test (atanh 0.00000001-3.14159265358979i) 0.00000000092000-1.26262725567891i) (num-test (atanh -0.00000001-3.14159265358979i) -0.00000000092000-1.26262725567891i) (num-test (atanh 0.00000001+2.71828182845905i) 0.00000000119203+1.21828290501728i) (num-test (atanh -0.00000001+2.71828182845905i) -0.00000000119203+1.21828290501728i) (num-test (atanh 0.00000001-2.71828182845905i) 0.00000000119203-1.21828290501728i) (num-test (atanh -0.00000001-2.71828182845905i) -0.00000000119203-1.21828290501728i) (num-test (atanh 0.00000001+1234.0i) 0.00000000000001+1.56998595420081i) (num-test (atanh -0.00000001+1234.0i) -0.00000000000001+1.56998595420081i) (num-test (atanh 0.00000001-1234.0i) 0.00000000000001-1.56998595420081i) (num-test (atanh -0.00000001-1234.0i) -0.00000000000001-1.56998595420081i) (num-test (atanh 1.0+0.00000001i) 9.55691396225616+0.78539816589745i) (num-test (atanh -1.0+0.00000001i) -9.55691396225615+0.78539816589745i) (num-test (atanh 1.0-0.00000001i) 9.55691396225616-0.78539816589745i) (num-test (atanh -1.0-0.00000001i) -9.55691396225615-0.78539816589745i) (num-test (atanh 1.0+1.0i) 0.40235947810853+1.01722196789785i) (num-test (atanh -1.0+1.0i) -0.40235947810853+1.01722196789785i) (num-test (atanh 1.0-1.0i) 0.40235947810853-1.01722196789785i) (num-test (atanh -1.0-1.0i) -0.40235947810853-1.01722196789785i) (num-test (atanh 1.0+3.14159265358979i) 0.08505998507745+1.28734057432439i) (num-test (atanh -1.0+3.14159265358979i) -0.08505998507745+1.28734057432439i) (num-test (atanh 1.0-3.14159265358979i) 0.08505998507745-1.28734057432439i) (num-test (atanh -1.0-3.14159265358979i) -0.08505998507745-1.28734057432439i) (num-test (atanh 1.0+2.71828182845905i) 0.10816322574795+1.25363416718071i) (num-test (atanh -1.0+2.71828182845905i) -0.10816322574795+1.25363416718071i) (num-test (atanh 1.0-2.71828182845905i) 0.10816322574795-1.25363416718071i) (num-test (atanh -1.0-2.71828182845905i) -0.10816322574795-1.25363416718071i) (num-test (atanh 1.0+1234.0i) 0.00000065670317+1.56998595473299i) (num-test (atanh -1.0+1234.0i) -0.00000065670317+1.56998595473299i) (num-test (atanh 1.0-1234.0i) 0.00000065670317-1.56998595473299i) (num-test (atanh -1.0-1234.0i) -0.00000065670317-1.56998595473299i) (num-test (atanh 3.14159265358979+0.0i) 0.32976531495670+1.57079632679490i) (num-test (atanh -3.14159265358979+0.0i) -0.32976531495670+1.57079632679490i) (num-test (atanh 3.14159265358979-0.0i) 0.32976531495670+1.57079632679490i) (num-test (atanh -3.14159265358979-0.0i) -0.32976531495670+1.57079632679490i) (num-test (atanh 3.14159265358979+0.00000001i) 0.32976531495670+1.57079632566745i) (num-test (atanh -3.14159265358979+0.00000001i) -0.32976531495670+1.57079632566745i) (num-test (atanh 3.14159265358979-0.00000001i) 0.32976531495670-1.57079632566745i) (num-test (atanh -3.14159265358979-0.00000001i) -0.32976531495670-1.57079632566745i) (num-test (atanh 3.14159265358979+1.0i) 0.29462144034086+1.47082882591946i) (num-test (atanh -3.14159265358979+1.0i) -0.29462144034086+1.47082882591946i) (num-test (atanh 3.14159265358979-1.0i) 0.29462144034086-1.47082882591946i) (num-test (atanh -3.14159265358979-1.0i) -0.29462144034086-1.47082882591946i) (num-test (atanh 3.14159265358979+3.14159265358979i) 0.15638868878130+1.40903828502376i) (num-test (atanh -3.14159265358979+3.14159265358979i) -0.15638868878130+1.40903828502376i) (num-test (atanh 3.14159265358979-3.14159265358979i) 0.15638868878130-1.40903828502376i) (num-test (atanh -3.14159265358979-3.14159265358979i) -0.15638868878130-1.40903828502376i) (num-test (atanh 3.14159265358979+2.71828182845905i) 0.17937970703436+1.40945039787275i) (num-test (atanh -3.14159265358979+2.71828182845905i) -0.17937970703436+1.40945039787275i) (num-test (atanh 3.14159265358979-2.71828182845905i) 0.17937970703436-1.40945039787275i) (num-test (atanh -3.14159265358979-2.71828182845905i) -0.17937970703436-1.40945039787275i) (num-test (atanh 3.14159265358979+1234.0i) 0.00000206308183+1.56998595945313i) (num-test (atanh -3.14159265358979+1234.0i) -0.00000206308183+1.56998595945313i) (num-test (atanh 3.14159265358979-1234.0i) 0.00000206308183-1.56998595945313i) (num-test (atanh -3.14159265358979-1234.0i) -0.00000206308183-1.56998595945313i) (num-test (atanh 2.71828182845905+0.0i) 0.38596841645265+1.57079632679490i) (num-test (atanh -2.71828182845905+0.0i) -0.38596841645265+1.57079632679490i) (num-test (atanh 2.71828182845905-0.0i) 0.38596841645265+1.57079632679490i) (num-test (atanh -2.71828182845905-0.0i) -0.38596841645265+1.57079632679490i) (num-test (atanh 2.71828182845905+0.00000001i) 0.38596841645265+1.57079632522972i) (num-test (atanh -2.71828182845905+0.00000001i) -0.38596841645265+1.57079632522972i) (num-test (atanh 2.71828182845905-0.00000001i) 0.38596841645265-1.57079632522972i) (num-test (atanh -2.71828182845905-0.00000001i) -0.38596841645265-1.57079632522972i) (num-test (atanh 2.71828182845905+1.0i) 0.33050259272341+1.43862796047891i) (num-test (atanh -2.71828182845905+1.0i) -0.33050259272341+1.43862796047891i) (num-test (atanh 2.71828182845905-1.0i) 0.33050259272341-1.43862796047891i) (num-test (atanh -2.71828182845905-1.0i) -0.33050259272341-1.43862796047891i) (num-test (atanh 2.71828182845905+3.14159265358979i) 0.15352587926173+1.38641010899673i) (num-test (atanh -2.71828182845905+3.14159265358979i) -0.15352587926173+1.38641010899673i) (num-test (atanh 2.71828182845905-3.14159265358979i) 0.15352587926173-1.38641010899673i) (num-test (atanh -2.71828182845905-3.14159265358979i) -0.15352587926173-1.38641010899673i) (num-test (atanh 2.71828182845905+2.71828182845905i) 0.17963089485802+1.38288382352616i) (num-test (atanh -2.71828182845905+2.71828182845905i) -0.17963089485802+1.38288382352616i) (num-test (atanh 2.71828182845905-2.71828182845905i) 0.17963089485802-1.38288382352616i) (num-test (atanh -2.71828182845905-2.71828182845905i) -0.17963089485802-1.38288382352616i) (num-test (atanh 2.71828182845905+1234.0i) 0.00000178509679+1.56998595813306i) (num-test (atanh -2.71828182845905+1234.0i) -0.00000178509679+1.56998595813306i) (num-test (atanh 2.71828182845905-1234.0i) 0.00000178509679-1.56998595813306i) (num-test (atanh -2.71828182845905-1234.0i) -0.00000178509679-1.56998595813306i) (num-test (atanh 1234.0+0.0i) 0.00081037294887+1.57079632679490i) (num-test (atanh -1234.0+0.0i) -0.00081037294887+1.57079632679490i) (num-test (atanh 1234.0-0.0i) 0.00081037294887+1.57079632679490i) (num-test (atanh -1234.0-0.0i) -0.00081037294887+1.57079632679490i) (num-test (atanh 1234.0+0.00000001i) 0.00081037294887+1.57079632679489i) (num-test (atanh -1234.0+0.00000001i) -0.00081037294887+1.57079632679489i) (num-test (atanh 1234.0-0.00000001i) 0.00081037294887-1.57079632679489i) (num-test (atanh -1234.0-0.00000001i) -0.00081037294887-1.57079632679489i) (num-test (atanh 1234.0+1.0i) 0.00081037241669+1.57079567009087i) (num-test (atanh -1234.0+1.0i) -0.00081037241669+1.57079567009087i) (num-test (atanh 1234.0-1.0i) 0.00081037241669-1.57079567009087i) (num-test (atanh -1234.0-1.0i) -0.00081037241669-1.57079567009087i) (num-test (atanh 1234.0+3.14159265358979i) 0.00081036769654+1.57079426371036i) (num-test (atanh -1234.0+3.14159265358979i) -0.00081036769654+1.57079426371036i) (num-test (atanh 1234.0-3.14159265358979i) 0.00081036769654-1.57079426371036i) (num-test (atanh -1234.0-3.14159265358979i) -0.00081036769654-1.57079426371036i) (num-test (atanh 1234.0+2.71828182845905i) 0.00081036901661+1.57079454169576i) (num-test (atanh -1234.0+2.71828182845905i) -0.00081036901661+1.57079454169576i) (num-test (atanh 1234.0-2.71828182845905i) 0.00081036901661-1.57079454169576i) (num-test (atanh -1234.0-2.71828182845905i) -0.00081036901661-1.57079454169576i) (num-test (atanh 1234.0+1234.0i) 0.00040518634139+1.57039114036481i) (num-test (atanh -1234.0+1234.0i) -0.00040518634139+1.57039114036481i) (num-test (atanh 1234.0-1234.0i) 0.00040518634139-1.57039114036481i) (num-test (atanh -1234.0-1234.0i) -0.00040518634139-1.57039114036481i) (num-test (atanh -1.0e+01) -1.0033534773107558064e-1+1.5707963267948966192e0i) (num-test (atanh -2.0e+00) -5.4930614433405484570e-1+1.5707963267948966192e0i) (num-test (atanh -7.50e-01) -9.7295507452765665255e-1+0.0i) (num-test (atanh -5.0e-01) -5.4930614433405484570e-1+0.0i) (num-test (atanh -1.250e-01) -1.2565721414045303884e-1+0.0i) (num-test (atanh -3.45266983001243932001e-04) -3.4526699672092216295e-4+0.0i) (num-test (atanh -1.19209289550781250e-07) -1.1920928955078181469e-7+0.0i) (num-test (atanh 0.0e+00) 0e0+0.0i) (num-test (atanh 1.19209289550781250e-07) 1.1920928955078181469e-7+0.0i) (num-test (atanh 3.45266983001243932001e-04) 3.4526699672092216295e-4+0.0i) (num-test (atanh 1.250e-01) 1.2565721414045303884e-1+0.0i) (num-test (atanh 5.0e-01) 5.4930614433405484570e-1+0.0i) (num-test (atanh 7.50e-01) 9.7295507452765665255e-1+0.0i) (num-test (atanh 2.0e+00) 5.4930614433405484570e-1-1.5707963267948966192e0i) (num-test (atanh 1.0e+01) 1.0033534773107558064e-1-1.5707963267948966192e0i) (num-test (atanh 2.8147497671066e+14) 3.552713678800501e-15-1.570796326794897i) (num-test (atanh 0.0e+00+0.0e+00i) 0e0+0.0i) (num-test (atanh 0.0e+00+1.19209289550781250e-07i) 0+1.1920928955078068531e-7i) (num-test (atanh 0.0e+00-1.19209289550781250e-07i) 0-1.1920928955078068531e-7i) (num-test (atanh 0.0e+00+5.0e-01i) 0+4.6364760900080611621e-1i) (num-test (atanh 0.0e+00-5.0e-01i) 0-4.6364760900080611621e-1i) (num-test (atanh 0.0e+00+1.0e+00i) 0+7.8539816339744830962e-1i) (num-test (atanh 0.0e+00-1.0e+00i) 0-7.8539816339744830962e-1i) (num-test (atanh 0.0e+00+2.0e+00i) 0+1.1071487177940905030e0i) (num-test (atanh 0.0e+00-2.0e+00i) 0-1.1071487177940905030e0i) (num-test (atanh 0.0e+00+8.3886080e+06i) 0+1.5707962075856070685e0i) (num-test (atanh 0.0e+00-8.3886080e+06i) 0-1.5707962075856070685e0i) (num-test (atanh 1.19209289550781250e-07+0.0e+00i) 1.1920928955078181469e-7+0.0i) (num-test (atanh -1.19209289550781250e-07+0.0e+00i) -1.1920928955078181469e-7+0.0i) (num-test (atanh 1.19209289550781250e-07+1.19209289550781250e-07i) 1.1920928955078012062e-7+1.1920928955078237938e-7i) (num-test (atanh 1.19209289550781250e-07-1.19209289550781250e-07i) 1.1920928955078012062e-7-1.1920928955078237938e-7i) (num-test (atanh -1.19209289550781250e-07+1.19209289550781250e-07i) -1.1920928955078012062e-7+1.1920928955078237938e-7i) (num-test (atanh -1.19209289550781250e-07-1.19209289550781250e-07i) -1.1920928955078012062e-7-1.1920928955078237938e-7i) (num-test (atanh 1.19209289550781250e-07+5.0e-01i) 9.5367431640625072280e-8+4.6364760900081066369e-1i) (num-test (atanh 1.19209289550781250e-07-5.0e-01i) 9.5367431640625072280e-8-4.6364760900081066369e-1i) (num-test (atanh -1.19209289550781250e-07+5.0e-01i) -9.5367431640625072280e-8+4.6364760900081066369e-1i) (num-test (atanh -1.19209289550781250e-07-5.0e-01i) -9.5367431640625072280e-8-4.6364760900081066369e-1i) (num-test (atanh 1.19209289550781250e-07+1.0e+00i) 5.9604644775390483828e-8+7.8539816339745186233e-1i) (num-test (atanh 1.19209289550781250e-07-1.0e+00i) 5.9604644775390483828e-8-7.8539816339745186233e-1i) (num-test (atanh -1.19209289550781250e-07+1.0e+00i) -5.9604644775390483828e-8+7.8539816339745186233e-1i) (num-test (atanh -1.19209289550781250e-07-1.0e+00i) -5.9604644775390483828e-8-7.8539816339745186233e-1i) (num-test (atanh 1.19209289550781250e-07+2.0e+00i) 2.3841857910156200307e-8+1.1071487177940916399e0i) (num-test (atanh 1.19209289550781250e-07-2.0e+00i) 2.3841857910156200307e-8-1.1071487177940916399e0i) (num-test (atanh -1.19209289550781250e-07+2.0e+00i) -2.3841857910156200307e-8+1.1071487177940916399e0i) (num-test (atanh -1.19209289550781250e-07-2.0e+00i) -2.3841857910156200307e-8-1.1071487177940916399e0i) (num-test (atanh 1.19209289550781250e-07+8.3886080e+06i) 1.6940658945085766040e-21+1.5707962075856070685e0i) (num-test (atanh 1.19209289550781250e-07-8.3886080e+06i) 1.6940658945085766040e-21-1.5707962075856070685e0i) (num-test (atanh -1.19209289550781250e-07+8.3886080e+06i) -1.6940658945085766040e-21+1.5707962075856070685e0i) (num-test (atanh -1.19209289550781250e-07-8.3886080e+06i) -1.6940658945085766040e-21-1.5707962075856070685e0i) (num-test (atanh 5.0e-01+0.0e+00i) 5.4930614433405484570e-1+0.0i) (num-test (atanh -5.0e-01+0.0e+00i) -5.4930614433405484570e-1+0.0i) (num-test (atanh 5.0e-01+1.19209289550781250e-07i) 5.4930614433404221383e-1+1.5894571940103932425e-7i) (num-test (atanh 5.0e-01-1.19209289550781250e-07i) 5.4930614433404221383e-1-1.5894571940103932425e-7i) (num-test (atanh -5.0e-01+1.19209289550781250e-07i) -5.4930614433404221383e-1+1.5894571940103932425e-7i) (num-test (atanh -5.0e-01-1.19209289550781250e-07i) -5.4930614433404221383e-1-1.5894571940103932425e-7i) (num-test (atanh 5.0e-01+5.0e-01i) 4.0235947810852509365e-1+5.5357435889704525151e-1i) (num-test (atanh 5.0e-01-5.0e-01i) 4.0235947810852509365e-1-5.5357435889704525151e-1i) (num-test (atanh -5.0e-01+5.0e-01i) -4.0235947810852509365e-1+5.5357435889704525151e-1i) (num-test (atanh -5.0e-01-5.0e-01i) -4.0235947810852509365e-1-5.5357435889704525151e-1i) (num-test (atanh 5.0e-01+1.0e+00i) 2.3887786125685909036e-1+8.4757566067082902713e-1i) (num-test (atanh 5.0e-01-1.0e+00i) 2.3887786125685909036e-1-8.4757566067082902713e-1i) (num-test (atanh -5.0e-01+1.0e+00i) -2.3887786125685909036e-1+8.4757566067082902713e-1i) (num-test (atanh -5.0e-01-1.0e+00i) -2.3887786125685909036e-1-8.4757566067082902713e-1i) (num-test (atanh 5.0e-01+2.0e+00i) 9.6415620202996167238e-2+1.1265564408348223487e0i) (num-test (atanh 5.0e-01-2.0e+00i) 9.6415620202996167238e-2-1.1265564408348223487e0i) (num-test (atanh -5.0e-01+2.0e+00i) -9.6415620202996167238e-2+1.1265564408348223487e0i) (num-test (atanh -5.0e-01-2.0e+00i) -9.6415620202996167238e-2-1.1265564408348223487e0i) (num-test (atanh 5.0e-01+8.3886080e+06i) 7.1054273576008756410e-15+1.5707962075856070685e0i) (num-test (atanh 5.0e-01-8.3886080e+06i) 7.1054273576008756410e-15-1.5707962075856070685e0i) (num-test (atanh -5.0e-01+8.3886080e+06i) -7.1054273576008756410e-15+1.5707962075856070685e0i) (num-test (atanh -5.0e-01-8.3886080e+06i) -7.1054273576008756410e-15-1.5707962075856070685e0i) (num-test (atanh 1.0e+00+1.19209289550781250e-07i) 8.3177661667193446012e0+7.8539819319977069731e-1i) (num-test (atanh 1.0e+00-1.19209289550781250e-07i) 8.3177661667193446012e0-7.8539819319977069731e-1i) (num-test (atanh -1.0e+00+1.19209289550781250e-07i) -8.3177661667193446012e0+7.8539819319977069731e-1i) (num-test (atanh -1.0e+00-1.19209289550781250e-07i) -8.3177661667193446012e0-7.8539819319977069731e-1i) (num-test (atanh 1.0e+00+5.0e-01i) 7.0830333601405402006e-1+9.0788749496088038670e-1i) (num-test (atanh 1.0e+00-5.0e-01i) 7.0830333601405402006e-1-9.0788749496088038670e-1i) (num-test (atanh -1.0e+00+5.0e-01i) -7.0830333601405402006e-1+9.0788749496088038670e-1i) (num-test (atanh -1.0e+00-5.0e-01i) -7.0830333601405402006e-1-9.0788749496088038670e-1i) (num-test (atanh 1.0e+00+1.0e+00i) 4.0235947810852509365e-1+1.0172219678978513677e0i) (num-test (atanh 1.0e+00-1.0e+00i) 4.0235947810852509365e-1-1.0172219678978513677e0i) (num-test (atanh -1.0e+00+1.0e+00i) -4.0235947810852509365e-1+1.0172219678978513677e0i) (num-test (atanh -1.0e+00-1.0e+00i) -4.0235947810852509365e-1-1.0172219678978513677e0i) (num-test (atanh 1.0e+00+2.0e+00i) 1.7328679513998632735e-1+1.1780972450961724644e0i) (num-test (atanh 1.0e+00-2.0e+00i) 1.7328679513998632735e-1-1.1780972450961724644e0i) (num-test (atanh -1.0e+00+2.0e+00i) -1.7328679513998632735e-1+1.1780972450961724644e0i) (num-test (atanh -1.0e+00-2.0e+00i) -1.7328679513998632735e-1-1.1780972450961724644e0i) (num-test (atanh 1.0e+00+8.3886080e+06i) 1.4210854715201599821e-14+1.5707962075856070685e0i) (num-test (atanh 1.0e+00-8.3886080e+06i) 1.4210854715201599821e-14-1.5707962075856070685e0i) (num-test (atanh -1.0e+00+8.3886080e+06i) -1.4210854715201599821e-14+1.5707962075856070685e0i) (num-test (atanh -1.0e+00-8.3886080e+06i) -1.4210854715201599821e-14-1.5707962075856070685e0i) (num-test (atanh 2.0e+00+0.0e+00i) 5.4930614433405484570e-1-1.5707963267948966192e0i) (num-test (atanh -2.0e+00+0.0e+00i) -5.4930614433405484570e-1+1.5707963267948966192e0i) (num-test (atanh 2.0e+00+1.19209289550781250e-07i) 5.4930614433405168773e-1+1.5707962870584667690e0i) (num-test (atanh 2.0e+00-1.19209289550781250e-07i) 5.4930614433405168773e-1-1.5707962870584667690e0i) (num-test (atanh -2.0e+00+1.19209289550781250e-07i) -5.4930614433405168773e-1+1.5707962870584667690e0i) (num-test (atanh -2.0e+00-1.19209289550781250e-07i) -5.4930614433405168773e-1-1.5707962870584667690e0i) (num-test (atanh 2.0e+00+5.0e-01i) 5.0037000005253101744e-1+1.4215468610018069803e0i) (num-test (atanh 2.0e+00-5.0e-01i) 5.0037000005253101744e-1-1.4215468610018069803e0i) (num-test (atanh -2.0e+00+5.0e-01i) -5.0037000005253101744e-1+1.4215468610018069803e0i) (num-test (atanh -2.0e+00-5.0e-01i) -5.0037000005253101744e-1-1.4215468610018069803e0i) (num-test (atanh 2.0e+00+1.0e+00i) 4.0235947810852509365e-1+1.3389725222944935611e0i) (num-test (atanh 2.0e+00-1.0e+00i) 4.0235947810852509365e-1-1.3389725222944935611e0i) (num-test (atanh -2.0e+00+1.0e+00i) -4.0235947810852509365e-1+1.3389725222944935611e0i) (num-test (atanh -2.0e+00-1.0e+00i) -4.0235947810852509365e-1-1.3389725222944935611e0i) (num-test (atanh 2.0e+00+2.0e+00i) 2.3887786125685909036e-1+1.3112232696716351433e0i) (num-test (atanh 2.0e+00-2.0e+00i) 2.3887786125685909036e-1-1.3112232696716351433e0i) (num-test (atanh -2.0e+00+2.0e+00i) -2.3887786125685909036e-1+1.3112232696716351433e0i) (num-test (atanh -2.0e+00-2.0e+00i) -2.3887786125685909036e-1-1.3112232696716351433e0i) (num-test (atanh 2.0e+00+8.3886080e+06i) 2.8421709430401987951e-14+1.5707962075856070685e0i) (num-test (atanh 2.0e+00-8.3886080e+06i) 2.8421709430401987951e-14-1.5707962075856070685e0i) (num-test (atanh -2.0e+00+8.3886080e+06i) -2.8421709430401987951e-14+1.5707962075856070685e0i) (num-test (atanh -2.0e+00-8.3886080e+06i) -2.8421709430401987951e-14-1.5707962075856070685e0i) (num-test (atanh 8.3886080e+06+0.0e+00i) 1.1920928955078181469e-7-1.5707963267948966192e0i) (num-test (atanh -8.3886080e+06+0.0e+00i) -1.1920928955078181469e-7+1.5707963267948966192e0i) (num-test (atanh 8.3886080e+06+1.19209289550781250e-07i) 1.1920928955078181469e-7+1.5707963267948966192e0i) (num-test (atanh 8.3886080e+06-1.19209289550781250e-07i) 1.1920928955078181469e-7-1.5707963267948966192e0i) (num-test (atanh -8.3886080e+06+1.19209289550781250e-07i) -1.1920928955078181469e-7+1.5707963267948966192e0i) (num-test (atanh -8.3886080e+06-1.19209289550781250e-07i) -1.1920928955078181469e-7-1.5707963267948966192e0i) (num-test (atanh 8.3886080e+06+5.0e-01i) 1.1920928955078139117e-7+1.5707963267948895138e0i) (num-test (atanh 8.3886080e+06-5.0e-01i) 1.1920928955078139117e-7-1.5707963267948895138e0i) (num-test (atanh -8.3886080e+06+5.0e-01i) -1.1920928955078139117e-7+1.5707963267948895138e0i) (num-test (atanh -8.3886080e+06-5.0e-01i) -1.1920928955078139117e-7-1.5707963267948895138e0i) (num-test (atanh 8.3886080e+06+1.0e+00i) 1.1920928955078012062e-7+1.5707963267948824084e0i) (num-test (atanh 8.3886080e+06-1.0e+00i) 1.1920928955078012062e-7-1.5707963267948824084e0i) (num-test (atanh -8.3886080e+06+1.0e+00i) -1.1920928955078012062e-7+1.5707963267948824084e0i) (num-test (atanh -8.3886080e+06-1.0e+00i) -1.1920928955078012062e-7-1.5707963267948824084e0i) (num-test (atanh 8.3886080e+06+2.0e+00i) 1.1920928955077503843e-7+1.5707963267948681975e0i) (num-test (atanh 8.3886080e+06-2.0e+00i) 1.1920928955077503843e-7-1.5707963267948681975e0i) (num-test (atanh -8.3886080e+06+2.0e+00i) -1.1920928955077503843e-7+1.5707963267948681975e0i) (num-test (atanh -8.3886080e+06-2.0e+00i) -1.1920928955077503843e-7-1.5707963267948681975e0i) (num-test (atanh 8.3886080e+06+8.3886080e+06i) 5.9604644775390483828e-8+1.5707962671902518438e0i) (num-test (atanh 8.3886080e+06-8.3886080e+06i) 5.9604644775390483828e-8-1.5707962671902518438e0i) (num-test (atanh -8.3886080e+06+8.3886080e+06i) -5.9604644775390483828e-8+1.5707962671902518438e0i) (num-test (atanh -8.3886080e+06-8.3886080e+06i) -5.9604644775390483828e-8-1.5707962671902518438e0i) (num-test (atanh -2.225073858507201399999999999999999999996E-308) -2.225073858507201399999999999999999999996E-308) (num-test (atanh 1.110223024625156799999999999999999999997E-16) 1.110223024625156800000000000000004561517E-16) (if with-bignums (begin (num-test (atanh 9223372036854775/9223372036854776) 1.872683213842718135862772724835833552118E1) (num-test (atanh 92233720368547758/92233720368547757) 1.987812468492420421418925039646711911969E1+1.570796326794896619231321691639751442098E0i) (num-test (atanh 9223372036854775806/9223372036854775807) 2.218070977791824990127011272372523734584E1) (num-test (atanh 9223372036854775807/9223372036854775806) 2.218070977791824990127013919350483904273E1+1.570796326794896619231321691639751442098E0i) )) (test (atanh) 'error) (test (atanh "hi") 'error) (test (atanh 1.0+23.0i 1.0+23.0i) 'error) (test (atanh 0 1) 'error) (for-each (lambda (arg) (test (atanh arg) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) (let ((err 0.0) (mx 0.0)) (do ((i 0 (+ i 1)) (x 1.0 (+ x .1))) ((= i 100)) (let ((y (abs (- x (cosh (acosh x)))))) (if (> y err) (begin (set! mx x) (set! err y))))) (if (> err 1e-14) (format-logged #t ";(cosh (acosh ~A)) error: ~A~%" mx err))) (let ((err 0.0) (mx 0.0)) (do ((i 0 (+ i 1)) (x 1.0+i (+ x 0.1-0.1i))) ((= i 100)) (let ((y (magnitude (- x (cosh (acosh x)))))) (if (> y err) (begin (set! mx x) (set! err y))))) (if (> err 1e-14) (format-logged #t ";(cosh (acosh ~A)) error: ~A~%" mx err))) (let ((err 0.0) (mx 0.0)) (do ((i 0 (+ i 1)) (x 1.0 (+ x .1))) ((= i 100)) (let ((y (abs (- x (sinh (asinh x)))))) (if (> y err) (begin (set! mx x) (set! err y))))) (if (> err 1e-14) (format-logged #t ";(sinh (asinh ~A)) error: ~A~%" mx err))) (let ((err 0.0) (mx 0.0)) (do ((i 0 (+ i 1)) (x 1.0-i (+ x -0.1+i))) ((= i 100)) (let ((y (magnitude (- x (sinh (asinh x)))))) (if (> y err) (begin (set! mx x) (set! err y))))) (if (> err 1e-9) (format-logged #t ";(sinh (asinh ~A)) error: ~A~%" mx err))) (let ((err 0.0) (mx 0.0)) (do ((i 0 (+ i 1)) (x 0.0 (+ x .1))) ((= i 100)) (let ((y (magnitude (- x (tanh (atanh x)))))) (if (> y err) (begin (set! mx x) (set! err y))))) (if (> err 1e-12) (format-logged #t ";(tanh (atanh ~A)) error: ~A~%" mx err))) (for-each (lambda (num-and-val) (let ((num (car num-and-val)) (val (cadr num-and-val))) (num-test-1 'atanh num (atanh num) val))) (vector (list 0 0) (list 2 0.54930614433405+1.5707963267949i) (list 3 0.34657359027997+1.5707963267949i) (list -2 -0.54930614433405+1.5707963267949i) (list -3 -0.34657359027997+1.5707963267949i) (list 9223372036854775807 -1.6740081543176e-15+1.5707963267949i) (list -9223372036854775808 -1.6740081543176e-15+1.5707963267949i) (list 1/2 0.54930614433405) (list 1/3 0.34657359027997) (list -1/2 -0.54930614433405) (list -1/3 -0.34657359027997) (list 1/9223372036854775807 1.0842021724855e-19) (list 0.0 0.0) (list 2.0 0.54930614433405+1.5707963267949i) (list -2.0 -0.54930614433405+1.5707963267949i) (list 1.000000000000000000000000000000000000002E-309 1.000000000000000000000000000000000000002E-309) (list 1e+16 1.7676832220204e-15+1.5707963267949i) (list inf.0 0+1.5707963267949i) (list -inf.0 -0+1.5707963267949i) (list 0+1i -5.8004816227974e-18+0.78539816339745i) (list 0+2i -2.320192649119e-17+1.1071487177941i) (list 0-1i -5.8004816227974e-18-0.78539816339745i) (list 1+1i 0.40235947810853+1.0172219678979i) (list 1-1i 0.40235947810853-1.0172219678979i) (list -1+1i -0.40235947810853+1.0172219678979i) (list -1-1i -0.40235947810853-1.0172219678979i) (list 0.1+0.1i 0.099325449367251+0.10065855418732i) (list 1e+16+1e+16i -1.3183898417424e-15+1.5707963267949i) (list 1e-16+1e-16i 1.1102230246252e-16+1e-16i) )) ;;; -------------------------------------------------------------------------------- ;;; sqrt ;;; -------------------------------------------------------------------------------- (num-test (sqrt 0) 0) (num-test (sqrt 1) 1) (num-test (sqrt -1) 0.0+1.0i) (num-test (sqrt 2) 1.41421356237310) (num-test (sqrt -2) 0.0+1.41421356237310i) (num-test (sqrt 3) 1.73205080756888) (num-test (sqrt -3) 0.0+1.73205080756888i) (num-test (sqrt 10) 3.16227766016838) (num-test (sqrt -10) 0.0+3.16227766016838i) (num-test (sqrt 1234) 35.12833614050059) (num-test (sqrt -1234) 0.0+35.12833614050059i) (num-test (sqrt 1234000000) 35128.33614050059259) (num-test (sqrt -1234000000) 0.0+35128.33614050059259i) (num-test (sqrt 500029) 707.12728698587216) (num-test (sqrt -500029) 0.0+707.12728698587216i) (num-test (sqrt 362880) 602.39521910453436) (num-test (sqrt -362880) 0.0+602.39521910453436i) (num-test (sqrt 0/1) 0) (num-test (sqrt 0/2) 0) (num-test (sqrt 0/3) 0) (num-test (sqrt 0/10) 0) (num-test (sqrt 0/1234) 0) (num-test (sqrt 0/1234000000) 0) (num-test (sqrt 0/500029) 0) (num-test (sqrt 0/362880) 0) (num-test (sqrt 1/1) 1) (num-test (sqrt -1/1) 0.0+1.0i) (num-test (sqrt 1/2) 0.70710678118655) (num-test (sqrt -1/2) 0.0+0.70710678118655i) (num-test (sqrt 1/3) 0.57735026918963) (num-test (sqrt -1/3) 0.0+0.57735026918963i) (num-test (sqrt 1/10) 0.31622776601684) (num-test (sqrt -1/10) 0.0+0.31622776601684i) (num-test (sqrt 1/1234) 0.02846704711548) (num-test (sqrt -1/1234) 0.0+0.02846704711548i) (num-test (sqrt 1/1234000000) 0.00002846704712) (num-test (sqrt -1/1234000000) 0.0+0.00002846704712i) (num-test (sqrt 1/500029) 0.00141417255196) (num-test (sqrt -1/500029) 0.0+0.00141417255196i) (num-test (sqrt 1/362880) 0.00166003973519) (num-test (sqrt -1/362880) 0.0+0.00166003973519i) (num-test (sqrt 2/1) 1.41421356237310) (num-test (sqrt -2/1) 0.0+1.41421356237310i) (num-test (sqrt 2/2) 1) (num-test (sqrt -2/2) 0.0+1.0i) (num-test (sqrt 2/3) 0.81649658092773) (num-test (sqrt -2/3) 0.0+0.81649658092773i) (num-test (sqrt 2/10) 0.44721359549996) (num-test (sqrt -2/10) 0.0+0.44721359549996i) (num-test (sqrt 2/1234) 0.04025848411142) (num-test (sqrt -2/1234) 0.0+0.04025848411142i) (num-test (sqrt 2/1234000000) 0.00004025848411) (num-test (sqrt -2/1234000000) 0.0+0.00004025848411i) (num-test (sqrt 2/500029) 0.00199994200252) (num-test (sqrt -2/500029) 0.0+0.00199994200252i) (num-test (sqrt 2/362880) 0.00234765070758) (num-test (sqrt -2/362880) 0.0+0.00234765070758i) (num-test (sqrt 3/1) 1.73205080756888) (num-test (sqrt -3/1) 0.0+1.73205080756888i) (num-test (sqrt 3/2) 1.22474487139159) (num-test (sqrt -3/2) 0.0+1.22474487139159i) (num-test (sqrt 3/3) 1) (num-test (sqrt -3/3) 0.0+1.0i) (num-test (sqrt 3/10) 0.54772255750517) (num-test (sqrt -3/10) 0.0+0.54772255750517i) (num-test (sqrt 3/1234) 0.04930637194547) (num-test (sqrt -3/1234) 0.0+0.04930637194547i) (num-test (sqrt 3/1234000000) 0.00004930637195) (num-test (sqrt -3/1234000000) 0.0+0.00004930637195i) (num-test (sqrt 3/500029) 0.00244941871067) (num-test (sqrt -3/500029) 0.0+0.00244941871067i) (num-test (sqrt 3/362880) 0.00287527316393) (num-test (sqrt -3/362880) 0.0+0.00287527316393i) (num-test (sqrt 10/1) 3.16227766016838) (num-test (sqrt -10/1) 0.0+3.16227766016838i) (num-test (sqrt 10/2) 2.23606797749979) (num-test (sqrt -10/2) 0.0+2.23606797749979i) (num-test (sqrt 10/3) 1.82574185835055) (num-test (sqrt -10/3) 0.0+1.82574185835055i) (num-test (sqrt 10/10) 1) (num-test (sqrt -10/10) 0.0+1.0i) (num-test (sqrt 10/1234) 0.09002070714424) (num-test (sqrt -10/1234) 0.0+0.09002070714424i) (num-test (sqrt 10/1234000000) 0.00009002070714) (num-test (sqrt -10/1234000000) 0.0+0.00009002070714i) (num-test (sqrt 10/500029) 0.00447200626870) (num-test (sqrt -10/500029) 0.0+0.00447200626870i) (num-test (sqrt 10/362880) 0.00524950656957) (num-test (sqrt -10/362880) 0.0+0.00524950656957i) (num-test (sqrt 1234/1) 35.12833614050059) (num-test (sqrt -1234/1) 0.0+35.12833614050059i) (num-test (sqrt 1234/2) 24.83948469674844) (num-test (sqrt -1234/2) 0.0+24.83948469674844i) (num-test (sqrt 1234/3) 20.28135432690167) (num-test (sqrt -1234/3) 0.0+20.28135432690167i) (num-test (sqrt 1234/10) 11.10855526159905) (num-test (sqrt -1234/10) 0.0+11.10855526159905i) (num-test (sqrt 1234/1234) 1) (num-test (sqrt -1234/1234) 0.0+1.0i) (num-test (sqrt 1234/1234000000) 0.001) (num-test (sqrt -1234/1234000000) 0.0+0.001i) (num-test (sqrt 1234/500029) 0.04967752876605) (num-test (sqrt -1234/500029) 0.0+0.04967752876605i) (num-test (sqrt 1234/362880) 0.05831443382422) (num-test (sqrt -1234/362880) 0.0+0.05831443382422i) (num-test (sqrt 1234000000/1) 35128.33614050059259) (num-test (sqrt -1234000000/1) 0.0+35128.33614050059259i) (num-test (sqrt 1234000000/2) 24839.48469674844091) (num-test (sqrt -1234000000/2) 0.0+24839.48469674844091i) (num-test (sqrt 1234000000/3) 20281.35432690167727) (num-test (sqrt -1234000000/3) 0.0+20281.35432690167727i) (num-test (sqrt 1234000000/10) 11108.55526159905276) (num-test (sqrt -1234000000/10) 0.0+11108.55526159905276i) (num-test (sqrt 1234000000/1234) 1000) (num-test (sqrt -1234000000/1234) 0.0+1000.0i) (num-test (sqrt 1234000000/1234000000) 1) (num-test (sqrt -1234000000/1234000000) 0.0+1.0i) (num-test (sqrt 1234000000/500029) 49.67752876605147) (num-test (sqrt -1234000000/500029) 0.0+49.67752876605147i) (num-test (sqrt 1234000000/362880) 58.31443382422451) (num-test (sqrt -1234000000/362880) 0.0+58.31443382422451i) (num-test (sqrt 500029/1) 707.12728698587216) (num-test (sqrt -500029/1) 0.0+707.12728698587216i) (num-test (sqrt 500029/2) 500.01449978975609) (num-test (sqrt -500029/2) 0.0+500.01449978975609i) (num-test (sqrt 500029/3) 408.26012949262304) (num-test (sqrt -500029/3) 0.0+408.26012949262304i) (num-test (sqrt 500029/10) 223.61328225308978) (num-test (sqrt -500029/10) 0.0+223.61328225308978i) (num-test (sqrt 500029/1234) 20.12982579526738) (num-test (sqrt -500029/1234) 0.0+20.12982579526738i) (num-test (sqrt 500029/1234000000) 0.02012982579527) (num-test (sqrt -500029/1234000000) 0.0+0.02012982579527i) (num-test (sqrt 500029/500029) 1) (num-test (sqrt -500029/500029) 0.0+1.0i) (num-test (sqrt 500029/362880) 1.17385939423129) (num-test (sqrt -500029/362880) 0.0+1.17385939423129i) (num-test (sqrt 362880/1) 602.39521910453436) (num-test (sqrt -362880/1) 0.0+602.39521910453436i) (num-test (sqrt 362880/2) 425.95774438317238) (num-test (sqrt -362880/2) 0.0+425.95774438317238i) (num-test (sqrt 362880/3) 347.79304190854651) (num-test (sqrt -362880/3) 0.0+347.79304190854651i) (num-test (sqrt 362880/10) 190.49409439665052) (num-test (sqrt -362880/10) 0.0+190.49409439665052i) (num-test (sqrt 362880/1234) 17.14841308438784) (num-test (sqrt -362880/1234) 0.0+17.14841308438784i) (num-test (sqrt 362880/1234000000) 0.01714841308439) (num-test (sqrt -362880/1234000000) 0.0+0.01714841308439i) (num-test (sqrt 362880/500029) 0.85189078429181) (num-test (sqrt -362880/500029) 0.0+0.85189078429181i) (num-test (sqrt 362880/362880) 1) (num-test (sqrt -362880/362880) 0.0+1.0i) (num-test (sqrt 0.0) 0.0) (num-test (sqrt 0.00000001) 0.00010000000000) (num-test (sqrt -0.00000001) 0.0+0.00010000000000i) (num-test (sqrt 1.0) 1.0) (num-test (sqrt -1.0) 0.0+1.0i) (num-test (sqrt pi) 1.77245385090552) (num-test (sqrt -3.14159265358979) 0.0+1.77245385090552i) (num-test (sqrt 2.71828182845905) 1.64872127070013) (num-test (sqrt -2.71828182845905) 0.0+1.64872127070013i) (num-test (sqrt 1234.0) 35.12833614050059) (num-test (sqrt -1234.0) 0.0+35.12833614050059i) (num-test (sqrt 1234000000.0) 35128.33614050059259) (num-test (sqrt -1234000000.0) 0.0+35128.33614050059259i) (num-test (sqrt 0.0+0.0i) 0.0) (num-test (sqrt -0.0+0.0i) 0.0) (num-test (sqrt 0.0-0.0i) 0.0) (num-test (sqrt -0.0-0.0i) 0.0) (num-test (sqrt 0.0+0.00000001i) 0.00007071067812+0.00007071067812i) (num-test (sqrt -0.0+0.00000001i) 0.00007071067812+0.00007071067812i) (num-test (sqrt 0.0-0.00000001i) 0.00007071067812-0.00007071067812i) (num-test (sqrt -0.0-0.00000001i) 0.00007071067812-0.00007071067812i) (num-test (sqrt 0.0+1.0i) 0.70710678118655+0.70710678118655i) (num-test (sqrt -0.0+1.0i) 0.70710678118655+0.70710678118655i) (num-test (sqrt 0.0-1.0i) 0.70710678118655-0.70710678118655i) (num-test (sqrt -0.0-1.0i) 0.70710678118655-0.70710678118655i) (num-test (sqrt 0.0+3.14159265358979i) 1.25331413731550+1.25331413731550i) (num-test (sqrt -0.0+3.14159265358979i) 1.25331413731550+1.25331413731550i) (num-test (sqrt 0.0-3.14159265358979i) 1.25331413731550-1.25331413731550i) (num-test (sqrt -0.0-3.14159265358979i) 1.25331413731550-1.25331413731550i) (num-test (sqrt 0.0+2.71828182845905i) 1.16582199079856+1.16582199079856i) (num-test (sqrt -0.0+2.71828182845905i) 1.16582199079856+1.16582199079856i) (num-test (sqrt 0.0-2.71828182845905i) 1.16582199079856-1.16582199079856i) (num-test (sqrt -0.0-2.71828182845905i) 1.16582199079856-1.16582199079856i) (num-test (sqrt 0.0+1234.0i) 24.83948469674844+24.83948469674844i) (num-test (sqrt -0.0+1234.0i) 24.83948469674844+24.83948469674844i) (num-test (sqrt 0.0-1234.0i) 24.83948469674844-24.83948469674844i) (num-test (sqrt -0.0-1234.0i) 24.83948469674844-24.83948469674844i) (num-test (sqrt 0.0+1234000000.0i) 24839.48469674844091+24839.48469674844091i) (num-test (sqrt -0.0+1234000000.0i) 24839.48469674844091+24839.48469674844091i) (num-test (sqrt 0.0-1234000000.0i) 24839.48469674844091-24839.48469674844091i) (num-test (sqrt -0.0-1234000000.0i) 24839.48469674844091-24839.48469674844091i) (num-test (sqrt 0.00000001+0.0i) 0.00010000000000) (num-test (sqrt -0.00000001+0.0i) 0.0+0.00010000000000i) (num-test (sqrt 0.00000001-0.0i) 0.00010000000000) (num-test (sqrt -0.00000001-0.0i) 0.0+0.00010000000000i) (num-test (sqrt 0.00000001+0.00000001i) 0.00010986841135+0.00004550898606i) (num-test (sqrt -0.00000001+0.00000001i) 0.00004550898606+0.00010986841135i) (num-test (sqrt 0.00000001-0.00000001i) 0.00010986841135-0.00004550898606i) (num-test (sqrt -0.00000001-0.00000001i) 0.00004550898606-0.00010986841135i) (num-test (sqrt 0.00000001+1.0i) 0.70710678472208+0.70710677765101i) (num-test (sqrt -0.00000001+1.0i) 0.70710677765101+0.70710678472208i) (num-test (sqrt 0.00000001-1.0i) 0.70710678472208-0.70710677765101i) (num-test (sqrt -0.00000001-1.0i) 0.70710677765101-0.70710678472208i) (num-test (sqrt 0.00000001+3.14159265358979i) 1.25331413931021+1.25331413532079i) (num-test (sqrt -0.00000001+3.14159265358979i) 1.25331413532079+1.25331413931021i) (num-test (sqrt 0.00000001-3.14159265358979i) 1.25331413931021-1.25331413532079i) (num-test (sqrt -0.00000001-3.14159265358979i) 1.25331413532079-1.25331413931021i) (num-test (sqrt 0.00000001+2.71828182845905i) 1.16582199294297+1.16582198865415i) (num-test (sqrt -0.00000001+2.71828182845905i) 1.16582198865415+1.16582199294297i) (num-test (sqrt 0.00000001-2.71828182845905i) 1.16582199294297-1.16582198865415i) (num-test (sqrt -0.00000001-2.71828182845905i) 1.16582198865415-1.16582199294297i) (num-test (sqrt 0.00000001+1234.0i) 24.83948469684909+24.83948469664779i) (num-test (sqrt -0.00000001+1234.0i) 24.83948469664779+24.83948469684909i) (num-test (sqrt 0.00000001-1234.0i) 24.83948469684909-24.83948469664779i) (num-test (sqrt -0.00000001-1234.0i) 24.83948469664779-24.83948469684909i) (num-test (sqrt 0.00000001+1234000000.0i) 24839.48469674844091+24839.48469674844091i) (num-test (sqrt -0.00000001+1234000000.0i) 24839.48469674844091+24839.48469674844091i) (num-test (sqrt 0.00000001-1234000000.0i) 24839.48469674844091-24839.48469674844091i) (num-test (sqrt -0.00000001-1234000000.0i) 24839.48469674844091-24839.48469674844091i) (num-test (sqrt 1.0+0.0i) 1.0) (num-test (sqrt -0.0) 0.0) (num-test (sqrt 0.0) 0.0) (num-test (sqrt -1.0+0.0i) 0.0+1.0i) (num-test (sqrt 1.0-0.0i) 1.0) (num-test (sqrt -1.0-0.0i) 0.0+1.0i) (num-test (sqrt 1.0+0.00000001i) 1.0+0.00000000500000i) (num-test (sqrt -1.0+0.00000001i) 0.00000000500000+1.0i) (num-test (sqrt 1.0-0.00000001i) 1.0-0.00000000500000i) (num-test (sqrt -1.0-0.00000001i) 0.00000000500000-1.0i) (num-test (sqrt 1.0+1.0i) 1.09868411346781+0.45508986056223i) (num-test (sqrt -1.0+1.0i) 0.45508986056223+1.09868411346781i) (num-test (sqrt 1.0-1.0i) 1.09868411346781-0.45508986056223i) (num-test (sqrt -1.0-1.0i) 0.45508986056223-1.09868411346781i) (num-test (sqrt 1.0+3.14159265358979i) 1.46576060621706+1.07165953303174i) (num-test (sqrt -1.0+3.14159265358979i) 1.07165953303174+1.46576060621706i) (num-test (sqrt 1.0-3.14159265358979i) 1.46576060621706-1.07165953303174i) (num-test (sqrt -1.0-3.14159265358979i) 1.07165953303174-1.46576060621706i) (num-test (sqrt 1.0+2.71828182845905i) 1.39577697566445+0.97375220964833i) (num-test (sqrt -1.0+2.71828182845905i) 0.97375220964833+1.39577697566445i) (num-test (sqrt 1.0-2.71828182845905i) 1.39577697566445-0.97375220964833i) (num-test (sqrt -1.0-2.71828182845905i) 0.97375220964833-1.39577697566445i) (num-test (sqrt 1.0+1234.0i) 24.84955135597340+24.82942211557006i) (num-test (sqrt -1.0+1234.0i) 24.82942211557006+24.84955135597340i) (num-test (sqrt 1.0-1234.0i) 24.84955135597340-24.82942211557006i) (num-test (sqrt -1.0-1234.0i) 24.82942211557006-24.84955135597340i) (num-test (sqrt 1.0+1234000000.0i) 24839.48470681306208+24839.48468668381975i) (num-test (sqrt -1.0+1234000000.0i) 24839.48468668381975+24839.48470681306208i) (num-test (sqrt 1.0-1234000000.0i) 24839.48470681306208-24839.48468668381975i) (num-test (sqrt -1.0-1234000000.0i) 24839.48468668381975-24839.48470681306208i) (num-test (sqrt 3.14159265358979+0.0i) 1.77245385090552) (num-test (sqrt -3.14159265358979+0.0i) 0.0+1.77245385090552i) (num-test (sqrt 3.14159265358979-0.0i) 1.77245385090552) (num-test (sqrt -3.14159265358979-0.0i) 0.0+1.77245385090552i) (num-test (sqrt 3.14159265358979+0.00000001i) 1.77245385090552+0.00000000282095i) (num-test (sqrt -3.14159265358979+0.00000001i) 0.00000000282095+1.77245385090552i) (num-test (sqrt 3.14159265358979-0.00000001i) 1.77245385090552-0.00000000282095i) (num-test (sqrt -3.14159265358979-0.00000001i) 0.00000000282095-1.77245385090552i) (num-test (sqrt 3.14159265358979+1.0i) 1.79422698718214+0.27867154132224i) (num-test (sqrt -3.14159265358979+1.0i) 0.27867154132224+1.79422698718214i) (num-test (sqrt 3.14159265358979-1.0i) 1.79422698718214-0.27867154132224i) (num-test (sqrt -3.14159265358979-1.0i) 0.27867154132224-1.79422698718214i) (num-test (sqrt 3.14159265358979+3.14159265358979i) 1.94736688784473+0.80662577586157i) (num-test (sqrt -3.14159265358979+3.14159265358979i) 0.80662577586157+1.94736688784473i) (num-test (sqrt 3.14159265358979-3.14159265358979i) 1.94736688784473-0.80662577586157i) (num-test (sqrt -3.14159265358979-3.14159265358979i) 0.80662577586157-1.94736688784473i) (num-test (sqrt 3.14159265358979+2.71828182845905i) 1.90996689184696+0.71160443672153i) (num-test (sqrt -3.14159265358979+2.71828182845905i) 0.71160443672153+1.90996689184696i) (num-test (sqrt 3.14159265358979-2.71828182845905i) 1.90996689184696-0.71160443672153i) (num-test (sqrt -3.14159265358979-2.71828182845905i) 0.71160443672153-1.90996689184696i) (num-test (sqrt 3.14159265358979+1234.0i) 24.87112373493049+24.80788590719961i) (num-test (sqrt -3.14159265358979+1234.0i) 24.80788590719961+24.87112373493049i) (num-test (sqrt 3.14159265358979-1234.0i) 24.87112373493049-24.80788590719961i) (num-test (sqrt -3.14159265358979-1234.0i) 24.80788590719961-24.87112373493049i) (num-test (sqrt 3.14159265358979+1234000000.0i) 24839.48472836738074+24839.48466512950108i) (num-test (sqrt -3.14159265358979+1234000000.0i) 24839.48466512950108+24839.48472836738074i) (num-test (sqrt 3.14159265358979-1234000000.0i) 24839.48472836738074-24839.48466512950108i) (num-test (sqrt -3.14159265358979-1234000000.0i) 24839.48466512950108-24839.48472836738074i) (num-test (sqrt 2.71828182845905+0.0i) 1.64872127070013) (num-test (sqrt -2.71828182845905+0.0i) 0.0+1.64872127070013i) (num-test (sqrt 2.71828182845905-0.0i) 1.64872127070013) (num-test (sqrt -2.71828182845905-0.0i) 0.0+1.64872127070013i) (num-test (sqrt 2.71828182845905+0.00000001i) 1.64872127070013+0.00000000303265i) (num-test (sqrt -2.71828182845905+0.00000001i) 0.00000000303265+1.64872127070013i) (num-test (sqrt 2.71828182845905-0.00000001i) 1.64872127070013-0.00000000303265i) (num-test (sqrt -2.71828182845905-0.00000001i) 0.00000000303265-1.64872127070013i) (num-test (sqrt 2.71828182845905+1.0i) 1.67551015515410+0.29841657387867i) (num-test (sqrt -2.71828182845905+1.0i) 0.29841657387867+1.67551015515410i) (num-test (sqrt 2.71828182845905-1.0i) 1.67551015515410-0.29841657387867i) (num-test (sqrt -2.71828182845905-1.0i) 0.29841657387867-1.67551015515410i) (num-test (sqrt 2.71828182845905+3.14159265358979i) 1.85373086379501+0.84737021833856i) (num-test (sqrt -2.71828182845905+3.14159265358979i) 0.84737021833856+1.85373086379501i) (num-test (sqrt 2.71828182845905-3.14159265358979i) 1.85373086379501-0.84737021833856i) (num-test (sqrt -2.71828182845905-3.14159265358979i) 0.84737021833856-1.85373086379501i) (num-test (sqrt 2.71828182845905+2.71828182845905i) 1.81142386765469+0.75031633318890i) (num-test (sqrt -2.71828182845905+2.71828182845905i) 0.75031633318890+1.81142386765469i) (num-test (sqrt 2.71828182845905-2.71828182845905i) 1.81142386765469-0.75031633318890i) (num-test (sqrt -2.71828182845905-2.71828182845905i) 0.75031633318890-1.81142386765469i) (num-test (sqrt 2.71828182845905+1234.0i) 24.86685822304219+24.81214130333015i) (num-test (sqrt -2.71828182845905+1234.0i) 24.81214130333015+24.86685822304219i) (num-test (sqrt 2.71828182845905-1234.0i) 24.86685822304219-24.81214130333015i) (num-test (sqrt -2.71828182845905-1234.0i) 24.81214130333015-24.86685822304219i) (num-test (sqrt 2.71828182845905+1234000000.0i) 24839.48472410691829+24839.48466938996353i) (num-test (sqrt -2.71828182845905+1234000000.0i) 24839.48466938996353+24839.48472410691829i) (num-test (sqrt 2.71828182845905-1234000000.0i) 24839.48472410691829-24839.48466938996353i) (num-test (sqrt -2.71828182845905-1234000000.0i) 24839.48466938996353-24839.48472410691829i) (num-test (sqrt 1234.0+0.0i) 35.12833614050059) (num-test (sqrt -1234.0+0.0i) 0.0+35.12833614050059i) (num-test (sqrt 1234.0-0.0i) 35.12833614050059) (num-test (sqrt -1234.0-0.0i) 0.0+35.12833614050059i) (num-test (sqrt 1234.0+0.00000001i) 35.12833614050059+0.00000000014234i) (num-test (sqrt -1234.0+0.00000001i) 0.00000000014234+35.12833614050059i) (num-test (sqrt 1234.0-0.00000001i) 35.12833614050059-0.00000000014234i) (num-test (sqrt -1234.0-0.00000001i) 0.00000000014234-35.12833614050059i) (num-test (sqrt 1234.0+1.0i) 35.12833902411499+0.01423352238934i) (num-test (sqrt -1234.0+1.0i) 0.01423352238934+35.12833902411499i) (num-test (sqrt 1234.0-1.0i) 35.12833902411499-0.01423352238934i) (num-test (sqrt -1234.0-1.0i) 0.01423352238934-35.12833902411499i) (num-test (sqrt 1234.0+3.14159265358979i) 35.12836460058208+0.04471589681601i) (num-test (sqrt -1234.0+3.14159265358979i) 0.04471589681601+35.12836460058208i) (num-test (sqrt 1234.0-3.14159265358979i) 35.12836460058208-0.04471589681601i) (num-test (sqrt -1234.0-3.14159265358979i) 0.04471589681601-35.12836460058208i) (num-test (sqrt 1234.0+2.71828182845905i) 35.12835744766116+0.03869070497402i) (num-test (sqrt -1234.0+2.71828182845905i) 0.03869070497402+35.12835744766116i) (num-test (sqrt 1234.0-2.71828182845905i) 35.12835744766116-0.03869070497402i) (num-test (sqrt -1234.0-2.71828182845905i) 0.03869070497402-35.12835744766116i) (num-test (sqrt 1234.0+1234.0i) 38.59494485012512+15.98654959596347i) (num-test (sqrt -1234.0+1234.0i) 15.98654959596347+38.59494485012512i) (num-test (sqrt 1234.0-1234.0i) 38.59494485012512-15.98654959596347i) (num-test (sqrt -1234.0-1234.0i) 15.98654959596347-38.59494485012512i) (num-test (sqrt 1234.0+1234000000.0i) 24839.49711649389428+24839.47227700919757i) (num-test (sqrt -1234.0+1234000000.0i) 24839.47227700919757+24839.49711649389428i) (num-test (sqrt 1234.0-1234000000.0i) 24839.49711649389428-24839.47227700919757i) (num-test (sqrt -1234.0-1234000000.0i) 24839.47227700919757-24839.49711649389428i) (num-test (sqrt 1234000000.0+0.0i) 35128.33614050059259) (num-test (sqrt -1234000000.0+0.0i) 0.0+35128.33614050059259i) (num-test (sqrt 1234000000.0-0.0i) 35128.33614050059259) (num-test (sqrt -1234000000.0-0.0i) 0.0+35128.33614050059259i) (num-test (sqrt 1234000000.0+0.00000001i) 35128.33614050059259+0.00000000000014i) (num-test (sqrt -1234000000.0+0.00000001i) 0.00000000000014+35128.33614050059259i) (num-test (sqrt 1234000000.0-0.00000001i) 35128.33614050059259-0.00000000000014i) (num-test (sqrt -1234000000.0-0.00000001i) 0.00000000000014-35128.33614050059259i) (num-test (sqrt 1234000000.0+1.0i) 35128.33614050059259+0.00001423352356i) (num-test (sqrt -1234000000.0+1.0i) 0.00001423352356+35128.33614050059259i) (num-test (sqrt 1234000000.0-1.0i) 35128.33614050059259-0.00001423352356i) (num-test (sqrt -1234000000.0-1.0i) 0.00001423352356-35128.33614050059259i) (num-test (sqrt 1234000000.0+3.14159265358979i) 35128.33614050059259+0.00004471593304i) (num-test (sqrt -1234000000.0+3.14159265358979i) 0.00004471593304+35128.33614050059259i) (num-test (sqrt 1234000000.0-3.14159265358979i) 35128.33614050059259-0.00004471593304i) (num-test (sqrt -1234000000.0-3.14159265358979i) 0.00004471593304-35128.33614050059259i) (num-test (sqrt 1234000000.0+2.71828182845905i) 35128.33614050059259+0.00003869072844i) (num-test (sqrt -1234000000.0+2.71828182845905i) 0.00003869072844+35128.33614050059259i) (num-test (sqrt 1234000000.0-2.71828182845905i) 35128.33614050059259-0.00003869072844i) (num-test (sqrt -1234000000.0-2.71828182845905i) 0.00003869072844-35128.33614050059259i) (num-test (sqrt 1234000000.0+1234.0i) 35128.33614050497999+0.01756416807025i) (num-test (sqrt -1234000000.0+1234.0i) 0.01756416807025+35128.33614050497999i) (num-test (sqrt 1234000000.0-1234.0i) 35128.33614050497999-0.01756416807025i) (num-test (sqrt -1234000000.0-1234.0i) 0.01756416807025-35128.33614050497999i) (num-test (sqrt 1234000000.0+1234000000.0i) 38594.94485012512450+15986.54959596346634i) (num-test (sqrt -1234000000.0+1234000000.0i) 15986.54959596346634+38594.94485012512450i) (num-test (sqrt 1234000000.0-1234000000.0i) 38594.94485012512450-15986.54959596346634i) (num-test (sqrt -1234000000.0-1234000000.0i) 15986.54959596346634-38594.94485012512450i) (num-test (sqrt 2.2250739e-308) 1.4916681e-154) (num-test (sqrt 1.7976931e+308) 1.3407808e+154) (num-test (sqrt 0.0e+00+0.0e+00i) 0e0+0.0i) (num-test (sqrt 0.0e+00+1.19209289550781250e-07i) 2.44140625e-4+2.44140625e-4i) (num-test (sqrt 0.0e+00-1.19209289550781250e-07i) 2.44140625e-4-2.44140625e-4i) (num-test (sqrt 0.0e+00+5.0e-01i) 5e-1+5e-1i) (num-test (sqrt 0.0e+00-5.0e-01i) 5e-1-5e-1i) (num-test (sqrt 0.0e+00+1.0e+00i) 7.0710678118654752440e-1+7.0710678118654752440e-1i) (num-test (sqrt 0.0e+00-1.0e+00i) 7.0710678118654752440e-1-7.0710678118654752440e-1i) (num-test (sqrt 0.0e+00+2.0e+00i) 1+1i) (num-test (sqrt 0.0e+00-2.0e+00i) 1-1i) (num-test (sqrt 0.0e+00+8.3886080e+06i) 2048+2048i) (num-test (sqrt 0.0e+00-8.3886080e+06i) 2048-2048i) (num-test (sqrt 1.19209289550781250e-07+0.0e+00i) 3.4526698300124390840e-4+0.0i) (num-test (sqrt -1.19209289550781250e-07+0.0e+00i) 0+3.4526698300124390840e-4i) (num-test (sqrt 1.19209289550781250e-07+1.19209289550781250e-07i) 3.7933934912842707699e-4+1.5712750315077700799e-4i) (num-test (sqrt 1.19209289550781250e-07-1.19209289550781250e-07i) 3.7933934912842707699e-4-1.5712750315077700799e-4i) (num-test (sqrt -1.19209289550781250e-07+1.19209289550781250e-07i) 1.5712750315077700799e-4+3.7933934912842707699e-4i) (num-test (sqrt -1.19209289550781250e-07-1.19209289550781250e-07i) 1.5712750315077700799e-4-3.7933934912842707699e-4i) (num-test (sqrt 1.19209289550781250e-07+5.0e-01i) 5.0000005960464832810e-1+4.9999994039535877732e-1i) (num-test (sqrt 1.19209289550781250e-07-5.0e-01i) 5.0000005960464832810e-1-4.9999994039535877732e-1i) (num-test (sqrt -1.19209289550781250e-07+5.0e-01i) 4.9999994039535877732e-1+5.0000005960464832810e-1i) (num-test (sqrt -1.19209289550781250e-07-5.0e-01i) 4.9999994039535877732e-1-5.0000005960464832810e-1i) (num-test (sqrt 1.19209289550781250e-07+1.0e+00i) 7.0710682333339729137e-1+7.0710673903970026958e-1i) (num-test (sqrt 1.19209289550781250e-07-1.0e+00i) 7.0710682333339729137e-1-7.0710673903970026958e-1i) (num-test (sqrt -1.19209289550781250e-07+1.0e+00i) 7.0710673903970026958e-1+7.0710682333339729137e-1i) (num-test (sqrt -1.19209289550781250e-07-1.0e+00i) 7.0710673903970026958e-1-7.0710682333339729137e-1i) (num-test (sqrt 1.19209289550781250e-07+2.0e+00i) 1.0000000298023228318e0+9.9999997019767805639e-1i) (num-test (sqrt 1.19209289550781250e-07-2.0e+00i) 1.0000000298023228318e0-9.9999997019767805639e-1i) (num-test (sqrt -1.19209289550781250e-07+2.0e+00i) 9.9999997019767805639e-1+1.0000000298023228318e0i) (num-test (sqrt -1.19209289550781250e-07-2.0e+00i) 9.9999997019767805639e-1-1.0000000298023228318e0i) (num-test (sqrt 1.19209289550781250e-07+8.3886080e+06i) 2.0480000000000145519e3+2.0479999999999854481e3i) (num-test (sqrt 1.19209289550781250e-07-8.3886080e+06i) 2.0480000000000145519e3-2.0479999999999854481e3i) (num-test (sqrt -1.19209289550781250e-07+8.3886080e+06i) 2.0479999999999854481e3+2.0480000000000145519e3i) (num-test (sqrt -1.19209289550781250e-07-8.3886080e+06i) 2.0479999999999854481e3-2.0480000000000145519e3i) (num-test (sqrt 5.0e-01+0.0e+00i) 7.0710678118654752440e-1+0.0i) (num-test (sqrt -5.0e-01+0.0e+00i) 0+7.0710678118654752440e-1i) (num-test (sqrt 5.0e-01+1.19209289550781250e-07i) 7.0710678118655254870e-1+8.4293697021787464631e-8i) (num-test (sqrt 5.0e-01-1.19209289550781250e-07i) 7.0710678118655254870e-1-8.4293697021787464631e-8i) (num-test (sqrt -5.0e-01+1.19209289550781250e-07i) 8.4293697021787464631e-8+7.0710678118655254870e-1i) (num-test (sqrt -5.0e-01-1.19209289550781250e-07i) 8.4293697021787464631e-8-7.0710678118655254870e-1i) (num-test (sqrt 5.0e-01+5.0e-01i) 7.7688698701501865367e-1+3.2179712645279131237e-1i) (num-test (sqrt 5.0e-01-5.0e-01i) 7.7688698701501865367e-1-3.2179712645279131237e-1i) (num-test (sqrt -5.0e-01+5.0e-01i) 3.2179712645279131237e-1+7.7688698701501865367e-1i) (num-test (sqrt -5.0e-01-5.0e-01i) 3.2179712645279131237e-1-7.7688698701501865367e-1i) (num-test (sqrt 5.0e-01+1.0e+00i) 8.9945371997393363613e-1+5.5589297025142117199e-1i) (num-test (sqrt 5.0e-01-1.0e+00i) 8.9945371997393363613e-1-5.5589297025142117199e-1i) (num-test (sqrt -5.0e-01+1.0e+00i) 5.5589297025142117199e-1+8.9945371997393363613e-1i) (num-test (sqrt -5.0e-01-1.0e+00i) 5.5589297025142117199e-1-8.9945371997393363613e-1i) (num-test (sqrt 5.0e-01+2.0e+00i) 1.1317139242778694103e0+8.8361553087551326576e-1i) (num-test (sqrt 5.0e-01-2.0e+00i) 1.1317139242778694103e0-8.8361553087551326576e-1i) (num-test (sqrt -5.0e-01+2.0e+00i) 8.8361553087551326576e-1+1.1317139242778694103e0i) (num-test (sqrt -5.0e-01-2.0e+00i) 8.8361553087551326576e-1-1.1317139242778694103e0i) (num-test (sqrt 5.0e-01+8.3886080e+06i) 2.0480000610351571595e3+2.0479999389648446595e3i) (num-test (sqrt 5.0e-01-8.3886080e+06i) 2.0480000610351571595e3-2.0479999389648446595e3i) (num-test (sqrt -5.0e-01+8.3886080e+06i) 2.0479999389648446595e3+2.0480000610351571595e3i) (num-test (sqrt -5.0e-01-8.3886080e+06i) 2.0479999389648446595e3-2.0480000610351571595e3i) (num-test (sqrt 1.0e+00+0.0e+00i) 1e0+0.0i) (num-test (sqrt -1.0e+00+0.0e+00i) 0+1i) (num-test (sqrt 1.0e+00+1.19209289550781250e-07i) 1.0000000000000017764e0+5.9604644775390519121e-8i) (num-test (sqrt 1.0e+00-1.19209289550781250e-07i) 1.0000000000000017764e0-5.9604644775390519121e-8i) (num-test (sqrt -1.0e+00+1.19209289550781250e-07i) 5.9604644775390519121e-8+1.0000000000000017764e0i) (num-test (sqrt -1.0e+00-1.19209289550781250e-07i) 5.9604644775390519121e-8-1.0000000000000017764e0i) (num-test (sqrt 1.0e+00+5.0e-01i) 1.0290855136357461252e0+2.4293413587832283909e-1i) (num-test (sqrt 1.0e+00-5.0e-01i) 1.0290855136357461252e0-2.4293413587832283909e-1i) (num-test (sqrt -1.0e+00+5.0e-01i) 2.4293413587832283909e-1+1.0290855136357461252e0i) (num-test (sqrt -1.0e+00-5.0e-01i) 2.4293413587832283909e-1-1.0290855136357461252e0i) (num-test (sqrt 1.0e+00+1.0e+00i) 1.0986841134678099660e0+4.5508986056222734130e-1i) (num-test (sqrt 1.0e+00-1.0e+00i) 1.0986841134678099660e0-4.5508986056222734130e-1i) (num-test (sqrt -1.0e+00+1.0e+00i) 4.5508986056222734130e-1+1.0986841134678099660e0i) (num-test (sqrt -1.0e+00-1.0e+00i) 4.5508986056222734130e-1-1.0986841134678099660e0i) (num-test (sqrt 1.0e+00+2.0e+00i) 1.2720196495140689643e0+7.8615137775742328607e-1i) (num-test (sqrt 1.0e+00-2.0e+00i) 1.2720196495140689643e0-7.8615137775742328607e-1i) (num-test (sqrt -1.0e+00+2.0e+00i) 7.8615137775742328607e-1+1.2720196495140689643e0i) (num-test (sqrt -1.0e+00-2.0e+00i) 7.8615137775742328607e-1-1.2720196495140689643e0i) (num-test (sqrt 1.0e+00+8.3886080e+06i) 2.0480001220703161380e3+2.0479998779296911380e3i) (num-test (sqrt 1.0e+00-8.3886080e+06i) 2.0480001220703161380e3-2.0479998779296911380e3i) (num-test (sqrt -1.0e+00+8.3886080e+06i) 2.0479998779296911380e3+2.0480001220703161380e3i) (num-test (sqrt -1.0e+00-8.3886080e+06i) 2.0479998779296911380e3-2.0480001220703161380e3i) (num-test (sqrt 2.0e+00+0.0e+00i) 1.4142135623730950488e0+0.0i) (num-test (sqrt -2.0e+00+0.0e+00i) 0+1.4142135623730950488e0i) (num-test (sqrt 2.0e+00+1.19209289550781250e-07i) 1.4142135623730956768e0+4.2146848510894013070e-8i) (num-test (sqrt 2.0e+00-1.19209289550781250e-07i) 1.4142135623730956768e0-4.2146848510894013070e-8i) (num-test (sqrt -2.0e+00+1.19209289550781250e-07i) 4.2146848510894013070e-8+1.4142135623730956768e0i) (num-test (sqrt -2.0e+00-1.19209289550781250e-07i) 4.2146848510894013070e-8-1.4142135623730956768e0i) (num-test (sqrt 2.0e+00+5.0e-01i) 1.4250531240639470060e0+1.7543205637629383228e-1i) (num-test (sqrt 2.0e+00-5.0e-01i) 1.4250531240639470060e0-1.7543205637629383228e-1i) (num-test (sqrt -2.0e+00+5.0e-01i) 1.7543205637629383228e-1+1.4250531240639470060e0i) (num-test (sqrt -2.0e+00-5.0e-01i) 1.7543205637629383228e-1-1.4250531240639470060e0i) (num-test (sqrt 2.0e+00+1.0e+00i) 1.4553466902253548081e0+3.4356074972251246414e-1i) (num-test (sqrt 2.0e+00-1.0e+00i) 1.4553466902253548081e0-3.4356074972251246414e-1i) (num-test (sqrt -2.0e+00+1.0e+00i) 3.4356074972251246414e-1+1.4553466902253548081e0i) (num-test (sqrt -2.0e+00-1.0e+00i) 3.4356074972251246414e-1-1.4553466902253548081e0i) (num-test (sqrt 2.0e+00+2.0e+00i) 1.5537739740300373073e0+6.4359425290558262474e-1i) (num-test (sqrt 2.0e+00-2.0e+00i) 1.5537739740300373073e0-6.4359425290558262474e-1i) (num-test (sqrt -2.0e+00+2.0e+00i) 6.4359425290558262474e-1+1.5537739740300373073e0i) (num-test (sqrt -2.0e+00-2.0e+00i) 6.4359425290558262474e-1-1.5537739740300373073e0i) (num-test (sqrt 2.0e+00+8.3886080e+06i) 2.0480002441406395519e3+2.0479997558593895519e3i) (num-test (sqrt 2.0e+00-8.3886080e+06i) 2.0480002441406395519e3-2.0479997558593895519e3i) (num-test (sqrt -2.0e+00+8.3886080e+06i) 2.0479997558593895519e3+2.0480002441406395519e3i) (num-test (sqrt -2.0e+00-8.3886080e+06i) 2.0479997558593895519e3-2.0480002441406395519e3i) (num-test (sqrt 8.3886080e+06+0.0e+00i) 2.8963093757400986599e3+0.0i) (num-test (sqrt -8.3886080e+06+0.0e+00i) 0+2.8963093757400986599e3i) (num-test (sqrt 8.3886080e+06+1.19209289550781250e-07i) 2.8963093757400986599e3+2.0579515874459976458e-11i) (num-test (sqrt 8.3886080e+06-1.19209289550781250e-07i) 2.8963093757400986599e3-2.0579515874459976458e-11i) (num-test (sqrt -8.3886080e+06+1.19209289550781250e-07i) 2.0579515874459976458e-11+2.8963093757400986599e3i) (num-test (sqrt -8.3886080e+06-1.19209289550781250e-07i) 2.0579515874459976458e-11-2.8963093757400986599e3i) (num-test (sqrt 8.3886080e+06+5.0e-01i) 2.8963093757400999462e3+8.6316745750310938767e-5i) (num-test (sqrt 8.3886080e+06-5.0e-01i) 2.8963093757400999462e3-8.6316745750310938767e-5i) (num-test (sqrt -8.3886080e+06+5.0e-01i) 8.6316745750310938767e-5+2.8963093757400999462e3i) (num-test (sqrt -8.3886080e+06-5.0e-01i) 8.6316745750310938767e-5-2.8963093757400999462e3i) (num-test (sqrt 8.3886080e+06+1.0e+00i) 2.8963093757401038048e3+1.7263349150062164754e-4i) (num-test (sqrt 8.3886080e+06-1.0e+00i) 2.8963093757401038048e3-1.7263349150062164754e-4i) (num-test (sqrt -8.3886080e+06+1.0e+00i) 1.7263349150062164754e-4+2.8963093757401038048e3i) (num-test (sqrt -8.3886080e+06-1.0e+00i) 1.7263349150062164754e-4-2.8963093757401038048e3i) (num-test (sqrt 8.3886080e+06+2.0e+00i) 2.8963093757401192395e3+3.4526698300124145513e-4i) (num-test (sqrt 8.3886080e+06-2.0e+00i) 2.8963093757401192395e3-3.4526698300124145513e-4i) (num-test (sqrt -8.3886080e+06+2.0e+00i) 3.4526698300124145513e-4+2.8963093757401192395e3i) (num-test (sqrt -8.3886080e+06-2.0e+00i) 3.4526698300124145513e-4-2.8963093757401192395e3i) (num-test (sqrt 8.3886080e+06+8.3886080e+06i) 3.1821290988135164054e3+1.3180810299506332155e3i) (num-test (sqrt 8.3886080e+06-8.3886080e+06i) 3.1821290988135164054e3-1.3180810299506332155e3i) (num-test (sqrt -8.3886080e+06+8.3886080e+06i) 1.3180810299506332155e3+3.1821290988135164054e3i) (num-test (sqrt -8.3886080e+06-8.3886080e+06i) 1.3180810299506332155e3-3.1821290988135164054e3i) (num-test (sqrt -1.0e+01) 0+3.1622776601683793320e0i) (num-test (sqrt -2.0e+00) 0+1.4142135623730950488e0i) (num-test (sqrt -1.0e+00) 0+1i) (num-test (sqrt -7.50e-01) 0+8.6602540378443864676e-1i) (num-test (sqrt -5.0e-01) 0+7.0710678118654752440e-1i) (num-test (sqrt -1.250e-01) 0+3.5355339059327376220e-1i) (num-test (sqrt -3.45266983001243932001e-04) 0+1.8581361171917517303e-2i) (num-test (sqrt -1.19209289550781250e-07) 0+3.4526698300124390840e-4i) (num-test (sqrt 0.0e+00) 0e0+0.0i) (num-test (sqrt 1.19209289550781250e-07) 3.4526698300124390840e-4+0.0i) (num-test (sqrt 3.45266983001243932001e-04) 1.8581361171917517303e-2+0.0i) (num-test (sqrt 1.250e-01) 3.5355339059327376220e-1+0.0i) (num-test (sqrt 5.0e-01) 7.0710678118654752440e-1+0.0i) (num-test (sqrt 7.50e-01) 8.6602540378443864676e-1+0.0i) (num-test (sqrt 1.0e+00) 1e0+0.0i) (num-test (sqrt 2.0e+00) 1.4142135623730950488e0+0.0i) (num-test (sqrt 1.0e+01) 3.1622776601683793320e0+0.0i) (num-test (sqrt 9) 3) (num-test (sqrt -9.0) 0.0+3.0i) (num-test (sqrt (sqrt (sqrt 256))) 2) (num-test (sqrt (sqrt (sqrt 1/256))) 1/2) (num-test (sqrt 0.1-111i) 7.4531887486175-7.4464771887462i) (num-test (sqrt -2.225073858507201399999999999999999999996E-308) 0.0+1.49166814624004135432626585974344862306E-154i) (num-test (sqrt -9223372036854775808) 0.0+3.037000499976049692451388530026308346744E9i) (num-test (sqrt 1.110223024625156799999999999999999999997E-16) 1.053671212772350917851343014434652692451E-8) (num-test (sqrt 9223372036854775807) 3.037000499976049692286752403030628535068E9) (num-test (sqrt (* 64686/26264 64686/26264)) 32343/13132) (num-test (sqrt (* 64812/61611 64812/61611)) 1964/1867) (num-test (sqrt (* 38868/48261 38868/48261)) 12956/16087) (num-test (sqrt (* 39537/63628 39537/63628)) 39537/63628) (num-test (sqrt (* 1238/47077 1238/47077)) 1238/47077) (num-test (sqrt (* 51490/46936 51490/46936)) 25745/23468) (num-test (sqrt (* 35778/34583 35778/34583)) 35778/34583) (num-test (sqrt (* 19920/16774 19920/16774)) 9960/8387) (num-test (sqrt (* 29100/37656 29100/37656)) 2425/3138) (num-test (sqrt (* 64906/58229 64906/58229)) 64906/58229) (num-test (sqrt 144) 12) (num-test (sqrt 9000000000000000000) 3000000000) ;; but unfortunately in non-gmp, 9400000000000000000 -> -9046744073709551616 (test (and (integer? (sqrt 9007199136250226)) (exact? (sqrt 9007199136250226))) #f) (test (and (integer? (sqrt 9007199136250225)) (exact? (sqrt 9007199136250225))) #t) (if (integer? (sqrt 4)) (begin (for-each (lambda (n sqn) (if (positive? n) ; in case 32 bit int (let ((val (sqrt n))) (if (or (not (integer? val)) (not (eqv? sqn val))) (format-logged #t ";(sqrt ~A) expected ~A but got ~A~%" n sqn val))))) (list 9 491401 19439281 1248844921 235565593201) (list 3 701 4409 35339 485351)) (for-each (lambda (n) (if (positive? n) (let ((val (sqrt n))) (if (or (integer? val) (> (abs (- (* val val) n)) .001)) (format-logged #t ";(sqrt ~A) expected ~A but got ~A~%" n (sqrt (* 1.0 n)) val))))) (list 10 491400 19439282 1248844920 235565593200)) (test (eqv? (expt 2 3) 8) #t) ;(test (eqv? (log 8 2) 3) #t) ; optimization in C (-O2) changes this (num-test (log 8 2) 3) (num-test (log 1/8 2) -3) (test (eqv? (expt 701 2) 491401) #t) (test (eqv? (log 491401 701) 2) #t) )) (let ((err 0.0) (mx 0.0)) (do ((i 0 (+ i 1)) (x -10.0 (+ x .1))) ((= i 200)) (let ((y (magnitude (- x (* (sqrt x) (sqrt x)))))) (if (> y err) (begin (set! mx x) (set! err y))))) (if (> err 1e-14) (format-logged #t ";(sqr (sqrt ~A)) error: ~A~%" mx err))) (let ((err 0.0) (mx 0.0)) (do ((i 0 (+ i 1)) (x -10.0+i (+ x .1+i))) ((= i 200)) (let ((y (magnitude (- x (* (sqrt x) (sqrt x)))))) (if (> y err) (begin (set! mx x) (set! err y))))) (if (> err 1e-12) (format-logged #t ";(sqr (sqrt ~A)) error: ~A~%" mx err))) (num-test (* (/ 4 (sqrt 522)) (log (* (expt (/ (+ 5 (sqrt 29)) (sqrt 2)) 3) (+ (* 5 (sqrt 29)) (* 11 (sqrt 6))) (expt (+ (sqrt (/ (+ 9 (* 3 (sqrt 6))) 4)) (sqrt (/ (+ 5 (* 3 (sqrt 6))) 4))) 6)))) ;31 digits pi) (num-test (let* ((N 3502) (D (* 1/2 (+ 1071 (* 184 (sqrt 34))))) (E (* 1/2 (+ 1553 (* 266 (sqrt 34))))) (F (+ 429 (* 304 (sqrt 2)))) (G (* 1/2 (+ 627 (* 442 (sqrt 2))))) (d1 (+ D (sqrt (- (* D D) 1)))) (e1 (+ E (sqrt (- (* E E) 1)))) (f1 (+ F (sqrt (- (* F F) 1)))) (g1 (+ G (sqrt (- (* G G) 1)))) (defg (* 2 d1 e1 f1 g1))) (* (/ (sqrt N)) (- (log (expt defg -6))))) pi) (num-test (let* ((N 2737) (D (* 1/2 (+ 621 (* 49 (sqrt 161))))) (E (* 1/4 (+ 321 (* 25 (sqrt 161))))) (F (* 1/4 (+ 393 (* 31 (sqrt 161))))) (G (* 1/4 (+ 2529 (* 199 (sqrt 161))))) (d (+ D (sqrt (- (* D D) 1)))) (e (+ E (sqrt (- (* E E) 1)))) (f (+ F (sqrt (- (* F F) 1)))) (g (+ G (sqrt (- (* G G) 1)))) (defg (* 2 d e f g))) (* (/ (sqrt N)) (- (log (abs (* -1 (expt defg -6))))))) pi) ; Newman and Shanks "On a Sequence Arising in Series for pi" (num-test (let* ((an (sqrt 2)) ; Borwein and Borwein "AGM Mean and Fast Computation" (bn 0) (pn (+ 2 (sqrt 2)))) (do ((i 0 (+ i 1))) ((= i 4) pn) (let* ((sqa (sqrt an)) (an1 (* 1/2 (+ sqa (/ 1.0 sqa)))) (bn1 (* sqa (/ (+ bn 1) (+ bn an)))) (pn1 (* pn bn1 (/ (+ an1 1) (+ bn1 1))))) (set! pn pn1) (set! bn bn1) (set! an an1)))) pi) (if with-bignums (begin (num-test (sqrt 340282366920938463463374607431768211456) 18446744073709551616) (num-test (sqrt 32317006071311007300714876688669951960444102669715484032130345427524655138867890893197201411522913463688717960921898019494119559150490921095088152386448283120630877367300996091750197750389652106796057638384067568276792218642619756161838094338476170470581645852036305042887575891541065808607552399123930385521914333389668342420684974786564569494856176035326322058077805659331026192708460314150258592864177116725943603718461857357598351152301645904403697613233287231227125684710820209725157101726931323469678542580656697935045997268352998638215525166389437335543602135433229604645318478604952148193555853611059596230656) 179769313486231590772930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474124377767893424865485276302219601246094119453082952085005768838150682342462881473913110540827237163350510684586298239947245938479716304835356329624224137216) (num-test (sqrt 1208925819614629174706176/717897987691852588770249) 1099511627776/847288609443) (num-test (sqrt (/ (* 1.0 (expt 2 80)) (expt 3 50))) 1.297682531692252029863335918836296060669E0) (num-test (sqrt -340282366920938463463374607431768211456) 0.0+1.8446744073709551616E19i) (num-test (sqrt 0+340282366920938463463374607431768211456i) 1.304381782533278221234957180625250836888E19+1.304381782533278221234957180625250836888E19i) )) (test (sqrt) 'error) (test (sqrt "hi") 'error) (test (sqrt 1.0+23.0i 1.0+23.0i) 'error) (for-each (lambda (arg) (test (sqrt arg) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) (num-test (sqrt 1/1073741824) 1/32768) (num-test (sqrt 1/274877906944) 1/524288) (num-test (sqrt 9223372030926249001) 3037000499) (num-test (sqrt 1/274877906944) 1/524288) (num-test (sqrt 1/1099511627776) 1/1048576) (num-test (sqrt 1/4398046511104) (sqrt (/ (expt 2 42)))) (num-test (sqrt 1/4611686018427387904) 1/2147483648) (num-test (sqrt 1/1152921504606846976) 1/1073741824) (num-test (sqrt 1/9223372030926249001) 1/3037000499) (num-test (sqrt 0+i) (/ 1+i (sqrt 2))) (num-test (+ 0-i(sqrt 00)) 0-i) (num-test (sqrt (* 1.2345e-127 1.2345e-127)) 1.2345e-127) (num-test (sqrt (* 1.2345e-27 1.2345e-27)) 1.2345e-27) (num-test (sqrt 13) (do ((i 1 (+ i 1)) (prod 1.0 (* prod (tan (/ (* i pi) 13))))) ((= i 7) prod))) (num-test (* 768 (sqrt (- 2 (sqrt (+ 2 (sqrt (+ 2 (sqrt (+ 2 (sqrt (+ 2 (sqrt (+ 2 (sqrt (+ 2 (sqrt (+ 2 (sqrt (+ 2 1))))))))))))))))))) 3.1415904632368) (for-each (lambda (num-and-val) (let ((num (car num-and-val)) (val (cadr num-and-val))) (num-test-1 'sqrt num (sqrt num) val))) (vector (list 0 0) (list 1 1) (list 2 1.4142135623731) (list 3 1.7320508075689) (list -1 0+1i) (list -2 0+1.4142135623731i) (list -3 0+1.7320508075689i) (list 9223372036854775807 3037000499.976) (list -9223372036854775808 0+3037000499.976i) (list 1/2 0.70710678118655) (list 1/3 0.57735026918963) (list -1/2 0+0.70710678118655i) (list -1/3 0+0.57735026918963i) (list 1/9223372036854775807 3.2927225399136e-10) (list 0.0 0.0) (list 1.0 1.0) (list 2.0 1.4142135623731) (list -2.0 0+1.4142135623731i) (list 1.000000000000000000000000000000000000002E-309 3.162277660168379331998893544432718533725E-155) (list 1e+16 100000000.0) (list 0+1i 0.70710678118655+0.70710678118655i) (list 0+2i 1+1i) (list 0-1i 0.70710678118655-0.70710678118655i) (list 1+1i 1.0986841134678+0.45508986056223i) (list 1-1i 1.0986841134678-0.45508986056223i) (list -1+1i 0.45508986056223+1.0986841134678i) (list -1-1i 0.45508986056223-1.0986841134678i) (list 0.1+0.1i 0.34743442276012+0.14391204994251i) (list 1e+16+1e+16i 109868411.34678+45508986.056223i) (list 1e-16+1e-16i 1.0986841134678e-08+4.5508986056223e-09i) )) (let ((sqrts (list 1.00000000000000000000000000000000000000000000000000000000000000000000 1.41421356237309504880168872420969807856967187537694807317667973799073 1.73205080756887729352744634150587236694280525381038062805580697945193 2.00000000000000000000000000000000000000000000000000000000000000000000 2.23606797749978969640917366873127623544061835961152572427089724541052 2.44948974278317809819728407470589139196594748065667012843269256725096 2.64575131106459059050161575363926042571025918308245018036833445920106 2.82842712474619009760337744841939615713934375075389614635335947598146 3.00000000000000000000000000000000000000000000000000000000000000000000 3.16227766016837933199889354443271853371955513932521682685750485279259 3.31662479035539984911493273667068668392708854558935359705868214611648 3.46410161513775458705489268301174473388561050762076125611161395890386 3.60555127546398929311922126747049594625129657384524621271045305622716 3.74165738677394138558374873231654930175601980777872694630374546732003 3.87298334620741688517926539978239961083292170529159082658757376611348 4.00000000000000000000000000000000000000000000000000000000000000000000 4.12310562561766054982140985597407702514719922537362043439863357309495 4.24264068711928514640506617262909423570901562613084421953003921397219 4.35889894354067355223698198385961565913700392523244493689034413815955 4.47213595499957939281834733746255247088123671922305144854179449082104 4.58257569495584000658804719372800848898445657676797190260724212390686 4.69041575982342955456563011354446628058822835341173715360570189101702 4.79583152331271954159743806416269391999670704190412934648530911444825 4.89897948556635619639456814941178278393189496131334025686538513450192 5.00000000000000000000000000000000000000000000000000000000000000000000 5.09901951359278483002822410902278198956377094609959640758497080442593 5.19615242270663188058233902451761710082841576143114188416742093835579 5.29150262212918118100323150727852085142051836616490036073666891840213 5.38516480713450403125071049154032955629512016164478883768038867001664 5.47722557505166113456969782800802133952744694997983254226894449732493 5.56776436283002192211947129891854952047639337757041430396843258560358 5.65685424949238019520675489683879231427868750150779229270671895196292 5.74456264653802865985061146821892931822026445798279236769987747056590 5.83095189484530047087415287754558307652139833488597195445000674486781 5.91607978309961604256732829156161704841550123079434032287971966914282 6.00000000000000000000000000000000000000000000000000000000000000000000 6.08276253029821968899968424520206706208497009478641118641915304648633 6.16441400296897645025019238145424422523562402344457454487457207245839 6.24499799839839820584689312093979446107295997799165630845297193060961 6.32455532033675866399778708886543706743911027865043365371500970558518))) (let ((mxerr 0.0)) (do ((i 1 (+ i 1))) ((> i 40)) (let ((err (abs (- (sqrt i) (list-ref sqrts (- i 1)))))) (if (> err mxerr) (set! mxerr err)))) (if (> mxerr 1e-12) (format-logged #t "sqrt err: ~A~%" mxerr)))) (if with-bignums (begin (num-test (/ (sqrt (* 1.2345e-170 1.2345e-170))) 8.100445524503847216161209708816501953798E169) (num-test (sqrt (expt 2 32)) 65536) (num-test (sqrt -1.797693134862315699999999999999999999998E308) 0.0+1.34078079299425963249160560140156653105E154i) (num-test (exp (* pi (sqrt (bignum "163")))) 2.625374126407687439999999999992500725895E17) )) (if with-bignums (let ((old-prec (*s7* 'bignum-precision))) (set! (*s7* 'bignum-precision) 500) (let ((sqrts (list ; table[Sqrt[k/10], {k, 0, 30}] 0.00000000000000000000000000000000000000000000000000000000000000000000e0 0.31622776601683793319988935444327185337195551393252168268575048527925 0.44721359549995793928183473374625524708812367192230514485417944908210 0.54772255750516611345696978280080213395274469499798325422689444973249 0.63245553203367586639977870888654370674391102786504336537150097055851 0.70710678118654752440084436210484903928483593768847403658833986899536 0.77459666924148337703585307995647992216658434105831816531751475322269 0.83666002653407554797817202578518748939281536929867219981119154308041 0.89442719099991587856366946749251049417624734384461028970835889816420 0.94868329805051379959966806332981556011586654179756504805725145583777 1.00000000000000000000000000000000000000000000000000000000000000000000 1.04880884817015154699145351367993759847527185768150398487575576358000 1.09544511501033222691393956560160426790548938999596650845378889946498 1.14017542509913797913604902556675447907600531091641037529746941724956 1.18321595661992320851346565831232340968310024615886806457594393382856 1.22474487139158904909864203735294569598297374032833506421634628362548 1.26491106406735173279955741777308741348782205573008673074300194111703 1.30384048104052974291659431148583688330561875578201309179007936989676 1.34164078649987381784550420123876574126437101576691543456253834724631 1.37840487520902217679559125529341754271981635583990014790642120179806 1.41421356237309504880168872420969807856967187537694807317667973799073 1.44913767461894385737186641571697717231401328747589730886959248071181 1.48323969741913258974227948816014261219598086381950031974652465286876 1.51657508881031011085136508725641431090992842790349245064524200355844 1.54919333848296675407170615991295984433316868211663633063502950644539 1.58113883008418966599944677221635926685977756966260841342875242639629 1.61245154965970993047332264606075422622687926112171467758731847785277 1.64316767251549834037090934840240640185823408499394976268068334919747 1.67332005306815109595634405157037497878563073859734439962238308616083 1.70293863659264011661333218238773227063897151909784216273026969624657 1.73205080756887729352744634150587236694280525381038062805580697945193))) (do ((i 0 (+ i 1))) ((= i 30)) (let ((val (sqrt (/ i (bignum "10"))))) (if (> (magnitude (- val (list-ref sqrts i))) 1e-36) (format-logged #t ";(sqrt ~A) -> ~A ~A~%[~A]~%" (/ i 10) val (list-ref sqrts i) (magnitude (- val (list-ref sqrts i)))))))) (set! (*s7* 'bignum-precision) old-prec))) ;;; -------------------------------------------------------------------------------- ;;; exp ;;; -------------------------------------------------------------------------------- (num-test (exp 0) 1.0) (num-test (exp 1) 2.71828182845905) (num-test (exp -1) 0.36787944117144) (num-test (exp 2) 7.38905609893065) (num-test (exp -2) 0.13533528323661) (num-test (exp 3) 20.08553692318767) (num-test (exp -3) 0.04978706836786) (num-test (exp 10) 22026.46579480671789) (num-test (exp -10) 0.00004539992976) (num-test (exp 0/1) 1.0) (num-test (exp 0/2) 1.0) (num-test (exp 0/3) 1.0) (num-test (exp 0/10) 1.0) (num-test (exp 0/1234) 1.0) (num-test (exp 0/1234000000) 1.0) (num-test (exp 0/500029) 1.0) (num-test (exp 0/362880) 1.0) (num-test (exp 1/1) 2.71828182845905) (num-test (exp -1/1) 0.36787944117144) (num-test (exp 1/2) 1.64872127070013) (num-test (exp -1/2) 0.60653065971263) (num-test (exp 1/3) 1.39561242508609) (num-test (exp -1/3) 0.71653131057379) (num-test (exp 1/10) 1.10517091807565) (num-test (exp -1/10) 0.90483741803596) (num-test (exp 1/1234) 1.00081070121220) (num-test (exp -1/1234) 0.99918995549186) (num-test (exp 1/1234000000) 1.00000000081037) (num-test (exp -1/1234000000) 0.99999999918963) (num-test (exp 1/500029) 1.00000199988601) (num-test (exp -1/500029) 0.99999800011799) (num-test (exp 1/362880) 1.00000275573572) (num-test (exp -1/362880) 0.99999724427187) (num-test (exp 2/1) 7.38905609893065) (num-test (exp -2/1) 0.13533528323661) (num-test (exp 2/2) 2.71828182845905) (num-test (exp -2/2) 0.36787944117144) (num-test (exp 2/3) 1.94773404105468) (num-test (exp -2/3) 0.51341711903259) (num-test (exp 2/10) 1.22140275816017) (num-test (exp -2/10) 0.81873075307798) (num-test (exp 2/1234) 1.00162205966086) (num-test (exp -2/1234) 0.99838056715583) (num-test (exp 2/1234000000) 1.00000000162075) (num-test (exp -2/1234000000) 0.99999999837925) (num-test (exp 2/500029) 1.00000399977601) (num-test (exp -2/500029) 0.99999600023999) (num-test (exp 2/362880) 1.00000551147903) (num-test (exp -2/362880) 0.99999448855134) (num-test (exp 3/1) 20.08553692318767) (num-test (exp -3/1) 0.04978706836786) (num-test (exp 3/2) 4.48168907033806) (num-test (exp -3/2) 0.22313016014843) (num-test (exp 3/3) 2.71828182845905) (num-test (exp -3/3) 0.36787944117144) (num-test (exp 3/10) 1.34985880757600) (num-test (exp -3/10) 0.74081822068172) (num-test (exp 3/1234) 1.00243407587880) (num-test (exp -3/1234) 0.99757183446037) (num-test (exp 3/1234000000) 1.00000000243112) (num-test (exp -3/1234000000) 0.99999999756888) (num-test (exp 3/500029) 1.00000599967002) (num-test (exp -3/500029) 0.99999400036598) (num-test (exp 3/362880) 1.00000826722994) (num-test (exp -3/362880) 0.99999173283841) (num-test (exp 10/1) 22026.46579480671789) (num-test (exp -10/1) 0.00004539992976) (num-test (exp 10/2) 148.41315910257660) (num-test (exp -10/2) 0.00673794699909) (num-test (exp 10/3) 28.03162489452614) (num-test (exp -10/3) 0.03567399334725) (num-test (exp 10/10) 2.71828182845905) (num-test (exp -10/10) 0.36787944117144) (num-test (exp 10/1234) 1.00813665179201) (num-test (exp -10/1234) 0.99192901897025) (num-test (exp 10/1234000000) 1.00000000810373) (num-test (exp -10/1234000000) 0.99999999189627) (num-test (exp 10/500029) 1.00001999904005) (num-test (exp -10/500029) 0.99998000135991) (num-test (exp 10/362880) 1.00002755769893) (num-test (exp -10/362880) 0.99997244306048) (num-test (exp 1234/1234) 2.71828182845905) (num-test (exp -1234/1234) 0.36787944117144) (num-test (exp 1234/1234000000) 1.00000100000050) (num-test (exp -1234/1234000000) 0.99999900000050) (num-test (exp 1234/500029) 1.00247090452960) (num-test (exp -1234/500029) 0.99753518579099) (num-test (exp 1234/362880) 1.00340636170081) (num-test (exp -1234/362880) 0.99660520220837) (num-test (exp 1234000000/1234000000) 2.71828182845905) (num-test (exp -1234000000/1234000000) 0.36787944117144) (num-test (exp 500029/1234000000) 1.00040529199516) (num-test (exp -500029/1234000000) 0.99959487219989) (num-test (exp 500029/500029) 2.71828182845905) (num-test (exp -500029/500029) 0.36787944117144) (num-test (exp 500029/362880) 3.96674507247837) (num-test (exp -500029/362880) 0.25209585736630) (num-test (exp 362880/1234000000) 1.00029411131357) (num-test (exp -362880/1234000000) 0.99970597516246) (num-test (exp 362880/500029) 2.06621391988774) (num-test (exp -362880/500029) 0.48397699307646) (num-test (exp 362880/362880) 2.71828182845905) (num-test (exp -362880/362880) 0.36787944117144) (num-test (exp 0.0) 1.0) (num-test (exp 0.00000001) 1.00000001) (num-test (exp -0.00000001) 0.99999999000000) (num-test (exp 1.0) 2.71828182845905) (num-test (exp -1.0) 0.36787944117144) (num-test (exp pi) 23.14069263277927) (num-test (exp -3.14159265358979) 0.04321391826377) (num-test (exp 2.71828182845905) 15.15426224147926) (num-test (exp -2.71828182845905) 0.06598803584531) (num-test (exp 0.0+0.0i) 1.0) (num-test (exp -0.0+0.0i) 1.0) (num-test (exp 0.0-0.0i) 1.0) (num-test (exp -0.0-0.0i) 1.0) (num-test (exp 0.0+0.00000001i) 1.0+0.00000001i) (num-test (exp -0.0+0.00000001i) 1.0+0.00000001i) (num-test (exp 0.0-0.00000001i) 1.0-0.00000001i) (num-test (exp -0.0-0.00000001i) 1.0-0.00000001i) (num-test (exp 0.0+1.0i) 0.54030230586814+0.84147098480790i) (num-test (exp -0.0+1.0i) 0.54030230586814+0.84147098480790i) (num-test (exp 0.0-1.0i) 0.54030230586814-0.84147098480790i) (num-test (exp -0.0-1.0i) 0.54030230586814-0.84147098480790i) (num-test (exp 0.0+3.14159265358979i) -1.0+0.0i) (num-test (exp -0.0+3.14159265358979i) -1.0+0.0i) (num-test (exp 0.0-3.14159265358979i) -1.0-0.0i) (num-test (exp -0.0-3.14159265358979i) -1.0-0.0i) (num-test (exp 0.0+2.71828182845905i) -0.91173391478697+0.41078129050291i) (num-test (exp -0.0+2.71828182845905i) -0.91173391478697+0.41078129050291i) (num-test (exp 0.0-2.71828182845905i) -0.91173391478697-0.41078129050291i) (num-test (exp -0.0-2.71828182845905i) -0.91173391478697-0.41078129050291i) (num-test (exp 0.00000001+0.0i) 1.00000001) (num-test (exp -0.00000001+0.0i) 0.99999999000000) (num-test (exp 0.00000001-0.0i) 1.00000001) (num-test (exp -0.00000001-0.0i) 0.99999999000000) (num-test (exp 0.00000001+0.00000001i) 1.00000001+0.00000001i) (num-test (exp -0.00000001+0.00000001i) 0.99999999000000+0.00000001i) (num-test (exp 0.00000001-0.00000001i) 1.00000001-0.00000001i) (num-test (exp -0.00000001-0.00000001i) 0.99999999000000-0.00000001i) (num-test (exp 0.00000001+1.0i) 0.54030231127116+0.84147099322261i) (num-test (exp -0.00000001+1.0i) 0.54030230046512+0.84147097639319i) (num-test (exp 0.00000001-1.0i) 0.54030231127116-0.84147099322261i) (num-test (exp -0.00000001-1.0i) 0.54030230046512-0.84147097639319i) (num-test (exp 0.00000001+3.14159265358979i) -1.00000001+0.0i) (num-test (exp -0.00000001+3.14159265358979i) -0.99999999000000+0.0i) (num-test (exp 0.00000001-3.14159265358979i) -1.00000001-0.0i) (num-test (exp -0.00000001-3.14159265358979i) -0.99999999000000-0.0i) (num-test (exp 0.00000001+2.71828182845905i) -0.91173392390430+0.41078129461072i) (num-test (exp -0.00000001+2.71828182845905i) -0.91173390566963+0.41078128639510i) (num-test (exp 0.00000001-2.71828182845905i) -0.91173392390430-0.41078129461072i) (num-test (exp -0.00000001-2.71828182845905i) -0.91173390566963-0.41078128639510i) (num-test (exp 1.0+0.0i) 2.71828182845905) (num-test (exp -1.0+0.0i) 0.36787944117144) (num-test (exp 1.0-0.0i) 2.71828182845905) (num-test (exp -1.0-0.0i) 0.36787944117144) (num-test (exp 1.0+0.00000001i) 2.71828182845905+0.00000002718282i) (num-test (exp -1.0+0.00000001i) 0.36787944117144+0.00000000367879i) (num-test (exp 1.0-0.00000001i) 2.71828182845905-0.00000002718282i) (num-test (exp -1.0-0.00000001i) 0.36787944117144-0.00000000367879i) (num-test (exp 1.0+1.0i) 1.46869393991589+2.28735528717884i) (num-test (exp -1.0+1.0i) 0.19876611034641+0.30955987565311i) (num-test (exp 1.0-1.0i) 1.46869393991589-2.28735528717884i) (num-test (exp -1.0-1.0i) 0.19876611034641-0.30955987565311i) (num-test (exp 1.0+3.14159265358979i) -2.71828182845905+0.0i) (num-test (exp -1.0+3.14159265358979i) -0.36787944117144+0.0i) (num-test (exp 1.0-3.14159265358979i) -2.71828182845905-0.0i) (num-test (exp -1.0-3.14159265358979i) -0.36787944117144-0.0i) (num-test (exp 1.0+2.71828182845905i) -2.47834973295523+1.11661931744501i) (num-test (exp -1.0+2.71828182845905i) -0.33540816306888+0.15111799159389i) (num-test (exp 1.0-2.71828182845905i) -2.47834973295523-1.11661931744501i) (num-test (exp -1.0-2.71828182845905i) -0.33540816306888-0.15111799159389i) (num-test (exp 3.14159265358979+0.0i) 23.14069263277927) (num-test (exp -3.14159265358979+0.0i) 0.04321391826377) (num-test (exp 3.14159265358979-0.0i) 23.14069263277927) (num-test (exp -3.14159265358979-0.0i) 0.04321391826377) (num-test (exp 3.14159265358979+0.00000001i) 23.14069263277926+0.00000023140693i) (num-test (exp -3.14159265358979+0.00000001i) 0.04321391826377+0.00000000043214i) (num-test (exp 3.14159265358979-0.00000001i) 23.14069263277926-0.00000023140693i) (num-test (exp -3.14159265358979-0.00000001i) 0.04321391826377-0.00000000043214i) (num-test (exp 3.14159265358979+1.0i) 12.50296958887651+19.47222141884161i) (num-test (exp -3.14159265358979+1.0i) 0.02334857968351+0.03636325835882i) (num-test (exp 3.14159265358979-1.0i) 12.50296958887651-19.47222141884161i) (num-test (exp -3.14159265358979-1.0i) 0.02334857968351-0.03636325835882i) (num-test (exp 3.14159265358979+3.14159265358979i) -23.14069263277927+0.0i) (num-test (exp -3.14159265358979+3.14159265358979i) -0.04321391826377+0.0i) (num-test (exp 3.14159265358979-3.14159265358979i) -23.14069263277927-0.0i) (num-test (exp -3.14159265358979-3.14159265358979i) -0.04321391826377-0.0i) (num-test (exp 3.14159265358979+2.71828182845905i) -21.09815428496572+9.50576358282422i) (num-test (exp -3.14159265358979+2.71828182845905i) -0.03939959487191+0.01775146911208i) (num-test (exp 3.14159265358979-2.71828182845905i) -21.09815428496572-9.50576358282422i) (num-test (exp -3.14159265358979-2.71828182845905i) -0.03939959487191-0.01775146911208i) (num-test (exp 2.71828182845905+0.0i) 15.15426224147926) (num-test (exp -2.71828182845905+0.0i) 0.06598803584531) (num-test (exp 2.71828182845905-0.0i) 15.15426224147926) (num-test (exp -2.71828182845905-0.0i) 0.06598803584531) (num-test (exp 2.71828182845905+0.00000001i) 15.15426224147926+0.00000015154262i) (num-test (exp -2.71828182845905+0.00000001i) 0.06598803584531+0.00000000065988i) (num-test (exp 2.71828182845905-0.00000001i) 15.15426224147926-0.00000015154262i) (num-test (exp -2.71828182845905-0.00000001i) 0.06598803584531-0.00000000065988i) (num-test (exp 2.71828182845905+1.0i) 8.18788283280173+12.75187197237468i) (num-test (exp -2.71828182845905+1.0i) 0.03565348792693+0.05552701750829i) (num-test (exp 2.71828182845905-1.0i) 8.18788283280173-12.75187197237468i) (num-test (exp -2.71828182845905-1.0i) 0.03565348792693-0.05552701750829i) (num-test (exp 2.71828182845905+3.14159265358979i) -15.15426224147926+0.0i) (num-test (exp -2.71828182845905+3.14159265358979i) -0.06598803584531+0.0i) (num-test (exp 2.71828182845905-3.14159265358979i) -15.15426224147926-0.0i) (num-test (exp -2.71828182845905-3.14159265358979i) -0.06598803584531-0.0i) (num-test (exp 2.71828182845905+2.71828182845905i) -13.81665483913218+6.22508740017436i) (num-test (exp -2.71828182845905+2.71828182845905i) -0.06016353025035+0.02710665052229i) (num-test (exp 2.71828182845905-2.71828182845905i) -13.81665483913218-6.22508740017436i) (num-test (exp -2.71828182845905-2.71828182845905i) -0.06016353025035-0.02710665052229i) (num-test (exp -1234.0+0.0i) 0.0) (num-test (exp -1234.0-0.0i) 0.0) (num-test (exp -1234.0+0.00000001i) 0.0) (num-test (exp -1234.0-0.00000001i) 0.0) (num-test (exp -1234.0+3.14159265358979i) 0.0) (num-test (exp -1234.0-3.14159265358979i) 0.0) (num-test (exp -1234.0+2.71828182845905i) 0.0) (num-test (exp -1234.0-2.71828182845905i) 0.0) (num-test (exp -1234000000.0+0.0i) 0.0) (num-test (exp -1234000000.0-0.0i) 0.0) (num-test (exp -1234000000.0+0.00000001i) 0.0) (num-test (exp -1234000000.0-0.00000001i) 0.0) (num-test (exp -1234000000.0+3.14159265358979i) 0.0) (num-test (exp -1234000000.0-3.14159265358979i) 0.0) (num-test (exp -1234000000.0+2.71828182845905i) 0.0) (num-test (exp -1234000000.0-2.71828182845905i) 0.0) (num-test (exp 10.0) 22026.46579480672) (num-test (exp 100.0) 2.688117141816135E+43) (num-test (exp -10.0) 4.5399929762484853E-5) (num-test (exp -100.0) 3.720075976020836E-44) (num-test (exp -7.080000e+02) 3.307553e-308) (num-test (exp 7.090000e+02) 8.218407461554972189241372386597816393254E307) (num-test (exp 0.00000001+1234.0i) -0.7985506315730906+0.601927660781774i) (num-test (exp 0.00000001+1234000000.0i) .1589091324793142-0.987293222712823i) (num-test (exp 3.14159265358979+1234.0i) -18.47901453215463+13.92902284602872i) (num-test (exp 3.14159265358979+1234000000.0i) 3.677267354472762-22.8466487767572i) (num-test (exp 2.71828182845905+1234.0i) -12.1014455629425+9.121769530669065i) (num-test (exp 2.71828182845905+1234000000.0i) 2.408150642075881-14.96170025660763i) (num-test (exp 0.0e+00-3.45266983001243932001e-04i) 9.9999994039535581673e-1-3.4526697614140534807e-4i) (num-test (exp 0.0e+00+3.45266983001243932001e-04i) 9.9999994039535581673e-1+3.4526697614140534807e-4i) (num-test (exp 0.0e+00+1.57045105981189525579e+00i) 3.4526697614152485627e-4+9.9999994039535581669e-1i) (num-test (exp 0.0e+00-1.57045105981189525579e+00i) 3.4526697614152485627e-4-9.9999994039535581669e-1i) (num-test (exp 0.0e+00+1.57114159377789786021e+00i) -3.4526697614140239160e-4+9.9999994039535581673e-1i) (num-test (exp 0.0e+00-1.57114159377789786021e+00i) -3.4526697614140239160e-4-9.9999994039535581673e-1i) (num-test (exp 0.0e+00+3.14124738660679181379e+00i) -9.9999994039535581667e-1+3.4526697614158608860e-4i) (num-test (exp 0.0e+00-3.14124738660679181379e+00i) -9.9999994039535581667e-1-3.4526697614158608860e-4i) (num-test (exp 0.0e+00+3.14193792057279441821e+00i) -9.9999994039535581675e-1-3.4526697614134115926e-4i) (num-test (exp 0.0e+00-3.14193792057279441821e+00i) -9.9999994039535581675e-1+3.4526697614134115926e-4i) (num-test (exp 0.0e+00+4.71204371340168837179e+00i) -3.4526697614164732094e-4-9.9999994039535581664e-1i) (num-test (exp 0.0e+00-4.71204371340168837179e+00i) -3.4526697614164732094e-4+9.9999994039535581664e-1i) (num-test (exp 0.0e+00+4.71273424736769097620e+00i) 3.4526697614127992692e-4-9.9999994039535581677e-1i) (num-test (exp 0.0e+00-4.71273424736769097620e+00i) 3.4526697614127992692e-4+9.9999994039535581677e-1i) (num-test (exp 0.0e+00+6.28284004019658492979e+00i) 9.9999994039535581662e-1-3.4526697614170855328e-4i) (num-test (exp 0.0e+00-6.28284004019658492979e+00i) 9.9999994039535581662e-1+3.4526697614170855328e-4i) (num-test (exp 0.0e+00+6.28353057416258753420e+00i) 9.9999994039535581679e-1+3.4526697614121869459e-4i) (num-test (exp 0.0e+00-6.28353057416258753420e+00i) 9.9999994039535581679e-1-3.4526697614121869459e-4i) (num-test (exp 0.0e+00+9.42443269378637893396e+00i) -9.9999994039535581689e-1+3.4526697614094283958e-4i) (num-test (exp 0.0e+00-9.42443269378637893396e+00i) -9.9999994039535581689e-1-3.4526697614094283958e-4i) (num-test (exp 0.0e+00+9.42512322775237976202e+00i) -9.9999994039535581714e-1-3.4526697614020805155e-4i) (num-test (exp 0.0e+00-9.42512322775237976202e+00i) -9.9999994039535581714e-1+3.4526697614020805155e-4i) (num-test (exp 1.19209289550781250e-07-3.45266983001243932001e-04i) 1.0000000596046453675e0-3.4526701730043873250e-4i) (num-test (exp 1.19209289550781250e-07+3.45266983001243932001e-04i) 1.0000000596046453675e0+3.4526701730043873250e-4i) (num-test (exp -1.19209289550781250e-07-3.45266983001243932001e-04i) 9.9999982118608047680e-1-3.4526693498237687017e-4i) (num-test (exp -1.19209289550781250e-07+3.45266983001243932001e-04i) 9.9999982118608047680e-1+3.4526693498237687017e-4i) (num-test (exp 1.19209289550781250e-07+1.57045105981189525579e+00i) 3.4526701730055824072e-4+1.0000000596046453675e0i) (num-test (exp 1.19209289550781250e-07-1.57045105981189525579e+00i) 3.4526701730055824072e-4-1.0000000596046453675e0i) (num-test (exp -1.19209289550781250e-07+1.57045105981189525579e+00i) 3.4526693498249637836e-4+9.9999982118608047676e-1i) (num-test (exp -1.19209289550781250e-07-1.57045105981189525579e+00i) 3.4526693498249637836e-4-9.9999982118608047676e-1i) (num-test (exp 1.19209289550781250e-07+1.57114159377789786021e+00i) -3.4526701730043577603e-4+1.0000000596046453675e0i) (num-test (exp 1.19209289550781250e-07-1.57114159377789786021e+00i) -3.4526701730043577603e-4-1.0000000596046453675e0i) (num-test (exp -1.19209289550781250e-07+1.57114159377789786021e+00i) -3.4526693498237391370e-4+9.9999982118608047680e-1i) (num-test (exp -1.19209289550781250e-07-1.57114159377789786021e+00i) -3.4526693498237391370e-4-9.9999982118608047680e-1i) (num-test (exp 1.19209289550781250e-07+3.14124738660679181379e+00i) -1.0000000596046453674e0+3.4526701730061947306e-4i) (num-test (exp 1.19209289550781250e-07-3.14124738660679181379e+00i) -1.0000000596046453674e0-3.4526701730061947306e-4i) (num-test (exp -1.19209289550781250e-07+3.14124738660679181379e+00i) -9.9999982118608047674e-1+3.4526693498255761069e-4i) (num-test (exp -1.19209289550781250e-07-3.14124738660679181379e+00i) -9.9999982118608047674e-1-3.4526693498255761069e-4i) (num-test (exp 1.19209289550781250e-07+3.14193792057279441821e+00i) -1.0000000596046453675e0-3.4526701730037454368e-4i) (num-test (exp 1.19209289550781250e-07-3.14193792057279441821e+00i) -1.0000000596046453675e0+3.4526701730037454368e-4i) (num-test (exp -1.19209289550781250e-07+3.14193792057279441821e+00i) -9.9999982118608047682e-1-3.4526693498231268137e-4i) (num-test (exp -1.19209289550781250e-07-3.14193792057279441821e+00i) -9.9999982118608047682e-1+3.4526693498231268137e-4i) (num-test (exp 1.19209289550781250e-07+4.71204371340168837179e+00i) -3.4526701730068070540e-4-1.0000000596046453674e0i) (num-test (exp 1.19209289550781250e-07-4.71204371340168837179e+00i) -3.4526701730068070540e-4+1.0000000596046453674e0i) (num-test (exp -1.19209289550781250e-07+4.71204371340168837179e+00i) -3.4526693498261884302e-4-9.9999982118608047672e-1i) (num-test (exp -1.19209289550781250e-07-4.71204371340168837179e+00i) -3.4526693498261884302e-4+9.9999982118608047672e-1i) (num-test (exp 1.19209289550781250e-07+4.71273424736769097620e+00i) 3.4526701730031331134e-4-1.0000000596046453676e0i) (num-test (exp 1.19209289550781250e-07-4.71273424736769097620e+00i) 3.4526701730031331134e-4+1.0000000596046453676e0i) (num-test (exp -1.19209289550781250e-07+4.71273424736769097620e+00i) 3.4526693498225144904e-4-9.9999982118608047684e-1i) (num-test (exp -1.19209289550781250e-07-4.71273424736769097620e+00i) 3.4526693498225144904e-4+9.9999982118608047684e-1i) (num-test (exp 1.19209289550781250e-07+6.28284004019658492979e+00i) 1.0000000596046453674e0-3.4526701730074193775e-4i) (num-test (exp 1.19209289550781250e-07-6.28284004019658492979e+00i) 1.0000000596046453674e0+3.4526701730074193775e-4i) (num-test (exp -1.19209289550781250e-07+6.28284004019658492979e+00i) 9.9999982118608047670e-1-3.4526693498268007535e-4i) (num-test (exp -1.19209289550781250e-07-6.28284004019658492979e+00i) 9.9999982118608047670e-1+3.4526693498268007535e-4i) (num-test (exp 1.19209289550781250e-07+6.28353057416258753420e+00i) 1.0000000596046453676e0+3.452670173002520790e-4i) (num-test (exp 1.19209289550781250e-07-6.28353057416258753420e+00i) 1.0000000596046453676e0-3.452670173002520790e-4i) (num-test (exp -1.19209289550781250e-07+6.28353057416258753420e+00i) 9.9999982118608047687e-1+3.4526693498219021671e-4i) (num-test (exp -1.19209289550781250e-07-6.28353057416258753420e+00i) 9.9999982118608047687e-1-3.4526693498219021671e-4i) (num-test (exp 1.19209289550781250e-07+9.42443269378637893396e+00i) -1.0000000596046453677e0+3.4526701729997622396e-4i) (num-test (exp 1.19209289550781250e-07-9.42443269378637893396e+00i) -1.0000000596046453677e0-3.4526701729997622396e-4i) (num-test (exp -1.19209289550781250e-07+9.42443269378637893396e+00i) -9.9999982118608047696e-1+3.4526693498191436174e-4i) (num-test (exp -1.19209289550781250e-07-9.42443269378637893396e+00i) -9.9999982118608047696e-1-3.4526693498191436174e-4i) (num-test (exp 1.19209289550781250e-07+9.42512322775237976202e+00i) -1.0000000596046453679e0-3.4526701729924143584e-4i) (num-test (exp 1.19209289550781250e-07-9.42512322775237976202e+00i) -1.0000000596046453679e0+3.4526701729924143584e-4i) (num-test (exp -1.19209289550781250e-07+9.42512322775237976202e+00i) -9.9999982118608047721e-1-3.4526693498117957380e-4i) (num-test (exp -1.19209289550781250e-07-9.42512322775237976202e+00i) -9.9999982118608047721e-1+3.4526693498117957380e-4i) (num-test (exp 5.0e-01-3.45266983001243932001e-04i) 1.6487211724286834494e0-5.6924900763464865323e-4i) (num-test (exp 5.0e-01+3.45266983001243932001e-04i) 1.6487211724286834494e0+5.6924900763464865323e-4i) (num-test (exp -5.0e-01-3.45266983001243932001e-04i) 6.0653062356058926519e-1-2.0941500681603265022e-4i) (num-test (exp -5.0e-01+3.45266983001243932001e-04i) 6.0653062356058926519e-1+2.0941500681603265022e-4i) (num-test (exp 5.0e-01+1.57045105981189525579e+00i) 5.6924900763484568894e-4+1.6487211724286834493e0i) (num-test (exp 5.0e-01-1.57045105981189525579e+00i) 5.6924900763484568894e-4-1.6487211724286834493e0i) (num-test (exp -5.0e-01+1.57045105981189525579e+00i) 2.0941500681610513560e-4+6.0653062356058926516e-1i) (num-test (exp -5.0e-01-1.57045105981189525579e+00i) 2.0941500681610513560e-4-6.0653062356058926516e-1i) (num-test (exp 5.0e-01+1.57114159377789786021e+00i) -5.6924900763464377883e-4+1.6487211724286834494e0i) (num-test (exp 5.0e-01-1.57114159377789786021e+00i) -5.6924900763464377883e-4-1.6487211724286834494e0i) (num-test (exp -5.0e-01+1.57114159377789786021e+00i) -2.0941500681603085702e-4+6.0653062356058926519e-1i) (num-test (exp -5.0e-01-1.57114159377789786021e+00i) -2.0941500681603085702e-4-6.0653062356058926519e-1i) (num-test (exp 5.0e-01+3.14124738660679181379e+00i) -1.6487211724286834493e0+5.6924900763494664399e-4i) (num-test (exp 5.0e-01-3.14124738660679181379e+00i) -1.6487211724286834493e0-5.6924900763494664399e-4i) (num-test (exp -5.0e-01+3.14124738660679181379e+00i) -6.0653062356058926515e-1+2.0941500681614227489e-4i) (num-test (exp -5.0e-01-3.14124738660679181379e+00i) -6.0653062356058926515e-1-2.0941500681614227489e-4i) (num-test (exp 5.0e-01+3.14193792057279441821e+00i) -1.6487211724286834494e0-5.6924900763454282377e-4i) (num-test (exp 5.0e-01-3.14193792057279441821e+00i) -1.6487211724286834494e0+5.6924900763454282377e-4i) (num-test (exp -5.0e-01+3.14193792057279441821e+00i) -6.0653062356058926520e-1-2.0941500681599371773e-4i) (num-test (exp -5.0e-01-3.14193792057279441821e+00i) -6.0653062356058926520e-1+2.0941500681599371773e-4i) (num-test (exp 5.0e-01+4.71204371340168837179e+00i) -5.6924900763504759905e-4-1.6487211724286834492e0i) (num-test (exp 5.0e-01-4.71204371340168837179e+00i) -5.6924900763504759905e-4+1.6487211724286834492e0i) (num-test (exp -5.0e-01+4.71204371340168837179e+00i) -2.0941500681617941418e-4-6.0653062356058926514e-1i) (num-test (exp -5.0e-01-4.71204371340168837179e+00i) -2.0941500681617941418e-4+6.0653062356058926514e-1i) (num-test (exp 5.0e-01+4.71273424736769097620e+00i) 5.6924900763444186872e-4-1.6487211724286834494e0i) (num-test (exp 5.0e-01-4.71273424736769097620e+00i) 5.6924900763444186872e-4+1.6487211724286834494e0i) (num-test (exp -5.0e-01+4.71273424736769097620e+00i) 2.0941500681595657844e-4-6.0653062356058926521e-1i) (num-test (exp -5.0e-01-4.71273424736769097620e+00i) 2.0941500681595657844e-4+6.0653062356058926521e-1i) (num-test (exp 5.0e-01+6.28284004019658492979e+00i) 1.6487211724286834492e0-5.6924900763514855410e-4i) (num-test (exp 5.0e-01-6.28284004019658492979e+00i) 1.6487211724286834492e0+5.6924900763514855410e-4i) (num-test (exp -5.0e-01+6.28284004019658492979e+00i) 6.0653062356058926512e-1-2.0941500681621655347e-4i) (num-test (exp -5.0e-01-6.28284004019658492979e+00i) 6.0653062356058926512e-1+2.0941500681621655347e-4i) (num-test (exp 5.0e-01+6.28353057416258753420e+00i) 1.6487211724286834495e0+5.6924900763434091366e-4i) (num-test (exp 5.0e-01-6.28353057416258753420e+00i) 1.6487211724286834495e0-5.6924900763434091366e-4i) (num-test (exp -5.0e-01+6.28353057416258753420e+00i) 6.0653062356058926523e-1+2.0941500681591943916e-4i) (num-test (exp -5.0e-01-6.28353057416258753420e+00i) 6.0653062356058926523e-1-2.0941500681591943916e-4i) (num-test (exp 5.0e-01+9.42443269378637893396e+00i) -1.6487211724286834496e0+5.6924900763388610565e-4i) (num-test (exp 5.0e-01-9.42443269378637893396e+00i) -1.6487211724286834496e0-5.6924900763388610565e-4i) (num-test (exp -5.0e-01+9.42443269378637893396e+00i) -6.0653062356058926528e-1+2.0941500681575212464e-4i) (num-test (exp -5.0e-01-9.42443269378637893396e+00i) -6.0653062356058926528e-1-2.0941500681575212464e-4i) (num-test (exp 5.0e-01+9.42512322775237976202e+00i) -1.6487211724286834501e0-5.6924900763267464498e-4i) (num-test (exp 5.0e-01-9.42512322775237976202e+00i) -1.6487211724286834501e0+5.6924900763267464498e-4i) (num-test (exp -5.0e-01+9.42512322775237976202e+00i) -6.0653062356058926544e-1-2.0941500681530645317e-4i) (num-test (exp -5.0e-01-9.42512322775237976202e+00i) -6.0653062356058926544e-1+2.0941500681530645317e-4i) (num-test (exp 1.0e+00-3.45266983001243932001e-04i) 2.7182816664368240602e0-9.3853294721218487636e-4i) (num-test (exp 1.0e+00+3.45266983001243932001e-04i) 2.7182816664368240602e0+9.3853294721218487636e-4i) (num-test (exp -1.0e+00-3.45266983001243932001e-04i) 3.6787941924411912823e-1-1.2701662223785390836e-4i) (num-test (exp -1.0e+00+3.45266983001243932001e-04i) 3.6787941924411912823e-1+1.2701662223785390836e-4i) (num-test (exp 1.0e+00+1.57045105981189525579e+00i) 9.3853294721250973333e-4+2.7182816664368240601e0i) (num-test (exp 1.0e+00-1.57045105981189525579e+00i) 9.3853294721250973333e-4-2.7182816664368240601e0i) (num-test (exp -1.0e+00+1.57045105981189525579e+00i) 1.2701662223789787297e-4+3.6787941924411912822e-1i) (num-test (exp -1.0e+00-1.57045105981189525579e+00i) 1.2701662223789787297e-4-3.6787941924411912822e-1i) (num-test (exp 1.0e+00+1.57114159377789786021e+00i) -9.3853294721217683983e-4+2.7182816664368240602e0i) (num-test (exp 1.0e+00-1.57114159377789786021e+00i) -9.3853294721217683983e-4-2.7182816664368240602e0i) (num-test (exp -1.0e+00+1.57114159377789786021e+00i) -1.2701662223785282074e-4+3.6787941924411912823e-1i) (num-test (exp -1.0e+00-1.57114159377789786021e+00i) -1.2701662223785282074e-4-3.6787941924411912823e-1i) (num-test (exp 1.0e+00+3.14124738660679181379e+00i) -2.718281666436824060e0+9.3853294721267618008e-4i) (num-test (exp 1.0e+00-3.14124738660679181379e+00i) -2.718281666436824060e0-9.3853294721267618008e-4i) (num-test (exp -1.0e+00+3.14124738660679181379e+00i) -3.6787941924411912821e-1+1.2701662223792039909e-4i) (num-test (exp -1.0e+00-3.14124738660679181379e+00i) -3.6787941924411912821e-1-1.2701662223792039909e-4i) (num-test (exp 1.0e+00+3.14193792057279441821e+00i) -2.7182816664368240603e0-9.3853294721201039309e-4i) (num-test (exp 1.0e+00-3.14193792057279441821e+00i) -2.7182816664368240603e0+9.3853294721201039309e-4i) (num-test (exp -1.0e+00+3.14193792057279441821e+00i) -3.6787941924411912824e-1-1.2701662223783029462e-4i) (num-test (exp -1.0e+00-3.14193792057279441821e+00i) -3.6787941924411912824e-1+1.2701662223783029462e-4i) (num-test (exp 1.0e+00+4.71204371340168837179e+00i) -9.3853294721284262682e-4-2.718281666436824060e0i) (num-test (exp 1.0e+00-4.71204371340168837179e+00i) -9.3853294721284262682e-4+2.718281666436824060e0i) (num-test (exp -1.0e+00+4.71204371340168837179e+00i) -1.2701662223794292521e-4-3.6787941924411912820e-1i) (num-test (exp -1.0e+00-4.71204371340168837179e+00i) -1.2701662223794292521e-4+3.6787941924411912820e-1i) (num-test (exp 1.0e+00+4.71273424736769097620e+00i) 9.3853294721184394634e-4-2.7182816664368240603e0i) (num-test (exp 1.0e+00-4.71273424736769097620e+00i) 9.3853294721184394634e-4+2.7182816664368240603e0i) (num-test (exp -1.0e+00+4.71273424736769097620e+00i) 1.2701662223780776850e-4-3.6787941924411912825e-1i) (num-test (exp -1.0e+00-4.71273424736769097620e+00i) 1.2701662223780776850e-4+3.6787941924411912825e-1i) (num-test (exp 1.0e+00+6.28284004019658492979e+00i) 2.7182816664368240599e0-9.3853294721300907357e-4i) (num-test (exp 1.0e+00-6.28284004019658492979e+00i) 2.7182816664368240599e0+9.3853294721300907357e-4i) (num-test (exp -1.0e+00+6.28284004019658492979e+00i) 3.6787941924411912819e-1-1.2701662223796545132e-4i) (num-test (exp -1.0e+00-6.28284004019658492979e+00i) 3.6787941924411912819e-1+1.2701662223796545132e-4i) (num-test (exp 1.0e+00+6.28353057416258753420e+00i) 2.7182816664368240604e0+9.3853294721167749959e-4i) (num-test (exp 1.0e+00-6.28353057416258753420e+00i) 2.7182816664368240604e0-9.3853294721167749959e-4i) (num-test (exp -1.0e+00+6.28353057416258753420e+00i) 3.6787941924411912825e-1+1.2701662223778524238e-4i) (num-test (exp -1.0e+00-6.28353057416258753420e+00i) 3.6787941924411912825e-1-1.2701662223778524238e-4i) (num-test (exp 1.0e+00+9.42443269378637893396e+00i) -2.7182816664368240606e0+9.3853294721092764795e-4i) (num-test (exp 1.0e+00-9.42443269378637893396e+00i) -2.7182816664368240606e0-9.3853294721092764795e-4i) (num-test (exp -1.0e+00+9.42443269378637893396e+00i) -3.6787941924411912829e-1+1.270166222376837610e-4i) (num-test (exp -1.0e+00-9.42443269378637893396e+00i) -3.6787941924411912829e-1-1.270166222376837610e-4i) (num-test (exp 1.0e+00+9.42512322775237976202e+00i) -2.7182816664368240613e0-9.3853294720893028698e-4i) (num-test (exp 1.0e+00-9.42512322775237976202e+00i) -2.7182816664368240613e0+9.3853294720893028698e-4i) (num-test (exp -1.0e+00+9.42512322775237976202e+00i) -3.6787941924411912838e-1-1.2701662223741344759e-4i) (num-test (exp -1.0e+00-9.42512322775237976202e+00i) -3.6787941924411912838e-1+1.2701662223741344759e-4i) (num-test (exp 2.0e+00-3.45266983001243932001e-04i) 7.3890556585085906002e0-2.5511970558169944872e-3i) (num-test (exp 2.0e+00+3.45266983001243932001e-04i) 7.3890556585085906002e0+2.5511970558169944872e-3i) (num-test (exp -2.0e+00-3.45266983001243932001e-04i) 1.3533527517000128913e-1-4.6726804008345889445e-5i) (num-test (exp -2.0e+00+3.45266983001243932001e-04i) 1.3533527517000128913e-1+4.6726804008345889445e-5i) (num-test (exp 2.0e+00+1.57045105981189525579e+00i) 2.551197055817877540e-3+7.3890556585085905999e0i) (num-test (exp 2.0e+00-1.57045105981189525579e+00i) 2.551197055817877540e-3-7.3890556585085905999e0i) (num-test (exp -2.0e+00+1.57045105981189525579e+00i) 4.6726804008362063122e-5+1.3533527517000128913e-1i) (num-test (exp -2.0e+00-1.57045105981189525579e+00i) 4.6726804008362063122e-5-1.3533527517000128913e-1i) (num-test (exp 2.0e+00+1.57114159377789786021e+00i) -2.5511970558169726417e-3+7.3890556585085906002e0i) (num-test (exp 2.0e+00-1.57114159377789786021e+00i) -2.5511970558169726417e-3-7.3890556585085906002e0i) (num-test (exp -2.0e+00+1.57114159377789786021e+00i) -4.6726804008345489330e-5+1.3533527517000128913e-1i) (num-test (exp -2.0e+00-1.57114159377789786021e+00i) -4.6726804008345489330e-5-1.3533527517000128913e-1i) (num-test (exp 2.0e+00+3.14124738660679181379e+00i) -7.3890556585085905998e0+2.5511970558183299892e-3i) (num-test (exp 2.0e+00-3.14124738660679181379e+00i) -7.3890556585085905998e0-2.5511970558183299892e-3i) (num-test (exp -2.0e+00+3.14124738660679181379e+00i) -1.3533527517000128912e-1+4.6726804008370350017e-5i) (num-test (exp -2.0e+00-3.14124738660679181379e+00i) -1.3533527517000128912e-1-4.6726804008370350017e-5i) (num-test (exp 2.0e+00+3.14193792057279441821e+00i) -7.3890556585085906004e0-2.5511970558165201925e-3i) (num-test (exp 2.0e+00-3.14193792057279441821e+00i) -7.3890556585085906004e0+2.5511970558165201925e-3i) (num-test (exp -2.0e+00+3.14193792057279441821e+00i) -1.3533527517000128914e-1-4.6726804008337202435e-5i) (num-test (exp -2.0e+00-3.14193792057279441821e+00i) -1.3533527517000128914e-1+4.6726804008337202435e-5i) (num-test (exp 2.0e+00+4.71204371340168837179e+00i) -2.5511970558187824384e-3-7.3890556585085905996e0i) (num-test (exp 2.0e+00-4.71204371340168837179e+00i) -2.5511970558187824384e-3+7.3890556585085905996e0i) (num-test (exp -2.0e+00+4.71204371340168837179e+00i) -4.6726804008378636913e-5-1.3533527517000128912e-1i) (num-test (exp -2.0e+00-4.71204371340168837179e+00i) -4.6726804008378636913e-5+1.3533527517000128912e-1i) (num-test (exp 2.0e+00+4.71273424736769097620e+00i) 2.5511970558160677434e-3-7.3890556585085906006e0i) (num-test (exp 2.0e+00-4.71273424736769097620e+00i) 2.5511970558160677434e-3+7.3890556585085906006e0i) (num-test (exp -2.0e+00+4.71273424736769097620e+00i) 4.6726804008328915539e-5-1.3533527517000128914e-1i) (num-test (exp -2.0e+00-4.71273424736769097620e+00i) 4.6726804008328915539e-5+1.3533527517000128914e-1i) (num-test (exp 2.0e+00+6.28284004019658492979e+00i) 7.3890556585085905995e0-2.5511970558192348875e-3i) (num-test (exp 2.0e+00-6.28284004019658492979e+00i) 7.3890556585085905995e0+2.5511970558192348875e-3i) (num-test (exp -2.0e+00+6.28284004019658492979e+00i) 1.3533527517000128912e-1-4.6726804008386923808e-5i) (num-test (exp -2.0e+00-6.28284004019658492979e+00i) 1.3533527517000128912e-1+4.6726804008386923808e-5i) (num-test (exp 2.0e+00+6.28353057416258753420e+00i) 7.3890556585085906007e0+2.5511970558156152942e-3i) (num-test (exp 2.0e+00-6.28353057416258753420e+00i) 7.3890556585085906007e0-2.5511970558156152942e-3i) (num-test (exp -2.0e+00+6.28353057416258753420e+00i) 1.3533527517000128914e-1+4.6726804008320628644e-5i) (num-test (exp -2.0e+00-6.28353057416258753420e+00i) 1.3533527517000128914e-1-4.6726804008320628644e-5i) (num-test (exp 2.0e+00+9.42443269378637893396e+00i) -7.3890556585085906014e0+2.5511970558135769861e-3i) (num-test (exp 2.0e+00-9.42443269378637893396e+00i) -7.3890556585085906014e0-2.5511970558135769861e-3i) (num-test (exp -2.0e+00+9.42443269378637893396e+00i) -1.3533527517000128916e-1+4.6726804008283295729e-5i) (num-test (exp -2.0e+00-9.42443269378637893396e+00i) -1.3533527517000128916e-1-4.6726804008283295729e-5i) (num-test (exp 2.0e+00+9.42512322775237976202e+00i) -7.3890556585085906033e0-2.5511970558081475961e-3i) (num-test (exp 2.0e+00-9.42512322775237976202e+00i) -7.3890556585085906033e0+2.5511970558081475961e-3i) (num-test (exp -2.0e+00+9.42512322775237976202e+00i) -1.3533527517000128919e-1-4.6726804008183852982e-5i) (num-test (exp -2.0e+00-9.42512322775237976202e+00i) -1.3533527517000128919e-1+4.6726804008183852982e-5i) (num-test (exp -1000) 0.0) (num-test (exp -1000000) 0.0) (num-test (exp (complex 0.0 (* 0.5 pi))) 0+i) (num-test (exp (complex 0.0 pi)) -1) (num-test (exp 100.0) 2.688117141816135e43) (num-test (exp 500.0) 1.40359221785284E+217) (num-test (exp -100.0) 3.720075976020836E-44) (num-test (exp -500.0) 7.12457640674129E-218) (num-test (exp 5e-10) 1.000000000500000000125000031161629077797E0) (num-test (- (expt (exp 5e-8) 2e7) (exp 1)) 0.0) (num-test (exp -2.225073858507201399999999999999999999996E-308) 1.000E0) (num-test (exp 1.110223024625156799999999999999999999997E-16) 1.000000000000000111022302462515686162976E0) (num-test (exp 1/9223372036854775807) 1.000000000000000000108420217248550443418E0) (num-test (exp -1/9223372036854775807) 9.999999999999999998915797827514495565934E-1) (num-test (exp (* pi (sqrt 163))) 262537412640768743.999999999999) (num-test (exp (* pi (sqrt 17))) 422150.99767568) (num-test (exp (* pi (sqrt 18))) 614551.992885619) (num-test (exp (* pi (sqrt 22))) 2508951.998257424) (num-test (exp (* pi (sqrt 6))) 2197.9908695437) (num-test (exp (* pi (sqrt 719))) 3.8426143735395488914902942778058291929999e+36) (num-test (exp (complex 0.0 pi)) -1.0) (for-each (lambda (num-and-val) (let ((num (car num-and-val)) (val (cadr num-and-val))) (num-test-1 'exp num (exp num) val))) (vector (list 0 1) (list 1 2.718281828459) (list 2 7.3890560989307) (list 3 20.085536923188) (list -1 0.36787944117144) (list -2 0.13533528323661) (list -3 0.049787068367864) (list -9223372036854775808 0.0) (list 1/2 1.6487212707001) (list 1/3 1.3956124250861) (list -1/2 0.60653065971263) (list -1/3 0.71653131057379) (list 1/9223372036854775807 1.0) (list 0.0 1.0) (list 1.0 2.718281828459) (list 2.0 7.3890560989307) (list -2.0 0.13533528323661) (list 1.000000000000000000000000000000000000002E-309 1.000E0) (list -inf.0 0.0) (list 0+1i 0.54030230586814+0.8414709848079i) (list 0+2i -0.41614683654714+0.90929742682568i) (list 0-1i 0.54030230586814-0.8414709848079i) (list 1+1i 1.4686939399159+2.2873552871788i) (list 1-1i 1.4686939399159-2.2873552871788i) (list -1+1i 0.19876611034641+0.30955987565311i) (list -1-1i 0.19876611034641-0.30955987565311i) (list 0.1+0.1i 1.0996496668294+0.1103329887302i) (list 1e-16+1e-16i 1+1e-16i) )) (test (exp) 'error) (test (exp "hi") 'error) (test (exp 1.0+23.0i 1.0+23.0i) 'error) (for-each (lambda (arg) (test (exp arg) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) (if (not with-bignums) (begin (test (infinite? (exp (expt 2 16))) #t) (test (infinite? (exp (expt 2 54))) #t) (test (infinite? (exp (exp 1e3))) #t) )) (if with-bignums (begin (let ((val1 (* 1000 (- (exp 30) 10686474581524))) (val2 (* 1000 (- (exp (bignum "30")) 10686474581524)))) (if (> (abs (- val1 val2)) 1) (format-logged #t "(exp 30): ~A ~A~%" val1 val2))) (num-test (exp (* 172.60813659204 (log 172.60813659204))) 1.364508485146898675293943657160611234948E386) ; not inf! (num-test (exp 800.0) 2.726374572112566567364779546367269757963E347) (num-test (exp -800.0) 3.667874584177687213455495654260798215465E-348) (num-test (exp 100) 2.688117141816135448412625551580013587359E43) (num-test (exp 50.0) 5.184705528587072464087453322933485384827E21))) (if with-bignums (let ((old-prec (*s7* 'bignum-precision))) (set! (*s7* 'bignum-precision) 500) (let ((exps (list ; table[Exp[k/10], {k, 0, 30}] 1.00000000000000000000000000000000000000000000000000000000000000000000 1.10517091807564762481170782649024666822454719473751871879286328944096 1.22140275816016983392107199463967417030758094152050364127342509859920 1.34985880757600310398374431332800733037829969735936580304991798993961 1.49182469764127031782485295283722228064328277393742528159563315007236 1.64872127070012814684865078781416357165377610071014801157507931164066 1.82211880039050897487536766816286451338223880854643538632054747658881 2.01375270747047652162454938858306527001754239414586731156898930087978 2.22554092849246760457953753139507675705363413504848459611858395555662 2.45960311115694966380012656360247069542177230644008302074854573665746 2.71828182845904523536028747135266249775724709369995957496696762772407 3.00416602394643311205840795358867239328268102601627276212975286052863 3.32011692273654748953076742960164432007363176479282675728202180154077 3.66929666761924422045748991601148625143151888455755146725622649459660 4.05519996684467458722410889522862025216756114168404107165223289450693 4.48168907033806482260205546011927581900574986836966705677265008278593 4.95303242439511480365428635642396425641303112355664964787158190112430 5.47394739172719976079086266300909670070076114490748605875498633804484 6.04964746441294608373102395302772533816116344511729126161486476549696 6.68589444227926941607253072769286145380311864710852264561241990317501 7.38905609893065022723042746057500781318031557055184732408712782252257 8.16616991256765007344972741047863128518315260430523695926385375737882 9.02501349943412092647177716688866402972021659669817926079803719255720 9.97418245481472073995761515690885800147870119368402956369142191697585 11.02317638064160165223793976966780200851716306933940388430829005877357 12.18249396070347343807017595116796618318276779006316131156039834183818 13.46373803500169039775082533258411724479408609657822907153993787261197 14.87973172487283411186899301946839578068879752075547683852481232002013 16.44464677109704987149801601092501556372435769719962288653996273295166 18.17414536944306094267625657412806698753309200930534632364757918918540 20.08553692318766774092852965458171789698790783855415014437893422969884))) (do ((i 0 (+ i 1))) ((= i 30)) (let ((val (exp (/ i (bignum "10"))))) (if (> (magnitude (- val (list-ref exps i))) 1e-36) (format-logged #t ";(exp ~A) -> ~A ~A~%[~A]~%" (/ i 10) val (list-ref exps i) (magnitude (- val (list-ref exps i)))))))) (set! (*s7* 'bignum-precision) old-prec))) ;;; -------------------------------------------------------------------------------- ;;; log ;;; -------------------------------------------------------------------------------- (num-test (* 0-2i (log 0+i)) pi) (num-test (* 2 0+i (log (/ 1-i 1+i))) pi) (num-test (+ 100 (expt 10.0 15) (- (expt 10.0 15))) 100.0) (num-test (/ (log -1) (sqrt -1)) pi) (num-test (/ (log -8) (log 2)) 3+4.5323601418272i) (num-test (/ 53453 (log 53453)) 4910.0000012208) (num-test (exp (log (expt 10.0 -16))) 1e-16) (num-test (exp (log (expt 10.0 -36))) 1e-36) (num-test (exp (log (expt 10.0 16))) 1e16) (num-test (exp (log (expt 10.0 36))) 1e36) (num-test (exp (log 1000)) 1000.0) (num-test (exp (log 1000000)) 1000000.0) (num-test (exp (log 1000000000)) 1000000000.0) (num-test (exp (log 8)) 8.0) (num-test (expt (+ 1 1e-10) (log 100.0 (+ 1 1e-10))) 100.0) (num-test (expt (+ 1 1e-15) (log 100.0 (+ 1 1e-15))) 100.0) ; 16 doesn't work if not gmp (num-test (expt -2.0 0.13926097063622-0.63118087262379i) 8.0) (num-test (expt -2.0 0.26160508088635-0.052598406051983i) 1.0+i) (num-test (expt 1.0+i 0.97790391649038-2.2161063668189i) 8.0) (num-test (log (/ (+ 1 (sqrt 5)) 2)) (acosh (/ (sqrt 5) 2))) (num-test (log (exp 0.0000001)) 0.0000001) (num-test (log (exp 0.0001)) 0.0001) (num-test (log (exp 0.1)) 0.1) (num-test (log (exp 8)) 8.0) (num-test (log (expt 2 1022)) 7.083964185322641062244112281302564525734E2) (num-test (log (expt 2 125)) 8.664339756999316367715401518227207100938E1) (num-test (log (expt 3/2 10) 3/2) 10.0) (num-test (log (log (log -1))) 0.66457192224882+0.9410294873126i) (num-test (log (sqrt (- (expt 10 17) 1))) 1.957197329044938830915292736481709573957E1) (num-test (log (sqrt (- (expt 10 20) 1))) 2.302585092994045684017491454684364207599E1) (num-test (log (sqrt (- (expt 10 9) 1))) 1.036163291797320557783096154591297226743E1) (num-test (log (sqrt -2) -2) 0.5) (num-test (log (sqrt 1+i) 1+i) 0.5) (num-test (log (sqrt 2) 2) 0.5) (num-test (log -0.0+0.00000001i) -18.42068074395237+1.57079632679490i) (num-test (log -0.0+1.0i) 0.0+1.57079632679490i) (num-test (log -0.0+1234.0i) 7.11801620446533+1.57079632679490i) (num-test (log -0.0+1234000000.0i) 20.93352676242961+1.57079632679490i) (num-test (log -0.0+2.71828182845905i) 1.0+1.57079632679490i) (num-test (log -0.0+3.14159265358979i) 1.14472988584940+1.57079632679490i) (num-test (log -0.0-0.00000001i) -18.42068074395237-1.57079632679490i) (num-test (log -0.0-1.0i) 0.0-1.57079632679490i) (num-test (log -0.0-1234.0i) 7.11801620446533-1.57079632679490i) (num-test (log -0.0-1234000000.0i) 20.93352676242961-1.57079632679490i) (num-test (log -0.0-2.71828182845905i) 1.0-1.57079632679490i) (num-test (log -0.0-3.14159265358979i) 1.14472988584940-1.57079632679490i) (num-test (log -0.00000001) -18.42068074395237+3.14159265358979i) (num-test (log -0.00000001+0.00000001i) -18.07410715367239+2.35619449019234i) (num-test (log -0.00000001+0.0i) -18.42068074395237+3.14159265358979i) (num-test (log -0.00000001+1.0i) 0.0+1.57079633679490i) (num-test (log -0.00000001+1234.0i) 7.11801620446533+1.57079632680300i) (num-test (log -0.00000001+1234000000.0i) 20.93352676242961+1.57079632679490i) (num-test (log -0.00000001+2.71828182845905i) 1.0+1.57079633047369i) (num-test (log -0.00000001+3.14159265358979i) 1.14472988584940+1.57079632997800i) (num-test (log -0.00000001-0.00000001i) -18.07410715367239-2.35619449019234i) (num-test (log -0.00000001-0.0i) -18.42068074395237+3.14159265358979i) (num-test (log -0.00000001-1.0i) 0.0-1.57079633679490i) (num-test (log -0.00000001-1234.0i) 7.11801620446533-1.57079632680300i) (num-test (log -0.00000001-1234000000.0i) 20.93352676242961-1.57079632679490i) (num-test (log -0.00000001-2.71828182845905i) 1.0-1.57079633047369i) (num-test (log -0.00000001-3.14159265358979i) 1.14472988584940-1.57079632997800i) (num-test (log -0.1e001) (complex 0.0 pi)) (num-test (log -1 -1) 1.0) (num-test (log -1) 0.0+3.141592653589793238462643383279502884197169399375105820974944592307816406286198E0i) (num-test (log -1) 0.0+3.14159265358979i) (num-test (log -1.0) 0.0+3.14159265358979i) (num-test (log -1.0+0.00000001i) 0.0+3.14159264358979i) (num-test (log -1.0+0.0i) 0.0+3.14159265358979i) (num-test (log -1.0+1.0i) 0.34657359027997+2.35619449019234i) (num-test (log -1.0+1234.0i) 7.11801653281724+1.57160669938898i) (num-test (log -1.0+1234000000.0i) 20.93352676242961+1.57079632760527i) (num-test (log -1.0+2.71828182845905i) 1.06346400552149+1.92330974857252i) (num-test (log -1.0+3.14159265358979i) 1.19298515341341+1.87896539791088i) (num-test (log -1.0-0.00000001i) 0.0-3.14159264358979i) (num-test (log -1.0-0.0i) 0.0+3.14159265358979i) (num-test (log -1.0-1.0i) 0.34657359027997-2.35619449019234i) (num-test (log -1.0-1234.0i) 7.11801653281724-1.57160669938898i) (num-test (log -1.0-1234000000.0i) 20.93352676242961-1.57079632760527i) (num-test (log -1.0-2.71828182845905i) 1.06346400552149-1.92330974857252i) (num-test (log -1.0-3.14159265358979i) 1.19298515341341-1.87896539791088i) (num-test (log -1.0e+00+0.0e+00i) 0+3.1415926535897932385e0i) (num-test (log -1.0e+00+1.0e+00i) 3.4657359027997265471e-1+2.3561944901923449288e0i) (num-test (log -1.0e+00+1.0e+00i) 3.4657359027997265471e-1+2.3561944901923449288e0i) (num-test (log -1.0e+00+1.19209289550781250e-07i) 7.1054273576009513716e-15+3.1415925343805036877e0i) (num-test (log -1.0e+00+1.19209289550781250e-07i) 7.1054273576009513716e-15+3.1415925343805036877e0i) (num-test (log -1.0e+00+2.0e+00i) 8.0471895621705018730e-1+2.0344439357957027354e0i) (num-test (log -1.0e+00+2.0e+00i) 8.0471895621705018730e-1+2.0344439357957027354e0i) (num-test (log -1.0e+00+5.0e-01i) 1.1157177565710487788e-1+2.6779450445889871222e0i) (num-test (log -1.0e+00+5.0e-01i) 1.1157177565710487788e-1+2.6779450445889871222e0i) (num-test (log -1.0e+00+8.3886080e+06i) 1.5942385152878749222e1+1.570796446004186170e0i) (num-test (log -1.0e+00+8.3886080e+06i) 1.5942385152878749222e1+1.570796446004186170e0i) (num-test (log -1.0e+00-1.0e+00i) 3.4657359027997265471e-1-2.3561944901923449288e0i) (num-test (log -1.0e+00-1.0e+00i) 3.4657359027997265471e-1-2.3561944901923449288e0i) (num-test (log -1.0e+00-1.19209289550781250e-07i) 7.1054273576009513716e-15-3.1415925343805036877e0i) (num-test (log -1.0e+00-1.19209289550781250e-07i) 7.1054273576009513716e-15-3.1415925343805036877e0i) (num-test (log -1.0e+00-2.0e+00i) 8.0471895621705018730e-1-2.0344439357957027354e0i) (num-test (log -1.0e+00-2.0e+00i) 8.0471895621705018730e-1-2.0344439357957027354e0i) (num-test (log -1.0e+00-5.0e-01i) 1.1157177565710487788e-1-2.6779450445889871222e0i) (num-test (log -1.0e+00-5.0e-01i) 1.1157177565710487788e-1-2.6779450445889871222e0i) (num-test (log -1.0e+00-8.3886080e+06i) 1.5942385152878749222e1-1.570796446004186170e0i) (num-test (log -1.0e+00-8.3886080e+06i) 1.5942385152878749222e1-1.570796446004186170e0i) (num-test (log -1.19209289550781250e-07+0.0e+00i) -1.5942385152878742117e1+3.1415926535897932385e0i) (num-test (log -1.19209289550781250e-07+1.0e+00i) 7.1054273576009513716e-15+1.570796446004186170e0i) (num-test (log -1.19209289550781250e-07+1.0e+00i) 7.1054273576009513716e-15+1.570796446004186170e0i) (num-test (log -1.19209289550781250e-07+1.19209289550781250e-07i) -1.5595811562598769462e1+2.3561944901923449288e0i) (num-test (log -1.19209289550781250e-07+1.19209289550781250e-07i) -1.5595811562598769462e1+2.3561944901923449288e0i) (num-test (log -1.19209289550781250e-07+2.0e+00i) 6.9314718055994708577e-1+1.5707963863995413946e0i) (num-test (log -1.19209289550781250e-07+2.0e+00i) 6.9314718055994708577e-1+1.5707963863995413946e0i) (num-test (log -1.19209289550781250e-07+5.0e-01i) -6.9314718055991688771e-1+1.5707965652134757208e0i) (num-test (log -1.19209289550781250e-07+5.0e-01i) -6.9314718055991688771e-1+1.5707965652134757208e0i) (num-test (log -1.19209289550781250e-07+8.3886080e+06i) 1.5942385152878742117e1+1.5707963267949108301e0i) (num-test (log -1.19209289550781250e-07+8.3886080e+06i) 1.5942385152878742117e1+1.5707963267949108301e0i) (num-test (log -1.19209289550781250e-07-1.0e+00i) 7.1054273576009513716e-15-1.570796446004186170e0i) (num-test (log -1.19209289550781250e-07-1.0e+00i) 7.1054273576009513716e-15-1.570796446004186170e0i) (num-test (log -1.19209289550781250e-07-1.19209289550781250e-07i) -1.5595811562598769462e1-2.3561944901923449288e0i) (num-test (log -1.19209289550781250e-07-1.19209289550781250e-07i) -1.5595811562598769462e1-2.3561944901923449288e0i) (num-test (log -1.19209289550781250e-07-2.0e+00i) 6.9314718055994708577e-1-1.5707963863995413946e0i) (num-test (log -1.19209289550781250e-07-2.0e+00i) 6.9314718055994708577e-1-1.5707963863995413946e0i) (num-test (log -1.19209289550781250e-07-5.0e-01i) -6.9314718055991688771e-1-1.5707965652134757208e0i) (num-test (log -1.19209289550781250e-07-5.0e-01i) -6.9314718055991688771e-1-1.5707965652134757208e0i) (num-test (log -1.19209289550781250e-07-8.3886080e+06i) 1.5942385152878742117e1-1.5707963267949108301e0i) (num-test (log -1.19209289550781250e-07-8.3886080e+06i) 1.5942385152878742117e1-1.5707963267949108301e0i) (num-test (log -1/1) 0.0+3.14159265358979i) (num-test (log -1/10) -2.30258509299405+3.14159265358979i) (num-test (log -1/1234) -7.11801620446533+3.14159265358979i) (num-test (log -1/1234000000) -20.93352676242961+3.14159265358979i) (num-test (log -1/2) -0.69314718055995+3.14159265358979i) (num-test (log -1/3) -1.09861228866811+3.14159265358979i) (num-test (log -1/362880) -12.80182748008147+3.14159265358979i) (num-test (log -1/500029) -13.12242137572239+3.14159265358979i) (num-test (log -10) 2.30258509299405+3.14159265358979i) (num-test (log -10/1) 2.30258509299405+3.14159265358979i) (num-test (log -10/10) 0.0+3.14159265358979i) (num-test (log -10/1234) -4.81543111147129+3.14159265358979i) (num-test (log -10/1234000000) -18.63094166943556+3.14159265358979i) (num-test (log -10/2) 1.60943791243410+3.14159265358979i) (num-test (log -10/3) 1.20397280432594+3.14159265358979i) (num-test (log -10/362880) -10.49924238708742+3.14159265358979i) (num-test (log -10/500029) -10.81983628272835+3.14159265358979i) (num-test (log -1234) 7.11801620446533+3.14159265358979i) (num-test (log -1234.0) 7.11801620446533+3.14159265358979i) (num-test (log -1234.0+0.00000001i) 7.11801620446533+3.14159265358169i) (num-test (log -1234.0+0.0i) 7.11801620446533+3.14159265358979i) (num-test (log -1234.0+1.0i) 7.11801653281724+3.14078228099571i) (num-test (log -1234.0+1234.0i) 7.46458979474531+2.35619449019234i) (num-test (log -1234.0+1234000000.0i) 20.93352676243011+1.57079732679490i) (num-test (log -1234.0+2.71828182845905i) 7.11801863067090+3.13938983557381i) (num-test (log -1234.0+3.14159265358979i) 7.11801944515932+3.13904679794449i) (num-test (log -1234.0-0.00000001i) 7.11801620446533-3.14159265358169i) (num-test (log -1234.0-0.0i) 7.11801620446533+3.14159265358979i) (num-test (log -1234.0-1.0i) 7.11801653281724-3.14078228099571i) (num-test (log -1234.0-1234.0i) 7.46458979474531-2.35619449019234i) (num-test (log -1234.0-1234000000.0i) 20.93352676243011-1.57079732679490i) (num-test (log -1234.0-2.71828182845905i) 7.11801863067090-3.13938983557381i) (num-test (log -1234.0-3.14159265358979i) 7.11801944515932-3.13904679794449i) (num-test (log -1234/1) 7.11801620446533+3.14159265358979i) (num-test (log -1234/10) 4.81543111147129+3.14159265358979i) (num-test (log -1234/1234) 0.0+3.14159265358979i) (num-test (log -1234/1234000000) -13.81551055796427+3.14159265358979i) (num-test (log -1234/2) 6.42486902390539+3.14159265358979i) (num-test (log -1234/3) 6.01940391579722+3.14159265358979i) (num-test (log -1234/362880) -5.68381127561614+3.14159265358979i) (num-test (log -1234/500029) -6.00440517125706+3.14159265358979i) (num-test (log -1234000000) 20.93352676242961+3.14159265358979i) (num-test (log -1234000000.0) 20.93352676242961+3.14159265358979i) (num-test (log -1234000000.0+0.00000001i) 20.93352676242961+3.14159265358979i) (num-test (log -1234000000.0+0.0i) 20.93352676242961+3.14159265358979i) (num-test (log -1234000000.0+1.0i) 20.93352676242961+3.14159265277942i) (num-test (log -1234000000.0+1234.0i) 20.93352676243011+3.14159165358979i) (num-test (log -1234000000.0+1234000000.0i) 21.28010035270958+2.35619449019234i) (num-test (log -1234000000.0+2.71828182845905i) 20.93352676242961+3.14159265138697i) (num-test (log -1234000000.0+3.14159265358979i) 20.93352676242961+3.14159265104393i) (num-test (log -1234000000.0-0.00000001i) 20.93352676242961-3.14159265358979i) (num-test (log -1234000000.0-0.0i) 20.93352676242961+3.14159265358979i) (num-test (log -1234000000.0-1.0i) 20.93352676242961-3.14159265277942i) (num-test (log -1234000000.0-1234.0i) 20.93352676243011-3.14159165358979i) (num-test (log -1234000000.0-1234000000.0i) 21.28010035270958-2.35619449019234i) (num-test (log -1234000000.0-2.71828182845905i) 20.93352676242961-3.14159265138697i) (num-test (log -1234000000.0-3.14159265358979i) 20.93352676242961-3.14159265104393i) (num-test (log -1234000000/1) 20.93352676242961+3.14159265358979i) (num-test (log -1234000000/10) 18.63094166943556+3.14159265358979i) (num-test (log -1234000000/1234) 13.81551055796427+3.14159265358979i) (num-test (log -1234000000/1234000000) 0.0+3.14159265358979i) (num-test (log -1234000000/2) 20.24037958186966+3.14159265358979i) (num-test (log -1234000000/3) 19.83491447376150+3.14159265358979i) (num-test (log -1234000000/362880) 8.13169928234814+3.14159265358979i) (num-test (log -1234000000/500029) 7.81110538670721+3.14159265358979i) (num-test (log -2 -2) 1) (num-test (log -2) 0.69314718055995+3.14159265358979i) (num-test (log -2.0e+00+0.0e+00i) 6.9314718055994530942e-1+3.1415926535897932385e0i) (num-test (log -2.0e+00+1.0e+00i) 8.0471895621705018730e-1+2.6779450445889871222e0i) (num-test (log -2.0e+00+1.0e+00i) 8.0471895621705018730e-1+2.6779450445889871222e0i) (num-test (log -2.0e+00+1.19209289550781250e-07i) 6.9314718055994708577e-1+3.1415925939851484631e0i) (num-test (log -2.0e+00+1.19209289550781250e-07i) 6.9314718055994708577e-1+3.1415925939851484631e0i) (num-test (log -2.0e+00+2.0e+00i) 1.0397207708399179641e0+2.3561944901923449288e0i) (num-test (log -2.0e+00+2.0e+00i) 1.0397207708399179641e0+2.3561944901923449288e0i) (num-test (log -2.0e+00+5.0e-01i) 7.2345949146816273071e-1+2.8966139904629290843e0i) (num-test (log -2.0e+00+5.0e-01i) 7.2345949146816273071e-1+2.8966139904629290843e0i) (num-test (log -2.0e+00+8.3886080e+06i) 1.5942385152878770538e1+1.5707965652134757208e0i) (num-test (log -2.0e+00+8.3886080e+06i) 1.5942385152878770538e1+1.5707965652134757208e0i) (num-test (log -2.0e+00-1.0e+00i) 8.0471895621705018730e-1-2.6779450445889871222e0i) (num-test (log -2.0e+00-1.0e+00i) 8.0471895621705018730e-1-2.6779450445889871222e0i) (num-test (log -2.0e+00-1.19209289550781250e-07i) 6.9314718055994708577e-1-3.1415925939851484631e0i) (num-test (log -2.0e+00-1.19209289550781250e-07i) 6.9314718055994708577e-1-3.1415925939851484631e0i) (num-test (log -2.0e+00-2.0e+00i) 1.0397207708399179641e0-2.3561944901923449288e0i) (num-test (log -2.0e+00-2.0e+00i) 1.0397207708399179641e0-2.3561944901923449288e0i) (num-test (log -2.0e+00-5.0e-01i) 7.2345949146816273071e-1-2.8966139904629290843e0i) (num-test (log -2.0e+00-5.0e-01i) 7.2345949146816273071e-1-2.8966139904629290843e0i) (num-test (log -2.0e+00-8.3886080e+06i) 1.5942385152878770538e1-1.5707965652134757208e0i) (num-test (log -2.0e+00-8.3886080e+06i) 1.5942385152878770538e1-1.5707965652134757208e0i) (num-test (log -2.71828182845905) 1.0+3.14159265358979i) (num-test (log -2.71828182845905+0.00000001i) 1.0+3.14159264991100i) (num-test (log -2.71828182845905+0.0i) 1.0+3.14159265358979i) (num-test (log -2.71828182845905+1.0i) 1.06346400552149+2.78907923181217i) (num-test (log -2.71828182845905+1234.0i) 7.11801863067090+1.57299914481088i) (num-test (log -2.71828182845905+1234000000.0i) 20.93352676242961+1.57079632899772i) (num-test (log -2.71828182845905+2.71828182845905i) 1.34657359027997+2.35619449019234i) (num-test (log -2.71828182845905+3.14159265358979i) 1.42415703773030+2.28408086723395i) (num-test (log -2.71828182845905-0.00000001i) 1.0-3.14159264991100i) (num-test (log -2.71828182845905-0.0i) 1.0+3.14159265358979i) (num-test (log -2.71828182845905-1.0i) 1.06346400552149-2.78907923181217i) (num-test (log -2.71828182845905-1234.0i) 7.11801863067090-1.57299914481088i) (num-test (log -2.71828182845905-1234000000.0i) 20.93352676242961-1.57079632899772i) (num-test (log -2.71828182845905-2.71828182845905i) 1.34657359027997-2.35619449019234i) (num-test (log -2.71828182845905-3.14159265358979i) 1.42415703773030-2.28408086723395i) (num-test (log -2/1) 0.69314718055995+3.14159265358979i) (num-test (log -2/10) -1.60943791243410+3.14159265358979i) (num-test (log -2/1234) -6.42486902390539+3.14159265358979i) (num-test (log -2/1234000000) -20.24037958186966+3.14159265358979i) (num-test (log -2/2) 0.0+3.14159265358979i) (num-test (log -2/3) -0.40546510810816+3.14159265358979i) (num-test (log -2/362880) -12.10868029952152+3.14159265358979i) (num-test (log -2/500029) -12.42927419516245+3.14159265358979i) (num-test (log -3) 1.09861228866811+3.14159265358979i) (num-test (log -3.14159265358979) 1.14472988584940+3.14159265358979i) (num-test (log -3.14159265358979+0.00000001i) 1.14472988584940+3.14159265040669i) (num-test (log -3.14159265358979+0.0i) 1.14472988584940+3.14159265358979i) (num-test (log -3.14159265358979+1.0i) 1.19298515341341+2.83342358247381i) (num-test (log -3.14159265358979+1234.0i) 7.11801944515932+1.57334218244020i) (num-test (log -3.14159265358979+1234000000.0i) 20.93352676242961+1.57079632934076i) (num-test (log -3.14159265358979+2.71828182845905i) 1.42415703773030+2.42830811315074i) (num-test (log -3.14159265358979+3.14159265358979i) 1.49130347612937+2.35619449019234i) (num-test (log -3.14159265358979-0.00000001i) 1.14472988584940-3.14159265040669i) (num-test (log -3.14159265358979-0.0i) 1.14472988584940+3.14159265358979i) (num-test (log -3.14159265358979-1.0i) 1.19298515341341-2.83342358247381i) (num-test (log -3.14159265358979-1234.0i) 7.11801944515932-1.57334218244020i) (num-test (log -3.14159265358979-1234000000.0i) 20.93352676242961-1.57079632934076i) (num-test (log -3.14159265358979-2.71828182845905i) 1.42415703773030-2.42830811315074i) (num-test (log -3.14159265358979-3.14159265358979i) 1.49130347612937-2.35619449019234i) (num-test (log -3/1) 1.09861228866811+3.14159265358979i) (num-test (log -3/10) -1.20397280432594+3.14159265358979i) (num-test (log -3/1234) -6.01940391579722+3.14159265358979i) (num-test (log -3/1234000000) -19.83491447376150+3.14159265358979i) (num-test (log -3/2) 0.40546510810816+3.14159265358979i) (num-test (log -3/3) 0.0+3.14159265358979i) (num-test (log -3/362880) -11.70321519141336+3.14159265358979i) (num-test (log -3/500029) -12.02380908705428+3.14159265358979i) (num-test (log -362880) 12.80182748008147+3.14159265358979i) (num-test (log -362880/1) 12.80182748008147+3.14159265358979i) (num-test (log -362880/10) 10.49924238708742+3.14159265358979i) (num-test (log -362880/1234) 5.68381127561614+3.14159265358979i) (num-test (log -362880/1234000000) -8.13169928234814+3.14159265358979i) (num-test (log -362880/2) 12.10868029952152+3.14159265358979i) (num-test (log -362880/3) 11.70321519141336+3.14159265358979i) (num-test (log -362880/362880) 0.0+3.14159265358979i) (num-test (log -362880/500029) -0.32059389564092+3.14159265358979i) (num-test (log -5.0e-01+0.0e+00i) -6.9314718055994530942e-1+3.1415926535897932385e0i) (num-test (log -5.0e-01+1.0e+00i) 1.1157177565710487788e-1+2.0344439357957027354e0i) (num-test (log -5.0e-01+1.0e+00i) 1.1157177565710487788e-1+2.0344439357957027354e0i) (num-test (log -5.0e-01+1.19209289550781250e-07i) -6.9314718055991688771e-1+3.1415924151712141369e0i) (num-test (log -5.0e-01+1.19209289550781250e-07i) -6.9314718055991688771e-1+3.1415924151712141369e0i) (num-test (log -5.0e-01+2.0e+00i) 7.2345949146816273071e-1+1.8157749899217607734e0i) (num-test (log -5.0e-01+2.0e+00i) 7.2345949146816273071e-1+1.8157749899217607734e0i) (num-test (log -5.0e-01+5.0e-01i) -3.4657359027997265471e-1+2.3561944901923449288e0i) (num-test (log -5.0e-01+5.0e-01i) -3.4657359027997265471e-1+2.3561944901923449288e0i) (num-test (log -5.0e-01+8.3886080e+06i) 1.5942385152878743893e1+1.5707963863995413946e0i) (num-test (log -5.0e-01+8.3886080e+06i) 1.5942385152878743893e1+1.5707963863995413946e0i) (num-test (log -5.0e-01-1.0e+00i) 1.1157177565710487788e-1-2.0344439357957027354e0i) (num-test (log -5.0e-01-1.0e+00i) 1.1157177565710487788e-1-2.0344439357957027354e0i) (num-test (log -5.0e-01-1.19209289550781250e-07i) -6.9314718055991688771e-1-3.1415924151712141369e0i) (num-test (log -5.0e-01-1.19209289550781250e-07i) -6.9314718055991688771e-1-3.1415924151712141369e0i) (num-test (log -5.0e-01-2.0e+00i) 7.2345949146816273071e-1-1.8157749899217607734e0i) (num-test (log -5.0e-01-2.0e+00i) 7.2345949146816273071e-1-1.8157749899217607734e0i) (num-test (log -5.0e-01-5.0e-01i) -3.4657359027997265471e-1-2.3561944901923449288e0i) (num-test (log -5.0e-01-5.0e-01i) -3.4657359027997265471e-1-2.3561944901923449288e0i) (num-test (log -5.0e-01-8.3886080e+06i) 1.5942385152878743893e1-1.5707963863995413946e0i) (num-test (log -5.0e-01-8.3886080e+06i) 1.5942385152878743893e1-1.5707963863995413946e0i) (num-test (log -500029) 13.12242137572239+3.14159265358979i) (num-test (log -500029/1) 13.12242137572239+3.14159265358979i) (num-test (log -500029/10) 10.81983628272835+3.14159265358979i) (num-test (log -500029/1234) 6.00440517125706+3.14159265358979i) (num-test (log -500029/1234000000) -7.81110538670721+3.14159265358979i) (num-test (log -500029/2) 12.42927419516245+3.14159265358979i) (num-test (log -500029/3) 12.02380908705428+3.14159265358979i) (num-test (log -500029/362880) 0.32059389564092+3.14159265358979i) (num-test (log -500029/500029) 0.0+3.14159265358979i) (num-test (log -8.3886080e+06+0.0e+00i) 1.5942385152878742117e1+3.1415926535897932385e0i) (num-test (log -8.3886080e+06+1.0e+00i) 1.5942385152878749222e1+3.1415925343805036877e0i) (num-test (log -8.3886080e+06+1.0e+00i) 1.5942385152878749222e1+3.1415925343805036877e0i) (num-test (log -8.3886080e+06+1.19209289550781250e-07i) 1.5942385152878742117e1+3.1415926535897790276e0i) (num-test (log -8.3886080e+06+1.19209289550781250e-07i) 1.5942385152878742117e1+3.1415926535897790276e0i) (num-test (log -8.3886080e+06+2.0e+00i) 1.5942385152878770538e1+3.1415924151712141369e0i) (num-test (log -8.3886080e+06+2.0e+00i) 1.5942385152878770538e1+3.1415924151712141369e0i) (num-test (log -8.3886080e+06+5.0e-01i) 1.5942385152878743893e1+3.1415925939851484631e0i) (num-test (log -8.3886080e+06+5.0e-01i) 1.5942385152878743893e1+3.1415925939851484631e0i) (num-test (log -8.3886080e+06+8.3886080e+06i) 1.6288958743158714771e1+2.3561944901923449288e0i) (num-test (log -8.3886080e+06+8.3886080e+06i) 1.6288958743158714771e1+2.3561944901923449288e0i) (num-test (log -8.3886080e+06-1.0e+00i) 1.5942385152878749222e1-3.1415925343805036877e0i) (num-test (log -8.3886080e+06-1.0e+00i) 1.5942385152878749222e1-3.1415925343805036877e0i) (num-test (log -8.3886080e+06-1.19209289550781250e-07i) 1.5942385152878742117e1-3.1415926535897790276e0i) (num-test (log -8.3886080e+06-1.19209289550781250e-07i) 1.5942385152878742117e1-3.1415926535897790276e0i) (num-test (log -8.3886080e+06-2.0e+00i) 1.5942385152878770538e1-3.1415924151712141369e0i) (num-test (log -8.3886080e+06-2.0e+00i) 1.5942385152878770538e1-3.1415924151712141369e0i) (num-test (log -8.3886080e+06-5.0e-01i) 1.5942385152878743893e1-3.1415925939851484631e0i) (num-test (log -8.3886080e+06-5.0e-01i) 1.5942385152878743893e1-3.1415925939851484631e0i) (num-test (log -8.3886080e+06-8.3886080e+06i) 1.6288958743158714771e1-2.3561944901923449288e0i) (num-test (log -8.3886080e+06-8.3886080e+06i) 1.6288958743158714771e1-2.3561944901923449288e0i) (num-test (log -9223372036854775808) 4.366827237527655449328562365186512378885E1+3.141592653589793238462643383279502884195E0i) (num-test (log .3678794411714423) -1.0) (num-test (log 0+i) (complex 0.0 (* 0.5 pi))) (num-test (log 0-i) (complex 0.0 (* -0.5 pi))) (num-test (log 0.0+0.00000001i) -18.42068074395237+1.57079632679490i) (num-test (log 0.0+1.0i) 0.0+1.57079632679490i) (num-test (log 0.0+1234.0i) 7.11801620446533+1.57079632679490i) (num-test (log 0.0+1234000000.0i) 20.93352676242961+1.57079632679490i) (num-test (log 0.0+2.71828182845905i) 1.0+1.57079632679490i) (num-test (log 0.0+3.14159265358979i) 1.14472988584940+1.57079632679490i) (num-test (log 0.0-0.00000001i) -18.42068074395237-1.57079632679490i) (num-test (log 0.0-1.0i) 0.0-1.57079632679490i) (num-test (log 0.0-1234.0i) 7.11801620446533-1.57079632679490i) (num-test (log 0.0-1234000000.0i) 20.93352676242961-1.57079632679490i) (num-test (log 0.0-2.71828182845905i) 1.0-1.57079632679490i) (num-test (log 0.0-3.14159265358979i) 1.14472988584940-1.57079632679490i) (num-test (log 0.00000001) -18.42068074395237) (num-test (log 0.00000001+0.00000001i) -18.07410715367239+0.78539816339745i) (num-test (log 0.00000001+0.0i) -18.42068074395237) (num-test (log 0.00000001+1.0i) 0.0+1.57079631679490i) (num-test (log 0.00000001+1234.0i) 7.11801620446533+1.57079632678679i) (num-test (log 0.00000001+1234000000.0i) 20.93352676242961+1.57079632679490i) (num-test (log 0.00000001+2.71828182845905i) 1.0+1.57079632311610i) (num-test (log 0.00000001+3.14159265358979i) 1.14472988584940+1.57079632361180i) (num-test (log 0.00000001-0.00000001i) -18.07410715367239-0.78539816339745i) (num-test (log 0.00000001-0.0i) -18.42068074395237) (num-test (log 0.00000001-1.0i) 0.0-1.57079631679490i) (num-test (log 0.00000001-1234.0i) 7.11801620446533-1.57079632678679i) (num-test (log 0.00000001-1234000000.0i) 20.93352676242961-1.57079632679490i) (num-test (log 0.00000001-2.71828182845905i) 1.0-1.57079632311610i) (num-test (log 0.00000001-3.14159265358979i) 1.14472988584940-1.57079632361180i) (num-test (log 0.0e+00+1.0e+00i) 0+1.5707963267948966192e0i) (num-test (log 0.0e+00+1.19209289550781250e-07i) -1.5942385152878742117e1+1.5707963267948966192e0i) (num-test (log 0.0e+00+2.0e+00i) 6.9314718055994530942e-1+1.5707963267948966192e0i) (num-test (log 0.0e+00+5.0e-01i) -6.9314718055994530942e-1+1.5707963267948966192e0i) (num-test (log 0.0e+00+8.3886080e+06i) 1.5942385152878742117e1+1.5707963267948966192e0i) (num-test (log 0.0e+00-1.0e+00i) 0-1.5707963267948966192e0i) (num-test (log 0.0e+00-1.19209289550781250e-07i) -1.5942385152878742117e1-1.5707963267948966192e0i) (num-test (log 0.0e+00-2.0e+00i) 6.9314718055994530942e-1-1.5707963267948966192e0i) (num-test (log 0.0e+00-5.0e-01i) -6.9314718055994530942e-1-1.5707963267948966192e0i) (num-test (log 0.0e+00-8.3886080e+06i) 1.5942385152878742117e1-1.5707963267948966192e0i) (num-test (log 1 -1) 0.0) (num-test (log 1) 0.0) (num-test (log 1.0) 0.0) (num-test (log 1.0+0.00000001i) 0.0+0.00000001i) (num-test (log 1.0+0.0i) 0.0) (num-test (log 1.0+1.0i) 0.34657359027997+0.78539816339745i) (num-test (log 1.0+1234.0i) 7.11801653281724+1.56998595420081i) (num-test (log 1.0+1234000000.0i) 20.93352676242961+1.57079632598452i) (num-test (log 1.0+2.71828182845905i) 1.06346400552149+1.21828290501728i) (num-test (log 1.0+3.14159265358979i) 1.19298515341341+1.26262725567891i) (num-test (log 1.0+i -2.0) 0.26160508088635-0.052598406051983i) (num-test (log 1.0-0.00000001i) 0.0-0.00000001i) (num-test (log 1.0-0.0i) 0.0) (num-test (log 1.0-1.0i) 0.34657359027997-0.78539816339745i) (num-test (log 1.0-1234.0i) 7.11801653281724-1.56998595420081i) (num-test (log 1.0-1234000000.0i) 20.93352676242961-1.57079632598452i) (num-test (log 1.0-2.71828182845905i) 1.06346400552149-1.21828290501728i) (num-test (log 1.0-3.14159265358979i) 1.19298515341341-1.26262725567891i) (num-test (log 1.0e+00+0.0e+00i) 0e0+0.0i) (num-test (log 1.0e+00+1.0e+00i) 3.4657359027997265471e-1+7.8539816339744830962e-1i) (num-test (log 1.0e+00+1.0e+00i) 3.4657359027997265471e-1+7.8539816339744830962e-1i) (num-test (log 1.0e+00+1.19209289550781250e-07i) 7.1054273576009513716e-15+1.1920928955078068531e-7i) (num-test (log 1.0e+00+1.19209289550781250e-07i) 7.1054273576009513716e-15+1.1920928955078068531e-7i) (num-test (log 1.0e+00+2.0e+00i) 8.0471895621705018730e-1+1.1071487177940905030e0i) (num-test (log 1.0e+00+2.0e+00i) 8.0471895621705018730e-1+1.1071487177940905030e0i) (num-test (log 1.0e+00+5.0e-01i) 1.1157177565710487788e-1+4.6364760900080611621e-1i) (num-test (log 1.0e+00+5.0e-01i) 1.1157177565710487788e-1+4.6364760900080611621e-1i) (num-test (log 1.0e+00+8.3886080e+06i) 1.5942385152878749222e1+1.5707962075856070685e0i) (num-test (log 1.0e+00+8.3886080e+06i) 1.5942385152878749222e1+1.5707962075856070685e0i) (num-test (log 1.0e+00-1.0e+00i) 3.4657359027997265471e-1-7.8539816339744830962e-1i) (num-test (log 1.0e+00-1.0e+00i) 3.4657359027997265471e-1-7.8539816339744830962e-1i) (num-test (log 1.0e+00-1.19209289550781250e-07i) 7.1054273576009513716e-15-1.1920928955078068531e-7i) (num-test (log 1.0e+00-1.19209289550781250e-07i) 7.1054273576009513716e-15-1.1920928955078068531e-7i) (num-test (log 1.0e+00-2.0e+00i) 8.0471895621705018730e-1-1.1071487177940905030e0i) (num-test (log 1.0e+00-2.0e+00i) 8.0471895621705018730e-1-1.1071487177940905030e0i) (num-test (log 1.0e+00-5.0e-01i) 1.1157177565710487788e-1-4.6364760900080611621e-1i) (num-test (log 1.0e+00-5.0e-01i) 1.1157177565710487788e-1-4.6364760900080611621e-1i) (num-test (log 1.0e+00-8.3886080e+06i) 1.5942385152878749222e1-1.5707962075856070685e0i) (num-test (log 1.0e+00-8.3886080e+06i) 1.5942385152878749222e1-1.5707962075856070685e0i) (num-test (log 1.0e-12) -27.63102111592855) (num-test (log 1.0e-8) -18.42068074395237) (num-test (log 1.110223024625156799999999999999999999997E-16) -3.673680056967710116530769529852882544059E1) (num-test (log 1.19209289550781250e-07+0.0e+00i) -1.5942385152878742117e1+0.0i) (num-test (log 1.19209289550781250e-07+1.0e+00i) 7.1054273576009513716e-15+1.5707962075856070685e0i) (num-test (log 1.19209289550781250e-07+1.0e+00i) 7.1054273576009513716e-15+1.5707962075856070685e0i) (num-test (log 1.19209289550781250e-07+1.19209289550781250e-07i) -1.5595811562598769462e1+7.8539816339744830962e-1i) (num-test (log 1.19209289550781250e-07+1.19209289550781250e-07i) -1.5595811562598769462e1+7.8539816339744830962e-1i) (num-test (log 1.19209289550781250e-07+2.0e+00i) 6.9314718055994708577e-1+1.5707962671902518438e0i) (num-test (log 1.19209289550781250e-07+2.0e+00i) 6.9314718055994708577e-1+1.5707962671902518438e0i) (num-test (log 1.19209289550781250e-07+5.0e-01i) -6.9314718055991688771e-1+1.5707960883763175177e0i) (num-test (log 1.19209289550781250e-07+5.0e-01i) -6.9314718055991688771e-1+1.5707960883763175177e0i) (num-test (log 1.19209289550781250e-07+8.3886080e+06i) 1.5942385152878742117e1+1.5707963267948824084e0i) (num-test (log 1.19209289550781250e-07+8.3886080e+06i) 1.5942385152878742117e1+1.5707963267948824084e0i) (num-test (log 1.19209289550781250e-07-1.0e+00i) 7.1054273576009513716e-15-1.5707962075856070685e0i) (num-test (log 1.19209289550781250e-07-1.0e+00i) 7.1054273576009513716e-15-1.5707962075856070685e0i) (num-test (log 1.19209289550781250e-07-1.19209289550781250e-07i) -1.5595811562598769462e1-7.8539816339744830962e-1i) (num-test (log 1.19209289550781250e-07-1.19209289550781250e-07i) -1.5595811562598769462e1-7.8539816339744830962e-1i) (num-test (log 1.19209289550781250e-07-2.0e+00i) 6.9314718055994708577e-1-1.5707962671902518438e0i) (num-test (log 1.19209289550781250e-07-2.0e+00i) 6.9314718055994708577e-1-1.5707962671902518438e0i) (num-test (log 1.19209289550781250e-07-5.0e-01i) -6.9314718055991688771e-1-1.5707960883763175177e0i) (num-test (log 1.19209289550781250e-07-5.0e-01i) -6.9314718055991688771e-1-1.5707960883763175177e0i) (num-test (log 1.19209289550781250e-07-8.3886080e+06i) 1.5942385152878742117e1-1.5707963267948824084e0i) (num-test (log 1.19209289550781250e-07-8.3886080e+06i) 1.5942385152878742117e1-1.5707963267948824084e0i) (num-test (log 1.5 -1) 0-0.12906355241341i) (num-test (log 1.7976931e+308) 709.78271287399) (num-test (log 1/1) 0.0) (num-test (log 1/10) -2.30258509299405) (num-test (log 1/1073741824 2) -30) (num-test (log 1/1152921504606846976 8) -20) (num-test (log 1/1234) -7.11801620446533) (num-test (log 1/1234000000) -20.93352676242961) (num-test (log 1/16777216 2) -24) (num-test (log 1/18014398509481984 512) -6) (num-test (log 1/2 1/4) 1/2) (num-test (log 1/2 1/8) 1/3) (num-test (log 1/2 8) -1/3) (num-test (log 1/2) -0.69314718055995) (num-test (log 1/2147483648 2) -31) (num-test (log 1/256 2) -8) (num-test (log 1/3) -1.09861228866811) (num-test (log 1/362880) -12.80182748008147) (num-test (log 1/4 1/2) 2) (num-test (log 1/4 1/2) 2) (num-test (log 1/500029) -13.12242137572239) (num-test (log 1/65536 2) -16) (num-test (log 1/8192 2) -13) ;(num-test (log 10 (real-part (log 0))) 0.0) ; ??? -- this returns -nan-nani in clang, 0.0 in gcc (num-test (log 10) 2.30258509299405) (num-test (log 10.0 (exp -1)) (- (log 10.0))) (num-test (log 10.0 (exp 1)) (log 10.0)) (num-test (log 10.0 -0.001) -0.27620436338394-0.12561556740966i) (num-test (log 10.0 0.001) -0.33333333333333) (num-test (log 10.0 100.0) 0.5) (num-test (log 10.0 1e-20) -0.05) (num-test (log 10.0 1e20) 0.05) (num-test (log 10.0 2124008553358849/781379079653017) 2.302585092994045684017991454684419658469E0) (num-test (log 10/1) 2.30258509299405) (num-test (log 10/10) 0.0) (num-test (log 10/1234) -4.81543111147129) (num-test (log 10/1234000000) -18.63094166943556) (num-test (log 10/2) 1.60943791243410) (num-test (log 10/3) 1.20397280432594) (num-test (log 10/362880) -10.49924238708742) (num-test (log 10/500029) -10.81983628272835) (num-test (log 12/8 3/2) 1.0) (num-test (log 1234) 7.11801620446533) (num-test (log 1234.0) 7.11801620446533) (num-test (log 1234.0+0.00000001i) 7.11801620446533+0.00000000000810i) (num-test (log 1234.0+0.0i) 7.11801620446533) (num-test (log 1234.0+1.0i) 7.11801653281724+0.00081037259408i) (num-test (log 1234.0+1234.0i) 7.46458979474531+0.78539816339745i) (num-test (log 1234.0+1234000000.0i) 20.93352676243011+1.57079532679490i) (num-test (log 1234.0+2.71828182845905i) 7.11801863067090+0.00220281801598i) (num-test (log 1234.0+3.14159265358979i) 7.11801944515932+0.00254585564530i) (num-test (log 1234.0-0.00000001i) 7.11801620446533-0.00000000000810i) (num-test (log 1234.0-0.0i) 7.11801620446533) (num-test (log 1234.0-1.0i) 7.11801653281724-0.00081037259408i) (num-test (log 1234.0-1234.0i) 7.46458979474531-0.78539816339745i) (num-test (log 1234.0-1234000000.0i) 20.93352676243011-1.57079532679490i) (num-test (log 1234.0-2.71828182845905i) 7.11801863067090-0.00220281801598i) (num-test (log 1234.0-3.14159265358979i) 7.11801944515932-0.00254585564530i) (num-test (log 1234/1) 7.11801620446533) (num-test (log 1234/10) 4.81543111147129) (num-test (log 1234/1234) 0.0) (num-test (log 1234/1234000000) -13.81551055796427) (num-test (log 1234/2) 6.42486902390539) (num-test (log 1234/3) 6.01940391579722) (num-test (log 1234/362880) -5.68381127561614) (num-test (log 1234/500029) -6.00440517125706) (num-test (log 1234000000) 20.93352676242961) (num-test (log 1234000000.0) 20.93352676242961) (num-test (log 1234000000.0+0.00000001i) 20.93352676242961+0.0i) (num-test (log 1234000000.0+0.0i) 20.93352676242961) (num-test (log 1234000000.0+1.0i) 20.93352676242961+0.00000000081037i) (num-test (log 1234000000.0+1234.0i) 20.93352676243011+0.00000100000000i) (num-test (log 1234000000.0+1234000000.0i) 21.28010035270958+0.78539816339745i) (num-test (log 1234000000.0+2.71828182845905i) 20.93352676242961+0.00000000220282i) (num-test (log 1234000000.0+3.14159265358979i) 20.93352676242961+0.00000000254586i) (num-test (log 1234000000.0-0.00000001i) 20.93352676242961-0.0i) (num-test (log 1234000000.0-0.0i) 20.93352676242961) (num-test (log 1234000000.0-1.0i) 20.93352676242961-0.00000000081037i) (num-test (log 1234000000.0-1234.0i) 20.93352676243011-0.00000100000000i) (num-test (log 1234000000.0-1234000000.0i) 21.28010035270958-0.78539816339745i) (num-test (log 1234000000.0-2.71828182845905i) 20.93352676242961-0.00000000220282i) (num-test (log 1234000000.0-3.14159265358979i) 20.93352676242961-0.00000000254586i) (num-test (log 1234000000/1) 20.93352676242961) (num-test (log 1234000000/10) 18.63094166943556) (num-test (log 1234000000/1234) 13.81551055796427) (num-test (log 1234000000/1234000000) 0.0) (num-test (log 1234000000/2) 20.24037958186966) (num-test (log 1234000000/3) 19.83491447376150) (num-test (log 1234000000/362880) 8.13169928234814) (num-test (log 1234000000/500029) 7.81110538670721) (num-test (log 15693/12583 24271/35566) -5.78025354982372501902371206100042173188E-1) (num-test (log 1e-100) -2.302585092994045684017991454684364207602E2) (num-test (log 1e-18) -4.144653167389282231232384618431855573682E1) (num-test (log 1e-300) -6.907755278982137052053974364053092622806E2) (num-test (log 1e-50 10) -50.0) (num-test (log 1e100) 2.302585092994045684017991454684364207602E2) (num-test (log 1e18) 4.144653167389282231232384618431855573682E1) (num-test (log 1e300) 6.907755278982137052053974364053092622806E2) (num-test (log 1e50 10) 50.0) (num-test (log 2 1/8) -1/3) (num-test (log 2 2) 1) (num-test (log 2 8) 1/3) (num-test (log 2) 0.69314718055995) (num-test (log 2.0e+00+0.0e+00i) 6.9314718055994530942e-1+0.0i) (num-test (log 2.0e+00+1.0e+00i) 8.0471895621705018730e-1+4.6364760900080611621e-1i) (num-test (log 2.0e+00+1.0e+00i) 8.0471895621705018730e-1+4.6364760900080611621e-1i) (num-test (log 2.0e+00+1.19209289550781250e-07i) 6.9314718055994708577e-1+5.9604644775390554414e-8i) (num-test (log 2.0e+00+1.19209289550781250e-07i) 6.9314718055994708577e-1+5.9604644775390554414e-8i) (num-test (log 2.0e+00+2.0e+00i) 1.0397207708399179641e0+7.8539816339744830962e-1i) (num-test (log 2.0e+00+2.0e+00i) 1.0397207708399179641e0+7.8539816339744830962e-1i) (num-test (log 2.0e+00+5.0e-01i) 7.2345949146816273071e-1+2.4497866312686415417e-1i) (num-test (log 2.0e+00+5.0e-01i) 7.2345949146816273071e-1+2.4497866312686415417e-1i) (num-test (log 2.0e+00+8.3886080e+06i) 1.5942385152878770538e1+1.5707960883763175177e0i) (num-test (log 2.0e+00+8.3886080e+06i) 1.5942385152878770538e1+1.5707960883763175177e0i) (num-test (log 2.0e+00-1.0e+00i) 8.0471895621705018730e-1-4.6364760900080611621e-1i) (num-test (log 2.0e+00-1.0e+00i) 8.0471895621705018730e-1-4.6364760900080611621e-1i) (num-test (log 2.0e+00-1.19209289550781250e-07i) 6.9314718055994708577e-1-5.9604644775390554414e-8i) (num-test (log 2.0e+00-1.19209289550781250e-07i) 6.9314718055994708577e-1-5.9604644775390554414e-8i) (num-test (log 2.0e+00-2.0e+00i) 1.0397207708399179641e0-7.8539816339744830962e-1i) (num-test (log 2.0e+00-2.0e+00i) 1.0397207708399179641e0-7.8539816339744830962e-1i) (num-test (log 2.0e+00-5.0e-01i) 7.2345949146816273071e-1-2.4497866312686415417e-1i) (num-test (log 2.0e+00-5.0e-01i) 7.2345949146816273071e-1-2.4497866312686415417e-1i) (num-test (log 2.0e+00-8.3886080e+06i) 1.5942385152878770538e1-1.5707960883763175177e0i) (num-test (log 2.0e+00-8.3886080e+06i) 1.5942385152878770538e1-1.5707960883763175177e0i) (num-test (log 2.2250739e-308) -708.39641851362) (num-test (log 2.688117141816135E+43) 100.0) (num-test (log 2.71828182845905) 1.0) (num-test (log 2.71828182845905+0.00000001i) 1.0+0.00000000367879i) (num-test (log 2.71828182845905+0.0i) 1.0) (num-test (log 2.71828182845905+1.0i) 1.06346400552149+0.35251342177762i) (num-test (log 2.71828182845905+1234.0i) 7.11801863067090+1.56859350877892i) (num-test (log 2.71828182845905+1234000000.0i) 20.93352676242961+1.57079632459208i) (num-test (log 2.71828182845905+2.71828182845905i) 1.34657359027997+0.78539816339745i) (num-test (log 2.71828182845905+3.14159265358979i) 1.42415703773030+0.85751178635585i) (num-test (log 2.71828182845905-0.00000001i) 1.0-0.00000000367879i) (num-test (log 2.71828182845905-0.0i) 1.0) (num-test (log 2.71828182845905-1.0i) 1.06346400552149-0.35251342177762i) (num-test (log 2.71828182845905-1234.0i) 7.11801863067090-1.56859350877892i) (num-test (log 2.71828182845905-1234000000.0i) 20.93352676242961-1.57079632459208i) (num-test (log 2.71828182845905-2.71828182845905i) 1.34657359027997-0.78539816339745i) (num-test (log 2.71828182845905-3.14159265358979i) 1.42415703773030-0.85751178635585i) (num-test (log 2/1) 0.69314718055995) (num-test (log 2/10) -1.60943791243410) (num-test (log 2/1234) -6.42486902390539) (num-test (log 2/1234000000) -20.24037958186966) (num-test (log 2/2) 0.0) (num-test (log 2/3) -0.40546510810816) (num-test (log 2/362880) -12.10868029952152) (num-test (log 2/500029) -12.42927419516245) (num-test (log 22026.46579480672) 10.0) (num-test (log 24998/50401 24728/63453) 7.441028498776462417495086765025452881649E-1) (num-test (log 25438/28960 36472/54817) 3.182468797561633550530828023298618520944E-1) (num-test (log 2921/7914 2921/7914) 1) (num-test (log 3) 1.09861228866811) (num-test (log 3.14159265358979+0.00000001i) 1.14472988584940+0.00000000318310i) (num-test (log 3.14159265358979+0.0i) 1.14472988584940) (num-test (log 3.14159265358979+1.0i) 1.19298515341341+0.30816907111598i) (num-test (log 3.14159265358979+1234.0i) 7.11801944515932+1.56825047114960i) (num-test (log 3.14159265358979+1234000000.0i) 20.93352676242961+1.57079632424904i) (num-test (log 3.14159265358979+2.71828182845905i) 1.42415703773030+0.71328454043905i) (num-test (log 3.14159265358979+3.14159265358979i) 1.49130347612937+0.78539816339745i) (num-test (log 3.14159265358979-0.00000001i) 1.14472988584940-0.00000000318310i) (num-test (log 3.14159265358979-0.0i) 1.14472988584940) (num-test (log 3.14159265358979-1.0i) 1.19298515341341-0.30816907111598i) (num-test (log 3.14159265358979-1234.0i) 7.11801944515932-1.56825047114960i) (num-test (log 3.14159265358979-1234000000.0i) 20.93352676242961-1.57079632424904i) (num-test (log 3.14159265358979-2.71828182845905i) 1.42415703773030-0.71328454043905i) (num-test (log 3.14159265358979-3.14159265358979i) 1.49130347612937-0.78539816339745i) (num-test (log 3.720075976020836E-44) -100.0) (num-test (log 3/1) 1.09861228866811) (num-test (log 3/10) -1.20397280432594) (num-test (log 3/1234) -6.01940391579722) (num-test (log 3/1234000000) -19.83491447376150) (num-test (log 3/2) 0.40546510810816) (num-test (log 3/3) 0.0) (num-test (log 3/362880) -11.70321519141336) (num-test (log 3/500029) -12.02380908705428) (num-test (log 362880) 12.80182748008147) (num-test (log 362880/1) 12.80182748008147) (num-test (log 362880/10) 10.49924238708742) (num-test (log 362880/1234) 5.68381127561614) (num-test (log 362880/1234000000) -8.13169928234814) (num-test (log 362880/2) 12.10868029952152) (num-test (log 362880/3) 11.70321519141336) (num-test (log 362880/362880) 0.0) (num-test (log 362880/500029) -0.32059389564092) (num-test (log 4 1/2) -2) (num-test (log 4.5399929762484853E-5) -10.0) (num-test (log 42665/30784 48270/29769) 6.752638664357152674138191677370820431573E-1) (num-test (log 43340/27863 27919/48593) -7.971826992064755184257579917033070384525E-1) (num-test (log 43686/40844 3924/13265) -5.522724914533037935994124583907811339125E-2) (num-test (log 46770/6899 56965/50618) 1.620137763694524415676013256791616662615E1) (num-test (log 5.0e-01+0.0e+00i) -6.9314718055994530942e-1+0.0i) (num-test (log 5.0e-01+1.0e+00i) 1.1157177565710487788e-1+1.1071487177940905030e0i) (num-test (log 5.0e-01+1.0e+00i) 1.1157177565710487788e-1+1.1071487177940905030e0i) (num-test (log 5.0e-01+1.19209289550781250e-07i) -6.9314718055991688771e-1+2.3841857910155798249e-7i) (num-test (log 5.0e-01+1.19209289550781250e-07i) -6.9314718055991688771e-1+2.3841857910155798249e-7i) (num-test (log 5.0e-01+2.0e+00i) 7.2345949146816273071e-1+1.3258176636680324651e0i) (num-test (log 5.0e-01+2.0e+00i) 7.2345949146816273071e-1+1.3258176636680324651e0i) (num-test (log 5.0e-01+5.0e-01i) -3.4657359027997265471e-1+7.8539816339744830962e-1i) (num-test (log 5.0e-01+5.0e-01i) -3.4657359027997265471e-1+7.8539816339744830962e-1i) (num-test (log 5.0e-01+8.3886080e+06i) 1.5942385152878743893e1+1.5707962671902518438e0i) (num-test (log 5.0e-01+8.3886080e+06i) 1.5942385152878743893e1+1.5707962671902518438e0i) (num-test (log 5.0e-01-1.0e+00i) 1.1157177565710487788e-1-1.1071487177940905030e0i) (num-test (log 5.0e-01-1.0e+00i) 1.1157177565710487788e-1-1.1071487177940905030e0i) (num-test (log 5.0e-01-1.19209289550781250e-07i) -6.9314718055991688771e-1-2.3841857910155798249e-7i) (num-test (log 5.0e-01-1.19209289550781250e-07i) -6.9314718055991688771e-1-2.3841857910155798249e-7i) (num-test (log 5.0e-01-2.0e+00i) 7.2345949146816273071e-1-1.3258176636680324651e0i) (num-test (log 5.0e-01-2.0e+00i) 7.2345949146816273071e-1-1.3258176636680324651e0i) (num-test (log 5.0e-01-5.0e-01i) -3.4657359027997265471e-1-7.8539816339744830962e-1i) (num-test (log 5.0e-01-5.0e-01i) -3.4657359027997265471e-1-7.8539816339744830962e-1i) (num-test (log 5.0e-01-8.3886080e+06i) 1.5942385152878743893e1-1.5707962671902518438e0i) (num-test (log 5.0e-01-8.3886080e+06i) 1.5942385152878743893e1-1.5707962671902518438e0i) (num-test (log 500029) 13.12242137572239) (num-test (log 500029/1) 13.12242137572239) (num-test (log 500029/10) 10.81983628272835) (num-test (log 500029/1234) 6.00440517125706) (num-test (log 500029/1234000000) -7.81110538670721) (num-test (log 500029/2) 12.42927419516245) (num-test (log 500029/3) 12.02380908705428) (num-test (log 500029/362880) 0.32059389564092) (num-test (log 500029/500029) 0.0) (num-test (log 54595/38975 21029/18267) 2.393514540234982342775959084446190967875E0) (num-test (log 55510/63095 55510/63095) 1) (num-test (log 60726/29873 34251/53142) -1.615057368690198504993598764304726754524E0) (num-test (log 62092/33540 1958/6237) -5.315823311016084206705945306286559292707E-1) (num-test (log 8 2) 3) (num-test (log 8.0 -2.0) 0.13926097063622-0.63118087262379i) (num-test (log 8.0 1.0+i) 0.97790391649038-2.2161063668189i) (num-test (log 8.0 2) 3.0) (num-test (log 8.3886080e+06+0.0e+00i) 1.5942385152878742117e1+0.0i) (num-test (log 8.3886080e+06+1.0e+00i) 1.5942385152878749222e1+1.1920928955078068531e-7i) (num-test (log 8.3886080e+06+1.0e+00i) 1.5942385152878749222e1+1.1920928955078068531e-7i) (num-test (log 8.3886080e+06+1.19209289550781250e-07i) 1.5942385152878742117e1+1.4210854715202003717e-14i) (num-test (log 8.3886080e+06+1.19209289550781250e-07i) 1.5942385152878742117e1+1.4210854715202003717e-14i) (num-test (log 8.3886080e+06+2.0e+00i) 1.5942385152878770538e1+2.3841857910155798249e-7i) (num-test (log 8.3886080e+06+2.0e+00i) 1.5942385152878770538e1+2.3841857910155798249e-7i) (num-test (log 8.3886080e+06+5.0e-01i) 1.5942385152878743893e1+5.9604644775390554414e-8i) (num-test (log 8.3886080e+06+5.0e-01i) 1.5942385152878743893e1+5.9604644775390554414e-8i) (num-test (log 8.3886080e+06+8.3886080e+06i) 1.6288958743158714771e1+7.8539816339744830962e-1i) (num-test (log 8.3886080e+06+8.3886080e+06i) 1.6288958743158714771e1+7.8539816339744830962e-1i) (num-test (log 8.3886080e+06-1.0e+00i) 1.5942385152878749222e1-1.1920928955078068531e-7i) (num-test (log 8.3886080e+06-1.0e+00i) 1.5942385152878749222e1-1.1920928955078068531e-7i) (num-test (log 8.3886080e+06-1.19209289550781250e-07i) 1.5942385152878742117e1-1.4210854715202003717e-14i) (num-test (log 8.3886080e+06-1.19209289550781250e-07i) 1.5942385152878742117e1-1.4210854715202003717e-14i) (num-test (log 8.3886080e+06-2.0e+00i) 1.5942385152878770538e1-2.3841857910155798249e-7i) (num-test (log 8.3886080e+06-2.0e+00i) 1.5942385152878770538e1-2.3841857910155798249e-7i) (num-test (log 8.3886080e+06-5.0e-01i) 1.5942385152878743893e1-5.9604644775390554414e-8i) (num-test (log 8.3886080e+06-5.0e-01i) 1.5942385152878743893e1-5.9604644775390554414e-8i) (num-test (log 8.3886080e+06-8.3886080e+06i) 1.6288958743158714771e1-7.8539816339744830962e-1i) (num-test (log 8.3886080e+06-8.3886080e+06i) 1.6288958743158714771e1-7.8539816339744830962e-1i) (num-test (log 9.0 3.0) 2.0) (num-test (log 9223372036854775807) 4.366827237527655449317720343461657334526E1) (num-test (log pi) 1.14472988584940) (num-test (log (/ 1+i)) (log (/ 1 1+i))) (test (< (real-part (log 0.0)) (real-part (- (log 0.0)))) #t) (test (infinite? (random (log 0.0))) #t) (test (infinite? (random inf.0)) #t) ;(num-test (log 1 1) 'error) ; (expt 1 0) is 1 but so is (expt 1 1) -- an ambiguous case (returns NaN in gmp) ;(num-test (log 2 1) 'error) ; now returns infinity ;; this is actually inconsistent in one way: ;; (log 1/0 2) -> nannani, (log 1/0 1) -> inf.0 (num-test (log -1) (complex 0 pi)) (do ((i 0 (+ i 1)) (n 1 (* n 2))) ((= i 60)) (let ((x (log n 2))) (if (not (= (expt 2 i) n)) (format *stderr* "(log ~D 2): ~A~%" n x)))) (for-each (lambda (num-and-val) (let ((num (car num-and-val)) (val (cadr num-and-val))) (num-test-1 'log num (log num) val))) (vector (list 1 0.0) (list 2 0.69314718055995) (list 3 1.0986122886681) (list -1 0+3.1415926535898i) (list -2 0.69314718055995+3.1415926535898i) (list -3 1.0986122886681+3.1415926535898i) (list 9223372036854775807 43.668272375277) (list -9223372036854775808 43.668272375277+3.1415926535898i) (list 1/2 -0.69314718055995) (list 1/3 -1.0986122886681) (list -1/2 -0.69314718055995+3.1415926535898i) (list -1/3 -1.0986122886681+3.1415926535898i) (list 1/9223372036854775807 -43.668272375277) (list 1.0 0.0) (list 2.0 0.69314718055995) (list -2.0 0.69314718055995+3.1415926535898i) (list 1.000000000000000000000000000000000000002E-309 -7.114987937351601163615593594974685401477E2) (list 1e+16 36.841361487905) (list 0+1i 0+1.5707963267949i) (list 0+2i 0.69314718055995+1.5707963267949i) (list 0-1i 0-1.5707963267949i) (list 1+1i 0.34657359027997+0.78539816339745i) (list 1-1i 0.34657359027997-0.78539816339745i) (list -1+1i 0.34657359027997+2.3561944901923i) (list -1-1i 0.34657359027997-2.3561944901923i) (list 0.1+0.1i -1.9560115027141+0.78539816339745i) (list 1e+16+1e+16i 37.187935078185+0.78539816339745i) (list 1e-16+1e-16i -36.494787897625+0.78539816339745i) )) (let ((err 0.0) (mx 0.0)) (do ((i 0 (+ i 1)) (x -10.0 (+ x .1))) ((= i 200)) (if (not (zero? x)) (let ((y (magnitude (- x (exp (log x)))))) (if (> y err) (begin (set! mx x) (set! err y)))))) (if (> err 1e-14) (format-logged #t ";(exp (log ~A)) error: ~A~%" mx err))) (let ((err 0.0) (mx 0.0)) (do ((i 0 (+ i 1)) (x -10.0+i (+ x 0.1-0.1i))) ((= i 200)) (if (not (zero? x)) (let ((y (magnitude (- x (exp (log x)))))) (if (> y err) (begin (set! err y) (set! mx x)))))) (if (> err 1e-14) (format-logged #t ";(exp (log ~A)) error: ~A~%" mx err))) (do ((i 0 (+ i 1))) ((= i 100)) (let ((val (+ .001 (random 100.0))) (base (+ 2 (random 20)))) (num-test (log val base) (/ (log val) (log base))))) (do ((i 0 (+ i 1))) ((= i 100)) (let ((val (+ .001 (random 10000.0))) (base (+ 1.0 (random 20.0)))) (num-test (log val base) (/ (log val) (log base))))) (let ((val1 (catch #t (lambda () (log 0.0)) (lambda args 'error))) (val2 (catch #t (lambda () (log -0.0)) (lambda args 'error)))) (test (equal? val1 val2) #t)) (do ((i 0 (+ i 1))) ((= i 100)) (let ((val (+ .001 (random 100.0))) (base (+ 2 (random 20)))) (if (> (random 1.0) 0.5) (set! val (- val))) (if (> (random 1.0) 0.5) (set! base (- base))) (num-test (log val base) (/ (log val) (log base))))) (do ((i 0 (+ i 1))) ((= i 100)) (let ((val (+ .001 (random 10000.0))) (base (+ 1.0 (random 20.0)))) (if (> (random 1.0) 0.5) (set! val (- val))) (if (> (random 1.0) 0.5) (set! base (- base))) (num-test (log val base) (/ (log val) (log base))))) (do ((i 0 (+ i 1))) ((= i 100)) (let ((val1 (+ .001 (random 10000.0))) (val2 (+ .001 (random 10000.0))) (base1 (+ 1.0 (random 20.0))) (base2 (+ 1.0 (random 20.0)))) (if (> (random 1.0) 0.5) (set! val1 (- val1))) (if (> (random 1.0) 0.5) (set! val2 (- val2))) (if (> (random 1.0) 0.5) (set! base1 (- base1))) (if (> (random 1.0) 0.5) (set! base2 (- base2))) (let ((val (complex val1 val2)) (base (complex base1 base2))) (num-test (log val base) (/ (log val) (log base)))))) (if (not with-bignums) (num-test (log 1 0) 0)) ; since (expt 0 0) is 1 (if with-bignums (begin (num-test (log (expt 2 16382)) 1.135513711193302405887309661372784853823E4) (num-test (log -1.797693134862315699999999999999999999998E308) 7.097827128933839967276924307167005609752E2+3.141592653589793238462643383279502884195E0i) (num-test (log -2.225073858507201399999999999999999999996E-308) -7.083964185322641062168115849912137186655E2+3.141592653589793238462643383279502884195E0i) (num-test (log 69720375229712477164533808935312303556800) 9.40453112293573922460049312446069272415E1) (num-test (log 100.0 (+ 1.0 (bignum "1e-16"))) 4.605170185988091598294419229104461919985E16) (num-test (expt (+ 1.0 (bignum "1e-16")) 4.605170185988091598294419229104461919985E16) 100.0) (num-test (log 100.0 (+ 1.0 (bignum "1e-34"))) 4.60520221864866031976806443342804401709E34) (num-test (expt (+ 1.0 (bignum "1e-34")) 4.60520221864866031976806443342804401709E34) 100.0) (num-test (expt (+ 1 1e-16) (log 100.0 (+ 1 1e-16))) 100.0) (num-test (+ 100 (expt 10.0 35) (- (expt 10.0 35))) 100.0) (num-test (log 1/9223372036854775808 2) -63) (num-test (log 9223372036854775808 2) 63) (num-test (log 9223372036854775807/9223372036854775806 9223372036854775806/9223372036854775807) -9.999999999999999999999999999999999999647E-1) )) (let ((logs-1 (list -4.60517018598809136803598290936872841520220297725754595206665580193514 -3.91202300542814605861875078791055184712670284289729069794597579244175 -3.50655789731998167664073767244620271055471241943479650033196146829765 -3.21887582486820074920151866645237527905120270853703544382529578294835 -2.99573227355399099343522357614254077567660162298902823015400791046096 -2.81341071676003636722350555098802614247921228507454124621128145880425 -2.65926003693277806293063016592554868556511824767568476360726565199756 -2.52572864430825543978428654499419871097570257417678018970461577345496 -2.40794560865187198524549243552367700590722186161204704859726713466015 -2.30258509299404568401799145468436420760110148862877297603332790096757 -2.20727491318972082397403933140359911538049612332012877684808809280457 -2.12026353620009105780627342952984957440371215071428599209060144931086 -2.04022082852655463198249546780340981039693503249733883564761029127168 -1.96611285637283275351339804446737211748961811331542950948658564250417 -1.89711998488588130203997833922001507102911106516627877841931357682347 -1.83258146374831013036705442353602214290020243981652493558393576396157 -1.77195684193187528778644829149560187961399996467180116476941806405285 -1.71479842809192667582826031406550043783172172725179179447658712516676 -1.66073120682165090802695547748087487796482371595841713352869556552585 -1.60943791243410037460075933322618763952560135426851772191264789147417)) (logs-2 (list 2.30258509299404568401799145468436420760110148862877297603332790096757 2.99573227355399099343522357614254077567660162298902823015400791046096 3.40119738166215537541323669160688991224859204645152242776802223460506 3.68887945411393630285245569760071734375210175734928348427468791995435 3.91202300542814605861875078791055184712670284289729069794597579244175 4.09434456222210068483046881306506648032409218081177768188870224409846 4.24849524204935898912334419812754393723818621821063416449271805090515 4.38202663467388161226968781905889391182760189170953873839536792944775 4.49980967033026506680848192852941561689608260427427187950271656824256 4.60517018598809136803598290936872841520220297725754595206665580193514 4.70048036579241622807993503264949350742280834256619015125189561009814 4.78749174278204599424770093452324304839959231517203293600938225359185 4.86753445045558242007147889624968281240636943338898009245237341163103 4.94164242260930429854057631958572050531368635257088941861339806039854 5.01063529409625575001399602483307755177419340072004014968067012607924 5.07517381523382692168691994051707047990310202606979399251604793894114 5.13579843705026176426752607255749074318930450121451776333056563884986 5.19295685089021037622571404998759218497158273863452713362339657773595 5.24702407216048614402701888657221774483848074992790179457128813737686 5.29831736654803667745321503082690498327770311161780120618733581142853))) (let ((mxerr 0.0)) (do ((i 0 (+ i 1)) (x 0.01 (+ x 0.01)) (y 10.0 (+ y 10.0))) ((= i 20)) (let ((err (max (abs (- (log x) (list-ref logs-1 i))) (abs (- (log y) (list-ref logs-2 i)))))) (if (> err mxerr) (set! mxerr err)))) (if (> mxerr 1e-12) (format-logged #t "log err: ~A~%" mxerr)))) (if with-bignums (let ((old-prec (*s7* 'bignum-precision))) (set! (*s7* 'bignum-precision) 500) (let ((logs (list ; table[Log[k/10 + 1.0], {k, 0, 30}] 0.00000000000000000000000000000000000000000000000000000000000000000000e0 0.09531017980432486004395212328076509222060536530864419918523980816300 0.18232155679395462621171802515451463319738933791448698394272645165670 0.26236426446749105203549598688095439720416645613143414038571760969589 0.33647223662121293050459341021699209011148337531334346654674225846340 0.40546510810816438197801311546434913657199042346249419761401432414410 0.47000362924573555365093703114834206470089904881224804044939213700600 0.53062825106217039623154316318876232798710152395697181126390983691471 0.58778666490211900818973114061886376976937976137698118155674077580080 0.64185388617239477599103597720348932963627777267035584250463233544172 0.69314718055994530941723212145817656807550013436025525412068000949339 0.74193734472937731248260652568134122668347379877583766416075658260750 0.78845736036427016946118424473894166029610549966889945330591981765639 0.83290912293510400678876137712583191084127882621166276596530747651542 0.87546873735389993562895014661269120127288947227474223806340646115010 0.91629073187415506518352721176801107145010121990826246779196788198078 0.95551144502743636145272810833913096527966659049168939450639761918928 0.99325177301028339016774425608321290634137018483947537917075509994491 1.02961941718115823992182553167516865818698350967359872066742226795679 1.06471073699242834316528057767754739789341142529397110288834245067520 1.09861228866810969139524523692252570464749055782274945173469433363749 1.13140211149110056191117286985799300284883744185181899572339017150740 1.16315080980568086306816915260651863277639918317250329457007214649939 1.19392246847243455143919736020329079686809592313139365091993414180049 1.22377543162211570564877528464693889606260165831722706538458984640811 1.25276296849536799568812062198500316156158459522160593433871014044418 1.28093384546206431760696326207704033784487989573723643567742078529420 1.30833281965017876035010421634708295629897609853886318761158478022541 1.33500106673234008540826809866166589771177790703061109662531234493511 1.36097655313560074343074122380348010185165701395418359212041194333338 1.38629436111989061883446424291635313615100026872051050824136001898678))) (do ((i 0 (+ i 1))) ((= i 30)) (let ((val (log (+ (/ i (bignum "10")) (bignum "1.0"))))) (if (> (magnitude (- val (list-ref logs i))) 1e-36) (format-logged #t ";(log ~A) -> ~A ~A~%[~A]~%" (+ 1.0 (/ i 10)) val (list-ref logs i) (magnitude (- val (list-ref logs i)))))))) (set! (*s7* 'bignum-precision) old-prec))) (test (log) 'error) (test (log "hi") 'error) (test (log 1.0+23.0i 1.0+23.0i 1.0+23.0i) 'error) (test (log "hi" (expt 2 30)) 'error) (test (log (expt 2 30) #t) 'error) (test (log 0 0) 'error) (test (log 3 0) 'error) (for-each (lambda (arg) (test (log arg) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) (for-each (lambda (arg) (test (log arg nan.0) 'error) (test (log nan.0 arg) 'error) (test (log arg inf.0) 'error) (test (log inf.0 arg) 'error) (test (log 10 arg) 'error) (test (log arg 10) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) ;;; do these make sense? ;;; (log -nan.0 1) -> inf.0 ;;; (log 1+infi 1) -> inf.0 ;;; -------------------------------------------------------------------------------- ;;; expt ;;; -------------------------------------------------------------------------------- (num-test (* (/ (expt 2 11) (+ (expt 2 10) 1)) (/ (+ (expt 2 11) 1) (expt 2 10))) 4098/1025) (num-test (* (/ (expt 2 21) (+ (expt 2 20) 1)) (/ (+ (expt 2 21) 1) (expt 2 20))) 4194306/1048577) (num-test (* (sqrt 2) (sqrt (- 31 (* 4 (sqrt (sqrt 3)) (sqrt (sqrt 5)))))) (+ (* (expt 3 1/4) (expt 5 3/4)) (- (* 2 (sqrt 5))) (* (expt 3 3/4) (expt 5 1/4)) (* 2 (sqrt 3)))) (num-test (* 1/18014398509481984 1/2) (expt 2 -55)) (num-test (+ (/ (expt 2 11) (+ (expt 2 10) 1)) (/ (+ (expt 2 11) 1) (expt 2 10))) 4197377/1049600) (num-test (+ (/ (expt 2 21) (+ (expt 2 20) 1)) (/ (+ (expt 2 21) 1) (expt 2 20))) 4398049656833/1099512676352) (num-test (+ (/ (expt 2 28)) (/ (expt 3 17)) 1/7 1/29) 1247968828249346465/7037157104192323584) (num-test (+ (/ (expt 2 28)) (/ (expt 3 17)) 1/7 1/31) 1317300430901043787/7522478283791794176) (num-test (+ (/ (expt 2 29)) (/ (expt 3 18)) 1/31) 207994819909949399/6447838528964395008) (num-test (+ (/ (expt 2 30)) (/ (expt 3 18)) 1/13) 415989601508942005/5407864572679815168) (num-test (+ (/ (expt 2 30)) (/ (expt 3 18)) 1/5) 415989589819643501/2079947912569159680) (num-test (+ (/ (expt 2 30)) (/ (expt 3 20))) 4560526225/3743906242624487424) (num-test (+ (/ (expt 2 31) (+ (expt 2 20) 1)) (/ (+ (expt 2 31) 1) (expt 2 20))) 4503601775902721/1099512676352) (num-test (+ (expt (+ 1/2 (/ (sqrt 69) 18)) 1/3) (/ (expt (+ 1/2 (/ (sqrt 69) 18)) -1/3) 3)) (* (/ (* 2 (sqrt 3)) 3) (cos (/ (acos (/ (* 3 (sqrt 3)) 2)) 3)))) (num-test (+ (expt 2 5) (expt 298 5) (expt 351 5) (expt 474 5) (expt 500 5)) (expt 575 5)) (num-test (+ (expt 2230 4) (expt 3196 4) (expt 5620 4) (expt 6995 4)) (expt 7703 4)) (num-test (+ (expt 415280564497/348671682660 3) (expt 676702467503/348671682660 3)) 9) (num-test (+ (expt 510 3) (expt 580 3)) (+ (expt 300 3) (expt 670 3))) (num-test (+ 1 (expt 2 54)) 18014398509481985) (num-test (+ 10000000000000000 1) 10000000000000001) (num-test (+ 2 (expt 276694819753963/226588 1/158)) pi) ; 23 digits (num-test (- (/ (expt 2 11) (+ (expt 2 10) 1)) (/ (+ (expt 2 11) 1) (expt 2 10))) -3073/1049600) (num-test (- (/ (expt 2 21) (+ (expt 2 20) 1)) (/ (+ (expt 2 21) 1) (expt 2 20))) -3145729/1099512676352) (num-test (- (/ (expt 2 31) (+ (expt 2 20) 1)) (/ (+ (expt 2 31) 1) (expt 2 20))) -2148532225/1099512676352) (num-test (- (expt 2 54) 18014398509481983) 1) (num-test (- (expt 2 54) 18014398509481984) 0) (num-test (- 10000000000000000 9999999999999999) 1) (num-test (/ (/ (expt 2 11) (+ (expt 2 10) 1)) (/ (+ (expt 2 11) 1) (expt 2 10))) 2097152/2100225) (num-test (/ (/ (expt 2 21) (+ (expt 2 20) 1)) (/ (+ (expt 2 21) 1) (expt 2 20))) 2199023255552/2199026401281) (num-test (/ (/ (expt 2 31) (+ (expt 2 20) 1)) (/ (+ (expt 2 31) 1) (expt 2 20))) 2251799813685248/2251801962217473) (num-test (/ (expt 10 -20) (expt 10 -20)) 1) (num-test (/ (expt 10 -200) (expt 10 -200)) 1) (num-test (/ (expt 2 -53) 2) (expt 2 -54)) (num-test (/ (expt 2.3 50) (expt 2.3 49)) 2.3) (num-test (/ (sqrt (* 7 (- 2 (expt 2 1/7)))) (expt 2 1/14)) (+ -1 (* 2 (expt 2 1/7)) (expt 2 3/7) (expt 2 5/7) (- (expt 2 6/7)))) (num-test (do ((i 1 (+ i 1)) (sum 0.0 (+ sum (expt (sin (/ (* pi i) (* 2 10))) 4)))) ((= i 11) sum)) 4.25) (num-test (expt #e1 -111) 1) (num-test (expt (+ (cos (/ (* 2 pi) 20)) (* 0+i (sin (/ (* 2 pi) 20)))) 20) 1.0) (num-test (expt (+ pi 20) 0+i) -0.99999999924368-3.8892669402222e-05i) (num-test (expt (- (expt 2 1/3) 1) 1/3) (+ (expt 1/9 1/3) (- (expt 2/9 1/3)) (expt 4/9 1/3))) (num-test (expt (- (expt 2 1/3) 1) 1/3) (+ (expt 1/9 1/3) (- (expt 2/9 1/3)) (expt 4/9 1/3))) (num-test (expt (- (expt 3 3/5) (expt 2 1/5)) 1/3) (/ (+ (- (* (expt 2 1/5) (expt 3 3/5))) (* (expt 2 3/5) (expt 3 2/5)) (expt 3 1/5) (expt 2 2/5)) (expt 5 2/3))) (num-test (expt (/ (+ 1 (sqrt 5)) 2) 5) (/ (+ 11 (* 5 (sqrt 5))) 2)) (num-test (expt (/ (log (+ (expt 640320 3) 744)) pi) 2) 163.0) ; rest is 2.32167e-29 (num-test (expt (expt -1 -1/2) -2) -1) (num-test (expt (expt -1 1/123) 123) -1) (num-test (expt (expt -1/2 -1/2) -2) -1/2) (num-test (expt (expt -1/2 1/2) 2) -1/2) (num-test (expt (expt -1/3 -1/2) -2) -1/3) (num-test (expt (expt -1/3 1/2) 2) -1/3) (num-test (expt (expt -1/3 1/3) 3) -1/3) (num-test (expt (expt -2 -1/2) -2) -2) (num-test (expt (expt -2 1/2) 2) -2) (num-test (expt (expt 0+i -1/2) -2) 0+i) (num-test (expt (expt 0+i -1/3) -3) 0+i) (num-test (expt (expt 0+i -1/4) -4) 0+i) (num-test (expt (expt 0+i 0.5) 2) 0+i) (num-test (expt (expt 0+i 1/10) 10) 0+i) (num-test (expt (expt 0+i 1/3) 3) 0+i) (num-test (expt (expt 0+i 1/4) 4) 0+i) (num-test (expt (expt 1 -1/2) -2) 1) (num-test (expt (expt 1 1/123) 123) 1) (num-test (expt (expt 1+i 1/2) 2) 1+i) (num-test (expt (expt 1+i 1/3) 3) 1+i) (num-test (expt (expt 1+i 1/4) 4) 1+i) (num-test (expt (expt 1-i 1/2) 2) 1-i) (num-test (expt (expt 1-i 1/3) 3) 1-i) (num-test (expt (expt 1-i 1/4) 4) 1-i) (num-test (expt (expt 1/2 -1/2) -2) 1/2) (num-test (expt (expt 2 0+i) (/ 0+i)) 2) (num-test (expt (expt 2 1/10) 10) 2) (num-test (expt (expt 2 1/30) 30) 2) (num-test (expt (expt 2 30) 1/30) 2) (num-test (expt (expt 2 50) 1/50) 2) (num-test (expt (expt 20 10) 1/10) 20) (num-test (expt (expt 40 10) 1/10) 40) (num-test (expt -0 -0) 1) (num-test (expt -0(quasiquote #e0)) 1) (num-test (expt -0.0 -0.0) 0.0) (num-test (expt -0.0 0) 0.0) (num-test (expt -0.0 0-i) 0.0) (num-test (expt -0.0 0.00000001) 0.0) (num-test (expt -0.0 1.0) 0.0) (num-test (expt -0.0 1234.0) 0.0) (num-test (expt -0.0 1234000000.0) 0.0) (num-test (expt -0.0 2.71828182845905) 0.0) (num-test (expt -0.0 pi) 0.0) (num-test (expt -0.0-1234000000.0i -1234000000.0-0.00000001i) 0.0) (num-test (expt -0.00000001 -0.0) 1.0) (num-test (expt -0.00000001 -0.00000001) 1.00000018420682-0.00000003141593i) (num-test (expt -0.00000001 -1) -100000000.00000017881393-0.00000001224606i) (num-test (expt -0.00000001 -1.0) -100000000.00000017881393-0.00000001224606i) (num-test (expt -0.00000001 0) 1.0) (num-test (expt -0.00000001 0.0) 1.0) (num-test (expt -0.00000001 0.00000001) 0.99999981579321+0.00000003141592i) (num-test (expt -0.00000001 1) -0.00000001+0.0i) (num-test (expt -0.00000001 1.0) -0.00000001+0.0i) (num-test (expt -0.00000001 10) 1e-80) (num-test (expt -0.00000001 1234) 0.0) (num-test (expt -0.00000001 1234.0) 0.0) (num-test (expt -0.00000001 1234000000) 0.0) (num-test (expt -0.00000001 1234000000.0) 0.0) (num-test (expt -0.00000001 2) 1e-16) (num-test (expt -0.00000001 2.71828182845905) -1.135859060227e-22+1.388206815575e-22i) (num-test (expt -0.00000001 3) -1e-24) (num-test (expt -0.00000001 362880) 0.0) (num-test (expt -0.00000001 500029) 0.0) (num-test (expt -0.00000001 pi) -6.6495946361558e-26-3.1697962381573e-26i) (num-test (expt -0.00000001+0.00000001i 1.0-0.0i) -0.00000001+0.00000001i) (num-test (expt -0.00000001+0.0i 0.00000001-0.00000001i) 0.99999984720911+0.00000021562270i) (num-test (expt -0.00000001-0.00000001i -1.0-0.0i) -50000000.00000003725290+50000000.00000004470348i) (num-test (expt -0.00000001-0.0i -0.00000001-0.00000001i) 1.00000021562275+0.00000015279091i) (num-test (expt -1 (+ 1 (expt 2 32))) -1) (num-test (expt -1 (- (expt 2 32))) 1) (num-test (expt -1 (expt 2 32)) 1) (num-test (expt -1 -0.0) 1.0) (num-test (expt -1 -100) 1) (num-test (expt -1 -1000) 1) (num-test (expt -1 -1001) -1) (num-test (expt -1 -101) -1) (num-test (expt -1 -255) -1) (num-test (expt -1 -256) 1) (num-test (expt -1 0) 1) (num-test (expt -1 0+i) 4.321391826377224977441773717172801127572810981063308298071968740105076575701806E-2) (num-test (expt -1 0-i) 2.314069263277926900572908636794854738026610624260021199344504640952434235069032E1) (num-test (expt -1 0.0) 1.0) (num-test (expt -1 0.00000001) 1.0+0.00000003141593i) (num-test (expt -1 1) -1) (num-test (expt -1 1.0) -1.0+0.0i) (num-test (expt -1 1/2) 0+i) (num-test (expt -1 10) 1) (num-test (expt -1 100) 1) (num-test (expt -1 1000) 1) (num-test (expt -1 1001) -1) (num-test (expt -1 101) -1) (num-test (expt -1 1234) 1) (num-test (expt -1 1234.0) 1.0) (num-test (expt -1 1234000000) 1) (num-test (expt -1 1234000000.0) 1.0) (num-test (expt -1 2) 1) (num-test (expt -1 2.71828182845905) -0.63325565131482+0.77394268526671i) (num-test (expt -1 255) -1) (num-test (expt -1 256) 1) (num-test (expt -1 3) -1) (num-test (expt -1 362880) 1) (num-test (expt -1 500029) -1) (num-test (expt -1 pi) -0.90268536193307-0.43030121700009i) (num-test (expt -1.0 -0.0) 1.0) (num-test (expt -1.0 -0.00000001) 1.0-0.00000003141593i) (num-test (expt -1.0 -1) -1.0-0.0i) (num-test (expt -1.0 -1.0) -1.0-0.0i) (num-test (expt -1.0 -10) 1.0+0.0i) (num-test (expt -1.0 -1234) 1.0) (num-test (expt -1.0 -1234.0) 1.0) (num-test (expt -1.0 -1234000000) 1.0) (num-test (expt -1.0 -1234000000.0) 1.0) (num-test (expt -1.0 -2) 1.0+0.0i) (num-test (expt -1.0 -2.71828182845905) -0.63325565131482-0.77394268526671i) (num-test (expt -1.0 -3) -1.0-0.0i) (num-test (expt -1.0 -3.14159265358979) -0.90268536193307+0.43030121700009i) (num-test (expt -1.0 -362880) 1.0) (num-test (expt -1.0 -500029) -1.0) (num-test (expt -1.0 0) 1.0) (num-test (expt -1.0 0.0) 1.0) (num-test (expt -1.0 0.00000001) 1.0+0.00000003141593i) (num-test (expt -1.0 1) -1.0+0.0i) (num-test (expt -1.0 1.0) -1.0+0.0i) (num-test (expt -1.0 1/2) 0+i) (num-test (expt -1.0 10) 1.0-0.0i) (num-test (expt -1.0 1234) 1.0) (num-test (expt -1.0 1234.0) 1.0) (num-test (expt -1.0 1234000000) 1.0) (num-test (expt -1.0 1234000000.0) 1.0) (num-test (expt -1.0 2) 1.0-0.0i) (num-test (expt -1.0 2.71828182845905) -0.63325565131482+0.77394268526671i) (num-test (expt -1.0 3) -1.0+0.0i) (num-test (expt -1.0 362880) 1.0) (num-test (expt -1.0 500029) -1.0) (num-test (expt -1.0 pi) -0.90268536193307-0.43030121700009i) (num-test (expt -1.0+0.00000001i 3.14159265358979-0.00000001i) -0.90268540381008-0.43030120215971i) (num-test (expt -1.0+1.0i 2.71828182845905-0.0i) 2.54637618158683+0.31121428769451i) (num-test (expt -1.0-0.00000001i -3.14159265358979-0.00000001i) -0.90268534709269-0.43030117512308i) (num-test (expt -1.0-1.0i -2.71828182845905-0.0i) 0.38693516117166+0.04729063656767i) (num-test (expt -1.0e+00+0.0e+00i -1.0e+00+0.0e+00i) -1e0+0.0i) (num-test (expt -1.0e+00+0.0e+00i 0.0e+00+0.0e+00i) 1e0+0.0i) (num-test (expt -1.0e+00+0.0e+00i 0.0e+00+1.0e+00i) 4.3213918263772249774e-2+0.0i) (num-test (expt -1.0e+00+0.0e+00i 0.0e+00-1.0e+00i) 2.3140692632779269006e1+0.0i) (num-test (expt -1.0e+00+0.0e+00i 1.0e+00+0.0e+00i) -1e0+0.0i) (num-test (expt -1.0e+00+0.0e+00i 5.0e-01+1.00000000000000005551e-01i) 0+7.3040269104864559813e-1i) (num-test (expt -1.0e+00+0.0e+00i 5.0e-01-1.00000000000000005551e-01i) 0+1.3691077706248469087e0i) (num-test (expt -1/10 1234/1234000000) 0.99999769741262+0.00000314158542i) (if (not (provided? 'freebsd)) (num-test (expt -1/2 (- (real-part (log 0)))) (expt -0.5 (- (real-part (log 0)))))) (num-test (expt -1/2 3/362880) 0.99999426929571+0.00002597201266i) (num-test (expt -1/3 10/500029) 0.99997802729625+0.00006282682861i) (num-test (expt -1/362880 0/2) 1) (num-test (expt -1/500029 362880/3) 0.0) (num-test (expt -1/8 -3) -512) (num-test (expt -10 0) 1) (num-test (expt -10 0.0) 1.0) (num-test (expt -10 0.00000001) 1.00000002302585+0.00000003141593i) (num-test (expt -10 1) -10) (num-test (expt -10 1.0) -10.0+0.0i) (num-test (expt -10 2) 100) (num-test (expt -10 2.71828182845905) -331.02508265804954+404.56716151063557i) (num-test (expt -10 3) -1000) (num-test (expt -10 pi) -1250.63060831127905-596.16328730697728i) (num-test (expt -10/1234 0/362880) 1) (num-test (expt -10/1234000000 1/500029) 0.99996274095212+0.00000628258681i) (num-test (expt -10/362880 3/1234) 0.97476967459219+0.00744502948457i) (num-test (expt -10/500029 2/1234000000) 0.99999998246380+0.00000000509172i) (num-test (expt -1234 0) 1) (num-test (expt -1234 0.0) 1.0) (num-test (expt -1234 0.00000001) 1.00000007118016+0.00000003141593i) (num-test (expt -1234 1) -1234) (num-test (expt -1234 1.0) -1234.00000000000045+0.00000000000015i) (num-test (expt -1234 2) 1522756) (num-test (expt -1234 2.71828182845905) -160193503.19500353932381+195782840.25985893607140i) (num-test (expt -1234.0 -0.0) 1.0) (num-test (expt -1234.0 -0.00000001) 0.99999992881984-0.00000003141592i) (num-test (expt -1234.0 -1) -0.00081037277147-0.0i) (num-test (expt -1234.0 -1.0) -0.00081037277147-0.0i) (num-test (expt -1234.0 -2) 0.00000065670403+0.0i) (num-test (expt -1234.0 -2.71828182845905) -0.00000000250330-0.00000000305945i) (num-test (expt -1234.0 -3) -0.00000000053218-0.0i) (num-test (expt -1234.0 -3.14159265358979) -0.00000000017534+0.00000000008358i) (num-test (expt -1234.0 0) 1.0) (num-test (expt -1234.0 0.0) 1.0) (num-test (expt -1234.0 0.00000001) 1.00000007118016+0.00000003141593i) (num-test (expt -1234.0 1) -1234.00000000000045+0.00000000000015i) (num-test (expt -1234.0 1.0) -1234.00000000000045+0.00000000000015i) (num-test (expt -1234.0 2) 1522756.00000000093132-0.00000000037296i) (num-test (expt -1234.0 2.71828182845905) -160193503.19500353932381+195782840.25985893607140i) (num-test (expt -1234.0+1234.0i 3.14159265358979-0.0i) 6676669154.05054950714111+13759228759.84499740600586i) (num-test (expt -1234.0+2.71828182845905i 1.0-0.00000001i) -1234.00003854658053+2.71836975014915i) (num-test (expt -1234.0-1234.0i -3.14159265358979-0.0i) 2.854567008891443E-11+5.882669873167984E-11i) (num-test (expt -1234.0-2.71828182845905i -1.0-0.00000001i) -0.00081036881365+0.00000178515559i) (num-test (expt -1234/10 0/1) 1) (num-test (expt -1234/1234000000 2/362880) 0.99992385906203+0.00001731345596i) (num-test (expt -1234/362880 10/1234000000) 0.99999995393994+0.00000002545861i) (num-test (expt -1234/500029 3/500029) 0.99996397612963+0.00001884778372i) (num-test (expt -1234000000 0) 1) (num-test (expt -1234000000 0.0) 1.0) (num-test (expt -1234000000 0.00000001) 1.00000020933529+0.00000003141593i) (num-test (expt -1234000000.0 -0.0) 1.0) (num-test (expt -1234000000.0 -0.00000001) 0.99999979066475-0.00000003141592i) (num-test (expt -1234000000.0 -1) -0.00000000081037-0.0i) (num-test (expt -1234000000.0 -1.0) -0.00000000081037-0.0i) (num-test (expt -1234000000.0 0) 1.0) (num-test (expt -1234000000.0 0.0) 1.0) (num-test (expt -1234000000.0 0.00000001) 1.00000020933529+0.00000003141593i) (num-test (expt -1234000000.0-1234.0i -2.71828182845905-0.00000001i) -1.2269326149532e-25+1.4995226540245e-25i) (num-test (expt -1234000000/10 1/2) 0.00000000000068+11108.55526159905094i) (num-test (expt -1234000000/3 0/3) 1) (num-test (expt -1234000000/362880 1234/500029) 1.02023991975054+0.00791007960266i) (num-test (expt -1234000000/500029 10/362880) 1.00021527254493+0.00008659250882i) (num-test (expt -2 0) 1) (num-test (expt -2 0.0) 1.0) (num-test (expt -2 0.00000001) 1.00000000693147+0.00000003141593i) (num-test (expt -2 1) -2) (num-test (expt -2 1.0) -2.0+0.0i) (num-test (expt -2 10) 1024) (num-test (expt -2 2) 4) (num-test (expt -2 2.71828182845905) -4.16738324447062+5.09322857532248i) (num-test (expt -2 3) -8) (num-test (expt -2 pi) -7.96617830388569-3.79739869898975i) (num-test (expt -2.71828182845905 -0.0) 1.0) (num-test (expt -2.71828182845905 -0.00000001) 0.99999999000000-0.00000003141593i) (num-test (expt -2.71828182845905 -1) -0.36787944117144-0.0i) (num-test (expt -2.71828182845905 -1.0) -0.36787944117144-0.0i) (num-test (expt -2.71828182845905 -10) 0.00004539992976+0.0i) (num-test (expt -2.71828182845905 -2) 0.13533528323661+0.0i) (num-test (expt -2.71828182845905 -2.71828182845905) -0.04178729661821-0.05107095765760i) (num-test (expt -2.71828182845905 -3) -0.04978706836786-0.0i) (num-test (expt -2.71828182845905 -3.14159265358979) -0.03900857144848+0.01859500162024i) (num-test (expt -2.71828182845905 0) 1.0) (num-test (expt -2.71828182845905 0.0) 1.0) (num-test (expt -2.71828182845905 0.00000001) 1.00000001+0.00000003141593i) (num-test (expt -2.71828182845905 1) -2.71828182845905+0.0i) (num-test (expt -2.71828182845905 1.0) -2.71828182845905+0.0i) (num-test (expt -2.71828182845905 10) 22026.46579480671789-0.00000000002697i) (num-test (expt -2.71828182845905 2) 7.38905609893065-0.0i) (num-test (expt -2.71828182845905 2.71828182845905) -9.59652220592352+11.72853041240636i) (num-test (expt -2.71828182845905 3) -20.08553692318767+0.00000000000001i) (num-test (expt -2.71828182845905 pi) -20.88876450460231-9.95746820210997i) (num-test (expt -2.71828182845905+2.71828182845905i 0.00000001-0.0i) 1.00000001346574+0.00000002356195i) (num-test (expt -2.71828182845905+3.14159265358979i 0.0-0.00000001i) 1.00000002284081-0.00000001424157i) (num-test (expt -2.71828182845905-2.71828182845905i -0.00000001-0.0i) 0.99999998653426+0.00000002356194i) (num-test (expt -2.71828182845905-3.14159265358979i -0.0-0.00000001i) 0.99999997715919-0.00000001424157i) (num-test (expt -2/1 3/1) -8) (num-test (expt -2/1234 500029/1234000000) 0.99739915734849+0.00126969420446i) (num-test (expt -2/3 1234/362880) 0.99856514997103+0.01066829281071i) (num-test (expt -2/500029 0/10) 1) (num-test (expt -256 0) 1) (num-test (expt -256 1) -256) (num-test (expt -2742638075.5 1/2) (sqrt -2742638075.5)) (num-test (expt -2742638075.5 2) (* -2742638075.5 -2742638075.5)) ; from bug-guile (num-test (expt -3 0) 1) (num-test (expt -3 0.0) 1.0) (num-test (expt -3 0.00000001) 1.00000001098612+0.00000003141593i) (num-test (expt -3 1) -3) (num-test (expt -3 1.0) -3.0+0.0i) (num-test (expt -3 10) 59049) (num-test (expt -3 2) 9) (num-test (expt -3 2.71828182845905) -12.54668835889338+15.33411926056231i) (num-test (expt -3 3) -27) (num-test (expt -3 pi) -28.47456044077623-13.57354237468751i) (num-test (expt -3.14159265358979 -0.0) 1.0) (num-test (expt -3.14159265358979 -0.00000001) 0.99999998855270-0.00000003141593i) (num-test (expt -3.14159265358979 -1) -0.31830988618379-0.0i) (num-test (expt -3.14159265358979 -1.0) -0.31830988618379-0.0i) (num-test (expt -3.14159265358979 -10) 0.00001067827923+0.0i) (num-test (expt -3.14159265358979 -2) 0.10132118364234+0.0i) (num-test (expt -3.14159265358979 -2.71828182845905) -0.02819587712308-0.03446000491078i) (num-test (expt -3.14159265358979 -3) -0.03225153443320-0.0i) (num-test (expt -3.14159265358979 -3.14159265358979) -0.02475677172327+0.01180130912803i) (num-test (expt -3.14159265358979 0) 1.0) (num-test (expt -3.14159265358979 0.0) 1.0) (num-test (expt -3.14159265358979 0.00000001) 1.00000001144730+0.00000003141593i) (num-test (expt -3.14159265358979 1) -3.14159265358979+0.0i) (num-test (expt -3.14159265358979 1.0) -3.14159265358979+0.0i) (num-test (expt -3.14159265358979 10) 93648.04747608296748) (num-test (expt -3.14159265358979 2) 9.86960440108936-0.0i) (num-test (expt -3.14159265358979 2.71828182845905) -14.22238854892297+17.38210083337688i) (num-test (expt -3.14159265358979 3) -31.00627668029983) (num-test (expt -3.14159265358979 pi) -32.91385774189388-15.68971165343314i) (num-test (expt -3.14159265358979-3.14159265358979i -1234000000.0-0.0i) 0.0) (num-test (expt -3/1 10/2) -243) (num-test (expt -3/10 500029/362880) -0.07120470796705-0.17650615015342i) (num-test (expt -3/1234 362880/500029) -0.00825127977478+0.00961700186370i) (num-test (expt -3/1234000000 0/1234000000) 1) (num-test (expt -3/362880 2/10) 0.07788060004397+0.05658356803852i) (num-test (expt -3/500029 1/1234) 0.99030033992383+0.00252117260474i) (num-test (expt -362880 0) 1) (num-test (expt -362880 0.0) 1.0) (num-test (expt -362880 0.00000001) 1.00000012801828+0.00000003141593i) (num-test (expt -362880 1) -362880) (num-test (expt -362880 1.0) -362879.99999999982538+0.00000000004444i) (num-test (expt -362880/1 0/500029) 1) (num-test (expt -362880/10 3/10) 13.71347740072436+18.87498236114703i) (num-test (expt -362880/1234 10/3) -84553109.08903615176678-146450280.88012450933456i) (num-test (expt -362880/1234000000 1234/2) 0.0) (num-test (expt -362880/2 1/1234000000) 1.00000000981254+0.00000000254586i) (num-test (expt -362880/3 2/1234) 1.01913575690562+0.00518920109559i) (num-test (expt -500029 0) 1) (num-test (expt -500029 0.0) 1.0) (num-test (expt -500029 0.00000001) 1.00000013122422+0.00000003141593i) (num-test (expt -500029 1) -500029) (num-test (expt -500029 1.0) -500029.00000000040745+0.00000000006123i) (num-test (expt -500029/1 362880/1234000000) 1.00386591183654+0.00092741384842i) (num-test (expt -500029/10 2/3) -678.63064326537926+1175.42275370878747i) (num-test (expt -500029/1234 3/2) -0.00000000000150-8156.80442672750178i) (num-test (expt -500029/1234000000 10/1) 0.0) (num-test (expt -500029/2 0/1234) 1) (num-test (expt -500029/3 1/10) 3.16514579334680+1.02841820970710i) (num-test (expt .1 -1) 10.0) (num-test (expt .1 -2) 100.0) (num-test (expt 0 (expt 2 31)) 0) (num-test (expt 0 (expt 2 32)) 0) (num-test (expt 0 (expt 2 33)) 0) (num-test (expt 0 (expt 2 63)) 0) (num-test (expt 0 (expt 2 64)) 0) (num-test (expt 0 (expt 2 65)) 0) (num-test (expt 0 -0.0) 0.0) (num-test (expt 0 -0/4) 1) (num-test (expt 0 0) 1) (num-test (expt 0 -0) 1) (num-test (expt 0 0.0) 0.0) (num-test (expt 0 -0.0) 0.0) (num-test (expt 0 0.00000001) 0.0) (num-test (expt 0 1) 0) (num-test (expt 0 1.0) 0.0) (num-test (expt 0 1.0+i) 0.0) ; ?? (num-test (expt 0 1/10) 0) (num-test (expt 0 1/4) 0) (num-test (expt 0 10) 0) (num-test (expt 0 100) 0) (num-test (expt 0 1000) 0) (num-test (expt 0 1001) 0) (num-test (expt 0 101) 0) (num-test (expt 0 1234) 0) (num-test (expt 0 1234.0) 0.0) (num-test (expt 0 1234000000) 0) (num-test (expt 0 1234000000.0) 0.0) (num-test (expt 0 2) 0) (num-test (expt 0 2.71828182845905) 0.0) (num-test (expt 0 256) 0) (num-test (expt 0 3) 0) (num-test (expt 0 362880) 0) (num-test (expt 0 500029) 0) (num-test (expt 0 pi) 0.0) (num-test (expt 0+1e-15i 0-1e-15i) 1.0000000000000015707963267943015114538E0+3.453877639491074211979699606989171173842E-14i) (num-test (expt 0+1i 2) -1) (num-test (expt 0+i 0+i) 2.078795763507619085469556198349787700342E-1) (num-test (expt 0+i 0+i) (exp (/ pi -2))) (num-test (expt 0+i 0-i) 4.810477380965351655473035666703833126401E0) (num-test (expt 0+i 1/2) (complex (/ (sqrt 2)) (/ (sqrt 2)))) (num-test (expt 0+i 2) -1.0) (num-test (expt 0-i 1+i) 0.0-4.810477380965351655473035666703833126401E0i) (num-test (expt 0-i 1-i) 0.0-2.078795763507619085469556198349787700342E-1i) (num-test (expt 0-i 2) -1) (num-test (expt 0.0 (expt 2 31)) 0.0) (num-test (expt 0.0 (expt 2 32)) 0.0) (num-test (expt 0.0 (expt 2 33)) 0.0) (num-test (expt 0.0 (expt 2 63)) 0.0) (num-test (expt 0.0 (expt 2 64)) 0.0) (num-test (expt 0.0 (expt 2 65)) 0.0) (num-test (expt 0.0 0) 0.0) (num-test (expt 0.0 0+i) 0.0) ; why would they be radically different? (num-test (expt 0.0 0-i) 0.0) (num-test (expt 0.0 0.0) 0.0) (num-test (expt 0.0 0.00000001) 0.0) (num-test (expt 0.0 1) 0.0) (num-test (expt 0.0 1.0) 0.0) (num-test (expt 0.0 1234.0) 0.0) (num-test (expt 0.0 1234000000.0) 0.0) (num-test (expt 0.0 1e-15+i) 0.0) (num-test (expt 0.0 1e-15-i) 0.0) (num-test (expt 0.0 2.71828182845905) 0.0) (num-test (expt 0.0 pi) 0.0) (num-test (expt 0.0-1234000000.0i -1234000000.0+0.00000001i) 0.0) (num-test (expt 0.00000001 -0.0) 1.0) (num-test (expt 0.00000001 -0.00000001) 1.00000018420682) (num-test (expt 0.00000001 -1) 100000000.00000017881393) (num-test (expt 0.00000001 -1.0) 100000000.00000017881393) (num-test (expt 0.00000001 0) 1.0) (num-test (expt 0.00000001 0.0) 1.0) (num-test (expt 0.00000001 0.00000001) 0.99999981579321) (num-test (expt 0.00000001 1) 0.00000001) (num-test (expt 0.00000001 1.0) 0.00000001) (num-test (expt 0.00000001 10) 0.0) (num-test (expt 0.00000001 1234) 0.0) (num-test (expt 0.00000001 1234.0) 0.0) (num-test (expt 0.00000001 1234000000) 0.0) (num-test (expt 0.00000001 1234000000.0) 0.0) (num-test (expt 0.00000001 2) 0.0) (num-test (expt 0.00000001 2.71828182845905) 0.0) (num-test (expt 0.00000001 3) 0.0) (num-test (expt 0.00000001 362880) 0.0) (num-test (expt 0.00000001 500029) 0.0) (num-test (expt 0.00000001 pi) 0.0) (num-test (expt 0.00000001+0.00000001i 1.0+0.0i) 0.00000001+0.00000001i) (num-test (expt 0.00000001+0.0i 0.00000001+0.00000001i) 0.99999981579319-0.00000018420677i) (num-test (expt 0.00000001-0.00000001i -1.0+0.0i) 50000000.00000004470348+50000000.00000003725290i) (num-test (expt 0.00000001-0.0i -0.00000001+0.00000001i) 1.00000018420681-0.00000018420684i) (num-test (expt 0.0e+00+1.0e+00i -1.0e+00+0.0e+00i) 0-1i) (num-test (expt 0.0e+00+1.0e+00i 0.0e+00+0.0e+00i) 1e0+0.0i) (num-test (expt 0.0e+00+1.0e+00i 0.0e+00+1.0e+00i) 2.0787957635076190855e-1+0.0i) (num-test (expt 0.0e+00+1.0e+00i 0.0e+00-1.0e+00i) 4.8104773809653516555e0+0.0i) (num-test (expt 0.0e+00+1.0e+00i 1.0e+00+0.0e+00i) 0+1i) (num-test (expt 0.0e+00+1.0e+00i 5.0e-01+1.00000000000000005551e-01i) 6.0431891044739184057e-1+6.0431891044739184057e-1i) (num-test (expt 0.0e+00+1.0e+00i 5.0e-01-1.00000000000000005551e-01i) 8.2737771622906514822e-1+8.2737771622906514822e-1i) (num-test (expt 0.0e+00-1.0e+00i -1.0e+00+0.0e+00i) 0+1i) (num-test (expt 0.0e+00-1.0e+00i 0.0e+00+0.0e+00i) 1e0+0.0i) (num-test (expt 0.0e+00-1.0e+00i 0.0e+00+1.0e+00i) 4.8104773809653516555e0+0.0i) (num-test (expt 0.0e+00-1.0e+00i 0.0e+00-1.0e+00i) 2.0787957635076190855e-1+0.0i) (num-test (expt 0.0e+00-1.0e+00i 1.0e+00+0.0e+00i) 0-1i) (num-test (expt 0.0e+00-1.0e+00i 5.0e-01+1.00000000000000005551e-01i) 8.2737771622906514822e-1-8.2737771622906514822e-1i) (num-test (expt 0.0e+00-1.0e+00i 5.0e-01-1.00000000000000005551e-01i) 6.0431891044739184057e-1-6.0431891044739184057e-1i) (num-test (expt 0/1 1/362880) 0.0) (num-test (expt 0/10 10/1234) 0.0) (num-test (expt 0/11 000) 1) (num-test (expt 0/1234 1234/10) 0.0) (num-test (expt 0/2 2/500029) 0.0) (num-test (expt 0/3 3/1234000000) 0.0) (num-test (expt 0/362880 362880/1) 0) (num-test (expt 0/500029 500029/2) 0.0) (num-test (expt -0.0 most-positive-fixnum) 0.0) (num-test (expt 0 most-positive-fixnum) 0) (test (expt 0 (- (expt 2 32))) 'error) (test (expt 0 (- (expt 2.0 60))) 'error) (test (expt 0 (complex (- (expt 2 60)) 1.0)) 'error) (test (expt 0 -255) 'error) (test (expt 0 -1) 'error) (test (expt 0 -1.0) 'error) (test (expt 0 -1/2) 'error) (num-test (expt 0 1/2) 0) ; or 0.0 (num-test (expt 0 -0+i) 0.0) (num-test (expt 0 -0-i) 0.0) (test (expt 0 -1+i) 'error) (test (expt 0 most-negative-fixnum) 'error) (test (expt 0.0 most-negative-fixnum) 'error) (test (expt 0.0 -255) 'error) (test (expt 0.0 -1) 'error) (test (expt 0.0 -1.0) 'error) (test (expt 0.0 -1/2) 'error) (num-test (expt 0.0 1/2) 0.0) (num-test (expt 0.0 -0+i) 0.0) (num-test (expt 0.0 -0-i) 0.0) (test (expt 0.0 -1+i) 'error) (test (expt 0.0 most-negative-fixnum) 'error) (test (expt 0.0 most-negative-fixnum) 'error) (num-test (expt 1 1/2) 1) (num-test (expt 1 (- (expt 2 32))) 1) (num-test (expt 1 (expt 2 32)) 1) (num-test (expt 1 (real-part (log 0))) (expt 1.0 (real-part (log 0)))) (num-test (expt 1 -0) 1) (num-test (expt 1 -0.0) 1.0) (num-test (expt 1 -0.00000001) 1.0) (num-test (expt 1 -1) 1) (num-test (expt 1 -1.0) 1.0) (num-test (expt 1 -10) 1) (num-test (expt 1 -100) 1) (num-test (expt 1 -1000) 1) (num-test (expt 1 -1001) 1) (num-test (expt 1 -101) 1) (num-test (expt 1 -1234) 1) (num-test (expt 1 -1234.0) 1.0) (num-test (expt 1 -1234000000) 1) (num-test (expt 1 -1234000000.0) 1.0) (num-test (expt 1 -1e-15) 1) (num-test (expt 1 -2) 1) (num-test (expt 1 -2.71828182845905) 1.0) (num-test (expt 1 -3) 1) (num-test (expt 1 -3.14159265358979) 1.0) (num-test (expt 1 -362880) 1) (num-test (expt 1 -500029) 1) (num-test (expt 1 0) 1) (num-test (expt 1 0+i) 1) (num-test (expt 1 0-i) 1) (num-test (expt 1 0.0) 1.0) (num-test (expt 1 0.00000001) 1.0) (num-test (expt 1 1) 1) (num-test (expt 1 1+i) 1) (num-test (expt 1 1.0) 1.0) (num-test (expt 1 1/10) 1) (num-test (expt 1 10) 1) (num-test (expt 1 100) 1) (num-test (expt 1 1000) 1) (num-test (expt 1 1001) 1) (num-test (expt 1 101) 1) (num-test (expt 1 1234) 1) (num-test (expt 1 1234.0) 1.0) (num-test (expt 1 1234000000) 1) (num-test (expt 1 1234000000.0) 1.0) (num-test (expt 1 2) 1) (num-test (expt 1 2.71828182845905) 1.0) (num-test (expt 1 3) 1) (num-test (expt 1 362880) 1) (num-test (expt 1 500029) 1) (num-test (expt 1 most-negative-fixnum) 1) (num-test (expt 1 pi) 1.0) (num-test (expt 1+i 1) 1+i) (num-test (expt 1+i 1.0) 1.0+i) (num-test (expt 1.0 -0.0) 1.0) (num-test (expt 1.0 -0.00000001) 1.0) (num-test (expt 1.0 -1) 1.0) (num-test (expt 1.0 -1.0) 1.0) (num-test (expt 1.0 -1/2) 1.0) (num-test (expt 1.0 -10) 1.0) (num-test (expt 1.0 -1234) 1.0) (num-test (expt 1.0 -1234.0) 1.0) (num-test (expt 1.0 -1234000000) 1.0) (num-test (expt 1.0 -1234000000.0) 1.0) (num-test (expt 1.0 -2) 1.0) (num-test (expt 1.0 -2.71828182845905) 1.0) (num-test (expt 1.0 -3) 1.0) (num-test (expt 1.0 -3.14159265358979) 1.0) (num-test (expt 1.0 -362880) 1.0) (num-test (expt 1.0 -500029) 1.0) (num-test (expt 1.0 0) 1.0) (num-test (expt 1.0 0.0) 1.0) (num-test (expt 1.0 0.00000001) 1.0) (num-test (expt 1.0 1) 1.0) (num-test (expt 1.0 1.0) 1.0) (num-test (expt 1.0 1/2) 1.0) (num-test (expt 1.0 10) 1.0) (num-test (expt 1.0 1234) 1.0) (num-test (expt 1.0 1234.0) 1.0) (num-test (expt 1.0 1234000000) 1.0) (num-test (expt 1.0 1234000000.0) 1.0) (num-test (expt 1.0 2) 1.0) (num-test (expt 1.0 2.71828182845905) 1.0) (num-test (expt 1.0 3) 1.0) (num-test (expt 1.0 362880) 1.0) (num-test (expt 1.0 500029) 1.0) (num-test (expt 1.0 pi) 1.0) (num-test (expt 1.0+0.00000001i 3.14159265358979+0.00000001i) 1.0+0.00000003141593i) (num-test (expt 1.0+1.0i 2.71828182845905+0.0i) -1.37164508585166+2.16782742612896i) (num-test (expt 1.0-0.00000001i -3.14159265358979+0.00000001i) 1.0+0.00000003141593i) (num-test (expt 1.0-1.0i -2.71828182845905+0.0i) -0.20842863525121+0.32941270052205i) (num-test (expt 1.0e+00+0.0e+00i -1.0e+00+0.0e+00i) 1e0+0.0i) (num-test (expt 1.0e+00+0.0e+00i 0.0e+00+1.0e+00i) 1e0+0.0i) (num-test (expt 1.0e+00+0.0e+00i 0.0e+00-1.0e+00i) 1e0+0.0i) (num-test (expt 1.0e+00+0.0e+00i 1.0e+00+0.0e+00i) 1e0+0.0i) (num-test (expt 1.0e+00+0.0e+00i 5.0e-01+1.00000000000000005551e-01i) 1e0+0.0i) (num-test (expt 1.0e+00+0.0e+00i 5.0e-01-1.00000000000000005551e-01i) 1e0+0.0i) (num-test (expt 1/10 1234/1234000000) 0.99999769741756) (num-test (expt 1/1234000000 500029/10) 0.0) (num-test (expt 1/2 (- (real-part (log 0)))) (expt 0.5 (- (real-part (log 0))))) (num-test (expt 1/2 -10) 1024) (num-test (expt 1/2 -3) 8) (num-test (expt 1/2 1/3) 7.937005259840997373758528196361541301963E-1) (num-test (expt 1/2 10) 1/1024) (num-test (expt 1/2 3) 1/8) (num-test (expt 1/2 3/362880) 0.99999426963298) (num-test (expt 1/3 10/500029) 0.99997802926990) (num-test (expt 1/362880 0/2) 1) (num-test (expt 1/4 -2) 16) (num-test (expt 1/4 1/2) 1/2) (num-test (expt 1/4 1/3) 6.299605249474365823836053036391141752849E-1) (num-test (expt 1/500029 362880/3) 0.0) (num-test (expt 1/64 -1/2) 8) (num-test (expt 1/64 -1/3) 4) (num-test (expt 1/64 -2/3) 16) (num-test (expt 1/64 -3/2) 512) (num-test (expt 1/64 1/2) 1/8) (num-test (expt 1/64 1/3) 1/4) (num-test (expt 1/64 2/3) 1/16) (num-test (expt 1/64 3/2) 1/512) (num-test (expt 1/9223372036854775807 -1) 9223372036854775807) (num-test (expt 1/9223372036854775807 1) 1/9223372036854775807) (num-test (expt 9223372036854775807 -1) 1/9223372036854775807) (num-test (expt 10 -0.0) 1.0) (num-test (expt 10 -0.00000001) 0.99999997697415) (num-test (expt 10 -1) 1/10) (num-test (expt 10 -1.0) 0.1) (num-test (expt 10 -10) 1/10000000000) (num-test (expt 10 -2) 1/100) (num-test (expt 10 -2.71828182845905) 0.00191301410222) (num-test (expt 10 -3) 1/1000) (num-test (expt 10 -3.14159265358979) 0.00072178415907) (num-test (expt 10 0) 1) (num-test (expt 10 0.0) 1.0) (num-test (expt 10 0.00000001) 1.00000002302585) (num-test (expt 10 1) 10) (num-test (expt 10 1.0) 10.0) (num-test (expt 10 10) 10000000000) (num-test (expt 10 2) 100) (num-test (expt 10 2.71828182845905) 522.73529967043669) (num-test (expt 10 3) 1000) (num-test (expt 10 pi) 1385.45573136701182) (num-test (expt 10/1234 0/362880) 1) (num-test (expt 10/1234000000 1/500029) 0.99996274097186) (num-test (expt 10/362880 3/1234) 0.97479810574733) (num-test (expt 10/500029 2/1234000000) 0.99999998246380) (num-test (expt 10000000000 1/10) 10) (num-test (expt 1024 1/10) 2) (num-test (expt 1048576 1/10) 4) (num-test (expt 1073741824 1/10) 8) (num-test (expt 11 10) 25937424601) (num-test (expt 1234 -0.0) 1.0) (num-test (expt 1234 -0.00000001) 0.99999992881984) (num-test (expt 1234 -1) 1/1234) (num-test (expt 1234 -1.0) 0.00081037277147) (num-test (expt 1234 -2) 1/1522756) (num-test (expt 1234 -2.71828182845905) 0.00000000395307) (num-test (expt 1234 -3) 1/1879080904) (num-test (expt 1234 -3.14159265358979) 0.00000000019424) (num-test (expt 1234 0) 1) (num-test (expt 1234 0.0) 1.0) (num-test (expt 1234 0.00000001) 1.00000007118016) (num-test (expt 1234 1) 1234) (num-test (expt 1234 1.0) 1234.00000000000045) (num-test (expt 1234 2) 1522756) (num-test (expt 1234 2.71828182845905) 252968138.32201290130615) (num-test (expt 1234.0 -0.0) 1.0) (num-test (expt 1234.0 -0.00000001) 0.99999992881984) (num-test (expt 1234.0 -1) 0.00081037277147) (num-test (expt 1234.0 -1.0) 0.00081037277147) (num-test (expt 1234.0 -2) 0.00000065670403) (num-test (expt 1234.0 -2.71828182845905) 0.00000000395307) (num-test (expt 1234.0 -3) 0.00000000053218) (num-test (expt 1234.0 -3.14159265358979) 0.00000000019424) (num-test (expt 1234.0 0) 1.0) (num-test (expt 1234.0 0.0) 1.0) (num-test (expt 1234.0 0.00000001) 1.00000007118016) (num-test (expt 1234.0 1) 1234.00000000000045) (num-test (expt 1234.0 1.0) 1234.00000000000045) (num-test (expt 1234.0 2) 1522756.00000000093132) (num-test (expt 1234.0 2.71828182845905) 252968138.32201290130615) (num-test (expt 1234.0+1234.0i 3.14159265358979+0.0i) -11947544392.17545890808105+9547275530.50568199157715i) (num-test (expt 1234.0+2.71828182845905i 1.0+0.00000001i) 1233.99999977932634+2.71836966474906i) (num-test (expt 1234.0-1234.0i -3.14159265358979+0.0i) -5.108095859217296E-11+4.081876325659167E-11i) (num-test (expt 1234.0-2.71828182845905i -1.0+0.00000001i) 0.00081036883911+0.00000178515565i) (num-test (expt 1234/10 0/1) 1) (num-test (expt 1234/1234000000 2/362880) 0.99992385921192) (num-test (expt 1234/362880 10/1234000000) 0.99999995393994) (num-test (expt 1234/500029 3/500029) 0.99996397630725) (num-test (expt 1234000000 -0.0) 1.0) (num-test (expt 1234000000 -0.00000001) 0.99999979066475) (num-test (expt 1234000000 -1) 1/1234000000) (num-test (expt 1234000000 -1.0) 0.00000000081037) (num-test (expt 1234000000 0) 1) (num-test (expt 1234000000 0.0) 1.0) (num-test (expt 1234000000 0.00000001) 1.00000020933529) (num-test (expt 1234000000.0 -0.0) 1.0) (num-test (expt 1234000000.0 -0.00000001) 0.99999979066475) (num-test (expt 1234000000.0 -1) 0.00000000081037) (num-test (expt 1234000000.0 -1.0) 0.00000000081037) (num-test (expt 1234000000.0 0) 1.0) (num-test (expt 1234000000.0 0.0) 1.0) (num-test (expt 1234000000.0 0.00000001) 1.00000020933529) (num-test (expt 1234000000.0-1234.0i -2.71828182845905+0.00000001i) 1.9375066625441e-25+5.672277629054e-31i) (num-test (expt 1234000000/10 1/2) 11108.55526159905094) (num-test (expt 1234000000/3 0/3) 1) (num-test (expt 1234000000/362880 1234/500029) 1.02027058333165) (num-test (expt 1234000000/500029 10/362880) 1.00021527629325) (num-test (expt 14879/18662 14879/18662) 8.347553395975456341642526041524525735791E-1) (num-test (expt 16 1/4) 2) (num-test (expt 1e-1 1e1) 1e-10) (num-test (expt 1e-1 1e2) 1e-100) (num-test (expt 1e-15 -1e-15) 1.000000000000034538776394911284329951335E0) (num-test (expt 1e-15 0+i) -0.999824358967590-0.018741697229594i) (num-test (expt 1e-15 0-i) -0.999824358967590+0.018741697229594i) (num-test (expt 1e-15 1e-15) 9.99999999999965461223605089908597123527E-1) (num-test (expt 1e-15 1e100) 0.0) (num-test (expt 1e15 -1e1) 1e-150) (num-test (expt 1e15 1e1) 1e150) (num-test (expt 1e18 -3) 1e-54) (if (not with-bignums) (num-test (expt 1e18 -63) 0.0)) ; 1e-1134 (num-test (expt 1+1i -63) 2.3283064365386962890625E-10+2.3283064365386962890625E-10i) (num-test (expt 1+1i -3) -0.25-0.25i) (num-test (expt 2 (real-part (log 0))) (expt 2.0 (real-part (log 0)))) (num-test (expt 2 -0.0) 1.0) (num-test (expt 2 -0.00000001) 0.99999999306853) (num-test (expt 2 -1) 1/2) (num-test (expt 2 -1.0) 0.50000000000000) (num-test (expt 2 -10) 1/1024) (num-test (expt 2 -2) 1/4) (num-test (expt 2 -2.71828182845905) 0.15195522325791) (num-test (expt 2 -3) 1/8) (num-test (expt 2 -3.14159265358979) 0.11331473229676) (num-test (expt 2 -9) 1/512) (num-test (expt 2 0) 1) (num-test (expt 2 0.0) 1.0) (num-test (expt 2 0.00000001) 1.00000000693147) (num-test (expt 2 1) 2) (num-test (expt 2 1+i) 1.538477802727944253156659987322541402879E0+1.277922552627269602300065822929403568513E0i) (num-test (expt 2 1.0) 2.0) (num-test (expt 2 1/3) 1.25992104989487316476721060727822835057E0) (num-test (expt 2 10) 1024) (num-test (expt 2 2) 4) (num-test (expt 2 2.71828182845905) 6.58088599101792) (num-test (expt 2 3) 8) (num-test (expt 2 9) 512) (if (not with-bignums) (test (infinite? (expt 2 1000000000000)) #t)) (num-test (expt 2 pi) 8.82497782707629) (num-test (expt 2.0 -1.0220000e+03) 2.225073858507201383090232717332404063624E-308) (num-test (expt 2.0 1.0230000e+03) 8.98846567431157953864652595394512365232E307) (num-test (expt 2.71828182845905 -0.0) 1.0) (num-test (expt 2.71828182845905 -0.00000001) 0.99999999000000) (num-test (expt 2.71828182845905 -1) 0.36787944117144) (num-test (expt 2.71828182845905 -1.0) 0.36787944117144) (num-test (expt 2.71828182845905 -10) 0.00004539992976) (num-test (expt 2.71828182845905 -2) 0.13533528323661) (num-test (expt 2.71828182845905 -2.71828182845905) 0.06598803584531) (num-test (expt 2.71828182845905 -3) 0.04978706836786) (num-test (expt 2.71828182845905 -3.14159265358979) 0.04321391826377) (num-test (expt 2.71828182845905 0) 1.0) (num-test (expt 2.71828182845905 0.0) 1.0) (num-test (expt 2.71828182845905 0.00000001) 1.00000001) (num-test (expt 2.71828182845905 1) 2.71828182845905) (num-test (expt 2.71828182845905 1.0) 2.71828182845905) (num-test (expt 2.71828182845905 10) 22026.46579480671789) (num-test (expt 2.71828182845905 2) 7.38905609893065) (num-test (expt 2.71828182845905 2.71828182845905) 15.15426224147926) (num-test (expt 2.71828182845905 3) 20.08553692318767) (num-test (expt 2.71828182845905 pi) 23.14069263277927) (num-test (expt 2.71828182845905+2.71828182845905i 0.00000001+0.0i) 1.00000001346574+0.00000000785398i) (num-test (expt 2.71828182845905+3.14159265358979i 0.0+0.00000001i) 0.99999999142488+0.00000001424157i) (num-test (expt 2.71828182845905-2.71828182845905i -0.00000001+0.0i) 0.99999998653426+0.00000000785398i) (num-test (expt 2.71828182845905-3.14159265358979i -0.0+0.00000001i) 1.00000000857512+0.00000001424157i) (num-test (expt 2/1 3/1) 8) (num-test (expt 2/10 1234000000/500029) 0.0) (num-test (expt 2/1234 500029/1234000000) 0.99739996551176) (num-test (expt 2/1234000000 362880/1234) 0.0) (num-test (expt 2/3 -5) (/ 1 (* 2/3 2/3 2/3 2/3 2/3))) (num-test (expt 2/3 1234/362880) 0.99862213634996) (num-test (expt 2/3 5) (* 2/3 2/3 2/3 2/3 2/3)) (num-test (expt 2/362880 1/3) 0.01766399721581) (num-test (expt 2/500029 0/10) 1) (num-test (expt 25 6) (+ (expt 1 6) (expt 2 6) (expt 3 6) (expt 5 6) (expt 6 6) (expt 7 6) (expt 8 6) (expt 9 6) (expt 10 6) (expt 12 6) (expt 13 6) (expt 15 6) (expt 16 6) (expt 17 6) (expt 18 6) (expt 23 6))) (num-test (expt 256 0) 1) (num-test (expt 256 1) 256) (num-test (expt 25937424601 1/10) 11) (num-test (expt 2718/1000 617/5) 3.858179469787681136058424024656091858698003418770850904916305853631035158956514884526199288e53) ; not an int! (num-test (expt 282475249 1/10) 7) (num-test (expt 29490/26049 29490/26049) 1.15080464191338725897675441635942490625E0) (num-test (expt 3 -0.0) 1.0) (num-test (expt 3 -0.00000001) 0.99999998901388) (num-test (expt 3 -1) 1/3) (num-test (expt 3 -1.0) 0.33333333333333) (num-test (expt 3 -10) 1/59049) (num-test (expt 3 -2) 1/9) (num-test (expt 3 -2.71828182845905) 0.05047193595639) (num-test (expt 3 -3) 1/27) (num-test (expt 3 -3.14159265358979) 0.03170146783514) (num-test (expt 3 0) 1) (num-test (expt 3 0.0) 1.0) (num-test (expt 3 0.00000001) 1.00000001098612) (num-test (expt 3 1) 3) (num-test (expt 3 1.0) 3.0) (num-test (expt 3 10) 59049) (num-test (expt 3 2) 9) (num-test (expt 3 2.71828182845905) 19.81299074527465) (num-test (expt 3 3) 27) (num-test (expt 3 9) (* 3 3 3 3 3 3 3 3 3)) (num-test (expt 3 pi) 31.54428070019755) (num-test (expt 3.0 0) 1.0) (num-test (expt 3.0 0.0) 1.0) (num-test (expt 3.0 1) 3.0) (num-test (expt 3.0 1.0) 3.0) (num-test (expt 3.14159265358979 -0.0) 1.0) (num-test (expt 3.14159265358979 -0.00000001) 0.99999998855270) (num-test (expt 3.14159265358979 -1) 0.31830988618379) (num-test (expt 3.14159265358979 -1.0) 0.31830988618379) (num-test (expt 3.14159265358979 -10) 0.00001067827923) (num-test (expt 3.14159265358979 -2) 0.10132118364234) (num-test (expt 3.14159265358979 -2.71828182845905) 0.04452526726692) (num-test (expt 3.14159265358979 -3) 0.03225153443320) (num-test (expt 3.14159265358979 -3.14159265358979) 0.02742569312330) (num-test (expt 3.14159265358979 0) 1.0) (num-test (expt 3.14159265358979 0.0) 1.0) (num-test (expt 3.14159265358979 0.00000001) 1.00000001144730) (num-test (expt 3.14159265358979 1) pi) (num-test (expt 3.14159265358979 1.0) pi) (num-test (expt 3.14159265358979 10) 93648.04747608296748) (num-test (expt 3.14159265358979 2) 9.86960440108936) (num-test (expt 3.14159265358979 2.71828182845905) 22.45915771836104) (num-test (expt 3.14159265358979 3) 31.00627668029983) (num-test (expt 3.14159265358979 pi) 36.46215960720790) (num-test (expt 3.14159265358979-3.14159265358979i -1234000000.0+0.0i) 0.0) (num-test (expt 3/1 10/2) 243) (num-test (expt 3/10 500029/362880) 0.19032743228093) (num-test (expt 3/1234 362880/500029) 0.01267163536282) (num-test (expt 3/1234000000 0/1234000000) 1) (num-test (expt 3/362880 2/10) 0.09626571578282) (num-test (expt 3/4 0) 1) (num-test (expt 3/4 0.0) 1.0) (num-test (expt 3/4 1) 3/4) (num-test (expt 3/4 1.0) 0.75) (num-test (expt 3/500029 1/1234) 0.99030354920325) (num-test (expt 3486784401 1/10) 9) (num-test (expt 362880 -0.0) 1.0) (num-test (expt 362880 -0.00000001) 0.99999987198173) (num-test (expt 362880 -1) 1/362880) (num-test (expt 362880 -1.0) 0.00000275573192) (num-test (expt 362880 -2) 1/131681894400) (num-test (expt 362880 0) 1) (num-test (expt 362880 0.0) 1.0) (num-test (expt 362880 0.00000001) 1.00000012801828) (num-test (expt 362880 1) 362880) (num-test (expt 362880 1.0) 362879.99999999982538) (num-test (expt 362880/1 0/500029) 1) (num-test (expt 362880/10 3/10) 23.33076127248722) (num-test (expt 362880/1234 10/3) 169106218.17807236313820) (num-test (expt 362880/1234000000 1234/2) 0.0) (num-test (expt 362880/2 1/1234000000) 1.00000000981254) (num-test (expt 362880/3 2/1234) 1.01914896791961) (num-test (expt 36836/40706 36836/40706) 9.135636805317119582757524254250295946631E-1) (num-test (expt 38246/41321 38246/41321) 9.309245639585393834533875308768247886091E-1) (num-test (expt 4 1/3) 1.587401051968199474751705639272308260393E0) (num-test (expt 4 10) 1048576) (num-test (expt 45692/25507 45692/25507) 2.841422098671431061341360858366953184273E0) (num-test (expt 46394/6866 46394/6866) 4.043224602803809364259118808807234861721E5) (num-test (expt 5 10) 9765625) (num-test (expt 5.0e-01+1.00000000000000005551e-01i -1.0e+00+0.0e+00i) 1.9230769230769230687e0-3.8461538461538463509e-1i) (num-test (expt 5.0e-01+1.00000000000000005551e-01i 0.0e+00+0.0e+00i) 1e0+0.0i) (num-test (expt 5.0e-01+1.00000000000000005551e-01i 0.0e+00+1.0e+00i) 6.4160554864378080418e-1-5.1201864456768275590e-1i) (num-test (expt 5.0e-01+1.00000000000000005551e-01i 0.0e+00-1.0e+00i) 9.5219021866126714108e-1+7.5987364224031834571e-1i) (num-test (expt 5.0e-01+1.00000000000000005551e-01i 1.0e+00+0.0e+00i) 5e-1+1.0000000000000000555e-1i) (num-test (expt 5.0e-01+1.00000000000000005551e-01i 5.0e-01+1.00000000000000005551e-01i) 6.9977300530987816719e-1+2.1940939105372143160e-2i) (num-test (expt 5.0e-01+1.00000000000000005551e-01i 5.0e-01-1.00000000000000005551e-01i) 7.1829191470060938876e-1+1.2038189555821612762e-1i) (num-test (expt 5.0e-01-1.00000000000000005551e-01i -1.0e+00+0.0e+00i) 1.9230769230769230687e0+3.8461538461538463509e-1i) (num-test (expt 5.0e-01-1.00000000000000005551e-01i 0.0e+00+0.0e+00i) 1e0+0.0i) (num-test (expt 5.0e-01-1.00000000000000005551e-01i 0.0e+00+1.0e+00i) 9.5219021866126714108e-1-7.5987364224031834571e-1i) (num-test (expt 5.0e-01-1.00000000000000005551e-01i 0.0e+00-1.0e+00i) 6.4160554864378080418e-1+5.1201864456768275590e-1i) (num-test (expt 5.0e-01-1.00000000000000005551e-01i 1.0e+00+0.0e+00i) 5e-1-1.0000000000000000555e-1i) (num-test (expt 5.0e-01-1.00000000000000005551e-01i 5.0e-01+1.00000000000000005551e-01i) 7.1829191470060938876e-1-1.2038189555821612762e-1i) (num-test (expt 5.0e-01-1.00000000000000005551e-01i 5.0e-01-1.00000000000000005551e-01i) 6.9977300530987816719e-1-2.1940939105372143160e-2i) (num-test (expt 5.551115123125783999999999999999999999984E-17 1.110223024625156799999999999999999999997E-16) 9.999999999999958444410197170329529649165E-1) (num-test (expt 500029 -0.0) 1.0) (num-test (expt 500029 -0.00000001) 0.99999986877579) (num-test (expt 500029 -1) 1/500029) (num-test (expt 500029 -1.0) 0.00000199988401) (num-test (expt 500029 -2) 1/250029000841) (num-test (expt 500029 0) 1) (num-test (expt 500029 0.0) 1.0) (num-test (expt 500029 0.00000001) 1.00000013122422) (num-test (expt 500029 1) 500029) (num-test (expt 500029 1.0) 500029.00000000040745) (num-test (expt 500029/1 362880/1234000000) 1.00386634022855) (num-test (expt 500029/10 2/3) 1357.26128653075921) (num-test (expt 500029/1234 3/2) 8156.80442672750178) (if (not with-bignums) (num-test (expt 500029/1234000000 10/1) 0.0) (num-test (expt 500029/1234000000 10/1) 977129054104898258427314355689841897479681961836578300201/8187505353567209228244052427776000000000000000000000000000000000000000000000000000000000000)) (num-test (expt 500029/2 0/1234) 1) (num-test (expt 500029/3 1/10) 3.32803123591083) (num-test (expt 50664/22466 50664/22466) 6.258302816095884603297081160883745414829E0) (num-test (expt 512 1/9) 2) (num-test (expt 56052/41477 56052/41477) 1.502246288382607077882411462458143945519E0) (num-test (expt 58288/55799 58288/55799) 1.046641989822034585352255152505850793912E0) (num-test (expt 59049 1/10) 3) (num-test (expt 6 10) 60466176) (num-test (expt 60466176 1/10) 6) (num-test (expt 64 -1/2) 1/8) (num-test (expt 64 -1/3) 1/4) (num-test (expt 64 -1/6) 1/2) (num-test (expt 64 -2/3) 1/16) (num-test (expt 64 -3/2) 1/512) (num-test (expt 64 1/2) 8) (num-test (expt 64 1/3) 4) (num-test (expt 64 1/6) 2) (num-test (expt 64 2/3) 16) (num-test (expt 64 3/2) 512) (num-test (expt 64/81 1/2) 8/9) (num-test (expt 7 10) 282475249) (num-test (expt 747/28616 747/28616) 9.092208838715899745892490249764275628871E-1) (num-test (expt 8 1/3) 2) (num-test (expt 8 10) 1073741824) (num-test (expt 9 10) 3486784401) (num-test (expt 9765625 1/10) 5) (num-test (sqrt (- (expt 4 1/5) (expt 3 1/5))) (/ (+ (* (- (expt 2 3/5)) (expt 3 4/5)) (expt 3 3/5) (* 2 (expt 2 2/5) (expt 3 2/5)) (* (- (expt 2 4/5)) (expt 3 1/5)) (expt 2 1/5)) 5)) (num-test (sqrt (- (expt 4 2/3) (* (sqrt 3) (expt 5 1/6)))) (+ (/ (expt 5 1/3) (sqrt 6)) (- (/ (expt 5 5/6) (* 3 (sqrt 2)))) (/ (* (expt 2 1/6) (sqrt 5)) 3) (- (/ (* (expt 2 5/6) (expt 5 1/6)) 3)) (/ (expt 2 1/6) (sqrt 3)))) (num-test (sqrt (- (expt 5 1/3) (expt 4 1/3))) (/ (+ (expt 2 1/3) (expt 20 1/3) (- (expt 25 1/3))) 3)) (num-test (sqrt (- (expt 5 1/3) (expt 4 1/3))) (/ (+ (expt 2 1/3) (expt 20 1/3) (- (expt 25 1/3))) 3)) (num-test (sqrt (- 127 (* 4 (sqrt 6) (expt 7 1/4)))) (+ (/ (* (sqrt 3) (expt 7 3/4)) (sqrt 2)) (* 2 (sqrt 7)) (/ (* 3 (sqrt 3) (expt 7 1/4)) (sqrt 2)) -6)) (num-test (sqrt (- 161 (* 12 (expt 5 1/4)))) (+ (* 2 (expt 5 3/4)) (- (* 3 (sqrt 5))) (* 4 (sqrt (sqrt 5))) 6)) (num-test (sqrt (- 2 (expt 2 1/7))) (/ (* (expt 2 1/14) (+ (- (expt 2 6/7)) (expt 2 5/7) (expt 2 3/7) (* 2 (expt 2 1/7)) -1)) (sqrt 7))) (test (= (+ (expt 2421 3) (expt 19083 3)) (+ (expt 5436 3) (expt 18948 3)) (+ (expt 10200 3) (expt 18072 3)) (+ (expt 13322 3) (expt 16630 3))) #t) ;;; amol sasane MAA Monthly (num-test (expt (sqrt 2) (log 3 2)) (sqrt 3)) (num-test (expt (expt 2 (sqrt 2)) 1/2) (expt (sqrt 2) (sqrt 2))) (num-test (expt (sqrt 2) (* 2 (log 3 2))) 3) (num-test (expt (sqrt 2) (+ (sqrt 2) 1)) (* (sqrt 2) (expt (sqrt 2) (sqrt 2)))) (num-test (expt (expt (sqrt 2) (sqrt 2)) (sqrt 2)) 2) (if (not with-bignums) (begin (num-test (expt (+ 1 (/ 1000000)) 100) 1.0001000049501534764) (num-test (expt (+ 1 (/ 1000000000)) 100000000) 1.1051709271646142850) (num-test (expt (+ 1 (/ 1000000000)) 10000000000) 2.20264839094613347809362152246750859877E4) (test (infinite? (expt 3/4 most-negative-fixnum)) #t) (num-test (expt 4/3 most-negative-fixnum) 0) (num-test (expt 1.0 most-negative-fixnum) 1.0) (num-test (expt -1.0 most-negative-fixnum) 1.0) (num-test (expt 1.0 most-positive-fixnum) 1.0) (num-test (expt -1.0 most-positive-fixnum) -1.0) (num-test (expt -1.0 (+ (expt 2 53) 1)) -1.0) (num-test (expt -1.0 (- 1 (expt 2 54))) -1.0) (num-test (expt -1.0 (expt 2 54)) 1.0) (num-test (expt 2.0 (- (expt 2 53))) 0.0) (num-test (expt 2 most-negative-fixnum) 0) (test (nan? (expt 1/0 0)) #t) (test (nan? (expt (complex 0 1/0) 0)) #t) (test (nan? (expt (complex 1/0 1/0) 0)) #t) (test (nan? (expt (complex 1/0 0) 0)) #t) (num-test (expt most-negative-fixnum 8) 5.237424972633826992021103514924158643547E151) (num-test (expt most-negative-fixnum 2) 8.5070591730234615865843651857942052864E37) (num-test (expt most-negative-fixnum -1) -1.084202172485504434007452800869941711426E-19) (num-test (expt most-negative-fixnum -2) 1.175494350822287507968736537222245677819E-38))) (num-test (expt 1 most-negative-fixnum) 1) (num-test (expt -1 most-negative-fixnum) 1) (num-test (expt 1 most-positive-fixnum) 1) (num-test (expt -1 most-positive-fixnum) -1) (num-test (expt most-positive-fixnum 1) most-positive-fixnum) (num-test (expt most-positive-fixnum -1) (/ most-positive-fixnum)) (num-test (expt most-negative-fixnum 1) most-negative-fixnum) (num-test (expt most-negative-fixnum 0) 1) (num-test (expt 1/9223372036854775807 9223372036854775807) 0.0) (test (infinite? (expt 1/9223372036854775807 -9223372036854775807)) #t) (test (infinite? (expt 9223372036854775807 9223372036854775807)) #t) (num-test (expt 0+i (+ 0 (expt 2 16))) 1.0) (num-test (expt 0+i (+ 1 (expt 2 16))) 0+i) (num-test (expt 0+i (+ 2 (expt 2 16))) -1.0) (num-test (expt 0+i (+ 3 (expt 2 16))) 0-i) (num-test (expt 0-i (+ 0 (expt 2 16))) 1.0) (num-test (expt 0-i (+ 1 (expt 2 16))) 0-i) (num-test (expt 0-i (+ 2 (expt 2 16))) -1.0) (num-test (expt 0-i (+ 3 (expt 2 16))) 0+i) (num-test (expt 0+i (+ 0 (expt 2 54))) 1.0) (num-test (expt 0+i (+ 1 (expt 2 54))) 0+i) (num-test (expt 0+i (+ 2 (expt 2 54))) -1.0) (num-test (expt 0+i (+ 3 (expt 2 54))) 0-i) (num-test (expt 0-i (+ 0 (expt 2 54))) 1.0) (num-test (expt 0-i (+ 1 (expt 2 54))) 0-i) (num-test (expt 0-i (+ 2 (expt 2 54))) -1.0) (num-test (expt 0-i (+ 3 (expt 2 54))) 0+i) (let ((val1 (catch #t (lambda () (expt 0.0 0.0)) (lambda args 'error))) (val2 (catch #t (lambda () (expt 0.0 -0.0)) (lambda args 'error)))) (test (equal? val1 val2) #t)) (let ((val1 (catch #t (lambda () (expt 2.0 0.0)) (lambda args 'error))) (val2 (catch #t (lambda () (expt 2.0 -0.0)) (lambda args 'error)))) (test (equal? val1 val2) #t)) ;; (test (expt 0 0-i) 0.0) ; sbcl and clisp say division by 0 here, guile says NaN ;; but (expt 0.0 1e-15-i) is 0.0?? ;; clisp says (expt 0 1+i) is 0, but (expt 0 0+i) is division by zero??) -- sbcl agrees #| (do ((i 30 (+ i 1))) ((= i 63)) (format-logged #t "~D: (- ~A ~A) -> ~A~%" i (+ (expt 2.0 i) 500) (+ (expt 2.0 i) 100) (- (+ (expt 2.0 i) 500) (+ (expt 2.0 i) 100)))) 55: (- 3.6028797018964e+16 3.6028797018964e+16) -> 400.0 56: (- 7.2057594037928e+16 7.2057594037928e+16) -> 400.0 57: (- 1.4411518807586e+17 1.4411518807586e+17) -> 416.0 58: (- 2.8823037615171e+17 2.8823037615171e+17) -> 384.0 59: (- 5.7646075230342e+17 5.7646075230342e+17) -> 384.0 60: (- 1.1529215046068e+18 1.1529215046068e+18) -> 512.0 61: (- 2.3058430092137e+18 2.3058430092137e+18) -> 512.0 62: (- 4.6116860184274e+18 4.6116860184274e+18) -> 0.0 |# (test (or (< (magnitude (- (expt -2/362880 1/3) 0.00883199860790+0.01529747032127i)) 1e-6) (< (magnitude (- (expt -2/362880 1/3) 0.00883199860790-0.01529747032127i)) 1e-6) (< (magnitude (- (expt -2/362880 1/3) -0.017663997215805)) 1e-6)) #t) (test (< (abs (- (+ (complex 1.0 0.0) (make-polar 1.0 0.0) 1.0+0i (* -1.0 -1.0) (/ 1.0) (exp 0.0) (abs -1.0) (cos 0.0) (log (exp 1)) (magnitude 1.0+0i) (max 0.0 1.0) (min 1.0 2.0)) 12.0)) 1e-12) #t) (let ((xs (list 2 3 4 1/2 1/3 1/4 2.5 1+i 2.5+1.5i 2.5-.5i)) (ys (list 2 3 4 -2 -3 1/2 1/3 1/4 -1/2 -1/3 -1/4 2.5 -3.5 1+i -1+2i 2.5+1.5i 2.5-.5i))) (for-each (lambda (x) (for-each (lambda (y) (num-test (expt (expt x y) (/ y)) x) ;; (if (> (magnitude (- (expt (expt x y) (/ y)) x)) 1e-6) ;; (format-logged #t ";(expt (expt ~A ~A) (/ ~A)) -> ~A (~A)~%" x y y (expt (expt x y) (/ y)) (magnitude (- (expt (expt x y) (/ y)) x)))) ) ys)) xs)) (if with-bignums (begin ;; from Knuth IIp245(3rd) (let* ((f (lambda (x) (/ (- 1 (expt x 107)) (- 1 x)))) (g (lambda (y) (f (* (- 1/3 (* y y)) (+ 3 (* 3.45 y y)))))) (gx (lambda (y) (+ 107 (* -10491.35 y y) (* 659749.9625 y y y y) (* 30141386.26625 (expt y 6)))))) (do ((i 3 (+ i 1))) ((> i 10)) (let ((g1 (g (expt 10 (- i)))) (g2 (gx (expt 10 (- i))))) (let ((diff (abs (- g1 g2)))) (if (or (nan? diff) (> diff (expt 10 (- -7 i)))) (format-logged #t ";g(1e-~D) -> ~A ~A, diff: ~A~%" i g1 g2 (abs (- g1 g2)))))))) (let ((p (lambda (x y) (+ (* 2 y y) (* 9 x x x x) (* -1 y y y y))))) (num-test (p 408855776 708158977) 1)) (let ((p (lambda (x y) (+ (* 2 y y) (* (- (* 3 x x) (* y y)) (+ (* 3 x x) (* y y))))))) (num-test (p 408855776 708158977) 1)) )) (let ((top-exp 60)) (let ((happy #t)) (do ((i 2 (+ i 1))) ((or (not happy) (> i top-exp))) (let* ((val1 (+ 2 (expt 2 i))) (val2 (- val1 1))) (if (not (> val1 val2)) (begin (set! happy #f) (display "(> ") (display val1) (display " ") (display val2) (display ") -> ") (display (> val1 val2)) (display "?") (newline))) (if (< val1 val2) (begin (set! happy #f) (display "(< ") (display val1) (display " ") (display val2) (display ") -> ") (display (< val1 val2)) (display "?") (newline)))))) (let ((happy #t)) (do ((i 2 (+ i 1))) ((or (not happy) (> i top-exp))) (let* ((val1 (/ (expt 2 i) 3)) (val2 (/ (+ 1 (expt 2 i)) 3))) (if (> val1 val2) (begin (set! happy #f) (display "(> ") (display val1) (display " ") (display val2) (display ") -> ") (display (> val1 val2)) (display "?") (newline))) (if (not (> val2 val1)) (begin (set! happy #f) (display "(> ") (display val1) (display " ") (display val2) (display ") -> ") (display (> val2 val1)) (display "?") (newline))) (if (not (< val1 val2)) (begin (set! happy #f) (display "(< ") (display val1) (display " ") (display val2) (display ") -> ") (display (< val1 val2)) (display "?") (newline))) (if (< val2 val1) (begin (set! happy #f) (display "(< ") (display val1) (display " ") (display val2) (display ") -> ") (display (< val2 val1)) (display "?") (newline))) )))) (let* ((x (* #x1.6000022202b1076a (expt 2 -58))) (a (expt (- 1.01 x) (- 1.01 x))) (b (expt x (- 1.01 (expt x (- 1.01 x)))))) (num-test a 1.010100503341741589854787064753636627742E0) (num-test b 3.201463978607038931337314838029261023486E-18) (num-test x 4.770489999999999999978271189676737354422E-18) (num-test (+ a b -1.01) 1.005033417415841744668463594232356924E-4) (test (positive? (+ a b -1.01)) #t)) (do ((k 1 (+ k 1))) ((= k 12)) (num-test (+ (expt 11 k) (expt 24 k) (expt 65 k) (expt 90 k) (expt 129 k) (expt 173 k) (expt 212 k) (expt 237 k) (expt 278 k) (expt 291 k) (expt 302 k)) (+ (expt 3 k) (expt 5 k) (expt 30 k) (expt 57 k) (expt 104 k) (expt 116 k) (expt 186 k) (expt 198 k) (expt 245 k) (expt 272 k) (expt 297 k) (expt 299 k)))) (let ((top 0)) (let ((x-10 (lambda (n) (- (expt n 10) (* n n n n n n n n n n))))) (let ((happy #t) (lim (if with-bignums 100 74))) (do ((i 1 (+ i 1))) ((or (not happy) (= i lim))) ; stop around 63 bits (let ((val (x-10 i))) (if (not (= val 0)) (begin (set! top (- i 1)) (set! happy #f) (display "(expt ") (display i) (display " 10) = ") (display (expt i 10)) (display " but (* ") (display i) (display "... 10x) = ") (display (* i i i i i i i i i i)) (newline))))))) (if (> top 63) (num-test (+ (expt 1 10) (expt 2 10) (expt 4 10) (expt 5 10) (expt 6 10) (expt 8 10) (expt 12 10) (expt 15 10) (expt 16 10) (expt 17 10) (expt 20 10) (expt 21 10) (expt 25 10) (expt 26 10) (expt 27 10) (expt 28 10) (expt 30 10) (expt 36 10) (expt 37 10) (expt 38 10) (expt 40 10) (expt 51 10) (expt 62 10)) (expt 63 10)))) (do ((i 1 (+ i 1))) ((= i 10)) (let ((v (vector i (- i) (/ i) (/ i (+ i 1)) (- (/ i)) (/ (- i) (+ i 1)) (random (* i 10.0)) (sqrt i) (+ i (random (sqrt i))) (- (random (* i 2.0)) i) (complex i i) (complex (- i) (- i)) ))) (let ((len (length v))) (do ((k 0 (+ k 1))) ((= k len)) (do ((j 0 (+ j 1))) ((= j len)) (let ((val1 (catch #t (lambda () (expt (v k) (v j))) (lambda args 'error)))) ; (expt 0 -1) for example (if (number? val1) (let ((val2 (if (zero? (v k)) 0 (exp (* (v j) (log (v k)))))) (val3 (if (zero? (v k)) 0 (exp (* (v j) (+ (* 0+2i pi) (log (v k)))))))) (let ((diff (min (magnitude (- val1 val2)) (magnitude (- val1 val3))))) (if (> (/ diff (max (magnitude val1) 1)) 1e-12) (format-logged #t ";(expt ~A ~A), ~A ~A ~A: ~A~%" (v k) (v j) val1 val2 val3 diff))))))))))) (if with-bignums (num-test (let ((dickey (lambda (x y) ; from Kawa (+ (* 1335/4 (expt y 6)) (* (expt x 2) (- (* 11 (expt x 2) (expt y 2)) (expt y 6) (* 121 (expt y 4)) 2)) (* 11/2 (expt y 8)) (/ x (* 2 y)))))) (dickey 77617 33096)) -54767/66192)) (let ((x-10 (lambda (n) (- (expt n 10) (* n n n n n n n n n n))))) (let ((happy #t) (lim (if with-bignums 100 74))) (do ((i 1 (+ i 2))) ((or (not happy) (> i lim))) ; stop around 63 bits (let ((val (x-10 (/ i 2)))) (if (not (= val 0)) (begin (set! happy #f) (display "(expt ") (display i) (display "/2 10) = ") (display (expt (/ i 2) 10)) (display " but (* ") (display i) (display "/2 ... 10x) = ") (display (/ (* i i i i i i i i i i) 1024)) (newline))))))) (let ((x-10 (lambda (n) (- (expt n -10) (/ 1 (* n n n n n n n n n n)))))) (let ((happy #t) (lim (if with-bignums 100 74))) (do ((i 1 (+ i 2))) ((or (not happy) (> i lim))) ; stop around 63 bits (let ((val (x-10 (/ i 2)))) (if (not (= val 0)) (begin (set! happy #f) (display "(expt ") (display i) (display "/2 -10) = ") (display (expt (/ i 2) -10)) (display " but (* 1/(") (display i) (display "/2) ... 10x) = ") (display (/ 1024 (* i i i i i i i i i i))) (display " [diff=") (display val) (display "]") (newline))))))) (let ((happy #t) (lim (if with-bignums 50 19))) (do ((i 1 (+ i 1))) ((or (not happy) (> i lim))) (let* ((val1 (expt 3 i)) (val2 (sqrt (* val1 val1)))) (if (not (= val1 val2)) (begin (set! happy #f) (display "[3^i] (sqrt ") (display (* val1 val1)) (display " = ") (display val2) (display " but should be ") (display val1) (newline)))))) (if (not with-bignums) (begin (num-test (* (/ (expt 2 31) (+ (expt 2 20) 1)) (/ (+ (expt 2 31) 1) (expt 2 20))) 4194300.0019569) (num-test (expt -2/10 1234000000/500029) 0.0) (num-test (expt -2/1234000000 362880/1234) 0.0) (num-test (expt -1/1234000000 500029/10) 0.0) (num-test (expt 3.14159265358979-1.0i -1234.0+0.00000001i) 0.0) (num-test (expt -3.14159265358979-1.0i -1234.0-0.00000001i) 0.0) (num-test (expt 1234000000.0-1234000000.0i -1234.0+0.0i) 0.0) (num-test (expt -1234000000.0-1234000000.0i -1234.0-0.0i) 0.0) ) (begin (num-test (* (/ (expt 2 31) (+ (expt 2 20) 1)) (/ (+ (expt 2 31) 1) (expt 2 20))) 4398046513152/1048577) (test (expt 1/2 9223372036854775807) 0.0) (num-test (expt (expt -4722366482869645213696/6561 1/2) 2) -4722366482869645213696/6561) (num-test (expt 324518553658426726783156020576256.0 1/3) 68719476736.0) (num-test (expt 4722366482869645213696 1/2) 68719476736) (num-test (expt 4722366482869645213696.0 1/2) 68719476736.0) (num-test (expt 4722366482869645213696/6561 -1/2) (/ 68719476736/81)) (num-test (* (/ (expt 2 61) (+ (expt 2 40) 1)) (/ (+ (expt 2 61) 1) (expt 2 40))) 4835703278458516700921856/1099511627777) (num-test (+ (- 512 (expt 2.0 62)) (- (expt 2.0 62) 513)) -1.0) (num-test (+ (/ (expt 2 61) (+ (expt 2 40) 1)) (/ (+ (expt 2 61) 1) (expt 2 40))) 5070602400915223450095538143233/1208925819615728686333952) (num-test (+ (expt 2 61) (expt 2 62) (expt 2 61)) (/ (expt 2 64) 2)) (num-test (* 2 (expt 2 62)) (expt 2 63)) (num-test (* 8 (expt 2 30) (expt 2 30)) 9223372036854775808) (num-test (- (+ (expt 2.0 62) 500) (+ (expt 2.0 62) 100)) 4.000E2) (num-test (- (+ (expt 2.0 62) 512) (+ (expt 2.0 62) 513)) -1.0) (num-test (- (/ (expt 2 61) (+ (expt 2 40) 1)) (/ (+ (expt 2 61) 1) (expt 2 40))) -2305844108725321729/1208925819615728686333952) (num-test (/ (/ (expt 2 61) (+ (expt 2 40) 1)) (/ (+ (expt 2 61) 1) (expt 2 40))) 2535301200456458802993406410752/2535301200458764647102131732481) (num-test (/ (expt (* 1.2345e-170 1.2345e-170) 1/100)) 2.501325312985302606641508258507698932691E3) (num-test (/ (log (expt 2 32)) (log 2)) 32.0) (num-test 1180591620717411303424/1180591620717411303425 (/ (expt 2 70) (+ (expt 2 70) 1))) (test (< (abs (- (expt (- (exp (* pi (sqrt (bignum "163")))) 744) 1/3) 6.4031999999999999999999999999939031735E5)) 1e-32) #t) (test (> (+ (expt 2.0 62) 500) (+ (expt 2.0 62) 100)) #t) (num-test (expt -2/10 1234000000/500029) 9.92209574402351949043519108941671096176E-1726-4.788930572030484370393069119625570107346E-1726i) (num-test (expt -2/1234000000 362880/1234) 1.116318539471846948140196659021553350719E-2585+2.424343808068083320544106524660635302266E-2586i) (num-test (expt -1/1234000000 500029/10) -7.168156874677746632219778149112758764437E-454593+2.32907535423388290492582809530285175961E-454593i) (num-test (expt 3.14159265358979-1.0i -1234.0+0.00000001i) -4.480790643664505864348068449454625911766E-640-6.676876181099023202939008945839411012697E-641i) (num-test (expt -3.14159265358979-1.0i -1234.0-0.00000001i) -4.480790502896318391426668753233092987401E-640+6.676875971338774903151645323179283073828E-641i) (num-test (expt 1234000000.0-1234000000.0i -1234.0+0.0i) 0.0+3.815800046393940013006703716489144169017E-11405i) (num-test (expt -1234000000.0-1234000000.0i -1234.0-0.0i) 0.0-3.815800046393940013006703716489144169017E-11405i) (num-test (expt 2 1/3) 1.25992104989487316476721060727822835057E0) (test (zero? (- (expt 2 1/3) 1.2599210498949)) #f) ; make sure it's not just libm's cbrt )) (when (and (not (provided? 'freebsd)) (not (provided? 'openbsd))) (for-each (lambda (data) (let ((num1 (car data)) (num2 (cadr data)) (val (caddr data))) (num-test-2 'expt num1 num2 (expt num1 num2) val))) (vector (list 0 0 1) (list 0 1 0) (list 0 2 0) (list 0 3 0) (list 0 1/2 0) (list 0 1/3 0) (list 0 0.0 0.0) (list 0 1.0 0.0) (list 0 2.0 0.0) (list 0 1.000000000000000000000000000000000000002E-309 0.0) (list 0 1e+16 0.0) (list 0 inf.0 0.0) (list 0 0+1i 0.0) (list 0 0+2i 0.0) (list 0 0-1i 0.0) (list 0 1+1i 0.0) (list 0 1-1i 0.0) (list 0 0.1+0.1i 0.0) (list 0 1e+16+1e+16i 0.0) (list 0 1e-16+1e-16i 0.0) (list 1 0 1) (list 1 1 1) (list 1 2 1) (list 1 3 1) (list 1 -1 1) (list 1 -2 1) (list 1 -3 1) (list 1 1/2 1) (list 1 1/3 1.0) (list 1 -1/2 1.000E0) (list 1 -1/3 1.000E0) (list 1 0.0 1.000E0) (list 1 1.0 1.000E0) (list 1 2.0 1.000E0) (list 1 -2.0 1.000E0) (list 1 1.000000000000000000000000000000000000002E-309 1.000E0) (list 1 1e+16 1.000E0) (list 1 inf.0 1.000E0) (list 1 -inf.0 1.000E0) (list 1 0+1i 1.0) (list 1 0+2i 1.0) (list 1 0-1i 1.0) (list 1 1+1i 1.0) (list 1 1-1i 1.0) (list 1 -1+1i 1.0) (list 1 -1-1i 1.0) (list 1 0.1+0.1i 1.0) (list 1 1e+16+1e+16i 1.0) (list 1 1e-16+1e-16i 1.0) (list 2 0 1) (list 2 1 2) (list 2 2 4) (list 2 3 8) (list 2 -1 1/2) (list 2 -2 1/4) (list 2 -3 1/8) (list 2 1/2 1.4142135623731) (list 2 1/3 1.2599210498949) (list 2 -1/2 7.071067811865475244008443621048490392845E-1) (list 2 -1/3 7.937005259840997475556964875637659160371E-1) (list 2 0.0 1.000E0) (list 2 1.0 2.000E0) (list 2 2.0 4.000E0) (list 2 -2.0 2.500E-1) (list 2 1.000000000000000000000000000000000000002E-309 1.000E0) (list 2 -inf.0 0.0) (list 2 0+1i 7.692389013639721265783299936612707014395E-1+6.389612763136348011500329114647017842567E-1i) (list 2 0+2i 1.83456974743301676839941236809235104518E-1+9.830277404112437205861648503427281526099E-1i) (list 2 0-1i 7.692389013639721265783299936612707014395E-1-6.389612763136348011500329114647017842567E-1i) (list 2 1+1i 1.538477802727944253156659987322541402879E0+1.277922552627269602300065822929403568513E0i) (list 2 1-1i 1.538477802727944253156659987322541402879E0-1.277922552627269602300065822929403568513E0i) (list 2 -1+1i 3.846194506819860632891649968306353507197E-1+3.194806381568174005750164557323508921283E-1i) (list 2 -1-1i 3.846194506819860632891649968306353507197E-1-3.194806381568174005750164557323508921283E-1i) (list 2 0.1+0.1i 1.069199809265204517687304849996528484166E0+7.423020183379063973209835788737470580225E-2i) (list 2 1e-16+1e-16i 1.00000000000000006931471805599452949289E0+6.931471805599453429742233135802455373554E-17i) (list 3 0 1) (list 3 1 3) (list 3 2 9) (list 3 3 27) (list 3 -1 1/3) (list 3 -2 1/9) (list 3 -3 1/27) (list 3 1/2 1.7320508075689) (list 3 1/3 1.4422495703074) (list 3 -1/2 5.773502691896257645091487805019574556475E-1) (list 3 -1/3 6.933612743506347189382852083362015558497E-1) (list 3 0.0 1.000E0) (list 3 1.0 3.000E0) (list 3 2.0 9.000E0) (list 3 -2.0 1.111111111111111111111111111111111111113E-1) (list 3 1.000000000000000000000000000000000000002E-309 1.000E0) (list 3 -inf.0 0.0) (list 3 0+1i 4.548324228266097550275651435950424840878E-1+8.905770416677470590749273065651780951036E-1i) (list 3 0+2i -5.862549342913521629213761016900936427016E-1+8.101266271509919688171526765177844453941E-1i) (list 3 0-1i 4.548324228266097550275651435950424840878E-1-8.905770416677470590749273065651780951036E-1i) (list 3 1+1i 1.364497268479829265082695430785127452266E0+2.671731125003241177224781919695534285314E0i) (list 3 1-1i 1.364497268479829265082695430785127452266E0-2.671731125003241177224781919695534285314E0i) (list 3 -1+1i 1.516108076088699183425217145316808280297E-1+2.968590138892490196916424355217260317017E-1i) (list 3 -1-1i 1.516108076088699183425217145316808280297E-1-2.968590138892490196916424355217260317017E-1i) (list 3 0.1+0.1i 1.109394427306365911813022078881836880638E0+1.223721548273860448930668229757603279477E-1i) (list 3 1e-16+1e-16i 1.00000000000000010986122886681096684318E0+1.098612288668109789126712952843432012306E-16i) (list -1 0 1) (list -1 1 -1) (list -1 2 1) (list -1 3 -1) (list -1 -1 -1) (list -1 -2 1) (list -1 -3 -1) (list -1 1/2 0+1i) (list -1 1/3 -1.0) (list -1 -1/2 0.0-1.00E0i) (list -1 -1/3 5.000000000000000503430454055824822034062E-1-8.660254037844386176981523540143355578944E-1i) (list -1 0.0 1.000E0) (list -1 1.0 -1.00E0) (list -1 2.0 1.000E0) (list -1 -2.0 1.000E0) ;(list -1 1e+16 1.000E0) (list -1 0+1i 4.321391826377224977441773717172801127579E-2) (list -1 0+2i 1.86744273170798881443021293482703039342E-3) (list -1 0-1i 2.314069263277926900572908636794854738031E1) (list -1 1+1i -4.321391826377224977441773717172801127579E-2) (list -1 1-1i -2.314069263277926900572908636794854738031E1) (list -1 -1+1i -4.321391826377224977441773717172801127579E-2) (list -1 -1-1i -2.314069263277926900572908636794854738031E1) (list -1 0.1+0.1i 6.946542388413302284911578278489504217747E-1+2.257068442712257901873502529761755278285E-1i) (list -1 1e+16+1e+16i 0.0) (list -1 1e-16+1e-16i 9.999999999999996858407346410206827203587E-1+3.141592653589792185835963602803850622895E-16i) (list -2 0 1) (list -2 1 -2) (list -2 2 4) (list -2 3 -8) (list -2 -1 -1/2) (list -2 -2 1/4) (list -2 -3 -1/8) (list -2 1/2 0+1.4142135623731i) (list -2 1/3 -1.2599210498949) (list -2 -1/2 0.0-7.071067811865475244008443621048490392845E-1i) (list -2 -1/3 3.968502629920499137351498618341152884837E-1-6.873648184993012989383839761489500939792E-1i) (list -2 0.0 1.000E0) (list -2 1.0 -2.00E0) (list -2 2.0 4.000E0) (list -2 -2.0 2.500E-1) (list -2 -inf.0 0.0) (list -2 0+1i 3.324182700885665525901791766265082328307E-2+2.761202036833300995082465454051316449496E-2i) (list -2 0+2i 3.425953940655147934023229852954811989202E-4+1.835748008898304681163796172161682131024E-3i) (list -2 0-1i 1.780072097764048857359856955378859222048E1-1.478600649942216768260366593652156810413E1i) (list -2 1+1i -6.648365401771331051803583532530164656613E-2-5.522404073666601990164930908102632898992E-2i) (list -2 1-1i -3.560144195528097714719713910757718444095E1+2.957201299884433536520733187304313620826E1i) (list -2 -1+1i -1.662091350442832762950895883132541164153E-2-1.380601018416650497541232727025658224748E-2i) (list -2 -1-1i -8.900360488820244286799284776894296110238E0+7.393003249711083841301832968260784052065E0i) (list -2 0.1+0.1i 7.259699150688950609812198701314241029302E-1+2.928900391985359860022641767906842987898E-1i) (list -2 1e+16+1e+16i 0.0) (list -2 1e-16+1e-16i 9.999999999999997551554526970151686615297E-1+3.834739834149737528810186916384012655492E-16i) (list -3 0 1) (list -3 1 -3) (list -3 2 9) (list -3 3 -27) (list -3 -1 -1/3) (list -3 -2 1/9) (list -3 -3 -1/27) (list -3 1/2 0+1.7320508075689i) (list -3 1/3 -1.4422495703074) (list -3 -1/2 0.0-5.773502691896257645091487805019574556475E-1i) (list -3 -1/3 3.466806371753173943750607212746369268463E-1-6.004684775880013553913614575447052401843E-1i) (list -3 0.0 1.000E0) (list -3 1.0 -3.00E0) (list -3 2.0 9.000E0) (list -3 -2.0 1.111111111111111111111111111111111111113E-1) (list -3 -inf.0 0.0) (list -3 0+1i 1.965509114374261361108537566165204334024E-2+3.848532348622211453375207440262631065206E-2i) (list -3 0+2i -1.094797515970330168691448329739632503045E-3+1.512865081636227781901948390654863520171E-3i) (list -3 0-1i 1.052513729605287378161514526579733692066E1-2.060856958704319044776041543097331663996E1i) (list -3 1+1i -5.896527343122784083325612698495613002091E-2-1.15455970458666343601256223207878931956E-1i) (list -3 1-1i -3.157541188815862134484543579739201076193E1+6.182570876112957134328124629291994991979E1i) (list -3 -1+1i -6.551697047914204537028458553884014446755E-3-1.282844116207403817791735813420877021735E-2i) (list -3 -1-1i -3.508379098684291260538381755265778973549E0+6.869523195681063482586805143657772213312E0i) (list -3 0.1+0.1i 7.430253085825579186796890883432274992943E-1+3.354042513063949187690186935389269335405E-1i) (list -3 1e+16+1e+16i 0.0) (list -3 1e-16+1e-16i 9.999999999999997957019635078315805356955E-1+4.240204942257901974962676555647136289098E-16i) (list 1/2 0 1) (list 1/2 1 1/2) (list 1/2 2 1/4) (list 1/2 3 1/8) (list 1/2 -1 2) (list 1/2 -2 4) (list 1/2 -3 8) (list 1/2 1/2 0.70710678118655) (list 1/2 1/3 0.7937005259841) (list 1/2 -1/2 1.414213562373095048801688724209698078569E0) (list 1/2 -1/3 1.259921049894873148607716059938123324722E0) (list 1/2 0.0 1.000E0) (list 1/2 1.0 5.000E-1) (list 1/2 2.0 2.500E-1) (list 1/2 -2.0 4.000E0) (list 1/2 1.000000000000000000000000000000000000002E-309 1.000E0) (list 1/2 1e+16 0.0) (list 1/2 inf.0 0.0) (list 1/2 0+1i 7.692389013639721265783299936612707014395E-1-6.389612763136348011500329114647017842567E-1i) (list 1/2 0+2i 1.83456974743301676839941236809235104518E-1-9.830277404112437205861648503427281526099E-1i) (list 1/2 0-1i 7.692389013639721265783299936612707014395E-1+6.389612763136348011500329114647017842567E-1i) (list 1/2 1+1i 3.846194506819860632891649968306353507197E-1-3.194806381568174005750164557323508921283E-1i) (list 1/2 1-1i 3.846194506819860632891649968306353507197E-1+3.194806381568174005750164557323508921283E-1i) (list 1/2 -1+1i 1.538477802727944253156659987322541402879E0-1.277922552627269602300065822929403568513E0i) (list 1/2 -1-1i 1.538477802727944253156659987322541402879E0+1.277922552627269602300065822929403568513E0i) (list 1/2 0.1+0.1i 9.307924962319322751032548220951692988141E-1-6.462114401999142796156052473887795907618E-2i) (list 1/2 1e+16+1e+16i 0.0) (list 1/2 1e-16+1e-16i 9.999999999999999306852819440054705071071E-1-6.931471805599452468836205299399646209468E-17i) (list 1/3 0 1) (list 1/3 1 1/3) (list 1/3 2 1/9) (list 1/3 3 1/27) (list 1/3 -1 3) (list 1/3 -2 9) (list 1/3 -3 27) (list 1/3 1/2 0.57735026918963) (list 1/3 1/3 0.69336127435063) (list 1/3 -1/2 1.732050807568877341601513501094972563495E0) (list 1/3 -1/3 1.442249570307408379689974332217791378498E0) (list 1/3 0.0 1.000E0) (list 1/3 1.0 3.333333333333333148296162562473909929395E-1) (list 1/3 2.0 1.111111111111110987752997263871498932361E-1) (list 1/3 -2.0 9.000000000000000999200722162640969581442E0) (list 1/3 1.000000000000000000000000000000000000002E-309 1.000E0) (list 1/3 1e+16 0.0) (list 1/3 inf.0 0.0) (list 1/3 0+1i 4.548324228266097055906083004905301340071E-1-8.905770416677470843231987149725161148001E-1i) (list 1/3 0+2i -5.862549342913522528634995341851693014879E-1-8.101266271509919037297800414810374565267E-1i) (list 1/3 0-1i 4.548324228266097055906083004905301340071E-1+8.905770416677470843231987149725161148001E-1i) (list 1/3 1+1i 1.516108076088698934474456306943980624137E-1-2.968590138892490116287472906226681453643E-1i) (list 1/3 1-1i 1.516108076088698934474456306943980624137E-1+2.968590138892490116287472906226681453643E-1i) (list 1/3 -1+1i 1.364497268479829192516639126693602447003E0-2.671731125003241401280466674231091613441E0i) (list 1/3 -1-1i 1.364497268479829192516639126693602447003E0+2.671731125003241401280466674231091613441E0i) (list 1/3 0.1+0.1i 8.905570151840088631186184238937353595899E-1-9.823321468210062916108146236871209771647E-2i) (list 1/3 1e+16+1e+16i 0.0) (list 1/3 1e-16+1e-16i 9.999999999999998901387711331890276057033E-1-1.098612288668109603248072021584861739285E-16i) (list -1/2 0 1) (list -1/2 1 -1/2) (list -1/2 2 1/4) (list -1/2 3 -1/8) (list -1/2 -1 -2) (list -1/2 -2 4) (list -1/2 -3 -8) (list -1/2 1/2 0+0.70710678118655i) (list -1/2 1/3 -0.7937005259841) (list -1/2 -1/2 0.0-1.414213562373095048801688724209698078569E0i) (list -1/2 -1/3 6.299605249474366377321206522758126486977E-1-1.09112363597172135294521532465807648133E0i) (list -1/2 0.0 1.000E0) (list -1/2 1.0 -5.00E-1) (list -1/2 2.0 2.500E-1) (list -1/2 -2.0 4.000E0) (list -1/2 1e+16 0.0) (list -1/2 inf.0 0.0) (list -1/2 0+1i 3.324182700885665525901791766265082328307E-2-2.761202036833300995082465454051316449496E-2i) (list -1/2 0+2i 3.425953940655147934023229852954811989202E-4-1.835748008898304681163796172161682131024E-3i) (list -1/2 0-1i 1.780072097764048857359856955378859222048E1+1.478600649942216768260366593652156810413E1i) (list -1/2 1+1i -1.662091350442832762950895883132541164153E-2+1.380601018416650497541232727025658224748E-2i) (list -1/2 1-1i -8.900360488820244286799284776894296110238E0-7.393003249711083841301832968260784052065E0i) (list -1/2 -1+1i -6.648365401771331051803583532530164656613E-2+5.522404073666601990164930908102632898992E-2i) (list -1/2 -1-1i -3.560144195528097714719713910757718444095E1-2.957201299884433536520733187304313620826E1i) (list -1/2 0.1+0.1i 6.611643874791633083240145101585573999158E-1+1.651968853835831321053883592233542783317E-1i) (list -1/2 1e+16+1e+16i 0.0) (list -1/2 1e-16+1e-16i 9.999999999999996165260165850261967791906E-1+2.448445473029846938952343072863939318955E-16i) (list -1/3 0 1) (list -1/3 1 -1/3) (list -1/3 2 1/9) (list -1/3 3 -1/27) (list -1/3 -1 -3) (list -1/3 -2 9) (list -1/3 -3 -27) (list -1/3 1/2 0+0.57735026918963i) (list -1/3 1/3 -0.69336127435063) (list -1/3 -1/2 0.0-1.732050807568877341601513501094972563495E0i) (list -1/3 -1/3 7.211247851537042624522227702765802634347E-1-1.249024766483406435214284662923064132397E0i) (list -1/3 0.0 1.000E0) (list -1/3 1.0 -3.333333333333333148296162562473909929395E-1) (list -1/3 2.0 1.111111111111110987752997263871498932361E-1) (list -1/3 -2.0 9.000000000000000999200722162640969581442E0) (list -1/3 1e+16 0.0) (list -1/3 inf.0 0.0) (list -1/3 0+1i 1.965509114374261147472076343409745270744E-2-3.848532348622211562482881134707887874423E-2i) (list -1/3 0+2i -1.094797515970330336653213008135348071651E-3-1.512865081636227660355007437386042651667E-3i) (list -1/3 0-1i 1.052513729605287263760972225954207976974E1+2.060856958704319103202290360191646176391E1i) (list -1/3 1+1i -6.551697047914203461214675496548324731564E-3+1.282844116207403782948806637317477237465E-2i) (list -1/3 1-1i -3.508379098684290684449078029532994204954E0-6.869523195681063296005826865220406716345E0i) (list -1/3 -1+1i -5.896527343122783769739250113564997536121E-2+1.154559704586663532835802707239006768699E-1i) (list -1/3 -1-1i -3.15754118881586196656166312914556280733E1-6.182570876112957652808497982451530065146E1i) (list -1/3 0.1+0.1i 6.408011144159694212372342969009069525835E-1+1.327666945668531521695779387535105337549E-1i) (list -1/3 1e+16+1e+16i 0.0) (list -1/3 1e-16+1e-16i 9.999999999999995759795057742097793539085E-1+2.042980364921682582587891581219059394882E-16i) (list 0.0 0 0.0) (list 0.0 1 0.0) (list 0.0 2 0.0) (list 0.0 3 0.0) (list 0.0 1/2 0.0) (list 0.0 1/3 0.0) (list 0.0 0.0 0.0) (list 0.0 1.0 0.0) (list 0.0 2.0 0.0) (list 0.0 1.000000000000000000000000000000000000002E-309 0.0) (list 0.0 1e+16 0.0) (list 0.0 inf.0 0.0) (list 0.0 0+1i 0.0) (list 0.0 0+2i 0.0) (list 0.0 0-1i 0.0) (list 0.0 1+1i 0.0) (list 0.0 1-1i 0.0) (list 0.0 0.1+0.1i 0.0) (list 0.0 1e+16+1e+16i 0.0) (list 0.0 1e-16+1e-16i 0.0) (list 1.0 0 1.0) (list 1.0 1 1.0) (list 1.0 2 1.0) (list 1.0 3 1.0) (list 1.0 -1 1.0) (list 1.0 -2 1.0) (list 1.0 -3 1.0) (list 1.0 1/2 1.0) (list 1.0 1/3 1.0) (list 1.0 -1/2 1.000E0) (list 1.0 -1/3 1.000E0) (list 1.0 0.0 1.000E0) (list 1.0 1.0 1.000E0) (list 1.0 2.0 1.000E0) (list 1.0 -2.0 1.000E0) (list 1.0 1.000000000000000000000000000000000000002E-309 1.000E0) (list 1.0 1e+16 1.000E0) (list 1.0 inf.0 1.000E0) (list 1.0 -inf.0 1.000E0) (list 1.0 0+1i 1) (list 1.0 0+2i 1) (list 1.0 0-1i 1) (list 1.0 1+1i 1) (list 1.0 1-1i 1) (list 1.0 -1+1i 1) (list 1.0 -1-1i 1) (list 1.0 0.1+0.1i 1) (list 1.0 1e+16+1e+16i 1) (list 1.0 1e-16+1e-16i 1) (list 2.0 0 1.0) (list 2.0 1 2.0) (list 2.0 2 4.000E0) (list 2.0 3 8.000E0) (list 2.0 -1 5.000E-1) (list 2.0 -2 2.500E-1) (list 2.0 -3 1.250E-1) (list 2.0 1/2 1.4142135623731) (list 2.0 1/3 1.2599210498949) (list 2.0 -1/2 7.071067811865475244008443621048490392845E-1) (list 2.0 -1/3 7.937005259840997475556964875637659160371E-1) (list 2.0 0.0 1.000E0) (list 2.0 1.0 2.000E0) (list 2.0 2.0 4.000E0) (list 2.0 -2.0 2.500E-1) (list 2.0 1.000000000000000000000000000000000000002E-309 1.000E0) (list 2.0 -inf.0 0.0) (list 2.0 0+1i 7.692389013639721265783299936612707014395E-1+6.389612763136348011500329114647017842567E-1i) (list 2.0 0+2i 1.83456974743301676839941236809235104518E-1+9.830277404112437205861648503427281526099E-1i) (list 2.0 0-1i 7.692389013639721265783299936612707014395E-1-6.389612763136348011500329114647017842567E-1i) (list 2.0 1+1i 1.538477802727944253156659987322541402879E0+1.277922552627269602300065822929403568513E0i) (list 2.0 1-1i 1.538477802727944253156659987322541402879E0-1.277922552627269602300065822929403568513E0i) (list 2.0 -1+1i 3.846194506819860632891649968306353507197E-1+3.194806381568174005750164557323508921283E-1i) (list 2.0 -1-1i 3.846194506819860632891649968306353507197E-1-3.194806381568174005750164557323508921283E-1i) (list 2.0 0.1+0.1i 1.069199809265204517687304849996528484166E0+7.423020183379063973209835788737470580225E-2i) (list 2.0 1e-16+1e-16i 1.00000000000000006931471805599452949289E0+6.931471805599453429742233135802455373554E-17i) (list -2.0 0 1.0) (list -2.0 1 -2.0) (list -2.0 2 4.000E0) (list -2.0 3 -8.00E0) (list -2.0 -1 -5.00E-1) (list -2.0 -2 2.500E-1) (list -2.0 -3 -1.25E-1) (list -2.0 1/2 0+1.4142135623731i) (list -2.0 1/3 -1.2599210498949) (list -2.0 -1/2 0.0-7.071067811865475244008443621048490392845E-1i) (list -2.0 -1/3 3.968502629920499137351498618341152884837E-1-6.873648184993012989383839761489500939792E-1i) (list -2.0 0.0 1.000E0) (list -2.0 1.0 -2.00E0) (list -2.0 2.0 4.000E0) (list -2.0 -2.0 2.500E-1) (list -2.0 -inf.0 0.0) (list -2.0 0+1i 3.324182700885665525901791766265082328307E-2+2.761202036833300995082465454051316449496E-2i) (list -2.0 0+2i 3.425953940655147934023229852954811989202E-4+1.835748008898304681163796172161682131024E-3i) (list -2.0 0-1i 1.780072097764048857359856955378859222048E1-1.478600649942216768260366593652156810413E1i) (list -2.0 1+1i -6.648365401771331051803583532530164656613E-2-5.522404073666601990164930908102632898992E-2i) (list -2.0 1-1i -3.560144195528097714719713910757718444095E1+2.957201299884433536520733187304313620826E1i) (list -2.0 -1+1i -1.662091350442832762950895883132541164153E-2-1.380601018416650497541232727025658224748E-2i) (list -2.0 -1-1i -8.900360488820244286799284776894296110238E0+7.393003249711083841301832968260784052065E0i) (list -2.0 0.1+0.1i 7.259699150688950609812198701314241029302E-1+2.928900391985359860022641767906842987898E-1i) (list -2.0 1e+16+1e+16i 0.0) (list -2.0 1e-16+1e-16i 9.999999999999997551554526970151686615297E-1+3.834739834149737528810186916384012655492E-16i) (list 1.000000000000000000000000000000000000002E-309 0 1.0) (list 1.000000000000000000000000000000000000002E-309 1 1.000000000000000000000000000000000000002E-309) (list 1.000000000000000000000000000000000000002E-309 2 1.000000000000000000000000000000000000006E-618) (list 1.000000000000000000000000000000000000002E-309 3 1.000000000000000000000000000000000000006E-927) (list 1.000000000000000000000000000000000000002E-309 1/2 3.162277660168379331998893544432718533725E-155) (list 1.000000000000000000000000000000000000002E-309 1/3 1.000000000000000000000000000000000000001E-103) (list 1.000000000000000000000000000000000000002E-309 -1/2 3.162277660168379331998893544432718533715E154) (list 1.000000000000000000000000000000000000002E-309 -1/3 9.999999999999868346276200367559315452517E102) (list 1.000000000000000000000000000000000000002E-309 0.0 1.000E0) (list 1.000000000000000000000000000000000000002E-309 1.0 1.000000000000000000000000000000000000002E-309) (list 1.000000000000000000000000000000000000002E-309 2.0 1.000000000000000000000000000000000000006E-618) (list 1.000000000000000000000000000000000000002E-309 1.000000000000000000000000000000000000002E-309 1.000E0) (list 1.000000000000000000000000000000000000002E-309 1e+16 0.0) (list 1.000000000000000000000000000000000000002E-309 inf.0 0.0) (list 1.000000000000000000000000000000000000002E-309 0+1i 7.188026041688456386956035152151008205727E-2-9.974132684912512522858369772702724490842E-1i) (list 1.000000000000000000000000000000000000002E-309 0+2i -9.896664563248017162886921042023427507381E-1-1.433886509648142863446390724753118562651E-1i) (list 1.000000000000000000000000000000000000002E-309 0-1i 7.188026041688456386956035152151008205727E-2+9.974132684912512522858369772702724490842E-1i) (list 1.000000000000000000000000000000000000002E-309 1+1i 7.188026041688456386956035152151008205733E-311-9.974132684912512522858369772702724490883E-310i) (list 1.000000000000000000000000000000000000002E-309 1-1i 7.188026041688456386956035152151008205733E-311+9.974132684912512522858369772702724490883E-310i) (list 1.000000000000000000000000000000000000002E-309 0.1+0.1i -5.63455610426506242496256141630861088283E-32-1.125793483521731083006048050604051624164E-31i) (list 1.000000000000000000000000000000000000002E-309 1e+16+1e+16i 0.0) (list 1.000000000000000000000000000000000000002E-309 1e-16+1e-16i 9.999999999999288501206264839898510340166E-1-7.114987937351094784363111696637191907549E-14i) (list 1e+16 0 1.0) (list 1e+16 1 1e+16) (list 1e+16 2 1.000E32) (list 1e+16 3 1.000E48) (list 1e+16 -1 1.000000000000000000000000000000000000001E-16) (list 1e+16 -2 9.999999999999999999999999999999999999998E-33) (list 1e+16 -3 9.999999999999999999999999999999999999991E-49) (list 1e+16 1/2 100000000.0) (list 1e+16 1/3 215443.46900319) (list 1e+16 -1/2 9.99999999999999999999999999999999999999E-9) (list 1e+16 -1/3 4.641588833612782056591069448235278756067E-6) (list 1e+16 0.0 1.000E0) (list 1e+16 1.0 1.000E16) (list 1e+16 2.0 1.000E32) (list 1e+16 -2.0 9.999999999999999999999999999999999999998E-33) (list 1e+16 1.000000000000000000000000000000000000002E-309 1.000E0) (list 1e+16 -inf.0 0.0) (list 1e+16 0+1i 6.541406923671771082966425998087477095845E-1-7.563728938753623529733450264648351927405E-1i) (list 1e+16 0+2i -1.441999091787803208994630162235380065937E-1-9.895485769747898065837021120946943010267E-1i) (list 1e+16 0-1i 6.541406923671771082966425998087477095845E-1+7.563728938753623529733450264648351927405E-1i) (list 1e+16 1+1i 6.541406923671771082966425998087477095832E15-7.563728938753623529733450264648351927387E15i) (list 1e+16 1-1i 6.541406923671771082966425998087477095832E15+7.563728938753623529733450264648351927387E15i) (list 1e+16 -1+1i 6.541406923671771082966425998087477095825E-17-7.563728938753623529733450264648351927399E-17i) (list 1e+16 -1-1i 6.541406923671771082966425998087477095825E-17+7.563728938753623529733450264648351927399E-17i) (list 1e+16 0.1+0.1i -3.409382666305111714726686098434812471081E1-2.055490637125206804018448749591854294103E1i) (list 1e+16 1e-16+1e-16i 1.000000000000003684136148790473017422188E0+3.684136148790486590281349632497736627823E-15i) (list inf.0 0 1.0) (list inf.0 -1 0.0) (list inf.0 -2 0.0) (list inf.0 -3 0.0) (list inf.0 -1/2 0.0) (list inf.0 -1/3 0.0) (list inf.0 0.0 1.000E0) (list inf.0 -2.0 0.0) (list inf.0 -inf.0 0.0) (list inf.0 -1+1i 0.0) (list inf.0 -1-1i 0.0) (list -inf.0 0 1.0) (list -inf.0 -1 0.0) (list -inf.0 -2 0.0) (list -inf.0 -3 0.0) (list -inf.0 -1/2 0.0) (list -inf.0 -1/3 0.0) (list -inf.0 0.0 1.000E0) (list -inf.0 -2.0 0.0) (list -inf.0 -inf.0 0.0) (list -inf.0 -1+1i 0.0) (list -inf.0 -1-1i 0.0) (list 0+1i 0 1.0) (list 0+1i 1 0+1i) (list 0+1i 2 -1.00E0) (list 0+1i 3 0.0-1.00E0i) (list 0+1i -1 0.0-1.00E0i) (list 0+1i -2 -1.00E0) (list 0+1i -3 0.0+1.000E0i) (list 0+1i 1/2 0.70710678118655+0.70710678118655i) (list 0+1i 1/3 8.660254037844386612965085791222353988232E-1+4.999999999999999748284772972087582646907E-1i) (list 0+1i -1/2 7.071067811865475244008443621048490392845E-1-7.071067811865475244008443621048490392845E-1i) (list 0+1i -1/3 8.660254037844386612965085791222353988232E-1-4.999999999999999748284772972087582646907E-1i) (list 0+1i 0.0 1.000E0) (list 0+1i 1.0 0.0+1.000E0i) (list 0+1i 2.0 -1.00E0) (list 0+1i -2.0 -1.00E0) (list 0+1i 1.000000000000000000000000000000000000002E-309 1.000E0+1.570796326794896619231321691639751442098E-309i) ;(list 0+1i 1e+16 1.000E0) (list 0+1i 0+1i 2.078795763507619085469556198349787700342E-1) (list 0+1i 0+2i 4.321391826377224977441773717172801127579E-2) (list 0+1i 0-1i 4.810477380965351655473035666703833126401E0) (list 0+1i 1+1i 0.0+2.078795763507619085469556198349787700342E-1i) (list 0+1i 1-1i 0.0+4.810477380965351655473035666703833126401E0i) (list 0+1i -1+1i 0.0-2.078795763507619085469556198349787700342E-1i) (list 0+1i -1-1i 0.0-4.810477380965351655473035666703833126401E0i) (list 0+1i 0.1+0.1i 8.441140118165246481415723784169170682829E-1+1.336945253316592796595429310740609657101E-1i) (list 0+1i 1e+16+1e+16i 0.0) (list 0+1i 1e-16+1e-16i 9.999999999999998429203673205103413601794E-1+1.570796326794896339658091828635841709635E-16i) (list 0+2i 0 1.0) (list 0+2i 1 0+2i) (list 0+2i 2 -4.00E0) (list 0+2i 3 0.0-8.00E0i) (list 0+2i -1 0.0-5.00E-1i) (list 0+2i -2 -2.50E-1) (list 0+2i -3 0.0+1.250E-1i) (list 0+2i 1/2 1+1i) (list 0+2i 1/3 1.09112363597172140787570207348670009638E0+6.299605249474365425897267188156853709001E-1i) (list 0+2i -1/2 5.000E-1-5.00E-1i) (list 0+2i -1/3 6.873648184993013335424222440592397343418E-1-3.968502629920498537991974347557662898919E-1i) (list 0+2i 0.0 1.000E0) (list 0+2i 1.0 0.0+2.000E0i) (list 0+2i 2.0 -4.00E0) (list 0+2i -2.0 -2.50E-1) (list 0+2i 1.000000000000000000000000000000000000002E-309 1.000E0+1.570796326794896619231321691639751442098E-309i) (list 0+2i -inf.0 0.0) (list 0+2i 0+1i 1.599090569280680525199117755445296515815E-1+1.328269994246205222492823642245871455648E-1i) (list 0+2i 0+2i 7.927894711475968677072935966913922424434E-3+4.248048042515221109836149914964543748435E-2i) (list 0+2i 0-1i 3.700406335570025108741522919010577122043E0-3.073708767019492322385562434551223151799E0i) (list 0+2i 1+1i -2.656539988492410444985647284491742911296E-1+3.19818113856136105039823551089059303163E-1i) (list 0+2i 1-1i 6.147417534038984644771124869102446303599E0+7.400812671140050217483045838021154244087E0i) (list 0+2i -1+1i 6.641349971231026112464118211229357278239E-2-7.995452846403402625995588777226482579074E-2i) (list 0+2i -1-1i -1.5368543835097461611927812172756115759E0-1.850203167785012554370761459505288561022E0i) (list 0+2i 0.1+0.1i 8.926023688328728424160522546503419745435E-1+2.056049144522835172454080598405456305612E-1i) (list 0+2i 1e+16+1e+16i 0.0) (list 0+2i 1e-16+1e-16i 9.999999999999999122350853765048490772098E-1+2.263943507354841682632315142216062597333E-16i) (list 0-1i 0 1.0) (list 0-1i 1 0-1i) (list 0-1i 2 -1.00E0) (list 0-1i 3 0.0+1.000E0i) (list 0-1i -1 0.0+1.000E0i) (list 0-1i -2 -1.00E0) (list 0-1i -3 0.0-1.00E0i) (list 0-1i 1/2 0.70710678118655-0.70710678118655i) (list 0-1i 1/3 8.660254037844386612965085791222353988232E-1-4.999999999999999748284772972087582646907E-1i) (list 0-1i -1/2 7.071067811865475244008443621048490392845E-1+7.071067811865475244008443621048490392845E-1i) (list 0-1i -1/3 8.660254037844386612965085791222353988232E-1+4.999999999999999748284772972087582646907E-1i) (list 0-1i 0.0 1.000E0) (list 0-1i 1.0 0.0-1.00E0i) (list 0-1i 2.0 -1.00E0) (list 0-1i -2.0 -1.00E0) (list 0-1i 1.000000000000000000000000000000000000002E-309 1.000E0-1.570796326794896619231321691639751442098E-309i) ;(list 0-1i 1e+16 1.000E0) (list 0-1i 0+1i 4.810477380965351655473035666703833126401E0) (list 0-1i 0+2i 2.314069263277926900572908636794854738031E1) (list 0-1i 0-1i 2.078795763507619085469556198349787700342E-1) (list 0-1i 1+1i 0.0-4.810477380965351655473035666703833126401E0i) (list 0-1i 1-1i 0.0-2.078795763507619085469556198349787700342E-1i) (list 0-1i -1+1i 0.0+4.810477380965351655473035666703833126401E0i) (list 0-1i -1-1i 0.0+2.078795763507619085469556198349787700342E-1i) (list 0-1i 0.1+0.1i 1.15568305287131774105188044357174956096E0-1.830422135215751576397991439148491080012E-1i) (list 0-1i 1e-16+1e-16i 1.000000000000000157079632679489658639818E0-1.570796326794896833138311883103752021701E-16i) (list 1+1i 0 1.0) (list 1+1i 1 1+1i) (list 1+1i 2 0.0+2.000E0i) (list 1+1i 3 -2.00E0+2.000E0i) (list 1+1i -1 5.000E-1-5.00E-1i) (list 1+1i -2 0.0-5.00E-1i) (list 1+1i -3 -2.50E-1-2.50E-1i) (list 1+1i 1/2 1.0986841134678+0.45508986056223i) (list 1+1i 1/3 1.084215081491351179148689172984121435876E0+2.905145555072514268841073782856571173254E-1i) (list 1+1i -1/2 7.768869870150186536720794765315734740815E-1-3.217971264527913123677217187091049044625E-1i) (list 1+1i -1/3 8.605420804595790018414012402960957705697E-1-2.305815555121423995608566442452670487351E-1i) (list 1+1i 0.0 1.000E0) (list 1+1i 1.0 1.000E0+1.000E0i) (list 1+1i 2.0 0.0+2.000E0i) (list 1+1i -2.0 0.0-5.00E-1i) (list 1+1i 1.000000000000000000000000000000000000002E-309 1.000E0+7.853981633974483096156608458198757210488E-310i) (list 1+1i -inf.0 0.0) (list 1+1i 0+1i 4.288290062943678493226520070973354996125E-1+1.548717524642467781923098896798325813036E-1i) (list 1+1i 0+2i 1.599090569280680525199117755445296515815E-1+1.328269994246205222492823642245871455648E-1i) (list 1+1i 0-1i 2.062872235080904951706990637170143171029E0-7.450070621797240878593548325920103204625E-1i) (list 1+1i 1+1i 2.739572538301210711303421174175029183081E-1+5.837007587586146275149618967771680809154E-1i) (list 1+1i 1-1i 2.807879297260629039566345469762153491497E0+1.317865172901180863847635804578132850572E0i) (list 1+1i -1+1i 2.918503793793073137574809483885840404577E-1-1.369786269150605355651710587087514591541E-1i) (list 1+1i -1-1i 6.589325864505904319238179022890664252861E-1-1.403939648630314519783172734881076745749E0i) (list 1+1i 0.1+0.1i 9.509412581367732262071184402582209392577E-1+1.08106001655210286400223506650660553711E-1i) (list 1+1i 1e+16+1e+16i 0.0) (list 1+1i 1e-16+1e-16i 9.99999999999999956117542688252429982572E-1+1.131971753677420890989859729961488955736E-16i) (list 1-1i 0 1.0) (list 1-1i 1 1-1i) (list 1-1i 2 0.0-2.00E0i) (list 1-1i 3 -2.00E0-2.00E0i) (list 1-1i -1 5.000E-1+5.000E-1i) (list 1-1i -2 0.0+5.000E-1i) (list 1-1i -3 -2.50E-1+2.500E-1i) (list 1-1i 1/2 1.0986841134678-0.45508986056223i) (list 1-1i 1/3 1.084215081491351179148689172984121435876E0-2.905145555072514268841073782856571173254E-1i) (list 1-1i -1/2 7.768869870150186536720794765315734740815E-1+3.217971264527913123677217187091049044625E-1i) (list 1-1i -1/3 8.605420804595790018414012402960957705697E-1+2.305815555121423995608566442452670487351E-1i) (list 1-1i 0.0 1.000E0) (list 1-1i 1.0 1.000E0-1.00E0i) (list 1-1i 2.0 0.0-2.00E0i) (list 1-1i -2.0 0.0+5.000E-1i) (list 1-1i 1.000000000000000000000000000000000000002E-309 1.000E0-7.853981633974483096156608458198757210488E-310i) (list 1-1i -inf.0 0.0) (list 1-1i 0+1i 2.062872235080904951706990637170143171029E0+7.450070621797240878593548325920103204625E-1i) (list 1-1i 0+2i 3.700406335570025108741522919010577122043E0+3.073708767019492322385562434551223151799E0i) (list 1-1i 0-1i 4.288290062943678493226520070973354996125E-1-1.548717524642467781923098896798325813036E-1i) (list 1-1i 1+1i 2.807879297260629039566345469762153491497E0-1.317865172901180863847635804578132850572E0i) (list 1-1i 1-1i 2.739572538301210711303421174175029183081E-1-5.837007587586146275149618967771680809154E-1i) (list 1-1i -1+1i 6.589325864505904319238179022890664252861E-1+1.403939648630314519783172734881076745749E0i) (list 1-1i -1-1i 2.918503793793073137574809483885840404577E-1+1.369786269150605355651710587087514591541E-1i) (list 1-1i 0.1+0.1i 1.118774658142734663065880800594211744947E0-4.912611879174141197780391086654035970153E-2i) (list 1-1i 1e-16+1e-16i 1.000000000000000113197175367742099510321E0-4.388245731174756954083421259082963337401E-17i) (list -1+1i 0 1.0) (list -1+1i 1 -1+1i) (list -1+1i 2 0.0-2.00E0i) (list -1+1i 3 2.000E0+2.000E0i) (list -1+1i -1 -5.00E-1-5.00E-1i) (list -1+1i -2 0.0+5.000E-1i) (list -1+1i -3 2.500E-1-2.50E-1i) (list -1+1i 1/2 0.45508986056223+1.0986841134678i) (list -1+1i 1/3 7.937005259840997668899692535826356354889E-1+7.937005259840996976818927177620594283082E-1i) (list -1+1i -1/2 3.217971264527913123677217187091049044625E-1-7.768869870150186536720794765315734740815E-1i) (list -1+1i -1/3 6.299605249474366138887223148884515164688E-1-6.299605249474365589582355660598282273075E-1i) (list -1+1i 0.0 1.000E0) (list -1+1i 1.0 -1.00E0+1.000E0i) (list -1+1i 2.0 0.0-2.00E0i) (list -1+1i -2.0 0.0+5.000E-1i) (list -1+1i 1.000000000000000000000000000000000000002E-309 1.000E0+2.35619449019234492884698253745962716315E-309i) (list -1+1i -inf.0 0.0) (list -1+1i 0+1i 8.914479215539140039333169785416699948907E-2+3.219467429096768688435430339284927790439E-2i) (list -1+1i 0+2i 6.910296915726436425237112293342453374671E-3+5.7399750963576748986151091014202337188E-3i) (list -1+1i 0-1i 9.923400226678132867281183645053121674554E0-3.583839621275010020102858511593195855531E0i) (list -1+1i 1+1i -1.213394664463590872776860012470162773935E-1+5.695011786442371350897739446131772158468E-2i) (list -1+1i 1-1i -6.339560605403122847178325133459925819034E0+1.350723984795314288738404215664631753007E1i) (list -1+1i -1+1i -2.847505893221185675448869723065886079234E-2-6.066973322317954363884300062350813869673E-2i) (list -1+1i -1-1i -6.753619923976571443692021078323158765037E0-3.169780302701561423589162566729962909517E0i) (list -1+1i 0.1+0.1i 7.882496598308880991233017323974702727041E-1+2.1838943088351018304792416348997040808E-1i) (list -1+1i 1e+16+1e+16i 0.0) (list -1+1i 1e-16+1e-16i 9.999999999999997990379100087627604548201E-1+2.702768080472316983907841531363385588262E-16i) (list -1-1i 0 1.0) (list -1-1i 1 -1-1i) (list -1-1i 2 0.0+2.000E0i) (list -1-1i 3 2.000E0-2.00E0i) (list -1-1i -1 -5.00E-1+5.000E-1i) (list -1-1i -2 0.0-5.00E-1i) (list -1-1i -3 2.500E-1+2.500E-1i) (list -1-1i 1/2 0.45508986056223-1.0986841134678i) (list -1-1i 1/3 7.937005259840997668899692535826356354889E-1-7.937005259840996976818927177620594283082E-1i) (list -1-1i -1/2 3.217971264527913123677217187091049044625E-1+7.768869870150186536720794765315734740815E-1i) (list -1-1i -1/3 6.299605249474366138887223148884515164688E-1+6.299605249474365589582355660598282273075E-1i) (list -1-1i 0.0 1.000E0) (list -1-1i 1.0 -1.00E0-1.00E0i) (list -1-1i 2.0 0.0+2.000E0i) (list -1-1i -2.0 0.0-5.00E-1i) (list -1-1i 1.000000000000000000000000000000000000002E-309 1.000E0-2.35619449019234492884698253745962716315E-309i) (list -1-1i -inf.0 0.0) (list -1-1i 0+1i 9.923400226678132867281183645053121674554E0+3.583839621275010020102858511593195855531E0i) (list -1-1i 0+2i 8.562996562781501151982322359385576132148E1+7.112774982027701655978420905114385775416E1i) (list -1-1i 0-1i 8.914479215539140039333169785416699948907E-2-3.219467429096768688435430339284927790439E-2i) (list -1-1i 1+1i -6.339560605403122847178325133459925819034E0-1.350723984795314288738404215664631753007E1i) (list -1-1i 1-1i -1.213394664463590872776860012470162773935E-1-5.695011786442371350897739446131772158468E-2i) (list -1-1i -1+1i -6.753619923976571443692021078323158765037E0+3.169780302701561423589162566729962909517E0i) (list -1-1i -1-1i -2.847505893221185675448869723065886079234E-2+6.066973322317954363884300062350813869673E-2i) (list -1-1i 0.1+0.1i 1.283956758872096257591990187677552600208E0-2.615572127992484175251616566885584992446E-1i) (list -1-1i 1e-16+1e-16i 1.000000000000000270276808047231769038073E0-2.009620899912372775286764036246047795846E-16i) (list 0.1+0.1i 0 1.0) (list 0.1+0.1i 1 0.1+0.1i) (list 0.1+0.1i 2 0.0+2.000000000000000222044604925031314247702E-2i) (list 0.1+0.1i 3 -2.000000000000000333066907387546980616012E-3+2.000000000000000333066907387546980616012E-3i) (list 0.1+0.1i -1 4.999999999999999722444243843710880301532E0-4.999999999999999722444243843710880301532E0i) (list 0.1+0.1i -2 0.0-4.999999999999999444888487687421776010503E1i) (list 0.1+0.1i -3 -2.499999999999999583666365765566343563457E2-2.499999999999999583666365765566343563457E2i) (list 0.1+0.1i 1/2 0.34743442276012+0.14391204994251i) (list 0.1+0.1i 1/3 5.032480615484825043523903544407412355396E-1+1.348449116844438143505188591437346924604E-1i) (list 0.1+0.1i -1/2 2.45673236351311521671469493547019420871E0-1.017611864088040968689409531603674348818E0i) (list 0.1+0.1i -1/3 1.853981710374325315321217484547221353494E0-4.967729020768720696346827580207236635648E-1i) (list 0.1+0.1i 0.0 1.000E0) (list 0.1+0.1i 1.0 1.000000000000000055511151231257827021182E-1+1.000000000000000055511151231257827021182E-1i) (list 0.1+0.1i 2.0 0.0+2.000000000000000222044604925031314247702E-2i) (list 0.1+0.1i -2.0 0.0-4.999999999999999444888487687421776010503E1i) (list 0.1+0.1i 1.000000000000000000000000000000000000002E-309 1.000E0+7.853981633974483096156608458198757210488E-310i) (list 0.1+0.1i 1e+16 0.0) (list 0.1+0.1i inf.0 0.0) (list 0.1+0.1i 0+1i -1.713226510357599956083331913106303247236E-1-4.22525887482460786856087271691853977193E-1i) (list 0.1+0.1i 0+2i -1.491766748349203175549260651566533449245E-1+1.447765103494648437770214174856742113327E-1i) (list 0.1+0.1i 0-1i -8.241437376545436347801862567004657850891E-1+2.032551224606688826869616254728598600103E0i) (list 0.1+0.1i 1+1i 2.512032364467008051923349285554493285946E-2-5.938485385182208154296364931488770060654E-2i) (list 0.1+0.1i 1-1i -2.856694962261232620228228583084710444815E-1+1.208407486952145259169520755212883935691E-1i) (list 0.1+0.1i -1+1i -2.969242692591103747496022164280467138525E0-1.256016182233503886515866161034993752114E0i) (list 0.1+0.1i -1-1i 6.042037434760725625046696204216927090118E0+1.428347481130616151535688219886713564214E1i) (list 0.1+0.1i 0.1+0.1i 7.550220306566742029451631510549876832316E-1-8.878982993466537268563019824356751882119E-2i) (list 0.1+0.1i 1e+16+1e+16i 0.0) (list 0.1+0.1i 1e-16+1e-16i 9.999999999999997258590333888479081137213E-1-1.170613339316624318801081266623392933101E-16i) (list 1e+16+1e+16i 0 1.0) (list 1e+16+1e+16i 1 1e+16+1e+16i) (list 1e+16+1e+16i 2 0.0+2.000E32i) (list 1e+16+1e+16i 3 -2.00E48+2.000E48i) (list 1e+16+1e+16i -1 5.000000000000000000000000000000000000004E-17-5.000000000000000000000000000000000000004E-17i) (list 1e+16+1e+16i -2 0.0-4.999999999999999999999999999999999999999E-33i) (list 1e+16+1e+16i -3 -2.499999999999999999999999999999999999998E-49-2.499999999999999999999999999999999999998E-49i) (list 1e+16+1e+16i 1/2 109868411.34678+45508986.056223i) (list 1e+16+1e+16i 1/3 2.335870583020711134947889498537726801442E5+6.258946363440152792122310286091229534238E4i) (list 1e+16+1e+16i -1/2 7.76886987015018653672079476531573474081E-9-3.217971264527913123677217187091049044617E-9i) (list 1e+16+1e+16i -1/3 3.994282511515094148675512812353991597295E-6-1.070264773302225997506194769200154785053E-6i) (list 1e+16+1e+16i 0.0 1.000E0) (list 1e+16+1e+16i 1.0 1.000E16+1.000E16i) (list 1e+16+1e+16i 2.0 0.0+2.000E32i) (list 1e+16+1e+16i -2.0 0.0-4.999999999999999999999999999999999999999E-33i) (list 1e+16+1e+16i 1.000000000000000000000000000000000000002E-309 1.000E0+7.853981633974483096156608458198757210488E-310i) (list 1e+16+1e+16i -inf.0 0.0) (list 1e+16+1e+16i 0+1i 3.97655298675457451476815297378330384373E-1-2.23046721083486532799277949440696753733E-1i) (list 1e+16+1e+16i 0+2i 1.083798967785726369788640263558841648425E-1-1.773914209820705797251910148995630479122E-1i) (list 1e+16+1e+16i 0-1i 1.912911819699309232365644880468914363155E0+1.072961206670599579011330828139081101248E0i) (list 1e+16+1e+16i 1+1i 6.207020197589439842760932468190271381067E15+1.746085775919709186775373479376336306396E15i) (list 1e+16+1e+16i 1-1i 8.39950613028709653354314052329833261908E15+2.985873026369908811376975708607995464407E16i) (list 1e+16+1e+16i -1+1i 8.730428879598545933876867396881681532013E-18-3.103510098794719921380466234095135690525E-17i) (list 1e+16+1e+16i -1-1i 1.492936513184954405688487854303997732202E-16-4.19975306514354826677157026164916630953E-17i) (list 1e+16+1e+16i 0.1+0.1i -3.019911767946562559553699791129052056384E1-2.323225580723027414176687762549620584343E1i) (list 1e+16+1e+16i 1e-16+1e-16i 1.000000000000003640253691478724868702006E0+3.797333324158228934745194038802400084708E-15i) (list 1e-16+1e-16i 0 1.0) (list 1e-16+1e-16i 1 1e-16+1e-16i) (list 1e-16+1e-16i 2 0.0+1.999999999999999916391146896138415121169E-32i) (list 1e-16+1e-16i 3 -1.999999999999999874586720344207623992465E-48+1.999999999999999874586720344207623992465E-48i) (list 1e-16+1e-16i -1 5.000000000000000104511066379826984375319E15-5.000000000000000104511066379826984375319E15i) (list 1e-16+1e-16i -2 0.0-5.00000000000000020902213275965397093513E31i) (list 1e-16+1e-16i -3 -2.500000000000000156766599569740479839725E47-2.500000000000000156766599569740479839725E47i) (list 1e-16+1e-16i 1/2 1.0986841134678e-08+4.5508986056223e-09i) (list 1e-16+1e-16i 1/3 5.032480615484828131577934532998162284517E-6+1.348449116844438970946772378503363059943E-6i) (list 1e-16+1e-16i -1/2 7.768869870150186617914082234866133300043E7-3.217971264527913157308578030636299721171E7i) (list 1e-16+1e-16i -1/3 1.853981710374324177672385518009559821262E5-4.967729020768717648025969623769604859166E4i) (list 1e-16+1e-16i 0.0 1.000E0) (list 1e-16+1e-16i 1.0 9.999999999999999790977867240346035618411E-17+9.999999999999999790977867240346035618411E-17i) (list 1e-16+1e-16i 2.0 0.0+1.999999999999999916391146896138415121169E-32i) (list 1e-16+1e-16i -2.0 0.0-5.00000000000000020902213275965397093513E31i) (list 1e-16+1e-16i 1.000000000000000000000000000000000000002E-309 1.000E0+7.853981633974483096156608458198757210488E-310i) (list 1e-16+1e-16i 1e+16 0.0) (list 1e-16+1e-16i inf.0 0.0) (list 1e-16+1e-16i 0+1i 1.633737074935952277071942452600366041402E-1+4.256625518536474393286932017574035701805E-1i) (list 1e-16+1e-16i 0+2i -1.544976397503562816275493845355474590488E-1+1.390841384750302156856253710476447606724E-1i) (list 1e-16+1e-16i 0-1i 7.859055245423894167511168257029299588438E-1-2.047640077615962126490396474363177248838E0i) (list 1e-16+1e-16i 1+1i -2.622888443600522061390815917770620324788E-17+5.890362593472426547237259268645081580369E-17i) (list 1e-16+1e-16i 1-1i 2.833545602158351484014138796578448096738E-16-1.26173455307357268336623492266154970137E-16i) (list 1e-16+1e-16i -1+1i 2.945181296736213396740244835851862239781E15+1.311444221800261085519581606088360070987E15i) (list 1e-16+1e-16i -1-1i -6.308672765367863680561621873294727149409E15-1.416772801079175801234443901776883778303E16i) (list 1e-16+1e-16i 0.1+0.1i -2.185846675892145203322615268234771243738E-2+1.000746379588156995072970612624735653063E-2i) (list 1e-16+1e-16i 1e+16+1e+16i 0.0) (list 1e-16+1e-16i 1e-16+1e-16i 9.999999999999962719813938977799891729155E-1-3.570938973422717612919117771011138615376E-15i) ))) ;; there's a difference here between gmp/non-gmp: ; (test (expt 0 (real-part (log 0))) (expt 0.0 (real-part (log 0)))) ; (num-test (expt 1.0 (/ (real-part (log 0)) (real-part (log 0)))) (expt 1 (/ (real-part (log 0)) (real-part (log 0))))) ; (num-test (expt 0.0 (/ (real-part (log 0)) (real-part (log 0)))) (expt 0 (/ (real-part (log 0)) (real-part (log 0))))) #| (let ((eps 1e-7)) (do ((i 0 (+ i 1))) ((= i 1000)) (let ((val (- (random 1000.0) 500.0))) (let ((rval (rationalize val)) (ival (floor val))) (let ((frval (exact->inexact rval)) (fival (exact->inexact ival))) (for-each (lambda (e) (if (> (magnitude (- (expt rval e) (expt frval e))) eps) (format-logged #t "~A: ;(expt ~A e) != (expt ~A e) -> ~A~%" e rval frval (magnitude (- (expt rval e) (expt frval e))))) (if (> (magnitude (- (expt ival e) (expt fival e))) eps) (format-logged #t "~A ;(expt ~A e) != (expt ~A e) -> ~A~%" e ival fival (magnitude (- (expt ival e) (expt fival e)))))) (list 0 0.0 (log 0) (real-part (log 0)) (- (real-part (log 0)))))))))) |# ;; table[(1/10^k)/(((1/10^k)^(1/10^k)) - 1), {k, 1, 30}] ;; the test came from calc_errors.txt from the web by "dave" (let ((expts (list -0.48621160938616180680870317336747983548142173621715706851490974881717 -0.22218561601345857583044966876729715619642038672598556073380084629504 -0.14526540294689938889864991134840220307566223888497162784858064408875 -0.10862362815109649171007844591526444220973735508130191198062253212652 -0.08686389647659141105044978528770239308857034812798554177686261943193 -0.07238291365169326382168151357331039782973682143307349669152489742891 -0.06204211884333512141082278643490234288550259196615819050849846987015 -0.05428681523790663196206398113420109019962541643547760927657854324749 -0.04825494293369464924373092184737925979664303236414611590980578553450 -0.04342944824032518278430110099994422226122739720915846151097610557365 -0.03948131654165925705940460838351885560840418164027583205682137097699 -0.03619120682577098563759637916147675090355043511246085981138602579761 -0.03340726783876167905008686486133377017608955166698061593202699553920 -0.03102103442166584483222349447696386196557178259759899539894506586562 -0.02895296546021728851007526126398523685253569082526692705926181546848 -0.02714340511895328922819555743231851877797306680518273360154914602559 -0.02554673422960305368536052464215356633451937057629542604571806752914 -0.02412747121684732425839605105092250802578858425793889081112350331353 -0.02285760431069746466321731152192658331511007129540571803806313398860 -0.02171472409516259138755644594583025411510361447234900258639235440074 -0.02068068961444056322198232947221928963307055360980162368063530687389 -0.01974065826832962852964676904166386737701808793240851850210059107980 -0.01888236877840225337614103995289587314323465286757518193028428290776 -0.01809560341263549281879753828819187842893320857975794377409033233328 -0.01737177927613007310604520675666420329177588023219463316734886061171 -0.01670363391935583952504342495833096470363065406937228989783888395986 -0.01608498081123154917226403453394833638127396317791358170357400676126 -0.01551051721083042241611174715416446722479989306441666312924319204483 -0.01497567178976730440176306617453810628601368985529884710795141610434 -0.01447648273010839425503763063105350274314656686012221887048754923492))) (let ((happy #t)) (do ((i 1 (+ i 1))) ((or (= i (length expts)) (not happy))) (catch #t (lambda () (let ((val (/ (expt .1 i) (- (expt (expt .1 i) (expt .1 i)) 1)))) (if (> (abs (- val (list-ref expts (- i 1)))) 1e-6) (begin (set! happy #f) (if (or with-bignums (< (abs (log (expt .1 i) 2)) 46)) (begin (display "expt error > 1e-6 around 2^") (display (log (expt .1 i) 2)) (newline))))))) (lambda args (display "expt not accurate below around 2^") (display (/ (log (expt .1 i)) (log 2))) (newline)))))) (test (expt) 'error) (test (expt 1) 'error) (test (expt 1.0+23.0i) 'error) (test (expt "hi" "hi") 'error) (test (expt 1.0+23.0i 1.0+23.0i 1.0+23.0i) 'error) (test (expt #t 0) 'error) (test (expt 0 -1) 'error) (test (expt 0 -1/4) 'error) (test (expt 0.0 -1.0) 'error) (test (expt 0.0 -0.1) 'error) (test (expt 0 -1.0) 'error) (test (expt 0 -1.0+i) 'error) (when (not with-bignums) (test (nan? (expt 0 0+0/0i)) #t) (test (nan? (expt 0 0-0/0i)) #t) (test (nan? (expt 0 0/0+i)) #t) (test (nan? (expt 0 nan.0)) #t)) (for-each (lambda (arg) (test (expt arg nan.0) 'error) (test (expt nan.0 arg) 'error) (test (expt arg inf.0) 'error) (test (expt inf.0 arg) 'error) (test (expt arg 2) 'error) (test (expt 2 arg) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) ;;; -------------------------------------------------------------------------------- (let ((f= (lambda (a b) (< (abs (- a b)) 1.0e-15)))) (let ((log2 0.69314718055994530941723212145817656807550013436025525412068000949339362196969471560586332699641868754200148102057068573368552023575813055703267075163507596193072757082837143519030703862389167347112335011536449795523912047517268157493206515552473413952588295045300709532636664265410423915781495204374043038550080194417064167151864471283996817178454695702627163106454615025720740248163777338963855069526066834113727387372292895649354702576265209885969320196505855476470330679365443254763274495125040606943814710468994650622016772042452452961268794654619316517468139267250410380254625965686914419287160829380317271436778265487756648508567407764845146443994046142260319309673540257444607030809608504748663852313818167675143866747664789088143714198549423151997354880375165861275352916610007105355824987941472950929311389715599820565439287170007218085761025236889213244971389320378439353088774825970171559107088236836275898425891853530243634214367061189236789192372314672321720534016492568727477823445353476481149418642386776774406069562657379600867076257199184734022651462837904883062033061144630073719489002743643965002580936519443041191150608094879306786515887090060520346842973619384128965255653968602219412292420757432175748909770675268711581705113700915894266547859596489065305846025866838294002283300538207400567705304678700184162404418833232798386349001563121889560650553151272199398332030751408426091479001265168243443893572472788205486271552741877243002489794540196187233980860831664811490930667519339312890431641370681397776498176974868903887789991296503619270710889264105230924783917373501229842420499568935992206602204654941510613918788574424557751020683703086661948089641218680779020818158858000168811597305618667619918739520076671921459223672060253959543654165531129517598994005600036651356756905124592682574394648316833262490180382424082423145230614096380570070255138770268178516306902551370323405380214501901537402950994226299577964742713815736380172987394070424217997226696297993931270694) (log3 1.09861228866810969139524523692252570464749055782274945173469433363749429321860896687361575481373208878797002906595786574236800422593051982105280187076727741060316276918338136717937369884436095990374257031679591152114559191775067134705494016677558022220317025294689756069010652150564286813803631737329857778236699165479213181814902003010382363012224865274819822599109745249089645805346700884596508574844411901885708764749486707961308582941160216612118400140982551439194876889367984943022557315353296853452952514592138764946859325627944165569415782723103551688661021184698904399430631382552857364668828249881368228006341439107868932514564375102044516275619349739821169415857405353617589009751222337977369696877543547951357129821770175812421223514058101632724655889372495649191852429607966842346470693772372526550820320783339280558928531468730951326064583091843974968222303257654675333118230196492752575991322178513533902374829643395025460742458249346668661218814365265654295427676105054777954229339733234011737431939745798470185595484940594783539438410106029307622922281312074893063445340252777326856271480016818715472439782071878034446780216178158419042820076721243255738014364178876826161041016818724240687908909929874208152183237528942752732534071002835750695062403965462752244308462588450859786253083224774538885068003488324340490083990058080943565282122370388702036804548600776214244088697259413584365999226211739670804950952792714363154640444623089158185367119608370304853520909672629582415040355995121355450332241748474100331981487832452569334704949937301656336660991903957122822844881674312150628569993874038819012744839564791034772885972119850649422796985791669956418551265041502191554719665856929726606523573293736830027830921776605387030462007661584946700226011756797518003934791763277844935142634968360037557857160700498181519184373438290934746660457750659273670121115370582496479847930404205823964753857850960626093389914706120130243108260518262958640076003059494321166880446106134684533980)) (if (not (f= log3 (log 3.0))) (begin (display "(- (log 3.0) true-log-3) = ") (display (- log3 (log 3.0))) (newline))) (if (not (f= log2 (log 2.0))) (begin (display "(- (log 2.0) true-log-2) = ") (display (- log2 (log 2.0))) (newline))) (if (not (f= 3.0 (exp log3))) (begin (display "(- 3.0 (exp log3)) = ") (display (- 3.0 (exp log3))) (newline))) (if (not (f= 2.0 (exp log2))) (begin (display "(- 2.0 (exp log2)) = ") (display (- 2.0 (exp log2))) (newline)))) (let ((sin1 8.414709848078965066525023216302989996225630607983710656727517099919104043912396689486397435430526959e-1) (cos1 5.403023058681397174009366074429766037323104206179222276700972553811003947744717645179518560871830894e-1) (tan1 1.557407724654902230506974807458360173087250772381520038383946605698861397151727289555099965202242984e0)) (if (not (f= sin1 (sin 1))) (begin (display "(- (sin 1) true-sin-1) = ") (display (- sin1 (sin 1))) (newline))) (if (not (f= (asin sin1) 1.0)) (begin (display "(- (asin (sin 1)) 1) = ") (display (- (asin sin1) 1)) (newline))) (if (not (f= cos1 (cos 1))) (begin (display "(- (cos 1) true-cos-1) = ") (display (- cos1 (cos 1))) (newline))) (if (not (f= (acos cos1) 1.0)) (begin (display "(- (acos (cos 1)) 1) = ") (display (- (acos cos1) 1)) (newline))) (if (not (f= tan1 (tan 1))) (begin (display "(- (tan 1) true-tan-1) = ") (display (- tan1 (tan 1))) (newline))) (if (not (f= (atan tan1) 1.0)) (begin (display "(- (atan (tan 1)) 1) = ") (display (- (atan tan1) 1)) (newline))) (set! sin1 -.3056143888882523) (set! cos1 -.9521553682590148) (set! tan1 .3209711346238149) (if (not (f= sin1 (sin 10000))) (begin (display "(- (sin 10000) true-sin-10000) = ") (display (- sin1 (sin 10000))) (newline))) (if (not (f= cos1 (cos 10000))) (begin (display "(- (cos 10000) true-cos-10000) = ") (display (- cos1 (cos 10000))) (newline))) (if (not (f= tan1 (tan 10000))) (begin (display "(- (tan 10000) true-tan-10000) = ") (display (- tan1 (tan 10000))) (newline))) ) (let ((sinh1 1.175201193643801456882381850595600815155717981334095870229565413013307567304323895607117452089623392e0) (cosh1 1.543080634815243778477905620757061682601529112365863704737402214710769063049223698964264726435543036e0) (tanh1 7.615941559557648881194582826047935904127685972579365515968105001219532445766384834589475216736767144e-1)) (if (not (f= sinh1 (sinh 1))) (begin (display "(- (sinh 1) true-sinh-1) = ") (display (- sinh1 (sinh 1))) (newline))) (if (not (f= (asinh sinh1) 1.0)) (begin (display "(- (asinh (sinh 1)) 1) = ") (display (- (asinh sinh1) 1)) (newline))) (if (not (f= cosh1 (cosh 1))) (begin (display "(- (cosh 1) true-cosh-1) = ") (display (- cosh1 (cosh 1))) (newline))) (if (not (f= (acosh cosh1) 1.0)) (begin (display "(- (acosh (cosh 1)) 1) = ") (display (- (acosh cosh1) 1)) (newline))) (if (not (f= tanh1 (tanh 1))) (begin (display "(- (tanh 1) true-tanh-1) = ") (display (- tanh1 (tanh 1))) (newline))) (if (not (f= (atanh tanh1) 1.0)) (begin (display "(- (atanh (tanh 1)) 1) = ") (display (- (atanh tanh1) 1)) (newline))) )) (if with-bignums (begin (let ((old-precision (*s7* 'bignum-precision))) ; these checked against arprec (digits = 512) (set! (*s7* 'bignum-precision) 512) (num-test (sin (bignum "696898287454081973170944403677937368733396.0")) -0.01999904696709900707248379699203543861700131080741493395453090012397) (num-test (cos (bignum "696898287454081973170944403677937368733396.0")) -0.99979999906001588673892554498680272502063995303949755633430660411025) (num-test (tan (bignum "696898287454081973170944403677937368733396.0")) 0.02000304759542063815661565629241173304757896817099118262507840447691) (num-test (log (bignum "696898287454081973170944403677937368733396.0")) 96.34745809783239800899232787971326647885871562509641009125683617504293) (num-test (sqrt (bignum "696898287454081973170944403677937368733396.0")) 8.34804340821298061589146684184612401904558331041225568173326261228620e20) (set! (*s7* 'bignum-precision) old-precision)) ;; these can be checked against arprec -- get tables of the others as well ;; (num-test (sin 31415926535897932384626433832795028841.971693993751058209749445) 6.8290634690588564658126265428876656461078982456442870201741792E-24) ;; this test requires 500 bits of precision (num-test (sin 31415926535897932384626433832795028841) -8.2584214320186030736155068085595298665361290626210864656288000E-1) (num-test (sin 1.0) 0.84147098480789650665250232163029899962256306079837106567275170999191) ; if bignum here ;; (num-test (cos 31415926535897932384626433832795028841.971693993751058209749445) 9.9999999999999999999999999999999999999999999997668194606778265E-1) ;; 500 bits (num-test (cos 1.0) 5.4030230586813971740093660744297660373231042061792222767009714E-1) )) ;;; -------------------------------------------------------------------------------- ;;; * ;;; -------------------------------------------------------------------------------- (num-test (* -0.0) 0.0) (num-test (* -0.0+0.00000001i) -0.0+0.00000001i) (num-test (* -1.0) -1.0) (num-test (* -1.0+1.0i -1.0+1.0i) 0.0-2.0i) (num-test (* -1.0+1.0i 0) 0.0) (num-test (* -1.0+1.0i 0.0) 0.0) (num-test (* -1.0+1.0i 0.0+1.0i) -1.0-1.0i) (num-test (* -1.0+1.0i 1) -1.0+1.0i) (num-test (* -1.0+1.0i 1.0) -1.0+1.0i) (num-test (* -1.0+1.0i 1.0+1.0i) -2.0) (num-test (* -1.0+1.0i 1.234+1.234i) -2.468) (num-test (* -1.0+1.0i 1/1) -1.0+1.0i) (num-test (* -1.0+1.0i 123.4) -123.4+123.4i) (num-test (* -1.0+1.0i 1234) -1234.0+1234.0i) (num-test (* -1.0+1.0i 1234/11) -112.18181818181819+112.18181818181819i) (num-test (* -1.0+1.0i) -1.0+1.0i) (num-test (* -10) -10) (num-test (* -10/3) -10/3) (num-test (* -1234000000) -1234000000) (num-test (* -1234000000.0) -1234000000.0) (num-test (* -1234000000.0+2.71828182845905i) -1234000000.0+2.71828182845905i) (num-test (* -1234000000/10) -1234000000/10) (num-test (* -2) -2) (num-test (* -2.71828182845905) -2.71828182845905) (num-test (* -2.71828182845905+3.14159265358979i) -2.71828182845905+3.14159265358979i) (num-test (* -2/2) -2/2) (num-test (* -362880) -362880) (num-test (* -362880/1234) -362880/1234) (num-test (* 0 -1.0+1.0i) 0.0) (num-test (* 0 0) 0) (num-test (* 0 0.0) 0.0) (num-test (* 0 0.0+1.0i) 0.0) (num-test (* 0 1 -1.0+1.0i) 0.0) (num-test (* 0 1 0) 0) (num-test (* 0 1 0.0) 0.0) (num-test (* 0 1 0.0+1.0i) 0.0) (num-test (* 0 1 1) 0) (num-test (* 0 1 1.0) 0.0) (num-test (* 0 1 1.0+1.0i) 0.0) (num-test (* 0 1 1.234+1.234i) 0.0) (num-test (* 0 1 1/1) 0) (num-test (* 0 1 123.4) 0.0) (num-test (* 0 1 1234) 0) (num-test (* 0 1 1234/11) 0) (num-test (* 0 1) 0) (num-test (* 0 1.0 -1.0+1.0i) 0.0) (num-test (* 0 1.0 0) 0.0) (num-test (* 0 1.0 0.0) 0.0) (num-test (* 0 1.0 0.0+1.0i) 0.0) (num-test (* 0 1.0 1) 0.0) (num-test (* 0 1.0 1.0) 0.0) (num-test (* 0 1.0 1.0+1.0i) 0.0) (num-test (* 0 1.0 1.234+1.234i) 0.0) (num-test (* 0 1.0 1/1) 0.0) (num-test (* 0 1.0 123.4) 0.0) (num-test (* 0 1.0 1234) 0.0) (num-test (* 0 1.0 1234/11) 0.0) (num-test (* 0 1.0) 0.0) (num-test (* 0 1.0+1.0i -1.0+1.0i) 0.0) (num-test (* 0 1.0+1.0i 0) 0.0) (num-test (* 0 1.0+1.0i 0.0) 0.0) (num-test (* 0 1.0+1.0i 0.0+1.0i) 0.0) (num-test (* 0 1.0+1.0i 1) 0.0) (num-test (* 0 1.0+1.0i 1.0) 0.0) (num-test (* 0 1.0+1.0i 1.0+1.0i) 0.0) (num-test (* 0 1.0+1.0i 1.234+1.234i) 0.0) (num-test (* 0 1.0+1.0i 1/1) 0.0) (num-test (* 0 1.0+1.0i 123.4) 0.0) (num-test (* 0 1.0+1.0i 1234) 0.0) (num-test (* 0 1.0+1.0i 1234/11) 0.0) (num-test (* 0 1.0+1.0i) 0.0) (num-test (* 0 1.234+1.234i) 0.0) (num-test (* 0 1/1 -1.0+1.0i) 0.0) (num-test (* 0 123.4) 0.0) (num-test (* 0 1234) 0) (num-test (* 0 1234/11) 0) (num-test (* 0) 0) (num-test (* 0) 0) (num-test (* 0.0 -1.0+1.0i -1.0+1.0i) 0.0) (num-test (* 0.0 -1.0+1.0i 0) 0.0) (num-test (* 0.0 -1.0+1.0i 0.0) 0.0) (num-test (* 0.0 -1.0+1.0i 0.0+1.0i) 0.0) (num-test (* 0.0 -1.0+1.0i 1) 0.0) (num-test (* 0.0 -1.0+1.0i 1.0) 0.0) (num-test (* 0.0 -1.0+1.0i 1.0+1.0i) 0.0) (num-test (* 0.0 -1.0+1.0i 1.234+1.234i) 0.0) (num-test (* 0.0 -1.0+1.0i 1/1) 0.0) (num-test (* 0.0 -1.0+1.0i 123.4) 0.0) (num-test (* 0.0 -1.0+1.0i 1234) 0.0) (num-test (* 0.0 -1.0+1.0i 1234/11) 0.0) (num-test (* 0.0 -1.0+1.0i) 0.0) (num-test (* 0.0 0 -1.0+1.0i) 0.0) (num-test (* 0.0 0 0) 0.0) (num-test (* 0.0 0 0.0) 0.0) (num-test (* 0.0 0 0.0+1.0i) 0.0) (num-test (* 0.0 0 1) 0.0) (num-test (* 0.0 0 1.0) 0.0) (num-test (* 0.0 0 1.0+1.0i) 0.0) (num-test (* 0.0 0 1.234+1.234i) 0.0) (num-test (* 0.0 0 1/1) 0.0) (num-test (* 0.0 0 123.4) 0.0) (num-test (* 0.0 0 1234) 0.0) (num-test (* 0.0 0 1234/11) 0.0) (num-test (* 0.0 0) 0.0) (num-test (* 0.0 0.0 -1.0+1.0i) 0.0) (num-test (* 0.0 0.0 0) 0.0) (num-test (* 0.0 0.0 0.0) 0.0) (num-test (* 0.0 0.0 0.0+1.0i) 0.0) (num-test (* 0.0 0.0 1) 0.0) (num-test (* 0.0 0.0 1.0) 0.0) (num-test (* 0.0 0.0 1.0+1.0i) 0.0) (num-test (* 0.0 0.0 1.234+1.234i) 0.0) (num-test (* 0.0 0.0 1/1) 0.0) (num-test (* 0.0 0.0 123.4) 0.0) (num-test (* 0.0 0.0 1234) 0.0) (num-test (* 0.0 0.0 1234/11) 0.0) (num-test (* 0.0 0.0) 0.0) (num-test (* 0.0 0.0+1.0i -1.0+1.0i) 0.0) (num-test (* 0.0 0.0+1.0i 0) 0.0) (num-test (* 0.0 0.0+1.0i 0.0) 0.0) (num-test (* 0.0 0.0+1.0i 0.0+1.0i) 0.0) (num-test (* 0.0 0.0+1.0i 1) 0.0) (num-test (* 0.0 0.0+1.0i 1.0) 0.0) (num-test (* 0.0 0.0+1.0i 1.0+1.0i) 0.0) (num-test (* 0.0 0.0+1.0i 1.234+1.234i) 0.0) (num-test (* 0.0 0.0+1.0i 1/1) 0.0) (num-test (* 0.0 0.0+1.0i 123.4) 0.0) (num-test (* 0.0 0.0+1.0i 1234) 0.0) (num-test (* 0.0 0.0+1.0i 1234/11) 0.0) (num-test (* 0.0 0.0+1.0i) 0.0) (num-test (* 0.0 1 -1.0+1.0i) 0.0) (num-test (* 0.0 1 0) 0.0) (num-test (* 0.0 1 0.0) 0.0) (num-test (* 0.0 1 0.0+1.0i) 0.0) (num-test (* 0.0 1 1.0) 0.0) (num-test (* 0.0 1 1.0+1.0i) 0.0) (num-test (* 0.0 1 1.234+1.234i) 0.0) (num-test (* 0.0 1 1/1) 0.0) (num-test (* 0.0 1 123.4) 0.0) (num-test (* 0.0 1 1234) 0.0) (num-test (* 0.0 1 1234/11) 0.0) (num-test (* 0.0 1) 0.0) (num-test (* 0.0 1.0 -1.0+1.0i) 0.0) (num-test (* 0.0 1.0 0) 0.0) (num-test (* 0.0 1.0 0.0) 0.0) (num-test (* 0.0 1.0 0.0+1.0i) 0.0) (num-test (* 0.0 1.0 1) 0.0) (num-test (* 0.0 1.0 1.0) 0.0) (num-test (* 0.0 1.0 1.0+1.0i) 0.0) (num-test (* 0.0 1.0 1.234+1.234i) 0.0) (num-test (* 0.0 1.0 1/1) 0.0) (num-test (* 0.0 1.0 123.4) 0.0) (num-test (* 0.0 1.0 1234) 0.0) (num-test (* 0.0 1.0 1234/11) 0.0) (num-test (* 0.0 1.0) 0.0) (num-test (* 0.0 1.0+1.0i -1.0+1.0i) 0.0) (num-test (* 0.0 1.0+1.0i 0) 0.0) (num-test (* 0.0 1.0+1.0i 0.0) 0.0) (num-test (* 0.0 1.0+1.0i 0.0+1.0i) 0.0) (num-test (* 0.0 1.0+1.0i 1) 0.0) (num-test (* 0.0 1.0+1.0i 1.0) 0.0) (num-test (* 0.0 1.0+1.0i 1.0+1.0i) 0.0) (num-test (* 0.0 1.0+1.0i 1.234+1.234i) 0.0) (num-test (* 0.0 1.0+1.0i 1/1) 0.0) (num-test (* 0.0 1.0+1.0i 123.4) 0.0) (num-test (* 0.0 1.0+1.0i 1234) 0.0) (num-test (* 0.0 1.0+1.0i 1234/11) 0.0) (num-test (* 0.0 1.0+1.0i) 0.0) (num-test (* 0.0 1.234+1.234i -1.0+1.0i) 0.0) (num-test (* 0.0 1.234+1.234i 0) 0.0) (num-test (* 0.0 1.234+1.234i 0.0) 0.0) (num-test (* 0.0 1.234+1.234i 0.0+1.0i) 0.0) (num-test (* 0.0 1.234+1.234i 1) 0.0) (num-test (* 0.0 1.234+1.234i 1.0) 0.0) (num-test (* 0.0 1.234+1.234i 1.0+1.0i) 0.0) (num-test (* 0.0 1.234+1.234i 1.234+1.234i) 0.0) (num-test (* 0.0 1.234+1.234i 1/1) 0.0) (num-test (* 0.0 1.234+1.234i 123.4) 0.0) (num-test (* 0.0 1.234+1.234i 1234) 0.0) (num-test (* 0.0 1.234+1.234i 1234/11) 0.0) (num-test (* 0.0 1.234+1.234i) 0.0) (num-test (* 0.0 123.4 -1.0+1.0i) 0.0) (num-test (* 0.0 123.4 0) 0.0) (num-test (* 0.0 123.4 0.0) 0.0) (num-test (* 0.0 123.4 0.0+1.0i) 0.0) (num-test (* 0.0 123.4 1) 0.0) (num-test (* 0.0 123.4 1.0) 0.0) (num-test (* 0.0 123.4 1.0+1.0i) 0.0) (num-test (* 0.0 123.4 1.234+1.234i) 0.0) (num-test (* 0.0 123.4 1/1) 0.0) (num-test (* 0.0 123.4 123.4) 0.0) (num-test (* 0.0 123.4 1234) 0.0) (num-test (* 0.0 123.4 1234/11) 0.0) (num-test (* 0.0 123.4) 0.0) (num-test (* 0.0 1234 -1.0+1.0i) 0.0) (num-test (* 0.0 1234 0) 0.0) (num-test (* 0.0 1234 0.0) 0.0) (num-test (* 0.0 1234 0.0+1.0i) 0.0) (num-test (* 0.0 1234 1) 0.0) (num-test (* 0.0 1234 1.0) 0.0) (num-test (* 0.0 1234 1.0+1.0i) 0.0) (num-test (* 0.0 1234 1.234+1.234i) 0.0) (num-test (* 0.0 1234 1/1) 0.0) (num-test (* 0.0 1234 123.4) 0.0) (num-test (* 0.0 1234 1234) 0.0) (num-test (* 0.0 1234 1234/11) 0.0) (num-test (* 0.0 1234) 0.0) (num-test (* 0.0 1234/11 -1.0+1.0i) 0.0) (num-test (* 0.0 1234/11 0) 0.0) (num-test (* 0.0 1234/11 0.0) 0.0) (num-test (* 0.0 1234/11 0.0+1.0i) 0.0) (num-test (* 0.0 1234/11 1) 0.0) (num-test (* 0.0 1234/11 1.0) 0.0) (num-test (* 0.0 1234/11 1.0+1.0i) 0.0) (num-test (* 0.0 1234/11 1.234+1.234i) 0.0) (num-test (* 0.0 1234/11 1/1) 0.0) (num-test (* 0.0 1234/11 123.4) 0.0) (num-test (* 0.0 1234/11 1234) 0.0) (num-test (* 0.0 1234/11 1234/11) 0.0) (num-test (* 0.0 1234/11) 0.0) (num-test (* 0.0) 0.0) (num-test (* 0.0+0.00000001i) 0.0+0.00000001i) (num-test (* 0.0+1.0i -1.0+1.0i) -1.0-1.0i) (num-test (* 0.0+1.0i 0) 0.0) (num-test (* 0.0+1.0i 0.0) 0.0) (num-test (* 0.0+1.0i 0.0+1.0i) -1.0) (num-test (* 0.0+1.0i 1) 0.0+1.0i) (num-test (* 0.0+1.0i 1.0) 0.0+1.0i) (num-test (* 0.0+1.0i 1.0+1.0i) -1.0+1.0i) (num-test (* 0.0+1.0i 1.234+1.234i) -1.234+1.234i) (num-test (* 0.0+1.0i 1/1) 0.0+1.0i) (num-test (* 0.0+1.0i 123.4) 0.0+123.4i) (num-test (* 0.0+1.0i 1234) 0.0+1234.0i) (num-test (* 0.0+1.0i 1234/11) 0.0+112.18181818181819i) (num-test (* 0/1) 0/1) (num-test (* 0/1) 0/1) (num-test (* 1 -1.0+1.0i) -1.0+1.0i) (num-test (* 1 0) 0) (num-test (* 1 0.0) 0.0) (num-test (* 1 0.0+1.0i) 0.0+1.0i) (num-test (* 1 1 -1.0+1.0i) -1.0+1.0i) (num-test (* 1 1 0) 0) (num-test (* 1 1 0.0) 0.0) (num-test (* 1 1 0.0+1.0i) 0.0+1.0i) (num-test (* 1 1 1) 1) (num-test (* 1 1 1.0) 1.0) (num-test (* 1 1 1.0+1.0i) 1.0+1.0i) (num-test (* 1 1 1.234+1.234i) 1.234+1.234i) (num-test (* 1 1 1/1) 1) (num-test (* 1 1 123.4) 123.4) (num-test (* 1 1 1234) 1234) (num-test (* 1 1 1234/11) 1234/11) (num-test (* 1 1) 1) (num-test (* 1 1.0 -1.0+1.0i) -1.0+1.0i) (num-test (* 1 1.0 0) 0.0) (num-test (* 1 1.0 0.0) 0.0) (num-test (* 1 1.0 0.0+1.0i) 0.0+1.0i) (num-test (* 1 1.0 1) 1.0) (num-test (* 1 1.0 1.0) 1.0) (num-test (* 1 1.0 1.0+1.0i) 1.0+1.0i) (num-test (* 1 1.0 1.234+1.234i) 1.234+1.234i) (num-test (* 1 1.0 1/1) 1.0) (num-test (* 1 1.0 123.4) 123.4) (num-test (* 1 1.0 1234) 1234.0) (num-test (* 1 1.0 1234/11) 112.18181818181819) (num-test (* 1 1.0) 1.0) (num-test (* 1 1.0+1.0i -1.0+1.0i) -2.0) (num-test (* 1 1.0+1.0i 0) 0.0) (num-test (* 1 1.0+1.0i 0.0) 0.0) (num-test (* 1 1.0+1.0i 0.0+1.0i) -1.0+1.0i) (num-test (* 1 1.0+1.0i 1) 1.0+1.0i) (num-test (* 1 1.0+1.0i 1.0) 1.0+1.0i) (num-test (* 1 1.0+1.0i 1.0+1.0i) 0.0+2.0i) (num-test (* 1 1.0+1.0i 1.234+1.234i) 0.0+2.468i) (num-test (* 1 1.0+1.0i 1/1) 1.0+1.0i) (num-test (* 1 1.0+1.0i 123.4) 123.4+123.4i) (num-test (* 1 1.0+1.0i 1234) 1234.0+1234.0i) (num-test (* 1 1.0+1.0i 1234/11) 112.18181818181819+112.18181818181819i) (num-test (* 1 1.0+1.0i) 1.0+1.0i) (num-test (* 1 1.234+1.234i) 1.234+1.234i) (num-test (* 1 123.4) 123.4) (num-test (* 1 1234) 1234) (num-test (* 1 1234/11) 1234/11) (num-test (* 1.0 -1.0+1.0i -1.0+1.0i) 0.0-2.0i) (num-test (* 1.0 -1.0+1.0i 0) 0.0) (num-test (* 1.0 -1.0+1.0i 0.0) 0.0) (num-test (* 1.0 -1.0+1.0i 0.0+1.0i) -1.0-1.0i) (num-test (* 1.0 -1.0+1.0i 1) -1.0+1.0i) (num-test (* 1.0 -1.0+1.0i 1.0) -1.0+1.0i) (num-test (* 1.0 -1.0+1.0i 1.0+1.0i) -2.0) (num-test (* 1.0 -1.0+1.0i 1.234+1.234i) -2.468) (num-test (* 1.0 -1.0+1.0i 1/1) -1.0+1.0i) (num-test (* 1.0 -1.0+1.0i 123.4) -123.4+123.4i) (num-test (* 1.0 -1.0+1.0i 1234) -1234.0+1234.0i) (num-test (* 1.0 -1.0+1.0i 1234/11) -112.18181818181819+112.18181818181819i) (num-test (* 1.0 -1.0+1.0i) -1.0+1.0i) (num-test (* 1.0 0 -1.0+1.0i) 0.0) (num-test (* 1.0 0 0) 0.0) (num-test (* 1.0 0 0.0) 0.0) (num-test (* 1.0 0 0.0+1.0i) 0.0) (num-test (* 1.0 0 1) 0.0) (num-test (* 1.0 0 1.0) 0.0) (num-test (* 1.0 0 1.0+1.0i) 0.0) (num-test (* 1.0 0 1.234+1.234i) 0.0) (num-test (* 1.0 0 1/1) 0.0) (num-test (* 1.0 0 123.4) 0.0) (num-test (* 1.0 0 1234) 0.0) (num-test (* 1.0 0 1234/11) 0.0) (num-test (* 1.0 0) 0.0) (num-test (* 1.0 0.0 -1.0+1.0i) 0.0) (num-test (* 1.0 0.0 0) 0.0) (num-test (* 1.0 0.0 0.0) 0.0) (num-test (* 1.0 0.0 0.0+1.0i) 0.0) (num-test (* 1.0 0.0 1) 0.0) (num-test (* 1.0 0.0 1.0) 0.0) (num-test (* 1.0 0.0 1.0+1.0i) 0.0) (num-test (* 1.0 0.0 1.234+1.234i) 0.0) (num-test (* 1.0 0.0 1/1) 0.0) (num-test (* 1.0 0.0 123.4) 0.0) (num-test (* 1.0 0.0 1234) 0.0) (num-test (* 1.0 0.0 1234/11) 0.0) (num-test (* 1.0 0.0) 0.0) (num-test (* 1.0 0.0+1.0i -1.0+1.0i) -1.0-1.0i) (num-test (* 1.0 0.0+1.0i 0) 0.0) (num-test (* 1.0 0.0+1.0i 0.0) 0.0) (num-test (* 1.0 0.0+1.0i 0.0+1.0i) -1.0) (num-test (* 1.0 0.0+1.0i 1) 0.0+1.0i) (num-test (* 1.0 0.0+1.0i 1.0) 0.0+1.0i) (num-test (* 1.0 0.0+1.0i 1.0+1.0i) -1.0+1.0i) (num-test (* 1.0 0.0+1.0i 1.234+1.234i) -1.234+1.234i) (num-test (* 1.0 0.0+1.0i 1/1) 0.0+1.0i) (num-test (* 1.0 0.0+1.0i 123.4) 0.0+123.4i) (num-test (* 1.0 0.0+1.0i 1234) 0.0+1234.0i) (num-test (* 1.0 0.0+1.0i 1234/11) 0.0+112.18181818181819i) (num-test (* 1.0 0.0+1.0i) 0.0+1.0i) (num-test (* 1.0 1 -1.0+1.0i) -1.0+1.0i) (num-test (* 1.0 1 0) 0.0) (num-test (* 1.0 1 0.0) 0.0) (num-test (* 1.0 1 0.0+1.0i) 0.0+1.0i) (num-test (* 1.0 1 1) 1.0) (num-test (* 1.0 1 1.0) 1.0) (num-test (* 1.0 1 1.0+1.0i) 1.0+1.0i) (num-test (* 1.0 1 1.234+1.234i) 1.234+1.234i) (num-test (* 1.0 1 1/1) 1.0) (num-test (* 1.0 1 123.4) 123.4) (num-test (* 1.0 1 1234) 1234.0) (num-test (* 1.0 1 1234/11) 112.18181818181819) (num-test (* 1.0 1) 1.0) (num-test (* 1.0 1.0 -1.0+1.0i) -1.0+1.0i) (num-test (* 1.0 1.0 0) 0.0) (num-test (* 1.0 1.0 0.0) 0.0) (num-test (* 1.0 1.0 0.0+1.0i) 0.0+1.0i) (num-test (* 1.0 1.0 1) 1.0) (num-test (* 1.0 1.0 1.0) 1.0) (num-test (* 1.0 1.0 1.0+1.0i) 1.0+1.0i) (num-test (* 1.0 1.0 1.234+1.234i) 1.234+1.234i) (num-test (* 1.0 1.0 1/1) 1.0) (num-test (* 1.0 1.0 123.4) 123.4) (num-test (* 1.0 1.0 1234) 1234.0) (num-test (* 1.0 1.0 1234/11) 112.18181818181819) (num-test (* 1.0 1.0) 1.0) (num-test (* 1.0 1.0+1.0i -1.0+1.0i) -2.0) (num-test (* 1.0 1.0+1.0i 0) 0.0) (num-test (* 1.0 1.0+1.0i 0.0) 0.0) (num-test (* 1.0 1.0+1.0i 0.0+1.0i) -1.0+1.0i) (num-test (* 1.0 1.0+1.0i 1) 1.0+1.0i) (num-test (* 1.0 1.0+1.0i 1.0) 1.0+1.0i) (num-test (* 1.0 1.0+1.0i 1.0+1.0i) 0.0+2.0i) (num-test (* 1.0 1.0+1.0i 1.234+1.234i) 0.0+2.468i) (num-test (* 1.0 1.0+1.0i 1/1) 1.0+1.0i) (num-test (* 1.0 1.0+1.0i 123.4) 123.4+123.4i) (num-test (* 1.0 1.0+1.0i 1234) 1234.0+1234.0i) (num-test (* 1.0 1.0+1.0i 1234/11) 112.18181818181819+112.18181818181819i) (num-test (* 1.0 1.0+1.0i) 1.0+1.0i) (num-test (* 1.0 1.234+1.234i -1.0+1.0i) -2.468) (num-test (* 1.0 1.234+1.234i 0) 0.0) (num-test (* 1.0 1.234+1.234i 0.0) 0.0) (num-test (* 1.0 1.234+1.234i 0.0+1.0i) -1.234+1.234i) (num-test (* 1.0 1.234+1.234i 1) 1.234+1.234i) (num-test (* 1.0 1.234+1.234i 1.0) 1.234+1.234i) (num-test (* 1.0 1.234+1.234i 1.0+1.0i) 0.0+2.468i) (num-test (* 1.0 1.234+1.234i 1.234+1.234i) 0.0+3.04551200000000i) (num-test (* 1.0 1.234+1.234i 1/1) 1.234+1.234i) (num-test (* 1.0 1.234+1.234i 123.4) 152.2756+152.2756i) (num-test (* 1.0 1.234+1.234i 1234) 1522.756+1522.756i) (num-test (* 1.0 1.234+1.234i 1234/11) 138.43236363636365+138.43236363636365i) (num-test (* 1.0 1.234+1.234i) 1.234+1.234i) (num-test (* 1.0 1/1 -1.0+1.0i) -1.0+1.0i) (num-test (* 1.0 123.4 -1.0+1.0i) -123.4+123.4i) (num-test (* 1.0 123.4 0) 0.0) (num-test (* 1.0 123.4 0.0) 0.0) (num-test (* 1.0 123.4 0.0+1.0i) 0.0+123.4i) (num-test (* 1.0 123.4 1) 123.4) (num-test (* 1.0 123.4 1.0) 123.4) (num-test (* 1.0 123.4 1.0+1.0i) 123.4+123.4i) (num-test (* 1.0 123.4 1.234+1.234i) 152.2756+152.2756i) (num-test (* 1.0 123.4 1/1) 123.4) (num-test (* 1.0 123.4 123.4) 15227.56000000000131) (num-test (* 1.0 123.4 1234) 152275.60000000000582) (num-test (* 1.0 123.4 1234/11) 13843.23636363636433) (num-test (* 1.0 123.4) 123.4) (num-test (* 1.0 1234 -1.0+1.0i) -1234.0+1234.0i) (num-test (* 1.0 1234 0) 0.0) (num-test (* 1.0 1234 0.0) 0.0) (num-test (* 1.0 1234 0.0+1.0i) 0.0+1234.0i) (num-test (* 1.0 1234 1) 1234.0) (num-test (* 1.0 1234 1.0) 1234.0) (num-test (* 1.0 1234 1.0+1.0i) 1234.0+1234.0i) (num-test (* 1.0 1234 1.234+1.234i) 1522.756+1522.756i) (num-test (* 1.0 1234 1/1) 1234.0) (num-test (* 1.0 1234 123.4) 152275.60000000000582) (num-test (* 1.0 1234 1234) 1522756.0) (num-test (* 1.0 1234 1234/11) 138432.36363636364695) (num-test (* 1.0 1234) 1234.0) (num-test (* 1.0 1234/11 -1.0+1.0i) -112.18181818181819+112.18181818181819i) (num-test (* 1.0 1234/11 0) 0.0) (num-test (* 1.0 1234/11 0.0) 0.0) (num-test (* 1.0 1234/11 0.0+1.0i) 0.0+112.18181818181819i) (num-test (* 1.0 1234/11 1) 112.18181818181819) (num-test (* 1.0 1234/11 1.0) 112.18181818181819) (num-test (* 1.0 1234/11 1.0+1.0i) 112.18181818181819+112.18181818181819i) (num-test (* 1.0 1234/11 1.234+1.234i) 138.43236363636365+138.43236363636365i) (num-test (* 1.0 1234/11 1/1) 112.18181818181819) (num-test (* 1.0 1234/11 123.4) 13843.23636363636433) (num-test (* 1.0 1234/11 1234) 138432.36363636364695) (num-test (* 1.0 1234/11 1234/11) 12584.76033057851237) (num-test (* 1.0 1234/11) 112.18181818181819) (num-test (* 1.0) 1.0) (num-test (* 1.0+1.0i -1.0+1.0i -1.0+1.0i) 2.0-2.0i) (num-test (* 1.0+1.0i -1.0+1.0i 0) 0.0) (num-test (* 1.0+1.0i -1.0+1.0i 0.0) 0.0) (num-test (* 1.0+1.0i -1.0+1.0i 0.0+1.0i) -0.0-2.0i) (num-test (* 1.0+1.0i -1.0+1.0i 1) -2.0) (num-test (* 1.0+1.0i -1.0+1.0i 1.0) -2.0) (num-test (* 1.0+1.0i -1.0+1.0i 1.0+1.0i) -2.0-2.0i) (num-test (* 1.0+1.0i -1.0+1.0i 1.234+1.234i) -2.468-2.468i) (num-test (* 1.0+1.0i -1.0+1.0i 1/1) -2.0) (num-test (* 1.0+1.0i -1.0+1.0i 123.4) -246.8) (num-test (* 1.0+1.0i -1.0+1.0i 1234) -2468.0) (num-test (* 1.0+1.0i -1.0+1.0i 1234/11) -224.36363636363637) (num-test (* 1.0+1.0i -1.0+1.0i) -2.0) (num-test (* 1.0+1.0i 0 -1.0+1.0i) 0.0) (num-test (* 1.0+1.0i 0 0) 0.0) (num-test (* 1.0+1.0i 0 0.0) 0.0) (num-test (* 1.0+1.0i 0 0.0+1.0i) 0.0) (num-test (* 1.0+1.0i 0 1) 0.0) (num-test (* 1.0+1.0i 0 1.0) 0.0) (num-test (* 1.0+1.0i 0 1.0+1.0i) 0.0) (num-test (* 1.0+1.0i 0 1.234+1.234i) 0.0) (num-test (* 1.0+1.0i 0 1/1) 0.0) (num-test (* 1.0+1.0i 0 123.4) 0.0) (num-test (* 1.0+1.0i 0 1234) 0.0) (num-test (* 1.0+1.0i 0 1234/11) 0.0) (num-test (* 1.0+1.0i 0) 0.0) (num-test (* 1.0+1.0i 0.0 -1.0+1.0i) 0.0) (num-test (* 1.0+1.0i 0.0 0) 0.0) (num-test (* 1.0+1.0i 0.0 0.0) 0.0) (num-test (* 1.0+1.0i 0.0 0.0+1.0i) 0.0) (num-test (* 1.0+1.0i 0.0 1) 0.0) (num-test (* 1.0+1.0i 0.0 1.0) 0.0) (num-test (* 1.0+1.0i 0.0 1.0+1.0i) 0.0) (num-test (* 1.0+1.0i 0.0 1.234+1.234i) 0.0) (num-test (* 1.0+1.0i 0.0 1/1) 0.0) (num-test (* 1.0+1.0i 0.0 123.4) 0.0) (num-test (* 1.0+1.0i 0.0 1234) 0.0) (num-test (* 1.0+1.0i 0.0 1234/11) 0.0) (num-test (* 1.0+1.0i 0.0) 0.0) (num-test (* 1.0+1.0i 0.0+1.0i -1.0+1.0i) 0.0-2.0i) (num-test (* 1.0+1.0i 0.0+1.0i 0) 0.0) (num-test (* 1.0+1.0i 0.0+1.0i 0.0) 0.0) (num-test (* 1.0+1.0i 0.0+1.0i 0.0+1.0i) -1.0-1.0i) (num-test (* 1.0+1.0i 0.0+1.0i 1) -1.0+1.0i) (num-test (* 1.0+1.0i 0.0+1.0i 1.0) -1.0+1.0i) (num-test (* 1.0+1.0i 0.0+1.0i 1.0+1.0i) -2.0) (num-test (* 1.0+1.0i 0.0+1.0i 1.234+1.234i) -2.468) (num-test (* 1.0+1.0i 0.0+1.0i 1/1) -1.0+1.0i) (num-test (* 1.0+1.0i 0.0+1.0i 123.4) -123.4+123.4i) (num-test (* 1.0+1.0i 0.0+1.0i 1234) -1234.0+1234.0i) (num-test (* 1.0+1.0i 0.0+1.0i 1234/11) -112.18181818181819+112.18181818181819i) (num-test (* 1.0+1.0i 0.0+1.0i) -1.0+1.0i) (num-test (* 1.0+1.0i 1 -1.0+1.0i) -2.0) (num-test (* 1.0+1.0i 1 0) 0.0) (num-test (* 1.0+1.0i 1 0.0) 0.0) (num-test (* 1.0+1.0i 1 0.0+1.0i) -1.0+1.0i) (num-test (* 1.0+1.0i 1 1) 1.0+1.0i) (num-test (* 1.0+1.0i 1 1.0) 1.0+1.0i) (num-test (* 1.0+1.0i 1 1.0+1.0i) 0.0+2.0i) (num-test (* 1.0+1.0i 1 1.234+1.234i) 0.0+2.468i) (num-test (* 1.0+1.0i 1 1/1) 1.0+1.0i) (num-test (* 1.0+1.0i 1 123.4) 123.4+123.4i) (num-test (* 1.0+1.0i 1 1234) 1234.0+1234.0i) (num-test (* 1.0+1.0i 1 1234/11) 112.18181818181819+112.18181818181819i) (num-test (* 1.0+1.0i 1) 1.0+1.0i) (num-test (* 1.0+1.0i 1.0 -1.0+1.0i) -2.0) (num-test (* 1.0+1.0i 1.0 0) 0.0) (num-test (* 1.0+1.0i 1.0 0.0) 0.0) (num-test (* 1.0+1.0i 1.0 0.0+1.0i) -1.0+1.0i) (num-test (* 1.0+1.0i 1.0 1) 1.0+1.0i) (num-test (* 1.0+1.0i 1.0 1.0) 1.0+1.0i) (num-test (* 1.0+1.0i 1.0 1.0+1.0i) 0.0+2.0i) (num-test (* 1.0+1.0i 1.0 1.234+1.234i) 0.0+2.468i) (num-test (* 1.0+1.0i 1.0 1/1) 1.0+1.0i) (num-test (* 1.0+1.0i 1.0 123.4) 123.4+123.4i) (num-test (* 1.0+1.0i 1.0 1234) 1234.0+1234.0i) (num-test (* 1.0+1.0i 1.0 1234/11) 112.18181818181819+112.18181818181819i) (num-test (* 1.0+1.0i 1.0) 1.0+1.0i) (num-test (* 1.0+1.0i 1.0+1.0i -1.0+1.0i) -2.0-2.0i) (num-test (* 1.0+1.0i 1.0+1.0i 0) 0.0) (num-test (* 1.0+1.0i 1.0+1.0i 0.0) 0.0) (num-test (* 1.0+1.0i 1.0+1.0i 0.0+1.0i) -2.0) (num-test (* 1.0+1.0i 1.0+1.0i 1) 0.0+2.0i) (num-test (* 1.0+1.0i 1.0+1.0i 1.0) 0.0+2.0i) (num-test (* 1.0+1.0i 1.0+1.0i 1.0+1.0i) -2.0+2.0i) (num-test (* 1.0+1.0i 1.0+1.0i 1.234+1.234i) -2.468+2.468i) (num-test (* 1.0+1.0i 1.0+1.0i 1/1) 0.0+2.0i) (num-test (* 1.0+1.0i 1.0+1.0i 123.4) 0.0+246.8i) (num-test (* 1.0+1.0i 1.0+1.0i 1234) 0.0+2468.0i) (num-test (* 1.0+1.0i 1.0+1.0i 1234/11) 0.0+224.36363636363637i) (num-test (* 1.0+1.0i 1.0+1.0i) 0.0+2.0i) (num-test (* 1.0+1.0i 1.234+1.234i -1.0+1.0i) -2.468-2.468i) (num-test (* 1.0+1.0i 1.234+1.234i 0) 0.0) (num-test (* 1.0+1.0i 1.234+1.234i 0.0) 0.0) (num-test (* 1.0+1.0i 1.234+1.234i 0.0+1.0i) -2.468) (num-test (* 1.0+1.0i 1.234+1.234i 1) 0.0+2.468i) (num-test (* 1.0+1.0i 1.234+1.234i 1.0) 0.0+2.468i) (num-test (* 1.0+1.0i 1.234+1.234i 1.0+1.0i) -2.468+2.468i) (num-test (* 1.0+1.0i 1.234+1.234i 1.234+1.234i) -3.04551200000000+3.04551200000000i) (num-test (* 1.0+1.0i 1.234+1.234i 1/1) 0.0+2.468i) (num-test (* 1.0+1.0i 1.234+1.234i 123.4) 0.0+304.55119999999999i) (num-test (* 1.0+1.0i 1.234+1.234i 1234) 0.0+3045.51200000000017i) (num-test (* 1.0+1.0i 1.234+1.234i 1234/11) 0.0+276.86472727272729i) (num-test (* 1.0+1.0i 1.234+1.234i) 0.0+2.468i) (num-test (* 1.0+1.0i 123.4 -1.0+1.0i) -246.8) (num-test (* 1.0+1.0i 123.4 0) 0.0) (num-test (* 1.0+1.0i 123.4 0.0) 0.0) (num-test (* 1.0+1.0i 123.4 0.0+1.0i) -123.4+123.4i) (num-test (* 1.0+1.0i 123.4 1) 123.4+123.4i) (num-test (* 1.0+1.0i 123.4 1.0) 123.4+123.4i) (num-test (* 1.0+1.0i 123.4 1.0+1.0i) 0.0+246.8i) (num-test (* 1.0+1.0i 123.4 1.234+1.234i) 0.0+304.55119999999999i) (num-test (* 1.0+1.0i 123.4 1/1) 123.4+123.4i) (num-test (* 1.0+1.0i 123.4 123.4) 15227.56000000000131+15227.56000000000131i) (num-test (* 1.0+1.0i 123.4 1234) 152275.60000000000582+152275.60000000000582i) (num-test (* 1.0+1.0i 123.4 1234/11) 13843.23636363636433+13843.23636363636433i) (num-test (* 1.0+1.0i 123.4) 123.4+123.4i) (num-test (* 1.0+1.0i 1234 -1.0+1.0i) -2468.0) (num-test (* 1.0+1.0i 1234 0) 0.0) (num-test (* 1.0+1.0i 1234 0.0) 0.0) (num-test (* 1.0+1.0i 1234 0.0+1.0i) -1234.0+1234.0i) (num-test (* 1.0+1.0i 1234 1) 1234.0+1234.0i) (num-test (* 1.0+1.0i 1234 1.0) 1234.0+1234.0i) (num-test (* 1.0+1.0i 1234 1.0+1.0i) 0.0+2468.0i) (num-test (* 1.0+1.0i 1234 1.234+1.234i) 0.0+3045.51200000000017i) (num-test (* 1.0+1.0i 1234 1/1) 1234.0+1234.0i) (num-test (* 1.0+1.0i 1234 123.4) 152275.60000000000582+152275.60000000000582i) (num-test (* 1.0+1.0i 1234 1234) 1522756.0+1522756.0i) (num-test (* 1.0+1.0i 1234 1234/11) 138432.36363636364695+138432.36363636364695i) (num-test (* 1.0+1.0i 1234) 1234.0+1234.0i) (num-test (* 1.0+1.0i 1234/11 -1.0+1.0i) -224.36363636363637) (num-test (* 1.0+1.0i 1234/11 0) 0.0) (num-test (* 1.0+1.0i 1234/11 0.0) 0.0) (num-test (* 1.0+1.0i 1234/11 0.0+1.0i) -112.18181818181819+112.18181818181819i) (num-test (* 1.0+1.0i 1234/11 1) 112.18181818181819+112.18181818181819i) (num-test (* 1.0+1.0i 1234/11 1.0) 112.18181818181819+112.18181818181819i) (num-test (* 1.0+1.0i 1234/11 1.0+1.0i) 0.0+224.36363636363637i) (num-test (* 1.0+1.0i 1234/11 1.234+1.234i) 0.0+276.86472727272729i) (num-test (* 1.0+1.0i 1234/11 1/1) 112.18181818181819+112.18181818181819i) (num-test (* 1.0+1.0i 1234/11 123.4) 13843.23636363636433+13843.23636363636433i) (num-test (* 1.0+1.0i 1234/11 1234) 138432.36363636364695+138432.36363636364695i) (num-test (* 1.0+1.0i 1234/11 1234/11) 12584.76033057851419+12584.76033057851419i) (num-test (* 1.0+1.0i 1234/11) 112.18181818181819+112.18181818181819i) (num-test (* 1.0+1.0i) 1.0+1.0i) (num-test (* 1.234+1.234i -1.0+1.0i) -2.468) (num-test (* 1.234+1.234i 0) 0.0) (num-test (* 1.234+1.234i 0.0) 0.0) (num-test (* 1.234+1.234i 0.0+1.0i) -1.234+1.234i) (num-test (* 1.234+1.234i 1) 1.234+1.234i) (num-test (* 1.234+1.234i 1.0) 1.234+1.234i) (num-test (* 1.234+1.234i 1.0+1.0i) 0.0+2.468i) (num-test (* 1.234+1.234i 1.234+1.234i) 0.0+3.04551200000000i) (num-test (* 1.234+1.234i 1/1) 1.234+1.234i) (num-test (* 1.234+1.234i 123.4) 152.2756+152.2756i) (num-test (* 1.234+1.234i 1234) 1522.756+1522.756i) (num-test (* 1.234+1.234i 1234/11) 138.43236363636365+138.43236363636365i) (num-test (* 10) 10) (num-test (* 10/3) 10/3) (num-test (* 123.4 -1.0+1.0i -1.0+1.0i) 0.0-246.8i) (num-test (* 123.4 -1.0+1.0i 0) 0.0) (num-test (* 123.4 -1.0+1.0i 0.0) 0.0) (num-test (* 123.4 -1.0+1.0i 0.0+1.0i) -123.4-123.4i) (num-test (* 123.4 -1.0+1.0i 1) -123.4+123.4i) (num-test (* 123.4 -1.0+1.0i 1.0) -123.4+123.4i) (num-test (* 123.4 -1.0+1.0i 1.0+1.0i) -246.8) (num-test (* 123.4 -1.0+1.0i 1.234+1.234i) -304.55119999999999) (num-test (* 123.4 -1.0+1.0i 1/1) -123.4+123.4i) (num-test (* 123.4 -1.0+1.0i 123.4) -15227.56000000000131+15227.56000000000131i) (num-test (* 123.4 -1.0+1.0i 1234) -152275.60000000000582+152275.60000000000582i) (num-test (* 123.4 -1.0+1.0i 1234/11) -13843.23636363636433+13843.23636363636433i) (num-test (* 123.4 -1.0+1.0i) -123.4+123.4i) (num-test (* 123.4 0 -1.0+1.0i) 0.0) (num-test (* 123.4 0 0) 0.0) (num-test (* 123.4 0 0.0) 0.0) (num-test (* 123.4 0 0.0+1.0i) 0.0) (num-test (* 123.4 0 1) 0.0) (num-test (* 123.4 0 1.0) 0.0) (num-test (* 123.4 0 1.0+1.0i) 0.0) (num-test (* 123.4 0 1.234+1.234i) 0.0) (num-test (* 123.4 0 1/1) 0.0) (num-test (* 123.4 0 123.4) 0.0) (num-test (* 123.4 0 1234) 0.0) (num-test (* 123.4 0 1234/11) 0.0) (num-test (* 123.4 0) 0.0) (num-test (* 123.4 0.0 -1.0+1.0i) 0.0) (num-test (* 123.4 0.0 0) 0.0) (num-test (* 123.4 0.0 0.0) 0.0) (num-test (* 123.4 0.0 0.0+1.0i) 0.0) (num-test (* 123.4 0.0 1) 0.0) (num-test (* 123.4 0.0 1.0) 0.0) (num-test (* 123.4 0.0 1.0+1.0i) 0.0) (num-test (* 123.4 0.0 1.234+1.234i) 0.0) (num-test (* 123.4 0.0 1/1) 0.0) (num-test (* 123.4 0.0 123.4) 0.0) (num-test (* 123.4 0.0 1234) 0.0) (num-test (* 123.4 0.0 1234/11) 0.0) (num-test (* 123.4 0.0) 0.0) (num-test (* 123.4 0.0+1.0i -1.0+1.0i) -123.4-123.4i) (num-test (* 123.4 0.0+1.0i 0) 0.0) (num-test (* 123.4 0.0+1.0i 0.0) 0.0) (num-test (* 123.4 0.0+1.0i 0.0+1.0i) -123.4) (num-test (* 123.4 0.0+1.0i 1) 0.0+123.4i) (num-test (* 123.4 0.0+1.0i 1.0) 0.0+123.4i) (num-test (* 123.4 0.0+1.0i 1.0+1.0i) -123.4+123.4i) (num-test (* 123.4 0.0+1.0i 1.234+1.234i) -152.2756+152.2756i) (num-test (* 123.4 0.0+1.0i 1/1) 0.0+123.4i) (num-test (* 123.4 0.0+1.0i 123.4) 0.0+15227.56000000000131i) (num-test (* 123.4 0.0+1.0i 1234) 0.0+152275.60000000000582i) (num-test (* 123.4 0.0+1.0i 1234/11) 0.0+13843.23636363636433i) (num-test (* 123.4 0.0+1.0i) 0.0+123.4i) (num-test (* 123.4 1 -1.0+1.0i) -123.4+123.4i) (num-test (* 123.4 1 0) 0.0) (num-test (* 123.4 1 0.0) 0.0) (num-test (* 123.4 1 0.0+1.0i) 0.0+123.4i) (num-test (* 123.4 1 1) 123.4) (num-test (* 123.4 1 1.0) 123.4) (num-test (* 123.4 1 1.0+1.0i) 123.4+123.4i) (num-test (* 123.4 1 1.234+1.234i) 152.2756+152.2756i) (num-test (* 123.4 1 1/1) 123.4) (num-test (* 123.4 1 123.4) 15227.56000000000131) (num-test (* 123.4 1 1234) 152275.60000000000582) (num-test (* 123.4 1 1234/11) 13843.23636363636433) (num-test (* 123.4 1) 123.4) (num-test (* 123.4 1.0 -1.0+1.0i) -123.4+123.4i) (num-test (* 123.4 1.0 0) 0.0) (num-test (* 123.4 1.0 0.0) 0.0) (num-test (* 123.4 1.0 0.0+1.0i) 0.0+123.4i) (num-test (* 123.4 1.0 1) 123.4) (num-test (* 123.4 1.0 1.0) 123.4) (num-test (* 123.4 1.0 1.0+1.0i) 123.4+123.4i) (num-test (* 123.4 1.0 1.234+1.234i) 152.2756+152.2756i) (num-test (* 123.4 1.0 1/1) 123.4) (num-test (* 123.4 1.0 123.4) 15227.56000000000131) (num-test (* 123.4 1.0 1234) 152275.60000000000582) (num-test (* 123.4 1.0 1234/11) 13843.23636363636433) (num-test (* 123.4 1.0) 123.4) (num-test (* 123.4 1.0+1.0i -1.0+1.0i) -246.8) (num-test (* 123.4 1.0+1.0i 0) 0.0) (num-test (* 123.4 1.0+1.0i 0.0) 0.0) (num-test (* 123.4 1.0+1.0i 0.0+1.0i) -123.4+123.4i) (num-test (* 123.4 1.0+1.0i 1) 123.4+123.4i) (num-test (* 123.4 1.0+1.0i 1.0) 123.4+123.4i) (num-test (* 123.4 1.0+1.0i 1.0+1.0i) 0.0+246.8i) (num-test (* 123.4 1.0+1.0i 1.234+1.234i) 0.0+304.55119999999999i) (num-test (* 123.4 1.0+1.0i 1/1) 123.4+123.4i) (num-test (* 123.4 1.0+1.0i 123.4) 15227.56000000000131+15227.56000000000131i) (num-test (* 123.4 1.0+1.0i 1234) 152275.60000000000582+152275.60000000000582i) (num-test (* 123.4 1.0+1.0i 1234/11) 13843.23636363636433+13843.23636363636433i) (num-test (* 123.4 1.0+1.0i) 123.4+123.4i) (num-test (* 123.4 1.234+1.234i -1.0+1.0i) -304.55119999999999) (num-test (* 123.4 1.234+1.234i 0) 0.0) (num-test (* 123.4 1.234+1.234i 0.0) 0.0) (num-test (* 123.4 1.234+1.234i 0.0+1.0i) -152.2756+152.2756i) (num-test (* 123.4 1.234+1.234i 1) 152.2756+152.2756i) (num-test (* 123.4 1.234+1.234i 1.0) 152.2756+152.2756i) (num-test (* 123.4 1.234+1.234i 1.0+1.0i) 0.0+304.55119999999999i) (num-test (* 123.4 1.234+1.234i 1.234+1.234i) 0.0+375.81618079999998i) (num-test (* 123.4 1.234+1.234i 1/1) 152.2756+152.2756i) (num-test (* 123.4 1.234+1.234i 123.4) 18790.80904000000010+18790.80904000000010i) (num-test (* 123.4 1.234+1.234i 1234) 187908.09039999998640+187908.09039999998640i) (num-test (* 123.4 1.234+1.234i 1234/11) 17082.55367272727381+17082.55367272727381i) (num-test (* 123.4 1.234+1.234i) 152.2756+152.2756i) (num-test (* 123.4 1/1 -1.0+1.0i) -123.4+123.4i) (num-test (* 123.4 123.4 -1.0+1.0i) -15227.56000000000131+15227.56000000000131i) (num-test (* 123.4 123.4 0) 0.0) (num-test (* 123.4 123.4 0.0) 0.0) (num-test (* 123.4 123.4 0.0+1.0i) 0.0+15227.56000000000131i) (num-test (* 123.4 123.4 1) 15227.56000000000131) (num-test (* 123.4 123.4 1.0) 15227.56000000000131) (num-test (* 123.4 123.4 1.0+1.0i) 15227.56000000000131+15227.56000000000131i) (num-test (* 123.4 123.4 1.234+1.234i) 18790.80904000000010+18790.80904000000010i) (num-test (* 123.4 123.4 1/1) 15227.56000000000131) (num-test (* 123.4 123.4 123.4) 1879080.90400000032969) (num-test (* 123.4 123.4 1234) 18790809.04000000283122) (num-test (* 123.4 123.4 1234/11) 1708255.36727272742428) (num-test (* 123.4 123.4) 15227.56000000000131) (num-test (* 123.4 1234 -1.0+1.0i) -152275.60000000000582+152275.60000000000582i) (num-test (* 123.4 1234 0) 0.0) (num-test (* 123.4 1234 0.0) 0.0) (num-test (* 123.4 1234 0.0+1.0i) 0.0+152275.60000000000582i) (num-test (* 123.4 1234 1) 152275.60000000000582) (num-test (* 123.4 1234 1.0) 152275.60000000000582) (num-test (* 123.4 1234 1.0+1.0i) 152275.60000000000582+152275.60000000000582i) (num-test (* 123.4 1234 1.234+1.234i) 187908.09040000001551+187908.09040000001551i) (num-test (* 123.4 1234 1/1) 152275.60000000000582) (num-test (* 123.4 1234 123.4) 18790809.04000000283122) (num-test (* 123.4 1234 1234) 187908090.40000000596046) (num-test (* 123.4 1234 1234/11) 17082553.67272727191448) (num-test (* 123.4 1234) 152275.60000000000582) (num-test (* 123.4 1234/11 -1.0+1.0i) -13843.23636363636433+13843.23636363636433i) (num-test (* 123.4 1234/11 0) 0.0) (num-test (* 123.4 1234/11 0.0) 0.0) (num-test (* 123.4 1234/11 0.0+1.0i) 0.0+13843.23636363636433i) (num-test (* 123.4 1234/11 1) 13843.23636363636433) (num-test (* 123.4 1234/11 1.0) 13843.23636363636433) (num-test (* 123.4 1234/11 1.0+1.0i) 13843.23636363636433+13843.23636363636433i) (num-test (* 123.4 1234/11 1.234+1.234i) 17082.55367272727381+17082.55367272727381i) (num-test (* 123.4 1234/11 1/1) 13843.23636363636433) (num-test (* 123.4 1234/11 123.4) 1708255.36727272742428) (num-test (* 123.4 1234/11 1234) 17082553.67272727191448) (num-test (* 123.4 1234/11 1234/11) 1552959.42479338846169) (num-test (* 123.4 1234/11) 13843.23636363636433) (num-test (* 1234 -1.0+1.0i) -1234.0+1234.0i) (num-test (* 1234 0) 0) (num-test (* 1234 0.0) 0.0) (num-test (* 1234 0.0+1.0i) 0.0+1234.0i) (num-test (* 1234 1) 1234) (num-test (* 1234 1.0) 1234.0) (num-test (* 1234 1.0+1.0i) 1234.0+1234.0i) (num-test (* 1234 1.234+1.234i) 1522.756+1522.756i) (num-test (* 1234 1/1) 1234) (num-test (* 1234 123.4) 152275.60000000000582) (num-test (* 1234 1234) 1522756) (num-test (* 1234 1234/11) 1522756/11) (num-test (* 1234/11 -1.0+1.0i) -112.18181818181819+112.18181818181819i) (num-test (* 1234/11 0) 0) (num-test (* 1234/11 0.0) 0.0) (num-test (* 1234/11 0.0+1.0i) 0.0+112.18181818181819i) (num-test (* 1234/11 1) 1234/11) (num-test (* 1234/11 1.0) 112.18181818181819) (num-test (* 1234/11 1.0+1.0i) 112.18181818181819+112.18181818181819i) (num-test (* 1234/11 1.234+1.234i) 138.43236363636365+138.43236363636365i) (num-test (* 1234/11 1/1) 1234/11) (num-test (* 1234/11 123.4) 13843.23636363636433) (num-test (* 1234/11 1234) 1522756/11) (num-test (* 1234/11 1234/11) 1522756/121) (num-test (* 1234000000) 1234000000) (num-test (* 1234000000.0) 1234000000.0) (num-test (* 1234000000.0+2.71828182845905i) 1234000000.0+2.71828182845905i) (num-test (* 1234000000/10) 1234000000/10) (num-test (* 2) 2) (num-test (* 2.71828182845905) 2.71828182845905) (num-test (* 2.71828182845905+3.14159265358979i) 2.71828182845905+3.14159265358979i) (num-test (* 2/2) 2/2) (num-test (* 362880) 362880) (num-test (* 362880/1234) 362880/1234) (num-test (let ((x 1) (y 2)) (set! x (* 0 (let () (set! y 32) 1))) y) 32) (num-test (* 4) 4 ) (num-test (* 7 6 5 4 3 2 1) 5040) (num-test (*) 1 ) (num-test (* (+ 1 3 5) (* 1 3 5)) 135) (num-test (* -1/2147483648 1/4294967296) -1/9223372036854775808) (num-test (* -2147483648 4294967296) -9223372036854775808) (num-test (* .000000000000123 .000000000000123) 1.5129e-26) (num-test (* 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20) 2432902008176640000) (num-test (* 1/98947 2/97499 3/76847) 6/741360956847391) (num-test (* 11/1234 1234/11 11/1234 1234/11 11/1234 1234/11) 1) (num-test (* 12 (/ 13591409 (expt 640320 3/2))) (/ pi)) (num-test (* 1e100 0.001) 1e97) (num-test (* 1e100 1e-100) 1.0) (num-test (* 1e200 1e-200) 1.0) (num-test (* 1e300 1e-300) 1.0) (num-test (* 500009/500029 500057/500041) 250033000513/250035001189) (num-test (* -9223372036854775808 5.551115123125783999999999999999999999984E-17) -5.120000000000001197084708550423347199985E2) (num-test (* -9223372036854775808) -9223372036854775808) (num-test (* 1.110223024625156799999999999999999999997E-16 -9223372036854775808) -1.024000000000000239416941710084669439997E3) (num-test (* 1.110223024625156799999999999999999999997E-16 5.551115123125783999999999999999999999984E-17 5.42101086242752217060000000000000000001E-20) 3.340955887615246120290922872835723707327E-52) (num-test (* 5.551115123125783999999999999999999999984E-17 1.110223024625156799999999999999999999997E-16) 6.162975822039157611655737122931199999952E-33) (num-test (* 9223372036854775807 (/ 9223372036854775807)) 1) (num-test (* 1234567890e24 1e-33) 1.23456789) (num-test (* 1234567890e-24 1e20) 123456.789) (num-test (* 92233720/9221 -92233720/9221 9221/92233720 -9221/92233720) 1) (num-test (* 9221/92233720 -9221/92233720 92233720/9221 -92233720/9221) 1) (for-each-permutation (lambda args (if (not (< (magnitude (- (apply * args) 0.25+0.25i)) 1e-15)) (format-logged #t "~A: (* ~{~A~^ ~}) -> ~A?~%" (port-line-number) args (apply * args)))) '(1 1/2 0.5 1+i)) (for-each-permutation (lambda args (if (not (< (magnitude (- (apply * args) 1.0)) 1e-15)) (format-logged #t "~A: (* ~{~A~^ ~}) -> ~A?~%" (port-line-number) args (apply * args)))) '(5 1/3 0.5 1+i 1/5 3 2.0 0.5-0.5i)) (num-test (* 7/1000 1000/999 999/7 most-positive-fixnum) most-positive-fixnum) (num-test (* 7/1000000 1/999 999/7 (- most-positive-fixnum 775807)) 9223372036854) (num-test (* 7/100000000000 1/999 999/7 (- most-positive-fixnum 36854775807)) 92233720) (num-test (* -0.2554913394465045E0 0.27042187315261135E0) -6.909044658739340841916780452607499999997E-2) (num-test (* -0.4489211233229662E0 -0.42892136850270857E0) 1.925518625654598642702435865603340000003E-1) (num-test (* -0.44586465919973783E0 -0.15168042462027043E0) 6.762894083058839862686475970136690000031E-2) (num-test (* 0.5509395670465355E0 0.3577558280766836E0) 1.971018410289428517174637096677999999998E-1) (num-test (* -0.42780066410606965E0 0.22704747885906007E0) -9.713106223951470697784938095387549999991E-2) (num-test (* 0.20955388816500042E0 0.605628751935113E0) 1.269118597525194529275610775776050864747E-1) (num-test (* 0.9993471610818964E0 -4.363771855901198E9) -4.360923015803940523218504871887199999987E9) (num-test (* 0.10502219375257282E0 3.425205053451057E9) 3.597225487658284459716764716837978363041E8) (num-test (* 0.7768651149081368E0 1.666066330143864E9) 1.294308811011790623456907580692100524906E9) (num-test (* -0.6438389801759042E0 2.8922130868526487E9) -1.862119524290613178578671687454540000003E9) (num-test (* -0.7427680566504474E0 6.763974500466173E9) -5.024064194944440168218138681386184692391E9) (num-test (* -0.8563035843259611E0 2.9100478627456827E9) -2.491884415429230578930028553142970000007E9) (num-test (* 0.6219502737119671E0 2.8868752190811842E-11) 1.795492832679837500144381979439820000005E-11) (num-test (* 0.6767479505813657E0 2.9324524289075574E-11) 1.98453117144053746900587234314118E-11) (num-test (* 0.7944531541461581E0 8.282076647859848E-11) 6.579721915772496180466156449968800000014E-11) (num-test (* -0.4662914070981966E0 -6.921260263903422E-11) 3.22732418734836218212517276876520000001E-11) (num-test (* 0.037804762510578516E0 -3.044514833184461E-11) -1.150971602284721156705916516398760000005E-12) (num-test (* -0.5364168049485208E0 -3.695280705974925E-11) 1.982210669686983584095600640940000000003E-11) (num-test (* 0.10343751426551051E0 4.8902635121181385E19) 5.058367017968254798845671333856350000002E18) (num-test (* -0.45511004829813784E0 1.8210069906740634E19) -8.287585794769196371535086060990559999988E18) (num-test (* -0.9675158737162977E0 8.097401718869682E19) -7.834364698864051180664785816331399999997E19) (num-test (* -0.06573561186185628E0 2.6049125586869125E19) -1.712355208919177984462215919354999999997E18) (num-test (* -0.5574365795036731E0 -8.822383181882661E19) 4.917919103979402413863422702119099999985E19) (num-test (* -0.4222667103024276E0 -1.8561723355961213E19) 7.837997859065477747526525340678799999995E18) (num-test (* -0.8412207478192143E0 2.3416069046402696E-22) -1.969808311420123220453436412175280000003E-22) (num-test (* 0.24291385591230452E0 -9.448120185342916E-21) -2.295079305344524973092760016780319999996E-21) (num-test (* -0.37792600430678414E0 -2.3929024368177364E-21) 9.043400566424941101603791982206959999978E-22) (num-test (* -0.007648867433060369E0 -5.3162210182098465E-21) 4.066306981313632980042734472335849999998E-23) (num-test (* -0.7631807323096114E0 -4.534410248041209E-21) 3.460574533692296555855373976182600000004E-21) (num-test (* 0.4735366300649959E0 -1.3895270471326203E-21) -6.579919552833457409343160757567699999986E-22) (num-test (* -8.64834403600587E9 -0.14057280586223464E0) 1.215721987203268063989050502795104980466E9) (num-test (* -1.5525713051163936E9 0.10621224657238759E0) -1.649020862802360033147528021954240000002E8) (num-test (* 3.297132746298694E9 0.05318660311813239E0) 1.753632908051865357781730185173082351681E8) (num-test (* 2.1659831568875275E9 0.11704159596099262E0) 2.535101255067452830195785975470499999995E8) (num-test (* -5.533403510176525E9 0.37778599060251605E0) -2.090442326495477997892444645726250000003E9) (num-test (* -2.4217306331294374E9 0.6051350227557695E0) -1.465474021787126179631541139079300000002E9) (num-test (* 1.4048311850866513E9 -4.304799039580996E9) -6.047515936334448947178704758694799999987E18) (num-test (* -5.070278162013437E9 -9.116233758795675E9) 4.622184094703138120556628748497500000004E19) (num-test (* 8.452801605894673E9 -9.002885976919611E9) -7.609960904339272295066535438875484466566E19) (num-test (* 6.352601599408395E9 -4.484034289922495E9) -2.84852834019637276707985964548254013062E19) (num-test (* -6.565407710101401E8 -6.718825369609182E9) 4.411182788445701880089696066398200000001E18) (num-test (* -9.37193973536698E9 9.577576231327314E9) -8.976046725088278448381480077370724757202E19) (num-test (* -1.7766859308675253E9 -4.079350537765101E-11) 7.247724707524128390808760574555300000015E-2) (num-test (* 2.3810136983742104E9 9.195156930614704E-11) 2.189379461049416913728349262972160000005E-1) (num-test (* -3.313966320976337E9 -3.44704749912067E-11) 1.142339931889161000998337758579000000001E-1) (num-test (* 6.598963960681895E9 -2.4298605961767928E-11) -1.6034562503651679888964996364737701416E-1) (num-test (* 7.908258993705348E9 1.528909719631646E-11) 1.209101404084048656249131044486427307128E-1) (num-test (* -5.906667889594469E9 5.917852809041966E-11) -3.4954791162514609467168142486054E-1) (num-test (* 4.86261281419926E9 -2.3925611132123714E19) -1.1634098327861323021375513143190574646E29) (num-test (* -9.753392818607462E9 -2.5653634777279775E18) 2.502099772078991953507318766810499999998E28) (num-test (* 1.5861252889272392E9 5.12939252547053E19) 8.135859201483165467280698143134187520016E28) (num-test (* -8.422142961023593E8 1.0428099441045047E19) -8.782694430425160722507674279387100000022E27) (num-test (* -3.109042783121446E9 -4.138252722536039E19) 1.286600476173334775049764879239400000004E29) (num-test (* -6.459303282089468E8 1.8408981660472957E19) -1.18909195659417795593544068516876E28) (num-test (* -1.432764110232635E9 8.98766033001457E-21) -1.287719715580647603395563949195000000001E-11) (num-test (* 8.539623949953406E9 -3.498784805440049E-21) -2.987830652026891151867478398400020599353E-11) (num-test (* 7.336784327799637E9 -1.048985206018761E-21) -7.696178219612118988966933703567504882842E-12) (num-test (* -4.320357143553698E9 2.591531476439043E-21) -1.119634152697768142457549423101400000004E-11) (num-test (* -9.374098076239548E9 5.5773248420603045E-21) -5.2282390072520541300690003822366E-11) (num-test (* 9.118926580475056E9 -1.379170270330765E-21) -1.257655243712018104094987568109512329098E-11) (num-test (* 8.145792307872788E-11 -0.06511382435429458E0) -5.304036895613925967063321178890399999982E-12) (num-test (* -6.1928426627437E-11 0.2526275616632321E0) -1.564482741652978543296795912770000000003E-11) (num-test (* -8.555119338859813E-11 -0.8366318482083728E0) 7.157485304113477734096792042286400000002E-11) (num-test (* 8.243060442429263E-12 0.3939656708074719E0) 3.247482836708180702664407610209699999993E-12) (num-test (* 8.600529286105945E-11 -0.891441509265547E0) -7.666868807288821095008580376914999999987E-11) (num-test (* -7.531046724969747E-11 0.24398797995196886E0) -1.837484877349259372047496586078419999997E-11) (num-test (* -3.7666526619188126E-12 4.659322150343885E9) -1.755004818033008198811983615043067932129E-2) (num-test (* 3.032501107241211E-11 -9.592046453776636E9) -2.908789149178678011789796814619600000006E-1) (num-test (* 7.311626957349528E-11 -9.061108567148174E9) -6.625144566303134478698468496187199999991E-1) (num-test (* 4.898078204161461E-11 8.88014689134599E9) 4.34956539382539434542556734824485778809E-1) (num-test (* 1.278207138618518E-11 -4.279966992086118E9) -5.470684362336102162321405533123999999992E-2) (num-test (* -8.538580654966055E-11 -5.191059833953482E8) 4.432428307696650304902715905351E-2) (num-test (* 4.0761422500127225E-11 1.527607426117321E-11) 6.226745171030000570391027616422499999987E-22) (num-test (* -9.186363051001198E-11 8.557763803549676E-11) -7.861472520412421845045812851184799999979E-21) (num-test (* -9.89183505930065E-11 9.717968160611499E-11) -9.61285381563042758142312881743500000002E-21) (num-test (* 7.440627873114725E-12 -4.535521332601712E-11) -3.374712644646273959960130740919999999997E-22) (num-test (* 8.701410920357686E-11 -7.032883383151379E-12) -6.119600827175551716944456414899399999975E-22) (num-test (* 9.866226673114161E-11 -2.814669610817353E-11) -2.777016839025002299729708883583300000003E-21) (num-test (* 5.192240545105114E-11 -3.366056660574579E19) -1.747737587015645175992519129700599999996E9) (num-test (* -1.372355669576939E-11 -4.819955130360066E19) 6.614692750256090679268960117974000000002E8) (num-test (* 3.637511103766519E-11 -4.071776382810416E19) -1.481113180452716050522430526190399999997E9) (num-test (* 7.446388208685151E-13 2.7760294268649034E19) 2.06713927911698144246650226294134E7) (num-test (* 6.267855179410938E-11 7.471751480940298E19) 4.683185621908299321917798617952399999997E9) (num-test (* -4.336562006766369E-11 8.143188451558233E19) -3.531344165296609191472762946597699999996E9) (num-test (* -1.0432655006975122E-11 -9.379512413340694E-21) 9.785321714202410134613576821466799999983E-32) (num-test (* -8.167646898574611E-11 -5.810795749825724E-21) 4.746052788431460582580726109336400000004E-31) (num-test (* -4.33805459341994E-11 -2.4289860591796017E-21) 1.053707413137706937228749003789799999998E-31) (num-test (* -1.384613082275421E-11 2.2174009100764947E-21) -3.070242308741338958377843646768700000007E-32) (num-test (* -4.910905591314494E-11 -5.456657623752349E-21) 2.679713043437427118620763024640600000007E-31) (num-test (* 1.3653011366548008E-11 -3.925911962906968E-21) -5.3600520653635635667567009719744E-32) (num-test (* 7.641468950470222E19 0.9034599537348024E0) 6.903761184457755820350566254132800000009E19) (num-test (* 5.146778093125584E19 -0.2791459460022878E0) -1.436702239669392041403916711075200000002E19) (num-test (* -8.874303077863696E19 -0.23153988023519345E0) 2.054755071819368785424861291991199999996E19) (num-test (* 7.10798162637783E19 -0.4719034863212067E0) -3.354281310194779040746230255943679999999E19) (num-test (* -9.820386602197546E19 0.03346146041258036E0) -3.286044775256677372510003197965599999991E18) (num-test (* -5.210458089116161E19 0.11173798093222442E0) -5.822060666098160855554015008516199999997E18) (num-test (* 3.257626718953688E18 -6.150510855712356E9) -2.003606849878328222529021336892800000007E28) (num-test (* -7.755105754004988E19 5.514896832715505E9) -4.276860816013589383294629509647750854492E29) (num-test (* 2.426235084788384E19 8.685431434428486E9) 2.10728984727342930836693974581298828125E29) (num-test (* -2.847383850475709E19 -2.412830829567453E9) 6.870255538040273498936753499177000000002E28) (num-test (* 1.4664659669727164E19 -4.8673539253155E9) -7.137808880686241930432174599520111083984E28) (num-test (* -4.24770317054668E19 1.3102543269150825E9) -5.5655714586597020914994623011E28) (num-test (* 2.17116835964837E19 -3.654789326884115E-11) -7.935162947711353824080778955354111999976E8) (num-test (* -1.8125809977916906E17 -5.944782899600832E-11) 1.077540051981345570924422644657920000001E7) (num-test (* -7.915462827540546E19 9.762153025588201E-11) -7.727195939080587759467382669774600000011E9) (num-test (* -4.360953588949649E19 -7.152431005584812E-11) 3.119141966351983288172806713098800000002E9) (num-test (* 3.550776271395866E19 -6.387656982922894E-11) -2.268114084477872045705002835620399999998E9) (num-test (* -8.278954580496595E19 -7.359178231519021E-11) 6.09263023285252303789473682334949999999E9) (num-test (* -5.5022682113038156E19 -8.979630229039327E19) 4.94083339585058897667477175561012E39) (num-test (* 1.1716230943203277E19 5.5764415854118265E19) 6.53348774559675813536051493554405E38) (num-test (* 7.462799608352103E19 6.061883497941003E19) 4.5238621794310193360802344979309E39) (num-test (* -3.2160334983646097E19 -3.8817785710003675E19) 1.248392991757108737054938769406475E39) (num-test (* 5.868090263060238E19 -8.37300331667736E19) -4.913353923516549470233569081168E39) (num-test (* -7.3652924769962656E19 9.725738480757314E19) -7.16329084655549342691442378865984E39) (num-test (* -6.447063647969567E19 4.0587529685661844E-21) -2.616703871973161409821231651015480000002E-1) (num-test (* -3.1999317568381926E17 3.015031281949113E-21) -9.647894346969533174030688093163799999993E-4) (num-test (* -1.5005852398726605E19 5.391316601974659E-21) -8.090130116403600588996007910269500000005E-2) (num-test (* 1.0084552719733576E19 2.78150956101201E-21) 2.805027980846861049488413624776000000002E-2) (num-test (* -7.171404412051077E19 1.4733392992015492E-21) -1.056591195074223176150038792848839999998E-1) (num-test (* -5.909802783283228E19 5.356071274587122E-21) -3.165332492601832012651928738981599999998E-1) (num-test (* 8.272641144282955E-22 -0.16191056182923802E0) -1.339427975482523749443486923949099999995E-22) (num-test (* 8.410471541398583E-21 -0.43256058128353736E0) -3.638038458816019512260007931560879999991E-21) (num-test (* -7.887238384137063E-22 0.5589746137044918E0) -4.408766028968254895651429959583400000002E-22) (num-test (* 4.778995446616728E-21 0.21608373898977795E0) 1.0326632047200663557809034755476E-21) (num-test (* 3.992449163872154E-21 0.9593422165456676E0) 3.830125030315009512425388980010399999991E-21) (num-test (* -9.700320218813958E-21 -0.42620535269852766E0) 4.134328400148261975602018057078279999983E-21) (num-test (* -1.7901566262876555E-21 9.461674014776534E8) -1.693787843332593653628245958251059055323E-12) (num-test (* 1.0928019952544443E-22 8.279199780524873E9) 9.047526039267738313652918648958873748777E-13) (num-test (* 9.942869097320962E-21 9.523169242022762E9) 9.46876251650656124754254949341964721678E-11) (num-test (* -2.7432601692209267E-21 -4.922145522647528E9) 1.350272575938808435595052562419760000003E-11) (num-test (* -5.97929682563092E-21 -6.147792689359443E8) 3.675947731212389417723913477756000000004E-12) (num-test (* -1.3564305221188254E-21 1.0862842413758955E9) -1.4734691006989580907776383331457E-12) (num-test (* -5.446806293721964E-21 -1.5358504316888942E-11) 8.365479797538664267835041412208799999977E-32) (num-test (* -1.0222776562632463E-21 -1.9781477525280056E-11) 2.022216248196737715829186720579279999999E-32) (num-test (* 8.192540157543917E-21 3.3215076993103644E-11) 2.721158521019146605658900627335480000005E-31) (num-test (* 9.685592607330157E-21 6.034805605641166E-11) 5.845066856067266821880143244306199999988E-31) (num-test (* 6.671870463340688E-21 -9.07657686679269E-11) -6.055774510579551477490933797071999999989E-31) (num-test (* -1.109409648670322E-21 -4.7905821901849965E-11) 5.314718104539438656835419223873000000025E-32) (num-test (* -3.9052432481663676E-22 2.0306112771345453E19) -7.930030979680167745084943578652280000005E-3) (num-test (* 8.596834841113507E-21 -9.453548987989818E19) -8.127059931212420192062869827172600000005E-1) (num-test (* 3.946325780779758E-21 -9.084484011754447E19) -3.585033346066809630978128408382600000004E-1) (num-test (* 5.3518824877647604E-21 -6.814116447592617E19) -3.64683504854607466529059878139668000001E-1) (num-test (* -7.456278485417833E-22 9.61914445493285E19) -7.172301984744205963559813785437470719996E-2) (num-test (* -5.0781537010216826E-21 9.216915512986622E19) -4.680491362427717476508990573017719999994E-1) (num-test (* 3.2906792172396555E-22 4.571445785546992E-21) 1.504316163923729767672342114125599999998E-42) (num-test (* 5.39814714322422E-21 6.687033308557664E-21) 3.609758975123575798079875142208000000008E-41) (num-test (* 4.3506183844841724E-21 7.266196706225928E-21) 3.161244897538486151238585450198720000008E-41) (num-test (* 6.910763289107986E-21 3.910584203890238E-21) 2.702512175521023610171407324066800000011E-41) (num-test (* -4.6131515924393325E-21 5.228174479773633E-21) -2.411836142691841383820888561997250000001E-41) (num-test (* -2.1886866436065787E-21 6.29322016055891E-22) -1.377388691069093503544474490121700000002E-42) (num-test (* 19813/30200 41168/38464 2571/31632) 43688873593/765502835200) (num-test (* 16476/12673 40086/15929) 38850408/11874601) (num-test (* 22713/35036 2008/41994 58982/21726 37919/44341 59831/3870) 608349727545125531/546777281752405290) (num-test (* 26100/43623 64347/64939 51424/56858) 4798021185600/8948293077857) (num-test (* 13336/48674 21323/50854 60055/14813) 4269362918510/9166534724887) (num-test (* 33457/53498 45548/13003 50476/8209 9613/3657) 369717652332927784/10441582621738311) (num-test (* 31186/2829 35725/62132) 557059925/87885714) (num-test (* 28682/22045 54652/61935 19725/39778 14431/165 5682/36504) 54173177045874781/6989848058967345) (num-test (* 6054/59436 53485/47493 65091/13749 59111/51596) 5324119682728535/8557570117787688) (num-test (* 26270/51496 62100/14371 9302/6501 11918/55524) 627970006908375/927532016146043) (num-test (* 6865/57699 53935/1664 25223/46128 13016/30664) 15194818521234275/16975596844836864) (num-test (* 0110/001) 110) (num-test (* 14000000000000 524288) 7340032000000000000) (num-test (* 17500000000000 524288) 9175040000000000000) (num-test (* 1907348632812 524288) 999999999999737856) (num-test (* 524288 14000000000000) 7340032000000000000) (num-test (* 524288 17500000000000) 9175040000000000000) (num-test (* 524288 1907348632812) 999999999999737856) (num-test (* 9223372036854775807 1/9223372036854775807) 1.0) (let ((bes-i0 (lambda (x) ;I0(x) (if (< (abs x) 3.75) (let* ((y (expt (/ x 3.75) 2))) (+ 1.0 (* y (+ 3.5156229 (* y (+ 3.0899424 (* y (+ 1.2067492 (* y (+ 0.2659732 (* y (+ 0.360768e-1 (* y 0.45813e-2))))))))))))) (let* ((ax (abs x)) (y (/ 3.75 ax))) (* (/ (exp ax) (sqrt ax)) (+ 0.39894228 (* y (+ 0.1328592e-1 (* y (+ 0.225319e-2 (* y (+ -0.157565e-2 (* y (+ 0.916281e-2 (* y (+ -0.2057706e-1 (* y (+ 0.2635537e-1 (* y (+ -0.1647633e-1 (* y 0.392377e-2)))))))))))))))))))))) (num-test (bes-i0 1.0) 1.266065877752009) (num-test (bes-i0 2.0) 2.279585302336067) (num-test (bes-i0 5.0) 27.23987182360445) (num-test (bes-i0 10.0) 2815.716628466254) (num-test (bes-i0 50.0) 2.93255291463847587034176447517387076592E20) ;2.932553783849336E+20) arprec (num-test (bes-i0 100.0) 1.073751199431789167620943174959211991306E42)) (if (not with-bignums) (begin (num-test (* 1/9223372036854775807 1/9223372036854775806) 1.1754943508223e-38) (num-test (* 1/98947 2/97499 3/76847 4/61981 5/59981 6/66601) 3.9223808052178e-27) (num-test (* 1/98947 2/97499 3/76847 4/61981 5/59981) 4.3539080668052e-23) (num-test (* 1/98947 2/97499 3/76847 4/61981) 5.2230351951008e-19) (num-test (* 500009/500029 500057/500041 500083/500069) 1.00001999432878) (num-test (* 98947 2/97499 76847 4/61981 5/59981) 304151204360/362470312515139) ;0.00083910652502692 (num-test (* 256 2048 35184372088832) 1.8446744073709551616E19) (num-test (* 64 67108864 4294967296) 1.8446744073709551616E19) (num-test (* 65535/131072 2305843009213693952 1048576/524287) 2.30581222282939585599978637654567059645E18) )) (if with-bignums (begin (let ((twos (make-vector 30))) (do ((i 0 (+ i 1)) (t2 1 (* t2 8))) ((= i 30)) (set! (twos i) t2)) (do ((i 0 (+ i 1))) ((= i 29)) (if (not (= (twos (+ i 1)) (* 8 (twos i)))) (format-logged #t "~A * 8 -> ~A (~A)~%" (twos i) (* 8 (twos i)) (twos (+ i 1)))) (if (not (= (+ (twos (+ i 1)) (* 8 (twos i))) (* 2 (twos (+ i 1))))) (format-logged #t "~A + ~A -> ~A (~A)~%" (* 8 (twos i)) (twos (+ i 1)) (* 2 (twos (+ i 1))))) (if (not (= (/ (twos (+ i 1)) (twos i)) 8)) (format-logged #t "~A / ~A = ~A (8)~%" (twos (+ i 1)) (twos i) (/ (twos (+ i 1)) (twos i)))) (if (not (= (- (twos (+ i 1)) (* 8 (twos i))) 0)) (format-logged #t "~A - ~A -> ~A (0)~%" (* 8 (twos i)) (twos (+ i 1)) (- (twos (+ i 1)) (* 8 (twos i))))))) (letrec ((factorial (lambda (n i) (if (positive? n) (factorial (- n 1) (* i n)) i)))) (num-test (/ (factorial 100 1) (factorial 99 1)) 100) (num-test (/ (factorial 1000 1) (factorial 999 1)) 1000) (num-test (factorial 100 1) 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000) (num-test (factorial 200 1) 788657867364790503552363213932185062295135977687173263294742533244359449963403342920304284011984623904177212138919638830257642790242637105061926624952829931113462857270763317237396988943922445621451664240254033291864131227428294853277524242407573903240321257405579568660226031904170324062351700858796178922222789623703897374720000000000000000000000000000000000000000000000000) (num-test (* (factorial 3 1) (factorial 5 1) (factorial 7 1)) (factorial 10 1))) (num-test (* 30370004999 30370004999) 922337203639284990001) (num-test (* 12345678901234567890 1e-19) 1.234567890123456789E0) (num-test (* 12345678901234567890123456789 1e-29) 1.2345678901234567890123456789e-1) (num-test (* -1.797693134862315699999999999999999999998E308 -9223372036854775808) 1.658079259093488393947175407121858559998E327) (num-test (* -1/21 -1/2432902008176640000) 1/51090942171709440000) (num-test (* -1/21 1/2432902008176640000) -1/51090942171709440000) (num-test (* -1/2432902008176640000 -1/21) 1/51090942171709440000) (num-test (* -1/2432902008176640000 1/21) -1/51090942171709440000) (num-test (* -1/2432902008176640000 2432902008176640000) -1) (num-test (* -21 -2432902008176640000) 51090942171709440000) (num-test (* -21 2432902008176640000) -51090942171709440000) (num-test (* -2432902008176640000 -21) 51090942171709440000) (num-test (* -2432902008176640000 21) -51090942171709440000) (num-test (* -524288 -17600000000000) 9227468800000000000) (num-test (* -9223372036854775808 -9223372036854775808) 85070591730234615865843651857942052864) (num-test (* -9223372036854775808 9223372036854775807 -9223372036854775808) 784637716923335095394403086170723686146950778700062261248) (num-test (* 0+1e20i 0+1e20i) -1e40) (num-test (* 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23) 25852016738884976640000) (num-test (* 1.0e70+i 1.0e70-i) 1.0e140) (num-test (* 1/1024 -1/9765625 -1/512 1/1953125) 1/10000000000000000000) (num-test (* 1/1024 1/9765625 1/512 1/1953125) 1/10000000000000000000) (num-test (* 1/21 -1/2432902008176640000) -1/51090942171709440000) (num-test (* 1/21 1/2432902008176640000) 1/51090942171709440000) (num-test (* 1/2432902008176640000 -1/21) -1/51090942171709440000) (num-test (* 1/2432902008176640000 1/21) 1/51090942171709440000) (num-test (* 1/256 1/256 1/256 1/256 1/256 1/256 1/256 -1/128) (/ most-negative-fixnum)) (num-test (* 1/9223372036854775807 1/9223372036854775806) 1/85070591730234615838173535747377725442) (num-test (* 1/98947 2/97499 3/76847 4/61981 5/59981 6/66601) 720/183561983334767209753061626751) (num-test (* 1/98947 2/97499 3/76847 4/61981 5/59981) 120/2756144552405627689570151) (num-test (* 1000000.0 (+ 1.0 1.2345e-10 -1.0)) 1.2345e-4) (num-test (* 1000000.0 (- 1.0 -1.2345e-10 1.0)) 1.2345e-4) (num-test (* 1000000000 1000000000 1000000000) 1000000000000000000000000000) (num-test (* 1024 -9765625 512 -1953125) 10000000000000000000) (num-test (* 1024 9765625 512 1953125) 10000000000000000000) (num-test (* 132120577/12 33292289/6 260046847/4) 1143841133453061178785791/288) (num-test (* 2 12345678901234567890+12345678901234567890i) 2.469135780246913578E19+2.469135780246913578E19i) (num-test (* 2.0e-170 3.0e-170 4.0e170 5.0e170) 120.0) (num-test (* 21 -2432902008176640000) -51090942171709440000) (num-test (* 21 2432902008176640000) 51090942171709440000) (num-test (* 2432902008176640000 -21) -51090942171709440000) (num-test (* 2432902008176640000 21) 51090942171709440000) (num-test (* 4.0e170 5.0e170 2.0e-170 3.0e-170) 120.0) (num-test (* 4294967296 4294967296) 18446744073709551616) (num-test (* 500009/500029 500057/500041 500083/500069) 125037252995542579/125034753009582041) (num-test (* 524288 -19073486328125) -10000000000000000000) (num-test (* 524288 -19073486328125) -10000000000000000000) (num-test (* 524288 17600000000000) 9227468800000000000) (num-test (* 9223372036854775807 -9223372036854775808) -85070591730234615856620279821087277056) (num-test (* 9223372036854775807 9223372036854775807) 85070591730234615847396907784232501249) (num-test (* 98947 2/97499 76847 4/61981 5/59981) 304151204360/362470312515139) (num-test (* 8736/53718 63349/36593 2595/65149 64793/55654 43939/26485) 1390659088083157464/64205855201422018751) (num-test (* 54969/62648 20435/1782 23198/40155 17874/3641 36734/7395 36402/62041) 13827254253801875273/166253154009320895) (num-test (* 60943/34150 48303/50035 11510/48029 47829/30632 32873/18834 22417/2481 33058/12503 17309/26655) 1265424338804436192426278624740533/72495658400472874898571063803000) (num-test (* 27004/45232 47028/36314 65506/17434 26523/52475 51611/16322 12090/12813 11405/42722) 3271229108161979601346009209/2797073684091589444785715868) (num-test (* 49543/13313 13047/51213 291/3256 62128/1256 22252/50000 6721/49922 20433/22341) 13848375453906602673519/60295540932769356700000) (num-test (* 24886/21411 24103/16998 16669/52061 10869/30910 63499/50270 23235/64564 6966/28625 26608/32424 957/55396 36661/63680) 252953666671747144783991553669663/1509848199529034284126219405993600000) (num-test (* 10658/5373 33874/4120 50218/27624 32003/31997 36890/5232 20975/22222 42566/23821 32593/38877) 79446367034396970532424018904275/268718417239101417993099877056) (num-test (* 47540/33937 9597/40213 20965/57592 33167/35761 51930/46345 5554/50786 22141/42957 38576/15987 33878/10223) 94287693697494661741863470671584800/1654020197364120441179131115365910721) (num-test (* 25521/34695 63478/8947 53875/28904 102/42469 1068/32213 42994/18166 58634/22402 26266/21149 46345/3896 12489/21331) 2213218340996076291055274962125/53325428353972306616141560355198) (num-test (* 40953/64127 12327/6961 22167/29019 49635/32796 7657/16493 22904/2449 61975/28667 20516/6004) 4090451708614082328368601750/97539662436128754819974369) (num-test (* 10109/23696 35613/28646 25222/28402 1339/25272 54032/1074 54456/39833 38346/15060 41802/41388 56761/38781 54798/1261) 8983158114946791370557093367421339/31998667830808722335250880339080) (num-test (* 3039/17717 46858/6352 49984/23638 8924/34958 34932/46369 4022/13488 38433/34538 46750/2645 43883/61392) 6694310491567033247725656525/3103280388958588906030059796) (num-test (* 31536/12807 62185/56296 30389/6526 53321/20781 58342/28759 39269/53225) 108723306155880938114002/2235179806925856029655) (num-test (* 58784/29145 14245/16217 32388/51826 46401/13774 59002/56853 35615/17085 41786/53891 41646/4047 49564/4554 33807/36767) 2545383335773830668541245993741980009984/3950524525412306420222230035841219227) (num-test (* 39890/59976 16641/39135 36632/15382 4037/16674 32789/39049 5621/24393 7230/37552) 4325746891228381220240705/712068637373286863948894448) (num-test (* 64658/532 12056/22843 48004/41965 17525/20404 46987/34608 39890/37132 32167/52059 26352/16429 62428/21665 39941/30015 19743/16456) 24452413077816850567396233613920457829/58345020552056693855433778720676771) (num-test (* 46215/56564 13217/15837 35488/45940 34754/59356 39024/37453 37845/19747 12129/17699 11475/23380 3024/11313) 9665517455334091811247537600/174562349461714107552224378659) (num-test (* 20849/43211 44644/8350 39144/3119 26169/58795 48540/58870 53603/35775 50387/50026) 1503119635914748931419827344/83828469729567613584821875) (num-test (* -1412797070596191471 -15492755620416346417) 21888119755986895161222137392796809407) (num-test (* 16686841096925954110 1491135775021813104) 24882345731730524499708005167300657440) (num-test (* 13262412958100188045 -18379071970155621919) -243750842254847872704698616507823758355) (num-test (* 889503034794263569 -16600674457216690894) -14766350309325860687849239111838240686) (num-test (* 3148165694020236318 -11771070679825280729) -37057280896113409834434531491271315822) (num-test (* -4443818546267181727 -12001052312087213799) 53330498839175802532024121011435050873) (num-test (* 8305259347214213793 -229351169208067535459370186456659711595) -1904820941859811670566233132773219565154696335396051029835) (num-test (* -18273334758510166901 290047155020180552782039318570071650475) -5300128759437251944808204783222405076790289915320785927975) (num-test (* -703280433697652940 91110448009482115063492795153459771021) -64076195390496041906141380919369524419358692517527451740) (num-test (* 15279634596127882146 -220998726467849290098339792307263567896) -3376779786638352686104608499923871317791563686466157184816) (num-test (* -4472497681184076830 325612942672822430032905460436166528379) -1456303131067722058341139305566346079551678140995111358570) (num-test (* -6180420673489141029 -161157288800853703711204405567379740552) 996019839388256252540244286609069684717518686623358308008) (num-test (* 14044956603588468379 10163190459901171254101452124764637970005230126310661589196828892266636678427020930101076689732526935899135126391465178494895371156141265424428405590113790) 142741568963316278148132287599703960511135825069792278910440475692913696263448088587778211787403889397993501704943449376875999977937418748662459138952952917221024170426846410) (num-test (* 2133283347509865817 10577710515843519541178984366353275630877942729579274295972091544607384358263130633386329706527832990861547566574369528634541156662300858851752195966167381) 22565253698228972909216255630133478029433774404794962869038558824053350969301054394347471181756471783852326407546652836376109109470959746153989521923555764579738243072315277) (num-test (* 7812722507014599311 -5055959518947106416800910724733658104378582281318226107212861190073091017493970778425583956006925004399967175604321778956828368132273155364830637407968648) -39500808728232764770485117356353304373275127104839804121600969932458363071148383405901570717732548020267052999198017578112731079638156026910705662052515278317807704170401528) (num-test (* -17560801708050275829 9842515227842383346577123873881045824143545509071137371075701856197189100217561683579562062872293951325890789283651221922663521213150065638405410634222129) -172842458224605375239887212582262805312641302639067963604956593404910080268476692854082531021580381176489626536608405283010496488558204787140272050713264572452317265305619941) (num-test (* 16743386830114877156 7347065846171565625701636575261347705942035850951855454324853850791855951431141198155170102434274509450315416946729031216385536668189501958761688618635668) 123014765528775807847206414290825117502032199391400884957413813554539073118943905948723779020186281150198999824020769031248882909461419778092564985979904308229718874140000208) (num-test (* 12697192948029671719 -11416780209809507417142822520376617951137069007568339428552592261458272400645205700952156716454820410468812274673183389934216970221062627926131479014990611) -144961061169197993494569769162151457365959287966302572862364500950127981616038900865036521107816831702945678695331078399461327412574397914795455218447174498277798426197230309) (num-test (* 17005139720743105479 -29990519259587469661876904501488342396062731024702923152492275204626478246142153608222329335341363164148761307659972897552084842238285026253664841395295138667328930482145590159132144957515157474957872335043653264146346772142483721767458961320947069718037828473530001033848282453826154763424789967441239969918856795769965946388666154136004597297855416503729657013008165049478441197537144135384444157408972370236442813734429031404855591324183846423588871065272526864866155918285777640819778251612915859290336548446745308788013234099839998683451658620461972798204104633072664604846231692505409653434538208644416538994256) -509992970306921990341332390474393215554862069848994183152714032617297815196921655222705396130464246880845576204295466273071779248718654338767559016551390771145212884412809612574391658668778295682412755916528976282396155832617323980694289208942491001345059122414240884660276842648466533488559879226195446807748573906940273568334343093922652142252689341425941673567630236228358747411926991658260241924294146562230425295426217833820067881064577380516936937782688004146531121831211284735538742160763820814174631414364095096099434285754767091040812242751724012532803037860394426031234340719537172735695313262283511554154662650333168783128624) (num-test (* -15877530153400521290 27863984127681242643954505352420303514833683768731313003271701952957204538094398204984051331105594788039352443762851136101330385230866919393696564428736685568762923746771275677491379334452751710169529933675128178840986001684425353245791752781476028565228371147542431713985092322787978914276414008774443194161599919167210582437024618824616489802661351916633993681556274980075051797120207655478780052593534285265078265845445633803877185868676955831374479850746658711791169579387317321983669227930929736238215792068273805543745311609083833407544342964285215427999724272264458975101474080574470499647168865409458531868592) -442411248181132450919255517905812929771246981404050821923231762557171158858876183536414772404562764742655092127161703706239729646027465795612501446223663310668879007072125975886873343449629108246953385822769744013416908613100114754904323190537317463286500657291202287742354250227377164455244103312266617146454847578457073139633297517170508179596166314955134347046515455569689877574427319658085169791949003021426613961459610227430636932814700361914589752207776142403364490846294795496119883683491811246550808038342285518518431538295199537270236275774546666026424361019715280652576803278928827199810150387207105149968313623040090578323680) (num-test (* -14162897687527555611 -23016403916121951319848021112075986869602408568431399211927062304968548663313037929311574133954267816204873252195499803324830278637331653769648377216095499136975244697758388851688873078022850203685120154634090802825656419418077380419130449990938627982123188424119187922828250625318327074513352279785514062876718714640725789938556578327139793467832731546881422469843509318627826856881082450937188956068348931459011923844607158528494902828851692203126881727638511348944908726926619613375594042390434147948508706733126737304560579515324106834237197081860910657003346633962662773394999353766192391746258372744063777808796) 325978973798843759388794644178802841408656469654887121096165875654577046313115917671847505813174070119516580105483409446057747653173640660143855580491229746795572929387698247460831363721394707501497262525550824977473864621747159715947297817600227665840640555029633517390896890601028716769035575763283168066843141870124768085499453574902575378368669494153555135898430469356384416638130459557518713454927909937610851489821263029886989981438507377741962130296498574556444168140838201069779040087521405032426995145166201901368032136008107323350679784004016321425234898132080844200202007395427054392280809376612533414505539109579739614954356) (num-test (* 10844738523441551664 13010289169828379103330191247192587220592807931898339555723704078985668371901953113936581573750666143303899278973814509164982887504269303358034042953769514772858989849512527461308415676004712388964136857232374888643347097138114199889581495448978914022318770898259317738823514820591042321773469959130347470144905381758960436645008051488666423115693738341045851119808222048272924385188356021826450267608127588500233526688704136268009202730309974485584784539415807259862449203760469406037505772435323036790641520939576046423540699016607317147689982042035523118533555744274806239272109508745089640043900389441390176681340) 141093184161152226992592021994885140117836445291515772908453669279294934817987511015413332614094493905560980363483549300117114491702466085602279965168041684355125886388302948336158133555051817733078300668260616983283027038746214728386770752826764135491650323133831923154477800324207350667020747545837613879364064704092093040155243919335078139087599906324684688427176309081290932504214653249366429592335409761783188358003723753633106574740731573467850133547164922532633897844647383889253777956821171583261238607289172489135768839436605233457738153233579088224808850428203888700116300637190661108848906846940291749737998056247719674749760) (num-test (* -16402132873169057380 8202725117980211375579199554494319645475746305836527475507064811368616698686329266053570766100878145903342129595869654087772486685252653587846560946850102095086896668181099435964053041678323706849735936082196618754721606824996486473796843333331029865501790248862590712245450877098960007272754260813822886287008295409755783478345202299352891066800825979067590290793893933819913530599309037639082839491869155044147367415785329077864525961799400923643936705317921900308490987828345313709179960659814100113658528990241758360711799009722683007157350272749544178688961738222930753008443755881419398858537860612954576778456) -134542187307192759584182063854799850608007421111316277594191532129597970622559949723743396309231347084450105499455916612009290113746722460358793168839937004812915757145655285798961178877391232945062437277255128401572171216279188126380587081673725314534095093062983435026047851041796084651601813918099532876684901239903769891552275465470747567830660442193995685219383258617057944010709906130655663966913354414611799232001438943448374556294933488875450563987147224709383408815994320229340710143082135667640802837699940654151297907451396297241124380508001357553893328703788960812706653503939250831164194874527033594779746890593262611805280) (num-test (* -12094905083549825231 -7303327854122277566083382629094740392048421584433028903125893639493993705575691832165314461496849401726460344615713884253150283931509897329926825128629833541892164122168618243719393446304446866677253728405617434021389128710195093788280203239300086905325641224801020413858421914412156234316517981228056539721130386645649016559425091470643854813419057026759188125291655398451427686659900364573485593902992038773538760663063071699966278379037038361219424927031644750173900916227834573604566165762753650347331082640552394430002401423199016978155236550541225512734287851807727860645247391524620773399994302380387697957581) 88333057189654571362020288527489792875655269960629008914349561689924145109953656394378545526256758871407020025766992398117775520525507898420898102744530402370720932219749861094609497366188371774072368034971851022164946370916317410415503705484491514312339956381120953283812334833067601825812118392757289250628861166579446800637104996060739031010579056633535166403083327528575504427815713481850979373113173151813491831551023902022537957860211597622343157802805275942920911544696695931809085743355666792408029743911424760065578742910735408262758198787195579745280191859776661700139596074108035867940154338953640690242795671183308201526211) (num-test (* -81618231044418675360403541307856740187 9751573706924018395) -795906195858402819552264165081526765614024708979523739865) (num-test (* -167600745660011044249531125104202473984 -12960244919927910377) 2172146712516287908809731894157839567367040369214826131968) (num-test (* 90306383312124738690336097936949488486 156109477991590792) 14097682358164298866835386043901377722456291173827620912) (num-test (* 126202800261728727198105694812165074067 -17404362862588500316) -2196479330029905727399352310201914876903532806486592905172) (num-test (* -80093647977875266525946940496137725572 -9499399805878278852) 760841584053111508349403804472960020663660465509267203344) (num-test (* 304052889577333477963637861956318521374 7233536405885618691) 2199377646072361697737485358722028853038393128548297401434) (num-test (* -124787646062877233829165925777950698937 -125798384154373172164515376683173327013) 15698084237137783175768362160964949930745617334715009097620154581879012485181) (num-test (* 259623502197082370239517374851053110076 307089583871541575627915295134832918432) 79727673252974285068387698133566605944659309374400074880377824560177225320832) (num-test (* -245358177397026033963771466683003477163 -285087883756432161967673595037725276963) 69948643556453419103498093570621669430956866597291662675473644085666220495969) (num-test (* 46731711386059374483493216849082745840 -216522280665540473581476116002923812173) -10118456728713381305690589407461434638634240429858378588644634276171257110320) (num-test (* -301422430661955757433852743238845048860 -737194742467573013847855072675441356) 222207031145790358162820429948896977201848379524899474475604149595884654160) (num-test (* 109781582310220385246795023904554278713 -273317662617851276579672019029762858338) -30005245475518685175699313262818315773200953201653075289648004177366787958994) (num-test (* -312236719893391897821327608828679767006 -661158307192284418474080017860142217763949256471548515134335997907628404839044913830388499435166012788226998900468665646723366842553747501004752506346280) 206437901167986463762021023207669068873036145952740267172145693855475451354717023377588805030022300923600718715029262618794758202955817341818233889201852381575043965927328029955969846754837680) (num-test (* -134379788461141842858846278268259347105 -5535479645589936472405910397299739073641612836770238183712206042659632410776896398062277742229906915852933418684231779996404071421767274180368154310128427) 743856583805332082970350662728998610690268824090148728726850517499798631519601137183443104910590855501252539324674812560702657332874686395923181633958702249128106139207076314713649515720653835) (num-test (* 278271843790644800793473851247546123375 -3845690285506025443856370771250487683891303505653819308540635173436088084480277686684743918745832832765066355874381847690771330587033980524869033600561589) -1070147326395532917564114389205677334125034378502074943828571411806344559859053091006175486397820822872698474899835730026158782698085673635033947150554253148685482702599776833910878579880042875) (num-test (* 22345490710865165412267189692679994671 -13168094845644809414256057134926669929759930873747535851687323456073141938879368460977723280750841588750507348317544461824280674332488497533955177541413394) -294247541053147552931885013427268298282376074124656716577088212043667912662239091316191145352314750820026626159649861330384837204227899202392764926604802655267738710003310052268554637728023374) (num-test (* -223445051950608517881717261787296926498 -2609806601119499724524852022247741111662431776874117401343811680374867931883996125145979162937751368655661775097445043144114599069842524778189198926688379) 583148371568187658089071213924575304457465978545376486297236105670932990897420147110485946155066725440999079357995678147717407410446012970360780626554347417807723098476525833332400212113766742) (num-test (* 12604140228725912459681435851589379433 10671266866958584640992033560488052420339425977492420594983497264069815016478448589306666811246532193922229713077112601565462530332258877522384022088660628) 134502144009302626262781543880199144227907004673612064586081220538754991037447647926963488301214672345398823354945333417956344119228084327815583754032364976497975702972112644238248704660063924) (num-test (* -221289678591114384943252477126208006780 20020996887149770966522122735176842174467884990518978494604707026520269232864200848420530223248762875769520715632742683760311747174524709550334825291720803698613541109690224185041740294906022358446325921538593105347423518731748623037078340006459454656405997570119591344894717789372844612253617591807770017562530034107842444403952657949565007792107071767260484233194674888488789619319597151367813735192433631007526015463229060702510632792171187339118004038505860316305860704455466207113207893106982258864355430481457640304138738182009363353560090082819036973601710432437342931523433079941958203038050750205966472435692) -4430439966231074415853738608900692925851705818190624801199561884242897308817127146763274284287396980593383317678766559004881552228480591814939402896201244425805503258878061459604511214900528594870260206969839682573246490602076070316760182753341371682323914671418233629420599310422437691170629449435494697829163966912842611408632129590129483811802031178053300073562716917597174161526976287351465154825036851645956354853960835948518860624747958440181683978083391663149733813297698623499283645627889274004656942800842013709298338912226207338477579862672216831422765369078886850523202897989792734789430796029206661261129141144642117177625405158700499049991760) (num-test (* 180785619668676509441152734583033930295 -11909038209406834057075682058438206007134213485822042209417443270921391661498900475635417780140585878716264253792335317341527677051828500780153492153490249297998660274828986996948999762620400587091118252205695562417522111840305140989214300921122857271717052213225664738544344394774362885331856170636862181712515248810239601812262573113794334115259873527539564296101166439562124016438281173202196876398090029995104489712272260608848551754611421227761245487365953257890749115194455096508613617028024932657498899001119282498614739316599704645009607294747043489655424155986912576002393048535846081096337705941547991821928) -2152982852345560218506186041143281789706715672110278207735389192913214838321097754496849942223194392302524369156102301165660674797665128931611291246607346536492650554391248756408556789391955568308599431054809433808337036546281323840555452571430884302696950144068129601527530304907460164571704857360215834011779559395577299313379666503707563751314135201994045874159291100986903645360754621200008830207429980872071814202801994486961737459218017354210479544121100423399040398021780750351097082070296255480707530391964970754186799748521538525274241709676878827522138880241734356460339681718690408853314007343934035505873192699052380699509877559455199604508760) (num-test (* -196121729286794751535600080816329923561 31755463535476988506639447113088283661031267977524968610501132544098607201258848456920865390506381665724254592728643925608893982794532243733117636645689751360224314774452374503339856173343683819017479955914451013484169313685311530532055735999039466721411777061709328450052490025363788971916050033904534189719389237878257877112162843506491071470067738867693853480174965212750301808781573369342701195147083717623066339671595077736036738235636996351642097684597005928843274525502529735435418805821748637387888409663397547514467435322454217015563134545731593492200855670248739786405074231658957946422903165662016649229286) -6227936422881500100190187768375947805694946596622670066116457374856427496311253030141271922822486386675428302332027411428470488965226898801659352566022706152307022438261392466548357753526474097246042956052374187605144719189465046544498482461077851578811186829094445089366592317045580466302238653533114619908864036973070346979261546801894831273337217021756025770590122176562027129481076270727248949609326868225755958667670279949371399535144788247565199415296122873444199709788941984099349149684384486618280260678252604631431089580057102263617056951788273430713908768738965854953667135156866028646584137788146112300214498814212865170902491169332389942607446) (num-test (* -149247491509558553673630984739524508601 -9241905448313719916485289537122695595500213295294799660583133638026091750542612875183284894676615989153030773719811347110864468582634048542108726080717551794580656021381515769591713295631818532114918070215760259364277583650102628486861397602958930509695263902920994329409932518607260720657755504091822028630927071374796474717671220452208310602827254296323761245420486376569048549643478954846020045263141546849795367522490793641049509748005893155533480849922847230018411440739584477452313387881413141538766185123978087175960946255649923135634987656065468774634483495944248865774633962770893338531522570776854773975281) 1379331204929344851843348280532786532350930013132149419346606977890849868537539899667631713548510207947097949976792337278764045110931774279794402312944786743575421497528669859045492875676005849752425421867514661792129580445000023570590786705609341859529483054902802038173138834528021423393677908655442991197348183257271932188161681770513283703502340499171444058119260228931558784004778969491586252899270869275893402714040693571919281494643765571068045362364213060063345212881008657925426024923296369533374671614852576576041747836643356665301762059898161073609265572267138950725010661453917338098901465732991316661901878681888138048552901254914604845891881) (num-test (* -246070233154436622785727814428081917418 29761582253452470642591719346200231425423204062498655510037025199574178834762931489817919404889920159374886981199608181795387339523762458361385170203883094308920011218315748466148953320570427838912637152446837553950810011344492780712558515815917745810385725989241835877316836808088478276603934260581342710503593237081689944686263274319354100341139245512159619947319496638082702549196795236216458749363904150768879765280332386830831409591769966706351022328535490587838695167807967607003680703048770719240872629379640571077329748828739281770075441660330884779539288220944313294762143588847790653176774089774033399559617) -7323439484151992757431054484912931979861244043627630118213112440051387392428853497035249623931234821362770902740177541812170377563064854590834087655133962963430877452052749127605572395112726398103244974178157574726551814002744001021805127518246639418981066588073652668879613252372759895389345727455380224104332342029151667860553645106555190741775758687650292791318963679857313030729683299101577207875499929500963723267185390425716927303375831321783415003339099100562942730763231688479910689887284950156875532151104047755803876078837921949287811575034368641167438367411569736575067233548122814012421044943430647665260439418887639347030312118291762161708906) (num-test (* 203826295936164259559522643510940430939 428315860474710981601019542870649234168732095026625500771233691514247613083810271191136212287636290276352210600151884730196161003906066671915478570992925366265552107746965374246537358349673161970290367972281768471743836339191023211359427335141701167253694144280251188008871929010775436125645541749886873478179599464478734149706121117222690271210887178499620737860802605991262799781279373870647695125320153193063528861104479576369448865373971847676465682752435142074973627172566791961541105525781297462635428308325033717669972726101583722868689418677558787287897456521530400671342257419067050354522203242849353639864) 87302035331271280954456598486072605056704393103691656908943847729634903654600322194677794243221825233700566108459784062758955025931450719283517278054268553004951352280583820782976072352456972931479389375165173986780482062859853305469143408707179895843295115510597584169486406323435925707638987591151227843652210256611991940374072593149367903739596883229844326054223707236369465710416960023659329202073724249764308867733476242261506975691004092043954515337899900837434270833782490145948781128533218641649564543508314976001614187701395586824982250794852925954991265270537649691628899148413763865280007928191637215283244406869662872539567459561720369352296) (num-test (* -5899540498246269366107488541138263797694914692322476860852796858749106720144552037986906792251681094769894732746138541066810195167688318229720888479512583 5834015210744942902) -34418009003174534626858248456163154666511779871358190892629413477534042866009573638264296461516598238780495750056279721797403178867717911762916049857737963922333901125535866) (num-test (* -7558198374656605586076446665394545534375963428962439959101805545423930654069723860456022097647139432324162475685494459942871728608277717748075653794546685 -2079670855873590264) 15718564882684481784074014915267371190416032453294568239793060140651422710113447422494938907375595456199203928496644205320139985222135619659630853564447794621716315309474840) (num-test (* -9442744083812363570102321552182535031605446031706376100893354933468482520577272174689455502380973733378565213055641110431767353396963744600184737808983381 -7204974197101757391) 68034727473703353914019458883709211780958983263702756416891835054494728840771498925306650413027883039860202168095834137357212487561983607389479135319040711944281262212918971) (num-test (* -10658732210276096534851972646242288663170038580488752611749460640657411087860047053151548660331707024718100598181073744715506934778234716535781332588396176 9193953347013373121) -97995886679587166046252015742839992974979220158813197140160489510432960510418039749924861744197553021702396544307690217470606424904065359660871469041838900287446937257585296) (num-test (* 3330096979672637104536573277593029682675932033891010715180474877149733802060455951241981993421466123791200840797318740359792251505430948855600408060492000 -9413190658845804679) -31346837782105095097578725347257193539696338226258990009265748336528353873277500144838721882313026604404426563737656928378230261942407473822851842589487713775609448642068000) (num-test (* 2224201331350479188470378485954814766783857696988331736807430786504130570570323948774102396158334805040994159865821844362926631687258969480929122732089195 10226747830478556903) 22746346139936030910929166328517425029735137934434969334578972386859485783192993228082340012742115893176871887387993591191632260444955081663604449277961804869872353878963085) (num-test (* -12394770820700925077767705800588617445613665027183406054209162910642613421436080064653443098327137503596792411463268187212855350864330592654862321763110243 336135860956209890623046930607725140868) -4166326961171213704571179876442248501325782360170764344978629523457550315208845439497110652079907652744850691289494398473488033083739905461347650605270023127087625641779424751335704552988710924) (num-test (* 11792778994619176404079667787533709801900490264171877873621265044313417667869688303207909681289642260521608966405181881416781694320672906600599581862090088 -197661229068721548419113517262926820105) -2330975190212228827672814304508257223671550753091700552243633152084831515892056240354560520878171696176381845689952044935988868477421447557890739834031207059212175922089523097911477486879619240) (num-test (* 11608994516281296345925963401821217560860934641820086911326880657644311461955556832927259499969983808078591149768068360172431078248807463030805586293656663 -40654941048774156019243747229920736005) -471962987694958552110784676392477007070112288398143925079396435246284471999814508543057304008480666763661066976653446723271982094424149279649226771823800871458389214002872916339341019732251315) (num-test (* 4821517917539756801293776911844480642406562140007084392649374723119190602353617113036081438891134008988421494142194891002983491670246762173236312873933599 -255528396376819316172341014108564420589) -1232034741571035406264710387186737842510579499938716343220834781077329515145216794636313459582844773420679078031627466542930137302257934575129329529129776153159694412903937370462708576694469811) (num-test (* 7638751115643228563298483305056828584775811590562130101723525925933790010789130133831569153863129513189315440899053288261039147463032870669035935364282061 114438828287750304954799140618669114911) 874169727255956505920153418854946321208907128396839975975317705220623267360648189969313978740314703015845506506608054761304647627635292132043887080298168302864314697920637105700927041824911571) (num-test (* -3653826017463740005170218884285271512636869606149686475539243914909566619638259666405831445823138528809165270360144267462878986866506114069923299116957450 215752050445782448772085819939961259625) -788320455239949216234629350585027855111249573063377172522422069903710014529292638311216050777840734448624510386643245486023092483841464815987597578151663227035102742664709136512524899527956250) (num-test (* -43242564273985683175827997542883970694363047476880657467026050730764924897992516355909421962249292250047896135687573746158665836208681548975073555418266 4424346097667245771102179669235543742385176589624011161914909311078645828684936231569739522607200308028372644149306431599085361996722603718517735348761218) -191320070498733614136284309000213964486426347688040889144514933290125387693498098446328694172047943298442181705949005984031677324306763731212307716485454004382079159622650481983102917517993601466178931324415483972311904823997211920702201161092866663969163567426868740120661073974542958600768774774949607988) (num-test (* -5093597555679260616199210906198149266592665304134802327659606846977583233938836318559188141955851256260954289429418183711191354912372372976165948043123133 -2240632735861652612028397136046974907251405868353380459030143407902436514978447480884513019736738955326732458088791830752499716417751919868492224207936623) 11412881426559848135724717164530530041659963797467536748076144863846600718211858527283843975968920120508569299672573958424908957105703597501013710262110218780710678312197455759181436286391257283676806548463507528765947919856827004176416634630489598937924092540289712219714362500246928243091408698274649199859) (num-test (* 6049789822056553589237940133475342650218069231558204589924996117723031491205673061674252841792149409384720347601549237626288416453061224734057079515141650 -826416247951451524584060567988229017033981218652490450160817307801130685352465013890931297548015267655971295627931896259998420078888499206031390299169584) -4999644605638856588581238481465237523157457201817697008198975191261856978252081380810200468420738807464233192102972784271159116426108806200426852134469939032473362689081653859652824862066224063273799612269941254948709760659691148103622071316554194507524610166457990087959160807415102946877307193349131573600) (num-test (* -1175978338162966145239180473229656000174129248706173549637767835154921467129547950144109700900405904250603515318348888619371004435353505449762899046094747 8633693716102199391202401198009047492431980605560930404972542822133579985462906768067706391388213605203282586546130434156768523403030127356256666478340720) -10153036788469908062299722391986722149392791936544969945546931764708792252481931153733789787389051773529081688846141949513463792442701686406966696738286561777611293604311491896230769507535896070984747493738525389837795316954065260075941524322954935690803870500012809797698319359975893462672845329776468197840) (num-test (* -5083395547684319640767882199938390155755986838939007846911062687871291096073452055061784159768637502151635665247461348347470360218957222873087414506633886 10813098236568616588240471432239693891825284805405416395976866126102880121934298269375465735278296789484402954117593716698067735458182402220278016922449294) -54967255432446073625448401244836956268872685687128644401372608170106281377801209665004925733448944141633739594240156882328181133879414641109484442890809130544146420476457200729843868300396656004198615619691952536924980482714767859804902602805398865249514544806725162402291122143659939645240358379962457176484) (num-test (* -8944626200084865988157251013718979706166428261352840753194709093968177704853157211364231059892647813839391802007588961807572842923682104089512428902387812 3814836951264415657788614449012480613328314590744410079075164918748648723114236698412482309581077603776489883375576245233128800002373843611668945838558629) -34122290543331565327874124324135450224668275222811493728051290368641401807963502623692504750924543845019291736982354932620821594287780848608647686402233097059022704206628297180782771812500512744911371653368388270442874670230118309469599458827222162362901084328510647514081302476000779049412605744638457029748) (num-test (* 5186176030253526423885531264483408352469356233262336223619904269047786350470477526433506158542551137478071074193659876898065998079440819597952826155782068 21428324964794197485898135923805540163916541943812058590308650649384013587098638034673796533027113673143959572855470411726978105342739938341516634354246514986124789451866589211982659199267654387148420461876524076040233779391563396552267276880650559148637067641021059664960876301072636635299261389450890094318429077561092553337025096293793433968243940381587994428364726938534453507046761494257538813861046058298873206568935790790373886840765817404479239485444563488020955730741209738203470138117422899051269778988135668626686262669881048094388220931264751830393793846372816717368806996496715219806062282836392457741918) 111131065300898907482632501071313138589398597291097276435916516379173430095773463468344138866282820740991088290299992221985607057347883717514843661030457396422379155394966857856069231504805779448809986906434617741485942621643754096548512120178021034054648207248963478122178145159262707381679354401629366698488021743300737044695960363216253889163551918513521913593214414139637549577618641974388739304727218804595402055185824193445089425262833385286117064481648652550355832014346131722965510192584901901111154083186713580209077544982897821477349293279848852596241762198202012197892321827305803333334823616660229870976569043453639028059771892706354703750763908127611939169337399882784092285804830644630059487027413697220038110815990084742241055099963659761569486906596326424) (num-test (* -12615422028124847936088012564413126213419674293830655240645918456932358053670311316461359727921727680491520480380615359506308571290338231702217134487397730 21538722931308708400287621200994476771789912594554241036641406577761480056366647329031140922034590767810855360008375309986798226712928670905618807986829790199948665185268081173685941421700542631395958882077936923141152528333121096909688700106365468854487023847026564219531968849793109908193037522063952753477768381591929787242143631287330811801315216116212154423972654430356675401769729358415036943501470085182304183033246682446978634892995900678975109490698283226559860736462409705544079080978470202336645384768211440438501339641775269445439018148409151795830925198162301321965042997632479354427154223366199106583051) -271720079725309675925162538296715595434811519956795637977932956405490708202732964133816538801099235844279338645471102896234318181092598033040518838847055114923365599862266767493227393553801736813141780001130539648588341196802606083178208108557367013886856183999712817955194261262279080641101769944037282423238147653270651419282545398168930625797556638625301898893565965773914460998322350526545278664715332414172614761548301364063397364632709194713561073496860524124460861314674679928692398440036071116570829193414179054372604203478369755566003622621281005164747628075596444178089558747835994702060740334079222508147598079351187013336751322569865313532407367116553748939535664259669808534100091049960040092785009707220249025633808590643620557093069849490009472441113874230) (num-test (* 10381022953674450046578890619826448644067144294659610359943634722044183130638243233110364436029778310048006743033299956844491228999113516347401915490861208 -20974871685432829994714153210121536409377362402944992609230062091789259307033495284524234519701670462495676590513192861649457148897274608767543942797542628100823017887236899471151903799837558453043431373811892813126194662218472834650841742305925226558315372771353677064933578639099452438843500601586038910108679737480263349221244638463171088589123712367802373159421798288708123925853179931628847579314900787361946716531755600236755527982132768286927549323465697241340003870259800347640599467922823203446834792229595507968354687630029075884034263531531423883902851487995214646322431057626558858528344843531280263328354) -217740624416854507100100919338835880277259264187442792458843251425095703739537223785767883764746809214920580060316177442387941385712712426957388995082877226019966428812240179251716274377143798847348759498926420314709056615470455134468678662646006408843897699718742372199854223008996321568642038054564397441209859567556502098420151667437837356649730396360374136203172669776530655738388121236079327354422138744456395348910073462618440421257604563050031602590345028438897601523520973759458890228893913090702884911857207117714231568437403212806578764580006787626657709435954760239671948147344463295520930250155876010414461245194991189183956653772752290656063730950237649394743456230607077768595983629559996700837383822873994717987698780007691157576205450973669241823945091632) (num-test (* -3984492646329789478973994496812455855595578196959138558282015917391108383154917581748539892089090551298072688793487597623310815918942283997753800645644511 22199897116873160263914990610762123553075230334116099569358672964060004245706770678771431369917479502828754815568950371273785689812698287446020480951417047185190067265849637510591502642000414540862689426343523077229502494771352820057572619644085930901096534031496492870227890836816886496090287321502805172125273822231241073590840684742085641304915656543831190976008986490532066597410386596132766422026234488163435487889876791504407434387555507637783709991326338482319227500686541368087892665100076351075069628862376686619537655838590687615291898971286325099164241688147975845320979841704002364545072665891829427213069) -88455326811459002089798581395024759975871889172872668466370443703433800509268320055453743803627754859670391415348970278548381190662701716228279482045339649051139909543850883613464992501666524385524517648069873862957915620016943364950043289963237718026629805297916194484838158010754666017024585366330526135823515744339445036315966714684052345462172808299142368905939297220895721123725415007532441824406115746741972351142687017849809593982432484296719999502992792447259391592152463664807498752410740679664044620898308783634092355737296495489953554685938970593890496829484673393665321572846542839714620847185428664388282452532264810310019327395691530430185946743995669191791841546685206884247468693248673484055915613115527492005264289557719000245333079386593840592027314259) (num-test (* -10672574004830373997900438516438419278676753890756925443116289034080220708922677740383425352837266631691319394850521121221541344600832530724104047804922665 -7307684417326792807224298894786988180161884427390942431653062127076829842696634441114228528164049031680536693195116703321494895319862805505304314401000204515985676763063862569446064343853536464020413910728442475032187317639476018710375702206456631041987826826225461927793241495220512935434301833094232834266749666697332380140380619185254354273073522191066457437931022783436360434167505326773192959291779779370530770935758482422581712556111319611455306383173529090289274267200543081481693078804068524057891845603351773722737987393428313340760607600482724483853560340630587029610437280601010173185018227638972500038072) 77991802747865927212086621295493124451256238920588746597961055391511562690441964216934615500942858653797884925704270904527938466874924049039962754703188019915846345804228044693122758075602494985337649496117180241872910247079655077012999375809878184011356481981590430241786534827516536543734645410817621964035091467871491521760928486006653992134635010794346993161329777270345449763927429735191213854873362673179799811714902439637861750855639857969259787075469241319618538795721956528400353086156169058060112255274542232054021662809196965752800525093125763127895334967094763817500702626282397394521201385439419885607578137159972521677923972708827090645776826953976605193554447841693259586575931864396484621463004541561908426383260772786784541411548146173991869741515701880) (num-test (* 1420855003086789510813111205540636553863493314684153860389816109865085846062678305775289632805233481596171530412925552158799875183492757047174905459819169 13897739053062356545217161606361735964779941697726983959749295377836209520566715597422965426908191354971972501742952706730523748574796773473606175934144970768662226027157110240776527834790487577863781140089347362129598158760833470434895693782503529955845076709376071972727346128409008293671217324995682020009675316075606538241192607139905488719485728099428376369506685875348346231688684483781160648420909364963718027571565217314827671844485031440079254478598236877074793221578612249882886835580737423192061550370069895525711885220268707201966615936769696379335772521903910689934596134239331592980694745008817040569590) 19746672065138309742065153069587996891492444461032276894328314121573439684229636534026409362850111716212254549198595854140809664451286626009917828620279583631575940837712663100442879662416765138504151063632823014639305658882804073655537352377258786105147057375069447099908107785635606190515362082317465738205179108333064680370909383338688734129396788764959056886328471374018961975554190739706996184818378586233017775166959010668462907838359485424792026496574369912033757997469014639705459505746723512361959074802456098328538419933637295482429555127226978561859965498424173552676019033370307387047798600024901453757451579262061785051932535359410827170361533603618131510421439128567361259204833501190218719779570258541358012741265599985490513564378203502703406698160470710) (num-test (* -25117824099635104147178796272946098711514362630774369209876335291088434247131228189812265510495277875692804180473811834186270331245779845635089547499275113671007257221593872123397418355506777725721168216892830217596134983713752526559153149600553468865338887605949011743043425900799896245185282419637806859906582214420191794114207677635194054239563071023206500505880052007267243210206807805387341085613436600843317096291021780624738422589234020279836961194869688005260369009833026575446099544900581955685627511787510900479881434909308757027825050977932238481841909425598834367032841935054158448815026264505726593064239 7846111496222858966) -197077248428250572361351389692146917243277049539013604789802566767174747369897711991559940484392921619974209620152008632450612546796556905740493507885376190913893140368029841033442857949219716681475253727058707723386016055991276120001690579154370788782636181079931076758384034193266737114305362492836167078199155929937891579224024229182935372106924021709421948701131654358516297806197381566809357458374057189773041520552821330635689748583803171230633654728360451100477472934847975252390985102859262992904778849652221553818627134153578436315973777720706502751232660284910468721430874674021521629540714057383398858244828214000543075116874) (num-test (* -12000343217458212092754251360179138661969968218789048702097501439124892987400633614429800307263114371624489988815324366411323242909652002510513570900627875514001409309670202055060404640758548257776155562167062337394219073071639153822126554525439988062676648294108951003012550815746564810508912122306190725453386412796036693387315128514162061147675205485143205925649214342646148112549805850530430229663418469577245456944558387628002442451042105749848177325651852669794048215063957689756465788955050513359977166122710392613631703123491357791351447110169966270916789849428298930624807758982400706608788793481972190953569 15463017349709835150) -185561515374029078700596518575548896805308728003103939537818954646551372890610870275966055765608887701776880889777402229764948269089126750201922167386201171243298907675542965323275634529293654817279957832652909009385491998537031060285890512199675273422070784691446251899120095880199298512230290860589352290462643231396804350623684034400741386070220057232978556614620855818271117742675632435727751812101639747357642295230273344552327870600519422276996860893842363996198017494117619585153346745838853026029459826407782259598477529242420507010652705302341725948095720110508044256096963772599572721279996322424269691990173052929936294150350) (num-test (* 20244597897909303129995907707212050478823487084391413473821544089492035634291726811145005824559631386634261268723753786161463497881725871168747275110149007801865428978596190887145324535224079986377522166727137028753272158887188902047835658826867304220850429481233026043496635847568448251753504834367809877190895369288045026559783632709799678639927825194847005181499299410953860627694080906167346078299421796974815616608326704894611151743720515377248152215241639534004099341398238713597030368980166731393247619511322804984829747216779359780372801101821087516269912916462719248736442644433057333788741151270815989388229 17931151643499274580) 363008954869078360197158713265773114114991766614027768774402465306840646219477262855625957403406166192075865834283840624408916170935610374573318606346031792128003204902147985329385955814330782527184421959263266167048755628089412213360508944817963403092490479480264538027768728303095523018598016863928762335410109567604756183580676503045557867957273324581082608248341332512325136675167966306268035077761004923732568405295901819511346235524577361289712297365403327125212199451099538443576479787130510546755789504852631291774614010584650672707483555436445926222945298928326313943231688436271883746272589347954697213098866117569339490918820) (num-test (* 18134862906191691435095953372467318196853760384894170022863300447691250350836421337333332682828557871096554531436829166444150586004379181099133295174348038948038399079336722004125999533719492457544642570217406286811480006881054375314838605871238868968956868878182133492469763282800195060849734382249696543089869191257451321764806079423169235271658993054867624410589213892458246001270123109841429271429275464249821855221014782727398959126117031823977229309775211695677345378510417534328974531801634095862859684508240122911023047425473036305928743193594967362216559973174709883576295373749738633873828863608550295977368 15082354452174510460) 273516430292774638949326170314933525797985748367549139070674899956657807928629067317576809269188258819686207094298714770978509118959142516619521080722291318367607601498107007447014759288176261262818034997399866363248136237609824401265450913244758024085739876914482935655100890803279961929047974391299795570244708811454483314898873277493486428279875241232025231140855860469097028388778917980779775554139507550577255217032521719099071084956515691364008526064349956553916033914728254580848198941020806723485184338914882588931083516851849558411503129184026079582257756707601984686901646494090820169212279581209612798749779318126482639269280) (num-test (* 19213874382308276075905228027166553836726993832150876980655958901416537033385379180983129528081628446454583401834309285184752924794893846406622935494758142810049493348116192315865522516744262115026742103678965417868790607689989205765793528434388393584537260717130892518011447327847533083474230074174308157934463971640826422302901570010591182715932658037868980053012095115562188975692530473556182305847290196895478280679341869546292639446526021874910117953225154204035612531584978136604161393474554294315903436682283787080297348697922389355209790646124024053098888687638640826064745026930980189268652291562437512941810 3155416591710364359) 60627778016974262766014671335614995348970065077989108071534610098195400001445248886220725085881796599270026085183075312353388418711598523030563716616967792282609748819081238929738105086199457414615236966895805539596649555457494710621217412773036416007129418290246899690911654008867819945724649185574237527152410775686803449108977881160831441280833577932476667657759420192656716352190871667386955409426879693856001112340390304980532208752863058384169885129364117656404549585836664647784765508649117301622797243353610345828189312360124462238989888436478381583689386509617357901461416012201469794664889076397809504626996523928173064949790) (num-test (* -6561903839860415551587224953276060627466820222543175464705113686962550773423611522044145975606965294164125376820288981286542044306677764776675868357117109664125730405280822770267329297542599719353907954399688197248115043785617436343303277493146049939491224480136371029084354063731401026459653680017632996944506546122253686805764620116169065663214526857151412139439538335533979733329962892417175374550305659302592107472151941922230309227785266745974334776462642676959433923828440435340579340133192678341787895007461237846313005612116885419002449356480017828933592324336731295317076205553526568668826499450826560670163 14908715577157091280) -97829557993133908713082095435440645457469053259814412551982534425389603663024461131358343104414088618618030154957456050473312402460589893359522167472060177968099538846750606564761307960896264958539903740023783283814849937681270591589750181462708056758506230073751440847913386576449367635057595344744119561166438538811561109125506233466453974371464999669336530949393433719456191822836826214814780222021267726528396849558417851727452246676857867278196266042327956933753121947589485377148388716839519782819642328655117625818256334190717182923260613562191698788004591479576661108985313450029332968584240383859113741485244318702724563478640) (num-test (* -10378013547095983701124686671659666242518351347561698092030999302329372512356819420877395264401390796163955327080881297568412490286247154759694714275858127906305200295043241717769593877683535229411640745872559018085757273530771413156968541499388413497221629366848027355125816131586610997516488552323667400115617175682996681969687885201321292153656071894385242141321468096793766926179134511319941715949712230831768643024119693594235207988046511542691719002262040067921088838755337917414526554050602539873232518619281766327369577617796816586064895744680567067970817494102948032924671421242699225194947982378019119315136 30004910492448871409155105619400474385) -311391367570036811050052853596227388481520279736812036769684195465110674594690412517879149770622679377262288447706750813509857551308594851067359841826754786725926298013483569424123912020079066150719085450400229896983461212531213110847425940968466564079253939695853896434719530729030897976597410468081535234663568150722646854183317007227669132983719314653861536414057481478039579810285535699518386214012059191958557306338432321511585867535008319640705419431310336566447165302011113284064246284641707577414470505948868362067233709611758700034131461348997580441628136979257037186480770286846026250437141175360847735150981343952303257191661069675154710791360) (num-test (* 6311357747888359229575837883366949670125882865462293491587368290797766017168248637163030339387377997726585769250585768079027576213724941259801478313127113803503561717311996500019522893295813684259416551410025111443510215766297835872165689077882298506134885487991732718254835036694083204758447948541157893533099634169589161496492972953698758234452126564385255035294546278732684663873459439615228706684138982066055370429797835904846166362278557095045056472775166294675997320598469599722704075215700819354957397052721573993997624711445698656580401684113096559767093466880001548887739825916626416328760047783071058963451 -212654096583990292869707082365869207538) -1342136080095566600483524091094048745061145155430997807005186206704767933140306297188996797343723817220160636373424666345108189275851749622201429179882167381735732553825696482751584102093819432866729465599060815670807282181979889263381844726842751894916887860819210652174987999919869623292751389157233409465756974677789790982740267208982768450215563288024088369480574425410032306456026930809228182100949940216614156925537929648841127727165386031716586596638254705402653861723407930666152691102484352058909219619985877341630210918347460471644327858114815713557305185589162775699323253049631349906791700893878999711846225062306568467992135934882289075693638) (num-test (* 25104391676237653962996674810232896003857294806799086059884413856421530328279649263948893056601611073815235439115612155497964541323584159786678357898152394779494741995735881624055133443980324145256438160990490767324719276757840825641421547232460969806196141938571103617707677351907526127993230143577974386169402623023560579220343920203666762052525898442578990183400559087522259053245822827313206196194989095468393682721753147596892214609346047051670610252732846805143964713621673722554204896154742594858056891979146566683467510164875593192581407047920719605560716270697985110227952698114701527191421628561835164291236 -205991315859231724218751687295926841150) -5171286675233738337789203670843122752625713948587464573381323151628930998435518250812603433784823922283042037694290795352461861058217142213862777203850665369756106838860420507328654214723398688455622487003912073924323587826356928211672752672052670663842775836967587150049181838707784871641183683742967716787111671792311389517753578360293551031540853470719098360013225516593755039537796518619542838794169319227197212817921098393499332268929332950035803734983497370378852859829228973012039890600437082235032378948656232679080766068869430262740600476498399803176452431728914806536862849281928869092524387549297345184969051926149006293586531930828748109161400) (num-test (* -25971587288596053786734900662696128734726180676323130693160397208008930123341700520454723462226657743365779183466120836187720332442041321870351823609046027805781414454998487673927365486893294110931852680018706479684281928396163669935417207859889405108139261480861908067489849403284000981453574189898304616775302917687860062501465417706095450121596418236563421425311420755550335597318818628123183624214438801254105808079227429950505879366254661664881055965092586612702279548151277733307180663770432418397550642136953750720624507617115504303570076531620003848642167562950736271141440609700821621532583527124386811144839 -182748557863603655835821910989658558236) 4746270122419629115710902425435990509747636609113505336611751359043717100752575149404352359855260443259846554733621122684788488984010741203981300775978945529551335641218319619542248418128319220383298229263331638090009313676486209764655429828385994626323209879925281409485074778611946493692237774852428345451174837474328995186242262565013937544898941834362941815633750896882758939509605799422068815435202904271722442099465950700886702949580264958171808372530471918175963644209760378395316412115175988232945569517230829200985652504383431054550902852797293952515652017940918628980037316292352828228005975466732028971159947131994753006597870175664981312344004) (num-test (* 2117427896392849163304163145095251890404997781812823978967013619233450901604407363671467658244435728579079751353560538034596183240362499870272373308111405924505741579887345118857908796509418246599428633956038017783178050402412769812823236255234302205027282366926174916871858199918908361186936687654278623156607813451034087735179167324944824913226799346886951212979149617678949292799645035425029596869092844906629996914674904522806258932192931217652241231736891642224851547474205131131019084734780208254203537633402057673465583362982905095029133132240839391503135932501785844503813910210348239157828902668852795945482 -296778668392678698960782643314222141731) -628407431508980610909134894336322264939705333430111861505965183839156278363647883745193463537783397824947515214540990712455315080515980803996660089847066076833542492719707493333185909990202372284811233272987993068106356248349054482194817336258302692039392400931536481136340269417905505366385505196886218794044229758585631131853635721528813397816307666671727692971421531381290925317161326036075629905443938124481334173158440927555118173661486114828362551889594188958723424604273078091320087897088472418346754088900034854230711982602435635574895960156993014703292551046970069204857846207328434544990709459402656908170089318995291341536347275682867153109342) (num-test (* 24743327715258194976385899813930363006464428087412805068703455203318769863096919192538751530954777047772548306936907016751357570434930538612382851621309732767199276228580401695793317612267605312672263736938703887622824117576912830029817460033437752668221355377879837833796222831371174014543622739933433581963103361464022058091243110136610854806189138108937004805781857031030005354158991203388998364340053773883952742645161560754545458260688560269655272249435540890073696261770299845722705104648358053080678920468895189601731801025555650490534399590288852165862135571140382055044665678298182909026026068995867606241201 309156501491030456401354118244509785044) 7649560631695275371386748526795333430293346807872366006552933839286343590101586516802834568317627508914888989005968805867728947519409222814667350103434422356009252082456906520988877859152125402282765775845766265340707473525444185795403554160270722809642681642831847296672303556012796775586274347178092325226458743113317655523655255626670958156216225968018208281266858684283741496986683426354716284780229004376492833583965647875097951642088252875535823145900129967026856898970545720526282798418382467634180690243423325770596949644122541224189780082061715230852249880601371985342796525016176048518593825361248232406051886794538203297084423942036889326397844) (num-test (* 31345149697924857384985323414506591310628538098830133854928154990821019223495435414394178930529373634315044777562902565397455028894455733092896622048288278424884040917250546068175763309233883078972879622697667174865833277342334219810618450605650614585133187005110148963483824629405555603493157452295284935004578187488673124814714326405406894084902824045787647963172437833905574178160343833139650913077173865287057167288286708807322607983179910358234015596109655900840652230258122852488289951986129788952718105898226951651151495867246384586164892018870981480003722043190639707903266193064807571586900961788679579912089 2067227180806746570739122295766566373146995767544546241400900414826379465803168632854028593293108913670556431832056563218709444199286888840721753894461468) 64797545442006646811970698282511426059102976298051534827345388707272469591333019870381858263624490336448197115781363489554169207652559213486772008013638214870324260793199674746523791257170452738018910619029072942848422098770309928561867618844814267276213608306045020686764830302020953883994906997293368193331696747777630621086600981981357507299729947717565760536305785574555255589190221698706036770081438750974356437738060098906046001271392354762036427049946092656701257615490057677558059955825843182799904828201890893555678855718728417223845757559310912618029462136640226686626513375024547351747669476392735304999046232068947570708757930233036922714350584650744960478326257916948676866148362166017752159953504981324652709881831381637989229842766220141292801807437886652) (num-test (* 1965759082776833678304908699214846485256126608825750175641683294458978302204367346739996602241053060915897480812220051082619942907491598551933638540412113496542245474287364500698693202553692963910123752514310355402167440783023542848697962967771951714434359320001430281377747193083851165947498546085410216620013287853719686698746328198021011905482303248172483782066908570502837009924228011993318265674390462360820566174204659723461994730913995303015012684826295802887547970851558451858623353950391701673651959262042520584275132971807158231859672678070714276061110616753309305801080136339206017351200193800253572481467 -11092241138073130060021642325471345789108575712118027611362686690749327689527135459714040658411176246054106270789083336195599640521602432629024562630323934) -21804673765518097879589124792137157558586438669762099454880024920520894260754279593873244443852337739758694535682558790532827482894104906218015712179591886600693703465749571299271429989154199263793230178266758966678432691901731270899259065726530463438316383699558373053423999416350780342222940065486831353604365192968606300436304827279383661172824549131179471364227618431414928702407510473319879188990689163932586727702195573766225861364297410904859137393184592815970592502081722125458353280743087607273547490382023433724488604177909671497082747464946083901888849483505451426245881736990810339421864101129619181017696837017966116165703320918568645290788634265522956017905246042460811062666193790657969385648522736090098231379029903772234867701846824572274796526421531178) (num-test (* -4067457132547237558852016696244696525033953641638067592741078194074861352472861925779476293767777560910963786727886946479865734639031042985368829200802420611189793957001730656623744670821921724417176679009632346904384261431052972127975733031277489967119978909321422086102208644766894305071609385305464547231057263658903212521469801833214062476735046735467944834107695748433481665714184831786462886261252526036621257865158497049125410241033365487816324425563483999957660557670189397770488996359512245971368638615503320507431381893539767352426795415898379765583574977542068222040889423739693921998717145084904555464058 9635268828818063607505341812331931088336041632536136269505180222913464638532245578488168867093853062326136774925531196873279749483997619950077042084971972) -39191042921786100943542578352486285322085069425292685238158202937549417928185097567102615300826629615520476316505465412722375794150552330462353356124896483739321653441446703127728441315609093330694305784991844511900128172079464896650958648496336601612657347012294121239821167759496102233234525084695798195547141521849769350204659392602605928907953707277320590923278178152903602506284861018886300148663530071056792375593665422754923886137410482547324901798328311927545105456397213670390651819229021443747424183114992653572959318104053511452473611466305149349027962240989590453237778130260105665310067480846969449221473610614214933278048389171979184119355459010233147440293881252851501522689209874112819966647846701257081192324007280573826673895648273593609466000383382376) (num-test (* -22047771987573494284336211037167956208924595972749016352929724093971147687332865088249749580556015503923927321586913446367676445848750229391300778587369581738560634537089081840938984779012854694220894920437076215176060179241185151442003472788530160589267677502568156006531439509890061829154786579353177129190813899423306499631144919702707240832059008168851983259611724134448165201725432622521420667808597545410136493805873769372831833878868603946583848422310946469083400330960925084024624317866822897278934924368888332618046649078771617892961267312226309927786691384460940015979582201446635756024251269978545916298961 7481502540911026808093162425787184755732317118387068406204973030847892995155568099553397887864257088525242568880427634318737874025160499293315047534753494) -164950462146458057264341765173378248123415893870534274075422323606836246718538063890359159423074703472625232511667875897808555123518162244263016096627959208397334135559180524195701526029092734741010866589515172934676451385008535538102832400604699294088534999994990970130226363762230944961249818769566697211068918154629209895730969522747736738946126971914549491889482944152891334838234907190697109929512401661529882587076352559260375439428815896053844621297552401396168240947357044985051323834074355418902009161796886350497072010833513601114819625605048943438304411954380599728561071485061414856047768286383287807924135081902458690495890129203192613070824670256334683011083767124852354110322463725619194174195587835939047474059288568764831570274891727391545546467943319734) (num-test (* 22607201423790553279447786193696575272983924506336369475058795405894123712509544256099524616893423762658394830755129501447553593365768543361107397299007141714383407862976654294384881771985218996697067215804348472693636567074361380875512341556932579903687576929186215185312685712277482751425466251201421842248749944123326048360909954588266368306843116245625635467041934524547983478110533044085242847795585598341867070787331785945399446665919396062565614516404861115244243161694059679274045050270546536781907061002623188435269769778378780371158624481539046590932125320888745103158180784231722265376331553893647061533815 10075764395489719205294189472045365742345400155046712954334138069917417587273618147303160957788995022989479371576840422540097479703418600112174202202728054) 227784835187493343385594867881830022845566753253174983274076326016001091958812135049265213053390506720261776960833046225700903422206015373488419693650378821159134369608830936915027161415300759990632038898164509761337714774392506802504397626551196717184785586630245704512525844329038355790338277254618639554796026366029578805283659986085947726260520495140332204643887370987929304924491772630534558682402396784510750317396488402942581973350428066695976988812610467654886227733900635715495731445319565054848075104982244316563526232071957624002266648721592744376122065531440026836549316222728280595228806728872537793522244957258060730038589170810090676474272044568671474692128168357087077816573419470273384256552275636517940058764711467508281344270125535855785388198570146010) (num-test (* 21997874907846585575969651776904015812729615626636027149446399573806943459105370044846476738175828244018281160136531735881270437472624605280356112191272531838028896521621800558410217146758345955334174583639352151367532676985598470747138461153212653362188252002768647808852054182649808145379073620834551216386805267446360709820441771932135218282126427988826945094538034579367527908530151926679515746133600376612899354099328788736038811470295396365432559354070365548930628714861826464935305416998192532029724853617023971964507955475554955277722555849603716733374588174421463022213135839490633927005539569058361144905451 -1400498192750070094581812894241996480373581610489471746158083224360249880335094841398529960182484181641387946900090289855375996313447832474435929084180606) -30807984052781257825246153008277875918087659020905755686964119182052911551148620538090633516362197112383237624321406969368641524681503231262834662890145617622830207559490089313283375890353617292096501953380469351747504928597461154633889236826060654886877907382241867167198409355653371944304660938495445848950444683274236538890057643038410268234731745456035923559528706349316582901179686671568504971088561096469997823300883298811440849031903066114422309644669680078733839046643542078157684064686933779591609758494599988463628362190034612412739669041368897594110022347872452261447359402810277413572637740870748949093642723240662839444216981630862346445890780016393330114883270596630385367407921496982236074288475142085411632630374714528706189796772213264952893973677883306) (num-test (* -270155241925436273159477510619232592261228150696806729750247050 15545126743930076938536195287546926534964892301082800206802745964245668351235397 72127079799316080210744562119267314209211162112457416152560774669179705347659265 58427280233475514109627698916382980237252687770812483048907352594138577656301900 91336330475502063985843547526216808965829995610054777216888670176112782119332811 99495081134815818196404370468895496198561677002653930126818668800341380375657337 6904264296552316628911621065724553059847235903647375662685025031963599691416829398469283631386160328944460790101458427909545198569619131058877708293713734 -16074984786353617526516141164566295497596312655026144270863093715961484079732496604871734572736757225277596743795506589617891195569235287256031608792067121393492186703333733526879481948463529609113624075923052999494363547340563039654910799974388353472433635130983731604982117092991918514078659590068643956240711810902756784590442416249652077644077280371860780741318193975770906075446772544431670392964384669681404295839302410058434872964315897505894833409101781069230919347279857855594782111721176074849502391457684148683668165019969667481755384384017844104770253558111588611189351637275389688093074751942960310850074) 17849860827147993486644896214424106325295064110723402251474432199595968349198253682890653243676378684005650871261983711134190416277366473221365848417375107498764965893729640224952922241531788638514200018520970345581414705756736222535562338748426356003659523260330725662384208724142177900990027225665451069059291754155591197426279006090296512196415617974140965334686090032257444820748820516976632201388937358434205022475303705442914044454220818215336283948743042841946229853366515552653568436171217572212088935263340599371830215580988184775240338748954666846379831467518505260487989636951404886967842600777836444030434816421999334066711024026401362115623932221335906548647785232855815515579448393689650116225664467056283988125816950714780486880294535933597118808163054631168063568847830481653855357008353733414826165759079092633441356914450038756281940532159493763482047244493174370100586359619040444818634156576789665732998111907245928253704097384811414269835758656988678207624731164159069547745777423464124959379113843649940896359346515513936964849811155238140671698227057228045173997904545787593258286212427476788605370334985423461194148838623911634821153061693257996982252745844329344589168264774527631972524787804330730506700000) (num-test (* 6411564443509812216548163965666668398784964137255201222920640150 65325385402074288043601436729391841747319174569548241717675134253657593233436152 63305037198546989906433329294566491017476837189978173607681765241525113921707860 72383582945810879300930057856704905379805338886592055772943486702915907397618845 35525980101796892634292856352740658817031405780112750352735419884048051630180860 47579150292602967366908574298176357632207539947399443701205872093150879604391127 7775494633965874654516687741429737470333189902121089184439228657893110997221737422210698789286625633365548095171257583020272703565350668755439139356570 -7847653632223099338936161226557020783515367997970448568586056286591257384101422312757649765574456754668588904917800060981155642916520580540801153603733496143328839018174649200566737789874193483124577734129346933208306772618814806884416239295732454033604210880463262467564639515484363761639994642888910703066277724414372379965872478153546766131136324967950786993982228851928269842355632200589446224738709869729930285189047112131897218464505263042012855229737941639093204086147932759923796947642895167078971517834730472596647456786099215405165290569214043431009370032818978995463168133051136053246705694337584724712230) -197949741939898550383903354028842356745461597695099989904494711851411610441324234089773644533872304737431480244289438922163630848266242200711131210228027234579469457105291847132071566876246332653149194709623963836885480655282595345693084881617726426841183231475364991154699746506928116505297453355016975688761948609740314324443406930215518937775475617384099331839748494157863510168743547396262979908353122625808170296763676837551973930928848463398657587603606321137626467028732193151671337338929938959296176472483674270114824853018199281637976410726195357458134038379491704909997939715446657856320452698914513791221947734373322868574099599391493563479057703049036936132407025278683219316357543078875410080612067641232277376174351958080693019953378024732243763129075732499165068171168470237875348580987967740148512425201518758344757030205911031119619416763996490581551977913711646761182756531618786226541010835120092904291975494846126923510483263978074437667987560077422810120462938292680423746968095994108344184522240467647491991837793653579480334442342102339933473270535800619630342940590477752278184994533764839125736268376640933720554199782388890444619996919031351334561766248781813883867406045414518951152508504891407920000000) (num-test (* 1669833986019218156514274418186396165434871163342486930502417566 58528969848472951398118375496887849181512821636583415470809040929690124231959506 50098163184827557635697120379841225459445103589988345336880332217224622666020381 90445522698871905833766573423181067004916996574451008349087758531794463581708977 92366726802191504770638415639612204654473958526592425718659284841373421985393966 69096133232785816552402133765198624674167660496399099321713067612475604030259084 323971624832697152056406152359288553860210436839331005469891386690556929684663075996719803995137130737141925308417709520389528780839777347463558171582753 2635514624483961079560488004237441873979133312246005082134175818331132377114926863102436691793380965631848192666106793612266994709357524826644421074908075389316030912936338175907209987972553710900613011802455058538786723149316934049388525865455871552882282353445228425640452635081303490379594663330152071465360003249884180020993032086861074931796165970076448856988084523672973069824258299029863033098237556417571526135639288006133579174344589248428714474318969988990720790226604664141927030250855550010512291136517209169959021730625428868037074528890516086527430801590050720467893089085308995719513895962750896813152) 2413207990093478676325592386500172980330574558867366638913149256222218924700401110600319869300256745035993991818342784487193857053589994816247466074246569162659879368383295411190237107255160498774228460295857931362161062884154872938368166514128474751716517750517217000290486110198899480877593169193610813452614906598055909439037075588626529658637140089909227353944313408987644743661503976835580507054926908821206921014266535160031749397432350114673787218438589065861056449106115395189057409933330355574558853874223262465965933679584884152813357065227868165556818717270584803360466149860292769520737249610469675917864449261901859162854558012721179400237645357401213337423255109839806528503425658270050436129019270883446965562683284298538825840361267548675967778385927410390726055957928634152514415917053614892441910675109517307682075989998558764742821214685548219206933043196677521610851950501225469125512893859254575460130829051324112015464552874242522140166275233893076603452098841950130740353331198999756316969161591691095397245996664755249875720008141774247384884623389430842799829690618405724986702942913150258769060684255363816662231923570491001519802836627028431389746450987110456127797025006251203111629141890634728548553728) (num-test (* -6520062188352981842/3213004995534018829 -3812444292971845716/15284944374811818089) 24857373879807849010516976362973488872/49110602632729971801355498746248797781) (num-test (* -844583948128454879/4750740551331102615 -1309778567130405125/4885884698278749707) 221243590680205607733892613510570975/4642314113048197066962569716783636761) (num-test (* -4579815856418431271/16947444571374397297 7990245706938186906/12540719430158043191) -36593853985314806270746820601513137526/212533147427761354206383017714519654727) (num-test (* -3587966953201943536/3194797554208122281 975954052071387816/2707062718507963111) -3501690886675668292903668827990357376/8648517352177231144330968693325176191) (num-test (* 710265334225408429/567023629756400552 -5578988760400430103/4131535930210536898) -3962562316545608552741467762441538187/2342678499616965424161446427863567696) (num-test (* 18305319006789031727/4480148641441744463 -1641093267260986094/16028097657311023719) -30040735777106040963634910981471804338/71808259944297590021537032075729917897) (num-test (* 522499067029593907/142530390958606446621834761330018829110 1567459634764499377/31663510497342378306792964160850079086) 818996196770998943862055820464495939/4513012530308148429025282037949729145117603192483641232823845248212618993460) (num-test (* 6214041481074460220/139497414619784295310756757536261769729 12187470171919324678/129216394212432939561557938117593031955) 15146689039532873328968703771155061832/3605070583825050709361064709099418651298807367637359842488375232197429738039) (num-test (* 10022419596195177499/91129297586760817507648681092594591108 239769653037576215/24086455608554015268646156321002022494) 104481394312031409685890479072416795/95433990476618390508514520731482064738017476445225501421324446942302103624) (num-test (* 127731839927226607/59760640855511386051149338950192132591 3679984267166095161/269870724770589242613062477043917992045) 470051161348371979221331000573148727/16127647460431744118786930146746069875784110572380855085272434637353123238595) (num-test (* 4919926511230586366/29288587285987487013553554568227355149 -2914615432991234299/34407808954885309804037535414452526052) -7169846869407694119621783007930483717/503878057947370143933800273784055481319429768630967123178484618174989420874) (num-test (* -4322680734125283661/246950524730861178141734701180345535020 11581515233057355754/82204027418720951285150957025638971309) -3575942340708251875937466941988609671/1450023407574517046920597087724458064116343346221474061477327267648859624370) (num-test (* -5552456004563371781/36434418778024040927761226774271610950778609263056622471030041615086459120568 233319937833204741/228703279535756717601739981368829304509550463672786894384479957768850829340) -1295498689806330283646616799874813721/8332671062513255913250553083541810221054209355142441164334390514659539371361850837178162594438925276666798780352514152276296209564179606228713851865120) (num-test (* 7279569964232187047/36316165899095632459738478614507512808578186173163489609755035948221062420580 4568992288187244990/18279847281938710983382796940666233712517527808023718591530848159479207220137) 1108676634263212048809114991909788151/22128465550033953372731954247755694375180631486898426116907313824243654714198100644737500721615620412852035450119116976232805701601749863504629937973982) (num-test (* -8689289043809733973/34365105035540924847908154205433563929060132734873649554594240958996510665976 281724695877043289/3383396067954681850718083474385093262190311835985400909911383280975222535225) -2447987313255021583629117408894957197/116270761252098802423406562021935246701911690887646043563899994409915142686943691634418411056232663942535537938126289647041118885713303684881867869004600) (num-test (* -4176416206981759902/47077361360975682486641492558477246171356187409295624938308162261216397376441 -10870319933050648575/51626085927005484523186190379579228801774286705829757742503501130303410401261) 2670528255498212232918897515060496450/142965876637554026205455979922464979254073063785755559223760631646970673683621524411341782655829702451013418009338618833412062193643308417898164204593653) (num-test (* 4496049401725150702/8024116634872885909638996643719901973664008349644172107626390134736213108465 -5231341280619167012/99267989241776204190444307671763754306088564051099822830201760217121508089279) -23520368834947889555464127765407042424/796537923785319116837266627763277272873506235001122453584405648384893204423914484193595265931840447141766909166026026228531619859740155558402735330646735) (num-test (* -2488955833769033882/80573015130339486598712021266263458487997757617589137912729682647628329090307 17723590657579960683/79078600039601362101827108583564759878924923849842119643649415446502020994810) -22056617181258995266120581914227430703/3185800618738432636378738398589185111057563002909241393794402306079667392482341108052833514927720630087013771419748846412352850012097731569487991234153335) (num-test (* 24410613567363183821142175154197794689/2233491913446620869 -289777146895293391500645889398422195537/12394177861163531771) -7073637953514043162500219088395995153310329907185649946877180402954938102993/27682296026727883467940485833673128999) (num-test (* 15029397898618080393623393093137341347/9939158597399833599 268484092305118852707129202725716126526/9752180454987984749) 1345051417567645337656755504737828287428006597367109244226136136424901090174/32309489404196149853047846865649927217) (num-test (* 175291724581304230067306380062677652261/4791591464449055089 -207911166974886786162808240992513636954/957635297799905137) -36445107018739410292029741836217649994267718828374576884161821761303211252994/4588597118993154438342028473487092193) (num-test (* 208446980882041538439350888438428103817/11756453246592156788 -99855903858077543170703702663212319708/7775813092266901197) -1734555140205305628415286772698507060801514301420325900368570916304368260453/7617998589456250715053087609460739603) (num-test (* -49595797981179247160347259926801311825/16426101929443877636 104499598328969971414586784725010079457/3085074725343747115) -1036548193567594227670217621556353400490405002875929378150074378019016735805/10135150379689493069951723318357604028) (num-test (* -288919818051255959565698296502103975540/9373352185361138021 77343596824463059344208562767410464067/8355013728778983070) -319229970313622361785032672064391711775428287673147624981393545586243098874/1118778374191039878067165437747032921) (num-test (* 301194765217764762175383920433701358543/150076401641721289621709469985978858175 -109319143590504335906407585568245068241/158084148208214805386290412276525928977) -32926353787549066990014316879429253235742017240010356390402491456481443332863/23724700119685440084214937112355810539035473428177368317381421021523605836975) (num-test (* 14575317438235510996984657523859363247/6747043355688580686998987940004831062 -98472042392613093668204392119412188287/152397803267436514292317070561082866275) -1435261276663720115408306632770383012566806521695455296458086302958691687889/1028234585957093005711368462502470683211464374115746651290896689614112234050) (num-test (* 7543367187310376010646193530301789591/61115754966424662873097894247178344192 309940239796651595482411737112678240799/200261667764086238794802895148430893795) 2337993034909171213000031444662193658341848356694420878002930517675329723209/12239143016237439360279809707749702660797878084581096344749106125186707088640) (num-test (* 306232835922656327867425959604977465100/55646521674811091128956181530575055283 45245255551837746690160535427248646677/3669533234425940180962041078287629087) 13855582919684583969821610044729507626133731299765443289084519977056998472700/204196760665922729081584465192637337445710456706084552841012480810023816621) (num-test (* -280037880297253633994139513185953058494/23798550327416056573646642830182072429 13967268482262630670960486883264178489/7947215947745048068401387767511847243) -434596028812829556627014314125713048434599389957141408329542154357763726174/21014690966139335562014814134594464675233042588696546668504776333756662583) (num-test (* 87160410649223805266866345018804635271/204719779683096591635231158476535039583 91197762560765392928084914476898132964/277206223024759381433146631560580134513) 7948834435086720002947247338196997812861466884983039250681993725808882173244/56749596904412078223459353928850191672356004665473536520452927516595919428079) (num-test (* 272801380449749740391855824723351316848/2170368723435176720708253536680067463416474841046765138040214254204061862261 14545537787709209389572055399030228996/8381323291479119825335849511027103148981778425333781230074116361235206363821) 3968042787871071204066360146704950989545352280096012736206796950415592924608/18190561932825050861659739926693806725838682397154479213760300500132465705680046683155463862909993066621811136554677896021527098482779305371951555659281) (num-test (* 58980225701104541897366713189611773567/10973700523953435846969235385386214078292603476932194022615006557054104506344 21633357583056027790037764923811848217/41236459355840549300942497778444413350482341379076368704834339005347182486274) 1275940312921345964633100864283753667394719832288287163056787891633576680039/452516555639171997520308257003811683819837367444947027711901120987864272999978391252372420644671039873982401560595091423172287702745925783369137325922256) (num-test (* -39569537110370574225194522625562874655/36290593978404925051095380486087641410218299612051669925683823165483928853304 39273660356839128453616088747231247259/28875229647500294680887983884278577441525691250738380954940513956990510132534) -1554040560950035541902707236381071410695075315482961522429891905381129320645/1047899235170633560739863801929205639611958070150694189488499584527041043137082563721218908614201921449076002548982308540689571766482794493357171683792336) (num-test (* 8957762734053174688386697837976422606/712105675122280831038408324375785815130945929819518342973925027507219300067 118977607972668646264715307919875588738/36563306353035936296510796886853084280648109576589600551753305930842020963283) 355257727628119695756412145322380851760544279491883270008434507085780737076/8678979318410478400681656718586483785992423192579006235728835173903750764880944673586689792087386144715446501744012435157310426693657188196381455479987) (num-test (* 114386050140129336980347743358441052599/11994188887964574384037137314302737861703229337059619512751326848591488081229 -50822174853799566513638003084407139228/97406657802317796912648600328217961853548397771614449630742570869667560514587) -5813347841057137571369557065847591420664634372223088557679866032754664253572/1168313852626327929522799656188055465298138284154709873285311568978496136227795809646907486798429717114923178357702460243511883684964123937654308495387423) (num-test (* -22147677230189664783449572410799931501/75580058176304394102183955194485040346816524663599269056794063928343401057143 -127672554664595215026114551202414743739/35777311684781371234035985601066874920871049301826919955489852676067316906014) 2827650531865200718433745248471704607394596478050653604940563621773668622239/2704051298527551014378337257898371613519363350219566689647796093438747503077807722203668806231503452508016974614236112792032033672965127824348803574358002) (num-test (* 3468729773587632113679855593063165286551216344725198121609354788619580819847/7106612002452012151 20863200733446307102600190583661606839853255577505815215312643683864543217073/5700246487811068117) 72368805556440529088812813715602124890901251289457147618293618526488567540302416253970205832659523238561757581481150988870947074663135867252252227647831/40509440107213064064897416415172689667) (num-test (* 43306673717838918980731699770600730039727453611468399058203483818093233880231/6173575908538565981 106634227988568775671050783423559067905086861634892257032833451008548321218936/17988169594879808463) 1539324572884864883885215269788177741067901747630436643318399808029602335378536990210735234944615096105103848497832537965483619535769637171783464984418072/37017110149885307295697375341989232401) (num-test (* 61636028396239445662576777415312348317278054920190931147781159688109244233565/149659999183936017 50280832809996410949441105432174396823883728565382915986396125237655209339731/3406752842984125790) 206607389257567119017662603624829733217835095238758046754428174885007999774491792658838812826043033826701244157167565054600950156595290052398436186551401/33990308513391731439280046802638562) (num-test (* -100579490802304807750359433955474958462342659278486016345156932756807754105945/15683759624513404963 7314396152134987983181095955389244247502417255088677055075146925285457081540/950287995699608967) -735678240508074701153113537069655056596152436111651040530896921701439724727486696483134676487497031899584038731663111390949471467249259023050011663755300/14904088498613295322494450308817103221) (num-test (* 25984831699359211750216710442693374608159925357093100400945034699383345074385/10463598404993207796 -2395913226491242076662067669730978955981403048697660449593722338244504668974/7015215522730452775) -6225740195664363384298636893730784883811595661227613249243163802476751022407971476247993440178871949687923603921101094083879668063131450147131783163099/7340439795432595812648347200273983390) (num-test (* 5173661857391320950903772549611256023540539838210520778403003347430938670915/2590493168574884173 100300641976357496491877756123729102910724064566692821682523911939220592349990/15304416107565779147) 518921605664943617990486317157527087053001312760892500249127957517476408720600460633868004681188890038115877413554399588737851074382787744833707113540850/39645985375676570588146199684023740431) (num-test (* 30299639015164203561126609159677900559022306879488518544803392527841364186955/97638167801975054493877206805944332747 -50150465496280036231382225902610460555496341860773955714344071185921583266663/170117675960786609061777750278261277482) -1519541000979732808188648781832621044050652591754537200855596768903085847105531546641139177813880505696192826380113425984545675787584857974943247950981165/16609978191541300835961154615181304582159561006676548938424954151558306303054) (num-test (* -34494394944257769716276791009665812125094062960425641316440943461722789694119/69239821080832171466311153221314488591 -68027404272124217088707268142523090163964888591405843143848585935878552833247/257149529774225346004390673137885895872) 2346564149995340998782934409780604815295734898030424565252099571337345550054284934036215402972664245125313098735082896555892607540059632597741979943574393/17804987432587488254198543762235568841018786223139145264591718687823557996352) (num-test (* 22330754509472350470460807673039908304726422770752644988051418230315708975569/141163736844241522445115344332946835969 -3776092949566234532895208849184634613770861313997034923686862122594334787771/22367110097535579962848998753563258272) -9369222740190326741203615957382420344247102784278353165345406236082475331042528539717966581690645628370939381978953360215380653092335198860022382107411/350824982641632215769272917522017419782283768012468846380070797128085153952) (num-test (* 1376215273451682681102140384578115142238259557166158859699272578561460124263/3593386179017642636485249017714833669104405991325015697577507088650274886871 37146275008876311604039415809582675415172661567487888072055609579242279390723/55424998453085285819414374477780690192979527887019008768378662580126754826472) 51121271019052119686352858568900325361226598163234091421115939503875711782442415328681175322030659510284806538410228985354770913411724825992699509412149/199163423413390889071651575953261174839972499014963134990506980080139461063269751906284862132821075544766093817070661266293471833091996501160433036049112) (num-test (* -88175289711320073148300791156190227927348022787624424521937188958291199926437/38194742314758366741668899229532351990874883495690656157862650973602784662629 93421911195279228911508870033119580111709458306921869937709821511660370035352/66371395138592894543765954603571534463846496049156722497129962530412046587003) -8237504085028962150049531747535213236460729066521397582683209771842938254589363802757604921456170821878391951762499073662677974506165863935238701489400824/2535038334389561782321790943041741331416028402594806464107449488311138037598457377927652600804722340759363172755193254192462811091332303758223034251210887) (num-test (* -88364214910455569163017945328431687038422451206033411348821431934742389780753/43010507830592044720656702803904712217809857004582018186125828892174875808576 10405170283887792832024806983921158923908589830001636723872220129826733402834/4055629711949631304631599195955105801456753694558712994574702123032807265321) -459722351572673455425943766571506569631562018487574498847133029199411842205331593858852090421782204158679934054007027833206633183796877753882057444427001/87217346741895687976684378003169607737518608233754137677854312677618987931466495788077930577814677920791330694741284253568592140275298729115088619596448) (num-test (* -1412797070596191471.0 -15492755620416346417.0) 21888119755986895161222137392796809407.0) (num-test (* 16686841096925954110.0 1491135775021813104.0) 24882345731730524499708005167300657440.0) (num-test (* 13262412958100188045.0 -18379071970155621919.0) -243750842254847872704698616507823758355.0) (num-test (* 889503034794263569.0 -16600674457216690894.0) -14766350309325860687849239111838240686.0) (num-test (* 3148165694020236318.0 -11771070679825280729.0) -37057280896113409834434531491271315822.0) (num-test (* -4443818546267181727.0 -12001052312087213799.0) 53330498839175802532024121011435050873.0) (num-test (* 8305259347214213793.0 -229351169208067535459370186456659711595.0) -1904820941859811670566233132773219565154696335396051029835.0) (num-test (* -18273334758510166901.0 290047155020180552782039318570071650475.0) -5300128759437251944808204783222405076790289915320785927975.0) (num-test (* -703280433697652940.0 91110448009482115063492795153459771021.0) -64076195390496041906141380919369524419358692517527451740.0) (num-test (* 15279634596127882146.0 -220998726467849290098339792307263567896.0) -3376779786638352686104608499923871317791563686466157184816.0) (num-test (* -4472497681184076830.0 325612942672822430032905460436166528379.0) -1456303131067722058341139305566346079551678140995111358570.0) (num-test (* -6180420673489141029.0 -161157288800853703711204405567379740552.0) 996019839388256252540244286609069684717518686623358308008.0) (num-test (* 14044956603588468379.0 10163190459901171254101452124764637970005230126310661589196828892266636678427020930101076689732526935899135126391465178494895371156141265424428405590113790.0) 142741568963316278148132287599703960511135825069792278910440475692913696263448088587778211787403889397993501704943449376875999977937418748662459138952952917221024170426846410.0) (num-test (* 2133283347509865817.0 10577710515843519541178984366353275630877942729579274295972091544607384358263130633386329706527832990861547566574369528634541156662300858851752195966167381.0) 22565253698228972909216255630133478029433774404794962869038558824053350969301054394347471181756471783852326407546652836376109109470959746153989521923555764579738243072315277.0) (num-test (* 7812722507014599311.0 -5055959518947106416800910724733658104378582281318226107212861190073091017493970778425583956006925004399967175604321778956828368132273155364830637407968648.0) -39500808728232764770485117356353304373275127104839804121600969932458363071148383405901570717732548020267052999198017578112731079638156026910705662052515278317807704170401528.0) (num-test (* -17560801708050275829.0 9842515227842383346577123873881045824143545509071137371075701856197189100217561683579562062872293951325890789283651221922663521213150065638405410634222129.0) -172842458224605375239887212582262805312641302639067963604956593404910080268476692854082531021580381176489626536608405283010496488558204787140272050713264572452317265305619941.0) (num-test (* 16743386830114877156.0 7347065846171565625701636575261347705942035850951855454324853850791855951431141198155170102434274509450315416946729031216385536668189501958761688618635668.0) 123014765528775807847206414290825117502032199391400884957413813554539073118943905948723779020186281150198999824020769031248882909461419778092564985979904308229718874140000208.0) (num-test (* 12697192948029671719.0 -11416780209809507417142822520376617951137069007568339428552592261458272400645205700952156716454820410468812274673183389934216970221062627926131479014990611.0) -144961061169197993494569769162151457365959287966302572862364500950127981616038900865036521107816831702945678695331078399461327412574397914795455218447174498277798426197230309.0) (num-test (* 17005139720743105479.0 -29990519259587469661876904501488342396062731024702923152492275204626478246142153608222329335341363164148761307659972897552084842238285026253664841395295138667328930482145590159132144957515157474957872335043653264146346772142483721767458961320947069718037828473530001033848282453826154763424789967441239969918856795769965946388666154136004597297855416503729657013008165049478441197537144135384444157408972370236442813734429031404855591324183846423588871065272526864866155918285777640819778251612915859290336548446745308788013234099839998683451658620461972798204104633072664604846231692505409653434538208644416538994256.0) -509992970306921990341332390474393215554862069848994183152714032617297815196921655222705396130464246880845576204295466273071779248718654338767559016551390771145212884412809612574391658668778295682412755916528976282396155832617323980694289208942491001345059122414240884660276842648466533488559879226195446807748573906940273568334343093922652142252689341425941673567630236228358747411926991658260241924294146562230425295426217833820067881064577380516936937782688004146531121831211284735538742160763820814174631414364095096099434285754767091040812242751724012532803037860394426031234340719537172735695313262283511554154662650333168783128624.0) (num-test (* -15877530153400521290.0 27863984127681242643954505352420303514833683768731313003271701952957204538094398204984051331105594788039352443762851136101330385230866919393696564428736685568762923746771275677491379334452751710169529933675128178840986001684425353245791752781476028565228371147542431713985092322787978914276414008774443194161599919167210582437024618824616489802661351916633993681556274980075051797120207655478780052593534285265078265845445633803877185868676955831374479850746658711791169579387317321983669227930929736238215792068273805543745311609083833407544342964285215427999724272264458975101474080574470499647168865409458531868592.0) -442411248181132450919255517905812929771246981404050821923231762557171158858876183536414772404562764742655092127161703706239729646027465795612501446223663310668879007072125975886873343449629108246953385822769744013416908613100114754904323190537317463286500657291202287742354250227377164455244103312266617146454847578457073139633297517170508179596166314955134347046515455569689877574427319658085169791949003021426613961459610227430636932814700361914589752207776142403364490846294795496119883683491811246550808038342285518518431538295199537270236275774546666026424361019715280652576803278928827199810150387207105149968313623040090578323680.0) (num-test (* -14162897687527555611.0 -23016403916121951319848021112075986869602408568431399211927062304968548663313037929311574133954267816204873252195499803324830278637331653769648377216095499136975244697758388851688873078022850203685120154634090802825656419418077380419130449990938627982123188424119187922828250625318327074513352279785514062876718714640725789938556578327139793467832731546881422469843509318627826856881082450937188956068348931459011923844607158528494902828851692203126881727638511348944908726926619613375594042390434147948508706733126737304560579515324106834237197081860910657003346633962662773394999353766192391746258372744063777808796.0) 325978973798843759388794644178802841408656469654887121096165875654577046313115917671847505813174070119516580105483409446057747653173640660143855580491229746795572929387698247460831363721394707501497262525550824977473864621747159715947297817600227665840640555029633517390896890601028716769035575763283168066843141870124768085499453574902575378368669494153555135898430469356384416638130459557518713454927909937610851489821263029886989981438507377741962130296498574556444168140838201069779040087521405032426995145166201901368032136008107323350679784004016321425234898132080844200202007395427054392280809376612533414505539109579739614954356.0) (num-test (* 10844738523441551664.0 13010289169828379103330191247192587220592807931898339555723704078985668371901953113936581573750666143303899278973814509164982887504269303358034042953769514772858989849512527461308415676004712388964136857232374888643347097138114199889581495448978914022318770898259317738823514820591042321773469959130347470144905381758960436645008051488666423115693738341045851119808222048272924385188356021826450267608127588500233526688704136268009202730309974485584784539415807259862449203760469406037505772435323036790641520939576046423540699016607317147689982042035523118533555744274806239272109508745089640043900389441390176681340.0) 141093184161152226992592021994885140117836445291515772908453669279294934817987511015413332614094493905560980363483549300117114491702466085602279965168041684355125886388302948336158133555051817733078300668260616983283027038746214728386770752826764135491650323133831923154477800324207350667020747545837613879364064704092093040155243919335078139087599906324684688427176309081290932504214653249366429592335409761783188358003723753633106574740731573467850133547164922532633897844647383889253777956821171583261238607289172489135768839436605233457738153233579088224808850428203888700116300637190661108848906846940291749737998056247719674749760.0) (num-test (* -16402132873169057380.0 8202725117980211375579199554494319645475746305836527475507064811368616698686329266053570766100878145903342129595869654087772486685252653587846560946850102095086896668181099435964053041678323706849735936082196618754721606824996486473796843333331029865501790248862590712245450877098960007272754260813822886287008295409755783478345202299352891066800825979067590290793893933819913530599309037639082839491869155044147367415785329077864525961799400923643936705317921900308490987828345313709179960659814100113658528990241758360711799009722683007157350272749544178688961738222930753008443755881419398858537860612954576778456.0) -134542187307192759584182063854799850608007421111316277594191532129597970622559949723743396309231347084450105499455916612009290113746722460358793168839937004812915757145655285798961178877391232945062437277255128401572171216279188126380587081673725314534095093062983435026047851041796084651601813918099532876684901239903769891552275465470747567830660442193995685219383258617057944010709906130655663966913354414611799232001438943448374556294933488875450563987147224709383408815994320229340710143082135667640802837699940654151297907451396297241124380508001357553893328703788960812706653503939250831164194874527033594779746890593262611805280.0) (num-test (* -12094905083549825231.0 -7303327854122277566083382629094740392048421584433028903125893639493993705575691832165314461496849401726460344615713884253150283931509897329926825128629833541892164122168618243719393446304446866677253728405617434021389128710195093788280203239300086905325641224801020413858421914412156234316517981228056539721130386645649016559425091470643854813419057026759188125291655398451427686659900364573485593902992038773538760663063071699966278379037038361219424927031644750173900916227834573604566165762753650347331082640552394430002401423199016978155236550541225512734287851807727860645247391524620773399994302380387697957581.0) 88333057189654571362020288527489792875655269960629008914349561689924145109953656394378545526256758871407020025766992398117775520525507898420898102744530402370720932219749861094609497366188371774072368034971851022164946370916317410415503705484491514312339956381120953283812334833067601825812118392757289250628861166579446800637104996060739031010579056633535166403083327528575504427815713481850979373113173151813491831551023902022537957860211597622343157802805275942920911544696695931809085743355666792408029743911424760065578742910735408262758198787195579745280191859776661700139596074108035867940154338953640690242795671183308201526211.0) (num-test (* -81618231044418675360403541307856740187.0 9751573706924018395.0) -795906195858402819552264165081526765614024708979523739865.0) (num-test (* -167600745660011044249531125104202473984.0 -12960244919927910377.0) 2172146712516287908809731894157839567367040369214826131968.0) (num-test (* 90306383312124738690336097936949488486.0 156109477991590792.0) 14097682358164298866835386043901377722456291173827620912.0) (num-test (* 126202800261728727198105694812165074067.0 -17404362862588500316.0) -2196479330029905727399352310201914876903532806486592905172.0) (num-test (* -80093647977875266525946940496137725572.0 -9499399805878278852.0) 760841584053111508349403804472960020663660465509267203344.0) (num-test (* 304052889577333477963637861956318521374.0 7233536405885618691.0) 2199377646072361697737485358722028853038393128548297401434.0) (num-test (* -124787646062877233829165925777950698937.0 -125798384154373172164515376683173327013.0) 15698084237137783175768362160964949930745617334715009097620154581879012485181.0) (num-test (* 259623502197082370239517374851053110076.0 307089583871541575627915295134832918432.0) 79727673252974285068387698133566605944659309374400074880377824560177225320832.0) (num-test (* -245358177397026033963771466683003477163.0 -285087883756432161967673595037725276963.0) 69948643556453419103498093570621669430956866597291662675473644085666220495969.0) (num-test (* 46731711386059374483493216849082745840.0 -216522280665540473581476116002923812173.0) -10118456728713381305690589407461434638634240429858378588644634276171257110320.0) (num-test (* -301422430661955757433852743238845048860.0 -737194742467573013847855072675441356.0) 222207031145790358162820429948896977201848379524899474475604149595884654160.0) (num-test (* 109781582310220385246795023904554278713.0 -273317662617851276579672019029762858338.0) -30005245475518685175699313262818315773200953201653075289648004177366787958994.0) (num-test (* -312236719893391897821327608828679767006.0 -661158307192284418474080017860142217763949256471548515134335997907628404839044913830388499435166012788226998900468665646723366842553747501004752506346280.0) 206437901167986463762021023207669068873036145952740267172145693855475451354717023377588805030022300923600718715029262618794758202955817341818233889201852381575043965927328029955969846754837680.0) (num-test (* -134379788461141842858846278268259347105.0 -5535479645589936472405910397299739073641612836770238183712206042659632410776896398062277742229906915852933418684231779996404071421767274180368154310128427.0) 743856583805332082970350662728998610690268824090148728726850517499798631519601137183443104910590855501252539324674812560702657332874686395923181633958702249128106139207076314713649515720653835.0) (num-test (* 278271843790644800793473851247546123375.0 -3845690285506025443856370771250487683891303505653819308540635173436088084480277686684743918745832832765066355874381847690771330587033980524869033600561589.0) -1070147326395532917564114389205677334125034378502074943828571411806344559859053091006175486397820822872698474899835730026158782698085673635033947150554253148685482702599776833910878579880042875.0) (num-test (* 22345490710865165412267189692679994671.0 -13168094845644809414256057134926669929759930873747535851687323456073141938879368460977723280750841588750507348317544461824280674332488497533955177541413394.0) -294247541053147552931885013427268298282376074124656716577088212043667912662239091316191145352314750820026626159649861330384837204227899202392764926604802655267738710003310052268554637728023374.0) (num-test (* -223445051950608517881717261787296926498.0 -2609806601119499724524852022247741111662431776874117401343811680374867931883996125145979162937751368655661775097445043144114599069842524778189198926688379.0) 583148371568187658089071213924575304457465978545376486297236105670932990897420147110485946155066725440999079357995678147717407410446012970360780626554347417807723098476525833332400212113766742.0) (num-test (* 12604140228725912459681435851589379433.0 10671266866958584640992033560488052420339425977492420594983497264069815016478448589306666811246532193922229713077112601565462530332258877522384022088660628.0) 134502144009302626262781543880199144227907004673612064586081220538754991037447647926963488301214672345398823354945333417956344119228084327815583754032364976497975702972112644238248704660063924.0) (num-test (* -221289678591114384943252477126208006780.0 20020996887149770966522122735176842174467884990518978494604707026520269232864200848420530223248762875769520715632742683760311747174524709550334825291720803698613541109690224185041740294906022358446325921538593105347423518731748623037078340006459454656405997570119591344894717789372844612253617591807770017562530034107842444403952657949565007792107071767260484233194674888488789619319597151367813735192433631007526015463229060702510632792171187339118004038505860316305860704455466207113207893106982258864355430481457640304138738182009363353560090082819036973601710432437342931523433079941958203038050750205966472435692.0) -4430439966231074415853738608900692925851705818190624801199561884242897308817127146763274284287396980593383317678766559004881552228480591814939402896201244425805503258878061459604511214900528594870260206969839682573246490602076070316760182753341371682323914671418233629420599310422437691170629449435494697829163966912842611408632129590129483811802031178053300073562716917597174161526976287351465154825036851645956354853960835948518860624747958440181683978083391663149733813297698623499283645627889274004656942800842013709298338912226207338477579862672216831422765369078886850523202897989792734789430796029206661261129141144642117177625405158700499049991760.0) (num-test (* 180785619668676509441152734583033930295.0 -11909038209406834057075682058438206007134213485822042209417443270921391661498900475635417780140585878716264253792335317341527677051828500780153492153490249297998660274828986996948999762620400587091118252205695562417522111840305140989214300921122857271717052213225664738544344394774362885331856170636862181712515248810239601812262573113794334115259873527539564296101166439562124016438281173202196876398090029995104489712272260608848551754611421227761245487365953257890749115194455096508613617028024932657498899001119282498614739316599704645009607294747043489655424155986912576002393048535846081096337705941547991821928.0) -2152982852345560218506186041143281789706715672110278207735389192913214838321097754496849942223194392302524369156102301165660674797665128931611291246607346536492650554391248756408556789391955568308599431054809433808337036546281323840555452571430884302696950144068129601527530304907460164571704857360215834011779559395577299313379666503707563751314135201994045874159291100986903645360754621200008830207429980872071814202801994486961737459218017354210479544121100423399040398021780750351097082070296255480707530391964970754186799748521538525274241709676878827522138880241734356460339681718690408853314007343934035505873192699052380699509877559455199604508760.0) (num-test (* -196121729286794751535600080816329923561.0 31755463535476988506639447113088283661031267977524968610501132544098607201258848456920865390506381665724254592728643925608893982794532243733117636645689751360224314774452374503339856173343683819017479955914451013484169313685311530532055735999039466721411777061709328450052490025363788971916050033904534189719389237878257877112162843506491071470067738867693853480174965212750301808781573369342701195147083717623066339671595077736036738235636996351642097684597005928843274525502529735435418805821748637387888409663397547514467435322454217015563134545731593492200855670248739786405074231658957946422903165662016649229286.0) -6227936422881500100190187768375947805694946596622670066116457374856427496311253030141271922822486386675428302332027411428470488965226898801659352566022706152307022438261392466548357753526474097246042956052374187605144719189465046544498482461077851578811186829094445089366592317045580466302238653533114619908864036973070346979261546801894831273337217021756025770590122176562027129481076270727248949609326868225755958667670279949371399535144788247565199415296122873444199709788941984099349149684384486618280260678252604631431089580057102263617056951788273430713908768738965854953667135156866028646584137788146112300214498814212865170902491169332389942607446.0) (num-test (* -149247491509558553673630984739524508601.0 -9241905448313719916485289537122695595500213295294799660583133638026091750542612875183284894676615989153030773719811347110864468582634048542108726080717551794580656021381515769591713295631818532114918070215760259364277583650102628486861397602958930509695263902920994329409932518607260720657755504091822028630927071374796474717671220452208310602827254296323761245420486376569048549643478954846020045263141546849795367522490793641049509748005893155533480849922847230018411440739584477452313387881413141538766185123978087175960946255649923135634987656065468774634483495944248865774633962770893338531522570776854773975281.0) 1379331204929344851843348280532786532350930013132149419346606977890849868537539899667631713548510207947097949976792337278764045110931774279794402312944786743575421497528669859045492875676005849752425421867514661792129580445000023570590786705609341859529483054902802038173138834528021423393677908655442991197348183257271932188161681770513283703502340499171444058119260228931558784004778969491586252899270869275893402714040693571919281494643765571068045362364213060063345212881008657925426024923296369533374671614852576576041747836643356665301762059898161073609265572267138950725010661453917338098901465732991316661901878681888138048552901254914604845891881.0) (num-test (* -246070233154436622785727814428081917418.0 29761582253452470642591719346200231425423204062498655510037025199574178834762931489817919404889920159374886981199608181795387339523762458361385170203883094308920011218315748466148953320570427838912637152446837553950810011344492780712558515815917745810385725989241835877316836808088478276603934260581342710503593237081689944686263274319354100341139245512159619947319496638082702549196795236216458749363904150768879765280332386830831409591769966706351022328535490587838695167807967607003680703048770719240872629379640571077329748828739281770075441660330884779539288220944313294762143588847790653176774089774033399559617.0) -7323439484151992757431054484912931979861244043627630118213112440051387392428853497035249623931234821362770902740177541812170377563064854590834087655133962963430877452052749127605572395112726398103244974178157574726551814002744001021805127518246639418981066588073652668879613252372759895389345727455380224104332342029151667860553645106555190741775758687650292791318963679857313030729683299101577207875499929500963723267185390425716927303375831321783415003339099100562942730763231688479910689887284950156875532151104047755803876078837921949287811575034368641167438367411569736575067233548122814012421044943430647665260439418887639347030312118291762161708906.0) (num-test (* 203826295936164259559522643510940430939.0 428315860474710981601019542870649234168732095026625500771233691514247613083810271191136212287636290276352210600151884730196161003906066671915478570992925366265552107746965374246537358349673161970290367972281768471743836339191023211359427335141701167253694144280251188008871929010775436125645541749886873478179599464478734149706121117222690271210887178499620737860802605991262799781279373870647695125320153193063528861104479576369448865373971847676465682752435142074973627172566791961541105525781297462635428308325033717669972726101583722868689418677558787287897456521530400671342257419067050354522203242849353639864.0) 87302035331271280954456598486072605056704393103691656908943847729634903654600322194677794243221825233700566108459784062758955025931450719283517278054268553004951352280583820782976072352456972931479389375165173986780482062859853305469143408707179895843295115510597584169486406323435925707638987591151227843652210256611991940374072593149367903739596883229844326054223707236369465710416960023659329202073724249764308867733476242261506975691004092043954515337899900837434270833782490145948781128533218641649564543508314976001614187701395586824982250794852925954991265270537649691628899148413763865280007928191637215283244406869662872539567459561720369352296.0) (num-test (* -5899540498246269366107488541138263797694914692322476860852796858749106720144552037986906792251681094769894732746138541066810195167688318229720888479512583.0 5834015210744942902.0) -34418009003174534626858248456163154666511779871358190892629413477534042866009573638264296461516598238780495750056279721797403178867717911762916049857737963922333901125535866.0) (num-test (* -7558198374656605586076446665394545534375963428962439959101805545423930654069723860456022097647139432324162475685494459942871728608277717748075653794546685.0 -2079670855873590264.0) 15718564882684481784074014915267371190416032453294568239793060140651422710113447422494938907375595456199203928496644205320139985222135619659630853564447794621716315309474840.0) (num-test (* -9442744083812363570102321552182535031605446031706376100893354933468482520577272174689455502380973733378565213055641110431767353396963744600184737808983381.0 -7204974197101757391.0) 68034727473703353914019458883709211780958983263702756416891835054494728840771498925306650413027883039860202168095834137357212487561983607389479135319040711944281262212918971.0) (num-test (* -10658732210276096534851972646242288663170038580488752611749460640657411087860047053151548660331707024718100598181073744715506934778234716535781332588396176.0 9193953347013373121.0) -97995886679587166046252015742839992974979220158813197140160489510432960510418039749924861744197553021702396544307690217470606424904065359660871469041838900287446937257585296.0) (num-test (* 3330096979672637104536573277593029682675932033891010715180474877149733802060455951241981993421466123791200840797318740359792251505430948855600408060492000.0 -9413190658845804679.0) -31346837782105095097578725347257193539696338226258990009265748336528353873277500144838721882313026604404426563737656928378230261942407473822851842589487713775609448642068000.0) (num-test (* 2224201331350479188470378485954814766783857696988331736807430786504130570570323948774102396158334805040994159865821844362926631687258969480929122732089195.0 10226747830478556903.0) 22746346139936030910929166328517425029735137934434969334578972386859485783192993228082340012742115893176871887387993591191632260444955081663604449277961804869872353878963085.0) (num-test (* -12394770820700925077767705800588617445613665027183406054209162910642613421436080064653443098327137503596792411463268187212855350864330592654862321763110243.0 336135860956209890623046930607725140868.0) -4166326961171213704571179876442248501325782360170764344978629523457550315208845439497110652079907652744850691289494398473488033083739905461347650605270023127087625641779424751335704552988710924.0) (num-test (* 11792778994619176404079667787533709801900490264171877873621265044313417667869688303207909681289642260521608966405181881416781694320672906600599581862090088.0 -197661229068721548419113517262926820105.0) -2330975190212228827672814304508257223671550753091700552243633152084831515892056240354560520878171696176381845689952044935988868477421447557890739834031207059212175922089523097911477486879619240.0) (num-test (* 11608994516281296345925963401821217560860934641820086911326880657644311461955556832927259499969983808078591149768068360172431078248807463030805586293656663.0 -40654941048774156019243747229920736005.0) -471962987694958552110784676392477007070112288398143925079396435246284471999814508543057304008480666763661066976653446723271982094424149279649226771823800871458389214002872916339341019732251315.0) (num-test (* 4821517917539756801293776911844480642406562140007084392649374723119190602353617113036081438891134008988421494142194891002983491670246762173236312873933599.0 -255528396376819316172341014108564420589.0) -1232034741571035406264710387186737842510579499938716343220834781077329515145216794636313459582844773420679078031627466542930137302257934575129329529129776153159694412903937370462708576694469811.0) (num-test (* 7638751115643228563298483305056828584775811590562130101723525925933790010789130133831569153863129513189315440899053288261039147463032870669035935364282061.0 114438828287750304954799140618669114911.0) 874169727255956505920153418854946321208907128396839975975317705220623267360648189969313978740314703015845506506608054761304647627635292132043887080298168302864314697920637105700927041824911571.0) (num-test (* -3653826017463740005170218884285271512636869606149686475539243914909566619638259666405831445823138528809165270360144267462878986866506114069923299116957450.0 215752050445782448772085819939961259625.0) -788320455239949216234629350585027855111249573063377172522422069903710014529292638311216050777840734448624510386643245486023092483841464815987597578151663227035102742664709136512524899527956250.0) (num-test (* -43242564273985683175827997542883970694363047476880657467026050730764924897992516355909421962249292250047896135687573746158665836208681548975073555418266.0 4424346097667245771102179669235543742385176589624011161914909311078645828684936231569739522607200308028372644149306431599085361996722603718517735348761218.0) -191320070498733614136284309000213964486426347688040889144514933290125387693498098446328694172047943298442181705949005984031677324306763731212307716485454004382079159622650481983102917517993601466178931324415483972311904823997211920702201161092866663969163567426868740120661073974542958600768774774949607988.0) (num-test (* -5093597555679260616199210906198149266592665304134802327659606846977583233938836318559188141955851256260954289429418183711191354912372372976165948043123133.0 -2240632735861652612028397136046974907251405868353380459030143407902436514978447480884513019736738955326732458088791830752499716417751919868492224207936623.0) 11412881426559848135724717164530530041659963797467536748076144863846600718211858527283843975968920120508569299672573958424908957105703597501013710262110218780710678312197455759181436286391257283676806548463507528765947919856827004176416634630489598937924092540289712219714362500246928243091408698274649199859.0) (num-test (* 6049789822056553589237940133475342650218069231558204589924996117723031491205673061674252841792149409384720347601549237626288416453061224734057079515141650.0 -826416247951451524584060567988229017033981218652490450160817307801130685352465013890931297548015267655971295627931896259998420078888499206031390299169584.0) -4999644605638856588581238481465237523157457201817697008198975191261856978252081380810200468420738807464233192102972784271159116426108806200426852134469939032473362689081653859652824862066224063273799612269941254948709760659691148103622071316554194507524610166457990087959160807415102946877307193349131573600.0) (num-test (* -1175978338162966145239180473229656000174129248706173549637767835154921467129547950144109700900405904250603515318348888619371004435353505449762899046094747.0 8633693716102199391202401198009047492431980605560930404972542822133579985462906768067706391388213605203282586546130434156768523403030127356256666478340720.0) -10153036788469908062299722391986722149392791936544969945546931764708792252481931153733789787389051773529081688846141949513463792442701686406966696738286561777611293604311491896230769507535896070984747493738525389837795316954065260075941524322954935690803870500012809797698319359975893462672845329776468197840.0) (num-test (* -5083395547684319640767882199938390155755986838939007846911062687871291096073452055061784159768637502151635665247461348347470360218957222873087414506633886.0 10813098236568616588240471432239693891825284805405416395976866126102880121934298269375465735278296789484402954117593716698067735458182402220278016922449294.0) -54967255432446073625448401244836956268872685687128644401372608170106281377801209665004925733448944141633739594240156882328181133879414641109484442890809130544146420476457200729843868300396656004198615619691952536924980482714767859804902602805398865249514544806725162402291122143659939645240358379962457176484.0) (num-test (* -8944626200084865988157251013718979706166428261352840753194709093968177704853157211364231059892647813839391802007588961807572842923682104089512428902387812.0 3814836951264415657788614449012480613328314590744410079075164918748648723114236698412482309581077603776489883375576245233128800002373843611668945838558629.0) -34122290543331565327874124324135450224668275222811493728051290368641401807963502623692504750924543845019291736982354932620821594287780848608647686402233097059022704206628297180782771812500512744911371653368388270442874670230118309469599458827222162362901084328510647514081302476000779049412605744638457029748.0) (num-test (* 5186176030253526423885531264483408352469356233262336223619904269047786350470477526433506158542551137478071074193659876898065998079440819597952826155782068.0 21428324964794197485898135923805540163916541943812058590308650649384013587098638034673796533027113673143959572855470411726978105342739938341516634354246514986124789451866589211982659199267654387148420461876524076040233779391563396552267276880650559148637067641021059664960876301072636635299261389450890094318429077561092553337025096293793433968243940381587994428364726938534453507046761494257538813861046058298873206568935790790373886840765817404479239485444563488020955730741209738203470138117422899051269778988135668626686262669881048094388220931264751830393793846372816717368806996496715219806062282836392457741918.0) 111131065300898907482632501071313138589398597291097276435916516379173430095773463468344138866282820740991088290299992221985607057347883717514843661030457396422379155394966857856069231504805779448809986906434617741485942621643754096548512120178021034054648207248963478122178145159262707381679354401629366698488021743300737044695960363216253889163551918513521913593214414139637549577618641974388739304727218804595402055185824193445089425262833385286117064481648652550355832014346131722965510192584901901111154083186713580209077544982897821477349293279848852596241762198202012197892321827305803333334823616660229870976569043453639028059771892706354703750763908127611939169337399882784092285804830644630059487027413697220038110815990084742241055099963659761569486906596326424.0) (num-test (* -12615422028124847936088012564413126213419674293830655240645918456932358053670311316461359727921727680491520480380615359506308571290338231702217134487397730.0 21538722931308708400287621200994476771789912594554241036641406577761480056366647329031140922034590767810855360008375309986798226712928670905618807986829790199948665185268081173685941421700542631395958882077936923141152528333121096909688700106365468854487023847026564219531968849793109908193037522063952753477768381591929787242143631287330811801315216116212154423972654430356675401769729358415036943501470085182304183033246682446978634892995900678975109490698283226559860736462409705544079080978470202336645384768211440438501339641775269445439018148409151795830925198162301321965042997632479354427154223366199106583051.0) -271720079725309675925162538296715595434811519956795637977932956405490708202732964133816538801099235844279338645471102896234318181092598033040518838847055114923365599862266767493227393553801736813141780001130539648588341196802606083178208108557367013886856183999712817955194261262279080641101769944037282423238147653270651419282545398168930625797556638625301898893565965773914460998322350526545278664715332414172614761548301364063397364632709194713561073496860524124460861314674679928692398440036071116570829193414179054372604203478369755566003622621281005164747628075596444178089558747835994702060740334079222508147598079351187013336751322569865313532407367116553748939535664259669808534100091049960040092785009707220249025633808590643620557093069849490009472441113874230.0) (num-test (* 10381022953674450046578890619826448644067144294659610359943634722044183130638243233110364436029778310048006743033299956844491228999113516347401915490861208.0 -20974871685432829994714153210121536409377362402944992609230062091789259307033495284524234519701670462495676590513192861649457148897274608767543942797542628100823017887236899471151903799837558453043431373811892813126194662218472834650841742305925226558315372771353677064933578639099452438843500601586038910108679737480263349221244638463171088589123712367802373159421798288708123925853179931628847579314900787361946716531755600236755527982132768286927549323465697241340003870259800347640599467922823203446834792229595507968354687630029075884034263531531423883902851487995214646322431057626558858528344843531280263328354.0) -217740624416854507100100919338835880277259264187442792458843251425095703739537223785767883764746809214920580060316177442387941385712712426957388995082877226019966428812240179251716274377143798847348759498926420314709056615470455134468678662646006408843897699718742372199854223008996321568642038054564397441209859567556502098420151667437837356649730396360374136203172669776530655738388121236079327354422138744456395348910073462618440421257604563050031602590345028438897601523520973759458890228893913090702884911857207117714231568437403212806578764580006787626657709435954760239671948147344463295520930250155876010414461245194991189183956653772752290656063730950237649394743456230607077768595983629559996700837383822873994717987698780007691157576205450973669241823945091632.0) (num-test (* -3984492646329789478973994496812455855595578196959138558282015917391108383154917581748539892089090551298072688793487597623310815918942283997753800645644511.0 22199897116873160263914990610762123553075230334116099569358672964060004245706770678771431369917479502828754815568950371273785689812698287446020480951417047185190067265849637510591502642000414540862689426343523077229502494771352820057572619644085930901096534031496492870227890836816886496090287321502805172125273822231241073590840684742085641304915656543831190976008986490532066597410386596132766422026234488163435487889876791504407434387555507637783709991326338482319227500686541368087892665100076351075069628862376686619537655838590687615291898971286325099164241688147975845320979841704002364545072665891829427213069.0) -88455326811459002089798581395024759975871889172872668466370443703433800509268320055453743803627754859670391415348970278548381190662701716228279482045339649051139909543850883613464992501666524385524517648069873862957915620016943364950043289963237718026629805297916194484838158010754666017024585366330526135823515744339445036315966714684052345462172808299142368905939297220895721123725415007532441824406115746741972351142687017849809593982432484296719999502992792447259391592152463664807498752410740679664044620898308783634092355737296495489953554685938970593890496829484673393665321572846542839714620847185428664388282452532264810310019327395691530430185946743995669191791841546685206884247468693248673484055915613115527492005264289557719000245333079386593840592027314259.0) (num-test (* -10672574004830373997900438516438419278676753890756925443116289034080220708922677740383425352837266631691319394850521121221541344600832530724104047804922665.0 -7307684417326792807224298894786988180161884427390942431653062127076829842696634441114228528164049031680536693195116703321494895319862805505304314401000204515985676763063862569446064343853536464020413910728442475032187317639476018710375702206456631041987826826225461927793241495220512935434301833094232834266749666697332380140380619185254354273073522191066457437931022783436360434167505326773192959291779779370530770935758482422581712556111319611455306383173529090289274267200543081481693078804068524057891845603351773722737987393428313340760607600482724483853560340630587029610437280601010173185018227638972500038072.0) 77991802747865927212086621295493124451256238920588746597961055391511562690441964216934615500942858653797884925704270904527938466874924049039962754703188019915846345804228044693122758075602494985337649496117180241872910247079655077012999375809878184011356481981590430241786534827516536543734645410817621964035091467871491521760928486006653992134635010794346993161329777270345449763927429735191213854873362673179799811714902439637861750855639857969259787075469241319618538795721956528400353086156169058060112255274542232054021662809196965752800525093125763127895334967094763817500702626282397394521201385439419885607578137159972521677923972708827090645776826953976605193554447841693259586575931864396484621463004541561908426383260772786784541411548146173991869741515701880.0) (num-test (* 1420855003086789510813111205540636553863493314684153860389816109865085846062678305775289632805233481596171530412925552158799875183492757047174905459819169.0 13897739053062356545217161606361735964779941697726983959749295377836209520566715597422965426908191354971972501742952706730523748574796773473606175934144970768662226027157110240776527834790487577863781140089347362129598158760833470434895693782503529955845076709376071972727346128409008293671217324995682020009675316075606538241192607139905488719485728099428376369506685875348346231688684483781160648420909364963718027571565217314827671844485031440079254478598236877074793221578612249882886835580737423192061550370069895525711885220268707201966615936769696379335772521903910689934596134239331592980694745008817040569590.0) 19746672065138309742065153069587996891492444461032276894328314121573439684229636534026409362850111716212254549198595854140809664451286626009917828620279583631575940837712663100442879662416765138504151063632823014639305658882804073655537352377258786105147057375069447099908107785635606190515362082317465738205179108333064680370909383338688734129396788764959056886328471374018961975554190739706996184818378586233017775166959010668462907838359485424792026496574369912033757997469014639705459505746723512361959074802456098328538419933637295482429555127226978561859965498424173552676019033370307387047798600024901453757451579262061785051932535359410827170361533603618131510421439128567361259204833501190218719779570258541358012741265599985490513564378203502703406698160470710.0) (num-test (* -25117824099635104147178796272946098711514362630774369209876335291088434247131228189812265510495277875692804180473811834186270331245779845635089547499275113671007257221593872123397418355506777725721168216892830217596134983713752526559153149600553468865338887605949011743043425900799896245185282419637806859906582214420191794114207677635194054239563071023206500505880052007267243210206807805387341085613436600843317096291021780624738422589234020279836961194869688005260369009833026575446099544900581955685627511787510900479881434909308757027825050977932238481841909425598834367032841935054158448815026264505726593064239.0 7846111496222858966.0) -197077248428250572361351389692146917243277049539013604789802566767174747369897711991559940484392921619974209620152008632450612546796556905740493507885376190913893140368029841033442857949219716681475253727058707723386016055991276120001690579154370788782636181079931076758384034193266737114305362492836167078199155929937891579224024229182935372106924021709421948701131654358516297806197381566809357458374057189773041520552821330635689748583803171230633654728360451100477472934847975252390985102859262992904778849652221553818627134153578436315973777720706502751232660284910468721430874674021521629540714057383398858244828214000543075116874.0) (num-test (* -12000343217458212092754251360179138661969968218789048702097501439124892987400633614429800307263114371624489988815324366411323242909652002510513570900627875514001409309670202055060404640758548257776155562167062337394219073071639153822126554525439988062676648294108951003012550815746564810508912122306190725453386412796036693387315128514162061147675205485143205925649214342646148112549805850530430229663418469577245456944558387628002442451042105749848177325651852669794048215063957689756465788955050513359977166122710392613631703123491357791351447110169966270916789849428298930624807758982400706608788793481972190953569.0 15463017349709835150.0) -185561515374029078700596518575548896805308728003103939537818954646551372890610870275966055765608887701776880889777402229764948269089126750201922167386201171243298907675542965323275634529293654817279957832652909009385491998537031060285890512199675273422070784691446251899120095880199298512230290860589352290462643231396804350623684034400741386070220057232978556614620855818271117742675632435727751812101639747357642295230273344552327870600519422276996860893842363996198017494117619585153346745838853026029459826407782259598477529242420507010652705302341725948095720110508044256096963772599572721279996322424269691990173052929936294150350.0) (num-test (* 20244597897909303129995907707212050478823487084391413473821544089492035634291726811145005824559631386634261268723753786161463497881725871168747275110149007801865428978596190887145324535224079986377522166727137028753272158887188902047835658826867304220850429481233026043496635847568448251753504834367809877190895369288045026559783632709799678639927825194847005181499299410953860627694080906167346078299421796974815616608326704894611151743720515377248152215241639534004099341398238713597030368980166731393247619511322804984829747216779359780372801101821087516269912916462719248736442644433057333788741151270815989388229.0 17931151643499274580.0) 363008954869078360197158713265773114114991766614027768774402465306840646219477262855625957403406166192075865834283840624408916170935610374573318606346031792128003204902147985329385955814330782527184421959263266167048755628089412213360508944817963403092490479480264538027768728303095523018598016863928762335410109567604756183580676503045557867957273324581082608248341332512325136675167966306268035077761004923732568405295901819511346235524577361289712297365403327125212199451099538443576479787130510546755789504852631291774614010584650672707483555436445926222945298928326313943231688436271883746272589347954697213098866117569339490918820.0) (num-test (* 18134862906191691435095953372467318196853760384894170022863300447691250350836421337333332682828557871096554531436829166444150586004379181099133295174348038948038399079336722004125999533719492457544642570217406286811480006881054375314838605871238868968956868878182133492469763282800195060849734382249696543089869191257451321764806079423169235271658993054867624410589213892458246001270123109841429271429275464249821855221014782727398959126117031823977229309775211695677345378510417534328974531801634095862859684508240122911023047425473036305928743193594967362216559973174709883576295373749738633873828863608550295977368.0 15082354452174510460.0) 273516430292774638949326170314933525797985748367549139070674899956657807928629067317576809269188258819686207094298714770978509118959142516619521080722291318367607601498107007447014759288176261262818034997399866363248136237609824401265450913244758024085739876914482935655100890803279961929047974391299795570244708811454483314898873277493486428279875241232025231140855860469097028388778917980779775554139507550577255217032521719099071084956515691364008526064349956553916033914728254580848198941020806723485184338914882588931083516851849558411503129184026079582257756707601984686901646494090820169212279581209612798749779318126482639269280.0) (num-test (* 19213874382308276075905228027166553836726993832150876980655958901416537033385379180983129528081628446454583401834309285184752924794893846406622935494758142810049493348116192315865522516744262115026742103678965417868790607689989205765793528434388393584537260717130892518011447327847533083474230074174308157934463971640826422302901570010591182715932658037868980053012095115562188975692530473556182305847290196895478280679341869546292639446526021874910117953225154204035612531584978136604161393474554294315903436682283787080297348697922389355209790646124024053098888687638640826064745026930980189268652291562437512941810.0 3155416591710364359.0) 60627778016974262766014671335614995348970065077989108071534610098195400001445248886220725085881796599270026085183075312353388418711598523030563716616967792282609748819081238929738105086199457414615236966895805539596649555457494710621217412773036416007129418290246899690911654008867819945724649185574237527152410775686803449108977881160831441280833577932476667657759420192656716352190871667386955409426879693856001112340390304980532208752863058384169885129364117656404549585836664647784765508649117301622797243353610345828189312360124462238989888436478381583689386509617357901461416012201469794664889076397809504626996523928173064949790.0) (num-test (* -6561903839860415551587224953276060627466820222543175464705113686962550773423611522044145975606965294164125376820288981286542044306677764776675868357117109664125730405280822770267329297542599719353907954399688197248115043785617436343303277493146049939491224480136371029084354063731401026459653680017632996944506546122253686805764620116169065663214526857151412139439538335533979733329962892417175374550305659302592107472151941922230309227785266745974334776462642676959433923828440435340579340133192678341787895007461237846313005612116885419002449356480017828933592324336731295317076205553526568668826499450826560670163.0 14908715577157091280.0) -97829557993133908713082095435440645457469053259814412551982534425389603663024461131358343104414088618618030154957456050473312402460589893359522167472060177968099538846750606564761307960896264958539903740023783283814849937681270591589750181462708056758506230073751440847913386576449367635057595344744119561166438538811561109125506233466453974371464999669336530949393433719456191822836826214814780222021267726528396849558417851727452246676857867278196266042327956933753121947589485377148388716839519782819642328655117625818256334190717182923260613562191698788004591479576661108985313450029332968584240383859113741485244318702724563478640.0) (num-test (* -10378013547095983701124686671659666242518351347561698092030999302329372512356819420877395264401390796163955327080881297568412490286247154759694714275858127906305200295043241717769593877683535229411640745872559018085757273530771413156968541499388413497221629366848027355125816131586610997516488552323667400115617175682996681969687885201321292153656071894385242141321468096793766926179134511319941715949712230831768643024119693594235207988046511542691719002262040067921088838755337917414526554050602539873232518619281766327369577617796816586064895744680567067970817494102948032924671421242699225194947982378019119315136.0 30004910492448871409155105619400474385.0) -311391367570036811050052853596227388481520279736812036769684195465110674594690412517879149770622679377262288447706750813509857551308594851067359841826754786725926298013483569424123912020079066150719085450400229896983461212531213110847425940968466564079253939695853896434719530729030897976597410468081535234663568150722646854183317007227669132983719314653861536414057481478039579810285535699518386214012059191958557306338432321511585867535008319640705419431310336566447165302011113284064246284641707577414470505948868362067233709611758700034131461348997580441628136979257037186480770286846026250437141175360847735150981343952303257191661069675154710791360.0) (num-test (* 6311357747888359229575837883366949670125882865462293491587368290797766017168248637163030339387377997726585769250585768079027576213724941259801478313127113803503561717311996500019522893295813684259416551410025111443510215766297835872165689077882298506134885487991732718254835036694083204758447948541157893533099634169589161496492972953698758234452126564385255035294546278732684663873459439615228706684138982066055370429797835904846166362278557095045056472775166294675997320598469599722704075215700819354957397052721573993997624711445698656580401684113096559767093466880001548887739825916626416328760047783071058963451.0 -212654096583990292869707082365869207538.0) -1342136080095566600483524091094048745061145155430997807005186206704767933140306297188996797343723817220160636373424666345108189275851749622201429179882167381735732553825696482751584102093819432866729465599060815670807282181979889263381844726842751894916887860819210652174987999919869623292751389157233409465756974677789790982740267208982768450215563288024088369480574425410032306456026930809228182100949940216614156925537929648841127727165386031716586596638254705402653861723407930666152691102484352058909219619985877341630210918347460471644327858114815713557305185589162775699323253049631349906791700893878999711846225062306568467992135934882289075693638.0) (num-test (* 25104391676237653962996674810232896003857294806799086059884413856421530328279649263948893056601611073815235439115612155497964541323584159786678357898152394779494741995735881624055133443980324145256438160990490767324719276757840825641421547232460969806196141938571103617707677351907526127993230143577974386169402623023560579220343920203666762052525898442578990183400559087522259053245822827313206196194989095468393682721753147596892214609346047051670610252732846805143964713621673722554204896154742594858056891979146566683467510164875593192581407047920719605560716270697985110227952698114701527191421628561835164291236.0 -205991315859231724218751687295926841150.0) -5171286675233738337789203670843122752625713948587464573381323151628930998435518250812603433784823922283042037694290795352461861058217142213862777203850665369756106838860420507328654214723398688455622487003912073924323587826356928211672752672052670663842775836967587150049181838707784871641183683742967716787111671792311389517753578360293551031540853470719098360013225516593755039537796518619542838794169319227197212817921098393499332268929332950035803734983497370378852859829228973012039890600437082235032378948656232679080766068869430262740600476498399803176452431728914806536862849281928869092524387549297345184969051926149006293586531930828748109161400.0) (num-test (* -25971587288596053786734900662696128734726180676323130693160397208008930123341700520454723462226657743365779183466120836187720332442041321870351823609046027805781414454998487673927365486893294110931852680018706479684281928396163669935417207859889405108139261480861908067489849403284000981453574189898304616775302917687860062501465417706095450121596418236563421425311420755550335597318818628123183624214438801254105808079227429950505879366254661664881055965092586612702279548151277733307180663770432418397550642136953750720624507617115504303570076531620003848642167562950736271141440609700821621532583527124386811144839.0 -182748557863603655835821910989658558236.0) 4746270122419629115710902425435990509747636609113505336611751359043717100752575149404352359855260443259846554733621122684788488984010741203981300775978945529551335641218319619542248418128319220383298229263331638090009313676486209764655429828385994626323209879925281409485074778611946493692237774852428345451174837474328995186242262565013937544898941834362941815633750896882758939509605799422068815435202904271722442099465950700886702949580264958171808372530471918175963644209760378395316412115175988232945569517230829200985652504383431054550902852797293952515652017940918628980037316292352828228005975466732028971159947131994753006597870175664981312344004.0) (num-test (* 2117427896392849163304163145095251890404997781812823978967013619233450901604407363671467658244435728579079751353560538034596183240362499870272373308111405924505741579887345118857908796509418246599428633956038017783178050402412769812823236255234302205027282366926174916871858199918908361186936687654278623156607813451034087735179167324944824913226799346886951212979149617678949292799645035425029596869092844906629996914674904522806258932192931217652241231736891642224851547474205131131019084734780208254203537633402057673465583362982905095029133132240839391503135932501785844503813910210348239157828902668852795945482.0 -296778668392678698960782643314222141731.0) -628407431508980610909134894336322264939705333430111861505965183839156278363647883745193463537783397824947515214540990712455315080515980803996660089847066076833542492719707493333185909990202372284811233272987993068106356248349054482194817336258302692039392400931536481136340269417905505366385505196886218794044229758585631131853635721528813397816307666671727692971421531381290925317161326036075629905443938124481334173158440927555118173661486114828362551889594188958723424604273078091320087897088472418346754088900034854230711982602435635574895960156993014703292551046970069204857846207328434544990709459402656908170089318995291341536347275682867153109342.0) (num-test (* 24743327715258194976385899813930363006464428087412805068703455203318769863096919192538751530954777047772548306936907016751357570434930538612382851621309732767199276228580401695793317612267605312672263736938703887622824117576912830029817460033437752668221355377879837833796222831371174014543622739933433581963103361464022058091243110136610854806189138108937004805781857031030005354158991203388998364340053773883952742645161560754545458260688560269655272249435540890073696261770299845722705104648358053080678920468895189601731801025555650490534399590288852165862135571140382055044665678298182909026026068995867606241201.0 309156501491030456401354118244509785044.0) 7649560631695275371386748526795333430293346807872366006552933839286343590101586516802834568317627508914888989005968805867728947519409222814667350103434422356009252082456906520988877859152125402282765775845766265340707473525444185795403554160270722809642681642831847296672303556012796775586274347178092325226458743113317655523655255626670958156216225968018208281266858684283741496986683426354716284780229004376492833583965647875097951642088252875535823145900129967026856898970545720526282798418382467634180690243423325770596949644122541224189780082061715230852249880601371985342796525016176048518593825361248232406051886794538203297084423942036889326397844.0) (num-test (* 31345149697924857384985323414506591310628538098830133854928154990821019223495435414394178930529373634315044777562902565397455028894455733092896622048288278424884040917250546068175763309233883078972879622697667174865833277342334219810618450605650614585133187005110148963483824629405555603493157452295284935004578187488673124814714326405406894084902824045787647963172437833905574178160343833139650913077173865287057167288286708807322607983179910358234015596109655900840652230258122852488289951986129788952718105898226951651151495867246384586164892018870981480003722043190639707903266193064807571586900961788679579912089.0 2067227180806746570739122295766566373146995767544546241400900414826379465803168632854028593293108913670556431832056563218709444199286888840721753894461468.0) 64797545442006646811970698282511426059102976298051534827345388707272469591333019870381858263624490336448197115781363489554169207652559213486772008013638214870324260793199674746523791257170452738018910619029072942848422098770309928561867618844814267276213608306045020686764830302020953883994906997293368193331696747777630621086600981981357507299729947717565760536305785574555255589190221698706036770081438750974356437738060098906046001271392354762036427049946092656701257615490057677558059955825843182799904828201890893555678855718728417223845757559310912618029462136640226686626513375024547351747669476392735304999046232068947570708757930233036922714350584650744960478326257916948676866148362166017752159953504981324652709881831381637989229842766220141292801807437886652.0) (num-test (* 1965759082776833678304908699214846485256126608825750175641683294458978302204367346739996602241053060915897480812220051082619942907491598551933638540412113496542245474287364500698693202553692963910123752514310355402167440783023542848697962967771951714434359320001430281377747193083851165947498546085410216620013287853719686698746328198021011905482303248172483782066908570502837009924228011993318265674390462360820566174204659723461994730913995303015012684826295802887547970851558451858623353950391701673651959262042520584275132971807158231859672678070714276061110616753309305801080136339206017351200193800253572481467.0 -11092241138073130060021642325471345789108575712118027611362686690749327689527135459714040658411176246054106270789083336195599640521602432629024562630323934.0) -21804673765518097879589124792137157558586438669762099454880024920520894260754279593873244443852337739758694535682558790532827482894104906218015712179591886600693703465749571299271429989154199263793230178266758966678432691901731270899259065726530463438316383699558373053423999416350780342222940065486831353604365192968606300436304827279383661172824549131179471364227618431414928702407510473319879188990689163932586727702195573766225861364297410904859137393184592815970592502081722125458353280743087607273547490382023433724488604177909671497082747464946083901888849483505451426245881736990810339421864101129619181017696837017966116165703320918568645290788634265522956017905246042460811062666193790657969385648522736090098231379029903772234867701846824572274796526421531178.0) (num-test (* -4067457132547237558852016696244696525033953641638067592741078194074861352472861925779476293767777560910963786727886946479865734639031042985368829200802420611189793957001730656623744670821921724417176679009632346904384261431052972127975733031277489967119978909321422086102208644766894305071609385305464547231057263658903212521469801833214062476735046735467944834107695748433481665714184831786462886261252526036621257865158497049125410241033365487816324425563483999957660557670189397770488996359512245971368638615503320507431381893539767352426795415898379765583574977542068222040889423739693921998717145084904555464058.0 9635268828818063607505341812331931088336041632536136269505180222913464638532245578488168867093853062326136774925531196873279749483997619950077042084971972.0) -39191042921786100943542578352486285322085069425292685238158202937549417928185097567102615300826629615520476316505465412722375794150552330462353356124896483739321653441446703127728441315609093330694305784991844511900128172079464896650958648496336601612657347012294121239821167759496102233234525084695798195547141521849769350204659392602605928907953707277320590923278178152903602506284861018886300148663530071056792375593665422754923886137410482547324901798328311927545105456397213670390651819229021443747424183114992653572959318104053511452473611466305149349027962240989590453237778130260105665310067480846969449221473610614214933278048389171979184119355459010233147440293881252851501522689209874112819966647846701257081192324007280573826673895648273593609466000383382376.0) (num-test (* -22047771987573494284336211037167956208924595972749016352929724093971147687332865088249749580556015503923927321586913446367676445848750229391300778587369581738560634537089081840938984779012854694220894920437076215176060179241185151442003472788530160589267677502568156006531439509890061829154786579353177129190813899423306499631144919702707240832059008168851983259611724134448165201725432622521420667808597545410136493805873769372831833878868603946583848422310946469083400330960925084024624317866822897278934924368888332618046649078771617892961267312226309927786691384460940015979582201446635756024251269978545916298961.0 7481502540911026808093162425787184755732317118387068406204973030847892995155568099553397887864257088525242568880427634318737874025160499293315047534753494.0) -164950462146458057264341765173378248123415893870534274075422323606836246718538063890359159423074703472625232511667875897808555123518162244263016096627959208397334135559180524195701526029092734741010866589515172934676451385008535538102832400604699294088534999994990970130226363762230944961249818769566697211068918154629209895730969522747736738946126971914549491889482944152891334838234907190697109929512401661529882587076352559260375439428815896053844621297552401396168240947357044985051323834074355418902009161796886350497072010833513601114819625605048943438304411954380599728561071485061414856047768286383287807924135081902458690495890129203192613070824670256334683011083767124852354110322463725619194174195587835939047474059288568764831570274891727391545546467943319734.0) (num-test (* 22607201423790553279447786193696575272983924506336369475058795405894123712509544256099524616893423762658394830755129501447553593365768543361107397299007141714383407862976654294384881771985218996697067215804348472693636567074361380875512341556932579903687576929186215185312685712277482751425466251201421842248749944123326048360909954588266368306843116245625635467041934524547983478110533044085242847795585598341867070787331785945399446665919396062565614516404861115244243161694059679274045050270546536781907061002623188435269769778378780371158624481539046590932125320888745103158180784231722265376331553893647061533815.0 10075764395489719205294189472045365742345400155046712954334138069917417587273618147303160957788995022989479371576840422540097479703418600112174202202728054.0) 227784835187493343385594867881830022845566753253174983274076326016001091958812135049265213053390506720261776960833046225700903422206015373488419693650378821159134369608830936915027161415300759990632038898164509761337714774392506802504397626551196717184785586630245704512525844329038355790338277254618639554796026366029578805283659986085947726260520495140332204643887370987929304924491772630534558682402396784510750317396488402942581973350428066695976988812610467654886227733900635715495731445319565054848075104982244316563526232071957624002266648721592744376122065531440026836549316222728280595228806728872537793522244957258060730038589170810090676474272044568671474692128168357087077816573419470273384256552275636517940058764711467508281344270125535855785388198570146010.0) (num-test (* 21997874907846585575969651776904015812729615626636027149446399573806943459105370044846476738175828244018281160136531735881270437472624605280356112191272531838028896521621800558410217146758345955334174583639352151367532676985598470747138461153212653362188252002768647808852054182649808145379073620834551216386805267446360709820441771932135218282126427988826945094538034579367527908530151926679515746133600376612899354099328788736038811470295396365432559354070365548930628714861826464935305416998192532029724853617023971964507955475554955277722555849603716733374588174421463022213135839490633927005539569058361144905451.0 -1400498192750070094581812894241996480373581610489471746158083224360249880335094841398529960182484181641387946900090289855375996313447832474435929084180606.0) -30807984052781257825246153008277875918087659020905755686964119182052911551148620538090633516362197112383237624321406969368641524681503231262834662890145617622830207559490089313283375890353617292096501953380469351747504928597461154633889236826060654886877907382241867167198409355653371944304660938495445848950444683274236538890057643038410268234731745456035923559528706349316582901179686671568504971088561096469997823300883298811440849031903066114422309644669680078733839046643542078157684064686933779591609758494599988463628362190034612412739669041368897594110022347872452261447359402810277413572637740870748949093642723240662839444216981630862346445890780016393330114883270596630385367407921496982236074288475142085411632630374714528706189796772213264952893973677883306.0) (num-test (* -270155241925436273159477510619232592261228150696806729750247050.0 15545126743930076938536195287546926534964892301082800206802745964245668351235397.0 72127079799316080210744562119267314209211162112457416152560774669179705347659265.0 58427280233475514109627698916382980237252687770812483048907352594138577656301900.0 91336330475502063985843547526216808965829995610054777216888670176112782119332811.0 99495081134815818196404370468895496198561677002653930126818668800341380375657337.0 6904264296552316628911621065724553059847235903647375662685025031963599691416829398469283631386160328944460790101458427909545198569619131058877708293713734.0 -16074984786353617526516141164566295497596312655026144270863093715961484079732496604871734572736757225277596743795506589617891195569235287256031608792067121393492186703333733526879481948463529609113624075923052999494363547340563039654910799974388353472433635130983731604982117092991918514078659590068643956240711810902756784590442416249652077644077280371860780741318193975770906075446772544431670392964384669681404295839302410058434872964315897505894833409101781069230919347279857855594782111721176074849502391457684148683668165019969667481755384384017844104770253558111588611189351637275389688093074751942960310850074.0) 17849860827147993486644896214424106325295064110723402251474432199595968349198253682890653243676378684005650871261983711134190416277366473221365848417375107498764965893729640224952922241531788638514200018520970345581414705756736222535562338748426356003659523260330725662384208724142177900990027225665451069059291754155591197426279006090296512196415617974140965334686090032257444820748820516976632201388937358434205022475303705442914044454220818215336283948743042841946229853366515552653568436171217572212088935263340599371830215580988184775240338748954666846379831467518505260487989636951404886967842600777836444030434816421999334066711024026401362115623932221335906548647785232855815515579448393689650116225664467056283988125816950714780486880294535933597118808163054631168063568847830481653855357008353733414826165759079092633441356914450038756281940532159493763482047244493174370100586359619040444818634156576789665732998111907245928253704097384811414269835758656988678207624731164159069547745777423464124959379113843649940896359346515513936964849811155238140671698227057228045173997904545787593258286212427476788605370334985423461194148838623911634821153061693257996982252745844329344589168264774527631972524787804330730506700000.0) (num-test (* 6411564443509812216548163965666668398784964137255201222920640150.0 65325385402074288043601436729391841747319174569548241717675134253657593233436152.0 63305037198546989906433329294566491017476837189978173607681765241525113921707860.0 72383582945810879300930057856704905379805338886592055772943486702915907397618845.0 35525980101796892634292856352740658817031405780112750352735419884048051630180860.0 47579150292602967366908574298176357632207539947399443701205872093150879604391127.0 7775494633965874654516687741429737470333189902121089184439228657893110997221737422210698789286625633365548095171257583020272703565350668755439139356570.0 -7847653632223099338936161226557020783515367997970448568586056286591257384101422312757649765574456754668588904917800060981155642916520580540801153603733496143328839018174649200566737789874193483124577734129346933208306772618814806884416239295732454033604210880463262467564639515484363761639994642888910703066277724414372379965872478153546766131136324967950786993982228851928269842355632200589446224738709869729930285189047112131897218464505263042012855229737941639093204086147932759923796947642895167078971517834730472596647456786099215405165290569214043431009370032818978995463168133051136053246705694337584724712230.0) -197949741939898550383903354028842356745461597695099989904494711851411610441324234089773644533872304737431480244289438922163630848266242200711131210228027234579469457105291847132071566876246332653149194709623963836885480655282595345693084881617726426841183231475364991154699746506928116505297453355016975688761948609740314324443406930215518937775475617384099331839748494157863510168743547396262979908353122625808170296763676837551973930928848463398657587603606321137626467028732193151671337338929938959296176472483674270114824853018199281637976410726195357458134038379491704909997939715446657856320452698914513791221947734373322868574099599391493563479057703049036936132407025278683219316357543078875410080612067641232277376174351958080693019953378024732243763129075732499165068171168470237875348580987967740148512425201518758344757030205911031119619416763996490581551977913711646761182756531618786226541010835120092904291975494846126923510483263978074437667987560077422810120462938292680423746968095994108344184522240467647491991837793653579480334442342102339933473270535800619630342940590477752278184994533764839125736268376640933720554199782388890444619996919031351334561766248781813883867406045414518951152508504891407920000000.0) (num-test (* 1669833986019218156514274418186396165434871163342486930502417566.0 58528969848472951398118375496887849181512821636583415470809040929690124231959506.0 50098163184827557635697120379841225459445103589988345336880332217224622666020381.0 90445522698871905833766573423181067004916996574451008349087758531794463581708977.0 92366726802191504770638415639612204654473958526592425718659284841373421985393966.0 69096133232785816552402133765198624674167660496399099321713067612475604030259084.0 323971624832697152056406152359288553860210436839331005469891386690556929684663075996719803995137130737141925308417709520389528780839777347463558171582753.0 2635514624483961079560488004237441873979133312246005082134175818331132377114926863102436691793380965631848192666106793612266994709357524826644421074908075389316030912936338175907209987972553710900613011802455058538786723149316934049388525865455871552882282353445228425640452635081303490379594663330152071465360003249884180020993032086861074931796165970076448856988084523672973069824258299029863033098237556417571526135639288006133579174344589248428714474318969988990720790226604664141927030250855550010512291136517209169959021730625428868037074528890516086527430801590050720467893089085308995719513895962750896813152.0) 2413207990093478676325592386500172980330574558867366638913149256222218924700401110600319869300256745035993991818342784487193857053589994816247466074246569162659879368383295411190237107255160498774228460295857931362161062884154872938368166514128474751716517750517217000290486110198899480877593169193610813452614906598055909439037075588626529658637140089909227353944313408987644743661503976835580507054926908821206921014266535160031749397432350114673787218438589065861056449106115395189057409933330355574558853874223262465965933679584884152813357065227868165556818717270584803360466149860292769520737249610469675917864449261901859162854558012721179400237645357401213337423255109839806528503425658270050436129019270883446965562683284298538825840361267548675967778385927410390726055957928634152514415917053614892441910675109517307682075989998558764742821214685548219206933043196677521610851950501225469125512893859254575460130829051324112015464552874242522140166275233893076603452098841950130740353331198999756316969161591691095397245996664755249875720008141774247384884623389430842799829690618405724986702942913150258769060684255363816662231923570491001519802836627028431389746450987110456127797025006251203111629141890634728548553728.0) )) (let ((val1 (catch #t (lambda () (* 1.0 0.0)) (lambda args 'error))) (val2 (catch #t (lambda () (* 1.0 -0.0)) (lambda args 'error)))) (test (equal? val1 val2) #t)) (if with-bignums (begin (num-test (let ((n 40) (s 1)) (do ((i 0 (+ i 1))) ((= i n) s) (set! s (* s 2/3)))) 1099511627776/12157665459056928801) (num-test (expt 2 40) 1099511627776) (num-test (expt 3 40) 12157665459056928801) ) (num-test (let ((n 40) (s 1)) (do ((i 0 (+ i 1))) ((= i n) s) (set! s (* s 2/3)))) 9.043772683816628192400549525035572818665E-8)) (test (* 0 1 "hi") 'error) (test (* 0.0 "hi") 'error) (test (* 0.0+0.0i "hi") 'error) (test (* 0/1 "hi") 'error) (test (* 1 0.0 #\a) 'error) (test (* 2 2 2.0 2) 16.0) (for-each (lambda (arg) (test (* arg nan.0) 'error) (test (* nan.0 arg) 'error) (test (* arg inf.0) 'error) (test (* inf.0 arg) 'error) (test (* 0 arg nan.0) 'error) (test (* 0 nan.0 arg) 'error) (test (* 0 arg inf.0) 'error) (test (* 0 inf.0 arg) 'error) (test (* 0 arg) 'error) (test (* 0.0 arg) 'error) (test (* 1 arg) 'error) (test (* 1.0 arg) 'error) (test (* 1/2 arg) 'error) (test (* 1+i arg) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) ;;; -------------------------------------------------------------------------------- ;;; + ;;; -------------------------------------------------------------------------------- (num-test (+ -0.0) 0.0) (num-test (+ -0.0+0.00000001i) -0.0+0.00000001i) (num-test (+ -1.0) -1.0) (num-test (+ -1.0+1.0i -1.0+1.0i) -2.0+2.0i) (num-test (+ -1.0+1.0i 0) -1.0+1.0i) (num-test (+ -1.0+1.0i 0.0) -1.0+1.0i) (num-test (+ -1.0+1.0i 0.0+1.0i) -1.0+2.0i) (num-test (+ -1.0+1.0i 1) 0.0+1.0i) (num-test (+ -1.0+1.0i 1.0) 0.0+1.0i) (num-test (+ -1.0+1.0i 1.0+1.0i) 0.0+2.0i) (num-test (+ -1.0+1.0i 1.234+1.234i) 0.234+2.234i) (num-test (+ -1.0+1.0i 1/1) 0.0+1.0i) (num-test (+ -1.0+1.0i 123.4) 122.4+1.0i) (num-test (+ -1.0+1.0i 1234) 1233.0+1.0i) (num-test (+ -1.0+1.0i 1234/11) 111.18181818181819+1.0i) (num-test (+ -1.0+1.0i) -1.0+1.0i) (num-test (+ -10) -10) (num-test (+ -10/3) -10/3) (num-test (+ -1234000000) -1234000000) (num-test (+ -1234000000.0) -1234000000.0) (num-test (+ -1234000000.0+2.71828182845905i) -1234000000.0+2.71828182845905i) (num-test (+ -1234000000/10) -1234000000/10) (num-test (+ -2) -2) (num-test (+ -2.71828182845905) -2.71828182845905) (num-test (+ -2.71828182845905+3.14159265358979i) -2.71828182845905+3.14159265358979i) (num-test (+ -2/2) -2/2) (num-test (+ -362880) -362880) (num-test (+ -362880/1234) -362880/1234) (num-test (+ 0 -1.0+1.0i) -1.0+1.0i) (num-test (+ 0 0) 0) (num-test (+ 0 0.0) 0.0) (num-test (+ 0 0.0+1.0i) 0.0+1.0i) (num-test (+ 0 1 -1.0+1.0i) 0.0+1.0i) (num-test (+ 0 1 0) 1) (num-test (+ 0 1 0.0) 1.0) (num-test (+ 0 1 0.0+1.0i) 1.0+1.0i) (num-test (+ 0 1 1) 2) (num-test (+ 0 1 1.0) 2.0) (num-test (+ 0 1 1.0+1.0i) 2.0+1.0i) (num-test (+ 0 1 1.234+1.234i) 2.234+1.234i) (num-test (+ 0 1 1/1) 2) (num-test (+ 0 1 123.4) 124.4) (num-test (+ 0 1 1234) 1235) (num-test (+ 0 1 1234/11) 1245/11) (num-test (+ 0 1) 1) (num-test (+ 0 1.0 -1.0+1.0i) 0.0+1.0i) (num-test (+ 0 1.0 0) 1.0) (num-test (+ 0 1.0 0.0) 1.0) (num-test (+ 0 1.0 0.0+1.0i) 1.0+1.0i) (num-test (+ 0 1.0 1) 2.0) (num-test (+ 0 1.0 1.0) 2.0) (num-test (+ 0 1.0 1.0+1.0i) 2.0+1.0i) (num-test (+ 0 1.0 1.234+1.234i) 2.234+1.234i) (num-test (+ 0 1.0 1/1) 2.0) (num-test (+ 0 1.0 123.4) 124.4) (num-test (+ 0 1.0 1234) 1235.0) (num-test (+ 0 1.0 1234/11) 113.18181818181819) (num-test (+ 0 1.0) 1.0) (num-test (+ 0 1.0+1.0i -1.0+1.0i) 0.0+2.0i) (num-test (+ 0 1.0+1.0i 0) 1.0+1.0i) (num-test (+ 0 1.0+1.0i 0.0) 1.0+1.0i) (num-test (+ 0 1.0+1.0i 0.0+1.0i) 1.0+2.0i) (num-test (+ 0 1.0+1.0i 1) 2.0+1.0i) (num-test (+ 0 1.0+1.0i 1.0) 2.0+1.0i) (num-test (+ 0 1.0+1.0i 1.0+1.0i) 2.0+2.0i) (num-test (+ 0 1.0+1.0i 1.234+1.234i) 2.234+2.234i) (num-test (+ 0 1.0+1.0i 1/1) 2.0+1.0i) (num-test (+ 0 1.0+1.0i 123.4) 124.4+1.0i) (num-test (+ 0 1.0+1.0i 1234) 1235.0+1.0i) (num-test (+ 0 1.0+1.0i 1234/11) 113.18181818181819+1.0i) (num-test (+ 0 1.0+1.0i) 1.0+1.0i) (num-test (+ 0 1.234+1.234i) 1.234+1.234i) (num-test (+ 0 1/1 -1.0+1.0i) 0.0+1.0i) (num-test (+ 0 123.4) 123.4) (num-test (+ 0 1234) 1234) (num-test (+ 0 1234/11) 1234/11) (num-test (+ 0) 0) (num-test (+ 0.0 -1.0+1.0i -1.0+1.0i) -2.0+2.0i) (num-test (+ 0.0 -1.0+1.0i 0) -1.0+1.0i) (num-test (+ 0.0 -1.0+1.0i 0.0) -1.0+1.0i) (num-test (+ 0.0 -1.0+1.0i 0.0+1.0i) -1.0+2.0i) (num-test (+ 0.0 -1.0+1.0i 1) 0.0+1.0i) (num-test (+ 0.0 -1.0+1.0i 1.0) 0.0+1.0i) (num-test (+ 0.0 -1.0+1.0i 1.0+1.0i) 0.0+2.0i) (num-test (+ 0.0 -1.0+1.0i 1.234+1.234i) 0.234+2.234i) (num-test (+ 0.0 -1.0+1.0i 1/1) 0.0+1.0i) (num-test (+ 0.0 -1.0+1.0i 123.4) 122.4+1.0i) (num-test (+ 0.0 -1.0+1.0i 1234) 1233.0+1.0i) (num-test (+ 0.0 -1.0+1.0i 1234/11) 111.18181818181819+1.0i) (num-test (+ 0.0 -1.0+1.0i) -1.0+1.0i) (num-test (+ 0.0 0 -1.0+1.0i) -1.0+1.0i) (num-test (+ 0.0 0 0) 0.0) (num-test (+ 0.0 0 0.0) 0.0) (num-test (+ 0.0 0 0.0+1.0i) 0.0+1.0i) (num-test (+ 0.0 0 1) 1.0) (num-test (+ 0.0 0 1.0) 1.0) (num-test (+ 0.0 0 1.0+1.0i) 1.0+1.0i) (num-test (+ 0.0 0 1.234+1.234i) 1.234+1.234i) (num-test (+ 0.0 0 1/1) 1.0) (num-test (+ 0.0 0 123.4) 123.4) (num-test (+ 0.0 0 1234) 1234.0) (num-test (+ 0.0 0 1234/11) 112.18181818181819) (num-test (+ 0.0 0) 0.0) (num-test (+ 0.0 0.0 -1.0+1.0i) -1.0+1.0i) (num-test (+ 0.0 0.0 0) 0.0) (num-test (+ 0.0 0.0 0.0) 0.0) (num-test (+ 0.0 0.0 0.0+1.0i) 0.0+1.0i) (num-test (+ 0.0 0.0 1) 1.0) (num-test (+ 0.0 0.0 1.0) 1.0) (num-test (+ 0.0 0.0 1.0+1.0i) 1.0+1.0i) (num-test (+ 0.0 0.0 1.234+1.234i) 1.234+1.234i) (num-test (+ 0.0 0.0 1/1) 1.0) (num-test (+ 0.0 0.0 123.4) 123.4) (num-test (+ 0.0 0.0 1234) 1234.0) (num-test (+ 0.0 0.0 1234/11) 112.18181818181819) (num-test (+ 0.0 0.0) 0.0) (num-test (+ 0.0 0.0+1.0i -1.0+1.0i) -1.0+2.0i) (num-test (+ 0.0 0.0+1.0i 0) 0.0+1.0i) (num-test (+ 0.0 0.0+1.0i 0.0) 0.0+1.0i) (num-test (+ 0.0 0.0+1.0i 0.0+1.0i) 0.0+2.0i) (num-test (+ 0.0 0.0+1.0i 1) 1.0+1.0i) (num-test (+ 0.0 0.0+1.0i 1.0) 1.0+1.0i) (num-test (+ 0.0 0.0+1.0i 1.0+1.0i) 1.0+2.0i) (num-test (+ 0.0 0.0+1.0i 1.234+1.234i) 1.234+2.234i) (num-test (+ 0.0 0.0+1.0i 1/1) 1.0+1.0i) (num-test (+ 0.0 0.0+1.0i 123.4) 123.4+1.0i) (num-test (+ 0.0 0.0+1.0i 1234) 1234.0+1.0i) (num-test (+ 0.0 0.0+1.0i 1234/11) 112.18181818181819+1.0i) (num-test (+ 0.0 0.0+1.0i) 0.0+1.0i) (num-test (+ 0.0 1 -1.0+1.0i) 0.0+1.0i) (num-test (+ 0.0 1 0) 1.0) (num-test (+ 0.0 1 0.0) 1.0) (num-test (+ 0.0 1 0.0+1.0i) 1.0+1.0i) (num-test (+ 0.0 1 1.0) 2.0) (num-test (+ 0.0 1 1.0+1.0i) 2.0+1.0i) (num-test (+ 0.0 1 1.234+1.234i) 2.234+1.234i) (num-test (+ 0.0 1 1/1) 2.0) (num-test (+ 0.0 1 123.4) 124.4) (num-test (+ 0.0 1 1234) 1235.0) (num-test (+ 0.0 1 1234/11) 113.18181818181819) (num-test (+ 0.0 1) 1.0) (num-test (+ 0.0 1.0 -1.0+1.0i) 0.0+1.0i) (num-test (+ 0.0 1.0 0) 1.0) (num-test (+ 0.0 1.0 0.0) 1.0) (num-test (+ 0.0 1.0 0.0+1.0i) 1.0+1.0i) (num-test (+ 0.0 1.0 1) 2.0) (num-test (+ 0.0 1.0 1.0) 2.0) (num-test (+ 0.0 1.0 1.0+1.0i) 2.0+1.0i) (num-test (+ 0.0 1.0 1.234+1.234i) 2.234+1.234i) (num-test (+ 0.0 1.0 1/1) 2.0) (num-test (+ 0.0 1.0 123.4) 124.4) (num-test (+ 0.0 1.0 1234) 1235.0) (num-test (+ 0.0 1.0 1234/11) 113.18181818181819) (num-test (+ 0.0 1.0) 1.0) (num-test (+ 0.0 1.0+1.0i -1.0+1.0i) 0.0+2.0i) (num-test (+ 0.0 1.0+1.0i 0) 1.0+1.0i) (num-test (+ 0.0 1.0+1.0i 0.0) 1.0+1.0i) (num-test (+ 0.0 1.0+1.0i 0.0+1.0i) 1.0+2.0i) (num-test (+ 0.0 1.0+1.0i 1) 2.0+1.0i) (num-test (+ 0.0 1.0+1.0i 1.0) 2.0+1.0i) (num-test (+ 0.0 1.0+1.0i 1.0+1.0i) 2.0+2.0i) (num-test (+ 0.0 1.0+1.0i 1.234+1.234i) 2.234+2.234i) (num-test (+ 0.0 1.0+1.0i 1/1) 2.0+1.0i) (num-test (+ 0.0 1.0+1.0i 123.4) 124.4+1.0i) (num-test (+ 0.0 1.0+1.0i 1234) 1235.0+1.0i) (num-test (+ 0.0 1.0+1.0i 1234/11) 113.18181818181819+1.0i) (num-test (+ 0.0 1.0+1.0i) 1.0+1.0i) (num-test (+ 0.0 1.234+1.234i -1.0+1.0i) 0.234+2.234i) (num-test (+ 0.0 1.234+1.234i 0) 1.234+1.234i) (num-test (+ 0.0 1.234+1.234i 0.0) 1.234+1.234i) (num-test (+ 0.0 1.234+1.234i 0.0+1.0i) 1.234+2.234i) (num-test (+ 0.0 1.234+1.234i 1) 2.234+1.234i) (num-test (+ 0.0 1.234+1.234i 1.0) 2.234+1.234i) (num-test (+ 0.0 1.234+1.234i 1.0+1.0i) 2.234+2.234i) (num-test (+ 0.0 1.234+1.234i 1.234+1.234i) 2.468+2.468i) (num-test (+ 0.0 1.234+1.234i 1/1) 2.234+1.234i) (num-test (+ 0.0 1.234+1.234i 123.4) 124.634+1.234i) (num-test (+ 0.0 1.234+1.234i 1234) 1235.23399999999992+1.234i) (num-test (+ 0.0 1.234+1.234i 1234/11) 113.41581818181818+1.234i) (num-test (+ 0.0 1.234+1.234i) 1.234+1.234i) (num-test (+ 0.0 1/1 -1.0+1.0i) 0.0+1.0i) (num-test (+ 0.0 123.4 -1.0+1.0i) 122.4+1.0i) (num-test (+ 0.0 123.4 0) 123.4) (num-test (+ 0.0 123.4 0.0) 123.4) (num-test (+ 0.0 123.4 0.0+1.0i) 123.4+1.0i) (num-test (+ 0.0 123.4 1) 124.4) (num-test (+ 0.0 123.4 1.0) 124.4) (num-test (+ 0.0 123.4 1.0+1.0i) 124.4+1.0i) (num-test (+ 0.0 123.4 1.234+1.234i) 124.634+1.234i) (num-test (+ 0.0 123.4 1/1) 124.4) (num-test (+ 0.0 123.4 123.4) 246.8) (num-test (+ 0.0 123.4 1234) 1357.4) (num-test (+ 0.0 123.4 1234/11) 235.58181818181819) (num-test (+ 0.0 123.4) 123.4) (num-test (+ 0.0 1234 -1.0+1.0i) 1233.0+1.0i) (num-test (+ 0.0 1234 0) 1234.0) (num-test (+ 0.0 1234 0.0) 1234.0) (num-test (+ 0.0 1234 0.0+1.0i) 1234.0+1.0i) (num-test (+ 0.0 1234 1) 1235.0) (num-test (+ 0.0 1234 1.0) 1235.0) (num-test (+ 0.0 1234 1.0+1.0i) 1235.0+1.0i) (num-test (+ 0.0 1234 1.234+1.234i) 1235.23399999999992+1.234i) (num-test (+ 0.0 1234 1/1) 1235.0) (num-test (+ 0.0 1234 123.4) 1357.4) (num-test (+ 0.0 1234 1234) 2468.0) (num-test (+ 0.0 1234 1234/11) 1346.18181818181824) (num-test (+ 0.0 1234) 1234.0) (num-test (+ 0.0 1234/11 -1.0+1.0i) 111.18181818181819+1.0i) (num-test (+ 0.0 1234/11 0) 112.18181818181819) (num-test (+ 0.0 1234/11 0.0) 112.18181818181819) (num-test (+ 0.0 1234/11 0.0+1.0i) 112.18181818181819+1.0i) (num-test (+ 0.0 1234/11 1) 113.18181818181819) (num-test (+ 0.0 1234/11 1.0) 113.18181818181819) (num-test (+ 0.0 1234/11 1.0+1.0i) 113.18181818181819+1.0i) (num-test (+ 0.0 1234/11 1.234+1.234i) 113.41581818181818+1.234i) (num-test (+ 0.0 1234/11 1/1) 113.18181818181819) (num-test (+ 0.0 1234/11 123.4) 235.58181818181819) (num-test (+ 0.0 1234/11 1234) 1346.18181818181824) (num-test (+ 0.0 1234/11 1234/11) 224.36363636363637) (num-test (+ 0.0 1234/11) 112.18181818181819) (num-test (+ 0.0) 0.0) (num-test (+ 0.0+0.00000001i) 0.0+0.00000001i) (num-test (+ 0.0+1.0i -1.0+1.0i) -1.0+2.0i) (num-test (+ 0.0+1.0i 0) 0.0+1.0i) (num-test (+ 0.0+1.0i 0.0) 0.0+1.0i) (num-test (+ 0.0+1.0i 0.0+1.0i) 0.0+2.0i) (num-test (+ 0.0+1.0i 1) 1.0+1.0i) (num-test (+ 0.0+1.0i 1.0) 1.0+1.0i) (num-test (+ 0.0+1.0i 1.0+1.0i) 1.0+2.0i) (num-test (+ 0.0+1.0i 1.234+1.234i) 1.234+2.234i) (num-test (+ 0.0+1.0i 1/1) 1.0+1.0i) (num-test (+ 0.0+1.0i 123.4) 123.4+1.0i) (num-test (+ 0.0+1.0i 1234) 1234.0+1.0i) (num-test (+ 0.0+1.0i 1234/11) 112.18181818181819+1.0i) (num-test (+ 0/1) 0/1) (num-test (+ 0/1) 0/1) (num-test (+ 1 -1.0+1.0i) 0.0+1.0i) (num-test (+ 1 0) 1) (num-test (+ 1 0.0) 1.0) (num-test (+ 1 0.0+1.0i) 1.0+1.0i) (num-test (+ 1 1 -1.0+1.0i) 1.0+1.0i) (num-test (+ 1 1 0) 2) (num-test (+ 1 1 0.0) 2.0) (num-test (+ 1 1 0.0+1.0i) 2.0+1.0i) (num-test (+ 1 1 1) 3) (num-test (+ 1 1 1.0) 3.0) (num-test (+ 1 1 1.0+1.0i) 3.0+1.0i) (num-test (+ 1 1 1.234+1.234i) 3.234+1.234i) (num-test (+ 1 1 1/1) 3) (num-test (+ 1 1 123.4) 125.4) (num-test (+ 1 1 1234) 1236) (num-test (+ 1 1 1234/11) 1256/11) (num-test (+ 1 1) 2) (num-test (+ 1 1.0 -1.0+1.0i) 1.0+1.0i) (num-test (+ 1 1.0 0) 2.0) (num-test (+ 1 1.0 0.0) 2.0) (num-test (+ 1 1.0 0.0+1.0i) 2.0+1.0i) (num-test (+ 1 1.0 1) 3.0) (num-test (+ 1 1.0 1.0) 3.0) (num-test (+ 1 1.0 1.0+1.0i) 3.0+1.0i) (num-test (+ 1 1.0 1.234+1.234i) 3.234+1.234i) (num-test (+ 1 1.0 1/1) 3.0) (num-test (+ 1 1.0 123.4) 125.4) (num-test (+ 1 1.0 1234) 1236.0) (num-test (+ 1 1.0 1234/11) 114.18181818181819) (num-test (+ 1 1.0) 2.0) (num-test (+ 1 1.0+1.0i -1.0+1.0i) 1.0+2.0i) (num-test (+ 1 1.0+1.0i 0) 2.0+1.0i) (num-test (+ 1 1.0+1.0i 0.0) 2.0+1.0i) (num-test (+ 1 1.0+1.0i 0.0+1.0i) 2.0+2.0i) (num-test (+ 1 1.0+1.0i 1) 3.0+1.0i) (num-test (+ 1 1.0+1.0i 1.0) 3.0+1.0i) (num-test (+ 1 1.0+1.0i 1.0+1.0i) 3.0+2.0i) (num-test (+ 1 1.0+1.0i 1.234+1.234i) 3.234+2.234i) (num-test (+ 1 1.0+1.0i 1/1) 3.0+1.0i) (num-test (+ 1 1.0+1.0i 123.4) 125.4+1.0i) (num-test (+ 1 1.0+1.0i 1234) 1236.0+1.0i) (num-test (+ 1 1.0+1.0i 1234/11) 114.18181818181819+1.0i) (num-test (+ 1 1.0+1.0i) 2.0+1.0i) (num-test (+ 1 1.234+1.234i) 2.234+1.234i) (num-test (+ 1 123.4) 124.4) (num-test (+ 1 1234) 1235) (num-test (+ 1 1234/11) 1245/11) (num-test (+ 1.0 -1.0+1.0i -1.0+1.0i) -1.0+2.0i) (num-test (+ 1.0 -1.0+1.0i 0) 0.0+1.0i) (num-test (+ 1.0 -1.0+1.0i 0.0) 0.0+1.0i) (num-test (+ 1.0 -1.0+1.0i 0.0+1.0i) 0.0+2.0i) (num-test (+ 1.0 -1.0+1.0i 1) 1.0+1.0i) (num-test (+ 1.0 -1.0+1.0i 1.0) 1.0+1.0i) (num-test (+ 1.0 -1.0+1.0i 1.0+1.0i) 1.0+2.0i) (num-test (+ 1.0 -1.0+1.0i 1.234+1.234i) 1.234+2.234i) (num-test (+ 1.0 -1.0+1.0i 1/1) 1.0+1.0i) (num-test (+ 1.0 -1.0+1.0i 123.4) 123.4+1.0i) (num-test (+ 1.0 -1.0+1.0i 1234) 1234.0+1.0i) (num-test (+ 1.0 -1.0+1.0i 1234/11) 112.18181818181819+1.0i) (num-test (+ 1.0 -1.0+1.0i) 0.0+1.0i) (num-test (+ 1.0 0 -1.0+1.0i) 0.0+1.0i) (num-test (+ 1.0 0 0) 1.0) (num-test (+ 1.0 0 0.0) 1.0) (num-test (+ 1.0 0 0.0+1.0i) 1.0+1.0i) (num-test (+ 1.0 0 1) 2.0) (num-test (+ 1.0 0 1.0) 2.0) (num-test (+ 1.0 0 1.0+1.0i) 2.0+1.0i) (num-test (+ 1.0 0 1.234+1.234i) 2.234+1.234i) (num-test (+ 1.0 0 1/1) 2.0) (num-test (+ 1.0 0 123.4) 124.4) (num-test (+ 1.0 0 1234) 1235.0) (num-test (+ 1.0 0 1234/11) 113.18181818181819) (num-test (+ 1.0 0) 1.0) (num-test (+ 1.0 0.0 -1.0+1.0i) 0.0+1.0i) (num-test (+ 1.0 0.0 0) 1.0) (num-test (+ 1.0 0.0 0.0) 1.0) (num-test (+ 1.0 0.0 0.0+1.0i) 1.0+1.0i) (num-test (+ 1.0 0.0 1) 2.0) (num-test (+ 1.0 0.0 1.0) 2.0) (num-test (+ 1.0 0.0 1.0+1.0i) 2.0+1.0i) (num-test (+ 1.0 0.0 1.234+1.234i) 2.234+1.234i) (num-test (+ 1.0 0.0 1/1) 2.0) (num-test (+ 1.0 0.0 123.4) 124.4) (num-test (+ 1.0 0.0 1234) 1235.0) (num-test (+ 1.0 0.0 1234/11) 113.18181818181819) (num-test (+ 1.0 0.0) 1.0) (num-test (+ 1.0 0.0+1.0i -1.0+1.0i) 0.0+2.0i) (num-test (+ 1.0 0.0+1.0i 0) 1.0+1.0i) (num-test (+ 1.0 0.0+1.0i 0.0) 1.0+1.0i) (num-test (+ 1.0 0.0+1.0i 0.0+1.0i) 1.0+2.0i) (num-test (+ 1.0 0.0+1.0i 1) 2.0+1.0i) (num-test (+ 1.0 0.0+1.0i 1.0) 2.0+1.0i) (num-test (+ 1.0 0.0+1.0i 1.0+1.0i) 2.0+2.0i) (num-test (+ 1.0 0.0+1.0i 1.234+1.234i) 2.234+2.234i) (num-test (+ 1.0 0.0+1.0i 1/1) 2.0+1.0i) (num-test (+ 1.0 0.0+1.0i 123.4) 124.4+1.0i) (num-test (+ 1.0 0.0+1.0i 1234) 1235.0+1.0i) (num-test (+ 1.0 0.0+1.0i 1234/11) 113.18181818181819+1.0i) (num-test (+ 1.0 0.0+1.0i) 1.0+1.0i) (num-test (+ 1.0 1 -1.0+1.0i) 1.0+1.0i) (num-test (+ 1.0 1 0) 2.0) (num-test (+ 1.0 1 0.0) 2.0) (num-test (+ 1.0 1 0.0+1.0i) 2.0+1.0i) (num-test (+ 1.0 1 1) 3.0) (num-test (+ 1.0 1 1.0) 3.0) (num-test (+ 1.0 1 1.0+1.0i) 3.0+1.0i) (num-test (+ 1.0 1 1.234+1.234i) 3.234+1.234i) (num-test (+ 1.0 1 1/1) 3.0) (num-test (+ 1.0 1 123.4) 125.4) (num-test (+ 1.0 1 1234) 1236.0) (num-test (+ 1.0 1 1234/11) 114.18181818181819) (num-test (+ 1.0 1) 2.0) (num-test (+ 1.0 1.0 -1.0+1.0i) 1.0+1.0i) (num-test (+ 1.0 1.0 0) 2.0) (num-test (+ 1.0 1.0 0.0) 2.0) (num-test (+ 1.0 1.0 0.0+1.0i) 2.0+1.0i) (num-test (+ 1.0 1.0 1) 3.0) (num-test (+ 1.0 1.0 1.0) 3.0) (num-test (+ 1.0 1.0 1.0+1.0i) 3.0+1.0i) (num-test (+ 1.0 1.0 1.234+1.234i) 3.234+1.234i) (num-test (+ 1.0 1.0 1/1) 3.0) (num-test (+ 1.0 1.0 123.4) 125.4) (num-test (+ 1.0 1.0 1234) 1236.0) (num-test (+ 1.0 1.0 1234/11) 114.18181818181819) (num-test (+ 1.0 1.0) 2.0) (num-test (+ 1.0 1.0+1.0i -1.0+1.0i) 1.0+2.0i) (num-test (+ 1.0 1.0+1.0i 0) 2.0+1.0i) (num-test (+ 1.0 1.0+1.0i 0.0) 2.0+1.0i) (num-test (+ 1.0 1.0+1.0i 0.0+1.0i) 2.0+2.0i) (num-test (+ 1.0 1.0+1.0i 1) 3.0+1.0i) (num-test (+ 1.0 1.0+1.0i 1.0) 3.0+1.0i) (num-test (+ 1.0 1.0+1.0i 1.0+1.0i) 3.0+2.0i) (num-test (+ 1.0 1.0+1.0i 1.234+1.234i) 3.234+2.234i) (num-test (+ 1.0 1.0+1.0i 1/1) 3.0+1.0i) (num-test (+ 1.0 1.0+1.0i 123.4) 125.4+1.0i) (num-test (+ 1.0 1.0+1.0i 1234) 1236.0+1.0i) (num-test (+ 1.0 1.0+1.0i 1234/11) 114.18181818181819+1.0i) (num-test (+ 1.0 1.0+1.0i) 2.0+1.0i) (num-test (+ 1.0 1.234+1.234i -1.0+1.0i) 1.234+2.234i) (num-test (+ 1.0 1.234+1.234i 0) 2.234+1.234i) (num-test (+ 1.0 1.234+1.234i 0.0) 2.234+1.234i) (num-test (+ 1.0 1.234+1.234i 0.0+1.0i) 2.234+2.234i) (num-test (+ 1.0 1.234+1.234i 1) 3.234+1.234i) (num-test (+ 1.0 1.234+1.234i 1.0) 3.234+1.234i) (num-test (+ 1.0 1.234+1.234i 1.0+1.0i) 3.234+2.234i) (num-test (+ 1.0 1.234+1.234i 1.234+1.234i) 3.468+2.468i) (num-test (+ 1.0 1.234+1.234i 1/1) 3.234+1.234i) (num-test (+ 1.0 1.234+1.234i 123.4) 125.634+1.234i) (num-test (+ 1.0 1.234+1.234i 1234) 1236.23399999999992+1.234i) (num-test (+ 1.0 1.234+1.234i 1234/11) 114.41581818181818+1.234i) (num-test (+ 1.0 1.234+1.234i) 2.234+1.234i) (num-test (+ 1.0 1/1 -1.0+1.0i) 1.0+1.0i) (num-test (+ 1.0 123.4 -1.0+1.0i) 123.4+1.0i) (num-test (+ 1.0 123.4 0) 124.4) (num-test (+ 1.0 123.4 0.0) 124.4) (num-test (+ 1.0 123.4 0.0+1.0i) 124.4+1.0i) (num-test (+ 1.0 123.4 1) 125.4) (num-test (+ 1.0 123.4 1.0) 125.4) (num-test (+ 1.0 123.4 1.0+1.0i) 125.4+1.0i) (num-test (+ 1.0 123.4 1.234+1.234i) 125.634+1.234i) (num-test (+ 1.0 123.4 1/1) 125.4) (num-test (+ 1.0 123.4 123.4) 247.8) (num-test (+ 1.0 123.4 1234) 1358.4) (num-test (+ 1.0 123.4 1234/11) 236.58181818181819) (num-test (+ 1.0 123.4) 124.4) (num-test (+ 1.0 1234 -1.0+1.0i) 1234.0+1.0i) (num-test (+ 1.0 1234 0) 1235.0) (num-test (+ 1.0 1234 0.0) 1235.0) (num-test (+ 1.0 1234 0.0+1.0i) 1235.0+1.0i) (num-test (+ 1.0 1234 1) 1236.0) (num-test (+ 1.0 1234 1.0) 1236.0) (num-test (+ 1.0 1234 1.0+1.0i) 1236.0+1.0i) (num-test (+ 1.0 1234 1.234+1.234i) 1236.23399999999992+1.234i) (num-test (+ 1.0 1234 1/1) 1236.0) (num-test (+ 1.0 1234 123.4) 1358.4) (num-test (+ 1.0 1234 1234) 2469.0) (num-test (+ 1.0 1234 1234/11) 1347.18181818181824) (num-test (+ 1.0 1234) 1235.0) (num-test (+ 1.0 1234/11 -1.0+1.0i) 112.18181818181819+1.0i) (num-test (+ 1.0 1234/11 0) 113.18181818181819) (num-test (+ 1.0 1234/11 0.0) 113.18181818181819) (num-test (+ 1.0 1234/11 0.0+1.0i) 113.18181818181819+1.0i) (num-test (+ 1.0 1234/11 1) 114.18181818181819) (num-test (+ 1.0 1234/11 1.0) 114.18181818181819) (num-test (+ 1.0 1234/11 1.0+1.0i) 114.18181818181819+1.0i) (num-test (+ 1.0 1234/11 1.234+1.234i) 114.41581818181818+1.234i) (num-test (+ 1.0 1234/11 1/1) 114.18181818181819) (num-test (+ 1.0 1234/11 123.4) 236.58181818181819) (num-test (+ 1.0 1234/11 1234) 1347.18181818181824) (num-test (+ 1.0 1234/11 1234/11) 225.36363636363637) (num-test (+ 1.0 1234/11) 113.18181818181819) (num-test (+ 1.0) 1.0) (num-test (+ 1.0+1.0i -1.0+1.0i -1.0+1.0i) -1.0+3.0i) (num-test (+ 1.0+1.0i -1.0+1.0i 0) 0.0+2.0i) (num-test (+ 1.0+1.0i -1.0+1.0i 0.0) 0.0+2.0i) (num-test (+ 1.0+1.0i -1.0+1.0i 0.0+1.0i) 0.0+3.0i) (num-test (+ 1.0+1.0i -1.0+1.0i 1) 1.0+2.0i) (num-test (+ 1.0+1.0i -1.0+1.0i 1.0) 1.0+2.0i) (num-test (+ 1.0+1.0i -1.0+1.0i 1.0+1.0i) 1.0+3.0i) (num-test (+ 1.0+1.0i -1.0+1.0i 1.234+1.234i) 1.234+3.234i) (num-test (+ 1.0+1.0i -1.0+1.0i 1/1) 1.0+2.0i) (num-test (+ 1.0+1.0i -1.0+1.0i 123.4) 123.4+2.0i) (num-test (+ 1.0+1.0i -1.0+1.0i 1234) 1234.0+2.0i) (num-test (+ 1.0+1.0i -1.0+1.0i 1234/11) 112.18181818181819+2.0i) (num-test (+ 1.0+1.0i -1.0+1.0i) 0.0+2.0i) (num-test (+ 1.0+1.0i 0 -1.0+1.0i) 0.0+2.0i) (num-test (+ 1.0+1.0i 0 0) 1.0+1.0i) (num-test (+ 1.0+1.0i 0 0.0) 1.0+1.0i) (num-test (+ 1.0+1.0i 0 0.0+1.0i) 1.0+2.0i) (num-test (+ 1.0+1.0i 0 1) 2.0+1.0i) (num-test (+ 1.0+1.0i 0 1.0) 2.0+1.0i) (num-test (+ 1.0+1.0i 0 1.0+1.0i) 2.0+2.0i) (num-test (+ 1.0+1.0i 0 1.234+1.234i) 2.234+2.234i) (num-test (+ 1.0+1.0i 0 1/1) 2.0+1.0i) (num-test (+ 1.0+1.0i 0 123.4) 124.4+1.0i) (num-test (+ 1.0+1.0i 0 1234) 1235.0+1.0i) (num-test (+ 1.0+1.0i 0 1234/11) 113.18181818181819+1.0i) (num-test (+ 1.0+1.0i 0) 1.0+1.0i) (num-test (+ 1.0+1.0i 0.0 -1.0+1.0i) 0.0+2.0i) (num-test (+ 1.0+1.0i 0.0 0) 1.0+1.0i) (num-test (+ 1.0+1.0i 0.0 0.0) 1.0+1.0i) (num-test (+ 1.0+1.0i 0.0 0.0+1.0i) 1.0+2.0i) (num-test (+ 1.0+1.0i 0.0 1) 2.0+1.0i) (num-test (+ 1.0+1.0i 0.0 1.0) 2.0+1.0i) (num-test (+ 1.0+1.0i 0.0 1.0+1.0i) 2.0+2.0i) (num-test (+ 1.0+1.0i 0.0 1.234+1.234i) 2.234+2.234i) (num-test (+ 1.0+1.0i 0.0 1/1) 2.0+1.0i) (num-test (+ 1.0+1.0i 0.0 123.4) 124.4+1.0i) (num-test (+ 1.0+1.0i 0.0 1234) 1235.0+1.0i) (num-test (+ 1.0+1.0i 0.0 1234/11) 113.18181818181819+1.0i) (num-test (+ 1.0+1.0i 0.0) 1.0+1.0i) (num-test (+ 1.0+1.0i 0.0+1.0i -1.0+1.0i) 0.0+3.0i) (num-test (+ 1.0+1.0i 0.0+1.0i 0) 1.0+2.0i) (num-test (+ 1.0+1.0i 0.0+1.0i 0.0) 1.0+2.0i) (num-test (+ 1.0+1.0i 0.0+1.0i 0.0+1.0i) 1.0+3.0i) (num-test (+ 1.0+1.0i 0.0+1.0i 1) 2.0+2.0i) (num-test (+ 1.0+1.0i 0.0+1.0i 1.0) 2.0+2.0i) (num-test (+ 1.0+1.0i 0.0+1.0i 1.0+1.0i) 2.0+3.0i) (num-test (+ 1.0+1.0i 0.0+1.0i 1.234+1.234i) 2.234+3.234i) (num-test (+ 1.0+1.0i 0.0+1.0i 1/1) 2.0+2.0i) (num-test (+ 1.0+1.0i 0.0+1.0i 123.4) 124.4+2.0i) (num-test (+ 1.0+1.0i 0.0+1.0i 1234) 1235.0+2.0i) (num-test (+ 1.0+1.0i 0.0+1.0i 1234/11) 113.18181818181819+2.0i) (num-test (+ 1.0+1.0i 0.0+1.0i) 1.0+2.0i) (num-test (+ 1.0+1.0i 1 -1.0+1.0i) 1.0+2.0i) (num-test (+ 1.0+1.0i 1 0) 2.0+1.0i) (num-test (+ 1.0+1.0i 1 0.0) 2.0+1.0i) (num-test (+ 1.0+1.0i 1 0.0+1.0i) 2.0+2.0i) (num-test (+ 1.0+1.0i 1 1) 3.0+1.0i) (num-test (+ 1.0+1.0i 1 1.0) 3.0+1.0i) (num-test (+ 1.0+1.0i 1 1.0+1.0i) 3.0+2.0i) (num-test (+ 1.0+1.0i 1 1.234+1.234i) 3.234+2.234i) (num-test (+ 1.0+1.0i 1 1/1) 3.0+1.0i) (num-test (+ 1.0+1.0i 1 123.4) 125.4+1.0i) (num-test (+ 1.0+1.0i 1 1234) 1236.0+1.0i) (num-test (+ 1.0+1.0i 1 1234/11) 114.18181818181819+1.0i) (num-test (+ 1.0+1.0i 1) 2.0+1.0i) (num-test (+ 1.0+1.0i 1.0 -1.0+1.0i) 1.0+2.0i) (num-test (+ 1.0+1.0i 1.0 0) 2.0+1.0i) (num-test (+ 1.0+1.0i 1.0 0.0) 2.0+1.0i) (num-test (+ 1.0+1.0i 1.0 0.0+1.0i) 2.0+2.0i) (num-test (+ 1.0+1.0i 1.0 1) 3.0+1.0i) (num-test (+ 1.0+1.0i 1.0 1.0) 3.0+1.0i) (num-test (+ 1.0+1.0i 1.0 1.0+1.0i) 3.0+2.0i) (num-test (+ 1.0+1.0i 1.0 1.234+1.234i) 3.234+2.234i) (num-test (+ 1.0+1.0i 1.0 1/1) 3.0+1.0i) (num-test (+ 1.0+1.0i 1.0 123.4) 125.4+1.0i) (num-test (+ 1.0+1.0i 1.0 1234) 1236.0+1.0i) (num-test (+ 1.0+1.0i 1.0 1234/11) 114.18181818181819+1.0i) (num-test (+ 1.0+1.0i 1.0) 2.0+1.0i) (num-test (+ 1.0+1.0i 1.0+1.0i -1.0+1.0i) 1.0+3.0i) (num-test (+ 1.0+1.0i 1.0+1.0i 0) 2.0+2.0i) (num-test (+ 1.0+1.0i 1.0+1.0i 0.0) 2.0+2.0i) (num-test (+ 1.0+1.0i 1.0+1.0i 0.0+1.0i) 2.0+3.0i) (num-test (+ 1.0+1.0i 1.0+1.0i 1) 3.0+2.0i) (num-test (+ 1.0+1.0i 1.0+1.0i 1.0) 3.0+2.0i) (num-test (+ 1.0+1.0i 1.0+1.0i 1.0+1.0i) 3.0+3.0i) (num-test (+ 1.0+1.0i 1.0+1.0i 1.234+1.234i) 3.234+3.234i) (num-test (+ 1.0+1.0i 1.0+1.0i 1/1) 3.0+2.0i) (num-test (+ 1.0+1.0i 1.0+1.0i 123.4) 125.4+2.0i) (num-test (+ 1.0+1.0i 1.0+1.0i 1234) 1236.0+2.0i) (num-test (+ 1.0+1.0i 1.0+1.0i 1234/11) 114.18181818181819+2.0i) (num-test (+ 1.0+1.0i 1.0+1.0i) 2.0+2.0i) (num-test (+ 1.0+1.0i 1.234+1.234i -1.0+1.0i) 1.234+3.234i) (num-test (+ 1.0+1.0i 1.234+1.234i 0) 2.234+2.234i) (num-test (+ 1.0+1.0i 1.234+1.234i 0.0) 2.234+2.234i) (num-test (+ 1.0+1.0i 1.234+1.234i 0.0+1.0i) 2.234+3.234i) (num-test (+ 1.0+1.0i 1.234+1.234i 1) 3.234+2.234i) (num-test (+ 1.0+1.0i 1.234+1.234i 1.0) 3.234+2.234i) (num-test (+ 1.0+1.0i 1.234+1.234i 1.0+1.0i) 3.234+3.234i) (num-test (+ 1.0+1.0i 1.234+1.234i 1.234+1.234i) 3.468+3.468i) (num-test (+ 1.0+1.0i 1.234+1.234i 1/1) 3.234+2.234i) (num-test (+ 1.0+1.0i 1.234+1.234i 123.4) 125.634+2.234i) (num-test (+ 1.0+1.0i 1.234+1.234i 1234) 1236.23399999999992+2.234i) (num-test (+ 1.0+1.0i 1.234+1.234i 1234/11) 114.41581818181818+2.234i) (num-test (+ 1.0+1.0i 1.234+1.234i) 2.234+2.234i) (num-test (+ 1.0+1.0i 123.4 -1.0+1.0i) 123.4+2.0i) (num-test (+ 1.0+1.0i 123.4 0) 124.4+1.0i) (num-test (+ 1.0+1.0i 123.4 0.0) 124.4+1.0i) (num-test (+ 1.0+1.0i 123.4 0.0+1.0i) 124.4+2.0i) (num-test (+ 1.0+1.0i 123.4 1) 125.4+1.0i) (num-test (+ 1.0+1.0i 123.4 1.0) 125.4+1.0i) (num-test (+ 1.0+1.0i 123.4 1.0+1.0i) 125.4+2.0i) (num-test (+ 1.0+1.0i 123.4 1.234+1.234i) 125.634+2.234i) (num-test (+ 1.0+1.0i 123.4 1/1) 125.4+1.0i) (num-test (+ 1.0+1.0i 123.4 123.4) 247.8+1.0i) (num-test (+ 1.0+1.0i 123.4 1234) 1358.4+1.0i) (num-test (+ 1.0+1.0i 123.4 1234/11) 236.58181818181819+1.0i) (num-test (+ 1.0+1.0i 123.4) 124.4+1.0i) (num-test (+ 1.0+1.0i 1234 -1.0+1.0i) 1234.0+2.0i) (num-test (+ 1.0+1.0i 1234 0) 1235.0+1.0i) (num-test (+ 1.0+1.0i 1234 0.0) 1235.0+1.0i) (num-test (+ 1.0+1.0i 1234 0.0+1.0i) 1235.0+2.0i) (num-test (+ 1.0+1.0i 1234 1) 1236.0+1.0i) (num-test (+ 1.0+1.0i 1234 1.0) 1236.0+1.0i) (num-test (+ 1.0+1.0i 1234 1.0+1.0i) 1236.0+2.0i) (num-test (+ 1.0+1.0i 1234 1.234+1.234i) 1236.23399999999992+2.234i) (num-test (+ 1.0+1.0i 1234 1/1) 1236.0+1.0i) (num-test (+ 1.0+1.0i 1234 123.4) 1358.4+1.0i) (num-test (+ 1.0+1.0i 1234 1234) 2469.0+1.0i) (num-test (+ 1.0+1.0i 1234 1234/11) 1347.18181818181824+1.0i) (num-test (+ 1.0+1.0i 1234) 1235.0+1.0i) (num-test (+ 1.0+1.0i 1234/11 -1.0+1.0i) 112.18181818181819+2.0i) (num-test (+ 1.0+1.0i 1234/11 0) 113.18181818181819+1.0i) (num-test (+ 1.0+1.0i 1234/11 0.0) 113.18181818181819+1.0i) (num-test (+ 1.0+1.0i 1234/11 0.0+1.0i) 113.18181818181819+2.0i) (num-test (+ 1.0+1.0i 1234/11 1) 114.18181818181819+1.0i) (num-test (+ 1.0+1.0i 1234/11 1.0) 114.18181818181819+1.0i) (num-test (+ 1.0+1.0i 1234/11 1.0+1.0i) 114.18181818181819+2.0i) (num-test (+ 1.0+1.0i 1234/11 1.234+1.234i) 114.41581818181818+2.234i) (num-test (+ 1.0+1.0i 1234/11 1/1) 114.18181818181819+1.0i) (num-test (+ 1.0+1.0i 1234/11 123.4) 236.58181818181819+1.0i) (num-test (+ 1.0+1.0i 1234/11 1234) 1347.18181818181824+1.0i) (num-test (+ 1.0+1.0i 1234/11 1234/11) 225.36363636363637+1.0i) (num-test (+ 1.0+1.0i 1234/11) 113.18181818181819+1.0i) (num-test (+ 1.0+1.0i) 1.0+1.0i) (num-test (+ 1.234+1.234i -1.0+1.0i) 0.234+2.234i) (num-test (+ 1.234+1.234i 0) 1.234+1.234i) (num-test (+ 1.234+1.234i 0.0) 1.234+1.234i) (num-test (+ 1.234+1.234i 0.0+1.0i) 1.234+2.234i) (num-test (+ 1.234+1.234i 1) 2.234+1.234i) (num-test (+ 1.234+1.234i 1.0) 2.234+1.234i) (num-test (+ 1.234+1.234i 1.0+1.0i) 2.234+2.234i) (num-test (+ 1.234+1.234i 1.234+1.234i) 2.468+2.468i) (num-test (+ 1.234+1.234i 1/1) 2.234+1.234i) (num-test (+ 1.234+1.234i 123.4) 124.634+1.234i) (num-test (+ 1.234+1.234i 1234) 1235.23399999999992+1.234i) (num-test (+ 1.234+1.234i 1234/11) 113.41581818181818+1.234i) (num-test (+ 10) 10) (num-test (+ 10/3) 10/3) (num-test (+ 123.4 -1.0+1.0i -1.0+1.0i) 121.4+2.0i) (num-test (+ 123.4 -1.0+1.0i 0) 122.4+1.0i) (num-test (+ 123.4 -1.0+1.0i 0.0) 122.4+1.0i) (num-test (+ 123.4 -1.0+1.0i 0.0+1.0i) 122.4+2.0i) (num-test (+ 123.4 -1.0+1.0i 1) 123.4+1.0i) (num-test (+ 123.4 -1.0+1.0i 1.0) 123.4+1.0i) (num-test (+ 123.4 -1.0+1.0i 1.0+1.0i) 123.4+2.0i) (num-test (+ 123.4 -1.0+1.0i 1.234+1.234i) 123.634+2.234i) (num-test (+ 123.4 -1.0+1.0i 1/1) 123.4+1.0i) (num-test (+ 123.4 -1.0+1.0i 123.4) 245.8+1.0i) (num-test (+ 123.4 -1.0+1.0i 1234) 1356.4+1.0i) (num-test (+ 123.4 -1.0+1.0i 1234/11) 234.58181818181819+1.0i) (num-test (+ 123.4 -1.0+1.0i) 122.4+1.0i) (num-test (+ 123.4 0 -1.0+1.0i) 122.4+1.0i) (num-test (+ 123.4 0 0) 123.4) (num-test (+ 123.4 0 0.0) 123.4) (num-test (+ 123.4 0 0.0+1.0i) 123.4+1.0i) (num-test (+ 123.4 0 1) 124.4) (num-test (+ 123.4 0 1.0) 124.4) (num-test (+ 123.4 0 1.0+1.0i) 124.4+1.0i) (num-test (+ 123.4 0 1.234+1.234i) 124.634+1.234i) (num-test (+ 123.4 0 1/1) 124.4) (num-test (+ 123.4 0 123.4) 246.8) (num-test (+ 123.4 0 1234) 1357.4) (num-test (+ 123.4 0 1234/11) 235.58181818181819) (num-test (+ 123.4 0) 123.4) (num-test (+ 123.4 0.0 -1.0+1.0i) 122.4+1.0i) (num-test (+ 123.4 0.0 0) 123.4) (num-test (+ 123.4 0.0 0.0) 123.4) (num-test (+ 123.4 0.0 0.0+1.0i) 123.4+1.0i) (num-test (+ 123.4 0.0 1) 124.4) (num-test (+ 123.4 0.0 1.0) 124.4) (num-test (+ 123.4 0.0 1.0+1.0i) 124.4+1.0i) (num-test (+ 123.4 0.0 1.234+1.234i) 124.634+1.234i) (num-test (+ 123.4 0.0 1/1) 124.4) (num-test (+ 123.4 0.0 123.4) 246.8) (num-test (+ 123.4 0.0 1234) 1357.4) (num-test (+ 123.4 0.0 1234/11) 235.58181818181819) (num-test (+ 123.4 0.0) 123.4) (num-test (+ 123.4 0.0+1.0i -1.0+1.0i) 122.4+2.0i) (num-test (+ 123.4 0.0+1.0i 0) 123.4+1.0i) (num-test (+ 123.4 0.0+1.0i 0.0) 123.4+1.0i) (num-test (+ 123.4 0.0+1.0i 0.0+1.0i) 123.4+2.0i) (num-test (+ 123.4 0.0+1.0i 1) 124.4+1.0i) (num-test (+ 123.4 0.0+1.0i 1.0) 124.4+1.0i) (num-test (+ 123.4 0.0+1.0i 1.0+1.0i) 124.4+2.0i) (num-test (+ 123.4 0.0+1.0i 1.234+1.234i) 124.634+2.234i) (num-test (+ 123.4 0.0+1.0i 1/1) 124.4+1.0i) (num-test (+ 123.4 0.0+1.0i 123.4) 246.8+1.0i) (num-test (+ 123.4 0.0+1.0i 1234) 1357.4+1.0i) (num-test (+ 123.4 0.0+1.0i 1234/11) 235.58181818181819+1.0i) (num-test (+ 123.4 0.0+1.0i) 123.4+1.0i) (num-test (+ 123.4 1 -1.0+1.0i) 123.4+1.0i) (num-test (+ 123.4 1 0) 124.4) (num-test (+ 123.4 1 0.0) 124.4) (num-test (+ 123.4 1 0.0+1.0i) 124.4+1.0i) (num-test (+ 123.4 1 1) 125.4) (num-test (+ 123.4 1 1.0) 125.4) (num-test (+ 123.4 1 1.0+1.0i) 125.4+1.0i) (num-test (+ 123.4 1 1.234+1.234i) 125.634+1.234i) (num-test (+ 123.4 1 1/1) 125.4) (num-test (+ 123.4 1 123.4) 247.8) (num-test (+ 123.4 1 1234) 1358.4) (num-test (+ 123.4 1 1234/11) 236.58181818181819) (num-test (+ 123.4 1) 124.4) (num-test (+ 123.4 1.0 -1.0+1.0i) 123.4+1.0i) (num-test (+ 123.4 1.0 0) 124.4) (num-test (+ 123.4 1.0 0.0) 124.4) (num-test (+ 123.4 1.0 0.0+1.0i) 124.4+1.0i) (num-test (+ 123.4 1.0 1) 125.4) (num-test (+ 123.4 1.0 1.0) 125.4) (num-test (+ 123.4 1.0 1.0+1.0i) 125.4+1.0i) (num-test (+ 123.4 1.0 1.234+1.234i) 125.634+1.234i) (num-test (+ 123.4 1.0 1/1) 125.4) (num-test (+ 123.4 1.0 123.4) 247.8) (num-test (+ 123.4 1.0 1234) 1358.4) (num-test (+ 123.4 1.0 1234/11) 236.58181818181819) (num-test (+ 123.4 1.0) 124.4) (num-test (+ 123.4 1.0+1.0i -1.0+1.0i) 123.4+2.0i) (num-test (+ 123.4 1.0+1.0i 0) 124.4+1.0i) (num-test (+ 123.4 1.0+1.0i 0.0) 124.4+1.0i) (num-test (+ 123.4 1.0+1.0i 0.0+1.0i) 124.4+2.0i) (num-test (+ 123.4 1.0+1.0i 1) 125.4+1.0i) (num-test (+ 123.4 1.0+1.0i 1.0) 125.4+1.0i) (num-test (+ 123.4 1.0+1.0i 1.0+1.0i) 125.4+2.0i) (num-test (+ 123.4 1.0+1.0i 1.234+1.234i) 125.634+2.234i) (num-test (+ 123.4 1.0+1.0i 1/1) 125.4+1.0i) (num-test (+ 123.4 1.0+1.0i 123.4) 247.8+1.0i) (num-test (+ 123.4 1.0+1.0i 1234) 1358.4+1.0i) (num-test (+ 123.4 1.0+1.0i 1234/11) 236.58181818181819+1.0i) (num-test (+ 123.4 1.0+1.0i) 124.4+1.0i) (num-test (+ 123.4 1.234+1.234i -1.0+1.0i) 123.634+2.234i) (num-test (+ 123.4 1.234+1.234i 0) 124.634+1.234i) (num-test (+ 123.4 1.234+1.234i 0.0) 124.634+1.234i) (num-test (+ 123.4 1.234+1.234i 0.0+1.0i) 124.634+2.234i) (num-test (+ 123.4 1.234+1.234i 1) 125.634+1.234i) (num-test (+ 123.4 1.234+1.234i 1.0) 125.634+1.234i) (num-test (+ 123.4 1.234+1.234i 1.0+1.0i) 125.634+2.234i) (num-test (+ 123.4 1.234+1.234i 1.234+1.234i) 125.86799999999999+2.468i) (num-test (+ 123.4 1.234+1.234i 1/1) 125.634+1.234i) (num-test (+ 123.4 1.234+1.234i 123.4) 248.03399999999999+1.234i) (num-test (+ 123.4 1.234+1.234i 1234) 1358.63400000000001+1.234i) (num-test (+ 123.4 1.234+1.234i 1234/11) 236.81581818181817+1.234i) (num-test (+ 123.4 1.234+1.234i) 124.634+1.234i) (num-test (+ 123.4 1/1 -1.0+1.0i) 123.4+1.0i) (num-test (+ 123.4 123.4 -1.0+1.0i) 245.8+1.0i) (num-test (+ 123.4 123.4 0) 246.8) (num-test (+ 123.4 123.4 0.0) 246.8) (num-test (+ 123.4 123.4 0.0+1.0i) 246.8+1.0i) (num-test (+ 123.4 123.4 1) 247.8) (num-test (+ 123.4 123.4 1.0) 247.8) (num-test (+ 123.4 123.4 1.0+1.0i) 247.8+1.0i) (num-test (+ 123.4 123.4 1.234+1.234i) 248.03400000000002+1.234i) (num-test (+ 123.4 123.4 1/1) 247.8) (num-test (+ 123.4 123.4 123.4) 370.20000000000005) (num-test (+ 123.4 123.4 1234) 1480.79999999999995) (num-test (+ 123.4 123.4 1234/11) 358.98181818181820) (num-test (+ 123.4 123.4) 246.8) (num-test (+ 123.4 1234 -1.0+1.0i) 1356.4+1.0i) (num-test (+ 123.4 1234 0) 1357.4) (num-test (+ 123.4 1234 0.0) 1357.4) (num-test (+ 123.4 1234 0.0+1.0i) 1357.4+1.0i) (num-test (+ 123.4 1234 1) 1358.4) (num-test (+ 123.4 1234 1.0) 1358.4) (num-test (+ 123.4 1234 1.0+1.0i) 1358.4+1.0i) (num-test (+ 123.4 1234 1.234+1.234i) 1358.63400000000001+1.234i) (num-test (+ 123.4 1234 1/1) 1358.4) (num-test (+ 123.4 1234 123.4) 1480.80000000000018) (num-test (+ 123.4 1234 1234) 2591.4) (num-test (+ 123.4 1234 1234/11) 1469.58181818181833) (num-test (+ 123.4 1234) 1357.4) (num-test (+ 123.4 1234/11 -1.0+1.0i) 234.58181818181819+1.0i) (num-test (+ 123.4 1234/11 0) 235.58181818181819) (num-test (+ 123.4 1234/11 0.0) 235.58181818181819) (num-test (+ 123.4 1234/11 0.0+1.0i) 235.58181818181819+1.0i) (num-test (+ 123.4 1234/11 1) 236.58181818181819) (num-test (+ 123.4 1234/11 1.0) 236.58181818181819) (num-test (+ 123.4 1234/11 1.0+1.0i) 236.58181818181819+1.0i) (num-test (+ 123.4 1234/11 1.234+1.234i) 236.81581818181820+1.234i) (num-test (+ 123.4 1234/11 1/1) 236.58181818181819) (num-test (+ 123.4 1234/11 123.4) 358.98181818181820) (num-test (+ 123.4 1234/11 1234) 1469.58181818181811) (num-test (+ 123.4 1234/11 1234/11) 347.76363636363635) (num-test (+ 123.4 1234/11) 235.58181818181819) (num-test (+ 1234 -1.0+1.0i) 1233.0+1.0i) (num-test (+ 1234 0) 1234) (num-test (+ 1234 0.0) 1234.0) (num-test (+ 1234 0.0+1.0i) 1234.0+1.0i) (num-test (+ 1234 1) 1235) (num-test (+ 1234 1.0) 1235.0) (num-test (+ 1234 1.0+1.0i) 1235.0+1.0i) (num-test (+ 1234 1.234+1.234i) 1235.23399999999992+1.234i) (num-test (+ 1234 1/1) 1235) (num-test (+ 1234 123.4) 1357.4) (num-test (+ 1234 1234) 2468) (num-test (+ 1234 1234/11) 14808/11) (num-test (+ 1234/11 -1.0+1.0i) 111.18181818181819+1.0i) (num-test (+ 1234/11 0) 1234/11) (num-test (+ 1234/11 0.0) 112.18181818181819) (num-test (+ 1234/11 0.0+1.0i) 112.18181818181819+1.0i) (num-test (+ 1234/11 1) 1245/11) (num-test (+ 1234/11 1.0) 113.18181818181819) (num-test (+ 1234/11 1.0+1.0i) 113.18181818181819+1.0i) (num-test (+ 1234/11 1.234+1.234i) 113.41581818181818+1.234i) (num-test (+ 1234/11 1/1) 1245/11) (num-test (+ 1234/11 123.4) 235.58181818181819) (num-test (+ 1234/11 1234) 14808/11) (num-test (+ 1234/11 1234/11) 2468/11) (num-test (+ 1234000000) 1234000000) (num-test (+ 1234000000.0) 1234000000.0) (num-test (+ 1234000000.0+2.71828182845905i) 1234000000.0+2.71828182845905i) (num-test (+ 1234000000.0-2.71828182845905i) 1234000000.0-2.71828182845905i) (num-test (+ 1234000000/10) 1234000000/10) (num-test (+ 2) 2) (num-test (+ 2.71828182845905) 2.71828182845905) (num-test (+ 2.71828182845905+3.14159265358979i) 2.71828182845905+3.14159265358979i) (num-test (+ 2.71828182845905-3.14159265358979i) 2.71828182845905-3.14159265358979i) (num-test (+ 2/2) 2/2) (num-test (+ 362880) 362880) (num-test (+ 362880/1234) 362880/1234) (for-each-permutation (lambda args (if (not (= (apply + args) 3+i)) (format-logged #t "~A: (+ ~{~A~^ ~}) -> ~A?~%" (port-line-number) args (apply + args)))) '(1 1/2 0.5 1+i)) (for-each-permutation (lambda args (if (not (zero? (apply + args))) (format-logged #t "~A: (+ ~{~A~^ ~}) -> ~A?~%" (port-line-number) args (apply + args)))) '(1 1/2 0.5 1+i -1/2 -1 -0.5 -1-i)) (num-test (+ 10.0+0.i) 10.0) (num-test (+ +10.+.0i) 10.0) (test (integer? (+ 1/2 1/2)) #t) (test (real? (+ 1+i 1-i)) #t) (test (integer? (+ 1/100 99/100 (- most-positive-fixnum 2))) #t) ; of course reversing the args won't work (test (integer? (+ 1/1000 999/1000 (- most-positive-fixnum 9223372036854775807))) #t) (num-test (+ 1/1000 999/1000 (- most-positive-fixnum 9223372036854775807)) 1) (test (integer? (+ 1/1000 999/1000 (- most-positive-fixnum 9200000000000000000))) #t) (num-test (+ 1/1000 999/1000 (- most-positive-fixnum 9200000000000000000)) 23372036854775808) (test (+ (rootlet) 1) 'error) (test (< (+ 0.7 8388608) 8388609) #t) ; false in clisp! (num-test (+ -1.797693134862315699999999999999999999998E308 -9223372036854775808) -1.797693134862315699999999999999999999998E308) (num-test (+ -9223372036854775808 5.551115123125783999999999999999999999984E-17) -9.223372036854775807999999999999999944489E18) (num-test (+ -9223372036854775808 9223372036854775807 -9223372036854775808) -9.223372036854775809e18) (num-test (+ -9223372036854775808) -9223372036854775808) (num-test (+ 1.110223024625156799999999999999999999997E-16 -9223372036854775808) -9.223372036854775807999999999999999888978E18) (num-test (+ 1.110223024625156799999999999999999999997E-16 5.551115123125783999999999999999999999984E-17 5.42101086242752217060000000000000000001E-20) 1.665876638023977952217059999999999999994E-16) (num-test (+ 5.551115123125783999999999999999999999984E-17 1.110223024625156799999999999999999999997E-16) 1.665334536937735199999999999999999999992E-16) (num-test (+ 9223372036854775807 -9223372036854775808) -1) (num-test (+ 0.(*)) 1.0) (num-test (+ 0.(+)) 0.0) (num-test (+ 1/9223372036854775807 1/9223372036854775807) 2/9223372036854775807) (num-test (+ 10000000/9223372036854775807 1/3) 3.333333333344175355058188377674583355698E-1) (num-test (+ 1073741824 1073741824 1073741824 1073741824) (* 4 1073741824)) (num-test (+ 268435456/129140163 129140163/268435456 7/19 29/19) 2933929486555791403/658650172313567232) (num-test (+ 268435456/129140163 129140163/268435456 7/29 29/19) 4.327416192871913348352681814704887193821E0) (num-test (+ -9223372036854775808 9223372036854775807) -1) (num-test (+ -9221/92233720 -92233720/9221 9221/92233720 92233720/9221) 0) (num-test (+ (/ most-negative-fixnum 2) (/ most-negative-fixnum 2)) -9223372036854775808) (num-test (+ (/ most-negative-fixnum 2) (/ most-negative-fixnum 2) 1) -9223372036854775807) (num-test (+ (/ most-negative-fixnum 2) (/ most-negative-fixnum 2) -1) (if with-bignums -9223372036854775809 -9.223372036854776e+18)) (num-test (- (/ most-negative-fixnum 2) (/ most-positive-fixnum 2) 1) (if with-bignums -18446744073709551617/2 -9.223372036854776e+18)) (num-test (* 3037000499 3037000500) 9223372033963249500) (num-test (* 3037000499 3037000499) 9223372030926249001) (num-test (* 3037000500 3037000500) (if with-bignums 9223372037000250000 9.223372037000249e+18)) (num-test (/ (* (/ 3037000499) (/ 3037000498))) 9223372027889248502) (num-test (/ (* (/ 3037000500) (/ 3037000500))) (if with-bignums 9223372037000250000 9.223372037000251e+18)) (num-test (/ 3037000499 (/ 3037000499)) 9223372030926249001) (num-test (/ 3037000500 (/ 3037000500)) (if with-bignums 9223372037000250000 9.223372037000251e+18)) (num-test (+ 0.6049332056786565E0 -0.9611373574853808E0) -3.562041518067242999999999999999999999981E-1) (num-test (+ -0.4763715667865308E0 0.25936932107685584E0) -2.170022457096749600000000000000000000008E-1) (num-test (+ 0.2666481927718355E0 -0.04984768063142031E0) 2.168005121404151899999999999999999999994E-1) (num-test (+ -0.29478659758474846E0 0.3371004337672615E0) 4.231383618251304000000000000000000000076E-2) (num-test (+ 0.8203063910979178E0 0.28968607542857916E0) 1.109992466526496959999999999999999999999E0) (num-test (+ -0.08207985138263585E0 0.4368723951711785E0) 3.5479254378854265E-1) (num-test (+ -0.8659875373355486E0 -6.631430771196765E9) -6.6314307720627525373355486E9) (num-test (+ 0.15071385783307878E0 -7.154424279496395E9) -7.154424279345681142166921220000000000013E9) (num-test (+ -0.8969642760814789E0 -2.4070067380831727E8) -2.407006747052815460814789000000000000005E8) (num-test (+ -0.9610362081435054E0 9.070410778399954E9) 9.070410777438917634019580537500000000004E9) (num-test (+ 0.5129052501104072E0 -7.47841120327471E9) -7.478411202761804451427678737500000000008E9) (num-test (+ 0.3840242289740675E0 7.793048210060242E9) 7.793048210444265928192817499999999999991E9) (num-test (+ 0.07603066126204616E0 5.215008470388369E-11) 7.603066131419624470388369000000000000006E-2) (num-test (+ -0.17187858025312586E0 -5.116645189173968E-11) -1.718785803042923118917396799999999999997E-1) (num-test (+ 0.2521315816245864E0 8.603210607505339E-11) 2.521315817106185060750533899999999999992E-1) (num-test (+ -0.3557185853193914E0 -2.0371324697272998E-11) -3.557185853397627246972729979999999999995E-1) (num-test (+ 0.7142792289542045E0 -7.106356053331326E-11) 7.142792288831409394666867399999999999997E-1) (num-test (+ 0.4380415886629452E0 -3.069969538383403E-11) 4.380415886322455046161659700000000000005E-1) (num-test (+ 0.24798614227178573E0 3.972393639614975E19) 3.972393639614975000024798614227178572989E19) (num-test (+ -0.5210677288128815E0 4.846393336901129E19) 4.846393336901128999947893227118711850007E19) (num-test (+ 0.5825404819115E0 1.9710987361264255E19) 1.971098736126425500058254048191149998548E19) (num-test (+ 0.9105175208730549E0 2.391166552096775E19) 2.391166552096775000091051752087305489998E19) (num-test (+ 0.48414423368371695E0 -9.696117779740095E19) -9.696117779740094999951585576631628304997E19) (num-test (+ 0.25780758450697716E0 6.094683117025535E19) 6.094683117025535000025780758450697715991E19) (num-test (+ 0.9824539149570484E0 -5.4680066990812835E-21) 9.824539149570483999945319933009187165013E-1) (num-test (+ -0.9520982941158654E0 3.2513564801568073E-21) -9.520982941158653999967486435198431927013E-1) (num-test (+ 0.0630170624560149E0 -9.858852595793203E-21) 6.301706245601489999014114740420679700008E-2) (num-test (+ 0.24705141169888878E0 1.4582081178692862E-22) 2.470514116988887800001458208117869286195E-1) (num-test (+ 0.7440948700757135E0 -3.0932442581890818E-21) 7.440948700757134999969067557418109181978E-1) (num-test (+ -0.5055970869515372E0 4.0277457257516025E-21) -5.055970869515371999959722542742483974988E-1) (num-test (+ 1.672355787134947E9 0.0064909681594120805E0) 1.6723557871414380296981083695625E9) (num-test (+ -9.694504381396599E9 -0.8925470085542831E0) -9.694504382289146008554283099999999999987E9) (num-test (+ -1.6695005924298635E9 -0.34426964741306E0) -1.669500592774133147413059987073324919041E9) (num-test (+ -6.085591212594774E9 0.5107956920100049E0) -6.085591212083978307989995100000000000004E9) (num-test (+ 7.457486660952688E9 -0.4323787588338597E0) 7.457486660520309458329226237499999999989E9) (num-test (+ -8.790796444526546E9 0.911415263281967E0) -8.790796443615130736718033019187146237507E9) (num-test (+ 9.667548804251982E9 -1.266547751029956E8) 9.54089402914898613522949218749999999999E9) (num-test (+ -6.169561898845145E9 9.627911197121864E9) 3.458349298276719318847656250000000000009E9) (num-test (+ -9.870287253215279E9 9.004242781937655E8) -8.969862975021513478950500488281249999995E9) (num-test (+ -8.175630881172554E9 -4.08632236263908E9) -1.226195324381163404760742187500000000002E10) (num-test (+ 2.9069444232153206E9 -7.961831315741894E9) -5.054886892526573399999999999999999999977E9) (num-test (+ -7.003647401371184E9 -1.768371514817526E9) -8.772018916188710000000000000000000000001E9) (num-test (+ -6.418847599138249E9 2.755257250162372E-11) -6.418847599138248999972447427498376279997E9) (num-test (+ 2.3093152687241793E9 1.2205440142364766E-11) 2.309315268724179300012205440142364766011E9) (num-test (+ 8.634577667577518E9 -9.065714034538668E-11) 8.634577667577518463044108484654613319994E9) (num-test (+ 1.711283212591781E9 -3.235019197733951E-11) 1.71128321259178090092285000333516049E9) (num-test (+ 2.583886638357791E9 -8.199109798920928E-11) 2.583886638357790946878458120760790719997E9) (num-test (+ -7.517123950474774E9 5.2057802142431697E-11) -7.51712395047477399994794219785756830298E9) (num-test (+ 3.266571938086574E9 -4.4782768261898355E19) -4.478276825863178306191342592239379882812E19) (num-test (+ 2.1000389219899452E9 -8.547158903365463E19) -8.547158903155459107801005480000000000002E19) (num-test (+ -3.9140926801217155E9 7.387959860641422E19) 7.387959860250012731987828450000000000009E19) (num-test (+ -7.087607465790431E9 7.96875093387599E19) 7.968750933167229781420956900000000000008E19) (num-test (+ -8.341000808926519E9 6.9360028397637304E19) 6.936002838929630319107348100000000000009E19) (num-test (+ -5.507940634743809E9 9.760028858210094E19) 9.760028857659299936525619099999999999989E19) (num-test (+ 8.492522971238823E9 -2.8253881864964467E-22) 8.492522971238822937011718749999717461174E9) (num-test (+ 1.2731765723336241E9 -5.8473937102910264E-21) 1.273176572333624099999999999994152606294E9) (num-test (+ 9.654280758878323E9 -4.2332114049658973E-22) 9.654280758878322601318359374999576678861E9) (num-test (+ -6.864618926120946E9 -1.245648314796599E-21) -6.864618926120946000000000000001245648334E9) (num-test (+ -3.9916044043798673E8 1.697737588450543E-21) -3.991604404379867299999999999983022624115E8) (num-test (+ -7.818041624198686E9 4.635421587404246E-21) -7.818041624198685999999999999995364578418E9) (num-test (+ 2.0609929543990767E-12 -0.2126306554359736E0) -2.126306554339126070456009232999999999998E-1) (num-test (+ -1.5923091695877845E-11 0.515731533720818E0) 5.157315337048949444413677540931484848253E-1) (num-test (+ 4.794527092905871E-11 -0.9066947202676092E0) -9.0669472021966392907094129E-1) (num-test (+ -8.63854477728633E-11 0.3122982022565777E0) 3.122982021701922522271366999999999999999E-1) (num-test (+ -7.577966666552416E-11 -0.24137602092437593E0) -2.413760210001555966655241600000000000004E-1) (num-test (+ -4.971730475882754E-11 -0.8202688719750202E0) -8.202688720247375047588275400000000000012E-1) (num-test (+ -5.249369194379291E-11 -8.546120620321186E9) -8.546120620321186000052493691943792910002E9) (num-test (+ 8.280786962526793E-11 5.758373397436368E9) 5.758373397436367988669233650875267930002E9) (num-test (+ 6.370323595535815E-11 -8.470663335712393E9) -8.470663335712392999936296764044641849996E9) (num-test (+ 3.59771226839467E-11 3.5042505440266216E8) 3.504250544026621600359771226839466999997E8) (num-test (+ -3.945501687396375E-11 -5.082779978069177E9) -5.082779978069177000039455016873963749988E9) (num-test (+ 9.780590963267516E-11 -5.05591945120475E9) -5.055919451204750060937350340367324839998E9) (num-test (+ 6.323293597096768E-11 -7.208898910487284E-11) -8.856053133905159999999999999999999999986E-12) (num-test (+ -4.549781732354749E-11 -6.095452636416357E-11) -1.064523436877110600000000000000000000002E-10) (num-test (+ -5.372680267837374E-11 2.0748354219485134E-11) -3.297844845888860599999999999999999999998E-11) (num-test (+ 3.550879553916665E-11 -4.374873254056574E-11) -8.239937001399090000000000000000000000007E-12) (num-test (+ -6.746002242414832E-11 3.0803985031459436E-11) -3.665603739268888400000000000000000000013E-11) (num-test (+ -7.902512161494214E-11 -8.907842858073236E-11) -1.681035501956744999999999999999999999998E-10) (num-test (+ -4.1465935469350415E-11 6.244210696961323E19) 6.24421069696132299999999999999585340645E19) (num-test (+ 4.921297536286578E-11 -1.694436650099881E19) -1.694436650099880999999999999995078702462E19) (num-test (+ -7.879478980672654E-11 6.41757969360492E19) 6.41757969360491970559999999999212052103E19) (num-test (+ -8.200749317872953E-11 -9.490225542618815E19) -9.490225542618815000000000000008200749324E19) (num-test (+ -7.572981329795812E-11 -3.350367078181029E19) -3.350367078181029000000000000007572981326E19) (num-test (+ -5.955255565125549E-11 -5.009913629288125E19) -5.00991362928812500000000000000595525556E19) (num-test (+ -9.818180775332558E-11 -7.926156011681593E-21) -9.818180776125173601168159300000000000011E-11) (num-test (+ -5.2466438379505935E-12 8.468830229031857E-21) -5.246643829481763270968143000000000000009E-12) (num-test (+ 3.582774358441715E-11 3.6865211729351863E-22) 3.582774358478580211729351862999999999999E-11) (num-test (+ 7.169296413565744E-11 -9.974881413980864E-21) 7.169296412568255858601913599999999999987E-11) (num-test (+ -9.615073655516977E-11 4.9552491300097786E-21) -9.615073655021452086999022140000000000005E-11) (num-test (+ 6.7696956269187E-11 4.1431488006404866E-21) 6.769695627333015423852294397336791395272E-11) (num-test (+ -4.663397365185298E19 0.9758464195927673E0) -4.663397365185297999902415358040723270005E19) (num-test (+ -4.77977261393851E19 0.04145189313162445E0) -4.779772613938509999995854810686837555009E19) (num-test (+ 7.195364554121596E19 0.5169917736820715E0) 7.195364554121596000051699177368207149992E19) (num-test (+ -7.766254779507882E19 0.5919134938460356E0) -7.766254779507881999940808650615396440016E19) (num-test (+ -8.411122653901408E19 -0.14463225181516137E0) -8.411122653901408000014463225181516137013E19) (num-test (+ -9.101920591747218E19 0.23349918704239836E0) -9.101920591747217999976650081295760164003E19) (num-test (+ 7.037477746142529E18 -3.250947575909365E9) 7.037477742891581424090634999999999999988E18) (num-test (+ -6.864341752972099E19 -4.0510449339565725E9) -6.864341753377203493395657250000000000004E19) (num-test (+ -5.329540273290228E19 8.14869777458878E9) -5.329540272475358222541121959686279296875E19) (num-test (+ -9.726234388247201E19 2.053976989398215E9) -9.726234388041803301060178494453430175781E19) (num-test (+ -1.910324088450308E19 6.247052535748024E9) -1.910324087825602746425197601318359375E19) (num-test (+ -6.079933001949367E18 6.316829148809886E9) -6.07993299563253785119011402130126953125E18) (num-test (+ -4.499107911798452E19 9.659763881732633E-11) -4.499107911798451999999999999990340236126E19) (num-test (+ -3.0972208018542522E19 -9.077209886078653E-11) -3.097220801854252200000000000009077209882E19) (num-test (+ -2.3000547840875442E19 -3.2043634522621155E-11) -2.300054784087544200000000000003204363456E19) (num-test (+ 2.124555308489292E19 2.252166800652451E-11) 2.124555308489292000000000000002252166802E19) (num-test (+ -7.74280238703686E19 1.7289553748884322E-11) -7.74280238703685999999999999999827104461E19) (num-test (+ -8.119446783121816E19 -4.3461802389685114E-11) -8.11944678312181600000000000000434618023E19) (num-test (+ -4.70848534032654E18 -4.698316648967506E19) -5.16916518300016E19) (num-test (+ 2.853799842810312E19 -5.56805968603395E19) -2.714259843223638E19) (num-test (+ -2.9128622996090335E19 -5.153369106520702E19) -8.0662314061297355E19) (num-test (+ -5.415993984772977E19 4.481932558278175E19) -9.34061426494802E18) (num-test (+ -1.4652301908531261E19 7.89284449966826E19) 6.4276143088151335352E19) (num-test (+ -8.241911630479252E19 5.377001886877124E19) -2.864909743602128E19) (num-test (+ -6.923631123395076E19 7.100129853298664E-22) -6.923631123395076E19) (num-test (+ -5.864213410820717E19 -2.649878514627326E-21) -5.864213410820717E19) (num-test (+ 8.660575002861176E19 2.751926085897399E-21) 8.660575002861176E19) (num-test (+ -3.0252871646631318E19 6.852831573716124E-21) -3.0252871646631318E19) (num-test (+ -9.155476807340938E19 -5.552907466957205E-21) -9.155476807340938E19) (num-test (+ -4.03382621358461E19 6.670808279457885E-21) -4.03382621358461E19) (num-test (+ 8.842980509187577E-21 0.5028466982188534E0) 5.028466982188534000088429805091875769998E-1) (num-test (+ 1.7292043381396136E-21 0.19490424064972922E0) 1.949042406497292200017292043381396136E-1) (num-test (+ -5.854820918836103E-21 -0.6700030154364615E0) -6.700030154364615000058548209188361029995E-1) (num-test (+ -2.152396491682048E-21 0.5002930268902921E0) 5.002930268902920999978476035083179519998E-1) (num-test (+ -1.0897149666610629E-21 0.16555534170490604E0) 1.655553417049060399989102850333389370996E-1) (num-test (+ 6.321421497987867E-24 -0.08008112131564671E0) -8.008112131564670999999367857850201213302E-2) (num-test (+ -6.1552667309563055E-21 7.235074489769488E9) 7.23507448976948833465576171874384473328E9) (num-test (+ -2.2311335001219955E-22 1.220011008333989E9) 1.220011008333988904953002929687276886647E9) (num-test (+ 8.523565724937177E-23 -4.1650242034123087E9) -4.165024203412308699999999999999914764338E9) (num-test (+ -2.4400041303825447E-21 4.435554678685388E9) 4.435554678685387611389160156247559995867E9) (num-test (+ -3.4479065449345757E-22 8.491084033112451E8) 8.491084033112450838088989257809052093456E8) (num-test (+ -7.919939059912893E-21 -7.610637842585286E9) -7.610637842585286000000000000007919939044E9) (num-test (+ 4.4958602369105625E-21 5.758376768873417E-11) 5.758376769323003023691056249999999999989E-11) (num-test (+ 2.4375297386412195E-21 9.417086717671841E-11) 9.41708671791559397386412194999999999998E-11) (num-test (+ 1.0040647133383462E-21 3.4701016271268983E-12) 3.470101628130963013338346199999999999999E-12) (num-test (+ -3.885093055726793E-21 -8.523534862249969E-11) -8.523534862638478305572679299999999999995E-11) (num-test (+ 1.027951323422187E-21 -7.65508060829868E-11) -7.655080608195884867657781300000000000011E-11) (num-test (+ -9.83813940552434E-21 -5.048380063082019E-11) -5.048380064065832940552434000000000000001E-11) (num-test (+ -7.640856498925806E-21 -5.743808556015994E19) -5.743808556015994E19) (num-test (+ 8.053891045717591E-21 4.0840032650134725E19) 4.0840032650134725E19) (num-test (+ -4.794782783871528E-21 -3.431216587740782E18) -3.431216587740782E18) (num-test (+ 1.860870988390988E-21 -3.757945694933625E19) -3.757945694933625E19) (num-test (+ 5.445498222566789E-21 7.575823566817991E19) 7.575823566817991E19) (num-test (+ 2.631896745307223E-21 4.906449817201212E19) 4.906449817201212E19) (num-test (+ -6.61689881073516E-21 5.357007670385275E-21) -1.25989114034988500000000000000000000001E-21) (num-test (+ 3.0173001109587537E-21 5.2947222461350496E-21) 8.312022357093803300000000000000000000009E-21) (num-test (+ -8.792518441030627E-21 -1.0516787854168774E-21) -9.84419722644750439999999999999999999997E-21) (num-test (+ 7.349451992884509E-21 -8.427997362671486E-21) -1.078545369786976999999999999999999999993E-21) (num-test (+ -7.881179611953633E-21 3.2080446524364824E-21) -4.673134959517150599999999999999999999987E-21) (num-test (+ -9.614117725927607E-21 -5.35667712698602E-21) -1.4970794852913627E-20) (num-test (+ 763661/10959 314049/215772 801211/520111) 29795593575023947/409959352197876) (num-test (+ 754684/707399 364133/66140) 43928874261/6683909980) (num-test (+ 440608/272315 551945/732519 640011/210080) 45409303060766899/8381179896953760) (num-test (+ 6567/58532 12009/41861 51413/44691) 169671941552201/109502248051932) (num-test (+ 24362/18498 57440/40727 22449/57480) 22502908640629/7217265880680) (num-test (+ 31721/56074 60995/54239) 5140748949/3041397686) (num-test (+ 53838/33670 41433/21212 18707/18707 38145/30697 18708/22768) 51605878718885969/7799478725530310) (num-test (+ 28104/38994 16087/7686 61878/25480) 238289915659/45455695740) (num-test (+ 19084/1172 31274/36894 58813/47401 21693/36339) 58866653148990514/3103363080883923) (num-test (+ 46622/34221 37123/47024 30488/35441) 2816139009923/934950024624) (num-test (+ 5132/18296 39996/45879 41433/58822 63206/41458) 72097712837475423/21322935628641329) (num-test (+ 2203/36057 55977/14559 48383/64098 9101/28942) 134587284141221743/27051518778595353) (num-test (+ 32375/41641 50274/42858 18792/37422 7370/20399) 1314683476492406/467198461232349) (num-test (+ 13733/12161 54393/23682 3717/60389) 2888390497365/828182803618) (num-test (+ 62280/7667 54471/23126 54070/62784) 31558604335387/2783011331232) (num-test (+ 11072/35120 33950/8514 59489/8783 38683/16720) 66811589960405/4989817212336) (num-test (+ 20220/12370 24149/50379 63926/10436) 2679308820467/325179618414) (num-test (+ 26718/50103 44333/20749 6375/11441 47216/19118) 12699871541397230/2229293103730143) (num-test (+ 38673/65491 57303/2569 40991/55309) 219956905519979/9305538976111) (num-test (+ 1/98947 2/97499 3/76847) 51641766530/741360956847391) (test (> (+ 123456789/3 3/123456789 -123456789/3 -3/123456789) 2e-12) #f) ; it's really 0, but fp inaccuracies catch us (num-test (+ 1e100 -1e100) 0.0) (num-test (+ 1e100 1e100) 2e100) (num-test (+ 1e200 -1e200) 0.0) (num-test (+ 1e300 -1e300) 0.0) (num-test (+ 500009/500029 500057/500041) 500068002022/250035001189) (num-test (+ 0.5 -0.5 1/2) 0.5) (num-test (+ 1 1/2 0.5 3.0+5.5i) 5.0+5.5i) (num-test (+ 1/2 0.5) 1.0) (num-test (+ 3 4) 7 ) (num-test (+ 3) '3 ) (num-test (+) 0 ) (num-test (+ 123123123123123 123123123123123) 246246246246246) (if (not with-bignums) (begin (num-test (+ 3/4 4611686018427387904) 4.61168601842738790475E18) (num-test (+ 1/17179869184 1073741824) 1.073741824000000000058207660913467407227E9) (num-test (+ 1/8589934592 1073741824) 1.073741824000000000116415321826934814453E9) (num-test (+ 100000 1/142857142857140) 1.000000000000000000070000000000001400001E5) (num-test (+ 4611686018427387904 3/4) 4.61168601842738790475E18) (num-test (+ -63 8 1/9223372036854775807) -55.0) (num-test (+ 8 8 1/9223372036854775807) 16.0) (num-test (+ -1 -63 1/9223372036854775807) -64.0) (num-test (+ 32768 -1 562949953421312/281474976710655) 32769.0) (num-test (+ -63 262144 70368744177664/35184372088831) 262083.0) (num-test (+ 2147483648 -1 8589934592/4294967295) 2147483649.0) (num-test (+ 8589934592/4294967295 2147483648 -1) 2147483649.0) (num-test (+ 8589934592/4294967295 -1 2147483648) 2147483649.0) (num-test (+ -1 8589934592/4294967295 2147483648) 2147483649.0) ; (num-test (+ 4611686018427387904 4611686018427387904) 9.223372036854775808e18) ; (num-test (+ most-positive-fixnum most-positive-fixnum) 1.8446744073709551614e19) ; (num-test (+ most-negative-fixnum most-negative-fixnum) -1.8446744073709551616e19) )) (let () (define (add1) (+ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99)) (num-test (add1) 4950) (define (add2) (+ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999)) (num-test (add2) 499500) (define (add3) (+ 1 (+ 2 (+ 3 (+ 4 (+ 5 (+ 6 (+ 7 (+ 8 (+ 9 (+ 10 (+ 11 (+ 12 (+ 13 (+ 14 (+ 15 (+ 16 (+ 17 (+ 18 (+ 19 (+ 20 (+ 21 (+ 22 (+ 23 (+ 24 (+ 25 (+ 26 (+ 27 (+ 28 (+ 29 (+ 30 (+ 31 (+ 32 (+ 33 (+ 34 (+ 35 (+ 36 (+ 37 (+ 38 (+ 39 (+ 40 (+ 41 (+ 42 (+ 43 (+ 44 (+ 45 (+ 46 (+ 47 (+ 48 (+ 49 (+ 50 (+ 51 (+ 52 (+ 53 (+ 54 (+ 55 (+ 56 (+ 57 (+ 58 (+ 59 (+ 60 (+ 61 (+ 62 (+ 63 (+ 64 (+ 65 (+ 66 (+ 67 (+ 68 (+ 69 (+ 70 (+ 71 (+ 72 (+ 73 (+ 74 (+ 75 (+ 76 (+ 77 (+ 78 (+ 79 (+ 80 (+ 81 (+ 82 (+ 83 (+ 84 (+ 85 (+ 86 (+ 87 (+ 88 (+ 89 (+ 90 (+ 91 (+ 92 (+ 93 (+ 94 (+ 95 (+ 96 (+ 97 (+ 98 (+ 99)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) (num-test (add3) 4950) (define (add4) (+ 1 (+ 2 (+ 3 (+ 4 (+ 5 (+ 6 (+ 7 (+ 8 (+ 9 (+ 10 (+ 11 (+ 12 (+ 13 (+ 14 (+ 15 (+ 16 (+ 17 (+ 18 (+ 19 (+ 20 (+ 21 (+ 22 (+ 23 (+ 24 (+ 25 (+ 26 (+ 27 (+ 28 (+ 29 (+ 30 (+ 31 (+ 32 (+ 33 (+ 34 (+ 35 (+ 36 (+ 37 (+ 38 (+ 39 (+ 40 (+ 41 (+ 42 (+ 43 (+ 44 (+ 45 (+ 46 (+ 47 (+ 48 (+ 49 (+ 50 (+ 51 (+ 52 (+ 53 (+ 54 (+ 55 (+ 56 (+ 57 (+ 58 (+ 59 (+ 60 (+ 61 (+ 62 (+ 63 (+ 64 (+ 65 (+ 66 (+ 67 (+ 68 (+ 69 (+ 70 (+ 71 (+ 72 (+ 73 (+ 74 (+ 75 (+ 76 (+ 77 (+ 78 (+ 79 (+ 80 (+ 81 (+ 82 (+ 83 (+ 84 (+ 85 (+ 86 (+ 87 (+ 88 (+ 89 (+ 90 (+ 91 (+ 92 (+ 93 (+ 94 (+ 95 (+ 96 (+ 97 (+ 98 (+ 99 (+ 100 (+ 101 (+ 102 (+ 103 (+ 104 (+ 105 (+ 106 (+ 107 (+ 108 (+ 109 (+ 110 (+ 111 (+ 112 (+ 113 (+ 114 (+ 115 (+ 116 (+ 117 (+ 118 (+ 119 (+ 120 (+ 121 (+ 122 (+ 123 (+ 124 (+ 125 (+ 126 (+ 127 (+ 128 (+ 129 (+ 130 (+ 131 (+ 132 (+ 133 (+ 134 (+ 135 (+ 136 (+ 137 (+ 138 (+ 139 (+ 140 (+ 141 (+ 142 (+ 143 (+ 144 (+ 145 (+ 146 (+ 147 (+ 148 (+ 149 (+ 150 (+ 151 (+ 152 (+ 153 (+ 154 (+ 155 (+ 156 (+ 157 (+ 158 (+ 159 (+ 160 (+ 161 (+ 162 (+ 163 (+ 164 (+ 165 (+ 166 (+ 167 (+ 168 (+ 169 (+ 170 (+ 171 (+ 172 (+ 173 (+ 174 (+ 175 (+ 176 (+ 177 (+ 178 (+ 179 (+ 180 (+ 181 (+ 182 (+ 183 (+ 184 (+ 185 (+ 186 (+ 187 (+ 188 (+ 189 (+ 190 (+ 191 (+ 192 (+ 193 (+ 194 (+ 195 (+ 196 (+ 197 (+ 198 (+ 199 (+ 200 (+ 201 (+ 202 (+ 203 (+ 204 (+ 205 (+ 206 (+ 207 (+ 208 (+ 209 (+ 210 (+ 211 (+ 212 (+ 213 (+ 214 (+ 215 (+ 216 (+ 217 (+ 218 (+ 219 (+ 220 (+ 221 (+ 222 (+ 223 (+ 224 (+ 225 (+ 226 (+ 227 (+ 228 (+ 229 (+ 230 (+ 231 (+ 232 (+ 233 (+ 234 (+ 235 (+ 236 (+ 237 (+ 238 (+ 239 (+ 240 (+ 241 (+ 242 (+ 243 (+ 244 (+ 245 (+ 246 (+ 247 (+ 248 (+ 249 (+ 250 (+ 251 (+ 252 (+ 253 (+ 254 (+ 255 (+ 256 (+ 257 (+ 258 (+ 259 (+ 260 (+ 261 (+ 262 (+ 263 (+ 264 (+ 265 (+ 266 (+ 267 (+ 268 (+ 269 (+ 270 (+ 271 (+ 272 (+ 273 (+ 274 (+ 275 (+ 276 (+ 277 (+ 278 (+ 279 (+ 280 (+ 281 (+ 282 (+ 283 (+ 284 (+ 285 (+ 286 (+ 287 (+ 288 (+ 289 (+ 290 (+ 291 (+ 292 (+ 293 (+ 294 (+ 295 (+ 296 (+ 297 (+ 298 (+ 299 (+ 300 (+ 301 (+ 302 (+ 303 (+ 304 (+ 305 (+ 306 (+ 307 (+ 308 (+ 309 (+ 310 (+ 311 (+ 312 (+ 313 (+ 314 (+ 315 (+ 316 (+ 317 (+ 318 (+ 319 (+ 320 (+ 321 (+ 322 (+ 323 (+ 324 (+ 325 (+ 326 (+ 327 (+ 328 (+ 329 (+ 330 (+ 331 (+ 332 (+ 333 (+ 334 (+ 335 (+ 336 (+ 337 (+ 338 (+ 339 (+ 340 (+ 341 (+ 342 (+ 343 (+ 344 (+ 345 (+ 346 (+ 347 (+ 348 (+ 349 (+ 350 (+ 351 (+ 352 (+ 353 (+ 354 (+ 355 (+ 356 (+ 357 (+ 358 (+ 359 (+ 360 (+ 361 (+ 362 (+ 363 (+ 364 (+ 365 (+ 366 (+ 367 (+ 368 (+ 369 (+ 370 (+ 371 (+ 372 (+ 373 (+ 374 (+ 375 (+ 376 (+ 377 (+ 378 (+ 379 (+ 380 (+ 381 (+ 382 (+ 383 (+ 384 (+ 385 (+ 386 (+ 387 (+ 388 (+ 389 (+ 390 (+ 391 (+ 392 (+ 393 (+ 394 (+ 395 (+ 396 (+ 397 (+ 398 (+ 399 (+ 400 (+ 401 (+ 402 (+ 403 (+ 404 (+ 405 (+ 406 (+ 407 (+ 408 (+ 409 (+ 410 (+ 411 (+ 412 (+ 413 (+ 414 (+ 415 (+ 416 (+ 417 (+ 418 (+ 419 (+ 420 (+ 421 (+ 422 (+ 423 (+ 424 (+ 425 (+ 426 (+ 427 (+ 428 (+ 429 (+ 430 (+ 431 (+ 432 (+ 433 (+ 434 (+ 435 (+ 436 (+ 437 (+ 438 (+ 439 (+ 440 (+ 441 (+ 442 (+ 443 (+ 444 (+ 445 (+ 446 (+ 447 (+ 448 (+ 449 (+ 450 (+ 451 (+ 452 (+ 453 (+ 454 (+ 455 (+ 456 (+ 457 (+ 458 (+ 459 (+ 460 (+ 461 (+ 462 (+ 463 (+ 464 (+ 465 (+ 466 (+ 467 (+ 468 (+ 469 (+ 470 (+ 471 (+ 472 (+ 473 (+ 474 (+ 475 (+ 476 (+ 477 (+ 478 (+ 479 (+ 480 (+ 481 (+ 482 (+ 483 (+ 484 (+ 485 (+ 486 (+ 487 (+ 488 (+ 489 (+ 490 (+ 491 (+ 492 (+ 493 (+ 494 (+ 495 (+ 496 (+ 497 (+ 498 (+ 499 (+ 500 (+ 501 (+ 502 (+ 503 (+ 504 (+ 505 (+ 506 (+ 507 (+ 508 (+ 509 (+ 510 (+ 511 (+ 512 (+ 513 (+ 514 (+ 515 (+ 516 (+ 517 (+ 518 (+ 519 (+ 520 (+ 521 (+ 522 (+ 523 (+ 524 (+ 525 (+ 526 (+ 527 (+ 528 (+ 529 (+ 530 (+ 531 (+ 532 (+ 533 (+ 534 (+ 535 (+ 536 (+ 537 (+ 538 (+ 539 (+ 540 (+ 541 (+ 542 (+ 543 (+ 544 (+ 545 (+ 546 (+ 547 (+ 548 (+ 549 (+ 550 (+ 551 (+ 552 (+ 553 (+ 554 (+ 555 (+ 556 (+ 557 (+ 558 (+ 559 (+ 560 (+ 561 (+ 562 (+ 563 (+ 564 (+ 565 (+ 566 (+ 567 (+ 568 (+ 569 (+ 570 (+ 571 (+ 572 (+ 573 (+ 574 (+ 575 (+ 576 (+ 577 (+ 578 (+ 579 (+ 580 (+ 581 (+ 582 (+ 583 (+ 584 (+ 585 (+ 586 (+ 587 (+ 588 (+ 589 (+ 590 (+ 591 (+ 592 (+ 593 (+ 594 (+ 595 (+ 596 (+ 597 (+ 598 (+ 599 (+ 600 (+ 601 (+ 602 (+ 603 (+ 604 (+ 605 (+ 606 (+ 607 (+ 608 (+ 609 (+ 610 (+ 611 (+ 612 (+ 613 (+ 614 (+ 615 (+ 616 (+ 617 (+ 618 (+ 619 (+ 620 (+ 621 (+ 622 (+ 623 (+ 624 (+ 625 (+ 626 (+ 627 (+ 628 (+ 629 (+ 630 (+ 631 (+ 632 (+ 633 (+ 634 (+ 635 (+ 636 (+ 637 (+ 638 (+ 639 (+ 640 (+ 641 (+ 642 (+ 643 (+ 644 (+ 645 (+ 646 (+ 647 (+ 648 (+ 649 (+ 650 (+ 651 (+ 652 (+ 653 (+ 654 (+ 655 (+ 656 (+ 657 (+ 658 (+ 659 (+ 660 (+ 661 (+ 662 (+ 663 (+ 664 (+ 665 (+ 666 (+ 667 (+ 668 (+ 669 (+ 670 (+ 671 (+ 672 (+ 673 (+ 674 (+ 675 (+ 676 (+ 677 (+ 678 (+ 679 (+ 680 (+ 681 (+ 682 (+ 683 (+ 684 (+ 685 (+ 686 (+ 687 (+ 688 (+ 689 (+ 690 (+ 691 (+ 692 (+ 693 (+ 694 (+ 695 (+ 696 (+ 697 (+ 698 (+ 699 (+ 700 (+ 701 (+ 702 (+ 703 (+ 704 (+ 705 (+ 706 (+ 707 (+ 708 (+ 709 (+ 710 (+ 711 (+ 712 (+ 713 (+ 714 (+ 715 (+ 716 (+ 717 (+ 718 (+ 719 (+ 720 (+ 721 (+ 722 (+ 723 (+ 724 (+ 725 (+ 726 (+ 727 (+ 728 (+ 729 (+ 730 (+ 731 (+ 732 (+ 733 (+ 734 (+ 735 (+ 736 (+ 737 (+ 738 (+ 739 (+ 740 (+ 741 (+ 742 (+ 743 (+ 744 (+ 745 (+ 746 (+ 747 (+ 748 (+ 749 (+ 750 (+ 751 (+ 752 (+ 753 (+ 754 (+ 755 (+ 756 (+ 757 (+ 758 (+ 759 (+ 760 (+ 761 (+ 762 (+ 763 (+ 764 (+ 765 (+ 766 (+ 767 (+ 768 (+ 769 (+ 770 (+ 771 (+ 772 (+ 773 (+ 774 (+ 775 (+ 776 (+ 777 (+ 778 (+ 779 (+ 780 (+ 781 (+ 782 (+ 783 (+ 784 (+ 785 (+ 786 (+ 787 (+ 788 (+ 789 (+ 790 (+ 791 (+ 792 (+ 793 (+ 794 (+ 795 (+ 796 (+ 797 (+ 798 (+ 799 (+ 800 (+ 801 (+ 802 (+ 803 (+ 804 (+ 805 (+ 806 (+ 807 (+ 808 (+ 809 (+ 810 (+ 811 (+ 812 (+ 813 (+ 814 (+ 815 (+ 816 (+ 817 (+ 818 (+ 819 (+ 820 (+ 821 (+ 822 (+ 823 (+ 824 (+ 825 (+ 826 (+ 827 (+ 828 (+ 829 (+ 830 (+ 831 (+ 832 (+ 833 (+ 834 (+ 835 (+ 836 (+ 837 (+ 838 (+ 839 (+ 840 (+ 841 (+ 842 (+ 843 (+ 844 (+ 845 (+ 846 (+ 847 (+ 848 (+ 849 (+ 850 (+ 851 (+ 852 (+ 853 (+ 854 (+ 855 (+ 856 (+ 857 (+ 858 (+ 859 (+ 860 (+ 861 (+ 862 (+ 863 (+ 864 (+ 865 (+ 866 (+ 867 (+ 868 (+ 869 (+ 870 (+ 871 (+ 872 (+ 873 (+ 874 (+ 875 (+ 876 (+ 877 (+ 878 (+ 879 (+ 880 (+ 881 (+ 882 (+ 883 (+ 884 (+ 885 (+ 886 (+ 887 (+ 888 (+ 889 (+ 890 (+ 891 (+ 892 (+ 893 (+ 894 (+ 895 (+ 896 (+ 897 (+ 898 (+ 899 (+ 900 (+ 901 (+ 902 (+ 903 (+ 904 (+ 905 (+ 906 (+ 907 (+ 908 (+ 909 (+ 910 (+ 911 (+ 912 (+ 913 (+ 914 (+ 915 (+ 916 (+ 917 (+ 918 (+ 919 (+ 920 (+ 921 (+ 922 (+ 923 (+ 924 (+ 925 (+ 926 (+ 927 (+ 928 (+ 929 (+ 930 (+ 931 (+ 932 (+ 933 (+ 934 (+ 935 (+ 936 (+ 937 (+ 938 (+ 939 (+ 940 (+ 941 (+ 942 (+ 943 (+ 944 (+ 945 (+ 946 (+ 947 (+ 948 (+ 949 (+ 950 (+ 951 (+ 952 (+ 953 (+ 954 (+ 955 (+ 956 (+ 957 (+ 958 (+ 959 (+ 960 (+ 961 (+ 962 (+ 963 (+ 964 (+ 965 (+ 966 (+ 967 (+ 968 (+ 969 (+ 970 (+ 971 (+ 972 (+ 973 (+ 974 (+ 975 (+ 976 (+ 977 (+ 978 (+ 979 (+ 980 (+ 981 (+ 982 (+ 983 (+ 984 (+ 985 (+ 986 (+ 987 (+ 988 (+ 989 (+ 990 (+ 991 (+ 992 (+ 993 (+ 994 (+ 995 (+ 996 (+ 997 (+ 998 (+ 999)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) (num-test (add4) 499500)) (let () (define (fact n) (if (<= n 1) 1 (* n (fact (- n 1))))) (num-test (fact 7) 5040) (num-test (fact 20) 2432902008176640000) (do ((i 2 (+ i 1))) ((= i 21)) (num-test (* i (fact (- i 1))) (fact i)) (num-test (/ (* i (fact (- i 1)))) (/ (fact i)))) (if with-bignums (begin (num-test (fact 21) 51090942171709440000) (num-test (fact 32) 263130836933693530167218012160000000) (do ((i 20 (+ i 1))) ((= i 40)) (num-test (* i (fact (- i 1))) (fact i)))))) (num-test (let ((pi2 0.0) (ais (vector 1 -3 -2 -3 1 0))) (do ((i 1 (+ i 1)) (two 2 (* two 2))) ((= i 30) (* 36 pi2)) (set! pi2 (+ pi2 (/ (vector-ref ais (modulo (- i 1) 6)) (* two i i)))))) (* pi pi)) (num-test (let ((log2 0.0) (ais (vector 2 -10 -7 -10 2 -1))) (do ((i 1 (+ i 1)) (two 2 (* two 2))) ((= i 30) (* 2 log2)) (set! log2 (+ log2 (/ (vector-ref ais (modulo (- i 1) 6)) (* two i i)))))) (* (log 2) (log 2))) (if (not with-bignums) (begin (num-test (+ 1/9223372036854775807 1/9223372036854775806) 2.168404344971e-19) (num-test (+ 1/98947 2/97499 3/76847 4/61981 5/59981 6/66601) 0.00030764243484887) (num-test (+ 1/98947 2/97499 3/76847 4/61981 5/59981) 0.00021755369744252) (num-test (+ 1/98947 2/97499 3/76847 4/61981) 0.00013419396686117) (num-test (+ 500009/500029 500057/500041 500083/500069) 3.00001999583261) (num-test (+ 98947 2/97499 76847 4/61981 5/59981) 175794.00016841) )) (if with-bignums (test (< (abs (- (do ((x0 11/2) (x1 61/11) (i 0 (+ i 1))) ((= i 100) x1) (let ((tmp x1)) (set! x1 (- 111 (/ (- 1130 (/ 3000 x0)) x1))) (set! x0 tmp))) 6)) ; (6 - 1/(1+(6/5)^k)) 0.00001) #t)) ;; in floats this heads for 100: ;; (do ((x0 (exact->inexact 11/2)) (x1 (exact->inexact 61/11)) (i 0 (+ i 1))) ((= i 100) x1) (let ((tmp x1)) (set! x1 (- 111 (/ (- 1130 (/ 3000 x0)) x1))) (set! x0 tmp))) #| in gmp case we get: :(+ 8388608 .00000001) 8388608.0 but it's the printout that is at fault: :(- (+ 8388608 .000000001) 8388608) 1.862645149231e-09 |# (if with-bignums (begin (num-test (+ 0.999999995 8388608) 8388608.999999995) (num-test (+ (+ 1.0e-30 1.0e30) -1.0e30) (+ 1.0e-30 (+ 1.0e30 -1.0e30))) (num-test (+ 11111111111111113.0 (+ -11111111111111111.0 7.5111111111111)) (+ (+ 11111111111111113.0 -11111111111111111.0) 7.5111111111111)) (num-test (+ -1000000000 -1000000000 -1000000000) -3000000000) (num-test (+ -8589934591 -4611686018427387904) -4611686027017322495) (num-test (+ -8589934591 4611686018427387904) 4611686009837453313) (num-test (+ -9223372036854775807 -1) -9223372036854775808) (num-test (+ -9223372036854775807 1) -9223372036854775806) (num-test (+ -9223372036854775808 -9223372036854775808) -18446744073709551616) (num-test (+ 1 1/2 0+9223372036854775808.0i 0-i) 1.5+9.223372036854775807E18i) (num-test (+ 1 1/2 9223372036854775808.0 0+i) 9.2233720368547758095E18+1.0i) (num-test (+ 1 1/2 9223372036854775808.0 0-i) 9.2233720368547758095E18-1.0i) (num-test (+ 1 1/2 9223372036854775808.0) 9.2233720368547758095E18) (num-test (+ 1.0 12345678901234567890) 1.2345678901234567891E19) (num-test (+ 1.0e80+i 1.0e80+i) 2.0e80+2.0i) (num-test (+ 1.0e80+i 1.0e80-i) 2.0e80) (num-test (+ 1.5 9223372036854775808.0) 9.2233720368547758095E18) (num-test (+ 1/1231234567891234567891 1/4) 1231234567891234567895/4924938271564938271564) (num-test (+ 1/2147483648 1/2147483647) 4294967295/4611686016279904256) (num-test (+ 1/3 (* 13835058055282163710 2/3)) 9223372036854775807) ; would be nice if this worked... (num-test (+ 1/65537 -1/65536) -1/4295032832) (num-test (+ 1/65537 -1/65538) 1/4295163906) (num-test (+ 1/65537 1/65536) 131073/4295032832) (num-test (+ 1/65537 1/65538) 131075/4295163906) (num-test (+ 1/9223372036854775807 1/9223372036854775806) 18446744073709551613/85070591730234615838173535747377725442) (num-test (+ 1/98947 2/97499 3/76847 4/61981 5/59981 6/66601) 56471455498794722585779775/183561983334767209753061626751) (num-test (+ 1/98947 2/97499 3/76847 4/61981 5/59981) 599609438061905323469/2756144552405627689570151) (num-test (+ 10 9223372036854775800) 9223372036854775810) (num-test (+ 1000000000 1000000000 1000000000) 3000000000) (num-test (+ 1073741825 1073741825) 2147483650) (num-test (+ 1099511627775 9223372036854775807) 9223373136366403582) (num-test (+ 1180591620717411303424+i 1+1180591620717411303424i) 1.180591620717411303425E21+1.180591620717411303425E21i) (num-test (+ 1180591620717411303424.0+i 1+1180591620717411303424.0i) 1.180591620717411303425E21+1.180591620717411303425E21i) (num-test (+ 12345678901234567890+12345678901234567890i 12345678901234567890-12345678901234567890i) 2.469135780246913578E19) (num-test (+ 132120577/12 33292289/6 260046847/4) 244711424/3) (num-test (+ 18446744082299486212 1) 18446744082299486213) (num-test (+ 1e400 1e399) 1.1e400) (num-test (+ 2147483647 1) 2147483648) (num-test (+ 2147483647 2) 2147483649) (num-test (+ 2147483647 4611686018427387904) 4611686020574871551) (num-test (+ 2147483648 -1) 2147483647) (num-test (+ 2147483648 -2) 2147483646) (num-test (+ 2147483648 1) 2147483649) (num-test (+ 2147483648 4611686018427387904) 4611686020574871552) (num-test (+ 2147483648) 2147483648) (num-test (+ 2147483649 -1) 2147483648) (num-test (+ 2147483649 -4611686018427387904 -2147483649 4611686018427387904) 0) (num-test (+ 2147483649 4611686018427387904 2147483649 4611686018427387904) 9223372041149743106) (num-test (+ 2147483649 4611686018427387904) 4611686020574871553) (num-test (+ 3 9223372036854775807/4) 9223372036854775819/4) (num-test (+ 3 9223372036854775808/4) 2305843009213693955) (num-test (+ 3/2 9223372036854775808.0) 9.2233720368547758095E18) (num-test (+ 3/4 9223372036854775807/4) 4611686018427387905/2) (num-test (+ 3/4 9223372036854775808) 36893488147419103235/4) (num-test (+ 4611686018427387904 -1) 4611686018427387903) (num-test (+ 4611686018427387904 -4611686018427387904) 0) (num-test (+ 4611686018427387904 1) 4611686018427387905) ; (expt 2 62) + 1 -- should work in both cases (num-test (+ 4611686018427387904 4611686018427387904) 9223372036854775808) (num-test (+ 4611686018427387904 4611686018427387906) 9223372036854775810) (num-test (+ 500009/500029 500057/500041 500083/500069) 375106759202738205/125034753009582041) (num-test (+ 8589934591 -4611686018427387904) -4611686009837453313) (num-test (+ 8589934591 4611686018427387904) 4611686027017322495) (num-test (+ 8589934592 4611686018427387904) 4611686027017322496) (num-test (+ 9223372036854775800 10) 9223372036854775810) (num-test (+ 9223372036854775807 -1) 9223372036854775806) (num-test (+ 9223372036854775807 1) 9223372036854775808) (num-test (+ 9223372036854775807 2) 9223372036854775809) (num-test (+ 9223372036854775807 9223372036854775807) 18446744073709551614) (num-test (+ 9223372036854775807/4 3) 9223372036854775819/4) (num-test (+ 9223372036854775807/4 3/4 4611686018427387905/2) 4611686018427387905) (num-test (+ 9223372036854775807/4 3/4) 4611686018427387905/2) (num-test (+ 9223372036854775807/4 4611686018427387905/3) 46116860184273879041/12) (num-test (+ 9223372036854775808 -1) 9223372036854775807) (num-test (+ 9223372036854775808 -2) 9223372036854775806) (num-test (+ 9223372036854775808 1) 9223372036854775809) (num-test (+ 9223372036854775808 3/4) 36893488147419103235/4) (num-test (+ 9223372036854775808.0 3.4) 9.2233720368547758114E18) (num-test (+ 9223372036854775808.0+1.5i 3.4) 9.2233720368547758114E18+1.5i) (num-test (+ 9223372036854775808/4 3) 2305843009213693955) (num-test (+ 9223372036854775808/9223372036854775808) 1) (num-test (+ 9223372036854775809 -1) 9223372036854775808) (num-test (+ 9223372041149743106 -9223372041149743106) 0) (num-test (+ 9223372041149743106 9223372041149743106) 18446744082299486212) (num-test (+ 98947 2/97499 76847 4/61981 5/59981) 63720106179329487759/362470312515139) (num-test (+ 576460752303423488 576460752303423488 576460752303423488 576460752303423488 576460752303423488 576460752303423488 576460752303423488 576460752303423488 576460752303423488 576460752303423488 576460752303423488 576460752303423488 576460752303423488 576460752303423488 576460752303423488 576460752303423488) 9223372036854775808) (num-test (+ -576460752303423488 -576460752303423488 -576460752303423488 -576460752303423488 -576460752303423488 -576460752303423488 -576460752303423488 -576460752303423488 -576460752303423488 -576460752303423488 -576460752303423488 -576460752303423488 -576460752303423488 -576460752303423488 -576460752303423488 -576460752303423488) -9223372036854775808) ; this fits in both cases = -(expt 2 63) (num-test (+ 12766/44484 39852/43605 31122/19043 51508/63811 36845/41288 28101/14083 56682/37410 47892/22120 39412/22980 60124/55166 42856/59693) 208780620213964670464533749059169842219977/15202497819117370814835285951563379420520) (num-test (+ 63216/39382 57676/45091 53354/2630 1048/39076 16116/23210 42095/55806 27474/26658 50811/59328) 191349291372060004326881331664759/7211602793633848370218614932160) (num-test (+ 59885/27233 26245/45891 40482/5828 51990/36443 9623/46196) 34799310234648621493801/3065498111736131980788) (num-test (+ 37870/11132 60558/48391 53644/64989 60943/2780 9073/15664 15430/61388 55088/37713) 49618689694342545850764990997/1671112820517946923490092720) (num-test (+ 37890/11488 45896/14037 3589/36071 22835/41473 42331/17823 42800/56681) 420312190408065989902262231/40617147626636993628447504) (num-test (+ 26660/49395 52605/23369 30235/15203 37926/38348 54028/49472 32407/12923 20689/1984 27919/46263) 69930317632493223450434305725419/3428000885137780298513956804672) (num-test (+ 56351/21775 14958/21250 13859/32508 24968/65124 885/6861 3913/38588 90/55711 12269/37075 6579/33653) 201796703852921650643001395969752/41522567198031666874435508825625) (num-test (+ 8582/48034 27069/11031 29676/5507 56684/32514 25699/47391 44069/2704 18193/3289) 5684819414248430672302049/176897854654356635413328) (num-test (+ 421240/871225 1021193/39462 252094/592111 2478/11660) 32043461749854904862/1186809749708031735) (num-test (+ 149278/597089 747410/315908 218673/956214 174632/245649 45750/515909) 165277142441527691870266634/45353662154623612097256297) (num-test (+ 361087/1038423 629417/722796 693707/392139 237025/961767 88560/187279) 2426130069686588061565863289/654491499930590555724694236) (num-test (+ 94466/1038229 807503/592385 802950/953585 954630/176875) 6384533383241957925411/829875721759976907875) (num-test (+ 913461/774815 817965/788155 237677/532117 542827/225728 343160/431483) 2183257313717880748058258989/372346251755101707126455360) (num-test (+ 888429/600657 680124/108845 265059/727366 395224/748135) 20445657641208104518701/2371792747070499020510) (num-test (+ 37622/1698 9183/57409 12127/36899 11451/26597 64339/35514) 14092685195493114237067/566256574856769105474) (num-test (+ 24122/8583 41997/57541 42760/57555 40699/12923 30325/37640) 1518749441232333398909/184353450944764326984) (num-test (+ 16104/12728 32020/64625 35345/37481 29241/50823 13216/61075 11245/2022) 751811438787510154499/83010789184720173150) (num-test (+ 4312/48465 44171/56694 8599/3231 46048/62568 2132/45901 24407/26161) 455702434782048082459/86885567283849955830) (num-test (+ 59496/7030 37058/2679 2158/41193 48873/59329 52768/30853 34749/39139) 339576145632874325598832/13177075606485410552535) (num-test (+ 131/58542 41136/2572 43951/20070 63439/14560 33259/63731 10981/51495 49078/63698 10727/32805 29362/30842) 51962727546984124809096307414129847/2051626916225689647807786049306080) (num-test (+ 16640/40785 56062/38132 43843/29406 5867/50944 19248/58540) 1083456041462784832133/284138789764221200640) (num-test (+ 34314/54910 54195/13905 32762/15225 20808/42764 20977/59771 26320/20306 53116/23035 30385/31200 57396/3367 58378/6806 5724/29599) 39875514688522166158239445824103603/1051980164901898842922034228906400) (num-test (+ 40391/35273 27957/29448 52381/18500 60009/3366 27528/2124 62426/65445 43110/25891 40183/26944 30274/1504 27638/40611) 15253761502587455936752727098716743/251570544261187774378167518568000) (num-test (+ 52269/62857 21518/38958 29849/9192 27730/2604 20427/36068) 116322789710447328047/7340588373519969288) (num-test (+ 17009115185923538769 -12047631083067675031) 4961484102855863738) (num-test (+ 12677011568664239747 3269056182420253574) 15946067751084493321) (num-test (+ 9315504781982082433 13857624532376678678) 23173129314358761111) (num-test (+ 15226508728194069537 11481952022080775416) 26708460750274844953) (num-test (+ 7461641943684774743 12249026721402718630) 19710668665087493373) (num-test (+ 1180469445886971055 -3208456171287181032) -2027986725400209977) (num-test (+ 18358552990465743315 221529797579218180385160273426219343697) 221529797579218180403518826416685087012) (num-test (+ -14819874956616484359 30498815629431206969122152847973230849) 30498815629431206954302277891356746490) (num-test (+ -11781881800334342169 112219460388643619332860331282276228017) 112219460388643619321078449481941885848) (num-test (+ 3570694277032201957 284821691832196381859344006870088122712) 284821691832196381862914701147120324669) (num-test (+ -17005463295060938595 69162171850264911722979835561124066203) 69162171850264911705974372266063127608) (num-test (+ 15647113311796203488 150750467185419235519670165664526735459) 150750467185419235535317278976322938947) (num-test (+ -14330150541101371097 -13054027994001826312503071338715966858478218093171762021549815587520723118772963817341751396703629529810372702877555022105594068768886421335353882155416908) -13054027994001826312503071338715966858478218093171762021549815587520723118772963817341751396703629529810372702877555022105594068768886435665504423256788005) (num-test (+ 7406427184711759740 -4059250217961011548005203450962458026528281798230141192186669580689721046971433745892994467792118611646113962840750314719233572760336084100766391093756252) -4059250217961011548005203450962458026528281798230141192186669580689721046971433745892994467792118611646113962840750314719233572760336076694339206381996512) (num-test (+ 8819522415901031498 7274905269237471130619913887005155660991437201841760414347836177003483932007334374478344594178179032728521106519295465031750530183363793325150672647162846) 7274905269237471130619913887005155660991437201841760414347836177003483932007334374478344594178179032728521106519295465031750530183363802144673088548194344) (num-test (+ -7242932332215698200 -10558564312909325527488520195600871241245891651644550509993750377630234801225525279855157008009255586978047154906058790342845859331159009687703010657137320) -10558564312909325527488520195600871241245891651644550509993750377630234801225525279855157008009255586978047154906058790342845859331159016930635342872835520) (num-test (+ 9794320575955609492 13380937715397052566925484435342184213544885758759259410983243841206628594840271850190097746775475837233042430565529099681550277688470325394342993771343357) 13380937715397052566925484435342184213544885758759259410983243841206628594840271850190097746775475837233042430565529099681550277688470335188663569726952849) (num-test (+ -18404048401680891243 6690884608978704096379677348142836785900717005050936986370615083929607190833180925295418079551348559691161519822750772440155040888224482801864925665484770) 6690884608978704096379677348142836785900717005050936986370615083929607190833180925295418079551348559691161519822750772440155040888224464397816523984593527) (num-test (+ -10763220363947284865 -30985722824355332972176356513316569304601382411274079243859710673739383446566598659878378034375348869471278415635671865753349734809209959160389615096293457362383744562507969316522225741589739150453090393424063226271167062127000223628785686999799282795143706407082119829140399988180879618548495395684946331608899565543458192773899200054228140747414544792128323269250618482622488195333106891323515989863192944848391405358725993695671970811097285270641251816244586360288952156538400321933146150313939864593445583603568771077260174826348411367609521412133720180359748539721570562669201065857989876521301209899829037444385) -30985722824355332972176356513316569304601382411274079243859710673739383446566598659878378034375348869471278415635671865753349734809209959160389615096293457362383744562507969316522225741589739150453090393424063226271167062127000223628785686999799282795143706407082119829140399988180879618548495395684946331608899565543458192773899200054228140747414544792128323269250618482622488195333106891323515989863192944848391405358725993695671970811097285270641251816244586360288952156538400321933146150313939864593445583603568771077260174826348411367609521412133720180359748539721570562669201065857989876521311973120192984729250) (num-test (+ -12742462236537568498 8711131313747826394504271797986775572294949693272674156076339989631171694968899228610359983845552623710580616605402899155485071497929100432998183040757832449369366844015907530612334721882095163137705867337969942902346066961718232788529860214990099385213558935023241940238638069647809530490438245386869385682221280939688108487754251075630026707075310465788398213293782900699868609660892232563106662995330591906155134237356516622436517046191466823447743155250482328613449506396571170001248589926831956459700467126756876526930443317428628239358666456771112897986098390410773312792390699312960051747534683311506465130527) 8711131313747826394504271797986775572294949693272674156076339989631171694968899228610359983845552623710580616605402899155485071497929100432998183040757832449369366844015907530612334721882095163137705867337969942902346066961718232788529860214990099385213558935023241940238638069647809530490438245386869385682221280939688108487754251075630026707075310465788398213293782900699868609660892232563106662995330591906155134237356516622436517046191466823447743155250482328613449506396571170001248589926831956459700467126756876526930443317428628239358666456771112897986098390410773312792390699312960051747521940849269927562029) (num-test (+ 9991390529516174614 7879872958436992955898278403297937595295396115022400543178444946646147916754852888072481665174663073269556311758611700754643170639645548596647557683044355930340624784190093631808382820554407595007761070026239341594197877214157118335743842022627898879376346092898666610367809537340994845045475091410516226225078052019727419030585524815982151736622865401299588936172760762386183577504972623377661437665668080131418564228642443266935225613702941906491478788336262289516199380144218708241406077806669686589734333554945412904560108150202389909124657090061223183441083590340175629756198442568877659538345749595968764873879) 7879872958436992955898278403297937595295396115022400543178444946646147916754852888072481665174663073269556311758611700754643170639645548596647557683044355930340624784190093631808382820554407595007761070026239341594197877214157118335743842022627898879376346092898666610367809537340994845045475091410516226225078052019727419030585524815982151736622865401299588936172760762386183577504972623377661437665668080131418564228642443266935225613702941906491478788336262289516199380144218708241406077806669686589734333554945412904560108150202389909124657090061223183441083590340175629756198442568877659538355740986498281048493) (num-test (+ 831234034418847630 -744676478858160349467117341859049692149463503380690495147216354303526704924280287782902146026018180364963325847811379182950159627878800024734206345960410146056000392683000433501805629464626281031086102425271022388473812300724085127447081771317912465921636737545371909901577246384446144919253141375367648958387948463576516115079816552636772639965957498569187848459747361493535081532845254971492261148968198806736512864867151355002902241562014241077734122599581732704243705918200179789271894804233542502502119523149682814025979598424744685548054183678652651244898867735764030968089217841214778606507809487462642341164) -744676478858160349467117341859049692149463503380690495147216354303526704924280287782902146026018180364963325847811379182950159627878800024734206345960410146056000392683000433501805629464626281031086102425271022388473812300724085127447081771317912465921636737545371909901577246384446144919253141375367648958387948463576516115079816552636772639965957498569187848459747361493535081532845254971492261148968198806736512864867151355002902241562014241077734122599581732704243705918200179789271894804233542502502119523149682814025979598424744685548054183678652651244898867735764030968089217841214778606506978253428223493534) (num-test (+ -6996572501442843347 -16567158719848992553565776505785820491834685475229611199353714982570065913508303466008005931649515528390057456882757990896824841386431756898386429000065518724021230756426613661219891419166146764347562529640689229693578574350948436847247856000438153789455857903402883189892697143647998643667467614427922009931545254965075041050860609824086811877108940020349157317276288348430058535959434983921323332907180869396258655826781438419383792024592535415693101119109484610789291889841197827977530804650015884500878613240443324806805475203272442094530735476095374446946252236490708915034012846683015547314889561060687692538144) -16567158719848992553565776505785820491834685475229611199353714982570065913508303466008005931649515528390057456882757990896824841386431756898386429000065518724021230756426613661219891419166146764347562529640689229693578574350948436847247856000438153789455857903402883189892697143647998643667467614427922009931545254965075041050860609824086811877108940020349157317276288348430058535959434983921323332907180869396258655826781438419383792024592535415693101119109484610789291889841197827977530804650015884500878613240443324806805475203272442094530735476095374446946252236490708915034012846683015547314896557633189135381491) (num-test (+ -8920936222630165483 -18738991973681679876688842391791783563249057933653045519186959571392922172943405646958686202208790537612746921398028331540617848217445632123805070077600768524509025758950743971128222843292926773668584735575066246660802064630842300367821042873152766467703905048558085377302000898639290554395913805527529259855535801856020623830262396582180677933562523957295341539162448074423901242873918231922121053192425691524797238343327318801359521456598967984637483081312932069399045363737622797213185099130529375169698811801965974416555301085043300426947769193582129151016159057101028336667142913854943018973494705119572045938607) -18738991973681679876688842391791783563249057933653045519186959571392922172943405646958686202208790537612746921398028331540617848217445632123805070077600768524509025758950743971128222843292926773668584735575066246660802064630842300367821042873152766467703905048558085377302000898639290554395913805527529259855535801856020623830262396582180677933562523957295341539162448074423901242873918231922121053192425691524797238343327318801359521456598967984637483081312932069399045363737622797213185099130529375169698811801965974416555301085043300426947769193582129151016159057101028336667142913854943018973503626055794676104090) (num-test (+ -243510292488206214847646757340020705642 5940577100149745132) -243510292488206214841706180239870960510) (num-test (+ 35446324064743728955945058978206455057 -6248622708755929572) 35446324064743728949696436269450525485) (num-test (+ -285342226760657637664173494795024413673 -11942737781617905307) -285342226760657637676116232576642318980) (num-test (+ 180790435817422032042321866247362452865 12401641959336396832) 180790435817422032054723508206698849697) (num-test (+ -179994871947239535956826388240542999950 13573822506399140772) -179994871947239535943252565734143859178) (num-test (+ -308198027295905163635866438671452347268 -8790069282378476990) -308198027295905163644656507953830824258) (num-test (+ -139324757925833055762410227358605285566 -190622873846936719063564661032771271922) -329947631772769774825974888391376557488) (num-test (+ 332866352618304570046318203427223999347 147978646177673305481282943528696833018) 480844998795977875527601146955920832365) (num-test (+ -39471620476300923970352914034802271156 28992893610776120142668950821916856486) -10478726865524803827683963212885414670) (num-test (+ 274120253734611965146455315763505869288 254675910805265090692978775702306142625) 528796164539877055839434091465812011913) (num-test (+ -122086811464559635596206661886176775901 287312583034687582188356355813963609701) 165225771570127946592149693927786833800) (num-test (+ 288576174771266329955482943556556984728 -57843540651903655425270706396868707777) 230732634119362674530212237159688276951) (num-test (+ -47977736580820486006305788441965482221 984809271313988066640898939725532304075331399066274624928410251834520283291912387208948664716457549646483445981126881113426109906085249657168046936670489) 984809271313988066640898939725532304075331399066274624928410251834520283291912387208948664716457549646483445981126833135689529085599243351379604971188268) (num-test (+ 21225484205143479814642328762121362291 11839789093732539327981861490012713257538550745921177905266671749716203131127256902110452504526721633943016923389974867770082516862899595554460170417713940) 11839789093732539327981861490012713257538550745921177905266671749716203131127256902110452504526721633943016923389974888995566722006379410196788932539076231) (num-test (+ -193095363331703875886398909106293703000 4389392021031719669078675478621418677903292147307684123866099084349756491860737402449105804868232530632178577388168068485304437343508442251302846768269976) 4389392021031719669078675478621418677903292147307684123866099084349756491860737402449105804868232530632178577388167875389941105639632555852393740474566976) (num-test (+ -14827657635864183514988182371035598180 -7256545787852407071411458891023580461638051949278710509801472046178301830006724297747051044450550248499056073213660185258676369175307019300952192657194576) -7256545787852407071411458891023580461638051949278710509801472046178301830006724297747051044450550248499056073213660200086334005039490534289134563692792756) (num-test (+ 54301423175725658626298504084995819705 -13385853291610595576947504757201441006088030688464261540642594993520424631577281077984278942244446266776534612440941312995898184903431893212829646845766101) -13385853291610595576947504757201441006088030688464261540642594993520424631577281077984278942244446266776534612440941258694475009177773266914325561849946396) (num-test (+ 195114404067053480147948948510253723990 -8373866462448797623435948949281383906369538962237624940506813188612614128993186653340202956656303504523161255703176374041758276069255591562198514767063594) -8373866462448797623435948949281383906369538962237624940506813188612614128993186653340202956656303504523161255703176178927354209015775443613250004513339604) (num-test (+ -308030589512186791277525017840002670741 -11922204352024596469278978325035646517433105521287613403902396944414655739824695945028308092245747333098422116078042326104667969967224788442970266049942774583538734406057081597034454910987815490244451193242377705191422489528853976486607580169986057592557285271953385769215318545520155212402919465580052078255078759756709086185424029620805084776442744700501748376290562843380642608395240491162047933014854466267084965223593172702334466729933986413870670083326499598274393380692146118979961818816348097032083332695128587696590646086980241100792624502607816103195636761141133903550454815591457829485684936036414823492160) -11922204352024596469278978325035646517433105521287613403902396944414655739824695945028308092245747333098422116078042326104667969967224788442970266049942774583538734406057081597034454910987815490244451193242377705191422489528853976486607580169986057592557285271953385769215318545520155212402919465580052078255078759756709086185424029620805084776442744700501748376290562843380642608395240491162047933014854466267084965223593172702334466729933986413870670083326499598274393380692146118979961818816348097032083332695128587696590646086980241100792624502607816103195636761141133903550762846180970016276962461054254826162901) (num-test (+ -172649878347923210775992373331623646864 22180935775581457002090790736532281654456312526625354262953960635330604551829750571440878712430708012807252279301365732385899228826740712544768476577874129759972563823209525283326887563301081200476495752033290851190327066070873711444930389093339915885090143783170994309089448293499799071372787520776773788274677288230540162485916160484352398851925328125588729604931589867889917097887951581817207079060016091919559509735997493084833476849835444339835031436580214492450731100723026312163752403946315983551266206214298679421644737804098691991631489261658890937663698502561036246447760919715595005106669653475931803053499) 22180935775581457002090790736532281654456312526625354262953960635330604551829750571440878712430708012807252279301365732385899228826740712544768476577874129759972563823209525283326887563301081200476495752033290851190327066070873711444930389093339915885090143783170994309089448293499799071372787520776773788274677288230540162485916160484352398851925328125588729604931589867889917097887951581817207079060016091919559509735997493084833476849835444339835031436580214492450731100723026312163752403946315983551266206214298679421644737804098691991631489261658890937663698502561036246447588269837247081895893661102600179406635) (num-test (+ 17539006966816771902104329685391462527 15609797782337099611892065465036826453911053690739041627254619195700021040383385710184052653282070244915503750549545390475671883312314708978681904377133928647935359080875691628246716591529028104762422990155477702994042953196747769893182153631482194578269859879402160062955490194674372351117284129320011166238130774752386987036267064693133554447596069886693581191241594745541512444806003236372840085705813835001957163976961730871756250344335996073970142337882238844723800849054637237549515249957267772181010402413375667537558243971058326641257721901094391380667244006959028327507917720426571969997513984360849930719808) 15609797782337099611892065465036826453911053690739041627254619195700021040383385710184052653282070244915503750549545390475671883312314708978681904377133928647935359080875691628246716591529028104762422990155477702994042953196747769893182153631482194578269859879402160062955490194674372351117284129320011166238130774752386987036267064693133554447596069886693581191241594745541512444806003236372840085705813835001957163976961730871756250344335996073970142337882238844723800849054637237549515249957267772181010402413375667537558243971058326641257721901094391380667244006959028327507935259433538786769416088690535322182335) (num-test (+ 244901855797156286376563377540855746602 -22138106346578776369849317622304392466030036563754663379976505966920461958652141160336156065177498990718609170201272980114106671808245437660234479124938853665375934080221740523696180221118540569603989748587853373569525751680828044059607889572522502629277877343410298879764820905044284757389006201848194571453112545228115550224254565141563427486518108434758694923122284117299374156393942906293546318323661938734959824887786185558612820887463537294120950912969343488704744978847504513710882720654330147775174336365363311173472002077960424794151168301281665765411704505095008907760396535767621855642720080219960822554492) -22138106346578776369849317622304392466030036563754663379976505966920461958652141160336156065177498990718609170201272980114106671808245437660234479124938853665375934080221740523696180221118540569603989748587853373569525751680828044059607889572522502629277877343410298879764820905044284757389006201848194571453112545228115550224254565141563427486518108434758694923122284117299374156393942906293546318323661938734959824887786185558612820887463537294120950912969343488704744978847504513710882720654330147775174336365363311173472002077960424794151168301281665765411704505095008907760151633911824699356343516842419966807890) (num-test (+ -119403662992279138748600939857239307122 26272999248235953724172008428088697264933069743507017434844709711501131900922919455931092196539942532993887162365511473221418376205773427597933886270411672062672089518774390132453916538404354895529975888201032175628249480896964400801763570333497287321002961557096975786141940970260074557095118887294558700145949117395512768347250531196100831164663613049206690894640391431616112104502483838173255614981302462548882276825096564828583591963617871547373532874400764134244496979962241959713525053686209002866840900623246072884125102845824992994967009109046451949348656842486048332953732384499190437432898387573320391878853) 26272999248235953724172008428088697264933069743507017434844709711501131900922919455931092196539942532993887162365511473221418376205773427597933886270411672062672089518774390132453916538404354895529975888201032175628249480896964400801763570333497287321002961557096975786141940970260074557095118887294558700145949117395512768347250531196100831164663613049206690894640391431616112104502483838173255614981302462548882276825096564828583591963617871547373532874400764134244496979962241959713525053686209002866840900623246072884125102845824992994967009109046451949348656842486048332953612980836198158294149786633463152571731) (num-test (+ 313963939617834410089002930298454269912 23286645405607099799151331553995799851855144387826191186590140820016670502830395945076644578998873585162998873396623634135231418574284200209367505115739462344028303923666952261030907434438322884189133236837089851688275865098623902644385995630973049587854251981548128145516004461191094062488421288607625783540996659060285661398859383778209495884203323937672739376151794507745282074538961033778823733980759695886879886017489555795079194346438911010371103435094677167286870898482214310646392174423422237727456012197253183422715313378603607058548706460095379882633958651034759773864354021315490712575535559549015858088608) 23286645405607099799151331553995799851855144387826191186590140820016670502830395945076644578998873585162998873396623634135231418574284200209367505115739462344028303923666952261030907434438322884189133236837089851688275865098623902644385995630973049587854251981548128145516004461191094062488421288607625783540996659060285661398859383778209495884203323937672739376151794507745282074538961033778823733980759695886879886017489555795079194346438911010371103435094677167286870898482214310646392174423422237727456012197253183422715313378603607058548706460095379882633958651034759773864667985255108546985624562479314312358520) (num-test (+ 2000877973959266893810594143560134441447453310844726478119781029700338468704683515329516333146806175216349912753585564808803731447160643580198590073658869 -17993015014355471903) 2000877973959266893810594143560134441447453310844726478119781029700338468704683515329516333146806175216349912753585564808803731447160625587183575718186966) (num-test (+ 5492930533666246223206322654398877802091439062008700770880939594548305919677404080859141226095489505872709347538974725998600861651942609010590873980143878 15372278140141207703) 5492930533666246223206322654398877802091439062008700770880939594548305919677404080859141226095489505872709347538974725998600861651942624382869014121351581) (num-test (+ -13405500833215428652808705089190188280715732437731292502890523313631564795139560159124390691283401484515088713758307366404145018349044148223082253439210893 -14793401891248640808) -13405500833215428652808705089190188280715732437731292502890523313631564795139560159124390691283401484515088713758307366404145018349044163016484144687851701) (num-test (+ 9945195259699924701593703207751086973468898794114625092150620088406276196469184233537941913755508476427888065765634203723512911676149274871082481174186606 8699133332160461067) 9945195259699924701593703207751086973468898794114625092150620088406276196469184233537941913755508476427888065765634203723512911676149283570215813334647673) (num-test (+ -1785165974800693006461065312083337532938610906605533088558498259067461510781028452552786542598361030690629530721209490413999022804146471920873844686294838 -13079925952361275418) -1785165974800693006461065312083337532938610906605533088558498259067461510781028452552786542598361030690629530721209490413999022804146485000799797047570256) (num-test (+ -4861207515430071951958387366611380234482792653010151054346367776006873932152600469133110239669746470475230906073865131648496652783311445471793936775767736 -9381557743227419896) -4861207515430071951958387366611380234482792653010151054346367776006873932152600469133110239669746470475230906073865131648496652783311454853351680003187632) (num-test (+ -6638723469626495957966112633999375479181736600737250559572415894485618850919815869703127084789143821420728194272094956858541960962483734293877093635361160 277811698220276334443479876776376776138) -6638723469626495957966112633999375479181736600737250559572415894485618850919815869703127084789143821420728194272094679046843740686149290814000317258585022) (num-test (+ 1983880417172931934469534542170437296262471214582817006917470485544552211448284732460451903536334682269123998240709059499894818265755197559390728940140016 -118940994129137705779355371753506018694) 1983880417172931934469534542170437296262471214582817006917470485544552211448284732460451903536334682269123998240708940558900689128049418204018975434121322) (num-test (+ -9354509264984586574958285335910611806441061705184818350015454221731287473282231343722010109181841005578131927454778025302197744540571159656556971614966757 120224841184491944160266976391113485817) -9354509264984586574958285335910611806441061705184818350015454221731287473282231343722010109181841005578131927454777905077356560048626999389580580501480940) (num-test (+ 4389359421234641412950681847970318834150108533025088077429496538447029921663033978550089607257809597829358374972237448178553189381274150213236222139873594 106674783386899772113212633712093787897) 4389359421234641412950681847970318834150108533025088077429496538447029921663033978550089607257809597829358374972237554853336576281046263425869934233661491) (num-test (+ -9319417879153488839579936799737117639058244394679644240663244688680826325564084529474537634510092069422987165268448907193562300482925125162731530249763801 192969103435503875767216559494769734726) -9319417879153488839579936799737117639058244394679644240663244688680826325564084529474537634510092069422987165268448714224458864979049357946172035480029075) (num-test (+ 1394404616168163951844558734723678125985464491792846741433683801962971891047718103736551854371207400145441134823994228143957746922511631911996296931168332 -211230038021470285136061932161632203274) 1394404616168163951844558734723678125985464491792846741433683801962971891047718103736551854371207400145441134823994016913919725452226495850064135298965058) (num-test (+ -2935941510094051560788359387128767361559188973149773593522440619832472030019457317998381634585179453958737810428870232715146002408187749944694186205812791 -1221176156661231926164756142840452419679061324806989304452215660535991083923207702827717652226257158321829748247784282139952864899457896871473184473608543) -4157117666755283486953115529969219781238250297956762897974656280368463113942665020826099286811436612280567558676654514855098867307645646816167370679421334) (num-test (+ -1338674579024795395027232680327531457830908239605718353094975139226848400289367913459076082700361212506196070727982446232782659114647371030398516119682505 -1298372177520411182435886041880377054374169787570856408996533471838082317927648953576721017727347029007573543972764860712708420553928791798580799809858729) -2637046756545206577463118722207908512205078027176574762091508611064930718217016867035797100427708241513769614700747306945491079668576162828979315929541234) (num-test (+ -2072456075229532951804023218627137969798924912365258263779029006567941400203608770518731715660383378937120213112973528605594220795605977413985543331908189 -9744489461776287963808523409593616918248399004543154581056479712028497082820841423941781438667661074968238703192056877665754560746003512076830245760254982) -11816945537005820915612546628220754888047323916908412844835508718596438483024450194460513154328044453905358916305030406271348781541609489490815789092163171) (num-test (+ -2570682164188734368809161664810917340861573482754788446510182252413437925852206735928397938304353826925422441004271229738766803460790995673395984247950088 656920705293329551826685120408221577679101260931105312141757138825917579070505267306626244216341686712802796891966598838285570807961966448181138356047523) -1913761458895404816982476544402695763182472221823683134368425113587520346781701468621771694088012140212619644112304630900481232652829029225214845891902565) (num-test (+ 7846359203342053693101523606887617345982401999003795257520576318451663998927274759872692123323796450295314377046602880394071105863527900699633560551732837 3683380639347829102597675045842249667669675715600522157867595962635108482512780509393310714588544837398923613138772339053021025559943198965234376657126821) 11529739842689882795699198652729867013652077714604317415388172281086772481440055269266002837912341287694237990185375219447092131423471099664867937208859658) (num-test (+ -11692323148567132684205145901751681947225824260005631214936266006610207543813382900867093989444659986091234552140689684476541703112098935301322850961583953 -8534276689564199122569555420819240948691777228327984555753862457592427992599992931175844172478864477440165366128106812103785256271256853749622592560655914) -20226599838131331806774701322570922895917601488333615770690128464202635536413375832042938161923524463531399918268796496580326959383355789050945443522239867) (num-test (+ -10734754884168724884333968138739681643742524619139397687680049322697740991391014196697040576174049452737571835233123127815762146577096625434481167057340772 17059878151450238567815178684522345445687980385106446646013863901583786249398194029757376950491550197185231926262467028755342392379269039238766592672298850588065335172902157386017520689203005559576263548017475991638498600879259882041932152385436968424098224966518534467302264172016376096778201462205990822825056602379115848799619564610033123837036507127427054121975400703490855123544706355545059512146550901507159940126280812512339749605195422987937677650572797378799103456094203126081464905326203083057134061673694975250599375795827437561275156235513192978645909947341297774926450637694325145427434486258223666250272) 17059878151450238567815178684522345445687980385106446646013863901583786249398194029757376950491550197185231926262467028755342392379269039238766592672298850588065335172902157386017520689203005559576263548017475991638498600879259882041932152385436968424098224966518534467302264172016376096778201462205990822825056602379115848799619564610033123837036507127427054121975400703490855123544706355545059512146550901507159940126280812512339749605195422987937677650572797368064348571925478241747496766586521439314609442534297287570550053098086446170260959538472616804596457209769462541803322821932178568330809051777056608909500) (num-test (+ 1982582032974021971225071139786536402936929744496433027195224299475980201425925452469321205602618940472354066218156609448199804973454183972974358405933935 -5591374624026484498020036332218412149978824230210339582240360391202660977358546150723165491729699122647688030937226316069237264083850854032732663284717882873051337566653841254365703461654061656817936193716386141166210237666314879751427421825450110467888973152907618520704486700443275358649289847595635931220181024199692771066498714511145489237541761266539978351840438236927937894376002981658065431416811632941197501676956304254109064936038146674412392128883565757325842468006824235119684861972224857533964558963441079998949499582965764591461900562931342373507763081479989957632695010603500633322408246084430203281475) -5591374624026484498020036332218412149978824230210339582240360391202660977358546150723165491729699122647688030937226316069237264083850854032732663284717882873051337566653841254365703461654061656817936193716386141166210237666314879751427421825450110467888973152907618520704486700443275358649289847595635931220181024199692771066498714511145489237541761266539978351840438236927937894376002981658065431416811632941197501676956304254109064936038146674412392128883565755343260435032802263894613722185688454597034814467008052803725200106985563165536448093610136770888822609125923739476085562403695659868224273110071797347540) (num-test (+ 11532228364136654310006206557545352284448588590560137249197311142901246089838098630841794341370689745410654263817911440601934362503092628725755210859171724 -25776236925500995542036591604259749301547568770017466769502569415611770276300787105037848049555500555975152877716727294374436703766730618054071617947449695177320842403963009384468257891933593584757723535299746543328292715942626303315235241470269740287031317322772461137186093930239744879822272349431389779234805703118929710210161489122272898252221025966631463842234537744822906696719691188223105175714602909117904182229960075276443648211003011686250829474364425483901920822837775032295913486152631638908227467242772081310515646217115760180349854601959031626524004201825198439309850266508687796415478396821644422350208) -25776236925500995542036591604259749301547568770017466769502569415611770276300787105037848049555500555975152877716727294374436703766730618054071617947449695177320842403963009384468257891933593584757723535299746543328292715942626303315235241470269740287031317322772461137186093930239744879822272349431389779234805703118929710210161489122272898252221025966631463842234537744822906696719691188223105175714602909117904182229960075276443648211003011686250829474364425472369692458701120722289706928607279354459638876682634832113204503315869670342251223760164690255834258791170934621398409664574325293322849671066433563178484) (num-test (+ -2603756427337798371354526130541868239006085657393372011847827118826669474695402075575479286172808099892726251004549675772420422527946534088483901153485670 -10844269742362409682236511127219508926736627172993604953084481596070757241623728297275447608738915355190715664012379562650777199088096670239050254578284071100042116609747208178716191571268815994455064584659920497876052406993834873124981417288518101426395560764186717660091472734401090302285129741058888303693710456902635092811413971399734306158050053239768185860958896447298052082493590498954512083131068867270078638929796561440903919430094619437872896595720463663570751134804664228918188923926951933302878771189484614604311920655871182974081898031051411394311700207305532216445616083858025977851570522763537300875989) -10844269742362409682236511127219508926736627172993604953084481596070757241623728297275447608738915355190715664012379562650777199088096670239050254578284071100042116609747208178716191571268815994455064584659920497876052406993834873124981417288518101426395560764186717660091472734401090302285129741058888303693710456902635092811413971399734306158050053239768185860958896447298052082493590498954512083131068867270078638929796561440903919430094619437872896595720463666174507562142462600272715054468820172308964428582856626452139039482540657669483973606530697567119800100031783220995291856278448505798104611247438454361659) (num-test (+ -5929887196386997518766568868806997104240129372360669348628384183712406620199102166145939206783172815805659513128544493795329100599632286529420772709366102 24544958491142793859949310604465694574872439331169358241746200808802938771527900616394258199996170862256988647191747967628756772368808644819831481350919782560499270148419601775750932556119448001824346026042068416905254113155445053931789404515589532235225580737103411251232560863878948880220469490014568323308965914171394449781093816607870593225534700167342589927524232815571862258490314644577819742372918446373756857848586825568514909823940075182825283229026250682015641747568282510036326125505522447591703308661608718100933027549520132308555240654655887041040427813131621391320267698106519650611462269033902177180035) 24544958491142793859949310604465694574872439331169358241746200808802938771527900616394258199996170862256988647191747967628756772368808644819831481350919782560499270148419601775750932556119448001824346026042068416905254113155445053931789404515589532235225580737103411251232560863878948880220469490014568323308965914171394449781093816607870593225534700167342589927524232815571862258490314644577819742372918446373756857848586825568514909823940075182825283229026250676085754551181284991269757256698525343351573936300939369472548843837113512109453074508716680257867612007472108262775773902777419050979175739613129467813933) (num-test (+ -8848084327536592532063677611386811805244460767433749071435930786126721080365289638381557872263825830664387392539638767251180242665642373539064690745095464 -15917950175678012281826361248776190984758236997789474333609547749168308439513527143790323694526378056113636462939674273462177686456811495629631337058042159570336251822399402513133598701991665209363955263097315081570618652783181494594400709239428597117944511110842795526862595552977665064029517628515465251448116061875878430407784298951946811321795808932206846491091803276390661869369638950672478828532423383951689632136029256108992610781912267083149156104328033893238864631158195280554850035949666897861529711006187241710164902350100555999894332438423857208747342184052953230247487231455921360593096823760117493579248) -15917950175678012281826361248776190984758236997789474333609547749168308439513527143790323694526378056113636462939674273462177686456811495629631337058042159570336251822399402513133598701991665209363955263097315081570618652783181494594400709239428597117944511110842795526862595552977665064029517628515465251448116061875878430407784298951946811321795808932206846491091803276390661869369638950672478828532423383951689632136029256108992610781912267083149156104328033902086948958694787812618527647336478703105990478439936313146095688476821636365183970819981729472573172848440345769886254482636164026235470362824808238674712) (num-test (+ -16314775600714318471451792035636584056297958597339492996728118376578145765736873313518831390349547274517050864260054903974054712997529177834428786007341762649083404743713562157667828894017440065599882523458121037421757904691003094608420565550031561905074671735751685371533975894842331113347413787808917193134135744321547478500861021485075363990553639161661734684228250909589741380076008551020384304303171431833670236949934603973673998262066558668396388979463892768199916011368116729432353268535563246463324517035331079693172060671712718486388759443825620676228470068291448236914050793177812037679396721657020438979754 12553426083939460917) -16314775600714318471451792035636584056297958597339492996728118376578145765736873313518831390349547274517050864260054903974054712997529177834428786007341762649083404743713562157667828894017440065599882523458121037421757904691003094608420565550031561905074671735751685371533975894842331113347413787808917193134135744321547478500861021485075363990553639161661734684228250909589741380076008551020384304303171431833670236949934603973673998262066558668396388979463892768199916011368116729432353268535563246463324517035331079693172060671712718486388759443825620676228470068291448236914050793177812037679384168230936499518837) (num-test (+ 20637030084881771176788188367974505419050866216433677435050410899110162793040751338330447574748263391136356400036001988938659722098883893353523409458775455519257672423829361150611806294256710309281788819450225670112435352092313483086404714074567539245791066202051788986426960935796927738180831688497683293306590464598379493141645539253898709000874685535467854788184424886911457134522632486730390913239660179785071885982403741669161655812015114272497907946919026898579927936299607156006210124954460880383605958519412435713868501997649784658832599101777001703519408664662715322044086646014163774269660274683400619225321 11620128128044940816) 20637030084881771176788188367974505419050866216433677435050410899110162793040751338330447574748263391136356400036001988938659722098883893353523409458775455519257672423829361150611806294256710309281788819450225670112435352092313483086404714074567539245791066202051788986426960935796927738180831688497683293306590464598379493141645539253898709000874685535467854788184424886911457134522632486730390913239660179785071885982403741669161655812015114272497907946919026898579927936299607156006210124954460880383605958519412435713868501997649784658832599101777001703519408664662715322044086646014163774269671894811528664166137) (num-test (+ -9838804688358141062268493389453191808060717708062736103828856866310283812230958467655270667206937622979717683919584610288962829724022506216738929136418489468786902364550847498615864720240589837282441807174290461916292258263929411081218952357662703079709351365960916688275651864441386750529258343003652300629003597744958152243494244227986280506395347894285277364095898602965258114321853474000520432831298793365139040664543928707100657375292032051256485942532600998813627925626928634068613637417702688610315924917761411247617905738119218110678854564441914784262998574445847209847985439514580300936248281049628734475702 2380166482232871816) -9838804688358141062268493389453191808060717708062736103828856866310283812230958467655270667206937622979717683919584610288962829724022506216738929136418489468786902364550847498615864720240589837282441807174290461916292258263929411081218952357662703079709351365960916688275651864441386750529258343003652300629003597744958152243494244227986280506395347894285277364095898602965258114321853474000520432831298793365139040664543928707100657375292032051256485942532600998813627925626928634068613637417702688610315924917761411247617905738119218110678854564441914784262998574445847209847985439514580300936245900883146501603886) (num-test (+ -30961575335426221869515496362216292453766907587859856766456625722888557357647164641922707199324601608700561081422636642523431947551124957385652791834855425829101761914145137205962610515642614866296480715893528289170482422505734612327038754622917335073993027434927547277037587173529054849390646376806910407207016292483185533697336599641898250465186168797820802225861771331652801064811222606773495565340386327294310913503461903243119204619412324538886439122443769008953829820425376589389335553937319588224864611583436327810214798652896733118881040503785110481197462772022447173744898802421806800203373153221004361953729 -10586442965055062759) -30961575335426221869515496362216292453766907587859856766456625722888557357647164641922707199324601608700561081422636642523431947551124957385652791834855425829101761914145137205962610515642614866296480715893528289170482422505734612327038754622917335073993027434927547277037587173529054849390646376806910407207016292483185533697336599641898250465186168797820802225861771331652801064811222606773495565340386327294310913503461903243119204619412324538886439122443769008953829820425376589389335553937319588224864611583436327810214798652896733118881040503785110481197462772022447173744898802421806800203383739663969417016488) (num-test (+ 8835746018617511846981408800319983340292665114153404569022025834059427359831684523399830234196625160662387716033871154398104436720494608541518837969397374272734698261557358249258503982414578618525420572597611597792132117034895074841909295420434392963714805547538976612884853497014341345150095544449860198192757839489063747595073430612069212219930749783824683135433987509303139260133564905961552149844964215891730262218278214035649706577154652729844092199333026620127958228847111442161350881527928460177763370427262298116900358910460957772350452949782281117704005514462730290063772968929608448642592954601418753021512 -12227722924075527556) 8835746018617511846981408800319983340292665114153404569022025834059427359831684523399830234196625160662387716033871154398104436720494608541518837969397374272734698261557358249258503982414578618525420572597611597792132117034895074841909295420434392963714805547538976612884853497014341345150095544449860198192757839489063747595073430612069212219930749783824683135433987509303139260133564905961552149844964215891730262218278214035649706577154652729844092199333026620127958228847111442161350881527928460177763370427262298116900358910460957772350452949782281117704005514462730290063772968929608448642580726878494677493956) (num-test (+ -5455184800550144006991157215735481579353213544152145628297990102571936052187486515129266239245491863623978659179559754999567936067584384479787934704340911556625153536160778495579370425428019248950494107696016864499055854257192071541354806671987402367524770228296322497224645429524493838356022616251290117624472061673033274133156467148770562815676767117605001434288573911556053311048284534341905722947046607192815465807736361991479044698448267471087552952494477144251510778491315012457514838113324210534577956298926109164909779987221094000880908857594198276812276890284008572664102792405452379662935026125770444036994 -7349798942312432150) -5455184800550144006991157215735481579353213544152145628297990102571936052187486515129266239245491863623978659179559754999567936067584384479787934704340911556625153536160778495579370425428019248950494107696016864499055854257192071541354806671987402367524770228296322497224645429524493838356022616251290117624472061673033274133156467148770562815676767117605001434288573911556053311048284534341905722947046607192815465807736361991479044698448267471087552952494477144251510778491315012457514838113324210534577956298926109164909779987221094000880908857594198276812276890284008572664102792405452379662942375924712756469144) (num-test (+ 27233955893140063612427006607965940109569052437681267421929959186535416115028420267622879017163568256526042146282241931623674996867133390355390677118211537487769195270234259640386625552763891339073878417517169618832945750393661600092643257470064376916337734385887099957095417541169462231630821139075814859604097878094729685589777579267192538715202397220666651307185763054526407234767132218634060693076054116575833737797189157152326979078121760900891899319809724675232853322526718686306470372869701173824664984405178677187081936624687293494821338781534163633206006387449585716391843039459733925494003066841874935048611 -66646390577667468207341453008390168215) 27233955893140063612427006607965940109569052437681267421929959186535416115028420267622879017163568256526042146282241931623674996867133390355390677118211537487769195270234259640386625552763891339073878417517169618832945750393661600092643257470064376916337734385887099957095417541169462231630821139075814859604097878094729685589777579267192538715202397220666651307185763054526407234767132218634060693076054116575833737797189157152326979078121760900891899319809724675232853322526718686306470372869701173824664984405178677187081936624687293494821338781534163633206006387449585716391776393069156258025795725388866544880396) (num-test (+ 15030400024888781078933103028897733817304421960545019199443871381537070197157227994520524631721701055962609956080413517776229513420814407790533237358129529547793422514837651333555776540939235592155512951229106778709351772195248438493792786143040421233061520515971787881798980515709417481015662862327435825812557205663033601853937647320838585333754027488605638576977560072206293290493215523194883494322543800546276353830683084405428005815296131527861252717516620765986589669237487765523936713749717927502645633123584240464131140829496052170285171610845098023517906586134613874506419828208611247177336492131262918439281 -164048419232636429449474429717211197442) 15030400024888781078933103028897733817304421960545019199443871381537070197157227994520524631721701055962609956080413517776229513420814407790533237358129529547793422514837651333555776540939235592155512951229106778709351772195248438493792786143040421233061520515971787881798980515709417481015662862327435825812557205663033601853937647320838585333754027488605638576977560072206293290493215523194883494322543800546276353830683084405428005815296131527861252717516620765986589669237487765523936713749717927502645633123584240464131140829496052170285171610845098023517906586134613874506255779789378610747887017701545707241839) (num-test (+ -10227062646189307616073129048534031298512434237226774743330733206156788005874968173984804649812506029813402205606562016228122184161577517837608957023376079537037472977098465137152327215807765130656192272994478964341604278041664840636982572214751638093860605132350960802560601354006634296348422600320863531059118477125143903734159707623839282511184908969206873548650544269932394344952983661665472663102992782521888857016369837211403335306200813816060883478434441858442549261115972947741929087886423170398410216855322384956160289855500229952405068604320121652911887067414460828300146993858360430784079225137421074839819 117460076430162201914796277915447781936) -10227062646189307616073129048534031298512434237226774743330733206156788005874968173984804649812506029813402205606562016228122184161577517837608957023376079537037472977098465137152327215807765130656192272994478964341604278041664840636982572214751638093860605132350960802560601354006634296348422600320863531059118477125143903734159707623839282511184908969206873548650544269932394344952983661665472663102992782521888857016369837211403335306200813816060883478434441858442549261115972947741929087886423170398410216855322384956160289855500229952405068604320121652911887067414460828300029533781930268582164428859505627057883) (num-test (+ 27989453264793973121573869640708223239762902243991948581280654553806618470632044367386680716040316895884976837122054709584963028986161694425215067648887944710852278135008221491665079705797192389681328802747226171436158375378499411314855257919224316919346771317457123252623293612958336691335423245293660257386649100685560072354549579281852792682734916555498283053758141666658137856828164206947320523255487437004565021167276952652515632644458005291855624829941937578229983628962137595011570216766689546500517528191189928660433013004254032861383790553611840534023221000900694995707453499030166286828319347894538505334235 -59175168207571178843658955348404514921) 27989453264793973121573869640708223239762902243991948581280654553806618470632044367386680716040316895884976837122054709584963028986161694425215067648887944710852278135008221491665079705797192389681328802747226171436158375378499411314855257919224316919346771317457123252623293612958336691335423245293660257386649100685560072354549579281852792682734916555498283053758141666658137856828164206947320523255487437004565021167276952652515632644458005291855624829941937578229983628962137595011570216766689546500517528191189928660433013004254032861383790553611840534023221000900694995707394323861958715649475688939190100819314) (num-test (+ 1178650930337394440162727078866515771626896502845852711186000991913866844090831426017480263676964607121490209778220339316756171449922437605552456088105443130477974682689512446683178356259305893852096425478878588001446154476458310269704392486398646169362313605456233489086567865316333034897433650974160168545492823208575634152241341906068149887959566983066154182855136114289266802474404127414747112706158621650063987662749553991791509795764642256261917497984177610694405881831052199417235241109412927893781778469398975117797578753730248539151297798807326284978255001046995523851829184120171969918537718488250577987049 -151873924489040812813761508259707631973) 1178650930337394440162727078866515771626896502845852711186000991913866844090831426017480263676964607121490209778220339316756171449922437605552456088105443130477974682689512446683178356259305893852096425478878588001446154476458310269704392486398646169362313605456233489086567865316333034897433650974160168545492823208575634152241341906068149887959566983066154182855136114289266802474404127414747112706158621650063987662749553991791509795764642256261917497984177610694405881831052199417235241109412927893781778469398975117797578753730248539151297798807326284978255001046995523851677310195682929105723956979990870355076) (num-test (+ 28233332719950979786871881804755080223325040620170668729385709165879717973040387558150293205758215739710262749733170837042434162049732587908182282319848154049410849721309988807368466228286699721201975848741931128639324322061892706638973259354962358866000024260698793885547287093369940035337370984725857550291339492871017395328145015077506882578124550084937438336881072124376107623716831044079223921566902242543198986921476998895559488862309653154914291349588095330683589871173449191854284433182368052817373384461363574550061788800329400860372148193491004593903732351395815409821222597665222975816418433744748143385431 -43245950360315656184924888243641533635) 28233332719950979786871881804755080223325040620170668729385709165879717973040387558150293205758215739710262749733170837042434162049732587908182282319848154049410849721309988807368466228286699721201975848741931128639324322061892706638973259354962358866000024260698793885547287093369940035337370984725857550291339492871017395328145015077506882578124550084937438336881072124376107623716831044079223921566902242543198986921476998895559488862309653154914291349588095330683589871173449191854284433182368052817373384461363574550061788800329400860372148193491004593903732351395815409821179351714862660160233508856504501851796) (num-test (+ 17311283930487575047109155431670372891723312431004343097275158353815289445461275098157423001160013464866170709729134076291306322952612660169010483426086431377525432637844274608988581691477819008626983761905899834444008235608280930166913911248710072733217113558125600345343437000427963292980921009445490627620344145866648036116660335905940809860199697939729919140888034303887423527841395304960072549430314367914315102150378504502158659627719016733307736583749830415574905929299482373462584995162798576853564481617711234957058703455021082855018642616999836886763535412642684228990890160568207941504887072856663966242787 1954009743321912552050341299974626734964446274711484506734354360114801426013796892421541915293157994203607853436799102383078659985249097057923578528366737) 17311283930487575047109155431670372891723312431004343097275158353815289445461275098157423001160013464866170709729134076291306322952612660169010483426086431377525432637844274608988581691477819008626983761905899834444008235608280930166913911248710072733217113558125600345343437000427963292980921009445490627620344145866648036116660335905940809860199697939729919140888034303887423527841395304960072549430314367914315102150378504502158659627719016733307736583749830417528915672621394925512926295137425311818010756329195741691413063569822508868815535038541752179921529616250537665789992543646867926753984130780242494609524) (num-test (+ 1135960177108146621604027872788612991247811085764456406834564014092038611848908717507207251239454266163702244932570537009884467598603226302482406831131219148530146321028801515381981782506355042255201016953375149829517466449677312249611502599434850555618739830488706171667035140895674806873502543300909514568759918040129665855731078258004983486524477103833885001539135541445685573269814159175744401893663504523858005835387122082112362666991112899837534230326730196110477118156871579503345757821268248575583821695674912517830056856597644827244194658166928026249459511837772775196175188368236573504643083995409774002567 -5513982495816270388232134254127393284677692173792609278582774509636977743203029647121158805174638642867428501907786521939155900331399058909602425073976766) 1135960177108146621604027872788612991247811085764456406834564014092038611848908717507207251239454266163702244932570537009884467598603226302482406831131219148530146321028801515381981782506355042255201016953375149829517466449677312249611502599434850555618739830488706171667035140895674806873502543300909514568759918040129665855731078258004983486524477103833885001539135541445685573269814159175744401893663504523858005835387122082112362666991112899837534230326730190596494622340601191271211503693874963897891647903065633935055547219619901624214547537008122851610816644409270867409653249212336242105584174392984700025801) (num-test (+ -30369736932762868789456108597366835061749107555998091727589163626331595118680326568212941898571309672187038272915036839449380083450246957904300051802617002374912724325419651633014408152565340519439718081357147324136023867003917288524338643759680061563616479323818330115572573568245719292922176485298767387601922362893307843067637295955606642841006993776777666041277965868780958830666697755738164183356399977211227424725670822944234275611849032230010745799964550976844117943559190671369193871330514473741920389633762695829790016565565261170688485790141638094160105909405353382982945608773290740598479367828342651860878 3451570547959142767282758882796967240086418127970526029661337442068316209707489088420708984628065070358319478649952710478991064476168799556496237099109563) -30369736932762868789456108597366835061749107555998091727589163626331595118680326568212941898571309672187038272915036839449380083450246957904300051802617002374912724325419651633014408152565340519439718081357147324136023867003917288524338643759680061563616479323818330115572573568245719292922176485298767387601922362893307843067637295955606642841006993776777666041277965868780958830666697755738164183356399977211227424725670822944234275611849032230010745799964550973392547395600047904086434988533547233655502261663236666168452574497249051463199397369432653466095035551085874733030235129782226264429679811332105552751315) (num-test (+ 24749014370880469345815230363662696846133977441600857690896762642529872426102613384561609594131771018575590861342023688138502403609639138062665279129058939911797019091643704220495944170754490238422880589600838613701783818105188827633578438439212856537589855796204839275633245851474930725845096235668385012500773524750522781174430369067441632028068262240870795850561389232369373523415592833273932285308223863420210049445377497367753786125779044716949754454461623397410528064697616617917065021866397277409044449982605591256067763430930720398889239414812509701319783809830072841056369381573100589260104551934136733317845 -9461623592584966196513107657889418526847060851423069480904645009418813160370721071067349946095573698635859409908288864150475056170059858850823883834932131) 24749014370880469345815230363662696846133977441600857690896762642529872426102613384561609594131771018575590861342023688138502403609639138062665279129058939911797019091643704220495944170754490238422880589600838613701783818105188827633578438439212856537589855796204839275633245851474930725845096235668385012500773524750522781174430369067441632028068262240870795850561389232369373523415592833273932285308223863420210049445377497367753786125779044716949754454461623387948904472112650421403957363976978750561983598559536110351422754012117560028168168347462563605746085173970662932767505231098044419200245701110252898385714) (num-test (+ 19070246171469235561279483225919489206942407814032615339351735800304747459507922411906751965555240682457214768298108831815622470433175555196912899313888991765436434867025639919521068437191248198117664398275835972573354886915721765715992151871453808224011999677700078879590132676060988550961950472536029228350169237717222998397029428440792110955380302156159849645211726041489206565536560827557279129751110297078563108009278363910936720061216511798518178957070787710331228500533067546198458251241005176280410230146430275074766072259256583499095689284871987010372039977403712023630453400259082684930755893684499232318008 12330599952818018622104330691506128012101935028731995985677032980931398338453806827555760801312052792065671886621851470997557806941112316627790755867100463) 19070246171469235561279483225919489206942407814032615339351735800304747459507922411906751965555240682457214768298108831815622470433175555196912899313888991765436434867025639919521068437191248198117664398275835972573354886915721765715992151871453808224011999677700078879590132676060988550961950472536029228350169237717222998397029428440792110955380302156159849645211726041489206565536560827557279129751110297078563108009278363910936720061216511798518178957070787722661828453351086168302788942747133188382345258878426260751799053190654921952902516840632788322424832043075598645481924397816889626043072521475255099418471) (num-test (+ -20895998178036569919774658790651496115060841511658297683195804524712012347695091074325978179977718571444320688167469052862702339462089668992243209990795362064005869602003990235714500149401994013174762139297327430396441552225926368085284222509085197484452650071390132794942944512235132641643003294762547138305644086106533258432786768644384855008506026923783604514268955071498269812887794817192371944269611642901807443894686178438687102834127061425955994253034824027771176714559050403098437684091684851207513969915720607528045624635094984539637789113651579846373399975502788877555747414523231999341294756679330384323996 764238600803843266244444637050072967342049538611688895792923539838804953492110953673720766879606601435939162680753428779068917662740403667549850724878795) -20895998178036569919774658790651496115060841511658297683195804524712012347695091074325978179977718571444320688167469052862702339462089668992243209990795362064005869602003990235714500149401994013174762139297327430396441552225926368085284222509085197484452650071390132794942944512235132641643003294762547138305644086106533258432786768644384855008506026923783604514268955071498269812887794817192371944269611642901807443894686178438687102834127061425955994253034824027006938113755207136853993047041611883865464431304031711735122084796290031047526835439930812966766798539563626196802318635454314336600891089129479659445201) (num-test (+ 6243894672855694190803081952962387322599009058758027960092936187687064819462191583137945440936085088260632250436567758576422207449236613172605950116622271404444221039084346501796818945639456207912207604248991842124079786471250102192718092353598850889806607728696519257402580732995770031331187089424192803722612735557735028710899438934171272639518928194764526910590046378401600819132587804143949995694950116915803127294011661411525934100144319021440919928013617766507409909846670172516021888661284467975865076091834094160862228180625536450124272957206172214541444266874056050295270719541605687740822711659847211976891 11877496607682442993105675644902145742318375725225741293060927105303783712520284640625374957608051032540491531573337817824773543104969422017506696018037874641947740606655370938613842356322585858034851150595788166740174872996252792014218946552442572806242471174234462119454014379628228878122072189387777413014452140618318641689597452676091677588204537830401725113931418426919671512011822864583481449136550835952005765386885680701637038206002172218712504732572449659704181315669255320876647592649071711438131711904976335957846353867776093588236311654631696625859173554395714740218099921290128795607292259527492722462071) 18121391280538137183908757597864533064917384783983769253153863292990848531982476223763320398544136120801123782009905576401195750554206035190112646134660146046391961645739717440410661301962042065947058754844780008864254659467502894206937038906041423696049078902930981376856595112623998909453259278811970216737064876176053670400496891610262950227723466025166252024521464805321272331144410668727431444831500952867808892680897342113162972306146491240153424660586067426211591225515925493392669481310356179413996787996810430118708582048401630038360584611837868840400617821269770790513370640831734483348114971187339934438962) (num-test (+ -24023960171862805266003610953999097357395283354964456554686635290239019705581779621120391229617494503580661676939681517550103414632840981987397485411400553792707518662609532504246677658012933762605038799352109564432278094548068984563394926376371580465135388578139331334464060067790936072127680597181415407099723844313625277987147283697141407959289588588489162704824409673099509423520008795428217612706997355591985894255450783091681112776112997887084157623388943538145736618168104404283342039105202585543852590302154958791010622670839015475427693311663800177428904406869645066988663292128104453773413982185343111560886 -31939808827732134714870375774276102357277346245583282398423150631754622253109692213928642228787888509211781331649081002266227303203259124984426497846441848502574293640959494009564992092503141598640200823656998243767453860939156780549404892392521391484933772285520949470194562525777116137058001008184603332597820522016200623301007194309404025522056113671560767212894303567191067178003014955596425115379852712737129325098876542459702682095445350281859042779889411325882123213577906096942649941285655935053362468972482748617111598313960198743596285343178242282172686940700127068972627110105953098737923773182254460772630) -55963768999594939980873986728275199714672629600547738953109785921993641958691471835049033458405383012792443008588762519816330717836100106971823983257842402295281812303569026513811669750516075361245239623009107808199731955487225765112799818768892971950069160863660280804658622593568052209185681605366018739697544366329825901288154478006545433481345702260049929917718713240290576601523023751024642728086850068329115219354327325551383794871558348168943200403278354864027859831746010501225991980390858520597215059274637707408122220984799214219023978654842042459601591347569772135961290402234057552511337755367597572333516) (num-test (+ 14513652183174940741664411990199277445706189147726874603036586212536012746892966848269748909379750612027025331446918381470766609543142456872580466135425754204680927122749772612276850998180593344389487924747722210296498854143380696064338777945015153982467675141485724865534995199700908286263993697988986805404864429385840512740226775506122190698806967785494289035976495492863456705096841250592980439363856397663738211335801835896091823148249303370609165910779981271035234045185574995335952208702661648744928539539455138167482396767268362221492607154709559716065850417221174683768503217544145599044845325824451589309835 -12814535978730024053359592817368712576084646962861720729844389627130663192435154658607204342320327460695280260731620465435530495952836598646143907272825807563512741964987882356778796849529260646503692618525570185450780889283642116889481314560395290434301143877809550098309214046129802023655714098730144464028249594406616074059558969757405392170810220921023905546104487938441503430332099605473144930508420331873995741851604525954472341693863067199617721032815462094767522339305487934030130207039176659398466616780628644572276059410087128533031562978399689702766028716401176531098447698206272762966470643604141938670152) 1699116204444916688304819172830564869621542184865153873192196585405349554457812189662544567059423151331745070715297916035236113590305858226436558862599946641168185157761890255498054148651332697885795306222152024845717964859738579174857463384619863548166531263676174767225781153571106262608279599258842341376614834979224438680667805748716798527996746864470383489872007554421953274764741645119835508855436065789742469484197309941619481454386236170991444877964519176267711705880087061305822001663484989346461922758826493595206337357181233688461044176309870013299821700819998152670055519337872836078374682220309650639683) (num-test (+ 11356479761814008572465147431830778885327227506593483181241437802252618729479905490826767363633131720717461693888023278837835457496021519184903984385091047829540007466025527592005114414671285638168997562037691602144751434208304408870143450743278437854754504713023422097017723330207792526222436928747286558205279330508360438281011315147578105966454344087225699378388309094140949428028313539634103047841948634832398526343605363013644180832752120081735152285507591096001749463421326282317713079361827765412853023201330345752038722069405404812511739634687282327711258974520622248165974215116400638833123609666501349513623 -2451734542868054449539778460457497703609327132304922810342762480808881050209276687756391911546806187586640918078231508181876445466503459873508196878629364924241891220686182517218825181707207808769770392864734466652524094735160185556148554260517746279303022469784592528209667497664672945900929888144529727881050106027775707933311860110618130543481573815538047460723253898548348335762406437618625388229555824532715231231491787570056329865617082709588903922431713098922691537317839185452018617461891748518176708607861270770493263960554805373552348256747200291438630960804647686832667981625018361034564086859426490014044) 8904745218945954122925368971373281181717900374288560370898675321443737679270628803070375452086325533130820775809791770655959012029518059311395787506461682905298116245339345074786289232964077829399227169172957135492227339473144223313994896482760691575451482243238829568808055832543119580321507040602756830324229224480584730347699455036959975422972770271687651917665055195592601092265907102015477659612392810299683295112113575443587850967135037372146248363075877997079057926103487096865694461899936016894676314593469074981545458108850599438959391377940082036272628013715974561333306233491382277798559522807074859499579) (num-test (+ -1814184401790217165873937825605141478060935014868566665644215718762341535891730598045990231798382966074312671040257824056876679135909008140059087311700216658095793352051583071432744886316274989901835606602224927350560604355249919901932382803472476702792978322468747380191775778902733911968522382089332819162367884984027854067607561808704316828316820133400099093450636968732151876570835173932998599031643640476109466728761033062776578175554441947411139184426213290292577467587355369954997241091769769542810051228504545831588488726789173405585678190671534386784806998695797717346491308862362775748058331375692317599945 15466182953987394334491149436346080039471412309427279110582769586053943302670765125931570041904640518032832554998553018838321871748542118021556398569294085708441934948186080236498081517178574839977996802813431873543309853609838200338534343580791382510179184571852290959723696010410340740895530535423959476873857191548113125728667781953125153120447892632916574768078583174099545013854248664119997703948998871566374080719541931440495888606776561795893839624084254684939434035018741535261951124673664746010067859317726891535170781460914710499572006592206360512398012457295755926986236618644330364227754380084585899275327) 13651998552197177168617211610740938561410477294558712444938553867291601766779034527885579810106257551958519883958295194781445192612633109881497311257593869050346141596134497165065336630862299850076161196211206946192749249254588280436601960777318905807386206249383543579531920231507606828927008153334626657711489306564085271661060220144420836292131072499516475674627946205367393137283413490186999104917355231090264613990780898377719310431222119848482700439658041394646856567431386165306953883581894976467257808089222345703582292734125537093986328401534826125613205458599958209639745309781967588479696048708893581675382) (num-test (+ -27127130599753372624001250456405972983012981437652156246797208697430661165612459362971759027335854588888552031022264244768883843080959804690580574272908031271224646245152017114094021048441971097191444782106551075175878815012595015584723250801765859461211934306789890718268168352614164589637346918581658850565274510502652089457352942736418509881708568727739912127781455473660768550022762222130489047215089836402367851853412705556570667960548570630054608024914653686223423908494006675057953013815512203710764854485332282975729323105427143207127239069826750682633272289409910001698385240596625059970587393681128674617278 5719655139276246085992066702308194672442413085748146924567717361937179810269300239821879673460959112727066470468217892213025828988023367028158410455624528688729907493639908638553730770145274142147983721694721139760883483821883267129411125364089207412089113869427479340283853501026803387874124668123626271531796990801822527792189514551888019206405597994403243358155410088320317141454525417323186389587327532772638942220300149829241141659063128602316305332848477566686425551944956989370838072872906293845914921103561360871571846865478762953536949621421094416539099628942010528483544062050170673327754206501716239719529) -21407475460477126538009183754097778310570568351904009322229491335493481355343159123149879353874895476161485560554046352555858014092936437662422163817283502582494738751512108475540290278296696955043461060411829935414995331190711748455312125437676652049122820437362411377984314851587361201763222250458032579033477519700829561665163428184530490675302970733336668769626045385340451408568236804807302657627762303629728909633112555727329526301485442027738302692066176119536998356549049685687114940942605909864849933381770922104157476239948380253590289448405656266094172660467899473214841178546454386642833187179412434897749) (num-test (+ -6069217517368004039/4076344942716985944 -399587800008780737/578697755310708616) -321318766345655960630110128852941297/147435729263904928853096856396980844) (num-test (+ -41285036778370718/305793940074617155 -1396094619926552183/15846027887642356854) -1081121118676718273499338028514700537/4845619302294419132297197085940230370) (num-test (+ 15975644088444536091/18063939613598316583 17501188199168431305/2979264551795273683) 363736076920798535449296038324193823968/53817254956563877935003279344562385189) (num-test (+ 10197734562406803221/17452826108659293487 14639450560606090654/236781760961536951) 257914422508077920978698094723491089669/4132510899763835955061848877304138137) (num-test (+ -16810360766832230069/13652857552883800956 5011749175730438558/4169057419710079215) -184295743992738197672588473692806043/6324394120121667288243293659228081060) (num-test (+ 2234573531734039025/1128831476977636536 5842177084459535064/10255356071975483971) 29511180623959738330730559435115466579/11576568741659658592450950022331964456) (num-test (+ 2268894928233321367/45672733521488298991909987382109984899 -10510750087507287356/187832098427494353069556175466145198255) -53883392376116199828369509984040539934420061636271022459/8578805378260910951788610598591490227836321974082207035230408675959411151245) (num-test (+ 14273433611429514043/7774518083776389556784045601066955324 17247074371340283485/225579726714102822702316919752160926694) 1676942472465190408518249346164012571239098147062478293991/876886832336064155131767120243155911448808491410701588797601053820468509428) (num-test (+ -384768590020206817/26284423885474502132625533495652664626 -913687410374243983/254477371735734658619949996700223764026) -10160887225658731404416073535892287983824191154410167550/557399258996959835387173465565070652935481894323496556880024318994528462023) (num-test (+ -4465222504572200650/89674568206322981678158378582739708537 4148550863841320780/74302497820894496090312266744880513261) 2118016946376507498169590394563632549990739165791772590/350686547828419379316750498534703170285368675911953477374458878558215968903) (num-test (+ -4466938407638238142/281859125741189685767904931589784285893 7302241525893379697/204618108204962312932373858463395271264) 1144186926000295881841982161759159994442430111060328362933/57673481089466829503954266461746705742702466399988738560842837126631263478752) (num-test (+ 6692616266348342275/280491911593106290120490189988812804382 5414100524539959087/183579771905991028181574615911067652873) 2747240373316006570071525025488180559154305534334705425309/51492641151737853299832848099101317109893853469394209716061486746077629289486) (num-test (+ -2794289802081124319/15768464977850217600859580216291365931410230647587457388598921425875331529149 10869776169503285673/33805119742344157512165738805682358903614971418053290198565741206390317449856) 76938383491719886409504555688515759257937029058461512747558964579607347503639994773101488934213/533054846729186819415263583890627325668798847177803707144003483502948153457972377767011992167761176556555806720273883868208938866192358148729990609852544) (num-test (+ -253222140119290489/2123024034843473393742534167007121513293496410591072104903085284304117612082 17957334013642389787/32058972871090153103034645121513493401113378486125580864856088310966601405847) 30005809992231287609744177955201962181880644831204431411802631067134766877061419104162728517351/68061969937719269465960475690278941280799593161143759512261685488134507341176789799765185182008442410081522124548392827986923668912612728349293792643454) (num-test (+ -13318881947309618/3105936147298438543619802738126617974207009907186580731552500517452462642139 1850968757748704519/36469179946212878965111748233319050931475015876401494718861814560453153824935) 5263262069792987469108717688485565287648879759118200779949761992573778798556738644541735401311/113270944257273905484832818286307416845956086746130199501242465128236430928807948126409718436237517505516279133169796919230385184900609912160483959935965) (num-test (+ -9937822914683494298/36414156259035675966580098631253549474580108307284844243190992829476777586283 -13712605099585970325/17758145954890657915358548152198427387923366136638180213650029984340849686198) -675810254607579372158951115566887998278519717754376916387787672973408477396668549189167387350979/646647901672150721610792561233068038707362067627156669418022102308446036384411330678972562863413004325878365438890328206637571985169324874284800419222034) (num-test (+ 2479135971595944301/28169711053558469409458629766960029324030958129245230797895768033968717159836 3427244662960653095/28446538857424788738244844756675951434179713170118835630969510829753715142438) 83533664807147783700314944003289704497366290621039272787320536148072960487262393639109696219129/400665390043739792096386856839000624247597803909916773326187593475005945995926511155915226239317839405221783416485999405286913042389632370302962776360084) (num-test (+ 14865500635281371370/56222262470894935247131881777606182311286871927285650835673424014252462156319 6436092572090050725/19282524131572095520593158313261757267758159099923763177708581262473988426947) 648496060602737474174747620183913927791943082591316359990137585798909535115053578637078811588665/1084107132826611778585714784136700465449309125114745313342842325649687943726086785657821763235618936882528385000712567133180567926723616940173290425928093) (num-test (+ 340196811925805824067049620503247332111/14422464039094716975 51285507111580975533385007190438537498/3230944134273302873) 1838820276033673324738967436225477772648372110186756083453/46598175588880723338390245118389369175) (num-test (+ -210449319160504160992731982827917332322/5436857856220342451 251628249079137248539965770847855056283/4323109210037952829) 458271632943884346915405609513071881239303671882386130695/23504130271893362375786510953364243879) (num-test (+ -40984360445255688839942109197081457275/6593417935076565019 -138094174027187773198981391229349265879/7135512300754720691) -1202957011856131413678873259651070808566709454882536663726/47047414779755620074837011989046108129) (num-test (+ -289704472880230079383856507128133962457/10452740760651010288 -55251460678415911958671096669490155237/10333740726609314202) -1785630052601050832889834016432677758176770083879794496285/54007956451514283340719766211063255088) (num-test (+ 276702099951674677215621541062877777467/3899918017008359516 42623843937285717338660228144403811741/1973785812353331893) 712380176058162142132059442064597996057720566915757732387/7697602851312240113570356856612843788) (num-test (+ -323480614013303716597188084301661616596/12957985934572321773 -72966206939397711493108854138997499334/4539020357040680881) -2413780175334213399707013296172687953960842714316410700258/58816561943270580900205343368941122013) (num-test (+ 65443777543319569578713907336699651721/218804857459609839540825438673960136766 -61986861924091374470669233802827103921/65997977315012279293170493460332070399) -9243869541956614722377007489838492339200370508580665293676272508698701352807/14440678019033825487758061900150103876633207457375858942267120523885980189634) (num-test (+ 75417845823236070411341994633288547531/70553457686181702397810927701121800017 -7132208259849175775323757110664708879/24379326462014713478002790304943339422) 1335434330716260509518880689691257567128541829706203586134358870209350816139/1720045777955364955754847231620711706115121721983605654691934662747636370174) (num-test (+ -144692585186931942602350348772472248638/135233395864627580439431775527364081053 282512666765911374279543408363363928190/317835040256607665191397469890906044457) -7783226336195038987381961251409043080655184208289882004756343793157154115496/42981911818671667582796085276418080952868666330715445603855323471628969373221) (num-test (+ 44888992584766727877549626240272070725/30583318432547259097085073976959329092 8004917623696885952432014881247978821/22005016116109025986417835664774768346) 616299974987760892931461886440810919939264155149950328291076750435394215691/336493207496148335911511951044490614757807556827643881435283379298939260916) (num-test (+ 78378756441281199312006031491361997668/175125578595003447448566412156266355477 41128705932035853424044828385766740319/216359823601433445464965619660717081261) 24160702340946845080381231961736762955784254747832931999121777482667650876511/37890139292913914697800186893609983979783140570423836226844401085057321416497) (num-test (+ -36669293296367265584135816683983780855/7341750629088488427994322429098120058 -110335983484012479290765295565662258281/5944410911181873015545360879141666465) -1028036623331099574157832708037007047972965676333418398303213384036005227873/43642382546729990922161061763293407461832155878510163500678954788762454970) (num-test (+ 228535455883892721240720366651075744967/13353170075841095813026701300679754576855418298534901819672803635370738730013 50622643250826426975012800479360461693/18462345430382979738234695697296360785230118465695284267226773073149552698303) 4895273294635392498665165879164922265508724130843670837390305811645771221742112327485665544066552056189958877583010/246530838530831602270074647792752210668736478466245992891169449973883874207653264921203783108295835419855394180777469634862446033810927048792871560267939) (num-test (+ 11355068601761731966774720678777239425/4604724775053993730579400400679579947095967462408565975449642189823843820753 140083339434585694465706029861026468774/44667214322013486680993684507177513903616004462434123967566781106229226297333) 1152244506542792151980649054527153167035843960949499862764543674633978109831264344257976000890169981044543787620347/205680228421222079539939271800361418862113882206694593495620042859527547538342323521609420336002641308832164587573546802806916292021672743366881933951749) (num-test (+ -1347509007210283053816302848714698886/1127513773036247565111791991337919355855664936242166138889250311777351432819 -29464928273311615445392112247506626497/61933028109313748081628643142485450090725737246358993405254280723087421657760) -116677425670791909053501267317366054796703074907755330120413752187834449333299886015456661052906469074533366060403/69830342199092322009251417145364324484174202256910311362396720371574344280505889954115533896831727771442604285956749924105078563356474162416148250025440) (num-test (+ -324250487660721070279458563122233299722/81069650926979269606211148691445887485067008319429991878657612702576019034861 221744296343315457943731256980089803078/69422237643162665956763790134527973903052044485041686255401689654420090859107) -1511153903564243978242173323335554031611949546418082039382510246845821774680210236992700372319944685567533765722032/1876012190766999122356500320654631447623282613780323887424324139799202291067983209550065997185860196433399782230215269625922714982832188312141580824109709) (num-test (+ -5518324152042099343909980322067306333/114786626838714403445081775763480415805466836213320421844559660900880511042496 -34415425451618992284220085078832944671/96012285963709194218263616278916829663708037691620330613749177799086889040577) -121088040955051148243092870850103339772063863319219725752028251933576579890093496821887384992074112246777968211161/297862876779681729593084954525306275464788137269287692384941959703420459939692410434239827100068259769782676124741025632728203586961467995819025176090816) (num-test (+ -14763921690861243371082340598041267817/5580497386043551028888310256097864185640794395615400088682607872958152738111 -37917865546640067592937379176813765341/6460563866107795917092814416816176677900242086501650458839130903088333290440) -306983808565398982164654624310995401934900925070311336095043743767915008644459192438083753301097540174379867380331/36053159767181973313125557585868206969047484351694148822117591172786449966899079869470557965303954072842600790897257698854023751399649072014440219958840) (num-test (+ -50167218239107621378232529938205077788547946059832391744348095230748591585676/15685777859540025727 2959973815535345735348053015389999235839609978295604181643547897863515739931/7556072538495923601) -332637648328710384664787658442281566361265475773778265650094684540358159241317316408573560734439/118522875329417757148187346888166482927) (num-test (+ 36275100136090483878026478935942224245036692059657264537598788566553406654319/7192442039871568876 31833552596558882106090352174644817045294359487590746360517241517440556146007/5115621724114081523) 6795584791386081942310910570767193224876510928834120433155946649367201608618436115134135392229/603177258173744207443043238127434068) (num-test (+ 1518304705177739493483387141342904186483658277690975456045607777812450680478/1837349761252804045 -98159070764971437450169149833809835519268242923913777966502463698396945141091/17238232824535200528) -154179655228376218743158291724235398278770272999447263973992852061897564252670941977524115620711/31672662964580000612902147746364535760) (num-test (+ -16820231344048323866426670709751443650129113909724546927974450301780935205864/4879137683452153951 41987219452495799378686134495924115238909423831017150785452046648616005475639/10470103987572807938) 28751853386830083847297108941057082854166610198448421498169760256533906032780671559334244751257/51085078915429149801779227663330863038) (num-test (+ 106981694162678522688926793970551228214793665448093395251834862896418045995969/12359470989873920972 57736849967187961211538031441400807467468650239660040144967046985609433512403/9148121311784151716) 211534804819567028232303054650327703050869189253958355919997046592895748577556985792570078031065/14133242495605447754080611005730273494) (num-test (+ 32477400086615533920132766925666506741908300936974348739732763951610256880146/9045135183308696243 -27444990730472195954051975667481893116650518055101159075033425831129583042846/14815776448343565085) 232934248044934592851252865496377968609159820017147884670610366058217203617961573611006127074832/134010700820948737148715427669965475655) (num-test (+ -110053921687226074580746319073262192216481755737797790655164396095655530752161/255625377233605953547425802301922658850 104095037267817888539158192425982072195078148060302393917025130946535913363779/52156238014583575190277280296975732513) 20869334635774913818120011435677143948904421430726712952150525645851498022294865158343391008006649321440592131083557/13332458017563665620865770931104425383051282278510599570476131200251352190050) (num-test (+ -29732769078100192507326444863945498799317005912797369958801703828462203585495/153426302667449722633466432797809987061 36094569840376017510791155197897623093337784636438580042046806320700826250193/73286165979315961333009750429763545174) 3358855747298609357265422062476767573626163217619249414656940907348235709105513077913806378841119674678021275101643/11244025482879487592663298816607141776071841230792806495601092332558428993614) (num-test (+ -5942892427460131788264792587455286675871284855854073854440582948253436001319/42136930106315714728428443448730580823 4013357443728612356640061171485791666303136232331145404661874650095235381569/4039594279673425548586623641599574814) 48367895947790658831309709091377784501687363167039737892874371817395083020674648576881857510385191335175551957207/56738700606823969419119152217721454504573192499839513549171731025354063974) (num-test (+ 83833896550100013648317056712064289497247852876055488793078639582729685477353/188580876675619574786621140720273228537 -94310653397371924313725082402708514144086936359594289802762093989853507835016/223423274286761439988276492107364036191) 945257965914081840217765265999453398105151083284254483307155736205796420255026737575918161700355729594975143830831/42133356934734885127066999419230498520039134905254787577957770920054881982567) (num-test (+ -14753992026457621496269953958381833108089826525439816493815533773338622353285/187171041855711408638339193132645929319 41340837577662628944845446369855468662228665858415210386857356535970453143469/322471558852595372991189266479896691326) 993354944176102401496932276511264091214577507066786487301109889019709943488537161608732610457423116833164991120567/20119112546425211128699888199278894685207186285215928241217590790016852128998) (num-test (+ 1370528773439579327226257222995383030603284075640526658282329726447335048230/305600505683287165495713194488435114383 65450762047588146235054351616480175308174618406941901794570541085963681607527/78934496562987400429145916504112602768) 2234440886428442112499564751364146150136438855986167755259621093816030535881959724370423862435538502079424185584609/2680269118389404699570998335430047660909241475691839354273569734988880268016) (num-test (+ -76890617375308981455205142622328108690129081798840077873315966300000409208129/15716637731576156581128288257209679492686622162926707938907282962815471734862 38716252217351070567267262306332875768795464072349655597599997486613800623507/8966639693620677733207403249675415446338239705879120765911896990394928596139) -80961151400006413290662155450270992168701818633203071886556882897757813544592915596861717853520674107309124394292702460320442121704840951425284048212897/140925427734207212133604717335369986754855062343668899363006574618520848268718851310007161609443093589067206438198588881828988648068282656538084484897818) (num-test (+ -43290760758277846058307167265569849910514905939554272559141355223092464986939/39390771697068809730875092892395235497943839933482798653607450783947201796777 -34021960935937170163894986285771504067448629886312440795733904794894095253649/106500928228745564800818258673435811176493306775154643113582742982704678574998) -5950657500399238361998292872481533631424138885403498309639150240712482075115081624153513501886127772738596607451116548616099047843190357858736503567640395/4195153749384427435979718872073512266029328962522899010907363614544821318917440413166534226890289043064894115954085809567292470182917919104836361549181446) (num-test (+ 17906146982204022925114071077515882010955693727109005464426577098738402001871/11978213712662686419384559301746021856683603106261241838035626618416021524231 37108371752538653389309509075248119316034595087990649061240232817571629131708/23044877611981158676785639370406786635050056158699399001947422631523989139615) 857136973087880657664203854652754375000000796400911171478039451763440064550649429609696307332611304395324153178602635490321877797571177424460384122636213/276036469018466057777760709173569478463866562650149880633721199971933767458324034017734890892482223472007882939609440193626728031771767304374122564511065) (num-test (+ -77062185592993847534024832256462395143306675613123510837298699277378172890089/108133793614758275822883834459865239455798743725021300772336023406871185253111 11169356025540464491224577661206910726665825152149521753528516637690366838655/6369000033300801574913390611244042297918207179453133439308688067382050608197) 716975776667538986425481530620118513423964367153518065425241139444161780269039780459555836804116752462325735011822817367819625929553250251515977390346172/688704135133337463423649074673019029541747166391680122270752018123634233590688096940261480888455237095078029621363428114402137147558304641222314936350867) (num-test (+ 13583698920327742567560325715281067532806062839142769830536738488850089822247/37364394142255392010559408553278838878570049727027927213977555360874308098434 89809462356450792524214360688853318641058652796345720882094866396911421360072/67457610947238032712889230619376608100793287037427539672885124981055281513463) 4272000026182362299819817378001862956001381379478285995446709640464951377212652125169846305230835604666564953883168949950485767679005929254184987140738609/2520512763327523955464432226120154092742373168521113224665257966793820057379494860454732800329019773731110452438496395974166220481124541266348389100216942) (num-test (+ -56124163112538495128545947597589743957824668875494126834084658670528264380488/4752969512023182700122983723156599300062332404522277372984645779569746369511 -24794747728228571193100294011820993825205231022194400752319729320185378063197/98168688073468429337427023004226732413974455700654808087001957859427678524065) -5627484141989830997868845457242226973925524393512774885292323552602180052845805156311097870316601631410500655735815037997645271136502511615781690896430387/466592781448509275992390948177487068548424631274164031114910250651063315574511979617153568070687706304645818907382693929886654490427484894987856595782215) (num-test (+ 17009115185923538769.0 -12047631083067675031.0) 4961484102855863738.0) (num-test (+ 12677011568664239747.0 3269056182420253574.0) 15946067751084493321.0) (num-test (+ 9315504781982082433.0 13857624532376678678.0) 23173129314358761111.0) (num-test (+ 15226508728194069537.0 11481952022080775416.0) 26708460750274844953.0) (num-test (+ 7461641943684774743.0 12249026721402718630.0) 19710668665087493373.0) (num-test (+ 1180469445886971055.0 -3208456171287181032.0) -2027986725400209977.0) (num-test (+ 18358552990465743315.0 221529797579218180385160273426219343697.0) 221529797579218180403518826416685087012.0) (num-test (+ -14819874956616484359.0 30498815629431206969122152847973230849.0) 30498815629431206954302277891356746490.0) (num-test (+ -11781881800334342169.0 112219460388643619332860331282276228017.0) 112219460388643619321078449481941885848.0) (num-test (+ 3570694277032201957.0 284821691832196381859344006870088122712.0) 284821691832196381862914701147120324669.0) (num-test (+ -17005463295060938595.0 69162171850264911722979835561124066203.0) 69162171850264911705974372266063127608.0) (num-test (+ 15647113311796203488.0 150750467185419235519670165664526735459.0) 150750467185419235535317278976322938947.0) (num-test (+ -14330150541101371097.0 -13054027994001826312503071338715966858478218093171762021549815587520723118772963817341751396703629529810372702877555022105594068768886421335353882155416908.0) -13054027994001826312503071338715966858478218093171762021549815587520723118772963817341751396703629529810372702877555022105594068768886435665504423256788005.0) (num-test (+ 7406427184711759740.0 -4059250217961011548005203450962458026528281798230141192186669580689721046971433745892994467792118611646113962840750314719233572760336084100766391093756252.0) -4059250217961011548005203450962458026528281798230141192186669580689721046971433745892994467792118611646113962840750314719233572760336076694339206381996512.0) (num-test (+ 8819522415901031498.0 7274905269237471130619913887005155660991437201841760414347836177003483932007334374478344594178179032728521106519295465031750530183363793325150672647162846.0) 7274905269237471130619913887005155660991437201841760414347836177003483932007334374478344594178179032728521106519295465031750530183363802144673088548194344.0) (num-test (+ -7242932332215698200.0 -10558564312909325527488520195600871241245891651644550509993750377630234801225525279855157008009255586978047154906058790342845859331159009687703010657137320.0) -10558564312909325527488520195600871241245891651644550509993750377630234801225525279855157008009255586978047154906058790342845859331159016930635342872835520.0) (num-test (+ 9794320575955609492.0 13380937715397052566925484435342184213544885758759259410983243841206628594840271850190097746775475837233042430565529099681550277688470325394342993771343357.0) 13380937715397052566925484435342184213544885758759259410983243841206628594840271850190097746775475837233042430565529099681550277688470335188663569726952849.0) (num-test (+ -18404048401680891243.0 6690884608978704096379677348142836785900717005050936986370615083929607190833180925295418079551348559691161519822750772440155040888224482801864925665484770.0) 6690884608978704096379677348142836785900717005050936986370615083929607190833180925295418079551348559691161519822750772440155040888224464397816523984593527.0) (num-test (+ -10763220363947284865.0 -30985722824355332972176356513316569304601382411274079243859710673739383446566598659878378034375348869471278415635671865753349734809209959160389615096293457362383744562507969316522225741589739150453090393424063226271167062127000223628785686999799282795143706407082119829140399988180879618548495395684946331608899565543458192773899200054228140747414544792128323269250618482622488195333106891323515989863192944848391405358725993695671970811097285270641251816244586360288952156538400321933146150313939864593445583603568771077260174826348411367609521412133720180359748539721570562669201065857989876521301209899829037444385.0) -30985722824355332972176356513316569304601382411274079243859710673739383446566598659878378034375348869471278415635671865753349734809209959160389615096293457362383744562507969316522225741589739150453090393424063226271167062127000223628785686999799282795143706407082119829140399988180879618548495395684946331608899565543458192773899200054228140747414544792128323269250618482622488195333106891323515989863192944848391405358725993695671970811097285270641251816244586360288952156538400321933146150313939864593445583603568771077260174826348411367609521412133720180359748539721570562669201065857989876521311973120192984729250.0) (num-test (+ -12742462236537568498.0 8711131313747826394504271797986775572294949693272674156076339989631171694968899228610359983845552623710580616605402899155485071497929100432998183040757832449369366844015907530612334721882095163137705867337969942902346066961718232788529860214990099385213558935023241940238638069647809530490438245386869385682221280939688108487754251075630026707075310465788398213293782900699868609660892232563106662995330591906155134237356516622436517046191466823447743155250482328613449506396571170001248589926831956459700467126756876526930443317428628239358666456771112897986098390410773312792390699312960051747534683311506465130527.0) 8711131313747826394504271797986775572294949693272674156076339989631171694968899228610359983845552623710580616605402899155485071497929100432998183040757832449369366844015907530612334721882095163137705867337969942902346066961718232788529860214990099385213558935023241940238638069647809530490438245386869385682221280939688108487754251075630026707075310465788398213293782900699868609660892232563106662995330591906155134237356516622436517046191466823447743155250482328613449506396571170001248589926831956459700467126756876526930443317428628239358666456771112897986098390410773312792390699312960051747521940849269927562029.0) (num-test (+ 9991390529516174614.0 7879872958436992955898278403297937595295396115022400543178444946646147916754852888072481665174663073269556311758611700754643170639645548596647557683044355930340624784190093631808382820554407595007761070026239341594197877214157118335743842022627898879376346092898666610367809537340994845045475091410516226225078052019727419030585524815982151736622865401299588936172760762386183577504972623377661437665668080131418564228642443266935225613702941906491478788336262289516199380144218708241406077806669686589734333554945412904560108150202389909124657090061223183441083590340175629756198442568877659538345749595968764873879.0) 7879872958436992955898278403297937595295396115022400543178444946646147916754852888072481665174663073269556311758611700754643170639645548596647557683044355930340624784190093631808382820554407595007761070026239341594197877214157118335743842022627898879376346092898666610367809537340994845045475091410516226225078052019727419030585524815982151736622865401299588936172760762386183577504972623377661437665668080131418564228642443266935225613702941906491478788336262289516199380144218708241406077806669686589734333554945412904560108150202389909124657090061223183441083590340175629756198442568877659538355740986498281048493.0) (num-test (+ 831234034418847630.0 -744676478858160349467117341859049692149463503380690495147216354303526704924280287782902146026018180364963325847811379182950159627878800024734206345960410146056000392683000433501805629464626281031086102425271022388473812300724085127447081771317912465921636737545371909901577246384446144919253141375367648958387948463576516115079816552636772639965957498569187848459747361493535081532845254971492261148968198806736512864867151355002902241562014241077734122599581732704243705918200179789271894804233542502502119523149682814025979598424744685548054183678652651244898867735764030968089217841214778606507809487462642341164.0) -744676478858160349467117341859049692149463503380690495147216354303526704924280287782902146026018180364963325847811379182950159627878800024734206345960410146056000392683000433501805629464626281031086102425271022388473812300724085127447081771317912465921636737545371909901577246384446144919253141375367648958387948463576516115079816552636772639965957498569187848459747361493535081532845254971492261148968198806736512864867151355002902241562014241077734122599581732704243705918200179789271894804233542502502119523149682814025979598424744685548054183678652651244898867735764030968089217841214778606506978253428223493534.0) (num-test (+ -6996572501442843347.0 -16567158719848992553565776505785820491834685475229611199353714982570065913508303466008005931649515528390057456882757990896824841386431756898386429000065518724021230756426613661219891419166146764347562529640689229693578574350948436847247856000438153789455857903402883189892697143647998643667467614427922009931545254965075041050860609824086811877108940020349157317276288348430058535959434983921323332907180869396258655826781438419383792024592535415693101119109484610789291889841197827977530804650015884500878613240443324806805475203272442094530735476095374446946252236490708915034012846683015547314889561060687692538144.0) -16567158719848992553565776505785820491834685475229611199353714982570065913508303466008005931649515528390057456882757990896824841386431756898386429000065518724021230756426613661219891419166146764347562529640689229693578574350948436847247856000438153789455857903402883189892697143647998643667467614427922009931545254965075041050860609824086811877108940020349157317276288348430058535959434983921323332907180869396258655826781438419383792024592535415693101119109484610789291889841197827977530804650015884500878613240443324806805475203272442094530735476095374446946252236490708915034012846683015547314896557633189135381491.0) (num-test (+ -8920936222630165483.0 -18738991973681679876688842391791783563249057933653045519186959571392922172943405646958686202208790537612746921398028331540617848217445632123805070077600768524509025758950743971128222843292926773668584735575066246660802064630842300367821042873152766467703905048558085377302000898639290554395913805527529259855535801856020623830262396582180677933562523957295341539162448074423901242873918231922121053192425691524797238343327318801359521456598967984637483081312932069399045363737622797213185099130529375169698811801965974416555301085043300426947769193582129151016159057101028336667142913854943018973494705119572045938607.0) -18738991973681679876688842391791783563249057933653045519186959571392922172943405646958686202208790537612746921398028331540617848217445632123805070077600768524509025758950743971128222843292926773668584735575066246660802064630842300367821042873152766467703905048558085377302000898639290554395913805527529259855535801856020623830262396582180677933562523957295341539162448074423901242873918231922121053192425691524797238343327318801359521456598967984637483081312932069399045363737622797213185099130529375169698811801965974416555301085043300426947769193582129151016159057101028336667142913854943018973503626055794676104090.0) (num-test (+ -243510292488206214847646757340020705642.0 5940577100149745132.0) -243510292488206214841706180239870960510.0) (num-test (+ 35446324064743728955945058978206455057.0 -6248622708755929572.0) 35446324064743728949696436269450525485.0) (num-test (+ -285342226760657637664173494795024413673.0 -11942737781617905307.0) -285342226760657637676116232576642318980.0) (num-test (+ 180790435817422032042321866247362452865.0 12401641959336396832.0) 180790435817422032054723508206698849697.0) (num-test (+ -179994871947239535956826388240542999950.0 13573822506399140772.0) -179994871947239535943252565734143859178.0) (num-test (+ -308198027295905163635866438671452347268.0 -8790069282378476990.0) -308198027295905163644656507953830824258.0) (num-test (+ -139324757925833055762410227358605285566.0 -190622873846936719063564661032771271922.0) -329947631772769774825974888391376557488.0) (num-test (+ 332866352618304570046318203427223999347.0 147978646177673305481282943528696833018.0) 480844998795977875527601146955920832365.0) (num-test (+ -39471620476300923970352914034802271156.0 28992893610776120142668950821916856486.0) -10478726865524803827683963212885414670.0) (num-test (+ 274120253734611965146455315763505869288.0 254675910805265090692978775702306142625.0) 528796164539877055839434091465812011913.0) (num-test (+ -122086811464559635596206661886176775901.0 287312583034687582188356355813963609701.0) 165225771570127946592149693927786833800.0) (num-test (+ 288576174771266329955482943556556984728.0 -57843540651903655425270706396868707777.0) 230732634119362674530212237159688276951.0) (num-test (+ -47977736580820486006305788441965482221.0 984809271313988066640898939725532304075331399066274624928410251834520283291912387208948664716457549646483445981126881113426109906085249657168046936670489.0) 984809271313988066640898939725532304075331399066274624928410251834520283291912387208948664716457549646483445981126833135689529085599243351379604971188268.0) (num-test (+ 21225484205143479814642328762121362291.0 11839789093732539327981861490012713257538550745921177905266671749716203131127256902110452504526721633943016923389974867770082516862899595554460170417713940.0) 11839789093732539327981861490012713257538550745921177905266671749716203131127256902110452504526721633943016923389974888995566722006379410196788932539076231.0) (num-test (+ -193095363331703875886398909106293703000.0 4389392021031719669078675478621418677903292147307684123866099084349756491860737402449105804868232530632178577388168068485304437343508442251302846768269976.0) 4389392021031719669078675478621418677903292147307684123866099084349756491860737402449105804868232530632178577388167875389941105639632555852393740474566976.0) (num-test (+ -14827657635864183514988182371035598180.0 -7256545787852407071411458891023580461638051949278710509801472046178301830006724297747051044450550248499056073213660185258676369175307019300952192657194576.0) -7256545787852407071411458891023580461638051949278710509801472046178301830006724297747051044450550248499056073213660200086334005039490534289134563692792756.0) (num-test (+ 54301423175725658626298504084995819705.0 -13385853291610595576947504757201441006088030688464261540642594993520424631577281077984278942244446266776534612440941312995898184903431893212829646845766101.0) -13385853291610595576947504757201441006088030688464261540642594993520424631577281077984278942244446266776534612440941258694475009177773266914325561849946396.0) (num-test (+ 195114404067053480147948948510253723990.0 -8373866462448797623435948949281383906369538962237624940506813188612614128993186653340202956656303504523161255703176374041758276069255591562198514767063594.0) -8373866462448797623435948949281383906369538962237624940506813188612614128993186653340202956656303504523161255703176178927354209015775443613250004513339604.0) (num-test (+ -308030589512186791277525017840002670741.0 -11922204352024596469278978325035646517433105521287613403902396944414655739824695945028308092245747333098422116078042326104667969967224788442970266049942774583538734406057081597034454910987815490244451193242377705191422489528853976486607580169986057592557285271953385769215318545520155212402919465580052078255078759756709086185424029620805084776442744700501748376290562843380642608395240491162047933014854466267084965223593172702334466729933986413870670083326499598274393380692146118979961818816348097032083332695128587696590646086980241100792624502607816103195636761141133903550454815591457829485684936036414823492160.0) -11922204352024596469278978325035646517433105521287613403902396944414655739824695945028308092245747333098422116078042326104667969967224788442970266049942774583538734406057081597034454910987815490244451193242377705191422489528853976486607580169986057592557285271953385769215318545520155212402919465580052078255078759756709086185424029620805084776442744700501748376290562843380642608395240491162047933014854466267084965223593172702334466729933986413870670083326499598274393380692146118979961818816348097032083332695128587696590646086980241100792624502607816103195636761141133903550762846180970016276962461054254826162901.0) (num-test (+ -172649878347923210775992373331623646864.0 22180935775581457002090790736532281654456312526625354262953960635330604551829750571440878712430708012807252279301365732385899228826740712544768476577874129759972563823209525283326887563301081200476495752033290851190327066070873711444930389093339915885090143783170994309089448293499799071372787520776773788274677288230540162485916160484352398851925328125588729604931589867889917097887951581817207079060016091919559509735997493084833476849835444339835031436580214492450731100723026312163752403946315983551266206214298679421644737804098691991631489261658890937663698502561036246447760919715595005106669653475931803053499.0) 22180935775581457002090790736532281654456312526625354262953960635330604551829750571440878712430708012807252279301365732385899228826740712544768476577874129759972563823209525283326887563301081200476495752033290851190327066070873711444930389093339915885090143783170994309089448293499799071372787520776773788274677288230540162485916160484352398851925328125588729604931589867889917097887951581817207079060016091919559509735997493084833476849835444339835031436580214492450731100723026312163752403946315983551266206214298679421644737804098691991631489261658890937663698502561036246447588269837247081895893661102600179406635.0) (num-test (+ 17539006966816771902104329685391462527.0 15609797782337099611892065465036826453911053690739041627254619195700021040383385710184052653282070244915503750549545390475671883312314708978681904377133928647935359080875691628246716591529028104762422990155477702994042953196747769893182153631482194578269859879402160062955490194674372351117284129320011166238130774752386987036267064693133554447596069886693581191241594745541512444806003236372840085705813835001957163976961730871756250344335996073970142337882238844723800849054637237549515249957267772181010402413375667537558243971058326641257721901094391380667244006959028327507917720426571969997513984360849930719808.0) 15609797782337099611892065465036826453911053690739041627254619195700021040383385710184052653282070244915503750549545390475671883312314708978681904377133928647935359080875691628246716591529028104762422990155477702994042953196747769893182153631482194578269859879402160062955490194674372351117284129320011166238130774752386987036267064693133554447596069886693581191241594745541512444806003236372840085705813835001957163976961730871756250344335996073970142337882238844723800849054637237549515249957267772181010402413375667537558243971058326641257721901094391380667244006959028327507935259433538786769416088690535322182335.0) (num-test (+ 244901855797156286376563377540855746602.0 -22138106346578776369849317622304392466030036563754663379976505966920461958652141160336156065177498990718609170201272980114106671808245437660234479124938853665375934080221740523696180221118540569603989748587853373569525751680828044059607889572522502629277877343410298879764820905044284757389006201848194571453112545228115550224254565141563427486518108434758694923122284117299374156393942906293546318323661938734959824887786185558612820887463537294120950912969343488704744978847504513710882720654330147775174336365363311173472002077960424794151168301281665765411704505095008907760396535767621855642720080219960822554492.0) -22138106346578776369849317622304392466030036563754663379976505966920461958652141160336156065177498990718609170201272980114106671808245437660234479124938853665375934080221740523696180221118540569603989748587853373569525751680828044059607889572522502629277877343410298879764820905044284757389006201848194571453112545228115550224254565141563427486518108434758694923122284117299374156393942906293546318323661938734959824887786185558612820887463537294120950912969343488704744978847504513710882720654330147775174336365363311173472002077960424794151168301281665765411704505095008907760151633911824699356343516842419966807890.0) (num-test (+ -119403662992279138748600939857239307122.0 26272999248235953724172008428088697264933069743507017434844709711501131900922919455931092196539942532993887162365511473221418376205773427597933886270411672062672089518774390132453916538404354895529975888201032175628249480896964400801763570333497287321002961557096975786141940970260074557095118887294558700145949117395512768347250531196100831164663613049206690894640391431616112104502483838173255614981302462548882276825096564828583591963617871547373532874400764134244496979962241959713525053686209002866840900623246072884125102845824992994967009109046451949348656842486048332953732384499190437432898387573320391878853.0) 26272999248235953724172008428088697264933069743507017434844709711501131900922919455931092196539942532993887162365511473221418376205773427597933886270411672062672089518774390132453916538404354895529975888201032175628249480896964400801763570333497287321002961557096975786141940970260074557095118887294558700145949117395512768347250531196100831164663613049206690894640391431616112104502483838173255614981302462548882276825096564828583591963617871547373532874400764134244496979962241959713525053686209002866840900623246072884125102845824992994967009109046451949348656842486048332953612980836198158294149786633463152571731.0) (num-test (+ 313963939617834410089002930298454269912.0 23286645405607099799151331553995799851855144387826191186590140820016670502830395945076644578998873585162998873396623634135231418574284200209367505115739462344028303923666952261030907434438322884189133236837089851688275865098623902644385995630973049587854251981548128145516004461191094062488421288607625783540996659060285661398859383778209495884203323937672739376151794507745282074538961033778823733980759695886879886017489555795079194346438911010371103435094677167286870898482214310646392174423422237727456012197253183422715313378603607058548706460095379882633958651034759773864354021315490712575535559549015858088608.0) 23286645405607099799151331553995799851855144387826191186590140820016670502830395945076644578998873585162998873396623634135231418574284200209367505115739462344028303923666952261030907434438322884189133236837089851688275865098623902644385995630973049587854251981548128145516004461191094062488421288607625783540996659060285661398859383778209495884203323937672739376151794507745282074538961033778823733980759695886879886017489555795079194346438911010371103435094677167286870898482214310646392174423422237727456012197253183422715313378603607058548706460095379882633958651034759773864667985255108546985624562479314312358520.0) (num-test (+ 2000877973959266893810594143560134441447453310844726478119781029700338468704683515329516333146806175216349912753585564808803731447160643580198590073658869.0 -17993015014355471903.0) 2000877973959266893810594143560134441447453310844726478119781029700338468704683515329516333146806175216349912753585564808803731447160625587183575718186966.0) (num-test (+ 5492930533666246223206322654398877802091439062008700770880939594548305919677404080859141226095489505872709347538974725998600861651942609010590873980143878.0 15372278140141207703.0) 5492930533666246223206322654398877802091439062008700770880939594548305919677404080859141226095489505872709347538974725998600861651942624382869014121351581.0) (num-test (+ -13405500833215428652808705089190188280715732437731292502890523313631564795139560159124390691283401484515088713758307366404145018349044148223082253439210893.0 -14793401891248640808.0) -13405500833215428652808705089190188280715732437731292502890523313631564795139560159124390691283401484515088713758307366404145018349044163016484144687851701.0) (num-test (+ 9945195259699924701593703207751086973468898794114625092150620088406276196469184233537941913755508476427888065765634203723512911676149274871082481174186606.0 8699133332160461067.0) 9945195259699924701593703207751086973468898794114625092150620088406276196469184233537941913755508476427888065765634203723512911676149283570215813334647673.0) (num-test (+ -1785165974800693006461065312083337532938610906605533088558498259067461510781028452552786542598361030690629530721209490413999022804146471920873844686294838.0 -13079925952361275418.0) -1785165974800693006461065312083337532938610906605533088558498259067461510781028452552786542598361030690629530721209490413999022804146485000799797047570256.0) (num-test (+ -4861207515430071951958387366611380234482792653010151054346367776006873932152600469133110239669746470475230906073865131648496652783311445471793936775767736.0 -9381557743227419896.0) -4861207515430071951958387366611380234482792653010151054346367776006873932152600469133110239669746470475230906073865131648496652783311454853351680003187632.0) (num-test (+ -6638723469626495957966112633999375479181736600737250559572415894485618850919815869703127084789143821420728194272094956858541960962483734293877093635361160.0 277811698220276334443479876776376776138.0) -6638723469626495957966112633999375479181736600737250559572415894485618850919815869703127084789143821420728194272094679046843740686149290814000317258585022.0) (num-test (+ 1983880417172931934469534542170437296262471214582817006917470485544552211448284732460451903536334682269123998240709059499894818265755197559390728940140016.0 -118940994129137705779355371753506018694.0) 1983880417172931934469534542170437296262471214582817006917470485544552211448284732460451903536334682269123998240708940558900689128049418204018975434121322.0) (num-test (+ -9354509264984586574958285335910611806441061705184818350015454221731287473282231343722010109181841005578131927454778025302197744540571159656556971614966757.0 120224841184491944160266976391113485817.0) -9354509264984586574958285335910611806441061705184818350015454221731287473282231343722010109181841005578131927454777905077356560048626999389580580501480940.0) (num-test (+ 4389359421234641412950681847970318834150108533025088077429496538447029921663033978550089607257809597829358374972237448178553189381274150213236222139873594.0 106674783386899772113212633712093787897.0) 4389359421234641412950681847970318834150108533025088077429496538447029921663033978550089607257809597829358374972237554853336576281046263425869934233661491.0) (num-test (+ -9319417879153488839579936799737117639058244394679644240663244688680826325564084529474537634510092069422987165268448907193562300482925125162731530249763801.0 192969103435503875767216559494769734726.0) -9319417879153488839579936799737117639058244394679644240663244688680826325564084529474537634510092069422987165268448714224458864979049357946172035480029075.0) (num-test (+ 1394404616168163951844558734723678125985464491792846741433683801962971891047718103736551854371207400145441134823994228143957746922511631911996296931168332.0 -211230038021470285136061932161632203274.0) 1394404616168163951844558734723678125985464491792846741433683801962971891047718103736551854371207400145441134823994016913919725452226495850064135298965058.0) (num-test (+ -2935941510094051560788359387128767361559188973149773593522440619832472030019457317998381634585179453958737810428870232715146002408187749944694186205812791.0 -1221176156661231926164756142840452419679061324806989304452215660535991083923207702827717652226257158321829748247784282139952864899457896871473184473608543.0) -4157117666755283486953115529969219781238250297956762897974656280368463113942665020826099286811436612280567558676654514855098867307645646816167370679421334.0) (num-test (+ -1338674579024795395027232680327531457830908239605718353094975139226848400289367913459076082700361212506196070727982446232782659114647371030398516119682505.0 -1298372177520411182435886041880377054374169787570856408996533471838082317927648953576721017727347029007573543972764860712708420553928791798580799809858729.0) -2637046756545206577463118722207908512205078027176574762091508611064930718217016867035797100427708241513769614700747306945491079668576162828979315929541234.0) (num-test (+ -2072456075229532951804023218627137969798924912365258263779029006567941400203608770518731715660383378937120213112973528605594220795605977413985543331908189.0 -9744489461776287963808523409593616918248399004543154581056479712028497082820841423941781438667661074968238703192056877665754560746003512076830245760254982.0) -11816945537005820915612546628220754888047323916908412844835508718596438483024450194460513154328044453905358916305030406271348781541609489490815789092163171.0) (num-test (+ -2570682164188734368809161664810917340861573482754788446510182252413437925852206735928397938304353826925422441004271229738766803460790995673395984247950088.0 656920705293329551826685120408221577679101260931105312141757138825917579070505267306626244216341686712802796891966598838285570807961966448181138356047523.0) -1913761458895404816982476544402695763182472221823683134368425113587520346781701468621771694088012140212619644112304630900481232652829029225214845891902565.0) (num-test (+ 7846359203342053693101523606887617345982401999003795257520576318451663998927274759872692123323796450295314377046602880394071105863527900699633560551732837.0 3683380639347829102597675045842249667669675715600522157867595962635108482512780509393310714588544837398923613138772339053021025559943198965234376657126821.0) 11529739842689882795699198652729867013652077714604317415388172281086772481440055269266002837912341287694237990185375219447092131423471099664867937208859658.0) (num-test (+ -11692323148567132684205145901751681947225824260005631214936266006610207543813382900867093989444659986091234552140689684476541703112098935301322850961583953.0 -8534276689564199122569555420819240948691777228327984555753862457592427992599992931175844172478864477440165366128106812103785256271256853749622592560655914.0) -20226599838131331806774701322570922895917601488333615770690128464202635536413375832042938161923524463531399918268796496580326959383355789050945443522239867.0) (num-test (+ -10734754884168724884333968138739681643742524619139397687680049322697740991391014196697040576174049452737571835233123127815762146577096625434481167057340772.0 17059878151450238567815178684522345445687980385106446646013863901583786249398194029757376950491550197185231926262467028755342392379269039238766592672298850588065335172902157386017520689203005559576263548017475991638498600879259882041932152385436968424098224966518534467302264172016376096778201462205990822825056602379115848799619564610033123837036507127427054121975400703490855123544706355545059512146550901507159940126280812512339749605195422987937677650572797378799103456094203126081464905326203083057134061673694975250599375795827437561275156235513192978645909947341297774926450637694325145427434486258223666250272.0) 17059878151450238567815178684522345445687980385106446646013863901583786249398194029757376950491550197185231926262467028755342392379269039238766592672298850588065335172902157386017520689203005559576263548017475991638498600879259882041932152385436968424098224966518534467302264172016376096778201462205990822825056602379115848799619564610033123837036507127427054121975400703490855123544706355545059512146550901507159940126280812512339749605195422987937677650572797368064348571925478241747496766586521439314609442534297287570550053098086446170260959538472616804596457209769462541803322821932178568330809051777056608909500.0) (num-test (+ 1982582032974021971225071139786536402936929744496433027195224299475980201425925452469321205602618940472354066218156609448199804973454183972974358405933935.0 -5591374624026484498020036332218412149978824230210339582240360391202660977358546150723165491729699122647688030937226316069237264083850854032732663284717882873051337566653841254365703461654061656817936193716386141166210237666314879751427421825450110467888973152907618520704486700443275358649289847595635931220181024199692771066498714511145489237541761266539978351840438236927937894376002981658065431416811632941197501676956304254109064936038146674412392128883565757325842468006824235119684861972224857533964558963441079998949499582965764591461900562931342373507763081479989957632695010603500633322408246084430203281475.0) -5591374624026484498020036332218412149978824230210339582240360391202660977358546150723165491729699122647688030937226316069237264083850854032732663284717882873051337566653841254365703461654061656817936193716386141166210237666314879751427421825450110467888973152907618520704486700443275358649289847595635931220181024199692771066498714511145489237541761266539978351840438236927937894376002981658065431416811632941197501676956304254109064936038146674412392128883565755343260435032802263894613722185688454597034814467008052803725200106985563165536448093610136770888822609125923739476085562403695659868224273110071797347540.0) (num-test (+ 11532228364136654310006206557545352284448588590560137249197311142901246089838098630841794341370689745410654263817911440601934362503092628725755210859171724.0 -25776236925500995542036591604259749301547568770017466769502569415611770276300787105037848049555500555975152877716727294374436703766730618054071617947449695177320842403963009384468257891933593584757723535299746543328292715942626303315235241470269740287031317322772461137186093930239744879822272349431389779234805703118929710210161489122272898252221025966631463842234537744822906696719691188223105175714602909117904182229960075276443648211003011686250829474364425483901920822837775032295913486152631638908227467242772081310515646217115760180349854601959031626524004201825198439309850266508687796415478396821644422350208.0) -25776236925500995542036591604259749301547568770017466769502569415611770276300787105037848049555500555975152877716727294374436703766730618054071617947449695177320842403963009384468257891933593584757723535299746543328292715942626303315235241470269740287031317322772461137186093930239744879822272349431389779234805703118929710210161489122272898252221025966631463842234537744822906696719691188223105175714602909117904182229960075276443648211003011686250829474364425472369692458701120722289706928607279354459638876682634832113204503315869670342251223760164690255834258791170934621398409664574325293322849671066433563178484.0) (num-test (+ -2603756427337798371354526130541868239006085657393372011847827118826669474695402075575479286172808099892726251004549675772420422527946534088483901153485670.0 -10844269742362409682236511127219508926736627172993604953084481596070757241623728297275447608738915355190715664012379562650777199088096670239050254578284071100042116609747208178716191571268815994455064584659920497876052406993834873124981417288518101426395560764186717660091472734401090302285129741058888303693710456902635092811413971399734306158050053239768185860958896447298052082493590498954512083131068867270078638929796561440903919430094619437872896595720463663570751134804664228918188923926951933302878771189484614604311920655871182974081898031051411394311700207305532216445616083858025977851570522763537300875989.0) -10844269742362409682236511127219508926736627172993604953084481596070757241623728297275447608738915355190715664012379562650777199088096670239050254578284071100042116609747208178716191571268815994455064584659920497876052406993834873124981417288518101426395560764186717660091472734401090302285129741058888303693710456902635092811413971399734306158050053239768185860958896447298052082493590498954512083131068867270078638929796561440903919430094619437872896595720463666174507562142462600272715054468820172308964428582856626452139039482540657669483973606530697567119800100031783220995291856278448505798104611247438454361659.0) (num-test (+ -5929887196386997518766568868806997104240129372360669348628384183712406620199102166145939206783172815805659513128544493795329100599632286529420772709366102.0 24544958491142793859949310604465694574872439331169358241746200808802938771527900616394258199996170862256988647191747967628756772368808644819831481350919782560499270148419601775750932556119448001824346026042068416905254113155445053931789404515589532235225580737103411251232560863878948880220469490014568323308965914171394449781093816607870593225534700167342589927524232815571862258490314644577819742372918446373756857848586825568514909823940075182825283229026250682015641747568282510036326125505522447591703308661608718100933027549520132308555240654655887041040427813131621391320267698106519650611462269033902177180035.0) 24544958491142793859949310604465694574872439331169358241746200808802938771527900616394258199996170862256988647191747967628756772368808644819831481350919782560499270148419601775750932556119448001824346026042068416905254113155445053931789404515589532235225580737103411251232560863878948880220469490014568323308965914171394449781093816607870593225534700167342589927524232815571862258490314644577819742372918446373756857848586825568514909823940075182825283229026250676085754551181284991269757256698525343351573936300939369472548843837113512109453074508716680257867612007472108262775773902777419050979175739613129467813933.0) (num-test (+ -8848084327536592532063677611386811805244460767433749071435930786126721080365289638381557872263825830664387392539638767251180242665642373539064690745095464.0 -15917950175678012281826361248776190984758236997789474333609547749168308439513527143790323694526378056113636462939674273462177686456811495629631337058042159570336251822399402513133598701991665209363955263097315081570618652783181494594400709239428597117944511110842795526862595552977665064029517628515465251448116061875878430407784298951946811321795808932206846491091803276390661869369638950672478828532423383951689632136029256108992610781912267083149156104328033893238864631158195280554850035949666897861529711006187241710164902350100555999894332438423857208747342184052953230247487231455921360593096823760117493579248.0) -15917950175678012281826361248776190984758236997789474333609547749168308439513527143790323694526378056113636462939674273462177686456811495629631337058042159570336251822399402513133598701991665209363955263097315081570618652783181494594400709239428597117944511110842795526862595552977665064029517628515465251448116061875878430407784298951946811321795808932206846491091803276390661869369638950672478828532423383951689632136029256108992610781912267083149156104328033902086948958694787812618527647336478703105990478439936313146095688476821636365183970819981729472573172848440345769886254482636164026235470362824808238674712.0) (num-test (+ -16314775600714318471451792035636584056297958597339492996728118376578145765736873313518831390349547274517050864260054903974054712997529177834428786007341762649083404743713562157667828894017440065599882523458121037421757904691003094608420565550031561905074671735751685371533975894842331113347413787808917193134135744321547478500861021485075363990553639161661734684228250909589741380076008551020384304303171431833670236949934603973673998262066558668396388979463892768199916011368116729432353268535563246463324517035331079693172060671712718486388759443825620676228470068291448236914050793177812037679396721657020438979754.0 12553426083939460917.0) -16314775600714318471451792035636584056297958597339492996728118376578145765736873313518831390349547274517050864260054903974054712997529177834428786007341762649083404743713562157667828894017440065599882523458121037421757904691003094608420565550031561905074671735751685371533975894842331113347413787808917193134135744321547478500861021485075363990553639161661734684228250909589741380076008551020384304303171431833670236949934603973673998262066558668396388979463892768199916011368116729432353268535563246463324517035331079693172060671712718486388759443825620676228470068291448236914050793177812037679384168230936499518837.0) (num-test (+ 20637030084881771176788188367974505419050866216433677435050410899110162793040751338330447574748263391136356400036001988938659722098883893353523409458775455519257672423829361150611806294256710309281788819450225670112435352092313483086404714074567539245791066202051788986426960935796927738180831688497683293306590464598379493141645539253898709000874685535467854788184424886911457134522632486730390913239660179785071885982403741669161655812015114272497907946919026898579927936299607156006210124954460880383605958519412435713868501997649784658832599101777001703519408664662715322044086646014163774269660274683400619225321.0 11620128128044940816.0) 20637030084881771176788188367974505419050866216433677435050410899110162793040751338330447574748263391136356400036001988938659722098883893353523409458775455519257672423829361150611806294256710309281788819450225670112435352092313483086404714074567539245791066202051788986426960935796927738180831688497683293306590464598379493141645539253898709000874685535467854788184424886911457134522632486730390913239660179785071885982403741669161655812015114272497907946919026898579927936299607156006210124954460880383605958519412435713868501997649784658832599101777001703519408664662715322044086646014163774269671894811528664166137.0) (num-test (+ -9838804688358141062268493389453191808060717708062736103828856866310283812230958467655270667206937622979717683919584610288962829724022506216738929136418489468786902364550847498615864720240589837282441807174290461916292258263929411081218952357662703079709351365960916688275651864441386750529258343003652300629003597744958152243494244227986280506395347894285277364095898602965258114321853474000520432831298793365139040664543928707100657375292032051256485942532600998813627925626928634068613637417702688610315924917761411247617905738119218110678854564441914784262998574445847209847985439514580300936248281049628734475702.0 2380166482232871816.0) -9838804688358141062268493389453191808060717708062736103828856866310283812230958467655270667206937622979717683919584610288962829724022506216738929136418489468786902364550847498615864720240589837282441807174290461916292258263929411081218952357662703079709351365960916688275651864441386750529258343003652300629003597744958152243494244227986280506395347894285277364095898602965258114321853474000520432831298793365139040664543928707100657375292032051256485942532600998813627925626928634068613637417702688610315924917761411247617905738119218110678854564441914784262998574445847209847985439514580300936245900883146501603886.0) (num-test (+ -30961575335426221869515496362216292453766907587859856766456625722888557357647164641922707199324601608700561081422636642523431947551124957385652791834855425829101761914145137205962610515642614866296480715893528289170482422505734612327038754622917335073993027434927547277037587173529054849390646376806910407207016292483185533697336599641898250465186168797820802225861771331652801064811222606773495565340386327294310913503461903243119204619412324538886439122443769008953829820425376589389335553937319588224864611583436327810214798652896733118881040503785110481197462772022447173744898802421806800203373153221004361953729.0 -10586442965055062759.0) -30961575335426221869515496362216292453766907587859856766456625722888557357647164641922707199324601608700561081422636642523431947551124957385652791834855425829101761914145137205962610515642614866296480715893528289170482422505734612327038754622917335073993027434927547277037587173529054849390646376806910407207016292483185533697336599641898250465186168797820802225861771331652801064811222606773495565340386327294310913503461903243119204619412324538886439122443769008953829820425376589389335553937319588224864611583436327810214798652896733118881040503785110481197462772022447173744898802421806800203383739663969417016488.0) (num-test (+ 8835746018617511846981408800319983340292665114153404569022025834059427359831684523399830234196625160662387716033871154398104436720494608541518837969397374272734698261557358249258503982414578618525420572597611597792132117034895074841909295420434392963714805547538976612884853497014341345150095544449860198192757839489063747595073430612069212219930749783824683135433987509303139260133564905961552149844964215891730262218278214035649706577154652729844092199333026620127958228847111442161350881527928460177763370427262298116900358910460957772350452949782281117704005514462730290063772968929608448642592954601418753021512.0 -12227722924075527556.0) 8835746018617511846981408800319983340292665114153404569022025834059427359831684523399830234196625160662387716033871154398104436720494608541518837969397374272734698261557358249258503982414578618525420572597611597792132117034895074841909295420434392963714805547538976612884853497014341345150095544449860198192757839489063747595073430612069212219930749783824683135433987509303139260133564905961552149844964215891730262218278214035649706577154652729844092199333026620127958228847111442161350881527928460177763370427262298116900358910460957772350452949782281117704005514462730290063772968929608448642580726878494677493956.0) (num-test (+ -5455184800550144006991157215735481579353213544152145628297990102571936052187486515129266239245491863623978659179559754999567936067584384479787934704340911556625153536160778495579370425428019248950494107696016864499055854257192071541354806671987402367524770228296322497224645429524493838356022616251290117624472061673033274133156467148770562815676767117605001434288573911556053311048284534341905722947046607192815465807736361991479044698448267471087552952494477144251510778491315012457514838113324210534577956298926109164909779987221094000880908857594198276812276890284008572664102792405452379662935026125770444036994.0 -7349798942312432150.0) -5455184800550144006991157215735481579353213544152145628297990102571936052187486515129266239245491863623978659179559754999567936067584384479787934704340911556625153536160778495579370425428019248950494107696016864499055854257192071541354806671987402367524770228296322497224645429524493838356022616251290117624472061673033274133156467148770562815676767117605001434288573911556053311048284534341905722947046607192815465807736361991479044698448267471087552952494477144251510778491315012457514838113324210534577956298926109164909779987221094000880908857594198276812276890284008572664102792405452379662942375924712756469144.0) (num-test (+ 27233955893140063612427006607965940109569052437681267421929959186535416115028420267622879017163568256526042146282241931623674996867133390355390677118211537487769195270234259640386625552763891339073878417517169618832945750393661600092643257470064376916337734385887099957095417541169462231630821139075814859604097878094729685589777579267192538715202397220666651307185763054526407234767132218634060693076054116575833737797189157152326979078121760900891899319809724675232853322526718686306470372869701173824664984405178677187081936624687293494821338781534163633206006387449585716391843039459733925494003066841874935048611.0 -66646390577667468207341453008390168215.0) 27233955893140063612427006607965940109569052437681267421929959186535416115028420267622879017163568256526042146282241931623674996867133390355390677118211537487769195270234259640386625552763891339073878417517169618832945750393661600092643257470064376916337734385887099957095417541169462231630821139075814859604097878094729685589777579267192538715202397220666651307185763054526407234767132218634060693076054116575833737797189157152326979078121760900891899319809724675232853322526718686306470372869701173824664984405178677187081936624687293494821338781534163633206006387449585716391776393069156258025795725388866544880396.0) (num-test (+ 15030400024888781078933103028897733817304421960545019199443871381537070197157227994520524631721701055962609956080413517776229513420814407790533237358129529547793422514837651333555776540939235592155512951229106778709351772195248438493792786143040421233061520515971787881798980515709417481015662862327435825812557205663033601853937647320838585333754027488605638576977560072206293290493215523194883494322543800546276353830683084405428005815296131527861252717516620765986589669237487765523936713749717927502645633123584240464131140829496052170285171610845098023517906586134613874506419828208611247177336492131262918439281.0 -164048419232636429449474429717211197442.0) 15030400024888781078933103028897733817304421960545019199443871381537070197157227994520524631721701055962609956080413517776229513420814407790533237358129529547793422514837651333555776540939235592155512951229106778709351772195248438493792786143040421233061520515971787881798980515709417481015662862327435825812557205663033601853937647320838585333754027488605638576977560072206293290493215523194883494322543800546276353830683084405428005815296131527861252717516620765986589669237487765523936713749717927502645633123584240464131140829496052170285171610845098023517906586134613874506255779789378610747887017701545707241839.0) (num-test (+ -10227062646189307616073129048534031298512434237226774743330733206156788005874968173984804649812506029813402205606562016228122184161577517837608957023376079537037472977098465137152327215807765130656192272994478964341604278041664840636982572214751638093860605132350960802560601354006634296348422600320863531059118477125143903734159707623839282511184908969206873548650544269932394344952983661665472663102992782521888857016369837211403335306200813816060883478434441858442549261115972947741929087886423170398410216855322384956160289855500229952405068604320121652911887067414460828300146993858360430784079225137421074839819.0 117460076430162201914796277915447781936.0) -10227062646189307616073129048534031298512434237226774743330733206156788005874968173984804649812506029813402205606562016228122184161577517837608957023376079537037472977098465137152327215807765130656192272994478964341604278041664840636982572214751638093860605132350960802560601354006634296348422600320863531059118477125143903734159707623839282511184908969206873548650544269932394344952983661665472663102992782521888857016369837211403335306200813816060883478434441858442549261115972947741929087886423170398410216855322384956160289855500229952405068604320121652911887067414460828300029533781930268582164428859505627057883.0) (num-test (+ 27989453264793973121573869640708223239762902243991948581280654553806618470632044367386680716040316895884976837122054709584963028986161694425215067648887944710852278135008221491665079705797192389681328802747226171436158375378499411314855257919224316919346771317457123252623293612958336691335423245293660257386649100685560072354549579281852792682734916555498283053758141666658137856828164206947320523255487437004565021167276952652515632644458005291855624829941937578229983628962137595011570216766689546500517528191189928660433013004254032861383790553611840534023221000900694995707453499030166286828319347894538505334235.0 -59175168207571178843658955348404514921.0) 27989453264793973121573869640708223239762902243991948581280654553806618470632044367386680716040316895884976837122054709584963028986161694425215067648887944710852278135008221491665079705797192389681328802747226171436158375378499411314855257919224316919346771317457123252623293612958336691335423245293660257386649100685560072354549579281852792682734916555498283053758141666658137856828164206947320523255487437004565021167276952652515632644458005291855624829941937578229983628962137595011570216766689546500517528191189928660433013004254032861383790553611840534023221000900694995707394323861958715649475688939190100819314.0) (num-test (+ 1178650930337394440162727078866515771626896502845852711186000991913866844090831426017480263676964607121490209778220339316756171449922437605552456088105443130477974682689512446683178356259305893852096425478878588001446154476458310269704392486398646169362313605456233489086567865316333034897433650974160168545492823208575634152241341906068149887959566983066154182855136114289266802474404127414747112706158621650063987662749553991791509795764642256261917497984177610694405881831052199417235241109412927893781778469398975117797578753730248539151297798807326284978255001046995523851829184120171969918537718488250577987049.0 -151873924489040812813761508259707631973.0) 1178650930337394440162727078866515771626896502845852711186000991913866844090831426017480263676964607121490209778220339316756171449922437605552456088105443130477974682689512446683178356259305893852096425478878588001446154476458310269704392486398646169362313605456233489086567865316333034897433650974160168545492823208575634152241341906068149887959566983066154182855136114289266802474404127414747112706158621650063987662749553991791509795764642256261917497984177610694405881831052199417235241109412927893781778469398975117797578753730248539151297798807326284978255001046995523851677310195682929105723956979990870355076.0) (num-test (+ 28233332719950979786871881804755080223325040620170668729385709165879717973040387558150293205758215739710262749733170837042434162049732587908182282319848154049410849721309988807368466228286699721201975848741931128639324322061892706638973259354962358866000024260698793885547287093369940035337370984725857550291339492871017395328145015077506882578124550084937438336881072124376107623716831044079223921566902242543198986921476998895559488862309653154914291349588095330683589871173449191854284433182368052817373384461363574550061788800329400860372148193491004593903732351395815409821222597665222975816418433744748143385431.0 -43245950360315656184924888243641533635.0) 28233332719950979786871881804755080223325040620170668729385709165879717973040387558150293205758215739710262749733170837042434162049732587908182282319848154049410849721309988807368466228286699721201975848741931128639324322061892706638973259354962358866000024260698793885547287093369940035337370984725857550291339492871017395328145015077506882578124550084937438336881072124376107623716831044079223921566902242543198986921476998895559488862309653154914291349588095330683589871173449191854284433182368052817373384461363574550061788800329400860372148193491004593903732351395815409821179351714862660160233508856504501851796.0) (num-test (+ 17311283930487575047109155431670372891723312431004343097275158353815289445461275098157423001160013464866170709729134076291306322952612660169010483426086431377525432637844274608988581691477819008626983761905899834444008235608280930166913911248710072733217113558125600345343437000427963292980921009445490627620344145866648036116660335905940809860199697939729919140888034303887423527841395304960072549430314367914315102150378504502158659627719016733307736583749830415574905929299482373462584995162798576853564481617711234957058703455021082855018642616999836886763535412642684228990890160568207941504887072856663966242787.0 1954009743321912552050341299974626734964446274711484506734354360114801426013796892421541915293157994203607853436799102383078659985249097057923578528366737.0) 17311283930487575047109155431670372891723312431004343097275158353815289445461275098157423001160013464866170709729134076291306322952612660169010483426086431377525432637844274608988581691477819008626983761905899834444008235608280930166913911248710072733217113558125600345343437000427963292980921009445490627620344145866648036116660335905940809860199697939729919140888034303887423527841395304960072549430314367914315102150378504502158659627719016733307736583749830417528915672621394925512926295137425311818010756329195741691413063569822508868815535038541752179921529616250537665789992543646867926753984130780242494609524.0) (num-test (+ 1135960177108146621604027872788612991247811085764456406834564014092038611848908717507207251239454266163702244932570537009884467598603226302482406831131219148530146321028801515381981782506355042255201016953375149829517466449677312249611502599434850555618739830488706171667035140895674806873502543300909514568759918040129665855731078258004983486524477103833885001539135541445685573269814159175744401893663504523858005835387122082112362666991112899837534230326730196110477118156871579503345757821268248575583821695674912517830056856597644827244194658166928026249459511837772775196175188368236573504643083995409774002567.0 -5513982495816270388232134254127393284677692173792609278582774509636977743203029647121158805174638642867428501907786521939155900331399058909602425073976766.0) 1135960177108146621604027872788612991247811085764456406834564014092038611848908717507207251239454266163702244932570537009884467598603226302482406831131219148530146321028801515381981782506355042255201016953375149829517466449677312249611502599434850555618739830488706171667035140895674806873502543300909514568759918040129665855731078258004983486524477103833885001539135541445685573269814159175744401893663504523858005835387122082112362666991112899837534230326730190596494622340601191271211503693874963897891647903065633935055547219619901624214547537008122851610816644409270867409653249212336242105584174392984700025801.0) (num-test (+ -30369736932762868789456108597366835061749107555998091727589163626331595118680326568212941898571309672187038272915036839449380083450246957904300051802617002374912724325419651633014408152565340519439718081357147324136023867003917288524338643759680061563616479323818330115572573568245719292922176485298767387601922362893307843067637295955606642841006993776777666041277965868780958830666697755738164183356399977211227424725670822944234275611849032230010745799964550976844117943559190671369193871330514473741920389633762695829790016565565261170688485790141638094160105909405353382982945608773290740598479367828342651860878.0 3451570547959142767282758882796967240086418127970526029661337442068316209707489088420708984628065070358319478649952710478991064476168799556496237099109563.0) -30369736932762868789456108597366835061749107555998091727589163626331595118680326568212941898571309672187038272915036839449380083450246957904300051802617002374912724325419651633014408152565340519439718081357147324136023867003917288524338643759680061563616479323818330115572573568245719292922176485298767387601922362893307843067637295955606642841006993776777666041277965868780958830666697755738164183356399977211227424725670822944234275611849032230010745799964550973392547395600047904086434988533547233655502261663236666168452574497249051463199397369432653466095035551085874733030235129782226264429679811332105552751315.0) (num-test (+ 24749014370880469345815230363662696846133977441600857690896762642529872426102613384561609594131771018575590861342023688138502403609639138062665279129058939911797019091643704220495944170754490238422880589600838613701783818105188827633578438439212856537589855796204839275633245851474930725845096235668385012500773524750522781174430369067441632028068262240870795850561389232369373523415592833273932285308223863420210049445377497367753786125779044716949754454461623397410528064697616617917065021866397277409044449982605591256067763430930720398889239414812509701319783809830072841056369381573100589260104551934136733317845.0 -9461623592584966196513107657889418526847060851423069480904645009418813160370721071067349946095573698635859409908288864150475056170059858850823883834932131.0) 24749014370880469345815230363662696846133977441600857690896762642529872426102613384561609594131771018575590861342023688138502403609639138062665279129058939911797019091643704220495944170754490238422880589600838613701783818105188827633578438439212856537589855796204839275633245851474930725845096235668385012500773524750522781174430369067441632028068262240870795850561389232369373523415592833273932285308223863420210049445377497367753786125779044716949754454461623387948904472112650421403957363976978750561983598559536110351422754012117560028168168347462563605746085173970662932767505231098044419200245701110252898385714.0) (num-test (+ 19070246171469235561279483225919489206942407814032615339351735800304747459507922411906751965555240682457214768298108831815622470433175555196912899313888991765436434867025639919521068437191248198117664398275835972573354886915721765715992151871453808224011999677700078879590132676060988550961950472536029228350169237717222998397029428440792110955380302156159849645211726041489206565536560827557279129751110297078563108009278363910936720061216511798518178957070787710331228500533067546198458251241005176280410230146430275074766072259256583499095689284871987010372039977403712023630453400259082684930755893684499232318008.0 12330599952818018622104330691506128012101935028731995985677032980931398338453806827555760801312052792065671886621851470997557806941112316627790755867100463.0) 19070246171469235561279483225919489206942407814032615339351735800304747459507922411906751965555240682457214768298108831815622470433175555196912899313888991765436434867025639919521068437191248198117664398275835972573354886915721765715992151871453808224011999677700078879590132676060988550961950472536029228350169237717222998397029428440792110955380302156159849645211726041489206565536560827557279129751110297078563108009278363910936720061216511798518178957070787722661828453351086168302788942747133188382345258878426260751799053190654921952902516840632788322424832043075598645481924397816889626043072521475255099418471.0) (num-test (+ -20895998178036569919774658790651496115060841511658297683195804524712012347695091074325978179977718571444320688167469052862702339462089668992243209990795362064005869602003990235714500149401994013174762139297327430396441552225926368085284222509085197484452650071390132794942944512235132641643003294762547138305644086106533258432786768644384855008506026923783604514268955071498269812887794817192371944269611642901807443894686178438687102834127061425955994253034824027771176714559050403098437684091684851207513969915720607528045624635094984539637789113651579846373399975502788877555747414523231999341294756679330384323996.0 764238600803843266244444637050072967342049538611688895792923539838804953492110953673720766879606601435939162680753428779068917662740403667549850724878795.0) -20895998178036569919774658790651496115060841511658297683195804524712012347695091074325978179977718571444320688167469052862702339462089668992243209990795362064005869602003990235714500149401994013174762139297327430396441552225926368085284222509085197484452650071390132794942944512235132641643003294762547138305644086106533258432786768644384855008506026923783604514268955071498269812887794817192371944269611642901807443894686178438687102834127061425955994253034824027006938113755207136853993047041611883865464431304031711735122084796290031047526835439930812966766798539563626196802318635454314336600891089129479659445201.0) (num-test (+ 6243894672855694190803081952962387322599009058758027960092936187687064819462191583137945440936085088260632250436567758576422207449236613172605950116622271404444221039084346501796818945639456207912207604248991842124079786471250102192718092353598850889806607728696519257402580732995770031331187089424192803722612735557735028710899438934171272639518928194764526910590046378401600819132587804143949995694950116915803127294011661411525934100144319021440919928013617766507409909846670172516021888661284467975865076091834094160862228180625536450124272957206172214541444266874056050295270719541605687740822711659847211976891.0 11877496607682442993105675644902145742318375725225741293060927105303783712520284640625374957608051032540491531573337817824773543104969422017506696018037874641947740606655370938613842356322585858034851150595788166740174872996252792014218946552442572806242471174234462119454014379628228878122072189387777413014452140618318641689597452676091677588204537830401725113931418426919671512011822864583481449136550835952005765386885680701637038206002172218712504732572449659704181315669255320876647592649071711438131711904976335957846353867776093588236311654631696625859173554395714740218099921290128795607292259527492722462071.0) 18121391280538137183908757597864533064917384783983769253153863292990848531982476223763320398544136120801123782009905576401195750554206035190112646134660146046391961645739717440410661301962042065947058754844780008864254659467502894206937038906041423696049078902930981376856595112623998909453259278811970216737064876176053670400496891610262950227723466025166252024521464805321272331144410668727431444831500952867808892680897342113162972306146491240153424660586067426211591225515925493392669481310356179413996787996810430118708582048401630038360584611837868840400617821269770790513370640831734483348114971187339934438962.0) (num-test (+ -24023960171862805266003610953999097357395283354964456554686635290239019705581779621120391229617494503580661676939681517550103414632840981987397485411400553792707518662609532504246677658012933762605038799352109564432278094548068984563394926376371580465135388578139331334464060067790936072127680597181415407099723844313625277987147283697141407959289588588489162704824409673099509423520008795428217612706997355591985894255450783091681112776112997887084157623388943538145736618168104404283342039105202585543852590302154958791010622670839015475427693311663800177428904406869645066988663292128104453773413982185343111560886.0 -31939808827732134714870375774276102357277346245583282398423150631754622253109692213928642228787888509211781331649081002266227303203259124984426497846441848502574293640959494009564992092503141598640200823656998243767453860939156780549404892392521391484933772285520949470194562525777116137058001008184603332597820522016200623301007194309404025522056113671560767212894303567191067178003014955596425115379852712737129325098876542459702682095445350281859042779889411325882123213577906096942649941285655935053362468972482748617111598313960198743596285343178242282172686940700127068972627110105953098737923773182254460772630.0) -55963768999594939980873986728275199714672629600547738953109785921993641958691471835049033458405383012792443008588762519816330717836100106971823983257842402295281812303569026513811669750516075361245239623009107808199731955487225765112799818768892971950069160863660280804658622593568052209185681605366018739697544366329825901288154478006545433481345702260049929917718713240290576601523023751024642728086850068329115219354327325551383794871558348168943200403278354864027859831746010501225991980390858520597215059274637707408122220984799214219023978654842042459601591347569772135961290402234057552511337755367597572333516.0) (num-test (+ 14513652183174940741664411990199277445706189147726874603036586212536012746892966848269748909379750612027025331446918381470766609543142456872580466135425754204680927122749772612276850998180593344389487924747722210296498854143380696064338777945015153982467675141485724865534995199700908286263993697988986805404864429385840512740226775506122190698806967785494289035976495492863456705096841250592980439363856397663738211335801835896091823148249303370609165910779981271035234045185574995335952208702661648744928539539455138167482396767268362221492607154709559716065850417221174683768503217544145599044845325824451589309835.0 -12814535978730024053359592817368712576084646962861720729844389627130663192435154658607204342320327460695280260731620465435530495952836598646143907272825807563512741964987882356778796849529260646503692618525570185450780889283642116889481314560395290434301143877809550098309214046129802023655714098730144464028249594406616074059558969757405392170810220921023905546104487938441503430332099605473144930508420331873995741851604525954472341693863067199617721032815462094767522339305487934030130207039176659398466616780628644572276059410087128533031562978399689702766028716401176531098447698206272762966470643604141938670152.0) 1699116204444916688304819172830564869621542184865153873192196585405349554457812189662544567059423151331745070715297916035236113590305858226436558862599946641168185157761890255498054148651332697885795306222152024845717964859738579174857463384619863548166531263676174767225781153571106262608279599258842341376614834979224438680667805748716798527996746864470383489872007554421953274764741645119835508855436065789742469484197309941619481454386236170991444877964519176267711705880087061305822001663484989346461922758826493595206337357181233688461044176309870013299821700819998152670055519337872836078374682220309650639683.0) (num-test (+ 11356479761814008572465147431830778885327227506593483181241437802252618729479905490826767363633131720717461693888023278837835457496021519184903984385091047829540007466025527592005114414671285638168997562037691602144751434208304408870143450743278437854754504713023422097017723330207792526222436928747286558205279330508360438281011315147578105966454344087225699378388309094140949428028313539634103047841948634832398526343605363013644180832752120081735152285507591096001749463421326282317713079361827765412853023201330345752038722069405404812511739634687282327711258974520622248165974215116400638833123609666501349513623.0 -2451734542868054449539778460457497703609327132304922810342762480808881050209276687756391911546806187586640918078231508181876445466503459873508196878629364924241891220686182517218825181707207808769770392864734466652524094735160185556148554260517746279303022469784592528209667497664672945900929888144529727881050106027775707933311860110618130543481573815538047460723253898548348335762406437618625388229555824532715231231491787570056329865617082709588903922431713098922691537317839185452018617461891748518176708607861270770493263960554805373552348256747200291438630960804647686832667981625018361034564086859426490014044.0) 8904745218945954122925368971373281181717900374288560370898675321443737679270628803070375452086325533130820775809791770655959012029518059311395787506461682905298116245339345074786289232964077829399227169172957135492227339473144223313994896482760691575451482243238829568808055832543119580321507040602756830324229224480584730347699455036959975422972770271687651917665055195592601092265907102015477659612392810299683295112113575443587850967135037372146248363075877997079057926103487096865694461899936016894676314593469074981545458108850599438959391377940082036272628013715974561333306233491382277798559522807074859499579.0) (num-test (+ -1814184401790217165873937825605141478060935014868566665644215718762341535891730598045990231798382966074312671040257824056876679135909008140059087311700216658095793352051583071432744886316274989901835606602224927350560604355249919901932382803472476702792978322468747380191775778902733911968522382089332819162367884984027854067607561808704316828316820133400099093450636968732151876570835173932998599031643640476109466728761033062776578175554441947411139184426213290292577467587355369954997241091769769542810051228504545831588488726789173405585678190671534386784806998695797717346491308862362775748058331375692317599945.0 15466182953987394334491149436346080039471412309427279110582769586053943302670765125931570041904640518032832554998553018838321871748542118021556398569294085708441934948186080236498081517178574839977996802813431873543309853609838200338534343580791382510179184571852290959723696010410340740895530535423959476873857191548113125728667781953125153120447892632916574768078583174099545013854248664119997703948998871566374080719541931440495888606776561795893839624084254684939434035018741535261951124673664746010067859317726891535170781460914710499572006592206360512398012457295755926986236618644330364227754380084585899275327.0) 13651998552197177168617211610740938561410477294558712444938553867291601766779034527885579810106257551958519883958295194781445192612633109881497311257593869050346141596134497165065336630862299850076161196211206946192749249254588280436601960777318905807386206249383543579531920231507606828927008153334626657711489306564085271661060220144420836292131072499516475674627946205367393137283413490186999104917355231090264613990780898377719310431222119848482700439658041394646856567431386165306953883581894976467257808089222345703582292734125537093986328401534826125613205458599958209639745309781967588479696048708893581675382.0) (num-test (+ -27127130599753372624001250456405972983012981437652156246797208697430661165612459362971759027335854588888552031022264244768883843080959804690580574272908031271224646245152017114094021048441971097191444782106551075175878815012595015584723250801765859461211934306789890718268168352614164589637346918581658850565274510502652089457352942736418509881708568727739912127781455473660768550022762222130489047215089836402367851853412705556570667960548570630054608024914653686223423908494006675057953013815512203710764854485332282975729323105427143207127239069826750682633272289409910001698385240596625059970587393681128674617278.0 5719655139276246085992066702308194672442413085748146924567717361937179810269300239821879673460959112727066470468217892213025828988023367028158410455624528688729907493639908638553730770145274142147983721694721139760883483821883267129411125364089207412089113869427479340283853501026803387874124668123626271531796990801822527792189514551888019206405597994403243358155410088320317141454525417323186389587327532772638942220300149829241141659063128602316305332848477566686425551944956989370838072872906293845914921103561360871571846865478762953536949621421094416539099628942010528483544062050170673327754206501716239719529.0) -21407475460477126538009183754097778310570568351904009322229491335493481355343159123149879353874895476161485560554046352555858014092936437662422163817283502582494738751512108475540290278296696955043461060411829935414995331190711748455312125437676652049122820437362411377984314851587361201763222250458032579033477519700829561665163428184530490675302970733336668769626045385340451408568236804807302657627762303629728909633112555727329526301485442027738302692066176119536998356549049685687114940942605909864849933381770922104157476239948380253590289448405656266094172660467899473214841178546454386642833187179412434897749.0) )) (test (+ 1 #f) 'error) (test (+ 1 #t) 'error) (test (+ 1 + 2) 'error) (test (+ 1 - 2) 'error) (test (+ 1 2 . 3) 'error) (test (+ 1 . 2) 'error) ;;; an optimizer test (let () (define (hi a b c) (+ (+ 1 (* 2 b)) (+ a (* b c)) (+ (* a b) c) (+ (* a 3) 4))) (num-test (hi 5 6 7) 116)) (for-each (lambda (arg) (test (+ arg nan.0) 'error) (test (+ nan.0 arg) 'error) (test (+ arg inf.0) 'error) (test (+ inf.0 arg) 'error) (test (+ arg) 'error) (test (+ 0 arg) 'error) (test (+ 0.0 arg) 'error) (test (+ 1 arg) 'error) (test (+ 1/2 arg) 'error) (test (+ 1.0 arg) 'error) (test (+ 1+i arg) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) ;;; -------------------------------------------------------------------------------- ;;; - ;;; -------------------------------------------------------------------------------- (num-test (- -0) 0) (num-test (- -0.0) 0.0) (num-test (- -0.0+0.00000001i) 0.0-0.00000001i) (num-test (- -1.0 0.0) -1.0) (num-test (- -1.0) 1.0) (num-test (- -1.0+1.0i -1.0+1.0i) 0.0) (num-test (- -1.0+1.0i 0) -1.0+1.0i) (num-test (- -1.0+1.0i 0.0) -1.0+1.0i) (num-test (- -1.0+1.0i 0.0) -1.0+1.0i) (num-test (- -1.0+1.0i 0.0+1.0i) -1.0) (num-test (- -1.0+1.0i 1) -2.0+1.0i) (num-test (- -1.0+1.0i 1.0) -2.0+1.0i) (num-test (- -1.0+1.0i 1.0+1.0i) -2.0) (num-test (- -1.0+1.0i 1.234+1.234i) -2.234-0.234i) (num-test (- -1.0+1.0i 1/1) -2.0+1.0i) (num-test (- -1.0+1.0i 123.4) -124.4+1.0i) (num-test (- -1.0+1.0i 1234) -1235.0+1.0i) (num-test (- -1.0+1.0i 1234/11) -113.18181818181819+1.0i) (num-test (- -1.0+1.0i) 1.0-1.0i) (num-test (- -10) 10) (num-test (- -10/3) 10/3) (num-test (- -1234000000) 1234000000) (num-test (- -1234000000.0) 1234000000.0) (num-test (- -1234000000.0+2.71828182845905i) 1234000000.0-2.71828182845905i) (num-test (- -1234000000/10) 1234000000/10) (num-test (- -2 0) -2) (num-test (- -2) 2) (num-test (- -2.71828182845905) 2.71828182845905) (num-test (- -2.71828182845905+3.14159265358979i) 2.71828182845905-3.14159265358979i) (num-test (- -2.71828182845905-3.14159265358979i) 2.71828182845905+3.14159265358979i) (num-test (- -2/2 0/1) -2/2) (num-test (- -362880) 362880) (num-test (- -362880/1234) 362880/1234) (num-test (- 0 -1.0+1.0i) 1.0-1.0i) (num-test (- 0 0) 0) (num-test (- 0 0.0) 0.0) (num-test (- 0 0.0+1.0i) 0.0-1.0i) (num-test (- 0 1 -1.0+1.0i) 0.0-1.0i) (num-test (- 0 1 0) -1) (num-test (- 0 1 0.0) -1.0) (num-test (- 0 1 0.0+1.0i) -1.0-1.0i) (num-test (- 0 1 1) -2) (num-test (- 0 1 1.0) -2.0) (num-test (- 0 1 1.0+1.0i) -2.0-1.0i) (num-test (- 0 1 1.234+1.234i) -2.234-1.234i) (num-test (- 0 1 1/1) -2) (num-test (- 0 1 123.4) -124.4) (num-test (- 0 1 1234) -1235) (num-test (- 0 1 1234/11) -1245/11) (num-test (- 0 1) -1) (num-test (- 0 1.0 -1.0+1.0i) 0.0-1.0i) (num-test (- 0 1.0 0) -1.0) (num-test (- 0 1.0 0.0) -1.0) (num-test (- 0 1.0 0.0+1.0i) -1.0-1.0i) (num-test (- 0 1.0 1) -2.0) (num-test (- 0 1.0 1.0) -2.0) (num-test (- 0 1.0 1.0+1.0i) -2.0-1.0i) (num-test (- 0 1.0 1.234+1.234i) -2.234-1.234i) (num-test (- 0 1.0 1/1) -2.0) (num-test (- 0 1.0 123.4) -124.4) (num-test (- 0 1.0 1234) -1235.0) (num-test (- 0 1.0 1234/11) -113.18181818181819) (num-test (- 0 1.0) -1.0) (num-test (- 0 1.0+1.0i -1.0+1.0i) 0.0-2.0i) (num-test (- 0 1.0+1.0i 0) -1.0-1.0i) (num-test (- 0 1.0+1.0i 0.0) -1.0-1.0i) (num-test (- 0 1.0+1.0i 0.0+1.0i) -1.0-2.0i) (num-test (- 0 1.0+1.0i 1) -2.0-1.0i) (num-test (- 0 1.0+1.0i 1.0) -2.0-1.0i) (num-test (- 0 1.0+1.0i 1.0+1.0i) -2.0-2.0i) (num-test (- 0 1.0+1.0i 1.234+1.234i) -2.234-2.234i) (num-test (- 0 1.0+1.0i 1/1) -2.0-1.0i) (num-test (- 0 1.0+1.0i 123.4) -124.4-1.0i) (num-test (- 0 1.0+1.0i 1234) -1235.0-1.0i) (num-test (- 0 1.0+1.0i 1234/11) -113.18181818181819-1.0i) (num-test (- 0 1.0+1.0i) -1.0-1.0i) (num-test (- 0 1.234+1.234i) -1.234-1.234i) (num-test (- 0 123.4) -123.4) (num-test (- 0 1234) -1234) (num-test (- 0 1234/11) -1234/11) (num-test (- 0) 0) (num-test (- 0) 0) (num-test (- 0.0 -1.0+1.0i -1.0+1.0i) 2.0-2.0i) (num-test (- 0.0 -1.0+1.0i 0) 1.0-1.0i) (num-test (- 0.0 -1.0+1.0i 0.0) 1.0-1.0i) (num-test (- 0.0 -1.0+1.0i 0.0+1.0i) 1.0-2.0i) (num-test (- 0.0 -1.0+1.0i 1) 0.0-1.0i) (num-test (- 0.0 -1.0+1.0i 1.0) 0.0-1.0i) (num-test (- 0.0 -1.0+1.0i 1.0+1.0i) 0.0-2.0i) (num-test (- 0.0 -1.0+1.0i 1.234+1.234i) -0.234-2.234i) (num-test (- 0.0 -1.0+1.0i 1/1) 0.0-1.0i) (num-test (- 0.0 -1.0+1.0i 123.4) -122.4-1.0i) (num-test (- 0.0 -1.0+1.0i 1234) -1233.0-1.0i) (num-test (- 0.0 -1.0+1.0i 1234/11) -111.18181818181819-1.0i) (num-test (- 0.0 -1.0+1.0i) 1.0-1.0i) (num-test (- 0.0 0 -1.0+1.0i) 1.0-1.0i) (num-test (- 0.0 0 0) 0.0) (num-test (- 0.0 0 0.0) 0.0) (num-test (- 0.0 0 0.0+1.0i) 0.0-1.0i) (num-test (- 0.0 0 1) -1.0) (num-test (- 0.0 0 1.0) -1.0) (num-test (- 0.0 0 1.0+1.0i) -1.0-1.0i) (num-test (- 0.0 0 1.234+1.234i) -1.234-1.234i) (num-test (- 0.0 0 1/1) -1.0) (num-test (- 0.0 0 123.4) -123.4) (num-test (- 0.0 0 1234) -1234.0) (num-test (- 0.0 0 1234/11) -112.18181818181819) (num-test (- 0.0 0) 0.0) (num-test (- 0.0 0.0 -1.0+1.0i) 1.0-1.0i) (num-test (- 0.0 0.0 0) 0.0) (num-test (- 0.0 0.0 0.0) 0.0) (num-test (- 0.0 0.0 0.0+1.0i) 0.0-1.0i) (num-test (- 0.0 0.0 1) -1.0) (num-test (- 0.0 0.0 1.0) -1.0) (num-test (- 0.0 0.0 1.0+1.0i) -1.0-1.0i) (num-test (- 0.0 0.0 1.234+1.234i) -1.234-1.234i) (num-test (- 0.0 0.0 1/1) -1.0) (num-test (- 0.0 0.0 123.4) -123.4) (num-test (- 0.0 0.0 1234) -1234.0) (num-test (- 0.0 0.0 1234/11) -112.18181818181819) (num-test (- 0.0 0.0) 0.0) (num-test (- 0.0 0.0+1.0i -1.0+1.0i) 1.0-2.0i) (num-test (- 0.0 0.0+1.0i 0) 0.0-1.0i) (num-test (- 0.0 0.0+1.0i 0.0) 0.0-1.0i) (num-test (- 0.0 0.0+1.0i 0.0+1.0i) 0.0-2.0i) (num-test (- 0.0 0.0+1.0i 1) -1.0-1.0i) (num-test (- 0.0 0.0+1.0i 1.0) -1.0-1.0i) (num-test (- 0.0 0.0+1.0i 1.0+1.0i) -1.0-2.0i) (num-test (- 0.0 0.0+1.0i 1.234+1.234i) -1.234-2.234i) (num-test (- 0.0 0.0+1.0i 1/1) -1.0-1.0i) (num-test (- 0.0 0.0+1.0i 123.4) -123.4-1.0i) (num-test (- 0.0 0.0+1.0i 1234) -1234.0-1.0i) (num-test (- 0.0 0.0+1.0i 1234/11) -112.18181818181819-1.0i) (num-test (- 0.0 0.0+1.0i) 0.0-1.0i) (num-test (- 0.0 1 -1.0+1.0i) 0.0-1.0i) (num-test (- 0.0 1 0) -1.0) (num-test (- 0.0 1 0.0) -1.0) (num-test (- 0.0 1 0.0+1.0i) -1.0-1.0i) (num-test (- 0.0 1 1.0) -2.0) (num-test (- 0.0 1 1.0+1.0i) -2.0-1.0i) (num-test (- 0.0 1 1.234+1.234i) -2.234-1.234i) (num-test (- 0.0 1 1/1) -2.0) (num-test (- 0.0 1 123.4) -124.4) (num-test (- 0.0 1 1234) -1235.0) (num-test (- 0.0 1 1234/11) -113.18181818181819) (num-test (- 0.0 1) -1.0) (num-test (- 0.0 1.0 -1.0+1.0i) 0.0-1.0i) (num-test (- 0.0 1.0 0) -1.0) (num-test (- 0.0 1.0 0.0) -1.0) (num-test (- 0.0 1.0 0.0+1.0i) -1.0-1.0i) (num-test (- 0.0 1.0 1) -2.0) (num-test (- 0.0 1.0 1.0) -2.0) (num-test (- 0.0 1.0 1.0+1.0i) -2.0-1.0i) (num-test (- 0.0 1.0 1.234+1.234i) -2.234-1.234i) (num-test (- 0.0 1.0 1/1) -2.0) (num-test (- 0.0 1.0 123.4) -124.4) (num-test (- 0.0 1.0 1234) -1235.0) (num-test (- 0.0 1.0 1234/11) -113.18181818181819) (num-test (- 0.0 1.0) -1.0) (num-test (- 0.0 1.0+1.0i -1.0+1.0i) 0.0-2.0i) (num-test (- 0.0 1.0+1.0i 0) -1.0-1.0i) (num-test (- 0.0 1.0+1.0i 0.0) -1.0-1.0i) (num-test (- 0.0 1.0+1.0i 0.0+1.0i) -1.0-2.0i) (num-test (- 0.0 1.0+1.0i 1) -2.0-1.0i) (num-test (- 0.0 1.0+1.0i 1.0) -2.0-1.0i) (num-test (- 0.0 1.0+1.0i 1.0+1.0i) -2.0-2.0i) (num-test (- 0.0 1.0+1.0i 1.234+1.234i) -2.234-2.234i) (num-test (- 0.0 1.0+1.0i 1/1) -2.0-1.0i) (num-test (- 0.0 1.0+1.0i 123.4) -124.4-1.0i) (num-test (- 0.0 1.0+1.0i 1234) -1235.0-1.0i) (num-test (- 0.0 1.0+1.0i 1234/11) -113.18181818181819-1.0i) (num-test (- 0.0 1.0+1.0i) -1.0-1.0i) (num-test (- 0.0 1.234+1.234i -1.0+1.0i) -0.234-2.234i) (num-test (- 0.0 1.234+1.234i 0) -1.234-1.234i) (num-test (- 0.0 1.234+1.234i 0.0) -1.234-1.234i) (num-test (- 0.0 1.234+1.234i 0.0+1.0i) -1.234-2.234i) (num-test (- 0.0 1.234+1.234i 1) -2.234-1.234i) (num-test (- 0.0 1.234+1.234i 1.0) -2.234-1.234i) (num-test (- 0.0 1.234+1.234i 1.0+1.0i) -2.234-2.234i) (num-test (- 0.0 1.234+1.234i 1.234+1.234i) -2.468-2.468i) (num-test (- 0.0 1.234+1.234i 1/1) -2.234-1.234i) (num-test (- 0.0 1.234+1.234i 123.4) -124.634-1.234i) (num-test (- 0.0 1.234+1.234i 1234) -1235.23399999999992-1.234i) (num-test (- 0.0 1.234+1.234i 1234/11) -113.41581818181818-1.234i) (num-test (- 0.0 1.234+1.234i) -1.234-1.234i) (num-test (- 0.0 1/1 -1.0+1.0i) 0.0-1.0i) (num-test (- 0.0 123.4 -1.0+1.0i) -122.4-1.0i) (num-test (- 0.0 123.4 0) -123.4) (num-test (- 0.0 123.4 0.0) -123.4) (num-test (- 0.0 123.4 0.0+1.0i) -123.4-1.0i) (num-test (- 0.0 123.4 1) -124.4) (num-test (- 0.0 123.4 1.0) -124.4) (num-test (- 0.0 123.4 1.0+1.0i) -124.4-1.0i) (num-test (- 0.0 123.4 1.234+1.234i) -124.634-1.234i) (num-test (- 0.0 123.4 1/1) -124.4) (num-test (- 0.0 123.4 123.4) -246.8) (num-test (- 0.0 123.4 1234) -1357.4) (num-test (- 0.0 123.4 1234/11) -235.58181818181819) (num-test (- 0.0 123.4) -123.4) (num-test (- 0.0 1234 -1.0+1.0i) -1233.0-1.0i) (num-test (- 0.0 1234 0) -1234.0) (num-test (- 0.0 1234 0.0) -1234.0) (num-test (- 0.0 1234 0.0+1.0i) -1234.0-1.0i) (num-test (- 0.0 1234 1) -1235.0) (num-test (- 0.0 1234 1.0) -1235.0) (num-test (- 0.0 1234 1.0+1.0i) -1235.0-1.0i) (num-test (- 0.0 1234 1.234+1.234i) -1235.23399999999992-1.234i) (num-test (- 0.0 1234 1/1) -1235.0) (num-test (- 0.0 1234 123.4) -1357.4) (num-test (- 0.0 1234 1234) -2468.0) (num-test (- 0.0 1234 1234/11) -1346.18181818181824) (num-test (- 0.0 1234) -1234.0) (num-test (- 0.0 1234/11 -1.0+1.0i) -111.18181818181819-1.0i) (num-test (- 0.0 1234/11 0) -112.18181818181819) (num-test (- 0.0 1234/11 0.0) -112.18181818181819) (num-test (- 0.0 1234/11 0.0+1.0i) -112.18181818181819-1.0i) (num-test (- 0.0 1234/11 1) -113.18181818181819) (num-test (- 0.0 1234/11 1.0) -113.18181818181819) (num-test (- 0.0 1234/11 1.0+1.0i) -113.18181818181819-1.0i) (num-test (- 0.0 1234/11 1.234+1.234i) -113.41581818181818-1.234i) (num-test (- 0.0 1234/11 1/1) -113.18181818181819) (num-test (- 0.0 1234/11 123.4) -235.58181818181819) (num-test (- 0.0 1234/11 1234) -1346.18181818181824) (num-test (- 0.0 1234/11 1234/11) -224.36363636363637) (num-test (- 0.0 1234/11) -112.18181818181819) (num-test (- 0.0) -0.0) (num-test (- 0.0+0.00000001i) -0.0-0.00000001i) (num-test (- 0.0+1.0i -1.0+1.0i) 1.0) (num-test (- 0.0+1.0i 0) 0.0+1.0i) (num-test (- 0.0+1.0i 0.0) 0.0+1.0i) (num-test (- 0.0+1.0i 0.0+1.0i) 0.0) (num-test (- 0.0+1.0i 1) -1.0+1.0i) (num-test (- 0.0+1.0i 1.0) -1.0+1.0i) (num-test (- 0.0+1.0i 1.0+1.0i) -1.0) (num-test (- 0.0+1.0i 1.234+1.234i) -1.234-0.234i) (num-test (- 0.0+1.0i 1/1) -1.0+1.0i) (num-test (- 0.0+1.0i 123.4) -123.4+1.0i) (num-test (- 0.0+1.0i 1234) -1234.0+1.0i) (num-test (- 0.0+1.0i 1234/11) -112.18181818181819+1.0i) (num-test (- 0.0-0.00000001i) -0.0+0.00000001i) (num-test (- 0/1) 0/1) (num-test (- 0/1) 0/1) (num-test (- 1 -1.0+1.0i) 2.0-1.0i) (num-test (- 1 0) 1) (num-test (- 1 0.0) 1.0) (num-test (- 1 0.0+1.0i) 1.0-1.0i) (num-test (- 1 1 -1.0+1.0i) 1.0-1.0i) (num-test (- 1 1 0) 0) (num-test (- 1 1 0.0) 0.0) (num-test (- 1 1 0.0+1.0i) 0.0-1.0i) (num-test (- 1 1 1) -1) (num-test (- 1 1 1.0) -1.0) (num-test (- 1 1 1.0+1.0i) -1.0-1.0i) (num-test (- 1 1 1.234+1.234i) -1.234-1.234i) (num-test (- 1 1 1/1) -1) (num-test (- 1 1 123.4) -123.4) (num-test (- 1 1 1234) -1234) (num-test (- 1 1 1234/11) -1234/11) (num-test (- 1 1) 0) (num-test (- 1 1.0 -1.0+1.0i) 1.0-1.0i) (num-test (- 1 1.0 0) 0.0) (num-test (- 1 1.0 0.0) 0.0) (num-test (- 1 1.0 0.0+1.0i) 0.0-1.0i) (num-test (- 1 1.0 1) -1.0) (num-test (- 1 1.0 1.0) -1.0) (num-test (- 1 1.0 1.0+1.0i) -1.0-1.0i) (num-test (- 1 1.0 1.234+1.234i) -1.234-1.234i) (num-test (- 1 1.0 1/1) -1.0) (num-test (- 1 1.0 123.4) -123.4) (num-test (- 1 1.0 1234) -1234.0) (num-test (- 1 1.0 1234/11) -112.18181818181819) (num-test (- 1 1.0) 0.0) (num-test (- 1 1.0+1.0i -1.0+1.0i) 1.0-2.0i) (num-test (- 1 1.0+1.0i 0) 0.0-1.0i) (num-test (- 1 1.0+1.0i 0.0) 0.0-1.0i) (num-test (- 1 1.0+1.0i 0.0+1.0i) 0.0-2.0i) (num-test (- 1 1.0+1.0i 1) -1.0-1.0i) (num-test (- 1 1.0+1.0i 1.0) -1.0-1.0i) (num-test (- 1 1.0+1.0i 1.0+1.0i) -1.0-2.0i) (num-test (- 1 1.0+1.0i 1.234+1.234i) -1.234-2.234i) (num-test (- 1 1.0+1.0i 1/1) -1.0-1.0i) (num-test (- 1 1.0+1.0i 123.4) -123.4-1.0i) (num-test (- 1 1.0+1.0i 1234) -1234.0-1.0i) (num-test (- 1 1.0+1.0i 1234/11) -112.18181818181819-1.0i) (num-test (- 1 1.0+1.0i) 0.0-1.0i) (num-test (- 1 1.234+1.234i) -0.234-1.234i) (num-test (- 1 1/1 -1.0+1.0i) 1.0-1.0i) (num-test (- 1 123.4) -122.4) (num-test (- 1 1234) -1233) (num-test (- 1 1234/11) -1223/11) (num-test (- 1.0 -1.0+1.0i -1.0+1.0i) 3.0-2.0i) (num-test (- 1.0 -1.0+1.0i 0) 2.0-1.0i) (num-test (- 1.0 -1.0+1.0i 0.0) 2.0-1.0i) (num-test (- 1.0 -1.0+1.0i 0.0+1.0i) 2.0-2.0i) (num-test (- 1.0 -1.0+1.0i 1) 1.0-1.0i) (num-test (- 1.0 -1.0+1.0i 1.0) 1.0-1.0i) (num-test (- 1.0 -1.0+1.0i 1.0+1.0i) 1.0-2.0i) (num-test (- 1.0 -1.0+1.0i 1.234+1.234i) 0.766-2.234i) (num-test (- 1.0 -1.0+1.0i 1/1) 1.0-1.0i) (num-test (- 1.0 -1.0+1.0i 123.4) -121.4-1.0i) (num-test (- 1.0 -1.0+1.0i 1234) -1232.0-1.0i) (num-test (- 1.0 -1.0+1.0i 1234/11) -110.18181818181819-1.0i) (num-test (- 1.0 -1.0+1.0i) 2.0-1.0i) (num-test (- 1.0 0 -1.0+1.0i) 2.0-1.0i) (num-test (- 1.0 0 0) 1.0) (num-test (- 1.0 0 0.0) 1.0) (num-test (- 1.0 0 0.0+1.0i) 1.0-1.0i) (num-test (- 1.0 0 1) 0.0) (num-test (- 1.0 0 1.0) 0.0) (num-test (- 1.0 0 1.0+1.0i) 0.0-1.0i) (num-test (- 1.0 0 1.234+1.234i) -0.234-1.234i) (num-test (- 1.0 0 1/1) 0.0) (num-test (- 1.0 0 123.4) -122.4) (num-test (- 1.0 0 1234) -1233.0) (num-test (- 1.0 0 1234/11) -111.18181818181819) (num-test (- 1.0 0) 1.0) (num-test (- 1.0 0.0 -1.0+1.0i) 2.0-1.0i) (num-test (- 1.0 0.0 0) 1.0) (num-test (- 1.0 0.0 0.0) 1.0) (num-test (- 1.0 0.0 0.0+1.0i) 1.0-1.0i) (num-test (- 1.0 0.0 1) 0.0) (num-test (- 1.0 0.0 1.0) 0.0) (num-test (- 1.0 0.0 1.0+1.0i) 0.0-1.0i) (num-test (- 1.0 0.0 1.234+1.234i) -0.234-1.234i) (num-test (- 1.0 0.0 1/1) 0.0) (num-test (- 1.0 0.0 123.4) -122.4) (num-test (- 1.0 0.0 1234) -1233.0) (num-test (- 1.0 0.0 1234/11) -111.18181818181819) (num-test (- 1.0 0.0) 1.0) (num-test (- 1.0 0.0+1.0i -1.0+1.0i) 2.0-2.0i) (num-test (- 1.0 0.0+1.0i 0) 1.0-1.0i) (num-test (- 1.0 0.0+1.0i 0.0) 1.0-1.0i) (num-test (- 1.0 0.0+1.0i 0.0+1.0i) 1.0-2.0i) (num-test (- 1.0 0.0+1.0i 1) 0.0-1.0i) (num-test (- 1.0 0.0+1.0i 1.0) 0.0-1.0i) (num-test (- 1.0 0.0+1.0i 1.0+1.0i) 0.0-2.0i) (num-test (- 1.0 0.0+1.0i 1.234+1.234i) -0.234-2.234i) (num-test (- 1.0 0.0+1.0i 1/1) 0.0-1.0i) (num-test (- 1.0 0.0+1.0i 123.4) -122.4-1.0i) (num-test (- 1.0 0.0+1.0i 1234) -1233.0-1.0i) (num-test (- 1.0 0.0+1.0i 1234/11) -111.18181818181819-1.0i) (num-test (- 1.0 0.0+1.0i) 1.0-1.0i) (num-test (- 1.0 1 -1.0+1.0i) 1.0-1.0i) (num-test (- 1.0 1 0) 0.0) (num-test (- 1.0 1 0.0) 0.0) (num-test (- 1.0 1 0.0+1.0i) 0.0-1.0i) (num-test (- 1.0 1 1) -1.0) (num-test (- 1.0 1 1.0) -1.0) (num-test (- 1.0 1 1.0+1.0i) -1.0-1.0i) (num-test (- 1.0 1 1.234+1.234i) -1.234-1.234i) (num-test (- 1.0 1 1/1) -1.0) (num-test (- 1.0 1 123.4) -123.4) (num-test (- 1.0 1 1234) -1234.0) (num-test (- 1.0 1 1234/11) -112.18181818181819) (num-test (- 1.0 1) 0.0) (num-test (- 1.0 1.0 -1.0+1.0i) 1.0-1.0i) (num-test (- 1.0 1.0 0) 0.0) (num-test (- 1.0 1.0 0.0) 0.0) (num-test (- 1.0 1.0 0.0+1.0i) 0.0-1.0i) (num-test (- 1.0 1.0 1) -1.0) (num-test (- 1.0 1.0 1.0) -1.0) (num-test (- 1.0 1.0 1.0+1.0i) -1.0-1.0i) (num-test (- 1.0 1.0 1.234+1.234i) -1.234-1.234i) (num-test (- 1.0 1.0 1/1) -1.0) (num-test (- 1.0 1.0 123.4) -123.4) (num-test (- 1.0 1.0 1234) -1234.0) (num-test (- 1.0 1.0 1234/11) -112.18181818181819) (num-test (- 1.0 1.0) 0.0) (num-test (- 1.0 1.0+1.0i -1.0+1.0i) 1.0-2.0i) (num-test (- 1.0 1.0+1.0i 0) 0.0-1.0i) (num-test (- 1.0 1.0+1.0i 0.0) 0.0-1.0i) (num-test (- 1.0 1.0+1.0i 0.0+1.0i) 0.0-2.0i) (num-test (- 1.0 1.0+1.0i 1) -1.0-1.0i) (num-test (- 1.0 1.0+1.0i 1.0) -1.0-1.0i) (num-test (- 1.0 1.0+1.0i 1.0+1.0i) -1.0-2.0i) (num-test (- 1.0 1.0+1.0i 1.234+1.234i) -1.234-2.234i) (num-test (- 1.0 1.0+1.0i 1/1) -1.0-1.0i) (num-test (- 1.0 1.0+1.0i 123.4) -123.4-1.0i) (num-test (- 1.0 1.0+1.0i 1234) -1234.0-1.0i) (num-test (- 1.0 1.0+1.0i 1234/11) -112.18181818181819-1.0i) (num-test (- 1.0 1.0+1.0i) 0.0-1.0i) (num-test (- 1.0 1.234+1.234i -1.0+1.0i) 0.766-2.234i) (num-test (- 1.0 1.234+1.234i 0) -0.234-1.234i) (num-test (- 1.0 1.234+1.234i 0.0) -0.234-1.234i) (num-test (- 1.0 1.234+1.234i 0.0+1.0i) -0.234-2.234i) (num-test (- 1.0 1.234+1.234i 1) -1.234-1.234i) (num-test (- 1.0 1.234+1.234i 1.0) -1.234-1.234i) (num-test (- 1.0 1.234+1.234i 1.0+1.0i) -1.234-2.234i) (num-test (- 1.0 1.234+1.234i 1.234+1.234i) -1.468-2.468i) (num-test (- 1.0 1.234+1.234i 1/1) -1.234-1.234i) (num-test (- 1.0 1.234+1.234i 123.4) -123.634-1.234i) (num-test (- 1.0 1.234+1.234i 1234) -1234.23399999999992-1.234i) (num-test (- 1.0 1.234+1.234i 1234/11) -112.41581818181818-1.234i) (num-test (- 1.0 1.234+1.234i) -0.234-1.234i) (num-test (- 1.0 1/1 -1.0+1.0i) 1.0-1.0i) (num-test (- 1.0 123.4 -1.0+1.0i) -121.4-1.0i) (num-test (- 1.0 123.4 0) -122.4) (num-test (- 1.0 123.4 0.0) -122.4) (num-test (- 1.0 123.4 0.0+1.0i) -122.4-1.0i) (num-test (- 1.0 123.4 1) -123.4) (num-test (- 1.0 123.4 1.0) -123.4) (num-test (- 1.0 123.4 1.0+1.0i) -123.4-1.0i) (num-test (- 1.0 123.4 1.234+1.234i) -123.634-1.234i) (num-test (- 1.0 123.4 1/1) -123.4) (num-test (- 1.0 123.4 123.4) -245.8) (num-test (- 1.0 123.4 1234) -1356.4) (num-test (- 1.0 123.4 1234/11) -234.58181818181819) (num-test (- 1.0 123.4) -122.4) (num-test (- 1.0 1234 -1.0+1.0i) -1232.0-1.0i) (num-test (- 1.0 1234 0) -1233.0) (num-test (- 1.0 1234 0.0) -1233.0) (num-test (- 1.0 1234 0.0+1.0i) -1233.0-1.0i) (num-test (- 1.0 1234 1) -1234.0) (num-test (- 1.0 1234 1.0) -1234.0) (num-test (- 1.0 1234 1.0+1.0i) -1234.0-1.0i) (num-test (- 1.0 1234 1.234+1.234i) -1234.23399999999992-1.234i) (num-test (- 1.0 1234 1/1) -1234.0) (num-test (- 1.0 1234 123.4) -1356.4) (num-test (- 1.0 1234 1234) -2467.0) (num-test (- 1.0 1234 1234/11) -1345.18181818181824) (num-test (- 1.0 1234) -1233.0) (num-test (- 1.0 1234/11 -1.0+1.0i) -110.18181818181819-1.0i) (num-test (- 1.0 1234/11 0) -111.18181818181819) (num-test (- 1.0 1234/11 0.0) -111.18181818181819) (num-test (- 1.0 1234/11 0.0+1.0i) -111.18181818181819-1.0i) (num-test (- 1.0 1234/11 1) -112.18181818181819) (num-test (- 1.0 1234/11 1.0) -112.18181818181819) (num-test (- 1.0 1234/11 1.0+1.0i) -112.18181818181819-1.0i) (num-test (- 1.0 1234/11 1.234+1.234i) -112.41581818181818-1.234i) (num-test (- 1.0 1234/11 1/1) -112.18181818181819) (num-test (- 1.0 1234/11 123.4) -234.58181818181819) (num-test (- 1.0 1234/11 1234) -1345.18181818181824) (num-test (- 1.0 1234/11 1234/11) -223.36363636363637) (num-test (- 1.0 1234/11) -111.18181818181819) (num-test (- 1.0) -1.0) (num-test (- 1.0+1.0i -1.0+1.0i -1.0+1.0i) 3.0-1.0i) (num-test (- 1.0+1.0i -1.0+1.0i 0) 2.0) (num-test (- 1.0+1.0i -1.0+1.0i 0.0) 2.0) (num-test (- 1.0+1.0i -1.0+1.0i 0.0+1.0i) 2.0-1.0i) (num-test (- 1.0+1.0i -1.0+1.0i 1) 1.0) (num-test (- 1.0+1.0i -1.0+1.0i 1.0) 1.0) (num-test (- 1.0+1.0i -1.0+1.0i 1.0+1.0i) 1.0-1.0i) (num-test (- 1.0+1.0i -1.0+1.0i 1.234+1.234i) 0.766-1.234i) (num-test (- 1.0+1.0i -1.0+1.0i 1/1) 1.0) (num-test (- 1.0+1.0i -1.0+1.0i 123.4) -121.4) (num-test (- 1.0+1.0i -1.0+1.0i 1234) -1232.0) (num-test (- 1.0+1.0i -1.0+1.0i 1234/11) -110.18181818181819) (num-test (- 1.0+1.0i -1.0+1.0i) 2.0) (num-test (- 1.0+1.0i 0 -1.0+1.0i) 2.0) (num-test (- 1.0+1.0i 0 0) 1.0+1.0i) (num-test (- 1.0+1.0i 0 0.0) 1.0+1.0i) (num-test (- 1.0+1.0i 0 0.0+1.0i) 1.0) (num-test (- 1.0+1.0i 0 1) 0.0+1.0i) (num-test (- 1.0+1.0i 0 1.0) 0.0+1.0i) (num-test (- 1.0+1.0i 0 1.0+1.0i) 0.0) (num-test (- 1.0+1.0i 0 1.234+1.234i) -0.234-0.234i) (num-test (- 1.0+1.0i 0 1/1) 0.0+1.0i) (num-test (- 1.0+1.0i 0 123.4) -122.4+1.0i) (num-test (- 1.0+1.0i 0 1234) -1233.0+1.0i) (num-test (- 1.0+1.0i 0 1234/11) -111.18181818181819+1.0i) (num-test (- 1.0+1.0i 0) 1.0+1.0i) (num-test (- 1.0+1.0i 0.0 -1.0+1.0i) 2.0) (num-test (- 1.0+1.0i 0.0 0) 1.0+1.0i) (num-test (- 1.0+1.0i 0.0 0.0) 1.0+1.0i) (num-test (- 1.0+1.0i 0.0 0.0+1.0i) 1.0) (num-test (- 1.0+1.0i 0.0 1) 0.0+1.0i) (num-test (- 1.0+1.0i 0.0 1.0) 0.0+1.0i) (num-test (- 1.0+1.0i 0.0 1.0+1.0i) 0.0) (num-test (- 1.0+1.0i 0.0 1.234+1.234i) -0.234-0.234i) (num-test (- 1.0+1.0i 0.0 1/1) 0.0+1.0i) (num-test (- 1.0+1.0i 0.0 123.4) -122.4+1.0i) (num-test (- 1.0+1.0i 0.0 1234) -1233.0+1.0i) (num-test (- 1.0+1.0i 0.0 1234/11) -111.18181818181819+1.0i) (num-test (- 1.0+1.0i 0.0) 1.0+1.0i) (num-test (- 1.0+1.0i 0.0+1.0i -1.0+1.0i) 2.0-1.0i) (num-test (- 1.0+1.0i 0.0+1.0i 0) 1.0) (num-test (- 1.0+1.0i 0.0+1.0i 0.0) 1.0) (num-test (- 1.0+1.0i 0.0+1.0i 0.0+1.0i) 1.0-1.0i) (num-test (- 1.0+1.0i 0.0+1.0i 1) 0.0) (num-test (- 1.0+1.0i 0.0+1.0i 1.0) 0.0) (num-test (- 1.0+1.0i 0.0+1.0i 1.0+1.0i) 0.0-1.0i) (num-test (- 1.0+1.0i 0.0+1.0i 1.234+1.234i) -0.234-1.234i) (num-test (- 1.0+1.0i 0.0+1.0i 1/1) 0.0) (num-test (- 1.0+1.0i 0.0+1.0i 123.4) -122.4) (num-test (- 1.0+1.0i 0.0+1.0i 1234) -1233.0) (num-test (- 1.0+1.0i 0.0+1.0i 1234/11) -111.18181818181819) (num-test (- 1.0+1.0i 0.0+1.0i) 1.0) (num-test (- 1.0+1.0i 1 -1.0+1.0i) 1.0) (num-test (- 1.0+1.0i 1 0) 0.0+1.0i) (num-test (- 1.0+1.0i 1 0.0) 0.0+1.0i) (num-test (- 1.0+1.0i 1 0.0+1.0i) 0.0) (num-test (- 1.0+1.0i 1 1) -1.0+1.0i) (num-test (- 1.0+1.0i 1 1.0) -1.0+1.0i) (num-test (- 1.0+1.0i 1 1.0+1.0i) -1.0) (num-test (- 1.0+1.0i 1 1.234+1.234i) -1.234-0.234i) (num-test (- 1.0+1.0i 1 1/1) -1.0+1.0i) (num-test (- 1.0+1.0i 1 123.4) -123.4+1.0i) (num-test (- 1.0+1.0i 1 1234) -1234.0+1.0i) (num-test (- 1.0+1.0i 1 1234/11) -112.18181818181819+1.0i) (num-test (- 1.0+1.0i 1) 0.0+1.0i) (num-test (- 1.0+1.0i 1.0 -1.0+1.0i) 1.0) (num-test (- 1.0+1.0i 1.0 0) 0.0+1.0i) (num-test (- 1.0+1.0i 1.0 0.0) 0.0+1.0i) (num-test (- 1.0+1.0i 1.0 0.0+1.0i) 0.0) (num-test (- 1.0+1.0i 1.0 1) -1.0+1.0i) (num-test (- 1.0+1.0i 1.0 1.0) -1.0+1.0i) (num-test (- 1.0+1.0i 1.0 1.0+1.0i) -1.0) (num-test (- 1.0+1.0i 1.0 1.234+1.234i) -1.234-0.234i) (num-test (- 1.0+1.0i 1.0 1/1) -1.0+1.0i) (num-test (- 1.0+1.0i 1.0 123.4) -123.4+1.0i) (num-test (- 1.0+1.0i 1.0 1234) -1234.0+1.0i) (num-test (- 1.0+1.0i 1.0 1234/11) -112.18181818181819+1.0i) (num-test (- 1.0+1.0i 1.0) 0.0+1.0i) (num-test (- 1.0+1.0i 1.0+1.0i -1.0+1.0i) 1.0-1.0i) (num-test (- 1.0+1.0i 1.0+1.0i 0) 0.0) (num-test (- 1.0+1.0i 1.0+1.0i 0.0) 0.0) (num-test (- 1.0+1.0i 1.0+1.0i 0.0+1.0i) 0.0-1.0i) (num-test (- 1.0+1.0i 1.0+1.0i 1) -1.0) (num-test (- 1.0+1.0i 1.0+1.0i 1.0) -1.0) (num-test (- 1.0+1.0i 1.0+1.0i 1.0+1.0i) -1.0-1.0i) (num-test (- 1.0+1.0i 1.0+1.0i 1.234+1.234i) -1.234-1.234i) (num-test (- 1.0+1.0i 1.0+1.0i 1/1) -1.0) (num-test (- 1.0+1.0i 1.0+1.0i 123.4) -123.4) (num-test (- 1.0+1.0i 1.0+1.0i 1234) -1234.0) (num-test (- 1.0+1.0i 1.0+1.0i 1234/11) -112.18181818181819) (num-test (- 1.0+1.0i 1.0+1.0i) 0.0) (num-test (- 1.0+1.0i 1.234+1.234i -1.0+1.0i) 0.766-1.234i) (num-test (- 1.0+1.0i 1.234+1.234i 0) -0.234-0.234i) (num-test (- 1.0+1.0i 1.234+1.234i 0.0) -0.234-0.234i) (num-test (- 1.0+1.0i 1.234+1.234i 0.0+1.0i) -0.234-1.234i) (num-test (- 1.0+1.0i 1.234+1.234i 1) -1.234-0.234i) (num-test (- 1.0+1.0i 1.234+1.234i 1.0) -1.234-0.234i) (num-test (- 1.0+1.0i 1.234+1.234i 1.0+1.0i) -1.234-1.234i) (num-test (- 1.0+1.0i 1.234+1.234i 1.234+1.234i) -1.468-1.468i) (num-test (- 1.0+1.0i 1.234+1.234i 1/1) -1.234-0.234i) (num-test (- 1.0+1.0i 1.234+1.234i 123.4) -123.634-0.234i) (num-test (- 1.0+1.0i 1.234+1.234i 1234) -1234.23399999999992-0.234i) (num-test (- 1.0+1.0i 1.234+1.234i 1234/11) -112.41581818181818-0.234i) (num-test (- 1.0+1.0i 1.234+1.234i) -0.234-0.234i) (num-test (- 1.0+1.0i 1/1 -1.0+1.0i) 1.0) (num-test (- 1.0+1.0i 123.4 -1.0+1.0i) -121.4) (num-test (- 1.0+1.0i 123.4 0) -122.4+1.0i) (num-test (- 1.0+1.0i 123.4 0.0) -122.4+1.0i) (num-test (- 1.0+1.0i 123.4 0.0+1.0i) -122.4) (num-test (- 1.0+1.0i 123.4 1) -123.4+1.0i) (num-test (- 1.0+1.0i 123.4 1.0) -123.4+1.0i) (num-test (- 1.0+1.0i 123.4 1.0+1.0i) -123.4) (num-test (- 1.0+1.0i 123.4 1.234+1.234i) -123.634-0.234i) (num-test (- 1.0+1.0i 123.4 1/1) -123.4+1.0i) (num-test (- 1.0+1.0i 123.4 123.4) -245.8+1.0i) (num-test (- 1.0+1.0i 123.4 1234) -1356.4+1.0i) (num-test (- 1.0+1.0i 123.4 1234/11) -234.58181818181819+1.0i) (num-test (- 1.0+1.0i 123.4) -122.4+1.0i) (num-test (- 1.0+1.0i 1234 -1.0+1.0i) -1232.0) (num-test (- 1.0+1.0i 1234 0) -1233.0+1.0i) (num-test (- 1.0+1.0i 1234 0.0) -1233.0+1.0i) (num-test (- 1.0+1.0i 1234 0.0+1.0i) -1233.0) (num-test (- 1.0+1.0i 1234 1) -1234.0+1.0i) (num-test (- 1.0+1.0i 1234 1.0) -1234.0+1.0i) (num-test (- 1.0+1.0i 1234 1.0+1.0i) -1234.0) (num-test (- 1.0+1.0i 1234 1.234+1.234i) -1234.23399999999992-0.234i) (num-test (- 1.0+1.0i 1234 1/1) -1234.0+1.0i) (num-test (- 1.0+1.0i 1234 123.4) -1356.4+1.0i) (num-test (- 1.0+1.0i 1234 1234) -2467.0+1.0i) (num-test (- 1.0+1.0i 1234 1234/11) -1345.18181818181824+1.0i) (num-test (- 1.0+1.0i 1234) -1233.0+1.0i) (num-test (- 1.0+1.0i 1234/11 -1.0+1.0i) -110.18181818181819) (num-test (- 1.0+1.0i 1234/11 0) -111.18181818181819+1.0i) (num-test (- 1.0+1.0i 1234/11 0.0) -111.18181818181819+1.0i) (num-test (- 1.0+1.0i 1234/11 0.0+1.0i) -111.18181818181819) (num-test (- 1.0+1.0i 1234/11 1) -112.18181818181819+1.0i) (num-test (- 1.0+1.0i 1234/11 1.0) -112.18181818181819+1.0i) (num-test (- 1.0+1.0i 1234/11 1.0+1.0i) -112.18181818181819) (num-test (- 1.0+1.0i 1234/11 1.234+1.234i) -112.41581818181818-0.234i) (num-test (- 1.0+1.0i 1234/11 1/1) -112.18181818181819+1.0i) (num-test (- 1.0+1.0i 1234/11 123.4) -234.58181818181819+1.0i) (num-test (- 1.0+1.0i 1234/11 1234) -1345.18181818181824+1.0i) (num-test (- 1.0+1.0i 1234/11 1234/11) -223.36363636363637+1.0i) (num-test (- 1.0+1.0i 1234/11) -111.18181818181819+1.0i) (num-test (- 1.0+1.0i) -1.0-1.0i) (num-test (- 1.234+1.234i -1.0+1.0i) 2.234+0.234i) (num-test (- 1.234+1.234i 0) 1.234+1.234i) (num-test (- 1.234+1.234i 0.0) 1.234+1.234i) (num-test (- 1.234+1.234i 0.0+1.0i) 1.234+0.234i) (num-test (- 1.234+1.234i 1) 0.234+1.234i) (num-test (- 1.234+1.234i 1.0) 0.234+1.234i) (num-test (- 1.234+1.234i 1.0+1.0i) 0.234+0.234i) (num-test (- 1.234+1.234i 1.234+1.234i) 0.0) (num-test (- 1.234+1.234i 1/1) 0.234+1.234i) (num-test (- 1.234+1.234i 123.4) -122.16600000000001+1.234i) (num-test (- 1.234+1.234i 1234) -1232.766+1.234i) (num-test (- 1.234+1.234i 1234/11) -110.94781818181818+1.234i) (num-test (- 10) -10) (num-test (- 10/3) -10/3) (num-test (- 123.4 -1.0+1.0i -1.0+1.0i) 125.4-2.0i) (num-test (- 123.4 -1.0+1.0i 0) 124.4-1.0i) (num-test (- 123.4 -1.0+1.0i 0.0) 124.4-1.0i) (num-test (- 123.4 -1.0+1.0i 0.0+1.0i) 124.4-2.0i) (num-test (- 123.4 -1.0+1.0i 1) 123.4-1.0i) (num-test (- 123.4 -1.0+1.0i 1.0) 123.4-1.0i) (num-test (- 123.4 -1.0+1.0i 1.0+1.0i) 123.4-2.0i) (num-test (- 123.4 -1.0+1.0i 1.234+1.234i) 123.16600000000001-2.234i) (num-test (- 123.4 -1.0+1.0i 1/1) 123.4-1.0i) (num-test (- 123.4 -1.0+1.0i 123.4) 1.0-1.0i) (num-test (- 123.4 -1.0+1.0i 1234) -1109.59999999999991-1.0i) (num-test (- 123.4 -1.0+1.0i 1234/11) 12.21818181818182-1.0i) (num-test (- 123.4 -1.0+1.0i) 124.4-1.0i) (num-test (- 123.4 0 -1.0+1.0i) 124.4-1.0i) (num-test (- 123.4 0 0) 123.4) (num-test (- 123.4 0 0.0) 123.4) (num-test (- 123.4 0 0.0+1.0i) 123.4-1.0i) (num-test (- 123.4 0 1) 122.4) (num-test (- 123.4 0 1.0) 122.4) (num-test (- 123.4 0 1.0+1.0i) 122.4-1.0i) (num-test (- 123.4 0 1.234+1.234i) 122.16600000000001-1.234i) (num-test (- 123.4 0 1/1) 122.4) (num-test (- 123.4 0 123.4) 0.0) (num-test (- 123.4 0 1234) -1110.59999999999991) (num-test (- 123.4 0 1234/11) 11.21818181818182) (num-test (- 123.4 0) 123.4) (num-test (- 123.4 0.0 -1.0+1.0i) 124.4-1.0i) (num-test (- 123.4 0.0 0) 123.4) (num-test (- 123.4 0.0 0.0) 123.4) (num-test (- 123.4 0.0 0.0+1.0i) 123.4-1.0i) (num-test (- 123.4 0.0 1) 122.4) (num-test (- 123.4 0.0 1.0) 122.4) (num-test (- 123.4 0.0 1.0+1.0i) 122.4-1.0i) (num-test (- 123.4 0.0 1.234+1.234i) 122.16600000000001-1.234i) (num-test (- 123.4 0.0 1/1) 122.4) (num-test (- 123.4 0.0 123.4) 0.0) (num-test (- 123.4 0.0 1234) -1110.59999999999991) (num-test (- 123.4 0.0 1234/11) 11.21818181818182) (num-test (- 123.4 0.0) 123.4) (num-test (- 123.4 0.0+1.0i -1.0+1.0i) 124.4-2.0i) (num-test (- 123.4 0.0+1.0i 0) 123.4-1.0i) (num-test (- 123.4 0.0+1.0i 0.0) 123.4-1.0i) (num-test (- 123.4 0.0+1.0i 0.0+1.0i) 123.4-2.0i) (num-test (- 123.4 0.0+1.0i 1) 122.4-1.0i) (num-test (- 123.4 0.0+1.0i 1.0) 122.4-1.0i) (num-test (- 123.4 0.0+1.0i 1.0+1.0i) 122.4-2.0i) (num-test (- 123.4 0.0+1.0i 1.234+1.234i) 122.16600000000001-2.234i) (num-test (- 123.4 0.0+1.0i 1/1) 122.4-1.0i) (num-test (- 123.4 0.0+1.0i 123.4) 0.0-1.0i) (num-test (- 123.4 0.0+1.0i 1234) -1110.59999999999991-1.0i) (num-test (- 123.4 0.0+1.0i 1234/11) 11.21818181818182-1.0i) (num-test (- 123.4 0.0+1.0i) 123.4-1.0i) (num-test (- 123.4 1 -1.0+1.0i) 123.4-1.0i) (num-test (- 123.4 1 0) 122.4) (num-test (- 123.4 1 0.0) 122.4) (num-test (- 123.4 1 0.0+1.0i) 122.4-1.0i) (num-test (- 123.4 1 1) 121.4) (num-test (- 123.4 1 1.0) 121.4) (num-test (- 123.4 1 1.0+1.0i) 121.4-1.0i) (num-test (- 123.4 1 1.234+1.234i) 121.16600000000001-1.234i) (num-test (- 123.4 1 1/1) 121.4) (num-test (- 123.4 1 123.4) -1.0) (num-test (- 123.4 1 1234) -1111.59999999999991) (num-test (- 123.4 1 1234/11) 10.21818181818182) (num-test (- 123.4 1) 122.4) (num-test (- 123.4 1.0 -1.0+1.0i) 123.4-1.0i) (num-test (- 123.4 1.0 0) 122.4) (num-test (- 123.4 1.0 0.0) 122.4) (num-test (- 123.4 1.0 0.0+1.0i) 122.4-1.0i) (num-test (- 123.4 1.0 1) 121.4) (num-test (- 123.4 1.0 1.0) 121.4) (num-test (- 123.4 1.0 1.0+1.0i) 121.4-1.0i) (num-test (- 123.4 1.0 1.234+1.234i) 121.16600000000001-1.234i) (num-test (- 123.4 1.0 1/1) 121.4) (num-test (- 123.4 1.0 123.4) -1.0) (num-test (- 123.4 1.0 1234) -1111.59999999999991) (num-test (- 123.4 1.0 1234/11) 10.21818181818182) (num-test (- 123.4 1.0) 122.4) (num-test (- 123.4 1.0+1.0i -1.0+1.0i) 123.4-2.0i) (num-test (- 123.4 1.0+1.0i 0) 122.4-1.0i) (num-test (- 123.4 1.0+1.0i 0.0) 122.4-1.0i) (num-test (- 123.4 1.0+1.0i 0.0+1.0i) 122.4-2.0i) (num-test (- 123.4 1.0+1.0i 1) 121.4-1.0i) (num-test (- 123.4 1.0+1.0i 1.0) 121.4-1.0i) (num-test (- 123.4 1.0+1.0i 1.0+1.0i) 121.4-2.0i) (num-test (- 123.4 1.0+1.0i 1.234+1.234i) 121.16600000000001-2.234i) (num-test (- 123.4 1.0+1.0i 1/1) 121.4-1.0i) (num-test (- 123.4 1.0+1.0i 123.4) -1.0-1.0i) (num-test (- 123.4 1.0+1.0i 1234) -1111.59999999999991-1.0i) (num-test (- 123.4 1.0+1.0i 1234/11) 10.21818181818182-1.0i) (num-test (- 123.4 1.0+1.0i) 122.4-1.0i) (num-test (- 123.4 1.234+1.234i -1.0+1.0i) 123.16600000000001-2.234i) (num-test (- 123.4 1.234+1.234i 0) 122.16600000000001-1.234i) (num-test (- 123.4 1.234+1.234i 0.0) 122.16600000000001-1.234i) (num-test (- 123.4 1.234+1.234i 0.0+1.0i) 122.16600000000001-2.234i) (num-test (- 123.4 1.234+1.234i 1) 121.16600000000001-1.234i) (num-test (- 123.4 1.234+1.234i 1.0) 121.16600000000001-1.234i) (num-test (- 123.4 1.234+1.234i 1.0+1.0i) 121.16600000000001-2.234i) (num-test (- 123.4 1.234+1.234i 1.234+1.234i) 120.93200000000002-2.468i) (num-test (- 123.4 1.234+1.234i 1/1) 121.16600000000001-1.234i) (num-test (- 123.4 1.234+1.234i 123.4) -1.23399999999999-1.234i) (num-test (- 123.4 1.234+1.234i 1234) -1111.83400000000006-1.234i) (num-test (- 123.4 1.234+1.234i 1234/11) 9.98418181818183-1.234i) (num-test (- 123.4 1.234+1.234i) 122.16600000000001-1.234i) (num-test (- 123.4 1/1 -1.0+1.0i) 123.4-1.0i) (num-test (- 123.4 123.4 -1.0+1.0i) 1.0-1.0i) (num-test (- 123.4 123.4 0) 0.0) (num-test (- 123.4 123.4 0.0) 0.0) (num-test (- 123.4 123.4 0.0+1.0i) 0.0-1.0i) (num-test (- 123.4 123.4 1) -1.0) (num-test (- 123.4 123.4 1.0) -1.0) (num-test (- 123.4 123.4 1.0+1.0i) -1.0-1.0i) (num-test (- 123.4 123.4 1.234+1.234i) -1.234-1.234i) (num-test (- 123.4 123.4 1/1) -1.0) (num-test (- 123.4 123.4 123.4) -123.4) (num-test (- 123.4 123.4 1234) -1234.0) (num-test (- 123.4 123.4 1234/11) -112.18181818181819) (num-test (- 123.4 123.4) 0.0) (num-test (- 123.4 1234 -1.0+1.0i) -1109.59999999999991-1.0i) (num-test (- 123.4 1234 0) -1110.59999999999991) (num-test (- 123.4 1234 0.0) -1110.59999999999991) (num-test (- 123.4 1234 0.0+1.0i) -1110.59999999999991-1.0i) (num-test (- 123.4 1234 1) -1111.59999999999991) (num-test (- 123.4 1234 1.0) -1111.59999999999991) (num-test (- 123.4 1234 1.0+1.0i) -1111.59999999999991-1.0i) (num-test (- 123.4 1234 1.234+1.234i) -1111.83399999999983-1.234i) (num-test (- 123.4 1234 1/1) -1111.59999999999991) (num-test (- 123.4 1234 123.4) -1234.0) (num-test (- 123.4 1234 1234) -2344.59999999999991) (num-test (- 123.4 1234 1234/11) -1222.78181818181815) (num-test (- 123.4 1234) -1110.59999999999991) (num-test (- 123.4 1234/11 -1.0+1.0i) 12.21818181818182-1.0i) (num-test (- 123.4 1234/11 0) 11.21818181818182) (num-test (- 123.4 1234/11 0.0) 11.21818181818182) (num-test (- 123.4 1234/11 0.0+1.0i) 11.21818181818182-1.0i) (num-test (- 123.4 1234/11 1) 10.21818181818182) (num-test (- 123.4 1234/11 1.0) 10.21818181818182) (num-test (- 123.4 1234/11 1.0+1.0i) 10.21818181818182-1.0i) (num-test (- 123.4 1234/11 1.234+1.234i) 9.98418181818182-1.234i) (num-test (- 123.4 1234/11 1/1) 10.21818181818182) (num-test (- 123.4 1234/11 123.4) -112.18181818181819) (num-test (- 123.4 1234/11 1234) -1222.78181818181815) (num-test (- 123.4 1234/11 1234/11) -100.96363636363635) (num-test (- 123.4 1234/11) 11.21818181818182) (num-test (- 1234 -1.0+1.0i) 1235.0-1.0i) (num-test (- 1234 0) 1234) (num-test (- 1234 0.0) 1234.0) (num-test (- 1234 0.0+1.0i) 1234.0-1.0i) (num-test (- 1234 1) 1233) (num-test (- 1234 1.0) 1233.0) (num-test (- 1234 1.0+1.0i) 1233.0-1.0i) (num-test (- 1234 1.234+1.234i) 1232.766-1.234i) (num-test (- 1234 1/1) 1233) (num-test (- 1234 123.4) 1110.59999999999991) (num-test (- 1234 1234) 0) (num-test (- 1234 1234/11) 12340/11) (num-test (- 1234/11 -1.0+1.0i) 113.18181818181819-1.0i) (num-test (- 1234/11 0) 1234/11) (num-test (- 1234/11 0.0) 112.18181818181819) (num-test (- 1234/11 0.0+1.0i) 112.18181818181819-1.0i) (num-test (- 1234/11 1) 1223/11) (num-test (- 1234/11 1.0) 111.18181818181819) (num-test (- 1234/11 1.0+1.0i) 111.18181818181819-1.0i) (num-test (- 1234/11 1.234+1.234i) 110.94781818181819-1.234i) (num-test (- 1234/11 1/1) 1223/11) (num-test (- 1234/11 123.4) -11.21818181818182) (num-test (- 1234/11 1234) -12340/11) (num-test (- 1234/11 1234/11) 0) (num-test (- 1234000000) -1234000000) (num-test (- 1234000000.0) -1234000000.0) (num-test (- 1234000000.0+2.71828182845905i) -1234000000.0-2.71828182845905i) (num-test (- 1234000000.0-2.71828182845905i) -1234000000.0+2.71828182845905i) (num-test (- 1234000000/10) -1234000000/10) (num-test (- 2) -2) (num-test (- 2.71828182845905) -2.71828182845905) (num-test (- 2.71828182845905+3.14159265358979i) -2.71828182845905-3.14159265358979i) (num-test (- 2.71828182845905-3.14159265358979i) -2.71828182845905+3.14159265358979i) (num-test (- 2/2) -2/2) (num-test (- 362880) -362880) (num-test (- 362880/1234) -362880/1234) (num-test (- 0+6i 1/4 0.5 7) -7.75+6.0i) (num-test (- 1/2 0.5e0) 0.0e0) (num-test (- 100000000000000.0 100000000000001.0) -1.0) (num-test (- 1000000000000000000/3 1000000000000000001/3) -1/3) (num-test (- 3 0 3 5 -6) 1) (num-test (- 3 4) -1 ) (num-test (- 3) -3 ) (call-with-exit (lambda (ok) (for-each-permutation (lambda args (when (not (morally-equal? (apply - args) (- (car args) (apply + (cdr args))))) (format-logged #t "~A: ~A != ~A?~%" (port-line-number) (apply - args) (- (car args) (apply + (cdr args)))) (ok))) '(1 1/2 0.5 1+i)))) (call-with-exit (lambda (ok) (for-each-permutation (lambda args (when (not (morally-equal? (apply - args) (+ (car args) (- (apply + (cdr args)))))) (format-logged #t "~A: (- ~{~A~^ ~}) -> ~A?~%" (port-line-number) args (apply - args)) (ok))) '(1 1/2 0.5 1+i -1/2 -1 -0.5 -1-i)))) (num-test (- -1.797693134862315699999999999999999999998E308 -9223372036854775808) -1.797693134862315699999999999999999999998E308) (num-test (- -9223372036854775808 -9223372036854775808) 0) (num-test (- -9223372036854775808 5.551115123125783999999999999999999999984E-17) -9.223372036854775808000000000000000055511E18) (num-test (- -9223372036854775808 9223372036854775807 -9223372036854775808) -9223372036854775807) (if with-bignums (num-test (- -9223372036854775808) 9223372036854775808)) (num-test (- 1.110223024625156799999999999999999999997E-16 -9223372036854775808) 9.223372036854775808000000000000000111022E18) (num-test (- 1.110223024625156799999999999999999999997E-16 5.551115123125783999999999999999999999984E-17 5.42101086242752217060000000000000000001E-20) 5.545694112263356477829399999999999999977E-17) (num-test (- 5.551115123125783999999999999999999999984E-17 1.110223024625156799999999999999999999997E-16) -5.551115123125783999999999999999999999984E-17) (num-test (- 9223372036854775807 9223372036854775807) 0) (num-test (- .(1.1)) -1.1) (num-test (- 1. .()) -1.0) (num-test (- 1/9223372036854775807 1/9223372036854775807) 0) (num-test (- 1/98947 2/97499 3/76847) -36656755224/741360956847391) (num-test (- 500009/500029 500057/500041) -18001284/250035001189) (if (not with-bignums) (begin (num-test (- 8 -1/9223372036854775807 1/9223372036854775807) 8.0) ; (num-test (- most-positive-fixnum most-negative-fixnum) 1.8446744073709551615E19) ; (num-test (- most-negative-fixnum most-positive-fixnum) -1.8446744073709551615E19) ;;; currently s7's optimizer screws up these cases )) (num-test (- -0.011326914400453525E0 -0.6668141757661364E0) 6.554872613656828749999999999999999999976E-1) (num-test (- -0.46185382764946437E0 0.7488210697846337E0) -1.210674897434098070000000000000000000001E0) (num-test (- -0.35834120541234993E0 -0.30919976341834987E0) -4.914144199400005999999999999999999999972E-2) (num-test (- 0.44705025064976966E0 -0.9277893553610955E0) 1.374839606010865160000000000000000000002E0) (num-test (- -0.47647537517067917E0 0.29158058381073604E0) -7.680559589814152099999999999999999999997E-1) (num-test (- -0.021697999002707746E0 0.1779871773524142E0) -1.996851763551219460000000000000000000001E-1) (num-test (- 0.4179484378019861E0 9.9990307469939E9) -9.999030746575951861270279525000000000019E9) (num-test (- -0.7475415524823718E0 1.3993312799214797E9) -1.399331280669021252482371799999999999998E9) (num-test (- 0.2519442433861928E0 -6.699632771871848E9) 6.699632772123792243386192799999999999993E9) (num-test (- -0.5124988631497671E0 2.7959244812290273E9) -2.795924481741526163149767100000000000009E9) (num-test (- -0.6870193827604301E0 4.851102442573468E9) -4.851102443260487591073418381249999999995E9) (num-test (- 0.7609656780357723E0 7.481252865855436E8) -7.481252858245779544715519187499999999991E8) (num-test (- -0.6301276042170191E0 -7.099314875214215E-11) -6.301276041460259512478578500000000000002E-1) (num-test (- -0.4139053484357884E0 -2.897413526398709E-11) -4.139053484068142647360129100000000000006E-1) (num-test (- -0.6944623060197281E0 -3.291569879873739E-11) -6.94462305986812401201262610000000000001E-1) (num-test (- -0.2057822500703933E0 3.6505182026159854E-11) -2.057822501068984820261598540000000000004E-1) (num-test (- -0.8792706674467908E0 8.094527736950817E-11) -8.792706675277360773695081699999999999978E-1) (num-test (- -0.6888184243601332E0 9.127622796988807E-11) -6.888184244514094279698880700000000000006E-1) (num-test (- -0.980711030497252E0 8.752272461345245E19) -8.752272461345245000098071103049725200009E19) (num-test (- 0.8035082489836539E0 -3.903355151264917E19) 3.90335515126491700008035082489836539001E19) (num-test (- -0.7537841372394811E0 -5.879942447417834E19) 5.879942447417833999924621586276051889998E19) (num-test (- -0.6877475951546845E0 -2.3972266191169642E19) 2.397226619116964199931225240484531550001E19) (num-test (- -0.43128282112433525E0 -5.422824998003439E19) 5.422824998003438999956871717887566474998E19) (num-test (- 0.29538116818276694E0 1.1291858990580939E19) -1.129185899058093899970461883181723306002E19) (num-test (- 0.9166687388673976E0 6.395175407123937E-21) 9.166687388673975999936048245928760629984E-1) (num-test (- 0.41840538498193025E0 -2.6655662412599155E-21) 4.18405384981930250002665566241259915501E-1) (num-test (- -0.8036940092501853E0 6.7473779576832565E-21) -8.036940092501853000067473779576832565009E-1) (num-test (- 0.8555054025209989E0 -7.939970418096797E-21) 8.55505402520998900007939970418096796999E-1) (num-test (- 0.3365495704567003E0 8.694519827555395E-21) 3.365495704567002999913054801724446050001E-1) (num-test (- -0.7430322011471231E0 7.430332379292914E-22) -7.430322011471231000007430332379292914019E-1) (num-test (- 5.102372414731216E9 -0.5073635765350494E0) 5.102372415238580007199111899999999999994E9) (num-test (- 4.629827365822252E9 0.6534380055543355E0) 4.629827365168814268005234812499999999993E9) (num-test (- 7.218192507117569E9 0.9781542046565127E0) 7.21819250613941476507004979999999999999E9) (num-test (- 6.595760326622413E8 0.7339510561932947E0) 6.595760319282902834902380148437500000014E8) (num-test (- 7.191166637703489E9 0.80792475493853E0) 7.191166636895564548650337188817616151937E9) (num-test (- -7.95531405213956E9 0.5353636841430115E0) -7.955314052674923429931585718750000000006E9) (num-test (- 5.438904545553836E8 6.533536518165114E9) -5.98964606360973083972930908203125E9) (num-test (- -7.389650313101625E8 -9.983943153365381E9) 9.244978122055218499999999999999999999979E9) (num-test (- 8.364404619492165E9 -7.600563055115287E9) 1.596496767460745161181640624999999999997E10) (num-test (- 2.070813748323649E9 6.421052769114957E9) -4.350239020791307926177978515625E9) (num-test (- -2.8555256820439434E9 -3.4077342921686625E8) -2.514752252827077150000000000000000000005E9) (num-test (- 9.147878229420991E8 8.439982790150545E9) -7.525194967208446025848388671875E9) (num-test (- -4.315772980070098E9 -6.48869466068404E-11) -4.315772980070097999935113053393159599999E9) (num-test (- -3.5186299785635023E9 3.990046539849716E-11) -3.518629978563502300039900465398497159997E9) (num-test (- 2.5645532837267537E9 8.566645694205622E-13) 2.564553283726753699999143335430579437802E9) (num-test (- 6.145110896031829E9 -9.242734002954773E-11) 6.145110896031828880402485933779547730013E9) (num-test (- -6.6836855975624E9 9.117930361283473E-11) -6.683685597562399864287956647362834729995E9) (num-test (- -1.7472828462085754E8 -5.125838712019503E-11) -1.747282846208575399487416128798049699998E8) (num-test (- 9.05675399397055E9 9.086705650502484E19) -9.0867056495968086006029449462890625E19) (num-test (- -5.834806594586836E9 9.981576053842906E19) -9.981576054426386659458683599999999999999E19) (num-test (- 3.047010922754272E9 1.1715352070471352E19) -1.171535206742434107724572801589965820312E19) (num-test (- 7.294295638574767E9 2.845702947515113E19) -2.845702946785683436142523288726806640625E19) (num-test (- 8.264143132493019E9 -1.6322956072452289E19) 1.632295608071643213249301910400390625E19) (num-test (- -9.597823287256088E9 3.954126758718671E19) -3.95412675967845332872560880000000000001E19) (num-test (- 3.229389511771705E9 -4.329831377266493E-21) 3.229389511771705150604248046879329831377E9) (num-test (- 6.897089200279753E9 2.4428208790287663E-21) 6.897089200279752731323242187497557179116E9) (num-test (- 2.3579775300187545E9 4.729400988996349E-21) 2.357977530018754499999999999995270599018E9) (num-test (- 1.6718929117460046E9 5.8162277016717065E-21) 1.671892911746004599999999999994183772301E9) (num-test (- 2.537177500868296E9 1.4856605280697543E-21) 2.537177500868296146392822265623514339469E9) (num-test (- 6.117674696930935E9 -1.6187214719634357E-21) 6.117674696930934906005859375001618721474E9) (num-test (- 4.1877888304549216E-11 -0.06920550501017497E0) 6.920550505205285830454921600000000000007E-2) (num-test (- 9.61054846124015E-11 0.885309193732889E0) -8.85309193636783481398417376384291797877E-1) (num-test (- 2.5559085051828467E-11 -0.8112181469812297E0) 8.112181470067887850518284670000000000006E-1) (num-test (- -1.4549570208293283E-12 -0.5049325945871657E0) 5.049325945857107429791706717000000000005E-1) (num-test (- -7.091628047158497E-11 0.61946884965934E0) -6.194688497302562955729347334266968816526E-1) (num-test (- 2.877466355456826E-11 0.4496491857374E0) -4.49649185708625317645189543551619872451E-1) (num-test (- 1.3041612488449928E-12 5.408018587130755E9) -5.40801858713075542449820755750115500719E9) (num-test (- -5.379752339715717E-11 -4.009594691514288E9) 4.009594691514287999946202476602842829998E9) (num-test (- 7.023042501342336E-12 -3.4153434285746374E9) 3.415343428574637400007023042501342336004E9) (num-test (- 6.968174934871611E-11 4.713087404332662E9) -4.713087404332661628653462781901283890003E9) (num-test (- -5.153562653896506E-11 -8.44732228013254E8) 8.447322280132540463885888851797849400006E8) (num-test (- -8.424177457818745E-11 1.6817117809824567E9) -1.681711780982456700084241774578187449998E9) (num-test (- 3.374755984316538E-11 8.893678266883364E-11) -5.518922282566826000000000000000000000009E-11) (num-test (- -8.684123447823306E-11 -7.888825869147879E-11) -7.952975786754269999999999999999999999987E-12) (num-test (- 7.788477523205632E-11 1.741674745286914E-11) 6.046802777918717999999999999999999999988E-11) (num-test (- 6.546622477606044E-11 -4.7719651007530584E-11) 1.131858757835910240000000000000000000001E-10) (num-test (- -1.8595152377503265E-11 5.7288738553553045E-11) -7.588389093105630999999999999999999999984E-11) (num-test (- -8.184033550427558E-11 -8.834399228929296E-11) 6.503656785017380000000000000000000000234E-12) (num-test (- 5.749469292140762E-11 7.493129199779113E19) -7.493129199779112999999999999994250530697E19) (num-test (- -5.2285095120702066E-11 -2.0611179974216552E19) 2.061117997421655199999999999994771490491E19) (num-test (- -8.84727820032067E-11 4.7423077384022024E19) -4.742307738402202400000000000008847278205E19) (num-test (- 3.437676989338625E-11 -3.5368755480277647E19) 3.536875548027764700000000000003437676988E19) (num-test (- 2.2665031619145437E-11 -6.072845659234921E19) 6.072845659234921000000000000002266503153E19) (num-test (- -8.429070146313393E-11 5.134329153614969E18) -5.134329153614969000000000000084290701453E18) (num-test (- -9.009531819191212E-11 2.301790665456671E-22) -9.009531819214229906654566710000000000025E-11) (num-test (- -2.706942469371907E-11 9.282350542107287E-21) -2.706942470300142054210728700000000000001E-11) (num-test (- 5.358266626996117E-11 -4.409057695582885E-22) 5.358266627040207576955828850000000000004E-11) (num-test (- -7.189537285608088E-11 9.569273217393917E-21) -7.189537286565015321739391700000000000027E-11) (num-test (- -4.160295905335358E-11 5.930867524794025E-21) -4.160295905928444752479402499999999999992E-11) (num-test (- 6.7922062777334035E-12 -7.747524338474154E-22) 6.792206278508155933847415400000000000006E-12) (num-test (- -9.038821102045805E19 0.04779131019959271E0) -9.038821102045805000004779131019959271002E19) (num-test (- 2.2020595055495963E19 -0.424631558292516E0) 2.202059505549596300042463155829251600002E19) (num-test (- -8.164003027214308E19 0.6832198147365239E0) -8.164003027214308000068321981473652389997E19) (num-test (- -3.878233560364984E19 -0.28756619113600546E0) -3.878233560364983999971243380886399453999E19) (num-test (- 7.0829003521450525E19 -0.6071548125948544E0) 7.08290035214505250006071548125948544E19) (num-test (- 5.968540808784698E19 0.7674294173432648E0) 5.968540808784697999923257058265673519995E19) (num-test (- -2.2143621795153547E19 -2.443529365769125E9) -2.214362179271001763423087500000000000004E19) (num-test (- -9.77092538926342E18 5.903189771537687E8) -9.770925389853738977153768658638000488281E18) (num-test (- 9.974714452399537E19 -6.980456691485629E9) 9.974714453097582669148562899999999999991E19) (num-test (- 1.7428950527159094E18 3.68843657888816E9) 1.742895049027472821111839771270751953125E18) (num-test (- -1.1094381875350845E19 -7.157723640671709E9) -1.109438186819312135932829100000000000002E19) (num-test (- -3.638795590369631E19 6.9246542750294075E9) -3.638795591062096427502940750000000000005E19) (num-test (- -5.66543282261991E19 -5.1005028153082024E-11) -5.665432822619909999999999999994899497189E19) (num-test (- -3.901527864456216E19 -1.064153465992923E-12) -3.901527864456215999999999999999893584646E19) (num-test (- 1.1477489418879848E19 3.327888063907735E-11) 1.147748941887984799999999999996672111937E19) (num-test (- 3.508978072054437E19 9.238453417997638E-11) 3.508978072054436999999999999990761546584E19) (num-test (- -4.7642024461416964E19 -4.758309941438892E-11) -4.764202446141696399999999999995241690065E19) (num-test (- -8.307715835429606E19 3.313910202186439E-11) -8.307715835429606000000000000003313910214E19) (num-test (- 2.704675010192592E18 -2.6840207147078365E19) 2.9544882157270957E19) (num-test (- -9.860969100714668E18 -4.719594638795429E19) 3.7334977287239622E19) (num-test (- 7.87799781828944E18 -6.657221298850535E19) 7.4450210806794789744E19) (num-test (- -3.3937781740759863E19 4.783805995045389E19) -8.1775841691213753E19) (num-test (- -1.0747572720102216E19 -1.7144708598072445E19) 6.397135877970229E18) (num-test (- 1.3938845733158445E19 5.604369854609131E19) -4.2104852812932865E19) (num-test (- 6.0938348303695315E19 1.1005522580049531E-21) 6.0938348303695315E19) (num-test (- -2.4870844028694925E19 1.5391650322730598E-22) -2.4870844028694925E19) (num-test (- 7.323118607079343E19 6.637280375859432E-21) 7.323118607079343E19) (num-test (- -4.181201584825501E19 4.768935182006663E-21) -4.181201584825501E19) (num-test (- 4.1225910279381205E19 6.117191687463543E-21) 4.1225910279381205E19) (num-test (- 6.438313875980151E17 -1.4883489002691529E-21) 6.438313875980151E17) (num-test (- -4.573961206963222E-21 0.3586300020381973E0) -3.586300020381973000045739612069632220001E-1) (num-test (- 7.74206782371325E-22 0.23168389210368656E0) -2.316838921036865599992257932176286750005E-1) (num-test (- 8.572446613640605E-21 0.6114581963443891E0) -6.114581963443890999914275533863593949978E-1) (num-test (- -8.539467934859551E-21 0.33474735899049E0) -3.347473589904900182020371578704711119401E-1) (num-test (- -5.55811309570968E-21 -0.9637216018651454E0) 9.637216018651453999944418869042903199998E-1) (num-test (- -6.705839413964189E-21 0.3787619614522374E0) -3.787619614522374000067058394139641890005E-1) (num-test (- 1.338539206480238E-22 6.683968625235106E9) -6.683968625235106468200683593749866146082E9) (num-test (- -9.64078167549023E-21 3.291420859310843E9) -3.291420859310842990875244140634640781671E9) (num-test (- -9.26536204591093E-22 2.9839295142529476E8) -2.98392951425294760000000000000926536205E8) (num-test (- -3.647737608953592E-21 6.115300020921433E8) -6.115300020921432971954345703161477376078E8) (num-test (- 1.4069763806331204E-21 -1.183109060480878E9) 1.18310906048087800000000000000140697638E9) (num-test (- -6.0037865798761924E-21 -7.442246743849378E9) 7.442246743849377999999999999993996213425E9) (num-test (- -5.994118986299138E-21 -9.091558282012836E-11) 9.091558281413424101370086199999999999991E-11) (num-test (- 6.969393585974241E-21 3.435352867093995E-11) -3.435352866397055641402575899999999999989E-11) (num-test (- -6.278554484817533E-22 -4.7211920270841604E-11) 4.721192027021374855151824670000000000001E-11) (num-test (- -8.603262886304741E-21 1.7296517702077242E-11) -1.729651771068050488630474100000000000006E-11) (num-test (- 4.104502790901735E-21 -4.8473213720301105E-11) 4.847321372440560779090173499999999999986E-11) (num-test (- -4.449725859444968E-21 -8.944265568403936E-11) 8.944265567958963414055503200000000000002E-11) (num-test (- 4.828216540804827E-21 -1.1712152029346877E19) 1.1712152029346877E19) (num-test (- -5.65034940464881E-21 -9.445303840982011E19) 9.445303840982011E19) (num-test (- -7.24107519738777E-21 2.340578690102746E19) -2.340578690102746E19) (num-test (- 1.7659593956231534E-21 -8.048768257390671E18) 8.048768257390671E18) (num-test (- -3.0538518255248124E-21 8.834631867521575E19) -8.834631867521575E19) (num-test (- 8.57952908388053E-21 -5.730742870111307E19) 5.730742870111307E19) (num-test (- -4.5090103564928485E-21 1.8907114777916313E-21) -6.399721834284479799999999999999999999996E-21) (num-test (- -3.8487625143236447E-22 5.354282198078924E-21) -5.739158449511288470000000000000000000003E-21) (num-test (- 2.6660110440404615E-22 3.833744224501756E-22) -1.167733180461294499999999999999999999996E-22) (num-test (- -7.503762004261027E-22 -9.623906576475644E-21) 8.873530376049541300000000000000000000014E-21) (num-test (- -9.113431042260725E-21 -3.5516521546085545E-21) -5.561778887652170499999999999999999999997E-21) (num-test (- -3.4813735333296525E-21 -2.6602650182385188E-21) -8.211085150911336999999999999999999999942E-22) (num-test (- 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99) -4948) (if (not with-bignums) (begin (num-test (- 1/9223372036854775807 1/9223372036854775806) -1.1754943508223e-38) (num-test (- 1/98947 2/97499 3/76847 4/61981 5/59981 6/66601) -0.00028742959363084) (num-test (- 1/98947 2/97499 3/76847 4/61981 5/59981) -0.00019734085622449) (num-test (- 1/98947 2/97499 3/76847 4/61981) -0.00011398112564314) (num-test (- 500009/500029 500057/500041 500083/500069) -1.00009999119288) (num-test (- 98947 2/97499 76847 4/61981 5/59981) 22099.999831591) (test (< (abs (- (/ 1/98947 2/97499 3/76847 4/61981) 195556288.07955816413500830)) 1e-8) #t) )) (if with-bignums (begin (num-test (- -4611686018427387904 4611686018427387906) -9223372036854775810) (num-test (- -9223372036854775800 10) -9223372036854775810) (num-test (- 1/9223372036854775807 1/9223372036854775806) -1/85070591730234615838173535747377725442) (num-test (- 1/98947 2/97499 3/76847 4/61981 5/59981 6/66601) -52761146275983172771170709/183561983334767209753061626751) (num-test (- 1/98947 2/97499 3/76847 4/61981 5/59981) -543899925850203550003/2756144552405627689570151) (num-test (- 1e40+1e30i 1e40-1e30i) 0+2e30i) (num-test (- 2 12345678901234567890+12345678901234567890i) -12345678901234567888-12345678901234567890i) (num-test (- 500009/500029 500057/500041 500083/500069) -125047255383687283/125034753009582041) (num-test (- 9223372036854775807 -9223372036854775808) 18446744073709551615) (num-test (- 98947 2/97499 76847 4/61981 5/59981) 8010593845541429507/362470312515139) (num-test (- most-negative-fixnum) 9223372036854775808) (num-test (- 3872339191937382556 13437882608410293981) -9565543416472911425) (num-test (- 12702320881720530101 13823645380834800545) -1121324499114270444) (num-test (- 10222969257152373972 -3454292165863475982) 13677261423015849954) (num-test (- 591233951053628288 -17639978232337836611) 18231212183391464899) (num-test (- -7878405903223218778 9050739027069287469) -16929144930292506247) (num-test (- 11347120771894057376 8443917396834074370) 2903203375059983006) (num-test (- 7831959259127703467 -257470007821066702597399141202130667973) 257470007821066702605231100461258371440) (num-test (- 1092406341647857980 -325710450166845666190895573961860069495) 325710450166845666191987980303507927475) (num-test (- -4220606126689357919 73461013742902296577411907972196819778) -73461013742902296581632514098886177697) (num-test (- -5112059189225304080 334306213789148650102245018234146620793) -334306213789148650107357077423371924873) (num-test (- 3093346224554776175 -204967241927023874963787190016588249299) 204967241927023874966880536241143025474) (num-test (- -5735747638156472357 -3881750746805128137401544408305666047) 3881750746805128131665796770149193690) (num-test (- 17639095392510638323 13312205908441007415860933757605397223142073616822325142416364932887680287063250296996056787873086490231950036662943632990219865746131453861285495087665017) -13312205908441007415860933757605397223142073616822325142416364932887680287063250296996056787873086490231950036662943632990219865746131436222190102577026694) (num-test (- 16304056910692545233 1463591032326743052350022746892396184459320617971409440301562638996633667625451301419074212369365394140737678584830314878769698416417465834928609990708982) -1463591032326743052350022746892396184459320617971409440301562638996633667625451301419074212369365394140737678584830314878769698416417449530871699298163749) (num-test (- -10347586523508777315 12614325304787850623826535169596975975360455924114817820074336137897280818245940873677389644701038550150832199897314137414727161192173691528917744363375331) -12614325304787850623826535169596975975360455924114817820074336137897280818245940873677389644701038550150832199897314137414727161192173701876504267872152646) (num-test (- 16875252323587344863 -10230183557696638447600885112945653217398839137450096120772416948425622105048400944465287395231588821521217980407867153259741079758527788318592431794213674) 10230183557696638447600885112945653217398839137450096120772416948425622105048400944465287395231588821521217980407867153259741079758527805193844755381558537) (num-test (- 8574302739232756920 2945205250727759066959418729185252318153395797902208079569164623770839848878181416073351760975066439564334127158302281471631001294503759011790017443478716) -2945205250727759066959418729185252318153395797902208079569164623770839848878181416073351760975066439564334127158302281471631001294503750437487278210721796) (num-test (- -17657597319577965851 -470389901349206124503884936612357721199915776516939967013182926735009022045917047211666512521578494339222795740836335004070464944715357800461845632614015) 470389901349206124503884936612357721199915776516939967013182926735009022045917047211666512521578494339222795740836335004070464944715340142864526054648164) (num-test (- 11472336850218354926 16764018932433717867649699977474298016589762238077229911249331402108995850754999065988360217500238643747316139204767820295123085026049273617874157749889925712672510963712964034497935503076689670786498045302562704435768723916334451317158760704743066709581593570757498670622547878516907127632802801541072452593999435195637193819500375063696114131057474475407791672955417184592088612921927282233762919112197264895445408873539746256555444555901857369535350160665235184955438709679669964546134487688796078142789125799020704969226557493354453298489954288702387159956161243151013189140749021799388406290339231792790773612376) -16764018932433717867649699977474298016589762238077229911249331402108995850754999065988360217500238643747316139204767820295123085026049273617874157749889925712672510963712964034497935503076689670786498045302562704435768723916334451317158760704743066709581593570757498670622547878516907127632802801541072452593999435195637193819500375063696114131057474475407791672955417184592088612921927282233762919112197264895445408873539746256555444555901857369535350160665235184955438709679669964546134487688796078142789125799020704969226557493354453298489954288702387159956161243151013189140749021799388406290327759455940555257450) (num-test (- 12682607562584942903 32133619583510009354538204193505267426986629771080807813988708187761849276650847958886764459302043799013813125903744946349479743277662066609741649009023451783267511140245797235200413941774959851628239089013586399425314412329003636059313583335807925401822165199322334470452126484173417518861322963430951772895619791799137157183662289329901964728384697377777905235894234370773419160283767144177627084271804319157013765325677633945370597318765372346484383325176768117059688792498687750479618961541872574768601477738410497806623403054372221338126223825515939164627992974469102910882915893925327931884157735553718792115929) -32133619583510009354538204193505267426986629771080807813988708187761849276650847958886764459302043799013813125903744946349479743277662066609741649009023451783267511140245797235200413941774959851628239089013586399425314412329003636059313583335807925401822165199322334470452126484173417518861322963430951772895619791799137157183662289329901964728384697377777905235894234370773419160283767144177627084271804319157013765325677633945370597318765372346484383325176768117059688792498687750479618961541872574768601477738410497806623403054372221338126223825515939164627992974469102910882915893925327931884145052946156207173026) (num-test (- 14621880654476679971 -10075923784619510279100488003620810539888599376089081798647754628017452762406215094511315867213396543200861274584884759429891242650999761503100661310915213260386281412125687376866399124849043409890009033179987278297335571911640353059036551139958369871790768643514550179661619387008678118363266091945225880595898524898713646458647465935791224159084684209727153050053537752111696883536364966526666445737103854446009305531519860527938394412863332757413309423156200192973778629503534709731073637828912608835085933003410694216843775182940057891552358942312728978810053715387504707194992816961400377579655168106377696154728) 10075923784619510279100488003620810539888599376089081798647754628017452762406215094511315867213396543200861274584884759429891242650999761503100661310915213260386281412125687376866399124849043409890009033179987278297335571911640353059036551139958369871790768643514550179661619387008678118363266091945225880595898524898713646458647465935791224159084684209727153050053537752111696883536364966526666445737103854446009305531519860527938394412863332757413309423156200192973778629503534709731073637828912608835085933003410694216843775182940057891552358942312728978810053715387504707194992816961400377579669789987032172834699) (num-test (- -3220156644655019630 -8347829670073174550775641165362740628312221836466572623516708794243074870361401136762432100726575330214254748615114820602945887237367461962207075265579588481261313345359877816874924645801358760718027997416917747796144940020489321523749233377708490614979453376328244189926517907474704635785063100359787580409065317918203485474119227673185211436285930586838616288721370975925191964611302275354365110550116042403226844820172448647475637867255305805337047967053177320593337377763657329816935516961201488840745892529800883680912275812320160312651894919502389242002380151562481051684439333368396132543667539444686619670713) 8347829670073174550775641165362740628312221836466572623516708794243074870361401136762432100726575330214254748615114820602945887237367461962207075265579588481261313345359877816874924645801358760718027997416917747796144940020489321523749233377708490614979453376328244189926517907474704635785063100359787580409065317918203485474119227673185211436285930586838616288721370975925191964611302275354365110550116042403226844820172448647475637867255305805337047967053177320593337377763657329816935516961201488840745892529800883680912275812320160312651894919502389242002380151562481051684439333368396132543664319288041964651083) (num-test (- 11628988978410243120 21091260149209133824278525560739673446778991946138130571540201996950100883736332286627324787663044982195445635023357027423513202277912840570399895946346028843517588470258087913846945044832851780108963206182331994065720076983528527849542421619745503796476103034657238118665288185878258232226731582201217795631247916614224227701409259346052937919425072595891571572960468193421257458185693656090215937518204243652916583730260295885562094977775951577484951577581277292356830523013216949489797535362720471761788697932265967910160407593278848113303674799017334692501935041730808945554336564957621028111014116286675587727714) -21091260149209133824278525560739673446778991946138130571540201996950100883736332286627324787663044982195445635023357027423513202277912840570399895946346028843517588470258087913846945044832851780108963206182331994065720076983528527849542421619745503796476103034657238118665288185878258232226731582201217795631247916614224227701409259346052937919425072595891571572960468193421257458185693656090215937518204243652916583730260295885562094977775951577484951577581277292356830523013216949489797535362720471761788697932265967910160407593278848113303674799017334692501935041730808945554336564957621028111002487297697177484594) (num-test (- -15960716439913426281 18799211173341989380260980155501104944815245973352765317821146163884181375747259542484535639646490774929026134833947975785613727050541297797675705933339289016115326958150660323801621778641184271728990164666383865587422591755046779736996211052149338115836473967202556153668963815595875844414662034458693455631979862997316049580586739835122770408911308146605671192538040301857163633538268589024651373766021087864982140201615461513687698136663128896835597598904095187715456109340116329587986878167776146023396961265667934659006280575496363066974484893764810659481361856335795455814679851690737943592227795474197104696127) -18799211173341989380260980155501104944815245973352765317821146163884181375747259542484535639646490774929026134833947975785613727050541297797675705933339289016115326958150660323801621778641184271728990164666383865587422591755046779736996211052149338115836473967202556153668963815595875844414662034458693455631979862997316049580586739835122770408911308146605671192538040301857163633538268589024651373766021087864982140201615461513687698136663128896835597598904095187715456109340116329587986878167776146023396961265667934659006280575496363066974484893764810659481361856335795455814679851690737943592243756190637018122408) (num-test (- -181065640455671431985325539445069267017 14120143334024043377) -181065640455671431999445682779093310394) (num-test (- -91295299684959299024846233061686623774 6891102275697080803) -91295299684959299031737335337383704577) (num-test (- -252582289949155881579950873916766853744 883304029266526072) -252582289949155881580834177946033379816) (num-test (- -10104159950635417603045689770006558103 17251490913777465304) -10104159950635417620297180683784023407) (num-test (- 288463495341489091297108607960869684860 -16376960611483226267) 288463495341489091313485568572352911127) (num-test (- 204661965092367792468062569536290631004 7774991291341524479) 204661965092367792460287578244949106525) (num-test (- 174559967167400201536723778015754014369 168183438971818617783400303174116396891) 6376528195581583753323474841637617478) (num-test (- -253300708624436983509156598368557395374 -77166863757693227553099778725240875400) -176133844866743755956056819643316519974) (num-test (- -38587765028356074196061530813295290944 5999161273284748726648331130480323187) -44586926301640822922709861943775614131) (num-test (- -236400856885875891058508662756360145662 222191413471626205952456600591947275777) -458592270357502097010965263348307421439) (num-test (- 212937903940173587742882129816769611096 336470165768472077447806282475185249734) -123532261828298489704924152658415638638) (num-test (- -264812595676159375893264580577855253845 -247068943830535581577267897204259299723) -17743651845623794315996683373595954122) (num-test (- -1725732715479127274526681751197327660 -2279805492899538651574406423954277869507456204136276822451602661149698386520868702017367409743272511010382761246500508887739763323997191435566266331339917) 2279805492899538651574406423954277869507456204136276822451602661149698386520868702017367409743272511010382761246500507162007047844869916908884515134012257) (num-test (- -220007189346579184019349894240059989979 9116030813176547770422918633286023943039811682891023288884273747820892639481842291616424036020927750322528731882517057595815179415042385175627374957565803) -9116030813176547770422918633286023943039811682891023288884273747820892639481842291616424036020927750322528731882517277603004525994226404525521615017555782) (num-test (- 139683266109784685815165642637380856544 5782493350903499652295971390391981928106911831248674750993968151944332845911526084530951283012280786005612601970108688202931002414214353708335212597807345) -5782493350903499652295971390391981928106911831248674750993968151944332845911526084530951283012280786005612601970108548519664892629528538542692575216950801) (num-test (- 239160165978290709841254489756277328273 5152132850125501873897264811465207492706871561577273155117982457627773151595716641409297120994045059130053034927464958986304380141364542178714472948085275) -5152132850125501873897264811465207492706871561577273155117982457627773151595716641409297120994045059130053034927464719826138401850654700924224716670757002) (num-test (- 315772704643232632782106484978382006176 -3689252327480456512393153800679864208480329729627292260734151097785848947569336194072922395859496552999163037466184616218582046814434719444842678248982224) 3689252327480456512393153800679864208480329729627292260734151097785848947569336194072922395859496552999163037466184931991286690047067501551327656630988400) (num-test (- 82735713197488344149642668226610301853 -12473025194535761005577066561696471986140205263843017221991729197337093872383371857001077050460827652296473928714097816492579684543651922277865558518876774) 12473025194535761005577066561696471986140205263843017221991729197337093872383371857001077050460827652296473928714097899228292882031996071920533785129178627) (num-test (- 63472235942371758467270296983419551089 -7866520408163137968600317959735552406794938230345293650627055135268307695389903092041438746530663083967329111232451176014649873249349534808700483360707382397988918594143264031213181385790969271527978925616276399184489007642142996251807222768397530946779296600805549276528669432847672215219943599871223372831999133812100481632278022608906065923652981249057846548868473376683960144009223047416366697876553049362242497225174860431577034875737250719899362881567590934060155436179316063810148362442197071642183371654740845983314705249832168923202400873364289483910868432511677656218937984504828452980698439495961392749596) 7866520408163137968600317959735552406794938230345293650627055135268307695389903092041438746530663083967329111232451176014649873249349534808700483360707382397988918594143264031213181385790969271527978925616276399184489007642142996251807222768397530946779296600805549276528669432847672215219943599871223372831999133812100481632278022608906065923652981249057846548868473376683960144009223047416366697876553049362242497225174860431577034875737250719899362881567590934060155436179316063810148362442197071642183371654740845983314705249832168923202400873364289483910868432511677656219001456740770824739165709792944812300685) (num-test (- -284018520801241078671538235859630240269 -5529748211779294240854894683633173443789067073881249229985499707296461959655918837051490512357840133495603640185675483847478587849599477020706893805485599954539589062532211767295361120129440287144117406526027552427750375526095104163474774446716012360038076376952619723549765229763943818011605991300849052030142173100367582906381575666628005795818339029350398340616624791399526643991489247585213423174803853961438830286737553181353007081438503238779644371968004083452645077716952159339978836669723137339898471600546912430030276920763475622536295311290657163861398519747560279682401429552174530714298081464588450842581) 5529748211779294240854894683633173443789067073881249229985499707296461959655918837051490512357840133495603640185675483847478587849599477020706893805485599954539589062532211767295361120129440287144117406526027552427750375526095104163474774446716012360038076376952619723549765229763943818011605991300849052030142173100367582906381575666628005795818339029350398340616624791399526643991489247585213423174803853961438830286737553181353007081438503238779644371968004083452645077716952159339978836669723137339898471600546912430030276920763475622536295311290657163861398519747560279682117411031373289635626543228728820602312) (num-test (- -171812101820192353275910956459431262142 11401673303315394031728944442295528921842441448377692701102691446500671963119794838260543877466107345474902885032629120622020177051592733148817057943390167845763358795044702079370835841331467130719834250134674578757640577473495192331790176510774020541399177011446664359866582351045889299070080989390219063301859447807907203943168891690028442190793548699886572720360741686677780644932612683647303776634496172481504075784427704287335805355801794320914944330891519283383694196486986108936857630373759865062862204149003789919218681050221366182434949855054760827976853645027544605870235074909890698574792562001595287630131) -11401673303315394031728944442295528921842441448377692701102691446500671963119794838260543877466107345474902885032629120622020177051592733148817057943390167845763358795044702079370835841331467130719834250134674578757640577473495192331790176510774020541399177011446664359866582351045889299070080989390219063301859447807907203943168891690028442190793548699886572720360741686677780644932612683647303776634496172481504075784427704287335805355801794320914944330891519283383694196486986108936857630373759865062862204149003789919218681050221366182434949855054760827976853645027544605870406887011710890928068472958054718892273) (num-test (- -243638660221338112796448050030955119997 -32214383478080953899491069562585164652288236626686985994647827422262342469970423345510055643470262764747630363450204055220886177681745412924556264758690138113272748656941509018308925555317383307928766093730384151056027828368474245304944063213926492719166086055718735381341569379006804236876950175122702350552198046290567043195716369691666842524594399597143281611765509174168738392889075290806378316647736667077047013214732267367344808724905727602402784621437141760604478301412768904784950365257469208085143467704875589485635570084387755189599791857576855454112556762755762408826226326879491415484319411662301650468948) 32214383478080953899491069562585164652288236626686985994647827422262342469970423345510055643470262764747630363450204055220886177681745412924556264758690138113272748656941509018308925555317383307928766093730384151056027828368474245304944063213926492719166086055718735381341569379006804236876950175122702350552198046290567043195716369691666842524594399597143281611765509174168738392889075290806378316647736667077047013214732267367344808724905727602402784621437141760604478301412768904784950365257469208085143467704875589485635570084387755189599791857576855454112556762755762408825982688219270077371522963612270695348951) (num-test (- -126332081511349770866908261827634312283 31497387372874133218238910173378055967910722258532087598053588964599898753455370244114881403020152175272452951858324158004662566613339529101292284073176382818309096142522412043073218657587031893636358434796164444941535757484360125937835242214199979245499374972029624710574236962978707708765065292759037309958875006017588240959790355958632745299212449602934380927677385974488564420550408281673927387615657765312151272852486266800510090872812376232597458154951925709496664568906509814364388823105469855516803225244972466742963619633076158367569109107733990828830121948130235858799809203410103682003414364238243553515261) -31497387372874133218238910173378055967910722258532087598053588964599898753455370244114881403020152175272452951858324158004662566613339529101292284073176382818309096142522412043073218657587031893636358434796164444941535757484360125937835242214199979245499374972029624710574236962978707708765065292759037309958875006017588240959790355958632745299212449602934380927677385974488564420550408281673927387615657765312151272852486266800510090872812376232597458154951925709496664568906509814364388823105469855516803225244972466742963619633076158367569109107733990828830121948130235858799935535491615031774281272500071187827544) (num-test (- 219979452670016849533060110266815720199 3900115048441644499033281842448985956665866771934663536385503692700586024397767816761943054115584011069129310718114010862034970648115172218305599786238607524420973404711138276011261135403209178420948996472570042497859127324157786975578751148348046315727383390370594954695454631662061021971027739429505825056455676233533511412589936865597034183410893428831818716136282201523804692574965779771140320669492229416601369453681528301333865290947482219850340728455965391492610516639151652595539203632139883064874286555941718154489936421274731413286355640404192677546692090304496817063325766995908926108582896362623757323811) -3900115048441644499033281842448985956665866771934663536385503692700586024397767816761943054115584011069129310718114010862034970648115172218305599786238607524420973404711138276011261135403209178420948996472570042497859127324157786975578751148348046315727383390370594954695454631662061021971027739429505825056455676233533511412589936865597034183410893428831818716136282201523804692574965779771140320669492229416601369453681528301333865290947482219850340728455965391492610516639151652595539203632139883064874286555941718154489936421274731413286355640404192677546692090304496817063105787543238909259049836252356941603612) (num-test (- 585873325961105129055557280004608765382109855007674169500308242261038324959928764512890600512016613154122762798104714052579267789493643522748210870974797 -1855792162818946202) 585873325961105129055557280004608765382109855007674169500308242261038324959928764512890600512016613154122762798104714052579267789493645378540373689920999) (num-test (- -3026050092505200332789765255096964033685859497096213532090644235603419347590512426830117415222669642053441336442247132403948783838396746566100575461602162 18009081534399282710) -3026050092505200332789765255096964033685859497096213532090644235603419347590512426830117415222669642053441336442247132403948783838396764575182109860884872) (num-test (- -11124638695599888462310706699308855434715251048597328942409434888923094027849143412724699165971400546471660924330688750607774759764580214088920441698992069 -4827559068742614723) -11124638695599888462310706699308855434715251048597328942409434888923094027849143412724699165971400546471660924330688750607774759764580209261361372956377346) (num-test (- 4950293428090696283711882613183655723616682297360442241017758383241177602498881186549809051670562038601658285833496694108818253845693871318067007752043113 17597810481352184048) 4950293428090696283711882613183655723616682297360442241017758383241177602498881186549809051670562038601658285833496694108818253845693853720256526399859065) (num-test (- -5733769947958740467479139247420201065087494801172241127791526686385518674532830661413722661802560247463032020003355494614502034002778775472609306735864748 -3892174127829225880) -5733769947958740467479139247420201065087494801172241127791526686385518674532830661413722661802560247463032020003355494614502034002778771580435178906638868) (num-test (- 8320894458193427045187598554188178307429755504967209344418448624882517461814957461249858674758807195827056824653471934409067429988676743031117653237018365 -12861394200627120797) 8320894458193427045187598554188178307429755504967209344418448624882517461814957461249858674758807195827056824653471934409067429988676755892511853864139162) (num-test (- 13033402737450594044106258936169013897237368708138118260402180886096095497725071502601849887805439844083105685971731015312020770945603825344926844435936044 236396022362585261770052671762207864597) 13033402737450594044106258936169013897237368708138118260402180886096095497725071502601849887805439844083105685971730778915998408360342055292255082228071447) (num-test (- 12170667278114656173974716189098171384426379753661081475485441559687661443127166543908925678856145097632475832903680828294561265828775791256812588754280222 -276673555533799047589626400978981416789) 12170667278114656173974716189098171384426379753661081475485441559687661443127166543908925678856145097632475832903681104968116799627823380883213567735697011) (num-test (- -12755594876262399860618168642932232021734362385933348033134635580177924615701078617214764415318471507488803810365565826229169313660087149542130819663319659 -157671440495648010763311068579191828684) -12755594876262399860618168642932232021734362385933348033134635580177924615701078617214764415318471507488803810365565668557728818012076386231062240471490975) (num-test (- 8664063140780163008577373335591938905735059211566906376953760862047748343846207426667781783874718320339071949903053785280430612875488847226724390758938740 54361107931665215623681874454167019934) 8664063140780163008577373335591938905735059211566906376953760862047748343846207426667781783874718320339071949903053730919322681210273223544849936591918806) (num-test (- 3699576825118349347309026261327541749454660339251578894574483235547605815416603169143590292164644149607672871236942391817131531474661895913650810587431606 -50508350367572393968128467319633674717) 3699576825118349347309026261327541749454660339251578894574483235547605815416603169143590292164644149607672871236942442325481899047055864042118130221106323) (num-test (- 5626548453644136572409808769267055618695663227750732922630041368983808478347120771651822300668480671524976882745306794511840379704578900504784165956486985 170502882789371639987361620116696459267) 5626548453644136572409808769267055618695663227750732922630041368983808478347120771651822300668480671524976882745306624008957590332938913143164049260027718) (num-test (- -10859007735074693411217019392659638207496329895257318665547454149984863458541990037760564769787816800806064437172810158051442267508476778676439633382657890 -7558060977666720080449823996328496253877735754811271086853901493753796001778345391546991917892931500169890406340928835457635973812901681485438886367096185) -3300946757407973330767195396331141953618594140446047578693552656231067456763644646213572851894885300636174030831881322593806293695575097191000747015561705) (num-test (- 9842028993407961669727766131360795288615020071102475108883839785397865740828387076847892646234215787999498419839351470775471313077046438080666908734795616 8259939762466350877481193620364896193464602165170783019804380181692322874550956777598992104871440502758410340359413403619753571535498118388286469082729503) 1582089230941610792246572510995899095150417905931692089079459603705542866277430299248900541362775285241088079479938067155717741541548319692380439652066113) (num-test (- 3122315115429970622394662815735050825423438028108957393747131991771456957037829402044934484343765915727397519247940959221091465331254497476137639859816450 10737995515603450913722681305571315249864367824351372254572936648132763616823019940208526402092654554035074813865303483747097673960803093638463005072804384) -7615680400173480291328018489836264424440929796242414860825804656361306659785190538163591917748888638307677294617362524526006208629548596162325365212987934) (num-test (- 11618335890332522671268040181306950825004789685088262996478365976802329054158653675768163009290064139158450983598701977173152384425333441365287895694522192 -13130287008197231017935223399369698658354829835061356451363818961959486828237111511740029441613108087354987794332115218978284937263725126538295501305403242) 24748622898529753689203263580676649483359619520149619447842184938761815882395765187508192450903172226513438777930817196151437321689058567903583396999925434) (num-test (- -4829477140897377009195646150061276059814366801005389903693533021027427566117360765323647260121062827801190746646296803957067548167571028717513392985791293 10716557117391614298810040587314742187092120526669273567183969821384063434473189717686678450880765426943205955814024872764413373364846268902370055526485180) -15546034258288991308005686737376018246906487327674663470877502842411491000590550483010325711001828254744396702460321676721480921532417297619883448512276473) (num-test (- 1560421244904974852620371975782132605421448226892487453928759432083522187778803424020804578027100625536441377609275030418285893555753560195716001014786650 -11797558308994912054526619290334311429749533070145154703018977152548370444659962978040151671210413666186432921816690953994784423526183449271023503069393845) 13357979553899886907146991266116444035170981297037642156947736584631892632438766402060956249237514291722874299425965984413070317081937009466739504084180495) (num-test (- -7701347923966912534344428538744620884561375267012102797292378941649984539207353887059064943586048644516121387166836442084007442716291792933061162738380376 5290969389374230541016502448421359606252744677802288901830045825873182202718418905866055323957065013553046698199939002159982374580735362593037515863844280108947533575824820196689891621498006303535207762625068798755031433921940066544809959896067184147997503827988613858484669349726945188167613248195147619673963531690938913245110754715059472477991342216448470339490385593605806518967792963339193162830698488489270925945408227996742278697477358272529028932771642478870844024835907350391770605391526921411004262446196112836319091260967898895009427182171643279100998182191816962677328417390867021108292139204864164048286) -5290969389374230541016502448421359606252744677802288901830045825873182202718418905866055323957065013553046698199939002159982374580735362593037515863844280108947533575824820196689891621498006303535207762625068798755031433921940066544809959896067184147997503827988613858484669349726945188167613248195147619673963531690938913245110754715059472477991342216448470339490385593605806518967792963339193162830698488489270925945408227996742278697477358272529028932771642486572191948802819884736199144136147805972379529458298910128698032910952438102363314241236586865149642698313204129513770501398309737400085072266026902428662) (num-test (- 9733743430220591762422540139212426729307515492818443460852332805653889275463385649305231919846970974905736816260992940027028218064265519723018527155353151 -29407855293830047984154639411082591337348779678279017647951764366455421210163494489475996514661359700145916243499452007595041420522019751347743105082745321262372977262641488359297167392118038994384136863563032667040671405618315550876997904307423736276844997706938133936081058323434935833614475654922773162140266784233792639117145232791514703532554345086520312281500696798706889025860427142771458666376271994240028586899592254884476941388776984078337603148583453255593120138178690189726206775893096279000909079330468718593887702543025737308336025198677457129910473491269839827087491228569718246503140134413881896746751) 29407855293830047984154639411082591337348779678279017647951764366455421210163494489475996514661359700145916243499452007595041420522019751347743105082745321262372977262641488359297167392118038994384136863563032667040671405618315550876997904307423736276844997706938133936081058323434935833614475654922773162140266784233792639117145232791514703532554345086520312281500696798706889025860427142771458666376271994240028586899592254884476941388776984078337603148583453265326863568399281952148746915105523008308424572148912179446220508196915012771721674503909376976881448397006656088080431255597936310768659857432409052099902) (num-test (- -276731217243271862683214238489380950428392903790808046630969592255272629537001990355375434170910931115552132394269672247616298060929507021008951190291387 100289083769237476480554074865040988004216167545459907207847010762380733541100608695693297149249375537088329431700364201275915507683345148401600569951338052791424407090330310974243070931256108167365334162914085216447196038922091547331474328250886730614683299908003398886233860613008266913065047699535081030427106800418656336608005860846045905149012346378286475449307630537665901621055008855374148058291266835796203075976592585729940879567246284967856356337849150102261744547461816282538319258966892339056695718919291240188920586288417893106046698069355647145603908383687239983874164793005765733782432717429040621674) -100289083769237476480554074865040988004216167545459907207847010762380733541100608695693297149249375537088329431700364201275915507683345148401600569951338052791424407090330310974243070931256108167365334162914085216447196038922091547331474328250886730614683299908003398886233860613008266913065047699535081030427106800418656336608005860846045905149012346378286475449307630537665901621055008855374148058291266835796203075976592585729940879567246284967856356337849150378992961790733678965752557748347842767449599509727337871158512841561047430108037053444789818056535023935819634253546412409303826663289453726380230913061) (num-test (- 8505070389896098095621766692413480203366379968950158493268895987250690600795955783113900096527432416791184386061684833478921638080978014176210898461637606 -16410711613672171332126342754193842244915477287016327757357714698751777287458963458682349581881560880814595167244857846847668988374679430572782121021084683986742283012573569894084166107235597351093334125816075658348307113218478800035703971671113417712009419861470917307849916674203301497919242668373376352901312309673053175315189945730756118172940886476343290174961420986113367531057713782438374928471960914578818951372282574754612716278516397754222547513576728677459134022062202283647690649100602260948409511070624300011106517649666031530376191755817891213910847547809248990517666613043010292627100428536737652546738) 16410711613672171332126342754193842244915477287016327757357714698751777287458963458682349581881560880814595167244857846847668988374679430572782121021084683986742283012573569894084166107235597351093334125816075658348307113218478800035703971671113417712009419861470917307849916674203301497919242668373376352901312309673053175315189945730756118172940886476343290174961420986113367531057713782438374928471960914578818951372282574754612716278516397754222547513576728685964204411958300379269457341514082464314789480020782793280002504900356632326331974869717987741343264338993635052202500091964648373605114604747636114184344) (num-test (- -12618010259109779267590315037969998053964054382853891516547435925972388025118492931596200697357628900783311183940584302426381939302632641549019984810957030 -30500906828861638007306362171210132987300359439962044769219457463653547834815716264412200930088623097530758080891972640000479943534665059199377729854850415258341537838023739964147532129877743393965857370995558748807382396090020006195649251292012405690725917389684473999400905751109361754679152179983739269026226054012963756892488872262522587481931950410504651253101938824790285623805566521723062029033001745636445860437154344665483641408727637784045030118212476306906983993748299291616038887011943864441807818857508443930272872365334665976442185494702520760793786640113779099219233665607521784524244604432396247693263) 30500906828861638007306362171210132987300359439962044769219457463653547834815716264412200930088623097530758080891972640000479943534665059199377729854850415258341537838023739964147532129877743393965857370995558748807382396090020006195649251292012405690725917389684473999400905751109361754679152179983739269026226054012963756892488872262522587481931950410504651253101938824790285623805566521723062029033001745636445860437154344665483641408727637784045030118212476294288973734638520024025723849041945810477753436003616927382836946392946640857949253898501823403164885856802595158634931239225582481891603055412411436736233) (num-test (- 793528769616879938852241178439496352527042950647521648629732169156958768358523029837406526207126598190786120139491813624819360632811627576064199559812277 -7357484069649002655190557040768215614708659708788999334802985986235721030962928900092675952032143512196279092521450986819067071570862007086586132687661085824939677603953832219860573980632016025218580608321648907608385784471745482257672314890331358256478273312255285010343369949412955387472116587504557483184506548209831317705115523967163525846685455369176657510129844566195941925821733027993620517287411895496215426174909366458092382652675628195464969405904518323018004882611048769247228828875493680284766874334247375868318795940759082324831733175858991629741478124633015067484305547002438816473086042218906532116413) 7357484069649002655190557040768215614708659708788999334802985986235721030962928900092675952032143512196279092521450986819067071570862007086586132687661085824939677603953832219860573980632016025218580608321648907608385784471745482257672314890331358256478273312255285010343369949412955387472116587504557483184506548209831317705115523967163525846685455369176657510129844566195941925821733027993620517287411895496215426174909366458092382652675628195464969405904518323811533652227928708099470007314990032811809824981769024498050965097717850683354763013265517836868076315419135206976119171821799449284713618283106091928690) (num-test (- 30958566711373255787092081401292877738974978442987704470984765018293851031728996862405055424093249924047528792113585028592262445810946419909807061004531455817427671594281537965628880611732831524185850161910304038646992464838306728350704966234151134620041799373762432970330864023007632010865749239024802839173884778578927209741320635135275002489733299806669933393428518104197594560039136096527206600870299327752296492029012993590212340409989598323540081430189567580333356380487749078595746626408529223195894600223743978246922817054226858311823994547784553612982586322603593335538875728113115443554199017672360091721648 9164115638960783470) 30958566711373255787092081401292877738974978442987704470984765018293851031728996862405055424093249924047528792113585028592262445810946419909807061004531455817427671594281537965628880611732831524185850161910304038646992464838306728350704966234151134620041799373762432970330864023007632010865749239024802839173884778578927209741320635135275002489733299806669933393428518104197594560039136096527206600870299327752296492029012993590212340409989598323540081430189567580333356380487749078595746626408529223195894600223743978246922817054226858311823994547784553612982586322603593335538875728113115443554189853556721130938178) (num-test (- -22540807692474380279530794404584230073523360203115293035869063366926380719566516089428840111682263403627532047214106171892715667227836310498366393991106231487046533598391969789120283294510723096483520917309134391072655861112766764278247568027435618337967113341863713181603534251049249873125130781073437913954718595729437608729446837417196899902194261111827656247095442897532040935029872731410799530408713850806239149348700486268275019296069828199088780767614008685960242354118969741283398882689239770114582524756296906388861630890288875920861344939520380841337675934551587994259348267613541166769237154904791412049964 16928681651977808800) -22540807692474380279530794404584230073523360203115293035869063366926380719566516089428840111682263403627532047214106171892715667227836310498366393991106231487046533598391969789120283294510723096483520917309134391072655861112766764278247568027435618337967113341863713181603534251049249873125130781073437913954718595729437608729446837417196899902194261111827656247095442897532040935029872731410799530408713850806239149348700486268275019296069828199088780767614008685960242354118969741283398882689239770114582524756296906388861630890288875920861344939520380841337675934551587994259348267613541166769254083586443389858764) (num-test (- -5403850875869356031749551669837202919756114555261706106905659104903792701565965475066159243529680606410723686422444947172225540145977333194008702465610630608545009270872541652430806931212184915840724378685979865349848151917650322286497417985248678815214889868576385900691591784772762893647315325310416150353725001943778473686980157692817497562783521120544549784746647104651038037129984152623720529803205580894126664077380391379306511348324442512538418658728022685805514196592544294177914956734669359073791151050869328577099869772182315103156047405800398706114122356939316464974680113324979723289916823063616573634058 -10755560408227106818) -5403850875869356031749551669837202919756114555261706106905659104903792701565965475066159243529680606410723686422444947172225540145977333194008702465610630608545009270872541652430806931212184915840724378685979865349848151917650322286497417985248678815214889868576385900691591784772762893647315325310416150353725001943778473686980157692817497562783521120544549784746647104651038037129984152623720529803205580894126664077380391379306511348324442512538418658728022685805514196592544294177914956734669359073791151050869328577099869772182315103156047405800398706114122356939316464974680113324979723289906067503208346527240) (num-test (- 16201587974698660164372991183566748501003872177894450603471850345714117528335101264234127789041855420954511595895378320972957964222386731614839583078498685801156670229700092209313747849610762975747730086443186821337319452128253859293962343891549207804191088925361935683615063225197130192492652062735684739784075955094308092423304262201429421582566117390598395895220976999990205945523225411701169301910362640419341608407294018105959688929256136725564385243617240412649023368133778798063226772467915584333795357813292935080009919284755332034998122912861893282865727947810588086156919649131720183722427134042574317487793 -126159569916621842) 16201587974698660164372991183566748501003872177894450603471850345714117528335101264234127789041855420954511595895378320972957964222386731614839583078498685801156670229700092209313747849610762975747730086443186821337319452128253859293962343891549207804191088925361935683615063225197130192492652062735684739784075955094308092423304262201429421582566117390598395895220976999990205945523225411701169301910362640419341608407294018105959688929256136725564385243617240412649023368133778798063226772467915584333795357813292935080009919284755332034998122912861893282865727947810588086156919649131720183722427260202144234109635) (num-test (- -9976758107386398142455037422077809088581080675608340830198269021688955930541332630075972471934165382030070969307731206728197760190279942894255740733209190331510591013089699837164445642396864912572863786290237335963836376543389815671640509582958465164874961381137096877288362944469137669502842448492172241151419831252572392809173900377271652074261706120638052379886108764460001026094198502028776365675088466580595870167840105746912975236851293882732079317535103041585285239081516202482201377111734010788198635874359396626004300532752450289119192633850562141516671742961938277967783337559307443617308447853505824391099 13449070890444925581) -9976758107386398142455037422077809088581080675608340830198269021688955930541332630075972471934165382030070969307731206728197760190279942894255740733209190331510591013089699837164445642396864912572863786290237335963836376543389815671640509582958465164874961381137096877288362944469137669502842448492172241151419831252572392809173900377271652074261706120638052379886108764460001026094198502028776365675088466580595870167840105746912975236851293882732079317535103041585285239081516202482201377111734010788198635874359396626004300532752450289119192633850562141516671742961938277967783337559307443617321896924396269316680) (num-test (- -8570952518585194406209873586517687582701183275108243979199329595605282282125006489076327154374449108678257552384372919282846744626955206382078850958298637157198962032090439427286914716782317030245513658212430127586764421559372214829010306717557679285031617989735914399954286846456953917915955558448774972943731602144914068097214910567329340361564904028964471241318105967747431610163083002382821902859161510204381788262611298660559327478615315484763561786397041779926288206767156863141140852268323253657685018587945456372648431446464389004257999049529945532453598011773843788498650935959375182414447893892341891463988 4431555062692055371) -8570952518585194406209873586517687582701183275108243979199329595605282282125006489076327154374449108678257552384372919282846744626955206382078850958298637157198962032090439427286914716782317030245513658212430127586764421559372214829010306717557679285031617989735914399954286846456953917915955558448774972943731602144914068097214910567329340361564904028964471241318105967747431610163083002382821902859161510204381788262611298660559327478615315484763561786397041779926288206767156863141140852268323253657685018587945456372648431446464389004257999049529945532453598011773843788498650935959375182414452325447404583519359) (num-test (- 4117976000917214601143188578494558474138167055110060832594841842655428229500889876131794484851166401425675703592388271925904534237338595998991043982676292549088043959446082382516734793718348862105938692342851330680670593768890094290655852108130945387988863730762717733881418314989528719379494082656897158942547008663543153236129762264443358316776532465284014215413819415615612452225913947961681691310132286840303081453109375175436902292224029179426794714036524361081174901146731799945483243427138748119832116750910126386838614645397770107366925613473924955965862778639046707637382775371488874447622330992324750207465 329466253508616383200261654231797136951) 4117976000917214601143188578494558474138167055110060832594841842655428229500889876131794484851166401425675703592388271925904534237338595998991043982676292549088043959446082382516734793718348862105938692342851330680670593768890094290655852108130945387988863730762717733881418314989528719379494082656897158942547008663543153236129762264443358316776532465284014215413819415615612452225913947961681691310132286840303081453109375175436902292224029179426794714036524361081174901146731799945483243427138748119832116750910126386838614645397770107366925613473924955965862778639046707637053309117980258064422069338092953070514) (num-test (- 28857935543824608075326348244201981931023939250259142606733822094071772153858420201297951828741003977413353359215638528196235956061529059419904405354390715114239219947402126760298132539402386106279333968395498788354937020337343839325588433318100331044091923709732742795159387846354148919054314582749477292946200912006940503778924320301062789466388997936618573519744795661160190636101768486096961991215006236190655062992372061052426455063703038765465688361316141792840153608145888307784845264037109867657483109819380082597605481013612040648149090345778910883349230476481347645708269410828528742743794495302359380494607 126536164564464424337714470705049463978) 28857935543824608075326348244201981931023939250259142606733822094071772153858420201297951828741003977413353359215638528196235956061529059419904405354390715114239219947402126760298132539402386106279333968395498788354937020337343839325588433318100331044091923709732742795159387846354148919054314582749477292946200912006940503778924320301062789466388997936618573519744795661160190636101768486096961991215006236190655062992372061052426455063703038765465688361316141792840153608145888307784845264037109867657483109819380082597605481013612040648149090345778910883349230476481347645708142874663964278319456780831654331030629) (num-test (- 3146199586408378667812619157270468624370984629500707476575291934586478540055436137993431548830607708293475788354970610669452058906009873485175438772484599603993015239438297747261356407887781450787482447252615210880612867127689283653562498484594955015919746443263740095372831444793239911996227663006098501180972347442107190398034048225264564325230296723559400768342331039755765597288518435463475921534765025262262798267314969774604439319964638461636007229819888743218820584570149249791727508891676067767073852694327748467914037392778283816153183422263956621516748627574334199731850712255885395479903525322397561293553 -169494171680584797187706369710105239124) 3146199586408378667812619157270468624370984629500707476575291934586478540055436137993431548830607708293475788354970610669452058906009873485175438772484599603993015239438297747261356407887781450787482447252615210880612867127689283653562498484594955015919746443263740095372831444793239911996227663006098501180972347442107190398034048225264564325230296723559400768342331039755765597288518435463475921534765025262262798267314969774604439319964638461636007229819888743218820584570149249791727508891676067767073852694327748467914037392778283816153183422263956621516748627574334199732020206427565980277091231692107666532677) (num-test (- -17024716654716744558842421452239026542281806678754026383430912733874686056449261218428541803113383766132449624540209841726047308927951820311213785345168358108138304716549475322223600292513384537980742126687035576531330089447100646214364923043445903103768701639992829171572718403272488931980504461938688955457870904289239032709146514866818331202329982821151580491257491540240579366183525075936339515949345815704583685855315810611089822402567649542290589282153225725537026309623090382054078872576985425957096858376112688308214148412270019118710904983829984589093557307164347051152307499446188262820058714564165108542508 -26845770031559702758807696432929071597) -17024716654716744558842421452239026542281806678754026383430912733874686056449261218428541803113383766132449624540209841726047308927951820311213785345168358108138304716549475322223600292513384537980742126687035576531330089447100646214364923043445903103768701639992829171572718403272488931980504461938688955457870904289239032709146514866818331202329982821151580491257491540240579366183525075936339515949345815704583685855315810611089822402567649542290589282153225725537026309623090382054078872576985425957096858376112688308214148412270019118710904983829984589093557307164347051152280653676156703117299906867732179470911) (num-test (- -20875354448001792153279041347864644172439177882677780548397567327274288309764204295853633150227327732322157811413794613378828291977852467550695289535036337326494269114787031260705326469002279939986228049380615128280814933748700667874022724707001736732724010699175779382411342385842744973636495738468838244099596215421975861650998954057316519632062827510021706536194961332185926551767127180751211669386674770139039516623606727799489291663572125587356845055646322930167536458093283930082765496058330805117442824718962237069840252138957395570892073194575112213410604881673785921789655406716271370732069643455590690035701 -321447426701397438572265325285879998363) -20875354448001792153279041347864644172439177882677780548397567327274288309764204295853633150227327732322157811413794613378828291977852467550695289535036337326494269114787031260705326469002279939986228049380615128280814933748700667874022724707001736732724010699175779382411342385842744973636495738468838244099596215421975861650998954057316519632062827510021706536194961332185926551767127180751211669386674770139039516623606727799489291663572125587356845055646322930167536458093283930082765496058330805117442824718962237069840252138957395570892073194575112213410604881673785921789333959289569973293497378130304810037338) (num-test (- -6750548706930727136186675393752693335334383613941059024795513640678178119089262068912855951615043660442324823673049951182143778744824110223137384940032268718291241014850714197673735719784663896993460156686600813524168487673234842233781654493200950459723884918456280719440022930492599128086690014332139955274261568563155723011697763382009890186816226119314994799655369791620499988988986590903148198659095740939986627235565633349906453726759224441608018598520571182643709143072528030332708598472074166415467718451869993686505339408706320298338691467040585228617379086727764240955696690287600957842671916189752415855520 132223863177855649509430852484092802671) -6750548706930727136186675393752693335334383613941059024795513640678178119089262068912855951615043660442324823673049951182143778744824110223137384940032268718291241014850714197673735719784663896993460156686600813524168487673234842233781654493200950459723884918456280719440022930492599128086690014332139955274261568563155723011697763382009890186816226119314994799655369791620499988988986590903148198659095740939986627235565633349906453726759224441608018598520571182643709143072528030332708598472074166415467718451869993686505339408706320298338691467040585228617379086727764240955828914150778813492181347042236508658191) (num-test (- 15737797902964168014939893286340956118635524170934156177365242966267432695262586636031957242055461736359478270642576860414422844075672388559647477705484719667060463718865742735598799928335211410004369240278699196301127699945374217439676378682879115442203681638050752745036508637214733712716867800216723838016099572951915042604603457902610639317648800296497583507890473114507231814851908526534709496988648572353272479026750068932474334642929727977996779536604912743446197670724757690108283368934769626461285961947257397454619164856011847736479229692086038931510067165282571276049292116713101550911614590774659556899356 -6114512833799784097991148713266650451765474382378581896952003894922931741133332233338460555227243451198289670274036744955599177213449957470212981501678055) 15737797902964168014939893286340956118635524170934156177365242966267432695262586636031957242055461736359478270642576860414422844075672388559647477705484719667060463718865742735598799928335211410004369240278699196301127699945374217439676378682879115442203681638050752745036508637214733712716867800216723838016099572951915042604603457902610639317648800296497583507890473114507231814851908526534709496988648572353272479026750068932474334642929727977996779536604912749560710504524541788099432082201420078226760344325839294406623059778943588869811463030546594158753518363572241550086037072312278764361572060987641058577411) (num-test (- -26633154627863501044020127597209297142657179797586777727331879111280843451446814109347357601013807189824906954310855123313836812409388745541128842840054310853220032505914307470215180950497357091093642400638925719682307925365402618310180378684705799724964274776149984064608716300479893889145492885897234574442542501896696821902329473018442082678749291668341477914681413039643187020003425962922948452894682558162414623956491734656939841377698702802567258906642912449969621455596132708975438173455827361542712483153981422051943690720556013580161324856788091093465837542336129629269227369781823515673967591796132853515009 3321161637038961370471515250185392889390643163295535903347391615170504064647249127732639364682803744773593849851778894972403397573953564801884397178069327) -26633154627863501044020127597209297142657179797586777727331879111280843451446814109347357601013807189824906954310855123313836812409388745541128842840054310853220032505914307470215180950497357091093642400638925719682307925365402618310180378684705799724964274776149984064608716300479893889145492885897234574442542501896696821902329473018442082678749291668341477914681413039643187020003425962922948452894682558162414623956491734656939841377698702802567258906642912453290783092635094079446953423641220250933355646449517325399335305891060078227410452589427455776269582315929979481048122342185221089627532393680530031584336) (num-test (- 27668394897866653012794531261739800318882766882548843941974485394983434533400277607364280566269718161470415771058329222680901477416257843578362127708934184467195154000133252468684612556324066063725677629160438683034201285122508880444372096430021219637788794365539396242345208611990491721052691567092029622640533057073151980959055665792776356282961971341363712186503783566960850166774438868528799819047163739437906559674823146932668464230936946321915236658512741918196732794332451120218658490129307932187658010681746557120172585093207839141764683325214902696969028472942954863209641597556494684135445935915485525220911 204625459185084436546676461283890328511903949966691877662249903659689934813784661695047569885195881142676761876303280806728760511429260843727967794322777) 27668394897866653012794531261739800318882766882548843941974485394983434533400277607364280566269718161470415771058329222680901477416257843578362127708934184467195154000133252468684612556324066063725677629160438683034201285122508880444372096430021219637788794365539396242345208611990491721052691567092029622640533057073151980959055665792776356282961971341363712186503783566960850166774438868528799819047163739437906559674823146932668464230936946321915236658512741917992107335147366683671982028845417603675754060715054679457922681433517904327980021630167332811773147330266192986906360790827734172706185092187517730898134) (num-test (- 18944451653774463090918576081661764936021793389045063662102219434278236461286997354190032851092512146937346521704215170240383659165117708716738711782597164244188741818096207452074083439983059414271417130274747048227795964884943105011205424198661201055104372863019759130697888820715782179466491256695453118035286889359217448004524564796840711987314064158194625731263591557915838970249677548534895064545467992194029425250039951132361639559343536937119283951538321037694842089561504643350632756961329867761604760788760440497535611072991056505806805291706178639395690245460397975614715123591611301423752799666149495108752 994321141213369910357526037382331323092462599623554452705525887587326552002660849455542761618020243106424015447778226642816634338781654345001677083881111) 18944451653774463090918576081661764936021793389045063662102219434278236461286997354190032851092512146937346521704215170240383659165117708716738711782597164244188741818096207452074083439983059414271417130274747048227795964884943105011205424198661201055104372863019759130697888820715782179466491256695453118035286889359217448004524564796840711987314064158194625731263591557915838970249677548534895064545467992194029425250039951132361639559343536937119283951538321036700520948348134732993106719578998544669142161165205987792009723485664504503145955836163417021375447139036382527836488480774976962642098454664472411227641) (num-test (- -25075128489482657321316021943980016828761861550379828525731288423212311433274066958090940464803020097932875912251380196071686918459370667428905844496548191635733867314315152547202859654044591981512687559437417616479425752991419002108503390319869665933757684966460526631533822984311725217788657567199485442486045019468844265484117570385156844404625735176559901986920712550964238722824122000259551821135404274194791706113272773768366572120227974096419295159271316157215551931810740200836725504693738229444336470213883741520460842708733150362983831267583568258736572295448486287825894301201018490203520738439038977754991 -7402949251688548738762242219263594861535354011996392637087346760786292549376145193266590582054224293289596877537643409310483743293801574030358189880866069) -25075128489482657321316021943980016828761861550379828525731288423212311433274066958090940464803020097932875912251380196071686918459370667428905844496548191635733867314315152547202859654044591981512687559437417616479425752991419002108503390319869665933757684966460526631533822984311725217788657567199485442486045019468844265484117570385156844404625735176559901986920712550964238722824122000259551821135404274194791706113272773768366572120227974096419295159271316149812602680122191462074483285430143367908982458217491104433114081922440600986838638000992986204512279005851608750182484990717275196401946708080849096888922) (num-test (- -26509487378481600038412836495388065888781507388737194948728047318975269277448073484403390476243134990463394380967295356958474984927721196047241216945988250219075749832868804186657201899994373052648345989716938779173325348547767647529160988985542438998030764420175306438858518207072038513664360905985908879070216069156102379349899544471658754952888660878997691670566078979940005195987259493512159628198906090101827331841914429358969184839073862821059400943312264269215878469013316796620921077244799814690434355127994011220041638393750697699141479399553359747084811371804524490919966410379714725200415331414459870271869 -9247155945465656153397925559476432992975541781462281935278489123804934847762489500833913193183733932905776020790478662969835879365116238125565077744775032) -26509487378481600038412836495388065888781507388737194948728047318975269277448073484403390476243134990463394380967295356958474984927721196047241216945988250219075749832868804186657201899994373052648345989716938779173325348547767647529160988985542438998030764420175306438858518207072038513664360905985908879070216069156102379349899544471658754952888660878997691670566078979940005195987259493512159628198906090101827331841914429358969184839073862821059400943312264259968722523547660643222995517768366821714892573665712075941552514588815849936651978565640166563350878466028503700441303440543835360084177205849382125496837) (num-test (- -17010604274474750006607667808593883725990508452473783283717890546525148212376267233909567638545898628257361383837671935903199638230375408397752251127816717091041943873728526445398525706450929660366518707254053655364610471112296477865068960744948010561798109833411657930112293904378353445961131058136287425064317621271289456901138718557297733713446119244533144377470099270824020439428168481914824420861176457152299497728390918971852021025089592998997807574907789524112450146545688385954763667980124432645276563626082835790429598328230426471161191074551543308732791287559033843466623138171520961684959997180979203053477 -17319079025684619178510812811805110270463447771889107440996086020812918555191263705580533644731591929176480040622705607552852994906782176254877135818109655911838591767583157894999741648979817400330572419476101372927546509769818404491634583907246692993992514876697330603464497645633398167129555001859772111887143352351860130929715392173452396253437927361301990735683539169040916027268831202732178553152351117118606495416985612909248422655861312689027789401950549626643389790516560291620711705848717875304929186131258525831197192620523261738944873398924939726689336762464320190834794155527335576391767307110012289717973) 308474751209869171903145003211226544472939319415324157278195474287770342814996471670966006185693300919118656785033671649653356676406767857124884690292938820796647893854631449601215942528887739964053712222047717562936038657521926626565623162298682432194405043285672673352203741255044721168423943723484686822825731080570674028576673616154662539991808116768846358213439898216895587840662720817354132291174659966306997688594693937396401630771719690029981827042760102530939643970871905665948037868593442659652622505175690040767594292292835267783682324373396417956545474905286347368171017355814614706807309929033086664496) (num-test (- -28362352496476494327713713233021518136860402239251781438945998574753662942796270292818595738100959519541952077905620088422871490191217157269435052965329201030095268586136492980900212955645939325800541690754639292707053269767151001292253701853012092829784482071789669480438026889625605099744553642207773753943711175375843649210118677569597324789367425691177169929576236753018329085700397911235750600921874606148324025962628852167093806152864269874177214562322576097931390470469397118268354868919899638376323751276807304678316688836173746719723312665764603485606350244811113608471530958617108833879194264695174468397461 -4081062111675377984305281082755054920741203741273067094307824323728798665450292976016160959354997082250970415737745853292134965575242789548167162064123232363464302136338349828801951197252612093077640695564825095503535921549690447893467349156939791370286866987224201115453216606688305427702274940837032716124925028835914047967887674858015919302546781010326385758988488478290741665427521820112231266659657169118374988259423444686317389869729817643396097464874333968181509317307320406521221309011946212308190273531009796563611621389720223920155554879800901239072885025170342349379379336047732368458185953903872634982504) -24281290384801116343408432150266463216119198497978714344638174251024864277345977316802434778745962437290981662167874235130736524615974367721267890901205968666630966449798143152098261758393327232722900995189814197203517348217460553398786352696072301459497615084565468364984810282937299672042278701370741037818786146539929601242231002711581405486820644680850784170587748274727587420272876091123519334262217437029949037703205407480776416283134452230781117097448242129749881153162076711747133559907953426068133477745797508114705067446453522799567757785963702246533465219640771259092151622569376465421008310791301833414957) (num-test (- 10367142604728811799331249565431331488313655422005202933702176605382043644320209814639311439871418581341534233560256605231366966869093495784665834232350567124110194965198962966795893926025854156729633358240069116588609932539289897499402463770167927610848388138020589286461244557962368497723086593344721146859584146431437967506007518396464517349944129896971137720357645026281243138165214047233258394590454775153944241555543594427555914116439316287902470043292624597940465373006598913770411505099332700167695871387948271302951230983772351549087620538875967635100644404345317626621438913980275970160864401622986870735123 -13323117602411502623386235160326625769048477819798659261203460002048250420188223753407093545503703207645050883770850457071863684414849353264890601744588860687970804808452855795406182324143949747985869939791374195222513169904228914579995165180964917538177994190229733465224857616114628815752065632238207474599531507602861647623695058640735949593381112671690796335596142010430124683781417828023076027476816068202219709673411776556090962187853799456968290579708094595903778622705850818245685205707447012659247018940946510378371952655457988959551256869060428488498330109152756599450626641948447980234503249330875085656261) 23690260207140314422717484725757957257362133241803862194905636607430294064508433568046404985375121788986585117331107062303230651283942849049556435976939427812080999773651818762202076250169803904715503298031443311811123102443518812079397628951132845149026382328250322751686102174076997313475152225582928621459115654034299615129702577037200466943325242568661934055953787036711367821946631875256334422067270843356163951228955370983646876304293115744870760623000719193844243995712449732016096710806779712826942890328894781681323183639230340508638877407936396123598974513498074226072065555928723950395367650953861956391384) (num-test (- -25321281404861286799950777949097462701962113587443565138655462269365151737118518315058035825695270231347401755128007072923189452859397209062457461602335603630181865680063451525170253746137368267674863889514153713728814272332433431604233690200451816570240227260445028630591376891139306370205846627093813889699170594185178241812081296510140572331372738998993116117098817936927692238682202717231675283209016857095739468507690090676681400453024293870135659990528969837132054786661560150259115734877162158755858653364070279937027014730947342216816307219127474721622123875699701715404820384545693058511056735799834754890692 -15870257059811626693754498423136372480069134596343998984549199283973854570508228359295418026089909378687774627821225399931314225867711515277913855368473873536462450935842786002269065816311054834857109074848803122494252885020527074586145467185882674518032764708782999568002770206995683800833252068328835778749976046128872525287656002968632147457840467536682726059599593635219947081138082647985895437016641903078766878782632503812736486529143041369932038649270950453231711525943737962179463585338023463992816994328519710963267459007592689204838965317062070771191372220277256094361390952025057574056586665509010902583686) -9451024345049660106196279525961090221892978991099566154106262985391297166610289955762617799605360852659627127306781672991875226991685693784543606233861730093719414744220665522901187929826313432817754814665350591234561387311906357018088223014569142052207462551662029062588606684143622569372594558764978110949194548056305716524425293541508424873532271462310390057499224301707745157544120069245779846192374954016972589725057586863944913923881252500203621341258019383900343260717822188079652149539138694763041659035550568973759555723354653011977341902065403950430751655422445621043429432520635484454470070290823852307006) (num-test (- -10064759312484387184876313010284016458560725440641239737323234767636591183611201479885347260175161165340917225306019885202675573016295152797559983194160634880140345743489989007821872426587698574795394887035658449467358615185057180305109018898637903449135520486663185036663238956537895356325733583128141439025002140924158670346599492383552938312402521066705186885506193758499006001382444818328802338159713646715901977137011576113434170842422373328479181457354927400927267448788528116619711184792932525071391797130057189079431487557270366699175956757661488296856660145077706273571985222726397848614141194988258117115194 -3689074607001776735792882994440038588887963294487080609346609068733026224735369468180206799966728461935654851527895876039403151156669223687679382665269013769686991783531091821265184956524448064027733731862929686596729449196238312997460578818232100254940830907672953344544031914926653652310468671685310332327057444910423081752028857828828473637496272809899061573593874011995802487442092326045415689987885712749026491545159340468151000027397821404233369034594141219014219707193746581364791219277489927025992135462852894714639406751538919395016165215641239054420028872350709704191189169571752512626755385998505584006855) -6375684705482610449083430015843977869672762146154159127976625698903564958875832011705140460208432703405262373778124009163272421859625929109880600528891621110453353959958897186556687470063250510767661155172728762870629165988818867307648440080405803194194689578990231692119207041611241704015264911442831106697944696013735588594570634554724464674906248256806125311912319746503203513940352492283386648171827933966875485591852235645283170815024551924245812422760786181913047741594781535254919965515442598045399661667204294364792080805731447304159791542020249242436631272726996569380796053154645335987385808989752533108339) (num-test (- -4621513851362114851854472268081584822344822740665629177305004335694395719163541988311496405455186973857145245414214464449674464879082042971313025249648887349614046805778335573547862191522938924075560443632614665169520240664970180760364771373836023824195690134618554368845612471858027311791638881380352344527105480173917778084361560336490212845414303819150625355111300877737042696291233444311426721588476948565949641149735838580313236869041013210454558557732497012037162735013212361842433337324577522358968152852532145622765032318936569346015498130151789662274686368870963891262060214274101000058555635785833724062234 20283847238128227963042817384468009365120280641032764409860857066215336820785816567924217697745867082423864450685360959383940995237907453126362378908108545669654749698030305432673477271848544313029448526561606175059997663752601262173667861202924953502866611309434183496911206954880840674239880495147451496219568787221129244201657487090244435562896841733049066453539864301122516559479757096183362477594406691085946787803323712522074578611082872627361465163804239673539339633332349145205596371287028267780080937728455742966681547897652607170788637996317683436193829274172400558140357237480809582038468874094877651383053) -24905361089490342814897289652549594187465103381698393587165861401909732539949358556235714103201054056281009696099575423833615460116989496097675404157757433019268796503808641006221339463371483237105008970194220840229517904417571442934032632576760977327062301444052737865756819426738867986031519376527803840746674267395047022286019047426734648408311145552199691808651165178859559255770990540494789199182883639651896428953059551102387815480123885837816023721536736685576502368345561507048029708611605790139049090580987888589446580216589176516804136126469473098468515643043364449402417451754910582097024509880711375445287) (num-test (- 8229768172162771789/4094631553683915058 14916542302144281688/9648520391570031013) 18327341244785642013243791303754634353/39507136041685332578233153660317693754) (num-test (- 13554976081719376860/5850035209629724601 -6813034992928443315/16012083383654426278) 256899901877002811987490932642058619395/93671251573905451634945335611797465078) (num-test (- -221798849980968127/896588178875000428 -10118632981534633697/16809799818197706916) 333990778095757160537366868413422249/941966737890699707694484674257410003) (num-test (- -10398409463665680242/10672871071680021919 908300169382593227/1663860017749090135) -2076589873614048366639515256135965791/1366012573135328609279238070700513005) (num-test (- -2198518713248421187/494031967775171833 162489257999262168/3608560229859558061) -8013762081101965644053022173225152351/1782744111192743850497670941715295813) (num-test (- 4025149216228566945/640594137312937394 5467380276809034025/15813352732084653151) 60148732603712157399679443099667862845/10129941051434949990590527231467828494) (num-test (- 45649282670476595/278386580761220266717341154184065537 -8637266763647548631/320617180101036447149595031898805939080) 17040443444897688379155017841073877168061229451634462447/89255520501631886327999278515127058459530587144975987720686743155549485960) (num-test (- 5648415331928005377/86815630814151297970860026950116430492 -3858618729527320883/27855468652821710859204555976171379400) 123081918822962876101148539477322308270739795776139149559/604572520679633516300271119677141637780408278090307422820905500994965166200) (num-test (- 9781572955588417059/112881800445343004034168709823458687843 -5059688483724168531/4577416283528891230944530353546966748) 615921077060787960354561606126348783111829996215681822765/516706991472571912574910836774186280180852506048696459094758451180832844564) (num-test (- -4967914039344839478/238170260180199675500515253723794945205 1851848905279976507/5731170327270969184071911155742503278) -469527297115675955424190428047537920421409443442551107819/1364994327983166854234805393053180119374354994464588574791772715189542881990) (num-test (- -16853061581795824324/96404437352723357070647888504166371117 2887610208906060444/32980643277330946266739822018299212963) -834203249643667606680245846951263316484378801689149307960/3179480358681967952651970543397987660141008737601948320258541111852875189671) (num-test (- -10766003534404571638/1736320411127247334175538439020437437 -220564366893542891/24024005562370344889629855466198025799) -11228676451427374102904112111967705085778332338188090365/1813624835433832784217556253227924899981441517333394378436857197512671181) (num-test (- -4039872531792560303/2717817538621352660433068255065439787147153801016478776178010367557953211548 -17969900169229544519/10371230759745501411127733226376204123221866394120596070959771442399588297129) 6940459580028931824293913174633904994365279610168782399332846513086074139209123514834476635325/28187112855925579976299840753672542065528422968220885043792832460046226866036339425358907691441054924266606457279617295071355282523744922239122018045692) (num-test (- 11905720953886477738/26349991043344773150817457299711471013733618033386232710348739943906972457535 -1868508269239354100/7915113871665192715310471309271830385175189228544536787145345883401181858893) 15941145914794937177093386304443205602552827651536706608400845076162777444155363739893353329726/23173686625047977587990304423741788120258508897732978034793987736019678129860415537604628640859289817332994555163435451240013483415438259775849311623195) (num-test (- -2449440712560236858/3924161613720467738425590715321110829708355586356453490516463081317902575263 3313932993860824279/18392642760231276916239249302906853654153090246504347205856270072174622214792) -19352032211145724571420568734409847660231095572377236173431089875006133635431666731719362137971/24058567564857748536604240288023690440577404826273237225585673569644473540232022448230431237781096357243673961302816983638647478040822458289501843963432) (num-test (- 2375854596996813469/17171542567603713573317138241061150416263899780234956304631913156611236192733 -1690236091628058998/115698505401619203741389026136939663329574241316722960060260525901879106902321) 303906786920788985464713527121698374469813384178920405503303785899916213843318155692692663023083/1986721810512032345893371071989737461519340072368099757524397292434629497187713075053126253107235936414498803590298681018206068059043963268488989361033293) (num-test (- -9066703779833220052/53996509329904595759286231403247566365148374715934463324003880626270687736687 10104829441267883881/34350188217372122913844475743718288066233853695548819225257606841719829170673) -857068498550946301314281599902676812596945461499639532351672507051201056365247232693696093577243/1854790258563312749374056592838765632813507083399863975139987272744324437901043103651094837595789610803765303659351781344942305171362498886075754606580351) (num-test (- -712905705954993103/38361275706852471555340413672243335795384295466685977818182375699688812583403 -3487523845474404757/24004509207225606167828624323100421869226668573968691661898194620137716910067) 116672912187985693533424614379662678476187446315443107971581372764612623068602629062267386180170/920843595906060126846114857872490000269306626188013726759480780006531676144330596572087176480154495471428384288229491172449159350622326294294528887818001) (num-test (- -104068455909264700529593875361271227125/3443783531459345396 94266182755532992545775726171008609186/10986871169556601787) -1468019045636814162670978305715811638938423723806410280031/37836405995984502494576730289263822652) (num-test (- 6250188382163250356218308848100308290/74975517450841979 10057222263694104272437942231238950849/1377150882331486572) 7853407001895533030925726629648778749078643531548391709/103252600010686800286181264132405988) (num-test (- -325869560300902552275820653500571757882/6390430580148850471 94468553562411191993094256419298214695/11908765973274803007) -4484399064985071999330976874105690617426359030318059422519/76102142247451389303559481900024166297) (num-test (- -93570528036598407567281714804477572547/1681213810574384291 -244906502561054838674546679498356325029/6878656438675875801) -231899320744132980638168050942881155823492361410591515708/11564492202898292712047439710761442091) (num-test (- -81411835730261219386583131450337332863/716127167248934 305772198898084305417824619321954306670/5852119619187572757) -476650772889757879179369019399921041943854248979406203071/4190861845290706865359628655691038) (num-test (- 8378821874364768218652992773582270365/264620166167099506 -235085292482743132422942426826553295351/5218853722286899445) 105936154887632142427944491040385766054707164161382644031/1381013939193345109641609957531174170) (num-test (- -46932041053326337601984043288899377207/83004348019257810472659105973646518650 -172752976692389001100875729845538600392/64697064048458368935602368307247306331) 11302882932785858045495103305619355060523322049764297548269071809310077113283/5370137620102451116225827082734739449691101289924623877117727128768254573150) (num-test (- -5215113722152182902641295804790889582/37267147737183802417372262122851319461 -174324915479281952095382231256728338942/198797486533978895289571841018885549001) 1819946959828587625889363843813156766676787993042778284071188313098762447560/2469538433480866339929667414220581052912334718874062150193407525506073469487) (num-test (- -308468863588547635528373349890793262605/277175417813474671446046438490775760091 -88071245580784145343997181342216325733/109042592277517238289414020635536175644) -9225060231388102579469362745283215538990500777711808852192407359260779270917/30223926073985207174135233898799350451872811382182855106546181559011381423604) (num-test (- -139281160373255540085888405052544101003/21590054032847718908692432707921390245 -175128181843395150044469443628898278945/101874815793501611839718166887463701141) -10408215647857282226079103083273257459322595128147732742048301223816698452898/2199482777568107961766315941206227462112836158088743951492692685709912769545) (num-test (- -13653637423911886957204229566898836211/6724361745919744069899921221745423919 60537422461958273742622747790343370991/323722395245687564470126807800714703749) -4827063738484690108652046326448960810791170812913084889649499536314520788768/2176826490887613088066161490358401961235974091796973399049221882998503572331) (num-test (- 207284509647982883454717074874778610186/315575836476247924963087075944676754095 59454580888278446469281150437143941047/3799382139920332759258392540934029749) -17974876032324524053425850245755672169670471578477359535347261991433397414151/1198993196898275844180025803639723883733761367273976879884312817813487572155) (num-test (- -149255714031984711085009662216310611563/61209488724728410476016289765233999883959861482512968048939594260689484910535 -206353007879160639705730135450663155/12341134377195982958424940281067948493740598784362073339140017508008773524522) -1829354061323966095884091779117676852909282652562065419187935424186237303685407507859167669375269438805585201409961/755394525511335693198081866608161950899365908489933659716533239785460293292606918153507868614180865950008697266433342863460741791684603303270127798639270) (num-test (- 286228990947356503137685907205210886138/64525193112922470913382853022276019736227442678252533126077234112153953877503 -93778927468512815169462456699065596479/70019706577332037325570327903202382111804035215024271930215402736305222068556) 26092773364888269343302672267572690894453186378630697330693315371426642609003667116358459590920104883240139740188665/4518035088612517412858008269349176355736855744033363257986123715832709510554983209440815107866748014413528943649032845277041680450752670951433682692095668) (num-test (- 128067958966292694713545212085241612749/50804897676960765097908813878456128842417954009101908722816951877006748778869 -331437715897535092432788513322484606485/102911257177761006574263802557003927106564530572416215828322919550454967864323) 30018293903870953799879886574342637699455128356488843398998059810000258259055116602688738404467489640369684487419392/5228395890723542025866546462435908982096651119675992137235094920338650164475761939608730060759309002063498665792819192135030537577109853650729817121390687) (num-test (- 27065789167947870065829490227927612633/10795458608984562931374526676297845621730864739104955678079256994070639461197 53314096352440087811254806167289750292/44807028208492548064750449353871285104149154384082409595945081934090139448067) 637187458285170434834128234123875152637450428605039275620795715002449318075555518355578432548587274399560043210887/483712418416385035748598509413117409273155809870339120248356475239836262578288026980177669113025449532258001487616187498682131415946755647640047843156199) (num-test (- 275528434092876314751862670579225752027/23290954563951481764306221308726902093226107549717031306984541394996363441752 118398743375843543978994815511147957868/26050691402435592629863948804505350954161759382372519491414484055670238339031) 4420086456754111377514058698455330162869575963826459083894390154200727636413353382047981846196341965799691593361101/606745469813648893293125236863835131523556569847025597910312571817347251611730291043895952533706547565767925058454286630395458711598751591845070996622312) (num-test (- -263828172858355421790882308711676546531/27836884730007976814146538035133148053942251062564400015534567388490010158584 31580638196736633522674344981675107601/26210154715367115936541726366619494863883445533448748701891278370021519416412) -1948520953518189888695889830515156795224640917019574042614412953331052369986548949517168001067643449389746489215939/182402263891837359872743630675214135004512597266032306942151126033873543370078488920825920736994254287019873146147276876145783659805845233146169813070152) (num-test (- 43029409555492054023102681165249027816896930295612442385573977041111849786681/17478431621804970398 -63831159286570708329826084149841946467426290005331979697932225104261019322894/15909114936773208135) 1800228375210677909820927489860838061135888931548234366640994061734196466170531105718785437541747/278066377585826623354880511023167787730) (num-test (- -34677827126365037739221949705076349308552841821108642369491195428278121711851/12321935233094032355 2466652720703038662112375481129216761044838204088317060529010755963314905661/458077759838279587) -46279076433142446690218423399092373290016631287423134630356063713373023144989129659854095947192/5644404488448083755690706619714037385) (num-test (- 75657421640076548917316021979547903196453821552146142751737530624725671569062/5416811919979369403 -51031635143911513328361770575139950616395278082588474953679149885798666896870/16274277637120569843) 1507698654622877634185545368063085304919907004898369478770589865697455127479301592176158803465876/88154701093808389139357381843158713729) (num-test (- -86696779369804422745383183615836359604633179506005810847902134850836986706763/15354752711854066426 83875579121692496325618937810567731584819474189441279434601944065565889174333/1890321146489013312) -725886765676185953186290796464189476910148783977596698524963064505627422317719186476684911836457/14512706875163632554860591439823131456) (num-test (- -2824584270835350806110810310308644313069326027498380007733023821989145840779/3128200028313826545 -16485532380752962986834975164722153533427821569516340079793116204530103476885/4044901389917631001) 40144878017198534388242075435853869853984060096218401720566307902396394251666454424383286522546/12653260642466969643085415999628721545) (num-test (- -71140717297594692514165816539390347954764512441693085945645019026357644035048/15130773661553937219 106518314860779634188990156539381479314908411240039365434170935270962911954978/11202282371121185733) -267626990691150539404999353980899804835901788880218020004516046839225745741587662342920970677374/18833244338916713919008552672213388503) (num-test (- -31372444086039981530710911528326367048894875160807395940269724829549418985367/149682691887362386596593782520991059630 13980025800771566396092717430902170466939197897483207383178768135899198010674/143215924045734814208985239450703841431) -6585601463869631351127457963734548845246885851328680299125624347680443020577881573937479731612385878788264587830797/21436945032301618223045694723696447349670080755369221855700055538448185530530) (num-test (- 60002561005149795132492915799111287923312170708430066011808292212167201814322/16346766380600148228286881361520329811 104734497917913613491539581495799848702023341599268915776996571583385896191203/61937476024742321910315674059586179787) 19844918952732846654680216616282727016967753441473733514766184661191061075852141231786969917096326062063227788681/10024529215648371311559365663430434349900555024451481776473735938354274557) (num-test (- 78980655687309201443760271907411093305339297143458162112992101000746746121121/24094471248783344167514231679460830840 10562090177736342378322146805187203837437609238688017154037816697523731420573/74961473522415640988394298626742882726) 2833009175986364875175323375606672657538996734036576482627590142336455915129629838687125527863027857335645122892263/903078534276138789186206765245648729133926893901427360507431923032322034920) (num-test (- 96507496069338193466683209170737942070468924698476218759487496209308948365/19252547784216386872197161331387216893 12563973560096321588715986952435909079270363887929001032891628645353358046011/79879611474172059435223762585596250921) -234179520035021783886726161079163865833895106001667476480293126893061678147610754451356994012799045797572757769658/1537886036891137155393554113191390737924110193971845147480358562685078008453) (num-test (- -95307376781556674397571761484869767912211504027346871580288574968524683908606/128329921725822403056205582017133271311 36170894925879686192917617159219095595164782822289198001474013555499918728596/240886887357120796976726436320063138705) -27600105449672599524131749634403660999916186956076872373762346977331203119722064380924286397976905109959929163304586/30912995399316310109755266138690547023211992922143297688759057498082990192255) (num-test (- -22104893896795356297688360407985617971036912713007110938688208155601366216839/5790727918973991999188987227357894380 -2339372311396919406471876113751500811577555408710269902369834593304924842262/12937689744925498650506694361349920911) -90813196841584888136609582546105640167792279132393576014002859436259486025871518847027719826829986116492656710923/24972880404321196721702428178050372850585634300866259560981343234830460060) (num-test (- -3426218098660813853559652497557253942819662042768623922183022792185928242671/2077407536662385613357832628600529321326686191757127715026249042748302985178 102639297566540827510784861997871251414598617775200449087621943894148321803293/83089038429507982364103335021257902316010144851865721965726693103637274338545) -497904817589969304680335736144278473886197067420059149312627956679073246109792679236301202959163792633927112737045328517845259242265445360227131779644849/172609794647490471018785535271654901168315737813115654161745630290269473799997219289162551586864155467201760250711449118429648095083028041134558889086010) (num-test (- 1543899448831604569141696144740105016328586790221799945430718394112623114412/1094690716976737526626281319975432667416762320123576900412499904933271786567 -101835025746074730017715423582062511397387458863000475669454309217160145993/55116548932808468782187525862059393507883043749327746382569396580129398962) 196572266866178229534134252625134989714563665559807019513454337864363053729628560611312158082929567528955985669620113192156991984486011150099776316375/60335574468539540262844259780498204139853746803235564167348945699931512713417761400790104247218084745081610815218855896912895393599203789305655343454) (num-test (- -37581128364300495505521143552535972339959603365602244668159915869829949338997/42947503543372015019662104425995959382231280059683481488692141811517675950053 -64888994735350842409379226446854438865448614840503930577860382883594178287934/83188698741706753136718468601650233481619465918167616089202536622553688681087) -339504834548876267781536981106771553482515399809961247195394672491113984585270709765073243997043174508213253440272888923497173265137136111635177948889237/3572746933977957867604303713153220827104741303667912510494658617478381525690274918494624922428110123336345510454960178899375325287131764283538305257747611) (num-test (- -16230533405187239318665866908175768720879595131719076634847964191318368133798/22572606803697929681675696479626869642065470042484269772607381297011844085929 -3238806615045730440879378702226410558103197865253164974472379309242480970831/7167633180423354812410246140643720752789573307606828791458541239290047771821) -43226201536346598702395278529841763047400215735214225929426206339139243925579733185594282160061132691154727543083543034702325848468839969037250195569159/161792165494835249202675342837643048016103040739685489755239980324180308179745586573032524649518850731442178659412287492012066453331740508600962908806709) (num-test (- -58154703770626762920775801228739843350302933064569814497417973139312614069763/25655935043535628671780902110427599603857741303802203417196105196580175051005 2291927744682353823611191393035210406213286149316388597509251757479544491322/2075117977066796442381930295725401140983312287419314083032058820231519915051) -2848879691864593463404526996418656511058536739346277043463623510210968076493148319480555434626780964688210750895957968447300033820091387019574369485421/845064952814266442598400897276554701819815257830830535600041451476645443978805142044657833921127247033533628716506571358424324423237490438402971304385) (num-test (- 16233726784138742204308718138203086218138595789383817317246449554340898453104/16370584482945481446847872945862788646563748664837147378940234530469832625057 14431071141710676049963542765626402177344958369162454874051268130438178883381/21166786163219212747261378458659387864767326410261049063051557406799162784072) 107370754167217929909136144689909613387440429633745577224054233373886366171618903318258855919060113440621302505589923655976636732694637334616990468681771/346512661117421566971293748815177161526095870176610277140325665174756629068111228154091043637596506814557119477231243643171068111260010676990408227692104) (num-test (- 3872339191937382556.0 13437882608410293981.0) -9565543416472911425.0) (num-test (- 12702320881720530101.0 13823645380834800545.0) -1121324499114270444.0) (num-test (- 10222969257152373972.0 -3454292165863475982.0) 13677261423015849954.0) (num-test (- 591233951053628288.0 -17639978232337836611.0) 18231212183391464899.0) (num-test (- -7878405903223218778.0 9050739027069287469.0) -16929144930292506247.0) (num-test (- 11347120771894057376.0 8443917396834074370.0) 2903203375059983006.0) (num-test (- 7831959259127703467.0 -257470007821066702597399141202130667973.0) 257470007821066702605231100461258371440.0) (num-test (- 1092406341647857980.0 -325710450166845666190895573961860069495.0) 325710450166845666191987980303507927475.0) (num-test (- -4220606126689357919.0 73461013742902296577411907972196819778.0) -73461013742902296581632514098886177697.0) (num-test (- -5112059189225304080.0 334306213789148650102245018234146620793.0) -334306213789148650107357077423371924873.0) (num-test (- 3093346224554776175.0 -204967241927023874963787190016588249299.0) 204967241927023874966880536241143025474.0) (num-test (- -5735747638156472357.0 -3881750746805128137401544408305666047.0) 3881750746805128131665796770149193690.0) (num-test (- 17639095392510638323.0 13312205908441007415860933757605397223142073616822325142416364932887680287063250296996056787873086490231950036662943632990219865746131453861285495087665017.0) -13312205908441007415860933757605397223142073616822325142416364932887680287063250296996056787873086490231950036662943632990219865746131436222190102577026694.0) (num-test (- 16304056910692545233.0 1463591032326743052350022746892396184459320617971409440301562638996633667625451301419074212369365394140737678584830314878769698416417465834928609990708982.0) -1463591032326743052350022746892396184459320617971409440301562638996633667625451301419074212369365394140737678584830314878769698416417449530871699298163749.0) (num-test (- -10347586523508777315.0 12614325304787850623826535169596975975360455924114817820074336137897280818245940873677389644701038550150832199897314137414727161192173691528917744363375331.0) -12614325304787850623826535169596975975360455924114817820074336137897280818245940873677389644701038550150832199897314137414727161192173701876504267872152646.0) (num-test (- 16875252323587344863.0 -10230183557696638447600885112945653217398839137450096120772416948425622105048400944465287395231588821521217980407867153259741079758527788318592431794213674.0) 10230183557696638447600885112945653217398839137450096120772416948425622105048400944465287395231588821521217980407867153259741079758527805193844755381558537.0) (num-test (- 8574302739232756920.0 2945205250727759066959418729185252318153395797902208079569164623770839848878181416073351760975066439564334127158302281471631001294503759011790017443478716.0) -2945205250727759066959418729185252318153395797902208079569164623770839848878181416073351760975066439564334127158302281471631001294503750437487278210721796.0) (num-test (- -17657597319577965851.0 -470389901349206124503884936612357721199915776516939967013182926735009022045917047211666512521578494339222795740836335004070464944715357800461845632614015.0) 470389901349206124503884936612357721199915776516939967013182926735009022045917047211666512521578494339222795740836335004070464944715340142864526054648164.0) (num-test (- 11472336850218354926.0 16764018932433717867649699977474298016589762238077229911249331402108995850754999065988360217500238643747316139204767820295123085026049273617874157749889925712672510963712964034497935503076689670786498045302562704435768723916334451317158760704743066709581593570757498670622547878516907127632802801541072452593999435195637193819500375063696114131057474475407791672955417184592088612921927282233762919112197264895445408873539746256555444555901857369535350160665235184955438709679669964546134487688796078142789125799020704969226557493354453298489954288702387159956161243151013189140749021799388406290339231792790773612376.0) -16764018932433717867649699977474298016589762238077229911249331402108995850754999065988360217500238643747316139204767820295123085026049273617874157749889925712672510963712964034497935503076689670786498045302562704435768723916334451317158760704743066709581593570757498670622547878516907127632802801541072452593999435195637193819500375063696114131057474475407791672955417184592088612921927282233762919112197264895445408873539746256555444555901857369535350160665235184955438709679669964546134487688796078142789125799020704969226557493354453298489954288702387159956161243151013189140749021799388406290327759455940555257450.0) (num-test (- 12682607562584942903.0 32133619583510009354538204193505267426986629771080807813988708187761849276650847958886764459302043799013813125903744946349479743277662066609741649009023451783267511140245797235200413941774959851628239089013586399425314412329003636059313583335807925401822165199322334470452126484173417518861322963430951772895619791799137157183662289329901964728384697377777905235894234370773419160283767144177627084271804319157013765325677633945370597318765372346484383325176768117059688792498687750479618961541872574768601477738410497806623403054372221338126223825515939164627992974469102910882915893925327931884157735553718792115929.0) -32133619583510009354538204193505267426986629771080807813988708187761849276650847958886764459302043799013813125903744946349479743277662066609741649009023451783267511140245797235200413941774959851628239089013586399425314412329003636059313583335807925401822165199322334470452126484173417518861322963430951772895619791799137157183662289329901964728384697377777905235894234370773419160283767144177627084271804319157013765325677633945370597318765372346484383325176768117059688792498687750479618961541872574768601477738410497806623403054372221338126223825515939164627992974469102910882915893925327931884145052946156207173026.0) (num-test (- 14621880654476679971.0 -10075923784619510279100488003620810539888599376089081798647754628017452762406215094511315867213396543200861274584884759429891242650999761503100661310915213260386281412125687376866399124849043409890009033179987278297335571911640353059036551139958369871790768643514550179661619387008678118363266091945225880595898524898713646458647465935791224159084684209727153050053537752111696883536364966526666445737103854446009305531519860527938394412863332757413309423156200192973778629503534709731073637828912608835085933003410694216843775182940057891552358942312728978810053715387504707194992816961400377579655168106377696154728.0) 10075923784619510279100488003620810539888599376089081798647754628017452762406215094511315867213396543200861274584884759429891242650999761503100661310915213260386281412125687376866399124849043409890009033179987278297335571911640353059036551139958369871790768643514550179661619387008678118363266091945225880595898524898713646458647465935791224159084684209727153050053537752111696883536364966526666445737103854446009305531519860527938394412863332757413309423156200192973778629503534709731073637828912608835085933003410694216843775182940057891552358942312728978810053715387504707194992816961400377579669789987032172834699.0) (num-test (- -3220156644655019630.0 -8347829670073174550775641165362740628312221836466572623516708794243074870361401136762432100726575330214254748615114820602945887237367461962207075265579588481261313345359877816874924645801358760718027997416917747796144940020489321523749233377708490614979453376328244189926517907474704635785063100359787580409065317918203485474119227673185211436285930586838616288721370975925191964611302275354365110550116042403226844820172448647475637867255305805337047967053177320593337377763657329816935516961201488840745892529800883680912275812320160312651894919502389242002380151562481051684439333368396132543667539444686619670713.0) 8347829670073174550775641165362740628312221836466572623516708794243074870361401136762432100726575330214254748615114820602945887237367461962207075265579588481261313345359877816874924645801358760718027997416917747796144940020489321523749233377708490614979453376328244189926517907474704635785063100359787580409065317918203485474119227673185211436285930586838616288721370975925191964611302275354365110550116042403226844820172448647475637867255305805337047967053177320593337377763657329816935516961201488840745892529800883680912275812320160312651894919502389242002380151562481051684439333368396132543664319288041964651083.0) (num-test (- 11628988978410243120.0 21091260149209133824278525560739673446778991946138130571540201996950100883736332286627324787663044982195445635023357027423513202277912840570399895946346028843517588470258087913846945044832851780108963206182331994065720076983528527849542421619745503796476103034657238118665288185878258232226731582201217795631247916614224227701409259346052937919425072595891571572960468193421257458185693656090215937518204243652916583730260295885562094977775951577484951577581277292356830523013216949489797535362720471761788697932265967910160407593278848113303674799017334692501935041730808945554336564957621028111014116286675587727714.0) -21091260149209133824278525560739673446778991946138130571540201996950100883736332286627324787663044982195445635023357027423513202277912840570399895946346028843517588470258087913846945044832851780108963206182331994065720076983528527849542421619745503796476103034657238118665288185878258232226731582201217795631247916614224227701409259346052937919425072595891571572960468193421257458185693656090215937518204243652916583730260295885562094977775951577484951577581277292356830523013216949489797535362720471761788697932265967910160407593278848113303674799017334692501935041730808945554336564957621028111002487297697177484594.0) (num-test (- -15960716439913426281.0 18799211173341989380260980155501104944815245973352765317821146163884181375747259542484535639646490774929026134833947975785613727050541297797675705933339289016115326958150660323801621778641184271728990164666383865587422591755046779736996211052149338115836473967202556153668963815595875844414662034458693455631979862997316049580586739835122770408911308146605671192538040301857163633538268589024651373766021087864982140201615461513687698136663128896835597598904095187715456109340116329587986878167776146023396961265667934659006280575496363066974484893764810659481361856335795455814679851690737943592227795474197104696127.0) -18799211173341989380260980155501104944815245973352765317821146163884181375747259542484535639646490774929026134833947975785613727050541297797675705933339289016115326958150660323801621778641184271728990164666383865587422591755046779736996211052149338115836473967202556153668963815595875844414662034458693455631979862997316049580586739835122770408911308146605671192538040301857163633538268589024651373766021087864982140201615461513687698136663128896835597598904095187715456109340116329587986878167776146023396961265667934659006280575496363066974484893764810659481361856335795455814679851690737943592243756190637018122408.0) (num-test (- -181065640455671431985325539445069267017.0 14120143334024043377.0) -181065640455671431999445682779093310394.0) (num-test (- -91295299684959299024846233061686623774.0 6891102275697080803.0) -91295299684959299031737335337383704577.0) (num-test (- -252582289949155881579950873916766853744.0 883304029266526072.0) -252582289949155881580834177946033379816.0) (num-test (- -10104159950635417603045689770006558103.0 17251490913777465304.0) -10104159950635417620297180683784023407.0) (num-test (- 288463495341489091297108607960869684860.0 -16376960611483226267.0) 288463495341489091313485568572352911127.0) (num-test (- 204661965092367792468062569536290631004.0 7774991291341524479.0) 204661965092367792460287578244949106525.0) (num-test (- 174559967167400201536723778015754014369.0 168183438971818617783400303174116396891.0) 6376528195581583753323474841637617478.0) (num-test (- -253300708624436983509156598368557395374.0 -77166863757693227553099778725240875400.0) -176133844866743755956056819643316519974.0) (num-test (- -38587765028356074196061530813295290944.0 5999161273284748726648331130480323187.0) -44586926301640822922709861943775614131.0) (num-test (- -236400856885875891058508662756360145662.0 222191413471626205952456600591947275777.0) -458592270357502097010965263348307421439.0) (num-test (- 212937903940173587742882129816769611096.0 336470165768472077447806282475185249734.0) -123532261828298489704924152658415638638.0) (num-test (- -264812595676159375893264580577855253845.0 -247068943830535581577267897204259299723.0) -17743651845623794315996683373595954122.0) (num-test (- -1725732715479127274526681751197327660.0 -2279805492899538651574406423954277869507456204136276822451602661149698386520868702017367409743272511010382761246500508887739763323997191435566266331339917.0) 2279805492899538651574406423954277869507456204136276822451602661149698386520868702017367409743272511010382761246500507162007047844869916908884515134012257.0) (num-test (- -220007189346579184019349894240059989979.0 9116030813176547770422918633286023943039811682891023288884273747820892639481842291616424036020927750322528731882517057595815179415042385175627374957565803.0) -9116030813176547770422918633286023943039811682891023288884273747820892639481842291616424036020927750322528731882517277603004525994226404525521615017555782.0) (num-test (- 139683266109784685815165642637380856544.0 5782493350903499652295971390391981928106911831248674750993968151944332845911526084530951283012280786005612601970108688202931002414214353708335212597807345.0) -5782493350903499652295971390391981928106911831248674750993968151944332845911526084530951283012280786005612601970108548519664892629528538542692575216950801.0) (num-test (- 239160165978290709841254489756277328273.0 5152132850125501873897264811465207492706871561577273155117982457627773151595716641409297120994045059130053034927464958986304380141364542178714472948085275.0) -5152132850125501873897264811465207492706871561577273155117982457627773151595716641409297120994045059130053034927464719826138401850654700924224716670757002.0) (num-test (- 315772704643232632782106484978382006176.0 -3689252327480456512393153800679864208480329729627292260734151097785848947569336194072922395859496552999163037466184616218582046814434719444842678248982224.0) 3689252327480456512393153800679864208480329729627292260734151097785848947569336194072922395859496552999163037466184931991286690047067501551327656630988400.0) (num-test (- 82735713197488344149642668226610301853.0 -12473025194535761005577066561696471986140205263843017221991729197337093872383371857001077050460827652296473928714097816492579684543651922277865558518876774.0) 12473025194535761005577066561696471986140205263843017221991729197337093872383371857001077050460827652296473928714097899228292882031996071920533785129178627.0) (num-test (- 63472235942371758467270296983419551089.0 -7866520408163137968600317959735552406794938230345293650627055135268307695389903092041438746530663083967329111232451176014649873249349534808700483360707382397988918594143264031213181385790969271527978925616276399184489007642142996251807222768397530946779296600805549276528669432847672215219943599871223372831999133812100481632278022608906065923652981249057846548868473376683960144009223047416366697876553049362242497225174860431577034875737250719899362881567590934060155436179316063810148362442197071642183371654740845983314705249832168923202400873364289483910868432511677656218937984504828452980698439495961392749596.0) 7866520408163137968600317959735552406794938230345293650627055135268307695389903092041438746530663083967329111232451176014649873249349534808700483360707382397988918594143264031213181385790969271527978925616276399184489007642142996251807222768397530946779296600805549276528669432847672215219943599871223372831999133812100481632278022608906065923652981249057846548868473376683960144009223047416366697876553049362242497225174860431577034875737250719899362881567590934060155436179316063810148362442197071642183371654740845983314705249832168923202400873364289483910868432511677656219001456740770824739165709792944812300685.0) (num-test (- -284018520801241078671538235859630240269.0 -5529748211779294240854894683633173443789067073881249229985499707296461959655918837051490512357840133495603640185675483847478587849599477020706893805485599954539589062532211767295361120129440287144117406526027552427750375526095104163474774446716012360038076376952619723549765229763943818011605991300849052030142173100367582906381575666628005795818339029350398340616624791399526643991489247585213423174803853961438830286737553181353007081438503238779644371968004083452645077716952159339978836669723137339898471600546912430030276920763475622536295311290657163861398519747560279682401429552174530714298081464588450842581.0) 5529748211779294240854894683633173443789067073881249229985499707296461959655918837051490512357840133495603640185675483847478587849599477020706893805485599954539589062532211767295361120129440287144117406526027552427750375526095104163474774446716012360038076376952619723549765229763943818011605991300849052030142173100367582906381575666628005795818339029350398340616624791399526643991489247585213423174803853961438830286737553181353007081438503238779644371968004083452645077716952159339978836669723137339898471600546912430030276920763475622536295311290657163861398519747560279682117411031373289635626543228728820602312.0) (num-test (- -171812101820192353275910956459431262142.0 11401673303315394031728944442295528921842441448377692701102691446500671963119794838260543877466107345474902885032629120622020177051592733148817057943390167845763358795044702079370835841331467130719834250134674578757640577473495192331790176510774020541399177011446664359866582351045889299070080989390219063301859447807907203943168891690028442190793548699886572720360741686677780644932612683647303776634496172481504075784427704287335805355801794320914944330891519283383694196486986108936857630373759865062862204149003789919218681050221366182434949855054760827976853645027544605870235074909890698574792562001595287630131.0) -11401673303315394031728944442295528921842441448377692701102691446500671963119794838260543877466107345474902885032629120622020177051592733148817057943390167845763358795044702079370835841331467130719834250134674578757640577473495192331790176510774020541399177011446664359866582351045889299070080989390219063301859447807907203943168891690028442190793548699886572720360741686677780644932612683647303776634496172481504075784427704287335805355801794320914944330891519283383694196486986108936857630373759865062862204149003789919218681050221366182434949855054760827976853645027544605870406887011710890928068472958054718892273.0) (num-test (- -243638660221338112796448050030955119997.0 -32214383478080953899491069562585164652288236626686985994647827422262342469970423345510055643470262764747630363450204055220886177681745412924556264758690138113272748656941509018308925555317383307928766093730384151056027828368474245304944063213926492719166086055718735381341569379006804236876950175122702350552198046290567043195716369691666842524594399597143281611765509174168738392889075290806378316647736667077047013214732267367344808724905727602402784621437141760604478301412768904784950365257469208085143467704875589485635570084387755189599791857576855454112556762755762408826226326879491415484319411662301650468948.0) 32214383478080953899491069562585164652288236626686985994647827422262342469970423345510055643470262764747630363450204055220886177681745412924556264758690138113272748656941509018308925555317383307928766093730384151056027828368474245304944063213926492719166086055718735381341569379006804236876950175122702350552198046290567043195716369691666842524594399597143281611765509174168738392889075290806378316647736667077047013214732267367344808724905727602402784621437141760604478301412768904784950365257469208085143467704875589485635570084387755189599791857576855454112556762755762408825982688219270077371522963612270695348951.0) (num-test (- -126332081511349770866908261827634312283.0 31497387372874133218238910173378055967910722258532087598053588964599898753455370244114881403020152175272452951858324158004662566613339529101292284073176382818309096142522412043073218657587031893636358434796164444941535757484360125937835242214199979245499374972029624710574236962978707708765065292759037309958875006017588240959790355958632745299212449602934380927677385974488564420550408281673927387615657765312151272852486266800510090872812376232597458154951925709496664568906509814364388823105469855516803225244972466742963619633076158367569109107733990828830121948130235858799809203410103682003414364238243553515261.0) -31497387372874133218238910173378055967910722258532087598053588964599898753455370244114881403020152175272452951858324158004662566613339529101292284073176382818309096142522412043073218657587031893636358434796164444941535757484360125937835242214199979245499374972029624710574236962978707708765065292759037309958875006017588240959790355958632745299212449602934380927677385974488564420550408281673927387615657765312151272852486266800510090872812376232597458154951925709496664568906509814364388823105469855516803225244972466742963619633076158367569109107733990828830121948130235858799935535491615031774281272500071187827544.0) (num-test (- 219979452670016849533060110266815720199.0 3900115048441644499033281842448985956665866771934663536385503692700586024397767816761943054115584011069129310718114010862034970648115172218305599786238607524420973404711138276011261135403209178420948996472570042497859127324157786975578751148348046315727383390370594954695454631662061021971027739429505825056455676233533511412589936865597034183410893428831818716136282201523804692574965779771140320669492229416601369453681528301333865290947482219850340728455965391492610516639151652595539203632139883064874286555941718154489936421274731413286355640404192677546692090304496817063325766995908926108582896362623757323811.0) -3900115048441644499033281842448985956665866771934663536385503692700586024397767816761943054115584011069129310718114010862034970648115172218305599786238607524420973404711138276011261135403209178420948996472570042497859127324157786975578751148348046315727383390370594954695454631662061021971027739429505825056455676233533511412589936865597034183410893428831818716136282201523804692574965779771140320669492229416601369453681528301333865290947482219850340728455965391492610516639151652595539203632139883064874286555941718154489936421274731413286355640404192677546692090304496817063105787543238909259049836252356941603612.0) (num-test (- 585873325961105129055557280004608765382109855007674169500308242261038324959928764512890600512016613154122762798104714052579267789493643522748210870974797.0 -1855792162818946202.0) 585873325961105129055557280004608765382109855007674169500308242261038324959928764512890600512016613154122762798104714052579267789493645378540373689920999.0) (num-test (- -3026050092505200332789765255096964033685859497096213532090644235603419347590512426830117415222669642053441336442247132403948783838396746566100575461602162.0 18009081534399282710.0) -3026050092505200332789765255096964033685859497096213532090644235603419347590512426830117415222669642053441336442247132403948783838396764575182109860884872.0) (num-test (- -11124638695599888462310706699308855434715251048597328942409434888923094027849143412724699165971400546471660924330688750607774759764580214088920441698992069.0 -4827559068742614723.0) -11124638695599888462310706699308855434715251048597328942409434888923094027849143412724699165971400546471660924330688750607774759764580209261361372956377346.0) (num-test (- 4950293428090696283711882613183655723616682297360442241017758383241177602498881186549809051670562038601658285833496694108818253845693871318067007752043113.0 17597810481352184048.0) 4950293428090696283711882613183655723616682297360442241017758383241177602498881186549809051670562038601658285833496694108818253845693853720256526399859065.0) (num-test (- -5733769947958740467479139247420201065087494801172241127791526686385518674532830661413722661802560247463032020003355494614502034002778775472609306735864748.0 -3892174127829225880.0) -5733769947958740467479139247420201065087494801172241127791526686385518674532830661413722661802560247463032020003355494614502034002778771580435178906638868.0) (num-test (- 8320894458193427045187598554188178307429755504967209344418448624882517461814957461249858674758807195827056824653471934409067429988676743031117653237018365.0 -12861394200627120797.0) 8320894458193427045187598554188178307429755504967209344418448624882517461814957461249858674758807195827056824653471934409067429988676755892511853864139162.0) (num-test (- 13033402737450594044106258936169013897237368708138118260402180886096095497725071502601849887805439844083105685971731015312020770945603825344926844435936044.0 236396022362585261770052671762207864597.0) 13033402737450594044106258936169013897237368708138118260402180886096095497725071502601849887805439844083105685971730778915998408360342055292255082228071447.0) (num-test (- 12170667278114656173974716189098171384426379753661081475485441559687661443127166543908925678856145097632475832903680828294561265828775791256812588754280222.0 -276673555533799047589626400978981416789.0) 12170667278114656173974716189098171384426379753661081475485441559687661443127166543908925678856145097632475832903681104968116799627823380883213567735697011.0) (num-test (- -12755594876262399860618168642932232021734362385933348033134635580177924615701078617214764415318471507488803810365565826229169313660087149542130819663319659.0 -157671440495648010763311068579191828684.0) -12755594876262399860618168642932232021734362385933348033134635580177924615701078617214764415318471507488803810365565668557728818012076386231062240471490975.0) (num-test (- 8664063140780163008577373335591938905735059211566906376953760862047748343846207426667781783874718320339071949903053785280430612875488847226724390758938740.0 54361107931665215623681874454167019934.0) 8664063140780163008577373335591938905735059211566906376953760862047748343846207426667781783874718320339071949903053730919322681210273223544849936591918806.0) (num-test (- 3699576825118349347309026261327541749454660339251578894574483235547605815416603169143590292164644149607672871236942391817131531474661895913650810587431606.0 -50508350367572393968128467319633674717.0) 3699576825118349347309026261327541749454660339251578894574483235547605815416603169143590292164644149607672871236942442325481899047055864042118130221106323.0) (num-test (- 5626548453644136572409808769267055618695663227750732922630041368983808478347120771651822300668480671524976882745306794511840379704578900504784165956486985.0 170502882789371639987361620116696459267.0) 5626548453644136572409808769267055618695663227750732922630041368983808478347120771651822300668480671524976882745306624008957590332938913143164049260027718.0) (num-test (- -10859007735074693411217019392659638207496329895257318665547454149984863458541990037760564769787816800806064437172810158051442267508476778676439633382657890.0 -7558060977666720080449823996328496253877735754811271086853901493753796001778345391546991917892931500169890406340928835457635973812901681485438886367096185.0) -3300946757407973330767195396331141953618594140446047578693552656231067456763644646213572851894885300636174030831881322593806293695575097191000747015561705.0) (num-test (- 9842028993407961669727766131360795288615020071102475108883839785397865740828387076847892646234215787999498419839351470775471313077046438080666908734795616.0 8259939762466350877481193620364896193464602165170783019804380181692322874550956777598992104871440502758410340359413403619753571535498118388286469082729503.0) 1582089230941610792246572510995899095150417905931692089079459603705542866277430299248900541362775285241088079479938067155717741541548319692380439652066113.0) (num-test (- 3122315115429970622394662815735050825423438028108957393747131991771456957037829402044934484343765915727397519247940959221091465331254497476137639859816450.0 10737995515603450913722681305571315249864367824351372254572936648132763616823019940208526402092654554035074813865303483747097673960803093638463005072804384.0) -7615680400173480291328018489836264424440929796242414860825804656361306659785190538163591917748888638307677294617362524526006208629548596162325365212987934.0) (num-test (- 11618335890332522671268040181306950825004789685088262996478365976802329054158653675768163009290064139158450983598701977173152384425333441365287895694522192.0 -13130287008197231017935223399369698658354829835061356451363818961959486828237111511740029441613108087354987794332115218978284937263725126538295501305403242.0) 24748622898529753689203263580676649483359619520149619447842184938761815882395765187508192450903172226513438777930817196151437321689058567903583396999925434.0) (num-test (- -4829477140897377009195646150061276059814366801005389903693533021027427566117360765323647260121062827801190746646296803957067548167571028717513392985791293.0 10716557117391614298810040587314742187092120526669273567183969821384063434473189717686678450880765426943205955814024872764413373364846268902370055526485180.0) -15546034258288991308005686737376018246906487327674663470877502842411491000590550483010325711001828254744396702460321676721480921532417297619883448512276473.0) (num-test (- 1560421244904974852620371975782132605421448226892487453928759432083522187778803424020804578027100625536441377609275030418285893555753560195716001014786650.0 -11797558308994912054526619290334311429749533070145154703018977152548370444659962978040151671210413666186432921816690953994784423526183449271023503069393845.0) 13357979553899886907146991266116444035170981297037642156947736584631892632438766402060956249237514291722874299425965984413070317081937009466739504084180495.0) (num-test (- -7701347923966912534344428538744620884561375267012102797292378941649984539207353887059064943586048644516121387166836442084007442716291792933061162738380376.0 5290969389374230541016502448421359606252744677802288901830045825873182202718418905866055323957065013553046698199939002159982374580735362593037515863844280108947533575824820196689891621498006303535207762625068798755031433921940066544809959896067184147997503827988613858484669349726945188167613248195147619673963531690938913245110754715059472477991342216448470339490385593605806518967792963339193162830698488489270925945408227996742278697477358272529028932771642478870844024835907350391770605391526921411004262446196112836319091260967898895009427182171643279100998182191816962677328417390867021108292139204864164048286.0) -5290969389374230541016502448421359606252744677802288901830045825873182202718418905866055323957065013553046698199939002159982374580735362593037515863844280108947533575824820196689891621498006303535207762625068798755031433921940066544809959896067184147997503827988613858484669349726945188167613248195147619673963531690938913245110754715059472477991342216448470339490385593605806518967792963339193162830698488489270925945408227996742278697477358272529028932771642486572191948802819884736199144136147805972379529458298910128698032910952438102363314241236586865149642698313204129513770501398309737400085072266026902428662.0) (num-test (- 9733743430220591762422540139212426729307515492818443460852332805653889275463385649305231919846970974905736816260992940027028218064265519723018527155353151.0 -29407855293830047984154639411082591337348779678279017647951764366455421210163494489475996514661359700145916243499452007595041420522019751347743105082745321262372977262641488359297167392118038994384136863563032667040671405618315550876997904307423736276844997706938133936081058323434935833614475654922773162140266784233792639117145232791514703532554345086520312281500696798706889025860427142771458666376271994240028586899592254884476941388776984078337603148583453255593120138178690189726206775893096279000909079330468718593887702543025737308336025198677457129910473491269839827087491228569718246503140134413881896746751.0) 29407855293830047984154639411082591337348779678279017647951764366455421210163494489475996514661359700145916243499452007595041420522019751347743105082745321262372977262641488359297167392118038994384136863563032667040671405618315550876997904307423736276844997706938133936081058323434935833614475654922773162140266784233792639117145232791514703532554345086520312281500696798706889025860427142771458666376271994240028586899592254884476941388776984078337603148583453265326863568399281952148746915105523008308424572148912179446220508196915012771721674503909376976881448397006656088080431255597936310768659857432409052099902.0) (num-test (- -276731217243271862683214238489380950428392903790808046630969592255272629537001990355375434170910931115552132394269672247616298060929507021008951190291387.0 100289083769237476480554074865040988004216167545459907207847010762380733541100608695693297149249375537088329431700364201275915507683345148401600569951338052791424407090330310974243070931256108167365334162914085216447196038922091547331474328250886730614683299908003398886233860613008266913065047699535081030427106800418656336608005860846045905149012346378286475449307630537665901621055008855374148058291266835796203075976592585729940879567246284967856356337849150102261744547461816282538319258966892339056695718919291240188920586288417893106046698069355647145603908383687239983874164793005765733782432717429040621674.0) -100289083769237476480554074865040988004216167545459907207847010762380733541100608695693297149249375537088329431700364201275915507683345148401600569951338052791424407090330310974243070931256108167365334162914085216447196038922091547331474328250886730614683299908003398886233860613008266913065047699535081030427106800418656336608005860846045905149012346378286475449307630537665901621055008855374148058291266835796203075976592585729940879567246284967856356337849150378992961790733678965752557748347842767449599509727337871158512841561047430108037053444789818056535023935819634253546412409303826663289453726380230913061.0) (num-test (- 8505070389896098095621766692413480203366379968950158493268895987250690600795955783113900096527432416791184386061684833478921638080978014176210898461637606.0 -16410711613672171332126342754193842244915477287016327757357714698751777287458963458682349581881560880814595167244857846847668988374679430572782121021084683986742283012573569894084166107235597351093334125816075658348307113218478800035703971671113417712009419861470917307849916674203301497919242668373376352901312309673053175315189945730756118172940886476343290174961420986113367531057713782438374928471960914578818951372282574754612716278516397754222547513576728677459134022062202283647690649100602260948409511070624300011106517649666031530376191755817891213910847547809248990517666613043010292627100428536737652546738.0) 16410711613672171332126342754193842244915477287016327757357714698751777287458963458682349581881560880814595167244857846847668988374679430572782121021084683986742283012573569894084166107235597351093334125816075658348307113218478800035703971671113417712009419861470917307849916674203301497919242668373376352901312309673053175315189945730756118172940886476343290174961420986113367531057713782438374928471960914578818951372282574754612716278516397754222547513576728685964204411958300379269457341514082464314789480020782793280002504900356632326331974869717987741343264338993635052202500091964648373605114604747636114184344.0) (num-test (- -12618010259109779267590315037969998053964054382853891516547435925972388025118492931596200697357628900783311183940584302426381939302632641549019984810957030.0 -30500906828861638007306362171210132987300359439962044769219457463653547834815716264412200930088623097530758080891972640000479943534665059199377729854850415258341537838023739964147532129877743393965857370995558748807382396090020006195649251292012405690725917389684473999400905751109361754679152179983739269026226054012963756892488872262522587481931950410504651253101938824790285623805566521723062029033001745636445860437154344665483641408727637784045030118212476306906983993748299291616038887011943864441807818857508443930272872365334665976442185494702520760793786640113779099219233665607521784524244604432396247693263.0) 30500906828861638007306362171210132987300359439962044769219457463653547834815716264412200930088623097530758080891972640000479943534665059199377729854850415258341537838023739964147532129877743393965857370995558748807382396090020006195649251292012405690725917389684473999400905751109361754679152179983739269026226054012963756892488872262522587481931950410504651253101938824790285623805566521723062029033001745636445860437154344665483641408727637784045030118212476294288973734638520024025723849041945810477753436003616927382836946392946640857949253898501823403164885856802595158634931239225582481891603055412411436736233.0) (num-test (- 793528769616879938852241178439496352527042950647521648629732169156958768358523029837406526207126598190786120139491813624819360632811627576064199559812277.0 -7357484069649002655190557040768215614708659708788999334802985986235721030962928900092675952032143512196279092521450986819067071570862007086586132687661085824939677603953832219860573980632016025218580608321648907608385784471745482257672314890331358256478273312255285010343369949412955387472116587504557483184506548209831317705115523967163525846685455369176657510129844566195941925821733027993620517287411895496215426174909366458092382652675628195464969405904518323018004882611048769247228828875493680284766874334247375868318795940759082324831733175858991629741478124633015067484305547002438816473086042218906532116413.0) 7357484069649002655190557040768215614708659708788999334802985986235721030962928900092675952032143512196279092521450986819067071570862007086586132687661085824939677603953832219860573980632016025218580608321648907608385784471745482257672314890331358256478273312255285010343369949412955387472116587504557483184506548209831317705115523967163525846685455369176657510129844566195941925821733027993620517287411895496215426174909366458092382652675628195464969405904518323811533652227928708099470007314990032811809824981769024498050965097717850683354763013265517836868076315419135206976119171821799449284713618283106091928690.0) (num-test (- 30958566711373255787092081401292877738974978442987704470984765018293851031728996862405055424093249924047528792113585028592262445810946419909807061004531455817427671594281537965628880611732831524185850161910304038646992464838306728350704966234151134620041799373762432970330864023007632010865749239024802839173884778578927209741320635135275002489733299806669933393428518104197594560039136096527206600870299327752296492029012993590212340409989598323540081430189567580333356380487749078595746626408529223195894600223743978246922817054226858311823994547784553612982586322603593335538875728113115443554199017672360091721648.0 9164115638960783470.0) 30958566711373255787092081401292877738974978442987704470984765018293851031728996862405055424093249924047528792113585028592262445810946419909807061004531455817427671594281537965628880611732831524185850161910304038646992464838306728350704966234151134620041799373762432970330864023007632010865749239024802839173884778578927209741320635135275002489733299806669933393428518104197594560039136096527206600870299327752296492029012993590212340409989598323540081430189567580333356380487749078595746626408529223195894600223743978246922817054226858311823994547784553612982586322603593335538875728113115443554189853556721130938178.0) (num-test (- -22540807692474380279530794404584230073523360203115293035869063366926380719566516089428840111682263403627532047214106171892715667227836310498366393991106231487046533598391969789120283294510723096483520917309134391072655861112766764278247568027435618337967113341863713181603534251049249873125130781073437913954718595729437608729446837417196899902194261111827656247095442897532040935029872731410799530408713850806239149348700486268275019296069828199088780767614008685960242354118969741283398882689239770114582524756296906388861630890288875920861344939520380841337675934551587994259348267613541166769237154904791412049964.0 16928681651977808800.0) -22540807692474380279530794404584230073523360203115293035869063366926380719566516089428840111682263403627532047214106171892715667227836310498366393991106231487046533598391969789120283294510723096483520917309134391072655861112766764278247568027435618337967113341863713181603534251049249873125130781073437913954718595729437608729446837417196899902194261111827656247095442897532040935029872731410799530408713850806239149348700486268275019296069828199088780767614008685960242354118969741283398882689239770114582524756296906388861630890288875920861344939520380841337675934551587994259348267613541166769254083586443389858764.0) (num-test (- -5403850875869356031749551669837202919756114555261706106905659104903792701565965475066159243529680606410723686422444947172225540145977333194008702465610630608545009270872541652430806931212184915840724378685979865349848151917650322286497417985248678815214889868576385900691591784772762893647315325310416150353725001943778473686980157692817497562783521120544549784746647104651038037129984152623720529803205580894126664077380391379306511348324442512538418658728022685805514196592544294177914956734669359073791151050869328577099869772182315103156047405800398706114122356939316464974680113324979723289916823063616573634058.0 -10755560408227106818.0) -5403850875869356031749551669837202919756114555261706106905659104903792701565965475066159243529680606410723686422444947172225540145977333194008702465610630608545009270872541652430806931212184915840724378685979865349848151917650322286497417985248678815214889868576385900691591784772762893647315325310416150353725001943778473686980157692817497562783521120544549784746647104651038037129984152623720529803205580894126664077380391379306511348324442512538418658728022685805514196592544294177914956734669359073791151050869328577099869772182315103156047405800398706114122356939316464974680113324979723289906067503208346527240.0) (num-test (- 16201587974698660164372991183566748501003872177894450603471850345714117528335101264234127789041855420954511595895378320972957964222386731614839583078498685801156670229700092209313747849610762975747730086443186821337319452128253859293962343891549207804191088925361935683615063225197130192492652062735684739784075955094308092423304262201429421582566117390598395895220976999990205945523225411701169301910362640419341608407294018105959688929256136725564385243617240412649023368133778798063226772467915584333795357813292935080009919284755332034998122912861893282865727947810588086156919649131720183722427134042574317487793.0 -126159569916621842.0) 16201587974698660164372991183566748501003872177894450603471850345714117528335101264234127789041855420954511595895378320972957964222386731614839583078498685801156670229700092209313747849610762975747730086443186821337319452128253859293962343891549207804191088925361935683615063225197130192492652062735684739784075955094308092423304262201429421582566117390598395895220976999990205945523225411701169301910362640419341608407294018105959688929256136725564385243617240412649023368133778798063226772467915584333795357813292935080009919284755332034998122912861893282865727947810588086156919649131720183722427260202144234109635.0) (num-test (- -9976758107386398142455037422077809088581080675608340830198269021688955930541332630075972471934165382030070969307731206728197760190279942894255740733209190331510591013089699837164445642396864912572863786290237335963836376543389815671640509582958465164874961381137096877288362944469137669502842448492172241151419831252572392809173900377271652074261706120638052379886108764460001026094198502028776365675088466580595870167840105746912975236851293882732079317535103041585285239081516202482201377111734010788198635874359396626004300532752450289119192633850562141516671742961938277967783337559307443617308447853505824391099.0 13449070890444925581.0) -9976758107386398142455037422077809088581080675608340830198269021688955930541332630075972471934165382030070969307731206728197760190279942894255740733209190331510591013089699837164445642396864912572863786290237335963836376543389815671640509582958465164874961381137096877288362944469137669502842448492172241151419831252572392809173900377271652074261706120638052379886108764460001026094198502028776365675088466580595870167840105746912975236851293882732079317535103041585285239081516202482201377111734010788198635874359396626004300532752450289119192633850562141516671742961938277967783337559307443617321896924396269316680.0) (num-test (- -8570952518585194406209873586517687582701183275108243979199329595605282282125006489076327154374449108678257552384372919282846744626955206382078850958298637157198962032090439427286914716782317030245513658212430127586764421559372214829010306717557679285031617989735914399954286846456953917915955558448774972943731602144914068097214910567329340361564904028964471241318105967747431610163083002382821902859161510204381788262611298660559327478615315484763561786397041779926288206767156863141140852268323253657685018587945456372648431446464389004257999049529945532453598011773843788498650935959375182414447893892341891463988.0 4431555062692055371.0) -8570952518585194406209873586517687582701183275108243979199329595605282282125006489076327154374449108678257552384372919282846744626955206382078850958298637157198962032090439427286914716782317030245513658212430127586764421559372214829010306717557679285031617989735914399954286846456953917915955558448774972943731602144914068097214910567329340361564904028964471241318105967747431610163083002382821902859161510204381788262611298660559327478615315484763561786397041779926288206767156863141140852268323253657685018587945456372648431446464389004257999049529945532453598011773843788498650935959375182414452325447404583519359.0) (num-test (- 4117976000917214601143188578494558474138167055110060832594841842655428229500889876131794484851166401425675703592388271925904534237338595998991043982676292549088043959446082382516734793718348862105938692342851330680670593768890094290655852108130945387988863730762717733881418314989528719379494082656897158942547008663543153236129762264443358316776532465284014215413819415615612452225913947961681691310132286840303081453109375175436902292224029179426794714036524361081174901146731799945483243427138748119832116750910126386838614645397770107366925613473924955965862778639046707637382775371488874447622330992324750207465.0 329466253508616383200261654231797136951.0) 4117976000917214601143188578494558474138167055110060832594841842655428229500889876131794484851166401425675703592388271925904534237338595998991043982676292549088043959446082382516734793718348862105938692342851330680670593768890094290655852108130945387988863730762717733881418314989528719379494082656897158942547008663543153236129762264443358316776532465284014215413819415615612452225913947961681691310132286840303081453109375175436902292224029179426794714036524361081174901146731799945483243427138748119832116750910126386838614645397770107366925613473924955965862778639046707637053309117980258064422069338092953070514.0) (num-test (- 28857935543824608075326348244201981931023939250259142606733822094071772153858420201297951828741003977413353359215638528196235956061529059419904405354390715114239219947402126760298132539402386106279333968395498788354937020337343839325588433318100331044091923709732742795159387846354148919054314582749477292946200912006940503778924320301062789466388997936618573519744795661160190636101768486096961991215006236190655062992372061052426455063703038765465688361316141792840153608145888307784845264037109867657483109819380082597605481013612040648149090345778910883349230476481347645708269410828528742743794495302359380494607.0 126536164564464424337714470705049463978.0) 28857935543824608075326348244201981931023939250259142606733822094071772153858420201297951828741003977413353359215638528196235956061529059419904405354390715114239219947402126760298132539402386106279333968395498788354937020337343839325588433318100331044091923709732742795159387846354148919054314582749477292946200912006940503778924320301062789466388997936618573519744795661160190636101768486096961991215006236190655062992372061052426455063703038765465688361316141792840153608145888307784845264037109867657483109819380082597605481013612040648149090345778910883349230476481347645708142874663964278319456780831654331030629.0) (num-test (- 3146199586408378667812619157270468624370984629500707476575291934586478540055436137993431548830607708293475788354970610669452058906009873485175438772484599603993015239438297747261356407887781450787482447252615210880612867127689283653562498484594955015919746443263740095372831444793239911996227663006098501180972347442107190398034048225264564325230296723559400768342331039755765597288518435463475921534765025262262798267314969774604439319964638461636007229819888743218820584570149249791727508891676067767073852694327748467914037392778283816153183422263956621516748627574334199731850712255885395479903525322397561293553.0 -169494171680584797187706369710105239124.0) 3146199586408378667812619157270468624370984629500707476575291934586478540055436137993431548830607708293475788354970610669452058906009873485175438772484599603993015239438297747261356407887781450787482447252615210880612867127689283653562498484594955015919746443263740095372831444793239911996227663006098501180972347442107190398034048225264564325230296723559400768342331039755765597288518435463475921534765025262262798267314969774604439319964638461636007229819888743218820584570149249791727508891676067767073852694327748467914037392778283816153183422263956621516748627574334199732020206427565980277091231692107666532677.0) (num-test (- -17024716654716744558842421452239026542281806678754026383430912733874686056449261218428541803113383766132449624540209841726047308927951820311213785345168358108138304716549475322223600292513384537980742126687035576531330089447100646214364923043445903103768701639992829171572718403272488931980504461938688955457870904289239032709146514866818331202329982821151580491257491540240579366183525075936339515949345815704583685855315810611089822402567649542290589282153225725537026309623090382054078872576985425957096858376112688308214148412270019118710904983829984589093557307164347051152307499446188262820058714564165108542508.0 -26845770031559702758807696432929071597.0) -17024716654716744558842421452239026542281806678754026383430912733874686056449261218428541803113383766132449624540209841726047308927951820311213785345168358108138304716549475322223600292513384537980742126687035576531330089447100646214364923043445903103768701639992829171572718403272488931980504461938688955457870904289239032709146514866818331202329982821151580491257491540240579366183525075936339515949345815704583685855315810611089822402567649542290589282153225725537026309623090382054078872576985425957096858376112688308214148412270019118710904983829984589093557307164347051152280653676156703117299906867732179470911.0) (num-test (- -20875354448001792153279041347864644172439177882677780548397567327274288309764204295853633150227327732322157811413794613378828291977852467550695289535036337326494269114787031260705326469002279939986228049380615128280814933748700667874022724707001736732724010699175779382411342385842744973636495738468838244099596215421975861650998954057316519632062827510021706536194961332185926551767127180751211669386674770139039516623606727799489291663572125587356845055646322930167536458093283930082765496058330805117442824718962237069840252138957395570892073194575112213410604881673785921789655406716271370732069643455590690035701.0 -321447426701397438572265325285879998363.0) -20875354448001792153279041347864644172439177882677780548397567327274288309764204295853633150227327732322157811413794613378828291977852467550695289535036337326494269114787031260705326469002279939986228049380615128280814933748700667874022724707001736732724010699175779382411342385842744973636495738468838244099596215421975861650998954057316519632062827510021706536194961332185926551767127180751211669386674770139039516623606727799489291663572125587356845055646322930167536458093283930082765496058330805117442824718962237069840252138957395570892073194575112213410604881673785921789333959289569973293497378130304810037338.0) (num-test (- -6750548706930727136186675393752693335334383613941059024795513640678178119089262068912855951615043660442324823673049951182143778744824110223137384940032268718291241014850714197673735719784663896993460156686600813524168487673234842233781654493200950459723884918456280719440022930492599128086690014332139955274261568563155723011697763382009890186816226119314994799655369791620499988988986590903148198659095740939986627235565633349906453726759224441608018598520571182643709143072528030332708598472074166415467718451869993686505339408706320298338691467040585228617379086727764240955696690287600957842671916189752415855520.0 132223863177855649509430852484092802671.0) -6750548706930727136186675393752693335334383613941059024795513640678178119089262068912855951615043660442324823673049951182143778744824110223137384940032268718291241014850714197673735719784663896993460156686600813524168487673234842233781654493200950459723884918456280719440022930492599128086690014332139955274261568563155723011697763382009890186816226119314994799655369791620499988988986590903148198659095740939986627235565633349906453726759224441608018598520571182643709143072528030332708598472074166415467718451869993686505339408706320298338691467040585228617379086727764240955828914150778813492181347042236508658191.0) (num-test (- 15737797902964168014939893286340956118635524170934156177365242966267432695262586636031957242055461736359478270642576860414422844075672388559647477705484719667060463718865742735598799928335211410004369240278699196301127699945374217439676378682879115442203681638050752745036508637214733712716867800216723838016099572951915042604603457902610639317648800296497583507890473114507231814851908526534709496988648572353272479026750068932474334642929727977996779536604912743446197670724757690108283368934769626461285961947257397454619164856011847736479229692086038931510067165282571276049292116713101550911614590774659556899356.0 -6114512833799784097991148713266650451765474382378581896952003894922931741133332233338460555227243451198289670274036744955599177213449957470212981501678055.0) 15737797902964168014939893286340956118635524170934156177365242966267432695262586636031957242055461736359478270642576860414422844075672388559647477705484719667060463718865742735598799928335211410004369240278699196301127699945374217439676378682879115442203681638050752745036508637214733712716867800216723838016099572951915042604603457902610639317648800296497583507890473114507231814851908526534709496988648572353272479026750068932474334642929727977996779536604912749560710504524541788099432082201420078226760344325839294406623059778943588869811463030546594158753518363572241550086037072312278764361572060987641058577411.0) (num-test (- -26633154627863501044020127597209297142657179797586777727331879111280843451446814109347357601013807189824906954310855123313836812409388745541128842840054310853220032505914307470215180950497357091093642400638925719682307925365402618310180378684705799724964274776149984064608716300479893889145492885897234574442542501896696821902329473018442082678749291668341477914681413039643187020003425962922948452894682558162414623956491734656939841377698702802567258906642912449969621455596132708975438173455827361542712483153981422051943690720556013580161324856788091093465837542336129629269227369781823515673967591796132853515009.0 3321161637038961370471515250185392889390643163295535903347391615170504064647249127732639364682803744773593849851778894972403397573953564801884397178069327.0) -26633154627863501044020127597209297142657179797586777727331879111280843451446814109347357601013807189824906954310855123313836812409388745541128842840054310853220032505914307470215180950497357091093642400638925719682307925365402618310180378684705799724964274776149984064608716300479893889145492885897234574442542501896696821902329473018442082678749291668341477914681413039643187020003425962922948452894682558162414623956491734656939841377698702802567258906642912453290783092635094079446953423641220250933355646449517325399335305891060078227410452589427455776269582315929979481048122342185221089627532393680530031584336.0) (num-test (- 27668394897866653012794531261739800318882766882548843941974485394983434533400277607364280566269718161470415771058329222680901477416257843578362127708934184467195154000133252468684612556324066063725677629160438683034201285122508880444372096430021219637788794365539396242345208611990491721052691567092029622640533057073151980959055665792776356282961971341363712186503783566960850166774438868528799819047163739437906559674823146932668464230936946321915236658512741918196732794332451120218658490129307932187658010681746557120172585093207839141764683325214902696969028472942954863209641597556494684135445935915485525220911.0 204625459185084436546676461283890328511903949966691877662249903659689934813784661695047569885195881142676761876303280806728760511429260843727967794322777.0) 27668394897866653012794531261739800318882766882548843941974485394983434533400277607364280566269718161470415771058329222680901477416257843578362127708934184467195154000133252468684612556324066063725677629160438683034201285122508880444372096430021219637788794365539396242345208611990491721052691567092029622640533057073151980959055665792776356282961971341363712186503783566960850166774438868528799819047163739437906559674823146932668464230936946321915236658512741917992107335147366683671982028845417603675754060715054679457922681433517904327980021630167332811773147330266192986906360790827734172706185092187517730898134.0) (num-test (- 18944451653774463090918576081661764936021793389045063662102219434278236461286997354190032851092512146937346521704215170240383659165117708716738711782597164244188741818096207452074083439983059414271417130274747048227795964884943105011205424198661201055104372863019759130697888820715782179466491256695453118035286889359217448004524564796840711987314064158194625731263591557915838970249677548534895064545467992194029425250039951132361639559343536937119283951538321037694842089561504643350632756961329867761604760788760440497535611072991056505806805291706178639395690245460397975614715123591611301423752799666149495108752.0 994321141213369910357526037382331323092462599623554452705525887587326552002660849455542761618020243106424015447778226642816634338781654345001677083881111.0) 18944451653774463090918576081661764936021793389045063662102219434278236461286997354190032851092512146937346521704215170240383659165117708716738711782597164244188741818096207452074083439983059414271417130274747048227795964884943105011205424198661201055104372863019759130697888820715782179466491256695453118035286889359217448004524564796840711987314064158194625731263591557915838970249677548534895064545467992194029425250039951132361639559343536937119283951538321036700520948348134732993106719578998544669142161165205987792009723485664504503145955836163417021375447139036382527836488480774976962642098454664472411227641.0) (num-test (- -25075128489482657321316021943980016828761861550379828525731288423212311433274066958090940464803020097932875912251380196071686918459370667428905844496548191635733867314315152547202859654044591981512687559437417616479425752991419002108503390319869665933757684966460526631533822984311725217788657567199485442486045019468844265484117570385156844404625735176559901986920712550964238722824122000259551821135404274194791706113272773768366572120227974096419295159271316157215551931810740200836725504693738229444336470213883741520460842708733150362983831267583568258736572295448486287825894301201018490203520738439038977754991.0 -7402949251688548738762242219263594861535354011996392637087346760786292549376145193266590582054224293289596877537643409310483743293801574030358189880866069.0) -25075128489482657321316021943980016828761861550379828525731288423212311433274066958090940464803020097932875912251380196071686918459370667428905844496548191635733867314315152547202859654044591981512687559437417616479425752991419002108503390319869665933757684966460526631533822984311725217788657567199485442486045019468844265484117570385156844404625735176559901986920712550964238722824122000259551821135404274194791706113272773768366572120227974096419295159271316149812602680122191462074483285430143367908982458217491104433114081922440600986838638000992986204512279005851608750182484990717275196401946708080849096888922.0) (num-test (- -26509487378481600038412836495388065888781507388737194948728047318975269277448073484403390476243134990463394380967295356958474984927721196047241216945988250219075749832868804186657201899994373052648345989716938779173325348547767647529160988985542438998030764420175306438858518207072038513664360905985908879070216069156102379349899544471658754952888660878997691670566078979940005195987259493512159628198906090101827331841914429358969184839073862821059400943312264269215878469013316796620921077244799814690434355127994011220041638393750697699141479399553359747084811371804524490919966410379714725200415331414459870271869.0 -9247155945465656153397925559476432992975541781462281935278489123804934847762489500833913193183733932905776020790478662969835879365116238125565077744775032.0) -26509487378481600038412836495388065888781507388737194948728047318975269277448073484403390476243134990463394380967295356958474984927721196047241216945988250219075749832868804186657201899994373052648345989716938779173325348547767647529160988985542438998030764420175306438858518207072038513664360905985908879070216069156102379349899544471658754952888660878997691670566078979940005195987259493512159628198906090101827331841914429358969184839073862821059400943312264259968722523547660643222995517768366821714892573665712075941552514588815849936651978565640166563350878466028503700441303440543835360084177205849382125496837.0) (num-test (- -17010604274474750006607667808593883725990508452473783283717890546525148212376267233909567638545898628257361383837671935903199638230375408397752251127816717091041943873728526445398525706450929660366518707254053655364610471112296477865068960744948010561798109833411657930112293904378353445961131058136287425064317621271289456901138718557297733713446119244533144377470099270824020439428168481914824420861176457152299497728390918971852021025089592998997807574907789524112450146545688385954763667980124432645276563626082835790429598328230426471161191074551543308732791287559033843466623138171520961684959997180979203053477.0 -17319079025684619178510812811805110270463447771889107440996086020812918555191263705580533644731591929176480040622705607552852994906782176254877135818109655911838591767583157894999741648979817400330572419476101372927546509769818404491634583907246692993992514876697330603464497645633398167129555001859772111887143352351860130929715392173452396253437927361301990735683539169040916027268831202732178553152351117118606495416985612909248422655861312689027789401950549626643389790516560291620711705848717875304929186131258525831197192620523261738944873398924939726689336762464320190834794155527335576391767307110012289717973.0) 308474751209869171903145003211226544472939319415324157278195474287770342814996471670966006185693300919118656785033671649653356676406767857124884690292938820796647893854631449601215942528887739964053712222047717562936038657521926626565623162298682432194405043285672673352203741255044721168423943723484686822825731080570674028576673616154662539991808116768846358213439898216895587840662720817354132291174659966306997688594693937396401630771719690029981827042760102530939643970871905665948037868593442659652622505175690040767594292292835267783682324373396417956545474905286347368171017355814614706807309929033086664496.0) (num-test (- -28362352496476494327713713233021518136860402239251781438945998574753662942796270292818595738100959519541952077905620088422871490191217157269435052965329201030095268586136492980900212955645939325800541690754639292707053269767151001292253701853012092829784482071789669480438026889625605099744553642207773753943711175375843649210118677569597324789367425691177169929576236753018329085700397911235750600921874606148324025962628852167093806152864269874177214562322576097931390470469397118268354868919899638376323751276807304678316688836173746719723312665764603485606350244811113608471530958617108833879194264695174468397461.0 -4081062111675377984305281082755054920741203741273067094307824323728798665450292976016160959354997082250970415737745853292134965575242789548167162064123232363464302136338349828801951197252612093077640695564825095503535921549690447893467349156939791370286866987224201115453216606688305427702274940837032716124925028835914047967887674858015919302546781010326385758988488478290741665427521820112231266659657169118374988259423444686317389869729817643396097464874333968181509317307320406521221309011946212308190273531009796563611621389720223920155554879800901239072885025170342349379379336047732368458185953903872634982504.0) -24281290384801116343408432150266463216119198497978714344638174251024864277345977316802434778745962437290981662167874235130736524615974367721267890901205968666630966449798143152098261758393327232722900995189814197203517348217460553398786352696072301459497615084565468364984810282937299672042278701370741037818786146539929601242231002711581405486820644680850784170587748274727587420272876091123519334262217437029949037703205407480776416283134452230781117097448242129749881153162076711747133559907953426068133477745797508114705067446453522799567757785963702246533465219640771259092151622569376465421008310791301833414957.0) (num-test (- 10367142604728811799331249565431331488313655422005202933702176605382043644320209814639311439871418581341534233560256605231366966869093495784665834232350567124110194965198962966795893926025854156729633358240069116588609932539289897499402463770167927610848388138020589286461244557962368497723086593344721146859584146431437967506007518396464517349944129896971137720357645026281243138165214047233258394590454775153944241555543594427555914116439316287902470043292624597940465373006598913770411505099332700167695871387948271302951230983772351549087620538875967635100644404345317626621438913980275970160864401622986870735123.0 -13323117602411502623386235160326625769048477819798659261203460002048250420188223753407093545503703207645050883770850457071863684414849353264890601744588860687970804808452855795406182324143949747985869939791374195222513169904228914579995165180964917538177994190229733465224857616114628815752065632238207474599531507602861647623695058640735949593381112671690796335596142010430124683781417828023076027476816068202219709673411776556090962187853799456968290579708094595903778622705850818245685205707447012659247018940946510378371952655457988959551256869060428488498330109152756599450626641948447980234503249330875085656261.0) 23690260207140314422717484725757957257362133241803862194905636607430294064508433568046404985375121788986585117331107062303230651283942849049556435976939427812080999773651818762202076250169803904715503298031443311811123102443518812079397628951132845149026382328250322751686102174076997313475152225582928621459115654034299615129702577037200466943325242568661934055953787036711367821946631875256334422067270843356163951228955370983646876304293115744870760623000719193844243995712449732016096710806779712826942890328894781681323183639230340508638877407936396123598974513498074226072065555928723950395367650953861956391384.0) (num-test (- -25321281404861286799950777949097462701962113587443565138655462269365151737118518315058035825695270231347401755128007072923189452859397209062457461602335603630181865680063451525170253746137368267674863889514153713728814272332433431604233690200451816570240227260445028630591376891139306370205846627093813889699170594185178241812081296510140572331372738998993116117098817936927692238682202717231675283209016857095739468507690090676681400453024293870135659990528969837132054786661560150259115734877162158755858653364070279937027014730947342216816307219127474721622123875699701715404820384545693058511056735799834754890692.0 -15870257059811626693754498423136372480069134596343998984549199283973854570508228359295418026089909378687774627821225399931314225867711515277913855368473873536462450935842786002269065816311054834857109074848803122494252885020527074586145467185882674518032764708782999568002770206995683800833252068328835778749976046128872525287656002968632147457840467536682726059599593635219947081138082647985895437016641903078766878782632503812736486529143041369932038649270950453231711525943737962179463585338023463992816994328519710963267459007592689204838965317062070771191372220277256094361390952025057574056586665509010902583686.0) -9451024345049660106196279525961090221892978991099566154106262985391297166610289955762617799605360852659627127306781672991875226991685693784543606233861730093719414744220665522901187929826313432817754814665350591234561387311906357018088223014569142052207462551662029062588606684143622569372594558764978110949194548056305716524425293541508424873532271462310390057499224301707745157544120069245779846192374954016972589725057586863944913923881252500203621341258019383900343260717822188079652149539138694763041659035550568973759555723354653011977341902065403950430751655422445621043429432520635484454470070290823852307006.0) (num-test (- -10064759312484387184876313010284016458560725440641239737323234767636591183611201479885347260175161165340917225306019885202675573016295152797559983194160634880140345743489989007821872426587698574795394887035658449467358615185057180305109018898637903449135520486663185036663238956537895356325733583128141439025002140924158670346599492383552938312402521066705186885506193758499006001382444818328802338159713646715901977137011576113434170842422373328479181457354927400927267448788528116619711184792932525071391797130057189079431487557270366699175956757661488296856660145077706273571985222726397848614141194988258117115194.0 -3689074607001776735792882994440038588887963294487080609346609068733026224735369468180206799966728461935654851527895876039403151156669223687679382665269013769686991783531091821265184956524448064027733731862929686596729449196238312997460578818232100254940830907672953344544031914926653652310468671685310332327057444910423081752028857828828473637496272809899061573593874011995802487442092326045415689987885712749026491545159340468151000027397821404233369034594141219014219707193746581364791219277489927025992135462852894714639406751538919395016165215641239054420028872350709704191189169571752512626755385998505584006855.0) -6375684705482610449083430015843977869672762146154159127976625698903564958875832011705140460208432703405262373778124009163272421859625929109880600528891621110453353959958897186556687470063250510767661155172728762870629165988818867307648440080405803194194689578990231692119207041611241704015264911442831106697944696013735588594570634554724464674906248256806125311912319746503203513940352492283386648171827933966875485591852235645283170815024551924245812422760786181913047741594781535254919965515442598045399661667204294364792080805731447304159791542020249242436631272726996569380796053154645335987385808989752533108339.0) (num-test (- -4621513851362114851854472268081584822344822740665629177305004335694395719163541988311496405455186973857145245414214464449674464879082042971313025249648887349614046805778335573547862191522938924075560443632614665169520240664970180760364771373836023824195690134618554368845612471858027311791638881380352344527105480173917778084361560336490212845414303819150625355111300877737042696291233444311426721588476948565949641149735838580313236869041013210454558557732497012037162735013212361842433337324577522358968152852532145622765032318936569346015498130151789662274686368870963891262060214274101000058555635785833724062234.0 20283847238128227963042817384468009365120280641032764409860857066215336820785816567924217697745867082423864450685360959383940995237907453126362378908108545669654749698030305432673477271848544313029448526561606175059997663752601262173667861202924953502866611309434183496911206954880840674239880495147451496219568787221129244201657487090244435562896841733049066453539864301122516559479757096183362477594406691085946787803323712522074578611082872627361465163804239673539339633332349145205596371287028267780080937728455742966681547897652607170788637996317683436193829274172400558140357237480809582038468874094877651383053.0) -24905361089490342814897289652549594187465103381698393587165861401909732539949358556235714103201054056281009696099575423833615460116989496097675404157757433019268796503808641006221339463371483237105008970194220840229517904417571442934032632576760977327062301444052737865756819426738867986031519376527803840746674267395047022286019047426734648408311145552199691808651165178859559255770990540494789199182883639651896428953059551102387815480123885837816023721536736685576502368345561507048029708611605790139049090580987888589446580216589176516804136126469473098468515643043364449402417451754910582097024509880711375445287.0) )) (test (- - 1) 'error) (test (-) 'error) (test (- 1 #f) 'error) (test (- 1 #t) 'error) (test (- 1 + 2) 'error) (test (- 1 - 2) 'error) (test (- 1 2 . 3) 'error) (test (- 1 . 2) 'error) (for-each (lambda (arg) (test (- arg nan.0) 'error) (test (- nan.0 arg) 'error) (test (- arg inf.0) 'error) (test (- inf.0 arg) 'error) (test (- arg) 'error) (test (- 1 arg) 'error) (test (- 1/2 arg) 'error) (test (- 1.0 arg) 'error) (test (- 1+i arg) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) ;;; -------------------------------------------------------------------------------- ;;; / ;;; -------------------------------------------------------------------------------- (num-test (/ -0.0+0.00000001i) 0.0-100000000.0i) (num-test (/ -1.0) -1.0) (num-test (/ -1.0+1.0i -1.0+1.0i) 1.0) (num-test (/ -1.0+1.0i 0.0+1.0i) 1.0+1.0i) (num-test (/ -1.0+1.0i 1) -1.0+1.0i) (num-test (/ -1.0+1.0i 1.0) -1.0+1.0i) (num-test (/ -1.0+1.0i 1.0+1.0i) 0.0+1.0i) (num-test (/ -1.0+1.0i 1.234+1.234i) 0.0+0.81037277147488i) (num-test (/ -1.0+1.0i 1/1) -1.0+1.0i) (num-test (/ -1.0+1.0i 123.4) -0.00810372771475+0.00810372771475i) (num-test (/ -1.0+1.0i 1234) -0.00081037277147+0.00081037277147i) (num-test (/ -1.0+1.0i 1234/11) -0.00891410048622+0.00891410048622i) (num-test (/ -1.0+1.0i) -0.5-0.5i) (num-test (/ -10) -1/10) (num-test (/ -10/3) -3/10) (num-test (/ -10 3) -10/3) (num-test (/ -1234000000) -1/1234000000) (num-test (/ -1234000000.0) -0.00000000081037) (num-test (/ -1234000000.0+2.71828182845905i) -0.00000000081037-0.0i) (num-test (/ -1234000000/10) -10/1234000000) (num-test (/ -2) -1/2) (num-test (/ -2.71828182845905) -0.36787944117144) (num-test (/ -2.71828182845905+3.14159265358979i) -0.15750247989732-0.18202992367723i) (num-test (/ -2/2) -2/2) (num-test (/ -362880) -1/362880) (num-test (/ -362880/1234) -1234/362880) (num-test (/ 0 -1.0+1.0i) 0.0) (num-test (/ 0 0.0+1.0i) 0.0) (num-test (/ 0 1 -1.0+1.0i) 0.0) (num-test (/ 0 1 0.0+1.0i) 0.0) (num-test (/ 0 1 1) 0) (num-test (/ 0 1 1.0) 0.0) (num-test (/ 0 1 1.0+1.0i) 0.0) (num-test (/ 0 1 1.234+1.234i) 0.0) (num-test (/ 0 1 1/1) 0) (num-test (/ 0 1 123.4) 0.0) (num-test (/ 0 1 1234) 0) (num-test (/ 0 1 1234/11) 0) (num-test (/ 0 1) 0) (num-test (/ 0 1.0 -1.0+1.0i) 0.0) (num-test (/ 0 1.0 0.0+1.0i) 0.0) (num-test (/ 0 1.0 1) 0.0) (num-test (/ 0 1.0 1.0) 0.0) (num-test (/ 0 1.0 1.0+1.0i) 0.0) (num-test (/ 0 1.0 1.234+1.234i) 0.0) (num-test (/ 0 1.0 1/1) 0.0) (num-test (/ 0 1.0 123.4) 0.0) (num-test (/ 0 1.0 1234) 0.0) (num-test (/ 0 1.0 1234/11) 0.0) (num-test (/ 0 1.0) 0.0) (num-test (/ 0 1.0+1.0i -1.0+1.0i) 0.0) (num-test (/ 0 1.0+1.0i 0.0+1.0i) 0.0) (num-test (/ 0 1.0+1.0i 1) 0.0) (num-test (/ 0 1.0+1.0i 1.0) 0.0) (num-test (/ 0 1.0+1.0i 1.0+1.0i) 0.0) (num-test (/ 0 1.0+1.0i 1.234+1.234i) 0.0) (num-test (/ 0 1.0+1.0i 1/1) 0.0) (num-test (/ 0 1.0+1.0i 123.4) 0.0) (num-test (/ 0 1.0+1.0i 1234) 0.0) (num-test (/ 0 1.0+1.0i 1234/11) 0.0) (num-test (/ 0 1.0+1.0i) 0.0) (num-test (/ 0 1.234+1.234i) 0.0) (num-test (/ 0 1/1 -1.0+1.0i) 0.0) (num-test (/ 0 123.4) 0.0) (num-test (/ 0 1234) 0) (num-test (/ 0 1234/11) 0) (num-test (/ 0.0 -1.0+1.0i -1.0+1.0i) 0.0) (num-test (/ 0.0 -1.0+1.0i 0.0+1.0i) 0.0) (num-test (/ 0.0 -1.0+1.0i 1) 0.0) (num-test (/ 0.0 -1.0+1.0i 1.0) 0.0) (num-test (/ 0.0 -1.0+1.0i 1.0+1.0i) 0.0) (num-test (/ 0.0 -1.0+1.0i 1.234+1.234i) 0.0) (num-test (/ 0.0 -1.0+1.0i 1/1) 0.0) (num-test (/ 0.0 -1.0+1.0i 123.4) 0.0) (num-test (/ 0.0 -1.0+1.0i 1234) 0.0) (num-test (/ 0.0 -1.0+1.0i 1234/11) 0.0) (num-test (/ 0.0 -1.0+1.0i) 0.0) (num-test (/ 0.0 0.0+1.0i -1.0+1.0i) 0.0) (num-test (/ 0.0 0.0+1.0i 0.0+1.0i) 0.0) (num-test (/ 0.0 0.0+1.0i 1) 0.0) (num-test (/ 0.0 0.0+1.0i 1.0) 0.0) (num-test (/ 0.0 0.0+1.0i 1.0+1.0i) 0.0) (num-test (/ 0.0 0.0+1.0i 1.234+1.234i) 0.0) (num-test (/ 0.0 0.0+1.0i 1/1) 0.0) (num-test (/ 0.0 0.0+1.0i 123.4) 0.0) (num-test (/ 0.0 0.0+1.0i 1234) 0.0) (num-test (/ 0.0 0.0+1.0i 1234/11) 0.0) (num-test (/ 0.0 0.0+1.0i) 0.0) (num-test (/ 0.0 1 -1.0+1.0i) 0.0) (num-test (/ 0.0 1 0.0+1.0i) 0.0) (num-test (/ 0.0 1 1.0) 0.0) (num-test (/ 0.0 1 1.0+1.0i) 0.0) (num-test (/ 0.0 1 1.234+1.234i) 0.0) (num-test (/ 0.0 1 1/1) 0.0) (num-test (/ 0.0 1 123.4) 0.0) (num-test (/ 0.0 1 1234) 0.0) (num-test (/ 0.0 1 1234/11) 0.0) (num-test (/ 0.0 1) 0.0) (num-test (/ 0.0 1.0 -1.0+1.0i) 0.0) (num-test (/ 0.0 1.0 0.0+1.0i) 0.0) (num-test (/ 0.0 1.0 1) 0.0) (num-test (/ 0.0 1.0 1.0) 0.0) (num-test (/ 0.0 1.0 1.0+1.0i) 0.0) (num-test (/ 0.0 1.0 1.234+1.234i) 0.0) (num-test (/ 0.0 1.0 1/1) 0.0) (num-test (/ 0.0 1.0 123.4) 0.0) (num-test (/ 0.0 1.0 1234) 0.0) (num-test (/ 0.0 1.0 1234/11) 0.0) (num-test (/ 0.0 1.0) 0.0) (num-test (/ 0.0 1.0+1.0i -1.0+1.0i) 0.0) (num-test (/ 0.0 1.0+1.0i 0.0+1.0i) 0.0) (num-test (/ 0.0 1.0+1.0i 1) 0.0) (num-test (/ 0.0 1.0+1.0i 1.0) 0.0) (num-test (/ 0.0 1.0+1.0i 1.0+1.0i) 0.0) (num-test (/ 0.0 1.0+1.0i 1.234+1.234i) 0.0) (num-test (/ 0.0 1.0+1.0i 1/1) 0.0) (num-test (/ 0.0 1.0+1.0i 123.4) 0.0) (num-test (/ 0.0 1.0+1.0i 1234) 0.0) (num-test (/ 0.0 1.0+1.0i 1234/11) 0.0) (num-test (/ 0.0 1.0+1.0i) 0.0) (num-test (/ 0.0 1.234+1.234i -1.0+1.0i) 0.0) (num-test (/ 0.0 1.234+1.234i 0.0+1.0i) 0.0) (num-test (/ 0.0 1.234+1.234i 1) 0.0) (num-test (/ 0.0 1.234+1.234i 1.0) 0.0) (num-test (/ 0.0 1.234+1.234i 1.0+1.0i) 0.0) (num-test (/ 0.0 1.234+1.234i 1.234+1.234i) 0.0) (num-test (/ 0.0 1.234+1.234i 1/1) 0.0) (num-test (/ 0.0 1.234+1.234i 123.4) 0.0) (num-test (/ 0.0 1.234+1.234i 1234) 0.0) (num-test (/ 0.0 1.234+1.234i 1234/11) 0.0) (num-test (/ 0.0 1.234+1.234i) 0.0) (num-test (/ 0.0 1/1 -1.0+1.0i) 0.0) (num-test (/ 0.0 123.4 -1.0+1.0i) 0.0) (num-test (/ 0.0 123.4 0.0+1.0i) 0.0) (num-test (/ 0.0 123.4 1) 0.0) (num-test (/ 0.0 123.4 1.0) 0.0) (num-test (/ 0.0 123.4 1.0+1.0i) 0.0) (num-test (/ 0.0 123.4 1.234+1.234i) 0.0) (num-test (/ 0.0 123.4 1/1) 0.0) (num-test (/ 0.0 123.4 123.4) 0.0) (num-test (/ 0.0 123.4 1234) 0.0) (num-test (/ 0.0 123.4 1234/11) 0.0) (num-test (/ 0.0 123.4) 0.0) (num-test (/ 0.0 1234 -1.0+1.0i) 0.0) (num-test (/ 0.0 1234 0.0+1.0i) 0.0) (num-test (/ 0.0 1234 1) 0.0) (num-test (/ 0.0 1234 1.0) 0.0) (num-test (/ 0.0 1234 1.0+1.0i) 0.0) (num-test (/ 0.0 1234 1.234+1.234i) 0.0) (num-test (/ 0.0 1234 1/1) 0.0) (num-test (/ 0.0 1234 123.4) 0.0) (num-test (/ 0.0 1234 1234) 0.0) (num-test (/ 0.0 1234 1234/11) 0.0) (num-test (/ 0.0 1234) 0.0) (num-test (/ 0.0 1234/11 -1.0+1.0i) 0.0) (num-test (/ 0.0 1234/11 0.0+1.0i) 0.0) (num-test (/ 0.0 1234/11 1) 0.0) (num-test (/ 0.0 1234/11 1.0) 0.0) (num-test (/ 0.0 1234/11 1.0+1.0i) 0.0) (num-test (/ 0.0 1234/11 1.234+1.234i) 0.0) (num-test (/ 0.0 1234/11 1/1) 0.0) (num-test (/ 0.0 1234/11 123.4) 0.0) (num-test (/ 0.0 1234/11 1234) 0.0) (num-test (/ 0.0 1234/11 1234/11) 0.0) (num-test (/ 0.0 1234/11) 0.0) (num-test (/ 0.0+0.00000001i) 0.0-100000000.0i) (num-test (/ 0.0+1.0i -1.0+1.0i) 0.5-0.5i) (num-test (/ 0.0+1.0i 0.0+1.0i) 1.0) (num-test (/ 0.0+1.0i 1) 0.0+1.0i) (num-test (/ 0.0+1.0i 1.0) 0.0+1.0i) (num-test (/ 0.0+1.0i 1.0+1.0i) 0.5+0.5i) (num-test (/ 0.0+1.0i 1.234+1.234i) 0.40518638573744+0.40518638573744i) (num-test (/ 0.0+1.0i 1/1) 0.0+1.0i) (num-test (/ 0.0+1.0i 123.4) 0.0+0.00810372771475i) (num-test (/ 0.0+1.0i 1234) 0.0+0.00081037277147i) (num-test (/ 0.0+1.0i 1234/11) 0.0+0.00891410048622i) (num-test (/ 1 -1.0+1.0i) -0.5-0.5i) (num-test (/ 1 0.0+1.0i) 0.0-1.0i) (num-test (/ 1 1 -1.0+1.0i) -0.5-0.5i) (num-test (/ 1 1 0.0+1.0i) 0.0-1.0i) (num-test (/ 1 1 1) 1) (num-test (/ 1 1 1.0) 1.0) (num-test (/ 1 1 1.0+1.0i) 0.5-0.5i) (num-test (/ 1 1 1.234+1.234i) 0.40518638573744-0.40518638573744i) (num-test (/ 1 1 1/1) 1) (num-test (/ 1 1 123.4) 0.00810372771475) (num-test (/ 1 1 1234) 1/1234) (num-test (/ 1 1 1234/11) 11/1234) (num-test (/ 1 1) 1) (num-test (/ 1 1.0 -1.0+1.0i) -0.5-0.5i) (num-test (/ 1 1.0 0.0+1.0i) 0.0-1.0i) (num-test (/ 1 1.0 1) 1.0) (num-test (/ 1 1.0 1.0) 1.0) (num-test (/ 1 1.0 1.0+1.0i) 0.5-0.5i) (num-test (/ 1 1.0 1.234+1.234i) 0.40518638573744-0.40518638573744i) (num-test (/ 1 1.0 1/1) 1.0) (num-test (/ 1 1.0 123.4) 0.00810372771475) (num-test (/ 1 1.0 1234) 0.00081037277147) (num-test (/ 1 1.0 1234/11) 0.00891410048622) (num-test (/ 1 1.0) 1.0) (num-test (/ 1 1.0+1.0i -1.0+1.0i) -0.5) (num-test (/ 1 1.0+1.0i 0.0+1.0i) -0.5-0.5i) (num-test (/ 1 1.0+1.0i 1) 0.5-0.5i) (num-test (/ 1 1.0+1.0i 1.0) 0.5-0.5i) (num-test (/ 1 1.0+1.0i 1.0+1.0i) 0.0-0.5i) (num-test (/ 1 1.0+1.0i 1.234+1.234i) 0.0-0.40518638573744i) (num-test (/ 1 1.0+1.0i 1/1) 0.5-0.5i) (num-test (/ 1 1.0+1.0i 123.4) 0.00405186385737-0.00405186385737i) (num-test (/ 1 1.0+1.0i 1234) 0.00040518638574-0.00040518638574i) (num-test (/ 1 1.0+1.0i 1234/11) 0.00445705024311-0.00445705024311i) (num-test (/ 1 1.0+1.0i) 0.5-0.5i) (num-test (/ 1 1.234+1.234i) 0.40518638573744-0.40518638573744i) (num-test (/ 1 123.4) 0.00810372771475) (num-test (/ 1 1234) 1/1234) (num-test (/ 1 1234/11) 11/1234) (num-test (/ 1.0 -1.0+1.0i -1.0+1.0i) -0.0+0.5i) (num-test (/ 1.0 -1.0+1.0i 0.0+1.0i) -0.5+0.5i) (num-test (/ 1.0 -1.0+1.0i 1) -0.5-0.5i) (num-test (/ 1.0 -1.0+1.0i 1.0) -0.5-0.5i) (num-test (/ 1.0 -1.0+1.0i 1.0+1.0i) -0.5) (num-test (/ 1.0 -1.0+1.0i 1.234+1.234i) -0.40518638573744) (num-test (/ 1.0 -1.0+1.0i 1/1) -0.5-0.5i) (num-test (/ 1.0 -1.0+1.0i 123.4) -0.00405186385737-0.00405186385737i) (num-test (/ 1.0 -1.0+1.0i 1234) -0.00040518638574-0.00040518638574i) (num-test (/ 1.0 -1.0+1.0i 1234/11) -0.00445705024311-0.00445705024311i) (num-test (/ 1.0 -1.0+1.0i) -0.5-0.5i) (num-test (/ 1.0 0.0+1.0i -1.0+1.0i) -0.5+0.5i) (num-test (/ 1.0 0.0+1.0i 0.0+1.0i) -1.0) (num-test (/ 1.0 0.0+1.0i 1) 0.0-1.0i) (num-test (/ 1.0 0.0+1.0i 1.0) 0.0-1.0i) (num-test (/ 1.0 0.0+1.0i 1.0+1.0i) -0.5-0.5i) (num-test (/ 1.0 0.0+1.0i 1.234+1.234i) -0.40518638573744-0.40518638573744i) (num-test (/ 1.0 0.0+1.0i 1/1) 0.0-1.0i) (num-test (/ 1.0 0.0+1.0i 123.4) 0.0-0.00810372771475i) (num-test (/ 1.0 0.0+1.0i 1234) 0.0-0.00081037277147i) (num-test (/ 1.0 0.0+1.0i 1234/11) 0.0-0.00891410048622i) (num-test (/ 1.0 0.0+1.0i) 0.0-1.0i) (num-test (/ 1.0 1 -1.0+1.0i) -0.5-0.5i) (num-test (/ 1.0 1 0.0+1.0i) 0.0-1.0i) (num-test (/ 1.0 1 1) 1.0) (num-test (/ 1.0 1 1.0) 1.0) (num-test (/ 1.0 1 1.0+1.0i) 0.5-0.5i) (num-test (/ 1.0 1 1.234+1.234i) 0.40518638573744-0.40518638573744i) (num-test (/ 1.0 1 1/1) 1.0) (num-test (/ 1.0 1 123.4) 0.00810372771475) (num-test (/ 1.0 1 1234) 0.00081037277147) (num-test (/ 1.0 1 1234/11) 0.00891410048622) (num-test (/ 1.0 1) 1.0) (num-test (/ 1.0 1.0 -1.0+1.0i) -0.5-0.5i) (num-test (/ 1.0 1.0 0.0+1.0i) 0.0-1.0i) (num-test (/ 1.0 1.0 1) 1.0) (num-test (/ 1.0 1.0 1.0) 1.0) (num-test (/ 1.0 1.0 1.0+1.0i) 0.5-0.5i) (num-test (/ 1.0 1.0 1.234+1.234i) 0.40518638573744-0.40518638573744i) (num-test (/ 1.0 1.0 1/1) 1.0) (num-test (/ 1.0 1.0 123.4) 0.00810372771475) (num-test (/ 1.0 1.0 1234) 0.00081037277147) (num-test (/ 1.0 1.0 1234/11) 0.00891410048622) (num-test (/ 1.0 1.0) 1.0) (num-test (/ 1.0 1.0+1.0i -1.0+1.0i) -0.5) (num-test (/ 1.0 1.0+1.0i 0.0+1.0i) -0.5-0.5i) (num-test (/ 1.0 1.0+1.0i 1) 0.5-0.5i) (num-test (/ 1.0 1.0+1.0i 1.0) 0.5-0.5i) (num-test (/ 1.0 1.0+1.0i 1.0+1.0i) 0.0-0.5i) (num-test (/ 1.0 1.0+1.0i 1.234+1.234i) 0.0-0.40518638573744i) (num-test (/ 1.0 1.0+1.0i 1/1) 0.5-0.5i) (num-test (/ 1.0 1.0+1.0i 123.4) 0.00405186385737-0.00405186385737i) (num-test (/ 1.0 1.0+1.0i 1234) 0.00040518638574-0.00040518638574i) (num-test (/ 1.0 1.0+1.0i 1234/11) 0.00445705024311-0.00445705024311i) (num-test (/ 1.0 1.0+1.0i) 0.5-0.5i) (num-test (/ 1.0 1.234+1.234i -1.0+1.0i) -0.40518638573744) (num-test (/ 1.0 1.234+1.234i 0.0+1.0i) -0.40518638573744-0.40518638573744i) (num-test (/ 1.0 1.234+1.234i 1) 0.40518638573744-0.40518638573744i) (num-test (/ 1.0 1.234+1.234i 1.0) 0.40518638573744-0.40518638573744i) (num-test (/ 1.0 1.234+1.234i 1.0+1.0i) 0.0-0.40518638573744i) (num-test (/ 1.0 1.234+1.234i 1.234+1.234i) 0.0-0.32835201437394i) (num-test (/ 1.0 1.234+1.234i 1/1) 0.40518638573744-0.40518638573744i) (num-test (/ 1.0 1.234+1.234i 123.4) 0.00328352014374-0.00328352014374i) (num-test (/ 1.0 1.234+1.234i 1234) 0.00032835201437-0.00032835201437i) (num-test (/ 1.0 1.234+1.234i 1234/11) 0.00361187215811-0.00361187215811i) (num-test (/ 1.0 1.234+1.234i) 0.40518638573744-0.40518638573744i) (num-test (/ 1.0 1/1 -1.0+1.0i) -0.5-0.5i) (num-test (/ 1.0 1/1 0.0+1.0i) 0.0-1.0i) (num-test (/ 1.0 123.4 -1.0+1.0i) -0.00405186385737-0.00405186385737i) (num-test (/ 1.0 123.4 0.0+1.0i) 0.0-0.00810372771475i) (num-test (/ 1.0 123.4 1) 0.00810372771475) (num-test (/ 1.0 123.4 1.0) 0.00810372771475) (num-test (/ 1.0 123.4 1.0+1.0i) 0.00405186385737-0.00405186385737i) (num-test (/ 1.0 123.4 1.234+1.234i) 0.00328352014374-0.00328352014374i) (num-test (/ 1.0 123.4 1/1) 0.00810372771475) (num-test (/ 1.0 123.4 123.4) 0.00006567040287) (num-test (/ 1.0 123.4 1234) 0.00000656704029) (num-test (/ 1.0 123.4 1234/11) 0.00007223744316) (num-test (/ 1.0 123.4) 0.00810372771475) (num-test (/ 1.0 1234 -1.0+1.0i) -0.00040518638574-0.00040518638574i) (num-test (/ 1.0 1234 0.0+1.0i) 0.0-0.00081037277147i) (num-test (/ 1.0 1234 1) 0.00081037277147) (num-test (/ 1.0 1234 1.0) 0.00081037277147) (num-test (/ 1.0 1234 1.0+1.0i) 0.00040518638574-0.00040518638574i) (num-test (/ 1.0 1234 1.234+1.234i) 0.00032835201437-0.00032835201437i) (num-test (/ 1.0 1234 1/1) 0.00081037277147) (num-test (/ 1.0 1234 123.4) 0.00000656704029) (num-test (/ 1.0 1234 1234) 0.00000065670403) (num-test (/ 1.0 1234 1234/11) 0.00000722374432) (num-test (/ 1.0 1234) 0.00081037277147) (num-test (/ 1.0 1234/11 -1.0+1.0i) -0.00445705024311-0.00445705024311i) (num-test (/ 1.0 1234/11 0.0+1.0i) 0.0-0.00891410048622i) (num-test (/ 1.0 1234/11 1) 0.00891410048622) (num-test (/ 1.0 1234/11 1.0) 0.00891410048622) (num-test (/ 1.0 1234/11 1.0+1.0i) 0.00445705024311-0.00445705024311i) (num-test (/ 1.0 1234/11 1.234+1.234i) 0.00361187215811-0.00361187215811i) (num-test (/ 1.0 1234/11 1/1) 0.00891410048622) (num-test (/ 1.0 1234/11 123.4) 0.00007223744316) (num-test (/ 1.0 1234/11 1234) 0.00000722374432) (num-test (/ 1.0 1234/11 1234/11) 0.00007946118748) (num-test (/ 1.0 1234/11) 0.00891410048622) (num-test (/ 1.0) 1.0) (num-test (/ 1.0+1.0i -1.0+1.0i -1.0+1.0i) -0.5+0.5i) (num-test (/ 1.0+1.0i -1.0+1.0i 0.0+1.0i) -1.0) (num-test (/ 1.0+1.0i -1.0+1.0i 1) -0.0-1.0i) (num-test (/ 1.0+1.0i -1.0+1.0i 1.0) -0.0-1.0i) (num-test (/ 1.0+1.0i -1.0+1.0i 1.0+1.0i) -0.5-0.5i) (num-test (/ 1.0+1.0i -1.0+1.0i 1.234+1.234i) -0.40518638573744-0.40518638573744i) (num-test (/ 1.0+1.0i -1.0+1.0i 1/1) -0.0-1.0i) (num-test (/ 1.0+1.0i -1.0+1.0i 123.4) -0.0-0.00810372771475i) (num-test (/ 1.0+1.0i -1.0+1.0i 1234) -0.0-0.00081037277147i) (num-test (/ 1.0+1.0i -1.0+1.0i 1234/11) -0.0-0.00891410048622i) (num-test (/ 1.0+1.0i -1.0+1.0i) -0.0-1.0i) (num-test (/ 1.0+1.0i 0.0+1.0i -1.0+1.0i) -1.0) (num-test (/ 1.0+1.0i 0.0+1.0i 0.0+1.0i) -1.0-1.0i) (num-test (/ 1.0+1.0i 0.0+1.0i 1) 1.0-1.0i) (num-test (/ 1.0+1.0i 0.0+1.0i 1.0) 1.0-1.0i) (num-test (/ 1.0+1.0i 0.0+1.0i 1.0+1.0i) 0.0-1.0i) (num-test (/ 1.0+1.0i 0.0+1.0i 1.234+1.234i) 0.0-0.81037277147488i) (num-test (/ 1.0+1.0i 0.0+1.0i 1/1) 1.0-1.0i) (num-test (/ 1.0+1.0i 0.0+1.0i 123.4) 0.00810372771475-0.00810372771475i) (num-test (/ 1.0+1.0i 0.0+1.0i 1234) 0.00081037277147-0.00081037277147i) (num-test (/ 1.0+1.0i 0.0+1.0i 1234/11) 0.00891410048622-0.00891410048622i) (num-test (/ 1.0+1.0i 0.0+1.0i) 1.0-1.0i) (num-test (/ 1.0+1.0i 1 -1.0+1.0i) -0.0-1.0i) (num-test (/ 1.0+1.0i 1 0.0+1.0i) 1.0-1.0i) (num-test (/ 1.0+1.0i 1 1) 1.0+1.0i) (num-test (/ 1.0+1.0i 1 1.0) 1.0+1.0i) (num-test (/ 1.0+1.0i 1 1.0+1.0i) 1.0) (num-test (/ 1.0+1.0i 1 1.234+1.234i) 0.81037277147488) (num-test (/ 1.0+1.0i 1 1/1) 1.0+1.0i) (num-test (/ 1.0+1.0i 1 123.4) 0.00810372771475+0.00810372771475i) (num-test (/ 1.0+1.0i 1 1234) 0.00081037277147+0.00081037277147i) (num-test (/ 1.0+1.0i 1 1234/11) 0.00891410048622+0.00891410048622i) (num-test (/ 1.0+1.0i 1) 1.0+1.0i) (num-test (/ 1.0+1.0i 1.0 -1.0+1.0i) -0.0-1.0i) (num-test (/ 1.0+1.0i 1.0 0.0+1.0i) 1.0-1.0i) (num-test (/ 1.0+1.0i 1.0 1) 1.0+1.0i) (num-test (/ 1.0+1.0i 1.0 1.0) 1.0+1.0i) (num-test (/ 1.0+1.0i 1.0 1.0+1.0i) 1.0) (num-test (/ 1.0+1.0i 1.0 1.234+1.234i) 0.81037277147488) (num-test (/ 1.0+1.0i 1.0 1/1) 1.0+1.0i) (num-test (/ 1.0+1.0i 1.0 123.4) 0.00810372771475+0.00810372771475i) (num-test (/ 1.0+1.0i 1.0 1234) 0.00081037277147+0.00081037277147i) (num-test (/ 1.0+1.0i 1.0 1234/11) 0.00891410048622+0.00891410048622i) (num-test (/ 1.0+1.0i 1.0) 1.0+1.0i) (num-test (/ 1.0+1.0i 1.0+1.0i -1.0+1.0i) -0.5-0.5i) (num-test (/ 1.0+1.0i 1.0+1.0i 0.0+1.0i) 0.0-1.0i) (num-test (/ 1.0+1.0i 1.0+1.0i 1) 1.0) (num-test (/ 1.0+1.0i 1.0+1.0i 1.0) 1.0) (num-test (/ 1.0+1.0i 1.0+1.0i 1.0+1.0i) 0.5-0.5i) (num-test (/ 1.0+1.0i 1.0+1.0i 1.234+1.234i) 0.40518638573744-0.40518638573744i) (num-test (/ 1.0+1.0i 1.0+1.0i 1/1) 1.0) (num-test (/ 1.0+1.0i 1.0+1.0i 123.4) 0.00810372771475) (num-test (/ 1.0+1.0i 1.0+1.0i 1234) 0.00081037277147) (num-test (/ 1.0+1.0i 1.0+1.0i 1234/11) 0.00891410048622) (num-test (/ 1.0+1.0i 1.0+1.0i) 1.0) (num-test (/ 1.0+1.0i 1.234+1.234i -1.0+1.0i) -0.40518638573744-0.40518638573744i) (num-test (/ 1.0+1.0i 1.234+1.234i 0.0+1.0i) 0.0-0.81037277147488i) (num-test (/ 1.0+1.0i 1.234+1.234i 1) 0.81037277147488) (num-test (/ 1.0+1.0i 1.234+1.234i 1.0) 0.81037277147488) (num-test (/ 1.0+1.0i 1.234+1.234i 1.0+1.0i) 0.40518638573744-0.40518638573744i) (num-test (/ 1.0+1.0i 1.234+1.234i 1.234+1.234i) 0.32835201437394-0.32835201437394i) (num-test (/ 1.0+1.0i 1.234+1.234i 1/1) 0.81037277147488) (num-test (/ 1.0+1.0i 1.234+1.234i 123.4) 0.00656704028748) (num-test (/ 1.0+1.0i 1.234+1.234i 1234) 0.00065670402875) (num-test (/ 1.0+1.0i 1.234+1.234i 1234/11) 0.00722374431623) (num-test (/ 1.0+1.0i 1.234+1.234i) 0.81037277147488) (num-test (/ 1.0+1.0i 1/1 -1.0+1.0i) -0.0-1.0i) (num-test (/ 1.0+1.0i 1/1 0.0+1.0i) 1.0-1.0i) (num-test (/ 1.0+1.0i 123.4 -1.0+1.0i) -0.0-0.00810372771475i) (num-test (/ 1.0+1.0i 123.4 0.0+1.0i) 0.00810372771475-0.00810372771475i) (num-test (/ 1.0+1.0i 123.4 1) 0.00810372771475+0.00810372771475i) (num-test (/ 1.0+1.0i 123.4 1.0) 0.00810372771475+0.00810372771475i) (num-test (/ 1.0+1.0i 123.4 1.0+1.0i) 0.00810372771475) (num-test (/ 1.0+1.0i 123.4 1.234+1.234i) 0.00656704028748) (num-test (/ 1.0+1.0i 123.4 1/1) 0.00810372771475+0.00810372771475i) (num-test (/ 1.0+1.0i 123.4 123.4) 0.00006567040287+0.00006567040287i) (num-test (/ 1.0+1.0i 123.4 1234) 0.00000656704029+0.00000656704029i) (num-test (/ 1.0+1.0i 123.4 1234/11) 0.00007223744316+0.00007223744316i) (num-test (/ 1.0+1.0i 123.4) 0.00810372771475+0.00810372771475i) (num-test (/ 1.0+1.0i 1234 -1.0+1.0i) -0.0-0.00081037277147i) (num-test (/ 1.0+1.0i 1234 0.0+1.0i) 0.00081037277147-0.00081037277147i) (num-test (/ 1.0+1.0i 1234 1) 0.00081037277147+0.00081037277147i) (num-test (/ 1.0+1.0i 1234 1.0) 0.00081037277147+0.00081037277147i) (num-test (/ 1.0+1.0i 1234 1.0+1.0i) 0.00081037277147) (num-test (/ 1.0+1.0i 1234 1.234+1.234i) 0.00065670402875) (num-test (/ 1.0+1.0i 1234 1/1) 0.00081037277147+0.00081037277147i) (num-test (/ 1.0+1.0i 1234 123.4) 0.00000656704029+0.00000656704029i) (num-test (/ 1.0+1.0i 1234 1234) 0.00000065670403+0.00000065670403i) (num-test (/ 1.0+1.0i 1234 1234/11) 0.00000722374432+0.00000722374432i) (num-test (/ 1.0+1.0i 1234) 0.00081037277147+0.00081037277147i) (num-test (/ 1.0+1.0i 1234/11 -1.0+1.0i) -0.0-0.00891410048622i) (num-test (/ 1.0+1.0i 1234/11 0.0+1.0i) 0.00891410048622-0.00891410048622i) (num-test (/ 1.0+1.0i 1234/11 1) 0.00891410048622+0.00891410048622i) (num-test (/ 1.0+1.0i 1234/11 1.0) 0.00891410048622+0.00891410048622i) (num-test (/ 1.0+1.0i 1234/11 1.0+1.0i) 0.00891410048622) (num-test (/ 1.0+1.0i 1234/11 1.234+1.234i) 0.00722374431623) (num-test (/ 1.0+1.0i 1234/11 1/1) 0.00891410048622+0.00891410048622i) (num-test (/ 1.0+1.0i 1234/11 123.4) 0.00007223744316+0.00007223744316i) (num-test (/ 1.0+1.0i 1234/11 1234) 0.00000722374432+0.00000722374432i) (num-test (/ 1.0+1.0i 1234/11 1234/11) 0.00007946118748+0.00007946118748i) (num-test (/ 1.0+1.0i 1234/11) 0.00891410048622+0.00891410048622i) (num-test (/ 1.0+1.0i) 0.5-0.5i) (num-test (/ 1.234+1.234i -1.0+1.0i) -0.0-1.234i) (num-test (/ 1.234+1.234i 0.0+1.0i) 1.234-1.234i) (num-test (/ 1.234+1.234i 1) 1.234+1.234i) (num-test (/ 1.234+1.234i 1.0) 1.234+1.234i) (num-test (/ 1.234+1.234i 1.0+1.0i) 1.234) (num-test (/ 1.234+1.234i 1.234+1.234i) 1.0) (num-test (/ 1.234+1.234i 1/1) 1.234+1.234i) (num-test (/ 1.234+1.234i 123.4) 0.01+0.01i) (num-test (/ 1.234+1.234i 1234) 0.001+0.001i) (num-test (/ 1.234+1.234i 1234/11) 0.011+0.011i) (num-test (/ 10) 1/10) (num-test (/ 10/3) 3/10) (num-test (/ 10 3) 10/3) (num-test (/ 10 -3) -10/3) (num-test (/ -10 -3) 10/3) (num-test (/ 11) 1/11) (num-test (/ 123.4 -1.0+1.0i -1.0+1.0i) -0.0+61.7i) (num-test (/ 123.4 -1.0+1.0i 0.0+1.0i) -61.7+61.7i) (num-test (/ 123.4 -1.0+1.0i 1) -61.7-61.7i) (num-test (/ 123.4 -1.0+1.0i 1.0) -61.7-61.7i) (num-test (/ 123.4 -1.0+1.0i 1.0+1.0i) -61.7) (num-test (/ 123.4 -1.0+1.0i 1.234+1.234i) -50.0) (num-test (/ 123.4 -1.0+1.0i 1/1) -61.7-61.7i) (num-test (/ 123.4 -1.0+1.0i 123.4) -0.5-0.5i) (num-test (/ 123.4 -1.0+1.0i 1234) -0.05000000000000-0.05000000000000i) (num-test (/ 123.4 -1.0+1.0i 1234/11) -0.55000000000000-0.55000000000000i) (num-test (/ 123.4 -1.0+1.0i) -61.7-61.7i) (num-test (/ 123.4 0.0+1.0i -1.0+1.0i) -61.7+61.7i) (num-test (/ 123.4 0.0+1.0i 0.0+1.0i) -123.4) (num-test (/ 123.4 0.0+1.0i 1) 0.0-123.4i) (num-test (/ 123.4 0.0+1.0i 1.0) 0.0-123.4i) (num-test (/ 123.4 0.0+1.0i 1.0+1.0i) -61.7-61.7i) (num-test (/ 123.4 0.0+1.0i 1.234+1.234i) -50.0-50.0i) (num-test (/ 123.4 0.0+1.0i 1/1) 0.0-123.4i) (num-test (/ 123.4 0.0+1.0i 123.4) 0.0-1.0i) (num-test (/ 123.4 0.0+1.0i 1234) 0.0-0.1i) (num-test (/ 123.4 0.0+1.0i 1234/11) 0.0-1.10000000000000i) (num-test (/ 123.4 0.0+1.0i) 0.0-123.4i) (num-test (/ 123.4 1 -1.0+1.0i) -61.7-61.7i) (num-test (/ 123.4 1 0.0+1.0i) 0.0-123.4i) (num-test (/ 123.4 1 1) 123.4) (num-test (/ 123.4 1 1.0) 123.4) (num-test (/ 123.4 1 1.0+1.0i) 61.7-61.7i) (num-test (/ 123.4 1 1.234+1.234i) 50.0-50.0i) (num-test (/ 123.4 1 1/1) 123.4) (num-test (/ 123.4 1 123.4) 1.0) (num-test (/ 123.4 1 1234) 0.1) (num-test (/ 123.4 1 1234/11) 1.10000000000000) (num-test (/ 123.4 1) 123.4) (num-test (/ 123.4 1.0 -1.0+1.0i) -61.7-61.7i) (num-test (/ 123.4 1.0 0.0+1.0i) 0.0-123.4i) (num-test (/ 123.4 1.0 1) 123.4) (num-test (/ 123.4 1.0 1.0) 123.4) (num-test (/ 123.4 1.0 1.0+1.0i) 61.7-61.7i) (num-test (/ 123.4 1.0 1.234+1.234i) 50.0-50.0i) (num-test (/ 123.4 1.0 1/1) 123.4) (num-test (/ 123.4 1.0 123.4) 1.0) (num-test (/ 123.4 1.0 1234) 0.1) (num-test (/ 123.4 1.0 1234/11) 1.10000000000000) (num-test (/ 123.4 1.0) 123.4) (num-test (/ 123.4 1.0+1.0i -1.0+1.0i) -61.7) (num-test (/ 123.4 1.0+1.0i 0.0+1.0i) -61.7-61.7i) (num-test (/ 123.4 1.0+1.0i 1) 61.7-61.7i) (num-test (/ 123.4 1.0+1.0i 1.0) 61.7-61.7i) (num-test (/ 123.4 1.0+1.0i 1.0+1.0i) 0.0-61.7i) (num-test (/ 123.4 1.0+1.0i 1.234+1.234i) 0.0-50.0i) (num-test (/ 123.4 1.0+1.0i 1/1) 61.7-61.7i) (num-test (/ 123.4 1.0+1.0i 123.4) 0.5-0.5i) (num-test (/ 123.4 1.0+1.0i 1234) 0.05000000000000-0.05000000000000i) (num-test (/ 123.4 1.0+1.0i 1234/11) 0.55000000000000-0.55000000000000i) (num-test (/ 123.4 1.0+1.0i) 61.7-61.7i) (num-test (/ 123.4 1.234+1.234i -1.0+1.0i) -50.0) (num-test (/ 123.4 1.234+1.234i 0.0+1.0i) -50.0-50.0i) (num-test (/ 123.4 1.234+1.234i 1) 50.0-50.0i) (num-test (/ 123.4 1.234+1.234i 1.0) 50.0-50.0i) (num-test (/ 123.4 1.234+1.234i 1.0+1.0i) 0.0-50.0i) (num-test (/ 123.4 1.234+1.234i 1.234+1.234i) 0.0-40.51863857374392i) (num-test (/ 123.4 1.234+1.234i 1/1) 50.0-50.0i) (num-test (/ 123.4 1.234+1.234i 123.4) 0.40518638573744-0.40518638573744i) (num-test (/ 123.4 1.234+1.234i 1234) 0.04051863857374-0.04051863857374i) (num-test (/ 123.4 1.234+1.234i 1234/11) 0.44570502431118-0.44570502431118i) (num-test (/ 123.4 1.234+1.234i) 50.0-50.0i) (num-test (/ 123.4 1/1 -1.0+1.0i) -61.7-61.7i) (num-test (/ 123.4 1/1 0.0+1.0i) 0.0-123.4i) (num-test (/ 123.4 123.4 -1.0+1.0i) -0.5-0.5i) (num-test (/ 123.4 123.4 0.0+1.0i) 0.0-1.0i) (num-test (/ 123.4 123.4 1) 1.0) (num-test (/ 123.4 123.4 1.0) 1.0) (num-test (/ 123.4 123.4 1.0+1.0i) 0.5-0.5i) (num-test (/ 123.4 123.4 1.234+1.234i) 0.40518638573744-0.40518638573744i) (num-test (/ 123.4 123.4 1/1) 1.0) (num-test (/ 123.4 123.4 123.4) 0.00810372771475) (num-test (/ 123.4 123.4 1234) 0.00081037277147) (num-test (/ 123.4 123.4 1234/11) 0.00891410048622) (num-test (/ 123.4 123.4) 1.0) (num-test (/ 123.4 1234 -1.0+1.0i) -0.05000000000000-0.05000000000000i) (num-test (/ 123.4 1234 0.0+1.0i) 0.0-0.1i) (num-test (/ 123.4 1234 1) 0.1) (num-test (/ 123.4 1234 1.0) 0.1) (num-test (/ 123.4 1234 1.0+1.0i) 0.05000000000000-0.05000000000000i) (num-test (/ 123.4 1234 1.234+1.234i) 0.04051863857374-0.04051863857374i) (num-test (/ 123.4 1234 1/1) 0.1) (num-test (/ 123.4 1234 123.4) 0.00081037277147) (num-test (/ 123.4 1234 1234) 0.00008103727715) (num-test (/ 123.4 1234 1234/11) 0.00089141004862) (num-test (/ 123.4 1234) 0.1) (num-test (/ 123.4 1234/11 -1.0+1.0i) -0.55000000000000-0.55000000000000i) (num-test (/ 123.4 1234/11 0.0+1.0i) 0.0-1.10000000000000i) (num-test (/ 123.4 1234/11 1) 1.10000000000000) (num-test (/ 123.4 1234/11 1.0) 1.10000000000000) (num-test (/ 123.4 1234/11 1.0+1.0i) 0.55000000000000-0.55000000000000i) (num-test (/ 123.4 1234/11 1.234+1.234i) 0.44570502431118-0.44570502431118i) (num-test (/ 123.4 1234/11 1/1) 1.10000000000000) (num-test (/ 123.4 1234/11 123.4) 0.00891410048622) (num-test (/ 123.4 1234/11 1234) 0.00089141004862) (num-test (/ 123.4 1234/11 1234/11) 0.00980551053485) (num-test (/ 123.4 1234/11) 1.10000000000000) (num-test (/ 1234 -1.0+1.0i) -617.0-617.0i) (num-test (/ 1234 0.0+1.0i) 0.0-1234.0i) (num-test (/ 1234 1) 1234) (num-test (/ 1234 1.0) 1234.0) (num-test (/ 1234 1.0+1.0i) 617.0-617.0i) (num-test (/ 1234 1.234+1.234i) 500.0-500.0i) (num-test (/ 1234 1/1) 1234) (num-test (/ 1234 123.4) 10.0) (num-test (/ 1234 1234) 1) (num-test (/ 1234 1234/11) 11) (num-test (/ 1234/11 -1.0+1.0i) -56.09090909090909-56.09090909090909i) (num-test (/ 1234/11 0.0+1.0i) 0.0-112.18181818181819i) (num-test (/ 1234/11 1) 1234/11) (num-test (/ 1234/11 1.0) 112.18181818181819) (num-test (/ 1234/11 1.0+1.0i) 56.09090909090909-56.09090909090909i) (num-test (/ 1234/11 1.234+1.234i) 45.45454545454546-45.45454545454546i) (num-test (/ 1234/11 1/1) 1234/11) (num-test (/ 1234/11 123.4) 0.90909090909091) (num-test (/ 1234/11 1234) 1/11) (num-test (/ 1234/11 1234/11) 1) (num-test (/ 1234000000) 1/1234000000) (num-test (/ 1234000000.0) 0.00000000081037) (num-test (/ 1234000000.0+2.71828182845905i) 0.00000000081037-0.0i) (num-test (/ 1234000000/10) 10/1234000000) (num-test (/ 2) 1/2) (num-test (/ 2.71828182845905) 0.36787944117144) (num-test (/ 2.71828182845905+3.14159265358979i) 0.15750247989732-0.18202992367723i) (num-test (/ 2/2) 2/2) (num-test (/ 362880) 1/362880) (num-test (/ 362880/1234) 1234/362880) (num-test (/ 1/2 1+i 1-i) 0.25) (num-test (/ 2/9223372036854775807 2) 1/9223372036854775807) (num-test (/ -63/288230376151711744 -63) 1/288230376151711744) (if (not with-bignums) (begin (num-test (/ 1/2305843009213693952 -1 4194304/2097151) -2.168403310995243176730312012479018335398E-19) (num-test (/ 1/2199023255552 -63 8388608/4194303) -3.609105098938467225452985162735872325445E-15) (num-test (/ 1/17179869184 -1 1073741824/536870911) -2.91038304025235949890060282996273599565E-11) )) (for-each-permutation (lambda args (if (not (= (apply / args) (/ (car args) (apply * (cdr args))))) (format-logged #t "~A: ~A != ~A?~%" (port-line-number) (apply / args) (/ (car args) (apply * (cdr args)))))) '(1 1/2 0.5 1+i)) (num-test (/ -9223372036854775808 5.551115123125783999999999999999999999984E-17) -1.661534994731144452653560599947843044136E35) (num-test (/ 1.110223024625156799999999999999999999997E-16 -9223372036854775808) -1.203706215242022689593248685469006886702E-35) (num-test (/ 1.110223024625156799999999999999999999997E-16 5.551115123125783999999999999999999999984E-17 5.42101086242752217060000000000000000001E-20) 3.689348814741910322817021726897015792169E19) (num-test (/ 5.551115123125783999999999999999999999984E-17 1.110223024625156799999999999999999999997E-16) 5.000E-1) (num-test (/ 9223372036854775807 9223372036854775807) 1) (num-test (/ (* 2 3 4 5 6 7 8 9 10) (* 2 (expt (log 2) 11))) 102247563.00527) (num-test (/ 1 (/ 1 1234)) 1234) (num-test (/ 1.0 (/ 1.0 1.0+1.0i)) 1.0+1.0i) (num-test (/ 1.0 (/ 1.0 pi)) pi) (num-test (/ 1/123412341234) 123412341234) (num-test (/ 1/98947 2/97499 3/76847) 7492505653/593682) (num-test (/ 123412341234) 1/123412341234) (num-test (/ 500009/500029 500057/500041) 250025000369/250043001653) (num-test (/ -9223372036854775808 -9223372036854775808 4) 1/4) (num-test (/ -9223372036854775808 2) -4611686018427387904) (num-test (/ 0 -00-1i) 0.0) (num-test (/ 0+i) 0-1i) (num-test (/ 0-i) 0+i) (num-test (/ 1+i) 1/2-1/2i); (num-test (/ 1.0 1/524288 1/19073486328125) 1.000000000000000024754073164739868757037E19) (num-test (/ 1/10 010) 1/100) (num-test (/ 1/9223372036854775807 1/9223372036854775807) 1) (num-test (/ 1234567890/9223372036854775807 123456789/9223372036854775807) 10) (num-test (/ 2 -9223372036854775808) -1/4611686018427387904) (num-test (/ 2 most-negative-fixnum) -1/4611686018427387904) (num-test (/ 2/9223372036854775807 2/3) 3/9223372036854775807) (num-test (/ 9223372036854775807/123456789 9223372036854775807/123456789) 1) (num-test (/ 9223372036854775807/1234567890 9223372036854775807/12345678900) 10) (num-test (/ most-negative-fixnum 2) -4611686018427387904) (num-test (/ most-negative-fixnum most-negative-fixnum 2) 1/2) (num-test (/ most-negative-fixnum most-negative-fixnum) 1) (num-test (/ (/ (- most-positive-fixnum))) -9223372036854775807) (num-test (/ most-negative-fixnum 864691128455135232) -32/3) (num-test (/(*(/(*)))) 1) (num-test (/ 12341234/111 123456789 12341234/111) 1/123456789) (num-test (/ 1e63 1e-63) 1e126) (num-test (/ 1e154 1e-154) 1e308) ; else inf (num-test (/ 1e-200 1e200) 0.0) ;;; inaccuracies creep in (/ 1e-200 1e123) => 9.8813129168249e-324 ;;; or (/ 10e307 1e309) => 0.0 and (/ 10e308 1e308) => inf ;;; might be neat to handle these (if exps= just divide mant? (num-test (/ -0.651381628953465E0 -0.9237050214744277E0) 7.051835962889135018948026610294923703508E-1) (num-test (/ 0.5067986732438687E0 0.6260017267692811E0) 8.095803119575965307784422745290898299591E-1) (num-test (/ -0.8399445051045212E0 0.1829250718359493E0) -4.591740742120902283769244624290448381427E0) (num-test (/ -0.5987041550692662E0 -0.4124053212463479E0) 1.451737221187875469260813375116670894624E0) (num-test (/ 0.5861382519823647E0 -0.7560374696447822E0) -7.752767230673855251634630463492900473644E-1) (num-test (/ -0.012882644582824954E0 -0.4671067448591679E0) 2.757965866390787237919533761751626109973E-2) (num-test (/ -0.7830198970435231E0 2.1690164135025935E9) -3.610022921767930828778117437420472499541E-10) (num-test (/ -0.2339206226652567E0 2.729373380002701E9) -8.570488170622710029144125942503181451939E-11) (num-test (/ -0.2285806315782951E0 -2.602073870582813E9) 8.784555817667757706754728345837912936962E-11) (num-test (/ -0.5298716781559242E0 1.3509547453340487E9) -3.922201539215168658138266422439019362809E-10) (num-test (/ 0.7287190523338418E0 -8.244205871151566E9) -8.839166121309546680006433484161854320415E-11) (num-test (/ 0.18973054487786212E0 6.557593452200545E9) 2.893295326415727180554709812740977209383E-11) (num-test (/ 0.5084032300982587E0 4.5431682148621014E-11) 1.119049980221104893780059617560389832312E10) (num-test (/ 0.6621212705475221E0 -1.838873437953206E-11) -3.6006897314505184969089186237646638616E10) (num-test (/ -0.4041791750277005E0 7.707875701307648E-11) -5.243716825365141031107302892929967408104E9) (num-test (/ -0.09569063343466655E0 4.789751448902253E-11) -1.9978204392338054187984205729651608099E9) (num-test (/ -0.6471008513340974E0 1.890250884404079E-11) -3.423359600956370337454713673029890117878E10) (num-test (/ -0.4301276572683971E0 9.134844738134672E-11) -4.708647706651977799170970961042517830565E9) (num-test (/ -0.5061027989171409E0 4.246468515299164E19) -1.191820443490291421327933820140392588455E-20) (num-test (/ -0.9601783702217944E0 7.495754288877955E19) -1.280962973461506313537075112900039769719E-20) (num-test (/ -0.6477754868655262E0 -8.507334914535449E19) 7.614317449272520944989386124046318248581E-21) (num-test (/ 0.1934462826116784E0 3.6173521417193476E19) 5.347731573618163299262146929108634114511E-21) (num-test (/ -0.7794308505212441E0 4.172217291786081E19) -1.868145391314406352823434511710862322776E-20) (num-test (/ -0.8462346361305484E0 7.378170819620111E19) -1.146943675904374803577079154661818066039E-20) (num-test (/ 0.9783005897625496E0 6.175045007596078E-21) 1.584280905740958108982369263614665552851E20) (num-test (/ -0.9700832605850568E0 -1.7695051741124812E-21) 5.4822290139480091183029856440319954731E20) (num-test (/ 0.07062591404368701E0 -8.855398515753737E-21) -7.975464223100026969579387130724758972895E18) (num-test (/ 0.4751383409805402E0 -8.1371029771106E-21) -5.839158510308749293926976970601471638106E19) (num-test (/ -0.5103510786836052E0 8.302178001281015E-21) -6.147195092719750272554937885528717433502E19) (num-test (/ 0.7148807879199733E0 4.338856119331781E-21) 1.647625015115898182854639201045676562387E20) (num-test (/ 4.180670608983218E9 -0.8621420131862095E0) -4.849167010818503318377538718886882159085E9) (num-test (/ 3.202209376555907E9 0.008113117870009012E0) 3.946952858152361317410218375892707092144E11) (num-test (/ 7.767843042272955E9 -0.04145956871894663E0) -1.87359475322354819500790198613468533242E11) (num-test (/ 1.1937839884817846E9 0.45557753834605563E0) 2.620374992181877679062077123717269598672E9) (num-test (/ -2.4205138097471213E9 -0.3737757916008485E0) 6.475844247109412171348144805246962117951E9) (num-test (/ -7.534066568550288E9 -0.3609372553147958E0) 2.087361849632108651836399241353567759856E10) (num-test (/ 6.098867840095913E9 3.0464612528039427E9) 2.001951554277132357084991750811780094278E0) (num-test (/ 4.956687716396978E9 7.035407926465974E9) 7.045345157244949942198957065331702603612E-1) (num-test (/ 6.969049109639194E9 -8.115758334653503E9) -8.587058438990264159516222429259889060394E-1) (num-test (/ -8.0699835500126705E9 -1.1896420666819375E9) 6.783539163608157717597859343396495021042E0) (num-test (/ -2.229793060172571E9 -2.658809828346301E9) 8.386433043838395143199282594014446842336E-1) (num-test (/ 3.0672739776038485E9 -7.988270854370873E9) -3.839722054398737311833139439634292109412E-1) (num-test (/ 2.477055391151669E9 -1.3522358047779648E-11) -1.831822070085178675709536653203693354871E20) (num-test (/ 1.1318646612469008E9 -8.457695758685169E-11) -1.338265992938554414702828284241585726631E19) (num-test (/ -7.978772126259147E9 6.210468872769038E-11) -1.284729428601367805018001112036580297153E20) (num-test (/ -9.057338243339752E9 7.364415429198257E-11) -1.22987877726580108212627205863468836645E20) (num-test (/ -5.341117220720213E9 4.7359651161519756E-11) -1.127777990277920421924982539741683693507E20) (num-test (/ 5.838003830912871E9 -5.0625478501901024E-11) -1.153175042225753978331600642680269130096E20) (num-test (/ 6.407156672927742E9 5.006339136594536E19) 1.279808758079079048751288572047629634958E-10) (num-test (/ 4.687485139826675E8 -3.5561755068968083E19) -1.318125365504547538826162177354689732851E-11) (num-test (/ -5.838044723576891E9 -6.843985743599882E19) 8.530182473036721969937888742798001972008E-11) (num-test (/ 3.9279221543350096E9 -5.882918042982924E19) -6.676826237652909876656284584084555589571E-11) (num-test (/ -9.686323716926361E9 -3.44800215666902E19) 2.809256861452760638746791455737599480861E-10) (num-test (/ 7.301304808910639E9 1.2845297359643038E19) 5.684029419085037872687787191413868358377E-10) (num-test (/ 4.380345662298534E9 -4.352751895415198E-21) -1.006339384266859136854551985691861659542E30) (num-test (/ 8.239490918139045E9 3.2397577733346748E-21) 2.543242888698483402490821850315555889368E30) (num-test (/ 3.8980499504872713E9 8.311650110069505E-21) 4.689862901910189296816144765858628505003E29) (num-test (/ -9.425472285331268E9 -3.294031046828316E-21) 2.861379310436876111669825630018089608938E30) (num-test (/ 2.517833161624173E9 3.6891560299469316E-21) 6.824957093669990747641669780362243770063E29) (num-test (/ -5.463519676339016E9 -7.298583081866205E-22) 7.485726496576409428699223883071063828111E30) (num-test (/ 1.39357009199772E-11 0.417842407627649E0) 3.335157146709649079791043787228216537723E-11) (num-test (/ 8.58494900746665E-11 -0.6481371063028898E0) -1.324557554872456302657963676252150750478E-10) (num-test (/ -9.310282234439046E-11 0.9146343299129254E0) -1.017923986663107128254299604028521252096E-10) (num-test (/ -8.800556770159418E-11 -0.9305573406536135E0) 9.457296596014170681132977631993414317205E-11) (num-test (/ -1.3361456473382827E-11 0.06420301636905124E0) -2.081125970247038707404762086321230923761E-10) (num-test (/ 6.1406425153971765E-12 -0.3082496074575478E0) -1.992100676476244033296635444865296145538E-11) (num-test (/ -3.6962256202372035E-11 3.089420488573177E9) -1.196413901541863127466123235969256148157E-20) (num-test (/ -6.145126590884831E-11 -6.225608984106817E9) 9.870723661849873241350389006374300024184E-21) (num-test (/ 9.052281678541901E-11 -6.9187138778508625E9) -1.308376359878287335554324548627653637652E-20) (num-test (/ -3.4950245360118636E-11 7.543342567738434E9) -4.633257080169574405642456881139071687897E-21) (num-test (/ -3.482822570743636E-11 -3.87599225187502E9) 8.985628309909063146939690605121402184145E-21) (num-test (/ -9.42226868788213E-11 7.501937454180854E9) -1.25597803839741017709728590003874245271E-20) (num-test (/ -4.8165035309367155E-11 9.484620130429997E-11) -5.078225026096383416618039442767276425835E-1) (num-test (/ 6.880022773725747E-11 -9.699156104509544E-11) -7.093424107822057000929770558471489984227E-1) (num-test (/ 1.5817962388036865E-11 -7.11651152335492E-11) -2.222712959309569253469449863287830842251E-1) (num-test (/ -7.0140750853949335E-12 -4.4677941652531186E-11) 1.569919030725435801904141818366904619636E-1) (num-test (/ -2.6947489262085355E-11 8.365454450205894E-11) -3.221282169723859093984652053864584015511E-1) (num-test (/ 8.703167674410303E-11 -4.88739813223768E-11) -1.780736383435491638475146912252252561499E0) (num-test (/ 1.165112061543483E-12 -5.899528740399518E19) -1.974923952086012268924127751659019857389E-32) (num-test (/ 7.126386981630328E-12 5.091741402945837E19) 1.399597194293359595983101664952569614126E-31) (num-test (/ -7.132349854872655E-13 7.70347159367981E19) -9.258617712985762871283798832641751905855E-33) (num-test (/ 4.507266517270466E-11 -1.6192737232544485E19) -2.78351118315665136913517665604742725923E-30) (num-test (/ -3.025128309814261E-11 -5.606736896306867E19) 5.395523930874836927233660478269495795871E-31) (num-test (/ -5.390258677516223E-11 6.628750121976767E18) -8.131636550373975963243412569165785520017E-30) (num-test (/ -8.484515181627938E-11 6.226893371743352E-21) -1.362559895457550846279271972989853630227E10) (num-test (/ 5.110456708789676E-11 -7.434814854731122E-21) -6.873683889434922905934754874417370413592E9) (num-test (/ -7.784815533665352E-11 -8.942884975553875E-21) 8.705038200698988300091363733020271337225E9) (num-test (/ 6.06871371776654E-11 -8.4720755768444E-21) -7.163195916657483482294943699821186479438E9) (num-test (/ 6.395725883763629E-11 3.2465500186809204E-21) 1.970006883295217146112013920243427167994E10) (num-test (/ 8.23766365482318E-11 3.5665958051648335E-21) 2.309671211661863324131996575306264215863E10) (num-test (/ -6.882125490660233E19 0.680553203393516E0) -1.011254587641810638505458546065261498221E20) (num-test (/ -8.955858402134752E19 0.11144092291315044E0) -8.036418012361891226885340978581557821805E20) (num-test (/ 4.517225460957592E19 -0.5804969398143229E0) -7.781652496570381006264991321295105224966E19) (num-test (/ -9.741926397385082E19 -0.9037000739789977E0) 1.078004381972805693752225428081454781542E20) (num-test (/ 9.654390326446178E19 -0.061963385089831124E0) -1.558079874501654704495847314268744072438E21) (num-test (/ 9.50855454738802E19 0.30375471599023185E0) 3.130339727036137864357134952530976170215E20) (num-test (/ 4.323538184184934E19 -2.6027608151521606E9) -1.661135421670382968923474255247239383096E10) (num-test (/ 4.0554081767557594E17 4.814123702784068E9) 8.423979995384136048633041200603888010585E7) (num-test (/ 5.12727309625028E19 1.761988796449604E9) 2.909935129316203535920673855950717437829E10) (num-test (/ -7.335661993746345E19 -4.961351435504E9) 1.478561252736806087045652086640747044774E10) (num-test (/ 3.7135994768593306E18 3.273427798269768E8) 1.134468118961482490398408895662653948827E10) (num-test (/ 1.3911083524706402E19 8.651242909451927E9) 1.607986698594236535694138981270724564992E9) (num-test (/ 6.473382688386894E19 -3.700509647679497E-11) -1.74932193257385527761113361595002688054E30) (num-test (/ 7.25328632809461E19 6.793518758100849E-11) 1.0676773828651782212117989476182162163E30) (num-test (/ 7.053090091571119E19 8.009021819073383E-11) 8.806431360661641824334823520600629499368E29) (num-test (/ -1.6322872380348074E19 -1.234889420758779E-11) 1.32180842316378978004378947103470484747E30) (num-test (/ -7.716951191497702E19 -2.473367210466666E-11) 3.120018393888910452644610629695438606501E30) (num-test (/ -2.1174708383466066E19 -9.66632270128099E-11) 2.190565020207733610503619470750854251338E29) (num-test (/ 4.0902039392392786E18 -5.029423690873208E19) -8.132549951322828067822875337940065787516E-2) (num-test (/ 1.4562115759233494E17 4.2665150414889705E19) 3.413117173530803542079920263107168159861E-3) (num-test (/ -3.309692589578652E19 1.1329455009949342E19) -2.92131667999222745140457080629099499358E0) (num-test (/ 3.059130103268258E19 -7.719433592654628E19) -3.962894513632647141286488246687660445133E-1) (num-test (/ 5.622979366632147E19 -8.407251901594788E19) -6.688248945610292804540334084533940238665E-1) (num-test (/ -7.457587910839625E18 1.102755747735572E19) -6.762683328700153669243467171164281736437E-1) (num-test (/ 1.2026615920578564E19 -3.77964792582931E-21) -3.181940793583240608441984111790776956096E39) (num-test (/ -2.74643694419756E19 2.538907641816601E-22) -1.08173960287601117923133084738647095934E41) (num-test (/ 8.267361397156658E18 -4.986401395715489E-21) -1.657981526368955793956856573504468676464E39) (num-test (/ 9.876393891158812E19 -5.792612775193684E-22) -1.704998119925007613535922021885867984527E41) (num-test (/ 3.927461252713038E17 4.810589424292295E-21) 8.164199656866003466542429981600313024025E37) (num-test (/ 7.29943837795987E19 -4.8820727437034755E-21) -1.495151498382347474354240468822304376928E40) (num-test (/ -7.837850970911807E-21 0.41514160181315674E0) -1.887994587070894820872902637806483134671E-20) (num-test (/ 1.1499234744049124E-21 0.4643166529612681E0) 2.476593219457143961012942936990797968514E-21) (num-test (/ -1.094368243984769E-21 0.9008053219044149E0) -1.214877640455251662856715755193246361763E-21) (num-test (/ 2.4821206327531197E-21 0.22988631081892086E0) 1.079716588565493668307955174993650571244E-20) (num-test (/ -4.56226662576732E-22 0.6695285124602162E0) -6.814148375851898788485451948577541009839E-22) (num-test (/ 6.442796853653397E-21 -0.0419134640377401E0) -1.537166397855380228851954699451812058468E-19) (num-test (/ -5.584403218169678E-21 -8.092869169805251E9) 6.900399723506295845105466793248363429626E-31) (num-test (/ -9.796722996869492E-21 -3.2988270899833827E9) 2.969759471970033259328414098139420231204E-30) (num-test (/ 9.441829923771915E-22 5.464575083746736E9) 1.727825087783076315606418411938950517056E-31) (num-test (/ -6.419360319610147E-21 -7.333962810289677E9) 8.752921831841952013186922455457072581443E-31) (num-test (/ 7.973734412555454E-21 -9.367577614661436E9) -8.512055880994845185202464827966401354632E-31) (num-test (/ 8.105484193881594E-21 -8.664550975192905E9) -9.354765431108951260398341387461553707907E-31) (num-test (/ -5.3151708182942476E-21 -3.406928289732576E-11) 1.560106455516695805992469791379650741489E-10) (num-test (/ -7.026602845639829E-21 -9.92483846943868E-11) 7.079815824989676856562805642631867847741E-11) (num-test (/ -5.901970468193158E-21 2.074489043942647E-11) -2.845023686881582124910812196899705492945E-10) (num-test (/ -6.40466723844613E-21 -2.551008177490094E-11) 2.510641594550905909683475044031419810602E-10) (num-test (/ 8.056066940872177E-21 4.645883100460603E-11) 1.734022739417072488146823616965762354533E-10) (num-test (/ 7.453765056481805E-21 6.956136187014756E-11) 1.071538114851171096483487539186715128913E-10) (num-test (/ 7.357434693258832E-21 -7.093525088486332E19) -1.037204295675341715303117810431180096085E-40) (num-test (/ -3.3759558579798473E-21 9.991075630444324E19) -3.378971376908405498870850768959668870304E-41) (num-test (/ 6.908026973557955E-21 -4.20805893397862E19) -1.641618399822784611549409240045335916762E-40) (num-test (/ 5.181767322756247E-21 7.46986056263721E19) 6.936899664063931551045422017869651239957E-41) (num-test (/ -5.7217313601659264E-21 5.604979023134118E19) -1.020830111326005351069300302415295512527E-40) (num-test (/ -9.340193892824771E-21 9.147101848766205E19) -1.021109641857175884684740262364588092125E-40) (num-test (/ 8.331002176099931E-21 2.0276444314093977E-21) 4.108709617449606347005645831416724715479E0) (num-test (/ -3.747505523684784E-21 4.394623185543803E-21) -8.527478615259381231018127145394525879915E-1) (num-test (/ -3.310403953328861E-21 2.3420390876737627E-21) -1.413470838617356120752866783055539347411E0) (num-test (/ 6.23845405853013E-21 -8.933620117412232E-21) -6.983119918397872761237650028889120834928E-1) (num-test (/ -4.276770609150315E-21 6.853299965034864E-21) -6.240454424832049912604789277138688124888E-1) (num-test (/ -8.847946637724495E-21 6.33827952828724E-21) -1.395953996386055439061738621964402924048E0) (when with-bignums ; from futilitycloset I think (let ((oldp (*s7* 'bignum-precision))) (set! (*s7* 'bignum-precision) 2048) (test (object->string (/ 1.0 999999999999999999999998999999999999999999999999)) "1.00000000000000000000000100000000000000000000000200000000000000000000000300000000000000000000000500000000000000000000000800000000000000000000001300000000000000000000002100000000000000000000003400000000000000000000005500000000000000000000008900000000000000000000014400000000000000000000023300000000000000000000037700000000000000000000061000000000000000000000098700000000000000000000159700000000000000000000258400000000000000000000418100000000000000000000676500000000000000000001094600000000000000000001771100000000000000000002865700000000000000000004636800000000000000000007502500000000000000000012139300000000000000001E-48") (set! (*s7* 'bignum-precision) oldp))) (for-each (lambda (num-and-val) (let ((num (car num-and-val)) (val (cadr num-and-val))) (num-test-1 '/ num (/ num) val))) (vector (list 1 1) (list 2 1/2) (list 3 1/3) (list -1 -1) (list -2 -1/2) (list -3 -1/3) (list 9223372036854775807 1/9223372036854775807) (list 1/2 2) (list 1/3 3) (list -1/2 -2) (list -1/3 -3) (list 1/9223372036854775807 9223372036854775807) (list 1.0 1.0) (list 2.0 0.5) (list -2.0 -0.5) (list 1e+16 1e-16) (list inf.0 0.0) (list -inf.0 0.0) (list 0+1i 0-1i) (list 0+2i 0-0.5i) (list 0-1i 0+1i) (list 1+1i 0.5-0.5i) (list 1-1i 0.5+0.5i) (list -1+1i -0.5-0.5i) (list -1-1i -0.5+0.5i) (list 0.1+0.1i 5-5i) (list 1e+16+1e+16i 5e-17-5e-17i) (list 1e-16+1e-16i 5e+15-5e+15i) )) (num-test (/ -8) -1/8) (num-test (/ 0 2/3) 0) (num-test (/ 1e-10 1e10) 1e-20) (num-test (/ 4 2) 2) (num-test (/ -9223372036854775808 -9223372036854775808) 1) (num-test (/ -9223372036854775808 9223372036854775807) -9223372036854775808/9223372036854775807) (num-test (/ most-positive-fixnum most-positive-fixnum) 1) (num-test (/ (/ 1 most-positive-fixnum)) most-positive-fixnum) (num-test (/ (/ -1 most-positive-fixnum)) (- most-positive-fixnum)) (num-test (/ (/ most-positive-fixnum) 1) 1/9223372036854775807) ; why isn't this a ratio in the non-bignum case? (if (not with-bignums) (begin (num-test (/ -1024 1/9765625 1/512 1/1953125) -1e19) (num-test (/ 1/19073486328125 -524288) -1e-19) (num-test (/ 1/19073486328125 524288) 1e-19) (num-test (/ 1/524288 -19073486328125) -1e-19) (num-test (/ 1/524288 19073486328125) 1e-19) (num-test (/ 1/9223372036854775807 1/3) 3.2526065174565e-19) (num-test (/ 1/9223372036854775807 1/9223372036854775806) 1.0) (num-test (/ 1/98947 2/97499 3/76847 4/61981 5/59981 6/66601) 2.6040239996689e+16) (num-test (/ 1/98947 2/97499 3/76847 4/61981 5/59981) 2345932343059.9) (num-test (/ 1/98947 2/97499 3/76847 4/61981) 464392992878593/2374728) ;195556288.07955 -- seems to fit (num-test (/ 1024 1/9765625 1/512 1/1953125) 1e19) (num-test (/ 500009/500029 500057/500041 500083/500069) 0.999900013909921) (num-test (/ 98947 2/97499 76847 4/61981 5/59981) 11667778186668.0) (num-test (/ 3037000500 1/3037000500) 9.22337203700025E18) )) (if with-bignums (begin (num-test (/ 1/9223372036854775807 1+1i 1-1i) 5.421010862427522170625011179760852311177E-20) (num-test (/ (/ 1 most-positive-fixnum) most-negative-fixnum) -1/85070591730234615856620279821087277056) (num-test (/ 1.0e308+1.0e308i 2.0e308+2.0e308i) (/ 1.0e307+1.0e307i 2.0e307+2.0e307i)) (num-test (/ (+ 1.2345e-15 1 -1)) 8.1004455245038e+14) (num-test (/ -1.797693134862315699999999999999999999998E308 -9223372036854775808) 1.949062802279999590850112500817203908808E289) (num-test (/ -1/19073486328125 524288) -1/10000000000000000000) (num-test (/ -1/524288 19073486328125) -1/10000000000000000000) (num-test (/ -1024 1/9765625 1/512 1/1953125) -10000000000000000000) (num-test (/ -21 -1/2432902008176640000) 51090942171709440000) (num-test (/ -21 1/2432902008176640000) -51090942171709440000) (num-test (/ -2432902008176640000 -1/21) 51090942171709440000) (num-test (/ -2432902008176640000 1/21) -51090942171709440000) (num-test (/ -9223372036854775808 -9223372036854775808 -9223372036854775808) -1/9223372036854775808) (num-test (/ -9223372036854775808 -9223372036854775808) 1) (num-test (/ -9223372036854775808 9223372036854775807 -9223372036854775808) 1/9223372036854775807) (num-test (/ 0+1e20i 0-1e20i) -1.0) (num-test (/ 1 1000000000 1000000000 1000000000) 1/1000000000000000000000000000) (num-test (/ 1.0e20+i 1.0e20+i) 1.0) (num-test (/ 1/1024 9765625 -512 1953125) -1/10000000000000000000) (num-test (/ 1/1024 9765625 512 1953125) 1/10000000000000000000) (num-test (/ 1/19073486328125 524288) 1/10000000000000000000) (num-test (/ 1/524288 19073486328125) 1/10000000000000000000) (num-test (/ 1/9223372036854775807 1/3) 3/9223372036854775807) (num-test (/ 1/9223372036854775807 1/9223372036854775806) 9223372036854775806/9223372036854775807) (num-test (/ 1/98947 2/97499 3/76847 4/61981 5/59981 6/66601) 1855154611405774907304533/71241840) (num-test (/ 1/98947 2/97499 3/76847 4/61981 5/59981) 27854756105850886733/11873640) (num-test (/ 1024 1/9765625 1/512 1/1953125) 10000000000000000000) (num-test (/ 132120577/12 33292289/6 260046847/4) 264241154/8657554783862783) (num-test (/ 1e20 0+i) 0-1e20i) (num-test (/ 21 -1/2432902008176640000) -51090942171709440000) (num-test (/ 21 1/2432902008176640000) 51090942171709440000) (num-test (/ 2432902008176640000 -1/21) -51090942171709440000) (num-test (/ 2432902008176640000 1/21) 51090942171709440000) (num-test (/ 500009/500029 500057/500041 500083/500069) 125029751909525461/125042254395637199) (num-test (/ 9223372036854775807 -9223372036854775808) -9223372036854775807/9223372036854775808) (num-test (/ 98947 2/97499 76847 4/61981 5/59981) 35865350012435458633/3073880) (num-test (/ most-negative-fixnum) -1/9223372036854775808) (num-test (/ 10105597264942543888 14352488138967388642) 5052798632471271944/7176244069483694321) (num-test (/ -17631701977702695093 3931860028646338313) -17631701977702695093/3931860028646338313) (num-test (/ -1606495881715082381 16324360910828438638) -1606495881715082381/16324360910828438638) (num-test (/ -7960193178071300653 -10280747961248435844) 7960193178071300653/10280747961248435844) (num-test (/ -11544909483975853384 -16041992360613233027) 11544909483975853384/16041992360613233027) (num-test (/ -5758820541298901548 -2596462557714095861) 5758820541298901548/2596462557714095861) (num-test (/ -13056342734667572546 46502284983183419157350605242474199851) -13056342734667572546/46502284983183419157350605242474199851) (num-test (/ 12668118634717482325 -338544675918656078399121171905238525746) -12668118634717482325/338544675918656078399121171905238525746) (num-test (/ -16738429327795346815 164053836541028518093058940786011794219) -16738429327795346815/164053836541028518093058940786011794219) (num-test (/ -9884600460121235549 -53914696297933680001835530599748561584) 9884600460121235549/53914696297933680001835530599748561584) (num-test (/ 6753521264659576004 71759828079371803409570464915096122874) 3376760632329788002/35879914039685901704785232457548061437) (num-test (/ -6072478784520825268 83641961138289700975241455431547940418) -3036239392260412634/41820980569144850487620727715773970209) (num-test (/ -6708950756971973620 -9847903810677323447803434015107261150885944735136350527205856921771320298384705376646797569973415403097847060539915279223391112430240736564839483430569706) 3354475378485986810/4923951905338661723901717007553630575442972367568175263602928460885660149192352688323398784986707701548923530269957639611695556215120368282419741715284853) (num-test (/ 11263779860755455072 2292311486393743282743453705144070351222990311578446825826935237655927864700827857707370158936582804478427014131790879562565658386819339761919809732496450) 1877296643459242512/382051914398957213790575617524011725203831718596407804304489206275987977450137976284561693156097134079737835688631813260427609731136556626986634955416075) (num-test (/ 9956488981426387585 -12351244248621474338537656633137999145154500022264356186225225426288301330225259889671144104952158102155582320296061124840400655528634050137479515338944145) -1991297796285277517/2470248849724294867707531326627599829030900004452871237245045085257660266045051977934228820990431620431116464059212224968080131105726810027495903067788829) (num-test (/ -14875992781716065391 4906952781757522095285156014969507916562921709689447567404076064849249737893410245743456952512717420040816186768213920574809530298070437840356629617118643) -2125141825959437913/700993254536788870755022287852786845223274529955635366772010866407035676841915749391922421787531060005830883824030560082115647185438633977193804231016949) (num-test (/ 16043178952268979636 -4962728781666935768923030490263743715131420507991284894489828489607808897271220927863958149140648859077934323268424257800724618076505149638049461104621679) -5347726317422993212/1654242927222311922974343496754581238377140169330428298163276163202602965757073642621319383046882953025978107756141419266908206025501716546016487034873893) (num-test (/ -14889985628902581941 3075736124701105220602924325296812116294816310089906623707854625135862902005059305428034753787024827094954645083406870532379125275086885405969947540175361) -14889985628902581941/3075736124701105220602924325296812116294816310089906623707854625135862902005059305428034753787024827094954645083406870532379125275086885405969947540175361) (num-test (/ -1719613957783789857 19860562547348050982501313785551054055826630539673708970554435103060535649825139319625648954889488501680865494719253019921780044205805557658109807483499994523398090829033362953135186523580359552555144614353929273831853529446536288544481045105104526669277307473478898498061888931858821517694257595658138564305517447595298378933983614114298000880741350618424855028965861930329619462261269994651112266861896630584883581092431090390354633458596611690990999635499563944625720180529318327647519405136188243979680965052005899543797270970540925042201315580510136864931200059448645464256385079735225156720340173280541113382758) -1719613957783789857/19860562547348050982501313785551054055826630539673708970554435103060535649825139319625648954889488501680865494719253019921780044205805557658109807483499994523398090829033362953135186523580359552555144614353929273831853529446536288544481045105104526669277307473478898498061888931858821517694257595658138564305517447595298378933983614114298000880741350618424855028965861930329619462261269994651112266861896630584883581092431090390354633458596611690990999635499563944625720180529318327647519405136188243979680965052005899543797270970540925042201315580510136864931200059448645464256385079735225156720340173280541113382758) (num-test (/ -10969623867482498359 1292477254230352575769754773488799598312602810841892384475535212194939033905139960602724737178675944133847094464739764817257836826367652752931492512753561670732296265459534230949226553571982695924178928914002527460943582374603078611662312521259541641138419845784008028215876048965254023368247445173694441960256131358058174374542730502334351759171930973722361567186133851896057677818979314942434199157003833234473048838906103902832115569853657335216793235394595479328932380393044485884605451918890395812628720641212850763944658735838941829604119213195707479940053016354291972875689927240247563236506479099606571912595) -10969623867482498359/1292477254230352575769754773488799598312602810841892384475535212194939033905139960602724737178675944133847094464739764817257836826367652752931492512753561670732296265459534230949226553571982695924178928914002527460943582374603078611662312521259541641138419845784008028215876048965254023368247445173694441960256131358058174374542730502334351759171930973722361567186133851896057677818979314942434199157003833234473048838906103902832115569853657335216793235394595479328932380393044485884605451918890395812628720641212850763944658735838941829604119213195707479940053016354291972875689927240247563236506479099606571912595) (num-test (/ -3716891004757979686 -19452372993227550502015765258932159656814363741878583541173956168837566077148160901999018823586675966076058615847408138956450751813058209394199427182041779436168298455103717521843644244801542056954603631432685194627158423459586845252167819811850263444712218938833443253125954475476481099092216538126519474183531297423759923656571895377587989169731023397615799830371852298135015608612181670362528239430952907458704415974164085176066242388561893721949244663406941558257051263727439679525692652639731850971185056484335828001005009903973037524233097329857690857731943951449292814500362180170793919266389501882641682782987) 3716891004757979686/19452372993227550502015765258932159656814363741878583541173956168837566077148160901999018823586675966076058615847408138956450751813058209394199427182041779436168298455103717521843644244801542056954603631432685194627158423459586845252167819811850263444712218938833443253125954475476481099092216538126519474183531297423759923656571895377587989169731023397615799830371852298135015608612181670362528239430952907458704415974164085176066242388561893721949244663406941558257051263727439679525692652639731850971185056484335828001005009903973037524233097329857690857731943951449292814500362180170793919266389501882641682782987) (num-test (/ -4863232114852441787 -22963038454503597269981750990033903654256693514059439027985256604978917966584414065892146187253799108250061573972673983350956191446047978392921074610323648301008272837432907303975548030552369880338022067315042332692023645592417869181836251486577977896077712912433381480614752789750181208326525834629219729662085632321271870762094800588296544243340047360684854239747242066367921596241226349790282723168222543448385227922748241223520686047460119733024390425165073367321644498280127168757335614077882325524816799960018589278475564547840614315473357481582710826551932681173443524724802157570101916268510464302946527662720) 4863232114852441787/22963038454503597269981750990033903654256693514059439027985256604978917966584414065892146187253799108250061573972673983350956191446047978392921074610323648301008272837432907303975548030552369880338022067315042332692023645592417869181836251486577977896077712912433381480614752789750181208326525834629219729662085632321271870762094800588296544243340047360684854239747242066367921596241226349790282723168222543448385227922748241223520686047460119733024390425165073367321644498280127168757335614077882325524816799960018589278475564547840614315473357481582710826551932681173443524724802157570101916268510464302946527662720) (num-test (/ -16248276650501285553 -3381199474840825715485713565301777938368574604710714363907009216856320913536015299178065264912798511857598595067318796576494480424838898250138649774858742984769125731728430552285782315111538920026330816414650913188340281906359149109963139438960274321560117812365241840204034925444652058916966934904097509799291744775242863360284348334605170437300543978049053839829106628489146216325576991696936733592366926096500684308845306493636196092408597450926695579897293944488261001228478152650490677071497874746121221519036861983646423005753475340900508665494162949119110128646472783016552527735050067363030838015919512260159) 16248276650501285553/3381199474840825715485713565301777938368574604710714363907009216856320913536015299178065264912798511857598595067318796576494480424838898250138649774858742984769125731728430552285782315111538920026330816414650913188340281906359149109963139438960274321560117812365241840204034925444652058916966934904097509799291744775242863360284348334605170437300543978049053839829106628489146216325576991696936733592366926096500684308845306493636196092408597450926695579897293944488261001228478152650490677071497874746121221519036861983646423005753475340900508665494162949119110128646472783016552527735050067363030838015919512260159) (num-test (/ 18296946401228630959 3302341071702763311560113831030141639804425031433511503765833897787925467295486187687396312611805794369889470239777040624530990622212474466940548049117664906468330871893337410618797113677420975837622378808494314918471282099855916016026079371666730617071364751834080179173620476977670099126230223862266413091012344741482772771219725893630556702028108027870656512750807359335108428687238687397060104669074315031780019301768744978815422943986587389425726602444937024004102212071953113581935989741954695450085391443134273670514145585869912689150728183940456773133212037846765421397201956541430155664614978559762638030787) 494512064898071107/89252461397371981393516590027841665940660135984689500101779294534808796413391518586145846286805562009997012709183163260122459206005742553160555352678855808282927861402522632719426949018308675022638442670499846349147872489185295027460164307342344070731658506806326491329016769648045137814222438482763957110567901209229264128951884483611636667622381298050558284128400198900948876451006451010731354180245251757615676197345101215643660079567205064579073691957971270919029789515458192258971242965998775552705010579544169558662544475293781424031100761728120453327924649671534200578302755582200815017962566988101692919751) (num-test (/ -60488682170925814337492051725122486652 14880088785789146426) -30244341085462907168746025862561243326/7440044392894573213) (num-test (/ 126617729996196635247771282957911941277 -7166506344996883172) -126617729996196635247771282957911941277/7166506344996883172) (num-test (/ -278675896803726074870988122161067771390 7744689831802931490) -27867589680372607487098812216106777139/774468983180293149) (num-test (/ -283351838662873779255871649630248958879 6912311315831153835) -14913254666467041013466928927907839941/363805858727955465) (num-test (/ -9715584046609700027352634666499181378 3368831995960494221) -9715584046609700027352634666499181378/3368831995960494221) (num-test (/ -137493547985106345282009151869389470397 -1916381539906956855) 137493547985106345282009151869389470397/1916381539906956855) (num-test (/ -328662747577960331872949773416436800743 -231069430804205460334599495337085157308) 328662747577960331872949773416436800743/231069430804205460334599495337085157308) (num-test (/ 213595640581249636406536485951630735277 -48492294677143227478357598229530842959) -213595640581249636406536485951630735277/48492294677143227478357598229530842959) (num-test (/ 85922846498729014445816145204889624189 193533957681757355413031965695625196813) 85922846498729014445816145204889624189/193533957681757355413031965695625196813) (num-test (/ 24053342958857142686054803491202486471 196417511107100936775397820630955772553) 24053342958857142686054803491202486471/196417511107100936775397820630955772553) (num-test (/ 102038936612518756467074084117019701214 -111946989731587760700903475996379168167) -102038936612518756467074084117019701214/111946989731587760700903475996379168167) (num-test (/ -3006867214208872584699983438179656913 -234257597822744479264249663225224173340) 3006867214208872584699983438179656913/234257597822744479264249663225224173340) (num-test (/ -279839802710533516603863620922251878907 -3244112647743502769852782626803305310331045534071805654982307107362388474314396636799597033636575215617240554815450017779373048313695795886893032630263219) 279839802710533516603863620922251878907/3244112647743502769852782626803305310331045534071805654982307107362388474314396636799597033636575215617240554815450017779373048313695795886893032630263219) (num-test (/ 123635964546481689465778244982425098404 7701433613491146708866098469269971554817017737111287276993583150548359764165526640986060909954451793171933304569726872785964805121981749276421956645830854) 61817982273240844732889122491212549202/3850716806745573354433049234634985777408508868555643638496791575274179882082763320493030454977225896585966652284863436392982402560990874638210978322915427) (num-test (/ 166158110049010486343321316578688184578 4093720847216792748840371965199135052196058344862447621818024731938681519017878880275303125899149558774718190527651555811733139227128378041055212888819294) 83079055024505243171660658289344092289/2046860423608396374420185982599567526098029172431223810909012365969340759508939440137651562949574779387359095263825777905866569613564189020527606444409647) (num-test (/ 147416259636838312272435267341375281181 -11266711292262839805944890501811605204323255169233519804446548849178247889563130015168799346120099052214488209897402054530713234143622703174309015777885801) -147416259636838312272435267341375281181/11266711292262839805944890501811605204323255169233519804446548849178247889563130015168799346120099052214488209897402054530713234143622703174309015777885801) (num-test (/ 102557200511608632541115941654031896919 3866177549962722728707550488877109233779215384377007088712280650225992470307822792085413087509167847767889824884877044539352696974351192629898363157976511) 102557200511608632541115941654031896919/3866177549962722728707550488877109233779215384377007088712280650225992470307822792085413087509167847767889824884877044539352696974351192629898363157976511) (num-test (/ 47794953079190110032282671989549362415 3802290983508829335098916118339496411537222492645529399519373082799614656011270200284796148989094312601047370399228868583158444769807910513767845541589667) 47794953079190110032282671989549362415/3802290983508829335098916118339496411537222492645529399519373082799614656011270200284796148989094312601047370399228868583158444769807910513767845541589667) (num-test (/ -169956065319483471022234920202991103615 -9934427489865644196610501807375648335352544234206717324511161205173460054921759084767897792996557220898467288533128078406604709773449948420404563411793533441010236017064154469575084055359823982786110746700747423674942932421964955746280671982635899487781780756099620799397239156211815110739544719746684712086075069101799537802834839550142629064374734870047412916259754010150500874430055034366305216104752636211802195447299210332237598443674867760860326529472901775427058078447963316168327741049511844237329137194533000697525539835371015163158135757326482343130221118201740819963770851200676279882978581431999960842565) 33991213063896694204446984040598220723/1986885497973128839322100361475129667070508846841343464902232241034692010984351816953579558599311444179693457706625615681320941954689989684080912682358706688202047203412830893915016811071964796557222149340149484734988586484392991149256134396527179897556356151219924159879447831242363022147908943949336942417215013820359907560566967910028525812874946974009482583251950802030100174886011006873261043220950527242360439089459842066447519688734973552172065305894580355085411615689592663233665548209902368847465827438906600139505107967074203032631627151465296468626044223640348163992754170240135255976595716286399992168513) (num-test (/ -83006311763073652927964071041666508273 13480787677843057038436344704360462056114592749322481662307876594244244638227291805757775026215166740035048814729231681821563443093991755779505400592913963236010573873554317250153995160235771659208137440518282824497744092608999871327127239673370293239927529076145825972430101380272357235582367639159280348164804218713823424182167974242317526959809443701996053548231667727254858428867000011055354779789221097183515832386890638024105232865079002765479933320220378271026425568216748186200736499581088153390350474814123049637951929317200314355414551809067125550551841102097159644340520444983020267926123546444838010089690) -83006311763073652927964071041666508273/13480787677843057038436344704360462056114592749322481662307876594244244638227291805757775026215166740035048814729231681821563443093991755779505400592913963236010573873554317250153995160235771659208137440518282824497744092608999871327127239673370293239927529076145825972430101380272357235582367639159280348164804218713823424182167974242317526959809443701996053548231667727254858428867000011055354779789221097183515832386890638024105232865079002765479933320220378271026425568216748186200736499581088153390350474814123049637951929317200314355414551809067125550551841102097159644340520444983020267926123546444838010089690) (num-test (/ -312626207169475064151212222217866488926 6989069923898656093413456232544365450599471748502878018530391549015151484336014906416216966193568842618920902504390187814247729346977677905224098932673981665869061845335443588666641982676550205160521286690015544764015602751932938178737949961754714143180917985455875095030469699198116593730005119922928175789172042067281849364217595912265452199938281052984802042194034638773435768458457616208103331213440768472281882976004050012769415198321241810008696147179275528426468408383757692656341606162350211696837361434874035354680073309142183699892959618671515841112321607728427286289324836870027735590091451421689980776552) -52104367861579177358535370369644414821/1164844987316442682235576038757394241766578624750479669755065258169191914056002484402702827698928140436486817084065031302374621557829612984204016488778996944311510307555907264777773663779425034193420214448335924127335933791988823029789658326959119023863486330909312515838411616533019432288334186653821362631528673677880308227369599318710908699989713508830800340365672439795572628076409602701350555202240128078713647162667341668794902533053540301668116024529879254737744734730626282109390267693725035282806226905812339225780012218190363949982159936445252640185386934621404547714887472811671289265015241903614996796092) (num-test (/ -151709660794612786408772973806200383563 -26960472721919005254400858042130056790831511338891584787669209989714807518625849812230185079206081782191501696661436514815190623849929065098497737155759771863508038766934134444191240792356114381746781342181881402424707118515655119761011977116554236461222788625158348668147995099157685699761135150772589445239536582228655532345059046596356954495360132444243748421428095867292294626357084961338288369883088525401649234025290736504802104065029036642533076183281468647642956623788270236516849523210698622687255735945678505925047193818483603361307498423724202227256505312543145618362906047473400380196192622607541097732443) 151709660794612786408772973806200383563/26960472721919005254400858042130056790831511338891584787669209989714807518625849812230185079206081782191501696661436514815190623849929065098497737155759771863508038766934134444191240792356114381746781342181881402424707118515655119761011977116554236461222788625158348668147995099157685699761135150772589445239536582228655532345059046596356954495360132444243748421428095867292294626357084961338288369883088525401649234025290736504802104065029036642533076183281468647642956623788270236516849523210698622687255735945678505925047193818483603361307498423724202227256505312543145618362906047473400380196192622607541097732443) (num-test (/ 138834496986391136939574372853300933725 -8052690543272184576133758511645801940246473546142520821850130421981395129853341888352999304040698251945886555605291324954368612109314080471658982022831338507499254609048475429862437003158379101603576571787302167207044118847876475134352180874260998595377014195145760071923429129767580115085764485254455919915567128572731355497418831212259648020550107573824886521471697331410754043280744066090848295906051303624846301488010249980896364883452154860562864255354208802313850527991005497484253401461375477060954782095047043919500670383372218536999834862885439984085848342867301834247551832677237328664699302165347765799113) -15426055220710126326619374761477881525/894743393696909397348195390182866882249608171793613424650014491331266125539260209816999922671188694660654061733921258328263179123257120052406553558092370945277694956560941714429159667017597677955952952420811351911893790983097386126039131208251222066153001577238417785769269903307508901676196053917161768879507458730303483944157647912473294224505567508202765169052410814601194893697860451787872032878450144847205144609778916664544040542605794984506984917261578755812650058665667277498250377940152830784550531343894115991055630042596913170777759429209493331565094260318589092694172425853026369851633255796149751755457) (num-test (/ 276499207940187081393841843387608369874 27347897028734618663428054896349668572244941195143856840032842195489553215406302254043947382368793914074147314353589439281000471813879502242851166670252197853998033813694814376228360691543987661407996785043637351295817024680721181205269262470473172181965930243852520386958529041036476807810647578694133804796395977642274699322030062940721165202488695975750512485574440928370802874677938542169620505668128224812441566912043326338714451629730522324228356364241376445033028898865300103247057378058702233150414643818049655628999871012383236520330575609745427181485617250755214922048672375947942288446974485524776744246517) 8919329288393131657865865915729302254/882190226733374795594453383753215115233707780488511510968801361144824297271171040453030560721573997228198300463019014170354853929479983943317779570008135414645097864957897237942850344888515731013161186614310882299865065312281328425976427821628166844579546136898468399579307388420531509929375728344972058219238579923944345139420324610991005329112538579862919757599175513818412995957352856199020016311875104026207792481033655688345627471926791042717043753685205691775258996737590325911195399292216201069368214316711279213838705516528491500655825019669207328435019911314684352324150721804772331885386273726605701427307) (num-test (/ -8979365591106781219797187096315899769868799444656824967426553299158070014074001230883484015880186603742048949313393413640240595706939311540002219411120389 -1698360947072008877) 1282766513015254459971026728045128538552685634950974995346650471308295716296285890126212002268598086248864135616199059091462942243848473077143174201588627/242622992438858411) (num-test (/ -12831814656788829919185319784994714617782749504716966706877579983082880759985031662545957372565411439648298939198657738497464024214657609856476819270030801 454910754379715) -273017333123166594025219569893504566335803180951424823550586808150699590637979397075445901543944924247836147642524632733988596259886332124605889771702783/9678952220845) (num-test (/ -7834266257250691217409788323211914445703052638619784568844628449769010091330019095736167988675873769434766592786720961949649685040028101508217441360672222 -428418418877192732) 3917133128625345608704894161605957222851526319309892284422314224884505045665009547868083994337936884717383296393360480974824842520014050754108720680336111/214209209438596366) (num-test (/ 5737805823029931079838944835405107564434908634489801628049345331760087020955028323378020396677249341204498685189403657652738071833877470777083253103936452 9588993061977446661) 5737805823029931079838944835405107564434908634489801628049345331760087020955028323378020396677249341204498685189403657652738071833877470777083253103936452/9588993061977446661) (num-test (/ -4001605821592542867351046644170905984672346731784670159062281252096012802838642896466582343641124674682428297533953704119505640938363392225910275838094045 15760991890495426717) -4001605821592542867351046644170905984672346731784670159062281252096012802838642896466582343641124674682428297533953704119505640938363392225910275838094045/15760991890495426717) (num-test (/ 2876630161532936743269451364955814480771395635620140205538288339793482694260173239474830738010159518887660000673207712630507802368373928478641773477534499 -6788234478844960330) -2876630161532936743269451364955814480771395635620140205538288339793482694260173239474830738010159518887660000673207712630507802368373928478641773477534499/6788234478844960330) (num-test (/ 6230070442453337264527950102774203962152836811174649694700041895216739851602598854067104967963392074425258687296947909484969927078206601660837276754799333 190237375887614033974333796608341639595) 6230070442453337264527950102774203962152836811174649694700041895216739851602598854067104967963392074425258687296947909484969927078206601660837276754799333/190237375887614033974333796608341639595) (num-test (/ -12098771374444180013224380531550204930654718468097503123335711776524055419889032578894177605164827523969169377266342179411916625188550162928371789854647472 -41681385674896602840749705069663453185) 12098771374444180013224380531550204930654718468097503123335711776524055419889032578894177605164827523969169377266342179411916625188550162928371789854647472/41681385674896602840749705069663453185) (num-test (/ 13185465843955116174925558412278612918939024395488172088108029202384613698982949554556435640011161663974075894844304583900497170806796813871943782330552768 -155202352609947911537719051033334010254) -6592732921977558087462779206139306459469512197744086044054014601192306849491474777278217820005580831987037947422152291950248585403398406935971891165276384/77601176304973955768859525516667005127) (num-test (/ 12784980722915659825738808684740823452025110516624579136271791852138148426775553817114893299569867520414470532361018804123866264934222335562072872489963044 -249441012384365373362771955533424187237) -12784980722915659825738808684740823452025110516624579136271791852138148426775553817114893299569867520414470532361018804123866264934222335562072872489963044/249441012384365373362771955533424187237) (num-test (/ 8517839393030302736298983538193047531846908718502576675615969705563208303329257882565359266876007571790337440612227785062203468682754778416335180236967433 -23101645464137481399279134347982485126) -8517839393030302736298983538193047531846908718502576675615969705563208303329257882565359266876007571790337440612227785062203468682754778416335180236967433/23101645464137481399279134347982485126) (num-test (/ -10157767522292361462005308817460390811646115952647174687477824271227382383351453540195549992670001314693794150879368708343715654899952822395459036505947192 -25611473771508763579433379623726126173) 10157767522292361462005308817460390811646115952647174687477824271227382383351453540195549992670001314693794150879368708343715654899952822395459036505947192/25611473771508763579433379623726126173) (num-test (/ -8580252632668820290302987230726290672170301642399871646484841866604753910447257372311950907045477729554307803379310475132687855999835211879267570997069974 5347050029330174629945013741349819215851040371727058829687387719215168997632386672310746837193930669173408831178932364105722911104309540550576485594530627) -8580252632668820290302987230726290672170301642399871646484841866604753910447257372311950907045477729554307803379310475132687855999835211879267570997069974/5347050029330174629945013741349819215851040371727058829687387719215168997632386672310746837193930669173408831178932364105722911104309540550576485594530627) (num-test (/ 7706102251141221799524762336156378964168657337573751909064577951085535246905735244239132983582998872001001594454632956803416956154262109939446710205558308 6334400709835247308796432875490978646658012545184955441452799118298109610816693049400832749087993843490999852355789914065232784070007399786089389453289854) 3853051125570610899762381168078189482084328668786875954532288975542767623452867622119566491791499436000500797227316478401708478077131054969723355102779154/3167200354917623654398216437745489323329006272592477720726399559149054805408346524700416374543996921745499926177894957032616392035003699893044694726644927) (num-test (/ 12609622044672092190084693450911157599596799695538449568681964257744962273690941575572590166273187189250007688411096790312605666562908125521094386992971478 -8237858212652788898158635047388584411011830102060269605835391741772914864422465141467281143809161251942948659243584296367296559912373856433388249393853968) -6304811022336046095042346725455578799798399847769224784340982128872481136845470787786295083136593594625003844205548395156302833281454062760547193496485739/4118929106326394449079317523694292205505915051030134802917695870886457432211232570733640571904580625971474329621792148183648279956186928216694124696926984) (num-test (/ -9988492519236282081446302885464711911055350309732728352574982611126604133339499170845224383282665522673248920309221355720665956477799939031063172954469785 -1878204914631111607000020160429571305542722711529281855381736226230242796648854769713662269068364131804626863789957256573308715572826753755672493154125086) 9988492519236282081446302885464711911055350309732728352574982611126604133339499170845224383282665522673248920309221355720665956477799939031063172954469785/1878204914631111607000020160429571305542722711529281855381736226230242796648854769713662269068364131804626863789957256573308715572826753755672493154125086) (num-test (/ -10729942326579120947061030583094707809945059776287551713953926998992375520903658867971835616518813070294302895655369081976222497359056962112544408591462495 -4917625712783289245414023733273041940212797202855299465496072729329693853584860839801663152618595377553772371725021213143455497822882736730281253858119747) 10729942326579120947061030583094707809945059776287551713953926998992375520903658867971835616518813070294302895655369081976222497359056962112544408591462495/4917625712783289245414023733273041940212797202855299465496072729329693853584860839801663152618595377553772371725021213143455497822882736730281253858119747) (num-test (/ 8114113595157517238445304590338354472776364877475201453112450680537221171989478096363668912966343706408770932684807802285529572133696646343108263717309148 5443953102973235688784499815692116502566847594605098596244123647428188581304528525010862185203718640610834003873728718183528722470626702382993497913086105) 8114113595157517238445304590338354472776364877475201453112450680537221171989478096363668912966343706408770932684807802285529572133696646343108263717309148/5443953102973235688784499815692116502566847594605098596244123647428188581304528525010862185203718640610834003873728718183528722470626702382993497913086105) (num-test (/ -7125100205152691887479515774712530950031072786448635736036405923401522078562323494262148946679985384635556474075282302608446439950458673260234175964199684 -23871420315894180764743988478670341498770583257649869670486332228804693253344466615199983955886679924409910043885402198203427975742868174334723967563526738510726448815413356678504144193747696164586135745786501041060322480940451156015256191962506052700295351077719851275026974629635679531161390660244641370183176979934485671396035404817388717005746812037357500295693454623478902942336087760288091719793968445716246099043828787040340339906538864570506773535078524092440112404847904632624419421052178754041718790915772437556681684830937503838434712179830722395832238257078212535157309743054115702650740005055678387806081) 7125100205152691887479515774712530950031072786448635736036405923401522078562323494262148946679985384635556474075282302608446439950458673260234175964199684/23871420315894180764743988478670341498770583257649869670486332228804693253344466615199983955886679924409910043885402198203427975742868174334723967563526738510726448815413356678504144193747696164586135745786501041060322480940451156015256191962506052700295351077719851275026974629635679531161390660244641370183176979934485671396035404817388717005746812037357500295693454623478902942336087760288091719793968445716246099043828787040340339906538864570506773535078524092440112404847904632624419421052178754041718790915772437556681684830937503838434712179830722395832238257078212535157309743054115702650740005055678387806081) (num-test (/ 4801495919363827077158204249631885157347198552733998896638174958434968555935827788499392382851493568264006507028024783408190862186734863708684652212703744 29234959990138609668202089052356468732793041824333219340488007351402997202222578434579705387840772390513345507274006495462445058795870182760749392281528881636623188890883479914921272700981309656920982410970774047916714087713562927554033500521877735827036675598267184309367127514966388636440710253467328441763131873309183205727440365838789320851968108312559316922678357314418486932673434031479515016224407618177089903730349114511598373251388750023508633761000320088841886505077453257141723747388913336375142897897501529451618927178835485127020789481918641637409265186365292847057986276062625965612268181771076051892980) 1200373979840956769289551062407971289336799638183499724159543739608742138983956947124848095712873392066001626757006195852047715546683715927171163053175936/7308739997534652417050522263089117183198260456083304835122001837850749300555644608644926346960193097628336376818501623865611264698967545690187348070382220409155797222720869978730318175245327414230245602742693511979178521928390731888508375130469433956759168899566796077341781878741597159110177563366832110440782968327295801431860091459697330212992027078139829230669589328604621733168358507869878754056101904544272475932587278627899593312847187505877158440250080022210471626269363314285430936847228334093785724474375382362904731794708871281755197370479660409352316296591323211764496569015656491403067045442769012973245) (num-test (/ 10769619761532897875307527770350128978615798426116103116325434914975512103385205123955114305107607195469345895102375220593168903042839441996791318999499708 -7224105715967976893083374742254251507019823877014718307738328810406361200631626366722837314776666720638271529652546975342143108973422364041422652163016078890272393678677152791565494865444430757858556891645947268886646732022748338160528677218733159766121781240328812893374941548395710123982510227501927393735585082736583984561348450061452997663109932611188779299623613963995350679177776686423432406091192517292522853783968685873925548901506191291253596763183277703635837071862492572256145656312023955675669362656148946145528559574994353884313568526553663370513565393821926602014407548325293145102073923450066319746913) -10769619761532897875307527770350128978615798426116103116325434914975512103385205123955114305107607195469345895102375220593168903042839441996791318999499708/7224105715967976893083374742254251507019823877014718307738328810406361200631626366722837314776666720638271529652546975342143108973422364041422652163016078890272393678677152791565494865444430757858556891645947268886646732022748338160528677218733159766121781240328812893374941548395710123982510227501927393735585082736583984561348450061452997663109932611188779299623613963995350679177776686423432406091192517292522853783968685873925548901506191291253596763183277703635837071862492572256145656312023955675669362656148946145528559574994353884313568526553663370513565393821926602014407548325293145102073923450066319746913) (num-test (/ 1505915608160301518246681692927442986955390537144107830770082927276722640395785957392652130911646706470337068266772174699405268120590454296080828168261019 31152879253507543898583880698200027990847289346701738353567402100527465991154555548630544962150902011282973749886327325250084401181379196961322399337408341296727915922288276602390334861175305055229766353672502691855637668618950047400571070157436221479289152631256433294884836727331457389922838951144187501751190662594278336543502171639899940796536926507796271202659224890656712231014450702948847764643603683153113663072089256293587951842007583210791100743318865647555912543508324790181772321217524164822106191538518498016236866957803105254555578252294418243701672226181762763332992886540089416888889135117147250495261) 1505915608160301518246681692927442986955390537144107830770082927276722640395785957392652130911646706470337068266772174699405268120590454296080828168261019/31152879253507543898583880698200027990847289346701738353567402100527465991154555548630544962150902011282973749886327325250084401181379196961322399337408341296727915922288276602390334861175305055229766353672502691855637668618950047400571070157436221479289152631256433294884836727331457389922838951144187501751190662594278336543502171639899940796536926507796271202659224890656712231014450702948847764643603683153113663072089256293587951842007583210791100743318865647555912543508324790181772321217524164822106191538518498016236866957803105254555578252294418243701672226181762763332992886540089416888889135117147250495261) (num-test (/ -4912349668310730778272626761660101328812783790262451913449395750351147048676353891314609774894027305081515542385381430403698808605768281804457186380542764 6582102431028556562269167182029950958541569095123705594954788174046339660437206159173417583841743892857066740116322758515837624700881569925244230209567223461401193316695082415261197843574563450002486582967745135870782254839990479649574452750850133306720341823136645982650022199634379361313745598455049448887744206616434903460504591098363901961758069797933831934878649993183747273660007900662110776570580293994733189753806312784239743585453090900671308673380802381312083077891736513388250097195232616017027333586286786139736783210630705878401429301217589001317082952461701571026008195534878902572422952568763551674434) -2456174834155365389136313380830050664406391895131225956724697875175573524338176945657304887447013652540757771192690715201849404302884140902228593190271382/3291051215514278281134583591014975479270784547561852797477394087023169830218603079586708791920871946428533370058161379257918812350440784962622115104783611730700596658347541207630598921787281725001243291483872567935391127419995239824787226375425066653360170911568322991325011099817189680656872799227524724443872103308217451730252295549181950980879034898966915967439324996591873636830003950331055388285290146997366594876903156392119871792726545450335654336690401190656041538945868256694125048597616308008513666793143393069868391605315352939200714650608794500658541476230850785513004097767439451286211476284381775837217) (num-test (/ -11503235648135220410087372678575470255397243144180272745183844970864347348074104828328211521698012119761674096067066173927209129755062269068090560678650614 -5548338218081690289723998288742945948643693817491921699797822887914665364835947234564530865119623677435878746610856459141463506776423054050179729345956931675338102809929977610828639446535095411122377961067651902947030310564736893080382424590568134091858634304377553326990788802662029347894499019277621467098333287442862683493159356014650672092060912274570436879076161496563079759704321556494898013269338428360856068237785049960484767969682269790642298701577934519452927652996671267126348627432295779183359417597868330923329974640383630473044712419371517153268338860560601603043892503067815822312755611206254762903436) 5751617824067610205043686339287735127698621572090136372591922485432173674037052414164105760849006059880837048033533086963604564877531134534045280339325307/2774169109040845144861999144371472974321846908745960849898911443957332682417973617282265432559811838717939373305428229570731753388211527025089864672978465837669051404964988805414319723267547705561188980533825951473515155282368446540191212295284067045929317152188776663495394401331014673947249509638810733549166643721431341746579678007325336046030456137285218439538080748281539879852160778247449006634669214180428034118892524980242383984841134895321149350788967259726463826498335633563174313716147889591679708798934165461664987320191815236522356209685758576634169430280300801521946251533907911156377805603127381451718) (num-test (/ -22964048032108117904633365483799091488990853392670636861794813863757795874434768543212887316456319246155824842161717179767513360050328383696194174741889496306018655333450647372293193335577883672679165775070112770359697627614883420620410888137853011387271594559450892054491963940112235887802995117234918878648066362268919389271696465517050425727202664230530633207566444357393843669758809938086228366322548799235049875711702216182219182908217345405023677260470015666831191434586902791186444958476491096759363292487221288620810273243009200212776634572092195691654105986099646006756823055390654876878195583529521482548988 10644501761877612307) -22964048032108117904633365483799091488990853392670636861794813863757795874434768543212887316456319246155824842161717179767513360050328383696194174741889496306018655333450647372293193335577883672679165775070112770359697627614883420620410888137853011387271594559450892054491963940112235887802995117234918878648066362268919389271696465517050425727202664230530633207566444357393843669758809938086228366322548799235049875711702216182219182908217345405023677260470015666831191434586902791186444958476491096759363292487221288620810273243009200212776634572092195691654105986099646006756823055390654876878195583529521482548988/10644501761877612307) (num-test (/ -19058897134776675884737764093896349427183484738023061956638485191239529906311503740032626797095131123523175909943402828257449376045336777553758951620699386266853663342003969442142858702229701661125904623724248177901462857013835790939020450746503125344631958534655024089231193396521561965297735217497608287565163852923704017958259400904834287026933197193592591423799328167149965328232560408884408251535373934831244856695227539243433290481951528897142697352526450162440279318507285454432916819060795455956931254810171588139618689138022062041222735056137988435900866680084665165131313435515187611756148824388549448126467 -8326067459929079652) 19058897134776675884737764093896349427183484738023061956638485191239529906311503740032626797095131123523175909943402828257449376045336777553758951620699386266853663342003969442142858702229701661125904623724248177901462857013835790939020450746503125344631958534655024089231193396521561965297735217497608287565163852923704017958259400904834287026933197193592591423799328167149965328232560408884408251535373934831244856695227539243433290481951528897142697352526450162440279318507285454432916819060795455956931254810171588139618689138022062041222735056137988435900866680084665165131313435515187611756148824388549448126467/8326067459929079652) (num-test (/ 25828007361450952719858846443651616751980622231808382804245407702688699228397920589229449608543284896555585501243582045708656531815385828908740757435341854996277769645696261182122648194952548457487178342682313459444433667556195761154944956714756269417591048771194019245925463541886773351873002480266654825771525233808830260734678788520487541379982691221386179066818743751876186761036101255542680066874888848011074569355779905086056095043888696435054884292698783753890317487209955316141370052511469715869816445031102161253514609763532756500340262263800747279044587806090353812452308490155782240390040070679663451429071 -16419739031141199968) -25828007361450952719858846443651616751980622231808382804245407702688699228397920589229449608543284896555585501243582045708656531815385828908740757435341854996277769645696261182122648194952548457487178342682313459444433667556195761154944956714756269417591048771194019245925463541886773351873002480266654825771525233808830260734678788520487541379982691221386179066818743751876186761036101255542680066874888848011074569355779905086056095043888696435054884292698783753890317487209955316141370052511469715869816445031102161253514609763532756500340262263800747279044587806090353812452308490155782240390040070679663451429071/16419739031141199968) (num-test (/ -1669696848499325185991294008037906453080648048592518700324899343297324898656645662186964240087582483813312797482298159224575128489696846451225871663856944749639170892311973606684486632224811435175199158920841554176114937196187087530038509898368755036744105403511353564606301040888877621412514452110348953863172547944175251415725815533087344857665837809749724257466399374547882097484009980477192931829030533366309859182367479867549644502538060694266048652224732348150866071381652452605392696555259221463464108413747443898588713629829490175098280805280460168541344102200890646453100478450456898359263676257882174308268 -3154577849943484396) 417424212124831296497823502009476613270162012148129675081224835824331224664161415546741060021895620953328199370574539806143782122424211612806467915964236187409792723077993401671121658056202858793799789730210388544028734299046771882509627474592188759186026350877838391151575260222219405353128613027587238465793136986043812853931453883271836214416459452437431064366599843636970524371002495119298232957257633341577464795591869966887411125634515173566512163056183087037716517845413113151348174138814805365866027103436860974647178407457372543774570201320115042135336025550222661613275119612614224589815919064470543577067/788644462485871099) (num-test (/ -2215504974719141921873290809898041836016933916943403987778356628123168736190963062169230280020568365292362281642280014010817115943641228422541948070912910166283758843455538187697141038676028739959626556519808411324617157646799936128314485433146912658200236754847332237438334421065771940922444296618134121662770699950019164632463150784605652351782139277998735272280336096528241168196650073301607171613955878761317417480490869592669781417658461696905996344800864447403426286476662235990122025654999230690604488053668524888833992415515434190712628587043474760836969696399229242018051635699746048823240033842587927229964 -11305319675542865070) 1107752487359570960936645404949020918008466958471701993889178314061584368095481531084615140010284182646181140821140007005408557971820614211270974035456455083141879421727769093848570519338014369979813278259904205662308578823399968064157242716573456329100118377423666118719167210532885970461222148309067060831385349975009582316231575392302826175891069638999367636140168048264120584098325036650803585806977939380658708740245434796334890708829230848452998172400432223701713143238331117995061012827499615345302244026834262444416996207757717095356314293521737380418484848199614621009025817849873024411620016921293963614982/5652659837771432535) (num-test (/ 24358677073350645219370308521851912760304925518671532565724702185818845784332554892130070740233218685874351979772556877899278790031132507391155876157108663291716896413773711734271947599485714147026138105714458778787734198938526335256418673319464023475137997251085298903419563039860433435847755093653670989129405749785476487449599232956305952768800154351414655365461746574761818724131185410194605648466196476174400166047788352670171627261342369793028465418799251589432585363577887467959594667618177199696618852093807640490831859585621198048572586882398004957371434677752931134884039120875470266936204172511104679441462 8754800987327220648) 12179338536675322609685154260925956380152462759335766282862351092909422892166277446065035370116609342937175989886278438949639395015566253695577938078554331645858448206886855867135973799742857073513069052857229389393867099469263167628209336659732011737568998625542649451709781519930216717923877546826835494564702874892738243724799616478152976384400077175707327682730873287380909362065592705097302824233098238087200083023894176335085813630671184896514232709399625794716292681788943733979797333809088599848309426046903820245415929792810599024286293441199002478685717338876465567442019560437735133468102086255552339720731/4377400493663610324) (num-test (/ -26302114071841994464108666310942614602208671348774320769941579409198660404735714925432808094014718434192516800374483192192707032773903982752997957629389083405320034044554226640590549491188742685901503166669355807243735533977994184111229208270447279559478659750835531593667003322059717930484363943660175452777363121025595100592911646539549735930625865256846706785601753749996181113742254145758187876411260965175520035400453360390392991183382425735199046574346992179663247011131958270717402007532256308394559029768974932620173103778338779940189812875680687510582798628982957687329572431433891809534332514765287899172737 196971971351558855568201373145365478995) -26302114071841994464108666310942614602208671348774320769941579409198660404735714925432808094014718434192516800374483192192707032773903982752997957629389083405320034044554226640590549491188742685901503166669355807243735533977994184111229208270447279559478659750835531593667003322059717930484363943660175452777363121025595100592911646539549735930625865256846706785601753749996181113742254145758187876411260965175520035400453360390392991183382425735199046574346992179663247011131958270717402007532256308394559029768974932620173103778338779940189812875680687510582798628982957687329572431433891809534332514765287899172737/196971971351558855568201373145365478995) (num-test (/ -25700334917103749626396366612061842558162882395534131493737229591609654899446089376271023701490708870843231350129849819430092002268875830384992877382393956173037794109904701961390126146975281052960293513473777226100954163054292968509501976296424278813632162404905591038465215586347229260479401862039805429711982871702185657527199220459658257385112793877259572278229045135617281858788415643567614198333459934599272409406206213115625226065750113120833933806486512117533453281522448845990642550827848765145774541658722594353290694745164913189694785762218575339370800538946514325662656804799046877175035545715523049884960 56325873113907570153638933263921340484) -6425083729275937406599091653015460639540720598883532873434307397902413724861522344067755925372677217710807837532462454857523000567218957596248219345598489043259448527476175490347531536743820263240073378368444306525238540763573242127375494074106069703408040601226397759616303896586807315119850465509951357427995717925546414381799805114914564346278198469314893069557261283904320464697103910891903549583364983649818102351551553278906306516437528280208483451621628029383363320380612211497660637706962191286443635414680648588322673686291228297423696440554643834842700134736628581415664201199761719293758886428880762471240/14081468278476892538409733315980335121) (num-test (/ -25716495567761925495340309269248196976121711927176026606462843116646034561721958499564011513233986043633061335866265799467020807570689498961190839877265773450484494789052182300993137822542881883769593344810286970036960228835955266304979090841345697560418139960733748874044680214388098802745248923989851173047158103142988835055585349795022662576576434371181693607267864646932929998659458265265400181839509356921460222604661909947838434113964465769102604033848276159366897885013231683417270877512514679528402888899725431524867260144325739317224922955028035417867933390409466302057857579158202739536568407090965929352402 -92089830031261826185903006947297196357) 25716495567761925495340309269248196976121711927176026606462843116646034561721958499564011513233986043633061335866265799467020807570689498961190839877265773450484494789052182300993137822542881883769593344810286970036960228835955266304979090841345697560418139960733748874044680214388098802745248923989851173047158103142988835055585349795022662576576434371181693607267864646932929998659458265265400181839509356921460222604661909947838434113964465769102604033848276159366897885013231683417270877512514679528402888899725431524867260144325739317224922955028035417867933390409466302057857579158202739536568407090965929352402/92089830031261826185903006947297196357) (num-test (/ 6427758281007308443295844679532867042370757542760390680622584758338041709910068192973790897624827722686313216884084305612889554116246627679267186323854642904894988936981064543865794245002470271142875081223308666588659587718561791667575945670118263124267218395749059879636505504607358472659126298770422135028955713148882314050530771750859372048576074912599265823577267962213046012777760882389021047579367276198483178024744924299929585515193595330026399302022065656106472153858484998010254767462854235008343139218888170221421046454280858208068658907389288543063912721882521711363713136166478126504226820360347652405439 80854661163518168674595213426641201760) 6427758281007308443295844679532867042370757542760390680622584758338041709910068192973790897624827722686313216884084305612889554116246627679267186323854642904894988936981064543865794245002470271142875081223308666588659587718561791667575945670118263124267218395749059879636505504607358472659126298770422135028955713148882314050530771750859372048576074912599265823577267962213046012777760882389021047579367276198483178024744924299929585515193595330026399302022065656106472153858484998010254767462854235008343139218888170221421046454280858208068658907389288543063912721882521711363713136166478126504226820360347652405439/80854661163518168674595213426641201760) (num-test (/ 1960728263483597985471065015024594804771170333646104429205729831998416939777820080209106943861368202560376682136488253096512360698625765514606930980274938979705620987031595592685578710084284618125325617453699875318678007463857705931376750632972266553809944621631324385690517092215690694024807784270742388108802858889381036105223858467345514041786882957807868961085072340965930749117411726729713477739990680381647988935514765113077094375924848051541167125595015542791382355149166582367766443782842193396221676952668624805183924877889696428989259842153378327156342464279071638070457876940165186524833987190050817072048 91266493124541431873557009470479491083) 1960728263483597985471065015024594804771170333646104429205729831998416939777820080209106943861368202560376682136488253096512360698625765514606930980274938979705620987031595592685578710084284618125325617453699875318678007463857705931376750632972266553809944621631324385690517092215690694024807784270742388108802858889381036105223858467345514041786882957807868961085072340965930749117411726729713477739990680381647988935514765113077094375924848051541167125595015542791382355149166582367766443782842193396221676952668624805183924877889696428989259842153378327156342464279071638070457876940165186524833987190050817072048/91266493124541431873557009470479491083) (num-test (/ 4941680418946960910262990974014623728051861920391294141439502190044830922127013115391726343950340163023958511659132792063033185693862678433421115681422259770928656196358763089894449447854011668445981430826871764812047994423858851467292757304285634515474652989618200442851239459073981986390515468331839802701176644729973346052528164203299481240263263697394061787580128379398464090163611942724580936445878570184925290925246112514015572149640886198984723311273144361235138411362294735799814160816806773736605477503201836095726740734281001021071803299510239436683913500734680524381145064985356627091311888606290704759943 291575320383555320391938911470370670502) 1647226806315653636754330324671541242683953973463764713813167396681610307375671038463908781316780054341319503886377597354344395231287559477807038560474086590309552065452921029964816482618003889481993810275623921604015998141286283822430919101428544838491550996539400147617079819691327328796838489443946600900392214909991115350842721401099827080087754565798020595860042793132821363387870647574860312148626190061641763641748704171338524049880295399661574437091048120411712803787431578599938053605602257912201825834400612031908913578093667007023934433170079812227971166911560174793715021661785542363770629535430234919981/97191773461185106797312970490123556834) (num-test (/ -17803449239532304707372697093467431202778585961066204978641168716990033159088600623106396534094218402005803618121159982050197012697237961155375180768349707725936023283589475384693590539312637333226292265409814019687105755522332846972859860649558844229320481883408457674560284773922666633054564243260924189551494368660033292970122831009582038986061326503238023206238467592238752824663935316307653075615249537594229930297642710570473007696494702367783692850946455203144153509057520651038068881755863521371187245025834292163874467913915588768778393773565536027848586260129438664753479013894698439967637389690509120223682 -10962227285754340409566802000064407225866105372406170304563353147415988225079632767886653994299800743521362563345682593189107807948342418743229049299449088) 8901724619766152353686348546733715601389292980533102489320584358495016579544300311553198267047109201002901809060579991025098506348618980577687590384174853862968011641794737692346795269656318666613146132704907009843552877761166423486429930324779422114660240941704228837280142386961333316527282121630462094775747184330016646485061415504791019493030663251619011603119233796119376412331967658153826537807624768797114965148821355285236503848247351183891846425473227601572076754528760325519034440877931760685593622512917146081937233956957794384389196886782768013924293130064719332376739506947349219983818694845254560111841/5481113642877170204783401000032203612933052686203085152281676573707994112539816383943326997149900371760681281672841296594553903974171209371614524649724544) (num-test (/ -11349783565099575757929584771389010505157850113880084607145768380886038854233583951229136273631022011781914171912628263930864052254964518914857757025547156428098062812984733912827827545722979442676567330004437902674729872754963478834939047061999292143602525229120558979819117729589695377623970606315287270030693151486803968345724658003068961239204812937084581894755863859944500186226990319892122692007317326534880413455575446314965159569830188583093978564829748603480193166063624130610256395632946002879039047154077629561745862713628266069928068634042545592328263646730943717246953000457159714049930890865576634096206 -5169948998417532948043886408019867395123131165917923418040862036041756675786217242743410895008311710518018466892169868028617239526646914529999134517417939) 11349783565099575757929584771389010505157850113880084607145768380886038854233583951229136273631022011781914171912628263930864052254964518914857757025547156428098062812984733912827827545722979442676567330004437902674729872754963478834939047061999292143602525229120558979819117729589695377623970606315287270030693151486803968345724658003068961239204812937084581894755863859944500186226990319892122692007317326534880413455575446314965159569830188583093978564829748603480193166063624130610256395632946002879039047154077629561745862713628266069928068634042545592328263646730943717246953000457159714049930890865576634096206/5169948998417532948043886408019867395123131165917923418040862036041756675786217242743410895008311710518018466892169868028617239526646914529999134517417939) (num-test (/ -4372008041495429462966226028389793326873997497126815043214338280101332483009650104005998792061125254101227371430911497751865710691604158789733634394053254604723940088324934622768312096370232736965692181452463495731681105253628558429524788376108667441329817524961077744083376843098018692898745743361309486938506049017980865957895278210133305721083115513131884239744064081819033733041876411992332060293539102545847193260167588667810376670587099064558298380310132769718526554738650709745767046942440481512965138461694790645096012018276362849398785863823724642554436182185786302301222529261914437437947741031113015699315 -13213007132248918651858333568248204618745148942720942572088217188768868803339938910599097839075045781852237705726227293430250507070717570662238736211897310) 874401608299085892593245205677958665374799499425363008642867656020266496601930020801199758412225050820245474286182299550373142138320831757946726878810650920944788017664986924553662419274046547393138436290492699146336221050725711685904957675221733488265963504992215548816675368619603738579749148672261897387701209803596173191579055642026661144216623102626376847948812816363806746608375282398466412058707820509169438652033517733562075334117419812911659676062026553943705310947730141949153409388488096302593027692338958129019202403655272569879757172764744928510887236437157260460244505852382887487589548206222603139863/2642601426449783730371666713649640923749029788544188514417643437753773760667987782119819567815009156370447541145245458686050101414143514132447747242379462) (num-test (/ -24003371850945507239307096734506644624830254935119140199726507920301383328662376914775504920527918338079792692943250446679097229950654636321252144129692109999375967030689211646504258922323499994340282315270808545865248969923421472430657741998787024263629527291510416193284540865950122841477102934165296344839654902079279846705581902668360663987722715177845485423354226653585575109653937253382583158263755381721094429734122004436184054214443676096492583897635497699417294183504529284810360226314491839533303380490277211336049582128602304906849999737224506976061216780230350942535246958957024226614847691329767208211525 10686139440491678930358521446524488461285005495304677740436234635584738003880529034339295291091217655777627375148264449580064000634364863951333061091724053) -1263335360576079328384584038658244453938434470269428431564553048436914912034861942882921311606732544109462773312802655088373538418455507174802744427878532105230314054246800612973908364332815789175804332382674133992907840522285340654245144315725632855980501436395285062804449519260532781130373838640278754991560784319962097195030626456229508630932774483044499232808117192293977637350207223862241218855987125353741812091269579180851792327075982952446978099875552510495647062289712067621597906648131149449121230552119853228213135901505384468781578933538131946108485093696334260133434050471422327716570931122619326747975/562428391604825206860974812974973076909737131331825144233486033451828315993712054438910278478485139777769861849908655241056000033387624418491213741669687) (num-test (/ 11114571678097117920369007866358540243142633567044843952020632081573546909920632543585596494530749645890342978505657174505155646987551523455565703297238406590291026899487431109110746657023874064284362499621762851387854720746040865741433394111425240861542892218169985953747711593827913014379823797703717216676877313898809377467394109623799717556800777662963842899812297087284510893865429864819927951428138755600792987191034272014681606301885821862650098620488569288170357746018556395309910262410994899971436293672676949544989196526035130226777567220128838888396668158456237490064462262193759918857287915854681904206680 4808076329737968688023887165061921594706561818755147855784713748545995818001333418509444774306288638038607173052166709335820929501845348060033808100812677) 11114571678097117920369007866358540243142633567044843952020632081573546909920632543585596494530749645890342978505657174505155646987551523455565703297238406590291026899487431109110746657023874064284362499621762851387854720746040865741433394111425240861542892218169985953747711593827913014379823797703717216676877313898809377467394109623799717556800777662963842899812297087284510893865429864819927951428138755600792987191034272014681606301885821862650098620488569288170357746018556395309910262410994899971436293672676949544989196526035130226777567220128838888396668158456237490064462262193759918857287915854681904206680/4808076329737968688023887165061921594706561818755147855784713748545995818001333418509444774306288638038607173052166709335820929501845348060033808100812677) (num-test (/ -27971792815424016824370019866875377333122266892537700816201893161065327053508379094007350664178576160161460501442627646041422270472469587140689725524176629653056006769618104516779694726446739085332330345789012312708713495757968594985567285237456431009983022526625885024663335598317191838389804118084831445251467492693688286258834282078888862754754572546522075833632779922232880101875914894393005204887265821991459415144492487189071888581048779385051174007698853920104709378859053075296413813207007405843448595681090932498329066591349910723578718333092115184652723310842559914379989208301125396793101430807658654849482 3169580893680227534064172567436590084742349042688765883461923377455374714865282199177755353861979892274552092801376364846717140845237173266602633583445110) -4661965469237336137395003311145896222187044482089616802700315526844221175584729849001225110696429360026910083573771274340237045078744931190114954254029438275509334461603017419463282454407789847555388390964835385451452249292994765830927880872909405168330503754437647504110555933052865306398300686347471907541911248782281381043139047013148143792459095424420345972272129987038813350312652482398834200814544303665243235857415414531511981430174796564175195667949808986684118229809842179216068968867834567640574765946848488749721511098558318453929786388848685864108787218473759985729998201383520899465516905134609775808247/528263482280037922344028761239431680790391507114794313910320562909229119144213699862959225643663315379092015466896060807786190140872862211100438930574185) (num-test (/ -138888658164471549506154385143989713534453638138516110941977029 48484067562152384719540184707188444570280914254129306788137384972303743285284814 56428088099244342456240635263153370817851703737803685168591843059886944388583310 6984617762898435035101945891920384937438416626357047934508608980105797822504000 90193136183227859939744547239819443586783276313678017953708293432043879247302040 70539472782976230144489157899475475029273447055080677052149474853222128626227832 2525164589393997980217929709704832829968554364529060039097810436136432713906553063644429644328565051224269893261942396763235990073001625976866246420775436 15614337547041181126817477188043219628044963126229393225781917631975649438502836750353253851523795212263078850399716875892512719059737913422781999218667136371648316387382440793865460028660248325297931269646982047533754121791358966254514009830876592200454797694143082163294323565673200905929297174223061890100210054105027025488322289599106119653451218493916291922340123640475500240519924011764050880374885136181582395113140580448936759383024305870622004464940344826337458060607492042593813585998516868215921180540240201095202617277388950504036371411600204964284568597705251929695275183521036281637399204541958859605054) -138888658164471549506154385143989713534453638138516110941977029/4793535847709521198063287553243915170068914691727215964454867625024011698922303669226389748584276840530192157568469968220857898703102351955898913589325705637953049380748829567692600765708909637920797057370082064005557328769108356548100875674196976079597658854339583183901899349355521527519781721778545444496852540362424465770767219571362842157786846795990148969989617793004579188905882473140017509154008696803103206996067638134383708975696867028865870695941933200225325283190379262695816923376790224594063264297952504481719779782130509306530621779762254864669078635401870023086312919956154224782043667754741333688780367667466505233610011253346902821033707597517691608103391952937194719540981992469020284583499872663129517095879706480339710037976698298522952071766717472040399518290905103777436461474880898550115925718887748413534479076504168236430697214654069473800915087572730747027455509241250627470590715812698745630545585772046458363388764449879417348554556621640336029897762172500880501074103433267444717053504878282494505367980026597725927414511391047010801407870379019921551218005714825277162504166028680939100225793768617321830389705750902850499916610355200000) (num-test (/ 2902267908619179684129536324641634394442732593027015198805855082 4748067699021154152763168285921806700655154833226062437593302484475663167752990 92172802787151156076284963978247829387076983213530315481815585776147505007251090 15808981285029107672090190966349736198141855760941720122983980047623201110025085 60559202289239963744584432021634662330089323842876293477363484160210450706125345 20641717016962556495214267565148984505293698026059157698737040675346468206231142 142380249473014630955299439077662853963947100833592874440361316474000948841420058017600161066408668117933232436922811486348705081331372574460204309908598 22418721268614574393232189860262616514600143215945007038687873335656746730488694050883006164427390756358558140145027011322151188565843290717535647848841274550496431839061217253488169143292339455650565906288959125935798633464526818546688779845699340483771625364583343140648892889571715648295855169294054985996834093294240640072029711789359793649773566295329912082241637482772608479106201840565936084243727069954911883243252762742415647868355726139789907900798435783365130277592703989608678774745914668128791639635886550753850811717805962562157686110637810320436812644047534536168343578232389700410352900247092236175044) 1451133954309589842064768162320817197221366296513507599402927541/13803211377640454778526029288269623376813125655593684775595099045285713415153039020789267800416616529908688645478733023490751981264976732618374046330204398361829051480928696426688037404239513603403603849882719851670264413777889524531938606364925013854252374108222701436535488401321603495905123597139234414735397259257280679663147039651553472142280954446675036289021783142392760217244908768132158498744301278889276778209560846418263599491357632762902447742083022806085077053406738681250354036208472026046315736408632370478801849290705001622808552373129971427533249307210975612625050706661691322027927380443494854794852235813844542319971019369687589916047377092369702778251658652143114091304960406840026816351348391618676357634544120732441610431417230403811846208113160343697557236265319994702483700922393762500190362776377442551539417224595247790865885105594005740401824824367904020732469833438717527758468635665777261969819260766044978137909489986407113029460354144391595512642835261443393260585888868936164331461486646676578398836326366036777321522851855085808626766493197635871100152761464712744017549919220291986785134521319127277292845352756807452050073157340000) (num-test (/ 7798204144688205291220879078360728451593323170355809361079096742 35808393784851478122520372074317359817820799318259895240196875729073154197251420 58532175726063855694248618287185551673975962776708803423334853085996022345828434 97834368697888769536063057370864051207348099191057106781292664602519775900739777 92489021460656714290092899983209031746574776013841975324837145038810562509209529 71083733375588666647468985607775761710974844539643116636307037921671845148256816 6123989271760127932230015643359630675168106436173654465119508990415235040641894537960236511442249258231302028977221206744158863083898145166446430168108 -27418900206398855942064397259705713102524342707255992250395147550519659429645343464288092288218160406382406024735131578979728501208163782063519839258876833755387025755815673514708453862847139552613587001235204464673999898312854941659541050445981594990466469147364579547089805525464252876345032296745312923488525701877655352034887018931755379078328147999631937419977103372927428613463482328465834563846802083044643719319690088670748858904291298575733560600669924511028715689681303059001186388754140003746463568171428267337107394361025465082282061651196456268663181772211292647101192148287507051053367729008997838464209) -3899102072344102645610439539180364225796661585177904680539548371/113184205287561573324139833190653102440730360395399197973956984769580868365256138025034414373155098575475566747215877030265786675432252675717351889433714136838615056208470421665419618669892136317438270826178251174708190860235979949204785938786562420189510825909814566675745650194525647207897976611434325225523578368855952217879373499055292850828774005130267218801086474623429504045290678320168493275019256514768273116059350700654655821674309331585233552793659038912697151359657915391954687630783641745610431060563252789714638916120291482852533638921356624929690158752601417722733222880768367060672103351737811624242610815140332559619520810810999145535251960674284283045907801934328911198563750515779896457101601178888594882087326241517566336011980952110586199881600553269825310575512911473547251704677890770772166895623118832621335417348044312911888377718725944255218219811801447500167145561774582342171995333086224230231746597452848775656030037837271428187450747141983599129861631612369300880722326218963779650411119279310045263996988089484063433088077868691314162108392639864773907107325220582413508233901954483499166402135445110435112499264825479433389003494762240) (num-test (/ 6291885367078853457481986049409245691302078375827782321496819120 20959289231548357352292073342856567687394126070322865796282035211176720583560298 24366038587110130209541647226271577368736240640393242419005751016119649778306566 40118119174220166901790237425673316895032570534639145502274313654443256239236466 73598137358602854818844747625643480865061277528564461120022408463105339470504117 36695182446520138181079917512512743290981469731336486456411609014364293489978544 8671667981598505073194269824535189054936442262459158402875147736469644925300845122881093216273840895555488593258562684601176239455526568314028830532770 15920064019095473156324398162334173238735268739049399738654357508344572552411935473846021991360836375685872129737682603096450566258725052013769725919038955505690389573813769125933987978360857342250911865713011888064725725934341157729878064563080803955584985269499994186472079783942404183377695242296289152788154908185130552013951432753148997632323578507137074131845177376689609114975253308906745794984371839952312988353950198030866538756253618535421214253194954603293145507537939731320546686208032528588232652963255550963088571344119439249328480867640436815434047309164687808223851012490130534705427647158409623238123) 1439421788255379275215959765325419043929720157723371200401/1747562187028503746686299553853635643553063923188506902759251937250022196751705340155682655202720363192751787186892107863159676381018035068965958466119538181810433273947829904580526582292369320932134048728374142501965682147541817431447933591106030690334465450755701191781243754499216697336293783127396687916725975251100500896467549458036395977769801208905203001097425041200299917628353220804629035768571072498715030261324138691471497255335498185741379289492513543474304524261634247519034231348033379344777678679950561777846684978640375273167561174451700942154388980887510088060818147834369595669846115248027925007288445161871535514130090907585140894883683709507099726386549038354860875469377442908932714711235823032704493155679240378374325069782368108779247450762222838197717507164088182062062215767468125843278459189085290703729281279344184417197883359351058003644499215541300350121854220342250451978930421772367851329849662028719768708399155817754711362398236471946313773603716759409265530444582884661320404389499624411965234669344882203618613097197387901166904575791500958722726774956950592290330175936039556139052663816485140080963740296685158607671768592) (num-test (/ 7377598052472799909620353419322603137723415431070641423056433630 50990728761110292768803869421408199244526424730838143228662194914314857136430737 89434155113971221138805303763480423496687322824531744020762041598590716339098287 91343386111124700155689622654961840380754244946720984970313893805578518003516073 5641075230099727784981579696383316732450130418277879081291954534985607255267932 91040802121912074401640073226003257602385910518707524375098380810792151468159323 59272268188012925764499414539835790113036863511169317924034366016920114706179376837448098952655862721652129333873020625135398431500899131874782270590048 26690053756452308398721390096804652429111408747235998849320348549870126230712525274708597346508961935323823048352116439255386668122483555236157562141222434006899926132549352821247340442387991613448730451171206857242290791156220288682675982609964518905569737166444127835826079348146626921864776959482079234994631361894786436656768739968380067890165160954836874044821979903056957225885565092422439358816023307475581832942250031121721325840673134241504501661692722633100336840768527354183989544434614842654682324213774503456414914613412547380720171088896588158750436205804689590730033393056191028424154915201435563063992) 3688799026236399954810176709661301568861707715535320711528216815/169215718032454146095901737002485678790901914179482864125777331106759302744215797822810809511498045518338288799757661725047129775976254373463314416017128993811694804386237923340900604770406784566473173755998386770282409830097844352035251738093305402541509197084964701114515390028814839744480965823142680384744649624767291550851759670297818996073873968006960956353033659153219390871979066743795530136868490210455800714335529013059123604101460242870160400211866883478263106349349114199154533363251799944090298252763172390952446660627602934622584400932001701907172000401485323481964448487312714644861543740014645407417493588261100128985848137181719614326345024112347151970444057551896842474702539258687521054961314443551837168457190568932765925484427579811571491887599619302241390226818415165012748654917331557679228501007751078584244340346651276906088856205294333241792044902850102153793417101337667969641035858108457362954650972654353600494166650067557014544136240962457086782865870886529792004619668808741311540795514394731398977642092124679638585188974746423756335151669217754388004341907440529525288302872368689364872785975840444000802518095138062596107983803117056) (num-test (/ -239344771695510351349291992975349015183687755312261264640655565 59880027487583466136533364102518649070390160795136023810470091681171428955831193 48344457085007359228086666145324485903333773379391455489556219681156342646858065 96824393663737121700189215323825147927318524415097221824671795011444303522438090 73240728471954064253765051525185557601431281145369716902120469411886093226662465 53476482728312567840603110355495270554470432250981685279567813448298175801364992 2468459436652089730331798017030410049989399340882712030505584719342958436741536069714790640546086933185494149096286590992747248311590137695839482679011866 -20583944357058654336975302336113341974001469085102805363209530168831840401111182124827636905521584509677325966689931599005216123375088335255672290604710305325984961984791919524676460851699284525672773368217606895110240237523696098521003978238685169880199868729577660354717875890521074505342309726366304528678619465048659607726264456481345739318939431629704180230985397408136331466856633265343276511285483458860216756106887559724757372775728879136089013590836231272961497930729470443491032308329051560641396901204040829291495325588896591482909336032903587307512310970849256645908744180630660878534263566681640143534823) 15956318113034023423286132865023267678912517020817417642710371/3718709813392127924163278362562751486187605430152002432053108623099406465632705761508167478249438322470295467114170871555665890539409511492475240415534629792791729596612426725326976353265532166735941330128195885206087665506220364347120981130748862937276841801804372097254983242962029582754709606117339082763083905960784323141929645331591164015455383939302728076410053178677168172481507115685831178503426055335630689722163467637005123748113214310366231893390818795405612007113310547901224920768646006621130651182788173442625298859454337696280614462941186626306295514630883052819172301830539345633711941340491653447613466053205836875456839023743314390098829184111583809697328393569588632000669468187410368485286035179259523632217543401146996259011916302393091677624838641658623073752023082344005134299104409908004250830639232078441523519412192782367689826532215394196055149255026188549091956300108740792221660678858924234682223183500313556198187095251404633698868186071148295957994257417049500872570631774233307260384902571112475241073598945295745287525486108978093728296107260155093397986671349139935376427469718767763295900745932105722655724205000829205748307261900800) (num-test (/ 7013212896988366906/12397903473277899947 818833870013215068/2125577647443895255) 7453564285301859120853045020886215515/5075911640537211768265804260348400698) (num-test (/ -15781329068048599432/14942574238341613337 4388772934226358350/2640112802717985697) -20832244458230302534551181278529162052/32789782692450857054331267544650656975) (num-test (/ -9015230453321124271/17425619133302730035 -10422000746814766599/14972344381173680534) 134979135022768387806775446187867640714/181609815620990738305316999098032100965) (num-test (/ -14741075237791868512/12448692140900938227 -1090381863721238817/1060836378253796023) 15637868866825840780217685066084527776/13573828137487503515304766902031557459) (num-test (/ -7371815071140740177/4722722556038701367 3872455829192658988/994203944294825175) -7329087620340161131469364260313555975/18288534491791723206480607737200436596) (num-test (/ -9856364379969390509/7988230468709836259 -7208901117187058135/7430860779232874136) 1093153305924514768551484985555671272/859497963436269188803272225817371895) (num-test (/ -16740689272507881147/56924866550406451570641164619431212169 -14712532880452686095/143481612520580129383584255576273223983) 2401981091525408257128502717450566513166280001357873948501/837508970838236191644285394369194561392491093277901090055) (num-test (/ 1874027699956565000/65960003455647360668413772300355814843 -172394881832672950/2006879686300828197846469567507151887) -75218962452157875130617756878839223573611935155763100/227423340028380523596387094039260091189651621559491937) (num-test (/ 851521912886492079/58839621451933520132430725102159653727 -5525838657334730480/268863138354222710211869290179088409033) -228942853876053297959532391872114722003932597144466549607/325138254802036127673497464266072288930584674567672498960) (num-test (/ 2130823024472312937/30463932363736038600114358208342163020 413938864244113775/131673792970459944919771618253738144891) 280573549781056638388629087822719475587456644826399754867/12610205563054396144647765193069861697742251186477600500) (num-test (/ 17234694073181371137/253506951459931119968572673772742357160 8407879684613951161/42697666588937447817581914537644794355) 147176244259806896721181660841298454615950364713859506327/426291189417673978158704851675227114861497071554451732552) (num-test (/ 14739301038477826821/4801125431810347467140397350459581435 -1752125940488995048/127905197451270157484305628763539243969) -1885233209620217720514367144506571751170505057476450692549/8412176412616337518572109406238500578932979745867733880) (num-test (/ 9194848570227974720/45448499872046683203864930109076126035374684748838016011669264943000310475483 -4572473918523931944/28941042619577200519536336906341131911598596429670188136734086846500956354149) -33263563043940787786171015409141766453199063320923723716765930467953050399983260590187417389160/25976510037621464639740779963549572814837984766154635046133743883024710122710674726552171566119) (num-test (/ -2662376868940711929/2674240208804755702377222409224408783678596883960539287029565653749020338064 -5046618244273151929/26826013625152995057141957222948811537350409769204161465077735924332004069058) 35710479080747854012875521001477955195584454274704368888444222736697434540936425667291700196441/6747934713661461716612153292457811722283965560031580498434684530869001786777260513409206862728) (num-test (/ 646980248518054663/28444849537262537816809349756569888989442483441699293309597267649158853799707 -10174938507557455325/16470612178414296088079890015341965945714023680627341561729034923083435428747) -10656160760434978971303471120231114671340660575734505071429575384684610862775940451177787597261/289424594898370460244167952344748286246980979584479610186308309369583658143095854438992150589775) (num-test (/ 1268676597518744714/6024937921458004492480888468749320142603908196076058575752452561172018490893 17823595902143962912/85935047374548136904062562443188289405155329832270007415035044821925251080203) 18170630585125644385503771892175817370913744757273904248648000044618805359154885235028182716157/17897676474595109057512045856227678061218241143085827332930191066967148125532813505892133626736) (num-test (/ -3035741006152688190/58890268425224581569217175195410848521985674465189565646495474378301884202047 -4870935665435665519/47998868922405332801456101880162843269583282603435159879276723163289928325531) 145712134636693761356266465698326002831562744975420904782663360472436650653549187025441059178890/286850708819506259357726384810790881448875152111132928069815447961129371272624891025817707117393) (num-test (/ -4420263280205408439/38682162086456801604593696710774835436326970692840048042132553053971380151628 -758651402628235427/1755534012040040367913026343944696058732638465867705260088080517539506722166) 3879961265286134914514096239640695384126081133972137242327715997675029567458817030555062379437/14673138261791601182714628661554161812345431143865809776872034934342213839184709418896670662578) (num-test (/ -312487180249669742743295380499853180353/9828632991038934281 -86131955660561774942466932680637336739/10268762916730341592) 3208856768501438660232746468300370677374054716853273141976/846559380988100144557815474234956961169507773676687849659) (num-test (/ 105376075880566042097567073713047434893/11411565636673693365 -220737802783327232867818580441304577024/5817406274606660773) -613015445021032499619145665530563205764250055719854552289/2518963924957071797477174332253152325843619212749200245760) (num-test (/ -311533429150518992652072799089375050497/4403073054828470603 -320230219907951760832723580313293021909/1370493254961533625) 426954463345823097468320537904981772054351338526938461625/1409997052618498081840381197699863669488222338862641441127) (num-test (/ 305676222727436457375950609916137360009/2001517485431820526 324338803123828318219640932070020543912/11123178903397935211) 3400091311912189654145957985944153094384781502787164376899/649169785656371151621897383467144093766684841422885937712) (num-test (/ 8845112929712368402815105446090151026/8124751572615311799 -107609110538267962880281203537194473336/8714443449141779053) -38540118213625599008519681983731393728094066419546629189/437148645036763776481446937412401903340367189496615845732) (num-test (/ 152921217721894690043853278309581658066/11705615305395353865 184187448038871874764725486848823516773/4171619104693691390) 127585814672335876029018138907883882524550368713261650348/431205482165106014329333719781838993214328411764819575529) (num-test (/ 16414254293541341780725162107696242521/155838132618727968561620486302365154071 323320173010032367023620851618405869489/49801924105617352177018959505967933104) 817461446577249670665800625691379410535771218196808189195363718417488315184/50385611999847495177988476252475899813264458225659097815552272081452203039719) (num-test (/ -188149667625860588508273820953820709614/21438745582767797684161462130971215025 128458309657689922121539794960212789849/134174286369366827879740776978166655691) -25244847384333405496229128525982900130397411994350175944375943735942831513274/2753985018743617742875555653653797261370358442640799457019039857068516281225) (num-test (/ 1218460641064115152742257147372113443/1773382194117714970762642066492794929 -105212349758139121832338365854603836112/35045896682356785176328011712384921341) -42702045738251194875426595475683618047253961691478453648029952948483687063/186581707662369193907913729212042024270164277319717456729276609131940676048) (num-test (/ 1467722271775252460214852151179762687/1747611358981474614363356529179985509 25495740211005247928144692929451604259/29615224810946461612486375021101910565) 14488975012885720730598332784736375353299643425098519766594278819666029385/14852215066131169889445443721709162270198753408805825268529301698140894277) (num-test (/ 6278399735526726207674375684072448068/13890681759576280617381650633747782321 -112063146811220963294237186476216238443/46495820670393894026441353693945662660) -291919348200099113895651901892723884699250237261456280525601785996696740880/1556633509331345870779770006255469001211806559199158615405344674499795966203) (num-test (/ 248406099260780863433196593538936526373/315762135750029127758352280023694126018 -24578051912523675039725210046249323571/3033769619337997374435389027823294736) -376803438597807975522050212312559316811899647514236724224019181136008036264/3880409082236781853269738100403484871805889674074731389226471480469265885139) (num-test (/ -305871752543087256004326578375555909668/80170799467978436032303243749692785696371676780847080230403479135749775915991 -208573266832391890136462745593008906685/96016271562601269514856687672805175650907293023094157826925793080307407361434) 29368665255505841438632782694581946057561031972462112644657516768267440383833513431444679871238206541553985530943912/16721485549600848123731461311227384049611071114404954309505697259277905994635125654414916826332204568970567318299835) (num-test (/ -171651126582338417143004525987733942986/48126955023093310081685702171788275811688444573315712039582092051531229683107 32570134112026732491936310765048378699/18584159151613423191553551933672204731023422884196280183931777685641069715348) -3189991854959918631828923606391779823799241149346421336570141741355492000935500642040047513113849334779592681149128/1567501379505627719887579027549074087653888429037997616626567546431482074522690424133509833932668944596793898937793) (num-test (/ -31304786393644787215292629624842492472/10539846271603297974613179098685212701091372728582260780054561526149580513583 43496364289252206338797704034889660065/966865502932307025364733802774045297740949567802356684866342045679773834966) -30267518040679809082934454680954168768135550720881039440573156734314284479043791824457029301083428211405425375952/458444992982373700837242411005687390212275114474481688646320865335043970683786989531994936463047685893258985162895) (num-test (/ 124366625369659591476708994326732418029/107684759001536292829359995221778346870065030877016948429894748600664800488759 -90949754058598173499067700725927605729/79727020098830307921496202496061295138733611655702270828135321391380898414003) -9915380440470549523296226431396644117384598256053664887332801972488440466568616812942647849957495261151611303260087/9793902347049141646079571573977765974008832433473016883117384010293158932212528563016145547341801740792289848500311) (num-test (/ 26792084925762094333829722201654015569/6815899891200140342329613369008754659665480100088941978786466272502677117648 179968988142253715757129058636648023126/97033837835570527321466682927970125702018459951415339098532052222053589117353) 866579607987744230609336186273867662887766686833260209925103055244528379635362816895584608387230956963010276689619/408883535566062149539621907018509777969515872715944952500700527207173412646715462423653890585029605025758308909216) (num-test (/ 320794852821756057819990044473359503428/42380074203350930293358543616207018031675687905746455222111844144668904183229 -11813439835454851567822019323728871339/51852159737956631156972450987013128151750117741949546305537111598356497409240) -5544635317209327550045071802859986261979158492907374734760649234578367469399038563605323839330681533705071632958240/166884818941132804535892580774781586387104334774784737031184369589400544303785250219152004898392301479219940857877) (num-test (/ 63160395612932962868082774785156358041658469338654564454114468396132462549944/5671929772244157797 19541045450680948617094710246839287171374470593288265457341382295544977156173/10827756125123268218) 227961786821047895774887365257727015864174017882302289602409601101722343657899277052494444293264/36945145824164509580938949252327087600266044162541122809277442696583642758457532273140841543627) (num-test (/ 31389399613343712511677734270541516183531975055644318154870016415582858008412/11320913214023484367 -95931706646769408081251897664360951854776052790951374912970042200868629796051/14301831604104230477) -149641969141325406602881756591195860220337618158488775091717625369334526143115090325362684257508/362011508473745439254610688691597507367516106821889963803421575701854031622412859179610532278239) (num-test (/ -50845041077039215658764589763556935122444212169574762080162289087527164772395/482986173890811026 -51342299909113507561385579724776151277474630060658338514843664853027455595538/3864573616937705869) 196494404298439669659681446421686066898686292162412914850963937042669022612531239234324840686255/24797620991857267698917294149872672843409173617406514673128342148521539559341861421304646801988) (num-test (/ 76283614020376921713154299810619585257752996149145061806263596894412414185408/337890011287912517039286436540240936661 70530558237421368381589233382700323659036925075366138096846582768833233488577/12121510300837787759729092713205686989) 924672613133132744522463879340347327755455994321131972145048214329608890428265966744607561005512244129921459256512/23831571118985077324412202325831974453532679575894228007993082738742295289254461850021038245882565939546151124021397) (num-test (/ 13518475961402756750057330871273933874583566313800024119371308450919239424622/71146816100737230880567880716110051085 -11914742388051168959634071864657967837347162591767656949770878950409478930980/166466796775669753065110807850377519909) -1125188695291804746273664719520877594103080002716204716437885631737502681157239448228517736957154781558316254899699/423847992785167635691798025732868758201476408654527740579259436528169254792708107390082891890404030666159494556650) (num-test (/ -53624051286117226406327700847140806598091981633622544805551583455315188018537/149060170957501829683988930330276188371 -49540630291338976658332195799658601133012561780540500265134312414843218811481/313014990314092319823049811442768272842) 16785131893926373429171158665038393627227592608630727377590747943991201054188961463248027101037470630205119769672154/7384534820569381535972144752572408048556227885764547207137140227958732266609348654686668662110083737942669493487451) (num-test (/ 2634758410586745842739353561704344884865889793873131750193619887157306355755/83106075320614705363810122092414199463231740446254118542567688658288107572919 10787649314660479714744029413883607304719873485501736976813666398631455642569/2439964488756696481271244145022481444549967702052558191280867337292105066432) 2142905652761565172685487282499186838096673751132490328620490049367034561455889328384026705096013173825469773464105722689198047146574263705663366838720/298839732158850477765824602476778580028064205733214070073086531571837859351705342746223206218407306637658483098569582239416197836311325170250187389329637) (num-test (/ -1907320079310938642409293211056905401889419041722087613680756850005726714712/10387378553621846874105702088597026076825105075730032753153301604042569998683 113647247724474559442709588703965365251731833799417671287796250968092484717057/58756890421232187224353930678527831208703723187770044891160428018937233424397) -37356065632762902117955690133395145368676268194116097031480521390942668514422835237280325034441435052929702455487858500299401976652159912902024146542888/393498994563785425899168694480259206994308562177080555315323154941891277193612821825931878224565302417504072329241812530787363937691786269618438039211977) (num-test (/ -54987418627898620923060954379316763081930842855917193391807940070173620336071/17370345837184638879794373707261631548922174314274224219546763452439685451597 107349939397731511365417710412808670916754334908520065561311453951414109180973/7800708635318451621630266369706695626474649690647985662113853436261704078874) -428940831324519456770429889832838610542119304716244392653623661175655561457214418178921042544524225772650432309479656622489393939407340321261255371264054/1864705572939408818246392762570376592749103793151936455808919833872532407312841098160841844995663367019074328670998871082130543124576872890789577304863881) (test (= -98781233389595723930250385525631360344437602649022271391716773162526352115087074898920261954897888235939429993829738630297052776667061779065100945771127020439712527398509771853491319737304616607041615012797134365574007368603232768089410097730646360760856052946465578073788924743642391638455649511108051053789425902013657106523269224045822294981391380222050223141347787674321888089837786284947870569165079491411110074602544203383038299901291952931113248943344436935596614205784436844912243069019367149526328612664067719765890897558075277707055756274228634652905751880612235340874976952880431555921814590049070979276358637989837532124647692152520447680373275200239544449293834424643702763974403094033892112967196087310232853165951285609426599617479356206218697586025251765476179158153123631158173662488102357611674821528467825910806391548770908013608889792001203039243914696463472490444573930050190716726220002151679336252008777326482398042427845860796285369622627679324605214987983884122808994422164327311297556122943400093231935477754959547620500784989043704825777186301417894825200797719289692636286337716705491307686644214213732116277102140558505945554566856673724837541141206267647285222293953181717113434757149921850120377706206012113994795124049471433490016083401216757825264766474891405185591236321448744678896448941259668731597494947127423662646933419809756274038044752395708014998820826196523041220918922611359697502638594907608648168849193813197790291360087857093790119162389573209640804111261616771827989939551840471235079945175327536638365874717775169210186608268924244639016270610098894971732892267642318266405837012482726627199088381027028630711279130575230815976484191675172279903609489448225149181063260231957171204855841611039996959582465138269247794842445177715476581512709861409446684911276158067098438009067149531119008707418601627426255891/2063950098473886055933596136103014753954685977787179797499441692283103642150668140884348149132839387663291870239435604463778573480782766958396423322880804442523056530013282118705429274303746421980903580754656364533869319744640130831962767797772323836293079599182477171562218297208495122660799328579852852969560730744211066545295945803939271680397511478811389399527913043145952054883289558914237172406636283114284363301999238526952309439259354223729114988806937903509692118585280437646676248013406270664905997291670857985754768850507766359973207600149782819306010561088246502918148146264806947375101624011387317921439210509902170092173796154464078297852707797984007992277904626058467143192149921546030028316990855470478894515952884526783686210401408859364838148201339959570732480920969000913791571631154267939054105878236201498477027265774680071188764947522112650857013491135901945605796776829525789886482760578142306057177990048751864852763036720112071475134369179525117161001517868525821398753039187062869247457336940152614866298628205010037695017885878296140891234142925514925051385440766473260338168038302226808098439763889250948602137806546736025439919604390464712793474019469457135856879584745805794574609707742445431851999335443724488636749987837445626810087003490329257105472274738811579817454656532496370562155449815456374456838912258383282154811001588175608617475540639254689723629881619252699580383612847920348111900440075645703960104081690968807839189109040568288972353424306876947127635585164905071821419089229871978994388197349499565628906992171901547121903117815637249359328193980583892566359962066242217169190169986105579733710057404319381685578470983838597020624234209884597110721892707818651210378187525863009879314177842634871978427592746452643603586344401223449546482306838947819060455178762434166799996220143825677025686435609179225302671777326568324855229172912876656233006785717920665743720753617646617017219230313226844735567400507490772935145894670445831971526014183234960075574401616682479457962912905141754252265169682318523572680657053374002911007741991220001444440319448034755483178790032581428679303588017268970 0) #f) (num-test (/ 10105597264942543888.0 14352488138967388642.0) 5052798632471271944/7176244069483694321) (num-test (/ -17631701977702695093.0 3931860028646338313.0) -17631701977702695093/3931860028646338313) (num-test (/ -1606495881715082381.0 16324360910828438638.0) -1606495881715082381/16324360910828438638) (num-test (/ -7960193178071300653.0 -10280747961248435844.0) 7960193178071300653/10280747961248435844) (num-test (/ -11544909483975853384.0 -16041992360613233027.0) 11544909483975853384/16041992360613233027) (num-test (/ -5758820541298901548.0 -2596462557714095861.0) 5758820541298901548/2596462557714095861) (num-test (/ -13056342734667572546.0 46502284983183419157350605242474199851.0) -13056342734667572546/46502284983183419157350605242474199851) (num-test (/ 12668118634717482325.0 -338544675918656078399121171905238525746.0) -12668118634717482325/338544675918656078399121171905238525746) (num-test (/ -16738429327795346815.0 164053836541028518093058940786011794219.0) -16738429327795346815/164053836541028518093058940786011794219) (num-test (/ -9884600460121235549.0 -53914696297933680001835530599748561584.0) 9884600460121235549/53914696297933680001835530599748561584) (num-test (/ 6753521264659576004.0 71759828079371803409570464915096122874.0) 3376760632329788002/35879914039685901704785232457548061437) (num-test (/ -6072478784520825268.0 83641961138289700975241455431547940418.0) -3036239392260412634/41820980569144850487620727715773970209) (num-test (/ -6708950756971973620.0 -9847903810677323447803434015107261150885944735136350527205856921771320298384705376646797569973415403097847060539915279223391112430240736564839483430569706.0) 3354475378485986810/4923951905338661723901717007553630575442972367568175263602928460885660149192352688323398784986707701548923530269957639611695556215120368282419741715284853) (num-test (/ 11263779860755455072.0 2292311486393743282743453705144070351222990311578446825826935237655927864700827857707370158936582804478427014131790879562565658386819339761919809732496450.0) 1877296643459242512/382051914398957213790575617524011725203831718596407804304489206275987977450137976284561693156097134079737835688631813260427609731136556626986634955416075) (num-test (/ 9956488981426387585.0 -12351244248621474338537656633137999145154500022264356186225225426288301330225259889671144104952158102155582320296061124840400655528634050137479515338944145.0) -1991297796285277517/2470248849724294867707531326627599829030900004452871237245045085257660266045051977934228820990431620431116464059212224968080131105726810027495903067788829) (num-test (/ -14875992781716065391.0 4906952781757522095285156014969507916562921709689447567404076064849249737893410245743456952512717420040816186768213920574809530298070437840356629617118643.0) -2125141825959437913/700993254536788870755022287852786845223274529955635366772010866407035676841915749391922421787531060005830883824030560082115647185438633977193804231016949) (num-test (/ 16043178952268979636.0 -4962728781666935768923030490263743715131420507991284894489828489607808897271220927863958149140648859077934323268424257800724618076505149638049461104621679.0) -5347726317422993212/1654242927222311922974343496754581238377140169330428298163276163202602965757073642621319383046882953025978107756141419266908206025501716546016487034873893) (num-test (/ -14889985628902581941.0 3075736124701105220602924325296812116294816310089906623707854625135862902005059305428034753787024827094954645083406870532379125275086885405969947540175361.0) -14889985628902581941/3075736124701105220602924325296812116294816310089906623707854625135862902005059305428034753787024827094954645083406870532379125275086885405969947540175361) (num-test (/ -1719613957783789857.0 19860562547348050982501313785551054055826630539673708970554435103060535649825139319625648954889488501680865494719253019921780044205805557658109807483499994523398090829033362953135186523580359552555144614353929273831853529446536288544481045105104526669277307473478898498061888931858821517694257595658138564305517447595298378933983614114298000880741350618424855028965861930329619462261269994651112266861896630584883581092431090390354633458596611690990999635499563944625720180529318327647519405136188243979680965052005899543797270970540925042201315580510136864931200059448645464256385079735225156720340173280541113382758.0) -1719613957783789857/19860562547348050982501313785551054055826630539673708970554435103060535649825139319625648954889488501680865494719253019921780044205805557658109807483499994523398090829033362953135186523580359552555144614353929273831853529446536288544481045105104526669277307473478898498061888931858821517694257595658138564305517447595298378933983614114298000880741350618424855028965861930329619462261269994651112266861896630584883581092431090390354633458596611690990999635499563944625720180529318327647519405136188243979680965052005899543797270970540925042201315580510136864931200059448645464256385079735225156720340173280541113382758) (num-test (/ -10969623867482498359.0 1292477254230352575769754773488799598312602810841892384475535212194939033905139960602724737178675944133847094464739764817257836826367652752931492512753561670732296265459534230949226553571982695924178928914002527460943582374603078611662312521259541641138419845784008028215876048965254023368247445173694441960256131358058174374542730502334351759171930973722361567186133851896057677818979314942434199157003833234473048838906103902832115569853657335216793235394595479328932380393044485884605451918890395812628720641212850763944658735838941829604119213195707479940053016354291972875689927240247563236506479099606571912595.0) -10969623867482498359/1292477254230352575769754773488799598312602810841892384475535212194939033905139960602724737178675944133847094464739764817257836826367652752931492512753561670732296265459534230949226553571982695924178928914002527460943582374603078611662312521259541641138419845784008028215876048965254023368247445173694441960256131358058174374542730502334351759171930973722361567186133851896057677818979314942434199157003833234473048838906103902832115569853657335216793235394595479328932380393044485884605451918890395812628720641212850763944658735838941829604119213195707479940053016354291972875689927240247563236506479099606571912595) (num-test (/ -3716891004757979686.0 -19452372993227550502015765258932159656814363741878583541173956168837566077148160901999018823586675966076058615847408138956450751813058209394199427182041779436168298455103717521843644244801542056954603631432685194627158423459586845252167819811850263444712218938833443253125954475476481099092216538126519474183531297423759923656571895377587989169731023397615799830371852298135015608612181670362528239430952907458704415974164085176066242388561893721949244663406941558257051263727439679525692652639731850971185056484335828001005009903973037524233097329857690857731943951449292814500362180170793919266389501882641682782987.0) 3716891004757979686/19452372993227550502015765258932159656814363741878583541173956168837566077148160901999018823586675966076058615847408138956450751813058209394199427182041779436168298455103717521843644244801542056954603631432685194627158423459586845252167819811850263444712218938833443253125954475476481099092216538126519474183531297423759923656571895377587989169731023397615799830371852298135015608612181670362528239430952907458704415974164085176066242388561893721949244663406941558257051263727439679525692652639731850971185056484335828001005009903973037524233097329857690857731943951449292814500362180170793919266389501882641682782987) (num-test (/ -4863232114852441787.0 -22963038454503597269981750990033903654256693514059439027985256604978917966584414065892146187253799108250061573972673983350956191446047978392921074610323648301008272837432907303975548030552369880338022067315042332692023645592417869181836251486577977896077712912433381480614752789750181208326525834629219729662085632321271870762094800588296544243340047360684854239747242066367921596241226349790282723168222543448385227922748241223520686047460119733024390425165073367321644498280127168757335614077882325524816799960018589278475564547840614315473357481582710826551932681173443524724802157570101916268510464302946527662720.0) 4863232114852441787/22963038454503597269981750990033903654256693514059439027985256604978917966584414065892146187253799108250061573972673983350956191446047978392921074610323648301008272837432907303975548030552369880338022067315042332692023645592417869181836251486577977896077712912433381480614752789750181208326525834629219729662085632321271870762094800588296544243340047360684854239747242066367921596241226349790282723168222543448385227922748241223520686047460119733024390425165073367321644498280127168757335614077882325524816799960018589278475564547840614315473357481582710826551932681173443524724802157570101916268510464302946527662720) (num-test (/ -16248276650501285553.0 -3381199474840825715485713565301777938368574604710714363907009216856320913536015299178065264912798511857598595067318796576494480424838898250138649774858742984769125731728430552285782315111538920026330816414650913188340281906359149109963139438960274321560117812365241840204034925444652058916966934904097509799291744775242863360284348334605170437300543978049053839829106628489146216325576991696936733592366926096500684308845306493636196092408597450926695579897293944488261001228478152650490677071497874746121221519036861983646423005753475340900508665494162949119110128646472783016552527735050067363030838015919512260159.0) 16248276650501285553/3381199474840825715485713565301777938368574604710714363907009216856320913536015299178065264912798511857598595067318796576494480424838898250138649774858742984769125731728430552285782315111538920026330816414650913188340281906359149109963139438960274321560117812365241840204034925444652058916966934904097509799291744775242863360284348334605170437300543978049053839829106628489146216325576991696936733592366926096500684308845306493636196092408597450926695579897293944488261001228478152650490677071497874746121221519036861983646423005753475340900508665494162949119110128646472783016552527735050067363030838015919512260159) (num-test (/ 18296946401228630959.0 3302341071702763311560113831030141639804425031433511503765833897787925467295486187687396312611805794369889470239777040624530990622212474466940548049117664906468330871893337410618797113677420975837622378808494314918471282099855916016026079371666730617071364751834080179173620476977670099126230223862266413091012344741482772771219725893630556702028108027870656512750807359335108428687238687397060104669074315031780019301768744978815422943986587389425726602444937024004102212071953113581935989741954695450085391443134273670514145585869912689150728183940456773133212037846765421397201956541430155664614978559762638030787.0) 494512064898071107/89252461397371981393516590027841665940660135984689500101779294534808796413391518586145846286805562009997012709183163260122459206005742553160555352678855808282927861402522632719426949018308675022638442670499846349147872489185295027460164307342344070731658506806326491329016769648045137814222438482763957110567901209229264128951884483611636667622381298050558284128400198900948876451006451010731354180245251757615676197345101215643660079567205064579073691957971270919029789515458192258971242965998775552705010579544169558662544475293781424031100761728120453327924649671534200578302755582200815017962566988101692919751) (num-test (/ -60488682170925814337492051725122486652.0 14880088785789146426.0) -30244341085462907168746025862561243326/7440044392894573213) (num-test (/ 126617729996196635247771282957911941277.0 -7166506344996883172.0) -126617729996196635247771282957911941277/7166506344996883172) (num-test (/ -278675896803726074870988122161067771390.0 7744689831802931490.0) -27867589680372607487098812216106777139/774468983180293149) (num-test (/ -283351838662873779255871649630248958879.0 6912311315831153835.0) -14913254666467041013466928927907839941/363805858727955465) (num-test (/ -9715584046609700027352634666499181378.0 3368831995960494221.0) -9715584046609700027352634666499181378/3368831995960494221) (num-test (/ -137493547985106345282009151869389470397.0 -1916381539906956855.0) 137493547985106345282009151869389470397/1916381539906956855) (num-test (/ -328662747577960331872949773416436800743.0 -231069430804205460334599495337085157308.0) 328662747577960331872949773416436800743/231069430804205460334599495337085157308) (num-test (/ 213595640581249636406536485951630735277.0 -48492294677143227478357598229530842959.0) -213595640581249636406536485951630735277/48492294677143227478357598229530842959) (num-test (/ 85922846498729014445816145204889624189.0 193533957681757355413031965695625196813.0) 85922846498729014445816145204889624189/193533957681757355413031965695625196813) (num-test (/ 24053342958857142686054803491202486471.0 196417511107100936775397820630955772553.0) 24053342958857142686054803491202486471/196417511107100936775397820630955772553) (num-test (/ 102038936612518756467074084117019701214.0 -111946989731587760700903475996379168167.0) -102038936612518756467074084117019701214/111946989731587760700903475996379168167) (num-test (/ -3006867214208872584699983438179656913.0 -234257597822744479264249663225224173340.0) 3006867214208872584699983438179656913/234257597822744479264249663225224173340) (num-test (/ -279839802710533516603863620922251878907.0 -3244112647743502769852782626803305310331045534071805654982307107362388474314396636799597033636575215617240554815450017779373048313695795886893032630263219.0) 279839802710533516603863620922251878907/3244112647743502769852782626803305310331045534071805654982307107362388474314396636799597033636575215617240554815450017779373048313695795886893032630263219) (num-test (/ 123635964546481689465778244982425098404.0 7701433613491146708866098469269971554817017737111287276993583150548359764165526640986060909954451793171933304569726872785964805121981749276421956645830854.0) 61817982273240844732889122491212549202/3850716806745573354433049234634985777408508868555643638496791575274179882082763320493030454977225896585966652284863436392982402560990874638210978322915427) (num-test (/ 166158110049010486343321316578688184578.0 4093720847216792748840371965199135052196058344862447621818024731938681519017878880275303125899149558774718190527651555811733139227128378041055212888819294.0) 83079055024505243171660658289344092289/2046860423608396374420185982599567526098029172431223810909012365969340759508939440137651562949574779387359095263825777905866569613564189020527606444409647) (num-test (/ 147416259636838312272435267341375281181.0 -11266711292262839805944890501811605204323255169233519804446548849178247889563130015168799346120099052214488209897402054530713234143622703174309015777885801.0) -147416259636838312272435267341375281181/11266711292262839805944890501811605204323255169233519804446548849178247889563130015168799346120099052214488209897402054530713234143622703174309015777885801) (num-test (/ 102557200511608632541115941654031896919.0 3866177549962722728707550488877109233779215384377007088712280650225992470307822792085413087509167847767889824884877044539352696974351192629898363157976511.0) 102557200511608632541115941654031896919/3866177549962722728707550488877109233779215384377007088712280650225992470307822792085413087509167847767889824884877044539352696974351192629898363157976511) (num-test (/ 47794953079190110032282671989549362415.0 3802290983508829335098916118339496411537222492645529399519373082799614656011270200284796148989094312601047370399228868583158444769807910513767845541589667.0) 47794953079190110032282671989549362415/3802290983508829335098916118339496411537222492645529399519373082799614656011270200284796148989094312601047370399228868583158444769807910513767845541589667) (num-test (/ -169956065319483471022234920202991103615.0 -9934427489865644196610501807375648335352544234206717324511161205173460054921759084767897792996557220898467288533128078406604709773449948420404563411793533441010236017064154469575084055359823982786110746700747423674942932421964955746280671982635899487781780756099620799397239156211815110739544719746684712086075069101799537802834839550142629064374734870047412916259754010150500874430055034366305216104752636211802195447299210332237598443674867760860326529472901775427058078447963316168327741049511844237329137194533000697525539835371015163158135757326482343130221118201740819963770851200676279882978581431999960842565.0) 33991213063896694204446984040598220723/1986885497973128839322100361475129667070508846841343464902232241034692010984351816953579558599311444179693457706625615681320941954689989684080912682358706688202047203412830893915016811071964796557222149340149484734988586484392991149256134396527179897556356151219924159879447831242363022147908943949336942417215013820359907560566967910028525812874946974009482583251950802030100174886011006873261043220950527242360439089459842066447519688734973552172065305894580355085411615689592663233665548209902368847465827438906600139505107967074203032631627151465296468626044223640348163992754170240135255976595716286399992168513) (num-test (/ -83006311763073652927964071041666508273.0 13480787677843057038436344704360462056114592749322481662307876594244244638227291805757775026215166740035048814729231681821563443093991755779505400592913963236010573873554317250153995160235771659208137440518282824497744092608999871327127239673370293239927529076145825972430101380272357235582367639159280348164804218713823424182167974242317526959809443701996053548231667727254858428867000011055354779789221097183515832386890638024105232865079002765479933320220378271026425568216748186200736499581088153390350474814123049637951929317200314355414551809067125550551841102097159644340520444983020267926123546444838010089690.0) -83006311763073652927964071041666508273/13480787677843057038436344704360462056114592749322481662307876594244244638227291805757775026215166740035048814729231681821563443093991755779505400592913963236010573873554317250153995160235771659208137440518282824497744092608999871327127239673370293239927529076145825972430101380272357235582367639159280348164804218713823424182167974242317526959809443701996053548231667727254858428867000011055354779789221097183515832386890638024105232865079002765479933320220378271026425568216748186200736499581088153390350474814123049637951929317200314355414551809067125550551841102097159644340520444983020267926123546444838010089690) (num-test (/ -312626207169475064151212222217866488926.0 6989069923898656093413456232544365450599471748502878018530391549015151484336014906416216966193568842618920902504390187814247729346977677905224098932673981665869061845335443588666641982676550205160521286690015544764015602751932938178737949961754714143180917985455875095030469699198116593730005119922928175789172042067281849364217595912265452199938281052984802042194034638773435768458457616208103331213440768472281882976004050012769415198321241810008696147179275528426468408383757692656341606162350211696837361434874035354680073309142183699892959618671515841112321607728427286289324836870027735590091451421689980776552.0) -52104367861579177358535370369644414821/1164844987316442682235576038757394241766578624750479669755065258169191914056002484402702827698928140436486817084065031302374621557829612984204016488778996944311510307555907264777773663779425034193420214448335924127335933791988823029789658326959119023863486330909312515838411616533019432288334186653821362631528673677880308227369599318710908699989713508830800340365672439795572628076409602701350555202240128078713647162667341668794902533053540301668116024529879254737744734730626282109390267693725035282806226905812339225780012218190363949982159936445252640185386934621404547714887472811671289265015241903614996796092) (num-test (/ -151709660794612786408772973806200383563.0 -26960472721919005254400858042130056790831511338891584787669209989714807518625849812230185079206081782191501696661436514815190623849929065098497737155759771863508038766934134444191240792356114381746781342181881402424707118515655119761011977116554236461222788625158348668147995099157685699761135150772589445239536582228655532345059046596356954495360132444243748421428095867292294626357084961338288369883088525401649234025290736504802104065029036642533076183281468647642956623788270236516849523210698622687255735945678505925047193818483603361307498423724202227256505312543145618362906047473400380196192622607541097732443.0) 151709660794612786408772973806200383563/26960472721919005254400858042130056790831511338891584787669209989714807518625849812230185079206081782191501696661436514815190623849929065098497737155759771863508038766934134444191240792356114381746781342181881402424707118515655119761011977116554236461222788625158348668147995099157685699761135150772589445239536582228655532345059046596356954495360132444243748421428095867292294626357084961338288369883088525401649234025290736504802104065029036642533076183281468647642956623788270236516849523210698622687255735945678505925047193818483603361307498423724202227256505312543145618362906047473400380196192622607541097732443) (num-test (/ 138834496986391136939574372853300933725.0 -8052690543272184576133758511645801940246473546142520821850130421981395129853341888352999304040698251945886555605291324954368612109314080471658982022831338507499254609048475429862437003158379101603576571787302167207044118847876475134352180874260998595377014195145760071923429129767580115085764485254455919915567128572731355497418831212259648020550107573824886521471697331410754043280744066090848295906051303624846301488010249980896364883452154860562864255354208802313850527991005497484253401461375477060954782095047043919500670383372218536999834862885439984085848342867301834247551832677237328664699302165347765799113.0) -15426055220710126326619374761477881525/894743393696909397348195390182866882249608171793613424650014491331266125539260209816999922671188694660654061733921258328263179123257120052406553558092370945277694956560941714429159667017597677955952952420811351911893790983097386126039131208251222066153001577238417785769269903307508901676196053917161768879507458730303483944157647912473294224505567508202765169052410814601194893697860451787872032878450144847205144609778916664544040542605794984506984917261578755812650058665667277498250377940152830784550531343894115991055630042596913170777759429209493331565094260318589092694172425853026369851633255796149751755457) (num-test (/ 276499207940187081393841843387608369874.0 27347897028734618663428054896349668572244941195143856840032842195489553215406302254043947382368793914074147314353589439281000471813879502242851166670252197853998033813694814376228360691543987661407996785043637351295817024680721181205269262470473172181965930243852520386958529041036476807810647578694133804796395977642274699322030062940721165202488695975750512485574440928370802874677938542169620505668128224812441566912043326338714451629730522324228356364241376445033028898865300103247057378058702233150414643818049655628999871012383236520330575609745427181485617250755214922048672375947942288446974485524776744246517.0) 8919329288393131657865865915729302254/882190226733374795594453383753215115233707780488511510968801361144824297271171040453030560721573997228198300463019014170354853929479983943317779570008135414645097864957897237942850344888515731013161186614310882299865065312281328425976427821628166844579546136898468399579307388420531509929375728344972058219238579923944345139420324610991005329112538579862919757599175513818412995957352856199020016311875104026207792481033655688345627471926791042717043753685205691775258996737590325911195399292216201069368214316711279213838705516528491500655825019669207328435019911314684352324150721804772331885386273726605701427307) (num-test (/ -8979365591106781219797187096315899769868799444656824967426553299158070014074001230883484015880186603742048949313393413640240595706939311540002219411120389.0 -1698360947072008877.0) 1282766513015254459971026728045128538552685634950974995346650471308295716296285890126212002268598086248864135616199059091462942243848473077143174201588627/242622992438858411) (num-test (/ -12831814656788829919185319784994714617782749504716966706877579983082880759985031662545957372565411439648298939198657738497464024214657609856476819270030801.0 454910754379715.0) -273017333123166594025219569893504566335803180951424823550586808150699590637979397075445901543944924247836147642524632733988596259886332124605889771702783/9678952220845) (num-test (/ -7834266257250691217409788323211914445703052638619784568844628449769010091330019095736167988675873769434766592786720961949649685040028101508217441360672222.0 -428418418877192732.0) 3917133128625345608704894161605957222851526319309892284422314224884505045665009547868083994337936884717383296393360480974824842520014050754108720680336111/214209209438596366) (num-test (/ -4001605821592542867351046644170905984672346731784670159062281252096012802838642896466582343641124674682428297533953704119505640938363392225910275838094045.0 15760991890495426717.0) -4001605821592542867351046644170905984672346731784670159062281252096012802838642896466582343641124674682428297533953704119505640938363392225910275838094045/15760991890495426717) (num-test (/ 2876630161532936743269451364955814480771395635620140205538288339793482694260173239474830738010159518887660000673207712630507802368373928478641773477534499.0 -6788234478844960330.0) -2876630161532936743269451364955814480771395635620140205538288339793482694260173239474830738010159518887660000673207712630507802368373928478641773477534499/6788234478844960330) (num-test (/ 6230070442453337264527950102774203962152836811174649694700041895216739851602598854067104967963392074425258687296947909484969927078206601660837276754799333.0 190237375887614033974333796608341639595.0) 6230070442453337264527950102774203962152836811174649694700041895216739851602598854067104967963392074425258687296947909484969927078206601660837276754799333/190237375887614033974333796608341639595) (num-test (/ -12098771374444180013224380531550204930654718468097503123335711776524055419889032578894177605164827523969169377266342179411916625188550162928371789854647472.0 -41681385674896602840749705069663453185.0) 12098771374444180013224380531550204930654718468097503123335711776524055419889032578894177605164827523969169377266342179411916625188550162928371789854647472/41681385674896602840749705069663453185) (num-test (/ 13185465843955116174925558412278612918939024395488172088108029202384613698982949554556435640011161663974075894844304583900497170806796813871943782330552768.0 -155202352609947911537719051033334010254.0) -6592732921977558087462779206139306459469512197744086044054014601192306849491474777278217820005580831987037947422152291950248585403398406935971891165276384/77601176304973955768859525516667005127) (num-test (/ 12784980722915659825738808684740823452025110516624579136271791852138148426775553817114893299569867520414470532361018804123866264934222335562072872489963044.0 -249441012384365373362771955533424187237.0) -12784980722915659825738808684740823452025110516624579136271791852138148426775553817114893299569867520414470532361018804123866264934222335562072872489963044/249441012384365373362771955533424187237) (num-test (/ 8517839393030302736298983538193047531846908718502576675615969705563208303329257882565359266876007571790337440612227785062203468682754778416335180236967433.0 -23101645464137481399279134347982485126.0) -8517839393030302736298983538193047531846908718502576675615969705563208303329257882565359266876007571790337440612227785062203468682754778416335180236967433/23101645464137481399279134347982485126) (num-test (/ -10157767522292361462005308817460390811646115952647174687477824271227382383351453540195549992670001314693794150879368708343715654899952822395459036505947192.0 -25611473771508763579433379623726126173.0) 10157767522292361462005308817460390811646115952647174687477824271227382383351453540195549992670001314693794150879368708343715654899952822395459036505947192/25611473771508763579433379623726126173) (num-test (/ -8580252632668820290302987230726290672170301642399871646484841866604753910447257372311950907045477729554307803379310475132687855999835211879267570997069974.0 5347050029330174629945013741349819215851040371727058829687387719215168997632386672310746837193930669173408831178932364105722911104309540550576485594530627.0) -8580252632668820290302987230726290672170301642399871646484841866604753910447257372311950907045477729554307803379310475132687855999835211879267570997069974/5347050029330174629945013741349819215851040371727058829687387719215168997632386672310746837193930669173408831178932364105722911104309540550576485594530627) (num-test (/ 7706102251141221799524762336156378964168657337573751909064577951085535246905735244239132983582998872001001594454632956803416956154262109939446710205558308.0 6334400709835247308796432875490978646658012545184955441452799118298109610816693049400832749087993843490999852355789914065232784070007399786089389453289854.0) 3853051125570610899762381168078189482084328668786875954532288975542767623452867622119566491791499436000500797227316478401708478077131054969723355102779154/3167200354917623654398216437745489323329006272592477720726399559149054805408346524700416374543996921745499926177894957032616392035003699893044694726644927) (num-test (/ 12609622044672092190084693450911157599596799695538449568681964257744962273690941575572590166273187189250007688411096790312605666562908125521094386992971478.0 -8237858212652788898158635047388584411011830102060269605835391741772914864422465141467281143809161251942948659243584296367296559912373856433388249393853968.0) -6304811022336046095042346725455578799798399847769224784340982128872481136845470787786295083136593594625003844205548395156302833281454062760547193496485739/4118929106326394449079317523694292205505915051030134802917695870886457432211232570733640571904580625971474329621792148183648279956186928216694124696926984) (num-test (/ -9988492519236282081446302885464711911055350309732728352574982611126604133339499170845224383282665522673248920309221355720665956477799939031063172954469785.0 -1878204914631111607000020160429571305542722711529281855381736226230242796648854769713662269068364131804626863789957256573308715572826753755672493154125086.0) 9988492519236282081446302885464711911055350309732728352574982611126604133339499170845224383282665522673248920309221355720665956477799939031063172954469785/1878204914631111607000020160429571305542722711529281855381736226230242796648854769713662269068364131804626863789957256573308715572826753755672493154125086) )) (let ((val1 (catch #t (lambda () (/ 1.0 0.0)) (lambda args 'error))) (val2 (catch #t (lambda () (/ 1.0 -0.0)) (lambda args 'error)))) (test (equal? val1 val2) #t)) (test (/ "hi") 'error) (test (/ -0) 'error) (test (/ 0) 'error) (test (/ 0.0) 'error) (test (/ 1.0 0) 'error) (test (/) 'error) (test (/ 0/3) 'error) (test (/ 0 1 "hi") 'error) (test (/ 2/3 0) 'error) (test (/ 0 0) 'error) (test (/ 1 0) 'error) (test (/ 0 0.0) 'error) (test (/ 1 0.0) 'error) (test (/ 0.0 0.0) 'error) (test (/ 1.0 0.0) 'error) (test (/ 0 1 2 3 0 4) 'error) (test (/ 0.0 1 2.0 3 0.0 4) 'error) (let ((NaN 1/0)) (test (/ 0 1 NaN 2 0 3) 'error)) ; i.e. divide by zero takes precedence over the NaN (let ((NaN 1/0)) (test (/ 0.0 1.0 NaN 0 1+i) 'error)) (test (/ 1/9223372036854775807 0) 'error) (test (/ 1/9223372036854775807 0.0) 'error) (if with-bignums (begin (test (/ (bignum 1.0) (bignum 0)) 'error) (test (/ (bignum 1.0) (bignum -0.0)) 'error) (test (/ 9223372036854775807123123123 0) 'error))) (for-each (lambda (arg) (test (/ arg nan.0) 'error) (test (/ nan.0 arg) 'error) (test (/ arg inf.0) 'error) (test (/ inf.0 arg) 'error) (test (/ 0 arg nan.0) 'error) (test (/ nan.0 0 arg) 'error) (test (/ arg inf.0 0) 'error) (test (/ 0 inf.0 arg) 'error) (test (/ 0 arg) 'error) (test (/ 0.0 arg) 'error) (test (/ 1/2 arg) 'error) (test (/ 1+i arg) 'error)) (list "hi" () (integer->char 65) #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) (for-each (lambda (arg) (test (/ arg) 'error)) (list "hi" () (integer->char 65) 0 0.0 0+0i -0.0 -0 0-0i #f #t '(1 2) _ht_ _null_ _c_obj_ 'a-symbol (cons 1 2) (make-vector 3) abs # '(1 2 3) #\newline (lambda (a) (+ a 1)) # #)) ;;; from guile irc (test (boolean? (let ((x (/ 1e-300 1e8))) x)) #f) (if with-bignums (let ((old-prec (*s7* 'bignum-precision))) (set! (*s7* 'bignum-precision) 512) (let* ((rats (list 2/3 5/8 12/19 53/84 253/401 665/1054 12941/20511 15601/24727 79335/125743 190537/301994 7161071/11350029 10400200/16483927 10781274/17087915 53715833/85137581 171928773/272500658 397573379/630138897 4201378396/6659027209 6189245291/9809721694 6586818670/10439860591 65470613321/103768467013 137528045312/217976794617 615582794569/975675645481 753110839881/1193652440098 5409303924479/8573543875303 11571718688839/18340740190704 52449289519716/83130157078217 326267455807135/517121682660006 483615324366283/766512153894657 3816473305410548/6048967074079039 6234549927241963/9881527843552324 111738283365989051/177100989030047175 130441933147714940/206745572560704147 397560349370386783/630118245525664765 3447601211185766107/5464318637170278738 4640282259296926456/7354673373747273033 22803850947114245497/36143248623210700400 50247984153525417450/79641170620168673833 205632218873398596256/325919355854421968365 5680010011095224105765/9002602871306688466954 7530699980955811472069/11935877073996486182239 23414628818361028801231/37111308645407146420177 31150961018190238869556/49373105075258054570781 1534133422091150914676569/2431543945117495582118873 1721039188200292347893905/2727782575569043909543559 3473229337418774934657366/5504938256213345873657899 154574280995644579711687565/244994438954031520405061896 171940427682738454384974395/272519130235098249773351391 522767741723052913024237917/828567267217721441067369971 2438425051595107335801557824/3864812267597295609689840565 8360810638231427833453149306/13251571337227329711204261637 25605199656417336413383685835/40583281278899710574680154882 62532402744384260909046316717/99111513429841767911321781937 201880404458020531058243690939/319972870696382667546684028520 378155609259623725703103696043/599362460113865624518687902158 2180796053156940756896192173706/3456479965974452268626125476129 30909300353456794322249794127927/48990081983756197385284444567964 72722580972698292428980549124384/115262563797384656113699516516573 253438635377865553122983825848491/401690733307859070263635245069941 579599851728429398674948200821366/918644030413102796640970006656455 2391121987886415887128773352409848/3789838685449795842677579543142393 8658726883466670304288180833845151/13723757414280836847692013404326603 13440970859239502078545727538664847/21303434785180428533047172490611389 42714034565604922122765955968404389/67700143040991081441819097014976560 114701132837575264289752140366548320/181796994337792815792410118554318291 845621964428631772151030938534242629/1340279103405540791988689926895204597 960323097266207036440783078900790949/1522076097743333607781100045449522888 6836962813701024519375233692672084963/10836329678541128070260110436700978507 14634248724668256075191250464244960875/23194735454825589748301320918851479902 51700032084971999781389768164307758537/81942612140761230922945173238704941101 229231662975523486756566339893048870935/363323589794154975118123224355821745701 724760772286874203975897537379209410467/1148718646068400566529013525387318698302 1360755729128472664464206788894048264735/2156746803310104260960438025216078994304 6167783688800764861832724692955402469407/9775705859308817610370765626251634675518 28435404464167678210479364512746335244699/45069049768544731377148664330740395536983 34603188152968443072312089205701737714106/54844755627853548987519429956992030212501 144580536300674537151081081515762353325831/229154728370723013560448485454219755525522 792109057809309571900029585990215242057367/1255463153109322165777281287185082838052612 1907982376372936661174533424217656928480502/3024080518587943907662978975235597217368769 27503862327030422828343497525037412240784395/43592590413340536873058986940483443881215378 31319827079776296150692564373472726097745399/49640751450516424688384944890954638315952916 221146771934807009716022484038526739612698295/350509340672202916726357593211918065429039181 252466599014583305866715048411999465710443694/400150092122719341414742538102872703744992097 2555985817225609354817843048493467383202182339/4051141672677709838835810325919681675765873886 2808452416240192660684558096905466848912626033/4451291764800429180250552864022554379510865983 50299676893308884586455330695886403814716824900/79723101674285005903095209014303106127450595597 72767296223230425871931795471130138606017833164/115333435792688439345099631926483541163537523461 148343044862701044404548149039165744060948292361/235118163350177307870449816716989636706585912905 590563727034563984957508038059757509394880543411/936021361635908802301548714003935992446832785637 1550580840017760484596044169668976645517675504708/2457612485764860659689096693368334799470374920545 26950438007336492223090258922432360483195364123447/42715433619638540017016192501265627583443206434902 )) (fifth (/ (log 2.0) (log 3.0))) (c-fifth (complex fifth fifth)) (p-fifth (make-polar (* (sqrt 2.0) fifth) (/ pi 4))) (last-rat 26950438007336492223090258922432360483195364123447/42715433619638540017016192501265627583443206434902)) (for-each (lambda (a b) (if (not (< (abs (- b fifth)) (abs (- a fifth)))) (format-logged #t ";fifth: ~A is not better than ~A??~%" b a)) (if (not (< (magnitude (- (complex b b) c-fifth)) (magnitude (- (complex a a) c-fifth)))) (format-logged #t ";rectangular fifth: ~A is not better than ~A??~%" b a)) (let ((pa (make-polar (* (sqrt 2.0) a) (/ pi 4))) (pb (make-polar (* (sqrt 2.0) b) (/ pi 4)))) (if (not (< (magnitude (- pb p-fifth)) (magnitude (- pa p-fifth)))) (format-logged #t ";polar fifth: ~A is not better than ~A??~%" b a))) (if (not (< (abs (- b last-rat)) (abs (- a last-rat)))) (format-logged #t ";- last: ~A is not better than ~A??~%" b a)) (if (not (< (magnitude (sqrt (- b last-rat))) (magnitude (sqrt (- a last-rat))))) (format-logged #t ";sqrt last: ~A is not better than ~A??~%" b a)) ) rats (cdr rats))) (set! (*s7* 'bignum-precision) old-prec))) (if with-bignums (num-test (- 2 (* 3796553736732654909229441/2684568892382786771291329 3796553736732654909229441/2684568892382786771291329)) 1/7206910137949342581102166717750576215502190586241)) ;;; -------------------------------------------------------------------------------- ;;; random ;;; -------------------------------------------------------------------------------- (let () (define (v n range chker) ; chi^2 or mus-random (let ((hits (make-vector 100 0))) (do ((i 0 (+ 1 i ))) ((= i n)) (let ((y (random range))) (if (not (chker y)) (format-logged #t ";(random ~A) -> ~A?~%" range y)) (let ((iy (min 99 (floor (* 100 (/ y range)))))) (vector-set! hits iy (+ 1 (vector-ref hits iy)))))) (let ((sum 0.0) (p (/ n 100.0))) (do ((i 0 (+ 1 i))) ((= i 100) sum) (let ((num (- (vector-ref hits i) p))) (set! sum (+ sum (/ (* num num) p)))))))) (num-test (random 0) 0) (num-test (random 0.0) 0.0) (let () (define (rtest) (- (random 2.0) 1.0)) (do ((i 0 (+ i 1))) ((= i 100)) (let ((val (rtest))) (if (or (> val 1.0) (< val -1.0)) (format-logged #t "(- (random 2.0) 1.0): ~A~%" i val))))) (let ((vr (v 1000 1.0 (lambda (val) (and (real? val) (not (negative? val)) (<= val 1.0)))))) (if (or (< vr 40) (> vr 400)) (format-logged #t ";(random 1.0) not so random? ~A~%" vr))) (let ((vr (v 1000 100 (lambda (val) (and (integer? val) (not (negative? val)) (<= val 100)))))) (if (or (< vr 40) (> vr 400)) (format-logged #t ";(random 100) not so random? ~A~%" vr))) (let ((vr (v 1000 1/2 (lambda (val) (and (rational? val) (not (negative? val)) (<= val 1/2)))))) (if (or (< vr 40) (> vr 400)) (format-logged #t ";(random 1/2) not so random? ~A~%" vr))) (let ((vr (v 1000 -10.0 (lambda (val) (and (real? val) (not (positive? val)) (>= val -10.0)))))) (if (or (< vr 40) (> vr 400)) (format-logged #t ";(random -10.0) not so random? ~A~%" vr))) (let ((imax 0.0) (rmax 0.0) (imin 100.0) (rmin 100.0)) (do ((i 0 (+ i 1))) ((= i 100)) (let ((val (random 1+i))) (set! imax (max imax (imag-part val))) (set! imin (min imin (imag-part val))) (set! rmax (max rmax (real-part val))) (set! rmin (min rmin (real-part val))))) (if (or (> imax 1.0) (< imin 0.0) (> rmax 1.0) (< rmin 0.0) (< rmax 0.001) (< imax 0.001)) (format-logged #t ";(random 1+i): ~A ~A ~A ~A~%" rmin rmax imin imax))) (let ((imax 0.0) (rmax 0.0) (imin 100.0) (rmin 100.0)) (do ((i 0 (+ i 1))) ((= i 100)) (let ((val (random 0+i))) (set! imax (max imax (imag-part val))) (set! imin (min imin (imag-part val))) (set! rmax (max rmax (real-part val))) (set! rmin (min rmin (real-part val))))) (if (or (> imax 1.0) (< imin 0.0) (> rmax 0.0) (< rmin 0.0) (< imax 0.001)) (format-logged #t ";(random 0+i): ~A ~A ~A ~A~%" rmin rmax imin imax))) (let ((imax 0.0) (rmax 0.0) (imin 100.0) (rmin 100.0)) (do ((i 0 (+ i 1))) ((= i 100)) (let ((val (random 10.0+100.0i))) (set! imax (max imax (imag-part val))) (set! imin (min imin (imag-part val))) (set! rmax (max rmax (real-part val))) (set! rmin (min rmin (real-part val))))) (if (or (> imax 100.0) (< imin 0.0) (> rmax 10.0) (< rmin 0.0) (< imax 0.1) (< rmax 0.01)) (format-logged #t ";(random 100+10i): ~A ~A ~A ~A~%" rmin rmax imin imax))) (do ((i 0 (+ i 1))) ((= i 100)) (let ((val (random 1.0+1.0i))) (if (or (not (complex? val)) (> (real-part val) 1.0) (> (imag-part val) 1.0) (< (real-part val) 0.0)) (format-logged #t ";(random 1.0+1.0i) -> ~A?~%" val)))) (let ((rs (random-state 12345678))) (do ((i 0 (+ i 1))) ((= i 100)) (let ((val (random 1.0 rs))) (if (or (not (real? val)) (negative? val) (> val 1.0)) (format-logged #t ";(random 1.0 rs) -> ~A?~%" val))))) (if with-bignums (begin (num-test (random (bignum "0")) 0) (num-test (random (bignum "0.0")) 0.0) (let ((vr (v 1000 (bignum "1.0") (lambda (val) (and (real? val) (not (negative? val)) (<= val 1.0)))))) (if (or (< vr 40) (> vr 400)) (format-logged #t ";(big-random 1.0) not so random? ~A~%" vr))) (let ((vr (v 1000 (bignum "100") (lambda (val) (and (integer? val) (not (negative? val)) (<= val 100)))))) (if (or (< vr 40) (> vr 400)) (format-logged #t ";(big-random 100) not so random? ~A~%" vr))) (let ((vr (v 1000 (bignum "1/2") (lambda (val) (and (rational? val) (not (negative? val)) (<= val 1/2)))))) (if (or (< vr 40) (> vr 400)) (format-logged #t ";(big-random 1/2) not so random? ~A~%" vr))) (let ((vr (v 1000 (bignum "-10.0") (lambda (val) (and (real? val) (not (positive? val)) (>= val -10.0)))))) (if (or (< vr 40) (> vr 400)) (format-logged #t ";(big-random -10.0) not so random? ~A~%" vr))) (do ((i 0 (+ i 1))) ((= i 100)) (let ((val (random (bignum "1.0+1.0i")))) (if (or (not (complex? val)) (> (real-part val) 1.0) (> (imag-part val) 1.0) (< (real-part val) 0.0)) (format-logged #t ";(big-random 1.0+1.0i) -> ~A?~%" val)))) (let ((rs (random-state (bignum "12345678")))) (do ((i 0 (+ i 1))) ((= i 100)) (let ((val (random (bignum "1.0") rs))) (if (or (not (real? val)) (negative? val) (> val 1.0)) (format-logged #t ";(big-random 1.0 rs) -> ~A?~%" val))) (let ((val (random 1.0 rs))) (if (or (not (real? val)) (negative? val) (> val 1.0)) (format-logged #t ";(big-random small-1.0 rs) -> ~A?~%" val))))) (let ((rs (random-state 1234))) (do ((i 0 (+ i 1))) ((= i 100)) (let ((val (random (bignum "1.0") rs))) (if (or (not (real? val)) (negative? val) (> val 1.0)) (format-logged #t ";(big-random 1.0 small-rs) -> ~A?~%" val))) (let ((val (random 1.0 rs))) (if (or (not (real? val)) (negative? val) (> val 1.0)) (format-logged #t ";(random small-1.0 rs) -> ~A?~%" val))))) )) ) (test (random 0 #t) 'error) (test (random 0.0 #(1 2)) 'error) (test (nan? (random 1/0)) #t) (test (zero? (random 1e-30)) #f) (unless with-bignums (test ((object->string (random-state 1234) :readable) 1) #\r) ; print-readably here (test ((object->string (random-state 1234)) 1) #\<)) ; write (#t as default) here (test (random-state 1.0) 'error) (test (random-state 1+i) 'error) (test (random-state 3/4) 'error) (test (random-state 1/0) 'error) (test (random-state (real-part (log 0))) 'error) (test (random-state? (random-state 100)) #t) (test (random-state?) 'error) (test (random-state? (random-state 100) 100) 'error) (test (equal? (random-state 1234) #f) #f) (unless with-bignums (test (random-state -1) 'error) (test (random-state -1 123) 'error) (test (random-state 1 -123) 'error) (test (random-state 1 most-negative-fixnum) 'error) (test (random-state -9223372036854775808) 'error) (let ((r1 (random-state 100)) (r2 (random-state 100)) (r3 (random-state 200))) (test (random-state? r3) #t) (test (equal? r1 r2) #t) (test (equal? r1 r3) #f) (random 1.0 r1) (test (equal? r1 r2) #f) (random 1.0 r2) (test (equal? r1 r2) #t) (test (equal? (copy r1) r1) #t) (test (random-state? r2) #t) (test (random-state? (copy r1)) #t))) (test (complex? (random 1+i (random-state 1234))) #t) (when with-bignums (test (complex? (random (bignum "1+i") (random-state 1234))) #t) (test (real? (random (bignum "1.5") (random-state 1234))) #t) (test (rational? (random (bignum "1/2") (random-state 1234))) #t) (test (integer? (random (bignum "100") (random-state 1234))) #t) (test (complex? (random (bignum "1+i") (random-state (bignum "1234")))) #t) (test (real? (random (bignum "1.5") (random-state (bignum "1234")))) #t) (test (rational? (random (bignum "1/2") (random-state (bignum "1234")))) #t) (test (integer? (random (bignum "100") (random-state (bignum "1234")))) #t)) (for-each (lambda (arg) (test (random arg) 'error) (test (random 1.0 arg) 'error) (test (random-state arg) 'error) (test (random-state->list arg) 'error) (test (random-state? arg) #f) ) (list "hi" _ht_ _null_ _c_obj_ () '(1 2) #f (integer->char 65) 'a-symbol (make-vector 3) abs #\f (lambda (a) (+ a 1)) (if #f #f) :hi # #)) (when (not with-bignums) (test (car (random-state->list (random-state 1234))) 1234) (test (pair? (random-state->list)) #t)) ; the default? (test (random-state->list #f 1234) 'error) (test (random-state) 'error) (let ((r1 (random-state 1234)) (r2 (random-state 1234))) (test (eq? r1 r2) #f) (unless with-bignums (test (equal? r1 r2) #t)) (test (eq? r2 r2) #t) (test (equal? r1 r1) #t) (test ((object->string r1 #f) 1) #\<) ; display, not write (let ((val1 (random 10000000 r1)) (val2 (random 10000000 r2))) (test val1 val2))) (let ((r1 (random-state 1234)) (r2 (random-state 1234567))) (let ((val1 (random 10000000 r1)) (val2 (random 10000000 r2))) (let ((val3 (random 10000000 r1)) (val4 (random 10000000 r2))) (let ((val5 (random 10000000 r1)) (val6 (random 10000000 r2))) (test (or (not (= val1 val2)) (not (= val3 val4)) (not (= val5 val6))) #t))))) (when (not with-bignums) (let ((r1 (make-vector 10))) (let* ((rs1 (random-state 12345)) (rs2 (copy rs1)) (rs3 (apply random-state (random-state->list rs1))) (rs4 #f) (rs5 #f)) (do ((i 0 (+ i 1))) ((= i 10)) (set! (r1 i) (random 1.0 rs1)) (if (= i 3) (set! rs4 (copy rs1))) (if (= i 5) (set! rs5 (apply random-state (random-state->list rs1))))) (do ((i 0 (+ i 1))) ((= i 10)) (let ((v1 (random 1.0 rs2)) (v2 (random 1.0 rs3))) (if (not (= v1 v2 (r1 i))) (format-logged #t ";random v1: ~A, v2: ~A, r1[~A]: ~A~%" v1 v2 i (r1 i)))) (if (> i 3) (let ((v3 (random 1.0 rs4))) (if (not (= v3 (r1 i))) (format-logged #t ";random v3: ~A, r1[~A]: ~A~%" v3 i (r1 i))))) (if (> i 5) (let ((v4 (random 1.0 rs5))) (if (not (= v4 (r1 i))) (format-logged #t ";random v4: ~A, r1[~A]: ~A~%" v4 i (r1 i))))))))) (do ((i 0 (+ i 1))) ((= i 20)) ; this was ((+ i 100)) !! -- surely a warning would be in order? (let ((val (random -1.0))) (test (and (real? val) (<= val 0.0) (>= val -1.0)) #t)) (let ((val (random -100))) (test (and (integer? val) (<= val 0) (>= val -100)) #t)) (let ((val (random most-negative-fixnum))) (test (and (integer? val) (<= val 0)) #t)) (let ((val (random most-positive-fixnum))) (test (and (integer? val) (>= val 0)) #t)) (let ((val (random pi))) (test (and (real? val) (>= val 0) (< val pi)) #t)) (let ((val (random 3/4))) (test (and (rational? val) (>= val 0) (< val 3/4)) #t)) (test (let ((x (random most-positive-fixnum))) (integer? x)) #t) (if with-bignums (begin (let ((val (random (expt 2 70)))) (test (and (integer? val) (>= val 0)) #t)) (let ((val (random 1180591620717411303424.0))) (test (and (real? val) (>= val 0.0)) #t))))) (if with-bignums (begin (let ((r1 (random-state (expt 2 70)))) (test (random-state? r1) #t) (test ((object->string r1) 1) #\<) (test (eq? r1 r1) #t) (test (equal? r1 r1) #t) (let ((val1 (random 10000000 r1)) (val2 (random 10000000 r1))) (test (not (= val1 val2)) #t))))) (let () ; optimizer tests (define (f1) (- (random 100) 50)) (define (f2) (- (random 1.0) 0.5)) (define (f3) (random 100)) (define (f4) (random 1.0)) (do ((i 0 (+ i 1))) ((= i 20)) (let ((v1 (f1)) (v2 (f2)) (v3 (f3)) (v4 (f4))) (if (not (<= -50 v1 50)) (format *stderr* ";f1: sub_random_ic: ~A~%" v1)) (if (not (<= 0 v3 100)) (format *stderr* ";f3: random_ic: ~A~%" v3)) (if (not (<= -0.5 v2 0.5)) (format *stderr* ";f2: sub_random_rc: ~A~%" v2)) (if (not (<= 0.0 v4 1.0)) (format *stderr* ";f4: random_rc: ~A~%" v4))))) ;;; -------------------------------------------------------------------------------- ;;; string->number ;;; number->string ;;; -------------------------------------------------------------------------------- (test (string->number "+#.#") #f) (test (string->number "-#.#") #f) (test (string->number "#.#") #f) (when (not pure-s7) (test (string->number "#i") #f) (test (string->number "#e") #f)) (test (string->number "#") #f) (for-each (lambda (n) (if (not (eqv? n (string->number (number->string n)))) (format-logged #t ";(string->number (number->string ~A)) = ~A?~%" n (string->number (number->string n))))) (list 1 2 3 10 1234 1234000000 500029 362880 0/1 0/2 0/3 0/10 0/1234 0/1234000000 0/500029 0/362880 1/1 1/2 1/3 1/10 1/1234 1/1234000000 1/500029 1/362880 2/1 2/2 2/3 2/10 2/1234 2/1234000000 2/500029 2/362880 3/1 3/2 3/3 3/10 3/1234 3/1234000000 3/500029 3/362880 10/1 10/2 10/3 10/10 10/1234 10/1234000000 10/500029 10/362880 1234/1 1234/2 1234/3 1234/10 1234/1234 1234/1234000000 1234/500029 1234/362880 1234000000/1 1234000000/2 1234000000/3 1234000000/10 1234000000/1234 1234000000/1234000000 1234000000/500029 1234000000/362880 500029/1 500029/2 500029/3 500029/10 500029/1234 500029/1234000000 500029/500029 500029/362880 362880/1 362880/2 362880/3 362880/10 362880/1234 362880/1234000000 362880/500029 362880/362880)) (let ((fequal? (lambda (a b) (< (magnitude (- a b)) 1e-14)))) (for-each (lambda (x) (if (not (fequal? x (string->number (number->string x)))) (format-logged #t ";(string->number (number->string ~A)) -> ~A?~%" x (string->number (number->string x))))) (list 0.000000 1.000000 3.141593 2.718282 1234.000000 1234000000.000000 0.000000+0.000000i 0.000000+0.000000i 0.000000+1.000000i 0.000000+3.141593i 0.000000+2.718282i 0.000000+1234.000000i 0.000000+1234000000.000000i 0.000000+0.000000i 0.000000+0.000000i 0.000000+1.000000i 0.000000+3.141593i 0.000000+2.718282i 0.000000+1234.000000i 0.000000+1234000000.000000i 1.000000+0.000000i 1.000000+0.000000i 1.000000+1.000000i 1.000000+3.141593i 1.000000+2.718282i 1.000000+1234.000000i 1.000000+1234000000.000000i 3.141593+0.000000i 3.141593+0.000000i 3.141593+1.000000i 3.141593+3.141593i 3.141593+2.718282i 3.141593+1234.000000i 3.141593+1234000000.000000i 2.718282+0.000000i 2.718282+0.000000i 2.718282+1.000000i 2.718282+3.141593i 2.718282+2.718282i 2.718282+1234.000000i 2.718282+1234000000.000000i 1234.000000+0.000000i 1234.000000+0.000000i 1234.000000+1.000000i 1234.000000+3.141593i 1234.000000+2.718282i 1234.000000+1234.000000i 1234.000000+1234000000.000000i 1234000000.000000+0.000000i 1234000000.000000+0.000000i 1234000000.000000+1.000000i 1234000000.000000+3.141593i 1234000000.000000+2.718282i 1234000000.000000+1234.000000i 1234000000.000000+1234000000.000000i))) (test (string->number "1+1+i") #f) (test (string->number "1+i+i") #f) (test (string->number "1+.i") #f) (test (string->number ".") #f) (test (string->number "8.41470984807896506652502321630298999622563060798371065672751709991910404391239668948639743543052695.") #f) (test (string->number "8.41470184807816506652502321630218111622563060718371065672751701111110404311231668148631743543052695" 9) #f) (test (number->string -9223372036854775808) "-9223372036854775808") (test (number->string 9223372036854775807) "9223372036854775807") (test (number->string 123 8) "173") (test (number->string 123 16) "7b") (test (number->string 123 2) "1111011") (test (number->string -123 8) "-173") (test (number->string -123 16) "-7b") (test (number->string -123 2) "-1111011") (test (number->string 0 8) "0") (test (number->string 0 2) "0") (test (number->string 0 16) "0") (test (number->string 1 8) "1") (test (number->string 1 2) "1") (test (number->string 1 16) "1") (test (number->string -1 8) "-1") (test (number->string -1 2) "-1") (test (number->string -1 16) "-1") (test (string->number "- 1") #f) (num-test (string->number "1+0i") 1.0) (num-test (string->number "0-0i") 0.0) (num-test (string->number "0-0e10i") 0.0) (num-test (string->number "0-0e40i") 0.0) (num-test (string->number "0-0e100i") 0.0) (test (string->number "0e10e100") #f) (test (equal? (string->number (number->string -1e19)) -1e19) #t) (test (equal? (string->number (number->string 1e308)) 1e308) #t) (test (equal? (string->number (number->string 9.22e18)) 9.22e18) #t) ;;; @ exponent added 26-Mar-12 (if (provided? '@-exponent) (begin (num-test 0.0 0@0) (num-test 0.0 0@-0) (num-test 0.0 0@+0) (num-test 1.0 1@0) (num-test 10.0 1@1) (num-test 10.0 1@+1) (num-test 0.1 1@-1) (num-test (string->number "1@0" 16) 1.0) (num-test (string->number "e@0" 16) 14.0) (num-test (string->number "a@1" 16) 160.0) (num-test (string->number "#xa@1") 160.0) (num-test (string->number ".a@0" 12) 0.83333333333333) (num-test (string->number "a.@0" 16) 10.0) (num-test (string->number "0a" 16) 10) (when (not pure-s7) (num-test (string->number "#e0a" 16) 10)) (num-test (string->number "a@-1" 16) 0.625) (num-test 1@0+1@0i 1+1i) (num-test (string->number "1@1" 12) 12.0) (num-test (string->number "1@-1" 16) 0.0625) (num-test (string->number "1.0@1+0.1@2i" 16) 16+16i) (num-test (string->number "#b.0@2") 0.0) (num-test (string->number ".2@-22") 2e-23) (num-test (string->number "+02@02") 200.0) (num-test (string->number "2fe2@2" 16) 3138048.0) (when (not pure-s7) (num-test (string->number "#i1@01" 16) 16.0)) (num-test (string->number "1@-0-bc/di" 16) 1-14.461538461538i) (num-test (string->number ".f-a.c1@0i" 16) 0.9375-10.75390625i) (num-test (string->number "df2@2-ccfi" 16) 913920-3279i) (num-test (string->number "0/0de-0@2i" 16) 0.0) (num-test (string->number "-1a12cd.@1" 16) -27339984.0) (num-test (string->number "fb/2ea+2@+1i" 16) 0.33646112600536+32i) (num-test (string->number "af.e0@-0+0b/efefd11i" 16) 175.875+4.3721589140015e-08i) (num-test (string->number "bb10@1-i" 12) 247248-1i) (num-test (string->number "b.+0@01i" 12) 11.0) (num-test (string->number "-0@-0221" 12) 0.0) (num-test (string->number "-a-01@2i" 12) -10-144i) (num-test (string->number "#d.0@-11" 10) 0.0) (num-test (string->number "#i+1@002" 10) 100.0) (num-test (string->number "-111@-1-1i" 10) -11.1-1i) (num-test (string->number "122@9-2@0i" 10) 122000000000-2i) (num-test (string->number "-0@+10-20i" 10) 0-20i) (num-test (string->number "+2@-909221" 10) 0.0) )) ;; s7.html claims this '=' is guaranteed... (test (= .6 (string->number ".6")) #t) (test (= 0.60 (string->number "0.60")) #t) (test (= 60e-2 (string->number "60e-2")) #t) (test (= #i3/5 (string->number "#i3/5")) #t) (test (= 0.11 (string->number "0.11")) #t) (test (= 0.999 (string->number "0.999")) #t) (test (= 100.000 (string->number "100.000")) #t) (test (= 1e10 (string->number "1e10")) #t) (test (= 0.18 (string->number "0.18")) #t) (test (= 0.3 (string->number "0.3")) #t) (test (= 0.333 (string->number "0.333")) #t) (test (= -1/10 (string->number "-1/10")) #t) (test (= -110 (string->number "-110")) #t) (test (= 1+i (string->number "1+i")) #t) (test (= 0.6-.1i (string->number "0.6-.1i")) #t) ;; but is this case also guaranteed?? (when (not with-bignums) (test (= .6 (string->number (number->string .6))) #t) (test (= 0.6 (string->number (number->string 0.6))) #t) (test (= 0.60 (string->number (number->string 0.60))) #t) (test (= 60e-2 (string->number (number->string 60e-2))) #t) (test (= 0.6-.1i (string->number (number->string 0.6-.1i))) #t)) ;(test (= #i3/5 (string->number (number->string #i3/5))) #t) (test (= 0.11 (string->number (number->string 0.11))) #t) (test (= 0.999 (string->number (number->string 0.999))) #t) (test (= 100.000 (string->number (number->string 100.000))) #t) (test (= 1e10 (string->number (number->string 1e10))) #t) (test (= 0.18 (string->number (number->string 0.18))) #t) (test (= 0.3 (string->number (number->string 0.3))) #t) (test (= 0.333 (string->number (number->string 0.333))) #t) (test (= -1/10 (string->number (number->string -1/10))) #t) (test (= -110 (string->number (number->string -110))) #t) (test (= 1+i (string->number (number->string 1+i))) #t) (test (= 0.6 0.600) #t) (test (= 0.6 6e-1 60e-2 .06e1 6.e-1) #t) (test (= 0.6 6e-1 60e-2 .06e1 600e-3 6000e-4 .0006e3) #t) (test (= 0.3 0.3000) #t) (test (= 0.345 0.345000 345.0e-3) #t) (test (string->number #u8(0 0 0 0 0) #\a) 'error) (test (string->number "" "") 'error) #| ;; scheme spec says (eqv? (number->string (string->number num radix) radix) num) is always #t ;; (also that radix is 10 if num is inexact) ;; currently in s7, if m below is 0, s7 is ok, but if there's a true integer part, we sometimes lose by 1e-15 or so (let () (do ((m 0 (+ m 1))) ((= m 10)) (do ((i 0 (+ i 1))) ((= i 10)) (do ((j 0 (+ j 1))) ((= j 10)) (do ((k 0 (+ k 1))) ((= k 10)) (let* ((str (string (integer->char (+ (char->integer #\0) i)) (integer->char (+ (char->integer #\0) j)) (integer->char (+ (char->integer #\0) k)))) (strd (string (integer->char (+ (char->integer #\0) m)))) (str1 (string-append strd "." str)) (str2 (string-append (if (= m 0) "" strd) "." str "000")) (str3 (string-append strd str "e-3")) (str4 (string-append strd str ".e-3")) (str5 (string-append "0.0" strd str "e2")) (str6 (string-append ".00000" strd str "e6")) (str7 (string-append strd str "00e-5")) (args (list (string->number str1) (string->number str2) (string->number str3) (string->number str4) (string->number str5) (string->number str6) (string->number str7)))) (if (not (apply = args)) (format-logged #t "~A.~A: ~{~D~^~4T~}~%" strd str (map (lambda (val) (let ((ctr 0)) (for-each (lambda (arg) (if (not (equal? val arg)) (set! ctr (+ ctr 1)))) args) ctr)) args))))))))) |# (test (number->string 1/0) "nan.0") (test (number->string 1/0 2) "nan.0") (test (number->string 1/0 10) "nan.0") (test (number->string 1/0 16) "nan.0") (test (number->string 1000000000000000000000000000000000/0) "nan.0") (test (number->string 0/1000000000000000000000000000000000) "0") (test (object->string 1/0) "nan.0") (test (format #f "~F" 1/0) "nan.0") (test (format #f "~E" 1/0) "nan.0") (test (format #f "~G" 1/0) "nan.0") (test (format #f "~D" 1/0) "nan.0") (test (format #f "~X" 1/0) "nan.0") (test (format #f "~B" 1/0) "nan.0") (test (format #f "~O" 1/0) "nan.0") (test (format #f "~A" 1/0) "nan.0") (test (format #f "~S" 1/0) "nan.0") (test (format #f "~P" 1/0) "s") (test (nan? (string->number "nan.0")) #t) (test (nan? (string->number "nan.0" 2)) #t) (test (number->string (real-part (log 0.0))) "-inf.0") (test (number->string (real-part (log 0.0)) 2) "-inf.0") (test (number->string (real-part (log 0.0)) 16) "-inf.0") (test (number->string (- (real-part (log 0.0)))) "inf.0") (test (number->string (- (real-part (log 0.0))) 2) "inf.0") (test (format #f "~G" (real-part (log 0))) "-inf.0") (test (format #f "~E" (real-part (log 0))) "-inf.0") (test (format #f "~F" (real-part (log 0))) "-inf.0") (test (format #f "~D" (real-part (log 0))) "-inf.0") (test (format #f "~X" (real-part (log 0))) "-inf.0") (test (format #f "~B" (real-part (log 0))) "-inf.0") (test (format #f "~O" (real-part (log 0))) "-inf.0") (test (format #f "~A" (real-part (log 0))) "-inf.0") (test (format #f "~S" (real-part (log 0))) "-inf.0") (test (format #f "~P" (real-part (log 0))) "s") (test (infinite? (string->number "inf.0")) #t) (test (infinite? (string->number "inf.0" 16)) #t) (test (infinite? (string->number "-inf.0")) #t) (test (infinite? (string->number "-inf.0" 16)) #t) (test (negative? (string->number "-inf.0")) #t) ;(test (number->string 0+0/0i 2) "0-nani") ; there are too many possible correct choices (test (equal? 0.0 0e0) #t) (test (equal? 0.0 -0.0) #t) (test (eqv? 0.0 -0.0) #t) (test (equal? 0.0 0e-0) #t) (test (equal? 0.0 .0e+0) #t) (test (equal? 0.0 00000000000000000000000000000000000000000000000000000e100) #t) (test (equal? 0.0 .0000000000000000000000000000000000000000000000000000e100) #t) (test (equal? 0.0 00000000000000000000000000000000000000000000000000000.0000000000000000000000000000000000000000000000000000000000e100) #t) (test (equal? 0.0 0e100000000000000000000000000000000000000000000000000000000000000000000000) #t) (num-test 0 0/1000000000) (num-test 0 0/100000000000000000000000000000000000000) (num-test 0 0/100000000000000000000000000000000000000000000000000000000000000) (num-test 0 0/100000000000000000000000000000000000000000000000000000000000000000000) (num-test 0 -0/100000000000000000000000000000000000000000000000000000000000000000000) (num-test 0 0/1000000000+0/1000000000i) (num-test 0 0/100000000000000000000000000000000000000-0/100000000000000000000000000000000000000i) (num-test 0 0/100000000000000000000000000000000000000000000000000000000000000+0/100000000000000000000000000000000000000000000000000000000000000i) (num-test 0 0/100000000000000000000000000000000000000000000000000000000000000000000-0/100000000000000000000000000000000000000000000000000000000000000000000i) (num-test 0 0+0/1000000000i) (num-test 0 0-0/100000000000000000000000000000000000000i) (num-test 0 0+0/100000000000000000000000000000000000000000000000000000000000000i) (num-test 0 0-0/100000000000000000000000000000000000000000000000000000000000000000000i) (num-test 0 0/1000000000+0i) (num-test 0 0/100000000000000000000000000000000000000-0i) (num-test 0 0/100000000000000000000000000000000000000000000000000000000000000+0i) (num-test 0 0/100000000000000000000000000000000000000000000000000000000000000000000-0i) (when with-bignums (test (< 0 1000000000000000000000000000000000) #t) (test (> 0 -1000000000000000000000000000000000) #t)) #| ;;; are these worth fixing? :(* 0 1000000000000000000000000000000000) nan.0 :(* 0.0 1000000000000000000000000000000000) nan.0 :(integer? 1000000000000000000000000000000000) #f :(positive? 1/1000000000000000000000000000000000) #f :(exact? 1/1000000000000000000000000000000000) #f :(floor 1/1000000000000000000000000000000000) ;floor argument 1, nan.0, is out of range (argument is NaN) etc.... 10000000000000000000000000000/10000000000000000000000000000 |# (test (equal? 0.0 0.0e10) #t) (test (equal? 0.0 0e100) #t) (test (equal? 0.0 0.0e1000) #t) (test (equal? 0.0 0e+1000) #t) (test (equal? 0.0 0.0e-1) #t) (test (equal? 0.0 0e-10) #t) (test (equal? 0.0 0.0e-100) #t) (test (equal? 0.0 0e-1000) #t) (test (equal? 0.0 0.0e0123456789) #t) (test (equal? 0.0 0-0e10i) #t) (test (equal? 0.0 0-0.0e100i) #t) (test (equal? 0.0 0-0e1000i) #t) (test (equal? 0.0 0-0.0e+1000i) #t) (test (equal? 0.0 0-0e-1i) #t) (test (equal? 0.0 0-0.0e-10i) #t) (test (equal? 0.0 0-0e-100i) #t) (test (equal? 0.0 0-0.0e-1000i) #t) (test (equal? 0.0 0.0+0e0123456789i) #t) (num-test 0.0 1e-1000) (num-test 0e123412341231231231231231231231231231 0.0) (num-test 0e-123412341231231231231231231231231231 0.0) (num-test 0.00000e123412341231231231231231231231231231 0.0) (num-test .0e-123412341231231231231231231231231231 0.0) (num-test 2e-123412341231231231231 0.0) (num-test 2e-123412341231231231231231231231231231 0.0) (num-test 2.001234e-123412341231231231231 0.0) (num-test .00122e-123412341231231231231231231231231231 0.0) (num-test 2e00000000000000000000000000000000000000001 20.0) (num-test 2e+00000000000000000000000000000000000000001 20.0) (num-test 2e-00000000000000000000000000000000000000001 0.2) (num-test 2e-9223372036854775807 0.0) (num-test 2000.000e-9223372036854775807 0.0) (if (not with-bignums) (begin (test (infinite? 2e123412341231231231231) #t) (test (infinite? 2e12341234123123123123123123) #t) (test (infinite? 2e12341234123123123123213123123123) #t) (test (infinite? 2e9223372036854775807) #t) )) (if (provided? 'dfls-exponents) (begin (test (> 1.0L10 1.0e9) #t) (test (> 1.0l10 1.0e9) #t) (test (> 1.0s10 1.0e9) #t) (test (> 1.0S10 1.0e9) #t) (test (> 1.0d10 1.0e9) #t) (test (> 1.0D10 1.0e9) #t) (test (> 1.0f10 1.0e9) #t) (test (> 1.0F10 1.0e9) #t) (test (> (real-part 1.0L10+i) 1.0e9) #t) (test (> (real-part 1.0l10+i) 1.0e9) #t) (test (> (real-part 1.0s10+i) 1.0e9) #t) (test (> (real-part 1.0S10+i) 1.0e9) #t) (test (> (real-part 1.0d10+i) 1.0e9) #t) (test (> (real-part 1.0D10+i) 1.0e9) #t) (test (> (real-part 1.0f10+i) 1.0e9) #t) (test (> (real-part 1.0F10+i) 1.0e9) #t) (test (> (imag-part 1.0+1.0L10i) 1.0e9) #t) (test (> (imag-part 1.0+1.0l10i) 1.0e9) #t) (test (> (imag-part 1.0+1.0s10i) 1.0e9) #t) (test (> (imag-part 1.0+1.0S10i) 1.0e9) #t) (test (> (imag-part 1.0+1.0d10i) 1.0e9) #t) (test (> (imag-part 1.0+1.0D10i) 1.0e9) #t) (test (> (imag-part 1.0+1.0f10i) 1.0e9) #t) (test (> (imag-part 1.0+1.0F10i) 1.0e9) #t) (test (> (string->number "1.0L10") 1.0e9) #t) (test (> (string->number "1.0l10") 1.0e9) #t) (test (> (string->number "1.0s10") 1.0e9) #t) (test (> (string->number "1.0S10") 1.0e9) #t) (test (> (string->number "1.0d10") 1.0e9) #t) (test (> (string->number "1.0D10") 1.0e9) #t) (test (> (string->number "1.0f10") 1.0e9) #t) (test (> (string->number "1.0F10") 1.0e9) #t) (test (> (real-part (string->number "1.0L10+i")) 1.0e9) #t) (test (> (real-part (string->number "1.0l10+i")) 1.0e9) #t) (test (> (real-part (string->number "1.0s10+i")) 1.0e9) #t) (test (> (real-part (string->number "1.0S10+i")) 1.0e9) #t) (test (> (real-part (string->number "1.0d10+i")) 1.0e9) #t) (test (> (real-part (string->number "1.0D10+i")) 1.0e9) #t) (test (> (real-part (string->number "1.0f10+i")) 1.0e9) #t) (test (> (real-part (string->number "1.0F10+i")) 1.0e9) #t) (test (> (imag-part (string->number "1.0+1.0L10i")) 1.0e9) #t) (test (> (imag-part (string->number "1.0+1.0l10i")) 1.0e9) #t) (test (> (imag-part (string->number "1.0+1.0s10i")) 1.0e9) #t) (test (> (imag-part (string->number "1.0+1.0S10i")) 1.0e9) #t) (test (> (imag-part (string->number "1.0+1.0d10i")) 1.0e9) #t) (test (> (imag-part (string->number "1.0+1.0D10i")) 1.0e9) #t) (test (> (imag-part (string->number "1.0+1.0f10i")) 1.0e9) #t) (test (> (imag-part (string->number "1.0+1.0F10i")) 1.0e9) #t) (if with-bignums (begin (test (> (string->number "1.0L100") 1.0e98) #t) (test (> (string->number "1.0l100") 1.0e98) #t) (test (> (string->number "1.0s100") 1.0e98) #t) (test (> (string->number "1.0S100") 1.0e98) #t) (test (> (string->number "1.0d100") 1.0e98) #t) (test (> (string->number "1.0D100") 1.0e98) #t) (test (> (string->number "1.0f100") 1.0e98) #t) (test (> (string->number "1.0F100") 1.0e98) #t) (test (> (string->number "1.0E100") 1.0e98) #t) (test (> 1.0L100 1.0e98) #t) (test (> 1.0l100 1.0e98) #t) (test (> 1.0s100 1.0e98) #t) (test (> 1.0S100 1.0e98) #t) (test (> 1.0d100 1.0e98) #t) (test (> 1.0D100 1.0e98) #t) (test (> 1.0f100 1.0e98) #t) (test (> 1.0F100 1.0e98) #t) (test (> (real-part (string->number "1.0L100+i")) 1.0e98) #t) (test (> (real-part (string->number "1.0l100+i")) 1.0e98) #t) (test (> (real-part (string->number "1.0s100+i")) 1.0e98) #t) (test (> (real-part (string->number "1.0S100+i")) 1.0e98) #t) (test (> (real-part (string->number "1.0d100+i")) 1.0e98) #t) (test (> (real-part (string->number "1.0D100+i")) 1.0e98) #t) (test (> (real-part (string->number "1.0f100+i")) 1.0e98) #t) (test (> (real-part (string->number "1.0F100+i")) 1.0e98) #t) (test (> (real-part 1.0L100+i) 1.0e98) #t) (test (> (real-part 1.0l100+i) 1.0e98) #t) (test (> (real-part 1.0s100+i) 1.0e98) #t) (test (> (real-part 1.0S100+i) 1.0e98) #t) (test (> (real-part 1.0d100+i) 1.0e98) #t) (test (> (real-part 1.0D100+i) 1.0e98) #t) (test (> (real-part 1.0f100+i) 1.0e98) #t) (test (> (real-part 1.0F100+i) 1.0e98) #t) (test (> (imag-part (string->number "1.0+1.0L100i")) 1.0e98) #t) (test (> (imag-part (string->number "1.0+1.0l100i")) 1.0e98) #t) (test (> (imag-part (string->number "1.0+1.0s100i")) 1.0e98) #t) (test (> (imag-part (string->number "1.0+1.0S100i")) 1.0e98) #t) (test (> (imag-part (string->number "1.0+1.0d100i")) 1.0e98) #t) (test (> (imag-part (string->number "1.0+1.0D100i")) 1.0e98) #t) (test (> (imag-part (string->number "1.0+1.0f100i")) 1.0e98) #t) (test (> (imag-part (string->number "1.0+1.0F100i")) 1.0e98) #t) (test (> (imag-part 1.0+1.0L100i) 1.0e98) #t) (test (> (imag-part 1.0+1.0l100i) 1.0e98) #t) (test (> (imag-part 1.0+1.0s100i) 1.0e98) #t) (test (> (imag-part 1.0+1.0S100i) 1.0e98) #t) (test (> (imag-part 1.0+1.0d100i) 1.0e98) #t) (test (> (imag-part 1.0+1.0D100i) 1.0e98) #t) (test (> (imag-part 1.0+1.0f100i) 1.0e98) #t) (test (> (imag-part 1.0+1.0F100i) 1.0e98) #t) )))) (if (and with-bignums (not pure-s7)) (begin (test (number? (string->number "#e1.0e564")) #t) (test (number? (string->number "#e1.0e307")) #t) (test (number? (string->number "#e1.0e310")) #t) (num-test (string->number "#e1624540914719833702142058941") 1624540914719833702142058941) (num-test (string->number "#i1624540914719833702142058941") 1.624540914719833702142058941E27) (num-test (string->number "#e8978167593632120808315265/5504938256213345873657899") 8978167593632120808315265/5504938256213345873657899) (num-test (string->number "#i8978167593632120808315265/5504938256213345873657899") 1.630929753571457437099527114342760854299E0) (num-test (string->number "#i119601499942330812329233874099/12967220607") 9.223372036854775808414213562473095048798E18) ;; this next test needs more bits to compare with other schemes -- this is the result if 128 bits (num-test (string->number "#e005925563891587147521650777143.74135805596e05") 826023606487248364518118333837545313/1394) (num-test (string->number "#e-1559696614.857e28") -15596966148570000000000000000000000000) (test (integer? (string->number "#e1e310")) #t) (test (number? (string->number "#e1.0e310")) #t) )) ;; in the non-gmp case #e1e321 is a read error -- should s7 return NaN silently? (when (and (not with-bignums) (not pure-s7)) (test (string->number "#e1e307") #f) (test (eval-string "(number? #e1.0e564)") 'error) (test (string->number "#e005925563891587147521650777143.74135805596e05") #f) (test (string->number "#e78.5e65") #f) (test (string->number "#e1e543") #f) (test (string->number "#e120d21") #f) (test (string->number "#e-2.2e021") #f) (if (provided? '@-exponent) (test (infinite? (string->number "9221.@9129" 10)) #t)) (test (string->number "#e120@21" 12) #f) (test (string->number "#d#e120@21") #f) (test (string->number "#b#e120@21") #f) (test (string->number "#e#b120@21") #f) (test (string->number "#e#d120@21") #f) (test (nan? (string->number "0f0/00" 16)) #t) (test (string->number "#e-1559696614.857e28") #f) (test (string->number "#e1+1i") #f) (test (= 0 00 -000 #e-0 0/1 #e#x0 #b0000 #e#d0.0 -0 +0) #t)) ;; (do ((i 0 (+ i 1)) (n 1 (* n 2))) ((= i 63)) (display n) (display " ") (display (number->string n 16)) (newline)) (test (number->string 3/4 2) "11/100") (test (number->string 3/4 8) "3/4") (test (number->string 3/4 16) "3/4") (test (number->string -3/4 2) "-11/100") (test (number->string -3/4 8) "-3/4") (test (number->string -3/4 16) "-3/4") (num-test (string->number "1/2") 1/2) (test (nan? (string->number "1/0")) #t) (test (nan? (string->number "0/0")) #t) (test (nan? 0/0) #t) (test (string->number "1.0/0.0") #f) (test (string->number "'1") #f) (test (string->number "`1") #f) (test (string->number ".@0") #f) (test (string->number "+.@0") #f) (test (string->number "+.-i") #f) (test (string->number "+.-0i") #f) (num-test (string->number "10111/100010" 2) 23/34) (num-test (string->number "27/42" 8) 23/34) (num-test (string->number "17/22" 16) 23/34) (num-test (string->number "-10111/100010" 2) -23/34) (num-test (string->number "-27/42" 8) -23/34) (num-test (string->number "-17/22" 16) -23/34) (num-test (string->number "11/100" 2) 3/4) (test (number->string 23/34 2) "10111/100010") (test (number->string 23/34 8) "27/42") (test (number->string 23/34 16) "17/22") (test (number->string -23/34 2) "-10111/100010") (test (number->string -23/34 8) "-27/42") (test (number->string -23/34 16) "-17/22") (test (number->string -1 16) "-1") ;(test (number->string #xffffffffffffffff 16) "-1") -- is this a bug? (when (not with-bignums) ;(test (= #xffffffffffffffff -1) #t) ; this is an overflow (test (= #x8000000000000000 -9223372036854775808) #t)) (test (= #x7fffffffffffffff 9223372036854775807) #t) (test (number->string 9223372036854775807 16) "7fffffffffffffff") (test (number->string -9223372036854775808 16) "-8000000000000000") (test (number->string #o777777777777777777777) "9223372036854775807") (when (not with-bignums) (test (number->string #o1000000000000000000000) "-9223372036854775808") (test (number->string #b1000000000000000000000000000000000000000000000000000000000000000) "-9223372036854775808")) (num-test (string->number "3/4+1/2i") 0.75+0.5i) (num-test (string->number "3/4+i") 0.75+i) (num-test (string->number "0+1/2i") 0+0.5i) (test (string->number "3+0i/4") #f) (num-test (string->number "3/4+0i") 0.75) (test (string->number " 1.0") #f) (test (string->number "1.0 ") #f) (test (string->number "1.0 1.0") #f) ;(test (string->number (string #\1 (integer->char 0) #\0)) 1) ; ?? Guile returns #f (test (string->number "1+1 i") #f) (test (string->number "1+ei") #f) (test (string->number " #b1") #f) (test (string->number "#b1 ") #f) (test (string->number "#b1 1") #f) (test (string->number "#b 1") #f) (test (string->number "# b1") #f) (test (string->number "#b12") #f) (test (string->number "000+1") #f) (test (string->number (string (integer->char 216))) #f) ; slashed 0 (test (string->number (string (integer->char 189))) #f) ; 1/2 as single char (test (string->number (string #\1 (integer->char 127) #\0)) #f) ; backspace (test (string->number "1\ 2") 12) (test (string->number "1E1") 10.0) (test (string->number "1e1") 10.0) (if (provided? 'dfls-exponents) (begin (test (string->number "1D1") 10.0) (test (string->number "1S1") 10.0) (test (string->number "1F1") 10.0) (test (string->number "1L1") 10.0) (test (string->number "1d1") 10.0) (test (string->number "1s1") 10.0) (test (string->number "1f1") 10.0) (test (string->number "1l1") 10.0))) (num-test (string->number "1234567890123456789012345678901234567890.123456789e-30") 1234567890.1235) (num-test (string->number "123456789012345678901234567890123456789012345678901234567890.123456789e-50") 1234567890.1235) (num-test (- 1234567890123456789012345678901234567890123456789012345678901234567890.123456789e-60 12345678901234567890123456789012345678901234567890.123456789e-40) 0.0) (num-test (string->number "#b000100111110110010011010100001.10111010011000100e1" 2) 167136579.45612) (num-test (string->number "000100111110110010011010100001.10111010011000100e1" 2) 167136579.45612) (num-test (string->number "#b1010100100110001111001001100101010011111010100110110.00011001001011101111101111111000110100100111011100100e-59") 5.163418497654431203689554326589836167902E-3) (num-test (string->number "#b01010011000101001010000101011001111110000010110010.1000000000111001011010110110011111101011100000100e-3") 4.567403573967031260951910866285885504112E13) (num-test 0000000000000000000000000001.0 1.0) (num-test 1.0000000000000000000000000000 1.0) (num-test 1000000000000000000000000000.0e-40 1.0e-12) (num-test 0.0000000000000000000000000001e40 1.0e12) (num-test 1.0e00000000000000000001 10.0) (num-test 12341234.56789e12 12341234567889999872.0) (num-test -1234567890123456789.0 -1234567890123456768.0) (num-test 12345678901234567890.0 12345678901234567168.0) (num-test 123.456e30 123456000000000012741097792995328.0) (num-test 12345678901234567890.0e12 12345678901234569054409354903552.0) (num-test 1.234567890123456789012e30 1234567890123456849145940148224.0) (num-test 1e20 100000000000000000000.0) (num-test 1234567890123456789.0 1234567890123456768.0) (num-test 123.456e16 1234560000000000000.0) (num-test 98765432101234567890987654321.0e-5 987654321012345728401408.0) (num-test 98765432101234567890987654321.0e-10 9876543210123456512.0) (num-test 0.00000000000000001234e20 1234.0) (num-test 0.000000000000000000000000001234e30 1234.0) (num-test 0.0000000000000000000000000000000000001234e40 1234.0) (num-test 0.000000000012345678909876543210e15 12345.678909877) (num-test 98765432101234567890987654321.0e-20 987654321.012346) (num-test 98765432101234567890987654321.0e-29 0.98765432101235) (num-test 98765432101234567890987654321.0e-30 0.098765432101235) (num-test 98765432101234567890987654321.0e-28 9.8765432101235) (num-test 1.0123456789876543210e1 10.12345678987654373771) (num-test 1.0123456789876543210e10 10123456789.87654304504394531250) (num-test 0.000000010000000000000000e10 100.0) (num-test 0.000000010000000000000000000000000000000000000e10 100.0) (num-test 0.000000012222222222222222222222222222222222222e10 122.22222222222222) (num-test 0.000000012222222222222222222222222222222222222e17 1222222222.222222) (num-test (- (string->number "769056139124082.") (string->number "769056139124080.")) 2.0) (num-test (string->number "0000000000000000000000000001.0") 1.0) (num-test (string->number "1.0000000000000000000000000000") 1.0) (num-test (string->number "1000000000000000000000000000.0e-40") 1.0e-12) (num-test (string->number "0.0000000000000000000000000001e40") 1.0e12) (num-test (string->number "1.0e00000000000000000001") 10.0) (num-test (string->number "12341234.56789e12") 12341234567889999872.0) (num-test (string->number "-1234567890123456789.0") -1234567890123456768.0) (num-test (string->number "12345678901234567890.0") 12345678901234567168.0) (num-test (string->number "123.456e30") 123456000000000012741097792995328.0) (num-test (string->number "12345678901234567890.0e12") 12345678901234569054409354903552.0) (num-test (string->number "1.234567890123456789012e30") 1234567890123456849145940148224.0) (num-test (string->number "1e20") 100000000000000000000.0) (num-test (string->number "1234567890123456789.0") 1234567890123456768.0) (num-test (string->number "123.456e16") 1234560000000000000.0) (num-test (string->number "98765432101234567890987654321.0e-5") 987654321012345728401408.0) (num-test (string->number "98765432101234567890987654321.0e-10") 9876543210123456512.0) (num-test (string->number "0.00000000000000001234e20") 1234.0) (num-test (string->number "0.000000000000000000000000001234e30") 1234.0) (num-test (string->number "0.0000000000000000000000000000000000001234e40") 1234.0) (num-test (string->number "0.000000000012345678909876543210e15") 12345.678909877) (num-test (string->number "98765432101234567890987654321.0e-20") 987654321.012346) (num-test (string->number "98765432101234567890987654321.0e-29") 0.98765432101235) (num-test (string->number "98765432101234567890987654321.0e-30") 0.098765432101235) (num-test (string->number "98765432101234567890987654321.0e-28") 9.8765432101235) (num-test (string->number "1.0123456789876543210e1") 10.12345678987654373771) (num-test (string->number "1.0123456789876543210e10") 10123456789.87654304504394531250) (num-test (string->number "0.000000010000000000000000e10") 100.0) (num-test (string->number "0.000000010000000000000000000000000000000000000e10") 100.0) (num-test (string->number "0.000000012222222222222222222222222222222222222e10") 122.22222222222222) (num-test (string->number "0.000000012222222222222222222222222222222222222e17") 1222222222.222222) (num-test (string->number "1.1001001000011111101101010100010001000010110100010011" 2) 1.5707963267949) (num-test #x0000000000000000000000000001.0 1.0) (num-test #x1.0000000000000000000000000000 1.0) ;(test (number->string 1222222222.222222 16) "48d9a18e.38e38c") (num-test (string->number (number->string 1222222222.222222222222222222 16) 16) 1222222222.222222222222222222) (if with-bignums (num-test (string->number "179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.0") 179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.0) (num-test (string->number "179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.0") 1.7976931348623e+308)) (when with-bignums (num-test (string->number (number->string (bignum "12345.67890987654321") 2) 2) 12345.67890987654321) (test (number->string 1234.5678909876543212345 16) "4.d291614dc3ab1f80e55a563311b8f308@2") (test (number->string -1234.5678909876543212345 16) "-4.d291614dc3ab1f80e55a563311b8f308@2") (test (number->string 1234.5678909876543212345e8 16) "1.cbe991a6ac3f35c11868cb7e3fb75536@9") (test (number->string 1234.5678909876543212345e-8 16) "c.f204983a27e1eff701c562a870641e5@-5") (test (number->string 123456789098765432.12345e-8 16) "4.99602d2fcd6e9e1748ba5adccc12c5a8@7") (test (number->string 123456789098765432.1e20 16) "9.49b0f70beeac8895e74b18b968@30")) (num-test (string->number "12345678900000000000.0") 1.23456789e+19) (num-test (string->number "1234567890000000000000000000000000000000000000000000000000000000000000.0") 1.23456789e+69) (num-test (string->number "1234567890000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0") 1.23456789e+129) (num-test (string->number "1.1e4" 5) 750.0) (num-test (string->number "1.1e4" 4) 320.0) (num-test (string->number "1.1e4" 3) 108.0) (num-test (string->number "1.1e4" 2) 24.0) (num-test #b111111111111111111111111111111111111111111111111111111111111111 most-positive-fixnum) (num-test #o777777777777777777777 most-positive-fixnum) (num-test #x7fffffffffffffff most-positive-fixnum) (num-test #d9223372036854775807 most-positive-fixnum) (num-test #d-9223372036854775808 most-negative-fixnum) (num-test #o-1000000000000000000000 most-negative-fixnum) (num-test #x-8000000000000000 most-negative-fixnum) (num-test #b-1000000000000000000000000000000000000000000000000000000000000000 most-negative-fixnum) (test (number->string 1.0 most-negative-fixnum) 'error) (test (number->string 1.0 most-positive-fixnum) 'error) (test (string->number "1.0" most-negative-fixnum) 'error) (test (string->number "1.0" most-positive-fixnum) 'error) (test (number->string 16 17) 'error) (test (number->string -0. 11 -) 'error) (test (string->number "11" 2 -) 'error) (test (string->number "1.0F") #f) (test (string->number "1F") #f) (test (string->number "1d") #f) (test (string->number "1.0L") #f) (test (string->number "1.0+1.0Ei") #f) (test (string->number "0xff") #f) ;; duplicate various non-digit chars (for-each (lambda (str) (test (string->number str) #f)) (list "..1" "1.." "1..2" "++1" "+-1" "-+1" "--1" "-..1" "+..1" "1+i+" "1+i." "1++i" "1--i" "1.ee1" "1+1..i" "1+ii" "1+1ee1i" "1e1e1" "1+2i.i" "1//2" "1+.1/2i" "1+1//2i" "1+1/2" "1i" "1ii" "1+.i" "1+..i")) (test (number->string most-positive-fixnum 2) "111111111111111111111111111111111111111111111111111111111111111") (test (number->string most-positive-fixnum 8) "777777777777777777777") (test (number->string most-positive-fixnum 16) "7fffffffffffffff") (test (number->string most-positive-fixnum 10) "9223372036854775807") (test (number->string most-negative-fixnum 10) "-9223372036854775808") (test (number->string most-negative-fixnum 8) "-1000000000000000000000") (test (number->string most-negative-fixnum 16) "-8000000000000000") (test (number->string most-negative-fixnum 2) "-1000000000000000000000000000000000000000000000000000000000000000") (test (string->number "111111111111111111111111111111111111111111111111111111111111111" 2) most-positive-fixnum) (test (string->number "777777777777777777777" 8) most-positive-fixnum) (test (string->number "7fffffffffffffff" 16) most-positive-fixnum) (test (string->number "9223372036854775807" 10) most-positive-fixnum) (test (string->number "-9223372036854775808" 10) most-negative-fixnum) (test (string->number "-1000000000000000000000" 8) most-negative-fixnum) (test (string->number "-8000000000000000" 16) most-negative-fixnum) (test (string->number "-1000000000000000000000000000000000000000000000000000000000000000" 2) most-negative-fixnum) (test (string->number (string #\1 #\. #\0 (integer->char 128) #\1)) #f) (test (string->number (string #\1 #\. #\0 (integer->char 20) #\1)) #f) (test (string->number (string #\1 #\. #\0 (integer->char 200) #\1)) #f) (test (string->number (string #\1 #\. #\0 (integer->char 255) #\1)) #f) (test (string->number (string #\1 #\. #\0 (integer->char 2) #\1)) #f) (test (string->number (string #\1 #\. (integer->char 128) #\1)) #f) (test (string->number (string #\1 #\. (integer->char 20) #\1)) #f) (test (string->number (string #\1 #\. (integer->char 200) #\1)) #f) (test (string->number (string #\1 #\. (integer->char 255) #\1)) #f) (test (string->number (string #\1 #\. (integer->char 2) #\1)) #f) (test (string->number (string #\1 (integer->char 128) #\1)) #f) (test (string->number (string #\1 (integer->char 20) #\1)) #f) (test (string->number (string #\1 (integer->char 200) #\1)) #f) (test (string->number (string #\1 (integer->char 255) #\1)) #f) (test (string->number (string #\1 (integer->char 2) #\1)) #f) (test (string->number (string (integer->char 128) #\1)) #f) (test (string->number (string (integer->char 20) #\1)) #f) (test (string->number (string (integer->char 200) #\1)) #f) (test (string->number (string (integer->char 255) #\1)) #f) (test (string->number (string (integer->char 2) #\1)) #f) (test (string->number (string (integer->char 128) #\/ #\2)) #f) (test (string->number (string (integer->char 20) #\/ #\2)) #f) (test (string->number (string (integer->char 200) #\/ #\2)) #f) (test (string->number (string (integer->char 255) #\/ #\2)) #f) (test (string->number (string (integer->char 2) #\/ #\2)) #f) (do ((i 103 (+ i 1))) ((= i 256)) (test (string->number (string (integer->char i))) #f) (test (string->number (string (integer->char i) #\. #\0)) #f)) (test (string->number "1,000") #f) (test (string->number "1 000") #f) (test (string->number "1 / 2") #f) (test (string->number "1 .2") #f) (test (string->number "1:") #f) (test (string->number "#b 1") #f) #| (do ((i 20 (+ i 1))) ((= i 128)) (let ((str (string-append "#" (string (integer->char i)) "1.0e8"))) (catch #t (lambda () (let ((val (eval-string str))) (format-logged #t "~A -> ~S~%" str val))) (lambda args 'error)))) |# (num-test #b1.0e8 256.0) (num-test #o1.0e8 16777216.0) (num-test #d1.0e8 100000000.0) (num-test #x1.0e8 1.056640625) ; e is a digit (num-test #e1.0e8 100000000) (num-test #i1.0e8 100000000.0) (if with-bignums (num-test #b1.1111111111111111111111111111111111111111111111111110011101010100100100011001011011111011000011001110110101010011110011000100111E1023 1.7976931348623156E308)) (test (number->string 1/9 2) "1/1001") (test (number->string -11/4 2) "-1011/100") (test (number->string -11/4 8) "-13/4") (test (number->string -15/4 16) "-f/4") (test (string->number "f/4" 16) 15/4) (test (string->number "#b'0") #f) (test (string->number "#b0/0") #f) (test (string->number "#b-1/0") #f) (test (string->number "1e1/2") #f) (test (string->number "1e#b0") #f) (test (string->number "#B0") #f) (test (string->number "0+I") #f) (when (not pure-s7) (test (string->number "#b#i0/0") #f) (test (string->number "#b#e0/0") #f) (test (string->number "#b#e1/0+i") #f) ; inf+i? (test (string->number "#e#b0/0") #f) (test (string->number "#i#b0/0") #f) (test (string->number "#e0/0") #f) (test (number? (string->number "#i0/0")) #t) ; nan since (number? 0/0) is #t (test (string->number "#e#b1/0") #f) (test (string->number "#i#b1/0") #f) (test (string->number "#e1/0") #f) (test (number? (string->number "#i1/0")) #t) (test (string->number "#e#b1/0+i") #f) (test (string->number "#i#b1/0+i") #f) ; inf+i? (test (string->number "#e1/0+i") #f) (test (number? (string->number "#i1/0+i")) #t) (test (number? (string->number "#i0/0+i")) #t) (test (nan? #i0/0) #t) ; but #i#d0/0 is a read error? (num-test (string->number "#b#e11e30") 3221225472) ; very confusing! (num-test (string->number "#b#i11e30") 3221225472.0) (num-test (string->number "#e#b11e30") 3221225472) (num-test (string->number "#i#b11e30") 3221225472.0) (num-test (string->number "#b#e+1e+1+0e+10i") 2) (num-test (string->number "#e+.0e-00-0i") 0) (num-test (string->number "#e-0/1110010") 0) (num-test (string->number "#x#e00110e") 4366) (num-test (string->number "#e#x-e/001") -14) (num-test (string->number "#e.001e-11") 0) (num-test (string->number "#x#e00/00e") 0) (num-test (string->number "#e#x+1e.01e10100") 65366158/2178339) (num-test (string->number "#i#x0e10-000i") 3600.0) (num-test (string->number "#x0/e010-e/1i") 0-14i) (num-test (string->number "#i-1/1-1.0e1i") -1-10i) (num-test (string->number "#e#x001ee11e1") 32379361) (num-test (string->number "#e#x010e10.e1") 17699041/256) (num-test #b#i.110e-1 0.375) (num-test #e01.1e1+00.i 11)) (num-test (string->number "#x10+10i") 16+16i) (num-test 00-10e+001i 0-100i) (num-test (string->number "#x+e/00011ee0") 7/36720) (num-test (string->number "-1.-00.0e+10i") -1.0) (num-test (string->number "#x+1e1.+e10i") 481+3600i) (num-test (string->number "#xe/e+e/ei") 1+1i) (num-test (string->number "1e-0-.11e+1i") 1-1.1i) (num-test (string->number "00.-1.1e-00i") 0-1.1i) (num-test (string->number "+01.e+1+.00i") 10.0) (num-test (string->number "#x1e0/e+0/ei") 34.285714285714) (num-test (string->number "+01e0+00.i") 1.0) (num-test (string->number "+0/0100+0i") 0.0) (num-test (string->number "#x-e1e/eee") -139/147) (num-test (string->number "#x-0101.+00/11i") -257.0) (num-test (string->number "#x+ee.-e00e0110i") 238-3759014160i) (num-test (string->number "#x-e0/1ee") -112/247) (if (provided? 'dfls-exponents) (begin (num-test (string->number "#d.0d1+i") 0+1i) (num-test (string->number "+.0d-1+i") 0+1i) (num-test (string->number "#d1d+0-1d-1i") 1-0.1i) (num-test (string->number "#i+1+0.d-0i") 1.0) (num-test (string->number "#o#i-101d+0") -65.0) (num-test (string->number "+001.110d+1") 11.1) (num-test (string->number "#e01+0d000i") 1) (num-test (string->number "#d1d0-0.d0i") 1.0) (num-test (string->number "#d#i001d+00") 1.0) (num-test (string->number "#o0010111/1") 4169) (num-test (string->number "0d00-0.d+0i") 0.0) (num-test (string->number "#o1.d0+10.d00i") 1+8i) (num-test (string->number "0d+01+1e+1i") 0+10i) (num-test (string->number "10.d-005" 2) 0.0625) (num-test (string->number "+7f2-73i" 8) 448-59i) )) (num-test (string->number "#e#d+11.e-0") 11) (num-test (string->number "#d.0e011110") 0.0) (num-test (string->number "+01e01+0/1i") 10.0) (num-test (string->number "#i#d1e1+.0i") 10.0) (num-test (string->number "1.-0.0e+00i") 1.0) (when (not pure-s7) (test (string->number "#o#e10.+1.i") #f) (test (string->number "#x#e1+i") #f) (test (string->number "#x#1+#e1i") #f) (test (string->number "#x#e1+#e1i") #f) (test (string->number "#b#e1+i") #f) (test (string->number "#o#e1-110.i") #f) (num-test (string->number "#e1+0i") 1) (num-test (string->number "#x#e1+0i") 1) (num-test (string->number "#e#x1+0i") 1)) (num-test (string->number "#x1/7e2") 1/2018) (num-test (string->number "0.1e00" 2) 0.5) (num-test (string->number "10.101" 2) 2.625) (num-test (string->number "0e1010" 2) 0.0) (num-test (string->number ".1e010" 2) 512.0) (num-test (string->number "1/000100" 2) 1/4) (num-test (string->number "1000e+03" 2) 64.0) (num-test (string->number "-1e+1-1i" 2) -2-1i) (num-test (string->number ".1-110e03i" 2) 0.5-48i) (num-test (string->number "1e9" 2) 512.0) (num-test (string->number "52/7" 8) 6) (num-test (string->number "130." 8) 88.0) (num-test (string->number "121.-16i" 8) 81-14i) (num-test (string->number "12/15150" 8) 1/676) (num-test (string->number "612444175735" 8) 52958395357) (num-test (string->number "31005331+.4i" 8) 6556377+0.5i) (num-test (string->number "42220e-2" 8) 274.25) (num-test (string->number "1e9" 8) 134217728.0) (test (string->number "1e9" 12) #f) ; this may not be ideal... (num-test (string->number "1b9/64" 12) 15/4) (num-test (string->number "a880+i" 12) 18528+1i) (num-test (string->number "dc-i" 16) 220-1i) (num-test (string->number "dcd-fi" 16) 3533-15i) (num-test (string->number "d/ebee" 16) 1/4646) (num-test (string->number "a.d-ci" 16) 10.8125-12i) (num-test (string->number "fac/ed" 16) 4012/237) (num-test (string->number "-ccdebef.a" 16) -214821871.625) (num-test (string->number "+dfefc/c" 16) 76437) (num-test (string->number "acd/eabf" 16) 79/1717) (num-test (string->number "-1e-1-1e-1i") -0.1-0.1i) (num-test (string->number "+1e+1+1e+1i") 10+10i) (when (not pure-s7) (num-test (string->number "#i#d+1e+1+1e+1i") 10+10i) (test (string->number "#e+1e+1+1e+1i") #f) ;; these depend on rationalize's default error I think ;; and they cause valgrind to hang!! ;;(num-test (string->number "#e.1e-11") 0) ;;(num-test (string->number "#e1e-12") 0) (num-test (string->number "#e1e-11") 1/90909090910) (test (string->number "#e#f1") #f) (if with-bignums (begin (test (= (string->number "#e1e19") (string->number "#e.1e20")) #t) (test (= (string->number "#e1e19") (* 10 (string->number "#e1e18"))) #t) (test (= (string->number "#e1e20") (* 100 (string->number "#e1e18"))) #t))) (test (= #i1e19 #i.1e20) #t)) (test (= 1e19 .1e20) #t) (test (string->number "15+b7a9+8bbi-95+4e" 16) #f) (num-test (string->number "776.0a9b863471095a93" 12) 1098.0752175102) (num-test (string->number "a72972b301/398371448" 12) 54708015601/1637213240) (num-test (string->number "+ac946/b72ddf4847ce6" 16) 353443/1611261179739763) (num-test (string->number "b85.361c23cec099e742" 15) 2600.2272029731) (num-test (string->number "ade2411.a1422432dea8" 15) 1.24494541672338806082296187159063753079E8) (num-test (string->number "da99007963b182/8a66b" 15) 26681038227104972/440201) (num-test (string->number "74cc.d+b44.02a11ee5i" 15) 24717.866666667+2539.0118742348i) (num-test (string->number "d+7a5d40di" 14) 13+58313541i) (test (nan? (string->number "1/0")) #t) (test (nan? (string->number "5639d72702b62527/0" 14)) #t) (test (nan? (string->number "-28133828f9421ef5/0" 16)) #t) (test (nan? (string->number "+4a11654f7e00d5f2/0" 16)) #t) (when (and with-bignums (not pure-s7)) (test (number->string (/ most-positive-fixnum most-negative-fixnum) 2) "-111111111111111111111111111111111111111111111111111111111111111/1000000000000000000000000000000000000000000000000000000000000000") (test (string->number "-111111111111111111111111111111111111111111111111111111111111111/1000000000000000000000000000000000000000000000000000000000000000" 2) -9223372036854775807/9223372036854775808) (num-test (string->number "#b#e-11e+111") -7788445287802241442795744493830144) (num-test (string->number "#i#b-11e+111") -7.788445287802241442795744493830144E33) (num-test (string->number "#b#i-11e+111") -7.788445287802241442795744493830144E33) (num-test (string->number "#i3e+111") 3.0e111) (num-test (string->number "#e3e30") 3000000000000000000000000000000) (num-test (string->number "#i3e30") 3.000E30) (num-test (string->number "#b#e11e80") 3626777458843887524118528) (num-test (string->number "#b#i11e80") 3626777458843887524118528.0) (num-test (string->number "#e#b11e80") 3626777458843887524118528) (num-test (string->number "#i#b11e80") 3626777458843887524118528.0) (num-test (string->number "b2706b3d3e8e46ad5aae" 15) 247500582888444441302414) (num-test (string->number "ceec932122d7c22289da9144.4b7836de0a2f5ef" 16) 6.403991331575236168367699181229480307503E28) (num-test (string->number "c23177c20fb1296/fcf15a82c8544613721236e2" 16) 437284287268358475/39141000511500755277510679409) (num-test (string->number "775f81b8fee51b723f" 16) 2202044529881940455999) (num-test (string->number "5d9eb6d6496f5c9b6e" 16) 1726983762769631550318) (num-test (string->number "+775f81b8fee51b723f" 16) 2202044529881940455999) (num-test (string->number "+5d9eb6d6496f5c9b6e" 16) 1726983762769631550318) (num-test (string->number "-775f81b8fee51b723f" 16) -2202044529881940455999) (num-test (string->number "-5d9eb6d6496f5c9b6e" 16) -1726983762769631550318) (num-test (string->number "+d053d635e581a5c4/d7" 16) 15011577509928084932/215) (num-test (string->number "+a053a635a581a5a4/a7" 16) 11552760218475668900/167) (num-test (string->number "-d053d635e581a5c4/d7" 16) -15011577509928084932/215) (num-test (string->number "-a053a635a581a5a4/a7" 16) -11552760218475668900/167) (num-test (string->number "+6/a47367025481df6c8" 16) 1/31599808811326133196) (num-test (string->number "d053d635e581a5c4/d7" 16) 15011577509928084932/215) (num-test (string->number "+074563336d48564b774" 16) 2146033681147780970356) (num-test (string->number "e/4246061597ec79345a" 15) 7/204584420774687563055) (num-test (string->number "c57252467ff.cfd94d" 16) 1.3568424830975811909496784210205078125E13) (num-test (string->number "f309e9b9ba.7c52ff2" 16) 1.043843365306485641427338123321533203125E12) (num-test (string->number "+42e-0106653" 10) 4.199999999999999999999999999999999999999E-106652) (test (infinite? (string->number "8e7290491476" 10)) #t) (num-test (string->number "4ff7da4d/ab09e16255c06a55c5cb7193ebb2fbb" 16) 1341643341/14209330580250438592763227155654717371) (num-test (string->number "#d3000000000000000000000000000000") 3000000000000000000000000000000) (num-test (string->number "#x400000000000000000") (expt 2 70)) (for-each (lambda (op) (if (not (= (op 1e19) (op .1e20))) (format-logged #t ";(~A 1e19) = ~A, but (~A .1e20) = ~A?~%" op (op 1e19) op (op .1e20)))) (list floor ceiling truncate round inexact->exact exact->inexact)) (for-each (lambda (op) (if (not (= (op -1e19) (op -.1e20))) (format-logged #t ";(~A -1e19) = ~A, but (~A -.1e20) = ~A?~%" op (op -1e19) op (op -.1e20)))) (list floor ceiling truncate round inexact->exact exact->inexact))) (num-test #b+01 1) (num-test #b-01 -1) (num-test #d-1/2 -1/2) (num-test #d+1/2 1/2) (num-test #b1.0e-8 0.00390625) (num-test #o1.0e-8 5.9604644775391e-08) (num-test #d1.0e-8 1.0e-8) (num-test #b-.1 -0.5) (num-test #o-.1 -0.125) (num-test #d-.1 -0.1) (num-test #x-.1 -0.0625) (num-test #b+.1 +0.5) (num-test #o+.1 +0.125) (num-test #d+.1 +0.1) (num-test #x+.1 +0.0625) (num-test #b+.1e+1 1.0) (num-test #d+.1e+1 1.0) (num-test #o+.1e+1 1.0) (num-test #b000000001 1) (num-test #b1e1 2.0) (num-test #b1.e1 2.0) (when (not pure-s7) (num-test #b#e-.1 -1/2) (num-test #o#e-.1 -1/8) (num-test #d#e-.1 -1/10) (num-test #x#e-.1 -1/16) (num-test #b#e1.1e2 6) (num-test #o#e1.1e2 72) (num-test #d#e1.1e2 110) (num-test #b#i-1.1e-2 -0.375) (num-test #o#i-1.1e-2 -0.017578125) (num-test #d#i-1.1e-2 -0.011) (num-test #e#b1e-10 1/1024) (num-test #e#b+1.1 3/2) (num-test #e#o+1.1 9/8) (num-test #e#d+1.1 11/10) (num-test #e#x+1.1 17/16) (num-test #e#b+1.1e+2 6) (num-test #e#o+1.1e+2 72) (num-test #e#d+1.1e+2 110) (num-test #i#b.001 0.125) (num-test #i#b000000000011 3.0) (num-test #i#b-000000000011e1 -6.0) (num-test #i#b-000000000011e+11 -6144.0) ;;(num-test #b#e0+i 0+1i) ; these 2 are now read-errors (#e0+i is an error because inexact->exact does not accept complex args in s7) ;;(num-test #b#e0+1.1i 0+1.5i) (test (string->number "#b#e0+i") #f) (num-test #i#xf/c 1.25) (num-test #e#x1.4 5/4) (num-test #e2/3 2/3) (num-test #b#e+.1e+1 1) (num-test #b#e.011-0.i 3/8) (num-test #b#i1.1e0-.0i 1.5) (num-test #b#e1.1e0-.0i 3/2) (num-test #b#e-1.00e+001 -2) (num-test #b#e+.01011100 23/64) (num-test #b#i-00-0/001i 0.0) (num-test #e#x1234/12 (string->number "#x#e1234/12")) (num-test #x#e.1 #e#x.1)) (num-test #e-.0 0) (num-test #e-123.0 -123) (num-test #i-123 -123.0) (num-test #e+123.0 123) (num-test #i+123 123.0) (num-test #i-0 0.0) (num-test #e-0.0 0) ;;; in guile #e1e-10 is 7737125245533627/77371252455336267181195264 (num-test #x-AAF -2735) (num-test #x-aAf -2735) (num-test #b1+1.1i 1+1.5i) ; yow... (num-test #xf/c 5/4) (num-test #x+f/c 5/4) (num-test #x-f/c -5/4) (num-test #d1/2 1/2) ;; nutty: #e+inf.0 #e+nan.0 ;; these don't arise in s7 because we don't define inf.0 and nan.0 (if with-bignums (num-test #e9007199254740995.0 9007199254740995)) (num-test #b0/1 0) ;(test #b0/0 'division-by-zero) ; read-error (num-test #d3/4 3/4) (num-test #o7/6 7/6) (num-test #o11/2 9/2) (num-test #d11/2 11/2) (num-test #x11/2 17/2) (num-test #b111/11 7/3) (num-test #b111111111111111111111111111111111111111111111111111111111111111/111 1317624576693539401) (num-test #d9223372036854775807/7 1317624576693539401) (num-test (* 1317624576693539401 7) most-positive-fixnum) (num-test #o777777777777777777777/7 1317624576693539401) (num-test #x7fffffffffffffff/7 1317624576693539401) (num-test (string->number "#x1234/12") (string->number "1234/12" 16)) (num-test #d#i1/10 #i#d1/10) (test (equal? 0.0 #b0e0) #t) (test (equal? 0.0 #b0e-0) #t) (test (equal? 0.0 #b.0e+0) #t) (test (equal? 0.0 #b00000000000000000000000000000000000000000000000000000e100) #t) (test (equal? 0.0 #b.0000000000000000000000000000000000000000000000000000e100) #t) (test (equal? 0.0 #b00000000000000000000000000000000000000000000000000000.0000000000000000000000000000000000000000000000000000000000e100) #t) (test (equal? 0.0 #b0e100000000000000000000000000000000000000000000000000000000000000000000000) #t) (num-test 0 #b0/1000000000) (num-test 0 #b0/100000000000000000000000000000000000000) (num-test 0 #b0/100000000000000000000000000000000000000000000000000000000000000) (if with-bignums (begin (num-test (string->number "#b0/100000000000000000000000000000000000000000000000000000000000000000000") 0) (num-test (string->number "#b-0/100000000000000000000000000000000000000000000000000000000000000000000") 0))) ;;; there's a problem here -- the reader tries to make sense of every form even if it can't actually ;;; be evaluated, so in the block above in the non-bignum case, if the #b... is not in double quotes, it tries to read ;;; the value as a number. make_atom however returns NaN because it can't represent the integer in 64 bits, and ;;; the #... code interprets that as #b and it raises a read error! Ideally, we'd distinguish ;;; between #b... that can't possibly be right and the same that might be ok if the bits are available. (test (equal? 0.0 #b0.0e10) #t) (test (equal? 0.0 #b0e100) #t) (test (equal? 0.0 #b0.0e1000) #t) (test (equal? 0.0 #b0e+1000) #t) (test (equal? 0.0 #b0.0e-1) #t) (test (equal? 0.0 #b0e-10) #t) (test (equal? 0.0 #b0.0e-100) #t) (test (equal? 0.0 #b0e-1000) #t) (test (equal? 0.0 #b0.0e0123456789) #t) (test (equal? 0.0 #b0-0e10i) #t) (test (equal? 0.0 #b0-0.0e100i) #t) (test (equal? 0.0 #b0-0e1000i) #t) (test (equal? 0.0 #b0-0.0e+1000i) #t) (test (equal? 0.0 #b0-0e-1i) #t) (test (equal? 0.0 #b0-0.0e-10i) #t) (test (equal? 0.0 #b0-0e-100i) #t) (test (equal? 0.0 #b0-0.0e-1000i) #t) (test (equal? 0.0 #b0.0+0e0123456789i) #t) (num-test 0.0 #b1e-1000) (num-test #b+0+i 0+1i) (num-test #b0.-i 0-1i) (num-test #b0/01 0) (num-test #b-0/1 0) (num-test #b1.+.1i 1+0.5i) (num-test 1e-0 1.0) (when (not pure-s7) (num-test #b#i0-0i 0.0) (num-test #b#e1e01 2) (num-test #b#e1e-0 1) (num-test #b#e11e-1 3/2) ;;(num-test #b#e-0/1+i 0+1i) (test (string->number "#b#e-1/1+01.1e1i") #f) (test (string->number "#d#i0/0") #f) (test (string->number "#i#x0/0") #f) (test (exact? #i#b1) #f) (test (exact? #e#b1) #t) (num-test #x#e1.5 21/16) (num-test #x#i3 3.0)) (num-test #b0100/10 2) (num-test #b0e+1-0.i 0.0) (num-test #b.1-0/01i 0.5) (num-test #b0e+1-0.i 0.0) (num-test #b1.+01.e+1i 1+2i) (num-test #b0+.0e10101i 0.0) (num-test #b00e+0-.00e11i 0.0) (num-test #b-000e+10110001 0.0) (test (exact? #i1) #f) (test (exact? #e1.0) #t) (test (exact? #i1.0) #f) (test (exact? #e1) #t) (test (number? ''1) #f) (test (symbol? ''1) #f) (test (string->number "''1") #f) (test 00 0) (test (string->number "00") 0) (test 000 0) (test (string->number "000") 0) (test 00.00 0.0) (test (string->number "00.00") 0.0) (test (number? '0-0) #f) (test (string->number "0-0") #f) (test (number? '00-) #f) (test (string->number "00-") #f) (if pure-s7 (exit)) ; no way to go on... (num-test #e0.1 1/10) (num-test #x#if 15.0) (num-test #i1/1 1.0) (num-test #o-11 -9) (num-test #o-0. 0.0) (num-test #o+.0 0.0) (num-test #xe/1 14) (num-test #xe/a 7/5) (num-test #xfad 4013) (num-test #xd/1 13) (num-test #x0/f 0) (num-test #x+00 0) (num-test #x.c0 0.75) (num-test #x-fc -252) (test (equal? #e1.5 3/2) #t) (test (equal? #e1.0 1) #t) (test (equal? #e-.1 -1/10) #t) (test (equal? #e1 1) #t) (test (equal? #e3/2 3/2) #t) (test (< (abs (- #i3/2 1.5)) 1e-12) #t) (test (< (abs (- #i1 1.0)) 1e-12) #t) (test (< (abs (- #i-1/10 -0.1)) 1e-12) #t) (test (< (abs (- #i1.5 1.5)) 1e-12) #t) (num-test (= 0e-1 0.0) #t) ;;; (/ (/ 0))?? (num-test #x.a+i 0.625+1i) (num-test #b1.+i 1+1i) (num-test 0.e-0 0.0) (if (provided? 'dfls-exponents) (begin (num-test (string->number "#i1s0") 1.0) ; need the s->n to avoid confusing reader in non-dfls case (num-test -0d-0 0.0) (num-test +1d+1 10.0) (num-test +1s00 1.0) )) (let ((str (make-string 3))) (set! (str 0) #\#) (set! (str 1) #\b) (set! (str 2) #\null) (test (string->number str) #f)) (let ((str (make-string 4))) (set! (str 0) #\#) (set! (str 1) #\b) (set! (str 2) #\0) (set! (str 3) #\null) ; #\space here -> #f (test (string->number str) 0)) ; this is consistent with other (non-#) cases (do ((i 2 (+ i 1))) ((= i 17)) (num-test (string->number (number->string 12345.67890987654321 i) i) 12345.67890987654321)) (let () (define (make-number radix) (let* ((max-len (+ 1 (vector-ref (vector 0 0 62 39 31 26 23 22 20 19 18 17 17 16 16 15 15) radix))) (int-len (floor (* max-len (random 1.0) (random 1.0) (random 1.0)))) (frac-len (floor (* max-len (random 1.0) (random 1.0) (random 1.0)))) (exp-len 1) (has-frac (> (random 1.0) 0.2)) (has-exp (and (<= radix 10) (< int-len 9) (> (random 1.0) 0.5))) (signed (> (random 1.0) 0.5)) (exp-signed (> (random 1.0) 0.5))) (if (and (= int-len 0) (or (not has-frac) (= frac-len 0))) (set! int-len 1)) (let ((str (make-string (+ int-len (if signed 1 0) (if has-frac (+ frac-len 1) 0) ; extra 1 for "." (if has-exp (+ (+ exp-len 1) ; extra 1 for exponent char (if exp-signed 1 0)) 0)))) (loc 0)) (define (digit->char digit) (if (< digit 10) (integer->char (+ (char->integer #\0) digit)) (integer->char (+ (char->integer #\a) (- digit 10))))) (define (exponent-marker) (if (provided? 'dfls-exponents) (string-ref "eEsSfFdDlL" (random 10)) (string-ref "eE" (random 2)))) (if signed (begin (set! (str 0) #\-) (set! loc (+ loc 1)))) (do ((i 0 (+ i 1))) ((= i int-len)) (set! (str loc) (digit->char (random radix))) (set! loc (+ loc 1))) (if has-frac (begin (set! (str loc) #\.) (set! loc (+ loc 1)) (do ((i 0 (+ i 1))) ((= i frac-len)) (set! (str loc) (digit->char (random radix))) (set! loc (+ loc 1))))) (if has-exp (begin (set! (str loc) (exponent-marker)) (set! loc (+ loc 1)) (if exp-signed (begin (set! (str loc) #\-) (set! loc (+ loc 1)))) (do ((i 0 (+ i 1))) ((= i exp-len)) (set! (str loc) (digit->char (random 10))) (set! loc (+ loc 1))))) str))) (let ((tries 1000)) (do ((i 0 (+ i 1))) ((= i tries)) (let ((rad (+ 2 (random 15)))) (let ((str (make-number rad))) (if (not (number? (string->number str rad))) (format-logged #t ";(1) trouble in string->number ~A ~S: ~A~%" rad str (string->number str rad)) (if (not (string? (number->string (string->number str rad) rad))) (format-logged #t ";(2) trouble in number->string ~A ~S: ~A ~S~%" rad str (string->number str rad) (number->string (string->number str rad) rad)) (if (not (number? (string->number (number->string (string->number str rad) rad) rad))) (format-logged #t ";(3) trouble in number->string ~A ~S: ~A ~S ~A~%" rad str (string->number str rad) (number->string (string->number str rad) rad) (string->number (number->string (string->number str rad) rad) rad)) (let ((diff (abs (- (string->number (number->string (string->number str rad) rad) rad) (string->number str rad))))) (if (> diff 2e-5) (format-logged #t "(string->number ~S ~D): ~A, n->s: ~S, s->n: ~A, diff: ~A~%" str rad (string->number str rad) (number->string (string->number str rad) rad) (string->number (number->string (string->number str rad) rad) rad) diff))))))))))) (let () (define (no-char str radix) (let ((len (length str))) (do ((i 0 (+ i 1))) ((= i len)) (if (and (not (char=? (str i) #\.)) (>= (string->number (string (str i)) 16) radix)) (format-logged #t ";~S in base ~D has ~C?" str radix (str i)))))) (no-char (number->string (* 1.0 2/3) 9) 9) (no-char (number->string (string->number "0.05" 9) 9) 9) ;; (number->string (string->number "-5L-4" 9) 9) -> "-0.00049" if rounding is stupid ;; (number->string (string->number "5.e-8" 6) 6) -> "0.000000046" (no-char (number->string (* 1.0 6/7) 7) 7) (do ((i 2 (+ i 1))) ((= i 17)) (no-char (number->string (* 1.0 (/ 1 i)) i) i) (no-char (number->string (* 1.0 (/ 1 (* i i))) i) i) (no-char (number->string (* 0.99999999999999 (/ 1 i)) i) i) (no-char (number->string (* 0.999999 (/ 1 i)) i) i))) (let ((happy #t)) (do ((i 2 (+ i 1))) ((or (not happy) (= i 17))) (if (not (eqv? 3/4 (string->number (number->string 3/4 i) i))) (begin (set! happy #f) (format-logged #t ";(string<->number 3/4 ~A) -> ~A?~%" i (string->number (number->string 3/4 i) i)))) (if (not (eqv? 1234/11 (string->number (number->string 1234/11 i) i))) (begin (set! happy #f) (format-logged #t ";(string<->number 1234/11 ~A) -> ~A?~%" i (string->number (number->string 1234/11 i) i)))) (if (not (eqv? -1234/11 (string->number (number->string -1234/11 i) i))) (begin (set! happy #f) (format-logged #t ";(string<->number -1234/11 ~A) -> ~A?~%" i (string->number (number->string -1234/11 i) i)))))) (test (< (abs (- (string->number "3.1415926535897932384626433832795029") 3.1415926535897932384626433832795029)) 1e-7) #t) (num-test (string->number "111.01" 2) 7.25) (num-test (string->number "-111.01" 2) -7.25) (num-test (string->number "0.001" 2) 0.125) (num-test (string->number "1000000.001" 2) 64.125) (num-test (string->number "111.01" 8) 73.015625) (num-test (string->number "-111.01" 8) -73.015625) (num-test (string->number "0.001" 8) 0.001953125) (num-test (string->number "1000000.001" 8) 262144.001953125) (num-test (string->number "111.01" 16) 273.00390625) (num-test (string->number "-111.01" 16) -273.00390625) (num-test (string->number "0.001" 16) 0.000244140625) (num-test (string->number "1000000.001" 16) 16777216.000244) (num-test (string->number "11.+i" 2) 3+1i) (num-test (string->number "0+.1i" 2) 0+0.5i) (num-test (string->number "1.+0.i" 2) 1.0) (num-test (string->number ".01+.1i" 2) 0.25+0.5i) (num-test (string->number "1+0.i" 2) 1.0) (num-test (string->number "1+0i" 2) 1.0) (test (number->string 0.75 2) "0.11") (test (number->string 0.125 8) "0.1") (test (number->string 12.5 8) "14.4") (test (number->string 12.5 16) "c.8") (test (number->string 12.5 2) "1100.1") (test (number->string -12.5 8) "-14.4") (test (number->string -12.5 16) "-c.8") (test (number->string -12.5 2) "-1100.1") (test (number->string 12.0+0.75i 2) "1100.0+0.11i") (test (number->string -12.5-3.75i 2) "-1100.1-11.11i") (test (number->string 12.0+0.75i 8) "14.0+0.6i") (test (number->string -12.5-3.75i 8) "-14.4-3.6i") (test (number->string 12.0+0.75i 16) "c.0+0.ci") (test (number->string -12.5-3.75i 16) "-c.8-3.ci") (test (string->number "2/#b1" 10) #f) (test (string->number "2.i" 10) #f) (num-test (string->number "6+3.i" 10) 6+3i) (num-test (string->number "#e8/2" 11) 4) (num-test (string->number "-61" 7) -43) ;(num-test (string->number "#eb8235.9865c01" 13) 19132998081/57607) ; this one depends on the underlying size (32/64) (num-test (string->number "10100.000e11+011110111.1010110e00i" 2) 40960+247.671875i) (num-test (string->number "#i-0.e11" 2) 0.0) (num-test (string->number "+4a00/b" 16) 18944/11) (num-test (string->number "#i+9/9" 10) 1.0) (num-test (string->number "#e9e-999" 10) 0) (num-test (string->number "#e-9.e-9" 10) -1/111098767) (num-test (string->number "#e-.9e+9" 10) -900000000) (num-test (string->number "9-9.e+9i" 10) 9-9000000000i) (num-test (string->number "-9+9e-9i" 10) -9+9e-09i) ; why the 09? (num-test (string->number "#e-.9e+9" 10) -900000000) (num-test (string->number "9-9.e+9i" 10) 9-9000000000i) (num-test #e+32/1-0.i 32) (num-test #e+32.-0/1i 32) (num-test #e-32/1+.0i -32) (num-test #e+2.-0/31i 2) (num-test +2-0.e-1i 2.0) (num-test +2.-0e-1i 2.0) (num-test #b#e.01 1/4) (num-test #e#b.01 1/4) (num-test #b#e10. 2) (num-test #e#b10. 2) (num-test #b#e0.e11 0) (num-test #b#e1.e10 1024) (num-test #b#e-0.e+1 0) (num-test #b#e+.1e-0 1/2) (num-test #b#e+1.e-0 1) (num-test #b#e-1.e+0 -1) ;; weird cases: (num-test (string->number "#b1000" 8) 8) (num-test (string->number "#b1000" 2) 8) (num-test (string->number "#b1000" 16) 8) (num-test (string->number "11" 2) 3) (num-test (string->number "#x11" 2) 17) (num-test (string->number "#b11" 16) 3) (num-test (string->number "#xffff" 2) 65535) (num-test (string->number "#xffff" 10) 65535) (num-test (string->number "#xffff" 6) 65535) (num-test (string->number "#xffff" 16) 65535) (num-test (string->number "#d9.11" 16) 9.11) (num-test (string->number "#d9.11" 10) 9.11) (num-test (string->number "#x35/3de" 10) 53/990) (num-test (string->number "#e87" 16) 135) (num-test (string->number "#e87" 10) 87) (num-test (string->number "#e#x87" 10) 135) (num-test (string->number "#e#x87" 16) 135) (num-test (string->number "#x#e87" 10) 135) (num-test (string->number "#i87" 16) 135.0) (num-test (string->number "#i87" 12) 103.0) (num-test (string->number "#ee" 16) 14) (num-test (string->number "#if" 16) 15.0) (num-test (string->number "#e10.01" 2) 9/4) (num-test (string->number "#e10.01" 6) 217/36) (num-test (string->number "#e10.01" 10) 1001/100) (num-test (string->number "#e10.01" 14) 2745/196) (num-test (string->number "#i10.01" 2) 2.25) (num-test (string->number "#i10.01" 6) 6.0277777777778) (num-test (string->number "#i10.01" 10) 10.01) (num-test (string->number "#i10.01" 14) 14.005102040816) (num-test (string->number "#i-.c2e9" 16) -0.76136779785156) (test (string->number "#x#|1|#1") #f) (test (string->number "#||#1") #f) (test (string->number "#<") #f) (test (string->number "+.e1") #f) (test (string->number ".e1") #f) (num-test (string->number "4\x32\x37") 427) (num-test (string->number "\x32.\x39") 2.9) (num-test (string->number "#i\x32\x38\x36") 286.0) (num-test (string->number "4\x31+3\x36i") 41+36i) (when with-bignums (num-test (string->number "101461074055444526136" 8) 1181671265888545886) (num-test (string->number "-67330507011755171566102306711560321" 8) -35128577239298592313751007322321) (num-test (string->number "35215052773447206642040260+177402503313573563274751i" 8) 1.38249897923920622272688E23+1.176027342049207220713E21i) ;; there is some randomness here: 1.0e309 -> inf, but 1.0e310 -> -nan and others equally scattered ) (test (string=? (substring (number->string pi 16) 0 14) "3.243f6a8885a3") #t) (for-each (lambda (expchar) (let ((exponent (string expchar))) (do ((base 2 (+ base 1))) ((= base 11)) (let ((val (string->number (string-append "1" exponent "1") base))) (if (and (number? val) (> (abs (- val base)) 1e-9)) (format-logged #t ";(string->number ~S ~A) returned ~A?~%" (string-append "1" exponent "1") base (string->number (string-append "1" exponent "1") base))))) (do ((base 2 (+ base 1))) ((= base 11)) (let ((val (string->number (string-append "1.1" exponent "1") base))) (if (and (number? val) (> (abs (- val (+ base 1))) 1e-9)) (format-logged #t ";(string->number ~S ~A) returned ~A?~%" (string-append "1.1" exponent "1") base (string->number (string-append "1.1" exponent "1") base))))) (do ((base 2 (+ base 1))) ((= base 11)) (let ((val (string->number (string-append "1" exponent "+1") base))) (if (and (number? val) (> (abs (- val base)) 1e-9)) (format-logged #t ";(string->number ~S ~A) returned ~A?~%" (string-append "1" exponent "+1") base (string->number (string-append "1" exponent "+1") base))))) ; in base 16 this is still not a number because of the + (or -) ; but "1e+1i" is a number -- gad! (do ((base 2 (+ base 1))) ((= base 11)) (let ((val (string->number (string-append "1" exponent "-1+1i") base))) (if (and (number? val) (> (magnitude (- val (complex (/ base) 1))) 1e-6)) (format-logged #t ";(string->number ~S ~A) returned ~A?~%" (string-append "1" exponent "-1+1i") base (string->number (string-append "1" exponent "-1+1i") base))))))) (list #\e #\d #\f #\s #\l)) (test (< (abs (- (string->number "3.1415926535897932384626433832795029" 10) 3.1415926535897932384626433832795029)) 1e-7) #t) (num-test (string->number "2.718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427" 16) 2.4433976119657) (num-test (string->number "2.718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427" 11) 2.6508258818757) (let ((happy #t)) (do ((i 2 (+ i 1))) ((or (not happy) (= i 17))) (let ((val (+ 1.0 i))) (do ((k 1 (+ k 1)) (incr (/ 1.0 i) (/ incr i))) ((< incr 1e-14)) (set! val (+ val incr))) (if (> (abs (- val (string->number "11.111111111111111111111111111111111111111111111111111111111111111111111111111111111111" i))) 1e-7) (begin (set! happy #f) (display "(string->number 11.111... ") (display i) (display ") -> ") (display (string->number "11.111111111111111111111111111111111111111111111111111111111111111111111111111111111111" i)) (display " but expected ") (display val) (newline)))) (let* ((digits "00123456789abcdef") (str (make-string 80 (string-ref digits i)))) (string-set! str 2 #\.) (let ((val (exact->inexact (* i i)))) (if (> (abs (- val (string->number str i))) 1e-7) (begin (set! happy #f) (format-logged #t ";(string->number ~S ~A) -> ~A (expected ~A)?~%" str i (string->number str i) val))))) (let* ((radlim (list 0 0 62 39 31 26 23 22 20 19 18 17 17 16 16 15 15)) (digits "00123456789abcdef")) (do ((k (- (list-ref radlim i) 3) (+ k 1))) ((= k (+ (list-ref radlim i) 4))) (let ((str (make-string (+ k 3) (string-ref digits i)))) (string-set! str 2 #\.) (let ((val (exact->inexact (* i i)))) (if (> (abs (- val (string->number str i))) 1e-7) (begin (set! happy #f) (format-logged #t ";(string->number ~S ~A) -> ~A (expected ~A)?~%" str i (string->number str i) val))))))))) (let ((happy #t)) (do ((i 2 (+ i 1))) ((or (not happy) (= i 17))) (if (> (abs (- 0.75 (string->number (number->string 0.75 i) i))) 1e-6) (begin (set! happy #f) (format-logged #t ";(string->number (number->string 0.75 ~A) ~A) -> ~A?~%" i i (string->number (number->string 0.75 i) i)))) (if (> (abs (- 1234.75 (string->number (number->string 1234.75 i) i))) 1e-6) (begin (set! happy #f) (format-logged #t ";(string->number (number->string 1234.75 ~A) ~A) -> ~A?~%" i i (string->number (number->string 1234.75 i) i)))) (if (> (abs (- -1234.25 (string->number (number->string -1234.25 i) i))) 1e-6) (begin (set! happy #f) (format-logged #t ";(string->number (number->string -1234.75 ~A) ~A) -> ~A?~%" i i (string->number (number->string -1234.75 i) i)))) (let ((val (string->number (number->string 12.5+3.75i i) i))) (if (or (not (number? val)) (> (abs (- (real-part val) 12.5)) 1e-6) (> (abs (- (imag-part val) 3.75)) 1e-6)) (begin (set! happy #f) (format-logged #t ";(string->number (number->string 12.5+3.75i ~A) ~A) -> ~A?~%" i i (string->number (number->string 12.5+3.75i i) i))))) (let ((happy #t)) (do ((base 2 (+ base 1))) ((or (not happy) (= base 11))) ;;; see s7.c for an explanation of this limit (do ((i 0 (+ i 1))) ((= i 10)) (let* ((rl (- (random 200.0) 100.0)) (im (- (random 200.0) 100.0)) (rlstr (number->string rl base)) (imstr (number->string im base)) (val (complex rl im)) (str (string-append rlstr (if (or (negative? im) (char=? (string-ref imstr 0) #\-)) ; sigh -- -0.0 is not negative! "" "+") imstr "i"))) (let* ((sn (string->number str base)) (nsn (and (number? sn) (number->string sn base))) (nval (and (string? nsn) (string->number nsn base)))) (if (or (not nval) (> (abs (- (real-part nval) (real-part val))) 1e-3) (> (abs (- (imag-part nval) (imag-part val))) 1e-3)) (begin (set! happy #f) (format-logged #t ";(number<->string ~S ~A) -> ~A? [~A ~S]~%" str base nval sn nsn) ))))))))) (let ((val (number->string 1.0-1.0i))) (if (and (not (string=? val "1-1i")) (not (string=? val "1.0-1.0i")) (not (string=? val "1-i")) (not (string=? val "1.0-i"))) (begin (display "(number->string 1.0-1.0i) returned ") (display val) (display "?") (newline)))) (let () (define (make-integer str j digits radix zero-ok) (do ((k 0 (+ k 1))) ((= k digits)) (if zero-ok (set! (str j) (#(#\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9 #\a #\b #\c #\d #\e #\f) (random radix))) (set! (str j) (#(#\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9 #\a #\b #\c #\d #\e #\f) (random (- radix 1))))) (set! j (+ j 1))) j) (define (make-ratio str j ndigits ddigits radix) (set! j (make-integer str j (+ 1 ndigits) radix #t)) (set! (str j) #\/) (make-integer str (+ j 1) (+ 1 ddigits) radix #f)) (define (make-real str j digits edigits radix) (let ((nj (make-integer str j (random digits) radix #t))) (set! (str nj) #\.) (set! j (make-integer str (+ nj 1) (+ (if (= j nj) 1 0) (random digits)) radix #t)) (if (and (> edigits 0) (<= radix 10)) (begin (set! (str j) #\e) (set! j (make-integer str (+ j 1) (+ 1 (random edigits)) radix #t)))) j)) (define (complex str j digits edigits radix) (set! j (make-real str j digits edigits radix)) (set! (str j) (#(#\+ #\-) (random 2))) (set! j (make-real str (+ j 1) digits edigits radix)) (set! (str j) #\i) (+ j 1)) (let ((str (make-string 512)) (max-digits 10) (edigits 2)) (do ((i 0 (+ i 1))) ((= i 100)) (let ((j 0) (radix (+ 2 (random 15))) (choice (case (random 10) ((0 1) 'integer) ((2 3) 'ratio) ((4 5 6) 'real) (else 'complex)))) ;; possible #e or #i (if (and (not (eq? choice 'complex)) (> (random 10) 8)) (begin (set! (str j) #\#) (set! j (+ j 1)) (set! (str j) (#(#\e #\i) (random 2))) (if (char=? (str j) #\e) (set! edigits 0)) (set! j (+ j 1)))) ;; possible #x etc (if (> (random 10) 7) (begin (set! (str j) #\#) (set! j (+ j 1)) (let ((rchoice (random 4))) (set! (str j) (#(#\b #\d #\o #\x) rchoice)) (set! radix (#(2 10 8 16) rchoice))) (set! j (+ j 1)))) ;; possible sign (if (> (random 10) 5) (begin (set! (str j) (#(#\+ #\-) (random 2))) (set! j (+ j 1)))) (set! j (case choice ((integer) (make-integer str j (+ 1 (random max-digits)) radix #t)) ((ratio) (make-ratio str j (random max-digits) (random max-digits) radix)) ((real) (make-real str j max-digits edigits radix)) ((complex) (complex str j max-digits edigits radix)))) (let ((num (catch #t (lambda () (string->number (substring str 0 j) radix)) (lambda args 'error)))) (if (not (number? num)) (format *stderr* "(string->number ~S ~D) ~60T~A~%" (substring str 0 j) radix num))))))) (let ((string->number-2 (lambda (str radix) (let ((old-str (if (string? str) (string-copy str) str))) (let ((val (string->number str radix))) (if (not (string=? str old-str)) (error 'string->number-messed-up) val))))) (string->number-1 (lambda (str) (let ((old-str (if (string? str) (string-copy str) str))) (let ((val (string->number str))) (if (not (string=? str old-str)) (error 'string->number-messed-up) val)))))) (num-test (string->number-1 "100") 100) (num-test (string->number-2 "100" 16) 256) (num-test (string->number-2 "100" 2) 4) (num-test (string->number-2 "100" 8) 64) (num-test (string->number-2 "100" 10) 100) (num-test (string->number-2 "11" 16) 17) (num-test (string->number-2 "-11" 16) -17) (num-test (string->number-2 "+aa" 16) 170) (num-test (string->number-2 "-aa" 16) -170) (for-each (lambda (str rval fval) (let ((happy #t)) (do ((radix 3 (+ radix 1))) ((or (not happy) (= radix 16))) (let ((val (string->number-2 str radix))) (if (and (number? val) (not (fval val (rval radix) radix))) (begin (display "(string->number \"") (display str) (display "\" ") (display radix) (display ") = ") (display val) (display "?") (newline) (set! happy #f))))))) (list "101" "201.02" "1/21" "2e1" "10.1e-1" ) (list (lambda (radix) (+ 1 (* radix radix))) (lambda (radix) (+ 1.0 (* 2 radix radix) (/ 2.0 (* radix radix)))) (lambda (radix) (/ 1 (+ 1 (* 2 radix)))) (lambda (radix) (if (< radix 15) (* 2 radix) (+ 1 (* 14 radix) (* 2 radix radix)))) (lambda (radix) (+ 1 (/ 1.0 (* radix radix)))) ) (list (lambda (a b radix) (= a b)) (lambda (a b radix) (< (abs (- a b)) (/ 1.0 (* radix radix)))) (lambda (a b radix) (= a b)) (lambda (a b radix) (= a b)) (lambda (a b radix) (< (abs (- a b)) (/ 1.0 (* radix radix radix)))) )) (num-test (string->number-2 "34" 2) #f) (num-test (string->number-2 "19" 8) #f) (num-test (string->number-2 "1c" 10) #f) (num-test (string->number-2 "1c" 16) 28) (test (string->number-1 "") #f ) (test (string->number-1 ".") #f ) (test (string->number-1 "d") #f ) (test (string->number-1 "D") #f ) (test (string->number-1 "i") #f ) (test (string->number-1 "I") #f ) (test (string->number-1 "3i") #f ) (test (string->number-1 "3I") #f ) (test (string->number-1 "33i") #f ) (test (string->number-1 "33I") #f ) (test (string->number-1 "3.3i") #f ) (test (string->number-1 "3.3I") #f ) (test (string->number-1 "-") #f ) (test (string->number-1 "+") #f ) (test (string->number-1 "#i1-1ei") #f) (test (string->number-1 "#i-2e+i") #f) (test (string->number-1 "#i1+i1i") #f) (test (string->number-1 "#i1+1") #f) (test (string->number-1 "#i2i.") #f) (test (string->number "1e0+i") 1+i) (test (string->number "1+ie0") #f) (test (string->number "1+e0") #f) (test (string->number "1+1e0i") 1+i) (test (string->number "1+1e0e0i") #f) (test (string->number "1+1e00i") 1+i) (test (string->number "1L") #f) (test (string->number "1.L") #f) (test (string->number "0+I") #f) (num-test (string->number-1 "3.4e3") 3400.0) (num-test (string->number-1 "0") 0) (num-test (string->number-1 "#x#e-2e2") -738) ) (test (let* ((str "1+0i") (x (string->number str))) (and (number? x) (string=? str "1+0i"))) #t) (test (= 1 #e1 1/1 #e1/1 #e1.0 #e1e0 #b1 #x1 #o1 #d1 #o001 #o+1 #o#e1 #e#x1 #e1+0i #e10e-1 #e0.1e1 #e+1-0i #e#b1) #t) ;(test (= 0.3 3e-1 0.3e0 3e-1) #t) (test (= 0 +0 0.0 +0.0 0/1 +0/24 0+0i #e0 #b0 #x0 #o0 #e#b0) #t) (let ((things (vector 123 #e123 #b1111011 #e#b1111011 #b#e1111011 #o173 #e#o173 #o#e173 #x7b #e#x7b #x#e7b (string->number "123") 246/2 #e123/1 #d123 #e#d123 #d#e123))) (do ((i 0 (+ i 1))) ((= i (- (vector-length things) 1))) (do ((j (+ i 1) (+ j 1))) ((= j (vector-length things))) (if (not (eqv? (vector-ref things i) (vector-ref things j))) (begin (display "(eqv? ") (display (vector-ref things i)) (display " ") (display (vector-ref things j)) (display ") -> #f?") (newline)))))) (for-each (lambda (n) (let ((nb (catch #t (lambda () (number? n)) (lambda args 'error)))) (if (not nb) (begin (display "(number? ") (display n) (display ") returned #f?") (newline))))) (if (provided? 'dfls-exponents) (list 1 -1 +1 +.1 -.1 .1 .0 0. 0.0 -0 +0 -0. +0. +1.1 -1.1 1.1 '1.0e2 '-1.0e2 '+1.0e2 '1.1e-2 '-1.1e-2 '+1.1e-2 '1.1e+2 '-1.1e+2 '+1.1e+2 '1/2 '-1/2 '+1/2 '1.0s2 '-1.0s2 '+1.0s2 '1.0d2 '-1.0d2 '+1.0d2 '1.0f2 '-1.0f2 '+1.0f2 '1.0l2 '-1.0l2 '+1.0l2 '1.0+1.0i '1.0-1.0i '-1.0-1.0i '-1.0+1.0i '1+i '1-i '-1-i '-1+i '2/3+i '2/3-i '-2/3+i '1+2/3i '1-2/3i '2/3+2/3i '2.3-2/3i '2/3-2.3i '2e2+1e3i '2e2-2e2i '2.0e2+i '1+2.0e2i '2.0e+2-2.0e-1i '2/3-2.0e3i '2e-3-2/3i '-2.0e-2-2.0e-2i '+2.0e+2+2.0e+2i '+2/3-2/3i '2e2-2/3i '1e1-i '1.-i '.0+i '-.0-1e-1i '1.+.1i '0.-.1i '.1+.0i '1.+.0i '.1+.1i '1.-.1i '.0+.00i '.10+.0i '-1.+.0i '.1-.01i '1.0+.1i '1e1+.1i '-1.-.10i '1e01+.0i '0e11+.0i '1.e1+.0i '1.00-.0i '-1e1-.0i '1.-.1e0i '1.+.001i '1e10-.1i '1e+0-.1i '-0e0-.1i '-1.0e-1-1.0e-1i '-111e1-.1i '1.1-.1e11i '-1e-1-.11i '-1.1-.1e1i '-.1+.1i) (list 1 -1 +1 +.1 -.1 .1 .0 0. 0.0 -0 +0 -0. +0. +1.1 -1.1 1.1 '1.0e2 '-1.0e2 '+1.0e2 '1.1e-2 '-1.1e-2 '+1.1e-2 '1.1e+2 '-1.1e+2 '+1.1e+2 '1/2 '-1/2 '+1/2 '1.0+1.0i '1.0-1.0i '-1.0-1.0i '-1.0+1.0i '1+i '1-i '-1-i '-1+i '2/3+i '2/3-i '-2/3+i '1+2/3i '1-2/3i '2/3+2/3i '2.3-2/3i '2/3-2.3i '2e2+1e3i '2e2-2e2i '2.0e2+i '1+2.0e2i '2.0e+2-2.0e-1i '2/3-2.0e3i '2e-3-2/3i '-2.0e-2-2.0e-2i '+2.0e+2+2.0e+2i '+2/3-2/3i '2e2-2/3i '1e1-i '1.-i '.0+i '-.0-1e-1i '1.+.1i '0.-.1i '.1+.0i '1.+.0i '.1+.1i '1.-.1i '.0+.00i '.10+.0i '-1.+.0i '.1-.01i '1.0+.1i '1e1+.1i '-1.-.10i '1e01+.0i '0e11+.0i '1.e1+.0i '1.00-.0i '-1e1-.0i '1.-.1e0i '1.+.001i '1e10-.1i '1e+0-.1i '-0e0-.1i '-1.0e-1-1.0e-1i '-111e1-.1i '1.1-.1e11i '-1e-1-.11i '-1.1-.1e1i '-.1+.1i))) (for-each (lambda (n rl im) (if (not (number? n)) (begin (display "(number? ") (display n) (display ") returned #f?") (newline)) (begin (if (> (abs (- (real-part n) rl)) .000001) (begin (display "real-part: ") (display n) (display " ") (display (real-part n)) (display " ") (display rl) (newline))) (if (> (abs (- (imag-part n) im)) .000001) (begin (display "imag-part: ") (display n) (display " ") (display (imag-part n)) (display " ") (display im) (newline))) ))) (list 1 -1 +1 +.1 -.1 .1 .0 0. 0.0 -0 +0 -0. +0. +1.1 -1.1 1.1 '1.0e2 '-1.0e2 '+1.0e2 '1.1e-2 '-1.1e-2 '+1.1e-2 '1.1e+2 '-1.1e+2 '+1.1e+2 '1/2 '-1/2 '+1/2 '1.0+1.0i '1.0-1.0i '-1.0-1.0i '-1.0+1.0i '1+i '1-i '-1-i '-1+i '2/3+i '2/3-i '-2/3+i '1+2/3i '1-2/3i '2/3+2/3i '2.3-2/3i '2/3-2.3i '2e2+1e3i '2e2-2e2i '2.0e2+i '1+2.0e2i '2.0e+2-2.0e-1i '2/3-2.0e3i '2e-3-2/3i '-2.0e-2-2.0e-2i '+2.0e+2+2.0e+2i '+2/3-2/3i '2e2-2/3i '1e1-i '1.-i '.0+i '-.0-1e-1i '1.+.1i '0.-.1i '.1+.0i '1.+.0i '.1+.1i '1.-.1i '.0+.00i '.10+.0i '-1.+.0i '.1-.01i '1.0+.1i '1e1+.1i '-1.-.10i '1e01+.0i '0e11+.0i '1.e1+.0i '1.00-.0i '-1e1-.0i '1.-.1e0i '1.+.001i '1e10-.1i '1e+0-.1i '-0e0-.1i '-1.0e-1-1.0e-1i '-111e1-.1i '1.1-.1e11i '-1e-1-.11i '-1.1-.1e1i) (list 1.0 -1.0 1.0 0.1 -0.1 0.1 0.0 0.0 0.0 0.0 0.0 -0.0 0.0 1.1 -1.1 1.1 100.0 -100.0 100.0 0.011 -0.011 0.011 110.0 -110.0 110.0 0.5 -0.5 0.5 1.0 1.0 -1.0 -1.0 1.0 1.0 -1.0 -1.0 0.66666666666667 0.66666666666667 -0.66666666666667 1.0 1.0 0.66666666666667 2.3 0.66666666666667 200.0 200.0 200.0 1.0 200.0 0.66666666666667 0.002 -0.02 200.0 0.66666666666667 200.0 10.0 1.0 0.0 -0.0 1.0 0.0 0.1 1.0 0.1 1.0 0.0 0.1 -1.0 0.1 1.0 10.0 -1.0 10.0 0.0 10.0 1.0 -10.0 1.0 1.0 10000000000.0 1.0 -0.0 -0.1 -1110.0 1.1 -0.1 -1.1) (list 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 -1.0 -1.0 1.0 1.0 -1.0 -1.0 1.0 1.0 -1.0 1.0 0.66666666666667 -0.66666666666667 0.66666666666667 -0.66666666666667 -2.3 1000.0 -200.0 1.0 200.0 -0.2 -2000.0 -0.66666666666667 -0.02 200.0 -0.66666666666667 -0.66666666666667 -1.0 -1.0 1.0 -0.1 0.1 -0.1 0.0 0.0 0.1 -0.1 0.0 0.0 0.0 -0.01 0.1 0.1 -0.1 0.0 0.0 0.0 0.0 0.0 -0.1 0.001 -0.1 -0.1 -0.1 -0.1 -0.1 -10000000000.0 -0.11 -1.0)) (for-each (lambda (n name) (if (number? n) (begin (display "(number? ") (display name) (display ") returned #t?") (newline))) (if (or (not (symbol? n)) (boolean? n)) (begin (display "(symbol? ") (display name) (display ") returned #f?") (newline))) (if (number? (string->number name)) (begin (display "(string->number ") (display name) (display ") returned ") (display (string->number name)) (display "?") (newline)))) (list '1e '--1 '++1 '+. '+.+ '.. '.- '1e- '+ '- '-e1 '1/2/3 '1/2+/2 '/2 '2/ '1+2 '1/+i '1/2e1 '1/2. '1..0 '1.+0 '1--1 '1+- '1.0++i '1.0-ie++2 '1+1 '1.0. '1.0e '1ee2 '1.0e2e2 '1es2 '1e1.0 '1.0.0 '1/2.0 '1+i2 '1+1.0i0 '+.i 'i 'e 'e1 '1e.1 '1+.i '1.0e.1 '-.1ei '-1.0+1.0 '1.0+1.0i+1.0 '1.1/2 '1/2.0 '1/e '1/i 'e/i '1e2/3 '2/1e2 '1e2+1e2ii '1i-1.0 '1.0-i/2 '1/2i '2i/3 '2+/i '2+2/i '2+2/-i '2/- '2/+ '2/+3 '1e1.0 '1e1e2 '1+ie2 '1ei1 '1e/2 '0-- '1+ '1- '.1. '.1+ '1//2 '1/-/2 '1/2/ '1// '+/1 '.0. '+0ei '0e++i '+0e+i '0e+-i '+0e-i '+00ei '+.0ei '0+0ei '-01ei '+.1ei '1-1ei '-1.ei '0+.i '0-.i '1+e0i '1+/0i '1-/0i '1+e1i '1+/1i '10+.i '.0+.i '-0+.i '.1+.i '0.+.i '00-.i '.1-.i '1.-.i '1e++0i '1e--1i '.1e++i '+10e+i '1+0e+i '+01e+i '+0e+-i '.1e+-i '1-10ei '0e++00i '1e--.1i '1.e-+1i '1-0.e+i '1.+1e+i '-1.e--i '1.e+-.0i '1-e+01i '1-/101i '1+/10i '1-e10i '-1+e+1i '.1-e-1i '1-/0e1i '1e10+.i '1/1.1+i '1/11.+i '1/2e1-i '-1.0e-1-1-1.0e-1i '-1.0e-1-1.0e-1-1i '1.0e2/3 '-1e--1.e1i '-11e--1e1i '1e--1.1e1i '1.e-1-1.ei '-1.e--1.ei '-1.1e1-e1i '-1.e1-e-1i '.1e1-e-11i '3.-3. '1'2 '+-2 '1? '1a '1.a '-a '+a '1.. '..1 '-..1 '1ee1 '1ef2 '1+ief2 '1.+ '1.0- '1/2+/3 '1'2 '1-#i '1-i. '1-ie '1... '1/1/1/1 '1//1 '-.e1 ) (list "1e" "--1" "++1" "+." "+.+" ".." ".-" "1e-" "+" "-" "-e1" "1/2/3" "1/2+/2" "/2" "2/" "1+2" "1/+i" "1/2e1" "1/2." "1..0" "1.+0" "1--1" "1+-" "1.0++i" "1.0-ie++2" "1+1" "1.0." "1.0e" "1ee2" "1.0e2e2" "1es2" "1e1.0" "1.0.0" "1/2.0" "1+i2" "1+1.0i0" "+.i" "i" "e" "e1" "1e.1" "1+.i" "1.0e.1" "-.1ei" "-1.0+1.0" "1.0+1.0i+1.0" "1.1/2" "1/2.0" "1/e" "1/i" "e/i" "1e2/3" "2/1e2" "1e2+1e2ii" "1i-1.0" "1.0-i/2" "1/2i" "2i/3" "2+/i" "2+2/i" "2+2/-i" "2/-" "2/+" "2/+3" "1e1.0" "1e1e2" "1+ie2" "1ei1" "1e/2" "0--" "1+" "1-" ".1." ".1+" "1//2" "1/-/2" "1/2/" "1//" "+/1" ".0." "+0ei" "0e++i" "+0e+i" "0e+-i" "+0e-i" "+00ei" "+.0ei" "0+0ei" "-01ei" "+.1ei" "1-1ei" "-1.ei" "0+.i" "0-.i" "1+e0i" "1+/0i" "1-/0i" "1+e1i" "1+/1i" "10+.i" ".0+.i" "-0+.i" ".1+.i" "0.+.i" "00-.i" ".1-.i" "1.-.i" "1e++0i" "1e--1i" ".1e++i" "+10e+i" "1+0e+i" "+01e+i" "+0e+-i" ".1e+-i" "1-10ei" "0e++00i" "1e--.1i" "1.e-+1i" "1-0.e+i" "1.+1e+i" "-1.e--i" "1.e+-.0i" "1-e+01i" "1-/101i" "1+/10i" "1-e10i" "-1+e+1i" ".1-e-1i" "1-/0e1i" "1e10+.i" "1/1.1+i" "1/11.+i" "1/2e1-i" "-1.0e-1-1-1.0e-1i" "-1.0e-1-1.0e-1-1i" "1.0e2/3" "-1e--1.e1i" "-11e--1e1i" "1e--1.1e1i" "1.e-1-1.ei" "-1.e--1.ei" "-1.1e1-e1i" "-1.e1-e-1i" ".1e1-e-11i" "3.-3." "'1'2" "'+-2" "'1?" "1a" "1.a" "-a" "+a" "1.." "..1" "-..1" "1ee1" "1ef2" "1+ief2" "1.+" "1.0-" "1/2+/3" "'1'2" "1-#i" "1-i." "1-ie" "1..." "1/1/1/1" "1//1" "-.e1" )) (let ((val (catch #t (lambda () (= 1 01 +1 1. 001 +01 1/1 1.0 1e0 01. +1. #b1 #d1 #e1 #o1 #x1 2/2 3/3 4/4 5/5 6/6 7/7 8/8 9/9 1E0 1e0 0001 +001 1/01 .1e1 01/1 +1/1 1.00 1e00 01.0 +1.0 1e+0 1e-0 01e0 +1e0 1.e0 001. +01. 1+0i 1-0i #b+1 #b01 #b1. #d+1 #d01 #d1. #e+1 #e01 #e1. #i+1 #i01 #i1. #o+1 #o01 #o1. #x+1 #x01 #x1. +1E0 +1e0 +2/2 +3/3 +4/4 +5/5 +6/6 +7/7 +8/8 +9/9 .1E1 0001 001. 01.0 01/1 01E0 02/2 03/3 04/4 05/5 06/6 07/7 08/8 09/9 1.E0 1/01 1E+0 1E-0 1E00 2/02 3/03 4/04 5/05 6/06 7/07 8/08 9/09 11/11 00001 +0001 1/001 .1e01 01/01 +1/01 .1e+1 10e-1 0.1e1 +.1e1 .10e1 001/1 +01/1 10/10 1.000 1e000 01.00 +1.00 1e+00 1e-00 01e00 +1e00 1.e00 001.0 +01.0 01e+0 +1e+0 1.e+0 01e-0 +1e-0 1.e-0 001e0 +01e0 1.0e0 01.e0 +1.e0 0001. +001. 1+00i 1-00i 1+.0i 1-.0i 01+0i +1+0i 1.+0i 01-0i +1-0i 1.-0i 1+0.i 1-0.i 11/011 011/11 +11/11 000001 +00001 1/0001 .1e001 01/001 +1/001 .1e+01 10e-01 0.1e01 +.1e01 .10e01 001/01 +01/01 0.1e+1 +.1e+1 .10e+1 010e-1 +10e-1 10.e-1 00.1e1 +0.1e1 0.10e1 +.10e1 .100e1 0001/1 +001/1 10/010 010/10 +10/10 1.0000 1e0000 01.000 +1.000 1e+000 1e-000 01e000 +1e000 1.e000 001.00 +01.00 01e+00 +1e+00 1.e+00 01e-00 +1e-00 1.e-00 001e00 +01e00 1.0e00 01.e00 +1.e00 0001.0 +001.0 001e+0 +01e+0 1.0e+0 01.e+0 +1.e+0 001e-0 +01e-0 1.0e-0 01.e-0 +1.e-0 0001e0 +001e0 1.00e0 01.0e0 +1.0e0 001.e0 +01.e0 00001. +0001. 1+0e1i 1-0e1i 1+0/1i 1-0/1i 1+000i 1-000i 1+.00i 1-.00i 01+00i +1+00i 1.+00i 01-00i +1-00i 1.-00i 1+0.0i 1-0.0i 01+.0i +1+.0i 1.+.0i 01-.0i +1-.0i 1.-.0i 001+0i +01+0i 1/1+0i 1.0+0i 1e0+0i 01.+0i +1.+0i 001-0i +01-0i 1/1-0i 1.0-0i 1e0-0i 01.-0i +1.-0i 1+0e0i 1-0e0i 1+00.i 1-00.i 01+0.i +1+0.i 1.+0.i 01-0.i +1-0.i 1.-0.i 111/111 11/0011 011/011 +11/011 0011/11 +011/11 101/101 0000001 +000001 1/00001 .1e0001 01/0001 +1/0001 .1e+001 10e-001 0.1e001 +.1e001 .10e001 001/001 +01/001 0.1e+01 +.1e+01 .10e+01 010e-01 +10e-01 10.e-01 00.1e01 +0.1e01 0.10e01 +.10e01 .100e01 0001/01 +001/01 00.1e+1 +0.1e+1 0.10e+1 +.10e+1 .100e+1 0010e-1 +010e-1 10.0e-1 010.e-1 +10.e-1 000.1e1 +00.1e1 00.10e1 +0.10e1 0.100e1 +.100e1 .1000e1 00001/1 +0001/1 110/110 10/0010 010/010 +10/010 0010/10 +010/10 100/100 1.00000 1e00000 01.0000 +1.0000 1e+0000 1e-0000 01e0000 +1e0000 1.e0000 001.000 +01.000 01e+000 +1e+000 1.e+000 01e-000 +1e-000 1.e-000 001e000 +01e000 1.0e000 01.e000 +1.e000 0001.00 +001.00 001e+00 +01e+00 1.0e+00 01.e+00 +1.e+00 001e-00 +01e-00 1.0e-00 01.e-00 +1.e-00 0001e00 +001e00 1.00e00 01.0e00 +1.0e00 001.e00 +01.e00 00001.0 +0001.0 0001e+0 +001e+0 1.00e+0 01.0e+0 +1.0e+0 001.e+0 +01.e+0 0001e-0 +001e-0 1.00e-0 01.0e-0 +1.0e-0 001.e-0 +01.e-0 00001e0 +0001e0 1.000e0 01.00e0 +1.00e0 001.0e0 +01.0e0 0001.e0 +001.e0 000001. +00001. 1+0e11i 1-0e11i 1+0/11i 1-0/11i 1+0e01i 1-0e01i 1+0/01i 1-0/01i 1+0e+1i 1-0e+1i 1+0e-1i 1-0e-1i 1+00e1i 1-00e1i 1+.0e1i 1-.0e1i 01+0e1i +1+0e1i 1.+0e1i 01-0e1i +1-0e1i 1.-0e1i 1+0.e1i 1-0.e1i 1+00/1i 1-00/1i 01+0/1i +1+0/1i 1.+0/1i 01-0/1i +1-0/1i 1.-0/1i 1+0e10i 1-0e10i 1+0/10i 1-0/10i 1+0000i 1-0000i 1+.000i 1-.000i 01+000i +1+000i 1.+000i 01-000i +1-000i 1.-000i 1+0.00i 1-0.00i 01+.00i +1+.00i 1.+.00i 01-.00i +1-.00i 1.-.00i 001+00i +01+00i 1/1+00i 1.0+00i 1e0+00i 01.+00i +1.+00i 001-00i +01-00i 1/1-00i 1.0-00i 1e0-00i 01.-00i +1.-00i 1+0e00i 1-0e00i 1+00.0i 1-00.0i 01+0.0i +1+0.0i 1.+0.0i 01-0.0i +1-0.0i 1.-0.0i 001+.0i +01+.0i 1/1+.0i 1.0+.0i 1e0+.0i 01.+.0i +1.+.0i 001-.0i +01-.0i 1/1-.0i 1.0-.0i 1e0-.0i 01.-.0i +1.-.0i 0001+0i +001+0i 1/01+0i .1e1+0i 01/1+0i +1/1+0i 1.00+0i 1e00+0i 01.0+0i +1.0+0i 1e+0+0i 1e-0+0i 01e0+0i +1e0+0i 1.e0+0i 001.+0i +01.+0i 1+0e+0i 1-0e+0i 0001-0i +001-0i 1/01-0i .1e1-0i 01/1-0i +1/1-0i 1.00-0i 1e00-0i 01.0-0i +1.0-0i 1e+0-0i 1e-0-0i 01e0-0i +1e0-0i 1.e0-0i 001.-0i +01.-0i 1+0e-0i 1-0e-0i 1+00e0i 1-00e0i 1+.0e0i 1-.0e0i 01+0e0i +1+0e0i 1.+0e0i 01-0e0i +1-0e0i 1.-0e0i 1+0.e0i 1-0.e0i 1+000.i 1-000.i 01+00.i +1+00.i 1.+00.i 01-00.i +1-00.i 1.-00.i 001+0.i +01+0.i 1/1+0.i 1.0+0.i 1e0+0.i 01.+0.i +1.+0.i 001-0.i +01-0.i 1/1-0.i 1.0-0.i 1e0-0.i 01.-0.i +1.-0.i 111/0111 0111/111 +111/111 11/00011 011/0011 +11/0011 0011/011 +011/011 00011/11 +0011/11 101/0101 0101/101 +101/101 00000001 +0000001 1/000001 .1e00001 01/00001 +1/00001 .1e+0001 10e-0001 0.1e0001 +.1e0001 .10e0001 001/0001 +01/0001 0.1e+001 +.1e+001 .10e+001 010e-001 +10e-001 10.e-001 00.1e001 +0.1e001 0.10e001 +.10e001 .100e001 0001/001 +001/001 00.1e+01 +0.1e+01 0.10e+01 +.10e+01 .100e+01 0010e-01 +010e-01 10.0e-01 010.e-01 +10.e-01 000.1e01 +00.1e01 00.10e01 +0.10e01 0.100e01 +.100e01 .1000e01 00001/01 +0001/01 000.1e+1 +00.1e+1 00.10e+1 +0.10e+1 0.100e+1 +.100e+1 .1000e+1 00010e-1 +0010e-1 10.00e-1 010.0e-1 +10.0e-1 0010.e-1 +010.e-1 0000.1e1 +000.1e1 000.10e1 +00.10e1 00.100e1 +0.100e1 0.1000e1 +.1000e1 .10000e1 000001/1 +00001/1 110/0110 0110/110 +110/110 10/00010 010/0010 +10/0010 0010/010 +010/010 00010/10 +0010/10 100/0100 0100/100 +100/100 1.000000 1e000000 01.00000 +1.00000 1e+00000 1e-00000 01e00000 +1e00000 1.e00000 001.0000 +01.0000 01e+0000 +1e+0000 1.e+0000 01e-0000 +1e-0000 1.e-0000 001e0000 +01e0000 1.0e0000 01.e0000 +1.e0000 0001.000 +001.000 001e+000 +01e+000 1.0e+000 01.e+000 +1.e+000 001e-000 +01e-000 1.0e-000 01.e-000 +1.e-000 0001e000 +001e000 1.00e000 01.0e000 +1.0e000 001.e000 +01.e000 00001.00 +0001.00 0001e+00 +001e+00 1.00e+00 01.0e+00 +1.0e+00 001.e+00 +01.e+00 0001e-00 +001e-00 1.00e-00 01.0e-00 +1.0e-00 001.e-00 +01.e-00 00001e00 +0001e00 1.000e00 01.00e00 +1.00e00 001.0e00 +01.0e00 0001.e00 +001.e00 000001.0 +00001.0 00001e+0 +0001e+0 1.000e+0 01.00e+0 +1.00e+0 001.0e+0 +01.0e+0 0001.e+0 +001.e+0 00001e-0 +0001e-0 1.000e-0 01.00e-0 +1.00e-0 001.0e-0 +01.0e-0 0001.e-0 +001.e-0 000001e0 +00001e0 1.0000e0 01.000e0 +1.000e0 001.00e0 +01.00e0 0001.0e0 +001.0e0 00001.e0 +0001.e0 0000001. +000001.)) (lambda args 'error)))) (if (not (eq? val #t)) (format-logged #t ";funny 1's are not all equal to 1? ~A~%" val))) (do ((i 0 (+ i 1))) ((= i 30)) (for-each (lambda (lst) (for-each (lambda (str) (let ((val (catch #t (lambda () (string->number str)) (lambda args 'error)))) (if (or (not (number? val)) (> (abs (- val 1.0)) 1.0e-15)) (format-logged #t ";(string->number ~S) = ~A?~%" str val)))) lst)) (list (list "1") (list "01" "+1" "1.") (list "001" "+01" "#e1" "#i1" "1/1" "#b1" "#x1" "#d1" "#o1" "1.0" "1e0" "9/9" "01." "+1." "1E0") (list "0001" "+001" "#e01" "#i01" "1/01" "#b01" "#x01" "#d01" "#o01" "#e+1" "#i+1" "#b+1" "#x+1" "#d+1" "#o+1" ".1e1" "01/1" "+1/1" "1.00" "1e00" "01.0" "+1.0" "1e+0" "1e-0" "01e0" "+1e0" "1.e0" "9/09" "09/9" "+9/9" "001." "+01." "#e1." "#i1." "1+0i" "1-0i" "#d1.") (list "11/11" "00001" "+0001" "#e001" "#i001" "1/001" "#b001" "#x001" "#d001" "#o001" "#e+01" "#i+01" "#b+01" "#x+01" "#d+01" "#o+01" ".1e01" "01/01" "+1/01" "91/91" ".1e+1" "10e-1" "0.1e1" "+.1e1" ".10e1" "#b#e1" "#x#e1" "#d#e1" "#o#e1" "#b#i1" "#x#i1" "#d#i1" "#o#i1" "001/1" "+01/1" "#e1/1" "#i1/1" "#b1/1" "#x1/1" "#d1/1" "#o1/1" "#e#b1" "#i#b1" "#e#x1" "#i#x1" "#e#d1" "#i#d1" "#e#o1" "#i#o1" "10/10" "1.000" "1e000" "01.00" "+1.00" "1e+00" "1e-00" "01e00" "+1e00" "1.e00" "90/90" "001.0" "+01.0" "#e1.0" "#i1.0" "01e+0" "+1e+0" "1.e+0" "01e-0" "+1e-0" "1.e-0" "001e0" "+01e0" "#e1e0" "#i1e0" "1.0e0" "01.e0" "+1.e0" "19/19" "9/009" "09/09" "+9/09" "99/99" "009/9" "+09/9" "#e9/9" "#i9/9" "#x9/9" "#d9/9" "0001." "+001." "#e01." "#i01." "#e+1." "#i+1." "#xe/e" "1+00i" "1-00i" "1+.0i" "1-.0i" "01+0i" "+1+0i" "1.+0i" "01-0i" "+1-0i" "1.-0i" "1+0.i" "1-0.i" "#xb/b" "#xd/d" "#xf/f") ;; remove "9": (list "11/011" "011/11" "+11/11" "000001" "+00001" "#e0001" "#i0001" "1/0001" "#b0001" "#x0001" "#d0001" "#o0001" "#e+001" "#i+001" "#b+001" "#x+001" "#d+001" "#o+001" ".1e001" "01/001" "+1/001" ".1e+01" "10e-01" "0.1e01" "+.1e01" ".10e01" "#b#e01" "#x#e01" "#d#e01" "#o#e01" "#b#i01" "#x#i01" "#d#i01" "#o#i01" "001/01" "+01/01" "#e1/01" "#i1/01" "#b1/01" "#x1/01" "#d1/01" "#o1/01" "#e#b01" "#i#b01" "#e#x01" "#i#x01" "#e#d01" "#i#d01" "#e#o01" "#i#o01" "0.1e+1" "+.1e+1" ".10e+1" "#b#e+1" "#x#e+1" "#d#e+1" "#o#e+1" "#b#i+1" "#x#i+1" "#d#i+1" "#o#i+1" "#e#b+1" "#i#b+1" "#e#x+1" "#i#x+1" "#e#d+1" "#i#d+1" "#e#o+1" "#i#o+1" "010e-1" "+10e-1" "10.e-1" "00.1e1" "+0.1e1" "#e.1e1" "#i.1e1" "0.10e1" "+.10e1" ".100e1" "0001/1" "+001/1" "#e01/1" "#i01/1" "#b01/1" "#x01/1" "#d01/1" "#o01/1" "#e+1/1" "#i+1/1" "#b+1/1" "#x+1/1" "#d+1/1" "#o+1/1" "10/010" "010/10" "+10/10" "1.0000" "1e0000" "01.000" "+1.000" "1e+000" "1e-000" "01e000" "+1e000" "1.e000" "001.00" "+01.00" "#e1.00" "#i1.00" "01e+00" "+1e+00" "1.e+00" "01e-00" "+1e-00" "1.e-00" "001e00" "+01e00" "#e1e00" "#i1e00" "1.0e00" "01.e00" "+1.e00" "0001.0" "+001.0" "#e01.0" "#i01.0" "#e+1.0" "#i+1.0" "001e+0" "+01e+0" "#e1e+0" "#i1e+0" "1.0e+0" "01.e+0" "+1.e+0" "001e-0" "+01e-0" "#e1e-0" "#i1e-0" "1.0e-0" "01.e-0" "+1.e-0" "0001e0" "+001e0" "#e01e0" "#i01e0" "#e+1e0" "#i+1e0" "1.00e0" "01.0e0" "+1.0e0" "001.e0" "+01.e0" "#e1.e0" "#i1.e0" "00001." "+0001." "#e001." "#i001." "#e+01." "#i+01." "#xe/0e" "#x0e/e" "#x+e/e" "1+0e1i" "1-0e1i" "1+0/1i" "1-0/1i" "1+000i" "1-000i" "1+.00i" "1-.00i" "01+00i" "+1+00i" "1.+00i" "01-00i" "+1-00i" "1.-00i" "1+0.0i" "1-0.0i" "01+.0i" "+1+.0i" "1.+.0i" "01-.0i" "+1-.0i" "1.-.0i" "001+0i" "+01+0i" "#e1+0i" "#i1+0i" "1/1+0i" "1.0+0i" "1e0+0i" "01.+0i" "+1.+0i" "001-0i" "+01-0i" "#e1-0i" "#i1-0i" "1/1-0i" "1.0-0i" "1e0-0i" "01.-0i" "+1.-0i" "1+0e0i" "1-0e0i" "1+00.i" "1-00.i" "01+0.i" "+1+0.i" "1.+0.i" "01-0.i" "+1-0.i" "1.-0.i" "#xb/0b" "#x0b/b" "#x+b/b" "#xd/0d" "#x0d/d" "#x+d/d" "#xf/0f" "#x0f/f" "#x+f/f") (list "111/111" "11/0011" "011/011" "+11/011" "0011/11" "+011/11" "#e11/11" "#i11/11" "#b11/11" "#x11/11" "#d11/11" "#o11/11" "101/101" "0000001" "+000001" "#e00001" "#i00001" "1/00001" "#b00001" "#x00001" "#d00001" "#o00001" "#e+0001" "#i+0001" "#b+0001" "#x+0001" "#d+0001" "#o+0001" ".1e0001" "01/0001" "+1/0001" ".1e+001" "10e-001" "0.1e001" "+.1e001" ".10e001" "#b#e001" "#x#e001" "#d#e001" "#o#e001" "#b#i001" "#x#i001" "#d#i001" "#o#i001" "001/001" "+01/001" "#e1/001" "#i1/001" "#b1/001" "#x1/001" "#d1/001" "#o1/001" "#e#b001" "#i#b001" "#e#x001" "#i#x001" "#e#d001" "#i#d001" "#e#o001" "#i#o001" "0.1e+01" "+.1e+01" ".10e+01" "#b#e+01" "#x#e+01" "#d#e+01" "#o#e+01" "#b#i+01" "#x#i+01" "#d#i+01" "#o#i+01" "#e#b+01" "#i#b+01" "#e#x+01" "#i#x+01" "#e#d+01" "#i#d+01" "#e#o+01" "#i#o+01" "010e-01" "+10e-01" "10.e-01" "1.00000" "1e00000" "01.0000" "+1.0000" "1e+0000" "1e-0000" "01e0000" "+1e0000" "1.e0000" "001.000" "+01.000" "#e1.000" "#i1.000" "#d1.000" "01e+000" "+1e+000" "1.e+000" "01e-000" "+1e-000" "1.e-000" "001e000" "+01e000" "#e1e000" "#i1e000" "#d1e000" "1.0e000" "+1.e000" "0001.00" "+001.00" "#e01.00" "#i01.00" "#d01.00" "#e+1.00" "#i+1.00" "#d+1.00" "001e+00" "+01e+00" "#e1e+00" "#i1e+00" "#d1e+00" "1.0e+00" "01.e+00" "+1.e+00" "001e-00" "+01e-00" "#e1e-00" "#i1e-00" "#d1e-00" "1.0e-00" "01.e-00" "+1.e-00" "000001." "+00001." "#e0001." "#i0001." "#d0001." "#e+001." "#i+001." "#d+001." "#d#e01." "#d#i01." "#e#d01." "#i#d01." "#d#e+1." "#d#i+1." "#e#d+1." "#i#d+1." "#x1e/1e" "#xe/00e" "#x0e/0e" "#x+e/0e" "#xee/ee" "#x00e/e" "#x+0e/e" "#x#ee/e" "#x#ie/e" "#e#xe/e" "#i#xe/e" "#xbe/be" "#xde/de" "1+0e11i" "1-0e11i" "1+0/11i" "1-0/11i" "1+0e01i" "1-0e01i" "1+0/01i" "1-0/01i" "1+0e+1i" "1-0e+1i" "1+0e-1i" "1-0e-1i" "1+00e1i" "1-00e1i" "1+.0e1i" "1-.0e1i" "01+0e1i" "+1+0e1i" "1.+0e1i" "01-0e1i" "+1-0e1i" "1.-0e1i" "1+0.e1i" "1-0.e1i" "1+00/1i" "1-00/1i" "01+0/1i" "+1+0/1i" "1.+0/1i" "01-0/1i" "+1-0/1i" "1.-0/1i" "1+0e10i" "1-0e10i" "1+0/10i" "1-0/10i" "1+0000i" "1-0000i" "1+.000i" "1-.000i" "01+000i" "+1+000i" "1.+000i" "01-000i" "+1-000i" "1.-000i" "1+0.00i" "1-0.00i" "01+.00i" "+1+.00i" "1.+.00i" "01-.00i" "+1-.00i" "1.-.00i" "001+00i" "+01+00i" "#e1+00i" "#i1+00i" "1/1+00i" "#b1+00i" "#x1+00i" "#d1+00i" "#o1+00i" "1.0+00i" "1e0+00i" "01.+00i" "+1.+00i" "001-00i" "+01-00i" "#e1-00i" "#i1-00i" "1/1-00i" "#b1-00i" "#x1-00i" "#d1-00i" "#o1-00i" "1.0-00i" "1e0-00i" "01.-00i" "+1.-00i" "1+0e00i" "1-0e00i" "1+00.0i" "1-00.0i" "01+0.0i" "+1+0.0i" "1.+0.0i" "01-0.0i" "+1-0.0i" "1.-0.0i" "001+.0i" "+01+.0i" "#e1+.0i" "#i1+.0i" "1/1+.0i" "#d1+.0i" "1.0+.0i" "1e0+.0i" "01.+.0i" "+1.+.0i" "001-.0i" "+01-.0i" "#e1-.0i" "#i1-.0i" "1/1-.0i" "#d1-.0i" "1.0-.0i" "1e0-.0i" "01.-.0i" "+1.-.0i" "0001+0i" "+001+0i" "#e01+0i" "#i01+0i" "1/01+0i" "#b01+0i" "#x01+0i" "#d01+0i" "#o01+0i" "#e+1+0i" "#i+1+0i" "#b+1+0i" "#x+1+0i" "#d+1+0i" "#o+1+0i" ".1e1+0i" "01/1+0i" "+1/1+0i" "1.00+0i" "1e00+0i" "01.0+0i" "+1.0+0i" "1e+0+0i" "1e-0+0i" "01e0+0i" "+1e0+0i" "1.e0+0i" "001.+0i" "+01.+0i" "#e1.+0i" "#i1.+0i" "#d1.+0i" "1+0e+0i" "1-0e+0i" "0001-0i" "+001-0i" "#e01-0i" "#i01-0i" "1/01-0i" "#b01-0i" "#x01-0i" "#d01-0i" "#o01-0i" "#e+1-0i" "#i+1-0i" "#b+1-0i" "#x+1-0i" "#d+1-0i" "#o+1-0i" ".1e1-0i" "01/1-0i" "+1/1-0i" "1.00-0i" "1e00-0i" "01.0-0i" "+1.0-0i" "1e+0-0i" "1e-0-0i" "01e0-0i" "+1e0-0i" "1.e0-0i" "001.-0i" "+01.-0i" "#e1.-0i" "#i1.-0i" "#d1.-0i" "1+0e-0i" "1-0e-0i" "1+00e0i" "1-00e0i" "1+.0e0i" "1-.0e0i" "01+0e0i" "+1+0e0i" "1.+0e0i" "01-0e0i" "+1-0e0i" "1.-0e0i" "1+0.e0i" "1-0.e0i" "1+000.i" "1-000.i" "01+00.i" "+1+00.i" "1.+00.i" "01-00.i" "+1-00.i" "1.-00.i" "001+0.i" "+01+0.i" "#e1+0.i" "#i1+0.i" "1/1+0.i" "#d1+0.i" "1.0+0.i" "1e0+0.i" "+1.+0.i" "001-0.i" "+01-0.i" "#e1-0.i" "#i1-0.i" "1/1-0.i" "#d1-0.i" "1.0-0.i" "1e0-0.i" "01.-0.i" "+1.-0.i" "#xb/00b" "#x0b/0b" "#x+b/0b" "#xeb/eb" "#x00b/b" "#x+0b/b" "#x#eb/b" "#x#ib/b" "#e#xb/b" "#i#xb/b" "#xbb/bb" "#xdb/db" "#xd/00d" "#x0d/0d" "#x+d/0d" "#xed/ed") ;;; selected ones... (list "#i+11/011" "+101/0101" "#o#e11/11" "#d+11/011" "#e1/0001" "#e#b+001" "#e10e-1" "#x#e1/001" "000000001" "#i+.1e+01" "#d+.1e+01" "00.10e+01" "+0.10e+01" "#e.10e+01" "#i.10e+01" "#d.10e+01" "#e.10e+01" "#i10.0e-01" "+010.e-01" "#e10.e-01" "#e00.1e01" "#e#d.1e01" "#i#d1e0+0e0i" "#e#d10e-1+0e-2i" "#e#d1e0+0e-2i" "#i#d+0.001e+03+0.0e-10i" "#i#d+1/1-0/1i" ) ))) (for-each (lambda (str) (let ((val (catch #t (lambda () (string->number str)) (lambda args 'error)))) (if (or (not (number? val)) (= val 1)) (format-logged #t ";(string->number ~S = ~A?~%" str val)))) (list "011e0" "11e-00" "00.e01-i" "+10e10+i" "+1.110+i" "10011-0i" "-000.111" "0.100111" "-11.1111" "10.00011" "110e00+i" "1e-011+i" "101001+i" "+11e-0-0i" "11+00e+0i" "-11101.-i" "1110e-0-i")) (for-each (lambda (str) (test (string->number str) #f)) ; an error but string->number is not supposed to return an error -- just #f or a number (list "#e1+i" "#e1-i" "#e01+i" "#e+1+i" "#e1.+i" "#e01-i" "#e+1-i" "#e1.-i" "#e1+1i" "#e1-1i")) (num-test (let ((0- 1) (1+ 2) (-0+ 3) (1e 4) (1/+2 5) (--1 6)) (+ 0- 1+ -0+ 1e 1/+2 --1)) 21) (for-each (lambda (str) (let ((val (catch #t (lambda () (string->number str)) (lambda args 'error)))) (if val ;(number? val) (format-logged #t ";(string->number ~S) = ~A?~%" str val)))) (list "#b#e#e1" "#x#e#e1" "#d#e#e1" "#o#e#e1" "#b#i#e1" "#x#i#e1" "#d#i#e1" "#o#i#e1" "#e#b#e1" "#i#b#e1" "#e#x#e1" "#i#x#e1" "#e#d#e1" "#i#d#e1" "#e#o#e1" "#i#o#e1" "#e#b#i1" "#e#x#i1" "#e#d#i1" "#e#o#i1" "#b#e#b1" "#x#e#b1" "#d#e#b1" "#o#e#b1" "#b#i#b1" "#x#i#b1" "#d#i#b1" "#o#i#b1" "#b#e#x1" "#x#e#x1" "#d#e#x1" "#o#e#x1" "#b#i#x1" "#x#i#x1" "#d#i#x1" "#o#i#x1" "#b#e#d1" "#x#e#d1" "#d#e#d1" "#o#e#d1" "#b#i#d1" "#x#i#d1" "#d#i#d1" "#o#i#d1" "#b#e#o1" "#x#e#o1" "#d#e#o1" "#o#e#o1" "#b#i#o1" "#x#i#o1" "#d#i#o1" "#o#i#o1" "+1ei" "-1ei" "+0ei" "-0ei" "+1di" "-1di" "+0di" "-0di" "+1fi" "-1fi" "+0fi" "-0fi" "0e-+i" "1d-+i" "0d-+i" "1f-+i" "0f-+i" "1e++i" "0e++i" "1d++i" ".10-10." "-1.e++i" "0e--01i" "1-00." "0-00." "#xf+b" "#x1+d" "0f++1i" "1+0d-i" ".0f--i" "1-0d-i" "#xe-ff" "0-" "0-e0" "-#b1" "#b.i" "#b+i" "#b1e.1" "#b1+1" "#b#e#e1" "#b#ee1" "#b#e0e" "#d#d1" "#d#1d1" "#b+1ei" "#b-1ei" "#b+0ei" "#b-0ei" "#b+1di" "#b-1di" "#b+0di" "#b-0di" "#b+1fi" "#b-1fi" "#b+0fi" "#b-0fi" "#b0e-+i" "#b1d-+i" )) (num-test (string->number "2.718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427") 2.718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427) ;; from testbase-report.ps Vern Paxson (with some changes) ;; resultant strings are thanks to clisp (let ((cases (list (list '(* 49517601571415211 (expt 2 -94)) "2.5e-12") (list '(* 49517601571415211 (expt 2 -95)) "1.25e-12") (list '(* 54390733528642804 (expt 2 -133)) "4.995e-24") (list '(* 71805402319113924 (expt 2 -157)) "3.9305e-31") (list '(* 40435277969631694 (expt 2 -179)) "5.27705e-38") (list '(* 57241991568619049 (expt 2 -165)) "1.223955e-33") (list '(* 65224162876242886 (expt 2.0 58)) "1.8799585e+34") (list '(* 70173376848895368 (expt 2 -138)) "2.01387715e-25") (list '(* 37072848117383207 (expt 2 -99)) "5.849064105e-14") (list '(* 56845051585389697 (expt 2 -176)) "5.9349003055e-37") (list '(* 54791673366936431 (expt 2 -145)) "1.22847180395e-27") (list '(* 66800318669106231 (expt 2 -169)) "8.927076718085e-35") (list '(* 66800318669106231 (expt 2 -170)) "4.4635383590425e-35") (list '(* 66574323440112438 (expt 2 -119)) "1.00169908625495e-19") (list '(* 65645179969330963 (expt 2 -173)) "5.482941262802465e-36") (list '(* 61847254334681076 (expt 2 -109)) "9.529078328103644e-17") (list '(* 39990712921393606 (expt 2 -145)) "8.966227936640557e-28") (list '(* 59292318184400283 (expt 2 -149)) "8.308623441805854e-29") (list '(* 69116558615326153 (expt 2 -143)) "6.1985873566126555e-27") (list '(* 69116558615326153 (expt 2 -144)) "3.0992936783063277e-27") (list '(* 39462549494468513 (expt 2 -152)) "6.912351250617602e-30") (list '(* 39462549494468513 (expt 2 -153)) "3.456175625308801e-30") (list '(* 50883641005312716 (expt 2 -172)) "8.5e-36") (list '(* 38162730753984537 (expt 2 -170)) "2.55e-35") (list '(* 50832789069151999 (expt 2 -101)) "2.005e-14") (list '(* 51822367833714164 (expt 2 -109)) "7.984499999999999e-17") (list '(* 66840152193508133 (expt 2 -172)) "1.11655e-35") (list '(* 55111239245584393 (expt 2 -138)) "1.581615e-25") (list '(* 71704866733321482 (expt 2 -112)) "1.3809855e-17") (list '(* 67160949328233173 (expt 2 -142)) "1.20464045e-26") (list '(* 53237141308040189 (expt 2 -152)) "9.325140545e-30") (list '(* 62785329394975786 (expt 2 -112)) "1.2092014595e-17") (list '(* 48367680154689523 (expt 2 -77)) "3.20070458385e-07") (list '(* 42552223180606797 (expt 2 -102)) "8.391946324355e-15") (list '(* 63626356173011241 (expt 2 -112)) "1.2253990460585e-17") (list '(* 43566388595783643 (expt 2 -99)) "6.87356414897605e-14") (list '(* 54512669636675272 (expt 2 -159)) "7.459816430480385e-32") (list '(* 52306490527514614 (expt 2 -167)) "2.7960588398142556e-34") (list '(* 52306490527514614 (expt 2 -168)) "1.3980294199071278e-34") (list '(* 41024721590449423 (expt 2 -89)) "6.627901237305737e-11") (list '(* 37664020415894738 (expt 2 -132)) "6.917788004396807e-24") (list '(* 37549883692866294 (expt 2 -93)) "3.791569310834971e-12") (list '(* 69124110374399839 (expt 2 -104)) "3.408081767659137e-15") (list '(* 69124110374399839 (expt 2 -105)) "1.7040408838295685e-15") (list '(* 9 (expt 10 26)) "9e+26") (list '(* 79 (expt 10 -8)) "7.9e-07") (list '(* 393 (expt 10.0 26)) "3.93e+28") (list '(* 9171 (expt 10 -40)) "9.171e-37") (list '(* 56257 (expt 10 -16)) "5.6257e-12") (list '(* 281285 (expt 10 -17)) "2.81285e-12") (list '(* 4691113 (expt 10 -43)) "4.691113e-37") (list '(* 29994057 (expt 10 -15)) "2.9994057e-08") (list '(* 834548641 (expt 10 -46)) "8.34548641e-38") (list '(* 1058695771 (expt 10 -47)) "1.058695771e-38") (list '(* 87365670181 (expt 10 -18)) "8.7365670181e-08") (list '(* 872580695561 (expt 10 -36)) "8.72580695561e-25") (list '(* 6638060417081 (expt 10 -51)) "6.638060417081e-39") (list '(* 88473759402752 (expt 10 -52)) "8.8473759402752e-39") (list '(* 412413848938563 (expt 10 -27)) "4.12413848938563e-13") (list '(* 5592117679628511 (expt 10 -48)) "5.592117679628511e-33") (list '(* 83881765194427665 (expt 10 -50)) "8.388176519442766e-34") ;(list '(* 638632866154697279 (expt 10 -35)) "6.3863286615469725e-18") ;(list '(* 3624461315401357483 (expt 10 -53)) "3.6244613154013574e-35") ;(list '(* 75831386216699428651 (expt 10 -30)) "7.583138621669942e-11") ;(list '(* 356645068918103229683 (expt 10 -42)) "3.566450689181032e-22") ;(list '(* 7022835002724438581513 (expt 10 -33)) "7.022835002724439e-12") (list '(* 7 (expt 10 -27)) "7e-27") (list '(* 37 (expt 10 -29)) "3.7e-28") (list '(* 743 (expt 10 -18)) "7.43e-16") (list '(* 7861 (expt 10 -33)) "7.861e-30") (list '(* 46073 (expt 10 -30)) "4.6073e-26") (list '(* 774497 (expt 10 -34)) "7.74497e-29") (list '(* 8184513 (expt 10 -33)) "8.184513e-27") (list '(* 89842219 (expt 10 -28)) "8.9842219e-21") (list '(* 449211095 (expt 10 -29)) "4.49211095e-21") (list '(* 8128913627 (expt 10 -40)) "8.128913627e-31") (list '(* 87365670181 (expt 10 -18)) "8.7365670181e-08") (list '(* 436828350905 (expt 10 -19)) "4.36828350905e-08") (list '(* 5569902441849 (expt 10 -49)) "5.569902441849e-37") (list '(* 60101945175297 (expt 10 -32)) "6.0101945175297e-19") (list '(* 754205928904091 (expt 10 -51)) "7.54205928904091e-37") (list '(* 5930988018823113 (expt 10 -37)) "5.930988018823113e-22") (list '(* 51417459976130695 (expt 10 -27)) "5.14174599761307e-11") (list '(* 826224659167966417 (expt 10 -41)) "8.262246591679665e-24") ;(list '(* 9612793100620708287 (expt 10 -57)) "9.612793100620708e-39") ;(list '(* 93219542812847969081 (expt 10 -39)) "9.321954281284797e-20") ;(list '(* 544579064588249633923 (expt 10 -48)) "5.445790645882496e-28") ;(list '(* 4985301935905831716201 (expt 10 -48)) "4.9853019359058315e-27") (list '(* 12676506 (expt 2 -102)) "2.499999999549897e-24") (list '(* 12676506 (expt 2 -103)) "1.2499999997749484e-24") (list '(* 15445013 (expt 2.0 86)) "1.1949999999989506e+33") (list '(* 13734123 (expt 2 -138)) "3.941499999999621e-35") (list '(* 12428269 (expt 2 -130)) "9.13084999999985e-33") (list '(* 15334037 (expt 2 -146)) "1.719004999999994e-37") (list '(* 11518287 (expt 2 -41)) "5.237910499999998e-06") (list '(* 12584953 (expt 2 -145)) "2.82164405e-37") (list '(* 15961084 (expt 2 -125)) "3.752432815e-31") (list '(* 14915817 (expt 2 -146)) "1.6721209165e-37") (list '(* 10845484 (expt 2 -102)) "2.13889458145e-24") (list '(* 16431059 (expt 2 -61)) "7.125835945615e-12") (list '(* 16093626 (expt 2.0 69)) "9.500000001279935e+27") (list '(* 9983778 (expt 2.0 25)) "335000000004096.0") (list '(* 12745034 (expt 2.0 104)) "2.5850000000046706e+38") (list '(* 12706553 (expt 2.0 72)) "6.000500000000674e+28") (list '(* 11005028 (expt 2.0 45)) "3.8720500000001465e+20") (list '(* 15059547 (expt 2.0 71)) "3.555835000000006e+28") (list '(* 16015691 (expt 2 -99)) "2.5268305000000024e-23") (list '(* 8667859 (expt 2.0 56)) "6.24585065e+23") (list '(* 14855922 (expt 2 -82)) "3.072132665e-18") (list '(* 14855922 (expt 2 -83)) "1.5360663325e-18") (list '(* 10144164 (expt 2 -110)) "7.81477968335e-27") (list '(* 13248074 (expt 2.0 95)) "5.248102799365e+35") (list '(* 5 (expt 10 -20)) "5e-20") (list '(* 67 (expt 10.0 14)) "6.7e+15") (list '(* 985 (expt 10.0 15)) "9.85e+17") (list '(* 7693 (expt 10 -42)) "7.693e-39") (list '(* 55895 (expt 10 -16)) "5.5895e-12") (list '(* 996622 (expt 10 -44)) "9.96622e-39") (list '(* 7038531 (expt 10 -32)) "7.038531e-26") (list '(* 60419369 (expt 10 -46)) "6.0419369e-39") (list '(* 702990899 (expt 10 -20)) "7.02990899e-12") (list '(* 6930161142 (expt 10 -48)) "6.930161142e-39") (list '(* 25933168707 (expt 10.0 13)) "2.5933168707e+23") (list '(* 596428896559 (expt 10.0 20)) "5.96428896559e+31") (list '(* 3 (expt 10 -23)) "3e-23") (list '(* 57 (expt 10.0 18)) "5.7e+19") (list '(* 789 (expt 10 -35)) "7.89e-33") (list '(* 2539 (expt 10 -18)) "2.539e-15") (list '(* 76173 (expt 10.0 28)) "7.6173e+32") (list '(* 887745 (expt 10 -11)) "8.87745e-06") (list '(* 5382571 (expt 10 -37)) "5.382571e-31") (list '(* 82381273 (expt 10 -35)) "8.2381273e-28") (list '(* 750486563 (expt 10 -38)) "7.50486563e-30") (list '(* 3752432815 (expt 10 -39)) "3.752432815e-30") (list '(* 75224575729 (expt 10 -45)) "7.5224575729e-35") (list '(* 459926601011 (expt 10.0 15)) "4.59926601011e+26") ; 10.0 (and 2.0 above) because we aren't interested here in numeric overflows ))) (let ((maxdiff 0.0) (maxdiff-case ())) (do ((lst cases (cdr lst))) ((null? lst)) (let* ((form (caar lst)) (str (cadar lst)) (num (eval form)) (fnum (* 1.0 num)) (n2s (number->string fnum)) (s2n (string->number n2s)) (mnum (string->number str)) (diff (let () (if (not (string? n2s)) (format-logged #t "(number->string ~A) #f?~%" fnum)) (if (not (number? s2n)) (format-logged #t "(string->number ~S) #f?~%" n2s)) (/ (abs (- mnum s2n)) (max (expt 2 -31.0) (abs fnum)))))) (if (> diff maxdiff) (begin (set! maxdiff diff) (set! maxdiff-case (car lst)))))) (if (> maxdiff 1e-15) ; we're only interested in real problems (format-logged #t ";number->string rounding checks worst case relative error ~A ~A ~S~%" maxdiff (car maxdiff-case) (cadr maxdiff-case))) )) (for-each (lambda (p) (let ((sym (car p)) (num (cdr p))) (let ((tag (catch #t (lambda () (string->number sym)) (lambda args 'error)))) (if (not (equal? num tag)) (format-logged #t ";(string->number ~S) = ~A [~A]~%" sym tag num))))) '(("#xe/d" . 14/13) ("#xb/d" . 11/13) ("#xf/d" . 15/13) ("#x1/f" . 1/15) ("#xd/f" . 13/15) ("#xe/f" . 14/15) ("#d.1" . .1) ("#d01" . 1) ("#d+1" . 1) ("#d+0" . 0) ("#d0+i" . 0+i) ("#xe+i" . 14.0+1.0i) ("#xf+i" . 15.0+1.0i) ("#d1-i" . 1.0-1.0i); ("#e1+i" . 1+i) )) #| ;;; here's code to generate all (im)possible numbers (using just a few digits) of a given length (define file (open-output-file "ntest.scm")) (define chars (list #\1 #\0 #\9 #\# #\. #\+ #\- #\e #\i #\/ #\b #\x #\d #\o #\l #\s #\f #\@)) (define (all-syms len with-file) (let ((sym (make-string len)) (num-chars (length chars)) (ctrs (make-vector len 0))) (do ((i 0 (+ i 1))) ((= i (expt num-chars len))) (let ((carry #t)) (do ((k 0 (+ k 1))) ((or (= k len) (not carry))) (vector-set! ctrs k (+ 1 (vector-ref ctrs k))) (if (= (vector-ref ctrs k) num-chars) (vector-set! ctrs k 0) (set! carry #f))) (do ((k 0 (+ k 1))) ((= k len)) (string-set! sym k (list-ref chars (vector-ref ctrs k))))) (let ((tag (catch #t (lambda () (string->number sym)) (lambda args (car args))))) (if (not with-file) (if (and (number? tag) (= tag 1)) (format #t "~S " sym)) (begin (if (number? tag) (format file "(if (not (number? (string->number ~S))) (begin (display ~S) (display #\\space)))" sym sym) (format file "(if (number? (string->number ~S)) (begin (display ~S) (display #\\space)))" sym sym)) (newline file))))))) (do ((len 1 (+ len 1))) ((= len 12)) (all-syms len #f)) (close-output-port file) |# (let () (define (~ !) (* 2 !)) (test (~ 3) 6) (define (~~ !) (* 2 !)) (test (~~ 3) 6) (define (\x00 !) (* 2 !)) (test (\x00 3) 6)) (for-each (lambda (n name) (if (number? n) (format-logged #t ";(number? ~A) returned #t?~%" name))) (list 'a9 'aa 'aA 'a! 'a$ 'a% 'a& 'a* 'a+ 'a- 'a. 'a/ 'a: 'a< 'a= 'a> 'a? 'a@ 'a^ 'a_ 'a~ 'A9 'Aa 'AA 'A! 'A$ 'A% 'A& 'A* 'A+ 'A- 'A. 'A/ 'A: 'A< 'A= 'A> 'A? 'A@ 'A^ 'A_ 'A~ '!9 '!a '!A '!! '!$ '!% '!& '!* '!+ '!- '!. '!/ '!: '!< '!= '!> '!? '!@ '!^ '!_ '!~ '$9 '$a '$A '$! '$$ '$% '$& '$* '$+ '$- '$. '$/ '$: '$< '$= '$> '$? '$@ '$^ '$_ '$~ '%9 '%a '%A '%! '%$ '%% '%& '%* '%+ '%- '%. '%/ '%: '%< '%= '%> '%? '%@ '%^ '%_ '%~ '&9 '&a '&A '&! '&$ '&% '&& '&* '&+ '&- '&. '&/ '&: '&< '&= '&> '&? '&@ '&^ '&_ '&~ '*9 '*a '*A '*! '*$ '*% '*& '** '*+ '*- '*. '*/ '*: '*< '*= '*> '*? '*@ '*^ '*_ '*~ '/9 '/a '/A '/! '/$ '/% '/& '/* '/+ '/- '/. '// '/: '/< '/= '/> '/? '/@ '/^ '/_ '/~ ':9 ':a ':A ':! ':$ ':% ':& ':* ':+ ':- ':. ':/ ':: ':< ':= ':> ':? ':@ ':^ ':_ ':~ '<9 ' '=? '=@ '=^ '=_ '=~ '>9 '>a '>A '>! '>$ '>% '>& '>* '>+ '>- '>. '>/ '>: '>< '>= '>> '>? '>@ '>^ '>_ '>~ '?9 '?a '?A '?! '?$ '?% '?& '?* '?+ '?- '?. '?/ '?: '?< '?= '?> '?? '?@ '?^ '?_ '?~ '^9 '^a '^A '^! '^$ '^% '^& '^* '^+ '^- '^. '^/ '^: '^< '^= '^> '^? '^@ '^^ '^_ '^~ '_9 '_a '_A '_! '_$ '_% '_& '_* '_+ '_- '_. '_/ '_: '_< '_= '_> '_? '_@ '_^ '__ '_~ '~9 '~a '~A '~! '~$ '~% '~& '~* '~+ '~- '~. '~/ '~: '~< '~= '~> '~? '~@ '~^ '~_ '~~) (list "'a9" "'aa" "'aA" "'a!" "'a$" "'a%" "'a&" "'a*" "'a+" "'a-" "'a." "'a/" "'a:" "'a<" "'a=" "'a>" "'a?" "'a@" "'a^" "'a_" "'a~" "'A9" "'Aa" "'AA" "'A!" "'A$" "'A%" "'A&" "'A*" "'A+" "'A-" "'A." "'A/" "'A:" "'A<" "'A=" "'A>" "'A?" "'A@" "'A^" "'A_" "'A~" "'!9" "'!a" "'!A" "'!!" "'!$" "'!%" "'!&" "'!*" "'!+" "'!-" "'!." "'!/" "'!:" "'!<" "'!=" "'!>" "'!?" "'!@" "'!^" "'!_" "'!~" "'$9" "'$a" "'$A" "'$!" "'$$" "'$%" "'$&" "'$*" "'$+" "'$-" "'$." "'$/" "'$:" "'$<" "'$=" "'$>" "'$?" "'$@" "'$^" "'$_" "'$~" "'%9" "'%a" "'%A" "'%!" "'%$" "'%%" "'%&" "'%*" "'%+" "'%-" "'%." "'%/" "'%:" "'%<" "'%=" "'%>" "'%?" "'%@" "'%^" "'%_" "'%~" "'&9" "'&a" "'&A" "'&!" "'&$" "'&%" "'&&" "'&*" "'&+" "'&-" "'&." "'&/" "'&:" "'&<" "'&=" "'&>" "'&?" "'&@" "'&^" "'&_" "'&~" "'*9" "'*a" "'*A" "'*!" "'*$" "'*%" "'*&" "'**" "'*+" "'*-" "'*." "'*/" "'*:" "'*<" "'*=" "'*>" "'*?" "'*@" "'*^" "'*_" "'*~" "'/9" "'/a" "'/A" "'/!" "'/$" "'/%" "'/&" "'/*" "'/+" "'/-" "'/." "'//" "'/:" "'/<" "'/=" "'/>" "'/?" "'/@" "'/^" "'/_" "'/~" "':9" "':a" "':A" "':!" "':$" "':%" "':&" "':*" "':+" "':-" "':." "':/" "'::" "':<" "':=" "':>" "':?" "':@" "':^" "':_" "':~" "'<9" "'" "'" "'=?" "'=@" "'=^" "'=_" "'=~" "'>9" "'>a" "'>A" "'>!" "'>$" "'>%" "'>&" "'>*" "'>+" "'>-" "'>." "'>/" "'>:" "'><" "'>=" "'>>" "'>?" "'>@" "'>^" "'>_" "'>~" "'?9" "'?a" "'?A" "'?!" "'?$" "'?%" "'?&" "'?*" "'?+" "'?-" "'?." "'?/" "'?:" "'?<" "'?=" "'?>" "'??" "'?@" "'?^" "'?_" "'?~" "'^9" "'^a" "'^A" "'^!" "'^$" "'^%" "'^&" "'^*" "'^+" "'^-" "'^." "'^/" "'^:" "'^<" "'^=" "'^>" "'^?" "'^@" "'^^" "'^_" "'^~" "'_9" "'_a" "'_A" "'_!" "'_$" "'_%" "'_&" "'_*" "'_+" "'_-" "'_." "'_/" "'_:" "'_<" "'_=" "'_>" "'_?" "'_@" "'_^" "'__" "'_~" "'~9" "'~a" "'~A" "'~!" "'~$" "'~%" "'~&" "'~*" "'~+" "'~-" "'~." "'~/" "'~:" "'~<" "'~=" "'~>" "'~?" "'~@" "'~^" "'~_" "'~~")) ;(let ((initial-chars "aA!$%&*/:<=>?^_~") ; (subsequent-chars "9aA!$%&*+-./:<=>?@^_~")) ; (do ((i 0 (+ i 1))) ; ((= i (string-length initial-chars))) ; (do ((k 0 (+ k 1))) ; ((= k (string-length subsequent-chars))) ; (format-logged #t "'~A " (string (string-ref initial-chars i) (string-ref subsequent-chars k)))))) (for-each (lambda (z) (if (not (zero? z)) (format-logged #t "~A is not zero?~%" z)) (if (and (real? z) (positive? z)) (format-logged #t "~A is positive?~%" z)) (if (and (real? z) (negative? z)) (format-logged #t "~A is negative?~%" z))) '(0 -0 +0 0.0 -0.0 +0.0 0/1 -0/1 +0/24 0+0i 0-0i -0-0i +0-0i 0.0-0.0i -0.0+0i #b0 #o-0 #x000 #e0 #e0.0 #e#b0 #b#e0 #e0/1 #b+0 #d000/1111 000/111)) (for-each (lambda (x) (if (string->number x) (format-logged #t ";(string->number ~A) returned ~A~%" x (string->number x)))) '("" "q" "1q" "6+7iq" "8+9q" "10+11" "13+" "18@19q" "20@q" "23@" "+25iq" "26i" "-q" "-iq" "i" "5#.0" "8/" "10#11" ".#" "." "3.4q" "15.16e17q" "18.19e+q" ".q" ".17#18" "10q" "#b2" "#b12" "#b-12" "#b3" "#b4" "#b5" "#b6" "#b7" "#b8" "#b9" "#ba" "#bb" "#bc" "#bd" "#be" "#bf" "#q" "#b#b1" "#o#o1" "#d#d1" "#x#x1" "#e#e1" "#xag" "#x1x" "#o8" "#o9" "1/#e1" "#o#" "#e#i1" "#d--2" "#b#x1" "#i#x#b1" "#e#e#b1" "#e#b#b1" "-#b1" "+#b1" "#b1/#b2" "#b1+#b1i" "1+#bi" "1+#b1i" "1#be1" "#b" "#o" "#" "#ea" "#e1a" "1+ie1" "1+i1" "1e+1i" "#e#b" "#b#b" "#b#b1" "1e3e4" "1.0e-3e+4" "1e3s" "1e3s3" "#o#x1" "#i#i1" "1e-i" "#be1" "1/i" "1/e1" "1+e1" "1e+" "1e1+" "1e1e1" "1e-+1" "1e0x1" "1e-" "1/#o2" "#i#i1" "12@12i")) (for-each (lambda (couple) (apply (lambda (x y) (let ((xx (string->number x))) (if (or (not xx) (not y) (and (rational? y) (not (eqv? xx y))) (> (abs (- xx y)) 1e-12)) (format-logged #t ";(string->number ~A) returned ~A but expected ~A (~A ~A ~A ~A)~%" x (string->number x) y xx (eq? xx #f) (if (and xx y) (and (rational? y) (not (eqv? xx y))) #f) (if (and xx y) (abs (- xx y)) #f))))) couple)) '( ("#b0" 0) ("#b1" 1) ("#o0" 0) ("#b-1" -1) ("#b+1" 1) ("#o1" 1) ("#o2" 2) ("#o3" 3) ("#o-1" -1) ("#o4" 4) ("#o5" 5) ("#o6" 6) ("#o7" 7) ("#d0" 0) ("#d1" 1) ("#d2" 2) ("#d3" 3) ("#d4" 4) ("#d5" 5) ("#d6" 6) ("#d7" 7) ("#d-123" -123) ("#d+123" 123) ("#d8" 8) ("#d9" 9) ("#xa" 10) ("#xb" 11) ("#x-1" -1) ("#x-a" -10) ("#xc" 12) ("#xd" 13) ("#xe" 14) ("#xf" 15) ("#x-abc" -2748) ("#b1010" 10) ("#o12345670" 2739128) ("#d1234567890" 1234567890) ("#x1234567890abcdef" 1311768467294899695) ("#e1" 1) ("#e1.2" 12/10) ("#i1.1" 1.1) ("#i1" 1.0) ("1" 1) ("23" 23) ("-1" -1) ("-45" -45) ;("2#" 20.0) ("2##" 200.0) ("12##" 1200.0) ; this # = 0 is about the stupidest thing I've ever seen ("#b#i100" 4.0) ("#b#e100" 4) ("#i#b100" 4.0) ("#e#b100" 4) ("#b#i-100" -4.0) ("#b#e+100" 4) ("#i#b-100" -4.0) ("#e#b+100" 4) ("#o#i100" 64.0) ("#o#e100" 64) ("#i#o100" 64.0) ("#e#o100" 64) ("#d#i100" 100.0) ("#d#e100" 100) ("#i#d100" 100.0) ("#e#d100" 100) ("#x#i100" 256.0) ("#x#e100" 256) ("#i#x100" 256.0) ("#e#x100" 256) ("#e#xee" 238) ("#e#x1e1" 481) ("#xA" 10) ("#xB" 11) ("#x-1" -1) ("#x-A" -10) ("#xC" 12) ("#xD" 13) ("#xE" 14) ("#xF" 15) ("#x-ABC" -2748) ("#xaBC" 2748) ("#xAbC" 2748) ("#xabC" 2748) ("#xABc" 2748) ("1/1" 1) ("1/2" 1/2) ("-1/2" -1/2) ("#e9/10" 9/10) ("#i6/8" 0.75) ("#i1/1" 1.0) ("1e2" 100.0) ("1e+2" 100.0) ("1e-2" 0.01) (".1" .1) (".0123456789" 123456789e-10) (".0123456789e10" 123456789.0) ("3." 3.0) ("3.e0" 3.0) ("1+i" 1+1i) ("1-i" 1-1i) ("#e1e1" 10) ("#i1e1+i" 10.0+1.0i) )) ;;; some schemes are case insensitive throughout -- they accept 0+I, #X11 etc (for-each (lambda (arg) (test (string->number arg) 'error)) (list -1 #f #\a 1 _ht_ _null_ _c_obj_ #(1 2 3) 3.14 3/4 1.0+1.0i () 'hi abs #(()) (list 1 2 3) '(1 . 2) (lambda () 1))) (for-each (lambda (arg) (test (string->number "123" arg) 'error) (test (string->number "1" arg) 'error)) (list -1 0 1 17 #f _ht_ _null_ _c_obj_ #\a #(1 2 3) 3.14 3/4 1.5+0.3i 1+i () "" "12" #() :hi most-positive-fixnum most-negative-fixnum 'hi abs #(()) (list 1 2 3) '(1 . 2) (lambda () 1))) ;; (string->number "0" 1) ?? why not? (for-each (lambda (arg) (test (number->string arg) 'error)) (list #\a #(1 2 3) () _ht_ _null_ _c_obj_ 'hi abs "hi" #(()) #f (list 1 2 3) '(1 . 2) (lambda () 1))) (for-each (lambda (arg) (test (number->string 123 arg) 'error)) (list -1 17 most-positive-fixnum most-negative-fixnum 0 1 512 _ht_ _null_ _c_obj_ #\a #f #(1 2 3) 3.14 2/3 1.5+0.3i 1+i () 'hi abs "hi" #(()) (list 1 2 3) '(1 . 2) (lambda () 1))) (test (string->number "34.1" (+ 5 (expt 2 32))) 'error) (test (number->string 34.1 (+ 5 (expt 2 32))) 'error) (test (string->number) 'error) (test (string->number 'symbol) 'error) (test (string->number "1.0" "1.0") 'error) (test (number->string) 'error) (test (number->string "hi") 'error) (test (number->string 1.0+23.0i 1.0+23.0i 1.0+23.0i) 'error) (test (string->number "") #f) (test (string->number "" 8) #f) (test (string->number (make-string 0)) #f) (test (string->number (string #\null)) #f) (test (string->number (string)) #f) (test (string->number (substring "hi" 0 0)) #f) (test (string->number (string (integer->char 30))) #f) (test (string->number "123" 10+0i) 'error) ; a real in s7 (if with-bignums (begin (test (number->string -46116860184273879035/27670116110564327424) "-46116860184273879035/27670116110564327424") (test (number->string 123 (bignum "10")) "123") (test (number->string 123 (bignum "2")) "1111011") (test (string->number "123" (bignum "10")) 123) (test (string->number "1111011" (bignum "2")) 123) (test (number->string 123 (bignum "17")) 'error) (test (number->string 123 (bignum "-1")) 'error) (test (number->string 123 (bignum "1")) 'error) (test (number->string 123 (bignum "1/2")) 'error) (test (string->number "101" (bignum "17")) 'error) (test (string->number "101" (bignum "1")) 'error) (test (string->number "101" (bignum "-1")) 'error) (test (string->number "101" (bignum "1/2")) 'error))) (num-test (- (string->number "11880772664.84631001" 10) (string->number "1.188077266484631001E10" 10)) 0.0) (num-test (- (string->number "11880772.66484631001" 10) (string->number "1.188077266484631001E7" 10)) 0.0) (if with-bignums (num-test (- (string->number "118807726648463.1001" 10) (string->number "1.188077266484631001E14" 10)) 0.0) (test (> (abs (- (string->number "118807726648463.1001" 10) (string->number "1.188077266484631001E14" 10))) 1e-1) #f)) (if with-bignums (num-test (- (string->number "118807726648463.1001" 9) (string->number "1.188077266484631001E14" 9)) 0.0) (test (> (abs (- (string->number "118807726648463.1001" 9) (string->number "1.188077266484631001E14" 9))) 1e-1) #f)) (num-test (- (string->number "11880772664.84631001" 9) (string->number "1.188077266484631001E10" 9)) 0.0) (num-test (- (string->number "11880772.66484631001" 9) (string->number "1.188077266484631001E7" 9)) 0.0) #| (num-test (- (string->number "1188077266484631001.") (string->number "1.188077266484631001E18")) 0.0) (num-test (- (string->number "1188077266484631001." 10) (string->number "1.188077266484631001E18" 10)) 0.0) (num-test (- (string->number "118807726648463100.1" 10) (string->number "1.188077266484631001E17" 10)) 0.0) (num-test (- (string->number "118807726648463100100." 9) (string->number "1.188077266484631001E20" 9)) 0.0) (num-test (- (string->number "1188077266484631001." 9) (string->number "1.188077266484631001E18" 9)) 0.0) (num-test (- (string->number "118807726648463100.1" 9) (string->number "1.188077266484631001E17" 9)) 0.0) ;; (num-test (- (string->number "1177077266474631001000." 8) (string->number "1.177077266474631001E21" 8)) 0.0) ;; a fake unfortunately -- actually all of these are not what they appear to be |# (num-test 111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111e-300 1.111111111111111111111111111111111111113E-1) (num-test 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e300 1.0) (num-test 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e309 1.0) (num-test 0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000123e309 1.23) (num-test -.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000123456e312 -1234.56) (num-test (string->number "111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111e-300") 1.111111111111111111111111111111111111113E-1) (num-test (string->number "0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e300") 1.0) (num-test (string->number "0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e309") 1.0) (num-test (string->number "0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000123e309") 1.23) (num-test (string->number "-.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000123456e312") -1234.56) (num-test #e0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e300 1) (num-test #e0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e309 1) (num-test #e0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000123e309 123/100) (num-test #e-.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000123456e314 -123456) (num-test #b0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e300 1.0) (num-test #d0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e300 1.0) (num-test #o0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e300 1.0) (num-test #x0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e300 1.0) (num-test 0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e600 10.0) (num-test 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-300 1.0) (num-test 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-309 1.0) (num-test -1234000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-309 -1.234) (num-test (string->number "1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-300") 1.0) (num-test (string->number "1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-309") 1.0) (num-test (string->number "-1234000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-309") -1.234) (num-test #e1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-300 1) (num-test #e1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-309 1) (num-test #e-1234000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-309 -617/500) (num-test 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-300 1.0) (num-test #e1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-300 1) (num-test (string->number "1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-300") 1.0) (num-test 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-309 1.0) (num-test #e1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-309 1) (num-test (string->number "1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-309") 1.0) (num-test (string->number "7218817.36503571385593731949749063134519967478471341285646368059547752954588980538968510599079437e7") 7.218817365035713855937319497490631345183E13) (num-test (string->number "-8209943b.31283867353472bb21b" 12) -2.928292312585025742274395996260284298851E8) (test (string->number "-8209943b.31283867353472bc21b" 12) #f) (num-test (string->number "-25708892.1b6583269007366320788640bb79398b32a42" 12) -8.835044616346879740283599816201349374646E7) (test (string->number "-25708892.1b6583269007366320788640bb79398b32ac2" 12) #f) (num-test (string->number "9418.b89a40b0211a01147b75b23a529b0382775b32b+45936610b.a936586185a57b00ba4a90a139343235054b2i" 12) 1.614897792919114090019672485580641433273E4+1.926841115897881740778679262842131716289E9i) (num-test (string->number "1.0e0000000000000000000000000000000000001") 10.0) (num-test #e1.0e0000000000000000000000000000000000001 10) (num-test #e1.0e-0000000000000000000000000000000000001 1/10) (num-test 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 10.0) (num-test #e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 10) (num-test (string->number "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001") 10.0) (num-test (string->number "\ 0000000000000000000000000000000000000000\ 0000000000000000000000000000000000000000\ 0000000000000000000000000000000000000000\ 0000000000000000000000000000000000000000\ 0000000000000000000000000000000000000000\ 0000000000000000000000000000000000000000\ 0000000000000000000000000000000000000000\ 0000000000000000000000000000000000000000\ 0000000000000000000000000000000000000000\ 0000000000000000000000000000000000000000\ 1.00000000000000000000000000000000000000\ 0000000000000000000000000000000000000000\ 0000000000000000000000000000000000000000\ 0000000000000000000000000000000000000000\ 0000000000000000000000000000000000000000\ 0000000000000000000000000000000000000000\ 0000000000000000000000000000000000000000\ 0000000000000000000000000000000000000000\ 0000000000000000000000000000000000000000\ 0000000000000000000000000000000000000000\ 00e0000000000000000000000000000000000000\ 0000000000000000000000000000000000000000\ 0000000000000000000000000000000000000000\ 0000000000000000000000000000000000000000\ 0000000000000000000000000000000000000000\ 0000000000000000000000000000000000000000\ 0000000000000000000000000000000000000000\ 0000000000000000000000000000000000000000\ 0000000000000000000000000000000000000000\ 0000000000000000000000000000000000000000\ 0001") 10.0) ;;; this whitespace handling only works in string constants in s7, not in arbitrary code. (num-test 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001/00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 1) (num-test (string->number "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001/00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001") 1) (num-test #i00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001/00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 1.0) #| ;;; if not gmp: :(string->number "0.999999999999999") 1.0 :(number->string 0.999999999999999) "1.0" also :(string->number ".0999999999999995") 0.099999999999999 :(string->number ".0999999999999996") 0.1 :(string->number ".0fffffffffff" 16) 0.062499999999996 :(string->number ".0ffffffffffff" 16) 0.0625 but :(number->string 0.062499999999996 16) "0.0ffffffffffee" :(number->string (string->number ".0fffffffffff" 16) 16) "0.0fffffffffff" the 0.624... version is actually an approximation (off by 4.4408920985006e-16) :(number->string 0.062499999999996 16) "0.0ffffffffffedfc506118a9ea64de0c590" more non-gmp: :9999999999999999999 -8446744073709551617 :9999999999999999991 -8446744073709551625 :-9999999999999999991 8446744073709551625 :9223372036854775810 -9223372036854775806 etc |# (if with-bignums (begin (test (char=? ((number->string 9.999999999999999) 0) #\9) #t) (test (char=? ((number->string 0.999999999999999999) 3) #\9) #t) (num-test -0.1e309 -1e308) (num-test .01e310 1e308) (num-test .1e310 1e309) (num-test 0.0e310 0.0) )) ;;; -------------------------------------------------------------------------------- ;;; bignum ;;; -------------------------------------------------------------------------------- (if with-bignums (begin (test (bignum? (bignum "2")) #t) (test (bignum? (bignum "#e1.5")) #t) (num-test (bignum "6/3") 2) (num-test (bignum "+3/6") 1/2) (num-test (bignum "7447415382/3") 2482471794) (for-each (lambda (n) (test (bignum? n) #f)) (list 0 1 -1 1/3 1.0 1+i 1073741824 1.0e8 1+1.0e8i "hi" () (integer->char 65) #f #t '(1 2) 'a-symbol _ht_ _null_ _c_obj_ (cons 1 2) (make-vector 3) abs)) (for-each (lambda (n) (test (bignum? n) #t)) (list 1.0e30 -1.0e20+i 1.0+1.0e80i 1e100 1267650600228229401496703205376 -1267650600228229401496703205376 1180591620717411303424/3 3/1180591620717411303424 1180591620717411303424/1180591620717411303423 1267650600228229401496703205376.99 -1267650600228229401496703205376.88 0.1231231231231231231231231231)) (for-each (lambda (n) (test (bignum n) 'error) (test (bignum "1.0" n) 'error)) (list "hi" (integer->char 65) #f #t '(1 2) 'a-symbol (cons 1 2) () _ht_ _null_ _c_obj_ (make-vector 3) 1 3/4 1.5 1+i abs)) (test (bignum?) 'error) (test (bignum? 1 2) 'error) (test (bignum) 'error) (test (bignum "hi" "ho") 'error) (test (bignum "") 'error) (test (bignum " ") 'error) (test (bignum " 1 ") 'error) (test (bignum "abc") 'error) (test (bignum "1/2/3") 'error) )) ;;; -------------------------------------------------------------------------------- ;;; errors ;;; -------------------------------------------------------------------------------- (let () (for-each (lambda (op) (for-each (lambda (arg) (let ((val (catch #t (lambda () (op arg)) (lambda args 'error)))) (if (not (eq? val 'error)) (format-logged #t "(~A ~A) -> ~A (expected 'error)~%" op arg val))) (let ((val (catch #t (lambda () (op 0 arg)) (lambda args 'error)))) (if (not (eq? val 'error)) (format-logged #t "(~A 0 ~A) -> ~A (expected 'error)~%" op arg val))) (let ((val (catch #t (lambda () (op 0 1 arg)) (lambda args 'error)))) (if (not (eq? val 'error)) (format-logged #t "(~A 0 1 ~A) -> ~A (expected 'error)~%" op arg val))) (if with-bignums (let ((val (catch #t (lambda () (op (expt 2 60) arg)) (lambda args 'error)))) (if (not (eq? val 'error)) (format-logged #t "(~A 2^60 ~A) -> ~A (expected 'error)~%" op arg val))))) (list "hi" () #\a (list 1) '(1 . 2) #f 'a-symbol (make-vector 3) abs #t _ht_ _null_ _c_obj_ :hi (if #f #f) (lambda (a) (+ a 1)) # # # :rest))) (list exact? inexact? zero? positive? negative? even? odd? quotient remainder modulo truncate floor ceiling round abs max min gcd lcm expt exact->inexact inexact->exact rationalize numerator denominator imag-part real-part magnitude angle make-polar complex sqrt exp log sin cos tan asin acos atan number->string + - * / < > <= >= =))) (let ((d 3.14) (i 32) (r 2/3) (c 1.5+0.3i)) (let ((check-vals (lambda (name) (if (or (not (= d 3.14)) ; (> (abs (- d 3.14)) 1e-16) ; (- 3.14 (bignum "3.14")) is around 1e-17! (not (= i 32)) (not (= r 2/3)) (not (= c 1.5+0.3i))) ; (> (magnitude (- c 1.5+0.3i)) 1e-16)) (begin (display name) (display " changed ") (if (not (= i 32)) (begin (display "stored integer to: ") (display i)) (if (not (= r 2/3)) (begin (display "stored ratio to: ") (display r)) (if (not (= d 3.14)) (begin (display "stored real to: ") (display d)) (begin (display "stored complex to: ") (display c))))) (display "?") (newline)))))) (for-each (lambda (op) (let ((x (catch #t (lambda () (op i)) (lambda args 'error)))) (check-vals op)) (let ((x (catch #t (lambda () (op r)) (lambda args 'error)))) (check-vals op)) (let ((x (catch #t (lambda () (op d)) (lambda args 'error)))) (check-vals op)) (let ((x (catch #t (lambda () (op c)) (lambda args 'error)))) (check-vals op)) (let ((x (catch #t (lambda () (op i d)) (lambda args 'error)))) (check-vals op)) (let ((x (catch #t (lambda () (op r d)) (lambda args 'error)))) (check-vals op)) (let ((x (catch #t (lambda () (op d d)) (lambda args 'error)))) (check-vals op)) (let ((x (catch #t (lambda () (op c d)) (lambda args 'error)))) (check-vals op))) (list number->string string->number complex magnitude abs exp make-polar angle sin cos tan sinh cosh tanh atan sqrt log asinh acosh atanh acos asin number? integer? real? complex? rational? even? odd? zero? positive? negative? real-part imag-part numerator denominator rationalize exact? inexact? exact->inexact inexact->exact floor ceiling truncate round logior logxor logand lognot logbit? ash integer-length + - * / quotient remainder expt = max min modulo < > <= >= lcm gcd )))) (if with-bignums (begin (test (bignum "1/3.0") 'error) (let ((d (bignum "3.14")) (i (bignum "32")) (r (bignum "2/3")) (c (bignum "1.5+0.3i"))) (let ((check-vals (lambda (name) (if (or (not (= d (bignum "3.14"))) ; see above (not (= i 32)) (not (= r 2/3)) (not (= c (bignum "1.5+0.3i")))) (begin (display name) (display " changed ") (if (not (= i 32)) (begin (display "stored integer to: ") (display i)) (if (not (= r 2/3)) (begin (display "stored ratio to: ") (display r)) (if (not (= d 3.14)) (begin (display "stored real to: ") (display d)) (begin (display "stored complex to: ") (display c))))) (display "?") (newline)))))) (for-each (lambda (op) (let ((x (catch #t (lambda () (op i)) (lambda args 'error)))) (check-vals op)) (let ((x (catch #t (lambda () (op r)) (lambda args 'error)))) (check-vals op)) (let ((x (catch #t (lambda () (op d)) (lambda args 'error)))) (check-vals op)) (let ((x (catch #t (lambda () (op c)) (lambda args 'error)))) (check-vals op)) (let ((x (catch #t (lambda () (op i d)) (lambda args 'error)))) (check-vals op)) (let ((x (catch #t (lambda () (op r d)) (lambda args 'error)))) (check-vals op)) (let ((x (catch #t (lambda () (op d d)) (lambda args 'error)))) (check-vals op)) (let ((x (catch #t (lambda () (op c d)) (lambda args 'error)))) (check-vals op))) (list number->string string->number complex magnitude abs exp make-polar angle sin cos tan sinh cosh tanh atan sqrt log asinh acosh atanh acos asin number? integer? real? complex? rational? even? odd? zero? positive? negative? real-part imag-part numerator denominator rationalize exact? inexact? exact->inexact inexact->exact floor ceiling truncate round logior logxor logand lognot logbit? ash integer-length + - * / quotient remainder expt = max min modulo < > <= >= lcm gcd )))) (for-each (lambda (arg) (test (bignum "1.0" arg) 'error)) (list -1 0 #\a #(1 2 3) 2/3 1.5+0.3i 1+i () 'hi abs "hi" #(()) (list 1 2 3) '(1 . 2) (lambda () 1))))) #| (let ((funcs (list make-polar complex magnitude angle real-part imag-part numerator denominator rationalize abs exp log sin cos tan asin acos atan sinh cosh tanh asinh acosh atanh sqrt floor ceiling truncate round lcm gcd + - * / max min quotient remainder modulo = < > <= >= even? odd? zero? positive? negative? infinite? inexact->exact exact->inexact integer-length logior logxor logand lognot logbit? ash integer-decode-float exact? inexact? number? integer? real? complex? rational? nan?; number->string expt )) (func-names (list 'make-polar 'complex 'magnitude 'angle 'real-part 'imag-part 'numerator 'denominator 'rationalize 'abs 'exp 'log 'sin 'cos 'tan 'asin 'acos 'atan 'sinh 'cosh 'tanh 'asinh 'acosh 'atanh 'sqrt 'floor 'ceiling 'truncate 'round 'lcm 'gcd '+ '- '* '/ 'max 'min 'quotient 'remainder 'modulo '= '< '> '<= '>= 'even? 'odd? 'zero? 'positive? 'negative? 'infinite? 'inexact->exact 'exact->inexact 'integer-length 'logior 'logxor 'logand 'lognot 'logbit? 'ash 'integer-decode-float 'exact? 'inexact? 'number? 'integer? 'real? 'complex? 'rational? 'nan?; 'number->string 'expt )) (args (list 0 1 -1))) (define (for-each-subset-permuted func name args) (let* ((ar (arity func)) (min-args (car ar)) (max-args (min 1000 (cdr ar)))) (if (= min-args 0) (set! min-args 1)) (for-each-subset (lambda s-args (if (<= min-args (length s-args) max-args) (for-each-permutation (lambda p-args (catch #t (lambda () (let ((val (apply func p-args))) (format #t "(let ((new-val (catch-it (~A ~{~A~^ ~})))) " name p-args) (if (not (number? val)) (format #t "(if (not (equal? new-val ~A)) (format #t \"(~A ~{~A~^ ~}) -> ~~A~~%\" new-val)))~%" val name p-args) (if (nan? val) (format #t "(if (not (nan? new-val)) (format #t \"(~A ~{~A~^ ~}) -> ~~A, not NaN?~~%\" new-val)))~%" name p-args) (if (infinite? val) (format #t "(if (not (infinite? new-val)) (format #t \"(~A ~{~A~^ ~}) -> ~~A, not inf?~~%\" new-val)))~%" name p-args) (format #t "(if (> (magnitude (- new-val ~A)) 1e-6) (format #t \"(~A ~{~A~^ ~}) -> ~~A, not ~A~~%\" new-val)))~%" val name p-args val)))))) (lambda e-args (format *stderr* "~A~%" e-args) ''error))) s-args))) args))) (with-output-to-file "t248.data" (lambda () (format #t "(define-macro (catch-it tst)~% `(catch #t (lambda () ,tst) (lambda args 'error)))~%") (for-each (lambda (func name) (for-each-subset-permuted func name args)) funcs func-names)))) |# ;(gc) ;;; -------------------------------------------------------------------------------- ;;; ;;; fft from s7.html (define* (cfft! data n (dir 1)) ; (complex data) (if (not n) (set! n (length data))) (do ((i 0 (+ i 1)) (j 0)) ((= i n)) (if (> j i) (let ((temp (data j))) (set! (data j) (data i)) (set! (data i) temp))) (let ((m (/ n 2))) (do () ((or (< m 2) (< j m))) (set! j (- j m)) (set! m (/ m 2))) (set! j (+ j m)))) (let ((ipow (floor (log n 2))) (prev 1)) (do ((lg 0 (+ lg 1)) (mmax 2 (* mmax 2)) (pow (/ n 2) (/ pow 2)) (theta (complex 0.0 (* pi dir)) (* theta 0.5))) ((= lg ipow)) (let ((wpc (exp theta)) (wc 1.0)) (do ((ii 0 (+ ii 1))) ((= ii prev)) (do ((jj 0 (+ jj 1)) (i ii (+ i mmax)) (j (+ ii prev) (+ j mmax))) ((>= jj pow)) (let ((tc (* wc (data j)))) (set! (data j) (- (data i) tc)) (set! (data i) (+ (data i) tc)))) (set! wc (* wc wpc))) (set! prev mmax)))) data) (test (morally-equal? (cfft! (list 0.0 1+i 0.0 0.0)) '(1+1i -1+1i -1-1i 1-1i)) #t) (test (morally-equal? (cfft! (vector 0.0 1+i 0.0 0.0)) #(1+1i -1+1i -1-1i 1-1i)) #t) (let ((size 32)) (let ((v (make-vector size))) (do ((i 0 (+ i 1))) ((= i size)) (set! (v i) (random 1.0))) (let ((copy-v (copy v))) (cfft! v size) (cfft! v size -1) (do ((i 0 (+ i 1))) ((= i size)) (set! (v i) (/ (v i) size)) (if (or (> (abs (imag-part (v i))) 1e-14) (> (magnitude (- (v i) (copy-v i))) 1e-14)) (format *stderr* ";cfft! reals: ~D: ~A ~A~%" i (v i) (copy-v i))))))) (let ((size 32)) (let ((v (make-vector size))) (do ((i 0 (+ i 1))) ((= i size)) (set! (v i) (random 100))) (let ((copy-v (copy v))) (cfft! v size) (cfft! v size -1) (do ((i 0 (+ i 1))) ((= i size)) (set! (v i) (/ (v i) size)) (if (or (> (abs (imag-part (v i))) 1e-12) (> (magnitude (- (v i) (copy-v i))) 1e-12)) (format *stderr* ";cfft! ints: ~D: ~A ~A~%" i (v i) (copy-v i))))))) (let ((size 32)) (let ((v (make-vector size))) (do ((i 0 (+ i 1))) ((= i size)) (set! (v i) (random 1+i))) (let ((copy-v (copy v))) (cfft! v size) (cfft! v size -1) (do ((i 0 (+ i 1))) ((= i size)) (set! (v i) (/ (v i) size)) (if (> (magnitude (- (v i) (copy-v i))) 1e-12) (format *stderr* ";cfft! complex: ~D: ~A ~A~%" i (v i) (copy-v i))))))) (if with-bignums (let ((size 32)) (let ((data (make-vector size))) (do ((i 0 (+ i 1))) ((= i size)) (set! (data i) (complex (bignum (number->string (random 1.0))) (bignum (number->string (random 1.0)))))) (let ((old-data (copy data))) (cfft! data size) (cfft! data size -1) (do ((i 0 (+ i 1))) ((= i size)) (set! (data i) (/ (data i) size)) (if (> (magnitude (- (data i) (old-data i))) 1e-14) (format *stderr* ";cfft! big: ~D: ~A~%" i (magnitude (- (old-data i) (data i)))))))))) #| ;;; 1048576 forces us to 4608000, 32568 512000 (let ((size 65536)) (let ((v (make-vector size))) (do ((i 0 (+ i 1))) ((= i size)) (set! (v i) (random 1+i))) (let ((copy-v (copy v))) (cfft! v size) (cfft! v size -1) (do ((i 0 (+ i 1))) ((= i size)) (set! (v i) (/ (v i) size)) (if (> (magnitude (- (v i) (copy-v i))) 1e-10) (format *stderr* "~D: ~A (~A ~A)~%" (magnitude (- (v i) (copy-v i))) i (v i) (copy-v i))))))) |# (if (not (provided? 'snd)) (load "stuff.scm")) (let () (if (provided? 'snd) (load "stuff.scm" (curlet))) (test (first '(1 2 3 4 5 6 7 8 9 10)) 1) (test (second '(1 2 3 4 5 6 7 8 9 10)) 2) (test (third '(1 2 3 4 5 6 7 8 9 10)) 3) (test (fourth '(1 2 3 4 5 6 7 8 9 10)) 4) (test (fifth '(1 2 3 4 5 6 7 8 9 10)) 5) (test (sixth '(1 2 3 4 5 6 7 8 9 10)) 6) (test (seventh '(1 2 3 4 5 6 7 8 9 10)) 7) (test (eighth '(1 2 3 4 5 6 7 8 9 10)) 8) (test (ninth '(1 2 3 4 5 6 7 8 9 10)) 9) (test (tenth '(1 2 3 4 5 6 7 8 9 10)) 10) (test (first #(1 2 3 4 5 6 7 8 9 10)) 1) (test (second #(1 2 3 4 5 6 7 8 9 10)) 2) (test (third #(1 2 3 4 5 6 7 8 9 10)) 3) (test (fourth #(1 2 3 4 5 6 7 8 9 10)) 4) (test (fifth #(1 2 3 4 5 6 7 8 9 10)) 5) (test (sixth #(1 2 3 4 5 6 7 8 9 10)) 6) (test (seventh #(1 2 3 4 5 6 7 8 9 10)) 7) (test (eighth #(1 2 3 4 5 6 7 8 9 10)) 8) (test (ninth #(1 2 3 4 5 6 7 8 9 10)) 9) (test (tenth #(1 2 3 4 5 6 7 8 9 10)) 10) (test (first "1234567890") #\1) (test (second "1234567890") #\2) (test (third "1234567890") #\3) (test (fourth "1234567890") #\4) (test (fifth "1234567890") #\5) (test (sixth "1234567890") #\6) (test (seventh "1234567890") #\7) (test (eighth "1234567890") #\8) (test (ninth "1234567890") #\9) (test (tenth "1234567890") #\0) (for-each (lambda (obj) (test (empty? obj) #t) (test (not (sequence? obj)) #f)) (list "" () #() (hash-table) (inlet) (if with-block (block) (float-vector)) (float-vector) #2d())) (for-each (lambda (obj) (test (empty? obj) #f) (test (not (sequence? obj)) #t) (test (not (applicable? obj)) #f)) (list abs (lambda () 1) quasiquote)) (for-each (lambda (obj) (test (empty? obj) #f) (test (indexable? obj) #f) (test (applicable? obj) #f) (test (not (sequence? obj)) #t)) (list #\null #\a 1 'a-symbol 1/0 (log 0) 3.14 3/4 1.0+1.0i #t :hi (if #f #f))) (test (sequence?) 'error) (test (sequence? () '(1)) 'error) (test (->predicate 1) integer?) (test (->predicate (curlet)) let?) (test (->predicate #) eof-object?) (test (->predicate (cons 1 2)) pair?) (test (->predicate :hi) keyword?) (test (->predicate #\a) char?) (test (->predicate) 'error) (when with-block (add-predicate block?) (test (->predicate (block 1 2)) block?)) (test (let ((a 1) (b "hi")) (value->symbol "hi")) 'b) (test (typeq? 1 2) #t) (test (typeq? #\a #\space #\b) #t) (test (typeq?) #t) (test (typeq? 1.2) #t) (test (typeq? 1 1/2) #f) (test (typeq? "hi" "" (string #\null) "abc") #t) (test (typeq? 1.0 pi) #t) (test (typeq? # (if #f #f)) #t) (test (let ((x 1)) (typecase x ((integer?) 32) ((real? string?) 2) (else 0))) 32) (test (let ((x 1.0)) (typecase x ((integer?) 32) ((real? string?) 2) (else 0))) 2) (test (let ((x ())) (typecase x ((integer?) 32) ((real? string?) 2) (else 0))) 0) (test (let ((x "hi")) (typecase x ((integer?) 32) ((real? string?) 2) (else 0))) 2) (test (let ((x 0)) (typecase (set! x (+ x 1)) ((even?) -1) ((odd?) 1))) 1) ;; 2^n and 2^n-1 are tested above as are log-n-of et al and the ldb/dpb functions (test (lognand 1 2) -1) (test (lognand -1 1) -2) (test (lognand -1 -2) 1) (test (lognand 123 321) -66) (test (lognor -1 -2) 0) (test (lognor 1 2) -4) (test (lognor 123 321) -380) (test (lognor 0 1) -2) (test (logeqv 1) 1) (test (logeqv) -1) (test (logeqv 1 2) -4) (test (logeqv -1 2) 2) (test (logeqv -1 123 321) -315) (test (logeqv 1 2 3 4) -5) (test (logeqv 1 2 3 4 5) 1) (test (iota 0) ()) (test (iota 3) '(0 1 2)) (test (iota -1) 'error) (test (iota 3 -2) '(-2 -1 0)) (test (union vector '(1 2 3) #() #(4 2 1)) #(1 2 3 4)) (test (union string '(#\a) #(#\b) "abcde") "abcde") (test (union vector) #()) (test (equal? (union list '(1 2 3) ()) '(1 2 3)) #t) (test (let? (union inlet (inlet 'a 2) (inlet 'b 3))) #t) (test ((union inlet '(a 1) #(b 2)) 'b) 2) (test ((union hash-table (hash-table '(a . 1)) (hash-table '(a . 1) '(b . 2))) 'b) 2) (test (intersection vector) #()) (test (intersection list '(1 2 3) #()) ()) (test (intersection list '(1 2 3) #(4 5 1 9)) '(1)) ; pair: unbound variable (num-test ((intersection float-vector '(1 2 3) #(4 5 1 9 3)) 0) 1.0) (test (intersection (lambda x (make-shared-vector (apply vector x) '(2 2))) '(1 2 3 4 5) #(4 5 1 9 3)) #2D((1 3) (4 5))) (when with-block (test (block? (intersection block '(1.0 2.0) #(1.0))) #t) (test (block? (intersection block (block 1.0 2.0) #(2.0))) #t)) (test (intersection list '(1 2 3) '(3 2 1)) '(1 2 3)) (test (intersection inlet (inlet 'a 1 'b 2) (inlet 'b 3)) (inlet)) (test (intersection inlet (inlet 'a 1 'b 2) (inlet 'b 2)) (inlet 'b 2)) (test (symmetric-difference list '(1 2 3)) '(1 2 3)) (test (symmetric-difference list ()) ()) (test (symmetric-difference list '(1 2 3) '(1 2 4)) '(3 4)) (test (symmetric-difference list '(1 2 3) '(1 2 4) '(3 1 5)) '(1 4 5)) (test (asymmetric-difference list '(1 2 3) '(1 2 4)) '(4)) (test (asymmetric-difference list ()) ()) (test (asymmetric-difference list '(1 2 3)) ()) (test (null? (cl-set-difference list () ())) #t) (test (null? (cl-set-difference list () '(1 2 3))) #t) (test (null? (cl-set-difference list '(1 2 3 4) '(4 3 2 1))) #t) (test (null? (cl-set-difference list '(1 2 3 4) '(2 4 3 1))) #t) (test (null? (cl-set-difference list '(1 2 3 4) '(1 3 4 2))) #t) (test (null? (cl-set-difference list '(1 2 3 4) '(1 3 2 4))) #t) (test (power-set list ()) '(())) (test (power-set list '(1)) '(() (1))) (test (power-set list '(1 2)) '(() (2) (1) (1 2))) (test (power-set list '(1 2 3)) '(() (3) (2) (2 3) (1) (1 3) (1 2) (1 2 3))) (test (apply union list (power-set list '(1 2 3))) '(3 2 1)) (test (hash-table->alist (hash-table)) ()) (test (hash-table->alist (hash-table '(a . 1))) '((a . 1))) (test (let ((lst (hash-table->alist (hash-table '(a . 1) '(b . 2))))) (or (equal? lst '((a . 1) (b . 2))) (equal? lst '((b . 2) (a . 1))))) #t) (test (merge-hash-tables (hash-table) (hash-table '(a . 1))) (hash-table '(a . 1))) (test (merge-hash-tables (hash-table '(a . 1) '(b . 2)) (hash-table '(a . 1))) (hash-table '(a . 1) '(b . 2))) (test (union hash-table (hash-table '(a . 1) '(b . 2)) (hash-table '(a . 1))) (hash-table '(a . 1) '(b . 2))) (test (with-let (union inlet (inlet 'a 1) (inlet 'b 2)) (+ a b)) 3) (let () (define e (let ((e's (list (inlet 'a 1 'b 2) (inlet 'a 3 'b 4)))) (lambda (sym) (apply values (map (lambda (e1) (if (defined? sym e1) (e1 sym) (values))) e's))))) (test (+ (e 'a) (e 'b)) 10)) (test (find-if (lambda (x) (= x 3)) '(1 2 3 4)) 3) (test (find-if (lambda (x) (= x 3)) '(1 2 5 4)) #f) (test (find-if (lambda (x) (= x 3)) ()) #f) (test (index-if (lambda (x) (= x 3)) '(1 2 3 4)) 2) (test (index-if (lambda (x) (= x 1)) '(1 2 3 4)) 0) (test (index-if (lambda (x) (= x 3)) '(1 2 5 4)) #f) (test (index-if (lambda (x) (= x 3)) ()) #f) (test (index-if (lambda (x) (equal? (cdr x) 2)) (hash-table '(a . 1) '(b . 2))) 'b) (test (count-if (lambda (x) (= x 3)) ()) 0) (test (count-if (lambda (x) (= x 3)) '(1 2)) 0) (test (count-if (lambda (x) (= x 3)) '(3 3)) 2) (test (every? (lambda (x) (= x 3)) ()) #t) (test (every? (lambda (x) (= x 3)) '(1 2)) #f) (test (every? (lambda (x) (= x 3)) '(1 3)) #f) (test (every? (lambda (x) (= x 3)) '(3 3 3)) #t) (test (any? (lambda (x) (= x 3)) ()) #f) (test (any? (lambda (x) (= x 3)) '(1 2)) #f) (test (not (any? (lambda (x) (= x 3)) '(1 3))) #f) (test (not (any? (lambda (x) (= x 3)) '(3 3 3))) #f) (test (collect-if list (lambda (x) (> x 3)) ()) ()) (test (collect-if list (lambda (x) (> x 3)) '(1)) ()) (test (collect-if list (lambda (x) (> x 3)) '(1 3 4)) '(4)) (test (collect-if list (lambda (x) (> x 3)) '(1 3 4 2 1 5 1)) '(4 5)) (test (collect-if inlet (let ((syms ())) (lambda (x) (and (not (memq (car x) syms)) (set! syms (cons (car x) syms))))) (inlet 'a 1 'b 2 'a 3)) (inlet 'b 2 'a 3)) ;; i.e. clean out shadowed vars, ((inlet 'a 1 'b 2 'a 3) 'a) -> 3 (test (remove-if list (lambda (x) (> x 3)) ()) ()) (test (remove-if list (lambda (x) (> x 3)) '(1)) '(1)) (test (remove-if list (lambda (x) (> x 3)) '(1 3 4)) '(1 3)) (test (remove-if list (lambda (x) (> x 3)) '(1 3 4 2 1 5 1)) '(1 3 2 1 1)) (test (let ((e (inlet 'a 1 'b 2 'c 3))) (remove-if inlet (lambda (x) (= (cdr x) 2)) e)) (inlet 'a 1 'c 3)) (test (let ((ht (hash-table '(a . 1) '(b . 2) '(c . 3)))) (remove-if hash-table (lambda (x) (= (cdr x) 2)) ht)) (hash-table '(a . 1) '(c . 3))) (test (remove-if vector (lambda (x) (integer? x)) #(() #\a 3/2 2 21 "hi")) #(() #\a 3/2 "hi")) (test (nonce list ()) ()) (test (nonce list '(1 2)) '(1 2)) (test (nonce list '(1 1)) ()) (test (nonce list '(1 2 3 1 3 1 1)) '(2)) (test (member? 1 ()) #f) (test (member? 1 '(2 3)) #f) (test (member? 1 '(2 1 3)) 1) (test (concatenate list ()) ()) (test (concatenate list () #() "") ()) (test (concatenate vector '(1) #() "2") #(1 #\2)) (test (concatenate string '(#\1 #\2) "34" #(#\5)) "12345") (test (concatenate inlet (inlet 'a 1) (inlet 'b 2 'a 3)) (inlet 'a 1 'b 2 'a 3)) (test (full-find-if (lambda (x) (and (integer? x) (= x 1))) '(2 (3 (4 5) 6 1))) 1) (test (full-find-if (lambda (x) (and (integer? x) (= x 1))) '(2 (3 (4 5) 6))) #f) (test (full-count-if (lambda (x) (and (integer? x) (= x 1))) '(1 2 (3 4 1) (5 (6 (1))))) 3) (test (let ((l1 '(1 2))) (full-count-if (lambda (x) (and (integer? x) (= x 2))) (list 1 l1 2 l1 3 l1))) 4) (test (full-index-if (lambda (x) (and (integer? x) (= x 3))) '(1 2 3)) '(2)) (test (full-index-if (lambda (x) (= (cdr x) 3)) (hash-table '(a . 1) '(b . 3))) '(b)) (test (full-index-if (lambda (x) (and (integer? x) (= x 3))) '(1 (2 3))) '(1 1)) (test (full-index-if (lambda (x) (and (integer? x) (= x 3))) '((1 (2 (3))))) '(0 1 1 0)) (test (full-index-if (lambda (x) (and (integer? x) (= x 3))) #((1 (2 #(3))))) '(0 1 1 0)) (test (full-index-if (lambda (x) (and (integer? x) (= x 3))) (hash-table '(a . 1) '(b . #(1 2 3)))) '(b 2)) (test (full-index-if (lambda (x) (and (integer? x) (= x 4))) (hash-table '(a . 1) '(b . #(1 2 3)))) #f) (test (let ((lst (list 1 2))) (set-cdr! lst lst) (let ((i (make-complete-iterator lst))) (map values i))) '(1)) (test (let ((lst (list 1 2))) (set-cdr! (cdr lst) lst) (let ((i (make-complete-iterator lst))) (map values i))) '(1 2)) (test (let ((lst (list 1 2 3))) (set-cdr! (cddr lst) lst) (let ((i (make-complete-iterator lst))) (map values i))) '(1 2 3)) (test (let ((lst (list 1 2 3 4))) (set-cdr! (cdddr lst) lst) (let ((i (make-complete-iterator lst))) (map values i))) '(1 2 3 4)) (test (let ((v '(1 2 . 3))) (let ((i (make-complete-iterator v))) (map values i))) '(1 2 3)) (test (let ((v '(1 2 #(4 5) ("67")))) (let ((i (make-complete-iterator v))) (map values i))) '(1 2 #(4 5) 4 5 ("67") "67" #\6 #\7)) (test (let ((v (list (circular-list 1)))) (let ((iter (make-complete-iterator v))) (map values iter))) (list (circular-list 1) 1)) (test (let ((v (list (circular-list 1 2)))) (let ((iter (make-complete-iterator v))) (map values iter))) (list (circular-list 1 2) 1 2)) (test (let ((v (cons 3 (circular-list 1)))) (let ((iter (make-complete-iterator v))) (map values iter))) '(3 1)) (test (let ((v (cons 3 (circular-list 1 2)))) (let ((iter (make-complete-iterator v))) (map values iter))) '(3 1 2)) (test (let ((v (list 3 (circular-list 1)))) (let ((iter (make-complete-iterator v))) (map values iter))) (list 3 (circular-list 1) 1)) (test (let ((v (list 3 (circular-list 1 2)))) (let ((iter (make-complete-iterator v))) (map values iter))) (list 3 (circular-list 1 2) 1 2)) (test (let ((v (vector (list 4 5) (circular-list 1 2 3) (cons 6 (cons 7 8))))) (let ((iter (make-complete-iterator v))) (map values iter))) (list (list 4 5) 4 5 (circular-list 1 2 3) 1 2 3 (cons 6 (cons 7 8)) 6 7 8)) (test (let ((lst (list 1 2))) (let ((v (list lst lst))) (let ((iter (make-complete-iterator v))) (map values iter)))) '((1 2) 1 2)) (test (let ((lst (circular-list 1))) (let ((v (list lst lst))) (let ((iter (make-complete-iterator v))) (map values iter)))) (list (circular-list 1) 1)) (let ((v (circular-list 1))) (set-car! v v) (test (let ((i5 (make-complete-iterator v))) (map values i5)) ())) (let ((v (vector 1))) (set! (v 0) v) (test (let ((i4 (make-complete-iterator v))) (map values i4)) ())) (let ((v (vector 1)) (lst (circular-list 2))) (set! (v 0) lst) (set-car! lst v) (test (let ((i1 (make-complete-iterator v))) (map values i1)) (list lst))) ; not v because it's the outermost container? (let ((v (vector 1)) (lst (circular-list 2))) (set! (v 0) lst) (set-car! lst v) (test (let ((i2 (make-complete-iterator (list v)))) (map values i2)) (list v lst))) (let ((v (vector 1 2))) (set! (v 1) v) (set! (v 0) v) (test (let ((i3 (make-complete-iterator (list v)))) (map values i3)) (list v))) (test (safe-find-if (lambda (x) (and (integer? x) (= x 1))) '(2 (3 (4 5) 6 1))) 1) (test (safe-find-if (lambda (x) (and (integer? x) (= x 1))) '(2 (3 (4 5) 6))) #f) (test (safe-find-if (lambda (x) (and (integer? x) (= x 1))) (circular-list 2 3 1 4)) 1) (test (safe-find-if (lambda (x) (and (integer? x) (= x 1))) (vector 2 (circular-list 2 3 1 4) 3)) 1) (test (safe-find-if (lambda (x) (and (integer? x) (= x 1))) (vector 2 (circular-list 2 3 4) 3)) #f) (test (let ((v (vector 1 2))) (set! (v 1) v) (safe-find-if (lambda (x) (and (integer? x) (= x 1))) v)) 1) (test (let ((v (vector 1 2)) (lst (list 1 2))) (set! (v 1) lst) (set! (lst 1) v) (safe-find-if (lambda (x) (and (integer? x) (= x 1))) v)) 1) (test (safe-count-if (lambda (x) (and (integer? x) (= x 1))) '(2 (3 (4 5) 6 1))) 1) (test (safe-count-if (lambda (x) (and (integer? x) (= x 1))) '(2 (3 (4 5) 6))) 0) (test (safe-count-if (lambda (x) (and (integer? x) (= x 1))) (circular-list 2 3 1 4)) 1) (test (safe-count-if (lambda (x) (and (integer? x) (= x 1))) (vector 2 (circular-list 2 3 1 4) 3)) 1) (test (safe-count-if (lambda (x) (and (integer? x) (= x 1))) (vector 2 (circular-list 2 3 4) 3)) 0) (test (safe-count-if (lambda (x) (and (integer? x) (= x 1))) (vector 2 #(1) (circular-list 2 1 3 1 4) 3)) 3) (test (let ((v (vector 1 2))) (set! (v 1) v) (safe-count-if (lambda (x) (and (integer? x) (= x 1))) v)) 1) (test (let ((v (vector 1 2)) (lst (list 1 2))) (set! (v 1) lst) (set! (lst 1) v) (safe-count-if (lambda (x) (and (integer? x) (= x 1))) v)) 2) (test (make-directory-iterator #\a) 'error) (test (catch #t (lambda () (let ((f (make-directory-iterator "/home/bil/libxm"))) (f) ((iterator-sequence f) #) #f)) (lambda args #f)) #f) (test (let ((x 32)) (define gx (elambda () (*env* 'x))) (let ((x 100)) (let ((x 12)) (gx)))) 12) (test (let () (define hi (elambda (x) (string->symbol "b"))) (eq? (hi 1) 'b)) #t) (test (let () (define hi (elambda (x) (+ (*env* 'y) x))) (let ((y 3)) (hi 1))) 4) (test (letrec ((efunc (elambda (x) (if (= x 0) 0 (efunc (- x 1)))))) (efunc 3)) 0) (test (let ((y 1)) (define hi (elambda (x z) (if (= x z) (display "oops")) (+ z x (*env* 'y)))) (hi 2 3)) 6) (test (let ((y 1)) (define hi (elambda (x z) (if (= x z) (display "oops")) (+ z x (*env* 'y)))) (let ((y 12)) (hi 2 3))) 17) (test (let ((vals #(0 0 0))) (define rx (rlambda ((a (+ c 1))) (+ a 2))) (set! (vals 0) (rx 5)) (let ((c 3)) (set! (vals 1) (rx))) ; error if lambda* not rlambda (let ((c 5)) (set! (vals 2) (rx))) vals) #(7 6 8)) (test (let ((x 3)) (define rx (rlambda ((a x)) (if (> a 0) (rx (- a 1)) 0))) (rx)) 0) (test (let () (define rx (rlambda ((a x)) (if (> a 0) (let ((x (- x 1))) (rx)) 0))) (let ((x 3)) (rx))) 0) (test (let ((a 1) (b 2)) (eval-case 1 ((a) 123) ((b) 321) (else 0))) 123) (test (let ((a 1) (b 2) (c 3)) (eval-case 3 ((a c) 123) ((b) 321) (else 0))) 123) (test (let ((a 1) (b 2)) (eval-case 3 ((a) 123) ((b) 321) (((+ a b)) -1) (else 0))) -1) (test (let ((a 1) (b 2)) (eval-case 6 ((a (* (+ a 2) b)) 123) ((b) 321) (((+ a b)) -1) (else 0))) 123) (test (let ((a 1) (b 2) (c 5)) (eval-case (set! c (+ c 1)) ((a (* (+ a 2) b)) 123) ((b) 321) (((+ a b)) -1) (else 0))) 123) (test (let ((a 1) (b 2) (c 5)) (eval-case (set! c (+ c 1)) ((b) 321) ((+ a b) -1) ((a (* (+ a 2) b)) 123) (((+ a b)) -1) (else 0))) 123) (test (linearize (circular-list 1 2 3)) '(1 2 3)) (test (linearize ()) ()) (test (linearize (let ((lst (list 1 2 3 4))) (set-cdr! (list-tail lst 3) (cdr lst)) lst)) '(1 2 3 4)) (test (flatten-let (with-let (inlet) (let ((x 1)) (curlet)))) (inlet 'x 1)) (test (flatten-let (with-let (inlet) (let ((x 1)) (let ((y 2)) (curlet))))) (inlet 'x 1 'y 2)) (test (clamp 1 0 3) 1) (test (clamp 1 2 3) 2) (test (clamp 1 4 3) 3) (test (n-choose-k 4 4) 1) (test (n-choose-k 4 3) 4) (test (n-choose-k 4 2) 6) (test (n-choose-k 4 1) 4) (test (n-choose-k 4 0) 1) (test (let ((a 1) (b 2) (c 3)) (reactive-set! a (+ b c)) (set! b 4) (set! c 5) a) 9) (test (let ((a 1) (b 2) (c 3)) (reactive-set! b (+ c 4)) (reactive-set! a (+ b c)) (set! c 5) a) 14) (test (let ((expr 21) (symbol 1)) (reactive-set! expr (* symbol 2)) (set! symbol 3) expr) 6) (test (let ((a 21) (b 1)) (reactive-set! a (* b 2)) (set! b 3) a) 6) (test (let ((s 21) (v 1)) (reactive-set! s (* v 2)) (set! v 3) s) 6) (test (let ((a 21) (v 1)) (reactive-set! a (* v 2)) (set! v 3) a) 6) (test (let ((symbol 21) (nv 1)) (reactive-set! symbol (* nv 2)) (set! nv 3) symbol) 6) (test (let ((nv 21) (sym 1)) (reactive-set! nv (* sym 2)) (set! sym 3) nv) 6) (test (let ((a 1) (b 2)) (reactive-set! b (+ a 4)) (let ((a 10)) (set! a (+ b 5)) (list a b))) '(10 5)) (test (let ((a 1) (b 2)) (reactive-set! b (+ a 4)) (list (let ((b 10)) (set! a (+ b 5)) a) b)) '(15 19)) (test (let ((a 21) (b 1)) (set! (symbol-access 'b) (lambda (x y) (* 2 y))) (reactive-set! a (* b 2)) (set! b 3) a) 12) (test (let ((a 21) (b 1)) (set! (symbol-access 'b) (lambda (x y) (* 2 y))) (let ((b 2)) (reactive-set! a (* b 2)) (set! b 3) a)) 6) (test (let ((a 1) (b 2) (c 3)) (reactive-set! b (+ c 4)) (let ((a 0)) (reactive-set! a (+ b c)) (set! c 5) a)) 14) (test (let ((a 1) (b 2) (c 3)) (reactive-set! a (reactive-set! b (+ c 4))) (list a b c)) '(7 7 3)) (test (let ((a 1) (b 2) (c 3)) (reactive-set! a (+ 1 (reactive-set! b (+ c 4)))) (list a b c)) '(8 7 3)) (test (let ((a 1) (v (vector 1 2 3))) (reactive-set! (v 1) (* a 3)) (set! a 4) v) #(1 12 3)) (test (let ((a 1)) (let ((v (reactive-vector a (+ a 1) 2))) (set! a 4) v)) #(4 5 2)) (test (let* ((a 1) (v (reactive-vector a (+ a 1) 2))) (set! a 4) v) #(4 5 2)) (test (let* ((a 1) (v (reactive-vector a (+ a 1) (* 2 (_ 0))))) (set! a 4) (v 'value)) #(4 5 8)) (test (let ((v (let ((a 1)) (reactive-vector a (+ a 1) (* 2 (_ 0)))))) (set! (v 0) 3) (v 'value)) #(3 2 6)) ;; unfortunately, reactive-set! does not clear out dead symbol-accessors: ;; (let ((a 1) (b 2)) (let ((c 3)) (reactive-set! b (* a c))) (let ((c 4)) (reactive-set! b (+ a 1)) (set! a 5)) (list a b)) ;; complains about unbound curlet gensym because the let it is defined in has been exited but the function still sits on the accessor (test (reactive-let () 3) 3) (test (let ((a 1)) (reactive-let ((b (+ a 1))) b)) 2) (test (let ((a 1)) (+ (reactive-let ((b (+ a 1))) (set! a 3) b) a)) 7) (test (let ((a 1)) (+ (reactive-let ((b (+ a 1)) (a 0)) (set! a 3) b) a)) 3) (test (let ((a 1)) (reactive-let ((a 2) (b (* a 3))) (set! a 3) b)) 3) (test (let ((a 1) (b 2)) (reactive-let ((a (* b 2)) (b (* a 3))) (set! a 3) b)) 3) (test (let ((a 1) (b 2)) (reactive-let ((a (* b 2)) (b (* a 3))) (set! b 3) a)) 4) (test (let ((a 1) (b 2)) (reactive-let ((a (* b 2))) (set! b 3) a)) 6) (test (let ((a 1)) (reactive-let ((b (+ a 1))) (set! a 3) b)) 4) (test (let ((a 1)) (reactive-let ((b (+ a 1)) (c (* a 2))) (set! a 3) (+ c b))) 10) (test (let ((a 1) (d 2)) (reactive-let ((b (+ a d)) (c (* a d)) (d 0)) (set! a 3) (+ b c))) 11) (test (let ((a 1) (d 2)) (reactive-let ((b (+ a d)) (c (* a d)) (d 0)) (set! a 3)) (symbol-access 'a)) #f) (test (let ((a 1) (d 2)) (reactive-let ((b (+ a d)) (c (* a d)) (d 0)) (set! a 3) (set! d 12) (+ b c))) 11) (test (let ((a 1) (b 2)) (+ (reactive-let ((b (+ a 1)) (c (* b 2))) (set! a 3) (+ b c)) a b)) 13) ;c=4 because it watches the outer b (test (let ((a 1)) (reactive-let ((b (* a 2))) (reactive-let ((c (* a 3))) (set! a 2) (+ b c)))) 10) (test (let ((a 1)) (reactive-let ((b (* a 2))) (let ((d (reactive-let ((c (* a 3))) c))) (set! a 2) (+ b d)))) 7) (test (let ((a 1)) (reactive-let ((b (* a 2))) (+ (reactive-let ((c (* a 3))) c) (set! a 2) b))) 9) ; a=2 is added to b=4 and c=3 (test (let ((a 1)) (reactive-let ((b (+ a 1))) (reactive-let ((c (* b 2))) (begin (set! a 3) (+ c b))))) 12) (test (reactive-let ((a (lambda (b) b))) (a 1)) 1) (test (reactive-let ((a (let ((b 1) (c 2)) (+ b c)))) a) 3) (test (let ((b 1)) (reactive-let ((a (let ((b 1) (c 2)) (+ b c))) (c (* b 2))) (set! b 43) c)) 86) (num-test (let ((x 0.0)) (reactive-let ((y (sin x))) (set! x 1.0) y)) (sin 1.0)) (num-test (let ((x 0.0)) (reactive-let* ((y x) (z (* y (cos x)))) (set! x 1.0) z)) (cos 1.0)) (test (let ((a 1)) (reactive-let* ((b a) (x (+ a b))) (set! a 3) (list b x))) '(3 6)) (test (let ((a 1)) (reactive-let ((b a) (c a)) (set! a 3) (list b c))) '(3 3)) (test (let ((a 1)) (reactive-let* ((b a) (c (* b a))) (set! a 3) (list b c))) '(3 9)) (test (let ((a 1)) (reactive-let ((b a)) (reactive-let ((c (* b a))) (set! a 3) (list b c)))) '(3 9)) (test (let ((a 1) (b 2)) (reactive-let ((c a) (d (* b a))) (set! a 3) (list a b c d))) '(3 2 3 6)) (test (let ((a 1)) (reactive-let ((b (* a 2)) (c (* a 3)) (d (* a 4))) (set! a 2) (list a b c d))) '(2 4 6 8)) (test (let ((b 2)) (reactive-let ((a (* b 2))) (+ (reactive-let ((a (* b 3))) (set! b 3) a) a))) 15) ;; (let ((a 1)) (define (set-a x) (set! a x)) (reactive-let ((b (* a 2))) (set-a 3) b)) -> b is still 2 ;; we can't see the outer set! without changing the outer accessor ;; even: (rlet ((a 1)) (define (set-a x) (set! a x)) (rlet ((b (* a 2))) (set-a 3) b)) -> 2 ;; (let ((a 1)) (define (set-a x e) (set! (e 'a) x)) (rlet ((b (* a 2))) (set-a 3 (curlet)) b)) -> 6 ;; (let ((a 1)) (define-macro (set-a x) `(set! a ,x)) (rlet ((b (* a 2))) (set-a 3) b)) -> 6 ;; reactive-set! places an accessor but never removes it -- dangling refs eventually (let ((max-stack 0)) (define (tc-1 a c) (reactive-let ((b (+ a 1))) (if (> (-s7-stack-top-) max-stack) (set! max-stack (-s7-stack-top-))) (if (< b c) (tc-1 b c)))) (tc-1 0 32) (if (> max-stack 12) (format *stderr* ";reactive-let tc max: ~D~%" max-stack))) (test (let ((a 1)) (reactive-let* ((b (+ a 1)) (c (* b 2))) (set! a 3) (+ c b))) 12) (test (let ((a 1)) (reactive-let* ((b (+ a 1))) (set! a 3) b)) 4) (test (reactive-let* ((a 1) (b (* a 2))) (set! a 3) b) 6) (let ((max-stack 0)) (define (tc-2 a c) (reactive-let* ((b (+ a 1))) (if (> (-s7-stack-top-) max-stack) (set! max-stack (-s7-stack-top-))) (if (< b c) (tc-2 b c)))) (tc-2 0 32) (if (> max-stack 12) (format *stderr* ";reactive-let* tc max: ~D~%" max-stack))) (let ((e (let ((a 1) (b 2)) (reactive-lambda* (s v) ((curlet) s)) (curlet)))) ; constant let (test (set! (e 'a) 32) 1) (set! (e 'b) 12) (test (e 'b) 2) (test (with-let e (set! a 32) a) 1)) (let () (define (make-library) (let ((A 1.0) ; define a library with 2 globals (A and B) and a function (f1) (B 2.0)) (reactive-lambda* (s v) ; make sure B is always twice A (case s ((A) (set! B (* 2 v))) ((B) (set! A (/ v 2)))) v) (define (f1 x) (+ A (* B x))) (curlet))) (with-let (make-library) (num-test (f1 3.0) 7.0) (set! A 3.0) (num-test B 6.0) (num-test (f1 3.0) 21.0) (set! B 4.0) (num-test (f1 3.0) 14.0))) (let ((lst ())) (call-with-input-vector (vector 1 2 3 4) (lambda (p) (do ((i 0 (+ i 1))) ((= i 4)) (set! lst (cons (read p) lst))))) (test lst '(4 3 2 1))) (test (call-with-output-vector (lambda (p) (do ((i 0 (+ i 1))) ((= i 4)) (write (* i 2) p) ; ("do" does not rebind in s7) (display (* i 4) p) (format p "~A" i)))) #(0 0 "0" 2 4 "1" 4 8 "2" 6 12 "3")) (test (subsequence (list 1 2 3 4)) (list 1 2 3 4)) (test (subsequence (list 1 2 3 4) 1) (list 2 3 4)) (test (subsequence (list 1 2 3 4) 1 3) (list 2 3)) (test (subsequence (list 1 2 3 4) 3 3) ()) (test (subsequence #(1 2 3 4) 2) #(3 4)) (test (subsequence "1234" 1) "234") (when with-block (test (subsequence (block .1 .2 .3 .4) 1 3) (block .2 .3))) (let ((e (openlet (inlet 'value #(1 2 3 4) 'subsequence (lambda args (apply subsequence ((car args) 'value) (cdr args))))))) (test (subsequence e 1 3) #(2 3)) (test (subsequence e 1) #(2 3 4)) (test (apply subsequence e ()) #(1 2 3 4)) (test (subsequence e) #(1 2 3 4))) (let ((vpl (*s7* 'print-length))) (set! (*s7* 'print-length) 3) (test (sequence->string '(0 1 2)) "(0 1 2)") (test (sequence->string '()) "()") (test (sequence->string '(0 1 2 3)) "(0 1 2 ...)") (test (sequence->string #(0 1 2)) "#(0 1 2)") (test (sequence->string #()) "#()") (test (sequence->string #(0 1 2 3)) "#(0 1 2 ...)") (test (sequence->string (hash-table)) "(hash-table)") (test (string? (sequence->string (hash-table '(a . 1) '(b . 2) '(c . 3)))) #t) (test (string? (sequence->string (hash-table '(a . 1) '(b . 2) '(c . 3) '(d . 4)))) #t) (test (sequence->string (inlet)) "(inlet)") (test (sequence->string (inlet 'a 1 'b 2 'c 3)) "(inlet '(a . 1) '(b . 2) '(c . 3))") (test (sequence->string (inlet 'a 1 'b 2 'c 3 'd 4)) "(inlet '(a . 1) '(b . 2) '(c . 3) ...)") (test (sequence->string "") "\"\"") (test (sequence->string "abc") "\"abc\"") (test (sequence->string "abcd") "\"abc ...\"") (test (sequence->string #u8()) "#u8()") (test (sequence->string (->byte-vector "abc")) "#u8(97 98 99)") (test (sequence->string (byte-vector 0 1 2 3)) "#u8(0 1 2 ...)") (test (sequence->string (float-vector)) "#()") (test (sequence->string (float-vector 0 1 2 3)) "#(0.0 1.0 2.0 ...)") (test (sequence->string (float-vector 0 1 2)) "#(0.0 1.0 2.0)") (when with-block (test (sequence->string (block)) "(block)")) (when with-block (test (sequence->string (block 0 1 2)) "(0.0 1.0 2.0)")) (when with-block (test (sequence->string (block 0 1 2 3)) "(0.0 1.0 2.0 ...)") ) (set! (*s7* 'print-length) 8) (test (string? (sequence->string (hash-table '(a . 1) '(b . 2) '(c . 3) '(d . 4)))) #t) (test (sequence->string (inlet 'a 1 'b 2 'c 3 'd 4)) "(inlet '(a . 1) '(b . 2) '(c . 3) '(d . 4))") (set! (*s7* 'print-length) vpl)) (test (pair? (member :heap-size (*s7*->list))) #t) (test (cdr-assoc 'a '((a . 1) (b . 2))) 1) (test (cdr-assoc 'c '((a . 1) (b . 2))) #f) (test (cdr-assoc 'c ()) #f) (test (adjoin 'a ()) '(a)) (test (adjoin 'a '(a)) '(a)) (test (adjoin 'a '(b a c)) '(b a c)) (test (adjoin 'a '(b c)) '(a b c)) (define (Display-test) (define-macro (with-Display . body) `(call-with-output-string (lambda (p) (let ((oldp (Display-port))) (set! (Display-port) p) ,@body (set! (Display-port) oldp))))) (define (strip-comments s) (let* ((len (length s)) (new-s (make-string len #\null))) (do ((i 0 (+ i 1)) (j 0) (k 1)) ((= i len) (substring new-s 0 j)) (case (s i) ((#\;) (set! k 0) (set! j (- j 1))) ((#\newline) (set! k 1) (set! (new-s j) #\newline)) (else (set! (new-s j) (s i)))) (set! j (+ j k))))) (define (Display-string=? s1 s2) (or (string=? s1 s2) (string=? (strip-comments s1) s2))) (Display (define (hi x) (+ x 1))) (let ((str (with-Display (hi 1)))) (if (not (Display-string=? str "(hi :x 1)\n -> 2\n")) (format *stderr* "Display 0: (hi 1) -> ~S~%" (strip-comments str)))) (define (ho y) (let ((z (+ y 1))) (hi z))) (let ((str (with-Display (ho 1)))) (if (not (Display-string=? str "(hi :x 2) ;called from ho\n -> 3\n")) (format *stderr* "Display 1: (ho 1) -> ~S~%" (strip-comments str)))) (Display (define (ho y) (let ((z (+ y 1))) (hi z)))) (let ((str (with-Display (ho 1)))) (if (not (Display-string=? str "(ho :y 1)\n (let ((z . 2))\n (hi :x 2)\n -> 3\n (hi z)) -> 3\n -> 3\n")) (format *stderr* "Display 1a: (ho 1) -> ~S~%" (strip-comments str)))) (Display (define (hi x) (if (> x 0) (hi (- x 1)) 0))) (let ((str (with-Display (hi 1)))) (if (not (Display-string=? str "(hi :x 1)\n (hi :x 0)\n -> 0\n -> 0\n")) (format *stderr* "Display 2: (hi 1) -> ~S~%" (strip-comments str)))) (Display (define (hi a b) (+ a b))) (let ((str (with-Display (hi 1 2)))) (if (and (not (Display-string=? str "(hi :a 1 :b 2)\n -> 3\n")) (not (Display-string=? str "(hi :b 2 :a 1)\n -> 3\n"))) (format *stderr* "Display 3: (hi 1 2) -> ~S~%" (strip-comments str)))) (Display (define (hi x) (let ((a 1) (b 2)) (+ x a b)))) (let ((str (with-Display (hi 1)))) (if (not (Display-string=? str "(hi :x 1)\n (let ((a . 1) (b . 2))\n (+ x a b)) -> 4\n -> 4\n")) (format *stderr* "Display 4: (hi 1) -> ~S~%" (strip-comments str)))) (Display (define (hi x) (let ((a 1) (b 2) (c 3) (d 4) (e 5) (f 6) (g 7)) (+ x e)))) (let ((str (with-Display (hi 1)))) (if (not (Display-string=? str "(hi :x 1)\n (let ((a . 1) (b . 2) (c . 3) (d . 4) (e . 5) (f . 6) ...)\n (+ x e)) -> 6\n -> 6\n")) (format *stderr* "Display 5: (hi 1) -> ~S~%" (strip-comments str)))) (Display (define (hi x) (x 0))) (let ((str (with-Display (hi '(0 1 2 3 4 5 6))))) (if (not (Display-string=? str "(hi :x (0 1 2 3 4 5 ...))\n -> 0\n")) (format *stderr* "Display 5: (hi '(0 1 2 3 4 5 6)) -> ~S~%" (strip-comments str)))) (let ((str (with-Display (hi #(0 1 2 3 4 5 6))))) (if (not (Display-string=? str "(hi :x #(0 1 2 3 4 5 ...))\n -> 0\n")) (format *stderr* "Display 5: (hi #(0 1 2 3 4 5 6)) -> ~S~%" (strip-comments str)))) (let ((str (with-Display (hi #u8(0 1 2 3 4 5 6))))) (if (not (Display-string=? str "(hi :x #u8(0 1 2 3 4 5 ...))\n -> 0\n")) (format *stderr* "Display 5: (hi #u8(0 1 2 3 4 5 6)) -> ~S~%" (strip-comments str)))) (let ((str (with-Display (hi "01234567")))) (if (not (Display-string=? str "(hi :x \"012345 ...\")\n -> #\\0\n")) (format *stderr* "Display 5: (hi \"01234567\") -> ~S~%" (strip-comments str)))) (Display (define (hi x) (x 'a))) (let ((str (with-Display (hi (hash-table '(a . 1)))))) (if (not (Display-string=? str "(hi :x (hash-table '(a . 1)))\n -> 1\n")) (format *stderr* "Display 5: (hi (hash-table '(a . 1))) -> ~S~%" (strip-comments str)))) (let ((str (with-Display (hi (inlet 'a 1))))) (if (not (Display-string=? str "(hi :x (inlet '(a . 1)))\n -> 1\n")) (format *stderr* "Display 5: (hi (inlet 'a 1)) -> ~S~%" (strip-comments str)))) (Display (define* (hi (x 1)) (* x 2))) (let ((str (with-Display (hi)))) (if (not (Display-string=? str "(hi :x 1)\n -> 2\n")) (format *stderr* "Display 6: (hi) -> ~S~%" (strip-comments str)))) (let ((y 5)) (Display (define* (hi (x (* y 2))) (* x 3))) (let ((str (with-Display (hi)))) (if (not (Display-string=? str "(hi :x 10)\n -> 30\n")) (format *stderr* "Display 7: (hi) -> ~S~%" (strip-comments str)))) (let ((str (with-Display (hi 3)))) (if (not (Display-string=? str "(hi :x 3)\n -> 9\n")) (format *stderr* "Display 8: (hi) -> ~S~%" (strip-comments str))))) (Display (define (f1 x) (or (> x 1) (< x -1) (= x 0)))) (let ((str (with-Display (f1 1)))) (if (not (Display-string=? str "(f1 :x 1)\n -> #f\n")) (format *stderr* "Display 9: (f1 1) -> ~S~%" (strip-comments str)))) (let ((str (with-Display (f1 -2)))) (if (not (Display-string=? str "(f1 :x -2)\n (or ... (< x -1) ... ) -> #t\n -> #t\n")) (format *stderr* "Display 9: (f1 -2) -> ~S~%" (strip-comments str)))) (let ((str (with-Display (f1 2)))) (if (not (Display-string=? str "(f1 :x 2)\n (or (> x 1) ... ) -> #t\n -> #t\n")) (format *stderr* "Display 9: (f1 2) -> ~S~%" (strip-comments str)))) (let ((str (with-Display (f1 0)))) (if (not (Display-string=? str "(f1 :x 0)\n (or ... (= x 0)) -> #t\n -> #t\n")) (format *stderr* "Display 9: (f1 0) -> ~S~%" (strip-comments str)))) (Display (define (f2 x) (and (> x 1) (not (= x 3)) (integer? x)))) (let ((str (with-Display (f2 0)))) (if (not (Display-string=? str "(f2 :x 0)\n (and (> x 1) ... ) -> #f\n -> #f\n")) (format *stderr* "Display 10: (f2 0) -> ~S~%" (strip-comments str)))) (let ((str (with-Display (f2 2)))) (if (not (Display-string=? str "(f2 :x 2)\n -> #t\n")) (format *stderr* "Display 10: (f2 2) -> ~S~%" (strip-comments str)))) (let ((str (with-Display (f2 3)))) (if (not (Display-string=? str "(f2 :x 3)\n (and ... (not (= x 3)) ... ) -> #f\n -> #f\n")) (format *stderr* "Display 10: (f2 3) -> ~S~%" (strip-comments str)))) (let ((str (with-Display (f2 3.5)))) (if (not (Display-string=? str "(f2 :x 3.5)\n (and ... (integer? x)) -> #f\n -> #f\n")) (format *stderr* "Display 10: (f2 3.5) -> ~S~%" (strip-comments str)))) (Display (define (f3 x) (let ((y (* x 2))) (and (> y 1) (not (= y 6)) (integer? x))))) (let ((str (with-Display (f3 3.5)))) (if (not (Display-string=? str "(f3 :x 3.5)\n (let ((y . 7.0))\n (and (> y 1) (not (= y 6)) (integer? x))) -> #f\n -> #f\n")) (format *stderr* "Display 11: (f3 3.5) -> ~S~%" (strip-comments str)))) (Display (define (f4 x) (display x (Display-port)) (newline (Display-port)) (* x 2))) (let ((str (with-Display (f4 1)))) (if (not (Display-string=? str "(f4 :x 1)\n1\n -> 2\n")) (format *stderr* "Display 12: (f4 1) -> ~S~%" (strip-comments str)))) (Display (define (f5 x) (when (> x 1) (display x (Display-port)) (newline (Display-port)) (* x 2)))) (let ((str (with-Display (f5 3)))) (if (not (Display-string=? str "(f5 :x 3)\n3\n(when ... (* x 2)) -> 6\n -> 6\n")) (format *stderr* "Display 13: (f5 3) -> ~S~%" (strip-comments str)))) (let ((str (with-Display (f5 0)))) (if (not (Display-string=? str "(f5 :x 0)\n(when (> x 1) -> #f ...)\n -> #\n")) (format *stderr* "Display 13: (f5 0) -> ~S~%" (strip-comments str)))) (Display (define (f5a x) (unless (> x 1) (display x (Display-port)) (newline (Display-port)) (* x 2)))) (let ((str (with-Display (f5a 3)))) (if (not (Display-string=? str "(f5a :x 3)\n(unless (> x 1) -> #t ...)\n -> #\n")) (format *stderr* "Display 14: (f5a 3) -> ~S~%" (strip-comments str)))) (let ((str (with-Display (f5a 0)))) (if (not (Display-string=? str "(f5a :x 0)\n0\n(unless ... (* x 2)) -> 0\n -> 0\n")) (format *stderr* "Display 14: (f5a 0) -> ~S~%" (strip-comments str)))) (Display (define (f6 x) (begin (display x (Display-port)) (newline (Display-port)) (* x 2)))) (let ((str (with-Display (f6 3)))) (if (not (Display-string=? str "(f6 :x 3)\n3\n(begin ... (* x 2)) -> 6\n -> 6\n")) (format *stderr* "Display 15: (f6 3) -> ~S~%" (strip-comments str)))) (Display (define (f7 x) (cond ((= x 0) 123) ((> x 1) (display x (Display-port)) (newline (Display-port)) (* x 2)) (#t x)))) (let ((str (with-Display (f7 3)))) (if (not (Display-string=? str "(f7 :x 3)\n3\n (cond ... ((> x 1) (display x (Display-port)) (newline (Display-port)) (* x 2)) ... ) -> 6\n -> 6\n")) (format *stderr* "Display 16: (f7 3) -> ~S~%" (strip-comments str)))) (let ((str (with-Display (f7 0)))) (if (not (Display-string=? str "(f7 :x 0)\n (cond ((= x 0) 123) ... ) -> 123\n -> 123\n")) (format *stderr* "Display 16: (f7 0) -> ~S~%" (strip-comments str)))) (let ((str (with-Display (f7 1)))) (if (not (Display-string=? str "(f7 :x 1)\n (cond ... (#t x)) -> 1\n -> 1\n")) (format *stderr* "Display 16: (f7 1) -> ~S~%" (strip-comments str)))) (Display (define (f8 x) (case (+ x 1) ((0) 123) ((1 2 3) 0) (else 4)))) (let ((str (with-Display (f8 3)))) (if (not (Display-string=? str "(f8 :x 3)\n (case [4] ... (else 4)) -> 4\n -> 4\n")) (format *stderr* "Display 17: (f8 3) -> ~S~%" (strip-comments str)))) (let ((str (with-Display (f8 -1)))) (if (not (Display-string=? str "(f8 :x -1)\n (case [0] ((0) 123) ... ) -> 123\n -> 123\n")) (format *stderr* "Display 17: (f8 -1) -> ~S~%" (strip-comments str)))) (let ((str (with-Display (f8 1)))) (if (not (Display-string=? str "(f8 :x 1)\n (case [2] ... ((1 2 3) 0) ... ) -> 0\n -> 0\n")) (format *stderr* "Display 17: (f8 1) -> ~S~%" (strip-comments str)))) (Display (define (f9 x) (if (< x 0) (* x 2) (* x 3)))) (let ((str (with-Display (f9 3)))) (if (not (Display-string=? str "(f9 :x 3)\n -> 9\n")) (format *stderr* "Display 18: (f9 3) -> ~S~%" (strip-comments str)))) (Display (define (f10 x) (dynamic-wind (lambda () (set! x (* x 2))) (lambda () (display x (Display-port)) (newline (Display-port)) (* x 2)) (lambda () (set! x 0))))) (let ((str (with-Display (f10 1)))) (if (not (Display-string=? str "(f10 :x 1)\n2\n(dynamic-wind ... (* x 2)) -> 4\n -> 4\n")) (format *stderr* "Display 19: (f10 1) -> ~S~%" (strip-comments str)))) (Display (define (f11 x) (cond (x => abs)))) (let ((str (with-Display (f11 -1)))) (if (not (Display-string=? str "(f11 :x -1)\n (cond (x => abs)) -> 1\n -> 1\n")) (format *stderr* "Display 20: (f11 -1) -> ~S~%" (strip-comments str)))) (Display (define (f12 x) (cond ((+ x 1) => (lambda (y) (* y 2)))))) (let ((str (with-Display (f12 2)))) (if (not (Display-string=? str "(f12 :x 2)\n (cond ((+ x 1) => (lambda (y) (* y 2)))) -> 6\n -> 6\n")) (format *stderr* "Display 21: (f12 2) -> ~S~%" (strip-comments str)))) (Display (define (f13 x) (case x ((a) => (lambda (y) y)) (else => symbol?)))) (let ((str (with-Display (f13 'a)))) (if (not (Display-string=? str "(f13 :x a)\n (case [a] ((a) => (lambda (y) y)) ... ) -> a\n -> a\n")) (format *stderr* "Display 22: (f13 'a) -> ~S~%" (strip-comments str)))) (let ((str (with-Display (f13 1)))) (if (not (Display-string=? str "(f13 :x 1)\n (case [1] ... (else => symbol?)) -> #f\n -> #f\n")) (format *stderr* "Display 22: (f13 1) -> ~S~%" (strip-comments str)))) (Display (define (f14 . x) (display x (Display-port)) (newline (Display-port)) (apply + x))) (let ((str (with-Display (f14)))) (if (not (Display-string=? str "(f14 :x ())\n()\n -> 0\n")) (format *stderr* "Display 23: (f14) -> ~S~%" (strip-comments str)))) (let ((str (with-Display (f14 1)))) (if (not (Display-string=? str "(f14 :x (1))\n(1)\n -> 1\n")) (format *stderr* "Display 23: (f14 1) -> ~S~%" (strip-comments str)))) (let ((str (with-Display (f14 1 2)))) (if (not (Display-string=? str "(f14 :x (1 2))\n(1 2)\n -> 3\n")) (format *stderr* "Display 23: (f14 1 2) -> ~S~%" (strip-comments str)))) (let ((str (with-Display (let ((a 1) (b 2)) (f14 a b))))) (if (not (Display-string=? str "(f14 :x (1 2))\n(1 2)\n -> 3\n")) (format *stderr* "Display 23: (f14 a b) -> ~S~%" (strip-comments str)))) (Display (define (f15) (+ 1 2))) (let ((str (with-Display (f15)))) (if (not (Display-string=? str "(f15)\n -> 3\n")) (format *stderr* "Display 23: (f15) -> ~S~%" (strip-comments str)))) (Display (define (f16 x) (case (+ x 1) ((0) 123) ((1 2 3) 0)))) (let ((str (with-Display (f16 4)))) (if (not (Display-string=? str "(f16 :x 4)\n (case [5] falls through\n -> #\n")) (format *stderr* "Display 24: (f16 4) -> ~S~%" (strip-comments str)))) (Display (define (f17 x . y) (display y (Display-port)) (newline (Display-port)) (apply + x y))) (let ((str (with-Display (f17 1)))) (if (and (not (Display-string=? str "(f17 :x 1 :y ())\n()\n -> 1\n")) (not (Display-string=? str "(f17 :y () :x 1)\n()\n -> 1\n"))) (format *stderr* "Display 25: (f17 1) -> ~S~%" (strip-comments str)))) (let ((str (with-Display (f17 1 2)))) (if (and (not (Display-string=? str "(f17 :x 1 :y (2))\n(2)\n -> 3\n")) (not (Display-string=? str "(f17 :y (2) :x 1)\n(2)\n -> 3\n"))) (format *stderr* "Display 25: (f17 1 2) -> ~S~%" (strip-comments str)))) (let ((str (with-Display (let ((a 1) (b 2)) (f17 a b))))) (if (and (not (Display-string=? str "(f17 :x 1 :y (2))\n(2)\n -> 3\n")) (not (Display-string=? str "(f17 :y (2) :x 1)\n(2)\n -> 3\n"))) (format *stderr* "Display 25: (f17 a b) -> ~S~%" (strip-comments str)))) (Display (define* (f18 (x 1) (y 2)) (display y (Display-port)) (newline (Display-port)) (+ x y))) (let ((str (with-Display (f18)))) (if (and (not (Display-string=? str "(f18 :x 1 :y 2)\n2\n -> 3\n")) (not (Display-string=? str "(f18 :y 2 :x 1)\n2\n -> 3\n"))) (format *stderr* "Display 26: (f18) -> ~S~%" (strip-comments str)))) (let ((str (with-Display (f18 3)))) (if (and (not (Display-string=? str "(f18 :x 3 :y 2)\n2\n -> 5\n")) (not (Display-string=? str "(f18 :y 2 :x 3)\n2\n -> 5\n"))) (format *stderr* "Display 26: (f18 3) -> ~S~%" (strip-comments str)))) (let ((str (with-Display (f18 :y 32)))) (if (and (not (Display-string=? str "(f18 :x 1 :y 32)\n32\n -> 33\n")) (not (Display-string=? str "(f18 :y 32 :x 1)\n32\n -> 33\n"))) (format *stderr* "Display 26: (f18 :y 32) -> ~S~%" (strip-comments str)))) (let ((str (with-Display (f18 :y 32 :x 12)))) (if (and (not (Display-string=? str "(f18 :x 12 :y 32)\n32\n -> 44\n")) (not (Display-string=? str "(f18 :y 32 :x 12)\n32\n -> 44\n"))) (format *stderr* "Display 26: (f18 :y 32 :x 12) -> ~S~%" (strip-comments str)))) (Display (define* (f19 (x 1) y) (display y (Display-port)) (newline (Display-port)) (list x y))) (let ((str (with-Display (f19)))) (if (and (not (Display-string=? str "(f19 :x 1 :y #f)\n#f\n -> (1 #f)\n")) (not (Display-string=? str "(f19 :y #f :x 1)\n#f\n -> (1 #f)\n"))) (format *stderr* "Display 27: (f19) -> ~S~%" (strip-comments str)))) (Display (define* (f20 x :rest y) (display y (Display-port)) (newline (Display-port)) (list x y))) (let ((str (with-Display (f20)))) (if (and (not (Display-string=? str "(f20 :x #f :y ())\n()\n -> (#f ())\n")) (not (Display-string=? str "(f20 :y () :x #f)\n()\n -> (#f ())\n"))) (format *stderr* "Display 28: (f20) -> ~S~%" (strip-comments str)))) (let ((str (with-Display (let ((x 1)) (Display (or (< x 1) (= x 1))))))) (if (not (Display-string=? str " (or ... (= x 1)) -> #t\n")) (format *stderr* "Display 29: (or...) -> ~S~%" (strip-comments str)))) (let ((str (with-Display (let ((x 1)) (Display (when (> x 0) (+ x 1))))))) (if (not (Display-string=? str "(when ... (+ x 1)) -> 2\n")) (format *stderr* "Display 30: (when...) -> ~S~%" (strip-comments str)))) (let ((str (with-Display (Display (let ((x 1)) (+ x 1)))))) (if (not (Display-string=? str "(let ((x . 1))\n (+ x 1)) -> 2\n")) (format *stderr* "Display 30: (let...) -> ~S~%" (strip-comments str)))) (set! ((funclet Display) '*display-spacing*) 4) (Display (define (f21 x) (if (> x 0) (f21 (- x 1)) 0))) (let ((str (with-Display (f21 2)))) (if (not (Display-string=? str "(f21 :x 2)\n (f21 :x 1)\n (f21 :x 0)\n -> 0\n -> 0\n -> 0\n")) (format *stderr* "Display 31: (f21 2) -> ~S~%" (strip-comments str)))) (set! ((funclet Display) '*display-spacing*) 1) (Display (define (f21 x) (if (> x 0) (f21 (- x 1)) 0))) (let ((str (with-Display (f21 2)))) (if (not (Display-string=? str "(f21 :x 2)\n (f21 :x 1)\n (f21 :x 0)\n -> 0\n -> 0\n -> 0\n")) (format *stderr* "Display 31a: (f21 2) -> ~S~%" (strip-comments str)))) (set! ((funclet Display) '*display-spacing*) 2) ) (Display-test) ) (let () (require write.scm) (if (not (string=? (pp '(lambda* (a b) (+ a b) (* 1 2))) "(lambda* (a b)\n (+ a b)\n (* 1 2))")) (format *stderr* "pp 1~%")) (if (not (string=? (pp '(let ((a 1) (b 2)) (+ a b))) "(let ((a 1)\n (b 2))\n (+ a b))")) (format *stderr* "pp 2~%")) (if (not (string=? (pp '(let () (+ a b))) "(let ()\n (+ a b))")) (format *stderr* "pp 2a~%")) (if (not (string=? (pp '(begin (+ 1 2) (* 2 3))) "(begin\n (+ 1 2)\n (* 2 3))")) (format *stderr* "pp 3~%")) (if (not (string=? (pp '(case a ((a b c) 1) ((d) 2) (else 3))) "(case a\n ((a b c) 1)\n ((d) 2)\n (else 3))")) (format *stderr* "pp 4: ~A~%" (pp '(case a ((a b c) 1) ((d) 2) (else 3))))) (if (not (string=? (pp '(cond ((> a 1) 2) ((< a 3) 3) (#t 4))) "(cond ((> a 1) 2)\n ((< a 3) 3)\n (#t 4))")) (format *stderr* "pp 5~%")) (if (not (string=? (pp '(if a '(1 2 3))) "(if a '(1 2 3))")) (format *stderr* "pp7~%")) (if (not (= ((funclet pretty-print) '*pretty-print-length*) 100)) (format *stderr* "*pretty-print-length*: ~A~%" ((funclet pretty-print) '*pretty-print-length*))) (if (not (= ((funclet pretty-print) '*pretty-print-spacing*) 2)) (format *stderr* "*pretty-print-spacing*: ~A~%" ((funclet pretty-print) '*pretty-print-spacing*))) (if (not (string=? (pp '(+ pi nan.0 1.123456)) "(+ pi nan.0 1.123456)")) (format *stderr* "pp8~%")) (if (not (string=? (pp 3.1415123123213) "3.1415")) (format *stderr* "pp9: ~A~%" (pp 3.1415123123213))) (let ((old-format ((funclet pretty-print) '*pretty-print-float-format*))) (set! ((funclet pretty-print) '*pretty-print-float-format*) "~,12F") (if (not (string=? (pp 3.1415123123213) "3.141512312321")) (format *stderr* "pp10: ~A~%" (pp 3.1415123123213))) (set! ((funclet pretty-print) '*pretty-print-float-format*) old-format)) (set! ((funclet pretty-print) '*pretty-print-spacing*) 8) (if (not (string=? (pp '(let () (+ a b))) "(let ()\n (+ a b))")) (format *stderr* "pp 11~%")) ) (let () (require r7rs.scm) ;;; boolean=? (test (boolean=? #f #f) #t) (test (boolean=? #f #t) #f) (test (boolean=? #f #f #f) #t) (test (boolean=? #t #t) #t) (test (boolean=? #f #f #t #f) #f) (test (boolean=? #f (values) #f) #f) (test (boolean=? 1 #t) #f) ;(test (boolean=?) 'error) ;(test (boolean=? #f) 'error) (for-each (lambda (arg) (if (boolean=? #f arg) (format-logged #t ";(boolean=? #f ~A) -> #t?~%" arg))) (list "hi" '(1 2) () "" #() (integer->char 65) 1 'a-symbol (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #\f (lambda (a) (+ a 1)) :hi (if #f #f) # # #)) (test (boolean=? #f #false) #t) (test (boolean=? #t #true) #t) ;;; symbol=? (test (symbol=? 'hi 'hi) #t) (test (symbol=? 'hi 'hi 'hi) #t) (test (symbol=? 'hi 'hi 'ho) #f) (test (symbol=? 'hi 'hi pi) #f) (test (symbol=? #f 'hi) #f) (for-each (lambda (arg) (if (symbol=? 'abs arg) (format-logged #t ";(symbol=? 'abs ~A) -> #t?~%" arg))) (list "hi" (integer->char 65) 1 (list 1 2) '#t '3 (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #\f (lambda (a) (+ a 1)) # #)) ;(test (symbol=?) 'error) ;(test (symbol=? 'hi) 'error) (test (symbol=? :hi :hi) #t) (test (symbol=? :hi hi:) #f) ;; from chibi scheme I think (let*-values (((root rem) (exact-integer-sqrt 32))) (test (* root rem) 35)) (test (let ((a 'a) (b 'b) (x 'x) (y 'y)) (let*-values (((a b) (values x y)) ((x y) (values a b))) (list a b x y))) '(x y x y)) (test (force (r7rs-delay (+ 1 2))) 3) (test (let ((p (r7rs-delay (+ 1 2)))) (list (force p) (force p))) '(3 3)) (let () (define integers (letrec ((next (lambda (n) (r7rs-delay (cons n (next (+ n 1))))))) (next 0))) (define head (lambda (stream) (car (force stream)))) (define tail (lambda (stream) (cdr (force stream)))) (test (head (tail (tail integers))) 2) (define (stream-filter p? s) (delay-force (if (null? (force s)) (r7rs-delay '()) (let ((h (car (force s))) (t (cdr (force s)))) (if (p? h) (r7rs-delay (cons h (stream-filter p? t))) (stream-filter p? t)))))) (test (head (tail (tail (stream-filter odd? integers)))) 5)) (let () (define radix (make-parameter 10 (lambda (x) (if (and (integer? x) (<= 2 x 16)) x (error "invalid radix"))))) (define (f n) (number->string n (radix))) (test (f 12) "12") (test (parameterize ((radix 2)) (f 12)) "1100") (test (f 12) "12")) (let () (define plus (case-lambda (() 0) ((x) x) ((x y) (+ x y)) ((x y z) (+ (+ x y) z)) (args (apply + args)))) (test (plus) 0) (test (plus 1) 1) (test (plus 1 2) 3) (test (plus 1 2 3) 6) (test (plus 1 2 3 4) 10) (define mult (case-lambda (() 1) ((x) x) ((x y) (* x y)) ((x y . z) (apply mult (* x y) z)))) (test (mult) 1) (test (mult 1) 1) (test (mult 1 2) 2) (test (mult 1 2 3) 6) (test (mult 1 2 3 4) 24)) (test (let () (define-values (x y) (values 1 2)) (+ x y)) 3) (test (call-with-values (lambda () (exact-integer-sqrt 4)) list) '(2 0)) (test (call-with-values (lambda () (exact-integer-sqrt 5)) list) '(2 1)) (test (vector-copy #()) #()) (test (vector-copy #(a b c)) #(a b c)) (test (vector-copy #(a b c) 1) #(b c)) (test (vector-copy #(a b c) 1 2) #(b)) (let ((e (box 1))) (test (box? e) #t) (test (unbox e) 1) (test (e 'value) 1) (set-box! e 2) (test (unbox e) 2) (test (string=? (object->string e) "#") #t)) ) ;;; -------------------------------------------------------------------------------- ;;; ;;; cload c-define tests ;;; (see libc.scm et al below) (if (provided? 'snd) (begin (load "cload.scm") (c-define '((double j0 (double)) (double j1 (double)) (double erf (double)) (double erfc (double)) (double lgamma (double))) "m" "math.h") (num-test (m:j0 1.0) 0.76519768655797) (num-test (m:j1 1.0) 0.44005058574493) (num-test (m:j0 1/2) 0.93846980724081) (num-test (m:erf 1.0) 0.84270079294971) (num-test (m:erf 2) 0.99532226501895) (num-test (m:erfc 1.0) 0.15729920705029) (num-test (m:lgamma 2/3) 0.30315027514752) (let () (c-define '(char* getenv (char*))) (c-define '(int setenv (char* char* int))) (test (string? (getenv "HOST")) #t)) (test (defined? 'setenv) #f) (let () (define local-file-exists? (let () ; define F_OK and access only within this let (c-define '((int F_OK) (int access (char* int))) "" "unistd.h") (lambda (arg) (= (access arg F_OK) 0)))) (define delete-file (let () (c-define '(int unlink (char*)) "" "unistd.h") (lambda (file) (= (unlink file) 0)))) ; 0=success (test (local-file-exists? "s7test.scm") #t)) (c-define '((in-C "static struct timeval overall_start_time; \n\ static bool time_set_up = false; \n\ static double get_internal_real_time(void) \n\ { \n\ struct timezone z0; \n\ struct timeval t0; \n\ double secs; \n\ if (!time_set_up) {gettimeofday(&overall_start_time, &z0); time_set_up = true;} \n\ gettimeofday(&t0, &z0); \n\ secs = difftime(t0.tv_sec, overall_start_time.tv_sec);\n\ return(secs + 0.000001 * (t0.tv_usec - overall_start_time.tv_usec)); \n\ }") (double get_internal_real_time (void))) "" '("time.h" "sys/time.h")) (define-macro (new-time func) `(let ((start (get_internal_real_time))) ,func (- (get_internal_real_time) start))) (test (real? (new-time (do ((i 0 (+ i 1))) ((= i 30) i)))) #t) (when (provided? 'linux) (c-define '(int getpid (void)) "" "unistd.h") (call-with-input-file (format #f "/proc/~D/status" (getpid)) (lambda (p) (let ((name (substring (read-line p) 6))) (do ((str (read-line p) (read-line p))) ((eof-object? str)) (if (string=? (substring str 0 6) "VmRSS:") (let ((size (with-input-from-string (substring str 7) read))) (format #t "~%~A size: ~A kB, time: ~A~%" name size (*s7* 'cpu-time))))))))) )) ;;; -------------------------------------------------------------------------------- (let ((e (openlet (inlet 'absolute-value (lambda (x) (abs x)))))) (test (+ 3 ((e 'absolute-value) -3)) 6) (test (catch #t (lambda () (+ ((e 'absolute-value) -3) 32)) (lambda args "oops")) 35) (test (catch #t (lambda () (+ ((e 'absolute-value) "oops") 32)) (lambda args 35)) 35)) (let ((e (openlet (inlet 'x -3 'abs (lambda (e) (let ((x (e 'x))) (if (negative? x) (- x) x))))))) (test (+ 3 (abs e)) 6) (test (catch #t (lambda () (+ (abs e) 32)) (lambda args "oops")) 35) (set! (e 'x) "oops") (test (catch #t (lambda () (+ (abs e) 32)) (lambda args 35)) 35)) (test (+ 32 (call-with-exit (lambda (return) (let ((e (lambda (x) (return (if (negative? x) (- x) x))))) (+ 123 (e -321)))))) 353) (test (+ 32 (catch #t (lambda () (let ((e (openlet (inlet 'x -3 'abs (lambda (e) (let ((x (e 'x))) (error 'oops (if (negative? x) (- x) x)))))))) (+ 123 (abs e) -321))) (lambda args 3))) 35) (test (+ 32 (catch #t (lambda () (let ((e (openlet (inlet 'x -3 'abs (lambda (e) (let ((x (e 'x))) (throw 'oops (if (negative? x) (- x) x)))))))) (+ 123 (abs e) -321))) (lambda args 3))) 35) (test (+ 32 (call-with-exit (lambda (return) (let ((e (openlet (inlet 'x -3 'abs (lambda (e) (let ((x (e 'x))) (return (if (negative? x) (- x) x)))))))) (+ 123 (abs e) -321))))) 35) (test (+ 32 (call-with-exit (lambda (return) (let ((e (openlet (inlet 'x -3 'abs (lambda (e) (let ((x (e 'x))) (return (if (negative? x) (- x) x)))))))) (+ 123 (eval `(abs e)) -321))))) 35) (test (+ 32 (catch #t (lambda () (call-with-exit (lambda (return) (let ((e (openlet (inlet 'x -3 'abs (lambda (e) (let ((x (e 'x))) (return (if (negative? x) (- x) x)))))))) (+ 123 (error 'oops (abs e)) -321))))) (lambda args 3))) 35) (test (+ 32 (call-with-exit (lambda (return) (let ((e (openlet (inlet 'x -3 'abs (lambda (e) (let ((x (e 'x))) (return (if (negative? x) (- x) x)))))))) (let ((e1 (openlet (inlet 'abs (lambda (x) (abs e)))))) (+ 123 (abs e1) -321)))))) 35) (test (+ 32 (call-with-exit (lambda (return) (let ((e (openlet (inlet 'x -3 'abs (lambda (e) (let ((x (e 'x))) (return (if (negative? x) (- x) x)))))))) (let ((e1 (openlet (inlet 'abs (lambda (x) (abs e)))))) (let ((e2 (openlet (inlet 'abs (lambda (x) (abs e1)))))) (+ 123 (abs e2) -321))))))) 35) (let () ; optimize these things (define (tst-it) (+ 32 (call-with-exit (lambda (return) (let ((e (openlet (inlet 'x -3 'abs (lambda (e) (let ((x (e 'x))) (return (if (negative? x) (- x) x)))))))) (+ 123 (abs e) -321)))))) (test (tst-it) 35)) ; (+ 123 3 -321 32) is -163 (let () (define (tst-it1) (+ 32 (catch 'ok (lambda () (let ((e (openlet (inlet 'x -3 'abs (lambda (e) (let ((x (e 'x))) (throw 'ok (if (negative? x) (- x) x)))))))) (+ 123 (abs e) -321))) (lambda (type info) (car info))))) (test (tst-it1) 35)) (let () (define (tst-it2) (+ 32 (call/cc (lambda (return) (let ((e (openlet (inlet 'x -3 'abs (lambda (e) (let ((x (e 'x))) (return (if (negative? x) (- x) x)))))))) (+ 123 (abs e) -321)))))) (test (tst-it2) 35)) ;;; reader-cond (define (rt2) (reader-cond ((> 3 2) `(+ 1 2)) (#t 'error))) (test (rt2) '(+ 1 2)) (define (rt3) (reader-cond ((> 3 2) (+ 1 2)) (#t 'error))) (test (rt3) 3) (let () (define (f1) (let ((x 1) (y 1)) (reader-cond ((not (provided? 'asdf)) (set! x (+ x 1)) (set! x (+ x 1))) (#t (set! x (- x 1)))) (reader-cond ((provided? 'asdf) (set! y (+ y 1)) (set! y (+ y 1))) (#t (set! y (- y 1)))) (list x y))) (f1) (test (f1) (list 3 0))) (test (list 1 (reader-cond ((> 3 2) 2 3 4)) 5) (list 1 2 3 4 5)) (define-expansion (__exp1__) (values 1 2 3)) (let () (test (abs (+ 2 -3)) (+ 1)) (define-macro (protected-let vars . body) ;; locals outside this let are not changed (and aren't accessible), ;; and we'll protect the current rootlet values of built-ins `(with-let (inlet :in (apply inlet ',(map (lambda (f) (values (car f) ((rootlet) (car f)))) (unlet)))) (dynamic-wind (lambda () #f) (lambda () (let ,vars ,@body)) (lambda () (for-each (lambda (f) ; if any built-in's value has changed in the protected-let, reset it (let ((value-before-let (in (car f)))) (unless (equal? (symbol->value (car f)) value-before-let) (apply set! (list (car f) (if (eq? value-before-let #) ; it was not changed before (cdr f) ; so use the start-up value value-before-let)))))) (unlet)))))) (let ((abs 32)) (let ((val (protected-let () (set! abs 64) (set! + 0) (test (- + abs) -64) 12))) (test (+ val abs) 44))) (test (abs (+ 2 -3)) (+ 1)) (define-macro (local-let vars . body) ;; locals outside this let are accessible and can be changed, but we'll protect them and the current rootlet values of built-ins `(let ((in (apply inlet (curlet) ',(map (lambda (f) (values (car f) ((rootlet) (car f)))) (unlet))))) (dynamic-wind (lambda () #f) (lambda () (let ,vars ,@body)) (lambda () (let ((out (unlet))) (when (out 'set!) ; in case set! was changed -- see example below (eval `(define set! #_set!) (rootlet))) (for-each (lambda (f) (let ((value-before-let (in (car f)))) (unless (or (equal? (symbol->value (car f)) value-before-let) (eq? 'set! (car f))) (apply #_set! (list (car f) (if (eq? value-before-let #) (cdr f) value-before-let)))))) (inlet in out))))))) #| (let ((abs 32) (a 20)) (let ((val (local-let () (set! abs 64) (set! a 1) (set! + 0) (define (set! a b) b) (format *stderr* "in local-let, abs: ~A, (- + abs): ~A~%" abs (- + abs)) 12))) (format *stderr* "in outer let: abs: ~A, (+ abs): ~A, protected-let: ~A, a: ~A~%" abs (+ abs) val a))) (format *stderr* "top: abs: ~A, +: ~A~%" abs +) |# (let ((abs 32) (a 20)) (let ((val (local-let () (set! abs 64) (set! + 0) (set! a 1) (test (- + abs) -64) 12))) (test (+ abs a val) 64))) (test (abs -1) (+ 1))) (let () (define (f1) (let ((lst '(1 2 (reader-cond ((> 1 0) 3) (else 4)) 5 6))) lst)) (test (f1) '(1 2 3 5 6)) (define (f2) (let ((lst '(1 2 (reader-cond ((> 1 0) 3 4)) 5 6))) lst)) (test (f2) '(1 2 3 4 5 6)) (define (f3) '((__exp1__) 5)) (test (f3) '(1 2 3 5)) (define (f4) (+ (__exp1__) (__exp1__))) (test (f4) 12) (define (f5) (let ((lst '((reader-cond ((> 1 0) (__exp1__)) (else 4)) 5 6))) lst)) (test (f5) '(1 2 3 5 6)) (define (f6) (let ((lst ((reader-cond ((> 1 0) list) (else cons)) 1 2))) lst)) (test (f6) '(1 2)) (define (f7) (let ((lst ((reader-cond ((= 1 0) vector) ((< 1 0) list) (else cons)) 1 2))) lst)) (test (f7) '(1 . 2)) (define (f8) (let ((lst ((reader-cond ((> 1 0) quote)) (+ 2 3)))) lst)) (test (f8) '(+ 2 3)) (define (f9) (let ((lst ((reader-cond ((= 1 0) quote)) list 2 3))) lst)) (test (f9) '(2 3)) (define (f10) (let ((lst #(0 (reader-cond ((> 1 0) (+ 2 3))) 2))) lst)) (test (f10) #(0 (+ 2 3) 2)) (define (f11) (let ((lst `(0 ,(reader-cond ((> 1 0) (+ 2 3))) 2))) lst)) (test (f11) '(0 5 2)) ) (test (let ((v #(1 (reader-cond (#t 32)) 890))) v) #(1 32 890)) (test (let ((v #(1 (reader-cond (#t 2 3)) 4))) v) #(1 2 3 4)) (test (let ((v #(1 (reader-cond ((+ 2 3))) 4))) v) #(1 5 4)) ;;; even worse: ;; (define (reader-cond ((display "defining hiho\n" *stderr*) hiho)) (lambda () "hiho")) ;; (format *stderr* "~S~%" (hiho)) (test (let ((equal? #f)) (member 3 '(1 2 3))) '(3)) (test (let ((eqv? #f)) (case 1 ((1) 1))) 1) ; scheme wg (test (let ((eqv? equal?)) (case "asd" (("asd") 1) (else 2))) 2) (test (let ((eq? #f)) (memq 'a '(a b c))) '(a b c)) (test (let ((if #t)) (or if)) #t) (test (let ((if +)) (if 1 2 3)) 6) (test (if (let ((if 3)) (> 2 if)) 4 5) 5) (test (let ('1 ) quote) 1) (test (let ((quote 1)) (+ quote 1)) 2) (test (let ((quote -)) '32) -32) (test (do ((do 1)) (#t do)) 1) (test (do ((do 1 (+ do do))) ((> do 3) do)) 4) (test (do ((do 1 do) (j do do)) (do do)) 1) (test (do ((do do do)) (do do)) do) (test (do ((do do do)) (do do do)) do) ; ok ok! (test (or (let ((or #t)) or)) #t) (test (and (let ((and #t)) and)) #t) (test (let ((=> 3) (cond 4)) (+ => cond)) 7) (test (case 1 ((1 2) (let ((case 3)) (+ case 1))) ((3 4) 0)) 4) (test (let ((lambda 4)) (+ lambda 1)) 5) (test (let () (define (hi a) (let ((pair? +)) (pair? a 1))) (hi 2)) 3) (test ((lambda (let) (let* ((letrec 1)) (+ letrec let))) 123) 124) (test (let ((begin 3)) (+ begin 1)) 4) (test ((lambda (let*) (let ((letrec 1)) (+ letrec let*))) 123) 124) (test ((lambda (quote) (+ quote 1)) 2) 3) (test ((lambda (quote . args) (list quote args)) 1 2 3) '(1 (2 3))) (test (let ((do 1) (map 2) (for-each 3) (quote 4)) (+ do map for-each quote)) 10) (test ((lambda lambda lambda) 'x) '(x)) (test ((lambda (begin) (begin 1 2 3)) (lambda lambda lambda)) '(1 2 3)) (test (let* ((let 3) (x let)) (+ x let)) 6) (test (((lambda case lcm))) 1) (test (((lambda let* *))) 1) (test (do ((i 0 1) '(list)) (#t quote)) ()) (test ((lambda (let) (+)) 0) 0) (test (let () (define (hi cond) (+ cond 1)) (hi 2)) 3) (test (let () (define* (hi (cond 1)) (+ cond 1)) (hi 2)) 3) (test (let () (define* (hi (cond 1)) (+ cond 1)) (hi)) 2) (test (let () ((lambda (cond) (+ cond 1)) 2)) 3) (test (let () ((lambda* (cond) (+ cond 1)) 2)) 3) (test (let () (define-macro (hi cond) `(+ 1 ,cond)) (hi 2)) 3) (test (let () (define-macro* (hi (cond 1)) `(+ 1 ,cond)) (hi)) 2) (test (let () (define (hi abs) (+ abs 1)) (hi 2)) 3) (test (let () (define (hi if) (+ if 1)) (hi 2)) 3) (test (let () (define* (hi (lambda 1)) (+ lambda 1)) (hi)) 2) (test (do ((i 0 0) '(+ 0 1)) ((= i 0) i)) 0) ; guile also! (do ((i 0 0) (quote list (+ 0 1))) ((= i 0) i))? (test (let () (define (cond a) a) (cond 1)) 1) (test (let ((cond 1)) (+ cond 3)) 4) (test (let () (define (tst cond) (if cond 0 1)) (tst #f)) 1) (test (let () (define (tst fnc) (fnc ((> 0 1) 2) (#t 3))) (tst cond)) 3) (test (let () (define (tst fnc) (fnc ((> 0 1) 2) (#t 3))) (define (val) cond) (tst (val))) 3) (test (let () (define-macro (hi a) `(let ((lambda +)) (lambda ,a 1))) (hi 2)) 3) (test ((let ((do or)) do) 1 2) 1) (test (let () (define (hi) (let ((oscil *)) (if (< 3 2) (+ 1 2) (oscil 4 2)))) (hi) (hi)) 8) (test (let () (define (hi) (let ((oscil *)) (if (< 3 2) (+ 1 2) (oscil 4 2)))) (hi) (hi) (hi) (hi)) 8) (test (let ((x 12)) (define (hi env) (set! x (env 0)) x) (hi '(1 2 3)) (hi '(1 2 3))) 1) (test (let ((x 12)) (define (hi env) (set! x (+ x (env 0))) x) (hi '(1 2 3)) (hi '(1 2 3))) 14) (test (let ((x 12)) (define (hi env) (set! x (+ (env 0) x)) x) (hi '(1 2 3)) (hi '(1 2 3))) 14) (test (let ((x 12)) (define (hi env) (set! x (+ x (env 0))) x) (hi '(1 2 3)) (hi '(1 2 3)) (hi '(1 2 3))) 15) (test (let ((x 12)) (define (hi env) (set! x (+ (env 0) x)) x) (hi '(1 2 3)) (hi '(1 2 3)) (hi '(1 2 3))) 15) (test (let ((env +) (x 0)) (define (hi) (do ((i 0 (+ i (env 1 2)))) ((> i (env 4 5)) (env 1 2 3)) (+ x (env 1)))) (hi) (hi)) 6) (test (let ((env +) (x 0)) (define (hi) (do ((i 0 (+ i 3))) ((> i (env 4 5)) (env 1 2 3)) (+ x (env 1)))) (hi) (hi)) 6) (test (let ((env +) (x 0)) (define (hi) (do ((i 0 (+ i 3))) ((> i (env 4 5)) (env 1 2 3)) (+ x 1))) (hi) (hi)) 6) (test (let ((env +) (x 0)) (define (hi) (do ((i 0 (+ i 3))) ((> i 9) (env 1 2 3)) (+ x 1))) (hi) (hi)) 6) (test (let ((env +) (x 0)) (define (hi) (do ((i 0 (+ i 3))) ((> i 9) (+ 1 2 3)) (+ x 1))) (hi) (hi)) 6) (test (let * ((i 0)) (if (< i 1) (* (+ i 1))) i) 0) (test (let ((car if)) (car #t 0 1)) 0) (test (call-with-exit (lambda (abs) (abs -1))) -1) (test (let ((sqrt (lambda (a) (* a a)))) `(+ ,@(map sqrt '(1 4 9)) 2)) '(+ 1 16 81 2)) (test (let ((sqrt (lambda (a) (* a a)))) `(+ ,(sqrt 9) 4)) '(+ 81 4)) (test `(+ ,(let ((sqrt (lambda (a) (* a a)))) (sqrt 9)) 4) '(+ 81 4)) (test `(+ (let ((sqrt (lambda (a) (* a a)))) ,(sqrt 9)) 4) '(+ (let ((sqrt (lambda (a) (* a a)))) 3) 4)) (test (let ((sqrt (lambda (a) (* a a)))) `(+ ,(apply values (map sqrt '(1 4 9))) 2)) '(+ 1 16 81 2)) (if (not (provided? 'immutable-unquote)) (test (let ((sqrt (lambda (a) (* a a)))) `(+ (unquote (apply values (map sqrt '(1 4 9)))) 2)) '(+ 1 16 81 2))) (test ((((eval lambda) lcm gcd))) 0) (test ((((lambda - -) -) 0) 1) -1) (test (let () (define (hi) (let ((oscil >)) (or (< 3 2) (oscil 4 2)))) (hi) (hi)) #t) (test (let () (define (hi) (let ((oscil >)) (and (< 2 3) (oscil 4 2)))) (hi) (hi)) #t) (test ((lambda* ((- 0)) -) :- 1) 1) (let () (define-macro (i_ arg) `(with-let (unlet) ,arg)) (define-bacro* (mac b) `((i_ let) ((a 12)) ((i_ +) a ,(symbol->value b)))) ;; this assumes the 'b' value is a symbol: (let ((a 1)) (mac (* a 2))) is an error -- see s7.html for a better version (test (let ((a 32) (+ -)) (mac a)) 44)) ;(define (hi) (do ((i 0 (+ i 1))) ((= i 200000) i) (abs i))) ;(test (hi) 200000) (let () (define-macro (cube x) `(with-let (inlet :x ,x) (* x x x))) (test (cube 2) 8) (let ((x 2)) (test (cube (set! x (+ x 1))) 27)) (define-macro (pop! sym) `(with-let (#_inlet :e (#_curlet) :result (#_car ,sym)) (with-let e (#_set! ,sym (#_cdr ,sym))) result)) (test (let ((lst '(1 2 3))) (list (pop! lst) lst)) '(1 (2 3))) (test (let ((lst (vector (list 1 2 3)))) (list (pop! (lst 0)) lst)) '(1 #((2 3)))) (test (let ((result '(1 2 3))) (list (pop! result) result)) '(1 (2 3))) (test (let ((cdr '(1 2 3))) (list (pop! cdr) cdr)) '(1 (2 3))) (define-macro (pushnew! val lst) `(set! ,lst (with-let (inlet :val ,val :lst ,lst) (if (not (member val lst)) (cons val lst) lst)))) (test (let ((lst (list 1 2))) (pushnew! 3 lst)) '(3 1 2)) (test (let ((val (list 1 2)) (lst 3)) (pushnew! lst val)) '(3 1 2)) (test (let ((lst (list 1 2)) (val 3)) (pushnew! val lst)) '(3 1 2)) (test (let ((lst (list 1 2)) (member 3)) (pushnew! member lst)) '(3 1 2)) ) (test (let () (define-immaculo (hi a) `(let ((b 23)) (+ b ,a))) (let ((+ *) (b 12)) (hi b))) 35) (test (let () (define-clean-macro (hi a) `(+ ,a 1)) (let ((+ *) (a 12)) (hi a))) 13) (test (let () (define-immaculo (hi a) `(+ ,a 1)) (let ((+ *) (a 12)) (hi a))) 13) (test (let () (define-clean-macro (mac a . body) `(+ ,a ,@body)) (let ((a 2) (+ *)) (mac a (- 5 a) (* a 2)))) 9) (test (let () (define-macro (mac b) `(let ((a 12)) (,+ a ,b))) (let ((a 1) (+ *)) (mac a))) 24) (test (let () (define-macro (mac b) `(let ((a 12)) (+ a ,b))) (let ((a 1) (+ *)) (mac a))) 144) (test (let () (define-immaculo (mac c d) `(let ((a 12) (b 3)) (+ a b ,c ,d))) (let ((a 21) (b 10) (+ *)) (mac a b))) 46) (let () (define-macro (pure-let bindings . body) `(with-let (unlet) (let ,bindings ,@body))) (test (let ((+ *) (lambda abs)) (pure-let ((x 2)) ((lambda (y) (+ x y)) 3))) 5)) (test (let ((name '+)) (let ((+ *)) (eval (list name 2 3)))) 6) (test (let ((name +)) (let ((+ *)) (eval (list name 2 3)))) 5) ;; why is this considered confusing? It has nothing to do with eval! (test (let ((call/cc (lambda (x) (let ((c (call/cc x))) c)))) (call/cc (lambda (r) (r 1)))) 1) ; (test (with-let (sublet (curlet) (cons '+ (lambda args (apply * args)))) (+ 1 2 3 4)) 24) ; not sure about this -- the inner '+ might be optimized (let () (define-constant [begin] begin) (define-constant [if] if) (define-macro (when1 expr . body) `([if] ,expr ([begin] ,@body))) (let ((if 32) (begin +)) (test (when1 (> 2 1) 1 2 3) 3) (test (when1 (> 1 2) 3 4 5) #)) (test (when1 (> 2 1) 3) 3)) (test (let ((car 1) (cdr 2) (list '(1 2 3))) (+ car cdr (cadr list))) 5) (test (letrec ((null? (lambda (car cdr) (+ car cdr)))) (null? 1 2)) 3) (test (letrec ((append (lambda (car list) (car list)))) (append cadr '(1 2 3))) 2) (test (let () (define (hi) (let ((car 1) (cdr 2) (list '(1 2 3))) (+ car cdr (cadr list)))) (hi)) 5) (test (let () (define (hi) (letrec ((null? (lambda (car cdr) (+ car cdr)))) (null? 1 2))) (hi)) 3) (test (let () (define (hi) (letrec ((append (lambda (car list) (car list)))) (append cadr '(1 2 3)))) (hi)) 2) (let () (test ((lambda 'a (eval-string "1")) (curlet) 1) 1) (test ((lambda 'a (eval-string "a")) (curlet) 1) 1)) ;;; check optimizer (let ((lst (list 1 2 3)) (old-lambda lambda) (ho #f) (val #f)) (let* ((lambda 1)) (define (hi) (for-each (lambda (a) (display a)) lst)) (set! val (+ lambda 2)) (set! ho hi)) (test val 3) (test (ho) 'error)) (let () (define mac (let ((var (gensym))) (define-macro (mac-inner b) `(#_let ((,var 12)) (#_+ ,var ,b))) mac-inner)) (test (let ((a 1) (+ *) (let /)) (mac a)) 13) (test (let ((a 1) (+ *) (let /)) (mac (mac a))) 25)) (test (let ((begin +)) (with-let (unlet) (begin 1 2))) 2) (test (let () (define (f x) (let > (begin (vector-dimensions 22)))) (f 0)) 'error) (test (let () (define (f x) (let asd ())) (f 1)) 'error) (test (let () (define (f x) (hook *)) (f #f)) 'error) (test (let ((e (sublet () '(a . 1)))) (define (f x) (e *)) (f 1)) 'error) (test (let () (define (f) (eval (lambda 2.(hash-table-ref 1-)))) (f)) 'error) (test (let () (eval (lambda 2.(hash-table-ref 1-)))) 'error) (test (let () (define (f) (eval (lambda 2 #f))) (f)) 'error) (test (let () (define (f) (eval (lambda #f))) (f)) 'error) (test (let () (define (f) (eval (lambda))) (f)) 'error) (test (let () ((lambda () (eval (lambda 2 #f))))) 'error) (test (let () (define (f x) (help (lambda `(x 1) 12))) (f (string #\a))) 'error) (test (let () (define (func x) (* +(quote (vector? )))) (func '((x 1) (y) . 2))) 'error) (test (let () (define (func x) (* +(quote i))) (func cond)) 'error) (test (let ((i 1)) (define (func x) (begin i(let -))) (func macroexpand)) 'error) (test (let ((i 1)) (define (func x) (if (* i '((x 1) (y) . 2) ) (atan (procedure? 2(sin ))))) (func '(values #\c 3 1.2))) 'error) (test (let ((i 1)) (define (func x) (* 1- '(values #\c 3 1.2) )) (func set!)) 'error) (test (let ((dynamic-wind 1)) (+ dynamic-wind 2)) 3) #| ;;; after much dithering I've decided that built-in C functions have a very aggressive take ;;; on "lexical scope": if gcd appears as the car of an expression in a function, and ;;; at that point in the overall s7 process gcd has not been redefined, then the function ;;; can embed the actual gcd function in that part of its source (as if it was (#_gcd ...)). ;;; Hence a subsequent (set! gcd +) has no effect on any call that lexically (textually) ;;; preceded that set!. This is different from the handling of scheme-defined functions ;;; where (define (a) 0) (define (b) (a)) (define (c) 1) (set! a c) (b) -> 1. ;;; The decision as to when to replace the 'gcd with the gcd function is up to the optimizer, so ;;; consistency here is considered of no importance compared to speed -- either don't (set! gcd +) ;;; or do it before using gcd in any way. (test (let () (define (gset-test) (let ((old-gcd gcd) (sum 0) (x 12) (y 4)) (do ((i 0 (+ i 1))) ((= i 3)) (set! sum (+ sum (gcd x y))) (set! gcd +)) (set! gcd old-gcd) sum)) (define (gset-test-1) (gset-test)) (gset-test-1)) 36 or 12 -- who knows) (let () (define %gcd gcd) (define (gset-test-x) (let ((sum 0) (x 12) (y 4)) (do ((i 0 (+ i 1))) ((= i 3) sum) (set! sum (+ sum (%gcd x y)))))) (define (gset-test-1x) (gset-test-x)) (define (gset-test-a) (let ((sum 0) (x 12) (y 4)) (do ((i 0 (+ i 1))) ((= i 3) sum) (set! sum (+ sum (gcd x y)))))) (define (gset-test-1a) (gset-test-a)) (define (gset-test-b) (let ((sum 0) (x 12) (y 4)) (do ((i 0 (+ i 1))) ((= i 3) sum) (set! sum (+ sum (gcd x y))) (set! gcd +)))) (define (gset-test-1b) (gset-test-b)) (define (gset-test-c) (let ((sum 0) (x 12) (y 4)) (do ((i 0 (+ i 1))) ((= i 3) sum) (set! sum (+ sum (gcd x y)))))) (define (gset-test-1c) (gset-test-c)) (let* ((x (gset-test-1x)) (a (gset-test-1a)) (b (gset-test-1b)) (c (gset-test-1c)) (a (gset-test-1a))) (set! %gcd +) (let ((xx (gset-test-1x))) (display (list x a b c a xx)) (newline)))) ;;; s7: 12 12 12 12 12 12 12 ;;; guile: 12 12 36 48 48 12 48 |# (define-class quaternion () '((r 0) (i 0) (j 0) (k 0)) (list (list 'real-part (lambda (obj) (obj 'r))) (list 'imag-part (lambda (obj) (vector (obj 'i) (obj 'j) (obj 'k)))) (list 'number? (lambda (obj) #t)) (list 'complex? (lambda (obj) #f)) (list 'real? (lambda (obj) #f)) (list 'integer? (lambda (obj) #f)) (list 'rational? (lambda (obj) #f)) (list '+ (lambda orig-args (let add ((r ()) (i ()) (j ()) (k ()) (args orig-args)) (if (null? args) (make-quaternion (apply + r) (apply + i) (apply + j) (apply + k)) (let ((n (car args))) (cond ((real? n) (add (cons n r) i j k (cdr args))) ((complex? n) (add (cons (real-part n) r) (cons (imag-part n) i) j k (cdr args))) ((quaternion? n) (add (cons (n 'r) r) (cons (n 'i) i) (cons (n 'j) j) (cons (n 'k) k) (cdr args))) ((openlet? n) (if (eq? n (car orig-args)) (error 'missing-method "+ can't handle these arguments: ~A" args) (apply (n '+) (make-quaternion (apply + r) (apply + i) (apply + j) (apply + k)) (cdr args)))) ;; this code is trying to make sure we don't start bouncing: ;; if (+ q1 o1) goes to (o1 '+) which also can't handle this ;; combination, don't bounce back here! ;; In the current case, it would be (+ o1 q1) bouncing us here. ;; we're assuming (+ a b c) = (+ (+ a b) c), and that any other ;; + method will behave that way. I think the optimizer also ;; assumes that (+ a b) = (+ b a). (else (error 'wrong-type-arg "+ argument ~A is not a number" n)))))))) (list '- (lambda args (let ((first (car args))) (if (null? (cdr args)) ; (- q) is not the same as (- q 0) (make-quaternion (- (first 'r)) (- (first 'i)) (- (first 'j)) (- (first 'k))) (let ((q (cond ((real? first) (make-quaternion first 0 0 0)) ((complex? first) (make-quaternion (real-part first) (imag-part first) 0 0)) (else (copy first)))) (n (apply + (cdr args)))) (cond ((real? n) (set! (q 'r) (- (q 'r) n)) q) ((complex? n) (make-quaternion (- (q 'r) (real-part n)) (- (q 'i) (imag-part n)) (q 'j) (q 'k))) ((quaternion? n) (make-quaternion (- (q 'r) (n 'r)) (- (q 'i) (n 'i)) (- (q 'j) (n 'j)) (- (q 'k) (n 'k)))) (else (apply (n '-) (list q n))))))))) )) (let ((old-make-quaternion make-quaternion)) (varlet (outlet (curlet)) (cons 'make-quaternion (lambda args (let ((q (apply old-make-quaternion args))) (if (or (not (real? (q 'r))) (not (real? (q 'i))) (not (real? (q 'j))) (not (real? (q 'k)))) (error 'wrong-type-arg "quaternion fields should all be real: ~A" q) q)))))) (define-class float () '((x 0.0)) (list (list '+ (lambda orig-args (let add ((x ()) (args orig-args)) (if (null? args) (make-float (apply + x)) (let ((n (car args))) (cond ((float? n) (add (cons (n 'x) x) (cdr args))) ((real? n) (add (cons n x) (cdr args))) ((complex? n) (add (cons (real-part n) x) (cdr args))) ((openlet? n) (if (eq? n (car orig-args)) (error 'missing-method "+ can't handle these arguments: ~A" args) (apply (n '+) (make-float (apply + x)) (cdr args)))) (else (error 'wrong-type-arg "+ argument ~A is not a number" n)))))))) (list 'number? (lambda (obj) #t)))) (let ((q1 (make-quaternion 1.0 1.0 0.0 0.0))) (test (complex? q1) #f) (test (number? q1) #t) (test (quaternion? q1) #t) (test (quaternion? 1) #f) (test (quaternion? 1+i) #f) (test (integer? q1) #f) (test (real? q1) #f) (test (rational? q1) #f) (test (real-part q1) 1.0) (test (imag-part q1) #(1.0 0.0 0.0)) (test (eq? q1 q1) #t) (test (eqv? q1 q1) #t) (test (equal? q1 q1) #t) (let ((q2 (make-quaternion 1.0 1.0 0.0 0.0))) (test (eq? q1 q2) #f) (test (eqv? q1 q2) #f) (test (equal? q1 q2) #t) (set! (q2 'r) 2.0) (test (equal? q1 q2) #f) (test (+ q1) q1) (test (+ 1 q1) q2) (test (+ q1 1) q2) (test (+ 1/2 q1 1/2) q2) (test (+ .5 1/2 q1) q2) (test (+ 1+i q1 0-i) q2) (test (+ 1.0 q1) q2) (test (+ q1 1+i 0-i) q2) (test (+ 0+i q1 1 0-i) q2) (test (- q1) (make-quaternion -1.0 -1.0 0.0 0.0)) (test (- q1 1) (make-quaternion 0.0 1.0 0.0 0.0)) (test (- q1 1 0.0+i) (make-quaternion 0.0 0.0 0.0 0.0)) (test (- 1 q1) (make-quaternion 0.0 -1.0 0.0 0.0)) (test (+ (make-float 1.0) 1.0) (make-float 2.0)) (test (+ (make-quaternion 1 0 0 0) (make-float 1.0)) 'error) (test (+ (make-float 1.0) 2 (make-quaternion 1 1 1 1)) 'error) (test (+ 1 (make-float 1.0) 2 (make-quaternion 1 1 1 1)) 'error) (test (make-quaternion 1 2+i 0 0) 'error) (test (make-quaternion 1 2 3 "hi") 'error) (let () (define (a1 q) (+ q 1)) (test (a1 q1) (make-quaternion 2.0 1.0 0.0 0.0))) (let () (define (a1 q) (+ 1 q)) (test (a1 q1) (make-quaternion 2.0 1.0 0.0 0.0))) (let () (define (a1 q) (+ q q)) (test (a1 q1) (make-quaternion 2.0 2.0 0.0 0.0))) (let () (define (a1 q) (- q 1)) (test (a1 q1) (make-quaternion 0.0 1.0 0.0 0.0))) )) (if (not with-bignums) (let ((e1 (openlet (inlet 'x 3 '* (lambda args (if (number? (car args)) ; are we the first? (apply * (car args) ((cadr args) 'x) (cddr args)) (apply * ((car args) 'x) (cdr args)))))))) (let ((e2 (copy e1))) (set! (e2 'x) 4) (test (* 2 e1 e2 5) 120) (test (* e1 e2 5) 60) (test (* e1 e2) 12) (test (* e1) 3) (test (* 2 e1 e2) 24) (test (* 2 e1 4) 24) (test (* e1 2 e2 e1) 72)))) (let () (begin (define fvector? #f) (define make-fvector #f) (let ((type (gensym)) (->float (lambda (x) (if (real? x) (* x 1.0) (error 'wrong-type-arg "fvector new value is not a real: ~A" x))))) (set! make-fvector (lambda* (len (init 0.0)) (openlet (inlet 'v (make-vector len (->float init)) 'type type 'length (lambda (e) len) 'let-set! (lambda (fv i val) (#_vector-set! (fv 'v) i (->float val))) 'let-ref (lambda (fv i) (#_vector-ref (fv 'v) i)))))) (set! fvector? (lambda (p) (and (let? p) (eq? (p 'type) type)))))) (let ((f (make-fvector 10))) (test (fvector? f) #t) (test (length f) 10) (test (f 0) 0.0) (set! (f 1) 123) (test (f 1) 123.0))) (let () (define (baser-method func) (lambda largs (if (let? (car largs)) (apply func ((car largs) 'c) (cdr largs)) (if (let? (cadr largs)) (apply func (car largs) ((cadr largs) 'c) (cddr largs)) (if (let? (caddr largs)) (apply func (car largs) (cadr largs) ((caddr largs) 'c) (cdddr largs)) (apply func (car largs) (cadr largs) (caddr largs) ((cadddr largs) 'c) (cddddr largs))))))) (test (constant? (openlet (inlet 'c #f 'constant? (baser-method constant?)))) #t) (test (numerator (openlet (inlet 'c 1/9223372036854775807 'numerator (baser-method numerator)))) 1) (test (cdaadr (openlet (inlet 'c '((1 (2)) (((3) 4))) 'cdaadr (baser-method cdaadr)))) '(4)) (test (cadadr (openlet (inlet 'c '((1 2) (3 4)) 'cadadr (baser-method cadadr)))) 4) (test (caadar (openlet (inlet 'c '((1 (2)) (((3) 4))) 'caadar (baser-method caadar)))) 2) (test (caaadr (openlet (inlet 'c '((1 (2)) (((3) 4))) 'caaadr (baser-method caaadr)))) '(3)) (test (boolean? (openlet (inlet 'c #f 'boolean? (baser-method boolean?)))) #t) (test (number->string (openlet (inlet 'c 1/9223372036854775807 'number->string (baser-method number->string)))) "1/9223372036854775807") (test (lognot (openlet (inlet 'c '9223372036854775807 'lognot (baser-method lognot)))) -9223372036854775808) (unless pure-s7 (test (vector-length (openlet (inlet 'c #() 'vector-length (baser-method vector-length)))) 0)) (test (round (openlet (inlet 'c 1/9223372036854775807 'round (baser-method round)))) 0) (test (string-upcase (openlet (inlet 'c #u8(104 105 52 53 53) 'string-upcase (baser-method string-upcase)))) "HI455") (test (vector? (openlet (inlet 'c #() 'vector? (baser-method vector?)))) #t) (test (null? (openlet (inlet 'c () 'null? (baser-method null?)))) #t) (test (keyword? (openlet (inlet 'c ':key 'keyword? (baser-method keyword?)))) #t) (test (real? (openlet (inlet 'c 1/9223372036854775807 'real? (baser-method real?)))) #t) (test (length (openlet (inlet 'c () 'length (baser-method length)))) 0) (test (pair? (openlet (inlet 'c '(1) 'pair? (baser-method pair?)))) #t) (test (number? (openlet (inlet 'c 1/9223372036854775807 'number? (baser-method number?)))) #t) (test (odd? (openlet (inlet 'c '9223372036854775807 'odd? (baser-method odd?)))) #t) (test (symbol (openlet (inlet 'c #u8(104 105 52 53 53) 'symbol (baser-method symbol)))) 'hi455) (test (cdar (openlet (inlet 'c '((1 2)) 'cdar (baser-method cdar)))) '(2)) (test (even? (openlet (inlet 'c -9223372036854775808 'even? (baser-method even?)))) #t) (test (caar (openlet (inlet 'c '((1 2)) 'caar (baser-method caar)))) 1) (test (negative? (openlet (inlet 'c -1/9223372036854775807 'negative? (baser-method negative?)))) #t) (test (floor (openlet (inlet 'c 1/9223372036854775807 'floor (baser-method floor)))) 0) (test (positive? (openlet (inlet 'c 1/9223372036854775807 'positive? (baser-method positive?)))) #t) (test (string (openlet (inlet 'c #\a 'string (baser-method string)))) "a") (test (rational? (openlet (inlet 'c 1/9223372036854775807 'rational? (baser-method rational?)))) #t) (unless pure-s7 (test (string-copy (openlet (inlet 'c #u8(104 105 52 53 53) 'string-copy (baser-method string-copy)))) "hi455")) (test (make-keyword (openlet (inlet 'c #u8(104 105 52 53 53) 'make-keyword (baser-method make-keyword)))) :hi455) (test (inexact? (openlet (inlet 'c 1.5+1i 'inexact? (baser-method inexact?)))) #t) (test (char? (openlet (inlet 'c #\a 'char? (baser-method char?)))) #t) (test (exact? (openlet (inlet 'c 1/9223372036854775807 'exact? (baser-method exact?)))) #t) (test (format (openlet (inlet 'c #u8(104 105 52 53 53) 'format (baser-method format)))) "hi455") (test (cadar (openlet (inlet 'c '((1 2)) 'cadar (baser-method cadar)))) '2) (test (char-lower-case? (openlet (inlet 'c #\a 'char-lower-case? (baser-method char-lower-case?)))) #t) (test (char-upcase (openlet (inlet 'c #\a 'char-upcase (baser-method char-upcase)))) #\A) (test (byte-vector? (openlet (inlet 'c #u8(104 105 52 53 53) 'byte-vector? (baser-method byte-vector?)))) #t) (unless pure-s7 (test (string->list (openlet (inlet 'c #u8(104 105 52 53 53) 'string->list (baser-method string->list)))) '(#\h #\i #\4 #\5 #\5))) (test (denominator (openlet (inlet 'c 1/9223372036854775807 'denominator (baser-method denominator)))) 9223372036854775807) (test (integer-length (openlet (inlet 'c '9223372036854775807 'integer-length (baser-method integer-length)))) 63) (test (integer? (openlet (inlet 'c '9223372036854775807 'integer? (baser-method integer?)))) #t) (test (char->integer (openlet (inlet 'c #\a 'char->integer (baser-method char->integer)))) 97) (test (min (openlet (inlet 'c 1/9223372036854775807 'real? (lambda (obj) (#_real? (obj 'c))) 'min (baser-method min)))) 1/9223372036854775807) (test (ceiling (openlet (inlet 'c 1/9223372036854775807 'ceiling (baser-method ceiling)))) 1) (test (max (openlet (inlet 'c 1/9223372036854775807 'real? (lambda (obj) (#_real? (obj 'c))) 'max (baser-method max)))) 1/9223372036854775807) (test (car (openlet (inlet 'c '(1) 'car (baser-method car)))) 1) (test (char-alphabetic? (openlet (inlet 'c #\a 'char-alphabetic? (baser-method char-alphabetic?)))) #t) (test (modulo 1/9223372036854775807 (openlet (inlet 'c 1/9223372036854775807 'modulo (baser-method modulo)))) 0) (test (substring #u8(104 105 52 53 53) (openlet (inlet 'c '0 'substring (baser-method substring)))) "hi455") (test (char-position #\a (openlet (inlet 'c #u8(97 0 98) 'char-position (baser-method char-position)))) 0) (test (assv 1 (openlet (inlet 'c '((1 2)) 'assv (baser-method assv)))) '(1 2)) (test (assq 1 (openlet (inlet 'c '((1 2)) 'assq (baser-method assq)))) '(1 2)) (test (rationalize 1/9223372036854775807 (openlet (inlet 'c 1/9223372036854775807 'rationalize (baser-method rationalize)))) 0) (test (make-shared-vector #(1 2) (openlet (inlet 'c '(1) 'make-shared-vector (baser-method make-shared-vector)))) #(1)) (test (string>=? #u8(52 53 104 105 53) (openlet (inlet 'c #u8(52 53 104 105 53) 'string>=? (baser-method string>=?)))) #t) (test (string<=? #u8(52 53 104 105 53) (openlet (inlet 'c #u8(52 53 104 105 53) 'string<=? (baser-method string<=?)))) #t) (test (fill! #u8(97 97 97 97 97) (openlet (inlet 'c 120 'fill! (baser-method fill!)))) 120) (test (string #\a (openlet (inlet 'c #\a 'string (baser-method string)))) "aa") (test (logbit? 9223372036854775807 (openlet (inlet 'c '0 'logbit? (baser-method logbit?)))) #t) (test (remainder 1/9223372036854775807 (openlet (inlet 'c 1/9223372036854775807 'remainder (baser-method remainder)))) 0) (if (not pure-s7) (test (string-ci>? #u8(0 0 0 0 0) (openlet (inlet 'c #u8(0) 'string-ci>? (baser-method string-ci>?)))) #t)) (if (not pure-s7) (test (string-ci=? #u8(0 0 0 0 0) (openlet (inlet 'c #u8(0 0 0 0 0) 'string-ci=? (baser-method string-ci=?)))) #t)) (test (string-ref #u8(0 0 0 0 0) (openlet (inlet 'c '0 'string-ref (baser-method string-ref)))) #\null) (test (string-position #u8(0 0 0 0 0) (openlet (inlet 'c #u8(0 0 0 0 0) 'string-position (baser-method string-position)))) 0) (test (string>? #u8(0 0 0 0 0) (openlet (inlet 'c #u8(0) 'string>? (baser-method string>?)))) #t) (test (string>=? #u8(52 53 104 105 53) #u8(52 53 104 105 53) (openlet (inlet 'c #u8(52 53 104 105 53) 'string>=? (baser-method string>=?)))) #t) (when (not with-bignums) (test (logxor (openlet (inlet 'c '9223372036854775807 'logxor (baser-method logxor)))) 9223372036854775807) (test (> 1/9223372036854775807 (openlet (inlet 'c -1/9223372036854775807 '> (baser-method >)))) #t) (test (= 1/9223372036854775807 (openlet (inlet 'c 1/9223372036854775807 '= (baser-method =)))) #t) (test (< 1/9223372036854775807 (openlet (inlet 'c 1e+18 '< (baser-method <)))) #t) (test (/ 1/9223372036854775807 (openlet (inlet 'c 1/9223372036854775807 '/ (baser-method /)))) 1) (test (- 1/9223372036854775807 (openlet (inlet 'c 1/9223372036854775807 '- (baser-method -)))) 0) (test (+ 1/9223372036854775807 (openlet (inlet 'c 1/9223372036854775807 '+ (baser-method +)))) 2/9223372036854775807) (test (> 1/9223372036854775807 -1/9223372036854775807 (openlet (inlet 'c -9223372036854775808 '> (baser-method >)))) #t) (test (= 1/9223372036854775807 1/9223372036854775807 (openlet (inlet 'c 1/9223372036854775807 '= (baser-method =)))) #t) (test (+ -1 (openlet (inlet 'c -1 '+ (baser-method +)))) -2) (test (- -1 (openlet (inlet 'c -1 '- (baser-method -)))) 0) (test (* (openlet (inlet 'c 2.0 '* (baser-method *))) 2.0) 4.0) (test (let ((x (openlet (inlet 'c -1 '- (baser-method -))))) (- x 1)) -2) (test (let ((x (openlet (inlet 'c 1.0 '- (baser-method -))))) (- 1.0 x)) 0.0) (test (* 3.0 (openlet (inlet 'c 2.0 '* (baser-method *))) 2.0) 12.0)) (test (symbol->string (openlet (inlet 'c 'a 'symbol->string (baser-method symbol->string)))) "a") (test (let? (outlet (openlet (inlet 'c (curlet) 'outlet (baser-method outlet)))) ) #t) (test (c-pointer? (c-pointer (openlet (inlet 'c 0 'c-pointer (baser-method c-pointer))))) #t)) (let ((e (openlet (inlet 'x (list 1 2 3) 'make-iterator (let ((iterator? #t)) (lambda (y) (#_make-iterator (y 'x)))))))) (test (map (lambda (z) (+ z 1)) e) '(2 3 4))) (let () (require mockery.scm) (let ((v ((*mock-vector* 'make-mock-vector) 10 0))) (test (vector? v) #t) (let ((old-vpl (*s7* 'print-length))) (set! (*s7* 'print-length) 32) (test (object->string v) "#(0 0 0 0 0 0 0 0 0 0)") (set! (*s7* 'print-length) old-vpl)) (test (length v) 10) (test (vector-length v) 10) (test (vector-dimensions v) '(10)) (test (vector-set! v 0 1) 1) (test (vector-ref v 0) 1) (test (v 0) 1) (test (set! (v 1) 2) 2) (test (v 1) 2) (fill! v 0) (test (v 'value) #(0 0 0 0 0 0 0 0 0 0)) (test (morally-equal? v #(0 0 0 0 0 0 0 0 0 0)) #t) (test (morally-equal? #(0 0 0 0 0 0 0 0 0 0) v) #t) (test (morally-equal? v ((*mock-vector* 'make-mock-vector) 10 0)) #t) (unless pure-s7 (vector-fill! v 3 1 4)) (unless pure-s7 (test (v 'value) #(0 3 3 3 0 0 0 0 0 0))) (unless pure-s7 (test (vector->list v) '(0 3 3 3 0 0 0 0 0 0))) (unless pure-s7 (test (map (lambda (a) (+ a 1)) v) '(1 4 4 4 1 1 1 1 1 1))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (v i) i)) (test (v 'value) #(0 1 2 3 4 5 6 7 8 9)) (for-each (lambda (x) (test (integer? x) #t)) v) (let ((v1 (make-shared-vector v '(3) 2))) (test v1 #(2 3 4))) (sort! v >) (test (v 'value) #(9 8 7 6 5 4 3 2 1 0)) (test (reverse v) #(0 1 2 3 4 5 6 7 8 9)) (test (let* ((y (list 1)) (x ((*mock-vector* 'mock-vector) y))) (set! (y 0) x) (null? (cyclic-sequences x))) #f) (let ((v1 ((*mock-vector* 'make-mock-vector) 10 1))) (let ((v2 (copy v1))) (set! (v1 3) 32) (test (or (eq? (v1 'value) (v2 'value)) (equal? (v1 'value) (v2 'value))) #f))) #| (let ((v1 #(1 2 3)) (v2 ((*mock-vector* 'make-mock-vector) 2 4))) (test (vector-append v1 v2) #(1 2 3 4 4)) (test (vector-append v2 v1) #(4 4 1 2 3)) (test (vector-append v1 v1 v2) #(1 2 3 1 2 3 4 4)) (test (vector-append v2 v2 v1) #(4 4 4 4 1 2 3))) |# (let ((v1 ((*mock-vector* 'mock-vector) 0 1 2 3 4))) (test (subsequence v1 0 2) #(0 1)))) (let () (define (vset v i j k) (let ((x 3.0)) (vector-set! v 0 x) (vector-set! v j (vector-ref v i)) (vector-set! v i (+ (vector-ref v j) x)) (vector-set! v k x))) (let ((v (vector 1 2 0)) (i 0) (j 1) (k 2)) (vset v i j k) (test (morally-equal? v #(6.0 3.0 3.0)) #t)) (let ((v ((*mock-vector* 'mock-vector) 1 2 0)) (i 0) (j 1) (k 2)) (vset v i j k) (test (morally-equal? v #(6.0 3.0 3.0)) #t)) (let ((v (vector 1 2 0)) (i ((*mock-number* 'mock-number) 0)) (j ((*mock-number* 'mock-number) 1)) (k ((*mock-number* 'mock-number) 2))) (vset v i j k) (test (morally-equal? v #(6.0 3.0 3.0)) #t)) (let ((v ((*mock-vector* 'mock-vector) 1 2 0)) (i ((*mock-number* 'mock-number) 0)) (j ((*mock-number* 'mock-number) 1)) (k ((*mock-number* 'mock-number) 2))) (vset v i j k) (test (morally-equal? v #(6.0 3.0 3.0)) #t)) (let ((v (vector 1 2 0)) (i 0) (j ((*mock-number* 'mock-number) 1)) (k 2)) (vset v i j k) (test (morally-equal? v #(6.0 3.0 3.0)) #t))) (num-test (+ ((*mock-number* 'mock-number) 1) ((*mock-number* 'mock-number) 2)) 3) (num-test (log ((*mock-number* 'mock-number) 2) ((*mock-number* 'mock-number) 2)) 1) (num-test (/ ((*mock-number* 'mock-number) 0) 1) 0) (num-test (/ ((*mock-number* 'mock-number) 0) ((*mock-number* 'mock-number) 1-i) ((*mock-number* 'mock-number) 3/4)) 0.0) (test (make-float-vector 0 ((*mock-number* 'mock-number) 3)) #()) (test (= ((*mock-number* 'mock-number) 0) ((*mock-number* 'mock-number) 0) ((*mock-number* 'mock-number) 0)) #t) (test (= ((*mock-number* 'mock-number) 0) ((*mock-number* 'mock-number) 0) #\a) 'error) (test (nan? (/ 0 1-1i inf.0 nan.0)) #t) (test (nan? (/ ((*mock-number* 'mock-number) 0) ((*mock-number* 'mock-number) 1-1i) ((*mock-number* 'mock-number) inf.0) ((*mock-number* 'mock-number) nan.0))) #t) (test (/ 0 0.0) 'error) (test (/ ((*mock-number* 'mock-number) 0) ((*mock-number* 'mock-number) 0.0)) 'error) (test (/ 0.0 0) 'error) (test (/ ((*mock-number* 'mock-number) 0.0) ((*mock-number* 'mock-number) 0)) 'error) (test (/ 2.0 inf.0 1-1i 0.0) 'error) (test (/ ((*mock-number* 'mock-number) 2.0) ((*mock-number* 'mock-number) inf.0) ((*mock-number* 'mock-number) 1-1i) ((*mock-number* 'mock-number) 0.0)) 'error) (test (length (append '(1) ((*mock-number* 'mock-number) 1))) -1) (test (number? (append ((*mock-number* 'mock-number) 1))) #t) ; (test (append ((*mock-number* 'mock-number) 1) ()) 'error) (test (string=? "hi" ((*mock-string* 'mock-string) "hi") ((*mock-string* 'mock-string) "hi")) #t) (test (string=? "hi" ((*mock-string* 'mock-string) "hi") ((*mock-string* 'mock-string) "ho")) #f) (test (string=? "hi" ((*mock-string* 'mock-string) "hi") ((*mock-string* 'mock-string) "hi") "hi") #t) (test (string=? ((*mock-string* 'mock-string) "hi") ((*mock-string* 'mock-string) "hi") "hi") #t) (test (string=? ((*mock-string* 'mock-string) "hi") ((*mock-string* 'mock-string) "hi") ((*mock-string* 'mock-string) "hi")) #t) (test (string<=? ((*mock-string* 'mock-string) "hi") ((*mock-string* 'mock-string) "hi") ((*mock-string* 'mock-string) "hi")) #t) (test (string>=? ((*mock-string* 'mock-string) "hi") ((*mock-string* 'mock-string) "hi") ((*mock-string* 'mock-string) "hi")) #t) (test (string>=? ((*mock-string* 'mock-string) "hi") ((*mock-string* 'mock-string) "hi") ((*mock-string* 'mock-string) "hj")) #f) (test (string>=? ((*mock-string* 'mock-string) "hi") ((*mock-string* 'mock-string) "hi") ((*mock-string* 'mock-string) "hj") 1) 'error) (test (string>=? ((*mock-string* 'mock-string) "hi") ((*mock-string* 'mock-string) "hi") ((*mock-string* 'mock-string) "hj") ((*mock-number* 'mock-number) 1)) 'error) (test (string? ((*mock-string* 'mock-string) "hi") ((*mock-string* 'mock-string) "hi") ((*mock-string* 'mock-string) "hi")) #f) (test (string? ((*mock-string* 'mock-string) "hihi") ((*mock-string* 'mock-string) "hih") ((*mock-string* 'mock-string) "hi")) #t) (test (string>? ((*mock-string* 'mock-string) "hihi") ((*mock-string* 'mock-string) "hih") ((*mock-string* 'mock-string) "hih")) #f) (test (string>? ((*mock-string* 'mock-string) "hihi") ((*mock-string* 'mock-string) "hih") ((*mock-string* 'mock-string) "hih") #\a) 'error) (test (string>? ((*mock-string* 'mock-string) "hihi") ((*mock-string* 'mock-string) "hih") ((*mock-string* 'mock-string) "hih") ((*mock-number* 'mock-number) 1)) 'error) (test (char=? #\i ((*mock-char* 'mock-char) #\i) ((*mock-char* 'mock-char) #\i)) #t) (test (char=? #\i ((*mock-char* 'mock-char) #\i) ((*mock-char* 'mock-char) #\k)) #f) (test (char=? #\i ((*mock-char* 'mock-char) #\i) ((*mock-char* 'mock-char) #\i) #\i) #t) (test (char=? ((*mock-char* 'mock-char) #\i) ((*mock-char* 'mock-char) #\i) #\i) #t) (test (char=? ((*mock-char* 'mock-char) #\i) ((*mock-char* 'mock-char) #\i) ((*mock-char* 'mock-char) #\i)) #t) (test (char<=? ((*mock-char* 'mock-char) #\i) ((*mock-char* 'mock-char) #\i) ((*mock-char* 'mock-char) #\i)) #t) (test (char>=? ((*mock-char* 'mock-char) #\i) ((*mock-char* 'mock-char) #\i) ((*mock-char* 'mock-char) #\i)) #t) (test (char>=? ((*mock-char* 'mock-char) #\i) ((*mock-char* 'mock-char) #\i) ((*mock-char* 'mock-char) #\j)) #f) (test (char>=? ((*mock-char* 'mock-char) #\i) ((*mock-char* 'mock-char) #\i) ((*mock-char* 'mock-char) #\j) 1) 'error) (test (char>=? ((*mock-char* 'mock-char) #\i) ((*mock-char* 'mock-char) #\i) ((*mock-char* 'mock-char) #\j) ((*mock-number* 'mock-number) 1)) 'error) (test (char? ((*mock-char* 'mock-char) #\i) ((*mock-char* 'mock-char) #\i) ((*mock-char* 'mock-char) #\i)) #f) (test (char? ((*mock-char* 'mock-char) #\p) ((*mock-char* 'mock-char) #\m) ((*mock-char* 'mock-char) #\i)) #t) (test (char>? ((*mock-char* 'mock-char) #\p) ((*mock-char* 'mock-char) #\m) ((*mock-char* 'mock-char) #\m)) #f) (test (char>? ((*mock-char* 'mock-char) #\p) ((*mock-char* 'mock-char) #\m) ((*mock-char* 'mock-char) #\m) "a") 'error) (test (char>? ((*mock-char* 'mock-char) #\p) ((*mock-char* 'mock-char) #\m) ((*mock-char* 'mock-char) #\m) ((*mock-number* 'mock-number) 1)) 'error) (test (string-ci=? "hi" ((*mock-string* 'mock-string) "HI") ((*mock-string* 'mock-string) "hi")) #t) (test (string-ci=? "hi" ((*mock-string* 'mock-string) "hi") ((*mock-string* 'mock-string) "ho")) #f) (test (string-ci=? "hi" ((*mock-string* 'mock-string) "hi") ((*mock-string* 'mock-string) "hi") "HI") #t) (test (string-ci=? ((*mock-string* 'mock-string) "HI") ((*mock-string* 'mock-string) "hi") "hi") #t) (test (string-ci=? ((*mock-string* 'mock-string) "hi") ((*mock-string* 'mock-string) "HI") ((*mock-string* 'mock-string) "hi")) #t) (test (string-ci<=? ((*mock-string* 'mock-string) "hi") ((*mock-string* 'mock-string) "hi") ((*mock-string* 'mock-string) "hi")) #t) (test (string-ci>=? ((*mock-string* 'mock-string) "HI") ((*mock-string* 'mock-string) "hi") ((*mock-string* 'mock-string) "hi")) #t) (test (string-ci>=? ((*mock-string* 'mock-string) "hi") ((*mock-string* 'mock-string) "hi") ((*mock-string* 'mock-string) "hj")) #f) (test (string-ci>=? ((*mock-string* 'mock-string) "hi") ((*mock-string* 'mock-string) "hi") ((*mock-string* 'mock-string) "hj") 1) 'error) (test (string-ci>=? ((*mock-string* 'mock-string) "hi") ((*mock-string* 'mock-string) "HI") ((*mock-string* 'mock-string) "hj") ((*mock-number* 'mock-number) 1)) 'error) (test (string-ci? ((*mock-string* 'mock-string) "hi") ((*mock-string* 'mock-string) "hi") ((*mock-string* 'mock-string) "HI")) #f) (test (string-ci? ((*mock-string* 'mock-string) "hihi") ((*mock-string* 'mock-string) "hih") ((*mock-string* 'mock-string) "HI")) #t) (test (string-ci>? ((*mock-string* 'mock-string) "HIHI") ((*mock-string* 'mock-string) "hih") ((*mock-string* 'mock-string) "hih")) #f) (test (string-ci>? ((*mock-string* 'mock-string) "hihi") ((*mock-string* 'mock-string) "HIH") ((*mock-string* 'mock-string) "hih") #\a) 'error) (test (string-ci>? ((*mock-string* 'mock-string) "hihi") ((*mock-string* 'mock-string) "hih") ((*mock-string* 'mock-string) "HIH") ((*mock-number* 'mock-number) 1)) 'error) (test (char-ci=? #\i ((*mock-char* 'mock-char) #\i) ((*mock-char* 'mock-char) #\I)) #t) (test (char-ci=? #\i ((*mock-char* 'mock-char) #\i) ((*mock-char* 'mock-char) #\k)) #f) (test (char-ci=? #\I ((*mock-char* 'mock-char) #\i) ((*mock-char* 'mock-char) #\i) #\i) #t) (test (char-ci=? ((*mock-char* 'mock-char) #\I) ((*mock-char* 'mock-char) #\i) #\i) #t) (test (char-ci=? ((*mock-char* 'mock-char) #\i) ((*mock-char* 'mock-char) #\I) ((*mock-char* 'mock-char) #\i)) #t) (test (char-ci<=? ((*mock-char* 'mock-char) #\I) ((*mock-char* 'mock-char) #\i) ((*mock-char* 'mock-char) #\i)) #t) (test (char-ci>=? ((*mock-char* 'mock-char) #\i) ((*mock-char* 'mock-char) #\I) ((*mock-char* 'mock-char) #\i)) #t) (test (char-ci>=? ((*mock-char* 'mock-char) #\I) ((*mock-char* 'mock-char) #\i) ((*mock-char* 'mock-char) #\j)) #f) (test (char-ci>=? ((*mock-char* 'mock-char) #\i) ((*mock-char* 'mock-char) #\i) ((*mock-char* 'mock-char) #\J) 1) 'error) (test (char-ci>=? ((*mock-char* 'mock-char) #\i) ((*mock-char* 'mock-char) #\I) ((*mock-char* 'mock-char) #\J) ((*mock-number* 'mock-number) 1)) 'error) (test (char-ci? ((*mock-char* 'mock-char) #\i) ((*mock-char* 'mock-char) #\I) ((*mock-char* 'mock-char) #\i)) #f) (test (char-ci? ((*mock-char* 'mock-char) #\P) ((*mock-char* 'mock-char) #\m) ((*mock-char* 'mock-char) #\i)) #t) (test (char-ci>? ((*mock-char* 'mock-char) #\p) ((*mock-char* 'mock-char) #\M) ((*mock-char* 'mock-char) #\m)) #f) (test (char-ci>? ((*mock-char* 'mock-char) #\p) ((*mock-char* 'mock-char) #\m) ((*mock-char* 'mock-char) #\M) "a") 'error) (test (char-ci>? ((*mock-char* 'mock-char) #\p) ((*mock-char* 'mock-char) #\m) ((*mock-char* 'mock-char) #\m) ((*mock-number* 'mock-number) 1)) 'error) (let ((v (make-vector 3 1.0 (openlet (inlet 'c #t 'make-vector (lambda args (make-vector (car args) (cadr args) ((caddr args) 'c)))))))) (test (float-vector? v) #t)) (test (rationalize ((*mock-number* 'mock-number) 2.5) (openlet (inlet 'c 1/100 'rationalize (make-method #_rationalize (lambda (obj) (obj 'c)))))) 5/2) (test (autoload 'asdf (openlet (inlet 'c "asdf" 'autoload (make-method #_autoload (lambda (obj) (obj 'c)))))) "asdf") (define stretchable-vector-class (let ((local-ref (lambda (obj index) (if (>= index (length (obj 'value))) (obj 'initial-element) (#_vector-ref (obj 'value) index)))) (local-set! (lambda (obj index val) (if (>= index (length (obj 'value))) (set! (obj 'value) (copy (obj 'value) (make-vector (+ index 8) (obj 'initial-element))))) (#_vector-set! (obj 'value) index val)))) (openlet (sublet (*mock-vector* 'mock-vector-class) 'value (vector) 'object->string (lambda* (obj (w #t)) (format #f "#" (obj 'value))) 'initial-element #f 'vector-ref local-ref 'let-ref local-ref 'vector-set! local-set! 'let-set! local-set!)))) (let ((v1 (copy stretchable-vector-class)) (ind 12)) (test (vector-length v1) 0) (test ((*mock-vector* 'mock-vector?) v1) #t) (test (v1 123) #f) (test (vector-length v1) 0) (test (object->string v1) "#") (set! (v1 ind) 32) (test (v1 ind) 32) (test (length v1) 20) (test (v1 11) #f)) (let ((ht ((*mock-hash-table* 'mock-hash-table*) 'a 1 'b 2))) (test (ht 'a) 1) (test (hash-table? ht) #t) (test ((*mock-hash-table* 'mock-hash-table?) ht) #t) (test (vector? ht) #f) (test (morally-equal? ht (hash-table* 'a 1 'b 2)) #t) (test (hash-table-ref ht 'b) 2) (hash-table-set! ht 'c 3) (test (ht 'c) 3) (test (ht 'd) #f) (set! (ht 'c) 32) (test (hash-table-ref ht 'c) 32) (test (length ht) (*s7* 'default-hash-table-length)) (test (hash-table-entries ht) 3) (let ((ht1 (copy ht))) (test (hash-table-ref ht1 'b) 2) (test (hash-table-entries ht1) 3)) (let ((hti (make-iterator ht))) (for-each (lambda (x) (if (not (equal? x (hti))) (format *stderr* "hti not ~A~%" x))) ht)) (fill! ht ()) (test (hash-table-entries ht) 3)) (unless pure-s7 (test (let ((e (openlet (inlet 'fill! (lambda (obj val) (string-fill! (obj 'value) val)) 'value "01234")))) (vector-fill! e #\a) (e 'value)) 'error)) (test (let ((e (openlet (inlet 'call/cc (lambda (obj) 32))))) (call/cc e)) 32) (test (let ((e (openlet (inlet 'call-with-current-continuation (lambda (obj) 32))))) (call/cc e)) 32) (define gloomy-hash-table (openlet (sublet (*mock-hash-table* 'mock-hash-table-class) 'mock-hash-table-table #f 'false (gensym) 'not-a-key #f 'hash-table-ref (lambda (obj key) (let ((val (#_hash-table-ref (obj 'mock-hash-table-table) key))) (if (eq? val (obj 'false)) #f (or val (obj 'not-a-key))))) 'hash-table-key? (lambda (obj key) (#_hash-table-ref (obj 'mock-hash-table-table) key))))) (define* (make-gloomy-hash-table (len 511) not-a-key) (let ((ht (copy gloomy-hash-table))) (set! (ht 'mock-hash-table-table) (make-hash-table len)) (set! (ht 'not-a-key) not-a-key) ht)) (define (hash-table-key? obj key) ((obj 'hash-table-key?) obj key)) (let ((ht (make-gloomy-hash-table :not-a-key 'nope))) (test (hash-table-key? ht 'a) #f) (test (hash-table-ref ht 'a) 'nope) (hash-table-set! ht 'a 1) (test (not (hash-table-key? ht 'a)) #f) (test (ht 'a) 1)) (let ((s ((*mock-string* 'mock-string) #\a #\b #\c))) (test (length s) 3) (test (string-length s) 3) (test (string? s) #t) (test (morally-equal? s "abc") #t) (test ((*mock-string* 'mock-string?) s) #t) (test ((*mock-vector* 'mock-vector?) s) #f) (test (string-ref s 0) #\a) (test (string-set! s 0 #\A) #\A) (test (s 0) #\A) (test (set! (s 1) #\B) #\B) (test (s 1) #\B) (test (string->list s) '(#\A #\B #\c)) (test (string-append s "d") "ABcd") (test (string-append "d" s "e") "dABce") (test (string-append "d" "f" s) "dfABc") (test (string-append "d" "f" s "gh") "dfABcgh") (test (reverse s) "cBA") (test (copy s) "ABc") (test (string-copy s) "ABc") (test (object->string s) "\"ABc\"") (test (string=? s "ABc") #t) (test (string=? "ABc" s) #t) (test (string=? s "ABC") #f) (test (substring s 0 1) "A") (test (string-downcase s) "abc") (test (string-upcase s) "ABC") (test (string->symbol s) 'ABc) (test (gensym? (gensym s)) #t) (test (make-keyword s) :ABc) (test (map values s) '(#\A #\B #\c)) (test (string>? s "ABC") #t) (test (string-ci>? s "ABC") #f) (test (string=? s "ABC") #t) (test (string-ci>=? s "ABC") #t) (test (string<=? s "ABC") #f) (test (string-ci<=? s "ABC") #t) (test (call-with-input-string s read) 'ABc) (test (with-input-from-string s read) 'ABc) (test (let ((p (open-input-string s))) (let ((r (read p))) (close-input-port p) r)) 'ABc) (string-fill! s #\1) (test (s 0) #\1) (test (string->number s) 111) (fill! s #\2) (test (s 1) #\2) (for-each (lambda (c) (if (not (char=? c #\2)) (format *stderr* ";fill! mock-string: ~C~%" c))) s) (test (format #f s) "222") (test (format #f "~A" s) "222") (test (format s) "222") (test (eval-string s) 222) (test (string-position "2" s) 0) (test (->byte-vector s) #u8(50 50 50))) (let ((c ((*mock-char* 'mock-char) #\a))) (test (char? c) #t) (test ((*mock-char* 'mock-char?) c) #t) (test (morally-equal? c #\a) #t) (test (char-upcase c) #\A) (test (char-downcase c) #\a) (test (char->integer c) 97) (test (char-upper-case? c) #f) (test (char-lower-case? c) #t) (test (char-alphabetic? c) #t) (test (char-numeric? c) #f) (test (char-whitespace? c) #f) (test (char=? c #\A) #f) (test (char=? c #\a) #t) (test (char? c #\b) #f) (test (char>=? c #\b) #f) (test (char-ci=? c #\A) #t) (test (char-ci=? c #\a) #t) (test (char-ci? c #\b) #f) (test (char-ci>=? c #\b) #f) (test (char-position c "abc") 0) (test (char-position ((*mock-char* 'mock-char) #\b) "hoho" 63) #f) (test (char-position #\null "hoho" ((*mock-char* 'mock-char) #\b)) 'error) (test (char-position ((*mock-char* 'mock-char) #\null) "hoho" ((*mock-char* 'mock-char) #\b)) 'error) (test (object->string c #f) "a") (test (copy c) #\a) (test (string c #\b) "ab") (test (string #\c c) "ca") (test (string #\a c c #\b) "aaab") (test (format #f "~C" c) (format #f "~C" (c 'value))) (let ((str "0123")) (string-set! str 1 c) (test str "0a23")) ) (let ((mock-number (*mock-number* 'mock-number)) (mock-number? (*mock-number* 'mock-number?))) (let ((i (mock-number 32)) (x (mock-number pi)) (z (mock-number 1+i)) (r (mock-number 3/2))) (let ((nums (list i r x z)) (rnums (list i r x))) (define (practically-equal? tst l1 l2) (call-with-exit (lambda (quit) (for-each (lambda (n1 n2) (when (not (number-ok? tst n1 n2)) (format *stderr* ";~S: ~A ~A~%" tst n1 n2) (quit #f))) l1 l2) #t))) (test (map mock-number? nums) '(#t #t #t #t)) (test (morally-equal? i 32) #t) (if with-bignums (test (map object->string nums) '("32" "3/2" "3.141592653589793238462643383279502884195E0" "1+1i")) (test (map object->string nums) '("32" "3/2" "3.141592653589793" "1+1i"))) (test (map copy nums) (list 32 3/2 pi 1+1i)) (test (practically-equal? 'real-part (map real-part nums) (list 32 3/2 pi 1.0)) #t) (test (map imag-part nums) '(0 0 0.0 1.0)) (test (numerator i) 32) (test (numerator r) 3) (test (denominator i) 1) (test (denominator r) 2) (test (even? i) #t) (test (odd? i) #f) (test (map zero? nums) '(#f #f #f #f)) (test (map positive? rnums) '(#t #t #t)) (test (map negative? rnums) '(#f #f #f)) (test (map infinite? nums) '(#f #f #f #f)) (test (map nan? nums) '(#f #f #f #f)) (num-test (make-polar i r) (make-polar 32 3/2)) (num-test (make-polar x i) (make-polar pi 32)) (num-test (complex i r) (complex 32 3/2)) (test (practically-equal? 'magnitude (map magnitude nums) (list 32 3/2 pi (sqrt 2))) #t) (test (practically-equal? 'angle (map angle nums) '(0 0 0.0 0.7853981633974483)) #t) (num-test (rationalize x) (rationalize pi)) (test (practically-equal? 'abs (map abs rnums) '(32 3/2 3.141592653589793)) #t) (test (practically-equal? 'exp (map exp nums) '(78962960182680.69 4.481689070338065 23.14069263277927 1.468693939915885+2.287355287178842i)) #t) (test (practically-equal? 'log (map log nums) '(3.465735902799727 0.4054651081081644 1.1447298858494 0.3465735902799727+0.7853981633974483i)) #t) (test (practically-equal? 'sin (map sin nums) '(0.5514266812416906 0.9974949866040544 1.224646799147353e-16 1.298457581415977+0.6349639147847361i)) #t) (test (practically-equal? 'cos (map cos nums) '(0.8342233605065102 0.07073720166770291 -1.0 0.8337300251311491-0.9888977057628651i)) #t) (test (practically-equal? 'tan (map tan nums) '(0.6610060414837631 14.10141994717172 -1.224646799147353e-16 0.2717525853195117+1.083923327338695i)) #t) (test (practically-equal? 'asin (map asin nums) '(1.570796326794897-4.158638853279167i 1.570796326794897-0.9624236501192069i 1.570796326794897-1.811526272460853i 0.6662394324925153+1.061275061905036i)) #t) (test (practically-equal? 'acos (map acos nums) '(0+4.158638853279167i 0+0.9624236501192069i 0+1.811526272460853i 0.9045568943023813-1.061275061905036i)) #t) (test (practically-equal? 'atan (map atan nums) '(1.539556493364628 0.9827937232473291 1.262627255678912 1.017221967897851+0.4023594781085251i)) #t) (test (practically-equal? 'sinh (map sinh nums) '(39481480091340.34 2.129279455094817 11.54873935725775 0.6349639147847361+1.298457581415977i)) #t) (test (practically-equal? 'cosh (map cosh nums) '(39481480091340.34 2.352409615243247 11.59195327552152 0.8337300251311491+0.9888977057628651i)) #t) (test (practically-equal? 'tanh (map tanh nums) '(1.0 0.9051482536448664 0.99627207622075 1.083923327338695+0.2717525853195117i)) #t) (test (practically-equal? 'asinh (map asinh nums) '(4.15912713462618 1.194763217287109 1.862295743310848 1.061275061905036+0.6662394324925153i)) #t) (test (practically-equal? 'acosh (map acosh nums) '(4.158638853279167 0.9624236501192069 1.811526272460853 1.061275061905036+0.9045568943023813i)) #t) (test (practically-equal? 'atanh (map atanh nums) '(0.03126017849066698+1.570796326794897i 0.8047189562170503+1.570796326794897i 0.3297653149566991+1.570796326794897i 0.4023594781085251+1.017221967897851i)) #t) (test (practically-equal? 'sqrt (map sqrt nums) '(5.656854249492381 1.224744871391589 1.772453850905516 1.09868411346781+0.4550898605622273i)) #t) (test (practically-equal? 'expt (map (lambda (n) (expt n 2)) nums) '(1024 9/4 9.869604401089358 1.224606353822377e-16+2i)) #t) (test (practically-equal? 'expt (map (lambda (n) (expt n r)) nums) '(181.0193359837562 1.837117307087384 5.568327996831708 0.6435942529055828+1.553773974030037i)) #t) (test (map floor rnums) '(32 1 3)) (test (map ceiling rnums) '(32 2 4)) (test (map truncate rnums) '(32 1 3)) (test (map round rnums) '(32 2 3)) (test (integer->char (mock-number (char->integer #\a))) #\a) (test (map inexact->exact rnums) '(32 3/2 4272943/1360120)) (test (practically-equal? 'exact->inexact (map exact->inexact rnums) '(32.0 1.5 3.141592653589793)) #t) (test (integer-length i) 6) (test (integer-decode-float x) '(7074237752028440 -51 1)) (test (map number? nums) '(#t #t #t #t)) (test (map integer? nums) '(#t #f #f #f)) (test (map real? nums) '(#t #t #t #f)) (test (map complex? nums) '(#t #t #t #t)) (test (map rational? nums) '(#t #t #f #f)) (test (map exact? nums) '(#t #t #f #f)) (test (map inexact? nums) '(#f #f #t #t)) (test (ash 1 i) 4294967296) (test (ash i -3) 4) (test (logbit? i 1) #f) (test (logbit? 1 i) #f) (if with-bignums (test (map number->string nums) '("32" "3/2" "3.141592653589793238462643383279502884195E0" "1+1i")) (test (map number->string nums) '("32" "3/2" "3.141592653589793" "1+1i"))) (test (every? number? (map random nums)) #t) (test (quotient i r) 21) (test (remainder i r) 1/2) (test (modulo i r) 1/2) (test (lognot i) -33) (test (logior i 2) 34) (test (logior 1 i 2 3) (logior 1 32 2 3)) (test (logior 1 7 i 62) (logior 1 7 32 62)) (test (logior (mock-number 1) (mock-number 8) 2 4 16 (mock-number 32)) 63) (test (logxor (mock-number 1) (mock-number 7) 2 4 16 (mock-number 32)) (logxor 1 7 2 4 16 32)) (test (logand 63 15 31 127) (logand 63 (mock-number 15) (mock-number 31) 127)) (num-test (apply + nums) 37.6415926535898+1i) (num-test (apply - nums) 26.35840734641021-1i) (num-test (apply * nums) 150.7964473723101+150.7964473723101i) (num-test (apply / nums) 3.3953054526271-3.3953054526271i) (num-test (apply max rnums) 32) (num-test (apply min rnums) 3/2) (num-test (min 65 i) 32) (test (apply < rnums) #f) (test (apply > rnums) #f) (test (apply <= rnums) #f) (test (apply >= rnums) #f) (test (< 1 3 i 47) #t) (test (> 5/2 r 1/2 (/ i 100)) #t) (test (<= 1.0 2.0 3.0 x) #t) (test (>= 101.231 i 4 x 5/2 r) #t) (test (> x z) 'error) (test (> i 0) #t) (test (< 0 i) #t) (test (>= x 0.0) #t) (test (<= 0.0 x) #t) (test (apply = nums) #f) (test (= i 32) #t) (test (= 33 i) #f) (test (= r 1/2) #f) (test (lcm i 3/2) (lcm i r)) (test (lcm 3/2 i) (lcm r i)) (test (lcm 33 2 i) (lcm 2 i 33)) (test (lcm 33 x) 'error) (test (apply lcm nums) 'error) (test (lcm i 0 x) 'error) (test (lcm 9 0 r) 0) (test (gcd i 3/2) (gcd i r)) (test (gcd i 3/2) (gcd 32 3/2)) (test (gcd 3/2 i) (gcd r i)) (test (gcd 33 2 i) (gcd 2 i 33)) (test (gcd 33 x) 'error) (test (apply gcd nums) 'error) (test (gcd i 0 x) 'error) (test (gcd 9 0 r) 3/2) (test (format #f "~D" ((*mock-number* 'mock-number) 123)) "123") (test (format #f "~F" ((*mock-number* 'mock-number) 1.23)) (format #f "~F" 1.23)) (test (format #f "~A" r) "3/2") (let ((index (mock-number 2)) (v #(0 1 2 3 4)) (s "01234") (p (list 0 1 2 3 4))) (test (string-ref s index) #\2) (test (list-ref p index) 2) (test (vector-ref v index) 2) (test (s index) #\2) (test (p index) 2) (test (v index) 2) (test (make-shared-vector #(0 1 2 3) '(3) (mock-number 1)) #(1 2 3)) (test (vector->list #(0 1 2 3 4) (mock-number 1) (mock-number 3)) '(1 2)) (test (list-tail p index) '(2 3 4)) (test (substring "01234" index) "234") (test (substring "01234" 0 index) "01") (test (substring "01234" index (mock-number 3)) "2") (test (vector->list #(0 1 2 3 4) index) '(2 3 4)) (test (vector->list #(0 1 2 3 4) index index) ()) (test (string->list "01234" index) '(#\2 #\3 #\4)) (test (string->list "01234" 0 index) '(#\0 #\1)) (test (let ((dest (make-string 3))) (copy "01234" dest index) dest) "234") (test (let ((dest (make-string 2))) (copy "01234" dest 0 index) dest) "01") (unless pure-s7 (test (let ((str "01234")) (string-fill! str #\a index) str) "01aaa")) (unless pure-s7 (test (let ((vec #(0 1 2 3 4))) (vector-fill! vec 5 (mock-number 0) (mock-number 3)) vec) #(5 5 5 3 4))) (test (let ((vec #2D((0 1 2) (3 4 5)))) (vector-ref vec (mock-number 1) index)) 5) ) (test (let ((vec ((*mock-vector* 'mock-vector) 10 11 12))) (vec ((*mock-number* 'mock-number) 1))) 11) (test (vector? (make-vector i)) #t) (test (string? (make-string i)) #t) (test (hash-table? (make-hash-table i)) #t) (test (pair? (make-list i)) #t) (define (p1-check . args) (if (> (magnitude (- (apply * args) 0.25+0.25i)) 1e-15) (format-logged #t "~A: (* ~{~A~^ ~}) -> ~A?~%" (port-line-number) args (apply * args))) (if (not (= (apply + args) 3+i)) (format-logged #t "~A: (+ ~{~A~^ ~}) -> ~A?~%" (port-line-number) args (apply + args))) (if (not (= (apply - args) (- (car args) (apply + (cdr args))))) (format-logged #t "~A: ~A != ~A?~%" (port-line-number) (apply - args) (- (car args) (apply + (cdr args))))) (if (not (= (apply / args) (/ (car args) (apply * (cdr args))))) (format-logged #t "~A: ~A != ~A?~%" (port-line-number) (apply / args) (/ (car args) (apply * (cdr args)))))) (for-each (lambda (lst) (for-each-permutation p1-check lst)) (list (list 1 1/2 0.5 1+i) (list (mock-number 1) 1/2 0.5 1+i) (list 1 (mock-number 1/2) 0.5 1+i) (list 1 1/2 (mock-number 0.5) 1+i) (list 1 1/2 0.5 (mock-number 1+i)) (list (mock-number 1) (mock-number 1/2) (mock-number 0.5) (mock-number 1+i)))) ))) (let () (let ((lst '(1 2 3))) (list-set! lst ((inlet 'i 2) 'i) 32) (test lst '(1 2 32))) (let ((lst '((1 2 3)))) (list-set! lst 0 ((inlet 'i 2) 'i) 32) (test lst '((1 2 32)))) (let ((lst '((1 2 3)))) (list-set! lst ((inlet 'i 0) 'i) ((inlet 'i 2) 'i) 32) (test lst '((1 2 32)))) (let ((i0 ((*mock-number* 'mock-number) 0)) (i1 ((*mock-number* 'mock-number) 1)) (i2 ((*mock-number* 'mock-number) 2)) (lst '((0 1 2) (3 4 5)))) (list-set! lst i0 i1 32) (test lst '((0 32 2) (3 4 5)))) (let ((i0 (openlet (inlet 'i 0 'list-set! (lambda (l . args) (apply #_list-set! l ((car args) 'i) (cdr args)))))) (i1 (openlet (inlet 'i 1 'list-set! (lambda (l . args) (apply #_list-set! l ((car args) 'i) (cdr args)))))) (i2 (openlet (inlet 'i 2 'list-set! (lambda (l . args) (apply #_list-set! l ((car args) 'i) (cdr args)))))) (lst '((0 1 2) (3 4 5)))) (list-set! lst i0 i1 32) (test lst '((0 32 2) (3 4 5))))) (let ((mock-pair (*mock-pair* 'mock-pair)) (mock-pair? (*mock-pair* 'mock-pair?))) (let ((lst (mock-pair 1 2 3))) (test (pair? lst) #t) (test (mock-pair? lst) #t) (test (morally-equal? (list 1 2 3) lst) #t) (test (morally-equal? lst (mock-pair 1 2 3)) #t) (test (integer? (pair-line-number lst)) #t) (unless pure-s7 (test (list->string (mock-pair #\a #\b #\c)) "abc")) (test (object->string lst) "(1 2 3)") (test (list? lst) #t) (test (null? lst) #f) (test (car lst) 1) (test (cdr lst) '(2 3)) (test (length lst) 3) (test (arity lst) (cons 1 1)) (test (reverse lst) '(3 2 1)) (unless pure-s7 (test (list->vector lst) #(1 2 3))) (test (map values lst) '(1 2 3)) (test (memq 2 lst) '(2 3)) (test (memv 3 lst) '(3)) (test (member 1 lst) '(1 2 3)) (test (list-tail lst 1) '(2 3)) (test (cadr lst) 2) (test (caddr lst) 3) (test (cddr lst) '(3)) (test (cdddr lst) ()) (test (list-ref lst 1) 2) (set-car! lst 4) (test (car lst) 4) (list-set! lst 2 32) (test (caddr lst) 32) (set-cdr! lst ()) (test (length lst) 1) (set! lst (apply mock-pair '((a . 1) (b . 2) (c . 3)))) (test (assq 'a lst) '(a . 1)) (test (assv 'b lst) '(b . 2)) (test (assoc 'c lst) '(c . 3)) (fill! lst 1) (test (car lst) 1) (set! lst (mock-pair 1 2 3)) (reverse! lst) (test (copy lst) '(3 2 1)) (set! lst (apply mock-pair (sort! lst <))) (test (copy lst) '(1 2 3)) (set! (lst 0) 4) (test (lst 0) 4) (test (list-tail lst 0) '(4 2 3)) (for-each (lambda (x) (if (not (integer? x)) (format *stderr* ";for-each mock-pair: ~A~%" x))) (mock-pair 1 2 3)) (test (make-shared-vector #(0 1 2 3) (mock-pair 2)) #(0 1)) (test (caar (apply mock-pair '((a) b c d e f g))) 'a) (test (cadr (apply mock-pair '(a b c d e f g))) 'b) (test (cdar (apply mock-pair '((a b) c d e f g))) '(b)) (test (cddr (apply mock-pair '(a b c d e f g))) '(c d e f g)) (test (caaar (apply mock-pair '(((a)) b c d e f g))) 'a) (test (caadr (apply mock-pair '(a (b) c d e f g))) 'b) (test (cadar (apply mock-pair '((a b) c d e f g))) 'b) (test (caddr (apply mock-pair '(a b c d e f g))) 'c) (test (cdaar (apply mock-pair '(((a b)) c d e f g))) '(b)) (test (cdadr (apply mock-pair '(a (b c) d e f g))) '(c)) (test (cddar (apply mock-pair '((a b c) d e f g))) '(c)) (test (cdddr (apply mock-pair '(a b c d e f g))) '(d e f g)) (test (caaaar (apply mock-pair '((((a))) b c d e f g))) 'a) (test (caaadr (apply mock-pair '(a ((b)) c d e f g))) 'b) (test (caadar (apply mock-pair '((a (b)) c d e f g))) 'b) (test (caaddr (apply mock-pair '(a b (c) d e f g))) 'c) (test (cadaar (apply mock-pair '(((a b)) c d e f g))) 'b) (test (cadadr (apply mock-pair '(a (b c) d e f g))) 'c) (test (caddar (apply mock-pair '((a b c) d e f g))) 'c) (test (cadddr (apply mock-pair '(a b c d e f g))) 'd) (test (cdaaar (apply mock-pair '((((a b))) c d e f g))) '(b)) (test (cdaadr (apply mock-pair '(a ((b c)) d e f g))) '(c)) (test (cdadar (apply mock-pair '((a (b c)) d e f g))) '(c)) (test (cdaddr (apply mock-pair '(a b (c d) e f g))) '(d)) (test (cddaar (apply mock-pair '(((a b c)) d e f g))) '(c)) (test (cddadr (apply mock-pair '(a (b c d) e f g))) '(d)) (test (cdddar (apply mock-pair '((a b c d) e f g))) '(d)) (test (cddddr (apply mock-pair '(a b c d e f g))) '(e f g)) (test (cyclic-sequences (mock-pair 1 2 3)) ()) (test (let ((y (mock-pair (make-circular-list 3)))) (let ((x (cyclic-sequences y))) (length x))) 1) (test (subsequence ((*mock-pair* 'mock-pair) 1 2 3 4) 2) '(3 4)) )) ; (test (let ((lst ((*mock-pair* 'mock-pair) 1 2 3))) (append lst '(4 5 6))) '(1 2 3 4 5 6)) ; (test (let ((lst ((*mock-pair* 'mock-pair) 1 2 3))) (append '(4 5 6) lst ())) '(4 5 6 1 2 3)) ; (test (let ((lst ((*mock-pair* 'mock-pair) 1 2 3))) (append '(4 5 6) lst)) '(4 5 6 1 2 3)) (test (sort! 'begin ((*mock-pair* 'mock-pair) 1 2)) 'error) (let ((immutable-list-class (sublet (*mock-pair* 'mock-pair-class) 'object->string (lambda (obj . args) (apply #_object->string (obj 'value) args)) 'let-set! (lambda (obj i val) (set! (obj 'value) (append (copy (obj 'value) (make-list (+ i 1))) (list-tail (obj 'value) (+ i 1)))) (list-set! (obj 'value) i val)) 'list-set! (lambda (obj i val) (set! (obj 'value) (append (copy (obj 'value) (make-list (+ i 1))) (list-tail (obj 'value) (+ i 1)))) (list-set! (obj 'value) i val)) 'set-car! (lambda (obj val) (set! (obj 'value) (cons val (cdr (obj 'value))))) 'set-cdr! (lambda (obj val) (set! (obj 'value) (cons (car (obj 'value)) val))) 'fill! (lambda (obj val) (set! (obj 'value) (fill! (copy (obj 'value)) val))) 'reverse! (lambda (obj) (set! (obj 'value) (reverse (obj 'value)))) 'sort! (lambda (obj func) (set! (obj 'value) (sort! (copy (obj 'value)) func)))))) (define (immutable-list lst) (openlet (sublet immutable-list-class 'value lst))) (let ((L1 (immutable-list (list 1 2 3 4 5)))) (let ((L2 (cdr L1)) (L3 (cons 0 (L1 'value)))) (list-set! L1 0 32) (test (L1 'value) '(32 2 3 4 5)) (test L2 '(2 3 4 5)) (test L3 '(0 1 2 3 4 5)) (set! (L1 2) 32) (test (L1 'value) '(32 2 32 4 5)) (test L2 '(2 3 4 5)) (test L3 '(0 1 2 3 4 5)) (set-cdr! L1 3) (test (L1 'value) '(32 . 3)) (test L2 '(2 3 4 5)) (set! L1 (immutable-list (list 1 2 3 4 5))) (set! L2 (cddr L1)) (set! L3 (cons 0 (L1 'value))) (sort! L1 >) (test (L1 'value) '(5 4 3 2 1)) (test L2 '(3 4 5)) (test L3 '(0 1 2 3 4 5)) (reverse! L1) (test (L1 'value) '(1 2 3 4 5)) (test L2 '(3 4 5)) (test (object->string L1) "(1 2 3 4 5)") ))) (let ((mock-symbol (*mock-symbol* 'mock-symbol)) (mock-symbol? (*mock-symbol* 'mock-symbol?))) (let ((sym (mock-symbol 'a))) (test (symbol? sym) #t) (test (mock-symbol? sym) #t) (test (morally-equal? sym 'a) #t) (test (keyword? sym) #f) (test (gensym? sym) #f) (test (symbol->string sym) "a") (let ((a 32)) (test (let ((a 32)) (symbol->value sym (curlet))) 32) (test (symbol->dynamic-value sym) 32) (test (defined? sym) #t) (test (symbol->keyword sym) :a) (test (provided? sym) #f) (test (symbol-access sym) #f))) (let ((sym (mock-symbol :a))) (test (keyword? sym) #t) (test (keyword->symbol sym) 'a)) (let () (define* (f1 a b) (+ a b)) (test (f1 (mock-symbol :a) 3 :b 2) 5))) (let ((mock-port (*mock-port* 'mock-port)) (mock-port? (*mock-port* 'mock-port?))) (let ((ip (open-input-string "0123456789")) (op (open-output-string))) (let ((mip (mock-port ip)) (mop (mock-port op))) (test (mock-port? mip) #t) (test (mock-port? ip) #f) (test (mock-port? mop) #t) (test (input-port? mip) #t) (test (output-port? mip) #f) (test (input-port? mop) #f) (test (output-port? mop) #t) (if (not pure-s7) (test (char-ready? mip) #t)) (test (char-ready? mop) 'error) (test (port-closed? mip) #f) (test (port-closed? mop) #f) ; (test (port-line-number mip) 0) ; ?? (test (port-filename mip) "") (test (read-char mip) #\0) (test (read-byte mip) (char->integer #\1)) (test (peek-char mip) #\2) (test (read-string 3 mip) "234") (test (read-line mip) "56789") (close-input-port mip) (test (port-closed? mip) #t) (test (port-closed? ip) #t) (write-char #\a mop) (test (get-output-string mop) "a") (write-byte (char->integer #\b) mop) (test (get-output-string mop) "ab") (write-string "cde" mop) (test (get-output-string mop) "abcde") (display #\f mop) (write 'g mop) (test (get-output-string mop) "abcdefg") (format mop "~C~C" #\h #\i) (test (get-output-string mop) "abcdefghi") (test (flush-output-port mop) op) (close-output-port mop) (test (port-closed? mop) #t) (test (port-closed? op) #t) (set! mip (mock-port (open-input-string "(+ 1 2)"))) (test (eval (read mip)) 3) (close-input-port mip) ))) ) ; mockery.scm ;(let () (define (f1) (with-let (inlet '+ (lambda args (apply * args))) (+ 1 2 3 4))) (test (with-let (inlet '+ (lambda args (apply * args))) (+ 1 2 3 4)) (f1))) ;as elsewhere stated, this is documented -- not sure it needs to be fixed (when (and (not with-bignums) (not pure-s7)) (let () (require stuff.scm mockery.scm) (define (write-func1 port name expr c method) (format port "(define (~A x) ~S)~%" name expr) (format port "(let ((val1 (~A ~S))~%" name c) (format port " (val2 (let ((x ~S)) ~S)))~%" c expr) (format port " (let ((val3 (~A (make-object 'x ~S '~A (make-method ~A (lambda (e) (e 'x)))))))~%" name c method method) (format port " (if (or (not (morally-equal? val1 val2))~%") (format port " (not (morally-equal? val2 val3)))~%") (format port " (format *stderr* \"~A: opt ~~A, unopt ~~A, env ~~A~~%\" val1 val2 val3))))~%~%" name)) (define* (write-func2 port name expr c1 c2 method method2) (format port "(define (~A x y) ~S)~%" name expr) (format port "(let ((val1 (~A ~S ~S))~%" name c1 c2) (format port " (val2 (let ((x ~S) (y ~S)) ~S)))~%" c1 c2 expr) (format port " (let ((val3 (~A (make-object 'x ~S '~A (make-method ~A (lambda (e) (e 'x))))~%" name c1 method method) (format port " (make-object 'y ~S '~A (make-method ~A (lambda (e) (e 'y)))))))~%" c2 (or method2 method) (or method2 method)) (format port " (let ((val4 (~A ~S (make-object 'y ~S '~A (make-method ~A (lambda (e) (e 'y)))))))~%" name c1 c2 (or method2 method) (or method2 method)) (format port " (let ((val5 (~A (make-object 'x ~S '~A (make-method ~A (lambda (e) (e 'x)))) ~S)))~%" name c1 method method c2) (format port " (if (or (not (morally-equal? val1 val2))~%") (format port " (not (morally-equal? val2 val3))~%") (format port " (not (morally-equal? val3 val4))~%") (format port " (not (morally-equal? val4 val5)))~%") (format port " (format *stderr* \"~A: opt ~~A, unopt ~~A, exy ~~A, ecy ~~A, exc ~~A~~%\" val1 val2 val3 val4 val5))))))~%~%" name)) (call-with-output-file "t923.scm" (lambda (p) (format p "(require stuff.scm)~%~%") (format p "(let ()~%") (write-func1 p "+_1s" '(+ 1 x) 3 '+) (write-func1 p "+_s1" '(+ x 1) 3 '+) (write-func1 p "+_s12" '(+ (+ x) 1) 3 '+) (write-func1 p "+_sf" '(+ x 2.0) 3 '+) (write-func1 p "+_fs" '(+ 2.0 x) 3 '+) (write-func2 p "+_xy" '(+ x y) 3 4 '+) (write-func2 p "+_xy1" '(+ 5 x y) 3 4 '+) (write-func2 p "+_xy2" '(+ 5 3 x 2 y) 3 4 '+) (write-func1 p "-_s1" '(- x 1) 3 '-) (write-func1 p "-_s1" '(- x 6) 3 '-) (write-func1 p "-_s1" '(- (- x) 1) 3 '-) (write-func1 p "-_1s" '(- 1 x) 3 '-) (write-func1 p "-_sf" '(- x 2.0) 3 '-) (write-func1 p "-_fs" '(- 2.0 x) 3 '-) (write-func2 p "-_xy" '(- x y) 3 4 '-) (write-func1 p "*_s" '(* x) 3 '*) (write-func1 p "*_2s" '(* 2 x) 3 '*) (write-func1 p "*_s2" '(* x 2) 3 '*) (write-func1 p "*_sf" '(* x 2.0) 3 '*) (write-func1 p "*_fs" '(* 2.0 x) 3 '*) (write-func1 p "*_xx" '(* x x) 3 '*) (write-func1 p "*_xnk" '(+ (* x 2) 3) 3 '*) (write-func1 p "-_fss" '(- 2.0 (* x x)) 3 '*) (write-func2 p "*_xy" '(* x y) 3 4 '*) (write-func2 p "*1xy" '(* (- 1.0 x) y) 3.0 4 '- '*) (write-func2 p "r2cos" '(* -2.0 x (cos y)) 3.0 1.8 '* 'cos) (write-func1 p "fsf" '(+ 3.5 (* x 4.5)) 5.0 '*) (write-func1 p "/_s" '(/ x) 3 '/) (write-func1 p "/_1s" '(/ 1 x) 3 '/) (write-func1 p "/_1.0s" '(/ 1.0 x) 3 '/) (write-func1 p "/_2s" '(/ 2 x) 3 '/) (write-func1 p "/_s2" '(/ x 2) 3 '/) (write-func1 p "/_sf" '(/ x 2.0) 3 '/) (write-func1 p "/_fs" '(/ 2.0 x) 3 '/) (write-func2 p "/_xy" '(/ x y) 3 4 '/) (write-func2 p "s_cos_s" '(* x (cos y)) 3.1 1.8 '* 'cos) (write-func2 p "s_sin_s" '(* x (sin y)) 3.1 1.8 '* 'sin) (write-func1 p "min_2f" '(min x 1.0) 3.1 'min) (write-func1 p "max_2f" '(max 1.0 x) 3.1 'max) (write-func1 p "min_2f1" '(min x 1.0) 3.1 'min) (write-func1 p "max_2f1" '(max 1.0 x) 3.1 'max) (write-func1 p "modsi0" '(zero? (modulo x 3)) 5 'modulo) (write-func1 p "neglen" '(negative? (length x)) #(0 1) 'length) (write-func1 p "eqzlen" '(= (length x) 0) #() 'length) (write-func1 p "zlen" '(zero? (length x)) #() 'length) (write-func1 p "=x" '(= x 1) 1 '=) (write-func1 p "=x" '(>= x 1) 1 '>=) (write-func1 p ">x" '(> x 1) 1 '>) (write-func1 p "=len" '(= (length x) 6) #(0 1 2 3 4 5) 'length) (write-func1 p "len" '(> (length x) 6) #(0 1 2 3 4 5) 'length) (write-func1 p "<=len" '(<= (length x) 6) #(0 1 2 3 4 5 ) 'length) (write-func1 p "<=len" '(<= (length x) 6) #(0 1 2 3 4 5) 'length) (write-func1 p ">=len" '(>= (length x) 6) #(0 1 2 3 4 5) 'length) (for-each ; ints (lambda (f1) (write-func1 p (string-append (symbol->string f1) "_si") `(,f1 x) -3 f1)) (list 'real-part 'imag-part 'numerator 'denominator 'even? 'odd? 'zero? 'positive? 'negative? 'infinite? 'nan? 'magnitude 'angle 'rationalize 'abs 'exp 'log 'sin 'cos 'tan 'asin 'acos 'atan 'sinh 'cosh 'tanh 'asinh 'acosh 'atanh 'sqrt 'floor 'ceiling 'truncate 'round 'inexact->exact 'exact->inexact 'integer-length 'logior 'logxor 'logand 'lognot 'number? 'integer? 'real? 'complex? 'rational? 'exact? 'inexact? 'number->string)) (for-each ; reals (lambda (f1) (write-func1 p (string-append (symbol->string f1) "_sf") `(,f1 x) 3.14 f1)) (list 'real-part 'imag-part 'zero? 'positive? 'negative? 'infinite? 'nan? 'magnitude 'angle 'rationalize 'abs 'exp 'log 'sin 'cos 'tan 'asin 'acos 'atan 'sinh 'cosh 'tanh 'asinh 'acosh 'atanh 'sqrt 'floor 'ceiling 'truncate 'round 'inexact->exact 'exact->inexact 'integer-decode-float 'number? 'integer? 'real? 'complex? 'rational? 'exact? 'inexact? 'number->string)) (for-each (lambda (f1) (write-func1 p (string-append (symbol->string f1) "_si") `(,f1 x 3) 4 f1)) (list 'log 'logior 'logxor 'logand 'modulo 'remainder 'quotient 'max 'min 'lcm 'gcd 'expt 'ash)) (for-each (lambda (f1) (write-func2 p (string-append (symbol->string f1) "_xy") `(,f1 x y) 3 4 f1)) (list 'make-polar 'complex 'expt 'lcm 'gcd 'max 'min 'quotient 'remainder 'modulo '= '< '> '<= '>= 'ash 'logbit?)) (for-each (lambda (f1) (write-func1 p (string-append (symbol->string f1) "_x0") `(,f1 x 0) 3 f1)) (list 'make-polar 'complex 'expt 'lcm 'gcd 'max 'min '= '< '> '<= '>= 'ash 'logbit?)) (for-each (lambda (f1) (write-func2 p (string-append (symbol->string f1) "_xy") `(,f1 x y) 3.14 4.2 f1)) (list 'make-polar 'complex 'expt 'max 'min 'quotient 'remainder 'modulo '= '< '> '<= '>=)) (for-each (lambda (f1) (write-func1 p (string-append (symbol->string f1) "_c") `(,f1 x) #\a f1)) (list 'char-upcase 'char-downcase 'char->integer 'char-upper-case? 'char-lower-case? 'char-alphabetic? 'char-numeric? 'char-whitespace? 'char?)) (for-each (lambda (f2) (write-func2 p (string-append (symbol->string f2) "_xy") `(,f2 x y) #\a #\space f2)) (list 'char=? 'char? 'char<=? 'char>=? 'string)) (for-each (lambda (f1) (write-func1 p (string-append (symbol->string f1) "_xc") `(,f1 x #\b) #\a f1)) (list 'char=? 'char? 'char<=? 'char>=?)) (write-func1 p "intchar" '(integer->char x) 92 'integer->char) (write-func2 p "charpos" '(char-position x y) #\a "dsafa" 'char-position 'char-position) (for-each (lambda (f1) (write-func1 p (string-append (symbol->string f1) "_c") `(,f1 x) "asd" f1)) (list 'string? 'string-downcase 'string-upcase 'string->list 'string-length 'string-copy)) (for-each (lambda (f2) (write-func2 p (string-append (symbol->string f2) "_xy") `(,f2 x y) "Aasd" "basd" f2)) (list 'string=? 'string? 'string<=? 'string>=? 'string-ci=? 'string-ci? 'string-ci<=? 'string-ci>=? 'string-append)) (for-each (lambda (f1) (write-func1 p (string-append (symbol->string f1) "_xc") `(,f1 x "asbda") "asda" f1)) (list 'string=? 'string? 'string<=? 'string>=? 'string-ci=? 'string-ci? 'string-ci<=? 'string-ci>=?)) (write-func1 p "lst0" '(list-ref x 0) '(list 0 1 3) 'list-ref) (write-func1 p "lst1" '(list-set! x 0 1) '(list 0 1 3) 'list-set!) (write-func1 p "vct0" '(vector-ref x 0) '(vector 0 1 3 4 5 6 7 8) 'vector-ref) (write-func1 p "vct1" '(vector-ref x 1) '(vector 0 1 3 4 5 6 7 8) 'vector-ref) (write-func1 p "vct2" '(vector-ref x 2) '(vector 0 1 3 4 5 6 7 8) 'vector-ref) (write-func1 p "vct3" '(vector-ref x 3) '(vector 0 1 3 4 5 6 7 8) 'vector-ref) (write-func1 p "vct4" '(vector-ref x 4) '(vector 0 1 3 4 5 6 7 8) 'vector-ref) (write-func1 p "arit" '(aritable? x 1) abs 'aritable?) (write-func1 p "arty" '(arity x) abs 'arity) (write-func1 p "bool" '(boolean? x) #f 'boolean?) (write-func1 p "cc" '(continuation? x) #f 'continuation?) (write-func1 p "eof" '(eof-object? x) # 'eof-object?) (write-func1 p "gen" '(gensym? x) ''a 'gensym?) (write-func1 p "con" '(constant? x) 1 'constant?) (write-func1 p "df" '(defined? x) ''format 'defined?) (write-func1 p "key" '(keyword? x) ':a 'keyword?) (write-func1 p "keysym" '(keyword->symbol x) ':a 'keyword->symbol) (write-func1 p "intchr" '(integer->char x) 95 'integer->char) ;(write-func1 p "gens" '(gensym x) "asdf" 'gensym) -- can't be the same (this is like calling random) ;(write-func1 p "evl" '(eval x) ''(+ 1 2) 'eval) -- env evals to itself (write-func1 p "evlstr" '(eval-string x) "(+ 1 2)" 'eval-string) (write-func1 p "rev" '(reverse x) #(0 1 2) 'reverse) (write-func1 p "symb" `(symbol x) "asdf" 'symbol) (write-func1 p "mb" '(member 1 x) '(list 0 1 2) 'member) (write-func1 p "mq" '(memq 1 x) '(list 0 1 2) 'memq) (write-func1 p "mv" '(memv 1 x) '(list 0 1 2) 'memv) (write-func1 p "ac" '(assoc 1 x) '(list (cons 0 1) (cons 1 2) (cons 2 3)) 'assoc) (write-func1 p "aq" '(assq 1 x) '(list (cons 0 1) (cons 1 2) (cons 2 3)) 'assq) (write-func1 p "av" '(assv 1 x) '(list (cons 0 1) (cons 1 2) (cons 2 3)) 'assv) (write-func1 p "srt" '(sort! x <) #(0 1 2) 'sort!) (for-each (lambda (f1) (write-func1 p (string-append (symbol->string f1) "_x") `(,f1 x) abs f1)) (list 'procedure-documentation 'funclet 'procedure-setter 'procedure-source 'dilambda? 'procedure?)) (for-each (lambda (f1) (write-func1 p (string-append (symbol->string f1) "_x") `(,f1 x) ''abs f1)) (list 'symbol->dynamic-value 'symbol->keyword 'symbol->string 'symbol->value 'symbol-access 'symbol?)) (for-each (lambda (f1) (write-func1 p (string-append (symbol->string f1) "_x") `(,f1 x) #(0 1 2) f1)) (list 'vector->list 'vector-dimensions 'vector-length 'vector?)) (write-func1 p "vs" '(vector-set! x 0 1) (vector 0 1) 'vector-set!) (write-func1 p "vf" '(vector-fill! x 0) (vector 0 1) 'vector-fill!) ;(write-func2 p "va" '(vector-append x y) (vector 0 1) (vector 2 3) 'vector-append 'vector-append) (write-func1 p "cwof" '(call-with-output-file x (lambda (p) (display 12 p))) "tmp1.r5rs" 'call-with-output-file) (write-func1 p "cwif" '(call-with-input-file x (lambda (p) (read p))) "tmp1.r5rs" 'call-with-input-file) (write-func1 p "cwis" '(call-with-input-string x (lambda (p) (read p))) "123" 'call-with-input-string) (write-func1 p "wof" '(with-output-to-file x (lambda () (display 12))) "tmp1.r5rs" 'with-output-to-file) (write-func1 p "wif" '(with-input-from-file x (lambda () (read))) "tmp1.r5rs" 'with-input-from-file) (write-func1 p "wis" '(with-input-from-string x (lambda () (read))) "123" 'with-input-from-string) (write-func1 p "fvr" '(float-vector-ref x 0) '(float-vector 0 1) 'float-vector-ref) (write-func1 p "fvs" '(float-vector-set! x 0 1.0) '(float-vector 0 1) 'float-vector-set!) ; g_vct_set_three clm2xen.c 9507 (write-func1 p "fvq" '(float-vector? x) '(float-vector 0 1) 'float-vector?) (for-each (lambda (f1) (write-func1 p (string-append (symbol->string f1) "_x") `(,f1 x) '(hash-table '(a . 1) '(b . 2)) f1)) (list 'hash-table-entries 'hash-table?)) (write-func1 p "htr" '(hash-table-ref x 'a) '(hash-table '(a . 1) '(b . 2)) 'hash-table-ref) (write-func1 p "hts" '(hash-table-set! x 'a 1) '(hash-table '(a . 1) '(b . 2)) 'hash-table-set!) (write-func1 p "lstail" '(list-tail x 2) '(list 0 1 2 3) 'list-tail) (write-func1 p "op1" '(let ((p (open-input-file x))) (close-input-port p)) "tmp1.r5rs" 'open-input-file) (write-func1 p "op1" '(let ((p (open-input-string x))) (close-input-port p)) "tmp1.r5rs" 'open-input-string) ; (write-func1 p "mapx" '(map abs x) #(-1 -2 -3) 'map) ; (write-func1 p "forx" '(let ((sum 0)) (for-each (lambda (n) (set! sum (+ sum n))) x) sum) #(1 2 3) 'for-each) (write-func1 p "strfil" '(string-fill! x #\a) '(make-string 3) 'string-fill!) (write-func1 p "strfil" '(string-fill! (make-string 3) x) #\a 'string-fill!) (write-func1 p "lststr" '(list->string x) '(list #\a #\b) 'list->string) (write-func1 p "substr" '(substring x 1) "asdf" 'substring) (write-func2 p "makstr" `(make-string x y) 3 #\a 'make-string) (write-func1 p "n?" '(null? x) '(list) 'null?) (write-func1 p "nl?" '(null? x) '(list 1) 'null?) (write-func1 p "npa" '(not (pair? (car x))) '(list 1 2) 'car) (write-func1 p "npa1" '(not (pair? (car x))) '(list (list 1 2)) 'car) (write-func1 p "ft" '(format #f x) "test" 'format) (write-func1 p "sca" '(set-car! x 1) '(list 1 2) 'set-car!) (write-func1 p "scd" '(set-cdr! x 1) '(list 1 2) 'set-cdr!) (write-func1 p "nnd" '(not (null? (cdr x))) '(list 1) 'cdr) (write-func1 p "nnd1" '(not (null? (cdr x))) '(list 1 2) 'cdr) (write-func2 p "strref" `(string-ref x y) "asdf" 1 'string-ref) (write-func2 p "strset" `(string-set! x y #\a) "asdf" 1 'string-set!) (write-func1 p "objstr" `(object->string x) 12 'object->string) (write-func1 p "newstr" `(call-with-output-string (lambda (p) (newline x))) #f 'newline) (write-func1 p "ftn" '(format #f x) "test~%" 'format) ;(write-func1 p "stk" '(stacktrace x) 2 'stacktrace) (write-func1 p "symstr" '(symbol->string x) ''a 'symbol->string) (write-func1 p "mrns" '(random-state x) 123 'random-state) (write-func1 p "mrnx" '(random-state 123 x) 123 'random-state) (write-func1 p "a1y" '(assoc (+ 0 1) x) '(list (cons 0 1) (cons 1 2) (cons 2 3)) 'assoc) (write-func1 p "mba" '(member 'a x) '(list 0 'a 2) 'member) (write-func1 p ">xf" '(> x 2.0) 3.0 '>) (write-func1 p "=rx" '(= 3/2 x) 2/3 '=) (write-func1 p "-*x" '(- (* x 2.0) 3.0) 4.0 '*) (write-func1 p "-_rs" '(- 2/3 x) 3 '-) (write-func1 p "-_rf" '(- 12 x) 3 '-) (write-func1 p "-_cs" '(- 1+i x) 3 '-) (write-func1 p "+_rs" '(+ 2/3 x) 3 '+) (write-func1 p "+_cs" '(+ 1+i x) 3 '+) (write-func1 p "*_rs" '(* 2/3 x) 3 '*) (write-func1 p "*_cs" '(* 1+i x) 3 '*) (write-func1 p "+_si" '(+ x 12) 3 '+) (for-each (lambda (f1 lst) (write-func1 p (string-append (symbol->string f1) "_x") `(,f1 x) lst f1)) (list 'car 'cdr 'caar 'cadr 'cdar 'cddr 'caaar 'caadr 'cadar 'caddr 'cdaar 'cdadr 'cddar 'cdddr 'caaaar 'caaadr 'caadar 'caaddr 'cadaar 'cadadr 'caddar 'cadddr 'cdaaar 'cdaadr 'cdadar 'cdaddr 'cddaar 'cddadr 'cdddar 'cddddr ) (list ''(a) ''(a b) ''((a) b c) ''(a b c) ''((a . aa) b c) ''(a b . c) ''(((a)) b c) ''(a (b) c) ''((a aa) b c) ''(a b c) ''(((a . aa)) b c) ''(a (b . bb) c) ''((a aa . aaa) b c) ''(a b c . d) ''((((a))) b c) ''(a ((b)) c) ''((a (aa)) b c) ''(a b (c)) ''(((a aa)) b c) ''(a (b bb) c) ''((a aa aaa) b c) ''(a b c d) ''((((a . aa))) b c) ''(a ((b . bb)) c) ''((a (aa . aaa)) b c) ''(a b (c . cc)) ''(((a aa . aaa)) b c) ''(a (b bb . bbb) c) ''((a aa aaa . aaaa) b c) ''(a b c d . e))) (write-func1 p "np" '(not (pair? x)) '(list 1) 'pair?) (write-func1 p "nn" '(not (null? x)) () 'null?) (write-func1 p "ns" '(not (symbol? x)) '(quote q) 'symbol?) (write-func1 p "nx" '(not (number? x)) 3 'number?) (write-func1 p "nr" '(not (real? x)) 3 'real?) (write-func1 p "nm" '(not (rational? x)) 3 'rational?) (write-func1 p "ni" '(not (integer? x)) 3 'integer?) (write-func1 p "nb" '(not (boolean? x)) #f 'boolean?) (write-func1 p "ny" '(not (string? x)) "a" 'string?) (write-func1 p "nc" '(not (char? x)) #\a 'char?) (write-func1 p "ne" '(not (eof-object? x)) # 'eof-object?) (write-func1 p "nl" '(not (list? x)) '(list 1) 'list?) (write-func1 p "nl1" '(not (proper-list? x)) '(cons 1 2) 'proper-list?) (write-func1 p "scar" '(set! (car x) 2) '(list 0 1) 'set-car!) (format p ")~%") )) (load "t923.scm" (curlet)))) (let () (define (call-with-input-vector v proc) (let ((i -1)) (proc (openlet (inlet 'read (lambda (p) (v (set! i (+ i 1)))) 'read-byte (lambda (p) (v (set! i (+ i 1)))) 'read-char (lambda (p) (v (set! i (+ i 1)))) 'read-line (lambda (p) (v (set! i (+ i 1)))) 'close-input-port (lambda (p) p) 'read-string (lambda (p) (v (set! i (+ i 1))))))))) (define (call-with-output-vector proc) (let* ((size 1) (v (make-vector size #f)) (i 0) (write-to-vector (lambda (obj p) (when (= i size) ; make the vector bigger to accommodate the output (set! v (copy v (make-vector (set! size (* size 2)) #f)))) (set! (v i) obj) (set! i (+ i 1)) #))) ; that's what write/display return! (proc (openlet (inlet 'write (lambda* (obj p) ((if (not (let? p)) write write-to-vector) obj p)) 'display (lambda* (obj p) ((if (not (let? p)) display write-to-vector) obj p)) 'format (lambda (p . args) (if (not (let? p)) (apply format p args) (write (apply format #f args) p))) 'write-byte (lambda* (obj p) ((if (not (let? p)) write write-to-vector) obj p)) 'write-char (lambda* (obj p) ((if (not (let? p)) write write-to-vector) obj p)) 'close-output-port (lambda (p) p) 'flush-output-port (lambda (p) p) 'write-string (lambda* (obj p) ((if (not (let? p)) write write-to-vector) obj p))))) (make-shared-vector v (list i)))) (let ((lst ())) (call-with-input-vector (vector 1 2 3 4 5) (lambda (p) (set! lst (cons (read p) lst)) (set! lst (cons (read-byte p) lst)) (set! lst (cons (read-char p) lst)) (set! lst (cons (read-line p) lst)) (set! lst (cons (read-string p) lst)) (close-input-port p))) (test lst '(5 4 3 2 1))) (test (call-with-output-vector (lambda (p) (write 2 p) (display 4 p) (format p "~C" #\a) (write-byte 8 p) (write-char #\a p) (write-string "a" p) (flush-output-port p) (close-output-port p))) #(2 4 "a" 8 #\a "a"))) (let () (define (open-output-log name) ;; return a soft output port that does not hold its output file open (define (logit name str) (let ((p (open-output-file name "a"))) (display str p) (close-output-port p))) (openlet (inlet :name name :format (lambda (p str . args) (logit (p 'name) (apply format #f str args))) :write (lambda (obj p) (logit (p 'name) (object->string obj #t))) :display (lambda (obj p) (logit (p 'name) (object->string obj #f))) :write-string (lambda (str p) (logit (p 'name) str)) :write-char (lambda (ch p) (logit (p 'name) (string ch))) :newline (lambda (p) (logit (p 'name) (string #\newline))) :close-output-port (lambda (p) #f) :flush-output-port (lambda (p) #f)))) (if (file-exists? "s7-test.log") (delete-file "s7-test.log")) (let ((elog (open-output-log "s7-test.log"))) (format elog "this is a test~%") (format elog "all done!~%")) (let ((p (open-input-file "s7-test.log"))) (test (read-line p) "this is a test") (test (read-line p) "all done!") (test (eof-object? (read-line p)) #t) (close-input-port p))) ;;; *s7* -------- (test (integer? (*s7* 'stack-top)) #t) (test (integer? (*s7* 'stack-size)) #t) (test (integer? (*s7* 'max-stack-size)) #t) (test (integer? (*s7* 'rootlet-size)) #t) (test (integer? (*s7* 'heap-size)) #t) (test (integer? (*s7* 'free-heap-size)) #t) (test (integer? (*s7* 'gc-freed)) #t) (test (real? (*s7* 'cpu-time)) #t) (test (vector? (*s7* 'symbol-table)) #t) (test (integer? (*s7* 'max-string-length)) #t) (test (integer? (*s7* 'max-list-length)) #t) (test (integer? (*s7* 'max-vector-length)) #t) (test (integer? (*s7* 'max-vector-dimensions)) #t) (test (integer? (*s7* 'default-hash-table-length)) #t) (test (integer? (*s7* 'initial-string-port-length)) #t) (test (real? (*s7* 'morally-equal-float-epsilon)) #t) (test (real? (*s7* 'hash-table-float-epsilon)) #t) (test (integer? (*s7* 'float-format-precision)) #t) (test (random-state? (*s7* 'default-random-state)) #t) (test (*s7* 'stacktrace-defaults) '(3 45 80 45 #t)) (test (boolean? (*s7* 'undefined-identifier-warnings)) #t) (let () (catch 'one (lambda () (catch 'two (lambda () (catch 'three (lambda () (test (*s7* 'catches) '(#t three two one))) (lambda a a))) (lambda a a))) (lambda a a))) (let () (call-with-exit (lambda (one) (call-with-exit (lambda (two) (call-with-exit (lambda (three) (test (list? (*s7* 'exits)) #t)))))))) (test (list? (*s7* 'stack)) #t) (test (string? (object->string (catch #t (lambda () (dynamic-wind (lambda () #f) (lambda () (object->string (*s7* 'stack))) (lambda () #f))) (lambda args #f)))) #t) (test (vector? (*s7* 'gc-protected-objects)) #t) (when (provided? 'debugging) (test (vector? (*s7* 'gensyms)) #t) (test (vector? (*s7* 'input-ports)) #t) (test (vector? (*s7* 'output-ports)) #t) (test (vector? (*s7* 'strings)) #t) (test (vector? (*s7* 'vectors)) #t) (test (vector? (*s7* 'hash-tables)) #t) (test (vector? (*s7* 'continuations)) #t)) (test (vector? (*s7* 'c-objects)) #t) (test (vector? (*s7* 'file-names)) #t) (test (boolean? (*s7* 'gc-stats)) #f) (test (real? (*s7* 'default-rationalize-error)) #t) (let ((old-default-hash-table-length (*s7* 'default-hash-table-length)) (old-initial-string-port-length (*s7* 'initial-string-port-length)) (old-hash-table-float-epsilon (*s7* 'hash-table-float-epsilon)) (old-morally-equal-float-epsilon (*s7* 'morally-equal-float-epsilon)) (old-gc-stats-symbol (*s7* 'gc-stats-symbol)) (old-symbol-table-locked? (*s7* 'symbol-table-locked?)) (old-max-stack-size (*s7* 'max-stack-size)) (old-safety (*s7* 'safety)) (old-default-rationalize-error (*s7* 'default-rationalize-error)) (old-default-random-state (*s7* 'default-random-state))) (set! (*s7* 'default-hash-table-length) 31) (let ((ht (make-hash-table))) (test (length ht) 32)) (let ((ht (hash-table '(a . 1)))) (test (length ht) 32)) (let ((ht (hash-table* :a 1))) (test (length ht) 32)) (set! (*s7* 'hash-table-float-epsilon) 1e-4) (let ((ht (make-hash-table))) (set! (ht 3.0) 'x) (set! (ht 3.00005) 'y) (test (ht 3.00001) 'y)) (set! (*s7* 'morally-equal-float-epsilon) .1) (test (morally-equal? 1.0 1.01) #t) (set! (*s7* 'default-rationalize-error) .1) (test (rationalize 3.14159) 16/5) (set! (*s7* 'default-hash-table-length) old-default-hash-table-length) (set! (*s7* 'initial-string-port-length) old-initial-string-port-length) (set! (*s7* 'hash-table-float-epsilon) old-hash-table-float-epsilon) (set! (*s7* 'morally-equal-float-epsilon) old-morally-equal-float-epsilon) (set! (*s7* 'gc-stats-symbol) old-gc-stats-symbol) (set! (*s7* 'symbol-table-locked?) old-symbol-table-locked?) (set! (*s7* 'max-stack-size) old-max-stack-size) (set! (*s7* 'safety) old-safety) (set! (*s7* 'default-rationalize-error) old-default-rationalize-error) (set! (*s7* 'default-random-state) old-default-random-state) (let ((ht (make-hash-table))) (test (length ht) (*s7* 'default-hash-table-length))) (let ((ht (make-hash-table))) (set! (ht 3.0) 'x) (set! (ht 3.05) 'y) (test (ht 3.01) #f)) (test (morally-equal? 1.0 1.01) #f) (test (rationalize 3.14159) 314159/100000) ) (let ((old-vlen (*s7* 'max-vector-length))) (set! (*s7* 'max-vector-length) 123) (test (catch #t (lambda () (make-vector 256)) (lambda args 'error)) 'error) (test (catch #t (lambda () (make-float-vector 256)) (lambda args 'error)) 'error) (test (catch #t (lambda () (make-int-vector 256)) (lambda args 'error)) 'error) (test (catch #t (lambda () (make-hash-table 256)) (lambda args 'error)) 'error) (set! (*s7* 'max-vector-length) old-vlen)) (let ((old-vdim (*s7* 'max-vector-dimensions))) (set! (*s7* 'max-vector-dimensions) 1) (test (catch #t (lambda () (make-vector '(2 3))) (lambda args 'error)) 'error) (test (catch #t (lambda () (make-float-vector '(2 3))) (lambda args 'error)) 'error) (test (catch #t (lambda () (make-int-vector '(2 3))) (lambda args 'error)) 'error) (set! (*s7* 'max-vector-dimensions) old-vdim)) (let ((old-slen (*s7* 'max-string-length))) (set! (*s7* 'max-string-length) 12) (test (catch #t (lambda () (make-string 256)) (lambda args 'error)) 'error) (set! (*s7* 'max-string-length) old-slen)) (let ((old-llen (*s7* 'max-list-length))) (set! (*s7* 'max-list-length) 1) (test (catch #t (lambda () (make-list 256)) (lambda args 'error)) 'error) (set! (*s7* 'max-list-length) old-llen)) (test (*s7* 14) 'error) (test (*s7* (list 1)) 'error) (test (set! (*s7* 14) 1) 'error) (let ((old-precision (*s7* 'float-format-precision))) (let ((v ())) (let ((val1 (object->string (do ((i 1 (+ i 1))) ((= i 4) v) (set! v (cons (sin i) v)))))) (set! v ()) (set! (*s7* 'float-format-precision) 3) (let ((val2 (object->string (do ((i 1 (+ i 1))) ((= i 4) v) (set! v (cons (sin i) v)))))) (set! (*s7* 'float-format-precision) old-precision) (if with-bignums (test val1 "(1.411200080598672221007448028081102798466E-1 9.092974268256816953960198659117448427036E-1 8.414709848078965066525023216302989996239E-1)") (test val1 "(0.1411200080598672 0.9092974268256817 0.8414709848078965)")) (if with-bignums (test val2 "(1.411200080598672221007448028081102798466E-1 9.092974268256816953960198659117448427036E-1 8.414709848078965066525023216302989996239E-1)") (test val2 "(0.141 0.909 0.841)")) (if (not with-bignums) (test (<= (length val1) (length val2)) #f)))))) (for-each (lambda (field) (for-each (lambda (arg) (test (set! (*s7* field) arg) 'error)) (list "hi" (integer->char 65) (list 1 2) #t (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1/0 (log 0) 3.14 3/4 1.0+1.0i #\f (lambda (a) (+ a 1)) # #))) '(print-length safety cpu-time heap-size free-heap-size gc-freed max-string-length max-list-length max-vector-length max-vector-dimensions default-hash-table-length initial-string-port-length gc-protected-objects file-names rootlet-size c-types stack-top stack-size stacktrace-defaults max-stack-size catches exits float-format-precision bignum-precision)) (for-each (lambda (field) (for-each (lambda (arg) (test (set! (*s7* field) arg) 'error)) (list "hi" (integer->char 65) (list 1 2) #t (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 1.0+1.0i #\f (lambda (a) (+ a 1)) # #))) '(default-rationalize-error default-random-state morally-equal-float-epsilon hash-table-float-epsilon)) (for-each (lambda (field) (for-each (lambda (arg) (test (set! (*s7* field) arg) 'error)) (list "hi" (integer->char 65) (list 1 2) (make-vector 3) abs _ht_ _null_ _c_obj_ quasiquote macroexpand 3/4 3.14 1.0+1.0i #\f (lambda (a) (+ a 1)) # #))) '(undefined-identifier-warnings gc-stats symbol-table-locked?)) ;; it's documented that this kind of stuff may be optimized out, so these can do anything ;(test (let ((x (abs -1)) (sba abs)) (set! abs odd?) (let ((y (abs 1))) (set! abs sba) (list x y abs))) (list 1 #t abs)) ;(test (let () (define (hi z) (abs z)) (let ((x (hi -1)) (sba abs)) (set! abs odd?) (let ((y (hi 1))) (set! abs sba) (list x y)))) (list 1 #t)) ;(test (let () (define (hi z) (abs z)) (let ((x (hi -1)) (sba abs)) (set! abs (lambda (a b) (+ a b))) (let ((y (hi 1))) (set! abs sba) (list x y)))) 'error) ;(set! abs #_abs) ;(test (let () (define (hi) (let ((cond 3)) (set! cond 4) cond)) (hi)) 4) ;(test (let ((old+ +) (j 0)) (do ((i 0 (+ i 1))) ((or (< i -3) (> i 3))) (set! + -) (set! j (old+ j i))) (set! + old+) j) -6) ;;; -------------------------------------------------------------------------------- ;;; libm (if (not (provided? 'windows)) (let () (require libm.scm) (when (and (defined? '*libm*) (procedure? (*libm* 'remquo))) ; ignore ancient versions of libm (with-let (sublet *libm*) ;; __DBL_DENORM_MIN__ comes from gcc ;; these tests come from the autotester (I also tried those in glibc 2-17 math/libm-test.inc) ;; just representative values -- maybe catch more possibilities? (when (not (provided? 'solaris)) (num-test __DBL_DENORM_MIN__ 4.9406564584125e-324) (num-test __DBL_MAX__ 1.7976931348623e+308) (num-test __DBL_MIN__ 2.2250738585072e-308) (num-test __DBL_EPSILON__ 2.2204460492503e-16) (num-test __DBL_MIN_10_EXP__ -307) (num-test __DBL_MAX_10_EXP__ 308) (num-test __DBL_DIG__ 15) (num-test __DBL_MANT_DIG__ 53) (num-test __DBL_MIN_EXP__ -1021) (num-test __DBL_MAX_EXP__ 1024) (reader-cond ((not (provided? 'openbsd)) (num-test __SIZEOF_DOUBLE__ 8))) (reader-cond ((not (provided? 'openbsd)) (num-test __SIZEOF_LONG_LONG__ 8))) (num-test __LONG_LONG_MAX__ 9223372036854775807)) (reader-cond ((provided? 'linux) (num-test FP_NAN 0) (num-test FP_INFINITE 1) (num-test FP_ZERO 2) (num-test FP_SUBNORMAL 3) (num-test FP_NORMAL 4)) ((provided? 'freebsd) (num-test FP_NAN 2) (num-test FP_INFINITE 1) (num-test FP_ZERO 16) (num-test FP_SUBNORMAL 8) (num-test FP_NORMAL 4)) ((provided? 'osx) (num-test FP_NAN 1) (num-test FP_INFINITE 2) (num-test FP_ZERO 3) (num-test FP_SUBNORMAL 5) (num-test FP_NORMAL 4))) (num-test M_E (exp 1.0)) (num-test M_LOG2E (/ (log 2))) (num-test M_LOG10E (/ (log 10))) (num-test M_LN2 (log 2)) (num-test M_LN10 (log 10)) (num-test M_PI pi) (num-test M_PI_2 (/ pi 2)) (num-test M_PI_4 (/ pi 4)) (num-test M_1_PI (/ pi)) (num-test M_2_PI (/ 2 pi)) (num-test M_2_SQRTPI (/ 2 (sqrt pi))) (num-test M_SQRT2 (sqrt 2)) (num-test M_SQRT1_2 (/ (sqrt 2))) (num-test (j0 -1) 0.76519768655797) (num-test (j0 0) 1.0) (num-test (j0 1) 0.76519768655797) (num-test (j0 1.5) 0.51182767173592) (num-test (j0 -1234567.5) -0.00056797538542782) (num-test (j0 32.75) 0.11922756341796) (num-test (j0 3) -0.26005195490193) (num-test (j0 inf.0) 0.0) (test (nan? (j0 nan.0)) #t) (num-test (j1 -42) 0.045993888221887) (num-test (j1 -1) -0.44005058574493) (num-test (j1 0) 0.0) (num-test (j1 3/4) 0.34924360217486) (num-test (j1 -63) 0.057696680293944) (num-test (j1 inf.0) 0.0) (test (nan? (j1 nan.0)) #t) (num-test (j1 32.75) 0.074086803054576) (num-test (j1 1.5) 0.5579365079101) (test (nan? (erf nan.0)) #t) (num-test (erf -1) -0.84270079294971) (num-test (erf 0) 0.0) (num-test (erf 1.5) 0.96610514647531) (num-test (erf 3/4) 0.71115563365352) (num-test (erf -63) -1.0) (num-test (erf 3.1415926535898) 0.99999112385363) (num-test (erf inf.0) 1.0) (num-test (erfc inf.0) 0.0) (test (nan? (erfc nan.0)) #t) (num-test (erfc 1234567.6) 0.0) (num-test (erfc 1.5) 0.033894853524689) (num-test (erfc -1.5) 1.9661051464753) (num-test (erfc 3.0) 2.2090496998585e-05) (num-test (lgamma inf.0) inf.0) (test (nan? (lgamma nan.0)) #t) (num-test (lgamma 1.5) -0.12078223763525) (num-test (lgamma 3/4) 0.2032809514313) (num-test (lgamma 32.75) 80.688603510529) (num-test (lgamma 1.5) -0.12078223763525) (num-test (lgamma -1.5) 0.86004701537648) (num-test (fabs -1) 1.0) (num-test (fabs 0) 0.0) (num-test (fabs inf.0) inf.0) (test (nan? (fabs nan.0)) #t) (num-test (fabs 1234567.6) 1234567.6) (num-test (fabs -1234567.6) 1234567.6) (num-test (fabs -1.5) 1.5) (num-test (ceil -1) -1.0) (num-test (ceil 0) 0.0) (num-test (ceil inf.0) inf.0) (test (nan? (ceil nan.0)) #t) (num-test (ceil 1234567.6) 1234568.0) (num-test (ceil -1234567.6) -1234567.0) (num-test (ceil 1234567.5) 1234568.0) (num-test (ceil -1234567.5) -1234567.0) (num-test (ceil 32.75) 33.0) (when (not (provided? 'netbsd)) (num-test (nearbyint 1.5) 2.0) (num-test (nearbyint 3/4) 1.0) (num-test (nearbyint -63) -63.0) (num-test (nearbyint inf.0) inf.0) (test (nan? (nearbyint nan.0)) #t) (num-test (nearbyint 1234567.6) 1234568.0) (num-test (nearbyint 1234567.5) 1234568.0) (num-test (nearbyint -1234567.5) -1234568.0) (num-test (nearbyint 1/9223372036854775807) 0.0)) (num-test (rint inf.0) inf.0) (test (nan? (rint nan.0)) #t) (num-test (rint 1234567.6) 1234568.0) (num-test (rint -1234567.6) -1234568.0) (num-test (rint 1234567.5) 1234568.0) (num-test (rint -1234567.5) -1234568.0) (num-test (rint 32.75) 33.0) (num-test (rint 1.5) 2.0) (num-test (llrint 3.1415926535898) 3) (num-test (llrint 1.5707963267949) 2) (num-test (llrint 1234567.6) 1234568) (num-test (llrint -1234567.6) -1234568) (num-test (llrint 1234567.5) 1234568) (num-test (llrint -1234567.5) -1234568) (num-test (llrint 32.75) 33) (num-test (llround 1.5) 2) (num-test (llround 3/4) 1) (num-test (llround 1234567.6) 1234568) (num-test (llround -1234567.6) -1234568) (num-test (llround 1234567.5) 1234568) (num-test (llround -1234567.5) -1234568) (num-test (llround 32.75) 33) (num-test (trunc 1.5707963267949) 1.0) (num-test (trunc inf.0) inf.0) (test (nan? (trunc nan.0)) #t) (num-test (trunc 1234567.6) 1234567.0) (num-test (trunc -1234567.6) -1234567.0) (num-test (trunc 1234567.5) 1234567.0) (num-test (trunc -1234567.5) -1234567.0) (num-test (trunc 32.75) 32.0) (num-test (trunc 1.5) 1.0) (num-test (trunc -1.5) -1.0) (test (nan? (fmod nan.0 -42.0)) #t) (num-test (fmod 3.1415926535898 3) 0.14159265358979) (num-test (fmod 32.75 -1.5) 1.25) (num-test (fmod 32.75 1.5) 1.25) (num-test (ldexp -1 6) -64.0) (num-test (ldexp 0 6) 0.0) (num-test (ldexp 6 6) 384.0) (num-test (ldexp 3.0 1) 6.0) (num-test (ldexp 6 0) 6.0) (num-test (ldexp inf.0 -1) inf.0) (test (nan? (ldexp nan.0 -1)) #t) (num-test (scalbn 1.5 3) 12.0) (num-test (scalbn 3.0 6) 192.0) (num-test (scalbn 1.5 1) 3.0) (num-test (scalbn 6 -1) 3.0) (when (not (provided? 'netbsd)) (num-test (scalbln inf.0 -42) inf.0) (test (nan? (scalbln nan.0 -42)) #t) (num-test (scalbln 3.0 3) 24.0) (num-test (scalbln 0 -42) 0.0) (num-test (scalbln -1.5 6) -96.0) (num-test (scalbln 3.0 6) 192.0) (num-test (scalbln 1 -1) 0.5) (num-test (scalbln 1.5 -1) 0.75)) (num-test (exp2 -1) 0.5) (num-test (exp2 0) 1.0) (num-test (exp2 1.5) 2.8284271247462) (num-test (exp2 3/4) 1.6817928305074) (num-test (exp2 6) 64.0) (num-test (exp2 inf.0) inf.0) (test (nan? (exp2 nan.0)) #t) (num-test (expm1 inf.0) inf.0) (test (nan? (expm1 nan.0)) #t) (num-test (expm1 -1) -0.63212055882856) (num-test (expm1 0) 0.0) (num-test (expm1 1) 1.718281828459) (num-test (expm1 1.5) 3.4816890703381) (num-test (expm1 3/4) 1.1170000166127) (num-test (expm1 -63) -1.0) (num-test (log10 inf.0) inf.0) (test (nan? (log10 nan.0)) #t) (num-test (log10 32.75) 1.5152113043278) (num-test (log10 1.5) 0.17609125905568) (num-test (log10 1) 0.0) (num-test (log10 1234567.6) 6.0915148751535) (num-test (log1p inf.0) inf.0) (if (provided? 'linux) (test (nan? (log1p nan.0)) #t)) (num-test (log1p 1234567.6) 14.02623215528) (num-test (log1p 0.0) 0.0) (num-test (log1p 1) 0.69314718055995) (num-test (log1p 1.5) 0.91629073187416) (num-test (log1p 3/4) 0.55961578793542) (num-test (log2 inf.0) inf.0) (test (nan? (log2 nan.0)) #t) (num-test (log2 1234567.6) 20.235574404197) (num-test (log2 1) 0.0) (num-test (log2 32.75) 5.0334230015375) (num-test (log2 1.5) 0.58496250072116) (num-test (ilogb 3.1415926535898) 1) (num-test (ilogb 1.5707963267949) 0) (num-test (ilogb inf.0) 2147483647) (num-test (ilogb nan.0) (if (or (provided? 'freebsd) (provided? 'solaris)) 2147483647 -2147483648)) (num-test (ilogb 1234567.6) 20) (num-test (ilogb -1234567.6) 20) (num-test (ilogb 1) 0) (num-test (ilogb 3.0) 1) (num-test (cbrt inf.0) inf.0) (test (nan? (cbrt nan.0)) #t) (num-test (cbrt 1234567.6) 107.27658956435) (num-test (cbrt -1) -1.0) (num-test (cbrt 0) 0.0) (num-test (cbrt 1) 1.0) (num-test (cbrt 1.5) 1.1447142425533) (num-test (cbrt 3.0) 1.4422495703074) (num-test (hypot 0 -42.0) 42.0) (num-test (hypot 1 3) 3.1622776601684) (num-test (hypot 1.5 3) 3.3541019662497) (num-test (hypot 3/4 3) 3.0923292192132) (num-test (hypot inf.0 -1.5) inf.0) (test (nan? (hypot nan.0 -1.5)) #t) (num-test (hypot 1.5 32.75) 32.784333148625) (when (not (provided? 'netbsd)) (num-test (fma 3.0 3 -42.0) -33.0) (num-test (fma 6 -42 -42.0) -294.0) (num-test (fma 1.5 -42 -42.0) -105.0) (num-test (fma -1.5 -42 -42.0) 21.0) (num-test (fma 3.0 -42 -42.0) -168.0) (num-test (fma inf.0 1.5 -42.0) inf.0)) (test (nan? (pow nan.0 -42.0)) #t) (num-test (pow 1 3) 1.0) (num-test (pow 1.5 3) 3.375) (num-test (pow 3/4 3) 0.421875) (num-test (pow -63 3) -250047.0) (num-test (pow 6 3) 216.0) (num-test (pow 0.0 3.0) 0.0) (num-test (fdim 1.5 -42) 43.5) (num-test (fdim -1.5 -42) 40.5) (num-test (fdim 3.0 -42) 45.0) (num-test (fdim 0 -42.0) 42.0) (test (nan? (fdim 0.0 nan.0)) #t) (num-test (fdim 1 6) 0.0) (num-test (fdim 32.75 6) 26.75) (num-test (tgamma 1.5) 0.88622692545276) (num-test (tgamma 3/4) 1.2254167024652) (num-test (tgamma 3.1415926535898) 2.28803779534) (num-test (tgamma 1.5707963267949) 0.89056089038154) (num-test (tgamma inf.0) inf.0) (test (nan? (tgamma nan.0)) #t) (num-test (tgamma -1.5) 2.3632718012074) (num-test (tgamma 3.0) 2.0) (num-test (copysign -1.5 3) 1.5) (num-test (copysign 3/4 -42.0) -0.75) (num-test (copysign inf.0 3.0) inf.0) (test (nan? (copysign nan.0 3.0)) #t) (num-test (copysign 1.5 3.0) 1.5) (num-test (copysign -1.5 3.0) 1.5) (num-test (nextafter 1 -42) 1.0) (num-test (nextafter 1.5 -42) 1.5) (num-test (nextafter 3/4 -42) 0.75) (test (nan? (nextafter nan.0 -1.5)) #t) (num-test (nextafter 0 -1.5) -4.9406564584125e-324) (num-test (nexttoward 0 -42) -4.9406564584125e-324) (num-test (nexttoward 1.5 3) 1.5) (when (not (provided? 'solaris)) (num-test (isfinite inf.0) 0) (num-test (isfinite nan.0) 0) (num-test (isfinite 1234567.6) 1) (num-test (isfinite -1234567.6) 1) (num-test (isfinite 9223372036854775807) 1) (num-test (isinf inf.0) 1) (num-test (isinf nan.0) 0) (num-test (isinf 1234567.6) 0) (num-test (isinf -9223372036854775807) 0) (num-test (isinf -1) 0) (num-test (isinf 0) 0) (num-test (isnan inf.0) 0) (num-test (isnan nan.0) 1) (num-test (isnan 1234567.6) 0) (num-test (isnormal inf.0) 0) (num-test (isnormal nan.0) 0) (num-test (isnormal 1234567.6) 1) (num-test (isnormal 0) 0) (num-test (signbit 1.5) 0) (reader-cond ((provided? 'linux) (num-test (signbit -1.5) 128) (num-test (signbit -1) 128)) ((provided? 'osx) (num-test (signbit -1.5) 1) (num-test (signbit -1) 1))) (num-test (signbit 0) 0) (num-test (signbit inf.0) 0) (num-test (signbit nan.0) 0)) (num-test (floor 1.5) 1.0) (num-test (floor 3/4) 0.0) (num-test (floor -63) -63.0) (num-test (floor inf.0) inf.0) (test (nan? (floor nan.0)) #t) (num-test (floor 1234567.6) 1234567.0) (num-test (floor -1234567.6) -1234568.0) (num-test (floor 1234567.5) 1234567.0) (num-test (floor -1234567.5) -1234568.0) (num-test (floor 32.75) 32.0) (num-test (floor 1.5) 1.0) (num-test (floor -1.5) -2.0) (num-test (round inf.0) inf.0) (test (nan? (round nan.0)) #t) (num-test (round 1234567.6) 1234568.0) (num-test (round -1234567.6) -1234568.0) (num-test (round 1234567.5) 1234568.0) (num-test (round -1234567.5) -1234568.0) (num-test (round 32.75) 33.0) (num-test (round 1.5) 2.0) (num-test (round -1.5) -2.0) (test (nan? (remainder nan.0 -42)) #t) (num-test (remainder 1234567.6 -42) 19.600000000093) (num-test (remainder -63 3.0) 0.0) (num-test (remainder 32.75 3.0) -0.25) (test (nan? (remainder 3.0 nan.0)) #t) (num-test (remainder -1.5 3/4) 0.0) (num-test (exp 1.5707963267949) 4.8104773809654) (num-test (exp inf.0) inf.0) (test (nan? (exp nan.0)) #t) (num-test (exp -1) 0.36787944117144) (num-test (exp 0) 1.0) (num-test (exp 1.5) 4.4816890703381) (num-test (exp 3/4) 2.1170000166127) (num-test (log 6) 1.7917594692281) (num-test (log 3.1415926535898) 1.1447298858494) (num-test (log 1.5707963267949) 0.45158270528945) (num-test (log inf.0) inf.0) (test (nan? (log nan.0)) #t) (num-test (log 1234567.6) 14.02623134528) (num-test (log 32.75) 3.4889029620813) (num-test (log 1.5) 0.40546510810816) (num-test (sqrt 0.0) 0.0) (num-test (sqrt 1) 1.0) (num-test (sqrt 1.5) 1.2247448713916) (num-test (sqrt 3/4) 0.86602540378444) (num-test (sqrt 6) 2.4494897427832) (num-test (sqrt 3.1415926535898) 1.7724538509055) (num-test (sqrt 1.5707963267949) 1.2533141373155) (num-test (sqrt inf.0) inf.0) (test (nan? (sqrt nan.0)) #t) (num-test (sqrt 1234567.6) 1111.1109755555) (num-test (cos 0.0) 1.0) (num-test (cos 1) 0.54030230586814) (num-test (cos 1.5) 0.070737201667703) (num-test (cos 3/4) 0.73168886887382) (num-test (cos -63) 0.98589658158255) (num-test (cos 6) 0.96017028665037) (num-test (cos 3.1415926535898) -1.0) (num-test (cos 1.5707963267949) 6.1232339957368e-17) (test (nan? (cos nan.0)) #t) (num-test (cos 1234567.6) -0.97435594756269) (num-test (sin 0.0) 0.0) (num-test (sin 1) 0.8414709848079) (num-test (sin 1.5) 0.99749498660405) (num-test (sin 3/4) 0.68163876002333) (num-test (sin -63) -0.16735570030281) (num-test (sin 6) -0.27941549819893) (num-test (sin 3.1415926535898) 1.2246467991474e-16) (num-test (sin 1.5707963267949) 1.0) (test (nan? (sin nan.0)) #t) (num-test (sin 1234567.6) -0.22501219400117) (num-test (tan 0.0) 0.0) (num-test (tan 1) 1.5574077246549) (num-test (tan 1.5) 14.101419947172) (num-test (tan 3/4) 0.93159645994407) (num-test (tan -63) -0.16974975208269) (num-test (tan 6) -0.29100619138475) (num-test (tan 3.1415926535898) -1.2246467991474e-16) (test (nan? (tan nan.0)) #t) (num-test (tan 1234567.6) 0.23093428491305) (num-test (sinh 0.0) 0.0) (num-test (sinh 1) 1.1752011936438) (num-test (sinh 1.5) 2.1292794550948) (num-test (sinh 3/4) 0.82231673193583) (num-test (sinh -63) -1.1468915797348e+27) (num-test (sinh 6) 201.71315737028) (num-test (sinh 3.1415926535898) 11.548739357258) (num-test (sinh 1.5707963267949) 2.3012989023073) (num-test (sinh inf.0) inf.0) (test (nan? (sinh nan.0)) #t) (num-test (sinh 1234567.6) inf.0) (num-test (tanh 0.0) 0.0) (num-test (tanh 1) 0.76159415595576) (num-test (tanh 1.5) 0.90514825364487) (num-test (tanh 3/4) 0.63514895238729) (num-test (tanh -63) -1.0) (num-test (tanh 6) 0.9999877116508) (num-test (tanh 3.1415926535898) 0.99627207622075) (num-test (tanh 1.5707963267949) 0.91715233566727) (num-test (tanh inf.0) 1.0) (test (nan? (tanh nan.0)) #t) (num-test (tanh 1234567.6) 1.0) (num-test (acos 1) 0.0) (num-test (acos 3/4) 0.72273424781342) (test (nan? (acos 1.5707963267949)) #t) (num-test (acos -1) 3.1415926535898) (num-test (acos 0) 1.5707963267949) (num-test (asin 0.0) 0.0) (num-test (asin 1) 1.5707963267949) (test (nan? (asin inf.0)) #t) (test (nan? (asin nan.0)) #t) (num-test (asin 3/4) 0.84806207898148) (num-test (atan 0.0) 0.0) (num-test (atan 1) 0.78539816339745) (num-test (atan 1.5) 0.98279372324733) (num-test (atan 3/4) 0.64350110879328) (num-test (atan -63) -1.5549246438031) (num-test (atan 6) 1.4056476493803) (num-test (atan 3.1415926535898) 1.2626272556789) (num-test (atan 1.5707963267949) 1.0038848218539) (num-test (atan inf.0) 1.5707963267949) (test (nan? (atan nan.0)) #t) (num-test (atan 1234567.6) 1.5707955167947) (test (nan? (atan2 nan.0 3.0)) #t) (num-test (atan2 -1 3) -0.32175055439664) (num-test (atan2 -1 32.75) -0.030524866917203) (num-test (atan2 0.0 3) 0.0) (num-test (atan2 1 3) 0.32175055439664) (num-test (atan2 1.5 3) 0.46364760900081) (num-test (atan2 3/4 3) 0.24497866312686) (num-test (atan2 -63 3) -1.5232132235179) (num-test (acosh 1) 0.0) (num-test (acosh 1.5) 0.96242365011921) (num-test (acosh 6) 2.4778887302885) (num-test (acosh 3.1415926535898) 1.8115262724609) (num-test (acosh 1.5707963267949) 1.0232274785476) (num-test (acosh inf.0) inf.0) (test (nan? (acosh nan.0)) #t) (num-test (acosh 1234567.6) 14.71937852584) (num-test (asinh 0.0) 0.0) (num-test (asinh 1) 0.88137358701954) (num-test (asinh 1.5) 1.1947632172871) (num-test (asinh 3/4) 0.69314718055995) (num-test (asinh -63) -4.8363448891593) (num-test (asinh 6) 2.4917798526449) (num-test (asinh 3.1415926535898) 1.8622957433108) (num-test (asinh 1.5707963267949) 1.2334031175112) (num-test (asinh inf.0) inf.0) (test (nan? (asinh nan.0)) #t) (num-test (asinh 1234567.6) 14.71937852584) (num-test (atanh 0.0) 0.0) (num-test (atanh 3/4) 0.97295507452766) (test (nan? (atanh nan.0)) #t) (morally-equal? (remquo -42.0 -42.0) '(0.0 1)) (morally-equal? (remquo 1234567.5 3) '(1.5 2)) (morally-equal? (remquo 3.1415926535898 3) '(0.14159265358979 1)) (morally-equal? (remquo -63 3.0) '(0.0 -5)) (morally-equal? (remquo 1 -1.5) '(-0.5 -1)) (morally-equal? (remquo 3/4 1.5) '(0.75 0)) (morally-equal? (frexp 0.0) '(0.0 0)) (morally-equal? (frexp 1) '(0.5 1)) (morally-equal? (frexp 1.5) '(0.75 1)) (morally-equal? (frexp 3/4) '(0.75 0)) (morally-equal? (frexp -63) '(-0.984375 6)) (morally-equal? (frexp 6) '(0.75 3)) (morally-equal? (frexp 3.1415926535898) '(0.78539816339745 2)) (morally-equal? (frexp 1.5707963267949) '(0.78539816339745 1)) (morally-equal? (frexp inf.0) '(inf.0 0)) (morally-equal? (frexp nan.0) '(nan.0 0)) (morally-equal? (frexp 1234567.6) '(0.58868770599365 21)) (morally-equal? (modf 0.0) '(0.0 0.0)) (morally-equal? (modf 1) '(0.0 1.0)) (morally-equal? (modf 1.5) '(0.5 1.0)) (morally-equal? (modf 3/4) '(0.75 0.0)) (morally-equal? (modf -63) '(0.0 -63.0)) (morally-equal? (modf 6) '(0.0 6.0)) (morally-equal? (modf 3.1415926535898) '(0.14159265358979 3.0)) (morally-equal? (modf 1.5707963267949) '(0.5707963267949 1.0)) (morally-equal? (modf inf.0) '(0.0 inf.0)) (morally-equal? (modf nan.0) '(nan.0 nan.0)) (morally-equal? (modf 1234567.6) '(0.60000000009313 1234567.0)) )))) ;; now check for leaks (test (defined? 'remquo) #f) (test (defined? 'M_LN2) #f) (num-test (sin 1+i) 1.298457581415977+0.6349639147847361i) (test (integer? (round 123.3)) #t) ;;; -------------------------------------------------------------------------------- ;;; libc (if (not (provided? 'windows)) (let () (require libc.scm) (when (and (defined? '*libc*) (procedure? (*libc* 'passwd_pw_name))) (with-let (sublet *libc*) (test (let ((buf (make-string 20 #\null))) (strcat buf "All ") (strcat buf "for ") (strcat buf "one.") (substring buf 0 12)) "All for one.") (test (strcmp "a" "b") -1) (test (strcmp "a" "a") 0) (test (strncmp "1234" "1235" 3) 0) (test (strcpy (make-string 3) "123") "123") (test (strlen "123") 3) (test (strchr "12345" (char->integer #\3)) "345") (test (strspn "12345" "123") 3) (test (isalpha (char->integer #\.)) 0) (test (zero? (isdigit (char->integer #\2))) #f) (test (integer->char (toupper (char->integer #\a))) #\A) (test (let ((buf (malloc 3))) (memset buf 90 3) (let ((result (c-pointer->string buf 3))) (free buf) result)) "ZZZ") (define get-environment-variable getenv) (define get-environment-variables getenvs) (define* (set-environment-variable x v (overwrite #t)) (setenv x v (if overwrite 1 0))) (define delete-environment-variable unsetenv) (define (file-exists? file) (= (access file F_OK) 0)) (define delete-file unlink) ;; system can be used as is (define* (ls dir-name (port *stderr*)) (let ((dir (opendir dir-name))) (do ((p (read_dir dir) (read_dir dir))) ((= (length p) 0)) (format port "~A " p)) (closedir dir))) (define (directory->list dir-name) (let ((lst ()) (dir (opendir dir-name))) (do ((p (read_dir dir) (read_dir dir))) ((= (length p) 0)) (if (not (member p '("." ".."))) (set! lst (cons p lst)))) ; read_dir in libc.scm returns dpos->d_name (closedir dir) lst)) (define (memory-usage) (let ((v (rusage.make))) (getrusage RUSAGE_SELF v) (let ((mem (rusage.ru_maxrss v))) (free v) (* 1024 mem)))) (define (os-type) (car (uname))) (define (cpu-architecture) (cadr (uname))) (define (machine-name) (caddr (uname))) (define (os-version) (string-append (list-ref (uname) 3) " " (list-ref (uname) 4))) (define (implementation-name) "s7") (define (implementation-version) (substring (s7-version) 3 7)) (reader-cond ((and (not (provided? 'openbsd)) (not (provided? 'solaris))) (define (word-size) __WORDSIZE))) (reader-cond ((and (not (provided? 'openbsd)) (not (provided? 'solaris))) (define (little-endian?) (= __BYTE_ORDER __LITTLE_ENDIAN)))) (define (command-line) (let ((lst ())) (with-input-from-file "/proc/self/cmdline" (lambda () (do ((c (read-char) (read-char)) (s "")) ((eof-object? c) (reverse lst)) (if (char=? c #\null) (begin (set! lst (cons s lst)) (set! s "")) (set! s (string-append s (string c))))))))) (define (daytime) (let ((timestr (make-string 64))) (let ((len (strftime timestr 64 "%a %d-%b-%Y %H:%M %Z" (localtime (time.make (time (c-pointer 0))))))) (substring timestr 0 len)))) (define (write-date file) (let ((buf (stat.make))) (and (stat file buf) (stat.st_mtime buf)))) (define (file-write-date->string file) (let ((timestr (make-string 64))) (let ((len (strftime timestr 64 "%a %d-%b-%Y %H:%M %Z" (localtime (time.make (write-date file)))))) (substring timestr 0 len)))) (define (copy-file in-file out-file) (with-let (sublet *libc* (inlet 'in-file in-file 'out-file out-file)) (let ((infd (open in-file O_RDONLY 0))) (if (= infd -1) (error 'io-error "can't find ~S~%" in-file) (let ((outfd (creat out-file #o666))) (if (= outfd -1) (begin (close infd) (error 'io-error "can't open ~S~%" out-file)) (let* ((BUF_SIZE 1024) (buf (malloc BUF_SIZE))) (do ((num (read infd buf BUF_SIZE) (read infd buf BUF_SIZE))) ((or (<= num 0) (not (= (write outfd buf num) num))))) (close outfd) (close infd) (free buf) out-file))))))) (define (tty-direct) ; run in a non-GUI repl (with-let (sublet *libc*) (call-with-exit (lambda (quit) (let ((saved (termios.make)) (fn (fileno stdin))) (define (tty_reset fd) (tcsetattr fd TCSAFLUSH saved)) (define (sigcatch no) (tty_reset fn) (quit)) (if (or (equal? (signal SIGINT sigcatch) SIG_ERR) (equal? (signal SIGQUIT sigcatch) SIG_ERR) (equal? (signal SIGTERM sigcatch) SIG_ERR) (negative? (tcgetattr fn saved))) (quit)) (let ((buf (termios.make)) (c (string #\null #\null))) (let ((cc (string->c-pointer c))) (tcgetattr fn buf) (termios.set_c_lflag buf (logand (termios.c_lflag buf) (lognot (logior ECHO ICANON)))) (termios.set_c_cc buf VMIN 1) (termios.set_c_cc buf VTIME 0) (if (negative? (tcsetattr fn TCSAFLUSH buf)) (quit)) (do ((i (read fn cc 1) (read fn cc 1))) ((not (= i 1)) (tty_reset fn) (quit)) (format *stderr* "got ~C~%" (c 0)))))))))) ;; to write a directory files + file size: ;; (ftw "/home/bil/sf1" (lambda (a b c) (format *stderr* "~A ~A~%" a (stat.st_size b)) 0) 10) (define (directory? file) (let ((buf (stat.make))) (let ((result (and (stat file buf) (S_ISDIR (stat.st_mode buf))))) (free buf) result))) (define* (home-directory name) (if (not name) (getenv "HOME") (passwd.pw_dir (getpwnam name)))) (define (file-length file) (let ((buf (stat.make))) (stat file buf) (let ((result (stat.st_size buf))) (free buf) result))) (define (system-limits) (list 'arg-max (sysconf _SC_ARG_MAX) 'login-max (sysconf _SC_LOGIN_NAME_MAX) 'open-max (sysconf _SC_OPEN_MAX) 'groups-max (sysconf _SC_NGROUPS_MAX) 'page-size (sysconf _SC_PAGESIZE))) (test (string? (get-environment-variable "HOME")) #t) (test (integer? (random)) #t) (test (assq 'decimal_point (localeconv)) '(decimal_point . ".")) (test (string? (getlogin)) #t) (test (integer? (getpid)) #t) (test (integer? _POSIX_VERSION) #t) (if (provided? 'linux) (test (>= __GLIBC__ 2) #t)) (test (c-null? (c-pointer 0)) #t) (test (fnmatch "*.c" "s7.c" FNM_PATHNAME) 0) (test (string? (realpath "s7.c" ".")) #t) (test (passwd.pw_name (getpwnam (getlogin))) (getlogin)) (test (string? (passwd.pw_shell (getpwnam (getlogin)))) #t) (reader-cond ((not (provided? 'openbsd)) (test (string? (car (let ((w (wordexp.make))) (wordexp "~/cl/snd-gdraw" w 0) (wordexp.we_wordv w)))) #t))) (test (pair? (system-limits)) #t) (test (> (file-length "s7test.scm") 4000000) #t) (test (string? (home-directory)) #t) (test (directory? (home-directory)) #t) (test (string? (file-write-date->string "s7test.scm")) #t) (if (provided? 'linux) (test (string? (car (command-line))) #t)) (test (string? (daytime)) #t) (reader-cond ((and (not (provided? 'openbsd)) (not (provided? 'solaris))) (test (not (member (word-size) '(32 64))) #f))) (reader-cond ((provided? 'linux) (test (os-type) "Linux")) ((provided? 'osx) (test (os-type) "Darwin")) ((provided? 'freebsd) (test (os-type) "FreeBSD")) ((provided? 'netbsd) (test (os-type) "NetBSD")) ((provided? 'openbsd) (test (os-type) "OpenBSD")) ((provided? 'solaris) (test (os-type) "SunOS")) (#t (test (os-type) "Unknown"))) (test (integer? (memory-usage)) #t) (test (file-exists? "s7test.scm") #t) (test (atoi "123") 123) (test (llabs -1234) 1234) (test (strtod "1.5") 1.5) (test CLOCKS_PER_SEC 1000000) (test (group.gr_name (getgrnam "wheel")) "wheel") (test (let ((g (glob.make))) (glob "s7t*.scm" 0 g) (let ((res (glob.gl_pathv g))) (globfree g) res)) '("s7test.scm")) )))) ;;; -------------------------------------------------------------------------------- ;;; libgsl (if (or (provided? 'linux) (provided? 'osx)) (let () (require libgsl.scm) (when (and (defined? '*libgsl*) (procedure? (*libgsl* 'gsl_vector_equal))) (with-let (sublet *libgsl*) (define (eigenvalues M) (with-let (sublet *libgsl* (inlet 'M M)) (let* ((len (sqrt (length M))) (gm (gsl_matrix_alloc len len)) (m (float-vector->gsl_matrix M gm)) (evl (gsl_vector_complex_alloc len)) (evc (gsl_matrix_complex_alloc len len)) (w (gsl_eigen_nonsymmv_alloc len))) (gsl_eigen_nonsymmv m evl evc w) (gsl_eigen_nonsymmv_free w) (gsl_eigen_nonsymmv_sort evl evc GSL_EIGEN_SORT_ABS_DESC) (let ((vals (make-vector len))) (do ((i 0 (+ i 1))) ((= i len)) (set! (vals i) (gsl_vector_complex_get evl i))) (gsl_matrix_free gm) (gsl_vector_complex_free evl) (gsl_matrix_complex_free evc) vals)))) (test (eigenvalues (float-vector 3 1 1 3)) #(4.0 2.0)) (test (eigenvalues (float-vector 1 2 4 3)) #(5.0 -1.0)) (num-test GSL_CONST_CGS_LIGHT_YEAR 9.460536207070001e+17) (num-test (GSL_SIGN -123) -1) (test (GSL_IS_ODD 4) #f) (test (integer? GSL_SF_FACT_NMAX) #t) (num-test (gsl_sf_airy_Ai -500.0 GSL_MODE_DEFAULT) 0.07259012010418163) (num-test (gsl_sf_airy_Bi -500.0 GSL_MODE_DEFAULT) -0.0946885701328829) (num-test (gsl_sf_airy_Ai_scaled -5.0 GSL_MODE_DEFAULT) 0.3507610090241141) (num-test (gsl_sf_airy_Bi_scaled -5.0 GSL_MODE_DEFAULT) -0.1383691349016009) (num-test (gsl_sf_airy_Ai_deriv -5.0 GSL_MODE_DEFAULT) 0.3271928185544435) (num-test (gsl_sf_airy_Bi_deriv -5.0 GSL_MODE_DEFAULT) 0.778411773001899) (num-test (gsl_sf_airy_Ai_deriv_scaled -5.0 GSL_MODE_DEFAULT) 0.3271928185544435) (num-test (gsl_sf_airy_Bi_deriv_scaled -5.0 GSL_MODE_DEFAULT) 0.778411773001899) (num-test (gsl_sf_airy_zero_Ai_deriv 2) -3.248197582179837) (num-test (gsl_sf_airy_zero_Bi_deriv 2) -4.073155089071828) (num-test (gsl_sf_bessel_J0 1.0) 0.7651976865579666) (num-test (let ((sfr (gsl_sf_result.make))) (gsl_sf_bessel_J0_e 1.0 sfr) (gsl_sf_result.val sfr)) 0.7651976865579666) (num-test (let ((sfr (gsl_sf_result.make))) (gsl_sf_bessel_J0_e 1.0 sfr) (gsl_sf_result.err sfr)) 6.72613016567227e-16) (num-test (gsl_sf_bessel_J0 .1) 0.9975015620660401) (num-test (gsl_sf_bessel_J1 .1) 0.049937526036242) (num-test (gsl_sf_bessel_Jn 45 900.0) 0.02562434700634277) (num-test (gsl_sf_bessel_Y0 .1) -1.534238651350367) (num-test (gsl_sf_bessel_Y1 .1) -6.458951094702027) (num-test (gsl_sf_bessel_Yn 4 .1) -305832.2979335312) (num-test (gsl_sf_bessel_I0_scaled .1) 0.9071009257823011) (num-test (gsl_sf_bessel_I1_scaled .1) 0.04529844680880932) (num-test (gsl_sf_bessel_In_scaled 4 .1) 2.35752586200546e-07) (num-test (gsl_sf_bessel_I0 .1) 1.002501562934096) (num-test (gsl_sf_bessel_I1 .1) 0.05006252604709269) (num-test (gsl_sf_bessel_In 4 .1) 2.605469021299657e-07) (num-test (gsl_sf_bessel_K0_scaled .1) 2.682326102262894) (num-test (gsl_sf_bessel_K1_scaled .1) 10.8901826830497) (num-test (gsl_sf_bessel_Kn_scaled 4 .1) 530040.2483725621) (num-test (gsl_sf_bessel_K0 .1) 2.427069024702016) (num-test (gsl_sf_bessel_K1 .1) 9.853844780870606) (num-test (gsl_sf_bessel_Kn 4 .1) 479600.2497925678) (num-test (gsl_sf_bessel_j0 1.0) 0.8414709848078965) (num-test (gsl_sf_bessel_j1 1.0) 0.3011686789397567) (num-test (gsl_sf_bessel_j2 1.0) 0.06203505201137386) (num-test (gsl_sf_bessel_jl 5 1.0) 9.256115861125814e-05) (num-test (gsl_sf_bessel_zero_J0 1) 2.404825557695771) (num-test (gsl_sf_bessel_zero_Jnu 5 5) 22.21779994656127) (num-test (gsl_sf_hydrogenicR_1 3 2) 0.02575994825614847) (num-test (gsl_sf_dilog -3.0) -1.939375420766708) (let ((s1 (gsl_sf_result.make)) (s2 (gsl_sf_result.make))) (gsl_sf_complex_dilog_e 0.99999 (/ pi 2) s1 s2) (num-test (gsl_sf_result.val s1) -0.2056132926277968) (num-test (gsl_sf_result.val s2) 0.9159577401813151)) (let ((s1 (gsl_sf_result.make)) (s2 (gsl_sf_result.make))) (gsl_sf_complex_spence_xy_e 0.5 0.0 s1 s2) (num-test (gsl_sf_result.val s1) 0.5822405264650126) (num-test (gsl_sf_result.val s2) 0.0)) (num-test (gsl_sf_lngamma -0.1) 2.368961332728787) (num-test (gsl_sf_gamma 9.0) 40320.0) (num-test (gsl_sf_gammastar 9.0) 1.009298426421819) (num-test (gsl_sf_gammainv -1.0) 0.0) (let ((s1 (gsl_sf_result.make)) (s2 (gsl_sf_result.make))) (gsl_sf_lngamma_complex_e 5.0 2.0 s1 s2) (num-test (gsl_sf_result.val s1) 2.748701756133804) (num-test (gsl_sf_result.val s2) 3.073843410049702)) (num-test (gsl_sf_taylorcoeff 10 5) 2.691144455467373) (num-test (gsl_sf_choose 7 3) 35.0) (num-test (gsl_sf_poch 7 3) 504.0000000000001) (num-test (gsl_sf_gamma_inc_P 1.0 10.0) 0.9999546000702381) (num-test (gsl_sf_lnbeta 0.1 1.0) 2.302585092994044) (num-test (gsl_sf_beta 100.1 -1.2) 1203.895236907804) (num-test (gsl_sf_hyperg_0F1 1 0.5) 1.56608292975635) (num-test (gsl_sf_hyperg_1F1 1 1.5 1) 2.030078469278705) (num-test (gsl_sf_hyperg_U_int 100 100 1) 0.009998990209084679) (num-test (gsl_sf_hyperg_2F1 1 1 1 0.5) 2.0) (num-test (gsl_sf_legendre_P1 -0.5) -0.5) (num-test (gsl_sf_legendre_sphPlm 10 0 -0.5) -0.2433270236930014) (num-test (gsl_sf_legendre_Q0 -0.5) -0.5493061443340549) (num-test (gsl_sf_clausen (+ (* 2 pi) (/ pi 3))) 1.014941606409653) (num-test (gsl_sf_coupling_3j 0 1 1 0 1 -1) 0.7071067811865476) (num-test (gsl_sf_dawson 0.5) 0.4244363835020223) (num-test (gsl_sf_multiply -3 2) -6.0) (num-test (gsl_sf_ellint_E (/ pi 2) 0.5 GSL_MODE_DEFAULT) 1.467462209339427) (num-test (gsl_sf_erfc -10) 2.0) (num-test (gsl_sf_exp_mult 10 -2) -44052.93158961344) (num-test (gsl_sf_expm1 -.001) -0.0009995001666250082) (num-test (gsl_sf_Shi -1) -1.057250875375728) (num-test (gsl_sf_fermi_dirac_0 -1) 0.3132616875182229) (num-test (gsl_sf_gegenpoly_1 1.0 1.0) 2.0) (let ((p (float-vector 1.0 -2.0 1.0)) (res (vector 0.0 0.0))) (gsl_poly_complex_solve (double* p) 3 res) (test res #(1.0 1.0))) (let ((p (float-vector 1 -1 1 -1 1 -1 1 -1 1 -1 1))) (num-test (gsl_poly_eval (double* p) 11 1.0) 1.0)) (let ((p (float-vector 2.1 -1.34 0.76 0.45))) (num-test (gsl_poly_complex_eval (double* p) 4 0.49+0.95i) 0.3959142999999998-0.6433305000000001i)) (let ((res (float-vector 0.0 0.0))) (let ((err (gsl_poly_solve_quadratic 4.0 -20.0 26.0 (double* res)))) (test err 0))) (let ((res (float-vector 0.0 0.0))) (let ((err (gsl_poly_solve_quadratic 4.0 -20.0 21.0 (double* res)))) (test res (float-vector 1.5 3.5)))) (let ((res (float-vector 0.0 0.0 0.0))) (let ((err (gsl_poly_solve_cubic -51 867 -4913 (double* res)))) (test res (float-vector 17.0 17.0 17.0)))) (let ((res (vector 0.0 0.0))) (let ((err (gsl_poly_complex_solve_quadratic 4.0 -20.0 26.0 res))) (test res #(2.5-0.5i 2.5+0.5i)))) (let ((res (vector 0.0 0.0 0.0))) ; workspace handling is internal (let ((err (gsl_poly_complex_solve_cubic -51 867 -4913 res))) (test res #(17.0 17.0 17.0)))) (num-test (gsl_hypot3 1.0 1.0 1.0) (sqrt 3)) (num-test (gsl_hypot 1.0 1.0) (sqrt 2)) (test (nan? (gsl_nan)) #t) (test (infinite? (gsl_posinf)) #t) (test (gsl_frexp 2.0) '(0.5 2)) (num-test (gsl_pow_2 4) 16.0) (num-test (gsl_cdf_ugaussian_P 0.0) 0.5) (num-test (gsl_cdf_ugaussian_P 0.5) 0.691462461274013) (num-test (gsl_cdf_ugaussian_Q 0.5) 0.3085375387259869) (num-test (gsl_cdf_ugaussian_Pinv 0.5) 0.0) (num-test (gsl_cdf_ugaussian_Qinv 0.5) 0.0) (num-test (gsl_cdf_exponential_P 0.1 0.7) 0.1331221002498184) (num-test (gsl_cdf_exponential_Q 0.1 0.7) 0.8668778997501816) (num-test (gsl_cdf_exponential_Pinv 0.13 0.7) 0.09748344713345537) (num-test (gsl_cdf_exponential_Qinv 0.86 0.7) 0.1055760228142086) (num-test (gsl_cdf_exppow_P -0.1 0.7 1.8) 0.4205349082867516) (num-test (gsl_cdf_exppow_Q -0.1 0.7 1.8) 0.5794650917132484) (num-test (gsl_cdf_tdist_P 0.0 1.0) 0.5) (num-test (gsl_cdf_tdist_Q 0.0 1.0) 0.5) (num-test (gsl_cdf_fdist_P 0.0 1.0 1.3) 0.0) (num-test (gsl_cdf_fdist_Q 0.0 1.0 1.3) 1.0) (num-test (gsl_cdf_fdist_Pinv 0.0 1.0 1.3) 0.0) (num-test (gsl_cdf_fdist_Qinv 1.0 1.0 1.3) 0.0) (num-test (gsl_cdf_gamma_P 0 1 1) 0.0) (num-test (gsl_cdf_gamma_Q 0 1 1) 1.0) (num-test (gsl_cdf_chisq_P 0 13) 0.0) (num-test (gsl_cdf_chisq_Q 0 13) 1.0) (num-test (gsl_cdf_beta_P 0 1.2 1.3) 0.0) (num-test (gsl_cdf_beta_Q 0 1.2 1.3) 1.0) #| ;; this is *very* slow! (let ((d (gsl_dht_new 128 1.0 1.0)) (f_in (make-float-vector 128 0.0)) (f_out (make-float-vector 128 0.0))) (do ((i 0 (+ i 1))) ((= i 128)) (let ((x (gsl_dht_x_sample d i))) (set! (f_in i) (* x (- 1.0 (* x x)))))) (gsl_dht_apply d (double* f_in) (double* f_out)) (let ((res (list (f_out 0) (f_out 5)))) (gsl_dht_free d) (num-test (res 0) 0.05727421417071144) (num-test (res 1) -0.0001908501261051786))) |# (num-test (gsl_stats_mean (double* (float-vector 1.0 2.0 3.0 4.0)) 1 4) 2.5) (num-test (gsl_stats_skew (double* (float-vector 1.0 2.0 3.0 4.0)) 1 4) 0.0) (num-test (gsl_stats_max (double* (float-vector 1.0 2.0 3.0 4.0)) 1 4) 4.0) (let ((rng (gsl_rng_alloc gsl_rng_default))) (test (real? (gsl_ran_exponential rng 1.0)) #t) (gsl_rng_free rng)) (num-test (gsl_complex_log 1+i) (log 1+i)) (num-test (gsl_complex_abs 1+i) (magnitude 1+i)) (num-test (gsl_complex_sin 1+i) (sin 1+i)) (let ((gs (gsl_cheb_alloc 40))) (gsl_cheb_init gs (lambda (x) x) -1.0 1.0) (num-test (gsl_cheb_eval gs -1.0) -1.0) (num-test (gsl_cheb_eval gs 0.0) 0.0) (num-test (gsl_cheb_eval gs 1.0) 1.0) (gsl_cheb_free gs)) (let ((x (float-vector 0.0)) (y (float-vector 0.0))) (gsl_deriv_central (lambda (x) (expt x 1.5)) 2.0 1e-8 (double* x) (double* y)) (num-test (x 0) (* 1.5 (sqrt 2))) (gsl_deriv_forward (lambda (x) (expt x 1.5)) 0.0 1e-8 (double* x) (double* y)) (num-test (x 0) 0.0)) (let ((f (float-vector -1 3 0 4 2 6))) (gsl_sort (double* f) 1 6) (test f (float-vector -1 0 2 3 4 6))) (let ((g1 (gsl_vector_alloc 3)) (g2 (gsl_vector_alloc 3)) (f1 (make-float-vector 3))) (gsl_vector_add (float-vector->gsl_vector (float-vector 0 1 2) g1) (float-vector->gsl_vector (float-vector 3 4 5) g2)) (gsl_vector->float-vector g1 f1) (gsl_vector_free g1) (gsl_vector_free g2) (test f1 (float-vector 3 5 7))) (let ((f (make-float-vector '(3 3)))) (let ((g (gsl_matrix_alloc 3 3))) (gsl_matrix_set_identity g) (do ((i 0 (+ i 1))) ((= i 3) (gsl_matrix_free g)) (do ((j 0 (+ j 1))) ((= j 3)) (set! (f i j) (gsl_matrix_get g i j))))) (test (morally-equal? f #2D((1.0 0.0 0.0) (0.0 1.0 0.0) (0.0 0.0 1.0))) #t)) (let ((f (make-vector '(3 3)))) (let ((g (gsl_matrix_complex_alloc 3 3))) (gsl_matrix_complex_set_identity g) (gsl_matrix_complex_scale g 1+i) (do ((i 0 (+ i 1))) ((= i 3) (gsl_matrix_complex_free g)) (do ((j 0 (+ j 1))) ((= j 3)) (set! (f i j) (gsl_matrix_complex_get g i j))))) (test (morally-equal? f #2D((1+i 0.0 0.0) (0.0 1+i 0.0) (0.0 0.0 1+i))) #t)) (let ((Y (float-vector 0.554)) (A (float-vector -0.047)) (X (float-vector 0.672))) (cblas_dgemv 101 111 1 1 -0.3 (double* A) 1 (double* X) -1 -1 (double* Y) -1) (num-test (Y 0) -0.5445248)) (let ((Y (float-vector 0.348 0.07)) (A (float-vector 0.932 -0.724)) (X (float-vector 0.334 -0.317)) (alpha (float-vector 0 .1)) (beta (float-vector 1 0))) (cblas_zgemv 101 111 1 1 (double* alpha) (double* A) 1 (double* X) -1 (double* beta) (double* Y) -1) (num-test (Y 0) 0.401726) (num-test (Y 1) 0.078178)) (test (let ((f (float-vector 0 1 2 3 4))) (gsl_interp_bsearch (double* f) 1.5 0 4)) 1) (let ((x (make-float-vector 10)) (y (make-float-vector 10))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (x i) (+ i (* 0.5 (sin i)))) (set! (y i) (+ i (cos (* i i))))) (let ((acc (gsl_interp_accel_alloc)) (spline (gsl_spline_alloc gsl_interp_cspline 10))) (gsl_spline_init spline (double* x) (double* y) 10) (let ((res (gsl_spline_eval spline (x 5) acc))) (gsl_spline_free spline) (gsl_interp_accel_free acc) (num-test res 5.991202811863474)))) (let ((c (gsl_combination_alloc 6 3)) (data #2d((0 1 2) (0 1 3) (0 1 4) (0 1 5) (0 2 3) (0 2 4) (0 2 5) (0 3 4) (0 3 5) (0 4 5) (1 2 3) (1 2 4) (1 2 5) (1 3 4) (1 3 5) (1 4 5) (2 3 4) (2 3 5) (2 4 5) (3 4 5))) (iv (make-vector 3 0 #t))) (gsl_combination_init_first c) (do ((i 0 (+ i 1))) ((= i 20)) ((*libgsl* 'gsl_combination->int-vector) c iv) (if (not (morally-equal? iv (data i))) (format *stderr* ";gsl_combination: ~A ~A~%" iv (data i))) (gsl_combination_next c)) (gsl_combination_free c)) (let ((p (gsl_permutation_alloc 3)) (data (make-vector 18 0 #t))) (gsl_permutation_init p) (do ((pp GSL_SUCCESS (gsl_permutation_next p)) (i 0 (+ i 3))) ((not (= pp GSL_SUCCESS))) (set! (data i) (gsl_permutation_get p 0)) (set! (data (+ i 1)) (gsl_permutation_get p 1)) (set! (data (+ i 2)) (gsl_permutation_get p 2))) (gsl_permutation_free p) (test (morally-equal? data #(0 1 2 0 2 1 1 0 2 1 2 0 2 0 1 2 1 0)) #t)) (let ((N 50)) (let ((t (make-float-vector N 0.0))) (do ((i 0 (+ i 1))) ((= i N)) (set! (t i) (/ 1.0 (* (+ i 1) (+ i 1))))) (let ((zeta_2 (/ (* pi pi) 6.0))) (let ((accel (float-vector 0.0)) (err (float-vector 0.0)) (w (gsl_sum_levin_u_alloc N))) (gsl_sum_levin_u_accel (double* t) N w (double* accel) (double* err)) (num-test zeta_2 (accel 0)) (gsl_sum_levin_u_free w))))) (let ((data (float-vector 0 0 1 0 1 1 0 -1)) ; complex data as rl+im coming and going (output (make-float-vector 8 0.0))) (gsl_dft_complex_forward (double* data) 1 4 (double* output)) ;; = -1 in snd terminology: (cfft! (vector 0 1 1+i 0-i) 4 -1): #(2.0 0-2i 0+2i -2.0) (test (morally-equal? output (float-vector 2.0 0.0 0.0 -2.0 0.0 2.0 -2.0 0.0)) #t)) (let ((data (float-vector 0 0 1 0 1 1 0 -1))) ; complex data as rl+im coming and going (gsl_fft_complex_radix2_forward (double* data) 1 4) (test (morally-equal? data (float-vector 2.0 0.0 0.0 -2.0 0.0 2.0 -2.0 0.0)) #t)) (let ((data (make-float-vector 256)) (w (gsl_wavelet_alloc gsl_wavelet_daubechies 4)) (work (gsl_wavelet_workspace_alloc 256))) (do ((i 0 (+ i 1))) ((= i 256)) (set! (data i) (sin (* i (/ pi 128))))) (gsl_wavelet_transform_forward w (double* data) 1 256 work) (gsl_wavelet_transform_inverse w (double* data) 1 256 work) (gsl_wavelet_free w) (gsl_wavelet_workspace_free work) data) (let ((h (gsl_histogram_alloc 10)) (data (make-int-vector 10))) (gsl_histogram_set_ranges_uniform h 0.0 1.0) (do ((i 0 (+ i 1))) ((= i 50)) (gsl_histogram_increment h (random 1.0))) (do ((i 0 (+ i 1))) ((= i 10)) (set! (data i) (round (gsl_histogram_get h i)))) (gsl_histogram_free h) data) (let ((a_data (float-vector 0.18 0.60 0.57 0.96 0.41 0.24 0.99 0.58 0.14 0.30 0.97 0.66 0.51 0.13 0.19 0.85)) (b_data (float-vector 1 2 3 4))) (let ((m (gsl_matrix_alloc 4 4)) (b (gsl_vector_alloc 4))) (let ((x (gsl_vector_alloc 4)) (p (gsl_permutation_alloc 4))) (do ((i 0 (+ i 1))) ((= i 4)) (do ((j 0 (+ j 1))) ((= j 4)) (gsl_matrix_set m i j (a_data (+ j (* i 4)))))) (do ((i 0 (+ i 1))) ((= i 4)) (gsl_vector_set b i (b_data i))) (gsl_linalg_LU_decomp m p) ; int-by-ref is internal (gsl_linalg_LU_solve m p b x) (do ((i 0 (+ i 1))) ((= i 4)) (set! (b_data i) (gsl_vector_get x i))) (gsl_permutation_free p) (gsl_vector_free x) b_data))) (if (>= gsl-version 1.16) (let () (define (dofit T X y c cov) (let ((work (gsl_multifit_robust_alloc T (car (gsl_matrix_size X)) (cdr (gsl_matrix_size X))))) (let ((s (gsl_multifit_robust X y c cov work))) (gsl_multifit_robust_free work) s))) (let* ((n 30) (p 2) (a 1.45) (b 3.88) (X (gsl_matrix_alloc n p)) (x (gsl_vector_alloc n)) (y (gsl_vector_alloc n)) (c (gsl_vector_alloc p)) (c_ols (gsl_vector_alloc p)) (cov (gsl_matrix_alloc p p)) (gv (gsl_vector_alloc p)) (r (gsl_rng_alloc gsl_rng_default))) (do ((i 0 (+ i 1))) ((= i (- n 3))) (let* ((dx (/ 10.0 (- n 1.0))) (ei (gsl_rng_uniform r)) (xi (+ -5.0 (* i dx))) (yi (+ b (* a xi)))) (gsl_vector_set x i xi) (gsl_vector_set y i (+ yi ei)))) (gsl_vector_set x (- n 3) 4.7) (gsl_vector_set y (- n 3) -8.3) (gsl_vector_set x (- n 2) 3.5) (gsl_vector_set y (- n 2) -6.7) (gsl_vector_set x (- n 1) 4.1) (gsl_vector_set y (- n 1) -6.0) (do ((i 0 (+ i 1))) ((= i n)) (let ((xi (gsl_vector_get x i))) (gsl_matrix_set X i 0 1.0) (gsl_matrix_set X i 1 xi))) (dofit gsl_multifit_robust_ols X y c_ols cov) (dofit gsl_multifit_robust_bisquare X y c cov) (do ((i 0 (+ i 1))) ((= i n)) (let ((xi (gsl_vector_get x i)) (yi (gsl_vector_get y i)) (y_ols (float-vector 0.0)) (y_rob (float-vector 0.0)) (y_err (float-vector 0.0))) (gsl_vector_set gv 0 (gsl_matrix_get X i 0)) (gsl_vector_set gv 1 (gsl_matrix_get X i 1)) (gsl_multifit_robust_est gv c cov (double* y_rob) (double* y_err)) (gsl_multifit_robust_est gv c_ols cov (double* y_ols) (double* y_err)))) (gsl_matrix_free X) (gsl_matrix_free cov) (gsl_vector_free x) (gsl_vector_free y) (gsl_vector_free c) (gsl_vector_free gv) (gsl_rng_free r)))) (let () (gsl_rng_env_setup) (let* ((T gsl_rng_default) (r (gsl_rng_alloc T)) (x 0) (y 0) (dx (float-vector 0.0)) (dy (float-vector 0.0))) (do ((i 0 (+ i 1))) ((= i 10)) (gsl_ran_dir_2d r (double* dx) (double* dy)) (set! x (+ x (dx 0))) (set! y (+ y (dy 0)))) (gsl_rng_free r))) (let ((f_size 2) (T gsl_multimin_fminimizer_nmsimplex)) (define (simple-abs x) (let ((u (gsl_vector_get x 0)) (v (gsl_vector_get x 1))) (let ((a (- u 1)) (b (- v 2))) (+ (abs a) (abs b))))) (let ((x (gsl_vector_alloc f_size)) (step_size (gsl_vector_alloc f_size)) (s (gsl_multimin_fminimizer_alloc T 2))) (gsl_vector_set x 0 1.0) (gsl_vector_set x 1 2.0) (gsl_vector_set step_size 0 1) (gsl_vector_set step_size 1 1) (gsl_multimin_fminimizer_set s simple-abs x step_size) (do ((i 0 (+ i 1))) ((= i 10)) (gsl_multimin_fminimizer_iterate s)) (let ((result (abs (gsl_multimin_fminimizer_fval s)))) (gsl_multimin_fminimizer_free s) (gsl_vector_free x) (gsl_vector_free step_size) (num-test result 0.0)))) (let ((n 4) (x (float-vector 1970 1980 1990 2000)) (y (float-vector 12 11 14 13)) (w (float-vector 0.1 0.2 0.3 0.4)) (c0 (float-vector 0.0)) (c1 (float-vector 0.0)) (cov00 (float-vector 0.0)) (cov01 (float-vector 0.0)) (cov11 (float-vector 0.0)) (chisq (float-vector 0.0))) (gsl_fit_wlinear (double* x) 1 (double* w) 1 (double* y) 1 n (double* c0) (double* c1) (double* cov00) (double* cov01) (double* cov11) (double* chisq)) (num-test (+ (c0 0) (c1 0)) -106.54)) (let ((c (gsl_multiset_calloc 4 2))) (test (list (gsl_multiset_n c) (gsl_multiset_k c)) '(4 2))) (let ((x (gsl_vector_alloc 2)) (factor 1.0) (T gsl_multiroot_fsolver_dnewton)) (define (rosenb x f) (let ((x0 (gsl_vector_get x 0)) (x1 (gsl_vector_get x 1))) (let ((y0 (- 1 x0)) (y1 (* 10 (- x1 (* x0 x0))))) (gsl_vector_set f 0 y0) (gsl_vector_set f 1 y1) GSL_SUCCESS))) (gsl_vector_set x 0 -1.2) (gsl_vector_set x 1 1.0) (let ((s (gsl_multiroot_fsolver_alloc T 2))) (gsl_multiroot_fsolver_set s rosenb x) (do ((i 0 (+ i 1))) ((= i 10)) (gsl_multiroot_fsolver_iterate s)) (let ((residual (abs (gsl_vector_get (gsl_multiroot_fsolver_f s) 0)))) (gsl_multiroot_fsolver_free s) (gsl_vector_free x) (test residual 0.0)))) )))) (test (defined? 'CLOCKS_PER_SEC (rootlet)) #f) ; autoloader can cause endless confusion here! ;;; -------------------------------------------------------------------------------- ;;; libgdbm (if (and (provided? 'linux) (provided? 'system-extras) (file-exists? "/usr/local/lib/libgdbm.a")) (let () (require libgdbm.scm) (when (and (defined? '*libgdbm*) (procedure? (*libgdbm* 'gdbm_store))) (with-let (sublet *libgdbm*) (let ((gfile (gdbm_open "test.gdbm" 1024 GDBM_NEWDB #o664 (lambda (str) (format *stderr* "str: ~S~%" str))))) (gdbm_store gfile "1" "1234" GDBM_REPLACE) (gdbm_fetch gfile "1") (gdbm_close gfile)) (define *db* (openlet (inlet :file (gdbm_open "test.gdbm" 1024 GDBM_NEWDB #o664 (lambda (str) (format *stderr* "gdbm error: ~S~%" str))) :let-ref-fallback (lambda (obj sym) (with-input-from-string (gdbm_fetch (obj 'file) (symbol->string sym)) (lambda () (eval (read))))) :let-set!-fallback (lambda (obj sym val) (gdbm_store (obj 'file) (symbol->string sym) (object->string val :readable) GDBM_REPLACE) val) :make-iterator (lambda (obj) (let ((key #f) (length (lambda (obj) (expt 2 20)))) (#_make-iterator (openlet (let ((iterator? #t)) (lambda () (if key (set! key (gdbm_nextkey (obj 'file) (cdr key))) (set! key (gdbm_firstkey (obj 'file)))) (if (pair? key) (cons (string->symbol (car key)) (with-input-from-string (gdbm_fetch (obj 'file) (car key)) (lambda () (eval (read))))) key)))))))))) (set! (*db* 'str) "123") ; add a variable named 'hi with the value "123" (test (*db* 'str) "123") (set! (*db* 'int) 432) (test (*db* 'int) 432) (test (with-let *db* (+ int (length str))) 435) (test (let ((lst (map values *db*))) (or (equal? lst '((str . "123") (int . 432))) (equal? lst '((int . 432) (str . "123"))))) #t) (gdbm_close (*db* 'file)))))) ;;; -------------------------------------------------------------------------------- ;;; libutf8proc ;;; ;;; these are from the libutf8proc test directory (when full-test (load "libutf8proc.scm") (when (defined? '*libutf8proc*) (with-let *libutf8proc* (define (print-property c) (format *stderr* " category = ~S~% charwidth = ~D~%~A~%" (utf8proc_category_string c) (utf8proc_charwidth c) (utf8proc_get_property c))) (do ((c 1 (+ c 1))) ((= c #x110000)) (let ((l (utf8proc_tolower c)) (u (utf8proc_toupper c))) (if (not (or (= l c) (utf8proc_codepoint_valid l))) (format *stderr* "~X: invalid tolower~%" c)) (if (not (or (= u c) (utf8proc_codepoint_valid u))) (format *stderr* "~X: invalid toupper~%" c)) )) (do ((c 0 (+ c 1))) ((or (= c #xd800) (and (not (utf8proc_codepoint_valid c)) (not (format *stderr* "~X: codepoint invalid~%" c)))))) (do ((c #xd800 (+ c 1))) ((or (= c #xe000) (and (utf8proc_codepoint_valid c) (not (format *stderr* "~X: codepoint valid?~%" c)))))) (do ((c #xe000 (+ c 1))) ((or (= c #x110000) (and (not (utf8proc_codepoint_valid c)) (not (format *stderr* "~X: codepoint invalid~%" c)))))) (do ((c #x110000 (+ c 1))) ((or (= c #x110010) (and (utf8proc_codepoint_valid c) (not (format *stderr* "~X: codepoint valid?~%" c)))))) ;; (print-property #xbb) (do ((c 1 (+ c 1))) ((= c #x110000)) (let ((cat ((utf8proc_get_property c) 'category)) (w (utf8proc_charwidth c))) (if (and (or (= cat UTF8PROC_CATEGORY_MN) (= cat UTF8PROC_CATEGORY_ME)) (positive? w)) (format *stderr* "nonzero width ~D for combining char ~X~%" w c)) (if (and (zero? w) (or (and (>= cat UTF8PROC_CATEGORY_LU) (<= cat UTF8PROC_CATEGORY_LO)) (and (>= cat UTF8PROC_CATEGORY_ND) (<= cat UTF8PROC_CATEGORY_SC)) (and (>= cat UTF8PROC_CATEGORY_SO) (<= cat UTF8PROC_CATEGORY_ZS)))) (format *stderr* "zero width for symbol-like char ~X~%" c)))) ))) (define (symbol->value-anywhere sym) (if (defined? sym) (symbol->value sym) (letrec ((libsearch (lambda (sym libs) (if (pair? libs) (if (defined? sym (cdar libs)) (symbol->value sym (cdar libs)) (libsearch sym (cdr libs))) #)))) (libsearch sym *libraries*)))) (test (procedure? (symbol->value-anywhere 'getchar)) #t) (test (integer? (symbol->value-anywhere 'GSL_SUCCESS)) #t) (test (integer? (symbol->value-anywhere 'most-positive-fixnum)) #t) (test (let? (cdr (assoc "libc.scm" *libraries*))) #t) ;;; -------------------------------------------------------------------------------- (define (string-wi=? s1 s2) (or (string=? s1 s2) (let ((len1 (length s1)) (len2 (length s2))) (let loop ((i1 0) (i2 0)) (or (and (= i1 len1) (= i2 len2)) (if (and (< i1 len1) (char-whitespace? (s1 i1))) (loop (+ i1 1) i2) (if (and (< i2 len2) (char-whitespace? (s2 i2))) (loop i1 (+ i2 1)) (and (< i1 len1) (< i2 len2) (char=? (s1 i1) (s2 i2)) (loop (+ i1 1) (+ i2 1)))))))))) (test (string-wi=? "" "") #t) (test (string-wi=? "" " ") #t) (test (string-wi=? "" " a") #f) (test (string-wi=? "a" " a") #t) (test (string-wi=? "a " " a") #t) (test (string-wi=? " a " "a") #t) (test (string-wi=? " a " " a") #t) (test (string-wi=? "\n a\n " "a") #t) (test (string-wi=? "aa" " a") #f) (test (string-wi=? "aa" " a a ") #t) (test (string-wi=? "aa" "aa ") #t) (let () (require lint.scm) (define (lint-test str1 str2) ;(display str1) (newline) (let ((result (call-with-output-string (lambda (op) (call-with-input-string str1 (lambda (ip) (lint ip op))))))) (define (no-lines s) (let ((pos (string-position "(line " s)) (epos (string-position "): " s))) (if (and pos epos) (no-lines (string-append (substring s 0 (- pos 1)) (substring s (+ epos 1)))) ; sometimes there are two "(line ...)" intrusions s))) (if (and (not (string-wi=? result str2)) (not (string-wi=? (no-lines result) str2))) (format *stderr* ";(lint ~S) -> ~S~%" str1 result)))) (lint-test "(+ 1 2)" " +: perhaps (+ 1 2) -> 3") (lint-test "(+ 1 (+ 2 3))" " +: perhaps (+ 1 (+ 2 3)) -> 6") (lint-test "(+ 1 (+ x 3))" " +: perhaps (+ 1 (+ x 3)) -> (+ 4 x)") (lint-test "(+ x)" " +: perhaps (+ x) -> x") (lint-test "(* 2 (+))" " *: perhaps (* 2 (+)) -> 0") (lint-test "(+ (+ (+ x 2) 3) 4)" " +: perhaps (+ (+ (+ x 2) 3) 4) -> (+ 9 x)") (lint-test "(+ 1 2 x -3)" " +: perhaps (+ 1 2 x -3) -> x") (lint-test "(+ 1/2 -1/2)" " +: perhaps (+ 1/2 -1/2) -> 0") (lint-test "(+ 1/3 2/3)" " +: perhaps (+ 1/3 2/3) -> 1") (lint-test "(+ (log x) (log 3))" "") ; oops... (lint-test "(+ x 0 (+ 0 0))" " +: perhaps (+ x 0 (+ 0 0)) -> x") (lint-test "(+ x #(0))" " +: +'s argument 2 should be a number?: #(0): (+ x #(0))") (lint-test "(+ x 2.0 -2)" "") (lint-test "(* 2 3)" " *: perhaps (* 2 3) -> 6") (lint-test "(* (* 2 3) 4)" " *: perhaps (* (* 2 3) 4) -> 24") (lint-test "(* (* x 3) 4)" " *: perhaps (* (* x 3) 4) -> (* 12 x)") (lint-test "(* x)" " *: perhaps (* x) -> x") (lint-test "(* x (*))" " *: perhaps (* x (*)) -> x") (lint-test "(* 2 x 3 y 1/6)" " *: perhaps (* 2 x 3 y 1/6) -> (* x y)") (lint-test "(* x -1)" " *: perhaps (* x -1) -> (- x)") (lint-test "(* x 1 1 1)" " *: perhaps (* x 1 1 1) -> x") (lint-test "(* x 1 1.0 1)" " *: perhaps (* x 1 1.0 1) -> (* x 1.0)") (lint-test "(* x y 2 0)" " *: perhaps (* x y 2 0) -> 0") (lint-test "(* -1 x -1 -1)" " *: perhaps (* -1 x -1 -1) -> (- x)") (lint-test "(- 1 2)" " -: perhaps (- 1 2) -> -1") (lint-test "(- 1 (- 1 2))" " -: perhaps (- 1 (- 1 2)) -> 2") (lint-test "(- x (- 2 0))" " -: perhaps (- x (- 2 0)) -> (- x 2)") (lint-test "(- (- x))" " -: perhaps (- (- x)) -> x") (lint-test "(- 0 x)" " -: perhaps (- 0 x) -> (- x)") (lint-test "(- x 0)" " -: perhaps (- x 0) -> x") (lint-test "(+ x (- 1))" " +: perhaps (+ x (- 1)) -> (+ x -1)") (lint-test "(- (- y x))" " -: perhaps (- (- y x)) -> (- x y)") (lint-test "(- 3/2 1/2)" " -: perhaps (- 3/2 1/2) -> 1") (lint-test "(- (- x y) z)" " -: perhaps (- (- x y) z) -> (- x y z)") (lint-test "(- x 0 (+ 3 2))" " -: perhaps (- x 0 (+ 3 2)) -> (- x 5)") (lint-test "(- 5 x (+ 3 2))" " -: perhaps (- 5 x (+ 3 2)) -> (- x)") (lint-test "(- x 0 0 0)" " -: perhaps (- x 0 0 0) -> x") (lint-test "(- 0 0 0 x)" " -: perhaps (- 0 0 0 x) -> (- x)") (lint-test "(- 0.0 x)" "") (lint-test "(- x (+ 0 x))" " -: perhaps (- x (+ 0 x)) -> 0") (lint-test "(- (abs x) (abs x) y)" " -: perhaps (- (abs x) (abs x) y) -> (- y)") (lint-test "(- (abs x) (abs x) (abs x) y)" " -: perhaps (- (abs x) (abs x) (abs x) y) -> (- 0 (abs x) y)") (lint-test "(+ x (+ y 2) (+ z 3))" " +: perhaps (+ x (+ y 2) (+ z 3)) -> (+ 5 x y z)") (lint-test "(/ 2 3)" " /: perhaps (/ 2 3) -> 2/3") (lint-test "(/ 1 x)" " /: perhaps (/ 1 x) -> (/ x)") (lint-test "(/ 2)" " /: perhaps (/ 2) -> 1/2") (lint-test "(/ 0 2 x)" "") (lint-test "(/ 0 x)" "") (lint-test "(/ (/ x))" " /: perhaps (/ (/ x)) -> x") (lint-test "(/ (log x) (log 2))" " /: perhaps (/ (log x) (log 2)) -> (log x 2)") (lint-test "(/ (log x) (log y))" " /: perhaps (/ (log x) (log y)) -> (log x y)") (lint-test "(/ x (/ y))" "") ; ideally (* x y) (lint-test "(/ x 1 1 1)" " /: perhaps (/ x 1 1 1) -> x") (lint-test "(/ x a (* b 1 c) d)" " /: perhaps (/ x a (* b 1 c) d) -> (/ x a b c d)") (lint-test "(/ 0 a (* b 1 c) d)" " /: perhaps (/ 0 a (* b 1 c) d) -> (/ 0 a b c d)") (lint-test "(/ x x)" " /: this looks odd: (/ x x)") (lint-test "(/ 0)" " /: attempt to invert zero: (/ 0)") (lint-test "(/ x y 2 0)" " /: attempt to divide by 0: (/ x y 2 0)") (lint-test "(/ (/ 1 a) (/ b c d))" " /: perhaps (/ (/ 1 a) (/ b c d)) -> (/ (* c d) (* a b))") (lint-test "(/ (/ a) (/ b))" " /: perhaps (/ (/ a) (/ b)) -> (/ b a)") (lint-test "(/ (/ a b c) (/ d e f))" " /: perhaps (/ (/ a b c) (/ d e f)) -> (/ (* a e f) (* b c d))") (lint-test "(sin (asin x))" " sin: perhaps (sin (asin x)) -> x") (lint-test "(sin 0)" " sin: perhaps (sin 0) -> 0") (lint-test "(sin pi)" " sin: perhaps (sin pi) -> 0.0") (lint-test "(cos 0)" " cos: perhaps (cos 0) -> 1") (lint-test "(cos (acos (+ x 1)))" " cos: perhaps (cos (acos (+ x 1))) -> (+ x 1)") (lint-test "(cos (* pi 1))" " cos: perhaps (cos (* pi 1)) -> 1.0") (lint-test "(cos (- (* x y)))" " cos: perhaps (cos (- (* x y))) -> (cos (* x y))") (lint-test "(cos 0)" " cos: perhaps (cos 0) -> 1") (lint-test "(exp (* (+ x y) (log (+ y 1))))" " exp: perhaps (exp (* (+ x y) (log (+ y 1)))) -> (expt (+ y 1) (+ x y))") (lint-test "(exp (* (log x) a))" " exp: perhaps (exp (* (log x) a)) -> (expt x a)") (lint-test "(acosh (cosh 0))" " acosh: perhaps (acosh (cosh 0)) -> (acosh 1)") (lint-test "(exp (log 1))" " exp: perhaps (exp (log 1)) -> 1") (if with-bignums (lint-test "(exp 0.0)" " exp: perhaps (exp 0.0) -> 1.000E0") (lint-test "(exp 0.0)" " exp: perhaps (exp 0.0) -> 1.0")) (lint-test "(sin x 0.0)" " sin: sin has too many arguments: (sin x 0.0)") (lint-test "(sin)" " sin: sin needs 1 argument: (sin)") (lint-test "(log 1)" " log: perhaps (log 1) -> 0") (lint-test "(log (exp 0))" " log: perhaps (log (exp 0)) -> 0") (lint-test "(log (exp (* x y)))" " log: perhaps (log (exp (* x y))) -> (* x y)") (lint-test "(log (* x 1) (- x 0))" " log: perhaps (log (* x 1) (- x 0)) -> 1.0") (lint-test "(log 2 2)" " log: perhaps (log 2 2) -> 1") (lint-test "(log pi pi)" " log: perhaps (log pi pi) -> 1.0") (lint-test "(log (* x pi) (* x pi))" " log: perhaps (log (* x pi) (* x pi)) -> 1.0") (lint-test "(log (* x pi))" "") (lint-test "(sqrt 4)" " sqrt: perhaps (sqrt 4) -> 2") (if (not with-bignums) (lint-test "(sqrt 3)" "")) (lint-test "(sqrt 4.0)" "") (lint-test "(sqrt (* (+ x 1) (+ x 1)))" "") ; tricky case, x might be -2 for example (lint-test "(sqrt)" " sqrt: sqrt needs 1 argument: (sqrt)") (lint-test "(sqrt (- x 0))" " sqrt: perhaps (sqrt (- x 0)) -> (sqrt x)") (lint-test "(complex (- x 0) 2)" " complex: perhaps (complex (- x 0) 2) -> (complex x 2)") (lint-test "(floor 3.4)" " floor: perhaps (floor 3.4) -> 3") (lint-test "(round 3.4+i)" " round: round's argument should be a real?: 3.4+1i: (round 3.4+1i)") (lint-test "(string-ref (round x) str)" " string-ref: string-ref's argument 1 should be a string?: (round x): (string-ref (round x) str)") (lint-test "(string-ref x (cons 1 2))" " string-ref: string-ref's argument 2 should be an integer?: (cons 1 2): (string-ref x (cons 1 2))") (lint-test "(ceiling (floor 2.1))" " ceiling: perhaps (ceiling (floor 2.1)) -> 2") (lint-test "(ceiling (floor x))" " ceiling: perhaps (ceiling (floor x)) -> (floor x)") (lint-test "(truncate 2/3)" " truncate: perhaps (truncate 2/3) -> 0") (lint-test "(truncate (/ 2 3))" " truncate: perhaps (truncate (/ 2 3)) -> 0") (lint-test "(truncate (/ 12 (* 2 3)))" " truncate: perhaps (truncate (/ 12 (* 2 3))) -> 2") (lint-test "(abs (magnitude 1+i))" " abs: perhaps (abs (magnitude 1+1i)) -> (magnitude 1+1i)") (lint-test "(magnitude 2/3)" " magnitude: perhaps use abs here: (magnitude 2/3) magnitude: perhaps (magnitude 2/3) -> 2/3") (lint-test "(abs (- (* 2 x)))" " abs: perhaps (abs (- (* 2 x))) -> (abs (* 2 x))") (lint-test "(abs (* (+ x 1) 1))" " abs: perhaps (abs (* (+ x 1) 1)) -> (abs (+ x 1))") (lint-test "(magnitude (real-part z))" " magnitude: perhaps use abs here: (magnitude (real-part z))") (lint-test "(abs (denominator x))" " abs: perhaps (abs (denominator x)) -> (denominator x)") (lint-test "(abs (modulo x 2))" " abs: perhaps (abs (modulo x 2)) -> (modulo x 2)") (lint-test "(real-part 3.0)" " real-part: perhaps (real-part 3.0) -> 3.0") (lint-test "(imag-part 3.0)" " imag-part: perhaps (imag-part 3.0) -> 0.0") (lint-test "(real-part (abs x))" " real-part: perhaps (real-part (abs x)) -> (abs x)") (lint-test "(imag-part (abs x))" " imag-part: perhaps (imag-part (abs x)) -> 0.0") (lint-test "(imag-part (sin x))" "") (lint-test "(real-part 1+i)" "") (lint-test "(imag-part x)" "") (lint-test "(real-part x)" "") (lint-test "(imag-part (vector-ref x i))" "") (lint-test "(imag-part (x i))" "") (lint-test "(string? (number->string x))" " string?: perhaps (string? (number->string x)) -> (number->string x)") (lint-test "(number? (string->number x))" " number?: perhaps (number? (string->number x)) -> (string->number x)") (lint-test "(numerator 1/3)" " numerator: perhaps (numerator 1/3) -> 1") (lint-test "(numerator 3)" " numerator: perhaps (numerator 3) -> 3") (lint-test "(numerator (floor x))" " numerator: perhaps (numerator (floor x)) -> (floor x)") (lint-test "(denominator (floor x))" " denominator: perhaps (denominator (floor x)) -> 1") (lint-test "(denominator 3)" " denominator: perhaps (denominator 3) -> 1") (lint-test "(denominator (round (+ x 1)))" " denominator: perhaps (denominator (round (+ x 1))) -> 1") (lint-test "(numerator (round (+ x 1)))" " numerator: perhaps (numerator (round (+ x 1))) -> (round (+ x 1))") (lint-test "(random 0)" " random: perhaps (random 0) -> 0") (lint-test "(random 0.0)" " random: perhaps (random 0.0) -> 0.0") (lint-test "(random x)" "") (lint-test "(random 1)" "") (lint-test "(random 0 y)" "") (lint-test "(lognot 1)" " lognot: perhaps (lognot 1) -> -2") (lint-test "(lognot 1/2)" " lognot: lognot's argument should be an integer?: 1/2: (lognot 1/2)") (if with-bignums (lint-test "(ash 2 64)" " ash: perhaps (ash 2 64) -> 36893488147419103232") (lint-test "(ash 2 64)" "")) (lint-test "(ash 1 7)" " ash: perhaps (ash 1 7) -> 128") (lint-test "(complex 1.0 0)" " complex: perhaps (complex 1.0 0) -> 1.0") (lint-test "(expt 0 x)" " expt: perhaps (expt 0 x) -> 0") (lint-test "(expt x 0)" " expt: perhaps (expt x 0) -> 1") (lint-test "(expt (* 2 x) 1)" " expt: perhaps (expt (* 2 x) 1) -> (* 2 x)") (lint-test "(expt (* 2 x) -1)" " expt: perhaps (expt (* 2 x) -1) -> (/ (* 2 x))") (lint-test "(expt 2 3)" " expt: perhaps (expt 2 3) -> 8") (lint-test "(expt 1/2 -2)" " expt: perhaps (expt 1/2 -2) -> 4") (lint-test "(expt 2 1/2)" "") (lint-test "(expt 1.0 1.0)" "") (lint-test "(expt 0 0)" " expt: perhaps (expt 0 0) -> 1") (lint-test "(angle -1)" " angle: perhaps (angle -1) -> pi") (lint-test "(angle 0.0)" " angle: perhaps (angle 0.0) -> 0.0") (lint-test "(angle pi)" " angle: perhaps (angle pi) -> 0.0") (lint-test "(atan x 0.0)" "") (lint-test "(atan (/ x y))" " atan: perhaps (atan (/ x y)) -> (atan x y)") (lint-test "(inexact->exact 1.5)" " inexact->exact: perhaps (inexact->exact 1.5) -> 3/2") (lint-test "(inexact->exact (floor x))" " inexact->exact: perhaps (inexact->exact (floor x)) -> (floor x)") (lint-test "(inexact->exact 2/3)" " inexact->exact: perhaps (inexact->exact 2/3) -> 2/3") (lint-test "(logior x (logior y z))" " logior: perhaps (logior x (logior y z)) -> (logior x y z)") (lint-test "(logior x 3 7 3 1 x)" " logior: perhaps (logior x 3 7 3 1 x) -> (logior 7 x)") (lint-test "(logior x)" " logior: perhaps (logior x) -> x") (lint-test "(logior x -1 2 y)" " logior: perhaps (logior x -1 2 y) -> -1") (lint-test "(logior 6 2)" " logior: perhaps (logior 6 2) -> 6") (lint-test "(logior)" " logior: perhaps (logior) -> 0") (lint-test "(logior x 0 y)" " logior: perhaps (logior x 0 y) -> (logior x y)") (lint-test "(logand x 3 7 3 1 x)" " logand: perhaps (logand x 3 7 3 1 x) -> (logand 1 x)") (lint-test "(logand 3 91 2)" " logand: perhaps (logand 3 91 2) -> 2") (lint-test "(logand)" " logand: perhaps (logand) -> -1") (lint-test "(logand (* x 3))" " logand: perhaps (logand (* x 3)) -> (* x 3)") (lint-test "(logand (* x 3) 0 y)" " logand: perhaps (logand (* x 3) 0 y) -> 0") (lint-test "(logand -1 x -1 y)" " logand: perhaps (logand -1 x -1 y) -> (logand x y)") (lint-test "(logand x (logand y 1))" " logand: perhaps (logand x (logand y 1)) -> (logand x y 1)") (lint-test "(logand x (logand y 0))" " logand: perhaps (logand x (logand y 0)) -> 0") (lint-test "(logxor x y x z)" "") (lint-test "(logxor 2 4 1)" " logxor: perhaps (logxor 2 4 1) -> 7") (lint-test "(logxor x)" " logxor: perhaps (logxor x) -> x") (lint-test "(logxor x x)" " logxor: perhaps (logxor x x) -> 0") (lint-test "(gcd x (gcd x y))" " gcd: perhaps (gcd x (gcd x y)) -> (gcd x y)") (lint-test "(lcm x (lcm x y))" " lcm: perhaps (lcm x (lcm x y)) -> (lcm x y)") (lint-test "(gcd x x)" " gcd: perhaps (gcd x x) -> (abs x)") (lint-test "(gcd)" " gcd: perhaps (gcd) -> 0") (lint-test "(lcm)" " lcm: perhaps (lcm) -> 1") (lint-test "(gcd x y 1 3)" " gcd: perhaps (gcd x y 1 3) -> 1") (lint-test "(lcm x y 0 3)" " lcm: perhaps (lcm x y 0 3) -> 0") (lint-test "(gcd 12 18)" " gcd: perhaps (gcd 12 18) -> 6") (lint-test "(gcd x 0)" " gcd: perhaps (gcd x 0) -> (abs x)") (lint-test "(* (gcd a b) (lcm a b))" " *: perhaps (* (gcd a b) (lcm a b)) -> (abs (* a b))") (lint-test "(lcm 12 18)" " lcm: perhaps (lcm 12 18) -> 36") (lint-test "(lcm x)" " lcm: perhaps (lcm x) -> (abs x)") (lint-test "(lcm x x x)" " lcm: perhaps (lcm x x x) -> (abs x)") (lint-test "(max x)" " max: perhaps (max x) -> x") (lint-test "(max 3 4 5)" " max: perhaps (max 3 4 5) -> 5") (lint-test "(max 3 x 4 5)" " max: perhaps (max 3 x 4 5) -> (max 5 x)") (lint-test "(max 3.0 x 4/5 5)" " max: perhaps (max 3.0 x 4/5 5) -> (max 5 x)") (lint-test "(min 3.0 x 4/5 5)" " min: perhaps (min 3.0 x 4/5 5) -> (min 4/5 x)") (lint-test "(max 3.0 x x 5)" " max: it looks odd to have repeated arguments in (max 3.0 x x 5) max: perhaps (max 3.0 x x 5) -> (max 5 x)") (lint-test "(max 3 (max 4 x) y)" " max: perhaps (max 3 (max 4 x) y) -> (max 4 x y)") (lint-test "(max 4 (min 3 x) y)" " max: perhaps (max 4 (min 3 x) y) -> (max 4 y)") (lint-test "(min 4 (max 3 x) y)" "") (lint-test "(min (max x 3) 4 y)" "") (lint-test "(min 3 (max 4 x) y)" " min: perhaps (min 3 (max 4 x) y) -> (min 3 y)") (lint-test "(max (min x 3) (min x 3))" " max: this looks odd: (max (min x 3) (min x 3)) max: perhaps (max (min x 3) (min x 3)) -> (min x 3)") (lint-test "(min x (max y x))" " min: perhaps (min x (max y x)) -> x") (lint-test "(max (min y x) x)" " max: perhaps (max (min y x) x) -> x") (lint-test "(min x (max y z (+ 21 x) x (* y z)))" " min: perhaps (min x (max y z (+ 21 x) x (* y z))) -> x") (lint-test "(equal? x y z)" " equal?: equal? has too many arguments: (equal? x y z)") (lint-test "(= 1 y 2)" " =: this comparison can't be true: (= 1 y 2)") (lint-test "(= x 1.5)" " =: = can be troublesome with floats: (= x 1.5)") (lint-test "(= x 0.0)" "") (lint-test "(= x 1.0 x)" " =: it looks odd to have repeated arguments in (= x 1.0 x)") (lint-test "(= (- x y) 0)" " =: perhaps (= (- x y) 0) -> (= x y)") (lint-test "(= (- (abs x) 2) 0)" " =: perhaps (= (- (abs x) 2) 0) -> (= (abs x) 2)") (lint-test "(memq 1.0 x)" " memq: (memq 1.0 x): perhaps memq -> memv") (lint-test "(assq \"test\" x)" " assq: (assq \"test\" x): perhaps assq -> assoc") (lint-test "(assq (list 1 2) x)" " assq: (assq (list 1 2) x): perhaps assq -> assoc") (lint-test "(assv #(0) x)" " assv: (assv #(0) x): perhaps assv -> assoc") (lint-test "(member 'a x (lambda (a b c) (eq? a b)))" " member: member equality function (optional 3rd arg) should take two arguments") (lint-test "(member 'a x (lambda (a b) (eq? a (car b))))" " member: member might perhaps be assq") (lint-test "(member y x (lambda (a b) (equal? a (car b))))" " member: member might perhaps be assoc") (lint-test "(member 1 x (lambda (a b) (> a b)))" " member: perhaps (lambda (a b) (> a b)) -> >") (lint-test "(member 1 x (lambda (a b) (> b a)))" " member: perhaps (lambda (a b) (> b a)) -> <") (lint-test "(member 1 x abs)" " member: abs is a questionable member function") (lint-test "(member x (list \"asdf\"))" " member: perhaps (member x (list \"asdf\")) -> (string=? x \"asdf\")") (lint-test "(member x (list \"asd\" \"abc\" \"asd\"))" " member: duplicated entry \"asd\" in (list \"asd\" \"abc\" \"asd\")") (lint-test "(memq x '(1))" " memq: perhaps (memq x '(1)) -> (= x 1)") (lint-test "(memq x '(begin))" " memq: perhaps (memq x '(begin)) -> (eq? x 'begin)") (lint-test "(memq x (list 'car))" " memq: perhaps (memq x (list 'car)) -> (eq? x 'car)") (lint-test "(memq x '(a 'b c))" " memq: stray quote? (memq x '(a 'b c))") (lint-test "(memq x '(a ,b c))" " memq: stray comma? (memq x '(a (unquote b) c))") (lint-test "(memq x '(a (+ 1 2) 3))" " memq: pointless list member: (+ 1 2) in (memq x '(a (+ 1 2) 3))") (lint-test "(memq x '(a #(0)))" " memq: pointless list member: #(0) in (memq x '(a #(0)))") (lint-test "(memv x '(#f #\\c a 1 () :a))" "") (lint-test "(memq x '(a b a c))" " memq: duplicated entry a in '(a b a c)") (lint-test "(assq x '((a . 1)))" "") (lint-test "(if #f x y)" " if: if test is never true: (if #f x y) if: perhaps (if #f x y) -> y") (lint-test "(if #t #f)" " if: if test is never false: (if #t #f) if: perhaps (if #t #f) -> #f") (lint-test "(if x #f #t)" " if: perhaps (if x #f #t) -> (not x)") (lint-test "(if x #t #t)" " if: if is not needed here: (if x #t #t) -> #t") (lint-test "(if x #f #f)" " if: if is not needed here: (if x #f #f) -> #f") (lint-test "(if x (+ y 1) (+ y 1))" " if: if is not needed here: (if x (+ y 1) (+ y 1)) -> (+ y 1)") (lint-test "(if #f #f)" " if: perhaps (if #f #f) -> #") (lint-test "(if #f x)" " if: if test is never true: (if #f x) if: perhaps (if #f x) -> #") (lint-test "(if #t x y)" " if: if test is never false: (if #t x y) if: perhaps (if #t x y) -> x") (lint-test "(if x #t #f)" " if: perhaps (if x #t #f) -> x") (lint-test "(if x y #f)" " if: perhaps (if x y #f) -> (and x y)") (lint-test "(if x y #t)" " if: perhaps (if x y #t) -> (or (not x) y)") (lint-test "(if x #f y)" " if: perhaps (if x #f y) -> (and (not x) y)") (lint-test "(if x #t y)" " if: perhaps (if x #t y) -> (or x y)") (lint-test "(if (not x) y #t)" " if: perhaps (if (not x) y #t) -> (or x y)") (lint-test "(if (not x) #f y)" " if: perhaps (if (not x) #f y) -> (and x y)") (lint-test "(if (< 1 2) x y)" " if: perhaps (if (< 1 2) x y) -> x") (lint-test "(if (and x z) y #f)" " if: perhaps (if (and x z) y #f) -> (and x z y)") (lint-test "(if (and x z) (and y w) #f)" " if: perhaps (if (and x z) (and y w) #f) -> (and x z y w)") (lint-test "(if (or x z) #t y)" " if: perhaps (if (or x z) #t y) -> (or x z y)") (lint-test "(if (or x z) #t (or y w))" " if: perhaps (if (or x z) #t (or y w)) -> (or x z y w)") (lint-test "(if (not (or x z)) y #t)" " if: perhaps (if (not (or x z)) y #t) -> (or x z y)") (lint-test "(if (not (and x z)) #f y)" " if: perhaps (if (not (and x z)) #f y) -> (and x z y)") (lint-test "(if (cons 1 2) x y)" " if: if test is never false: (if (cons 1 2) x y)") (lint-test "(if y)" " if: if has too few clauses: (if y)") (lint-test "(if y z a b)" " if: if has too many clauses: (if y z a b)") (lint-test "(if x y (if z y))" " if: perhaps (if x y (if z y)) -> (if (or x z) y)") (lint-test "(if x y (if x y))" " if: perhaps (if x y (if x y)) -> (if x y)") (lint-test "(if x (if x y))" " if: perhaps (if x (if x y)) -> (if x y)") (lint-test "(if x (set! y #t) (set! y #f))" " if: perhaps (if x (set! y #t) (set! y #f)) -> (set! y x)") (lint-test "(if x (if y z))" " if: perhaps (if x (if y z)) -> (if (and x y) z)") (lint-test "(if (cadr x) (if (cadr x) 0))" " if: perhaps (if (cadr x) (if (cadr x) 0)) -> (if (cadr x) 0)") (lint-test "(if (cadr x) 3 (if (not (cadr x)) 4))" " if: pointless repetition of if test: (if (cadr x) 3 (if (not (cadr x)) 4)) -> (if (cadr x) 3 4)") (lint-test "(if (cadr x) 3 (if (not (cadr x)) 4 5))" " if: pointless repetition of if test: (if (cadr x) 3 (if (not (cadr x)) 4 5)) -> (if (cadr x) 3 4)") (lint-test "(if x x y)" " if: perhaps (if x x y) -> (or x y)") (lint-test "(if x y x)" " if: perhaps (if x y x) -> (and x y)") (lint-test "(if (> x 1) (> x 1) (< x 2))" " if: perhaps (if (> x 1) (> x 1) (< x 2)) -> (or (> x 1) (< x 2))") (lint-test "(if x x x)" " if: perhaps (if x x x) -> x if: if is not needed here: (if x x x) -> x") (lint-test "(if x x)" " if: perhaps (if x x) -> (or x #)") (lint-test "(if (> x 1) (> x 1))" " if: perhaps (if (> x 1) (> x 1)) -> (or (> x 1) #)") (lint-test "(if (display x) (display x) y)" "") (lint-test "(if (= x 1) 2 (if (= x 3) 2 3))" " if: perhaps (if (= x 1) 2 (if (= x 3) 2 3)) -> (if (memv x '(1 3)) 2 3)") (lint-test "(if z x z)" " if: perhaps (if z x z) -> (and z x)") (lint-test "(begin (if x (y)) (if x (z)) (if x (w)) 32)" " begin: perhaps combine repeated if's: (if x (y)) ... (if x (w)) -> (when x (y) ... (w))") (lint-test "(begin (if x (y)) (if x (z)) (if x (w)))" " begin: perhaps combine repeated if's: (if x (y)) ... (if x (w)) -> (when x (y) ... (w))") (lint-test "(begin (if x (y)) (if x (z)) 32)" "") (lint-test "(begin (if x (y)) (if x (z)))" "") (lint-test "(begin (if x (y)) (if x (z)) (v) (if x (w)))" "") (lint-test "(begin (if x (y)) (if x (z)) (v) (if x (w)) 12)" "") (lint-test "(car (cons 1 2))" " car: (car (cons 1 2)) is the same as 1") (lint-test "(and x x y)" " and: perhaps (and x x y) -> (and x y)") (lint-test "(or x x y)" " or: perhaps (or x x y) -> (or x y)") (lint-test "(or x (or x y))" " or: perhaps (or x (or x y)) -> (or x y)") (lint-test "(< x 1 2 0 y)" " <: this comparison can't be true: (< x 1 2 0 y)") (lint-test "(< x 1 2 y)" "") (lint-test "(< x 1 y)" "") (lint-test "(char>? x #\\a #\\b y)" " char>?: this comparison can't be true: (char>? x #\\a #\\b y)") (lint-test "(string>? \"a\" x \"b\" y)" " string>?: this comparison can't be true: (string>? \"a\" x \"b\" y)") (lint-test "(copy (copy x))" " copy: (copy (copy x)) could be (copy x)") (lint-test "(string-copy (string-copy x))" " string-copy: (string-copy (string-copy x)) could be (string-copy x)") (lint-test "(string-append x)" " string-append: perhaps (string-append x) -> x, or use copy") (lint-test "(string-append \"\" \"\" x)" " string-append: perhaps (string-append \"\" \"\" x) -> x, or use copy") (lint-test "(string-append \"\" \"\")" " string-append: perhaps (string-append \"\" \"\") -> \"\"") (lint-test "(string-append \"\" (string-append x y) \"\")" " string-append: perhaps (string-append \"\" (string-append x y) \"\") -> (string-append x y)") (lint-test "(string-append \"123\" \"456\")" " string-append: perhaps (string-append \"123\" \"456\") -> \"123456\"") (lint-test "(string-append x (string-append y z))" " string-append: perhaps (string-append x (string-append y z)) -> (string-append x y z)") (lint-test "(vector-append)" " vector-append: perhaps (vector-append) -> #()") (lint-test "(vector-append #(1 2) (vector-append #(3)))" " vector-append: perhaps (vector-append #(1 2) (vector-append #(3))) -> #(1 2 3)") (lint-test "(vector-append x (vector-append y z))" " vector-append: perhaps (vector-append x (vector-append y z)) -> (vector-append x y z)") (lint-test "(object->string (object->string x))" " object->string: (object->string (object->string x)) could be (object->string x)") (lint-test "(object->string x :else)" " object->string: bad second argument: :else") (lint-test "(display (format #f str x))" " display: (display (format #f str x)) could be (format #t str x)") (lint-test "(vector->list (list->vector x))" " vector->list: (vector->list (list->vector x)) could be (copy x)") (lint-test "(reverse (reverse x))" " reverse: (reverse (reverse x)) could be (copy x)") (lint-test "(string->number (number->string x))" " string->number: (string->number (number->string x)) could be x") (lint-test "(append 3)" " append: perhaps (append 3) -> 3") (lint-test "(append)" " append: perhaps (append) -> ()") (lint-test "(append (append))" " append: perhaps (append (append)) -> ()") (lint-test "(append '(1) (append '(2)))" " append: perhaps (append '(1) (append '(2))) -> (list 1 2)") (lint-test "(append x (append))" " append: perhaps clearer: (append x (append)) -> (copy x)") (lint-test "(append '(1 2) (list))" " append: perhaps clearer: (append '(1 2) (list)) -> (copy '(1 2))") (lint-test "(append x '())" " append: perhaps clearer: (append x '()) -> (copy x) append: quote is not needed here: '()") (lint-test "(append '(1) (append 2))" " append: perhaps (append '(1) (append 2)) -> (append '(1) 2)") (lint-test "(append '(1) (append '(2) '(3)) '(4))" " append: perhaps (append '(1) (append '(2) '(3)) '(4)) -> (list 1 2 3 4)") (lint-test "(append (list x y) (list z))" " append: perhaps (append (list x y) (list z)) -> (list x y z)") (lint-test "(append '(1 2) (list 3))" " append: perhaps (append '(1 2) (list 3)) -> (list 1 2 3)") (lint-test "(append '(1) '(2 3))" " append: perhaps (append '(1) '(2 3)) -> (list 1 2 3)") (lint-test "(append '(x) '((+ 1 2) #(0)))" " append: perhaps (append '(x) '((+ 1 2) #(0))) -> (list 'x '(+ 1 2) #(0))") ;; (equal? (list 'x '(+ 1 2) #(0)) (append '(x) '((+ 1 2) #(0)))) -> #t (lint-test "(append (list x) (list y z) (list 1))" " append: perhaps (append (list x) (list y z) (list 1)) -> (list x y z 1)") (lint-test "(cons x (list y z))" " cons: perhaps (cons x (list y z)) -> (list x y z)") (lint-test "(cons x (list))" " cons: perhaps (cons x (list)) -> (list x)") (lint-test "(sort! x abs)" " sort!: abs is a questionable sort! function") (lint-test "(sort! x (lambda (a b) (< a b)))" " sort!: perhaps (lambda (a b) (< a b)) -> <") (lint-test "(sort! x (lambda (a b) (< b a)))" " sort!: perhaps (lambda (a b) (< b a)) -> >") (lint-test "(abs 1 2)" " abs: abs has too many arguments: (abs 1 2)") (lint-test "(-)" " -: - needs at least 1 argument: (-)") (lint-test "(modulo 3)" " modulo: modulo needs 2 arguments: (modulo 3)") (lint-test "(let () (define* (f1 a b) (+ a b)) (f1 :c 1))" " let: f1 keyword argument :c (in (f1 :c 1)) does not match any argument in (a b)") (lint-test "(let () (define (f2 a b) (+ a b)) (f2 1 2 3))" " let: f2 has too many arguments: (f2 1 2 3)") (lint-test "(let () (define* (f3 a . b) (+ a b)) (f3 1 2 3))" "") (lint-test "(let () (define* (f4 (a #f)) a) (f4))" " f4: the default argument value is #f in define* (a #f)") (lint-test "(let () (define (f1 a) a) 32)" " let: let variable f1 not used") (lint-test "(letrec ((f1 (lambda (a) a))) 32)" " letrec: letrec variable f1 not used") (lint-test "(let () (define x 3) 32)" " let: let variable x not used") (lint-test "(let ((z 1)) (define x 12) (define (y a) a) 32)" " let: let variables x, y, z not used") (lint-test "(let ((z 1)) (define x 12) (define (y a) a) (+ z 32))" " let: let variables x, y not used") (lint-test "(let* ((a 1) (b 2) (c (+ a 1))) (* c 2))" " let*: let* variable b not used") (lint-test "(let () (define (f4 a . b) (+ a b)) (f4))" " let: f4 needs 1 argument: (f4)") (lint-test "(let ((a)) #f)" " let: let variable value is missing? (a)") (lint-test "(let ((a . 1)) #f)" " let: let binding is an improper list? (a . 1)") (lint-test "(let ((1 2)) #f)" " let: let variable is not a symbol? (1 2)") (lint-test "(let ((pi 2)) #f)" " let: can't bind a constant: (pi 2)") (lint-test "(let ((:a 1)) :a)" " let: let variable is a keyword? (:a 1)") (lint-test "(let ((a 2) (a 3)) a)" " let: let variable a is declared twice let: let variable a not used") (lint-test "(let (a) a)" " let: let binding is not a list? a") (lint-test "(let ((a 1) (set! a 2)))" " let: let is messed up: (let ((a 1) (set! a 2)))") (lint-test "(let ((a 1)) (set! a 2))" " let: let variable a set, but not used") (lint-test "(let ((a 1)) #f)" " let: perhaps (let ((a 1)) #f) -> #f let: let variable a not used") (lint-test "(let ((x 1) (y 2)) (+ x y))" " let: perhaps (let ((x 1) (y 2)) (+ x y)) -> 3") (lint-test "(let :x ((i y)) (x i))" " let: bad let name: :x") (lint-test "(let xx () z)" " let: perhaps (let xx () z) -> z let: let variable xx not used") (lint-test "(eq? x 1.5)" " eq?: eq? should be eqv? in (eq? x 1.5)") (lint-test "(eq? 3 x)" " eq?: eq? should be eqv? in (eq? 3 x)") (lint-test "(eq? x (not x))" " eq?: this looks odd: (eq? x (not x))") (lint-test "(eq? #(0) #(0))" " eq?: this looks odd: (eq? #(0) #(0)) eq?: eq? should be equal? in (eq? #(0) #(0))") (lint-test "(eq? #() ())" " eq?: eq? should be equal? in (eq? #() ())") (lint-test "(eq? (symbol->string x) z)" " eq?: eq? should be equal? in (eq? (symbol->string x) z)") (lint-test "(eq? (symbol? x) #t)" " eq?: perhaps (eq? (symbol? x) #t) -> (symbol? x)") (lint-test "(eq? (symbol? x) #f)" " eq?: perhaps (eq? (symbol? x) #f) -> (not (symbol? x))") (lint-test "(eq? x '())" " eq?: perhaps (eq? x '()) -> (null? x) eq?: quote is not needed here: '()") (lint-test "(eq? x '#\\a)" " eq?: eq? should be eqv? in (eq? x '#\\a)") (lint-test "(eqv? x ())" " eqv?: eqv? could be null?: (eqv? x ()) -> (null? x)") (lint-test "(eqv? x '())" " eqv?: eqv? could be null?: (eqv? x '()) -> (null? x) eqv?: quote is not needed here: '()") (lint-test "(eqv? x #(0))" " eqv?: eqv? should be equal? in (eqv? x #(0))") (lint-test "(eqv? x 'a)" " eqv?: eqv? could be eq? in (eqv? x 'a)") (lint-test "(eqv? x #f)" " eqv?: eqv? could be not: (eqv? x #f) -> (not x)") (lint-test "(equal? x 'a)" " equal?: equal? could be eq? in (equal? x 'a)") (lint-test "(equal? x (integer->char 96))" " equal?: equal? could be eqv? in (equal? x (integer->char 96))") (lint-test "(equal? x #f)" " equal?: equal? could be not: (equal? x #f) -> (not x)") (lint-test "(equal? x ())" " equal?: equal? could be null?: (equal? x ()) -> (null? x)") (lint-test "(equal? x '())" " equal?: equal? could be null?: (equal? x '()) -> (null? x) equal?: quote is not needed here: '()") (lint-test "(equal? (expt x y) z)" " equal?: equal? could be eqv? in (equal? (expt x y) z)") (lint-test "(morally-equal? x 'a)" " morally-equal?: morally-equal? could be eq? in (morally-equal? x 'a)") (lint-test "(morally-equal? x 0)" " morally-equal?: morally-equal? could be eqv? in (morally-equal? x 0)") (lint-test "(morally-equal? x 0.0)" "") (lint-test "(map abs '(1 2) '(3 4))" " map: map has too many arguments in: (map abs '(1 2) '(3 4))") (lint-test "(map (lambda (a b) a) '(1 2))" " map: map has too few arguments in: (map (lambda (a b) a) '(1 2))") (lint-test "(map (lambda (a) (abs a)) '(1 2 3))" " map: perhaps (lambda (a) (abs a)) -> abs") (lint-test "(map abs (vector->list #(1 2)))" " map: (vector->list #(1 2)) could be simplified to: #(1 2) ; (map accepts non-list sequences)") (lint-test "(begin (map g123 x) x)" " begin: map could be for-each: (map g123 x)") (lint-test "(map log x x)" "") (lint-test "(catch #(0) (lambda () #f) (lambda a a))" " catch: catch tag #(0) is unreliable (catch uses eq? to match tags)") (lint-test "(catch 'hi x y)" "") (lint-test "(car #(0))" " car: car's argument should be a pair?: #(0): (car #(0))") (lint-test "(vector->list 1.4)" " vector->list: vector->list's argument should be a vector?: 1.4: (vector->list 1.4)") (lint-test "(vector-set! #(0 1) 0 2)" " vector-set!: perhaps (vector-set! #(0 1) 0 2) -> 2") (lint-test "(defmacro hi ())" " defmacro: defmacro declaration is messed up: (defmacro hi ())") (lint-test "(defmacro hi (a b a) a)" " defmacro: defmacro parameter is repeated: (a b a)") (lint-test "(define)" " define: (define) makes no sense") (lint-test "(define a)" " define: (define a) has no value?") (lint-test "(define a . b)" " define: (define a . b) makes no sense") (lint-test "(define a b c)" " define: (define a b c) has too many values?") (lint-test "(define a a)" " define: this define is either not needed, or is an error: (define a a)") (lint-test "(define #(0) 2)" " define: strange form: (define #(0) 2)") (lint-test "(define (f1 a) (abs a))" " f1: f1 could be (define f1 abs)") (lint-test "(define (f1 a b) \"a docstring\" (log a b))" " f1: f1 could be (define f1 log)") (lint-test "(lambda ())" " lambda: lambda is messed up in (lambda ())") (lint-test "(lambda (a b a) a)" " lambda: lambda parameter is repeated: (a b a)") (lint-test "((lambda () 32) 0)" " (lambda () 32): lambda has too many arguments: ((lambda () 32) 0)") (lint-test "((lambda (a b) (+ a b)) 1)" " (lambda (a b) (+ a b)): lambda has too few arguments: ((lambda (a b) (+ a b)) 1) (lambda (a b) (+ a b)): perhaps (lambda (a b) (+ a b)) -> +") (lint-test "(lambda* (:key a :optional b :rest c :allow-other-keys) a)" " lambda*: :optional and key are no longer accepted: (:key a :optional b :rest c :allow-other-keys)") (lint-test "(lambda* (a :rest) a)" " lambda*: :rest parameter needs a name: (a :rest)") (lint-test "(lambda* (a :allow-other-keys b) a)" " lambda*: :allow-other-keys should be at the end of the parameter list:(a :allow-other-keys b)") (lint-test "(lambda (a :b c) a)" " lambda: lambda arglist can't handle keywords (use lambda*)") (lint-test "(lambda (a b) (>= b a))" " lambda: perhaps (lambda (a b) (>= b a)) -> <=") (lint-test "(lambda (a b c) (/ a b c))" " lambda: perhaps (lambda (a b c) (/ a b c)) -> /") (lint-test "(+ . 1)" " +: unexpected dot: (+ . 1)") (lint-test "(length (a . b))" " length: missing quote? (a . b) in (length (a . b))") (lint-test "(length ,a)" " length: stray comma? (unquote a) in (length (unquote a))") (lint-test "(let () (define (f1 a) a) (f1 2 3))" " let: f1 has too many arguments: (f1 2 3)") (lint-test "(let () (define-macro (f1 a) a) (f1 2 3))" " let: f1 has too many arguments: (f1 2 3)") (lint-test "(set! a b c)" " set!: set! has too many arguments: (set! a b c)") (lint-test "(set! a)" " set!: set! has too few arguments: (set! a)") (lint-test "(set! (vector-ref v 0) 3)" " set!: vector-ref as target of set! (set! (vector-ref v 0) 3)") (lint-test "(set! pi 3)" " set!: can't set! (set! pi 3) (it is a constant)") (lint-test "(set! 3 1)" " set!: can't set! (set! 3 1)") (lint-test "(set! a a)" " set!: pointless set! (set! a a)") (lint-test "(begin (set! x (cons 1 z)) (set! x (cons 2 x)))" " begin: perhaps (set! x (cons 1 z)) (set! x (cons 2 x)) -> (set! x (cons 2 (cons 1 z)))") (lint-test "(begin (set! x 0) (set! x 1))" " begin: this could be omitted: (set! x 0)") (lint-test "(quote 3)" " quote: quote is not needed here: '3") (lint-test "(quote . 3)" " quote: stray dot in quote's arguments? (quote . 3)") (lint-test "(quote 3 4)" " quote: quote has too many arguments: (quote 3 4)") (lint-test "'#(0)" " quote: quote is not needed here: '#(0)") (lint-test "(cond . 1)" " cond: cond is messed up: (cond . 1)") (lint-test "(cond 1)" " cond: cond clause is messed up: 1") (lint-test "(cond ((< 3 1) 2))" " cond: cond test is never true: (cond ((< 3 1) 2)) cond: cond test is always false: ((< 3 1) 2)") (lint-test "(cond (else 2) (x 3))" " cond: cond else clause is not the last: (cond (else 2) (x 3))") (lint-test "(cond (x => abs))" "") (lint-test "(cond (x =>))" " cond: cond => target is messed up: (x =>)") (lint-test "(cond (x #f) (#t #t))" " cond: perhaps (cond (x #f) (#t #t)) -> (not x)") (lint-test "(cond (x #t) (else #f))" " cond: perhaps (cond (x #t) (else #f)) -> x") (lint-test "(cond ((= x 1) 2) (else 2))" " cond: perhaps (cond ((= x 1) 2) (else 2)) -> 2") (lint-test "(cond ((and (display x) x) 32) (#t 32))" "") (lint-test "(cond (x y) (z 32) (else 32))" " cond: this clause could be omitted: (z 32)") (lint-test "(cond ((= x 1) (display \"a\") 32) (#t (display \"a\") 32))" " cond: perhaps (cond ((= x 1) (display \"a\") 32) (#t (display \"a\") 32)) -> (begin (display \"a\") 32)") (lint-test "(cond ((= x 1) 32))" "") (lint-test "(cond ((and (display 32) (= x 1)) 1) (#t 1))" "") (lint-test "(cond ((< x 1) 2) (else (cond ((< y 3) 2) (#t 4))))" " cond: else clause cond could be folded into the outer cond: (else (cond ((< y 3) 2) (#t 4)))") (lint-test "(cond ((< x 2) 3) ((> x 0) 4) ((< x 2) 5))" " cond: cond test is never true: (cond ((< x 2) 3) ((> x 0) 4) ((< x 2) 5)) cond: cond test repeated: ((< x 2) 5) cond: cond test is always false: ((< x 2) 5)") (lint-test "(cond ((< x 1) (+ x 1)) ((> x 1) (+ x 1)) (#t 2))" " cond: perhaps (cond ((< x 1) (+ x 1)) ((> x 1) (+ x 1)) (#t 2)) -> (cond ((or (< x 1) (> x 1)) (+ x 1)) (#t 2))") (lint-test "(cond ((= x 3) 4) ((= x 2) 4) ((= x 1) 4) (else 5))" " cond: perhaps (cond ((= x 3) 4) ((= x 2) 4) ((= x 1) 4) (else 5)) -> (cond ((memv x '(3 2 1)) 4) (else 5))") (lint-test "(cond ((= x 3) 3) ((= x 2) 4) ((= x 1) 4) (else 5))" " cond: perhaps (cond ((= x 3) 3) ((= x 2) 4) ((= x 1) 4) (else 5)) -> (cond ((= x 3) 3) ((memv x '(2 1)) 4) (else 5))") (lint-test "(cond (a) (b) (c))" " cond: perhaps (cond (a) (b) (c)) -> (cond ((or a b c)))") (lint-test "(cond ((= x 0) x) ((= x 1) (= x 1)))" " cond: no need to repeat the test: ((= x 1) (= x 1)) -> ((= x 1))") (lint-test "(cond (x => expt))" " cond: => target (expt) may be unhappy: (x => expt)") (lint-test "(cond (x (abs x)))" " cond: perhaps use => here: (x (abs x)) -> (x => abs)") (lint-test "(cond (x (let ((z w)) (+ x z)) y) (else 2))" " cond: this could be omitted: (let ((z w)) (+ x z))") (lint-test "(cond (x (if x y z) (+ x 1)) (z 2))" " cond: this could be omitted: (if x y z)") (lint-test "(let () (when a (+ x 1)) y)" " let: this could be omitted: (when a (+ x 1))") (lint-test "(let () (unless a (+ x 1)) y)" " let: this could be omitted: (unless a (+ x 1))") (lint-test "(let () (cond ((< x y) 3) ((< y z) 4)) (+ x 1))" " let: this could be omitted: (cond ((< x y) 3) ((< y z) 4))") (lint-test "(let () (case x ((0) 1) (else 2)) x)" " let: this could be omitted: (case x ((0) 1) (else 2))") (lint-test "(begin (let ((a (+ x 1)) (b 2)) (+ a b)) 32)" " begin: this could be omitted: (let ((a (+ x 1)) (b 2)) (+ a b))") (lint-test "(begin (if x y z) a)" " begin: this could be omitted: (if x y z)") (lint-test "(lambda (a) (if x y z) a)" " lambda: this could be omitted: (if x y z)") (lint-test "(lambda (a) (case x ((0) 1) (else x)) a)" " lambda: this could be omitted: (case x ((0) 1) (else x))") (lint-test "(let () (do ((i 0 (+ i 1))) ((= i 1))) x)" " let: this could be omitted: (do ((i 0 (+ i 1))) ((= i 1))) let: this do-loop could be replaced by (): (do ((i 0 (+ i 1))) ((= i 1)))") (lint-test "(case 3)" " case: case is messed up: (case 3)") (lint-test "(case 3 ((0) #t))" " case: case selector is a constant: (case 3 ((0) #t))") (lint-test "(case (list 1) ((0) #t))" " case: case selector may not work with eqv: (list 1) case: case key 0 in ((0) #t) is pointless") (lint-test "(case x (0))" " case: clause result is missing: (0) case: bad case key 0 in (0)") (lint-test "(case x ((0)))" " case: clause result is missing: ((0))") (lint-test "(case x ((0) 1) ((1) 2) ((3 0) 4))" " case: repeated case key 0 in ((3 0) 4)") (lint-test "(case x ((0) 1) ((1) 2) ((3 . 0) 4))" " case: stray dot in case case key list: ((3 . 0) 4)") (lint-test "(case x ((#(0)) 2))" " case: case key #(0) in ((#(0)) 2) is unlikely to work (case uses eqv?)") (lint-test "(case x (else 2) ((0) 1))" " case: case else clause is not the last: ((else 2) ((0) 1))") (lint-test "(case x ((0) 32) (else 32))" " case: perhaps (case x ((0) 32) (else 32)) -> 32") (lint-test "(case (string->symbol x) ((a) 1) ((2 3) 3))" " case: case key 2 in ((2 3) 3) is pointless case: case key 3 in ((2 3) 3) is pointless") (lint-test "(case c ((a) b) (else (begin (display d) e)))" " case: redundant begin: (begin (display d) e)") (lint-test "(case x ((0) 32) ((1) 32))" " case: perhaps (case x ((0) 32) ((1) 32)) -> (case x ((0 1) 32))") (lint-test "(case x ((0) 32) (else (case x ((1) 32))))" " case: perhaps (case x ((0) 32) (else (case x ((1) 32)))) -> (case x ((0 1) 32))") (lint-test "(case x ((0) 32) (else (case x ((1) 32)) x))" " case: this could be omitted: (case x ((1) 32))") (lint-test "(case x ((0) (display 1) 2) (else (display 1) 2))" " case: perhaps (case x ((0) (display 1) 2) (else (display 1) 2)) -> (begin (display 1) 2)") (lint-test "(case x (else (case x ((0) 1))))" " case: perhaps (case x (else (case x ((0) 1)))) -> (case x ((0) 1))") (lint-test "(case x (else (case x (else 1))))" " case: perhaps (case x (else 1)) -> 1 case: perhaps (case x (else (case x (else 1)))) -> 1") (lint-test "(case x ((0) 1) ((1 2) 1))" " case: perhaps (case x ((0) 1) ((1 2) 1)) -> (case x ((0 1 2) 1))") (lint-test "(case x ((0 1) (abs x)))" " case: perhaps use => here: ((0 1) (abs x)) -> ((0 1) => abs)") (lint-test "(case x ((a b a) 1) ((c) 2))" " case: repeated case key a in ((a b a) 1)") (lint-test "(do ())" " do: do is messed up: (do ())") (lint-test "(do () ())" " do: this do-loop could be replaced by (): (do () ())") (lint-test "(do ((x 2) y) ())" " do: do binding is not a list? y do: do variable x not used") (lint-test "(do ((x 2 1)) () x)" " do: this do-loop could be replaced by (): (do ((x 2 1)) () x) do: this could be omitted: x") (lint-test "(do ((x 2 1)) () (display 1))" " do: do variable x not used") (lint-test "(do ((i 0 (+ i 1))) ((+ i 10) i))" " do: end test is never false: (+ i 10)") (lint-test "(do ((i 0 (+ i 1))) (#f i))" " do: result is unreachable: (#f i)") (lint-test "(do ((i 0 (+ i 0))) ((= i 10) i))" " do: perhaps (+ i 0) -> i") (lint-test "(do ((i 0 (+ i 1))) ((= i len)) (string-set! s i #\\a))" " do: perhaps (do ((i 0 (+ i 1))) ((= i len)) (string-set! s i #\\a)) -> (fill! s #\\a 0 len)") (lint-test "(do ((i 0 (+ i 1))) ((= i len)) (vector-set! v0 i (vector-ref v1 i)))" " do: perhaps (do ((i 0 (+ i 1))) ((= i len)) (vector-set! v0 i (vector-ref v1 i))) -> (copy v1 v0 0 len)") (lint-test "(do ((i 0 (+ 1 1))) ((= i 3) z))" " do: perhaps (+ 1 1) -> 2") (lint-test "(do ((x lst (cdr lst))) ((null? x) y))" " do: this looks suspicious: (x lst (cdr lst))") (lint-test "(do ((i 0 (+ i 1))) ((>= i len)) (display i))" "") (lint-test "(do ((i 0 (+ i 1))) ((< i len)) (display i))" " do: do step looks like it doesn't match end test: (+ i 1) -> (< i len)") (lint-test "(do ((i 0 (- i 1))) ((<= i len)) (display i))" "") (lint-test "(do ((i 0 (- i 1))) ((> i len)) (display i))" " do: do step looks like it doesn't match end test: (- i 1) -> (> i len)") (lint-test "(do ((i 0 (+ i 1))) (= i 10) (display i))" " do: this could be omitted: (= i 10) do: perhaps missing parens: (= i 10)") (lint-test "(do ((i 0 (+ i 1)) (j 0 (+ j 1))) ((= i 10)) (display i))" " do: do variable j not used") (lint-test "(do ((i 0 (+ i j)) (j 0 (+ j 1))) ((= i 10)) (display i))" "") ; displays 00136 (lint-test "(do ((i 0 j) (j 0 (+ j 1))) (display i))" "") (lint-test "(do ((i 0 (display i))) ((x y) z))" "") ;(lint-test "(byte-vector 3213)" " byte-vector: byte-vector's argument should be a byte?: 3213: (byte-vector 3213)") (lint-test "(let ())" " let: let is messed up: (let ())") (lint-test "(let ((x (lambda (a) (x 1)))) x)" " let: let variable x is called in its binding? Perhaps let should be letrec: ((x (lambda (a) (x 1))))") (lint-test "(let* ((x 1)) x)" " let*: let* could be let: (let* ((x 1)) x)") (lint-test "(let* ((x 1) (x x)) x)" " let*: let* variable x is declared twice") (lint-test "(let* ((x (g g0)) (y (g g0))) (+ x y))" "") (lint-test "(let* ((x 0) (y (g 0))) (+ x y))" "") ; no telling what g is or does (lint-test "(let () (define x 3) (define (y a) a) (g z))" " let: let variables y, x not used") (lint-test "(letrec () 1)" " letrec: letrec could be let: (letrec () 1)") (lint-test "(letrec* ((a (lambda b (a 1)))) a)" " letrec*: letrec* could be letrec? (letrec* ((a (lambda b (a 1)))) a)") (lint-test "(begin . 1)" " begin: stray dot in begin? (begin . 1)") (lint-test "(begin (map abs x) #f)" " begin: map could be for-each: (map abs x) begin: this could be omitted: (map abs x)") (lint-test "(begin 1 #f)" " begin: this could be omitted: 1") (lint-test "(begin (+ x y) 3)" " begin: this could be omitted: (+ x y)") (lint-test "(begin (display 1) (begin #f))" " begin: redundant begin: (begin #f) begin: begin could be omitted: (begin #f)") (lint-test "(let () (display 1) (begin (display 1) #f))" " let: redundant begin: (begin (display 1) #f)") (lint-test "(if (< x 1) (begin x) y)" " if: begin could be omitted: (begin x)") (lint-test "(if (< x 1) (begin (display 1) x) y)" "") (lint-test "(format)" " format: format needs at least 1 argument: (format) format: format has too few arguments: (format)") (lint-test "(format (format #f str))" " format: redundant format: (format (format #f str))") (lint-test "(format #f \"~H\" 1)" " format: unrecognized format directive: H in \"~H\", (format #f \"~H\" 1)") (lint-test "(format #f \"~^\")" " format: ~^ has ^ outside ~{~}?") (lint-test "(format #f \"~A\")" " format: format has too few arguments: (format #f \"~A\")") (lint-test "(format #f \"~A\" 1 2)" " format: format has too many arguments: (format #f \"~A\" 1 2)") (lint-test "(format #f \"asdf~\")" " format: format control string ends in tilde: (format #f \"asdf~\")") (lint-test "(format #f \"~{~A\" 1)" " format: format has 1 unmatched {: (format #f \"~{~A\" 1)") (lint-test "(format #f \"123\")" " format: (format #f \"123\") could be \"123\", (format is a no-op here)") (lint-test "(format #f \"~nD\" 1 2)" "") (lint-test "(format #f \"~n,nD\" 1 2 3)" "") (lint-test "(format #f \"~nT\" 1 2)" " format: format has too many arguments: (format #f \"~nT\" 1 2)") (lint-test "(format #f \"~nD\" 1)" " format: format has too few arguments: (format #f \"~nD\" 1)") (lint-test "(format 1)" " format: format with one argument takes a string: (format 1)") (lint-test "(format #f \"~NC ~W\" 1 #\\c 2)" "") (lint-test "(open-output-file x \"fb+\")" " open-output-file: unexpected mode: (open-output-file x \"fb+\")") (lint-test "(vector 1 2 . 3)" " vector: unexpected dot: (vector 1 2 . 3)") (lint-test "(begin (display x) (newline) (display y) (newline))" " begin: perhaps ((display x) (newline) (display y) (newline)) -> (format () \"~A~%~A~%\" x y)") (lint-test "(begin (display x) (newline) (display y) (newline) 32)" " begin: perhaps ((display x) (newline) (display y) (newline)) -> (format () \"~A~%~A~%\" x y)") (lint-test "(begin (write x p) (newline p) (write-char #\\a p) (write-string \"bc\" p))" " begin: perhaps ((write x p) (newline p) (write-char #\\a p) (write-string \"bc\" p)) -> (format p \"~S~%abc\" x)") (lint-test "(begin (newline) (set! x 1) (display x) (newline) (newline))" " begin: perhaps ((display x) (newline) (newline)) -> (format () \"~A~%~%\" x)") (lint-test "(begin (write-string x p y z) (write-string \"1234\" p 1) (write-string \"5678\" p 2 3) (write-string \"abc\" p 2 z))" " begin: perhaps ((write-string x p y z) (write-string \"1234\" p 1) (write-string \"5678\" p 2 3) (write-string \"abc\" p 2 z)) -> (format p \"~A2347~A\" (substring x y z) (substring \"abc\" 2 z))") (lint-test "(substring x 0)" " substring: perhaps clearer: (substring x 0) -> (copy x)") (lint-test "(substring (substring x 1) 2)" " substring: perhaps (substring (substring x 1) 2) -> (substring x 3)") (lint-test "(list-tail x 0)" " list-tail: perhaps (list-tail x 0) -> x") (lint-test "(list-tail (list-tail x 1) 2)" " list-tail: perhaps (list-tail (list-tail x 1) 2) -> (list-tail x 3)") (lint-test "(list-tail (list-tail x y) z)" " list-tail: perhaps (list-tail (list-tail x y) z) -> (list-tail x (+ y z))") (lint-test "(unless x)" " unless: unless is messed up: (unless x)") (lint-test "(unless (abs x) #f)" " unless: unless test is never false: (unless (abs x) #f)") (lint-test "(with-let x)" " with-let: with-let is messed up: (with-let x)") (lint-test "(with-let (curlet) x)" " with-let: with-let is not needed here: (with-let (curlet) x)") (lint-test "(object->string x y)" "") (lint-test "(or)" " or: perhaps (or) -> #f") (lint-test "(or x)" " or: perhaps (or x) -> x") (lint-test "(or 'a)" " or: perhaps (or 'a) -> 'a") (lint-test "(or 'a 'b)" " or: perhaps (or 'a 'b) -> 'a") (lint-test "(or x x)" " or: perhaps (or x x) -> x") (lint-test "(or x x y)" " or: perhaps (or x x y) -> (or x y)") (lint-test "(or 1 x)" " or: perhaps (or 1 x) -> 1") (lint-test "(or (or y) x)" " or: perhaps (or (or y) x) -> (or y x)") (lint-test "(or (or y x) x)" " or: perhaps (or (or y x) x) -> (or y x)") (lint-test "(or x (not x))" " or: perhaps (or x (not x)) -> (or x #t)") (lint-test "(or (> x 1) (not (> x 1)))" " or: perhaps (or (> x 1) (not (> x 1))) -> (or (> x 1) #t)") (lint-test "(or x (and x y))" " or: perhaps (or x (and x y)) -> x") (lint-test "(or x #f y)" " or: perhaps (or x #f y) -> (or x y)") (lint-test "(or x #f)" " or: perhaps (or x #f) -> x") (lint-test "(or x (not (and x y)))" " or: perhaps (or x (not (and x y))) -> (or x #t)") (lint-test "(or (pair? x) (list? x))" " or: perhaps (or (pair? x) (list? x)) -> (list? x)") (lint-test "(or (number? x) (rational? x))" " or: perhaps (or (number? x) (rational? x)) -> (number? x)") (lint-test "(or (pair? x) (null? x))" "") (lint-test "(or (list? x) (list? x))" " or: perhaps (or (list? x) (list? x)) -> (list? x)") (lint-test "(or #f (= x 1))" " or: perhaps (or #f (= x 1)) -> (= x 1)") (lint-test "(or (integer? (cadr x)) (number? (cadr x)))" " or: perhaps (or (integer? (cadr x)) (number? (cadr x))) -> (number? (cadr x))") (lint-test "(or (eq? x 'a) (eq? x 'b) (eq? x 'c))" " or: perhaps (or (eq? x 'a) (eq? x 'b) (eq? x 'c)) -> (memq x '(a b c))") (lint-test "(or (= x 1) (= x 2) (= x 3))" " or: perhaps (or (= x 1) (= x 2) (= x 3)) -> (memv x '(1 2 3))") (lint-test "(or (equal? x #()) (equal? x #(1)))" " or: perhaps (or (equal? x #()) (equal? x #(1))) -> (member x '(#() #(1)))") (lint-test "(or (string=? x \"a\") (string=? x \"b\"))" " or: perhaps (or (string=? x \"a\") (string=? x \"b\")) -> (member x '(\"a\" \"b\") string=?)") (lint-test "(or (char=? (cadr x) #\\a) (char=? (cadr x) #\\b))" " or: perhaps (or (char=? (cadr x) #\\a) (char=? (cadr x) #\\b)) -> (memv (cadr x) '(#\\a #\\b))") (lint-test "(or (= (let ((z 1)) (display z) z) 1) (= (let ((z 1)) (display z) z) 2))" "") (lint-test "(or (not (null? x)) (not (pair? x)))" " or: perhaps (or (not (null? x)) (not (pair? x))) -> #t") (lint-test "(or (not (= x 1)) (not (= y 1)))" " or: perhaps (or (not (= x 1)) (not (= y 1))) -> (not (= x 1 y))") (lint-test "(or (char=? x #\\a) (char=? x #\\A))" " or: perhaps (or (char=? x #\\a) (char=? x #\\A)) -> (char-ci=? x #\\a)") (lint-test "(or (string=? x \"a\") (string=? x \"A\"))" " or: perhaps (or (string=? x \"a\") (string=? x \"A\")) -> (string-ci=? x \"a\")") (lint-test "(and)" " and: perhaps (and) -> #t") (lint-test "(and x)" " and: perhaps (and x) -> x") (lint-test "(and x #t)" "") (lint-test "(and x (not x))" " and: perhaps (and x (not x)) -> #f") (lint-test "(and x (and x y))" " and: perhaps (and x (and x y)) -> (and x y)") (lint-test "(and x (or x y))" " and: perhaps (and x (or x y)) -> x") (lint-test "(and (number? x) (pair? x))" " and: perhaps (and (number? x) (pair? x)) -> #f") (lint-test "(not (> x 1))" " not: perhaps (not (> x 1)) -> (<= x 1)") (lint-test "(not (exact? x))" " not: perhaps (not (exact? x)) -> (inexact? x)") (lint-test "(not (not x))" " not: perhaps (not (not x)) -> x") (lint-test "(not (zero? (logand x (ash 1 z))))" " not: perhaps (not (zero? (logand x (ash 1 z)))) -> (logbit? x z)") (lint-test "(not x y)" " not: not has too many arguments: (not x y) not: perhaps (not x y) -> (not)") (lint-test "(and x (or y 123) z)" " and: perhaps (and x (or y 123) z) -> (and x z)") (lint-test "(and (pair? x) (list? x))" " and: perhaps (and (pair? x) (list? x)) -> (pair? x)") (lint-test "(and (number? x) (rational? x))" " and: perhaps (and (number? x) (rational? x)) -> (rational? x)") (lint-test "(and (pair? x) (null? x))" " and: perhaps (and (pair? x) (null? x)) -> #f") (lint-test "(and (list? x) (list? x))" " and: perhaps (and (list? x) (list? x)) -> (list? x)") (lint-test "(and 3.1 #f (= x 1))" " and: perhaps (and 3.1 #f (= x 1)) -> #f") (lint-test "(and 3.1 #t (= x 1))" " and: perhaps (and 3.1 #t (= x 1)) -> (= x 1)") (lint-test "(and (number? (cadr x)) (integer? (cadr x)))" " and: perhaps (and (number? (cadr x)) (integer? (cadr x))) -> (integer? (cadr x))") (lint-test "(and x y x)" "") (lint-test "(and x y y)" " and: perhaps (and x y y) -> (and x y)") (lint-test "(and x y x y)" " and: perhaps (and x y x y) -> (and x y)") (lint-test "(and x #f y)" " and: perhaps (and x #f y) -> #f") (lint-test "(and x y #t z)" " and: perhaps (and x y #t z) -> (and x y z)") (lint-test "(and (g x) (g y) (g x))" "") (lint-test "(and (cadr x) (car y) (cadr x))" "") (lint-test "(and (cadr x) (car y) (cadr x) (car y))" " and: perhaps (and (cadr x) (car y) (cadr x) (car y)) -> (and (cadr x) (car y))") (lint-test "(and (g x) #f (g y))" " and: perhaps (and (g x) #f (g y)) -> (and (g x) #f)") (lint-test "(and x (or y 123 z))" " and: perhaps (and x (or y 123 z)) -> (and x (or y 123))") (lint-test "(and x (or y 123 z) w)" " and: perhaps (and x (or y 123 z) w) -> (and x w)") (lint-test "(and x (or (g y) z) w)" "") (lint-test "(and (integer? x) (number? x))" " and: perhaps (and (integer? x) (number? x)) -> (integer? x)") (lint-test "(and x y #t)" "") (lint-test "(and x y (integer? 1))" " and: perhaps (and x y (integer? 1)) -> (and x y #t)") (lint-test "(and x (or x y))" " and: perhaps (and x (or x y)) -> x") (lint-test "(and x (or x))" " and: perhaps (and x (or x)) -> x") (lint-test "(and (cadr x) (cadr x))" " and: perhaps (and (cadr x) (cadr x)) -> (cadr x)") (lint-test "(and (< x y) (< y z))" " and: perhaps (and (< x y) (< y z)) -> (< x y z)") (lint-test "(and (>= x y) (>= z x))" " and: perhaps (and (>= x y) (>= z x)) -> (>= z x y)") (lint-test "(and (>= x y) (>= x z))" "") (lint-test "(and (= x y) (= x z))" " and: perhaps (and (= x y) (= x z)) -> (= x y z)") (lint-test "(and (< x y) (> z y))" " and: perhaps (and (< x y) (> z y)) -> (< x y z)") (lint-test "(and (< x y) (< y (let ((z 1)) (display z) z)))" "") (lint-test "(and (pair? x) (null? x))" " and: perhaps (and (pair? x) (null? x)) -> #f") (lint-test "(car (car x))" " car: perhaps (car (car x)) -> (caar x)") (lint-test "(cdr (cadr x))" " cdr: perhaps (cdr (cadr x)) -> (cdadr x)") (lint-test "(car (car (cdr x)))" " car: perhaps (car (car (cdr x))) -> (caadr x)") (lint-test "(car (car (cdr (cdr x))))" " car: perhaps (car (car (cdr (cdr x)))) -> (caaddr x)") (lint-test "(car (cadr (cdr x)))" " car: perhaps (car (cadr (cdr x))) -> (caaddr x)") (lint-test "(cddar (car x))" " cddar: perhaps (cddar (car x)) -> (cddaar x)") (lint-test "(cadr (car (cdr x)))" " cadr: perhaps (cadr (car (cdr x))) -> (cadadr x)") (lint-test "(cddddr (cddr x))" " cddddr: perhaps (cddddr (cddr x)) -> (list-tail x 6)") (lint-test "(car (cddddr (cddr x)))" " car: perhaps (car (cddddr (cddr x))) -> (list-ref x 6)") (lint-test "(cadr (cddr (cdddr x)))" " cadr: perhaps (cadr (cddr (cdddr x))) -> (list-ref x 6)") (lint-test "(cadr (cddr (cdddr (cdr x))))" " cadr: perhaps (cadr (cddr (cdddr (cdr x)))) -> (list-ref x 7)") (lint-test "(cddddr (cdddr (cddddr x)))" " cddddr: perhaps (cddddr (cdddr (cddddr x))) -> (list-tail x 11)") (lint-test "(let ((x 3) (y 5)) (set! x (+ x y)) (+ x y))" " let: this could be omitted: (+ x y)") (lint-test "(let ((x 3)) (set! x (+ x 1)) x)" " let: this could be omitted: x") (lint-test "(begin (vector-set! x 0 32) (vector-ref x 0))" " begin: this could be omitted: (vector-ref x 0)") (lint-test "(begin (list-set! x (* y 2) 32) (list-ref x (* y 2)))" " begin: this could be omitted: (list-ref x (* y 2))") (lint-test "(let () (vector-set! x 0 32) (vector-ref x 0))" " let: this could be omitted: (vector-ref x 0)") (lint-test "(let () (list-set! x (* y 2) 32) (list-ref x (* y 2)))" " let: this could be omitted: (list-ref x (* y 2))") (lint-test "(begin (z 1) (do ((i 0 (+ i 1))) ((= i n) 32)))" " begin: this do-loop could be replaced by 32: (do ((i 0 (+ i 1))) ((= i n) 32))") (lint-test "(vector-set! v i (vector-ref v i))" " vector-set!: redundant?: (vector-set! v i (vector-ref v i))") (lint-test "(list-set! v (+ i 1) (list-ref v (+ i 1)))" " list-set!: redundant?: (list-set! v (+ i 1) (list-ref v (+ i 1)))") (lint-test "(abs () ())" " abs: abs has too many arguments: (abs () ()) abs: abs's argument 1 should be a real?: (): (abs () ())") (lint-test "(vector-ref (vector-ref x 0) y)" " vector-ref: perhaps (vector-ref (vector-ref x 0) y) -> (x 0 y)") (lint-test "(list-ref (list-ref (list-ref (cadr x) (+ y 1)) (+ y 2)) (+ y 3))" " list-ref: perhaps (list-ref (list-ref (list-ref (cadr x) (+ y 1)) (+ y 2)) (+ y 3)) -> ((cadr x) (+ y 1) (+ y 2) (+ y 3))") (if (not pure-s7) (lint-test "(current-output-port 123)" " current-output-port: too many arguments: (current-output-port 123)")) (lint-test "(copy (owlet))" " copy: (copy (owlet)) could be (owlet): owlet is copied internally") (lint-test "(gcd x '(asd))" " gcd: gcd's argument 2 should be a rational?: '(asd): (gcd x '(asd))") (lint-test "(string #\\null)" "") (lint-test "(string (char->integer x))" " string: string's argument should be a char?: (char->integer x): (string (char->integer x))") (lint-test "(close-output-port 022120)" " close-output-port: close-output-port's argument should be a output-port?: 22120: (close-output-port 22120)") (lint-test "(close-input-port (log 32))" " close-input-port: close-input-port's argument should be an input-port?: (log 32): (close-input-port (log 32))") (lint-test "(call-with-exit (lambda (p) (+ x 1)))" " call-with-exit: exit-function appears to be unused: (call-with-exit (lambda (p) (+ x 1)))") (lint-test "(call-with-output-file file (lambda (p) (+ x 1)))" " call-with-output-file: port appears to be unused: (call-with-output-file file (lambda (p) (+ x 1)))") (lint-test "(quasiquote 1 2)" " quasiquote: quasiquote has too many arguments: (quasiquote 1 2)") (lint-test "(apply + 1)" " apply: last argument should be a list: (apply + 1)") (lint-test "(apply (lambda (x) (abs x)) y)" " apply: perhaps (lambda (x) (abs x)) -> abs") (lint-test "(apply log (list x y))" " apply: perhaps (apply log (list x y)) -> (log x y)") (lint-test "(apply + 1 2 ())" " apply: perhaps (apply + 1 2 ()) -> 3") (lint-test "(apply real? 1 3 rest)" " apply: too many arguments for real?: (apply real? 1 3 rest)") (lint-test "(with-let 123 123)" " with-let: with-let: first argument should be an environment: (with-let 123 123)") (lint-test "(with-let random .1)" " with-let: with-let: first argument should be an environment: (with-let random 0.1)") (lint-test "(with-let (rootlet) 1)" "") (lint-test "(round '(1))" " round: round's argument should be a real?: '(1): (round '(1))") (lint-test "(round '1.2)" " round: quote is not needed here: '1.2") (lint-test "(round (integer->char 96))" " round: round's argument should be a real?: (integer->char 96): (round (integer->char 96))") (lint-test "(let ((v (make-vector 3))) (vector-set! v 3.14 #\\a))" " let: vector-set!'s argument 2 should be an integer?: 3.14: (vector-set! v 3.14 #\\a)") (lint-test "(let ((v (make-float-vector 3))) (float-vector-set! v 3.14 1))" " let: float-vector-set!'s argument 2 should be an integer?: 3.14: (float-vector-set! v 3.14 1)") (lint-test "(let ((v (make-float-vector 3))) (float-vector-set! v 1 3.14))" "") (lint-test "(let ((v (make-float-vector 3))) (float-vector-set! v 1 #\\a))" " let: float-vector-set!'s argument 3 should be a real?: #\\a: (float-vector-set! v 1 #\\a)") (lint-test "(append () '(1 2) 1)" "") (lint-test "(vector-set! (vector-ref a i) j x)" " vector-set!: perhaps (vector-set! (vector-ref a i) j x) -> (set! (a i j) x)") (lint-test "(round (char-position #\\a \"asb\"))" "") (lint-test "(string-ref (char-position #\\a \"asb\") 1)" " string-ref: string-ref's argument 1 should be a string?: (char-position #\\a \"asb\"): (string-ref (char-position #\\a \"asb\") 1)") (lint-test "(char-position \"xyz\" \"asb\")" "") (lint-test "(if (null? (cons x y)) 1.0 0.0)" " if: perhaps (if (null? (cons x y)) 1.0 0.0) -> 0.0") (lint-test "(if (null (cdr x)) 0)" " if: misspelled 'null? in (null (cdr x))?") (lint-test "(if (pair? (sin x)) 1.0 0.0)" " if: perhaps (if (pair? (sin x)) 1.0 0.0) -> 0.0") (lint-test "(if (number? (sin x)) 1.0)" " if: perhaps (if (number? (sin x)) 1.0) -> 1.0") (lint-test "(if (number? (car x)) 1.0)" "") (lint-test "(if (real? (sin x)) 1.0)" "") ; (lint-test "(real? (imag-part z))" "...") ; this should be reduced outside if... ; (lint-test "(char? (string-ref z y))" "...") (lint-test "(if (number? 1.0) 1.0 0.0)" " if: perhaps (if (number? 1.0) 1.0 0.0) -> 1.0") (lint-test "(if (pair? 1.0) 1.0 0.0)" " if: perhaps (if (pair? 1.0) 1.0 0.0) -> 0.0") (lint-test "(if (symbol? (string->symbol x)) 0 1)" " if: perhaps (if (symbol? (string->symbol x)) 0 1) -> 0") (lint-test "(if (symbol? (symbol->string x)) 0 1)" " if: perhaps (if (symbol? (symbol->string x)) 0 1) -> 1") (lint-test "(and (symbol? x) (gensym? x))" " and: perhaps (and (symbol? x) (gensym? x)) -> (gensym? x)") (lint-test "(integer? (*s7* 'vector-print-length))" " integer?: unknown *s7* field: 'vector-print-length") (lint-test "(dynamic-wind (lambda () (s7-version)) (lambda () (list)) (lambda () #f))" " dynamic-wind: perhaps (lambda () (s7-version)) -> s7-version dynamic-wind: perhaps (lambda () (list)) -> list") (lint-test "(lambda args (apply + args))" " lambda: perhaps (lambda args (apply + args)) -> +") (lint-test "(define-macro (mac a) `(+ ,,a 1))" " mac: define-macro probably has too many unquotes: ({list} '+ (unquote a) 1)") ;; these tickled a lint bug (lint-test "(define :xxx 321)" " define: keywords are constants :xxx") (lint-test "(define (:yyy a) a)" " define: keywords are constants :yyy") (lint-test "(define (f1) 32)" "") (lint-test "(define (f2 a) a)" "") (lint-test "(define (f3 . a) a)" "") (lint-test "(define (f4 a b) a)" "") (lint-test "(define (f5 a . b) a)" "") (lint-test "(define (f6 a b . c) a)" "") (lint-test "(define* (f1) 32)" " f1: define* could be define") (lint-test "(define* (f2 a) a)" "") (lint-test "(define* (f3 . a) a)" "") (lint-test "(define* (f4 a (b 2)) a)" "") (lint-test "(define* (f5 a :rest b) a)" "") (lint-test "(define* (f6 a b :allow-other-keys) a)" "") (lint-test "(define f1 (lambda () 32))" "") (lint-test "(define f2 (lambda (a) a))" "") (lint-test "(define f3 (lambda a a))" "") (lint-test "(define f4 (lambda (a b) a))" "") (lint-test "(define f5 (lambda (a . b) a))" "") (lint-test "(define-macro (f1) 32)" "") (lint-test "(define-macro (f2 a) a)" "") (lint-test "(define-macro (f3 . a) a)" "") (lint-test "(define-macro (f4 a b) a)" "") (lint-test "(define-macro (f5 a . b) a)" "") (lint-test "(define-macro (f6 a b . c) a)" "") (lint-test "(let ((a 1)) (define (f1 b) (+ a b)) (f1 0))" "") (lint-test "(let f1 ((a 1)) a)" " let: let variable f1 not used") (lint-test "(let f1 ((a 1)) (f1 a))" "") (lint-test "(let f1 ((a 1)) (+ a (f1)))" " let: f1 needs 1 argument: (f1)") (lint-test "(let f1 ((a 1)) (f1 a 2))" " let: f1 has too many arguments: (f1 a 2)") (lint-test "(define f7 (let ((a 1)) (lambda () a)))" "") (lint-test "(let () (define f7 (let ((a 1)) (lambda () a))) (f7))" "") (lint-test "(let () (define f7 (let ((a 1)) (lambda () a))) (f7 1))" "...") (lint-test "(let () (define (f1) 32) (f1))" "") (lint-test "(let () (define (f1) 32) (f1 32))" " let: f1 has too many arguments: (f1 32)") (lint-test "(let () (define (f2 a) a) (f2))" " let: f2 needs 1 argument: (f2)") (lint-test "(let () (define (f2 a) a) (f2 3))" "") (lint-test "(let () (define (f2 a) a) (f2 3 32))" " let: f2 has too many arguments: (f2 3 32)") (lint-test "(let () (define (f3 . a) a) (f3))" "") (lint-test "(let () (define (f3 . a) a) (f3 1))" "") (lint-test "(let () (define (f3 . a) a) (f3 1 2 3))" "") (lint-test "(let () (define (f4 a b) a) (f4))" " let: f4 needs 2 arguments: (f4)") (lint-test "(let () (define (f4 a b) a) (f4 1))" " let: f4 needs 2 arguments: (f4 1)") (lint-test "(let () (define (f4 a b) a) (f4 1 2))" "") (lint-test "(let () (define (f4 a b) a) (f4 1 2 3))" " let: f4 has too many arguments: (f4 1 2 3)") (lint-test "(let () (define (f5 a . b) a) (f5))" " let: f5 needs 1 argument: (f5)") (lint-test "(let () (define (f5 a . b) a) (f5 1))" "") (lint-test "(let () (define (f5 a . b) a) (f5 1 2))" "") (lint-test "(let () (define (f5 a . b) a) (f5 1 2 3 4))" "") (lint-test "(let () (define (f6 a b . c) a) (f6))" " let: f6 needs 2 arguments: (f6)") (lint-test "(let () (define (f6 a b . c) a) (f6 1))" " let: f6 needs 2 arguments: (f6 1)") (lint-test "(let () (define (f6 a b . c) a) (f6 1 2))" "") (lint-test "(let () (define (f6 a b . c) a) (f6 1 2 3))" "") (lint-test "(let () (define (f6 a b . c) a) (f6 1 2 3 4))" "") (lint-test "(begin (define* (f1) 32) (f1))" " f1: define* could be define") (lint-test "(begin (define* (f1) 32) (f1 :a 1))" " f1: define* could be define begin: f1 has too many arguments: (f1 :a 1)") (lint-test "(begin (define* (f2 a) a) (f2))" "") (lint-test "(begin (define* (f2 a) a) (f2 1))" "") (lint-test "(begin (define* (f2 a) a) (f2 :a 1))" "") (lint-test "(begin (define* (f2 a) a) (f2 :b 1))" " begin: f2 keyword argument :b (in (f2 :b 1)) does not match any argument in (a)") (lint-test "(begin (define* (f2 a) a) (f2 :a 1 2))" " begin: f2 has too many arguments: (f2 :a 1 2)") (lint-test "(begin (define* (f2 a) a) (f2 :a 1 :a 2))" " begin: f2 has too many arguments: (f2 :a 1 :a 2)") (lint-test "(begin (define* (f2 a) a) (f2 1 2))" " begin: f2 has too many arguments: (f2 1 2)") (lint-test "(begin (define* (f3 . a) a) (f3))" "") (lint-test "(begin (define* (f3 . a) a) (f3 1))" "") (lint-test "(begin (define* (f3 . a) a) (f3 :a 1))" "") (lint-test "(begin (define* (f3 . a) a) (f3 1 2))" "") (lint-test "(begin (define* (f4 a (b 2)) a) (f4))" "") (lint-test "(begin (define* (f4 a (b 2)) a) (f4 :a 1))" "") (lint-test "(begin (define* (f4 a (b 2)) a) (f4 :b 1))" "") (lint-test "(begin (define* (f4 a (b 2)) a) (f4 :c 1))" " begin: f4 keyword argument :c (in (f4 :c 1)) does not match any argument in (a (b 2))") (lint-test "(begin (define* (f4 a (b 2)) a) (f4 :a 1 :c 2))" " begin: f4 keyword argument :c (in (f4 :a 1 :c 2)) does not match any argument in (a (b 2))") (lint-test "(begin (define* (f4 a (b 2)) a) (f4 :a 1 :b 2))" "") (lint-test "(begin (define* (f5 a :rest b) a) (f5))" "") (lint-test "(begin (define* (f5 a :rest b) a) (f5 1))" "") (lint-test "(begin (define* (f5 a :rest b) a) (f5 1 2 3))" "") (lint-test "(begin (define* (f5 a :rest b) a) (f5 :b 1))" "") (lint-test "(begin (define* (f5 a :rest b) a) (f5 :a 1 2 3))" "") (lint-test "(begin (define* (f6 a b :allow-other-keys) a) (f6))" "") (lint-test "(begin (define* (f6 a b :allow-other-keys) a) (f6 :a 1 :b 2 :c 3))" "") (lint-test "(let () (define (f8 a b) (+ 1 (f8 2 3))) (f8 1 2))" "") (lint-test "(let () (define (f8 a b) ((lambda (c) (f8 c 3)) 1)) (f8 1 2))" "") (lint-test "(let () (define (f1) 32) (set! f1 4) (+ 1 f1))" "") (lint-test "(let () (define f10 (lambda (a) a)) (set! f10 (lambda (a b) (+ a b))) (f10 1 2))" " let: perhaps (lambda (a b) (+ a b)) -> +") (when (provided? 'snd) (lint-test "(if (real? (oscil x)) 1.0 0.0)" " if: perhaps (if (real? (oscil x)) 1.0 0.0) -> 1.0") (lint-test "(if (pair? (oscil x)) 1.0 0.0)" " if: perhaps (if (pair? (oscil x)) 1.0 0.0) -> 0.0") (lint-test "(if (float? (oscil x)) 1.0 0.0)" " if: perhaps (if (float? (oscil x)) 1.0 0.0) -> 1.0") (lint-test "(radians->hz 3.4+i)" " radians->hz: radians->hz's argument should be a real?: 3.4+1i: (radians->hz 3.4+1i)") (lint-test "(string-ref (radians->hz x) 3)" " string-ref: string-ref's argument 1 should be a string?: (radians->hz x): (string-ref (radians->hz x) 3)") (lint-test "(set! (print-length) \"asd\")" " set!: print-length: new value should be an integer?: string?: (set! (print-length) \"asd\")") (lint-test "(set! (print-length) 9)" "") (lint-test "(set! (show-indices) 32)" " set!: show-indices: new value should be a boolean?: integer?: (set! (show-indices) 32)") (lint-test "(set! (show-indices) #t)" "") ) (define f321 (let ((signature '(float? integer?))) (lambda (int) (if (integer? int) (* 1.0 int) (error 'wrong-type-arg "~A: ~A is not an integer" f321 int))))) (lint-test "(string-ref (f321 3) 2)" " string-ref: string-ref's argument 1 should be a string?: (f321 3): (string-ref (f321 3) 2)") (set! reader-cond #f) ) #| (let ((old+ +)) (let ((vals (list (let () (define a 32) (define p +) (define (f b) (+ a b)) (set! a 1) (let ((t1 (f 2))) (set! + -) (let ((t2 (f 2))) (let ((t3 (equal? p +))) (list t1 t2 t3))))) ;; s7: (3 -1 #f) ; this is now (3 3 #f) which strikes me as correct ;; guile: (3 3 #f) (let () (define a 32) (define p old+) (define (f b) (p a b)) (set! a 1) (let ((t1 (f 2))) (set! p -) (let ((t2 (f 2))) (let ((t3 (equal? p old+))) (list t1 t2 t3))))) ;; s7 (3 -1 #t) ;; guile (3 -1 #t) ))) (set! + old+) (test (car vals) (cadr vals)))) |# (let ((old+ +)) (define (f x) (with-let (unlet) (+ x 1))) (set! + -) (test (+ 1 1) 0) (test (f 1) 2) (set! + old+)) (let ((old+ +)) (let ((f #f)) (let ((+ -)) (set! f (lambda (a) (+ 1 a)))) (test (f 2) -1) (set! + *) (test (f 2) -1) (set! + old+))) #| ;;; this is confusing lint in t101.scm (set! *#readers* old-readers) (set! *#readers* (list (cons #\F (lambda (s) (and (string=? s "F") (list 'not #t)))) (cons #\F (lambda (s) (and (string=? s "First") 1))))) (let ((x #F)) (if x (format *stderr* "#F true?~%")) ; to what extent can this actually work? (if #F (format *stderr* "#F #t?~%"))) (let ((x #First)) (test (+ x 1) 2) (test (if #F #First (not #F)) #t)) (set! *#readers* (list (cons #\A (lambda (s) (and (string=? s "A") let))) (cons #\B (lambda (s) (and (string=? s "B") `((x 1))))) (cons #\C (lambda (s) (and (string=? s "C") `(+ x 1)))))) (test (#A #B #C) 2) ; yow!! (set! *#readers* old-readers) |# #| (define (mu) ; infinite loop if bignums (let* ((x 1) (xp (+ x 1))) (do () ((<= xp 1) (list (* 2 x) (* 2.0 x))) (set! x (/ x 2)) (set! xp (+ x 1))))) ; (1/1152921504606846976 8.673617379884e-19) smallest positive normalized fp 2-1022 = 2.225 10-308 largest normalized fp 2+1023 (2 - 2-52) 2+1024 - 2+971 = 1.798 10+308 smallest positive denormal 2-1023 2-52 2-1075 = 2.470 10-324 largest denormal 2-1023 (1 - 2-52) 2-1023 - 2-1075 = 1.113 10-308 largest fp integer 2+1024 - 2+971 = 1.798 10+308 gap from largest fp integer to previous fp integer 2+971 = 1.996 10+292 largest fp integer with a predecessor 2+53 - 1 = 9,007,199,254,740,991 #x7ff0000000000000 +inf #xfff0000000000000 -inf #x7ff8000000000000 nan #xfff8000000000000 -nan but how to build these in scheme? (set! flt (integer-encode-float 0 #x7ff 0)) ? (would need check for invalid args) in C: s7_pointer p; unsigned long long int NAN_1, NAN_0; s7_double f_NAN_0, f_NAN_1; p = s7_make_real(sc, NAN); f_NAN_0 = real(p); NAN_0 = integer(p); NAN_1 = integer(p) | 1; f_NAN_1 = (* ((s7_double*)(&NAN_1))); fprintf(stderr, "%llx %f %d, %llx %f %d\n", NAN_0, f_NAN_0, is_NaN(f_NAN_0), NAN_1, f_NAN_1, is_NaN(f_NAN_1)); 7ff8000000000000 nan 1, 7ff8000000000001 nan 1 so we can use these low order bits to mark where the NaN was created but I think we get NaN's implicitly and s7_make_real does not check in non-gmp, (+ most-negative-fixnum -1 most-positive-fixnum) is the same as (+ most-positive-fixnum most-positive-fixnum) -> -2! apparently in solaris, it's NaN.0 not nan.0? fprintf(stderr, "NaN: %f %e %g\n", NAN, NAN, NAN); in every other case this prints "nan nan nan", but on Solaris it's "NaN NaN NaN" (let ((lst ())) (do ((i 0 (+ i 1))) ((= i 1000) (reverse lst)) (set! lst (cons i lst)))) ;;; ok (tested) up to 10000000 (set! (*s7* 'print-length) 256) (let ((st (symbol-table)) (counts 0) (alphs (make-vector 256 0 #t)) (alph-min (make-vector 256 256 #t)) (alph-max (make-vector 256 -1 #t))) (for-each (lambda (sym) (let ((name (symbol->string sym))) (if (= (length name) 2) (let ((index (char->integer (name 0))) (index2 (char->integer (name 1)))) (set! counts (+ counts 1)) (set! (alphs index) (+ (alphs index) 1)) (set! (alph-min index) (min (alph-min index) index2)) (set! (alph-max index) (max (alph-min index) index2)))))) st) (format *stderr* "~A~%" (list counts (let ((in-use 0)) (for-each (lambda (c) (if (> c 0) (set! in-use (+ in-use 1)))) alphs) in-use) (let ((total 0)) (do ((i 0 (+ i 1))) ((= i 256)) (if (>= (alph-max i) 0) (set! total (+ total (+ 1 (- (alph-max i) (alph-min i))))))) total) alphs))) ;; this works but has the same results as (let () (load "s7test.scm" (curlet))) ;; some minor __func__ mis-assumption at 27547 (let () (call-with-input-file "s7test.scm" (lambda (p) (do ((form (read p) (read p))) ((eq? form #)) (eval form))))) |# (when (and full-test (provided? 'snd)) ; repl gets confused here (set! *#readers* ()) (require lint.scm) (lint "s7test.scm" #f)) #| (for-each (lambda (s) (if (and (symbol-access s) (not (char=? #\* ((symbol->string s) 0)))) (format *stderr* "~A " s))) (symbol-table)) (for-each (lambda (s) (if (and (dilambda? (symbol->value s)) (defined? (string->symbol (string-append "*" (symbol->string s) "*")))) (format *stderr* "~A " s))) (symbol-table)) (let ((vars (make-vector 32 0))) (for-each (lambda (s) (let ((len (min (length (symbol->string s)) 31))) (set! (vars len) (+ (vars len) 1)))) (symbol-table)) (do ((i 0 (+ i 1))) ((= i 32)) (format *stderr* "~D: ~D~%" i (vars i)))) (let ((st (symbol-table))) (for-each (lambda (s) (if (and (keyword? s) (not (eq? s (symbol->value s)))) (format *stderr* "~S: ~S~%" s (symbol->value s)))) st)) |# (if (provided? 'debugging) (format-logged #t "~%;all done! (debugging flag is on)~%") (format-logged #t "~%;all done!~%")) ;(close-output-port error-port) (s7-version) (if s7test-exits (exit)) snd-16.1/snd-gmix.c0000644000076400007640000007644012512761107012242 0ustar bilbil#include "snd.h" /* ---------------- mix dialog ---------------- */ static GtkWidget *mix_dialog = NULL; static int mix_dialog_id = INVALID_MIX_ID, old_mix_dialog_id = INVALID_MIX_ID; static env *dialog_env = NULL; static bool dragging = false; static int edpos_before_drag; static with_hook_t hookable_before_drag; static mus_long_t drag_beg = 0, drag_end = 0; static void start_dragging(int mix_id) { chan_info *cp; cp = mix_chan_info_from_id(mix_id); edpos_before_drag = cp->edit_ctr; hookable_before_drag = cp->hookable; cp->hookable = WITHOUT_HOOK; dragging = true; drag_beg = mix_position_from_id(mix_id); drag_end = drag_beg + mix_length_from_id(mix_id); start_dragging_syncd_mixes(mix_id); } static void keep_dragging(int mix_id) { chan_info *cp; cp = mix_chan_info_from_id(mix_id); cp->edit_ctr = edpos_before_drag; keep_dragging_syncd_mixes(mix_id); } static void stop_dragging(int mix_id) { chan_info *cp; cp = mix_chan_info_from_id(mix_id); undo_edit(cp, 1); cp->hookable = hookable_before_drag; dragging = false; stop_dragging_syncd_mixes(mix_id); } /* -------- speed -------- */ static GtkWidget *w_speed, *w_speed_label, *w_speed_number, *w_speed_form, *w_speed_event, *w_speed_label_event; static GtkAdjustment *w_speed_adj; static bool speed_pressed = false, speed_dragged = false; /* can't use value_changed on adjustment and motion event happens even when the mouse merely moves across the slider without dragging */ static speed_style_t gmix_speed_control_style = SPEED_CONTROL_AS_FLOAT; #if WITH_AUDIO static graphics_context *mix_play_ax = NULL; #endif static mus_float_t speed_to_scrollbar(mus_float_t minval, mus_float_t val, mus_float_t maxval) { if (val <= minval) return(0.0); if (val >= maxval) return(0.9); return(0.9 * ((log(val) - log(minval)) / (log(maxval) - log(minval)))); } static mus_float_t scrollbar_to_speed(mus_float_t scroll) { return(exp((scroll * (log(speed_control_max(ss)) - log(speed_control_min(ss))) / 0.9) + log(speed_control_min(ss)))); } static mus_float_t set_speed_label(GtkWidget *label, mus_float_t in_speed) { mus_float_t speed; char speed_number_buffer[6]; speed = speed_changed(in_speed, speed_number_buffer, gmix_speed_control_style, speed_control_tones(ss), 6); gtk_label_set_text(GTK_LABEL(label), speed_number_buffer); return(speed); } static void reflect_mix_speed(mus_float_t speed) { ADJUSTMENT_SET_VALUE(w_speed_adj, speed_to_scrollbar(speed_control_min(ss), set_speed_label(w_speed_number, speed), speed_control_max(ss))); /* gtk_adjustment_value_changed(GTK_ADJUSTMENT(w_speed_adj)); */ } static gboolean mix_speed_click_callback(GtkWidget *w, GdkEventButton *ev, gpointer data) { /* label click -- not part of slider stuff */ speed_pressed = false; speed_dragged = false; if (!(mix_is_active(mix_dialog_id))) return(false); mix_set_speed_edit(mix_dialog_id, 1.0); syncd_mix_set_speed(mix_dialog_id, 1.0); after_mix_edit(mix_dialog_id); after_syncd_mix_edit(mix_dialog_id); reflect_mix_speed(1.0); return(false); } static gboolean speed_label_click_callback(GtkWidget *w, GdkEventButton *ev, gpointer data) { /* (number) label click -- not part of slider stuff */ speed_pressed = false; speed_dragged = false; if (!(mix_is_active(mix_dialog_id))) return(false); switch (gmix_speed_control_style) { default: case SPEED_CONTROL_AS_FLOAT: gmix_speed_control_style = SPEED_CONTROL_AS_RATIO; break; case SPEED_CONTROL_AS_RATIO: gmix_speed_control_style = SPEED_CONTROL_AS_SEMITONE; break; case SPEED_CONTROL_AS_SEMITONE: gmix_speed_control_style = SPEED_CONTROL_AS_FLOAT; break; } set_speed_label(w_speed_number, mix_speed_from_id(mix_dialog_id)); return(false); } static gboolean speed_motion_callback(GtkWidget *w, GdkEventMotion *ev, gpointer data) { mus_float_t speed; mus_long_t beg, end; if (!speed_pressed) {speed_dragged = false; return(false);} speed_dragged = true; if (!(mix_is_active(mix_dialog_id))) return(false); if (!dragging) start_dragging(mix_dialog_id); else keep_dragging(mix_dialog_id); speed = set_speed_label(w_speed_number, scrollbar_to_speed(ADJUSTMENT_VALUE(w_speed_adj))); mix_set_speed_edit(mix_dialog_id, speed); beg = mix_position_from_id(mix_dialog_id); end = beg + mix_length_from_id(mix_dialog_id); if (drag_beg > beg) drag_beg = beg; if (drag_end < end) drag_end = end; mix_display_during_drag(mix_dialog_id, drag_beg, drag_end); syncd_mix_set_speed(mix_dialog_id, speed); return(false); } static gboolean mix_speed_release_callback(GtkWidget *w, GdkEventButton *ev, gpointer data) { mus_float_t speed; speed_pressed = false; speed_dragged = false; if (!(mix_is_active(mix_dialog_id))) return(false); if (dragging) stop_dragging(mix_dialog_id); speed = set_speed_label(w_speed_number, scrollbar_to_speed(ADJUSTMENT_VALUE(w_speed_adj))); mix_set_speed_edit(mix_dialog_id, speed); syncd_mix_set_speed(mix_dialog_id, speed); after_mix_edit(mix_dialog_id); after_syncd_mix_edit(mix_dialog_id); return(false); } static gboolean speed_press_callback(GtkWidget *w, GdkEventButton *ev, gpointer data) { speed_dragged = false; speed_pressed = true; return(false); } /* -------- amp -------- */ static GtkWidget *w_amp, *w_amp_label, *w_amp_number, *w_amp_event, *w_amp_form; static GtkAdjustment *w_amp_adj; static mus_float_t scrollbar_to_amp(mus_float_t val) { if (val <= 0.0) return(amp_control_min(ss)); if (val >= 0.9) return(amp_control_max(ss)); if (val > (0.5 * 0.9)) return((((val / (0.5 * 0.9)) - 1.0) * (amp_control_max(ss) - 1.0)) + 1.0); else return((val * (1.0 - amp_control_min(ss)) / (0.5 * 0.9)) + amp_control_min(ss)); } static bool amp_pressed = false, amp_dragged = false; static void reflect_mix_amp(mus_float_t val) { char sfs[6]; ADJUSTMENT_SET_VALUE(w_amp_adj, amp_to_scroll(amp_control_min(ss), val, amp_control_max(ss))); /* gtk_adjustment_value_changed(GTK_ADJUSTMENT(w_amp_adj)); */ snprintf(sfs, 6, "%.2f", val); gtk_label_set_text(GTK_LABEL(w_amp_number), sfs); } static gboolean mix_amp_click_callback(GtkWidget *w, GdkEventButton *ev, gpointer data) { amp_dragged = false; amp_pressed = false; if (!(mix_is_active(mix_dialog_id))) return(false); reflect_mix_amp(1.0); mix_set_amp_edit(mix_dialog_id, 1.0); syncd_mix_set_amp(mix_dialog_id, 1.0); after_mix_edit(mix_dialog_id); after_syncd_mix_edit(mix_dialog_id); ADJUSTMENT_SET_VALUE(w_amp_adj, amp_to_scroll(amp_control_min(ss), 1.0, amp_control_max(ss))); /* gtk_adjustment_value_changed(GTK_ADJUSTMENT(w_amp_adj)); */ return(false); } static gboolean amp_motion_callback(GtkWidget *w, GdkEventMotion *ev, gpointer data) { mus_float_t amp; if (!amp_pressed) {amp_dragged = false; return(false);} amp_dragged = true; if (!(mix_is_active(mix_dialog_id))) return(false); if (!dragging) start_dragging(mix_dialog_id); else keep_dragging(mix_dialog_id); amp = scrollbar_to_amp(ADJUSTMENT_VALUE(w_amp_adj)); reflect_mix_amp(amp); mix_set_amp_edit(mix_dialog_id, amp); mix_display_during_drag(mix_dialog_id, drag_beg, drag_end); syncd_mix_set_amp(mix_dialog_id, amp); return(false); } static gboolean mix_amp_release_callback(GtkWidget *w, GdkEventButton *ev, gpointer data) { mus_float_t amp; dragging = false; amp_pressed = false; amp_dragged = false; if (!(mix_is_active(mix_dialog_id))) return(false); if (dragging) stop_dragging(mix_dialog_id); amp = scrollbar_to_amp(ADJUSTMENT_VALUE(w_amp_adj)); reflect_mix_amp(amp); mix_set_amp_edit(mix_dialog_id, amp); syncd_mix_set_amp(mix_dialog_id, amp); after_mix_edit(mix_dialog_id); after_syncd_mix_edit(mix_dialog_id); return(false); } static gboolean amp_press_callback(GtkWidget *w, GdkEventButton *ev, gpointer data) { amp_pressed = true; amp_dragged = false; return(false); } /* -------- amp-env -------- */ static GtkWidget *w_env_frame, *w_env; static graphics_context *ax = NULL; static gc_t *cur_gc; static env_editor *spf = NULL; static bool with_mix_background_wave = false; static void show_mix_background_wave(int mix_id) { env_editor *e; int pts; bool two_sided = false; e = spf; if (e == NULL) return; pts = prepare_mix_dialog_waveform(mix_id, e->axis, &two_sided); if (pts > 0) { gc_set_foreground(ax->gc, ss->enved_waveform_color); if (two_sided) draw_both_grf_points(1, ax, pts, GRAPH_LINES); else draw_grf_points(1, ax, pts, e->axis, ungrf_y(e->axis, 0.0), GRAPH_LINES); gc_set_foreground(ax->gc, ss->black); } } static void mix_amp_env_resize(GtkWidget *w) { if (!(mix_is_active(mix_dialog_id))) return; if (ax == NULL) { cur_gc = gc_new(); gc_set_background(cur_gc, ss->graph_color); gc_set_foreground(cur_gc, ss->data_color); ax = (graphics_context *)calloc(1, sizeof(graphics_context)); ax->wn = WIDGET_TO_WINDOW(w_env); ax->w = w_env; ax->gc = cur_gc; } ss->cr = make_cairo(ax->wn); cairo_push_group(ss->cr); /* erase previous */ cairo_set_source_rgba(ss->cr, cur_gc->bg_color->red, cur_gc->bg_color->green, cur_gc->bg_color->blue, cur_gc->bg_color->alpha); cairo_rectangle(ss->cr, 0, 0, widget_width(w), widget_height(w)); cairo_fill(ss->cr); spf->with_dots = true; env_editor_display_env(spf, dialog_env, ax, "mix env", 0, 0, widget_width(w), widget_height(w), NOT_PRINTING); if (with_mix_background_wave) show_mix_background_wave(mix_dialog_id); cairo_pop_group_to_source(ss->cr); cairo_paint(ss->cr); free_cairo(ss->cr); ss->cr = NULL; } static gboolean mix_drawer_button_press(GtkWidget *w, GdkEventButton *ev, gpointer data) { if (!(mix_is_active(mix_dialog_id))) return(false); spf->with_dots = false; if (env_editor_button_press(spf, (int)(EVENT_X(ev)), (int)(EVENT_Y(ev)), EVENT_TIME(ev), dialog_env)) mix_amp_env_resize(w); return(false); } static gboolean mix_drawer_button_release(GtkWidget *w, GdkEventButton *ev, gpointer data) { if (!(mix_is_active(mix_dialog_id))) return(false); env_editor_button_release(spf, dialog_env); mix_amp_env_resize(w); return(false); } static gboolean mix_drawer_button_motion(GtkWidget *w, GdkEventMotion *ev, gpointer data) { if (!(mix_is_active(mix_dialog_id))) return(false); if (BUTTON1_PRESSED(EVENT_STATE(ev))) { int x, y; GdkModifierType state; if (EVENT_IS_HINT(ev)) window_get_pointer(ev, &x, &y, &state); else { x = (int)(EVENT_X(ev)); y = (int)(EVENT_Y(ev)); } spf->with_dots = false; env_editor_button_motion(spf, x, y, EVENT_TIME(ev), dialog_env); mix_amp_env_resize(w); } return(false); } static gboolean mix_amp_env_expose_callback(GtkWidget *w, GdkEventExpose *ev, gpointer data) { mix_amp_env_resize(w); return(false); } static gboolean mix_amp_env_resize_callback(GtkWidget *w, GdkEventConfigure *ev, gpointer data) { if (!(mix_is_active(mix_dialog_id))) return(false); mix_amp_env_resize(w); return(false); } static GtkWidget *w_id = NULL, *w_beg = NULL, *w_id_label = NULL; #if WITH_AUDIO static GtkWidget *mix_play = NULL; #endif static bool id_changed = false; static GtkWidget *error_frame = NULL, *error_label = NULL; static void clear_mix_error(void) { if ((error_frame) && (widget_is_active(error_frame))) gtk_widget_hide(error_frame); } static gint unpost_mix_error(gpointer data) { clear_mix_error(); return(0); } static void errors_to_mix_text(const char *msg, void *data) { gtk_label_set_text(GTK_LABEL(error_label), msg); gtk_widget_show(error_frame); g_timeout_add_full(0, (guint32)5000, unpost_mix_error, NULL, NULL); } static void id_activated(GtkWidget *w, gpointer context) { char *val; id_changed = false; val = (char *)gtk_entry_get_text(GTK_ENTRY(w_id)); if (val) { int id; /* look for a mix name first, then a number */ id = mix_name_to_id(val); if (id < 0) { redirect_errors_to(errors_to_mix_text, NULL); id = string_to_int(val, 0, "id"); redirect_errors_to(NULL, NULL); } if (mix_is_active(id)) { mix_dialog_id = id; reflect_mix_change(id); } } } static gboolean id_check_callback(GtkWidget *w, GdkEventCrossing *ev, gpointer unknown) { if (id_changed) id_activated(w_id, NULL); return(false); } static gboolean id_modify_callback(GtkWidget *w, GdkEventKey *event, gpointer data) { id_changed = true; return(false); } static void beg_activated(GtkWidget *w, gpointer context) { char *val; if (!(mix_is_active(mix_dialog_id))) return; val = (char *)gtk_entry_get_text(GTK_ENTRY(w_beg)); if (val) { chan_info *cp; mus_float_t beg; char *up_to_colon; up_to_colon = string_to_colon(val); cp = mix_chan_info_from_id(mix_dialog_id); redirect_errors_to(errors_to_mix_text, NULL); beg = string_to_mus_float_t(up_to_colon, 0.0, "begin time"); redirect_errors_to(NULL, NULL); if (beg >= 0.0) { mus_long_t pos, old_pos; old_pos = mix_position_from_id(mix_dialog_id); pos = (mus_long_t)(beg * snd_srate(cp->sound)); mix_set_position_edit(mix_dialog_id, pos); syncd_mix_change_position(mix_dialog_id, pos - old_pos); } after_mix_edit(mix_dialog_id); free(up_to_colon); } } static void widget_mix_to_text(GtkWidget *w, int id) { if (mix_name(id)) gtk_entry_set_text(GTK_ENTRY(w), mix_name(id)); else widget_int_to_text(w, id); } static gboolean copy_mix_callback(GtkWidget *w, GdkEventButton *ev, gpointer data) { copy_mix(mix_dialog_id); after_mix_edit(mix_dialog_id); return(false); } /* -------- mix play -------- */ static bool mix_playing = false; void reflect_mix_play_stop(void) { /* called in snd-dac.c */ mix_playing = false; } #if WITH_AUDIO static void mix_play_callback(GtkWidget *w, gpointer context) { if (mix_playing) mix_playing = false; else { if (!(mix_exists(mix_dialog_id))) return; syncd_mix_play(mix_dialog_id); mix_playing = true; play_mix_from_id(mix_dialog_id); } } static gboolean mix_play_pix_expose(GtkWidget *w, GdkEventExpose *ev, gpointer data) { draw_picture(mix_play_ax, snd_icon(SND_PNG_SPEAKER), 0, 0, 0, 0, 16, 16); /* in gtk2 this looks better if y-dest is 2 */ return(false); } #endif static void mix_dB_callback(GtkWidget *w, gpointer context) { spf->in_dB = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w)); mix_amp_env_resize(w_env); } static void mix_sync_callback(GtkWidget *w, gpointer context) { bool cb_set; cb_set = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w)); if ((cb_set) && (mix_sync_from_id(mix_dialog_id) == 0)) { mix_set_sync_from_id(mix_dialog_id, GET_ORIGINAL_SYNC); /* choose a new sync val or return to previous */ /* check for resync */ syncd_mix_set_color(mix_dialog_id, ss->red); } else { if ((!(cb_set)) && (mix_sync_from_id(mix_dialog_id) != 0)) { syncd_mix_unset_color(mix_dialog_id); /* unset colors of any syncd mixes */ mix_set_sync_from_id(mix_dialog_id, 0); } } for_each_normal_chan(display_channel_data); } static void mix_clip_callback(GtkWidget *w, gpointer context) { spf->clipping = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w)); mix_amp_env_resize(w_env); } static void mix_wave_callback(GtkWidget *w, gpointer context) { with_mix_background_wave = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w)); mix_amp_env_resize(w_env); } static void apply_env_callback(GtkWidget *w, gpointer context) { /* set all mix amp envs, last one should remix */ if (!(mix_is_active(mix_dialog_id))) return; if ((dialog_env) && (!(is_default_env(dialog_env)))) { mix_set_amp_env_edit(mix_dialog_id, dialog_env); syncd_mix_set_amp_env(mix_dialog_id, dialog_env); } else { mix_set_amp_env_edit(mix_dialog_id, NULL); syncd_mix_set_amp_env(mix_dialog_id, NULL); } after_mix_edit(mix_dialog_id); mix_amp_env_resize(w_env); } static void dismiss_mix_dialog(GtkWidget *w, gpointer context) { clear_mix_error(); gtk_widget_hide(mix_dialog); } static gint delete_mix_dialog(GtkWidget *w, GdkEvent *event, gpointer context) { clear_mix_error(); gtk_widget_hide(mix_dialog); return(true); } static GtkWidget *mix_next_button, *mix_previous_button, *mix_apply_button; static void mix_next_callback(GtkWidget *w, gpointer context) { int id; clear_mix_error(); id = next_mix_id(mix_dialog_id); if (id != INVALID_MIX_ID) { mix_dialog_id = id; reflect_mix_change(id); if (next_mix_id(id) == INVALID_MIX_ID) set_sensitive(mix_next_button, false); } } static void mix_previous_callback(GtkWidget *w, gpointer context) { int id; clear_mix_error(); id = previous_mix_id(mix_dialog_id); if (id != INVALID_MIX_ID) { mix_dialog_id = id; reflect_mix_change(id); if (previous_mix_id(id) == INVALID_MIX_ID) set_sensitive(mix_previous_button, false); } } static void mix_dialog_help_callback(GtkWidget *w, gpointer context) { mix_dialog_help(); } static GtkWidget *w_sync; #define LEFT_MARGIN 6 GtkWidget *make_mix_dialog(void) { if (mix_dialog == NULL) { GtkWidget *dismiss_button, *help_button, *rc, *mix_frame, *rc_top, *copy_button; GtkWidget *lo_hbox, *w_dB_frame, *w_dB, *w_clip, *w_wave, *w_dB_row; #if WITH_AUDIO GtkWidget *mix_play_pix; #endif char amplab[LABEL_BUFFER_SIZE]; gmix_speed_control_style = speed_control_style(ss); mix_dialog_id = any_mix_id(); mix_dialog = snd_gtk_dialog_new(); #if GTK_CHECK_VERSION(3, 14, 0) gtk_window_set_transient_for(GTK_WINDOW(mix_dialog), GTK_WINDOW(MAIN_SHELL(ss))); #endif SG_SIGNAL_CONNECT(mix_dialog, "delete_event", delete_mix_dialog, NULL); gtk_window_set_title(GTK_WINDOW(mix_dialog), "Mixes"); sg_make_resizable(mix_dialog); gtk_container_set_border_width (GTK_CONTAINER(mix_dialog), 6); gtk_window_resize(GTK_WINDOW(mix_dialog), 560, 280); gtk_widget_realize(mix_dialog); help_button = gtk_dialog_add_button(GTK_DIALOG(mix_dialog), "Help", GTK_RESPONSE_NONE); gtk_widget_set_name(help_button, "dialog_button"); SG_SIGNAL_CONNECT(help_button, "clicked", mix_dialog_help_callback, NULL); #if GTK_CHECK_VERSION(3, 0, 0) add_highlight_button_style(help_button); #endif gtk_widget_show(help_button); copy_button = gtk_dialog_add_button(GTK_DIALOG(mix_dialog), "Copy mix", GTK_RESPONSE_NONE); gtk_widget_set_name(copy_button, "dialog_button"); SG_SIGNAL_CONNECT(copy_button, "clicked", copy_mix_callback, NULL); #if GTK_CHECK_VERSION(3, 0, 0) add_highlight_button_style(copy_button); #endif gtk_widget_show(copy_button); dismiss_button = gtk_dialog_add_button(GTK_DIALOG(mix_dialog), I_GO_AWAY, GTK_RESPONSE_NONE); gtk_widget_set_name(dismiss_button, "dialog_button"); SG_SIGNAL_CONNECT(dismiss_button, "clicked", dismiss_mix_dialog, NULL); #if GTK_CHECK_VERSION(3, 0, 0) add_highlight_button_style(dismiss_button); #endif gtk_widget_show(dismiss_button); mix_apply_button = gtk_dialog_add_button(GTK_DIALOG(mix_dialog), "Apply env", GTK_RESPONSE_NONE); gtk_widget_set_name(mix_apply_button, "dialog_button"); SG_SIGNAL_CONNECT(mix_apply_button, "clicked", apply_env_callback, NULL); #if GTK_CHECK_VERSION(3, 0, 0) add_highlight_button_style(mix_apply_button); #endif gtk_widget_show(mix_apply_button); /* normally hidden error indication at top */ error_frame = gtk_frame_new(NULL); gtk_box_pack_start(GTK_BOX(DIALOG_CONTENT_AREA(mix_dialog)), error_frame, false, false, 4); error_label = gtk_label_new(NULL); gtk_container_add(GTK_CONTAINER(error_frame), error_label); gtk_widget_show(error_label); /* top row of mix id name position */ rc_top = gtk_hbox_new(false, 0); gtk_box_pack_start(GTK_BOX(DIALOG_CONTENT_AREA(mix_dialog)), rc_top, false, false, 4); gtk_widget_show(rc_top); mix_frame = gtk_frame_new(NULL); gtk_box_pack_start(GTK_BOX(rc_top), mix_frame, false, false, 4); gtk_widget_show(mix_frame); rc = gtk_hbox_new(false, 0); gtk_container_add(GTK_CONTAINER(mix_frame), rc); gtk_widget_show(rc); w_id_label = gtk_label_new("mix:"); gtk_box_pack_start(GTK_BOX(rc), w_id_label, false, false, 4); gtk_widget_show(w_id_label); w_id = snd_entry_new(rc, NULL, WITH_DEFAULT_BACKGROUND); SG_SIGNAL_CONNECT(w_id, "activate", id_activated, NULL); SG_SIGNAL_CONNECT(w_id, "leave_notify_event", id_check_callback, NULL); SG_SIGNAL_CONNECT(w_id, "key_press_event", id_modify_callback, NULL); w_beg = snd_entry_new(rc, NULL, WITH_DEFAULT_BACKGROUND); SG_SIGNAL_CONNECT(w_beg, "activate", beg_activated, NULL); #if WITH_AUDIO mix_play = gtk_button_new(); gtk_box_pack_start(GTK_BOX(rc), mix_play, false, false, 2); SG_SIGNAL_CONNECT(mix_play, "clicked", mix_play_callback, NULL); gtk_widget_show(mix_play); widget_modify_bg(mix_play, GTK_STATE_ACTIVE, ss->basic_color); widget_modify_bg(mix_play, GTK_STATE_SELECTED, ss->basic_color); mix_play_pix = gtk_drawing_area_new(); gtk_widget_set_events(mix_play_pix, GDK_EXPOSURE_MASK); gtk_widget_set_size_request(mix_play_pix, 16, 16); gtk_container_add(GTK_CONTAINER(mix_play), mix_play_pix); gtk_widget_show(mix_play_pix); SG_SIGNAL_CONNECT(mix_play_pix, DRAW_SIGNAL, mix_play_pix_expose, NULL); #endif mix_next_button = button_new_with_icon(ICON_GO_FORWARD); gtk_widget_set_name(mix_next_button, "dialog_button"); gtk_box_pack_end(GTK_BOX(rc), mix_next_button, false, true, 6); #if GTK_CHECK_VERSION(3, 0, 0) add_highlight_button_style(mix_next_button); #endif SG_SIGNAL_CONNECT(mix_next_button, "clicked", mix_next_callback, NULL); gtk_widget_show(mix_next_button); set_stock_button_label(mix_next_button, I_NEXT); mix_previous_button = button_new_with_icon(ICON_GO_BACK); gtk_widget_set_name(mix_previous_button, "dialog_button"); gtk_box_pack_end(GTK_BOX(rc), mix_previous_button, false, true, 6); #if GTK_CHECK_VERSION(3, 0, 0) add_highlight_button_style(mix_previous_button); #endif SG_SIGNAL_CONNECT(mix_previous_button, "clicked", mix_previous_callback, NULL); gtk_widget_show(mix_previous_button); set_stock_button_label(mix_previous_button, I_PREVIOUS); /* SPEED */ w_speed_form = gtk_hbox_new(false, 2); gtk_box_pack_start(GTK_BOX(DIALOG_CONTENT_AREA(mix_dialog)), w_speed_form, false, false, 4); w_speed_event = gtk_event_box_new(); gtk_box_pack_start(GTK_BOX(w_speed_form), w_speed_event, false, false, 4); gtk_widget_show(w_speed_event); SG_SIGNAL_CONNECT(w_speed_event, "button_press_event", mix_speed_click_callback, NULL); #if (!GTK_CHECK_VERSION(3, 0, 0)) w_speed_label = gtk_label_new("speed:"); #else w_speed_label = gtk_button_new_with_label("speed:"); add_highlight_button_style(w_speed_label); #endif gtk_container_add(GTK_CONTAINER(w_speed_event), w_speed_label); gtk_widget_show(w_speed_label); w_speed_label_event = gtk_event_box_new(); gtk_box_pack_start(GTK_BOX(w_speed_form), w_speed_label_event, false, false, 4); gtk_widget_show(w_speed_label_event); SG_SIGNAL_CONNECT(w_speed_label_event, "button_press_event", speed_label_click_callback, NULL); switch (speed_control_style(ss)) { case SPEED_CONTROL_AS_RATIO: w_speed_number = gtk_label_new("1/1"); break; case SPEED_CONTROL_AS_SEMITONE: w_speed_number = gtk_label_new("1"); break; default: w_speed_number = gtk_label_new("1.00"); break; } gtk_container_add(GTK_CONTAINER(w_speed_label_event), w_speed_number); gtk_widget_show(w_speed_number); w_speed_adj = (GtkAdjustment *)gtk_adjustment_new(0.45, 0.0, 1.0, 0.001, 0.01, .1); w_speed = gtk_hscrollbar_new(GTK_ADJUSTMENT(w_speed_adj)); gtk_box_pack_start(GTK_BOX(w_speed_form), w_speed, true, true, 4); SG_SIGNAL_CONNECT(w_speed, "button_release_event", mix_speed_release_callback, NULL); SG_SIGNAL_CONNECT(w_speed, "motion_notify_event", speed_motion_callback, NULL); SG_SIGNAL_CONNECT(w_speed, "button_press_event", speed_press_callback, NULL); gtk_widget_show(w_speed); gtk_widget_show(w_speed_form); /* AMP */ spf = new_env_editor(); w_amp_form = gtk_hbox_new(false, 2); gtk_box_pack_start(GTK_BOX(DIALOG_CONTENT_AREA(mix_dialog)), w_amp_form, false, false, 0); w_amp_event = gtk_event_box_new(); gtk_box_pack_start(GTK_BOX(w_amp_form), w_amp_event, false, false, 4); gtk_widget_show(w_amp_event); SG_SIGNAL_CONNECT(w_amp_event, "button_press_event", mix_amp_click_callback, NULL); snprintf(amplab, LABEL_BUFFER_SIZE, "%s", "amp:"); #if (!GTK_CHECK_VERSION(3, 0, 0)) w_amp_label = gtk_label_new(amplab); #else w_amp_label = gtk_button_new_with_label("amp:"); add_highlight_button_style(w_amp_label); #endif gtk_container_add(GTK_CONTAINER(w_amp_event), w_amp_label); gtk_widget_show(w_amp_label); w_amp_number = gtk_label_new("1.00"); gtk_box_pack_start(GTK_BOX(w_amp_form), w_amp_number, false, false, 0); gtk_widget_show(w_amp_number); w_amp_adj = (GtkAdjustment *)gtk_adjustment_new(0.5, 0.0, 1.0, 0.001, 0.01, .1); w_amp = gtk_hscrollbar_new(GTK_ADJUSTMENT(w_amp_adj)); gtk_box_pack_start(GTK_BOX(w_amp_form), w_amp, true, true, 4); SG_SIGNAL_CONNECT(w_amp, "motion_notify_event", amp_motion_callback, NULL); SG_SIGNAL_CONNECT(w_amp, "button_release_event", mix_amp_release_callback, NULL); SG_SIGNAL_CONNECT(w_amp, "button_press_event", amp_press_callback, NULL); gtk_widget_show(w_amp); gtk_widget_show(w_amp_form); lo_hbox = gtk_hbox_new(false, 0); gtk_box_pack_start(GTK_BOX(DIALOG_CONTENT_AREA(mix_dialog)), lo_hbox, true, true, 5); gtk_widget_show(lo_hbox); /* GRAPH (frame) */ w_env_frame = gtk_frame_new(NULL); gtk_box_pack_start(GTK_BOX(lo_hbox), w_env_frame, true, true, 10); /* GRAPH (buttons) */ w_dB_frame = gtk_frame_new(NULL); gtk_box_pack_end(GTK_BOX(lo_hbox), w_dB_frame, false, false, 2); gtk_widget_show(w_dB_frame); w_dB_row = gtk_vbox_new(false, 0); gtk_container_add(GTK_CONTAINER(w_dB_frame), w_dB_row); gtk_widget_show(w_dB_row); w_clip = gtk_check_button_new_with_label("clip"); widget_set_margin_left(w_clip, LEFT_MARGIN); SG_SIGNAL_CONNECT(w_clip, "toggled", mix_clip_callback, NULL); gtk_box_pack_start(GTK_BOX(w_dB_row), w_clip, false, false, 0); gtk_widget_show(w_clip); w_wave = gtk_check_button_new_with_label("wave"); widget_set_margin_left(w_wave, LEFT_MARGIN); SG_SIGNAL_CONNECT(w_wave, "toggled", mix_wave_callback, NULL); gtk_box_pack_start(GTK_BOX(w_dB_row), w_wave, false, false, 0); gtk_widget_show(w_wave); w_dB = gtk_check_button_new_with_label("dB"); widget_set_margin_left(w_dB, LEFT_MARGIN); SG_SIGNAL_CONNECT(w_dB, "toggled", mix_dB_callback, NULL); gtk_box_pack_start(GTK_BOX(w_dB_row), w_dB, false, false, 0); gtk_widget_show(w_dB); w_sync = gtk_check_button_new_with_label("sync"); widget_set_margin_left(w_sync, LEFT_MARGIN); SG_SIGNAL_CONNECT(w_sync, "toggled", mix_sync_callback, NULL); gtk_box_pack_start(GTK_BOX(w_dB_row), w_sync, false, false, 0); gtk_widget_show(w_sync); /* GRAPH (drawing area) */ w_env = gtk_drawing_area_new(); gtk_widget_set_events(w_env, GDK_ALL_EVENTS_MASK); gtk_container_add(GTK_CONTAINER(w_env_frame), w_env); widget_modify_bg(w_env, GTK_STATE_NORMAL, ss->highlight_color); gtk_widget_show(w_env); SG_SIGNAL_CONNECT(w_env, DRAW_SIGNAL, mix_amp_env_expose_callback, NULL); SG_SIGNAL_CONNECT(w_env, "configure_event", mix_amp_env_resize_callback, NULL); SG_SIGNAL_CONNECT(w_env, "button_press_event", mix_drawer_button_press, NULL); SG_SIGNAL_CONNECT(w_env, "button_release_event", mix_drawer_button_release, NULL); SG_SIGNAL_CONNECT(w_env, "motion_notify_event", mix_drawer_button_motion, NULL); gtk_widget_show(w_env_frame); gtk_widget_show(mix_dialog); set_dialog_widget(MIX_DIALOG, mix_dialog); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w_clip), true); if (mix_sync_from_id(mix_dialog_id) != 0) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w_sync), true); #if WITH_AUDIO mix_play_ax = (graphics_context *)calloc(1, sizeof(graphics_context)); mix_play_ax->wn = WIDGET_TO_WINDOW(mix_play_pix); mix_play_ax->gc = ss->basic_gc; #endif gtk_widget_hide(error_frame); } else { raise_dialog(mix_dialog); } reflect_mix_change(mix_dialog_id); return(mix_dialog); } void reflect_mix_change(int mix_id) { if ((mix_dialog) && (widget_is_active(mix_dialog))) { if (mix_id != ANY_MIX_ID) mix_dialog_id = mix_id; if (!(mix_exists(mix_dialog_id))) { mix_dialog_id = any_mix_id(); mix_id = mix_dialog_id; } if ((mix_id == mix_dialog_id) || (mix_id == ANY_MIX_ID)) { mus_float_t val; set_sensitive(mix_next_button, (next_mix_id(mix_dialog_id) != INVALID_MIX_ID)); set_sensitive(mix_previous_button, (previous_mix_id(mix_dialog_id) != INVALID_MIX_ID)); /* now reflect current mix state in mix dialog controls */ if (mix_exists(mix_dialog_id)) { char lab[LABEL_BUFFER_SIZE]; chan_info *cp; mus_long_t beg, len; cp = mix_chan_info_from_id(mix_dialog_id); if (old_mix_dialog_id != INVALID_MIX_ID) { mix_unset_color_from_id(old_mix_dialog_id); syncd_mix_unset_color(old_mix_dialog_id); } old_mix_dialog_id = mix_dialog_id; mix_set_color_from_id(mix_dialog_id, ss->red); syncd_mix_set_color(mix_dialog_id, ss->red); for_each_normal_chan(display_channel_data); if (!dragging) { val = mix_speed_from_id(mix_dialog_id); reflect_mix_speed(val); } beg = mix_position_from_id(mix_dialog_id); len = mix_length_from_id(mix_dialog_id); snprintf(lab, LABEL_BUFFER_SIZE, "%.3f : %.3f%s", (float)((double)beg / (float)snd_srate(cp->sound)), (float)((double)(beg + len) / (float)snd_srate(cp->sound)), (mix_is_active(mix_dialog_id)) ? "" : " (locked)"); gtk_entry_set_text(GTK_ENTRY(w_beg), lab); widget_mix_to_text(w_id, mix_dialog_id); set_sensitive(mix_apply_button, true); } else { gtk_entry_set_text(GTK_ENTRY(w_id), "-1"); gtk_entry_set_text(GTK_ENTRY(w_beg), "no active mixes"); set_sensitive(mix_apply_button, false); } if (!dragging) { if (mix_is_active(mix_dialog_id)) val = mix_amp_from_id(mix_dialog_id); else val = 1.0; reflect_mix_amp(val); } if (mix_amp_env_from_id(mix_dialog_id)) { if (dialog_env) free_env(dialog_env); dialog_env = copy_env(mix_amp_env_from_id(mix_dialog_id)); } /* copy here else we're editing it directly afterwards (and we free old in mix_set_amp_env_edit) */ if (!dialog_env) dialog_env = default_env(1.0, 1.0); mix_amp_env_resize(w_env); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w_sync), (mix_sync_from_id(mix_dialog_id) != 0)); } } } int mix_dialog_mix(void) { return(mix_dialog_id); } void mix_dialog_set_mix(int id) { mix_dialog_id = id; reflect_mix_change(mix_dialog_id); } snd-16.1/libutf8proc.scm0000644000076400007640000002523312571166477013325 0ustar bilbil;;; utf8proc.scm ;;; ;;; tie the utf8proc library into the *utf8proc* environment (require cload.scm) (provide 'libutf8proc.scm) ;; if loading from a different directory, pass that info to C (let ((current-file (port-filename (current-input-port)))) (let ((directory (and (or (char=? (current-file 0) #\/) (char=? (current-file 0) #\~)) (substring current-file 0 (- (length current-file) 9))))) (when (and directory (not (member directory *load-path*))) (set! *load-path* (cons directory *load-path*))) (with-let (rootlet) (require cload.scm)) (when (and directory (not (string-position directory *cload-cflags*))) (set! *cload-cflags* (string-append "-I" directory " " *cload-cflags*))))) (if (not (defined? '*libutf8proc*)) (define *libutf8proc* (with-let (unlet) (set! *libraries* (cons (cons "libutf8proc.scm" (curlet)) *libraries*)) (c-define '((C-macro (int (UTF8PROC_VERSION_MAJOR UTF8PROC_VERSION_MINOR UTF8PROC_VERSION_PATCH))) (int (UTF8PROC_NULLTERM UTF8PROC_STABLE UTF8PROC_COMPAT UTF8PROC_COMPOSE UTF8PROC_DECOMPOSE UTF8PROC_IGNORE UTF8PROC_REJECTNA UTF8PROC_NLF2LS UTF8PROC_NLF2PS UTF8PROC_NLF2LF UTF8PROC_STRIPCC UTF8PROC_CASEFOLD UTF8PROC_CHARBOUND UTF8PROC_LUMP UTF8PROC_STRIPMARK)) (C-macro (int (UTF8PROC_ERROR_NOMEM UTF8PROC_ERROR_OVERFLOW UTF8PROC_ERROR_INVALIDUTF8 UTF8PROC_ERROR_NOTASSIGNED UTF8PROC_ERROR_INVALIDOPTS))) (int (UTF8PROC_CATEGORY_CN UTF8PROC_CATEGORY_LU UTF8PROC_CATEGORY_LL UTF8PROC_CATEGORY_LT UTF8PROC_CATEGORY_LM UTF8PROC_CATEGORY_LO UTF8PROC_CATEGORY_MN UTF8PROC_CATEGORY_MC UTF8PROC_CATEGORY_ME UTF8PROC_CATEGORY_ND UTF8PROC_CATEGORY_NL UTF8PROC_CATEGORY_NO UTF8PROC_CATEGORY_PC UTF8PROC_CATEGORY_PD UTF8PROC_CATEGORY_PS UTF8PROC_CATEGORY_PE UTF8PROC_CATEGORY_PI UTF8PROC_CATEGORY_PF UTF8PROC_CATEGORY_PO UTF8PROC_CATEGORY_SM UTF8PROC_CATEGORY_SC UTF8PROC_CATEGORY_SK UTF8PROC_CATEGORY_SO UTF8PROC_CATEGORY_ZS UTF8PROC_CATEGORY_ZL UTF8PROC_CATEGORY_ZP UTF8PROC_CATEGORY_CC UTF8PROC_CATEGORY_CF UTF8PROC_CATEGORY_CS UTF8PROC_CATEGORY_CO)) (int (UTF8PROC_BIDI_CLASS_L UTF8PROC_BIDI_CLASS_LRE UTF8PROC_BIDI_CLASS_LRO UTF8PROC_BIDI_CLASS_R UTF8PROC_BIDI_CLASS_AL UTF8PROC_BIDI_CLASS_RLE UTF8PROC_BIDI_CLASS_RLO UTF8PROC_BIDI_CLASS_PDF UTF8PROC_BIDI_CLASS_EN UTF8PROC_BIDI_CLASS_ES UTF8PROC_BIDI_CLASS_ET UTF8PROC_BIDI_CLASS_AN UTF8PROC_BIDI_CLASS_CS UTF8PROC_BIDI_CLASS_NSM UTF8PROC_BIDI_CLASS_BN UTF8PROC_BIDI_CLASS_B UTF8PROC_BIDI_CLASS_S UTF8PROC_BIDI_CLASS_WS UTF8PROC_BIDI_CLASS_ON UTF8PROC_BIDI_CLASS_LRI UTF8PROC_BIDI_CLASS_RLI UTF8PROC_BIDI_CLASS_FSI UTF8PROC_BIDI_CLASS_PDI)) (int (UTF8PROC_DECOMP_TYPE_FONT UTF8PROC_DECOMP_TYPE_NOBREAK UTF8PROC_DECOMP_TYPE_INITIAL UTF8PROC_DECOMP_TYPE_MEDIAL UTF8PROC_DECOMP_TYPE_FINAL UTF8PROC_DECOMP_TYPE_ISOLATED UTF8PROC_DECOMP_TYPE_CIRCLE UTF8PROC_DECOMP_TYPE_SUPER UTF8PROC_DECOMP_TYPE_SUB UTF8PROC_DECOMP_TYPE_VERTICAL UTF8PROC_DECOMP_TYPE_WIDE UTF8PROC_DECOMP_TYPE_NARROW UTF8PROC_DECOMP_TYPE_SMALL UTF8PROC_DECOMP_TYPE_SQUARE UTF8PROC_DECOMP_TYPE_FRACTION UTF8PROC_DECOMP_TYPE_COMPAT)) (int (UTF8PROC_BOUNDCLASS_START UTF8PROC_BOUNDCLASS_OTHER UTF8PROC_BOUNDCLASS_CR UTF8PROC_BOUNDCLASS_LF UTF8PROC_BOUNDCLASS_CONTROL UTF8PROC_BOUNDCLASS_EXTEND UTF8PROC_BOUNDCLASS_L UTF8PROC_BOUNDCLASS_V UTF8PROC_BOUNDCLASS_T UTF8PROC_BOUNDCLASS_LV UTF8PROC_BOUNDCLASS_LVT UTF8PROC_BOUNDCLASS_REGIONAL_INDICATOR UTF8PROC_BOUNDCLASS_SPACINGMARK)) (char* utf8proc_version (void)) (char* utf8proc_errmsg (int)) (int utf8proc_tolower ((utf8proc_int32_t int))) (int utf8proc_toupper ((utf8proc_int32_t int))) (int utf8proc_charwidth ((utf8proc_int32_t int))) (int utf8proc_category ((utf8proc_int32_t int))) (char* utf8proc_category_string ((utf8proc_int32_t int))) (bool utf8proc_codepoint_valid ((utf8proc_int32_t int))) (bool utf8proc_grapheme_break ((utf8proc_int32_t int) (utf8proc_int32_t int))) (char* utf8proc_NFD (char*)) (char* utf8proc_NFC (char*)) (char* utf8proc_NFKD (char*)) (char* utf8proc_NFKC (char*)) (in-C "static s7_pointer g_utf8proc_iterate(s7_scheme *sc, s7_pointer args) { utf8proc_int32_t code_ref = 0; int len, res; char *str; str = (char *)s7_string(s7_car(args)); len = s7_string_length(s7_car(args)); res = utf8proc_iterate(str, len, &code_ref); return(s7_list(sc, 2, s7_make_integer(sc, code_ref), s7_make_integer(sc, res))); }") (C-function ("utf8proc_iterate" g_utf8proc_iterate "" 1)) (in-C "static s7_pointer g_utf8proc_encode_char(s7_scheme *sc, s7_pointer args) { ssize_t res; utf8proc_uint8_t buf[8]; res = utf8proc_encode_char((utf8proc_int32_t)s7_integer(s7_car(args)), buf); return(s7_list(sc, 2, s7_make_string_with_length(sc, buf, res), s7_make_integer(sc, res))); }") (C-function ("utf8proc_encode_char" g_utf8proc_encode_char "" 1)) (in-C "static s7_pointer g_utf8proc_reencode(s7_scheme *sc, s7_pointer args) { s7_pointer buffer, codepoints, options; ssize_t res; buffer = s7_car(args); codepoints = s7_cadr(args); options = s7_caddr(args); res = utf8proc_reencode((utf8proc_int32_t *)s7_string(buffer), (utf8proc_ssize_t)s7_integer(codepoints), (utf8proc_option_t)s7_integer(options)); return(s7_make_integer(sc, res)); }") (C-function ("utf8proc_reencode" g_utf8proc_reencode "" 1)) #| (in-C "static s7_pointer g_utf8proc_utf8class(s7_scheme *sc, s7_pointer args) { return(s7_make_string_with_length(sc, (char *)utf8proc_utf8class, 256)); }") (C-function ("utf8proc_utf8class" g_utf8proc_utf8class "" 0)) |# (in-C "static s7_pointer g_utf8proc_get_property(s7_scheme *sc, s7_pointer args) { const utf8proc_property_t *info; info = utf8proc_get_property((utf8proc_int32_t)s7_integer(s7_car(args))); return(s7_inlet(sc, s7_list(sc, 30, s7_make_symbol(sc, \"category\"), s7_make_integer(sc, info->category), s7_make_symbol(sc, \"combining_class\"), s7_make_integer(sc, info->combining_class), s7_make_symbol(sc, \"bidi_class\"), s7_make_integer(sc, info->bidi_class), s7_make_symbol(sc, \"decomp_type\"), s7_make_integer(sc, info->decomp_type), s7_make_symbol(sc, \"uppercase_mapping\"), s7_make_integer(sc, info->uppercase_mapping), s7_make_symbol(sc, \"lowercase_mapping\"), s7_make_integer(sc, info->lowercase_mapping), s7_make_symbol(sc, \"titlecase_mapping\"), s7_make_integer(sc, info->titlecase_mapping), s7_make_symbol(sc, \"comb1st_index\"), s7_make_integer(sc, info->comb1st_index), s7_make_symbol(sc, \"comb2nd_index\"), s7_make_integer(sc, info->comb2nd_index), s7_make_symbol(sc, \"bidi_mirrored\"), s7_make_integer(sc, info->bidi_mirrored), s7_make_symbol(sc, \"comp_exclusion\"), s7_make_integer(sc, info->comp_exclusion), s7_make_symbol(sc, \"ignorable\"), s7_make_integer(sc, info->ignorable), s7_make_symbol(sc, \"control_boundary\"), s7_make_integer(sc, info->control_boundary), s7_make_symbol(sc, \"boundclass\"), s7_make_integer(sc, info->boundclass), s7_make_symbol(sc, \"charwidth\"), s7_make_integer(sc, info->charwidth)))); }") (C-function ("utf8proc_get_property" g_utf8proc_get_property "" 1)) (in-C "static s7_pointer g_utf8proc_decompose_char(s7_scheme *sc, s7_pointer args) { s7_pointer code, opt, str; int last_boundclass; utf8proc_ssize_t size; utf8proc_int32_t *dst; ssize_t res; code = s7_car(args); str = s7_cadr(args); opt = s7_caddr(args); dst = (utf8proc_int32_t *)s7_string(str); size = (utf8proc_ssize_t)s7_string_length(str); res = utf8proc_decompose_char((utf8proc_int32_t)s7_integer(code), dst, size, (utf8proc_option_t)s7_integer(opt), &last_boundclass); return(s7_make_integer(sc, res)); }") (C-function ("utf8proc_decompose_char" g_utf8proc_decompose_char "" 3)) (in-C "static s7_pointer g_utf8proc_map(s7_scheme *sc, s7_pointer args) { s7_pointer opt, str; ssize_t res; utf8proc_uint8_t *dst; str = s7_car(args); opt = s7_cadr(args); res = utf8proc_map((utf8proc_uint8_t *)s7_string(str), s7_string_length(str), &dst, (utf8proc_option_t)s7_integer(opt)); if (res < 0) return(s7_make_integer(sc, res)); return(s7_make_string_with_length(sc, dst, res)); }") (C-function ("utf8proc_map" g_utf8proc_map "" 2)) (in-C "static s7_pointer g_utf8proc_decompose(s7_scheme *sc, s7_pointer args) { s7_pointer opt, str; int len; ssize_t res; utf8proc_int32_t *dst; str = s7_car(args); opt = s7_cadr(args); len = s7_string_length(str); dst = (utf8proc_int32_t *)malloc(len * 4); res = utf8proc_decompose((const utf8proc_uint8_t *)s7_string(str), len, dst, len, (utf8proc_option_t)s7_integer(opt)); if (res < 0) return(s7_make_integer(sc, res)); return(s7_make_string_with_length(sc, (char *)dst, res)); }") (C-function ("utf8proc_decompose" g_utf8proc_decompose "" 2)) ) "" "utf8proc.h" "" "-lutf8proc" "utf8proc_s7") (curlet)))) *libutf8proc* snd-16.1/libgdbm.scm0000644000076400007640000002435512502665142012453 0ustar bilbil;;; libgdbm.scm ;;; ;;; tie libgdbm into s7 (require cload.scm) (provide 'libgdbm.scm) ;; if loading from a different directory, pass that info to C (let ((current-file (port-filename (current-input-port)))) (let ((directory (and (or (char=? (current-file 0) #\/) (char=? (current-file 0) #\~)) (substring current-file 0 (- (length current-file) 9))))) (when (and directory (not (member directory *load-path*))) (set! *load-path* (cons directory *load-path*))) (with-let (rootlet) (require cload.scm)) (when (and directory (not (string-position directory *cload-cflags*))) (set! *cload-cflags* (string-append "-I" directory " " *cload-cflags*))))) (if (not (defined? '*libgdbm*)) (define *libgdbm* (with-let (unlet) (set! *libraries* (cons (cons "libgdbm.scm" (curlet)) *libraries*)) (c-define '((C-macro (int (GDBM_READER GDBM_WRITER GDBM_WRCREAT GDBM_NEWDB GDBM_FAST GDBM_SYNC GDBM_NOLOCK GDBM_INSERT GDBM_REPLACE GDBM_CACHESIZE GDBM_FASTMODE GDBM_SYNCMODE GDBM_CENTFREE GDBM_COALESCEBLKS GDBM_OPENMASK GDBM_NOMMAP GDBM_CLOEXEC GDBM_SETCACHESIZE GDBM_SETSYNCMODE GDBM_SETCENTFREE GDBM_SETCOALESCEBLKS GDBM_SETMAXMAPSIZE GDBM_SETMMAP GDBM_GETFLAGS GDBM_GETMMAP GDBM_GETCACHESIZE GDBM_GETSYNCMODE GDBM_GETCENTFREE GDBM_GETCOALESCEBLKS GDBM_GETMAXMAPSIZE GDBM_GETDBNAME))) (C-macro (int (GDBM_VERSION_MAJOR GDBM_VERSION_MINOR GDBM_VERSION_PATCH))) (C-macro (int (GDBM_NO_ERROR GDBM_MALLOC_ERROR GDBM_BLOCK_SIZE_ERROR GDBM_FILE_OPEN_ERROR GDBM_FILE_WRITE_ERROR GDBM_FILE_SEEK_ERROR GDBM_FILE_READ_ERROR GDBM_BAD_MAGIC_NUMBER GDBM_EMPTY_DATABASE GDBM_CANT_BE_READER GDBM_CANT_BE_WRITER GDBM_READER_CANT_DELETE GDBM_READER_CANT_STORE GDBM_READER_CANT_REORGANIZE GDBM_UNKNOWN_UPDATE GDBM_ITEM_NOT_FOUND GDBM_REORGANIZE_FAILED GDBM_CANNOT_REPLACE GDBM_ILLEGAL_DATA GDBM_OPT_ALREADY_SET GDBM_OPT_ILLEGAL GDBM_BYTE_SWAPPED GDBM_BAD_FILE_OFFSET GDBM_BAD_OPEN_FLAGS GDBM_FILE_STAT_ERROR GDBM_FILE_EOF))) (in-C "static s7_pointer g_gdbm_version(s7_scheme *sc, s7_pointer args) {return(s7_make_string(sc, gdbm_version));}") (C-function ("gdbm_version" g_gdbm_version "(gdbm_version) returns the current gbdm version" 0)) (in-C "static s7_pointer g_gdbm_errno(s7_scheme *sc, s7_pointer args) {return(s7_make_integer(sc, gdbm_errno));}") (C-function ("gdbm_errno" g_gdbm_errno "(gdbm_errno) returns the current gdbm error number" 0)) (char* gdbm_strerror (int)) (int gdbm_fdesc ((GDBM_FILE c_pointer))) (int gdbm_reorganize ((GDBM_FILE c_pointer))) (void gdbm_close ((GDBM_FILE c_pointer))) (void gdbm_sync ((GDBM_FILE c_pointer))) ;(int gdbm_export ((GDBM_FILE c_pointer) char* int int)) ;(int gdbm_import ((GDBM_FILE c_pointer) char* int)) (in-C " static void *make_datum(datum key) {datum *p; p = (datum *)malloc(sizeof(datum)); p->dptr = key.dptr; p->dsize = key.dsize; return((void *)p);} static s7_pointer g_gdbm_firstkey(s7_scheme *sc, s7_pointer args) { if (s7_is_c_pointer(s7_car(args))) { datum key; key = gdbm_firstkey((GDBM_FILE)s7_c_pointer(s7_car(args))); if (key.dptr) return(s7_cons(sc, s7_make_string_with_length(sc, key.dptr, key.dsize), s7_make_c_pointer(sc, make_datum(key)))); return(s7_eof_object(sc)); } return(s7_wrong_type_arg_error(sc, \"gdbm_firstkey\", 0, s7_car(args), \"a gdbm file\")); } static s7_pointer g_gdbm_nextkey(s7_scheme *sc, s7_pointer args) { if (s7_is_c_pointer(s7_car(args))) { if (s7_is_c_pointer(s7_cadr(args))) { datum *p; datum key, rtn; p = (datum *)s7_c_pointer(s7_cadr(args)); key.dptr = p->dptr; key.dsize = p->dsize; rtn = gdbm_nextkey((GDBM_FILE)s7_c_pointer(s7_car(args)), key); free(key.dptr); free(p); if (rtn.dptr) return(s7_cons(sc, s7_make_string_with_length(sc, rtn.dptr, rtn.dsize), s7_make_c_pointer(sc, make_datum(rtn)))); return(s7_eof_object(sc)); } return(s7_wrong_type_arg_error(sc, \"gdbm_nextkey\", 2, s7_cadr(args), \"a string\")); } return(s7_wrong_type_arg_error(sc, \"gdbm_nextkey\", 1, s7_car(args), \"a gdbm file\")); } static s7_pointer g_gdbm_exists(s7_scheme *sc, s7_pointer args) { if (s7_is_c_pointer(s7_car(args))) { if (s7_is_string(s7_cadr(args))) { datum key; key.dptr = (char *)s7_string(s7_cadr(args)); key.dsize = (int)s7_string_length(s7_cadr(args)); return(s7_make_integer(sc, gdbm_exists((GDBM_FILE)s7_c_pointer(s7_car(args)), key))); } return(s7_wrong_type_arg_error(sc, \"gdbm_exists\", 2, s7_cadr(args), \"a string\")); } return(s7_wrong_type_arg_error(sc, \"gdbm_exists\", 1, s7_car(args), \"a gdbm file\")); } static s7_pointer g_gdbm_delete(s7_scheme *sc, s7_pointer args) { if (s7_is_c_pointer(s7_car(args))) { if (s7_is_string(s7_cadr(args))) { datum key; key.dptr = (char *)s7_string(s7_cadr(args)); key.dsize = (int)s7_string_length(s7_cadr(args)); return(s7_make_integer(sc, gdbm_delete((GDBM_FILE)s7_c_pointer(s7_car(args)), key))); } \n\ return(s7_wrong_type_arg_error(sc, \"gdbm_delete\", 2, s7_cadr(args), \"a string\")); } return(s7_wrong_type_arg_error(sc, \"gdbm_delete\", 1, s7_car(args), \"a gdbm file\")); } static s7_pointer g_gdbm_fetch(s7_scheme *sc, s7_pointer args) { if (s7_is_c_pointer(s7_car(args))) { if (s7_is_string(s7_cadr(args))) { datum key, rtn; key.dptr = (char *)s7_string(s7_cadr(args)); key.dsize = (int)s7_string_length(s7_cadr(args)); rtn = gdbm_fetch((GDBM_FILE)s7_c_pointer(s7_car(args)), key); if (rtn.dptr) { s7_pointer result; result = s7_make_string_with_length(sc, rtn.dptr, rtn.dsize - 1); free(rtn.dptr); return(result); } else return(s7_make_string_with_length(sc, \"#\", 12)); } return(s7_wrong_type_arg_error(sc, \"gdbm_fetch\", 2, s7_cadr(args), \"a string\")); } return(s7_wrong_type_arg_error(sc, \"gdbm_fetch\", 1, s7_car(args), \"a gdbm file\")); } static s7_pointer g_gdbm_store(s7_scheme *sc, s7_pointer args) { if (s7_is_c_pointer(s7_car(args))) { if (s7_is_string(s7_cadr(args))) { if (s7_is_string(s7_caddr(args))) { if (s7_is_integer(s7_cadddr(args))) { datum key, val; key.dptr = (char *)s7_string(s7_cadr(args)); key.dsize = (int)s7_string_length(s7_cadr(args)); val.dptr = (char *)s7_string(s7_caddr(args)); val.dsize = (int)s7_string_length(s7_caddr(args)) + 1; return(s7_make_integer(sc, gdbm_store((GDBM_FILE)s7_c_pointer(s7_car(args)), key, val, (int)s7_integer(s7_cadddr(args))))); } return(s7_wrong_type_arg_error(sc, \"gdbm_fetch\", 4, s7_cadddr(args), \"an integer (flag)\")); } return(s7_wrong_type_arg_error(sc, \"gdbm_fetch\", 3, s7_caddr(args), \"a string\")); } return(s7_wrong_type_arg_error(sc, \"gdbm_fetch\", 2, s7_cadr(args), \"a string\")); } return(s7_wrong_type_arg_error(sc, \"gdbm_fetch\", 1, s7_car(args), \"a gdbm file\")); } static s7_pointer open_error_func = NULL; static s7_scheme *open_error_s7 = NULL; static void gdbm_open_error(const char *name) { if (open_error_func) s7_apply_function(open_error_s7, open_error_func, s7_list(open_error_s7, 1, s7_make_string(open_error_s7, name))); } static s7_pointer g_gdbm_open(s7_scheme *sc, s7_pointer args) { if (s7_is_string(s7_car(args))) { char *name; name = (char *)s7_string(s7_car(args)); args = s7_cdr(args); if (s7_is_integer(s7_car(args))) { int block_size; block_size = (int)s7_integer(s7_car(args)); args = s7_cdr(args); if (s7_is_integer(s7_car(args))) { int flags; flags = (int)s7_integer(s7_car(args)); args = s7_cdr(args); if (s7_is_integer(s7_car(args))) { int mode; mode = (int)s7_integer(s7_car(args)); if (s7_is_procedure(s7_cadr(args))) { open_error_func = s7_cadr(args); open_error_s7 = sc; } else { open_error_func = NULL; open_error_s7 = NULL; } return(s7_make_c_pointer(sc, (void *)gdbm_open(name, block_size, flags, mode, gdbm_open_error))); } return(s7_wrong_type_arg_error(sc, \"gdbm_open\", 4, s7_car(args), \"an integer (mode)\")); } return(s7_wrong_type_arg_error(sc, \"gdbm_open\", 3, s7_car(args), \"an integer (flags)\")); } return(s7_wrong_type_arg_error(sc, \"gdbm_open\", 2, s7_car(args), \"an integer (block_size)\")); } return(s7_wrong_type_arg_error(sc, \"gdbm_open\", 1, s7_car(args), \"a string (file name)\")); } ") (C-function ("gdbm_firstkey" g_gdbm_firstkey "(gdbm_firstkey gdbm)" 1)) (C-function ("gdbm_exists" g_gdbm_exists "(gdbm_exists gdbm key)" 2)) (C-function ("gdbm_delete" g_gdbm_delete "(gdbm_delete gdbm key)" 2)) (C-function ("gdbm_nextkey" g_gdbm_nextkey "(gdbm_nextkey gdbm prev)" 2)) (C-function ("gdbm_fetch" g_gdbm_fetch "(gdbm_fetch gdbm key)" 2)) (C-function ("gdbm_store" g_gdbm_store "(gdbm_store gdbm key context flag)" 4)) (C-function ("gdbm_open" g_gdbm_open "(gdbm_open filename size flags mode func) opens a gdbm data base" 5)) ) "" "gdbm.h" "" "-lgdbm" "libgdbm_s7") (curlet)))) *libgdbm* ;;; extern int gdbm_setopt (GDBM_FILE, int, void *, int) ;;; this is a huge mess #| (define gfile ((*libgdbm* 'gdbm_open) "test.gdbm" 1024 (*libgdbm* 'GDBM_NEWDB) #o664 (lambda (str) (format *stderr* "str: ~S~%" str)))) ((*libgdbm* 'gdbm_store) gfile "1" "1234" (*libgdbm* 'GDBM_REPLACE)) ((*libgdbm* 'gdbm_fetch) gfile "1") ((*libgdbm* 'gdbm_close) gfile) |# snd-16.1/fade.scm0000644000076400007640000002262712555220234011747 0ustar bilbil;;; cross fade instruments ;;; ;;; cross-fade sweeps up, down, or from mid-spectrum outwards, ;;; dissolve-fade chooses randomly -- like a graphical dissolve ;;; neither is exactly spectacular, but they work -- use similar sounds if possible (speech is problematic) ;;; ;;; translated from fade.ins (provide 'snd-fade.scm) (if (provided? 'snd) (require snd-ws.scm) (require sndlib-ws.scm)) (definstrument (cross-fade beg dur amp file1 file2 ramp-beg ramp-dur ramp-type bank-dur fs fwidth) ;; ramp-type 0=sweep up, 1=sweep down, 2=split from middle (if (> (+ (max bank-dur ramp-beg) ramp-dur bank-dur) dur) (begin (set! ramp-beg (* 0.25 dur)) (set! ramp-dur (* dur 0.49)) (set! bank-dur (* dur 0.24)))) (let ((fil1 (make-sampler 0 file1)) (fil2 (make-sampler 0 file2)) (start (seconds->samples beg)) (ramp-samps (seconds->samples ramp-dur)) (bank-samps (seconds->samples bank-dur)) (fs1 (make-vector fs))) (let ((bin (/ *clm-srate* (* 2 fs))) (radius (- 1.0 (/ fwidth (* 2 fs))))) (do ((k 0 (+ k 1))) ((= k fs)) (set! (fs1 k) (make-formant (* k bin) radius)))) (set! fs1 (make-formant-bank fs1)) (let ((end (+ start (seconds->samples dur))) (bank-incr (/ 1.0 bank-samps)) (ramp-incr (/ 1.0 ramp-samps)) (ramp-start (+ start (seconds->samples ramp-beg)))) (let ((bank1-start (- ramp-start bank-samps)) (ramp-end (+ ramp-start ramp-samps)) (bank2-start (+ ramp-start ramp-samps))) (do ((i start (+ i 1))) ((= i bank1-start)) ;; in first section -- just mix in file1 (outa i (* amp (read-sample fil1)))) (let ((bank2-end (+ bank2-start bank-samps)) (ramp 0.0) (outval 0.0) (inputs (make-float-vector fs 0.0)) (ifs (/ 1.0 fs)) (mid 0)) (do ((i bank1-start (+ i 1)) (bank1 0.0 (+ bank1 bank-incr))) ((= i ramp-start)) ;; in bank1 section -- fire up the resonators (let ((inval (read-sample fil1))) (set! outval (formant-bank fs1 inval)) (outa i (* amp (+ (* bank1 outval) (* (- 1.0 bank1) inval)))))) ;; in the ramp (case ramp-type ((0) (do ((i ramp-start (+ i 1))) ((= i ramp-end)) (let ((inval1 (read-sample fil1)) (inval2 (read-sample fil2))) ;; now the choice of spectral fade -- we should end with all bank1 0.0 and all bank2 1.0 (set! ramp (+ ramp ramp-incr)) ;; low freqs go first (if (>= ramp 0.5) (begin (set! mid (floor (* (- (* 2.0 ramp) 1.0) fs))) (fill! inputs inval2 0 mid) (float-vector-interpolate inputs mid fs 1.0 (- ifs) inval2 inval1) ;; (do ((k mid (+ k 1)) (ks 1.0 (- ks ifs))) ((>= k fs)) (float-vector-set! inputs k (+ (* ks inval2) (* (- 1.0 ks) inval1)))) ) (begin (set! mid (min fs (floor (* 2.0 ramp fs)))) (fill! inputs inval1 mid) (float-vector-interpolate inputs 0 mid (* 2.0 ramp) (- ifs) inval2 inval1) ;; (do ((k 0 (+ k 1)) (ks (* 2.0 ramp) (- ks ifs))) ((= k mid)) (float-vector-set! inputs k (+ (* ks inval2) (* (- 1.0 ks) inval1)))) )) (outa i (* amp (formant-bank fs1 inputs)))))) ((1) (do ((i ramp-start (+ i 1))) ((= i ramp-end)) (let ((inval1 (read-sample fil1)) (inval2 (read-sample fil2))) (set! ramp (+ ramp ramp-incr)) ;; high freqs go first (if (>= ramp 0.5) (let ((r2 (- (* 2.0 ramp) 1.0))) (set! mid (min fs (ceiling (* (- 1.0 r2) fs)))) (fill! inputs inval2 mid) (float-vector-interpolate inputs 0 mid r2 ifs inval2 inval1) ;; (do ((k 0 (+ k 1)) (ks r2 (+ ks ifs))) ((= k mid)) (float-vector-set! inputs k (+ (* ks inval2) (* (- 1.0 ks) inval1)))) ) (begin (set! mid (ceiling (* (- 1.0 (* 2.0 ramp)) fs))) (fill! inputs inval1 0 mid) (float-vector-interpolate inputs mid fs 0.0 ifs inval2 inval1) ;; (do ((k mid (+ k 1)) (ks 0.0 (+ ks ifs))) ((>= k fs)) (float-vector-set! inputs k (+ (* ks inval2) (* (- 1.0 ks) inval1)))) )) (outa i (* amp (formant-bank fs1 inputs)))))) (else (let ((half-fs (/ fs 2))) (do ((i ramp-start (+ i 1))) ((= i ramp-end)) (let ((inval1 (read-sample fil1)) (inval2 (read-sample fil2))) ;; now the choice of spectral fade -- we should end with all bank1 0.0 and all bank2 1.0 (set! ramp (+ ramp ramp-incr)) ;; sweep from midpoint out (fill! inputs inval1) (set! mid (min half-fs (floor (* fs ramp)))) (do ((k (- half-fs mid) (+ k 1)) (hk (+ half-fs mid -1) (- hk 1)) (ks (max 0.0 (- (* 2.0 ramp) 1.0)) (+ ks ifs))) ((= k half-fs)) (let ((rfs (min 1.0 ks))) (set! (inputs k) (+ (* rfs inval2) (* (- 1.0 rfs) inval1))) (set! (inputs hk) (inputs k)))) (outa i (* amp (formant-bank fs1 inputs)))))))) (do ((i ramp-end (+ i 1)) (bank2 1.0 (- bank2 bank-incr))) ((= i bank2-end)) ;; in bank2 section -- ramp out resonators (let ((inval (read-sample fil2))) (set! outval (formant-bank fs1 inval)) (outa i (* amp (+ (* bank2 outval) (* (- 1.0 bank2) inval)))))) (do ((i bank2-end (+ i 1))) ((= i end)) ;; in last section -- just mix file2 (outa i (* amp (read-sample fil2)))) ))))) ;;; (float-vector->channel (with-sound ((make-float-vector 22050)) (cross-fade 0 .1 1 0 1 .01 .01 0 .1 256 2))) ;;; (float-vector->channel (with-sound ((make-float-vector 44100)) (cross-fade 0 2 1.0 "oboe.snd" "trumpet.snd" 0.5 1.0 0 .1 256 2))) ;;; (with-sound (:statistics #t) (cross-fade 0 2 1.0 "oboe.snd" "trumpet.snd" 0.5 1.0 0 .1 256 2)) ;;; (with-sound () (cross-fade 0 2 1.0 "oboe.snd" "trumpet.snd" 0.5 1.0 0 .1 256 2)) ;;; these fades seem more successful to me when done relatively quickly (the opposite of the dissolve below ;;; which is best if done as slowly as possible). I like the sweep up best -- a sort of "evaporation" effect. (definstrument (dissolve-fade beg dur amp file1 file2 fsize r lo hi) (let ((fil1 (make-sampler 0 file1)) (fil2 (make-sampler 0 file2)) (start (seconds->samples beg)) (freq-inc (floor (/ fsize 2))) (ramp-inc (/ 1.0 1024.0))) (let ((end (+ start (seconds->samples dur))) (spectr (make-vector freq-inc #f)) (trigger (floor (/ (* dur *clm-srate*) freq-inc))) (fs (make-vector freq-inc #f)) (amps (make-float-vector freq-inc amp)) (ctr 0) (inputs (make-float-vector freq-inc 0.0)) (ramps (make-vector freq-inc -1)) (in2s (make-int-vector freq-inc 0)) (in2-ctr 0) (ramp-ctr 0)) (if (not (number? hi)) (set! hi freq-inc)) (let ((bin (floor (/ *clm-srate* fsize))) (radius (- 1.0 (/ r fsize)))) (do ((k lo (+ k 1))) ((= k hi)) (set! (fs k) (make-formant (* k bin) radius)))) (set! fs (make-formant-bank fs amps)) ; wrap it up... (do ((i start (+ i 1))) ((= i end)) ;; once a ramp is set in motion, it takes care of itself -- we need only choose which to trigger (set! ctr (+ ctr 1)) (if (> ctr trigger) (let ((next (floor (random freq-inc)))) ;; find next randomly chosen resonator to flip (if (not (spectr next)) (set! (spectr next) (- 1.0 ramp-inc)) (call-with-exit (lambda (bbreak) (do ((j next (+ j 1)) (k next (- k 1))) () (if (and (< j freq-inc) (not (spectr j))) (begin (set! (spectr j) (- 1.0 ramp-inc)) (set! next j) (bbreak))) (if (and (>= k 0) (not (spectr k))) (begin (set! (spectr k) (- 1.0 ramp-inc)) (set! next k) (bbreak))))))) (set! (ramps ramp-ctr) next) (set! ramp-ctr (+ ramp-ctr 1)) (set! ctr 0))) (let ((inval1 (read-sample fil1)) (inval2 (read-sample fil2))) (fill! inputs inval1) (float-vector-spatter inputs in2s in2-ctr inval2) ;; (do ((k 0 (+ k 1))) ((= k in2-ctr)) (float-vector-set! inputs (int-vector-ref in2s k) inval2)) (if (> ramp-ctr 0) (let ((rk 0) (sp 0.0) (fixup-ramps #f)) (do ((k 0 (+ k 1))) ((= k ramp-ctr)) (set! rk (ramps k)) (set! sp (vector-ref spectr rk)) (float-vector-set! inputs k (+ (* sp inval1) (* (- 1.0 sp) inval2))) (set! sp (- sp ramp-inc)) (if (> sp 0.0) (vector-set! spectr rk sp) (begin (set! (in2s in2-ctr) rk) (set! in2-ctr (+ in2-ctr 1)) (set! fixup-ramps #t) (set! (ramps k) -1)))) (if fixup-ramps (let ((j 0)) (do ((k 0 (+ k 1))) ((= k ramp-ctr)) (if (>= (ramps k) 0) (begin (set! (ramps j) (ramps k)) (set! j (+ j 1))))) (set! ramp-ctr j))))) (outa i (formant-bank fs inputs))))))) ;;; (with-sound (:statistics #t) (dissolve-fade 0 1 1.0 "oboe.snd" "trumpet.snd" 256 2 0 128)) ;;; (float-vector->channel (with-sound ((make-float-vector 44100)) (dissolve-fade 0 2 1 0 1 4096 2 2 #f))) ;;; ;;; another neat effect here is to simply let the random changes float along with no ;;; direction -- if the hit is 1.0 send it toward 0.0 and vice versa -- strange ;;; pitches emerge from noises etc #| ;;; make it easy to see and hear: (with-sound ("p1.snd") (let ((g (make-ncos 200 100))) (do ((i 0 (+ i 1))) ((= i 100000)) (outa i (ncos g))))) (with-sound ("p2.snd") (let ((g (make-ncos 123 100))) (do ((i 0 (+ i 1))) ((= i 100000)) (outa i (ncos g))))) (with-sound (:statistics #t) (cross-fade 0 2 1.0 "p1.snd" "p2.snd" 0.5 1.0 0 .1 256 2)) (with-sound (:statistics #t) (dissolve-fade 0 2 1.0 "p1.snd" "p2.snd" 256 2 0 128)) |# snd-16.1/draw.scm0000644000076400007640000002505212447054525012010 0ustar bilbil;;; examples of extensions to Snd's graphics (provide 'snd-draw.scm) (define (overlay-rms-env snd chn) (let ((red (make-color 1 0 0)) ; rms env displayed in red (left (left-sample snd chn)) (right (right-sample snd chn)) (rms-size 128) ; this could be a parameter -- not sure what the "right" size is (sr (/ 1.0 (srate snd))) (old-color (foreground-color snd chn)) (axinf (axis-info snd chn)) (old-axinf (channel-property 'rms-axis-info snd chn)) (cr (make-cairo (car (channel-widgets snd chn))))) ;; these functions are an optimization to speed up calculating the rms env graph. ;; ideally we'd use something like: ;; ;; (let* ((x1 (x->position (/ i (srate)) snd chn)) ;; (y1 (y->position (moving-rms rms (reader)) snd chn))) ;; (draw-line x0 y0 x1 y1) ;; ;; in the do-loop below that runs through the samples, but I haven't added x|y->position or draw-line ;; to the optimizer ("run"), and each would be looking up the graph axis info on each call even if ;; available to the optimizer -- this seems wasteful. So, the grf-it function below is using the ;; axis info in axinf to get the pixel location for the envelope line segment break point. ;; Also, draw-lines takes a vector for some reason, so we need to tell "run" that it is an ;; integer vector (and preload it with 0). We save the vector in the channel property 'rms-lines, ;; and the associated axis info in 'rms-axis-info. Since redisplay is common in Snd, it reduces ;; flicker a lot to have this data instantly available. (define (pack-x-info axinf) (float-vector (axinf 2) ; x0 (axinf 4) ; x1 (axinf 10) ; x_axis_x0 (axinf 12) ; x_axis_x1 (axinf 15) ; scale (- (axinf 10) (* (axinf 2) (axinf 15))))) ; base (define (pack-y-info axinf) (float-vector (axinf 3) ; y0 (axinf 5) ; y1 (axinf 11) ; y_axis_y0 (axinf 13) ; y_axis_y1 (axinf 16) ; scale (- (axinf 11) (* (axinf 3) (axinf 16))))) ; base (define (grf-it val v) (round (if (>= val (v 1)) (v 3) (if (<= val (v 0)) (v 2) (+ (v 5) (* val (v 4))))))) (define* (make-moving-rms (size 128)) (make-moving-average size)) (define (moving-rms gen y) (sqrt (moving-average gen (* y y)))) (if (equal? axinf old-axinf) ; the previously calculated lines can be re-used (begin (set! (foreground-color snd chn) red) (draw-lines (channel-property 'rms-lines snd chn) snd chn time-graph cr) (set! (foreground-color snd chn) old-color)) (let* ((xdata (pack-x-info axinf)) (ydata (pack-y-info axinf)) (start (max 0 (- left rms-size))) (reader (make-sampler start snd chn)) (rms (make-moving-rms rms-size)) (x0 0) (y0 0) (line-ctr 2) (lines (make-vector (* 2 (+ 1 (- (axinf 12) (axinf 10)))) 0))) (dynamic-wind (lambda () (set! (foreground-color snd chn) red)) (lambda () (if (< start left) ; check previous samples to get first rms value (do ((i start (+ 1 i))) ((= i left)) (moving-rms rms (reader)))) (let ((first-sample (next-sample reader))) (set! x0 (grf-it (* left sr) xdata)) (set! y0 (grf-it first-sample ydata)) (set! (lines 0) x0) ; first graph point (set! (lines 1) y0)) (do ((i (+ left 1) (+ 1 i))) ; loop through all samples calling moving-rms ((= i right)) (let ((x1 (grf-it (* i sr) xdata)) (y (moving-rms rms (next-sample reader)))) (if (> x1 x0) ; very often many samples are represented by one pixel (let ((y1 (grf-it y ydata))) (set! (lines line-ctr) x1) (set! (lines (+ 1 line-ctr)) y1) (set! line-ctr (+ line-ctr 2)) (set! x0 x1) (set! y0 y1))))) ; else should we do "max" here? or draw a vertical line from min to max? (if (< line-ctr (length lines)) (do ((j line-ctr (+ j 2))) ; off-by-one in vector size calc -- need to pad so we don't get a bogus line to (0, 0) ((>= j (length lines))) (set! (lines j) x0) (set! (lines (+ j 1)) y0))) (draw-lines lines snd chn time-graph cr) (set! (channel-property 'rms-lines snd chn) lines) ; save current data for possible redisplay (set! (channel-property 'rms-axis-info snd chn) axinf)) (lambda () (set! (foreground-color snd chn) old-color))))) (free-cairo cr))) ;(hook-push after-graph-hook (lambda (hook) (overlay-rms-env (hook 'snd) (hook 'chn)))) (define display-colored-samples (let ((documentation "(display-colored-samples color beg dur snd chn) displays samples from beg for dur in color whenever they're in the current view.")) (lambda* (color beg dur snd chn) (let ((left (left-sample snd chn)) (right (right-sample snd chn)) (end (+ beg dur)) (old-color (foreground-color snd chn)) (cr (make-cairo (car (channel-widgets snd chn))))) (if (and (< left end) (> right beg)) (let ((data (make-graph-data snd chn))) (if (float-vector? data) (let* ((samps (- (min right end) (max left beg))) (offset (max 0 (- beg left))) (new-data (float-vector-subseq data offset (+ offset samps)))) (set! (foreground-color snd chn) color) (graph-data new-data snd chn copy-context (max beg left) (min end right) (time-graph-style snd chn) cr) (set! (foreground-color snd chn) old-color)) (let* ((low-data (car data)) (high-data (cadr data)) (size (length low-data)) (samps (- right left)) (left-offset (max 0 (- beg left))) (left-bin (floor (/ (* size left-offset) samps))) (right-offset (- (min end right) left)) (right-bin (floor (/ (* size right-offset) samps))) (new-low-data (float-vector-subseq low-data left-bin right-bin)) (new-high-data (float-vector-subseq high-data left-bin right-bin))) (set! (foreground-color snd chn) color) (graph-data (list new-low-data new-high-data) snd chn copy-context left-bin right-bin (time-graph-style snd chn) cr) (set! (foreground-color snd chn) old-color))))) (free-cairo cr))))) (define (display-samples-in-color hook) (let ((snd (hook 'snd)) (chn (hook 'chn))) ;; intended as after-graph-hook member ;; run through 'colored-samples lists passing each to display-colored-samples (let ((colors (channel-property 'colored-samples snd chn))) (if colors (for-each (lambda (vals) (apply display-colored-samples (append vals (list snd chn)))) colors))))) (define color-samples (let ((documentation "(color-samples color beg dur snd chn) causes samples from beg to beg+dur to be displayed in color")) (lambda* (color ubeg udur usnd uchn) (if (not (member display-samples-in-color (hook-functions after-graph-hook))) (hook-push after-graph-hook display-samples-in-color)) (let* ((beg (or ubeg 0)) (snd (or usnd (selected-sound) (car (sounds)))) (chn (or uchn (selected-channel snd) 0)) (dur (or udur (- (framples snd chn) beg))) (old-colors (or (channel-property 'colored-samples snd chn) ()))) (set! (channel-property 'colored-samples snd chn) (cons (list color beg dur) old-colors)) (update-time-graph snd chn))))) (define uncolor-samples (let ((documentation "(uncolor-samples snd chn) cancels sample coloring in the given channel")) (lambda* (usnd uchn) (let* ((snd (or usnd (selected-sound) (car (sounds)))) (chn (or uchn (selected-channel snd) 0))) (set! (channel-property 'colored-samples snd chn) ()) (update-time-graph snd chn))))) (define display-previous-edits (let ((documentation "(display-previous-edits snd chn) displays all edits of the current sound, with older versions gradually fading away")) (lambda (snd chn) (let ((edits (edit-position snd chn))) (if (> edits 0) (let* ((old-color (foreground-color snd chn)) (clist (color->list old-color)) (r (car clist)) (g (cadr clist)) (b (caddr clist)) (rinc (/ (- 1.0 r) (+ edits 1))) (ginc (/ (- 1.0 g) (+ edits 1))) (binc (/ (- 1.0 b) (+ edits 1))) (cr (make-cairo (car (channel-widgets snd chn))))) (do ((pos 0 (+ 1 pos)) (re (- 1.0 rinc) (- re rinc)) (ge (- 1.0 ginc) (- ge ginc)) (be (- 1.0 binc) (- be binc))) ((> pos edits)) (let ((data (make-graph-data snd chn pos))) (set! (foreground-color snd chn) (make-color re ge be)) (graph-data data snd chn copy-context #f #f (time-graph-style snd chn) cr))) (set! (foreground-color snd chn) old-color) (free-cairo cr))))))) (define overlay-sounds (let ((documentation "(overlay-sounds . args) overlays onto its first argument all subsequent arguments: (overlay-sounds 1 0 3)")) (lambda args (let ((base (if (integer? (car args)) (integer->sound (car args)) (car args)))) (hook-push after-graph-hook (lambda (hook) (let ((snd (hook 'snd)) (chn (hook 'chn))) (if (equal? snd base) (let ((cr (make-cairo (car (channel-widgets snd chn))))) (for-each (lambda (nsnd) (if (and (sound? nsnd) (> (chans nsnd) chn)) (graph-data (make-graph-data nsnd chn) base chn copy-context #f #f graph-dots cr))) (cdr args)) (free-cairo cr)))))))))) (define samples-via-colormap (let ((documentation "(samples-via-colormap snd chn) displays time domain graph using current colormap (just an example of colormap-ref)")) (lambda (snd chn) (let ((left (left-sample snd chn)) (right (right-sample snd chn)) (old-color (foreground-color snd chn)) (data (make-graph-data snd chn)) (cr (make-cairo (car (channel-widgets snd chn))))) (define (samples-1 cur-data) (let* ((x0 (x->position (/ left (srate snd)))) (y0 (y->position (cur-data 0))) (colors (make-vector *colormap-size* #f)) (len (length cur-data)) (incr (/ (+ 1 (- right left)) len))) (do ((i (+ left incr) (+ i incr)) (j 1 (+ 1 j))) ((or (>= i right) (>= j len))) (let* ((x1 (x->position (/ i (srate snd)))) (y1 (y->position (cur-data j))) (x (abs (cur-data j))) (ref (floor (* *colormap-size* x))) (color (or (colors ref) (let ((new-color (apply make-color (colormap-ref (colormap) x)))) (set! (colors ref) new-color))))) (set! (foreground-color snd chn) color) (draw-line x0 y0 x1 y1 snd chn time-graph cr) (set! x0 x1) (set! y0 y1))) (set! (foreground-color snd chn) old-color))) (if data (if (float-vector? data) (samples-1 data) (begin (samples-1 (car data)) (samples-1 (cadr data))))) (free-cairo cr))))) snd-16.1/strad.scm0000644000076400007640000002770712624726277012210 0ustar bilbil;;; strad.scm -- Translation CLM -> Snd ;; Bowed string physical model with stiffness. CLM version adapted ;; from the Matlab and C versions courtesy of JOS and Stefania Serafin ;; from code revised on 7/14/01 ;; CLM version by Juan Reyes ;; SND version by Michael Scholz (based on strad.ins) ;; revised by Bill to suit the run macro (provide 'snd-strad.scm) (if (provided? 'snd) (require snd-ws.scm) (require sndlib-ws.scm)) (define make-biquad (let ((documentation "(make-biquad a0 a1 a2 b1 b2) returns a biquad filter (use with the CLM filter gen)")) (lambda (a0 a1 a2 b1 b2) (make-filter 3 (float-vector a0 a1 a2) (float-vector 0.0 b1 b2))))) (definstrument (bow beg dur frq amplitude (bufsize 2205) (fb 0.2) ;; bow force: between 0.0 and 1.0 (vb 0.05) ;; bow velocity: between 0.0 and 0.8 (bp 0.08) ;; bow position: 0.0=bridge; 0.5=middle of string; 1.0=Nut (inharm 0.1) ;; inharmonicity: 0.0 harmonic; 1.0 not harmonico (ampenv '(0 1 15 1 95 1 100 0)) (degree 45) (dist 0.0025) (reverb 0)) (let ((beg (seconds->samples beg)) (len-1 (seconds->samples dur)) (freq frq) (len (- (/ *clm-srate* frq ) 2)) (twavespeedfactor 5.2) (stringImpedance 0.55) (stringImpedancet 1.8)) (let ((lent (/ (- (/ *clm-srate* freq) 2) twavespeedfactor))) (let ((ampf (make-env :envelope ampenv :scaler amplitude :duration dur)) (end (+ beg len-1)) (loc (make-locsig degree dist reverb)) (vinut (make-float-vector bufsize)) (vinbridge (make-float-vector bufsize)) (vinutt (make-float-vector bufsize)) (vinbridget (make-float-vector bufsize)) (vib 0.0) (vin 0.0) (vibt 0.0) (vint 0.0) (mus 0.8) (posl 0) (posr 0) (poslt 0) (posrt 0) (indexl 0) (indexr 0) (indexlt 0) (indexrt 0) (indexl_1 0) (indexr_1 0) (indexlt_1 0) (indexrt_1 0) (indexl_2 0) (indexr_2 0) (indexlt_2 0) (indexrt_2 0) (updl 0) (updr 0) (updlt 0) (updrt 0) (b0b 0.859210) (b1b -0.704922) (b2b 0.022502) (a1b -0.943639) (a2b 0.120665) (b0n 7.0580050e-001) (b1n -5.3168461e-001) (b2n 1.4579750e-002) (a1n -9.9142489e-001) (a2n 1.8012052e-001) (b0bt 9.9157155e-001) (b1bt -8.2342890e-001) (b2bt 8.8441749e-002) (a1bt -8.3628218e-001) (a2bt 9.2866585e-002) (b0nt 4.3721359e-001) (b1nt -2.7034968e-001) (b2nt -5.7147560e-002) (a1nt -1.2158343e+000) (a2nt 3.2555068e-001) (ynb 0.0e0) (ynbt 0.0e0) (ynn 0.0e0) (ynnt 0.0e0) (ya1nb 0.0e0) (ynba1 0.0e0) (y1nb 0.0e0) (vh 0.0e0) (aa 0.0e0) (bb1 0.0e0) (cc1 0.0e0) (delta1 0.0e0) (bb2 0.0e0) (cc2 0.0e0) (delta2 0.0e0) (v 0.0e0) (v1 0.0e0) (v2 0.0e0) (rhs #f) (lhs #f) (vtemp 0.0e0) (f 0.0e0) (stick 0) ;;(zslope (/ 1 (+ (/ 1 (* 2 stringImpedance)) (/ 1 (* 2 stringImpedancet))))) (zslope (/ (* 2 stringImpedance stringImpedancet) (+ stringImpedance stringImpedancet))) (xnn 0.0e0) (xnb 0.0e0) (xnnt 0.0e0) (xnbt 0.0e0) (alphar 0) (alphal 0) (alphart 0) (alphalt 0) (del_right (* len bp)) (del_left (* len (- 1 bp))) (del_leftt (* lent (- 1 bp))) (del_rightt (* lent bp))) (let ((samp_rperiod (floor del_right)) (samp_lperiod (floor del_left)) (samp_lperiodt (floor del_leftt)) (samp_rperiodt (floor del_rightt))) (let ((g1 (make-biquad b0b b1b b2b a1b a2b)) (g2 (make-biquad b0n b1n b2n a1n a2n)) (g3 (make-biquad b0bt b1bt b2bt a1bt a2bt)) (g4 (make-biquad b0nt b1nt b2nt a1nt a2nt))) (define (bowfilt inharmon) (set! ynb (filter g1 vib)) (set! ynn (filter g2 vin)) (set! ynbt (filter g3 vibt)) (set! ynnt (filter g4 vint)) (if (<= inharmon 0.00001) (set! inharmon 0.00001)) (if (>= inharmon 0.9999) (set! inharmon 0.9999)) (set! y1nb (+ (* -1 inharmon ynb) ynba1 (* inharmon ya1nb))) (set! ya1nb y1nb) (set! ynba1 ynb) (set! y1nb (- y1nb)) (set! ynn (- ynn)) (set! ynbt (- ynbt))) (if (< samp_rperiod 0) (set! samp_rperiod 0)) (if (> samp_rperiod (- bufsize 1)) (set! samp_rperiod (- bufsize 1))) (if (< samp_lperiod 0) (set! samp_lperiod 0)) (if (> samp_lperiod (- bufsize 1)) (set! samp_lperiod (- bufsize 1))) (set! alphar (* 1.0 (- del_right samp_rperiod))) (set! alphal (* 1.0 (- del_left samp_lperiod))) (if (< samp_rperiodt 0)(set! samp_rperiodt 0)) (if (> samp_rperiodt (- bufsize 1)) (set! samp_rperiodt (- bufsize 1))) (if (< samp_lperiodt 0) (set! samp_lperiodt 0)) (if (> samp_lperiodt (- bufsize 1)) (set! samp_lperiodt (- bufsize 1))) (set! alphart (* 1.0 (- del_rightt samp_rperiodt))) (set! alphalt (* 1.0 (- del_leftt samp_lperiodt))) (set! posr (modulo (floor (+ end posr)) bufsize)) (set! posl (modulo (floor (+ end posl)) bufsize)) (set! posrt (modulo (floor (+ end posrt)) bufsize)) (set! poslt (modulo (floor (+ end poslt)) bufsize)) (set! indexl (modulo (floor (- (+ beg posl bufsize) samp_lperiod)) bufsize)) (set! indexr (modulo (floor (- (+ beg posr bufsize) samp_rperiod)) bufsize)) (set! indexlt (modulo (floor (- (+ beg poslt bufsize) samp_lperiodt)) bufsize)) (set! indexrt (modulo (floor (- (+ beg posrt bufsize) samp_rperiodt)) bufsize)) (set! indexl_1 (modulo (floor (- (+ beg posl bufsize) samp_lperiod 1)) bufsize)) (set! indexr_1 (modulo (floor (- (+ beg posr bufsize) samp_rperiod 1)) bufsize)) (set! indexlt_1 (modulo (floor (- (+ beg poslt bufsize) samp_lperiodt 1)) bufsize)) (set! indexrt_1 (modulo (floor (- (+ beg posrt bufsize) samp_rperiodt 1)) bufsize)) (set! indexl_2 (modulo (floor (- (+ beg posl bufsize) samp_lperiod 2)) bufsize)) (set! indexr_2 (modulo (floor (- (+ beg posr bufsize) samp_rperiod 2)) bufsize)) (set! indexlt_2 (modulo (floor (- (+ beg poslt bufsize) samp_lperiodt 2)) bufsize)) (set! indexrt_2 (modulo (floor (- (+ beg posrt bufsize) samp_rperiodt 2)) bufsize)) (set! updl (modulo (floor (+ beg posl bufsize)) bufsize)) (set! updr (modulo (floor (+ beg posr bufsize)) bufsize)) (set! updlt (modulo (floor (+ beg poslt bufsize)) bufsize)) (set! updrt (modulo (floor (+ beg posrt bufsize)) bufsize)) (do ((i beg (+ i 1))) ((= i end)) (set! vib (+ (/ (* (vinbridge indexl_2) (- alphal 1) (- alphal 2)) 2) (* (vinbridge indexl_1) alphal -1 (- alphal 2)) (/ (* (vinbridge indexl) alphal (- alphal 1)) 2))) (set! vin (+ (/ (* (vinut indexr_2) (- alphar 1) (- alphar 2)) 2) (* (vinut indexr_1) alphar -1 (- alphar 2)) (/ (* (vinut indexr) (- alphar 1) alphar) 2))) (set! vibt (+ (/ (* (vinbridget indexlt_2) (- alphalt 1)(- alphalt 2)) 2) (* (vinbridget indexlt_1) alphalt -1 (- alphalt 2)) (/ (* (vinbridget indexlt) alphalt (- alphalt 1)) 2))) (set! vint (+ (/ (* (vinutt indexrt_2) (- alphart 1) (- alphart 2)) 2) (* (vinutt indexrt_1) alphart -1 (- alphart 2)) (/ (* (vinutt indexrt) (- alphart 1) alphart) 2))) (bowfilt inharm) (set! vh (+ ynn y1nb ynnt ynbt)) (set! aa zslope) (set! bb1 (- (+ (* 0.2 zslope) (* 0.3 fb)) (* zslope vb) (* zslope vh))) (set! cc1 (- (+ (* 0.06 fb) (* zslope vh vb)) (* 0.2 zslope vh) (* 0.3 vb fb))) (set! delta1 (- (* bb1 bb1) (* 4 aa cc1))) (set! bb2 (- (- (* -0.2 zslope) (* 0.3 fb)) (* zslope vb) (* zslope vh))) (set! cc2 (+ (* 0.06 fb) (* zslope vh vb) (* 0.2 zslope vh) (* 0.3 vb fb) (* 0.1 fb))) (set! delta2 (- (* bb2 bb2) (* 4 aa cc2))) (if (or (= vb 0) (= fb 0)) (set! v vh) (begin (if (= vh vb) (begin (set! v vb) (set! stick 1)) (begin (if (> vh vb) (begin (set! lhs #f) (set! rhs #t)) (begin (set! rhs #f) (set! lhs #t))) (if rhs (begin (if (< delta1 0) (begin (set! v vb) (set! stick 1)) (begin (if (= stick 1) (begin (set! vtemp vb) (set! f (* 2 zslope (- vtemp vh))) (if (>= f (* -1 mus fb)) (set! v vtemp) (begin (set! v1 (/ (+ (- bb1) (sqrt delta1)) (* 2 aa))) (set! v2 (/ (- (- bb1) (sqrt delta1)) (* 2 aa))) (set! v (min v1 v2)) (set! stick 0)))) (begin (set! v1 (/ (+ (- bb1) (sqrt delta1)) (* 2 aa))) (set! v2 (/ (- (- bb1) (sqrt delta1)) (* 2 aa))) (set! v (min v1 v2)) (set! stick 0)))))) (if lhs (begin (if (< delta2 0) (begin (set! v vb) (set! stick 1)) (begin (if (= stick 1) (begin (set! vtemp vb) (set! f (* zslope (- vtemp vh))) (if (and (<= f (* mus fb)) (> f 0)) (set! v vtemp) (begin (set! v1 (/ (- (- bb2) (sqrt delta2)) (* 2 aa))) (set! v2 (/ (+ (- bb2) (sqrt delta2)) (* 2 aa))) (set! vtemp (min v1 v2)) (set! stick 0) (if (> vtemp vb) (begin (set! v vb) (set! stick 1)) (begin (set! v vtemp) (set! f (* zslope (- v vh) ))))))) (begin (set! v1 (/ (- (- bb2) (sqrt delta2)) (* 2 aa))) (set! v2 (/ (+ (- bb2) (sqrt delta2)) (* 2 aa))) (set! v (min v1 v2)) (set! stick 0))))) (if (> v vb) (begin (set! v vb) (set! stick 1)))))))) (set! f (* zslope (- v vh))) (set! xnn (+ y1nb (/ f (* 2 stringImpedance)))) (set! xnb (+ ynn (/ f (* 2 stringImpedance)))))) (set! f (* zslope (- v vh))) (set! xnnt (+ ynbt (/ f (* 2 stringImpedancet)))) (set! xnbt (+ ynnt (/ f (* 2 stringImpedancet)))) (set! (vinbridge updl) xnb) (set! (vinut updr) xnn) (set! (vinbridget updlt) xnbt) (set! (vinutt updrt) xnnt) (set! indexl (+ indexl 1)) (if (>= indexl bufsize) (set! indexl 0)) (set! indexr (+ indexr 1)) (if (>= indexr bufsize) (set! indexr 0)) (set! indexlt (+ indexlt 1)) (if (>= indexlt bufsize) (set! indexlt 0)) (set! indexrt (+ indexrt 1)) (if (>= indexrt bufsize) (set! indexrt 0)) (set! indexl_1 (+ indexl_1 1)) (if (>= indexl_1 bufsize) (set! indexl_1 0)) (set! indexr_1 (+ indexr_1 1)) (if (>= indexr_1 bufsize) (set! indexr_1 0)) (set! indexlt_1 (+ indexlt_1 1)) (if (>= indexlt_1 bufsize) (set! indexlt_1 0)) (set! indexrt_1 (+ indexrt_1 1)) (if (>= indexrt_1 bufsize) (set! indexrt_1 0)) (set! indexl_2 (+ indexl_2 1)) (if (>= indexl_2 bufsize) (set! indexl_2 0)) (set! indexr_2 (+ indexr_2 1)) (if (>= indexr_2 bufsize) (set! indexr_2 0)) (set! indexlt_2 (+ indexlt_2 1)) (if (>= indexlt_2 bufsize) (set! indexlt_2 0)) (set! indexrt_2 (+ indexrt_2 1)) (if (>= indexrt_2 bufsize) (set! indexrt_2 0)) (set! updl (+ updl 1)) (if (>= updl bufsize) (set! updl 0)) (set! updr (+ updr 1)) (if (>= updr bufsize) (set! updr 0)) (set! updlt (+ updlt 1)) (if (>= updlt bufsize) (set! updlt 0)) (set! updrt (+ updrt 1)) (if (>= updrt bufsize) (set! updrt 0)) (locsig loc i (* xnb (env ampf))) (set! lhs #f) (set! rhs #f)))))))) ;(with-sound (:channels 2) (bow 0 3 400 0.5 :vb 0.15 :fb 0.1 :inharm 0.25)) ;(with-sound (:channels 2) (bow 0 2 440 0.5 :fb 0.25)) ;(with-sound (:channels 2) (bow 0 4 600 0.8)) ;(with-sound (:channels 2) (bow 0 6 147 2 :fb 0.035 :vb 0.1)) ;(with-sound (:channels 2) (bow 0 3 1100 0.5 :vb 0.45 :fb 0.9 :inharm 0.3)) ;(with-sound (:channels 2) (bow 0 3 1500 0.5 :vb 0.25 :fb 0.9 :inharm 0.3)) ;(with-sound (:channels 2) (bow 0 3 1525 0.5 :vb 0.25 :fb 0.9 :inharm 0.3)) ;(with-sound (:channels 2 :reverb jc-reverb) (bow 0 1 400 0.5 :reverb 0.0051)) ; ;(with-sound (:channels 2 :reverb jc-reverb) ; (bow 0 3 366 0.5 :degree 0) ; (bow 0 3 422 0.5 :degree 90) ; (bow 4 6 147 2 :fb 0.035 :vb 0.1 :reverb 0.051)) ;; strad.scm ends here snd-16.1/extensions.scm0000644000076400007640000005452312616231602013246 0ustar bilbil;;; various generally useful Snd extensions ;;; mix then scale result to original peak amp ;;; mix with envelope ;;; map-sound-files, for-each-sound-file, match-sound-files, directory->list ;;; mix-channel, insert-channel ;;; redo-channel, undo-channel ;;; sine-ramp, sine-env-channel, blackman4-ramp, blackman4-env-channel ;;; ramp-squared, env-squared-channel ;;; ramp-expt, env-expt-channel ;;; offset-channel ;;; channels-equal ;;; mono->stereo, mono-files->stereo, stereo->mono (provide 'snd-extensions.scm) (define remove-if (let ((documentation "(remove-if func lst) removes any element from 'lst' that 'func' likes")) (lambda (pred l) (map (lambda (x) (if (pred x) (values) x)) l)))) (if (not (defined? 'all-chans)) (define all-chans (let ((documentation "(all-chans) -> two parallel lists, the first sound objects, the second channel numbers. If we have two sounds open (indices 0 and 1 for example), and the second has two channels, (all-chans) returns '((# # #) (0 0 1))")) (lambda () (let ((sndlist ()) (chnlist ())) (for-each (lambda (snd) (do ((i (- (channels snd) 1) (- i 1))) ((< i 0)) (set! sndlist (cons snd sndlist)) (set! chnlist (cons i chnlist)))) (sounds)) (list sndlist chnlist)))))) (define channel-sync (dilambda (let ((documentation "(channel-sync snd chn) returns the sync property of that channel (it is not actually used anywhere)")) (lambda (snd chn) (channel-property 'sync snd chn))) (lambda (snd chn val) (set! (channel-property 'sync snd chn) val)))) ;;; -------- mix with result at original peak amp (define normalized-mix (let ((documentation "(normalized-mix filename beg in-chan snd chn) is like mix but the mix result has same peak amp as unmixed snd/chn (returns scaler)")) (lambda* (filename beg in-chan snd chn) (let ((original-maxamp (maxamp snd chn))) (mix filename beg in-chan snd chn) (let ((new-maxamp (maxamp snd chn))) (if (not (= original-maxamp new-maxamp)) (let ((scaler (/ original-maxamp new-maxamp)) (old-sync (sync snd))) (set! (sync snd) (+ (sync-max) 1)) (scale-by scaler snd chn) (set! (sync snd) old-sync) scaler) 1.0)))))) ;;;-------- mix with envelope on mixed-in file (define enveloped-mix (let ((documentation "(enveloped-mix filename beg e) mixes filename starting at beg with amplitude envelope e. (enveloped-mix \"pistol.snd\" 0 '(0 0 1 1 2 0))")) (lambda (filename beg e) (let* ((len (framples filename)) (amp-env (make-env e :length len)) (rd (make-readin filename))) (map-channel (lambda (y) (+ y (* (env amp-env) (readin rd)))) beg len))))) ;;; -------- map-sound-files, match-sound-files ;;; ;;; apply a function to each sound in dir ;;; ;;; (map-sound-files (lambda (n) (if (> (mus-sound-duration n) 10.0) (snd-print n)))) (define map-sound-files (let ((documentation "(map-sound-files func dir) applies func to each sound file in dir")) (lambda* (func dir) (map func (sound-files-in-directory (or dir ".")))))) (define for-each-sound-file (let ((documentation "(for-each-sound-file func dir) applies func to each sound file in dir")) (lambda* (func dir) (for-each func (sound-files-in-directory (or dir ".")))))) #| (for-each-sound-file (lambda (n) (catch #t (lambda () (if (pair? (mus-sound-loop-info (string-append "/home/bil/sf/" n))) (snd-print (format #f "~%~A" n)))) (lambda args #f))) "/home/bil/sf") |# (define match-sound-files (let ((documentation "(match-sound-files func dir) applies func to each sound file in dir and returns a list of files for which func does not return #f")) (lambda* (func dir) (let ((matches ())) (for-each (lambda (file) (if (func file) (set! matches (cons file matches)))) (sound-files-in-directory (or dir "."))) matches)))) ;;; -------- mix-channel, insert-channel, c-channel (define mix-channel (let ((documentation "(mix-channel file beg dur snd chn edpos with-tag) mixes in file. file can be the file name, a sound object, or \ a list (file-name-or-sound-object [beg [channel]]).")) (lambda* (input-data (beg 0) dur snd (chn 0) edpos with-tag) (define (channel->mix input-snd input-chn input-beg input-len output-snd output-chn output-beg) (if (< input-len 1000000) (mix-float-vector (channel->float-vector input-beg input-len input-snd input-chn) output-beg output-snd output-chn #t) (let* ((output-name (snd-tempnam)) (output (new-sound output-name :size input-len))) (float-vector->channel (samples input-beg input-len input-snd input-chn) 0 input-len output 0) (save-sound output) (close-sound output) (mix output-name output-beg 0 output-snd output-chn #t #t)))) (let* ((input (if (not (pair? input-data)) input-data (car input-data))) (input-beg (if (or (not (pair? input-data)) (< (length input-data) 2)) 0 (cadr input-data))) (input-channel (if (or (not (pair? input-data)) (< (length input-data) 3)) 0 (caddr input-data))) (len (or dur (- (if (string? input) (framples input) (framples input input-channel)) input-beg))) (start (or beg 0))) (if (< start 0) (error 'no-such-sample "mix-channel: begin time < 0: ~A" beg) (if (> len 0) (if (not with-tag) ;; not a virtual mix (let ((d1 (samples input-beg len input input-channel)) (d2 (samples start len snd chn edpos))) (float-vector-add! d1 d2) (float-vector->channel d1 start len snd chn current-edit-position (if (string? input-data) (format #f "mix-channel ~S ~A ~A" input-data beg dur) (format #f "mix-channel '~A ~A ~A" input-data beg dur)))) ;; a virtual mix -- use simplest method available (if (sound? input) ;; sound object case (channel->mix input input-channel input-beg len snd chn start) ;; file input (if (and (= start 0) (= len (framples input))) ;; mixing entire file (mix input start 0 snd chn #t #f) ; don't delete it! ;; mixing part of file (let* ((output-name (snd-tempnam)) (output (new-sound output-name :size len))) (float-vector->channel (samples input-beg len input input-channel) 0 len output 0) (save-sound output) (close-sound output) (mix output-name start 0 snd chn #t #t))))))))))) (define insert-channel (let ((documentation "(insert-channel file beg dur snd chn edpos) inserts the file. file can be the file name or a list (file-name [beg [channel]])")) (lambda* (file-data beg dur snd chn edpos) (let* ((file-name (if (string? file-data) file-data (car file-data))) (file-beg (if (or (string? file-data) (< (length file-data) 2)) 0 (cadr file-data))) (file-channel (if (or (string? file-data) (< (length file-data) 3)) 0 (caddr file-data))) (len (or dur (- (framples file-name) file-beg))) (start (or beg 0))) (if (< start 0) (error 'no-such-sample "insert-channel: begin time < 0: ~A" beg)) (if (> len 0) (insert-samples start len (samples file-beg len file-name file-channel) snd chn edpos #f (if (string? file-data) (format #f "insert-channel ~S ~A ~A" file-data beg dur) (format #f "insert-channel '~A ~A ~A" file-data beg dur)))))))) ;;; -------- redo-channel, undo-channel (define redo-channel (let ((documentation "(redo-channel (edits 1) snd chn) is the regularized version of redo")) (lambda* ((edits 1) snd chn) (if (and snd (not (= (sync snd) 0)) chn) (set! (edit-position snd chn) (+ (edit-position snd chn) edits)) (redo edits snd))))) (define undo-channel (let ((documentation "(undo-channel (edits 1) snd chn) is the regularized version of undo")) (lambda* ((edits 1) snd chn) (if (and snd (not (= (sync snd) 0)) chn) (set! (edit-position snd chn) (max 0 (- (edit-position snd chn) edits))) (undo edits snd))))) ;;; -------- any-env-channel (define any-env-channel (let ((documentation "(any-env-channel e func (beg 0) dur snd chn edpos origin) takes breakpoints in 'e', \ connects them with 'func', and applies the result as an amplitude envelope to the given channel")) (lambda* (e func (beg 0) dur snd chn edpos origin) ;; handled as a sequence of funcs and scales (if (pair? e) (let ((pts (/ (length e) 2))) (if (= pts 1) (scale-channel (car e) beg dur snd chn edpos) (let ((x0 0) (y0 0) (x1 (car e)) (y1 (cadr e)) (xrange (- (e (- (length e) 2)) (car e))) (ramp-beg beg) (ramp-dur 0)) (if (not (number? dur)) (set! dur (framples snd chn))) (as-one-edit (lambda () (do ((i 1 (+ 1 i)) (j 2 (+ j 2))) ((= i pts)) (set! x0 x1) (set! y0 y1) (set! x1 (e j)) (set! y1 (e (+ 1 j))) (set! ramp-dur (round (* dur (/ (- x1 x0) xrange)))) (if (= y0 y1) (scale-channel y0 ramp-beg ramp-dur snd chn edpos) (func y0 y1 ramp-beg ramp-dur snd chn edpos)) (set! ramp-beg (+ ramp-beg ramp-dur)))) origin)))))))) ;;; -------- sine-ramp sine-env-channel (define sine-ramp (let ((documentation "(sine-ramp rmp0 rmp1 (beg 0) dur snd chn edpos) produces a sinsusoidal connection from rmp0 to rmp1")) (lambda* (rmp0 rmp1 (beg 0) dur snd chn edpos) (let ((len (if (number? dur) dur (- (framples snd chn) beg)))) (let ((data (samples beg len snd chn edpos)) (incr (/ pi len)) (scl (* 0.5 (- rmp1 rmp0)))) (let ((off (+ rmp0 scl))) (do ((i 0 (+ i 1)) (angle (- pi) (+ angle incr))) ((= i len)) (float-vector-set! data i (* (float-vector-ref data i) (+ off (* scl (cos angle))))))) (float-vector->channel data beg len snd chn current-edit-position (format #f "sine-ramp ~A ~A ~A ~A" rmp0 rmp1 beg dur))))))) (define sine-env-channel (let ((documentation "(sine-env-channel e (beg 0) dur snd chn edpos) connects e's dots with sinusoids")) (lambda* (e (beg 0) dur snd chn edpos) (any-env-channel e sine-ramp beg dur snd chn edpos (format #f "sine-env-channel '~A ~A ~A" e beg dur))))) ;;; (sine-env-channel '(0 0 1 1 2 -.5 3 1)) ;;; an obvious extension of this idea is to use the blackman fft window formulas ;;; to get sharper sinusoids (i.e. use the sum of n cosines, rather than just 1) ;;; -------- blackman4-ramp, blackman4-env-channel (define blackman4-ramp (let ((documentation "(blackman4-ramp rmp0 rmp1 (beg 0) dur snd chn edpos) produces a blackman4-shaped envelope")) (lambda* (rmp0 rmp1 (beg 0) dur snd chn edpos) ;; float-vector: angle incr off scl (let ((len (if (number? dur) dur (- (framples snd chn) beg)))) (let ((incr (/ pi len)) (data (samples beg len snd chn edpos)) (coeffs (float-vector-scale! (float-vector 0.084037 -.29145 .375696 -.20762 .041194) (- rmp1 rmp0)))) (float-vector-set! coeffs 0 (+ (float-vector-ref coeffs 0) rmp0)) (do ((i 0 (+ i 1)) (angle 0.0 (+ angle incr))) ((= i len)) (float-vector-set! data i (* (float-vector-ref data i) (polynomial coeffs (cos angle))))) (float-vector->channel data beg len snd chn current-edit-position (format #f "blackman4-ramp ~A ~A ~A ~A" rmp0 rmp1 beg dur))))))) (define blackman4-env-channel (let ((documentation "(blackman4-env-channel e (beg 0) dur snd chn edpos) uses the blackman4 window to connect the dots in 'e'")) (lambda* (e (beg 0) dur snd chn edpos) (any-env-channel e blackman4-ramp beg dur snd chn edpos (format #f "blackman4-env-channel '~A ~A ~A" e beg dur))))) ;;; -------- ramp-squared, env-squared-channel (define ramp-squared (let ((documentation "(ramp-squared rmp0 rmp1 (symmetric #t) (beg 0) dur snd chn edpos) connects rmp0 and rmp1 with an x^2 curve")) (lambda* (rmp0 rmp1 (symmetric #t) (beg 0) dur snd chn edpos) ;; float-vector: start incr off scl (let ((len (if (number? dur) dur (- (framples snd chn) beg)))) (let ((incr (/ 1.0 len)) (data (samples beg len snd chn edpos)) (scl (- rmp1 rmp0))) (if (and symmetric (< rmp1 rmp0)) (begin (set! scl (- scl)) (do ((i 0 (+ i 1)) (angle 1.0 (- angle incr))) ((= i len)) (float-vector-set! data i (* (float-vector-ref data i) (+ rmp1 (* scl angle angle)))))) (do ((i 0 (+ i 1)) (angle 0.0 (+ angle incr))) ((= i len)) (float-vector-set! data i (* (float-vector-ref data i) (+ rmp0 (* scl angle angle)))))) (float-vector->channel data beg len snd chn current-edit-position (format #f "ramp-squared ~A ~A ~A ~A ~A" rmp0 rmp1 symmetric beg dur))))))) (define env-squared-channel (let ((documentation "(env-squared-channel e (symmetric #t) (beg 0) dur snd chn edpos) connects e's dots with x^2 curves")) (lambda* (e (symmetric #t) (beg 0) dur snd chn edpos) (any-env-channel e (lambda (r0 r1 b d s c e) (ramp-squared r0 r1 symmetric b d s c e)) beg dur snd chn edpos (format #f "env-squared-channel '~A ~A ~A ~A" e symmetric beg dur))))) ;;; (env-squared-channel '(0 0 1 1 2 -.5 3 1)) ;;; -------- ramp-expt, env-expt-channel (define ramp-expt (let ((documentation "(ramp-expt rmp0 rmp1 exponent (symmetric #t) (beg 0) dur snd chn edpos) connects rmp0 and rmp1 with an x^exponent curve")) (lambda* (rmp0 rmp1 exponent (symmetric #t) (beg 0) dur snd chn edpos) ;; float-vector: start incr off scl exponent ;; a^x = exp(x * log(a)) (let ((len (if (number? dur) dur (- (framples snd chn) beg)))) (let ((incr (/ 1.0 len)) (data (samples beg len snd chn edpos)) (scl (- rmp1 rmp0))) (if (and symmetric (< rmp1 rmp0)) (begin (set! scl (- scl)) (do ((i 0 (+ i 1)) (angle 1.0 (- angle incr))) ((= i len)) (float-vector-set! data i (* (float-vector-ref data i) (+ rmp1 (* scl (expt angle exponent))))))) (do ((i 0 (+ i 1)) (angle 0.0 (+ angle incr))) ((= i len)) (float-vector-set! data i (* (float-vector-ref data i) (+ rmp0 (* scl (expt angle exponent))))))) (float-vector->channel data beg len snd chn current-edit-position (format #f "ramp-expt ~A ~A ~A ~A ~A ~A" rmp0 rmp1 exponent symmetric beg dur))))))) (define env-expt-channel (let ((documentation "(env-expt-channel e exponent (symmetric #t) (beg 0) dur snd chn edpos) connects e's dots with x^exponent curves")) (lambda* (e exponent (symmetric #t) (beg 0) dur snd chn edpos) (if (= exponent 1.0) (env-channel e beg dur snd chn edpos) (any-env-channel e (lambda (r0 r1 b d s c e) (ramp-expt r0 r1 exponent symmetric b d s c e)) beg dur snd chn edpos (format #f "env-expt-channel '~A ~A ~A ~A ~A" e exponent symmetric beg dur)))))) ;;; -------- offset-channel (define offset-channel (let ((documentation "(offset-channel amount (beg 0) dur snd chn edpos) adds amount to each sample")) (lambda* (dc (beg 0) dur snd chn edpos) (let ((len (if (number? dur) dur (- (framples snd chn) beg)))) (float-vector->channel (float-vector-offset! (samples beg len snd chn edpos) dc) beg len snd chn current-edit-position (format #f "offset-channel ~A ~A ~A" dc beg dur)))))) (define offset-sound (let ((documentation "(offset-sound off beg dur snd) adds 'off' to every sample in 'snd'")) (lambda* (off (beg 0) dur snd) (let ((index (or snd (selected-sound) (car (sounds))))) (if (sound? index) (let ((out-chans (channels index))) (do ((chn 0 (+ 1 chn))) ((= chn out-chans)) (offset-channel off beg dur index chn))) (error 'no-such-sound "offset-sound: no such sound: ~A" snd)))))) ;;; -------- pad-sound (define pad-sound (let ((documentation "(pad-sound beg dur snd) places a block of 'dur' zeros in every channel of 'snd' starting at 'beg'")) (lambda* (beg dur snd) (let ((index (or snd (selected-sound) (car (sounds))))) (if (sound? index) (let ((out-chans (channels index))) (do ((chn 0 (+ 1 chn))) ((= chn out-chans)) (pad-channel beg dur index chn))) (error 'no-such-sound "pad-sound: no such sound: ~A" snd)))))) ;;; -------- dither-channel (define dither-channel (let ((documentation "(dither-channel (amount .00006) (beg 0) dur snd chn edpos) adds amount dither to each sample")) (lambda* ((amount .00006) (beg 0) dur snd chn edpos) (let ((dither (* .5 amount))) (let* ((len (if (number? dur) dur (- (framples snd chn) beg))) (data (samples beg len snd chn edpos))) (do ((i 0 (+ i 1))) ((= i len)) (float-vector-set! data i (+ (float-vector-ref data i) (mus-random dither) (mus-random dither)))) (float-vector->channel data beg len snd chn current-edit-position (format #f "dither-channel ~,8F ~A ~A" amount beg dur))))))) (define dither-sound (let ((documentation "(dither-sound (amount .00006) beg dur snd) adds dithering to every channel of 'snd'")) (lambda* ((amount .00006) (beg 0) dur snd) (let ((index (or snd (selected-sound) (car (sounds))))) (if (sound? index) (let ((out-chans (channels index))) (do ((chn 0 (+ 1 chn))) ((= chn out-chans)) (dither-channel amount beg dur index chn))) (error 'no-such-sound "dither-sound: no such sound: ~A" snd)))))) ;;; -------- contrast-channel (define contrast-channel (let ((documentation "(contrast-channel index (beg 0) dur snd chn edpos) applies contrast enhancement to the sound")) (lambda* (index (beg 0) dur snd chn edpos) (let* ((len (if (number? dur) dur (- (framples snd chn) beg))) (data (samples beg len snd chn edpos))) (do ((i 0 (+ i 1))) ((= i len)) (float-vector-set! data i (contrast-enhancement (float-vector-ref data i) index))) ; (sin (+ (* 0.5 pi y) (* index (sin (* 2.0 pi y)))))))) (float-vector->channel data beg len snd chn current-edit-position (format #f "contrast-channel ~A ~A ~A" index beg dur)))))) (define contrast-sound (let ((documentation "(contrast-sound index beg dur snd) applies contrast-enhancement to every channel of 'snd'")) (lambda* (index (beg 0) dur snd) (let ((ind (or snd (selected-sound) (car (sounds))))) (if (sound? ind) (let ((out-chans (channels ind))) (do ((chn 0 (+ 1 chn))) ((= chn out-chans)) (contrast-channel index beg dur ind chn))) (error 'no-such-sound "contrast-sound: no such sound: ~A" snd)))))) ;;; -------- scale-sound (define scale-sound (let ((documentation "(scale-sound scl beg dur snd) multiplies every sample in 'snd' by 'scl'")) (lambda* (scl (beg 0) dur snd) ;; the slow way: ;; (map-sound (lambda (fr) (frame* fr scl)) beg dur snd)) (let ((index (or snd (selected-sound) (car (sounds))))) (if (sound? index) (let ((out-chans (channels index))) (do ((chn 0 (+ 1 chn))) ((= chn out-chans)) (scale-channel scl beg dur index chn))) (error 'no-such-sound "scale-sound: no such sound: ~A" snd)))))) ;;; -------- normalize-sound (define normalize-sound (let ((documentation "(normalize-sound amp beg dur snd) scales 'snd' to peak amplitude 'amp'")) (lambda* (amp (beg 0) dur snd) (let ((index (or snd (selected-sound) (car (sounds))))) (if (sound? index) (let ((out-chans (channels index)) (mx (apply max (maxamp index #t)))) (do ((chn 0 (+ 1 chn))) ((= chn out-chans)) (scale-channel (/ amp mx) beg dur index chn))) (error 'no-such-sound "normalize-sound: no such sound: ~A" snd)))))) ;;; -------- channels-equal (define channels=? (let ((documentation "(channels=? s1 c1 s2 c2 (diff 0.0)) -> #t if the two channels are the same (within diff) modulo trailing 0's")) (lambda* (snd1 (chn1 0) snd2 (chn2 0) (allowable-difference 0.0)) (or (and (equal? snd1 snd2) (= chn1 chn2)) (let ((mx1 (maxamp snd1 chn1)) (mx2 (maxamp snd1 chn1))) (and (<= (abs (- mx1 mx2)) allowable-difference) (let* ((len1 (framples snd1 chn1)) (len2 (framples snd2 chn2)) (first-longer (>= len1 len2))) (let ((len (if first-longer len1 len2)) (s1 (if first-longer snd1 snd2)) (s2 (if first-longer snd2 snd1)) (c1 (if first-longer chn1 chn2)) (c2 (if first-longer chn2 chn1))) (let ((v0 (channel->float-vector 0 len s1 c1)) (v1 (channel->float-vector 0 len s2 c2))) (<= (float-vector-peak (float-vector-subtract! v0 v1)) allowable-difference)))))))))) (define channels-equal? (let ((documentation "(channels-equal? s1 c1 s2 c2 (diff 0.0)) -> #t if the two channels are the same (within diff)")) (lambda* (snd1 chn1 snd2 chn2 (allowable-difference 0.0)) (let ((len1 (framples snd1 chn1)) (len2 (framples snd2 chn2))) (and (= len1 len2) (channels=? snd1 chn1 snd2 chn2 allowable-difference)))))) ;;; -------- mono->stereo, mono-files->stereo (define mono->stereo (let ((documentation "(mono->stereo new-name snd1 chn1 snd2 chn2) takes the two channels and combines them into a stereo sound 'new-name'")) (lambda (new-name snd1 chn1 snd2 chn2) ;; (mono->stereo "test.snd" 0 0 1 0) (let ((old-ed1 (edit-position snd1 chn1)) (old-ed2 (edit-position snd2 chn2)) (ind (new-sound new-name :channels 2 :srate (srate snd1)))) (swap-channels ind 0 snd1 chn1) (swap-channels ind 1 snd2 chn2) (set! (edit-position snd1 chn1) old-ed1) (set! (edit-position snd2 chn2) old-ed2) ind)))) (define mono-files->stereo (let ((documentation "(mono-files->stereo new-name file1 file2) combines two mono files into the stereo file 'new-name'")) (lambda (new-name chan1-name chan2-name) ;; (mono-files->stereo "test.snd" "oboe.snd" "pistol.snd") (let* ((ind1 (open-sound chan1-name)) (ind2 (open-sound chan2-name)) (ind3 (mono->stereo new-name ind1 0 ind2 0))) (close-sound ind1) (close-sound ind2) ind3)))) (define stereo->mono (let ((documentation "(stereo->mono stereo-sound new-chan1 new-chan2) splits a stereo sound into two mono sounds named 'new-chan1' and 'new-chan2'")) (lambda (orig-snd chan1-name chan2-name) ;; (stereo->mono 0 "hi1.snd" "hi2.snd") (let ((old-ed0 (edit-position orig-snd 0)) (old-ed1 (edit-position orig-snd 1)) (chan1 (new-sound chan1-name :srate (srate orig-snd))) (chan2 (new-sound chan2-name :srate (srate orig-snd)))) (swap-channels orig-snd 0 chan1 0) (swap-channels orig-snd 1 chan2 0) (set! (edit-position orig-snd 0) old-ed0) (set! (edit-position orig-snd 1) old-ed1) (list chan1 chan2))))) snd-16.1/mix.scm0000644000076400007640000004566412616231602011652 0ustar bilbil;;; various mix related functions ;;; ;;; (mix->float-vector mix) return mix data in float-vector ;;; (snap-mix-to-beat) forces dragged mix to end up on a beat ;;; (silence-all-mixes) sets all mix amps to 0.0 ;;; (find-mix sample snd chn) returns the mix at the given sample, or #f ;;; (mix-maxamp mix) maxamp of mix ;;; ;;; mix-click-sets-amp sets up hook functions so that mix click zeros amps, then subsequent click resets to the before-zero value ;;; check-mix-tags tries to move mix tags around to avoid collisions (require snd-env.scm) (provide 'snd-mix.scm) (define tree-for-each (let ((documentation "(tree-for-each func tree) applies func to every leaf of 'tree'")) (lambda (func tree) (cond ((null? tree) ()) ((not (pair? tree)) (func tree)) (else (tree-for-each func (car tree)) (tree-for-each func (cdr tree))))))) (define tree-for-each-reversed (let ((documentation "(tree-for-each-reversed func tree) applies func to every leaf of 'tree' moving in reverse through all the lists")) (lambda (func tree) (define (flatten lst) ;; there's probably a more elegant way to do this (cond ((null? lst) ()) ((pair? lst) (if (pair? (car lst)) (append (flatten (car lst)) (flatten (cdr lst))) (cons (car lst) (flatten (cdr lst))))) (#t lst))) (for-each func (reverse (flatten tree)))))) (define mix-sound (let ((documentation "(mix-sound file start) mixes file (all chans) at start in the currently selected sound.")) (lambda (file start) (mix file start #t)))) (define silence-all-mixes (let ((documentation "(silence-all-mixes) sets all mix amps to 0")) (lambda () (as-one-edit (lambda () (tree-for-each (lambda (id) (set! (mix-amp id) 0.0)) (mixes))))))) (define find-mix (let ((documentation "(find-mix sample snd chn) returns the mix at the given sample, or #f")) (lambda* (samp snd chn) (let ((mix-list (mixes (or snd (selected-sound) (car (sounds))) (or chn (selected-channel snd) 0)))) (call-with-exit (lambda (found-it) (for-each (lambda (n) (if (= (mix-position n) samp) (found-it n))) mix-list) #f)))))) (define (mix->float-vector id) (samples 0 (mix-length id) id)) ;;; 12-Nov-09: moved save-mix to C (snd-mix.c) (define (mix-maxamp id) (float-vector-peak (mix->float-vector id))) ;;; -------- snap dragged mix(es) to the nearest beat (define (snap-mix-1 id samps-moved) (let* ((samp (+ samps-moved (mix-position id))) (snd (car (mix-home id))) (chn (cadr (mix-home id))) (bps (/ (beats-per-minute snd chn) 60.0)) (sr (srate snd)) (beat (floor (/ (* samp bps) sr))) (lower (floor (/ (* beat sr) bps))) (higher (floor (/ (* (+ 1 beat) sr) bps)))) (set! (mix-position id) (if (< (- samp lower) (- higher samp)) (max 0 lower) higher)) #t)) (define snap-mix-to-beat (let ((documentation "(snap-mix-to-beat) forces a dragged mix to end up on a beat (see beats-per-minute). (hook-remove mix-release-hook snap-mix-1) to cancel.")) (lambda () (hook-push mix-release-hook (lambda (hook) (set! (hook 'result) (snap-mix-1 (hook 'id) (hook 'samples)))))))) (define (snap-syncd-mixes-1 id samps-moved) (let* ((samp (+ samps-moved (mix-position id))) (snd (car (mix-home id))) (chn (cadr (mix-home id))) (bps (/ (beats-per-minute snd chn) 60.0)) (sr (srate snd)) (beat (floor (/ (* samp bps) sr))) (lower (floor (/ (* beat sr) bps))) (higher (floor (/ (* (+ 1 beat) sr) bps))) (new-position (if (< (- samp lower) (- higher samp)) (max 0 lower) higher)) (true-samps-moved (- new-position (mix-position id)))) (if (= (sync id) 0) (set! (mix-position id) new-position) (move-mixes (syncd-mixes (sync id)) true-samps-moved)) #t)) (define snap-syncd-mixes-to-beat (let ((documentation "(snap-mix-to-beat) forces a dragged mix to end up on a beat (see beats-per-minute). \ All mixes sync'd to it are also moved the same number of samples. (hook-remove mix-release-hook snap-syncd-mixes-1) to cancel.")) (lambda () (hook-push mix-release-hook (lambda (hook) (set! (hook 'result) (snap-syncd-mixes-1 (hook 'id) (hook 'samples)))))))) ;;; -------- mix-click-sets-amp (define (mix-click-sets-amp) (hook-push mix-click-hook (lambda (hook) (let ((n (hook 'id))) (let ((zeroed (mix-property :zero n))) (if (not zeroed) (begin (set! (mix-property :amp n) (mix-amp n)) (set! (mix-amp n) 0.0) (set! (mix-property :zero n) #t)) (begin (set! (mix-amp n) (mix-property :amp n)) (set! (mix-property :zero n) #f))) (set! (hook 'result) #t)))))) ;(mix-click-sets-amp) ;;; ---------- mix-click-info (define mix-click-info (let ((documentation "(mix-click-info n) is a mix-click-hook function that describes a mix and its properties")) (lambda (n) (help-dialog "Mix Help" (format #f "Mix ~A (sync: ~A):~% position: ~D = ~,3F secs~% length: ~D (~,3F secs)~% in: ~A[~D]~% scaler: ~A~% speed: ~A~% env: ~A~A" (if (mix-name n) (format #f "~S (~A)" (mix-name n) n) (format #f "~A" n)) (mix-sync n) (mix-position n) (* 1.0 (/ (mix-position n) (srate (car (mix-home n))))) (framples n) (* 1.0 (/ (framples n) (srate (car (mix-home n))))) (short-file-name (car (mix-home n))) (cadr (mix-home n)) (mix-amp n) (mix-speed n) (mix-amp-env n) (let ((props (mix-properties n))) (if (pair? props) (format #f "~% properties: '~A" props) "")))) #t))) ;(hook-push mix-click-hook (lambda (hook) (set! (hook 'result) (mix-click-info (hook 'id))))) ;;; -------- mix-name->id (define mix-name->id (let ((documentation "(mix-name->id name) returns the mix associated with 'name'")) (lambda (name) (call-with-exit (lambda (return) (for-each (lambda (snd) (do ((chn 0 (+ 1 chn))) ((= chn (channels snd))) (for-each (lambda (m) (if (and (string? (mix-name m)) (string=? (mix-name m) name)) (return m))) (mixes snd chn)))) (sounds)) 'no-such-mix))))) ;;; ---------------- backwards compatibilty (define delete-mix (let ((documentation "(delete-mix mix) sets the mix's amp to 0.0")) (lambda (id) (set! (mix-amp id) 0.0)))) ;;; -------- mix lists (used to be called "tracks") ;;; ;;; to use these based on a mix-sync setting, use syncd-mixes below: ;;; (scale-mixes (syncd-mixes 2) 2.0) scales all mixes whose mix-sync field is 2 by 2.0. (define scale-mixes (let ((documentation "(scale-mixes mix-list scl) scales the amplitude of each mix in 'mix-list' by 'scl'")) (lambda (mix-list scl) (as-one-edit (lambda () (for-each (lambda (m) (set! (mix-amp m) (* scl (mix-amp m)))) mix-list)))))) (define silence-mixes (let ((documentation "(silence-mixes mix-list) sets the amplitude of each mix in 'mix-list' to 0.0")) (lambda (mix-list) (scale-mixes mix-list 0.0)))) (define move-mixes (let ((documentation "(move-mixes mix-list samps) moves each mix in 'mix-list' by 'samps' samples")) (lambda (mix-list samps) (as-one-edit (lambda () (for-each (lambda (m) (set! (mix-position m) (max 0 (+ (mix-position m) samps)))) mix-list)))))) (define src-mixes (let ((documentation "(src-mixes mix-list sr) multiplies the speed (resampling ratio) of each mix in 'mix-list' by 'sr'")) (lambda (mix-list sr) (if (not (= sr 0.0)) (as-one-edit (lambda () (for-each (lambda (m) (set! (mix-speed m) (* (mix-speed m) sr))) mix-list))))))) (define transpose-mixes (let ((documentation "(transpose-mixes mix-list semitones) transposes each mix in mix-list by semitones")) (lambda (mix-list semitones) (if (not (= semitones 0)) (src-mixes mix-list (expt 2.0 (/ semitones 12.0))))))) (define color-mixes (let ((documentation "(color-mixes mix-list color) sets the tag and waveform color of each mix in 'mix-list' to 'color'")) (lambda (mix-list col) (for-each (lambda (m) (set! (mix-color m) col)) mix-list)))) (define set-mixes-tag-y (let ((documentation "(set-mixes-tag-y mix-list new-y) sets the mix tag vertical position of each mix in 'mix-list' to 'new-y'. The \ position is measured from the top of the graph, so higher tag-y values position the tag lower in the graph. For \ example, if you know the frequency of the mix sound, you can reflect that in the tag height with: \n\n\ \n\ (set! (mix-tag-y mix-id) (round (* 100 (- 1.0 (/ (log (/ freq 40.0)) (* (log 2.0) 7))))))\n")) (lambda (mix-list new-y) (for-each (lambda (m) (set! (mix-tag-y m) new-y)) mix-list)))) (define mixes-maxamp (let ((documentation "(mixes-maxamp mix-list) returns the maximum amplitude of the data in the mixes in 'mix-list'")) (lambda (mix-list) (let ((mx 0.0)) (for-each (lambda (m) (set! mx (max mx (mix-maxamp m)))) mix-list) mx)))) (define scale-tempo (let ((documentation "(scale-tempo mix-list scl) changes the rate at which the mixes in 'mix-list' occur to reflect \ the tempo scaler 'scl'. If 'scl' is 2.0, for example, the mixes are re-positioned so that they \ happen twice as slowly (the data is not resampled -- each mix is untouched except that its begin time \ may change)")) (lambda (mix-list tempo-scl) (let* ((first-beg (mix-position (car mix-list))) (last-beg first-beg)) (for-each (lambda (m) (let ((pos (mix-position m))) (set! first-beg (min first-beg pos)) (set! last-beg (max last-beg pos)))) (cdr mix-list)) (as-one-edit (lambda () (for-each (lambda (m) (let ((diff (round (* tempo-scl (- (mix-position m) first-beg))))) (if (not (= diff 0)) (set! (mix-position m) (+ first-beg diff))))) mix-list))))))) ;;; reverse-mix-list is (scale-tempo mix-list -1.0) (define mixes-length (let ((documentation "(mixes-length mix-list) returns the number of samples between the start of the earliest mix and the \ last end of the mixes in 'mix-list'")) (lambda (mix-list) (+ 1 (- (apply max (map (lambda (m) (+ (mix-position m) (framples m))) mix-list)) (apply min (map mix-position mix-list))))))) (define env-mixes (let ((documentation "(env-mixes mix-list amp-env) applies 'amp-env' as a global amplitude envelope to the mixes in 'mix-list'")) (lambda (mix-list overall-amp-env) (let* ((mix-begs (map mix-position mix-list)) (mix-ends (map (lambda (m) (+ (mix-position m) (framples m))) mix-list)) (beg (apply min mix-begs)) (end (apply max mix-ends)) (first-x (car overall-amp-env)) (last-x (envelope-last-x overall-amp-env)) (x-scale (/ (- last-x first-x) (+ 1 (- end beg))))) (as-one-edit (lambda () (for-each (lambda (m) (let* ((beg-x (+ first-x (* x-scale (- (mix-position m) beg)))) (end-x (+ first-x (* x-scale (- (+ (mix-position m) (framples m)) beg)))) (wenv (window-envelope beg-x end-x overall-amp-env))) (if (null? (mix-amp-env m)) (set! (mix-amp-env m) wenv) (set! (mix-amp-env m) (multiply-envelopes (mix-amp-env m) wenv))))) mix-list))))))) (define sync-all-mixes ;; a replacement for set-all-tracks in snd-8 (let ((documentation "(sync-all-mixes (new-sync 1)) sets the mix-sync field of every active mix to new-sync")) (lambda* ((new-sync 1)) (for-each (lambda (snd-m) (for-each (lambda (chn-m) (for-each (lambda (m) (set! (sync m) new-sync)) chn-m)) snd-m)) (mixes))))) (define syncd-mixes (let ((documentation "(syncd-mixes val) returns a list (possibly null) of all mixes whose mix-sync field is set to 'val'")) (lambda (val) (if (<= val 0) (list) (let ((mix-list ())) (for-each (lambda (snd-m) (for-each (lambda (chn-m) (for-each (lambda (m) (if (= (sync m) val) (set! mix-list (cons m mix-list)))) chn-m)) snd-m)) (mixes)) mix-list))))) (define play-mixes (let ((documentation "(play-mixes mix-list) plays the mixes in 'mix-list'")) (lambda (mix-list) (let* ((sorted-mixes (sort! (copy mix-list) (lambda (a b) (< (mix-position a) (mix-position b))))) (now (mix-position (car sorted-mixes)))) (play (lambda () (while (and (pair? sorted-mixes) (= now (mix-position (car sorted-mixes)))) (play (let ((mx (car sorted-mixes))) (if (integer? mx) (integer->mix mx) mx))) (set! sorted-mixes (cdr sorted-mixes))) (set! now (+ 1 now)) (and (pair? sorted-mixes) 0.0))))))) ;;; -------- pan-mix -------- (define pan-mix (let ((documentation "(pan-mix file start pan-env snd (auto-delete #f)) mixes 'file' into the sound 'snd' starting at 'start' (in samples) using 'pan-env' to decide how to split the sound between the output channels (0: all chan 0, 1: all chan 1). So, (pan-mix \"oboe.snd\" 0 '(0 0 1 1)) goes from all chan 0 to all chan 1. 'auto-delete' determines whether the in-coming file should be treated as a temporary file and deleted when the mix is no longer accessible. pan-mix returns a list of the mixes performing the panning operation.")) (lambda* (name beg pan snd auto-delete) (let* ((index (or snd (selected-sound) (and (sounds) (car (sounds))))) (deletion-choice (if auto-delete 3 0)) ; multichannel deletion case (end-deletion-choice (if (= deletion-choice 3) 4 0))) (if (not (sound? index)) (error 'no-such-sound (list "pan-mix" snd))) (if (not (file-exists? name)) (error 'no-such-file (list "pan-mix" name))) (as-one-edit (lambda () (define (invert-envelope e) (if (null? e) () (append (list (car e) (- 1.0 (cadr e))) (invert-envelope (cddr e))))) (let ((incoming-chans (channels name)) (receiving-chans (channels index))) (if (= incoming-chans 1) ;; mono input (if (= receiving-chans 1) ;; mono to mono = just scale or envelope (let ((idx (mix name beg 0 index 0 *with-mix-tags* auto-delete))) ; file start in-chan snd chn ... (and idx (mix? (car idx)) (let ((id (car idx))) (set! (mix-amp-env id) (invert-envelope pan)) idx))) ;; mono to stereo (let ((idx0 (mix name beg 0 index 0 *with-mix-tags* deletion-choice)) (idx1 (mix name beg 0 index 1 *with-mix-tags* end-deletion-choice))) (and idx0 (mix? (car idx0)) idx1 (mix? (car idx1)) (let ((id0 (car idx0)) (id1 (car idx1))) (set! (mix-amp-env id0) (invert-envelope pan)) (set! (mix-amp-env id1) pan) (list id0 id1))))) ;; stero input (if (= receiving-chans 1) ;; stereo -> mono => scale or envelope both input chans into the output (let ((idx0 (mix name beg 0 index 0 *with-mix-tags* deletion-choice)) (idx1 (mix name beg 1 index 0 *with-mix-tags* end-deletion-choice))) (and idx0 (mix? (car idx0)) idx1 (mix? (car idx1)) (let ((id0 (car idx0)) (id1 (car idx1))) (set! (mix-amp-env id0) (invert-envelope pan)) (set! (mix-amp-env id1) (invert-envelope pan)) (list id0 id1)))) ;; stereo -> stereo => incoming chans are treated equally, each panned into outputs (let ((idx00 (mix name beg 0 index 0 *with-mix-tags* deletion-choice)) (idx01 (mix name beg 0 index 1 *with-mix-tags* deletion-choice)) (idx10 (mix name beg 1 index 0 *with-mix-tags* deletion-choice)) (idx11 (mix name beg 1 index 1 *with-mix-tags* end-deletion-choice))) (and idx00 (mix? (car idx00)) idx01 (mix? (car idx01)) idx10 (mix? (car idx10)) idx11 (mix? (car idx11)) (let ((id00 (car idx00)) (id01 (car idx01)) (id10 (car idx10)) (id11 (car idx11))) (set! (mix-amp-env id00) (invert-envelope pan)) (set! (mix-amp-env id10) (invert-envelope pan)) (set! (mix-amp-env id01) pan) (set! (mix-amp-env id11) pan) (list id00 id01 id10 id11))))))))))))) (define pan-mix-selection (let ((documentation "(pan-mix-selection start pan-env snd) mixes the current selection into the sound 'snd' starting at 'start' (in samples) using 'pan-env' to pan (0: all chan 0, 1: all chan 1).")) (lambda* (beg pan snd) (if (not (selection?)) (error 'no-active-selection (list "pan-mix-selection")) (pan-mix (save-selection (snd-tempnam)) beg pan snd #t))))) (define pan-mix-region (let ((documentation "(pan-mix-region reg start pan-env snd) mixes the given region into the sound 'snd' starting at 'start' (in samples) using 'pan-env' to pan (0: all chan 0, 1: all chan 1).")) (lambda* (reg beg pan snd) (if (not (region? reg)) (error 'no-such-region (list "pan-mix-region" reg)) (pan-mix (save-region reg (snd-tempnam)) beg pan snd #t))))) (define pan-mix-float-vector (let ((documentation "(pan-mix-float-vector v start pan-env snd) mixes the float-vector data into the sound 'snd' starting at 'start' (in samples) using 'pan-env' to pan (0: all chan 0, 1: all chan 1).")) (lambda* (v beg pan snd) (let ((temp-file (snd-tempnam))) (array->file temp-file v (length v) (srate snd) 1) (pan-mix temp-file beg pan snd #t))))) ;;; -------- delay-channel-mixes (define delay-channel-mixes (let ((documentation "(delay-channel-mixes beg dur snd chn) adds dur (which can be negative) to the \ begin time of each mix that starts after beg in the given channel")) (lambda* (beg dur snd chn) (for-each (lambda (m) (if (>= (mix-position m) beg) (set! (mix-position m) (max 0 (+ (mix-position m) dur))))) (mixes (or snd (selected-sound) (car (sounds))) (or chn 0)))))) ;;; -------- check-mix-tags (define check-mix-tags (let ((documentation "(check-mix-tags snd chn) tries to move mix tags around to avoid collisions")) (lambda* (snd chn) (if (not snd) (for-each check-mix-tags (sounds)) (if (not chn) (let ((chns (channels snd))) (do ((i 0 (+ i 1))) ((= i chns)) (check-mix-tags snd i))) (let ((mxs (mixes snd chn)) (changed #f)) (define (check-mix mx trailing-mixes) (if (pair? trailing-mixes) (let ((pos (mix-position mx)) (ls (left-sample snd chn)) (rs (right-sample snd chn))) (if (<= ls pos rs) (let ((x (x->position (/ pos (srate snd)))) (y (mix-tag-y mx))) (for-each (lambda (other-mix) (let ((other-pos (mix-position other-mix))) (if (<= ls other-pos rs) (let ((other-x (x->position (/ other-pos (srate snd)))) (other-y (mix-tag-y other-mix))) (if (and (< (abs (- x other-x)) 6) (< (abs (- y other-y)) 10)) (begin (set! (mix-tag-y other-mix) (+ (mix-tag-y other-mix) 20)) (set! changed #t))))))) trailing-mixes))) (check-mix (car trailing-mixes) (cdr trailing-mixes))))) (check-mix (car mxs) (cdr mxs)) (if changed (update-time-graph snd chn)))))))) snd-16.1/snd.html0000644000076400007640000024144012574565143012026 0ustar bilbil Snd
Snd
Bill Schottstaedt (bil@ccrma.stanford.edu)
standard Snd appearance
title bar File menu Edit menu View menu Options menu Help menu edit history list Y axis zoom Y axis position fft button waveform button graphs graphs graphs X axis position X axis zoom sound file name sound file name status area sync button play button play button play button

Snd is a sound editor modelled loosely after Emacs. It can be customized and extended using either s7 (included in the Snd sources), Ruby, or Forth. Snd is free; the code is available via anonymous ftp as snd-16.tar.gz. Snd has a home page and a CVS repository, and is included in PlanetCCRMA.

Contents
this file:extsnd.html:grfsnd.html:
File Menu Edit Menu View Menu Options Menu Help Menu
Open Undo Open listener Transform Options About Snd
Close Redo Files Control panel options Customization
Save Find Mixes Save session Control panel
Save as Delete selection Regions Preferences Key bindings
Revert Insert selection Color/Orientation Play
Mix Mix Selection Show controls Save
Insert Play Selection Graph style Mix
Update Save Selection Verbose cursor Resample
New Select all With inset graph FFT
View Unselect all Channel style Filter
Print Edit Envelope Show y=0 Reverb
Exit Edit Header X axis units Envelope
Axes Marks
Zoom focus Insert
With grid Delete
Getting started

Once compiled and loaded (see README.Snd for instructions), start Snd, snd some.snd:

basic snd display

where "some.snd" is any available sound file. You should get a window with the first .1 seconds of the sound displayed as a time domain waveform. Click the file name at the lower left to get some information about the file. Click the "f" button, and an fft window appears alongside the waveform. Drag the upper scale at the bottom of the graph and both graphs are updated as you move through the file. Drag the lower scale to zoom in or out. Drag the outer scale (the wider one) on the left to change the y axis bounds. The inner scale moves the y axis up and down. Click the "w" button (unset it) and the time domain waveform goes away. Click "play" to play the file. "sync" is more complicated — it is used to group sounds together for simultaneous editing.

basic snd display

Now return to the time domain form (click "w" and "f"), and click in the graph itself. A red cursor (a big "+") appears at that point. The cursor is just like an Emacs cursor — you can delete the sample at the cursor, for example, by typing control D (abbreviated in this document C-d), or move back one pixel with C-b.

Click and drag the mouse through some portion of the graph — the portion dragged is highlighted in some way. When you release the mouse button, the highlighted portion becomes a 'selection' that you can play, delete, or mix elsewhere. If you place the mouse toward the top of the graph at the selection boundary, the cursor changes to a double-arrow, and you can drag the boundary. There's a triangular area beneath the x axis at the start and end of the selection. Click the left one to play (or stop playing) the selected portion; the right one starts a looping play. The cursor, marks, and mixes also have associated play arrows (triangles).

You'll notice if you make some change to the data that the file name gets an asterisk, as in Emacs, and the various 'undo' and 'redo' menu options come to life. Just for laughs, delete the selection (via the Edit menu), then click the right mouse button to get the popup menu, and try Undo followed by Redo.

basic snd display

Next type C-m. This places a mark at the current cursor location. C-a goes to the start of the window; C-j jumps forward to the next mark. Click and drag the upper horizontal mark portion to move the mark; click the triangular lower portion to play from the mark. If you are editing a multichannel file, control-click the triangle to play all channels together from the mark.

Finally, go to the View menu and select 'Show controls'. A new portion of the Snd window opens, containing a number of controls. Try goofing around with them while playing the sound. For the more complex cases, the button on the right side turns the option on or off.

But this is all standard stuff; even the various dialogs scattered around the menus will present no surprises. The GL spectrograph is somewhat unusual, and I like the paned window approach to multichannel sounds ("de gustibus..."). But it is primarily the embedded extension language (s7, Ruby, or Forth) that makes Snd different from other editors. Everything in Snd from the low-level data readers to the high-level editing operations is tied into the extension language. You can do anything you want with sounds. Rather than try to present endless menus full of canned effects, Snd gives you full programming power over sounds, and you can extend it to include whatever you want. But if you are in a big hurry, or not yet confident in your ability as a programmer, many such operations have been included in the various scm (s7 = Scheme), rb (Ruby), and fs (Forth) files in the Snd tarball. Dave Phillips wrote a set of files that implement dozens of the effects and editing operations built into other editors. Just load the files that look interesting, and start clicking widgets.

basic snd display

Manipulating sounds in a programming environment is most enjoyable if you can edit and retry expressions easily. Old-time Lispers called this special kind of text widget a "listener". There is one in Snd — see the View:Open Listener menu. The listener has a prompt (">") at which you can type any expression: (+ 1 2) which it then evaluates, returning the result. I normally work in the listener, leave the menus untouched, and use the mouse to scan through the current sound data.

The rest of this document describes the user interface; extsnd.html presents the programming interface; grfsnd.html describes Snd's connection to various other programs and X; sndscm.html has brief descriptions of most of the Scheme/Ruby/Forth code included in the Snd tarball; fm.html is an introduction to FM; sndclm.html is the basic generator documentation; sndlib.html describes the underlying sound IO library; s7.html is the s7 documentation.

There are context-sensitive popup menus, and (if you like) a toolbar:

selection popup menu
File operations
File Menu
Open open a new file
Close close a file, flush any unsaved edits
Save save current edits, overwriting previous version
Save as save current edits under a new name, stay in current file
Revert flush edits
Mix mix file
Insert insert file
Update re-read file (data changed behind Snd's back)
View open file read-only
New create a new, empty file
Print produce a Postscript version of current display
Exit leave Snd, flushing all pending edits

When invoked, Snd scans its arguments for file names, and opens any it finds.

snd oboe.snd fyow.snd

If there are no arguments, Snd comes up as a bare menu bar. If a name is preceded by "-p" or "-preload", it is treated as a directory name, and all sound files found in that directory are added to the View:Files list. To load arbitrary Snd customizations (your own code, or a saved state file), precede the file name with "-l" or "-load" (or use the load function).

snd oboe.snd -l examp.scm

opens the sound file oboe.snd and loads the Scheme file examp.scm.

Normally Snd adds each new sound below those currently being displayed. To position sounds horizontally (adding on the right), use the "-h" (or "-horizontal") flag. Other overall layout choices include the Notebook widget (-notebook), and separate windows for each sound (-separate).

Open File dialog

A file can be opened from the File menu via Open or View. View opens the file read-only, whereas Open allows it to be changed. The equivalent keyboard command is C-x C-f. If a file cannot be changed (either it was opened read-only or you don't have write permission for it), a lock appears next to the file name. Similarly, if Snd notices that the file on the disk no longer matches the original, a warning is posted. This can happen if some other program writes a sound while you are editing an earlier version of it. If the variable auto-update is #t (the default is #f), Snd automatically updates any such file.

The file selection dialog is slightly different from the Motif or Gtk default. If you single click in the directory list, that directory is immediately opened and displayed. Also there are a variety of context-sensitive popup menus to handle special chores such as setting the current sort routine (right click over the file list), jump to any higher level directory (right click in the directory list), choose a recently opened file (click in the filename text widget), or return to a previous list of files (click in the filter text widget). The 'sound files only' button filters out all non-sound files from the files list, using the extension; you can add to the list of sound file extensions via add-sound-file-extension. The built-in extensions are "snd", "wav", "aiff", "aif", "au", "aifc", "voc", and "wve". When a sound file is selected, information about it is posted under the lists, and a 'play' button is displayed. The name field has TAB completion, of course, and also watches as you type a new name, reflecting that partial name by moving the file list to display possible matches.

Snd can handle the following file and data types:

read/write (many sample types):

    NeXT/Sun/DEC/AFsp
    AIFF/AIFC
    RIFF (Microsoft wave)
    RF64
    IRCAM (old style)
    NIST-sphere
    CAFF
    no header ("raw")


read-only (in selected sample types):

    8SVX (IFF), EBICSF, INRS, ESPS, SPPACK, ADC (OGI), AVR, VOC, PVF,
    Sound Tools, Turtle Beach SMP, SoundFont 2.0, Sound Designer I, PSION, MAUD, Kurzweil 2000,
    Gravis Ultrasound, ASF, PAF, CSL, Comdisco SPW, Goldwave sample, omf, quicktime, sox,
    Sonic Foundry, SBStudio II, Delusion digital, Digiplayer ST3, Farandole Composer WaveSample,
    Ultratracker WaveSample, Sample Dump exchange, Yamaha SY85, SY99, and TX16, Covox v8, AVI, 
    Impulse tracker, Korg, Akai, Turtle Beach, Matlab-5


automatically translated to a readable format:

    IEEE text, Mus10, SAM 16-bit (modes 1 and 4), AVI, NIST shortpack, HCOM, Intel, 
    IBM, and Oki (Dialogic) ADPCM, G721, G723_24, G723_40, MIDI sample dump, Ogg, Speex, 
    Flac, Midi, Mpeg, Shorten, Wavepack, tta (via external programs)

The files can have any number of channels. Data can be either big or little endian. A 'New' file (one created by the File:New option) can get its type and so on from the default output variables such as default-output-header-type, or from a dialog that pops up when some field has not been set in advance. Similary, a raw data file gets its srate, chans, and sample type information either from the open-raw-sound-hook or from a dialog window that pops up when such a file is opened. The file types listed above as "automatically translated" are decoded upon being opened, translated to some format Snd can read and write, and rewritten as a new file with an added (possibly redundant) extension .snd, and that file is the one the editor sees from then on.

Each file has its own 'pane', a horizontal section of the overall Snd screen space; within that section, each channel has a pane, and below the channels is the 'control pane', normally hidden except for the file name and 'status area'. At the very bottom of the Snd window is the listener, if any (see the View menu Open listener option). The panes can all be independently raised and lowered by dragging the pane buttons on the right. Each channel has the four scrollbars setting what portion of the data is displayed; the 'w' button (normally set) which causes the time domain waveform to be displayed; and the 'f' button (normally unset) which includes the frequency domain (FFT) display. There is a third display settable by user-provided functions; if both the 'w' and 'f' buttons are off and there is no active user-display function, you get an empty display. For each sound there is a control panel containing the file name, in parentheses if the file is actually a link, with an asterisk if there are unsaved edits, a 'status area' for various kinds of simple text-based interactions, a 'sync' button for grouped display and edit operations, a 'unite' button (if the sound has more than one channel), and a 'play' button to play the current (edited) state of the file.

To open a new, empty file, use the File:New option. The default values for the fields can be set by clicking "Reset". These values are default-output-chans, default-output-sample-type, default-output-srate, and default-output-header-type.

To close a file (flushing any unsaved edits), use the File:Close option, or C-x k. This command applies to the currently selected sound.

To save the current edited state of a file, use the Save option (to overwrite the old version of the file), or Save as (to write to a new file, leaving the old file unchanged). The equivalent keyboard command is C-x C-s (save). Normally, if the new file already exists, and it is not currently being edited in Snd, it is silently overwritten. If you try to overwrite a file, and that file has active edits in a different Snd window, you'll be asked for confirmation. If you want Snd to ask before overwriting a file, set the variable ask-before-overwrite to #t. If you edit a write-protected file and try to save the edits, Snd will try to save the edits in a temporary file and will post a warning that the current file can not be overwritten. To extract just one channel of a multichannel file from the Save-as dialog, put the desired channel number (0-based) in the "extract channel" field, then click 'Extract'.

To undo all edits and return to the last saved state of a file, use the Revert option. The edit history is still available, so you can redo all the edits in order by calling Redo repeatedly. There's also a list on the left of each channel pane containing a list of the current edits. You can click anywhere in the list to move to that edit.

edit history list

The Print option opens the Print dialog. You can send the currently active graph directly to a printer, or save it as an encapsulated Postscript file. The default name of this file is "snd.eps"; it can be set via eps-file.

To mix files, see "Mix Files". The Insert option inserts a file at the cursor.

Finally, to exit Snd cleanly (that is, removing any temporary files, and cleaning up some system stuff), use the Exit option. Unsaved edits are silently flushed (but see the function ask-about-unsaved-edits).

The display
View Menu
Show controlsshow the control panel
Open listenershow listener
Mixesmix browser
Regionsa browser to examine the region stack
Filesa browser of interesting files
Color/Orientationa browser for color and viewing-orientation choices
Channel styleseparate, combined or superimposed channels
Graph styleuse dots, lines, filled polygons etc in the data displays
Verbose cursordescribe the current sample every time the cursor moves
Show y=0show or hide the y=0 line
X axis unitsx axis labelled in seconds, samples, percent of total
Zoom focuswhere to focus during zooms
With gridshow a grid in the graph

The sound display can be modified in various ways. Choose View:Graph style:dots to view the sound as dots rather than connected lines (see also dot-size).

Similarly, to show (or hide) the line Y = 0, use the y=0 option. The Region browser is described under Regions. To open the control panel, use Show Controls. To open or close the listener, use Open listener.

The Color/Orientation option activates a window that sets various aspects of the sonogram, spectrogram, and wavogram displays. There are fifteen or so colormaps available along with ways to invert the maps, and scale (darken) them differently according to screen or printer characteristics.

The Popup menu's Info dialog can be left in view and updated with M-v i to reflect the currently active sound. The same information is displayed in the status area when you click the file name.

In the Motif version of Snd, the View Files option starts a dialog with a list of interesting files, controls for amplitude, speed (sampling rate change), and amplitude envelope, and buttons to mix, insert, or open the selected files. This dialog is sort of a combination of the File:Mix and View:Mixes dialog, aimed at making it easy to toss together bunches of sound files. In the file list, the button on the left plays the file. Single-click a file name to select it; double-click a file name to open it in Snd. The 'update' button runs through the file list checking for files that have been deleted or moved behind Snd's back. 'sort' is a drop-down menu of file sorting possibilities. You can add to this list either by dragging file icons around the screen (which I think is a very awkward thing to do), or by calling add-file-sorter and friends, or by typing the file or directory name in the 'add:' text widget.

View:Files dialog

Files can be added to the list at startup via the -p switch, and with the functions add-file-to-view-files-list and add-directory-to-view-files-list. The 'Mix' button mixes in the currently selected sound, and 'Insert' inserts it. See nb.scm for an extension of this dialog that posts various kinds of information about each file as the mouse passes over it.

The Regions and Mix Dialog options are described below.

Other options
Options Menu
Transform optionsvarious transform (FFT, etc) choices
Control panel optionsset variables that affect the control panel processing
Save sessionsave current state
Preferencescustomize Snd

Transform Options applies mainly to the FFT display triggered by setting the 'f' button in the channel window. The dialog that is launched by this menu item has six sections: on the upper left is a list of available transform types; next on the right is a list of fft sizes; next is a panel of buttons that sets various display-oriented choices; the lower left panel sets the current wavelet, when relevant; next is the fft data window choice; and next to it is a graph of the current fft window with the spectrum of that window in blue. When the window has an associated parameter (sometimes known as "alpha" or "beta"), the slider beneath the window list is highlighted and can be used to choose the desired member of that family of windows.

transform dialog

The FFT is taken from the start (the left edge) of the current window and is updated as the window bounds change. If you'd like the fft size to reflect the current time domain window size:

(hook-push graph-hook
  (lambda (hook)
    ;; check that we are displaying an FFT, 
    ;; if so, set the FFT size to reflect the graph boundaries
    (if (and (transform-graph?) 
             (= (transform-graph-type) graph-once))
        (let ((size (expt 2 (ceiling (log (+ 1.0 (- (right-sample) (left-sample))) 2.0)))))
          (if (not (= size (transform-size)))
              (set! (transform-size) size))))))

The fft data is scaled to fit between 0.0 and 1.0 unless transform normalization is off. The full frequency axis is normally displayed, but the axis is draggable — put the mouse on the axis and drag it either way to change the range (this is equivalent to changing the variable spectrum-end). You can also click on any point in the fft to get the associated fft value at that point displayed; if with-verbose-cursor is on, you can drag the mouse through the fft display and the description in the status area will be constantly updated.

The transform is normally the Fourier Transform, but others are available, including about 20 wavelet choices, and autocorrelation.

The top three buttons in the transform dialog choose between a normal fft, a sonogram, or a spectrogram. The peaks button affects whether peak info is displayed alongside the graph of the spectrum. The dB button selects between a linear and logarithmic Y (magnitude) axis. The log freq button makes a similar choice along the frequency axis.

The easiest way to change the colormap and graph orientation of the spectrogram, wavogram, and sonogram, is to use the Color/Orientation dialog from the View menu. The keypad keys are mapped to various variables as follows:

variable        increase        decrease
spectro-hop      Add (+)        Subtract (-)
transform-size   Multiply (*)   Divide (/)
dot-size         Delete         Insert

The keypad Enter key resets all the spectrogram variables to their default values. The keypad arrow keys zoom and move the fft spectrum.

picture of sonogram

If your time domain data can be viewed as a series of slices through a 3-D landscape, you can use the "wavogram" to mimic the spectrogram in the time domain. The first trace is at the bottom of the graph, moving from left to right. The same rotation commands apply to this display, with the additional variable wavo-hop which sets the density of the traces. To get this display (set! (time-graph-type) graph-as-wavogram). It is important to set the length of each trace so that successive peaks line up. The trace length in samples is set by the variable wavo-trace, or the numeric keypad + and - keys.

wavogram of oboe

The Zoom style option chooses which graph point to center on during an x-axis zoom. The default is to zoom onto the cursor or the beginning of the current selection if either is visible. You can also have zoom focus on the left edge, right edge, or midpoint of the current window.

The Preferences dialog tries to make it easier to set up Snd initially. It is a GUI-based way to write your initialization file. Most of the global variables are included, and a number of ancillary functions that seem to be popular. It's not yet completed, but more than 100 topics are currently included — a good start! To get more help on a particular topic, scroll horizontally to the list of topic names on the far right, and click on the one you're interested in. If you leave the help dialog active, it becomes a sort of tooltip — if you linger over some other topic, its help info will be posted in the help dialog.

preferences dialog
Edit operations
Edit Menu
UndoUndo last edit
RedoRedo last edit
FindGlobal search via find dialog
CutCut (delete) selected portion
PastePaste (insert) selected portion
Mix selectionMix (add) selected portion
Play selectionPlay selected portion
Save selectionSave selected portion as file
Select allselect entire file
Unselect allunselect everything
Edit EnvelopeEdit or view envelopes
Edit HeaderEdit or view file header

Editing in Snd is modelled after Emacs in many regards. Each channel has a cursor (a big "+"), a set of marks, and a list of edits that have not yet been saved. Most operations take place at the cursor. Operations can be applied simultaneously to any other channels or sounds by using the 'sync' button. Operations can be applied either to a sample, a selected portion, a channel, a sound, or any number of sounds at the same time. Where an operation has an obvious analog in text editing, I've tried to use the associated Emacs command. To delete the sample at the cursor, for example, use C-d.

The following sections describe how to move the cursor and the window; how to change which channel is active; how to use marks and regions; how to perform various common editing operations. It ends with a description of all the mouse and keyboard editing commands. The 'control panel' provides more complex editing operations, but has a chapter to itself.

The active channel and cursor

Click in the time domain waveform to activate the cursor and select that channel. To make the selected channel stand out from the rest, set the selected-data-color or the selected-graph-color:

(define beige (make-color 0.96 0.96 0.86))
(define blue (make-color 0 0 1))
(set! (selected-graph-color) beige)
(set! (selected-data-color) blue)

The selected channel receives keyboard commands. You can also move between windows with C-x o.

Moving the cursor

Any mouse click on the waveform causes the cursor to move to that point. "The cursor" here refers to the sample cursor, normally a big "+". There is also the cursor associated with the mouse which is a slanting arrow outside the graph, but changes to a small "+" inside the graph. When the mouse is hovering over something that can be dragged (a selection edge, a mark, a mix, etc), it changes to a double arrow. When a mouse click will start sound playing, it becomes a right arrow. And when it's over the selection loop-play triangle, it's a left arrow. But the main cursor in Snd is the big "+" that marks a particular sample. To move it from the keyboard, use:

<      move cursor to sample 0
>      move cursor to last sample
C-<    move cursor to sample 0
C->    move cursor to last sample

C-a    move cursor to window start
C-e    move cursor to window end
C-b    move cursor back one pixel
C-f    move cursor ahead one pixel or n samples

C-n    move cursor ahead one 'line'
C-p    move cursor back one 'line'
C-v    move cursor to mid-window

C-i    display cursor info
C-j    go to mark

All keyboard commands accept numerical arguments, as in Emacs. If the argument is a float, it is multiplied by the sampling rate before being applied to the command, so C-u 2.1 C-f moves the cursor forward 2.1 seconds in the data.

Moving the window

The simplest way to move the window (the portion of the data in the current graph) is to drag the scrollbars with the mouse. The darker scrollbars zoom in and out; the lighter bars move the window along the x or y axis. To move by a single window, click the arrows on the scrollbar. To move by smaller amounts, use the left and right arrow keys (or zoom with the up and down arrow keys); the control, shift, and meta keys are multipliers on this movement — each key adds a factor of .5 to the multiple, so to move by .25 windows, press control, meta, left (or right) arrow. A similar mechanism can be used to zoom quickly onto a particular point; hold the keys and click the mouse in the waveform and you'll zoom an increasing amount into the data at that point.

Various keyboard commands provide much more precise control of the window bounds and placement:

C-l          position window so cursor is in the middle
C-x b        position window so cursor is on left margin
C-x f        position window so cursor is on right margin
[Down]       zoom out, amount depends on shift, control, and meta
[Up]         zoom in
[Left]       move window left
[Right]      move window right
C-x l        position selection in mid-view
C-x v        position window over current selection
C-x C-b      set x window bounds (preceded by number of leftmost sample)
C-x C-p      set window size (preceded by size as numeric argument)

As in most other cases, the sample numbers (or sizes) can be floats; if the argument is not an integer, it is multiplied by the sampling rate before being applied to the command. So, C-u .1 C-x C-p makes the window display .1 seconds of data. If you'd like far more precise window moving and zooming control, see move-one-pixel and zoom-one-pixel.

Marks

A 'mark' marks a particular sample in a sound (not a position in that sound). If we mark a sample, then delete 100 samples before it, the mark follows the sample, changing its current position in the data. If we delete the sample, the mark is also deleted; a subsequent undo that returns the sample also returns its associated mark. I'm not sure this is the right thing, but it's a lot less stupid than marking a position.

Once set, a mark can be moved by dragging the horizontal tab at the top. Control-click of the tab followed by mouse drag will drag the underlying data too, either inserting zeros or deleting data. Click on the triangle at the bottom to play (or stop playing) from the mark.

A mark can be named or unnamed. It it has a name, it is displayed above the horizontal tab at the top of the window. As with sounds and mixes, marks can be grouped together through the sync field; marks sharing the same sync value (other than 0) will move together when one is moved, and so on. See the marks chapter for a further discussion of synced marks. The following keyboard commands relate to marks:

C-m       place (or remove if argument negative) mark at cursor
C-M       place syncd marks at all currently syncd chan cursors
C-x /     place named mark at cursor
C-x C-m   add named mark

C-j       go to mark

The distance from the cursor to a mark can be used as a numeric argument for other commands by following C-u with C-m. Any number in-between is the number of marks to jump forward before getting the distance.

The function save-marks saves the current marks in a file.

Regions

A region is a portion of the sound data. Although I'm not completely consistent in this document, the word "selection" is used to refer to the currently selected (and highlighted) portion of the data; an operation such as filter-selection affects the underlying data. A "region" on the other hand, refers to the saved (copied) version of (the original form of) that data that can be inserted or mixed elsewhere. That is, when a portion is selected, it is (by default) saved as the new region; subsequent edits will not affect the region data. You can disable the region creation by setting the variable selection-creates-region to #f (its default is #t which can slow down editing of very large sounds). Regions can be defined by make-region, by dragging the mouse through a portion of the data, or via the Select All menu option. If the mouse drags off the end of the graph, the x axis moves, in a sense dragging the data along to try to keep up with the mouse; the further away the mouse is from the display, the faster the axis moves. (One minor caveat: if you drag the mouse too quickly off the end of the graph, making a grand sweeping gesture, the last portion of the graph may be missed because the mouse updates are coalesced by X; move deliberately as you near the end of the sound). In large sounds, the mouse granularity can be large, but you can zoom onto the start or end of the selected portion and move them using selection-position and selection-framples. A region can also be defined with keyboard commands, much as in Emacs. C-[space] starts the region definition and the various cursor moving commands continue the definition.

Once defined, the copied region is added to a list of currently available regions (the maximum list size is normally 16 — see max-regions). The currently available regions can be view from the View menu's Region browser:

picture of region browser

'play' plays the region. The graphical display shows the waveform with arrows to move around in the channels of multichannel regions. If you double click the region entry, it loads the region into the main editor as a temporary file. It can be edited or renamed, etc. If you save the file, the region is updated to reflect any edits you made.

The keyboard commands that apply to regions are:

C-y         paste in current selection at cursor
C-[space]   start keyboard-based selection definition
C-x c       define selection from cursor to mark
C-x p       play selection or region
C-x q       mix in selection
C-x l       position selection in mid-view
C-x v       position window over current selection

If the current selection is active (displayed somewhere in the current time domain displays), there are lots of functions that can edit that portion of the current sounds. If the 'selection' button is set in the transform options dialog, (or equivalently, show-selection-transform is #t), the fft display, if any, displays the transform of the selected portion.

The edit list

The current state of the undo/redo list can be viewed as a scrolled list of strings in the pane on the left of the graph. If there are no current edits, it just lists the associated file name (i.e. the zero-edits state). As you edit the sound, the operations appear in the edit list window. Click on a member of the list to move to that point in the edit list (equivalent to some number of undo's or redo's).

The function save-edit-history saves the current edit list as a loadable program (assuming the base sounds haven't changed in the meantime). The file can be edited (it's just a text file with comments). See Edit Lists for more details.

How to ...
Save, open, close, print

Most of these kinds of operations are accessible from the File menu:

save as dialog

They can also be invoked from the keyboard:

C-x k     close currently selected file
C-x C-f   open file 
C-x C-s   save file
C-x C-w   save currently selected channel as file

The Print command produces a PostScript file which can be sent to directly a printer or saved for later use.

Delete, insert, mix

The fastest way to delete a section is to drag the mouse through it and call the Edit menu's Delete selection option. The current selection can be pasted in by clicking the middle mouse button. The associated keyboard commands are:

C-d      delete sample at cursor
C-h      delete previous sample
C-k      delete a 'line' — 128 samples
C-w      delete current selected portion
C-o      insert a zero sample at cursor
C-y      paste in current selection at cursor
C-x q    mix in region (arg = region number)
C-x C-q  mix in file

The File:Insert menu option inserts a sound file at the cursor, and the Edit:Insert Selection menu option does the same with the current selection.

Multichannel operations

Normally each operation applies only to the currently active channel. If, however, the sound's 'sync' button is set, the operations apply to every sound or channel that also has the sync field set to the same value. If you click the 'sync' button, its value is 1 and its color is blue; C-click gives 2 and green, C-M-click gives 3 and yellow; C-M-Shift-click gives 4 and red; any other value (set via the syncing function) shows as a black button. The point of all this is that only those sounds that share the sync value of the current sound are considered to be sync'd to it; for example, to make a stereo selection in one file, then paste it into some other stereo file, set the sync buttons in each sound, but use different values; that way, the channels within each sound are sync'd together (giving stereo operations), but the sounds themselves are separate.

A multichannel sound also has a 'unite' button to the left of the 'sync' button. If this button is set, all channels are displayed in one graph; the x and y-axis scrollbars apply to all the channels at once, as do the 'f' and 'w' buttons; two new scrollbars appear on the right of the window; the furthest right scrollbar affects the placement of the window within the overall set of graphs, and the scrollbar on its left zooms in and out of the overall graph. For stereo files, this is user-interface overkill, but the hope is to accommodate sounds with many channels. The View menu Channel style option has the same effect but applies to all active multichannel sounds. Control-click the unite button to get superimposed channels. If the channels are not combined (the default), control-click the 'f' or 'w' button in one channel to affect all channels at once.

The superimposed channels display is not very useful if you're trying to edit the sound; it's aimed more at FFT comparisons and so on.

To get multichannel selections, set the sync button, then define the selection (by dragging the mouse) in one channel, and the parallel portions of the other channels will also be selected.

Amplitude envelopes and scaling

An envelope in Snd is a list of x y break-point pairs. The x axis range is arbitrary. To define a triangle curve: '(0 0 1 1 2 0). There is no preset limit on the number of breakpoints. Envelopes can be defined with define and referred to thereafter by name. Use the envelope editor to draw envelopes with the mouse.

To scale a file or selection by or to some amplitude, use the functions:

scale-by args
scale-to args
scale-selection-by args
scale-selection-to args

scale-by scales the current sync'd channels by its arguments, and scale-to scales them to its arguments (a normalization). The arguments in each case are either a list of floats corresponding to each successive member of the current set of sync'd channels, or just one argument. In the latter case, scale-by uses that scaler for all its channels, and scale-to normalizes all the channels together so that the loudest reaches that amplitude (that is, (scale-to .5) when applied to a stereo file means that both channels are scaled by the same amount so that the loudest point in the file becomes .5). There's one special case here: if you (scale-to 1.0) in a sound that is stored as short ints and you haven't set the clipping variable to #t, since 1.0 itself is not representable, the actual scaled-to value is just less than 1.0 to avoid the (unwanted) wrap-around.

Searches in Snd refer to the sound data, and are, in general, patterned after Emacs. When you type C-s, the find dialog is activated. The expression it asks for is a function that takes one argument, the current sample value, and returns #t when it finds a match. To look for the next sample that is greater than .1, (lambda (y) (> y .1)). The cursor then moves to the next such sample, if any. Successive C-s's repeat the search. These searching functions can be closures; the following searches for the next positive-going zero crossing, placing the cursor just before it:

(define (zero+)
  ;; return a closure to search for positive-going zero crossing.	
  (let ((lastn 0.0))
    (lambda (n)
      (let ((rtn (and (< lastn 0.0)
		      (>= n 0.0)
		      -1)))
	(set! lastn n)
	rtn))))

Now C-s (zero+) followed by C-s's moves to successive zero crossings. There are more examples in sndscm.html.

Change samples

The simplest changes are:

C-z       set current sample to zero
C-x C-z   smooth data using cosine (smooth-sound)

(set! (sample (cursor)) .1) sets the sample at the cursor to .1. To set several samples to zero, use C-u <number> C-z.

Undo, redo, revert

Snd supports 'unlimited undo' in the sense that you can move back and forth in the list of edits without any limit on how long that list can get. The data displayed is always the edited form thereof. Each editing operation extends the current edit list; each undo backs up in that list, and each redo moves forward in the list of previously un-done edits. Besides the Edit and Popup menu options, there are these keyboard commands:

C-x r     redo last edit
C-x u     undo last edit
C-x C-r   redo last edit
C-x C-u   undo last edit
C-_       undo last edit

Revert is the same as undoing all edits.

To play a sound, click the 'play' button. If the sound has more channels than your DAC(s), Snd will (normally) try to mix the extra channels into the available DAC outputs. While it is playing, you can click the button again to stop it, or click some other file's 'play' button to mix it into the current set of sounds being played. To play from a particular point, set a mark there, then click its 'play triangle' (the triangular portion below the x axis). (Use control-click here to play all channels from the mark point). To play simultaneously from an arbitrary group of start points (possibly spread among many sounds), set syncd marks at the start points, then click the play triangle of one of them. The Edit menu 'Play' option plays the current selection, if any. And the region and file browsers provide play buttons for each of the listed regions or files. If you hold down the control key when you click 'play', the cursor follows along as the sound is played. If 'verbose cursor' is on, the time is also displayed in the status area. If you stop the play in progress, the cursor remains where you stopped it, but otherwise returns to its original position. Type space (without control) to pause and continue during playback. The color of the play button corresponds to the state of the playback: normal: not playing, blue: playing, green: playing and tracking with the cursor (if any), red: playback paused.

If you're getting interruptions while playing a sound (stereo 44.1 kHz sounds can be problematic), try using a very large dac buffer. Use set! to change this: (set! (dac-size) 65536). If you're getting clicks in Linux despite a large dac-size, try setting the OSS fragment sizes by hand: (mus-oss-set-buffers fragments fragment-size). OSS's defaults are 16 and 12 which make the control panel controls very sluggish. Snd used to default to 4 and 12, but this seems to cause trouble for a variety of new sound cards. My initialization file uses (mus-oss-set-buffers 2 12).

The keyboard commands for playing are:

C-q or space   play current channel starting at the cursor
C-t            stop playing
C-x p          play region (numeric arg selects region)

In a multichannel file, C-q plays all channels from the current channel's cursor if the sync button is on, and otherwise plays only the current channel. While playing, space pauses playback or resumes it. Except in the browsers, what is actually played depends on the control panel. Both C-q and C-x p allow overlapped plays; that is, if you type C-q several times in succession, you'll hear several simultaneous renditions of the sound. The various 'play' buttons scattered around Snd on the other hand, interrupt the current play if you click them during a run. C-g stops any current playing. If no numeric argument is supplied, C-x p plays the currently active selection.

Mix Files

Mixing (adding, not multiplying by a sinusoid) is the most common editing operation performed on sounds, so there is relatively elaborate support for it in Snd. To mix in a file, use the File Mix menu option, the command C-x C-q, drag-and-drop it into its new home, or use one of the many mixing functions. Currently the only difference between the first two is that the Mix menu option tries to take the current sync state into account, whereas the C-x C-q command does not. To mix a selection, use C-x q. In drag-and-drop, the mix starts at the mouse location; in the other cases, the default is usually to start at the current cursor location. The mixed-in sound is displayed as a separate waveform above the main waveform with a tag at the beginning. You can drag the tag to reposition the mix. The amplitude, amplitude envelope, and speed (resampling rate) of the mixed-in portion can be changed independently of anything else either through such functions as mix-amp, or through the View:Mix Dialog.

mix tags

The function make-sound-box produces a container with each sound represented by an icon; you can drag-and-drop the icon to the place where you want it mixed, or drop it on the main menubar to open it.

The Mix dialog

The Mix Dialog (click a mix tag, or click Mixes in the View Menu) provides various commonly-used controls on the currently chosen mix.

mix dialog

At the top are the mix id (an integer), its begin and end times, and a play button for the mix. Beneath that are various sliders controlling the speed (resampling rate) and amplitude of the mix, and beneath that an envelope editor for the mix's amplitude envelope. The current mix amp env is not actually changed until you click 'Apply Env'. The editor envelope is drawn in black with dots whereas the current mix amp env (if any) is drawn in blue. If the mix's sync field is not 0, any other mixes that share that sync field are edited in parallel with the current one.

Change file format

To change the sound file's header or sample type, use the File or Edit menu Save as option. Choose the header type you want, then the sample type, (the sample type list will change depending on the header choice). The File:Save dialog saves the currently selected sound. The Edit:Save dialog saves the selection in a new file.

Extend a File

The easiest way to extend the file is to pad it with zeros. Go to the end of the file, via the C-> command, then use the C-u command with a float argument, giving the number of seconds to add to the end of the file, followed by C-o (insert zeros): to add a second, C-> C-u 1.0 C-o. The same sequence can be used to add silence to the start of a file. Functions such as insert-sound automatically pad with zeros, if necessary.

Edit or View an Envelope
picture of envelope editor

The Edit Envelope dialog (under the Edit menu) opens a window for viewing and editing envelopes. The dialog has a display showing either the envelope currently being edited or a panorama of all currently loaded envelopes. The current envelope can be edited with the mouse: click at some spot in the graph to place a new breakpoint, drag an existing breakpoint to change its position, and click an existing breakpoint to delete it. The Undo and Redo buttons can be used to move around in the list of envelope edits; the current state of the envelope can be defined in the extension language (and added to the envelope list on the left) with the 'define it' button. Envelopes can also be loaded from a separate file of envelope definitions via load:

(define-envelope ramp '(0 0 1 1))
(define-envelope pyramid '(0 0 1 1 2 0))

This defines two envelopes that can be used in Snd wherever an envelope is needed. You can also define a new envelope in the dialog's text field; for example, '(0 0 1 1) followed by return creates a ramp.

In the overall view of envelopes, click one, or click its name in the scrolled list on the left to select it; click the selected envelope to load it into the editor portion, clearing out whatever was previously there. To load an existing envelope into the editor, you can also type its name in the text field; to give a name to the envelope as it is currently defined in the graph viewer, type its name in this field, then either hit return or the 'define it' button.

Once you have an envelope in the editor, you can apply it to the current sounds with the 'Apply' or 'Undo&Apply' buttons; the latter first tries to undo the previous edit, then applies the envelope. The envelope can be applied to the amplitude, the spectrum, or the sampling rate. The choice is made via the three buttons marked 'amp', 'flt', and 'src'. The filter order is the variable enved-filter-order which defaults to 40. To use fft-filtering (convolution) instead, click the "fir" button, changing its label to "fft". If you are displaying the fft graph of the current channel, and the fft is large enough to include the entire sound, and the 'wave' button is set, the spectrum is also displayed in the envelope editor, making it easier to perform accurate (fussy?) filtering operations.

To apply the envelope to the current selection, rather than the current sound, set the 'selection' button. To apply it to the currently selected mix, set the 'mix' button. Control-click 'mix' to load the current mix amplitude envelope into the editor.

The two toggle buttons at the lower right choose whether to show a light-colored version of the currently active sound (the 'wave' button), and whether to clip mouse movement at the current y axis bounds (the 'clip' button). The 'linear' and 'exp' buttons choose the type of connecting lines, and the 'exp base' slider at the bottom sets the 'base' of the exponential curves, just as in CLM. If the envelope is being treated as a spectrum ('flt' is selected), the 'wave' button shows the actual frequency response of the filter that will be applied to the waveform by the 'apply' buttons. Increase the enved-filter-order to improve the fit. In this case, the X axis goes from 0 Hz to half the sampling rate, labelled as "1.0".

Edit, add, or remove the header
edit header dialog

The Edit menu's Edit Header option starts a dialog to edit, add, or remove the sound's header. No change is made to the actual sound data; the new header is blindly written out; any unsaved edits are ignored. If you specify 'raw' as the type, any existing header is removed. This dialog is aimed at adding or removing an entire header, or editing the header comments; anything else is obviously dangerous. If you don't change the data location, it will be updated to reflect any header changes; that is, unless you intervene, the resultant header will be syntactically correct. After writing the new header, you should either close or update the associated sound.

Save session

At any time you can save the current state of Snd by calling (save-state name) where name is a file name. You can restart the saved session by calling Snd with this file name and the "-l" switch: snd -l name. This file is in exactly the same format as the initialization file, and can be edited, renamed, or whatever. To load such a file after startup, (load name).

Center a tiny signal with DC

Due to the quantized nature of the y-axis position scroller, a tiny signal that is not centered on 0 can be a pain to position in the window. Use the y-bounds function to set the y axis bounds to some small number, then use the position scroller to find the signal. For example, if your signal is a very soft recording setting only the lowest two bits of a 16 bit signal but with DC offset due to the recording conditions, (set! (y-bounds) '(-.01 .01)) and try the scroller.

Miscellaneous commands

C-g at any point aborts the current keyboard command sequence, as does any mouse click. C-g can also interrupt most long computations (search, eval expression, and the various envelope applications). If you notice one that is not interruptible, send me a note — I probably just forgot about it.

C-u introduces a numeric argument. Besides the integer and float cases mentioned several times above, you can also use marks to set the argument. If the (optional) number after C-u is followed by C-m, the resultant number passed to the command is the distance (in samples) from the cursor to the n-th successive mark. That is C-u C-m C-f is the same as C-j.

C-x introduces an 'extended command'. It can be preceded by a numeric argument or aborted with C-g. C-x halts any on-going region definition.

C-x C-c closes the control panel. C-x C-o opens the panel.

To change a key binding, use bind-key.

As in Emacs or Tcsh, the Tab key in a text field invokes a context-sensitive completion function that tries to figure out what the rest of the text probably should be. If it finds no matches, the text flashes red; if it finds multiple matches and can't extend the current text, it flashes green. In the listener, the choices are displayed in a scrolled list; the up and down arrow keys can move the selection, carriage-return accepts the current selection, mouse click on any item accepts it, and any other character removes the list.

The control panel

The control panel is the portion of each sound's pane beneath the channel graphs.

picture of Snd control panel

The controls are: amp, speed, expand, contrast, reverb, and filter.

'Speed' here refers to the rate at which the sound data is consumed during playback. Another term might be 'srate'. The arrow button on the right determines the direction Snd moves through the data. The scroll bar position is normally interpreted as a float between .05 and 20.

'Expand' refers to granular synthesis used to change the tempo of events in the sound without changing pitch. Successive short slices of the file are overlapped with the difference in size between the input and output hops (between successive slices) giving the change in tempo. This doesn't work in all files — it sometimes sounds like execrable reverb or is too buzzy — but it certainly is more robust than the phase vocoder approach to the same problem. The best quality time expansion comes from rubber-sound in rubber.scm, but unfortunately it only works on well-behaved sounds. The expander is on only if the expand button is set.

The reverberator is a version of Michael McNabb's Nrev. In addition to the controls in the control pane, you can set the reverb feedback gain and the coefficient of the lowpass filter in the allpass bank (see below). The reverb is on only if the reverb button is set. The reverb length field takes effect only when the reverb is set up (when the DAC is started by clicking 'play' when nothing else is being played).

'Contrast enhancement' is my name for a somewhat weird waveshaper or compander. It phase-modulates a sound, which can in some cases make it sound sharper or brighter. For softer sounds, it causes only an amplitude change. To scale a soft sound up before being 'contrasted', use the variable contrast-control-amp. The function maxamp returns the channel's maximum amplitude, so the inverse of that is a good first guess for contrast-control-amp. Contrast is on only if the contrast button is set.

The filter is an arbitrary (even) order FIR filter specified by giving the frequency response envelope and filter order in the text windows provided. The envelope X axis goes from 0 to half the sampling rate — see filter-control-in-hz. If you raise the control pane from its default height, a graph is revealed beneath the filter text field; this is an envelope editor like the envelope editor dialog but specialized for filtering. The actual frequency response (given the current filter order) is displayed in blue. As with all the user interface text entry widgets, anything you type in the filter envelope text field is evaluated, returning in this case a list of breakpoints; you can define a function that returns the list you want, then call that function in the text field. The filter is on only if the filter button is set.

There are many variables that reflect or control the panel's various sliders; each also has a default value. The reverb and expand functions also have several aspects that aren't brought out to sliders or buttons on the panel, but that can be accessed through these variables. See the control panel section for details.

To take the current panel settings and turn them into an edit of the sound, call apply-controls. This may change the length of the file; for example, if reverb is on, the reverb decay length is added onto the end. Once apply-controls has taken effect, the controls section is reset to its clean state (so a subsequent 'play' plays the unmodified newly edited version).

The keyboard commands associated with the control panel are:

C-x C-o   show ("open") control panel
C-x C-c   hide ("close") control panel
Customization and extension

For information on the extension language functions, see extsnd.html. For information on initialization, configuration, and connections to other programs, see grfsnd.html.

snd-16.1/clm.c0000644000076400007640000151761512623170515011274 0ustar bilbil/* CLM (Music V) implementation */ #include "mus-config.h" #if USE_SND #include "snd.h" #endif #include #include #include #include #include #include #include #ifndef _MSC_VER #include #else #include #pragma warning(disable: 4244) #endif #include "_sndlib.h" #include "clm.h" #include "clm-strings.h" #if HAVE_GSL #include #include #endif #if HAVE_FFTW3 #include #endif #if HAVE_COMPLEX_TRIG #include #endif #if (!DISABLE_SINCOS) && defined(__GNUC__) && defined(__linux__) #define HAVE_SINCOS 1 void sincos(double x, double *sin, double *cos); #else #define HAVE_SINCOS 0 #endif #ifndef TWO_PI #define TWO_PI (2.0 * M_PI) #endif struct mus_any_class { int type; char *name; void (*release)(mus_any *ptr); char *(*describe)(mus_any *ptr); /* caller should free the string */ bool (*equalp)(mus_any *gen1, mus_any *gen2); mus_float_t *(*data)(mus_any *ptr); mus_float_t *(*set_data)(mus_any *ptr, mus_float_t *new_data); mus_long_t (*length)(mus_any *ptr); mus_long_t (*set_length)(mus_any *ptr, mus_long_t new_length); mus_float_t (*frequency)(mus_any *ptr); mus_float_t (*set_frequency)(mus_any *ptr, mus_float_t new_freq); mus_float_t (*phase)(mus_any *ptr); mus_float_t (*set_phase)(mus_any *ptr, mus_float_t new_phase); mus_float_t (*scaler)(mus_any *ptr); mus_float_t (*set_scaler)(mus_any *ptr, mus_float_t val); mus_float_t (*increment)(mus_any *ptr); mus_float_t (*set_increment)(mus_any *ptr, mus_float_t val); mus_float_t (*run)(mus_any *gen, mus_float_t arg1, mus_float_t arg2); mus_clm_extended_t extended_type; void *(*closure)(mus_any *gen); int (*channels)(mus_any *ptr); mus_float_t (*offset)(mus_any *ptr); mus_float_t (*set_offset)(mus_any *ptr, mus_float_t val); mus_float_t (*width)(mus_any *ptr); mus_float_t (*set_width)(mus_any *ptr, mus_float_t val); mus_float_t (*xcoeff)(mus_any *ptr, int index); mus_float_t (*set_xcoeff)(mus_any *ptr, int index, mus_float_t val); mus_long_t (*hop)(mus_any *ptr); mus_long_t (*set_hop)(mus_any *ptr, mus_long_t new_length); mus_long_t (*ramp)(mus_any *ptr); mus_long_t (*set_ramp)(mus_any *ptr, mus_long_t new_length); mus_float_t (*read_sample)(mus_any *ptr, mus_long_t samp, int chan); mus_float_t (*write_sample)(mus_any *ptr, mus_long_t samp, int chan, mus_float_t data); char *(*file_name)(mus_any *ptr); int (*end)(mus_any *ptr); mus_long_t (*location)(mus_any *ptr); mus_long_t (*set_location)(mus_any *ptr, mus_long_t loc); int (*channel)(mus_any *ptr); mus_float_t (*ycoeff)(mus_any *ptr, int index); mus_float_t (*set_ycoeff)(mus_any *ptr, int index, mus_float_t val); mus_float_t *(*xcoeffs)(mus_any *ptr); mus_float_t *(*ycoeffs)(mus_any *ptr); void (*reset)(mus_any *ptr); void *(*set_closure)(mus_any *gen, void *e); mus_any *(*copy)(mus_any *ptr); }; enum {MUS_OSCIL, MUS_NCOS, MUS_DELAY, MUS_COMB, MUS_NOTCH, MUS_ALL_PASS, MUS_TABLE_LOOKUP, MUS_SQUARE_WAVE, MUS_SAWTOOTH_WAVE, MUS_TRIANGLE_WAVE, MUS_PULSE_TRAIN, MUS_RAND, MUS_RAND_INTERP, MUS_ASYMMETRIC_FM, MUS_ONE_ZERO, MUS_ONE_POLE, MUS_TWO_ZERO, MUS_TWO_POLE, MUS_FORMANT, MUS_SRC, MUS_GRANULATE, MUS_WAVE_TRAIN, MUS_FILTER, MUS_FIR_FILTER, MUS_IIR_FILTER, MUS_CONVOLVE, MUS_ENV, MUS_LOCSIG, MUS_READIN, MUS_FILE_TO_SAMPLE, MUS_FILE_TO_FRAMPLE, MUS_SAMPLE_TO_FILE, MUS_FRAMPLE_TO_FILE, MUS_PHASE_VOCODER, MUS_MOVING_AVERAGE, MUS_MOVING_MAX, MUS_MOVING_NORM, MUS_NSIN, MUS_SSB_AM, MUS_POLYSHAPE, MUS_FILTERED_COMB, MUS_MOVE_SOUND, MUS_NRXYSIN, MUS_NRXYCOS, MUS_POLYWAVE, MUS_FIRMANT, MUS_FORMANT_BANK, MUS_ONE_POLE_ALL_PASS, MUS_COMB_BANK, MUS_ALL_PASS_BANK, MUS_FILTERED_COMB_BANK, MUS_OSCIL_BANK, MUS_PULSED_ENV, MUS_RXYKSIN, MUS_RXYKCOS, MUS_INITIAL_GEN_TAG}; mus_any_class *mus_generator_class(mus_any *ptr) {return(ptr->core);} void mus_generator_set_extended_type(mus_any_class *p, mus_clm_extended_t extended_type) {p->extended_type = extended_type;} void mus_generator_set_length(mus_any_class *p, mus_long_t (*length)(mus_any *ptr)) {p->length = length;} void mus_generator_set_scaler(mus_any_class *p, mus_float_t (*scaler)(mus_any *ptr)) {p->scaler = scaler;} void mus_generator_set_channels(mus_any_class *p, int (*channels)(mus_any *ptr)) {p->channels = channels;} void mus_generator_set_location(mus_any_class *p, mus_long_t (*location)(mus_any *ptr)) {p->location = location;} void mus_generator_set_set_location(mus_any_class *p, mus_long_t (*set_location)(mus_any *ptr, mus_long_t loc)) {p->set_location = set_location;} void mus_generator_set_read_sample(mus_any_class *p, mus_float_t (*read_sample)(mus_any *ptr, mus_long_t samp, int chan)) {p->read_sample = read_sample;} void mus_generator_set_channel(mus_any_class *p, int (*channel)(mus_any *ptr)) {p->channel = channel;} void mus_generator_set_file_name(mus_any_class *p, char *(*file_name)(mus_any *ptr)) {p->file_name = file_name;} mus_any_class *mus_make_generator(int type, char *name, void (*release)(mus_any *ptr), char *(*describe)(mus_any *ptr), bool (*equalp)(mus_any *gen1, mus_any *gen2)) { mus_any_class *p; p = (mus_any_class *)calloc(1, sizeof(mus_any_class)); p->type = type; p->name = name; p->release = release; p->describe = describe; p->equalp = equalp; return(p); } static int mus_generator_type = MUS_INITIAL_GEN_TAG; int mus_make_generator_type(void) {return(mus_generator_type++);} static const char *interp_name[] = {"step", "linear", "sinusoidal", "all-pass", "lagrange", "bezier", "hermite"}; static const char *interp_type_to_string(int type) { if (mus_is_interp_type(type)) return(interp_name[type]); return("unknown"); } static mus_float_t sampling_rate = MUS_DEFAULT_SAMPLING_RATE; static mus_float_t w_rate = (TWO_PI / MUS_DEFAULT_SAMPLING_RATE); static mus_float_t float_equal_fudge_factor = 0.0000001; mus_float_t mus_float_equal_fudge_factor(void) {return(float_equal_fudge_factor);} mus_float_t mus_set_float_equal_fudge_factor(mus_float_t val) { mus_float_t prev; prev = float_equal_fudge_factor; float_equal_fudge_factor = val; return(prev); } static int array_print_length = MUS_DEFAULT_ARRAY_PRINT_LENGTH; int mus_array_print_length(void) {return(array_print_length);} int mus_set_array_print_length(int val) { int prev; prev = array_print_length; if (val >= 0) array_print_length = val; return(prev); } static mus_long_t clm_file_buffer_size = MUS_DEFAULT_FILE_BUFFER_SIZE; mus_long_t mus_file_buffer_size(void) {return(clm_file_buffer_size);} mus_long_t mus_set_file_buffer_size(mus_long_t size) { /* this is set in with-sound, among other places */ mus_long_t prev; prev = clm_file_buffer_size; clm_file_buffer_size = size; return(prev); } mus_float_t mus_radians_to_hz(mus_float_t rads) {return(rads / w_rate);} mus_float_t mus_hz_to_radians(mus_float_t hz) {return(hz * w_rate);} mus_float_t mus_degrees_to_radians(mus_float_t degree) {return(degree * TWO_PI / 360.0);} mus_float_t mus_radians_to_degrees(mus_float_t rads) {return(rads * 360.0 / TWO_PI);} mus_float_t mus_db_to_linear(mus_float_t x) {return(pow(10.0, x / 20.0));} mus_float_t mus_linear_to_db(mus_float_t x) {if (x > 0.0) return(20.0 * log10(x)); return(-100.0);} mus_float_t mus_odd_multiple(mus_float_t x, mus_float_t y) {mus_long_t f; f = (mus_long_t)floor(x); return(y * ((f & 1) ? f : (f + 1)));} mus_float_t mus_even_multiple(mus_float_t x, mus_float_t y) {mus_long_t f; f = (mus_long_t)floor(x); return(y * ((f & 1) ? (f + 1) : f));} mus_float_t mus_odd_weight(mus_float_t x) {mus_long_t f; f = (mus_long_t)floor(x); return(1.0 - fabs(x - ((f & 1) ? f : (f + 1))));} mus_float_t mus_even_weight(mus_float_t x) {mus_long_t f; f = (mus_long_t)floor(x); return(1.0 - fabs(x - ((f & 1) ? (f + 1) : f)));} mus_float_t mus_srate(void) {return(sampling_rate);} mus_float_t mus_set_srate(mus_float_t val) { mus_float_t prev; prev = sampling_rate; if (val > 0.0) { sampling_rate = val; w_rate = (TWO_PI / sampling_rate); } return(prev); } mus_long_t mus_seconds_to_samples(mus_float_t secs) {return((mus_long_t)(secs * sampling_rate));} mus_float_t mus_samples_to_seconds(mus_long_t samps) {return((mus_float_t)((mus_float_t)samps / (mus_float_t)sampling_rate));} #define DESCRIBE_BUFFER_SIZE 2048 #define STR_SIZE 128 static char *float_array_to_string(mus_float_t *arr, int len, int loc) { /* %g is needed here rather than %f -- otherwise the number strings can be any size */ #define MAX_NUM_SIZE 64 char *base, *str; int i, lim, size = 512; if (arr == NULL) { str = (char *)malloc(4 * sizeof(char)); snprintf(str, 4, "nil"); return(str); } lim = (array_print_length + 4) * MAX_NUM_SIZE; /* 4 for possible bounds below */ if (lim > size) size = lim; if (loc < 0) loc = 0; base = (char *)calloc(size, sizeof(char)); str = (char *)malloc(STR_SIZE * sizeof(char)); if (len > 0) { int k; snprintf(base, size, "["); lim = len; if (lim > array_print_length) lim = array_print_length; k = loc; if (k >= len) k = 0; for (i = 0; i < lim - 1; i++) { snprintf(str, STR_SIZE, "%.3g ", arr[k]); strcat(base, str); if ((int)(strlen(base) + MAX_NUM_SIZE) > size) { base = (char *)realloc(base, size * 2 * sizeof(char)); base[size] = 0; size *= 2; } k++; if (k >= len) k = 0; } snprintf(str, STR_SIZE, "%.3g%s", arr[k], (len > lim) ? "..." : "]"); strcat(base, str); } else snprintf(base, size, "[]"); if (len > lim) { /* print ranges */ int min_loc = 0, max_loc = 0; mus_float_t min_val, max_val; min_val = arr[0]; max_val = arr[0]; for (i = 1; i < len; i++) { if (arr[i] < min_val) {min_val = arr[i]; min_loc = i;} if (arr[i] > max_val) {max_val = arr[i]; max_loc = i;} } snprintf(str, STR_SIZE, "(%d: %.3g, %d: %.3g)]", min_loc, min_val, max_loc, max_val); strcat(base, str); } free(str); return(base); } static char *clm_array_to_string(mus_any **gens, int num_gens, const char *name, const char *indent) { char *descr = NULL; if ((gens) && (num_gens > 0)) { int i, len = 0; char **descrs; descrs = (char **)calloc(num_gens, sizeof(char *)); for (i = 0; i < num_gens; i++) { if (gens[i]) { char *str = NULL; descrs[i] = mus_format("\n%s[%d]: %s", indent, i, str = mus_describe(gens[i])); if (str) free(str); } else descrs[i] = mus_format("\n%s[%d]: nil", indent, i); len += strlen(descrs[i]); } len += (64 + strlen(name)); descr = (char *)malloc(len * sizeof(char)); snprintf(descr, len, "%s[%d]:", name, num_gens); for (i = 0; i < num_gens; i++) { strcat(descr, descrs[i]); free(descrs[i]); } free(descrs); } else { descr = (char *)malloc(128 * sizeof(char)); snprintf(descr, 128, "%s: nil", name); } return(descr); } static char *int_array_to_string(int *arr, int num_ints, const char *name) { #define MAX_INT_SIZE 32 char *descr = NULL; if ((arr) && (num_ints > 0)) { int i, len; char *intstr; len = num_ints * MAX_INT_SIZE + 64; descr = (char *)calloc(len, sizeof(char)); intstr = (char *)malloc(MAX_INT_SIZE * sizeof(char)); snprintf(descr, len, "%s[%d]: (", name, num_ints); for (i = 0; i < num_ints - 1; i++) { snprintf(intstr, MAX_INT_SIZE, "%d ", arr[i]); strcat(descr, intstr); } snprintf(intstr, MAX_INT_SIZE, "%d)", arr[num_ints - 1]); strcat(descr, intstr); free(intstr); } else { descr = (char *)malloc(128 * sizeof(char)); snprintf(descr, 128, "%s: nil", name); } return(descr); } /* ---------------- generic functions ---------------- */ #define check_gen(Ptr, Name) ((Ptr) ? true : (!mus_error(MUS_NO_GEN, "null generator passed to %s", Name))) int mus_type(mus_any *ptr) { return(((check_gen(ptr, S_mus_type)) && (ptr->core)) ? ptr->core->type : -1); } const char *mus_name(mus_any *ptr) { return((ptr == NULL) ? "null" : ptr->core->name); } void mus_free(mus_any *gen) { if (gen) (*(gen->core->release))(gen); } char *mus_describe(mus_any *gen) { if (gen == NULL) return(mus_strdup((char *)"null")); if ((gen->core) && (gen->core->describe)) return((*(gen->core->describe))(gen)); else mus_error(MUS_NO_DESCRIBE, "can't describe %s", mus_name(gen)); return(NULL); } bool mus_equalp(mus_any *p1, mus_any *p2) { if ((p1) && (p2)) { if ((p1->core)->equalp) return((*((p1->core)->equalp))(p1, p2)); else return(p1 == p2); } return(true); /* (eq nil nil) */ } void mus_reset(mus_any *gen) { if ((check_gen(gen, S_mus_reset)) && (gen->core->reset)) (*(gen->core->reset))(gen); else mus_error(MUS_NO_RESET, "can't reset %s", mus_name(gen)); } mus_any *mus_copy(mus_any *gen) { if ((check_gen(gen, S_mus_copy)) && (gen->core->copy)) return((*(gen->core->copy))(gen)); else mus_error(MUS_NO_COPY, "can't copy %s", mus_name(gen)); return(NULL); } mus_float_t mus_frequency(mus_any *gen) { if ((check_gen(gen, S_mus_frequency)) && (gen->core->frequency)) return((*(gen->core->frequency))(gen)); return((mus_float_t)mus_error(MUS_NO_FREQUENCY, "can't get %s's frequency", mus_name(gen))); } mus_float_t mus_set_frequency(mus_any *gen, mus_float_t val) { if ((check_gen(gen, S_set S_mus_frequency)) && (gen->core->set_frequency)) return((*(gen->core->set_frequency))(gen, val)); return((mus_float_t)mus_error(MUS_NO_FREQUENCY, "can't set %s's frequency", mus_name(gen))); } mus_float_t mus_phase(mus_any *gen) { if ((check_gen(gen, S_mus_phase)) && (gen->core->phase)) return((*(gen->core->phase))(gen)); return((mus_float_t)mus_error(MUS_NO_PHASE, "can't get %s's phase", mus_name(gen))); } mus_float_t mus_set_phase(mus_any *gen, mus_float_t val) { if ((check_gen(gen, S_set S_mus_phase)) && (gen->core->set_phase)) return((*(gen->core->set_phase))(gen, val)); return((mus_float_t)mus_error(MUS_NO_PHASE, "can't set %s's phase", mus_name(gen))); } mus_float_t mus_scaler(mus_any *gen) { if ((check_gen(gen, S_mus_scaler)) && (gen->core->scaler)) return((*(gen->core->scaler))(gen)); return((mus_float_t)mus_error(MUS_NO_SCALER, "can't get %s's scaler", mus_name(gen))); } mus_float_t mus_set_scaler(mus_any *gen, mus_float_t val) { if ((check_gen(gen, S_set S_mus_scaler)) && (gen->core->set_scaler)) return((*(gen->core->set_scaler))(gen, val)); return((mus_float_t)mus_error(MUS_NO_SCALER, "can't set %s's scaler", mus_name(gen))); } mus_float_t mus_feedforward(mus_any *gen) /* shares "scaler" */ { if ((check_gen(gen, S_mus_feedforward)) && (gen->core->scaler)) return((*(gen->core->scaler))(gen)); return((mus_float_t)mus_error(MUS_NO_FEEDFORWARD, "can't get %s's feedforward", mus_name(gen))); } mus_float_t mus_set_feedforward(mus_any *gen, mus_float_t val) { if ((check_gen(gen, S_set S_mus_feedforward)) && (gen->core->set_scaler)) return((*(gen->core->set_scaler))(gen, val)); return((mus_float_t)mus_error(MUS_NO_FEEDFORWARD, "can't set %s's feedforward", mus_name(gen))); } mus_float_t mus_offset(mus_any *gen) { if ((check_gen(gen, S_mus_offset)) && (gen->core->offset)) return((*(gen->core->offset))(gen)); return((mus_float_t)mus_error(MUS_NO_OFFSET, "can't get %s's offset", mus_name(gen))); } mus_float_t mus_set_offset(mus_any *gen, mus_float_t val) { if ((check_gen(gen, S_set S_mus_offset)) && (gen->core->set_offset)) return((*(gen->core->set_offset))(gen, val)); return((mus_float_t)mus_error(MUS_NO_OFFSET, "can't set %s's offset", mus_name(gen))); } mus_float_t mus_width(mus_any *gen) { if ((check_gen(gen, S_mus_width)) && (gen->core->width)) return((*(gen->core->width))(gen)); return((mus_float_t)mus_error(MUS_NO_WIDTH, "can't get %s's width", mus_name(gen))); } mus_float_t mus_set_width(mus_any *gen, mus_float_t val) { if ((check_gen(gen, S_set S_mus_width)) && (gen->core->set_width)) return((*(gen->core->set_width))(gen, val)); return((mus_float_t)mus_error(MUS_NO_WIDTH, "can't set %s's width", mus_name(gen))); } mus_float_t mus_increment(mus_any *gen) { if ((check_gen(gen, S_mus_increment)) && (gen->core->increment)) return((*(gen->core->increment))(gen)); return((mus_float_t)mus_error(MUS_NO_INCREMENT, "can't get %s's increment", mus_name(gen))); } mus_float_t mus_set_increment(mus_any *gen, mus_float_t val) { if ((check_gen(gen, S_set S_mus_increment)) && (gen->core->set_increment)) return((*(gen->core->set_increment))(gen, val)); return((mus_float_t)mus_error(MUS_NO_INCREMENT, "can't set %s's increment", mus_name(gen))); } mus_float_t mus_feedback(mus_any *gen) /* shares "increment" */ { if ((check_gen(gen, S_mus_feedback)) && (gen->core->increment)) return((*(gen->core->increment))(gen)); return((mus_float_t)mus_error(MUS_NO_FEEDBACK, "can't get %s's feedback", mus_name(gen))); } mus_float_t mus_set_feedback(mus_any *gen, mus_float_t val) { if ((check_gen(gen, S_set S_mus_feedback)) && (gen->core->set_increment)) return((*(gen->core->set_increment))(gen, val)); return((mus_float_t)mus_error(MUS_NO_FEEDBACK, "can't set %s's feedback", mus_name(gen))); } void *mus_environ(mus_any *gen) { if (check_gen(gen, "mus-environ")) return((*(gen->core->closure))(gen)); return(NULL); } void *mus_set_environ(mus_any *gen, void *e) { if (check_gen(gen, S_set "mus-environ")) return((*(gen->core->set_closure))(gen, e)); return(NULL); } mus_float_t mus_run(mus_any *gen, mus_float_t arg1, mus_float_t arg2) { if ((check_gen(gen, "mus-run")) && (gen->core->run)) return((*(gen->core->run))(gen, arg1, arg2)); return((mus_float_t)mus_error(MUS_NO_RUN, "can't run %s", mus_name(gen))); } mus_long_t mus_length(mus_any *gen) { if ((check_gen(gen, S_mus_length)) && (gen->core->length)) return((*(gen->core->length))(gen)); return(mus_error(MUS_NO_LENGTH, "can't get %s's length", mus_name(gen))); } mus_long_t mus_set_length(mus_any *gen, mus_long_t len) { if ((check_gen(gen, S_set S_mus_length)) && (gen->core->set_length)) return((*(gen->core->set_length))(gen, len)); return(mus_error(MUS_NO_LENGTH, "can't set %s's length", mus_name(gen))); } mus_long_t mus_order(mus_any *gen) /* shares "length", no set */ { if ((check_gen(gen, S_mus_order)) && (gen->core->length)) return((*(gen->core->length))(gen)); return(mus_error(MUS_NO_ORDER, "can't get %s's order", mus_name(gen))); } int mus_channels(mus_any *gen) { if ((check_gen(gen, S_mus_channels)) && (gen->core->channels)) return((*(gen->core->channels))(gen)); return(mus_error(MUS_NO_CHANNELS, "can't get %s's channels", mus_name(gen))); } int mus_interp_type(mus_any *gen) /* shares "channels", no set */ { if ((check_gen(gen, S_mus_interp_type)) && (gen->core->channels)) return((*(gen->core->channels))(gen)); return(mus_error(MUS_NO_INTERP_TYPE, "can't get %s's interp type", mus_name(gen))); } int mus_position(mus_any *gen) /* shares "channels", no set, only used in C (snd-env.c) */ { if ((check_gen(gen, "mus-position")) && (gen->core->channels)) return((*(gen->core->channels))(gen)); return(mus_error(MUS_NO_POSITION, "can't get %s's position", mus_name(gen))); } int mus_channel(mus_any *gen) { if ((check_gen(gen, S_mus_channel)) && (gen->core->channel)) return(((*gen->core->channel))(gen)); return(mus_error(MUS_NO_CHANNEL, "can't get %s's channel", mus_name(gen))); } mus_long_t mus_hop(mus_any *gen) { if ((check_gen(gen, S_mus_hop)) && (gen->core->hop)) return((*(gen->core->hop))(gen)); return(mus_error(MUS_NO_HOP, "can't get %s's hop value", mus_name(gen))); } mus_long_t mus_set_hop(mus_any *gen, mus_long_t len) { if ((check_gen(gen, S_set S_mus_hop)) && (gen->core->set_hop)) return((*(gen->core->set_hop))(gen, len)); return(mus_error(MUS_NO_HOP, "can't set %s's hop value", mus_name(gen))); } mus_long_t mus_ramp(mus_any *gen) { if ((check_gen(gen, S_mus_ramp)) && (gen->core->ramp)) return((*(gen->core->ramp))(gen)); return(mus_error(MUS_NO_RAMP, "can't get %s's ramp value", mus_name(gen))); } mus_long_t mus_set_ramp(mus_any *gen, mus_long_t len) { if ((check_gen(gen, S_set S_mus_ramp)) && (gen->core->set_ramp)) return((*(gen->core->set_ramp))(gen, len)); return(mus_error(MUS_NO_RAMP, "can't set %s's ramp value", mus_name(gen))); } mus_float_t *mus_data(mus_any *gen) { if ((check_gen(gen, S_mus_data)) && (gen->core->data)) return((*(gen->core->data))(gen)); mus_error(MUS_NO_DATA, "can't get %s's data", mus_name(gen)); return(NULL); } /* every case that implements the data or set data functions needs to include * a var-allocated flag, since all such memory has to be handled via vcts */ mus_float_t *mus_set_data(mus_any *gen, mus_float_t *new_data) { if (check_gen(gen, S_set S_mus_data)) { if (gen->core->set_data) { (*(gen->core->set_data))(gen, new_data); return(new_data); } else mus_error(MUS_NO_DATA, "can't set %s's data", mus_name(gen)); } return(new_data); } mus_float_t *mus_xcoeffs(mus_any *gen) { if ((check_gen(gen, S_mus_xcoeffs)) && (gen->core->xcoeffs)) return((*(gen->core->xcoeffs))(gen)); mus_error(MUS_NO_XCOEFFS, "can't get %s's xcoeffs", mus_name(gen)); return(NULL); } mus_float_t *mus_ycoeffs(mus_any *gen) { if ((check_gen(gen, S_mus_ycoeffs)) && (gen->core->ycoeffs)) return((*(gen->core->ycoeffs))(gen)); mus_error(MUS_NO_YCOEFFS, "can't get %s's ycoeffs", mus_name(gen)); return(NULL); } mus_float_t mus_xcoeff(mus_any *gen, int index) { if ((check_gen(gen, S_mus_xcoeff)) && (gen->core->xcoeff)) return((*(gen->core->xcoeff))(gen, index)); return(mus_error(MUS_NO_XCOEFF, "can't get %s's xcoeff[%d] value", mus_name(gen), index)); } mus_float_t mus_set_xcoeff(mus_any *gen, int index, mus_float_t val) { if ((check_gen(gen, S_set S_mus_xcoeff)) && (gen->core->set_xcoeff)) return((*(gen->core->set_xcoeff))(gen, index, val)); return(mus_error(MUS_NO_XCOEFF, "can't set %s's xcoeff[%d] value", mus_name(gen), index)); } mus_float_t mus_ycoeff(mus_any *gen, int index) { if ((check_gen(gen, S_mus_ycoeff)) && (gen->core->ycoeff)) return((*(gen->core->ycoeff))(gen, index)); return(mus_error(MUS_NO_YCOEFF, "can't get %s's ycoeff[%d] value", mus_name(gen), index)); } mus_float_t mus_set_ycoeff(mus_any *gen, int index, mus_float_t val) { if ((check_gen(gen, S_set S_mus_ycoeff)) && (gen->core->set_ycoeff)) return((*(gen->core->set_ycoeff))(gen, index, val)); return(mus_error(MUS_NO_YCOEFF, "can't set %s's ycoeff[%d] value", mus_name(gen), index)); } mus_long_t mus_location(mus_any *gen) { if ((check_gen(gen, S_mus_location)) && (gen->core->location)) return(((*gen->core->location))(gen)); return((mus_long_t)mus_error(MUS_NO_LOCATION, "can't get %s's location", mus_name(gen))); } /* ---------------- AM etc ---------------- */ mus_float_t mus_ring_modulate(mus_float_t sig1, mus_float_t sig2) { return(sig1 * sig2); } mus_float_t mus_amplitude_modulate(mus_float_t carrier, mus_float_t sig1, mus_float_t sig2) { return(sig1 * (carrier + sig2)); } mus_float_t mus_contrast_enhancement(mus_float_t sig, mus_float_t index) { return(sin((sig * M_PI_2) + (index * sin(sig * TWO_PI)))); } bool mus_arrays_are_equal(mus_float_t *arr1, mus_float_t *arr2, mus_float_t fudge, mus_long_t len) { mus_long_t i; if (fudge == 0.0) { for (i = 0; i < len; i++) if (arr1[i] != arr2[i]) return(false); } else { mus_long_t len4; len4 = len - 4; i = 0; while (i <= len4) { if (fabs(arr1[i] - arr2[i]) > fudge) return(false); i++; if (fabs(arr1[i] - arr2[i]) > fudge) return(false); i++; if (fabs(arr1[i] - arr2[i]) > fudge) return(false); i++; if (fabs(arr1[i] - arr2[i]) > fudge) return(false); i++; } for (; i < len; i++) if (fabs(arr1[i] - arr2[i]) > fudge) return(false); } return(true); } static bool clm_arrays_are_equal(mus_float_t *arr1, mus_float_t *arr2, mus_long_t len) { return(mus_arrays_are_equal(arr1, arr2, float_equal_fudge_factor, len)); } mus_float_t mus_dot_product(mus_float_t *data1, mus_float_t *data2, mus_long_t size) { mus_long_t i, size4; mus_float_t sum = 0.0; size4 = size - 4; i = 0; while (i <= size4) { sum += (data1[i] * data2[i]); i++; sum += (data1[i] * data2[i]); i++; sum += (data1[i] * data2[i]); i++; sum += (data1[i] * data2[i]); i++; } for (; i < size; i++) sum += (data1[i] * data2[i]); return(sum); } #if HAVE_COMPLEX_TRIG #if HAVE_FORTH #include "xen.h" #endif complex double mus_edot_product(complex double freq, complex double *data, mus_long_t size) { int i; complex double sum = 0.0; for (i = 0; i < size; i++) sum += (cexp(i * freq) * data[i]); return(sum); } #endif mus_float_t mus_polynomial(mus_float_t *coeffs, mus_float_t x, int ncoeffs) { mus_float_t sum; int i; if (ncoeffs <= 0) return(0.0); if (ncoeffs == 1) return(coeffs[0]); /* just a constant term */ sum = coeffs[ncoeffs - 1]; /* unrolled is slower */ for (i = ncoeffs - 2; i >= 0; i--) sum = (sum * x) + coeffs[i]; return((mus_float_t)sum); } void mus_rectangular_to_polar(mus_float_t *rl, mus_float_t *im, mus_long_t size) { mus_long_t i; for (i = 0; i < size; i++) { mus_float_t temp; /* apparently floating underflows (denormals?) in sqrt are bringing us to a halt */ temp = rl[i] * rl[i] + im[i] * im[i]; if (temp < .00000001) { rl[i] = 0.0; im[i] = 0.0; } else { im[i] = -atan2(im[i], rl[i]); /* "-" here so that clockwise is positive? is this backwards? */ rl[i] = sqrt(temp); } } } void mus_rectangular_to_magnitudes(mus_float_t *rl, mus_float_t *im, mus_long_t size) { mus_long_t i; for (i = 0; i < size; i++) { mus_float_t temp; /* apparently floating underflows in sqrt are bringing us to a halt */ temp = rl[i] * rl[i] + im[i] * im[i]; if (temp < .00000001) rl[i] = 0.0; else rl[i] = sqrt(temp); } } void mus_polar_to_rectangular(mus_float_t *rl, mus_float_t *im, mus_long_t size) { mus_long_t i; for (i = 0; i < size; i++) { #if HAVE_SINCOS double sx, cx; sincos(-im[i], &sx, &cx); im[i] = sx * rl[i]; rl[i] *= cx; #else mus_float_t temp; temp = rl[i] * sin(-im[i]); /* minus to match sense of rectangular->polar above */ rl[i] *= cos(-im[i]); im[i] = temp; #endif } } static mus_float_t *array_normalize(mus_float_t *table, mus_long_t table_size) { mus_float_t amp = 0.0; mus_long_t i; for (i = 0; i < table_size; i++) if (amp < (fabs(table[i]))) amp = fabs(table[i]); if ((amp > 0.0) && (amp != 1.0)) for (i = 0; i < table_size; i++) table[i] /= amp; return(table); } /* ---------------- interpolation ---------------- */ mus_float_t mus_array_interp(mus_float_t *wave, mus_float_t phase, mus_long_t size) { /* changed 26-Sep-00 to be closer to mus.lisp */ mus_long_t int_part; mus_float_t frac_part; if ((phase < 0.0) || (phase > size)) { /* 28-Mar-01 changed to fmod; I was hoping to avoid this... */ phase = fmod((mus_float_t)phase, (mus_float_t)size); if (phase < 0.0) phase += size; } int_part = (mus_long_t)phase; /* (mus_long_t)floor(phase); */ frac_part = phase - int_part; if (int_part == size) int_part = 0; if (frac_part == 0.0) return(wave[int_part]); else { mus_long_t inx; inx = int_part + 1; if (inx >= size) inx = 0; return(wave[int_part] + (frac_part * (wave[inx] - wave[int_part]))); } } static mus_float_t mus_array_all_pass_interp(mus_float_t *wave, mus_float_t phase, mus_long_t size, mus_float_t yn1) { /* this is intended for delay lines where you have a stream of values; in table-lookup it can be a mess */ mus_long_t int_part, inx; mus_float_t frac_part; if ((phase < 0.0) || (phase > size)) { phase = fmod((mus_float_t)phase, (mus_float_t)size); if (phase < 0.0) phase += size; } int_part = (mus_long_t)floor(phase); frac_part = phase - int_part; if (int_part == size) int_part = 0; inx = int_part + 1; if (inx >= size) inx -= size; #if 1 /* from DAFX */ if (frac_part == 0.0) return(wave[inx] - yn1); return(wave[int_part] * frac_part + (1.0 - frac_part) * (wave[inx] - yn1)); #else /* from Perry Cook */ if (frac_part == 0.0) return(wave[int_part] + wave[inx] - yn1); else return(wave[int_part] + ((1.0 - frac_part) / (1 + frac_part)) * (wave[inx] - yn1)); #endif } static mus_float_t mus_array_lagrange_interp(mus_float_t *wave, mus_float_t x, mus_long_t size) { /* Abramovitz and Stegun 25.2.11 -- everyone badmouths this poor formula */ /* x assumed to be in the middle, between second and third vals */ mus_long_t x0, xp1, xm1; mus_float_t p, pp; if ((x < 0.0) || (x > size)) { x = fmod((mus_float_t)x, (mus_float_t)size); if (x < 0.0) x += size; } x0 = (mus_long_t)floor(x); p = x - x0; if (x0 >= size) x0 -= size; if (p == 0.0) return(wave[x0]); xp1 = x0 + 1; if (xp1 >= size) xp1 -= size; xm1 = x0 - 1; if (xm1 < 0) xm1 += size; pp = p * p; return((wave[xm1] * 0.5 * (pp - p)) + (wave[x0] * (1.0 - pp)) + (wave[xp1] * 0.5 * (p + pp))); } static mus_float_t mus_array_hermite_interp(mus_float_t *wave, mus_float_t x, mus_long_t size) { /* from James McCartney */ mus_long_t x0, x1, x2, x3; mus_float_t p, c0, c1, c2, c3, y0, y1, y2, y3; if ((x < 0.0) || (x > size)) { x = fmod((mus_float_t)x, (mus_float_t)size); if (x < 0.0) x += size; } x1 = (mus_long_t)floor(x); p = x - x1; if (x1 == size) x1 = 0; if (p == 0.0) return(wave[x1]); x2 = x1 + 1; if (x2 == size) x2 = 0; x3 = x2 + 1; if (x3 == size) x3 = 0; x0 = x1 - 1; if (x0 < 0) x0 = size - 1; y0 = wave[x0]; y1 = wave[x1]; y2 = wave[x2]; y3 = wave[x3]; c0 = y1; c1 = 0.5 * (y2 - y0); c3 = 1.5 * (y1 - y2) + 0.5 * (y3 - y0); c2 = y0 - y1 + c1 - c3; return(((c3 * p + c2) * p + c1) * p + c0); } static mus_float_t mus_array_bezier_interp(mus_float_t *wave, mus_float_t x, mus_long_t size) { mus_long_t x0, x1, x2, x3; mus_float_t p, y0, y1, y2, y3, ay, by, cy; if ((x < 0.0) || (x > size)) { x = fmod((mus_float_t)x, (mus_float_t)size); if (x < 0.0) x += size; } x1 = (mus_long_t)floor(x); p = ((x - x1) + 1.0) / 3.0; if (x1 == size) x1 = 0; x2 = x1 + 1; if (x2 == size) x2 = 0; x3 = x2 + 1; if (x3 == size) x3 = 0; x0 = x1 - 1; if (x0 < 0) x0 = size - 1; y0 = wave[x0]; y1 = wave[x1]; y2 = wave[x2]; y3 = wave[x3]; cy = 3 * (y1 - y0); by = 3 * (y2 - y1) - cy; ay = y3 - y0 - cy - by; return(y0 + p * (cy + (p * (by + (p * ay))))); } bool mus_is_interp_type(int val) { /* this is C++'s fault. */ switch (val) { case MUS_INTERP_NONE: case MUS_INTERP_LINEAR: case MUS_INTERP_SINUSOIDAL: case MUS_INTERP_LAGRANGE: case MUS_INTERP_HERMITE: case MUS_INTERP_ALL_PASS: case MUS_INTERP_BEZIER: return(true); break; } return(false); } mus_float_t mus_interpolate(mus_interp_t type, mus_float_t x, mus_float_t *table, mus_long_t table_size, mus_float_t y) { switch (type) { case MUS_INTERP_NONE: { mus_long_t x0; x0 = ((mus_long_t)x) % table_size; if (x0 < 0) x0 += table_size; return(table[x0]); } break; case MUS_INTERP_LAGRANGE: return(mus_array_lagrange_interp(table, x, table_size)); break; case MUS_INTERP_HERMITE: return(mus_array_hermite_interp(table, x, table_size)); break; case MUS_INTERP_LINEAR: return(mus_array_interp(table, x, table_size)); break; case MUS_INTERP_ALL_PASS: return(mus_array_all_pass_interp(table, x, table_size, y)); break; case MUS_INTERP_BEZIER: return(mus_array_bezier_interp(table, x, table_size)); break; default: mus_error(MUS_ARG_OUT_OF_RANGE, "unknown interpolation type: %d", type); break; } return(0.0); } /* ---------------- oscil ---------------- */ typedef struct { mus_any_class *core; mus_float_t phase, freq; } osc; mus_float_t mus_oscil(mus_any *ptr, mus_float_t fm, mus_float_t pm) { osc *gen = (osc *)ptr; mus_float_t result; result = gen->phase + pm; gen->phase += (gen->freq + fm); return(sin(result)); } mus_float_t mus_oscil_unmodulated(mus_any *ptr) { osc *gen = (osc *)ptr; mus_float_t result; result = gen->phase; gen->phase += gen->freq; return(sin(result)); } mus_float_t mus_oscil_fm(mus_any *ptr, mus_float_t fm) { osc *gen = (osc *)ptr; mus_float_t result; result = gen->phase; gen->phase += (gen->freq + fm); return(sin(result)); } mus_float_t mus_oscil_pm(mus_any *ptr, mus_float_t pm) { mus_float_t result; osc *gen = (osc *)ptr; result = gen->phase + pm; gen->phase += gen->freq; return(sin(result)); } bool mus_is_oscil(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_OSCIL)); } /* this could be: bool mus_is_oscil(mus_any *ptr) {return((ptr) && (ptr->core == &OSCIL_CLASS));} */ static void free_oscil(mus_any *ptr) {free(ptr);} static mus_float_t oscil_freq(mus_any *ptr) {return(mus_radians_to_hz(((osc *)ptr)->freq));} static mus_float_t oscil_set_freq(mus_any *ptr, mus_float_t val) {((osc *)ptr)->freq = mus_hz_to_radians(val); return(val);} static mus_float_t oscil_increment(mus_any *ptr) {return(((osc *)ptr)->freq);} static mus_float_t oscil_set_increment(mus_any *ptr, mus_float_t val) {((osc *)ptr)->freq = val; return(val);} static mus_float_t oscil_phase(mus_any *ptr) {return(fmod(((osc *)ptr)->phase, TWO_PI));} static mus_float_t oscil_set_phase(mus_any *ptr, mus_float_t val) {((osc *)ptr)->phase = val; return(val);} static mus_long_t oscil_cosines(mus_any *ptr) {return(1);} static void oscil_reset(mus_any *ptr) {((osc *)ptr)->phase = 0.0;} static mus_any *oscil_copy(mus_any *ptr) { osc *g; g = (osc *)malloc(sizeof(osc)); memcpy((void *)g, (void *)ptr, sizeof(osc)); return((mus_any *)g); } static mus_float_t fallback_scaler(mus_any *ptr) {return(1.0);} static bool oscil_equalp(mus_any *p1, mus_any *p2) { return((p1 == p2) || ((mus_is_oscil((mus_any *)p1)) && (mus_is_oscil((mus_any *)p2)) && ((((osc *)p1)->freq) == (((osc *)p2)->freq)) && ((((osc *)p1)->phase) == (((osc *)p2)->phase)))); } static char *describe_oscil(mus_any *ptr) { char *describe_buffer; describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE); snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s freq: %.3fHz, phase: %.3f", mus_name(ptr), mus_frequency(ptr), mus_phase(ptr)); return(describe_buffer); } static mus_any_class OSCIL_CLASS = { MUS_OSCIL, (char *)S_oscil, /* the "(char *)" business is for g++'s benefit */ &free_oscil, &describe_oscil, &oscil_equalp, 0, 0, &oscil_cosines, 0, &oscil_freq, &oscil_set_freq, &oscil_phase, &oscil_set_phase, &fallback_scaler, 0, &oscil_increment, &oscil_set_increment, &mus_oscil, MUS_NOT_SPECIAL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &oscil_reset, 0, &oscil_copy }; mus_any *mus_make_oscil(mus_float_t freq, mus_float_t phase) { osc *gen; gen = (osc *)malloc(sizeof(osc)); gen->core = &OSCIL_CLASS; gen->freq = mus_hz_to_radians(freq); gen->phase = phase; return((mus_any *)gen); } /* decided against feedback-oscil (as in cellon) because it's not clear how to handle the index, * and there are many options for the filtering -- since this part of the signal path * is not hidden, there's no reason to bring it out explicitly (as in filtered-comb) */ /* ---------------- oscil-bank ---------------- */ typedef struct { mus_any_class *core; int size, orig_size; mus_float_t *amps, *phases, *freqs; /* these can change, so sincos is not always safe */ bool free_phases; mus_float_t (*ob_func)(mus_any *ptr); #if HAVE_SINCOS double *sn1, *cs1, *sn2, *cs2, *phs; bool use_sc; #endif } ob; static void free_oscil_bank(mus_any *ptr) { ob *g = (ob *)ptr; #if HAVE_SINCOS if (g->sn1) {free(g->sn1); g->sn1 = NULL;} if (g->sn2) {free(g->sn2); g->sn2 = NULL;} if (g->cs1) {free(g->cs1); g->cs1 = NULL;} if (g->cs2) {free(g->cs2); g->cs2 = NULL;} if (g->phs) {free(g->phs); g->phs = NULL;} #endif if ((g->phases) && (g->free_phases)) {free(g->phases); g->phases = NULL;} free(ptr); } static mus_any *ob_copy(mus_any *ptr) { ob *g, *p; int bytes; p = (ob *)ptr; g = (ob *)malloc(sizeof(ob)); memcpy((void *)g, (void *)ptr, sizeof(ob)); g->ob_func = p->ob_func; #if HAVE_SINCOS if (g->sn1) { bytes = g->size * sizeof(double); g->sn1 = (double *)malloc(bytes); memcpy((void *)(g->sn1), (void *)(p->sn1), bytes); g->sn2 = (double *)malloc(bytes); memcpy((void *)(g->sn2), (void *)(p->sn2), bytes); g->cs1 = (double *)malloc(bytes); memcpy((void *)(g->cs1), (void *)(p->cs1), bytes); g->cs2 = (double *)malloc(bytes); memcpy((void *)(g->cs2), (void *)(p->cs2), bytes); g->phs = (double *)malloc(bytes); memcpy((void *)(g->phs), (void *)(p->phs), bytes); g->use_sc = p->use_sc; } #endif bytes = g->size * sizeof(mus_float_t); /* we have to make a new phases array -- otherwise the original and copy step on each other */ g->free_phases = true; g->phases = (mus_float_t *)malloc(bytes); memcpy((void *)(g->phases), (void *)(p->phases), bytes); return((mus_any *)g); } static mus_float_t *ob_data(mus_any *ptr) {return(((ob *)ptr)->phases);} static mus_float_t run_oscil_bank(mus_any *ptr, mus_float_t input, mus_float_t unused) { return(mus_oscil_bank(ptr)); } static mus_long_t oscil_bank_length(mus_any *ptr) { return(((ob *)ptr)->size); } static mus_long_t oscil_bank_set_length(mus_any *ptr, mus_long_t len) { ob *g = (ob *)ptr; if (len < 0) g->size = 0; else { if (len > g->orig_size) g->size = g->orig_size; else g->size = len; } return(len); } static void oscil_bank_reset(mus_any *ptr) { ob *p = (ob *)ptr; p->size = p->orig_size; memset((void *)(p->phases), 0, p->orig_size * sizeof(mus_float_t)); } static bool oscil_bank_equalp(mus_any *p1, mus_any *p2) { ob *o1 = (ob *)p1; ob *o2 = (ob *)p2; if (p1 == p2) return(true); return((o1->size == o2->size) && (o1->orig_size == o2->orig_size) && (o1->amps == o2->amps) && (o1->freqs == o2->freqs) && ((o1->phases == o2->phases) || (clm_arrays_are_equal(o1->phases, o2->phases, o2->size)))); } static char *describe_oscil_bank(mus_any *ptr) { ob *gen = (ob *)ptr; char *describe_buffer; describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE); snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s size: %d", mus_name(ptr), gen->size); return(describe_buffer); } static mus_any_class OSCIL_BANK_CLASS = { MUS_OSCIL_BANK, (char *)S_oscil_bank, &free_oscil_bank, &describe_oscil_bank, &oscil_bank_equalp, &ob_data, 0, &oscil_bank_length, &oscil_bank_set_length, 0, 0, 0, 0, 0, 0, 0, 0, &run_oscil_bank, MUS_NOT_SPECIAL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &oscil_bank_reset, 0, &ob_copy }; bool mus_is_oscil_bank(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_OSCIL_BANK)); } static mus_float_t oscil_bank(mus_any *ptr) { ob *p = (ob *)ptr; int i; mus_float_t sum = 0.0; if (!p->amps) { for (i = 0; i < p->size; i++) { sum += sin(p->phases[i]); p->phases[i] += p->freqs[i]; } } else { for (i = 0; i < p->size; i++) { sum += (p->amps[i] * sin(p->phases[i])); p->phases[i] += p->freqs[i]; } } return(sum); } #if HAVE_SINCOS static mus_float_t stable_oscil_bank(mus_any *ptr) { ob *p = (ob *)ptr; int i; mus_float_t sum = 0.0; if (p->use_sc) { for (i = 0; i < p->size; i++) sum += (p->sn1[i] * p->cs2[i] + p->cs1[i] * p->sn2[i]); p->use_sc = false; } else { double s, c; if (!p->amps) { for (i = 0; i < p->size; i++) { sincos(p->phases[i], &s, &c); p->sn2[i] = s; p->cs2[i] = c; sum += s; p->phases[i] += p->phs[i]; } } else { for (i = 0; i < p->size; i++) { sincos(p->phases[i], &s, &c); p->sn2[i] = s; p->cs2[i] = c; sum += p->amps[i] * s; p->phases[i] += p->phs[i]; } } p->use_sc = true; } return(sum); } #endif mus_float_t mus_oscil_bank(mus_any *ptr) { ob *p = (ob *)ptr; return(p->ob_func(ptr)); } mus_any *mus_make_oscil_bank(int size, mus_float_t *freqs, mus_float_t *phases, mus_float_t *amps, bool stable) { ob *gen; gen = (ob *)malloc(sizeof(ob)); gen->core = &OSCIL_BANK_CLASS; gen->orig_size = size; gen->size = size; gen->amps = amps; gen->freqs = freqs; gen->phases = phases; gen->free_phases = false; gen->ob_func = oscil_bank; #if HAVE_SINCOS if (stable) { int i; double s, c; gen->ob_func = stable_oscil_bank; gen->use_sc = false; gen->sn1 = (double *)malloc(size * sizeof(double)); gen->sn2 = (double *)malloc(size * sizeof(double)); gen->cs1 = (double *)malloc(size * sizeof(double)); gen->cs2 = (double *)malloc(size * sizeof(double)); gen->phs = (double *)malloc(size * sizeof(double)); for (i = 0; i < size; i++) { sincos(freqs[i], &s, &c); if (amps) { s *= amps[i]; c *= amps[i]; } gen->sn1[i] = s; gen->cs1[i] = c; gen->phs[i] = freqs[i] * 2.0; } } else { gen->sn1 = NULL; gen->sn2 = NULL; gen->cs1 = NULL; gen->cs2 = NULL; gen->phs = NULL; } #endif return((mus_any *)gen); } /* ---------------- ncos ---------------- */ typedef struct { mus_any_class *core; int n; mus_float_t scaler, cos5, phase, freq; } cosp; #define DIVISOR_NEAR_ZERO(Den) (fabs(Den) < 1.0e-14) mus_float_t mus_ncos(mus_any *ptr, mus_float_t fm) { /* changed 25-Apr-04: use less stupid formula */ /* (/ (- (/ (sin (* (+ n 0.5) angle)) (* 2 (sin (* 0.5 angle)))) 0.5) n) */ mus_float_t val, den; cosp *gen = (cosp *)ptr; den = sin(gen->phase * 0.5); if (DIVISOR_NEAR_ZERO(den)) /* see note -- this was den == 0.0 1-Aug-07 */ /* perhaps use DBL_EPSILON (1.0e-9 I think) */ val = 1.0; else { val = (gen->scaler * (((sin(gen->phase * gen->cos5)) / (2.0 * den)) - 0.5)); if (val > 1.0) val = 1.0; /* I think this can't happen now that we check den above, but just in case... */ /* this check is actually incomplete, since we can be much below the correct value also, but the den check should fix those cases too */ } gen->phase += (gen->freq + fm); return((mus_float_t)val); } /* I think we could add ncos_pm via: * * mus_float_t mus_ncos_pm(mus_any *ptr, mus_float_t fm, mus_float_t pm) * { * cosp *gen = (cosp *)ptr; * mus_float_t result; * gen->phase += pm; * result = mus_ncos(ptr, fm); * gen->phase -= pm; * return(result); * } * * and the same trick could add pm to anything: * * mus_float_t mus_run_with_pm(mus_any *ptr, mus_float_t fm, mus_float_t pm) * { * mus_float_t result; * mus_set_phase(ptr, mus_phase(ptr) + pm); * result = mus_run(ptr, fm, 0.0); * mus_set_phase (ptr, mus_phase(ptr) - pm); * return(result); * } * * fm could also be handled here so the 4 cases become gen, mus_run_with_fm|pm|fm_and_pm(gen) * but... this could just as well happen at the extension language level, except that run doesn't expand macros? * The problem with differentiating the pm and using the fm arg is that we'd need a closure. */ #if 0 /* if the current phase is close to 0.0, there were numerical troubles here: :(/ (cos (* 1.5 pi 1.0000000000000007)) (cos (* 0.5 pi 1.0000000000000007))) -3.21167411694788 :(/ (cos (* 1.5 pi 1.0000000000000004)) (cos (* 0.5 pi 1.0000000000000004))) -2.63292557243357 :(/ (cos (* 1.5 pi 1.0000000000000002)) (cos (* 0.5 pi 1.0000000000000002))) -1.84007079646018 :(/ (cos (* 1.5 pi 1.0000000000000001)) (cos (* 0.5 pi 1.0000000000000001))) -3.0 :(/ (cos (* 1.5 pi 1.0000000000000008)) (cos (* 0.5 pi 1.0000000000000008))) -3.34939116712516 ;; 16 bits in is probably too much for mus_float_ts ;; these numbers can be hit in normal cases: (define (ncos-with-inversions n x) ;; Andrews Askey Roy 261 (let* ((num (cos (* x (+ 0.5 n)))) (den (cos (* x 0.5))) (val (/ num den))) ; Chebyshev polynomial of the third kind! (4th uses sin = our current formula) (/ (- (if (even? n) val (- val)) 0.5) (+ 1 (* n 2))))) (with-sound (:scaled-to 1.0) (do ((i 0 (1+ i)) (x 0.0 (+ x .01))) ((= i 200)) ; glitch at 100 (= 1) (outa i (ncos-with-inversions 1 (* pi x)) *output*))) */ #endif bool mus_is_ncos(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_NCOS)); } static void free_ncos(mus_any *ptr) {free(ptr);} static void ncos_reset(mus_any *ptr) {((cosp *)ptr)->phase = 0.0;} static mus_float_t ncos_freq(mus_any *ptr) {return(mus_radians_to_hz(((cosp *)ptr)->freq));} static mus_float_t ncos_set_freq(mus_any *ptr, mus_float_t val) {((cosp *)ptr)->freq = mus_hz_to_radians(val); return(val);} static mus_float_t ncos_increment(mus_any *ptr) {return(((cosp *)ptr)->freq);} static mus_float_t ncos_set_increment(mus_any *ptr, mus_float_t val) {((cosp *)ptr)->freq = val; return(val);} static mus_float_t ncos_phase(mus_any *ptr) {return(fmod(((cosp *)ptr)->phase, TWO_PI));} static mus_float_t ncos_set_phase(mus_any *ptr, mus_float_t val) {((cosp *)ptr)->phase = val; return(val);} static mus_float_t ncos_scaler(mus_any *ptr) {return(((cosp *)ptr)->scaler);} static mus_float_t ncos_set_scaler(mus_any *ptr, mus_float_t val) {((cosp *)ptr)->scaler = val; return(val);} static mus_long_t ncos_n(mus_any *ptr) {return(((cosp *)ptr)->n);} static mus_any *cosp_copy(mus_any *ptr) { cosp *g; g = (cosp *)malloc(sizeof(cosp)); memcpy((void *)g, (void *)ptr, sizeof(cosp)); return((mus_any *)g); } static mus_long_t ncos_set_n(mus_any *ptr, mus_long_t val) { cosp *gen = (cosp *)ptr; if (val > 0) { gen->n = (int)val; gen->cos5 = val + 0.5; gen->scaler = 1.0 / (mus_float_t)val; } return(val); } static mus_float_t run_ncos(mus_any *ptr, mus_float_t fm, mus_float_t unused) {return(mus_ncos(ptr, fm));} static bool ncos_equalp(mus_any *p1, mus_any *p2) { return((p1 == p2) || ((mus_is_ncos((mus_any *)p1)) && (mus_is_ncos((mus_any *)p2)) && ((((cosp *)p1)->freq) == (((cosp *)p2)->freq)) && ((((cosp *)p1)->phase) == (((cosp *)p2)->phase)) && ((((cosp *)p1)->n) == (((cosp *)p2)->n)) && ((((cosp *)p1)->scaler) == (((cosp *)p2)->scaler)))); } static char *describe_ncos(mus_any *ptr) { char *describe_buffer; describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE); snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s freq: %.3fHz, phase: %.3f, n: %d", mus_name(ptr), mus_frequency(ptr), mus_phase(ptr), (int)mus_order(ptr)); return(describe_buffer); } static mus_any_class NCOS_CLASS = { MUS_NCOS, (char *)S_ncos, &free_ncos, &describe_ncos, &ncos_equalp, 0, 0, /* data */ &ncos_n, &ncos_set_n, &ncos_freq, &ncos_set_freq, &ncos_phase, &ncos_set_phase, &ncos_scaler, &ncos_set_scaler, &ncos_increment, &ncos_set_increment, &run_ncos, MUS_NOT_SPECIAL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &ncos_reset, 0, &cosp_copy }; mus_any *mus_make_ncos(mus_float_t freq, int n) { cosp *gen; gen = (cosp *)malloc(sizeof(cosp)); gen->core = &NCOS_CLASS; if (n == 0) n = 1; gen->scaler = 1.0 / (mus_float_t)n; gen->n = n; gen->cos5 = n + 0.5; gen->freq = mus_hz_to_radians(freq); gen->phase = 0.0; return((mus_any *)gen); } /* ---------------- nsin ---------------- */ static bool nsin_equalp(mus_any *p1, mus_any *p2) { return((p1 == p2) || ((mus_is_nsin((mus_any *)p1)) && (mus_is_nsin((mus_any *)p2)) && ((((cosp *)p1)->freq) == (((cosp *)p2)->freq)) && ((((cosp *)p1)->phase) == (((cosp *)p2)->phase)) && ((((cosp *)p1)->n) == (((cosp *)p2)->n)) && ((((cosp *)p1)->scaler) == (((cosp *)p2)->scaler)))); } static char *describe_nsin(mus_any *ptr) { char *describe_buffer; describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE); snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s freq: %.3fHz, phase: %.3f, n: %d", mus_name(ptr), mus_frequency(ptr), mus_phase(ptr), (int)mus_order(ptr)); return(describe_buffer); } bool mus_is_nsin(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_NSIN)); } #if 0 /* its simplest to get the maxes by running an example and recording the maxamp, but it also * works for small "n" to use the derivative of the sum-of-sines as a Chebyshev polynomial in cos x, * find its roots, and plug acos(root) into the original, recording the max: * (define (smax coeffs) (let* ((n (vct-length coeffs)) (dcos (make-vct n 1.0))) (do ((i 0 (1+ i))) ((= i n)) (vct-set! dcos i (* (+ i 1) (vct-ref coeffs i)))) (let ((partials ())) (do ((i 0 (1+ i))) ((= i n)) (set! partials (append (list (vct-ref dcos i) (+ i 1)) partials))) (let ((Tn (partials->polynomial (reverse partials)))) (let ((roots (poly-roots Tn))) (let ((mx (* -2 n))) (for-each (lambda (root) (let ((acr (acos root)) (sum 0.0)) (do ((i 0 (1+ i))) ((= i n)) (set! sum (+ sum (* (vct-ref coeffs i) (sin (* (+ i 1) acr)))))) (if (> (abs sum) mx) (set! mx (abs sum))))) roots) mx)))))) (smax (make-vct n 1.0)) * but that's too much effort for an initialization function. * much faster is this search (it usually hits an answer in 2 or 3 tries): * (define (find-nsin-max n) (define (ns x n) (let* ((a2 (/ x 2)) (den (sin a2))) (if (= den 0.0) 0.0 (/ (* (sin (* n a2)) (sin (* (1+ n) a2))) den)))) (define (find-mid-max n lo hi) (let ((mid (/ (+ lo hi) 2))) (let ((ylo (ns lo n)) (yhi (ns hi n))) (if (< (abs (- ylo yhi)) 1e-100) (list (ns mid n) (rationalize (/ mid pi) 0.0)) (if (> ylo yhi) (find-mid-max n lo mid) (find-mid-max n mid hi)))))) (find-mid-max n 0.0 (/ pi (+ n .5)))) * * the 'mid' point has a surprisingly simple relation to pi: * * (find-max 100000000000000) * 7.24518620297426541161857919764185053934850053037407235e13 * * (find-max 1000000000000000000000000) * 7.24518620297422918568756794921595308358209723004380140e23 1/1333333333333333333333334 = .75e-24 -> (3*pi)/(4*n) * * (find-max 10000000000000000000000000000000000) * 7.24518620297422918568756432662285195872681453497436666955413707681801083640192066844820049586929551886747925783e33 * * which is approximately (/ (* 8 (expt (sin (* pi 3/8)) 2)) (* 3 pi)): * 7.245186202974229185687564326622851596467504 * * (to get that expression, plug in 3pi/4n, treat (n+1)/n as essentially 1 as n gets very large, * treat (sin x) as about x when x is very small, and simplify) * so if n>10, we could use (ns (/ (* 3 pi) (* 4 n)) n) without major error * It's possible to differentiate the nsin formula: * * -(cos(x/2)sin(nx/2)sin((n+1)x/2))/(2sin^2(x/2)) + ncos(nx/2)sin((n+1)x/2)/(2sin(x/2)) + (n+1)sin(nx/2)cos((n+1)x/2)/(2sin(x/2)) * * and find the first 0 when n is very large -- it is very close to 3pi/(4*n) */ #endif static mus_float_t nsin_ns(mus_float_t x, int n) { mus_float_t a2, den; a2 = x / 2; den = sin(a2); if (den == 0.0) return(0.0); return(sin(n * a2) * sin((n + 1) * a2) / den); } static mus_float_t find_nsin_scaler(int n, mus_float_t lo, mus_float_t hi) { mus_float_t mid, ylo, yhi; mid = (lo + hi) / 2; ylo = nsin_ns(lo, n); yhi = nsin_ns(hi, n); if (fabs(ylo - yhi) < 1e-12) return(nsin_ns(mid, n)); if (ylo > yhi) return(find_nsin_scaler(n, lo, mid)); return(find_nsin_scaler(n, mid, hi)); } static mus_float_t nsin_scaler(int n) { return(1.0 / find_nsin_scaler(n, 0.0, M_PI / (n + 0.5))); } static mus_long_t nsin_set_n(mus_any *ptr, mus_long_t val) { cosp *gen = (cosp *)ptr; gen->n = (int)val; gen->cos5 = val + 1.0; gen->scaler = nsin_scaler((int)val); return(val); } mus_float_t mus_nsin(mus_any *ptr, mus_float_t fm) { /* (let* ((a2 (* angle 0.5)) (den (sin a2))) (if (= den 0.0) 0.0 (/ (* (sin (* n a2)) (sin (* (1+ n) a2))) den))) */ #if HAVE_SINCOS double val, a2, ns, nc, s, c; cosp *gen = (cosp *)ptr; a2 = gen->phase * 0.5; sincos(a2, &s, &c); if (DIVISOR_NEAR_ZERO(s)) /* see note under ncos */ val = 0.0; else { sincos(gen->n * a2, &ns, &nc); val = gen->scaler * ns * (ns * c + nc * s) / s; } #else mus_float_t val, den, a2; cosp *gen = (cosp *)ptr; a2 = gen->phase * 0.5; den = sin(a2); if (DIVISOR_NEAR_ZERO(den)) /* see note under ncos */ val = 0.0; else val = gen->scaler * sin(gen->n * a2) * sin(a2 * gen->cos5) / den; #endif gen->phase += (gen->freq + fm); return((mus_float_t)val); } static mus_float_t run_nsin(mus_any *ptr, mus_float_t fm, mus_float_t unused) {return(mus_nsin(ptr, fm));} static mus_any_class NSIN_CLASS = { MUS_NSIN, (char *)S_nsin, &free_ncos, &describe_nsin, &nsin_equalp, 0, 0, /* data */ &ncos_n, &nsin_set_n, &ncos_freq, &ncos_set_freq, &ncos_phase, &ncos_set_phase, &ncos_scaler, &ncos_set_scaler, &ncos_increment, &ncos_set_increment, &run_nsin, MUS_NOT_SPECIAL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &ncos_reset, 0, &cosp_copy }; mus_any *mus_make_nsin(mus_float_t freq, int n) { cosp *gen; gen = (cosp *)mus_make_ncos(freq, n); gen->core = &NSIN_CLASS; gen->scaler = nsin_scaler(n); gen->cos5 = gen->n + 1.0; return((mus_any *)gen); } /* ---------------- asymmetric-fm ---------------- */ /* changed from sin(sin) to cos(sin) and added amplitude normalization 6-Sep-07 */ typedef struct { mus_any_class *core; mus_float_t r; mus_float_t freq, phase; mus_float_t ratio; mus_float_t cosr, sinr; mus_float_t one; } asyfm; static void free_asymmetric_fm(mus_any *ptr) {free(ptr);} static void asyfm_reset(mus_any *ptr) {((asyfm *)ptr)->phase = 0.0;} static mus_any *asyfm_copy(mus_any *ptr) { asyfm *g; g = (asyfm *)malloc(sizeof(asyfm)); memcpy((void *)g, (void *)ptr, sizeof(asyfm)); return((mus_any *)g); } static mus_float_t asyfm_freq(mus_any *ptr) {return(mus_radians_to_hz(((asyfm *)ptr)->freq));} static mus_float_t asyfm_set_freq(mus_any *ptr, mus_float_t val) {((asyfm *)ptr)->freq = mus_hz_to_radians(val); return(val);} static mus_float_t asyfm_increment(mus_any *ptr) {return(((asyfm *)ptr)->freq);} static mus_float_t asyfm_set_increment(mus_any *ptr, mus_float_t val) {((asyfm *)ptr)->freq = val; return(val);} static mus_float_t asyfm_phase(mus_any *ptr) {return(fmod(((asyfm *)ptr)->phase, TWO_PI));} static mus_float_t asyfm_set_phase(mus_any *ptr, mus_float_t val) {((asyfm *)ptr)->phase = val; return(val);} static mus_float_t asyfm_ratio(mus_any *ptr) {return(((asyfm *)ptr)->ratio);} static mus_float_t asyfm_r(mus_any *ptr) {return(((asyfm *)ptr)->r);} static mus_float_t asyfm_set_r(mus_any *ptr, mus_float_t val) { asyfm *gen = (asyfm *)ptr; if (val != 0.0) { gen->r = val; gen->cosr = 0.5 * (val - (1.0 / val)); gen->sinr = 0.5 * (val + (1.0 / val)); if ((val > 1.0) || ((val < 0.0) && (val > -1.0))) gen->one = -1.0; else gen->one = 1.0; } return(val); } static bool asyfm_equalp(mus_any *p1, mus_any *p2) { return((p1 == p2) || (((p1->core)->type == (p2->core)->type) && ((((asyfm *)p1)->freq) == (((asyfm *)p2)->freq)) && ((((asyfm *)p1)->phase) == (((asyfm *)p2)->phase)) && ((((asyfm *)p1)->ratio) == (((asyfm *)p2)->ratio)) && ((((asyfm *)p1)->r) == (((asyfm *)p2)->r)))); } static char *describe_asyfm(mus_any *ptr) { char *describe_buffer; describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE); snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s freq: %.3fHz, phase: %.3f, ratio: %.3f, r: %.3f", mus_name(ptr), mus_frequency(ptr), mus_phase(ptr), ((asyfm *)ptr)->ratio, asyfm_r(ptr)); return(describe_buffer); } bool mus_is_asymmetric_fm(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_ASYMMETRIC_FM)); } mus_float_t mus_asymmetric_fm(mus_any *ptr, mus_float_t index, mus_float_t fm) { asyfm *gen = (asyfm *)ptr; mus_float_t result; mus_float_t mth; mth = gen->ratio * gen->phase; result = exp(index * gen->cosr * (gen->one + cos(mth))) * cos(gen->phase + index * gen->sinr * sin(mth)); /* second index factor added 4-Mar-02 and (+/-)1.0 + cos to normalize amps 6-Sep-07 */ gen->phase += (gen->freq + fm); return(result); } mus_float_t mus_asymmetric_fm_unmodulated(mus_any *ptr, mus_float_t index) { asyfm *gen = (asyfm *)ptr; mus_float_t result, mth; mth = gen->ratio * gen->phase; result = exp(index * gen->cosr * (gen->one + cos(mth))) * cos(gen->phase + index * gen->sinr * sin(mth)); /* second index factor added 4-Mar-02 */ gen->phase += gen->freq; return(result); } static mus_any_class ASYMMETRIC_FM_CLASS = { MUS_ASYMMETRIC_FM, (char *)S_asymmetric_fm, &free_asymmetric_fm, &describe_asyfm, &asyfm_equalp, 0, 0, 0, 0, &asyfm_freq, &asyfm_set_freq, &asyfm_phase, &asyfm_set_phase, &asyfm_r, &asyfm_set_r, &asyfm_increment, &asyfm_set_increment, &mus_asymmetric_fm, MUS_NOT_SPECIAL, NULL, 0, &asyfm_ratio, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &asyfm_reset, 0, &asyfm_copy }; mus_any *mus_make_asymmetric_fm(mus_float_t freq, mus_float_t phase, mus_float_t r, mus_float_t ratio) /* r default 1.0, ratio 1.0 */ { asyfm *gen = NULL; if (r == 0.0) mus_error(MUS_ARG_OUT_OF_RANGE, S_make_asymmetric_fm ": r can't be 0.0"); else { gen = (asyfm *)malloc(sizeof(asyfm)); gen->core = &ASYMMETRIC_FM_CLASS; gen->freq = mus_hz_to_radians(freq); gen->phase = phase; gen->r = r; gen->ratio = ratio; gen->cosr = 0.5 * (r - (1.0 / r)); /* 0.5 factor for I/2 */ gen->sinr = 0.5 * (r + (1.0 / r)); if ((r > 1.0) || ((r < 0.0) && (r > -1.0))) gen->one = -1.0; else gen->one = 1.0; } return((mus_any *)gen); } /*---------------- nrxysin (sine-summation) and nrxycos ---------------- */ /* the generator uses x and y (frequencies), but it's very common to start up with 0 freqs * and let the fm arg set the frequency, so it seems like we want to give the ratio between * the frequencies at make time, rather than two (possibly dummy) frequencies). * xy-ratio negative to build (via r) backwards. */ #define MAX_R 0.999999 #define MIN_R -0.999999 typedef struct { mus_any_class *core; mus_float_t freq, phase; int n; mus_float_t norm, r, r_to_n_plus_1, r_squared_plus_1, y_over_x; } nrxy; static void free_nrxy(mus_any *ptr) {free(ptr);} static void nrxy_reset(mus_any *ptr) {((nrxy *)ptr)->phase = 0.0;} static mus_any *nrxy_copy(mus_any *ptr) { nrxy *g; g = (nrxy *)malloc(sizeof(nrxy)); memcpy((void *)g, (void *)ptr, sizeof(nrxy)); return((mus_any *)g); } static mus_float_t nrxy_freq(mus_any *ptr) {return(mus_radians_to_hz(((nrxy *)ptr)->freq));} static mus_float_t nrxy_set_freq(mus_any *ptr, mus_float_t val) {((nrxy *)ptr)->freq = mus_hz_to_radians(val); return(val);} static mus_float_t nrxy_increment(mus_any *ptr) {return(((nrxy *)ptr)->freq);} static mus_float_t nrxy_set_increment(mus_any *ptr, mus_float_t val) {((nrxy *)ptr)->freq = val; return(val);} static mus_float_t nrxy_phase(mus_any *ptr) {return(fmod(((nrxy *)ptr)->phase, TWO_PI));} static mus_float_t nrxy_set_phase(mus_any *ptr, mus_float_t val) {((nrxy *)ptr)->phase = val; return(val);} static mus_long_t nrxy_n(mus_any *ptr) {return((mus_long_t)(((nrxy *)ptr)->n));} static mus_float_t nrxy_y_over_x(mus_any *ptr) {return(((nrxy *)ptr)->y_over_x);} static mus_float_t nrxy_set_y_over_x(mus_any *ptr, mus_float_t val) {((nrxy *)ptr)->y_over_x = val; return(val);} static mus_float_t nrxy_r(mus_any *ptr) {return(((nrxy *)ptr)->r);} static mus_float_t nrxy_set_r(mus_any *ptr, mus_float_t r) { nrxy *gen = (nrxy *)ptr; int n; n = gen->n; if (r > MAX_R) r = MAX_R; if (r < MIN_R) r = MIN_R; gen->r = r; gen->r_to_n_plus_1 = pow(r, n + 1); gen->r_squared_plus_1 = 1.0 + r * r; if (n == 0) gen->norm = 1.0; else gen->norm = (pow(fabs(r), n + 1) - 1.0) / (fabs(r) - 1.0); /* fabs here because if r<0.0, we line up at (2k-1)*pi rather than 2k*pi, but * otherwise the waveform is identical */ return(r); } static bool nrxy_equalp(mus_any *p1, mus_any *p2) { nrxy *g1 = (nrxy *)p1; nrxy *g2 = (nrxy *)p2; return((p1 == p2) || (((g1->core)->type == (g2->core)->type) && (g1->freq == g2->freq) && (g1->phase == g2->phase) && (g1->n == g2->n) && (g1->r == g2->r) && (g1->y_over_x == g2->y_over_x))); } bool mus_is_nrxysin(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_NRXYSIN)); } static char *describe_nrxysin(mus_any *ptr) { nrxy *gen = (nrxy *)ptr; char *describe_buffer; describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE); snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s frequency: %.3f, ratio: %.3f, phase: %.3f, n: %d, r: %.3f", mus_name(ptr), mus_frequency(ptr), gen->y_over_x, mus_phase(ptr), gen->n, nrxy_r(ptr)); return(describe_buffer); } mus_float_t mus_nrxysin(mus_any *ptr, mus_float_t fm) { /* Jolley 475 but 0..n rather than 0..n-1 */ /* see also Durell and Robson "Advanced Trigonometry" p 175 */ nrxy *gen = (nrxy *)ptr; mus_float_t x, y, r, divisor; int n; x = gen->phase; n = gen->n; r = gen->r; gen->phase += (gen->freq + fm); if (gen->y_over_x == 1.0) { #if (!HAVE_SINCOS) divisor = gen->norm * (gen->r_squared_plus_1 - (2 * r * cos(x))); if (DIVISOR_NEAR_ZERO(divisor)) return(0.0); return((sin(x) - gen->r_to_n_plus_1 * (sin(x * (n + 2)) - r * sin(x * (n + 1)))) / divisor); #else double sx, cx, snx, cnx; sincos(x, &sx, &cx); divisor = gen->norm * (gen->r_squared_plus_1 - (2 * r * cx)); if (DIVISOR_NEAR_ZERO(divisor)) return(0.0); sincos((n + 1) * x, &snx, &cnx); return((sx - gen->r_to_n_plus_1 * (sx * cnx + (cx - r) * snx)) / divisor); #endif } #if HAVE_SINCOS { double xs, xc, ys, yc, nys, nyc, sin_x_y, sin_x_ny, sin_x_n1y, cos_x_ny; y = x * gen->y_over_x; sincos(y, &ys, &yc); divisor = gen->norm * (gen->r_squared_plus_1 - (2 * r * yc)); if (DIVISOR_NEAR_ZERO(divisor)) return(0.0); sincos(x, &xs, &xc); sincos(n * y, &nys, &nyc); sin_x_y = (xs * yc - ys * xc); sin_x_ny = (xs * nyc + nys * xc); cos_x_ny = (xc * nyc - xs * nys); sin_x_n1y = (sin_x_ny * yc + cos_x_ny * ys); return((xs - r * sin_x_y - gen->r_to_n_plus_1 * (sin_x_n1y - r * sin_x_ny)) / divisor); } #else y = x * gen->y_over_x; divisor = gen->norm * (gen->r_squared_plus_1 - (2 * r * cos(y))); if (DIVISOR_NEAR_ZERO(divisor)) return(0.0); return((sin(x) - r * sin(x - y) - gen->r_to_n_plus_1 * (sin(x + (n + 1) * y) - r * sin(x + n * y))) / divisor); #endif } static mus_float_t run_nrxysin(mus_any *ptr, mus_float_t fm, mus_float_t unused) {return(mus_nrxysin(ptr, fm));} static mus_any_class NRXYSIN_CLASS = { MUS_NRXYSIN, (char *)S_nrxysin, &free_nrxy, &describe_nrxysin, &nrxy_equalp, 0, 0, &nrxy_n, 0, &nrxy_freq, &nrxy_set_freq, &nrxy_phase, &nrxy_set_phase, &nrxy_r, &nrxy_set_r, &nrxy_increment, &nrxy_set_increment, &run_nrxysin, MUS_NOT_SPECIAL, NULL, 0, &nrxy_y_over_x, &nrxy_set_y_over_x, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &nrxy_reset, 0, &nrxy_copy }; mus_any *mus_make_nrxysin(mus_float_t frequency, mus_float_t y_over_x, int n, mus_float_t r) { nrxy *gen; gen = (nrxy *)malloc(sizeof(nrxy)); gen->core = &NRXYSIN_CLASS; gen->freq = mus_hz_to_radians(frequency); gen->y_over_x = y_over_x; gen->phase = 0.0; gen->n = n; nrxy_set_r((mus_any *)gen, r); return((mus_any *)gen); } bool mus_is_nrxycos(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_NRXYCOS)); } static char *describe_nrxycos(mus_any *ptr) { nrxy *gen = (nrxy *)ptr; char *describe_buffer; describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE); snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s frequency: %.3f, ratio: %.3f, phase: %.3f, n: %d, r: %.3f", mus_name(ptr), mus_frequency(ptr), gen->y_over_x, mus_phase(ptr), gen->n, nrxy_r(ptr)); return(describe_buffer); } mus_float_t mus_nrxycos(mus_any *ptr, mus_float_t fm) { nrxy *gen = (nrxy *)ptr; mus_float_t x, y, r, divisor; int n; x = gen->phase; y = x * gen->y_over_x; n = gen->n; r = gen->r; gen->phase += (gen->freq + fm); #if HAVE_SINCOS { double xs, xc, ys, yc, nys, nyc, cos_x_y, cos_x_ny, cos_x_n1y, sin_x_ny; sincos(y, &ys, &yc); divisor = gen->norm * (gen->r_squared_plus_1 - (2 * r * yc)); if (DIVISOR_NEAR_ZERO(divisor)) return(1.0); sincos(x, &xs, &xc); sincos(n * y, &nys, &nyc); cos_x_y = (xc * yc + ys * xs); sin_x_ny = (xs * nyc + nys * xc); cos_x_ny = (xc * nyc - xs * nys); cos_x_n1y = (cos_x_ny * yc - sin_x_ny * ys); return((xc - r * cos_x_y - gen->r_to_n_plus_1 * (cos_x_n1y - r * cos_x_ny)) / divisor); } #else divisor = gen->norm * (gen->r_squared_plus_1 - (2 * r * cos(y))); if (DIVISOR_NEAR_ZERO(divisor)) return(1.0); /* this can happen if r>0.9999999 or thereabouts; */ return((cos(x) - r * cos(x - y) - gen->r_to_n_plus_1 * (cos(x + (n + 1) * y) - r * cos(x + n * y))) / divisor); #endif } static mus_float_t run_nrxycos(mus_any *ptr, mus_float_t fm, mus_float_t unused) {return(mus_nrxycos(ptr, fm));} static mus_any_class NRXYCOS_CLASS = { MUS_NRXYCOS, (char *)S_nrxycos, &free_nrxy, &describe_nrxycos, &nrxy_equalp, 0, 0, &nrxy_n, 0, &nrxy_freq, &nrxy_set_freq, &nrxy_phase, &nrxy_set_phase, &nrxy_r, &nrxy_set_r, &nrxy_increment, &nrxy_set_increment, &run_nrxycos, MUS_NOT_SPECIAL, NULL, 0, &nrxy_y_over_x, &nrxy_set_y_over_x, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &nrxy_reset, 0, &nrxy_copy }; mus_any *mus_make_nrxycos(mus_float_t frequency, mus_float_t y_over_x, int n, mus_float_t r) { nrxy *gen; gen = (nrxy *)mus_make_nrxysin(frequency, y_over_x, n, r); gen->core = &NRXYCOS_CLASS; return((mus_any *)gen); } /* ---------------- rxykcos/sin ---------------- */ typedef struct { mus_any_class *core; mus_float_t r, ar; mus_float_t freq, phase; mus_float_t ratio; } rxyk; static void free_rxykcos(mus_any *ptr) {free(ptr);} static void rxyk_reset(mus_any *ptr) {((rxyk *)ptr)->phase = 0.0;} static mus_any *rxyk_copy(mus_any *ptr) { rxyk *g; g = (rxyk *)malloc(sizeof(rxyk)); memcpy((void *)g, (void *)ptr, sizeof(rxyk)); return((mus_any *)g); } static mus_float_t rxyk_freq(mus_any *ptr) {return(mus_radians_to_hz(((rxyk *)ptr)->freq));} static mus_float_t rxyk_set_freq(mus_any *ptr, mus_float_t val) {((rxyk *)ptr)->freq = mus_hz_to_radians(val); return(val);} static mus_float_t rxyk_increment(mus_any *ptr) {return(((rxyk *)ptr)->freq);} static mus_float_t rxyk_set_increment(mus_any *ptr, mus_float_t val) {((rxyk *)ptr)->freq = val; return(val);} static mus_float_t rxyk_phase(mus_any *ptr) {return(fmod(((rxyk *)ptr)->phase, TWO_PI));} static mus_float_t rxyk_set_phase(mus_any *ptr, mus_float_t val) {((rxyk *)ptr)->phase = val; return(val);} static mus_float_t rxyk_ratio(mus_any *ptr) {return(((rxyk *)ptr)->ratio);} static mus_float_t rxyk_r(mus_any *ptr) {return(((rxyk *)ptr)->r);} static mus_float_t rxyk_set_r(mus_any *ptr, mus_float_t val) { rxyk *gen = (rxyk *)ptr; gen->r = val; gen->ar = 1.0 / exp(fabs(val)); return(val); } static mus_float_t run_rxykcos(mus_any *ptr, mus_float_t fm, mus_float_t unused) {return(mus_rxykcos(ptr, fm));} static mus_float_t run_rxyksin(mus_any *ptr, mus_float_t fm, mus_float_t unused) {return(mus_rxyksin(ptr, fm));} static bool rxyk_equalp(mus_any *p1, mus_any *p2) { return((p1 == p2) || (((p1->core)->type == (p2->core)->type) && ((((rxyk *)p1)->freq) == (((rxyk *)p2)->freq)) && ((((rxyk *)p1)->phase) == (((rxyk *)p2)->phase)) && ((((rxyk *)p1)->ratio) == (((rxyk *)p2)->ratio)) && ((((rxyk *)p1)->r) == (((rxyk *)p2)->r)))); } static char *describe_rxyk(mus_any *ptr) { char *describe_buffer; describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE); snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s freq: %.3fHz, phase: %.3f, ratio: %.3f, r: %.3f", mus_name(ptr), mus_frequency(ptr), mus_phase(ptr), ((rxyk *)ptr)->ratio, rxyk_r(ptr)); return(describe_buffer); } bool mus_is_rxykcos(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_RXYKCOS)); } mus_float_t mus_rxykcos(mus_any *ptr, mus_float_t fm) { rxyk *gen = (rxyk *)ptr; mus_float_t result, rx; rx = gen->ratio * gen->phase; result = gen->ar * exp(gen->r * cos(rx)) * cos(gen->phase + (gen->r * sin(rx))); gen->phase += (fm + gen->freq); return(result); } static mus_any_class RXYKCOS_CLASS = { MUS_RXYKCOS, (char *)S_rxykcos, &free_rxykcos, &describe_rxyk, &rxyk_equalp, 0, 0, 0, 0, &rxyk_freq, &rxyk_set_freq, &rxyk_phase, &rxyk_set_phase, &rxyk_r, &rxyk_set_r, &rxyk_increment, &rxyk_set_increment, &run_rxykcos, MUS_NOT_SPECIAL, NULL, 0, &rxyk_ratio, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &rxyk_reset, 0, &rxyk_copy }; mus_any *mus_make_rxykcos(mus_float_t freq, mus_float_t phase, mus_float_t r, mus_float_t ratio) /* r default 0.5, ratio 1.0 */ { rxyk *gen = NULL; gen = (rxyk *)malloc(sizeof(rxyk)); gen->core = &RXYKCOS_CLASS; gen->freq = mus_hz_to_radians(freq); gen->phase = phase; gen->r = r; gen->ar = 1.0 / exp(fabs(r)); gen->ratio = ratio; return((mus_any *)gen); } bool mus_is_rxyksin(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_RXYKSIN)); } mus_float_t mus_rxyksin(mus_any *ptr, mus_float_t fm) { rxyk *gen = (rxyk *)ptr; mus_float_t result, rx; rx = gen->ratio * gen->phase; result = gen->ar * exp(gen->r * cos(rx)) * sin(gen->phase + (gen->r * sin(rx))); gen->phase += (fm + gen->freq); return(result); } static mus_any_class RXYKSIN_CLASS = { MUS_RXYKSIN, (char *)S_rxyksin, &free_rxykcos, &describe_rxyk, &rxyk_equalp, 0, 0, 0, 0, &rxyk_freq, &rxyk_set_freq, &rxyk_phase, &rxyk_set_phase, &rxyk_r, &rxyk_set_r, &rxyk_increment, &rxyk_set_increment, &run_rxyksin, MUS_NOT_SPECIAL, NULL, 0, &rxyk_ratio, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &rxyk_reset, 0, &rxyk_copy }; mus_any *mus_make_rxyksin(mus_float_t freq, mus_float_t phase, mus_float_t r, mus_float_t ratio) /* r default 0.5, ratio 1.0 */ { rxyk *gen = NULL; gen = (rxyk *)malloc(sizeof(rxyk)); gen->core = &RXYKSIN_CLASS; gen->freq = mus_hz_to_radians(freq); gen->phase = phase; gen->r = r; gen->ar = 1.0 / exp(fabs(r)); gen->ratio = ratio; return((mus_any *)gen); } /* ---------------- table lookup ---------------- */ typedef struct { mus_any_class *core; mus_float_t freq, internal_mag, phase; mus_float_t *table; mus_long_t table_size; mus_interp_t type; bool table_allocated; mus_float_t yn1; mus_float_t (*tbl_look)(mus_any *ptr, mus_float_t fm); mus_float_t (*tbl_look_unmod)(mus_any *ptr); } tbl; mus_float_t *mus_partials_to_wave(mus_float_t *partial_data, int partials, mus_float_t *table, mus_long_t table_size, bool normalize) { int partial, k; if (!table) return(NULL); memset((void *)table, 0, table_size * sizeof(mus_float_t)); for (partial = 0, k = 1; partial < partials; partial++, k += 2) { mus_float_t amp; amp = partial_data[k]; if (amp != 0.0) { mus_long_t i; mus_float_t freq, angle; freq = (partial_data[partial * 2] * TWO_PI) / (mus_float_t)table_size; for (i = 0, angle = 0.0; i < table_size; i++, angle += freq) table[i] += amp * sin(angle); } } if (normalize) return(array_normalize(table, table_size)); return(table); } mus_float_t *mus_phase_partials_to_wave(mus_float_t *partial_data, int partials, mus_float_t *table, mus_long_t table_size, bool normalize) { int partial, k, n; if (!table) return(NULL); memset((void *)table, 0, table_size * sizeof(mus_float_t)); for (partial = 0, k = 1, n = 2; partial < partials; partial++, k += 3, n += 3) { mus_float_t amp; amp = partial_data[k]; if (amp != 0.0) { mus_long_t i; mus_float_t freq, angle; freq = (partial_data[partial * 3] * TWO_PI) / (mus_float_t)table_size; for (i = 0, angle = partial_data[n]; i < table_size; i++, angle += freq) table[i] += amp * sin(angle); } } if (normalize) return(array_normalize(table, table_size)); return(table); } mus_float_t mus_table_lookup(mus_any *ptr, mus_float_t fm) { return(((tbl *)ptr)->tbl_look(ptr, fm)); } static mus_float_t table_look_linear(mus_any *ptr, mus_float_t fm) { tbl *gen = (tbl *)ptr; /* we're checking already for out-of-range indices, so mus_array_interp is more than we need */ mus_long_t int_part; mus_float_t frac_part, f1; int_part = (mus_long_t)(gen->phase); /* floor(gen->phase) -- slow! modf is even worse */ frac_part = gen->phase - int_part; f1 = gen->table[int_part]; int_part++; if (int_part == gen->table_size) gen->yn1 = f1 + frac_part * (gen->table[0] - f1); else gen->yn1 = f1 + frac_part * (gen->table[int_part] - f1); gen->phase += (gen->freq + (fm * gen->internal_mag)); if ((gen->phase >= gen->table_size) || (gen->phase < 0.0)) { gen->phase = fmod(gen->phase, gen->table_size); if (gen->phase < 0.0) gen->phase += gen->table_size; } return(gen->yn1); } static mus_float_t table_look_any(mus_any *ptr, mus_float_t fm) { tbl *gen = (tbl *)ptr; gen->yn1 = mus_interpolate(gen->type, gen->phase, gen->table, gen->table_size, gen->yn1); gen->phase += (gen->freq + (fm * gen->internal_mag)); if ((gen->phase >= gen->table_size) || (gen->phase < 0.0)) { gen->phase = fmod(gen->phase, gen->table_size); if (gen->phase < 0.0) gen->phase += gen->table_size; } return(gen->yn1); } mus_float_t mus_table_lookup_unmodulated(mus_any *ptr) { return(((tbl *)ptr)->tbl_look_unmod(ptr)); } static mus_float_t table_look_unmodulated_linear(mus_any *ptr) { tbl *gen = (tbl *)ptr; mus_long_t int_part; mus_float_t frac_part, f1; int_part = (mus_long_t)(gen->phase); frac_part = gen->phase - int_part; f1 = gen->table[int_part]; int_part++; if (int_part == gen->table_size) f1 += frac_part * (gen->table[0] - f1); else f1 += frac_part * (gen->table[int_part] - f1); gen->phase += gen->freq; if ((gen->phase >= gen->table_size) || (gen->phase < 0.0)) { gen->phase = fmod(gen->phase, gen->table_size); if (gen->phase < 0.0) gen->phase += gen->table_size; } return(f1); } static mus_float_t table_look_unmodulated_any(mus_any *ptr) { tbl *gen = (tbl *)ptr; gen->yn1 = mus_interpolate(gen->type, gen->phase, gen->table, gen->table_size, gen->yn1); gen->phase += gen->freq; if ((gen->phase >= gen->table_size) || (gen->phase < 0.0)) { gen->phase = fmod(gen->phase, gen->table_size); if (gen->phase < 0.0) gen->phase += gen->table_size; } return(gen->yn1); } static mus_float_t run_table_lookup(mus_any *ptr, mus_float_t fm, mus_float_t unused) {return(((tbl *)ptr)->tbl_look(ptr, fm)); } bool mus_is_table_lookup(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_TABLE_LOOKUP)); } static mus_long_t table_lookup_length(mus_any *ptr) {return(((tbl *)ptr)->table_size);} static mus_float_t *table_lookup_data(mus_any *ptr) {return(((tbl *)ptr)->table);} static mus_float_t table_lookup_freq(mus_any *ptr) {return((((tbl *)ptr)->freq * sampling_rate) / (((tbl *)ptr)->table_size));} static mus_float_t table_lookup_set_freq(mus_any *ptr, mus_float_t val) {((tbl *)ptr)->freq = (val * ((tbl *)ptr)->table_size) / sampling_rate; return(val);} static mus_float_t table_lookup_increment(mus_any *ptr) {return(((tbl *)ptr)->freq);} static mus_float_t table_lookup_set_increment(mus_any *ptr, mus_float_t val) {((tbl *)ptr)->freq = val; return(val);} static mus_float_t table_lookup_phase(mus_any *ptr) {return(fmod(((TWO_PI * ((tbl *)ptr)->phase) / ((tbl *)ptr)->table_size), TWO_PI));} static mus_float_t table_lookup_set_phase(mus_any *ptr, mus_float_t val) {((tbl *)ptr)->phase = (val * ((tbl *)ptr)->table_size) / TWO_PI; return(val);} static int table_lookup_interp_type(mus_any *ptr) {return((int)(((tbl *)ptr)->type));} /* ints here and elsewhere to fit mus_channels method = interp-type */ static void table_lookup_reset(mus_any *ptr) {((tbl *)ptr)->phase = 0.0;} static char *describe_table_lookup(mus_any *ptr) { char *describe_buffer; describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE); snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s freq: %.3fHz, phase: %.3f, length: %d, interp: %s", mus_name(ptr), mus_frequency(ptr), mus_phase(ptr), (int)mus_length(ptr), interp_type_to_string(table_lookup_interp_type(ptr))); return(describe_buffer); } static bool table_lookup_equalp(mus_any *p1, mus_any *p2) { tbl *t1 = (tbl *)p1; tbl *t2 = (tbl *)p2; if (p1 == p2) return(true); return((t1) && (t2) && (t1->core->type == t2->core->type) && (t1->table_size == t2->table_size) && (t1->freq == t2->freq) && (t1->phase == t2->phase) && (t1->type == t2->type) && (t1->internal_mag == t2->internal_mag) && (clm_arrays_are_equal(t1->table, t2->table, t1->table_size))); } static void free_table_lookup(mus_any *ptr) { tbl *gen = (tbl *)ptr; if ((gen->table) && (gen->table_allocated)) free(gen->table); free(gen); } static mus_any *tbl_copy(mus_any *ptr) { mus_long_t bytes; tbl *g, *p; p = (tbl *)ptr; g = (tbl *)malloc(sizeof(tbl)); memcpy((void *)g, (void *)ptr, sizeof(tbl)); bytes = g->table_size * sizeof(mus_float_t); g->table = (mus_float_t *)malloc(bytes); memcpy((void *)(g->table), (void *)(p->table), bytes); g->table_allocated = true; return((mus_any *)g); } static mus_float_t *table_set_data(mus_any *ptr, mus_float_t *val) { tbl *gen = (tbl *)ptr; if (gen->table_allocated) {free(gen->table); gen->table_allocated = false;} gen->table = val; return(val); } static mus_any_class TABLE_LOOKUP_CLASS = { MUS_TABLE_LOOKUP, (char *)S_table_lookup, &free_table_lookup, &describe_table_lookup, &table_lookup_equalp, &table_lookup_data, &table_set_data, &table_lookup_length, 0, &table_lookup_freq, &table_lookup_set_freq, &table_lookup_phase, &table_lookup_set_phase, &fallback_scaler, 0, &table_lookup_increment, &table_lookup_set_increment, &run_table_lookup, MUS_NOT_SPECIAL, NULL, &table_lookup_interp_type, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &table_lookup_reset, 0, &tbl_copy }; mus_any *mus_make_table_lookup(mus_float_t freq, mus_float_t phase, mus_float_t *table, mus_long_t table_size, mus_interp_t type) { tbl *gen; gen = (tbl *)malloc(sizeof(tbl)); gen->core = &TABLE_LOOKUP_CLASS; gen->table_size = table_size; gen->internal_mag = table_size / TWO_PI; gen->freq = (freq * table_size) / sampling_rate; gen->phase = (fmod(phase, TWO_PI) * table_size) / TWO_PI; gen->type = type; if (type == MUS_INTERP_LINEAR) { gen->tbl_look = table_look_linear; gen->tbl_look_unmod = table_look_unmodulated_linear; } else { gen->tbl_look = table_look_any; gen->tbl_look_unmod = table_look_unmodulated_any; } gen->yn1 = 0.0; if (table) { gen->table = table; gen->table_allocated = false; } else { gen->table = (mus_float_t *)calloc(table_size, sizeof(mus_float_t)); gen->table_allocated = true; } return((mus_any *)gen); } /* ---------------- polywave ---------------- */ mus_float_t *mus_partials_to_polynomial(int npartials, mus_float_t *partials, mus_polynomial_t kind) { /* coeffs returned in partials */ int i; mus_long_t *T0, *T1, *Tn; mus_float_t *Cc1; T0 = (mus_long_t *)calloc(npartials + 1, sizeof(mus_long_t)); T1 = (mus_long_t *)calloc(npartials + 1, sizeof(mus_long_t)); Tn = (mus_long_t *)calloc(npartials + 1, sizeof(mus_long_t)); Cc1 = (mus_float_t *)calloc(npartials + 1, sizeof(mus_float_t)); if (kind == MUS_CHEBYSHEV_FIRST_KIND) T0[0] = 1; else T0[0] = 0; T1[1] = 1; Cc1[0] = partials[0]; /* DC requested? */ for (i = 1; i < npartials; i++) { int k; mus_float_t amp; amp = partials[i]; if (amp != 0.0) { if (kind == MUS_CHEBYSHEV_FIRST_KIND) for (k = 0; k <= i; k++) Cc1[k] += (amp * T1[k]); else for (k = 1; k <= i; k++) Cc1[k - 1] += (amp * T1[k]); } for (k = i + 1; k > 0; k--) Tn[k] = (2 * T1[k - 1]) - T0[k]; Tn[0] = -T0[0]; for (k = i + 1; k >= 0; k--) { T0[k] = T1[k]; T1[k] = Tn[k]; } } for (i = 0; i < npartials; i++) partials[i] = Cc1[i]; free(T0); free(T1); free(Tn); free(Cc1); return(partials); } mus_float_t *mus_normalize_partials(int num_partials, mus_float_t *partials) { int i; mus_float_t sum = 0.0; for (i = 0; i < num_partials; i++) sum += fabs(partials[2 * i + 1]); if ((sum != 0.0) && (sum != 1.0)) { sum = 1.0 / sum; for (i = 0; i < num_partials; i++) partials[2 * i + 1] *= sum; } return(partials); } typedef struct { mus_any_class *core; mus_float_t phase, freq; mus_float_t *coeffs, *ucoeffs; int n, cheby_choice; mus_float_t index; mus_float_t (*polyw)(mus_any *ptr, mus_float_t fm); } pw; mus_float_t (*mus_polywave_function(mus_any *g))(mus_any *gen, mus_float_t fm) { if (mus_is_polywave(g)) return(((pw *)g)->polyw); return(NULL); } static void free_pw(mus_any *pt) {free(pt);} static mus_any *pw_copy(mus_any *ptr) { pw *g; g = (pw *)malloc(sizeof(pw)); memcpy((void *)g, (void *)ptr, sizeof(pw)); return((mus_any *)g); } static void pw_reset(mus_any *ptr) { pw *gen = (pw *)ptr; gen->phase = 0.0; } static bool pw_equalp(mus_any *p1, mus_any *p2) { pw *w1 = (pw *)p1; pw *w2 = (pw *)p2; if (p1 == p2) return(true); return((w1) && (w2) && (w1->core->type == w2->core->type) && (w1->freq == w2->freq) && (w1->phase == w2->phase) && (w1->n == w2->n) && (w1->index == w2->index) && (w1->cheby_choice == w2->cheby_choice) && (clm_arrays_are_equal(w1->coeffs, w2->coeffs, w1->n))); } static mus_float_t pw_freq(mus_any *ptr) {return(mus_radians_to_hz(((pw *)ptr)->freq));} static mus_float_t pw_set_freq(mus_any *ptr, mus_float_t val) {((pw *)ptr)->freq = mus_hz_to_radians(val); return(val);} static mus_float_t pw_increment(mus_any *ptr) {return(((pw *)ptr)->freq);} static mus_float_t pw_set_increment(mus_any *ptr, mus_float_t val) {((pw *)ptr)->freq = val; return(val);} static mus_float_t pw_phase(mus_any *ptr) {return(fmod(((pw *)ptr)->phase, TWO_PI));} static mus_float_t pw_set_phase(mus_any *ptr, mus_float_t val) {((pw *)ptr)->phase = val; return(val);} static mus_long_t pw_n(mus_any *ptr) {return(((pw *)ptr)->n);} static mus_long_t pw_set_n(mus_any *ptr, mus_long_t val) {((pw *)ptr)->n = (int)val; return(val);} static mus_float_t *pw_data(mus_any *ptr) {return(((pw *)ptr)->coeffs);} static mus_float_t *pw_udata(mus_any *ptr) {return(((pw *)ptr)->ucoeffs);} static mus_float_t *pw_set_data(mus_any *ptr, mus_float_t *val) {((pw *)ptr)->coeffs = val; return(val);} static mus_float_t pw_xcoeff(mus_any *ptr, int index) {return(((pw *)ptr)->coeffs[index]);} static mus_float_t pw_set_xcoeff(mus_any *ptr, int index, mus_float_t val) {((pw *)ptr)->coeffs[index] = val; return(val);} static mus_float_t pw_ycoeff(mus_any *ptr, int index) {if (((pw *)ptr)->ucoeffs) return(((pw *)ptr)->ucoeffs[index]); return(0.0);} static mus_float_t pw_set_ycoeff(mus_any *ptr, int index, mus_float_t val) {if (((pw *)ptr)->ucoeffs) ((pw *)ptr)->ucoeffs[index] = val; return(val);} static mus_float_t pw_index(mus_any *ptr) {return(((pw *)ptr)->index);} static mus_float_t pw_set_index(mus_any *ptr, mus_float_t val) {((pw *)ptr)->index = val; return(val);} static int pw_choice(mus_any *ptr) {return(((pw *)ptr)->cheby_choice);} mus_float_t mus_chebyshev_tu_sum(mus_float_t x, int n, mus_float_t *tn, mus_float_t *un) { /* the Clenshaw algorithm -- beware of -cos(nx) where you'd expect cos(nx) */ mus_float_t x2, tb, tb1 = 0.0, tb2, cx, ub, ub1 = 0.0; mus_float_t *tp, *up; cx = cos(x); x2 = 2.0 * cx; tp = (mus_float_t *)(tn + n - 1); up = (mus_float_t *)(un + n - 1); tb = (*tp--); ub = (*up--); while (up != un) { mus_float_t ub2; tb2 = tb1; tb1 = tb; tb = x2 * tb1 - tb2 + (*tp--); ub2 = ub1; ub1 = ub; ub = x2 * ub1 - ub2 + (*up--); } tb2 = tb1; tb1 = tb; tb = x2 * tb1 - tb2 + tn[0]; return((mus_float_t)((tb - tb1 * cx) + (sin(x) * ub))); } mus_float_t mus_chebyshev_t_sum(mus_float_t x, int n, mus_float_t *tn) { int i; mus_float_t x2, b, b1 = 0.0, cx; cx = cos(x); x2 = 2.0 * cx; /* Tn calc */ b = tn[n - 1]; for (i = n - 2; i >= 0; i--) { mus_float_t b2; b2 = b1; b1 = b; b = x2 * b1 - b2 + tn[i]; } return((mus_float_t)(b - b1 * cx)); } #if 0 /* here is the trick to do odd Tn without doing the intervening evens: */ (define (mus-chebyshev-odd-t-sum x n t2n) (let* ((b1 0.0) (b2 0.0) (cx1 (cos x)) (cx (- (* 2 cx1 cx1) 1)) (x2 (* 2.0 cx)) (b (vct-ref t2n (- n 1)))) (do ((i (- n 2) (1- i))) ((< i 0)) (set! b2 b1) (set! b1 b) (set! b (- (+ (* b1 x2) (vct-ref t2n i)) b2))) (* cx1 (- b b1)))) (with-sound () (let ((t2n (vct 0.5 0.25 0.25)) (x 0.0) (dx (hz->radians 10.0))) (do ((i 0 (1+ i))) ((= i 22050)) (outa i (mus-chebyshev-odd-t-sum x 3 t2n)) (set! x (+ x dx))))) #endif mus_float_t mus_chebyshev_u_sum(mus_float_t x, int n, mus_float_t *un) { int i; mus_float_t x2, b, b1 = 0.0, cx; cx = cos(x); x2 = 2.0 * cx; /* Un calc */ b = un[n - 1]; for (i = n - 2; i > 0; i--) { mus_float_t b2; b2 = b1; b1 = b; b = x2 * b1 - b2 + un[i]; } return((mus_float_t)(sin(x) * b)); } static mus_float_t mus_chebyshev_t_sum_with_index(mus_float_t x, mus_float_t index, int n, mus_float_t *tn) { int i; mus_float_t x2, b, b1 = 0.0, b2, cx; cx = index * cos(x); x2 = 2.0 * cx; /* Tn calc */ b = tn[n - 1]; i = n - 2; while (i >= 4) { b2 = b1; b1 = b; b = x2 * b1 - b2 + tn[i--]; b2 = b1; b1 = b; b = x2 * b1 - b2 + tn[i--]; b2 = b1; b1 = b; b = x2 * b1 - b2 + tn[i--]; b2 = b1; b1 = b; b = x2 * b1 - b2 + tn[i--]; } for (; i >= 0; i--) { b2 = b1; b1 = b; b = x2 * b1 - b2 + tn[i]; } return((mus_float_t)(b - b1 * cx)); } static mus_float_t mus_chebyshev_t_sum_with_index_2(mus_float_t x, mus_float_t index, int n, mus_float_t *tn) { int i; mus_float_t x2, b, b1 = 0.0, cx; cx = index * cos(x); x2 = 2.0 * cx; /* Tn calc */ b = tn[n - 1]; for (i = n - 2; i > 0;) { mus_float_t b2; b2 = b1; b1 = b; b = x2 * b1 - b2 + tn[i--]; b2 = b1; b1 = b; b = x2 * b1 - b2 + tn[i--]; } return((mus_float_t)(b - b1 * cx)); } static mus_float_t mus_chebyshev_t_sum_with_index_3(mus_float_t x, mus_float_t index, int n, mus_float_t *tn) { int i; mus_float_t x2, b, b1 = 0.0, cx; cx = index * cos(x); x2 = 2.0 * cx; /* Tn calc */ b = tn[n - 1]; for (i = n - 2; i > 0;) { mus_float_t b2; b2 = b1; b1 = b; b = x2 * b1 - b2 + tn[i--]; b2 = b1; b1 = b; b = x2 * b1 - b2 + tn[i--]; b2 = b1; b1 = b; b = x2 * b1 - b2 + tn[i--]; } return((mus_float_t)(b - b1 * cx)); } static mus_float_t mus_chebyshev_t_sum_with_index_5(mus_float_t x, mus_float_t index, int n, mus_float_t *tn) { int i; mus_float_t x2, b, b1 = 0.0, cx; cx = index * cos(x); x2 = 2.0 * cx; /* Tn calc */ b = tn[n - 1]; for (i = n - 2; i > 0;) /* this was >= ?? (also cases above) -- presumably a copy-and-paste typo? */ { mus_float_t b2; b2 = b1; b1 = b; b = x2 * b1 - b2 + tn[i--]; b2 = b1; b1 = b; b = x2 * b1 - b2 + tn[i--]; b2 = b1; b1 = b; b = x2 * b1 - b2 + tn[i--]; b2 = b1; b1 = b; b = x2 * b1 - b2 + tn[i--]; b2 = b1; b1 = b; b = x2 * b1 - b2 + tn[i--]; } return((mus_float_t)(b - b1 * cx)); } static mus_float_t mus_chebyshev_u_sum_with_index(mus_float_t x, mus_float_t index, int n, mus_float_t *un) { int i; mus_float_t x2, b, b1 = 0.0, cx; cx = index * cos(x); x2 = 2.0 * cx; /* Un calc */ b = un[n - 1]; for (i = n - 2; i > 0; i--) { mus_float_t b2; b2 = b1; b1 = b; b = x2 * b1 - b2 + un[i]; } return((mus_float_t)(sin(x) * b + un[0])); /* don't drop the constant, 16-Jan-14 */ } /* (with-sound () (let ((p (make-polywave 100 (list 0 0.5 1 -.2) mus-chebyshev-second-kind))) (do ((i 0 (+ i 1))) ((= i 1000)) (outa i (polywave p))))) */ static mus_float_t polyw_second_2(mus_any *ptr, mus_float_t fm) { pw *gen = (pw *)ptr; mus_float_t x; x = gen->phase; /* this order (as opposed to saving the full expr below) is much faster?! */ gen->phase += (gen->freq + fm); return(gen->coeffs[1] * sin(x) + gen->coeffs[0]); } static mus_float_t polyw_first_1(mus_any *ptr, mus_float_t fm) { pw *gen = (pw *)ptr; mus_float_t x; x = gen->phase; gen->phase += (gen->freq + fm); return(gen->index * cos(x)); } static mus_float_t polyw_first_3(mus_any *ptr, mus_float_t fm) { pw *gen = (pw *)ptr; mus_float_t x, cx; mus_float_t *tn; x = gen->phase; tn = gen->coeffs; gen->phase += (gen->freq + fm); cx = cos(x); return((2.0 * cx * tn[2] + tn[1]) * cx - tn[2]); /* b = x2 * b1 - b2;, then return(b - b1 * cx) * but x2 = 2 * cx, so b1*(x2 - cx) -> b1 * cx * and the final recursion unrolls. The old code * (which thought tn[0] might not be 0.0) was: * cx = cos(x); * x2 = 2.0 * cx; * b = tn[2]; * b2 = b1; -- but b1 is 0 * b1 = b; -- b not used so this is tn[2] * b = x2 * b1 - b2 + tn[1]; -- b2 is 0.0 * b2 = b1; * b1 = b; * b = x2 * b1 - b2 + tn[0]; * return(b - b1 * cx); */ } /* (with-sound () (let ((p (make-polywave 100 (list 1 .5 2 .25)))) (do ((i 0 (+ i 1))) ((= i 30000)) (outa i (polywave p))))) */ static mus_float_t polyw_first_4(mus_any *ptr, mus_float_t fm) { pw *gen = (pw *)ptr; mus_float_t x, x2, b, cx; mus_float_t *tn; x = gen->phase; tn = gen->coeffs; gen->phase += (gen->freq + fm); cx = cos(x); x2 = 2.0 * cx; b = x2 * tn[3] + tn[2]; /* was -tn[2]! 19-Feb-14 */ return((x2 * b - tn[3] + tn[1]) * cx - b); } static mus_float_t polyw_first_5(mus_any *ptr, mus_float_t fm) { pw *gen = (pw *)ptr; mus_float_t x; mus_float_t *tn; mus_float_t x2, b, b1, b2, cx; x = gen->phase; tn = gen->coeffs; gen->phase += (gen->freq + fm); cx = cos(x); x2 = 2.0 * cx; b1 = tn[4]; b = x2 * b1 + tn[3]; b2 = b1; b1 = b; b = x2 * b1 - b2 + tn[2]; return((x2 * b - b1 + tn[1]) * cx - b); } static mus_float_t polyw_first_6(mus_any *ptr, mus_float_t fm) { pw *gen = (pw *)ptr; mus_float_t x; mus_float_t *tn; mus_float_t x2, b, b1, b2, cx; x = gen->phase; tn = gen->coeffs; gen->phase += (gen->freq + fm); cx = cos(x); x2 = 2.0 * cx; b1 = tn[5]; b = x2 * b1 + tn[4]; b2 = b1; b1 = b; b = x2 * b1 - b2 + tn[3]; b2 = b1; b1 = b; b = x2 * b1 - b2 + tn[2]; return((x2 * b - b1 + tn[1]) * cx - b); } static mus_float_t polyw_first_8(mus_any *ptr, mus_float_t fm) { pw *gen = (pw *)ptr; mus_float_t x; mus_float_t *tn; mus_float_t x2, b, b1, b2, cx; x = gen->phase; tn = gen->coeffs; gen->phase += (gen->freq + fm); cx = cos(x); x2 = 2.0 * cx; b1 = tn[7]; b = x2 * b1 + tn[6]; b2 = b1; b1 = b; b = x2 * b1 - b2 + tn[5]; b2 = b1; b1 = b; b = x2 * b1 - b2 + tn[4]; b2 = b1; b1 = b; b = x2 * b1 - b2 + tn[3]; b2 = b1; b1 = b; b = x2 * b1 - b2 + tn[2]; return((x2 * b - b1 + tn[1]) * cx - b); } static mus_float_t polyw_first_11(mus_any *ptr, mus_float_t fm) { pw *gen = (pw *)ptr; mus_float_t x; mus_float_t *tn; mus_float_t x2, b, b1, b2, cx; x = gen->phase; tn = gen->coeffs; gen->phase += (gen->freq + fm); cx = cos(x); x2 = 2.0 * cx; b1 = tn[10]; b = x2 * b1 + tn[9]; b2 = b1; b1 = b; b = x2 * b1 - b2 + tn[8]; b2 = b1; b1 = b; b = x2 * b1 - b2 + tn[7]; b2 = b1; b1 = b; b = x2 * b1 - b2 + tn[6]; b2 = b1; b1 = b; b = x2 * b1 - b2 + tn[5]; b2 = b1; b1 = b; b = x2 * b1 - b2 + tn[4]; b2 = b1; b1 = b; b = x2 * b1 - b2 + tn[3]; b2 = b1; b1 = b; b = x2 * b1 - b2 + tn[2]; return((x2 * b - b1 + tn[1]) * cx - b); } static mus_float_t polyw_first(mus_any *ptr, mus_float_t fm) { pw *gen = (pw *)ptr; mus_float_t ph; ph = gen->phase; gen->phase += (gen->freq + fm); return(mus_chebyshev_t_sum_with_index(ph, gen->index, gen->n, gen->coeffs)); } static mus_float_t polyw_f1(mus_any *ptr, mus_float_t fm) { pw *gen = (pw *)ptr; mus_float_t cx; cx = gen->index * cos(gen->phase); gen->phase += (gen->freq + fm); return(cx * gen->coeffs[1] + gen->coeffs[0]); } static mus_float_t polyw_f2(mus_any *ptr, mus_float_t fm) { pw *gen = (pw *)ptr; mus_float_t ph; ph = gen->phase; gen->phase += (gen->freq + fm); return(mus_chebyshev_t_sum_with_index_2(ph, gen->index, gen->n, gen->coeffs)); } static mus_float_t polyw_f3(mus_any *ptr, mus_float_t fm) { pw *gen = (pw *)ptr; mus_float_t ph; ph = gen->phase; gen->phase += (gen->freq + fm); return(mus_chebyshev_t_sum_with_index_3(ph, gen->index, gen->n, gen->coeffs)); } static mus_float_t polyw_f5(mus_any *ptr, mus_float_t fm) { pw *gen = (pw *)ptr; mus_float_t ph; ph = gen->phase; gen->phase += (gen->freq + fm); return(mus_chebyshev_t_sum_with_index_5(ph, gen->index, gen->n, gen->coeffs)); } static mus_float_t polyw_second(mus_any *ptr, mus_float_t fm) { pw *gen = (pw *)ptr; mus_float_t ph; ph = gen->phase; gen->phase += (gen->freq + fm); return(mus_chebyshev_u_sum_with_index(ph, gen->index, gen->n, gen->coeffs)); } static mus_float_t polyw_second_5(mus_any *ptr, mus_float_t fm) { pw *gen = (pw *)ptr; mus_float_t *un; mus_float_t x, b, b1, cx; x = gen->phase; gen->phase += (gen->freq + fm); /* gen->n is 5 */ un = gen->coeffs; /* this is a candidate for sincos, but gcc is already using it here! */ cx = 2.0 * cos(x); b1 = cx * un[4] + un[3]; b = cx * b1 + gen->index; return(sin(x) * (cx * b - b1 + un[1])); } static mus_float_t polyw_third(mus_any *ptr, mus_float_t fm) { pw *gen = (pw *)ptr; mus_float_t ph; ph = gen->phase; gen->phase += (gen->freq + fm); return(mus_chebyshev_tu_sum(ph, gen->n, gen->coeffs, gen->ucoeffs)); } mus_float_t mus_polywave(mus_any *ptr, mus_float_t fm) { /* changed to use recursion, rather than polynomial in x, 25-May-08 * this algorithm taken from Mason and Handscomb, "Chebyshev Polynomials" p27 */ return((((pw *)ptr)->polyw)(ptr, fm)); } mus_float_t mus_polywave_unmodulated(mus_any *ptr) { return(mus_polywave(ptr, 0.0)); } static mus_float_t run_polywave(mus_any *ptr, mus_float_t fm, mus_float_t ignored) {return(mus_polywave(ptr, fm));} static char *describe_polywave(mus_any *ptr) { pw *gen = (pw *)ptr; char *str; char *describe_buffer; str = float_array_to_string(gen->coeffs, gen->n, 0); describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE); snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s freq: %.3fHz, phase: %.3f, coeffs[%d]: %s", mus_name(ptr), mus_frequency(ptr), mus_phase(ptr), gen->n, str); free(str); return(describe_buffer); } static mus_float_t pw_set_index_and_func(mus_any *ptr, mus_float_t val) { pw *gen = (pw *)ptr; gen->index = val; if (gen->cheby_choice == MUS_CHEBYSHEV_FIRST_KIND) gen->polyw = polyw_first; else gen->polyw = polyw_second; return(val); } static mus_any_class POLYWAVE_CLASS = { MUS_POLYWAVE, (char *)S_polywave, &free_pw, &describe_polywave, &pw_equalp, &pw_data, &pw_set_data, &pw_n, &pw_set_n, &pw_freq, &pw_set_freq, &pw_phase, &pw_set_phase, &pw_index, &pw_set_index_and_func, &pw_increment, &pw_set_increment, &run_polywave, MUS_NOT_SPECIAL, NULL, 0, 0, 0, 0, 0, &pw_xcoeff, &pw_set_xcoeff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &pw_choice, &pw_ycoeff, &pw_set_ycoeff, &pw_data, &pw_udata, &pw_reset, 0, &pw_copy }; mus_any *mus_make_polywave(mus_float_t frequency, mus_float_t *coeffs, int n, int cheby_choice) { pw *gen; gen = (pw *)malloc(sizeof(pw)); gen->core = &POLYWAVE_CLASS; gen->phase = 0.0; /* cos used in cheby funcs above */ gen->freq = mus_hz_to_radians(frequency); gen->coeffs = coeffs; gen->ucoeffs = NULL; gen->n = n; gen->index = 1.0; gen->cheby_choice = cheby_choice; if (cheby_choice != MUS_CHEBYSHEV_SECOND_KIND) { if (coeffs[0] == 0.0) { /* these also ignore gen->index (assumed to be 1.0) (leaving aside the first_1 case) * pw_set_index_and_func protects against that case */ if (n == 2) { gen->polyw = polyw_first_1; gen->index = coeffs[1]; } else { if (n == 3) gen->polyw = polyw_first_3; else { if (n == 4) gen->polyw = polyw_first_4; else { if (n == 5) gen->polyw = polyw_first_5; else { if (n == 6) gen->polyw = polyw_first_6; else { if (n == 8) gen->polyw = polyw_first_8; else { if (n == 11) /* a common case oddly enough */ gen->polyw = polyw_first_11; else { if (((n - 1) % 5) == 0) gen->polyw = polyw_f5; else { if (((n - 1) % 3) == 0) gen->polyw = polyw_f3; else { if (((n - 1) % 2) == 0) gen->polyw = polyw_f2; else { /* lots of n=8 here */ gen->polyw = polyw_first; } } } } } } } } } } } else { if (n == 2) gen->polyw = polyw_f1; else { if (((n - 1) % 3) == 0) gen->polyw = polyw_f3; else { if (((n - 1) % 2) == 0) gen->polyw = polyw_f2; else gen->polyw = polyw_first; } } } } else { if ((n == 5) && (coeffs[0] == 0.0)) { gen->polyw = polyw_second_5; gen->index = coeffs[2] - coeffs[4]; } else { if (n == 2) gen->polyw = polyw_second_2; else gen->polyw = polyw_second; } } return((mus_any *)gen); } mus_any *mus_make_polywave_tu(mus_float_t frequency, mus_float_t *tcoeffs, mus_float_t *ucoeffs, int n) { pw *gen; gen = (pw *)malloc(sizeof(pw)); gen->core = &POLYWAVE_CLASS; gen->phase = 0.0; /* cos used in cheby funcs above */ gen->freq = mus_hz_to_radians(frequency); gen->coeffs = tcoeffs; gen->ucoeffs = ucoeffs; gen->n = n; gen->index = 1.0; gen->cheby_choice = MUS_CHEBYSHEV_BOTH_KINDS; gen->polyw = polyw_third; return((mus_any *)gen); } bool mus_is_polywave(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_POLYWAVE)); } /* ---------------- polyshape ---------------- */ static char *describe_polyshape(mus_any *ptr) { pw *gen = (pw *)ptr; char *str; char *describe_buffer; describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE); str = float_array_to_string(gen->coeffs, gen->n, 0); snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s freq: %.3fHz, phase: %.3f, coeffs[%d]: %s", mus_name(ptr), mus_frequency(ptr), mus_phase(ptr), gen->n, str); free(str); return(describe_buffer); } mus_float_t mus_polyshape(mus_any *ptr, mus_float_t index, mus_float_t fm) { pw *gen = (pw *)ptr; mus_float_t result; gen->index = index; result = mus_polynomial(gen->coeffs, index * cos(gen->phase), gen->n); if (gen->cheby_choice == MUS_CHEBYSHEV_SECOND_KIND) result *= sin(gen->phase); gen->phase += (gen->freq + fm); return(result); } mus_float_t mus_polyshape_unmodulated(mus_any *ptr, mus_float_t index) { pw *gen = (pw *)ptr; mus_float_t result; gen->index = index; result = mus_polynomial(gen->coeffs, index * cos(gen->phase), gen->n); if (gen->cheby_choice == MUS_CHEBYSHEV_SECOND_KIND) result *= sin(gen->phase); gen->phase += gen->freq; return(result); } static mus_any_class POLYSHAPE_CLASS = { MUS_POLYSHAPE, (char *)S_polyshape, &free_pw, &describe_polyshape, &pw_equalp, &pw_data, &pw_set_data, &pw_n, &pw_set_n, &pw_freq, &pw_set_freq, &pw_phase, &pw_set_phase, &pw_index, &pw_set_index, &pw_increment, &pw_set_increment, &mus_polyshape, MUS_NOT_SPECIAL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &pw_reset, 0, &pw_copy }; mus_any *mus_make_polyshape(mus_float_t frequency, mus_float_t phase, mus_float_t *coeffs, int size, int cheby_choice) { mus_any *gen; gen = mus_make_polywave(frequency, coeffs, size, cheby_choice); gen->core = &POLYSHAPE_CLASS; pw_set_phase(gen, phase); return(gen); } bool mus_is_polyshape(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_POLYSHAPE)); } /* ---------------- wave-train ---------------- */ typedef struct { mus_any_class *core; mus_float_t freq, phase; mus_float_t *wave; /* passed in from caller */ mus_long_t wave_size; mus_float_t *out_data; mus_long_t out_data_size; mus_interp_t interp_type; /* "type" field exists in core -- avoid confusion */ mus_float_t next_wave_time; mus_long_t out_pos; bool first_time; mus_float_t yn1; } wt; static mus_float_t wt_freq(mus_any *ptr) {return(((wt *)ptr)->freq);} static mus_float_t wt_set_freq(mus_any *ptr, mus_float_t val) {((wt *)ptr)->freq = val; return(val);} static mus_float_t wt_phase(mus_any *ptr) {return(fmod(((TWO_PI * ((wt *)ptr)->phase) / ((mus_float_t)((wt *)ptr)->wave_size)), TWO_PI));} static mus_float_t wt_set_phase(mus_any *ptr, mus_float_t val) {((wt *)ptr)->phase = (fmod(val, TWO_PI) * ((wt *)ptr)->wave_size) / TWO_PI; return(val);} static mus_long_t wt_length(mus_any *ptr) {return(((wt *)ptr)->wave_size);} static mus_long_t wt_set_length(mus_any *ptr, mus_long_t val) {if (val > 0) ((wt *)ptr)->wave_size = val; return(((wt *)ptr)->wave_size);} static int wt_interp_type(mus_any *ptr) {return((int)(((wt *)ptr)->interp_type));} static mus_float_t *wt_data(mus_any *ptr) {return(((wt *)ptr)->wave);} static mus_float_t *wt_set_data(mus_any *ptr, mus_float_t *data) {((wt *)ptr)->wave = data; return(data);} static mus_any *wt_copy(mus_any *ptr) { wt *g, *p; int bytes; p = (wt *)ptr; g = (wt *)malloc(sizeof(wt)); memcpy((void *)g, (void *)ptr, sizeof(wt)); bytes = g->out_data_size * sizeof(mus_float_t); g->out_data = (mus_float_t *)malloc(bytes); memcpy((void *)(g->out_data), (void *)(p->out_data), bytes); /* g->wave is caller's data */ return((mus_any *)g); } static bool wt_equalp(mus_any *p1, mus_any *p2) { wt *w1 = (wt *)p1; wt *w2 = (wt *)p2; if (p1 == p2) return(true); return((w1) && (w2) && (w1->core->type == w2->core->type) && (w1->freq == w2->freq) && (w1->phase == w2->phase) && (w1->interp_type == w2->interp_type) && (w1->wave_size == w2->wave_size) && (w1->out_data_size == w2->out_data_size) && (w1->out_pos == w2->out_pos) && (clm_arrays_are_equal(w1->wave, w2->wave, w1->wave_size)) && (clm_arrays_are_equal(w1->out_data, w2->out_data, w1->out_data_size))); } static char *describe_wt(mus_any *ptr) { char *describe_buffer; describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE); snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s freq: %.3fHz, phase: %.3f, size: %lld, interp: %s", mus_name(ptr), mus_frequency(ptr), mus_phase(ptr), mus_length(ptr), interp_type_to_string(wt_interp_type(ptr))); return(describe_buffer); } static mus_float_t mus_wave_train_any(mus_any *ptr, mus_float_t fm) { wt *gen = (wt *)ptr; mus_float_t result = 0.0; if (gen->out_pos < gen->out_data_size) result = gen->out_data[gen->out_pos]; gen->out_pos++; if (gen->out_pos >= gen->next_wave_time) { mus_long_t i; mus_float_t *wave, *out_data; mus_long_t wave_size; wave = gen->wave; wave_size = gen->wave_size; out_data = gen->out_data; if (gen->out_pos < gen->out_data_size) { mus_long_t good_samps; good_samps = gen->out_data_size - gen->out_pos; memmove((void *)out_data, (void *)(out_data + gen->out_pos), good_samps * sizeof(mus_float_t)); memset((void *)(out_data + good_samps), 0, gen->out_pos * sizeof(mus_float_t)); } else memset((void *)out_data, 0, gen->out_data_size * sizeof(mus_float_t)); if (gen->interp_type == MUS_INTERP_LINEAR) { /* gen->phase doesn't change, and i is an int, so we can precalculate the fractional part, etc */ mus_float_t phase, frac_part; mus_long_t int_part; phase = gen->phase; if ((phase < 0.0) || (phase > wave_size)) { phase = fmod((mus_float_t)phase, (mus_float_t)wave_size); if (phase < 0.0) phase += wave_size; } int_part = (mus_long_t)floor(phase); frac_part = phase - int_part; if (int_part == wave_size) int_part = 0; if (frac_part == 0.0) { mus_long_t p; for (i = 0, p = int_part; i < wave_size; i++, p++) { if (p == wave_size) p = 0; out_data[i] += wave[p]; } } else { mus_long_t p, p1; for (i = 0, p = int_part, p1 = int_part + 1; i < wave_size; i++, p1++) { if (p1 == wave_size) p1 = 0; out_data[i] += (wave[p] + frac_part * (wave[p1] - wave[p])); p = p1; } } } else { for (i = 0; i < wave_size; i++) { gen->yn1 = mus_interpolate(gen->interp_type, gen->phase + i, wave, wave_size, gen->yn1); out_data[i] += gen->yn1; } } if (gen->first_time) { gen->first_time = false; gen->out_pos = (mus_long_t)(gen->phase); /* initial phase, but as an integer in terms of wave table size (gad...) */ if (gen->out_pos >= wave_size) gen->out_pos = gen->out_pos % wave_size; result = out_data[gen->out_pos++]; gen->next_wave_time = ((mus_float_t)sampling_rate / (gen->freq + fm)); } else { gen->next_wave_time += (((mus_float_t)sampling_rate / (gen->freq + fm)) - gen->out_pos); gen->out_pos = 0; } } return(result); } mus_float_t mus_wave_train(mus_any *ptr, mus_float_t fm) {return(mus_wave_train_any(ptr, fm / w_rate));} mus_float_t mus_wave_train_unmodulated(mus_any *ptr) {return(mus_wave_train(ptr, 0.0));} static mus_float_t run_wave_train(mus_any *ptr, mus_float_t fm, mus_float_t unused) {return(mus_wave_train_any(ptr, fm / w_rate));} static void free_wt(mus_any *p) { wt *ptr = (wt *)p; if (ptr->out_data) { free(ptr->out_data); ptr->out_data = NULL; } free(ptr); } static void wt_reset(mus_any *ptr) { wt *gen = (wt *)ptr; gen->phase = 0.0; memset((void *)(gen->out_data), 0, gen->out_data_size * sizeof(mus_float_t)); gen->out_pos = gen->out_data_size; gen->next_wave_time = 0.0; gen->first_time = true; } static mus_any_class WAVE_TRAIN_CLASS = { MUS_WAVE_TRAIN, (char *)S_wave_train, &free_wt, &describe_wt, &wt_equalp, &wt_data, &wt_set_data, &wt_length, &wt_set_length, &wt_freq, &wt_set_freq, &wt_phase, &wt_set_phase, &fallback_scaler, 0, 0, 0, &run_wave_train, MUS_NOT_SPECIAL, NULL, &wt_interp_type, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &wt_reset, 0, &wt_copy }; mus_any *mus_make_wave_train(mus_float_t freq, mus_float_t phase, mus_float_t *wave, mus_long_t wave_size, mus_interp_t type) { wt *gen; gen = (wt *)malloc(sizeof(wt)); gen->core = &WAVE_TRAIN_CLASS; gen->freq = freq; gen->phase = (wave_size * fmod(phase, TWO_PI)) / TWO_PI; gen->wave = wave; gen->wave_size = wave_size; gen->interp_type = type; gen->out_data_size = wave_size + 2; gen->out_data = (mus_float_t *)calloc(gen->out_data_size, sizeof(mus_float_t)); gen->out_pos = gen->out_data_size; gen->next_wave_time = 0.0; gen->first_time = true; gen->yn1 = 0.0; return((mus_any *)gen); } bool mus_is_wave_train(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_WAVE_TRAIN)); } /* ---------------- delay, comb, notch, all-pass, moving-average, filtered-comb ---------------- */ typedef struct dly { mus_any_class *core; unsigned int loc, size; bool zdly, line_allocated, filt_allocated; mus_float_t *line; unsigned int zloc, zsize; mus_float_t xscl, yscl, yn1, y1, norm; mus_interp_t type; mus_any *filt; struct dly *next; mus_float_t (*runf)(mus_any *gen, mus_float_t arg1, mus_float_t arg2); mus_float_t (*del)(mus_any *ptr, mus_float_t input); /* zdelay or normal tap */ mus_float_t (*delt)(mus_any *ptr, mus_float_t input); /* just tick */ mus_float_t (*delu)(mus_any *ptr, mus_float_t input); /* unmodulated */ } dly; mus_float_t mus_delay_tick(mus_any *ptr, mus_float_t input) { return(((dly *)ptr)->delt(ptr, input)); } mus_float_t mus_tap(mus_any *ptr, mus_float_t loc) { return(((dly *)ptr)->del(ptr, loc)); } mus_float_t mus_delay_unmodulated(mus_any *ptr, mus_float_t input) { return(((dly *)ptr)->delu(ptr, input)); } static mus_float_t ztap(mus_any *ptr, mus_float_t loc) { dly *gen = (dly *)ptr; /* this is almost always linear */ if (gen->type == MUS_INTERP_LINEAR) return(mus_array_interp(gen->line, gen->zloc - loc, gen->zsize)); gen->yn1 = mus_interpolate(gen->type, gen->zloc - loc, gen->line, gen->zsize, gen->yn1); return(gen->yn1); } static mus_float_t dtap(mus_any *ptr, mus_float_t loc) { dly *gen = (dly *)ptr; int taploc; if (gen->size == 0) return(gen->line[0]); if ((int)loc == 0) return(gen->line[gen->loc]); taploc = (int)(gen->loc - (int)loc) % gen->size; if (taploc < 0) taploc += gen->size; return(gen->line[taploc]); } mus_float_t mus_tap_unmodulated(mus_any *ptr) { dly *gen = (dly *)ptr; return(gen->line[gen->loc]); } static mus_float_t zdelt(mus_any *ptr, mus_float_t input) { dly *gen = (dly *)ptr; gen->line[gen->loc] = input; gen->loc++; if (gen->loc >= gen->zsize) gen->loc = 0; gen->zloc++; if (gen->zloc >= gen->zsize) gen->zloc = 0; return(input); } static mus_float_t delt(mus_any *ptr, mus_float_t input) { dly *gen = (dly *)ptr; gen->line[gen->loc] = input; gen->loc++; if (gen->loc >= gen->size) gen->loc = 0; return(input); } mus_float_t mus_delay(mus_any *ptr, mus_float_t input, mus_float_t pm) { mus_float_t result; dly *gen = (dly *)ptr; if ((gen->size == 0) && (pm < 1.0)) result = pm * gen->line[0] + (1.0 - pm) * input; else result = mus_tap(ptr, pm); mus_delay_tick(ptr, input); return(result); } static mus_float_t zdelay_unmodulated(mus_any *ptr, mus_float_t input) { dly *gen = (dly *)ptr; mus_float_t result; result = gen->line[gen->zloc]; mus_delay_tick(ptr, input); return(result); } static mus_float_t delay_unmodulated_zero(mus_any *ptr, mus_float_t input) { return(input); } mus_float_t mus_delay_unmodulated_noz(mus_any *ptr, mus_float_t input) { dly *gen = (dly *)ptr; mus_float_t result; result = gen->line[gen->loc]; gen->line[gen->loc] = input; gen->loc++; if (gen->loc >= gen->size) gen->loc = 0; return(result); } static dly *dly_free_list = NULL; static void free_delay(mus_any *gen) { dly *ptr = (dly *)gen; if ((ptr->line) && (ptr->line_allocated)) free(ptr->line); if ((ptr->filt) && (ptr->filt_allocated)) mus_free(ptr->filt); /* free(ptr); */ ptr->next = dly_free_list; dly_free_list = ptr; } static mus_any *dly_copy(mus_any *ptr) { dly *g, *p; mus_long_t bytes; p = (dly *)ptr; if (dly_free_list) { g = dly_free_list; dly_free_list = g->next; } else g = (dly *)malloc(sizeof(dly)); memcpy((void *)g, (void *)ptr, sizeof(dly)); bytes = g->size * sizeof(mus_float_t); g->line = (mus_float_t *)malloc(bytes); memcpy((void *)(g->line), (void *)(p->line), bytes); g->line_allocated = true; if (p->filt) { g->filt = mus_copy(p->filt); g->filt_allocated = true; } return((mus_any *)g); } static char *describe_delay(mus_any *ptr) { char *str = NULL; dly *gen = (dly *)ptr; char *describe_buffer; describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE); if (gen->zdly) snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s line[%u,%u, %s]: %s", mus_name(ptr), gen->size, gen->zsize, interp_type_to_string(gen->type), str = float_array_to_string(gen->line, gen->size, gen->zloc)); else snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s line[%u, %s]: %s", mus_name(ptr), gen->size, interp_type_to_string(gen->type), str = float_array_to_string(gen->line, gen->size, gen->loc)); if (str) free(str); return(describe_buffer); } static bool delay_equalp(mus_any *p1, mus_any *p2) { dly *d1 = (dly *)p1; dly *d2 = (dly *)p2; if (p1 == p2) return(true); return((d1) && (d2) && (d1->core->type == d2->core->type) && (d1->size == d2->size) && (d1->loc == d2->loc) && (d1->zdly == d2->zdly) && (d1->zloc == d2->zloc) && (d1->zsize == d2->zsize) && (d1->xscl == d2->xscl) && (d1->yscl == d2->yscl) && (d1->yn1 == d2->yn1) && (d1->type == d2->type) && (clm_arrays_are_equal(d1->line, d2->line, d1->size))); } static mus_long_t delay_length(mus_any *ptr) { dly *d = (dly *)ptr; if (d->size > 0) /* this is possible (not sure it's a good idea...) */ return(d->size); return(d->zsize); /* maybe always use this? */ } static mus_float_t delay_scaler(mus_any *ptr) {return(((dly *)ptr)->xscl);} static mus_float_t delay_set_scaler(mus_any *ptr, mus_float_t val) {((dly *)ptr)->xscl = val; return(val);} static mus_float_t delay_fb(mus_any *ptr) {return(((dly *)ptr)->yscl);} static mus_float_t delay_set_fb(mus_any *ptr, mus_float_t val) {((dly *)ptr)->yscl = val; return(val);} static int delay_interp_type(mus_any *ptr) {return((int)(((dly *)ptr)->type));} static mus_long_t delay_loc(mus_any *ptr){return((mus_long_t)(((dly *)ptr)->loc));} static mus_float_t *delay_data(mus_any *ptr) {return(((dly *)ptr)->line);} static mus_float_t *delay_set_data(mus_any *ptr, mus_float_t *val) { dly *gen = (dly *)ptr; if (gen->line_allocated) {free(gen->line); gen->line_allocated = false;} gen->line = val; return(val); } static mus_long_t delay_set_length(mus_any *ptr, mus_long_t val) { dly *gen = (dly *)ptr; if (val > 0) { unsigned int old_size; old_size = gen->size; gen->size = (unsigned int)val; if (gen->size < old_size) { if (gen->loc > gen->size) gen->loc = 0; gen->zdly = false; /* otherwise too many ways to screw up */ } } return((mus_long_t)(gen->size)); } bool mus_is_tap(mus_any *gen) { return((gen) && (gen->core->extended_type == MUS_DELAY_LINE)); } static void delay_reset(mus_any *ptr) { dly *gen = (dly *)ptr; gen->loc = 0; gen->zloc = 0; gen->yn1 = 0.0; memset((void *)(gen->line), 0, gen->zsize * sizeof(mus_float_t)); } static mus_any_class DELAY_CLASS = { MUS_DELAY, (char *)S_delay, &free_delay, &describe_delay, &delay_equalp, &delay_data, &delay_set_data, &delay_length, &delay_set_length, 0, 0, 0, 0, /* freq phase */ &delay_scaler, &delay_set_scaler, &delay_fb, &delay_set_fb, &mus_delay, MUS_DELAY_LINE, NULL, &delay_interp_type, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &delay_loc, 0, 0, 0, 0, 0, 0, &delay_reset, 0, &dly_copy }; mus_any *mus_make_delay(int size, mus_float_t *preloaded_line, int line_size, mus_interp_t type) { /* if preloaded_line null, allocated locally. * if size == line_size, normal (non-interpolating) delay * in clm2xen.c, if size=0 and max-size unset, max-size=1 (line_size here) */ dly *gen; if (dly_free_list) { gen = dly_free_list; dly_free_list = gen->next; } else gen = (dly *)malloc(sizeof(dly)); gen->core = &DELAY_CLASS; gen->loc = 0; gen->size = size; gen->zsize = line_size; gen->zdly = ((line_size != size) || (type != MUS_INTERP_NONE)); if (gen->zdly) { gen->del = ztap; gen->delt = zdelt; if (gen->size == 0) gen->delu = delay_unmodulated_zero; else gen->delu = zdelay_unmodulated; } else { gen->del = dtap; gen->delt = delt; if (gen->size == 0) gen->delu = delay_unmodulated_zero; else gen->delu = mus_delay_unmodulated_noz; } gen->type = type; if (preloaded_line) { gen->line = preloaded_line; gen->line_allocated = false; } else { gen->line = (mus_float_t *)calloc((line_size <= 0) ? 1 : line_size, sizeof(mus_float_t)); gen->line_allocated = true; } gen->zloc = line_size - size; gen->filt = NULL; gen->filt_allocated = false; gen->xscl = 0.0; gen->yscl = 0.0; gen->yn1 = 0.0; gen->runf = NULL; return((mus_any *)gen); } bool mus_is_delay(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_DELAY)); } /* ---------------- comb ---------------- */ mus_float_t mus_comb(mus_any *ptr, mus_float_t input, mus_float_t pm) { dly *gen = (dly *)ptr; if (gen->zdly) return(mus_delay(ptr, input + (gen->yscl * mus_tap(ptr, pm)), pm)); /* mus.lisp has 0 in place of the final pm -- the question is whether the delay should interpolate as well as the tap. There is a subtle difference in output (the pm case is low-passed by the interpolation ("average")), but I don't know if there's a standard here, or what people expect. We're doing the outer-level interpolation in notch and all-pass. Should mus.lisp be changed? */ else return(mus_delay_unmodulated(ptr, input + (gen->line[gen->loc] * gen->yscl))); } mus_float_t mus_comb_unmodulated(mus_any *ptr, mus_float_t input) { dly *gen = (dly *)ptr; if (gen->zdly) return(mus_delay_unmodulated(ptr, input + (gen->line[gen->zloc] * gen->yscl))); return(mus_delay_unmodulated(ptr, input + (gen->line[gen->loc] * gen->yscl))); } mus_float_t mus_comb_unmodulated_noz(mus_any *ptr, mus_float_t input) { dly *gen = (dly *)ptr; mus_float_t result; result = gen->line[gen->loc]; gen->line[gen->loc] = input + (result * gen->yscl); gen->loc++; if (gen->loc >= gen->size) gen->loc = 0; return(result); } static char *describe_comb(mus_any *ptr) { char *str = NULL; dly *gen = (dly *)ptr; char *describe_buffer; describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE); if (gen->zdly) snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s scaler: %.3f, line[%u,%u, %s]: %s", mus_name(ptr), gen->yscl, gen->size, gen->zsize, interp_type_to_string(gen->type), str = float_array_to_string(gen->line, gen->size, gen->zloc)); else snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s scaler: %.3f, line[%u, %s]: %s", mus_name(ptr), gen->yscl, gen->size, interp_type_to_string(gen->type), str = float_array_to_string(gen->line, gen->size, gen->loc)); if (str) free(str); return(describe_buffer); } static mus_any_class COMB_CLASS = { MUS_COMB, (char *)S_comb, &free_delay, &describe_comb, &delay_equalp, &delay_data, &delay_set_data, &delay_length, &delay_set_length, 0, 0, 0, 0, /* freq phase */ &delay_scaler, &delay_set_scaler, &delay_fb, &delay_set_fb, &mus_comb, MUS_DELAY_LINE, NULL, &delay_interp_type, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &delay_loc, 0, 0, 0, 0, 0, 0, &delay_reset, 0, &dly_copy }; mus_any *mus_make_comb(mus_float_t scaler, int size, mus_float_t *line, int line_size, mus_interp_t type) { dly *gen; gen = (dly *)mus_make_delay(size, line, line_size, type); if (gen) { gen->core = &COMB_CLASS; gen->yscl = scaler; return((mus_any *)gen); } return(NULL); } bool mus_is_comb(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_COMB)); } /* ---------------- comb-bank ---------------- */ typedef struct { mus_any_class *core; int size; mus_any **gens; mus_float_t (*cmbf)(mus_any *ptr, mus_float_t input); } cmb_bank; static void free_comb_bank(mus_any *ptr) { cmb_bank *f = (cmb_bank *)ptr; if (f->gens) {free(f->gens); f->gens = NULL;} free(ptr); } static mus_any *cmb_bank_copy(mus_any *ptr) { cmb_bank *g, *p; int i; p = (cmb_bank *)ptr; g = (cmb_bank *)malloc(sizeof(cmb_bank)); memcpy((void *)g, (void *)ptr, sizeof(cmb_bank)); g->gens = (mus_any **)malloc(p->size * sizeof(mus_any *)); for (i = 0; i < p->size; i++) g->gens[i] = mus_copy(p->gens[i]); return((mus_any *)g); } static mus_float_t run_comb_bank(mus_any *ptr, mus_float_t input, mus_float_t unused) { return(mus_comb_bank(ptr, input)); } static mus_long_t comb_bank_length(mus_any *ptr) { return(((cmb_bank *)ptr)->size); } static void comb_bank_reset(mus_any *ptr) { cmb_bank *f = (cmb_bank *)ptr; int i; for (i = 0; i < f->size; i++) mus_reset(f->gens[i]); } static bool comb_bank_equalp(mus_any *p1, mus_any *p2) { cmb_bank *f1 = (cmb_bank *)p1; cmb_bank *f2 = (cmb_bank *)p2; int i, size; if (f1 == f2) return(true); if (f1->size != f2->size) return(false); size = f1->size; for (i = 0; i < size; i++) if (!delay_equalp(f1->gens[i], f2->gens[i])) return(false); /* now check the locals... */ return(true); } static char *describe_comb_bank(mus_any *ptr) { cmb_bank *gen = (cmb_bank *)ptr; char *describe_buffer; describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE); snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s size: %d", mus_name(ptr), gen->size); return(describe_buffer); } static mus_any_class COMB_BANK_CLASS = { MUS_COMB_BANK, (char *)S_comb_bank, &free_comb_bank, &describe_comb_bank, &comb_bank_equalp, 0, 0, &comb_bank_length, 0, 0, 0, 0, 0, 0, 0, 0, 0, &run_comb_bank, MUS_NOT_SPECIAL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &comb_bank_reset, 0, &cmb_bank_copy }; static mus_float_t comb_bank_any(mus_any *combs, mus_float_t inval) { int i; mus_float_t sum = 0.0; cmb_bank *c = (cmb_bank *)combs; for (i = 0; i < c->size; i++) sum += mus_comb_unmodulated_noz(c->gens[i], inval); return(sum); } static mus_float_t comb_bank_4(mus_any *combs, mus_float_t inval) { cmb_bank *c = (cmb_bank *)combs; mus_any **gs; gs = c->gens; return(mus_comb_unmodulated_noz(gs[0], inval) + mus_comb_unmodulated_noz(gs[1], inval) + mus_comb_unmodulated_noz(gs[2], inval) + mus_comb_unmodulated_noz(gs[3], inval)); } static mus_float_t comb_bank_6(mus_any *combs, mus_float_t inval) { cmb_bank *c = (cmb_bank *)combs; mus_any **gs; gs = c->gens; return(mus_comb_unmodulated_noz(gs[0], inval) + mus_comb_unmodulated_noz(gs[1], inval) + mus_comb_unmodulated_noz(gs[2], inval) + mus_comb_unmodulated_noz(gs[3], inval) + mus_comb_unmodulated_noz(gs[4], inval) + mus_comb_unmodulated_noz(gs[5], inval)); } mus_any *mus_make_comb_bank(int size, mus_any **combs) { cmb_bank *gen; int i; gen = (cmb_bank *)malloc(sizeof(cmb_bank)); gen->core = &COMB_BANK_CLASS; gen->size = size; gen->gens = (mus_any **)malloc(size * sizeof(mus_any *)); for (i = 0; i < size; i++) gen->gens[i] = combs[i]; if (size == 4) gen->cmbf = comb_bank_4; else { if (size == 6) gen->cmbf = comb_bank_6; else gen->cmbf = comb_bank_any; } return((mus_any *)gen); } bool mus_is_comb_bank(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_COMB_BANK)); } mus_float_t mus_comb_bank(mus_any *combs, mus_float_t inval) { cmb_bank *gen = (cmb_bank *)combs; return((gen->cmbf)(combs, inval)); } /* ---------------- notch ---------------- */ static char *describe_notch(mus_any *ptr) { char *str = NULL; dly *gen = (dly *)ptr; char *describe_buffer; describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE); if (gen->zdly) snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s scaler: %.3f, line[%u,%u, %s]: %s", mus_name(ptr), gen->xscl, gen->size, gen->zsize, interp_type_to_string(gen->type), str = float_array_to_string(gen->line, gen->size, gen->zloc)); else snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s scaler: %.3f, line[%u, %s]: %s", mus_name(ptr), gen->xscl, gen->size, interp_type_to_string(gen->type), str = float_array_to_string(gen->line, gen->size, gen->loc)); if (str) free(str); return(describe_buffer); } static mus_any_class NOTCH_CLASS = { MUS_NOTCH, (char *)S_notch, &free_delay, &describe_notch, &delay_equalp, &delay_data, &delay_set_data, &delay_length, &delay_set_length, 0, 0, 0, 0, /* freq phase */ &delay_scaler, &delay_set_scaler, 0, 0, &mus_notch, MUS_DELAY_LINE, NULL, &delay_interp_type, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &delay_loc, 0, 0, 0, 0, 0, 0, &delay_reset, 0, &dly_copy }; mus_float_t mus_notch(mus_any *ptr, mus_float_t input, mus_float_t pm) { dly *gen = (dly *)ptr; return((input * gen->xscl) + mus_delay(ptr, input, pm)); } mus_float_t mus_notch_unmodulated(mus_any *ptr, mus_float_t input) { return((input * ((dly *)ptr)->xscl) + mus_delay_unmodulated(ptr, input)); } #if 0 static mus_float_t mus_notch_unmodulated_noz(mus_any *ptr, mus_float_t input) { dly *gen = (dly *)ptr; mus_float_t result; result = gen->line[gen->loc] + (input * gen->xscl); gen->line[gen->loc] = input; gen->loc++; if (gen->loc >= gen->size) gen->loc = 0; return(result); } #endif bool mus_is_notch(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_NOTCH)); } mus_any *mus_make_notch(mus_float_t scaler, int size, mus_float_t *line, int line_size, mus_interp_t type) { dly *gen; gen = (dly *)mus_make_delay(size, line, line_size, type); if (gen) { gen->core = &NOTCH_CLASS; gen->xscl = scaler; return((mus_any *)gen); } return(NULL); } mus_float_t mus_all_pass(mus_any *ptr, mus_float_t input, mus_float_t pm) { mus_float_t din; dly *gen = (dly *)ptr; if (gen->zdly) din = input + (gen->yscl * mus_tap(ptr, pm)); else din = input + (gen->yscl * gen->line[gen->loc]); return(mus_delay(ptr, din, pm) + (gen->xscl * din)); } mus_float_t mus_all_pass_unmodulated(mus_any *ptr, mus_float_t input) { mus_float_t din; dly *gen = (dly *)ptr; if (gen->zdly) din = input + (gen->yscl * gen->line[gen->zloc]); else din = input + (gen->yscl * gen->line[gen->loc]); return(mus_delay_unmodulated(ptr, din) + (gen->xscl * din)); } mus_float_t mus_all_pass_unmodulated_noz(mus_any *ptr, mus_float_t input) { mus_float_t result, din; dly *gen = (dly *)ptr; unsigned int loc; loc = gen->loc++; din = input + (gen->yscl * gen->line[loc]); result = gen->line[loc] + (gen->xscl * din); gen->line[loc] = din; if (gen->loc >= gen->size) gen->loc = 0; return(result); } bool mus_is_all_pass(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_ALL_PASS)); } static char *describe_all_pass(mus_any *ptr) { char *str = NULL; dly *gen = (dly *)ptr; char *describe_buffer; describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE); if (gen->zdly) snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s feedback: %.3f, feedforward: %.3f, line[%u,%u, %s]:%s", mus_name(ptr), gen->yscl, gen->xscl, gen->size, gen->zsize, interp_type_to_string(gen->type), str = float_array_to_string(gen->line, gen->size, gen->zloc)); else snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s feedback: %.3f, feedforward: %.3f, line[%u, %s]:%s", mus_name(ptr), gen->yscl, gen->xscl, gen->size, interp_type_to_string(gen->type), str = float_array_to_string(gen->line, gen->size, gen->loc)); if (str) free(str); return(describe_buffer); } static mus_any_class ALL_PASS_CLASS = { MUS_ALL_PASS, (char *)S_all_pass, &free_delay, &describe_all_pass, &delay_equalp, &delay_data, &delay_set_data, &delay_length, &delay_set_length, 0, 0, 0, 0, /* freq phase */ &delay_scaler, &delay_set_scaler, &delay_fb, &delay_set_fb, &mus_all_pass, MUS_DELAY_LINE, NULL, &delay_interp_type, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &delay_loc, 0, 0, 0, 0, 0, 0, &delay_reset, 0, &dly_copy }; mus_any *mus_make_all_pass(mus_float_t backward, mus_float_t forward, int size, mus_float_t *line, int line_size, mus_interp_t type) { dly *gen; gen = (dly *)mus_make_delay(size, line, line_size, type); if (gen) { gen->core = &ALL_PASS_CLASS; gen->xscl = forward; gen->yscl = backward; return((mus_any *)gen); } return(NULL); } /* ---------------- all_pass-bank ---------------- */ typedef struct { mus_any_class *core; int size; mus_any **gens; mus_float_t (*apf)(mus_any *ptr, mus_float_t input); } allp_bank; static void free_all_pass_bank(mus_any *ptr) { allp_bank *f = (allp_bank *)ptr; if (f->gens) {free(f->gens); f->gens = NULL;} free(ptr); } static mus_any *allp_bank_copy(mus_any *ptr) { allp_bank *g, *p; int i; p = (allp_bank *)ptr; g = (allp_bank *)malloc(sizeof(allp_bank)); memcpy((void *)g, (void *)ptr, sizeof(allp_bank)); g->gens = (mus_any **)malloc(p->size * sizeof(mus_any *)); for (i = 0; i < p->size; i++) g->gens[i] = mus_copy(p->gens[i]); return((mus_any *)g); } static mus_float_t run_all_pass_bank(mus_any *ptr, mus_float_t input, mus_float_t unused) { return(mus_all_pass_bank(ptr, input)); } static mus_long_t all_pass_bank_length(mus_any *ptr) { return(((allp_bank *)ptr)->size); } static void all_pass_bank_reset(mus_any *ptr) { allp_bank *f = (allp_bank *)ptr; int i; for (i = 0; i < f->size; i++) mus_reset(f->gens[i]); } static bool all_pass_bank_equalp(mus_any *p1, mus_any *p2) { allp_bank *f1 = (allp_bank *)p1; allp_bank *f2 = (allp_bank *)p2; int i, size; if (f1 == f2) return(true); if (f1->size != f2->size) return(false); size = f1->size; for (i = 0; i < size; i++) if (!delay_equalp(f1->gens[i], f2->gens[i])) return(false); return(true); } static char *describe_all_pass_bank(mus_any *ptr) { allp_bank *gen = (allp_bank *)ptr; char *describe_buffer; describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE); snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s size: %d", mus_name(ptr), gen->size); return(describe_buffer); } static mus_any_class ALL_PASS_BANK_CLASS = { MUS_ALL_PASS_BANK, (char *)S_all_pass_bank, &free_all_pass_bank, &describe_all_pass_bank, &all_pass_bank_equalp, 0, 0, &all_pass_bank_length, 0, 0, 0, 0, 0, 0, 0, 0, 0, &run_all_pass_bank, MUS_NOT_SPECIAL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &all_pass_bank_reset, 0, &allp_bank_copy }; static mus_float_t all_pass_bank_3(mus_any *all_passes, mus_float_t inval) { allp_bank *c = (allp_bank *)all_passes; mus_any **gs; gs = c->gens; return(mus_all_pass_unmodulated_noz(gs[2], mus_all_pass_unmodulated_noz(gs[1], mus_all_pass_unmodulated_noz(gs[0], inval)))); } static mus_float_t all_pass_bank_4(mus_any *all_passes, mus_float_t inval) { allp_bank *c = (allp_bank *)all_passes; mus_any **gs; gs = c->gens; return(mus_all_pass_unmodulated_noz(gs[3], mus_all_pass_unmodulated_noz(gs[2], mus_all_pass_unmodulated_noz(gs[1], mus_all_pass_unmodulated_noz(gs[0], inval))))); } static mus_float_t all_pass_bank_any(mus_any *all_passs, mus_float_t inval) { int i; mus_float_t sum = inval; allp_bank *c = (allp_bank *)all_passs; for (i = 0; i < c->size; i++) sum = mus_all_pass_unmodulated_noz(c->gens[i], sum); return(sum); } mus_any *mus_make_all_pass_bank(int size, mus_any **all_passs) { allp_bank *gen; int i; gen = (allp_bank *)malloc(sizeof(allp_bank)); gen->core = &ALL_PASS_BANK_CLASS; gen->size = size; gen->gens = (mus_any **)malloc(size * sizeof(mus_any *)); for (i = 0; i < size; i++) gen->gens[i] = all_passs[i]; if (size == 3) gen->apf = all_pass_bank_3; else { if (size == 4) gen->apf = all_pass_bank_4; else gen->apf = all_pass_bank_any; } return((mus_any *)gen); } bool mus_is_all_pass_bank(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_ALL_PASS_BANK)); } mus_float_t mus_all_pass_bank(mus_any *all_passes, mus_float_t inval) { allp_bank *gen = (allp_bank *)all_passes; return((gen->apf)(all_passes, inval)); } /* ---------------- moving-average ---------------- */ bool mus_is_moving_average(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_MOVING_AVERAGE)); } mus_float_t mus_moving_average(mus_any *ptr, mus_float_t input) { dly *gen = (dly *)ptr; mus_float_t output; output = mus_delay_unmodulated_noz(ptr, input); gen->xscl += (input - output); return(gen->xscl * gen->yscl); /* xscl=sum, yscl=1/n */ } static mus_float_t run_mus_moving_average(mus_any *ptr, mus_float_t input, mus_float_t unused) {return(mus_moving_average(ptr, input));} static void moving_average_reset(mus_any *ptr) { dly *gen = (dly *)ptr; delay_reset(ptr); gen->xscl = 0.0; } static char *describe_moving_average(mus_any *ptr) { char *str = NULL; dly *gen = (dly *)ptr; char *describe_buffer; describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE); snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s %.3f, line[%u]:%s", mus_name(ptr), gen->xscl * gen->yscl, gen->size, str = float_array_to_string(gen->line, gen->size, gen->loc)); if (str) free(str); return(describe_buffer); } static mus_any_class MOVING_AVERAGE_CLASS = { MUS_MOVING_AVERAGE, (char *)S_moving_average, &free_delay, &describe_moving_average, &delay_equalp, &delay_data, &delay_set_data, &delay_length, &delay_set_length, 0, 0, 0, 0, /* freq phase */ &delay_scaler, &delay_set_scaler, &delay_fb, &delay_set_fb, &run_mus_moving_average, MUS_DELAY_LINE, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &delay_loc, 0, 0, 0, 0, 0, 0, &moving_average_reset, 0, &dly_copy }; mus_any *mus_make_moving_average(int size, mus_float_t *line) { dly *gen; gen = (dly *)mus_make_delay(size, line, size, MUS_INTERP_NONE); if (gen) { int i; gen->core = &MOVING_AVERAGE_CLASS; gen->xscl = 0.0; for (i = 0; i < size; i++) gen->xscl += gen->line[i]; gen->yscl = 1.0 / (mus_float_t)size; return((mus_any *)gen); } return(NULL); } mus_any *mus_make_moving_average_with_initial_sum(int size, mus_float_t *line, mus_float_t sum) { dly *gen; gen = (dly *)mus_make_delay(size, line, size, MUS_INTERP_NONE); if (gen) { gen->core = &MOVING_AVERAGE_CLASS; gen->xscl = sum; gen->yscl = 1.0 / (mus_float_t)size; return((mus_any *)gen); } return(NULL); } /* -------- moving-max -------- */ bool mus_is_moving_max(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_MOVING_MAX)); } mus_float_t mus_moving_max(mus_any *ptr, mus_float_t input) { dly *gen = (dly *)ptr; mus_float_t output, abs_input; abs_input = fabs(input); output = mus_delay_unmodulated_noz(ptr, abs_input); if (abs_input >= gen->xscl) gen->xscl = abs_input; else { if (output >= gen->xscl) { unsigned int i; for (i = 0; i < gen->size; i++) if (gen->line[i] > abs_input) abs_input = gen->line[i]; gen->xscl = abs_input; } } return(gen->xscl); } static mus_float_t run_mus_moving_max(mus_any *ptr, mus_float_t input, mus_float_t unused) {return(mus_moving_max(ptr, input));} static void moving_max_reset(mus_any *ptr) { dly *gen = (dly *)ptr; delay_reset(ptr); gen->xscl = 0.0; } static char *describe_moving_max(mus_any *ptr) { char *str = NULL; dly *gen = (dly *)ptr; char *describe_buffer; describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE); snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s %.3f, line[%u]:%s", mus_name(ptr), gen->xscl, gen->size, str = float_array_to_string(gen->line, gen->size, gen->loc)); if (str) free(str); return(describe_buffer); } static mus_any_class MOVING_MAX_CLASS = { MUS_MOVING_MAX, (char *)S_moving_max, &free_delay, &describe_moving_max, &delay_equalp, &delay_data, &delay_set_data, &delay_length, &delay_set_length, 0, 0, 0, 0, /* freq phase */ &delay_scaler, &delay_set_scaler, &delay_fb, &delay_set_fb, &run_mus_moving_max, MUS_DELAY_LINE, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &delay_loc, 0, 0, 0, 0, 0, 0, &moving_max_reset, 0, &dly_copy }; mus_any *mus_make_moving_max(int size, mus_float_t *line) { dly *gen; gen = (dly *)mus_make_delay(size, line, size, MUS_INTERP_NONE); if (gen) { int i; gen->core = &MOVING_MAX_CLASS; gen->xscl = 0.0; for (i = 0; i < size; i++) if (fabs(gen->line[i]) > gen->xscl) gen->xscl = fabs(gen->line[i]); return((mus_any *)gen); } return(NULL); } /* -------- moving-norm -------- */ bool mus_is_moving_norm(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_MOVING_NORM)); } mus_float_t mus_moving_norm(mus_any *ptr, mus_float_t input) { dly *gen = (dly *)ptr; mus_float_t output, abs_input; abs_input = fabs(input); if (abs_input < 0.01) abs_input = 0.01; /* 0.01 sets the max norm output (~100) -- maybe a parameter to make-norm? */ output = mus_moving_max(ptr, abs_input); gen->y1 = output + (gen->yscl * gen->y1); return(gen->norm / gen->y1); } static mus_float_t run_mus_moving_norm(mus_any *ptr, mus_float_t input, mus_float_t unused) {return(mus_moving_norm(ptr, input));} static void moving_norm_reset(mus_any *ptr) { dly *gen = (dly *)ptr; delay_reset(ptr); gen->xscl = 0.0; gen->y1 = 0.0; } static char *describe_moving_norm(mus_any *ptr) { char *str = NULL; dly *gen = (dly *)ptr; char *describe_buffer; describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE); snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s, max %.3f, y1 %.3f, weight %.3f, line[%u]:%s", mus_name(ptr), gen->xscl, gen->y1, gen->yscl, gen->size, str = float_array_to_string(gen->line, gen->size, gen->loc)); if (str) free(str); return(describe_buffer); } static mus_any_class MOVING_NORM_CLASS = { MUS_MOVING_NORM, (char *)S_moving_norm, &free_delay, &describe_moving_norm, &delay_equalp, &delay_data, &delay_set_data, &delay_length, &delay_set_length, 0, 0, 0, 0, /* freq phase */ &delay_scaler, &delay_set_scaler, &delay_fb, &delay_set_fb, &run_mus_moving_norm, MUS_DELAY_LINE, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &delay_loc, 0, 0, 0, 0, 0, 0, &moving_norm_reset, 0, &dly_copy }; mus_any *mus_make_moving_norm(int size, mus_float_t *line, mus_float_t norm) { dly *gen; gen = (dly *)mus_make_moving_max(size, line); if (gen) { gen->core = &MOVING_NORM_CLASS; gen->yscl = (mus_float_t)size / (size + 1.0); /* one-pole -b1 = -feedback so this is a lowpass filter */ gen->norm = norm * (size + 1.0); gen->yn1 = 1.0 / size; gen->y1 = size + 1.0; return((mus_any *)gen); } return(NULL); } /* ---------------------------------------- filtered-comb ---------------------------------------- */ static void filtered_comb_reset(mus_any *ptr) { dly *fc = (dly *)ptr; delay_reset(ptr); mus_reset(fc->filt); } static bool filtered_comb_equalp(mus_any *p1, mus_any *p2) { return((delay_equalp(p1, p2)) && (mus_equalp(((dly *)p1)->filt, ((dly *)p2)->filt))); } static char *describe_filtered_comb(mus_any *ptr) { char *comb_str, *filter_str, *res; int len; comb_str = describe_comb(ptr); filter_str = mus_describe(((dly *)ptr)->filt); len = strlen(comb_str) + strlen(filter_str) + 64; res = (char *)malloc(len * sizeof(char)); snprintf(res, len, "%s, filter: [%s]", comb_str, filter_str); if (comb_str) free(comb_str); if (filter_str) free(filter_str); return(res); } bool mus_is_filtered_comb(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_FILTERED_COMB)); } mus_float_t mus_filtered_comb(mus_any *ptr, mus_float_t input, mus_float_t pm) { dly *fc = (dly *)ptr; if (fc->zdly) return(mus_delay(ptr, input + (fc->yscl * fc->runf(fc->filt, mus_tap(ptr, pm), 0.0)), pm)); return(mus_delay_unmodulated(ptr, input + (fc->yscl * fc->runf(fc->filt, fc->line[fc->loc], 0.0)))); } mus_float_t mus_filtered_comb_unmodulated(mus_any *ptr, mus_float_t input) { dly *fc = (dly *)ptr; return(mus_delay_unmodulated(ptr, input + (fc->yscl * fc->runf(fc->filt, fc->line[fc->loc], 0.0)))); } static mus_any_class FILTERED_COMB_CLASS = { MUS_FILTERED_COMB, (char *)S_filtered_comb, &free_delay, &describe_filtered_comb, &filtered_comb_equalp, &delay_data, &delay_set_data, &delay_length, &delay_set_length, 0, 0, 0, 0, /* freq phase */ &delay_scaler, &delay_set_scaler, &delay_fb, &delay_set_fb, &mus_filtered_comb, MUS_DELAY_LINE, NULL, &delay_interp_type, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &delay_loc, 0, 0, 0, 0, 0, 0, &filtered_comb_reset, 0, &dly_copy }; mus_any *mus_make_filtered_comb(mus_float_t scaler, int size, mus_float_t *line, int line_size, mus_interp_t type, mus_any *filt) { dly *fc; fc = (dly *)mus_make_comb(scaler, size, line, line_size, type); if (fc) { fc->core = &FILTERED_COMB_CLASS; if (filt) fc->filt = filt; else { fc->filt = mus_make_one_zero(1.0, 0.0); fc->filt_allocated = true; } fc->runf = mus_run_function(fc->filt); return((mus_any *)fc); } else return(NULL); } /* ---------------- filtered-comb-bank ---------------- */ typedef struct { mus_any_class *core; int size; mus_any **gens; mus_float_t (*cmbf)(mus_any *ptr, mus_float_t input); } fltcmb_bank; static void free_filtered_comb_bank(mus_any *ptr) { fltcmb_bank *f = (fltcmb_bank *)ptr; if (f->gens) {free(f->gens); f->gens = NULL;} free(ptr); } static mus_any *fltcmb_bank_copy(mus_any *ptr) { fltcmb_bank *g, *p; int i; p = (fltcmb_bank *)ptr; g = (fltcmb_bank *)malloc(sizeof(fltcmb_bank)); memcpy((void *)g, (void *)ptr, sizeof(fltcmb_bank)); g->gens = (mus_any **)malloc(p->size * sizeof(mus_any *)); for (i = 0; i < p->size; i++) g->gens[i] = mus_copy(p->gens[i]); return((mus_any *)g); } static mus_float_t run_filtered_comb_bank(mus_any *ptr, mus_float_t input, mus_float_t unused) { return(mus_filtered_comb_bank(ptr, input)); } static mus_long_t filtered_comb_bank_length(mus_any *ptr) { return(((fltcmb_bank *)ptr)->size); } static void filtered_comb_bank_reset(mus_any *ptr) { fltcmb_bank *f = (fltcmb_bank *)ptr; int i; for (i = 0; i < f->size; i++) mus_reset(f->gens[i]); } static bool filtered_comb_bank_equalp(mus_any *p1, mus_any *p2) { fltcmb_bank *f1 = (fltcmb_bank *)p1; fltcmb_bank *f2 = (fltcmb_bank *)p2; int i, size; if (f1 == f2) return(true); if (f1->size != f2->size) return(false); size = f1->size; for (i = 0; i < size; i++) if (!filtered_comb_equalp(f1->gens[i], f2->gens[i])) return(false); return(true); } static char *describe_filtered_comb_bank(mus_any *ptr) { fltcmb_bank *gen = (fltcmb_bank *)ptr; char *describe_buffer; describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE); snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s size: %d", mus_name(ptr), gen->size); return(describe_buffer); } static mus_any_class FILTERED_COMB_BANK_CLASS = { MUS_FILTERED_COMB_BANK, (char *)S_filtered_comb_bank, &free_filtered_comb_bank, &describe_filtered_comb_bank, &filtered_comb_bank_equalp, 0, 0, &filtered_comb_bank_length, 0, 0, 0, 0, 0, 0, 0, 0, 0, &run_filtered_comb_bank, MUS_NOT_SPECIAL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &filtered_comb_bank_reset, 0, &fltcmb_bank_copy }; static mus_float_t filtered_comb_one_zero(mus_any *ptr, mus_float_t input) { dly *gen = (dly *)ptr; mus_float_t result; result = gen->line[gen->loc]; gen->line[gen->loc] = input + mus_one_zero(gen->filt, result); /* gen->yscl folded into one_zero coeffs via smp_scl */ gen->loc++; if (gen->loc >= gen->size) gen->loc = 0; return(result); } static mus_float_t filtered_comb_bank_8(mus_any *combs, mus_float_t inval) { fltcmb_bank *c = (fltcmb_bank *)combs; mus_any **gs; gs = c->gens; return(filtered_comb_one_zero(gs[0], inval) + filtered_comb_one_zero(gs[1], inval) + filtered_comb_one_zero(gs[2], inval) + filtered_comb_one_zero(gs[3], inval) + filtered_comb_one_zero(gs[4], inval) + filtered_comb_one_zero(gs[5], inval) + filtered_comb_one_zero(gs[6], inval) + filtered_comb_one_zero(gs[7], inval)); } static mus_float_t filtered_comb_bank_any(mus_any *filtered_combs, mus_float_t inval) { int i; mus_float_t sum = 0.0; fltcmb_bank *c = (fltcmb_bank *)filtered_combs; for (i = 0; i < c->size; i++) sum += mus_filtered_comb_unmodulated(c->gens[i], inval); return(sum); } static void smp_scl(mus_any *ptr, mus_float_t scl); mus_any *mus_make_filtered_comb_bank(int size, mus_any **filtered_combs) { fltcmb_bank *gen; int i; bool zdly = false, oz = true; gen = (fltcmb_bank *)malloc(sizeof(fltcmb_bank)); gen->core = &FILTERED_COMB_BANK_CLASS; gen->size = size; gen->gens = (mus_any **)malloc(size * sizeof(mus_any *)); for (i = 0; i < size; i++) { gen->gens[i] = filtered_combs[i]; zdly = (zdly) || (((dly *)(filtered_combs[i]))->zdly); oz = (oz) && (mus_is_one_zero(((dly *)(filtered_combs[i]))->filt)); } if ((size == 8) && (oz) && (!zdly)) { gen->cmbf = filtered_comb_bank_8; for (i = 0; i < 8; i++) { dly *d; d = (dly *)gen->gens[i]; smp_scl(d->filt, d->yscl); } } else gen->cmbf = filtered_comb_bank_any; return((mus_any *)gen); } bool mus_is_filtered_comb_bank(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_FILTERED_COMB_BANK)); } mus_float_t mus_filtered_comb_bank(mus_any *filtered_combs, mus_float_t inval) { fltcmb_bank *gen = (fltcmb_bank *)filtered_combs; return((gen->cmbf)(filtered_combs, inval)); } mus_any *mus_bank_generator(mus_any *g, int i) { if (mus_is_comb_bank(g)) return(((cmb_bank *)g)->gens[i]); if (mus_is_all_pass_bank(g)) return(((allp_bank *)g)->gens[i]); if (mus_is_filtered_comb_bank(g)) return(((fltcmb_bank *)g)->gens[i]); return(NULL); } /* ---------------- sawtooth et al ---------------- */ typedef struct { mus_any_class *core; mus_float_t current_value; mus_float_t freq, phase, base, width; } sw; static void free_sw(mus_any *ptr) {free(ptr);} static mus_any *sw_copy(mus_any *ptr) { sw *g; g = (sw *)malloc(sizeof(sw)); memcpy((void *)g, (void *)ptr, sizeof(sw)); return((mus_any *)g); } mus_float_t mus_sawtooth_wave(mus_any *ptr, mus_float_t fm) { sw *gen = (sw *)ptr; mus_float_t result; result = gen->current_value; gen->phase += (gen->freq + fm); if ((gen->phase >= TWO_PI) || (gen->phase < 0.0)) { gen->phase = fmod(gen->phase, TWO_PI); if (gen->phase < 0.0) gen->phase += TWO_PI; } gen->current_value = gen->base * (gen->phase - M_PI); return(result); } static mus_float_t run_sawtooth_wave(mus_any *ptr, mus_float_t fm, mus_float_t unused) {return(mus_sawtooth_wave(ptr, fm));} bool mus_is_sawtooth_wave(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_SAWTOOTH_WAVE)); } static mus_float_t sw_freq(mus_any *ptr) {return(mus_radians_to_hz(((sw *)ptr)->freq));} static mus_float_t sw_set_freq(mus_any *ptr, mus_float_t val) {((sw *)ptr)->freq = mus_hz_to_radians(val); return(val);} static mus_float_t sw_increment(mus_any *ptr) {return(((sw *)ptr)->freq);} static mus_float_t sw_set_increment(mus_any *ptr, mus_float_t val) {((sw *)ptr)->freq = val; return(val);} static mus_float_t sw_phase(mus_any *ptr) {return(fmod(((sw *)ptr)->phase, TWO_PI));} static mus_float_t sw_set_phase(mus_any *ptr, mus_float_t val) {((sw *)ptr)->phase = val; return(val);} static mus_float_t sw_width(mus_any *ptr) {return((((sw *)ptr)->width) / ( 2 * M_PI));} static mus_float_t sw_set_width(mus_any *ptr, mus_float_t val) {((sw *)ptr)->width = (2 * M_PI * val); return(val);} static mus_float_t sawtooth_scaler(mus_any *ptr) {return(((sw *)ptr)->base * M_PI);} static mus_float_t sawtooth_set_scaler(mus_any *ptr, mus_float_t val) {((sw *)ptr)->base = val / M_PI; return(val);} static bool sw_equalp(mus_any *p1, mus_any *p2) { sw *s1, *s2; s1 = (sw *)p1; s2 = (sw *)p2; return((p1 == p2) || ((s1) && (s2) && (s1->core->type == s2->core->type) && (s1->freq == s2->freq) && (s1->phase == s2->phase) && (s1->base == s2->base) && (s1->current_value == s2->current_value))); } static char *describe_sw(mus_any *ptr) { char *describe_buffer; describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE); snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s freq: %.3fHz, phase: %.3f, amp: %.3f", mus_name(ptr), mus_frequency(ptr), mus_phase(ptr), mus_scaler(ptr)); return(describe_buffer); } static void sawtooth_reset(mus_any *ptr) { sw *gen = (sw *)ptr; gen->phase = M_PI; gen->current_value = 0.0; } static mus_any_class SAWTOOTH_WAVE_CLASS = { MUS_SAWTOOTH_WAVE, (char *)S_sawtooth_wave, &free_sw, &describe_sw, &sw_equalp, 0, 0, 0, 0, &sw_freq, &sw_set_freq, &sw_phase, &sw_set_phase, &sawtooth_scaler, &sawtooth_set_scaler, &sw_increment, &sw_set_increment, &run_sawtooth_wave, MUS_NOT_SPECIAL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &sawtooth_reset, 0, &sw_copy }; mus_any *mus_make_sawtooth_wave(mus_float_t freq, mus_float_t amp, mus_float_t phase) /* M_PI as initial phase, normally */ { sw *gen; gen = (sw *)malloc(sizeof(sw)); gen->core = &SAWTOOTH_WAVE_CLASS; gen->freq = mus_hz_to_radians(freq); gen->base = (amp / M_PI); gen->phase = phase; gen->current_value = gen->base * (gen->phase - M_PI); return((mus_any *)gen); } mus_float_t mus_square_wave(mus_any *ptr, mus_float_t fm) { sw *gen = (sw *)ptr; mus_float_t result; result = gen->current_value; gen->phase += (gen->freq + fm); if ((gen->phase >= TWO_PI) || (gen->phase < 0.0)) { gen->phase = fmod(gen->phase, TWO_PI); if (gen->phase < 0.0) gen->phase += TWO_PI; } if (gen->phase < gen->width) gen->current_value = gen->base; else gen->current_value = 0.0; return(result); } bool mus_is_square_wave(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_SQUARE_WAVE)); } static mus_float_t run_square_wave(mus_any *ptr, mus_float_t fm, mus_float_t unused) {return(mus_square_wave(ptr, fm));} static mus_float_t square_wave_scaler(mus_any *ptr) {return(((sw *)ptr)->base);} static mus_float_t square_wave_set_scaler(mus_any *ptr, mus_float_t val) {((sw *)ptr)->base = val; return(val);} static void square_wave_reset(mus_any *ptr) { sw *gen = (sw *)ptr; gen->phase = 0.0; gen->current_value = gen->base; } static mus_any_class SQUARE_WAVE_CLASS = { MUS_SQUARE_WAVE, (char *)S_square_wave, &free_sw, &describe_sw, &sw_equalp, 0, 0, 0, 0, &sw_freq, &sw_set_freq, &sw_phase, &sw_set_phase, &square_wave_scaler, &square_wave_set_scaler, &sw_increment, &sw_set_increment, &run_square_wave, MUS_NOT_SPECIAL, NULL, 0, 0, 0, &sw_width, &sw_set_width, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &square_wave_reset, 0, &sw_copy }; mus_any *mus_make_square_wave(mus_float_t freq, mus_float_t amp, mus_float_t phase) { sw *gen; gen = (sw *)malloc(sizeof(sw)); gen->core = &SQUARE_WAVE_CLASS; gen->freq = mus_hz_to_radians(freq); gen->base = amp; gen->phase = phase; gen->width = M_PI; if (gen->phase < gen->width) gen->current_value = gen->base; else gen->current_value = 0.0; return((mus_any *)gen); } mus_float_t mus_triangle_wave(mus_any *ptr, mus_float_t fm) { sw *gen = (sw *)ptr; mus_float_t result; result = gen->current_value; gen->phase += (gen->freq + fm); if ((gen->phase >= TWO_PI) || (gen->phase < 0.0)) { gen->phase = fmod(gen->phase, TWO_PI); if (gen->phase < 0.0) gen->phase += TWO_PI; } if (gen->phase < (M_PI / 2.0)) gen->current_value = gen->base * gen->phase; else if (gen->phase < (M_PI * 1.5)) gen->current_value = gen->base * (M_PI - gen->phase); else gen->current_value = gen->base * (gen->phase - TWO_PI); return(result); } mus_float_t mus_triangle_wave_unmodulated(mus_any *ptr) { sw *gen = (sw *)ptr; mus_float_t result; result = gen->current_value; gen->phase += gen->freq; TRY_AGAIN: if (gen->phase < (M_PI / 2.0)) gen->current_value = gen->base * gen->phase; else { if (gen->phase < (M_PI * 1.5)) gen->current_value = gen->base * (M_PI - gen->phase); else { if (gen->phase < TWO_PI) gen->current_value = gen->base * (gen->phase - TWO_PI); else { gen->phase -= TWO_PI; goto TRY_AGAIN; } } } return(result); } bool mus_is_triangle_wave(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_TRIANGLE_WAVE)); } static mus_float_t run_triangle_wave(mus_any *ptr, mus_float_t fm, mus_float_t unused) {return(mus_triangle_wave(ptr, fm));} static mus_float_t triangle_wave_scaler(mus_any *ptr) {return(((sw *)ptr)->base * M_PI_2);} static mus_float_t triangle_wave_set_scaler(mus_any *ptr, mus_float_t val) {((sw *)ptr)->base = (val * 2.0 / M_PI); return(val);} static void triangle_wave_reset(mus_any *ptr) { sw *gen = (sw *)ptr; gen->phase = 0.0; gen->current_value = 0.0; } static mus_any_class TRIANGLE_WAVE_CLASS = { MUS_TRIANGLE_WAVE, (char *)S_triangle_wave, &free_sw, &describe_sw, &sw_equalp, 0, 0, 0, 0, &sw_freq, &sw_set_freq, &sw_phase, &sw_set_phase, &triangle_wave_scaler, &triangle_wave_set_scaler, &sw_increment, &sw_set_increment, &run_triangle_wave, MUS_NOT_SPECIAL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &triangle_wave_reset, 0, &sw_copy }; mus_any *mus_make_triangle_wave(mus_float_t freq, mus_float_t amp, mus_float_t phase) { sw *gen; gen = (sw *)malloc(sizeof(sw)); gen->core = &TRIANGLE_WAVE_CLASS; if (freq < 0.0) { freq = -freq; phase += M_PI; if (phase > TWO_PI) phase -= TWO_PI; } gen->freq = mus_hz_to_radians(freq); gen->base = (2.0 * amp / M_PI); gen->phase = phase; if (gen->phase < M_PI_2) gen->current_value = gen->base * gen->phase; else if (gen->phase < (M_PI * 1.5)) gen->current_value = gen->base * (M_PI - gen->phase); else gen->current_value = gen->base * (gen->phase - TWO_PI); return((mus_any *)gen); } mus_float_t mus_pulse_train(mus_any *ptr, mus_float_t fm) { sw *gen = (sw *)ptr; if ((gen->phase >= TWO_PI) || (gen->phase < 0.0)) { gen->phase = fmod(gen->phase, TWO_PI); if (gen->phase < 0.0) gen->phase += TWO_PI; gen->current_value = gen->base; } else gen->current_value = 0.0; gen->phase += (gen->freq + fm); return(gen->current_value); } mus_float_t mus_pulse_train_unmodulated(mus_any *ptr) { sw *gen = (sw *)ptr; /* here unfortunately, we might get any phase: (pulse-train p (+ (pulse-train p) -1.0)) */ if ((gen->phase >= TWO_PI) || (gen->phase < 0.0)) { gen->phase = fmod(gen->phase, TWO_PI); if (gen->phase < 0.0) gen->phase += TWO_PI; gen->current_value = gen->base; } else gen->current_value = 0.0; gen->phase += gen->freq; return(gen->current_value); } bool mus_is_pulse_train(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_PULSE_TRAIN)); } static mus_float_t run_pulse_train(mus_any *ptr, mus_float_t fm, mus_float_t unused) {return(mus_pulse_train(ptr, fm));} static mus_float_t pulse_train_scaler(mus_any *ptr) {return(((sw *)ptr)->base);} static mus_float_t pulse_train_set_scaler(mus_any *ptr, mus_float_t val) {((sw *)ptr)->base = val; return(val);} static void pulse_train_reset(mus_any *ptr) { sw *gen = (sw *)ptr; gen->phase = TWO_PI; gen->current_value = 0.0; } static mus_any_class PULSE_TRAIN_CLASS = { MUS_PULSE_TRAIN, (char *)S_pulse_train, &free_sw, &describe_sw, &sw_equalp, 0, 0, 0, 0, &sw_freq, &sw_set_freq, &sw_phase, &sw_set_phase, &pulse_train_scaler, &pulse_train_set_scaler, &sw_increment, &sw_set_increment, &run_pulse_train, MUS_NOT_SPECIAL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &pulse_train_reset, 0, &sw_copy }; mus_any *mus_make_pulse_train(mus_float_t freq, mus_float_t amp, mus_float_t phase) /* TWO_PI initial phase, normally */ { sw *gen; gen = (sw *)malloc(sizeof(sw)); gen->core = &PULSE_TRAIN_CLASS; if (freq < 0.0) freq = -freq; gen->freq = mus_hz_to_radians(freq); gen->base = amp; gen->phase = phase; gen->current_value = 0.0; return((mus_any *)gen); } /* ---------------- rand, rand_interp ---------------- */ typedef struct { mus_any_class *core; mus_float_t freq, phase, base, incr, norm; mus_float_t output; mus_float_t *distribution; int distribution_size; mus_float_t (*ran_unmod)(mus_any *ptr); } noi; /* rand taken from the ANSI C standard (essentially the same as the Cmix form used earlier) */ static unsigned long randx = 1; #define INVERSE_MAX_RAND 0.0000610351563 #define INVERSE_MAX_RAND2 0.000030517579 void mus_set_rand_seed(unsigned long val) {randx = val;} unsigned long mus_rand_seed(void) {return(randx);} static mus_float_t next_random(void) { randx = randx * 1103515245 + 12345; return((mus_float_t)((unsigned int)(randx >> 16) & 32767)); } mus_float_t mus_random(mus_float_t amp) /* -amp to amp as mus_float_t */ { return(amp * (next_random() * INVERSE_MAX_RAND - 1.0)); } mus_float_t mus_frandom(mus_float_t amp) /* 0.0 to amp as mus_float_t */ { return(amp * next_random() * INVERSE_MAX_RAND2); } int mus_irandom(int amp) { return((int)(amp * next_random() * INVERSE_MAX_RAND2)); } static mus_float_t random_any(noi *gen) /* -amp to amp possibly through distribution */ { if (gen->distribution) return(gen->base * mus_array_interp(gen->distribution, next_random() * INVERSE_MAX_RAND2 * gen->distribution_size, gen->distribution_size)); return(gen->base * (next_random() * INVERSE_MAX_RAND - 1.0)); } mus_float_t mus_rand(mus_any *ptr, mus_float_t fm) { noi *gen = (noi *)ptr; if ((gen->phase >= TWO_PI) || (gen->phase < 0.0)) { gen->phase = fmod(gen->phase, TWO_PI); if (gen->phase < 0.0) gen->phase += TWO_PI; gen->output = random_any(gen); } gen->phase += (gen->freq + fm); return(gen->output); } static mus_float_t zero_unmodulated(mus_any *ptr) {return(0.0);} mus_float_t mus_rand_unmodulated(mus_any *ptr) { noi *gen = (noi *)ptr; if (gen->phase >= TWO_PI) { gen->phase -= TWO_PI; gen->output = random_any(gen); } gen->phase += gen->freq; return(gen->output); } mus_float_t mus_rand_interp(mus_any *ptr, mus_float_t fm) { /* fm can change the increment step during a ramp */ noi *gen = (noi *)ptr; gen->output += gen->incr; if (gen->output > gen->base) gen->output = gen->base; else { if (gen->output < -gen->base) gen->output = -gen->base; } if ((gen->phase >= TWO_PI) || (gen->phase < 0.0)) { gen->phase = fmod(gen->phase, TWO_PI); if (gen->phase < 0.0) gen->phase += TWO_PI; gen->incr = (random_any(gen) - gen->output) / (ceil(TWO_PI / (gen->freq + fm))); } gen->phase += (gen->freq + fm); return(gen->output); } mus_float_t mus_rand_interp_unmodulated(mus_any *ptr) { return(((noi *)ptr)->ran_unmod(ptr)); } mus_float_t (*mus_rand_interp_unmodulated_function(mus_any *g))(mus_any *gen); mus_float_t (*mus_rand_interp_unmodulated_function(mus_any *g))(mus_any *gen) { if (mus_is_rand_interp(g)) return(((noi *)g)->ran_unmod); return(NULL); } static mus_float_t rand_interp_unmodulated_with_distribution(mus_any *ptr) { noi *gen = (noi *)ptr; gen->output += gen->incr; if (gen->phase >= TWO_PI) { gen->phase -= TWO_PI; gen->incr = (random_any(gen) - gen->output) / (ceil(TWO_PI / gen->freq)); } gen->phase += gen->freq; return(gen->output); } static mus_float_t rand_interp_unmodulated(mus_any *ptr) { noi *gen = (noi *)ptr; gen->output += gen->incr; gen->phase += gen->freq; if (gen->phase >= TWO_PI) { gen->phase -= TWO_PI; randx = randx * 1103515245 + 12345; gen->incr = ((gen->base * ((mus_float_t)((unsigned int)(randx >> 16) & 32767) * INVERSE_MAX_RAND - 1.0)) - gen->output) * gen->norm; } return(gen->output); } static mus_float_t run_rand(mus_any *ptr, mus_float_t fm, mus_float_t unused) {return(mus_rand(ptr, fm));} static mus_float_t run_rand_interp(mus_any *ptr, mus_float_t fm, mus_float_t unused) {return(mus_rand_interp(ptr, fm));} bool mus_is_rand(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_RAND)); } bool mus_is_rand_interp(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_RAND_INTERP)); } static void free_noi(mus_any *ptr) {free(ptr);} static mus_any *noi_copy(mus_any *ptr) { noi *g; g = (noi *)malloc(sizeof(noi)); memcpy((void *)g, (void *)ptr, sizeof(noi)); /* if ptr->distribution, it comes from elsewhere -- we don't touch it here, * and in clm2xen, we merely wrap it. */ return((mus_any *)g); } static mus_float_t noi_freq(mus_any *ptr) {return(mus_radians_to_hz(((noi *)ptr)->freq));} static mus_float_t noi_set_freq(mus_any *ptr, mus_float_t val) { if (val < 0.0) val = -val; ((noi *)ptr)->freq = mus_hz_to_radians(val); return(val); } static mus_float_t interp_noi_set_freq(mus_any *ptr, mus_float_t val) { noi *gen = (noi *)ptr; if (val < 0.0) val = -val; gen->freq = mus_hz_to_radians(val); if (gen->freq != 0.0) gen->norm = 1.0 / (ceil(TWO_PI / gen->freq)); return(val); } static mus_float_t noi_increment(mus_any *ptr) {return(((noi *)ptr)->freq);} static mus_float_t noi_set_increment(mus_any *ptr, mus_float_t val) {((noi *)ptr)->freq = val; return(val);} static mus_float_t noi_incr(mus_any *ptr) {return(((noi *)ptr)->incr);} static mus_float_t noi_set_incr(mus_any *ptr, mus_float_t val) {((noi *)ptr)->incr = val; return(val);} static mus_float_t noi_phase(mus_any *ptr) {return(fmod(((noi *)ptr)->phase, TWO_PI));} static mus_float_t noi_set_phase(mus_any *ptr, mus_float_t val) {((noi *)ptr)->phase = val; return(val);} static mus_float_t noi_scaler(mus_any *ptr) {return(((noi *)ptr)->base);} static mus_float_t noi_set_scaler(mus_any *ptr, mus_float_t val) {((noi *)ptr)->base = val; return(val);} /* rand, not rand-interp */ static mus_float_t *noi_data(mus_any *ptr) {return(((noi *)ptr)->distribution);} static mus_long_t noi_length(mus_any *ptr) {return(((noi *)ptr)->distribution_size);} static mus_float_t randi_set_scaler(mus_any *ptr, mus_float_t val) { noi *gen = (noi *)ptr; if (val == 0.0) gen->ran_unmod = zero_unmodulated; else { if (gen->base == 0.0) { if (gen->distribution) gen->ran_unmod = rand_interp_unmodulated_with_distribution; else gen->ran_unmod = rand_interp_unmodulated; } } gen->base = val; return(val); } static void noi_reset(mus_any *ptr) { noi *gen = (noi *)ptr; gen->phase = 0.0; gen->output = 0.0; } static bool noi_equalp(mus_any *p1, mus_any *p2) { noi *g1 = (noi *)p1; noi *g2 = (noi *)p2; return((p1 == p2) || ((g1) && (g2) && (g1->core->type == g2->core->type) && (g1->freq == g2->freq) && (g1->phase == g2->phase) && (g1->output == g2->output) && (g1->incr == g2->incr) && (g1->base == g2->base) && (g1->distribution_size == g2->distribution_size) && (g1->distribution == g2->distribution))); } static char *describe_noi(mus_any *ptr) { noi *gen = (noi *)ptr; char *describe_buffer; describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE); if (mus_is_rand(ptr)) snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s freq: %.3fHz, phase: %.3f, amp: %.3f%s", mus_name(ptr), mus_frequency(ptr), mus_phase(ptr), mus_scaler(ptr), (gen->distribution) ? ", with distribution envelope" : ""); else snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s freq: %.3fHz, phase: %.3f, amp: %.3f, incr: %.3f, curval: %.3f%s", mus_name(ptr), mus_frequency(ptr), mus_phase(ptr), mus_scaler(ptr), gen->incr, gen->output, (gen->distribution) ? ", with distribution envelope" : ""); return(describe_buffer); } static mus_any_class RAND_CLASS = { MUS_RAND, (char *)S_rand, &free_noi, &describe_noi, &noi_equalp, &noi_data, 0, &noi_length, 0, &noi_freq, &noi_set_freq, &noi_phase, &noi_set_phase, &noi_scaler, &noi_set_scaler, &noi_increment, /* this is the phase increment, not the incr field */ &noi_set_increment, &run_rand, MUS_NOT_SPECIAL, NULL, 0, &noi_incr, &noi_set_incr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &noi_reset, 0, &noi_copy }; static mus_any_class RAND_INTERP_CLASS = { MUS_RAND_INTERP, (char *)S_rand_interp, &free_noi, &describe_noi, &noi_equalp, &noi_data, 0, &noi_length, 0, &noi_freq, &interp_noi_set_freq, &noi_phase, &noi_set_phase, &noi_scaler, &randi_set_scaler, &noi_increment, /* phase increment, not incr field */ &noi_set_increment, &run_rand_interp, MUS_NOT_SPECIAL, NULL, 0, &noi_incr, &noi_set_incr, /* incr field == mus_offset method */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &noi_reset, 0, &noi_copy }; mus_any *mus_make_rand(mus_float_t freq, mus_float_t base) { noi *gen; gen = (noi *)calloc(1, sizeof(noi)); gen->core = &RAND_CLASS; if (freq < 0.0) freq = -freq; gen->freq = mus_hz_to_radians(freq); gen->base = base; gen->incr = 0.0; gen->output = random_any(gen); /* this was always starting at 0.0 (changed 23-Dec-06) */ return((mus_any *)gen); } mus_any *mus_make_rand_with_distribution(mus_float_t freq, mus_float_t base, mus_float_t *distribution, int distribution_size) { noi *gen; gen = (noi *)mus_make_rand(freq, base); gen->distribution = distribution; gen->distribution_size = distribution_size; gen->output = random_any(gen); return((mus_any *)gen); } mus_any *mus_make_rand_interp(mus_float_t freq, mus_float_t base) { noi *gen; gen = (noi *)calloc(1, sizeof(noi)); gen->core = &RAND_INTERP_CLASS; /* gen->distribution = NULL; */ if (freq < 0.0) freq = -freq; gen->freq = mus_hz_to_radians(freq); gen->base = base; gen->incr = mus_random(base) * freq / sampling_rate; gen->output = 0.0; if (gen->freq != 0.0) gen->norm = 1.0 / (ceil(TWO_PI / gen->freq)); else gen->norm = 1.0; gen->ran_unmod = ((base == 0.0) ? zero_unmodulated : rand_interp_unmodulated); return((mus_any *)gen); } mus_any *mus_make_rand_interp_with_distribution(mus_float_t freq, mus_float_t base, mus_float_t *distribution, int distribution_size) { noi *gen; gen = (noi *)mus_make_rand_interp(freq, base); gen->distribution = distribution; gen->distribution_size = distribution_size; gen->ran_unmod = ((base == 0.0) ? zero_unmodulated : rand_interp_unmodulated_with_distribution); return((mus_any *)gen); } /* ---------------- simple filters ---------------- */ typedef struct { mus_any_class *core; mus_float_t xs[3]; mus_float_t ys[3]; mus_float_t x1, x2, y1, y2; } smpflt; static void free_smpflt(mus_any *ptr) {free(ptr);} static mus_any *smpflt_copy(mus_any *ptr) { smpflt *g; g = (smpflt *)malloc(sizeof(smpflt)); memcpy((void *)g, (void *)ptr, sizeof(smpflt)); return((mus_any *)g); } static bool smpflt_equalp(mus_any *p1, mus_any *p2) { smpflt *g1 = (smpflt *)p1; smpflt *g2 = (smpflt *)p2; return((p1 == p2) || ((g1->core->type == g2->core->type) && (g1->xs[0] == g2->xs[0]) && (g1->xs[1] == g2->xs[1]) && (g1->xs[2] == g2->xs[2]) && (g1->ys[1] == g2->ys[1]) && (g1->ys[2] == g2->ys[2]) && (g1->x1 == g2->x1) && (g1->x2 == g2->x2) && (g1->y1 == g2->y1) && (g1->y2 == g2->y2))); } static char *describe_smpflt(mus_any *ptr) { smpflt *gen = (smpflt *)ptr; char *describe_buffer; describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE); switch (gen->core->type) { case MUS_ONE_ZERO: snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s a0: %.3f, a1: %.3f, x1: %.3f", mus_name(ptr), gen->xs[0], gen->xs[1], gen->x1); break; case MUS_ONE_POLE: snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s a0: %.3f, b1: %.3f, y1: %.3f", mus_name(ptr), gen->xs[0], gen->ys[1], gen->y1); break; case MUS_TWO_ZERO: snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s a0: %.3f, a1: %.3f, a2: %.3f, x1: %.3f, x2: %.3f", mus_name(ptr), gen->xs[0], gen->xs[1], gen->xs[2], gen->x1, gen->x2); break; case MUS_TWO_POLE: snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s a0: %.3f, b1: %.3f, b2: %.3f, y1: %.3f, y2: %.3f", mus_name(ptr), gen->xs[0], gen->ys[1], gen->ys[2], gen->y1, gen->y2); break; } return(describe_buffer); } mus_float_t mus_one_zero(mus_any *ptr, mus_float_t input) { smpflt *gen = (smpflt *)ptr; mus_float_t result; result = (gen->xs[0] * input) + (gen->xs[1] * gen->x1); gen->x1 = input; return(result); } static mus_float_t run_one_zero(mus_any *ptr, mus_float_t input, mus_float_t unused) {return(mus_one_zero(ptr, input));} static mus_long_t one_length(mus_any *ptr) {return(1);} static mus_long_t two_length(mus_any *ptr) {return(2);} static mus_float_t smp_xcoeff(mus_any *ptr, int index) {return(((smpflt *)ptr)->xs[index]);} static mus_float_t smp_set_xcoeff(mus_any *ptr, int index, mus_float_t val) {((smpflt *)ptr)->xs[index] = val; return(val);} static mus_float_t smp_ycoeff(mus_any *ptr, int index) {return(((smpflt *)ptr)->ys[index]);} static mus_float_t smp_set_ycoeff(mus_any *ptr, int index, mus_float_t val) {((smpflt *)ptr)->ys[index] = val; return(val);} static mus_float_t *smp_xcoeffs(mus_any *ptr) {return(((smpflt *)ptr)->xs);} static mus_float_t *smp_ycoeffs(mus_any *ptr) {return(((smpflt *)ptr)->ys);} static void smp_scl(mus_any *ptr, mus_float_t scl) {smpflt *g = (smpflt *)ptr; g->xs[0] *= scl; g->xs[1] *= scl;} static void smpflt_reset(mus_any *ptr) { smpflt *gen = (smpflt *)ptr; gen->x1 = 0.0; gen->x2 = 0.0; gen->y1 = 0.0; gen->y2 = 0.0; } static mus_any_class ONE_ZERO_CLASS = { MUS_ONE_ZERO, (char *)S_one_zero, &free_smpflt, &describe_smpflt, &smpflt_equalp, 0, 0, &one_length, 0, 0, 0, 0, 0, 0, 0, 0, 0, &run_one_zero, MUS_SIMPLE_FILTER, NULL, 0, 0, 0, 0, 0, &smp_xcoeff, &smp_set_xcoeff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &smp_xcoeffs, &smp_ycoeffs, &smpflt_reset, 0, &smpflt_copy }; mus_any *mus_make_one_zero(mus_float_t a0, mus_float_t a1) { smpflt *gen; gen = (smpflt *)calloc(1, sizeof(smpflt)); gen->core = &ONE_ZERO_CLASS; gen->xs[0] = a0; gen->xs[1] = a1; return((mus_any *)gen); } bool mus_is_one_zero(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_ONE_ZERO)); } mus_float_t mus_one_pole(mus_any *ptr, mus_float_t input) { smpflt *gen = (smpflt *)ptr; gen->y1 = (gen->xs[0] * input) - (gen->ys[1] * gen->y1); return(gen->y1); } /* incrementer: (make-one-pole 1.0 -1.0) */ static mus_float_t run_one_pole(mus_any *ptr, mus_float_t input, mus_float_t unused) {return(mus_one_pole(ptr, input));} static mus_any_class ONE_POLE_CLASS = { MUS_ONE_POLE, (char *)S_one_pole, &free_smpflt, &describe_smpflt, &smpflt_equalp, 0, 0, &one_length, 0, 0, 0, 0, 0, 0, 0, 0, 0, &run_one_pole, MUS_SIMPLE_FILTER, NULL, 0, 0, 0, 0, 0, &smp_xcoeff, &smp_set_xcoeff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &smp_ycoeff, &smp_set_ycoeff, &smp_xcoeffs, &smp_ycoeffs, &smpflt_reset, 0, &smpflt_copy }; mus_any *mus_make_one_pole(mus_float_t a0, mus_float_t b1) { smpflt *gen; gen = (smpflt *)calloc(1, sizeof(smpflt)); gen->core = &ONE_POLE_CLASS; gen->xs[0] = a0; gen->ys[1] = b1; return((mus_any *)gen); } bool mus_is_one_pole(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_ONE_POLE)); } mus_float_t mus_two_zero(mus_any *ptr, mus_float_t input) { smpflt *gen = (smpflt *)ptr; mus_float_t result; result = (gen->xs[0] * input) + (gen->xs[1] * gen->x1) + (gen->xs[2] * gen->x2); gen->x2 = gen->x1; gen->x1 = input; return(result); } static mus_float_t run_two_zero(mus_any *ptr, mus_float_t input, mus_float_t unused) {return(mus_two_zero(ptr, input));} static mus_float_t two_zero_radius(mus_any *ptr) { smpflt *gen = (smpflt *)ptr; return(sqrt(gen->xs[2])); } static mus_float_t two_zero_set_radius(mus_any *ptr, mus_float_t new_radius) { smpflt *gen = (smpflt *)ptr; gen->xs[1] = -2.0 * new_radius * cos(mus_hz_to_radians(mus_frequency(ptr))); gen->xs[2] = new_radius * new_radius; return(new_radius); } static mus_float_t two_zero_frequency(mus_any *ptr) { smpflt *gen = (smpflt *)ptr; return(mus_radians_to_hz(acos(gen->xs[1] / (-2.0 * two_zero_radius(ptr))))); } static mus_float_t two_zero_set_frequency(mus_any *ptr, mus_float_t new_freq) { smpflt *gen = (smpflt *)ptr; gen->xs[1] = -2.0 * mus_scaler(ptr) * cos(mus_hz_to_radians(new_freq)); return(new_freq); } static mus_any_class TWO_ZERO_CLASS = { MUS_TWO_ZERO, (char *)S_two_zero, &free_smpflt, &describe_smpflt, &smpflt_equalp, 0, 0, &two_length, 0, &two_zero_frequency, &two_zero_set_frequency, 0, 0, &two_zero_radius, &two_zero_set_radius, 0, 0, &run_two_zero, MUS_SIMPLE_FILTER, NULL, 0, 0, 0, 0, 0, &smp_xcoeff, &smp_set_xcoeff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &smp_xcoeffs, &smp_ycoeffs, &smpflt_reset, 0, &smpflt_copy }; mus_any *mus_make_two_zero(mus_float_t a0, mus_float_t a1, mus_float_t a2) { smpflt *gen; gen = (smpflt *)calloc(1, sizeof(smpflt)); gen->core = &TWO_ZERO_CLASS; gen->xs[0] = a0; gen->xs[1] = a1; gen->xs[2] = a2; return((mus_any *)gen); } bool mus_is_two_zero(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_TWO_ZERO)); } mus_any *mus_make_two_zero_from_frequency_and_radius(mus_float_t frequency, mus_float_t radius) { return(mus_make_two_zero(1.0, -2.0 * radius * cos(mus_hz_to_radians(frequency)), radius * radius)); } mus_float_t mus_two_pole(mus_any *ptr, mus_float_t input) { smpflt *gen = (smpflt *)ptr; mus_float_t result; result = (gen->xs[0] * input) - (gen->ys[1] * gen->y1) - (gen->ys[2] * gen->y2); gen->y2 = gen->y1; gen->y1 = result; return(result); } static mus_float_t run_two_pole(mus_any *ptr, mus_float_t input, mus_float_t unused) {return(mus_two_pole(ptr, input));} static mus_float_t two_pole_radius(mus_any *ptr) { smpflt *gen = (smpflt *)ptr; return(sqrt(gen->ys[2])); } static mus_float_t two_pole_set_radius(mus_any *ptr, mus_float_t new_radius) { smpflt *gen = (smpflt *)ptr; gen->ys[1] = -2.0 * new_radius * cos(mus_hz_to_radians(mus_frequency(ptr))); gen->ys[2] = new_radius * new_radius; return(new_radius); } static mus_float_t two_pole_frequency(mus_any *ptr) { smpflt *gen = (smpflt *)ptr; return(mus_radians_to_hz(acos(gen->ys[1] / (-2.0 * two_pole_radius(ptr))))); } static mus_float_t two_pole_set_frequency(mus_any *ptr, mus_float_t new_freq) { smpflt *gen = (smpflt *)ptr; gen->ys[1] = -2.0 * mus_scaler(ptr) * cos(mus_hz_to_radians(new_freq)); return(new_freq); } static mus_any_class TWO_POLE_CLASS = { MUS_TWO_POLE, (char *)S_two_pole, &free_smpflt, &describe_smpflt, &smpflt_equalp, 0, 0, &two_length, 0, &two_pole_frequency, &two_pole_set_frequency, 0, 0, &two_pole_radius, &two_pole_set_radius, 0, 0, &run_two_pole, MUS_SIMPLE_FILTER, NULL, 0, 0, 0, 0, 0, &smp_xcoeff, &smp_set_xcoeff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &smp_ycoeff, &smp_set_ycoeff, &smp_xcoeffs, &smp_ycoeffs, &smpflt_reset, 0, &smpflt_copy }; mus_any *mus_make_two_pole(mus_float_t a0, mus_float_t b1, mus_float_t b2) { smpflt *gen; gen = (smpflt *)calloc(1, sizeof(smpflt)); gen->core = &TWO_POLE_CLASS; gen->xs[0] = a0; gen->ys[1] = b1; gen->ys[2] = b2; return((mus_any *)gen); } bool mus_is_two_pole(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_TWO_POLE)); } mus_any *mus_make_two_pole_from_frequency_and_radius(mus_float_t frequency, mus_float_t radius) { return(mus_make_two_pole(1.0, -2.0 * radius * cos(mus_hz_to_radians(frequency)), radius * radius)); } /* ---------------- formant ---------------- */ typedef struct { mus_any_class *core; mus_float_t frequency, radius; mus_float_t x1, x2, y1, y2; mus_float_t rr, gain, fdbk; } frm; static void free_frm(mus_any *ptr) {free(ptr);} static mus_any *frm_copy(mus_any *ptr) { frm *g; g = (frm *)malloc(sizeof(frm)); memcpy((void *)g, (void *)ptr, sizeof(frm)); return((mus_any *)g); } bool mus_is_formant(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_FORMANT)); } static void frm_reset(mus_any *ptr) { frm *gen = (frm *)ptr; gen->x1 = 0.0; gen->x2 = 0.0; gen->y1 = 0.0; gen->y2 = 0.0; } static bool frm_equalp(mus_any *p1, mus_any *p2) { frm *g1 = (frm *)p1; frm *g2 = (frm *)p2; return((p1 == p2) || ((g1->core->type == g2->core->type) && (g1->radius == g2->radius) && (g1->frequency == g2->frequency) && (g1->x1 == g2->x1) && (g1->x2 == g2->x2) && (g1->y1 == g2->y1) && (g1->y2 == g2->y2))); } static char *describe_formant(mus_any *ptr) { frm *gen = (frm *)ptr; char *describe_buffer; describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE); snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s frequency: %.3f, radius: %.3f", mus_name(ptr), mus_radians_to_hz(gen->frequency), gen->radius); return(describe_buffer); } mus_float_t mus_formant(mus_any *ptr, mus_float_t input) { frm *gen = (frm *)ptr; mus_float_t x0, y0; x0 = gen->gain * input; y0 = x0 - gen->x2 + (gen->fdbk * gen->y1) - (gen->rr * gen->y2); gen->y2 = gen->y1; gen->y1 = y0; gen->x2 = gen->x1; gen->x1 = x0; return(y0); } static mus_float_t run_formant(mus_any *ptr, mus_float_t input, mus_float_t unused) {return(mus_formant(ptr, input));} static void mus_set_formant_radius_and_frequency_in_radians(mus_any *ptr, mus_float_t radius, mus_float_t freq_in_radians) { frm *gen = (frm *)ptr; gen->radius = radius; gen->frequency = freq_in_radians; gen->rr = radius * radius; gen->gain = (1.0 - gen->rr) * 0.5; gen->fdbk = 2.0 * radius * cos(freq_in_radians); } void mus_set_formant_radius_and_frequency(mus_any *ptr, mus_float_t radius, mus_float_t freq_in_hz) { mus_set_formant_radius_and_frequency_in_radians(ptr, radius, mus_hz_to_radians(freq_in_hz)); } static mus_float_t formant_frequency(mus_any *ptr) {return(mus_radians_to_hz(((frm *)ptr)->frequency));} mus_float_t mus_set_formant_frequency(mus_any *ptr, mus_float_t freq_in_hz) { frm *gen = (frm *)ptr; mus_float_t fw; fw = mus_hz_to_radians(freq_in_hz); gen->frequency = fw; gen->fdbk = 2.0 * gen->radius * cos(fw); return(freq_in_hz); } mus_float_t mus_formant_with_frequency(mus_any *ptr, mus_float_t input, mus_float_t freq_in_radians) { frm *gen = (frm *)ptr; if (gen->frequency != freq_in_radians) { gen->frequency = freq_in_radians; gen->fdbk = 2.0 * gen->radius * cos(freq_in_radians); } return(mus_formant(ptr, input)); } static mus_float_t formant_radius(mus_any *ptr) {return(((frm *)ptr)->radius);} static mus_float_t formant_set_radius(mus_any *ptr, mus_float_t val) { mus_set_formant_radius_and_frequency_in_radians(ptr, val, ((frm *)ptr)->frequency); return(val); } static mus_any_class FORMANT_CLASS = { MUS_FORMANT, (char *)S_formant, &free_frm, &describe_formant, &frm_equalp, 0, 0, &two_length, 0, &formant_frequency, &mus_set_formant_frequency, 0, 0, &formant_radius, &formant_set_radius, 0, 0, &run_formant, MUS_SIMPLE_FILTER, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &frm_reset, 0, &frm_copy }; mus_any *mus_make_formant(mus_float_t frequency, mus_float_t radius) { frm *gen; gen = (frm *)calloc(1, sizeof(frm)); gen->core = &FORMANT_CLASS; mus_set_formant_radius_and_frequency((mus_any *)gen, radius, frequency); return((mus_any *)gen); } /* ---------------- formant-bank ---------------- */ typedef struct { mus_any_class *core; int size, mctr; mus_float_t *x0, *x1, *x2, *y0, *y1, *y2, *amps, *rr, *fdbk, *gain; mus_float_t c1, c2; mus_float_t (*one_input)(mus_any *fbank, mus_float_t inval); mus_float_t (*many_inputs)(mus_any *fbank, mus_float_t *inval); } frm_bank; static void free_formant_bank(mus_any *ptr) { frm_bank *f = (frm_bank *)ptr; if (f->x0) {free(f->x0); f->x0 = NULL;} if (f->x1) {free(f->x1); f->x1 = NULL;} if (f->x2) {free(f->x2); f->x2 = NULL;} if (f->y0) {free(f->y0); f->y0 = NULL;} if (f->y1) {free(f->y1); f->y1 = NULL;} if (f->y2) {free(f->y2); f->y2 = NULL;} if (f->rr) {free(f->rr); f->rr = NULL;} if (f->fdbk) {free(f->fdbk); f->fdbk = NULL;} if (f->gain) {free(f->gain); f->gain = NULL;} free(ptr); } static mus_any *frm_bank_copy(mus_any *ptr) { frm_bank *g, *p; int bytes; p = (frm_bank *)ptr; g = (frm_bank *)malloc(sizeof(frm_bank)); memcpy((void *)g, (void *)ptr, sizeof(frm_bank)); bytes = g->size * sizeof(mus_float_t); g->x0 = (mus_float_t *)malloc(bytes); memcpy((void *)(g->x0), (void *)(p->x0), bytes); g->x1 = (mus_float_t *)malloc(bytes); memcpy((void *)(g->x1), (void *)(p->x1), bytes); g->x2 = (mus_float_t *)malloc(bytes); memcpy((void *)(g->x2), (void *)(p->x2), bytes); g->y0 = (mus_float_t *)malloc(bytes); memcpy((void *)(g->y0), (void *)(p->y0), bytes); g->y1 = (mus_float_t *)malloc(bytes); memcpy((void *)(g->y1), (void *)(p->y1), bytes); g->y2 = (mus_float_t *)malloc(bytes); memcpy((void *)(g->y2), (void *)(p->y2), bytes); g->rr = (mus_float_t *)malloc(bytes); memcpy((void *)(g->rr), (void *)(p->rr), bytes); g->fdbk = (mus_float_t *)malloc(bytes); memcpy((void *)(g->fdbk), (void *)(p->fdbk), bytes); g->gain = (mus_float_t *)malloc(bytes); memcpy((void *)(g->gain), (void *)(p->gain), bytes); return((mus_any *)g); } static mus_float_t run_formant_bank(mus_any *ptr, mus_float_t input, mus_float_t unused) { return(mus_formant_bank(ptr, input)); } static mus_long_t formant_bank_length(mus_any *ptr) { return(((frm_bank *)ptr)->size); } static void formant_bank_reset(mus_any *ptr) { frm_bank *f = (frm_bank *)ptr; int size; size = f->size * sizeof(mus_float_t); memset((void *)(f->x0), 0, size); memset((void *)(f->x1), 0, size); memset((void *)(f->x2), 0, size); memset((void *)(f->y0), 0, size); memset((void *)(f->y1), 0, size); memset((void *)(f->y2), 0, size); } static bool formant_bank_equalp(mus_any *p1, mus_any *p2) { frm_bank *f1 = (frm_bank *)p1; frm_bank *f2 = (frm_bank *)p2; #if 0 int i, size; #endif if (f1 == f2) return(true); if (f1->size != f2->size) return(false); #if 0 size = f1->size; for (i = 0; i < size; i++) if (!frm_equalp(f1->gens[i], f2->gens[i])) return(false); #endif /* now check the locals... */ return(true); } static char *describe_formant_bank(mus_any *ptr) { frm_bank *gen = (frm_bank *)ptr; char *describe_buffer; describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE); snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s size: %d", mus_name(ptr), gen->size); return(describe_buffer); } mus_float_t mus_formant_bank(mus_any *fbank, mus_float_t inval) { frm_bank *bank = (frm_bank *)fbank; return(bank->one_input(fbank, inval)); } mus_float_t mus_formant_bank_with_inputs(mus_any *fbank, mus_float_t *inval) { frm_bank *bank = (frm_bank *)fbank; return(bank->many_inputs(fbank, inval)); } static mus_float_t fb_one_with_amps(mus_any *fbank, mus_float_t inval) { frm_bank *bank = (frm_bank *)fbank; int i, size4; mus_float_t sum = 0.0; mus_float_t *x0, *x1, *x2, *y0, *y1, *y2, *amps, *rr, *fdbk, *gain; x0 = bank->x0; x1 = bank->x1; x2 = bank->x2; y0 = bank->y0; y1 = bank->y1; y2 = bank->y2; rr = bank->rr; fdbk = bank->fdbk; gain = bank->gain; amps = bank->amps; size4 = bank->size - 4; i = 0; while (i <= size4) { x0[i] = gain[i] * inval; y0[i] = x0[i] - x2[i] + (fdbk[i] * y1[i]) - (rr[i] * y2[i]); sum += amps[i] * y0[i]; i++; x0[i] = gain[i] * inval; y0[i] = x0[i] - x2[i] + (fdbk[i] * y1[i]) - (rr[i] * y2[i]); sum += amps[i] * y0[i]; i++; x0[i] = gain[i] * inval; y0[i] = x0[i] - x2[i] + (fdbk[i] * y1[i]) - (rr[i] * y2[i]); sum += amps[i] * y0[i]; i++; x0[i] = gain[i] * inval; y0[i] = x0[i] - x2[i] + (fdbk[i] * y1[i]) - (rr[i] * y2[i]); sum += amps[i] * y0[i]; i++; } for (; i < bank->size; i++) { x0[i] = gain[i] * inval; y0[i] = x0[i] - x2[i] + (fdbk[i] * y1[i]) - (rr[i] * y2[i]); sum += amps[i] * y0[i]; } bank->x2 = x1; bank->x1 = x0; bank->x0 = x2; bank->y2 = y1; bank->y1 = y0; bank->y0 = y2; return(sum); } static mus_float_t fb_one_without_amps(mus_any *fbank, mus_float_t inval) { frm_bank *bank = (frm_bank *)fbank; int i; mus_float_t sum = 0.0; mus_float_t *x0, *x1, *x2, *y0, *y1, *y2, *rr, *fdbk, *gain; x0 = bank->x0; x1 = bank->x1; x2 = bank->x2; y0 = bank->y0; y1 = bank->y1; y2 = bank->y2; rr = bank->rr; fdbk = bank->fdbk; gain = bank->gain; for (i = 0; i < bank->size; i++) { x0[i] = gain[i] * inval; y0[i] = x0[i] - x2[i] + (fdbk[i] * y1[i]) - (rr[i] * y2[i]); sum += y0[i]; } bank->x2 = x1; bank->x1 = x0; bank->x0 = x2; bank->y2 = y1; bank->y1 = y0; bank->y0 = y2; return(sum); } static mus_float_t fb_many_with_amps(mus_any *fbank, mus_float_t *inval) { frm_bank *bank = (frm_bank *)fbank; int i; mus_float_t sum = 0.0; mus_float_t *x0, *x1, *x2, *y0, *y1, *y2, *amps, *rr, *fdbk, *gain; x0 = bank->x0; x1 = bank->x1; x2 = bank->x2; y0 = bank->y0; y1 = bank->y1; y2 = bank->y2; rr = bank->rr; fdbk = bank->fdbk; gain = bank->gain; amps = bank->amps; for (i = 0; i < bank->size; i++) { x0[i] = gain[i] * inval[i]; y0[i] = x0[i] - x2[i] + (fdbk[i] * y1[i]) - (rr[i] * y2[i]); sum += amps[i] * y0[i]; } bank->x2 = x1; bank->x1 = x0; bank->x0 = x2; bank->y2 = y1; bank->y1 = y0; bank->y0 = y2; return(sum); } static mus_float_t fb_many_without_amps(mus_any *fbank, mus_float_t *inval) { frm_bank *bank = (frm_bank *)fbank; int i; mus_float_t sum = 0.0; mus_float_t *x0, *x1, *x2, *y0, *y1, *y2, *rr, *fdbk, *gain; x0 = bank->x0; x1 = bank->x1; x2 = bank->x2; y0 = bank->y0; y1 = bank->y1; y2 = bank->y2; rr = bank->rr; fdbk = bank->fdbk; gain = bank->gain; for (i = 0; i < bank->size; i++) { x0[i] = gain[i] * inval[i]; y0[i] = x0[i] - x2[i] + (fdbk[i] * y1[i]) - (rr[i] * y2[i]); sum += y0[i]; } bank->x2 = x1; bank->x1 = x0; bank->x0 = x2; bank->y2 = y1; bank->y1 = y0; bank->y0 = y2; return(sum); } static mus_float_t fb_one_with_amps_c1_c2(mus_any *fbank, mus_float_t inval) { frm_bank *bank = (frm_bank *)fbank; int i, size4; mus_float_t sum = 0.0, rr, gain; mus_float_t *x0, *x1, *x2, *y0, *y1, *y2, *amps, *fdbk; x0 = bank->x0; x1 = bank->x1; x2 = bank->x2; y0 = bank->y0; y1 = bank->y1; y2 = bank->y2; fdbk = bank->fdbk; amps = bank->amps; size4 = bank->size - 4; bank->mctr++; rr = bank->c1; gain = (bank->c2 * inval); x0[0] = gain; if (bank->mctr < 3) { i = 0; while (i <= size4) { y0[i] = gain - x2[i] + (fdbk[i] * y1[i]) - (rr * y2[i]); sum += amps[i] * y0[i]; i++; /* in isolation this looks like the x0[i]-x2[i] business could be handled outside the loop * by a single float, but formant-bank can be called in the same do-loop both with and * without multiple inputs, so fb_one has to be completely compatible sample-by-sample * with fb_many. Since we can't predict here when we'll need bank->x2, we can't collapse * this calculation. * * If we know we've had 2 fb_one calls just before this one, then x2[i] are all the same, * x0[i] will all be the same in this loop, so x0[i] - x2[i] can be collapsed, but * we still need to set x0[0]=gain: enter mctr. * * So in the current case, we can save x0[0]=gain -> x1 -> x2, then in fm_many * mctr=1 -- x2 is ok, x1[0] needs to be propogated * mctr>1 -- x2 and x1 need propogation * On the other side, if mctr>=3, then x2[i] was not set, so don't access it. */ y0[i] = gain - x2[i] + (fdbk[i] * y1[i]) - (rr * y2[i]); sum += amps[i] * y0[i]; i++; y0[i] = gain - x2[i] + (fdbk[i] * y1[i]) - (rr * y2[i]); sum += amps[i] * y0[i]; i++; y0[i] = gain - x2[i] + (fdbk[i] * y1[i]) - (rr * y2[i]); sum += amps[i] * y0[i]; i++; } for (; i < bank->size; i++) { y0[i] = gain - x2[i] + (fdbk[i] * y1[i]) - (rr * y2[i]); sum += amps[i] * y0[i]; } } else { mus_float_t g2; g2 = gain - x2[0]; i = 0; while (i <= size4) { y0[i] = g2 + (fdbk[i] * y1[i]) - (rr * y2[i]); sum += amps[i] * y0[i]; i++; y0[i] = g2 + (fdbk[i] * y1[i]) - (rr * y2[i]); sum += amps[i] * y0[i]; i++; y0[i] = g2 + (fdbk[i] * y1[i]) - (rr * y2[i]); sum += amps[i] * y0[i]; i++; y0[i] = g2 + (fdbk[i] * y1[i]) - (rr * y2[i]); sum += amps[i] * y0[i]; i++; } for (; i < bank->size; i++) { y0[i] = g2 + (fdbk[i] * y1[i]) - (rr * y2[i]); sum += amps[i] * y0[i]; } } bank->x2 = x1; bank->x1 = x0; bank->x0 = x2; bank->y2 = y1; bank->y1 = y0; bank->y0 = y2; return(sum); } static mus_float_t fb_many_with_amps_c1_c2(mus_any *fbank, mus_float_t *inval) { frm_bank *bank = (frm_bank *)fbank; int i, size4; mus_float_t sum = 0.0, rr, gain; mus_float_t *x0, *x1, *x2, *y0, *y1, *y2, *amps, *fdbk; x0 = bank->x0; x1 = bank->x1; x2 = bank->x2; y0 = bank->y0; y1 = bank->y1; y2 = bank->y2; fdbk = bank->fdbk; amps = bank->amps; size4 = bank->size - 4; if (bank->mctr > 0) { if (bank->mctr == 1) { for (i = 1; i < bank->size; i++) x1[i] = x1[0]; } else { for (i = 1; i < bank->size; i++) {x1[i] = x1[0]; x2[i] = x2[0];} } bank->mctr = 0; } rr = bank->c1; gain = bank->c2; i = 0; while (i <= size4) { x0[i] = gain * inval[i]; y0[i] = x0[i] - x2[i] + (fdbk[i] * y1[i]) - (rr * y2[i]); sum += amps[i] * y0[i]; i++; x0[i] = gain * inval[i]; y0[i] = x0[i] - x2[i] + (fdbk[i] * y1[i]) - (rr * y2[i]); sum += amps[i] * y0[i]; i++; x0[i] = gain * inval[i]; y0[i] = x0[i] - x2[i] + (fdbk[i] * y1[i]) - (rr * y2[i]); sum += amps[i] * y0[i]; i++; x0[i] = gain * inval[i]; y0[i] = x0[i] - x2[i] + (fdbk[i] * y1[i]) - (rr * y2[i]); sum += amps[i] * y0[i]; i++; } for (; i < bank->size; i++) { x0[i] = gain * inval[i]; y0[i] = x0[i] - x2[i] + (fdbk[i] * y1[i]) - (rr * y2[i]); sum += amps[i] * y0[i]; } bank->x2 = x1; bank->x1 = x0; bank->x0 = x2; bank->y2 = y1; bank->y1 = y0; bank->y0 = y2; return(sum); } static mus_float_t fb_one_without_amps_c1_c2(mus_any *fbank, mus_float_t inval) { frm_bank *bank = (frm_bank *)fbank; int i, size4; mus_float_t sum = 0.0, rr, gain; mus_float_t *x0, *x1, *x2, *y0, *y1, *y2, *fdbk; x0 = bank->x0; x1 = bank->x1; x2 = bank->x2; y0 = bank->y0; y1 = bank->y1; y2 = bank->y2; fdbk = bank->fdbk; size4 = bank->size - 4; bank->mctr++; rr = bank->c1; gain = (bank->c2 * inval); x0[0] = gain; if (bank->mctr < 3) { i = 0; while (i <= size4) { y0[i] = gain - x2[i] + (fdbk[i] * y1[i]) - (rr * y2[i]); sum += y0[i]; i++; y0[i] = gain - x2[i] + (fdbk[i] * y1[i]) - (rr * y2[i]); sum += y0[i]; i++; y0[i] = gain - x2[i] + (fdbk[i] * y1[i]) - (rr * y2[i]); sum += y0[i]; i++; y0[i] = gain - x2[i] + (fdbk[i] * y1[i]) - (rr * y2[i]); sum += y0[i]; i++; } for (; i < bank->size; i++) { y0[i] = gain - x2[i] + (fdbk[i] * y1[i]) - (rr * y2[i]); sum += y0[i]; } } else { mus_float_t g2; g2 = gain - x2[0]; i = 0; while (i <= size4) { y0[i] = g2 + (fdbk[i] * y1[i]) - (rr * y2[i]); sum += y0[i]; i++; y0[i] = g2 + (fdbk[i] * y1[i]) - (rr * y2[i]); sum += y0[i]; i++; y0[i] = g2 + (fdbk[i] * y1[i]) - (rr * y2[i]); sum += y0[i]; i++; y0[i] = g2 + (fdbk[i] * y1[i]) - (rr * y2[i]); sum += y0[i]; i++; } for (; i < bank->size; i++) { y0[i] = g2 + (fdbk[i] * y1[i]) - (rr * y2[i]); sum += y0[i]; } } bank->x2 = x1; bank->x1 = x0; bank->x0 = x2; bank->y2 = y1; bank->y1 = y0; bank->y0 = y2; return(sum); } static mus_float_t fb_many_without_amps_c1_c2(mus_any *fbank, mus_float_t *inval) { frm_bank *bank = (frm_bank *)fbank; int i, size4; mus_float_t sum = 0.0, rr, gain; mus_float_t *x0, *x1, *x2, *y0, *y1, *y2, *fdbk; x0 = bank->x0; x1 = bank->x1; x2 = bank->x2; y0 = bank->y0; y1 = bank->y1; y2 = bank->y2; fdbk = bank->fdbk; size4 = bank->size - 4; if (bank->mctr > 0) { if (bank->mctr == 1) { for (i = 1; i < bank->size; i++) x1[i] = x1[0]; } else { for (i = 1; i < bank->size; i++) {x1[i] = x1[0]; x2[i] = x2[0];} } bank->mctr = 0; } rr = bank->c1; gain = bank->c2; i = 0; while (i <= size4) { x0[i] = gain * inval[i]; y0[i] = x0[i] - x2[i] + (fdbk[i] * y1[i]) - (rr * y2[i]); sum += y0[i]; i++; x0[i] = gain * inval[i]; y0[i] = x0[i] - x2[i] + (fdbk[i] * y1[i]) - (rr * y2[i]); sum += y0[i]; i++; x0[i] = gain * inval[i]; y0[i] = x0[i] - x2[i] + (fdbk[i] * y1[i]) - (rr * y2[i]); sum += y0[i]; i++; x0[i] = gain * inval[i]; y0[i] = x0[i] - x2[i] + (fdbk[i] * y1[i]) - (rr * y2[i]); sum += y0[i]; i++; } for (; i < bank->size; i++) { x0[i] = gain * inval[i]; y0[i] = x0[i] - x2[i] + (fdbk[i] * y1[i]) - (rr * y2[i]); sum += y0[i]; } bank->x2 = x1; bank->x1 = x0; bank->x0 = x2; bank->y2 = y1; bank->y1 = y0; bank->y0 = y2; return(sum); } static mus_any_class FORMANT_BANK_CLASS = { MUS_FORMANT_BANK, (char *)S_formant_bank, &free_formant_bank, &describe_formant_bank, &formant_bank_equalp, 0, 0, &formant_bank_length, 0, 0, 0, 0, 0, 0, 0, 0, 0, &run_formant_bank, MUS_NOT_SPECIAL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &formant_bank_reset, 0, &frm_bank_copy }; mus_any *mus_make_formant_bank(int size, mus_any **formants, mus_float_t *amps) { frm_bank *gen; int i; gen = (frm_bank *)malloc(sizeof(frm_bank)); gen->core = &FORMANT_BANK_CLASS; gen->size = size; gen->mctr = 0; gen->x0 = (mus_float_t *)calloc(size, sizeof(mus_float_t)); gen->x1 = (mus_float_t *)calloc(size, sizeof(mus_float_t)); gen->x2 = (mus_float_t *)calloc(size, sizeof(mus_float_t)); gen->y0 = (mus_float_t *)calloc(size, sizeof(mus_float_t)); gen->y1 = (mus_float_t *)calloc(size, sizeof(mus_float_t)); gen->y2 = (mus_float_t *)calloc(size, sizeof(mus_float_t)); gen->amps = amps; gen->rr = (mus_float_t *)malloc(size * sizeof(mus_float_t)); gen->fdbk = (mus_float_t *)malloc(size * sizeof(mus_float_t)); gen->gain = (mus_float_t *)malloc(size * sizeof(mus_float_t)); if (amps) { gen->one_input = fb_one_with_amps; gen->many_inputs = fb_many_with_amps; } else { gen->one_input = fb_one_without_amps; gen->many_inputs = fb_many_without_amps; } for (i = 0; i < size; i++) { frm *g; g = (frm *)formants[i]; gen->rr[i] = g->rr; gen->fdbk[i] = g->fdbk; gen->gain[i] = g->gain; /* one case: 1.0 val 0.0 throughout * also c1 x c2 */ } gen->c1 = gen->rr[0]; gen->c2 = gen->gain[0]; for (i = 1; i < size; i++) if ((gen->rr[i] != gen->c1) || (gen->gain[i] != gen->c2)) return((mus_any *)gen); if (amps) { gen->one_input = fb_one_with_amps_c1_c2; gen->many_inputs = fb_many_with_amps_c1_c2; } else { gen->one_input = fb_one_without_amps_c1_c2; gen->many_inputs = fb_many_without_amps_c1_c2; } return((mus_any *)gen); } bool mus_is_formant_bank(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_FORMANT_BANK)); } /* ---------------- firmant ---------------- */ static char *describe_firmant(mus_any *ptr) { frm *gen = (frm *)ptr; char *describe_buffer; describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE); snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s frequency: %.3f, radius: %.3f", mus_name(ptr), mus_radians_to_hz(gen->frequency), gen->radius); return(describe_buffer); } static mus_float_t firmant_frequency(mus_any *ptr) {return(mus_radians_to_hz(((frm *)ptr)->frequency));} static mus_float_t firmant_set_frequency(mus_any *ptr, mus_float_t freq_in_hz) { frm *gen = (frm *)ptr; mus_float_t fw; fw = mus_hz_to_radians(freq_in_hz); gen->frequency = fw; gen->fdbk = 2.0 * sin(gen->frequency * 0.5); return(freq_in_hz); } static mus_float_t firmant_radius(mus_any *ptr) {return(((frm *)ptr)->radius);} static mus_float_t firmant_set_radius(mus_any *ptr, mus_float_t radius) { frm *gen = (frm *)ptr; gen->radius = radius; gen->gain = 1.0 - radius * radius; return(radius); } bool mus_is_firmant(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_FIRMANT)); } mus_float_t mus_firmant(mus_any *ptr, mus_float_t input) { frm *gen = (frm *)ptr; mus_float_t xn1, yn1; xn1 = gen->gain * input + gen->radius * (gen->x1 - gen->fdbk * gen->y1); yn1 = gen->radius * (gen->fdbk * xn1 + gen->y1); gen->x1 = xn1; gen->y1 = yn1; return(yn1); } mus_float_t mus_firmant_with_frequency(mus_any *ptr, mus_float_t input, mus_float_t freq_in_radians) { frm *gen = (frm *)ptr; gen->frequency = freq_in_radians; gen->fdbk = 2.0 * sin(gen->frequency * 0.5); return(mus_firmant(ptr, input)); } static mus_float_t run_firmant(mus_any *ptr, mus_float_t input, mus_float_t unused) {return(mus_firmant(ptr, input));} static mus_any_class FIRMANT_CLASS = { MUS_FIRMANT, (char *)S_firmant, &free_frm, &describe_firmant, &frm_equalp, 0, 0, &two_length, 0, &firmant_frequency, &firmant_set_frequency, 0, 0, &firmant_radius, &firmant_set_radius, 0, 0, &run_firmant, MUS_SIMPLE_FILTER, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &frm_reset, 0, &frm_copy }; mus_any *mus_make_firmant(mus_float_t frequency, mus_float_t radius) { frm *gen; gen = (frm *)calloc(1, sizeof(frm)); gen->core = &FIRMANT_CLASS; gen->frequency = mus_hz_to_radians(frequency); gen->radius = radius; gen->fdbk = 2.0 * sin(gen->frequency * 0.5); gen->gain = 1.0 - radius * radius; return((mus_any *)gen); } /* ---------------- filter ---------------- */ typedef struct { mus_any_class *core; int order, allocated_size, loc; bool state_allocated; mus_float_t *x, *y, *state; mus_float_t (*filtw)(mus_any *ptr, mus_float_t fm); } flt; mus_float_t mus_filter(mus_any *ptr, mus_float_t input) { return((((flt *)ptr)->filtw)(ptr, input)); } static mus_float_t filter_eight(mus_any *ptr, mus_float_t input) { /* oddly enough, this separated form is faster than the interleaved version below, or is valgrind confused? */ flt *gen = (flt *)ptr; mus_float_t xout; mus_float_t *state, *ts, *ts1, *y, *x; x = (mus_float_t *)(gen->x); y = (mus_float_t *)(gen->y + 1); /* assume y[0] = 1.0 I think */ state = (mus_float_t *)(gen->state + gen->loc); ts = (mus_float_t *)(state + gen->order - 1); ts1 = (mus_float_t *)(state + gen->order); gen->loc++; if (gen->loc == gen->order) gen->loc = 0; input -= ((*ts--) * (*y++)); input -= ((*ts--) * (*y++)); input -= ((*ts--) * (*y++)); input -= ((*ts--) * (*y++)); input -= ((*ts--) * (*y++)); input -= ((*ts--) * (*y++)); input -= ((*ts--) * (*y++)); input -= ((*ts) * (*y)); state[0] = input; state[gen->order] = input; xout = (*ts1--) * (*x++); xout += (*ts1--) * (*x++); xout += (*ts1--) * (*x++); xout += (*ts1--) * (*x++); xout += (*ts1--) * (*x++); xout += (*ts1--) * (*x++); xout += (*ts1--) * (*x++); xout += (*ts1--) * (*x++); return(xout + ((*ts1) * (*x))); /* * flt *gen = (flt *)ptr; * mus_float_t xout; * mus_float_t *state, *ts, *y, *x; * * x = (mus_float_t *)(gen->x + 1); * y = (mus_float_t *)(gen->y + 1); * state = (mus_float_t *)(gen->state + gen->loc); * ts = (mus_float_t *)(state + gen->order - 1); * * gen->loc++; * if (gen->loc == gen->order) * gen->loc = 0; * * xout = (*ts) * (*x++); * input -= ((*ts--) * (*y++)); * xout += (*ts) * (*x++); * input -= ((*ts--) * (*y++)); * xout += (*ts) * (*x++); * input -= ((*ts--) * (*y++)); * xout += (*ts) * (*x++); * input -= ((*ts--) * (*y++)); * xout += (*ts) * (*x++); * input -= ((*ts--) * (*y++)); * xout += (*ts) * (*x++); * input -= ((*ts--) * (*y++)); * xout += (*ts) * (*x++); * input -= ((*ts--) * (*y++)); * xout += (*ts) * (*x); * input -= ((*ts--) * (*y)); * * state[0] = input; * state[gen->order] = input; * return(xout + ((*ts) * gen->x[0])); */ } static mus_float_t filter_four(mus_any *ptr, mus_float_t input) { flt *gen = (flt *)ptr; mus_float_t xout; mus_float_t *state, *ts, *ts1, *y, *x; x = (mus_float_t *)(gen->x); y = (mus_float_t *)(gen->y + 1); state = (mus_float_t *)(gen->state + gen->loc); ts = (mus_float_t *)(state + gen->order - 1); ts1 = (mus_float_t *)(state + gen->order); gen->loc++; if (gen->loc == gen->order) gen->loc = 0; input -= ((*ts--) * (*y++)); input -= ((*ts--) * (*y++)); input -= ((*ts--) * (*y++)); input -= ((*ts) * (*y)); state[0] = input; state[gen->order] = input; xout = (*ts1--) * (*x++); xout += (*ts1--) * (*x++); xout += (*ts1--) * (*x++); xout += (*ts1--) * (*x++); return(xout + ((*ts1) * (*x))); /* * flt *gen = (flt *)ptr; * mus_float_t xout; * mus_float_t *state, *ts, *y, *x; * * x = (mus_float_t *)(gen->x + 1); * y = (mus_float_t *)(gen->y + 1); * state = (mus_float_t *)(gen->state + gen->loc); * ts = (mus_float_t *)(state + gen->order - 1); * * gen->loc++; * if (gen->loc == gen->order) * gen->loc = 0; * * xout = (*ts) * (*x++); * input -= ((*ts--) * (*y++)); * xout += (*ts) * (*x++); * input -= ((*ts--) * (*y++)); * xout += (*ts) * (*x++); * input -= ((*ts--) * (*y++)); * xout += (*ts) * (*x++); * input -= ((*ts--) * (*y++)); * * state[0] = input; * state[gen->order] = input; * return(xout + ((*ts) * gen->x[0])); */ } static mus_float_t filter_two(mus_any *ptr, mus_float_t input) { /* here the mus_float_t-delay form is not faster, but use it for consistency */ flt *gen = (flt *)ptr; mus_float_t *state, *ts, *y, *x; x = gen->x; y = gen->y; state = (mus_float_t *)(gen->state + gen->loc); ts = (mus_float_t *)(state + gen->order - 2); gen->loc++; if (gen->loc == gen->order) gen->loc = 0; state[0] = input - ((ts[1] * y[1]) + (ts[0] * y[2])); state[gen->order] = state[0]; return((ts[0] * x[2]) + (ts[1] * x[1]) + (ts[2] * x[0])); } static mus_float_t filter_lt_10(mus_any *ptr, mus_float_t input) { flt *gen = (flt *)ptr; mus_float_t xout = 0.0; mus_float_t *state, *state1, *ts, *y, *x; x = (mus_float_t *)(gen->x); y = (mus_float_t *)(gen->y + 1); /* assume y[0] = 1.0 I think */ state = (mus_float_t *)(gen->state + gen->loc); state1 = (mus_float_t *)(state + 1); ts = (mus_float_t *)(state + gen->order - 1); while (ts > state1) input -= ((*ts--) * (*y++)); input -= ((*ts) * (*y)); state[0] = input; state[gen->order] = input; ts = (mus_float_t *)(state + gen->order); while (ts > state1) xout += (*ts--) * (*x++); gen->loc++; if (gen->loc == gen->order) gen->loc = 0; return(xout + ((*ts) * (*x))); } static mus_float_t filter_ge_10(mus_any *ptr, mus_float_t input) { flt *gen = (flt *)ptr; mus_float_t xout = 0.0; mus_float_t *state, *state1, *state11, *ts, *y, *x; x = (mus_float_t *)(gen->x); y = (mus_float_t *)(gen->y + 1); /* assume y[0] = 1.0 I think */ state = (mus_float_t *)(gen->state + gen->loc); state1 = (mus_float_t *)(state + 1); state11 = (mus_float_t *)(state + 11); ts = (mus_float_t *)(state + gen->order - 1); while (ts >= state11) { input -= ((*ts--) * (*y++)); input -= ((*ts--) * (*y++)); input -= ((*ts--) * (*y++)); input -= ((*ts--) * (*y++)); input -= ((*ts--) * (*y++)); input -= ((*ts--) * (*y++)); input -= ((*ts--) * (*y++)); input -= ((*ts--) * (*y++)); input -= ((*ts--) * (*y++)); input -= ((*ts--) * (*y++)); } while (ts > state1) input -= ((*ts--) * (*y++)); input -= ((*ts) * (*y)); state[0] = input; state[gen->order] = input; ts = (mus_float_t *)(state + gen->order); while (ts >= state11) { xout += (*ts--) * (*x++); xout += (*ts--) * (*x++); xout += (*ts--) * (*x++); xout += (*ts--) * (*x++); xout += (*ts--) * (*x++); xout += (*ts--) * (*x++); xout += (*ts--) * (*x++); xout += (*ts--) * (*x++); xout += (*ts--) * (*x++); xout += (*ts--) * (*x++); } while (ts > state1) xout += (*ts--) * (*x++); gen->loc++; if (gen->loc == gen->order) gen->loc = 0; return(xout + ((*ts) * (*x))); } mus_float_t mus_fir_filter(mus_any *ptr, mus_float_t input) { return((((flt *)ptr)->filtw)(ptr, input)); } static mus_float_t fir_n(mus_any *ptr, mus_float_t input) { mus_float_t xout = 0.0; flt *gen = (flt *)ptr; mus_float_t *state, *ts, *x, *end; x = (mus_float_t *)(gen->x); state = (mus_float_t *)(gen->state + gen->loc); ts = (mus_float_t *)(state + gen->order); (*state) = input; (*ts) = input; state++; end = (mus_float_t *)(state + 4); while (ts > end) { xout += (*ts--) * (*x++); xout += (*ts--) * (*x++); xout += (*ts--) * (*x++); xout += (*ts--) * (*x++); } while (ts > state) xout += (*ts--) * (*x++); gen->loc++; if (gen->loc == gen->order) gen->loc = 0; return(xout + ((*ts) * (*x))); } static mus_float_t fir_ge_20(mus_any *ptr, mus_float_t input) { mus_float_t xout = 0.0; flt *gen = (flt *)ptr; mus_float_t *state, *ts, *x, *end; x = (mus_float_t *)(gen->x); state = (mus_float_t *)(gen->state + gen->loc); ts = (mus_float_t *)(state + gen->order); end = (mus_float_t *)(state + 20); (*state) = input; (*ts) = input; state++; while (ts >= end) { xout += (*ts--) * (*x++); xout += (*ts--) * (*x++); xout += (*ts--) * (*x++); xout += (*ts--) * (*x++); xout += (*ts--) * (*x++); xout += (*ts--) * (*x++); xout += (*ts--) * (*x++); xout += (*ts--) * (*x++); xout += (*ts--) * (*x++); xout += (*ts--) * (*x++); xout += (*ts--) * (*x++); xout += (*ts--) * (*x++); xout += (*ts--) * (*x++); xout += (*ts--) * (*x++); xout += (*ts--) * (*x++); xout += (*ts--) * (*x++); xout += (*ts--) * (*x++); xout += (*ts--) * (*x++); xout += (*ts--) * (*x++); xout += (*ts--) * (*x++); } while (ts > state) xout += (*ts--) * (*x++); gen->loc++; if (gen->loc == gen->order) gen->loc = 0; return((ts == state) ? (xout + ((*ts) * (*x))) : xout); } mus_float_t mus_iir_filter(mus_any *ptr, mus_float_t input) { return((((flt *)ptr)->filtw)(ptr, input)); } static mus_float_t iir_n(mus_any *ptr, mus_float_t input) { flt *gen = (flt *)ptr; mus_float_t *state, *ts, *y; y = (mus_float_t *)(gen->y + 1); /* assume y[0] = 1.0 I think */ state = (mus_float_t *)(gen->state + gen->loc); ts = (mus_float_t *)(state + gen->order - 1); while (ts > state) input -= ((*ts--) * (*y++)); gen->loc++; if (gen->loc == gen->order) gen->loc = 0; state[0] = input; state[gen->order] = input; return(input); } static mus_float_t run_filter(mus_any *ptr, mus_float_t input, mus_float_t unused) {return((((flt *)ptr)->filtw)(ptr, input));} bool mus_is_filter(mus_any *ptr) { return((ptr) && ((ptr->core->type == MUS_FILTER) || (ptr->core->type == MUS_FIR_FILTER) || (ptr->core->type == MUS_IIR_FILTER))); } bool mus_is_fir_filter(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_FIR_FILTER)); } bool mus_is_iir_filter(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_IIR_FILTER)); } static mus_float_t *filter_data(mus_any *ptr) {return(((flt *)ptr)->state);} static mus_long_t filter_length(mus_any *ptr) {return(((flt *)ptr)->order);} static mus_float_t *filter_xcoeffs(mus_any *ptr) {return(((flt *)ptr)->x);} static mus_float_t *filter_ycoeffs(mus_any *ptr) {return(((flt *)ptr)->y);} mus_float_t *mus_filter_set_xcoeffs(mus_any *ptr, mus_float_t *new_data) { /* needed by Snd if filter order increased during play */ flt *gen = (flt *)ptr; mus_float_t *old_data; old_data = gen->x; gen->x = new_data; return(old_data); } mus_float_t *mus_filter_set_ycoeffs(mus_any *ptr, mus_float_t *new_data) { flt *gen = (flt *)ptr; mus_float_t *old_data; old_data = gen->y; gen->y = new_data; return(old_data); } static mus_long_t filter_set_length(mus_any *ptr, mus_long_t val) { /* just resets order if order < allocated size */ flt *gen = (flt *)ptr; if ((val > 0) && (val <= gen->allocated_size)) gen->order = (int)val; return((mus_long_t)(gen->order)); } static void set_filter_function(flt *gen); int mus_filter_set_order(mus_any *ptr, int order) { /* resets order and fixes state array if needed (coeffs arrays should be handled separately by set_x|ycoeffs above) */ /* returns either old order or -1 if state array can't be reallocated */ flt *gen = (flt *)ptr; int old_order; if ((order > gen->allocated_size) && (!(gen->state_allocated))) return(-1); old_order = gen->order; gen->order = order; if (order > gen->allocated_size) { int i; gen->allocated_size = order; gen->state = (mus_float_t *)realloc(gen->state, order * 2 * sizeof(mus_float_t)); for (i = old_order; i < order; i++) { gen->state[i] = 0.0; /* try to minimize click */ gen->state[i + order] = 0.0; /* just a guess */ } } set_filter_function(gen); return(old_order); } static mus_float_t filter_xcoeff(mus_any *ptr, int index) { flt *gen = (flt *)ptr; if (!(gen->x)) return((mus_float_t)mus_error(MUS_NO_XCOEFFS, S_mus_xcoeff ": no xcoeffs")); if ((index >= 0) && (index < gen->order)) return(gen->x[index]); return((mus_float_t)mus_error(MUS_ARG_OUT_OF_RANGE, S_mus_xcoeff ": invalid index %d, order = %d?", index, gen->order)); } static mus_float_t filter_set_xcoeff(mus_any *ptr, int index, mus_float_t val) { flt *gen = (flt *)ptr; if (!(gen->x)) return((mus_float_t)mus_error(MUS_NO_XCOEFFS, S_set S_mus_xcoeff ": no xcoeffs")); if ((index >= 0) && (index < gen->order)) { gen->x[index] = val; return(val); } return((mus_float_t)mus_error(MUS_ARG_OUT_OF_RANGE, S_set S_mus_xcoeff ": invalid index %d, order = %d?", index, gen->order)); } static mus_float_t filter_ycoeff(mus_any *ptr, int index) { flt *gen = (flt *)ptr; if (!(gen->y)) return((mus_float_t)mus_error(MUS_NO_YCOEFFS, S_mus_ycoeff ": no ycoeffs")); if ((index >= 0) && (index < gen->order)) return(gen->y[index]); return((mus_float_t)mus_error(MUS_ARG_OUT_OF_RANGE, S_mus_ycoeff ": invalid index %d, order = %d?", index, gen->order)); } static mus_float_t filter_set_ycoeff(mus_any *ptr, int index, mus_float_t val) { flt *gen = (flt *)ptr; if (!(gen->y)) return((mus_float_t)mus_error(MUS_NO_YCOEFFS, S_set S_mus_ycoeff ": no ycoeffs")); if ((index >= 0) && (index < gen->order)) { gen->y[index] = val; return(val); } return((mus_float_t)mus_error(MUS_ARG_OUT_OF_RANGE, S_set S_mus_ycoeff ": invalid index %d, order = %d?", index, gen->order)); } static void free_filter(mus_any *ptr) { flt *gen = (flt *)ptr; if ((gen->state) && (gen->state_allocated)) free(gen->state); free(gen); } static mus_any *flt_copy(mus_any *ptr) { flt *g, *p; int bytes; p = (flt *)ptr; g = (flt *)malloc(sizeof(flt)); memcpy((void *)g, (void *)ptr, sizeof(flt)); /* we have to make a new state array -- otherwise the original and copy step on each other */ bytes = p->order * 2 * sizeof(mus_float_t); g->state_allocated = true; g->state = (mus_float_t *)malloc(bytes); memcpy((void *)(g->state), (void *)(p->state), bytes); return((mus_any *)g); } static bool filter_equalp(mus_any *p1, mus_any *p2) { flt *f1, *f2; f1 = (flt *)p1; f2 = (flt *)p2; if (p1 == p2) return(true); return(((p1->core)->type == (p2->core)->type) && ((mus_is_filter(p1)) || (mus_is_fir_filter(p1)) || (mus_is_iir_filter(p1))) && (f1->order == f2->order) && ((!(f1->x)) || (!(f2->x)) || (clm_arrays_are_equal(f1->x, f2->x, f1->order))) && ((!(f1->y)) || (!(f2->y)) || (clm_arrays_are_equal(f1->y, f2->y, f1->order))) && (clm_arrays_are_equal(f1->state, f2->state, f1->order))); } static char *describe_filter(mus_any *ptr) { flt *gen = (flt *)ptr; char *xstr = NULL, *ystr = NULL; char *describe_buffer; describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE); xstr = float_array_to_string(gen->x, gen->order, 0); ystr = float_array_to_string(gen->y, gen->order, 0); snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s order: %d, xs: %s, ys: %s", mus_name(ptr), gen->order, xstr, ystr); if (xstr) free(xstr); if (ystr) free(ystr); return(describe_buffer); } static char *describe_fir_filter(mus_any *ptr) { flt *gen = (flt *)ptr; char *xstr = NULL; char *describe_buffer; describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE); xstr = float_array_to_string(gen->x, gen->order, 0); snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s order: %d, xs: %s", mus_name(ptr), gen->order, xstr); if (xstr) free(xstr); return(describe_buffer); } static char *describe_iir_filter(mus_any *ptr) { flt *gen = (flt *)ptr; char *ystr = NULL; char *describe_buffer; describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE); ystr = float_array_to_string(gen->y, gen->order, 0); snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s order: %d, ys: %s", mus_name(ptr), gen->order, ystr); if (ystr) free(ystr); return(describe_buffer); } static void filter_reset(mus_any *ptr) { flt *gen = (flt *)ptr; memset((void *)(gen->state), 0, gen->allocated_size * 2 * sizeof(mus_float_t)); } static mus_any_class FILTER_CLASS = { MUS_FILTER, (char *)S_filter, &free_filter, &describe_filter, &filter_equalp, &filter_data, 0, &filter_length, &filter_set_length, 0, 0, 0, 0, 0, 0, 0, 0, &run_filter, MUS_FULL_FILTER, NULL, 0, 0, 0, 0, 0, &filter_xcoeff, &filter_set_xcoeff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &filter_ycoeff, &filter_set_ycoeff, &filter_xcoeffs, &filter_ycoeffs, &filter_reset, 0, &flt_copy }; static mus_any_class FIR_FILTER_CLASS = { MUS_FIR_FILTER, (char *)S_fir_filter, &free_filter, &describe_fir_filter, &filter_equalp, &filter_data, 0, &filter_length, &filter_set_length, 0, 0, 0, 0, 0, 0, 0, 0, &run_filter, MUS_FULL_FILTER, NULL, 0, 0, 0, 0, 0, &filter_xcoeff, &filter_set_xcoeff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &filter_xcoeffs, 0, &filter_reset, 0, &flt_copy }; static mus_any_class IIR_FILTER_CLASS = { MUS_IIR_FILTER, (char *)S_iir_filter, &free_filter, &describe_iir_filter, &filter_equalp, &filter_data, 0, &filter_length, &filter_set_length, 0, 0, 0, 0, 0, 0, 0, 0, &run_filter, MUS_FULL_FILTER, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &filter_ycoeff, &filter_set_ycoeff, 0, &filter_ycoeffs, &filter_reset, 0, &flt_copy }; static void set_filter_function(flt *gen) { /* choose the run-time function based on the current filter order and type */ int order; order = gen->order - 1; if (gen->core == &FILTER_CLASS) { if (order == 2) gen->filtw = filter_two; else { if (order == 8) gen->filtw = filter_eight; else { if (order == 4) gen->filtw = filter_four; else { if (order >= 10) gen->filtw = filter_ge_10; else gen->filtw = filter_lt_10; } } } } else { if (gen->core == &FIR_FILTER_CLASS) { if (order >= 20) gen->filtw = fir_ge_20; else gen->filtw = fir_n; } else gen->filtw = iir_n; } } static mus_any *make_filter(mus_any_class *cls, const char *name, int order, mus_float_t *xcoeffs, mus_float_t *ycoeffs, mus_float_t *state) { /* if state is null, it is allocated locally, otherwise it's size should be at least 2 * order. */ if (order <= 0) mus_error(MUS_ARG_OUT_OF_RANGE, S_make_filter ": %s order = %d?", name, order); else { flt *gen; gen = (flt *)malloc(sizeof(flt)); if (state) { gen->state = state; gen->state_allocated = false; } else { gen->state = (mus_float_t *)calloc(order * 2, sizeof(mus_float_t)); gen->state_allocated = true; } gen->loc = 0; if (cls == &FILTER_CLASS) { if (!ycoeffs) cls = &FIR_FILTER_CLASS; else { if (!xcoeffs) cls = &IIR_FILTER_CLASS; } } gen->core = cls; gen->order = order; gen->allocated_size = order; gen->x = xcoeffs; gen->y = ycoeffs; gen->filtw = NULL; set_filter_function(gen); return((mus_any *)gen); } return(NULL); } mus_any *mus_make_filter(int order, mus_float_t *xcoeffs, mus_float_t *ycoeffs, mus_float_t *state) { return(make_filter(&FILTER_CLASS, S_make_filter, order, xcoeffs, ycoeffs, state)); } mus_any *mus_make_fir_filter(int order, mus_float_t *xcoeffs, mus_float_t *state) { return(make_filter(&FIR_FILTER_CLASS, S_make_fir_filter, order, xcoeffs, NULL, state)); } mus_any *mus_make_iir_filter(int order, mus_float_t *ycoeffs, mus_float_t *state) { return(make_filter(&IIR_FILTER_CLASS, S_make_iir_filter, order, NULL, ycoeffs, state)); } mus_float_t *mus_make_fir_coeffs(int order, mus_float_t *envl, mus_float_t *aa) { /* envl = evenly sampled freq response, has order samples */ int n, i, j, jj; mus_float_t scl; mus_float_t *a; n = order; if (n <= 0) return(aa); if (aa) a = aa; else a = (mus_float_t *)calloc(order + 1, sizeof(mus_float_t)); if (!a) return(NULL); if (!(is_power_of_2(order))) { int m; mus_float_t am, q, xt0, x; m = (n + 1) / 2; am = 0.5 * (n + 1) - 1.0; scl = 2.0 / (mus_float_t)n; q = TWO_PI / (mus_float_t)n; xt0 = envl[0] * 0.5; for (j = 0, jj = n - 1; j < m; j++, jj--) { mus_float_t xt, qj; #if HAVE_SINCOS double s1, c1, s2, c2, qj1; xt = xt0; qj = q * (am - j); sincos(qj, &s1, &c1); qj1 = qj * 2.0; for (i = 1, x = qj; i < m; i += 2, x += qj1) { sincos(x, &s2, &c2); xt += (envl[i] * c2); if (i < (m - 1)) xt += (envl[i + 1] * (c1 * c2 - s1 * s2)); } #else xt = xt0; qj = q * (am - j); for (i = 1, x = qj; i < m; i++, x += qj) xt += (envl[i] * cos(x)); #endif a[j] = xt * scl; a[jj] = a[j]; } } else /* use fft if it's easy to match -- there must be a way to handle non-power-of-2 orders here * stretch envl to a power of 2, fft, subsample? */ { mus_float_t *rl, *im; mus_long_t fsize; int lim; mus_float_t offset; fsize = 2 * order; /* checked power of 2 above */ rl = (mus_float_t *)calloc(fsize, sizeof(mus_float_t)); im = (mus_float_t *)calloc(fsize, sizeof(mus_float_t)); lim = order / 2; memcpy((void *)rl, (void *)envl, lim * sizeof(mus_float_t)); mus_fft(rl, im, fsize, 1); scl = 4.0 / fsize; offset = -2.0 * envl[0] / fsize; for (i = 0; i < fsize; i++) rl[i] = rl[i] * scl + offset; for (i = 1, j = lim - 1, jj = lim; i < order; i += 2, j--, jj++) { a[j] = rl[i]; a[jj] = rl[i]; } free(rl); free(im); } return(a); } /* ---------------- one-pole-all-pass ---------------- */ typedef struct { mus_any_class *core; int size; mus_float_t coeff; mus_float_t *x, *y; mus_float_t (*f)(mus_any *ptr, mus_float_t input); } onepall; static void free_onepall(mus_any *ptr) { onepall *f = (onepall *)ptr; if (f->x) {free(f->x); f->x = NULL;} if (f->y) {free(f->y); f->y = NULL;} free(ptr); } static mus_any *onepall_copy(mus_any *ptr) { onepall *g, *p; int bytes; p = (onepall *)ptr; g = (onepall *)malloc(sizeof(onepall)); memcpy((void *)g, (void *)ptr, sizeof(onepall)); bytes = g->size * sizeof(mus_float_t); g->x = (mus_float_t *)malloc(bytes); memcpy((void *)(g->x), (void *)(p->x), bytes); g->y = (mus_float_t *)malloc(bytes); memcpy((void *)(g->y), (void *)(p->y), bytes); return((mus_any *)g); } static mus_float_t run_onepall(mus_any *ptr, mus_float_t input, mus_float_t unused) { return((((onepall *)ptr)->f)(ptr, input)); } static mus_long_t onepall_length(mus_any *ptr) { return(((onepall *)ptr)->size); } static void onepall_reset(mus_any *ptr) { onepall *f = (onepall *)ptr; int size; size = f->size; memset((void *)(f->x), 0, size * sizeof(mus_float_t)); memset((void *)(f->y), 0, size * sizeof(mus_float_t)); } static bool onepall_equalp(mus_any *p1, mus_any *p2) { onepall *f1 = (onepall *)p1; onepall *f2 = (onepall *)p2; if (f1 == f2) return(true); if (f1->size != f2->size) return(false); if (f1->coeff != f2->coeff) return(false); return((mus_arrays_are_equal(f1->x, f2->x, float_equal_fudge_factor, f1->size)) && (mus_arrays_are_equal(f1->y, f2->y, float_equal_fudge_factor, f1->size))); } static char *describe_onepall(mus_any *ptr) { onepall *gen = (onepall *)ptr; char *describe_buffer; describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE); snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s size: %d, coeff: %f", mus_name(ptr), gen->size, gen->coeff); return(describe_buffer); } mus_float_t mus_one_pole_all_pass(mus_any *ptr, mus_float_t input) { return((((onepall *)ptr)->f)(ptr, input)); } static mus_float_t one_pole_all_pass_n(mus_any *f, mus_float_t input) { onepall *p = (onepall *)f; int i; mus_float_t coeff, y0; mus_float_t *x, *y; x = p->x; y = p->y; coeff = p->coeff; y0 = input; for (i = 0; i < p->size; i++) { y[i] = x[i] + (coeff * (y0 - y[i])); x[i] = y0; y0 = y[i]; } return(y0); } static mus_float_t one_pole_all_pass_8(mus_any *f, mus_float_t input) { onepall *p = (onepall *)f; mus_float_t coeff; mus_float_t *x, *y; x = p->x; y = p->y; coeff = p->coeff; y[0] = x[0] + (coeff * (input - y[0])); x[0] = input; y[1] = x[1] + (coeff * (y[0] - y[1])); x[1] = y[0]; y[2] = x[2] + (coeff * (y[1] - y[2])); x[2] = y[1]; y[3] = x[3] + (coeff * (y[2] - y[3])); x[3] = y[2]; y[4] = x[4] + (coeff * (y[3] - y[4])); x[4] = y[3]; y[5] = x[5] + (coeff * (y[4] - y[5])); x[5] = y[4]; y[6] = x[6] + (coeff * (y[5] - y[6])); x[6] = y[5]; y[7] = x[7] + (coeff * (y[6] - y[7])); x[7] = y[6]; return(y[7]); } static mus_float_t one_pole_all_pass_1(mus_any *f, mus_float_t input) { onepall *p = (onepall *)f; p->y[0] = p->x[0] + (p->coeff * (input - p->y[0])); p->x[0] = input; return(p->y[0]); } static mus_any_class ONE_POLE_ALL_PASS_CLASS = { MUS_ONE_POLE_ALL_PASS, (char *)S_one_pole_all_pass, &free_onepall, &describe_onepall, &onepall_equalp, 0, 0, &onepall_length, 0, 0, 0, 0, 0, 0, 0, 0, 0, &run_onepall, MUS_NOT_SPECIAL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &onepall_reset, 0, &onepall_copy }; mus_any *mus_make_one_pole_all_pass(int size, mus_float_t coeff) { onepall *gen; gen = (onepall *)malloc(sizeof(onepall)); gen->core = &ONE_POLE_ALL_PASS_CLASS; gen->size = size; gen->x = (mus_float_t *)calloc(size, sizeof(mus_float_t)); gen->y = (mus_float_t *)calloc(size, sizeof(mus_float_t)); gen->coeff = coeff; if (size == 1) gen->f = one_pole_all_pass_1; else { if (size == 8) gen->f = one_pole_all_pass_8; else gen->f = one_pole_all_pass_n; } return((mus_any *)gen); } bool mus_is_one_pole_all_pass(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_ONE_POLE_ALL_PASS)); } /* ---------------- env ---------------- */ typedef enum {MUS_ENV_LINEAR, MUS_ENV_EXPONENTIAL, MUS_ENV_STEP} mus_env_t; typedef struct { mus_any_class *core; mus_float_t rate, current_value, base, offset, scaler, power, init_y, init_power, original_scaler, original_offset; mus_long_t loc, end; mus_env_t style; int index, size; mus_float_t *original_data; mus_float_t *rates; mus_long_t *locs; mus_float_t (*env_func)(mus_any *g); void *next; void (*free_env)(mus_any *ptr); } seg; /* I used to use exp directly, but: (define (texp1 start end num) (let* ((ls (log start)) (le (log end)) (cf (exp (/ (- le ls) (1- num)))) (max-diff 0.0) (xstart start)) (do ((i 0 (1+ i))) ((= i num) max-diff) (let ((val1 (* start (exp (* (/ i (1- num)) (- le ls))))) (val2 xstart)) (set! xstart (* xstart cf)) (set! max-diff (max max-diff (abs (- val1 val2)))))))) returns: :(texp1 1.0 3.0 1000000) 2.65991229042584e-10 :(texp1 1.0 10.0 100000000) 2.24604939091932e-8 :(texp1 10.0 1000.0 100000000) 4.11786902532185e-6 :(texp1 1.0 1.1 100000000) 1.28246036013024e-9 :(texp1 10.0 1000.0 1000000000) 4.39423240550241e-5 so the repeated multiply version is more than accurate enough */ bool mus_is_env(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_ENV)); } mus_float_t mus_env(mus_any *ptr) { seg *gen = (seg *)ptr; return((*(gen->env_func))(ptr)); } mus_float_t (*mus_env_function(mus_any *g))(mus_any *gen) { if (mus_is_env(g)) return(((seg *)g)->env_func); return(NULL); } static mus_float_t mus_env_step(mus_any *ptr) { seg *gen = (seg *)ptr; mus_float_t val; val = gen->current_value; if (gen->loc == 0) { gen->index++; gen->loc = gen->locs[gen->index] - gen->locs[gen->index - 1]; gen->rate = gen->rates[gen->index]; gen->current_value = gen->rate; } gen->loc--; return(val); } static mus_float_t mus_env_line(mus_any *ptr) { seg *gen = (seg *)ptr; return(gen->current_value); } static mus_float_t mus_env_linear(mus_any *ptr) { seg *gen = (seg *)ptr; mus_float_t val; val = gen->current_value; if (gen->loc == 0) { /* we can save about 10% total env time by checking here that we're on the last segment, * and setting gen->env_func to a version of mus_env_linear that does not watch gen->loc. * In any case, this code is strange -- change anything and it is 20% slower, sez callgrind. */ gen->index++; gen->loc = gen->locs[gen->index] - gen->locs[gen->index - 1]; gen->rate = gen->rates[gen->index]; } gen->current_value += gen->rate; gen->loc--; return(val); } static mus_float_t mus_env_exponential(mus_any *ptr) { seg *gen = (seg *)ptr; mus_float_t val; val = gen->current_value; if (gen->loc == 0) { gen->index++; gen->loc = gen->locs[gen->index] - gen->locs[gen->index - 1]; gen->rate = gen->rates[gen->index]; } gen->power *= gen->rate; gen->current_value = gen->offset + (gen->scaler * gen->power); gen->loc--; return(val); } static mus_float_t run_env(mus_any *ptr, mus_float_t unused1, mus_float_t unused2) { return(mus_env(ptr)); } static void canonicalize_env(seg *e, const mus_float_t *data, int pts, mus_long_t dur, mus_float_t scaler) { int i, j, pts2; mus_float_t xscl, cur_loc, x1, y1, xdur; mus_long_t samps, pre_loc; /* pts > 1 if we get here, so the loop below is always exercised */ pts2 = pts * 2; xdur = data[pts2 - 2] - data[0]; if (xdur > 0.0) xscl = (mus_float_t)(dur - 1) / xdur; else xscl = 1.0; e->locs[pts - 2] = e->end; x1 = data[0]; y1 = data[1]; pre_loc = 0; for (j = 0, i = 2, cur_loc = 0.0; i < pts2; i += 2, j++) { mus_float_t cur_dx, x0, y0; x0 = x1; x1 = data[i]; y0 = y1; y1 = data[i + 1]; cur_dx = xscl * (x1 - x0); if (cur_dx < 1.0) cur_loc += 1.0; else cur_loc += cur_dx; switch (e->style) { case MUS_ENV_LINEAR: e->locs[j] = (mus_long_t)(cur_loc + 0.5); samps = e->locs[j] - pre_loc; pre_loc = e->locs[j]; if (samps == 0) e->rates[j] = 0.0; else e->rates[j] = scaler * (y1 - y0) / (mus_float_t)samps; break; case MUS_ENV_EXPONENTIAL: e->locs[j] = (mus_long_t)(cur_loc + 0.5); samps = e->locs[j] - pre_loc; pre_loc = e->locs[j]; if (samps == 0) e->rates[j] = 1.0; else e->rates[j] = exp((y1 - y0) / (mus_float_t)samps); break; case MUS_ENV_STEP: e->locs[j] = (mus_long_t)cur_loc; /* this is the change boundary (confusing...) */ e->rates[j] = e->offset + (scaler * y0); break; } } e->locs[pts - 1] = 1000000000; e->locs[pts] = 1000000000; /* guard cell at end to make bounds check simpler */ } static mus_float_t *fixup_exp_env(seg *e, const mus_float_t *data, int pts, mus_float_t offset, mus_float_t scaler, mus_float_t base) { mus_float_t min_y, max_y, val = 0.0, tmp = 0.0, b1; int len, i; bool flat; mus_float_t *result = NULL; if ((base <= 0.0) || (base == 1.0)) return(NULL); min_y = offset + scaler * data[1]; max_y = min_y; len = pts * 2; /* fill "result" with x and (offset+scaler*y) */ result = (mus_float_t *)malloc(len * sizeof(mus_float_t)); result[0] = data[0]; result[1] = min_y; for (i = 2; i < len; i += 2) { tmp = offset + scaler * data[i + 1]; result[i] = data[i]; result[i + 1] = tmp; if (tmp < min_y) min_y = tmp; if (tmp > max_y) max_y = tmp; } b1 = base - 1.0; flat = (min_y == max_y); if (!flat) val = 1.0 / (max_y - min_y); /* now logify result */ for (i = 1; i < len; i += 2) { if (flat) tmp = 1.0; else tmp = val * (result[i] - min_y); result[i] = log(1.0 + (tmp * b1)); } e->scaler = (max_y - min_y) / b1; e->offset = min_y; return(result); } static bool env_equalp(mus_any *p1, mus_any *p2) { seg *e1 = (seg *)p1; seg *e2 = (seg *)p2; if (p1 == p2) return(true); return((e1) && (e2) && (e1->core->type == e2->core->type) && (e1->loc == e2->loc) && (e1->end == e2->end) && (e1->style == e2->style) && (e1->index == e2->index) && (e1->size == e2->size) && (e1->rate == e2->rate) && (e1->base == e2->base) && (e1->power == e2->power) && (e1->current_value == e2->current_value) && (e1->scaler == e2->scaler) && (e1->offset == e2->offset) && (e1->init_y == e2->init_y) && (e1->init_power == e2->init_power) && (clm_arrays_are_equal(e1->original_data, e2->original_data, e1->size * 2))); } static char *describe_env(mus_any *ptr) { char *str = NULL; seg *e = (seg *)ptr; char *describe_buffer; describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE); snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s %s, pass: %lld (dur: %lld), index: %d, scaler: %.4f, offset: %.4f, data: %s", mus_name(ptr), ((e->style == MUS_ENV_LINEAR) ? "linear" : ((e->style == MUS_ENV_EXPONENTIAL) ? "exponential" : "step")), (e->locs) ? (e->locs[e->index] - e->loc) : -1, e->end + 1, e->index, e->original_scaler, e->original_offset, str = float_array_to_string(e->original_data, e->size * 2, 0)); if (str) free(str); return(describe_buffer); } static seg *e2_free_list = NULL, *e3_free_list = NULL, *e4_free_list = NULL; static void free_env_gen(mus_any *pt) { seg *ptr = (seg *)pt; (*(ptr->free_env))(pt); } static void fe2(mus_any *pt) { seg *ptr = (seg *)pt; ptr->next = e2_free_list; e2_free_list = ptr; } static void fe3(mus_any *pt) { seg *ptr = (seg *)pt; ptr->next = e3_free_list; e3_free_list = ptr; } static void fe4(mus_any *pt) { seg *ptr = (seg *)pt; ptr->next = e4_free_list; e4_free_list = ptr; } static void ferest(mus_any *pt) { seg *ptr = (seg *)pt; if (ptr->locs) {free(ptr->locs); ptr->locs = NULL;} if (ptr->rates) {free(ptr->rates); ptr->rates = NULL;} free(ptr); } static mus_any *seg_copy(mus_any *ptr) { seg *e = NULL, *p; p = (seg *)ptr; switch (p->size) /* "npts" */ { case 1: e = (seg *)malloc(sizeof(seg)); memcpy((void *)e, (void *)ptr, sizeof(seg)); return((mus_any *)e); case 2: if (e2_free_list) {e = e2_free_list; e2_free_list = (seg *)(e->next);} break; case 3: if (e3_free_list) {e = e3_free_list; e3_free_list = (seg *)(e->next);} break; case 4: if (e4_free_list) {e = e4_free_list; e4_free_list = (seg *)(e->next);} break; default: break; } if (!e) { e = (seg *)malloc(sizeof(seg)); memcpy((void *)e, (void *)ptr, sizeof(seg)); if (p->rates) { int bytes; bytes = p->size * sizeof(mus_float_t); e->rates = (mus_float_t *)malloc(bytes); memcpy((void *)(e->rates), (void *)(p->rates), bytes); bytes = (p->size + 1) * sizeof(mus_long_t); e->locs = (mus_long_t *)malloc(bytes); memcpy((void *)(e->locs), (void *)(p->locs), bytes); } } else { mus_float_t *r; mus_long_t *l; int bytes; bytes = p->size * sizeof(mus_float_t); r = e->rates; memcpy((void *)r, (void *)(p->rates), bytes); bytes = (p->size + 1) * sizeof(mus_long_t); l = e->locs; memcpy((void *)l, (void *)(p->locs), bytes); memcpy((void *)e, (void *)ptr, sizeof(seg)); e->rates = r; e->locs = l; } return((mus_any *)e); } static mus_float_t *env_data(mus_any *ptr) {return(((seg *)ptr)->original_data);} /* mus-data */ static mus_float_t env_scaler(mus_any *ptr) {return(((seg *)ptr)->original_scaler);} /* "mus_float_t" for mus-scaler */ static mus_float_t env_offset(mus_any *ptr) {return(((seg *)ptr)->original_offset);} int mus_env_breakpoints(mus_any *ptr) {return(((seg *)ptr)->size);} static mus_long_t env_length(mus_any *ptr) {return((((seg *)ptr)->end + 1));} /* this needs to match the :length arg to make-env (changed to +1, 20-Feb-08) */ static mus_float_t env_current_value(mus_any *ptr) {return(((seg *)ptr)->current_value);} mus_long_t *mus_env_passes(mus_any *gen) {return(((seg *)gen)->locs);} mus_float_t *mus_env_rates(mus_any *gen) {return(((seg *)gen)->rates);} static int env_position(mus_any *ptr) {return(((seg *)ptr)->index);} mus_float_t mus_env_offset(mus_any *gen) {return(((seg *)gen)->offset);} mus_float_t mus_env_scaler(mus_any *gen) {return(((seg *)gen)->scaler);} mus_float_t mus_env_initial_power(mus_any *gen) {return(((seg *)gen)->init_power);} static void env_set_location(mus_any *ptr, mus_long_t val); static mus_long_t seg_set_pass(mus_any *ptr, mus_long_t val) {env_set_location(ptr, val); return(val);} static mus_long_t seg_pass(mus_any *ptr) { seg *gen = (seg *)ptr; return(gen->locs[gen->index] - gen->loc); } static mus_float_t env_increment(mus_any *rd) { if (((seg *)rd)->style == MUS_ENV_STEP) return(0.0); return(((seg *)rd)->base); } static void env_reset(mus_any *ptr) { seg *gen = (seg *)ptr; gen->current_value = gen->init_y; gen->index = 0; gen->loc = gen->locs[0]; gen->rate = gen->rates[0]; gen->power = gen->init_power; } static void rebuild_env(seg *e, mus_float_t scl, mus_float_t off, mus_long_t end) { seg *new_e; new_e = (seg *)mus_make_env(e->original_data, e->size, scl, off, e->base, 0.0, end, NULL); if (e->locs) free(e->locs); if (e->rates) free(e->rates); e->locs = new_e->locs; e->rates = new_e->rates; e->init_y = new_e->init_y; e->init_power = new_e->init_power; env_reset((mus_any *)e); free(new_e); } static mus_float_t env_set_scaler(mus_any *ptr, mus_float_t val) { seg *e; e = (seg *)ptr; rebuild_env(e, val, e->original_offset, e->end); e->original_scaler = val; return(val); } static mus_float_t env_set_offset(mus_any *ptr, mus_float_t val) { seg *e; e = (seg *)ptr; rebuild_env(e, e->original_scaler, val, e->end); e->original_offset = val; return(val); } static mus_long_t env_set_length(mus_any *ptr, mus_long_t val) { seg *e; e = (seg *)ptr; rebuild_env(e, e->original_scaler, e->original_offset, val - 1); e->end = val - 1; return(val); } static mus_any_class ENV_CLASS = { MUS_ENV, (char *)S_env, &free_env_gen, &describe_env, &env_equalp, &env_data, /* mus-data -> original breakpoints */ 0, &env_length, &env_set_length, 0, 0, &env_current_value, 0, /* mus-phase?? -- used in snd-sig.c, but this needs a better access point */ &env_scaler, &env_set_scaler, &env_increment, 0, &run_env, MUS_NOT_SPECIAL, NULL, &env_position, &env_offset, &env_set_offset, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &seg_pass, &seg_set_pass, 0, 0, 0, 0, 0, &env_reset, 0, &seg_copy }; mus_any *mus_make_env(mus_float_t *brkpts, int npts, mus_float_t scaler, mus_float_t offset, mus_float_t base, mus_float_t duration, mus_long_t end, mus_float_t *ignored) { /* brkpts are not freed by the new env gen when it is freed, but should be protected during its existence */ int i; mus_long_t dur_in_samples; mus_float_t *edata; seg *e = NULL; void (*fe_release)(mus_any *ptr); for (i = 2; i < npts * 2; i += 2) if (brkpts[i - 2] >= brkpts[i]) { char *temp = NULL; mus_error(MUS_BAD_ENVELOPE, S_make_env ": env at breakpoint %d: x axis value: %f <= previous x value: %f (env: %s)", i / 2, brkpts[i], brkpts[i - 2], temp = float_array_to_string(brkpts, npts * 2, 0)); /* minor memleak here */ if (temp) free(temp); return(NULL); } switch (npts) { case 1: e = (seg *)calloc(1, sizeof(seg)); e->core = &ENV_CLASS; e->current_value = offset + scaler * brkpts[1]; e->env_func = mus_env_line; e->original_data = brkpts; e->free_env = ferest; return((mus_any *)e); case 2: if (e2_free_list) { e = e2_free_list; e2_free_list = (seg *)(e->next); } fe_release = fe2; break; case 3: if (e3_free_list) { e = e3_free_list; e3_free_list = (seg *)(e->next); } fe_release = fe3; break; case 4: if (e4_free_list) { e = e4_free_list; e4_free_list = (seg *)(e->next); } fe_release = fe4; break; default: fe_release = ferest; break; } if (!e) { e = (seg *)malloc(sizeof(seg)); e->core = &ENV_CLASS; e->size = npts; e->rates = (mus_float_t *)malloc(npts * sizeof(mus_float_t)); e->locs = (mus_long_t *)malloc((npts + 1) * sizeof(mus_long_t)); } e->free_env = fe_release; e->original_data = brkpts; if (duration != 0.0) dur_in_samples = (mus_long_t)(duration * sampling_rate); else dur_in_samples = (end + 1); e->init_y = offset + scaler * brkpts[1]; e->current_value = e->init_y; e->rate = 0.0; e->offset = offset; e->scaler = scaler; e->original_offset = offset; e->original_scaler = scaler; e->base = base; e->end = (dur_in_samples - 1); e->loc = 0; e->index = 0; if (base == 1.0) { e->style = MUS_ENV_LINEAR; if ((npts == 2) && (brkpts[1] == brkpts[3])) e->env_func = mus_env_line; else e->env_func = mus_env_linear; e->power = 0.0; e->init_power = 0.0; canonicalize_env(e, brkpts, npts, dur_in_samples, scaler); e->rates[npts - 1] = 0.0; } else { if (base == 0.0) { e->style = MUS_ENV_STEP; e->env_func = mus_env_step; e->power = 0.0; e->init_power = 0.0; canonicalize_env(e, brkpts, npts, dur_in_samples, scaler); e->rates[npts - 1] = e->offset + (scaler * brkpts[npts * 2 - 1]); /* stick at last value, which in this case is the value (not an increment) */ } else { e->style = MUS_ENV_EXPONENTIAL; e->env_func = mus_env_exponential; edata = fixup_exp_env(e, brkpts, npts, offset, scaler, base); if (edata == NULL) { free(e); return(NULL); } canonicalize_env(e, edata, npts, dur_in_samples, 1.0); e->rates[npts - 1] = 1.0; e->power = exp(edata[1]); e->init_power = e->power; e->offset -= e->scaler; free(edata); } } e->rate = e->rates[0]; e->loc = e->locs[0]; return((mus_any *)e); } /* one way to make an impulse: (make-env '(0 1 1 0) :length 1 :base 0.0) * a counter: (make-env '(0 0 1 1) :length 21 :scaler 20) -- length = 1+scaler */ static void env_set_location(mus_any *ptr, mus_long_t val) { seg *gen = (seg *)ptr; mus_long_t ctr = 0, loc; loc = gen->locs[gen->index] - gen->loc; if (loc == val) return; if (loc > val) mus_reset(ptr); else ctr = loc; while ((gen->index < (gen->size - 1)) && /* this was gen->size */ (ctr < val)) { mus_long_t samps; if (val > gen->locs[gen->index]) samps = gen->locs[gen->index] - ctr; else samps = val - ctr; switch (gen->style) { case MUS_ENV_LINEAR: gen->current_value += (samps * gen->rate); break; case MUS_ENV_STEP: gen->current_value = gen->rate; break; case MUS_ENV_EXPONENTIAL: gen->power *= exp(samps * log(gen->rate)); gen->current_value = gen->offset + (gen->scaler * gen->power); break; } ctr += samps; if (ctr < val) { gen->index++; if (gen->index < gen->size) gen->rate = gen->rates[gen->index]; } } gen->loc = gen->locs[gen->index] - ctr; } mus_float_t mus_env_interp(mus_float_t x, mus_any *ptr) { /* the accuracy depends on the duration here -- more samples = more accurate */ seg *gen = (seg *)ptr; env_set_location(ptr, (mus_long_t)((x * (gen->end + 1)) / (gen->original_data[gen->size * 2 - 2]))); return(gen->current_value); } mus_float_t mus_env_any(mus_any *e, mus_float_t (*connect_points)(mus_float_t val)) { /* "env_any" is supposed to mimic "out-any" */ seg *gen = (seg *)e; mus_float_t *pts; int pt, size; mus_float_t y0, y1, new_val, val; mus_float_t scaler, offset; scaler = gen->original_scaler; offset = gen->original_offset; size = gen->size; if (size <= 1) return(offset + scaler * connect_points(0.0)); pts = gen->original_data; pt = gen->index; if (pt >= (size - 1)) pt = size - 2; if (pts[pt * 2 + 1] <= pts[pt * 2 + 3]) { y0 = pts[pt * 2 + 1]; y1 = pts[pt * 2 + 3]; } else { y1 = pts[pt * 2 + 1]; y0 = pts[pt * 2 + 3]; } val = (mus_env(e) - offset) / scaler; new_val = connect_points( (val - y0) / (y1 - y0)); return(offset + scaler * (y0 + new_val * (y1 - y0))); } /* ---------------- pulsed-env ---------------- */ typedef struct { mus_any_class *core; mus_any *e, *p; bool gens_allocated; } plenv; static void free_pulsed_env(mus_any *ptr) { plenv *g; g = (plenv *)ptr; if (g->gens_allocated) { mus_free(g->e); mus_free(g->p); } free(ptr); } static mus_any *plenv_copy(mus_any *ptr) { plenv *g, *p; p = (plenv *)ptr; g = (plenv *)malloc(sizeof(plenv)); memcpy((void *)g, (void *)ptr, sizeof(plenv)); g->gens_allocated = true; g->e = mus_copy(p->e); g->p = mus_copy(p->p); return((mus_any *)g); } static mus_float_t run_pulsed_env(mus_any *ptr, mus_float_t input, mus_float_t unused) { return(mus_pulsed_env(ptr, input)); } static void pulsed_env_reset(mus_any *ptr) { plenv *pl = (plenv *)ptr; mus_reset(pl->e); mus_reset(pl->p); } static bool pulsed_env_equalp(mus_any *p1, mus_any *p2) { plenv *f1 = (plenv *)p1; plenv *f2 = (plenv *)p2; if (f1 == f2) return(true); return((env_equalp(f1->e, f2->e)) && (sw_equalp(f1->p, f2->p))); } static char *describe_pulsed_env(mus_any *ptr) { char *describe_buffer; describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE); snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s", mus_name(ptr)); return(describe_buffer); } static mus_any_class PULSED_ENV_CLASS = { MUS_PULSED_ENV, (char *)S_pulsed_env, &free_pulsed_env, &describe_pulsed_env, &pulsed_env_equalp, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &run_pulsed_env, MUS_NOT_SPECIAL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &pulsed_env_reset, 0, &plenv_copy }; mus_any *mus_make_pulsed_env(mus_any *e, mus_any *p) { plenv *gen; gen = (plenv *)malloc(sizeof(plenv)); gen->core = &PULSED_ENV_CLASS; gen->e = e; gen->p = p; gen->gens_allocated = false; return((mus_any *)gen); } bool mus_is_pulsed_env(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_PULSED_ENV)); } mus_float_t mus_pulsed_env(mus_any *g, mus_float_t inval) { plenv *pl = (plenv *)g; mus_float_t pt_val; pt_val = mus_pulse_train(pl->p, inval); if (pt_val > 0.1) mus_reset(pl->e); return(mus_env(pl->e)); } mus_float_t mus_pulsed_env_unmodulated(mus_any *g) { plenv *pl = (plenv *)g; mus_float_t pt_val; pt_val = mus_pulse_train_unmodulated(pl->p); if (pt_val > 0.1) mus_reset(pl->e); return(mus_env(pl->e)); } /* ---------------- input/output ---------------- */ static mus_float_t mus_read_sample(mus_any *fd, mus_long_t frample, int chan) { if ((check_gen(fd, "mus-read-sample")) && ((fd->core)->read_sample)) return(((*(fd->core)->read_sample))(fd, frample, chan)); return((mus_float_t)mus_error(MUS_NO_SAMPLE_INPUT, ":can't find %s's sample input function", mus_name(fd))); } char *mus_file_name(mus_any *gen) { if ((check_gen(gen, S_mus_file_name)) && (gen->core->file_name)) return((*(gen->core->file_name))(gen)); else mus_error(MUS_NO_FILE_NAME, "can't get %s's file name", mus_name(gen)); return(NULL); } bool mus_is_input(mus_any *gen) { return((gen) && (gen->core->extended_type == MUS_INPUT)); } bool mus_is_output(mus_any *gen) { return((gen) && (gen->core->extended_type == MUS_OUTPUT)); } /* ---------------- file->sample ---------------- */ typedef struct { mus_any_class *core; int chan; int dir; mus_long_t loc; char *file_name; int chans; mus_float_t **ibufs, **saved_data; mus_float_t *sbuf; mus_long_t data_start, data_end, file_end; mus_long_t file_buffer_size; mus_float_t (*reader)(mus_any *ptr); } rdin; static char *describe_file_to_sample(mus_any *ptr) { rdin *gen = (rdin *)ptr; char *describe_buffer; describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE); snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s %s", mus_name(ptr), gen->file_name); return(describe_buffer); } static bool rdin_equalp(mus_any *p1, mus_any *p2) { rdin *r1 = (rdin *)p1; rdin *r2 = (rdin *)p2; return((p1 == p2) || ((r1) && (r2) && (r1->core->type == r2->core->type) && (r1->chan == r2->chan) && (r1->loc == r2->loc) && (r1->dir == r2->dir) && (r1->file_name) && (r2->file_name) && (strcmp(r1->file_name, r2->file_name) == 0))); } static void free_file_to_sample(mus_any *p) { rdin *ptr = (rdin *)p; if (ptr->core->end) ((*ptr->core->end))(p); free(ptr->file_name); free(ptr); } static mus_long_t make_ibufs(rdin *gen) { int i; mus_long_t len; len = gen->file_end + 1; if (len > gen->file_buffer_size) len = gen->file_buffer_size; gen->ibufs = (mus_float_t **)malloc(gen->chans * sizeof(mus_float_t *)); for (i = 0; i < gen->chans; i++) gen->ibufs[i] = (mus_float_t *)malloc(len * sizeof(mus_float_t)); return(len); } static mus_any *rdin_copy(mus_any *ptr) { rdin *g, *p; p = (rdin *)ptr; g = (rdin *)malloc(sizeof(rdin)); memcpy((void *)g, (void *)ptr, sizeof(rdin)); g->file_name = mus_strdup(p->file_name); if (p->ibufs) { int i; mus_long_t len; len = make_ibufs(g); for (i = 0; i < g->chans; i++) memcpy((void *)(g->ibufs[i]), (void *)(p->ibufs[i]), len * sizeof(mus_float_t)); } return((mus_any *)g); } static mus_long_t file_to_sample_length(mus_any *ptr) {return((((rdin *)ptr)->file_end));} static int file_to_sample_channels(mus_any *ptr) {return((int)(((rdin *)ptr)->chans));} static mus_float_t file_to_sample_increment(mus_any *rd) {return((mus_float_t)(((rdin *)rd)->dir));} static mus_float_t file_to_sample_set_increment(mus_any *rd, mus_float_t val) {((rdin *)rd)->dir = (int)val; return(val);} static char *file_to_sample_file_name(mus_any *ptr) {return(((rdin *)ptr)->file_name);} static void no_reset(mus_any *ptr) {} static mus_float_t mus_in_any_from_file(mus_any *ptr, mus_long_t samp, int chan) { /* check in-core buffer bounds, * if needed read new buffer (taking into account dir) * return mus_float_t at samp (frample) */ rdin *gen = (rdin *)ptr; if (chan >= gen->chans) return(0.0); if ((samp <= gen->data_end) && (samp >= gen->data_start)) return((mus_float_t)(gen->ibufs[chan][samp - gen->data_start])); if ((samp >= 0) && (samp < gen->file_end)) { /* got to read it from the file */ int fd; mus_long_t newloc; /* read in first buffer start either at samp (dir > 0) or samp-bufsize (dir < 0) */ if (samp >= gen->data_start) /* gen dir is irrelevant here (see grev in clm23.scm) */ newloc = samp; else newloc = (mus_long_t)(samp - (gen->file_buffer_size * .75)); /* The .75 in the backwards read is trying to avoid reading the full buffer on * nearly every sample when we're oscillating around the * nominal buffer start/end (in src driven by an oscil for example) */ if (newloc < 0) newloc = 0; gen->data_start = newloc; gen->data_end = newloc + gen->file_buffer_size - 1; fd = mus_sound_open_input(gen->file_name); if (fd == -1) return((mus_float_t)mus_error(MUS_CANT_OPEN_FILE, "open(%s) -> %s", gen->file_name, STRERROR(errno))); else { if (gen->ibufs == NULL) make_ibufs(gen); mus_file_seek_frample(fd, gen->data_start); if ((gen->data_start + gen->file_buffer_size) >= gen->file_end) mus_file_read_chans(fd, gen->data_start, gen->file_end - gen->data_start, gen->chans, gen->ibufs, gen->ibufs); else mus_file_read_chans(fd, gen->data_start, gen->file_buffer_size, gen->chans, gen->ibufs, gen->ibufs); /* we have to check file_end here because chunked files can have trailing chunks containing * comments or whatever. io.c (mus_file_read_*) merely calls read, and translates bytes -- * if it gets fewer than requested, it zeros from the point where the incoming file data stopped, * but that can be far beyond the actual end of the sample data! It is at this level that * we know how much data is actually supposed to be in the file. * * Also, file_end is the number of framples, so we should not read samp # file_end (see above). */ mus_sound_close_input(fd); if (gen->data_end > gen->file_end) gen->data_end = gen->file_end; } return((mus_float_t)(gen->ibufs[chan][samp - gen->data_start])); } return(0.0); } static mus_float_t run_file_to_sample(mus_any *ptr, mus_float_t arg1, mus_float_t arg2) { /* mus_read_sample here? */ return(mus_in_any_from_file(ptr, (int)arg1, (int)arg2)); } static int file_to_sample_end(mus_any *ptr) { rdin *gen = (rdin *)ptr; if (gen) { if (gen->ibufs) { int i; for (i = 0; i < gen->chans; i++) if (gen->ibufs[i]) free(gen->ibufs[i]); free(gen->ibufs); gen->ibufs = NULL; gen->sbuf = NULL; } } return(0); } static mus_any_class FILE_TO_SAMPLE_CLASS = { MUS_FILE_TO_SAMPLE, (char *)S_file_to_sample, &free_file_to_sample, &describe_file_to_sample, &rdin_equalp, 0, 0, &file_to_sample_length, 0, 0, 0, 0, 0, 0, 0, &file_to_sample_increment, &file_to_sample_set_increment, &run_file_to_sample, MUS_INPUT, NULL, &file_to_sample_channels, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &mus_in_any_from_file, 0, &file_to_sample_file_name, &file_to_sample_end, 0, /* location */ 0, /* set_location */ 0, /* channel */ 0, 0, 0, 0, &no_reset, 0, &rdin_copy }; bool mus_is_file_to_sample(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_FILE_TO_SAMPLE)); } mus_any *mus_make_file_to_sample_with_buffer_size(const char *filename, mus_long_t buffer_size) { rdin *gen; if (filename == NULL) mus_error(MUS_NO_FILE_NAME_PROVIDED, S_make_file_to_sample " requires a file name"); else { gen = (rdin *)calloc(1, sizeof(rdin)); gen->core = &FILE_TO_SAMPLE_CLASS; gen->file_name = (char *)malloc((strlen(filename) + 1) * sizeof(char)); strcpy(gen->file_name, filename); gen->data_end = -1; /* force initial read */ gen->chans = mus_sound_chans(gen->file_name); if (gen->chans <= 0) mus_error(MUS_NO_CHANNELS, S_make_file_to_sample ": %s chans: %d", filename, gen->chans); gen->file_end = mus_sound_framples(gen->file_name); if (gen->file_end < 0) mus_error(MUS_NO_LENGTH, S_make_file_to_sample ": %s framples: %lld", filename, gen->file_end); if (buffer_size < gen->file_end) gen->file_buffer_size = buffer_size; else gen->file_buffer_size = gen->file_end; return((mus_any *)gen); } return(NULL); } mus_any *mus_make_file_to_sample(const char *filename) { return(mus_make_file_to_sample_with_buffer_size(filename, clm_file_buffer_size)); } mus_float_t mus_file_to_sample(mus_any *ptr, mus_long_t samp, int chan) { rdin *gen = (rdin *)ptr; if (chan >= gen->chans) return(0.0); /* redundant in a sense, but saves the call overhead of mus_in_any_from_file */ if ((samp <= gen->data_end) && (samp >= gen->data_start)) return((mus_float_t)(gen->ibufs[chan][samp - gen->data_start])); return(mus_in_any_from_file(ptr, samp, chan)); } /* ---------------- readin ---------------- */ /* readin reads only the desired channel and increments the location by the direction * it inherits from and specializes the file_to_sample class */ static char *describe_readin(mus_any *ptr) { rdin *gen = (rdin *)ptr; char *describe_buffer; describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE); snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s %s[chan %d], loc: %lld, dir: %d", mus_name(ptr), gen->file_name, gen->chan, gen->loc, gen->dir); return(describe_buffer); } static void free_readin(mus_any *p) { rdin *ptr = (rdin *)p; if (ptr->core->end) ((*ptr->core->end))(p); free(ptr->file_name); free(ptr); } static mus_float_t run_readin(mus_any *ptr, mus_float_t unused1, mus_float_t unused2) {return(((rdin *)ptr)->reader(ptr));} static mus_float_t readin_to_sample(mus_any *ptr, mus_long_t samp, int chan) {return(((rdin *)ptr)->reader(ptr));} static mus_float_t rd_increment(mus_any *ptr) {return((mus_float_t)(((rdin *)ptr)->dir));} static mus_float_t rd_set_increment(mus_any *ptr, mus_float_t val) {((rdin *)ptr)->dir = (int)val; return(val);} static mus_long_t rd_location(mus_any *rd) {return(((rdin *)rd)->loc);} static mus_long_t rd_set_location(mus_any *rd, mus_long_t loc) {((rdin *)rd)->loc = loc; return(loc);} static int rd_channel(mus_any *rd) {return(((rdin *)rd)->chan);} static mus_any_class READIN_CLASS = { MUS_READIN, (char *)S_readin, &free_readin, &describe_readin, &rdin_equalp, 0, 0, &file_to_sample_length, 0, 0, 0, 0, 0, &fallback_scaler, 0, &rd_increment, &rd_set_increment, &run_readin, MUS_INPUT, NULL, &file_to_sample_channels, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &readin_to_sample, 0, &file_to_sample_file_name, &file_to_sample_end, &rd_location, &rd_set_location, &rd_channel, 0, 0, 0, 0, &no_reset, 0, &rdin_copy }; bool mus_is_readin(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_READIN)); } mus_float_t mus_readin(mus_any *ptr) { return(((rdin *)ptr)->reader(ptr)); } static mus_float_t safe_readin(mus_any *ptr) { mus_float_t res; rdin *rd = (rdin *)ptr; if ((rd->loc < rd->file_end) && (rd->loc >= 0)) res = rd->sbuf[rd->loc]; else res = 0.0; rd->loc += rd->dir; return(res); } static mus_float_t readin(mus_any *ptr) { mus_float_t res; rdin *rd = (rdin *)ptr; if ((rd->loc <= rd->data_end) && (rd->loc >= rd->data_start)) res = rd->sbuf[rd->loc - rd->data_start]; else { if ((rd->loc < 0) || (rd->loc >= rd->file_end)) res = 0.0; else res = mus_in_any_from_file(ptr, rd->loc, rd->chan); } rd->loc += rd->dir; return(res); } mus_any *mus_make_readin_with_buffer_size(const char *filename, int chan, mus_long_t start, int direction, mus_long_t buffer_size) { rdin *gen; if (chan >= mus_sound_chans(filename)) mus_error(MUS_NO_SUCH_CHANNEL, S_make_readin ": %s, chan: %d, but chans: %d", filename, chan, mus_sound_chans(filename)); gen = (rdin *)mus_make_file_to_sample(filename); if (gen) { mus_float_t **saved_data = NULL; gen->core = &READIN_CLASS; gen->loc = start; gen->dir = direction; gen->chan = chan; /* the saved data option does not save us anything in file_to_sample above */ gen->saved_data = mus_sound_saved_data(filename); if (!saved_data) { char *str; str = mus_expand_filename(filename); if (str) { gen->saved_data = mus_sound_saved_data(str); free(str); } } if (gen->saved_data) { gen->file_buffer_size = gen->file_end; gen->sbuf = gen->saved_data[chan]; gen->reader = safe_readin; gen->data_start = 0; gen->data_end = gen->file_end; } else { gen->ibufs = (mus_float_t **)calloc(gen->chans, sizeof(mus_float_t *)); if (buffer_size > gen->file_end) { gen->file_buffer_size = gen->file_end; gen->reader = safe_readin; gen->ibufs[chan] = (mus_float_t *)malloc(gen->file_buffer_size * sizeof(mus_float_t)); mus_in_any_from_file((mus_any *)gen, 0, chan); } else { gen->file_buffer_size = buffer_size; gen->reader = readin; gen->ibufs[chan] = (mus_float_t *)malloc(gen->file_buffer_size * sizeof(mus_float_t)); } gen->sbuf = gen->ibufs[chan]; } return((mus_any *)gen); } return(NULL); } /* it would be easy to extend readin to read from a float-vector by using the saved_data and safe_readin * business above -- just need mus_make_readin_from_float_vector or something. */ mus_long_t mus_set_location(mus_any *gen, mus_long_t loc) { if ((check_gen(gen, S_set S_mus_location)) && (gen->core->set_location)) return((*(gen->core->set_location))(gen, loc)); return((mus_long_t)mus_error(MUS_NO_LOCATION, "can't set %s's location", mus_name(gen))); } /* ---------------- in-any ---------------- */ mus_float_t mus_in_any(mus_long_t samp, int chan, mus_any *IO) { if (IO) return(mus_read_sample(IO, samp, chan)); return(0.0); } bool mus_in_any_is_safe(mus_any *ptr) { rdin *gen = (rdin *)ptr; return((gen) && ((gen->core->read_sample == mus_in_any_from_file) || (gen->core->read_sample == readin_to_sample))); } /* ---------------- file->frample ---------------- */ /* also built on file->sample */ static char *describe_file_to_frample(mus_any *ptr) { rdin *gen = (rdin *)ptr; char *describe_buffer; describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE); snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s %s", mus_name(ptr), gen->file_name); return(describe_buffer); } static mus_float_t run_file_to_frample(mus_any *ptr, mus_float_t arg1, mus_float_t arg2) { mus_error(MUS_NO_RUN, "no run method for file->frample"); return(0.0); } static mus_any_class FILE_TO_FRAMPLE_CLASS = { MUS_FILE_TO_FRAMPLE, (char *)S_file_to_frample, &free_file_to_sample, &describe_file_to_frample, &rdin_equalp, 0, 0, &file_to_sample_length, 0, 0, 0, 0, 0, &fallback_scaler, 0, &file_to_sample_increment, /* allow backward reads */ &file_to_sample_set_increment, &run_file_to_frample, MUS_INPUT, NULL, &file_to_sample_channels, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &mus_in_any_from_file, 0, &file_to_sample_file_name, &file_to_sample_end, 0, /* location */ 0, /* set_location */ 0, /* channel */ 0, 0, 0, 0, &no_reset, 0, &rdin_copy }; mus_any *mus_make_file_to_frample_with_buffer_size(const char *filename, mus_long_t buffer_size) { rdin *gen; gen = (rdin *)mus_make_file_to_sample_with_buffer_size(filename, buffer_size); if (gen) { gen->core = &FILE_TO_FRAMPLE_CLASS; return((mus_any *)gen); } return(NULL); } mus_any *mus_make_file_to_frample(const char *filename) { return(mus_make_file_to_frample_with_buffer_size(filename, clm_file_buffer_size)); } bool mus_is_file_to_frample(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_FILE_TO_FRAMPLE)); } mus_float_t *mus_file_to_frample(mus_any *ptr, mus_long_t samp, mus_float_t *f) { rdin *gen = (rdin *)ptr; int i; if ((samp <= gen->data_end) && (samp >= gen->data_start)) { mus_long_t pos; pos = samp - gen->data_start; f[0] = gen->ibufs[0][pos]; for (i = 1; i < gen->chans; i++) f[i] = gen->ibufs[i][pos]; } else { if ((samp < 0) || (samp >= gen->file_end)) { for (i = 0; i < gen->chans; i++) f[i] = 0.0; } else { f[0] = mus_in_any_from_file(ptr, samp, 0); for (i = 1; i < gen->chans; i++) f[i] = mus_in_any_from_file(ptr, samp, i); } } return(f); } /* ---------------- sample->file ---------------- */ /* in all output functions, the assumption is that we're adding to whatever already exists */ /* also, the "end" methods need to flush the output buffer */ /* rdout struct is in clm.h */ static char *describe_sample_to_file(mus_any *ptr) { rdout *gen = (rdout *)ptr; char *describe_buffer; describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE); snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s %s", mus_name(ptr), gen->file_name); return(describe_buffer); } static bool sample_to_file_equalp(mus_any *p1, mus_any *p2) {return(p1 == p2);} static void free_sample_to_file(mus_any *p) { rdout *ptr = (rdout *)p; if (ptr->core->end) ((*ptr->core->end))(p); free(ptr->file_name); free(ptr); } static mus_any *rdout_copy(mus_any *ptr) { rdout *g, *p; p = (rdout *)ptr; g = (rdout *)malloc(sizeof(rdout)); memcpy((void *)g, (void *)ptr, sizeof(rdout)); g->file_name = mus_strdup(p->file_name); if (p->obufs) { int i; mus_long_t bytes; bytes = clm_file_buffer_size * sizeof(mus_float_t); g->obufs = (mus_float_t **)malloc(g->chans * sizeof(mus_float_t *)); for (i = 0; i < g->chans; i++) { g->obufs[i] = (mus_float_t *)malloc(bytes); memcpy((void *)(g->obufs[i]), (void *)(p->obufs[i]), bytes); } g->obuf0 = g->obufs[0]; if (g->chans > 1) g->obuf1 = g->obufs[1]; else g->obuf1 = NULL; } return((mus_any *)g); } static int sample_to_file_channels(mus_any *ptr) {return((int)(((rdout *)ptr)->chans));} static mus_long_t bufferlen(mus_any *ptr) {return(clm_file_buffer_size);} static mus_long_t set_bufferlen(mus_any *ptr, mus_long_t len) {clm_file_buffer_size = len; return(len);} static char *sample_to_file_file_name(mus_any *ptr) {return(((rdout *)ptr)->file_name);} static int sample_to_file_end(mus_any *ptr); static mus_float_t run_sample_to_file(mus_any *ptr, mus_float_t arg1, mus_float_t arg2) {mus_error(MUS_NO_RUN, "no run method for sample->file"); return(0.0);} static mus_any_class SAMPLE_TO_FILE_CLASS = { MUS_SAMPLE_TO_FILE, (char *)S_sample_to_file, &free_sample_to_file, &describe_sample_to_file, &sample_to_file_equalp, 0, 0, &bufferlen, &set_bufferlen, /* does this have any effect on the current gen? */ 0, 0, 0, 0, &fallback_scaler, 0, 0, 0, &run_sample_to_file, MUS_OUTPUT, NULL, &sample_to_file_channels, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &mus_out_any_to_file, &sample_to_file_file_name, &sample_to_file_end, 0, 0, 0, 0, 0, 0, 0, &no_reset, 0, &rdout_copy }; static int *sample_type_zero = NULL; int mus_sample_type_zero(mus_sample_t samp_type) { return(sample_type_zero[samp_type]); } static void flush_buffers(rdout *gen) { int fd; if ((gen->obufs == NULL) || (mus_file_probe(gen->file_name) == 0) || (gen->chans == 0)) return; /* can happen if output abandoned, then later mus_free called via GC sweep */ fd = mus_sound_open_input(gen->file_name); if (fd == -1) { /* no output yet, so open the output file and write the current samples (no need to add to existing samples in this case) */ fd = mus_sound_open_output(gen->file_name, (int)sampling_rate, gen->chans, gen->output_sample_type, gen->output_header_type, NULL); if (fd == -1) mus_error(MUS_CANT_OPEN_FILE, "open(%s) -> %s", gen->file_name, STRERROR(errno)); else { mus_file_write(fd, 0, gen->out_end, gen->chans, gen->obufs); mus_sound_close_output(fd, (gen->out_end + 1) * gen->chans * mus_bytes_per_sample(mus_sound_sample_type(gen->file_name))); } } else { /* get existing samples, add new output, write back to output */ mus_float_t **addbufs = NULL; int i; mus_sample_t sample_type; mus_long_t current_file_framples, framples_to_add; sample_type = mus_sound_sample_type(gen->file_name); current_file_framples = mus_sound_framples(gen->file_name); /* this is often 0 (brand-new file) */ if (current_file_framples > gen->data_start) { bool allocation_failed = false; addbufs = (mus_float_t **)calloc(gen->chans, sizeof(mus_float_t *)); for (i = 0; i < gen->chans; i++) { /* clm_file_buffer_size may be too large, but it's very hard to tell that * in advance. In Linux, malloc returns a non-null pointer even when * there's no memory available, so you have to touch the memory to force * the OS to deal with it, then the next allocation returns null. */ addbufs[i] = (mus_float_t *)malloc(clm_file_buffer_size * sizeof(mus_float_t)); if (addbufs[i]) addbufs[i][0] = 0.0; else { allocation_failed = true; break; } } if (allocation_failed) { mus_long_t old_file_buffer_size = 0; /* first clean up the mess we made */ for (i = 0; i < gen->chans; i++) if (addbufs[i]) { free(addbufs[i]); addbufs[i] = NULL; } free(addbufs); /* it would take a lot of screwing around to find the biggest clm_file_buffer_size we could handle, * and it might fail on the next call (if more chans), so we'll throw an error. We could get * say 1024 samps per chan, then run through a loop outputting the current buffer, but geez... */ /* but... if we hit this in with-sound, mus_error calls (eventually) s7_error which sees the * dynamic-wind and tries to call mus-close, which tries to flush the buffers and we have * an infinite loop. So, we need to clean up right now. */ mus_sound_close_input(fd); old_file_buffer_size = clm_file_buffer_size; clm_file_buffer_size = MUS_DEFAULT_FILE_BUFFER_SIZE; mus_error(MUS_MEMORY_ALLOCATION_FAILED, S_mus_file_buffer_size " (%lld) is too large: we can't allocate the output buffers!", old_file_buffer_size); return; } } framples_to_add = gen->out_end - gen->data_start; /* if the caller reset clm_file_buffer_size during a run, framples_to_add might be greater than the assumed buffer size, * so we need to complain and fix up the limits. In CLM, the size is set in sound.lisp, begin-with-sound. * In Snd via mus_set_file_buffer_size in clm2xen.c. The initial default is set in mus_initialize * called in CLM by clm-initialize-links via in cmus.c, and in Snd in clm2xen.c when the module is setup. */ if (framples_to_add >= clm_file_buffer_size) { mus_print("clm-file-buffer-size changed? %lld <= %lld (start: %lld, end: %lld, %lld)", clm_file_buffer_size, framples_to_add, gen->data_start, gen->data_end, gen->out_end); framples_to_add = clm_file_buffer_size - 1; /* this means we drop samples -- the other choice (short of throwing an error) would * be to read/allocate the bigger size. */ } if (addbufs) { mus_file_seek_frample(fd, gen->data_start); mus_file_read(fd, gen->data_start, framples_to_add + 1, gen->chans, addbufs); } mus_sound_close_input(fd); /* close previous mus_sound_open_input */ fd = mus_sound_reopen_output(gen->file_name, gen->chans, sample_type, mus_sound_header_type(gen->file_name), mus_sound_data_location(gen->file_name)); if ((current_file_framples < gen->data_start) && (sample_type_zero[sample_type] != 0)) { /* we're about to create a gap in the output file. mus_file_seek_frample calls lseek which (man lseek): * * "The lseek function allows the file offset to be set beyond the end of * the existing end-of-file of the file (but this does not change the size * of the file). If data is later written at this point, subsequent reads * of the data in the gap return bytes of zeros (until data is actually * written into the gap)." * * but 0 bytes in a file are not interpreted as sound samples of 0 in several sample types. * for example, mus-mulaw 0 => -.98, whereas sound sample 0 is a byte of 255. * see the table at the end of this file (sample_type_zero) for the other cases. * * So, we need to write explicit sample-type 0 values in those cases where machine 0's * won't be sample type 0. sample_type_zero[type] != 0 signals we have such a * case, and returns the nominal zero value. For unsigned shorts, we also need to * take endianess into account. */ mus_long_t filler, current_samps, bytes, bps; unsigned char *zeros; #define MAX_ZERO_SAMPLES 65536 bps = mus_bytes_per_sample(sample_type); filler = gen->data_start - current_file_framples; mus_file_seek_frample(fd, current_file_framples); if (filler > MAX_ZERO_SAMPLES) bytes = MAX_ZERO_SAMPLES * bps * gen->chans; else bytes = filler * bps * gen->chans; zeros = (unsigned char *)malloc(bytes); if (bps == 1) memset((void *)zeros, sample_type_zero[sample_type], bytes); else /* it has to be a short */ { int df, i, b1, b2; df = sample_type_zero[sample_type]; b1 = df >> 8; b2 = df & 0xff; for (i = 0; i < bytes; i += 2) { zeros[i] = b2; zeros[i + 1] = b1; } } /* (with-sound (:sample-type mus-ulshort) (fm-violin 10 1 440 .1)) */ while (filler > 0) { ssize_t wbytes; if (filler > MAX_ZERO_SAMPLES) current_samps = MAX_ZERO_SAMPLES; else { current_samps = filler; bytes = current_samps * bps * gen->chans; } wbytes = write(fd, zeros, bytes); if (wbytes != bytes) fprintf(stderr, "%s[%d]: write trouble\n", __func__, __LINE__); filler -= current_samps; } free(zeros); } if (addbufs) { int j; /* fill/write output buffers with current data added to saved data */ for (j = 0; j < gen->chans; j++) { mus_float_t *adder, *vals; mus_long_t add4; adder = addbufs[j]; vals = gen->obufs[j]; add4 = framples_to_add - 4; i = 0; while (i <= add4) { adder[i] += vals[i]; i++; adder[i] += vals[i]; i++; adder[i] += vals[i]; i++; adder[i] += vals[i]; i++; } for (; i <= framples_to_add; i++) adder[i] += vals[i]; } mus_file_seek_frample(fd, gen->data_start); mus_file_write(fd, 0, framples_to_add, gen->chans, addbufs); for (i = 0; i < gen->chans; i++) free(addbufs[i]); free(addbufs); } else { /* output currently empty, so just flush out the gen->obufs */ mus_file_seek_frample(fd, gen->data_start); mus_file_write(fd, 0, framples_to_add, gen->chans, gen->obufs); } if (current_file_framples <= gen->out_end) current_file_framples = gen->out_end + 1; mus_sound_close_output(fd, current_file_framples * gen->chans * mus_bytes_per_sample(sample_type)); } } mus_any *mus_sample_to_file_add(mus_any *out1, mus_any *out2) { mus_long_t min_framples; rdout *dest = (rdout *)out1; rdout *in_coming = (rdout *)out2; int chn, min_chans; min_chans = dest->chans; if (in_coming->chans < min_chans) min_chans = in_coming->chans; min_framples = in_coming->out_end; for (chn = 0; chn < min_chans; chn++) { mus_long_t i; for (i = 0; i < min_framples; i++) dest->obufs[chn][i] += in_coming->obufs[chn][i]; memset((void *)(in_coming->obufs[chn]), 0, min_framples * sizeof(mus_float_t)); } if (min_framples > dest->out_end) dest->out_end = min_framples; in_coming->out_end = 0; in_coming->data_start = 0; return((mus_any*)dest); } mus_float_t mus_out_any_to_file(mus_any *ptr, mus_long_t samp, int chan, mus_float_t val) { rdout *gen = (rdout *)ptr; if (!ptr) return(val); if ((chan >= gen->chans) || /* checking for (val == 0.0) here appears to make no difference overall */ (!(gen->obufs))) return(val); if ((samp <= gen->data_end) && (samp >= gen->data_start)) gen->obufs[chan][samp - gen->data_start] += val; else { int j; if (samp < 0) return(val); flush_buffers(gen); for (j = 0; j < gen->chans; j++) memset((void *)(gen->obufs[j]), 0, clm_file_buffer_size * sizeof(mus_float_t)); gen->data_start = samp; gen->data_end = samp + clm_file_buffer_size - 1; gen->obufs[chan][0] += val; gen->out_end = samp; /* this resets the current notion of where in the buffer the new data ends */ } if (samp > gen->out_end) gen->out_end = samp; return(val); } static void mus_out_chans_to_file(rdout *gen, mus_long_t samp, int chans, mus_float_t *vals) { int i; if ((samp <= gen->data_end) && (samp >= gen->data_start)) { mus_long_t pos; pos = samp - gen->data_start; for (i = 0; i < chans; i++) gen->obufs[i][pos] += vals[i]; } else { int j; if (samp < 0) return; flush_buffers(gen); for (j = 0; j < gen->chans; j++) memset((void *)(gen->obufs[j]), 0, clm_file_buffer_size * sizeof(mus_float_t)); gen->data_start = samp; gen->data_end = samp + clm_file_buffer_size - 1; for (i = 0; i < chans; i++) gen->obufs[i][0] += vals[i]; gen->out_end = samp; /* this resets the current notion of where in the buffer the new data ends */ } if (samp > gen->out_end) gen->out_end = samp; } static mus_float_t mus_outa_to_file(mus_any *ptr, mus_long_t samp, mus_float_t val) { rdout *gen = (rdout *)ptr; if (!ptr) return(val); if ((!(gen->obuf0)) || (!(gen->obufs))) return(val); if ((samp <= gen->data_end) && (samp >= gen->data_start)) gen->obuf0[samp - gen->data_start] += val; else { int j; if (samp < 0) return(val); flush_buffers(gen); for (j = 0; j < gen->chans; j++) memset((void *)(gen->obufs[j]), 0, clm_file_buffer_size * sizeof(mus_float_t)); gen->data_start = samp; gen->data_end = samp + clm_file_buffer_size - 1; gen->obuf0[0] += val; gen->out_end = samp; /* this resets the current notion of where in the buffer the new data ends */ } if (samp > gen->out_end) gen->out_end = samp; return(val); } static mus_float_t mus_outb_to_file(mus_any *ptr, mus_long_t samp, mus_float_t val) { rdout *gen = (rdout *)ptr; if (!ptr) return(val); if ((!(gen->obuf1)) || (!(gen->obufs))) return(val); if ((samp <= gen->data_end) && (samp >= gen->data_start)) gen->obuf1[samp - gen->data_start] += val; else { int j; if (samp < 0) return(val); flush_buffers(gen); for (j = 0; j < gen->chans; j++) memset((void *)(gen->obufs[j]), 0, clm_file_buffer_size * sizeof(mus_float_t)); gen->data_start = samp; gen->data_end = samp + clm_file_buffer_size - 1; gen->obuf1[0] += val; gen->out_end = samp; /* this resets the current notion of where in the buffer the new data ends */ } if (samp > gen->out_end) gen->out_end = samp; return(val); } static int sample_to_file_end(mus_any *ptr) { rdout *gen = (rdout *)ptr; if ((gen) && (gen->obufs)) { if (gen->chans > 0) { int i; flush_buffers(gen); /* this forces the error handling stuff, unlike in free reader case */ for (i = 0; i < gen->chans; i++) if (gen->obufs[i]) free(gen->obufs[i]); } free(gen->obufs); gen->obufs = NULL; gen->obuf0 = NULL; gen->obuf1 = NULL; } return(0); } bool mus_is_sample_to_file(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_SAMPLE_TO_FILE)); } static mus_any *mus_make_sample_to_file_with_comment_1(const char *filename, int out_chans, mus_sample_t samp_type, mus_header_t head_type, const char *comment, bool reopen) { if (filename == NULL) mus_error(MUS_NO_FILE_NAME_PROVIDED, S_make_sample_to_file " requires a file name"); else { int fd; if (out_chans <= 0) return(NULL); if (reopen) fd = mus_sound_reopen_output(filename, out_chans, samp_type, head_type, mus_sound_data_location(filename)); else fd = mus_sound_open_output(filename, (int)sampling_rate, out_chans, samp_type, head_type, comment); if (fd == -1) mus_error(MUS_CANT_OPEN_FILE, S_make_sample_to_file ": open(%s) -> %s", filename, STRERROR(errno)); else { rdout *gen; int i; gen = (rdout *)calloc(1, sizeof(rdout)); gen->core = &SAMPLE_TO_FILE_CLASS; gen->file_name = (char *)calloc(strlen(filename) + 1, sizeof(char)); strcpy(gen->file_name, filename); gen->data_start = 0; gen->data_end = clm_file_buffer_size - 1; gen->out_end = 0; gen->chans = out_chans; gen->output_sample_type = samp_type; gen->output_header_type = head_type; gen->obufs = (mus_float_t **)malloc(gen->chans * sizeof(mus_float_t *)); for (i = 0; i < gen->chans; i++) gen->obufs[i] = (mus_float_t *)calloc(clm_file_buffer_size, sizeof(mus_float_t)); gen->obuf0 = gen->obufs[0]; if (out_chans > 1) gen->obuf1 = gen->obufs[1]; else gen->obuf1 = NULL; /* clear previous, if any */ if (mus_file_close(fd) != 0) mus_error(MUS_CANT_CLOSE_FILE, S_make_sample_to_file ": close(%d, %s) -> %s", fd, gen->file_name, STRERROR(errno)); return((mus_any *)gen); } } return(NULL); } mus_any *mus_continue_sample_to_file(const char *filename) { return(mus_make_sample_to_file_with_comment_1(filename, mus_sound_chans(filename), mus_sound_sample_type(filename), mus_sound_header_type(filename), NULL, true)); } mus_any *mus_make_sample_to_file_with_comment(const char *filename, int out_chans, mus_sample_t samp_type, mus_header_t head_type, const char *comment) { return(mus_make_sample_to_file_with_comment_1(filename, out_chans, samp_type, head_type, comment, false)); } mus_float_t mus_sample_to_file(mus_any *fd, mus_long_t samp, int chan, mus_float_t val) { /* return(mus_write_sample(ptr, samp, chan, val)); */ if ((fd) && ((fd->core)->write_sample)) return(((*(fd->core)->write_sample))(fd, samp, chan, val)); mus_error(MUS_NO_SAMPLE_OUTPUT, S_sample_to_file ": can't find %s's sample output function", mus_name(fd)); return(val); } int mus_close_file(mus_any *ptr) { rdout *gen = (rdout *)ptr; if ((mus_is_output(ptr)) && (gen->obufs)) sample_to_file_end(ptr); return(0); } /* ---------------- out-any ---------------- */ mus_float_t mus_out_any(mus_long_t samp, mus_float_t val, int chan, mus_any *IO) { if ((IO) && (samp >= 0)) { if ((IO->core)->write_sample) return(((*(IO->core)->write_sample))(IO, samp, chan, val)); mus_error(MUS_NO_SAMPLE_OUTPUT, "can't find %s's sample output function", mus_name(IO)); } return(val); } mus_float_t mus_safe_out_any_to_file(mus_long_t samp, mus_float_t val, int chan, mus_any *IO) { rdout *gen = (rdout *)IO; if (chan >= gen->chans) /* checking for (val == 0.0) here appears to make no difference overall */ return(val); /* does this need to check obufs? */ if ((samp <= gen->data_end) && (samp >= gen->data_start)) { gen->obufs[chan][samp - gen->data_start] += val; if (samp > gen->out_end) gen->out_end = samp; } else { int j; if (samp < 0) return(val); flush_buffers(gen); for (j = 0; j < gen->chans; j++) memset((void *)(gen->obufs[j]), 0, clm_file_buffer_size * sizeof(mus_float_t)); gen->data_start = samp; gen->data_end = samp + clm_file_buffer_size - 1; gen->obufs[chan][0] += val; gen->out_end = samp; /* this resets the current notion of where in the buffer the new data ends */ } return(val); } bool mus_out_any_is_safe(mus_any *IO) { rdout *gen = (rdout *)IO; return((gen) && (gen->obufs) && (gen->core->write_sample == mus_out_any_to_file)); } /* ---------------- frample->file ---------------- */ static char *describe_frample_to_file(mus_any *ptr) { rdout *gen = (rdout *)ptr; char *describe_buffer; describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE); snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s %s", mus_name(ptr), gen->file_name); return(describe_buffer); } static mus_float_t run_frample_to_file(mus_any *ptr, mus_float_t arg1, mus_float_t arg2) { mus_error(MUS_NO_RUN, "no run method for frample->file"); return(0.0); } static mus_any_class FRAMPLE_TO_FILE_CLASS = { MUS_FRAMPLE_TO_FILE, (char *)S_frample_to_file, &free_sample_to_file, &describe_frample_to_file, &sample_to_file_equalp, 0, 0, &bufferlen, &set_bufferlen, 0, 0, 0, 0, &fallback_scaler, 0, 0, 0, &run_frample_to_file, MUS_OUTPUT, NULL, &sample_to_file_channels, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &mus_out_any_to_file, &sample_to_file_file_name, &sample_to_file_end, 0, 0, 0, 0, 0, 0, 0, &no_reset, 0, &rdout_copy }; mus_any *mus_make_frample_to_file_with_comment(const char *filename, int chans, mus_sample_t samp_type, mus_header_t head_type, const char *comment) { rdout *gen = NULL; gen = (rdout *)mus_make_sample_to_file_with_comment(filename, chans, samp_type, head_type, comment); if (gen) gen->core = &FRAMPLE_TO_FILE_CLASS; return((mus_any *)gen); } bool mus_is_frample_to_file(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_FRAMPLE_TO_FILE)); } mus_float_t *mus_frample_to_file(mus_any *ptr, mus_long_t samp, mus_float_t *data) { rdout *gen = (rdout *)ptr; if (!gen) return(data); if (gen->chans == 1) mus_outa_to_file(ptr, samp, data[0]); else { if (gen->chans == 2) { mus_outa_to_file(ptr, samp, data[0]); mus_outb_to_file(ptr, samp, data[1]); } else mus_out_chans_to_file(gen, samp, gen->chans, data); } return(data); } mus_any *mus_continue_frample_to_file(const char *filename) { rdout *gen = NULL; gen = (rdout *)mus_continue_sample_to_file(filename); if (gen) gen->core = &FRAMPLE_TO_FILE_CLASS; return((mus_any *)gen); } mus_float_t *mus_frample_to_frample(mus_float_t *matrix, int mx_chans, mus_float_t *in_samps, int in_chans, mus_float_t *out_samps, int out_chans) { /* in->out conceptually, so left index is in_chan, it (j below) steps by out_chans */ int i, j, offset; if (mx_chans < out_chans) out_chans = mx_chans; if (mx_chans < in_chans) in_chans = mx_chans; for (i = 0; i < out_chans; i++) { out_samps[i] = in_samps[0] * matrix[i]; for (j = 1, offset = mx_chans; j < in_chans; j++, offset += mx_chans) out_samps[i] += in_samps[j] * matrix[offset + i]; } return(out_samps); } /* ---------------- locsig ---------------- */ typedef struct { mus_any_class *core; mus_any *outn_writer; mus_any *revn_writer; mus_float_t *outf, *revf; mus_float_t *outn; mus_float_t *revn; int chans, rev_chans; mus_interp_t type; mus_float_t reverb; bool safe_output; void *closure; void (*locsig_func)(mus_any *ptr, mus_long_t loc, mus_float_t val); void (*detour)(mus_any *ptr, mus_long_t loc); } locs; static bool locsig_equalp(mus_any *p1, mus_any *p2) { locs *g1 = (locs *)p1; locs *g2 = (locs *)p2; if (p1 == p2) return(true); return((g1) && (g2) && (g1->core->type == g2->core->type) && (g1->chans == g2->chans) && (clm_arrays_are_equal(g1->outn, g2->outn, g1->chans)) && (((bool)(g1->revn != NULL)) == ((bool)(g2->revn != NULL))) && ((!(g1->revn)) || (clm_arrays_are_equal(g1->revn, g2->revn, g1->rev_chans)))); } static char *describe_locsig(mus_any *ptr) { char *str; int i, lim = 16; locs *gen = (locs *)ptr; char *describe_buffer; describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE); snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s chans %d, outn: [", mus_name(ptr), gen->chans); str = (char *)malloc(STR_SIZE * sizeof(char)); if (gen->outn) { if (gen->chans - 1 < lim) lim = gen->chans - 1; for (i = 0; i < lim; i++) { snprintf(str, STR_SIZE, "%.3f ", gen->outn[i]); if ((strlen(describe_buffer) + strlen(str)) < (DESCRIBE_BUFFER_SIZE - 16)) strcat(describe_buffer, str); else break; } if (gen->chans - 1 > lim) strcat(describe_buffer, "..."); snprintf(str, STR_SIZE, "%.3f]", gen->outn[gen->chans - 1]); strcat(describe_buffer, str); } else { strcat(describe_buffer, "nil!]"); } if ((gen->rev_chans > 0) && (gen->revn)) { strcat(describe_buffer, ", revn: ["); lim = 16; if (gen->rev_chans - 1 < lim) lim = gen->rev_chans - 1; for (i = 0; i < lim; i++) { snprintf(str, STR_SIZE, "%.3f ", gen->revn[i]); if ((strlen(describe_buffer) + strlen(str)) < (DESCRIBE_BUFFER_SIZE - 16)) strcat(describe_buffer, str); else break; } if (gen->rev_chans - 1 > lim) strcat(describe_buffer, "..."); snprintf(str, STR_SIZE, "%.3f]", gen->revn[gen->rev_chans - 1]); strcat(describe_buffer, str); } snprintf(str, STR_SIZE, ", interp: %s", interp_type_to_string(gen->type)); strcat(describe_buffer, str); free(str); return(describe_buffer); } static void free_locsig(mus_any *p) { locs *ptr = (locs *)p; if (ptr->outn) { free(ptr->outn); ptr->outn = NULL; } if (ptr->revn) { free(ptr->revn); ptr->revn = NULL; } if (ptr->outf) free(ptr->outf); ptr->outf = NULL; if (ptr->revf) free(ptr->revf); ptr->revf = NULL; ptr->outn_writer = NULL; ptr->revn_writer = NULL; ptr->chans = 0; ptr->rev_chans = 0; free(ptr); } static mus_any *locs_copy(mus_any *ptr) { locs *g, *p; int bytes; p = (locs *)ptr; g = (locs *)malloc(sizeof(locs)); memcpy((void *)g, (void *)ptr, sizeof(locs)); bytes = g->chans * sizeof(mus_float_t); if (p->outn) { g->outn = (mus_float_t *)malloc(bytes); memcpy((void *)(g->outn), (void *)(p->outn), bytes); } if (p->outf) { g->outf = (mus_float_t *)malloc(bytes); memcpy((void *)(g->outf), (void *)(p->outf), bytes); } bytes = g->rev_chans * sizeof(mus_float_t); if (p->revn) { g->revn = (mus_float_t *)malloc(bytes); memcpy((void *)(g->revn), (void *)(p->revn), bytes); } if (p->revf) { g->revf = (mus_float_t *)malloc(bytes); memcpy((void *)(g->revf), (void *)(p->revf), bytes); } return((mus_any *)g); } static mus_long_t locsig_length(mus_any *ptr) {return(((locs *)ptr)->chans);} static int locsig_channels(mus_any *ptr) {return(((locs *)ptr)->chans);} static mus_float_t *locsig_data(mus_any *ptr) {return(((locs *)ptr)->outn);} static mus_float_t *locsig_xcoeffs(mus_any *ptr) {return(((locs *)ptr)->revn);} mus_float_t *mus_locsig_outf(mus_any *ptr) {return(((locs *)ptr)->outf);} /* clm2xen.c */ mus_float_t *mus_locsig_revf(mus_any *ptr) {return(((locs *)ptr)->revf);} void *mus_locsig_closure(mus_any *ptr) {return(((locs *)ptr)->closure);} static void *locsig_set_closure(mus_any *ptr, void *e) {((locs *)ptr)->closure = e; return(e);} void mus_locsig_set_detour(mus_any *ptr, void (*detour)(mus_any *ptr, mus_long_t val)) { locs *gen = (locs *)ptr; gen->detour = detour; } static void locsig_reset(mus_any *ptr) { locs *gen = (locs *)ptr; if (gen->outn) memset((void *)(gen->outn), 0, gen->chans * sizeof(mus_float_t)); if (gen->revn) memset((void *)(gen->revn), 0, gen->rev_chans * sizeof(mus_float_t)); } static mus_float_t locsig_xcoeff(mus_any *ptr, int index) { locs *gen = (locs *)ptr; if (gen->revn) return(gen->revn[index]); return(0.0); } static mus_float_t locsig_set_xcoeff(mus_any *ptr, int index, mus_float_t val) { locs *gen = (locs *)ptr; if (gen->revn) gen->revn[index] = val; return(val); } static mus_any *locsig_warned = NULL; /* these locsig error messages are a pain -- using the output pointer in the wan hope that * subsequent runs will use a different output generator. */ mus_float_t mus_locsig_ref(mus_any *ptr, int chan) { locs *gen = (locs *)ptr; if ((ptr) && (mus_is_locsig(ptr))) { if ((chan >= 0) && (chan < gen->chans)) return(gen->outn[chan]); else { if (locsig_warned != gen->outn_writer) { mus_error(MUS_NO_SUCH_CHANNEL, S_locsig_ref ": chan %d >= %d", chan, gen->chans); locsig_warned = gen->outn_writer; } } } return(0.0); } mus_float_t mus_locsig_set(mus_any *ptr, int chan, mus_float_t val) { locs *gen = (locs *)ptr; if ((ptr) && (mus_is_locsig(ptr))) { if ((chan >= 0) && (chan < gen->chans)) gen->outn[chan] = val; else { if (locsig_warned != gen->outn_writer) { mus_error(MUS_NO_SUCH_CHANNEL, S_locsig_set ": chan %d >= %d", chan, gen->chans); locsig_warned = gen->outn_writer; } } } return(val); } mus_float_t mus_locsig_reverb_ref(mus_any *ptr, int chan) { locs *gen = (locs *)ptr; if ((ptr) && (mus_is_locsig(ptr))) { if ((chan >= 0) && (chan < gen->rev_chans)) return(gen->revn[chan]); else { if (locsig_warned != gen->outn_writer) { mus_error(MUS_NO_SUCH_CHANNEL, S_locsig_reverb_ref ": chan %d, but this locsig has %d reverb chans", chan, gen->rev_chans); locsig_warned = gen->outn_writer; } } } return(0.0); } mus_float_t mus_locsig_reverb_set(mus_any *ptr, int chan, mus_float_t val) { locs *gen = (locs *)ptr; if ((ptr) && (mus_is_locsig(ptr))) { if ((chan >= 0) && (chan < gen->rev_chans)) gen->revn[chan] = val; else { if (locsig_warned != gen->outn_writer) { mus_error(MUS_NO_SUCH_CHANNEL, S_locsig_reverb_set ": chan %d >= %d", chan, gen->rev_chans); locsig_warned = gen->outn_writer; } } } return(val); } static mus_float_t run_locsig(mus_any *ptr, mus_float_t arg1, mus_float_t arg2) { mus_locsig(ptr, (mus_long_t)arg1, arg2); return(arg2); } static mus_any_class LOCSIG_CLASS = { MUS_LOCSIG, (char *)S_locsig, &free_locsig, &describe_locsig, &locsig_equalp, &locsig_data, 0, &locsig_length, 0, 0, 0, 0, 0, 0, 0, 0, 0, &run_locsig, MUS_OUTPUT, &mus_locsig_closure, &locsig_channels, 0, 0, 0, 0, &locsig_xcoeff, &locsig_set_xcoeff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &locsig_xcoeffs, 0, &locsig_reset, &locsig_set_closure, /* the method name is set_environ (clm2xen.c) */ &locs_copy }; bool mus_is_locsig(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_LOCSIG)); } static void mus_locsig_fill(mus_float_t *arr, int chans, mus_float_t degree, mus_float_t scaler, mus_interp_t type) { if (chans == 1) arr[0] = scaler; else { mus_float_t deg, pos, frac, degs_per_chan; int left, right; /* this used to check for degree < 0.0 first, but as Michael Klingbeil noticed, that * means that in the stereo case, the location can jump to 90 => click. */ if (chans == 2) { /* there's no notion of a circle of speakers here, so we don't have to equate, for example, -90 and 270 */ if (degree > 90.0) deg = 90.0; else { if (degree < 0.0) deg = 0.0; else deg = degree; } degs_per_chan = 90.0; } else { deg = fmod(degree, 360.0); if (deg < 0.0) { /* -0.0 is causing trouble when mus_float_t == float */ if (deg < -0.0000001) deg += 360.0; /* C's fmod can return negative results when modulus is positive */ else deg = 0.0; } degs_per_chan = 360.0 / chans; } pos = deg / degs_per_chan; left = (int)pos; /* floor(pos) */ right = left + 1; if (right >= chans) right = 0; frac = pos - left; if (type == MUS_INTERP_LINEAR) { arr[left] = scaler * (1.0 - frac); arr[right] = scaler * frac; } else { mus_float_t ldeg, c, s; ldeg = M_PI_2 * (0.5 - frac); scaler *= sqrt(2.0) / 2.0; c = cos(ldeg); s = sin(ldeg); arr[left] = scaler * (c + s); arr[right] = scaler * (c - s); } } } static void mus_locsig_mono_no_reverb(mus_any *ptr, mus_long_t loc, mus_float_t val) { locs *gen = (locs *)ptr; mus_outa_to_file(gen->outn_writer, loc, val * gen->outn[0]); } static void mus_locsig_mono(mus_any *ptr, mus_long_t loc, mus_float_t val) { locs *gen = (locs *)ptr; mus_outa_to_file(gen->outn_writer, loc, val * gen->outn[0]); mus_outa_to_file(gen->revn_writer, loc, val * gen->revn[0]); } static void mus_locsig_stereo_no_reverb(mus_any *ptr, mus_long_t loc, mus_float_t val) { locs *gen = (locs *)ptr; mus_outa_to_file(gen->outn_writer, loc, val * gen->outn[0]); mus_outb_to_file(gen->outn_writer, loc, val * gen->outn[1]); } static void mus_locsig_stereo(mus_any *ptr, mus_long_t loc, mus_float_t val) /* but mono rev */ { locs *gen = (locs *)ptr; mus_outa_to_file(gen->outn_writer, loc, val * gen->outn[0]); mus_outb_to_file(gen->outn_writer, loc, val * gen->outn[1]); mus_outa_to_file(gen->revn_writer, loc, val * gen->revn[0]); } static void mus_locsig_any(mus_any *ptr, mus_long_t loc, mus_float_t val) { int i; locs *gen = (locs *)ptr; rdout *writer = (rdout *)(gen->outn_writer); for (i = 0; i < gen->chans; i++) { gen->outf[i] = val * gen->outn[i]; if (writer) mus_out_any_to_file((mus_any *)writer, loc, i, gen->outf[i]); } writer = (rdout *)(gen->revn_writer); for (i = 0; i < gen->rev_chans; i++) { gen->revf[i] = val * gen->revn[i]; if (writer) mus_out_any_to_file((mus_any *)writer, loc, i, gen->revf[i]); } } static void mus_locsig_safe_mono_no_reverb(mus_any *ptr, mus_long_t loc, mus_float_t val) { /* here we know in each safe case that obufs fits loc chans and the output gen is ok */ locs *gen = (locs *)ptr; rdout *writer = (rdout *)(gen->outn_writer); if ((loc <= writer->data_end) && (loc >= writer->data_start)) { writer->obufs[0][loc - writer->data_start] += (val * gen->outn[0]); if (loc > writer->out_end) writer->out_end = loc; } else mus_outa_to_file((mus_any *)writer, loc, val * gen->outn[0]); } static void mus_locsig_safe_mono(mus_any *ptr, mus_long_t loc, mus_float_t val) { locs *gen = (locs *)ptr; rdout *writer = (rdout *)(gen->outn_writer); if ((loc <= writer->data_end) && (loc >= writer->data_start)) { writer->obufs[0][loc - writer->data_start] += (val * gen->outn[0]); if (loc > writer->out_end) writer->out_end = loc; } else mus_outa_to_file((mus_any *)writer, loc, val * gen->outn[0]); writer = (rdout *)(gen->revn_writer); if ((loc <= writer->data_end) && (loc >= writer->data_start)) { writer->obufs[0][loc - writer->data_start] += (val * gen->revn[0]); if (loc > writer->out_end) writer->out_end = loc; } else mus_outa_to_file((mus_any *)writer, loc, val * gen->revn[0]); } static void mus_locsig_safe_stereo_no_reverb(mus_any *ptr, mus_long_t loc, mus_float_t val) { locs *gen = (locs *)ptr; rdout *writer = (rdout *)(gen->outn_writer); if ((loc <= writer->data_end) && (loc >= writer->data_start)) { mus_long_t pos; pos = loc - writer->data_start; writer->obufs[0][pos] += (val * gen->outn[0]); writer->obufs[1][pos] += (val * gen->outn[1]); if (loc > writer->out_end) writer->out_end = loc; } else { mus_outa_to_file((mus_any *)writer, loc, val * gen->outn[0]); mus_outb_to_file((mus_any *)writer, loc, val * gen->outn[1]); } } static void mus_locsig_safe_stereo(mus_any *ptr, mus_long_t loc, mus_float_t val) { locs *gen = (locs *)ptr; rdout *writer = (rdout *)(gen->outn_writer); if ((loc <= writer->data_end) && (loc >= writer->data_start)) { mus_long_t pos; pos = loc - writer->data_start; writer->obufs[0][pos] += (val * gen->outn[0]); writer->obufs[1][pos] += (val * gen->outn[1]); if (loc > writer->out_end) writer->out_end = loc; } else { mus_outa_to_file((mus_any *)writer, loc, val * gen->outn[0]); mus_outb_to_file((mus_any *)writer, loc, val * gen->outn[1]); } writer = (rdout *)(gen->revn_writer); if ((loc <= writer->data_end) && (loc >= writer->data_start)) { writer->obufs[0][loc - writer->data_start] += (val * gen->revn[0]); if (loc > writer->out_end) writer->out_end = loc; } else mus_outa_to_file((mus_any *)writer, loc, val * gen->revn[0]); } static void mus_locsig_detour(mus_any *ptr, mus_long_t loc, mus_float_t val) { /* here we let the closure data decide what to do with the output */ locs *gen = (locs *)ptr; if (gen->detour) { int i; for (i = 0; i < gen->chans; i++) gen->outf[i] = val * gen->outn[i]; for (i = 0; i < gen->rev_chans; i++) gen->revf[i] = val * gen->revn[i]; (*(gen->detour))(ptr, loc); } } static void mus_locsig_any_no_reverb(mus_any *ptr, mus_long_t loc, mus_float_t val) { int i; locs *gen = (locs *)ptr; rdout *writer = (rdout *)(gen->outn_writer); for (i = 0; i < gen->chans; i++) { gen->outf[i] = val * gen->outn[i]; if (writer) mus_out_any_to_file((mus_any *)writer, loc, i, gen->outf[i]); } } static void mus_locsig_safe_any_no_reverb(mus_any *ptr, mus_long_t loc, mus_float_t val) { int i; locs *gen = (locs *)ptr; rdout *writer = (rdout *)(gen->outn_writer); if ((loc <= writer->data_end) && (loc >= writer->data_start)) { mus_long_t pos; pos = loc - writer->data_start; for (i = 0; i < gen->chans; i++) writer->obufs[i][pos] += (val * gen->outn[i]); if (loc > writer->out_end) writer->out_end = loc; } else { for (i = 0; i < gen->chans; i++) mus_safe_out_any_to_file(loc, val * gen->outn[i], i, (mus_any *)writer); } } static void mus_locsig_safe_any(mus_any *ptr, mus_long_t loc, mus_float_t val) { int i; locs *gen = (locs *)ptr; rdout *writer = (rdout *)(gen->outn_writer); if ((loc <= writer->data_end) && (loc >= writer->data_start)) { mus_long_t pos; pos = loc - writer->data_start; for (i = 0; i < gen->chans; i++) writer->obufs[i][pos] += (val * gen->outn[i]); if (loc > writer->out_end) writer->out_end = loc; } else { for (i = 0; i < gen->chans; i++) mus_safe_out_any_to_file(loc, val * gen->outn[i], i, (mus_any *)writer); } writer = (rdout *)(gen->revn_writer); if ((loc <= writer->data_end) && (loc >= writer->data_start)) { mus_long_t pos; pos = loc - writer->data_start; for (i = 0; i < gen->rev_chans; i++) writer->obufs[i][pos] += (val * gen->revn[i]); if (loc > writer->out_end) writer->out_end = loc; } else { for (i = 0; i < gen->rev_chans; i++) mus_safe_out_any_to_file(loc, val * gen->revn[i], i, (mus_any *)writer); } } mus_any *mus_make_locsig(mus_float_t degree, mus_float_t distance, mus_float_t reverb, int chans, mus_any *output, /* direct signal output */ int rev_chans, mus_any *revput, /* reverb output */ mus_interp_t type) { locs *gen; mus_float_t dist; if (chans <= 0) { mus_error(MUS_ARG_OUT_OF_RANGE, S_make_locsig ": chans: %d", chans); return(NULL); } if (isnan(degree)) { mus_error(MUS_ARG_OUT_OF_RANGE, S_make_locsig ": degree: %f", degree); return(NULL); } gen = (locs *)calloc(1, sizeof(locs)); gen->core = &LOCSIG_CLASS; gen->outf = (mus_float_t *)calloc(chans, sizeof(mus_float_t)); gen->type = type; gen->reverb = reverb; gen->safe_output = false; if (distance > 1.0) dist = 1.0 / distance; else dist = 1.0; if (mus_is_output(output)) gen->outn_writer = output; gen->chans = chans; gen->outn = (mus_float_t *)calloc(gen->chans, sizeof(mus_float_t)); mus_locsig_fill(gen->outn, gen->chans, degree, dist, type); if (mus_is_output(revput)) gen->revn_writer = revput; gen->rev_chans = rev_chans; if (gen->rev_chans > 0) { gen->revn = (mus_float_t *)calloc(gen->rev_chans, sizeof(mus_float_t)); gen->revf = (mus_float_t *)calloc(gen->rev_chans, sizeof(mus_float_t)); mus_locsig_fill(gen->revn, gen->rev_chans, degree, (reverb * sqrt(dist)), type); } /* now choose the output function based on chans, and reverb */ if ((output == NULL) && (revput == NULL)) gen->locsig_func = mus_locsig_detour; else { gen->locsig_func = mus_locsig_any; if ((mus_is_output(output)) && (mus_out_any_is_safe(output)) && (mus_channels(output) == chans)) { if (rev_chans > 0) { if ((rev_chans == 1) && (mus_is_output(revput)) && (mus_out_any_is_safe(revput)) && (mus_channels(revput) == 1)) { gen->safe_output = true; switch (chans) { case 1: gen->locsig_func = mus_locsig_safe_mono; break; case 2: gen->locsig_func = mus_locsig_safe_stereo; break; default: gen->locsig_func = mus_locsig_safe_any; break; } } } else { gen->safe_output = true; switch (chans) { case 1: gen->locsig_func = mus_locsig_safe_mono_no_reverb; break; case 2: gen->locsig_func = mus_locsig_safe_stereo_no_reverb; break; default: gen->locsig_func = mus_locsig_safe_any_no_reverb; break; } } } else { if (rev_chans > 0) { if (rev_chans == 1) { switch (chans) { case 1: gen->locsig_func = mus_locsig_mono; break; case 2: gen->locsig_func = mus_locsig_stereo; break; default: gen->locsig_func = mus_locsig_any; break; } } } else { switch (chans) { case 1: gen->locsig_func = mus_locsig_mono_no_reverb; break; case 2: gen->locsig_func = mus_locsig_stereo_no_reverb; break; default: gen->locsig_func = mus_locsig_any_no_reverb; break; } } } } return((mus_any *)gen); } void mus_locsig(mus_any *ptr, mus_long_t loc, mus_float_t val) { locs *gen = (locs *)ptr; (*(gen->locsig_func))(ptr, loc, val); } int mus_locsig_channels(mus_any *ptr) { return(((locs *)ptr)->chans); } int mus_locsig_reverb_channels(mus_any *ptr) { return(((locs *)ptr)->rev_chans); } void mus_move_locsig(mus_any *ptr, mus_float_t degree, mus_float_t distance) { locs *gen = (locs *)ptr; mus_float_t dist; if (distance > 1.0) dist = 1.0 / distance; else dist = 1.0; if (gen->rev_chans > 0) { if (gen->rev_chans > 2) memset((void *)(gen->revn), 0, gen->rev_chans * sizeof(mus_float_t)); mus_locsig_fill(gen->revn, gen->rev_chans, degree, (gen->reverb * sqrt(dist)), gen->type); } if (gen->chans > 2) memset((void *)(gen->outn), 0, gen->chans * sizeof(mus_float_t)); mus_locsig_fill(gen->outn, gen->chans, degree, dist, gen->type); } /* ---------------- move-sound ---------------- */ typedef struct { mus_any_class *core; mus_any *outn_writer; mus_any *revn_writer; mus_float_t *outf, *revf; int out_channels, rev_channels; mus_long_t start, end; mus_any *doppler_delay, *doppler_env, *rev_env; mus_any **out_delays, **out_envs, **rev_envs; int *out_map; bool free_arrays, free_gens; void *closure; void (*detour)(mus_any *ptr, mus_long_t loc); } dloc; static bool move_sound_equalp(mus_any *p1, mus_any *p2) {return(p1 == p2);} int mus_move_sound_channels(mus_any *ptr) {return(((dloc *)ptr)->out_channels);} int mus_move_sound_reverb_channels(mus_any *ptr) {return(((dloc *)ptr)->rev_channels);} static mus_long_t move_sound_length(mus_any *ptr) {return(((dloc *)ptr)->out_channels);} /* need both because return types differ */ static void move_sound_reset(mus_any *ptr) {} mus_float_t *mus_move_sound_outf(mus_any *ptr) {return(((dloc *)ptr)->outf);} mus_float_t *mus_move_sound_revf(mus_any *ptr) {return(((dloc *)ptr)->revf);} void *mus_move_sound_closure(mus_any *ptr) {return(((dloc *)ptr)->closure);} static void *move_sound_set_closure(mus_any *ptr, void *e) {((dloc *)ptr)->closure = e; return(e);} void mus_move_sound_set_detour(mus_any *ptr, void (*detour)(mus_any *ptr, mus_long_t val)) { dloc *gen = (dloc *)ptr; gen->detour = detour; } static char *describe_move_sound(mus_any *ptr) { dloc *gen = (dloc *)ptr; char *dopdly = NULL, *dopenv = NULL, *revenv = NULL; char *outdlys = NULL, *outenvs = NULL, *revenvs = NULL; char *outmap = NULL; char *starts = NULL; char *str1 = NULL, *str2 = NULL, *str3 = NULL; char *allstr = NULL; int len; starts = mus_format("%s start: %lld, end: %lld, out chans %d, rev chans: %d", mus_name(ptr), gen->start, gen->end, gen->out_channels, gen->rev_channels); dopdly = mus_format("doppler %s", str1 = mus_describe(gen->doppler_delay)); dopenv = mus_format("doppler %s", str2 = mus_describe(gen->doppler_env)); revenv = mus_format("global reverb %s", str3 = mus_describe(gen->rev_env)); outdlys = clm_array_to_string(gen->out_delays, gen->out_channels, "out_delays", " "); outenvs = clm_array_to_string(gen->out_envs, gen->out_channels, "out_envs", " "); revenvs = clm_array_to_string(gen->rev_envs, gen->rev_channels, "rev_envs", " "); outmap = int_array_to_string(gen->out_map, gen->out_channels, "out_map"); len = 64 + strlen(starts) + strlen(dopdly) + strlen(dopenv) + strlen(revenv) + strlen(outdlys) + strlen(outenvs) + strlen(revenvs) + strlen(outmap); allstr = (char *)malloc(len * sizeof(char)); snprintf(allstr, len, "%s\n %s\n %s\n %s\n %s\n %s\n %s\n %s\n free: arrays: %s, gens: %s\n", starts, dopdly, dopenv, revenv, outdlys, outenvs, revenvs, outmap, (gen->free_arrays) ? "true" : "false", (gen->free_gens) ? "true" : "false"); if (str1) free(str1); if (str2) free(str2); if (str3) free(str3); free(starts); free(dopdly); free(dopenv); free(revenv); free(outdlys); free(outenvs); free(revenvs); free(outmap); return(allstr); } static void free_move_sound(mus_any *p) { dloc *ptr = (dloc *)p; if (ptr->free_gens) { int i; /* free everything except outer arrays and IO stuff */ if (ptr->doppler_delay) mus_free(ptr->doppler_delay); if (ptr->doppler_env) mus_free(ptr->doppler_env); if (ptr->rev_env) mus_free(ptr->rev_env); if (ptr->out_delays) for (i = 0; i < ptr->out_channels; i++) if (ptr->out_delays[i]) mus_free(ptr->out_delays[i]); if (ptr->out_envs) for (i = 0; i < ptr->out_channels; i++) if (ptr->out_envs[i]) mus_free(ptr->out_envs[i]); if (ptr->rev_envs) for (i = 0; i < ptr->rev_channels; i++) if (ptr->rev_envs[i]) mus_free(ptr->rev_envs[i]); } if (ptr->free_arrays) { /* free outer arrays */ if (ptr->out_envs) {free(ptr->out_envs); ptr->out_envs = NULL;} if (ptr->rev_envs) {free(ptr->rev_envs); ptr->rev_envs = NULL;} if (ptr->out_delays) {free(ptr->out_delays); ptr->out_delays = NULL;} if (ptr->out_map) free(ptr->out_map); } /* we created these in make_move_sound, so it should always be safe to free them */ if (ptr->outf) free(ptr->outf); if (ptr->revf) free(ptr->revf); free(ptr); } static mus_any *dloc_copy(mus_any *ptr) { dloc *g, *p; int i, bytes; p = (dloc *)ptr; g = (dloc *)malloc(sizeof(dloc)); memcpy((void *)g, (void *)ptr, sizeof(dloc)); if (p->outf) { bytes = p->out_channels * sizeof(mus_float_t); g->outf = (mus_float_t *)malloc(bytes); memcpy((void *)(g->outf), (void *)(p->outf), bytes); } if (p->revf) { bytes = p->rev_channels * sizeof(mus_float_t); g->revf = (mus_float_t *)malloc(bytes); memcpy((void *)(g->revf), (void *)(p->revf), bytes); } g->free_arrays = true; g->free_gens = true; if (p->doppler_delay) g->doppler_delay = mus_copy(p->doppler_delay); if (p->doppler_env) g->doppler_env = mus_copy(p->doppler_env); if (p->rev_env) g->rev_env = mus_copy(p->rev_env); if (p->out_envs) { g->out_envs = (mus_any **)malloc(p->out_channels * sizeof(mus_any *)); for (i = 0; i < p->out_channels; i++) g->out_envs[i] = mus_copy(p->out_envs[i]); } if (p->rev_envs) { g->rev_envs = (mus_any **)malloc(p->rev_channels * sizeof(mus_any *)); for (i = 0; i < p->rev_channels; i++) g->rev_envs[i] = mus_copy(p->rev_envs[i]); } if (p->out_delays) { g->out_delays = (mus_any **)malloc(p->out_channels * sizeof(mus_any *)); for (i = 0; i < p->out_channels; i++) g->out_delays[i] = mus_copy(p->out_delays[i]); } if (p->out_map) { bytes = p->out_channels * sizeof(int); g->out_map = (int *)malloc(bytes); memcpy((void *)(g->out_map), (void *)(p->out_map), bytes); } return((mus_any *)g); } bool mus_is_move_sound(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_MOVE_SOUND)); } mus_float_t mus_move_sound(mus_any *ptr, mus_long_t loc, mus_float_t uval) { dloc *gen = (dloc *)ptr; mus_float_t val; int chan; if (loc > gen->end) val = 0.0; else val = uval; /* initial silence */ if (loc < gen->start) { mus_delay_unmodulated(gen->doppler_delay, val); /* original calls out_any here with 0.0 -- a no-op */ return(val); } /* doppler */ if (gen->doppler_delay) val = mus_delay(gen->doppler_delay, val, mus_env(gen->doppler_env)); /* direct signal */ for (chan = 0; chan < gen->out_channels; chan++) { mus_float_t sample; sample = val * mus_env(gen->out_envs[chan]); if (gen->out_delays[chan]) sample = mus_delay_unmodulated(gen->out_delays[chan], sample); gen->outf[gen->out_map[chan]] = sample; } /* reverb */ if ((gen->rev_env) && (gen->revf)) { val *= mus_env(gen->rev_env); if (gen->rev_envs) { if (gen->rev_channels == 1) gen->revf[0] = val * mus_env(gen->rev_envs[0]); else { for (chan = 0; chan < gen->rev_channels; chan++) gen->revf[gen->out_map[chan]] = val * mus_env(gen->rev_envs[chan]); } } else gen->revf[0] = val; if (gen->revn_writer) mus_frample_to_file(gen->revn_writer, loc, gen->revf); } /* file output */ if (gen->outn_writer) mus_frample_to_file(gen->outn_writer, loc, gen->outf); if (gen->detour) (*(gen->detour))(ptr, loc); return(uval); } static mus_float_t run_move_sound(mus_any *ptr, mus_float_t arg1, mus_float_t arg2) { mus_move_sound(ptr, (mus_long_t)arg1, arg2); return(arg2); } static mus_any_class MOVE_SOUND_CLASS = { MUS_MOVE_SOUND, (char *)S_move_sound, &free_move_sound, &describe_move_sound, &move_sound_equalp, 0, 0, &move_sound_length, 0, 0, 0, 0, 0, 0, 0, 0, 0, &run_move_sound, MUS_OUTPUT, &mus_move_sound_closure, &mus_move_sound_channels, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &move_sound_reset, &move_sound_set_closure, &dloc_copy }; mus_any *mus_make_move_sound(mus_long_t start, mus_long_t end, int out_channels, int rev_channels, mus_any *doppler_delay, mus_any *doppler_env, mus_any *rev_env, mus_any **out_delays, mus_any **out_envs, mus_any **rev_envs, int *out_map, mus_any *output, mus_any *revput, bool free_arrays, bool free_gens) { /* most of these args come to us in a list at the lisp/xen level ("dlocs" struct is actually a list) * so the make-move-sound function in lisp/xen is (make-move-sound dloc-list output revout) * where the trailing args mimic locsig. */ dloc *gen; if (out_channels <= 0) { mus_error(MUS_ARG_OUT_OF_RANGE, S_make_move_sound ": out chans: %d", out_channels); return(NULL); } gen = (dloc *)calloc(1, sizeof(dloc)); gen->core = &MOVE_SOUND_CLASS; gen->start = start; gen->end = end; gen->out_channels = out_channels; gen->rev_channels = rev_channels; gen->doppler_delay = doppler_delay; gen->doppler_env = doppler_env; gen->rev_env = rev_env; gen->out_delays = out_delays; gen->out_envs = out_envs; gen->rev_envs = rev_envs; gen->out_map = out_map; /* default is to free only what we make ourselves */ gen->free_gens = free_gens; gen->free_arrays = free_arrays; gen->outf = (mus_float_t *)calloc(out_channels, sizeof(mus_float_t)); if (mus_is_output(output)) gen->outn_writer = output; if (rev_channels > 0) { if (mus_is_output(revput)) gen->revn_writer = revput; gen->revf = (mus_float_t *)calloc(rev_channels, sizeof(mus_float_t)); } return((mus_any *)gen); } /* ---------------- src ---------------- */ /* sampling rate conversion */ /* taken from sweep_srate.c of Perry Cook. To quote Perry: * * 'The conversion is performed by sinc interpolation. * J. O. Smith and P. Gossett, "A Flexible Sampling-Rate Conversion Method," * Proc. of the IEEE Conference on Acoustics, Speech, and Signal Processing, San Diego, CA, March, 1984. * There are essentially two cases, one where the conversion factor * is less than one, and the sinc table is used as is yielding a sound * which is band limited to the 1/2 the new sampling rate (we don't * want to create bandwidth where there was none). The other case * is where the conversion factor is greater than one and we 'warp' * the sinc table to make the final cutoff equal to the original sampling * rate /2. Warping the sinc table is based on the similarity theorem * of the time and frequency domain, stretching the time domain (sinc * table) causes shrinking in the frequency domain.' * * we also scale the amplitude if interpolating to take into account the broadened sinc * this means that isolated pulses get scaled by 1/src, but that's a dumb special case */ typedef struct { mus_any_class *core; mus_float_t (*feeder)(void *arg, int direction); mus_float_t (*block_feeder)(void *arg, int direction, mus_float_t *block, mus_long_t start, mus_long_t end); mus_float_t x; mus_float_t incr, width_1; int width, lim, start, sinc4; int len; mus_float_t *data, *sinc_table, *coeffs; void *closure; } sr; #define SRC_SINC_DENSITY 2000 #define SRC_SINC_WIDTH 10 #define SRC_SINC_WINDOW_SIZE 8000 static mus_float_t **sinc_tables = NULL; static int *sinc_widths = NULL; static int sincs = 0; static mus_float_t *sinc = NULL, *sinc_window = NULL; static int sinc_size = 0; void mus_clear_sinc_tables(void) { if (sincs) { int i; for (i = 0; i < sincs; i++) if (sinc_tables[i]) free(sinc_tables[i]); free(sinc_tables); sinc_tables = NULL; free(sinc_window); sinc_window = NULL; free(sinc_widths); sinc_widths = NULL; sincs = 0; } } static int init_sinc_table(int width) { int i, size, padded_size, loc; mus_float_t win_freq, win_phase; #if HAVE_SINCOS double sn, snp, cs, csp; #endif if (width > sinc_size) { int old_end; mus_float_t sinc_phase, sinc_freq; if (sinc_size == 0) old_end = 1; else old_end = sinc_size * SRC_SINC_DENSITY + 4; padded_size = width * SRC_SINC_DENSITY + 4; if (sinc_size == 0) { sinc = (mus_float_t *)malloc(padded_size * sizeof(mus_float_t)); sinc[0] = 1.0; } else sinc = (mus_float_t *)realloc(sinc, padded_size * sizeof(mus_float_t)); sinc_size = width; sinc_freq = M_PI / (mus_float_t)SRC_SINC_DENSITY; sinc_phase = old_end * sinc_freq; #if HAVE_SINCOS sincos(sinc_freq, &sn, &cs); if (old_end == 1) { sinc[1] = sin(sinc_phase) / (2.0 * sinc_phase); old_end++; sinc_phase += sinc_freq; } for (i = old_end; i < padded_size;) { sincos(sinc_phase, &snp, &csp); sinc[i] = snp / (2.0 * sinc_phase); i++; sinc_phase += sinc_freq; sinc[i] = (snp * cs + csp * sn) / (2.0 * sinc_phase); i++; sinc_phase += sinc_freq; } #else for (i = old_end; i < padded_size; i++, sinc_phase += sinc_freq) sinc[i] = sin(sinc_phase) / (2.0 * sinc_phase); #endif } for (i = 0; i < sincs; i++) if (sinc_widths[i] == width) return(i); if (sincs == 0) { mus_float_t ph, incr; incr = M_PI / SRC_SINC_WINDOW_SIZE; sinc_window = (mus_float_t *)calloc(SRC_SINC_WINDOW_SIZE + 16, sizeof(mus_float_t)); for (i = 0, ph = 0.0; i < SRC_SINC_WINDOW_SIZE; i++, ph += incr) sinc_window[i] = 1.0 + cos(ph); sinc_tables = (mus_float_t **)calloc(8, sizeof(mus_float_t *)); sinc_widths = (int *)calloc(8, sizeof(int)); sincs = 8; loc = 0; } else { loc = -1; for (i = 0; i < sincs; i++) if (sinc_widths[i] == 0) { loc = i; break; } if (loc == -1) { sinc_tables = (mus_float_t **)realloc(sinc_tables, (sincs + 8) * sizeof(mus_float_t *)); sinc_widths = (int *)realloc(sinc_widths, (sincs + 8) * sizeof(int)); for (i = sincs; i < (sincs + 8); i++) { sinc_widths[i] = 0; sinc_tables[i] = NULL; } loc = sincs; sincs += 8; } } sinc_widths[loc] = width; size = width * SRC_SINC_DENSITY; padded_size = size + 4; win_freq = (mus_float_t)SRC_SINC_WINDOW_SIZE / (mus_float_t)size; sinc_tables[loc] = (mus_float_t *)malloc(padded_size * 2 * sizeof(mus_float_t)); sinc_tables[loc][padded_size] = 1.0; for (i = 1, win_phase = win_freq; i < padded_size; i++, win_phase += win_freq) { mus_float_t val; val = sinc[i] * sinc_window[(int)win_phase]; sinc_tables[loc][padded_size + i] = val; sinc_tables[loc][padded_size - i] = val; } return(loc); } bool mus_is_src(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_SRC)); } static void free_src_gen(mus_any *srptr) { sr *srp = (sr *)srptr; if (srp->data) free(srp->data); if (srp->coeffs) free(srp->coeffs); free(srp); } static mus_any *sr_copy(mus_any *ptr) { sr *g, *p; int bytes; p = (sr *)ptr; g = (sr *)malloc(sizeof(sr)); memcpy((void *)g, (void *)ptr, sizeof(sr)); bytes = (2 * g->lim + 1) * sizeof(mus_float_t); g->data = (mus_float_t *)malloc(bytes); memcpy((void *)(g->data), (void *)(p->data), bytes); if (p->coeffs) { bytes = p->lim * sizeof(mus_float_t); g->coeffs = (mus_float_t *)malloc(bytes); memcpy((void *)(g->coeffs), (void *)(p->coeffs), bytes); } return((mus_any *)g); } static bool src_equalp(mus_any *p1, mus_any *p2) {return(p1 == p2);} static char *describe_src(mus_any *ptr) { sr *gen = (sr *)ptr; char *describe_buffer; describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE); snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s width: %d, x: %.3f, incr: %.3f, sinc table len: %d", mus_name(ptr), gen->width, gen->x, gen->incr, gen->len); return(describe_buffer); } static mus_long_t src_length(mus_any *ptr) {return(((sr *)ptr)->width);} static mus_float_t run_src_gen(mus_any *srptr, mus_float_t sr_change, mus_float_t unused) {return(mus_src(srptr, sr_change, NULL));} static void *src_closure(mus_any *rd) {return(((sr *)rd)->closure);} static void *src_set_closure(mus_any *rd, void *e) {((sr *)rd)->closure = e; return(e);} static mus_float_t src_increment(mus_any *rd) {return(((sr *)rd)->incr);} static mus_float_t src_set_increment(mus_any *rd, mus_float_t val) {((sr *)rd)->incr = val; return(val);} static mus_float_t *src_sinc_table(mus_any *rd) {return(((sr *)rd)->sinc_table);} static void src_reset(mus_any *ptr) { sr *gen = (sr *)ptr; memset((void *)(gen->data), 0, (gen->lim + 1) * sizeof(mus_float_t)); gen->x = 0.0; /* center the data if possible */ if (gen->feeder) { int i, dir = 1; if (gen->incr < 0.0) dir = -1; for (i = gen->width - 1; i < gen->lim; i++) gen->data[i] = gen->feeder(gen->closure, dir); } gen->start = 0; } void mus_src_init(mus_any *ptr) { sr *srp = (sr *)ptr; if (srp->feeder) { int i, dir = 1; if (srp->incr < 0.0) dir = -1; for (i = srp->width - 1; i < srp->lim; i++) { srp->data[i] = srp->feeder(srp->closure, dir); srp->data[i + srp->lim] = srp->data[i]; } } } static mus_any_class SRC_CLASS = { MUS_SRC, (char *)S_src, &free_src_gen, &describe_src, &src_equalp, &src_sinc_table, 0, &src_length, /* sinc width actually */ 0, 0, 0, 0, 0, &fallback_scaler, 0, &src_increment, &src_set_increment, &run_src_gen, MUS_NOT_SPECIAL, &src_closure, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &src_reset, &src_set_closure, &sr_copy }; mus_any *mus_make_src_with_init(mus_float_t (*input)(void *arg, int direction), mus_float_t srate, int width, void *closure, void (*init)(void *p, mus_any *g)) { /* besides 1, 2, .5, other common cases: 1.5, 3 */ if (fabs(srate) > MUS_MAX_CLM_SRC) mus_error(MUS_ARG_OUT_OF_RANGE, S_make_src ": srate arg invalid: %f", srate); else { if ((width < 0) || (width > MUS_MAX_CLM_SINC_WIDTH)) mus_error(MUS_ARG_OUT_OF_RANGE, S_make_src ": width arg invalid: %d", width); else { sr *srp; int wid, loc; if (width <= 0) width = SRC_SINC_WIDTH; if (width < (int)(fabs(srate) * 2)) wid = (int)(ceil(fabs(srate)) * 2); else wid = width; if ((srate == 2.0) && ((wid & 1) != 0)) wid++; srp = (sr *)calloc(1, sizeof(sr)); srp->core = &SRC_CLASS; srp->x = 0.0; srp->feeder = input; srp->block_feeder = NULL; srp->closure = closure; srp->incr = srate; srp->width = wid; srp->lim = 2 * wid; srp->start = 0; srp->len = wid * SRC_SINC_DENSITY; srp->width_1 = 1.0 - wid; srp->sinc4 = srp->width * SRC_SINC_DENSITY + 4; srp->data = (mus_float_t *)calloc(2 * srp->lim + 1, sizeof(mus_float_t)); loc = init_sinc_table(wid); srp->sinc_table = sinc_tables[loc]; srp->coeffs = NULL; if (init) init(closure, (mus_any *)srp); if (srp->feeder) { int i, dir = 1; if (srate < 0.0) dir = -1; for (i = wid - 1; i < srp->lim; i++) { srp->data[i] = srp->feeder(closure, dir); srp->data[i + srp->lim] = srp->data[i]; } /* was i = 0 here but we want the incoming data centered */ } return((mus_any *)srp); } } return(NULL); } mus_any *mus_make_src(mus_float_t (*input)(void *arg, int direction), mus_float_t srate, int width, void *closure) { return(mus_make_src_with_init(input, srate, width, closure, NULL)); } mus_float_t mus_src(mus_any *srptr, mus_float_t sr_change, mus_float_t (*input)(void *arg, int direction)) { sr *srp = (sr *)srptr; mus_float_t sum, zf, srx, factor; int lim, loc, xi; bool int_ok; mus_float_t *data, *sinc_table; lim = srp->lim; loc = srp->start; data = srp->data; sinc_table = srp->sinc_table; if (sr_change > MUS_MAX_CLM_SRC) sr_change = MUS_MAX_CLM_SRC; else { if (sr_change < -MUS_MAX_CLM_SRC) sr_change = -MUS_MAX_CLM_SRC; } srx = srp->incr + sr_change; if (srp->x >= 1.0) { int i, fsx, dir = 1; if (srx < 0.0) dir = -1; fsx = (int)(srp->x); srp->x -= fsx; if (input) {srp->feeder = input; srp->block_feeder = NULL;} data[loc] = srp->feeder(srp->closure, dir); data[loc + lim] = data[loc]; loc++; if (loc == lim) loc = 0; for (i = 1; i < fsx; i++) { /* there are two copies of the circular data buffer back-to-back so that we can * run the convolution below without worrying about the buffer end. */ data[loc] = srp->feeder(srp->closure, dir); data[loc + lim] = data[loc]; loc++; if (loc == lim) loc = 0; } srp->start = loc; /* next time around we start here */ } /* now loc = beginning of data */ /* if (srx == 0.0) srx = 0.01; */ /* can't decide about this ... */ if (srx < 0.0) srx = -srx; if (srx > 1.0) { factor = 1.0 / srx; /* this is not exact since we're sampling the sinc and so on, but it's close over a wide range */ zf = factor * (mus_float_t)SRC_SINC_DENSITY; xi = (int)(zf + 0.5); /* (let ((e (make-env '(0 1 1 1.1) :length 11))) (src-channel e)) */ /* we're comparing adding xi lim times to zf and if there's no difference, using the int case */ if (fabs((xi - zf) * lim) > 2.0) int_ok = false; else int_ok = true; } else { factor = 1.0; zf = (mus_float_t)SRC_SINC_DENSITY; xi = SRC_SINC_DENSITY; int_ok = true; } sum = 0.0; if (int_ok) { int sinc_loc, sinc_incr, last, last10, xs; xs = (int)(zf * (srp->width_1 - srp->x)); sinc_loc = xs + srp->sinc4; sinc_incr = xi; last = loc + lim; last10 = last - 10; while (loc <= last10) { sum += data[loc++] * sinc_table[sinc_loc]; sinc_loc += sinc_incr; sum += data[loc++] * sinc_table[sinc_loc]; sinc_loc += sinc_incr; sum += data[loc++] * sinc_table[sinc_loc]; sinc_loc += sinc_incr; sum += data[loc++] * sinc_table[sinc_loc]; sinc_loc += sinc_incr; sum += data[loc++] * sinc_table[sinc_loc]; sinc_loc += sinc_incr; sum += data[loc++] * sinc_table[sinc_loc]; sinc_loc += sinc_incr; sum += data[loc++] * sinc_table[sinc_loc]; sinc_loc += sinc_incr; sum += data[loc++] * sinc_table[sinc_loc]; sinc_loc += sinc_incr; sum += data[loc++] * sinc_table[sinc_loc]; sinc_loc += sinc_incr; sum += data[loc++] * sinc_table[sinc_loc]; sinc_loc += sinc_incr; } for (; loc < last; loc++, sinc_loc += sinc_incr) sum += data[loc] * sinc_table[sinc_loc]; } else { mus_float_t sinc_loc, sinc_incr, x; int last, last10; x = zf * (srp->width_1 - srp->x); sinc_loc = x + srp->sinc4; sinc_incr = zf; last = loc + lim; last10 = last - 10; while (loc <= last10) { sum += data[loc++] * sinc_table[(int)sinc_loc]; sinc_loc += sinc_incr; sum += data[loc++] * sinc_table[(int)sinc_loc]; sinc_loc += sinc_incr; sum += data[loc++] * sinc_table[(int)sinc_loc]; sinc_loc += sinc_incr; sum += data[loc++] * sinc_table[(int)sinc_loc]; sinc_loc += sinc_incr; sum += data[loc++] * sinc_table[(int)sinc_loc]; sinc_loc += sinc_incr; sum += data[loc++] * sinc_table[(int)sinc_loc]; sinc_loc += sinc_incr; sum += data[loc++] * sinc_table[(int)sinc_loc]; sinc_loc += sinc_incr; sum += data[loc++] * sinc_table[(int)sinc_loc]; sinc_loc += sinc_incr; sum += data[loc++] * sinc_table[(int)sinc_loc]; sinc_loc += sinc_incr; sum += data[loc++] * sinc_table[(int)sinc_loc]; sinc_loc += sinc_incr; } for (; loc < last; loc++, sinc_loc += sinc_incr) sum += data[loc] * sinc_table[(int)sinc_loc]; } srp->x += srx; return(sum * factor); } void mus_src_to_buffer(mus_any *srptr, mus_float_t (*input)(void *arg, int direction), mus_float_t *out_data, mus_long_t dur) { /* sr_change = 0.0 */ sr *srp = (sr *)srptr; mus_float_t sum, x, zf, srx, factor, sincx, srpx; int lim, i, xi, xs, dir = 1; bool int_ok; mus_long_t k; mus_float_t *data, *sinc_table; lim = srp->lim; sincx = (mus_float_t)SRC_SINC_DENSITY; data = srp->data; sinc_table = srp->sinc_table; srx = srp->incr; srpx = srp->x; if (srx < 0.0) { dir = -1; srx = -srx; } if (srx > 1.0) { factor = 1.0 / srx; /* this is not exact since we're sampling the sinc and so on, but it's close over a wide range */ zf = factor * sincx; xi = (int)zf; if (fabs((xi - zf) * lim) > 2.0) int_ok = false; else int_ok = true; } else { factor = 1.0; zf = sincx; xi = SRC_SINC_DENSITY; int_ok = true; } for (k = 0; k < dur; k++) { int loc; loc = srp->start; if (srpx >= 1.0) { int fsx; /* modf here is very slow??! */ fsx = (int)srpx; srpx -= fsx; data[loc] = input(srp->closure, dir); data[loc + lim] = data[loc]; loc++; if (loc == lim) loc = 0; for (i = 1; i < fsx; i++) { /* there are two copies of the circular data buffer back-to-back so that we can * run the convolution below without worrying about the buffer end. */ data[loc] = input(srp->closure, dir); data[loc + lim] = data[loc]; loc++; if (loc == lim) loc = 0; } srp->start = loc; /* next time around we start here */ } sum = 0.0; if (int_ok) { int sinc_loc, sinc_incr, last, last10; xs = (int)(zf * (srp->width_1 - srpx)); sinc_loc = xs + srp->sinc4; sinc_incr = xi; last = loc + lim; last10 = last - 10; while (loc <= last10) { sum += data[loc++] * sinc_table[sinc_loc]; sinc_loc += sinc_incr; sum += data[loc++] * sinc_table[sinc_loc]; sinc_loc += sinc_incr; sum += data[loc++] * sinc_table[sinc_loc]; sinc_loc += sinc_incr; sum += data[loc++] * sinc_table[sinc_loc]; sinc_loc += sinc_incr; sum += data[loc++] * sinc_table[sinc_loc]; sinc_loc += sinc_incr; sum += data[loc++] * sinc_table[sinc_loc]; sinc_loc += sinc_incr; sum += data[loc++] * sinc_table[sinc_loc]; sinc_loc += sinc_incr; sum += data[loc++] * sinc_table[sinc_loc]; sinc_loc += sinc_incr; sum += data[loc++] * sinc_table[sinc_loc]; sinc_loc += sinc_incr; sum += data[loc++] * sinc_table[sinc_loc]; sinc_loc += sinc_incr; } for (; loc < last; loc++, sinc_loc += sinc_incr) sum += data[loc] * sinc_table[sinc_loc]; } else { mus_float_t sinc_loc, sinc_incr; int last, last10; x = zf * (srp->width_1 - srpx); sinc_loc = x + srp->sinc4; sinc_incr = zf; last = loc + lim; last10 = last - 10; while (loc <= last10) { sum += data[loc++] * sinc_table[(int)sinc_loc]; sinc_loc += sinc_incr; sum += data[loc++] * sinc_table[(int)sinc_loc]; sinc_loc += sinc_incr; sum += data[loc++] * sinc_table[(int)sinc_loc]; sinc_loc += sinc_incr; sum += data[loc++] * sinc_table[(int)sinc_loc]; sinc_loc += sinc_incr; sum += data[loc++] * sinc_table[(int)sinc_loc]; sinc_loc += sinc_incr; sum += data[loc++] * sinc_table[(int)sinc_loc]; sinc_loc += sinc_incr; sum += data[loc++] * sinc_table[(int)sinc_loc]; sinc_loc += sinc_incr; sum += data[loc++] * sinc_table[(int)sinc_loc]; sinc_loc += sinc_incr; sum += data[loc++] * sinc_table[(int)sinc_loc]; sinc_loc += sinc_incr; sum += data[loc++] * sinc_table[(int)sinc_loc]; sinc_loc += sinc_incr; } for (; loc < last; loc++, sinc_loc += sinc_incr) sum += data[loc] * sinc_table[(int)sinc_loc]; } srpx += srx; out_data[k] = sum * factor; } srp->x = srpx; } /* it was a cold, rainy day... * and on an even colder day, I changed this to use a circular data buffer, rather than memmove * then changed yet again to use straight buffers */ mus_float_t *mus_src_20(mus_any *srptr, mus_float_t *in_data, mus_long_t dur) { sr *srp = (sr *)srptr; mus_float_t sum; int lim, i, width, wid1, wid10, xs, xi; mus_long_t k, dur2; mus_float_t *out_data, *ldata, *coeffs; dur2 = dur / 2 + 1; if ((dur & 1) != 0) dur2++; out_data = (mus_float_t *)malloc(dur2 * sizeof(mus_float_t)); lim = srp->lim; /* 2 * width so it's even */ width = srp->width; coeffs = (mus_float_t *)malloc(lim * sizeof(mus_float_t)); if ((width & 1) != 0) xs = (int)((2 + width) * (SRC_SINC_DENSITY / 2)) + 4; /* Humph -- looks like crap -- maybe if odd width use the real one above, or insist on even width */ else xs = (int)((1 + width) * (SRC_SINC_DENSITY / 2)) + 4; xi = SRC_SINC_DENSITY; /* skip a location (coeff=0.0) */ for (i = 0; i < width; i++, xs += xi) coeffs[i] = srp->sinc_table[xs]; for (i = 0; i < lim; i++) in_data[i] = srp->data[i]; ldata = (mus_float_t *)in_data; wid10 = width - 10; wid1 = width - 1; for (k = 0; k < dur2; k++, ldata += 2) { int j; sum = ldata[wid1]; i = 0; j = 0; while (i <= wid10) { sum += (ldata[j] * coeffs[i++]); j += 2; sum += (ldata[j] * coeffs[i++]); j += 2; sum += (ldata[j] * coeffs[i++]); j += 2; sum += (ldata[j] * coeffs[i++]); j += 2; sum += (ldata[j] * coeffs[i++]); j += 2; sum += (ldata[j] * coeffs[i++]); j += 2; sum += (ldata[j] * coeffs[i++]); j += 2; sum += (ldata[j] * coeffs[i++]); j += 2; sum += (ldata[j] * coeffs[i++]); j += 2; sum += (ldata[j] * coeffs[i++]); j += 2; } for (; i < width; i++, j += 2) sum += (ldata[j] * coeffs[i]); out_data[k] = sum * 0.5; } free(coeffs); return(out_data); } mus_float_t *mus_src_05(mus_any *srptr, mus_float_t *in_data, mus_long_t dur) { sr *srp = (sr *)srptr; mus_float_t sum; int lim, i, width, wid1, wid10, xs, xi; mus_long_t k, dur2; mus_float_t *out_data, *ldata, *coeffs; dur2 = dur * 2; out_data = (mus_float_t *)malloc((dur2 + 1) * sizeof(mus_float_t)); out_data[dur2] = 0.0; lim = srp->lim; width = srp->width; coeffs = (mus_float_t *)malloc(lim * sizeof(mus_float_t)); xs = (SRC_SINC_DENSITY / 2) + 4; xi = SRC_SINC_DENSITY; for (i = 0; i < lim; i++, xs += xi) coeffs[i] = srp->sinc_table[xs]; for (i = 0; i < lim; i++) in_data[i] = srp->data[i]; ldata = (mus_float_t *)in_data; wid10 = lim - 10; wid1 = width - 1; for (k = 0; k < dur2; k += 2) { out_data[k] = ldata[wid1]; sum = 0.0; i = 0; while (i <= wid10) { sum += (ldata[i] * coeffs[i]); i++; sum += (ldata[i] * coeffs[i]); i++; sum += (ldata[i] * coeffs[i]); i++; sum += (ldata[i] * coeffs[i]); i++; sum += (ldata[i] * coeffs[i]); i++; sum += (ldata[i] * coeffs[i]); i++; sum += (ldata[i] * coeffs[i]); i++; sum += (ldata[i] * coeffs[i]); i++; sum += (ldata[i] * coeffs[i]); i++; sum += (ldata[i] * coeffs[i]); i++; } for (; i < lim; i++) sum += (ldata[i] * coeffs[i]); out_data[k + 1] = sum; ldata++; } free(coeffs); return(out_data); } /* ---------------- granulate ---------------- */ typedef struct { mus_any_class *core; mus_float_t (*rd)(void *arg, int direction); mus_float_t (*block_rd)(void *arg, int direction, mus_float_t *block, mus_long_t start, mus_long_t end); int s20; int s50; int rmp; mus_float_t amp; int cur_out; int input_hop; int ctr; int output_hop; mus_float_t *out_data; /* output buffer */ int out_data_len; mus_float_t *in_data; /* input buffer */ int in_data_len; void *closure; int (*edit)(void *closure); mus_float_t *grain; /* grain data */ int grain_len; bool first_samp; unsigned long randx; /* gen-local random number seed */ } grn_info; bool mus_is_granulate(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_GRANULATE)); } static bool granulate_equalp(mus_any *p1, mus_any *p2) {return(p1 == p2);} static char *describe_granulate(mus_any *ptr) { grn_info *gen = (grn_info *)ptr; char *describe_buffer; describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE); snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s expansion: %.3f (%d/%d), scaler: %.3f, length: %.3f secs (%d samps), ramp: %.3f", mus_name(ptr), (mus_float_t)(gen->output_hop) / (mus_float_t)(gen->input_hop), gen->input_hop, gen->output_hop, gen->amp, (mus_float_t)(gen->grain_len) / (mus_float_t)sampling_rate, gen->grain_len, (mus_float_t)(gen->rmp) / (mus_float_t)sampling_rate); return(describe_buffer); } static void free_granulate(mus_any *ptr) { grn_info *gen = (grn_info *)ptr; if (gen->out_data) free(gen->out_data); if (gen->in_data) free(gen->in_data); if (gen->grain) free(gen->grain); free(gen); } static mus_any *grn_info_copy(mus_any *ptr) { grn_info *g, *p; int bytes; p = (grn_info *)ptr; g = (grn_info *)malloc(sizeof(grn_info)); memcpy((void *)g, (void *)ptr, sizeof(grn_info)); bytes = g->out_data_len * sizeof(mus_float_t); g->out_data = (mus_float_t *)malloc(bytes); memcpy((void *)(g->out_data), (void *)(p->out_data), bytes); bytes = g->in_data_len * sizeof(mus_float_t); g->in_data = (mus_float_t *)malloc(bytes); memcpy((void *)(g->in_data), (void *)(p->in_data), bytes); g->grain = (mus_float_t *)malloc(bytes); memcpy((void *)(g->grain), (void *)(p->grain), bytes); return((mus_any *)g); } static mus_long_t grn_length(mus_any *ptr) {return(((grn_info *)ptr)->grain_len);} static mus_long_t grn_set_length(mus_any *ptr, mus_long_t val) { grn_info *gen = ((grn_info *)ptr); if ((val > 0) && (val < gen->out_data_len)) gen->grain_len = (int)val; /* larger -> segfault */ return(gen->grain_len); } static mus_float_t grn_scaler(mus_any *ptr) {return(((grn_info *)ptr)->amp);} static mus_float_t grn_set_scaler(mus_any *ptr, mus_float_t val) {((grn_info *)ptr)->amp = val; return(val);} static mus_float_t grn_frequency(mus_any *ptr) {return(((mus_float_t)((grn_info *)ptr)->output_hop) / (mus_float_t)sampling_rate);} static mus_float_t grn_set_frequency(mus_any *ptr, mus_float_t val) {((grn_info *)ptr)->output_hop = (int)((mus_float_t)sampling_rate * val); return(val);} static void *grn_closure(mus_any *rd) {return(((grn_info *)rd)->closure);} static void *grn_set_closure(mus_any *rd, void *e) {((grn_info *)rd)->closure = e; return(e);} static mus_float_t grn_increment(mus_any *ptr) { grn_info *gen = ((grn_info *)ptr); return(((mus_float_t)(gen->output_hop)) / ((mus_float_t)(gen->input_hop))); } static mus_float_t grn_set_increment(mus_any *ptr, mus_float_t val) { grn_info *gen = ((grn_info *)ptr); if (val != 0.0) gen->input_hop = (int)(gen->output_hop / val); return(val); } static mus_long_t grn_hop(mus_any *ptr) {return(((grn_info *)ptr)->output_hop);} static mus_long_t grn_set_hop(mus_any *ptr, mus_long_t val) {((grn_info *)ptr)->output_hop = (int)val; return(val);} static mus_long_t grn_ramp(mus_any *ptr) {return(((grn_info *)ptr)->rmp);} static mus_long_t grn_set_ramp(mus_any *ptr, mus_long_t val) { grn_info *gen = (grn_info *)ptr; if (val < (gen->grain_len * .5)) gen->rmp = (int)val; return(val); } static mus_float_t *granulate_data(mus_any *ptr) {return(((grn_info *)ptr)->grain);} int mus_granulate_grain_max_length(mus_any *ptr) {return(((grn_info *)ptr)->in_data_len);} static mus_long_t grn_location(mus_any *ptr) {return((mus_long_t)(((grn_info *)ptr)->randx));} static mus_long_t grn_set_location(mus_any *ptr, mus_long_t val) {((grn_info *)ptr)->randx = (unsigned long)val; return(val);} static mus_float_t run_granulate(mus_any *ptr, mus_float_t unused1, mus_float_t unused2) {return(mus_granulate(ptr, NULL));} static void grn_reset(mus_any *ptr) { grn_info *gen = (grn_info *)ptr; gen->cur_out = 0; gen->ctr = 0; memset((void *)(gen->out_data), 0, gen->out_data_len * sizeof(mus_float_t)); memset((void *)(gen->in_data), 0, gen->in_data_len * sizeof(mus_float_t)); memset((void *)(gen->grain), 0, gen->in_data_len * sizeof(mus_float_t)); gen->first_samp = true; } static int grn_irandom(grn_info *spd, int amp) { /* gen-local next_random */ spd->randx = spd->randx * 1103515245 + 12345; return((int)(amp * INVERSE_MAX_RAND2 * ((mus_float_t)((unsigned int)(spd->randx >> 16) & 32767)))); } static mus_any_class GRANULATE_CLASS = { MUS_GRANULATE, (char *)S_granulate, &free_granulate, &describe_granulate, &granulate_equalp, &granulate_data, 0, &grn_length, /* segment-length */ &grn_set_length, &grn_frequency, /* spd-out */ &grn_set_frequency, 0, 0, &grn_scaler, /* segment-scaler */ &grn_set_scaler, &grn_increment, &grn_set_increment, &run_granulate, MUS_NOT_SPECIAL, &grn_closure, 0, 0, 0, 0, 0, 0, 0, &grn_hop, &grn_set_hop, &grn_ramp, &grn_set_ramp, 0, 0, 0, 0, &grn_location, &grn_set_location, /* local randx */ 0, 0, 0, 0, 0, &grn_reset, &grn_set_closure, &grn_info_copy }; mus_any *mus_make_granulate(mus_float_t (*input)(void *arg, int direction), mus_float_t expansion, mus_float_t length, mus_float_t scaler, mus_float_t hop, mus_float_t ramp, mus_float_t jitter, int max_size, int (*edit)(void *closure), void *closure) { grn_info *spd; int outlen; outlen = (int)(sampling_rate * (hop + length)); if (max_size > outlen) outlen = max_size; if (expansion <= 0.0) { mus_error(MUS_ARG_OUT_OF_RANGE, S_make_granulate ": expansion must be > 0.0: %f", expansion); return(NULL); } if (outlen <= 0) { mus_error(MUS_NO_LENGTH, S_make_granulate ": size is %d (hop: %f, segment-length: %f)?", outlen, hop, length); return(NULL); } if ((hop * sampling_rate) < expansion) { mus_error(MUS_ARG_OUT_OF_RANGE, S_make_granulate ": expansion (%f) must be < hop * srate (%f)", expansion, hop * sampling_rate); return(NULL); } spd = (grn_info *)malloc(sizeof(grn_info)); spd->core = &GRANULATE_CLASS; spd->cur_out = 0; spd->ctr = 0; spd->grain_len = (int)(ceil(length * sampling_rate)); spd->rmp = (int)(ramp * spd->grain_len); spd->amp = scaler; spd->output_hop = (int)(hop * sampling_rate); spd->input_hop = (int)((mus_float_t)(spd->output_hop) / expansion); spd->s20 = 2 * (int)(jitter * sampling_rate * hop); /* was *.05 here and *.02 below */ /* added "2 *" 21-Mar-05 and replaced irandom with (grn)mus_irandom below */ spd->s50 = (int)(jitter * sampling_rate * hop * 0.4); spd->out_data_len = outlen; spd->out_data = (mus_float_t *)calloc(spd->out_data_len, sizeof(mus_float_t)); spd->in_data_len = outlen + spd->s20 + 1; spd->in_data = (mus_float_t *)malloc(spd->in_data_len * sizeof(mus_float_t)); spd->rd = input; spd->block_rd = NULL; spd->closure = closure; spd->edit = edit; spd->grain = (mus_float_t *)malloc(spd->in_data_len * sizeof(mus_float_t)); spd->first_samp = true; spd->randx = mus_rand_seed(); /* caller can override this via the mus_location method */ next_random(); return((mus_any *)spd); } void mus_granulate_set_edit_function(mus_any *ptr, int (*edit)(void *closure)) { grn_info *gen = (grn_info *)ptr; if (!(gen->grain)) gen->grain = (mus_float_t *)calloc(gen->in_data_len, sizeof(mus_float_t)); gen->edit = edit; } mus_float_t mus_granulate_with_editor(mus_any *ptr, mus_float_t (*input)(void *arg, int direction), int (*edit)(void *closure)) { /* in_data_len is the max grain size (:maxsize arg), not the current grain size * out_data_len is the size of the output buffer * grain_len is the current grain size * cur_out is the out_data buffer location where we need to add in the next grain * ctr is where we are now in out_data */ grn_info *spd = (grn_info *)ptr; mus_float_t result = 0.0; if (spd->ctr < spd->out_data_len) result = spd->out_data[spd->ctr]; /* else return 0.0 */ spd->ctr++; if (spd->ctr >= spd->cur_out) /* time for next grain */ { /* set up edit/input functions and possible outside-accessible grain array */ int i; int (*spd_edit)(void *closure) = edit; if (input) {spd->rd = input; spd->block_rd = NULL;} if (spd_edit == NULL) spd_edit = spd->edit; if (spd->first_samp) { /* fill up in_data, out_data is already cleared */ if (spd->block_rd) spd->block_rd(spd->closure, 1, spd->in_data, 0, spd->in_data_len); else { for (i = 0; i < spd->in_data_len; i++) spd->in_data[i] = spd->rd(spd->closure, 1); } } else { /* align output buffer to flush the data we've already output, and zero out new trailing portion */ if (spd->cur_out >= spd->out_data_len) { /* entire buffer has been output, and in fact we've been sending 0's for awhile to fill out hop */ memset((void *)(spd->out_data), 0, spd->out_data_len * sizeof(mus_float_t)); /* so zero the entire thing (it's all old) */ } else { /* move yet-un-output data to 0, zero trailers */ int good_samps; good_samps = (spd->out_data_len - spd->cur_out); memmove((void *)(spd->out_data), (void *)(spd->out_data + spd->cur_out), good_samps * sizeof(mus_float_t)); memset((void *)(spd->out_data + good_samps), 0, spd->cur_out * sizeof(mus_float_t)); /* must be cur_out trailing samples to 0 */ } /* align input buffer */ if (spd->input_hop > spd->in_data_len) { /* need to flush enough samples to accommodate the fact that the hop is bigger than our data buffer */ for (i = spd->in_data_len; i < spd->input_hop; i++) spd->rd(spd->closure, 1); /* then get a full input buffer */ if (spd->block_rd) spd->block_rd(spd->closure, 1, spd->in_data, 0, spd->in_data_len); else { for (i = 0; i < spd->in_data_len; i++) spd->in_data[i] = spd->rd(spd->closure, 1); } } else { /* align input buffer with current input hop location */ int good_samps; good_samps = (spd->in_data_len - spd->input_hop); memmove((void *)(spd->in_data), (void *)(spd->in_data + spd->input_hop), good_samps * sizeof(mus_float_t)); if (spd->block_rd) spd->block_rd(spd->closure, 1, spd->in_data, good_samps, spd->in_data_len); else { for (i = good_samps; i < spd->in_data_len; i++) spd->in_data[i] = spd->rd(spd->closure, 1); } } } /* create current grain */ { int lim, curstart, j; lim = spd->grain_len; curstart = grn_irandom(spd, spd->s20); /* start location in input buffer */ if ((curstart + spd->grain_len) > spd->in_data_len) lim = (spd->in_data_len - curstart); if (lim > spd->grain_len) lim = spd->grain_len; else { if (lim < spd->grain_len) memset((void *)(spd->grain), 0, (spd->grain_len - lim) * sizeof(mus_float_t)); } if (spd->rmp > 0) { int steady_end, up_end; mus_float_t amp = 0.0, incr; steady_end = (spd->grain_len - spd->rmp); incr = (mus_float_t)(spd->amp) / (mus_float_t)(spd->rmp); up_end = spd->rmp; if (up_end > lim) up_end = lim; for (i = 0, j = curstart; i < up_end; i++, j++) { spd->grain[i] = (amp * spd->in_data[j]); amp += incr; } if (steady_end > lim) steady_end = lim; for (; i < steady_end; i++, j++) spd->grain[i] = (amp * spd->in_data[j]); for (; i < lim; i++, j++) { spd->grain[i] = (amp * spd->in_data[j]); amp -= incr; } } else { /* ramp is 0.0, so just scale the input buffer by the current amp */ if (spd->amp == 1.0) memcpy((void *)(spd->grain), (void *)(spd->in_data + curstart), lim * sizeof(mus_float_t)); else { for (i = 0, j = curstart; i < lim; i++, j++) spd->grain[i] = (spd->amp * spd->in_data[j]); } } } /* add new grain into output buffer */ { int new_len; if (spd_edit) { new_len = (*spd_edit)(spd->closure); if (new_len <= 0) new_len = spd->grain_len; else { if (new_len > spd->out_data_len) new_len = spd->out_data_len; } } else new_len = spd->grain_len; if (new_len > spd->out_data_len) /* can be off-by-one here if hop is just barely greater then 0.0 (user is screwing around...) */ new_len = spd->out_data_len; for (i = 0; i < new_len; i++) spd->out_data[i] += spd->grain[i]; } /* set location of next grain calculation */ spd->ctr = 0; spd->cur_out = spd->output_hop + grn_irandom(spd, 2 * spd->s50) - (spd->s50 >> 1); /* this form suggested by Marc Lehmann */ /* "2 *" added 21-Mar-05 and irandom replaced with mus_irandom, grn_irandom 28-Feb-06 */ /* use of gen-local random sequence suggested by Kjetil Matheussen (to keep multi-channel grns in sync) */ if (spd->cur_out < 0) spd->cur_out = 0; if (spd->first_samp) { spd->first_samp = false; spd->ctr = 1; return(spd->out_data[0]); } } return(result); } mus_float_t mus_granulate(mus_any *ptr, mus_float_t (*input)(void *arg, int direction)) { return(mus_granulate_with_editor(ptr, input, NULL)); } /* ---------------- Fourier transform ---------------- */ /* fft of mus_float_t data in zero-based arrays */ static void mus_big_fft(mus_float_t *rl, mus_float_t *im, mus_long_t n, int is); #if HAVE_FFTW3 && HAVE_COMPLEX_TRIG static fftw_complex *c_in_data = NULL, *c_out_data = NULL; static fftw_plan c_r_plan, c_i_plan; static int last_c_fft_size = 0; static void mus_fftw_with_imag(mus_float_t *rl, mus_float_t *im, int n, int dir) { int i, n4; if (n != last_c_fft_size) { if (c_in_data) { fftw_free(c_in_data); fftw_free(c_out_data); fftw_destroy_plan(c_r_plan); fftw_destroy_plan(c_i_plan); } c_in_data = (fftw_complex *)fftw_malloc(n * sizeof(fftw_complex)); /* rl/im data is mus_float_t */ c_out_data = (fftw_complex *)fftw_malloc(n * sizeof(fftw_complex)); c_r_plan = fftw_plan_dft_1d(n, c_in_data, c_out_data, FFTW_FORWARD, FFTW_ESTIMATE); c_i_plan = fftw_plan_dft_1d(n, c_in_data, c_out_data, FFTW_BACKWARD, FFTW_ESTIMATE); last_c_fft_size = n; } n4 = n - 4; i = 0; while (i <= n4) { /* adding code to avoid this loop saves essentially nothing, mainly because the great majority of the calls * are actually handling two real arrays at once -- the imag=0 case is 1/10 of the total. In the zero case, * the savings here is about 10%, but that is swamped by the fft itself (say 5-10 in c*). * using the new split array code (see below) saves essentially nothing -- perhaps 1 to 2% overall. */ c_in_data[i] = rl[i] + _Complex_I * im[i]; i++; c_in_data[i] = rl[i] + _Complex_I * im[i]; i++; c_in_data[i] = rl[i] + _Complex_I * im[i]; i++; c_in_data[i] = rl[i] + _Complex_I * im[i]; i++; } for (; i < n; i++) c_in_data[i] = rl[i] + _Complex_I * im[i]; if (dir == -1) fftw_execute(c_r_plan); else fftw_execute(c_i_plan); i = 0; while (i <= n4) { rl[i] = creal(c_out_data[i]); im[i] = cimag(c_out_data[i]); i++; rl[i] = creal(c_out_data[i]); im[i] = cimag(c_out_data[i]); i++; rl[i] = creal(c_out_data[i]); im[i] = cimag(c_out_data[i]); i++; rl[i] = creal(c_out_data[i]); im[i] = cimag(c_out_data[i]); i++; } for (; i < n; i++) { rl[i] = creal(c_out_data[i]); im[i] = cimag(c_out_data[i]); } } void mus_fft(mus_float_t *rl, mus_float_t *im, mus_long_t n, int is) { /* simple timing tests indicate fftw is slightly faster than mus_fft in this context */ if (n < (1 << 30)) mus_fftw_with_imag(rl, im, n, is); else mus_big_fft(rl, im, n, is); } #else static void mus_scramble(mus_float_t *rl, mus_float_t *im, int n) { /* bit reversal */ int i, j; mus_float_t vr, vi; j = 0; for (i = 0; i < n; i++) { int m; if (j > i) { vr = rl[j]; vi = im[j]; rl[j] = rl[i]; im[j] = im[i]; rl[i] = vr; im[i] = vi; } m = n >> 1; while ((m >= 2) && (j >= m)) { j -= m; m = m >> 1; } j += m; } } void mus_fft(mus_float_t *rl, mus_float_t *im, mus_long_t n, int is) { /* standard fft: real part in rl, imaginary in im, * rl and im are zero-based. * see fxt/simplfft/fft.c (Joerg Arndt) */ int m, j, mh, ldm, lg, i, i2, j2, imh; mus_float_t u, vr, vi, angle; if (n >= (1 << 30)) { mus_big_fft(rl, im, n, is); return; } imh = (int)(log(n + 1) / log(2.0)); mus_scramble(rl, im, n); m = 2; ldm = 1; mh = n >> 1; angle = (M_PI * is); for (lg = 0; lg < imh; lg++) { mus_float_t c, s, ur, ui; c = cos(angle); s = sin(angle); ur = 1.0; ui = 0.0; for (i2 = 0; i2 < ldm; i2++) { i = i2; j = i2 + ldm; for (j2 = 0; j2 < mh; j2++) { vr = ur * rl[j] - ui * im[j]; vi = ur * im[j] + ui * rl[j]; rl[j] = rl[i] - vr; im[j] = im[i] - vi; rl[i] += vr; im[i] += vi; i += m; j += m; } u = ur; ur = (ur * c) - (ui * s); ui = (ui * c) + (u * s); } mh >>= 1; ldm = m; angle *= 0.5; m <<= 1; } } #endif static void mus_big_fft(mus_float_t *rl, mus_float_t *im, mus_long_t n, int is) { mus_long_t m, j, mh, ldm, i, i2, j2; int imh, lg; mus_float_t u, vr, vi, angle; imh = (int)(log(n + 1) / log(2.0)); j = 0; for (i = 0; i < n; i++) { if (j > i) { vr = rl[j]; vi = im[j]; rl[j] = rl[i]; im[j] = im[i]; rl[i] = vr; im[i] = vi; } m = n >> 1; while ((m >= 2) && (j >= m)) { j -= m; m = m >> 1; } j += m; } m = 2; ldm = 1; mh = n >> 1; angle = (M_PI * is); for (lg = 0; lg < imh; lg++) { mus_float_t c, s, ur, ui; c = cos(angle); s = sin(angle); ur = 1.0; ui = 0.0; for (i2 = 0; i2 < ldm; i2++) { i = i2; j = i2 + ldm; for (j2 = 0; j2 < mh; j2++) { vr = ur * rl[j] - ui * im[j]; vi = ur * im[j] + ui * rl[j]; rl[j] = rl[i] - vr; im[j] = im[i] - vi; rl[i] += vr; im[i] += vi; i += m; j += m; } u = ur; ur = (ur * c) - (ui * s); ui = (ui * c) + (u * s); } mh >>= 1; ldm = m; angle *= 0.5; m <<= 1; } } #if HAVE_GSL #include mus_float_t mus_bessi0(mus_float_t x) { gsl_sf_result res; gsl_sf_bessel_I0_e(x, &res); return((mus_float_t)(res.val)); } #else mus_float_t mus_bessi0(mus_float_t x) { if (x == 0.0) return(1.0); if (fabs(x) <= 15.0) { mus_float_t z, denominator, numerator; z = x * x; numerator = (z * (z * (z * (z * (z * (z * (z * (z * (z * (z * (z * (z * (z * (z * 0.210580722890567e-22 + 0.380715242345326e-19) + 0.479440257548300e-16) + 0.435125971262668e-13) + 0.300931127112960e-10) + 0.160224679395361e-7) + 0.654858370096785e-5) + 0.202591084143397e-2) + 0.463076284721000e0) + 0.754337328948189e2) + 0.830792541809429e4) + 0.571661130563785e6) + 0.216415572361227e8) + 0.356644482244025e9) + 0.144048298227235e10); denominator = (z * (z * (z - 0.307646912682801e4) + 0.347626332405882e7) - 0.144048298227235e10); return(-numerator / denominator); } return(1.0); } #endif #if HAVE_COMPLEX_TRIG || HAVE_GSL static mus_float_t ultraspherical(int n, mus_float_t x, mus_float_t lambda) { /* this is also the algorithm used in gsl gegenbauer.c -- slow but not as bad as using the binomials! */ mus_float_t fn1, fn2 = 1.0, fn = 1.0; int k; if (n == 0) return(1.0); if (lambda == 0.0) fn1 = 2.0 * x; else fn1 = 2.0 * x * lambda; if (n == 1) return(fn1); for (k = 2; k <= n; k++) { fn = ((2.0 * x * (k + lambda - 1.0) * fn1) - ((k + (2.0 * lambda) - 2.0) * fn2)) / (mus_float_t)k; fn2 = fn1; fn1 = fn; } return(fn); } #endif bool mus_is_fft_window(int val) { switch (val) { case MUS_RECTANGULAR_WINDOW: case MUS_HANN_WINDOW: case MUS_WELCH_WINDOW: case MUS_PARZEN_WINDOW: case MUS_BARTLETT_WINDOW: case MUS_HAMMING_WINDOW: case MUS_BLACKMAN2_WINDOW: case MUS_BLACKMAN3_WINDOW: case MUS_BLACKMAN4_WINDOW: case MUS_EXPONENTIAL_WINDOW: case MUS_RIEMANN_WINDOW: case MUS_KAISER_WINDOW: case MUS_CAUCHY_WINDOW: case MUS_POISSON_WINDOW: case MUS_GAUSSIAN_WINDOW: case MUS_TUKEY_WINDOW: case MUS_DOLPH_CHEBYSHEV_WINDOW: case MUS_HANN_POISSON_WINDOW: case MUS_CONNES_WINDOW: case MUS_SAMARAKI_WINDOW: case MUS_ULTRASPHERICAL_WINDOW: case MUS_BARTLETT_HANN_WINDOW: case MUS_BOHMAN_WINDOW: case MUS_FLAT_TOP_WINDOW: case MUS_BLACKMAN5_WINDOW: case MUS_BLACKMAN6_WINDOW: case MUS_BLACKMAN7_WINDOW: case MUS_BLACKMAN8_WINDOW: case MUS_BLACKMAN9_WINDOW: case MUS_BLACKMAN10_WINDOW: case MUS_RV2_WINDOW: case MUS_RV3_WINDOW: case MUS_RV4_WINDOW: case MUS_MLT_SINE_WINDOW: case MUS_PAPOULIS_WINDOW: case MUS_DPSS_WINDOW: case MUS_SINC_WINDOW: return(true); break; } return(false); } #if HAVE_GSL #include #if ((GSL_MAJOR_VERSION >= 1) && (GSL_MINOR_VERSION >= 9)) #include #include #define HAVE_GSL_EIGEN_NONSYMMV_WORKSPACE 1 #endif #endif static mus_float_t sqr(mus_float_t x) {return(x * x);} mus_float_t *mus_make_fft_window_with_window(mus_fft_window_t type, mus_long_t size, mus_float_t beta, mus_float_t mu, mus_float_t *window) { /* mostly taken from * Fredric J. Harris, "On the Use of Windows for Harmonic Analysis with the * Discrete Fourier Transform," Proceedings of the IEEE, Vol. 66, No. 1, * January 1978. * * Albert H. Nuttall, "Some Windows with Very Good Sidelobe Behaviour", * IEEE Transactions of Acoustics, Speech, and Signal Processing, Vol. ASSP-29, * No. 1, February 1981, pp 84-91 */ mus_long_t i, j, midn, midp1; mus_float_t freq, rate, angle = 0.0, cx; if (window == NULL) return(NULL); midn = size >> 1; midp1 = (size + 1) / 2; freq = TWO_PI / (mus_float_t)size; rate = 1.0 / (mus_float_t)midn; switch (type) { case MUS_RECTANGULAR_WINDOW: for (i = 0; i < size; i++) window[i] = 1.0; break; case MUS_WELCH_WINDOW: for (i = 0, j = size - 1; i <= midn; i++, j--) { window[i] = 1.0 - sqr((mus_float_t)(i - midn) / (mus_float_t)midp1); window[j] = window[i]; } break; case MUS_CONNES_WINDOW: for (i = 0, j = size - 1; i <= midn; i++, j--) { window[i] = sqr(1.0 - sqr((mus_float_t)(i - midn) / (mus_float_t)midp1)); window[j] = window[i]; } break; case MUS_PARZEN_WINDOW: for (i = 0, j = size - 1; i <= midn; i++, j--) { window[i] = 1.0 - fabs((mus_float_t)(i - midn) / (mus_float_t)midp1); window[j] = window[i]; } break; case MUS_BARTLETT_WINDOW: for (i = 0, j = size - 1, angle = 0.0; i <= midn; i++, j--, angle += rate) { window[i] = angle; window[j] = angle; } break; case MUS_BARTLETT_HANN_WINDOW: { mus_float_t ramp; rate *= 0.5; /* this definition taken from mathworks docs: they use size - 1 throughout -- this makes very little * difference unless you're using a small window. I decided to be consistent with all the other * windows, and besides, this way actually peaks at 1.0 (which matlab misses) */ for (i = 0, j = size - 1, angle = -M_PI, ramp = 0.5; i <= midn; i++, j--, angle += freq, ramp -= rate) { window[i] = 0.62 - 0.48 * ramp + 0.38 * cos(angle); window[j] = window[i]; } } break; case MUS_BOHMAN_WINDOW: { mus_float_t ramp; /* definition from diracdelta docs and "DSP Handbook" -- used in bispectrum ("minimum bispectrum bias supremum") */ for (i = 0, j = size - 1, angle = M_PI, ramp = 0.0; i <= midn; i++, j--, angle -= freq, ramp += rate) { window[i] = ramp * cos(angle) + (sin(angle) / M_PI); window[j] = window[i]; } } break; case MUS_HANN_WINDOW: for (i = 0, j = size - 1, angle = 0.0; i <= midn; i++, j--, angle += freq) { window[i] = 0.5 - 0.5 * cos(angle); window[j] = window[i]; } break; /* Rife-Vincent windows are an elaboration of this (Hann = RV1) */ case MUS_RV2_WINDOW: for (i = 0, j = size - 1, angle = 0.0; i <= midn; i++, j--, angle += freq) { window[i] = .375 - 0.5 * cos(angle) + .125 * cos(2 * angle); window[j] = window[i]; } break; case MUS_RV3_WINDOW: for (i = 0, j = size - 1, angle = 0.0; i <= midn; i++, j--, angle += freq) { window[i] = (10.0 / 32.0) - (15.0 / 32.0) * cos(angle) + (6.0 / 32.0) * cos(2 * angle) - (1.0 / 32.0) * cos(3 * angle); window[j] = window[i]; } break; case MUS_RV4_WINDOW: for (i = 0, j = size - 1, angle = 0.0; i <= midn; i++, j--, angle += freq) { window[i] = (35.0 / 128.0) - (56.0 / 128.0) * cos(angle) + (28.0 / 128.0) * cos(2 * angle) - (8.0 / 128.0) * cos(3 * angle) + (1.0 / 128.0) * cos(4 * angle); window[j] = window[i]; } break; case MUS_HAMMING_WINDOW: for (i = 0, j = size - 1, angle = 0.0; i <= midn; i++, j--, angle += freq) { window[i] = 0.54 - 0.46 * cos(angle); window[j] = window[i]; } break; /* Blackman 1 is the same as Hamming */ case MUS_BLACKMAN2_WINDOW: /* using Chebyshev polynomial equivalents here (this is also given as .42 .5 .08) */ for (i = 0, j = size - 1, angle = 0.0; i <= midn; i++, j--, angle += freq) { /* (+ 0.42323 (* -0.49755 (cos a)) (* 0.07922 (cos (* a 2)))) */ /* "A Family...": .42438 .49341 .078279 */ cx = cos(angle); window[i] = .34401 + (cx * (-.49755 + (cx * .15844))); window[j] = window[i]; } break; case MUS_BLACKMAN3_WINDOW: for (i = 0, j = size - 1, angle = 0.0; i <= midn; i++, j--, angle += freq) { /* (+ 0.35875 (* -0.48829 (cos a)) (* 0.14128 (cos (* a 2))) (* -0.01168 (cos (* a 3)))) */ /* (+ 0.36336 (* 0.48918 (cos a)) (* 0.13660 (cos (* a 2))) (* 0.01064 (cos (* a 3)))) is "Nuttall" window? */ /* "A Family...": .36358 .489177 .136599 .0106411 */ cx = cos(angle); window[i] = .21747 + (cx * (-.45325 + (cx * (.28256 - (cx * .04672))))); window[j] = window[i]; } break; case MUS_BLACKMAN4_WINDOW: for (i = 0, j = size - 1, angle = 0.0; i <= midn; i++, j--, angle += freq) { /* (+ 0.287333 (* -0.44716 (cos a)) (* 0.20844 (cos (* a 2))) (* -0.05190 (cos (* a 3))) (* 0.005149 (cos (* a 4)))) */ /* "A Family...": .32321 .471492 .175534 .0284969 .001261357 */ cx = cos(angle); window[i] = .084037 + (cx * (-.29145 + (cx * (.375696 + (cx * (-.20762 + (cx * .041194))))))); window[j] = window[i]; } break; /* "A Family of Cosine-Sum Windows..." Albrecht */ case MUS_BLACKMAN5_WINDOW: for (i = 0, j = size - 1, angle = 0.0; i <= midn; i++, j--, angle += freq) { /* .293557 -.451935 .201416 -.047926 .00502619 -.000137555 */ /* partials->polynomial -> -0.196389809 -0.308844775 0.3626224697 -0.188952908 0.0402095206 -0.002200880, then fixup constant */ cx = cos(angle); window[i] = 0.097167 + (cx * (-.3088448 + (cx * (.3626224 + (cx * (-.1889530 + (cx * (.04020952 + (cx * -.0022008))))))))); window[j] = window[i]; } break; case MUS_BLACKMAN6_WINDOW: for (i = 0, j = size - 1, angle = 0.0; i <= midn; i++, j--, angle += freq) { /* .2712203 -.4334446 .2180041 -.0657853 .010761867 -.0007700127 .00001368088 */ /* partials->polynomial -> -0.207255900 -0.239938736 0.3501594961 * -0.247740954 0.0854382589 -0.012320203 0.0004377882 */ cx = cos(angle); window[i] = 0.063964353 + (cx * (-0.239938736 + (cx * (0.3501594961 + (cx * (-0.247740954 + (cx * (0.0854382589 + (cx * (-0.012320203 + (cx * 0.0004377882))))))))))); window[j] = window[i]; } break; case MUS_BLACKMAN7_WINDOW: for (i = 0, j = size - 1, angle = 0.0; i <= midn; i++, j--, angle += freq) { /* .2533176 -.4163269 .2288396 -.08157508 .017735924 -.0020967027 .00010677413 -.0000012807 */ /* partials->polynomial -> -0.211210445 -0.182076216 0.3177137375 -0.284437984 * 0.1367622316 -0.033403806 0.0034167722 -0.000081965 */ cx = cos(angle); window[i] = 0.04210723 + (cx * (-0.18207621 + (cx * (0.3177137375 + (cx * (-0.284437984 + (cx * (0.1367622316 + (cx * (-0.033403806 + (cx * (0.0034167722 + (cx * -0.000081965))))))))))))); window[j] = window[i]; } break; case MUS_BLACKMAN8_WINDOW: for (i = 0, j = size - 1, angle = 0.0; i <= midn; i++, j--, angle += freq) { /* .2384331 -.4005545 .2358242 -.09527918 .025373955 -.0041524329 .00036856041 -.00001384355 .0000001161808 */ /* partials->polynomial -> -0.210818693 -0.135382235 0.2752871215 -0.298843294 0.1853193194 * -0.064888448 0.0117641902 -0.000885987 0.0000148711 */ cx = cos(angle); window[i] = 0.027614462 + (cx * (-0.135382235 + (cx * (0.2752871215 + (cx * (-0.298843294 + (cx * (0.1853193194 + (cx * (-0.064888448 + (cx * (0.0117641902 + (cx * (-0.000885987 + (cx * 0.0000148711))))))))))))))); window[j] = window[i]; } break; case MUS_BLACKMAN9_WINDOW: for (i = 0, j = size - 1, angle = 0.0; i <= midn; i++, j--, angle += freq) { /* .2257345 -.3860122 .2401294 -.1070542 .03325916 -.00687337 .0008751673 -.0000600859 .000001710716 -.00000001027272 */ /* partials->polynomial -> -0.207743675 -0.098795950 0.2298837751 -0.294112951 0.2243389785 * -0.103248745 0.0275674108 -0.003839580 0.0002189716 -0.000002630 */ cx = cos(angle); window[i] = 0.01799071953 + (cx * (-0.098795950 + (cx * (0.2298837751 + (cx * (-0.294112951 + (cx * (0.2243389785 + (cx * (-0.103248745 + (cx * (0.0275674108 + (cx * (-0.003839580 + (cx * (0.0002189716 + (cx * -0.000002630))))))))))))))))); window[j] = window[i]; } break; case MUS_BLACKMAN10_WINDOW: for (i = 0, j = size - 1, angle = 0.0; i <= midn; i++, j--, angle += freq) { /* .2151527 -.3731348 .2424243 -.1166907 .04077422 -.01000904 .0016398069 -.0001651660 .000008884663 -.000000193817 .00000000084824 */ /* partials->polynomial -> -0.203281015 -0.071953468 0.1878870875 -0.275808066 * 0.2489042133 -0.141729787 0.0502002984 -0.010458985 0.0011361511 -0.000049617 0.0000004343 */ cx = cos(angle); window[i] = 0.0118717384 + (cx * (-0.071953468 + (cx * (0.1878870875 + (cx * (-0.275808066 + (cx * (0.2489042133 + (cx * (-0.141729787 + (cx * (0.0502002984 + (cx * (-0.010458985 + (cx * (0.0011361511 + (cx * (-0.000049617 + (cx * 0.0000004343))))))))))))))))))); window[j] = window[i]; } break; case MUS_FLAT_TOP_WINDOW: /* this definition taken from mathworks docs -- see above */ for (i = 0, j = size - 1, angle = 0.0; i <= midn; i++, j--, angle += freq) { window[i] = 0.2156 - 0.4160 * cos(angle) + 0.2781 * cos(2 * angle) - 0.0836 * cos(3 * angle) + 0.0069 * cos(4 * angle); window[j] = window[i]; } break; case MUS_EXPONENTIAL_WINDOW: { mus_float_t expn, expsum = 1.0; expn = log(2) / (mus_float_t)midn + 1.0; for (i = 0, j = size - 1; i <= midn; i++, j--) { window[i] = expsum - 1.0; window[j] = window[i]; expsum *= expn; } } break; case MUS_KAISER_WINDOW: { mus_float_t I0beta; I0beta = mus_bessi0(beta); /* Harris multiplies beta by pi */ for (i = 0, j = size - 1, angle = 1.0; i <= midn; i++, j--, angle -= rate) { window[i] = mus_bessi0(beta * sqrt(1.0 - sqr(angle))) / I0beta; window[j] = window[i]; } } break; case MUS_CAUCHY_WINDOW: for (i = 0, j = size - 1, angle = 1.0; i <= midn; i++, j--, angle -= rate) { window[i] = 1.0 / (1.0 + sqr(beta * angle)); window[j] = window[i]; } break; case MUS_POISSON_WINDOW: for (i = 0, j = size - 1, angle = 1.0; i <= midn; i++, j--, angle -= rate) { window[i] = exp((-beta) * angle); window[j] = window[i]; } break; case MUS_HANN_POISSON_WINDOW: /* Hann * Poisson -- from JOS */ { mus_float_t angle1; for (i = 0, j = size - 1, angle = 1.0, angle1 = 0.0; i <= midn; i++, j--, angle -= rate, angle1 += freq) { window[i] = exp((-beta) * angle) * (0.5 - 0.5 * cos(angle1)); window[j] = window[i]; } } break; case MUS_RIEMANN_WINDOW: { mus_float_t sr1; sr1 = TWO_PI / (mus_float_t)size; for (i = 0, j = size - 1; i <= midn; i++, j--) { if (i == midn) window[i] = 1.0; else { cx = sr1 * (midn - i); window[i] = sin(cx) / cx; } window[j] = window[i]; } } break; case MUS_GAUSSIAN_WINDOW: for (i = 0, j = size - 1, angle = 1.0; i <= midn; i++, j--, angle -= rate) { window[i] = exp(-.5 * sqr(beta * angle)); window[j] = window[i]; } break; case MUS_TUKEY_WINDOW: cx = midn * (1.0 - beta); for (i = 0, j = size - 1; i <= midn; i++, j--) { if (i >= cx) window[i] = 1.0; else window[i] = .5 * (1.0 - cos(M_PI * i / cx)); window[j] = window[i]; } break; case MUS_MLT_SINE_WINDOW: { mus_float_t scl; scl = M_PI / (mus_float_t)size; for (i = 0, j = size - 1; i <= midn; i++, j--) { window[i] = sin((i + 0.5) * scl); window[j] = window[i]; } } break; case MUS_PAPOULIS_WINDOW: { int n2; n2 = size / 2; for (i = -n2; i < n2; i++) { mus_float_t ratio, pratio; ratio = (mus_float_t)i / (mus_float_t)n2; pratio = M_PI * ratio; window[i + n2] = (fabs(sin(pratio)) / M_PI) + (cos(pratio) * (1.0 - fabs(ratio))); } } break; case MUS_SINC_WINDOW: { mus_float_t scl; scl = 2 * M_PI / (size - 1); for (i = -midn, j = 0; i < midn; i++, j++) { if (i == 0) window[j] = 1.0; else window[j] = sin(i * scl) / (i * scl); } } break; case MUS_DPSS_WINDOW: #if HAVE_GSL_EIGEN_NONSYMMV_WORKSPACE { /* from Verma, Bilbao, Meng, "The Digital Prolate Spheroidal Window" * output checked using Julius Smith's dpssw.m, although my "beta" is different */ double *data; /* "double" for gsl func */ double cw, n1, pk = 0.0; cw = cos(2 * M_PI * beta); n1 = (size - 1) * 0.5; if ((mus_long_t)(size * size * sizeof(double)) > mus_max_malloc()) { mus_error(MUS_ARG_OUT_OF_RANGE, S_make_fft_window ": dpss window requires size^2 * 8 bytes, but that exceeds the current mus-max-malloc amount"); return(window); } data = (double *)calloc(size * size, sizeof(double)); for (i = 0; i < size; i++) { double n2; n2 = n1 - i; data[i * size + i] = cw * n2 * n2; if (i < (size - 1)) data[i * (size + 1) + 1] = 0.5 * (i + 1) * (size - 1 - i); if (i > 0) data[i * (size + 1) - 1] = 0.5 * i * (size - i); } { gsl_vector_complex_view evec_i; gsl_matrix_view m = gsl_matrix_view_array(data, size, size); gsl_vector_complex *eval = gsl_vector_complex_alloc(size); gsl_matrix_complex *evec = gsl_matrix_complex_alloc(size, size); gsl_eigen_nonsymmv_workspace *w = gsl_eigen_nonsymmv_alloc(size); gsl_eigen_nonsymmv(&m.matrix, eval, evec, w); gsl_eigen_nonsymmv_free(w); gsl_eigen_nonsymmv_sort(eval, evec, GSL_EIGEN_SORT_ABS_DESC); evec_i = gsl_matrix_complex_column(evec, 0); for (j = 0; j < size; j++) window[j] = GSL_REAL(gsl_vector_complex_get(&evec_i.vector, j)); gsl_vector_complex_free(eval); gsl_matrix_complex_free(evec); } for (i = 0; i < size; i++) if (fabs(window[i]) > fabs(pk)) pk = window[i]; if (pk != 0.0) for (i = 0; i < size; i++) window[i] /= pk; free(data); } #else mus_error(MUS_NO_SUCH_FFT_WINDOW, S_make_fft_window ": DPSS window needs GSL"); #endif break; case MUS_ULTRASPHERICAL_WINDOW: case MUS_SAMARAKI_WINDOW: case MUS_DOLPH_CHEBYSHEV_WINDOW: /* "Design of Ultraspherical Window Functions with Prescribed Spectral Characteristics", Bergen and Antoniou, EURASIP JASP 2004 */ if (type == MUS_ULTRASPHERICAL_WINDOW) { if (mu == 0.0) type = MUS_DOLPH_CHEBYSHEV_WINDOW; else { if (mu == 1.0) type = MUS_SAMARAKI_WINDOW; } } #if HAVE_COMPLEX_TRIG { mus_float_t *rl, *im; mus_float_t pk = 0.0; mus_float_t alpha; freq = M_PI / (mus_float_t)size; if (beta < 0.2) beta = 0.2; alpha = creal(ccosh(cacosh(pow(10.0, beta)) / (mus_float_t)size)); rl = (mus_float_t *)malloc(size * sizeof(mus_float_t)); im = (mus_float_t *)calloc(size, sizeof(mus_float_t)); for (i = 0, angle = 0.0; i < size; i++, angle += freq) { switch (type) { case MUS_DOLPH_CHEBYSHEV_WINDOW: rl[i] = creal(ccos(cacos(alpha * cos(angle)) * size)); /* here is Tn (Chebyshev polynomial first kind) */ break; case MUS_SAMARAKI_WINDOW: /* Samaraki window uses Un instead */ rl[i] = creal(csin(cacos(alpha * cos(angle)) * (size + 1.0)) / csin(cacos(alpha * cos(angle)))); break; case MUS_ULTRASPHERICAL_WINDOW: /* Cn here */ rl[i] = ultraspherical(size, alpha * cos(angle), mu); break; default: break; } } mus_fft(rl, im, size, -1); /* can be 1 here */ pk = 0.0; for (i = 0; i < size; i++) if (pk < rl[i]) pk = rl[i]; if ((pk != 0.0) && (pk != 1.0)) { for (i = 0, j = size / 2; i < size; i++) { window[i] = rl[j++] / pk; if (j == size) j = 0; } } else { memcpy((void *)window, (void *)rl, size * sizeof(mus_float_t)); } free(rl); free(im); } #else #if HAVE_GSL { mus_float_t *rl, *im; mus_float_t pk; mus_float_t alpha; freq = M_PI / (mus_float_t)size; if (beta < 0.2) beta = 0.2; alpha = GSL_REAL(gsl_complex_cosh( gsl_complex_mul_real( gsl_complex_arccosh_real(pow(10.0, beta)), (mus_float_t)(1.0 / (mus_float_t)size)))); rl = (mus_float_t *)malloc(size * sizeof(mus_float_t)); im = (mus_float_t *)calloc(size, sizeof(mus_float_t)); for (i = 0, angle = 0.0; i < size; i++, angle += freq) { switch (type) { case MUS_DOLPH_CHEBYSHEV_WINDOW: rl[i] = GSL_REAL(gsl_complex_cos( gsl_complex_mul_real( gsl_complex_arccos_real(alpha * cos(angle)), (mus_float_t)size))); break; case MUS_SAMARAKI_WINDOW: rl[i] = GSL_REAL(gsl_complex_div( gsl_complex_sin( gsl_complex_mul_real( gsl_complex_arccos_real(alpha * cos(angle)), (mus_float_t)(size + 1.0))), gsl_complex_sin( gsl_complex_arccos_real(alpha * cos(angle))))); break; case MUS_ULTRASPHERICAL_WINDOW: rl[i] = ultraspherical(size, alpha * cos(angle), mu); break; default: break; } } mus_fft(rl, im, size, -1); /* can be 1 here */ pk = 0.0; for (i = 0; i < size; i++) if (pk < rl[i]) pk = rl[i]; if ((pk != 0.0) && (pk != 1.0)) { for (i = 0, j = size / 2; i < size; i++) { window[i] = rl[j++] / pk; if (j == size) j = 0; } } else { memcpy((void *)window, (void *)rl, size * sizeof(mus_float_t)); } free(rl); free(im); } #else mus_error(MUS_NO_SUCH_FFT_WINDOW, S_make_fft_window ": Dolph-Chebyshev, Samaraki, and Ultraspherical windows need complex trig support"); #endif #endif break; default: mus_error(MUS_NO_SUCH_FFT_WINDOW, S_make_fft_window ": unknown fft data window: %d", (int)type); break; } return(window); } mus_float_t *mus_make_fft_window(mus_fft_window_t type, mus_long_t size, mus_float_t beta) { return(mus_make_fft_window_with_window(type, size, beta, 0.0, (mus_float_t *)calloc(size, sizeof(mus_float_t)))); } static const char *fft_window_names[MUS_NUM_FFT_WINDOWS] = {"Rectangular", "Hann", "Welch", "Parzen", "Bartlett", "Hamming", "Blackman2", "Blackman3", "Blackman4", "Exponential", "Riemann", "Kaiser", "Cauchy", "Poisson", "Gaussian", "Tukey", "Dolph-Chebyshev", "Hann-Poisson", "Connes", "Samaraki", "Ultraspherical", "Bartlett-Hann", "Bohman", "Flat-top", "Blackman5", "Blackman6", "Blackman7", "Blackman8", "Blackman9", "Blackman10", "Rife-Vincent2", "Rife-Vincent3", "Rife-Vincent4", "MLT Sine", "Papoulis", "DPSS (Slepian)", "Sinc" }; const char *mus_fft_window_name(mus_fft_window_t win) { if (mus_is_fft_window((int)win)) return(fft_window_names[(int)win]); return("unknown"); } const char **mus_fft_window_names(void) { return(fft_window_names); } mus_float_t *mus_spectrum(mus_float_t *rdat, mus_float_t *idat, mus_float_t *window, mus_long_t n, mus_spectrum_t type) { mus_long_t i; mus_float_t maxa, lowest; if (window) { for (i = 0; i < n; i++) rdat[i] *= window[i]; } memset((void *)idat, 0, n * sizeof(mus_float_t)); mus_fft(rdat, idat, n, 1); lowest = 0.000001; maxa = 0.0; n = n / 2; for (i = 0; i < n; i++) { mus_float_t val; val = rdat[i] * rdat[i] + idat[i] * idat[i]; if (val < lowest) rdat[i] = 0.001; else { rdat[i] = sqrt(val); if (rdat[i] > maxa) maxa = rdat[i]; } } if (maxa > 0.0) { maxa = 1.0 / maxa; if (type == MUS_SPECTRUM_IN_DB) { mus_float_t todb; todb = 20.0 / log(10.0); for (i = 0; i < n; i++) rdat[i] = todb * log(rdat[i] * maxa); } else { if (type == MUS_SPECTRUM_NORMALIZED) for (i = 0; i < n; i++) rdat[i] *= maxa; } } return(rdat); } mus_float_t *mus_autocorrelate(mus_float_t *data, mus_long_t n) { mus_float_t *im; mus_float_t fscl; mus_long_t i, n2; n2 = n / 2; fscl = 1.0 / (mus_float_t)n; im = (mus_float_t *)calloc(n, sizeof(mus_float_t)); mus_fft(data, im, n, 1); for (i = 0; i < n; i++) data[i] = data[i] * data[i] + im[i] * im[i]; memset((void *)im, 0, n * sizeof(mus_float_t)); mus_fft(data, im, n, -1); for (i = 0; i <= n2; i++) data[i] *= fscl; for (i = n2 + 1; i < n; i++) data[i] = 0.0; free(im); return(data); } mus_float_t *mus_correlate(mus_float_t *data1, mus_float_t *data2, mus_long_t n) { mus_float_t *im1, *im2; mus_long_t i; mus_float_t fscl; im1 = (mus_float_t *)calloc(n, sizeof(mus_float_t)); im2 = (mus_float_t *)calloc(n, sizeof(mus_float_t)); mus_fft(data1, im1, n, 1); mus_fft(data2, im2, n, 1); for (i = 0; i < n; i++) { mus_float_t tmp1, tmp2, tmp3, tmp4; tmp1 = data1[i] * data2[i]; tmp2 = im1[i] * im2[i]; tmp3 = data1[i] * im2[i]; tmp4 = data2[i] * im1[i]; data1[i] = tmp1 + tmp2; im1[i] = tmp3 - tmp4; } mus_fft(data1, im1, n, -1); fscl = 1.0 / (mus_float_t)n; for (i = 0; i < n; i++) data1[i] *= fscl; free(im1); free(im2); return(data1); } mus_float_t *mus_cepstrum(mus_float_t *data, mus_long_t n) { mus_float_t *rl, *im; mus_float_t fscl, lowest; mus_long_t i; lowest = 0.00000001; fscl = 2.0 / (mus_float_t)n; rl = (mus_float_t *)malloc(n * sizeof(mus_float_t)); im = (mus_float_t *)calloc(n, sizeof(mus_float_t)); memcpy((void *)rl, (void *)data, n * sizeof(mus_float_t)); mus_fft(rl, im, n, 1); for (i = 0; i < n; i++) { rl[i] = rl[i] * rl[i] + im[i] * im[i]; if (rl[i] < lowest) rl[i] = -10.0; else rl[i] = log(sqrt(rl[i])); } memset((void *)im, 0, n * sizeof(mus_float_t)); mus_fft(rl, im, n, -1); for (i = 0; i < n; i++) if (fabs(rl[i]) > fscl) fscl = fabs(rl[i]); if (fscl > 0.0) for (i = 0; i < n; i++) data[i] = rl[i] / fscl; free(rl); free(im); return(data); } /* ---------------- convolve ---------------- */ mus_float_t *mus_convolution(mus_float_t *rl1, mus_float_t *rl2, mus_long_t n) { /* convolves two real arrays. * rl1 and rl2 are assumed to be set up correctly for the convolution * (that is, rl1 (the "signal") is zero-padded by length of * (non-zero part of) rl2 and rl2 is stored in wrap-around order) * We treat rl2 as the imaginary part of the first fft, then do * the split, scaling, and (complex) spectral multiply in one step. * result in rl1 */ mus_long_t j, n2; mus_float_t invn; mus_fft(rl1, rl2, n, 1); n2 = n >> 1; invn = 0.25 / (mus_float_t)n; rl1[0] = ((rl1[0] * rl2[0]) / (mus_float_t)n); rl2[0] = 0.0; for (j = 1; j <= n2; j++) { mus_long_t nn2; mus_float_t rem, rep, aim, aip; nn2 = n - j; rep = (rl1[j] + rl1[nn2]); rem = (rl1[j] - rl1[nn2]); aip = (rl2[j] + rl2[nn2]); aim = (rl2[j] - rl2[nn2]); rl1[j] = invn * (rep * aip + aim * rem); rl2[j] = invn * (aim * aip - rep * rem); rl1[nn2] = rl1[j]; rl2[nn2] = -rl2[j]; } mus_fft(rl1, rl2, n, -1); return(rl1); } typedef struct { mus_any_class *core; mus_float_t (*feeder)(void *arg, int direction); mus_float_t (*block_feeder)(void *arg, int direction, mus_float_t *block, mus_long_t start, mus_long_t end); mus_long_t fftsize, fftsize2, ctr, filtersize; mus_float_t *rl1, *rl2, *buf, *filter; void *closure; } conv; static bool convolve_equalp(mus_any *p1, mus_any *p2) {return(p1 == p2);} static char *describe_convolve(mus_any *ptr) { conv *gen = (conv *)ptr; char *describe_buffer; describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE); snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s size: %lld", mus_name(ptr), gen->fftsize); return(describe_buffer); } static void free_convolve(mus_any *ptr) { conv *gen = (conv *)ptr; if (gen->rl1) free(gen->rl1); if (gen->rl2) free(gen->rl2); if (gen->buf) free(gen->buf); free(gen); } static mus_any *conv_copy(mus_any *ptr) { conv *g, *p; int bytes; p = (conv *)ptr; g = (conv *)malloc(sizeof(conv)); memcpy((void *)g, (void *)ptr, sizeof(conv)); bytes = g->fftsize * sizeof(mus_float_t); g->rl1 = (mus_float_t *)malloc(bytes); memcpy((void *)(g->rl1), (void *)(p->rl1), bytes); g->rl2 = (mus_float_t *)malloc(bytes); memcpy((void *)(g->rl2), (void *)(p->rl2), bytes); g->buf = (mus_float_t *)malloc(bytes); memcpy((void *)(g->buf), (void *)(p->buf), bytes); return((mus_any *)g); } static mus_long_t conv_length(mus_any *ptr) {return(((conv *)ptr)->fftsize);} static mus_float_t run_convolve(mus_any *ptr, mus_float_t unused1, mus_float_t unused2) {return(mus_convolve(ptr, NULL));} static void *conv_closure(mus_any *rd) {return(((conv *)rd)->closure);} static void *conv_set_closure(mus_any *rd, void *e) {((conv *)rd)->closure = e; return(e);} static void convolve_reset(mus_any *ptr) { conv *gen = (conv *)ptr; gen->ctr = gen->fftsize2; memset((void *)(gen->rl1), 0, gen->fftsize * sizeof(mus_float_t)); memset((void *)(gen->rl2), 0, gen->fftsize * sizeof(mus_float_t)); memset((void *)(gen->buf), 0, gen->fftsize * sizeof(mus_float_t)); } static mus_any_class CONVOLVE_CLASS = { MUS_CONVOLVE, (char *)S_convolve, &free_convolve, &describe_convolve, &convolve_equalp, 0, 0, &conv_length, 0, 0, 0, 0, 0, 0, 0, 0, 0, &run_convolve, MUS_NOT_SPECIAL, &conv_closure, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &convolve_reset, &conv_set_closure, &conv_copy }; mus_float_t mus_convolve(mus_any *ptr, mus_float_t (*input)(void *arg, int direction)) { conv *gen = (conv *)ptr; mus_float_t result; if (gen->ctr >= gen->fftsize2) { mus_long_t i, N; size_t bytes; N = gen->fftsize2; bytes = N * sizeof(mus_float_t); if (input) {gen->feeder = input; gen->block_feeder = NULL;} memset((void *)(gen->rl2), 0, bytes * 2); memcpy((void *)(gen->rl2), (void *)(gen->filter), gen->filtersize * sizeof(mus_float_t)); memcpy((void *)(gen->buf), (void *)(gen->buf + N), bytes); memset((void *)(gen->buf + N), 0, bytes); memset((void *)(gen->rl1 + N), 0, bytes); if (gen->block_feeder) gen->block_feeder(gen->closure, 1, gen->rl1, 0, N); else { for (i = 0; i < N;) { gen->rl1[i] = gen->feeder(gen->closure, 1); i++; gen->rl1[i] = gen->feeder(gen->closure, 1); i++; } } mus_convolution(gen->rl1, gen->rl2, gen->fftsize); for (i = 0; i < N;) { gen->buf[i] += gen->rl1[i]; i++; gen->buf[i] += gen->rl1[i]; i++; } memcpy((void *)(gen->buf + N), (void *)(gen->rl1 + N), bytes); gen->ctr = 0; } result = gen->buf[gen->ctr]; gen->ctr++; return(result); } bool mus_is_convolve(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_CONVOLVE)); } mus_any *mus_make_convolve(mus_float_t (*input)(void *arg, int direction), mus_float_t *filter, mus_long_t fftsize, mus_long_t filtersize, void *closure) { conv *gen = NULL; gen = (conv *)malloc(sizeof(conv)); gen->core = &CONVOLVE_CLASS; gen->feeder = input; gen->block_feeder = NULL; gen->closure = closure; gen->filter = filter; if (filter) { mus_long_t i; bool all_zero = true; for (i = 0; i < filtersize; i++) if (fabs(filter[i]) != 0.0) /* I'm getting -0.000 != 0.000 */ { all_zero = false; break; } if (all_zero) mus_print("make_convolve: filter contains only 0.0."); } gen->filtersize = filtersize; gen->fftsize = fftsize; gen->fftsize2 = gen->fftsize / 2; gen->ctr = gen->fftsize2; gen->rl1 = (mus_float_t *)malloc(fftsize * sizeof(mus_float_t)); gen->rl2 = (mus_float_t *)malloc(fftsize * sizeof(mus_float_t)); gen->buf = (mus_float_t *)calloc(fftsize, sizeof(mus_float_t)); return((mus_any *)gen); } void mus_convolve_files(const char *file1, const char *file2, mus_float_t maxamp, const char *output_file) { mus_long_t file1_len, file2_len, outlen, totallen; int file1_chans, file2_chans, output_chans; mus_float_t *data1, *data2; const char *errmsg = NULL; mus_float_t maxval = 0.0; mus_long_t i, fftlen; file1_len = mus_sound_framples(file1); file2_len = mus_sound_framples(file2); if ((file1_len <= 0) || (file2_len <= 0)) return; file1_chans = mus_sound_chans(file1); if (file1_chans <= 0) mus_error(MUS_NO_CHANNELS, S_convolve_files ": %s chans: %d", file1, file1_chans); file2_chans = mus_sound_chans(file2); if (file2_chans <= 0) mus_error(MUS_NO_CHANNELS, S_convolve_files ": %s chans: %d", file2, file2_chans); output_chans = file1_chans; if (file2_chans > output_chans) output_chans = file2_chans; fftlen = (mus_long_t)(pow(2.0, (int)ceil(log(file1_len + file2_len + 1) / log(2.0)))); outlen = file1_len + file2_len + 1; totallen = outlen * output_chans; data1 = (mus_float_t *)calloc(fftlen, sizeof(mus_float_t)); data2 = (mus_float_t *)calloc(fftlen, sizeof(mus_float_t)); if (output_chans == 1) { mus_float_t *samps; samps = (mus_float_t *)calloc(fftlen, sizeof(mus_float_t)); mus_file_to_array(file1, 0, 0, file1_len, samps); for (i = 0; i < file1_len; i++) data1[i] = samps[i]; mus_file_to_array(file2, 0, 0, file2_len, samps); for (i = 0; i < file2_len; i++) data2[i] = samps[i]; mus_convolution(data1, data2, fftlen); for (i = 0; i < outlen; i++) if (maxval < fabs(data1[i])) maxval = fabs(data1[i]); if (maxval > 0.0) { maxval = maxamp / maxval; for (i = 0; i < outlen; i++) data1[i] *= maxval; } for (i = 0; i < outlen; i++) samps[i] = data1[i]; errmsg = mus_array_to_file_with_error(output_file, samps, outlen, mus_sound_srate(file1), 1); free(samps); } else { mus_float_t *samps; mus_float_t *outdat = NULL; int c1 = 0, c2 = 0, chan; samps = (mus_float_t *)calloc(totallen, sizeof(mus_float_t)); outdat = (mus_float_t *)malloc(totallen * sizeof(mus_float_t)); for (chan = 0; chan < output_chans; chan++) { mus_long_t j, k; mus_file_to_array(file1, c1, 0, file1_len, samps); for (k = 0; k < file1_len; k++) data1[k] = samps[k]; mus_file_to_array(file2, c2, 0, file2_len, samps); for (k = 0; k < file2_len; k++) data2[k] = samps[k]; mus_convolution(data1, data2, fftlen); for (j = chan, k = 0; j < totallen; j += output_chans, k++) outdat[j] = data1[k]; c1++; if (c1 >= file1_chans) c1 = 0; c2++; if (c2 >= file2_chans) c2 = 0; memset((void *)data1, 0, fftlen * sizeof(mus_float_t)); memset((void *)data2, 0, fftlen * sizeof(mus_float_t)); } for (i = 0; i < totallen; i++) if (maxval < fabs(outdat[i])) maxval = fabs(outdat[i]); if (maxval > 0.0) { maxval = maxamp / maxval; for (i = 0; i < totallen; i++) outdat[i] *= maxval; } for (i = 0; i < totallen; i++) samps[i] = outdat[i]; errmsg = mus_array_to_file_with_error(output_file, samps, totallen, mus_sound_srate(file1), output_chans); free(samps); free(outdat); } free(data1); free(data2); if (errmsg) mus_error(MUS_CANT_OPEN_FILE, S_convolve_files ": %s", errmsg); } /* ---------------- phase-vocoder ---------------- */ typedef struct { mus_any_class *core; mus_float_t pitch; mus_float_t (*input)(void *arg, int direction); mus_float_t (*block_input)(void *arg, int direction, mus_float_t *block, mus_long_t start, mus_long_t end); void *closure; bool (*analyze)(void *arg, mus_float_t (*input)(void *arg1, int direction)); int (*edit)(void *arg); mus_float_t (*synthesize)(void *arg); int outctr, interp, filptr, N, D, topN; mus_float_t *win, *ampinc, *amps, *freqs, *phases, *phaseinc, *lastphase, *in_data; mus_float_t sum1; bool calc; #if HAVE_SINCOS double *cs, *sn; bool *sc_safe; int *indices; #endif } pv_info; bool mus_is_phase_vocoder(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_PHASE_VOCODER)); } static bool phase_vocoder_equalp(mus_any *p1, mus_any *p2) {return(p1 == p2);} static char *describe_phase_vocoder(mus_any *ptr) { char *arr = NULL; pv_info *gen = (pv_info *)ptr; char *describe_buffer; describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE); snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s outctr: %d, interp: %d, filptr: %d, N: %d, D: %d, in_data: %s", mus_name(ptr), gen->outctr, gen->interp, gen->filptr, gen->N, gen->D, arr = float_array_to_string(gen->in_data, gen->N, 0)); if (arr) free(arr); return(describe_buffer); } static void free_phase_vocoder(mus_any *ptr) { pv_info *gen = (pv_info *)ptr; if (gen->in_data) free(gen->in_data); if (gen->amps) free(gen->amps); if (gen->freqs) free(gen->freqs); if (gen->phases) free(gen->phases); if (gen->win) free(gen->win); if (gen->phaseinc) free(gen->phaseinc); if (gen->lastphase) free(gen->lastphase); if (gen->ampinc) free(gen->ampinc); #if HAVE_SINCOS if (gen->indices) free(gen->indices); if (gen->sn) free(gen->sn); if (gen->cs) free(gen->cs); if (gen->sc_safe) free(gen->sc_safe); #endif free(gen); } static mus_any *pv_info_copy(mus_any *ptr) { pv_info *g, *p; int bytes; p = (pv_info *)ptr; g = (pv_info *)malloc(sizeof(pv_info)); memcpy((void *)g, (void *)ptr, sizeof(pv_info)); bytes = p->N * sizeof(mus_float_t); g->freqs = (mus_float_t *)malloc(bytes); memcpy((void *)(g->freqs), (void *)(p->freqs), bytes); g->ampinc = (mus_float_t *)malloc(bytes); memcpy((void *)(g->ampinc), (void *)(p->ampinc), bytes); g->win = (mus_float_t *)malloc(bytes); memcpy((void *)(g->win), (void *)(p->win), bytes); if (p->in_data) { g->in_data = (mus_float_t *)malloc(bytes); memcpy((void *)(g->in_data), (void *)(p->in_data), bytes); } bytes = (p->N / 2) * sizeof(mus_float_t); g->amps = (mus_float_t *)malloc(bytes); memcpy((void *)(g->amps), (void *)(p->amps), bytes); g->phases = (mus_float_t *)malloc(bytes); memcpy((void *)(g->phases), (void *)(p->phases), bytes); g->lastphase = (mus_float_t *)malloc(bytes); memcpy((void *)(g->lastphase), (void *)(p->lastphase), bytes); g->phaseinc = (mus_float_t *)malloc(bytes); memcpy((void *)(g->phaseinc), (void *)(p->phaseinc), bytes); #if HAVE_SINCOS bytes = (p->N / 2) * sizeof(int); g->indices = (int *)malloc(bytes); memcpy((void *)(g->indices), (void *)(p->indices), bytes); bytes = p->N * sizeof(double); g->sn = (double *)malloc(bytes); memcpy((void *)(g->sn), (void *)(p->sn), bytes); g->cs = (double *)malloc(bytes); memcpy((void *)(g->cs), (void *)(p->cs), bytes); bytes = p->N * sizeof(bool); g->sc_safe = (bool *)malloc(bytes); memcpy((void *)(g->sc_safe), (void *)(p->sc_safe), bytes); #endif return((mus_any *)g); } static mus_long_t pv_length(mus_any *ptr) {return(((pv_info *)ptr)->N);} static mus_long_t pv_hop(mus_any *ptr) {return(((pv_info *)ptr)->D);} static mus_long_t pv_set_hop(mus_any *ptr, mus_long_t val) {((pv_info *)ptr)->D = (int)val; return(val);} static mus_float_t pv_frequency(mus_any *ptr) {return(((pv_info *)ptr)->pitch);} static mus_float_t pv_set_frequency(mus_any *ptr, mus_float_t val) {((pv_info *)ptr)->pitch = val; return(val);} static void *pv_closure(mus_any *rd) {return(((pv_info *)rd)->closure);} static void *pv_set_closure(mus_any *rd, void *e) {((pv_info *)rd)->closure = e; return(e);} mus_float_t *mus_phase_vocoder_amp_increments(mus_any *ptr) {return(((pv_info *)ptr)->ampinc);} mus_float_t *mus_phase_vocoder_amps(mus_any *ptr) {return(((pv_info *)ptr)->amps);} mus_float_t *mus_phase_vocoder_freqs(mus_any *ptr) {return(((pv_info *)ptr)->freqs);} mus_float_t *mus_phase_vocoder_phases(mus_any *ptr) {return(((pv_info *)ptr)->phases);} mus_float_t *mus_phase_vocoder_phase_increments(mus_any *ptr) {return(((pv_info *)ptr)->phaseinc);} static mus_long_t pv_outctr(mus_any *ptr) {return((mus_long_t)(((pv_info *)ptr)->outctr));} /* mus_location wrapper */ static mus_long_t pv_set_outctr(mus_any *ptr, mus_long_t val) {((pv_info *)ptr)->outctr = (int)val; return(val);} static mus_float_t run_phase_vocoder(mus_any *ptr, mus_float_t unused1, mus_float_t unused2) {return(mus_phase_vocoder(ptr, NULL));} static mus_float_t pv_increment(mus_any *rd) {return((mus_float_t)(((pv_info *)rd)->interp));} static mus_float_t pv_set_increment(mus_any *rd, mus_float_t val) {((pv_info *)rd)->interp = (int)val; return(val);} static void pv_reset(mus_any *ptr) { pv_info *gen = (pv_info *)ptr; if (gen->in_data) free(gen->in_data); gen->in_data = NULL; gen->outctr = gen->interp; gen->filptr = 0; memset((void *)(gen->ampinc), 0, gen->N * sizeof(mus_float_t)); memset((void *)(gen->freqs), 0, gen->N * sizeof(mus_float_t)); memset((void *)(gen->amps), 0, (gen->N / 2) * sizeof(mus_float_t)); memset((void *)(gen->phases), 0, (gen->N / 2) * sizeof(mus_float_t)); memset((void *)(gen->lastphase), 0, (gen->N / 2) * sizeof(mus_float_t)); memset((void *)(gen->phaseinc), 0, (gen->N / 2) * sizeof(mus_float_t)); } static mus_any_class PHASE_VOCODER_CLASS = { MUS_PHASE_VOCODER, (char *)S_phase_vocoder, &free_phase_vocoder, &describe_phase_vocoder, &phase_vocoder_equalp, 0, 0, &pv_length, 0, &pv_frequency, &pv_set_frequency, 0, 0, 0, 0, &pv_increment, &pv_set_increment, &run_phase_vocoder, MUS_NOT_SPECIAL, &pv_closure, 0, 0, 0, 0, 0, 0, 0, &pv_hop, &pv_set_hop, 0, 0, 0, 0, 0, 0, &pv_outctr, &pv_set_outctr, 0, 0, 0, 0, 0, &pv_reset, &pv_set_closure, &pv_info_copy }; static int pv_last_fftsize = -1; static mus_float_t *pv_last_window = NULL; mus_any *mus_make_phase_vocoder(mus_float_t (*input)(void *arg, int direction), int fftsize, int overlap, int interp, mus_float_t pitch, bool (*analyze)(void *arg, mus_float_t (*input)(void *arg1, int direction)), int (*edit)(void *arg), mus_float_t (*synthesize)(void *arg), void *closure) { /* order of args is trying to match src, granulate etc * the inclusion of pitch and interp provides built-in time/pitch scaling which is 99% of phase-vocoder use */ pv_info *pv; int N2, D; N2 = (int)(fftsize / 2); if (N2 == 0) return(NULL); D = fftsize / overlap; if (D == 0) return(NULL); pv = (pv_info *)malloc(sizeof(pv_info)); pv->core = &PHASE_VOCODER_CLASS; pv->N = fftsize; pv->D = D; pv->topN = 0; pv->interp = interp; pv->outctr = interp; pv->filptr = 0; pv->pitch = pitch; pv->ampinc = (mus_float_t *)malloc(fftsize * sizeof(mus_float_t)); pv->freqs = (mus_float_t *)malloc(fftsize * sizeof(mus_float_t)); pv->amps = (mus_float_t *)calloc(N2, sizeof(mus_float_t)); pv->phases = (mus_float_t *)calloc(N2, sizeof(mus_float_t)); pv->lastphase = (mus_float_t *)calloc(N2, sizeof(mus_float_t)); pv->phaseinc = (mus_float_t *)calloc(N2, sizeof(mus_float_t)); pv->in_data = NULL; pv->input = input; pv->block_input = NULL; pv->closure = closure; pv->analyze = analyze; pv->edit = edit; pv->synthesize = synthesize; pv->calc = true; if ((fftsize == pv_last_fftsize) && (pv_last_window)) { pv->win = (mus_float_t *)malloc(fftsize * sizeof(mus_float_t)); memcpy((void *)(pv->win), (const void *)pv_last_window, fftsize * sizeof(mus_float_t)); } else { int i; mus_float_t scl; if (pv_last_window) free(pv_last_window); pv_last_fftsize = fftsize; pv_last_window = (mus_float_t *)malloc(fftsize * sizeof(mus_float_t)); pv->win = mus_make_fft_window(MUS_HAMMING_WINDOW, fftsize, 0.0); scl = 2.0 / (0.54 * (mus_float_t)fftsize); for (i = 0; i < fftsize; i++) pv->win[i] *= scl; memcpy((void *)pv_last_window, (const void *)(pv->win), fftsize * sizeof(mus_float_t)); } #if HAVE_SINCOS /* in some cases, sincos is slower than sin+cos? Callgrind is seriously confused by it! * in Linux at least, sincos is faster than sin+sin -- in my timing tests, although * callgrind is crazy, the actual runtimes are about 25% faster (sincos vs sin+sin). */ pv->cs = (double *)malloc(fftsize * sizeof(double)); pv->sn = (double *)malloc(fftsize * sizeof(double)); pv->sc_safe = (bool *)calloc(fftsize, sizeof(bool)); pv->indices = (int *)malloc(N2 * sizeof(int)); #endif return((mus_any *)pv); } mus_float_t mus_phase_vocoder_with_editors(mus_any *ptr, mus_float_t (*input)(void *arg, int direction), bool (*analyze)(void *arg, mus_float_t (*input)(void *arg1, int direction)), int (*edit)(void *arg), mus_float_t (*synthesize)(void *arg)) { pv_info *pv = (pv_info *)ptr; int N2, i; mus_float_t sum, sum1; mus_float_t (*pv_synthesize)(void *arg) = synthesize; if (pv_synthesize == NULL) pv_synthesize = pv->synthesize; N2 = pv->N / 2; if (pv->outctr >= pv->interp) { mus_float_t scl; bool (*pv_analyze)(void *arg, mus_float_t (*input)(void *arg1, int direction)) = analyze; int (*pv_edit)(void *arg) = edit; if (pv_analyze == NULL) pv_analyze = pv->analyze; if (pv_edit == NULL) pv_edit = pv->edit; if (input) {pv->input = input; pv->block_input = NULL;} pv->outctr = 0; if ((pv_analyze == NULL) || ((*pv_analyze)(pv->closure, pv->input))) { int buf; memset((void *)(pv->freqs), 0, pv->N * sizeof(mus_float_t)); if (pv->in_data == NULL) { pv->in_data = (mus_float_t *)malloc(pv->N * sizeof(mus_float_t)); if (pv->block_input) pv->block_input(pv->closure, 1, pv->in_data, 0, pv->N); else { for (i = 0; i < pv->N; i++) pv->in_data[i] = pv->input(pv->closure, 1); } } else { int j; /* if back-to-back here we could omit a lot of data movement or just use a circle here! */ for (i = 0, j = pv->D; j < pv->N; i++, j++) pv->in_data[i] = pv->in_data[j]; if (pv->block_input) pv->block_input(pv->closure, 1, pv->in_data, pv->N - pv->D, pv->N); else { for (i = pv->N - pv->D; i < pv->N; i++) pv->in_data[i] = pv->input(pv->closure, 1); } } buf = pv->filptr % pv->N; for (i = 0; i < pv->N; i++) { pv->ampinc[buf++] = pv->win[i] * pv->in_data[i]; if (buf >= pv->N) buf = 0; } pv->filptr += pv->D; mus_fft(pv->ampinc, pv->freqs, pv->N, 1); mus_rectangular_to_polar(pv->ampinc, pv->freqs, N2); } if ((pv_edit == NULL) || ((*pv_edit)(pv->closure))) { mus_float_t pscl, kscl, ks; pscl = 1.0 / (mus_float_t)(pv->D); kscl = TWO_PI / (mus_float_t)(pv->N); for (i = 0, ks = 0.0; i < N2; i++, ks += kscl) { mus_float_t diff; diff = pv->freqs[i] - pv->lastphase[i]; pv->lastphase[i] = pv->freqs[i]; while (diff > M_PI) diff -= TWO_PI; while (diff < -M_PI) diff += TWO_PI; pv->freqs[i] = pv->pitch * (diff * pscl + ks); } } /* it's possible to build the endpoint waveforms here and interpolate, but there is no savings. * other pvocs use ifft rather than sin-bank, but then they have to make excuses. * Something I didn't expect -- the algorithm above focusses on the active frequency! * For example, the 4 or so bins around a given peak all tighten * to 4 bins running at almost exactly the same frequency (the center). */ scl = 1.0 / (mus_float_t)(pv->interp); #if HAVE_SINCOS pv->topN = 0; #else pv->topN = N2; #endif for (i = 0; i < N2; i++) { #if HAVE_SINCOS double s, c; bool amp_zero; amp_zero = ((pv->amps[i] < 1e-7) && (pv->ampinc[i] == 0.0)); if (!amp_zero) { pv->indices[pv->topN++] = i; pv->sc_safe[i] = (fabs(pv->freqs[i] - pv->phaseinc[i]) < 0.02); /* .5 is too big, .01 and .03 ok by tests */ if (pv->sc_safe[i]) { sincos((pv->freqs[i] + pv->phaseinc[i]) * 0.5, &s, &c); pv->sn[i] = s; pv->cs[i] = c; } } if ((!(pv->synthesize)) && (amp_zero)) { pv->phases[i] += (pv->interp * (pv->freqs[i] + pv->phaseinc[i]) * 0.5); pv->phaseinc[i] = pv->freqs[i]; } else { pv->ampinc[i] = scl * (pv->ampinc[i] - pv->amps[i]); pv->freqs[i] = scl * (pv->freqs[i] - pv->phaseinc[i]); } #else pv->ampinc[i] = scl * (pv->ampinc[i] - pv->amps[i]); pv->freqs[i] = scl * (pv->freqs[i] - pv->phaseinc[i]); #endif } } pv->outctr++; if (pv_synthesize) return((*pv_synthesize)(pv->closure)); if (pv->calc) { mus_float_t *pinc, *frq, *ph, *amp, *panc; int topN; #if HAVE_SINCOS int j; double *cs, *sn; #endif topN = pv->topN; pinc = pv->phaseinc; frq = pv->freqs; ph = pv->phases; amp = pv->amps; panc = pv->ampinc; #if HAVE_SINCOS cs = pv->cs; sn = pv->sn; #endif sum = 0.0; sum1 = 0.0; /* amps can be negative here due to rounding troubles * sincos is faster (using shell time command) except in virtualbox running linux on a mac? * (callgrind does not handle sincos correctly). * * this version (22-Jan-14) is slower if no sincos; * if sincos, we use sin(a + b) = sin(a)cos(b) + cos(a)sin(b) * since sin(b) and cos(b) are constant through the pv->interp (implicit) loop, they are calculated once above. * Then here we calculate 2 samples on each run through this loop. I wonder if we could center the true case, * and get 3 samples? If 2, the difference is very small (we're taking the midpoint of the phase increment change, * so the two are not quite the same). In tests, 10000 samples, channel-distance is ca .15. * * If the amp zero phase is off (incorrectly incremented above), the effect is a sort of low-pass filter?? * Are we getting cancellation from the overlap? */ #if HAVE_SINCOS for (j = 0; j < topN; j++) { double sx, cx; i = pv->indices[j]; pinc[i] += frq[i]; ph[i] += pinc[i]; amp[i] += panc[i]; sincos(ph[i], &sx, &cx); sum += (amp[i] * sx); pinc[i] += frq[i]; ph[i] += pinc[i]; amp[i] += panc[i]; if (pv->sc_safe[i]) sum1 += amp[i] * (sx * cs[i] + cx * sn[i]); else sum1 += amp[i] * sin(ph[i]); } #else for (i = 0; i < topN; i++) { pinc[i] += frq[i]; ph[i] += pinc[i]; amp[i] += panc[i]; if (amp[i] > 0.0) sum += amp[i] * sin(ph[i]); pinc[i] += frq[i]; ph[i] += pinc[i]; amp[i] += panc[i]; if (amp[i] > 0.0) sum1 += amp[i] * sin(ph[i]); } #endif pv->sum1 = sum1; pv->calc = false; return(sum); } pv->calc = true; return(pv->sum1); } mus_float_t mus_phase_vocoder(mus_any *ptr, mus_float_t (*input)(void *arg, int direction)) { return(mus_phase_vocoder_with_editors(ptr, input, NULL, NULL, NULL)); } void mus_generator_set_feeders(mus_any *g, mus_float_t (*feed)(void *arg, int direction), mus_float_t (*block_feed)(void *arg, int direction, mus_float_t *block, mus_long_t start, mus_long_t end)) { if (mus_is_src(g)) { ((sr *)g)->feeder = feed; ((sr *)g)->block_feeder = block_feed; } else { if (mus_is_granulate(g)) { ((grn_info *)g)->rd = feed; ((grn_info *)g)->block_rd = block_feed; } else { if (mus_is_phase_vocoder(g)) { ((pv_info *)g)->input = feed; ((pv_info *)g)->block_input = block_feed; } else { if (mus_is_convolve(g)) { ((conv *)g)->feeder = feed; ((conv *)g)->block_feeder = block_feed; } } } } } void mus_generator_copy_feeders(mus_any *dest, mus_any *source) { if (mus_is_src(dest)) { ((sr *)dest)->feeder = ((sr *)source)->feeder; ((sr *)dest)->block_feeder = ((sr *)source)->block_feeder; } else { if (mus_is_granulate(dest)) { ((grn_info *)dest)->rd = ((grn_info *)source)->rd; ((grn_info *)dest)->block_rd = ((grn_info *)source)->block_rd; } else { if (mus_is_phase_vocoder(dest)) { ((pv_info *)dest)->input = ((pv_info *)source)->input; ((pv_info *)dest)->block_input = ((pv_info *)source)->block_input; } else { if (mus_is_convolve(dest)) { ((conv *)dest)->feeder = ((conv *)source)->feeder; ((conv *)dest)->block_feeder = ((conv *)source)->block_feeder; } } } } } /* ---------------- single sideband "suppressed carrier" amplitude modulation (ssb-am) ---------------- */ typedef struct { mus_any_class *core; bool shift_up; mus_float_t *coeffs; mus_any *hilbert, *dly; #if (!HAVE_SINCOS) mus_any *sin_osc, *cos_osc; #else double phase, freq, sign; #endif int size; } ssbam; bool mus_is_ssb_am(mus_any *ptr) { return((ptr) && (ptr->core->type == MUS_SSB_AM)); } static mus_float_t run_hilbert(flt *gen, mus_float_t input) { mus_float_t xout = 0.0; mus_float_t *state, *ts, *x, *end; x = (mus_float_t *)(gen->x); state = (mus_float_t *)(gen->state + gen->loc); ts = (mus_float_t *)(state + gen->order); (*state) = input; (*ts) = input; state += 2; end = (mus_float_t *)(state + 20); while (ts > end) { xout += (*ts) * (*x); ts -= 2; x += 2; xout += (*ts) * (*x); ts -= 2; x += 2; xout += (*ts) * (*x); ts -= 2; x += 2; xout += (*ts) * (*x); ts -= 2; x += 2; xout += (*ts) * (*x); ts -= 2; x += 2; xout += (*ts) * (*x); ts -= 2; x += 2; xout += (*ts) * (*x); ts -= 2; x += 2; xout += (*ts) * (*x); ts -= 2; x += 2; xout += (*ts) * (*x); ts -= 2; x += 2; xout += (*ts) * (*x); ts -= 2; x += 2; } while (ts > state) { xout += (*ts) * (*x); ts -= 2; x += 2; } gen->loc++; if (gen->loc == gen->order) gen->loc = 0; return(xout + ((*ts) * (*x))); #if 0 int i, len; mus_float_t val = 0.0; len = g->order; g->state[0] = insig; for (i = 0; i < len; i += 2) val += (g->x[i] * g->state[i]); for (i = len - 1; i >= 1; i--) g->state[i] = g->state[i - 1]; return(val); #endif } mus_float_t mus_ssb_am_unmodulated(mus_any *ptr, mus_float_t insig) { ssbam *gen = (ssbam *)ptr; #if (!HAVE_SINCOS) return((mus_oscil_unmodulated(gen->cos_osc) * mus_delay_unmodulated_noz(gen->dly, insig)) + (mus_oscil_unmodulated(gen->sin_osc) * run_hilbert((flt *)(gen->hilbert), insig))); #else double cx, sx; sincos(gen->phase, &sx, &cx); gen->phase += gen->freq; return((cx * mus_delay_unmodulated_noz(gen->dly, insig)) + (sx * gen->sign * run_hilbert((flt *)(gen->hilbert), insig))); #endif } mus_float_t mus_ssb_am(mus_any *ptr, mus_float_t insig, mus_float_t fm) { ssbam *gen = (ssbam *)ptr; #if (!HAVE_SINCOS) return((mus_oscil_fm(gen->cos_osc, fm) * mus_delay_unmodulated_noz(gen->dly, insig)) + (mus_oscil_fm(gen->sin_osc, fm) * run_hilbert((flt *)(gen->hilbert), insig))); #else double cx, sx; sincos(gen->phase, &sx, &cx); gen->phase += (fm + gen->freq); return((cx * mus_delay_unmodulated_noz(gen->dly, insig)) + (sx * gen->sign * run_hilbert((flt *)(gen->hilbert), insig))); #endif } static void free_ssb_am(mus_any *ptr) { ssbam *gen = (ssbam *)ptr; mus_free(gen->dly); mus_free(gen->hilbert); #if (!HAVE_SINCOS) mus_free(gen->cos_osc); mus_free(gen->sin_osc); #endif if (gen->coeffs) {free(gen->coeffs); gen->coeffs = NULL;} free(ptr); } static mus_any *ssbam_copy(mus_any *ptr) { ssbam *g, *p; int bytes; p = (ssbam *)ptr; g = (ssbam *)malloc(sizeof(ssbam)); memcpy((void *)g, (void *)ptr, sizeof(ssbam)); g->dly = mus_copy(p->dly); g->hilbert = mus_copy(p->hilbert); #if (!HAVE_SINCOS) g->cos_osc = mus_copy(p->cos_osc); g->sin_osc = mus_copy(p->sin_osc); #endif bytes = p->size * sizeof(mus_float_t); g->coeffs = (mus_float_t *)malloc(bytes); memcpy((void *)(g->coeffs), (void *)(p->coeffs), bytes); return((mus_any *)g); } static mus_float_t ssb_am_freq(mus_any *ptr) { #if (!HAVE_SINCOS) return(mus_radians_to_hz(((osc *)((ssbam *)ptr)->sin_osc)->freq)); #else return(mus_radians_to_hz(((ssbam *)ptr)->freq)); #endif } static mus_float_t ssb_am_set_freq(mus_any *ptr, mus_float_t val) { ssbam *gen = (ssbam *)ptr; mus_float_t rads; rads = mus_hz_to_radians(val); #if (!HAVE_SINCOS) ((osc *)(gen->sin_osc))->freq = rads; ((osc *)(gen->cos_osc))->freq = rads; #else gen->freq = rads; #endif return(val); } static mus_float_t ssb_am_increment(mus_any *ptr) { #if (!HAVE_SINCOS) return(((osc *)((ssbam *)ptr)->sin_osc)->freq); #else return(((ssbam *)ptr)->freq); #endif } static mus_float_t ssb_am_set_increment(mus_any *ptr, mus_float_t val) { ssbam *gen = (ssbam *)ptr; #if (!HAVE_SINCOS) ((osc *)(gen->sin_osc))->freq = val; ((osc *)(gen->cos_osc))->freq = val; #else gen->freq = val; #endif return(val); } static mus_float_t ssb_am_phase(mus_any *ptr) { #if (!HAVE_SINCOS) return(fmod(((osc *)((ssbam *)ptr)->cos_osc)->phase - 0.5 * M_PI, TWO_PI)); #else return(fmod(((ssbam *)ptr)->phase, TWO_PI)); #endif } static mus_float_t ssb_am_set_phase(mus_any *ptr, mus_float_t val) { ssbam *gen = (ssbam *)ptr; #if (!HAVE_SINCOS) if (gen->shift_up) ((osc *)(gen->sin_osc))->phase = val + M_PI; else ((osc *)(gen->sin_osc))->phase = val; ((osc *)(gen->cos_osc))->phase = val + 0.5 * M_PI; #else gen->phase = val; #endif return(val); } static mus_long_t ssb_am_order(mus_any *ptr) {return(mus_order(((ssbam *)ptr)->dly));} static int ssb_am_interp_type(mus_any *ptr) {return(delay_interp_type(((ssbam *)ptr)->dly));} static mus_float_t *ssb_am_data(mus_any *ptr) {return(filter_data(((ssbam *)ptr)->hilbert));} static mus_float_t ssb_am_run(mus_any *ptr, mus_float_t insig, mus_float_t fm) {return(mus_ssb_am(ptr, insig, fm));} static mus_float_t *ssb_am_xcoeffs(mus_any *ptr) {return(mus_xcoeffs(((ssbam *)ptr)->hilbert));} static mus_float_t ssb_am_xcoeff(mus_any *ptr, int index) {return(mus_xcoeff(((ssbam *)ptr)->hilbert, index));} static mus_float_t ssb_am_set_xcoeff(mus_any *ptr, int index, mus_float_t val) {return(mus_set_xcoeff(((ssbam *)ptr)->hilbert, index, val));} static bool ssb_am_equalp(mus_any *p1, mus_any *p2) { return((p1 == p2) || ((mus_is_ssb_am((mus_any *)p1)) && (mus_is_ssb_am((mus_any *)p2)) && (((ssbam *)p1)->shift_up == ((ssbam *)p2)->shift_up) && #if (!HAVE_SINCOS) (mus_equalp(((ssbam *)p1)->sin_osc, ((ssbam *)p2)->sin_osc)) && (mus_equalp(((ssbam *)p1)->cos_osc, ((ssbam *)p2)->cos_osc)) && #else (((ssbam *)p1)->freq == ((ssbam *)p2)->freq) && (((ssbam *)p1)->phase == ((ssbam *)p2)->phase) && #endif (mus_equalp(((ssbam *)p1)->dly, ((ssbam *)p2)->dly)) && (mus_equalp(((ssbam *)p1)->hilbert, ((ssbam *)p2)->hilbert)))); } static char *describe_ssb_am(mus_any *ptr) { ssbam *gen = (ssbam *)ptr; char *describe_buffer; describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE); snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s shift: %s, sin/cos: %f Hz (%f radians), order: %d", mus_name(ptr), (gen->shift_up) ? "up" : "down", mus_frequency(ptr), mus_phase(ptr), (int)mus_order(ptr)); return(describe_buffer); } static void ssb_reset(mus_any *ptr) { ssbam *gen = (ssbam *)ptr; ssb_am_set_phase(ptr, 0.0); mus_reset(gen->dly); mus_reset(gen->hilbert); } static mus_any_class SSB_AM_CLASS = { MUS_SSB_AM, (char *)S_ssb_am, &free_ssb_am, &describe_ssb_am, &ssb_am_equalp, &ssb_am_data, 0, &ssb_am_order, 0, &ssb_am_freq, &ssb_am_set_freq, &ssb_am_phase, &ssb_am_set_phase, &fallback_scaler, 0, &ssb_am_increment, &ssb_am_set_increment, &ssb_am_run, MUS_NOT_SPECIAL, NULL, &ssb_am_interp_type, 0, 0, 0, 0, &ssb_am_xcoeff, &ssb_am_set_xcoeff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &ssb_am_xcoeffs, 0, &ssb_reset, 0, &ssbam_copy }; static int ssb_am_last_flen = -1; static mus_float_t *ssb_am_last_coeffs = NULL; mus_any *mus_make_ssb_am(mus_float_t freq, int order) { ssbam *gen; int len, flen; if ((order & 1) == 0) order++; /* if order is even, the first Hilbert coeff is 0.0 */ gen = (ssbam *)malloc(sizeof(ssbam)); gen->core = &SSB_AM_CLASS; if (freq > 0) gen->shift_up = true; else gen->shift_up = false; #if (!HAVE_SINCOS) gen->sin_osc = mus_make_oscil(fabs(freq), (gen->shift_up) ? M_PI : 0.0); gen->cos_osc = mus_make_oscil(fabs(freq), M_PI * 0.5); #else if (gen->shift_up) gen->sign = -1.0; else gen->sign = 1.0; gen->freq = mus_hz_to_radians(fabs(freq)); gen->phase = 0.0; #endif gen->dly = mus_make_delay(order, NULL, order, MUS_INTERP_NONE); len = order * 2 + 1; flen = len + 1; /* even -- need 4 */ if ((flen & 2) != 0) flen += 2; gen->size = flen; if ((flen == ssb_am_last_flen) && (ssb_am_last_coeffs)) { gen->coeffs = (mus_float_t *)malloc(flen * sizeof(mus_float_t)); memcpy((void *)(gen->coeffs), (const void *)ssb_am_last_coeffs, flen * sizeof(mus_float_t)); } else { int i, k; gen->coeffs = (mus_float_t *)calloc(flen, sizeof(mus_float_t)); for (i = -order, k = 0; i <= order; i++, k++) { mus_float_t denom, num; denom = i * M_PI; num = 1.0 - cos(denom); if (i == 0) gen->coeffs[k] = 0.0; else gen->coeffs[k] = (num / denom) * (0.54 + (0.46 * cos(denom / order))); } /* so odd numbered coeffs are zero */ /* can't be too fancy here because there might be several of these gens running in parallel at different sizes */ if (ssb_am_last_coeffs) free(ssb_am_last_coeffs); ssb_am_last_flen = flen; ssb_am_last_coeffs = (mus_float_t *)malloc(flen * sizeof(mus_float_t)); memcpy((void *)(ssb_am_last_coeffs), (const void *)(gen->coeffs), flen * sizeof(mus_float_t)); } gen->hilbert = mus_make_fir_filter(flen, gen->coeffs, NULL); return((mus_any *)gen); } /* (define (hi) (let ((g (make-ssb-am 100.0))) (ssb-am g 1.0) (ssb-am g 0.0))) */ /* ---------------- mus-apply ---------------- */ mus_float_t (*mus_run_function(mus_any *g))(mus_any *gen, mus_float_t arg1, mus_float_t arg2) { if (g) return(g->core->run); return(NULL); } mus_float_t mus_apply(mus_any *gen, mus_float_t f1, mus_float_t f2) { /* what about non-gen funcs such as polynomial, ring_modulate etc? */ if ((gen) && (gen->core->run)) return((*(gen->core->run))(gen, f1, f2)); return(0.0); } /* ---------------- mix files ---------------- */ /* a mixing "instrument" along the lines of the mix function in clm */ /* this is a very commonly used function, so it's worth picking out the special cases for optimization */ #define IDENTITY_MIX 0 #define IDENTITY_MONO_MIX 1 #define SCALED_MONO_MIX 2 #define SCALED_MIX 3 #define ENVELOPED_MONO_MIX 4 #define ENVELOPED_MIX 5 #define ALL_MIX 6 static int mix_file_type(int out_chans, int in_chans, mus_float_t *mx, mus_any ***envs) { if (envs) { if ((in_chans == 1) && (out_chans == 1)) { if (envs[0][0]) return(ENVELOPED_MONO_MIX); return(SCALED_MONO_MIX); } else { if (mx) return(ALL_MIX); return(ENVELOPED_MIX); } } if (mx) { int i, j; if ((in_chans == 1) && (out_chans == 1)) { if (mx[0] == 1.0) return(IDENTITY_MONO_MIX); return(SCALED_MONO_MIX); } for (i = 0; i < out_chans; i++) for (j = 0; j < in_chans; j++) if (((i == j) && (mx[i * in_chans + j] != 1.0)) || ((i != j) && (mx[i * in_chans + j] != 0.0))) return(SCALED_MIX); } if ((in_chans == 1) && (out_chans == 1)) return(IDENTITY_MONO_MIX); return(IDENTITY_MIX); } void mus_file_mix_with_reader_and_writer(mus_any *outf, mus_any *inf, mus_long_t out_start, mus_long_t out_framples, mus_long_t in_start, mus_float_t *mx, int mx_chans, mus_any ***envs) { int mixtype, in_chans, out_chans; mus_long_t inc, outc, out_end; mus_float_t *out_data, *in_data, *local_mx; out_chans = mus_channels(outf); if (out_chans <= 0) mus_error(MUS_NO_CHANNELS, S_mus_file_mix ": %s chans: %d", mus_describe(outf), out_chans); in_chans = mus_channels(inf); if (in_chans <= 0) mus_error(MUS_NO_CHANNELS, S_mus_file_mix ": %s chans: %d", mus_describe(inf), in_chans); out_end = out_start + out_framples; mixtype = mix_file_type(out_chans, in_chans, mx, envs); in_data = (mus_float_t *)calloc((in_chans < out_chans) ? out_chans : in_chans, sizeof(mus_float_t)); out_data = (mus_float_t *)calloc((in_chans < out_chans) ? out_chans : in_chans, sizeof(mus_float_t)); local_mx = mx; switch (mixtype) { case ENVELOPED_MONO_MIX: { mus_any *e; e = envs[0][0]; for (inc = in_start, outc = out_start; outc < out_end; inc++, outc++) { mus_file_to_frample(inf, inc, in_data); mus_outa_to_file(outf, outc, in_data[0] * mus_env(e)); } } break; case ENVELOPED_MIX: if (mx == NULL) { int i; mx_chans = (in_chans < out_chans) ? out_chans : in_chans; local_mx = (mus_float_t *)calloc(mx_chans * mx_chans, sizeof(mus_float_t)); for (i = 0; i < mx_chans; i++) local_mx[i * mx_chans + i] = 1.0; } /* fall through */ case ALL_MIX: /* the general case -- possible envs/scalers on every mixer cell */ for (inc = in_start, outc = out_start; outc < out_end; inc++, outc++) { int j, k; for (j = 0; j < in_chans; j++) for (k = 0; k < out_chans; k++) if (envs[j][k]) local_mx[j * mx_chans + k] = mus_env(envs[j][k]); mus_frample_to_file(outf, outc, mus_frample_to_frample(local_mx, mx_chans, mus_file_to_frample(inf, inc, in_data), in_chans, out_data, out_chans)); } if (mx == NULL) free(local_mx); break; case IDENTITY_MONO_MIX: for (inc = in_start, outc = out_start; outc < out_end; inc++, outc++) { mus_file_to_frample(inf, inc, in_data); mus_outa_to_file(outf, outc, in_data[0]); } break; case IDENTITY_MIX: for (inc = in_start, outc = out_start; outc < out_end; inc++, outc++) mus_frample_to_file(outf, outc, mus_file_to_frample(inf, inc, in_data)); break; case SCALED_MONO_MIX: { mus_float_t scl; scl = mx[0]; for (inc = in_start, outc = out_start; outc < out_end; inc++, outc++) { mus_file_to_frample(inf, inc, in_data); mus_outa_to_file(outf, outc, scl * in_data[0]); } } break; case SCALED_MIX: for (inc = in_start, outc = out_start; outc < out_end; inc++, outc++) mus_frample_to_file(outf, outc, mus_frample_to_frample(mx, mx_chans, mus_file_to_frample(inf, inc, in_data), in_chans, out_data, out_chans)); break; } free(in_data); free(out_data); } void mus_file_mix(const char *outfile, const char *infile, mus_long_t out_start, mus_long_t out_framples, mus_long_t in_start, mus_float_t *mx, int mx_chans, mus_any ***envs) { int in_chans, out_chans, min_chans, mixtype; out_chans = mus_sound_chans(outfile); if (out_chans <= 0) mus_error(MUS_NO_CHANNELS, S_mus_file_mix ": %s chans: %d", outfile, out_chans); in_chans = mus_sound_chans(infile); if (in_chans <= 0) mus_error(MUS_NO_CHANNELS, S_mus_file_mix ": %s chans: %d", infile, in_chans); if (out_chans > in_chans) min_chans = in_chans; else min_chans = out_chans; mixtype = mix_file_type(out_chans, in_chans, mx, envs); if (mixtype == ALL_MIX) { mus_any *inf, *outf; /* the general case -- possible envs/scalers on every mixer cell */ outf = mus_continue_sample_to_file(outfile); inf = mus_make_file_to_frample(infile); mus_file_mix_with_reader_and_writer(outf, inf, out_start, out_framples, in_start, mx, mx_chans, envs); mus_free(inf); mus_free(outf); } else { mus_long_t j = 0; int i, m, ofd, ifd; mus_float_t scaler; mus_any *e; mus_float_t **obufs, **ibufs; mus_long_t offk, curoutframples; /* highly optimizable cases */ obufs = (mus_float_t **)malloc(out_chans * sizeof(mus_float_t *)); for (i = 0; i < out_chans; i++) obufs[i] = (mus_float_t *)malloc(clm_file_buffer_size * sizeof(mus_float_t)); ibufs = (mus_float_t **)malloc(in_chans * sizeof(mus_float_t *)); for (i = 0; i < in_chans; i++) ibufs[i] = (mus_float_t *)malloc(clm_file_buffer_size * sizeof(mus_float_t)); ifd = mus_sound_open_input(infile); mus_file_seek_frample(ifd, in_start); mus_file_read(ifd, in_start, clm_file_buffer_size, in_chans, ibufs); ofd = mus_sound_reopen_output(outfile, out_chans, mus_sound_sample_type(outfile), mus_sound_header_type(outfile), mus_sound_data_location(outfile)); curoutframples = mus_sound_framples(outfile); mus_file_seek_frample(ofd, out_start); mus_file_read(ofd, out_start, clm_file_buffer_size, out_chans, obufs); mus_file_seek_frample(ofd, out_start); switch (mixtype) { case IDENTITY_MONO_MIX: for (offk = 0, j = 0; offk < out_framples; offk++, j++) { if (j == clm_file_buffer_size) { mus_file_write(ofd, 0, j - 1, out_chans, obufs); j = 0; mus_file_seek_frample(ofd, out_start + offk); mus_file_read(ofd, out_start + offk, clm_file_buffer_size, out_chans, obufs); mus_file_seek_frample(ofd, out_start + offk); mus_file_read(ifd, in_start + offk, clm_file_buffer_size, in_chans, ibufs); } obufs[0][j] += ibufs[0][j]; } break; case IDENTITY_MIX: for (offk = 0, j = 0; offk < out_framples; offk++, j++) { if (j == clm_file_buffer_size) { mus_file_write(ofd, 0, j - 1, out_chans, obufs); j = 0; mus_file_seek_frample(ofd, out_start + offk); mus_file_read(ofd, out_start + offk, clm_file_buffer_size, out_chans, obufs); mus_file_seek_frample(ofd, out_start + offk); mus_file_read(ifd, in_start + offk, clm_file_buffer_size, in_chans, ibufs); } for (i = 0; i < min_chans; i++) obufs[i][j] += ibufs[i][j]; } break; case SCALED_MONO_MIX: scaler = mx[0]; for (offk = 0, j = 0; offk < out_framples; offk++, j++) { if (j == clm_file_buffer_size) { mus_file_write(ofd, 0, j - 1, out_chans, obufs); j = 0; mus_file_seek_frample(ofd, out_start + offk); mus_file_read(ofd, out_start + offk, clm_file_buffer_size, out_chans, obufs); mus_file_seek_frample(ofd, out_start + offk); mus_file_read(ifd, in_start + offk, clm_file_buffer_size, in_chans, ibufs); } obufs[0][j] += (mus_float_t)(scaler * ibufs[0][j]); } break; case SCALED_MIX: for (offk = 0, j = 0; offk < out_framples; offk++, j++) { if (j == clm_file_buffer_size) { mus_file_write(ofd, 0, j - 1, out_chans, obufs); j = 0; mus_file_seek_frample(ofd, out_start + offk); mus_file_read(ofd, out_start + offk, clm_file_buffer_size , out_chans, obufs); mus_file_seek_frample(ofd, out_start + offk); mus_file_read(ifd, in_start + offk, clm_file_buffer_size, in_chans, ibufs); } for (i = 0; i < min_chans; i++) for (m = 0; m < in_chans; m++) obufs[i][j] += (mus_float_t)(ibufs[m][j] * mx[m * mx_chans + i]); } break; case ENVELOPED_MONO_MIX: e = envs[0][0]; for (offk = 0, j = 0; offk < out_framples; offk++, j++) { if (j == clm_file_buffer_size) { mus_file_write(ofd, 0, j - 1, out_chans, obufs); j = 0; mus_file_seek_frample(ofd, out_start + offk); mus_file_read(ofd, out_start + offk, clm_file_buffer_size, out_chans, obufs); mus_file_seek_frample(ofd, out_start + offk); mus_file_read(ifd, in_start + offk, clm_file_buffer_size, in_chans, ibufs); } obufs[0][j] += (mus_float_t)(mus_env(e) * ibufs[0][j]); } break; case ENVELOPED_MIX: e = envs[0][0]; for (offk = 0, j = 0; offk < out_framples; offk++, j++) { if (j == clm_file_buffer_size) { mus_file_write(ofd, 0, j - 1, out_chans, obufs); j = 0; mus_file_seek_frample(ofd, out_start + offk); mus_file_read(ofd, out_start + offk, clm_file_buffer_size, out_chans, obufs); mus_file_seek_frample(ofd, out_start + offk); mus_file_read(ifd, in_start + offk, clm_file_buffer_size, in_chans, ibufs); } scaler = mus_env(e); for (i = 0; i < min_chans; i++) obufs[i][j] += (mus_float_t)(scaler * ibufs[i][j]); } break; } if (j > 0) mus_file_write(ofd, 0, j - 1, out_chans, obufs); if (curoutframples < (out_framples + out_start)) curoutframples = out_framples + out_start; mus_sound_close_output(ofd, curoutframples * out_chans * mus_bytes_per_sample(mus_sound_sample_type(outfile))); mus_sound_close_input(ifd); for (i = 0; i < in_chans; i++) free(ibufs[i]); free(ibufs); for (i = 0; i < out_chans; i++) free(obufs[i]); free(obufs); } } /* ---------------- init clm ---------------- */ void mus_initialize(void) { #define MULAW_ZERO 255 #define ALAW_ZERO 213 #define UBYTE_ZERO 128 mus_generator_type = MUS_INITIAL_GEN_TAG; sampling_rate = MUS_DEFAULT_SAMPLING_RATE; w_rate = (TWO_PI / MUS_DEFAULT_SAMPLING_RATE); array_print_length = MUS_DEFAULT_ARRAY_PRINT_LENGTH; clm_file_buffer_size = MUS_DEFAULT_FILE_BUFFER_SIZE; #if HAVE_FFTW3 && HAVE_COMPLEX_TRIG last_c_fft_size = 0; /* is there a problem if the caller built fftw with --enable-threads? * How to tell via configure that we need to initialize the thread stuff in libfftw? */ #endif sincs = 0; locsig_warned = NULL; sample_type_zero = (int *)calloc(MUS_NUM_SAMPLES, sizeof(int)); sample_type_zero[MUS_MULAW] = MULAW_ZERO; sample_type_zero[MUS_ALAW] = ALAW_ZERO; sample_type_zero[MUS_UBYTE] = UBYTE_ZERO; #if MUS_LITTLE_ENDIAN sample_type_zero[MUS_UBSHORT] = 0x80; sample_type_zero[MUS_ULSHORT] = 0x8000; #else sample_type_zero[MUS_UBSHORT] = 0x8000; sample_type_zero[MUS_ULSHORT] = 0x80; #endif } snd-16.1/snd15.scm0000644000076400007640000000231212453776451012005 0ustar bilbil(define vct-multiply! float-vector-multiply!) (define vct-scale! float-vector-scale!) (define vct-abs! float-vector-abs!) (define vct-add! float-vector-add!) (define vct-subtract! float-vector-subtract!) (define vct-offset! float-vector-offset!) (define vct-peak float-vector-peak) (define vct-peak-and-location float-vector-peak-and-location) (define vct-move! float-vector-move!) (define vct-subseq float-vector-subseq) (define vct->string float-vector->string) (define vct* float-vector*) (define vct+ float-vector+) (define vct-max float-vector-max) (define vct-min float-vector-min) (define vct-ref float-vector-ref) (define vct-set! float-vector-set!) (define region->vct region->float-vector) (define mix-vct mix-float-vector) (define transform->vct transform->float-vector) (define vct->channel float-vector->channel) (define channel->vct channel->float-vector) (define data-format sample-type) (define mus-sound-data-format mus-sound-sample-type) (define mus-data-format-name mus-sample-type-name) (define mus-data-format->string mus-sample-type->string) (define default-output-data-format (dilambda (lambda () *default-output-sample-type*) (lambda (val) (set! *default-output-sample-type* val)))) snd-16.1/piano.scm0000644000076400007640000005110312551507344012153 0ustar bilbil;;; CLM piano.ins (Scott Van Duyne) translated to Snd/Scheme (provide 'snd-piano.scm) (if (provided? 'snd) (require snd-ws.scm) (require sndlib-ws.scm)) (require snd-env.scm) ;;; see generators.scm for the old scheme versions of one-pole-all-pass, pnoise, one-pole-swept, and expseg (define number-of-stiffness-allpasses 8) (define longitudinal-mode-cutoff-keynum 29) (define longitudinal-mode-stiffness-coefficient -.5) (define golden-mean .618) (define loop-gain-env-t60 .05) (define loop-gain-default .9999) (define nstrings 3) (define two-pi (* 2 pi)) ;;keyNum indexed parameter tables ;;these should all be &key variable defaults for p instrument (define default-loudPole-table '(36 .8 60 .85 84 .7 96 .6 108 .5)) (define default-softPole-table '(36 .93 60 .9 84 .9 96 .8 108 .8)) (define default-loudGain-table '(21.000 0.700 36.000 0.700 48.000 0.700 60.000 0.650 72.000 0.650 84.000 0.650 87.006 0.681 88.070 0.444 90.653 0.606 95.515 0.731 99.770 0.775 101.897 0.794 104.024 0.800 105.695 0.806)) (define default-softGain-table '(21 .25 108 .25)) (define default-strikePosition-table '(21.000 0.140 23.884 0.139 36.000 0.128 56.756 0.129 57.765 0.130 59.000 0.130 60.000 0.128 61.000 0.128 62.000 0.129 66.128 0.129 69.000 0.128 72.000 0.128 73.000 0.128 79.000 0.128 80.000 0.128 96.000 0.128 99.000 0.128)) (define default-detuning2-table '(22.017 -0.090 23.744 -0.090 36.000 -0.080 48.055 -0.113 60.000 -0.135 67.264 -0.160 72.000 -0.200 84.054 -0.301 96.148 -0.383 108 -0.383)) (define default-detuning3-table '(21.435 0.027 23.317 0.043 36.000 0.030 48.000 0.030 60.000 0.030 72.000 0.020 83.984 0.034 96.000 0.034 99.766 0.034)) (define default-stiffnessCoefficient-table '(21.000 -0.920 24.000 -0.900 36.000 -0.700 48.000 -0.250 60.000 -0.100 75.179 -0.040 82.986 -0.040 92.240 -0.040 96.000 -0.040 99.000 .2 108.000 .5)) (define default-singleStringDecayRate-table '(21.678 -2.895 24.000 -3.000 36.000 -4.641 41.953 -5.867 48.173 -7.113 53.818 -8.016 59.693 -8.875 66.605 -9.434 73.056 -10.035 78.931 -10.293 84.000 -12.185)) (define default-singleStringZero-table '(21.000 -0.300 24.466 -0.117 28.763 -0.047 36.000 -0.030 48.000 -0.020 60.000 -0.010 72.000 -0.010 84.000 -0.010 96.000 -0.010)) (define default-singleStringPole-table '(21.000 0 24.466 0 28.763 0 36.000 0 108 0)) (define default-releaseLoopGain-table '(21.643 0.739 24.000 0.800 36.000 0.880 48.000 0.910 60.000 0.940 72.000 0.965 84.000 0.987 88.99 .987 89.0 1.0 108 1.0)) (define default-DryTapFiltCoeft60-table '(36 .35 60 .25 108 .15)) (define default-DryTapFiltCoefTarget-table '(36 -.8 60 -.5 84 -.4 108 -.1)) (define default-DryTapFiltCoefCurrent-table '(0 0 200 0)) (define default-DryTapAmpt60-table '(36 .55 60 .5 108 .45)) (define default-sustainPedalLevel-table '(21.000 0.250 24.000 0.250 36.000 0.200 48.000 0.125 60.000 0.075 72.000 0.050 84.000 0.030 96.000 0.010 99.000 0.010)) (define default-pedalResonancePole-table '(20.841 0.534 21.794 0.518 33.222 0.386 45.127 0.148 55.445 -0.065 69.255 -0.409 82.905 -0.729 95.763 -0.869 106.398 -0.861)) (define default-pedalEnvelopet60-table '(21.0 7.5 108.0 7.5)) (define default-soundboardCutofft60-table '(21.0 .25 108.0 .25)) (define default-DryPedalResonanceFactor-table '(21.0 .5 108.0 .5)) (define default-unaCordaGain-table '(21 1.0 24 .4 29 .1 29.1 .95 108 .95)) (definstrument (p start (duration 1.0) (keyNum 60.0) ; middleC=60: can use fractional part to detune (strike-velocity 0.5) ; corresponding normalized velocities (range: 0.0--1.0) pedal-down ; set to #t for sustain pedal down...pedal-down-times not yet implemented (release-time-margin 0.75) ; extra compute time allowed beyond duration (amp .5) ; amp scale of noise inputs... ;;slider controls (detuningFactor 1.0) (detuningFactor-table ()) (stiffnessFactor 1.0) (stiffnessFactor-table ()) (pedalPresenceFactor .3) (longitudinalMode 10.5) (StrikePositionInvFac -0.9) (singleStringDecayRateFactor 1.0) ;; parameter tables indexed by keyNum ;; you can override the loudPole-table by directly setting :loudPole to a value loudPole (loudPole-table default-loudPole-table) softPole (softPole-table default-softPole-table) loudGain (loudGain-table default-loudGain-table) softGain (softGain-table default-softGain-table) strikePosition (strikePosition-table default-strikePosition-table) detuning2 (detuning2-table default-detuning2-table) detuning3 (detuning3-table default-detuning3-table) stiffnessCoefficient (stiffnessCoefficient-table default-stiffnessCoefficient-table) singleStringDecayRate (singleStringDecayRate-table default-singleStringDecayRate-table) singleStringZero (singleStringZero-table default-singleStringZero-table) singleStringPole (singleStringPole-table default-singleStringPole-table) releaseLoopGain (releaseLoopGain-table default-releaseLoopGain-table) DryTapFiltCoeft60 (DryTapFiltCoeft60-table default-DryTapFiltCoeft60-table) DryTapFiltCoefTarget (DryTapFiltCoefTarget-table default-DryTapFiltCoefTarget-table) DryTapFiltCoefCurrent (DryTapFiltCoefCurrent-table default-DryTapFiltCoefCurrent-table) DryTapAmpt60 (DryTapAmpt60-table default-DryTapAmpt60-table) sustainPedalLevel (sustainPedalLevel-table default-sustainPedalLevel-table) pedalResonancePole (pedalResonancePole-table default-pedalResonancePole-table) pedalEnvelopet60 (pedalEnvelopet60-table default-pedalEnvelopet60-table) soundboardCutofft60 (soundboardCutofft60-table default-soundboardCutofft60-table) DryPedalResonanceFactor (DryPedalResonanceFactor-table default-DryPedalResonanceFactor-table) unaCordaGain (unaCordaGain-table default-unaCordaGain-table)) ;; converts t60 values to suitable :rate values for expseg (define (In-t60 t60) (- 1.0 (expt 0.001 (/ 1.0 t60 *clm-srate*)))) (define (make-one-pole-one-zero a0 a1 b1) (list (make-one-zero a0 a1) (make-one-pole 1.0 b1))) (define (apPhase a1 wT) (atan (* (- (* a1 a1) 1.0) (sin wT)) (+ (* 2.0 a1) (* (+ (* a1 a1) 1.0) (cos wT))))) (define (opozPhase b0 b1 a1 wT) (let ((s (sin wT)) (c (cos wT))) (atan (- (* a1 s (+ b0 (* b1 c))) (* b1 s (+ 1 (* a1 c)))) (+ (* (+ b0 (* b1 c)) (+ 1 (* a1 c))) (* b1 s a1 s))))) (define (signum n) ;; in CL this returns 1.0 if n is float (if (positive? n) 1 (if (zero? n) 0 -1))) (define (get-allpass-coef samp-frac wT) (let ((ta (tan (- (* samp-frac wT)))) (c (cos wT)) (s (sin wT))) (/ (+ (- ta) (* (signum ta) (sqrt (* (+ 1 (* ta ta)) (* s s))))) ; is this correct? it's in the original (- (* c ta) s)))) (define (apfloor len wT) (let* ((len-int (floor len)) (len-frac (- len len-int))) (if (< len-frac golden-mean) (begin (set! len-int (- len-int 1)) (set! len-frac (+ len-frac 1.0)))) (if (and (< len-frac golden-mean) (> len-int 0)) (begin (set! len-int (- len-int 1)) (set! len-frac (+ len-frac 1.0)))) (list len-int (get-allpass-coef len-frac wT)))) (define (tune-piano frequency stiffnessCoefficient numAllpasses b0 b1 a1) (let* ((wT (/ (* frequency two-pi) *clm-srate*)) (len (/ (+ two-pi (* numAllpasses (apPhase stiffnessCoefficient wT)) (opozPhase (+ 1 (* 3 b0)) (+ a1 (* 3 b1)) a1 wT)) wT))) (apfloor len wT))) (let (;;look-up parameters in tables (or else use the override value) (loudPole (or loudPole (envelope-interp keyNum loudPole-table))) (softPole (or softPole (envelope-interp keyNum softPole-table))) (loudGain (or loudGain (envelope-interp keyNum loudGain-table))) (softGain (or softGain (envelope-interp keyNum softGain-table))) (strikePosition (or strikePosition (envelope-interp keyNum strikePosition-table))) (detuning2 (or detuning2 (envelope-interp keyNum detuning2-table))) (detuning3 (or detuning3 (envelope-interp keyNum detuning3-table))) (stiffnessCoefficient (or stiffnessCoefficient (envelope-interp keyNum stiffnessCoefficient-table))) (singleStringDecayRate-1 (or singleStringDecayRate (envelope-interp keyNum singleStringDecayRate-table))) (singleStringZero (or singleStringZero (envelope-interp keyNum singleStringZero-table))) (singleStringPole (or singleStringPole (envelope-interp keyNum singleStringPole-table))) (releaseLoopGain (or releaseLoopGain (envelope-interp keyNum releaseLoopGain-table))) (DryTapFiltCoeft60 (or DryTapFiltCoeft60 (envelope-interp keyNum DryTapFiltCoeft60-table))) (DryTapFiltCoefTarget (or DryTapFiltCoefTarget (envelope-interp keyNum DryTapFiltCoefTarget-table))) (DryTapFiltCoefCurrent (or DryTapFiltCoefCurrent (envelope-interp keyNum DryTapFiltCoefCurrent-table))) (DryTapAmpt60 (or DryTapAmpt60 (envelope-interp keyNum DryTapAmpt60-table))) (sustainPedalLevel (or sustainPedalLevel (envelope-interp keyNum sustainPedalLevel-table))) (pedalResonancePole (or pedalResonancePole (envelope-interp keyNum pedalResonancePole-table))) (pedalEnvelopet60 (or pedalEnvelopet60 (envelope-interp keyNum pedalEnvelopet60-table))) (soundboardCutofft60 (or soundboardCutofft60 (envelope-interp keyNum soundboardCutofft60-table))) (DryPedalResonanceFactor (or DryPedalResonanceFactor (envelope-interp keyNum DryPedalResonanceFactor-table))) (unaCordaGain (or unaCordaGain (envelope-interp keyNum unaCordaGain-table))) (detuningFactor (if (null? detuningFactor-table) (envelope-interp keyNum detuningFactor-table) detuningFactor)) (stiffnessFactor (if (null? stiffnessFactor-table) (envelope-interp keyNum stiffnessFactor-table) stiffnessFactor)) (dryTap-one-pole-one-zero-pair (make-one-pole-one-zero 1.0 0.0 0.0)) (dryTap-one-pole-swept 0.0) (wetTap-one-pole-swept 0.0) (beg (seconds->samples start)) (dur (seconds->samples duration)) (freq (* 440.0 (expt 2.0 (/ (- keyNum 69.0) 12.0))))) (let((end (+ beg dur (seconds->samples release-time-margin))) (release-time (+ beg dur)) (wT (/ (* two-pi freq) *clm-srate*)) ;;strike position comb filter delay length (agraffe-len (/ (* *clm-srate* strikePosition) freq)) (singleStringDecayRate (* singleStringDecayRateFactor singleStringDecayRate-1))) (let (;;initialize soundboard impulse response elements ;;initialize open-string resonance elements (wetTap-one-pole-one-zero-pair (make-one-pole-one-zero (- 1.0 (* (signum pedalResonancePole) pedalResonancePole)) 0.0 (- pedalResonancePole))) (sb-cutoff-rate (In-t60 soundboardCutofft60)) ;;initialize velocity-dependent piano hammer filter elements (hammerPole (+ softPole (* (- loudPole softPole) strike-velocity))) (hammerGain (+ softGain (* (- loudGain softGain) strike-velocity))) (vals (apfloor agraffe-len wT)) (attenuationPerPeriod (expt 10.0 (/ singleStringDecayRate freq 20.0)))) (let ((dlen1 (car vals)) (apcoef1 (cadr vals)) ;;compute coefficients for and initialize the coupling filter ;; taking L=g(1 - bz^-1)/(1-b), and computing Hb = -(1-L)/(2-L) (g attenuationPerPeriod) ;;DC gain (b singleStringZero) (a singleStringPole) ;;determine string tunings (and longitudinal modes, if present) (freq1 (if (<= keyNum longitudinal-mode-cutoff-keynum) (* freq longitudinalMode) freq)) (freq2 (+ freq (* detuning2 detuningFactor))) (freq3 (+ freq (* detuning3 detuningFactor))) ;;scale stiffness coefficients, if desired (stiffnessCoefficient (if (> stiffnessFactor 1.0) (- stiffnessCoefficient (* (+ 1 stiffnessCoefficient) (- stiffnessFactor 1))) (* stiffnessCoefficient stiffnessFactor)))) (let ((ctemp (+ 1 (- b) g (- (* a g)) (* nstrings (+ 1 (- b) (- g) (* a g))))) (stiffnessCoefficientL (if (<= keyNum longitudinal-mode-cutoff-keynum) longitudinal-mode-stiffness-coefficient stiffnessCoefficient))) (let ((cfb0 (/ (* 2 (+ -1 b g (- (* a g)))) ctemp)) (cfb1 (/ (* 2 (+ a (- (* a b)) (- (* b g)) (* a b g))) ctemp)) (cfa1 (/ (+ (- a) (* a b) (- (* b g)) (* a b g) (* nstrings (+ (- a) (* a b) (* b g) (- (* a b g))))) ctemp)) (agraffe-delay1 (make-delay dlen1)) (agraffe-tuning-ap1 (make-one-pole-all-pass 1 apcoef1))) (let ((couplingFilter-pair (make-one-pole-one-zero cfb0 cfb1 cfa1)) ;;initialize the coupled-string elements (vals1 (tune-piano freq1 stiffnessCoefficientL number-of-stiffness-allpasses cfb0 cfb1 cfa1)) (vals2 (tune-piano freq2 stiffnessCoefficient number-of-stiffness-allpasses cfb0 cfb1 cfa1)) (vals3 (tune-piano freq3 stiffnessCoefficient number-of-stiffness-allpasses cfb0 cfb1 cfa1))) (let ((delayLength1 (car vals1)) (tuningCoefficient1 (cadr vals1)) (delayLength2 (car vals2)) (tuningCoefficient2 (cadr vals2)) (delayLength3 (car vals3)) (tuningCoefficient3 (cadr vals3))) (let ((dryTap0 (car dryTap-one-pole-one-zero-pair)) (dryTap1 (cadr dryTap-one-pole-one-zero-pair)) (wetTap0 (car wetTap-one-pole-one-zero-pair)) (wetTap1 (cadr wetTap-one-pole-one-zero-pair)) (op1 (make-one-pole (- 1.0 hammerPole) (- hammerPole))) (op2 (make-one-pole (- 1.0 hammerPole) (- hammerPole))) (op3 (make-one-pole (- 1.0 hammerPole) (- hammerPole))) (op4 (make-one-pole (- 1.0 hammerPole) (- hammerPole))) (cou0 (car couplingFilter-pair)) (cou1 (cadr couplingFilter-pair)) (string1-delay (make-delay (- delayLength1 1))) (string1-tuning-ap (make-one-pole-all-pass 1 tuningCoefficient1)) (string1-stiffness-ap (make-one-pole-all-pass 8 stiffnessCoefficientL)) (string2-delay (make-delay (- delayLength2 1))) (string2-tuning-ap (make-one-pole-all-pass 1 tuningCoefficient2)) (string2-stiffness-ap (make-one-pole-all-pass 8 stiffnessCoefficient)) (string3-delay (make-delay (- delayLength3 1))) (string3-tuning-ap (make-one-pole-all-pass 1 tuningCoefficient3)) (string3-stiffness-ap (make-one-pole-all-pass 8 stiffnessCoefficient)) ;;initialize loop-gain envelope (loop-gain loop-gain-default) (loop-gain-ry (* releaseLoopGain (In-t60 loop-gain-env-t60))) (loop-gain-rx (- 1.0 (In-t60 loop-gain-env-t60))) (dry-coef (* 1.0 DryTapFiltCoefCurrent)) (dry-coef-ry (* DryTapFiltCoefTarget (In-t60 DryTapFiltCoeft60))) (dry-coef-rx (- 1.0 (In-t60 DryTapFiltCoeft60))) (wet-coef 0.0) (wet-coef-ry (* -0.5 (In-t60 pedalEnvelopet60))) (wet-coef-rx (- 1.0 (In-t60 pedalEnvelopet60))) (dryTap 0.0) (dryTap-x 1.0) (dryTap-rx (- 1.0 (In-t60 DryTapAmpt60))) (openStrings 0.0) (wetTap-x (* sustainPedalLevel pedalPresenceFactor (if pedal-down 1.0 DryPedalResonanceFactor))) (wetTap-rx (- 1.0 (In-t60 pedalEnvelopet60))) (combedExcitationSignal 0.0) (adelOut 0.0) (adelIn 0.0) (totalTap 0.0) (string1-junction-input 0.0) (string2-junction-input 0.0) (string3-junction-input 0.0) (couplingFilter-input 0.0) (couplingFilter-output 0.0) (temp1 0.0) ;; (pn-gen 16383) (pnoise (int-vector 16383)) (interp 0.0) ) (define (piano-loop beg end) (do ((i beg (+ i 1))) ((= i end)) (set! loop-gain (+ (* interp (+ loop-gain-ry (* loop-gain-rx loop-gain))) (* (- 1.0 interp) loop-gain-default))) (set! temp1 (one-zero dryTap0 (one-pole dryTap1 (piano-noise pnoise amp)))) (set! dry-coef (+ dry-coef-ry (* dry-coef-rx dry-coef))) (set! dryTap-one-pole-swept (- (* (+ 1.0 dry-coef) temp1) (* dry-coef dryTap-one-pole-swept))) (set! dryTap-x (* dryTap-x dryTap-rx)) (set! dryTap (* dryTap-x dryTap-one-pole-swept)) (set! temp1 (one-zero wetTap0 (one-pole wetTap1 (piano-noise pnoise amp)))) (set! wet-coef (+ wet-coef-ry (* wet-coef-rx wet-coef))) (set! wetTap-one-pole-swept (- (* (+ 1.0 wet-coef) temp1) (* wet-coef wetTap-one-pole-swept))) (set! wetTap-x (* wetTap-x wetTap-rx)) (set! openStrings (* wetTap-x wetTap-one-pole-swept)) (set! totalTap (+ dryTap openStrings)) (set! adelIn (one-pole op1 (one-pole op2 (one-pole op3 (one-pole op4 totalTap))))) (set! combedExcitationSignal (* hammerGain (+ adelOut (* adelIn StrikePositionInvFac)))) (set! adelOut (one-pole-all-pass agraffe-tuning-ap1 (delay agraffe-delay1 adelIn))) (set! string1-junction-input (+ (* unaCordaGain combedExcitationSignal) (* loop-gain (delay string1-delay (one-pole-all-pass string1-tuning-ap (one-pole-all-pass string1-stiffness-ap (+ string1-junction-input couplingFilter-output))))))) (set! string2-junction-input (+ combedExcitationSignal (* loop-gain (delay string2-delay (one-pole-all-pass string2-tuning-ap (one-pole-all-pass string2-stiffness-ap (+ string2-junction-input couplingFilter-output))))))) (set! string3-junction-input (+ combedExcitationSignal (* loop-gain (delay string3-delay (one-pole-all-pass string3-tuning-ap (one-pole-all-pass string3-stiffness-ap (+ string3-junction-input couplingFilter-output))))))) (set! couplingFilter-input (+ string1-junction-input string2-junction-input string3-junction-input)) (set! couplingFilter-output (one-zero cou0 (one-pole cou1 couplingFilter-input))) (outa i couplingFilter-input))) (piano-loop beg release-time) (set! dryTap-rx (- 1.0 sb-cutoff-rate)) (set! wetTap-rx dryTap-rx) (set! interp 1.0) (piano-loop release-time end) )))))))))) #| (with-sound () (do ((i 0 (+ i 1))) ((= i 8)) (p (* i .5) :duration .5 :keyNum (+ 24 (* 12 i)) :strike-velocity .5 ;0 to 1, 0 is softest played note, 1 is loud note :amp .4 ;overall volume level :DryPedalResonanceFactor .25 ;0 no open string resonance ;1.0 is about full resonance of dampers raised ;can be greater than 1.0 ))) (with-sound () (do ((i 0 (+ i 1))) ((= i 8)) (p (* i .5) :duration .5 :keyNum (+ 24 (* 12 i)) :strike-velocity .5 ;0 to 1, 0 is softest played note, 1 is loud note :amp .4 ;overall volume level :DryPedalResonanceFactor .25 ;0 no open string resonance ;1.0 is about full resonance of dampers raised ;can be greater than 1.0 ;;modification to do detunedness :detuningFactor-table '(24 5 36 7.0 48 7.5 60 12.0 72 20 84 30 96 100 108 300) ;scales the above detuning values ; so 1.0 is nominal detuning ; 0.0 is exactly in tune (no two stage decay...) ; > 1.0 is out of tune... ;;modification to do stiffness :stiffnessFactor-table '(21 1.5 24 1.5 36 1.5 48 1.5 60 1.4 72 1.3 84 1.2 96 1.0 108 1.0) ;0.0 to 1.0 is less stiff, 1.0 to 2.0 is more stiff... ))) (with-sound () (do ((i 0 (+ i 1))) ((= i 8)) (p (* i .5) :duration .5 :keyNum (+ 24 (* 12 i)) :strike-velocity .5 ;0 to 1, 0 is softest played note, 1 is loud note :amp .4 ;overall volume level :DryPedalResonanceFactor .25 ;0 no open string resonance ;1.0 is about full resonance of dampers raised ;can be greater than 1.0 ;;modifications to do damped sounds :singleStringDecayRate-table '(21 -5 24.000 -5.000 36.000 -5.4 41.953 -5.867 48.173 -7.113 53.818 -8.016 59.693 -8.875 66.605 -9.434 73.056 -10.035 78.931 -10.293 84.000 -12.185) :singleStringPole-table '(21 .8 24 0.7 36.000 .6 48 .5 60 .3 84 .1 96 .03 108 .03) :stiffnessCoefficient-table '(21.000 -0.920 24.000 -0.900 36.000 -0.700 48.000 -0.250 60.000 -0.100 75.179 -0.040 82.986 -0.040 92.240 .3 96.000 .5 99.000 .7 108.000 .7) ;these are the actual allpass coefficients modified here ;to allow dampedness at high freqs ))) (let ((i 5)) (with-sound () (p 0 :duration 5 :keyNum (+ 24 (* 12 i)) :strike-velocity .5 ;0 to 1, 0 is softest played note, 1 is loud note :amp .4 ;overall volume level :DryPedalResonanceFactor .25 ;0 no open string resonance ;1.0 is about full resonance of dampers raised ;can be greater than 1.0 ;;modification for long duration notes :singleStringDecayRateFactor 1/10 ;scales attenuation rate (1/2 means twice as long duration) ))) |# snd-16.1/bowl.cms0000644000076400007640000001507512406634066012021 0ustar bilbil;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; ;;; Banded Waveguide Tibetan Bowl Instrument based on ;;; ====== ========= ======= ==== ========== ;;; ;;; Essl, G. and Cook, P. "Banded ;;; Waveguides: Towards Physical Modelling of Bar ;;; Percussion Instruments", Proceedings of the ;;; 1999 International Computer Music Conference. ;;; ;;; Also, Essl, Serafin, Cook, and Smith J.O., ;;; "Theory of Banded Waveguides", CMJ, 28:1, ;;; pp37-50, Spring 2004. ;;; ;;; ;;; CLM version by Juan Reyes 2004-2005, ;;; NOTES: ;;; As with all physical models, initial conditions matter. ;;; Frequency range is not too broad. 220Hz. is a good ;;; starting point. ;;; ;;; ;;; 08/24/2013 replaced delay line macros with DelayL using clm's delay ug ;;; 08/29/2014 fixed waveguide with feed and reflections ;;; 08/30/2014 Try different delay line lengths. Fixing bandpass radius param. ;;; 09/08/2014 Tibetan bowl, using formant filter ug. ;;; 09/14/2014 This SND's S7 version ;;; (define* (make-bowtable (offset 0.0) (slope 1.0)) (float-vector offset slope)) (define (bowtable b samp) (max 0.0 (- 1.0 (abs (* (b 1) (+ samp (b 0))))))) ;;; Let's try a formant for bandpass filtering (define (make-formantbp freq radius) (make-formant freq radius)) (define (formantbp f sample0) (formant f sample0)) ;;; Delay line structures and functions using SND's delay generator (as per prc95.scm) (defgenerator dlya (outp 0) (input #f)) (define (make-delayl len lag) (make-dlya :input (make-delay len :max-size (ceiling (+ len lag 1))) :outp (- lag len))) (define (delayl d samp) (delay-tick (d 'input) samp) (tap (d 'input) (d 'outp))) ;;;;;;;;;;;;;;;;;;;; (definstrument (singbowl beg dur freq amplitude (maxa 0.9998) ;; max bow velocity (bv 1.0) ;; bow velocity scaler ;; velocity envelope (vel-env '(0 1.0 .95 1.1 1 1.0)) (amp-env '(0 0 0.5 1 1 0)) ;;'(0 0.0 .95 1.0 .99 0.00)) (rev-amount .08) ) (let ((nrmodes 12) (ratius 0.45)) (let* ((start (seconds->samples beg)) (baselen (/ *clm-srate* (* freq ratius))) ;; original stk delayl length (baselag (/ *clm-srate* (* 0.9 freq ratius))) (dtapoffs 7.0) ;; tap offset is 0.0 in StK's version (bandpass (make-vector nrmodes)) (delayslft (make-vector nrmodes)) (delaysrfl (make-vector nrmodes)) (modes (make-float-vector nrmodes)) (gains (make-float-vector nrmodes)) (basegains (make-float-vector nrmodes)) (excitations (make-float-vector nrmodes)) (delastout (make-float-vector nrmodes)) ;; (fradius 0.0) ;; radius for bandpass filter (dlength 0.0) ;; delay-line length (dlag 0.0) ;; delay lag (for tap) ;; (bowtab (make-bowtable :slope 3.0 :offset 0.001)) (ampenv (make-env amp-env :scaler amplitude :duration dur)) ;; (vel-env (make-env vel-env :scaler bv :duration dur)) ;; (maxvelocity maxa) (end (+ start (seconds->samples dur))) ) ;; ;; ;; Tibetan Prayer Bowl (ICMC'02) ;; (set! (modes 0) 0.996108344) (set! (basegains 0) 0.999925960128219) (set! (modes 1) 1.0038916562) (set! (basegains 1) 0.999925960128219) (set! (modes 2) 2.979178) (set! (basegains 2) 0.999982774366897) (set! (modes 3) 2.99329767) (set! (basegains 3) 0.999982774366897) (set! (modes 4) 5.704452) (set! (basegains 4) 1.0) ;; 0.999999999999999999987356406352 (set! (modes 5) 5.704452) (set! (basegains 5) 1.0) ;; 0.999999999999999999987356406352 (set! (modes 6) 8.9982) (set! (basegains 6) 1.0) ;;0.999999999999999999996995497558225 (set! (modes 7) 9.01549726) (set! (basegains 7) 1.0) ;;0.999999999999999999996995497558225 (set! (modes 8) 12.83303) (set! (basegains 8) 0.99965497558225) (set! (modes 9) 12.807382) (set! (basegains 9) 0.999965497558225) (set! (modes 10) 17.2808219) (set! (basegains 10) 0.9999999999999999999965497558225) (set! (modes 11) 21.97602739726) (set! (basegains 11) 0.999999999999999965497558225) ;; ;; (set! (excitations 0) (/ 11.900357 10)) (set! (excitations 1) (/ 11.900357 10)) (set! (excitations 2) (/ 10.914886 10)) (set! (excitations 3) (/ 10.914886 10)) (set! (excitations 4) (/ 42.995041 10)) (set! (excitations 5) (/ 42.995041 10)) (set! (excitations 6) (/ 40.063034 10)) (set! (excitations 7) (/ 40.063034 10)) (set! (excitations 8) (/ 7.063034 10)) (set! (excitations 9) (/ 7.063034 10)) (set! (excitations 10) (/ 57.063034 10)) (set! (excitations 11) (/ 57.063034 10)) ;; ;; setFrequency method in STK's BandedWG ;; (set! fradius (- 0.79998 (* pi (/ 32 *clm-srate*)))) (do ((i 0 (+ i 1))) ((= i nrmodes)) (set! dlength (floor (/ baselen (modes i)))) (set! dlag (floor (/ baselag (modes i)))) ;; (- lag len) --> tap offset (set! (delayslft i) (make-delayl dlength dlag)) (set! (delaysrfl i) (make-delayl dlength dlag)) (set! (gains i) ( basegains i)) (set! (bandpass i) (make-formantbp (* freq (modes i)) fradius)) ) ;; ;;;;;;;;;;;; ;; (do ((i start (+ i 1))) ((= i end)) ;; (let ((input 0.00) (velinput 0.00) (bowvelocity 0.00) (bplastout 0.0) (dlastsampl 0.00) (sample0 0.00) ) (do ((k 0 (+ k 1))) ((= k nrmodes)) (set! velinput (+ velinput (* (basegains k) (delastout k))))) ;; ;; ;; (set! bowvelocity (* 0.3 (env vel-env) maxvelocity)) (set! bowvelocity (* 0.3 maxvelocity)) (set! input (- bowvelocity velinput)) (set! input (* input (bowtable bowtab input))) (set! input (/ input nrmodes )) ;; ;; Here the waveguide ;; (do ((j 0 (1+ j))) ((= j nrmodes)) (set! bplastout (+ bplastout (formantbp (bandpass j) (delayl (delayslft j) (+ input (* (gains j) dlastsampl)) )))) ;; (set! dlastsampl (+ dlastsampl (delayl ( delaysrfl j) bplastout))) (set! (delastout j) dlastsampl) ) ;; ;; (set! sample0 (* 2.0 (env ampenv) bplastout)) ;; (outa i sample0) ;; (if *reverb* (begin (outa i (* sample0 rev-amount) *reverb*))) ))) )) ;;; (with-sound () (singbowl 0 1 200 0.4 )) ;;; (with-sound () (singbowl 0 1 220 0.4 )) ;;; (with-sound () (singbowl 0 1 180 0.2 )) snd-16.1/zip.rb0000644000076400007640000000755212306421672011476 0ustar bilbil# zip.rb -- zip.scm -> zip.rb -*- snd-ruby -*- # Translator: Michael Scholz # Created: Sun Apr 24 22:53:42 CEST 2005 # Changed: Sat Sep 26 02:08:01 CEST 2009 # Commentary: # create the 'digital zipper' effect # a not-very-debonair way to fade out file1 and fade in file2 # this is also good if the same file is used twice -- sort of like a # CD player gone berserk # # safe_srate # # class Zipper # initialize(ramp_env, frame_size = 0.05, frame_env = false) # zipper(input1, input2) # # make_zipper(ramp_env, frame_size = 0.05, frame_env = false) # zipper(zp, input1, input2) # zip_sound(start, dur, file1, file2, ramp = [0, 0, 1, 1], size = 0.05) # Code: def safe_srate (sounds and srate()) or mus_srate() end class Zipper def initialize(ramp_env, frame_size = 0.05, frame_env = false) max_size = 1 + (safe_srate * frame_size).ceil @low_start = 20 @frame_loc = 0 @cursamples = 0 @frame0 = Vct.new(max_size) @frame1 = Vct.new(max_size) @frame2 = Vct.new(max_size) @fe = (frame_env or make_env([0, safe_srate * 0.05], :length, ramp_env.length)) @rampe = ramp_env end def zipper(input1, input2) ramp_loc = env(@rampe) frame_samples = env(@fe).floor if (chunk_len = (frame_samples.to_f * ramp_loc).round) <= @low_start @frame_loc = 0 input1.call elsif chunk_len >= frame_samples - @low_start @frame_loc = 0 input2.call else if @frame_loc >= @cursamples @frame_loc = 0 @cursamples = frame_samples frame_samples.times do |i| @frame1[i] = input1.call @frame2[i] = input2.call end @frame0.fill(0.0) start_ctr = 0.0 samp2 = frame_samples.to_f / chunk_len chunk_len.times do |i| ictr = start_ctr.floor y0 = @frame2[ictr] y1 = @frame2[ictr + 1] @frame0[i] = y0 + (y1 - y0) * (start_ctr - ictr) start_ctr += samp2 end start_ctr = 0 samp1 = frame_samples.to_f / (frame_samples.to_f - chunk_len) chunk_len.upto(frame_samples - 1) do |i| ictr = start_ctr.floor y0 = @frame1[ictr] y1 = @frame1[ictr + 1] @frame0[i] = y0 + (y1 - y0) * (start_ctr - ictr) start_ctr += samp1 end end result = @frame0[@frame_loc] @frame_loc += 1 result end end end add_help(:make_zipper, "make_zipper(ramp_env, [frame_size=0.05, [frame_env=false]]) \ makes a zipper generator. 'ramp_env' is an envelope (normally a ramp from 0 to 1) \ which sets where we are in the zipping process, \ 'frame_size' is the maximum frame length during the zip in seconds (defaults to 0.05), \ and 'frame_env' is an envelope returning the current frame size during the zip process.") def make_zipper(ramp_env, frame_size = 0.05, frame_env = false) Zipper.new(ramp_env, frame_size, frame_env) end add_help(:zipper, "zipper(zip, in1, in2) \ creates the digital zipper sound effect using zipper generator 'zip' \ and the two samplers 'in1' and 'in2'") def zipper(zp, input1, input2) zp.zipper(input1, input2) end add_help(:zip_sound, "zip_sound(start, dur, file1, file2, [ramp_env=[0, 0, 1, 1], [size=0.05]]) \ zips the two files and mixes the result into the current sound") def zip_sound(start, dur, file1, file2, ramp = [0, 0, 1, 1], size = 0.05) beg = seconds2samples(start) len = seconds2samples(dur) zip = make_zipper(make_env(:envelope, ramp, :length, len), size, make_env(:envelope, [0, safe_srate * size], :length, len)) read0 = make_sampler(0, file1) read1 = make_sampler(0, file2) map_channel(lambda do |y| y + zipper(zip, read0, read1) end, beg, len) end # zip_sound(0, 1, "fyow.snd", "now.snd", [0, 0, 1, 1], 0.05) # zip_sound(0, 3, "mb.snd", "fyow.snd", [0, 0, 1, 0, 1.5, 1, 3, 1], 0.025) # zip.rb ends here snd-16.1/snd-gutils.c0000644000076400007640000012355412616725517012616 0ustar bilbil#include "snd.h" #if GTK_CHECK_VERSION(3, 0, 0) cairo_t *make_cairo(GdkWindow *win) #else cairo_t *make_cairo(GdkDrawable *win) #endif { ss->line_width = -1.0; return(gdk_cairo_create(win)); } void free_cairo(cairo_t *cr) { ss->line_width = -1.0; cairo_destroy(cr); } bool set_tiny_font(const char *font) { PangoFontDescription *fs = NULL; if ((font) && (font[0] == '/')) return(false); /* pango accepts bogus font names, but then cairo segfaults trying to get the font height */ fs = pango_font_description_from_string(font); if (fs) { if (tiny_font(ss)) free(tiny_font(ss)); in_set_tiny_font(mus_strdup(font)); if (TINY_FONT(ss)) pango_font_description_free(TINY_FONT(ss)); TINY_FONT(ss) = fs; return(true); } return(false); } bool set_listener_font(const char *font) { PangoFontDescription *fs = NULL; if ((font) && (font[0] == '/')) return(false); fs = pango_font_description_from_string(font); if (fs) { if (listener_font(ss)) free(listener_font(ss)); in_set_listener_font(mus_strdup(font)); if (LISTENER_FONT(ss)) pango_font_description_free(LISTENER_FONT(ss)); LISTENER_FONT(ss) = fs; set_listener_text_font(); return(true); } return(false); } bool set_peaks_font(const char *font) { PangoFontDescription *fs = NULL; if ((font) && (font[0] == '/')) return(false); fs = pango_font_description_from_string(font); if (fs) { if (peaks_font(ss)) free(peaks_font(ss)); in_set_peaks_font(mus_strdup(font)); if (PEAKS_FONT(ss)) pango_font_description_free(PEAKS_FONT(ss)); PEAKS_FONT(ss) = fs; return(true); } return(false); } bool set_bold_peaks_font(const char *font) { PangoFontDescription *fs = NULL; if ((font) && (font[0] == '/')) return(false); fs = pango_font_description_from_string(font); if (fs) { if (bold_peaks_font(ss)) free(bold_peaks_font(ss)); in_set_bold_peaks_font(mus_strdup(font)); if (BOLD_PEAKS_FONT(ss)) pango_font_description_free(BOLD_PEAKS_FONT(ss)); BOLD_PEAKS_FONT(ss) = fs; return(true); } return(false); } bool set_axis_label_font(const char *font) { PangoFontDescription *fs = NULL; if ((font) && (font[0] == '/')) return(false); fs = pango_font_description_from_string(font); if (fs) { if (axis_label_font(ss)) free(axis_label_font(ss)); in_set_axis_label_font(mus_strdup(font)); if (AXIS_LABEL_FONT(ss)) pango_font_description_free(AXIS_LABEL_FONT(ss)); AXIS_LABEL_FONT(ss) = fs; return(true); } return(false); } bool set_axis_numbers_font(const char *font) { PangoFontDescription *fs = NULL; if ((font) && (font[0] == '/')) return(false); fs = pango_font_description_from_string(font); if (fs) { if (axis_numbers_font(ss)) free(axis_numbers_font(ss)); in_set_axis_numbers_font(mus_strdup(font)); if (AXIS_NUMBERS_FONT(ss)) pango_font_description_free(AXIS_NUMBERS_FONT(ss)); AXIS_NUMBERS_FONT(ss) = fs; return(true); } return(false); } int sg_text_width(const char *txt, PangoFontDescription *font) { int wid = 0; PangoLayout *layout = NULL; PangoContext *ctx; if (txt == NULL) return(0); if (mus_strlen(txt) == 0) return(0); if (!(g_utf8_validate(txt, -1, NULL))) return(0); ctx = gdk_pango_context_get(); layout = pango_layout_new(ctx); if (layout) { pango_layout_set_font_description(layout, font); pango_layout_set_text(layout, txt, -1); pango_layout_get_pixel_size(layout, &wid, NULL); /* huge (6MBytes!) memleak here */ g_object_unref(G_OBJECT(layout)); } g_object_unref(ctx); return(wid); } int mark_name_width(const char *txt) { if (txt) return(sg_text_width(txt, PEAKS_FONT(ss))); return(0); } int label_width(const char *txt, bool use_tiny_font) { if (txt) return(sg_text_width(txt, (use_tiny_font) ? TINY_FONT(ss) : AXIS_LABEL_FONT(ss))); else return(0); } int number_width(const char *num, bool use_tiny_font) { if (num) return(sg_text_width(num, (use_tiny_font) ? TINY_FONT(ss) : AXIS_NUMBERS_FONT(ss))); return(0); } #if 0 static int sg_font_width(PangoFontDescription *font) { /* returns size in pixels */ int wid; double dpi; PangoContext *ctx; PangoFontMetrics *m; #if HAVE_GTK_LINK_BUTTON_NEW dpi = gdk_screen_get_resolution(gdk_display_get_default_screen(gdk_display_get_default())); /* pixels/inch */ #else dpi = 96.0; /* see below */ #endif ctx = gdk_pango_context_get(); m = pango_context_get_metrics(ctx, font, gtk_get_default_language()); /* returns size in pango-scaled points (1024/72 inch) */ wid = (int)((dpi / 72.0) * PANGO_PIXELS(pango_font_metrics_get_approximate_char_width(m))); pango_font_metrics_unref(m); g_object_unref(ctx); return(wid); } #endif static int sg_font_height(PangoFontDescription *font) { /* returns size in pixels */ double dpi; int hgt; PangoContext *ctx; PangoFontMetrics *m; #if HAVE_GTK_LINK_BUTTON_NEW /* gtk 2.1: gdk_display_get_default, gdk_display_get_default_screen */ /* gtk 2.9: gdk_screen_get_resolution */ dpi = gdk_screen_get_resolution(gdk_display_get_default_screen(gdk_display_get_default())); #else dpi = 96.0; /* a plausible guess */ #endif ctx = gdk_pango_context_get(); m = pango_context_get_metrics(ctx, font, gtk_get_default_language()); hgt = (int)((dpi / 72.0) * PANGO_PIXELS(pango_font_metrics_get_ascent(m))); pango_font_metrics_unref(m); g_object_unref(ctx); return(hgt); } static PangoFontDescription *last_tiny_font = NULL, *last_numbers_font = NULL, *last_label_font = NULL, *last_peaks_font = NULL; static int last_numbers_height = 14, last_tiny_height = 10, last_label_height = 14, last_peaks_height = 10; int number_height(PangoFontDescription *font) { int hgt = 14; if (font == TINY_FONT(ss)) { if (last_tiny_font == TINY_FONT(ss)) return(last_tiny_height); hgt = sg_font_height(TINY_FONT(ss)); last_tiny_font = TINY_FONT(ss); last_tiny_height = hgt; } else { if (font == AXIS_NUMBERS_FONT(ss)) { if (last_numbers_font == AXIS_NUMBERS_FONT(ss)) return(last_numbers_height); hgt = sg_font_height(AXIS_NUMBERS_FONT(ss)); last_numbers_font = AXIS_NUMBERS_FONT(ss); last_numbers_height = hgt; } else { if (last_peaks_font == PEAKS_FONT(ss)) return(last_peaks_height); hgt = sg_font_height(PEAKS_FONT(ss)); last_peaks_font = PEAKS_FONT(ss); last_peaks_height = hgt; } } return(hgt); } int label_height(bool use_tiny_font) { int hgt = 14; if (use_tiny_font) { if (last_tiny_font == TINY_FONT(ss)) return(last_tiny_height); hgt = sg_font_height(TINY_FONT(ss)); last_tiny_font = TINY_FONT(ss); last_tiny_height = hgt; } else { if (last_label_font == AXIS_LABEL_FONT(ss)) return(last_label_height); hgt = sg_font_height(AXIS_LABEL_FONT(ss)); last_label_font = AXIS_LABEL_FONT(ss); last_label_height = hgt; } return(hgt); } void clear_window(graphics_context *ax) { /* if (ax) gdk_window_clear(ax->wn); */ } void raise_dialog(GtkWidget *w) { /* since we're using non-transient message dialogs, the dialog window can become completely * hidden behind other windows, with no easy way to raise it back to the top, so... */ gtk_widget_show(w); gtk_window_present(GTK_WINDOW(w)); } static void set_stock_button_label_1(gpointer w1, gpointer label) { GtkWidget *w = (GtkWidget *)w1; if (GTK_IS_LABEL(w)) { gtk_widget_hide(w); gtk_label_set_text(GTK_LABEL(w), (char *)label); gtk_widget_show(w); } else { if (GTK_IS_CONTAINER(w)) g_list_foreach(gtk_container_get_children(GTK_CONTAINER(w)), set_stock_button_label_1, label); } } void set_stock_button_label(GtkWidget *w, const char *new_label) { set_stock_button_label_1((gpointer)w, (gpointer)new_label); } void set_button_label(GtkWidget *label, const char *str) { gtk_label_set_text(GTK_LABEL(BIN_CHILD(label)), str); } #if GTK_CHECK_VERSION(3, 10, 0) static const char *icon_to_label(const char *label) { /* these are the new-style labels in snd-g0.h */ /* fprintf(stderr, "label: [%s]\n", label); */ switch (label[0]) { case 'A': case 'E': case 'O': case 'P': case 'S': return(label); case 'a': return("Exit"); case 'd': if (mus_strcmp(label, "document-new")) return("New"); else if (mus_strcmp(label, "document-open")) return("Open"); else if (mus_strcmp(label, "document-print")) return("Print"); else if (mus_strcmp(label, "document-revert")) return("Revert"); else if (mus_strcmp(label, "document-save")) return("Save"); else if (mus_strcmp(label, "document-save-as")) return("Save as"); break; case 'e': if (mus_strcmp(label, "edit-clear")) return("Clear"); else if (mus_strcmp(label, "edit-copy")) return("Copy"); else if (mus_strcmp(label, "edit-cut")) return("Cut"); else if (mus_strcmp(label, "edit-find")) return("Find"); else if (mus_strcmp(label, "edit-paste")) return("Paste"); else if (mus_strcmp(label, "edit-redo")) return("Redo"); else if (mus_strcmp(label, "edit-select-all")) return("Select all"); else if (mus_strcmp(label, "edit-undo")) return("Undo"); break; case 'g': if (mus_strcmp(label, "go-first")) return("Go to start"); else if (mus_strcmp(label, "go-last")) return("Go to end"); else if (mus_strcmp(label, "go-next")) return("Next"); else if (mus_strcmp(label, "go-previous")) return("Previous"); break; case 'h': return("Help"); case 'm': if (mus_strcmp(label, "media-playback-start")) return("Play"); else if (mus_strcmp(label, "media-playback-stop")) return("Stop playing"); else if (mus_strcmp(label, "media-playback-forward")) return("Play from cursor"); break; case 'p': return("Stop"); case 'v': if (mus_strcmp(label, "view-fullscreen")) return("Show all"); else if (mus_strcmp(label, "view-refresh")) return("Show again"); break; case 'w': return("Close"); case 'z': if (mus_strcmp(label, "zoom-in")) return("Zoom in"); else if (mus_strcmp(label, "zoom-out")) return("Zoom out"); break; } return(label); } GtkWidget *button_new_with_icon(const gchar *label) { return(gtk_button_new_with_label(icon_to_label(label))); } #endif void set_label(GtkWidget *label, const char *str) { gtk_label_set_text(GTK_LABEL(label), str); } void check_for_event(void) { /* this is needed to force label updates and provide interrupts for long computations * * Valgrind is confused about something here -- it thinks _XEnq malloc in XTranslateCoordinates in gdk_event_translate is never freed * but this way of letting events run is used (for example) in gtktreeview.c and gtkwidget.c, so if it's wrong here... */ int i = 0; if (ss->checking_explicitly) return; ss->checking_explicitly = true; while ((i < 100) && (gtk_events_pending())) { gtk_main_iteration(); i++; /* don't hang! */ } ss->checking_explicitly = false; } void set_title(const char *title) { gtk_window_set_title(GTK_WINDOW(MAIN_SHELL(ss)), title); } void goto_window(GtkWidget *text) { gtk_widget_grab_focus(text); } /* try to keep track of colors */ void gc_set_foreground(gc_t *gp, color_info *color) { gp->fg_color = color; } void gc_set_background(gc_t *gp, color_info *color) { gp->bg_color = color; } void gc_set_colors(gc_t *gp, color_info *col1, color_info *col2) { gp->fg_color = col1; gp->bg_color = col2; } gc_t *gc_new(void) { gc_t *gp; gp = (gc_t *)calloc(1, sizeof(gc_t)); return(gp); } void color_cursor(color_info *color) { ss->cursor_color = color; #if HAVE_SCHEME s7_symbol_set_value(s7, ss->cursor_color_symbol, Xen_wrap_pixel(color)); #endif gc_set_colors(ss->cursor_gc, color, ss->graph_color); gc_set_colors(ss->selected_cursor_gc, color, ss->selected_graph_color); } void color_marks(color_info *color) { ss->mark_color = color; #if HAVE_SCHEME s7_symbol_set_value(s7, ss->mark_color_symbol, Xen_wrap_pixel(color)); #endif gc_set_colors(ss->mark_gc, color, ss->graph_color); gc_set_colors(ss->selected_mark_gc, color, ss->selected_graph_color); } void color_selection(color_info *color) { ss->selection_color = color; #if HAVE_SCHEME s7_symbol_set_value(s7, ss->selection_color_symbol, Xen_wrap_pixel(color)); #endif gc_set_colors(ss->selection_gc, color, ss->graph_color); gc_set_colors(ss->selected_selection_gc, color, ss->selected_graph_color); } void color_graph(color_info *color) { gc_set_background(ss->basic_gc, color); gc_set_foreground(ss->erase_gc, color); gc_set_colors(ss->selection_gc, ss->selection_color, color); gc_set_colors(ss->cursor_gc, ss->cursor_color, color); gc_set_colors(ss->mark_gc, ss->mark_color, color); } void color_selected_graph(color_info *color) { gc_set_background(ss->selected_basic_gc, color); gc_set_foreground(ss->selected_erase_gc, color); gc_set_colors(ss->selected_selection_gc, ss->selection_color, color); gc_set_colors(ss->selected_cursor_gc, ss->cursor_color, color); gc_set_colors(ss->selected_mark_gc, ss->mark_color, color); } void color_data(color_info *color) { gc_set_foreground(ss->basic_gc, color); gc_set_background(ss->erase_gc, color); } void color_selected_data(color_info *color) { gc_set_foreground(ss->selected_basic_gc, color); gc_set_background(ss->selected_erase_gc, color); } void set_mix_color(color_info *color) { ss->mix_color = color; #if HAVE_SCHEME s7_symbol_set_value(s7, ss->mix_color_symbol, Xen_wrap_pixel(color)); #endif gc_set_foreground(ss->mix_gc, color); } color_t rgb_to_color(mus_float_t r, mus_float_t g, mus_float_t b) { color_info *ccolor; ccolor = (color_info *)malloc(sizeof(color_info)); ccolor->red = r; ccolor->green = g; ccolor->blue = b; ccolor->alpha = 1.0; return(ccolor); } #if (!GTK_CHECK_VERSION(3, 0, 0)) GdkColor *rgb_to_gdk_color(color_t col) { GdkColor gcolor; GdkColor *ccolor; gcolor.red = (unsigned short)(col->red * 65535); gcolor.green = (unsigned short)(col->green * 65535); gcolor.blue = (unsigned short)(col->blue * 65535); ccolor = gdk_color_copy(&gcolor); /* gdk_rgb_find_color(gdk_colormap_get_system(), ccolor); */ return(ccolor); } #endif void widget_modify_bg(GtkWidget *w, GtkStateType type, color_t color) { /* the color has to stick around??? */ /* another stop-gap: allocate a color each time... */ #if (!GTK_CHECK_VERSION(3, 0, 0)) gtk_widget_modify_bg(w, type, rgb_to_gdk_color(color)); #else #if (!GTK_CHECK_VERSION(3, 16, 0)) gtk_widget_override_background_color(w, GTK_STATE_FLAG_NORMAL, (GdkRGBA *)color); #endif #endif } void widget_modify_fg(GtkWidget *w, GtkStateType type, color_t color) { #if (!GTK_CHECK_VERSION(3, 0, 0)) gtk_widget_modify_fg(w, type, rgb_to_gdk_color(color)); #else #if (!GTK_CHECK_VERSION(3, 16, 0)) gtk_widget_override_color(w, GTK_STATE_FLAG_NORMAL, (GdkRGBA *)color); #endif #endif } void widget_modify_base(GtkWidget *w, GtkStateType type, color_t color) { #if (!GTK_CHECK_VERSION(3, 0, 0)) gtk_widget_modify_base(w, type, rgb_to_gdk_color(color)); #else #if (!GTK_CHECK_VERSION(3, 16, 0)) gtk_widget_override_background_color(w, GTK_STATE_FLAG_NORMAL, (GdkRGBA *)color); #endif #endif } void recolor_graph(chan_info *cp, bool selected) { widget_modify_bg(channel_graph(cp), GTK_STATE_NORMAL, (selected) ? ss->selected_graph_color : ss->graph_color); } void set_sensitive(GtkWidget *wid, bool val) { if (wid) gtk_widget_set_sensitive(wid, val); } void set_toggle_button(GtkWidget *wid, bool val, bool passed, void *data) { if (!passed) g_signal_handlers_block_matched((gpointer)wid, G_SIGNAL_MATCH_DATA, 0, 0, NULL, 0, (gpointer)data); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(wid), val); if (!passed) g_signal_handlers_unblock_matched((gpointer)wid, G_SIGNAL_MATCH_DATA, 0, 0, NULL, 0, (gpointer)data); } bool cursor_set_blinks(GtkWidget *w, bool blinks) { GtkSettings *settings; settings = gtk_widget_get_settings(w); g_object_set(settings, "gtk-cursor-blink", (gboolean)blinks, NULL); return(blinks); } #if GTK_CHECK_VERSION(3, 0, 0) int widget_height(GtkWidget *w) { return(gtk_widget_get_allocated_height(w)); } int widget_width(GtkWidget *w) { return(gtk_widget_get_allocated_width(w)); } #else guint16 widget_height(GtkWidget *w) { gint x, y; gdk_drawable_get_size(WIDGET_TO_WINDOW(w), &x, &y); return(y); } guint16 widget_width(GtkWidget *w) { gint x, y; gdk_drawable_get_size(WIDGET_TO_WINDOW(w), &x, &y); return(x); } #endif void set_widget_height(GtkWidget *w, guint16 height) { set_widget_size(w, widget_width(w), height); } void set_widget_width(GtkWidget *w, guint16 width) { set_widget_size(w, width, widget_height(w)); } gint16 widget_x(GtkWidget *w) { gint x, y; gdk_window_get_position(WIDGET_TO_WINDOW(w), &x, &y); return(x); } gint16 widget_y(GtkWidget *w) { gint x, y; gdk_window_get_position(WIDGET_TO_WINDOW(w), &x, &y); return(y); } void set_widget_x(GtkWidget *w, gint16 x) { gtk_window_move(GTK_WINDOW(w), x, widget_y(w)); } void set_widget_y(GtkWidget *w, gint16 y) { gtk_window_move(GTK_WINDOW(w), widget_x(w), y); } void set_widget_size(GtkWidget *w, guint16 width, guint16 height) { gdk_window_resize(WIDGET_TO_WINDOW(w), width, height); #if 0 /* This one doesn't do anything, and prints out errors. */ gtk_window_resize(GTK_WINDOW(w), width, height); #endif } void set_widget_position(GtkWidget *w, gint16 x, gint16 y) { gtk_window_move(GTK_WINDOW(w), x, y); } void set_user_data(GObject *obj, gpointer data) { g_object_set_data(obj, "snd-data", data); } gpointer get_user_data(GObject *obj) { return(g_object_get_data(obj, "snd-data")); } void set_user_int_data(GObject *obj, int data) { int *gdata; gdata = (int *)malloc(sizeof(int)); gdata[0] = data; g_object_set_data(obj, "snd-data", (gpointer)gdata); } int get_user_int_data(GObject *obj) { gpointer gdata; gdata = g_object_get_data(obj, "snd-data"); return(((int *)gdata)[0]); } void reset_user_int_data(GObject *obj, int data) { gpointer gdata; gdata = g_object_get_data(obj, "snd-data"); ((int *)gdata)[0] = data; } char *sg_get_text(GtkWidget *w, int start, int end) /* g_free result */ { GtkTextIter s, e; GtkTextBuffer *buf; buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(w)); gtk_text_buffer_get_iter_at_offset(buf, &s, start); gtk_text_buffer_get_iter_at_offset(buf, &e, end); return(gtk_text_buffer_get_text(buf, &s, &e, true)); } void sg_text_insert(GtkWidget *w, const char *text) { if (text) { GtkTextIter pos; GtkTextBuffer *buf; buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(w)); gtk_text_buffer_get_end_iter(buf, &pos); gtk_text_buffer_insert(buf, &pos, text, strlen(text)); } else gtk_text_buffer_set_text(gtk_text_view_get_buffer(GTK_TEXT_VIEW(w)), "", 0); } GtkWidget *make_scrolled_text(GtkWidget *parent, bool editable, int add_choice, bool resize) { /* returns new text widget */ GtkWidget *sw, *new_text; GtkTextBuffer *buf; sw = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); /* gtk_scrolled_window_set_min_content_height(GTK_SCROLLED_WINDOW(sw), 1000); * seems to be a no-op -- I think they are maxing this against the current contents window size (see below) */ new_text = gtk_text_view_new(); buf = gtk_text_buffer_new(NULL); gtk_text_view_set_buffer(GTK_TEXT_VIEW(new_text), buf); gtk_text_view_set_editable(GTK_TEXT_VIEW(new_text), editable); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(new_text), GTK_WRAP_NONE); gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(new_text), editable); gtk_text_view_set_left_margin(GTK_TEXT_VIEW(new_text), 4); gtk_container_add(GTK_CONTAINER(sw), new_text); if (editable) gtk_widget_set_events(new_text, GDK_ALL_EVENTS_MASK); gtk_widget_show(new_text); switch (add_choice) { case 0: gtk_container_add(GTK_CONTAINER(parent), sw); break; case 1: gtk_paned_pack2(GTK_PANED(parent), sw, resize, true); break; case 2: default: gtk_box_pack_start(GTK_BOX(parent), sw, true, true, 0); break; } gtk_widget_show(sw); return(new_text); } void sg_make_resizable(GtkWidget *w) { if (GTK_IS_DIALOG(w)) { gtk_window_set_default_size(GTK_WINDOW(w), -1, -1); gtk_window_set_resizable(GTK_WINDOW(w), true); } } idle_t add_work_proc(GSourceFunc func, gpointer data) { /* during auto-testing I need to force the background procs to run to completion */ if (with_background_processes(ss)) return(g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, func, data, NULL)); else { while (((*func)(data)) == BACKGROUND_CONTINUE) {}; return((idle_t)0); } } GtkWidget *snd_gtk_dialog_new(void) { GtkWidget *w; w = gtk_dialog_new(); #if GTK_CHECK_VERSION(3, 14, 0) gtk_window_set_transient_for(GTK_WINDOW(w), GTK_WINDOW(MAIN_SHELL(ss))); #endif add_dialog_style(w); g_object_ref(w); return(w); } GtkWidget *snd_gtk_highlight_label_new(const char *label) { char *str; GtkWidget *w; w = gtk_label_new(label); str = mus_format("%s", label); gtk_label_set_markup(GTK_LABEL(w), str); gtk_label_set_use_markup(GTK_LABEL(w), true); free(str); return(w); } void widget_int_to_text(GtkWidget *w, int val) { char *str; str = (char *)calloc(8, sizeof(char)); snprintf(str, 8, "%d", val); gtk_entry_set_text(GTK_ENTRY(w), str); free(str); } void widget_mus_long_t_to_text(GtkWidget *w, mus_long_t val) { char *str; str = (char *)calloc(8, sizeof(char)); snprintf(str, 8, "%lld", val); gtk_entry_set_text(GTK_ENTRY(w), str); free(str); } #if HAVE_GTK_ADJUSTMENT_GET_UPPER #define ADJUSTMENT_LOWER(Adjust) gtk_adjustment_get_lower(GTK_ADJUSTMENT(Adjust)) #define ADJUSTMENT_UPPER(Adjust) gtk_adjustment_get_upper(GTK_ADJUSTMENT(Adjust)) #else #define ADJUSTMENT_LOWER(Adjust) ((GTK_ADJUSTMENT(Adjust))->lower) #define ADJUSTMENT_UPPER(Adjust) ((GTK_ADJUSTMENT(Adjust))->upper) #endif void ensure_scrolled_window_row_visible(widget_t list, int row, int num_rows) { /* view files file list */ /* called in snd-file.c on vdat->file_list which is a vbox; its parent is a viewport */ /* also used in slist_moveto below */ GtkWidget *parent; GtkAdjustment *v; gdouble maximum, size, new_value, minimum; parent = gtk_widget_get_parent(list); #if GTK_CHECK_VERSION(3, 0, 0) v = gtk_scrollable_get_vadjustment(GTK_SCROLLABLE(parent)); #else v = gtk_viewport_get_vadjustment(GTK_VIEWPORT(parent)); #endif maximum = ADJUSTMENT_UPPER(v); minimum = ADJUSTMENT_LOWER(v); size = ADJUSTMENT_PAGE_SIZE(v); maximum -= size; if (row == 0) new_value = 0.0; else { if (row >= (num_rows - 1)) new_value = maximum; else new_value = ((row + 0.5) * ((maximum - minimum) / (float)(num_rows - 1))); } if (new_value != ADJUSTMENT_VALUE(v)) ADJUSTMENT_SET_VALUE(v, new_value); } /* ---------------- scrolled list replacement ---------------- */ static int slist_row(GtkWidget *item); static void slist_set_row(GtkWidget *item, int row); static void slist_item_clicked(GtkWidget *w, gpointer gp) { slist *lst = (slist *)gp; slist_select(lst, slist_row(w)); if (lst->select_callback) (*(lst->select_callback))((const char *)gtk_button_get_label(GTK_BUTTON(w)), /* do not free this!! */ slist_row(w), lst->select_callback_data); } static gboolean slist_item_button_pressed(GtkWidget *w, GdkEventButton *ev, gpointer data) { slist *lst = (slist *)data; if (lst->button_press_callback) return((*(lst->button_press_callback))(ev, lst->button_press_callback_data)); return(false); } #if GTK_CHECK_VERSION(3, 0, 0) static GtkCssProvider *wb_provider, *listener_provider, *dialog_provider, *hl_provider, *tb_provider, *mu_provider; static GtkCssProvider *rsc_provider, *gsc_provider, *bsc_provider, *pd_provider, *cb_provider, *entry_provider; static GtkCssProvider *cl_provider; void add_white_button_style(GtkWidget *w) { GtkStyleContext *c; c = gtk_widget_get_style_context(w); gtk_style_context_add_provider(c, GTK_STYLE_PROVIDER(wb_provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); gtk_widget_set_name(w, "white_button"); } void add_highlight_button_style(GtkWidget *w) { GtkStyleContext *c; c = gtk_widget_get_style_context(w); gtk_style_context_add_provider(c, GTK_STYLE_PROVIDER(hl_provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); gtk_widget_set_name(w, "highlight_button"); } void add_center_button_style(GtkWidget *w) { GtkStyleContext *c; c = gtk_widget_get_style_context(w); gtk_style_context_add_provider(c, GTK_STYLE_PROVIDER(cl_provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); } void add_listener_style(GtkWidget *w) { GtkStyleContext *c; c = gtk_widget_get_style_context(w); gtk_style_context_add_provider(c, GTK_STYLE_PROVIDER(listener_provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); gtk_widget_set_name(w, "listener_text"); } void add_dialog_style(GtkWidget *w) { GtkStyleContext *c; c = gtk_widget_get_style_context(w); gtk_style_context_add_provider(c, GTK_STYLE_PROVIDER(dialog_provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); } void add_toolbar_style(GtkWidget *w) { GtkStyleContext *c; c = gtk_widget_get_style_context(w); gtk_style_context_add_provider(c, GTK_STYLE_PROVIDER(tb_provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); } void add_menu_style(GtkWidget *w) { GtkStyleContext *c; c = gtk_widget_get_style_context(w); gtk_style_context_add_provider(c, GTK_STYLE_PROVIDER(mu_provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); } void add_paned_style(GtkWidget *w) { #if 0 GtkStyleContext *c; c = gtk_widget_get_style_context(w); gtk_style_context_add_provider(c, GTK_STYLE_PROVIDER(pd_provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); #endif } void add_red_scale_style(GtkWidget *w) { GtkStyleContext *c; c = gtk_widget_get_style_context(w); gtk_style_context_add_provider(c, GTK_STYLE_PROVIDER(rsc_provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); } void add_green_scale_style(GtkWidget *w) { GtkStyleContext *c; c = gtk_widget_get_style_context(w); gtk_style_context_add_provider(c, GTK_STYLE_PROVIDER(gsc_provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); } void add_blue_scale_style(GtkWidget *w) { GtkStyleContext *c; c = gtk_widget_get_style_context(w); gtk_style_context_add_provider(c, GTK_STYLE_PROVIDER(bsc_provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); } void add_check_button_style(GtkWidget *w) { GtkStyleContext *c; c = gtk_widget_get_style_context(w); gtk_style_context_add_provider(c, GTK_STYLE_PROVIDER(cb_provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); } void add_entry_style(GtkWidget *w) { GtkStyleContext *c; c = gtk_widget_get_style_context(w); gtk_style_context_add_provider(c, GTK_STYLE_PROVIDER(entry_provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); } #else void add_red_scale_style(GtkWidget *w) { } void add_green_scale_style(GtkWidget *w) { } void add_blue_scale_style(GtkWidget *w) { } void add_toolbar_style(GtkWidget *w) { } void add_menu_style(GtkWidget *w) { } void add_paned_style(GtkWidget *w) { } void add_highlight_button_style(GtkWidget *w) { } void add_center_button_style(GtkWidget *w) { } void add_white_button_style(GtkWidget *w) { gtk_widget_set_name(w, "white_button"); } void add_listener_style(GtkWidget *w) { gtk_widget_set_name(w, "listener_text"); } void add_dialog_style(GtkWidget *w) { } void add_check_button_style(GtkWidget *w) { } void add_entry_style(GtkWidget *w) { } #endif static GtkWidget *slist_new_item(slist *lst, const char *label, int row) { GtkWidget *item; item = gtk_button_new_with_label(label); slist_set_row(item, row); gtk_button_set_relief(GTK_BUTTON(item), GTK_RELIEF_HALF); #if GTK_CHECK_VERSION(3, 14, 0) gtk_widget_set_halign(GTK_WIDGET(item), GTK_ALIGN_START); #else gtk_button_set_alignment(GTK_BUTTON(item), 0.05, 1.0); #endif gtk_box_pack_start(GTK_BOX(lst->topics), item, false, false, 0); widget_modify_bg(item, GTK_STATE_NORMAL, ss->white); widget_modify_bg(item, GTK_STATE_PRELIGHT, ss->light_blue); add_white_button_style(item); SG_SIGNAL_CONNECT(item, "clicked", slist_item_clicked, (gpointer)lst); SG_SIGNAL_CONNECT(item, "button_press_event", slist_item_button_pressed, (gpointer)lst); gtk_widget_show(item); return(item); } slist *slist_new_with_title_and_table_data(const char *title, GtkWidget *parent, const char **initial_items, int num_items, widget_add_t paned, int t1, int t2, int t3, int t4) { slist *lst; GtkWidget *topw = NULL; lst = (slist *)calloc(1, sizeof(slist)); lst->selected_item = SLIST_NO_ITEM_SELECTED; if (title) { lst->box = gtk_vbox_new(false, 0); widget_set_vexpand(lst->box, true); lst->label = snd_gtk_highlight_label_new(title); gtk_box_pack_start(GTK_BOX(lst->box), lst->label, false, false, 0); topw = lst->box; } lst->topics = gtk_vbox_new(false, 2); /* sets list item vertical spacing */ widget_set_vexpand(lst->topics, true); lst->scroller = gtk_scrolled_window_new(NULL, NULL); if (!title) topw = lst->scroller; else gtk_box_pack_start(GTK_BOX(lst->box), lst->scroller, true, true, 0); switch (paned) { case PANED_ADD1: gtk_paned_add1(GTK_PANED(parent), topw); break; case BOX_PACK: gtk_box_pack_start(GTK_BOX(parent), topw, true, true, 4); break; case TABLE_ATTACH: gtk_table_attach(GTK_TABLE(parent), topw, t1, t2, t3, t4, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)(GTK_FILL | GTK_EXPAND | GTK_SHRINK), 0, 0); break; case CONTAINER_ADD: gtk_container_add(GTK_CONTAINER(parent), topw); break; } gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(lst->scroller), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); #if HAVE_GTK_HEADER_BAR_NEW gtk_container_add(GTK_CONTAINER(lst->scroller), lst->topics); #else gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(lst->scroller), lst->topics); #endif if (title) { gtk_widget_show(lst->label); gtk_widget_show(lst->box); } gtk_widget_show(lst->topics); gtk_widget_show(lst->scroller); if (num_items > 0) { int i; lst->items = (GtkWidget **)calloc(num_items, sizeof(GtkWidget *)); lst->items_size = num_items; lst->num_items = num_items; for (i = 0; i < num_items; i++) lst->items[i] = slist_new_item(lst, initial_items[i], i); } /* gtk_scrolled_window_set_min_content_height(GTK_SCROLLED_WINDOW(lst->scroller), 200); * this actually works! */ return(lst); } slist *slist_new(GtkWidget *parent, const char **initial_items, int num_items, widget_add_t paned) { return(slist_new_with_title_and_table_data(NULL, parent, initial_items, num_items, paned, 0, 0, 0, 0)); } slist *slist_new_with_title(const char *title, GtkWidget *parent, const char **initial_items, int num_items, widget_add_t paned) { return(slist_new_with_title_and_table_data(title, parent, initial_items, num_items, paned, 0, 0, 0, 0)); } void slist_clear(slist *lst) { int i; for (i = 0; i < lst->items_size; i++) if (lst->items[i]) { gtk_widget_hide(lst->items[i]); gtk_button_set_label(GTK_BUTTON(lst->items[i]), " "); } lst->num_items = 0; if (lst->selected_item != SLIST_NO_ITEM_SELECTED) widget_modify_bg(lst->items[lst->selected_item], GTK_STATE_NORMAL, ss->white); lst->selected_item = SLIST_NO_ITEM_SELECTED; } static int slist_row(GtkWidget *item) { gpointer gdata; gdata = g_object_get_data(G_OBJECT(item), "slist-row"); return(((int *)gdata)[0]); } static void slist_set_row(GtkWidget *item, int row) { int *gdata; gdata = (int *)malloc(sizeof(int)); gdata[0] = row; g_object_set_data(G_OBJECT(item), "slist-row", (gpointer)gdata); } #define INITIAL_SLIST_LENGTH 8 void slist_append(slist *lst, const char *name) { int loc = 0; if ((!name) || (!g_utf8_validate(name, -1, NULL))) return; if (lst->items_size == 0) { lst->items = (GtkWidget **)calloc(INITIAL_SLIST_LENGTH, sizeof(GtkWidget *)); lst->items_size = INITIAL_SLIST_LENGTH; lst->num_items = 0; } if (lst->num_items == lst->items_size) { int i; lst->items_size += INITIAL_SLIST_LENGTH; lst->items = (GtkWidget **)realloc(lst->items, lst->items_size * sizeof(GtkWidget *)); for (i = lst->num_items; i < lst->items_size; i++) lst->items[i] = NULL; } loc = lst->num_items++; if (lst->items[loc] == NULL) lst->items[loc] = slist_new_item(lst, name, loc); else { gtk_button_set_label(GTK_BUTTON(lst->items[loc]), name); /* gtkbutton.c strdups name */ gtk_widget_show(lst->items[loc]); } } void slist_moveto(slist *lst, int row) { ensure_scrolled_window_row_visible(lst->topics, row, lst->num_items); } void slist_select(slist *lst, int row) { if (lst->selected_item != SLIST_NO_ITEM_SELECTED) widget_modify_bg(lst->items[lst->selected_item], GTK_STATE_NORMAL, ss->white); if (row != SLIST_NO_ITEM_SELECTED) widget_modify_bg(lst->items[row], GTK_STATE_NORMAL, ss->light_blue); lst->selected_item = row; } #if (!GTK_CHECK_VERSION(3, 0, 0)) void init_gtk(void) { gtk_rc_parse_string("\n\ \n \ style \"default\"\n \ {\n \ fg[NORMAL] = { 0.0, 0.00, 0.0 }\n \ text[NORMAL] = { 0.0, 0.0, 0.0 }\n \ bg[NORMAL] = { 0.96, 0.96, 0.90 }\n \ bg[ACTIVE] = { 0.80, 0.80, 0.75 }\n \ bg[INSENSITIVE] = { 0.96, 0.96, 0.90 }\n \ base[NORMAL] = { 1.00, 1.00, 1.00 }\n \ bg[PRELIGHT] = { 0.70, 0.70, 0.64 }\n \ fg[PRELIGHT] = { 1.0, 0.0, 0.0}\n \ GtkPaned::handle_size = 6\n \ xthickness = 1\n \ ythickness = 1\n \ }\n \ style \"default_button\" = \"default\"\n \ {\n \ GtkButton::default_border = { 1, 0, 1, 0 }\n \ GtkButton::default_outside_border = { 1, 0, 1, 0 }\n \ GtkButton::inner_border = { 1, 0, 1, 0 }\n \ GtkButton::focus_line_width = 0\n \ GtkButton::focus_padding = 0\n \ }\n \ style \"default_pane\" = \"default\"\n \ {\n \ bg[NORMAL] = { 0.56, 0.93, 0.56 }\n \ bg[PRELIGHT] = { 0.26, 0.8, 0.26}\n \ }\n \ style \"default_entry\" = \"default\"\n \ {\n \ base[ACTIVE] = { 0.96, 0.96, 0.90 }\n \ base[SELECTED] = { 0.80, 0.80, 0.75 }\n \ base[PRELIGHT] = { 1.0, 1.0, 1.0}\n \ base[NORMAL] = { 0.96, 0.96, 0.90 }\n \ base[INSENSITIVE] = { 0.96, 0.96, 0.90 }\n \ bg[ACTIVE] = { 1.0, 1.0, 1.0 }\n \ bg[SELECTED] = { 1.0, 1.0, 1.0 }\n \ bg[PRELIGHT] = { 1.0, 1.0, 1.0 }\n \ text[ACTIVE] = { 0.0, 0.0, 0.0 }\n \ text[SELECTED] = { 0.0, 0.0, 0.0 }\n \ text[PRELIGHT] = { 0.0, 0.0, 0.0 }\n \ }\n \ style \"default_text\" = \"default_entry\"\n \ {\n \ base[NORMAL] = { 1.0, 1.0, 1.0 }\n \ }\n \ style \"default_slider\" = \"default\"\n \ {\n \ bg[NORMAL] = { 0.90, 0.90, 0.85 }\n \ bg[ACTIVE] = { 0.70, 0.70, 0.64 }\n \ bg[PRELIGHT] = { 0.90, 0.90, 0.85 }\n \ GtkRange::slider_width = 13\n \ GtkRange::stepper_size = 10\n \ }\n \ style \"prefs_scale\" = \"default_slider\"\n \ {\n \ GtkScale::slider-length = 24\n \ }\n \ widget \"*.prefs_color_scale\" style \"prefs_scale\"\n \ style \"default_frame\" = \"default\"\n \ {\n \ xthickness = 4\n \ ythickness = 4\n \ }\n \ class \"GtkWidget\" style \"default\"\n \ class \"GtkButton\" style \"default_button\"\n \ class \"GtkEntry\" style \"default_entry\"\n \ class \"GtkTextView\" style \"default_text\"\n \ class \"GtkPaned\" style \"default_pane\"\n \ class \"GtkRange\" style \"default_slider\"\n \ class \"GtkFrame\" style \"default_frame\"\n \ \n \ style \"zoom_slider\" = \"default_slider\"\n \ {\n \ bg[NORMAL] = { 0.70, 0.70, 0.64 }\n \ bg[ACTIVE] = { 0.54, 0.54, 0.51 }\n \ bg[PRELIGHT] = { 0.70, 0.70, 0.64 }\n \ \n \ GtkRange::slider_width = 12\n \ GtkRange::stepper_size = 12\n \ }\n \ widget \"*.zx_slider\" style \"zoom_slider\"\n \ widget \"*.zy_slider\" style \"zoom_slider\"\n \ widget \"*.gzy_slider\" style \"zoom_slider\"\n \ style \"default_tree_view\" = \"default\"\n \ {\n \ GtkTreeView::odd-row-color = { 0.94, 0.97, 1.0 }\n \ GtkTreeView::even-row-color = { 1.0, 1.0, 1.0 }\n \ }\n \ class \"GtkTreeView\" style \"default_tree_view\"\n \ style \"dialog_button\" = \"default_button\"\n \ {\n \ bg[NORMAL] = { 1.0, 1.0, 0.94 }\n \ bg[PRELIGHT] = { 1.0, 1.0, 0.94 }\n \ }\n \ widget \"*.dialog_button\" style \"dialog_button\"\n \ style \"white_button\" = \"default_button\"\n \ {\n \ bg[NORMAL] = { 1.0, 1.0, 1.0 }\n \ bg[PRELIGHT] = { 0.94, 0.97, 1.0 }\n \ fg[PRELIGHT] = { 0.0, 0.0, 0.0}\n \ GtkButton::default_border = { 0, 0, 0, 0 }\n \ GtkButton::default_outside_border = { 0, 0, 0, 0 }\n \ GtkButton::inner_border = { 0, 0, 0, 0 }\n \ GtkButton::focus_line_width = 0\n \ GtkButton::focus_padding = 0\n \ xthickness = 0\n \ ythickness = 0\n \ }\n \ widget \"*.white_button\" style \"white_button\"\n"); } #else void init_gtk(void) { wb_provider = gtk_css_provider_new(); gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(wb_provider), "GtkButton#white_button { \n" " padding-top: 0px;\n" " padding-bottom: 0px;\n" " border-width: 0px;\n" " background-color: #ffffff;\n" "}\n" "GtkButton#white_button:prelight { \n" " background-image: -gtk-gradient (linear, left top, right bottom, from(#ffffff), to(rgb(200, 225, 255)));\n" "}\n", -1, NULL); hl_provider = gtk_css_provider_new(); gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(hl_provider), "GtkEventBox, GtkButton#highlight_button { \n" " padding-top: 0px;\n" " padding-bottom: 0px;\n" " border-width: 0px;\n" " background-color: #fffff0;\n" "}\n" "GtkButton#highlight_button:prelight { \n" " background-image: -gtk-gradient (linear, left top, right bottom, from(#fffff0), to(rgb(200, 225, 255)));\n" "}\n", -1, NULL); cl_provider = gtk_css_provider_new(); gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(cl_provider), "GtkEventBox, GtkButton { \n" " padding-top: 0px;\n" " padding-bottom: 0px;\n" " padding-left: 8px;\n" " padding-right: 8px;\n" " border-width: 1px;\n" " border-color: gray;\n" " background-color: #fffff0;\n" "}\n" "GtkButton:prelight { \n" " background-image: -gtk-gradient (linear, left top, right bottom, from(#fffff0), to(rgb(200, 225, 255)));\n" "}\n", -1, NULL); listener_provider = gtk_css_provider_new(); gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(listener_provider), "#listener_text { \n" /* " background-color: rgb(240, 248, 255);\n" */ " background-color: #ffffff;\n" " color: #000000;\n" "}\n" "#listener_text:selected { \n" " background-color: darker(rgb(240, 248, 255));\n" " color: #000000;\n" "}\n", -1, NULL); entry_provider = gtk_css_provider_new(); gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(entry_provider), "GtkEntry:selected { \n" " background-color: darker(rgb(240, 248, 255));\n" " color: #000000;\n" "}\n", -1, NULL); dialog_provider = gtk_css_provider_new(); gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(dialog_provider), "GtkDialog { \n" " background-image: -gtk-gradient (linear, left top, right bottom, from(rgb(250, 250, 230)), to(rgb(235, 235, 210)));\n" "}\n", -1, NULL); tb_provider = gtk_css_provider_new(); gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(tb_provider), "GtkToolbar, GtkToolButton, GtkToolItem { \n" " border-color: #fffff0;\n" /* " background-color: #fffff0;\n" */ " padding-left: 8px;\n" " padding-bottom: 4px;\n" " background-image: -gtk-gradient (linear, left top, right bottom, from(rgb(255, 255, 240)), to(rgb(255, 255, 255)));\n" "}\n", -1, NULL); /* the 8px here refers to the whole bar, not each entry */ mu_provider = gtk_css_provider_new(); gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(mu_provider), "GtkMenuBar, GtkMenu, GtkMenuItem { \n" " border-width: 4px;\n" " border-color: #fffff0;\n" " background-color: #fffff0;\n" " padding-bottom: 4px;\n" " padding-left: 8px;\n" "}\n", -1, NULL); rsc_provider = gtk_css_provider_new(); gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(rsc_provider), "GtkScale { \n" " background-image: -gtk-gradient (linear, left top, right bottom, from(rgb(250, 250, 230)), to(rgb(160, 0, 0)));\n" "}\n", -1, NULL); gsc_provider = gtk_css_provider_new(); gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(gsc_provider), "GtkScale { \n" " background-image: -gtk-gradient (linear, left top, right bottom, from(rgb(250, 250, 230)), to(rgb(0, 160, 0)));\n" "}\n", -1, NULL); bsc_provider = gtk_css_provider_new(); gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(bsc_provider), "GtkScale { \n" " background-image: -gtk-gradient (linear, left top, right bottom, from(rgb(250, 250, 230)), to(rgb(0, 0, 160)));\n" "}\n", -1, NULL); /* I wanted to make the handle larger and set its color to #90ee90 -- no way! */ pd_provider = gtk_css_provider_new(); gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(pd_provider), "GtkPaned { \n" " background-color: #fffff0;\n" "}\n", -1, NULL); cb_provider = gtk_css_provider_new(); gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(cb_provider), "GtkRadioButton:hover, GtkCheckButton:hover { \n" " background-color: rgb(200, 200, 190);\n" "}\n", -1, NULL); /* gtk3 tree view is inaccessible in filechooser and row colors can't be set! */ } #endif snd-16.1/s7.h0000644000076400007640000016314412622067374011057 0ustar bilbil#ifndef S7_H #define S7_H #define S7_VERSION "4.2" #define S7_DATE "6-Nov-15" typedef long long int s7_int; /* This sets the size of integers in Scheme; it needs to be big enough to accomodate a C pointer. */ typedef double s7_double; /* similarly for Scheme reals; only "double" works in C++ */ /* old forms... */ typedef s7_int s7_Int; typedef s7_double s7_Double; #include #ifndef __cplusplus #ifndef _MSC_VER #include #else #ifndef true #define bool unsigned char #define true 1 #define false 0 #endif #endif #endif #ifdef __cplusplus extern "C" { #endif typedef struct s7_scheme s7_scheme; typedef struct s7_cell *s7_pointer; s7_scheme *s7_init(void); /* s7_scheme is our interpreter * s7_pointer is a Scheme object of any (Scheme) type * s7_init creates the interpreter. */ typedef s7_pointer (*s7_function)(s7_scheme *sc, s7_pointer args); /* that is, obj = func(s7, args) -- args is a list of arguments */ s7_pointer s7_f(s7_scheme *sc); /* #f */ s7_pointer s7_t(s7_scheme *sc); /* #t */ s7_pointer s7_nil(s7_scheme *sc); /* () */ s7_pointer s7_undefined(s7_scheme *sc); /* # */ s7_pointer s7_unspecified(s7_scheme *sc); /* # */ bool s7_is_unspecified(s7_scheme *sc, s7_pointer val); /* returns true if val is # */ s7_pointer s7_eof_object(s7_scheme *sc); /* # */ bool s7_is_null(s7_scheme *sc, s7_pointer p); /* null? */ /* these are the Scheme constants; they do not change in value during a run, * so they can be safely assigned to C global variables if desired. */ bool s7_is_valid(s7_scheme *sc, s7_pointer arg); /* does 'arg' look like an s7 object? */ bool s7_is_c_pointer(s7_pointer arg); void *s7_c_pointer(s7_pointer p); s7_pointer s7_make_c_pointer(s7_scheme *sc, void *ptr); /* these are for passing uninterpreted C pointers through Scheme */ s7_pointer s7_eval_c_string(s7_scheme *sc, const char *str); /* (eval-string str) */ s7_pointer s7_eval_c_string_with_environment(s7_scheme *sc, const char *str, s7_pointer e); s7_pointer s7_object_to_string(s7_scheme *sc, s7_pointer arg, bool use_write); /* (object->string obj) */ char *s7_object_to_c_string(s7_scheme *sc, s7_pointer obj); /* same as object->string but returns a C char* directly */ /* the returned value should be freed by the caller */ s7_pointer s7_load(s7_scheme *sc, const char *file); /* (load file) */ s7_pointer s7_load_path(s7_scheme *sc); /* *load-path* */ s7_pointer s7_add_to_load_path(s7_scheme *sc, const char *dir); /* (set! *load-path* (cons dir *load-path*)) */ s7_pointer s7_autoload(s7_scheme *sc, s7_pointer symbol, s7_pointer file_or_function); /* (autoload symbol file-or-function) */ /* the load path is a list of directories to search if load can't find the file passed as its argument. */ void s7_quit(s7_scheme *sc); /* this tries to break out of the current evaluation, leaving everything else intact */ void (*s7_begin_hook(s7_scheme *sc))(s7_scheme *sc, bool *val); void s7_set_begin_hook(s7_scheme *sc, void (*hook)(s7_scheme *sc, bool *val)); /* call "hook" at the start of any block; use NULL to cancel. * s7_begin_hook returns the current begin_hook function or NULL. */ s7_pointer s7_eval(s7_scheme *sc, s7_pointer code, s7_pointer e); /* (eval code e) -- e is the optional environment */ s7_pointer s7_eval_form(s7_scheme *sc, s7_pointer form, s7_pointer e); void s7_provide(s7_scheme *sc, const char *feature); /* add feature (as a symbol) to the *features* list */ bool s7_is_provided(s7_scheme *sc, const char *feature); /* (provided? feature) */ s7_pointer s7_error(s7_scheme *sc, s7_pointer type, s7_pointer info); s7_pointer s7_wrong_type_arg_error(s7_scheme *sc, const char *caller, int arg_n, s7_pointer arg, const char *descr); /* set arg_n to 0 to indicate that caller takes only one argument (so the argument number need not be reported */ s7_pointer s7_out_of_range_error(s7_scheme *sc, const char *caller, int arg_n, s7_pointer arg, const char *descr); s7_pointer s7_wrong_number_of_args_error(s7_scheme *sc, const char *caller, s7_pointer args); s7_pointer s7_stacktrace(s7_scheme *sc); /* these are equivalent to (error ...) in Scheme * the first argument to s7_error is a symbol that can be caught (via (catch tag ...)) * the rest of the arguments are passed to the error handler (if in catch) * or printed out (in the default case). If the first element of the list * of args ("info") is a string, the default error handler treats it as * a format control string, and passes it to format with the rest of the * info list as the format function arguments. * * s7_wrong_type_arg_error is equivalent to s7_error with a type of 'wrong-type-arg * and similarly s7_out_of_range_error with type 'out-of-range. * * catch in Scheme is taken from Guile: * * (catch tag thunk handler) * * evaluates 'thunk'. If an error occurs, and the type matches 'tag' (or if 'tag' is #t), * the handler is called, passing it the arguments (including the type) passed to the * error function. If no handler is found, the default error handler is called, * normally printing the error arguments to current-error-port. */ unsigned int s7_gc_protect(s7_scheme *sc, s7_pointer x); void s7_gc_unprotect(s7_scheme *sc, s7_pointer x); void s7_gc_unprotect_at(s7_scheme *sc, unsigned int loc); s7_pointer s7_gc_protected_at(s7_scheme *sc, unsigned int loc); s7_pointer s7_gc_on(s7_scheme *sc, bool on); void s7_gc_stats(s7_scheme *sc, bool on); unsigned int s7_heap_size(s7_scheme *sc); int s7_gc_freed(s7_scheme *sc); /* any s7_pointer object held in C (as a local variable for example) needs to be * protected from garbage collection if there is any chance the GC may run without * an existing Scheme-level reference to that object. s7_gc_protect places the * object in a vector that the GC always checks, returning the object's location * in that table. s7_gc_unprotect and s7_gc_unprotect_at unprotect the object * (remove it from the vector). s7_gc_unprotect_at uses the location passed * to it, whereas s7_gc_unprotect scans the vector to find the object. * s7_gc_protected_at returns the object at the given location. * * You can turn the GC on and off via s7_gc_on. * * There is a built-in lag between the creation of a new object and its first possible GC * (the lag time is set indirectly by GC_TEMPS_SIZE in s7.c), so you don't need to worry about * very short term temps such as the arguments to s7_cons in: * * s7_cons(s7, s7_make_real(s7, 3.14), * s7_cons(s7, s7_make_integer(s7, 123), * s7_nil(s7))); */ bool s7_is_eq(s7_pointer a, s7_pointer b); /* (eq? a b) */ bool s7_is_eqv(s7_pointer a, s7_pointer b); /* (eqv? a b) */ bool s7_is_equal(s7_scheme *sc, s7_pointer a, s7_pointer b); /* (equal? a b) */ bool s7_is_boolean(s7_pointer x); /* (boolean? x) */ bool s7_boolean(s7_scheme *sc, s7_pointer x); /* Scheme boolean -> C bool */ s7_pointer s7_make_boolean(s7_scheme *sc, bool x); /* C bool -> Scheme boolean */ /* for each Scheme type (boolean, integer, string, etc), there are three * functions: s7_(...), s7_make_(...), and s7_is_(...): * * s7_boolean(s7, obj) returns the C bool corresponding to the value of 'obj' (#f -> false) * s7_make_boolean(s7, false|true) returns the s7 boolean corresponding to the C bool argument (false -> #f) * s7_is_boolean(s7, obj) returns true if 'obj' has a boolean value (#f or #t). */ bool s7_is_pair(s7_pointer p); /* (pair? p) */ s7_pointer s7_cons(s7_scheme *sc, s7_pointer a, s7_pointer b); /* (cons a b) */ s7_pointer s7_car(s7_pointer p); /* (car p) */ s7_pointer s7_cdr(s7_pointer p); /* (cdr p) */ s7_pointer s7_set_car(s7_pointer p, s7_pointer q); /* (set-car! p q) */ s7_pointer s7_set_cdr(s7_pointer p, s7_pointer q); /* (set-cdr! p q) */ s7_pointer s7_cadr(s7_pointer p); /* (cadr p) */ s7_pointer s7_cddr(s7_pointer p); /* (cddr p) */ s7_pointer s7_cdar(s7_pointer p); /* (cdar p) */ s7_pointer s7_caar(s7_pointer p); /* (caar p) */ s7_pointer s7_caadr(s7_pointer p); /* etc */ s7_pointer s7_caddr(s7_pointer p); s7_pointer s7_cadar(s7_pointer p); s7_pointer s7_caaar(s7_pointer p); s7_pointer s7_cdadr(s7_pointer p); s7_pointer s7_cdddr(s7_pointer p); s7_pointer s7_cddar(s7_pointer p); s7_pointer s7_cdaar(s7_pointer p); s7_pointer s7_caaadr(s7_pointer p); s7_pointer s7_caaddr(s7_pointer p); s7_pointer s7_caadar(s7_pointer p); s7_pointer s7_caaaar(s7_pointer p); s7_pointer s7_cadadr(s7_pointer p); s7_pointer s7_cadddr(s7_pointer p); s7_pointer s7_caddar(s7_pointer p); s7_pointer s7_cadaar(s7_pointer p); s7_pointer s7_cdaadr(s7_pointer p); s7_pointer s7_cdaddr(s7_pointer p); s7_pointer s7_cdadar(s7_pointer p); s7_pointer s7_cdaaar(s7_pointer p); s7_pointer s7_cddadr(s7_pointer p); s7_pointer s7_cddddr(s7_pointer p); s7_pointer s7_cdddar(s7_pointer p); s7_pointer s7_cddaar(s7_pointer p); bool s7_is_list(s7_scheme *sc, s7_pointer p); /* (list? p) -> (or (pair? p) (null? p)) */ int s7_list_length(s7_scheme *sc, s7_pointer a); /* (length a) */ s7_pointer s7_list(s7_scheme *sc, int num_values, ...); /* (list ...) */ s7_pointer s7_reverse(s7_scheme *sc, s7_pointer a); /* (reverse a) */ s7_pointer s7_append(s7_scheme *sc, s7_pointer a, s7_pointer b); /* (append a b) */ s7_pointer s7_list_ref(s7_scheme *sc, s7_pointer lst, int num); /* (list-ref lst num) */ s7_pointer s7_list_set(s7_scheme *sc, s7_pointer lst, int num, s7_pointer val); /* (list-set! lst num val) */ s7_pointer s7_assoc(s7_scheme *sc, s7_pointer obj, s7_pointer lst); /* (assoc obj lst) */ s7_pointer s7_assq(s7_scheme *sc, s7_pointer obj, s7_pointer x); /* (assq obj lst) */ s7_pointer s7_member(s7_scheme *sc, s7_pointer obj, s7_pointer lst); /* (member obj lst) */ s7_pointer s7_memq(s7_scheme *sc, s7_pointer obj, s7_pointer x); /* (memq obj lst) */ bool s7_is_string(s7_pointer p); /* (string? p) */ const char *s7_string(s7_pointer p); /* Scheme string -> C string (do not free the string) */ s7_pointer s7_make_string(s7_scheme *sc, const char *str); /* C string -> Scheme string (str is copied) */ s7_pointer s7_make_string_with_length(s7_scheme *sc, const char *str, int len); /* same as s7_make_string, but provides strlen */ s7_pointer s7_make_permanent_string(const char *str); /* make a string that will never be GC'd */ unsigned int s7_string_length(s7_pointer str); /* (string-length str) */ bool s7_is_character(s7_pointer p); /* (character? p) */ char s7_character(s7_pointer p); /* Scheme character -> C char */ s7_pointer s7_make_character(s7_scheme *sc, unsigned int c); /* C char (as unsigned int) -> Scheme character */ bool s7_is_number(s7_pointer p); /* (number? p) */ bool s7_is_integer(s7_pointer p); /* (integer? p) */ s7_int s7_integer(s7_pointer p); /* Scheme integer -> C int (long long int probably) */ s7_pointer s7_make_integer(s7_scheme *sc, s7_int num); /* C long long int -> Scheme integer */ bool s7_is_real(s7_pointer p); /* (real? p) */ s7_double s7_real(s7_pointer p); /* Scheme real -> C double */ s7_pointer s7_make_real(s7_scheme *sc, s7_double num); /* C double -> Scheme real */ s7_pointer s7_make_mutable_real(s7_scheme *sc, s7_double n); s7_double s7_number_to_real(s7_scheme *sc, s7_pointer x); /* x can be any kind of number */ s7_double s7_number_to_real_with_caller(s7_scheme *sc, s7_pointer x, const char *caller); s7_int s7_number_to_integer(s7_scheme *sc, s7_pointer x); s7_int s7_number_to_integer_with_caller(s7_scheme *sc, s7_pointer x, const char *caller); bool s7_is_ulong(s7_pointer arg); /* returns true if arg is an unsigned long */ unsigned long s7_ulong(s7_pointer p); /* Scheme unsigned long -> C */ s7_pointer s7_make_ulong(s7_scheme *sc, unsigned long n); /* C unsigned lonog -> Scheme */ bool s7_is_ulong_long(s7_pointer arg); /* returns true if arg is an unsigned long long */ unsigned long long s7_ulong_long(s7_pointer p); /* Scheme unsigned long long -> C */ s7_pointer s7_make_ulong_long(s7_scheme *sc, unsigned long long n); /* C unsigned long long -> Scheme */ /* the ulong stuff is intended for passing uninterpreted C pointers through Scheme and back to C */ bool s7_is_rational(s7_pointer arg); /* (rational? arg) -- integer or ratio */ bool s7_is_ratio(s7_pointer arg); /* true if arg is a ratio, not an integer */ s7_pointer s7_make_ratio(s7_scheme *sc, s7_int a, s7_int b); /* returns the Scheme object a/b */ s7_pointer s7_rationalize(s7_scheme *sc, s7_double x, s7_double error); /* (rationalize x error) */ s7_int s7_numerator(s7_pointer x); /* (numerator x) */ s7_int s7_denominator(s7_pointer x); /* (denominator x) */ s7_double s7_random(s7_scheme *sc, s7_pointer state); /* (random x) */ s7_pointer s7_random_state(s7_scheme *sc, s7_pointer seed); /* (random-state seed) */ s7_pointer s7_random_state_to_list(s7_scheme *sc, s7_pointer args); /* (random-state->list r) */ void s7_set_default_random_state(s7_scheme *sc, s7_int seed, s7_int carry); bool s7_is_complex(s7_pointer arg); /* (complex? arg) */ s7_pointer s7_make_complex(s7_scheme *sc, s7_double a, s7_double b); /* returns the Scheme object a+bi */ s7_double s7_real_part(s7_pointer z); /* (real-part z) */ s7_double s7_imag_part(s7_pointer z); /* (imag-part z) */ char *s7_number_to_string(s7_scheme *sc, s7_pointer obj, int radix); /* (number->string obj radix) */ bool s7_is_vector(s7_pointer p); /* (vector? p) */ s7_int s7_vector_length(s7_pointer vec); /* (vector-length vec) */ int s7_vector_rank(s7_pointer vect); /* number of dimensions in vect */ s7_int *s7_vector_dimensions(s7_pointer vec); /* dimensions */ s7_int *s7_vector_offsets(s7_pointer vec); /* precalculated offsets to speed-up addressing */ s7_pointer *s7_vector_elements(s7_pointer vec); /* a pointer to the array of s7_pointers */ s7_int *s7_int_vector_elements(s7_pointer vec); s7_double *s7_float_vector_elements(s7_pointer vec); bool s7_is_float_vector(s7_pointer p); bool s7_is_int_vector(s7_pointer p); s7_pointer s7_vector_ref(s7_scheme *sc, s7_pointer vec, s7_int index); /* (vector-ref vec index) */ s7_pointer s7_vector_set(s7_scheme *sc, s7_pointer vec, s7_int index, s7_pointer a); /* (vector-set! vec index a) */ s7_pointer s7_vector_ref_n(s7_scheme *sc, s7_pointer vector, int indices, ...); /* multidimensional vector-ref */ s7_pointer s7_vector_set_n(s7_scheme *sc, s7_pointer vector, s7_pointer value, int indices, ...); /* multidimensional vector-set! */ s7_pointer s7_make_vector(s7_scheme *sc, s7_int len); /* (make-vector len) */ s7_pointer s7_make_int_vector(s7_scheme *sc, s7_int len, int dims, s7_int *dim_info); s7_pointer s7_make_float_vector(s7_scheme *sc, s7_int len, int dims, s7_int *dim_info); s7_pointer s7_make_float_vector_wrapper(s7_scheme *sc, s7_int len, s7_double *data, int dims, s7_int *dim_info, bool free_data); s7_pointer s7_make_and_fill_vector(s7_scheme *sc, s7_int len, s7_pointer fill); /* (make-vector len fill) */ void s7_vector_fill(s7_scheme *sc, s7_pointer vec, s7_pointer obj); /* (vector-fill! vec obj) */ s7_pointer s7_vector_copy(s7_scheme *sc, s7_pointer old_vect); s7_pointer s7_vector_to_list(s7_scheme *sc, s7_pointer vect); /* (vector->list vec) */ s7_int s7_print_length(s7_scheme *sc); /* value of (*s7* 'print-length) */ s7_int s7_set_print_length(s7_scheme *sc, s7_int new_len); /* * (vect i) is the same as (vector-ref vect i) * (set! (vect i) x) is the same as (vector-set! vect i x) * (vect i j k) accesses the 3-dimensional vect * (set! (vect i j k) x) sets that element (vector-ref and vector-set! can also be used) * (make-vector (list 2 3 4)) returns a 3-dimensional vector with the given dimension sizes * (make-vector '(2 3) 1.0) returns a 2-dim vector with all elements set to 1.0 */ bool s7_is_hash_table(s7_pointer p); /* (hash-table? p) */ s7_pointer s7_make_hash_table(s7_scheme *sc, s7_int size); /* (make-hash-table size) */ s7_pointer s7_hash_table_ref(s7_scheme *sc, s7_pointer table, s7_pointer key); /* (hash-table-ref table key) */ s7_pointer s7_hash_table_set(s7_scheme *sc, s7_pointer table, s7_pointer key, s7_pointer value); /* (hash-table-set! table key value) */ s7_pointer s7_hook_functions(s7_scheme *sc, s7_pointer hook); /* (hook-functions hook) */ s7_pointer s7_hook_set_functions(s7_scheme *sc, s7_pointer hook, s7_pointer functions); /* (set! (hook-functions hook) ...) */ bool s7_is_input_port(s7_scheme *sc, s7_pointer p); /* (input-port? p) */ bool s7_is_output_port(s7_scheme *sc, s7_pointer p); /* (output-port? p) */ const char *s7_port_filename(s7_pointer x); /* (port-filename p) */ int s7_port_line_number(s7_pointer p); /* (port-line-number p) */ s7_pointer s7_current_input_port(s7_scheme *sc); /* (current-input-port) */ s7_pointer s7_set_current_input_port(s7_scheme *sc, s7_pointer p); /* (set-current-input-port) */ s7_pointer s7_current_output_port(s7_scheme *sc); /* (current-output-port) */ s7_pointer s7_set_current_output_port(s7_scheme *sc, s7_pointer p); /* (set-current-output-port) */ s7_pointer s7_current_error_port(s7_scheme *sc); /* (current-error-port) */ s7_pointer s7_set_current_error_port(s7_scheme *sc, s7_pointer port); /* (set-current-error-port port) */ void s7_close_input_port(s7_scheme *sc, s7_pointer p); /* (close-input-port p) */ void s7_close_output_port(s7_scheme *sc, s7_pointer p); /* (close-output-port p) */ s7_pointer s7_open_input_file(s7_scheme *sc, const char *name, const char *mode); /* (open-input-file name mode) */ s7_pointer s7_open_output_file(s7_scheme *sc, const char *name, const char *mode); /* (open-output-file name mode) */ /* mode here is an optional C style flag, "a" for "alter", etc ("r" is the input default, "w" is the output default) */ s7_pointer s7_open_input_string(s7_scheme *sc, const char *input_string); /* (open-input-string str) */ s7_pointer s7_open_output_string(s7_scheme *sc); /* (open-output-string) */ const char *s7_get_output_string(s7_scheme *sc, s7_pointer out_port); /* (get-output-string port) -- current contents of output string */ /* don't free the string */ void s7_flush_output_port(s7_scheme *sc, s7_pointer p); /* (flush-output-port port) */ typedef enum {S7_READ, S7_READ_CHAR, S7_READ_LINE, S7_READ_BYTE, S7_PEEK_CHAR, S7_IS_CHAR_READY} s7_read_t; s7_pointer s7_open_output_function(s7_scheme *sc, void (*function)(s7_scheme *sc, unsigned char c, s7_pointer port)); s7_pointer s7_open_input_function(s7_scheme *sc, s7_pointer (*function)(s7_scheme *sc, s7_read_t read_choice, s7_pointer port)); int s7_read_char(s7_scheme *sc, s7_pointer port); /* (read-char port) */ int s7_peek_char(s7_scheme *sc, s7_pointer port); /* (peek-char port) */ s7_pointer s7_read(s7_scheme *sc, s7_pointer port); /* (read port) */ void s7_newline(s7_scheme *sc, s7_pointer port); /* (newline port) */ void s7_write_char(s7_scheme *sc, int c, s7_pointer port); /* (write-char c port) */ void s7_write(s7_scheme *sc, s7_pointer obj, s7_pointer port); /* (write obj port) */ void s7_display(s7_scheme *sc, s7_pointer obj, s7_pointer port); /* (display obj port) */ const char *s7_format(s7_scheme *sc, s7_pointer args); /* (format ... */ bool s7_is_procedure(s7_pointer x); /* (procedure? x) */ bool s7_is_macro(s7_scheme *sc, s7_pointer x); /* (macro? x) */ s7_pointer s7_closure_body(s7_scheme *sc, s7_pointer p); s7_pointer s7_closure_let(s7_scheme *sc, s7_pointer p); s7_pointer s7_closure_args(s7_scheme *sc, s7_pointer p); s7_pointer s7_funclet(s7_scheme *sc, s7_pointer p); /* (funclet x) */ const char *s7_procedure_documentation(s7_scheme *sc, s7_pointer p); /* (procedure-documentation x) if any (don't free the string) */ s7_pointer s7_make_signature(s7_scheme *sc, int len, ...); /* procedure-signature data */ s7_pointer s7_make_circular_signature(s7_scheme *sc, int cycle_point, int len, ...); bool s7_is_aritable(s7_scheme *sc, s7_pointer x, int args); /* (aritable? x args) */ s7_pointer s7_arity(s7_scheme *sc, s7_pointer x); /* (arity x) */ const char *s7_help(s7_scheme *sc, s7_pointer obj); /* (help obj) */ s7_pointer s7_make_continuation(s7_scheme *sc); /* call/cc... (see example below) */ bool s7_is_syntax(s7_pointer p); bool s7_is_symbol(s7_pointer p); /* (symbol? p) */ const char *s7_symbol_name(s7_pointer p); /* (symbol->string p) -- don't free the string */ s7_pointer s7_make_symbol(s7_scheme *sc, const char *name); /* (string->symbol name) */ s7_pointer s7_gensym(s7_scheme *sc, const char *prefix); /* (gensym prefix) */ bool s7_is_keyword(s7_pointer obj); /* (keyword? obj) */ s7_pointer s7_make_keyword(s7_scheme *sc, const char *key); /* (make-keyword key) */ s7_pointer s7_symbol_access(s7_scheme *sc, s7_pointer sym); s7_pointer s7_symbol_set_access(s7_scheme *sc, s7_pointer symbol, s7_pointer func); s7_pointer s7_slot(s7_scheme *sc, s7_pointer symbol); s7_pointer s7_slot_value(s7_pointer slot); s7_pointer s7_slot_set_value(s7_scheme *sc, s7_pointer slot, s7_pointer value); s7_pointer s7_make_slot(s7_scheme *sc, s7_pointer env, s7_pointer symbol, s7_pointer value); s7_pointer s7_rootlet(s7_scheme *sc); /* (rootlet) */ s7_pointer s7_shadow_rootlet(s7_scheme *sc); s7_pointer s7_set_shadow_rootlet(s7_scheme *sc, s7_pointer let); s7_pointer s7_curlet(s7_scheme *sc); /* (curlet) */ s7_pointer s7_set_curlet(s7_scheme *sc, s7_pointer e); /* returns previous curlet */ s7_pointer s7_outlet(s7_scheme *sc, s7_pointer e); /* (outlet e) */ s7_pointer s7_sublet(s7_scheme *sc, s7_pointer env, s7_pointer bindings); /* (sublet e ...) */ s7_pointer s7_inlet(s7_scheme *sc, s7_pointer bindings); /* (inlet ...) */ s7_pointer s7_let_to_list(s7_scheme *sc, s7_pointer env); /* (let->list env) */ bool s7_is_let(s7_pointer e); /* )let? e) */ s7_pointer s7_let_ref(s7_scheme *sc, s7_pointer env, s7_pointer sym); /* (let-ref e sym) */ s7_pointer s7_let_set(s7_scheme *sc, s7_pointer env, s7_pointer sym, s7_pointer val); /* (let-set! e sym val) */ s7_pointer s7_openlet(s7_scheme *sc, s7_pointer e); /* (openlet e) */ bool s7_is_openlet(s7_pointer e); /* (openlet? e) */ s7_pointer s7_method(s7_scheme *sc, s7_pointer obj, s7_pointer method); s7_pointer s7_name_to_value(s7_scheme *sc, const char *name); s7_pointer s7_symbol_table_find_name(s7_scheme *sc, const char *name); s7_pointer s7_symbol_value(s7_scheme *sc, s7_pointer sym); s7_pointer s7_symbol_set_value(s7_scheme *sc, s7_pointer sym, s7_pointer val); s7_pointer s7_symbol_local_value(s7_scheme *sc, s7_pointer sym, s7_pointer local_env); char *s7_symbol_documentation(s7_scheme *sc, s7_pointer sym); char *s7_symbol_set_documentation(s7_scheme *sc, s7_pointer sym, const char *new_doc); bool s7_for_each_symbol_name(s7_scheme *sc, bool (*symbol_func)(const char *symbol_name, void *data), void *data); bool s7_for_each_symbol(s7_scheme *sc, bool (*symbol_func)(const char *symbol_name, s7_pointer value, void *data), void *data); /* these access the current environment and symbol table, providing * a symbol's current binding (s7_name_to_value takes the symbol name as a char*, * s7_symbol_value takes the symbol itself, s7_symbol_set_value changes the * current binding, and s7_symbol_local_value uses the environment passed * as its third argument). * * To iterate over the complete symbol table, use s7_for_each_symbol_name, * and s7_for_each_symbol. The latter calls the 'symbol_func' on each * symbol, passing the symbol name, its current binding, and the uninterpreted * 'data' pointer. s7_for_each_symbol_name is similar, but does not include * the current binding. * * The for-each loop stops if the symbol_func returns true, or at the end of the table. */ void s7_define(s7_scheme *sc, s7_pointer env, s7_pointer symbol, s7_pointer value); bool s7_is_defined(s7_scheme *sc, const char *name); s7_pointer s7_define_variable(s7_scheme *sc, const char *name, s7_pointer value); s7_pointer s7_define_variable_with_documentation(s7_scheme *sc, const char *name, s7_pointer value, const char *help); s7_pointer s7_define_constant(s7_scheme *sc, const char *name, s7_pointer value); s7_pointer s7_define_constant_with_documentation(s7_scheme *sc, const char *name, s7_pointer value, const char *help); bool s7_is_constant(s7_pointer p); /* These three functions add a symbol and its binding to either the top-level environment * or the 'env' passed as the second argument to s7_define. * * s7_define_variable(sc, "*features*", sc->NIL); * * in s7.c is equivalent to the top level form * * (define *features* ()) * * s7_define_variable is simply s7_define with string->symbol and the global environment. * s7_define_constant is s7_define but makes its "definee" immutable. * s7_define is equivalent to define in Scheme. */ bool s7_is_function(s7_pointer p); s7_pointer s7_make_function(s7_scheme *sc, const char *name, s7_function fnc, int required_args, int optional_args, bool rest_arg, const char *doc); s7_pointer s7_make_safe_function(s7_scheme *sc, const char *name, s7_function fnc, int required_args, int optional_args, bool rest_arg, const char *doc); s7_pointer s7_make_typed_function(s7_scheme *sc, const char *name, s7_function f, int required_args, int optional_args, bool rest_arg, const char *doc, s7_pointer signature); s7_pointer s7_define_function(s7_scheme *sc, const char *name, s7_function fnc, int required_args, int optional_args, bool rest_arg, const char *doc); s7_pointer s7_define_safe_function(s7_scheme *sc, const char *name, s7_function fnc, int required_args, int optional_args, bool rest_arg, const char *doc); s7_pointer s7_define_typed_function(s7_scheme *sc, const char *name, s7_function fnc, int required_args, int optional_args, bool rest_arg, const char *doc, s7_pointer signature); void s7_define_function_star(s7_scheme *sc, const char *name, s7_function fnc, const char *arglist, const char *doc); void s7_define_safe_function_star(s7_scheme *sc, const char *name, s7_function fnc, const char *arglist, const char *doc); void s7_define_function_with_setter(s7_scheme *sc, const char *name, s7_function get_fnc, s7_function set_fnc, int req_args, int opt_args, const char *doc); /* this is now the same as s7_dilambda (different args) */ s7_pointer s7_apply_function(s7_scheme *sc, s7_pointer fnc, s7_pointer args); s7_pointer s7_define_macro(s7_scheme *sc, const char *name, s7_function fnc, int required_args, int optional_args, bool rest_arg, const char *doc); /* s7_make_function creates a Scheme function object from the s7_function 'fnc'. * Its name (for s7_describe_object) is 'name', it requires 'required_args' arguments, * can accept 'optional_args' other arguments, and if 'rest_arg' is true, it accepts * a "rest" argument (a list of all the trailing arguments). The function's documentation * is 'doc'. * * s7_define_function is the same as s7_make_function, but it also adds 'name' (as a symbol) to the * global (top-level) environment, with the function as its value. For example, the Scheme * function 'car' is essentially: * * s7_pointer g_car(s7_scheme *sc, s7_pointer args) * {return(s7_car(sc, s7_car(sc, args)));} * * then bound to the name "car": * * s7_define_function(sc, "car", g_car, 1, 0, false, "(car obj)"); * one required arg, no optional arg, no "rest" arg * * s7_is_function returns true if its argument is a function defined in this manner. * s7_apply_function applies the function (the result of s7_make_function) to the arguments. * * s7_define_macro defines a Scheme macro; its arguments are not evaluated (unlike a function), * but its returned value (assumed to be some sort of Scheme expression) is evaluated. */ /* In s7, (define* (name . args) body) or (define name (lambda* args body)) * define a function that takes optional (keyword) named arguments. * The "args" is a list that can contain either names (normal arguments), * or lists of the form (name default-value), in any order. When called, * the names are bound to their default values (or #f), then the function's * current arglist is scanned. Any name that occurs as a keyword (":name") * precedes that argument's new value. Otherwise, as values occur, they * are plugged into the environment based on their position in the arglist * (as normal for a function). So, * * (define* (hi a (b 32) (c "hi")) (list a b c)) * (hi 1) -> '(1 32 "hi") * (hi :b 2 :a 3) -> '(3 2 "hi") * (hi 3 2 1) -> '(3 2 1) * * :rest causes its argument to be bound to the rest of the arguments at that point. * * The C connection to this takes the function name, the C function to call, the argument * list as written in Scheme, and the documentation string. s7 makes sure the arguments * are ordered correctly and have the specified defaults before calling the C function. * s7_define_function_star(sc, "a-func", a_func, "arg1 (arg2 32)", "an example of C define*"); * Now (a-func :arg1 2) calls the C function a_func(2, 32). See the example program in s7.html. * * In s7 Scheme, define* can be used just for its optional arguments feature, but that is * included in s7_define_function. s7_define_function_star implements keyword arguments * for C-level functions (as well as optional/rest arguments). */ s7_pointer s7_call(s7_scheme *sc, s7_pointer func, s7_pointer args); s7_pointer s7_call_with_location(s7_scheme *sc, s7_pointer func, s7_pointer args, const char *caller, const char *file, int line); /* s7_call takes a Scheme function (e.g. g_car above), and applies it to 'args' (a list of arguments) * returning the result. * * s7_integer(s7_call(s7, g_car, s7_cons(s7, s7_make_integer(s7, 123), s7_nil(s7)))); * * returns 123. * * s7_call_with_location passes some information to the error handler. */ s7_pointer s7_dynamic_wind(s7_scheme *sc, s7_pointer init, s7_pointer body, s7_pointer finish); bool s7_is_dilambda(s7_pointer obj); s7_pointer s7_dilambda(s7_scheme *sc, const char *name, s7_pointer (*getter)(s7_scheme *sc, s7_pointer args), int get_req_args, int get_opt_args, s7_pointer (*setter)(s7_scheme *sc, s7_pointer args), int set_req_args, int set_opt_args, const char *documentation); s7_pointer s7_typed_dilambda(s7_scheme *sc, const char *name, s7_pointer (*getter)(s7_scheme *sc, s7_pointer args), int get_req_args, int get_opt_args, s7_pointer (*setter)(s7_scheme *sc, s7_pointer args), int set_req_args, int set_opt_args, const char *documentation, s7_pointer get_sig, s7_pointer set_sig); s7_pointer s7_procedure_setter(s7_scheme *sc, s7_pointer obj); s7_pointer s7_values(s7_scheme *sc, s7_pointer args); s7_pointer s7_make_iterator(s7_scheme *sc, s7_pointer e); bool s7_is_iterator(s7_pointer obj); bool s7_iterator_is_at_end(s7_pointer obj); s7_pointer s7_iterate(s7_scheme *sc, s7_pointer iter); /* ancient form -- backwards compatibility */ int s7_new_type(const char *name, char *(*print)(s7_scheme *sc, void *value), void (*free)(void *value), bool (*equal)(void *val1, void *val2), void (*gc_mark)(void *val), s7_pointer (*apply)(s7_scheme *sc, s7_pointer obj, s7_pointer args), s7_pointer (*set)(s7_scheme *sc, s7_pointer obj, s7_pointer args)); /* new form */ int s7_new_type_x(s7_scheme *sc, const char *name, char *(*print)(s7_scheme *sc, void *value), void (*free)(void *value), bool (*equal)(void *val1, void *val2), void (*gc_mark)(void *val), s7_pointer (*apply)(s7_scheme *sc, s7_pointer obj, s7_pointer args), s7_pointer (*set)(s7_scheme *sc, s7_pointer obj, s7_pointer args), s7_pointer (*length)(s7_scheme *sc, s7_pointer obj), s7_pointer (*copy)(s7_scheme *sc, s7_pointer args), s7_pointer (*reverse)(s7_scheme *sc, s7_pointer obj), s7_pointer (*fill)(s7_scheme *sc, s7_pointer args)); bool s7_is_object(s7_pointer p); int s7_object_type(s7_pointer obj); void *s7_object_value(s7_pointer obj); void *s7_object_value_checked(s7_pointer obj, int type); s7_pointer s7_make_object(s7_scheme *sc, int type, void *value); void s7_mark_object(s7_pointer p); s7_pointer s7_object_let(s7_pointer obj); s7_pointer s7_object_set_let(s7_pointer obj, s7_pointer e); void s7_set_object_print_readably(int type, char *(*printer)(s7_scheme *sc, void *val)); /* These functions create a new Scheme object type. There is a simple example in s7.html. * * s7_new_type describes the type for Scheme: * name: the name used by describe-object * print: the function called whenever s7 is asked to display a value with this type * free: the function called when an object of this type is about to be garbage collected * equal: compare two objects of this type; (equal? obj1 obj2) * gc_mark: called during the GC mark pass -- you should call s7_mark_object * on any embedded s7_pointer associated with the object. * apply: a function that is called whenever an object of this type * occurs in the function position (at the car of a list; the rest of the list * is passed to the apply function as the arguments). * set: a function that is called whenever an object of this type occurs as * the target of a generalized set! * * in the extended version (s7_new_type_x), you can also set the following: * length: the function called when the object is asked what its length is. * copy: the function called when a copy of the object is needed. * fill: the function called to fill the object with some value. * * s7_new_type and s7_new_typ_x return an integer that identifies the new type for the other functions. * * s7_is_object returns true if 'p' holds a value of a type created by s7_new_type. * s7_object_type returns the object's type * s7_object_value returns the value bound to that object (the void *value of s7_make_object) * s7_make_object creates a new Scheme entity of the given type with the given (uninterpreted) value * s7_mark_object marks any Scheme object as in-use (use this in the gc_mark function to mark * any embedded s7_pointer variables). */ void s7_autoload_set_names(s7_scheme *sc, const char **names, int size); s7_pointer s7_copy(s7_scheme *sc, s7_pointer args); s7_pointer s7_fill(s7_scheme *sc, s7_pointer args); /* these are aimed at the CLM optimizer -- they change daily! */ typedef s7_double (*s7_rf_t)(s7_scheme *sc, s7_pointer **p); typedef s7_rf_t (*s7_rp_t)(s7_scheme *sc, s7_pointer expr); void s7_rf_set_function(s7_pointer f, s7_rp_t rp); s7_rp_t s7_rf_function(s7_scheme *sc, s7_pointer func); s7_rf_t s7_rf_1(s7_scheme *sc, s7_pointer expr, s7_rf_t r, s7_rf_t s, s7_rf_t x); s7_rf_t s7_rf_2(s7_scheme *sc, s7_pointer expr, s7_rf_t rr, s7_rf_t sr, s7_rf_t xr, s7_rf_t rs, s7_rf_t ss, s7_rf_t xs, s7_rf_t rx, s7_rf_t sx, s7_rf_t xx); typedef s7_int (*s7_if_t)(s7_scheme *sc, s7_pointer **p); typedef s7_if_t (*s7_ip_t)(s7_scheme *sc, s7_pointer expr); void s7_if_set_function(s7_pointer f, s7_ip_t rp); s7_ip_t s7_if_function(s7_scheme *sc, s7_pointer func); typedef s7_pointer (*s7_pf_t)(s7_scheme *sc, s7_pointer **p); typedef s7_pf_t (*s7_pp_t)(s7_scheme *sc, s7_pointer expr); void s7_pf_set_function(s7_pointer f, s7_pp_t rp); s7_pp_t s7_pf_function(s7_scheme *sc, s7_pointer func); void s7_gf_set_function(s7_pointer f, s7_pp_t gp); s7_pp_t s7_gf_function(s7_scheme *sc, s7_pointer func); void *s7_xf_new(s7_scheme *sc, s7_pointer e); void s7_xf_free(s7_scheme *sc); s7_int s7_xf_store(s7_scheme *sc, s7_pointer val); void s7_xf_store_at(s7_scheme *sc, s7_int index, s7_pointer val); void *s7_xf_detach(s7_scheme *sc); void s7_xf_attach(s7_scheme *sc, void *ur); s7_pointer *s7_xf_start(s7_scheme *sc); s7_pointer *s7_xf_top(s7_scheme *sc, void *ur); bool s7_xf_is_stepper(s7_scheme *sc, s7_pointer sym); bool s7_arg_to_gf(s7_scheme *sc, s7_pointer a1); bool s7_arg_to_pf(s7_scheme *sc, s7_pointer a1); bool s7_arg_to_if(s7_scheme *sc, s7_pointer a1); bool s7_arg_to_rf(s7_scheme *sc, s7_pointer a1); s7_int s7_slot_integer_value(s7_pointer slot); bool s7_is_stepper(s7_pointer p); s7_double s7_slot_real_value(s7_scheme *sc, s7_pointer slot, const char *caller); void s7_slot_set_real_value(s7_scheme *sc, s7_pointer slot, s7_double value); void s7_object_type_set_xf(int tag, s7_ip_t ip, s7_ip_t set_ip, s7_rp_t rp, s7_rp_t set_rp); void s7_object_type_set_direct(int tag, s7_pointer (*dref)(s7_scheme *sc, s7_pointer obj, s7_int index), s7_pointer (*dset)(s7_scheme *sc, s7_pointer obj, s7_int index, s7_pointer val)); /* end CLM stuff */ /* this is experimental */ s7_pointer s7_apply_1(s7_scheme *sc, s7_pointer args, s7_pointer (*f1)(s7_pointer a1)); s7_pointer s7_apply_2(s7_scheme *sc, s7_pointer args, s7_pointer (*f2)(s7_pointer a1, s7_pointer a2)); s7_pointer s7_apply_3(s7_scheme *sc, s7_pointer args, s7_pointer (*f3)(s7_pointer a1, s7_pointer a2, s7_pointer a3)); s7_pointer s7_apply_4(s7_scheme *sc, s7_pointer args, s7_pointer (*f4)(s7_pointer a1, s7_pointer a2, s7_pointer a3, s7_pointer a4)); s7_pointer s7_apply_5(s7_scheme *sc, s7_pointer args, s7_pointer (*f5)(s7_pointer a1, s7_pointer a2, s7_pointer a3, s7_pointer a4, s7_pointer a5)); s7_pointer s7_apply_6(s7_scheme *sc, s7_pointer args, s7_pointer (*f6)(s7_pointer a1, s7_pointer a2, s7_pointer a3, s7_pointer a4, s7_pointer a5, s7_pointer a6)); s7_pointer s7_apply_7(s7_scheme *sc, s7_pointer args, s7_pointer (*f7)(s7_pointer a1, s7_pointer a2, s7_pointer a3, s7_pointer a4, s7_pointer a5, s7_pointer a6, s7_pointer a7)); s7_pointer s7_apply_8(s7_scheme *sc, s7_pointer args, s7_pointer (*f8)(s7_pointer a1, s7_pointer a2, s7_pointer a3, s7_pointer a4, s7_pointer a5, s7_pointer a6, s7_pointer a7, s7_pointer a8)); s7_pointer s7_apply_9(s7_scheme *sc, s7_pointer args, s7_pointer (*f9)(s7_pointer a1, s7_pointer a2, s7_pointer a3, s7_pointer a4, s7_pointer a5, s7_pointer a6, s7_pointer a7, s7_pointer a8, s7_pointer a9)); s7_pointer s7_apply_n_1(s7_scheme *sc, s7_pointer args, s7_pointer (*f1)(s7_pointer a1)); s7_pointer s7_apply_n_2(s7_scheme *sc, s7_pointer args, s7_pointer (*f2)(s7_pointer a1, s7_pointer a2)); s7_pointer s7_apply_n_3(s7_scheme *sc, s7_pointer args, s7_pointer (*f3)(s7_pointer a1, s7_pointer a2, s7_pointer a3)); s7_pointer s7_apply_n_4(s7_scheme *sc, s7_pointer args, s7_pointer (*f4)(s7_pointer a1, s7_pointer a2, s7_pointer a3, s7_pointer a4)); s7_pointer s7_apply_n_5(s7_scheme *sc, s7_pointer args, s7_pointer (*f5)(s7_pointer a1, s7_pointer a2, s7_pointer a3, s7_pointer a4, s7_pointer a5)); s7_pointer s7_apply_n_6(s7_scheme *sc, s7_pointer args, s7_pointer (*f6)(s7_pointer a1, s7_pointer a2, s7_pointer a3, s7_pointer a4, s7_pointer a5, s7_pointer a6)); s7_pointer s7_apply_n_7(s7_scheme *sc, s7_pointer args, s7_pointer (*f7)(s7_pointer a1, s7_pointer a2, s7_pointer a3, s7_pointer a4, s7_pointer a5, s7_pointer a6, s7_pointer a7)); s7_pointer s7_apply_n_8(s7_scheme *sc, s7_pointer args, s7_pointer (*f8)(s7_pointer a1, s7_pointer a2, s7_pointer a3, s7_pointer a4, s7_pointer a5, s7_pointer a6, s7_pointer a7, s7_pointer a8)); s7_pointer s7_apply_n_9(s7_scheme *sc, s7_pointer args, s7_pointer (*f9)(s7_pointer a1, s7_pointer a2, s7_pointer a3, s7_pointer a4, s7_pointer a5, s7_pointer a6, s7_pointer a7, s7_pointer a8, s7_pointer a9)); #if WITH_GMP #include #include #include bool s7_is_bignum(s7_pointer obj); mpfr_t *s7_big_real(s7_pointer x); mpz_t *s7_big_integer(s7_pointer x); mpq_t *s7_big_ratio(s7_pointer x); mpc_t *s7_big_complex(s7_pointer x); s7_pointer s7_make_big_integer(s7_scheme *sc, mpz_t *val); s7_pointer s7_make_big_ratio(s7_scheme *sc, mpq_t *val); s7_pointer s7_make_big_real(s7_scheme *sc, mpfr_t *val); s7_pointer s7_make_big_complex(s7_scheme *sc, mpc_t *val); #endif #ifdef __cplusplus } #endif #endif #if (!DISABLE_DEPRECATED) /* cm uses this: */ #define s7_UNSPECIFIED(Sc) s7_unspecified(Sc) #define s7_NIL(Sc) s7_nil(Sc) #define s7_is_procedure_with_setter s7_is_dilambda #define s7_make_procedure_with_setter s7_dilambda #define s7_define_integer_function s7_define_safe_function #define s7_make_random_state s7_random_state #endif /* -------------------------------------------------------------------------------- * * s7 changes * * 6-Nov: removed :key and :optional. * 16-Oct: s7_make_random_state -> s7_random_state. * 16-Aug: remove s7_define_integer_function, s7_function_set_removes_temp, * add s7_define_typed_function, s7_make_signature. * 5-Aug: added s7_scheme* arg to s7_openlet and s7_outlet. * 3-Jul: s7_Double -> s7_double, s7_Int -> s7_int. Removed function_chooser_data. * 27-Jun: s7_rf_t, s7_rp_t etc. * 19-Jun: removed the ex_parser stuff, set_step_safe, s7_ex_fallback. * 5-May: s7_make_iterator and friends. * 16-Apr: added s7_fill, changed arg interpretation of s7_copy, s7_dynamic_wind. * 30-Mar: s7_eval_c_string_with_environment (repl experiment). * 19-Mar: repl.scm. * 28-Feb: s7_vector_print_length -> s7_print_length, set case also. * 25-Feb: s7_closure_* funcs to replace clumsy (deprecated) s7_procedure_source. * 29-Jan: changed args to s7_new_type_x (added s7_scheme arg, fill! takes s7_function). * 14-Jan-15: make-iterator, iterator? * -------- * 26-Dec: s7_arity replaces s7_procedure_arity. s7_define_integer_function. deprecate s7_procedure_name. * 5-Nov: s7_shadow_rootlet and s7_set_shadow_rootlet. * 30-Aug: s7_make_safe_function (for cload.scm). * 25-July: define and friends now return the value, not the symbol. * procedure_with_setter -> dilambda. * environment -> let. All the replaced names are deprecated. * 30-June: s7_method. * 16-June: remove unoptimize and s7_unoptimize. * 14-May: s7_define_safe_function_star. Removed s7_catch_all. * 22-Apr: remove s7_apply_n_10, s7_is_valid_pointer, s7_keyword_eq_p. * 5-Mar-14: s7_heap_size, s7_gc_freed. * -------- * 8-Nov: s7_symbol_documentation, s7_define_constant_with_documentation. * 17-Oct: bignum-precision (procedure-with-setter) is now an integer variable named *bignum-precision*. * 28-Aug: s7_int|float_vector_elements (homogenous vectors), libc.scm. * 16-Aug: ~W directive in format, make-shared-vector. * 23-Jul: s7_autoload_set_names, libm.scm, libdl.scm, libgdbm.scm, r7rs.scm, s7libtest.scm. * 21-Jul: s7_is_valid (replaces deprecated s7_is_valid_pointer). * 24-Jun: some bool-related changes for Windows Visual C++, including change to s7_begin_hook. * 3-June: s7_autoload. * 28-May: export s7_is_provided. Added s7_scheme* arg to s7_procedure_environment. * 21-May: equality predicate optional arg in make-hash-table. * 14-May: glistener.c, glistener.h, s7_symbol_table_find_name (for glistener). * 2-May: r7rs changes: flush-output-port, vector-append, read|write-string, boolean=?, symbol=?. * start/end args for string-fill!, vector-fill!, string->list, vector->list, and copy. * exit, emergency-exit. * 7-Apr: removed s7_scheme* arg from s7_slot_value, added s7_is_local_variable. * 25-Mar: char-position, string-position, environment-ref, environment-set! added to the scheme side. * 9-Jan-13: s7_cos, s7_sin, other optimization changes. * -------- * 24-Dec: s7_set_object_array_info and other such changes. * 20-Nov: removed s7_set_error_exiter and s7_error_and_exit which I think have never been used. * 22-Oct: changed args to s7_function_class and s7_function_set_class. * 22-Aug: symbol->dynamic-value. * 10-Aug: exported s7_outer_environment. * 6-Aug: removed WITH_OPTIMIZATION. * 25-July: environment (in scheme). s7_vector_ref_n and s7_vector_set_n. s7_copy. * added s7_scheme arg to s7_number_to_real|integer. * 16-July: s7_function_returns_temp (an experiment). * 2-July: s7_object_set_* functions. * 11-June: throw. * 4-June. s7_object_environment. * 31-May: added s7_scheme argument to all the optimizer chooser functions. * 24-May: open-environment? * 17-May: arity, aritable? * removed trace and untrace. * 14-May: s7_list. s7_procedure_set_setter. Removed s7_procedure_getter. * procedure-setter is settable: removed most of procedure-with-setter. * make-type replaced by open-environment. * 11-May: s7 2.0: hook implementation changed completely. * s7_environment_ref|set. * 4-May: *error-info* replaced by error-environment, and stacktrace has changed. * 22-Apr: #_ = startup (built-in) value of name * 17-Apr: with-baffle. * 14-Apr: WITH_SYSTEM_EXTRAS (default 0) has additional OS and IO functions: * directory? file-exists? delete-file getenv directory->list system * 26-Mar: "@" as exponent, WITH_AT_SIGN_AS_EXPONENT switch (default is 1). * 18-Mar: removed *trace-hook*. * 6-Feb: random-state?, hash-table-iterator?, and morally-equal? * 18-Jan: s7_environment_to_list and environment->list return just the local environment's bindings. * outer-environment returns the environment enclosing its argument (an environment). * environments are now applicable objects. * added the object system example to s7.html. * 12-Jan: added reverse argument to s7_new_type_x. This is needed because an object might implement * the apply and set methods, but they might refer to different things. * 6-Jan-12: added (scheme side) logbit?. * -------- * 21-Dec: s7_eval, s7_make_slot, s7_slot_set_value. * changed s7_symbol_slot to s7_slot, and s7_symbol_slot_value to s7_slot_value. * 26-Oct: s7_procedure_name. * 6-Oct: changed s7_make_closure args: split the code argument in two (args and body). * s7_make_closure(... code ...) is now s7_make_closure(... car(code), cdr(code) ...) * s7_is_environment. * 19-Aug: s7_function_chooser_data. * 11-Aug: s7_symbol_accessor functions. s7_cxxxxr. * 9-Aug: s7_function_chooser, s7_function_choice, s7_function_choice_set_direct. * 20-Jul: s7_function_class, s7_function_set_class, and s7_function_set_chooser. * 14-Jul: removed thread and profiling support. * 5-June: s7_define_safe_function and s7_unoptimize exported; added unoptimize function in scheme. * 30-May: environment->list and s7_environment_to_list since environments are no longer alists internally. * 26-May: added s7_scheme argument to s7_procedure_setter and getter (old names had "with_setter_"). * 28-Apr: s7_help. * 5-Apr: pair-line-number. * 14-Mar: s7_make_random_state, optional state argument to s7_random, random-state->list, s7_random_state_to_list. * 10-Feb: s7_vector_print_length, s7_set_vector_print_length. * 7-Feb: s7_begin_hook, s7_set_begin_hook. * 25-Jan: s7_is_thread, s7_thread, s7_make_thread, s7_thread_s7, s7_thread_data. * s7_is_lock, s7_make_lock, s7_lock. * changed s7_thread_variable_value to s7_thread_variable. * 23-Jan: removed (scheme-level) quit. * 17-Jan-11: make-hash-table-iterator. * map and for-each accept any applicable object as the first argument. * format's ~{...~} directive can handle any applicable object. * -------- * 17-Dec: removed unquote-splicing; replaced by (unquote (apply values ...)). * 12-Dec: environment? * 7-Dec: member and assoc have an optional third arg, the comparison function. * 1-Dec: *gc-stats* in Scheme, s7_gc_stats in C. * gmp and gtk-repl examples in s7.html. * 21-Nov: Load C module example in s7.html. * 12-Nov: *trace-hook*, *load-hook*, *error-hook*, and *unbound-variable-hook* are now s7 hooks. * 9-Nov: hooks: C side: s7_is_hook, s7_make_hook, s7_hook_apply, s7_hook_functions, s7_hook_arity, s7_hook_documentation. * s7 side: hook?, make-hook, hook, hook-apply, hook-functions, hook-arity, hook-documentation. * 8-Nov: Closure defined in C example in s7.html. * 23-Oct: s7_call_with_location for better error reporting. * 19-Oct: *stdin*, *stdout*, *stderr* for default IO ports (rather than nil which is ambiguous). * 14-Oct: removed special variable support. * 30-Sep: setters for current-input-port, current-output-port, and current-error-port. * 30-Aug: :allow-other-keys in define*. * 10-Aug: added boolean argument use_write to s7_object_to_string (true=write, false=display). * 30-July: special macro for access to dynamic binding. * s7_symbol_special_value for C-side access to dynamic bindings. * s7_is_macro. * port-closed? returns #t if its argument (a port) is closed. * 22-July: s7_make_character takes unsigned int, rather than int. * added symbol function for funny symbol names. * 12-July: initial-environment. * 7-July: removed force and delay: use slib. * 3-July: new backquote implementation. * 28-June: syntactic keywords (e.g. lambda) are applicable. * 7-June: changed key arg in s7_hash_table_ref|set to be s7_pointer, not const char*. * hash-tables can now handle any s7 object as the key. * map and for-each now pass a hash-table entry to the function, rather than an internal alist. * reverse of a hash-table reverses the keys and values (i.e. old value becomes new key, etc). * 2-June: removed procedure-with-setter-setter-arity and folded that info into procedure-arity (use cdddr). * 22-May: multidimensional vectors are no longer optional. * 9-May: s7_read_char and s7_peek_char have to return an int, not a char (=-1, but 255 is a legit char). * s7_write_char and s7_open_output_function have similar changes. * 3-May: *#readers* to customize #... reading. Also nan? and infinite?. * multidimensional vector constants using #nD(...): (#2D((1 2 3) (4 5 6)) 0 0) -> 1. * 13-Apr: removed hash-table|vector|string-for-each -- these are handled by for-each. * also removed vector-map -- map is generic, but always returns a list. * 12-Apr: removed immutable constant checks -- see s7.html. * 7-Apr: *unbound-variable-hook*. * augment-environment and s7_augment_environment. * 29-Mar: symbol-access, s7_symbol_access, s7_symbol_set_access. * C example of notification in s7.html. * 25-Mar: make-type. s7_is_equal now includes an s7_scheme pointer as its first argument. * 24-Mar: s7_is_defined. * 19-Mar: removed encapsulation mechanism and s7_define_set_function. * 18-Mar: added macro?. * 27-Feb: removed r4rs-style macro syntax. * 17-Feb: s7_number_to_integer. * 20-Jan-10: removed the stack function. * -------- * 16-Dec: hash-table-for-each. * 1-Dec: mpc versions before 0.8.0 are no longer supported. * 24-Nov: define-macro* and defmacro*. * force and delay included only if WITH_FORCE set, promise? removed. * 17-Nov: s7_is_boolean no longer takes the s7_scheme argument. * 7-Nov: s7_vector_dimensions, s7_vector_offsets, example of use. * 3-Nov: s7_vector_rank. * 30-Oct: *trace-hook*. * 12-Oct: s7_port_filename. * 5-Oct: s7_c_pointer and friends. * 14-Sep: s7_values, s7_make_continuation, and a better interrupt example. * vector-for-each, vector-map, string-for-each. * 7-Sep: s7_open_input_function. with-environment. receive. * 3-Sep: s7.html, s7-slib-init.scm. * s7_stacktrace in s7.h. * 27-Aug: vector and hash-table sizes are now s7_ints, rather than ints. * 20-Aug: s7_remove_from_heap. * 17-Aug: *error-info*. * 14-Aug: define-expansion. * 7-Aug: s7_define_function_with_setter. * s7_quit and example of signal handling. * 6-Aug: encapsulation. s7_define_set_function. s7_new_type_x. * generic function: copy, and length is generic. * 1-Aug: lower-case versions of s7_T and friends. * s7_define_macro. macroexpand. * strings are set-applicable (like vectors). * 31-Jul: *error-hook*. * 30-Jul: changed backtrace handling: removed backtrace stuff, added stacktrace. * removed gc-verbose and load-verbose replaced by *load-hook*. * 23-Jul: __func__. * 20-Jul: trace and untrace. * 14-Jul: replaced s7_make_closure_star with s7_define_function_star. * 29-Jun: s7_format declaration. * 12-May: s7_is_constant. * 20-Apr: changed rationalize to be both r5rs-acceptable and fast. * 6-Apr: added s7_make_permanent_string. * 14-Mar: removed s7_local_gc_protect and s7_local_gc_unprotect. * 4-Mar: multidimensional and applicable vectors. * 1-Mar: s7_random added to s7.h. * 29-Jan: s7_is_bignum and friends. * 26-Jan: added s7_scheme arg to s7_vector_fill. * 16-Jan: s7_is_ulong_long and friends for C pointers in 64-bit situations. * 9-Jan-09 multiprecision arithmetic (gmp, mpfr, mpc) on the WITH_GMP switch * -------- * 29-Dec: "+" specialization example, s7_apply_function. * 3-Dec: s7_open_output_function. * 30-Nov: s7_wrong_number_of_args_error. * 24-Nov: changed s7_make_counted_string to s7_make_string_with_length. * also added built-in format and define* * 10-Nov: s7_define_constant, * built-in (scheme-side) pi, most-positive-fixnum, most-negative-fixnum * 7-Nov: removed s7_is_immutable and friends, s7_reverse_in_place. * removed the s7_pointer arg to s7_gc_on. * added s7_UNSPECIFIED * 25-Oct: added name arg to s7_make_procedure_with_setter, * and s7_scheme arg to new_type print func. * 1-Oct-08 version 1.0 */ snd-16.1/sndlib2xen.c0000644000076400007640000014435012603035272012556 0ustar bilbil/* Tie sndlib into Xen */ #include "mus-config.h" #if USE_SND #include "snd.h" #else #if HAVE_RUBY #define PROC_FALSE "false" #define PROC_TRUE "true" #endif #if HAVE_SCHEME || HAVE_FORTH #define PROC_FALSE "#f" #define PROC_TRUE "#t" #endif #endif #include #include #include #include #include #include #include #ifdef _MSC_VER #pragma warning(disable: 4244) #endif #include "_sndlib.h" #include "sndlib-strings.h" #include "vct.h" #include "clm.h" #include "sndlib2xen.h" #include "clm2xen.h" #ifndef S_set #if HAVE_RUBY #define S_set "set_" #endif #if HAVE_SCHEME #define S_set "set! " #endif #if HAVE_FORTH #define S_set "set-" #endif #endif /* originally I tried to simplify C GC by using global static strings that were * freed whenever the associated function was called again, on the assumption * that the preceding value was now unused. In a multithread context, that * assumption is false, so I didn't use code like this: * * static char *tmpstr = NULL; * * static char *local_mus_expand_filename(char *name) * { * if (tmpstr) {free(tmpstr); tmpstr = NULL;} * tmpstr = mus_expand_filename(name); * return(tmpstr); * } */ static Xen g_mus_sound_loop_info(Xen gfilename) { #define H_mus_sound_loop_info "(" S_mus_sound_loop_info " filename): synth loop info for sound as a list: (start1 \ end1 start2 end2 base-note base-detune mode1 mode2)" int *res; Xen sres = Xen_empty_list; char *str = NULL; Xen_check_type(Xen_is_string(gfilename), gfilename, 1, S_mus_sound_loop_info, "a string"); res = mus_sound_loop_info(str = mus_expand_filename(Xen_string_to_C_string(gfilename))); if (str) free(str); if (res) { sres = Xen_list_8(C_int_to_Xen_integer(res[0]), C_int_to_Xen_integer(res[1]), C_int_to_Xen_integer(res[2]), C_int_to_Xen_integer(res[3]), C_int_to_Xen_integer(res[4]), C_int_to_Xen_integer(res[5]), C_int_to_Xen_integer(res[6]), C_int_to_Xen_integer(res[7])); free(res); } return(sres); } static Xen g_mus_sound_mark_info(Xen gfilename) { #define H_mus_sound_mark_info "(" S_mus_sound_mark_info " filename): aifc header mark info as a list of lists: ((id pos)...)" int *mark_ids, *mark_positions; int marks = 0; Xen sres = Xen_empty_list; char *str = NULL; Xen_check_type(Xen_is_string(gfilename), gfilename, 1, S_mus_sound_mark_info, "a string"); marks = mus_sound_mark_info(str = mus_expand_filename(Xen_string_to_C_string(gfilename)), &mark_ids, &mark_positions); if (str) free(str); if (marks > 0) { int i; for (i = 0; i < marks; i++) sres = Xen_cons(Xen_list_2(C_int_to_Xen_integer(mark_ids[i]), C_int_to_Xen_integer(mark_positions[i])), sres); } return(sres); } static Xen gmus_sound(const char *caller, int (*func)(const char *file), Xen gfilename) { char *str = NULL; Xen result; Xen_check_type(Xen_is_string(gfilename), gfilename, 1, caller, "a string"); str = mus_expand_filename(Xen_string_to_C_string(gfilename)); result = C_int_to_Xen_integer((*func)(str)); if (str) free(str); return(result); } static Xen gmus_sound_set(const char *caller, int (*func)(const char *file, int newval), Xen gfilename, Xen val) { char *str = NULL; Xen result; Xen_check_type(Xen_is_string(gfilename), gfilename, 1, caller, "a string"); Xen_check_type(Xen_is_integer(val), val, 2, caller, "an integer"); str = mus_expand_filename(Xen_string_to_C_string(gfilename)); result = C_int_to_Xen_integer((*func)(str, Xen_integer_to_C_int(val))); if (str) free(str); return(result); } static Xen glmus_sound(const char *caller, mus_long_t (*func)(const char *file), Xen gfilename) { char *str = NULL; Xen result; Xen_check_type(Xen_is_string(gfilename), gfilename, 1, caller, "a string"); str = mus_expand_filename(Xen_string_to_C_string(gfilename)); result = C_llong_to_Xen_llong((*func)(str)); if (str) free(str); return(result); } static Xen glmus_sound_set(const char *caller, int (*func)(const char *file, mus_long_t newval), Xen gfilename, Xen val) { char *str = NULL; Xen result; Xen_check_type(Xen_is_string(gfilename), gfilename, 1, caller, "a string"); Xen_check_type(Xen_is_number(val), val, 2, caller, "a number"); str = mus_expand_filename(Xen_string_to_C_string(gfilename)); result = C_llong_to_Xen_llong((*func)(str, Xen_llong_to_C_llong(val))); if (str) free(str); return(result); } static Xen g_mus_sound_samples(Xen filename) { #define H_mus_sound_samples "(" S_mus_sound_samples " filename): samples (framples * channels) in sound file" return(glmus_sound(S_mus_sound_samples, mus_sound_samples, filename)); } static Xen g_mus_sound_set_samples(Xen filename, Xen val) { return(glmus_sound_set(S_set S_mus_sound_samples, mus_sound_set_samples, filename, val)); } Xen g_mus_sound_framples(Xen filename) { #define H_mus_sound_framples "(" S_mus_sound_framples " filename): framples (samples / channel) in sound file" return(glmus_sound(S_mus_sound_framples, mus_sound_framples, filename)); } static Xen g_mus_sound_datum_size(Xen filename) { #define H_mus_sound_datum_size "(" S_mus_sound_datum_size " filename): bytes per sample used by the data in sound file (sample type dependent)" return(gmus_sound(S_mus_sound_datum_size, mus_sound_datum_size, filename)); } static Xen g_mus_sound_data_location(Xen filename) { #define H_mus_sound_data_location "(" S_mus_sound_data_location " filename): location (in bytes) of first sample of sound data" return(glmus_sound(S_mus_sound_data_location, mus_sound_data_location, filename)); } static Xen g_mus_sound_set_data_location(Xen filename, Xen val) { return(glmus_sound_set(S_set S_mus_sound_data_location, mus_sound_set_data_location, filename, val)); } Xen g_mus_sound_chans(Xen filename) { #define H_mus_sound_chans "(" S_mus_sound_chans " filename): channels of data in sound file" return(gmus_sound(S_mus_sound_chans, mus_sound_chans, filename)); } static Xen g_mus_sound_set_chans(Xen filename, Xen val) { return(gmus_sound_set(S_set S_mus_sound_chans, mus_sound_set_chans, filename, val)); } Xen g_mus_sound_srate(Xen filename) { #define H_mus_sound_srate "(" S_mus_sound_srate " filename): sampling rate of sound file" return(gmus_sound(S_mus_sound_srate, mus_sound_srate, filename)); } static Xen g_mus_sound_set_srate(Xen filename, Xen val) { return(gmus_sound_set(S_set S_mus_sound_srate, mus_sound_set_srate, filename, val)); } static Xen g_mus_sound_header_type(Xen filename) { #define H_mus_sound_header_type "(" S_mus_sound_header_type " filename): header type (e.g. " S_mus_aifc ") of sound file" char *str = NULL; Xen result; Xen_check_type(Xen_is_string(filename), filename, 1, S_mus_sound_header_type, "a string"); str = mus_expand_filename(Xen_string_to_C_string(filename)); result = C_int_to_Xen_integer((int)mus_sound_header_type(str)); if (str) free(str); return(result); } static Xen g_mus_sound_set_header_type(Xen filename, Xen val) { char *str = NULL; Xen result; Xen_check_type(Xen_is_string(filename), filename, 1, S_set S_mus_sound_header_type, "a string"); Xen_check_type(Xen_is_integer(val), val, 2, S_set S_mus_sound_header_type, "an integer"); str = mus_expand_filename(Xen_string_to_C_string(filename)); result = C_int_to_Xen_integer((int)mus_sound_set_header_type(str, (mus_header_t)Xen_integer_to_C_int(val))); if (str) free(str); return(result); } static Xen g_mus_sound_sample_type(Xen filename) { #define H_mus_sound_sample_type "(" S_mus_sound_sample_type " filename): sample type (e.g. " S_mus_bshort ") of data in sound file" char *str = NULL; Xen result; Xen_check_type(Xen_is_string(filename), filename, 1, S_mus_sound_sample_type, "a string"); str = mus_expand_filename(Xen_string_to_C_string(filename)); result = C_int_to_Xen_integer((int)mus_sound_sample_type(str)); if (str) free(str); return(result); } static Xen g_mus_sound_set_sample_type(Xen filename, Xen val) { char *str = NULL; Xen result; Xen_check_type(Xen_is_string(filename), filename, 1, S_set S_mus_sound_sample_type, "a string"); Xen_check_type(Xen_is_integer(val), val, 2, S_set S_mus_sound_sample_type, "an integer"); str = mus_expand_filename(Xen_string_to_C_string(filename)); result = C_int_to_Xen_integer((int)mus_sound_set_sample_type(str, (mus_sample_t)Xen_integer_to_C_int(val))); if (str) free(str); return(result); } static Xen g_mus_sound_length(Xen filename) { #define H_mus_sound_length "(" S_mus_sound_length " filename): sound file length in bytes" return(glmus_sound(S_mus_sound_length, mus_sound_length, filename)); } static Xen g_mus_sound_type_specifier(Xen filename) { #define H_mus_sound_type_specifier "(" S_mus_sound_type_specifier " filename): original sound file header type identifier (e.g. 0x2e736e64)" return(gmus_sound(S_mus_sound_type_specifier, mus_sound_type_specifier, filename)); } static Xen g_mus_sound_forget(Xen filename) { #define H_mus_sound_forget "(" S_mus_sound_forget " filename): remove 'filename' from sound cache. If you create, then later \ delete a sound file, " S_mus_sound_forget " can be used to clear it from sndlib's cache of sound files" return(gmus_sound(S_mus_sound_forget, mus_sound_forget, filename)); } static Xen g_mus_sound_prune(void) { #define H_mus_sound_prune "(" S_mus_sound_prune "): remove all defunct entries from sndlib's sound file cache." return(C_int_to_Xen_integer(mus_sound_prune())); } static Xen g_mus_sound_comment(Xen gfilename) { #define H_mus_sound_comment "(" S_mus_sound_comment " filename): comment (a string) found in sound file's header" char *res = NULL, *str = NULL; Xen newstr; Xen_check_type(Xen_is_string(gfilename), gfilename, 1, S_mus_sound_comment, "a string"); res = mus_sound_comment(str = mus_expand_filename(Xen_string_to_C_string(gfilename))); if (str) free(str); newstr = C_string_to_Xen_string(res); if (res) free(res); return(newstr); } static Xen g_mus_sound_write_date(Xen filename) { char *str = NULL; Xen result; #define H_mus_sound_write_date "(" S_mus_sound_write_date " filename): write date of sound file" Xen_check_type(Xen_is_string(filename), filename, 1, S_mus_sound_write_date, "a string"); str = mus_expand_filename(Xen_string_to_C_string(filename)); result = C_ulong_to_Xen_ulong((unsigned long)mus_sound_write_date(str)); /* actually time_t */ if (str) free(str); return(result); } static Xen g_mus_header_writable(Xen head, Xen data) { #define H_mus_header_writable "(" S_mus_header_writable " header-type sample-type) returns " PROC_TRUE " if the header can handle the sample type" Xen_check_type(Xen_is_integer(head), head, 1, S_mus_header_writable, "a header type"); Xen_check_type(Xen_is_integer(data), data, 2, S_mus_header_writable, "a sample type"); return(C_bool_to_Xen_boolean(mus_header_writable((mus_header_t)Xen_integer_to_C_int(head), (mus_sample_t)Xen_integer_to_C_int(data)))); } static Xen g_mus_header_raw_defaults(void) { #define H_mus_header_raw_defaults "(" S_mus_header_raw_defaults "): returns list '(srate chans sample-type) of current raw sound default attributes" int srate, chans; mus_sample_t sample_type; mus_header_raw_defaults(&srate, &chans, &sample_type); return(Xen_list_3(C_int_to_Xen_integer(srate), C_int_to_Xen_integer(chans), C_int_to_Xen_integer((int)sample_type))); } static Xen g_mus_header_set_raw_defaults(Xen lst) { Xen_check_type((Xen_is_list(lst)) && (Xen_list_length(lst) == 3), lst, 1, S_mus_header_raw_defaults, "a list: '(srate chans sample-type)"); Xen_check_type(Xen_is_integer(Xen_car(lst)), Xen_car(lst), 1, S_mus_header_raw_defaults, "an integer = srate"); Xen_check_type(Xen_is_integer(Xen_cadr(lst)), Xen_cadr(lst), 2, S_mus_header_raw_defaults, "an integer = chans"); Xen_check_type(Xen_is_integer(Xen_caddr(lst)), Xen_caddr(lst), 3, S_mus_header_raw_defaults, "an integer = sample-type"); mus_header_set_raw_defaults(Xen_integer_to_C_int(Xen_car(lst)), Xen_integer_to_C_int(Xen_cadr(lst)), (mus_sample_t)Xen_integer_to_C_int(Xen_caddr(lst))); return(lst); } static Xen g_mus_header_type_name(Xen type) { #define H_mus_header_type_name "(" S_mus_header_type_name " type): header type (e.g. " S_mus_aiff ") as a string" Xen_check_type(Xen_is_integer(type), type, 1, S_mus_header_type_name, "an integer (header-type id)"); return(C_string_to_Xen_string(mus_header_type_name((mus_header_t)Xen_integer_to_C_int(type)))); } static Xen g_mus_header_type_to_string(Xen type) { #define H_mus_header_type_to_string "(" S_mus_header_type_to_string " type): header type (e.g. " S_mus_aiff ") as a string" Xen_check_type(Xen_is_integer(type), type, 1, S_mus_header_type_to_string, "an integer (header-type id)"); return(C_string_to_Xen_string(mus_header_type_to_string((mus_header_t)Xen_integer_to_C_int(type)))); } static Xen g_mus_sample_type_name(Xen samp_type) { #define H_mus_sample_type_name "(" S_mus_sample_type_name " samp_type): sample type (e.g. " S_mus_bshort ") as a string" Xen_check_type(Xen_is_integer(samp_type), samp_type, 1, S_mus_sample_type_name, "an integer (sample-type id)"); return(C_string_to_Xen_string(mus_sample_type_name((mus_sample_t)Xen_integer_to_C_int(samp_type)))); } static Xen g_mus_sample_type_to_string(Xen samp_type) { #define H_mus_sample_type_to_string "(" S_mus_sample_type_to_string " samp_type): sample type (e.g. " S_mus_bshort ") as a string" Xen_check_type(Xen_is_integer(samp_type), samp_type, 1, S_mus_sample_type_to_string, "an integer (sample-type id)"); return(C_string_to_Xen_string(mus_sample_type_to_string((mus_sample_t)Xen_integer_to_C_int(samp_type)))); } static Xen g_mus_bytes_per_sample(Xen samp_type) { #define H_mus_bytes_per_sample "(" S_mus_bytes_per_sample " sample-type): number of bytes per sample in \ sample-type (e.g. " S_mus_bshort " = 2)" Xen_check_type(Xen_is_integer(samp_type), samp_type, 1, S_mus_bytes_per_sample, "an integer (sample-type id)"); return(C_int_to_Xen_integer(mus_bytes_per_sample((mus_sample_t)Xen_integer_to_C_int(samp_type)))); } static Xen g_mus_sound_duration(Xen gfilename) { #define H_mus_sound_duration "(" S_mus_sound_duration " filename): duration (in seconds) of sound file" float res; char *str = NULL; Xen_check_type(Xen_is_string(gfilename), gfilename, 1, S_mus_sound_duration, "a string"); res = mus_sound_duration(str = mus_expand_filename(Xen_string_to_C_string(gfilename))); if (str) free(str); return(C_double_to_Xen_real(res)); } static Xen g_mus_oss_set_buffers(Xen num, Xen size) { #define H_mus_oss_set_buffers "(" S_mus_oss_set_buffers " num size): set Linux OSS 'fragment' number and size. \ If Snd's controls seem sluggish, try (" S_mus_oss_set_buffers " 4 12) or even (" S_mus_oss_set_buffers " 2 12). \ This reduces the on-card buffering, but may introduce clicks." #if (HAVE_OSS || HAVE_ALSA) Xen_check_type(Xen_is_integer(num), num, 1, S_mus_oss_set_buffers, "an integer"); Xen_check_type(Xen_is_integer(size), size, 2, S_mus_oss_set_buffers, "an integer"); mus_oss_set_buffers(Xen_integer_to_C_int(num), Xen_integer_to_C_int(size)); #endif return(Xen_false); } static Xen g_mus_alsa_buffers(void) { #define H_mus_alsa_buffers "(" S_mus_alsa_buffers "): current number of ALSA periods." #if HAVE_ALSA return(C_int_to_Xen_integer(mus_alsa_buffers())); #endif return(Xen_false); } static Xen g_mus_alsa_set_buffers(Xen val) { Xen_check_type(Xen_is_integer(val), val, 1, S_set S_mus_alsa_buffers, "an integer"); #if HAVE_ALSA return(C_int_to_Xen_integer(mus_alsa_set_buffers(Xen_integer_to_C_int(val)))); #endif return(Xen_false); } static Xen g_mus_alsa_buffer_size(void) { #define H_mus_alsa_buffer_size "(" S_mus_alsa_buffer_size "): current size of ALSA buffers." #if HAVE_ALSA return(C_int_to_Xen_integer(mus_alsa_buffer_size())); #endif return(Xen_false); } static Xen g_mus_alsa_set_buffer_size(Xen val) { Xen_check_type(Xen_is_integer(val), val, 1, S_set S_mus_alsa_buffer_size, "an integer"); #if HAVE_ALSA return(C_int_to_Xen_integer(mus_alsa_set_buffer_size(Xen_integer_to_C_int(val)))); #endif return(Xen_false); } static Xen g_mus_alsa_device(void) { #define H_mus_alsa_device "(" S_mus_alsa_device "): current ALSA device." #if HAVE_ALSA return(C_string_to_Xen_string(mus_alsa_device())); #endif return(Xen_false); } static Xen g_mus_alsa_set_device(Xen val) { Xen_check_type(Xen_is_string(val), val, 1, S_set S_mus_alsa_device, "a string (ALSA device name)"); #if HAVE_ALSA return(C_string_to_Xen_string(mus_alsa_set_device(Xen_string_to_C_string(val)))); #endif return(Xen_false); } static Xen g_mus_alsa_playback_device(void) { #define H_mus_alsa_playback_device "(" S_mus_alsa_playback_device "): current ALSA playback device." #if HAVE_ALSA return(C_string_to_Xen_string(mus_alsa_playback_device())); #endif return(Xen_false); } static Xen g_mus_alsa_set_playback_device(Xen val) { Xen_check_type(Xen_is_string(val), val, 1, S_set S_mus_alsa_playback_device, "a string (ALSA device name)"); #if HAVE_ALSA return(C_string_to_Xen_string(mus_alsa_set_playback_device(Xen_string_to_C_string(val)))); #endif return(Xen_false); } static Xen g_mus_alsa_capture_device(void) { #define H_mus_alsa_capture_device "(" S_mus_alsa_capture_device "): current ALSA capture device." #if HAVE_ALSA return(C_string_to_Xen_string(mus_alsa_capture_device())); #endif return(Xen_false); } static Xen g_mus_alsa_set_capture_device(Xen val) { Xen_check_type(Xen_is_string(val), val, 1, S_set S_mus_alsa_capture_device, "a string (ALSA device name)"); #if HAVE_ALSA return(C_string_to_Xen_string(mus_alsa_set_capture_device(Xen_string_to_C_string(val)))); #endif return(Xen_false); } static Xen g_mus_alsa_squelch_warning(void) { #define H_mus_alsa_squelch_warning "(" S_mus_alsa_squelch_warning "): whether to squelch ALSA srate mismatch warnings." #if HAVE_ALSA return(C_bool_to_Xen_boolean(mus_alsa_squelch_warning())); #endif return(Xen_false); } static Xen g_mus_alsa_set_squelch_warning(Xen val) { Xen_check_type(Xen_is_boolean(val), val, 1, S_set S_mus_alsa_squelch_warning, "a boolean"); #if HAVE_ALSA return(C_bool_to_Xen_boolean(mus_alsa_set_squelch_warning(Xen_boolean_to_C_bool(val)))); #endif return(Xen_false); } static Xen g_mus_sound_maxamp_exists(Xen file) { #define H_mus_sound_maxamp_exists "(" S_mus_sound_maxamp_exists " filename): " PROC_TRUE " if sound's maxamp data is available \ in the sound cache; if it isn't, a call on " S_mus_sound_maxamp " has to open and read the data to get the maxamp." bool val; char *str = NULL; Xen_check_type(Xen_is_string(file), file, 1, S_mus_sound_maxamp_exists, "a string"); val = mus_sound_maxamp_exists(str = mus_expand_filename(Xen_string_to_C_string(file))); if (str) free(str); return(C_bool_to_Xen_boolean(val)); } Xen g_mus_sound_maxamp(Xen file) { #define H_mus_sound_maxamp "(" S_mus_sound_maxamp " filename): maxamps in sound (a list of paired amps (floats) and locations (samples))" int chans; char *filename; Xen res = Xen_empty_list; Xen_check_type(Xen_is_string(file), file, 1, S_mus_sound_maxamp, "a string"); filename = mus_expand_filename(Xen_string_to_C_string(file)); chans = mus_sound_chans(filename); if (chans > 0) { mus_long_t rtn; mus_float_t *vals; mus_long_t *times; vals = (mus_float_t *)calloc(chans, sizeof(mus_float_t)); times = (mus_long_t *)calloc(chans, sizeof(mus_long_t)); rtn = mus_sound_maxamps(filename, chans, vals, times); if (rtn != MUS_ERROR) { int i; for (i = chans - 1; i >= 0; i--) res = Xen_cons(C_llong_to_Xen_llong(times[i]), Xen_cons(C_double_to_Xen_real(vals[i]), res)); } free(vals); free(times); if (filename) free(filename); } else { if (filename) free(filename); Xen_error(BAD_HEADER, Xen_list_1(C_string_to_Xen_string(S_mus_sound_maxamp ": chans <= 0"))); } return(res); } static Xen g_mus_sound_set_maxamp(Xen file, Xen vals) { int chans; char *filename; Xen_check_type(Xen_is_string(file), file, 1, S_set S_mus_sound_maxamp, "a string"); Xen_check_type(Xen_is_list(vals), vals, 2, S_set S_mus_sound_maxamp, "a list"); filename = mus_expand_filename(Xen_string_to_C_string(file)); chans = mus_sound_chans(filename); /* presumably any actual error here will be trapped via mus-error (raised in mus_header_read via read_sound_file_header), * so chans <= 0 is actually in the header? */ if (chans > 0) { Xen lst; int i, j, len; mus_float_t *mvals; mus_long_t *times; len = Xen_list_length(vals); if (len < (chans * 2)) Xen_wrong_type_arg_error(S_set S_mus_sound_maxamp, 2, vals, "max amp list length must = 2 * chans"); if (len > chans * 2) len = chans * 2; mvals = (mus_float_t *)calloc(chans, sizeof(mus_float_t)); times = (mus_long_t *)calloc(chans, sizeof(mus_long_t)); for (i = 0, j = 0, lst = Xen_copy_arg(vals); i < len; i += 2, j++, lst = Xen_cddr(lst)) { times[j] = Xen_llong_to_C_llong(Xen_car(lst)); mvals[j] = Xen_real_to_C_double(Xen_cadr(lst)); } fprintf(stderr, "set in g_mus_sound_set_maxamp\n"); mus_sound_set_maxamps(filename, chans, mvals, times); free(mvals); free(times); if (filename) free(filename); } else { if (filename) free(filename); Xen_error(BAD_HEADER, Xen_list_1(C_string_to_Xen_string(S_set S_mus_sound_maxamp ": chans <= 0"))); } return(vals); } #define S_mus_sound_preload "mus-sound-preload" static Xen g_mus_sound_preload(Xen file) { #define H_mus_sound_preload "(" S_mus_sound_preload " filename): save filename's data in memory (faster opens and so on)." char *str; Xen_check_type(Xen_is_string(file), file, 1, S_mus_sound_preload, "a string"); str = mus_expand_filename(Xen_string_to_C_string(file)); if (str) { int ifd; ifd = mus_sound_open_input(str); if (ifd != MUS_ERROR) { int i, chans; mus_float_t **bufs; mus_long_t framples; chans = mus_sound_chans(str); framples = mus_sound_framples(str) + 8; /* + 8 for readers than wander off the end */ bufs = (mus_float_t **)malloc(chans * sizeof(mus_float_t *)); for (i = 0; i < chans; i++) bufs[i] = (mus_float_t *)malloc(framples * sizeof(mus_float_t)); mus_file_seek_frample(ifd, 0); mus_file_read_file(ifd, 0, chans, framples, bufs); mus_sound_set_saved_data(str, bufs); mus_sound_close_input(ifd); } free(str); } return(file); } /* global default clipping values */ static Xen g_mus_clipping(void) { #define H_mus_clipping "(" S_mus_clipping "): whether sound data written to a file should be clipped" return(C_bool_to_Xen_boolean(mus_clipping())); } static Xen g_mus_set_clipping(Xen clipped) { Xen_check_type(Xen_is_boolean(clipped), clipped, 1, S_set S_mus_clipping, "a boolean"); return(C_bool_to_Xen_boolean(mus_set_clipping(Xen_boolean_to_C_bool(clipped)))); } /* file local clipping values */ static Xen g_mus_file_clipping(Xen fd) { #define H_mus_file_clipping "(" S_mus_file_clipping " fd): whether sound data written to file 'fd' should be clipped" Xen_check_type(Xen_is_integer(fd), fd, 1, S_mus_file_clipping, "an integer"); return(C_bool_to_Xen_boolean(mus_file_clipping(Xen_integer_to_C_int(fd)))); } static Xen g_mus_file_set_clipping(Xen fd, Xen clipped) { Xen_check_type(Xen_is_integer(fd), fd, 1, S_set S_mus_file_clipping, "an integer"); Xen_check_type(Xen_is_boolean(clipped), clipped, 2, S_set S_mus_file_clipping, "a boolean"); return(C_bool_to_Xen_boolean(mus_file_set_clipping(Xen_integer_to_C_int(fd), Xen_boolean_to_C_bool(clipped)))); } Xen g_mus_expand_filename(Xen file) { #define H_mus_expand_filename "(" S_mus_expand_filename " name): expand 'name' into a canonical or absolute filename, that is, \ one in which all directories in the path are explicit." char *str = NULL; Xen result; Xen_check_type(Xen_is_string(file), file, 1, S_mus_expand_filename, "a string"); str = mus_expand_filename(Xen_string_to_C_string(file)); result = C_string_to_Xen_string(str); if (str) free(str); return(result); } static Xen g_mus_sound_report_cache(Xen file) { #define H_mus_sound_report_cache "(" S_mus_sound_report_cache " (name)): print the current sound \ cache info to the file given or stdout" const char *name; if (!Xen_is_bound(file)) { mus_sound_report_cache(stdout); return(Xen_false); } Xen_check_type(Xen_is_string(file), file, 1, S_mus_sound_report_cache, "a string"); name = Xen_string_to_C_string(file); if (name) { char *str = NULL; str = mus_expand_filename(name); if (str) { FILE *fd; fd = FOPEN(str, "w"); free(str); if (fd) { mus_sound_report_cache(fd); FCLOSE(fd, name); return(file); } } } Xen_error(Xen_make_error_type("cannot-save"), Xen_list_3(C_string_to_Xen_string(S_mus_sound_report_cache ": ~S ~A"), file, C_string_to_Xen_string(STRERROR(errno)))); return(Xen_false); } static Xen g_mus_error_type_to_string(Xen err) { #define H_mus_error_type_to_string "(" S_mus_error_type_to_string " err): string description of err (a sndlib error type)" Xen_check_type(Xen_is_integer(err), err, 1, S_mus_error_type_to_string, "an integer"); return(C_string_to_Xen_string((char *)mus_error_type_to_string(Xen_integer_to_C_int(err)))); } static Xen g_array_to_file(Xen filename, Xen data, Xen len, Xen srate, Xen channels) { #define H_array_to_file "(" S_array_to_file " filename data len srate channels): write 'data', \ a " S_vct " of interleaved samples, to the sound file 'filename' set up to have the given \ srate and channels. 'len' samples are written." /* this exists for compatibility with the Common Lisp version of CLM. Ideally, we'd get rid * of it and provide vct<->file and sound-data<->file instead so that the channels aren't * handled through interleaving. But that means extensive changes to the Lisp code... */ mus_long_t olen, samps; vct *v; Xen_check_type(Xen_is_string(filename), filename, 1, S_array_to_file, "a string"); Xen_check_type(mus_is_vct(data), data, 2, S_array_to_file, "a " S_vct); Xen_check_type(Xen_is_llong(len), len, 3, S_array_to_file, "an integer"); Xen_check_type(Xen_is_integer(srate), srate, 4, S_array_to_file, "an integer"); Xen_check_type(Xen_is_integer(channels), channels, 5, S_array_to_file, "an integer"); v = Xen_to_vct(data); samps = Xen_llong_to_C_llong(len); if (samps <= 0) Xen_out_of_range_error(S_array_to_file, 3, len, "samples <= 0?"); if (samps > mus_vct_length(v)) samps = mus_vct_length(v); olen = mus_float_array_to_file(Xen_string_to_C_string(filename), mus_vct_data(v), samps, Xen_integer_to_C_int(srate), Xen_integer_to_C_int(channels)); return(C_llong_to_Xen_llong(olen)); } static Xen g_file_to_array(Xen filename, Xen chan, Xen start, Xen samples, Xen data) { #define H_file_to_array "(" S_file_to_array " filename chan start samples data): read the sound file \ 'filename' placing samples from channel 'chan' into the " S_vct " 'data' starting in the file \ at frample 'start' and reading 'samples' samples altogether." int chn, chans; mus_long_t samps; vct *v; const char *name = NULL; Xen_check_type(Xen_is_string(filename), filename, 1, S_file_to_array, "a string"); Xen_check_type(Xen_is_integer(chan), chan, 2, S_file_to_array, "an integer"); Xen_check_type(Xen_is_llong(start), start, 3, S_file_to_array, "an integer"); Xen_check_type(Xen_is_llong(samples), samples, 4, S_file_to_array, "an integer"); Xen_check_type((mus_is_vct(data)), data, 5, S_file_to_array, "a " S_vct); name = Xen_string_to_C_string(filename); if (!(mus_file_probe(name))) Xen_error(NO_SUCH_FILE, Xen_list_3(C_string_to_Xen_string(S_file_to_array ": ~S ~A"), filename, C_string_to_Xen_string(STRERROR(errno)))); v = Xen_to_vct(data); samps = Xen_llong_to_C_llong(samples); if (samps <= 0) Xen_out_of_range_error(S_file_to_array, 4, samples, "samples <= 0?"); if (samps > mus_vct_length(v)) samps = mus_vct_length(v); chn = Xen_integer_to_C_int(chan); chans = mus_sound_chans(name); if ((chn < 0) || (chn > chans)) Xen_error(NO_SUCH_CHANNEL, Xen_list_4(C_string_to_Xen_string(S_file_to_array ": invalid chan: ~A, ~S has ~A chans"), chan, filename, C_int_to_Xen_integer(chans))); if (chans <= 0) Xen_error(BAD_HEADER, Xen_list_2(C_string_to_Xen_string(S_file_to_array ": ~S chans <= 0"), filename)); mus_file_to_float_array(name, chn, Xen_llong_to_C_llong(start), samps, mus_vct_data(v)); return(data); } static Xen new_sound_hook; static void g_new_sound_hook(const char *filename) { if (Xen_hook_has_list(new_sound_hook)) { #if HAVE_SCHEME s7_call(s7, new_sound_hook, s7_cons(s7, C_string_to_Xen_string(filename), Xen_empty_list)); #else Xen procs, fname; fname = C_string_to_Xen_string(filename); procs = Xen_hook_list(new_sound_hook); while (!Xen_is_null(procs)) { Xen_call_with_1_arg(Xen_car(procs), fname, S_new_sound_hook); procs = Xen_cdr(procs); } #endif } } static Xen sound_path; Xen g_mus_sound_path(void) { #define H_mus_sound_path "(" S_mus_sound_path "): a list of directories to search for sound files." return(sound_path); } #if HAVE_SCHEME static int sound_path_loc = -1; static s7_pointer mus_sound_path_symbol; #endif static Xen g_mus_set_sound_path(Xen val) { Xen_check_type(Xen_is_list(val), val, 1, S_set S_mus_sound_path, "a list"); #if HAVE_SCHEME if (sound_path_loc != -1) s7_gc_unprotect_at(s7, sound_path_loc); sound_path = val; sound_path_loc = s7_gc_protect(s7, sound_path); s7_symbol_set_value(s7, mus_sound_path_symbol, val); #else if (sound_path != Xen_empty_list) Xen_GC_unprotect(sound_path); Xen_GC_protect(val); sound_path = val; #endif return(val); } static Xen g_mus_max_malloc(void) { #define H_mus_max_malloc "(" S_mus_max_malloc "): maximum number of bytes we will try to malloc." return(C_llong_to_Xen_llong(mus_max_malloc())); } #if HAVE_SCHEME static s7_pointer mus_max_malloc_symbol; #endif static Xen g_mus_set_max_malloc(Xen val) { mus_long_t size; Xen_check_type(Xen_is_llong(val), val, 1, S_set S_mus_max_malloc, "an integer"); size = Xen_llong_to_C_llong(val); #if HAVE_SCHEME s7_symbol_set_value(s7, mus_max_malloc_symbol, s7_make_integer(s7, size)); #endif return(C_llong_to_Xen_llong(mus_set_max_malloc(size))); } static Xen g_mus_max_table_size(void) { #define H_mus_max_table_size "(" S_mus_max_table_size "): maximum table size." return(C_llong_to_Xen_llong(mus_max_table_size())); } #if HAVE_SCHEME static s7_pointer mus_max_table_size_symbol; #endif static Xen g_mus_set_max_table_size(Xen val) { mus_long_t size; Xen_check_type(Xen_is_llong(val), val, 1, S_set S_mus_max_table_size, "an integer"); size = Xen_llong_to_C_llong(val); #if HAVE_SCHEME s7_symbol_set_value(s7, mus_max_table_size_symbol, s7_make_integer(s7, size)); #endif return(C_llong_to_Xen_llong(mus_set_max_table_size(size))); } #if __APPLE__ #define S_mus_audio_output_properties_mutable "mus-audio-output-properties-mutable" static Xen g_mus_audio_output_properties_mutable(Xen mut) { #define H_mus_audio_output_properties_mutable "(" S_mus_audio_output_properties_mutable " val): can DAC settings be changed to match the current sound" Xen_check_type(Xen_is_boolean(mut), mut, 1, S_mus_audio_output_properties_mutable, "a boolean"); return(C_bool_to_Xen_boolean(mus_audio_output_properties_mutable(Xen_boolean_to_C_bool(mut)))); } #endif Xen_wrap_1_arg(g_mus_sound_samples_w, g_mus_sound_samples) Xen_wrap_2_args(g_mus_sound_set_samples_w, g_mus_sound_set_samples) Xen_wrap_1_arg(g_mus_sound_framples_w, g_mus_sound_framples) Xen_wrap_1_arg(g_mus_sound_duration_w, g_mus_sound_duration) Xen_wrap_1_arg(g_mus_sound_datum_size_w, g_mus_sound_datum_size) Xen_wrap_1_arg(g_mus_sound_data_location_w, g_mus_sound_data_location) Xen_wrap_2_args(g_mus_sound_set_data_location_w, g_mus_sound_set_data_location) Xen_wrap_1_arg(g_mus_sound_chans_w, g_mus_sound_chans) Xen_wrap_2_args(g_mus_sound_set_chans_w, g_mus_sound_set_chans) Xen_wrap_1_arg(g_mus_sound_srate_w, g_mus_sound_srate) Xen_wrap_2_args(g_mus_sound_set_srate_w, g_mus_sound_set_srate) Xen_wrap_1_arg(g_mus_sound_header_type_w, g_mus_sound_header_type) Xen_wrap_2_args(g_mus_sound_set_header_type_w, g_mus_sound_set_header_type) Xen_wrap_1_arg(g_mus_sound_sample_type_w, g_mus_sound_sample_type) Xen_wrap_2_args(g_mus_sound_set_sample_type_w, g_mus_sound_set_sample_type) Xen_wrap_1_arg(g_mus_sound_length_w, g_mus_sound_length) Xen_wrap_1_arg(g_mus_sound_type_specifier_w, g_mus_sound_type_specifier) Xen_wrap_1_arg(g_mus_header_type_name_w, g_mus_header_type_name) Xen_wrap_1_arg(g_mus_header_type_to_string_w, g_mus_header_type_to_string) Xen_wrap_1_arg(g_mus_sample_type_name_w, g_mus_sample_type_name) Xen_wrap_1_arg(g_mus_sample_type_to_string_w, g_mus_sample_type_to_string) Xen_wrap_1_arg(g_mus_sound_comment_w, g_mus_sound_comment) Xen_wrap_1_arg(g_mus_sound_write_date_w, g_mus_sound_write_date) Xen_wrap_1_arg(g_mus_bytes_per_sample_w, g_mus_bytes_per_sample) Xen_wrap_1_arg(g_mus_sound_loop_info_w, g_mus_sound_loop_info) Xen_wrap_1_arg(g_mus_sound_mark_info_w, g_mus_sound_mark_info) Xen_wrap_1_arg(g_mus_sound_maxamp_w, g_mus_sound_maxamp) Xen_wrap_2_args(g_mus_sound_set_maxamp_w, g_mus_sound_set_maxamp) Xen_wrap_1_arg(g_mus_sound_maxamp_exists_w, g_mus_sound_maxamp_exists) Xen_wrap_1_arg(g_mus_sound_preload_w, g_mus_sound_preload) Xen_wrap_no_args(g_mus_clipping_w, g_mus_clipping) Xen_wrap_1_arg(g_mus_set_clipping_w, g_mus_set_clipping) Xen_wrap_1_arg(g_mus_file_clipping_w, g_mus_file_clipping) Xen_wrap_2_args(g_mus_file_set_clipping_w, g_mus_file_set_clipping) Xen_wrap_no_args(g_mus_header_raw_defaults_w, g_mus_header_raw_defaults) Xen_wrap_1_arg(g_mus_header_set_raw_defaults_w, g_mus_header_set_raw_defaults) Xen_wrap_2_args(g_mus_header_writable_w, g_mus_header_writable) Xen_wrap_1_arg(g_mus_expand_filename_w, g_mus_expand_filename) Xen_wrap_1_optional_arg(g_mus_sound_report_cache_w, g_mus_sound_report_cache) Xen_wrap_1_arg(g_mus_sound_forget_w, g_mus_sound_forget) Xen_wrap_no_args(g_mus_sound_prune_w, g_mus_sound_prune) Xen_wrap_1_arg(g_mus_error_type_to_string_w, g_mus_error_type_to_string) Xen_wrap_2_args(g_mus_oss_set_buffers_w, g_mus_oss_set_buffers) Xen_wrap_5_args(g_array_to_file_w, g_array_to_file) Xen_wrap_5_args(g_file_to_array_w, g_file_to_array) Xen_wrap_no_args(g_mus_alsa_buffers_w, g_mus_alsa_buffers) Xen_wrap_1_arg(g_mus_alsa_set_buffers_w, g_mus_alsa_set_buffers) Xen_wrap_no_args(g_mus_alsa_buffer_size_w, g_mus_alsa_buffer_size) Xen_wrap_1_arg(g_mus_alsa_set_buffer_size_w, g_mus_alsa_set_buffer_size) Xen_wrap_no_args(g_mus_alsa_device_w, g_mus_alsa_device) Xen_wrap_1_arg(g_mus_alsa_set_device_w, g_mus_alsa_set_device) Xen_wrap_no_args(g_mus_alsa_playback_device_w, g_mus_alsa_playback_device) Xen_wrap_1_arg(g_mus_alsa_set_playback_device_w, g_mus_alsa_set_playback_device) Xen_wrap_no_args(g_mus_alsa_capture_device_w, g_mus_alsa_capture_device) Xen_wrap_1_arg(g_mus_alsa_set_capture_device_w, g_mus_alsa_set_capture_device) Xen_wrap_no_args(g_mus_alsa_squelch_warning_w, g_mus_alsa_squelch_warning) Xen_wrap_1_arg(g_mus_alsa_set_squelch_warning_w, g_mus_alsa_set_squelch_warning) #if __APPLE__ Xen_wrap_1_arg(g_mus_audio_output_properties_mutable_w, g_mus_audio_output_properties_mutable) #endif Xen_wrap_no_args(g_mus_max_malloc_w, g_mus_max_malloc) Xen_wrap_1_arg(g_mus_set_max_malloc_w, g_mus_set_max_malloc) Xen_wrap_no_args(g_mus_max_table_size_w, g_mus_max_table_size) Xen_wrap_1_arg(g_mus_set_max_table_size_w, g_mus_set_max_table_size) Xen_wrap_no_args(g_mus_sound_path_w, g_mus_sound_path) Xen_wrap_1_arg(g_mus_set_sound_path_w, g_mus_set_sound_path) #if HAVE_SCHEME static s7_pointer acc_mus_max_table_size(s7_scheme *sc, s7_pointer args) {return(g_mus_set_max_table_size(s7_cadr(args)));} static s7_pointer acc_mus_max_malloc(s7_scheme *sc, s7_pointer args) {return(g_mus_set_max_malloc(s7_cadr(args)));} static s7_pointer acc_mus_sound_path(s7_scheme *sc, s7_pointer args) {return(g_mus_set_sound_path(s7_cadr(args)));} #endif void mus_sndlib_xen_initialize(void) { #if HAVE_SCHEME s7_pointer pl_is, pl_isi, pl_si, pl_ss, pl_ps, pl_psp, pl_i, pl_bii, pl_p, pl_rs, pl_bi, pl_bib, pl_b; s7_pointer pl_l, pl_isfiii, pl_fsiiif, pl_bs, pl_ts; #endif mus_sound_initialize(); sound_path = Xen_empty_list; #if HAVE_RUBY Init_Hook(); #endif Xen_define_constant(S_mus_out_format, MUS_OUT_SAMPLE_TYPE, "sample type for fastest IO"); Xen_define_constant(S_mus_unknown_header, MUS_UNKNOWN_HEADER, "unknown header type"); Xen_define_constant(S_mus_next, MUS_NEXT, "NeXT (Sun) sound header id"); Xen_define_constant(S_mus_aifc, MUS_AIFC, "AIFC sound header id"); Xen_define_constant(S_mus_rf64, MUS_RF64, "RF64 sound header id"); Xen_define_constant(S_mus_riff, MUS_RIFF, "RIFF (MS wave) sound header id"); Xen_define_constant(S_mus_nist, MUS_NIST, "NIST (Sphere) sound header id"); Xen_define_constant(S_mus_raw, MUS_RAW, "raw (headerless) sound header id"); Xen_define_constant(S_mus_ircam, MUS_IRCAM, "IRCAM sound header id"); Xen_define_constant(S_mus_aiff, MUS_AIFF, "AIFF (old-style) sound header id"); Xen_define_constant(S_mus_bicsf, MUS_BICSF, "BICSF header id"); Xen_define_constant(S_mus_voc, MUS_VOC, "VOC header id"); Xen_define_constant(S_mus_svx, MUS_SVX, "SVX (IFF) header id"); Xen_define_constant(S_mus_soundfont, MUS_SOUNDFONT, "soundfont header id"); Xen_define_constant(S_mus_caff, MUS_CAFF, "Apple Core Audio File Format header id"); Xen_define_constant(S_mus_unknown_sample, MUS_UNKNOWN_SAMPLE, "unknown sample type"); Xen_define_constant(S_mus_bshort, MUS_BSHORT, "big-endian short sample type id"); Xen_define_constant(S_mus_lshort, MUS_LSHORT, "little-endian short sample type id"); Xen_define_constant(S_mus_mulaw, MUS_MULAW, "mulaw (8-bit) sample type id"); Xen_define_constant(S_mus_alaw, MUS_ALAW, "alaw (8-bit) sample type id"); Xen_define_constant(S_mus_byte, MUS_BYTE, "signed byte sample type id"); Xen_define_constant(S_mus_ubyte, MUS_UBYTE, "unsigned byte sample type id"); Xen_define_constant(S_mus_bfloat, MUS_BFLOAT, "big-endian float sample type id"); Xen_define_constant(S_mus_lfloat, MUS_LFLOAT, "little-endian float sample type id"); Xen_define_constant(S_mus_bint, MUS_BINT, "big-endian int sample type id"); Xen_define_constant(S_mus_lint, MUS_LINT, "little-endian int sample type id"); Xen_define_constant(S_mus_bintn, MUS_BINTN, "normalized big-endian int sample type id"); Xen_define_constant(S_mus_lintn, MUS_LINTN, "normalized little-endian int sample type id"); Xen_define_constant(S_mus_b24int, MUS_B24INT, "big-endian 24-bit sample type id"); Xen_define_constant(S_mus_l24int, MUS_L24INT, "little-endian 24-bit sample type id"); Xen_define_constant(S_mus_bdouble, MUS_BDOUBLE, "big-endian double sample type id"); Xen_define_constant(S_mus_ldouble, MUS_LDOUBLE, "little-endian double sample type id"); Xen_define_constant(S_mus_ubshort, MUS_UBSHORT, "unsigned big-endian short sample type id"); Xen_define_constant(S_mus_ulshort, MUS_ULSHORT, "unsigned little-endian short sample type id"); Xen_define_constant(S_mus_bdouble_unscaled, MUS_BDOUBLE_UNSCALED, "unscaled big-endian double sample type id"); Xen_define_constant(S_mus_ldouble_unscaled, MUS_LDOUBLE_UNSCALED, "unscaled little-endian double sample type id"); Xen_define_constant(S_mus_bfloat_unscaled, MUS_BFLOAT_UNSCALED, "unscaled big-endian float sample type id"); Xen_define_constant(S_mus_lfloat_unscaled, MUS_LFLOAT_UNSCALED, "unscaled little-endian float sample type id"); #if HAVE_SCHEME { s7_pointer s, i, p, b, r, f, t, l; s = s7_make_symbol(s7, "string?"); i = s7_make_symbol(s7, "integer?"); p = s7_make_symbol(s7, "pair?"); l = s7_make_symbol(s7, "list?"); b = s7_make_symbol(s7, "boolean?"); r = s7_make_symbol(s7, "real?"); f = s7_make_symbol(s7, "float-vector?"); t = s7_t(s7); pl_is = s7_make_signature(s7, 2, i, s); pl_isi = s7_make_signature(s7, 3, i, s, i); pl_si = s7_make_signature(s7, 2, s, i); pl_ss = s7_make_signature(s7, 2, s, s); pl_ts = s7_make_signature(s7, 2, t, s); pl_ps = s7_make_signature(s7, 2, p, s); pl_psp = s7_make_signature(s7, 3, p, s, p); pl_i = s7_make_circular_signature(s7, 0, 1, i); pl_bii = s7_make_signature(s7, 3, b, i, i); pl_p = s7_make_circular_signature(s7, 0, 1, p); pl_l = s7_make_circular_signature(s7, 0, 1, l); pl_rs = s7_make_signature(s7, 2, r, s); pl_bi = s7_make_signature(s7, 2, b, i); pl_bib = s7_make_signature(s7, 3, b, i, b); pl_b = s7_make_circular_signature(s7, 0, 1, b); pl_bs = s7_make_signature(s7, 2, b, s); pl_isfiii = s7_make_signature(s7, 6, i, s, f, i, i, i); pl_fsiiif = s7_make_signature(s7, 6, f, s, i, i, i, f); } #endif Xen_define_typed_dilambda(S_mus_sound_samples, g_mus_sound_samples_w, H_mus_sound_samples, S_set S_mus_sound_samples, g_mus_sound_set_samples_w, 1, 0, 2, 0, pl_is, pl_isi); Xen_define_typed_dilambda(S_mus_sound_data_location, g_mus_sound_data_location_w, H_mus_sound_data_location, S_set S_mus_sound_data_location, g_mus_sound_set_data_location_w, 1, 0, 2, 0, pl_is, pl_isi); Xen_define_typed_dilambda(S_mus_sound_chans, g_mus_sound_chans_w, H_mus_sound_chans, S_set S_mus_sound_chans, g_mus_sound_set_chans_w, 1, 0, 2, 0, pl_is, pl_isi); Xen_define_typed_dilambda(S_mus_sound_srate, g_mus_sound_srate_w, H_mus_sound_srate, S_set S_mus_sound_srate, g_mus_sound_set_srate_w, 1, 0, 2, 0, pl_is, pl_isi); Xen_define_typed_dilambda(S_mus_sound_header_type, g_mus_sound_header_type_w, H_mus_sound_header_type, S_set S_mus_sound_header_type, g_mus_sound_set_header_type_w, 1, 0, 2, 0, pl_is, pl_isi); Xen_define_typed_dilambda(S_mus_sound_sample_type, g_mus_sound_sample_type_w, H_mus_sound_sample_type, S_set S_mus_sound_sample_type, g_mus_sound_set_sample_type_w, 1, 0, 2, 0, pl_is, pl_isi); Xen_define_typed_procedure(S_mus_sound_framples, g_mus_sound_framples_w, 1, 0, 0, H_mus_sound_framples, pl_is); Xen_define_typed_procedure("mus-sound-frames", g_mus_sound_framples_w, 1, 0, 0, H_mus_sound_framples, pl_is); Xen_define_typed_procedure(S_mus_sound_duration, g_mus_sound_duration_w, 1, 0, 0, H_mus_sound_duration, pl_rs); Xen_define_typed_procedure(S_mus_sound_datum_size, g_mus_sound_datum_size_w, 1, 0, 0, H_mus_sound_datum_size, pl_is); Xen_define_typed_procedure(S_mus_sound_length, g_mus_sound_length_w, 1, 0, 0, H_mus_sound_length, pl_is); Xen_define_typed_procedure(S_mus_sound_type_specifier, g_mus_sound_type_specifier_w, 1, 0, 0, H_mus_sound_type_specifier, pl_is); Xen_define_typed_procedure(S_mus_header_type_name, g_mus_header_type_name_w, 1, 0, 0, H_mus_header_type_name, pl_si); Xen_define_typed_procedure(S_mus_header_type_to_string,g_mus_header_type_to_string_w, 1, 0, 0, H_mus_header_type_to_string, pl_si); Xen_define_typed_procedure(S_mus_header_writable, g_mus_header_writable_w, 2, 0, 0, H_mus_header_writable, pl_bii); Xen_define_typed_procedure(S_mus_sample_type_name, g_mus_sample_type_name_w, 1, 0, 0, H_mus_sample_type_name, pl_si); Xen_define_typed_procedure(S_mus_sample_type_to_string,g_mus_sample_type_to_string_w, 1, 0, 0, H_mus_sample_type_to_string, pl_si); Xen_define_typed_procedure(S_mus_sound_comment, g_mus_sound_comment_w, 1, 0, 0, H_mus_sound_comment, pl_ts); Xen_define_typed_procedure(S_mus_sound_write_date, g_mus_sound_write_date_w, 1, 0, 0, H_mus_sound_write_date, pl_is); Xen_define_typed_procedure(S_mus_bytes_per_sample, g_mus_bytes_per_sample_w, 1, 0, 0, H_mus_bytes_per_sample, pl_i); Xen_define_typed_procedure(S_mus_sound_loop_info, g_mus_sound_loop_info_w, 1, 0, 0, H_mus_sound_loop_info, pl_ps); Xen_define_typed_procedure(S_mus_sound_mark_info, g_mus_sound_mark_info_w, 1, 0, 0, H_mus_sound_mark_info, pl_ps); Xen_define_typed_procedure(S_mus_sound_maxamp_exists, g_mus_sound_maxamp_exists_w, 1, 0, 0, H_mus_sound_maxamp_exists, pl_bs); Xen_define_typed_procedure(S_mus_sound_forget, g_mus_sound_forget_w, 1, 0, 0, H_mus_sound_forget, pl_is); Xen_define_typed_procedure(S_mus_sound_prune, g_mus_sound_prune_w, 0, 0, 0, H_mus_sound_prune, pl_i); Xen_define_typed_procedure(S_mus_expand_filename, g_mus_expand_filename_w, 1, 0, 0, H_mus_expand_filename, pl_ss); Xen_define_typed_procedure(S_mus_sound_report_cache, g_mus_sound_report_cache_w, 0, 1, 0, H_mus_sound_report_cache, NULL); Xen_define_typed_procedure(S_mus_error_type_to_string, g_mus_error_type_to_string_w, 1, 0, 0, H_mus_error_type_to_string, pl_si); Xen_define_typed_procedure(S_mus_oss_set_buffers, g_mus_oss_set_buffers_w, 2, 0, 0, H_mus_oss_set_buffers, pl_bii); Xen_define_typed_procedure(S_array_to_file, g_array_to_file_w, 5, 0, 0, H_array_to_file, pl_isfiii); Xen_define_typed_procedure(S_file_to_array, g_file_to_array_w, 5, 0, 0, H_file_to_array, pl_fsiiif); Xen_define_typed_procedure(S_mus_sound_preload, g_mus_sound_preload_w, 1, 0, 0, H_mus_sound_preload, pl_ss); Xen_define_typed_dilambda(S_mus_header_raw_defaults, g_mus_header_raw_defaults_w, H_mus_header_raw_defaults, S_set S_mus_header_raw_defaults, g_mus_header_set_raw_defaults_w, 0, 0, 1, 0, pl_p, pl_p); Xen_define_typed_dilambda(S_mus_clipping, g_mus_clipping_w, H_mus_clipping, S_set S_mus_clipping, g_mus_set_clipping_w, 0, 0, 1, 0, pl_b, pl_b); Xen_define_typed_dilambda(S_mus_file_clipping, g_mus_file_clipping_w, H_mus_file_clipping, S_set S_mus_file_clipping, g_mus_file_set_clipping_w, 1, 0, 2, 0, pl_bi, pl_bib); Xen_define_typed_dilambda(S_mus_sound_maxamp, g_mus_sound_maxamp_w, H_mus_sound_maxamp, S_set S_mus_sound_maxamp, g_mus_sound_set_maxamp_w, 1, 0, 2, 0, pl_ps, pl_psp); /* these are no-ops if not ALSA, but that makes it easier to maintain global initialization files */ Xen_define_typed_dilambda(S_mus_alsa_buffers, g_mus_alsa_buffers_w, H_mus_alsa_buffers, S_set S_mus_alsa_buffers, g_mus_alsa_set_buffers_w, 0, 0, 1, 0, NULL, NULL); Xen_define_typed_dilambda(S_mus_alsa_buffer_size, g_mus_alsa_buffer_size_w, H_mus_alsa_buffer_size, S_set S_mus_alsa_buffer_size, g_mus_alsa_set_buffer_size_w, 0, 0, 1, 0, NULL, NULL); Xen_define_typed_dilambda(S_mus_alsa_device, g_mus_alsa_device_w, H_mus_alsa_device, S_set S_mus_alsa_device, g_mus_alsa_set_device_w, 0, 0, 1, 0, NULL, NULL); Xen_define_typed_dilambda(S_mus_alsa_playback_device, g_mus_alsa_playback_device_w, H_mus_alsa_playback_device, S_set S_mus_alsa_playback_device, g_mus_alsa_set_playback_device_w, 0, 0, 1, 0, NULL, NULL); Xen_define_typed_dilambda(S_mus_alsa_capture_device, g_mus_alsa_capture_device_w, H_mus_alsa_capture_device, S_set S_mus_alsa_capture_device, g_mus_alsa_set_capture_device_w, 0, 0, 1, 0, NULL, NULL); Xen_define_typed_dilambda(S_mus_alsa_squelch_warning, g_mus_alsa_squelch_warning_w, H_mus_alsa_squelch_warning, S_set S_mus_alsa_squelch_warning, g_mus_alsa_set_squelch_warning_w, 0, 0, 1, 0, NULL, NULL); Xen_define_typed_dilambda(S_mus_max_malloc, g_mus_max_malloc_w, H_mus_max_malloc, S_set S_mus_max_malloc, g_mus_set_max_malloc_w, 0, 0, 1, 0, pl_i, pl_i); Xen_define_typed_dilambda(S_mus_max_table_size, g_mus_max_table_size_w, H_mus_max_table_size, S_set S_mus_max_table_size, g_mus_set_max_table_size_w, 0, 0, 1, 0, pl_i, pl_i); Xen_define_typed_dilambda(S_mus_sound_path, g_mus_sound_path_w, H_mus_sound_path, S_set S_mus_sound_path, g_mus_set_sound_path_w, 0, 0, 1, 0, pl_l, pl_l); #if HAVE_SCHEME mus_max_table_size_symbol = s7_define_variable(s7, "*" S_mus_max_table_size "*", s7_make_integer(s7, MUS_MAX_TABLE_SIZE_DEFAULT)); s7_symbol_set_documentation(s7, mus_max_table_size_symbol, "*mus-max-table-size*: maximum table size."); s7_symbol_set_access(s7, mus_max_table_size_symbol, s7_make_function(s7, "[acc-mus-max-table-size]" "]", acc_mus_max_table_size, 2, 0, false, "accessor")); mus_max_malloc_symbol = s7_define_variable(s7, "*" S_mus_max_malloc "*", s7_make_integer(s7, MUS_MAX_MALLOC_DEFAULT)); s7_symbol_set_documentation(s7, mus_max_malloc_symbol, "*mus-max-malloc*: maximum number of bytes we will try to malloc."); s7_symbol_set_access(s7, mus_max_malloc_symbol, s7_make_function(s7, "[acc-mus-max-malloc]" "]", acc_mus_max_malloc, 2, 0, false, "accessor")); mus_sound_path_symbol = s7_define_variable(s7, "*" S_mus_sound_path "*", s7_nil(s7)); s7_symbol_set_documentation(s7, mus_sound_path_symbol, "*" S_mus_sound_path "* is a list of directories to search for sound files"); s7_symbol_set_access(s7, mus_sound_path_symbol, s7_make_function(s7, "[acc-mus-sound-path]" "]", acc_mus_sound_path, 2, 0, false, "accessor")); #endif #if __APPLE__ Xen_define_procedure(S_mus_audio_output_properties_mutable, g_mus_audio_output_properties_mutable_w, 1, 0, 0, H_mus_audio_output_properties_mutable); #endif #define H_new_sound_hook S_new_sound_hook "(name): called when a new sound file is being created" new_sound_hook = Xen_define_hook(S_new_sound_hook, "(make-hook 'name)", 1, H_new_sound_hook); mus_header_write_set_hook(g_new_sound_hook); Xen_provide_feature("sndlib"); } snd-16.1/xm.c0000644000076400007640000453002512614436175011145 0ustar bilbil/* xm.c: s7/Ruby/Forth bindings for X/Xt/Xpm/Xm/Xext * needs xen.h * for tests and examples see snd-motif.scm, bess.scm|rb, and snd-test.scm */ #include "mus-config.h" #include #define HAVE_XSHAPEQUERYEXTENSION 1 /* this dates from X11 R6.4 -- set to 0 if you're running a 20 year old version of X */ #define HAVE_XP 0 #define XM_DATE "29-Oct-15" /* HISTORY: * * 29-Oct-15: removed ->string. * -------- * 6-Mar: more macro name changes. * 21-Feb-14: _P changed to use _is_. * -------- * 7-Jul-13: removed the non-standard extra widgets. * -------- * 20-Oct: changed INT64_T to LONG_LONG. * 20-Mar-11: X/Xpm/Motif are assumed now. * -------- * 23-Dec: removed XmPrint/libXp support. * 16-Dec: removed Guile support. * 16-Nov: XM_XTPOINTER resource type for 64-bit systems. * 7-Aug: s7 extended type change. * 27-Jul: changed OFF_T to INT64_T. * 24-Feb: and then changed some back to ULONGs! * 16-Jan: changed some ULONG's to C_POINTER's * 12-Jan-09: changed strdup to xen_strdup. * -------- * 11-Dec: removed all the stuff on the XM_DISABLE_DEPRECATED switch. * 16-Oct: removed Gauche support. * 1-Oct: XtAppAddInput condition arg is a mess. * 10-Sep: XtAppAddInput condition arg is an int. * 1-Sep-08: S7 support. * -------- * 26-Aug: removed WITH_GTK_AND_X11 switch. * 21-Apr: Gauche additions. * 30-Jan: removed XmMultiList. * 1-Jan-06: XmNpopupEnabled resource type changed from boolean to int (enum) (Motif docs bug). * -------- * 16-Sep: XmUNSPECIFIED_PIXEL and friends should be unsigned long (not int). * 17-Aug: XtSetArg 3rd arg should be 0, not NULL (type mismatch if 64-bit). * 14-June: various xen-related updates (Xen_DEFINE). * 13-June: fold xm-ruby.c into xm.c. * 15-Apr: XGetWindowProperty free bugfix. * 28-Mar: fix some Ruby error strings (#f->false). * 31-Jan: remove Motif 1 support, and Lesstif. * 4-Jan-05: replace Xen_VECTOR_ELEMENTS usages. * -------- * 30-Dec: plug various memory leaks. * 23-Nov: resource type lookup indexing bugfix. * 22-Sep: various minor cleanups. * 23-Aug: more changes for new Guile. * 12-Aug: some changes to accommodate new Guile names. * 22-June: XmColorSelector resources. * 19-May: plug several memory leaks. * 21-Apr: XmMultiList, XmTabStack. * 19-Apr: XmDataField. * 12-Apr: XmDropDown, XmColumn. * 7-Apr: XmButtonBox. * 22-Mar: added feature 'Xp to indicate that the Xp stuff is included. * 8-Mar: XtAppAddActionHook arity bugfix. * 12-Jan: resources for XmFontSelector. * 8-Jan: various changes for the SGI C compiler, thanks to Avi Bercovich. * 5-Jan-04: added (Motif 2.2.3) XmCreateFontSelector, XmCreateColorSelector. * -------- * 1-Dec: XShapeGetRectangles XRectangle array needed local allocation. * removed (unusable) XtCallCallbackList. * 25-Nov: more GC protection. Removed XInitThreads, XLockDisplay, XUnlockDisplay. Fixed XmTextBlock allocation bug. * 15-Oct: XFontsOfFontSet indexing bugfix and several more struct field accessors from MS. * 14-Oct: XShapeQueryExtension from Michael Scholz, plus other extensions/shape.h functions and constants. * Also XSizeHints, XSet[Standard|WM]Properties and accessors for input and initial_state. * 3-Oct: removed some macros that were intended only for testing, added XmTOP_LEFT etc. * 29-Sep: changed: XSetWindowBorder, XSetWindowBackground, XCreatePixmapFromBitmapData, XSetWindowAttributes, * .backing_pixel, .border_pixel, .background_pixel, .base_pixel; these now use the "wrapped" * form of pixels, not the bare unsigned long. * 26-Sep: .event -> #f if event is NULL. * 3-Sep: XmRenderTableGetRenditions was incorrectly freeing the XmRenditions. * 20-Aug: XtEventHandler *flag set to false if handler returns 'done. * 11-Aug: int -> bool. * 17-July: XpmAttributes .colorsymbols is a list. * 15-July: type check cleanups. * 14-July: .depths returns a list of Depth pointers; similar change for .visuals. * 11-July: Several int->Dimension|Position|short resource type changes. * removed several more undocumented resource names. * 23-June: Motif 1 fixups. * 10-June: added XmCvtByteStreamToXmString, XmCvtXmStringToByteStream, XmStringByteStreamLength. * removed XFreeStringList (a no-op). * 20-May: showValue resource is int (enumeration) in Motif 2. resizeWidth|Height are booleans, not ints. * 9-May: Ruby fixups (some functions accidentally omitted earlier). * 8-Apr: XSetErrorHandler proc takes XErrorEvent, not XEvent 2nd arg (thanks Friedrich Delgado Friedrichs) * 7-Apr: more changes for the WITH_GTK_AND_X11 switch. * 1-Apr: XGetWindowProperty uses mem2string if not XA_STRING. * 31-Mar: added WITH_GTK_AND_X11 switch for xg+local X funcs. * 4-Mar: xm-ruby XM_DEFINE_ACCESSOR quoted SetName bugfix (Michael Scholz). * 1-Feb-03: XChangeProperty data (arg7) can be list of ints as well as string. * ---------- * 19-Dec: more Ruby fixups. * 6-Nov: Ruby XmWMProtocols bugfixes thanks to Michael Scholz. * 17-Oct: XtAppSetFallbackResources and fallbacks added to XtAppInitialize etc. * 15-Oct: XtGetResourceList. * 11-Oct: xm-ruby XM_DEFINE* cleaned up (thanks to Michael Scholz). * removed all (ignored) XrmOptionDesc args (XtAppInitialize etc). * 8-Oct: added [MUS_]WITH_EDITRES to include _XEditResCheckMessages. * 1-Oct: some int args are now KeyCodes (Modifiermap stuff). * 23-Sep: X ScreenSaver constants omitted earlier. * 18-Sep: properties XFontStruct field now returns list of all properties. * removed XmFontListCreate_r, XmFontListEntryCreate_r * 9-Sep: added Motif WMProtocol convenience macros. * 30-Aug: added add-resource for user-defined extensions to the resources. * 29-Aug: added ten resources accidentally omitted earlier (thanks to Michael Scholz). * 2-Aug: some Lesstif-related compile-time switches. * 26-Jul: removed wrappers Widget Pixel GC and XtAppContext. * 24-Jul: removed "|" prefix, use "." as default struct field prefix. * 19-Jul: XM_FIELD_PREFIX for change from using vertical-bar ("|" is reserved in R5RS). * 17-Jun: removed XtSetWMColormapWindows. * 29-Apr: minor 64-bit fixups. * 29-Mar: XmParseProc. * 20-Mar: XpmGetErrorString omitted inadvertently earlier. * 4-Mar: XWindowChanges and XSetWindowAttributes struct creators. * 1-Mar: XmTabListFree, various ->* conversions(->strings etc). * 25-Feb: XmTextBlock fields * 22-Feb: #f = NULL and vice-versa throughout * 21-Feb: added various callback struct makers, changed XtCallCallbacks to be compatible with them. * 18-Feb: removed undocumented functions: XmCvtFromHorizontalPixels, XmCvtFromVerticalPixels, XmCvtToHorizontalPixels, XInitImage * XmCvtToVerticalPixels, XmGetIconFileName, XmStringCreateFontList, XmStringCreateFontList_r, XmStringLtoRCreate * added XM_DISABLE_DEPRECATED which affects: * XtError, XtSetErrorHandler, XtSetWarningHandler, XtSetErrorMsgHandler, XtSetWarningMsgHandler, XtWarningMsg, XtAppWarning, XtErrorMsg * XtSetSelectionTimeout, XtInitialize , XtAddActions, XtAddInput, XtAddTimeout, XtAddWorkProc, XtCreateApplicationShell * XtNextEvent, XtPeekEvent, XtPending, XtProcessEvent, XtMainLoop, XtGetSelectionTimeout, XtWarning, * XmNdefaultFontList, XmNshellUnitType, XmNfontList, XmFontList*, XmNchildType, XmGetMenuCursor, * XmNstringDirection, XmMainWindowSep1, XmMainWindowSep2, XmMainWindowSep3, XmMainWindowSetAreas, * XmNwhichButton, XmScrolledWindowSetAreas, XmSetFontUnit, XmSetFontUnits, XmNdefaultFontList, * XmSetMenuCursor, XmStringByteCompare, XmStringCreateLtoR, XmSTRING_COMPONENT_CHARSET, XmSTRING_COMPONENT_FONTLIST_ELEMENT_TAG, * XmStringCreateSimple, XmStringGetLtoR, XmStringGetNextComponent, XmStringGetNextSegment, XmStringLength, XmStringNConcat * XmStringNCopy, XmStringPeekNextComponent, XmStringSegmentCreate, XmTrackingLocate, XmRemoveFrom|AddTo|PostFromList * XGet|SetStandardColormap * added XmWidgetGetDisplayRect inadvertently omitted earlier. * 14-Feb: XUniqueContext added, XExtentsOfFontSet and XGetErrorDatabaseText deleted. * X save-set and X host-address stuff deleted. * XVisualInfo fields added. * Cursor type added. * 1-Feb: Motif 2.2 additions (tooltip). * 21-Jan: Ruby fixups (Xen_COPY_ARG to protect lists) * 7-Jan-02: XEvent fields settable. added XtCallCallbacks-raw. * ---------- * 12-Sep: xm-version. * 13-Aug: Xp bindings, X11 predefined Atoms. * 6-Aug: XmTransfer functions inadvertently omitted earlier. * 3-Aug: type checks in XtSetValues. * 23-Jul-01: use lists rather than vectors. */ #if HAVE_EXTENSION_LANGUAGE #include #include #include #include #if HAVE_XSHAPEQUERYEXTENSION #include #endif #if ((!__NetBSD__) && ((_MSC_VER) || (!defined(__STC__)) || (defined(__STDC_VERSION__) && (__STDC_VERSION__ < 199901L)))) #define __func__ __FUNCTION__ #endif /* compile-time flags are HAVE_RUBY|SCHEME WITH_EDITRES */ /* if you're using g++ and it complains about XmRemoveFromPostFromList, update Motif (you need 2.1.30) */ #if USE_SND /* USE_SND causes xm to use Snd's error handlers which are much smarter than xen's fallback versions */ #include "snd.h" #else #include "xen.h" /* in snd-0.h: */ #if HAVE_RUBY #define S_set "set_" #define PROC_FALSE "false" #define PROC_TRUE "true" #endif #if HAVE_SCHEME #define S_set "set! " #define PROC_FALSE "#f" #define PROC_TRUE "#t" #endif #if HAVE_FORTH #define S_set "set-" #define PROC_FALSE "#f" #define PROC_TRUE "#t" #endif #define NOT_A_GC_LOC -1 #endif #include #if WITH_EDITRES #include #endif /* prefix for all names */ #if HAVE_SCHEME #define XM_PREFIX "" #define XM_POSTFIX "" #define XM_FIELD_PREFIX "." #endif #if HAVE_RUBY /* for Ruby, XM PREFIX needs to be uppercase */ #define XM_PREFIX "R" #define XM_POSTFIX "" #define XM_FIELD_PREFIX "R" #endif #if HAVE_FORTH #define XM_PREFIX "F" #define XM_POSTFIX "" #define XM_FIELD_PREFIX "F" #endif #define XM_field_assert_type(Assertion, Arg, Position, Caller, Correct_Type) \ Xen_check_type(Assertion, Arg, Position, XM_FIELD_PREFIX Caller XM_POSTFIX, Correct_Type) #if HAVE_RUBY #define XM_set_field_assert_type(Assertion, Arg, Position, Caller, Correct_Type) \ Xen_check_type(Assertion, Arg, Position, XM_FIELD_PREFIX S_set Caller XM_POSTFIX, Correct_Type) #endif #if HAVE_SCHEME || HAVE_FORTH #define XM_set_field_assert_type(Assertion, Arg, Position, Caller, Correct_Type) \ Xen_check_type(Assertion, Arg, Position, S_set XM_FIELD_PREFIX Caller XM_POSTFIX, Correct_Type) #endif #define XtIsSubClass XtIsSubclass /* kludge around a bug in some Motif versions */ /* layout of file: * preliminaries * type manglers * arglist handlers * Motif procedures * X procedures * Xt procedures * Xp procedures * Xpm procedures * struct handlers * string constants * integer constants * pointer constants * atom constants */ /* -------------------------------------------------------------------------------- * a sample program (let* ((shell-app (XtVaOpenApplication "Test" 0 () applicationShellWidgetClass (list XmNallowShellResize #t))) (app (cadr shell-app)) (shell (car shell-app)) (black (BlackPixelOfScreen (DefaultScreenOfDisplay (XtDisplay shell))))) (if (not (XtIsApplicationShell shell)) (display "not appshell"?)) (XtSetValues shell (list XmNtitle "Hi!")) (let* ((main-pane (XtVaCreateManagedWidget "main-pane" xmFormWidgetClass shell (list XmNforeground black XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_FORM XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNallowResize #t))) (button (XtCreateManagedWidget "push me" xmPushButtonWidgetClass main-pane () 0))) (XtAddCallback button XmNactivateCallback (lambda (widget context event-info) (display widget) (display (.reason event-info)) (display context)) 123) (XtRealizeWidget shell) (XtAppMainLoop app))) */ /* -------------------------------------------------------------------------------- * differences from C: * * Arg list is lisp list of name/value pairs and the "len" arg associated with it is optional * ref args are usually returned by proc, and not passed in unless init val is needed * array args are passed as lists, returned as lists * pointers to structs are '(type val) where val is opaque except via accessors * that is, all non-simple types are lists in xm where the first element is a symbol describing the type * and the second is usually the C value stored directly as an unsigned long * "Va" args are passed and returned as lists * XtCallback procedure args are passed by value * various "client data" args are optional * XtCallbackLists are passed as lists of procedure/data pairs * where explicit NULL is needed as arg, use #f (or () for list args) * * omitted: * * Xwc*, Xrm*, XIM*, XOM*, XIC*, XOC*, Xcms*, * "resource" handlers and "quark" stuff (XtAppSetTypeConverter etc) * all XTextProperty, XClassHint, XSizeHints support, XSetIconSizes * XConnection internal stuff, XVaCreateNestedList, XSetAuthorization * XtQueryGeometry and XtMakeGeometryRequest, all text16 stuff * XtGetKeySymTable, XtChangeManagedSet (undocumented), XtAppGet|SetExitFlag * XtSetEventDispatcher (undoc), XtSignal stuff (undoc), XtGetErrorDatabaseText * XtBlockHook stuff (undoc), XtRegisterExtensionSelector (undoc) * XmResolvePartOffsets, XmResolveAllPartOffsets * XpSet|GetLocaleHinter, XFreeStringList * XtHooksOfDisplay, XtRegiserDrawable, XtUnregisterDrawable * * added: * * XGCValues -> a blank XGCValues struct (for XCreateGC etc) * XColor pixel red green blue flags pad * XArc XRectangle XPoint XSegment XEvent XWindowChanges XSetWindowAttributes * XTextItem XpmImage XpmColorSymbol * XDrawLinesDirect same as XDrawLines but takes (opaque) ptr to XPoint array * vector->XPoints vect packages point data in vector as (opaque) array of XPoints * freeXPoints to free (opaque) XPoint array created by vector->Xpoints * ? -> #t if arg is of type * -> empty struct of type * * Structs are accessed by the field name and the lisp variable (which contains the struct type) * (.pixel color) for example, or (.foreground gcvalue) */ /* -------------------------------- GC -------------------------------- */ static Xen_object_type_t xm_obj_tag; #if HAVE_RUBY static void *xm_obj_free(Xen obj) { void *vobj; vobj = (void *)obj; free(vobj); return(NULL); } #endif #if HAVE_FORTH static void xm_obj_free(Xen obj) { void *val; val = (void *)Xen_object_ref(obj); free(val); } #endif #if HAVE_SCHEME static void xm_obj_free(void *val) { free(val); } static bool s7_equalp_xm(void *x1, void *x2) { return(x1 == x2); } #endif static Xen make_xm_obj(void *ptr) { return(Xen_make_object(xm_obj_tag, ptr, 0, xm_obj_free)); } static void define_xm_obj(void) { #if HAVE_SCHEME xm_obj_tag = s7_new_type_x(s7, "", NULL, xm_obj_free, s7_equalp_xm, NULL, NULL, NULL, NULL, NULL, NULL, NULL); #else xm_obj_tag = Xen_make_object_type("XmObj", sizeof(void *)); #endif #if HAVE_FORTH fth_set_object_free(xm_obj_tag, xm_obj_free); #endif } /* -------------------------------- type manglers -------------------------------- */ /* most non-simple vars are handled as a list: (type ptr) where ptr is the (un-interpreted) C value * the _OBJ form is used where we need to eventually free the memory * the _PTR form treats NULL as #f and vice-versa */ #define wrap_for_Xen(Name, Value) Xen_list_2(C_string_to_Xen_symbol(Name), Xen_wrap_C_pointer(Value)) #define wrap_for_Xen_obj(Name, Value) Xen_list_3(C_string_to_Xen_symbol(Name), Xen_wrap_C_pointer(Value), make_xm_obj(Value)) #define is_wrapped(Name, Value) (Xen_is_list(Value) && \ (Xen_list_length(Value) >= 2) && \ (Xen_is_symbol(Xen_car(Value))) && \ (strcmp(Name, Xen_symbol_to_C_string(Xen_car(Value))) == 0)) /* Xm_type is used for non-pointers (XID mainly) */ #define Xm_type(Name, XType) \ static Xen C_to_Xen_ ## Name (XType val) {return(Xen_list_2(C_string_to_Xen_symbol(#Name), C_ulong_to_Xen_ulong(val)));} \ static XType Xen_to_C_ ## Name (Xen val) {return((XType)Xen_ulong_to_C_ulong(Xen_cadr(val)));} \ static bool Xen_is_ ## Name (Xen val) {return(is_wrapped(#Name, val));} \ static Xen g_is_ ## Name (Xen val) {return(C_bool_to_Xen_boolean(is_wrapped(#Name, val)));} #define Xm_type_no_p(Name, XType) \ static Xen C_to_Xen_ ## Name (XType val) {return(Xen_list_2(C_string_to_Xen_symbol(#Name), C_ulong_to_Xen_ulong(val)));} \ static XType Xen_to_C_ ## Name (Xen val) {return((XType)Xen_ulong_to_C_ulong(Xen_cadr(val)));} \ static bool Xen_is_ ## Name (Xen val) {return(is_wrapped(#Name, val));} #define Xm_type_int(Name, XType) \ static Xen C_to_Xen_ ## Name (XType val) {return(Xen_list_2(C_string_to_Xen_symbol(#Name), C_int_to_Xen_integer(val)));} \ static XType Xen_to_C_ ## Name (Xen val) {return((XType)Xen_integer_to_C_int(Xen_cadr(val)));} \ static bool Xen_is_ ## Name (Xen val) {return(is_wrapped(#Name, val));} \ static Xen g_is_ ## Name (Xen val) {return(C_bool_to_Xen_boolean(is_wrapped(#Name, val)));} #define Xm_type_ptr(Name, XType) \ static Xen C_to_Xen_ ## Name (XType val) {if (val) return(wrap_for_Xen(#Name, val)); return(Xen_false);} \ static XType Xen_to_C_ ## Name (Xen val) {if (Xen_is_false(val)) return((XType)NULL); return((XType)Xen_unwrap_C_pointer(Xen_cadr(val)));} \ static bool Xen_is_ ## Name (Xen val) {return(is_wrapped(#Name, val));} \ static Xen g_is_ ## Name (Xen val) {return(C_bool_to_Xen_boolean(is_wrapped(#Name, val)));} #define Xm_type_ptr_no_p(Name, XType) \ static Xen C_to_Xen_ ## Name (XType val) {if (val) return(wrap_for_Xen(#Name, val)); return(Xen_false);} \ static XType Xen_to_C_ ## Name (Xen val) {if (Xen_is_false(val)) return((XType)NULL); return((XType)Xen_unwrap_C_pointer(Xen_cadr(val)));} \ static bool Xen_is_ ## Name (Xen val) {return(is_wrapped(#Name, val));} #define Xm_type_ptr_no_p_NO_P(Name, XType) \ static Xen C_to_Xen_ ## Name (XType val) {if (val) return(wrap_for_Xen(#Name, val)); return(Xen_false);} \ static XType Xen_to_C_ ## Name (Xen val) {if (Xen_is_false(val)) return((XType)NULL); return((XType)Xen_unwrap_C_pointer(Xen_cadr(val)));} #define Xm_type_ptr_no_c2x(Name, XType) \ static XType Xen_to_C_ ## Name (Xen val) {if (Xen_is_false(val)) return((XType)NULL); return((XType)Xen_unwrap_C_pointer(Xen_cadr(val)));} \ static bool Xen_is_ ## Name (Xen val) {return(is_wrapped(#Name, val));} \ static Xen g_is_ ## Name (Xen val) {return(C_bool_to_Xen_boolean(is_wrapped(#Name, val)));} #define Xm_type_ptr_no_c2x_no_p(Name, XType) \ static XType Xen_to_C_ ## Name (Xen val) {if (Xen_is_false(val)) return((XType)NULL); return((XType)Xen_unwrap_C_pointer(Xen_cadr(val)));} \ static bool Xen_is_ ## Name (Xen val) {return(is_wrapped(#Name, val));} #define Xm_type_ptr_obj(Name, XType) \ static Xen C_to_Xen_ ## Name (XType val) {if (val) return(wrap_for_Xen_obj(#Name, val)); return(Xen_false);} \ static XType Xen_to_C_ ## Name (Xen val) {if (Xen_is_false(val)) return(NULL); return((XType)Xen_unwrap_C_pointer(Xen_cadr(val)));} \ static bool Xen_is_ ## Name (Xen val) {return(is_wrapped(#Name, val));} \ static Xen g_is_ ## Name (Xen val) {return(C_bool_to_Xen_boolean(is_wrapped(#Name, val)));} #define Xen_to_C_Dimension(Arg) (Dimension)(Xen_integer_to_C_int(Arg)) #define C_to_Xen_Dimension(Arg) (C_int_to_Xen_integer((Dimension)Arg)) #define Xen_is_Dimension(Arg) (Xen_is_integer(Arg)) #define Xen_to_C_Position(Arg) (Position)(Xen_integer_to_C_int(Arg)) #define C_to_Xen_Position(Arg) (C_int_to_Xen_integer((Position)Arg)) #define Xen_is_Position(Arg) (Xen_is_integer(Arg)) #define Xen_to_C_Modifiers(Arg) (Modifiers)(Xen_ulong_to_C_ulong(Arg)) #define C_to_Xen_Modifiers(Arg) (C_ulong_to_Xen_ulong(Arg)) #define Xen_is_Modifiers(Arg) (Xen_is_ulong(Arg)) Xm_type(Cursor, Cursor) Xm_type_ptr(Screen, Screen *) Xm_type_ptr_obj(XRectangle, XRectangle *) Xm_type_ptr_obj(XArc, XArc *) Xm_type_ptr_obj(XPoint, XPoint *) Xm_type_ptr_obj(XSegment, XSegment *) Xm_type_ptr_obj(XColor, XColor *) Xm_type(Atom, Atom) Xm_type(Colormap, Colormap) /* XID */ Xm_type_ptr_no_c2x(Depth, Depth *) Xm_type_ptr(Display, Display *) Xm_type(Font, Font) Xm_type_ptr(GC, GC) Xm_type(KeySym, KeySym) Xm_type(Pixel, Pixel) Xm_type(Pixmap, Pixmap) Xm_type(Region, Region) Xm_type(Time, Time) Xm_type_ptr(Visual, Visual *) Xm_type(Window, Window) /* this is XID = long I think */ Xm_type_ptr(XCharStruct, XCharStruct *) Xm_type_ptr(XFontProp, XFontProp *) Xm_type(XFontSet, XFontSet) Xm_type_ptr(XFontStruct, XFontStruct *) Xm_type_ptr(XGCValues, XGCValues *) Xm_type_ptr_no_c2x(XTextItem, XTextItem *) Xm_type_ptr(XModifierKeymap, XModifierKeymap *) /* opaque in this implementation */ Xm_type_ptr(XImage, XImage *) static XAnyEvent *Xen_to_C_XAnyEvent(Xen val) {return((XAnyEvent *)Xen_unwrap_C_pointer(Xen_cadr(val)));} Xm_type_ptr_no_c2x(XButtonEvent, XButtonEvent *) Xm_type_ptr_no_c2x(XCirculateEvent, XCirculateEvent *) Xm_type_ptr_no_c2x(XCirculateRequestEvent, XCirculateRequestEvent *) Xm_type_ptr_no_c2x(XClientMessageEvent, XClientMessageEvent *) Xm_type_ptr_no_c2x(XColormapEvent, XColormapEvent *) Xm_type_ptr_no_c2x(XConfigureEvent, XConfigureEvent *) Xm_type_ptr_no_c2x(XConfigureRequestEvent, XConfigureRequestEvent *) Xm_type_ptr_no_c2x(XCreateWindowEvent, XCreateWindowEvent *) Xm_type_ptr_no_c2x(XCrossingEvent, XCrossingEvent *) Xm_type_ptr_no_c2x(XDestroyWindowEvent, XDestroyWindowEvent *) Xm_type_ptr(XErrorEvent, XErrorEvent *) Xm_type_ptr_no_c2x(XExposeEvent, XExposeEvent *) Xm_type_ptr_no_c2x(XFocusChangeEvent, XFocusChangeEvent *) Xm_type_ptr_no_c2x(XGraphicsExposeEvent, XGraphicsExposeEvent *) Xm_type_ptr_no_c2x(XGravityEvent, XGravityEvent *) Xm_type_ptr_no_c2x(XKeyEvent, XKeyEvent *) Xm_type_ptr_no_c2x(XKeymapEvent, XKeymapEvent *) Xm_type_ptr_no_c2x(XMapEvent, XMapEvent *) Xm_type_ptr_no_c2x(XMapRequestEvent, XMapRequestEvent *) Xm_type_ptr_no_c2x(XMappingEvent, XMappingEvent *) Xm_type_ptr_no_c2x(XMotionEvent, XMotionEvent *) Xm_type_ptr_no_c2x(XNoExposeEvent, XNoExposeEvent *) Xm_type_ptr_no_c2x(XPropertyEvent, XPropertyEvent *) Xm_type_ptr_no_c2x(XReparentEvent, XReparentEvent *) Xm_type_ptr_no_c2x(XResizeRequestEvent, XResizeRequestEvent *) Xm_type_ptr_no_c2x(XSelectionClearEvent, XSelectionClearEvent *) Xm_type_ptr_no_c2x(XSelectionEvent, XSelectionEvent *) Xm_type_ptr(XSelectionRequestEvent, XSelectionRequestEvent *) Xm_type_ptr_no_c2x(XUnmapEvent, XUnmapEvent *) Xm_type_ptr_no_c2x(XVisibilityEvent, XVisibilityEvent *) Xm_type_ptr_obj(XSetWindowAttributes, XSetWindowAttributes *) Xm_type_ptr(XVisualInfo, XVisualInfo *) Xm_type_ptr(XWMHints, XWMHints *) Xm_type_ptr_no_c2x_no_p(XSizeHints, XSizeHints *) Xm_type_ptr(XWindowAttributes, XWindowAttributes *) Xm_type_ptr_obj(XWindowChanges, XWindowChanges *) Xm_type_ptr(XStandardColormap, XStandardColormap *) Xm_type_int(KeyCode, KeyCode) Xm_type_int(XContext, XContext) Xm_type_ptr(XIconSize, XIconSize *) Xm_type_ptr(Widget, Widget) Xm_type(WidgetClass, WidgetClass) Xm_type(XtAppContext, XtAppContext) Xm_type(XtRequestId, XtRequestId) Xm_type(XtWorkProcId, XtWorkProcId) Xm_type(XtInputId, XtInputId) Xm_type(XtIntervalId, XtIntervalId) Xm_type_no_p(XtActionHookId, XtActionHookId) Xm_type_no_p(XtTranslations, XtTranslations) /* opaque */ Xm_type_ptr(XmString, XmString) Xm_type_ptr_no_p_NO_P(XmAnyCallbackStruct, XmAnyCallbackStruct *) Xm_type_ptr_no_p(XmArrowButtonCallbackStruct, XmArrowButtonCallbackStruct *) Xm_type_ptr_no_p(XmCommandCallbackStruct, XmCommandCallbackStruct *) Xm_type_ptr_no_p(XmDragDropFinishCallbackStruct, XmDragDropFinishCallbackStruct *) Xm_type_ptr_no_p(XmDragMotionCallbackStruct, XmDragMotionCallbackStruct *) Xm_type_ptr_no_p(XmDragProcCallbackStruct, XmDragProcCallbackStruct *) Xm_type_ptr_no_p(XmDrawingAreaCallbackStruct, XmDrawingAreaCallbackStruct *) Xm_type_ptr_no_p(XmDrawnButtonCallbackStruct, XmDrawnButtonCallbackStruct *) Xm_type_ptr_no_p(XmDropFinishCallbackStruct, XmDropFinishCallbackStruct *) Xm_type_ptr_no_p(XmDropProcCallbackStruct, XmDropProcCallbackStruct *) Xm_type_ptr_no_p(XmDropSiteEnterCallbackStruct, XmDropSiteEnterCallbackStruct *) Xm_type_ptr_no_p(XmDropSiteLeaveCallbackStruct, XmDropSiteLeaveCallbackStruct *) Xm_type_ptr_no_p(XmDropStartCallbackStruct, XmDropStartCallbackStruct *) Xm_type_ptr_no_p(XmFileSelectionBoxCallbackStruct, XmFileSelectionBoxCallbackStruct *) Xm_type_ptr_no_p(XmListCallbackStruct, XmListCallbackStruct *) Xm_type(XmTab, XmTab) /* opaque */ Xm_type_ptr_no_p(XmDragStartCallbackStruct, XmDragStartCallbackStruct *) Xm_type_ptr_no_p(XmDisplayCallbackStruct, XmDisplayCallbackStruct *) Xm_type_ptr_no_p(XmDestinationCallbackStruct, XmDestinationCallbackStruct *) Xm_type_ptr_no_p(XmConvertCallbackStruct, XmConvertCallbackStruct *) Xm_type_ptr_no_p(XmComboBoxCallbackStruct, XmComboBoxCallbackStruct *) Xm_type_ptr_no_p(XmContainerOutlineCallbackStruct, XmContainerOutlineCallbackStruct *) Xm_type_ptr_no_p(XmContainerSelectCallbackStruct, XmContainerSelectCallbackStruct *) Xm_type_ptr_no_p(XmNotebookCallbackStruct, XmNotebookCallbackStruct *) Xm_type_ptr_no_p(XmNotebookPageInfo, XmNotebookPageInfo *) Xm_type_ptr(XmRenderTable, XmRenderTable) Xm_type_ptr(XmRendition, XmRendition) Xm_type_ptr_no_p(XmSpinBoxCallbackStruct, XmSpinBoxCallbackStruct *) Xm_type_ptr_no_p(XmTraverseObscuredCallbackStruct, XmTraverseObscuredCallbackStruct *) Xm_type_ptr_no_p(XmTopLevelLeaveCallbackStruct, XmTopLevelLeaveCallbackStruct *) Xm_type_ptr_no_p(XmTopLevelEnterCallbackStruct, XmTopLevelEnterCallbackStruct *) Xm_type_ptr_no_p(XmPopupHandlerCallbackStruct, XmPopupHandlerCallbackStruct *) Xm_type_ptr_no_p(XmSelectionCallbackStruct, XmSelectionCallbackStruct *) Xm_type_ptr_no_c2x_no_p(XmTransferDoneCallbackStruct, XmTransferDoneCallbackStruct *) Xm_type_ptr(XmTabList, XmTabList) /* opaque */ Xm_type(XmParseMapping, XmParseMapping) Xm_type_ptr_no_p(XmOperationChangedCallbackStruct, XmOperationChangedCallbackStruct *) Xm_type_ptr_no_p(XmPushButtonCallbackStruct, XmPushButtonCallbackStruct *) Xm_type_ptr_no_p(XmRowColumnCallbackStruct, XmRowColumnCallbackStruct *) Xm_type_ptr_no_p(XmScaleCallbackStruct, XmScaleCallbackStruct *) Xm_type_ptr_no_p(XmScrollBarCallbackStruct, XmScrollBarCallbackStruct *) Xm_type_ptr_no_p(XmSelectionBoxCallbackStruct, XmSelectionBoxCallbackStruct *) Xm_type_ptr_no_p(XmTextVerifyCallbackStruct, XmTextVerifyCallbackStruct *) Xm_type_ptr_no_c2x_no_p(XmTextBlock, XmTextBlock) Xm_type_ptr_no_p(XmToggleButtonCallbackStruct, XmToggleButtonCallbackStruct *) #define Xen_to_C_XmFontList(Arg) Xen_to_C_XmRenderTable(Arg) Xm_type(XmTextSource, XmTextSource) Xm_type(XmStringContext, XmStringContext) static int Xen_is_XmFontList_or_XmRenderTable(Xen arg) { return(Xen_is_XmRenderTable(arg)); } static Xen type_to_event_symbol(int utype) { const char *type; type = "XErrorEvent"; /* -1 for an error event? */ switch (utype) { case 0: type = "XAnyEvent"; break; case KeyPress: case KeyRelease: type = "XKeyEvent"; break; case ButtonPress: case ButtonRelease: type = "XButtonEvent"; break; case MotionNotify: type = "XMotionEvent"; break; case EnterNotify: case LeaveNotify: type = "XCrossingEvent"; break; case FocusIn: case FocusOut: type = "XFocusChangeEvent"; break; case KeymapNotify: type = "XKeymapEvent"; break; case Expose: type = "XExposeEvent"; break; case GraphicsExpose: type = "XGraphicsExposeEvent"; break; case NoExpose: type = "XNoExposeEvent"; break; case VisibilityNotify: type = "XVisibilityEvent"; break; case CreateNotify: type = "XCreateWindowEvent"; break; case DestroyNotify: type = "XDestroyWindowEvent"; break; case UnmapNotify: type = "XUnmapEvent"; break; case MapNotify: type = "XMapEvent"; break; case MapRequest: type = "XMapRequestEvent"; break; case ReparentNotify: type = "XReparentEvent"; break; case ConfigureNotify: type = "XConfigureEvent"; break; case ConfigureRequest: type = "XConfigureRequestEvent"; break; case GravityNotify: type = "XGravityEvent"; break; case ResizeRequest: type = "XResizeRequestEvent"; break; case CirculateNotify: type = "XCirculateEvent"; break; case CirculateRequest: type = "XCirculateRequestEvent"; break; case PropertyNotify: type = "XPropertyEvent"; break; case SelectionClear: type = "XSelectionClearEvent"; break; case SelectionRequest: type = "XSelectionRequestEvent"; break; case SelectionNotify: type = "XSelectionEvent"; break; case ColormapNotify: type = "XColormapEvent"; break; case ClientMessage: type = "XClientMessageEvent"; break; case MappingNotify: type = "XMappingEvent"; break; } return(C_string_to_Xen_symbol(type)); } static Xen C_to_Xen_XEvent_1(XEvent *e, int need_free) { if (e == NULL) return(Xen_false); /* synthetic callback may have no event */ if (need_free) return(Xen_list_4(type_to_event_symbol(e->type), Xen_wrap_C_pointer(e), make_xm_obj(e), C_string_to_Xen_symbol("XEvent"))); return(Xen_list_4(type_to_event_symbol(e->type), Xen_wrap_C_pointer(e), Xen_false, C_string_to_Xen_symbol("XEvent"))); } #define C_to_Xen_XEvent(e) C_to_Xen_XEvent_1(e, false) #define C_to_Xen_XEvent_OBJ(e) C_to_Xen_XEvent_1(e, true) #define Xen_to_C_XEvent(Arg) (XEvent *)Xen_unwrap_C_pointer(Xen_cadr(Arg)) #define Xen_is_XEvent(Value) (Xen_is_list(Value) &&\ (Xen_list_length(Value) == 4) &&\ (Xen_is_symbol(Xen_cadddr(Value))) &&\ (strcmp("XEvent", Xen_symbol_to_C_string(Xen_cadddr(Value))) == 0)) static Xen g_is_XEvent(Xen val) { return(C_bool_to_Xen_boolean(Xen_is_XEvent(val))); } static Xen gxm_XEvent(Xen type) { XEvent *e; Xen_check_type(Xen_is_integer_or_unbound(type), type, 1, "XEvent", "an X event type (integer)"); e = (XEvent *)calloc(1, sizeof(XEvent)); if (Xen_is_integer(type)) e->type = Xen_integer_to_C_int(type); return(Xen_list_4(type_to_event_symbol(e->type), Xen_wrap_C_pointer(e), make_xm_obj(e), C_string_to_Xen_symbol("XEvent"))); } static Xen gxm_XGCValues(void) { XGCValues *e; e = (XGCValues *)calloc(1, sizeof(XGCValues)); return(wrap_for_Xen_obj("XGCValues", e)); } #define XM_Make(Name) \ static Xen gxm_ ## Name (void) {Name *e; e = (Name *)calloc(1, sizeof(Name)); return(wrap_for_Xen_obj(#Name, e));} \ Xen_wrap_no_args(gxm_ ## Name ## _w, gxm_ ## Name) #define XM_Declare(Name) \ Xen_define_safe_procedure(XM_PREFIX #Name XM_POSTFIX, gxm_ ## Name ## _w, 0, 0, 0, "Make an " #Name " struct") XM_Make(XmAnyCallbackStruct) XM_Make(XmArrowButtonCallbackStruct) XM_Make(XmCommandCallbackStruct) XM_Make(XmDragDropFinishCallbackStruct) XM_Make(XmDragMotionCallbackStruct) XM_Make(XmDragProcCallbackStruct) XM_Make(XmDrawingAreaCallbackStruct) XM_Make(XmDrawnButtonCallbackStruct) XM_Make(XmDropFinishCallbackStruct) XM_Make(XmDropProcCallbackStruct) XM_Make(XmDropSiteEnterCallbackStruct) XM_Make(XmDropSiteLeaveCallbackStruct) XM_Make(XmDropStartCallbackStruct) XM_Make(XmFileSelectionBoxCallbackStruct) XM_Make(XmListCallbackStruct) XM_Make(XmOperationChangedCallbackStruct) XM_Make(XmPushButtonCallbackStruct) XM_Make(XmRowColumnCallbackStruct) XM_Make(XmScaleCallbackStruct) XM_Make(XmScrollBarCallbackStruct) XM_Make(XmSelectionBoxCallbackStruct) XM_Make(XmTextVerifyCallbackStruct) XM_Make(XmToggleButtonCallbackStruct) XM_Make(XmDestinationCallbackStruct) XM_Make(XmConvertCallbackStruct) XM_Make(XmComboBoxCallbackStruct) XM_Make(XmContainerOutlineCallbackStruct) XM_Make(XmContainerSelectCallbackStruct) XM_Make(XmNotebookCallbackStruct) XM_Make(XmSpinBoxCallbackStruct) XM_Make(XmTraverseObscuredCallbackStruct) XM_Make(XmTopLevelLeaveCallbackStruct) XM_Make(XmTopLevelEnterCallbackStruct) XM_Make(XmPopupHandlerCallbackStruct) XM_Make(XmSelectionCallbackStruct) XM_Make(XmTransferDoneCallbackStruct) XM_Make(XmDisplayCallbackStruct) XM_Make(XmDragStartCallbackStruct) static Xen gxm_XmTextBlock(void) { XmTextBlockRec *e; e = (XmTextBlockRec *)calloc(1, sizeof(XmTextBlockRec)); return(wrap_for_Xen_obj("XmTextBlock", e)); } Xen_wrap_no_args(gxm_XmTextBlock_w, gxm_XmTextBlock) static void define_makes(void) { XM_Declare(XmAnyCallbackStruct); XM_Declare(XmArrowButtonCallbackStruct); XM_Declare(XmCommandCallbackStruct); XM_Declare(XmDragDropFinishCallbackStruct); XM_Declare(XmDragMotionCallbackStruct); XM_Declare(XmDragProcCallbackStruct); XM_Declare(XmDrawingAreaCallbackStruct); XM_Declare(XmDrawnButtonCallbackStruct); XM_Declare(XmDropFinishCallbackStruct); XM_Declare(XmDropProcCallbackStruct); XM_Declare(XmDropSiteEnterCallbackStruct); XM_Declare(XmDropSiteLeaveCallbackStruct); XM_Declare(XmDropStartCallbackStruct); XM_Declare(XmFileSelectionBoxCallbackStruct); XM_Declare(XmListCallbackStruct); XM_Declare(XmOperationChangedCallbackStruct); XM_Declare(XmPushButtonCallbackStruct); XM_Declare(XmRowColumnCallbackStruct); XM_Declare(XmScaleCallbackStruct); XM_Declare(XmScrollBarCallbackStruct); XM_Declare(XmSelectionBoxCallbackStruct); XM_Declare(XmTextVerifyCallbackStruct); XM_Declare(XmToggleButtonCallbackStruct); Xen_define_safe_procedure(XM_PREFIX "XmTextBlock" XM_POSTFIX, gxm_XmTextBlock_w, 0, 0, 0, "Make an XmTextBlock struct"); XM_Declare(XmDestinationCallbackStruct); XM_Declare(XmConvertCallbackStruct); XM_Declare(XmComboBoxCallbackStruct); XM_Declare(XmContainerOutlineCallbackStruct); XM_Declare(XmContainerSelectCallbackStruct); XM_Declare(XmNotebookCallbackStruct); XM_Declare(XmSpinBoxCallbackStruct); XM_Declare(XmTraverseObscuredCallbackStruct); XM_Declare(XmTopLevelLeaveCallbackStruct); XM_Declare(XmTopLevelEnterCallbackStruct); XM_Declare(XmPopupHandlerCallbackStruct); XM_Declare(XmSelectionCallbackStruct); XM_Declare(XmTransferDoneCallbackStruct); XM_Declare(XmDisplayCallbackStruct); XM_Declare(XmDragStartCallbackStruct); } static int its_a_callbackstruct(const char *name) { if (name) { int len; len = strlen(name); if (len > 16) { char *end_name; end_name = (char *)(name + len - 14); return(strcmp(end_name, "CallbackStruct") == 0); } } return(0); } #define Xen_is_AnyCallbackStruct(Value) (Xen_is_list(Value) && \ (Xen_list_length(Value) >= 2) && \ (Xen_is_symbol(Xen_car(Value))) && \ (its_a_callbackstruct(Xen_symbol_to_C_string(Xen_car(Value))))) static int xm_protect(Xen obj); static void xm_unprotect_at(int ind); /* in XtGetValues we need to return tagged-types (etc) for arbitrarily named resources, * and in XtSetValues we need to do type checks, so resources are hashed by * name and type: */ typedef enum {XM_INT, XM_ULONG, XM_UCHAR, XM_FLOAT, XM_STRING, XM_XMSTRING, XM_STRING_TABLE, XM_INT_TABLE, XM_RENDER_TABLE, XM_TAB_LIST, XM_WIDGET, XM_WIDGET_LIST, XM_BOOLEAN, XM_CALLBACK, XM_PIXEL, XM_PIXMAP, XM_XFONTSTRUCT, XM_DIMENSION, XM_ATOM, XM_ATOM_LIST, XM_STRING_LIST, XM_CHARSET_TABLE, XM_TEXT_SOURCE, XM_COLORMAP, XM_KEYSYM, XM_KEYSYM_TABLE, XM_SCREEN, XM_WINDOW, XM_VISUAL, XM_RECTANGLE_LIST, XM_WIDGET_CLASS, XM_STRING_OR_INT, XM_TRANSFER_CALLBACK, XM_CONVERT_CALLBACK, XM_SEARCH_CALLBACK, XM_ORDER_CALLBACK, XM_QUALIFY_CALLBACK, XM_ALLOC_COLOR_CALLBACK, XM_POPUP_CALLBACK, XM_SCREEN_COLOR_CALLBACK, XM_DROP_CALLBACK, XM_TRANSFER_ENTRY_LIST, XM_DRAG_CALLBACK, XM_STRING_OR_XMSTRING, XM_PARSE_CALLBACK, XM_BOOLEAN_OR_INT, XM_POSITION, XM_SHORT, XM_CURSOR, XM_XTPOINTER, XM_NOT_A_RESOURCE } xm_resource_t; static xm_resource_t resource_type(const char *resource); static Xen C_to_Xen_Widgets(Widget *array, int len) { Xen lst = Xen_empty_list; if (array) { int i, loc; loc = xm_protect(lst); for (i = len - 1; i >= 0; i--) lst = Xen_cons(C_to_Xen_Widget(array[i]), lst); xm_unprotect_at(loc); } return(lst); } static Xen C_to_Xen_XmStringTable(XmStringTable array, int len) { Xen lst = Xen_empty_list; if (array) { int i, loc; loc = xm_protect(lst); for (i = len - 1; i >= 0; i--) lst = Xen_cons(C_to_Xen_XmString(array[i]), lst); xm_unprotect_at(loc); } return(lst); } static Widget *Xen_to_C_Widgets(Xen lst_1, int n) { Widget *ws; int i; Xen lst; lst = Xen_copy_arg(lst_1); ws = (Widget *)calloc(n, sizeof(Widget)); for (i = 0; (i < n) && (!Xen_is_null(lst)); i++, lst = Xen_cdr(lst)) if (Xen_is_Widget(Xen_car(lst))) ws[i] = Xen_to_C_Widget(Xen_car(lst)); else { free(ws); ws = NULL; Xen_check_type(0, Xen_car(lst), i, __func__, "a Widget"); break; } return(ws); } static XmString *Xen_to_C_XmStrings(Xen v_1, int len) { XmString *str; int i; Xen v; v = Xen_copy_arg(v_1); str = (XmString *)calloc(len, sizeof(XmString)); for (i = 0; (i < len) && (!Xen_is_null(v)); i++, v = Xen_cdr(v)) if (Xen_is_XmString(Xen_car(v))) str[i] = (XmString)Xen_to_C_XmString(Xen_car(v)); else { free(str); str = NULL; Xen_check_type(0, Xen_car(v), i, __func__, "an XmString"); break; } return(str); } static XmDropTransferEntryRec *Xen_to_C_XmDropTransferEntryRecs(Xen v_1, int len) { XmDropTransferEntryRec *ps; int i; Xen v; v = Xen_copy_arg(v_1); ps = (XmDropTransferEntryRec *)calloc(len, sizeof(XmDropTransferEntryRec)); for (i = 0; (i < len) && (!Xen_is_null(v)); i++, v = Xen_cdr(v)) { if (Xen_is_Atom(Xen_car(v))) ps[i].target = Xen_to_C_Atom(Xen_car(v)); else { if (Xen_is_list(Xen_car(v))) { if (Xen_is_Atom(Xen_car(Xen_car(v)))) ps[i].target = Xen_to_C_Atom(Xen_car(Xen_car(v))); else Xen_check_type(0, Xen_car(v), i, __func__, "an Atom"); ps[i].client_data = (XtPointer)Xen_cadr(Xen_car(v)); } } } return(ps); } static XmStringTable Xen_to_C_XmStringTable(Xen v_1, int len) { Xen v; XmStringTable str; int i; v = Xen_copy_arg(v_1); str = (XmStringTable)calloc(len + 1, sizeof(XmString)); for (i = 0; (i < len) && (!Xen_is_null(v)); i++, v = Xen_cdr(v)) if (Xen_is_XmString(Xen_car(v))) str[i] = Xen_to_C_XmString(Xen_car(v)); else { free(str); str = NULL; Xen_check_type(0, Xen_car(v), i, __func__, "an XmString"); break; } return(str); } static Xen C_to_Xen_Ints(int *array, int len) { Xen lst = Xen_empty_list; if (array) { int i, loc; loc = xm_protect(lst); for (i = len - 1; i >= 0; i--) lst = Xen_cons(C_int_to_Xen_integer(array[i]), lst); xm_unprotect_at(loc); } return(lst); } #if HAVE_SCHEME static Xen c_to_xen_ints(Xen array, Xen len) { #define H_to_ints "->ints translates a Motif int array (from a .value reference for example) into a scheme list of ints" Xen_check_type(Xen_is_wrapped_c_pointer(array), array, 1, "->ints", "int*"); return(C_to_Xen_Ints((int *)Xen_unwrap_C_pointer(array), Xen_integer_to_C_int(len))); } #endif static Xen C_to_Xen_Atoms(Atom *array, int len) { Xen lst = Xen_empty_list; if (array) { int i, loc; loc = xm_protect(lst); for (i = len - 1; i >= 0; i--) lst = Xen_cons(C_to_Xen_Atom(array[i]), lst); xm_unprotect_at(loc); } return(lst); } #if HAVE_SCHEME static Xen c_to_xen_atoms(Xen array, Xen len) { #define H_to_Atoms "->Atoms translates a Motif Atoms array (from a .value reference for example) into a scheme list of Atoms" Xen_check_type(Xen_is_wrapped_c_pointer(array), array, 1, "->Atoms", "Atom*"); return(C_to_Xen_Atoms((Atom *)Xen_unwrap_C_pointer(array), Xen_integer_to_C_int(len))); } #endif static Xen C_to_Xen_Strings(char **array, int len) { Xen lst = Xen_empty_list; if (array) { int i, loc; loc = xm_protect(lst); for (i = len - 1; i >= 0; i--) lst = Xen_cons(C_string_to_Xen_string(array[i]), lst); xm_unprotect_at(loc); } return(lst); } #if HAVE_SCHEME static Xen c_to_xen_strings(Xen array, Xen len) { #define H_to_strings "->strings translates a Motif string array (from a .value reference for example) into a scheme list of strings" Xen_check_type(Xen_is_wrapped_c_pointer(array), array, 1, "->strings", "char**"); return(C_to_Xen_Strings((char **)Xen_unwrap_C_pointer(array), Xen_integer_to_C_int(len))); } #endif static Xen copy_xrectangle(XRectangle *old_r) { XRectangle *r; r = (XRectangle *)calloc(1, sizeof(XRectangle)); r->x = old_r->x; r->y = old_r->y; r->width = old_r->width; r->height = old_r->height; return(C_to_Xen_XRectangle(r)); } static Xen C_to_Xen_XRectangles(XRectangle *array, int len) { Xen lst = Xen_empty_list; if (array) { int i, loc; loc = xm_protect(lst); for (i = len - 1; i >= 0; i--) lst = Xen_cons(copy_xrectangle(&(array[i])), lst); xm_unprotect_at(loc); } return(lst); } #if HAVE_SCHEME static Xen c_to_xen_xrectangles(Xen array, Xen len) { #define H_to_XRectangles "->XRectangles translates a Motif rectangle array (from a .value reference for example) into a scheme list of rectangles" Xen_check_type(Xen_is_wrapped_c_pointer(array), array, 1, "->XRectangles", "Motif rectangle array"); return(C_to_Xen_XRectangles((XRectangle *)Xen_unwrap_C_pointer(array), Xen_integer_to_C_int(len))); } #endif static Xen C_to_Xen_KeySyms(KeySym *array, int len) { Xen lst = Xen_empty_list; if (array) { int i, loc; loc = xm_protect(lst); for (i = len - 1; i >= 0; i--) lst = Xen_cons(C_to_Xen_KeySym(array[i]), lst); xm_unprotect_at(loc); } return(lst); } static Window *Xen_to_C_Windows(Xen lst_1, int n) { Window *ws; int i; Xen lst; if (n == 0) return(NULL); lst = Xen_copy_arg(lst_1); ws = (Window *)calloc(n, sizeof(Window)); for (i = 0; (i < n) && (!Xen_is_null(lst)); i++, lst = Xen_cdr(lst)) if (Xen_is_Window(Xen_car(lst))) ws[i] = Xen_to_C_Window(Xen_car(lst)); else { free(ws); ws = NULL; Xen_check_type(0, Xen_car(lst), i, __func__, "a Window"); break; } return(ws); } static XmRendition *Xen_to_C_XmRenditions(Xen lst_1, int n) { Xen lst; XmRendition *ws; int i; if (n == 0) return(NULL); lst = Xen_copy_arg(lst_1); ws = (XmRendition *)calloc(n, sizeof(XmRendition)); for (i = 0; (i < n) && (!Xen_is_null(lst)); i++, lst = Xen_cdr(lst)) if (Xen_is_XmRendition(Xen_car(lst))) ws[i] = Xen_to_C_XmRendition(Xen_car(lst)); else { free(ws); ws = NULL; Xen_check_type(0, Xen_car(lst), i, __func__, "an XmRendition"); break; } return(ws); } static XmTab *Xen_to_C_XmTabs(Xen v_1, int len) { Xen v; XmTab *str; int i; if (len == 0) return(NULL); v = Xen_copy_arg(v_1); str = (XmTab *)calloc(len, sizeof(XmTab)); for (i = 0; (i < len) && (!Xen_is_null(v)); i++, v = Xen_cdr(v)) if (Xen_is_XmTab(Xen_car(v))) str[i] = (XmTab)Xen_to_C_XmTab(Xen_car(v)); else { free(str); str = NULL; Xen_check_type(0, Xen_car(v), i, __func__, "an XmTab"); break; } return(str); } static Atom *Xen_to_C_Atoms(Xen v_1, int len) { Xen v; Atom *str; int i; if (len == 0) return(NULL); v = Xen_copy_arg(v_1); str = (Atom *)calloc(len, sizeof(Atom)); for (i = 0; (i < len) && (!Xen_is_null(v)); i++, v = Xen_cdr(v)) if (Xen_is_Atom(Xen_car(v))) str[i] = (Atom)Xen_to_C_Atom(Xen_car(v)); else { free(str); str = NULL; Xen_check_type(0, Xen_car(v), i, __func__, "an Atom"); break; } return(str); } static Pixel *Xen_to_C_Pixels(Xen v_1, int len) { Xen v; Pixel *str; int i; if (len == 0) return(NULL); v = Xen_copy_arg(v_1); str = (Pixel *)calloc(len, sizeof(Pixel)); for (i = 0; (i < len) && (!Xen_is_null(v)); i++, v = Xen_cdr(v)) if (Xen_is_Pixel(Xen_car(v))) str[i] = (Pixel)Xen_to_C_Pixel(Xen_car(v)); else { free(str); str = NULL; Xen_check_type(0, Xen_car(v), i, __func__, "a Pixel"); break; } return(str); } static KeySym *Xen_to_C_KeySyms(Xen v_1, int len) { Xen v; KeySym *str; int i; if (len == 0) return(NULL); v = Xen_copy_arg(v_1); str = (KeySym *)calloc(len, sizeof(KeySym)); for (i = 0; (i < len) && (!Xen_is_null(v)); i++, v = Xen_cdr(v)) if (Xen_is_KeySym(Xen_car(v))) str[i] = (KeySym)Xen_to_C_KeySym(Xen_car(v)); else { free(str); str = NULL; Xen_check_type(0, Xen_car(v), i, __func__, "a KeySym"); break; } return(str); } static char **Xen_to_C_Strings(Xen v_1, int len) { Xen v; char **str; int i; if (len == 0) return(NULL); v = Xen_copy_arg(v_1); str = (char **)calloc(len, sizeof(char *)); for (i = 0; (i < len) && (!Xen_is_null(v)); i++, v = Xen_cdr(v)) if (Xen_is_string(Xen_car(v))) str[i] = (char *)Xen_string_to_C_string(Xen_car(v)); /* should this be protected? */ else { free(str); str = NULL; Xen_check_type(0, Xen_car(v), i, __func__, "a char*"); break; } return(str); } static int *Xen_to_C_Ints(Xen v_1, int len) { Xen v; int *ps; int i; if (len == 0) return(NULL); v = Xen_copy_arg(v_1); ps = (int *)calloc(len, sizeof(int)); for (i = 0; (i < len) && (!Xen_is_null(v)); i++, v = Xen_cdr(v)) if (Xen_is_integer(Xen_car(v))) ps[i] = Xen_integer_to_C_int(Xen_car(v)); else { free(ps); ps = NULL; Xen_check_type(0, Xen_car(v), i, __func__, "an int"); break; } return(ps); } static Cardinal *Xen_to_C_Cardinals(Xen v_1, int len) { Xen v; Cardinal *ps; int i; if (len == 0) return(NULL); v = Xen_copy_arg(v_1); ps = (Cardinal *)calloc(len, sizeof(int)); for (i = 0; (i < len) && (!Xen_is_null(v)); i++, v = Xen_cdr(v)) if (Xen_is_integer(Xen_car(v))) ps[i] = (Cardinal)Xen_integer_to_C_int(Xen_car(v)); else { free(ps); ps = NULL; Xen_check_type(0, Xen_car(v), i, __func__, "a Cardinal"); break; } return(ps); } static XRectangle *Xen_to_C_XRectangles(Xen v_1, int len) { Xen v; XRectangle *str, *dat; int i; if (len == 0) return(NULL); v = Xen_copy_arg(v_1); str = (XRectangle *)calloc(len, sizeof(XRectangle)); for (i = 0; (i < len) && (!Xen_is_null(v)); i++, v = Xen_cdr(v)) { if (Xen_is_XRectangle(Xen_car(v))) dat = (XRectangle *)Xen_to_C_XRectangle(Xen_car(v)); else { free(str); str = NULL; Xen_check_type(0, Xen_car(v), i, __func__, "an XRectangle"); break; } str[i].x = dat->x; str[i].y = dat->y; str[i].width = dat->width; str[i].height = dat->height; } return(str); } /* -------- arglists -------- */ static Xen wrap_callback_struct(int type, XtPointer info); static int map_over_protected_elements(bool (*func)(Xen val, int loc, unsigned long fid), unsigned long id); static Xen xm_protected_element(int loc); static int callback_struct_type(Widget w, const char *name); static void xm_unprotect(Xen obj); enum {CALLBACK_TYPE, CALLBACK_FUNC, CALLBACK_DATA, CALLBACK_STRUCT_TYPE, CALLBACK_GC_LOC}; #define C_to_Xen_XM_XtCallback(Code, Context) \ Xen_list_5(C_string_to_Xen_symbol("XtCallback"), Code, Context, Xen_integer_zero, Xen_integer_zero) static void gxm_XtCallbackProc(Widget w, XtPointer context, XtPointer info) { Xen descr = (Xen)context; Xen_call_with_3_args(Xen_list_ref(descr, CALLBACK_FUNC), /* descr: (list "XtCallback" func user-data struct-type gc-loc) */ C_to_Xen_Widget(w), Xen_list_ref(descr, CALLBACK_DATA), wrap_callback_struct(Xen_integer_to_C_int(Xen_list_ref(descr, CALLBACK_STRUCT_TYPE)), info), __func__); } #define C_to_Xen_XM_Drop_Callback(Code) \ Xen_list_5(C_string_to_Xen_symbol("Drop_Callback"), Code, Xen_false, Xen_integer_zero, Xen_integer_zero) #define XM_is_Drop_Callback(Arg) is_wrapped("Drop_Callback", Arg) static bool find_dropproc(Xen val, int loc, unsigned long w) { return((XM_is_Drop_Callback(val)) && (((Xen_is_false((Xen)w)) && (Xen_is_false(Xen_list_ref(val, CALLBACK_DATA)))) || ((Xen_is_Widget(Xen_list_ref(val, CALLBACK_DATA))) && (Xen_ulong_to_C_ulong(Xen_cadr(Xen_list_ref(val, CALLBACK_DATA))) == w)))); } static void gxm_Drop_Callback(Widget w, XtPointer context, XtPointer info) { int i; XmDropProcCallbackStruct *cb = (XmDropProcCallbackStruct *)info; i = map_over_protected_elements(find_dropproc, (unsigned long)w); if (i >= 0) { Xen code; code = Xen_list_ref(xm_protected_element(i), CALLBACK_FUNC); if (Xen_is_procedure(code)) Xen_call_with_3_args(code, C_to_Xen_Widget(w), Xen_false, C_to_Xen_XmDropProcCallbackStruct(cb), __func__); } cb->dropSiteStatus = XmINVALID_DROP_SITE; /* try to exit cleanly from on-going drop */ } #define C_to_Xen_XM_Drag_Callback(Code) \ Xen_list_5(C_string_to_Xen_symbol("Drag_Callback"), Code, Xen_false, Xen_integer_zero, Xen_integer_zero) #define XM_is_Drag_Callback(Arg) is_wrapped("Drag_Callback", Arg) static bool find_dragproc(Xen val, int loc, unsigned long w) { return((XM_is_Drag_Callback(val)) && (((Xen_is_false((Xen)w)) && (Xen_is_false(Xen_list_ref(val, CALLBACK_DATA)))) || ((Xen_is_Widget(Xen_list_ref(val, CALLBACK_DATA))) && (Xen_ulong_to_C_ulong(Xen_cadr(Xen_list_ref(val, CALLBACK_DATA))) == w)))); } static void gxm_Drag_Callback(Widget w, XtPointer context, XtPointer info) { int i; XmDragProcCallbackStruct *cb = (XmDragProcCallbackStruct *)info; i = map_over_protected_elements(find_dragproc, (unsigned long)w); if (i >= 0) { Xen code; code = Xen_list_ref(xm_protected_element(i), CALLBACK_FUNC); if (Xen_is_procedure(code)) Xen_call_with_3_args(code, C_to_Xen_Widget(w), Xen_false, C_to_Xen_XmDragProcCallbackStruct(cb), __func__); } } #define C_to_Xen_XM_XtPopupChild(Code) \ Xen_list_5(C_string_to_Xen_symbol("XtPopupChild"), Code, Xen_false, Xen_integer_zero, Xen_integer_zero) #define XM_is_XtPopupChild(Arg) is_wrapped("XtPopupChild", Arg) static bool find_popupchild(Xen val, int loc, unsigned long w) { return((XM_is_XtPopupChild(val)) && (((Xen_is_false((Xen)w)) && (Xen_is_false(Xen_list_ref(val, CALLBACK_DATA)))) || ((Xen_is_Widget(Xen_list_ref(val, CALLBACK_DATA))) && (Xen_ulong_to_C_ulong(Xen_cadr(Xen_list_ref(val, CALLBACK_DATA))) == w)))); } static void gxm_XtPopupChild(Widget w) { /* since all we have to go by is the widget, we have to scan the gc table for any associated code */ int i; i = map_over_protected_elements(find_popupchild, (unsigned long)w); if (i >= 0) { Xen code; code = Xen_list_ref(xm_protected_element(i), CALLBACK_FUNC); if (Xen_is_procedure(code)) Xen_call_with_1_arg(code, C_to_Xen_Widget(w), __func__); } } #define C_to_Xen_XM_XmSearchProc(Code) \ Xen_list_5(C_string_to_Xen_symbol("XmSearchProc"), Code, Xen_false, Xen_integer_zero, Xen_integer_zero) #define XM_is_XmSearchProc(Arg) is_wrapped("XmSearchProc", Arg) static bool find_searchproc(Xen val, int loc, unsigned long w) { return((XM_is_XmSearchProc(val)) && (((Xen_is_false((Xen)w)) && (Xen_is_false(Xen_list_ref(val, CALLBACK_DATA)))) || ((Xen_is_Widget(Xen_list_ref(val, CALLBACK_DATA))) && (Xen_ulong_to_C_ulong(Xen_cadr(Xen_list_ref(val, CALLBACK_DATA))) == w)))); } static void gxm_XmSearchProc(Widget w, XmFileSelectionBoxCallbackStruct *info) { /* here we again have to go by the widget */ int i; i = map_over_protected_elements(find_searchproc, (unsigned long)w); if (i >= 0) { Xen code; code = Xen_list_ref(xm_protected_element(i), CALLBACK_FUNC); if (Xen_is_procedure(code)) Xen_call_with_2_args(code, C_to_Xen_Widget(w), C_to_Xen_XmFileSelectionBoxCallbackStruct(info), __func__); } } #define C_to_Xen_XM_XmQualifyProc(Code) \ Xen_list_5(C_string_to_Xen_symbol("XmQualifyProc"), Code, Xen_false, Xen_integer_zero, Xen_integer_zero) #define XM_is_XmQualifyProc(Arg) is_wrapped("XmQualifyProc", Arg) static bool find_qualifyproc(Xen val, int loc, unsigned long w) { return((XM_is_XmQualifyProc(val)) && (((Xen_is_false((Xen)w)) && (Xen_is_false(Xen_list_ref(val, CALLBACK_DATA)))) || ((Xen_is_Widget(Xen_list_ref(val, CALLBACK_DATA))) && (Xen_ulong_to_C_ulong(Xen_cadr(Xen_list_ref(val, CALLBACK_DATA))) == w)))); } static void gxm_XmQualifyProc(Widget w, XtPointer indata, XtPointer outdata) { /* here we again have to go by the widget */ int i; i = map_over_protected_elements(find_qualifyproc, (unsigned long)w); if (i >= 0) { Xen code; code = Xen_list_ref(xm_protected_element(i), CALLBACK_FUNC); if (Xen_is_procedure(code)) Xen_call_with_3_args(code, C_to_Xen_Widget(w), C_to_Xen_XmFileSelectionBoxCallbackStruct((XmFileSelectionBoxCallbackStruct *)indata), C_to_Xen_XmFileSelectionBoxCallbackStruct((XmFileSelectionBoxCallbackStruct *)outdata), __func__); } } #define C_to_Xen_XM_XtOrderProc(Code) \ Xen_list_5(C_string_to_Xen_symbol("XtOrderProc"), Code, Xen_false, Xen_integer_zero, Xen_integer_zero) #define XM_is_XtOrderProc(Arg) is_wrapped("XtOrderProc", Arg) static bool find_orderproc(Xen val, int loc, unsigned long w) { return((XM_is_XtOrderProc(val)) && (((Xen_is_false((Xen)w)) && (Xen_is_false(Xen_list_ref(val, CALLBACK_DATA)))) || ((Xen_is_Widget(Xen_list_ref(val, CALLBACK_DATA))) && (Xen_ulong_to_C_ulong(Xen_cadr(Xen_list_ref(val, CALLBACK_DATA))) == w)))); } static Cardinal gxm_XtOrderProc(Widget w) { /* here we again have to go by the widget */ int i, result = 0; i = map_over_protected_elements(find_orderproc, (unsigned long)w); if (i >= 0) { Xen code; code = Xen_list_ref(xm_protected_element(i), CALLBACK_FUNC); if (Xen_is_procedure(code)) result = Xen_integer_to_C_int(Xen_call_with_1_arg(code, C_to_Xen_Widget(w), __func__)); } return((Cardinal)result); } #define C_to_Xen_XM_Parse_Callback(Code) \ Xen_list_5(C_string_to_Xen_symbol("Parse_Callback"), Code, Xen_false, Xen_integer_zero, Xen_integer_zero) #define XM_is_Parse_Callback(Arg) is_wrapped("Parse_Callback", Arg) static bool find_parseproc(Xen val, int loc, unsigned long w) { return((XM_is_Parse_Callback(val)) && (((Xen_is_false((Xen)w)) && (Xen_is_false(Xen_list_ref(val, CALLBACK_DATA)))) || ((Xen_is_XmParseMapping(Xen_list_ref(val, CALLBACK_DATA))) && (Xen_ulong_to_C_ulong(Xen_cadr(Xen_list_ref(val, CALLBACK_DATA))) == w)))); } static XmIncludeStatus gxm_Parse_Callback(XtPointer *in_out, XtPointer text_end, XmTextType type, XmStringTag locale_tag, XmParseMapping entry, int pattern_length, XmString *str_include, XtPointer call_data) { int i; i = map_over_protected_elements(find_parseproc, (unsigned long)entry); if (i >= 0) { Xen code; code = Xen_list_ref(xm_protected_element(i), CALLBACK_FUNC); if (Xen_is_procedure(code)) return(Xen_integer_to_C_int(Xen_apply(code, Xen_list_8(C_string_to_Xen_string((char *)(*in_out)), Xen_wrap_C_pointer(text_end), /* can't work... */ C_int_to_Xen_integer(type), C_string_to_Xen_string(locale_tag), C_to_Xen_XmParseMapping(entry), C_int_to_Xen_integer(pattern_length), C_to_Xen_XmString((*str_include)), /* can't work... */ (Xen)call_data), __func__))); } return(0); } static Xen xm_XmColorAllocationProc; static void gxm_XmAllocColorProc(Display *dpy, Colormap color, XColor *bs) { /* DIFF: XmAllocColorProc should return new XColor value */ Xen val; val = Xen_call_with_3_args(xm_XmColorAllocationProc, C_to_Xen_Display(dpy), C_to_Xen_Colormap(color), C_to_Xen_XColor(bs), __func__); (*bs) = (*(Xen_to_C_XColor(val))); } static Xen xm_XmColorCalculationProc; static void gxm_XmColorCalculationProc(Screen *scr, XColor *bg, XColor *fg, XColor *sel, XColor *ts, XColor *bs) { /* DIFF: XmColorCalculationProc takes 2 args, returns list of 4 colors */ Xen lst; int loc; lst = Xen_call_with_2_args(xm_XmColorCalculationProc, C_to_Xen_Screen(scr), C_to_Xen_XColor(bg), __func__); loc = xm_protect(lst); if (Xen_is_list(lst)) { (*fg) = (*(Xen_to_C_XColor(Xen_list_ref(lst, 0)))); (*sel) = (*(Xen_to_C_XColor(Xen_list_ref(lst, 1)))); (*ts) = (*(Xen_to_C_XColor(Xen_list_ref(lst, 2)))); (*bs) = (*(Xen_to_C_XColor(Xen_list_ref(lst, 3)))); } xm_unprotect_at(loc); } static Xen xm_XmColorProc; /* XmColorProc is not the same as XmScreen color calculation proc */ static void gxm_XmColorProc(XColor *bg, XColor *fg, XColor *sel, XColor *ts, XColor *bs) { Xen lst; int loc; lst = Xen_call_with_1_arg(xm_XmColorProc, C_to_Xen_XColor(bg), __func__); loc = xm_protect(lst); if (Xen_is_list(lst)) { (*fg) = (*(Xen_to_C_XColor(Xen_list_ref(lst, 0)))); (*sel) = (*(Xen_to_C_XColor(Xen_list_ref(lst, 1)))); (*ts) = (*(Xen_to_C_XColor(Xen_list_ref(lst, 2)))); (*bs) = (*(Xen_to_C_XColor(Xen_list_ref(lst, 3)))); } xm_unprotect_at(loc); } static XtCallbackList Xen_to_C_XtCallbackList(Xen call_list1) { Xen call_list; int call_i, call_len; XtCallbackRec *cl = NULL; call_list = Xen_copy_arg(call_list1); call_len = Xen_list_length(call_list) / 2; if (call_len == 0) return(NULL); cl = (XtCallbackRec *)calloc(call_len + 1, sizeof(XtCallbackRec)); for (call_i = 0; call_i < call_len; call_i++, call_list = Xen_cddr(call_list)) { Xen func, data; func = Xen_car(call_list); if (Xen_list_length(call_list) == 2) data = Xen_cadr(call_list); else data = Xen_false; if ((Xen_is_procedure(func)) && (Xen_is_aritable(func, 3))) { Xen descr; cl[call_i].callback = gxm_XtCallbackProc; descr = C_to_Xen_XM_XtCallback(Xen_car(call_list), data); cl[call_i].closure = (XtPointer)descr; Xen_list_set(descr, CALLBACK_GC_LOC, C_int_to_Xen_integer(xm_protect(descr))); } } return(cl); } static Xen C_to_Xen_STRING_WITH_TERMINATION(char *str, unsigned long len) { if ((len == 0) || (str == NULL)) return(Xen_false); str[len] = '\0'; return(C_string_to_Xen_string(str)); } static Xen xm_XtSelectionCallback_Descr; static void gxm_XtSelectionCallbackProc(Widget w, XtPointer x, Atom *a1, Atom *a2, XtPointer x1, unsigned long *l, int *i) { Xen_apply(Xen_car(xm_XtSelectionCallback_Descr), Xen_list_7(C_to_Xen_Widget(w), Xen_cadr(xm_XtSelectionCallback_Descr), C_to_Xen_Atom(*a1), C_to_Xen_Atom(*a2), C_to_Xen_STRING_WITH_TERMINATION((char *)x1, *l), /* should we handle Atom -> Lisp type conversions? */ C_ulong_to_Xen_ulong(*l), C_int_to_Xen_integer(*i)), __func__); } static Xen xm_XtConvertSelectionIncr_Descr; static Boolean gxm_XtConvertSelectionIncrProc(Widget w, Atom *selection, Atom *target, Atom *type_return, XtPointer *value_return, unsigned long *length_return, int *format_return, unsigned long *max_length, XtPointer client_data, XtRequestId *request_id) { /* DIFF: user callback here takes 6 args (w selection target max_length client_data request_id) * should return (list ...) if ok, #f if not * the list should be (type value length format) */ Xen result; result = Xen_apply(xm_XtConvertSelectionIncr_Descr, Xen_list_6(C_to_Xen_Widget(w), C_to_Xen_Atom(*selection), C_to_Xen_Atom(*target), C_int_to_Xen_integer(*max_length), Xen_wrap_C_pointer(client_data), C_ulong_to_Xen_ulong(*request_id)), /* XtRequestId is XtPointer */ __func__); if (Xen_is_false(result)) return(0); (*type_return) = Xen_to_C_Atom(Xen_list_ref(result, 0)); (*value_return) = (XtPointer)Xen_unwrap_C_pointer(Xen_list_ref(result, 1)); (*length_return) = (unsigned long)Xen_integer_to_C_int(Xen_list_ref(result, 2)); (*format_return) = Xen_integer_to_C_int(Xen_list_ref(result, 3)); return(1); } static Arg *protect_args(Arg *args, int len) { /* probably too clever... trying to put off the copy until after all error checking to reduce memory leakage */ int i; for (i = 0; i < len; i++) if (args[i].name) args[i].name = xen_strdup(args[i].name); /* Xen_to_C_STRING will eventually gc, so protect against that until we're done with args */ return(args); } static Arg *free_args(Arg *args, int len) { int i; for (i = 0; i < len; i++) if (args[i].name) free(args[i].name); /* free what we xen_strdup'd above */ free(args); return(NULL); } static Arg *Xen_to_C_Args(Xen inargl) { /* an Arg array in xm is a list of name value pairs */ Arg *args = NULL; int i, len, gcloc; Xen descr, inarg; /* if XtVaNestedList supported, scan for it here, and increase length as needed, * then make recursive call to Xen_to_C_Args in that branch, unloading afterwards * this is not actually needed in xm -- just use append! */ inarg = Xen_copy_arg(inargl); len = Xen_list_length(inarg) / 2; if (len == 0) return(NULL); gcloc = xm_protect(inarg); args = (Arg *)calloc(len, sizeof(Arg)); for (i = 0; i < len; i++, inarg = Xen_cddr(inarg)) { XtCallbackRec *cl = NULL; xm_resource_t type; Xen xname, value; char *name; xname = Xen_car(inarg); Xen_check_type(Xen_is_string(xname), xname, 0, __func__, "string"); name = (char *)Xen_string_to_C_string(xname); type = resource_type(name); value = Xen_cadr(inarg); switch (type) { /* here the XtSetArg call wants an XtCallbackList, the incoming Xen type is a list of callback data pairs * the new callback rec.callback = gxm_XtCallback (etc -- chosen by resource type) * the rec.closure will be the wrapped func/data info * we don't have all the data we need for the actual wrapped list here since we need the widget to choose the callback struct type * so fixup_args should always follow if there's a possible callback list in the resource settings * also, which callback is invoked may depend on callback type */ case XM_CALLBACK: cl = Xen_to_C_XtCallbackList(value); if (cl) XtSetArg(args[i], name, cl); break; case XM_PARSE_CALLBACK: if ((Xen_is_procedure(value)) && (Xen_is_aritable(value, 8))) { XtSetArg(args[i], name, (unsigned long)gxm_Parse_Callback); descr = C_to_Xen_XM_Parse_Callback(value); Xen_list_set(descr, CALLBACK_GC_LOC, C_int_to_Xen_integer(xm_protect(descr))); } else { if (Xen_is_false(value)) XtSetArg(args[i], name, 0); else Xen_check_type(0, value, 0, name, "procedure of 8 args"); } break; case XM_DROP_CALLBACK: if ((Xen_is_procedure(value)) && (Xen_is_aritable(value, 3))) { XtSetArg(args[i], name, (unsigned long)gxm_Drop_Callback); descr = C_to_Xen_XM_Drop_Callback(value); Xen_list_set(descr, CALLBACK_GC_LOC, C_int_to_Xen_integer(xm_protect(descr))); } else { if (Xen_is_false(value)) XtSetArg(args[i], name, 0); else Xen_check_type(0, value, 0, name, "procedure of 3 args"); } break; case XM_DRAG_CALLBACK: if ((Xen_is_procedure(value)) && (Xen_is_aritable(value, 3))) { XtSetArg(args[i], name, (unsigned long)gxm_Drag_Callback); descr = C_to_Xen_XM_Drag_Callback(value); Xen_list_set(descr, CALLBACK_GC_LOC, C_int_to_Xen_integer(xm_protect(descr))); } else { if (Xen_is_false(value)) XtSetArg(args[i], name, 0); else Xen_check_type(0, value, 0, name, "procedure of 3 args"); } break; case XM_SEARCH_CALLBACK: /* XmNfileSearchProc and XmNdirSearchProc, XmSearchProc XmFileSelectionBox 756 */ if ((Xen_is_procedure(value)) && (Xen_is_aritable(value, 2))) { XtSetArg(args[i], name, (unsigned long)gxm_XmSearchProc); descr = C_to_Xen_XM_XmSearchProc(value); Xen_list_set(descr, CALLBACK_GC_LOC, C_int_to_Xen_integer(xm_protect(descr))); } else { if (Xen_is_false(value)) XtSetArg(args[i], name, 0); else Xen_check_type(0, value, 0, name, "procedure of 2 args"); } break; case XM_QUALIFY_CALLBACK: /* XmNqualifySearchDataProc, XmQualifyProc */ if ((Xen_is_procedure(value)) && (Xen_is_aritable(value, 3))) { XtSetArg(args[i], name, (unsigned long)gxm_XmQualifyProc); descr = C_to_Xen_XM_XmQualifyProc(value); Xen_list_set(descr, CALLBACK_GC_LOC, C_int_to_Xen_integer(xm_protect(descr))); } else { if (Xen_is_false(value)) XtSetArg(args[i], name, 0); else Xen_check_type(0, value, 0, name, "procedure of 3 args"); } break; case XM_ORDER_CALLBACK: if ((Xen_is_procedure(value)) && (Xen_is_aritable(value, 1))) { XtSetArg(args[i], name, (unsigned long)gxm_XtOrderProc); descr = C_to_Xen_XM_XtOrderProc(value); Xen_list_set(descr, CALLBACK_GC_LOC, C_int_to_Xen_integer(xm_protect(descr))); } else { if (Xen_is_false(value)) XtSetArg(args[i], name, 0); else Xen_check_type(0, value, 0, name, "procedure of 1 arg"); } break; case XM_TRANSFER_CALLBACK: /* XmNtransferProc, XtSelectionCallbackProc, XmDropTransfer */ /* for now I'll assume no collisions here */ xm_XtSelectionCallback_Descr = Xen_list_2(value, Xen_false); xm_protect(xm_XtSelectionCallback_Descr); XtSetArg(args[i], name, (unsigned long)gxm_XtSelectionCallbackProc); break; case XM_CONVERT_CALLBACK: /* XmNconvertProc, XtConvertSelectionIncrProc, XmDragContext */ xm_XtConvertSelectionIncr_Descr = value; xm_protect(xm_XtConvertSelectionIncr_Descr); XtSetArg(args[i], name, (unsigned long)gxm_XtConvertSelectionIncrProc); break; case XM_ALLOC_COLOR_CALLBACK: /* XmNcolorAllocationProc, XmAllocColorProc XmScreen 921 */ if ((Xen_is_procedure(value)) && (Xen_is_aritable(value, 3))) { XtSetArg(args[i], name, (unsigned long)gxm_XmAllocColorProc); if (Xen_is_procedure(xm_XmColorAllocationProc)) xm_unprotect(xm_XmColorAllocationProc); xm_protect(value); xm_XmColorAllocationProc = value; } else { if (Xen_is_false(value)) XtSetArg(args[i], name, 0); else Xen_check_type(0, value, 0, name, "procedure of 3 args"); } break; case XM_SCREEN_COLOR_CALLBACK: /* XmNcolorCalculationProc, XmScreen 921 */ if ((Xen_is_procedure(value)) && (Xen_is_aritable(value, 2))) { XtSetArg(args[i], name, (unsigned long)gxm_XmColorCalculationProc); if (Xen_is_procedure(xm_XmColorCalculationProc)) xm_unprotect(xm_XmColorCalculationProc); xm_protect(value); xm_XmColorCalculationProc = value; } else { if (Xen_is_false(value)) XtSetArg(args[i], name, 0); else Xen_check_type(0, value, 0, name, "procedure of 2 args"); } break; case XM_POPUP_CALLBACK: /* XmNcreatePopupChildProc, XtCreatePopupChildProc */ if ((Xen_is_procedure(value)) && (Xen_is_aritable(value, 1))) { XtSetArg(args[i], name, (unsigned long)gxm_XtPopupChild); descr = C_to_Xen_XM_XtPopupChild(value); Xen_list_set(descr, CALLBACK_GC_LOC, C_int_to_Xen_integer(xm_protect(descr))); } else { if (Xen_is_false(value)) XtSetArg(args[i], name, 0); else Xen_check_type(0, value, 0, name, "procedure of 1 arg"); } break; /* the rest are just doing type checks before the conversion to C */ case XM_INT: Xen_check_type(Xen_is_integer(value), value, 1, name, "an integer"); XtSetArg(args[i], name, (XtArgVal)(Xen_integer_to_C_int(value))); break; case XM_FLOAT: Xen_check_type(Xen_is_double(value), value, 1, name, "a float"); XtSetArg(args[i], name, (XtArgVal)(Xen_real_to_C_double(value))); break; case XM_STRING: Xen_check_type(Xen_is_string(value), value, 1, name, "a string"); XtSetArg(args[i], name, (XtArgVal)(Xen_string_to_C_string(value))); break; case XM_STRING_OR_INT: Xen_check_type(Xen_is_string(value) || Xen_is_integer(value), value, 1, name, "an integer or a string"); if (Xen_is_string(value)) XtSetArg(args[i], name, (XtArgVal)(Xen_string_to_C_string(value))); else XtSetArg(args[i], name, (XtArgVal)(Xen_integer_to_C_int(value))); break; case XM_XMSTRING: Xen_check_type(Xen_is_XmString(value), value, 1, name, "an XmString"); XtSetArg(args[i], name, (XtArgVal)(Xen_to_C_XmString(value))); break; case XM_STRING_OR_XMSTRING: Xen_check_type(Xen_is_XmString(value) || Xen_is_string(value), value, 1, name, "a string or an XmString"); if (Xen_is_string(value)) XtSetArg(args[i], name, (XtArgVal)(Xen_string_to_C_string(value))); else XtSetArg(args[i], name, (XtArgVal)(Xen_to_C_XmString(value))); break; case XM_STRING_TABLE: Xen_check_type(Xen_is_list(value), value, 1, name, "an XmStringTable"); XtSetArg(args[i], name, (XtArgVal)(Xen_to_C_XmStringTable(value, Xen_list_length(value)))); break; case XM_TRANSFER_ENTRY_LIST: Xen_check_type(Xen_is_list(value), value, 1, name, "a list"); XtSetArg(args[i], name, (XtArgVal)(Xen_to_C_XmDropTransferEntryRecs(value, Xen_list_length(value)))); break; case XM_RENDER_TABLE: Xen_check_type(Xen_is_XmRenderTable(value), value, 1, name, "an XmRenderTable"); XtSetArg(args[i], name, (XtArgVal)(Xen_to_C_XmRenderTable(value))); break; case XM_TAB_LIST: Xen_check_type(Xen_is_XmTabList(value), value, 1, name, "an XmTabList"); XtSetArg(args[i], name, (XtArgVal)(Xen_to_C_XmTabList(value))); break; case XM_WIDGET: Xen_check_type(Xen_is_Widget(value), value, 1, name, "a Widget"); XtSetArg(args[i], name, (XtArgVal)(Xen_to_C_Widget(value))); break; case XM_BOOLEAN: Xen_check_type(Xen_is_boolean(value), value, 1, name, "a boolean"); XtSetArg(args[i], name, (XtArgVal)(Xen_boolean_to_C_bool(value))); break; case XM_BOOLEAN_OR_INT: Xen_check_type(Xen_is_boolean(value) || Xen_is_integer(value), value, 1, name, "a boolean or int"); if (Xen_is_boolean(value)) XtSetArg(args[i], name, (XtArgVal)(Xen_boolean_to_C_bool(value))); else XtSetArg(args[i], name, (XtArgVal)(Xen_integer_to_C_int(value))); break; case XM_PIXEL: Xen_check_type(Xen_is_Pixel(value), value, 1, name, "a pixel"); XtSetArg(args[i], name, (XtArgVal)(Xen_to_C_Pixel(value))); break; case XM_PIXMAP: Xen_check_type(Xen_is_Pixmap(value), value, 1, name, "a pixmap"); XtSetArg(args[i], name, (XtArgVal)(Xen_to_C_Pixmap(value))); break; case XM_DIMENSION: Xen_check_type(Xen_is_integer(value), value, 1, name, "a Dimension (integer)"); XtSetArg(args[i], name, (XtArgVal)(Xen_to_C_Dimension(value))); break; case XM_POSITION: Xen_check_type(Xen_is_integer(value), value, 1, name, "a Position (integer)"); XtSetArg(args[i], name, (XtArgVal)(Xen_to_C_Position(value))); break; case XM_SHORT: Xen_check_type(Xen_is_integer(value), value, 1, name, "a short"); XtSetArg(args[i], name, (XtArgVal)(Xen_integer_to_C_int(value))); break; case XM_ATOM: Xen_check_type(Xen_is_Atom(value), value, 1, name, "an Atom"); XtSetArg(args[i], name, (XtArgVal)(Xen_to_C_Atom(value))); break; case XM_TEXT_SOURCE: Xen_check_type(Xen_is_XmTextSource(value), value, 1, name, "an XmTextSource"); XtSetArg(args[i], name, (XtArgVal)(Xen_to_C_XmTextSource(value))); break; case XM_COLORMAP: Xen_check_type(Xen_is_Colormap(value), value, 1, name, "a Colormap"); XtSetArg(args[i], name, (XtArgVal)(Xen_to_C_Colormap(value))); break; case XM_KEYSYM: Xen_check_type(Xen_is_KeySym(value), value, 1, name, "a KeySym"); XtSetArg(args[i], name, (XtArgVal)(Xen_to_C_KeySym(value))); break; case XM_SCREEN: Xen_check_type(Xen_is_Screen(value), value, 1, name, "a Screen"); XtSetArg(args[i], name, (XtArgVal)(Xen_to_C_Screen(value))); break; case XM_WINDOW: Xen_check_type(Xen_is_Window(value), value, 1, name, "a Window"); XtSetArg(args[i], name, (XtArgVal)(Xen_to_C_Window(value))); break; case XM_VISUAL: Xen_check_type(Xen_is_Visual(value), value, 1, name, "a Visual"); XtSetArg(args[i], name, (XtArgVal)(Xen_to_C_Visual(value))); break; case XM_WIDGET_CLASS: Xen_check_type(Xen_is_WidgetClass(value), value, 1, name, "a WidgetClass"); XtSetArg(args[i], name, (XtArgVal)(Xen_to_C_WidgetClass(value))); break; case XM_ATOM_LIST: Xen_check_type(Xen_is_list(value), value, 1, name, "a list of Atoms"); XtSetArg(args[i], name, (XtArgVal)(Xen_to_C_Atoms(value, Xen_list_length(value)))); break; case XM_INT_TABLE: Xen_check_type(Xen_is_list(value), value, 1, name, "a list of ints"); XtSetArg(args[i], name, (XtArgVal)(Xen_to_C_Ints(value, Xen_list_length(value)))); break; case XM_WIDGET_LIST: Xen_check_type(Xen_is_list(value), value, 1, name, "a list of Widgets"); XtSetArg(args[i], name, (XtArgVal)(Xen_to_C_Widgets(value, Xen_list_length(value)))); break; case XM_KEYSYM_TABLE: Xen_check_type(Xen_is_list(value), value, 1, name, "a list of KeySyms"); XtSetArg(args[i], name, (XtArgVal)(Xen_to_C_KeySyms(value, Xen_list_length(value)))); break; case XM_STRING_LIST: case XM_CHARSET_TABLE: Xen_check_type(Xen_is_list(value), value, 1, name, "a list of char *"); XtSetArg(args[i], name, (XtArgVal)(Xen_to_C_Strings(value, Xen_list_length(value)))); break; case XM_RECTANGLE_LIST: Xen_check_type(Xen_is_list(value), value, 1, name, "a list of XRectangles"); XtSetArg(args[i], name, (XtArgVal)(Xen_to_C_XRectangles(value, Xen_list_length(value)))); break; case XM_CURSOR: Xen_check_type(Xen_is_Cursor(value), value, 1, name, "a cursor"); XtSetArg(args[i], name, (XtArgVal)(Xen_to_C_Cursor(value))); break; default: if (Xen_is_ulong(value)) XtSetArg(args[i], name, (XtArgVal)(Xen_ulong_to_C_ulong(value))); else if (Xen_is_integer(value)) XtSetArg(args[i], name, (XtArgVal)(Xen_integer_to_C_int(value))); else if (Xen_is_boolean(value)) XtSetArg(args[i], name, (XtArgVal)(Xen_boolean_to_C_bool(value))); else if (Xen_is_string(value)) XtSetArg(args[i], name, (XtArgVal)(Xen_string_to_C_string(value))); /* these are bare pointers -- we can't assume they can be "unwrapped" in xen jargon */ else if (Xen_is_list(value)) XtSetArg(args[i], name, (XtArgVal)(Xen_llong_to_C_llong(Xen_cadr(value)))); /* all tagged types */ else XtSetArg(args[i], name, (XtArgVal)(Xen_llong_to_C_llong(value))); break; } } xm_unprotect_at(gcloc); return(protect_args(args, len)); } static void fixup_args(Widget w, Arg *args, int len) { /* search for and fill-in incompletely specified callback info now that we have the widget type */ int i; for (i = 0; i < len; i++) { char *name; name = args[i].name; if (name) { XtCallbackRec *cl = NULL; int j; Xen data; switch (resource_type(name)) { case XM_STRING_TABLE: { XmStringTable *st; st = (XmStringTable *)(args[i].value); free(st); } break; case XM_WIDGET_LIST: { Widget *w; w =(Widget *)(args[i].value); free(w); } break; case XM_CALLBACK: cl = (XtCallbackRec *)(args[i].value); for (j = 0 ;; j++) { if (cl[j].callback == NULL) break; data = (Xen)(cl[j].closure); Xen_list_set(data, CALLBACK_STRUCT_TYPE, C_int_to_Xen_integer(callback_struct_type(w, name))); } free(cl); break; case XM_DROP_CALLBACK: j = map_over_protected_elements(find_dropproc, (unsigned long)w); if (j >= 0) { data = xm_protected_element(j); xm_unprotect_at(Xen_integer_to_C_int(Xen_list_ref(data, CALLBACK_GC_LOC))); } j = map_over_protected_elements(find_dropproc, (unsigned long)Xen_false); if (j >= 0) { data = xm_protected_element(j); Xen_list_set(data, CALLBACK_DATA, C_to_Xen_Widget(w)); } else fprintf(stderr,"can't fixup drop proc!"); break; case XM_DRAG_CALLBACK: j = map_over_protected_elements(find_dragproc, (unsigned long)w); if (j >= 0) { data = xm_protected_element(j); xm_unprotect_at(Xen_integer_to_C_int(Xen_list_ref(data, CALLBACK_GC_LOC))); } j = map_over_protected_elements(find_dragproc, (unsigned long)Xen_false); if (j >= 0) { data = xm_protected_element(j); Xen_list_set(data, CALLBACK_DATA, C_to_Xen_Widget(w)); } else fprintf(stderr,"can't fixup drag proc!"); break; case XM_QUALIFY_CALLBACK: j = map_over_protected_elements(find_qualifyproc, (unsigned long)w); /* see if one already exists */ if (j >= 0) { data = xm_protected_element(j); xm_unprotect_at(Xen_integer_to_C_int(Xen_list_ref(data, CALLBACK_GC_LOC))); } j = map_over_protected_elements(find_qualifyproc, (unsigned long)Xen_false); /* i.e. find the unset one */ if (j >= 0) { data = xm_protected_element(j); Xen_list_set(data, CALLBACK_DATA, C_to_Xen_Widget(w)); } break; case XM_SEARCH_CALLBACK: j = map_over_protected_elements(find_searchproc, (unsigned long)w); if (j >= 0) { data = xm_protected_element(j); xm_unprotect_at(Xen_integer_to_C_int(Xen_list_ref(data, CALLBACK_GC_LOC))); } j = map_over_protected_elements(find_searchproc, (unsigned long)Xen_false); if (j >= 0) { data = xm_protected_element(j); Xen_list_set(data, CALLBACK_DATA, C_to_Xen_Widget(w)); } break; case XM_ORDER_CALLBACK: j = map_over_protected_elements(find_orderproc, (unsigned long)w); if (j >= 0) { data = xm_protected_element(j); xm_unprotect_at(Xen_integer_to_C_int(Xen_list_ref(data, CALLBACK_GC_LOC))); } j = map_over_protected_elements(find_orderproc, (unsigned long)Xen_false); if (j >= 0) { data = xm_protected_element(j); Xen_list_set(data, CALLBACK_DATA, C_to_Xen_Widget(w)); } break; case XM_POPUP_CALLBACK: j = map_over_protected_elements(find_popupchild, (unsigned long)w); if (j >= 0) { data = xm_protected_element(j); xm_unprotect_at(Xen_integer_to_C_int(Xen_list_ref(data, CALLBACK_GC_LOC))); } j = map_over_protected_elements(find_popupchild, (unsigned long)Xen_false); if (j >= 0) { data = xm_protected_element(j); Xen_list_set(data, CALLBACK_DATA, C_to_Xen_Widget(w)); } break; default: break; } } } } static int xmstringtable_length(Widget w, const char *name) { /* it's not safe here to search for 0 as end of table, so where possible we'll match resources with counts */ int len = 0; if (strcmp(name, XmNitems) == 0) XtVaGetValues(w, XmNitemCount, &len, NULL); else if (strcmp(name, XmNlistItems) == 0) XtVaGetValues(w, XmNlistItemCount, &len, NULL); else if (strcmp(name, XmNselectedItems) == 0) XtVaGetValues(w, XmNselectedItemCount, &len, NULL); else if (strcmp(name, XmNhistoryItems) == 0) XtVaGetValues(w, XmNhistoryItemCount, &len, NULL); else if (strcmp(name, XmNfileListItems) == 0) XtVaGetValues(w, XmNfileListItemCount, &len, NULL); else if (strcmp(name, XmNdirListItems) == 0) XtVaGetValues(w, XmNdirListItemCount, &len, NULL); else if (strcmp(name, XmNdetail) == 0) XtVaGetValues(w, XmNdetailCount, &len, NULL); else if (strcmp(name, XmNvalues) == 0) XtVaGetValues(w, XmNnumValues, &len, NULL); else XtVaGetValues(w, XmNbuttonCount, &len, NULL); return(len); } static Xen C_to_Xen_ANY(Widget w, Arg arg) { /* XtGetValues -- a list of pairs: resource-name place-holder where we fill in the 2nd element */ /* this has to wait until the last moment to decide what arg.value is -- if we assume unsigned long* * (which works on the Pentium/Linux), the Sun gets confused by Dimensions (unsigned short) */ Arg a[1]; int j, ilen = 0; switch (resource_type(arg.name)) { case XM_INT: return(C_int_to_Xen_integer((*((int *)(arg.value))))); case XM_ULONG: return(C_ulong_to_Xen_ulong((*((unsigned long *)(arg.value))))); case XM_XTPOINTER: return(Xen_wrap_C_pointer((XtPointer)(arg.value))); case XM_UCHAR: return(C_int_to_Xen_integer((*((unsigned char *)(arg.value))))); case XM_FLOAT: return(C_double_to_Xen_real((*((float *)(arg.value))))); /* the resource values are floats */ case XM_STRING: return(C_string_to_Xen_string((char *)(*((char **)(arg.value))))); case XM_STRING_OR_XMSTRING: /* fileselectionbox here , not parsemapping */ case XM_XMSTRING: return(C_to_Xen_XmString((XmString)(*((XmString *)(arg.value))))); case XM_STRING_TABLE: return(C_to_Xen_XmStringTable((XmStringTable)(*((XmStringTable *)(arg.value))), xmstringtable_length(w, arg.name))); case XM_RENDER_TABLE: return(C_to_Xen_XmRenderTable((XmRenderTable)(*((XmRenderTable *)(arg.value))))); case XM_TAB_LIST: return(C_to_Xen_XmTabList((XmTabList)(*((XmTabList *)(arg.value))))); case XM_WIDGET: return(C_to_Xen_Widget((Widget)(*((Widget *)(arg.value))))); case XM_WIDGET_LIST: /* (XtGetValues c1 (list XmNchildren 0) 1) */ if (strcmp(arg.name, XmNchildren) == 0) XtSetArg(a[0], XmNnumChildren, &ilen); /* Composite */ else XtSetArg(a[0], XmNselectedObjectCount, &ilen); /* Container */ XtGetValues(w, a, 1); return(C_to_Xen_Widgets((Widget *)(*((Widget **)(arg.value))), ilen)); break; case XM_BOOLEAN: return(C_bool_to_Xen_boolean((*((Boolean *)(arg.value))))); case XM_BOOLEAN_OR_INT: return(C_int_to_Xen_integer((*((int *)(arg.value))))); case XM_SEARCH_CALLBACK: j = map_over_protected_elements(find_searchproc, (unsigned long)w); if (j >= 0) return(Xen_list_ref(xm_protected_element(j), CALLBACK_FUNC)); break; case XM_DROP_CALLBACK: j = map_over_protected_elements(find_dropproc, (unsigned long)w); if (j >= 0) return(Xen_list_ref(xm_protected_element(j), CALLBACK_FUNC)); break; case XM_DRAG_CALLBACK: j = map_over_protected_elements(find_dragproc, (unsigned long)w); if (j >= 0) return(Xen_list_ref(xm_protected_element(j), CALLBACK_FUNC)); break; case XM_ORDER_CALLBACK: j = map_over_protected_elements(find_orderproc, (unsigned long)w); if (j >= 0) return(Xen_list_ref(xm_protected_element(j), CALLBACK_FUNC)); break; case XM_QUALIFY_CALLBACK: j = map_over_protected_elements(find_qualifyproc, (unsigned long)w); if (j >= 0) return(Xen_list_ref(xm_protected_element(j), CALLBACK_FUNC)); break; case XM_ALLOC_COLOR_CALLBACK: return(xm_XmColorAllocationProc); break; case XM_SCREEN_COLOR_CALLBACK: return(xm_XmColorCalculationProc); break; case XM_POPUP_CALLBACK: j = map_over_protected_elements(find_popupchild, (unsigned long)w); if (j >= 0) return(Xen_list_ref(xm_protected_element(j), CALLBACK_FUNC)); break; case XM_TRANSFER_CALLBACK: return(xm_XtSelectionCallback_Descr); case XM_CONVERT_CALLBACK: return(xm_XtConvertSelectionIncr_Descr); case XM_CALLBACK: /* this can't work because we don't know what the desired callback was, so we can't search the gc table */ /* and if the callback was a C procedure, what good would its address be in this context? */ /* (XtGetValues_1 would need to pass the entire Arg or something) */ return(C_ulong_to_Xen_ulong((*((unsigned long *)(arg.value))))); break; case XM_PIXEL: return(C_to_Xen_Pixel((*((Pixel *)(arg.value))))); case XM_PIXMAP: return(C_to_Xen_Pixmap((*((Pixmap *)(arg.value))))); case XM_XFONTSTRUCT: return(C_to_Xen_XFontStruct((XFontStruct *)(*((XFontStruct **)(arg.value))))); case XM_DIMENSION: return(C_to_Xen_Dimension((*((Dimension *)(arg.value))))); case XM_POSITION: return(C_to_Xen_Position((*((Position *)(arg.value))))); case XM_SHORT: return(C_int_to_Xen_integer((*((short *)(arg.value))))); case XM_ATOM: return(C_to_Xen_Atom((*((Atom *)(arg.value))))); case XM_TEXT_SOURCE: return(C_to_Xen_XmTextSource((XmTextSource)(*((XmTextSource *)(arg.value))))); case XM_ATOM_LIST: if (strcmp(arg.name, XmNexportTargets) == 0) /* DragContext */ XtSetArg(a[0], XmNnumExportTargets, &ilen); /* DropSite */ else XtSetArg(a[0], XmNnumImportTargets, &ilen); XtGetValues(w, a, 1); if ((ilen > 0) && (ilen < 100)) return(C_to_Xen_Atoms((Atom *)(*((Atom **)(arg.value))), ilen)); else return(Xen_false); break; case XM_STRING_LIST: /* ApplicationShell */ XtSetArg(a[0], XmNargc, &ilen); XtGetValues(w, a, 1); return(C_to_Xen_Strings((char **)(*((char ***)(arg.value))), ilen)); break; case XM_CHARSET_TABLE: XtSetArg(a[0], XmNbuttonCount, &ilen); /* may not be long enough... */ XtGetValues(w, a, 1); return(C_to_Xen_Strings((char **)(*((char ***)(arg.value))), ilen)); break; case XM_COLORMAP: return(C_to_Xen_Colormap((*((Colormap *)(arg.value))))); case XM_KEYSYM: return(C_to_Xen_KeySym((*((KeySym *)(arg.value))))); case XM_KEYSYM_TABLE: XtSetArg(a[0], XmNbuttonCount, &ilen); XtGetValues(w, a, 1); return(C_to_Xen_KeySyms((KeySym *)(*((KeySym **)(arg.value))), ilen)); break; case XM_SCREEN: return(C_to_Xen_Screen((Screen *)(*((Screen **)(arg.value))))); case XM_WINDOW: return(C_to_Xen_Window((Window)(*((Window *)(arg.value))))); case XM_VISUAL: return(C_to_Xen_Visual((Visual *)(*((Visual **)(arg.value))))); case XM_INT_TABLE: if (strcmp(arg.name, XmNdetailOrder) == 0) XtSetArg(a[0], XmNdetailOrderCount, &ilen); else { if (strcmp(arg.name, XmNselectionArray) == 0) XtSetArg(a[0], XmNselectionArrayCount, &ilen); else XtSetArg(a[0], XmNselectedPositionCount, &ilen); } XtGetValues(w, a, 1); return(C_to_Xen_Ints((int *)(*((int **)(arg.value))), ilen)); break; case XM_RECTANGLE_LIST: /* XmNrectangles exists but is not documented */ XtSetArg(a[0], XmNnumDropRectangles, &ilen); XtGetValues(w, a, 1); return(C_to_Xen_XRectangles((XRectangle *)(*((XRectangle **)(arg.value))), ilen)); break; case XM_WIDGET_CLASS: return(C_to_Xen_WidgetClass((WidgetClass)(*((WidgetClass *)(arg.value))))); case XM_STRING_OR_INT: if ((w) && ((XmIsText(w)) || (XmIsTextField(w)))) return(C_string_to_Xen_string((char *)(*((char **)(arg.value))))); else return(C_int_to_Xen_integer((int)(*((int *)(arg.value))))); break; default: break; } return(C_ulong_to_Xen_ulong((*((unsigned long *)(arg.value))))); /* fallback */ } static Xen C_to_Xen_Args(Widget w, Arg *args, int len) { /* here XtGetValues (or equivalent) has filled in the resource values and we need to pass them back * to scheme properly wrapped */ int i, loc; Xen lst = Xen_empty_list; loc = xm_protect(lst); for (i = len - 1; i >= 0; i--) lst = Xen_cons_2(C_string_to_Xen_string(args[i].name), C_to_Xen_ANY(w, args[i]), lst); xm_unprotect_at(loc); return(lst); } /* (XtGetValues c1 (list XmNx 0) 1) */ static Xen gxm_XtGetValues_1(Xen arg1, Xen larg2, int len) { Arg *args; unsigned long *locs; Widget w; Xen val, arg2; int i, gcloc; /* here we need to make sure the ref args are ok from C's point of view */ if (len <= 0) return(Xen_false); w = Xen_to_C_Widget(arg1); arg2 = Xen_copy_arg(larg2); gcloc = xm_protect(arg2); args = (Arg *)calloc(len, sizeof(Arg)); locs = (unsigned long *)calloc(len, sizeof(unsigned long)); for (i = 0; i < len; i++, arg2 = Xen_cddr(arg2)) { char *name; name = xen_strdup(Xen_string_to_C_string(Xen_car(arg2))); XtSetArg(args[i], name, &(locs[i])); } XtGetValues(w, args, len); val = C_to_Xen_Args(w, args, len); free_args(args, len); free(locs); xm_unprotect_at(gcloc); return(val); } /* -------------------------------- gc protection -------------------------------- */ static Xen xm_protected; static int xm_protected_size = 0; static Xen xm_gc_table; static int last_xm_unprotect = NOT_A_GC_LOC; static int xm_protect(Xen obj) { int i, new_size; Xen new_table; if (last_xm_unprotect >= 0) { i = last_xm_unprotect; if (Xen_is_false(Xen_vector_ref(xm_protected, i))) { Xen_vector_set(xm_protected, i, obj); last_xm_unprotect = NOT_A_GC_LOC; return(i); } last_xm_unprotect = NOT_A_GC_LOC; } for (i = 0; i < xm_protected_size; i++) if (Xen_is_false(Xen_vector_ref(xm_protected, i))) { Xen_vector_set(xm_protected, i, obj); return(i); } new_size = xm_protected_size * 2; new_table = Xen_make_vector(new_size, Xen_false); for (i = 0; i < xm_protected_size; i++) { Xen_vector_set(new_table, i, Xen_vector_ref(xm_protected, i)); Xen_vector_set(xm_protected, i, Xen_false); } Xen_vector_set(new_table, xm_protected_size, obj); Xen_vector_set(xm_gc_table, 0, new_table); i = xm_protected_size; xm_protected_size = new_size; xm_protected = new_table; return(i); } static void xm_unprotect(Xen obj) { int i; for (i = 0; i < xm_protected_size; i++) if (Xen_is_eq(Xen_vector_ref(xm_protected, i), obj)) { Xen_vector_set(xm_protected, i, Xen_false); last_xm_unprotect = i; return; } } static void xm_unprotect_at(int ind) { Xen_vector_set(xm_protected, ind, Xen_false); last_xm_unprotect = ind; } static int map_over_protected_elements(bool (*func)(Xen val, int loc, unsigned long fid), unsigned long id) { int i; for (i = 0; i < xm_protected_size; i++) if (func(Xen_vector_ref(xm_protected, i), i, id)) return(i); return(-1); } static Xen xm_protected_element(int loc) { return(Xen_vector_ref(xm_protected, loc)); } /* ---------------------------------------------------------------------------------------------------- * * * * * * * * * ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ---------------------------------------------------------------------------------------------------- */ /* Motif */ /* weird order of procedures here and throughout caused by the C-header scripts -- * basically I forgot to reverse the main lists before pouring out the code, * so everything is slightly backwards */ static int Xen_to_C_INT_DEF(Xen len, Xen lst) { if (Xen_is_integer(len)) return(Xen_integer_to_C_int(len)); else { int list_len; list_len = Xen_list_length(lst); return((int)(list_len / 2)); } } static Xen gxm_XmTransferDone(Xen arg1, Xen arg2) { #define H_XmTransferDone "void XmTransferDone(XtPointer transfer_id, XmTransferStatus status) completes a data transfer" Xen_check_type(Xen_is_wrapped_c_pointer(arg1), arg1, 1, "XmTransferDone", "XtPointer"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmTransferDone", "XmTransferStatus"); XmTransferDone((XtPointer)Xen_unwrap_C_pointer(arg1), (XmTransferStatus)Xen_integer_to_C_int(arg2)); return(arg1); } static Xen gxm_XmTransferSendRequest(Xen arg1, Xen arg2) { #define H_XmTransferSendRequest "void XmTransferSendRequest(XtPointer transfer_id, Time time) transfers a MULTIPLE request" Xen_check_type(Xen_is_wrapped_c_pointer(arg1), arg1, 1, "XmTransferSendRequest", "XtPointer"); Xen_check_type(Xen_is_Time(arg2), arg2, 2, "XmTransferSendRequest", "Time"); XmTransferSendRequest((XtPointer)Xen_unwrap_C_pointer(arg1), Xen_to_C_Time(arg2)); return(arg1); } static Xen gxm_XmTransferStartRequest(Xen arg1) { #define H_XmTransferStartRequest "void XmTransferStartRequest(XtPointer transfer_id) begins a MULTIPLE transfer" Xen_check_type(Xen_is_wrapped_c_pointer(arg1), arg1, 1, "XmTransferStartRequest", "XtPointer"); XmTransferStartRequest((XtPointer)Xen_unwrap_C_pointer(arg1)); return(arg1); } static Xen gxm_XmTransferSetParameters(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5) { #define H_XmTransferSetParameters "void XmTransferSetParameters(XtPointer transfer_id, XtPointer parm, int parm_fmt, \ unsigned long parm_length, Atom parm_type) establishes parameters to be passed by the next call to XmTransferValue" Xen_check_type(Xen_is_wrapped_c_pointer(arg1), arg1, 1, "XmTransferSetParameters", "XtPointer"); Xen_check_type(Xen_is_wrapped_c_pointer(arg2), arg2, 2, "XmTransferSetParameters", "XtPointer"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XmTransferSetParameters", "an integer"); Xen_check_type(Xen_is_ulong(arg4), arg4, 4, "XmTransferSetParameters", "unsigned long"); Xen_check_type(Xen_is_Atom(arg5), arg5, 5, "XmTransferSetParameters", "an Atom"); XmTransferSetParameters((XtPointer)Xen_unwrap_C_pointer(arg1), (XtPointer)Xen_unwrap_C_pointer(arg2), Xen_integer_to_C_int(arg3), Xen_ulong_to_C_ulong(arg4), Xen_to_C_Atom(arg5)); return(arg1); } static void gxm_TransferValueProc(Widget w, XtPointer context, XtPointer info) { Xen descr = (Xen)context; Xen_call_with_3_args(Xen_list_ref(descr, 0), C_to_Xen_Widget(w), Xen_list_ref(descr, 1), C_to_Xen_XmSelectionCallbackStruct((XmSelectionCallbackStruct *)info), __func__); } static Xen gxm_XmTransferValue(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5) { #define H_XmTransferValue "void XmTransferValue(XtPointer transfer_id, Atom target, XtCallbackProc proc, XtPointer client_data, Time time) \ transfers data to a destination" Xen_check_type(Xen_is_wrapped_c_pointer(arg1), arg1, 1, "XmTransferValue", "XtPointer"); Xen_check_type(Xen_is_Atom(arg2), arg2, 2, "XmTransferValue", "an Atom"); Xen_check_type(Xen_is_procedure(arg3) && (Xen_is_aritable(arg3, 3)), arg3, 3, "XmTransferValue", "XtCallbackProc (3 args)"); Xen_check_type(Xen_is_Time(arg5), arg5, 5, "XmTransferValue", "Time"); XmTransferValue((XtPointer)Xen_unwrap_C_pointer(arg1), Xen_to_C_Atom(arg2), gxm_TransferValueProc, (XtPointer)Xen_list_2(arg3, arg4), Xen_to_C_Time(arg5)); return(arg1); } static Xen gxm_new_widget(const char *caller, Widget (*func)(Widget parent, char *name, ArgList al, Cardinal ac), Xen arg1, Xen arg2, Xen arg3, Xen arg4) { Widget w; Xen_check_type(Xen_is_Widget(arg1), arg1, 1, caller, "Widget"); Xen_check_type(Xen_is_string(arg2), arg2, 2, caller, "char*"); Xen_check_type(Xen_is_list(arg3), arg3, 3, caller, "ArgList"); Xen_check_type(Xen_is_integer_or_unbound(arg4), arg4, 4, caller, "int"); { Arg *args; int arglen; args = Xen_to_C_Args(arg3); w = (*func)(Xen_to_C_Widget(arg1), (char *)Xen_string_to_C_string(arg2), args, arglen = Xen_to_C_INT_DEF(arg4, arg3)); if (args) { fixup_args(w, args, arglen); free_args(args, arglen); } } return(C_to_Xen_Widget(w)); } static Xen gxm_XmCreateMenuShell(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateMenuShell "Widget XmCreateMenuShell(Widget parent, String name, ArgList arglist, Cardinal argcount) \ The MenuShell widget creation function" return(gxm_new_widget("XmCreateMenuShell", XmCreateMenuShell, arg1, arg2, arg3, arg4)); } static Xen gxm_XmProcessTraversal(Xen arg1, Xen arg2) { #define H_XmProcessTraversal "Boolean XmProcessTraversal(Widget widget, XmTraversalDirection direction) determines which \ component receives keyboard events when a widget has the focus" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmProcessTraversal", "Widget"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmProcessTraversal", "XmTraversalDirection"); return(C_bool_to_Xen_boolean(XmProcessTraversal(Xen_to_C_Widget(arg1), (XmTraversalDirection)Xen_integer_to_C_int(arg2)))); } static Xen gxm_XmGetFocusWidget(Xen arg1) { #define H_XmGetFocusWidget "Widget XmGetFocusWidget(Widget widget): returns the ID of the widget that has keyboard focus" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmGetFocusWidget", "Widget"); return(C_to_Xen_Widget(XmGetFocusWidget(Xen_to_C_Widget(arg1)))); } static Xen gxm_XmGetTabGroup(Xen arg1) { #define H_XmGetTabGroup "Widget XmGetTabGroup(Widget widget): returns the widget ID of a tab group" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmGetTabGroup", "Widget"); return(C_to_Xen_Widget(XmGetTabGroup(Xen_to_C_Widget(arg1)))); } static Xen gxm_XmGetVisibility(Xen arg1) { #define H_XmGetVisibility "XmVisibility XmGetVisibility(Widget widget) determines if a widget is visible" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmGetVisibility", "Widget"); return(C_int_to_Xen_integer(XmGetVisibility(Xen_to_C_Widget(arg1)))); } static Xen gxm_XmIsTraversable(Xen arg1) { #define H_XmIsTraversable "Boolean XmIsTraversable(Widget widget) identifies whether a widget can be traversed" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmIsTraversable", "Widget"); return(C_bool_to_Xen_boolean(XmIsTraversable(Xen_to_C_Widget(arg1)))); } static Xen gxm_XmGetDestination(Xen arg1) { #define H_XmGetDestination "Widget XmGetDestination(Display *display) gets the current destination widget for paste etc" Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XmGetDestination", "Display*"); return(C_to_Xen_Widget(XmGetDestination(Xen_to_C_Display(arg1)))); } static Xen gxm_XmRenderTableAddRenditions(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmRenderTableAddRenditions "XmRenderTable XmRenderTableAddRenditions(XmRenderTable oldtable, \ XmRendition *renditions, Cardinal rendition_count, XmMergeMode merge_mode) adds renditions to a render table" /* DIFF: XmRenderTableAddRenditions arg2 is list of Renditions, arg1 can be #f = NULL */ int len, listlen = 0; XmRendition *rs; XmRenderTable res; Xen_check_type(Xen_is_XmRenderTable(arg1) || Xen_is_false(arg1), arg1, 1, "XmRenderTableAddRenditions", "XmRenderTable"); Xen_check_type(Xen_is_list(arg2), arg2, 2, "XmRenderTableAddRenditions", "list of XmRendition"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XmRenderTableAddRenditions", "int"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XmRenderTableAddRenditions", "XmMergeMode"); listlen = Xen_list_length(arg2); len = Xen_integer_to_C_int(arg3); if (len > listlen) len = listlen; if (len <= 0) return(Xen_false); rs = Xen_to_C_XmRenditions(arg2, len); res = XmRenderTableAddRenditions(Xen_is_false(arg1) ? NULL : Xen_to_C_XmRenderTable(arg1), rs, (Cardinal)len, (XmMergeMode)Xen_integer_to_C_int(arg4)); free(rs); return(C_to_Xen_XmRenderTable(res)); } static Xen gxm_XmRenderTableRemoveRenditions(Xen arg1, Xen arg2, Xen arg3) { #define H_XmRenderTableRemoveRenditions "XmRenderTable XmRenderTableRemoveRenditions(XmRenderTable oldtable, XmStringTag *tags, int tag_count) \ removes renditions" /* DIFF: XmRenderTableRemoveRenditions arg2 is list of strings */ int len = 0; XmStringTag *tags = NULL; XmRenderTable rt = NULL; if (!Xen_is_bound(arg1) || Xen_is_false(arg1)) return(Xen_false); Xen_check_type(Xen_is_XmRenderTable(arg1) || Xen_is_false(arg1), arg1, 1, "XmRenderTableRemoveRenditions", "XmRenderTable"); Xen_check_type(Xen_is_list(arg2) || Xen_is_false(arg2) || !Xen_is_bound(arg2), arg2, 2, "XmRenderTableRemoveRenditions", "XmStringTag*"); Xen_check_type(Xen_is_integer_or_unbound(arg3), arg3, 3, "XmRenderTableRemoveRenditions", "int"); if (Xen_is_integer(arg3)) { len = Xen_integer_to_C_int(arg3); if (len <= 0) return(Xen_false); } else { if (Xen_is_list(arg2)) len = Xen_list_length(arg2); } if (Xen_is_bound(arg2)) tags = (XmStringTag *)Xen_to_C_Strings(arg2, len); rt = XmRenderTableRemoveRenditions(Xen_to_C_XmRenderTable(arg1), tags, len); if (tags) free(tags); return(C_to_Xen_XmRenderTable(rt)); } static Xen gxm_XmRenderTableCopy(Xen arg1, Xen arg2, Xen arg3) { #define H_XmRenderTableCopy "XmRenderTable XmRenderTableCopy(XmRenderTable table, XmStringTag *tags, int tag_count) copies renditions" /* DIFF: XmRenderTableCopy arg2 is list of strings */ int len = 0; XmStringTag *tags = NULL; XmRenderTable rt = NULL; if (!Xen_is_bound(arg1) || Xen_is_false(arg1)) return(Xen_false); Xen_check_type(Xen_is_XmRenderTable(arg1), arg1, 1, "XmRenderTableCopy", "XmRenderTable"); Xen_check_type(Xen_is_list(arg2) || Xen_is_false(arg2) || !Xen_is_bound(arg2), arg2, 2, "XmRenderTableCopy", "XmStringTag*"); Xen_check_type(Xen_is_integer_or_unbound(arg3), arg3, 3, "XmRenderTableCopy", "int"); if (Xen_is_integer(arg3)) { len = Xen_integer_to_C_int(arg3); if (len <= 0) return(Xen_false); } else { if (Xen_is_list(arg2)) len = Xen_list_length(arg2); } if (Xen_is_bound(arg2)) tags = (XmStringTag *)Xen_to_C_Strings(arg2, len); rt = XmRenderTableCopy(Xen_to_C_XmRenderTable(arg1), tags, len); if (tags) free(tags); return(C_to_Xen_XmRenderTable(rt)); } static Xen gxm_XmRenderTableFree(Xen arg1) { #define H_XmRenderTableFree "void XmRenderTableFree(XmRenderTable table) recovers memory" Xen_check_type(Xen_is_XmRenderTable(arg1), arg1, 1, "XmRenderTableFree", "XmRenderTable"); XmRenderTableFree(Xen_to_C_XmRenderTable(arg1)); return(Xen_false); } static Xen gxm_XmRenderTableGetTags(Xen arg1) { #define H_XmRenderTableGetTags "int XmRenderTableGetTags(XmRenderTable table) gets rendition tags (list of strings)" /* DIFF: XmRenderTableGetTags omits arg2, returns list of strings */ int len, loc; Xen lst = Xen_empty_list; XmStringTag *str; Xen_check_type(Xen_is_XmRenderTable(arg1), arg1, 1, "XmRenderTableGetTags", "XmRenderTable"); loc = xm_protect(lst); len = XmRenderTableGetTags(Xen_to_C_XmRenderTable(arg1), &str); if (str) { int i; for (i = len - 1; i >= 0; i--) { lst = Xen_cons(C_string_to_Xen_string(str[i]), lst); free(str[i]); } free(str); } xm_unprotect_at(loc); return(lst); } static Xen gxm_XmRenderTableGetRendition(Xen arg1, Xen arg2) { #define H_XmRenderTableGetRendition "XmRendition XmRenderTableGetRendition(XmRenderTable table, XmStringTag tag) \ matches a rendition tag" Xen_check_type(Xen_is_XmRenderTable(arg1), arg1, 1, "XmRenderTableGetRendition", "XmRenderTable"); Xen_check_type(Xen_is_string(arg2), arg2, 2, "XmRenderTableGetRendition", "XmStringTag"); return(C_to_Xen_XmRendition(XmRenderTableGetRendition(Xen_to_C_XmRenderTable(arg1), (char *)Xen_string_to_C_string(arg2)))); } static Xen gxm_XmRenderTableGetRenditions(Xen arg1, Xen arg2, Xen arg3) { #define H_XmRenderTableGetRenditions "XmRendition *XmRenderTableGetRenditions(XmRenderTable table, XmStringTag *tags, Cardinal tag_count) \ matches rendition tags" /* DIFF: XmRenderTableGetRenditions returns list of XmRenditions, arg2 is list of strings */ int i, len = 0, loc; Xen lst = Xen_empty_list; XmRendition *rs; XmStringTag *tags; if ((!Xen_is_bound(arg1)) || !Xen_is_bound(arg2) || Xen_is_false(arg2)) return(Xen_false); Xen_check_type(Xen_is_XmRenderTable(arg1), arg1, 1, "XmRenderTableGetRenditions", "XmRenderTable"); Xen_check_type(Xen_is_list(arg2), arg2, 2, "XmRenderTableGetRenditions", "list of String"); Xen_check_type(Xen_is_integer_or_unbound(arg3), arg3, 3, "XmRenderTableGetRenditions", "int"); if (Xen_is_bound(arg3)) len = Xen_integer_to_C_int(arg3); else len = Xen_list_length(arg2); if (len <= 0) return(Xen_false); loc = xm_protect(lst); tags = (XmStringTag *)Xen_to_C_Strings(arg2, len); rs = XmRenderTableGetRenditions(Xen_to_C_XmRenderTable(arg1), tags, (Cardinal)len); free(tags); for (i = len - 1; i >= 0; i--) lst = Xen_cons(C_to_Xen_XmRendition(rs[i]), lst); free(rs); xm_unprotect_at(loc); return(lst); } static Xen gxm_XmRenditionCreate(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmRenditionCreate "XmRendition XmRenditionCreate(Widget widget, XmStringTag tag, ArgList arglist, Cardinal argcount) \ creates a rendition" XmRendition w; Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmRenditionCreate", "Widget"); Xen_check_type(Xen_is_string(arg2), arg2, 2, "XmRenditionCreate", "XmStringTag"); Xen_check_type(Xen_is_list(arg3), arg3, 3, "XmRenditionCreate", "ArgList"); Xen_check_type(Xen_is_integer_or_unbound(arg4), arg4, 4, "XmRenditionCreate", "int"); { Arg *args; int arglen; args = Xen_to_C_Args(arg3); arglen = Xen_to_C_INT_DEF(arg4, arg3); w = XmRenditionCreate(Xen_to_C_Widget(arg1), (char *)Xen_string_to_C_string(arg2), args, arglen); if (args) free_args(args, arglen); } return(C_to_Xen_XmRendition(w)); } static Xen gxm_XmRenditionFree(Xen arg1) { #define H_XmRenditionFree "void XmRenditionFree(XmRendition rendition) frees a rendition" Xen_check_type(Xen_is_XmRendition(arg1), arg1, 1, "XmRenditionFree", "XmRendition"); XmRenditionFree(Xen_to_C_XmRendition(arg1)); return(Xen_false); } static Xen gxm_XmRenditionRetrieve(Xen arg1, Xen larg2, Xen arg3) { #define H_XmRenditionRetrieve "void XmRenditionRetrieve(XmRendition rendition, ArgList arglist, Cardinal argcount) \ retrieves rendition resources" Xen_check_type(Xen_is_XmRendition(arg1), arg1, 1, "XmRenditionRetrieve", "XmRendition"); Xen_check_type(Xen_is_list(larg2), larg2, 2, "XmRenditionRetrieve", "ArgList"); Xen_check_type(Xen_is_integer_or_unbound(arg3), arg3, 3, "XmRenditionRetrieve", "int"); { /* this is a kind of XtGetvalues, not set */ Arg *args; unsigned long *locs; Xen val; int i, len, gcloc; XmRendition r; Xen arg2; arg2 = Xen_copy_arg(larg2); gcloc = xm_protect(arg2); /* here we need to make sure the ref args are ok from C's point of view */ r = Xen_to_C_XmRendition(arg1); len = Xen_to_C_INT_DEF(arg3, arg2); if (len <= 0) Xen_check_type(0, arg3, 3, "XmRenditionRetrieve", "positive integer"); args = (Arg *)calloc(len, sizeof(Arg)); locs = (unsigned long *)calloc(len, sizeof(unsigned long)); for (i = 0; i < len; i++, arg2 = Xen_cddr(arg2)) { char *name; name = xen_strdup(Xen_string_to_C_string(Xen_car(arg2))); XtSetArg(args[i], name, &(locs[i])); } XmRenditionRetrieve(r, args, len); val = C_to_Xen_Args((Widget)r, args, len); free_args(args, len); free(locs); xm_unprotect_at(gcloc); return(val); } } static Xen gxm_XmRenditionUpdate(Xen arg1, Xen arg2, Xen arg3) { #define H_XmRenditionUpdate "void XmRenditionUpdate(XmRendition rendition, ArgList arglist, Cardinal argcount) \ modifies resources" Xen_check_type(Xen_is_XmRendition(arg1), arg1, 1, "XmRenditionUpdate", "XmRendition"); Xen_check_type(Xen_is_list(arg2), arg2, 2, "XmRenditionUpdate", "ArgList"); Xen_check_type(Xen_is_integer_or_unbound(arg3), arg3, 3, "XmRenditionUpdate", "int"); { Arg *args; int arglen; args = Xen_to_C_Args(arg2); arglen = Xen_to_C_INT_DEF(arg3, arg2); XmRenditionUpdate(Xen_to_C_XmRendition(arg1), args, arglen); if (args) free_args(args, arglen); } return(Xen_false); } static Xen gxm_XmRenderTableCvtToProp(Xen arg1, Xen arg2) { #define H_XmRenderTableCvtToProp "unsigned int XmRenderTableCvtToProp(Widget widget, XmRenderTable table) \ converts a render table to a string representation -> (val props)" /* DIFF: XmRenderTableCvtToProp omits and rtns arg3 */ char *buf; unsigned int val; Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmRenderTableCvtToProp", "Widget"); Xen_check_type(Xen_is_XmRenderTable(arg2), arg2, 2, "XmRenderTableCvtToProp", "XmRenderTable"); val = XmRenderTableCvtToProp(Xen_to_C_Widget(arg1), Xen_to_C_XmRenderTable(arg2), &buf); return(Xen_list_2(C_ulong_to_Xen_ulong(val), C_string_to_Xen_string(buf))); } static Xen gxm_XmRenderTableCvtFromProp(Xen arg1, Xen arg2, Xen arg3) { char *str; int len; #define H_XmRenderTableCvtFromProp "XmRenderTable XmRenderTableCvtFromProp(Widget widget, char *property, unsigned int length) \ converts from a string representation to a render table" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmRenderTableCvtFromProp", "Widget"); Xen_check_type(Xen_is_string(arg2), arg2, 2, "XmRenderTableCvtFromProp", "char*"); Xen_check_type(Xen_is_ulong(arg3), arg3, 3, "XmRenderTableCvtFromProp", "unsigned int"); str = (char *)Xen_string_to_C_string(arg2); len = Xen_ulong_to_C_ulong(arg3); if ((str) && ((int)strlen(str) == len)) return(C_to_Xen_XmRenderTable(XmRenderTableCvtFromProp(Xen_to_C_Widget(arg1), str, len))); return(Xen_false); } static Xen gxm_XmTabListInsertTabs(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmTabListInsertTabs "XmTabList XmTabListInsertTabs(XmTabList oldlist, XmTab *tabs, Cardinal tab_count, int position) \ inserts tabs into a tab list" /* DIFF: XmTabListInsertTabs arg2 is list of XmTabs (can be #f = NULL) */ int len, listlen = 0; XmTab *tabs; XmTabList tl; Xen_check_type(Xen_is_XmTabList(arg1) || Xen_is_false(arg1), arg1, 1, "XmTabListInsertTabs", "XmTabList"); Xen_check_type(Xen_is_list(arg2), arg2, 2, "XmTabListInsertTabs", "list of XmTab"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XmTabListInsertTabs", "int"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XmTabListInsertTabs", "int"); listlen = Xen_list_length(arg2); len = Xen_integer_to_C_int(arg3); if (len > listlen) len = listlen; if (len <= 0) return(Xen_false); tabs = Xen_to_C_XmTabs(arg2, len); tl = XmTabListInsertTabs(Xen_is_false(arg1) ? NULL : Xen_to_C_XmTabList(arg1), tabs, len, Xen_integer_to_C_int(arg4)); free(tabs); return(C_to_Xen_XmTabList(tl)); } static Xen gxm_XmTabListCopy(Xen arg1, Xen arg2, Xen arg3) { #define H_XmTabListCopy "XmTabList XmTabListCopy(XmTabList tablist, int offset, Cardinal count) creates \ a new tab list from an existing list" /* Motif documentation incorrectly calls this "XmTabListTabCopy" */ Xen_check_type(Xen_is_XmTabList(arg1), arg1, 1, "XmTabListCopy", "XmTabList"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmTabListCopy", "int"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XmTabListCopy", "int"); return(C_to_Xen_XmTabList(XmTabListCopy(Xen_to_C_XmTabList(arg1), Xen_integer_to_C_int(arg2), Xen_integer_to_C_int(arg3)))); } static Xen gxm_XmTabListTabCount(Xen arg1) { #define H_XmTabListTabCount "Cardinal XmTabListTabCount(XmTabList tablist): returns length of tablist" Xen_check_type(Xen_is_XmTabList(arg1), arg1, 1, "XmTabListTabCount", "XmTabList"); return(C_int_to_Xen_integer(XmTabListTabCount(Xen_to_C_XmTabList(arg1)))); } static Xen gxm_XmTabListGetTab(Xen arg1, Xen arg2) { #define H_XmTabListGetTab "XmTab XmTabListGetTab(XmTabList tablist, Cardinal position): returns a copy of a tab" Xen_check_type(Xen_is_XmTabList(arg1), arg1, 1, "XmTabListGetTab", "XmTabList"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmTabListGetTab", "int"); return(C_to_Xen_XmTab(XmTabListGetTab(Xen_to_C_XmTabList(arg1), Xen_integer_to_C_int(arg2)))); } static Xen gxm_XmTabListReplacePositions(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmTabListReplacePositions "XmTabList XmTabListReplacePositions(XmTabList oldlist, Cardinal *position_list, XmTab *tabs, Cardinal tab_count) \ creates a new tab list with replacement tabs" /* DIFF: XmTabListReplacePositions arg2 is list of ints, arg3 is list of XmTabs */ Cardinal *ts; int len; Xen res; XmTab *tabs; Xen_check_type(Xen_is_XmTabList(arg1), arg1, 1, "XmTabListReplacePositions", "XmTabList"); Xen_check_type(Xen_is_list(arg2), arg2, 2, "XmTabListReplacePositions", "list of ints"); Xen_check_type(Xen_is_list(arg3), arg3, 3, "XmTabListReplacePositions", "list of XmTab"); Xen_check_type(Xen_is_integer_or_unbound(arg4), arg4, 4, "XmTabListReplacePositions", "int"); if (Xen_is_integer(arg4)) len = Xen_integer_to_C_int(arg4); else len = Xen_list_length(arg3); if (len <= 0) return(Xen_false); ts = Xen_to_C_Cardinals(arg2, len); tabs = Xen_to_C_XmTabs(arg3, len); res = C_to_Xen_XmTabList(XmTabListReplacePositions(Xen_to_C_XmTabList(arg1), ts, tabs, len)); free(ts); free(tabs); return(res); } static Xen gxm_XmTabListRemoveTabs(Xen arg1, Xen arg2, Xen arg3) { #define H_XmTabListRemoveTabs "XmTabList XmTabListRemoveTabs(XmTabList oldlist, Cardinal *position_list, Cardinal position_count) \ removes noncontiguous tabs" /* DIFF: XmTabListRemoveTabs arg2 is list of ints */ Cardinal *ts; int len; Xen res; Xen_check_type(Xen_is_XmTabList(arg1), arg1, 1, "XmTabListRemoveTabs", "XmTabList"); Xen_check_type(Xen_is_list(arg2), arg2, 2, "XmTabListRemoveTabs", "list of int"); Xen_check_type(Xen_is_integer_or_unbound(arg3), arg3, 3, "XmTabListRemoveTabs", "int"); if (Xen_is_integer(arg3)) len = Xen_integer_to_C_int(arg3); else len = Xen_list_length(arg2); if (len <= 0) return(Xen_false); ts = Xen_to_C_Cardinals(arg2, len); res = C_to_Xen_XmTabList(XmTabListRemoveTabs(Xen_to_C_XmTabList(arg1), ts, len)); free(ts); return(res); } static Xen gxm_XmTabCreate(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5) { #define H_XmTabCreate "XmTab XmTabCreate(float value, unsigned char units, XmOffsetModel offset_model, unsigned char alignment, char *decimal) \ creates a tab stop" Xen_check_type(Xen_is_double(arg1), arg1, 1, "XmTabCreate", "float"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmTabCreate", "unsigned char"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XmTabCreate", "XmOffsetModel"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XmTabCreate", "unsigned char"); Xen_check_type(Xen_is_string(arg5), arg5, 5, "XmTabCreate", "char*"); return(C_to_Xen_XmTab(XmTabCreate((float)Xen_real_to_C_double(arg1), (unsigned char)(Xen_integer_to_C_int(arg2)), (XmOffsetModel)Xen_integer_to_C_int(arg3), (unsigned char)(Xen_integer_to_C_int(arg4)), (char *)Xen_string_to_C_string(arg5)))); } static Xen gxm_XmTabListFree(Xen arg1) { #define H_XmTabListFree "void XmTabListFree(XmTabList tab) frees a tab list" Xen_check_type(Xen_is_XmTabList(arg1), arg1, 1, "XmTabListFree", "XmTabList"); XmTabListFree(Xen_to_C_XmTabList(arg1)); return(Xen_false); } static Xen gxm_XmTabFree(Xen arg1) { #define H_XmTabFree "void XmTabFree(XmTab tab) frees a tab" Xen_check_type(Xen_is_XmTab(arg1), arg1, 1, "XmTabFree", "XmTab"); XmTabFree(Xen_to_C_XmTab(arg1)); return(Xen_false); } static Xen gxm_XmTabGetValues(Xen arg1) { #define H_XmTabGetValues "float XmTabGetValues(XmTab tab): returns tab values" /* DIFF: XmTabGetValues tab [units offset align decimal] -> (list val units ofset align decimal) arg2/3/4/5 omit rtn with float */ XmOffsetModel off; unsigned char a1, a2; char **a3; float res; Xen val; Xen_check_type(Xen_is_XmTab(arg1), arg1, 1, "XmTabGetValues", "XmTab"); a3 = (char **)calloc(1, sizeof(char *)); res = XmTabGetValues(Xen_to_C_XmTab(arg1), &a1, &off, &a2, a3); val = Xen_list_5(C_double_to_Xen_real((double)res), C_int_to_Xen_integer((int)a1), C_int_to_Xen_integer((int)off), C_int_to_Xen_integer((int)a2), C_string_to_Xen_string(a3[0])); free(a3); return(val); } static Xen gxm_XmTabSetValue(Xen arg1, Xen arg2) { #define H_XmTabSetValue "void XmTabSetValue(XmTab tab, float value) sets a tab stop" Xen_check_type(Xen_is_XmTab(arg1), arg1, 1, "XmTabSetValue", "XmTab"); Xen_check_type(Xen_is_double(arg2), arg2, 2, "XmTabSetValue", "float"); XmTabSetValue(Xen_to_C_XmTab(arg1), (float)Xen_real_to_C_double(arg2)); return(Xen_false); } static Xen gxm_XmStringTableProposeTablist(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5) { #define H_XmStringTableProposeTablist "XmTabList XmStringTableProposeTablist(XmStringTable strings, Cardinal num_strings, Widget widget, \ float pad_value, XmOffsetModel offset_model): returns a tab list" /* DIFF: XmStringTableProposetablist first arg is list of XmStrings */ XmStringTable tab; XmTabList tabl; Xen_check_type(Xen_is_list(arg1), arg1, 1, "XmStringTableProposeTablist", "XmStringTable"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmStringTableProposeTablist", "int"); Xen_check_type(Xen_is_Widget(arg3), arg3, 3, "XmStringTableProposeTablist", "Widget"); Xen_check_type(Xen_is_double(arg4), arg4, 4, "XmStringTableProposeTablist", "float"); Xen_check_type(Xen_is_integer(arg5), arg5, 5, "XmStringTableProposeTablist", "XmOffsetModel"); tab = Xen_to_C_XmStringTable(arg1, Xen_integer_to_C_int(arg2)); tabl = XmStringTableProposeTablist(tab, Xen_integer_to_C_int(arg2), Xen_to_C_Widget(arg3), (float)Xen_real_to_C_double(arg4), (XmOffsetModel)Xen_integer_to_C_int(arg5)); free(tab); return(C_to_Xen_XmTabList(tabl)); } #define Xen_is_XmParseTable(Arg) Xen_is_list(Arg) static XmParseTable Xen_to_C_XmParseTable(Xen lst, int size) { int i; XmParseTable pt; if (size <= 0) return(NULL); pt = (XmParseTable)XtCalloc(size, sizeof(XmParseMapping)); for (i = 0; i < size; i++) { Xen val; val = Xen_list_ref(lst, i); if (Xen_is_XmParseMapping(val)) pt[i] = Xen_to_C_XmParseMapping(val); else Xen_check_type(0, val, i, __func__, "an XmParseMapping"); } return(pt); } static Xen gxm_XmParseTableFree(Xen arg1, Xen arg2) { #define H_XmParseTableFree "void XmParseTableFree(XmParseTable parse_table, Cardinal count) recovers memory" Xen_check_type(Xen_is_XmParseTable(arg1), arg1, 1, "XmParseTableFree", "XmParseTable"); Xen_check_type(Xen_is_integer_or_unbound(arg2), arg2, 2, "XmParseTableFree", "int"); /* can't happen -- a no-op */ return(Xen_false); } static Xen gxm_XmParseMappingFree(Xen arg1) { #define H_XmParseMappingFree "void XmParseMappingFree(XmParseMapping parse_mapping) frees a parse mapping" Xen_check_type(Xen_is_XmParseMapping(arg1), arg1, 1, "XmParseMappingFree", "XmParseMapping"); XmParseMappingFree(Xen_to_C_XmParseMapping(arg1)); return(Xen_false); } static Xen gxm_XmParseMappingGetValues(Xen arg1, Xen larg2, Xen arg3) { #define H_XmParseMappingGetValues "void XmParseMappingGetValues(XmParseMapping parse_mapping, ArgList arglist, Cardinal argcount) \ retrieves attributes of a parse mapping" Xen_check_type(Xen_is_XmParseMapping(arg1), arg1, 1, "XmParseMappingGetValues", "XmParseMapping"); Xen_check_type(Xen_is_list(larg2), larg2, 2, "XmParseMappingGetValues", "ArgList"); Xen_check_type(Xen_is_integer_or_unbound(arg3), arg3, 3, "XmParseMappingGetValues", "int"); { Arg *args; unsigned long *locs; int len, gcloc; Xen val, arg2; int i; len = Xen_to_C_INT_DEF(arg3, larg2); arg2 = Xen_copy_arg(larg2); gcloc = xm_protect(arg2); args = (Arg *)calloc(len, sizeof(Arg)); locs = (unsigned long *)calloc(len, sizeof(unsigned long)); for (i = 0; i < len; i++, arg2 = Xen_cddr(arg2)) { char *name; name = xen_strdup(Xen_string_to_C_string(Xen_car(arg2))); XtSetArg(args[i], name, &(locs[i])); } XmParseMappingGetValues(Xen_to_C_XmParseMapping(arg1), args, len); val = C_to_Xen_Args(NULL, args, len); free_args(args, len); free(locs); xm_unprotect_at(gcloc); return(val); } } static Xen gxm_XmParseMappingSetValues(Xen arg1, Xen arg2, Xen arg3) { #define H_XmParseMappingSetValues "void XmParseMappingSetValues(XmParseMapping parse_mapping, ArgList arglist, Cardinal argcount) \ sets attributes of a parse mapping" Xen_check_type(Xen_is_XmParseMapping(arg1), arg1, 1, "XmParseMappingSetValues", "XmParseMapping"); Xen_check_type(Xen_is_list(arg2), arg2, 2, "XmParseMappingSetValues", "ArgList"); Xen_check_type(Xen_is_integer_or_unbound(arg3), arg3, 3, "XmParseMappingSetValues", "int"); { Arg *args; int arglen; args = Xen_to_C_Args(arg2); arglen = Xen_to_C_INT_DEF(arg3, arg2); XmParseMappingSetValues(Xen_to_C_XmParseMapping(arg1), args, arglen); if (args) free_args(args, arglen); return(Xen_false); } } static Xen gxm_XmParseMappingCreate(Xen arg1, Xen arg2) { #define H_XmParseMappingCreate "XmParseMapping XmParseMappingCreate(ArgList arglist, Cardinal argcount) create a parse mapping" XmParseMapping w; Xen_check_type(Xen_is_list(arg1), arg1, 1, "XmParseMappingCreate", "ArgList"); Xen_check_type(Xen_is_integer_or_unbound(arg2), arg2, 2, "XmParseMappingCreate", "int"); { Arg *args; int arglen; args = Xen_to_C_Args(arg1); arglen = Xen_to_C_INT_DEF(arg2, arg1); w = XmParseMappingCreate(args, arglen); if (args) free_args(args, arglen); } return(C_to_Xen_XmParseMapping(w)); } static Xen gxm_XmCvtXmStringToByteStream(Xen str) { #define H_XmCvtXmStringToByteStream "int XmCvtXmStringToByteStream(XmString str) converts an XmString into a byte stream." unsigned char *prop = NULL; int res = 0; /* #bytes in returned val */ XmString xstr; Xen_check_type(Xen_is_XmString(str), str, 1, "XmCvtXmStringToByteStream", "XmString"); xstr = Xen_to_C_XmString(str); if (!(XmStringEmpty(xstr))) res = XmCvtXmStringToByteStream(xstr, &prop); /* here there is apparently no trailing 0, so this function worries Valgrind */ return(Xen_list_2(C_int_to_Xen_integer(res), C_string_to_Xen_string((const char *)prop))); } static Xen gxm_XmCvtByteStreamToXmString(Xen str) { #define H_XmCvtByteStreamToXmString "XmString XmCvtByteStreamToXmString(char *str) converts a byte stream into an XmString." XmString res = NULL; const char *bstr; Xen_check_type(Xen_is_string(str), str, 1, "XmCvtByteStreamToXmString", "char *"); bstr = Xen_string_to_C_string(str); if (bstr) res = XmCvtByteStreamToXmString((unsigned char *)(Xen_string_to_C_string(str))); return(C_to_Xen_XmString(res)); } static Xen gxm_XmStringByteStreamLength(Xen str) { #define H_XmStringByteStreamLength "int XmStringByteStreamLength(char *str): returns the length of the byte stream." unsigned char *stream; Xen_check_type(Xen_is_string(str), str, 1, "XmStringByteStreamLength", "char *"); stream = (unsigned char *)(Xen_string_to_C_string(str)); if (!stream) Xen_out_of_range_error("XmStringByteStreamLength", 1, str, "a null stream?"); return(C_int_to_Xen_integer((int)XmStringByteStreamLength(stream))); } static Xen gxm_XmStringPutRendition(Xen arg1, Xen arg2) { #define H_XmStringPutRendition "XmString XmStringPutRendition(XmString string, XmStringTag rendition) places \ renditions around strings" Xen_check_type(Xen_is_XmString(arg1), arg1, 1, "XmStringPutRendition", "XmString"); Xen_check_type(Xen_is_string(arg2), arg2, 2, "XmStringPutRendition", "XmStringTag"); return(C_to_Xen_XmString(XmStringPutRendition(Xen_to_C_XmString(arg1), (char *)Xen_string_to_C_string(arg2)))); } static Xen gxm_XmStringGenerate(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmStringGenerate "XmString XmStringGenerate(XtPointer text, XmStringTag tag, XmTextType type, XmStringTag rendition) \ generates a compound string" XmTextType type; XmStringTag rendition; Xen_check_type(Xen_is_string(arg1), arg1, 1, "XmStringGenerate", "XtPointer"); Xen_check_type(Xen_is_string(arg2) || Xen_is_false(arg2), arg2, 2, "XmStringGenerate", "XmStringTag"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XmStringGenerate", "XmTextType"); Xen_check_type(Xen_is_string(arg4), arg4, 4, "XmStringGenerate", "XmStringTag"); type = (XmTextType)Xen_integer_to_C_int(arg3); if (type > 1) Xen_check_type(0, arg3, 3, "XmStringGenerate", "XmTextType"); rendition = (XmStringTag)Xen_string_to_C_string(arg4); if (!rendition) Xen_out_of_range_error("XmStringGenerate", 4, arg4, "a null rendition?"); return(C_to_Xen_XmString(XmStringGenerate((XtPointer)Xen_string_to_C_string(arg1), Xen_is_false(arg2) ? NULL : (char *)Xen_string_to_C_string(arg2), type, rendition))); } static Xen gxm_XmStringDirectionToDirection(Xen arg1) { #define H_XmStringDirectionToDirection "XmDirection XmStringDirectionToDirection(XmStringDirection direction) converts \ from XmStringDirection to XmDirection" Xen_check_type(Xen_is_integer(arg1), arg1, 1, "XmStringDirectionToDirection", "XmStringDirection"); return(C_int_to_Xen_integer(XmStringDirectionToDirection(Xen_integer_to_C_int(arg1)))); } static Xen gxm_XmDirectionToStringDirection(Xen arg1) { #define H_XmDirectionToStringDirection "XmStringDirection XmDirectionToStringDirection (dir) converts an XmDirection \ value to an XmStringDirection value" Xen_check_type(Xen_is_integer(arg1), arg1, 1, "XmDirectionToStringDirection", "XmDirection"); return(C_int_to_Xen_integer(XmDirectionToStringDirection(Xen_integer_to_C_int(arg1)))); } static Xen gxm_XmStringTableParseStringArray(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6, Xen arg7) { #define H_XmStringTableParseStringArray "XmStringTable XmStringTableParseStringArray(XtPointer *strings, Cardinal count, XmStringTag tag, \ XmTextType type, XmParseTable parse, Cardinal parse_count, XtPointer call_data) converts an array of strings \ to a compound string table" /* DIFF: XmStringTableParseStringArray arg1 is list of strings */ char **strs; int len; XmStringTable val; XmParseTable pt = NULL; Xen lst; XmTextType type; Xen_check_type(Xen_is_list(arg1), arg1, 1, "XmStringTableParseStringArray", "list of strings"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmStringTableParseStringArray", "int"); Xen_check_type(Xen_is_false(arg3) || Xen_is_string(arg3), arg3, 3, "XmStringTableParseStringArray", "XmStringTag"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XmStringTableParseStringArray", "XmTextType"); Xen_check_type(Xen_is_false(arg5) || Xen_is_XmParseTable(arg5), arg5, 5, "XmStringTableParseStringArray", "XmParseTable"); Xen_check_type(Xen_is_integer(arg6), arg6, 6, "XmStringTableParseStringArray", "int"); type = (XmTextType)Xen_integer_to_C_int(arg4); if (type > 1) Xen_check_type(0, arg4, 4, "XmStringTableParseStringArray", "XmTextType"); len = Xen_integer_to_C_int(arg2); if (len <= 0) return(Xen_false); strs = Xen_to_C_Strings(arg1, len); if (Xen_is_XmParseTable(arg5)) pt = Xen_to_C_XmParseTable(arg5, len); val = XmStringTableParseStringArray((XtPointer *)strs, (Cardinal)len, (Xen_is_false(arg3)) ? NULL : (char *)Xen_string_to_C_string(arg3), type, pt, Xen_integer_to_C_int(arg6), (XtPointer)arg7); free(strs); lst = C_to_Xen_XmStringTable(val, len); free(val); if (pt) free(pt); return(lst); } static Xen gxm_XmStringTableUnparse(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6, Xen arg7, Xen arg8) { #define H_XmStringTableUnparse "XtPointer *XmStringTableUnparse(XmStringTable table, Cardinal count, XmStringTag tag, XmTextType tag_type, \ XmTextType output_type, XmParseTable parse, Cardinal parse_count, XmParseModel parse_model) converts a table of \ compound strings to an array of text" /* DIFF: XmStringTableUnparse returns list of strings, first arg is list of XmStrings */ Xen lst = Xen_empty_list; char **tab; XmStringTable tb; int i, len, loc; XmTextType type1, type2; XmParseTable pt = NULL; Xen_check_type(Xen_is_list(arg1), arg1, 1, "XmStringTableUnparse", "XmStringTable"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmStringTableUnparse", "int"); Xen_check_type(Xen_is_false(arg3) || Xen_is_string(arg3), arg3, 3, "XmStringTableUnparse", "XmStringTag"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XmStringTableUnparse", "XmTextType"); Xen_check_type(Xen_is_integer(arg5), arg5, 5, "XmStringTableUnparse", "XmTextType"); Xen_check_type(Xen_is_false(arg6) || Xen_is_XmParseTable(arg6), arg6, 6, "XmStringTableUnparse", "XmParseTable"); Xen_check_type(Xen_is_integer(arg7), arg7, 7, "XmStringTableUnparse", "int"); Xen_check_type(Xen_is_integer(arg8), arg8, 8, "XmStringTableUnparse", "XmParseModel"); type1 = (XmTextType)Xen_integer_to_C_int(arg4); if (type1 > 1) Xen_check_type(0, arg4, 4, "XmStringTableUnparse", "XmTextType"); type2 = (XmTextType)Xen_integer_to_C_int(arg5); if (type2 > 1) Xen_check_type(0, arg5, 5, "XmStringTableUnparse", "XmTextType"); len = Xen_integer_to_C_int(arg2); if (len <= 0) return(Xen_false); loc = xm_protect(lst); tb = Xen_to_C_XmStringTable(arg1, len); if (Xen_is_XmParseTable(arg6)) pt = Xen_to_C_XmParseTable(arg6, len); tab = (char **)XmStringTableUnparse(tb, len, (Xen_is_false(arg3)) ? NULL : (char *)Xen_string_to_C_string(arg3), type1, type2, pt, Xen_integer_to_C_int(arg7), (XmParseModel)Xen_integer_to_C_int(arg8)); free(tb); for (i = len - 1; i >= 0; i--) { lst = Xen_cons(C_string_to_Xen_string(tab[i]), lst); free(tab[i]); } free(tab); if (pt) free(pt); xm_unprotect_at(loc); return(lst); } static Xen gxm_XmStringTableToXmString(Xen arg1, Xen arg2, Xen arg3) { #define H_XmStringTableToXmString "XmString XmStringTableToXmString(XmStringTable table, Cardinal count, XmString break_component) \ converts a compound string table to a single compound string" /* DIFF: XmStringTableToXmString first arg is list of XmStrings */ int count; XmStringTable tab; XmString val; Xen_check_type(Xen_is_list(arg1), arg1, 1, "XmStringTableToXmString", "XmStringTable"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmStringTableToXmString", "int"); Xen_check_type(Xen_is_XmString(arg3) || Xen_is_false(arg3), arg3, 3, "XmStringTableToXmString", "XmString"); count = Xen_integer_to_C_int(arg2); if (count <= 0) return(Xen_false); tab = Xen_to_C_XmStringTable(arg1, count); val = XmStringTableToXmString(tab, count, (Xen_is_XmString(arg3)) ? Xen_to_C_XmString(arg3) : NULL); free(tab); return(C_to_Xen_XmString(val)); } static Xen gxm_XmStringToXmStringTable(Xen arg1, Xen arg2) { #define H_XmStringToXmStringTable "Cardinal XmStringToXmStringTable(XmString string, XmString break_component) \ converts a single compound string to a table of compound strings" /* DIFF: XmStringToXmStringTable omits and rtns (list len table) */ XmStringTable tab; Cardinal val; Xen_check_type(Xen_is_XmString(arg1), arg1, 1, "XmStringToXmStringTable", "XmString"); Xen_check_type(Xen_is_XmString(arg2) || Xen_is_false(arg2), arg2, 2, "XmStringToXmStringTable", "XmString"); val = XmStringToXmStringTable(Xen_to_C_XmString(arg1), (Xen_is_XmString(arg2)) ? Xen_to_C_XmString(arg2) : NULL, &tab); return(Xen_list_2(C_int_to_Xen_integer(val), C_to_Xen_XmStringTable(tab, val))); } static Xen gxm_XmStringParseText(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6, Xen arg7) { #define H_XmStringParseText "XmString XmStringParseText(XtPointer text, XtPointer *text_end, XmStringTag tag, XmTextType type, \ XmParseTable parse_table, Cardinal parse_count, XtPointer call_data) converts a character string to a compound string" /* DIFF: XmStringParseText arg1 is string, arg2 is int */ int len; const char *str, *tag = NULL; XmTextType type; XtPointer *intext = NULL; XmParseTable pt = NULL; Xen rtn; Xen_check_type(Xen_is_string(arg1), arg1, 1, "XmStringParseText", "string"); Xen_check_type(Xen_is_integer(arg2) || Xen_is_false(arg2), arg2, 2, "XmStringParseText", "int"); Xen_check_type(Xen_is_string(arg3) || Xen_is_false(arg3), arg3, 3, "XmStringParseText", "XmStringTag"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XmStringParseText", "XmTextType"); Xen_check_type(Xen_is_XmParseTable(arg5), arg5, 5, "XmStringParseText", "XmParseTable"); Xen_check_type(Xen_is_integer(arg6), arg6, 6, "XmStringParseText", "int"); type = (XmTextType)Xen_integer_to_C_int(arg4); if (type > 1) Xen_check_type(0, arg4, 4, "XmStringParseText", "XmTextType"); str = Xen_string_to_C_string(arg1); if (Xen_is_integer(arg2)) { int loc; loc = Xen_integer_to_C_int(arg2); intext = (XtPointer *)(str + loc); } if (Xen_is_string(arg3)) tag = Xen_string_to_C_string(arg3); len = Xen_integer_to_C_int(arg6); if (Xen_is_XmParseTable(arg5)) pt = Xen_to_C_XmParseTable(arg5, len); rtn = C_to_Xen_XmString(XmStringParseText((char *)str, intext, (char *)tag, type, pt, len, (XtPointer)arg7)); if (pt) free(pt); return(rtn); } static Xen gxm_XmStringUnparse(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6, Xen arg7) { #define H_XmStringUnparse "XtPointer XmStringUnparse(XmString string, XmStringTag tag, XmTextType tag_type, XmTextType output_type, \ XmParseTable parse_table, Cardinal parse_count, XmParseModel parse_model) unparses text" XmTextType type1, type2; Xen rtn; char *str; XmParseTable pt = NULL; int len; Xen_check_type(Xen_is_XmString(arg1), arg1, 1, "XmStringUnparse", "XmString"); Xen_check_type(Xen_is_string(arg2) || Xen_is_false(arg2), arg2, 2, "XmStringUnparse", "XmStringTag or " PROC_FALSE); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XmStringUnparse", "XmTextType"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XmStringUnparse", "XmTextType"); Xen_check_type(Xen_is_XmParseTable(arg5) || Xen_is_false(arg5), arg5, 5, "XmStringUnparse", "XmParseTable"); Xen_check_type(Xen_is_integer(arg6), arg6, 6, "XmStringUnparse", "int"); Xen_check_type(Xen_is_integer(arg7), arg7, 7, "XmStringUnparse", "XmParseModel"); type1 = (XmTextType)Xen_integer_to_C_int(arg3); if (type1 > 1) Xen_check_type(0, arg3, 3, "XmStringUnparse", "XmTextType"); type2 = (XmTextType)Xen_integer_to_C_int(arg4); if (type2 > 1) Xen_check_type(0, arg4, 4, "XmStringUnparse", "XmTextType"); len = Xen_integer_to_C_int(arg6); if (Xen_is_XmParseTable(arg5)) pt = Xen_to_C_XmParseTable(arg5, len); str = (char *)XmStringUnparse(Xen_to_C_XmString(arg1), (Xen_is_string(arg2)) ? (char *)Xen_string_to_C_string(arg2) : NULL, type1, type2, pt, len, (XmParseModel)Xen_integer_to_C_int(arg7)); rtn = C_string_to_Xen_string(str); if (str) XtFree(str); if (pt) free(pt); return(rtn); } static Xen gxm_XmStringComponentCreate(Xen arg1, Xen arg2, Xen arg3) { #define H_XmStringComponentCreate "XmString XmStringComponentCreate(XmStringComponentType c_type, unsigned int length, XtPointer value) \ creates arbitrary components" Xen_check_type(Xen_is_integer(arg1), arg1, 1, "XmStringComponentCreate", "XmStringComponentType"); Xen_check_type(Xen_is_ulong(arg2), arg2, 2, "XmStringComponentCreate", "unsigned int"); Xen_check_type(Xen_is_string(arg3) || Xen_is_false(arg3), arg3, 3, "XmStringComponentCreate", "XtPointer"); return(C_to_Xen_XmString(XmStringComponentCreate(Xen_integer_to_C_int(arg1), Xen_ulong_to_C_ulong(arg2), Xen_is_false(arg3) ? NULL : (char *)Xen_string_to_C_string(arg3)))); } static Xen gxm_XmStringGetNextTriple(Xen arg1) { #define H_XmStringGetNextTriple "XmStringComponentType XmStringGetNextTriple(XmStringContext context) \ returns the type, length, and value of the next component in the compound string" /* DIFF: XmStringGetNextTriple omits last 2 args, returns val */ unsigned int len; int val; XtPointer *ptr = NULL; Xen_check_type(Xen_is_XmStringContext(arg1), arg1, 1, "XmStringGetNextTriple", "XmStringContext"); val = XmStringGetNextTriple(Xen_to_C_XmStringContext(arg1), &len, ptr); return(Xen_list_3(C_int_to_Xen_integer(val), C_int_to_Xen_integer((int)len), (val == XmSTRING_COMPONENT_TEXT) ? C_string_to_Xen_string((char *)(*ptr)) : Xen_wrap_C_pointer(ptr))); } static Xen gxm_XmStringPeekNextTriple(Xen arg1) { #define H_XmStringPeekNextTriple "XmStringComponentType XmStringPeekNextTriple(XmStringContext context): returns the \ component type of the next component" Xen_check_type(Xen_is_XmStringContext(arg1), arg1, 1, "XmStringPeekNextTriple", "XmStringContext"); return(C_int_to_Xen_integer(XmStringPeekNextTriple(Xen_to_C_XmStringContext(arg1)))); } static Xen gxm_XmStringDrawUnderline(Xen args) { #define H_XmStringDrawUnderline "void XmStringDrawUnderline(Display *d, Window w, XmRenderTable rendertable, XmString string, GC gc, \ Position x, Position y, Dimension width, unsigned char alignment, unsigned char layout_direction, XRectangle *clip, XmString underline) \ underlines a string drawn in an X Window" Xen arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12; arg1 = Xen_list_ref(args, 0); arg2 = Xen_list_ref(args, 1); arg3 = Xen_list_ref(args, 2); arg4 = Xen_list_ref(args, 3); arg5 = Xen_list_ref(args, 4); arg6 = Xen_list_ref(args, 5); arg7 = Xen_list_ref(args, 6); arg8 = Xen_list_ref(args, 7); arg9 = Xen_list_ref(args, 8); arg10 = Xen_list_ref(args, 9); arg11 = Xen_list_ref(args, 10); arg12 = Xen_list_ref(args, 11); Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XmStringDrawUnderline", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XmStringDrawUnderline", "Window"); Xen_check_type(Xen_is_XmFontList_or_XmRenderTable(arg3), arg3, 3, "XmStringDrawUnderline", "XmFontList"); Xen_check_type(Xen_is_XmString(arg4), arg4, 4, "XmStringDrawUnderline", "XmString"); Xen_check_type(Xen_is_GC(arg5), arg5, 5, "XmStringDrawUnderline", "GC"); Xen_check_type(Xen_is_integer(arg6), arg6, 6, "XmStringDrawUnderline", "int"); Xen_check_type(Xen_is_integer(arg7), arg7, 7, "XmStringDrawUnderline", "int"); Xen_check_type(Xen_is_integer(arg8), arg8, 8, "XmStringDrawUnderline", "int"); Xen_check_type(Xen_is_ulong(arg9), arg9, 9, "XmStringDrawUnderline", "unsigned int"); Xen_check_type(Xen_is_ulong(arg10), arg10, 10, "XmStringDrawUnderline", "unsigned int"); Xen_check_type(Xen_is_XRectangle(arg11), arg11, 11, "XmStringDrawUnderline", "XRectangle"); Xen_check_type(Xen_is_XmString(arg12), arg12, 12, "XmStringDrawUnderline", "XmString"); XmStringDrawUnderline(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_to_C_XmFontList(arg3), Xen_to_C_XmString(arg4), Xen_to_C_GC(arg5), Xen_integer_to_C_int(arg6), Xen_integer_to_C_int(arg7), Xen_integer_to_C_int(arg8), Xen_ulong_to_C_ulong(arg9), Xen_ulong_to_C_ulong(arg10), Xen_to_C_XRectangle(arg11), Xen_to_C_XmString(arg12)); return(Xen_false); } static Xen gxm_XmStringDrawImage(Xen args) { #define H_XmStringDrawImage "void XmStringDrawImage(Display *d, Window w, XmRenderTable rendertable, XmString string, GC gc, Position x, \ Position y, Dimension width, unsigned char alignment, unsigned char layout_direction, XRectangle *clip) \ draws a compound string in an X Window and creates an image" Xen arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11; arg1 = Xen_list_ref(args, 0); arg2 = Xen_list_ref(args, 1); arg3 = Xen_list_ref(args, 2); arg4 = Xen_list_ref(args, 3); arg5 = Xen_list_ref(args, 4); arg6 = Xen_list_ref(args, 5); arg7 = Xen_list_ref(args, 6); arg8 = Xen_list_ref(args, 7); arg9 = Xen_list_ref(args, 8); arg10 = Xen_list_ref(args, 9); arg11 = Xen_list_ref(args, 10); Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XmStringDrawImage", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XmStringDrawImage", "Window"); Xen_check_type(Xen_is_XmFontList_or_XmRenderTable(arg3), arg3, 3, "XmStringDrawImage", "XmFontList"); Xen_check_type(Xen_is_XmString(arg4), arg4, 4, "XmStringDrawImage", "XmString"); Xen_check_type(Xen_is_GC(arg5), arg5, 5, "XmStringDrawImage", "GC"); Xen_check_type(Xen_is_integer(arg6), arg6, 6, "XmStringDrawImage", "int"); Xen_check_type(Xen_is_integer(arg7), arg7, 7, "XmStringDrawImage", "int"); Xen_check_type(Xen_is_integer(arg8), arg8, 8, "XmStringDrawImage", "int"); Xen_check_type(Xen_is_ulong(arg9), arg9, 9, "XmStringDrawImage", "unsigned int"); Xen_check_type(Xen_is_ulong(arg10), arg10, 10, "XmStringDrawImage", "unsigned int"); Xen_check_type(Xen_is_XRectangle(arg11), arg11, 11, "XmStringDrawImage", "XRectangle*"); XmStringDrawImage(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_to_C_XmFontList(arg3), Xen_to_C_XmString(arg4), Xen_to_C_GC(arg5), Xen_integer_to_C_int(arg6), Xen_integer_to_C_int(arg7), Xen_integer_to_C_int(arg8), Xen_ulong_to_C_ulong(arg9), Xen_ulong_to_C_ulong(arg10), Xen_to_C_XRectangle(arg11)); return(Xen_false); } static Xen gxm_XmStringDraw(Xen args) { #define H_XmStringDraw "void XmStringDraw(Display *d, Window w, XmRenderTable rendertable, XmString string, GC gc, Position x, Position y, \ Dimension width, unsigned char alignment, unsigned char layout_direction, XRectangle *clip) draws a compound \ string in an X window" Xen arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11; arg1 = Xen_list_ref(args, 0); arg2 = Xen_list_ref(args, 1); arg3 = Xen_list_ref(args, 2); arg4 = Xen_list_ref(args, 3); arg5 = Xen_list_ref(args, 4); arg6 = Xen_list_ref(args, 5); arg7 = Xen_list_ref(args, 6); arg8 = Xen_list_ref(args, 7); arg9 = Xen_list_ref(args, 8); arg10 = Xen_list_ref(args, 9); arg11 = Xen_list_ref(args, 10); Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XmStringDraw", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XmStringDraw", "Window"); Xen_check_type(Xen_is_XmFontList_or_XmRenderTable(arg3), arg3, 3, "XmStringDraw", "XmFontList"); Xen_check_type(Xen_is_XmString(arg4), arg4, 4, "XmStringDraw", "XmString"); Xen_check_type(Xen_is_GC(arg5), arg5, 5, "XmStringDraw", "GC"); Xen_check_type(Xen_is_integer(arg6), arg6, 6, "XmStringDraw", "int"); Xen_check_type(Xen_is_integer(arg7), arg7, 7, "XmStringDraw", "int"); Xen_check_type(Xen_is_integer(arg8), arg8, 8, "XmStringDraw", "int"); Xen_check_type(Xen_is_ulong(arg9), arg9, 9, "XmStringDraw", "unsigned int"); Xen_check_type(Xen_is_ulong(arg10), arg10, 10, "XmStringDraw", "unsigned int"); Xen_check_type(Xen_is_XRectangle(arg11), arg11, 11, "XmStringDraw", "XRectangle*"); XmStringDraw(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_to_C_XmFontList(arg3), Xen_to_C_XmString(arg4), Xen_to_C_GC(arg5), Xen_integer_to_C_int(arg6), Xen_integer_to_C_int(arg7), Xen_integer_to_C_int(arg8), Xen_ulong_to_C_ulong(arg9), Xen_ulong_to_C_ulong(arg10), Xen_to_C_XRectangle(arg11)); return(Xen_false); } static Xen gxm_XmStringLineCount(Xen arg1) { #define H_XmStringLineCount "int XmStringLineCount(XmString string): returns the number of separators plus one \ in the provided compound string" Xen_check_type(Xen_is_XmString(arg1), arg1, 1, "XmStringLineCount", "XmString"); return(C_int_to_Xen_integer(XmStringLineCount(Xen_to_C_XmString(arg1)))); } static Xen gxm_XmStringExtent(Xen arg1, Xen arg2) { #define H_XmStringExtent "void XmStringExtent(XmRenderTable rendertable, XmString string) \ determines the size of the smallest rectangle that will enclose the compound string" /* DIFF: XmStringExtent omits and returns the last 2 args */ Dimension w, h; Xen_check_type(Xen_is_XmFontList_or_XmRenderTable(arg1), arg1, 1, "XmStringExtent", "XmFontList"); Xen_check_type(Xen_is_XmString(arg2), arg2, 2, "XmStringExtent", "XmString"); XmStringExtent(Xen_to_C_XmFontList(arg1), Xen_to_C_XmString(arg2), &w, &h); return(Xen_list_2(C_to_Xen_Dimension(w), C_to_Xen_Dimension(h))); } static Xen gxm_XmStringHeight(Xen arg1, Xen arg2) { #define H_XmStringHeight "Dimension XmStringHeight(XmRenderTable rendertable, XmString string): returns the line \ height of the given compound string" Xen_check_type(Xen_is_XmFontList_or_XmRenderTable(arg1), arg1, 1, "XmStringHeight", "XmFontList"); Xen_check_type(Xen_is_XmString(arg2), arg2, 2, "XmStringHeight", "XmString"); return(C_to_Xen_Dimension(XmStringHeight(Xen_to_C_XmFontList(arg1), Xen_to_C_XmString(arg2)))); } static Xen gxm_XmStringWidth(Xen arg1, Xen arg2) { #define H_XmStringWidth "Dimension XmStringWidth(XmRenderTable rendertable, XmString string): returns \ the width of the widest line in a compound string" Xen_check_type(Xen_is_XmFontList_or_XmRenderTable(arg1), arg1, 1, "XmStringWidth", "XmFontList"); Xen_check_type(Xen_is_XmString(arg2), arg2, 2, "XmStringWidth", "XmString"); return(C_to_Xen_Dimension(XmStringWidth(Xen_to_C_XmFontList(arg1), Xen_to_C_XmString(arg2)))); } static Xen gxm_XmStringBaseline(Xen arg1, Xen arg2) { #define H_XmStringBaseline "Dimension XmStringBaseline(XmRenderTable rendertable, XmString string): returns \ the number of pixels between \ the top of the character box and the baseline of the first line of text" Xen_check_type(Xen_is_XmFontList_or_XmRenderTable(arg1), arg1, 1, "XmStringBaseline", "XmFontList"); Xen_check_type(Xen_is_XmString(arg2), arg2, 2, "XmStringBaseline", "XmString"); return(C_to_Xen_Dimension(XmStringBaseline(Xen_to_C_XmFontList(arg1), Xen_to_C_XmString(arg2)))); } static Xen gxm_XmStringFree(Xen arg1) { #define H_XmStringFree "void XmStringFree(XmString string) conditionally deallocates memory" Xen_check_type(Xen_is_XmString(arg1), arg1, 1, "XmStringFree", "XmString"); XmStringFree(Xen_to_C_XmString(arg1)); return(Xen_false); } static Xen gxm_XmStringHasSubstring(Xen arg1, Xen arg2) { #define H_XmStringHasSubstring "Boolean XmStringHasSubstring(XmString string, XmString substring) indicates \ whether one compound string is contained within another" Xen_check_type(Xen_is_XmString(arg1), arg1, 1, "XmStringHasSubstring", "XmString"); Xen_check_type(Xen_is_XmString(arg2), arg2, 2, "XmStringHasSubstring", "XmString"); return(C_bool_to_Xen_boolean(XmStringHasSubstring(Xen_to_C_XmString(arg1), Xen_to_C_XmString(arg2)))); } static Xen gxm_XmStringIsVoid(Xen arg1) { #define H_XmStringIsVoid "Boolean XmStringIsVoid(XmString s1) provides information on the existence of non-zero-length text \ components, tab components, or separator components" Xen_check_type(Xen_is_XmString(arg1), arg1, 1, "XmStringIsVoid", "XmString"); return(C_bool_to_Xen_boolean(XmStringIsVoid(Xen_to_C_XmString(arg1)))); } static Xen gxm_XmStringEmpty(Xen arg1) { #define H_XmStringEmpty "Boolean XmStringEmpty(XmString s1) provides information on the existence of \ non-zero-length text components" Xen_check_type(Xen_is_XmString(arg1), arg1, 1, "XmStringEmpty", "XmString"); return(C_bool_to_Xen_boolean(XmStringEmpty(Xen_to_C_XmString(arg1)))); } static Xen gxm_XmStringCompare(Xen arg1, Xen arg2) { #define H_XmStringCompare "Boolean XmStringCompare(XmString s1, XmString s2) compares two strings" Xen_check_type(Xen_is_XmString(arg1), arg1, 1, "XmStringCompare", "XmString"); Xen_check_type(Xen_is_XmString(arg2), arg2, 2, "XmStringCompare", "XmString"); return(C_bool_to_Xen_boolean(XmStringCompare(Xen_to_C_XmString(arg1), Xen_to_C_XmString(arg2)))); } static Xen gxm_XmStringCopy(Xen arg1) { #define H_XmStringCopy "XmString XmStringCopy(XmString s1) makes a copy of a string" Xen_check_type(Xen_is_XmString(arg1), arg1, 1, "XmStringCopy", "XmString"); return(C_to_Xen_XmString(XmStringCopy(Xen_to_C_XmString(arg1)))); } static Xen gxm_XmStringConcatAndFree(Xen arg1, Xen arg2) { #define H_XmStringConcatAndFree "XmString XmStringConcatAndFree(XmString s1, XmString s2) appends one string to \ another and frees the original strings" Xen_check_type(Xen_is_XmString(arg1), arg1, 1, "XmStringConcatAndFree", "XmString"); Xen_check_type(Xen_is_XmString(arg2), arg2, 2, "XmStringConcatAndFree", "XmString"); return(C_to_Xen_XmString(XmStringConcatAndFree(Xen_to_C_XmString(arg1), Xen_to_C_XmString(arg2)))); } static Xen gxm_XmStringConcat(Xen arg1, Xen arg2) { #define H_XmStringConcat "XmString XmStringConcat(XmString s1, XmString s2) appends one string to another" Xen_check_type(Xen_is_XmString(arg1), arg1, 1, "XmStringConcat", "XmString"); Xen_check_type(Xen_is_XmString(arg2), arg2, 2, "XmStringConcat", "XmString"); return(C_to_Xen_XmString(XmStringConcat(Xen_to_C_XmString(arg1), Xen_to_C_XmString(arg2)))); } static Xen gxm_XmStringFreeContext(Xen arg1) { #define H_XmStringFreeContext "void XmStringFreeContext(XmStringContext context) releases the string scanning \ context data structure" Xen_check_type(Xen_is_XmStringContext(arg1), arg1, 1, "XmStringFreeContext", "XmStringContext"); XmStringFreeContext(Xen_to_C_XmStringContext(arg1)); return(Xen_false); } static XmStringContext gxm_initxmsc; static Xen gxm_XmStringInitContext(Xen arg2) { #define H_XmStringInitContext "Boolean XmStringInitContext(XmString string) creates \ a data structure for scanning an XmString component by component" /* DIFF XmStringInitContext first arg omitted and rtn */ int val; Xen_check_type(Xen_is_XmString(arg2), arg2, 1, "XmStringInitContext", "XmString"); val = XmStringInitContext(&gxm_initxmsc, Xen_to_C_XmString(arg2)); return(Xen_list_2(C_bool_to_Xen_boolean(val), C_to_Xen_XmStringContext(gxm_initxmsc))); } static Xen gxm_XmStringSeparatorCreate(void) { #define H_XmStringSeparatorCreate "XmString XmStringSeparatorCreate(void) creates a compound string" return(C_to_Xen_XmString(XmStringSeparatorCreate())); } static Xen gxm_XmStringDirectionCreate(Xen arg1) { #define H_XmStringDirectionCreate "XmString XmStringDirectionCreate(XmStringDirection direction) creates a compound string" Xen_check_type(Xen_is_integer(arg1), arg1, 1, "XmStringDirectionCreate", "int"); return(C_to_Xen_XmString(XmStringDirectionCreate(Xen_integer_to_C_int(arg1)))); } static Xen gxm_XmStringCreateLocalized(Xen arg1) { #define H_XmStringCreateLocalized "XmString XmStringCreateLocalized(char *text) creates a compound string in the current locale" Xen_check_type(Xen_is_string(arg1), arg1, 1, "XmStringCreateLocalized", "String"); return(C_to_Xen_XmString(XmStringCreateLocalized((char *)Xen_string_to_C_string(arg1)))); } static Xen gxm_XmStringCreate(Xen arg1, Xen arg2) { #define H_XmStringCreate "XmString XmStringCreate(char *text, char *tag) creates a compound string" Xen_check_type(Xen_is_string(arg1), arg1, 1, "XmStringCreate", "char*"); Xen_check_type(Xen_is_string(arg2), arg2, 2, "XmStringCreate", "XmStringCharSet"); return(C_to_Xen_XmString(XmStringCreate((char *)Xen_string_to_C_string(arg1), (char *)Xen_string_to_C_string(arg2)))); } static Xen gxm_XmChangeColor(Xen arg1, Xen arg2) { #define H_XmChangeColor "void XmChangeColor(Widget widget, Pixel background) recalculates all associated colors of a widget" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmChangeColor", "Widget"); Xen_check_type(Xen_is_Pixel(arg2), arg2, 2, "XmChangeColor", "Pixel"); XmChangeColor(Xen_to_C_Widget(arg1), Xen_to_C_Pixel(arg2)); return(Xen_false); } static Xen gxm_XmGetColors(Xen arg1, Xen arg2, Xen arg3) { #define H_XmGetColors "void XmGetColors(Screen *screen, Colormap colormap, Pixel background) generates foreground, select, and shadow colors" /* DIFF: XmGetColors omits trailing 4 args and returns them */ Pixel fg,ts, bs, sr; Xen_check_type(Xen_is_Screen(arg1), arg1, 1, "XmGetColors", "Screen*"); Xen_check_type(Xen_is_Colormap(arg2), arg2, 2, "XmGetColors", "Colormap"); Xen_check_type(Xen_is_Pixel(arg3), arg3, 3, "XmGetColors", "Pixel"); XmGetColors(Xen_to_C_Screen(arg1), Xen_to_C_Colormap(arg2), Xen_to_C_Pixel(arg3), &fg, &ts, &bs, &sr); return(Xen_list_4(C_to_Xen_Pixel(fg), C_to_Xen_Pixel(ts), C_to_Xen_Pixel(bs), C_to_Xen_Pixel(sr))); } static Xen gxm_XmGetColorCalculation(void) { #define H_XmGetColorCalculation "XmColorProc XmGetColorCalculation(void) get the procedure used for default color calculation" return(xm_XmColorProc); } static Xen gxm_XmSetColorCalculation(Xen arg1) { #define H_XmSetColorCalculation "XmColorProc XmSetColorCalculation(XmColorProc color_proc) set the procedure used for default color calculation" /* DIFF: XmSetColorCalculation NULL -> #f */ if (Xen_is_procedure(xm_XmColorProc)) xm_unprotect(xm_XmColorProc); if (Xen_is_false(arg1)) { xm_XmColorProc = Xen_false; XmSetColorCalculation(NULL); } else { Xen_check_type(Xen_is_procedure(arg1) && (Xen_is_aritable(arg1, 1)), arg1, 1, "XmSetColorCalculation", "(XmColorProc but 1 arg)"); xm_protect(arg1); xm_XmColorProc = arg1; XmSetColorCalculation((XmColorProc)gxm_XmColorProc); } return(arg1); } static Xen gxm_XmTrackingEvent(Xen arg1, Xen arg2, Xen arg3) { #define H_XmTrackingEvent "Widget XmTrackingEvent(Widget widget, Cursor cursor, Boolean confine_to): (widget event)" /* DIFF: XmTrackingEvent widget cursor confine [event] -> (list widget event) */ XEvent *e; /* do we need to allocate? */ Widget w; Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmTrackingEvent", "Widget"); Xen_check_type(Xen_is_Cursor(arg2), arg2, 2, "XmTrackingEvent", "Cursor"); Xen_check_type(Xen_is_boolean(arg3), arg3, 3, "XmTrackingEvent", "boolean"); e = (XEvent *)calloc(1, sizeof(XEvent)); w = XmTrackingEvent(Xen_to_C_Widget(arg1), Xen_ulong_to_C_ulong(arg2), Xen_boolean_to_C_bool(arg3), e); return(Xen_list_2(C_to_Xen_Widget(w), C_to_Xen_XEvent_OBJ(e))); } /* The various XmVaCreateSimple{object} require special arg handling -- these are not "normal" resource lists, but can also contain special indicators -- not immediately clear how to handle these things! Apparently we need to run through the args, split out the special args, collect arglists, add to arglist buttons, buttonCount etc, then call the underlying simple creator. (see lesstif lib/Xm/VaSimple.c) rowcol = XmVaCreateSimpleCheckBox(toplevel, "checkBox", cb, XmNspacing, 2, XmNmarginHeight, 4, XmVaCHECKBUTTON, s1, 0, NULL, NULL, XmVaCHECKBUTTON, s2, 0, NULL, NULL, NULL); option = XmVaCreateSimpleOptionMenu(form, "option", cs("MyLabel"), (KeySym) 'M', 1, SimpleCallbackProc, XmVaPUSHBUTTON, cs("Red"), (int) 'R', "", XmNULL, XmVaCASCADEBUTTON, cs("Help"), (int) 'H', XmVaSEPARATOR, XmVaPUSHBUTTON, cs("Green"), (int) 'G', "", XmNULL, XmVaSEPARATOR, XmVaPUSHBUTTON, cs("Blue"), (int) 'B', "", XmNULL, NULL); */ static Xen gxm_XmVaCreateSimpleCheckBox(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmVaCreateSimpleCheckBox "Widget XmVaCreateSimpleCheckBox(Widget parent, String name, XtCallbackProc callback, args)" Widget w; Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmVaCreateSimpleCheckBox", "Widget"); Xen_check_type(Xen_is_string(arg2), arg2, 2, "XmVaCreateSimpleCheckBox", "String"); Xen_check_type(Xen_is_procedure(arg3) && (Xen_is_aritable(arg3, 3)), arg3, 3, "XmVaCreateSimpleCheckBox", "XtCallbackProc (3 args)"); Xen_check_type(Xen_is_list(arg4), arg4, 4, "XmVaCreateSimpleCheckBox", "List"); arg4 = Xen_cons_2(C_string_to_Xen_string(XmNvalueChangedCallback), Xen_list_2(arg3, Xen_false), /* XtCallbackList technically */ arg4); { int arglen; Arg *args; args = Xen_to_C_Args(arg4); arglen = Xen_list_length(arg4) / 2; w = XmCreateSimpleCheckBox(Xen_to_C_Widget(arg1), (char *)Xen_string_to_C_string(arg2), args, arglen); if (args) { fixup_args(w, args, arglen); free_args(args, arglen); } } return(C_to_Xen_Widget(w)); } static Xen gxm_XmVaCreateSimpleRadioBox(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5) { #define H_XmVaCreateSimpleRadioBox "Widget XmVaCreateSimpleRadioBox(Widget parent, String name, int button_set, XtCallbackProc callback, args)" Widget w; Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmVaCreateSimpleRadioBox", "Widget"); Xen_check_type(Xen_is_string(arg2), arg2, 2, "XmVaCreateSimpleRadioBox", "String"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XmVaCreateSimpleRadioBox", "int"); Xen_check_type(Xen_is_procedure(arg4) && (Xen_is_aritable(arg4, 3)), arg4, 4, "XmVaCreateSimpleRadioBox", "XtCallbackProc (3 args"); Xen_check_type(Xen_is_list(arg5), arg5, 5, "XmVaCreateSimpleRadioBox", "List"); arg5 = Xen_cons_2(C_string_to_Xen_string(XmNvalueChangedCallback), Xen_list_2(arg4, Xen_false), arg5); /* can't handle button set here since the menuHistory resource is the widget allocated later */ { int arglen; Arg *args; args = Xen_to_C_Args(arg5); arglen = Xen_list_length(arg5) / 2; w = XmCreateSimpleRadioBox(Xen_to_C_Widget(arg1), (char *)Xen_string_to_C_string(arg2), args, arglen); if (args) { fixup_args(w, args, arglen); free_args(args, arglen); } } return(C_to_Xen_Widget(w)); } static Xen gxm_XmVaCreateSimpleOptionMenu(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6, Xen arg7) { #define H_XmVaCreateSimpleOptionMenu "Widget XmVaCreateSimpleOptionMenu(Widget parent, String name, XmString option_label, \ KeySym option_mnemonic, int button_set, XtCallbackProc callback, args)" Widget w; Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmVaCreateSimpleOptionMenu", "Widget"); Xen_check_type(Xen_is_string(arg2), arg2, 2, "XmVaCreateSimpleOptionMenu", "String"); Xen_check_type(Xen_is_XmString(arg3), arg3, 3, "XmVaCreateSimpleOptionMenu", "XmString"); Xen_check_type(Xen_is_KeySym(arg4), arg4, 4, "XmVaCreateSimpleOptionMenu", "KeySym"); Xen_check_type(Xen_is_integer(arg5), arg5, 5, "XmVaCreateSimpleOptionMenu", "int"); Xen_check_type(Xen_is_procedure(arg6) && (Xen_is_aritable(arg6, 3)), arg6, 6, "XmVaCreateSimpleOptionMenu", "XtCallbackProc (3 args)"); Xen_check_type(Xen_is_list(arg7), arg7, 7, "XmVaCreateSimpleOptionMenu", "List"); arg7 = Xen_cons_2(C_string_to_Xen_string(XmNlabelString), arg3, Xen_cons_2(C_string_to_Xen_string(XmNmnemonic), arg4, Xen_cons_2(C_string_to_Xen_string(XmNvalueChangedCallback), Xen_list_2(arg6, Xen_false), arg7))); { int arglen; Arg *args; args = Xen_to_C_Args(arg7); arglen = Xen_list_length(arg7) / 2; w = XmCreateSimpleOptionMenu(Xen_to_C_Widget(arg1), (char *)Xen_string_to_C_string(arg2), args, arglen); if (args) { fixup_args(w, args, arglen); free_args(args, arglen); } } return(C_to_Xen_Widget(w)); } static Xen gxm_XmVaCreateSimplePulldownMenu(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5) { #define H_XmVaCreateSimplePulldownMenu "Widget XmVaCreateSimplePulldownMenu(Widget parent, String name, int post_from_button, XtCallbackProc callback, args)" Widget w; Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmVaCreateSimplePulldownMenu", "Widget"); Xen_check_type(Xen_is_string(arg2), arg2, 2, "XmVaCreateSimplePulldownMenu", "String"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XmVaCreateSimplePulldownMenu", "int"); Xen_check_type(Xen_is_procedure(arg4) && (Xen_is_aritable(arg4, 3)), arg4, 4, "XmVaCreateSimplePulldownMenu", "XtCallbackProc (3 args)"); Xen_check_type(Xen_is_list(arg5), arg5, 5, "XmVaCreateSimplePulldownMenu", "List"); arg5 = Xen_cons_2(C_string_to_Xen_string(XmNvalueChangedCallback), Xen_list_2(arg4, Xen_false), arg5); { int arglen; Arg *args; args = Xen_to_C_Args(arg5); arglen = Xen_list_length(arg5) / 2; w = XmCreateSimplePulldownMenu(Xen_to_C_Widget(arg1), (char *)Xen_string_to_C_string(arg2), args, arglen); if (args) { fixup_args(w, args, arglen); free_args(args, arglen); } } return(C_to_Xen_Widget(w)); } static Xen gxm_XmVaCreateSimplePopupMenu(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmVaCreateSimplePopupMenu "Widget XmVaCreateSimplePopupMenu(Widget parent, String name, XtCallbackProc callback, args)" Widget w; Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmVaCreateSimplePopupMenu", "Widget"); Xen_check_type(Xen_is_string(arg2), arg2, 2, "XmVaCreateSimplePopupMenu", "String"); Xen_check_type(Xen_is_procedure(arg3) && (Xen_is_aritable(arg3, 3)), arg3, 3, "XmVaCreateSimplePopupMenu", "XtCallbackProc (3 args)"); Xen_check_type(Xen_is_list(arg4), arg4, 4, "XmVaCreateSimplePopupMenu", "List"); arg4 = Xen_cons_2(C_string_to_Xen_string(XmNvalueChangedCallback), Xen_list_2(arg3, Xen_false), arg4); { int arglen; Arg *args; args = Xen_to_C_Args(arg4); arglen = Xen_list_length(arg4) / 2; w = XmCreateSimplePopupMenu(Xen_to_C_Widget(arg1), (char *)Xen_string_to_C_string(arg2), args, arglen); if (args) { fixup_args(w, args, arglen); free_args(args, arglen); } } return(C_to_Xen_Widget(w)); } static Xen gxm_XmVaCreateSimpleMenuBar(Xen arg1, Xen arg2, Xen arg3) { #define H_XmVaCreateSimpleMenuBar "Widget XmVaCreateSimpleMenuBar(Widget parent, String name, args)" Widget w; Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmVaCreateSimpleMenuBar", "Widget"); Xen_check_type(Xen_is_string(arg2), arg2, 2, "XmVaCreateSimpleMenuBar", "String"); Xen_check_type(Xen_is_list(arg3), arg3, 3, "XmVaCreateSimpleMenuBar", "List"); { int arglen; Arg *args; args = Xen_to_C_Args(arg3); arglen = Xen_list_length(arg3) / 2; w = XmVaCreateSimpleMenuBar(Xen_to_C_Widget(arg1), (char *)Xen_string_to_C_string(arg2), args, arglen); if (args) { fixup_args(w, args, arglen); free_args(args, arglen); } } return(C_to_Xen_Widget(w)); } static Xen gxm_XmCreateSimpleCheckBox(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateSimpleCheckBox "Widget XmCreateSimpleCheckBox(Widget parent, String name, ArgList arglist, Cardinal argcount)" return(gxm_new_widget("XmCreateSimpleCheckBox", XmCreateSimpleCheckBox, arg1, arg2, arg3, arg4)); } static Xen gxm_XmCreateSimpleRadioBox(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateSimpleRadioBox "Widget XmCreateSimpleRadioBox(Widget parent, String name, ArgList arglist, Cardinal argcount)" return(gxm_new_widget("XmCreateSimpleRadioBox", XmCreateSimpleRadioBox, arg1, arg2, arg3, arg4)); } static Xen gxm_XmCreateSimpleOptionMenu(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateSimpleOptionMenu "Widget XmCreateSimpleOptionMenu(Widget parent, String name, ArgList arglist, Cardinal argcount)" return(gxm_new_widget("XmCreateSimpleOptionMenu", XmCreateSimpleOptionMenu, arg1, arg2, arg3, arg4)); } static Xen gxm_XmCreateSimplePulldownMenu(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateSimplePulldownMenu "Widget XmCreateSimplePulldownMenu(Widget parent, String name, ArgList arglist, Cardinal argcount)" return(gxm_new_widget("XmCreateSimplePulldownMenu", XmCreateSimplePulldownMenu, arg1, arg2, arg3, arg4)); } static Xen gxm_XmCreateSimplePopupMenu(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateSimplePopupMenu "Widget XmCreateSimplePopupMenu(Widget parent, String name, ArgList arglist, Cardinal argcount)" return(gxm_new_widget("XmCreateSimplePopupMenu", XmCreateSimplePopupMenu, arg1, arg2, arg3, arg4)); } static Xen gxm_XmCreateSimpleMenuBar(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateSimpleMenuBar "Widget XmCreateSimpleMenuBar(Widget parent, String name, ArgList arglist, Cardinal argcount)" return(gxm_new_widget("XmCreateSimpleMenuBar", XmCreateSimpleMenuBar, arg1, arg2, arg3, arg4)); } static Xen gxm_XmConvertUnits(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5) { #define H_XmConvertUnits "int XmConvertUnits(Widget widget, int orientation, int from_unit_type, int from_value, int to_unit_type) \ converts a value in one unit type to another unit type" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmConvertUnits", "Widget"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmConvertUnits", "int"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XmConvertUnits", "register"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XmConvertUnits", "register"); Xen_check_type(Xen_is_integer(arg5), arg5, 5, "XmConvertUnits", "register"); return(C_int_to_Xen_integer(XmConvertUnits(Xen_to_C_Widget(arg1), Xen_integer_to_C_int(arg2), Xen_integer_to_C_int(arg3), Xen_integer_to_C_int(arg4), Xen_integer_to_C_int(arg5)))); } static Xen gxm_XmConvertStringToUnits(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmConvertStringToUnits "int XmConvertStringToUnits(Screen *screen, String spec, int orientation, int to_type, XtEnum *parse_error) \ converts a string specification to a unit value" /* DIFF: XmConvertStringToUnits scr spec orient type [err] -> #f (err) or val */ XtEnum err = 0; int val; Xen_check_type(Xen_is_Screen(arg1), arg1, 1, "XmConvertStringToUnits", "Screen*"); Xen_check_type(Xen_is_string(arg2), arg2, 2, "XmConvertStringToUnits", "String"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XmConvertStringToUnits", "int"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XmConvertStringToUnits", "int"); val = XmConvertStringToUnits(Xen_to_C_Screen(arg1), (char *)Xen_string_to_C_string(arg2), Xen_integer_to_C_int(arg3), Xen_integer_to_C_int(arg4), &err); if (err == 0) return(C_int_to_Xen_integer(val)); return(Xen_false); } static Xen gxm_XmCvtXmStringToCT(Xen arg1) { #define H_XmCvtXmStringToCT "char *XmCvtXmStringToCT(XmString string) converts a compound string to compound text" Xen_check_type(Xen_is_XmString(arg1), arg1, 1, "XmCvtXmStringToCT", "XmString"); return(C_string_to_Xen_string(XmCvtXmStringToCT(Xen_to_C_XmString(arg1)))); /* memory leak here, but the docs don't say that I should free the string of "compound text" */ } static Xen gxm_XmCvtCTToXmString(Xen arg1) { #define H_XmCvtCTToXmString "XmString XmCvtCTToXmString(char *text) converts compound text to a compound string" Xen_check_type(Xen_is_string(arg1), arg1, 1, "XmCvtCTToXmString", "char*"); return(C_to_Xen_XmString(XmCvtCTToXmString((char *)Xen_string_to_C_string(arg1)))); } static Xen gxm_XmMapSegmentEncoding(Xen arg1) { char *str; Xen res; #define H_XmMapSegmentEncoding "char *XmMapSegmentEncoding(char *fontlist_tag): returns the compound text \ encoding format associated with the specified font list tag" Xen_check_type(Xen_is_string(arg1), arg1, 1, "XmMapSegmentEncoding", "char*"); str = XmMapSegmentEncoding((char *)Xen_string_to_C_string(arg1)); res = C_string_to_Xen_string(str); if (str) XtFree(str); return(res); } static Xen gxm_XmRegisterSegmentEncoding(Xen arg1, Xen arg2) { char *str; Xen res; #define H_XmRegisterSegmentEncoding "char *XmRegisterSegmentEncoding(char *fontlist_tag, char *ct_encoding) \ registers a compound text encoding format for a specified font list element tag" Xen_check_type(Xen_is_string(arg1), arg1, 1, "XmRegisterSegmentEncoding", "char*"); Xen_check_type(Xen_is_string(arg2), arg2, 2, "XmRegisterSegmentEncoding", "char*"); str = XmRegisterSegmentEncoding((char *)Xen_string_to_C_string(arg1), (char *)Xen_string_to_C_string(arg2)); res = C_string_to_Xen_string(str); if (str) XtFree(str); return(res); } static Xen gxm_XmWidgetGetBaselines(Xen arg1) { #define H_XmWidgetGetBaselines "Boolean XmWidgetGetBaselines(Widget widget) retrieves baseline information for a widget" /* DIFF: XmWidgetGetBaselines omits args 2 and 3, returns list of Dimensions */ Dimension *ds; int len, i, loc; Boolean b; Xen lst = Xen_empty_list; Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmWidgetGetBaselines", "Widget"); b = XmWidgetGetBaselines(Xen_to_C_Widget(arg1), &ds, &len); if (!b) return(Xen_false); loc = xm_protect(lst); for (i = len - 1; i >= 0; i--) lst = Xen_cons(C_to_Xen_Dimension(ds[i]), lst); free(ds); xm_unprotect_at(loc); return(lst); } static Xen gxm_XmWidgetGetDisplayRect(Xen arg1) { #define H_XmWidgetGetDisplayRect "Boolean XmWidgetGetDisplayRect(Widget widget): returns widget's bounding box as XRectangle" XRectangle *r; Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmWidgetGetDisplayRect", "Widget"); r = (XRectangle *)calloc(1, sizeof(XRectangle)); if (!(XmWidgetGetDisplayRect(Xen_to_C_Widget(arg1), r))) { free(r); return(Xen_false); } return(C_to_Xen_XRectangle(r)); } static Xen gxm_XmObjectAtPoint(Xen arg1, Xen arg2, Xen arg3) { #define H_XmObjectAtPoint "Widget XmObjectAtPoint(Widget widget, Position x, Position y) determines which child \ intersects or comes closest to a specified point" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmObjectAtPoint", "Widget"); Xen_check_type(Xen_is_Position(arg2), arg2, 2, "XmObjectAtPoint", "Position"); Xen_check_type(Xen_is_Position(arg3), arg3, 3, "XmObjectAtPoint", "Position"); return(C_to_Xen_Widget(XmObjectAtPoint(Xen_to_C_Widget(arg1), Xen_to_C_Position(arg2), Xen_to_C_Position(arg3)))); } static Xen gxm_XmUpdateDisplay(Xen arg1) { #define H_XmUpdateDisplay "void XmUpdateDisplay (widget) processes all pending exposure events immediately" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmUpdateDisplay", "Widget"); XmUpdateDisplay(Xen_to_C_Widget(arg1)); return(Xen_false); } static Xen gxm_XmDestroyPixmap(Xen arg1, Xen arg2) { #define H_XmDestroyPixmap "Boolean XmDestroyPixmap(Screen *screen, Pixmap pixmap) removes a pixmap from the pixmap cache" Xen_check_type(Xen_is_Screen(arg1), arg1, 1, "XmDestroyPixmap", "Screen*"); Xen_check_type(Xen_is_Pixmap(arg2), arg2, 2, "XmDestroyPixmap", "Pixmap"); return(C_bool_to_Xen_boolean(XmDestroyPixmap(Xen_to_C_Screen(arg1), Xen_to_C_Pixmap(arg2)))); } static Xen gxm_XmGetPixmapByDepth(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5) { #define H_XmGetPixmapByDepth "Pixmap XmGetPixmapByDepth(Screen *screen, char *image_name, Pixel foreground, Pixel background, int depth) \ generates a pixmap, stores it in a pixmap cache, and returns the pixmap" Xen_check_type(Xen_is_Screen(arg1), arg1, 1, "XmGetPixmapByDepth", "Screen*"); Xen_check_type(Xen_is_string(arg2), arg2, 2, "XmGetPixmapByDepth", "char*"); Xen_check_type(Xen_is_Pixel(arg3), arg3, 3, "XmGetPixmapByDepth", "Pixel"); Xen_check_type(Xen_is_Pixel(arg4), arg4, 4, "XmGetPixmapByDepth", "Pixel"); Xen_check_type(Xen_is_integer(arg5), arg5, 5, "XmGetPixmapByDepth", "int"); return(C_to_Xen_Pixmap(XmGetPixmapByDepth(Xen_to_C_Screen(arg1), (char *)Xen_string_to_C_string(arg2), Xen_to_C_Pixel(arg3), Xen_to_C_Pixel(arg4), Xen_integer_to_C_int(arg5)))); } static Xen gxm_XmGetPixmap(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmGetPixmap "Pixmap XmGetPixmap(Screen *screen, char *image_name, Pixel foreground, Pixel background) A pixmap caching function \ that generates a pixmap, stores it in a pixmap cache, and returns the pixmap" Xen_check_type(Xen_is_Screen(arg1), arg1, 1, "XmGetPixmap", "Screen*"); Xen_check_type(Xen_is_string(arg2), arg2, 2, "XmGetPixmap", "char*"); Xen_check_type(Xen_is_Pixel(arg3), arg3, 3, "XmGetPixmap", "Pixel"); Xen_check_type(Xen_is_Pixel(arg4), arg4, 4, "XmGetPixmap", "Pixel"); return(C_to_Xen_Pixmap(XmGetPixmap(Xen_to_C_Screen(arg1), (char *)Xen_string_to_C_string(arg2), Xen_to_C_Pixel(arg3), Xen_to_C_Pixel(arg4)))); } static Xen gxm_XmUninstallImage(Xen arg1) { #define H_XmUninstallImage "Boolean XmUninstallImage(XImage *image) removes an image from the image cache" Xen_check_type(Xen_is_XImage(arg1), arg1, 1, "XmUninstallImage", "XImage*"); return(C_bool_to_Xen_boolean(XmUninstallImage(Xen_to_C_XImage(arg1)))); } static Xen gxm_XmInstallImage(Xen arg1, Xen arg2) { #define H_XmInstallImage "Boolean XmInstallImage(XImage *image, char *image_name) adds an image to the image cache" Xen_check_type(Xen_is_XImage(arg1), arg1, 1, "XmInstallImage", "XImage*"); Xen_check_type(Xen_is_string(arg2), arg2, 2, "XmInstallImage", "char*"); return(C_bool_to_Xen_boolean(XmInstallImage(Xen_to_C_XImage(arg1), (char *)Xen_string_to_C_string(arg2)))); } static Xen gxm_XmCreateMainWindow(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateMainWindow "Widget XmCreateMainWindow(Widget parent, String name, ArgList arglist, Cardinal argcount) \ The MainWindow widget creation function" return(gxm_new_widget("XmCreateMainWindow", XmCreateMainWindow, arg1, arg2, arg3, arg4)); } static Xen gxm_XmTranslateKey(Xen arg1, Xen arg2, Xen arg3) { #define H_XmTranslateKey "void XmTranslateKey(Display *display, KeyCode keycode, Modifiers modifiers) \ The default keycode-to-keysym translator -> (modifiers keysym)" /* DIFF: XmTranslateKey omit and rtn last 2 args */ Modifiers m; KeySym k; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XmTranslateKey", "Display*"); Xen_check_type(Xen_is_KeyCode(arg2), arg2, 2, "XmTranslateKey", "KeyCode"); Xen_check_type(Xen_is_Modifiers(arg3), arg3, 3, "XmTranslateKey", "Modifiers"); XmTranslateKey(Xen_to_C_Display(arg1), Xen_to_C_KeyCode(arg2), Xen_to_C_Modifiers(arg3), &m, &k); return(Xen_list_2(C_to_Xen_Modifiers(m), C_to_Xen_KeySym(k))); } static Xen gxm_XmCreateScrolledList(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateScrolledList "Widget XmCreateScrolledList(Widget parent, String name, ArgList arglist, Cardinal argcount) The List \ ScrolledList creation function" return(gxm_new_widget("XmCreateScrolledList", XmCreateScrolledList, arg1, arg2, arg3, arg4)); } static Xen gxm_XmCreateList(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateList "Widget XmCreateList(Widget parent, String name, ArgList arglist, Cardinal argcount) The List widget creation function" return(gxm_new_widget("XmCreateList", XmCreateList, arg1, arg2, arg3, arg4)); } #define Xen_is_ListWidget(Arg) (Xen_is_Widget(Arg) && XmIsList(Xen_to_C_Widget(Arg))) static Xen gxm_XmListPosSelected(Xen arg1, Xen arg2) { #define H_XmListPosSelected "Boolean XmListPosSelected(Widget widget, int position) determines if the list item at a \ specified position is selected" Xen_check_type(Xen_is_ListWidget(arg1), arg1, 1, "XmListPosSelected", "List Widget"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmListPosSelected", "int"); return(C_bool_to_Xen_boolean(XmListPosSelected(Xen_to_C_Widget(arg1), Xen_integer_to_C_int(arg2)))); } static Xen gxm_XmListUpdateSelectedList(Xen arg1) { #define H_XmListUpdateSelectedList "void XmListUpdateSelectedList(Widget widget) updates the XmNselectedItems resource" Xen_check_type(Xen_is_ListWidget(arg1), arg1, 1, "XmListUpdateSelectedList", "List Widget"); XmListUpdateSelectedList(Xen_to_C_Widget(arg1)); return(Xen_false); } static Xen gxm_XmListSetHorizPos(Xen arg1, Xen arg2) { #define H_XmListSetHorizPos "void XmListSetHorizPos(Widget widget, int position) scrolls to the specified position in the list" Xen_check_type(Xen_is_ListWidget(arg1), arg1, 1, "XmListSetHorizPos", "List Widget"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmListSetHorizPos", "int"); XmListSetHorizPos(Xen_to_C_Widget(arg1), Xen_integer_to_C_int(arg2)); return(Xen_false); } static Xen gxm_XmListGetSelectedPos(Xen arg1) { #define H_XmListGetSelectedPos "Boolean XmListGetSelectedPos(Widget widget) A List function that returns the position of every selected item in the list" /* DIFF: XmListGetSelectedPos omits args 2 and 3, returns list of positions */ int *ps; int i, len, loc; Boolean b; Xen lst = Xen_empty_list; Xen_check_type(Xen_is_ListWidget(arg1), arg1, 1, "XmListGetSelectedPos", "List Widget"); b = XmListGetSelectedPos(Xen_to_C_Widget(arg1), &ps, &len); if (!b) return(Xen_false); loc = xm_protect(lst); for (i = len - 1; i >= 0; i--) lst = Xen_cons(C_int_to_Xen_integer(ps[i]), lst); free(ps); xm_unprotect_at(loc); return(lst); } static Xen gxm_XmListGetMatchPos(Xen arg1, Xen arg2) { #define H_XmListGetMatchPos "Boolean XmListGetMatchPos(Widget widget, XmString item): returns all instances of an item in the list" /* DIFF: XmListGetSelectedPos omits args 3 and 4, returns list of positions */ int *ps; int i, len, loc; Boolean b; Xen lst = Xen_empty_list; Xen_check_type(Xen_is_ListWidget(arg1), arg1, 1, "XmListGetMatchPos", "List Widget"); Xen_check_type(Xen_is_XmString(arg2), arg2, 2, "XmListGetMatchPos", "XmString"); b = XmListGetMatchPos(Xen_to_C_Widget(arg1), Xen_to_C_XmString(arg2), &ps, &len); if (!b) return(Xen_false); loc = xm_protect(lst); for (i = len - 1; i >= 0; i--) lst = Xen_cons(C_int_to_Xen_integer(ps[i]), lst); free(ps); xm_unprotect_at(loc); return(lst); } static Xen gxm_XmListPosToBounds(Xen arg1, Xen arg2) { #define H_XmListPosToBounds "Boolean XmListPosToBounds(Widget widget, int position): returns the bounding box of an item at a specified position in a list" /* DIFF: XmListPosToBounds last 4 args omitted and returned */ Position x, y; Dimension w, h; int val; Xen_check_type(Xen_is_ListWidget(arg1), arg1, 1, "XmListPosToBounds", "List Widget"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmListPosToBounds", "int"); val = XmListPosToBounds(Xen_to_C_Widget(arg1), Xen_integer_to_C_int(arg2), &x, &y, &w, &h); return(Xen_list_5(C_bool_to_Xen_boolean(val), C_to_Xen_Position(x), C_to_Xen_Position(y), C_to_Xen_Dimension(w), C_to_Xen_Dimension(h))); } static Xen gxm_XmListYToPos(Xen arg1, Xen arg2) { #define H_XmListYToPos "int XmListYToPos(Widget widget, Position y): returns the position of the item at a specified y-coordinate" Xen_check_type(Xen_is_ListWidget(arg1), arg1, 1, "XmListYToPos", "List Widget"); Xen_check_type(Xen_is_Position(arg2), arg2, 2, "XmListYToPos", "Position"); return(C_int_to_Xen_integer(XmListYToPos(Xen_to_C_Widget(arg1), Xen_to_C_Position(arg2)))); } static Xen gxm_XmListSetKbdItemPos(Xen arg1, Xen arg2) { #define H_XmListSetKbdItemPos "Boolean XmListSetKbdItemPos(Widget widget, int position) sets the location cursor at a specified position" Xen_check_type(Xen_is_ListWidget(arg1), arg1, 1, "XmListSetKbdItemPos", "List Widget"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmListSetKbdItemPos", "int"); return(C_bool_to_Xen_boolean(XmListSetKbdItemPos(Xen_to_C_Widget(arg1), Xen_integer_to_C_int(arg2)))); } static Xen gxm_XmListGetKbdItemPos(Xen arg1) { #define H_XmListGetKbdItemPos "int XmListGetKbdItemPos(Widget widget): returns the position of the item at the location cursor" Xen_check_type(Xen_is_ListWidget(arg1), arg1, 1, "XmListGetKbdItemPos", "List Widget"); return(C_int_to_Xen_integer(XmListGetKbdItemPos(Xen_to_C_Widget(arg1)))); } static Xen gxm_XmListItemPos(Xen arg1, Xen arg2) { #define H_XmListItemPos "int XmListItemPos(Widget widget, XmString item): returns the position of an item in the list" Xen_check_type(Xen_is_ListWidget(arg1), arg1, 1, "XmListItemPos", "List Widget"); Xen_check_type(Xen_is_XmString(arg2), arg2, 2, "XmListItemPos", "XmString"); return(C_int_to_Xen_integer(XmListItemPos(Xen_to_C_Widget(arg1), Xen_to_C_XmString(arg2)))); } static Xen gxm_XmListItemExists(Xen arg1, Xen arg2) { #define H_XmListItemExists "Boolean XmListItemExists(Widget widget, XmString item) checks if a specified item is in the list" Xen_check_type(Xen_is_ListWidget(arg1), arg1, 1, "XmListItemExists", "List Widget"); Xen_check_type(Xen_is_XmString(arg2), arg2, 2, "XmListItemExists", "XmString"); return(C_bool_to_Xen_boolean(XmListItemExists(Xen_to_C_Widget(arg1), Xen_to_C_XmString(arg2)))); } static Xen gxm_XmListSetAddMode(Xen arg1, Xen arg2) { #define H_XmListSetAddMode "void XmListSetAddMode(Widget widget, Boolean state) sets add mode in the list" Xen_check_type(Xen_is_ListWidget(arg1), arg1, 1, "XmListSetAddMode", "List Widget"); Xen_check_type(Xen_is_boolean(arg2), arg2, 2, "XmListSetAddMode", "boolean"); XmListSetAddMode(Xen_to_C_Widget(arg1), Xen_boolean_to_C_bool(arg2)); return(Xen_false); } static Xen gxm_XmListSetBottomItem(Xen arg1, Xen arg2) { #define H_XmListSetBottomItem "void XmListSetBottomItem(Widget widget, XmString item) makes an existing item the last \ visible item in the list" Xen_check_type(Xen_is_ListWidget(arg1), arg1, 1, "XmListSetBottomItem", "List Widget"); Xen_check_type(Xen_is_XmString(arg2), arg2, 2, "XmListSetBottomItem", "XmString"); XmListSetBottomItem(Xen_to_C_Widget(arg1), Xen_to_C_XmString(arg2)); return(Xen_false); } static Xen gxm_XmListSetItem(Xen arg1, Xen arg2) { #define H_XmListSetItem "void XmListSetItem(Widget widget, XmString item) makes an existing item the first visible item in the list" Xen_check_type(Xen_is_ListWidget(arg1), arg1, 1, "XmListSetItem", "List Widget"); Xen_check_type(Xen_is_XmString(arg2), arg2, 2, "XmListSetItem", "XmString"); XmListSetItem(Xen_to_C_Widget(arg1), Xen_to_C_XmString(arg2)); return(Xen_false); } static Xen gxm_XmListSetBottomPos(Xen arg1, Xen arg2) { #define H_XmListSetBottomPos "void XmListSetBottomPos(Widget widget, int position) makes a specified item the last visible item in the list" Xen_check_type(Xen_is_ListWidget(arg1), arg1, 1, "XmListSetBottomPos", "List Widget"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmListSetBottomPos", "int"); XmListSetBottomPos(Xen_to_C_Widget(arg1), Xen_integer_to_C_int(arg2)); return(Xen_false); } static Xen gxm_XmListSetPos(Xen arg1, Xen arg2) { #define H_XmListSetPos "void XmListSetPos(Widget widget, int position) makes the item at the given position the first \ visible position in the list" Xen_check_type(Xen_is_ListWidget(arg1), arg1, 1, "XmListSetPos", "List Widget"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmListSetPos", "int"); XmListSetPos(Xen_to_C_Widget(arg1), Xen_integer_to_C_int(arg2)); return(Xen_false); } static Xen gxm_XmListDeselectAllItems(Xen arg1) { #define H_XmListDeselectAllItems "void XmListDeselectAllItems(Widget widget) unhighlights and removes all items from the selected list" Xen_check_type(Xen_is_ListWidget(arg1), arg1, 1, "XmListDeselectAllItems", "List Widget"); XmListDeselectAllItems(Xen_to_C_Widget(arg1)); return(Xen_false); } static Xen gxm_XmListDeselectPos(Xen arg1, Xen arg2) { #define H_XmListDeselectPos "void XmListDeselectPos(Widget widget, int position) deselects an item at a specified position in the list" Xen_check_type(Xen_is_ListWidget(arg1), arg1, 1, "XmListDeselectPos", "List Widget"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmListDeselectPos", "int"); XmListDeselectPos(Xen_to_C_Widget(arg1), Xen_integer_to_C_int(arg2)); return(Xen_false); } static Xen gxm_XmListDeselectItem(Xen arg1, Xen arg2) { #define H_XmListDeselectItem "void XmListDeselectItem(Widget widget, XmString item) deselects the specified item from the selected list" Xen_check_type(Xen_is_ListWidget(arg1), arg1, 1, "XmListDeselectItem", "List Widget"); Xen_check_type(Xen_is_XmString(arg2), arg2, 2, "XmListDeselectItem", "XmString"); XmListDeselectItem(Xen_to_C_Widget(arg1), Xen_to_C_XmString(arg2)); return(Xen_false); } static Xen gxm_XmListSelectPos(Xen arg1, Xen arg2, Xen arg3) { #define H_XmListSelectPos "void XmListSelectPos(Widget widget, int position, Boolean notify) selects an item at a specified \ position in the list" Xen_check_type(Xen_is_ListWidget(arg1), arg1, 1, "XmListSelectPos", "List Widget"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmListSelectPos", "int"); Xen_check_type(Xen_is_boolean(arg3), arg3, 3, "XmListSelectPos", "boolean"); XmListSelectPos(Xen_to_C_Widget(arg1), Xen_integer_to_C_int(arg2), Xen_boolean_to_C_bool(arg3)); return(Xen_false); } static Xen gxm_XmListSelectItem(Xen arg1, Xen arg2, Xen arg3) { #define H_XmListSelectItem "void XmListSelectItem(Widget widget, XmString item, Boolean notify) selects an item in the list" Xen_check_type(Xen_is_ListWidget(arg1), arg1, 1, "XmListSelectItem", "List Widget"); Xen_check_type(Xen_is_XmString(arg2), arg2, 2, "XmListSelectItem", "XmString"); Xen_check_type(Xen_is_boolean(arg3), arg3, 3, "XmListSelectItem", "boolean"); XmListSelectItem(Xen_to_C_Widget(arg1), Xen_to_C_XmString(arg2), Xen_boolean_to_C_bool(arg3)); return(Xen_false); } static Xen gxm_XmListReplacePositions(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmListReplacePositions "void XmListReplacePositions(Widget widget, int *position_list, XmString *item_list, int item_count) \ replaces items in a list based on position" /* DIFF: XmListReplacePositions arg 2 is list of ints, arg3 is list of XmStrings */ int *ps; XmString *str; int len; Xen_check_type(Xen_is_ListWidget(arg1), arg1, 1, "XmListReplacePositions", "List Widget"); Xen_check_type(Xen_is_list(arg2), arg2, 2, "XmListReplacePositions", "list of int"); Xen_check_type(Xen_is_list(arg3), arg3, 3, "XmListReplacePositions", "list of XmString"); Xen_check_type(Xen_is_integer_or_unbound(arg4), arg4, 4, "XmListReplacePositions", "int"); if (Xen_is_integer(arg4)) len = Xen_integer_to_C_int(arg4); else len = Xen_list_length(arg3); if (len <= 0) return(Xen_false); ps = Xen_to_C_Ints(arg2, len); str = Xen_to_C_XmStrings(arg3, len); XmListReplacePositions(Xen_to_C_Widget(arg1), ps, str, len); free(ps); free(str); return(Xen_false); } static Xen gxm_XmListReplaceItemsPosUnselected(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmListReplaceItemsPosUnselected "void XmListReplaceItemsPosUnselected(Widget widget, XmString *new_items, int item_count, int position) \ replaces items in a list without selecting the replacement items" /* DIFF: XmListReplaceItemsPosUnselected arg 2 is list of XmStrings */ XmString *str; int len; Xen_check_type(Xen_is_ListWidget(arg1), arg1, 1, "XmListReplaceItemsPosUnselected", "List Widget"); Xen_check_type(Xen_is_list(arg2), arg2, 2, "XmListReplaceItemsPosUnselected", "list of XmString"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XmListReplaceItemsPosUnselected", "int"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XmListReplaceItemsPosUnselected", "int"); len = Xen_integer_to_C_int(arg3); if (len <= 0) return(Xen_false); str = Xen_to_C_XmStrings(arg2, len); XmListReplaceItemsPosUnselected(Xen_to_C_Widget(arg1), str, len, Xen_integer_to_C_int(arg4)); free(str); return(Xen_false); } static Xen gxm_XmListReplaceItemsUnselected(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmListReplaceItemsUnselected "void XmListReplaceItemsUnselected(Widget widget, XmString *old_items, int item_count, XmString *new_items) \ replaces items in a list" /* DIFF: XmListReplaceItemsUnselected args 2 and 4 are lists of XmStrings */ XmString *str1, *str2; int len; Xen_check_type(Xen_is_ListWidget(arg1), arg1, 1, "XmListReplaceItemsUnselected", "List Widget"); Xen_check_type(Xen_is_list(arg2), arg2, 2, "XmListReplaceItemsUnselected", "list of XmString"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XmListReplaceItemsUnselected", "int"); Xen_check_type(Xen_is_list(arg4), arg4, 4, "XmListReplaceItemsUnselected", "list of XmString"); len = Xen_integer_to_C_int(arg3); if (len <= 0) return(Xen_false); str1 = Xen_to_C_XmStrings(arg2, len); str2 = Xen_to_C_XmStrings(arg4, len); XmListReplaceItemsUnselected(Xen_to_C_Widget(arg1), str1, len, str2); free(str1); free(str2); return(Xen_false); } static Xen gxm_XmListReplaceItemsPos(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmListReplaceItemsPos "void XmListReplaceItemsPos(Widget widget, XmString *new_items, int item_count, int position) \ replaces the specified elements in the list" /* DIFF: XmListReplaceItemsPos arg 2 is list of XmStrings */ XmString *str; int len; Xen_check_type(Xen_is_ListWidget(arg1), arg1, 1, "XmListReplaceItemsPos", "List Widget"); Xen_check_type(Xen_is_list(arg2), arg2, 2, "XmListReplaceItemsPos", "list of XmString"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XmListReplaceItemsPos", "int"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XmListReplaceItemsPos", "int"); len = Xen_integer_to_C_int(arg3); if (len <= 0) return(Xen_false); str = Xen_to_C_XmStrings(arg2, len); XmListReplaceItemsPos(Xen_to_C_Widget(arg1), str, len, Xen_integer_to_C_int(arg4)); free(str); return(Xen_false); } static Xen gxm_XmListReplaceItems(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmListReplaceItems "void XmListReplaceItems(Widget widget, XmString *old_items, int item_count, XmString *new_items) \ replaces the specified elements in the list" /* DIFF: XmListReplaceItems args 2 and 4 are lists of XmStrings */ XmString *str1, *str2; int len; Xen_check_type(Xen_is_ListWidget(arg1), arg1, 1, "XmListReplaceItems", "List Widget"); Xen_check_type(Xen_is_list(arg2), arg2, 2, "XmListReplaceItems", "list of XmString"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XmListReplaceItems", "int"); Xen_check_type(Xen_is_list(arg4), arg4, 4, "XmListReplaceItems", "XmString*"); len = Xen_integer_to_C_int(arg3); if (len <= 0) return(Xen_false); str1 = Xen_to_C_XmStrings(arg2, len); str2 = Xen_to_C_XmStrings(arg4, len); XmListReplaceItems(Xen_to_C_Widget(arg1), str1, len, str2); free(str1); free(str2); return(Xen_false); } static Xen gxm_XmListDeleteAllItems(Xen arg1) { #define H_XmListDeleteAllItems "void XmListDeleteAllItems(Widget widget) deletes all items from the list" Xen_check_type(Xen_is_ListWidget(arg1), arg1, 1, "XmListDeleteAllItems", "List Widget"); XmListDeleteAllItems(Xen_to_C_Widget(arg1)); return(Xen_false); } static Xen gxm_XmListDeleteItemsPos(Xen arg1, Xen arg2, Xen arg3) { #define H_XmListDeleteItemsPos "void XmListDeleteItemsPos(Widget widget, int item_count, int position) deletes \ items from the list starting at the given position" Xen_check_type(Xen_is_ListWidget(arg1), arg1, 1, "XmListDeleteItemsPos", "List Widget"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmListDeleteItemsPos", "int"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XmListDeleteItemsPos", "int"); XmListDeleteItemsPos(Xen_to_C_Widget(arg1), Xen_integer_to_C_int(arg2), Xen_integer_to_C_int(arg3)); return(Xen_false); } static Xen gxm_XmListDeletePos(Xen arg1, Xen arg2) { #define H_XmListDeletePos "void XmListDeletePos(Widget widget, int position) deletes an item from a list at a specified position" Xen_check_type(Xen_is_ListWidget(arg1), arg1, 1, "XmListDeletePos", "List Widget"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmListDeletePos", "int"); XmListDeletePos(Xen_to_C_Widget(arg1), Xen_integer_to_C_int(arg2)); return(Xen_false); } static Xen gxm_XmListDeletePositions(Xen arg1, Xen arg2, Xen arg3) { #define H_XmListDeletePositions "void XmListDeletePositions(Widget widget, int *position_list, int position_count) deletes \ items from a list based on an array of positions" /* DIFF: XmListDeletePositions arg2 is list of ints */ int *pos; int len; Xen_check_type(Xen_is_ListWidget(arg1), arg1, 1, "XmListDeletePositions", "List Widget"); Xen_check_type(Xen_is_list(arg2), arg2, 2, "XmListDeletePositions", "list of int"); Xen_check_type(Xen_is_integer_or_unbound(arg3), arg3, 3, "XmListDeletePositions", "int"); if (Xen_is_integer(arg3)) len = Xen_integer_to_C_int(arg3); else len = Xen_list_length(arg2); if (len <= 0) return(Xen_false); pos = Xen_to_C_Ints(arg2, len); XmListDeletePositions(Xen_to_C_Widget(arg1), pos, len); free(pos); return(Xen_false); } static Xen gxm_XmListDeleteItems(Xen arg1, Xen arg2, Xen arg3) { #define H_XmListDeleteItems "void XmListDeleteItems(Widget widget, XmString *items, int item_count) deletes items from the list" /* DIFF: XmListDeleteItems arg 2 is list of XmStrings */ XmString *str; int len; Xen_check_type(Xen_is_ListWidget(arg1), arg1, 1, "XmListDeleteItems", "List Widget"); Xen_check_type(Xen_is_list(arg2), arg2, 2, "XmListDeleteItems", "list of XmString"); Xen_check_type(Xen_is_integer_or_unbound(arg3), arg3, 3, "XmListDeleteItems", "int"); if (Xen_is_integer(arg3)) len = Xen_integer_to_C_int(arg3); else len = Xen_list_length(arg2); if (len <= 0) return(Xen_false); str = Xen_to_C_XmStrings(arg2, len); XmListDeleteItems(Xen_to_C_Widget(arg1), str, len); free(str); return(Xen_false); } static Xen gxm_XmListDeleteItem(Xen arg1, Xen arg2) { #define H_XmListDeleteItem "void XmListDeleteItem(Widget widget, XmString item) deletes an item from the list" Xen_check_type(Xen_is_ListWidget(arg1), arg1, 1, "XmListDeleteItem", "List Widget"); Xen_check_type(Xen_is_XmString(arg2), arg2, 2, "XmListDeleteItem", "XmString"); XmListDeleteItem(Xen_to_C_Widget(arg1), Xen_to_C_XmString(arg2)); return(Xen_false); } static Xen gxm_XmListAddItemUnselected(Xen arg1, Xen arg2, Xen arg3) { #define H_XmListAddItemUnselected "void XmListAddItemUnselected(Widget widget, XmString item, int position) adds an item to the list" Xen_check_type(Xen_is_ListWidget(arg1), arg1, 1, "XmListAddItemUnselected", "List Widget"); Xen_check_type(Xen_is_XmString(arg2), arg2, 2, "XmListAddItemUnselected", "XmString"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XmListAddItemUnselected", "int"); XmListAddItemUnselected(Xen_to_C_Widget(arg1), Xen_to_C_XmString(arg2), Xen_integer_to_C_int(arg3)); return(Xen_false); } static Xen gxm_XmListAddItemsUnselected(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmListAddItemsUnselected "void XmListAddItemsUnselected(Widget widget, XmString *items, int item_count, int position) \ adds items to a list" /* DIFF: XmListAddItemsUnselected arg 2 is list of XmStrings */ XmString *str; int len; Xen_check_type(Xen_is_ListWidget(arg1), arg1, 1, "XmListAddItemsUnselected", "List Widget"); Xen_check_type(Xen_is_list(arg2), arg2, 2, "XmListAddItemsUnselected", "list of XmString"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XmListAddItemsUnselected", "int"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XmListAddItemsUnselected", "int"); len = Xen_integer_to_C_int(arg3); if (len <= 0) return(Xen_false); str = Xen_to_C_XmStrings(arg2, len); XmListAddItemsUnselected(Xen_to_C_Widget(arg1), str, len, Xen_integer_to_C_int(arg4)); free(str); return(Xen_false); } static Xen gxm_XmListAddItems(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmListAddItems "void XmListAddItems(Widget widget, XmString *items, int item_count, int position) adds items to the list" /* DIFF: XmListAddItems arg 2 is list of XmStrings */ XmString *str; int len; Xen_check_type(Xen_is_ListWidget(arg1), arg1, 1, "XmListAddItems", "List Widget"); Xen_check_type(Xen_is_list(arg2), arg2, 2, "XmListAddItems", "XmString*"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XmListAddItems", "int"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XmListAddItems", "int"); len = Xen_integer_to_C_int(arg3); if (len <= 0) return(Xen_false); str = Xen_to_C_XmStrings(arg2, len); XmListAddItems(Xen_to_C_Widget(arg1), str, len, Xen_integer_to_C_int(arg4)); free(str); return(Xen_false); } static Xen gxm_XmListAddItem(Xen arg1, Xen arg2, Xen arg3) { #define H_XmListAddItem "void XmListAddItem(Widget widget, XmString item, int position) adds an item to the list" Xen_check_type(Xen_is_ListWidget(arg1), arg1, 1, "XmListAddItem", "List Widget"); Xen_check_type(Xen_is_XmString(arg2), arg2, 2, "XmListAddItem", "XmString"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XmListAddItem", "int"); XmListAddItem(Xen_to_C_Widget(arg1), Xen_to_C_XmString(arg2), Xen_integer_to_C_int(arg3)); return(Xen_false); } static Xen gxm_XmIsMotifWMRunning(Xen arg1) { #define H_XmIsMotifWMRunning "Boolean XmIsMotifWMRunning(Widget shell) determines whether the window manager is running" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmIsMotifWMRunning", "Widget"); return(C_bool_to_Xen_boolean(XmIsMotifWMRunning(Xen_to_C_Widget(arg1)))); } /* DIFF: all XmCreate arglist is a list of args */ static Xen gxm_XmCreateLabel(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateLabel "Widget XmCreateLabel(Widget parent, String name, ArgList arglist, Cardinal argcount) The Label widget creation function" return(gxm_new_widget("XmCreateLabel", XmCreateLabel, arg1, arg2, arg3, arg4)); } static Xen gxm_XmCreateLabelGadget(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateLabelGadget "Widget XmCreateLabelGadget(Widget parent, String name, ArgList arglist, Cardinal argcount) The LabelGadget creation function" return(gxm_new_widget("XmCreateLabelGadget", XmCreateLabelGadget, arg1, arg2, arg3, arg4)); } static Xen gxm_XmCreateIconHeader(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateIconHeader "Widget XmCreateIconHeader(Widget parent, String name, ArgList arglist, Cardinal argcount)" return(gxm_new_widget("XmCreateIconHeader", XmCreateIconHeader, arg1, arg2, arg3, arg4)); } static Xen gxm_XmCreateIconGadget(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateIconGadget "Widget XmCreateIconGadget(Widget parent, String name, ArgList arglist, Cardinal argcount) \ The IconGadget widget creation function" return(gxm_new_widget("XmCreateIconGadget", XmCreateIconGadget, arg1, arg2, arg3, arg4)); } static Xen gxm_XmCreateToggleButton(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateToggleButton "Widget XmCreateToggleButton(Widget parent, String name, ArgList arglist, Cardinal argcount) \ The ToggleButton widget creation function" return(gxm_new_widget("XmCreateToggleButton", XmCreateToggleButton, arg1, arg2, arg3, arg4)); } #define Xen_is_ToggleButtonWidget(Arg) (Xen_is_Widget(Arg) && (XmIsToggleButton(Xen_to_C_Widget(Arg)) || XmIsToggleButtonGadget(Xen_to_C_Widget(Arg)))) static Xen gxm_XmToggleButtonSetValue(Xen arg1, Xen arg2, Xen arg3) { #define H_XmToggleButtonSetValue "void XmToggleButtonSetValue(Widget widget, XmToggleButtonState state, Boolean notify) \ sets or changes the current state" Xen_check_type(Xen_is_ToggleButtonWidget(arg1), arg1, 1, "XmToggleButtonSetValue", "ToggleButton Widget"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmToggleButtonSetValue", "int (actually XmToggleButtonState)"); Xen_check_type(Xen_is_boolean(arg3), arg3, 3, "XmToggleButtonSetValue", "boolean"); return(C_bool_to_Xen_boolean(XmToggleButtonSetValue(Xen_to_C_Widget(arg1), Xen_integer_to_C_int(arg2), Xen_boolean_to_C_bool(arg3)))); } static Xen gxm_XmToggleButtonSetState(Xen arg1, Xen arg2, Xen arg3) { #define H_XmToggleButtonSetState "void XmToggleButtonSetState(Widget widget, Boolean state, Boolean notify) \ sets or changes the current state" Xen_check_type(Xen_is_ToggleButtonWidget(arg1), arg1, 1, "XmToggleButtonSetState", "ToggleButton Widget"); Xen_check_type(Xen_is_boolean(arg2), arg2, 2, "XmToggleButtonSetState", "boolean"); Xen_check_type(Xen_is_boolean(arg3), arg3, 3, "XmToggleButtonSetState", "boolean"); XmToggleButtonSetState(Xen_to_C_Widget(arg1), Xen_boolean_to_C_bool(arg2), Xen_boolean_to_C_bool(arg3)); return(Xen_false); } static Xen gxm_XmToggleButtonGetState(Xen arg1) { #define H_XmToggleButtonGetState "Boolean XmToggleButtonGetState(Widget widget) obtains the state of a ToggleButton" Xen_check_type(Xen_is_ToggleButtonWidget(arg1), arg1, 1, "XmToggleButtonGetState", "ToggleButton Widget"); return(C_bool_to_Xen_boolean(XmToggleButtonGetState(Xen_to_C_Widget(arg1)))); } static Xen gxm_XmCreateToggleButtonGadget(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateToggleButtonGadget "Widget XmCreateToggleButtonGadget(Widget parent, String name, ArgList arglist, Cardinal argcount) \ The ToggleButtonGadget creation function" return(gxm_new_widget("XmCreateToggleButtonGadget", XmCreateToggleButtonGadget, arg1, arg2, arg3, arg4)); } static Xen gxm_XmToggleButtonGadgetSetValue(Xen arg1, Xen arg2, Xen arg3) { #define H_XmToggleButtonGadgetSetValue "Boolean XmToggleButtonGadgetSetValue(Widget w, XmToggleButtonState newstate, Boolean notify)" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmToggleButtonGadgetSetValue", "Widget"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmToggleButtonGadgetSetValue", "int"); Xen_check_type(Xen_is_boolean(arg3), arg3, 3, "XmToggleButtonGadgetSetValue", "boolean"); return(C_bool_to_Xen_boolean(XmToggleButtonGadgetSetValue(Xen_to_C_Widget(arg1), Xen_integer_to_C_int(arg2), Xen_boolean_to_C_bool(arg3)))); } static Xen gxm_XmCreateGrabShell(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateGrabShell "Widget XmCreateGrabShell(Widget parent, char *name, ArgList al, Cardinal ac): a new GrabShell" return(gxm_new_widget("XmCreateGrabShell", XmCreateGrabShell, arg1, arg2, arg3, arg4)); } static Xen gxm_XmToggleButtonGadgetSetState(Xen arg1, Xen arg2, Xen arg3) { #define H_XmToggleButtonGadgetSetState "void XmToggleButtonGadgetSetState(Widget widget, Boolean state, Boolean notify) \ sets or changes the current state" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmToggleButtonGadgetSetState", "Widget"); Xen_check_type(Xen_is_boolean(arg2), arg2, 2, "XmToggleButtonGadgetSetState", "boolean"); Xen_check_type(Xen_is_boolean(arg3), arg3, 3, "XmToggleButtonGadgetSetState", "boolean"); XmToggleButtonGadgetSetState(Xen_to_C_Widget(arg1), Xen_boolean_to_C_bool(arg2), Xen_boolean_to_C_bool(arg3)); return(Xen_false); } static Xen gxm_XmToggleButtonGadgetGetState(Xen arg1) { #define H_XmToggleButtonGadgetGetState "Boolean XmToggleButtonGadgetGetState(Widget widget) obtains \ the state of a ToggleButtonGadget" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmToggleButtonGadgetGetState", "Widget"); return(C_bool_to_Xen_boolean(XmToggleButtonGadgetGetState(Xen_to_C_Widget(arg1)))); } static Xen gxm_XmCreateFrame(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateFrame "Widget XmCreateFrame(Widget parent, String name, ArgList arglist, Cardinal argcount) The Frame widget creation function" return(gxm_new_widget("XmCreateFrame", XmCreateFrame, arg1, arg2, arg3, arg4)); } static Xen gxm_XmCreateFormDialog(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateFormDialog "Widget XmCreateFormDialog(Widget parent, String name, ArgList arglist, Cardinal argcount) \ A Form FormDialog creation function" return(gxm_new_widget("XmCreateFormDialog", XmCreateFormDialog, arg1, arg2, arg3, arg4)); } static Xen gxm_XmCreateForm(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateForm "Widget XmCreateForm(Widget parent, String name, ArgList arglist, Cardinal argcount) The Form widget creation function" return(gxm_new_widget("XmCreateForm", XmCreateForm, arg1, arg2, arg3, arg4)); } #define Xen_is_TextWidget(Arg) (Xen_is_Widget(Arg) && (XmIsText(Xen_to_C_Widget(Arg)) || XmIsTextField(Xen_to_C_Widget(Arg)))) #define Xen_is_JustTextWidget(Arg) (Xen_is_Widget(Arg) && XmIsText(Xen_to_C_Widget(Arg))) static Xen gxm_XmTextFindString(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmTextFindString "Boolean XmTextFindString(Widget widget, XmTextPosition start, char *string, XmTextDirection direction) \ finds the beginning position of a text string" /* DIFF: XmTextFindString widget start string dir [pos] -> pos or #f */ XmTextPosition pos; int res; Xen_check_type(Xen_is_JustTextWidget(arg1), arg1, 1, "XmTextFindString", "Text or TextField Widget"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmTextFindString", "XmTextPosition"); Xen_check_type(Xen_is_string(arg3), arg3, 3, "XmTextFindString", "char*"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XmTextFindString", "XmTextDirection"); res = XmTextFindString(Xen_to_C_Widget(arg1), (XmTextPosition)Xen_integer_to_C_int(arg2), (char *)Xen_string_to_C_string(arg3), (XmTextDirection)Xen_integer_to_C_int(arg4), &pos); if (res) return(C_int_to_Xen_integer(pos)); return(Xen_false); } static Xen gxm_XmTextEnableRedisplay(Xen arg1) { #define H_XmTextEnableRedisplay "void XmTextEnableRedisplay(Widget widget) forces the visual update of a Text widget" Xen_check_type(Xen_is_JustTextWidget(arg1), arg1, 1, "XmTextEnableRedisplay", "Text or TextField Widget"); XmTextEnableRedisplay(Xen_to_C_Widget(arg1)); return(Xen_false); } static Xen gxm_XmTextDisableRedisplay(Xen arg1) { #define H_XmTextDisableRedisplay "void XmTextDisableRedisplay(Widget widget) temporarily prevents visual update of the Text widget" Xen_check_type(Xen_is_JustTextWidget(arg1), arg1, 1, "XmTextDisableRedisplay", "Text or TextField Widget"); XmTextDisableRedisplay(Xen_to_C_Widget(arg1)); return(Xen_false); } static Xen gxm_XmTextGetCenterline(Xen arg1) { #define H_XmTextGetCenterline "int XmTextGetCenterline(Widget widget) Return the height (length) of a character string when the writing direction is vertical" Xen_check_type(Xen_is_TextWidget(arg1), arg1, 1, "XmTextGetCenterline", "Text or TextField Widget"); return(C_int_to_Xen_integer(XmTextGetCenterline(Xen_to_C_Widget(arg1)))); } static Xen gxm_XmTextGetBaseline(Xen arg1) { #define H_XmTextGetBaseline "int XmTextGetBaseline(Widget widget) accesses the y position of the baseline" Xen_check_type(Xen_is_TextWidget(arg1), arg1, 1, "XmTextGetBaseline", "Text or TextField Widget"); return(C_int_to_Xen_integer(XmTextGetBaseline(Xen_to_C_Widget(arg1)))); } static Xen gxm_XmTextScroll(Xen arg1, Xen arg2) { #define H_XmTextScroll "void XmTextScroll(Widget widget, int lines) scrolls text" Xen_check_type(Xen_is_JustTextWidget(arg1), arg1, 1, "XmTextScroll", "Text or TextField Widget"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmTextScroll", "int"); XmTextScroll(Xen_to_C_Widget(arg1), Xen_integer_to_C_int(arg2)); return(Xen_false); } static Xen gxm_XmTextShowPosition(Xen arg1, Xen arg2) { #define H_XmTextShowPosition "void XmTextShowPosition(Widget widget, XmTextPosition position) forces text at a given position to be displayed" Xen_check_type(Xen_is_TextWidget(arg1), arg1, 1, "XmTextShowPosition", "Text or TextField Widget"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmTextShowPosition", "XmTextPosition"); XmTextShowPosition(Xen_to_C_Widget(arg1), Xen_integer_to_C_int(arg2)); return(Xen_false); } static Xen gxm_XmTextSetSource(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmTextSetSource "void XmTextSetSource(Widget widget, XmTextSource source, XmTextPosition top_character, \ XmTextPosition cursor_position) sets the source of the widget" Xen_check_type(Xen_is_JustTextWidget(arg1), arg1, 1, "XmTextSetSource", "Text or TextField Widget"); Xen_check_type(Xen_is_XmTextSource(arg2), arg2, 2, "XmTextSetSource", "XmTextSource"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XmTextSetSource", "XmTextPosition"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XmTextSetSource", "XmTextPosition"); XmTextSetSource(Xen_to_C_Widget(arg1), Xen_to_C_XmTextSource(arg2), Xen_integer_to_C_int(arg3), Xen_integer_to_C_int(arg4)); return(Xen_false); } static Xen gxm_XmTextGetSource(Xen arg1) { #define H_XmTextGetSource "XmTextSource XmTextGetSource(Widget widget) accesses the source of the widget" Xen_check_type(Xen_is_JustTextWidget(arg1), arg1, 1, "XmTextGetSource", "Text or TextField Widget"); return(C_to_Xen_XmTextSource(XmTextGetSource(Xen_to_C_Widget(arg1)))); } static Xen gxm_XmTextPosToXY(Xen arg1, Xen arg2) { #define H_XmTextPosToXY "Boolean XmTextPosToXY(Widget widget, XmTextPosition position) A Text function \ that returns the x and y position of a character position" /* DIFF: XmTextPosToXY omits last 2 args and returns them */ Position x, y; int val; Xen_check_type(Xen_is_TextWidget(arg1), arg1, 1, "XmTextPosToXY", "Text or TextField Widget"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmTextPosToXY", "XmTextPosition"); val = XmTextPosToXY(Xen_to_C_Widget(arg1), Xen_integer_to_C_int(arg2), &x, &y); return(Xen_list_3(C_bool_to_Xen_boolean(val), C_to_Xen_Position(x), C_to_Xen_Position(y))); } static Xen gxm_XmTextXYToPos(Xen arg1, Xen arg2, Xen arg3) { #define H_XmTextXYToPos "XmTextPosition XmTextXYToPos(Widget widget, Position x, Position y) accesses \ the character position nearest an x and y position" Xen_check_type(Xen_is_TextWidget(arg1), arg1, 1, "XmTextXYToPos", "Text or TextField Widget"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmTextXYToPos", "int"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XmTextXYToPos", "int"); return(C_int_to_Xen_integer(XmTextXYToPos(Xen_to_C_Widget(arg1), Xen_integer_to_C_int(arg2), Xen_integer_to_C_int(arg3)))); } static Xen gxm_XmTextGetSelectionPosition(Xen arg1) { #define H_XmTextGetSelectionPosition "Boolean XmTextGetSelectionPosition(Widget widget): returns the position of the primary selection" /* DIFF: XmTextGetSelectionPosition widget [left right] -> (list res left right) no arg2 arg3, returns (owner left right) instead */ XmTextPosition pos1, pos2; int res; Xen_check_type(Xen_is_TextWidget(arg1), arg1, 1, "XmTextGetSelectionPosition", "Text or TextField Widget"); res = XmTextGetSelectionPosition(Xen_to_C_Widget(arg1), &pos1, &pos2); return(Xen_list_3(C_bool_to_Xen_boolean(res), C_int_to_Xen_integer(pos1), C_int_to_Xen_integer(pos2))); } static Xen gxm_XmTextClearSelection(Xen arg1, Xen arg2) { #define H_XmTextClearSelection "void XmTextClearSelection(Widget widget, Time time) clears the primary selection" Xen_check_type(Xen_is_TextWidget(arg1), arg1, 1, "XmTextClearSelection", "Text or TextField Widget"); Xen_check_type(Xen_is_Time(arg2), arg2, 2, "XmTextClearSelection", "Time"); XmTextClearSelection(Xen_to_C_Widget(arg1), Xen_to_C_Time(arg2)); return(Xen_false); } static Xen gxm_XmTextSetSelection(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmTextSetSelection "void XmTextSetSelection(Widget widget, XmTextPosition first, XmTextPosition last, Time time) \ sets the primary selection of the text" Xen_check_type(Xen_is_TextWidget(arg1), arg1, 1, "XmTextSetSelection", "Text or TextField Widget"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmTextSetSelection", "XmTextPosition"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XmTextSetSelection", "XmTextPosition"); Xen_check_type(Xen_is_Time(arg4), arg4, 4, "XmTextSetSelection", "Time"); XmTextSetSelection(Xen_to_C_Widget(arg1), Xen_integer_to_C_int(arg2), Xen_integer_to_C_int(arg3), Xen_to_C_Time(arg4)); return(Xen_false); } static Xen gxm_XmTextGetSelection(Xen arg1) { char *str; Xen res; #define H_XmTextGetSelection "char *XmTextGetSelection(Widget widget) retrieves the value of the primary selection" Xen_check_type(Xen_is_TextWidget(arg1), arg1, 1, "XmTextGetSelection", "Text or TextField Widget"); str = XmTextGetSelection(Xen_to_C_Widget(arg1)); res = C_string_to_Xen_string(str); if (str) XtFree(str); return(res); } static Xen gxm_XmTextPasteLink(Xen arg1) { #define H_XmTextPasteLink "Boolean XmTextPasteLink(Widget widget) inserts a link to the clipboard selection" Xen_check_type(Xen_is_TextWidget(arg1), arg1, 1, "XmTextPasteLink", "Text or TextField Widget"); return(C_bool_to_Xen_boolean(XmTextPasteLink(Xen_to_C_Widget(arg1)))); } static Xen gxm_XmTextPaste(Xen arg1) { #define H_XmTextPaste "Boolean XmTextPaste(Widget widget) inserts the clipboard selection" Xen_check_type(Xen_is_TextWidget(arg1), arg1, 1, "XmTextPaste", "Text or TextField Widget"); return(C_bool_to_Xen_boolean(XmTextPaste(Xen_to_C_Widget(arg1)))); } static Xen gxm_XmTextCut(Xen arg1, Xen arg2) { #define H_XmTextCut "Boolean XmTextCut(Widget widget, Time time) copies the primary selection to the clipboard and deletes the selected text" Xen_check_type(Xen_is_TextWidget(arg1), arg1, 1, "XmTextCut", "Text or TextField Widget"); Xen_check_type(Xen_is_Time(arg2), arg2, 2, "XmTextCut", "Time"); return(C_bool_to_Xen_boolean(XmTextCut(Xen_to_C_Widget(arg1), Xen_to_C_Time(arg2)))); } static Xen gxm_XmTextCopyLink(Xen arg1, Xen arg2) { #define H_XmTextCopyLink "Boolean XmTextCopyLink(Widget widget, Time time) copies a link to the primary selection to the clipboard" Xen_check_type(Xen_is_TextWidget(arg1), arg1, 1, "XmTextCopyLink", "Text or TextField Widget"); Xen_check_type(Xen_is_Time(arg2), arg2, 2, "XmTextCopyLink", "Time"); return(C_bool_to_Xen_boolean(XmTextCopyLink(Xen_to_C_Widget(arg1), Xen_to_C_Time(arg2)))); } static Xen gxm_XmTextCopy(Xen arg1, Xen arg2) { #define H_XmTextCopy "Boolean XmTextCopy(Widget widget, Time time) copies the primary selection to the clipboard" Xen_check_type(Xen_is_TextWidget(arg1), arg1, 1, "XmTextCopy", "Text or TextField Widget"); Xen_check_type(Xen_is_Time(arg2), arg2, 2, "XmTextCopy", "Time"); return(C_bool_to_Xen_boolean(XmTextCopy(Xen_to_C_Widget(arg1), Xen_to_C_Time(arg2)))); } static Xen gxm_XmTextRemove(Xen arg1) { #define H_XmTextRemove "Boolean XmTextRemove(Widget widget) deletes the primary selection" Xen_check_type(Xen_is_TextWidget(arg1), arg1, 1, "XmTextRemove", "Text or TextField Widget"); return(C_bool_to_Xen_boolean(XmTextRemove(Xen_to_C_Widget(arg1)))); } static Xen gxm_XmTextSetCursorPosition(Xen arg1, Xen arg2) { #define H_XmTextSetCursorPosition "void XmTextSetCursorPosition(Widget w, int position) sets the insertion cursor position" Xen_check_type(Xen_is_TextWidget(arg1), arg1, 1, "XmTextSetCursorPosition", "Text or TextField Widget"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmTextSetCursorPosition", "XmTextPosition"); XmTextSetCursorPosition(Xen_to_C_Widget(arg1), Xen_integer_to_C_int(arg2)); return(Xen_false); } static Xen gxm_XmTextSetInsertionPosition(Xen arg1, Xen arg2) { #define H_XmTextSetInsertionPosition "void XmTextSetInsertionPosition(Widget widget, XmTextPosition position) \ sets the position of the insert cursor" Xen_check_type(Xen_is_TextWidget(arg1), arg1, 1, "XmTextSetInsertionPosition", "Text or TextField Widget"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmTextSetInsertionPosition", "XmTextPosition"); XmTextSetInsertionPosition(Xen_to_C_Widget(arg1), Xen_integer_to_C_int(arg2)); return(Xen_false); } static Xen gxm_XmTextGetInsertionPosition(Xen arg1) { #define H_XmTextGetInsertionPosition "XmTextPosition XmTextGetInsertionPosition(Widget widget) accesses the \ position of the insert cursor" Xen_check_type(Xen_is_TextWidget(arg1), arg1, 1, "XmTextGetInsertionPosition", "Text or TextField Widget"); return(C_int_to_Xen_integer(XmTextGetInsertionPosition(Xen_to_C_Widget(arg1)))); } static Xen gxm_XmTextGetCursorPosition(Xen arg1) { #define H_XmTextGetCursorPosition "int XmTextGetCursorPosition(Widget w) presumably returns the widget's insertion cursor position" Xen_check_type(Xen_is_TextWidget(arg1), arg1, 1, "XmTextGetCursorPosition", "Text or TextField Widget"); return(C_int_to_Xen_integer(XmTextGetCursorPosition(Xen_to_C_Widget(arg1)))); } static Xen gxm_XmTextSetTopCharacter(Xen arg1, Xen arg2) { #define H_XmTextSetTopCharacter "void XmTextSetTopCharacter(Widget widget, XmTextPosition top_character) sets \ the position of the first character displayed" Xen_check_type(Xen_is_JustTextWidget(arg1), arg1, 1, "XmTextSetTopCharacter", "Text or TextField Widget"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmTextSetTopCharacter", "XmTextPosition"); XmTextSetTopCharacter(Xen_to_C_Widget(arg1), Xen_integer_to_C_int(arg2)); return(Xen_false); } static Xen gxm_XmTextGetTopCharacter(Xen arg1) { #define H_XmTextGetTopCharacter "XmTextPosition XmTextGetTopCharacter(Widget widget) accesses the position of the first character displayed" Xen_check_type(Xen_is_JustTextWidget(arg1), arg1, 1, "XmTextGetTopCharacter", "Text or TextField Widget"); return(C_int_to_Xen_integer(XmTextGetTopCharacter(Xen_to_C_Widget(arg1)))); } static Xen gxm_XmTextSetMaxLength(Xen arg1, Xen arg2) { #define H_XmTextSetMaxLength "void XmTextSetMaxLength(Widget widget, int max_length) sets the value of the current \ maximum allowable length of a text string entered from the keyboard" Xen_check_type(Xen_is_TextWidget(arg1), arg1, 1, "XmTextSetMaxLength", "Text or TextField Widget"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmTextSetMaxLength", "int"); XmTextSetMaxLength(Xen_to_C_Widget(arg1), Xen_integer_to_C_int(arg2)); return(Xen_false); } static Xen gxm_XmTextGetMaxLength(Xen arg1) { #define H_XmTextGetMaxLength "int XmTextGetMaxLength(Widget widget) accesses the value of the current maximum allowable \ length of a text string entered from the keyboard" Xen_check_type(Xen_is_TextWidget(arg1), arg1, 1, "XmTextGetMaxLength", "Text or TextField Widget"); return(C_int_to_Xen_integer(XmTextGetMaxLength(Xen_to_C_Widget(arg1)))); } static Xen gxm_XmTextSetEditable(Xen arg1, Xen arg2) { #define H_XmTextSetEditable "void XmTextSetEditable(Widget widget, Boolean editable) sets the edit permission" Xen_check_type(Xen_is_TextWidget(arg1), arg1, 1, "XmTextSetEditable", "Text or TextField Widget"); Xen_check_type(Xen_is_boolean(arg2), arg2, 2, "XmTextSetEditable", "boolean"); XmTextSetEditable(Xen_to_C_Widget(arg1), Xen_boolean_to_C_bool(arg2)); return(Xen_false); } static Xen gxm_XmTextGetEditable(Xen arg1) { #define H_XmTextGetEditable "Boolean XmTextGetEditable(Widget widget) accesses the edit permission state" Xen_check_type(Xen_is_TextWidget(arg1), arg1, 1, "XmTextGetEditable", "Text or TextField Widget"); return(C_bool_to_Xen_boolean(XmTextGetEditable(Xen_to_C_Widget(arg1)))); } static Xen gxm_XmTextGetAddMode(Xen arg1) { #define H_XmTextGetAddMode "Boolean XmTextGetAddMode(Widget w) presumably returns the widget's current add mode." Xen_check_type(Xen_is_TextWidget(arg1), arg1, 1, "XmTextGetAddMode", "Text or TextField Widget"); return(C_bool_to_Xen_boolean(XmTextGetAddMode(Xen_to_C_Widget(arg1)))); } static Xen gxm_XmTextSetAddMode(Xen arg1, Xen arg2) { #define H_XmTextSetAddMode "void XmTextSetAddMode(Widget widget, Boolean state) sets the widget's add mode -- \ this determines whether you can move the insertion cursor without changing the primary selection" Xen_check_type(Xen_is_TextWidget(arg1), arg1, 1, "XmTextSetAddMode", "Text or TextField Widget"); Xen_check_type(Xen_is_boolean(arg2), arg2, 2, "XmTextSetAddMode", "boolean"); XmTextSetAddMode(Xen_to_C_Widget(arg1), Xen_boolean_to_C_bool(arg2)); return(Xen_false); } static Xen gxm_XmTextInsert(Xen arg1, Xen arg2, Xen arg3) { #define H_XmTextInsert "void XmTextInsert(Widget widget, XmTextPosition position, char *value) inserts a character \ string into a text string" Xen_check_type(Xen_is_TextWidget(arg1), arg1, 1, "XmTextInsert", "Text or TextField Widget"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmTextInsert", "XmTextPosition"); Xen_check_type(Xen_is_string(arg3), arg3, 3, "XmTextInsert", "char*"); XmTextInsert(Xen_to_C_Widget(arg1), Xen_integer_to_C_int(arg2), (char *)Xen_string_to_C_string(arg3)); return(Xen_false); } static Xen gxm_XmTextReplace(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmTextReplace "void XmTextReplace(Widget widget, XmTextPosition from_pos, XmTextPosition to_pos, char *value) \ replaces part of a text string" Xen_check_type(Xen_is_TextWidget(arg1), arg1, 1, "XmTextReplace", "Text or TextField Widget"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmTextReplace", "XmTextPosition"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XmTextReplace", "XmTextPosition"); Xen_check_type(Xen_is_string(arg4), arg4, 4, "XmTextReplace", "char*"); XmTextReplace(Xen_to_C_Widget(arg1), Xen_integer_to_C_int(arg2), Xen_integer_to_C_int(arg3), (char *)Xen_string_to_C_string(arg4)); return(Xen_false); } static Xen gxm_XmTextSetString(Xen arg1, Xen arg2) { #define H_XmTextSetString "void XmTextSetString(Widget widget, char *value) sets the string value" Xen_check_type(Xen_is_TextWidget(arg1), arg1, 1, "XmTextSetString", "Text or TextField Widget"); Xen_check_type(Xen_is_string(arg2), arg2, 2, "XmTextSetString", "char*"); XmTextSetString(Xen_to_C_Widget(arg1), (char *)Xen_string_to_C_string(arg2)); return(Xen_false); } static Xen gxm_XmTextGetLastPosition(Xen arg1) { #define H_XmTextGetLastPosition "XmTextPosition XmTextGetLastPosition(Widget widget) accesses the last position in the text" Xen_check_type(Xen_is_TextWidget(arg1), arg1, 1, "XmTextGetLastPosition", "Text or TextField Widget"); return(C_int_to_Xen_integer(XmTextGetLastPosition(Xen_to_C_Widget(arg1)))); } static Xen gxm_XmTextGetString(Xen arg1) { char *str; Xen res; #define H_XmTextGetString "char *XmTextGetString(Widget widget) accesses the string value" Xen_check_type(Xen_is_TextWidget(arg1), arg1, 1, "XmTextGetString", "Text or TextField Widget"); str = XmTextGetString(Xen_to_C_Widget(arg1)); res = C_string_to_Xen_string(str); if (str) XtFree(str); return(res); } static Xen gxm_XmTextGetSubstring(Xen arg1, Xen arg2, Xen arg3) { /* DIFF: omit and rtn last 2 args */ #define H_XmTextGetSubstring "int XmTextGetSubstring(Widget widget, XmTextPosition start, int num_chars) \ retrieves a copy of a portion of the internal text buffer" int rtn, len; char *buf; Xen str = Xen_false; Xen_check_type(Xen_is_TextWidget(arg1), arg1, 1, "XmTextGetSubstring", "Text or TextField Widget"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmTextGetSubstring", "XmTextPosition"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XmTextGetSubstring", "int"); len = Xen_integer_to_C_int(arg3); buf = (char *)calloc(len + 1, sizeof(char)); rtn = XmTextGetSubstring(Xen_to_C_Widget(arg1), Xen_integer_to_C_int(arg2), len, len + 1, buf); if (rtn != XmCOPY_FAILED) str = C_string_to_Xen_string(buf); free(buf); return(str); } static Xen gxm_XmCreateText(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateText "Widget XmCreateText(Widget parent, String name, ArgList arglist, Cardinal argcount) The Text widget creation function" return(gxm_new_widget("XmCreateText", XmCreateText, arg1, arg2, arg3, arg4)); } static Xen gxm_XmCreateScrolledText(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateScrolledText "Widget XmCreateScrolledText(Widget parent, String name, ArgList arglist, Cardinal argcount) \ The Text ScrolledText creation function" return(gxm_new_widget("XmCreateScrolledText", XmCreateScrolledText, arg1, arg2, arg3, arg4)); } static Xen gxm_XmTextSetHighlight(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmTextSetHighlight "void XmTextSetHighlight(Widget widget, XmTextPosition left, XmTextPosition right, XmHighlightMode mode) \ highlights text" Xen_check_type(Xen_is_TextWidget(arg1), arg1, 1, "XmTextSetHighlight", "Text or TextField Widget"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmTextSetHighlight", "XmTextPosition"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XmTextSetHighlight", "XmTextPosition"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XmTextSetHighlight", "XmHighlightMode"); XmTextSetHighlight(Xen_to_C_Widget(arg1), (XmTextPosition)Xen_integer_to_C_int(arg2), (XmTextPosition)Xen_integer_to_C_int(arg3), (XmHighlightMode)Xen_integer_to_C_int(arg4)); return(Xen_false); } static Xen gxm_XmCreateFileSelectionDialog(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateFileSelectionDialog "Widget XmCreateFileSelectionDialog(Widget parent, String name, ArgList arglist, Cardinal argcount) \ The FileSelectionBox FileSelectionDialog creation function" return(gxm_new_widget("XmCreateFileSelectionDialog", XmCreateFileSelectionDialog, arg1, arg2, arg3, arg4)); } static Xen gxm_XmCreateFileSelectionBox(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateFileSelectionBox "Widget XmCreateFileSelectionBox(Widget parent, String name, ArgList arglist, Cardinal argcount) \ The FileSelectionBox widget creation function" return(gxm_new_widget("XmCreateFileSelectionBox", XmCreateFileSelectionBox, arg1, arg2, arg3, arg4)); } static Xen gxm_XmFileSelectionDoSearch(Xen arg1, Xen arg2) { #define H_XmFileSelectionDoSearch "void XmFileSelectionDoSearch(Widget widget, XmString dirmask) \ initiates a directory search" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmFileSelectionDoSearch", "Widget"); Xen_check_type(Xen_is_XmString(arg2) || Xen_is_false(arg2), arg2, 2, "XmFileSelectionDoSearch", "XmString"); XmFileSelectionDoSearch(Xen_to_C_Widget(arg1), Xen_is_false(arg2) ? NULL : Xen_to_C_XmString(arg2)); return(Xen_false); } static Xen gxm_XmFileSelectionBoxGetChild(Xen arg1, Xen arg2) { #define H_XmFileSelectionBoxGetChild "Widget XmFileSelectionBoxGetChild(Widget widget, unsigned char child) \ used to access a component" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmFileSelectionBoxGetChild", "Widget"); Xen_check_type(Xen_is_ulong(arg2), arg2, 2, "XmFileSelectionBoxGetChild", "unsigned int"); return(C_to_Xen_Widget(XmFileSelectionBoxGetChild(Xen_to_C_Widget(arg1), Xen_ulong_to_C_ulong(arg2)))); } static Xen gxm_XmCreateTextField(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateTextField "Widget XmCreateTextField(Widget parent, String name, ArgList arglist, Cardinal argcount) \ The TextField widget creation function" return(gxm_new_widget("XmCreateTextField", XmCreateTextField, arg1, arg2, arg3, arg4)); } #define Xen_is_TextFieldWidget(Arg) (Xen_is_Widget(Arg) && XmIsTextField(Xen_to_C_Widget(Arg))) static Xen gxm_XmTextFieldGetBaseline(Xen arg1) { #define H_XmTextFieldGetBaseline "int XmTextFieldGetBaseline(Widget widget) accesses the y position of the baseline" Xen_check_type(Xen_is_TextFieldWidget(arg1), arg1, 1, "XmTextFieldGetBaseline", "TextField Widget"); return(C_int_to_Xen_integer(XmTextFieldGetBaseline(Xen_to_C_Widget(arg1)))); } static Xen gxm_XmTextFieldSetHighlight(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmTextFieldSetHighlight "void XmTextFieldSetHighlight(Widget widget, XmTextPosition left, XmTextPosition right, XmHighlightMode mode) \ highlights text" Xen_check_type(Xen_is_TextFieldWidget(arg1), arg1, 1, "XmTextFieldSetHighlight", "TextField Widget"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmTextFieldSetHighlight", "XmTextPosition"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XmTextFieldSetHighlight", "XmTextPosition"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XmTextFieldSetHighlight", "XmHighlightMode"); XmTextFieldSetHighlight(Xen_to_C_Widget(arg1), (XmTextPosition)Xen_integer_to_C_int(arg2), (XmTextPosition)Xen_integer_to_C_int(arg3), (XmHighlightMode)Xen_integer_to_C_int(arg4)); return(Xen_false); } static Xen gxm_XmTextFieldShowPosition(Xen arg1, Xen arg2) { #define H_XmTextFieldShowPosition "void XmTextFieldShowPosition(Widget widget, XmTextPosition position) \ forces text at a given position to be displayed" Xen_check_type(Xen_is_TextFieldWidget(arg1), arg1, 1, "XmTextFieldShowPosition", "TextField Widget"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmTextFieldShowPosition", "XmTextPosition"); XmTextFieldShowPosition(Xen_to_C_Widget(arg1), (XmTextPosition)Xen_integer_to_C_int(arg2)); return(Xen_false); } static Xen gxm_XmTextFieldPosToXY(Xen arg1, Xen arg2) { #define H_XmTextFieldPosToXY "Boolean XmTextFieldPosToXY(Widget widget, XmTextPosition position): returns the x and y position of a character position" /* DIFF: XmTextFieldPosToXY omits last 2 args and returns them */ Position x, y; int val; Xen_check_type(Xen_is_TextFieldWidget(arg1), arg1, 1, "XmTextFieldPosToXY", "TextField Widget"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmTextFieldPosToXY", "XmTextPosition"); Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmTextPosToXY", "Widget"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmTextPosToXY", "XmTextPosition"); val = XmTextFieldPosToXY(Xen_to_C_Widget(arg1), Xen_integer_to_C_int(arg2), &x, &y); return(Xen_list_3(C_bool_to_Xen_boolean(val), C_to_Xen_Position(x), C_to_Xen_Position(y))); } static Xen gxm_XmTextFieldXYToPos(Xen arg1, Xen arg2, Xen arg3) { #define H_XmTextFieldXYToPos "XmTextPosition XmTextFieldXYToPos(Widget widget, Position x, Position y) \ accesses the character position nearest an x and y position" Xen_check_type(Xen_is_TextFieldWidget(arg1), arg1, 1, "XmTextFieldXYToPos", "TextField Widget"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmTextFieldXYToPos", "int"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XmTextFieldXYToPos", "int"); return(C_int_to_Xen_integer(XmTextFieldXYToPos(Xen_to_C_Widget(arg1), Xen_integer_to_C_int(arg2), Xen_integer_to_C_int(arg3)))); } static Xen gxm_XmTextFieldSetSelection(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmTextFieldSetSelection "void XmTextFieldSetSelection(Widget widget, XmTextPosition first, XmTextPosition last, Time time) \ sets the primary selection of the text" Xen_check_type(Xen_is_TextFieldWidget(arg1), arg1, 1, "XmTextFieldSetSelection", "TextField Widget"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmTextFieldSetSelection", "XmTextPosition"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XmTextFieldSetSelection", "XmTextPosition"); Xen_check_type(Xen_is_Time(arg4), arg4, 4, "XmTextFieldSetSelection", "Time"); XmTextFieldSetSelection(Xen_to_C_Widget(arg1), Xen_integer_to_C_int(arg2), Xen_integer_to_C_int(arg3), Xen_to_C_Time(arg4)); return(Xen_false); } static Xen gxm_XmTextFieldClearSelection(Xen arg1, Xen arg2) { #define H_XmTextFieldClearSelection "void XmTextFieldClearSelection(Widget widget, Time time) clears the primary selection" Xen_check_type(Xen_is_TextFieldWidget(arg1), arg1, 1, "XmTextFieldClearSelection", "TextField Widget"); Xen_check_type(Xen_is_Time(arg2), arg2, 2, "XmTextFieldClearSelection", "Time"); XmTextFieldClearSelection(Xen_to_C_Widget(arg1), Xen_to_C_Time(arg2)); return(Xen_false); } static Xen gxm_XmTextFieldPasteLink(Xen arg1) { #define H_XmTextFieldPasteLink "Boolean XmTextFieldPasteLink(Widget widget) inserts a link to the clipboard selection" Xen_check_type(Xen_is_TextFieldWidget(arg1), arg1, 1, "XmTextFieldPasteLink", "TextField Widget"); return(C_bool_to_Xen_boolean(XmTextFieldPasteLink(Xen_to_C_Widget(arg1)))); } static Xen gxm_XmTextFieldCopyLink(Xen arg1, Xen arg2) { #define H_XmTextFieldCopyLink "Boolean XmTextFieldCopyLink(Widget widget, Time time) copies a link to the \ primary selection to the clipboard" Xen_check_type(Xen_is_TextFieldWidget(arg1), arg1, 1, "XmTextFieldCopyLink", "TextField Widget"); Xen_check_type(Xen_is_Time(arg2), arg2, 2, "XmTextFieldCopyLink", "Time"); return(C_bool_to_Xen_boolean(XmTextFieldCopyLink(Xen_to_C_Widget(arg1), Xen_to_C_Time(arg2)))); } static Xen gxm_XmTextFieldPaste(Xen arg1) { #define H_XmTextFieldPaste "Boolean XmTextFieldPaste(Widget widget) inserts the clipboard selection" Xen_check_type(Xen_is_TextFieldWidget(arg1), arg1, 1, "XmTextFieldPaste", "TextField Widget"); return(C_bool_to_Xen_boolean(XmTextFieldPaste(Xen_to_C_Widget(arg1)))); } static Xen gxm_XmTextFieldCut(Xen arg1, Xen arg2) { #define H_XmTextFieldCut "Boolean XmTextFieldCut(Widget widget, Time time) copies the primary selection \ to the clipboard and deletes the selected text" Xen_check_type(Xen_is_TextFieldWidget(arg1), arg1, 1, "XmTextFieldCut", "TextField Widget"); Xen_check_type(Xen_is_Time(arg2), arg2, 2, "XmTextFieldCut", "Time"); return(C_bool_to_Xen_boolean(XmTextFieldCut(Xen_to_C_Widget(arg1), Xen_to_C_Time(arg2)))); } static Xen gxm_XmTextFieldCopy(Xen arg1, Xen arg2) { #define H_XmTextFieldCopy "Boolean XmTextFieldCopy(Widget widget, Time time) copies the primary selection to the clipboard" Xen_check_type(Xen_is_TextFieldWidget(arg1), arg1, 1, "XmTextFieldCopy", "TextField Widget"); Xen_check_type(Xen_is_Time(arg2), arg2, 2, "XmTextFieldCopy", "Time"); return(C_bool_to_Xen_boolean(XmTextFieldCopy(Xen_to_C_Widget(arg1), Xen_to_C_Time(arg2)))); } static Xen gxm_XmTextFieldRemove(Xen arg1) { #define H_XmTextFieldRemove "Boolean XmTextFieldRemove(Widget widget) deletes the primary selection" Xen_check_type(Xen_is_TextFieldWidget(arg1), arg1, 1, "XmTextFieldRemove", "TextField Widget"); return(C_bool_to_Xen_boolean(XmTextFieldRemove(Xen_to_C_Widget(arg1)))); } static Xen gxm_XmTextFieldGetSelection(Xen arg1) { char *str; Xen res; #define H_XmTextFieldGetSelection "char *XmTextFieldGetSelection(Widget widget) retrieves the value of the primary selection" Xen_check_type(Xen_is_TextFieldWidget(arg1), arg1, 1, "XmTextFieldGetSelection", "TextField Widget"); str = XmTextFieldGetSelection(Xen_to_C_Widget(arg1)); res = C_string_to_Xen_string(str); if (str) XtFree(str); return(res); } static Xen gxm_XmTextFieldGetSelectionPosition(Xen arg1) { #define H_XmTextFieldGetSelectionPosition "Boolean XmTextFieldGetSelectionPosition(Widget widget) \ returns the position of the primary selection" /* DIFF: XmTextFieldGetSelectionPosition widget [left right] -> (list res left right) no arg2 arg3, returns (owner left right) instead */ XmTextPosition pos1, pos2; int res; Xen_check_type(Xen_is_TextFieldWidget(arg1), arg1, 1, "XmTextFieldGetSelectionPosition", "TextField Widget"); res = XmTextFieldGetSelectionPosition(Xen_to_C_Widget(arg1), &pos1, &pos2); return(Xen_list_3(C_bool_to_Xen_boolean(res), C_int_to_Xen_integer(pos1), C_int_to_Xen_integer(pos2))); } static Xen gxm_XmTextFieldSetInsertionPosition(Xen arg1, Xen arg2) { #define H_XmTextFieldSetInsertionPosition "void XmTextFieldSetInsertionPosition(Widget widget, XmTextPosition position) \ sets the position of the insertion cursor" Xen_check_type(Xen_is_TextFieldWidget(arg1), arg1, 1, "XmTextFieldSetInsertionPosition", "TextField Widget"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmTextFieldSetInsertionPosition", "XmTextPosition"); XmTextFieldSetInsertionPosition(Xen_to_C_Widget(arg1), Xen_integer_to_C_int(arg2)); return(Xen_false); } static Xen gxm_XmTextFieldSetCursorPosition(Xen arg1, Xen arg2) { #define H_XmTextFieldSetCursorPosition "void XmTextFieldSetCursorPosition(Widget w, int position) sets the insertion cursor position" Xen_check_type(Xen_is_TextFieldWidget(arg1), arg1, 1, "XmTextFieldSetCursorPosition", "TextField Widget"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmTextFieldSetCursorPosition", "XmTextPosition"); XmTextFieldSetCursorPosition(Xen_to_C_Widget(arg1), Xen_integer_to_C_int(arg2)); return(Xen_false); } static Xen gxm_XmTextFieldGetInsertionPosition(Xen arg1) { #define H_XmTextFieldGetInsertionPosition "XmTextPosition XmTextFieldGetInsertionPosition(Widget widget) \ accesses the position of the insertion cursor" Xen_check_type(Xen_is_TextFieldWidget(arg1), arg1, 1, "XmTextFieldGetInsertionPosition", "TextField Widget"); return(C_int_to_Xen_integer(XmTextFieldGetInsertionPosition(Xen_to_C_Widget(arg1)))); } static Xen gxm_XmTextFieldGetCursorPosition(Xen arg1) { #define H_XmTextFieldGetCursorPosition "int XmTextFieldGetCursorPosition(Widget w) presumably returns the widget's insertion cursor position" Xen_check_type(Xen_is_TextFieldWidget(arg1), arg1, 1, "XmTextFieldGetCursorPosition", "TextField Widget"); return(C_int_to_Xen_integer(XmTextFieldGetCursorPosition(Xen_to_C_Widget(arg1)))); } static Xen gxm_XmTextFieldSetMaxLength(Xen arg1, Xen arg2) { #define H_XmTextFieldSetMaxLength "void XmTextFieldSetMaxLength(Widget widget, int max_length) sets the \ value of the current maximum allowable length of a text string \ entered from the keyboard" Xen_check_type(Xen_is_TextFieldWidget(arg1), arg1, 1, "XmTextFieldSetMaxLength", "TextField Widget"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmTextFieldSetMaxLength", "int"); XmTextFieldSetMaxLength(Xen_to_C_Widget(arg1), Xen_integer_to_C_int(arg2)); return(Xen_false); } static Xen gxm_XmTextFieldGetMaxLength(Xen arg1) { #define H_XmTextFieldGetMaxLength "int XmTextFieldGetMaxLength(Widget widget) accesses the value of the \ current maximum allowable length of a text string \ entered from the keyboard" Xen_check_type(Xen_is_TextFieldWidget(arg1), arg1, 1, "XmTextFieldGetMaxLength", "TextField Widget"); return(C_int_to_Xen_integer(XmTextFieldGetMaxLength(Xen_to_C_Widget(arg1)))); } static Xen gxm_XmTextFieldSetEditable(Xen arg1, Xen arg2) { #define H_XmTextFieldSetEditable "void XmTextFieldSetEditable(Widget widget, Boolean editable) sets the edit permission" Xen_check_type(Xen_is_TextFieldWidget(arg1), arg1, 1, "XmTextFieldSetEditable", "TextField Widget"); Xen_check_type(Xen_is_boolean(arg2), arg2, 2, "XmTextFieldSetEditable", "boolean"); XmTextFieldSetEditable(Xen_to_C_Widget(arg1), Xen_boolean_to_C_bool(arg2)); return(Xen_false); } static Xen gxm_XmTextFieldGetEditable(Xen arg1) { #define H_XmTextFieldGetEditable "Boolean XmTextFieldGetEditable(Widget widget) accesses the edit permission state" Xen_check_type(Xen_is_TextFieldWidget(arg1), arg1, 1, "XmTextFieldGetEditable", "TextField Widget"); return(C_bool_to_Xen_boolean(XmTextFieldGetEditable(Xen_to_C_Widget(arg1)))); } static Xen gxm_XmTextFieldGetAddMode(Xen arg1) { #define H_XmTextFieldGetAddMode "Boolean XmTextFieldGetAddMode(Widget w) presumably returns the widget's current add mode." Xen_check_type(Xen_is_TextFieldWidget(arg1), arg1, 1, "XmTextFieldGetAddMode", "TextField Widget"); return(C_bool_to_Xen_boolean(XmTextFieldGetAddMode(Xen_to_C_Widget(arg1)))); } static Xen gxm_XmTextFieldSetAddMode(Xen arg1, Xen arg2) { #define H_XmTextFieldSetAddMode "void XmTextFieldSetAddMode(Widget widget, Boolean state) sets the state of Add mode" Xen_check_type(Xen_is_TextFieldWidget(arg1), arg1, 1, "XmTextFieldSetAddMode", "TextField Widget"); Xen_check_type(Xen_is_boolean(arg2), arg2, 2, "XmTextFieldSetAddMode", "boolean"); XmTextFieldSetAddMode(Xen_to_C_Widget(arg1), Xen_boolean_to_C_bool(arg2)); return(Xen_false); } static Xen gxm_XmTextFieldInsert(Xen arg1, Xen arg2, Xen arg3) { #define H_XmTextFieldInsert "void XmTextFieldInsert(Widget widget, XmTextPosition position, char *value) \ inserts a character string into a text string" Xen_check_type(Xen_is_TextFieldWidget(arg1), arg1, 1, "XmTextFieldInsert", "TextField Widget"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmTextFieldInsert", "XmTextPosition"); Xen_check_type(Xen_is_string(arg3), arg3, 3, "XmTextFieldInsert", "char*"); XmTextFieldInsert(Xen_to_C_Widget(arg1), Xen_integer_to_C_int(arg2), (char *)Xen_string_to_C_string(arg3)); return(Xen_false); } static Xen gxm_XmTextFieldReplace(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmTextFieldReplace "void XmTextFieldReplace(Widget widget, XmTextPosition from_pos, XmTextPosition to_pos, char *value) \ replaces part of a text string" Xen_check_type(Xen_is_TextFieldWidget(arg1), arg1, 1, "XmTextFieldReplace", "TextField Widget"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmTextFieldReplace", "XmTextPosition"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XmTextFieldReplace", "XmTextPosition"); Xen_check_type(Xen_is_string(arg4), arg4, 4, "XmTextFieldReplace", "char*"); XmTextFieldReplace(Xen_to_C_Widget(arg1), Xen_integer_to_C_int(arg2), Xen_integer_to_C_int(arg3), (char *)Xen_string_to_C_string(arg4)); return(Xen_false); } static Xen gxm_XmTextFieldSetString(Xen arg1, Xen arg2) { #define H_XmTextFieldSetString "void XmTextFieldSetString(Widget widget, char *value) sets the string value" Xen_check_type(Xen_is_TextFieldWidget(arg1), arg1, 1, "XmTextFieldSetString", "TextField Widget"); Xen_check_type(Xen_is_string(arg2), arg2, 2, "XmTextFieldSetString", "char*"); XmTextFieldSetString(Xen_to_C_Widget(arg1), (char *)Xen_string_to_C_string(arg2)); return(Xen_false); } static Xen gxm_XmTextFieldGetLastPosition(Xen arg1) { #define H_XmTextFieldGetLastPosition "XmTextPosition XmTextFieldGetLastPosition(Widget widget) accesses \ the position of the last text character" Xen_check_type(Xen_is_TextFieldWidget(arg1), arg1, 1, "XmTextFieldGetLastPosition", "TextField Widget"); return(C_int_to_Xen_integer(XmTextFieldGetLastPosition(Xen_to_C_Widget(arg1)))); } static Xen gxm_XmTextFieldGetSubstring(Xen arg1, Xen arg2, Xen arg3) { /* DIFF: omit and rtn last 2 args */ #define H_XmTextFieldGetSubstring "int XmTextFieldGetSubstring(Widget widget, XmTextPosition start, int num_chars) \ retrieves a copy of a portion of the internal text buffer" int rtn, len; char *buf; Xen str = Xen_false; Xen_check_type(Xen_is_TextFieldWidget(arg1), arg1, 1, "XmTextFieldGetSubstring", "TextField Widget"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmTextFieldGetSubstring", "XmTextPosition"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XmTextFieldGetSubstring", "int"); len = Xen_integer_to_C_int(arg3); buf = (char *)calloc(len + 1, sizeof(char)); rtn = XmTextFieldGetSubstring(Xen_to_C_Widget(arg1), Xen_integer_to_C_int(arg2), len, len + 1, buf); if (rtn != XmCOPY_FAILED) str = C_string_to_Xen_string(buf); free(buf); return(str); } static Xen gxm_XmTextFieldGetString(Xen arg1) { char *str; Xen res; #define H_XmTextFieldGetString "char *XmTextFieldGetString(Widget widget) accesses the string value" Xen_check_type(Xen_is_TextFieldWidget(arg1), arg1, 1, "XmTextFieldGetString", "TextField Widget"); str = XmTextFieldGetString(Xen_to_C_Widget(arg1)); res = C_string_to_Xen_string(str); if (str) XtFree(str); return(res); } static Xen gxm_XmDropTransferAdd(Xen arg1, Xen arg2) { #define H_XmDropTransferAdd "void XmDropTransferAdd(Widget drop_transfer, XmDropTransferEntryRec *transfers) \ enables additional drop transfer entries to be processed after initiating a drop transfer" /* DIFF: XmDropTransferAdd arg2 is list of (atom data) lists, arg3 omitted */ int len; XmDropTransferEntryRec *entries; Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmDropTransferAdd", "Widget"); Xen_check_type(Xen_is_list(arg2), arg2, 2, "XmDropTransferAdd", "XmDropTransferEntry"); len = Xen_list_length(arg2); if (len <= 0) return(Xen_false); entries = Xen_to_C_XmDropTransferEntryRecs(arg2, len); XmDropTransferAdd(Xen_to_C_Widget(arg1), entries, len); free(entries); return(Xen_false); } static Xen gxm_XmDropTransferStart(Xen arg1, Xen arg2, Xen arg3) { #define H_XmDropTransferStart "Widget XmDropTransferStart(Widget widget, ArgList arglist, Cardinal argcount) \ initiates a drop transfer" Widget w; Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmDropTransferStart", "Widget"); Xen_check_type(Xen_is_list(arg2), arg2, 2, "XmDropTransferStart", "ArgList"); Xen_check_type(Xen_is_integer_or_unbound(arg3), arg3, 3, "XmDropTransferStart", "int"); { Arg *args; int arglen; args = Xen_to_C_Args(arg2); arglen = Xen_to_C_INT_DEF(arg3, arg2); w = XmDropTransferStart(Xen_to_C_Widget(arg1), args, arglen); if (args) { fixup_args(w, args, arglen); free_args(args, arglen); } } return(C_to_Xen_Widget(w)); } static Xen gxm_XmDropSiteConfigureStackingOrder(Xen arg1, Xen arg2, Xen arg3) { #define H_XmDropSiteConfigureStackingOrder "void XmDropSiteConfigureStackingOrder(Widget widget, Widget sibling, Cardinal stack_mode) \ reorders a stack of widgets that are registered drop sites" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmDropSiteConfigureStackingOrder", "Widget"); Xen_check_type(Xen_is_Widget(arg2), arg2, 2, "XmDropSiteConfigureStackingOrder", "Widget"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XmDropSiteConfigureStackingOrder", "int"); XmDropSiteConfigureStackingOrder(Xen_to_C_Widget(arg1), Xen_to_C_Widget(arg2), Xen_integer_to_C_int(arg3)); return(Xen_false); } static Xen gxm_XmDropSiteQueryStackingOrder(Xen arg1) { #define H_XmDropSiteQueryStackingOrder "Status XmDropSiteQueryStackingOrder(Widget widget): (list parent child ...)" /* DIFF: XmDropSiteQueryStackingOrder widget [parent child numchild] -> (list parent child ...) no parent children num_children -- returned as '(parent child1...) or #f */ Widget parent; Widget *children; Xen lst = Xen_empty_list; unsigned int num_children; int res, i, loc; Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmDropSiteQueryStackingOrder", "Widget"); res = XmDropSiteQueryStackingOrder(Xen_to_C_Widget(arg1), &parent, &children, &num_children); if (res == 0) return(Xen_false); loc = xm_protect(lst); for (i = num_children - 1; i >= 0; i--) lst = Xen_cons(C_to_Xen_Widget(children[i]), lst); xm_unprotect_at(loc); return(Xen_cons(C_to_Xen_Widget(parent), lst)); } static Xen gxm_XmDropSiteRetrieve(Xen arg1, Xen larg2, Xen arg3) { #define H_XmDropSiteRetrieve "void XmDropSiteRetrieve(Widget widget, ArgList arglist, Cardinal argcount) \ retrieves resource values set on a drop site" Arg *args; unsigned long *locs; Xen val = Xen_false; int i, len, gcloc; Xen arg2; Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmDropSiteRetrieve", "Widget"); Xen_check_type(Xen_is_list(larg2), larg2, 2, "XmDropSiteRetrieve", "ArgList"); Xen_check_type(Xen_is_integer_or_unbound(arg3), arg3, 3, "XmDropSiteRetrieve", "int"); arg2 = Xen_copy_arg(larg2); gcloc = xm_protect(arg2); len = Xen_to_C_INT_DEF(arg3, larg2); if (len <= 0) Xen_check_type(0, arg3, 3, "XmDropSiteRetrieve", "positive integer"); args = (Arg *)calloc(len, sizeof(Arg)); locs = (unsigned long *)calloc(len, sizeof(unsigned long)); for (i = 0; i < len; i++, arg2 = Xen_cddr(arg2)) { char *name; name = xen_strdup(Xen_string_to_C_string(Xen_car(arg2))); XtSetArg(args[i], name, &(locs[i])); } XmDropSiteRetrieve(Xen_to_C_Widget(arg1), args, len); val = C_to_Xen_Args((Widget)(Xen_to_C_Widget(arg1)), args, len); free_args(args, len); free(locs); xm_unprotect_at(gcloc); return(val); } static Xen gxm_XmDropSiteEndUpdate(Xen arg1) { #define H_XmDropSiteEndUpdate "void XmDropSiteEndUpdate(Widget widget) facilitates processing updates to multiple drop sites" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmDropSiteEndUpdate", "Widget"); XmDropSiteEndUpdate(Xen_to_C_Widget(arg1)); return(Xen_false); } static Xen gxm_XmDropSiteUpdate(Xen arg1, Xen arg2, Xen arg3) { #define H_XmDropSiteUpdate "void XmDropSiteUpdate(Widget widget, ArgList arglist, Cardinal argcount) sets \ resource values for a drop site" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmDropSiteUpdate", "Widget"); Xen_check_type(Xen_is_list(arg2), arg2, 2, "XmDropSiteUpdate", "ArgList"); Xen_check_type(Xen_is_integer_or_unbound(arg3), arg3, 3, "XmDropSiteUpdate", "int"); { Widget w; Arg *args; int arglen; w = Xen_to_C_Widget(arg1); args = Xen_to_C_Args(arg2); arglen = Xen_to_C_INT_DEF(arg3, arg2); XmDropSiteUpdate(w, args, arglen); if (args) { fixup_args(w, args, arglen); free_args(args, arglen); } } return(Xen_false); } static Xen gxm_XmDropSiteStartUpdate(Xen arg1) { #define H_XmDropSiteStartUpdate "void XmDropSiteStartUpdate(Widget widget) facilitates processing updates \ to multiple drop sites" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmDropSiteStartUpdate", "Widget"); XmDropSiteStartUpdate(Xen_to_C_Widget(arg1)); return(Xen_false); } static Xen gxm_XmDropSiteRegistered(Xen arg1) { #define H_XmDropSiteRegistered "Boolean XmDropSiteRegistered(Widget widget) determines if a drop site has been registered" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmDropSiteRegistered", "Widget"); return(C_bool_to_Xen_boolean(XmDropSiteRegistered(Xen_to_C_Widget(arg1)))); } static Xen gxm_XmDropSiteUnregister(Xen arg1) { #define H_XmDropSiteUnregister "void XmDropSiteUnregister(Widget widget) frees drop site information" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmDropSiteUnregister", "Widget"); XmDropSiteUnregister(Xen_to_C_Widget(arg1)); return(Xen_false); } static Xen gxm_XmDropSiteRegister(Xen arg1, Xen arg2, Xen arg3) { #define H_XmDropSiteRegister "void XmDropSiteRegister(Widget widget, ArgList arglist, Cardinal argcount) \ identifies a drop site and assigns resources that specify its behavior" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmDropSiteRegister", "Widget"); Xen_check_type(Xen_is_list(arg2), arg2, 2, "XmDropSiteRegister", "ArgList"); Xen_check_type(Xen_is_integer_or_unbound(arg3), arg3, 3, "XmDropSiteRegister", "int"); { Widget w; Arg *args; int arglen; w = Xen_to_C_Widget(arg1); args = Xen_to_C_Args(arg2); arglen = Xen_to_C_INT_DEF(arg3, arg2); XmDropSiteRegister(w, args, arglen); if (args) { fixup_args(w, args, arglen); free_args(args, arglen); } } return(Xen_false); } static Xen gxm_XmSimpleSpinBoxSetItem(Xen arg1, Xen arg2) { #define H_XmSimpleSpinBoxSetItem "void XmSimpleSpinBoxSetItem(Widget w, XmString item) set an item in the XmSimpleSpinBox list" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmSimpleSpinBoxSetItem", "Widget"); Xen_check_type(Xen_is_XmString(arg2), arg2, 2, "XmSimpleSpinBoxSetItem", "XmString"); XmSimpleSpinBoxSetItem(Xen_to_C_Widget(arg1), Xen_to_C_XmString(arg2)); return(Xen_false); } static Xen gxm_XmSimpleSpinBoxDeletePos(Xen arg1, Xen arg2) { #define H_XmSimpleSpinBoxDeletePos "void XmSimpleSpinBoxDeletePos(Widget w, int pos) delete a XmSimpleSpinBox item" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmSimpleSpinBoxDeletePos", "Widget"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmSimpleSpinBoxDeletePos", "int"); XmSimpleSpinBoxDeletePos(Xen_to_C_Widget(arg1), Xen_integer_to_C_int(arg2)); return(Xen_false); } static Xen gxm_XmSimpleSpinBoxAddItem(Xen arg1, Xen arg2, Xen arg3) { #define H_XmSimpleSpinBoxAddItem "void XmSimpleSpinBoxAddItem(Widget w, XmString item, int pos) add an item to the XmSimpleSpinBox" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmSimpleSpinBoxAddItem", "Widget"); Xen_check_type(Xen_is_XmString(arg2), arg2, 2, "XmSimpleSpinBoxAddItem", "XmString"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XmSimpleSpinBoxAddItem", "int"); XmSimpleSpinBoxAddItem(Xen_to_C_Widget(arg1), Xen_to_C_XmString(arg2), Xen_integer_to_C_int(arg3)); return(Xen_false); } static Xen gxm_XmCreateSimpleSpinBox(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateSimpleSpinBox "Widget XmCreateSimpleSpinBox(Widget parent, String name, ArgList arglist, Cardinal argcount) \ The SimpleSpinBox widget creation function" return(gxm_new_widget("XmCreateSimpleSpinBox", XmCreateSimpleSpinBox, arg1, arg2, arg3, arg4)); } static Xen gxm_XmCreateDrawnButton(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateDrawnButton "Widget XmCreateDrawnButton(Widget parent, String name, ArgList arglist, Cardinal argcount) \ The DrawnButton widget creation function" return(gxm_new_widget("XmCreateDrawnButton", XmCreateDrawnButton, arg1, arg2, arg3, arg4)); } static Xen gxm_XmSpinBoxValidatePosition(Xen arg1) { #define H_XmSpinBoxValidatePosition "int XmSpinBoxValidatePosition(Widget textfield) translate the current value of \ the specified XmSpinBox child into a valid position" /* DIFF: XmSpinBoxValidatePosition omits arg2, returns pos */ int pos; Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmSpinBoxValidatePosition", "Widget"); XmSpinBoxValidatePosition(Xen_to_C_Widget(arg1), &pos); return(C_int_to_Xen_integer(pos)); } static Xen gxm_XmCreateSpinBox(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateSpinBox "The SpinBox creation function" return(gxm_new_widget("XmCreateSpinBox", XmCreateSpinBox, arg1, arg2, arg3, arg4)); } static Xen gxm_XmCreateDrawingArea(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateDrawingArea "Widget XmCreateDrawingArea(Widget parent, String name, ArgList arglist, Cardinal argcount) \ The DrawingArea widget creation function" return(gxm_new_widget("XmCreateDrawingArea", XmCreateDrawingArea, arg1, arg2, arg3, arg4)); } static Xen gxm_XmCreateSeparator(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateSeparator "Widget XmCreateSeparator(Widget parent, String name, ArgList arglist, Cardinal argcount) \ The Separator widget creation function" return(gxm_new_widget("XmCreateSeparator", XmCreateSeparator, arg1, arg2, arg3, arg4)); } static Xen gxm_XmCreateDragIcon(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateDragIcon "Widget XmCreateDragIcon(Widget widget, String name, ArgList arglist, Cardinal argcount) \ creates a DragIcon widget" return(gxm_new_widget("XmCreateDragIcon", XmCreateDragIcon, arg1, arg2, arg3, arg4)); } static Xen gxm_XmCreateSeparatorGadget(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateSeparatorGadget "Widget XmCreateSeparatorGadget(Widget parent, String name, ArgList arglist, Cardinal argcount) \ The SeparatorGadget creation function" return(gxm_new_widget("XmCreateSeparatorGadget", XmCreateSeparatorGadget, arg1, arg2, arg3, arg4)); } static Xen gxm_XmTargetsAreCompatible(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5) { #define H_XmTargetsAreCompatible "Boolean XmTargetsAreCompatible(Display *display, Atom *export_targets, Cardinal num_export_targets, \ Atom *import_targets, Cardinal num_import_targets) tests whether the target types match between a drop site and source object" /* DIFF: XmTargetsAreCompatible arg2 and arg4 are lists of Atoms */ Atom *outs, *ins; int val, len1, len2; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XmTargetsAreCompatible", "Display*"); Xen_check_type(Xen_is_list(arg2), arg2, 2, "XmTargetsAreCompatible", "list of Atom"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XmTargetsAreCompatible", "int"); Xen_check_type(Xen_is_list(arg4), arg4, 4, "XmTargetsAreCompatible", "list of Atom"); Xen_check_type(Xen_is_integer(arg5), arg5, 5, "XmTargetsAreCompatible", "int"); len1 = Xen_integer_to_C_int(arg3); outs = Xen_to_C_Atoms(arg2, len1); len2 = Xen_integer_to_C_int(arg5); ins = Xen_to_C_Atoms(arg4, len2); val = XmTargetsAreCompatible(Xen_to_C_Display(arg1), outs, len1, ins, len2); free(outs); free(ins); return(C_bool_to_Xen_boolean(val)); } static Xen gxm_XmDragCancel(Xen arg1) { #define H_XmDragCancel "void XmDragCancel(Widget dragcontext) terminates a drag transaction" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmDragCancel", "Widget"); XmDragCancel(Xen_to_C_Widget(arg1)); return(Xen_false); } static Xen gxm_XmDragStart(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmDragStart "Widget XmDragStart(Widget widget, XEvent *event, ArgList arglist, Cardinal argcount) \ initiates a drag and drop transaction" Widget w; Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmDragStart", "Widget"); Xen_check_type(Xen_is_XEvent(arg2), arg2, 2, "XmDragStart", "XEvent*"); Xen_check_type(Xen_is_list(arg3), arg3, 3, "XmDragStart", "ArgList"); Xen_check_type(Xen_is_integer_or_unbound(arg4), arg4, 4, "XmDragStart", "int"); { Arg *args; int arglen; args = Xen_to_C_Args(arg3); arglen = Xen_to_C_INT_DEF(arg4, arg3); w = XmDragStart(Xen_to_C_Widget(arg1), Xen_to_C_XEvent(arg2), args, arglen); if (args) { fixup_args(w, args, arglen); free_args(args, arglen); } } return(C_to_Xen_Widget(w)); } static Xen gxm_XmCreatePromptDialog(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreatePromptDialog "Widget XmCreatePromptDialog(Widget parent, String name, ArgList arglist, Cardinal argcount) \ The SelectionBox PromptDialog creation function" return(gxm_new_widget("XmCreatePromptDialog", XmCreatePromptDialog, arg1, arg2, arg3, arg4)); } static Xen gxm_XmCreateSelectionDialog(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateSelectionDialog "Widget XmCreateSelectionDialog(Widget parent, String name, ArgList arglist, Cardinal argcount) \ The SelectionBox SelectionDialog creation function" return(gxm_new_widget("XmCreateSelectionDialog", XmCreateSelectionDialog, arg1, arg2, arg3, arg4)); } static Xen gxm_XmCreateSelectionBox(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateSelectionBox "Widget XmCreateSelectionBox(Widget parent, String name, ArgList arglist, Cardinal argcount) \ The SelectionBox widget creation function" return(gxm_new_widget("XmCreateSelectionBox", XmCreateSelectionBox, arg1, arg2, arg3, arg4)); } static Xen gxm_XmSelectionBoxGetChild(Xen arg1, Xen arg2) { #define H_XmSelectionBoxGetChild "Widget XmSelectionBoxGetChild(Widget widget, unsigned char child) used to access a SelectionBox component" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmSelectionBoxGetChild", "Widget"); Xen_check_type(Xen_is_ulong(arg2), arg2, 2, "XmSelectionBoxGetChild", "unsigned int"); return(C_to_Xen_Widget(XmSelectionBoxGetChild(Xen_to_C_Widget(arg1), Xen_ulong_to_C_ulong(arg2)))); } static Xen gxm_XmGetXmDisplay(Xen arg1) { #define H_XmGetXmDisplay "Widget XmGetXmDisplay(Display *display) A Display function that returns the" Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XmGetXmDisplay", "Display*"); return(C_to_Xen_Widget(XmGetXmDisplay(Xen_to_C_Display(arg1)))); } static Xen gxm_XmGetDragContext(Xen arg1, Xen arg2) { #define H_XmGetDragContext "Widget XmGetDragContext(Widget refwidget, Time timestamp) retrieves \ the DragContext widget ID associated with a timestamp" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmGetDragContext", "Widget"); Xen_check_type(Xen_is_Time(arg2), arg2, 2, "XmGetDragContext", "Time"); return(C_to_Xen_Widget(XmGetDragContext(Xen_to_C_Widget(arg1), Xen_to_C_Time(arg2)))); } static Xen gxm_XmScrollVisible(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmScrollVisible "void XmScrollVisible(Widget scrollw_widget, Widget widget, Dimension left_right_margin, Dimension top_bottom_margin) \ makes an invisible descendant of a ScrolledWindow work area visible" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmScrollVisible", "Widget"); Xen_check_type(Xen_is_Widget(arg2), arg2, 2, "XmScrollVisible", "Widget"); Xen_check_type(Xen_is_Dimension(arg3), arg3, 3, "XmScrollVisible", "Dimension"); Xen_check_type(Xen_is_Dimension(arg4), arg4, 4, "XmScrollVisible", "Dimension"); XmScrollVisible(Xen_to_C_Widget(arg1), Xen_to_C_Widget(arg2), Xen_to_C_Dimension(arg3), Xen_to_C_Dimension(arg4)); return(Xen_false); } static Xen gxm_XmCreateScrolledWindow(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateScrolledWindow "Widget XmCreateScrolledWindow(Widget parent, String name, ArgList arglist, Cardinal argcount) \ The ScrolledWindow widget creation function" return(gxm_new_widget("XmCreateScrolledWindow", XmCreateScrolledWindow, arg1, arg2, arg3, arg4)); } static Xen gxm_XmCreateDialogShell(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateDialogShell "Widget XmCreateDialogShell(Widget parent, String name, ArgList arglist, Cardinal argcount) \ The DialogShell widget creation function" return(gxm_new_widget("XmCreateDialogShell", XmCreateDialogShell, arg1, arg2, arg3, arg4)); } static Xen gxm_XmScrollBarSetValues(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6) { #define H_XmScrollBarSetValues "void XmScrollBarSetValues (widget, value, slider_size, increment, page_increment, notify) \ changes ScrollBar's increment values and the slider's size and position" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmScrollBarSetValues", "Widget"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmScrollBarSetValues", "int"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XmScrollBarSetValues", "int"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XmScrollBarSetValues", "int"); Xen_check_type(Xen_is_integer(arg5), arg5, 5, "XmScrollBarSetValues", "int"); Xen_check_type(Xen_is_boolean(arg6), arg6, 6, "XmScrollBarSetValues", "boolean"); XmScrollBarSetValues(Xen_to_C_Widget(arg1), Xen_integer_to_C_int(arg2), Xen_integer_to_C_int(arg3), Xen_integer_to_C_int(arg4), Xen_integer_to_C_int(arg5), Xen_boolean_to_C_bool(arg6)); return(Xen_false); } static Xen gxm_XmScrollBarGetValues(Xen arg1) { #define H_XmScrollBarGetValues "void XmScrollBarGetValues (widget): returns the ScrollBar's increment values (list val size incr page)" /* DIFF: XmScrollBarGetValues omits and returns last 4 args */ int val, size, incr, page; Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmScrollBarGetValues", "Widget"); XmScrollBarGetValues(Xen_to_C_Widget(arg1), &val, &size, &incr, &page); return(Xen_list_4(C_int_to_Xen_integer(val), C_int_to_Xen_integer(size), C_int_to_Xen_integer(incr), C_int_to_Xen_integer(page))); } static Xen gxm_XmCreateScrollBar(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateScrollBar "Widget XmCreateScrollBar(Widget parent, String name, ArgList arglist, Cardinal argcount) \ The ScrollBar widget creation function" return(gxm_new_widget("XmCreateScrollBar", XmCreateScrollBar, arg1, arg2, arg3, arg4)); } static Xen gxm_XmGetXmScreen(Xen arg1) { #define H_XmGetXmScreen "Widget XmGetXmScreen(Screen *screen): returns the XmScreen object ID for a specified screen" /* this is the Motif Screen "widget" */ Xen_check_type(Xen_is_Screen(arg1), arg1, 1, "XmGetXmScreen", "Screen*"); return(C_to_Xen_Widget(XmGetXmScreen(Xen_to_C_Screen(arg1)))); } static Xen gxm_XmClipboardRegisterFormat(Xen arg1, Xen arg2, Xen arg3) { #define H_XmClipboardRegisterFormat "int XmClipboardRegisterFormat (display, format_name, format_length) registers a new format" Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XmClipboardRegisterFormat", "Display*"); Xen_check_type(Xen_is_string(arg2), arg2, 2, "XmClipboardRegisterFormat", "char*"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XmClipboardRegisterFormat", "int"); return(C_int_to_Xen_integer(XmClipboardRegisterFormat(Xen_to_C_Display(arg1), (char *)Xen_string_to_C_string(arg2), Xen_integer_to_C_int(arg3)))); } static Xen gxm_XmClipboardInquirePendingItems(Xen arg1, Xen arg2, Xen arg3) { #define H_XmClipboardInquirePendingItems "int XmClipboardInquirePendingItems (display, window, format_name) \ returns a list of data ID/private ID pairs" /* DIFF: XmClipboardInquirePendingItems omits last 2 args, returns list of pairs */ unsigned long len; XmClipboardPendingList clst; int i, loc, rtn; Xen lst = Xen_empty_list; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XmClipboardInquirePendingItems", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XmClipboardInquirePendingItems", "Window"); Xen_check_type(Xen_is_string(arg3), arg3, 3, "XmClipboardInquirePendingItems", "char*"); rtn = XmClipboardInquirePendingItems(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), (char *)Xen_string_to_C_string(arg3), &clst, &len); loc = xm_protect(lst); for (i = len - 1; i >= 0; i--) lst = Xen_cons(Xen_list_2(C_int_to_Xen_integer(clst[i].DataId), C_int_to_Xen_integer(clst[i].PrivateId)), lst); lst = Xen_cons(C_int_to_Xen_integer(rtn), lst); xm_unprotect_at(loc); return(lst); } static Xen gxm_XmClipboardInquireLength(Xen arg1, Xen arg2, Xen arg3) { #define H_XmClipboardInquireLength "int XmClipboardInquireLength (display, window, format_name): returns the length of the stored data" /* DIFF: XmClipboardInquireLength omit and rtn last arg */ unsigned long len; int val; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XmClipboardInquireLength", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XmClipboardInquireLength", "Window"); Xen_check_type(Xen_is_string(arg3), arg3, 3, "XmClipboardInquireLength", "char*"); val = XmClipboardInquireLength(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), (char *)Xen_string_to_C_string(arg3), &len); return(Xen_list_2(C_int_to_Xen_integer(val), C_ulong_to_Xen_ulong(len))); } static Xen gxm_XmClipboardInquireFormat(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmClipboardInquireFormat "int XmClipboardInquireFormat (display, window, index, buffer_len) \ returns a specified format name" /* DIFF: XmClipboardInquireFormat omits arg4 (XtPointer buffer) and arg6, returns them */ Xen res; XtPointer buf; unsigned long len, n; int val; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XmClipboardInquireFormat", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XmClipboardInquireFormat", "Window"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XmClipboardInquireFormat", "int"); Xen_check_type(Xen_is_ulong(arg4), arg4, 4, "XmClipboardInquireFormat", "ulong"); len = Xen_ulong_to_C_ulong(arg4); if (len == 0) return(Xen_false); buf = (XtPointer)calloc(len + 1, sizeof(char)); val = XmClipboardInquireFormat(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_integer_to_C_int(arg3), buf, len, &n); res = C_string_to_Xen_string((char *)buf); free(buf); return(Xen_list_2(C_int_to_Xen_integer(val), res)); } static Xen gxm_XmClipboardInquireCount(Xen arg1, Xen arg2) { #define H_XmClipboardInquireCount "int XmClipboardInquireCount (display, window): returns the number of data item formats" /* DIFF: XmClipboardInquireCount omits and rtns last 2 args */ int count, val; unsigned long len; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XmClipboardInquireCount", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XmClipboardInquireCount", "Window"); val = XmClipboardInquireCount(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), &count, &len); return(Xen_list_3(C_int_to_Xen_integer(val), C_int_to_Xen_integer(count), C_ulong_to_Xen_ulong(len))); } static Xen gxm_XmClipboardRetrieve(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmClipboardRetrieve "int XmClipboardRetrieve (display, window, format_name, length) retrieves a data item from the clipboard" /* DIFF: XmClipboardRetrieve omits buf arg, and last 2, returning them and a list of ulongs */ unsigned long n; long id; XtPointer buf; int len, val; Xen str; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XmClipboardRetrieve", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XmClipboardRetrieve", "Window"); Xen_check_type(Xen_is_string(arg3), arg3, 3, "XmClipboardRetrieve", "char*"); Xen_check_type(Xen_is_ulong(arg4), arg4, 4, "XmClipboardRetrieve", "ulong"); len = Xen_ulong_to_C_ulong(arg4); if (len <= 0) return(Xen_false); buf = (XtPointer)malloc(len); val = XmClipboardRetrieve(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), (char *)Xen_string_to_C_string(arg3), buf, len, &n, &id); str = C_string_to_Xen_string((char *)buf); free(buf); return(Xen_list_3(C_int_to_Xen_integer(val), str, C_ulong_to_Xen_ulong(id))); } static Xen gxm_XmClipboardEndRetrieve(Xen arg1, Xen arg2) { #define H_XmClipboardEndRetrieve "int XmClipboardEndRetrieve (display, window) completes retrieval of \ data from the clipboard" Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XmClipboardEndRetrieve", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XmClipboardEndRetrieve", "Window"); return(C_int_to_Xen_integer(XmClipboardEndRetrieve(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2)))); } static Xen gxm_XmClipboardStartRetrieve(Xen arg1, Xen arg2, Xen arg3) { #define H_XmClipboardStartRetrieve "int XmClipboardStartRetrieve (display, window, timestamp) \ prepares to retrieve data from the clipboard" Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XmClipboardStartRetrieve", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XmClipboardStartRetrieve", "Window"); Xen_check_type(Xen_is_Time(arg3), arg3, 3, "XmClipboardStartRetrieve", "Time"); return(C_int_to_Xen_integer(XmClipboardStartRetrieve(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_to_C_Time(arg3)))); } static Xen gxm_XmClipboardUnlock(Xen arg1, Xen arg2, Xen arg3) { #define H_XmClipboardUnlock "int XmClipboardUnlock (display, window, remove_all_locks) unlocks the clipboard" Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XmClipboardUnlock", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XmClipboardUnlock", "Window"); Xen_check_type(Xen_is_boolean(arg3), arg3, 3, "XmClipboardUnlock", "boolean"); return(C_int_to_Xen_integer(XmClipboardUnlock(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_boolean_to_C_bool(arg3)))); } static Xen gxm_XmClipboardLock(Xen arg1, Xen arg2) { #define H_XmClipboardLock "int XmClipboardLock (display, window) locks the clipboard" Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XmClipboardLock", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XmClipboardLock", "Window"); return(C_int_to_Xen_integer(XmClipboardLock(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2)))); } static Xen gxm_XmClipboardUndoCopy(Xen arg1, Xen arg2) { #define H_XmClipboardUndoCopy "int XmClipboardUndoCopy (display, window) deletes the last item placed on the clipboard" Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XmClipboardUndoCopy", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XmClipboardUndoCopy", "Window"); return(C_int_to_Xen_integer(XmClipboardUndoCopy(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2)))); } static Xen gxm_XmClipboardCopyByName(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6) { #define H_XmClipboardCopyByName "int XmClipboardCopyByName (display, window, data_id, buf, len, id) copies a data item passed by name" /* DIFF: XmClipboardCopyByName arg4 is string */ Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XmClipboardCopyByName", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XmClipboardCopyByName", "Window"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XmClipboardCopyByName", "long"); Xen_check_type(Xen_is_string(arg4), arg4, 4, "XmClipboardCopyByName", "XtPointer"); Xen_check_type(Xen_is_ulong(arg5), arg5, 5, "XmClipboardCopyByName", "ulong"); return(C_int_to_Xen_integer(XmClipboardCopyByName(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_integer_to_C_int(arg3), (XtPointer)Xen_string_to_C_string(arg4), Xen_ulong_to_C_ulong(arg5), (unsigned long)arg6))); } static Xen gxm_XmClipboardWithdrawFormat(Xen arg1, Xen arg2, Xen arg3) { #define H_XmClipboardWithdrawFormat "int XmClipboardWithdrawFormat (display, window, data_id) \ indicates that the application no longer wants to supply a data item" Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XmClipboardWithdrawFormat", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XmClipboardWithdrawFormat", "Window"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XmClipboardWithdrawFormat", "long"); return(C_int_to_Xen_integer(XmClipboardWithdrawFormat(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_integer_to_C_int(arg3)))); } static Xen gxm_XmClipboardCancelCopy(Xen arg1, Xen arg2, Xen arg3) { #define H_XmClipboardCancelCopy "int XmClipboardCancelCopy (display, window, item_id) cancels a copy to the clipboard" Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XmClipboardCancelCopy", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XmClipboardCancelCopy", "Window"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XmClipboardCancelCopy", "long"); return(C_int_to_Xen_integer(XmClipboardCancelCopy(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_integer_to_C_int(arg3)))); } static Xen gxm_XmClipboardEndCopy(Xen arg1, Xen arg2, Xen arg3) { #define H_XmClipboardEndCopy "int XmClipboardEndCopy (display, window, item_id) completes the \ copying of data to the clipboard" Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XmClipboardEndCopy", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XmClipboardEndCopy", "Window"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XmClipboardEndCopy", "long"); return(C_int_to_Xen_integer(XmClipboardEndCopy(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_integer_to_C_int(arg3)))); } static Xen gxm_XmClipboardCopy(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6, Xen arg7) { #define H_XmClipboardCopy "int XmClipboardCopy (display, window, item_id, format_name, buffer, len, id) copies a data item \ to temporary storage for later copying to clipboard" /* DIFF: XmClipboardCopy omits and returns last arg, arg5 is string */ long id; int val; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XmClipboardCopy", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XmClipboardCopy", "Window"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XmClipboardCopy", "long"); Xen_check_type(Xen_is_string(arg4), arg4, 4, "XmClipboardCopy", "char*"); Xen_check_type(Xen_is_string(arg5), arg5, 5, "XmClipboardCopy", "XtPointer"); Xen_check_type(Xen_is_ulong(arg6), arg6, 6, "XmClipboardCopy", "ulong"); Xen_check_type(Xen_is_integer(arg7), arg7, 7, "XmClipboardCopy", "long"); val = XmClipboardCopy(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_integer_to_C_int(arg3), (char *)Xen_string_to_C_string(arg4), (XtPointer)Xen_string_to_C_string(arg5), Xen_ulong_to_C_ulong(arg6), Xen_integer_to_C_int(arg7), &id); return(Xen_list_2(C_int_to_Xen_integer(val), C_int_to_Xen_integer(id))); } /* There's just one clipboard, I think, so these callbacks must be globals */ static Xen xm_XmCutPasteProc; static void gxm_XmCutPasteProc(Widget w, long *data, long *privater, int *reason) { Xen_call_with_4_args(xm_XmCutPasteProc, C_to_Xen_Widget(w), C_ulong_to_Xen_ulong(*data), C_ulong_to_Xen_ulong(*privater), C_int_to_Xen_integer(*reason), __func__); } static Xen gxm_XmClipboardStartCopy(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6) { #define H_XmClipboardStartCopy "int XmClipboardStartCopy (display, window, clip_label, timestamp, widget, callback) \ sets up a storage and data structure, returns id" /* DIFF: XmClipboardStartCopy omits and returns last arg */ long id; int val; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XmClipboardStartCopy", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XmClipboardStartCopy", "Window"); Xen_check_type(Xen_is_XmString(arg3), arg3, 3, "XmClipboardStartCopy", "XmString"); Xen_check_type(Xen_is_Time(arg4), arg4, 4, "XmClipboardStartCopy", "Time"); Xen_check_type(Xen_is_Widget(arg5), arg5, 5, "XmClipboardStartCopy", "Widget"); Xen_check_type(Xen_is_procedure(arg6) && (Xen_is_aritable(arg6, 4)), arg6, 6, "XmClipboardStartCopy", "(XmCutPasteProc widget data priv reason)"); xm_protect(arg6); if (Xen_is_procedure(xm_XmCutPasteProc)) xm_unprotect(xm_XmCutPasteProc); xm_XmCutPasteProc = arg6; val = XmClipboardStartCopy(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_to_C_XmString(arg3), Xen_to_C_Time(arg4), Xen_to_C_Widget(arg5), (XmCutPasteProc)gxm_XmCutPasteProc, &id); return(Xen_list_2(C_int_to_Xen_integer(val), C_int_to_Xen_integer(id))); } static Xen xm_XmVoidProc; static void gxm_XmVoidProc(Widget w, int *data, int *privater, int *reason) { Xen_call_with_4_args(xm_XmVoidProc, C_to_Xen_Widget(w), C_ulong_to_Xen_ulong(*data), C_ulong_to_Xen_ulong(*privater), C_int_to_Xen_integer(*reason), __func__); } static Xen gxm_XmClipboardBeginCopy(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5) { #define H_XmClipboardBeginCopy "int XmClipboardBeginCopy(display, window, XmString label, widget, callback)" /* DIFF: XmClipboardBeinCopy omits and returns last arg */ long id; int val; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XmClipboardBeginCopy", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XmClipboardBeginCopy", "Window"); Xen_check_type(Xen_is_XmString(arg3), arg3, 3, "XmClipboardBeginCopy", "XmString"); Xen_check_type(Xen_is_Widget(arg4), arg4, 4, "XmClipboardBeginCopy", "Widget"); Xen_check_type(Xen_is_procedure(arg5) && (Xen_is_aritable(arg5, 4)), arg5, 5, "XmClipboardBeginCopy", "(XmVoidProc widget data priv reason)"); xm_protect(arg5); if (Xen_is_procedure(xm_XmVoidProc)) xm_unprotect(xm_XmVoidProc); xm_XmVoidProc = arg5; val = XmClipboardBeginCopy(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_to_C_XmString(arg3), Xen_to_C_Widget(arg4), gxm_XmVoidProc, &id); return(Xen_list_2(C_int_to_Xen_integer(val), C_int_to_Xen_integer(id))); } #define Xen_is_ScaleWidget(Arg) (Xen_is_Widget(Arg) && XmIsScale(Xen_to_C_Widget(Arg))) static Xen gxm_XmScaleSetTicks(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6, Xen arg7) { #define H_XmScaleSetTicks "void XmScaleSetTicks(Widget scale, int big_every, Cardinal num_medium, Cardinal num_small, Dimension size_big, \ Dimension size_medium, Dimension size_small) controls Scale tick marks" Xen_check_type(Xen_is_ScaleWidget(arg1), arg1, 1, "XmScaleSetTicks", "Scale Widget"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmScaleSetTicks", "int"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XmScaleSetTicks", "int"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XmScaleSetTicks", "int"); Xen_check_type(Xen_is_Dimension(arg5), arg5, 5, "XmScaleSetTicks", "Dimension"); Xen_check_type(Xen_is_Dimension(arg6), arg6, 6, "XmScaleSetTicks", "Dimension"); Xen_check_type(Xen_is_Dimension(arg7), arg7, 7, "XmScaleSetTicks", "Dimension"); XmScaleSetTicks(Xen_to_C_Widget(arg1), Xen_integer_to_C_int(arg2), Xen_integer_to_C_int(arg3), Xen_integer_to_C_int(arg4), Xen_to_C_Dimension(arg5), Xen_to_C_Dimension(arg6), Xen_to_C_Dimension(arg7)); return(Xen_false); } static Xen gxm_XmCreateScale(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateScale "Widget XmCreateScale(Widget parent, String name, ArgList arglist, Cardinal argcount) \ The Scale widget creation function" return(gxm_new_widget("XmCreateScale", XmCreateScale, arg1, arg2, arg3, arg4)); } static Xen gxm_XmScaleGetValue(Xen arg1) { #define H_XmScaleGetValue "void XmScaleGetValue(Widget widget): returns the current (scale) slider position" /* DIFF: XmScaleGetValue omits and returns arg2 */ int val; Xen_check_type(Xen_is_ScaleWidget(arg1), arg1, 1, "XmScaleGetValue", "Scale Widget"); XmScaleGetValue(Xen_to_C_Widget(arg1), &val); return(C_int_to_Xen_integer(val)); } static Xen gxm_XmScaleSetValue(Xen arg1, Xen arg2) { #define H_XmScaleSetValue "void XmScaleSetValue(Widget widget, int value) sets a Scale slider value" Xen_check_type(Xen_is_ScaleWidget(arg1), arg1, 1, "XmScaleSetValue", "Scale Widget"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmScaleSetValue", "int"); XmScaleSetValue(Xen_to_C_Widget(arg1), Xen_integer_to_C_int(arg2)); return(Xen_false); } #define Xen_is_ContainerWidget(Arg) (Xen_is_Widget(Arg) && XmIsContainer(Xen_to_C_Widget(Arg))) static Xen gxm_XmContainerPasteLink(Xen arg1) { #define H_XmContainerPasteLink "Boolean XmContainerPasteLink(Widget container) container function to insert links from the clipboard" Xen_check_type(Xen_is_ContainerWidget(arg1), arg1, 1, "XmContainerPasteLink", "Container Widget"); return(C_bool_to_Xen_boolean(XmContainerPasteLink(Xen_to_C_Widget(arg1)))); } static Xen gxm_XmContainerCopyLink(Xen arg1, Xen arg2) { #define H_XmContainerCopyLink "Boolean XmContainerCopyLink(Widget container, Time timestamp) Container function to copy links to the clipboard" Xen_check_type(Xen_is_ContainerWidget(arg1), arg1, 1, "XmContainerCopyLink", "Container Widget"); Xen_check_type(Xen_is_Time(arg2), arg2, 2, "XmContainerCopyLink", "Time"); return(C_bool_to_Xen_boolean(XmContainerCopyLink(Xen_to_C_Widget(arg1), Xen_to_C_Time(arg2)))); } static Xen gxm_XmContainerPaste(Xen arg1) { #define H_XmContainerPaste "Boolean XmContainerPaste(Widget container) Container function to insert items from the clipboard" Xen_check_type(Xen_is_ContainerWidget(arg1), arg1, 1, "XmContainerPaste", "Container Widget"); return(C_bool_to_Xen_boolean(XmContainerPaste(Xen_to_C_Widget(arg1)))); } static Xen gxm_XmContainerCopy(Xen arg1, Xen arg2) { #define H_XmContainerCopy "Boolean XmContainerCopy(Widget container, Time timestamp) Container function to copy primary selection to the clipboard" Xen_check_type(Xen_is_ContainerWidget(arg1), arg1, 1, "XmContainerCopy", "Container Widget"); Xen_check_type(Xen_is_Time(arg2), arg2, 2, "XmContainerCopy", "Time"); return(C_bool_to_Xen_boolean(XmContainerCopy(Xen_to_C_Widget(arg1), Xen_to_C_Time(arg2)))); } static Xen gxm_XmContainerCut(Xen arg1, Xen arg2) { #define H_XmContainerCut "Boolean XmContainerCut(Widget container, Time timestamp) Container function to move items to the clipboard" Xen_check_type(Xen_is_ContainerWidget(arg1), arg1, 1, "XmContainerCut", "Container Widget"); Xen_check_type(Xen_is_Time(arg2), arg2, 2, "XmContainerCut", "Time"); return(C_bool_to_Xen_boolean(XmContainerCut(Xen_to_C_Widget(arg1), Xen_to_C_Time(arg2)))); } static Xen gxm_XmContainerReorder(Xen arg1, Xen arg2, Xen arg3) { #define H_XmContainerReorder "void XmContainerReorder(Widget container, WidgetList widgets, int num_widgets) Container function to reorder children" /* DIFF: XmContainerReorder arg2 is list of Widgets */ int len; Xen_check_type(Xen_is_ContainerWidget(arg1), arg1, 1, "XmContainerReorder", "Container Widget"); Xen_check_type(Xen_is_list(arg2), arg2, 2, "XmContainerReorder", "WidgetList"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XmContainerReorder", "int"); len = Xen_integer_to_C_int(arg3); if (len > 0) { if (len > Xen_list_length(arg2)) Xen_out_of_range_error("XmContainerReorder", 3, arg3, "len too large"); else { WidgetList ws; ws = Xen_to_C_Widgets(arg2, len); XmContainerReorder(Xen_to_C_Widget(arg1), ws, len); if (ws) free(ws); } } return(Xen_false); } static Xen gxm_XmContainerRelayout(Xen arg1) { #define H_XmContainerRelayout "void XmContainerRelayout(Widget container) Container relayout function" Xen_check_type(Xen_is_ContainerWidget(arg1), arg1, 1, "XmContainerRelayout", "Container Widget"); XmContainerRelayout(Xen_to_C_Widget(arg1)); return(Xen_false); } static Xen gxm_XmContainerGetItemChildren(Xen arg1, Xen arg2) { #define H_XmContainerGetItemChildren "int XmContainerGetItemChildren(Widget container, Widget item) \ returns a list of all children of an item" /* DIFF: XmContainerGetItemChildren omits arg3, rtns widget list */ Widget *ws; int len; Xen_check_type(Xen_is_ContainerWidget(arg1), arg1, 1, "XmContainerGetItemChildren", "Container Widget"); Xen_check_type(Xen_is_Widget(arg2), arg2, 2, "XmContainerGetItemChildren", "Widget"); len = XmContainerGetItemChildren(Xen_to_C_Widget(arg1), Xen_to_C_Widget(arg2), &ws); return(C_to_Xen_Widgets(ws, len)); } static Xen gxm_XmCreateContainer(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateContainer "Widget XmCreateContainer(Widget parent, String name, ArgList arglist, Cardinal argcount) \ The Container creation function" return(gxm_new_widget("XmCreateContainer", XmCreateContainer, arg1, arg2, arg3, arg4)); } static Xen gxm_XmGetTearOffControl(Xen arg1) { #define H_XmGetTearOffControl "Widget XmGetTearOffControl(Widget menu) obtains the widget ID for the tear-off control in a menu" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmGetTearOffControl", "Widget"); return(C_to_Xen_Widget(XmGetTearOffControl(Xen_to_C_Widget(arg1)))); } static Xen gxm_XmGetPostedFromWidget(Xen arg1) { #define H_XmGetPostedFromWidget "Widget XmGetPostedFromWidget(Widget menu): returns the widget from which a menu was posted" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmGetPostedFromWidget", "Widget"); return(C_to_Xen_Widget(XmGetPostedFromWidget(Xen_to_C_Widget(arg1)))); } static Xen gxm_XmCreatePulldownMenu(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreatePulldownMenu "Widget XmCreatePulldownMenu(Widget parent, String name, ArgList arglist, Cardinal argcount) \ A RowColumn widget creation function" return(gxm_new_widget("XmCreatePulldownMenu", XmCreatePulldownMenu, arg1, arg2, arg3, arg4)); } static Xen gxm_XmCreatePopupMenu(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreatePopupMenu "Widget XmCreatePopupMenu(Widget parent, String name, ArgList arglist, Cardinal argcount) \ A RowColumn widget creation function" return(gxm_new_widget("XmCreatePopupMenu", XmCreatePopupMenu, arg1, arg2, arg3, arg4)); } static Xen gxm_XmCreateMenuBar(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateMenuBar "Widget XmCreateMenuBar(Widget parent, String name, ArgList arglist, Cardinal argcount) \ A RowColumn widget creation function" return(gxm_new_widget("XmCreateMenuBar", XmCreateMenuBar, arg1, arg2, arg3, arg4)); } static Xen gxm_XmOptionButtonGadget(Xen arg1) { #define H_XmOptionButtonGadget "Widget XmOptionButtonGadget(Widget option_menu) obtains \ the widget ID for the CascadeButtonGadget in an OptionMenu" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmOptionButtonGadget", "Widget"); return(C_to_Xen_Widget(XmOptionButtonGadget(Xen_to_C_Widget(arg1)))); } static Xen gxm_XmOptionLabelGadget(Xen arg1) { #define H_XmOptionLabelGadget "Widget XmOptionLabelGadget(Widget option_menu) obtains the \ widget ID for the LabelGadget in an OptionMenu" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmOptionLabelGadget", "Widget"); return(C_to_Xen_Widget(XmOptionLabelGadget(Xen_to_C_Widget(arg1)))); } static Xen gxm_XmCreateOptionMenu(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateOptionMenu "Widget XmCreateOptionMenu(Widget parent, String name, ArgList arglist, Cardinal argcount) \ A RowColumn widget creation function" return(gxm_new_widget("XmCreateOptionMenu", XmCreateOptionMenu, arg1, arg2, arg3, arg4)); } static Xen gxm_XmCreateRadioBox(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateRadioBox "Widget XmCreateRadioBox(Widget parent, String name, ArgList arglist, Cardinal argcount) \ A RowColumn widget creation function" return(gxm_new_widget("XmCreateRadioBox", XmCreateRadioBox, arg1, arg2, arg3, arg4)); } static Xen gxm_XmCreateWorkArea(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateWorkArea "Widget XmCreateWorkArea(Widget parent, String name, ArgList arglist, Cardinal argcount) \ creates a RowColumn WorkArea" return(gxm_new_widget("XmCreateWorkArea", XmCreateWorkArea, arg1, arg2, arg3, arg4)); } static Xen gxm_XmCreateRowColumn(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateRowColumn "Widget XmCreateRowColumn(Widget parent, String name, ArgList arglist, Cardinal argcount) \ The RowColumn widget creation function" return(gxm_new_widget("XmCreateRowColumn", XmCreateRowColumn, arg1, arg2, arg3, arg4)); } static Xen gxm_XmMenuPosition(Xen arg1, Xen arg2) { #define H_XmMenuPosition "void XmMenuPosition(Widget menu, XButtonPressedEvent *event) positions a Popup menu pane" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmMenuPosition", "Widget"); Xen_check_type(Xen_is_XButtonEvent(arg2), arg2, 2, "XmMenuPosition", "XButtonPressedEvent*"); XmMenuPosition(Xen_to_C_Widget(arg1), Xen_to_C_XButtonEvent(arg2)); return(Xen_false); } static Xen gxm_XmCreateCommandDialog(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateCommandDialog "Widget XmCreateCommandDialog(Widget parent, String name, ArgList arglist, Cardinal argcount) \ The Command CommandDialog creation function" return(gxm_new_widget("XmCreateCommandDialog", XmCreateCommandDialog, arg1, arg2, arg3, arg4)); } #define Xen_is_CommandWidget(Arg) (Xen_is_Widget(Arg) && XmIsCommand(Xen_to_C_Widget(Arg))) static Xen gxm_XmCommandError(Xen arg1, Xen arg2) { #define H_XmCommandError "void XmCommandError(Widget widget, XmString error) Command function that displays an error message" Xen_check_type(Xen_is_CommandWidget(arg1), arg1, 1, "XmCommandError", "Command Widget"); Xen_check_type(Xen_is_XmString(arg2), arg2, 2, "XmCommandError", "XmString"); XmCommandError(Xen_to_C_Widget(arg1), Xen_to_C_XmString(arg2)); return(Xen_false); } static Xen gxm_XmCommandAppendValue(Xen arg1, Xen arg2) { #define H_XmCommandAppendValue "void XmCommandAppendValue(Widget widget, XmString command) \ appends the passed XmString to the end of the string displayed in the command area of the widget" Xen_check_type(Xen_is_CommandWidget(arg1), arg1, 1, "XmCommandAppendValue", "Command Widget"); Xen_check_type(Xen_is_XmString(arg2), arg2, 2, "XmCommandAppendValue", "XmString"); XmCommandAppendValue(Xen_to_C_Widget(arg1), Xen_to_C_XmString(arg2)); return(Xen_false); } static Xen gxm_XmCommandSetValue(Xen arg1, Xen arg2) { #define H_XmCommandSetValue "void XmCommandSetValue(Widget widget, XmString command) A Command function that replaces a displayed string" Xen_check_type(Xen_is_CommandWidget(arg1), arg1, 1, "XmCommandSetValue", "Command Widget"); Xen_check_type(Xen_is_XmString(arg2), arg2, 2, "XmCommandSetValue", "XmString"); XmCommandSetValue(Xen_to_C_Widget(arg1), Xen_to_C_XmString(arg2)); return(Xen_false); } static Xen gxm_XmCommandGetChild(Xen arg1, Xen arg2) { #define H_XmCommandGetChild "Widget XmCommandGetChild(Widget widget, unsigned char child) A Command function that is used to access a component" Xen_check_type(Xen_is_CommandWidget(arg1), arg1, 1, "XmCommandGetChild", "Command Widget"); Xen_check_type(Xen_is_ulong(arg2), arg2, 2, "XmCommandGetChild", "unsigned int"); return(C_to_Xen_Widget(XmCommandGetChild(Xen_to_C_Widget(arg1), Xen_ulong_to_C_ulong(arg2)))); } static Xen gxm_XmCreateCommand(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateCommand "Widget XmCreateCommand(Widget parent, String name, ArgList arglist, Cardinal argcount) \ The Command widget creation function" return(gxm_new_widget("XmCreateCommand", XmCreateCommand, arg1, arg2, arg3, arg4)); } #define Xen_is_ComboBoxWidget(Arg) (Xen_is_Widget(Arg) && XmIsComboBox(Xen_to_C_Widget(Arg))) static Xen gxm_XmComboBoxUpdate(Xen arg1) { #define H_XmComboBoxUpdate "void XmComboBoxUpdate(Widget widget) A ComboBox function that resynchronizes data" Xen_check_type(Xen_is_ComboBoxWidget(arg1), arg1, 1, "XmComboBoxUpdate", "ComboBox Widget"); XmComboBoxUpdate(Xen_to_C_Widget(arg1)); return(Xen_false); } static Xen gxm_XmComboBoxSetItem(Xen arg1, Xen arg2) { #define H_XmComboBoxSetItem "void XmComboBoxSetItem(Widget w, XmString item) set an item in the XmComboBox list" Xen_check_type(Xen_is_ComboBoxWidget(arg1), arg1, 1, "XmComboBoxSetItem", "ComboBox Widget"); Xen_check_type(Xen_is_XmString(arg2), arg2, 2, "XmComboBoxSetItem", "XmString"); XmComboBoxSetItem(Xen_to_C_Widget(arg1), Xen_to_C_XmString(arg2)); return(Xen_false); } static Xen gxm_XmComboBoxSelectItem(Xen arg1, Xen arg2) { #define H_XmComboBoxSelectItem "void XmComboBoxSelectItem(Widget w, XmString item) select a XmComboBox item" Xen_check_type(Xen_is_ComboBoxWidget(arg1), arg1, 1, "XmComboBoxSelectItem", "ComboBox Widget"); Xen_check_type(Xen_is_XmString(arg2), arg2, 2, "XmComboBoxSelectItem", "XmString"); XmComboBoxSelectItem(Xen_to_C_Widget(arg1), Xen_to_C_XmString(arg2)); return(Xen_false); } static Xen gxm_XmComboBoxDeletePos(Xen arg1, Xen arg2) { #define H_XmComboBoxDeletePos "void XmComboBoxDeletePos(Widget w, int pos) Delete a XmComboBox item" Xen_check_type(Xen_is_ComboBoxWidget(arg1), arg1, 1, "XmComboBoxDeletePos", "ComboBox Widget"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmComboBoxDeletePos", "int"); XmComboBoxDeletePos(Xen_to_C_Widget(arg1), Xen_integer_to_C_int(arg2)); return(Xen_false); } static Xen gxm_XmComboBoxAddItem(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmComboBoxAddItem "void XmComboBoxAddItem(Widget w, XmString item, int pos, Boolean unique) add an item to the ComboBox widget" Xen_check_type(Xen_is_ComboBoxWidget(arg1), arg1, 1, "XmComboBoxAddItem", "ComboBox Widget"); Xen_check_type(Xen_is_XmString(arg2), arg2, 2, "XmComboBoxAddItem", "XmString"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XmComboBoxAddItem", "int"); Xen_check_type(Xen_is_boolean(arg4), arg4, 4, "XmComboBoxAddItem", "Boolean"); XmComboBoxAddItem(Xen_to_C_Widget(arg1), Xen_to_C_XmString(arg2), Xen_integer_to_C_int(arg3), Xen_boolean_to_C_bool(arg4)); return(Xen_false); } static Xen gxm_XmCreateDropDownList(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateDropDownList "Widget XmCreateDropDownList(Widget parent, String name, ArgList arglist, Cardinal arg_count) \ The Drop-down list ComboBox widget creation function" return(gxm_new_widget("XmCreateDropDownList", XmCreateDropDownList, arg1, arg2, arg3, arg4)); } static Xen gxm_XmCreateDropDownComboBox(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateDropDownComboBox "Widget XmCreateDropDownComboBox(Widget parent, String name, ArgList arglist, Cardinal arg_count) \ The Drop-down ComboBox widget creation function" return(gxm_new_widget("XmCreateDropDownComboBox", XmCreateDropDownComboBox, arg1, arg2, arg3, arg4)); } static Xen gxm_XmCreateComboBox(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateComboBox "Widget XmCreateComboBox(Widget parent, String name, ArgList arglist, Cardinal arg_count) \ The default ComboBox widget creation function" return(gxm_new_widget("XmCreateComboBox", XmCreateComboBox, arg1, arg2, arg3, arg4)); } static Xen gxm_XmCreatePushButton(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreatePushButton "Widget XmCreatePushButton(Widget parent, String name, ArgList arglist, Cardinal argcount) \ The PushButton widget creation function" return(gxm_new_widget("XmCreatePushButton", XmCreatePushButton, arg1, arg2, arg3, arg4)); } static Xen gxm_XmCreatePushButtonGadget(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreatePushButtonGadget "Widget XmCreatePushButtonGadget(Widget parent, String name, ArgList arglist, Cardinal argcount) \ The PushButtonGadget creation function" return(gxm_new_widget("XmCreatePushButtonGadget", XmCreatePushButtonGadget, arg1, arg2, arg3, arg4)); } static Xen gxm_XmCascadeButtonHighlight(Xen arg1, Xen arg2) { #define H_XmCascadeButtonHighlight "void XmCascadeButtonHighlight(Widget cascadeButton, Boolean highlight) A CascadeButton and \ CascadeButtonGadget function that sets the highlight state" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmCascadeButtonHighlight", "Widget"); Xen_check_type(Xen_is_boolean(arg2), arg2, 2, "XmCascadeButtonHighlight", "boolean"); XmCascadeButtonHighlight(Xen_to_C_Widget(arg1), Xen_boolean_to_C_bool(arg2)); return(Xen_false); } static Xen gxm_XmCreateCascadeButton(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateCascadeButton "Widget XmCreateCascadeButton(Widget parent, String name, ArgList arglist, Cardinal argcount) \ The CascadeButton widget creation function" return(gxm_new_widget("XmCreateCascadeButton", XmCreateCascadeButton, arg1, arg2, arg3, arg4)); } static void gxm_ProtocolProc(Widget w, XtPointer context, XtPointer info) { Xen descr = (Xen)context; Xen_call_with_3_args(Xen_cadr(descr), C_to_Xen_Widget(w), Xen_caddr(descr), Xen_wrap_C_pointer(info), /* what's this? */ __func__); } #define C_to_Xen_XM_ProtocolHook(Code, Context, PropertyAtom, ProtocolAtom) \ Xen_list_5(C_string_to_Xen_symbol("ProtocolHook"), Code, Context, PropertyAtom, ProtocolAtom) /* #define XM_ProtocolHook_P(Arg) is_wrapped("ProtocolHook", Arg) */ #define C_to_Xen_XM_ProtocolProc(Code, Context, PropertyAtom, ProtocolAtom) \ Xen_list_5(C_string_to_Xen_symbol("ProtocolProc"), Code, Context, PropertyAtom, ProtocolAtom) #define XM_is_ProtocolProc(Arg) is_wrapped("ProtocolProc", Arg) static Xen gxm_XmSetProtocolHooks(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6, Xen arg7) { #define H_XmSetProtocolHooks "void XmSetProtocolHooks(Widget shell, Atom property, Atom protocol, XtCallbackProc prehook, \ XtPointer pre_closure, XtCallbackProc posthook, XtPointer post_closure) A VendorShell function that allows preactions and postactions \ to be executed when a protocol message is received from MWM" Xen descr1, descr2; Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmSetProtocolHooks", "Widget"); Xen_check_type(Xen_is_Atom(arg2), arg2, 2, "XmSetProtocolHooks", "Atom"); Xen_check_type(Xen_is_Atom(arg3), arg3, 3, "XmSetProtocolHooks", "Atom"); Xen_check_type(Xen_is_procedure(arg4) && (Xen_is_aritable(arg4, 3)), arg4, 4, "XmSetProtocolHooks", "(XtCallbackProc widget data callb)"); Xen_check_type(Xen_is_procedure(arg6) && (Xen_is_aritable(arg6, 3)), arg6, 6, "XmSetProtocolHooks", "(XtCallbackProc widget data callb)"); descr1 = C_to_Xen_XM_ProtocolHook(arg4, arg5, arg2, arg3); descr2 = C_to_Xen_XM_ProtocolHook(arg6, arg7, arg2, arg3); xm_protect(descr1); xm_protect(descr2); XmSetProtocolHooks(Xen_to_C_Widget(arg1), Xen_to_C_Atom(arg2), Xen_to_C_Atom(arg3), gxm_ProtocolProc, (XtPointer)descr1, gxm_ProtocolProc, (XtPointer)descr2); return(Xen_false); } static Xen gxm_XmSetWMProtocolHooks(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6) { #define H_XmSetWMProtocolHooks "void XmSetWMProtocolHooks(Widget shell, Atom property, XtCallbackProc prehook, \ XtPointer pre_closure, XtCallbackProc posthook, XtPointer post_closure) A VendorShell function that allows preactions and postactions \ to be executed when a protocol message is received from MWM" Xen descr1, descr2, wm_atom; Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmSetWMProtocolHooks", "Widget"); Xen_check_type(Xen_is_Atom(arg2), arg2, 2, "XmSetWMProtocolHooks", "Atom"); Xen_check_type(Xen_is_procedure(arg3) && (Xen_is_aritable(arg3, 3)), arg3, 3, "XmSetWMProtocolHooks", "(XtCallbackProc widget data callb)"); Xen_check_type(Xen_is_procedure(arg5) && (Xen_is_aritable(arg5, 3)), arg5, 5, "XmSetWMProtocolHooks", "(XtCallbackProc widget data callb)"); wm_atom = C_to_Xen_Atom(XInternAtom(XtDisplay(Xen_to_C_Widget(arg1)), "WM_PROTOCOLS", false)); descr1 = C_to_Xen_XM_ProtocolHook(arg3, arg4, arg2, wm_atom); descr2 = C_to_Xen_XM_ProtocolHook(arg5, arg6, arg2, wm_atom); xm_protect(descr1); xm_protect(descr2); XmSetWMProtocolHooks(Xen_to_C_Widget(arg1), Xen_to_C_Atom(arg2), gxm_ProtocolProc, (XtPointer)descr1, gxm_ProtocolProc, (XtPointer)descr2); return(Xen_false); } static Xen gxm_XmDeactivateProtocol(Xen arg1, Xen arg2, Xen arg3) { #define H_XmDeactivateProtocol "void XmDeactivateProtocol(Widget shell, Atom property, Atom protocol) \ deactivates a protocol without removing it" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmDeactivateProtocol", "Widget"); Xen_check_type(Xen_is_Atom(arg2), arg2, 2, "XmDeactivateProtocol", "Atom"); Xen_check_type(Xen_is_Atom(arg3), arg3, 3, "XmDeactivateProtocol", "Atom"); XmDeactivateProtocol(Xen_to_C_Widget(arg1), Xen_to_C_Atom(arg2), Xen_to_C_Atom(arg3)); return(Xen_false); } static Xen gxm_XmDeactivateWMProtocol(Xen arg1, Xen arg2) { #define H_XmDeactivateWMProtocol "void XmDeactivateWMProtocol(Widget shell, Atom property) \ deactivates a property in WM_PROTOCOLS without removing it" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmDeactivateProtocol", "Widget"); Xen_check_type(Xen_is_Atom(arg2), arg2, 2, "XmDeactivateProtocol", "Atom"); XmDeactivateWMProtocol(Xen_to_C_Widget(arg1), Xen_to_C_Atom(arg2)); return(Xen_false); } static Xen gxm_XmActivateProtocol(Xen arg1, Xen arg2, Xen arg3) { #define H_XmActivateProtocol "oid XmActivateProtocol(Widget shell, Atom property, Atom protocol) activates a protocol" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmActivateProtocol", "Widget"); Xen_check_type(Xen_is_Atom(arg2), arg2, 2, "XmActivateProtocol", "Atom"); Xen_check_type(Xen_is_Atom(arg3), arg3, 3, "XmActivateProtocol", "Atom"); XmActivateProtocol(Xen_to_C_Widget(arg1), Xen_to_C_Atom(arg2), Xen_to_C_Atom(arg3)); return(Xen_false); } static Xen gxm_XmActivateWMProtocol(Xen arg1, Xen arg2) { #define H_XmActivateWMProtocol "oid XmActivateWMProtocol(Widget shell, Atom property) activates a property in the WM_PROTOCOLS" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmActivateProtocol", "Widget"); Xen_check_type(Xen_is_Atom(arg2), arg2, 2, "XmActivateProtocol", "Atom"); XmActivateWMProtocol(Xen_to_C_Widget(arg1), Xen_to_C_Atom(arg2)); return(Xen_false); } static bool unprotect_protocolproc(Xen val, int loc, unsigned long udescr) { Xen descr = (Xen)udescr; /* ('protocolproc func data propatom protoatom) */ return((XM_is_ProtocolProc(val)) && (Xen_ulong_to_C_ulong(Xen_cadr(val)) == Xen_ulong_to_C_ulong(Xen_cadr(descr))) && (Xen_ulong_to_C_ulong(Xen_caddr(val)) == Xen_ulong_to_C_ulong(Xen_caddr(descr))) && (Xen_to_C_Atom(Xen_list_ref(val, 3)) == Xen_to_C_Atom(Xen_list_ref(val,3))) && (Xen_to_C_Atom(Xen_list_ref(val, 4)) == Xen_to_C_Atom(Xen_list_ref(val,4)))); } static Xen gxm_XmRemoveProtocolCallback(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5) { #define H_XmRemoveProtocolCallback "void XmRemoveProtocolCallback(Widget shell, Atom property, Atom protocol, XtCallbackProc callback, \ XtPointer closure) removes a callback from the internal list" Xen descr; int loc, dloc; Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmRemoveProtocolCallback", "Widget"); Xen_check_type(Xen_is_Atom(arg2), arg2, 2, "XmRemoveProtocolCallback", "Atom"); Xen_check_type(Xen_is_Atom(arg3), arg3, 3, "XmRemoveProtocolCallback", "Atom"); Xen_check_type(Xen_is_procedure(arg4) && (Xen_is_aritable(arg4, 3)), arg4, 4, "XmRemoveProtocolCallback", "XtCallbackProc (3 args)"); descr = C_to_Xen_XM_ProtocolProc(arg4, arg5, arg2, arg3); dloc = xm_protect(descr); loc = map_over_protected_elements(unprotect_protocolproc, (unsigned long)descr); XmRemoveProtocolCallback(Xen_to_C_Widget(arg1), Xen_to_C_Atom(arg2), Xen_to_C_Atom(arg3), gxm_ProtocolProc, (XtPointer)(Xen_vector_ref(xm_protected, loc))); /* this was the original tag passed in */ /* now unprotect the proc and our descr */ xm_unprotect_at(dloc); xm_unprotect_at(loc); return(Xen_false); } static Xen gxm_XmRemoveWMProtocolCallback(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmRemoveWMProtocolCallback "void XmRemoveWMProtocolCallback(Widget shell, Atom property, XtCallbackProc callback, \ XtPointer closure) removes a callback from the WM_PROTOCOLS list" Xen descr; int loc, dloc; Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmRemoveWMProtocolCallback", "Widget"); Xen_check_type(Xen_is_Atom(arg2), arg2, 2, "XmRemoveWMProtocolCallback", "Atom"); Xen_check_type(Xen_is_procedure(arg3) && (Xen_is_aritable(arg3, 3)), arg3, 3, "XmRemoveWMProtocolCallback", "XtCallbackProc (3 args)"); descr = C_to_Xen_XM_ProtocolProc(arg3, arg4, arg2, C_to_Xen_Atom(XInternAtom(XtDisplay(Xen_to_C_Widget(arg1)), "WM_PROTOCOLS", false))); dloc = xm_protect(descr); loc = map_over_protected_elements(unprotect_protocolproc, (unsigned long)descr); XmRemoveWMProtocolCallback(Xen_to_C_Widget(arg1), Xen_to_C_Atom(arg2), gxm_ProtocolProc, (XtPointer)(Xen_vector_ref(xm_protected, loc))); /* this was the original tag passed in */ /* now unprotect the proc and our descr */ xm_unprotect_at(dloc); xm_unprotect_at(loc); return(Xen_false); } static Xen gxm_XmAddProtocolCallback(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5) { #define H_XmAddProtocolCallback "void XmAddProtocolCallback(Widget shell, Atom property, Atom protocol, XtCallbackProc callback, \ XtPointer closure) adds client callbacks for a protocol" Xen descr; Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmAddProtocolCallback", "Widget"); Xen_check_type(Xen_is_Atom(arg2), arg2, 2, "XmAddProtocolCallback", "Atom"); Xen_check_type(Xen_is_Atom(arg3), arg3, 3, "XmAddProtocolCallback", "Atom"); Xen_check_type(Xen_is_procedure(arg4) && (Xen_is_aritable(arg4, 3)), arg4, 4, "XmAddProtocolCallback", "(XtCallbackProc widget data callb)"); descr = C_to_Xen_XM_ProtocolProc(arg4, arg5, arg2, arg3); xm_protect(descr); XmAddProtocolCallback(Xen_to_C_Widget(arg1), Xen_to_C_Atom(arg2), Xen_to_C_Atom(arg3), gxm_ProtocolProc, (XtPointer)descr); return(Xen_false); } static Xen gxm_XmAddWMProtocolCallback(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmAddWMProtocolCallback "void XmAddWMProtocolCallback(Widget shell, Atom property, XtCallbackProc callback, \ XtPointer closure) adds client callbacks for the WM_PROTOCOLS" Xen descr; Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmAddWMProtocolCallback", "Widget"); Xen_check_type(Xen_is_Atom(arg2), arg2, 2, "XmAddWMProtocolCallback", "Atom"); Xen_check_type(Xen_is_procedure(arg3) && (Xen_is_aritable(arg3, 3)), arg3, 3, "XmAddWMProtocolCallback", "(XtCallbackProc widget data callb)"); descr = C_to_Xen_XM_ProtocolProc(arg3, arg4, arg2, C_to_Xen_Atom(XInternAtom(XtDisplay(Xen_to_C_Widget(arg1)), "WM_PROTOCOLS", false))); xm_protect(descr); XmAddWMProtocolCallback(Xen_to_C_Widget(arg1), Xen_to_C_Atom(arg2), gxm_ProtocolProc, (XtPointer)descr); return(Xen_false); } static Xen gxm_XmRemoveProtocols(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmRemoveProtocols "void XmRemoveProtocols(Widget shell, Atom property, Atom *protocols, Cardinal num_protocols) \ removes the protocols from the protocol manager and deallocates the internal tables" /* DIFF: XmRemoveProtocols takes list of Atoms */ Atom *outs; int len; Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmRemoveProtocols", "Widget"); Xen_check_type(Xen_is_Atom(arg2), arg2, 2, "XmRemoveProtocols", "Atom"); Xen_check_type(Xen_is_list(arg3), arg3, 3, "XmRemoveProtocols", "list of Atom"); Xen_check_type(Xen_is_integer_or_unbound(arg4), arg4, 4, "XmRemoveProtocols", "int"); if (Xen_is_integer(arg4)) len = Xen_integer_to_C_int(arg4); else len = Xen_list_length(arg3); if (len <= 0) return(Xen_false); outs = Xen_to_C_Atoms(arg3, len); XmRemoveProtocols(Xen_to_C_Widget(arg1), Xen_to_C_Atom(arg2), outs, len); free(outs); return(Xen_false); } static Xen gxm_XmRemoveWMProtocols(Xen arg1, Xen arg2, Xen arg3) { #define H_XmRemoveWMProtocols "void XmRemoveWMProtocols(Widget shell, Atom *protocols, Cardinal num_protocols) \ removes the protocols from WM_PROTOCOLS" Atom *outs; int len; Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmRemoveWMProtocols", "Widget"); Xen_check_type(Xen_is_list(arg2), arg2, 2, "XmRemoveWMProtocols", "list of Atom"); Xen_check_type(Xen_is_integer_or_unbound(arg3), arg3, 3, "XmRemoveWMProtocols", "int"); if (Xen_is_integer(arg3)) len = Xen_integer_to_C_int(arg3); else len = Xen_list_length(arg2); if (len <= 0) return(Xen_false); outs = Xen_to_C_Atoms(arg2, len); XmRemoveWMProtocols(Xen_to_C_Widget(arg1), outs, len); free(outs); return(Xen_false); } static Xen gxm_XmAddProtocols(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmAddProtocols "void XmAddProtocols(Widget shell, Atom property, Atom *protocols, Cardinal num_protocols) \ adds the protocols to the protocol manager and allocates the internal tables" /* DIFF: XmAddProtocols takes list of Atoms */ Atom *outs; int len; Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmAddProtocols", "Widget"); Xen_check_type(Xen_is_Atom(arg2), arg2, 2, "XmAddProtocols", "Atom"); Xen_check_type(Xen_is_list(arg3), arg3, 3, "XmAddProtocols", "list of Atom"); Xen_check_type(Xen_is_integer_or_unbound(arg4), arg4, 4, "XmAddProtocols", "int"); if (Xen_is_integer(arg4)) len = Xen_integer_to_C_int(arg4); else len = Xen_list_length(arg3); if (len <= 0) return(Xen_false); outs = Xen_to_C_Atoms(arg3, len); XmAddProtocols(Xen_to_C_Widget(arg1), Xen_to_C_Atom(arg2), outs, len); free(outs); return(Xen_false); } static Xen gxm_XmAddWMProtocols(Xen arg1, Xen arg2, Xen arg3) { #define H_XmAddWMProtocols "void XmAddWMProtocols(Widget shell, Atom *protocols, Cardinal num_protocols) \ adds the protocols to WM_PROTOCOLS" Atom *outs; int len; Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmAddWMProtocols", "Widget"); Xen_check_type(Xen_is_list(arg2), arg2, 2, "XmAddWMProtocols", "list of Atom"); Xen_check_type(Xen_is_integer_or_unbound(arg3), arg3, 3, "XmAddWMProtocols", "int"); if (Xen_is_integer(arg3)) len = Xen_integer_to_C_int(arg3); else len = Xen_list_length(arg2); if (len <= 0) return(Xen_false); outs = Xen_to_C_Atoms(arg2, len); XmAddWMProtocols(Xen_to_C_Widget(arg1), outs, len); free(outs); return(Xen_false); } static Xen gxm_XmCascadeButtonGadgetHighlight(Xen arg1, Xen arg2) { #define H_XmCascadeButtonGadgetHighlight "void XmCascadeButtonGadgetHighlight(Widget cascadeButtonGadget, Boolean highlight) \ A CascadeButtonGadget function that sets the highlight state" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmCascadeButtonGadgetHighlight", "Widget"); Xen_check_type(Xen_is_boolean(arg2), arg2, 2, "XmCascadeButtonGadgetHighlight", "boolean"); XmCascadeButtonGadgetHighlight(Xen_to_C_Widget(arg1), Xen_boolean_to_C_bool(arg2)); return(Xen_false); } static Xen gxm_XmCreateCascadeButtonGadget(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateCascadeButtonGadget "Widget XmCreateCascadeButtonGadget(Widget parent, String name, ArgList arglist, Cardinal argcount) \ The CascadeButtonGadget creation function" return(gxm_new_widget("XmCreateCascadeButtonGadget", XmCreateCascadeButtonGadget, arg1, arg2, arg3, arg4)); } static Xen gxm_XmCreateBulletinBoardDialog(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateBulletinBoardDialog "Widget XmCreateBulletinBoardDialog(Widget parent, String name, ArgList arglist, Cardinal argcount) \ The BulletinBoard BulletinBoardDialog creation function" return(gxm_new_widget("XmCreateBulletinBoardDialog", XmCreateBulletinBoardDialog, arg1, arg2, arg3, arg4)); } static Xen gxm_XmCreateBulletinBoard(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateBulletinBoard "Widget XmCreateBulletinBoard(Widget parent, String name, ArgList arglist, Cardinal argcount) \ The BulletinBoard widget creation function" return(gxm_new_widget("XmCreateBulletinBoard", XmCreateBulletinBoard, arg1, arg2, arg3, arg4)); } static Xen gxm_XmCreatePanedWindow(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreatePanedWindow "Widget XmCreatePanedWindow(Widget parent, String name, ArgList arglist, Cardinal argcount) \ The PanedWindow widget creation function" return(gxm_new_widget("XmCreatePanedWindow", XmCreatePanedWindow, arg1, arg2, arg3, arg4)); } static Xen gxm_XmGetAtomName(Xen arg1, Xen arg2) { char *str; Xen res; #define H_XmGetAtomName "String XmGetAtomName(Display *display, Atom atom) returns the string representation for an atom" Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XmGetAtomName", "Display*"); Xen_check_type(Xen_is_Atom(arg2), arg2, 2, "XmGetAtomName", "Atom"); str = XmGetAtomName(Xen_to_C_Display(arg1), Xen_to_C_Atom(arg2)); res = C_string_to_Xen_string(str); if (str) XtFree(str); return(res); } static Xen gxm_XmInternAtom(Xen arg1, Xen arg2, Xen arg3) { #define H_XmInternAtom "A macro that returns an atom for a given name" Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XmInternAtom", "Display*"); Xen_check_type(Xen_is_string(arg2), arg2, 2, "XmInternAtom", "String"); Xen_check_type(Xen_is_boolean(arg3), arg3, 3, "XmInternAtom", "Boolean"); return(C_to_Xen_Atom(XmInternAtom(Xen_to_C_Display(arg1), (char *)Xen_string_to_C_string(arg2), Xen_boolean_to_C_bool(arg3)))); } static Xen gxm_XmNotebookGetPageInfo(Xen arg1, Xen arg2) { #define H_XmNotebookGetPageInfo "XmNotebookPageStatus XmNotebookGetPageInfo(Widget notebook, int page_number) \ A Notebook function that returns page information" XmNotebookPageInfo *info; int err; Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmNotebookGetPageInfo", "Widget"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XmNotebookGetPageInfo", "int"); info = (XmNotebookPageInfo *)calloc(1, sizeof(XmNotebookPageInfo)); err = XmNotebookGetPageInfo(Xen_to_C_Widget(arg1), Xen_integer_to_C_int(arg2), info); return(Xen_list_2(C_int_to_Xen_integer(err), C_to_Xen_XmNotebookPageInfo(info))); } static Xen gxm_XmCreateNotebook(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateNotebook "void XmCreateNotebook(Widget parent, String name, ArgList arglist, Cardinal argcount) The Notebook widget creation function" return(gxm_new_widget("XmCreateNotebook", XmCreateNotebook, arg1, arg2, arg3, arg4)); } static Xen gxm_XmCreateArrowButton(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateArrowButton "Widget XmCreateArrowButton(Widget parent, String name, ArgList arglist, Cardinal argcount) \ The ArrowButton widget creation function" return(gxm_new_widget("XmCreateArrowButton", XmCreateArrowButton, arg1, arg2, arg3, arg4)); } static Xen gxm_XmCreateArrowButtonGadget(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateArrowButtonGadget "Widget XmCreateArrowButtonGadget(Widget parent, String name, ArgList arglist, Cardinal argcount) \ The ArrowButtonGadget creation function" return(gxm_new_widget("XmCreateArrowButtonGadget", XmCreateArrowButtonGadget, arg1, arg2, arg3, arg4)); } static Xen gxm_XmMessageBoxGetChild(Xen arg1, Xen arg2) { #define H_XmMessageBoxGetChild "Widget XmMessageBoxGetChild(Widget widget, unsigned char child) A MessageBox function that is used to access a component" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XmMessageBoxGetChild", "Widget"); Xen_check_type(Xen_is_ulong(arg2), arg2, 2, "XmMessageBoxGetChild", "unsigned int"); return(C_to_Xen_Widget(XmMessageBoxGetChild(Xen_to_C_Widget(arg1), Xen_ulong_to_C_ulong(arg2)))); } static Xen gxm_XmCreateTemplateDialog(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateTemplateDialog "Widget XmCreateTemplateDialog(Widget parent, String name, ArgList arglist, Cardinal argcount) \ A MessageBox TemplateDialog creation function" return(gxm_new_widget("XmCreateTemplateDialog", XmCreateTemplateDialog, arg1, arg2, arg3, arg4)); } static Xen gxm_XmCreateWorkingDialog(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateWorkingDialog "Widget XmCreateWorkingDialog(Widget parent, String name, ArgList arglist, Cardinal argcount) \ The MessageBox WorkingDialog creation function" return(gxm_new_widget("XmCreateWorkingDialog", XmCreateWorkingDialog, arg1, arg2, arg3, arg4)); } static Xen gxm_XmCreateWarningDialog(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateWarningDialog "Widget XmCreateWarningDialog(Widget parent, String name, ArgList arglist, Cardinal argcount) \ The MessageBox WarningDialog creation function" return(gxm_new_widget("XmCreateWarningDialog", XmCreateWarningDialog, arg1, arg2, arg3, arg4)); } static Xen gxm_XmCreateQuestionDialog(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateQuestionDialog "Widget XmCreateQuestionDialog(Widget parent, String name, ArgList arglist, Cardinal argcount) \ The MessageBox QuestionDialog creation function" return(gxm_new_widget("XmCreateQuestionDialog", XmCreateQuestionDialog, arg1, arg2, arg3, arg4)); } static Xen gxm_XmCreateInformationDialog(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateInformationDialog "Widget XmCreateInformationDialog(Widget parent, String name, ArgList arglist, Cardinal argcount) \ The MessageBox InformationDialog creation function" return(gxm_new_widget("XmCreateInformationDialog", XmCreateInformationDialog, arg1, arg2, arg3, arg4)); } static Xen gxm_XmCreateErrorDialog(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateErrorDialog "Widget XmCreateErrorDialog(Widget parent, String name, ArgList arglist, Cardinal argcount) \ The MessageBox ErrorDialog creation function" return(gxm_new_widget("XmCreateErrorDialog", XmCreateErrorDialog, arg1, arg2, arg3, arg4)); } static Xen gxm_XmCreateMessageDialog(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateMessageDialog "Widget XmCreateMessageDialog(Widget parent, String name, ArgList arglist, Cardinal argcount) \ The MessageBox MessageDialog creation function" return(gxm_new_widget("XmCreateMessageDialog", XmCreateMessageDialog, arg1, arg2, arg3, arg4)); } static Xen gxm_XmCreateMessageBox(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XmCreateMessageBox "Widget XmCreateMessageBox(Widget parent, String name, ArgList arglist, Cardinal argcount) \ The MessageBox widget creation function" return(gxm_new_widget("XmCreateMessageBox", XmCreateMessageBox, arg1, arg2, arg3, arg4)); } static Xen gxm_XmIsMessageBox(Xen arg) { #define H_XmIsMessageBox "XmIsMessageBox(arg): " PROC_TRUE " if arg is a MessageBox widget" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XmIsMessageBox", "Widget"); return(C_bool_to_Xen_boolean(XmIsMessageBox(Xen_to_C_Widget(arg)))); } static Xen gxm_XmIsArrowButtonGadget(Xen arg) { #define H_XmIsArrowButtonGadget "XmIsArrowButtonGadget(arg): " PROC_TRUE " if arg is an ArrowButton gadget" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XmIsArrowButtonGadget", "Widget"); return(C_bool_to_Xen_boolean(XmIsArrowButtonGadget(Xen_to_C_Widget(arg)))); } static Xen gxm_XmIsArrowButton(Xen arg) { #define H_XmIsArrowButton "XmIsArrowButton(arg): " PROC_TRUE " if arg is an ArrowButton widget" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XmIsArrowButton", "Widget"); return(C_bool_to_Xen_boolean(XmIsArrowButton(Xen_to_C_Widget(arg)))); } static Xen gxm_XmIsNotebook(Xen arg) { #define H_XmIsNotebook "XmIsNotebook(arg): " PROC_TRUE " if arg is a Notebook widget" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XmIsNotebook", "Widget"); return(C_bool_to_Xen_boolean(XmIsNotebook(Xen_to_C_Widget(arg)))); } static Xen gxm_XmIsPanedWindow(Xen arg) { #define H_XmIsPanedWindow "XmIsPanedWindow(arg): " PROC_TRUE " if arg is a PanedWindow widget" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XmIsPanedWindow", "Widget"); return(C_bool_to_Xen_boolean(XmIsPanedWindow(Xen_to_C_Widget(arg)))); } static Xen gxm_XmIsBulletinBoard(Xen arg) { #define H_XmIsBulletinBoard "XmIsBulletinBoard(arg): " PROC_TRUE " if arg is a BulletinBoard widget" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XmIsBulletinBoard", "Widget"); return(C_bool_to_Xen_boolean(XmIsBulletinBoard(Xen_to_C_Widget(arg)))); } static Xen gxm_XmIsPrimitive(Xen arg) { #define H_XmIsPrimitive "XmIsPrimitive(arg): " PROC_TRUE " if arg is a Primitive widget" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XmIsPrimitive", "Widget"); return(C_bool_to_Xen_boolean(XmIsPrimitive(Xen_to_C_Widget(arg)))); } static Xen gxm_XmIsCascadeButtonGadget(Xen arg) { #define H_XmIsCascadeButtonGadget "XmIsCascadeButtonGadget(arg): " PROC_TRUE " if arg is a CascadeButtonGadget gadget" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XmIsCascadeButtonGadget", "Widget"); return(C_bool_to_Xen_boolean(XmIsCascadeButtonGadget(Xen_to_C_Widget(arg)))); } static Xen gxm_XmIsCascadeButton(Xen arg) { #define H_XmIsCascadeButton "XmIsCascadeButton(arg): " PROC_TRUE " if arg is a CascadeButton widget" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XmIsCascadeButton", "Widget"); return(C_bool_to_Xen_boolean(XmIsCascadeButton(Xen_to_C_Widget(arg)))); } static Xen gxm_XmIsPushButtonGadget(Xen arg) { #define H_XmIsPushButtonGadget "XmIsPushButtonGadget(arg): " PROC_TRUE " if arg is a PushButtonGadget gadget" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XmIsPushButtonGadget", "Widget"); return(C_bool_to_Xen_boolean(XmIsPushButtonGadget(Xen_to_C_Widget(arg)))); } static Xen gxm_XmIsPushButton(Xen arg) { #define H_XmIsPushButton "XmIsPushButton(arg): " PROC_TRUE " if arg is a PushButton widget" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XmIsPushButton", "Widget"); return(C_bool_to_Xen_boolean(XmIsPushButton(Xen_to_C_Widget(arg)))); } static Xen gxm_XmIsComboBox(Xen arg) { #define H_XmIsComboBox "XmIsComboBox(arg): " PROC_TRUE " if arg is a ComboBox widget" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XmIsComboBox", "Widget"); return(C_bool_to_Xen_boolean(XmIsComboBox(Xen_to_C_Widget(arg)))); } static Xen gxm_XmIsCommand(Xen arg) { #define H_XmIsCommand "XmIsCommand(arg): " PROC_TRUE " if arg is a Command widget" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XmIsCommand", "Widget"); return(C_bool_to_Xen_boolean(XmIsCommand(Xen_to_C_Widget(arg)))); } static Xen gxm_XmIsRowColumn(Xen arg) { #define H_XmIsRowColumn "XmIsRowColumn(arg): " PROC_TRUE " if arg is a RowColumn widget" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XmIsRowColumn", "Widget"); return(C_bool_to_Xen_boolean(XmIsRowColumn(Xen_to_C_Widget(arg)))); } static Xen gxm_XmIsContainer(Xen arg) { #define H_XmIsContainer "XmIsContainer(arg): " PROC_TRUE " if arg is a Container widget" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XmIsContainer", "Widget"); return(C_bool_to_Xen_boolean(XmIsContainer(Xen_to_C_Widget(arg)))); } static Xen gxm_XmIsScreen(Xen arg) { #define H_XmIsScreen "XmIsScreen(arg): " PROC_TRUE " if arg is a Screen widget" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XmIsScreen", "Widget"); return(C_bool_to_Xen_boolean(XmIsScreen(Xen_to_C_Widget(arg)))); } static Xen gxm_XmIsScale(Xen arg) { #define H_XmIsScale "XmIsScale(arg): " PROC_TRUE " if arg is a Scale widget" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XmIsScale", "Widget"); return(C_bool_to_Xen_boolean(XmIsScale(Xen_to_C_Widget(arg)))); } static Xen gxm_XmIsScrollBar(Xen arg) { #define H_XmIsScrollBar "XmIsScrollBar(arg): " PROC_TRUE " if arg is a ScrollBar widget" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XmIsScrollBar", "Widget"); return(C_bool_to_Xen_boolean(XmIsScrollBar(Xen_to_C_Widget(arg)))); } static Xen gxm_XmIsDialogShell(Xen arg) { #define H_XmIsDialogShell "XmIsDialogShell(arg): " PROC_TRUE " if arg is a DialogShell widget" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XmIsDialogShell", "Widget"); return(C_bool_to_Xen_boolean(XmIsDialogShell(Xen_to_C_Widget(arg)))); } static Xen gxm_XmIsScrolledWindow(Xen arg) { #define H_XmIsScrolledWindow "XmIsScrolledWindow(arg): " PROC_TRUE " if arg is a ScrolledWindow widget" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XmIsScrolledWindow", "Widget"); return(C_bool_to_Xen_boolean(XmIsScrolledWindow(Xen_to_C_Widget(arg)))); } static Xen gxm_XmIsDisplay(Xen arg) { #define H_XmIsDisplay "XmIsDisplay(arg): " PROC_TRUE " if arg is a Display widget" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XmIsDisplay", "Widget"); return(C_bool_to_Xen_boolean(XmIsDisplay(Xen_to_C_Widget(arg)))); } static Xen gxm_XmIsSelectionBox(Xen arg) { #define H_XmIsSelectionBox "XmIsSelectionBox(arg): " PROC_TRUE " if arg is a SelectionBox widget" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XmIsSelectionBox", "Widget"); return(C_bool_to_Xen_boolean(XmIsSelectionBox(Xen_to_C_Widget(arg)))); } static Xen gxm_XmIsDragContext(Xen arg) { #define H_XmIsDragContext "XmIsDragContext(arg): " PROC_TRUE " if arg is a DragContext widget" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XmIsDragContext", "Widget"); return(C_bool_to_Xen_boolean(XmIsDragContext(Xen_to_C_Widget(arg)))); } static Xen gxm_XmIsSeparatorGadget(Xen arg) { #define H_XmIsSeparatorGadget "XmIsSeparatorGadget(arg): " PROC_TRUE " if arg is a SeparatorGadget gadget" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XmIsSeparatorGadget", "Widget"); return(C_bool_to_Xen_boolean(XmIsSeparatorGadget(Xen_to_C_Widget(arg)))); } static Xen gxm_XmIsDragIconObjectClass(Xen arg) { #define H_XmIsDragIconObjectClass "XmIsDragIconObjectClass(arg): " PROC_TRUE " if arg is a DragIconObjectClass widget" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XmIsDragIconObjectClass", "Widget"); return(C_bool_to_Xen_boolean(XmIsDragIconObjectClass(Xen_to_C_Widget(arg)))); } static Xen gxm_XmIsSeparator(Xen arg) { #define H_XmIsSeparator "XmIsSeparator(arg): " PROC_TRUE " if arg is a Separator widget" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XmIsSeparator", "Widget"); return(C_bool_to_Xen_boolean(XmIsSeparator(Xen_to_C_Widget(arg)))); } static Xen gxm_XmIsDrawingArea(Xen arg) { #define H_XmIsDrawingArea "XmIsDrawingArea(arg): " PROC_TRUE " if arg is a DrawingArea widget" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XmIsDrawingArea", "Widget"); return(C_bool_to_Xen_boolean(XmIsDrawingArea(Xen_to_C_Widget(arg)))); } static Xen gxm_XmIsDrawnButton(Xen arg) { #define H_XmIsDrawnButton "XmIsDrawnButton(arg): " PROC_TRUE " if arg is a DrawnButton widget" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XmIsDrawnButton", "Widget"); return(C_bool_to_Xen_boolean(XmIsDrawnButton(Xen_to_C_Widget(arg)))); } static Xen gxm_XmIsDropSiteManager(Xen arg) { #define H_XmIsDropSiteManager "XmIsDropSiteManager(arg): " PROC_TRUE " if arg is a DropSiteManager widget" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XmIsDropSiteManager", "Widget"); return(C_bool_to_Xen_boolean(XmIsDropSiteManager(Xen_to_C_Widget(arg)))); } static Xen gxm_XmIsDropTransfer(Xen arg) { #define H_XmIsDropTransfer "XmIsDropTransfer(arg): " PROC_TRUE " if arg is a DropTransfer widget" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XmIsDropTransfer", "Widget"); return(C_bool_to_Xen_boolean(XmIsDropTransfer(Xen_to_C_Widget(arg)))); } static Xen gxm_XmIsTextField(Xen arg) { #define H_XmIsTextField "XmIsTextField(arg): " PROC_TRUE " if arg is a TextField widget" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XmIsTextField", "Widget"); return(C_bool_to_Xen_boolean(XmIsTextField(Xen_to_C_Widget(arg)))); } static Xen gxm_XmIsFileSelectionBox(Xen arg) { #define H_XmIsFileSelectionBox "XmIsFileSelectionBox(arg): " PROC_TRUE " if arg is a FileSelectionBox widget" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XmIsFileSelectionBox", "Widget"); return(C_bool_to_Xen_boolean(XmIsFileSelectionBox(Xen_to_C_Widget(arg)))); } static Xen gxm_XmIsText(Xen arg) { #define H_XmIsText "XmIsText(arg): " PROC_TRUE " if arg is a Text widget" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XmIsText", "Widget"); return(C_bool_to_Xen_boolean(XmIsText(Xen_to_C_Widget(arg)))); } static Xen gxm_XmIsForm(Xen arg) { #define H_XmIsForm "XmIsForm(arg): " PROC_TRUE " if arg is a Form widget" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XmIsForm", "Widget"); return(C_bool_to_Xen_boolean(XmIsForm(Xen_to_C_Widget(arg)))); } static Xen gxm_XmIsFrame(Xen arg) { #define H_XmIsFrame "XmIsFrame(arg): " PROC_TRUE " if arg is a Frame widget" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XmIsFrame", "Widget"); return(C_bool_to_Xen_boolean(XmIsFrame(Xen_to_C_Widget(arg)))); } static Xen gxm_XmIsGadget(Xen arg) { #define H_XmIsGadget "XmIsGadget(arg): " PROC_TRUE " if arg is a Gadget" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XmIsGadget", "Widget"); return(C_bool_to_Xen_boolean(XmIsGadget(Xen_to_C_Widget(arg)))); } static Xen gxm_XmIsToggleButtonGadget(Xen arg) { #define H_XmIsToggleButtonGadget "XmIsToggleButtonGadget(arg): " PROC_TRUE " if arg is a ToggleButtonGadget gadget" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XmIsToggleButtonGadget", "Widget"); return(C_bool_to_Xen_boolean(XmIsToggleButtonGadget(Xen_to_C_Widget(arg)))); } static Xen gxm_XmIsGrabShell(Xen arg) { #define H_XmIsGrabShell "XmIsGrabShell(arg): " PROC_TRUE " if arg is a GrabShell widget" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XmIsGrabShell", "Widget"); return(C_bool_to_Xen_boolean(XmIsGrabShell(Xen_to_C_Widget(arg)))); } static Xen gxm_XmIsToggleButton(Xen arg) { #define H_XmIsToggleButton "XmIsToggleButton(arg): " PROC_TRUE " if arg is a ToggleButton widget" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XmIsToggleButton", "Widget"); return(C_bool_to_Xen_boolean(XmIsToggleButton(Xen_to_C_Widget(arg)))); } static Xen gxm_XmIsIconGadget(Xen arg) { #define H_XmIsIconGadget "XmIsIconGadget(arg): " PROC_TRUE " if arg is a IconGadget widget" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XmIsIconGadget", "Widget"); return(C_bool_to_Xen_boolean(XmIsIconGadget(Xen_to_C_Widget(arg)))); } static Xen gxm_XmIsIconHeader(Xen arg) { #define H_XmIsIconHeader "XmIsIconHeader(arg): " PROC_TRUE " if arg is a IconHeader widget" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XmIsIconHeader", "Widget"); return(C_bool_to_Xen_boolean(XmIsIconHeader(Xen_to_C_Widget(arg)))); } static Xen gxm_XmIsLabelGadget(Xen arg) { #define H_XmIsLabelGadget "XmIsLabelGadget(arg): " PROC_TRUE " if arg is a LabelGadget widget" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XmIsLabelGadget", "Widget"); return(C_bool_to_Xen_boolean(XmIsLabelGadget(Xen_to_C_Widget(arg)))); } static Xen gxm_XmIsLabel(Xen arg) { #define H_XmIsLabel "XmIsLabel(arg): " PROC_TRUE " if arg is a Label widget" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XmIsLabel", "Widget"); return(C_bool_to_Xen_boolean(XmIsLabel(Xen_to_C_Widget(arg)))); } static Xen gxm_XmIsVendorShell(Xen arg) { #define H_XmIsVendorShell "XmIsVendorShell(arg): " PROC_TRUE " if arg is a VendorShell widget" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XmIsVendorShell", "Widget"); return(C_bool_to_Xen_boolean(XmIsVendorShell(Xen_to_C_Widget(arg)))); } static Xen gxm_XmIsList(Xen arg) { #define H_XmIsList "XmIsList(arg): " PROC_TRUE " if arg is a List widget" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XmIsList", "Widget"); return(C_bool_to_Xen_boolean(XmIsList(Xen_to_C_Widget(arg)))); } static Xen gxm_XmIsMainWindow(Xen arg) { #define H_XmIsMainWindow "XmIsMainWindow(arg): " PROC_TRUE " if arg is a MainWindow widget" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XmIsMainWindow", "Widget"); return(C_bool_to_Xen_boolean(XmIsMainWindow(Xen_to_C_Widget(arg)))); } static Xen gxm_XmIsManager(Xen arg) { #define H_XmIsManager "XmIsManager(arg): " PROC_TRUE " if arg is a Manager widget" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XmIsManager", "Widget"); return(C_bool_to_Xen_boolean(XmIsManager(Xen_to_C_Widget(arg)))); } static Xen gxm_XmIsMenuShell(Xen arg) { #define H_XmIsMenuShell "XmIsMenuShell(arg): " PROC_TRUE " if arg is a MenuShell widget" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XmIsMenuShell", "Widget"); return(C_bool_to_Xen_boolean(XmIsMenuShell(Xen_to_C_Widget(arg)))); } /* ---------------------------------------------------------------------------------------------------- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ---------------------------------------------------------------------------------------------------- */ static Xen gxm_XXorRegion(Xen arg1, Xen arg2, Xen arg3) { #define H_XXorRegion "XXorRegion(sra, srb, dr_return) calculates the difference between the union and intersection of two regions." Xen_check_type(Xen_is_Region(arg1), arg1, 1, "XXorRegion", "Region"); Xen_check_type(Xen_is_Region(arg2), arg2, 2, "XXorRegion", "Region"); Xen_check_type(Xen_is_Region(arg3), arg3, 3, "XXorRegion", "Region"); return(C_int_to_Xen_integer(XXorRegion(Xen_to_C_Region(arg1), Xen_to_C_Region(arg2), Xen_to_C_Region(arg3)))); } static Xen gxm_XUnionRegion(Xen arg1, Xen arg2, Xen arg3) { #define H_XUnionRegion "XUnionRegion(sra, srb, dr_return) computes the union of two regions." Xen_check_type(Xen_is_Region(arg1), arg1, 1, "XUnionRegion", "Region"); Xen_check_type(Xen_is_Region(arg2), arg2, 2, "XUnionRegion", "Region"); Xen_check_type(Xen_is_Region(arg3), arg3, 3, "XUnionRegion", "Region"); return(C_int_to_Xen_integer(XUnionRegion(Xen_to_C_Region(arg1), Xen_to_C_Region(arg2), Xen_to_C_Region(arg3)))); } static Xen gxm_XUnionRectWithRegion(Xen arg1, Xen arg2, Xen arg3) { #define H_XUnionRectWithRegion "XUnionRectWithRegion(rectangle, src_region, dest_region_return) updates the destination region from a \ union of the specified rectangle and the specified source region." Xen_check_type(Xen_is_XRectangle(arg1), arg1, 1, "XUnionRectWithRegion", "XRectangle*"); Xen_check_type(Xen_is_Region(arg2), arg2, 2, "XUnionRectWithRegion", "Region"); Xen_check_type(Xen_is_Region(arg3), arg3, 3, "XUnionRectWithRegion", "Region"); return(C_int_to_Xen_integer(XUnionRectWithRegion(Xen_to_C_XRectangle(arg1), Xen_to_C_Region(arg2), Xen_to_C_Region(arg3)))); } static Xen gxm_XSubtractRegion(Xen arg1, Xen arg2, Xen arg3) { #define H_XSubtractRegion "XSubtractRegion(sra, srb, dr_return) subtracts srb from sra and stores the results in dr_return." Xen_check_type(Xen_is_Region(arg1), arg1, 1, "XSubtractRegion", "Region"); Xen_check_type(Xen_is_Region(arg2), arg2, 2, "XSubtractRegion", "Region"); Xen_check_type(Xen_is_Region(arg3), arg3, 3, "XSubtractRegion", "Region"); return(C_int_to_Xen_integer(XSubtractRegion(Xen_to_C_Region(arg1), Xen_to_C_Region(arg2), Xen_to_C_Region(arg3)))); } static Xen gxm_XShrinkRegion(Xen arg1, Xen arg2, Xen arg3) { #define H_XShrinkRegion "XShrinkRegion(r, dx, dy) reduces the specified region by a specified amount." Xen_check_type(Xen_is_Region(arg1), arg1, 1, "XShrinkRegion", "Region"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XShrinkRegion", "int"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XShrinkRegion", "int"); return(C_int_to_Xen_integer(XShrinkRegion(Xen_to_C_Region(arg1), Xen_integer_to_C_int(arg2), Xen_integer_to_C_int(arg3)))); } static Xen gxm_XSetWMProperties(Xen dpy, Xen win, Xen win_name, Xen icon_name, Xen argv, Xen argc, Xen normal_hints, Xen wm_hints) { /* last arg omitted -- XClassHint not supported */ #define H_XSetWMProperties "XSetWMProperties(dpy, win, win_name, icon_name, argv, argc, normal_hints wm_hints) sets the window properties" int c_argc = 0; char **c_argv = NULL; XTextProperty w_name, i_name; bool use_w_name = false, use_i_name = false; Xen_check_type(Xen_is_Display(dpy), dpy, 1, "XSetWMProperties", "Display*"); Xen_check_type(Xen_is_Window(win), win, 2, "XSetWMProperties", "Window"); Xen_check_type(Xen_is_string(win_name) || Xen_is_null(win_name) || Xen_is_false(win_name), win_name, 3, "XSetWMProperties", "char*"); Xen_check_type(Xen_is_string(icon_name) || Xen_is_null(icon_name) || Xen_is_false(icon_name), icon_name, 4, "XSetWMProperties", "char*"); Xen_check_type(Xen_is_list(argv), argv, 5, "XSetWMProperties", "list of char*"); Xen_check_type(Xen_is_integer(argc), argc, 6, "XSetWMProperties", "int"); Xen_check_type(Xen_is_false(normal_hints) || Xen_is_XSizeHints(normal_hints), normal_hints, 7, "XSetWMProperties", "XSizeHints* or false"); Xen_check_type(Xen_is_false(wm_hints) || Xen_is_XWMHints(wm_hints), wm_hints, 8, "XSetWMProperties", "XWMHints* or false"); c_argc = Xen_integer_to_C_int(argc); if (c_argc > 0) c_argv = Xen_to_C_Strings(argv, c_argc); if (Xen_is_string(win_name)) { char *name; use_w_name = true; name = (char *)Xen_string_to_C_string(win_name); XStringListToTextProperty(&name, 1, &w_name); } if (Xen_is_string(icon_name)) { char *name; use_i_name = true; name = (char *)Xen_string_to_C_string(icon_name); XStringListToTextProperty(&name, 1, &i_name); } XSetWMProperties(Xen_to_C_Display(dpy), Xen_to_C_Window(win), (use_w_name) ? &w_name : NULL, (use_i_name) ? &i_name : NULL, c_argv, c_argc, Xen_to_C_XSizeHints(normal_hints), Xen_to_C_XWMHints(wm_hints), NULL); if (c_argv) free(c_argv); return(Xen_false); } static Xen gxm_XSetRegion(Xen arg1, Xen arg2, Xen arg3) { #define H_XSetRegion "XSetRegion(display, gc, r) sets the clip-mask in the GC to the specified region." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XSetRegion", "Display*"); Xen_check_type(Xen_is_GC(arg2), arg2, 2, "XSetRegion", "GC"); Xen_check_type(Xen_is_Region(arg3), arg3, 3, "XSetRegion", "Region"); return(C_int_to_Xen_integer(XSetRegion(Xen_to_C_Display(arg1), Xen_to_C_GC(arg2), Xen_to_C_Region(arg3)))); } static Xen gxm_XSetWMHints(Xen arg1, Xen arg2, Xen arg3) { #define H_XSetWMHints "XSetWMHints(display, w, wmhints) sets the window manager hints that include icon information and location, the \ initial state of the window, and whether the application relies on the window manager to get keyboard input." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XSetWMHints", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XSetWMHints", "Window"); Xen_check_type(Xen_is_XWMHints(arg3), arg3, 3, "XSetWMHints", "XWMHints*"); return(C_int_to_Xen_integer(XSetWMHints(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_to_C_XWMHints(arg3)))); } static Xen gxm_XSetRGBColormaps(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5) { #define H_XSetRGBColormaps "void XSetRGBColormaps(display, w, std_colormap, count, property) replaces the RGB colormap definition in the \ specified property on the named window." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XSetRGBColormaps", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XSetRGBColormaps", "Window"); Xen_check_type(Xen_is_XStandardColormap(arg3), arg3, 3, "XSetRGBColormaps", "XStandardColormap*"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XSetRGBColormaps", "int"); Xen_check_type(Xen_is_Atom(arg5), arg5, 5, "XSetRGBColormaps", "Atom"); XSetRGBColormaps(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_to_C_XStandardColormap(arg3), Xen_integer_to_C_int(arg4), Xen_to_C_Atom(arg5)); return(Xen_false); } static Xen gxm_XUniqueContext(void) { #define H_XUniqueContext "XContext XUniqueContext() creates a unique context type that may be used in subsequent calls to XSaveContext." return(C_to_Xen_XContext(XUniqueContext())); } static Xen gxm_XSaveContext(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XSaveContext "XSaveContext(dpy, rid, context) saves a context" Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XSaveContext", "Display*"); Xen_check_type(Xen_is_ulong(arg2), arg2, 2, "XSaveContext", "XID"); Xen_check_type(Xen_is_XContext(arg3), arg3, 3, "XSaveContext", "XContext"); return(C_int_to_Xen_integer(XSaveContext(Xen_to_C_Display(arg1), Xen_ulong_to_C_ulong(arg2), Xen_to_C_XContext(arg3), (caddr_t)arg4))); } static Xen gxm_XRectInRegion(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5) { #define H_XRectInRegion "int XRectInRegion(r, x, y, width, height): returns RectangleIn if the rectangle is entirely in the specified region, \ RectangleOut if the rectangle is entirely out of the specified region, and RectanglePart if the rectangle is partially in the specified region. " Xen_check_type(Xen_is_Region(arg1), arg1, 1, "XRectInRegion", "Region"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XRectInRegion", "int"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XRectInRegion", "int"); Xen_check_type(Xen_is_ulong(arg4), arg4, 4, "XRectInRegion", "unsigned int"); Xen_check_type(Xen_is_ulong(arg5), arg5, 5, "XRectInRegion", "unsigned int"); return(C_int_to_Xen_integer(XRectInRegion(Xen_to_C_Region(arg1), Xen_integer_to_C_int(arg2), Xen_integer_to_C_int(arg3), Xen_ulong_to_C_ulong(arg4), Xen_ulong_to_C_ulong(arg5)))); } static Xen gxm_XPolygonRegion(Xen larg1, Xen arg2, Xen arg3) { #define H_XPolygonRegion "Region XPolygonRegion(points, n, fill_rule): returns a region for the polygon defined by the points list." /* DIFF: XPolygonRegion XPoint* arg (arg 1) is list of XPoints */ XPoint *pt, *pt1; int i, len; Region res; Xen arg1; Xen_check_type(Xen_is_list(larg1), larg1, 1, "XPolygonRegion", "list of XPoints"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XPolygonRegion", "int"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XPolygonRegion", "int"); arg1 = Xen_copy_arg(larg1); len = Xen_integer_to_C_int(arg2); if (len <= 0) Xen_check_type(0, arg2, 2, "XPolygonRegion", "positive integer"); pt = (XPoint *)calloc(len, sizeof(XPoint)); for (i = 0; (i < len) && (!Xen_is_null(arg1)); i++, arg1 = Xen_cdr(arg1)) { Xen xp; xp = Xen_car(arg1); if (!(Xen_is_XPoint(xp))) {free(pt); Xen_check_type(0, xp, i, "XPolygonRegion", "XPoint"); return(Xen_false);} pt1 = Xen_to_C_XPoint(Xen_car(arg1)); pt[i].x = pt1->x; pt[i].y = pt1->y; } res = XPolygonRegion(pt, len, Xen_integer_to_C_int(arg3)); free(pt); return(C_to_Xen_Region(res)); } static Xen gxm_XPointInRegion(Xen arg1, Xen arg2, Xen arg3) { #define H_XPointInRegion "Bool XPointInRegion(r, x, y): returns " PROC_TRUE " if the point (x, y) is contained in the region r." Xen_check_type(Xen_is_Region(arg1), arg1, 1, "XPointInRegion", "Region"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XPointInRegion", "int"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XPointInRegion", "int"); return(C_bool_to_Xen_boolean(XPointInRegion(Xen_to_C_Region(arg1), Xen_integer_to_C_int(arg2), Xen_integer_to_C_int(arg3)))); } static Xen gxm_XOffsetRegion(Xen arg1, Xen arg2, Xen arg3) { #define H_XOffsetRegion "XOffsetRegion(r, dx, dy) moves the specified region by a specified amount." Xen_check_type(Xen_is_Region(arg1), arg1, 1, "XOffsetRegion", "Region"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XOffsetRegion", "int"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XOffsetRegion", "int"); return(C_int_to_Xen_integer(XOffsetRegion(Xen_to_C_Region(arg1), Xen_integer_to_C_int(arg2), Xen_integer_to_C_int(arg3)))); } static XVisualInfo *match_visual_info; static Xen gxm_XMatchVisualInfo(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XMatchVisualInfo "Status XMatchVisualInfo(display, screen, depth, class): returns the visual information for a \ visual that matches the specified depth and class for a screen." /* DIFF: XMatchVisualInfo dpy scr dep class [visual] -> #f or visual */ int val; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XMatchVisualInfo", "Display*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XMatchVisualInfo", "int"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XMatchVisualInfo", "int"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XMatchVisualInfo", "int"); match_visual_info = (XVisualInfo *)calloc(1, sizeof(XVisualInfo)); val = XMatchVisualInfo(Xen_to_C_Display(arg1), Xen_integer_to_C_int(arg2), Xen_integer_to_C_int(arg3), Xen_integer_to_C_int(arg4), match_visual_info); if (val) return(C_to_Xen_XVisualInfo(match_visual_info)); return(Xen_false); } static Xen gxm_XLookupString(Xen arg1) { #define H_XLookupString "int XLookupString(event_struct) translates a key event to a KeySym and a string -> (len str keysym)." /* DIFF: XLookupString last arg is ignored, keyevent and all but last omitted -> (list len str keysym) */ KeySym key; char *str; int len; Xen res; Xen_check_type(Xen_is_XKeyEvent(arg1), arg1, 1, "XLookupString", "XKeyEvent*");/* user-created */ str = (char *)calloc(16, sizeof(char)); len = XLookupString(Xen_to_C_XKeyEvent(arg1), str, 16, &key, NULL); res = Xen_list_3(C_int_to_Xen_integer(len), C_string_to_Xen_string(str), C_to_Xen_KeySym(key)); free(str); return(res); } static Xen gxm_XConvertCase(Xen arg1) { #define H_XConvertCase "void XConvertCase(keysym): returns the uppercase and lowercase forms of the specified \ Keysym, if the KeySym is subject to case conversion; otherwise, the specified KeySym is returned to both lower_return and upper_return." /* DIFF: XConvertCase keysym [k1 k2] -> (list k1 k2) */ KeySym k1, k2; Xen_check_type(Xen_is_KeySym(arg1), arg1, 1, "XConvertCase", "KeySym"); XConvertCase(Xen_to_C_KeySym(arg1), &k1, &k2); return(Xen_list_2(C_to_Xen_KeySym(k1), C_to_Xen_KeySym(k2))); } static Xen gxm_XIntersectRegion(Xen arg1, Xen arg2, Xen arg3) { #define H_XIntersectRegion "XIntersectRegion(sra, srb, dr_return) computes the intersection of two regions." Xen_check_type(Xen_is_Region(arg1), arg1, 1, "XIntersectRegion", "Region"); Xen_check_type(Xen_is_Region(arg2), arg2, 2, "XIntersectRegion", "Region"); Xen_check_type(Xen_is_Region(arg3), arg3, 3, "XIntersectRegion", "Region"); return(C_int_to_Xen_integer(XIntersectRegion(Xen_to_C_Region(arg1), Xen_to_C_Region(arg2), Xen_to_C_Region(arg3)))); } static Xen gxm_XGetWMHints(Xen arg1, Xen arg2) { #define H_XGetWMHints "XWMHints *XGetWMHints(display, w) reads the window manager hints and returns NULL if no WM_HINTS property was \ set on the window or returns a pointer to a XWMHints structure if it succeeds." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XGetWMHints", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XGetWMHints", "Window"); return(C_to_Xen_XWMHints(XGetWMHints(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2)))); } static Xen gxm_XGetVisualInfo(Xen arg1, Xen arg2, Xen arg3) { #define H_XGetVisualInfo "XVisualInfo *XGetVisualInfo(display, vinfo_mask, vinfo_template): returns a list of visual \ structures that have attributes equal to the attributes specified by vinfo_template." /* DIFF: XGetVisualInfo dpy mask template [nitems] -> () or (list visual...) */ XVisualInfo *v; int len; Xen lst = Xen_empty_list; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XGetVisualInfo", "Display*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XGetVisualInfo", "long"); Xen_check_type(Xen_is_XVisualInfo(arg3), arg3, 3, "XGetVisualInfo", "XVisualInfo*"); v = XGetVisualInfo(Xen_to_C_Display(arg1), Xen_integer_to_C_int(arg2), Xen_to_C_XVisualInfo(arg3), &len); if (v) { int i, loc; loc = xm_protect(lst); for (i = len - 1; i >= 0; i--) lst = Xen_cons(C_to_Xen_XVisualInfo(v + i), lst); xm_unprotect_at(loc); /* XFree(v); */ /* valgrind says this is a bad idea */ } return(lst); } static Xen gxm_XGetRGBColormaps(Xen arg1, Xen arg2, Xen arg3) { #define H_XGetRGBColormaps "Status XGetRGBColormaps(display, w, property): returns the RGB colormap \ definitions stored in the specified property on the named window." /* DIFF: XGetRGBColormaps omits arg 3 and 4, returns list of XStandardColormaps */ int len, i, loc; Status val; Xen lst = Xen_empty_list; XStandardColormap **cs = NULL; /* do I allocate this?? */ Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XGetRGBColormaps", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XGetRGBColormaps", "Window"); Xen_check_type(Xen_is_Atom(arg3), arg3, 3, "XGetRGBColormaps", "Atom"); val = XGetRGBColormaps(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), cs, &len, Xen_to_C_Atom(arg3)); if (val == 0) return(Xen_false); loc = xm_protect(lst); for (i = len - 1; i >= 0; i--) lst = Xen_cons(C_to_Xen_XStandardColormap(cs[i]), lst); xm_unprotect_at(loc); return(lst); } static Xen gxm_XGetIconSizes(Xen arg1, Xen arg2) { #define H_XGetIconSizes "Status XGetIconSizes(display, w): returns " PROC_FALSE " if the window manager has not \ set icon sizes; otherwise, it return nonzero and a list of XIconSize structs." /* DIFF: XGetIconSizes omit last 2 args, return list of XIconSizes */ XIconSize *sizes; int i, len, val, loc; Xen lst = Xen_empty_list; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XGetIconSizes", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XGetIconSizes", "Window"); val = XGetIconSizes(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), &sizes, &len); if (val == 0) return(Xen_false); loc = xm_protect(lst); for (i = len - 1; i >= 0; i--) lst = Xen_cons(C_to_Xen_XIconSize(&(sizes[i])), lst); XFree(sizes); xm_unprotect_at(loc); return(Xen_list_2(C_int_to_Xen_integer(val), lst)); } static Xen gxm_XFindContext(Xen arg1, Xen arg2, Xen arg3) { #define H_XFindContext "XFindContext(dpy, rid, context) gets data from the context manager" /* DIFF: XFindContext last arg omitted, val returned */ caddr_t x; int val; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XFindContext", "Display*"); Xen_check_type(Xen_is_ulong(arg2), arg2, 2, "XFindContext", "XID"); Xen_check_type(Xen_is_XContext(arg3), arg3, 3, "XFindContext", "XContext"); val = XFindContext(Xen_to_C_Display(arg1), Xen_ulong_to_C_ulong(arg2), Xen_to_C_XContext(arg3), &x); return(Xen_list_2(C_int_to_Xen_integer(val), (Xen)x)); } static Xen gxm_XEqualRegion(Xen arg1, Xen arg2) { #define H_XEqualRegion "Bool XEqualRegion(r1, r2): returns " PROC_TRUE " if the two regions have the same offset, size, and shape." Xen_check_type(Xen_is_Region(arg1), arg1, 1, "XEqualRegion", "Region"); Xen_check_type(Xen_is_Region(arg2), arg2, 2, "XEqualRegion", "Region"); return(C_bool_to_Xen_boolean(XEqualRegion(Xen_to_C_Region(arg1), Xen_to_C_Region(arg2)))); } static Xen gxm_XEmptyRegion(Xen arg1) { #define H_XEmptyRegion "Bool XEmptyRegion(r): returns " PROC_TRUE " if the region is empty." Xen_check_type(Xen_is_Region(arg1), arg1, 1, "XEmptyRegion", "Region"); return(C_bool_to_Xen_boolean(XEmptyRegion(Xen_to_C_Region(arg1)))); } static Xen gxm_XDestroyRegion(Xen arg1) { #define H_XDestroyRegion "XDestroyRegion(r) deallocates the storage associated with a specified region." Xen_check_type(Xen_is_Region(arg1), arg1, 1, "XDestroyRegion", "Region"); return(C_int_to_Xen_integer(XDestroyRegion(Xen_to_C_Region(arg1)))); } static Xen gxm_XDeleteContext(Xen arg1, Xen arg2, Xen arg3) { #define H_XDeleteContext "int XDeleteContext(display, rid, context) deletes the entry for the given resource ID and type from the data structure." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XDeleteContext", "Display*"); Xen_check_type(Xen_is_ulong(arg2), arg2, 2, "XDeleteContext", "XID"); Xen_check_type(Xen_is_XContext(arg3), arg3, 3, "XDeleteContext", "XContext"); return(C_int_to_Xen_integer(XDeleteContext(Xen_to_C_Display(arg1), Xen_ulong_to_C_ulong(arg2), Xen_to_C_XContext(arg3)))); } static Xen gxm_XDefaultString(void) { #define H_XDefaultString "char *XDefaultString(): returns the default string used by Xlib for text conversion" return(C_string_to_Xen_string(XDefaultString())); } static Xen gxm_XCreateRegion(void) { #define H_XCreateRegion "Region XCreateRegion()" return(C_to_Xen_Region(XCreateRegion())); } static Xen gxm_XClipBox(Xen arg1) { #define H_XClipBox "XClipBox(r): returns the smallest rectangle enclosing the specified region." /* DIFF: XClipBox region [rectangle] -> (list val rectangle) */ XRectangle *r; int val; Xen_check_type(Xen_is_Region(arg1), arg1, 1, "XClipBox", "Region"); r = (XRectangle *)calloc(1, sizeof(XRectangle)); val = XClipBox(Xen_to_C_Region(arg1), r); return(Xen_list_2(C_int_to_Xen_integer(val), C_to_Xen_XRectangle(r))); } static Xen gxm_XAllocWMHints(void) { #define H_XAllocWMHints "XAllocWMHints() allocates a window manager hints structure" return(C_to_Xen_XWMHints(XAllocWMHints())); } static Xen gxm_XAllocStandardColormap(void) { #define H_XAllocStandardColormap "XStandardColormap *XAllocStandardColormap() allocates and returns a pointer to a XStandardColormap structure." return(C_to_Xen_XStandardColormap(XAllocStandardColormap())); } static Xen gxm_XAllocIconSize(void) { #define H_XAllocIconSize "XIconSize *XAllocIconSize() allocates and returns a pointer to a XIconSize structure." return(C_to_Xen_XIconSize(XAllocIconSize())); } static Xen gxm_XFilterEvent(Xen arg1, Xen arg2) { #define H_XFilterEvent "Bool XFilterEvent(event, w) passes the event to any filters registered for it in the given window" Xen_check_type(Xen_is_XEvent(arg1), arg1, 1, "XFilterEvent", "XEvent*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XFilterEvent", "Window"); return(C_bool_to_Xen_boolean(XFilterEvent(Xen_to_C_XEvent(arg1), Xen_to_C_Window(arg2)))); } static Xen gxm_XContextualDrawing(Xen arg1) { #define H_XContextualDrawing "Bool XContextualDrawing(font_set): returns " PROC_TRUE " if text drawn with the font set might include context-dependent drawing." Xen_check_type(Xen_is_XFontSet(arg1), arg1, 1, "XContextualDrawing", "XFontSet"); return(C_bool_to_Xen_boolean(XContextualDrawing(Xen_to_C_XFontSet(arg1)))); } static Xen gxm_XDirectionalDependentDrawing(Xen arg1) { #define H_XDirectionalDependentDrawing "Bool XDirectionalDependentDrawing(font_set): returns " PROC_TRUE " if the drawing functions implement \ implicit text directionality." Xen_check_type(Xen_is_XFontSet(arg1), arg1, 1, "XDirectionalDependentDrawing", "XFontSet"); return(C_bool_to_Xen_boolean(XDirectionalDependentDrawing(Xen_to_C_XFontSet(arg1)))); } static Xen gxm_XContextDependentDrawing(Xen arg1) { #define H_XContextDependentDrawing "Bool XContextDependentDrawing(font_set): returns " PROC_TRUE " if the drawing functions implement implicit \ text directionality or if text drawn with the font_set might include context-dependent drawing." Xen_check_type(Xen_is_XFontSet(arg1), arg1, 1, "XContextDependentDrawing", "XFontSet"); return(C_bool_to_Xen_boolean(XContextDependentDrawing(Xen_to_C_XFontSet(arg1)))); } static Xen gxm_XLocaleOfFontSet(Xen arg1) { #define H_XLocaleOfFontSet "char *XLocaleOfFontSet(font_set): returns the name of the locale bound to the specified XFontSet, as a \ null-terminated string." Xen_check_type(Xen_is_XFontSet(arg1), arg1, 1, "XLocaleOfFontSet", "XFontSet"); return(C_string_to_Xen_string(XLocaleOfFontSet(Xen_to_C_XFontSet(arg1)))); } static Xen gxm_XBaseFontNameListOfFontSet(Xen arg1) { #define H_XBaseFontNameListOfFontSet "char *XBaseFontNameListOfFontSet(font_set): returns the original base font name list supplied \ by the client when the XFontSet was created." Xen_check_type(Xen_is_XFontSet(arg1), arg1, 1, "XBaseFontNameListOfFontSet", "XFontSet"); return(C_string_to_Xen_string(XBaseFontNameListOfFontSet(Xen_to_C_XFontSet(arg1)))); } static Xen gxm_XFontsOfFontSet(Xen arg1) { #define H_XFontsOfFontSet "int XFontsOfFontSet(font_set): returns a list of one or more \ XFontStructs and font names for the fonts used by the Xmb and Xwc layers, for the given font set." /* DIFF: XFontsOfFontSet omit last 2 args, return 2 lists */ int i, len, loc1, loc2; char **names; Xen lst1 = Xen_empty_list, lst2 = Xen_empty_list; XFontStruct **fs; Xen_check_type(Xen_is_XFontSet(arg1), arg1, 1, "XFontsOfFontSet", "XFontSet"); len = XFontsOfFontSet(Xen_to_C_XFontSet(arg1), &fs, &names); loc1 = xm_protect(lst1); loc2 = xm_protect(lst2); for (i = len - 1; i >= 0; i--) { lst1 = Xen_cons(C_to_Xen_XFontStruct(fs[i]), lst1); lst2 = Xen_cons(C_string_to_Xen_string(names[i]), lst2); } xm_unprotect_at(loc1); xm_unprotect_at(loc2); return(Xen_list_2(lst1, lst2)); } static Xen gxm_XFreeFontSet(Xen arg1, Xen arg2) { #define H_XFreeFontSet "void XFreeFontSet(display, font_set) frees the specified font set." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XFreeFontSet", "Display*"); Xen_check_type(Xen_is_XFontSet(arg2), arg2, 2, "XFreeFontSet", "XFontSet"); XFreeFontSet(Xen_to_C_Display(arg1), Xen_to_C_XFontSet(arg2)); return(Xen_false); } static Xen gxm_XCreateFontSet(Xen arg1, Xen arg2) { #define H_XCreateFontSet "XFontSet XCreateFontSet(display, base_font_name_list) creates a font set for the specified display." /* DIFF: XCreateFontSet ignores (omits) the 3 trailing missing glyph args */ char **cs; int len; char *str; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XCreateFontSet", "Display*"); Xen_check_type(Xen_is_string(arg2), arg2, 2, "XCreateFontSet", "char*"); return(C_to_Xen_XFontSet(XCreateFontSet(Xen_to_C_Display(arg1), (char *)Xen_string_to_C_string(arg2), &cs, &len, &str))); } static Xen gxm_XSetLocaleModifiers(Xen arg1) { #define H_XSetLocaleModifiers "char *XSetLocaleModifiers(modifier_list) sets the X modifiers for the current locale setting." Xen_check_type(Xen_is_string(arg1), arg1, 1, "XSetLocaleModifiers", "char*"); return(C_string_to_Xen_string(XSetLocaleModifiers(Xen_string_to_C_string(arg1)))); } static Xen gxm_XSupportsLocale(void) { #define H_XSupportsLocale "Bool XSupportsLocale(): returns " PROC_TRUE " if Xlib functions are capable of operating under the current locale." return(C_bool_to_Xen_boolean(XSupportsLocale())); } static Xen gxm_XWriteBitmapFile(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6, Xen arg7) { #define H_XWriteBitmapFile "int XWriteBitmapFile(display, filename, bitmap, width, height, x_hot, y_hot) writes a bitmap out to a file in \ the X Version 11 format." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XWriteBitmapFile", "Display*"); Xen_check_type(Xen_is_string(arg2), arg2, 2, "XWriteBitmapFile", "char*"); Xen_check_type(Xen_is_Pixmap(arg3), arg3, 3, "XWriteBitmapFile", "Pixmap"); Xen_check_type(Xen_is_ulong(arg4), arg4, 4, "XWriteBitmapFile", "unsigned int"); Xen_check_type(Xen_is_ulong(arg5), arg5, 5, "XWriteBitmapFile", "unsigned int"); Xen_check_type(Xen_is_integer(arg6), arg6, 6, "XWriteBitmapFile", "int"); Xen_check_type(Xen_is_integer(arg7), arg7, 7, "XWriteBitmapFile", "int"); return(C_int_to_Xen_integer(XWriteBitmapFile(Xen_to_C_Display(arg1), (char *)Xen_string_to_C_string(arg2), Xen_to_C_Pixmap(arg3), Xen_ulong_to_C_ulong(arg4), Xen_ulong_to_C_ulong(arg5), Xen_integer_to_C_int(arg6), Xen_integer_to_C_int(arg7)))); } static Xen gxm_XWindowEvent(Xen arg1, Xen arg2, Xen arg3) { #define H_XWindowEvent "XWindowEvent(display, w, event_mask) searches the event queue for an event that matches both \ the specified window and event mask, and removes it or waits until it arrives." /* DIFF: XWindowEvent dpy win ev [evrtn] -> (list val evrtn) */ XEvent *e; int val; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XWindowEvent", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XWindowEvent", "Window"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XWindowEvent", "long"); e = (XEvent *)calloc(1, sizeof(XEvent)); val = XWindowEvent(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_integer_to_C_int(arg3), e); return(Xen_list_2(C_int_to_Xen_integer(val), C_to_Xen_XEvent_OBJ(e))); } static Xen gxm_XWidthOfScreen(Xen arg1) { #define H_WidthOfScreen "XWidthOfScreen(screen): returns the width of the specified screen." Xen_check_type(Xen_is_Screen(arg1), arg1, 1, "XWidthOfScreen", "Screen*"); return(C_int_to_Xen_integer(XWidthOfScreen(Xen_to_C_Screen(arg1)))); } static Xen gxm_XWidthMMOfScreen(Xen arg1) { #define H_WidthMMOfScreen "XWidthMMOfScreen(screen): returns the width of the specified screen in millimeters." Xen_check_type(Xen_is_Screen(arg1), arg1, 1, "XWidthMMOfScreen", "Screen*"); return(C_int_to_Xen_integer(XWidthMMOfScreen(Xen_to_C_Screen(arg1)))); } static Xen gxm_XWarpPointer(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6, Xen arg7, Xen arg8, Xen arg9) { #define H_XWarpPointer "XWarpPointer(display, src_w, dest_w, src_x, src_y, src_width, src_height, dest_x, dest_y)" Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XWarpPointer", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XWarpPointer", "Window"); Xen_check_type(Xen_is_Window(arg3), arg3, 3, "XWarpPointer", "Window"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XWarpPointer", "int"); Xen_check_type(Xen_is_integer(arg5), arg5, 5, "XWarpPointer", "int"); Xen_check_type(Xen_is_ulong(arg6), arg6, 6, "XWarpPointer", "unsigned int"); Xen_check_type(Xen_is_ulong(arg7), arg7, 7, "XWarpPointer", "unsigned int"); Xen_check_type(Xen_is_integer(arg8), arg8, 8, "XWarpPointer", "int"); Xen_check_type(Xen_is_integer(arg9), arg9, 9, "XWarpPointer", "int"); return(C_int_to_Xen_integer(XWarpPointer(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_to_C_Window(arg3), Xen_integer_to_C_int(arg4), Xen_integer_to_C_int(arg5), Xen_ulong_to_C_ulong(arg6), Xen_ulong_to_C_ulong(arg7), Xen_integer_to_C_int(arg8), Xen_integer_to_C_int(arg9)))); } static Xen gxm_XVendorRelease(Xen arg1) { #define H_VendorRelease "VendorRelease(display): returns a number related to a vendor's release of the X server." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XVendorRelease", "Display*"); return(C_int_to_Xen_integer(XVendorRelease(Xen_to_C_Display(arg1)))); } static Xen gxm_XUnmapWindow(Xen arg1, Xen arg2) { #define H_XUnmapWindow "XUnmapWindow(display, w) unmaps the specified window and causes the X server to generate an UnmapNotify event." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XUnmapWindow", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XUnmapWindow", "Window"); return(C_int_to_Xen_integer(XUnmapWindow(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2)))); } static Xen gxm_XUnmapSubwindows(Xen arg1, Xen arg2) { #define H_XUnmapSubwindows "XUnmapSubwindows(display, w) unmaps all subwindows for the specified window in bottom-to-top stacking order." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XUnmapSubwindows", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XUnmapSubwindows", "Window"); return(C_int_to_Xen_integer(XUnmapSubwindows(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2)))); } static Xen gxm_XUnloadFont(Xen arg1, Xen arg2) { #define H_XUnloadFont "XUnloadFont(display, font) deletes the association between the font resource ID and the specified font." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XUnloadFont", "Display*"); Xen_check_type(Xen_is_Font(arg2), arg2, 2, "XUnloadFont", "Font"); return(C_int_to_Xen_integer(XUnloadFont(Xen_to_C_Display(arg1), Xen_to_C_Font(arg2)))); } static Xen gxm_XUninstallColormap(Xen arg1, Xen arg2) { #define H_XUninstallColormap "XUninstallColormap(display, colormap) removes the specified colormap from the required list for its screen." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XUninstallColormap", "Display*"); Xen_check_type(Xen_is_Colormap(arg2), arg2, 2, "XUninstallColormap", "Colormap"); return(C_int_to_Xen_integer(XUninstallColormap(Xen_to_C_Display(arg1), Xen_to_C_Colormap(arg2)))); } static Xen gxm_XUngrabServer(Xen arg1) { #define H_XUngrabServer "XUngrabServer(display) restarts processing of requests and close downs on other connections." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XUngrabServer", "Display*"); return(C_int_to_Xen_integer(XUngrabServer(Xen_to_C_Display(arg1)))); } static Xen gxm_XUngrabPointer(Xen arg1, Xen arg2) { #define H_XUngrabPointer "XUngrabPointer(display, time) releases the pointer and any queued events if this client has actively grabbed the \ pointer from XGrabPointer, XGrabButton,or from a normal button press." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XUngrabPointer", "Display*"); Xen_check_type(Xen_is_Time(arg2), arg2, 2, "XUngrabPointer", "Time"); return(C_int_to_Xen_integer(XUngrabPointer(Xen_to_C_Display(arg1), Xen_to_C_Time(arg2)))); } static Xen gxm_XUngrabKeyboard(Xen arg1, Xen arg2) { #define H_XUngrabKeyboard "XUngrabKeyboard(display, time) releases the keyboard and any queued events if this client has it actively grabbed \ from either XGrabKeyboard or XGrabKey." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XUngrabKeyboard", "Display*"); Xen_check_type(Xen_is_Time(arg2), arg2, 2, "XUngrabKeyboard", "Time"); return(C_int_to_Xen_integer(XUngrabKeyboard(Xen_to_C_Display(arg1), Xen_to_C_Time(arg2)))); } static Xen gxm_XUngrabKey(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XUngrabKey "XUngrabKey(display, keycode, modifiers, grab_window) releases the key combination on the specified window if it was \ grabbed by this client." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XUngrabKey", "Display*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XUngrabKey", "int"); Xen_check_type(Xen_is_ulong(arg3), arg3, 3, "XUngrabKey", "unsigned int"); Xen_check_type(Xen_is_Window(arg4), arg4, 4, "XUngrabKey", "Window"); return(C_int_to_Xen_integer(XUngrabKey(Xen_to_C_Display(arg1), Xen_integer_to_C_int(arg2), Xen_ulong_to_C_ulong(arg3), Xen_to_C_Window(arg4)))); } static Xen gxm_XUngrabButton(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XUngrabButton "XUngrabButton(display, button, modifiers, grab_window) releases the passive button/key combination on the specified \ window if it was grabbed by this client." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XUngrabButton", "Display*"); Xen_check_type(Xen_is_ulong(arg2), arg2, 2, "XUngrabButton", "unsigned int"); Xen_check_type(Xen_is_ulong(arg3), arg3, 3, "XUngrabButton", "unsigned int"); Xen_check_type(Xen_is_Window(arg4), arg4, 4, "XUngrabButton", "Window"); return(C_int_to_Xen_integer(XUngrabButton(Xen_to_C_Display(arg1), Xen_ulong_to_C_ulong(arg2), Xen_ulong_to_C_ulong(arg3), Xen_to_C_Window(arg4)))); } static Xen gxm_XUndefineCursor(Xen arg1, Xen arg2) { #define H_XUndefineCursor "XUndefineCursor(display, w) undoes the effect of a previous XDefineCursor for this window." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XUndefineCursor", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XUndefineCursor", "Window"); return(C_int_to_Xen_integer(XUndefineCursor(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2)))); } static Xen gxm_XTranslateCoordinates(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5) { #define H_XTranslateCoordinates "Bool XTranslateCoordinates(display, src_w, dest_w, src_x, src_y) \ takes the src_x and src_y coordinates relative to the source window's origin and returns these coordinates to dest_x_return and dest_y_return \ relative to the destination window's origin -> (rtn x y win)." /* DIFF: XTranslateCoordinates omit last 3 args */ Window w; int x, y, rtn; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XTranslateCoordinates", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XTranslateCoordinates", "Window"); Xen_check_type(Xen_is_Window(arg3), arg3, 3, "XTranslateCoordinates", "Window"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XTranslateCoordinates", "int"); Xen_check_type(Xen_is_integer(arg5), arg5, 5, "XTranslateCoordinates", "int"); rtn = XTranslateCoordinates(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_to_C_Window(arg3), Xen_integer_to_C_int(arg4), Xen_integer_to_C_int(arg5), &x, &y, &w); return(Xen_list_4(C_bool_to_Xen_boolean(rtn), C_int_to_Xen_integer(x), C_int_to_Xen_integer(y), C_to_Xen_Window(w))); } static Xen gxm_XTextWidth(Xen arg1, Xen arg2, Xen arg3) { #define H_XTextWidth "int XTextWidth(font_struct, string, count): returns the width of the specified 8-bit string." Xen_check_type(Xen_is_XFontStruct(arg1), arg1, 1, "XTextWidth", "XFontStruct*"); Xen_check_type(Xen_is_string(arg2), arg2, 2, "XTextWidth", "char*"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XTextWidth", "int"); return(C_int_to_Xen_integer(XTextWidth(Xen_to_C_XFontStruct(arg1), (char *)Xen_string_to_C_string(arg2), Xen_integer_to_C_int(arg3)))); } static Xen gxm_XTextExtents(Xen arg1, Xen arg2, Xen arg3) { #define H_XTextExtents "XTextExtents(font_struct, string, nchars): returns an XCharStruct structure describing the text." /* DIFF: XTextExtents omit final 4 args and returns them [Xcharset returned as embedded list) */ int dir, fa, fd, rtn; XCharStruct val; Xen_check_type(Xen_is_XFontStruct(arg1), arg1, 1, "XTextExtents", "XFontStruct*"); Xen_check_type(Xen_is_string(arg2), arg2, 2, "XTextExtents", "char*"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XTextExtents", "int"); rtn = XTextExtents(Xen_to_C_XFontStruct(arg1), (char *)Xen_string_to_C_string(arg2), Xen_integer_to_C_int(arg3), &dir, &fa, &fd, &val); return(Xen_list_5(C_int_to_Xen_integer(rtn), C_int_to_Xen_integer(dir), C_int_to_Xen_integer(fa), C_int_to_Xen_integer(fd), Xen_list_6(C_int_to_Xen_integer((int)(val.lbearing)), C_int_to_Xen_integer((int)(val.rbearing)), C_int_to_Xen_integer((int)(val.width)), C_int_to_Xen_integer((int)(val.ascent)), C_int_to_Xen_integer((int)(val.descent)), C_int_to_Xen_integer((int)(val.attributes))))); } static Xen gxm_XSync(Xen arg1, Xen arg2) { #define H_XSync "XSync(display, discard) flushes the output buffer and then waits until all requests have been received and processed by the X server." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XSync", "Display*"); Xen_check_type(Xen_is_boolean(arg2), arg2, 2, "XSync", "Bool"); return(C_int_to_Xen_integer(XSync(Xen_to_C_Display(arg1), Xen_boolean_to_C_bool(arg2)))); } static Xen gxm_XStoreNamedColor(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5) { #define H_XStoreNamedColor "XStoreNamedColor(display, colormap, color, pixel, flags) looks up the named color with respect to the screen \ associated with the colormap and stores the result in the specified colormap." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XStoreNamedColor", "Display*"); Xen_check_type(Xen_is_Colormap(arg2), arg2, 2, "XStoreNamedColor", "Colormap"); Xen_check_type(Xen_is_string(arg3), arg3, 3, "XStoreNamedColor", "char*"); Xen_check_type(Xen_is_ulong(arg4), arg4, 4, "XStoreNamedColor", "ulong"); /* this is explicitly an index into the colormap, so I'll leave it as is */ Xen_check_type(Xen_is_integer(arg5), arg5, 5, "XStoreNamedColor", "int"); return(C_int_to_Xen_integer(XStoreNamedColor(Xen_to_C_Display(arg1), Xen_to_C_Colormap(arg2), (char *)Xen_string_to_C_string(arg3), Xen_ulong_to_C_ulong(arg4), Xen_integer_to_C_int(arg5)))); } static Xen gxm_XStoreName(Xen arg1, Xen arg2, Xen arg3) { #define H_XStoreName "XStoreName(display, w, window_name) assigns the name passed to window_name to the specified window." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XStoreName", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XStoreName", "Window"); Xen_check_type(Xen_is_string(arg3), arg3, 3, "XStoreName", "char*"); return(C_int_to_Xen_integer(XStoreName(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), (char *)Xen_string_to_C_string(arg3)))); } static Xen gxm_XStoreColors(Xen arg1, Xen arg2, Xen larg3, Xen arg4) { #define H_XStoreColors "XStoreColors(display, colormap, color, ncolors) changes the colormap entries of the pixel values specified in the \ pixel members of the XColor structures." /* DIFF: XStoreColors arg 3 is list of XColor */ XColor *xc; int i, len; Xen arg3; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XStoreColors", "Display*"); Xen_check_type(Xen_is_Colormap(arg2), arg2, 2, "XStoreColors", "Colormap"); Xen_check_type(Xen_is_list(larg3), larg3, 3, "XStoreColors", "list of XColor"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XStoreColors", "int"); arg3 = Xen_copy_arg(larg3); len = Xen_integer_to_C_int(arg4); if (len <= 0) Xen_check_type(0, arg4, 4, "XStoreColors", "positive integer"); xc = (XColor *)calloc(len, sizeof(XColor)); for (i = 0; (i < len) && (!Xen_is_null(arg3)); i++, arg3 = Xen_cdr(arg3)) { XColor *xc1; xc1 = Xen_to_C_XColor(Xen_car(arg3)); xc[i].pixel = xc1->pixel; xc[i].red = xc1->red; xc[i].green = xc1->green; xc[i].blue = xc1->blue; xc[i].flags = xc1->flags; xc[i].pad = xc1->pad; } XStoreColors(Xen_to_C_Display(arg1), Xen_to_C_Colormap(arg2), xc, len); free(xc); return(C_int_to_Xen_integer(len)); } static Xen gxm_XStoreColor(Xen arg1, Xen arg2, Xen arg3) { #define H_XStoreColor "XStoreColor(display, colormap, color) changes the colormap entry of the pixel value specified in the pixel member \ of the XColor structure." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XStoreColor", "Display*"); Xen_check_type(Xen_is_Colormap(arg2), arg2, 2, "XStoreColor", "Colormap"); Xen_check_type(Xen_is_XColor(arg3), arg3, 3, "XStoreColor", "XColor"); return(C_int_to_Xen_integer(XStoreColor(Xen_to_C_Display(arg1), Xen_to_C_Colormap(arg2), Xen_to_C_XColor(arg3)))); } static Xen gxm_XStoreBytes(Xen arg1, Xen arg2, Xen arg3) { #define H_XStoreBytes "XStoreBytes(display, bytes, nbytes)" Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XStoreBytes", "Display*"); Xen_check_type(Xen_is_string(arg2), arg2, 2, "XStoreBytes", "char*"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XStoreBytes", "int"); return(C_int_to_Xen_integer(XStoreBytes(Xen_to_C_Display(arg1), (char *)Xen_string_to_C_string(arg2), Xen_integer_to_C_int(arg3) + 1))); } static Xen gxm_XStoreBuffer(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XStoreBuffer "XStoreBuffer(display, bytes, nbytes, buffer)" Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XStoreBuffer", "Display*"); Xen_check_type(Xen_is_string(arg2), arg2, 2, "XStoreBuffer", "char*"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XStoreBuffer", "int"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XStoreBuffer", "int"); return(C_int_to_Xen_integer(XStoreBuffer(Xen_to_C_Display(arg1), (char *)Xen_string_to_C_string(arg2), Xen_integer_to_C_int(arg3) + 1, Xen_integer_to_C_int(arg4)))); } static Xen gxm_XSetWindowColormap(Xen arg1, Xen arg2, Xen arg3) { #define H_XSetWindowColormap "XSetWindowColormap(display, w, colormap) sets the specified colormap of the specified window." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XSetWindowColormap", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XSetWindowColormap", "Window"); Xen_check_type(Xen_is_Colormap(arg3), arg3, 3, "XSetWindowColormap", "Colormap"); return(C_int_to_Xen_integer(XSetWindowColormap(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_to_C_Colormap(arg3)))); } static Xen gxm_XSetWindowBorderWidth(Xen arg1, Xen arg2, Xen arg3) { #define H_XSetWindowBorderWidth "XSetWindowBorderWidth(display, w, width) sets the specified window's border width to the specified width." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XSetWindowBorderWidth", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XSetWindowBorderWidth", "Window"); Xen_check_type(Xen_is_ulong(arg3), arg3, 3, "XSetWindowBorderWidth", "unsigned int"); return(C_int_to_Xen_integer(XSetWindowBorderWidth(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_ulong_to_C_ulong(arg3)))); } static Xen gxm_XSetWindowBorderPixmap(Xen arg1, Xen arg2, Xen arg3) { #define H_XSetWindowBorderPixmap "XSetWindowBorderPixmap(display, w, border_pixmap) sets the border pixmap of the window to the pixmap you specify." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XSetWindowBorderPixmap", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XSetWindowBorderPixmap", "Window"); Xen_check_type(Xen_is_Pixmap(arg3) || Xen_is_integer(arg3), arg3, 3, "XSetWindowBorderPixmap", "Pixmap"); return(C_int_to_Xen_integer(XSetWindowBorderPixmap(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), (Xen_is_Pixmap(arg3)) ? Xen_to_C_Pixmap(arg3) : CopyFromParent))); } static Xen gxm_XSetWindowBorder(Xen arg1, Xen arg2, Xen arg3) { #define H_XSetWindowBorder "XSetWindowBorder(display, w, border_pixel) sets the border of the window to the pixel value you specify." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XSetWindowBorder", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XSetWindowBorder", "Window"); Xen_check_type(Xen_is_Pixel(arg3), arg3, 3, "XSetWindowBorder", "pixel"); return(C_int_to_Xen_integer(XSetWindowBorder(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_to_C_Pixel(arg3)))); } static Xen gxm_XSetWindowBackgroundPixmap(Xen arg1, Xen arg2, Xen arg3) { #define H_XSetWindowBackgroundPixmap "XSetWindowBackgroundPixmap(display, w, background_pixmap) sets the background pixmap of the window to \ the specified pixmap." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XSetWindowBackgroundPixmap", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XSetWindowBackgroundPixmap", "Window"); Xen_check_type(Xen_is_Pixmap(arg3) || Xen_is_integer(arg3), arg3, 3, "XSetWindowBackgroundPixmap", "Pixmap"); return(C_int_to_Xen_integer(XSetWindowBackgroundPixmap(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), (Xen_is_Pixmap(arg3)) ? Xen_to_C_Pixmap(arg3) : Xen_ulong_to_C_ulong(arg3)))); } static Xen gxm_XSetWindowBackground(Xen arg1, Xen arg2, Xen arg3) { #define H_XSetWindowBackground "XSetWindowBackground(display, w, background_pixel) sets the background of the window to the specified pixel value." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XSetWindowBackground", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XSetWindowBackground", "Window"); Xen_check_type(Xen_is_Pixel(arg3), arg3, 3, "XSetWindowBackground", "pixel"); return(C_int_to_Xen_integer(XSetWindowBackground(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_to_C_Pixel(arg3)))); } static Xen gxm_XSetTile(Xen arg1, Xen arg2, Xen arg3) { #define H_XSetTile "XSetTile(display, gc, tile) sets the fill tile in the specified GC." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XSetTile", "Display*"); Xen_check_type(Xen_is_GC(arg2), arg2, 2, "XSetTile", "GC"); Xen_check_type(Xen_is_Pixmap(arg3), arg3, 3, "XSetTile", "Pixmap"); return(C_int_to_Xen_integer(XSetTile(Xen_to_C_Display(arg1), Xen_to_C_GC(arg2), Xen_to_C_Pixmap(arg3)))); } static Xen gxm_XSetTSOrigin(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XSetTSOrigin "XSetTSOrigin(display, gc, ts_x_origin, ts_y_origin) sets the tile/stipple origin in the specified GC." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XSetTSOrigin", "Display*"); Xen_check_type(Xen_is_GC(arg2), arg2, 2, "XSetTSOrigin", "GC"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XSetTSOrigin", "int"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XSetTSOrigin", "int"); return(C_int_to_Xen_integer(XSetTSOrigin(Xen_to_C_Display(arg1), Xen_to_C_GC(arg2), Xen_integer_to_C_int(arg3), Xen_integer_to_C_int(arg4)))); } static Xen gxm_XSetSubwindowMode(Xen arg1, Xen arg2, Xen arg3) { #define H_XSetSubwindowMode "XSetSubwindowMode(display, gc, subwindow_mode) sets the subwindow mode in the specified GC." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XSetSubwindowMode", "Display*"); Xen_check_type(Xen_is_GC(arg2), arg2, 2, "XSetSubwindowMode", "GC"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XSetSubwindowMode", "int"); return(C_int_to_Xen_integer(XSetSubwindowMode(Xen_to_C_Display(arg1), Xen_to_C_GC(arg2), Xen_integer_to_C_int(arg3)))); } static Xen gxm_XSetStipple(Xen arg1, Xen arg2, Xen arg3) { #define H_XSetStipple "XSetStipple(display, gc, stipple) sets the stipple in the specified GC." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XSetStipple", "Display*"); Xen_check_type(Xen_is_GC(arg2), arg2, 2, "XSetStipple", "GC"); Xen_check_type(Xen_is_Pixmap(arg3), arg3, 3, "XSetStipple", "Pixmap"); return(C_int_to_Xen_integer(XSetStipple(Xen_to_C_Display(arg1), Xen_to_C_GC(arg2), Xen_to_C_Pixmap(arg3)))); } static Xen gxm_XSetState(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6) { #define H_XSetState "XSetState(display, gc, foreground, background, function, plane_mask) sets the foreground, background, plane mask, and \ function components for the specified GC." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XSetState", "Display*"); Xen_check_type(Xen_is_GC(arg2), arg2, 2, "XSetState", "GC"); Xen_check_type(Xen_is_Pixel(arg3), arg3, 3, "XSetState", "Pixel"); Xen_check_type(Xen_is_Pixel(arg4), arg4, 4, "XSetState", "Pixel"); Xen_check_type(Xen_is_integer(arg5), arg5, 5, "XSetState", "int"); Xen_check_type(Xen_is_ulong(arg6), arg6, 6, "XSetState", "ulong"); return(C_int_to_Xen_integer(XSetState(Xen_to_C_Display(arg1), Xen_to_C_GC(arg2), Xen_to_C_Pixel(arg3), Xen_to_C_Pixel(arg4), Xen_integer_to_C_int(arg5), Xen_ulong_to_C_ulong(arg6)))); } static Xen gxm_XSetSelectionOwner(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XSetSelectionOwner "XSetSelectionOwner(display, selection, owner, time) changes the owner and last-change time for the specified selection" Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XSetSelectionOwner", "Display*"); Xen_check_type(Xen_is_Atom(arg2), arg2, 2, "XSetSelectionOwner", "Atom"); Xen_check_type(Xen_is_Window(arg3), arg3, 3, "XSetSelectionOwner", "Window"); Xen_check_type(Xen_is_Time(arg4), arg4, 4, "XSetSelectionOwner", "Time"); return(C_int_to_Xen_integer(XSetSelectionOwner(Xen_to_C_Display(arg1), Xen_to_C_Atom(arg2), Xen_to_C_Window(arg3), Xen_to_C_Time(arg4)))); } static Xen gxm_XSetScreenSaver(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5) { #define H_XSetScreenSaver "XSetScreenSaver(display, timeout, interval, prefer_blanking, allow_exposures) enables the screen saver." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XSetScreenSaver", "Display*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XSetScreenSaver", "int"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XSetScreenSaver", "int"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XSetScreenSaver", "int"); Xen_check_type(Xen_is_integer(arg5), arg5, 5, "XSetScreenSaver", "int"); return(C_int_to_Xen_integer(XSetScreenSaver(Xen_to_C_Display(arg1), Xen_integer_to_C_int(arg2), Xen_integer_to_C_int(arg3), Xen_integer_to_C_int(arg4), Xen_integer_to_C_int(arg5)))); } static Xen gxm_XSetPointerMapping(Xen arg1, Xen arg2, Xen arg3) { #define H_XSetPointerMapping "int XSetPointerMapping(display, map, nmap) sets the mapping of the pointer." int i, len, rtn; unsigned char *map; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XSetPointerMapping", "Display*"); Xen_check_type(Xen_is_list(arg2), arg2, 2, "XSetPointerMapping", "list of ints"); Xen_check_type(Xen_is_integer_or_unbound(arg3), arg3, 3, "XSetPointerMapping", "int"); if (Xen_is_integer(arg3)) len = Xen_integer_to_C_int(arg3); else len = Xen_list_length(arg2); map = (unsigned char *)calloc(len, sizeof(unsigned char)); for (i = 0; i < len; i++) map[i] = (unsigned char)Xen_integer_to_C_int(Xen_list_ref(arg2, i)); rtn = XSetPointerMapping(Xen_to_C_Display(arg1), map, len); free(map); return(C_int_to_Xen_integer(rtn)); } static Xen gxm_XSetPlaneMask(Xen arg1, Xen arg2, Xen arg3) { #define H_XSetPlaneMask "XSetPlaneMask(display, gc, plane_mask) sets the plane mask in the specified GC." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XSetPlaneMask", "Display*"); Xen_check_type(Xen_is_GC(arg2), arg2, 2, "XSetPlaneMask", "GC"); Xen_check_type(Xen_is_ulong(arg3), arg3, 3, "XSetPlaneMask", "ulong"); return(C_int_to_Xen_integer(XSetPlaneMask(Xen_to_C_Display(arg1), Xen_to_C_GC(arg2), Xen_ulong_to_C_ulong(arg3)))); } static Xen gxm_XSetModifierMapping(Xen arg1, Xen arg2) { #define H_XSetModifierMapping "int XSetModifierMapping(display, modmap) specifies the KeyCodes of the keys (if any) that are to be used as modifiers." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XSetModifierMapping", "Display*"); Xen_check_type(Xen_is_XModifierKeymap(arg2), arg2, 2, "XSetModifierMapping", "XModifierKeymap*"); return(C_int_to_Xen_integer(XSetModifierMapping(Xen_to_C_Display(arg1), Xen_to_C_XModifierKeymap(arg2)))); } static Xen gxm_XSetLineAttributes(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6) { #define H_XSetLineAttributes "XSetLineAttributes(display, gc, line_width, line_style, cap_style, join_style) sets the line drawing components \ in the specified GC." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XSetLineAttributes", "Display*"); Xen_check_type(Xen_is_GC(arg2), arg2, 2, "XSetLineAttributes", "GC"); Xen_check_type(Xen_is_ulong(arg3), arg3, 3, "XSetLineAttributes", "unsigned int"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XSetLineAttributes", "int"); Xen_check_type(Xen_is_integer(arg5), arg5, 5, "XSetLineAttributes", "int"); Xen_check_type(Xen_is_integer(arg6), arg6, 6, "XSetLineAttributes", "int"); return(C_int_to_Xen_integer(XSetLineAttributes(Xen_to_C_Display(arg1), Xen_to_C_GC(arg2), Xen_ulong_to_C_ulong(arg3), Xen_integer_to_C_int(arg4), Xen_integer_to_C_int(arg5), Xen_integer_to_C_int(arg6)))); } static Xen gxm_XSetInputFocus(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XSetInputFocus "XSetInputFocus(display, focus, revert_to, time) changes the input focus and the last-focus-change time." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XSetInputFocus", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XSetInputFocus", "Window"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XSetInputFocus", "int"); Xen_check_type(Xen_is_Time(arg4), arg4, 4, "XSetInputFocus", "Time"); return(C_int_to_Xen_integer(XSetInputFocus(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_integer_to_C_int(arg3), Xen_to_C_Time(arg4)))); } static Xen gxm_XSetIconName(Xen arg1, Xen arg2, Xen arg3) { #define H_XSetIconName "XSetIconName(display, w, icon_name) sets the name to be displayed in a window's icon." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XSetIconName", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XSetIconName", "Window"); Xen_check_type(Xen_is_string(arg3), arg3, 3, "XSetIconName", "char*"); return(C_int_to_Xen_integer(XSetIconName(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), (char *)Xen_string_to_C_string(arg3)))); } static Xen gxm_XSetGraphicsExposures(Xen arg1, Xen arg2, Xen arg3) { #define H_XSetGraphicsExposures "XSetGraphicsExposures(display, gc, graphics_exposures) sets the graphics-exposures flag in the specified GC." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XSetGraphicsExposures", "Display*"); Xen_check_type(Xen_is_GC(arg2), arg2, 2, "XSetGraphicsExposures", "GC"); Xen_check_type(Xen_is_boolean(arg3), arg3, 3, "XSetGraphicsExposures", "Bool"); return(C_int_to_Xen_integer(XSetGraphicsExposures(Xen_to_C_Display(arg1), Xen_to_C_GC(arg2), Xen_boolean_to_C_bool(arg3)))); } static Xen gxm_XSetFunction(Xen arg1, Xen arg2, Xen arg3) { #define H_XSetFunction "XSetFunction(display, gc, function) sets a specified value in the specified GC" Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XSetFunction", "Display*"); Xen_check_type(Xen_is_GC(arg2), arg2, 2, "XSetFunction", "GC"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XSetFunction", "int"); return(C_int_to_Xen_integer(XSetFunction(Xen_to_C_Display(arg1), Xen_to_C_GC(arg2), Xen_integer_to_C_int(arg3)))); } static Xen gxm_XSetForeground(Xen arg1, Xen arg2, Xen arg3) { #define H_XSetForeground "XSetForeground(display, gc, foreground) sets the foreground in the specified GC." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XSetForeground", "Display*"); Xen_check_type(Xen_is_GC(arg2), arg2, 2, "XSetForeground", "GC"); Xen_check_type(Xen_is_Pixel(arg3), arg3, 3, "XSetForeground", "Pixel"); return(C_int_to_Xen_integer(XSetForeground(Xen_to_C_Display(arg1), Xen_to_C_GC(arg2), Xen_to_C_Pixel(arg3)))); } static Xen gxm_XSetFontPath(Xen arg1, Xen arg2, Xen arg3) { #define H_XSetFontPath "XSetFontPath(display, directories, ndirs) defines the directory search path for font lookup." /* DIFF: XSetFontPath arg2 is list of strings */ char **paths; int len, rtn; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XSetFontPath", "Display*"); Xen_check_type(Xen_is_list(arg2), arg2, 2, "XSetFontPath", "list of char*"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XSetFontPath", "int"); len = Xen_integer_to_C_int(arg3); if (len > 0) paths = Xen_to_C_Strings(arg2, len); else paths = NULL; rtn = XSetFontPath(Xen_to_C_Display(arg1), paths, len); if (paths) free(paths); return(C_int_to_Xen_integer(rtn)); } static Xen gxm_XSetFont(Xen arg1, Xen arg2, Xen arg3) { #define H_XSetFont "XSetFont(display, gc, font) sets the current font in the specified GC." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XSetFont", "Display*"); Xen_check_type(Xen_is_GC(arg2), arg2, 2, "XSetFont", "GC"); Xen_check_type(Xen_is_Font(arg3), arg3, 3, "XSetFont", "Font"); return(C_int_to_Xen_integer(XSetFont(Xen_to_C_Display(arg1), Xen_to_C_GC(arg2), Xen_to_C_Font(arg3)))); } static Xen gxm_XSetFillStyle(Xen arg1, Xen arg2, Xen arg3) { #define H_XSetFillStyle "XSetFillStyle(display, gc, fill_style) sets the fill-style in the specified GC." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XSetFillStyle", "Display*"); Xen_check_type(Xen_is_GC(arg2), arg2, 2, "XSetFillStyle", "GC"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XSetFillStyle", "int"); return(C_int_to_Xen_integer(XSetFillStyle(Xen_to_C_Display(arg1), Xen_to_C_GC(arg2), Xen_integer_to_C_int(arg3)))); } static Xen gxm_XSetFillRule(Xen arg1, Xen arg2, Xen arg3) { #define H_XSetFillRule "XSetFillRule(display, gc, fill_rule) sets the fill-rule in the specified GC." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XSetFillRule", "Display*"); Xen_check_type(Xen_is_GC(arg2), arg2, 2, "XSetFillRule", "GC"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XSetFillRule", "int"); return(C_int_to_Xen_integer(XSetFillRule(Xen_to_C_Display(arg1), Xen_to_C_GC(arg2), Xen_integer_to_C_int(arg3)))); } static Xen gxm_XSetDashes(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5) { #define H_XSetDashes "XSetDashes(display, gc, dash_offset, dash_list, n) sets the dash-offset and dash-list attributes for dashed line styles \ in the specified GC." char *dashes; int i, len = 0, val; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XSetDashes", "Display*"); Xen_check_type(Xen_is_GC(arg2), arg2, 2, "XSetDashes", "GC"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XSetDashes", "int"); Xen_check_type(Xen_is_list(arg4), arg4, 4, "XSetDashes", "list of ints"); Xen_check_type(Xen_is_integer_or_unbound(arg5), arg5, 5, "XSetDashes", "optional length of list (int)"); if (Xen_is_integer(arg5)) len = Xen_integer_to_C_int(arg5); if (len <= 0) len = Xen_list_length(arg4); dashes = (char *)calloc(len, sizeof(char)); for (i = 0; i < len; i++) dashes[i] = (char)(Xen_integer_to_C_int(Xen_list_ref(arg4, i))); val = XSetDashes(Xen_to_C_Display(arg1), Xen_to_C_GC(arg2), Xen_integer_to_C_int(arg3), dashes, len); free(dashes); return(C_int_to_Xen_integer(val)); } static Xen gxm_XSetCommand(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XSetCommand "XSetCommand(display, w, argv, argc) sets the command and arguments used to invoke the application." /* DIFF: XSetCommand argv is list of strings */ int len, val; char **str; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XSetCommand", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XSetCommand", "Window"); Xen_check_type(Xen_is_list(arg3), arg3, 3, "XSetCommand", "list of char*"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XSetCommand", "int"); len = Xen_integer_to_C_int(arg4); if (len <= 0) return(Xen_false); str = Xen_to_C_Strings(arg3, len); val = XSetCommand(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), str, len); free(str); return(C_int_to_Xen_integer(val)); } static Xen gxm_XSetCloseDownMode(Xen arg1, Xen arg2) { #define H_XSetCloseDownMode "XSetCloseDownMode(display, close_mode) defines what will happen to the client's resources at connection close." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XSetCloseDownMode", "Display*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XSetCloseDownMode", "int"); return(C_int_to_Xen_integer(XSetCloseDownMode(Xen_to_C_Display(arg1), Xen_integer_to_C_int(arg2)))); } static Xen gxm_XSetClipRectangles(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen larg5, Xen arg6, Xen arg7) { #define H_XSetClipRectangles "XSetClipRectangles(display, gc, clip_x_origin, clip_y_origin, rectangles, n, ordering) changes the clip-mask in \ the specified GC to the specified list of rectangles and sets the clip origin." /* DIFF: XSetClipRectangles XRectangle* arg (arg 5) is list of XRectangles */ XRectangle *pt; int i, len; Xen arg5; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XSetClipRectangles", "Display*"); Xen_check_type(Xen_is_GC(arg2), arg2, 2, "XSetClipRectangles", "GC"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XSetClipRectangles", "int"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XSetClipRectangles", "int"); Xen_check_type(Xen_is_list(larg5), larg5, 5, "XSetClipRectangles", "list of XRectangles"); Xen_check_type(Xen_is_integer(arg6), arg6, 6, "XSetClipRectangles", "int"); Xen_check_type(Xen_is_integer(arg7), arg7, 7, "XSetClipRectangles", "int"); arg5 = Xen_copy_arg(larg5); len = Xen_integer_to_C_int(arg6); if (len <= 0) Xen_check_type(0, arg6, 6, "XSetClipRectangles", "positive integer"); pt = (XRectangle *)calloc(len, sizeof(XRectangle)); for (i = 0; (i < len) && (!Xen_is_null(arg5)); i++, arg5 = Xen_cdr(arg5)) { XRectangle *pt1; pt1 = Xen_to_C_XRectangle(Xen_car(arg5)); pt[i].x = pt1->x; pt[i].y = pt1->y; pt[i].width = pt1->width; pt[i].height = pt1->height; } XSetClipRectangles(Xen_to_C_Display(arg1), Xen_to_C_GC(arg2), Xen_integer_to_C_int(arg3), Xen_integer_to_C_int(arg4), pt, len, Xen_integer_to_C_int(arg7)); free(pt); return(C_int_to_Xen_integer(len)); } static Xen gxm_XSetClipOrigin(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XSetClipOrigin "XSetClipOrigin(display, gc, clip_x_origin, clip_y_origin) sets the clip origin in the specified GC." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XSetClipOrigin", "Display*"); Xen_check_type(Xen_is_GC(arg2), arg2, 2, "XSetClipOrigin", "GC"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XSetClipOrigin", "int"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XSetClipOrigin", "int"); return(C_int_to_Xen_integer(XSetClipOrigin(Xen_to_C_Display(arg1), Xen_to_C_GC(arg2), Xen_integer_to_C_int(arg3), Xen_integer_to_C_int(arg4)))); } static Xen gxm_XSetClipMask(Xen arg1, Xen arg2, Xen arg3) { #define H_XSetClipMask "XSetClipMask(display, gc, pixmap) sets the clip-mask in the specified GC to the specified pixmap." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XSetClipMask", "Display*"); Xen_check_type(Xen_is_GC(arg2), arg2, 2, "XSetClipMask", "GC"); Xen_check_type(Xen_is_Pixmap(arg3) || Xen_is_integer(arg3), arg3, 3, "XSetClipMask", "Pixmap or None"); return(C_int_to_Xen_integer(XSetClipMask(Xen_to_C_Display(arg1), Xen_to_C_GC(arg2), (Xen_is_Pixmap(arg3)) ? Xen_to_C_Pixmap(arg3) : None))); } static Xen gxm_XSetBackground(Xen arg1, Xen arg2, Xen arg3) { #define H_XSetBackground "XSetBackground(display, gc, background) sets the background in the specified GC." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XSetBackground", "Display*"); Xen_check_type(Xen_is_GC(arg2), arg2, 2, "XSetBackground", "GC"); Xen_check_type(Xen_is_Pixel(arg3), arg3, 3, "XSetBackground", "Pixel"); return(C_int_to_Xen_integer(XSetBackground(Xen_to_C_Display(arg1), Xen_to_C_GC(arg2), Xen_to_C_Pixel(arg3)))); } static Xen gxm_XSetArcMode(Xen arg1, Xen arg2, Xen arg3) { #define H_XSetArcMode "XSetArcMode(display, gc, arc_mode)" Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XSetArcMode", "Display*"); Xen_check_type(Xen_is_GC(arg2), arg2, 2, "XSetArcMode", "GC"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XSetArcMode", "int"); return(C_int_to_Xen_integer(XSetArcMode(Xen_to_C_Display(arg1), Xen_to_C_GC(arg2), Xen_integer_to_C_int(arg3)))); } static Xen gxm_XSetAccessControl(Xen arg1, Xen arg2) { #define H_XSetAccessControl "XSetAccessControl(display, mode) either enables or disables the use of the access control list at each connection setup." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XSetAccessControl", "Display*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XSetAccessControl", "int"); return(C_int_to_Xen_integer(XSetAccessControl(Xen_to_C_Display(arg1), Xen_integer_to_C_int(arg2)))); } static Xen gxm_XSendEvent(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5) { #define H_XSendEvent "Status XSendEvent(display, w, propagate, event_mask, event_send) identifies the destination window, determines which \ clients should receive the specified events, " Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XSendEvent", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XSendEvent", "Window"); Xen_check_type(Xen_is_boolean(arg3), arg3, 3, "XSendEvent", "Bool"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XSendEvent", "long"); Xen_check_type(Xen_is_XEvent(arg5), arg5, 5, "XSendEvent", "XEvent*"); return(C_int_to_Xen_integer(XSendEvent(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_boolean_to_C_bool(arg3), Xen_integer_to_C_int(arg4), Xen_to_C_XEvent(arg5)))); } static Xen gxm_XSelectInput(Xen arg1, Xen arg2, Xen arg3) { #define H_XSelectInput "XSelectInput(dpy, window, event_mask) selects input events" Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XSelectInput", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XSelectInput", "Window"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XSelectInput", "long"); return(C_int_to_Xen_integer(XSelectInput(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_integer_to_C_int(arg3)))); } static Xen gxm_XScreenCount(Xen arg1) { #define H_ScreenCount "returns the number of available screens." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XScreenCount", "Display*"); return(C_int_to_Xen_integer(XScreenCount(Xen_to_C_Display(arg1)))); } static Xen gxm_XRotateWindowProperties(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5) { #define H_XRotateWindowProperties "XRotateWindowProperties(display, w, properties, num_prop, npositions) allows you to rotate properties on a \ window and causes the X server to generate PropertyNotify events." /* DIFF: XRotateWindowProperties arg3 is list of atoms */ Atom *outs; int val, len; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XRotateWindowProperties", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XRotateWindowProperties", "Window"); Xen_check_type(Xen_is_list(arg3), arg3, 3, "XRotateWindowProperties", "list of Atom"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XRotateWindowProperties", "int"); Xen_check_type(Xen_is_integer(arg5), arg5, 5, "XRotateWindowProperties", "int"); len = Xen_integer_to_C_int(arg4); if (len <= 0) return(Xen_false); outs = Xen_to_C_Atoms(arg3, len); val = XRotateWindowProperties(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), outs, len, Xen_integer_to_C_int(arg5)); free(outs); return(C_int_to_Xen_integer(val)); } static Xen gxm_XRotateBuffers(Xen arg1, Xen arg2) { #define H_XRotateBuffers "XRotateBuffers(display, rotate) rotates the cut buffers, such that buffer 0 becomes buffer n, buffer 1 becomes n + 1 \ mod 8, and so on. " Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XRotateBuffers", "Display*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XRotateBuffers", "int"); return(C_int_to_Xen_integer(XRotateBuffers(Xen_to_C_Display(arg1), Xen_integer_to_C_int(arg2)))); } static Xen gxm_XRestackWindows(Xen arg1, Xen arg2, Xen arg3) { #define H_XRestackWindows "XRestackWindows(display, windows, nwindows) restacks the windows in the order specified, from top to bottom." /* DIFF: XRestackWindows arg2 is list of Windows */ int len, rtn; Window *ws; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XRestackWindows", "Display*"); Xen_check_type(Xen_is_list(arg2), arg2, 2, "XRestackWindows", "list of Windows"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XRestackWindows", "int"); len = Xen_integer_to_C_int(arg3); if (len <= 0) return(Xen_false); ws = Xen_to_C_Windows(arg2, len); rtn = XRestackWindows(Xen_to_C_Display(arg1), ws, len); free(ws); return(C_int_to_Xen_integer(rtn)); } static Xen gxm_XResizeWindow(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XResizeWindow "XResizeWindow(display, w, width, height) changes the inside dimensions of the specified window, not including its borders." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XResizeWindow", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XResizeWindow", "Window"); Xen_check_type(Xen_is_ulong(arg3), arg3, 3, "XResizeWindow", "unsigned int"); Xen_check_type(Xen_is_ulong(arg4), arg4, 4, "XResizeWindow", "unsigned int"); return(C_int_to_Xen_integer(XResizeWindow(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_ulong_to_C_ulong(arg3), Xen_ulong_to_C_ulong(arg4)))); } static Xen gxm_XResetScreenSaver(Xen arg1) { #define H_XResetScreenSaver "XResetScreenSaver(display) resets the screen saver." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XResetScreenSaver", "Display*"); return(C_int_to_Xen_integer(XResetScreenSaver(Xen_to_C_Display(arg1)))); } static Xen gxm_XReparentWindow(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5) { #define H_XReparentWindow "XReparentWindow(display, w, parent, x, y)" Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XReparentWindow", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XReparentWindow", "Window"); Xen_check_type(Xen_is_Window(arg3), arg3, 3, "XReparentWindow", "Window"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XReparentWindow", "int"); Xen_check_type(Xen_is_integer(arg5), arg5, 5, "XReparentWindow", "int"); return(C_int_to_Xen_integer(XReparentWindow(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_to_C_Window(arg3), Xen_integer_to_C_int(arg4), Xen_integer_to_C_int(arg5)))); } static Xen gxm_XRefreshKeyboardMapping(Xen arg1) { #define H_XRefreshKeyboardMapping "XRefreshKeyboardMapping(event_map) refreshes the stored modifier and keymap information." Xen_check_type(Xen_is_XMappingEvent(arg1), arg1, 1, "XRefreshKeyboardMapping", "XMappingEvent*"); return(C_int_to_Xen_integer(XRefreshKeyboardMapping(Xen_to_C_XMappingEvent(arg1)))); } static Xen gxm_XRecolorCursor(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XRecolorCursor "XRecolorCursor(display, cursor, foreground_color, background_color) changes the color of the specified cursor, and if \ the cursor is being displayed on a screen, the change is visible immediately." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XRecolorCursor", "Display*"); Xen_check_type(Xen_is_Cursor(arg2), arg2, 2, "XRecolorCursor", "Cursor"); Xen_check_type(Xen_is_XColor(arg3), arg3, 3, "XRecolorCursor", "XColor"); Xen_check_type(Xen_is_XColor(arg4), arg4, 4, "XRecolorCursor", "XColor"); return(C_int_to_Xen_integer(XRecolorCursor(Xen_to_C_Display(arg1), Xen_to_C_Cursor(arg2), Xen_to_C_XColor(arg3), Xen_to_C_XColor(arg4)))); } static Xen gxm_XRebindKeysym(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6) { #define H_XRebindKeysym "XRebindKeysym(display, keysym, list, mod_count, string, num_bytes) can be used to rebind the meaning of a KeySym for the client." /* DIFF: XRebindKeysym mod_list is list of keysyms */ KeySym *ks; int len, val; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XRebindKeysym", "Display*"); Xen_check_type(Xen_is_KeySym(arg2), arg2, 2, "XRebindKeysym", "KeySym"); Xen_check_type(Xen_is_list(arg3), arg3, 3, "XRebindKeysym", "list of KeySym"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XRebindKeysym", "int"); Xen_check_type(Xen_is_string(arg5), arg5, 5, "XRebindKeysym", "string"); Xen_check_type(Xen_is_integer(arg6), arg6, 6, "XRebindKeysym", "int"); len = Xen_integer_to_C_int(arg4); if (len <= 0) return(Xen_false); ks = Xen_to_C_KeySyms(arg3, len); val = XRebindKeysym(Xen_to_C_Display(arg1), Xen_to_C_KeySym(arg2), ks, len, (unsigned char *)Xen_string_to_C_string(arg5), Xen_integer_to_C_int(arg6)); free(ks); return(C_int_to_Xen_integer(val)); } static Xen gxm_XReadBitmapFileData(Xen arg1) { #define H_XReadBitmapFileData "int XReadBitmapFileData(filename) reads in a \ file containing a bitmap, in the same manner as XReadBitmapFile, but returns the data directly rather than creating a pixmap in the server." /* DIFF: XReadBitmapFileData omits last 5 args, returns as list */ unsigned int w = 0, h = 0, i, j; int x, y; unsigned char **str = NULL; /* allocated by X? */ int val, loc; Xen bits = Xen_empty_list; Xen_check_type(Xen_is_string(arg1), arg1, 1, "XReadBitmapFileData", "char*"); val = XReadBitmapFileData((char *)Xen_string_to_C_string(arg1), &w, &h, str, &x, &y); loc = xm_protect(bits); for (i = 0; i < h; i++) for (j = 0; j < w; j++) bits = Xen_cons(C_int_to_Xen_integer((int)(str[i][j])), bits); if (str) free(str); xm_unprotect_at(loc); return(Xen_list_6(C_int_to_Xen_integer(val), C_int_to_Xen_integer((int)w), C_int_to_Xen_integer((int)h), bits, C_int_to_Xen_integer((int)x), C_int_to_Xen_integer((int)y))); } static Xen gxm_XReadBitmapFile(Xen arg1, Xen arg2, Xen arg3) { #define H_XReadBitmapFile "int XReadBitmapFile(display, d, filename) reads in a file containing a bitmap." /* DIFF: XReadBitmapFile omits last 5 args, returns as list */ unsigned int w, h; int x, y; int val; Pixmap *p = NULL; /* allocated by X? */ Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XReadBitmapFile", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XReadBitmapFile", "Drawable"); Xen_check_type(Xen_is_string(arg3), arg3, 3, "XReadBitmapFile", "char*"); val = XReadBitmapFile(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), (char *)Xen_string_to_C_string(arg3), &w, &h, p, &x, &y); return(Xen_list_6(C_int_to_Xen_integer(val), C_int_to_Xen_integer((int)w), C_int_to_Xen_integer((int)h), C_to_Xen_Pixmap(*p), C_int_to_Xen_integer((int)x), C_int_to_Xen_integer((int)y))); } static Xen gxm_XRaiseWindow(Xen arg1, Xen arg2) { #define H_XRaiseWindow "XRaiseWindow(display, w)" Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XRaiseWindow", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XRaiseWindow", "Window"); return(C_int_to_Xen_integer(XRaiseWindow(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2)))); } static Xen gxm_XQueryTree(Xen arg1, Xen arg2) { #define H_XQueryTree "Status XQueryTree(display, w): returns the root ID, the \ parent window ID, a pointer to the list of children windows and the number of children in the list for the specified window." /* DIFF: XQueryTree last 4 arg omit, returns (list val root parent (list children)) */ unsigned int arrlen; Window *ws; Window root, parent; int i, val, loc; Xen lst = Xen_empty_list; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XQueryTree", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XQueryTree", "Window"); val = XQueryTree(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), &root, &parent, &ws, &arrlen); loc = xm_protect(lst); for (i = arrlen - 1; i >= 0; i--) lst = Xen_cons(C_to_Xen_Window(ws[i]), lst); XFree(ws); xm_unprotect_at(loc); return(Xen_list_4(C_int_to_Xen_integer(val), C_to_Xen_Window(root), C_to_Xen_Window(parent), lst)); } static Xen gxm_XQueryTextExtents(Xen arg1, Xen arg2, Xen arg3) { #define H_XQueryTextExtents "XQueryTextExtents(display, font, string): returns the bounding box of the specified 8-bit string." /* DIFF: XQueryTextExtents omits last 5 args, returns list */ XCharStruct *c; int fa, fd, dr, val; char *str; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XQueryTextExtents", "Display*"); Xen_check_type(Xen_is_Font(arg2), arg2, 2, "XQueryTextExtents", "Font"); Xen_check_type(Xen_is_string(arg3), arg3, 3, "XQueryTextExtents", "char*"); str = (char *)Xen_string_to_C_string(arg3); c = (XCharStruct *)calloc(1, sizeof(XCharStruct)); val = XQueryTextExtents(Xen_to_C_Display(arg1), Xen_to_C_Font(arg2), str, strlen(str), &dr, &fa, &fd, c); return(Xen_list_5(C_int_to_Xen_integer(val), C_int_to_Xen_integer(dr), C_int_to_Xen_integer(fa), C_int_to_Xen_integer(fd), wrap_for_Xen_obj("XCharStruct", c))); } static Xen gxm_XQueryPointer(Xen arg1, Xen arg2) { #define H_XQueryPointer "Bool XQueryPointer(display, w): returns the root window the pointer is logically on and the pointer \ coordinates relative to the root window's origin." /* DIFF: XQueryPointer last 7 args omit and rtn */ Window w1, w2; int rx, ry, wx, wy; unsigned int mask; int rtn; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XQueryPointer", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XQueryPointer", "Window"); rtn = XQueryPointer(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), &w1, &w2, &rx, &ry, &wx, &wy, &mask); return(Xen_list_8(C_bool_to_Xen_boolean(rtn), C_to_Xen_Window(w1), C_to_Xen_Window(w2), C_int_to_Xen_integer(rx), C_int_to_Xen_integer(ry), C_int_to_Xen_integer(wx), C_int_to_Xen_integer(wy), C_ulong_to_Xen_ulong((unsigned long)mask))); } static Xen gxm_XQueryKeymap(Xen arg1) { #define H_XQueryKeymap "XQueryKeymap(display): returns a bit vector for the logical state of the keyboard, where each bit \ set to 1 indicates that the corresponding key is currently pressed down." /* DIFF: XQueryKeymap omits keys -> (list val keys) */ char keys[32]; int val, i, loc; Xen lst = Xen_empty_list; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XQueryKeymap", "Display*"); val = XQueryKeymap(Xen_to_C_Display(arg1), keys); loc = xm_protect(lst); for (i = 31; i >= 0; i--) lst = Xen_cons(C_int_to_Xen_integer((int)keys[i]), lst); xm_unprotect_at(loc); return(Xen_cons(C_int_to_Xen_integer(val), lst)); } static Xen gxm_XQueryExtension(Xen arg1, Xen arg2) { #define H_XQueryExtension "Bool XQueryExtension(dpy, name) gets extension version information" /* DIFF: XQueryExtension dpy name [op er er] -> (list val op er er) */ int op, err1, err2, val; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XQueryExtension", "Display*"); Xen_check_type(Xen_is_string(arg2), arg2, 2, "XQueryExtension", "char*"); val = XQueryExtension(Xen_to_C_Display(arg1), (char *)Xen_string_to_C_string(arg2), &op, &err1, &err2); return(Xen_list_4(C_bool_to_Xen_boolean(val), C_int_to_Xen_integer(op), C_int_to_Xen_integer(err1), C_int_to_Xen_integer(err2))); } static Xen gxm_XQueryColors(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XQueryColors "XQueryColors(display, colormap, defs_in_out, ncolors)" int i, len, rtn; Xen lst; XColor *cols; XColor *col; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XQueryColors", "Display*"); Xen_check_type(Xen_is_Colormap(arg2), arg2, 2, "XQueryColors", "Colormap"); Xen_check_type(Xen_is_list(arg3), arg3, 3, "XQueryColors", "XColor list"); Xen_check_type(Xen_is_integer_or_unbound(arg4), arg4, 4, "XQueryColors", "int"); if (Xen_is_integer(arg4)) len = Xen_integer_to_C_int(arg4); else len = Xen_list_length(arg3); lst = Xen_copy_arg(arg3); cols = (XColor *)calloc(len, sizeof(XColor)); for (i = 0; (i < len) && (!Xen_is_null(lst)); i++, lst = Xen_cdr(lst)) { if (Xen_is_XColor(Xen_car(lst))) { col = Xen_to_C_XColor(Xen_car(lst)); cols[i].pixel = col->pixel; } else Xen_check_type(0, Xen_car(lst), i, __func__, "an XColor"); } rtn = XQueryColors(Xen_to_C_Display(arg1), Xen_to_C_Colormap(arg2), cols, len); for (i = 0; i < len; i++) { col = Xen_to_C_XColor(Xen_list_ref(arg3, i)); col->red = cols[i].red; col->green = cols[i].green; col->blue = cols[i].blue; col->flags = cols[i].flags; } free(cols); return(C_int_to_Xen_integer(rtn)); } static Xen gxm_XQueryColor(Xen arg1, Xen arg2, Xen arg3) { #define H_XQueryColor "XQueryColor(display, colormap, def_in_out): returns the current RGB value for the pixel in the XColor structure \ and sets the DoRed, DoGreen, DoBlue flags." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XQueryColor", "Display*"); Xen_check_type(Xen_is_Colormap(arg2), arg2, 2, "XQueryColor", "Colormap"); Xen_check_type(Xen_is_XColor(arg3), arg3, 3, "XQueryColor", "XColor*"); return(C_int_to_Xen_integer(XQueryColor(Xen_to_C_Display(arg1), Xen_to_C_Colormap(arg2), Xen_to_C_XColor(arg3)))); } static Xen gxm_XQueryBestTile(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XQueryBestTile "Status XQueryBestTile(display, which_screen, width, height) returns the best or \ closest size, that is, the size that can be tiled fastest on the screen specified by which_screen." /* DIFF: XQueryBestTile dpy scr wid hgt [wd hg] -> (list status wd hg) */ unsigned int w, h; int val; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XQueryBestTile", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XQueryBestTile", "Drawable"); Xen_check_type(Xen_is_ulong(arg3), arg3, 3, "XQueryBestTile", "unsigned int"); Xen_check_type(Xen_is_ulong(arg4), arg4, 4, "XQueryBestTile", "unsigned int"); val = XQueryBestTile(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_ulong_to_C_ulong(arg3), Xen_ulong_to_C_ulong(arg4), &w, &h); return(Xen_list_3(C_int_to_Xen_integer(val), C_ulong_to_Xen_ulong(w), C_ulong_to_Xen_ulong(h))); } static Xen gxm_XQueryBestStipple(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XQueryBestStipple "Status XQueryBestStipple(display, which_screen, width, height) returns the \ best or closest size, that is, the size that can be stippled fastest on the screen specified by which_screen." /* DIFF: XQueryBestStipple dpy scr wid hgt [wd hg] -> (list status wd hg) */ unsigned int w, h; int val; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XQueryBestStipple", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XQueryBestStipple", "Drawable"); Xen_check_type(Xen_is_ulong(arg3), arg3, 3, "XQueryBestStipple", "unsigned int"); Xen_check_type(Xen_is_ulong(arg4), arg4, 4, "XQueryBestStipple", "unsigned int"); val = XQueryBestStipple(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_ulong_to_C_ulong(arg3), Xen_ulong_to_C_ulong(arg4), &w, &h); return(Xen_list_3(C_int_to_Xen_integer(val), C_ulong_to_Xen_ulong(w), C_ulong_to_Xen_ulong(h))); } static Xen gxm_XQueryBestSize(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5) { #define H_XQueryBestSize "Status XQueryBestSize(display, class, which_screen, width, height) returns the \ best or closest size to the specified size." /* DIFF: XQueryBestSize dpy cls scr wid hgt [wd hg] -> (list status wd hg) */ unsigned int w, h; int val; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XQueryBestSize", "Display*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XQueryBestSize", "int"); Xen_check_type(Xen_is_Window(arg3), arg3, 3, "XQueryBestSize", "Drawable"); Xen_check_type(Xen_is_ulong(arg4), arg4, 4, "XQueryBestSize", "unsigned int"); Xen_check_type(Xen_is_ulong(arg5), arg5, 5, "XQueryBestSize", "unsigned int"); val = XQueryBestSize(Xen_to_C_Display(arg1), Xen_integer_to_C_int(arg2), Xen_to_C_Window(arg3), Xen_ulong_to_C_ulong(arg4), Xen_ulong_to_C_ulong(arg5), &w, &h); return(Xen_list_3(C_int_to_Xen_integer(val), C_ulong_to_Xen_ulong(w), C_ulong_to_Xen_ulong(h))); } static Xen gxm_XQueryBestCursor(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XQueryBestCursor "Status XQueryBestCursor(display, d, width, height) provides a way to find \ out what size cursors are actually possible on the display." /* DIFF: XQueryBestCursor dpy d wid hgt [wd hg] -> (list status wd hg) */ unsigned int w, h; int val; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XQueryBestCursor", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XQueryBestCursor", "Drawable"); Xen_check_type(Xen_is_ulong(arg3), arg3, 3, "XQueryBestCursor", "unsigned int"); Xen_check_type(Xen_is_ulong(arg4), arg4, 4, "XQueryBestCursor", "unsigned int"); val = XQueryBestCursor(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_ulong_to_C_ulong(arg3), Xen_ulong_to_C_ulong(arg4), &w, &h); return(Xen_list_3(C_int_to_Xen_integer(val), C_ulong_to_Xen_ulong(w), C_ulong_to_Xen_ulong(h))); } static Xen gxm_XQLength(Xen arg1) { #define H_QLength "returns the length of the event queue for the connected display." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XQLength", "Display*"); return(C_int_to_Xen_integer(XQLength(Xen_to_C_Display(arg1)))); } static Xen gxm_XPutImage(Xen args) { #define H_XPutImage "XPutImage(display, d, gc, image, src_x, src_y, dest_x, dest_y, width, height) combines an image with a rectangle \ of the specified drawable." Xen arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10; arg1 = Xen_list_ref(args, 0); arg2 = Xen_list_ref(args, 1); arg3 = Xen_list_ref(args, 2); arg4 = Xen_list_ref(args, 3); arg5 = Xen_list_ref(args, 4); arg6 = Xen_list_ref(args, 5); arg7 = Xen_list_ref(args, 6); arg8 = Xen_list_ref(args, 7); arg9 = Xen_list_ref(args, 8); arg10 = Xen_list_ref(args, 9); Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XPutImage", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XPutImage", "Drawable"); Xen_check_type(Xen_is_GC(arg3), arg3, 3, "XPutImage", "GC"); Xen_check_type(Xen_is_XImage(arg4), arg4, 4, "XPutImage", "XImage*"); Xen_check_type(Xen_is_integer(arg5), arg5, 5, "XPutImage", "int"); Xen_check_type(Xen_is_integer(arg6), arg6, 6, "XPutImage", "int"); Xen_check_type(Xen_is_integer(arg7), arg7, 7, "XPutImage", "int"); Xen_check_type(Xen_is_integer(arg8), arg8, 8, "XPutImage", "int"); Xen_check_type(Xen_is_ulong(arg9), arg9, 9, "XPutImage", "unsigned int"); Xen_check_type(Xen_is_ulong(arg10), arg10, 10, "XPutImage", "unsigned int"); return(C_int_to_Xen_integer(XPutImage(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_to_C_GC(arg3), Xen_to_C_XImage(arg4), Xen_integer_to_C_int(arg5), Xen_integer_to_C_int(arg6), Xen_integer_to_C_int(arg7), Xen_integer_to_C_int(arg8), Xen_ulong_to_C_ulong(arg9), Xen_ulong_to_C_ulong(arg10)))); } static Xen gxm_XPutBackEvent(Xen arg1, Xen arg2) { #define H_XPutBackEvent "XPutBackEvent(display, event) pushes an event back onto the head of the display's event queue by copying the event into the queue." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XPutBackEvent", "Display*"); Xen_check_type(Xen_is_XEvent(arg2), arg2, 2, "XPutBackEvent", "XEvent*"); return(C_int_to_Xen_integer(XPutBackEvent(Xen_to_C_Display(arg1), Xen_to_C_XEvent(arg2)))); } static Xen gxm_XProtocolVersion(Xen arg1) { #define H_ProtocolVersion "ProtocolVersion(display): returns the major version number (11) of the X protocol associated with the connected display." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XProtocolVersion", "Display*"); return(C_int_to_Xen_integer(XProtocolVersion(Xen_to_C_Display(arg1)))); } static Xen gxm_XProtocolRevision(Xen arg1) { #define H_ProtocolRevision "ProtocolRevision(display): returns the minor protocol revision number of the X server." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XProtocolRevision", "Display*"); return(C_int_to_Xen_integer(XProtocolRevision(Xen_to_C_Display(arg1)))); } static Xen gxm_XPlanesOfScreen(Xen arg1) { #define H_PlanesOfScreen "PlanesOfScreen(screen): returns the number of planes in the root window of the specified screen." Xen_check_type(Xen_is_Screen(arg1), arg1, 1, "XPlanesOfScreen", "Screen*"); return(C_int_to_Xen_integer(XPlanesOfScreen(Xen_to_C_Screen(arg1)))); } static Xen gxm_XPending(Xen arg1) { #define H_XPending "int XPending(display): returns the number of events that have been received from the X server but have not been removed \ from the event queue." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XPending", "Display*"); return(C_int_to_Xen_integer(XPending(Xen_to_C_Display(arg1)))); } static Xen xm_XPeekIfEventProc; static Bool gxm_XPeekIfEventProc(Display *dpy, XEvent *e, XtPointer p) { return(Xen_boolean_to_C_bool(Xen_call_with_3_args(xm_XPeekIfEventProc, C_to_Xen_Display(dpy), C_to_Xen_XEvent(e), (Xen)(p), __func__))); } static Xen gxm_XPeekIfEvent(Xen arg1, Xen arg2, Xen arg3) { #define H_XPeekIfEvent "XPeekIfEvent(display, predicate, arg): returns only when the specified predicate procedure returns " PROC_TRUE " for an event." /* DIFF: XPeekIfEvent dpy [evrtn] proc ptr -> (list val evrtn) */ XEvent *e; int val; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XPeekIfEvent", "Display*"); Xen_check_type(Xen_is_procedure(arg2) && (Xen_is_aritable(arg2, 3)), arg2, 2, "XPeekIfEvent", "(Bool_Proc dpy ev data)"); e = (XEvent *)calloc(1, sizeof(XEvent)); val = XPeekIfEvent(Xen_to_C_Display(arg1), e, (Bool (*)(Display *d, XEvent *ev, char *p))gxm_XPeekIfEventProc, /* C++ insists on the cast */ (XPointer)arg3); return(Xen_list_2(C_int_to_Xen_integer(val), C_to_Xen_XEvent_OBJ(e))); } static Xen gxm_XPeekEvent(Xen arg1) { #define H_XPeekEvent "XPeekEvent(display): returns the first event from the event queue, but it does not remove the event from the queue." /* DIFF: XPeekEvent dpy [ev] -> (list int event) */ XEvent *e; int val; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XPeekEvent", "Display*"); e = (XEvent *)calloc(1, sizeof(XEvent)); val = XPeekEvent(Xen_to_C_Display(arg1), e); return(Xen_list_2(C_int_to_Xen_integer(val), C_to_Xen_XEvent_OBJ(e))); } static Xen gxm_XParseGeometry(Xen arg1) { #define H_XParseGeometry "int XParseGeometry(parsestring): returns a bitmask that \ indicates which of the four values (width, height, xoffset, and yoffset) were actually found in the string and whether the x and y values are negative. " /* DIFF: XParseGeometry str [x y w h] -> (list bit x y w h) */ int x = 0, y = 0, val = 0; unsigned int w = 0, h = 0; Xen_check_type(Xen_is_string(arg1), arg1, 1, "XParseGeometry", "char*"); val = XParseGeometry((char *)Xen_string_to_C_string(arg1), &x, &y, &w, &h); return(Xen_list_5(C_int_to_Xen_integer(val), C_int_to_Xen_integer(x), C_int_to_Xen_integer(y), C_int_to_Xen_integer(w), C_int_to_Xen_integer(h))); } static Xen gxm_XParseColor(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XParseColor "Status XParseColor(display, colormap, spec, exact_def_return) looks up the string name of a color with respect \ to the screen associated with the specified colormap." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XParseColor", "Display*"); Xen_check_type(Xen_is_Colormap(arg2), arg2, 2, "XParseColor", "Colormap"); Xen_check_type(Xen_is_string(arg3), arg3, 3, "XParseColor", "char*"); Xen_check_type(Xen_is_XColor(arg4), arg4, 4, "XParseColor", "XColor"); return(C_int_to_Xen_integer(XParseColor(Xen_to_C_Display(arg1), Xen_to_C_Colormap(arg2), (char *)Xen_string_to_C_string(arg3), Xen_to_C_XColor(arg4)))); } static Xen gxm_XNoOp(Xen arg1) { #define H_XNoOp "XNoOp(dpy) sends the server a no-op for exercise" Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XNoOp", "Display*"); return(C_int_to_Xen_integer(XNoOp(Xen_to_C_Display(arg1)))); } static Xen gxm_XNextEvent(Xen arg1) { #define H_XNextEvent "XNextEvent(display) copies the first event from the event queue into the specified XEvent structure \ and then removes it from the queue." /* DIFF: XNextEvent dpy [ev] -> (list int event) */ XEvent *e; int val; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XNextEvent", "Display*"); e = (XEvent *)calloc(1, sizeof(XEvent)); val = XNextEvent(Xen_to_C_Display(arg1), e); return(Xen_list_2(C_int_to_Xen_integer(val), C_to_Xen_XEvent_OBJ(e))); } static Xen gxm_XMoveWindow(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XMoveWindow "XMoveWindow(display, w, x, y) moves the specified window to the specified x and y coordinates, but it does not \ change the window's size, raise the window, or change the mapping state of the window." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XMoveWindow", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XMoveWindow", "Window"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XMoveWindow", "int"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XMoveWindow", "int"); return(C_int_to_Xen_integer(XMoveWindow(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_integer_to_C_int(arg3), Xen_integer_to_C_int(arg4)))); } static Xen gxm_XMoveResizeWindow(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6) { #define H_XMoveResizeWindow "XMoveResizeWindow(display, w, x, y, width, height) changes the size and location of the specified window without raising it." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XMoveResizeWindow", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XMoveResizeWindow", "Window"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XMoveResizeWindow", "int"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XMoveResizeWindow", "int"); Xen_check_type(Xen_is_ulong(arg5), arg5, 5, "XMoveResizeWindow", "unsigned int"); Xen_check_type(Xen_is_ulong(arg6), arg6, 6, "XMoveResizeWindow", "unsigned int"); return(C_int_to_Xen_integer(XMoveResizeWindow(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_integer_to_C_int(arg3), Xen_integer_to_C_int(arg4), Xen_ulong_to_C_ulong(arg5), Xen_ulong_to_C_ulong(arg6)))); } static Xen gxm_XMinCmapsOfScreen(Xen arg1) { #define H_MinCmapsOfScreen "returns the minimum number of installed colormaps supported by the specified screen." Xen_check_type(Xen_is_Screen(arg1), arg1, 1, "XMinCmapsOfScreen", "Screen*"); return(C_int_to_Xen_integer(XMinCmapsOfScreen(Xen_to_C_Screen(arg1)))); } static Xen gxm_XMaxCmapsOfScreen(Xen arg1) { #define H_MaxCmapsOfScreen "returns the maximum number of installed colormaps supported by the specified screen." Xen_check_type(Xen_is_Screen(arg1), arg1, 1, "XMaxCmapsOfScreen", "Screen*"); return(C_int_to_Xen_integer(XMaxCmapsOfScreen(Xen_to_C_Screen(arg1)))); } static Xen gxm_XMaskEvent(Xen arg1, Xen arg2) { #define H_XMaskEvent "XMaskEvent(display, event_mask) searches the event queue for the events associated with the specified mask." /* DIFF: XMaskEvent dpy mask [ev] -> (list val ev) */ XEvent *e; int val; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XMaskEvent", "Display*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XMaskEvent", "long"); e = (XEvent *)calloc(1, sizeof(XEvent)); val = XMaskEvent(Xen_to_C_Display(arg1), Xen_integer_to_C_int(arg2), e); return(Xen_list_2(C_int_to_Xen_integer(val), C_to_Xen_XEvent_OBJ(e))); } static Xen gxm_XMapWindow(Xen arg1, Xen arg2) { #define H_XMapWindow "XMapWindow(display, w) maps the window and all of its subwindows that have had map requests." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XMapWindow", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XMapWindow", "Window"); return(C_int_to_Xen_integer(XMapWindow(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2)))); } static Xen gxm_XMapSubwindows(Xen arg1, Xen arg2) { #define H_XMapSubwindows "XMapSubwindows(display, w) maps all subwindows for a specified window in top-to-bottom stacking order." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XMapSubwindows", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XMapSubwindows", "Window"); return(C_int_to_Xen_integer(XMapSubwindows(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2)))); } static Xen gxm_XMapRaised(Xen arg1, Xen arg2) { #define H_XMapRaised "XMapRaised(display, w) maps the window and all of its subwindows that have had map requests, and raises the \ specified window to the top of the stack." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XMapRaised", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XMapRaised", "Window"); return(C_int_to_Xen_integer(XMapRaised(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2)))); } static Xen gxm_XLowerWindow(Xen arg1, Xen arg2) { #define H_XLowerWindow "XLowerWindow(display, w) lowers the specified window to the bottom of the stack so that it does not obscure any sibling windows." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XLowerWindow", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XLowerWindow", "Window"); return(C_int_to_Xen_integer(XLowerWindow(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2)))); } static Xen gxm_XLookupColor(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5) { #define H_XLookupColor "Status XLookupColor(display, colormap, color_name, exact_def_return, screen_def_return) looks up the string name \ of a color with respect to the screen associated with the specified colormap." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XLookupColor", "Display*"); Xen_check_type(Xen_is_Colormap(arg2), arg2, 2, "XLookupColor", "Colormap"); Xen_check_type(Xen_is_string(arg3), arg3, 3, "XLookupColor", "char*"); Xen_check_type(Xen_is_XColor(arg4), arg4, 4, "XLookupColor", "XColor*"); Xen_check_type(Xen_is_XColor(arg5), arg5, 5, "XLookupColor", "XColor*"); return(C_int_to_Xen_integer(XLookupColor(Xen_to_C_Display(arg1), Xen_to_C_Colormap(arg2), (char *)Xen_string_to_C_string(arg3), Xen_to_C_XColor(arg4), Xen_to_C_XColor(arg5)))); } static Xen gxm_XKillClient(Xen arg1, Xen arg2) { #define H_XKillClient "XKillClient(display, resource) forces a close-down of the client that created the resource" Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XKillClient", "Display*"); Xen_check_type(Xen_is_ulong(arg2), arg2, 2, "XKillClient", "XID"); return(C_int_to_Xen_integer(XKillClient(Xen_to_C_Display(arg1), Xen_ulong_to_C_ulong(arg2)))); } static Xen gxm_XKeysymToKeycode(Xen arg1, Xen arg2) { #define H_XKeysymToKeycode "KeyCode XKeysymToKeycode(display, keysym)" Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XKeysymToKeycode", "Display*"); Xen_check_type(Xen_is_KeySym(arg2), arg2, 2, "XKeysymToKeycode", "KeySym"); return(C_to_Xen_KeyCode(XKeysymToKeycode(Xen_to_C_Display(arg1), Xen_to_C_KeySym(arg2)))); } static Xen gxm_XInstallColormap(Xen arg1, Xen arg2) { #define H_XInstallColormap "XInstallColormap(display, colormap) installs the specified colormap for its associated screen." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XInstallColormap", "Display*"); Xen_check_type(Xen_is_Colormap(arg2), arg2, 2, "XInstallColormap", "Colormap"); return(C_int_to_Xen_integer(XInstallColormap(Xen_to_C_Display(arg1), Xen_to_C_Colormap(arg2)))); } static Xen gxm_XImageByteOrder(Xen arg1) { #define H_ImageByteOrder "specifies the required byte order for images for each scanline unit in XY format (bitmap) or for each pixel value in Z format." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XImageByteOrder", "Display*"); return(C_int_to_Xen_integer(XImageByteOrder(Xen_to_C_Display(arg1)))); } static Xen gxm_XIfEvent(Xen arg1, Xen arg2, Xen arg3) { #define H_XIfEvent "XIfEvent(display, predicate, arg) completes only when the specified predicate procedure returns " PROC_TRUE " for \ an event, which indicates an event in the queue matches." /* DIFF: XIfEvent dpy [ev] proc ptr -> (list val ev) */ XEvent *e; int val; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XIfEvent", "Display*"); Xen_check_type(Xen_is_procedure(arg2) && (Xen_is_aritable(arg2, 3)), arg2, 2, "XIfEvent", "(Bool_Proc dpy ev data)"); e = (XEvent *)calloc(1, sizeof(XEvent)); val = XIfEvent(Xen_to_C_Display(arg1), e, (Bool (*)(Display *d1, XEvent *e1, char *p1))gxm_XPeekIfEventProc, (char *)arg3); return(Xen_list_2(C_int_to_Xen_integer(val), C_to_Xen_XEvent_OBJ(e))); } static Xen gxm_XHeightOfScreen(Xen arg1) { #define H_HeightOfScreen "XHeightOfScreen(screen): returns the height of the specified screen." Xen_check_type(Xen_is_Screen(arg1), arg1, 1, "XHeightOfScreen", "Screen*"); return(C_int_to_Xen_integer(XHeightOfScreen(Xen_to_C_Screen(arg1)))); } static Xen gxm_XHeightMMOfScreen(Xen arg1) { #define H_HeightMMOfScreen "XHeightMMOfScreen(screen): returns the height of the specified screen in millimeters." Xen_check_type(Xen_is_Screen(arg1), arg1, 1, "XHeightMMOfScreen", "Screen*"); return(C_int_to_Xen_integer(XHeightMMOfScreen(Xen_to_C_Screen(arg1)))); } static Xen gxm_XGrabServer(Xen arg1) { #define H_XGrabServer "XGrabServer(display) disables processing of requests and close downs on all other connections than the one this request arrived on." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XGrabServer", "Display*"); return(C_int_to_Xen_integer(XGrabServer(Xen_to_C_Display(arg1)))); } static Xen gxm_XGrabPointer(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6, Xen arg7, Xen arg8, Xen arg9) { #define H_XGrabPointer "int XGrabPointer(display, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor, time) \ actively grabs control of the pointer and returns GrabSuccess if the grab was successful." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XGrabPointer", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XGrabPointer", "Window"); Xen_check_type(Xen_is_boolean(arg3), arg3, 3, "XGrabPointer", "Bool"); Xen_check_type(Xen_is_ulong(arg4), arg4, 4, "XGrabPointer", "unsigned int"); Xen_check_type(Xen_is_integer(arg5), arg5, 5, "XGrabPointer", "int"); Xen_check_type(Xen_is_integer(arg6), arg6, 6, "XGrabPointer", "int"); Xen_check_type(Xen_is_Window(arg7), arg7, 7, "XGrabPointer", "Window"); Xen_check_type(Xen_is_Cursor(arg8), arg8, 8, "XGrabPointer", "Cursor"); Xen_check_type(Xen_is_Time(arg9), arg9, 9, "XGrabPointer", "Time"); return(C_int_to_Xen_integer(XGrabPointer(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_boolean_to_C_bool(arg3), Xen_ulong_to_C_ulong(arg4), Xen_integer_to_C_int(arg5), Xen_integer_to_C_int(arg6), Xen_to_C_Window(arg7), Xen_to_C_Cursor(arg8), Xen_to_C_Time(arg9)))); } static Xen gxm_XGrabKeyboard(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6) { #define H_XGrabKeyboard "int XGrabKeyboard(display, grab_window, owner_events, pointer_mode, keyboard_mode, time) actively grabs control of \ the keyboard and generates FocusIn and FocusOut events." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XGrabKeyboard", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XGrabKeyboard", "Window"); Xen_check_type(Xen_is_boolean(arg3), arg3, 3, "XGrabKeyboard", "Bool"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XGrabKeyboard", "int"); Xen_check_type(Xen_is_integer(arg5), arg5, 5, "XGrabKeyboard", "int"); Xen_check_type(Xen_is_Time(arg6), arg6, 6, "XGrabKeyboard", "Time"); return(C_int_to_Xen_integer(XGrabKeyboard(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_boolean_to_C_bool(arg3), Xen_integer_to_C_int(arg4), Xen_integer_to_C_int(arg5), Xen_to_C_Time(arg6)))); } static Xen gxm_XGrabKey(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6, Xen arg7) { #define H_XGrabKey "XGrabKey(display, keycode, modifiers, grab_window, owner_events, pointer_mode, keyboard_mode) establishes a passive \ grab on the keyboard." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XGrabKey", "Display*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XGrabKey", "int"); Xen_check_type(Xen_is_ulong(arg3), arg3, 3, "XGrabKey", "unsigned int"); Xen_check_type(Xen_is_Window(arg4), arg4, 4, "XGrabKey", "Window"); Xen_check_type(Xen_is_boolean(arg5), arg5, 5, "XGrabKey", "Bool"); Xen_check_type(Xen_is_integer(arg6), arg6, 6, "XGrabKey", "int"); Xen_check_type(Xen_is_integer(arg7), arg7, 7, "XGrabKey", "int"); return(C_int_to_Xen_integer(XGrabKey(Xen_to_C_Display(arg1), Xen_integer_to_C_int(arg2), Xen_ulong_to_C_ulong(arg3), Xen_to_C_Window(arg4), Xen_boolean_to_C_bool(arg5), Xen_integer_to_C_int(arg6), Xen_integer_to_C_int(arg7)))); } static Xen gxm_XGrabButton(Xen args) { #define H_XGrabButton "XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor) \ establishes a passive grab." Xen arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10; arg1 = Xen_list_ref(args, 0); arg2 = Xen_list_ref(args, 1); arg3 = Xen_list_ref(args, 2); arg4 = Xen_list_ref(args, 3); arg5 = Xen_list_ref(args, 4); arg6 = Xen_list_ref(args, 5); arg7 = Xen_list_ref(args, 6); arg8 = Xen_list_ref(args, 7); arg9 = Xen_list_ref(args, 8); arg10 = Xen_list_ref(args, 9); Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XGrabButton", "Display*"); Xen_check_type(Xen_is_ulong(arg2), arg2, 2, "XGrabButton", "unsigned int"); Xen_check_type(Xen_is_ulong(arg3), arg3, 3, "XGrabButton", "unsigned int"); Xen_check_type(Xen_is_Window(arg4), arg4, 4, "XGrabButton", "Window"); Xen_check_type(Xen_is_boolean(arg5), arg5, 5, "XGrabButton", "Bool"); Xen_check_type(Xen_is_ulong(arg6), arg6, 6, "XGrabButton", "unsigned int"); Xen_check_type(Xen_is_integer(arg7), arg7, 7, "XGrabButton", "int"); Xen_check_type(Xen_is_integer(arg8), arg8, 8, "XGrabButton", "int"); Xen_check_type(Xen_is_Window(arg9), arg9, 9, "XGrabButton", "Window"); Xen_check_type(Xen_is_Cursor(arg10), arg10, 10, "XGrabButton", "Cursor"); return(C_int_to_Xen_integer(XGrabButton(Xen_to_C_Display(arg1), Xen_ulong_to_C_ulong(arg2), Xen_ulong_to_C_ulong(arg3), Xen_to_C_Window(arg4), Xen_boolean_to_C_bool(arg5), Xen_ulong_to_C_ulong(arg6), Xen_integer_to_C_int(arg7), Xen_integer_to_C_int(arg8), Xen_to_C_Window(arg9), Xen_to_C_Cursor(arg10)))); } static Xen gxm_XGetWindowAttributes(Xen arg1, Xen arg2) { #define H_XGetWindowAttributes "Status XGetWindowAttributes(display, w): returns the current attributes for the \ specified window to an XWindowAttributes structure." /* DIFF: XGetWindowAttributes omits and rtns arg3 */ XWindowAttributes *w; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XGetWindowAttributes", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XGetWindowAttributes", "Window"); w = (XWindowAttributes *)calloc(1, sizeof(XWindowAttributes)); XGetWindowAttributes(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), w); return(C_to_Xen_XWindowAttributes(w)); } static Xen gxm_XGetWindowProperty(Xen args) { #define H_XGetWindowProperty "int XGetWindowProperty(display, w, property, long_offset, long_length, delete, req_type) \ returns the actual type of the property; the actual format of the property; the \ number of 8-bit, 16-bit, or 32-bit items transferred; the number of bytes remaining to be read in the property; and a pointer to the data \ actually returned." /* DIFF: XGetWindowProperty omit trailing 5 args, rtn as list */ Xen arg1, arg2, arg3, arg4, arg5, arg6, arg7; Xen result = Xen_false; Atom a; int ret, val; unsigned long len = 0, bytes; unsigned char *data[1]; arg1 = Xen_list_ref(args, 0); arg2 = Xen_list_ref(args, 1); arg3 = Xen_list_ref(args, 2); arg4 = Xen_list_ref(args, 3); arg5 = Xen_list_ref(args, 4); arg6 = Xen_list_ref(args, 5); arg7 = Xen_list_ref(args, 6); Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XGetWindowProperty", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XGetWindowProperty", "Window"); Xen_check_type(Xen_is_Atom(arg3), arg3, 3, "XGetWindowProperty", "Atom"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XGetWindowProperty", "long"); Xen_check_type(Xen_is_integer(arg5), arg5, 5, "XGetWindowProperty", "long"); Xen_check_type(Xen_is_boolean(arg6), arg6, 6, "XGetWindowProperty", "Bool"); Xen_check_type(Xen_is_Atom(arg7), arg7, 7, "XGetWindowProperty", "Atom"); val = XGetWindowProperty(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_to_C_Atom(arg3), Xen_integer_to_C_int(arg4), Xen_integer_to_C_int(arg5), Xen_boolean_to_C_bool(arg6), Xen_to_C_Atom(arg7), &a, &ret, &len, &bytes, (unsigned char **)data); if ((a != (Atom)None) && (len > 0)) { if (a == XA_STRING) result = C_string_to_Xen_string((char *)data[0]); else result = C_string_to_Xen_string_with_length((char *)data[0], len * ret / 8); /* is this a good idea? -- perhaps a void pointer here? */ if (data[0]) XFree(data[0]); } return(Xen_list_6(C_int_to_Xen_integer(val), C_to_Xen_Atom(a), C_int_to_Xen_integer(ret), C_ulong_to_Xen_ulong(len), C_ulong_to_Xen_ulong(bytes), result)); } static Xen gxm_XGetTransientForHint(Xen arg1, Xen arg2) { #define H_XGetTransientForHint "Status XGetTransientForHint(display, w): returns the WM_TRANSIENT_FOR property for the specified window." /* DIFF: XGetTransientForHint omit and rtn last arg */ Window w; int val; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XGetTransientForHint", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XGetTransientForHint", "Window"); val = XGetTransientForHint(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), &w); return(Xen_list_2(C_int_to_Xen_integer(val), C_to_Xen_Window(w))); } static Xen gxm_XGetScreenSaver(Xen arg1) { #define H_XGetScreenSaver "XGetScreenSaver(display) gets the current screen saver values." /* DIFF: XGetScreenSaver omit and rtn last 4 args */ int a, b, c ,d, val; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XGetScreenSaver", "Display*"); val = XGetScreenSaver(Xen_to_C_Display(arg1), &a, &b, &c, &d); return(Xen_list_5(C_int_to_Xen_integer(val), C_int_to_Xen_integer(a), C_int_to_Xen_integer(b), C_int_to_Xen_integer(c), C_int_to_Xen_integer(d))); } static Xen gxm_XGetPointerMapping(Xen arg1, Xen ignore, Xen arg3) { #define H_XGetPointerMapping "int XGetPointerMapping(display, ignored, len): returns the current mapping of the pointer." /* DIFF: XGetPointerMapping ignores arg2, returns list * (XGetPointerMapping (XtDisplay (cadr (main-widgets))) 0 3) */ int i, len, loc, rtn; unsigned char *map; Xen lst = Xen_empty_list; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XGetPointerMapping", "Display*"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XGetPointerMapping", "int"); len = Xen_integer_to_C_int(arg3); if (len <= 0) Xen_check_type(0, arg3, 3, "XGetPointerMapping", "positive integer"); map = (unsigned char *)calloc(len, sizeof(unsigned char)); rtn = XGetPointerMapping(Xen_to_C_Display(arg1), map, len); if (len > rtn) len = rtn; loc = xm_protect(lst); for (i = len - 1; i >= 0; i--) lst = Xen_cons(C_int_to_Xen_integer((int)(map[i])), lst); free(map); xm_unprotect_at(loc); return(lst); } static Xen gxm_XGetPointerControl(Xen arg1) { #define H_XGetPointerControl "XGetPointerControl(display) \ returns the pointer's current acceleration multiplier and acceleration threshold." /* DIFF: XGetPointerControl omits and return last 3 args */ int val, num, den, thresh; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XGetPointerControl", "Display*"); val = XGetPointerControl(Xen_to_C_Display(arg1), &num, &den, &thresh); return(Xen_list_4(C_int_to_Xen_integer(val), C_int_to_Xen_integer(num), C_int_to_Xen_integer(den), C_int_to_Xen_integer(thresh))); } static Xen gxm_XGetKeyboardControl(Xen arg1) { #define H_XGetKeyboardControl "XGetKeyboardControl(display): returns the current control values for the keyboard \ to the XKeyboardState structure." /* DIFF: XGetKeyboardControl omits arg2 and rtns list of fields */ XKeyboardState ks; Xen v; int i, loc; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XGetKeyboardControl", "Display*"); XGetKeyboardControl(Xen_to_C_Display(arg1), &ks); v = Xen_make_vector(32, Xen_integer_zero); loc = xm_protect(v); for (i = 0; i < 32; i++) Xen_vector_set(v, i, C_int_to_Xen_integer((int)(ks.auto_repeats[i]))); xm_unprotect_at(loc); return(Xen_list_7(C_int_to_Xen_integer(ks.key_click_percent), C_int_to_Xen_integer(ks.bell_percent), C_int_to_Xen_integer(ks.bell_pitch), C_int_to_Xen_integer(ks.bell_duration), C_int_to_Xen_integer(ks.led_mask), C_int_to_Xen_integer(ks.global_auto_repeat), v)); } static Xen gxm_XGetInputFocus(Xen arg1) { #define H_XGetInputFocus "XGetInputFocus(display): returns the focus window and the current focus state." /* DIFF: XGetInputFocus omit and rtn last 2 args */ Window w; int r, val; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XGetInputFocus", "Display*"); val = XGetInputFocus(Xen_to_C_Display(arg1), &w, &r); return(Xen_list_3(C_int_to_Xen_integer(val), C_to_Xen_Window(w), C_int_to_Xen_integer(r))); } static Xen gxm_XGetIconName(Xen arg1, Xen arg2) { #define H_XGetIconName "Status XGetIconName(display, w): returns the name to be displayed in the specified window's icon." /* DIFF: XGetIconName omits and returns arg3 */ char *str; int val; Xen res = Xen_false; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XGetIconName", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XGetIconName", "Window"); val = XGetIconName(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), &str); if (val != 0) { res = C_string_to_Xen_string(str); XFree(str); } return(res); } static Xen gxm_XGetGeometry(Xen arg1, Xen arg2) { #define H_XGetGeometry "Status XGetGeometry(display, d): returns the root window and the current geometry of the drawable." /* DIFF: XGetGeometry omits last 7 args and returns list */ unsigned int wr, hr, br, dr; int xr, yr, val; Window root; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XGetGeometry", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XGetGeometry", "Drawable"); val = XGetGeometry(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), &root, &xr, &yr, &wr, &hr, &br, &dr); return(Xen_list_8(C_int_to_Xen_integer(val), C_to_Xen_Window(root), C_int_to_Xen_integer(xr), C_int_to_Xen_integer(yr), C_ulong_to_Xen_ulong(wr), C_ulong_to_Xen_ulong(hr), C_ulong_to_Xen_ulong(br), C_ulong_to_Xen_ulong(dr))); } static Xen gxm_XGetGCValues(Xen arg1, Xen arg2, Xen arg3) { #define H_XGetGCValues "Status XGetGCValues(display, gc, valuemask): returns the components specified by valuemask for the specified GC." /* DIFF: XGetGCValues omits and returns last arg */ XGCValues *val; int rtn; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XGetGCValues", "Display*"); Xen_check_type(Xen_is_GC(arg2), arg2, 2, "XGetGCValues", "GC"); Xen_check_type(Xen_is_ulong(arg3), arg3, 3, "XGetGCValues", "ulong"); val = (XGCValues *)calloc(1, sizeof(XGCValues)); rtn = XGetGCValues(Xen_to_C_Display(arg1), Xen_to_C_GC(arg2), Xen_ulong_to_C_ulong(arg3), val); return(Xen_list_2(C_int_to_Xen_integer(rtn), C_to_Xen_XGCValues(val))); } static Xen gxm_XGetFontProperty(Xen arg1, Xen arg2) { #define H_XGetFontProperty "Bool XGetFontProperty(font_struct, atom): returns the value of the specified font property. " /* DIFF: XGetFontProperty omits and rtns last arg */ Bool val = False; unsigned long prop = 0; Xen_check_type(Xen_is_XFontStruct(arg1), arg1, 1, "XGetFontProperty", "XFontStruct*"); Xen_check_type(Xen_is_Atom(arg2), arg2, 2, "XGetFontProperty", "Atom"); val = XGetFontProperty(Xen_to_C_XFontStruct(arg1), Xen_to_C_Atom(arg2), &prop); return(Xen_list_2(C_bool_to_Xen_boolean(val), C_ulong_to_Xen_ulong(prop))); } static Xen gxm_XGetErrorText(Xen arg1, Xen arg2, Xen ignore, Xen arg4) { #define H_XGetErrorText "XGetErrorText(display, code, buffer_return, length) copies a null-terminated string describing the specified error \ code into the specified buffer." /* DIFF: XGetErrorText ignores arg3, returns text */ char *buf; int len, val; Xen str; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XGetErrorText", "Display*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XGetErrorText", "int"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XGetErrorText", "int"); len = Xen_integer_to_C_int(arg4); if (len <= 0) Xen_check_type(0, arg4, 4, "XGetErrorText", "positive integer"); buf = (char *)calloc(len, sizeof(char)); val = XGetErrorText(Xen_to_C_Display(arg1), Xen_integer_to_C_int(arg2), buf, len); str = C_string_to_Xen_string(buf); free(buf); return(Xen_list_2(C_int_to_Xen_integer(val), str)); } static Xen gxm_XGeometry(Xen args) { #define H_XGeometry "int XGeometry(dpy, screen, position, default_position, bwidth, fwidth, fheight, xadder, yadder) calculates \ window geometry given user geometry string and default geometry" /* DIFF: XGetGeometry omits trailing 4 args and returns them */ int x, y, w, h, val; Xen arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9; arg1 = Xen_list_ref(args, 0); arg2 = Xen_list_ref(args, 1); arg3 = Xen_list_ref(args, 2); arg4 = Xen_list_ref(args, 3); arg5 = Xen_list_ref(args, 4); arg6 = Xen_list_ref(args, 5); arg7 = Xen_list_ref(args, 6); arg8 = Xen_list_ref(args, 7); arg9 = Xen_list_ref(args, 8); Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XGeometry", "Display*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XGeometry", "int"); Xen_check_type(Xen_is_string(arg3), arg3, 3, "XGeometry", "char*"); Xen_check_type(Xen_is_string(arg4), arg4, 4, "XGeometry", "char*"); Xen_check_type(Xen_is_ulong(arg5), arg5, 5, "XGeometry", "unsigned int"); Xen_check_type(Xen_is_ulong(arg6), arg6, 6, "XGeometry", "unsigned int"); Xen_check_type(Xen_is_ulong(arg7), arg7, 7, "XGeometry", "unsigned int"); Xen_check_type(Xen_is_integer(arg8), arg8, 8, "XGeometry", "int"); Xen_check_type(Xen_is_integer(arg9), arg9, 9, "XGeometry", "int"); val = XGeometry(Xen_to_C_Display(arg1), Xen_integer_to_C_int(arg2), (char *)Xen_string_to_C_string(arg3), (char *)Xen_string_to_C_string(arg4), Xen_ulong_to_C_ulong(arg5), Xen_ulong_to_C_ulong(arg6), Xen_ulong_to_C_ulong(arg7), Xen_integer_to_C_int(arg8), Xen_integer_to_C_int(arg9), &x, &y, &w, &h); return(Xen_list_5(C_int_to_Xen_integer(val), C_int_to_Xen_integer(x), C_int_to_Xen_integer(y), C_int_to_Xen_integer(w), C_int_to_Xen_integer(h))); } static Xen gxm_XFreePixmap(Xen arg1, Xen arg2) { #define H_XFreePixmap "XFreePixmap(display, pixmap) first deletes the association between the pixmap ID and the pixmap." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XFreePixmap", "Display*"); Xen_check_type(Xen_is_Pixmap(arg2), arg2, 2, "XFreePixmap", "Pixmap"); return(C_int_to_Xen_integer(XFreePixmap(Xen_to_C_Display(arg1), Xen_to_C_Pixmap(arg2)))); } static Xen gxm_XFreeModifiermap(Xen arg1) { #define H_XFreeModifiermap "XFreeModifiermap(modmap) frees the specified XModifierKeymap structure." Xen_check_type(Xen_is_XModifierKeymap(arg1), arg1, 1, "XFreeModifiermap", "XModifierKeymap*"); return(C_int_to_Xen_integer(XFreeModifiermap(Xen_to_C_XModifierKeymap(arg1)))); } static Xen gxm_XFreeGC(Xen arg1, Xen arg2) { #define H_XFreeGC "XFreeGC(display, gc) destroys the specified GC as well as all the associated storage." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XFreeGC", "Display*"); Xen_check_type(Xen_is_GC(arg2), arg2, 2, "XFreeGC", "GC"); return(C_int_to_Xen_integer(XFreeGC(Xen_to_C_Display(arg1), Xen_to_C_GC(arg2)))); } static Xen gxm_XFreeFontPath(Xen ignore) { #define H_XFreeFontPath "XFreeFontPath(list) frees the data allocated by XGetFontPath (a no-op in xm)." /* DIFF: XFreeFontPath is no-op */ return(Xen_false); } static Xen gxm_XFreeFontNames(Xen ignore) { #define H_XFreeFontNames "XFreeFontNames(list) frees the array and strings returned by XListFonts or XListFontsWithInfo (a no-op in xm)." /* DIFF: XFreeFontNames is no-op */ return(Xen_false); } static Xen gxm_XFreeFontInfo(Xen ignore1, Xen ignore2, Xen ignore3) { #define H_XFreeFontInfo "XFreeFontInfo(names, free_info, actual_count) frees a font structure or an array of font structures, and \ optionally an array of font names (a no-op in xm)." /* DIFF: XFreeFontInfo is a no-op */ return(Xen_false); } static Xen gxm_XFreeFont(Xen arg1, Xen arg2) { #define H_XFreeFont "XFreeFont(display, font_struct) deletes the association between the font resource ID and the specified font and \ frees the XFontStruct structure." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XFreeFont", "Display*"); Xen_check_type(Xen_is_XFontStruct(arg2), arg2, 2, "XFreeFont", "XFontStruct*"); return(C_int_to_Xen_integer(XFreeFont(Xen_to_C_Display(arg1), Xen_to_C_XFontStruct(arg2)))); } static Xen gxm_XFreeExtensionList(Xen ignore) { /* DIFF: XFreeExtensionList is a no-op */ return(Xen_false); } static Xen gxm_XFreeCursor(Xen arg1, Xen arg2) { #define H_XFreeCursor "XFreeCursor(display, cursor) deletes the association between the cursor resource ID and the specified cursor." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XFreeCursor", "Display*"); Xen_check_type(Xen_is_Cursor(arg2), arg2, 2, "XFreeCursor", "Cursor"); return(C_int_to_Xen_integer(XFreeCursor(Xen_to_C_Display(arg1), Xen_to_C_Cursor(arg2)))); } static Xen gxm_XFreeColors(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5) { #define H_XFreeColors "XFreeColors(display, colormap, pixels, npixels, planes) frees the cells represented by pixels whose values are in the pixels array." /* DIFF: XFreeColors pixel array (arg3) is list of pixels */ unsigned long *ps; int len, val; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XFreeColors", "Display*"); Xen_check_type(Xen_is_Colormap(arg2), arg2, 2, "XFreeColors", "Colormap"); Xen_check_type(Xen_is_list(arg3), arg3, 3, "XFreeColors", "list of pixel"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XFreeColors", "int"); Xen_check_type(Xen_is_ulong(arg5), arg5, 5, "XFreeColors", "ulong"); len = Xen_integer_to_C_int(arg4); if (len <= 0) return(Xen_false); ps = Xen_to_C_Pixels(arg3, len); val = XFreeColors(Xen_to_C_Display(arg1), Xen_to_C_Colormap(arg2), ps, len, Xen_ulong_to_C_ulong(arg5)); free(ps); return(C_int_to_Xen_integer(val)); } static Xen gxm_XFreeColormap(Xen arg1, Xen arg2) { #define H_XFreeColormap "XFreeColormap(display, colormap) deletes the association between the colormap resource ID and the colormap and \ frees the colormap storage." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XFreeColormap", "Display*"); Xen_check_type(Xen_is_Colormap(arg2), arg2, 2, "XFreeColormap", "Colormap"); return(C_int_to_Xen_integer(XFreeColormap(Xen_to_C_Display(arg1), Xen_to_C_Colormap(arg2)))); } static Xen gxm_XFree(Xen arg1) { #define H_XFree "XFree(data) is a general-purpose Xlib routine that frees the specified data." Xen_check_type(Xen_is_wrapped_c_pointer(arg1) || Xen_is_list(arg1), arg1, 1, "XFree", "void* or xm entity"); if (Xen_is_list(arg1)) XFree((void *)Xen_unwrap_C_pointer(Xen_cadr(arg1))); else XFree((void *)Xen_unwrap_C_pointer(arg1)); return(Xen_false); } static Xen gxm_XForceScreenSaver(Xen arg1, Xen arg2) { #define H_XForceScreenSaver "XForceScreenSaver(display, mode) activates the screen saver" Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XForceScreenSaver", "Display*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XForceScreenSaver", "int"); return(C_int_to_Xen_integer(XForceScreenSaver(Xen_to_C_Display(arg1), Xen_integer_to_C_int(arg2)))); } static Xen gxm_XFlush(Xen arg1) { #define H_XFlush "XFlush(display) flushes the output buffer." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XFlush", "Display*"); return(C_int_to_Xen_integer(XFlush(Xen_to_C_Display(arg1)))); } static Xen gxm_XFillRectangles(Xen arg1, Xen arg2, Xen arg3, Xen larg4, Xen arg5) { #define H_XFillRectangles "XFillRectangles(display, d, gc, rectangles, nrectangles)" /* DIFF: XFillRectangles XRectangle* arg (arg 4) is list of XRectangles */ XRectangle *pt; int i, len; Xen arg4; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XFillRectangles", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XFillRectangles", "Drawable"); Xen_check_type(Xen_is_GC(arg3), arg3, 3, "XFillRectangles", "GC"); Xen_check_type(Xen_is_list(larg4), larg4, 4, "XFillRectangles", "list of XRectangle"); Xen_check_type(Xen_is_integer(arg5), arg5, 5, "XFillRectangles", "int"); arg4 = Xen_copy_arg(larg4); len = Xen_integer_to_C_int(arg5); if (len <= 0) Xen_check_type(0, arg5, 5, "XFillRectangles", "positive integer"); pt = (XRectangle *)calloc(len, sizeof(XRectangle)); for (i = 0; (i < len) && (!Xen_is_null(arg4)); i++, arg4 = Xen_cdr(arg4)) { XRectangle *pt1; pt1 = Xen_to_C_XRectangle(Xen_car(arg4)); pt[i].x = pt1->x; pt[i].y = pt1->y; pt[i].width = pt1->width; pt[i].height = pt1->height; } XFillRectangles(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_to_C_GC(arg3), pt, len); free(pt); return(C_int_to_Xen_integer(len)); } static Xen gxm_XFillRectangle(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6, Xen arg7) { #define H_XFillRectangle "XFillRectangle(display, d, gc, x, y, width, height)" Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XFillRectangle", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XFillRectangle", "Drawable"); Xen_check_type(Xen_is_GC(arg3), arg3, 3, "XFillRectangle", "GC"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XFillRectangle", "int"); Xen_check_type(Xen_is_integer(arg5), arg5, 5, "XFillRectangle", "int"); Xen_check_type(Xen_is_ulong(arg6), arg6, 6, "XFillRectangle", "unsigned int"); Xen_check_type(Xen_is_ulong(arg7), arg7, 7, "XFillRectangle", "unsigned int"); return(C_int_to_Xen_integer(XFillRectangle(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_to_C_GC(arg3), Xen_integer_to_C_int(arg4), Xen_integer_to_C_int(arg5), Xen_ulong_to_C_ulong(arg6), Xen_ulong_to_C_ulong(arg7)))); } static Xen gxm_XFillPolygon(Xen arg1, Xen arg2, Xen arg3, Xen larg4, Xen arg5, Xen arg6, Xen arg7) { #define H_XFillPolygon "XFillPolygon(display, d, gc, points, npoints, shape, mode)" /* DIFF: XFillPolygon Point* arg (arg 4) is list of XPoint */ XPoint *pt, *pt1; int i, len; Xen arg4; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XFillPolygon", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XFillPolygon", "Drawable"); Xen_check_type(Xen_is_GC(arg3), arg3, 3, "XFillPolygon", "GC"); Xen_check_type(Xen_is_list(larg4), larg4, 4, "XFillPolygon", "list of XPoints"); Xen_check_type(Xen_is_integer(arg5), arg5, 5, "XFillPolygon", "int"); Xen_check_type(Xen_is_integer(arg6), arg6, 6, "XFillPolygon", "int"); Xen_check_type(Xen_is_integer(arg7), arg7, 7, "XFillPolygon", "int"); arg4 = Xen_copy_arg(larg4); len = Xen_integer_to_C_int(arg5); if (len <= 0) Xen_check_type(0, arg5, 5, "XFillPolygon", "positive integer"); pt = (XPoint *)calloc(len, sizeof(XPoint)); for (i = 0; (i < len) && (!Xen_is_null(arg4)); i++, arg4 = Xen_cdr(arg4)) { Xen xp; xp = Xen_car(arg4); if (!(Xen_is_XPoint(xp))) Xen_check_type(0, xp, i, "XFillRegion", "XPoint"); pt1 = Xen_to_C_XPoint(xp); pt[i].x = pt1->x; pt[i].y = pt1->y; } XFillPolygon(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_to_C_GC(arg3), pt, len, Xen_integer_to_C_int(arg6), Xen_integer_to_C_int(arg7)); free(pt); return(C_int_to_Xen_integer(len)); } static Xen gxm_XFillArcs(Xen arg1, Xen arg2, Xen arg3, Xen larg4, Xen arg5) { #define H_XFillArcs "XFillArcs(display, d, gc, arcs, narcs)" /* DIFF: XFillArcs Arc* arg (arg 4) is list of XArcs */ int i, len; Display *dpy; Drawable draw; GC gc; Xen arg4; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XFillArcs", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XFillArcs", "Drawable"); Xen_check_type(Xen_is_GC(arg3), arg3, 3, "XFillArcs", "GC"); Xen_check_type(Xen_is_list(larg4), larg4, 4, "XFillArcs", "list of XArcs"); Xen_check_type(Xen_is_integer(arg5), arg5, 5, "XFillArcs", "int"); arg4 = Xen_copy_arg(larg4); len = Xen_integer_to_C_int(arg5); if (len <= 0) return(Xen_false); dpy = Xen_to_C_Display(arg1); draw = Xen_to_C_Window(arg2); gc = Xen_to_C_GC(arg3); for (i = 0; (i < len) && (!Xen_is_null(arg4)); i++, arg4 = Xen_cdr(arg4)) { XArc *arc; arc = Xen_to_C_XArc(Xen_car(arg4)); XFillArc(dpy, draw, gc, arc->x, arc->y, arc->width, arc->height, arc->angle1, arc->angle2); } return(C_int_to_Xen_integer(len)); } static Xen gxm_XFillArc(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6, Xen arg7, Xen arg8, Xen arg9) { #define H_XFillArc "XFillArc(display, d, gc, x, y, width, height, angle1, angle2) fills the region described by the specified arc." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XFillArc", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XFillArc", "Drawable"); Xen_check_type(Xen_is_GC(arg3), arg3, 3, "XFillArc", "GC"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XFillArc", "int"); Xen_check_type(Xen_is_integer(arg5), arg5, 5, "XFillArc", "int"); Xen_check_type(Xen_is_ulong(arg6), arg6, 6, "XFillArc", "unsigned int"); Xen_check_type(Xen_is_ulong(arg7), arg7, 7, "XFillArc", "unsigned int"); Xen_check_type(Xen_is_integer(arg8), arg8, 8, "XFillArc", "int"); Xen_check_type(Xen_is_integer(arg9), arg9, 9, "XFillArc", "int"); return(C_int_to_Xen_integer(XFillArc(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_to_C_GC(arg3), Xen_integer_to_C_int(arg4), Xen_integer_to_C_int(arg5), Xen_ulong_to_C_ulong(arg6), Xen_ulong_to_C_ulong(arg7), Xen_integer_to_C_int(arg8), Xen_integer_to_C_int(arg9)))); } static Xen gxm_XFetchName(Xen arg1, Xen arg2) { #define H_XFetchName "Status XFetchName(display, w): returns the name of the specified window." /* DIFF: XFetchName omits and rtns arg3 */ char *name; int val; Xen str; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XFetchName", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XFetchName", "Window"); val = XFetchName(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), &name); if (val == 0) return(Xen_false); str = C_string_to_Xen_string(name); free(name); return(str); } static Xen gxm_XEventsQueued(Xen arg1, Xen arg2) { #define H_XEventsQueued "int XEventsQueued(display, mode)" Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XEventsQueued", "Display*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XEventsQueued", "int"); return(C_int_to_Xen_integer(XEventsQueued(Xen_to_C_Display(arg1), Xen_integer_to_C_int(arg2)))); } static Xen gxm_XEnableAccessControl(Xen arg1) { #define H_XEnableAccessControl "XEnableAccessControl(display) enables the use of the access control list at each connection setup." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XEnableAccessControl", "Display*"); return(C_int_to_Xen_integer(XEnableAccessControl(Xen_to_C_Display(arg1)))); } static Xen gxm_XDrawText(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6, Xen arg7) { #define H_XDrawText "XDrawText(display, d, gc, x, y, items, nitems) draws text" int i, len = 0, res; XTextItem *items; Xen lst; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XDrawText", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XDrawText", "Drawable"); Xen_check_type(Xen_is_GC(arg3), arg3, 3, "XDrawText", "GC"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XDrawText", "int"); Xen_check_type(Xen_is_integer(arg5), arg5, 5, "XDrawText", "int"); Xen_check_type(Xen_is_list(arg6), arg6, 6, "XDrawText", "list of XTextItem"); Xen_check_type(Xen_is_integer_or_unbound(arg7), arg7, 7, "XDrawText", "int"); lst = Xen_copy_arg(arg6); if (Xen_is_integer(arg7)) len = Xen_integer_to_C_int(arg7); else len = Xen_list_length(arg6); items = (XTextItem *)calloc(len, sizeof(XTextItem)); for (i = 0; (i < len) && (!Xen_is_null(lst)); i++, lst = Xen_cdr(lst)) { XTextItem *val; val = Xen_to_C_XTextItem(Xen_car(lst)); items[i].chars = val->chars; items[i].nchars = val->nchars; items[i].delta = val->delta; items[i].font = val->font; } res = XDrawText(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_to_C_GC(arg3), Xen_integer_to_C_int(arg4), Xen_integer_to_C_int(arg5), items, len); free(items); return(C_int_to_Xen_integer(res)); } static Xen gxm_XDrawString(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6, Xen arg7) { #define H_XDrawString "XDrawString(display, d, gc, x, y, string, length)" Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XDrawString", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XDrawString", "Drawable"); Xen_check_type(Xen_is_GC(arg3), arg3, 3, "XDrawString", "GC"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XDrawString", "int"); Xen_check_type(Xen_is_integer(arg5), arg5, 5, "XDrawString", "int"); Xen_check_type(Xen_is_string(arg6), arg6, 6, "XDrawString", "char*"); Xen_check_type(Xen_is_integer(arg7), arg7, 7, "XDrawString", "int"); return(C_int_to_Xen_integer(XDrawString(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_to_C_GC(arg3), Xen_integer_to_C_int(arg4), Xen_integer_to_C_int(arg5), (char *)Xen_string_to_C_string(arg6), Xen_integer_to_C_int(arg7)))); } static Xen gxm_XDrawSegments(Xen arg1, Xen arg2, Xen arg3, Xen larg4, Xen arg5) { #define H_XDrawSegments "XDrawSegments(display, d, gc, segments, nsegments) draws multiple, unconnected lines. " /* DIFF: XDrawSegments XSegment* arg (arg 4) is list of XSegments */ XSegment *pt; int i, len; Xen arg4; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XDrawSegments", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XDrawSegments", "Drawable"); Xen_check_type(Xen_is_GC(arg3), arg3, 3, "XDrawSegments", "GC"); Xen_check_type(Xen_is_list(larg4), larg4, 4, "XDrawSegments", "list of XSegments"); Xen_check_type(Xen_is_integer(arg5), arg5, 5, "XDrawSegments", "int"); arg4 = Xen_copy_arg(larg4); len = Xen_integer_to_C_int(arg5); if (len <= 0) Xen_check_type(0, arg5, 5, "XDrawSegments", "positive integer"); pt = (XSegment *)calloc(len, sizeof(XSegment)); for (i = 0; (i < len) && (!Xen_is_null(arg4)); i++, arg4 = Xen_cdr(arg4)) { XSegment *pt1; pt1 = Xen_to_C_XSegment(Xen_car(arg4)); pt[i].x1 = pt1->x1; pt[i].y1 = pt1->y1; pt[i].x2 = pt1->x2; pt[i].y2 = pt1->y2; } XDrawSegments(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_to_C_GC(arg3), pt, len); free(pt); return(C_int_to_Xen_integer(len)); } static Xen gxm_XDrawRectangles(Xen arg1, Xen arg2, Xen arg3, Xen larg4, Xen arg5) { #define H_XDrawRectangles "XDrawRectangles(display, d, gc, rectangles, nrectangles) draws the outlines of the specified rectangles." /* DIFF: XDrawRectangles XRectangle* arg (arg 4) is list of XRectangles */ XRectangle *pt; int i, len; Xen arg4; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XDrawRectangles", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XDrawRectangles", "Drawable"); Xen_check_type(Xen_is_GC(arg3), arg3, 3, "XDrawRectangles", "GC"); Xen_check_type(Xen_is_list(larg4), larg4, 4, "XDrawRectangles", "list of XRectangles"); Xen_check_type(Xen_is_integer(arg5), arg5, 5, "XDrawRectangles", "int"); arg4 = Xen_copy_arg(larg4); len = Xen_integer_to_C_int(arg5); if (len <= 0) Xen_check_type(0, arg5, 5, "XDrawRectangles", "positive integer"); pt = (XRectangle *)calloc(len, sizeof(XRectangle)); for (i = 0; (i < len) && (!Xen_is_null(arg4)); i++, arg4 = Xen_cdr(arg4)) { XRectangle *pt1; pt1 = Xen_to_C_XRectangle(Xen_car(arg4)); pt[i].x = pt1->x; pt[i].y = pt1->y; pt[i].width = pt1->width; pt[i].height = pt1->height; } XDrawRectangles(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_to_C_GC(arg3), pt, len); free(pt); return(C_int_to_Xen_integer(len)); } static Xen gxm_XDrawRectangle(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6, Xen arg7) { #define H_XDrawRectangle "XDrawRectangle(display, d, gc, x, y, width, height) draws the outlines of the specified rectangle." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XDrawRectangle", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XDrawRectangle", "Drawable"); Xen_check_type(Xen_is_GC(arg3), arg3, 3, "XDrawRectangle", "GC"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XDrawRectangle", "int"); Xen_check_type(Xen_is_integer(arg5), arg5, 5, "XDrawRectangle", "int"); Xen_check_type(Xen_is_ulong(arg6), arg6, 6, "XDrawRectangle", "unsigned int"); Xen_check_type(Xen_is_ulong(arg7), arg7, 7, "XDrawRectangle", "unsigned int"); return(C_int_to_Xen_integer(XDrawRectangle(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_to_C_GC(arg3), Xen_integer_to_C_int(arg4), Xen_integer_to_C_int(arg5), Xen_ulong_to_C_ulong(arg6), Xen_ulong_to_C_ulong(arg7)))); } static Xen gxm_XDrawPoints(Xen arg1, Xen arg2, Xen arg3, Xen larg4, Xen arg5, Xen arg6) { #define H_XDrawPoints "XDrawPoints(display, d, gc, points, npoints, mode) draws multiple points." /* DIFF: XDrawPoints XPoint* arg (arg 4) is list of XPoints */ XPoint *pt, *pt1; int i, len; Xen arg4; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XDrawPoints", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XDrawPoints", "Drawable"); Xen_check_type(Xen_is_GC(arg3), arg3, 3, "XDrawPoints", "GC"); Xen_check_type(Xen_is_list(larg4), larg4, 4, "XDrawPoints", "list of XPoints"); Xen_check_type(Xen_is_integer(arg5), arg5, 5, "XDrawPoints", "int"); Xen_check_type(Xen_is_integer(arg6), arg6, 6, "XDrawPoints", "int"); arg4 = Xen_copy_arg(larg4); len = Xen_integer_to_C_int(arg5); if (len <= 0) Xen_check_type(0, arg5, 5, "XDrawPoints", "positive integer"); pt = (XPoint *)calloc(len, sizeof(XPoint)); for (i = 0; (i < len) && (!Xen_is_null(arg4)); i++, arg4 = Xen_cdr(arg4)) { Xen xp; xp = Xen_car(arg4); if (!(Xen_is_XPoint(xp))) Xen_check_type(0, xp, i, "XDrawPoints", "XPoint"); pt1 = Xen_to_C_XPoint(xp); pt[i].x = pt1->x; pt[i].y = pt1->y; } XDrawPoints(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_to_C_GC(arg3), pt, len, Xen_integer_to_C_int(arg6)); free(pt); return(C_int_to_Xen_integer(len)); } static Xen gxm_XDrawPoint(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5) { #define H_XDrawPoint "XDrawPoint(display, d, gc, x, y) uses the foreground pixel and function components of the GC to draw a single \ point into the specified drawable." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XDrawPoint", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XDrawPoint", "Drawable"); Xen_check_type(Xen_is_GC(arg3), arg3, 3, "XDrawPoint", "GC"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XDrawPoint", "int"); Xen_check_type(Xen_is_integer(arg5), arg5, 5, "XDrawPoint", "int"); return(C_int_to_Xen_integer(XDrawPoint(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_to_C_GC(arg3), Xen_integer_to_C_int(arg4), Xen_integer_to_C_int(arg5)))); } static Xen gxm_XDrawLines(Xen arg1, Xen arg2, Xen arg3, Xen larg4, Xen arg5, Xen arg6) { #define H_XDrawLines "XDrawLines(display, d, gc, points, npoints, mode) uses the components of the specified GC to draw npoints lines \ between each pair of points (point[i], point[i+1]) in the array of XPoint structures." /* DIFF: XDrawLines XPoint* arg (arg 4) is list of XPoints */ XPoint *pt, *pt1; int i, len; Xen arg4; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XDrawLines", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XDrawLines", "Drawable"); Xen_check_type(Xen_is_GC(arg3), arg3, 3, "XDrawLines", "GC"); Xen_check_type(Xen_is_list(larg4), larg4, 4, "XDrawLines", "list of XPoints"); Xen_check_type(Xen_is_integer(arg5), arg5, 5, "XDrawLines", "int"); Xen_check_type(Xen_is_integer(arg6), arg6, 6, "XDrawLines", "int"); arg4 = Xen_copy_arg(larg4); len = Xen_integer_to_C_int(arg5); if (len <= 0) Xen_check_type(0, arg5, 5, "XDrawLines", "positive integer"); pt = (XPoint *)calloc(len, sizeof(XPoint)); for (i = 0; (i < len) && (!Xen_is_null(arg4)); i++, arg4 = Xen_cdr(arg4)) { Xen xp; xp = Xen_car(arg4); if (!(Xen_is_XPoint(xp))) Xen_check_type(0, xp, i, "XDrawLines", "XPoint"); pt1 = Xen_to_C_XPoint(xp); pt[i].x = pt1->x; pt[i].y = pt1->y; } XDrawLines(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_to_C_GC(arg3), pt, len, Xen_integer_to_C_int(arg6)); free(pt); return(C_int_to_Xen_integer(len)); } static Xen gxm_XDrawLinesDirect(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6) { #define H_XDrawLinesDirect "XDrawLinesDirect is the same as XDrawLines but takes an (opaque) pointer to an XPoint array" XPoint *pt; int len; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XDrawLinesDirect", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XDrawLinesDirect", "Drawable"); Xen_check_type(Xen_is_GC(arg3), arg3, 3, "XDrawLinesDirect", "GC"); Xen_check_type(Xen_is_wrapped_c_pointer(arg4), arg4, 4, "XDrawLinesDirect", "array of XPoints"); Xen_check_type(Xen_is_integer(arg5), arg5, 5, "XDrawLines", "int"); Xen_check_type(Xen_is_integer(arg6), arg6, 6, "XDrawLines", "int"); len = Xen_integer_to_C_int(arg5); if (len <= 0) return(Xen_false); pt = (XPoint *)Xen_unwrap_C_pointer(arg4); XDrawLines(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_to_C_GC(arg3), pt, len, Xen_integer_to_C_int(arg6)); return(C_int_to_Xen_integer(len)); } static Xen gxm_Vector2XPoints(Xen arg1) { #define H_vector2XPoints "(vector->XPoints vect) packages point data in vect as (opaque) array of XPoints" int i, j, len; /* vector assumed to be sequence of x y pairs (not XPoints from local view) */ XPoint *pt; Xen_check_type(Xen_is_vector(arg1), arg1, 1, "vector->XPoints", "vector of x,y values"); len = Xen_vector_length(arg1) / 2; if (len <= 0) Xen_check_type(0, arg1, 1, "vector->XPoints", "positive integer"); pt = (XPoint *)calloc(len, sizeof(XPoint)); for (i = 0, j = 0; i < len; i++, j += 2) { pt[i].x = Xen_integer_to_C_int(Xen_vector_ref(arg1, j)); pt[i].y = Xen_integer_to_C_int(Xen_vector_ref(arg1, j + 1)); } return(Xen_wrap_C_pointer(pt)); } static Xen gxm_FreeXPoints(Xen arg1) { void *pts; #define H_freeXPoints "(freeXPoints vect) frees an (opaque) XPoint array created by vector->Xpoints" Xen_check_type(Xen_is_wrapped_c_pointer(arg1), arg1, 1, "freeXPoints", "opaque XPoint array"); pts = (void *)(Xen_unwrap_C_pointer(arg1)); free(pts); return(Xen_false); } static Xen gxm_XDrawLine(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6, Xen arg7) { #define H_XDrawLine "XDrawLine(display, d, gc, x1, y1, x2, y2) uses the components of the specified GC to draw a line between the \ specified set of points (x1, y1) and (x2, y2)." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XDrawLine", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XDrawLine", "Drawable"); Xen_check_type(Xen_is_GC(arg3), arg3, 3, "XDrawLine", "GC"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XDrawLine", "int"); Xen_check_type(Xen_is_integer(arg5), arg5, 5, "XDrawLine", "int"); Xen_check_type(Xen_is_integer(arg6), arg6, 6, "XDrawLine", "int"); Xen_check_type(Xen_is_integer(arg7), arg7, 7, "XDrawLine", "int"); return(C_int_to_Xen_integer(XDrawLine(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_to_C_GC(arg3), Xen_integer_to_C_int(arg4), Xen_integer_to_C_int(arg5), Xen_integer_to_C_int(arg6), Xen_integer_to_C_int(arg7)))); } static Xen gxm_XDrawImageString(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6, Xen arg7) { #define H_XDrawImageString "XDrawImageString(display, d, gc, x, y, string, length)" Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XDrawImageString", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XDrawImageString", "Drawable"); Xen_check_type(Xen_is_GC(arg3), arg3, 3, "XDrawImageString", "GC"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XDrawImageString", "int"); Xen_check_type(Xen_is_integer(arg5), arg5, 5, "XDrawImageString", "int"); Xen_check_type(Xen_is_string(arg6), arg6, 6, "XDrawImageString", "char*"); Xen_check_type(Xen_is_integer(arg7), arg7, 7, "XDrawImageString", "int"); return(C_int_to_Xen_integer(XDrawImageString(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_to_C_GC(arg3), Xen_integer_to_C_int(arg4), Xen_integer_to_C_int(arg5), (char *)Xen_string_to_C_string(arg6), Xen_integer_to_C_int(arg7)))); } static Xen gxm_XDrawArcs(Xen arg1, Xen arg2, Xen arg3, Xen larg4, Xen arg5) { #define H_XDrawArcs "XDrawArcs(display, d, gc, arcs, narcs) draws multiple circular or elliptical arcs." /* DIFF: XDrawArcs Arc* arg (arg 4) is list of XArcs */ int i, len; Display *dpy; Drawable draw; GC gc; Xen arg4; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XDrawArcs", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XDrawArcs", "Drawable"); Xen_check_type(Xen_is_GC(arg3), arg3, 3, "XDrawArcs", "GC"); Xen_check_type(Xen_is_list(larg4), larg4, 4, "XDrawArcs", "list of XArcs"); Xen_check_type(Xen_is_integer(arg5), arg5, 5, "XDrawArcs", "int"); arg4 = Xen_copy_arg(larg4); len = Xen_integer_to_C_int(arg5); dpy = Xen_to_C_Display(arg1); draw = Xen_to_C_Window(arg2); gc = Xen_to_C_GC(arg3); for (i = 0; (i < len) && (!Xen_is_null(arg4)); i++, arg4 = Xen_cdr(arg4)) { XArc *arc; arc = Xen_to_C_XArc(Xen_car(arg4)); XDrawArc(dpy, draw, gc, arc->x, arc->y, arc->width, arc->height, arc->angle1, arc->angle2); } return(C_int_to_Xen_integer(len)); } static Xen gxm_XDrawArc(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6, Xen arg7, Xen arg8, Xen arg9) { #define H_XDrawArc "XDrawArc(display, d, gc, x, y, width, height, angle1, angle2) draws a single circular or elliptical arc." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XDrawArc", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XDrawArc", "Drawable"); Xen_check_type(Xen_is_GC(arg3), arg3, 3, "XDrawArc", "GC"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XDrawArc", "int"); Xen_check_type(Xen_is_integer(arg5), arg5, 5, "XDrawArc", "int"); Xen_check_type(Xen_is_ulong(arg6), arg6, 6, "XDrawArc", "unsigned int"); Xen_check_type(Xen_is_ulong(arg7), arg7, 7, "XDrawArc", "unsigned int"); Xen_check_type(Xen_is_integer(arg8), arg8, 8, "XDrawArc", "int"); Xen_check_type(Xen_is_integer(arg9), arg9, 9, "XDrawArc", "int"); return(C_int_to_Xen_integer(XDrawArc(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_to_C_GC(arg3), Xen_integer_to_C_int(arg4), Xen_integer_to_C_int(arg5), Xen_ulong_to_C_ulong(arg6), Xen_ulong_to_C_ulong(arg7), Xen_integer_to_C_int(arg8), Xen_integer_to_C_int(arg9)))); } static Xen gxm_XDisplayWidthMM(Xen arg1, Xen arg2) { #define H_DisplayWidthMM "DisplayWidthMM(display, screen_number): returns the width of the specified screen in millimeters." #define H_XDisplayWidthMM "XDisplayWidthMM(display, screen_number): returns the width of the specified screen in millimeters." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XDisplayWidthMM", "Display*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XDisplayWidthMM", "int"); return(C_int_to_Xen_integer(XDisplayWidthMM(Xen_to_C_Display(arg1), Xen_integer_to_C_int(arg2)))); } static Xen gxm_XDisplayWidth(Xen arg1, Xen arg2) { #define H_DisplayWidth "DisplayWidth(display, screen_number): returns the width of the screen in pixels." #define H_XDisplayWidth "XDisplayWidth(display, screen_number): returns the width of the screen in pixels." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XDisplayWidth", "Display*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XDisplayWidth", "int"); return(C_int_to_Xen_integer(XDisplayWidth(Xen_to_C_Display(arg1), Xen_integer_to_C_int(arg2)))); } static Xen gxm_XDisplayPlanes(Xen arg1, Xen arg2) { #define H_DisplayPlanes "DisplayPlanes(display, screen_number): returns the depth of the root window of the specified screen." #define H_XDisplayPlanes "XDisplayPlanes(display, screen_number): returns the depth of the root window of the specified screen." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XDisplayPlanes", "Display*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XDisplayPlanes", "int"); return(C_int_to_Xen_integer(XDisplayPlanes(Xen_to_C_Display(arg1), Xen_integer_to_C_int(arg2)))); } static Xen gxm_XDisplayKeycodes(Xen arg1) { #define H_XDisplayKeycodes "XDisplayKeycodes(display): returns the min-keycodes and max-keycodes supported by the specified display." /* DIFF: XDisplayKeycodes omit and rtn arg 2 and 3 */ int m1, m2, val; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XDisplayKeycodes", "Display*"); val = XDisplayKeycodes(Xen_to_C_Display(arg1), &m1, &m2); return(Xen_list_3(C_int_to_Xen_integer(val), C_int_to_Xen_integer(m1), C_int_to_Xen_integer(m2))); } static Xen gxm_XDisplayHeightMM(Xen arg1, Xen arg2) { #define H_DisplayHeightMM "DisplayHeightMM(display, screen_number): returns the height of the specified screen in millimeters." #define H_XDisplayHeightMM "XDisplayHeightMM(display, screen_number): returns the height of the specified screen in millimeters." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XDisplayHeightMM", "Display*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XDisplayHeightMM", "int"); return(C_int_to_Xen_integer(XDisplayHeightMM(Xen_to_C_Display(arg1), Xen_integer_to_C_int(arg2)))); } static Xen gxm_XDisplayHeight(Xen arg1, Xen arg2) { #define H_DisplayHeight "DisplayHeight(display, screen_number): returns the height of the specified screen in pixels." #define H_XDisplayHeight "XDisplayHeight(display, screen_number): returns the height of the specified screen in pixels." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XDisplayHeight", "Display*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XDisplayHeight", "int"); return(C_int_to_Xen_integer(XDisplayHeight(Xen_to_C_Display(arg1), Xen_integer_to_C_int(arg2)))); } static Xen gxm_XDisplayCells(Xen arg1, Xen arg2) { #define H_DisplayCells "DisplayCells(display, screen_number): returns the number of entries in the default colormap." #define H_XDisplayCells "XDisplayCells(display, screen_number): returns the number of entries in the default colormap." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XDisplayCells", "Display*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XDisplayCells", "int"); return(C_int_to_Xen_integer(XDisplayCells(Xen_to_C_Display(arg1), Xen_integer_to_C_int(arg2)))); } static Xen gxm_XDisableAccessControl(Xen arg1) { #define H_XDisableAccessControl "XDisableAccessControl(display) disables the use of the access control list at each connection setup." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XDisableAccessControl", "Display*"); return(C_int_to_Xen_integer(XDisableAccessControl(Xen_to_C_Display(arg1)))); } static Xen gxm_XDoesSaveUnders(Xen arg1) { #define H_DoesSaveUnders "DoesSaveUnders(screen): returns a Boolean value indicating whether the screen supports save unders." #define H_XDoesSaveUnders "XDoesSaveUnders(screen): returns a Boolean value indicating whether the screen supports save unders." Xen_check_type(Xen_is_Screen(arg1), arg1, 1, "XDoesSaveUnders", "Screen*"); return(C_bool_to_Xen_boolean(XDoesSaveUnders(Xen_to_C_Screen(arg1)))); } static Xen gxm_XDoesBackingStore(Xen arg1) { #define H_DoesBackingStore "DoesBackingStore(screen): returns WhenMapped, NotUseful,or Always,which indicate whether the screen supports backing stores." #define H_XDoesBackingStore "XDoesBackingStore(screen): returns WhenMapped, NotUseful,or Always,which indicate whether the screen supports backing stores." Xen_check_type(Xen_is_Screen(arg1), arg1, 1, "XDoesBackingStore", "Screen*"); return(C_bool_to_Xen_boolean(XDoesBackingStore(Xen_to_C_Screen(arg1)))); } static Xen gxm_XDestroySubwindows(Xen arg1, Xen arg2) { #define H_XDestroySubwindows "XDestroySubwindows(display, w) destroys all inferior windows of the specified window, in bottom-to-top stacking order." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XDestroySubwindows", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XDestroySubwindows", "Window"); return(C_int_to_Xen_integer(XDestroySubwindows(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2)))); } static Xen gxm_XDestroyWindow(Xen arg1, Xen arg2) { #define H_XDestroyWindow "XDestroyWindow(display, w) destroys the specified window as well as all of its subwindows and causes the X server \ to generate a DestroyNotify event for each window." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XDestroyWindow", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XDestroyWindow", "Window"); return(C_int_to_Xen_integer(XDestroyWindow(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2)))); } static Xen gxm_XDeleteProperty(Xen arg1, Xen arg2, Xen arg3) { #define H_XDeleteProperty "XDeleteProperty(display, w, property) deletes the specified property only if the property was defined on the specified \ window and causes the X server to generate a PropertyNotify event on the window unless the property does not exist." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XDeleteProperty", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XDeleteProperty", "Window"); Xen_check_type(Xen_is_Atom(arg3), arg3, 3, "XDeleteProperty", "Atom"); return(C_int_to_Xen_integer(XDeleteProperty(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_to_C_Atom(arg3)))); } static Xen gxm_XDefineCursor(Xen arg1, Xen arg2, Xen arg3) { #define H_XDefineCursor "XDefineCursor(display, w, cursor)" Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XDefineCursor", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XDefineCursor", "Window"); Xen_check_type(Xen_is_Cursor(arg3), arg3, 3, "XDefineCursor", "Cursor"); return(C_int_to_Xen_integer(XDefineCursor(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_to_C_Cursor(arg3)))); } static Xen gxm_XDefaultScreen(Xen arg1) { #define H_XDefaultScreen "XDefaultScreen(display)" #define H_XDefaultScreenOfDisplay "returns the default screen of the specified display." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XDefaultScreen", "Display*"); return(C_int_to_Xen_integer(XDefaultScreen(Xen_to_C_Display(arg1)))); } static Xen gxm_XDefaultDepthOfScreen(Xen arg1) { #define H_DefaultDepthOfScreen "returns the default depth of the root window of the specified screen." #define H_XDefaultDepthOfScreen "returns the default depth of the root window of the specified screen." Xen_check_type(Xen_is_Screen(arg1), arg1, 1, "XDefaultDepthOfScreen", "Screen*"); return(C_int_to_Xen_integer(XDefaultDepthOfScreen(Xen_to_C_Screen(arg1)))); } static Xen gxm_XDefaultDepth(Xen arg1, Xen arg2) { #define H_DefaultDepth "returns the depth (number of planes) of the default root window for the specified screen." #define H_XDefaultDepth "returns the depth (number of planes) of the default root window for the specified screen." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XDefaultDepth", "Display*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XDefaultDepth", "int"); return(C_int_to_Xen_integer(XDefaultDepth(Xen_to_C_Display(arg1), Xen_integer_to_C_int(arg2)))); } static Xen gxm_XCopyPlane(Xen args) { #define H_XCopyPlane "XCopyPlane(display, src, dest, gc, src_x, src_y, width, height, dest_x, dest_y, plane) uses a single bit plane of the \ specified source rectangle combined with the specified GC to modify the specified rectangle of dest." Xen arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11; arg1 = Xen_list_ref(args, 0); arg2 = Xen_list_ref(args, 1); arg3 = Xen_list_ref(args, 2); arg4 = Xen_list_ref(args, 3); arg5 = Xen_list_ref(args, 4); arg6 = Xen_list_ref(args, 5); arg7 = Xen_list_ref(args, 6); arg8 = Xen_list_ref(args, 7); arg9 = Xen_list_ref(args, 8); arg10 = Xen_list_ref(args, 9); arg11 = Xen_list_ref(args, 10); Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XCopyPlane", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XCopyPlane", "Drawable"); Xen_check_type(Xen_is_Window(arg3), arg3, 3, "XCopyPlane", "Drawable"); Xen_check_type(Xen_is_GC(arg4), arg4, 4, "XCopyPlane", "GC"); Xen_check_type(Xen_is_integer(arg5), arg5, 5, "XCopyPlane", "int"); Xen_check_type(Xen_is_integer(arg6), arg6, 6, "XCopyPlane", "int"); Xen_check_type(Xen_is_ulong(arg7), arg7, 7, "XCopyPlane", "unsigned int"); Xen_check_type(Xen_is_ulong(arg8), arg8, 8, "XCopyPlane", "unsigned int"); Xen_check_type(Xen_is_integer(arg9), arg9, 9, "XCopyPlane", "int"); Xen_check_type(Xen_is_integer(arg10), arg10, 10, "XCopyPlane", "int"); Xen_check_type(Xen_is_ulong(arg11), arg11, 11, "XCopyPlane", "ulong"); return(C_int_to_Xen_integer(XCopyPlane(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_to_C_Window(arg3), Xen_to_C_GC(arg4), Xen_integer_to_C_int(arg5), Xen_integer_to_C_int(arg6), Xen_ulong_to_C_ulong(arg7), Xen_ulong_to_C_ulong(arg8), Xen_integer_to_C_int(arg9), Xen_integer_to_C_int(arg10), Xen_ulong_to_C_ulong(arg11)))); } static Xen gxm_XCopyGC(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XCopyGC "XCopyGC(display, src, valuemask, dest) copies the specified components from the source GC to the destination GC." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XCopyGC", "Display*"); Xen_check_type(Xen_is_GC(arg2), arg2, 2, "XCopyGC", "GC"); Xen_check_type(Xen_is_ulong(arg3), arg3, 3, "XCopyGC", "ulong"); Xen_check_type(Xen_is_GC(arg4), arg4, 4, "XCopyGC", "GC"); return(C_int_to_Xen_integer(XCopyGC(Xen_to_C_Display(arg1), Xen_to_C_GC(arg2), Xen_ulong_to_C_ulong(arg3), Xen_to_C_GC(arg4)))); } static Xen gxm_XCopyArea(Xen args) { #define H_XCopyArea "XCopyArea(display, src, dest, gc, src_x, src_y, width, height, dest_x, dest_y) combines the specified rectangle of src \ with the specified rectangle of dest." Xen arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10; arg1 = Xen_list_ref(args, 0); arg2 = Xen_list_ref(args, 1); arg3 = Xen_list_ref(args, 2); arg4 = Xen_list_ref(args, 3); arg5 = Xen_list_ref(args, 4); arg6 = Xen_list_ref(args, 5); arg7 = Xen_list_ref(args, 6); arg8 = Xen_list_ref(args, 7); arg9 = Xen_list_ref(args, 8); arg10 = Xen_list_ref(args, 9); Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XCopyArea", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XCopyArea", "Drawable"); Xen_check_type(Xen_is_Window(arg3), arg3, 3, "XCopyArea", "Drawable"); Xen_check_type(Xen_is_GC(arg4), arg4, 4, "XCopyArea", "GC"); Xen_check_type(Xen_is_integer(arg5), arg5, 5, "XCopyArea", "int"); Xen_check_type(Xen_is_integer(arg6), arg6, 6, "XCopyArea", "int"); Xen_check_type(Xen_is_ulong(arg7), arg7, 7, "XCopyArea", "unsigned int"); Xen_check_type(Xen_is_ulong(arg8), arg8, 8, "XCopyArea", "unsigned int"); Xen_check_type(Xen_is_integer(arg9), arg9, 9, "XCopyArea", "int"); Xen_check_type(Xen_is_integer(arg10), arg10, 10, "XCopyArea", "int"); return(C_int_to_Xen_integer(XCopyArea(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_to_C_Window(arg3), Xen_to_C_GC(arg4), Xen_integer_to_C_int(arg5), Xen_integer_to_C_int(arg6), Xen_ulong_to_C_ulong(arg7), Xen_ulong_to_C_ulong(arg8), Xen_integer_to_C_int(arg9), Xen_integer_to_C_int(arg10)))); } static Xen gxm_XConvertSelection(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6) { #define H_XConvertSelection "void XConvertSelection(display, selection, target, property, requestor, time)" Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XConvertSelection", "Display*"); Xen_check_type(Xen_is_Atom(arg2), arg2, 2, "XConvertSelection", "Atom"); Xen_check_type(Xen_is_Atom(arg3), arg3, 3, "XConvertSelection", "Atom"); Xen_check_type(Xen_is_Atom(arg4), arg4, 4, "XConvertSelection", "Atom"); Xen_check_type(Xen_is_Window(arg5), arg5, 5, "XConvertSelection", "Window"); Xen_check_type(Xen_is_Time(arg6), arg6, 6, "XConvertSelection", "Time"); return(C_int_to_Xen_integer(XConvertSelection(Xen_to_C_Display(arg1), Xen_to_C_Atom(arg2), Xen_to_C_Atom(arg3), Xen_to_C_Atom(arg4), Xen_to_C_Window(arg5), Xen_to_C_Time(arg6)))); } static Xen gxm_XConnectionNumber(Xen arg1) { #define H_XConnectionNumber "returns a connection number for the specified display." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XConnectionNumber", "Display*"); return(C_int_to_Xen_integer(XConnectionNumber(Xen_to_C_Display(arg1)))); } static Xen gxm_XConfigureWindow(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XConfigureWindow "XConfigureWindow(display, w, value_mask, values) uses the values specified in the XWindowChanges structure to \ reconfigure a window's size, position, border, and stacking order." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XConfigureWindow", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XConfigureWindow", "Window"); Xen_check_type(Xen_is_ulong(arg3), arg3, 3, "XConfigureWindow", "unsigned int"); Xen_check_type(Xen_is_XWindowChanges(arg4), arg4, 4, "XConfigureWindow", "XWindowChanges*"); return(C_int_to_Xen_integer(XConfigureWindow(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_ulong_to_C_ulong(arg3), Xen_to_C_XWindowChanges(arg4)))); } static Xen gxm_XCloseDisplay(Xen arg1) { #define H_XCloseDisplay "XCloseDisplay(display) closes the connection to the X server for the display specified in the Display structure and \ destroys all windows, resource IDs etc." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XCloseDisplay", "Display*"); return(C_int_to_Xen_integer(XCloseDisplay(Xen_to_C_Display(arg1)))); } static Xen gxm_XClearWindow(Xen arg1, Xen arg2) { #define H_XClearWindow "XClearWindow(display, w) clears the entire area in the specified window." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XClearWindow", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XClearWindow", "Window"); return(C_int_to_Xen_integer(XClearWindow(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2)))); } static Xen gxm_XClearArea(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6, Xen arg7) { #define H_XClearArea "XClearArea(display, w, x, y, width, height, exposures) paints a rectangular area in the specified window according to the \ specified dimensions with the window's background pixel or pixmap." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XClearArea", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XClearArea", "Window"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XClearArea", "int"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XClearArea", "int"); Xen_check_type(Xen_is_ulong(arg5), arg5, 5, "XClearArea", "unsigned int"); Xen_check_type(Xen_is_ulong(arg6), arg6, 6, "XClearArea", "unsigned int"); Xen_check_type(Xen_is_boolean(arg7), arg7, 7, "XClearArea", "Bool"); return(C_int_to_Xen_integer(XClearArea(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_integer_to_C_int(arg3), Xen_integer_to_C_int(arg4), Xen_ulong_to_C_ulong(arg5), Xen_ulong_to_C_ulong(arg6), Xen_boolean_to_C_bool(arg7)))); } static Xen gxm_XCirculateSubwindowsUp(Xen arg1, Xen arg2) { #define H_XCirculateSubwindowsUp "XCirculateSubwindowsUp(display, w) raises the lowest mapped child of the specified window that is partially or \ completely occluded by another child." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XCirculateSubwindowsUp", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XCirculateSubwindowsUp", "Window"); return(C_int_to_Xen_integer(XCirculateSubwindowsUp(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2)))); } static Xen gxm_XCirculateSubwindowsDown(Xen arg1, Xen arg2) { #define H_XCirculateSubwindowsDown "XCirculateSubwindowsDown(display, w) lowers the highest mapped child of the specified window that partially or \ completely occludes another child." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XCirculateSubwindowsDown", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XCirculateSubwindowsDown", "Window"); return(C_int_to_Xen_integer(XCirculateSubwindowsDown(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2)))); } static Xen gxm_XCirculateSubwindows(Xen arg1, Xen arg2, Xen arg3) { #define H_XCirculateSubwindows "XCirculateSubwindows(display, w, direction) circulates children of the specified window in the specified direction." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XCirculateSubwindows", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XCirculateSubwindows", "Window"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XCirculateSubwindows", "int"); return(C_int_to_Xen_integer(XCirculateSubwindows(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_integer_to_C_int(arg3)))); } static Xen gxm_XCheckWindowEvent(Xen arg1, Xen arg2, Xen arg3) { #define H_XCheckWindowEvent "Bool XCheckWindowEvent(display, w, event_mask) searches the event queue and then the events available \ on the server connection for the first event that matches the specified window and event mask." /* DIFF: XCheckWindowEvent dpy win mask [ev] -> (list val ev) */ XEvent *e; int val; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XCheckWindowEvent", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XCheckWindowEvent", "Window"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XCheckWindowEvent", "long"); e = (XEvent *)calloc(1, sizeof(XEvent)); val = XCheckWindowEvent(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_integer_to_C_int(arg3), e); if (val) return(C_to_Xen_XEvent_OBJ(e)); else { free(e); return(Xen_false); } } static Xen gxm_XCheckTypedWindowEvent(Xen arg1, Xen arg2, Xen arg3) { #define H_XCheckTypedWindowEvent "Bool XCheckTypedWindowEvent(display, w, event_type) searches the event queue and then any events \ available on the server connection for the first event that matches the specified event mask" /* DIFF: XCheckTypedWindowEvent dpy win mask [ev] -> (list val ev) */ XEvent *e; int val; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XCheckTypedWindowEvent", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XCheckTypedWindowEvent", "Window"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XCheckTypedWindowEvent", "int"); e = (XEvent *)calloc(1, sizeof(XEvent)); val = XCheckTypedWindowEvent(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_integer_to_C_int(arg3), e); if (val) return(C_to_Xen_XEvent_OBJ(e)); else { free(e); return(Xen_false); } } static Xen gxm_XCheckTypedEvent(Xen arg1, Xen arg2) { #define H_XCheckTypedEvent "Bool XCheckTypedEvent(display, event_type) searches the event queue and then any events available \ on the server connection for the first event that matches the specified type." /* DIFF: XCheckTypedEvent dpy mask [ev] -> (list val ev) */ XEvent *e; int val; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XCheckTypedEvent", "Display*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XCheckTypedEvent", "int"); e = (XEvent *)calloc(1, sizeof(XEvent)); val = XCheckTypedEvent(Xen_to_C_Display(arg1), Xen_integer_to_C_int(arg2), e); if (val) return(C_to_Xen_XEvent_OBJ(e)); else { free(e); return(Xen_false); } } static Xen gxm_XCheckMaskEvent(Xen arg1, Xen arg2) { #define H_XCheckMaskEvent "Bool XCheckMaskEvent(display, event_mask) searches the event queue and then any events available on \ the server connection for the first event that matches the specified mask." /* DIFF: XCheckMaskEvent dpy mask [ev] -> (list val ev) */ XEvent *e; int val; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XCheckMaskEvent", "Display*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XCheckMaskEvent", "long"); e = (XEvent *)calloc(1, sizeof(XEvent)); val = XCheckMaskEvent(Xen_to_C_Display(arg1), Xen_integer_to_C_int(arg2), e); if (val) return(C_to_Xen_XEvent_OBJ(e)); else { free(e); return(Xen_false); } } static Xen gxm_XCheckIfEvent(Xen arg1, Xen arg2, Xen arg3) { #define H_XCheckIfEvent "Bool XCheckIfEvent(display, predicate, arg)" /* DIFF: XCheckIfEvent dpy [ev] proc ptr -> (list val ev) */ XEvent *e; int val; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XCheckIfEvent", "Display*"); Xen_check_type(Xen_is_procedure(arg2) && (Xen_is_aritable(arg2, 3)), arg2, 2, "XCheckIfEvent", "(Bool_Proc dpy ev data)"); e = (XEvent *)calloc(1, sizeof(XEvent)); val = XCheckIfEvent(Xen_to_C_Display(arg1), e, (Bool (*)(Display *d, XEvent *ev, char *p))gxm_XPeekIfEventProc, (char*)arg3); if (val) return(C_to_Xen_XEvent_OBJ(e)); else { free(e); return(Xen_false); } } static Xen gxm_XChangeWindowAttributes(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XChangeWindowAttributes "XChangeWindowAttributes(display, w, valuemask, attributes) uses the window attributes in the XSetWindowAttributes \ structure to change the specified window attributes." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XChangeWindowAttributes", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XChangeWindowAttributes", "Window"); Xen_check_type(Xen_is_ulong(arg3), arg3, 3, "XChangeWindowAttributes", "ulong"); Xen_check_type(Xen_is_XSetWindowAttributes(arg4), arg4, 4, "XChangeWindowAttributes", "XSetWindowAttributes*"); return(C_int_to_Xen_integer(XChangeWindowAttributes(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_ulong_to_C_ulong(arg3), Xen_to_C_XSetWindowAttributes(arg4)))); } static Xen gxm_XChangeProperty(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6, Xen arg7, Xen arg8) { #define H_XChangeProperty "XChangeProperty(display, w, property, type, format, mode, data, nelements) alters the property for the specified \ window and causes the X server to generate a PropertyNotify event on that window." unsigned char *command; int len; int *data = NULL; Xen rtn; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XChangeProperty", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XChangeProperty", "Window"); Xen_check_type(Xen_is_Atom(arg3), arg3, 3, "XChangeProperty", "Atom"); Xen_check_type(Xen_is_Atom(arg4), arg4, 4, "XChangeProperty", "Atom"); Xen_check_type(Xen_is_integer(arg5), arg5, 5, "XChangeProperty", "int"); Xen_check_type(Xen_is_integer(arg6), arg6, 6, "XChangeProperty", "int"); Xen_check_type(Xen_is_string(arg7) || Xen_is_list(arg7), arg7, 7, "XChangeProperty", "string or list of int"); Xen_check_type(Xen_is_integer_or_unbound(arg8), arg8, 8, "XChangeProperty", "int"); if (Xen_is_string(arg7)) { command = (unsigned char *)(Xen_string_to_C_string(arg7)); if (Xen_is_integer(arg8)) len = Xen_integer_to_C_int(arg8); else len = strlen((const char *)command) + 1; } else { if (Xen_is_integer(arg8)) len = Xen_integer_to_C_int(arg8); else len = Xen_list_length(arg7); data = Xen_to_C_Ints(arg7, len); command = (unsigned char *)data; } rtn = C_int_to_Xen_integer(XChangeProperty(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_to_C_Atom(arg3), Xen_to_C_Atom(arg4), Xen_integer_to_C_int(arg5), Xen_integer_to_C_int(arg6), (const unsigned char *)command, len)); if (data) free(data); return(rtn); } static Xen gxm_XChangePointerControl(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6) { #define H_XChangePointerControl "XChangePointerControl(display, do_accel, do_threshold, accel_numerator, accel_denominator, threshold) \ defines how the pointing device moves." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XChangePointerControl", "Display*"); Xen_check_type(Xen_is_boolean(arg2), arg2, 2, "XChangePointerControl", "Bool"); Xen_check_type(Xen_is_boolean(arg3), arg3, 3, "XChangePointerControl", "Bool"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XChangePointerControl", "int"); Xen_check_type(Xen_is_integer(arg5), arg5, 5, "XChangePointerControl", "int"); Xen_check_type(Xen_is_integer(arg6), arg6, 6, "XChangePointerControl", "int"); return(C_int_to_Xen_integer(XChangePointerControl(Xen_to_C_Display(arg1), Xen_boolean_to_C_bool(arg2), Xen_boolean_to_C_bool(arg3), Xen_integer_to_C_int(arg4), Xen_integer_to_C_int(arg5), Xen_integer_to_C_int(arg6)))); } static Xen gxm_XChangeKeyboardMapping(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5) { #define H_XChangeKeyboardMapping "XChangeKeyboardMapping(display, first_keycode, keysyms_per_keycode, keysyms, num_codes) defines the \ symbols for the specified number of KeyCodes starting with first_keycode." /* DIFF: XChangeKeyboardMapping takes list of KeySyms */ KeySym *ks; int len, val; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XChangeKeyboardMapping", "Display*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XChangeKeyboardMapping", "int"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XChangeKeyboardMapping", "int"); Xen_check_type(Xen_is_list(arg4), arg4, 4, "XChangeKeyboardMapping", "list of KeySym"); Xen_check_type(Xen_is_integer(arg5), arg5, 5, "XChangeKeyboardMapping", "int"); len = Xen_integer_to_C_int(arg5); if (len <= 0) return(Xen_false); ks = Xen_to_C_KeySyms(arg4, len); val = XChangeKeyboardMapping(Xen_to_C_Display(arg1), Xen_integer_to_C_int(arg2), Xen_integer_to_C_int(arg3), ks, len); free(ks); return(C_int_to_Xen_integer(val)); } static Xen gxm_XChangeKeyboardControl(Xen arg1, Xen arg2, Xen larg3) { #define H_XChangeKeyboardControl "XChangeKeyboardControl(display, value_mask, values) controls the keyboard characteristics defined by \ the XKeyboardControl structure." /* DIFF: XChangeKeyboardControl arg3 is list of XKeyboardControl fields */ Xen arg3; XKeyboardControl kc; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XChangeKeyboardControl", "Display*"); Xen_check_type(Xen_is_ulong(arg2), arg2, 2, "XChangeKeyboardControl", "ulong"); Xen_check_type(Xen_is_list(larg3), larg3, 3, "XChangeKeyboardControl", "XKeyboardControl*"); arg3 = Xen_copy_arg(larg3); kc.key_click_percent = Xen_integer_to_C_int(Xen_car(arg3)); arg3 = Xen_cdr(arg3); if (!(Xen_is_null(arg3))) { kc.bell_percent = Xen_integer_to_C_int(Xen_car(arg3)); arg3 = Xen_cdr(arg3); if (!(Xen_is_null(arg3))) { kc.bell_pitch = Xen_integer_to_C_int(Xen_car(arg3)); arg3 = Xen_cdr(arg3); if (!(Xen_is_null(arg3))) { kc.bell_duration = Xen_integer_to_C_int(Xen_car(arg3)); arg3 = Xen_cdr(arg3); if (!(Xen_is_null(arg3))) { kc.led = Xen_integer_to_C_int(Xen_car(arg3)); arg3 = Xen_cdr(arg3); if (!(Xen_is_null(arg3))) { kc.led_mode = Xen_integer_to_C_int(Xen_car(arg3)); arg3 = Xen_cdr(arg3); if (!(Xen_is_null(arg3))) { kc.key = Xen_integer_to_C_int(Xen_car(arg3)); arg3 = Xen_cdr(arg3); if (!(Xen_is_null(arg3))) { kc.auto_repeat_mode = Xen_integer_to_C_int(Xen_car(arg3)); }}}}}}} return(C_int_to_Xen_integer(XChangeKeyboardControl(Xen_to_C_Display(arg1), Xen_ulong_to_C_ulong(arg2), &kc))); } static Xen gxm_XChangeGC(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XChangeGC "XChangeGC(display, gc, valuemask, values) changes the components specified by valuemask for the specified GC." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XChangeGC", "Display*"); Xen_check_type(Xen_is_GC(arg2), arg2, 2, "XChangeGC", "GC"); Xen_check_type(Xen_is_ulong(arg3), arg3, 3, "XChangeGC", "ulong"); Xen_check_type(Xen_is_XGCValues(arg4), arg4, 4, "XChangeGC", "XGCValues*"); return(C_int_to_Xen_integer(XChangeGC(Xen_to_C_Display(arg1), Xen_to_C_GC(arg2), Xen_ulong_to_C_ulong(arg3), Xen_to_C_XGCValues(arg4)))); } static Xen gxm_XChangeActivePointerGrab(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XChangeActivePointerGrab "XChangeActivePointerGrab(display, event_mask, cursor, time) changes the specified dynamic parameters \ if the pointer is actively grabbed by the client and if the specified time is no earlier than the last-pointer-grab time and no later than \ the current X server time." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XChangeActivePointerGrab", "Display*"); Xen_check_type(Xen_is_ulong(arg2), arg2, 2, "XChangeActivePointerGrab", "unsigned int"); Xen_check_type(Xen_is_Cursor(arg3), arg3, 3, "XChangeActivePointerGrab", "Cursor"); Xen_check_type(Xen_is_Time(arg4), arg4, 4, "XChangeActivePointerGrab", "Time"); return(C_int_to_Xen_integer(XChangeActivePointerGrab(Xen_to_C_Display(arg1), Xen_ulong_to_C_ulong(arg2), Xen_to_C_Cursor(arg3), Xen_to_C_Time(arg4)))); } static Xen gxm_XCellsOfScreen(Xen arg1) { #define H_CellsOfScreen "CellsOfScreen(screen): returns the number of colormap cells in the default colormap of the specified screen." Xen_check_type(Xen_is_Screen(arg1), arg1, 1, "XCellsOfScreen", "Screen*"); return(C_int_to_Xen_integer(XCellsOfScreen(Xen_to_C_Screen(arg1)))); } static Xen gxm_XBitmapUnit(Xen arg1) { #define H_BitmapUnit "BitmapUnit(display): returns the size of a bitmap's scanline unit in bits." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XBitmapUnit", "Display*"); return(C_int_to_Xen_integer(XBitmapUnit(Xen_to_C_Display(arg1)))); } static Xen gxm_XBitmapPad(Xen arg1) { #define H_BitmapPad "BitmapPad(display): returns the number of bits that each scanline must be padded." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XBitmapPad", "Display*"); return(C_int_to_Xen_integer(XBitmapPad(Xen_to_C_Display(arg1)))); } static Xen gxm_XBitmapBitOrder(Xen arg1) { #define H_BitmapBitOrder "BitmapBitOrder(display): returns LSBFirst or MSBFirst to indicate whether the leftmost bit in the bitmap as \ displayed on the screen is the least or most significant bit in the unit." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XBitmapBitOrder", "Display*"); return(C_int_to_Xen_integer(XBitmapBitOrder(Xen_to_C_Display(arg1)))); } static Xen gxm_XBell(Xen arg1, Xen arg2) { #define H_XBell "XBell(display, percent) rings the bell on the keyboard on the specified display, if possible." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XBell", "Display*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XBell", "int"); return(C_int_to_Xen_integer(XBell(Xen_to_C_Display(arg1), Xen_integer_to_C_int(arg2)))); } static Xen gxm_XAutoRepeatOn(Xen arg1) { #define H_XAutoRepeatOn "XAutoRepeatOn(display) turns on auto-repeat for the keyboard on the specified display." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XAutoRepeatOn", "Display*"); return(C_int_to_Xen_integer(XAutoRepeatOn(Xen_to_C_Display(arg1)))); } static Xen gxm_XAutoRepeatOff(Xen arg1) { #define H_XAutoRepeatOff "XAutoRepeatOff(display) turns off auto-repeat for the keyboard on the specified display." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XAutoRepeatOff", "Display*"); return(C_int_to_Xen_integer(XAutoRepeatOff(Xen_to_C_Display(arg1)))); } static Xen gxm_XAllowEvents(Xen arg1, Xen arg2, Xen arg3) { #define H_XAllowEvents "XAllowEvents(display, event_mode, time)" Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XAllowEvents", "Display*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XAllowEvents", "int"); Xen_check_type(Xen_is_Time(arg3), arg3, 3, "XAllowEvents", "Time"); return(C_int_to_Xen_integer(XAllowEvents(Xen_to_C_Display(arg1), Xen_integer_to_C_int(arg2), Xen_to_C_Time(arg3)))); } static Xen gxm_XAllocNamedColor(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5) { #define H_XAllocNamedColor "Status XAllocNamedColor(display, colormap, color_name, screen_def_return, exact_def_return) looks up the \ named color with respect to the screen that is associated with the specified colormap." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XAllocNamedColor", "Display*"); Xen_check_type(Xen_is_Colormap(arg2), arg2, 2, "XAllocNamedColor", "Colormap"); Xen_check_type(Xen_is_string(arg3), arg3, 3, "XAllocNamedColor", "char*"); Xen_check_type(Xen_is_XColor(arg4), arg4, 4, "XAllocNamedColor", "XColor"); Xen_check_type(Xen_is_XColor(arg5), arg5, 5, "XAllocNamedColor", "XColor"); return(C_int_to_Xen_integer(XAllocNamedColor(Xen_to_C_Display(arg1), Xen_to_C_Colormap(arg2), (char *)Xen_string_to_C_string(arg3), Xen_to_C_XColor(arg4), Xen_to_C_XColor(arg5)))); } static Xen gxm_XAllocColorPlanes(Xen args) { #define H_XAllocColorPlanes "Status XAllocColorPlanes(display, colormap, contig, ncolors, nreds, ngreens, nblues)" /* DIFF: XAllocColorPlanes omits pixel array (arg4) and trailing 3 args, returns them and embedded list of pixels */ unsigned long r,g,b; unsigned long *ps; int len, val; Xen lst = Xen_false; Xen arg1, arg2, arg3, arg5, arg6, arg7, arg8; arg1 = Xen_list_ref(args, 0); arg2 = Xen_list_ref(args, 1); arg3 = Xen_list_ref(args, 2); arg5 = Xen_list_ref(args, 3); arg6 = Xen_list_ref(args, 4); arg7 = Xen_list_ref(args, 5); arg8 = Xen_list_ref(args, 6); Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XAllocColorPlanes", "Display*"); Xen_check_type(Xen_is_Colormap(arg2), arg2, 2, "XAllocColorPlanes", "Colormap"); Xen_check_type(Xen_is_boolean(arg3), arg3, 3, "XAllocColorPlanes", "Bool"); Xen_check_type(Xen_is_integer(arg5), arg5, 5, "XAllocColorPlanes", "int"); Xen_check_type(Xen_is_integer(arg6), arg6, 6, "XAllocColorPlanes", "int"); Xen_check_type(Xen_is_integer(arg7), arg7, 7, "XAllocColorPlanes", "int"); Xen_check_type(Xen_is_integer(arg8), arg8, 8, "XAllocColorPlanes", "int"); len = Xen_integer_to_C_int(arg5); if (len <= 0) Xen_check_type(0, arg5, 5, "XAllocColorPlanes", "positive integer"); ps = (unsigned long *)calloc(len, sizeof(unsigned long)); val = XAllocColorPlanes(Xen_to_C_Display(arg1), Xen_to_C_Colormap(arg2), Xen_boolean_to_C_bool(arg3), ps, len, Xen_integer_to_C_int(arg6), Xen_integer_to_C_int(arg7), Xen_integer_to_C_int(arg8), &r, &g, &b); if (val != 0) { Xen plist = Xen_empty_list; int i, loc; loc = xm_protect(plist); for (i = len - 1; i >= 0; i--) plist = Xen_cons(C_ulong_to_Xen_ulong(ps[i]), plist); xm_unprotect_at(loc); lst = Xen_list_5(C_int_to_Xen_integer(val), plist, C_ulong_to_Xen_ulong(r), C_ulong_to_Xen_ulong(g), C_ulong_to_Xen_ulong(b)); } free(ps); return(lst); } static Xen gxm_XAllocColorCells(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5) { #define H_XAllocColorCells "Status XAllocColorCells(display, colormap, contig, nplanes, npixels) \ allocates read/write color cells." /* DIFF: XAllocColorCells arg 4 and 6 omitted and returned as (embedded) lists */ int mlen, plen, val; Xen mlst = Xen_empty_list, plst = Xen_empty_list; unsigned long *ms, *ps; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XAllocColorCells", "Display*"); Xen_check_type(Xen_is_Colormap(arg2), arg2, 2, "XAllocColorCells", "Colormap"); Xen_check_type(Xen_is_boolean(arg3), arg3, 3, "XAllocColorCells", "Bool"); Xen_check_type(Xen_is_ulong(arg4), arg4, 4, "XAllocColorCells", "unsigned int"); Xen_check_type(Xen_is_ulong(arg5), arg5, 5, "XAllocColorCells", "unsigned int"); mlen = Xen_integer_to_C_int(arg4); if (mlen <= 0) return(Xen_false); plen = Xen_integer_to_C_int(arg5); if (plen <= 0) return(Xen_false); ms = (unsigned long *)calloc(mlen, sizeof(unsigned long)); ps = (unsigned long *)calloc(plen, sizeof(unsigned long)); val = XAllocColorCells(Xen_to_C_Display(arg1), Xen_to_C_Colormap(arg2), Xen_boolean_to_C_bool(arg3), ms, mlen, ps, plen); if (val != 0) { int i, loc1, loc2; loc1 = xm_protect(mlst); loc2 = xm_protect(plst); for (i = mlen - 1; i >= 0; i--) mlst = Xen_cons(C_ulong_to_Xen_ulong(ms[i]), mlst); for (i = plen - 1; i >= 0; i--) mlst = Xen_cons(C_ulong_to_Xen_ulong(ps[i]), plst); xm_unprotect_at(loc1); xm_unprotect_at(loc2); } free(ms); free(ps); if (val != 0) return(Xen_list_3(C_int_to_Xen_integer(val), mlst, plst)); return(Xen_false); } static Xen gxm_XAllocColor(Xen arg1, Xen arg2, Xen arg3) { #define H_XAllocColor "Status XAllocColor(display, colormap, screen_in_out) allocates a read-only colormap entry corresponding to the \ closest RGB value supported by the hardware." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XAllocColor", "Display*"); Xen_check_type(Xen_is_Colormap(arg2), arg2, 2, "XAllocColor", "Colormap"); Xen_check_type(Xen_is_XColor(arg3), arg3, 3, "XAllocColor", "XColor"); return(C_int_to_Xen_integer(XAllocColor(Xen_to_C_Display(arg1), Xen_to_C_Colormap(arg2), Xen_to_C_XColor(arg3)))); } static Xen gxm_XActivateScreenSaver(Xen arg1) { #define H_XActivateScreenSaver "XActivateScreenSaver(display) activates the screen saver." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XActivateScreenSaver", "Display*"); return(C_int_to_Xen_integer(XActivateScreenSaver(Xen_to_C_Display(arg1)))); } static Xen gxm_XSetTransientForHint(Xen arg1, Xen arg2, Xen arg3) { #define H_XSetTransientForHint "XSetTransientForHint(display, w, prop_window) sets the WM_TRANSIENT_FOR property of the specified \ window to the specified prop_window." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XSetTransientForHint", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XSetTransientForHint", "Window"); Xen_check_type(Xen_is_Window(arg3), arg3, 3, "XSetTransientForHint", "Window"); return(C_int_to_Xen_integer(XSetTransientForHint(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_to_C_Window(arg3)))); } static Xen gxm_XSetWMColormapWindows(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XSetWMColormapWindows "Status XSetWMColormapWindows(display, w, colormap_windows, count) replaces the WM_COLORMAP_WINDOWS property \ on the specified window with the list of windows specified by the colormap_windows argument." /* DIFF: XSetWMColormapWindows arg 3 is list of Windows */ int len, rtn; Window *ws; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XSetWMColormapWindows", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XSetWMColormapWindows", "Window"); Xen_check_type(Xen_is_list(arg3), arg3, 3, "XSetWMColormapWindows", "list of Windows"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XSetWMColormapWindows", "int"); len = Xen_integer_to_C_int(arg4); if (len <= 0) return(Xen_false); ws = Xen_to_C_Windows(arg3, len); rtn = XSetWMColormapWindows(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), ws, len); free(ws); return(C_int_to_Xen_integer(rtn)); } static Xen gxm_XGetWMColormapWindows(Xen arg1, Xen arg2) { #define H_XGetWMColormapWindows "Status XGetWMColormapWindows(display, w): returns the list of \ window identifiers stored in the WM_COLORMAP_WINDOWS property on the specified window." /* DIFF: XGetWMColormapWindows omit last 2 args, return list of windows */ Xen lst = Xen_empty_list; int i, len, rtn, loc; Window *ws; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XGetWMColormapWindows", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XGetWMColormapWindows", "Window"); rtn = XGetWMColormapWindows(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), &ws, &len); if (rtn == 0) return(Xen_false); loc = xm_protect(lst); for (i = len - 1; i >= 0; i--) lst = Xen_cons(C_to_Xen_Window(ws[i]), lst); xm_unprotect_at(loc); XFree(ws); return(lst); } static Xen gxm_XGetCommand(Xen arg1, Xen arg2) { #define H_XGetCommand "Status XGetCommand(display, w) reads the WM_COMMAND property from the specified window \ and returns a string list." /* DIFF: XGetCommand omits last 2 args, returns list */ char **argv; int argc; Xen lst = Xen_empty_list; Status err; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XGetCommand", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XGetCommand", "Window"); err = XGetCommand(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), &argv, &argc); if (err != 0) { int i, loc; loc = xm_protect(lst); for (i = argc - 1; i >= 0; i--) lst = Xen_cons(C_string_to_Xen_string(argv[i]), lst); XFreeStringList(argv); xm_unprotect_at(loc); } return(lst); } static Xen gxm_XWithdrawWindow(Xen arg1, Xen arg2, Xen arg3) { #define H_XWithdrawWindow "Status XWithdrawWindow(display, w, screen_number) unmaps the specified window and sends a synthetic \ UnmapNotify event to the root window of the specified screen." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XWithdrawWindow", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XWithdrawWindow", "Window"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XWithdrawWindow", "int"); return(C_int_to_Xen_integer(XWithdrawWindow(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_integer_to_C_int(arg3)))); } static Xen gxm_XIconifyWindow(Xen arg1, Xen arg2, Xen arg3) { #define H_XIconifyWindow "Status XIconifyWindow(display, w, screen_number) sends a WM_CHANGE_STATE ClientMessage event with a format of \ 32 and a first data element of IconicState to the root window of the specified screen with an event mask set to \ SubstructureNotifyMask | SubstructureRedirectMask." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XIconifyWindow", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XIconifyWindow", "Window"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XIconifyWindow", "int"); return(C_int_to_Xen_integer(XIconifyWindow(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_integer_to_C_int(arg3)))); } static Xen gxm_XSetWMProtocols(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XSetWMProtocols "Status XSetWMProtocols(display, w, protocols, count) replaces the WM_PROTOCOLS property on the \ specified window with the list of atoms specified by the protocols argument." /* DIFF: XSetWMProtocols arg3 is list of atoms */ Atom *outs; int val, len; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XSetWMProtocols", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XSetWMProtocols", "Window"); Xen_check_type(Xen_is_list(arg3), arg3, 3, "XSetWMProtocols", "list of Atom"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XSetWMProtocols", "int"); len = Xen_integer_to_C_int(arg4); if (len <= 0) return(Xen_false); outs = Xen_to_C_Atoms(arg3, len); val = XSetWMProtocols(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), outs, len); free(outs); return(C_int_to_Xen_integer(val)); } static Xen gxm_XGetWMProtocols(Xen arg1, Xen arg2) { #define H_XGetWMProtocols "Status XGetWMProtocols(display, w): returns the list of atoms stored in the \ WM_PROTOCOLS property on the specified window." /* DIFF: XGetWMProtocols omits last 2 args, returns list */ Atom *ats; int len, i, val, loc; Xen lst = Xen_empty_list; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XGetWMProtocols", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XGetWMProtocols", "Window"); val = XGetWMProtocols(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), &ats, &len); if (val == 0) return(Xen_false); loc = xm_protect(lst); for (i = len - 1; i >= 0; i--) lst = Xen_cons(C_to_Xen_Atom(ats[i]), lst); xm_unprotect_at(loc); XFree((void *)ats); return(lst); } static Xen gxm_XReconfigureWMWindow(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5) { #define H_XReconfigureWMWindow "Status XReconfigureWMWindow(display, w, screen_number, value_mask, values) issues a ConfigureWindow \ request on the specified top-level window." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XReconfigureWMWindow", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XReconfigureWMWindow", "Window"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XReconfigureWMWindow", "int"); Xen_check_type(Xen_is_ulong(arg4), arg4, 4, "XReconfigureWMWindow", "unsigned int"); Xen_check_type(Xen_is_XWindowChanges(arg5), arg5, 5, "XReconfigureWMWindow", "XWindowChanges*"); return(C_int_to_Xen_integer(XReconfigureWMWindow(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_integer_to_C_int(arg3), Xen_ulong_to_C_ulong(arg4), Xen_to_C_XWindowChanges(arg5)))); } static Xen gxm_XListDepths(Xen arg1, Xen arg2) { #define H_XListDepths "int *XListDepths(display, screen_number): returns the array of depths that are available on the \ specified screen." /* DIFF: XListDepths omits last arg, returns list of depths */ Xen lst = Xen_empty_list; int i, len, loc; int *ds; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XListDepths", "Display*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XListDepths", "int"); ds = XListDepths(Xen_to_C_Display(arg1), Xen_integer_to_C_int(arg2), &len); loc = xm_protect(lst); for (i = len - 1; i >= 0; i--) lst = Xen_cons(C_int_to_Xen_integer(ds[i]), lst); XFree(ds); xm_unprotect_at(loc); return(lst); } static Xen gxm_XListPixmapFormats(Xen arg1) { #define H_XListPixmapFormats "XPixmapFormatValues *XListPixmapFormats(display): returns an array of XPixmapFormatValues \ structures that describe the types of Z format images supported by the specified display." /* DIFF: XListPixmapFormats omits arg2, rtns list of lists, each holding XPixmapFormatValues data */ XPixmapFormatValues *ps; int len, loc; Xen lst = Xen_empty_list; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XListPixmapFormats", "Display*"); ps = XListPixmapFormats(Xen_to_C_Display(arg1), &len); loc = xm_protect(lst); if (ps) { int i; for (i = len - 1; i >= 0; i--) lst = Xen_cons(Xen_list_3(C_int_to_Xen_integer(ps[i].depth), C_int_to_Xen_integer(ps[i].bits_per_pixel), C_int_to_Xen_integer(ps[i].scanline_pad)), lst); free(ps); } xm_unprotect_at(loc); return(lst); } static Xen xm_XIOErrorHandler; static int gxm_XIOErrorHandler(Display *dpy) { Xen_call_with_1_arg(xm_XIOErrorHandler, C_to_Xen_Display(dpy), __func__); return(0); /* never happens */ } static Xen gxm_XSetIOErrorHandler(Xen arg1) { #define H_XSetIOErrorHandler "int (*XSetIOErrorHandler(handler))() sets the fatal I/O error handler. " Xen old_val; Xen_check_type(Xen_is_false(arg1) || Xen_is_procedure(arg1), arg1, 1, "XSetIOErrorHandler", PROC_FALSE "=null or function of 1 arg"); xm_protect(arg1); old_val = xm_XIOErrorHandler; xm_XIOErrorHandler = arg1; if (Xen_is_false(arg1)) XSetIOErrorHandler(NULL); else XSetIOErrorHandler(gxm_XIOErrorHandler); if (Xen_is_procedure(old_val)) xm_unprotect(old_val); /* hmmm... what if we're gc'd on the way back? */ return(old_val); } static Xen xm_XErrorHandler; static int gxm_XErrorHandler(Display *dpy, XErrorEvent *e) { Xen_call_with_2_args(xm_XErrorHandler, C_to_Xen_Display(dpy), C_to_Xen_XErrorEvent((XErrorEvent *)e), __func__); return(0); /* never happens */ } static Xen gxm_XSetErrorHandler(Xen arg1) { #define H_XSetErrorHandler "XSetErrorHandler(proc) causes proc to be called if an error occurs" Xen old_val; Xen_check_type(Xen_is_false(arg1) || Xen_is_procedure(arg1), arg1, 1, "XSetErrorHandler", PROC_FALSE "=null or function of 2 args"); xm_protect(arg1); old_val = xm_XErrorHandler; xm_XErrorHandler = arg1; if (Xen_is_false(arg1)) XSetErrorHandler(NULL); else XSetErrorHandler(gxm_XErrorHandler); if (Xen_is_procedure(old_val)) xm_unprotect(old_val); /* hmmm... what if we're gc'd on the way back? */ return(old_val); } static Xen gxm_XScreenNumberOfScreen(Xen arg1) { #define H_XScreenNumberOfScreen "int XScreenNumberOfScreen(screen): returns the screen index number of the specified screen." Xen_check_type(Xen_is_Screen(arg1), arg1, 1, "XScreenNumberOfScreen", "Screen*"); return(C_int_to_Xen_integer(XScreenNumberOfScreen(Xen_to_C_Screen(arg1)))); } static Xen gxm_XEventMaskOfScreen(Xen arg1) { #define H_EventMaskOfScreen "EventMaskOfScreen(screen): returns the root event mask of the root window for the specified screen at connection setup." Xen_check_type(Xen_is_Screen(arg1), arg1, 1, "XEventMaskOfScreen", "Screen*"); return(C_ulong_to_Xen_ulong(XEventMaskOfScreen(Xen_to_C_Screen(arg1)))); } static Xen gxm_XDefaultScreenOfDisplay(Xen arg1) { /* #define DefaultScreenOfDisplay(display) */ Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XDefaultScreenOfDisplay", "Display*"); return(C_to_Xen_Screen(XDefaultScreenOfDisplay(Xen_to_C_Display(arg1)))); } static Xen gxm_XScreenOfDisplay(Xen arg1, Xen arg2) { #define H_ScreenOfDisplay "ScreenOfDisplay(display, screen_number): returns a pointer to the screen of the specified display." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XScreenOfDisplay", "Display*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XScreenOfDisplay", "int"); return(C_to_Xen_Screen(XScreenOfDisplay(Xen_to_C_Display(arg1), Xen_integer_to_C_int(arg2)))); } static Xen gxm_XDisplayOfScreen(Xen arg1) { #define H_DisplayOfScreen "DisplayOfScreen(screen): returns the display of the specified screen." Xen_check_type(Xen_is_Screen(arg1), arg1, 1, "XDisplayOfScreen", "Screen*"); return(C_to_Xen_Display(XDisplayOfScreen(Xen_to_C_Screen(arg1)))); } static Xen gxm_XDefaultColormapOfScreen(Xen arg1) { #define H_DefaultColormapOfScreen "DefaultColormapOfScreen(screen): returns the default colormap of the specified screen." Xen_check_type(Xen_is_Screen(arg1), arg1, 1, "XDefaultColormapOfScreen", "Screen*"); return(C_to_Xen_Colormap(XDefaultColormapOfScreen(Xen_to_C_Screen(arg1)))); } static Xen gxm_XDefaultColormap(Xen arg1, Xen arg2) { #define H_DefaultColormap "DefaultColormap(display, screen_number): returns the default colormap ID for allocation on the specified screen." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XDefaultColormap", "Display*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XDefaultColormap", "int"); return(C_to_Xen_Colormap(XDefaultColormap(Xen_to_C_Display(arg1), Xen_integer_to_C_int(arg2)))); } static Xen gxm_XDisplayString(Xen arg1) { #define H_DisplayString "DisplayString(display): returns the string that was passed to XOpenDisplay when the current display was opened." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XDisplayString", "Display*"); return(C_string_to_Xen_string(XDisplayString(Xen_to_C_Display(arg1)))); } static Xen gxm_XServerVendor(Xen arg1) { #define H_ServerVendor "ServerVendor(display): returns a pointer to a null-terminated string that provides some identification of the \ owner of the X server implementation." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XServerVendor", "Display*"); return(C_string_to_Xen_string(XServerVendor(Xen_to_C_Display(arg1)))); } static Xen gxm_XLastKnownRequestProcessed(Xen arg1) { #define H_LastKnownRequestProcessed "LastKnownRequestProcessed(display) extracts the full serial number of the last request known by Xlib \ to have been processed by the X server." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XLastKnownRequestProcessed", "Display*"); return(C_ulong_to_Xen_ulong(XLastKnownRequestProcessed(Xen_to_C_Display(arg1)))); } static Xen gxm_XNextRequest(Xen arg1) { #define H_NextRequest "NextRequest(display) extracts the full serial number that is to be used for the next request." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XNextRequest", "Display*"); return(C_ulong_to_Xen_ulong(XNextRequest(Xen_to_C_Display(arg1)))); } static Xen gxm_XWhitePixelOfScreen(Xen arg1) { #define H_WhitePixelOfScreen "WhitePixelOfScreen(screen): returns the white pixel value of the specified screen." Xen_check_type(Xen_is_Screen(arg1), arg1, 1, "XWhitePixelOfScreen", "Screen*"); return(C_to_Xen_Pixel(XWhitePixelOfScreen(Xen_to_C_Screen(arg1)))); } static Xen gxm_XBlackPixelOfScreen(Xen arg1) { #define H_BlackPixelOfScreen "BlackPixelOfScreen(screen): returns the black pixel value of the specified screen." Xen_check_type(Xen_is_Screen(arg1), arg1, 1, "XBlackPixelOfScreen", "Screen*"); return(C_to_Xen_Pixel(XBlackPixelOfScreen(Xen_to_C_Screen(arg1)))); } static Xen gxm_XAllPlanes(void) { #define H_AllPlanes "Allplanes(): returns a value with all bits set to 1 suitable for use in a plane argument to a procedure." return(C_ulong_to_Xen_ulong(XAllPlanes())); } static Xen gxm_XWhitePixel(Xen arg1, Xen arg2) { #define H_WhitePixel "WhitePixel(display, screen_number): returns the white pixel value for the specified screen." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XWhitePixel", "Display*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XWhitePixel", "int"); return(C_to_Xen_Pixel(XWhitePixel(Xen_to_C_Display(arg1), Xen_integer_to_C_int(arg2)))); } static Xen gxm_XBlackPixel(Xen arg1, Xen arg2) { #define H_BlackPixel "BlackPixel(display, screen_number): returns the black pixel value for the specified screen." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XBlackPixel", "Display*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XBlackPixel", "int"); return(C_to_Xen_Pixel(XBlackPixel(Xen_to_C_Display(arg1), Xen_integer_to_C_int(arg2)))); } static Xen gxm_XDefaultGCOfScreen(Xen arg1) { #define H_DefaultGCOfScreen "DefaultGCOfScreen(screen): returns the default GC of the specified screen, which has the same depth as the root \ window of the screen." Xen_check_type(Xen_is_Screen(arg1), arg1, 1, "XDefaultGCOfScreen", "Screen*"); return(C_to_Xen_GC(XDefaultGCOfScreen(Xen_to_C_Screen(arg1)))); } static Xen gxm_XDefaultGC(Xen arg1, Xen arg2) { #define H_DefaultGC "DefaultGC(display, screen_number): returns the default GC for the root window of the " Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XDefaultGC", "Display*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XDefaultGC", "int"); return(C_to_Xen_GC(XDefaultGC(Xen_to_C_Display(arg1), Xen_integer_to_C_int(arg2)))); } static Xen gxm_XDefaultVisualOfScreen(Xen arg1) { #define H_DefaultVisualOfScreen "DefaultVisualOfScreen(screen): returns the default visual of the specified screen." Xen_check_type(Xen_is_Screen(arg1), arg1, 1, "XDefaultVisualOfScreen", "Screen*"); return(C_to_Xen_Visual(XDefaultVisualOfScreen(Xen_to_C_Screen(arg1)))); } static Xen gxm_XDefaultVisual(Xen arg1, Xen arg2) { #define H_DefaultVisual "DefaultVisual(display, screen_number): returns the default visual type for the specified screen." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XDefaultVisual", "Display*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XDefaultVisual", "int"); return(C_to_Xen_Visual(XDefaultVisual(Xen_to_C_Display(arg1), Xen_integer_to_C_int(arg2)))); } static Xen gxm_XRootWindowOfScreen(Xen arg1) { #define H_RootWindowOfScreen "RootWindowOfScreen(screen): returns the root window of the specified screen." Xen_check_type(Xen_is_Screen(arg1), arg1, 1, "XRootWindowOfScreen", "Screen*"); return(C_to_Xen_Window(XRootWindowOfScreen(Xen_to_C_Screen(arg1)))); } static Xen gxm_XDefaultRootWindow(Xen arg1) { #define H_DefaultRootWindow "DefaultRootWindow(display): returns the root window for the default screen." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XDefaultRootWindow", "Display*"); return(C_to_Xen_Window(XDefaultRootWindow(Xen_to_C_Display(arg1)))); } static Xen gxm_XRootWindow(Xen arg1, Xen arg2) { #define H_RootWindow "RootWindow(display, screen_number): returns the root window." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XRootWindow", "Display*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XRootWindow", "int"); return(C_to_Xen_Window(XRootWindow(Xen_to_C_Display(arg1), Xen_integer_to_C_int(arg2)))); } static Xen gxm_XVisualIDFromVisual(Xen arg1) { #define H_XVisualIDFromVisual "VisualID XVisualIDFromVisual(visual): returns the visual ID for the specified visual type." Xen_check_type(Xen_is_Visual(arg1), arg1, 1, "XVisualIDFromVisual", "Visual*"); return(C_ulong_to_Xen_ulong(XVisualIDFromVisual(Xen_to_C_Visual(arg1)))); } static Xen gxm_XDisplayMotionBufferSize(Xen arg1) { #define H_XDisplayMotionBufferSize "unsigned long XDisplayMotionBufferSize(display)" Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XDisplayMotionBufferSize", "Display*"); return(C_ulong_to_Xen_ulong(XDisplayMotionBufferSize(Xen_to_C_Display(arg1)))); } static Xen gxm_XExtendedMaxRequestSize(Xen arg1) { #define H_XExtendedMaxRequestSize "long XExtendedMaxRequestSize(display): returns zero if the specified display does not support an \ extended-length protocol encoding; otherwise, it returns the maximum request size (in 4-byte units) supported by the server using the \ extended-length encoding." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XExtendedMaxRequestSize", "Display*"); return(C_int_to_Xen_integer(XExtendedMaxRequestSize(Xen_to_C_Display(arg1)))); } static Xen gxm_XMaxRequestSize(Xen arg1) { #define H_XMaxRequestSize "long XMaxRequestSize(display): returns the maximum request size (in 4-byte units) supported by the server \ without using an extended-length protocol encoding." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XMaxRequestSize", "Display*"); return(C_int_to_Xen_integer(XMaxRequestSize(Xen_to_C_Display(arg1)))); } static Xen gxm_XStringToKeysym(Xen arg1) { #define H_XStringToKeysym "KeySym XStringToKeysym(string)" Xen_check_type(Xen_is_string(arg1), arg1, 1, "XStringToKeysym", "char*"); return(C_to_Xen_KeySym(XStringToKeysym((char *)Xen_string_to_C_string(arg1)))); } static Xen gxm_XGetKeyboardMapping(Xen arg1, Xen arg2, Xen arg3) { #define H_XGetKeyboardMapping "KeySym *XGetKeyboardMapping(display, first_keycode, keycode_count): returns \ the symbols for the specified number of KeyCodes starting with first_keycode." /* DIFF: XGetKeyboardMapping omits last arg, returns list of keys */ int n, i, len, count, loc; KeySym *keys; Xen lst = Xen_empty_list; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XGetKeyboardMapping", "Display*"); Xen_check_type(Xen_is_KeyCode(arg2), arg2, 2, "XGetKeyboardMapping", "KeyCode"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XGetKeyboardMapping", "int"); count = Xen_integer_to_C_int(arg3); keys = XGetKeyboardMapping(Xen_to_C_Display(arg1), Xen_to_C_KeyCode(arg2), count, &n); len = count * n; loc = xm_protect(lst); for (i = len - 1; i >= 0; i--) lst = Xen_cons(C_to_Xen_KeySym(keys[i]), lst); XFree(keys); xm_unprotect_at(loc); return(lst); } static Xen gxm_XLookupKeysym(Xen arg1, Xen arg2) { #define H_XLookupKeysym "KeySym XLookupKeysym(key_event, index) uses a given keyboard event and the index you specified to return \ the KeySym from the list that corresponds to the KeyCode member in the XKeyPressedEvent or XKeyReleasedEvent structure." Xen_check_type(Xen_is_XKeyEvent(arg1), arg1, 1, "XLookupKeysym", "XKeyEvent*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XLookupKeysym", "int"); return(C_to_Xen_KeySym(XLookupKeysym(Xen_to_C_XKeyEvent(arg1), Xen_integer_to_C_int(arg2)))); } #if 0 /* this has been deprecated for XkbKeycodeToKeysym */ static Xen gxm_XKeycodeToKeysym(Xen arg1, Xen arg2, Xen arg3) { #define H_XKeycodeToKeysym "KeySym XKeycodeToKeysym(display, keycode, index) uses internal Xlib tables and returns the KeySym defined \ for the specified KeyCode and the element of the KeyCode vector." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XKeycodeToKeysym", "Display*"); Xen_check_type(Xen_is_KeyCode(arg2), arg2, 2, "XKeycodeToKeysym", "KeyCode"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XKeycodeToKeysym", "int"); return(C_to_Xen_KeySym(XKeycodeToKeysym(Xen_to_C_Display(arg1), Xen_to_C_KeyCode(arg2), Xen_integer_to_C_int(arg3)))); } #endif static Xen gxm_XListProperties(Xen arg1, Xen arg2) { #define H_XListProperties "Atom *XListProperties(display, w): returns a pointer to an array of atom properties that \ are defined for the specified window or returns NULL if no properties were found." /* DIFF: XListProperties returns list, no arg3 */ int i, len, loc; Xen lst = Xen_empty_list; Atom *ats; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XListProperties", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XListProperties", "Window"); ats = XListProperties(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), &len); if (ats == NULL) return(Xen_false); loc = xm_protect(lst); for (i = len - 1; i >= 0; i--) lst = Xen_cons(C_to_Xen_Atom(ats[i]), lst); xm_unprotect_at(loc); XFree(ats); return(lst); } static Xen gxm_XListExtensions(Xen arg1) { #define H_XListExtensions "XListExtensions(dpy): list of strings describing available extensions" /* DIFF: XListExtensions omits arg2, returns list */ int i, len, loc; Xen lst = Xen_empty_list; char **str; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XListExtensions", "Display*"); str = XListExtensions(Xen_to_C_Display(arg1), &len); loc = xm_protect(lst); for (i = len - 1; i >= 0; i--) lst = Xen_cons(C_string_to_Xen_string(str[i]), lst); XFreeExtensionList(str); xm_unprotect_at(loc); return(lst); } static Xen gxm_XGetFontPath(Xen arg1) { #define H_XGetFontPath "char **XGetFontPath(display) allocates and returns an array of strings containing the search path." /* DIFF: XGetFontPath omits arg2, returns list */ int i, len, loc; Xen lst = Xen_empty_list; char **str; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XGetFontPath", "Display*"); str = XGetFontPath(Xen_to_C_Display(arg1), &len); loc = xm_protect(lst); for (i = len - 1; i >= 0; i--) lst = Xen_cons(C_string_to_Xen_string(str[i]), lst); XFreeFontPath(str); xm_unprotect_at(loc); return(lst); } static Xen gxm_XListFontsWithInfo(Xen arg1, Xen arg2, Xen arg3) { #define H_XListFontsWithInfo "char **XListFontsWithInfo(display, pattern, maxnames): returns a list of \ font names that match the specified pattern and their associated font information." /* DIFF: XListFontsWithInfo omit last 2 args, returns list of lists */ int i, count, loc; XFontStruct *info; char **val; Xen lst = Xen_empty_list; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XListFontsWithInfo", "Display*"); Xen_check_type(Xen_is_string(arg2), arg2, 2, "XListFontsWithInfo", "char*"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XListFontsWithInfo", "int"); val = XListFontsWithInfo(Xen_to_C_Display(arg1), (char *)Xen_string_to_C_string(arg2), Xen_integer_to_C_int(arg3), &count, &info); loc = xm_protect(lst); for (i = count - 1; i >= 0; i--) lst = Xen_cons(Xen_list_2(C_string_to_Xen_string(val[i]), C_to_Xen_XFontStruct(&(info[i]))), lst); XFreeFontInfo(val, info, count); /* XFreeFontNames(val); */ xm_unprotect_at(loc); return(lst); } static Xen gxm_XListFonts(Xen arg1, Xen arg2, Xen arg3) { #define H_XListFonts "char **XListFonts(display, pattern, maxnames): returns an array of available font names that match \ the string you passed to the pattern argument." /* DIFF: XListFonts omits arg4, returns list */ int i, len, loc; Xen lst = Xen_empty_list; char **str; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XListFonts", "Display*"); Xen_check_type(Xen_is_string(arg2), arg2, 2, "XListFonts", "char*"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XListFonts", "int"); str = XListFonts(Xen_to_C_Display(arg1), (char *)Xen_string_to_C_string(arg2), Xen_integer_to_C_int(arg3), &len); loc = xm_protect(lst); for (i = len - 1; i >= 0; i--) lst = Xen_cons(C_string_to_Xen_string(str[i]), lst); XFreeFontNames(str); xm_unprotect_at(loc); return(lst); } static Xen gxm_XListInstalledColormaps(Xen arg1, Xen arg2) { #define H_XListInstalledColormaps "Colormap *XListInstalledColormaps(display, w): returns a list of the currently installed \ colormaps for the screen of the specified window." /* DIFF: XListInstalledColormaps omits last arg, rtns list of XColormaps */ Colormap *cm; int i, len, loc; Xen lst = Xen_empty_list; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XListInstalledColormaps", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XListInstalledColormaps", "Window"); cm = XListInstalledColormaps(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), &len); loc = xm_protect(lst); for (i = len - 1; i >= 0; i--) lst = Xen_cons(C_to_Xen_Colormap(cm[i]), lst); free(cm); xm_unprotect_at(loc); return(lst); } static Xen gxm_XCreateWindow(Xen args) { #define H_XCreateWindow "Window XCreateWindow(display, parent, x, y, width, height, border_width, depth, class, visual, valuemask, attributes) \ creates an unmapped subwindow for a specified parent window, returns the window ID of the created window, and causes the X server to generate \ a CreateNotify event." Xen arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12; arg1 = Xen_list_ref(args, 0); arg2 = Xen_list_ref(args, 1); arg3 = Xen_list_ref(args, 2); arg4 = Xen_list_ref(args, 3); arg5 = Xen_list_ref(args, 4); arg6 = Xen_list_ref(args, 5); arg7 = Xen_list_ref(args, 6); arg8 = Xen_list_ref(args, 7); arg9 = Xen_list_ref(args, 8); arg10 = Xen_list_ref(args, 9); arg11 = Xen_list_ref(args, 10); arg12 = Xen_list_ref(args, 11); Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XCreateWindow", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XCreateWindow", "Window"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XCreateWindow", "int"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XCreateWindow", "int"); Xen_check_type(Xen_is_ulong(arg5), arg5, 5, "XCreateWindow", "unsigned int"); Xen_check_type(Xen_is_ulong(arg6), arg6, 6, "XCreateWindow", "unsigned int"); Xen_check_type(Xen_is_ulong(arg7), arg7, 7, "XCreateWindow", "unsigned int"); Xen_check_type(Xen_is_integer(arg8), arg8, 8, "XCreateWindow", "int"); Xen_check_type(Xen_is_ulong(arg9), arg9, 9, "XCreateWindow", "unsigned int"); Xen_check_type(Xen_is_Visual(arg10), arg10, 10, "XCreateWindow", "Visual*"); Xen_check_type(Xen_is_ulong(arg11), arg11, 11, "XCreateWindow", "ulong"); Xen_check_type(Xen_is_XSetWindowAttributes(arg12), arg12, 12, "XCreateWindow", "XSetWindowAttributes*"); return(C_to_Xen_Window(XCreateWindow(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_integer_to_C_int(arg3), Xen_integer_to_C_int(arg4), Xen_ulong_to_C_ulong(arg5), Xen_ulong_to_C_ulong(arg6), Xen_ulong_to_C_ulong(arg7), Xen_integer_to_C_int(arg8), Xen_ulong_to_C_ulong(arg9), Xen_to_C_Visual(arg10), Xen_ulong_to_C_ulong(arg11), Xen_to_C_XSetWindowAttributes(arg12)))); } static Xen gxm_XGetSelectionOwner(Xen arg1, Xen arg2) { #define H_XGetSelectionOwner "Window XGetSelectionOwner(display, selection): returns the window ID associated with the window that \ currently owns the specified selection." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XGetSelectionOwner", "Display*"); Xen_check_type(Xen_is_Atom(arg2), arg2, 2, "XGetSelectionOwner", "Atom"); return(C_to_Xen_Window(XGetSelectionOwner(Xen_to_C_Display(arg1), Xen_to_C_Atom(arg2)))); } static Xen gxm_XCreateSimpleWindow(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6, Xen arg7, Xen arg8, Xen arg9) { #define H_XCreateSimpleWindow "Window XCreateSimpleWindow(display, parent, x, y, width, height, border_width, border, background) \ creates an unmapped InputOutput subwindow for a specified parent window, returns the window ID of the created window, and causes the X \ server to generate a CreateNotify event." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XCreateSimpleWindow", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XCreateSimpleWindow", "Window"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XCreateSimpleWindow", "int"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XCreateSimpleWindow", "int"); Xen_check_type(Xen_is_ulong(arg5), arg5, 5, "XCreateSimpleWindow", "unsigned int"); Xen_check_type(Xen_is_ulong(arg6), arg6, 6, "XCreateSimpleWindow", "unsigned int"); Xen_check_type(Xen_is_ulong(arg7), arg7, 7, "XCreateSimpleWindow", "unsigned int"); Xen_check_type(Xen_is_Pixel(arg8), arg8, 8, "XCreateSimpleWindow", "Pixel"); Xen_check_type(Xen_is_Pixel(arg9), arg9, 9, "XCreateSimpleWindow", "Pixel"); return(C_to_Xen_Window(XCreateSimpleWindow(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_integer_to_C_int(arg3), Xen_integer_to_C_int(arg4), Xen_ulong_to_C_ulong(arg5), Xen_ulong_to_C_ulong(arg6), Xen_ulong_to_C_ulong(arg7), Xen_to_C_Pixel(arg8), Xen_to_C_Pixel(arg9)))); } static Xen gxm_XCreatePixmapFromBitmapData(Xen arg1, Xen arg2, Xen larg3, Xen arg4, Xen arg5, Xen arg6, Xen arg7, Xen arg8) { #define H_XCreatePixmapFromBitmapData "Pixmap XCreatePixmapFromBitmapData(display, d, data, width, height, fg, bg, depth) creates a \ pixmap of the given depth and then does a bitmap-format XPutImage of the data into it." /* DIFF: XCreatePixmapFromBitmapData takes list of chars as arg3 (not char *) */ char *bits; int i, len; Pixmap p; Xen arg3; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XCreatePixmapFromBitmapData", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XCreatePixmapFromBitmapData", "Drawable"); Xen_check_type(Xen_is_list(larg3), larg3, 3, "XCreatePixmapFromBitmapData", "list of char"); Xen_check_type(Xen_is_ulong(arg4), arg4, 4, "XCreatePixmapFromBitmapData", "unsigned int"); Xen_check_type(Xen_is_ulong(arg5), arg5, 5, "XCreatePixmapFromBitmapData", "unsigned int"); Xen_check_type(Xen_is_Pixel(arg6), arg6, 6, "XCreatePixmapFromBitmapData", "pixel"); Xen_check_type(Xen_is_Pixel(arg7), arg7, 7, "XCreatePixmapFromBitmapData", "pixel"); Xen_check_type(Xen_is_ulong(arg8), arg8, 8, "XCreatePixmapFromBitmapData", "unsigned int"); len = Xen_list_length(larg3); if (len <= 0) Xen_check_type(0, larg3, 3, "XCreatePixmapFromBitmapData", "positive integer"); arg3 = Xen_copy_arg(larg3); bits = (char *)calloc(len, sizeof(char)); for (i = 0; i < len; i++, arg3 = Xen_cdr(arg3)) bits[i] = (char)Xen_integer_to_C_int(Xen_car(arg3)); p = XCreatePixmapFromBitmapData(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), bits, Xen_ulong_to_C_ulong(arg4), Xen_ulong_to_C_ulong(arg5), Xen_to_C_Pixel(arg6), Xen_to_C_Pixel(arg7), Xen_ulong_to_C_ulong(arg8)); free(bits); return(C_to_Xen_Pixmap(p)); } static Xen gxm_XCreateBitmapFromData(Xen arg1, Xen arg2, Xen larg3, Xen arg4, Xen arg5) { #define H_XCreateBitmapFromData "Pixmap XCreateBitmapFromData(display, d, data, width, height) allows you to include in your C \ program a bitmap file that was written out by XWriteBitmapFile" /* DIFF: XCreateBitmapFromData takes list of chars as arg3 (not char *) */ char *bits; int i, len; Pixmap p; Xen arg3; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XCreateBitmapFromData", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XCreateBitmapFromData", "Drawable"); Xen_check_type(Xen_is_list(larg3), larg3, 3, "XCreateBitmapFromData", "list of char"); Xen_check_type(Xen_is_ulong(arg4), arg4, 4, "XCreateBitmapFromData", "unsigned int"); Xen_check_type(Xen_is_ulong(arg5), arg5, 5, "XCreateBitmapFromData", "unsigned int"); len = Xen_list_length(larg3); if (len <= 0) Xen_check_type(0, larg3, 3, "XCreateBitmapFromData", "positive integer"); arg3 = Xen_copy_arg(larg3); bits = (char *)calloc(len, sizeof(char)); for (i = 0; i < len; i++, arg3 = Xen_cdr(arg3)) bits[i] = (char)Xen_integer_to_C_int(Xen_car(arg3)); p = XCreateBitmapFromData(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), bits, Xen_ulong_to_C_ulong(arg4), Xen_ulong_to_C_ulong(arg5)); free(bits); return(C_to_Xen_Pixmap(p)); } static Xen gxm_XCreatePixmap(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5) { #define H_XCreatePixmap "Pixmap XCreatePixmap(display, d, width, height, depth)" Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XCreatePixmap", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XCreatePixmap", "Drawable"); Xen_check_type(Xen_is_ulong(arg3), arg3, 3, "XCreatePixmap", "unsigned int"); Xen_check_type(Xen_is_ulong(arg4), arg4, 4, "XCreatePixmap", "unsigned int"); Xen_check_type(Xen_is_ulong(arg5), arg5, 5, "XCreatePixmap", "unsigned int"); return(C_to_Xen_Pixmap(XCreatePixmap(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_ulong_to_C_ulong(arg3), Xen_ulong_to_C_ulong(arg4), Xen_ulong_to_C_ulong(arg5)))); } static Xen gxm_XFlushGC(Xen arg1, Xen arg2) { #define H_XFlushGC "XFlushGC(dpy, gc) forces cached GC changes to X server" Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XFlushGC", "Display*"); Xen_check_type(Xen_is_GC(arg2), arg2, 2, "XFlushGC", "GC"); XFlushGC(Xen_to_C_Display(arg1), Xen_to_C_GC(arg2)); return(Xen_false); } static Xen gxm_XCreateGC(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XCreateGC "GC XCreateGC(display, d, valuemask, values) creates a graphics context and returns a GC." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XCreateGC", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XCreateGC", "Drawable"); Xen_check_type(Xen_is_ulong(arg3), arg3, 3, "XCreateGC", "ulong"); Xen_check_type(Xen_is_XGCValues(arg4), arg4, 4, "XCreateGC", "XGCValues*"); return(C_to_Xen_GC(XCreateGC(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_ulong_to_C_ulong(arg3), Xen_to_C_XGCValues(arg4)))); } static Xen gxm_XLoadFont(Xen arg1, Xen arg2) { #define H_XLoadFont "Font XLoadFont(display, name) loads the specified font and returns its associated font ID." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XLoadFont", "Display*"); Xen_check_type(Xen_is_string(arg2), arg2, 2, "XLoadFont", "char*"); return(C_to_Xen_Font(XLoadFont(Xen_to_C_Display(arg1), (char *)Xen_string_to_C_string(arg2)))); } static Xen gxm_XCreateFontCursor(Xen arg1, Xen arg2) { #define H_XCreateFontCursor "Cursor XCreateFontCursor(display, shape)" Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XCreateFontCursor", "Display*"); Xen_check_type(Xen_is_ulong(arg2), arg2, 2, "XCreateFontCursor", "unsigned int"); return(C_to_Xen_Cursor(XCreateFontCursor(Xen_to_C_Display(arg1), Xen_ulong_to_C_ulong(arg2)))); } static Xen gxm_XCreateGlyphCursor(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6, Xen arg7) { #define H_XCreateGlyphCursor "Cursor XCreateGlyphCursor(display, source_font, mask_font, source_char, mask_char, foreground_color, \ background_color) is similar to XCreatePixmapCursor except that the source and mask bitmaps are obtained from the specified font glyphs." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XCreateGlyphCursor", "Display*"); Xen_check_type(Xen_is_Font(arg2), arg2, 2, "XCreateGlyphCursor", "Font"); Xen_check_type(Xen_is_Font(arg3) || Xen_is_integer(arg3) || Xen_is_false(arg3), arg3, 3, "XCreateGlyphCursor", "Font"); Xen_check_type(Xen_is_ulong(arg4), arg4, 4, "XCreateGlyphCursor", "unsigned int"); Xen_check_type(Xen_is_ulong(arg5), arg5, 5, "XCreateGlyphCursor", "unsigned int"); Xen_check_type(Xen_is_XColor(arg6), arg6, 6, "XCreateGlyphCursor", "XColor"); Xen_check_type(Xen_is_XColor(arg7), arg7, 7, "XCreateGlyphCursor", "XColor"); return(C_to_Xen_Cursor(XCreateGlyphCursor(Xen_to_C_Display(arg1), Xen_to_C_Font(arg2), (Xen_is_Font(arg3)) ? Xen_to_C_Font(arg3) : None, Xen_ulong_to_C_ulong(arg4), Xen_ulong_to_C_ulong(arg5), Xen_to_C_XColor(arg6), Xen_to_C_XColor(arg7)))); } static Xen gxm_XCreatePixmapCursor(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6, Xen arg7) { #define H_XCreatePixmapCursor "Cursor XCreatePixmapCursor(display, source, mask, foreground_color, background_color, x, y) creates \ a cursor and returns the cursor ID associated with it." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XCreatePixmapCursor", "Display*"); Xen_check_type(Xen_is_Pixmap(arg2), arg2, 2, "XCreatePixmapCursor", "Pixmap"); Xen_check_type(Xen_is_Pixmap(arg3) || Xen_is_integer(arg3) || Xen_is_false(arg3), arg3, 3, "XCreatePixmapCursor", "Pixmap"); Xen_check_type(Xen_is_XColor(arg4), arg4, 4, "XCreatePixmapCursor", "XColor"); Xen_check_type(Xen_is_XColor(arg5), arg5, 5, "XCreatePixmapCursor", "XColor"); Xen_check_type(Xen_is_ulong(arg6), arg6, 6, "XCreatePixmapCursor", "unsigned int"); Xen_check_type(Xen_is_ulong(arg7), arg7, 7, "XCreatePixmapCursor", "unsigned int"); return(C_to_Xen_Cursor(XCreatePixmapCursor(Xen_to_C_Display(arg1), Xen_to_C_Pixmap(arg2), (Xen_is_Pixmap(arg3)) ? Xen_to_C_Pixmap(arg3) : None, Xen_to_C_XColor(arg4), Xen_to_C_XColor(arg5), Xen_ulong_to_C_ulong(arg6), Xen_ulong_to_C_ulong(arg7)))); } static Xen gxm_XCreateColormap(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XCreateColormap "Colormap XCreateColormap(display, w, visual, alloc) creates a colormap of the specified visual type for \ the screen on which the specified window resides and returns the colormap ID associated with it." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XCreateColormap", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XCreateColormap", "Window"); Xen_check_type(Xen_is_Visual(arg3), arg3, 3, "XCreateColormap", "Visual*"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XCreateColormap", "int"); return(C_to_Xen_Colormap(XCreateColormap(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_to_C_Visual(arg3), Xen_integer_to_C_int(arg4)))); } static Xen gxm_XCopyColormapAndFree(Xen arg1, Xen arg2) { #define H_XCopyColormapAndFree "Colormap XCopyColormapAndFree(display, colormap) creates a colormap of the same visual type and \ for the same screen as the specified colormap and returns the new colormap ID." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XCopyColormapAndFree", "Display*"); Xen_check_type(Xen_is_Colormap(arg2), arg2, 2, "XCopyColormapAndFree", "Colormap"); return(C_to_Xen_Colormap(XCopyColormapAndFree(Xen_to_C_Display(arg1), Xen_to_C_Colormap(arg2)))); } static Xen gxm_XInternAtom(Xen arg1, Xen arg2, Xen arg3) { #define H_XInternAtom "Atom XInternAtom(display, atom_name, only_if_exists): returns the atom identifier associated with the specified atom_name string." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XInternAtom", "Display*"); Xen_check_type(Xen_is_string(arg2), arg2, 2, "XInternAtom", "char*"); Xen_check_type(Xen_is_boolean(arg3), arg3, 3, "XInternAtom", "Bool"); return(C_to_Xen_Atom(XInternAtom(Xen_to_C_Display(arg1), (char *)Xen_string_to_C_string(arg2), Xen_boolean_to_C_bool(arg3)))); } static Xen xm_AfterFunction; static int default_after_function(Display *ignore) {return(0);} static int gxm_AfterFunction(Display *dpy) { return(Xen_integer_to_C_int(Xen_call_with_1_arg(xm_AfterFunction, C_to_Xen_Display(dpy), __func__))); } static Xen gxm_XSetAfterFunction(Xen arg1, Xen arg2) { #define H_XSetAfterFunction "XSetAfterFunction(dpy, proc) sets a function (one arg: dpy) to be called after every X function call" Xen old_func; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XSetAfterFunction", "Display*"); xm_protect(arg2); old_func = xm_AfterFunction; xm_AfterFunction = arg2; if (Xen_is_procedure(arg2)) XSetAfterFunction(Xen_to_C_Display(arg1), gxm_AfterFunction); else XSetAfterFunction(Xen_to_C_Display(arg1), default_after_function); if (Xen_is_procedure(old_func)) xm_unprotect(old_func); return(old_func); } static Xen gxm_XSynchronize(Xen arg1, Xen arg2) { #define H_XSynchronize "int (*XSynchronize(display, onoff))() turns on/off synchronous behavior." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XSynchronize", "Display*"); Xen_check_type(Xen_is_boolean(arg2), arg2, 2, "XSynchronize", "boolean"); XSynchronize(Xen_to_C_Display(arg1), Xen_boolean_to_C_bool(arg2)); return(xm_AfterFunction); } static Xen gxm_XKeysymToString(Xen arg1) { #define H_XKeysymToString "char *XKeysymToString(keysym)" Xen_check_type(Xen_is_KeySym(arg1), arg1, 1, "XKeysymToString", "KeySym"); return(C_string_to_Xen_string(XKeysymToString(Xen_to_C_KeySym(arg1)))); } static Xen gxm_XDisplayName(Xen arg1) { #define H_XDisplayName "char *XDisplayName(string): returns the name of the display that XOpenDisplay would attempt to use." Xen_check_type(Xen_is_string(arg1), arg1, 1, "XDisplayName", "char*"); return(C_string_to_Xen_string(XDisplayName((char *)Xen_string_to_C_string(arg1)))); } static Xen gxm_XGetAtomName(Xen arg1, Xen arg2) { #define H_XGetAtomName "char *XGetAtomName(display, atom): returns the name associated with the specified atom." char *str; Xen res; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XGetAtomName", "Display*"); Xen_check_type(Xen_is_Atom(arg2), arg2, 2, "XGetAtomName", "Atom"); str = XGetAtomName(Xen_to_C_Display(arg1), Xen_to_C_Atom(arg2)); res = C_string_to_Xen_string(str); XFree(str); return(res); } static Xen gxm_XFetchBuffer(Xen arg1, Xen arg2) { #define H_XFetchBuffer "char *XFetchBuffer(display, buffer): returns " PROC_FALSE " if there \ is no data in the buffer or if an invalid buffer is specified, otherwise a string." int len = 0; char *buf; Xen lst = Xen_false; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XFetchBuffer", "Display*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XFetchBuffer", "int"); buf = XFetchBuffer(Xen_to_C_Display(arg1), &len, Xen_integer_to_C_int(arg2)); if (len > 0) { lst = C_string_to_Xen_string(buf); free(buf); } return(lst); } static Xen gxm_XFetchBytes(Xen arg1) { #define H_XFetchBytes "char *XFetchBytes(display): returns the string in cut buffer 0" /* DIFF: XFetchBytes returns string, omits arg2 */ int len = 0; char *buf; Xen lst = Xen_false; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XFetchBytes", "Display*"); buf = XFetchBytes(Xen_to_C_Display(arg1), &len); if (len > 0) { lst = C_string_to_Xen_string(buf); free(buf); } return(lst); } static Xen gxm_XOpenDisplay(Xen arg1) { #define H_XOpenDisplay "Display *XOpenDisplay(display_name): returns a Display structure that serves as the connection to the X server \ and that contains all the information about that X server." Display *dpy; Xen_check_type(Xen_is_string(arg1) || Xen_is_false(arg1), arg1, 1, "XOpenDisplay", "char*"); dpy = XOpenDisplay(Xen_is_false(arg1) ? NULL : (char *)Xen_string_to_C_string(arg1)); if (dpy) return(C_to_Xen_Display(dpy)); return(Xen_false); } static Xen gxm_XGetSubImage(Xen args) { #define H_XGetSubImage "XImage *XGetSubImage(display, d, x, y, width, height, plane_mask, format, dest_image, dest_x, dest_y) updates \ dest_image with the specified subimage in the same manner as " Xen arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11; arg1 = Xen_list_ref(args, 0); arg2 = Xen_list_ref(args, 1); arg3 = Xen_list_ref(args, 2); arg4 = Xen_list_ref(args, 3); arg5 = Xen_list_ref(args, 4); arg6 = Xen_list_ref(args, 5); arg7 = Xen_list_ref(args, 6); arg8 = Xen_list_ref(args, 7); arg9 = Xen_list_ref(args, 8); arg10 = Xen_list_ref(args, 9); arg11 = Xen_list_ref(args, 10); Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XGetSubImage", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XGetSubImage", "Drawable"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XGetSubImage", "int"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XGetSubImage", "int"); Xen_check_type(Xen_is_ulong(arg5), arg5, 5, "XGetSubImage", "unsigned int"); Xen_check_type(Xen_is_ulong(arg6), arg6, 6, "XGetSubImage", "unsigned int"); Xen_check_type(Xen_is_ulong(arg7), arg7, 7, "XGetSubImage", "ulong"); Xen_check_type(Xen_is_integer(arg8), arg8, 8, "XGetSubImage", "int"); Xen_check_type(Xen_is_XImage(arg9), arg9, 9, "XGetSubImage", "XImage*"); Xen_check_type(Xen_is_integer(arg10), arg10, 10, "XGetSubImage", "int"); Xen_check_type(Xen_is_integer(arg11), arg11, 11, "XGetSubImage", "int"); return(C_to_Xen_XImage(XGetSubImage(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_integer_to_C_int(arg3), Xen_integer_to_C_int(arg4), Xen_ulong_to_C_ulong(arg5), Xen_ulong_to_C_ulong(arg6), Xen_ulong_to_C_ulong(arg7), Xen_integer_to_C_int(arg8), Xen_to_C_XImage(arg9), Xen_integer_to_C_int(arg10), Xen_integer_to_C_int(arg11)))); } static Xen gxm_XGetImage(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6, Xen arg7, Xen arg8) { #define H_XGetImage "XImage *XGetImage(display, d, x, y, width, height, plane_mask, format): returns a pointer to an XImage structure." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XGetImage", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XGetImage", "Drawable"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XGetImage", "int"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XGetImage", "int"); Xen_check_type(Xen_is_ulong(arg5), arg5, 5, "XGetImage", "unsigned int"); Xen_check_type(Xen_is_ulong(arg6), arg6, 6, "XGetImage", "unsigned int"); Xen_check_type(Xen_is_ulong(arg7), arg7, 7, "XGetImage", "ulong"); Xen_check_type(Xen_is_integer(arg8), arg8, 8, "XGetImage", "int"); return(C_to_Xen_XImage(XGetImage(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_integer_to_C_int(arg3), Xen_integer_to_C_int(arg4), Xen_ulong_to_C_ulong(arg5), Xen_ulong_to_C_ulong(arg6), Xen_ulong_to_C_ulong(arg7), Xen_integer_to_C_int(arg8)))); } static Xen gxm_XCreateImage(Xen args) { #define H_XCreateImage "XImage *XCreateImage(display, visual, depth, format, offset, data, width, height, bitmap_pad, bytes_per_line) \ allocates the memory needed for an XImage structure for the specified display but does not allocate space for the image itself." Xen arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10; arg1 = Xen_list_ref(args, 0); arg2 = Xen_list_ref(args, 1); arg3 = Xen_list_ref(args, 2); arg4 = Xen_list_ref(args, 3); arg5 = Xen_list_ref(args, 4); arg6 = Xen_list_ref(args, 5); arg7 = Xen_list_ref(args, 6); arg8 = Xen_list_ref(args, 7); arg9 = Xen_list_ref(args, 8); arg10 = Xen_list_ref(args, 9); Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XCreateImage", "Display*"); Xen_check_type(Xen_is_Visual(arg2), arg2, 2, "XCreateImage", "Visual*"); Xen_check_type(Xen_is_ulong(arg3), arg3, 3, "XCreateImage", "unsigned int"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XCreateImage", "int"); Xen_check_type(Xen_is_integer(arg5), arg5, 5, "XCreateImage", "int"); Xen_check_type(Xen_is_wrapped_c_pointer(arg6), arg6, 6, "XCreateImage", "pointer"); Xen_check_type(Xen_is_ulong(arg7), arg7, 7, "XCreateImage", "unsigned int"); Xen_check_type(Xen_is_ulong(arg8), arg8, 8, "XCreateImage", "unsigned int"); Xen_check_type(Xen_is_integer(arg9), arg9, 9, "XCreateImage", "int"); Xen_check_type(Xen_is_integer(arg10), arg10, 10, "XCreateImage", "int"); return(C_to_Xen_XImage(XCreateImage(Xen_to_C_Display(arg1), Xen_to_C_Visual(arg2), Xen_ulong_to_C_ulong(arg3), Xen_integer_to_C_int(arg4), Xen_integer_to_C_int(arg5), (char *)Xen_unwrap_C_pointer(arg6), Xen_ulong_to_C_ulong(arg7), Xen_ulong_to_C_ulong(arg8), Xen_integer_to_C_int(arg9), Xen_integer_to_C_int(arg10)))); } static Xen gxm_XNewModifiermap(Xen arg1) { #define H_XNewModifiermap "XModifierKeymap *XNewModifiermap(max_keys_per_mod): returns a pointer to XModifierKeymap structure for later use." Xen_check_type(Xen_is_integer(arg1), arg1, 1, "XNewModifiermap", "int"); return(C_to_Xen_XModifierKeymap(XNewModifiermap(Xen_integer_to_C_int(arg1)))); } static Xen gxm_XInsertModifiermapEntry(Xen arg1, Xen arg2, Xen arg3) { #define H_XInsertModifiermapEntry "XModifierKeymap *XInsertModifiermapEntry(modmap, keycode_entry, modifier) adds the specified KeyCode to \ the set that controls the specified modifier and returns the resulting XModifierKeymap structure (expanded as needed)." Xen_check_type(Xen_is_XModifierKeymap(arg1), arg1, 1, "XInsertModifiermapEntry", "XModifierKeymap*"); Xen_check_type(Xen_is_KeyCode(arg2), arg2, 2, "XInsertModifiermapEntry", "KeyCode"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XInsertModifiermapEntry", "int"); return(C_to_Xen_XModifierKeymap(XInsertModifiermapEntry(Xen_to_C_XModifierKeymap(arg1), Xen_to_C_KeyCode(arg2), Xen_integer_to_C_int(arg3)))); } static Xen gxm_XGetModifierMapping(Xen arg1) { #define H_XGetModifierMapping "XModifierKeymap *XGetModifierMapping(display): returns a pointer to a newly created XModifierKeymap structure \ that contains the keys being used as modifiers." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XGetModifierMapping", "Display*"); return(C_to_Xen_XModifierKeymap(XGetModifierMapping(Xen_to_C_Display(arg1)))); } static Xen gxm_XDeleteModifiermapEntry(Xen arg1, Xen arg2, Xen arg3) { #define H_XDeleteModifiermapEntry "XModifierKeymap *XDeleteModifiermapEntry(modmap, keycode_entry, modifier) deletes the specified KeyCode \ from the set that controls the specified modifier and returns a pointer to the resulting XModifierKeymap structure." Xen_check_type(Xen_is_XModifierKeymap(arg1), arg1, 1, "XDeleteModifiermapEntry", "XModifierKeymap*"); Xen_check_type(Xen_is_KeyCode(arg2), arg2, 2, "XDeleteModifiermapEntry", "KeyCode"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XDeleteModifiermapEntry", "int"); return(C_to_Xen_XModifierKeymap(XDeleteModifiermapEntry(Xen_to_C_XModifierKeymap(arg1), Xen_to_C_KeyCode(arg2), Xen_integer_to_C_int(arg3)))); } static Xen gxm_XGetMotionEvents(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XGetMotionEvents "XTimeCoord *XGetMotionEvents(display, w, start, stop): returns all events in the motion history \ buffer that fall between the specified start and stop times, inclusive, and that have coordinates that lie within the specified window \ (including its borders) at its present placement." /* DIFF: XGetMotionEvents omits last arg, return time coords as list of lists */ int n, i, loc; XTimeCoord *tcs; Xen lst = Xen_empty_list; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XGetMotionEvents", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XGetMotionEvents", "Window"); Xen_check_type(Xen_is_Time(arg3), arg3, 3, "XGetMotionEvents", "Time"); Xen_check_type(Xen_is_Time(arg4), arg4, 4, "XGetMotionEvents", "Time"); tcs = XGetMotionEvents(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_to_C_Time(arg3), Xen_to_C_Time(arg4), &n); loc = xm_protect(lst); for (i = n - 1; i > 0; i--) lst = Xen_cons(Xen_list_3(C_to_Xen_Time(tcs->time), C_int_to_Xen_integer((int)(tcs->x)), C_int_to_Xen_integer((int)(tcs->y))), lst); XFree(tcs); /* free each as well? */ xm_unprotect_at(loc); return(lst); } static Xen gxm_XQueryFont(Xen arg1, Xen arg2) { #define H_XQueryFont "XFontStruct *XQueryFont(display, font): returns a pointer to the XFontStruct structure, which contains information \ associated with the font." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XQueryFont", "Display*"); Xen_check_type(Xen_is_Font(arg2), arg2, 2, "XQueryFont", "Font"); return(C_to_Xen_XFontStruct(XQueryFont(Xen_to_C_Display(arg1), Xen_to_C_Font(arg2)))); } static Xen gxm_XLoadQueryFont(Xen arg1, Xen arg2) { #define H_XLoadQueryFont "XFontStruct *XLoadQueryFont(display, name) provides the most common way for accessing a font. XLoadQueryFont \ both opens (loads) the specified font and returns a pointer to the appropriate XFontStruct structure." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XLoadQueryFont", "Display*"); Xen_check_type(Xen_is_string(arg2), arg2, 2, "XLoadQueryFont", "char*"); return(C_to_Xen_XFontStruct(XLoadQueryFont(Xen_to_C_Display(arg1), (char *)Xen_string_to_C_string(arg2)))); } static Xen gxm_DefaultScreen(Xen arg) { #define H_DefaultScreen "returns the default screen number referenced in the XOpenDisplay routine." Xen_check_type(Xen_is_Display(arg), arg, 0, "DefaultScreen", "Display*"); return(C_int_to_Xen_integer(DefaultScreen(Xen_to_C_Display(arg)))); } static Xen gxm_DefaultRootWindow(Xen arg) { Xen_check_type(Xen_is_Display(arg), arg, 0, "DefaultRootWindow", "Display*"); return(C_to_Xen_Window(DefaultRootWindow(Xen_to_C_Display(arg)))); } static Xen gxm_QLength(Xen arg) { /* QLength(display) */ Xen_check_type(Xen_is_Display(arg), arg, 0, "QLength", "Display*"); return(C_int_to_Xen_integer(QLength(Xen_to_C_Display(arg)))); } static Xen gxm_ScreenCount(Xen arg1) { /* ScreenCount(display) */ Xen_check_type(Xen_is_Display(arg1), arg1, 1, "ScreenCount", "Display*"); return(C_int_to_Xen_integer(XScreenCount(Xen_to_C_Display(arg1)))); } static Xen gxm_ServerVendor(Xen arg) { Xen_check_type(Xen_is_Display(arg), arg, 0, "ServerVendor", "Display*"); return(C_string_to_Xen_string(ServerVendor(Xen_to_C_Display(arg)))); } static Xen gxm_ProtocolVersion(Xen arg) { Xen_check_type(Xen_is_Display(arg), arg, 0, "ProtocolVersion", "Display*"); return(C_int_to_Xen_integer(ProtocolVersion(Xen_to_C_Display(arg)))); } static Xen gxm_ProtocolRevision(Xen arg) { Xen_check_type(Xen_is_Display(arg), arg, 0, "ProtocolRevision", "Display*"); return(C_int_to_Xen_integer(ProtocolRevision(Xen_to_C_Display(arg)))); } static Xen gxm_VendorRelease(Xen arg) { Xen_check_type(Xen_is_Display(arg), arg, 0, "VendorRelease", "Display*"); return(C_int_to_Xen_integer(VendorRelease(Xen_to_C_Display(arg)))); } static Xen gxm_DisplayString(Xen arg) { Xen_check_type(Xen_is_Display(arg), arg, 0, "DisplayString", "Display*"); return(C_string_to_Xen_string(DisplayString(Xen_to_C_Display(arg)))); } static Xen gxm_BitmapUnit(Xen arg) { Xen_check_type(Xen_is_Display(arg), arg, 0, "BitmapUnit", "Display*"); return(C_int_to_Xen_integer(BitmapUnit(Xen_to_C_Display(arg)))); } static Xen gxm_BitmapBitOrder(Xen arg) { Xen_check_type(Xen_is_Display(arg), arg, 0, "BitmapBitOrder", "Display*"); return(C_int_to_Xen_integer(BitmapBitOrder(Xen_to_C_Display(arg)))); } static Xen gxm_BitmapPad(Xen arg) { Xen_check_type(Xen_is_Display(arg), arg, 0, "BitmapPad", "Display*"); return(C_int_to_Xen_integer(BitmapPad(Xen_to_C_Display(arg)))); } static Xen gxm_ImageByteOrder(Xen arg) { Xen_check_type(Xen_is_Display(arg), arg, 0, "ImageByteOrder", "Display*"); return(C_int_to_Xen_integer(ImageByteOrder(Xen_to_C_Display(arg)))); } static Xen gxm_NextRequest(Xen arg) { Xen_check_type(Xen_is_Display(arg), arg, 0, "NextRequest", "Display*"); return(C_ulong_to_Xen_ulong(NextRequest(Xen_to_C_Display(arg)))); } static Xen gxm_LastKnownRequestProcessed(Xen arg) { Xen_check_type(Xen_is_Display(arg), arg, 0, "LastKnownRequestProcessed", "Display*"); return(C_ulong_to_Xen_ulong(LastKnownRequestProcessed(Xen_to_C_Display(arg)))); } static Xen gxm_DefaultScreenOfDisplay(Xen arg) { #define H_DefaultScreenOfDisplay "returns the default screen of the specified display." Xen_check_type(Xen_is_Display(arg), arg, 0, "DefaultScreenOfDisplay", "Display"); return(C_to_Xen_Screen(DefaultScreenOfDisplay(Xen_to_C_Display(arg)))); } static Xen gxm_DisplayOfScreen(Xen arg) { Xen_check_type(Xen_is_Screen(arg), arg, 0, "DisplayOfScreen", "Screen"); return(C_to_Xen_Display(DisplayOfScreen(Xen_to_C_Screen(arg)))); } static Xen gxm_RootWindowOfScreen(Xen arg) { Xen_check_type(Xen_is_Screen(arg), arg, 0, "RootWindowOfScreen", "Screen"); return(C_to_Xen_Window(RootWindowOfScreen(Xen_to_C_Screen(arg)))); } static Xen gxm_BlackPixelOfScreen(Xen arg) { Xen_check_type(Xen_is_Screen(arg), arg, 0, "BlackPixelOfScreen", "Screen"); return(C_to_Xen_Pixel(BlackPixelOfScreen(Xen_to_C_Screen(arg)))); } static Xen gxm_WhitePixelOfScreen(Xen arg) { Xen_check_type(Xen_is_Screen(arg), arg, 0, "WhitePixelOfScreen", "Screen"); return(C_to_Xen_Pixel(WhitePixelOfScreen(Xen_to_C_Screen(arg)))); } static Xen gxm_DefaultColormapOfScreen(Xen arg) { Xen_check_type(Xen_is_Screen(arg), arg, 0, "DefaultColormapOfScreen", "Screen"); return(C_to_Xen_Colormap(DefaultColormapOfScreen(Xen_to_C_Screen(arg)))); } static Xen gxm_DefaultDepthOfScreen(Xen arg) { /* DefaultDepthOfScreen(screen) */ Xen_check_type(Xen_is_Screen(arg), arg, 0, "DefaultDepthOfScreen", "Screen"); return(C_int_to_Xen_integer(DefaultDepthOfScreen(Xen_to_C_Screen(arg)))); } static Xen gxm_DefaultGCOfScreen(Xen arg) { Xen_check_type(Xen_is_Screen(arg), arg, 0, "DefaultGCOfScreen", "Screen"); return(C_to_Xen_GC(DefaultGCOfScreen(Xen_to_C_Screen(arg)))); } static Xen gxm_DefaultVisualOfScreen(Xen arg) { Xen_check_type(Xen_is_Screen(arg), arg, 0, "DefaultVisualOfScreen", "Screen"); return(C_to_Xen_Visual(DefaultVisualOfScreen(Xen_to_C_Screen(arg)))); } static Xen gxm_WidthOfScreen(Xen arg) { Xen_check_type(Xen_is_Screen(arg), arg, 0, "WidthOfScreen", "Screen"); return(C_int_to_Xen_integer(WidthOfScreen(Xen_to_C_Screen(arg)))); } static Xen gxm_HeightOfScreen(Xen arg) { /* HeightOfScreen(screen) */ Xen_check_type(Xen_is_Screen(arg), arg, 0, "HeightOfScreen", "Screen"); return(C_int_to_Xen_integer(HeightOfScreen(Xen_to_C_Screen(arg)))); } static Xen gxm_WidthMMOfScreen(Xen arg) { Xen_check_type(Xen_is_Screen(arg), arg, 0, "WidthMMOfScreen", "Screen"); return(C_int_to_Xen_integer(WidthMMOfScreen(Xen_to_C_Screen(arg)))); } static Xen gxm_HeightMMOfScreen(Xen arg) { Xen_check_type(Xen_is_Screen(arg), arg, 0, "HeightMMOfScreen", "Screen"); return(C_int_to_Xen_integer(HeightMMOfScreen(Xen_to_C_Screen(arg)))); } static Xen gxm_PlanesOfScreen(Xen arg) { Xen_check_type(Xen_is_Screen(arg), arg, 0, "PlanesOfScreen", "Screen"); return(C_int_to_Xen_integer(PlanesOfScreen(Xen_to_C_Screen(arg)))); } static Xen gxm_CellsOfScreen(Xen arg) { Xen_check_type(Xen_is_Screen(arg), arg, 0, "CellsOfScreen", "Screen"); return(C_int_to_Xen_integer(CellsOfScreen(Xen_to_C_Screen(arg)))); } static Xen gxm_MinCmapsOfScreen(Xen arg) { /* MinCmapsOfScreen(screen) */ Xen_check_type(Xen_is_Screen(arg), arg, 0, "MinCmapsOfScreen", "Screen"); return(C_int_to_Xen_integer(MinCmapsOfScreen(Xen_to_C_Screen(arg)))); } static Xen gxm_MaxCmapsOfScreen(Xen arg) { /* MaxCmapsOfScreen(screen) */ Xen_check_type(Xen_is_Screen(arg), arg, 0, "MaxCmapsOfScreen", "Screen"); return(C_int_to_Xen_integer(MaxCmapsOfScreen(Xen_to_C_Screen(arg)))); } static Xen gxm_DoesSaveUnders(Xen arg) { Xen_check_type(Xen_is_Screen(arg), arg, 0, "DoesSaveUnders", "Screen"); return(C_bool_to_Xen_boolean(DoesSaveUnders(Xen_to_C_Screen(arg)))); } static Xen gxm_DoesBackingStore(Xen arg) { Xen_check_type(Xen_is_Screen(arg), arg, 0, "DoesBackingStore", "Screen"); return(C_bool_to_Xen_boolean(DoesBackingStore(Xen_to_C_Screen(arg)))); } static Xen gxm_EventMaskOfScreen(Xen arg) { Xen_check_type(Xen_is_Screen(arg), arg, 0, "EventMaskOfScreen", "Screen"); return(C_ulong_to_Xen_ulong(EventMaskOfScreen(Xen_to_C_Screen(arg)))); } static Xen gxm_RootWindow(Xen arg1, Xen arg2) { Xen_check_type(Xen_is_Display(arg1), arg1, 1, "RootWindow", "Display*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "RootWindow", "int"); return(C_to_Xen_Window(RootWindow(Xen_to_C_Display(arg1), Xen_integer_to_C_int(arg2)))); } static Xen gxm_DefaultVisual(Xen arg1, Xen arg2) { Xen_check_type(Xen_is_Display(arg1), arg1, 1, "DefaultVisual", "Display*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "DefaultVisual", "int"); return(C_to_Xen_Visual(DefaultVisual(Xen_to_C_Display(arg1), Xen_integer_to_C_int(arg2)))); } static Xen gxm_DefaultGC(Xen arg1, Xen arg2) { Xen_check_type(Xen_is_Display(arg1), arg1, 1, "DefaultGC", "Display*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "DefaultGC", "int"); return(C_to_Xen_GC(DefaultGC(Xen_to_C_Display(arg1), Xen_integer_to_C_int(arg2)))); } static Xen gxm_BlackPixel(Xen arg1, Xen arg2) { Xen_check_type(Xen_is_Display(arg1), arg1, 1, "BlackPixel", "Display*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "BlackPixel", "int"); return(C_to_Xen_Pixel(BlackPixel(Xen_to_C_Display(arg1), Xen_integer_to_C_int(arg2)))); } static Xen gxm_WhitePixel(Xen arg1, Xen arg2) { Xen_check_type(Xen_is_Display(arg1), arg1, 1, "WhitePixel", "Display*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "WhitePixel", "int"); return(C_to_Xen_Pixel(WhitePixel(Xen_to_C_Display(arg1), Xen_integer_to_C_int(arg2)))); } static Xen gxm_DisplayWidth(Xen arg1, Xen arg2) { Xen_check_type(Xen_is_Display(arg1), arg1, 1, "DisplayWidth", "Display*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "DisplayWidth", "int"); return(C_int_to_Xen_integer(DisplayWidth(Xen_to_C_Display(arg1), Xen_integer_to_C_int(arg2)))); } static Xen gxm_DisplayHeight(Xen arg1, Xen arg2) { Xen_check_type(Xen_is_Display(arg1), arg1, 1, "DisplayHeight", "Display*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "DisplayHeight", "int"); return(C_int_to_Xen_integer(DisplayHeight(Xen_to_C_Display(arg1), Xen_integer_to_C_int(arg2)))); } static Xen gxm_DisplayWidthMM(Xen arg1, Xen arg2) { Xen_check_type(Xen_is_Display(arg1), arg1, 1, "DisplayWidthMM", "Display*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "DisplayWidthMM", "int"); return(C_int_to_Xen_integer(DisplayWidthMM(Xen_to_C_Display(arg1), Xen_integer_to_C_int(arg2)))); } static Xen gxm_DisplayHeightMM(Xen arg1, Xen arg2) { Xen_check_type(Xen_is_Display(arg1), arg1, 1, "DisplayHeightMM", "Display*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "DisplayHeightMM", "int"); return(C_int_to_Xen_integer(DisplayHeightMM(Xen_to_C_Display(arg1), Xen_integer_to_C_int(arg2)))); } static Xen gxm_DisplayPlanes(Xen arg1, Xen arg2) { Xen_check_type(Xen_is_Display(arg1), arg1, 1, "DisplayPlanes", "Display*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "DisplayPlanes", "int"); return(C_int_to_Xen_integer(DisplayPlanes(Xen_to_C_Display(arg1), Xen_integer_to_C_int(arg2)))); } static Xen gxm_DisplayCells(Xen arg1, Xen arg2) { Xen_check_type(Xen_is_Display(arg1), arg1, 1, "DisplayCells", "Display*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "DisplayCells", "int"); return(C_int_to_Xen_integer(DisplayCells(Xen_to_C_Display(arg1), Xen_integer_to_C_int(arg2)))); } static Xen gxm_DefaultColormap(Xen arg1, Xen arg2) { Xen_check_type(Xen_is_Display(arg1), arg1, 1, "DefaultColormap", "Display*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "DefaultColormap", "int"); return(C_to_Xen_Colormap(DefaultColormap(Xen_to_C_Display(arg1), Xen_integer_to_C_int(arg2)))); } static Xen gxm_ScreenOfDisplay(Xen arg1, Xen arg2) { Xen_check_type(Xen_is_Display(arg1), arg1, 1, "ScreenOfDisplay", "Display*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "ScreenOfDisplay", "int"); return(C_to_Xen_Screen(ScreenOfDisplay(Xen_to_C_Display(arg1), Xen_integer_to_C_int(arg2)))); } static Xen gxm_DefaultDepth(Xen arg1, Xen arg2) { /* DefaultDepth(display, screen_number) */ Xen_check_type(Xen_is_Display(arg1), arg1, 1, "DefaultDepth", "Display*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "DefaultDepth", "int"); return(C_int_to_Xen_integer(DefaultDepth(Xen_to_C_Display(arg1), Xen_integer_to_C_int(arg2)))); } static Xen gxm_IsKeypadKey(Xen arg) { #define H_IsKeypadKey "IsKeypadKey(keysym): returns " PROC_TRUE " if the specified KeySym is a keypad key." Xen_check_type(Xen_is_KeySym(arg), arg, 0, "IsKeypadKey", "KeySym"); return(C_bool_to_Xen_boolean(IsKeypadKey(Xen_to_C_KeySym(arg)))); } static Xen gxm_IsPrivateKeypadKey(Xen arg) { #define H_IsPrivateKeypadKey "IsPrivateKeypadKey(keysym): returns " PROC_TRUE " if the specified KeySym is a vendor-private keypad key." Xen_check_type(Xen_is_KeySym(arg), arg, 0, "IsPrivateKeypadKey", "KeySym"); return(C_bool_to_Xen_boolean(IsPrivateKeypadKey(Xen_to_C_KeySym(arg)))); } static Xen gxm_IsCursorKey(Xen arg) { #define H_IsCursorKey "IsCursorKey(keysym): returns " PROC_TRUE " if the specified KeySym is a cursor key." Xen_check_type(Xen_is_KeySym(arg), arg, 0, "IsCursorKey", "KeySym"); return(C_bool_to_Xen_boolean(IsCursorKey(Xen_to_C_KeySym(arg)))); } static Xen gxm_IsPFKey(Xen arg) { #define H_IsPFKey "IsPFKey(keysym): returns " PROC_TRUE " if the specified KeySym is a PF key." Xen_check_type(Xen_is_KeySym(arg), arg, 0, "IsPFKey", "KeySym"); return(C_bool_to_Xen_boolean(IsPFKey(Xen_to_C_KeySym(arg)))); } static Xen gxm_IsFunctionKey(Xen arg) { #define H_IsFunctionKey "IsFunctionKey(keysym): returns " PROC_TRUE " if the KeySym is a function key." Xen_check_type(Xen_is_KeySym(arg), arg, 0, "IsFunctionKey", "KeySym"); return(C_bool_to_Xen_boolean(IsFunctionKey(Xen_to_C_KeySym(arg)))); } static Xen gxm_IsMiscFunctionKey(Xen arg) { #define H_IsMiscFunctionKey "IsMiscFunctionKey(keysym): returns " PROC_TRUE " if the specified KeySym is a miscellaneous function key." Xen_check_type(Xen_is_KeySym(arg), arg, 0, "IsMiscFunctionKey", "KeySym"); return(C_bool_to_Xen_boolean(IsMiscFunctionKey(Xen_to_C_KeySym(arg)))); } static Xen gxm_IsModifierKey(Xen arg) { #define H_IsModifierKey "IsModifierKey(keysym): returns " PROC_TRUE " if the specified KeySym is a modifier key." Xen_check_type(Xen_is_KeySym(arg), arg, 0, "IsModifierKey", "KeySym"); return(C_bool_to_Xen_boolean(IsModifierKey(Xen_to_C_KeySym(arg)))); } static Xen gxm_XAddPixel(Xen arg1, Xen arg2) { #define H_XAddPixel "XAddPixel(ximage, value) adds a constant value to every pixel in an image." Xen_check_type(Xen_is_XImage(arg1), arg1, 1, "XAddPixel", "XImage*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XAddPixel", "long"); return(C_int_to_Xen_integer(XAddPixel(Xen_to_C_XImage(arg1), Xen_integer_to_C_int(arg2)))); } static Xen gxm_XSubImage(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5) { #define H_XSubImage "XImage *XSubImage(ximage, x, y, subimage_width, subimage_height) creates a new image that is a subsection of an existing one." Xen_check_type(Xen_is_XImage(arg1), arg1, 1, "XSubImage", "XImage*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XSubImage", "int"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XSubImage", "int"); Xen_check_type(Xen_is_ulong(arg4), arg4, 4, "XSubImage", "unsigned int"); Xen_check_type(Xen_is_ulong(arg5), arg5, 5, "XSubImage", "unsigned int"); return(C_to_Xen_XImage(XSubImage(Xen_to_C_XImage(arg1), Xen_integer_to_C_int(arg2), Xen_integer_to_C_int(arg3), Xen_ulong_to_C_ulong(arg4), Xen_ulong_to_C_ulong(arg5)))); } static Xen gxm_XPutPixel(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XPutPixel "XPutPixel(ximage, x, y, pixel) overwrites the pixel in the named image with the specified pixel value." Xen_check_type(Xen_is_XImage(arg1), arg1, 1, "XPutPixel", "XImage*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XPutPixel", "int"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XPutPixel", "int"); Xen_check_type(Xen_is_Pixel(arg4), arg4, 4, "XPutPixel", "Pixel"); return(C_int_to_Xen_integer(XPutPixel(Xen_to_C_XImage(arg1), Xen_integer_to_C_int(arg2), Xen_integer_to_C_int(arg3), Xen_to_C_Pixel(arg4)))); } static Xen gxm_XGetPixel(Xen arg1, Xen arg2, Xen arg3) { #define H_XGetPixel "Pixel XGetPixel(ximage, x, y): returns the specified pixel from the named image." Xen_check_type(Xen_is_XImage(arg1), arg1, 1, "XGetPixel", "XImage*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XGetPixel", "int"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XGetPixel", "int"); return(C_to_Xen_Pixel(XGetPixel(Xen_to_C_XImage(arg1), Xen_integer_to_C_int(arg2), Xen_integer_to_C_int(arg3)))); } static Xen gxm_XDestroyImage(Xen arg1) { #define H_XDestroyImage "XDestroyImage(ximage) deallocates the memory associated with the XImage structure." Xen_check_type(Xen_is_XImage(arg1), arg1, 1, "XDestroyImage", "XImage*"); return(C_int_to_Xen_integer(XDestroyImage(Xen_to_C_XImage(arg1)))); } /* ---------------------------------------------------------------------------------------------------- * * * * *********** * * *********** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ******* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *********** * * * * ---------------------------------------------------------------------------------------------------- */ #if HAVE_XSHAPEQUERYEXTENSION /* thanks to Michael Scholz! */ static Xen gxm_XShapeQueryExtension(Xen dpy) { #define H_XShapeQueryExtension "(XShapeQueryExtension dpy): returns list of (Bool event_base error_base)" /* DIFF: (proposal) [C] Bool XShapeQueryExtension(Display *dpy, int *event_base, int *error_base) [XEN] (XShapeQueryExtension dpy): (list Bool event_base error_base) */ int event_base = 0, error_base = 0; Bool ret = False; Xen_check_type(Xen_is_Display(dpy), dpy, 1, "XShapeQueryExtension", "Display*"); ret = XShapeQueryExtension(Xen_to_C_Display(dpy), &event_base, &error_base); return(Xen_list_3(C_bool_to_Xen_boolean(ret), C_int_to_Xen_integer(event_base), C_int_to_Xen_integer(error_base))); } static Xen gxm_XShapeQueryVersion(Xen dpy) { #define H_XShapeQueryVersion "(XShapeQueryVersion dpy): returns list of (Bool major_version minor_version)" int major = 0, minor = 0; Bool ret = False; Xen_check_type(Xen_is_Display(dpy), dpy, 1, "XShapeQueryVersion", "Display*"); ret = XShapeQueryVersion(Xen_to_C_Display(dpy), &major, &minor); return(Xen_list_3(C_bool_to_Xen_boolean(ret), C_int_to_Xen_integer(major), C_int_to_Xen_integer(minor))); } static Xen gxm_XShapeQueryExtents(Xen dpy, Xen win) { #define H_XShapeQueryExtents "(XShapeQueryExtents dpy win): returns list of (status bounding_shaped x_bound y_bound w_bound \ h_bound clip_shaped x_clip y_clip w_clip h_clip)" Bool bounding_shaped; int x_bounding; int y_bounding; unsigned int w_bounding; unsigned int h_bounding; Bool clip_shaped; int x_clip; int y_clip; unsigned int w_clip; unsigned int h_clip; Status ret; Xen_check_type(Xen_is_Display(dpy), dpy, 1, "XShapeQueryExtents", "Display*"); Xen_check_type(Xen_is_Window(win), win, 2, "XShapeQueryExtents", "Window"); ret = XShapeQueryExtents(Xen_to_C_Display(dpy), Xen_to_C_Window(win), &bounding_shaped, &x_bounding, &y_bounding, &w_bounding, &h_bounding, &clip_shaped, &x_clip, &y_clip, &w_clip, &h_clip); return(Xen_cons(C_int_to_Xen_integer(ret), Xen_cons(C_int_to_Xen_integer(bounding_shaped), Xen_list_9(C_int_to_Xen_integer(x_bounding), C_int_to_Xen_integer(y_bounding), C_int_to_Xen_integer(w_bounding), C_int_to_Xen_integer(h_bounding), C_int_to_Xen_integer(clip_shaped), C_int_to_Xen_integer(x_clip), C_int_to_Xen_integer(y_clip), C_int_to_Xen_integer(w_clip), C_int_to_Xen_integer(h_clip))))); } static Xen gxm_XShapeGetRectangles(Xen dpy, Xen win, Xen kind) { #define H_XShapeGetRectangles "(XShapeGetRectangles dpy win kind): returns list of (xrectangles ordering)" int count = 0, ordering = 0; XRectangle *res; Xen_check_type(Xen_is_Display(dpy), dpy, 1, "XShapeGetRectangles", "Display*"); Xen_check_type(Xen_is_Window(win), win, 2, "XShapeGetRectangles", "Window"); Xen_check_type(Xen_is_integer(kind), kind, 3, "XShapeGetRectangles", "int"); res = XShapeGetRectangles(Xen_to_C_Display(dpy), Xen_to_C_Window(win), Xen_integer_to_C_int(kind), &count, &ordering); return(Xen_list_2(C_to_Xen_XRectangles(res, count), C_int_to_Xen_integer(ordering))); } static Xen gxm_XShapeOffsetShape(Xen dpy, Xen win, Xen kind, Xen x, Xen y) { #define H_XShapeOffsetShape "(XShapeOffsetShape dpy win kind x-off y-off)" Xen_check_type(Xen_is_Display(dpy), dpy, 1, "XShapeOffsetShape", "Display*"); Xen_check_type(Xen_is_Window(win), win, 2, "XShapeOffsetShape", "Window"); Xen_check_type(Xen_is_integer(kind), kind, 3, "XShapeOffsetShape", "int"); Xen_check_type(Xen_is_integer(x), x, 4, "XShapeOffsetShape", "int"); Xen_check_type(Xen_is_integer(y), y, 5, "XShapeOffsetShape", "int"); XShapeOffsetShape(Xen_to_C_Display(dpy), Xen_to_C_Window(win), Xen_integer_to_C_int(kind), Xen_integer_to_C_int(x), Xen_integer_to_C_int(y)); return(Xen_false); } static Xen gxm_XShapeCombineRegion(Xen dpy, Xen win, Xen kind, Xen x, Xen y, Xen reg, Xen op) { #define H_XShapeCombineRegion "(XShapeCombineRegion dpy win kind x-off y-off region op)" Xen_check_type(Xen_is_Display(dpy), dpy, 1, "XShapeCombineRegion", "Display*"); Xen_check_type(Xen_is_Window(win), win, 2, "XShapeCombineRegion", "Window"); Xen_check_type(Xen_is_integer(kind), kind, 3, "XShapeCombineRegion", "int"); Xen_check_type(Xen_is_integer(x), x, 4, "XShapeCombineRegion", "int"); Xen_check_type(Xen_is_integer(y), y, 5, "XShapeCombineRegion", "int"); Xen_check_type(Xen_is_Region(reg), reg, 6, "XShapeCombineRegion", "Region"); Xen_check_type(Xen_is_integer(op), op, 6, "XShapeCombineRegion", "int"); XShapeCombineRegion(Xen_to_C_Display(dpy), Xen_to_C_Window(win), Xen_integer_to_C_int(kind), Xen_integer_to_C_int(x), Xen_integer_to_C_int(y), Xen_to_C_Region(reg), Xen_integer_to_C_int(op)); return(Xen_false); } static Xen gxm_XShapeCombineMask(Xen dpy, Xen win, Xen kind, Xen x, Xen y, Xen pix, Xen op) { #define H_XShapeCombineMask "(XShapeCombineMask dpy win kind x-off y-off pixmap op)" Xen_check_type(Xen_is_Display(dpy), dpy, 1, "XShapeCombineMask", "Display*"); Xen_check_type(Xen_is_Window(win), win, 2, "XShapeCombineMask", "Window"); Xen_check_type(Xen_is_integer(kind), kind, 3, "XShapeCombineMask", "int"); Xen_check_type(Xen_is_integer(x), x, 4, "XShapeCombineMask", "int"); Xen_check_type(Xen_is_integer(y), y, 5, "XShapeCombineMask", "int"); Xen_check_type(Xen_is_Pixmap(pix), pix, 6, "XShapeCombineMask", "Pixmap"); Xen_check_type(Xen_is_integer(op), op, 6, "XShapeCombineMask", "int"); XShapeCombineMask(Xen_to_C_Display(dpy), Xen_to_C_Window(win), Xen_integer_to_C_int(kind), Xen_integer_to_C_int(x), Xen_integer_to_C_int(y), Xen_to_C_Pixmap(pix), Xen_integer_to_C_int(op)); return(Xen_false); } static Xen gxm_XShapeCombineShape(Xen dpy, Xen win, Xen kind, Xen x, Xen y, Xen src, Xen src_kind, Xen op) { #define H_XShapeCombineShape "(XShapeCombineShape dpy win kind x-off y-off src src_kind op)" Xen_check_type(Xen_is_Display(dpy), dpy, 1, "XShapeCombineShape", "Display*"); Xen_check_type(Xen_is_Window(win), win, 2, "XShapeCombineShape", "Window"); Xen_check_type(Xen_is_integer(kind), kind, 3, "XShapeCombineShape", "int"); Xen_check_type(Xen_is_integer(x), x, 4, "XShapeCombineShape", "int"); Xen_check_type(Xen_is_integer(y), y, 5, "XShapeCombineShape", "int"); Xen_check_type(Xen_is_Window(src), src, 6, "XShapeCombineShape", "Window"); Xen_check_type(Xen_is_integer(src_kind), src_kind, 7, "XShapeCombineShape", "int"); Xen_check_type(Xen_is_integer(op), op, 8, "XShapeCombineShape", "int"); XShapeCombineShape(Xen_to_C_Display(dpy), Xen_to_C_Window(win), Xen_integer_to_C_int(kind), Xen_integer_to_C_int(x), Xen_integer_to_C_int(y), Xen_to_C_Window(src), Xen_integer_to_C_int(src_kind), Xen_integer_to_C_int(op)); return(Xen_false); } static Xen gxm_XShapeCombineRectangles(Xen dpy, Xen win, Xen kind, Xen x, Xen y, Xen rects, Xen n_rects, Xen op, Xen ordering) { #define H_XShapeCombineRectangles "(XShapeCombineRectangles dpy win kind x-off y-off rectangles n-rects op ordering)" XRectangle *cr = NULL; Xen_check_type(Xen_is_Display(dpy), dpy, 1, "XShapeCombineRectangles", "Display*"); Xen_check_type(Xen_is_Window(win), win, 2, "XShapeCombineRectangles", "Window"); Xen_check_type(Xen_is_integer(kind), kind, 3, "XShapeCombineRectangles", "int"); Xen_check_type(Xen_is_integer(x), x, 4, "XShapeCombineRectangles", "int"); Xen_check_type(Xen_is_integer(y), y, 5, "XShapeCombineRectangles", "int"); Xen_check_type(Xen_is_list(rects), rects, 6, "XShapeCombineRectangles", "list of XRectangles"); Xen_check_type(Xen_is_integer(n_rects), n_rects, 7, "XShapeCombineRectangles", "int"); Xen_check_type(Xen_is_integer(op), op, 8, "XShapeCombineRectangles", "int"); Xen_check_type(Xen_is_integer(ordering), ordering, 9, "XShapeCombineRectangles", "int"); cr = Xen_to_C_XRectangles(rects, Xen_integer_to_C_int(n_rects)); XShapeCombineRectangles(Xen_to_C_Display(dpy), Xen_to_C_Window(win), Xen_integer_to_C_int(kind), Xen_integer_to_C_int(x), Xen_integer_to_C_int(y), cr, Xen_integer_to_C_int(n_rects), Xen_integer_to_C_int(op), Xen_integer_to_C_int(ordering)); if (cr) free(cr); return(Xen_false); } #endif /* ---------------------------------------------------------------------------------------------------- * * * * *********** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ---------------------------------------------------------------------------------------------------- */ typedef enum {CANCEL_CONVERT, CONVERT, LOSE, DONE, CONVERT_INCR, LOSE_INCR, DONE_INCR} xm_selmap_t; /* need a way to map from widget to selection proc */ typedef struct { Widget w; xm_selmap_t type; Xen proc; } selmap; static selmap *selmaps = NULL; static int selmap_size = 0; static int selmap_ctr = 0; static void add_selmap(Widget w, xm_selmap_t type, Xen proc) { if (selmap_size == 0) selmaps = (selmap *)calloc(8, sizeof(selmap)); else { if (selmap_size == selmap_ctr) { int i; selmap_size += 8; selmaps = (selmap *)realloc(selmaps, selmap_size * sizeof(selmap)); for (i = selmap_ctr; i < selmap_size; i++) selmaps[i].w = NULL; } } selmaps[selmap_ctr].w = w; selmaps[selmap_ctr].type = type; xm_protect(proc); selmaps[selmap_ctr++].proc = proc; } static Xen unselmap(Widget w, xm_selmap_t type) { int i; for (i = 0; i < selmap_ctr; i++) if ((selmaps[i].w == w) && (selmaps[i].type == type)) return(selmaps[i].proc); return(Xen_false); } static void gxm_XtCancelConvertSelectionProc(Widget w, Atom *a1, Atom *a2, XtRequestId *id, XtPointer x) { Xen proc; proc = unselmap(w, CANCEL_CONVERT); if (Xen_is_procedure(proc)) Xen_call_with_5_args(proc, C_to_Xen_Widget(w), C_to_Xen_Atom(*a1), C_to_Xen_Atom(*a2), C_to_Xen_XtRequestId(*id), (Xen)x, "CancelConvert"); } static Boolean gxm_XtConvertSelectionProc(Widget w, Atom *a1, Atom *a2, Atom *a3, XtPointer* x, unsigned long *l, int *i) { Xen proc; proc = unselmap(w, CONVERT); if (Xen_is_procedure(proc)) { Xen val; val = Xen_call_with_3_args(proc, C_to_Xen_Widget(w), C_to_Xen_Atom(*a1), C_to_Xen_Atom(*a2), "ConvertSelection"); (*a3) = Xen_to_C_Atom(Xen_list_ref(val, 1)); (*x) = (XtPointer)(Xen_list_ref(val, 2)); (*l) = Xen_ulong_to_C_ulong(Xen_list_ref(val, 3)); (*i) = Xen_integer_to_C_int(Xen_list_ref(val, 4)); return(Xen_boolean_to_C_bool(Xen_car(val))); } return(0); } static void gxm_XtLoseSelectionIncrProc(Widget w, Atom *a, XtPointer x) { Xen proc; proc = unselmap(w, LOSE_INCR); if (Xen_is_procedure(proc)) Xen_call_with_3_args(proc, C_to_Xen_Widget(w), C_to_Xen_Atom(*a), (Xen)x, "LoseSelectionIncr"); } static void gxm_XtLoseSelectionProc(Widget w, Atom *a) { Xen proc; proc = unselmap(w, LOSE); if (Xen_is_procedure(proc)) Xen_call_with_2_args(proc, C_to_Xen_Widget(w), C_to_Xen_Atom(*a), "LoseSelection"); } static void gxm_XtSelectionDoneProc(Widget w, Atom *a1, Atom *a2) { Xen proc; proc = unselmap(w, DONE); if (Xen_is_procedure(proc)) Xen_call_with_3_args(proc, C_to_Xen_Widget(w), C_to_Xen_Atom(*a1), C_to_Xen_Atom(*a2), "DoneSelection"); } static void gxm_XtSelectionDoneIncrProc(Widget w, Atom *a1, Atom *a2, XtRequestId *i, XtPointer x) { Xen proc; proc = unselmap(w, DONE_INCR); if (Xen_is_procedure(proc)) Xen_call_with_5_args(proc, C_to_Xen_Widget(w), C_to_Xen_Atom(*a1), C_to_Xen_Atom(*a2), C_to_Xen_XtRequestId(*i), (Xen)x, "DoneSelectionIncr"); } static Xen gxm_XtAppUnlock(Xen arg1) { #define H_XtAppUnlock "void XtAppUnlock(app_context) unlocks the application context." Xen_check_type(Xen_is_XtAppContext(arg1), arg1, 1, "XtAppUnlock", "XtAppContext"); XtAppUnlock(Xen_to_C_XtAppContext(arg1)); return(Xen_false); } static Xen gxm_XtAppLock(Xen arg1) { #define H_XtAppLock "void XtAppLock(app_context) locks the application context including all its related displays and widgets." Xen_check_type(Xen_is_XtAppContext(arg1), arg1, 1, "XtAppLock", "XtAppContext"); XtAppLock(Xen_to_C_XtAppContext(arg1)); return(Xen_false); } static Xen gxm_XtToolkitThreadInitialize(void) { #define H_XtToolkitThreadInitialize "Boolean XtToolkitThreadInitialize()" return(C_bool_to_Xen_boolean(XtToolkitThreadInitialize())); } static Xen gxm_XtGetDisplays(Xen arg1) { #define H_XtGetDisplays "void XtGetDisplays(app_context): list of displays" /* DIFF: XtGetDisplays not arg2 arg3 returns list */ unsigned int x; Display **ds; int i, loc; Xen lst = Xen_empty_list; Xen_check_type(Xen_is_XtAppContext(arg1), arg1, 1, "XtGetDisplays", "XtAppContext"); XtGetDisplays(Xen_to_C_XtAppContext(arg1), &ds, &x); loc = xm_protect(lst); for (i = x - 1; i >= 0; i--) lst = Xen_cons(C_to_Xen_Display(ds[i]), lst); xm_unprotect_at(loc); return(lst); } static Xen gxm_XtGetApplicationNameAndClass(Xen arg1) { #define H_XtGetApplicationNameAndClass "void XtGetApplicationNameAndClass(display): returns the application name \ and class passed to XtDisplayInitialize for the specified display." /* DIFF: XtGetApplicationNameAndClass omits and rtns args 2 and 3 */ char *name, *clas; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XtGetApplicationNameAndClass", "Display*"); XtGetApplicationNameAndClass(Xen_to_C_Display(arg1), &name, &clas); return(Xen_list_2(C_string_to_Xen_string(name), C_string_to_Xen_string(clas))); } static Xen gxm_XtUngrabPointer(Xen arg1, Xen arg2) { #define H_XtUngrabPointer "void XtUngrabPointer(widget, time) calls XUngrabPointer with the specified time." Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtUngrabPointer", "Widget"); Xen_check_type(Xen_is_Time(arg2), arg2, 2, "XtUngrabPointer", "Time"); XtUngrabPointer(Xen_to_C_Widget(arg1), Xen_to_C_Time(arg2)); return(Xen_false); } static Xen gxm_XtGrabPointer(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6, Xen arg7, Xen arg8) { #define H_XtGrabPointer "int XtGrabPointer(widget, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor, time) calls \ XGrabPointer specifying the widget's window as the grab window." Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtGrabPointer", "Widget"); Xen_check_type(Xen_is_boolean(arg2), arg2, 2, "XtGrabPointer", "boolean"); Xen_check_type(Xen_is_ulong(arg3), arg3, 3, "XtGrabPointer", "unsigned int"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XtGrabPointer", "int"); Xen_check_type(Xen_is_integer(arg5), arg5, 5, "XtGrabPointer", "int"); Xen_check_type(Xen_is_Window(arg6), arg6, 6, "XtGrabPointer", "Window"); Xen_check_type(Xen_is_Cursor(arg7), arg7, 7, "XtGrabPointer", "Cursor"); Xen_check_type(Xen_is_Time(arg8), arg8, 8, "XtGrabPointer", "Time"); return(C_int_to_Xen_integer(XtGrabPointer(Xen_to_C_Widget(arg1), Xen_boolean_to_C_bool(arg2), Xen_ulong_to_C_ulong(arg3), Xen_integer_to_C_int(arg4), Xen_integer_to_C_int(arg5), Xen_to_C_Window(arg6), Xen_to_C_Cursor(arg7), Xen_to_C_Time(arg8)))); } static Xen gxm_XtUngrabButton(Xen arg1, Xen arg2, Xen arg3) { #define H_XtUngrabButton "void XtUngrabButton(widget, button, modifiers) calls XUngrabButton specifying the widget's window as the ungrab \ window if the widget is realized. " Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtUngrabButton", "Widget"); Xen_check_type(Xen_is_ulong(arg2), arg2, 2, "XtUngrabButton", "unsigned int"); Xen_check_type(Xen_is_Modifiers(arg3), arg3, 3, "XtUngrabButton", "Modifiers"); XtUngrabButton(Xen_to_C_Widget(arg1), Xen_ulong_to_C_ulong(arg2), Xen_to_C_Modifiers(arg3)); return(Xen_false); } static Xen gxm_XtGrabButton(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6, Xen arg7, Xen arg8, Xen arg9) { #define H_XtGrabButton "void XtGrabButton(widget, button, modifiers, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor) \ calls XGrabButton specifying the widget's window as the grab window if the widget is realized." Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtGrabButton", "Widget"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XtGrabButton", "int"); Xen_check_type(Xen_is_Modifiers(arg3), arg3, 3, "XtGrabButton", "Modifiers"); Xen_check_type(Xen_is_boolean(arg4), arg4, 4, "XtGrabButton", "boolean"); Xen_check_type(Xen_is_ulong(arg5), arg5, 5, "XtGrabButton", "unsigned int"); Xen_check_type(Xen_is_integer(arg6), arg6, 6, "XtGrabButton", "int"); Xen_check_type(Xen_is_integer(arg7), arg7, 7, "XtGrabButton", "int"); Xen_check_type(Xen_is_Window(arg8), arg8, 8, "XtGrabButton", "Window"); Xen_check_type(Xen_is_Cursor(arg9), arg9, 9, "XtGrabButton", "Cursor"); XtGrabButton(Xen_to_C_Widget(arg1), Xen_integer_to_C_int(arg2), Xen_to_C_Modifiers(arg3), Xen_boolean_to_C_bool(arg4), Xen_ulong_to_C_ulong(arg5), Xen_integer_to_C_int(arg6), Xen_integer_to_C_int(arg7), Xen_to_C_Window(arg8), Xen_to_C_Cursor(arg9)); return(Xen_false); } static Xen gxm_XtUngrabKeyboard(Xen arg1, Xen arg2) { #define H_XtUngrabKeyboard "void XtUngrabKeyboard(widget, time) calls XUngrabKeyboard with the specified time." Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtUngrabKeyboard", "Widget"); Xen_check_type(Xen_is_Time(arg2), arg2, 2, "XtUngrabKeyboard", "Time"); XtUngrabKeyboard(Xen_to_C_Widget(arg1), Xen_to_C_Time(arg2)); return(Xen_false); } static Xen gxm_XtGrabKeyboard(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5) { #define H_XtGrabKeyboard "int XtGrabKeyboard(widget, owner_events, pointer_mode, keyboard_mode, time)" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtGrabKeyboard", "Widget"); Xen_check_type(Xen_is_boolean(arg2), arg2, 2, "XtGrabKeyboard", "boolean"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XtGrabKeyboard", "int"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XtGrabKeyboard", "int"); Xen_check_type(Xen_is_Time(arg5), arg5, 5, "XtGrabKeyboard", "Time"); return(C_int_to_Xen_integer(XtGrabKeyboard(Xen_to_C_Widget(arg1), Xen_boolean_to_C_bool(arg2), Xen_integer_to_C_int(arg3), Xen_integer_to_C_int(arg4), Xen_to_C_Time(arg5)))); } static Xen gxm_XtUngrabKey(Xen arg1, Xen arg2, Xen arg3) { #define H_XtUngrabKey "void XtUngrabKey(widget, keycode, modifiers) calls XUngrabKey specifying the widget's window as the ungrab window \ if the widget is realized." Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtUngrabKey", "Widget"); Xen_check_type(Xen_is_KeyCode(arg2), arg2, 2, "XtUngrabKey", "KeyCode"); Xen_check_type(Xen_is_Modifiers(arg3), arg3, 3, "XtUngrabKey", "Modifiers"); XtUngrabKey(Xen_to_C_Widget(arg1), Xen_to_C_KeyCode(arg2), Xen_to_C_Modifiers(arg3)); return(Xen_false); } static Xen gxm_XtGrabKey(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6) { #define H_XtGrabKey "void XtGrabKey(widget, keycode, modifiers, owner_events, pointer_mode, keyboard_mode) calls XGrabKey specifying the \ widget's window as the grab window if the widget is realized." Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtGrabKey", "Widget"); Xen_check_type(Xen_is_KeyCode(arg2), arg2, 2, "XtGrabKey", "KeyCode"); Xen_check_type(Xen_is_Modifiers(arg3), arg3, 3, "XtGrabKey", "Modifiers"); Xen_check_type(Xen_is_boolean(arg4), arg4, 4, "XtGrabKey", "boolean"); Xen_check_type(Xen_is_integer(arg5), arg5, 5, "XtGrabKey", "int"); Xen_check_type(Xen_is_integer(arg6), arg6, 6, "XtGrabKey", "int"); XtGrabKey(Xen_to_C_Widget(arg1), Xen_to_C_KeyCode(arg2), Xen_to_C_Modifiers(arg3), Xen_boolean_to_C_bool(arg4), Xen_integer_to_C_int(arg5), Xen_integer_to_C_int(arg6)); return(Xen_false); } static Xen gxm_XtCancelSelectionRequest(Xen arg1, Xen arg2) { #define H_XtCancelSelectionRequest "void XtCancelSelectionRequest(requestor, selection)" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtCancelSelectionRequest", "Widget"); Xen_check_type(Xen_is_Atom(arg2), arg2, 2, "XtCancelSelectionRequest", "Atom"); XtCancelSelectionRequest(Xen_to_C_Widget(arg1), Xen_to_C_Atom(arg2)); return(Xen_false); } static Xen gxm_XtSendSelectionRequest(Xen arg1, Xen arg2, Xen arg3) { #define H_XtSendSelectionRequest "void XtSendSelectionRequest(requestor, selection, time)" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtSendSelectionRequest", "Widget"); Xen_check_type(Xen_is_Atom(arg2), arg2, 2, "XtSendSelectionRequest", "Atom"); Xen_check_type(Xen_is_Time(arg3), arg3, 3, "XtSendSelectionRequest", "Time"); XtSendSelectionRequest(Xen_to_C_Widget(arg1), Xen_to_C_Atom(arg2), Xen_to_C_Time(arg3)); return(Xen_false); } static Xen gxm_XtCreateSelectionRequest(Xen arg1, Xen arg2) { #define H_XtCreateSelectionRequest "void XtCreateSelectionRequest(requestor, selection)" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtCreateSelectionRequest", "Widget"); Xen_check_type(Xen_is_Atom(arg2), arg2, 2, "XtCreateSelectionRequest", "Atom"); XtCreateSelectionRequest(Xen_to_C_Widget(arg1), Xen_to_C_Atom(arg2)); return(Xen_false); } static Xen gxm_XtGetSelectionValuesIncremental(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6, Xen arg7) { #define H_XtGetSelectionValuesIncremental "void XtGetSelectionValuesIncremental(w, selection, targets, count, callback, client_data, time) \ is similar to XtGetSelectionValueIncremental except that it takes a list of target types and a list of client data and obtains the current \ value of the selection converted to each of the targets." /* DIFF: XtGetSelectionValuesIncremental arg 3 is list of Atoms */ Atom *outs; int len, loc; Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtGetSelectionValuesIncremental", "Widget"); Xen_check_type(Xen_is_Atom(arg2), arg2, 2, "XtGetSelectionValuesIncremental", "Atom"); Xen_check_type(Xen_is_list(arg3), arg3, 3, "XtGetSelectionValuesIncremental", "list of Atom"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XtGetSelectionValuesIncremental", "int"); Xen_check_type(Xen_is_procedure(arg5) && (Xen_is_aritable(arg5, 7)), arg5, 5, "XtGetSelectionValuesIncremental", "XtSelectionCallbackProc"); Xen_check_type(Xen_is_Time(arg7), arg7, 7, "XtGetSelectionValuesIncremental", "Time"); len = Xen_integer_to_C_int(arg4); if (len <= 0) return(Xen_false); outs = Xen_to_C_Atoms(arg3, len); xm_XtSelectionCallback_Descr = Xen_list_2(arg5, arg6); loc = xm_protect(xm_XtSelectionCallback_Descr); XtGetSelectionValuesIncremental(Xen_to_C_Widget(arg1), Xen_to_C_Atom(arg2), outs, len, gxm_XtSelectionCallbackProc, (XtPointer *)arg6, Xen_to_C_Time(arg7)); xm_unprotect_at(loc); free(outs); return(Xen_false); } static Xen gxm_XtGetSelectionValueIncremental(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6) { #define H_XtGetSelectionValueIncremental "void XtGetSelectionValueIncremental(w, selection, target, callback, client_data, time) is similar \ to XtGetSelectionValue except that the selection_callback procedure will be called repeatedly upon delivery of multiple segments of the selection value." int loc; Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtGetSelectionValueIncremental", "Widget"); Xen_check_type(Xen_is_Atom(arg2), arg2, 2, "XtGetSelectionValueIncremental", "Atom"); Xen_check_type(Xen_is_Atom(arg3), arg3, 3, "XtGetSelectionValueIncremental", "Atom"); Xen_check_type(Xen_is_procedure(arg4) && (Xen_is_aritable(arg4, 7)), arg4, 4, "XtGetSelectionValueIncremental", "XtSelectionCallbackProc"); Xen_check_type(Xen_is_Time(arg6), arg6, 6, "XtGetSelectionValueIncremental", "Time"); xm_XtSelectionCallback_Descr = Xen_list_2(arg4, arg5); loc = xm_protect(xm_XtSelectionCallback_Descr); XtGetSelectionValueIncremental(Xen_to_C_Widget(arg1), Xen_to_C_Atom(arg2), Xen_to_C_Atom(arg3), gxm_XtSelectionCallbackProc, (XtPointer)arg5, Xen_to_C_Time(arg6)); xm_unprotect_at(loc); return(Xen_false); } static Xen gxm_XtGetSelectionRequest(Xen arg1, Xen arg2, Xen arg3) { #define H_XtGetSelectionRequest "XSelectionRequestEvent* XtGetSelectionRequest(w, selection, request_id)" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtGetSelectionRequest", "Widget"); Xen_check_type(Xen_is_Atom(arg2), arg2, 2, "XtGetSelectionRequest", "Atom"); Xen_check_type(Xen_is_XtRequestId(arg3), arg3, 3, "XtGetSelectionRequest", "XtRequestId"); return(C_to_Xen_XSelectionRequestEvent(XtGetSelectionRequest(Xen_to_C_Widget(arg1), Xen_to_C_Atom(arg2), Xen_to_C_XtRequestId(arg3)))); } static Xen gxm_XtAppGetSelectionTimeout(Xen arg1) { #define H_XtAppGetSelectionTimeout "unsigned long XtAppGetSelectionTimeout(app_context): returns the current selection timeout value, in milliseconds." Xen_check_type(Xen_is_XtAppContext(arg1), arg1, 1, "XtAppGetSelectionTimeout", "XtAppContext"); return(C_ulong_to_Xen_ulong(XtAppGetSelectionTimeout(Xen_to_C_XtAppContext(arg1)))); } static Xen gxm_XtAppSetSelectionTimeout(Xen arg1, Xen arg2) { #define H_XtAppSetSelectionTimeout "void XtAppSetSelectionTimeout(app_context, timeout) sets the app's selection timeout mechanism." Xen_check_type(Xen_is_XtAppContext(arg1), arg1, 1, "XtAppSetSelectionTimeout", "XtAppContext"); Xen_check_type(Xen_is_ulong(arg2), arg2, 2, "XtAppSetSelectionTimeout", "ulong"); XtAppSetSelectionTimeout(Xen_to_C_XtAppContext(arg1), Xen_ulong_to_C_ulong(arg2)); return(Xen_false); } static Xen gxm_XtGetSelectionValues(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6, Xen arg7) { #define H_XtGetSelectionValues "void XtGetSelectionValues(w, selection, targets, count, callback, client_data, time) is similar to \ XtGetSelectionValue except that it takes a list of target types and a list of client data and obtains the current value of the selection \ converted to each of the targets." /* DIFF: XtGetSelectionValues arg 3 is list of Atoms */ Atom *outs; int len, loc; Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtGetSelectionValues", "Widget"); Xen_check_type(Xen_is_Atom(arg2), arg2, 2, "XtGetSelectionValues", "Atom"); Xen_check_type(Xen_is_list(arg3), arg3, 3, "XtGetSelectionValues", "list of Atom"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XtGetSelectionValues", "int"); Xen_check_type(Xen_is_procedure(arg5) && (Xen_is_aritable(arg5, 7)), arg5, 5, "XtGetSelectionValues", "XtSelectionCallbackProc"); Xen_check_type(Xen_is_Time(arg7), arg7, 7, "XtGetSelectionValues", "Time"); len = Xen_integer_to_C_int(arg4); if (len <= 0) return(Xen_false); outs = Xen_to_C_Atoms(arg3, len); xm_XtSelectionCallback_Descr = Xen_list_2(arg5, arg6); loc = xm_protect(xm_XtSelectionCallback_Descr); XtGetSelectionValues(Xen_to_C_Widget(arg1), Xen_to_C_Atom(arg2), outs, len, gxm_XtSelectionCallbackProc, (XtPointer *)arg6, Xen_to_C_Time(arg7)); xm_unprotect_at(loc); free(outs); return(Xen_false); } static Xen gxm_XtGetSelectionValue(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6) { #define H_XtGetSelectionValue "void XtGetSelectionValue(w, selection, target, callback, client_data, time) requests the value of the \ selection that has been converted to the target type. " int loc; Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtGetSelectionValue", "Widget"); Xen_check_type(Xen_is_Atom(arg2), arg2, 2, "XtGetSelectionValue", "Atom"); Xen_check_type(Xen_is_Atom(arg3), arg3, 3, "XtGetSelectionValue", "Atom"); Xen_check_type(Xen_is_procedure(arg4) && (Xen_is_aritable(arg4, 7)), arg4, 4, "XtGetSelectionValue", "XtSelectionCallbackProc"); Xen_check_type(Xen_is_Time(arg6), arg6, 6, "XtGetSelectionValue", "Time"); xm_XtSelectionCallback_Descr = Xen_list_2(arg4, arg5); loc = xm_protect(xm_XtSelectionCallback_Descr); XtGetSelectionValue(Xen_to_C_Widget(arg1), Xen_to_C_Atom(arg2), Xen_to_C_Atom(arg3), gxm_XtSelectionCallbackProc, (XtPointer)arg5, Xen_to_C_Time(arg6)); xm_unprotect_at(loc); return(Xen_false); } static Xen gxm_XtDisownSelection(Xen arg1, Xen arg2, Xen arg3) { #define H_XtDisownSelection "void XtDisownSelection(w, selection, time) informs the selection mechanism that the specified widget is to \ lose ownership of the selection." Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtDisownSelection", "Widget"); Xen_check_type(Xen_is_Atom(arg2), arg2, 2, "XtDisownSelection", "Atom"); Xen_check_type(Xen_is_Time(arg3), arg3, 3, "XtDisownSelection", "Time"); XtDisownSelection(Xen_to_C_Widget(arg1), Xen_to_C_Atom(arg2), Xen_to_C_Time(arg3)); return(Xen_false); } /*-------- file predicate -------- */ /* a "Substitution" is a list '(char substitute), so pass a list of such lists below where a substitution array is required */ static Xen xm_filepredicate_proc; static Boolean gxm_XtFilePredicate(String filename) { return(Xen_boolean_to_C_bool(Xen_call_with_1_arg(xm_filepredicate_proc, C_string_to_Xen_string(filename), __func__))); } static SubstitutionRec *gxm_make_subs(Xen lst_1) { int len; SubstitutionRec *subs = NULL; len = Xen_list_length(lst_1); if (len > 0) { int i; Xen lst; lst = Xen_copy_arg(lst_1); subs = (SubstitutionRec *)calloc(len, sizeof(SubstitutionRec)); for (i = 0; i < len; i++, lst = Xen_cdr(lst)) { if (!(Xen_is_list(Xen_car(lst)))) { free(subs); return(NULL); } subs[i].match = Xen_char_to_C_char(Xen_car(Xen_car(lst))); subs[i].substitution = xen_strdup(Xen_string_to_C_string(Xen_cadr(Xen_car(lst)))); } } return(subs); } /* (XtFindFile "/lib/%N:/usr/lib/%N:/usr/local/lib/%N" (list (list #\N "libxm.so")) 1 file-exists?) */ static Xen gxm_XtResolvePathname(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6, Xen arg7, Xen arg8) { #define H_XtResolvePathname "String XtResolvePathname(display, type, filename, suffix, path, substitutions, num_substitutions, predicate)" /* DIFF: XtResolvePathname args use #f for NULL * (XtResolvePathname (XtDisplay (cadr (main-widgets))) "app-defaults" #f #f #f #f 0 #f) */ int arg8_loc = -1; Xen res; char *str; SubstitutionRec *subs = NULL; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XtResolvePathname", "Display*"); Xen_check_type(Xen_is_false(arg2) || Xen_is_string(arg2), arg2, 2, "XtResolvePathname", "char*"); Xen_check_type(Xen_is_false(arg3) || Xen_is_string(arg3), arg3, 3, "XtResolvePathname", "char*"); Xen_check_type(Xen_is_false(arg4) || Xen_is_string(arg4), arg4, 4, "XtResolvePathname", "char*"); Xen_check_type(Xen_is_false(arg5) || Xen_is_string(arg5), arg5, 5, "XtResolvePathname", "char*"); Xen_check_type(Xen_is_false(arg6) || Xen_is_list(arg6), arg6, 6, "XtResolvePathname", "Substitution list"); Xen_check_type(Xen_is_integer(arg7), arg7, 7, "XtResolvePathname", "int"); Xen_check_type(Xen_is_false(arg8) || (Xen_is_procedure(arg8) && (Xen_is_aritable(arg8, 1))), arg8, 8, "XtResolvePathname", "XtFilePredicate (takes 1 arg)"); if (Xen_is_list(arg6)) { subs = gxm_make_subs(Xen_copy_arg(arg6)); if (subs == NULL) return(Xen_false); /* type error? */ } if (Xen_is_procedure(arg8)) { arg8_loc = xm_protect(arg8); xm_filepredicate_proc = arg8; } str = XtResolvePathname(Xen_to_C_Display(arg1), (Xen_is_false(arg2)) ? NULL : (char *)Xen_string_to_C_string(arg2), (Xen_is_false(arg3)) ? NULL : (char *)Xen_string_to_C_string(arg3), (Xen_is_false(arg4)) ? NULL : (char *)Xen_string_to_C_string(arg4), (Xen_is_false(arg5)) ? NULL : (char *)Xen_string_to_C_string(arg5), subs, Xen_integer_to_C_int(arg7), (Xen_is_false(arg8)) ? NULL : gxm_XtFilePredicate); if (Xen_is_procedure(arg8)) xm_unprotect_at(arg8_loc); if (subs) { int i, len; len = Xen_list_length(arg6); for (i = 0; i < len; i++) if (subs[i].substitution) free(subs[i].substitution); free(subs); } res = C_string_to_Xen_string(str); if (str) XtFree(str); return(res); } static Xen gxm_XtFindFile(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XtFindFile "String XtFindFile(path, substitutions, num_substitutions, predicate) \ searches for a file using substitutions in the path list" char *str; Xen res; int arg4_loc = -1; SubstitutionRec *subs = NULL; Xen_check_type(Xen_is_string(arg1), arg1, 1, "XtFindFile", "char*"); Xen_check_type(Xen_is_false(arg2) || Xen_is_list(arg2), arg2, 2, "XtFindFile", "Substitution list"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XtFindFile", "int"); Xen_check_type(Xen_is_false(arg4) || (Xen_is_procedure(arg4) && (Xen_is_aritable(arg4, 1))), arg4, 4, "XtFindFile", "XtFilePredicate (takes 1 arg)"); if (Xen_is_list(arg2)) { subs = gxm_make_subs(Xen_copy_arg(arg2)); if (subs == NULL) return(Xen_false); /* type error? */ } if (Xen_is_procedure(arg4)) { arg4_loc = xm_protect(arg4); xm_filepredicate_proc = arg4; } str = XtFindFile((char *)Xen_string_to_C_string(arg1), subs, Xen_integer_to_C_int(arg3), (Xen_is_false(arg4) ? NULL : gxm_XtFilePredicate)); if (Xen_is_procedure(arg4)) xm_unprotect_at(arg4_loc); if (subs) { int i, len; len = Xen_list_length(arg2); for (i = 0; i < len; i++) if (subs[i].substitution) free(subs[i].substitution); free(subs); } res = C_string_to_Xen_string(str); if (str) XtFree(str); return(res); } static Xen gxm_XtReleaseGC(Xen arg1, Xen arg2) { #define H_XtReleaseGC "void XtReleaseGC(w, gc) deallocate the specified shared GC." Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtReleaseGC", "Widget"); Xen_check_type(Xen_is_GC(arg2), arg2, 2, "XtReleaseGC", "GC"); XtReleaseGC(Xen_to_C_Widget(arg1), Xen_to_C_GC(arg2)); return(Xen_false); } static Xen gxm_XtDestroyGC(Xen arg1) { #define H_XtDestroyGC "XtDestroyGC(gc) is obsolete -- use XtReleaseGC" Xen_check_type(Xen_is_GC(arg1), arg1, 1, "XtDestroyGC", "GC"); XtDestroyGC(Xen_to_C_GC(arg1)); return(Xen_false); } static Xen gxm_XtAllocateGC(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6) { #define H_XtAllocateGC "GC XtAllocateGC(w, depth, value_mask, values, dynamic_mask, unused_mask): returns a sharable GC that may be modified by the client." Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtAllocateGC", "Widget"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XtAllocateGC", "int"); Xen_check_type(Xen_is_ulong(arg3), arg3, 3, "XtAllocateGC", "XtGCMask"); Xen_check_type(Xen_is_XGCValues(arg4), arg4, 4, "XtAllocateGC", "XGCValues*"); Xen_check_type(Xen_is_ulong(arg5), arg5, 5, "XtAllocateGC", "XtGCMask"); Xen_check_type(Xen_is_ulong(arg6), arg6, 6, "XtAllocateGC", "XtGCMask"); return(C_to_Xen_GC(XtAllocateGC(Xen_to_C_Widget(arg1), Xen_integer_to_C_int(arg2), Xen_ulong_to_C_ulong(arg3), Xen_to_C_XGCValues(arg4), Xen_ulong_to_C_ulong(arg5), Xen_ulong_to_C_ulong(arg6)))); } static Xen gxm_XtGetGC(Xen arg1, Xen arg2, Xen arg3) { #define H_XtGetGC "GC XtGetGC(w, value_mask, values): returns a sharable, read-only GC." Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtGetGC", "Widget"); Xen_check_type(Xen_is_ulong(arg2), arg2, 2, "XtGetGC", "XtGCMask"); Xen_check_type(Xen_is_XGCValues(arg3), arg3, 3, "XtGetGC", "XGCValues*"); return(C_to_Xen_GC(XtGetGC(Xen_to_C_Widget(arg1), Xen_ulong_to_C_ulong(arg2), Xen_to_C_XGCValues(arg3)))); } /* -------- background process -------- */ /* (80) XtWorkProc called (protected) until quits or removed explicitly */ #define C_to_Xen_XM_Background(Code, Context) \ Xen_list_5(C_string_to_Xen_symbol("Background"), Code, Context, Xen_integer_zero, Xen_integer_zero) #define XM_is_Background(Arg) is_wrapped("Background", Arg) static Boolean gxm_XtWorkProc(XtPointer cdata) { /* if true, quits */ int val; Xen descr = (Xen)cdata; /* (list 'Background function context gc-loc id) */ val = Xen_boolean_to_C_bool(Xen_call_with_1_arg(Xen_cadr(descr), Xen_caddr(descr), __func__)); if (val) xm_unprotect_at(Xen_integer_to_C_int(Xen_list_ref(descr, 3))); return(val); } static bool unprotect_workproc(Xen val, int loc, unsigned long id) { if ((XM_is_Background(val)) && ((XtWorkProcId)Xen_ulong_to_C_ulong(Xen_list_ref(val, 4)) == id)) { xm_unprotect_at(loc); return(true); } return(false); } static Xen gxm_XtRemoveWorkProc(Xen arg1) { #define H_XtRemoveWorkProc "void XtRemoveWorkProc(id) explicitly removes the specified background work procedure." XtWorkProcId id; Xen_check_type(Xen_is_XtWorkProcId(arg1), arg1, 1, "XtRemoveWorkProc", "XtWorkProcId"); id = Xen_to_C_XtWorkProcId(arg1); XtRemoveWorkProc(id); map_over_protected_elements(unprotect_workproc, id); return(Xen_false); } static Xen gxm_XtAppAddWorkProc(Xen arg1, Xen arg2, Xen arg3) { #define H_XtAppAddWorkProc "XtWorkProcId XtAppAddWorkProc(app_context, proc, client_data) adds the specified work procedure for the \ application identified by app_context." XtWorkProcId id; int gc_loc; Xen descr; Xen_check_type(Xen_is_XtAppContext(arg1), arg1, 1, "XtAppAddWorkProc", "XtAppContext"); Xen_check_type(Xen_is_procedure(arg2) && (Xen_is_aritable(arg2, 1)), arg2, 2, "XtAppAddWorkProc", "(XtWorkProc data)"); descr = C_to_Xen_XM_Background(arg2, (Xen_is_bound(arg3)) ? arg3 : Xen_false); gc_loc = xm_protect(descr); id = XtAppAddWorkProc(Xen_to_C_XtAppContext(arg1), gxm_XtWorkProc, (XtPointer)descr); Xen_list_set(descr, 3, C_int_to_Xen_integer(gc_loc)); Xen_list_set(descr, 4, C_ulong_to_Xen_ulong(id)); return(C_to_Xen_XtWorkProcId(id)); } /* the next 4 are needed where the caller allocates a block of memory, but X frees it (XCreateImage) -- * can't use Scheme-allocated memory here etc */ static Xen gxm_XtFree(Xen arg1) { #define H_XtFree "void XtFree(ptr)" char *ptr; Xen_check_type(Xen_is_wrapped_c_pointer(arg1), arg1, 1, "XtFree", "pointer"); ptr = (char *)Xen_unwrap_C_pointer(arg1); if (ptr) XtFree(ptr); return(Xen_false); } static Xen gxm_XtRealloc(Xen arg1, Xen arg2) { #define H_XtRealloc "char *XtRealloc(ptr, num)" int num; char *ptr; Xen_check_type(Xen_is_wrapped_c_pointer(arg1), arg1, 1, "XtRealloc", "pointer"); ptr = (char *)Xen_unwrap_C_pointer(arg1); if (!ptr) return(Xen_false); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XtRealloc", "int"); num = Xen_integer_to_C_int(arg2); if (num <= 0) Xen_out_of_range_error("XtRealloc", 2, arg2, "num should be positive"); return(C_ulong_to_Xen_ulong(XtRealloc(ptr, num))); } static Xen gxm_XtCalloc(Xen arg1, Xen arg2) { #define H_XtCalloc "char *XtCalloc(num, size)" int num, size; Xen_check_type(Xen_is_integer(arg1), arg1, 1, "XtCalloc", "int"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XtCalloc", "int"); num = Xen_integer_to_C_int(arg1); if (num <= 0) Xen_out_of_range_error("XtCalloc", 1, arg1, "num should be positive"); size = Xen_integer_to_C_int(arg2); if (size <= 0) Xen_out_of_range_error("XtCalloc", 2, arg2, "size should be positive"); return(Xen_wrap_C_pointer(XtCalloc(num, size))); /* dumb thing simply exits the main program on error! */ } static Xen gxm_XtMalloc(Xen arg1) { #define H_XtMalloc "char *XtMalloc(size)" int size; Xen_check_type(Xen_is_integer(arg1), arg1, 1, "XtMalloc", "int"); size = Xen_integer_to_C_int(arg1); if (size <= 0) Xen_out_of_range_error("XtMalloc", 1, arg1, "size should be positive"); return(Xen_wrap_C_pointer(XtMalloc(size))); } static Xen xm_XtErrorHandler; static Xen xm_XtWarningHandler; static void gxm_XtErrorHandler(String msg) { if (Xen_is_procedure(xm_XtErrorHandler)) Xen_call_with_1_arg(xm_XtErrorHandler, C_string_to_Xen_string(msg), __func__); } static Xen gxm_XtAppSetErrorHandler(Xen arg1, Xen arg2) { #define H_XtAppSetErrorHandler "void XtAppSetErrorHandler(app_context, handler) registers the specified procedure, which is called when \ a fatal error condition occurs." Xen old_val; Xen_check_type(Xen_is_XtAppContext(arg1), arg1, 1, "XtAppSetErrorHandler", "XtAppContext"); old_val = xm_XtErrorHandler; xm_protect(arg2); xm_XtErrorHandler = arg2; XtAppSetErrorHandler(Xen_to_C_XtAppContext(arg1), gxm_XtErrorHandler); if (Xen_is_procedure(old_val)) xm_unprotect(old_val); return(old_val); } static void gxm_XtWarningHandler(String msg) { if (Xen_is_procedure(xm_XtWarningHandler)) Xen_call_with_1_arg(xm_XtWarningHandler, C_string_to_Xen_string(msg), __func__); } static Xen gxm_XtAppSetWarningHandler(Xen arg1, Xen arg2) { #define H_XtAppSetWarningHandler "void XtAppSetWarningHandler(app_context, handler) registers the specified procedure, which is called \ when a nonfatal error condition occurs." Xen old_val; Xen_check_type(Xen_is_XtAppContext(arg1), arg1, 1, "XtAppSetWarningHandler", "XtAppContext"); old_val = xm_XtWarningHandler; xm_protect(arg2); xm_XtWarningHandler = arg2; XtAppSetWarningHandler(Xen_to_C_XtAppContext(arg1), gxm_XtWarningHandler); if (Xen_is_procedure(old_val)) xm_unprotect(old_val); return(old_val); } static Xen gxm_XtAppError(Xen arg1, Xen arg2) { #define H_XtAppError "void XtAppError(app_context, message) calls the installed error procedure and passes the specified message." Xen_check_type(Xen_is_XtAppContext(arg1), arg1, 1, "XtAppError", "XtAppContext"); Xen_check_type(Xen_is_string(arg2), arg2, 2, "XtAppError", "char*"); XtAppError(Xen_to_C_XtAppContext(arg1), (char *)Xen_string_to_C_string(arg2)); return(Xen_false); } static Xen gxm_XtAppWarningMsg(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6, Xen arg7) { #define H_XtAppWarningMsg "void XtAppWarningMsg(app_context, name, type, class, default, params, num_params) calls the high-level error \ handler and passes the specified information." /* DIFF: XtAppWarningMsg takes final int not int*, arg6 is list of strings */ int size; Cardinal csize; char **pars; Xen_check_type(Xen_is_XtAppContext(arg1), arg1, 1, "XtAppWarningMsg", "XtAppContext"); Xen_check_type(Xen_is_string(arg2), arg2, 2, "XtAppWarningMsg", "char*"); Xen_check_type(Xen_is_string(arg3), arg3, 3, "XtAppWarningMsg", "char*"); Xen_check_type(Xen_is_string(arg4), arg4, 4, "XtAppWarningMsg", "char*"); Xen_check_type(Xen_is_string(arg5), arg5, 5, "XtAppWarningMsg", "char*"); Xen_check_type(Xen_is_list(arg6), arg6, 6, "XtAppWarningMsg", "list of String"); Xen_check_type(Xen_is_integer(arg7), arg7, 7, "XtAppWarningMsg", "int"); size = Xen_integer_to_C_int(arg7); if (size <= 0) return(Xen_false); pars = Xen_to_C_Strings(arg6, size); csize = (Cardinal)size; XtAppWarningMsg(Xen_to_C_XtAppContext(arg1), (char *)Xen_string_to_C_string(arg2), (char *)Xen_string_to_C_string(arg3), (char *)Xen_string_to_C_string(arg4), (char *)Xen_string_to_C_string(arg5), pars, &csize); free(pars); return(Xen_false); } static Xen gxm_XtAppErrorMsg(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6, Xen arg7) { #define H_XtAppErrorMsg "void XtAppErrorMsg(app_context, name, type, class, default, params, num_params) calls the high-level error \ handler and passes the specified information." /* DIFF: XtAppErrorMsg takes final int not int*, arg6 is list of strings */ int size; Cardinal csize; char **pars; Xen_check_type(Xen_is_XtAppContext(arg1), arg1, 1, "XtAppErrorMsg", "XtAppContext"); Xen_check_type(Xen_is_string(arg2), arg2, 2, "XtAppErrorMsg", "char*"); Xen_check_type(Xen_is_string(arg3), arg3, 3, "XtAppErrorMsg", "char*"); Xen_check_type(Xen_is_string(arg4), arg4, 4, "XtAppErrorMsg", "char*"); Xen_check_type(Xen_is_string(arg5), arg5, 5, "XtAppErrorMsg", "char*"); Xen_check_type(Xen_is_list(arg6), arg6, 6, "XtAppErrorMsg", "list of String"); Xen_check_type(Xen_is_integer(arg7), arg7, 7, "XtAppErrorMsg", "int"); size = Xen_integer_to_C_int(arg7); if (size <= 0) return(Xen_false); pars = Xen_to_C_Strings(arg6, size); csize = (Cardinal)size; XtAppErrorMsg(Xen_to_C_XtAppContext(arg1), (char *)Xen_string_to_C_string(arg2), (char *)Xen_string_to_C_string(arg3), (char *)Xen_string_to_C_string(arg4), (char *)Xen_string_to_C_string(arg5), pars, &csize); free(pars); return(Xen_false); } static Xen xm_XtErrorMsgHandler; static Xen xm_XtWarningMsgHandler; static void gxm_XtErrorMsgHandler(String name, String type, String clas, String defp, String *pars, Cardinal *num) { /* DIFF: XtErrorMsgHandler takes list of string pars */ if ((Xen_is_procedure(xm_XtErrorMsgHandler)) && (num) && ((pars) || (*num == 0))) { Xen lst = Xen_empty_list; int i, len, loc; loc = xm_protect(lst); len = (*num); for (i = len - 1; i >= 0; i--) lst = Xen_cons(C_string_to_Xen_string(pars[i]), lst); Xen_call_with_6_args(xm_XtErrorMsgHandler, C_string_to_Xen_string(name), C_string_to_Xen_string(type), C_string_to_Xen_string(clas), C_string_to_Xen_string(defp), lst, C_int_to_Xen_integer(*num), __func__); xm_unprotect_at(loc); } } static Xen gxm_XtAppSetErrorMsgHandler(Xen arg1, Xen arg2) { #define H_XtAppSetErrorMsgHandler "void XtAppSetErrorMsgHandler(app_context, msg_handler) registers the specified procedure, which is called \ when a fatal error occurs." Xen old_val; Xen_check_type(Xen_is_XtAppContext(arg1), arg1, 1, "XtAppSetErrorMsgHandler", "XtAppContext"); old_val = xm_XtErrorMsgHandler; xm_protect(arg2); xm_XtErrorMsgHandler = arg2; XtAppSetErrorMsgHandler(Xen_to_C_XtAppContext(arg1), gxm_XtErrorMsgHandler); if (Xen_is_procedure(old_val)) xm_unprotect(old_val); return(old_val); } static void gxm_XtWarningMsgHandler(String name, String type, String clas, String defp, String *pars, Cardinal *num) { /* DIFF: XtWarningMsgHandler takes list of string pars */ if ((Xen_is_procedure(xm_XtWarningMsgHandler)) && (num) && ((pars) || (*num == 0))) { Xen lst = Xen_empty_list; int i, len, loc; loc = xm_protect(lst); len = (*num); for (i = len - 1; i >= 0; i--) lst = Xen_cons(C_string_to_Xen_string(pars[i]), lst); Xen_call_with_6_args(xm_XtWarningMsgHandler, C_string_to_Xen_string(name), C_string_to_Xen_string(type), C_string_to_Xen_string(clas), C_string_to_Xen_string(defp), lst, C_int_to_Xen_integer(*num), __func__); xm_unprotect_at(loc); } } static Xen gxm_XtAppSetWarningMsgHandler(Xen arg1, Xen arg2) { #define H_XtAppSetWarningMsgHandler "void XtAppSetWarningMsgHandler(app_context, msg_handler) registers the specified procedure, which \ is called when a nonfatal error condition occurs." Xen old_val; Xen_check_type(Xen_is_XtAppContext(arg1), arg1, 1, "XtAppSetWarningMsgHandler", "XtAppContext"); old_val = xm_XtWarningMsgHandler; xm_protect(arg2); xm_XtWarningMsgHandler = arg2; XtAppSetWarningMsgHandler(Xen_to_C_XtAppContext(arg1), gxm_XtWarningMsgHandler); if (Xen_is_procedure(old_val)) xm_unprotect(old_val); return(old_val); } static Xen gxm_XtGetValues(Xen arg1, Xen arg2, Xen arg3) { #define H_XtGetValues "void XtGetValues(Widget w, ArgList args, Cardinal num_args): returns the values of the \ resources specified for the widget w. In xm, 'args' is a list of resource names followed by a placeholder \ (normally 0), and the length of the arglist is optional. For example, to get the current height and width \ of a widget, (" XM_PREFIX "XtGetValues" XM_POSTFIX " w (list " XM_PREFIX "XmNheight" XM_POSTFIX " 0 \ " XM_PREFIX "XmNwidth" XM_POSTFIX " 0)) which returns the list with the values filled in: (list height 123 \ width 321). If the resource value is an array in C, it is returned as a list." Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtGetValues", "Widget"); Xen_check_type(Xen_is_list(arg2), arg2, 2, "XtGetValues", "List"); Xen_check_type(Xen_is_integer_or_unbound(arg3), arg3, 3, "XtGetValues", "int"); return(gxm_XtGetValues_1(arg1, arg2, Xen_to_C_INT_DEF(arg3, arg2))); } static Xen gxm_XtVaGetValues(Xen arg1, Xen arg2) { #define H_XtVaGetValues "void XtVaGetValues(w, ...) in xm is the same as XtGetValues." /* DIFF: XtVaGetValues -> returns original list with vals in place */ Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtVaGetValues", "Widget"); Xen_check_type(Xen_is_list(arg2), arg2, 2, "XtVaGetValues", "List"); return(gxm_XtGetValues_1(arg1, arg2, Xen_list_length(arg2) / 2)); } static Xen gxm_XtVaSetValues(Xen arg1, Xen arg2) { #define H_XtVaSetValues "void XtVaSetValues(w, ...) in xm is the same as XtSetValues." Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtVaSetValues", "Widget"); Xen_check_type(Xen_is_list(arg2), arg2, 2, "XtVaSetValues", "List"); { Widget w; Arg *args; int arglen; args = Xen_to_C_Args(arg2); w = Xen_to_C_Widget(arg1); arglen = Xen_list_length(arg2) / 2; XtSetValues(w, args, arglen); if (args) { fixup_args(w, args, arglen); free_args(args, arglen); } } return(Xen_false); } static Xen gxm_XtSetValues(Xen arg1, Xen arg2, Xen arg3) { #define H_XtSetValues "void XtSetValues(Widget w, ArgList args, Cardinal num_args) sets the values of the \ resources specified for the widget w. In xm, 'args' is a list of resource names followed by the new value, \ and the length of the arglist is optional. For example, to set the current height and width \ of a widget, (" XM_PREFIX "XtSetValues" XM_POSTFIX " w (list " XM_PREFIX "XmNheight" XM_POSTFIX " 123 \ " XM_PREFIX "XmNwidth" XM_POSTFIX " 321)). If the resource value in C is an array, it is a list in xm." Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtSetValues", "Widget"); Xen_check_type(Xen_is_list(arg2), arg2, 2, "XtSetValues", "ArgList"); Xen_check_type(Xen_is_integer_or_unbound(arg3), arg3, 3, "XtSetValues", "int"); { Arg *args; int arglen; Widget w; w = Xen_to_C_Widget(arg1); args = Xen_to_C_Args(arg2); arglen = Xen_to_C_INT_DEF(arg3, arg2); XtSetValues(w, args, arglen); if (args) { fixup_args(w, args, arglen); free_args(args, arglen); } } return(Xen_false); } static Xen gxm_XtCloseDisplay(Xen arg1) { #define H_XtCloseDisplay "void XtCloseDisplay(display) closes the specified display as soon as it is safe to do so." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XtCloseDisplay", "Display*"); XtCloseDisplay(Xen_to_C_Display(arg1)); return(Xen_false); } static Xen gxm_XtDisplayToApplicationContext(Xen arg1) { #define H_XtDisplayToApplicationContext "XtAppContext XtDisplayToApplicationContext(dpy): returns the application context for the specified display." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XtDisplayToApplicationContext", "Display*"); return(C_to_Xen_XtAppContext(XtDisplayToApplicationContext(Xen_to_C_Display(arg1)))); } static Xen gxm_XtWidgetToApplicationContext(Xen arg1) { #define H_XtWidgetToApplicationContext "XtAppContext XtWidgetToApplicationContext(w): returns the application context for the specified widget." Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtWidgetToApplicationContext", "Widget"); return(C_to_Xen_XtAppContext(XtWidgetToApplicationContext(Xen_to_C_Widget(arg1)))); } static Xen gxm_XtInitializeWidgetClass(Xen arg1) { #define H_XtInitializeWidgetClass "void XtInitializeWidgetClass(object_class)" Xen_check_type(Xen_is_WidgetClass(arg1), arg1, 1, "XtInitializeWidgetClass", "WidgetClass"); XtInitializeWidgetClass(Xen_to_C_WidgetClass(arg1)); return(Xen_false); } static Xen gxm_XtDestroyApplicationContext(Xen arg1) { #define H_XtDestroyApplicationContext "void XtDestroyApplicationContext(app_context) destroys the specified application context as soon as it is safe to do so." Xen_check_type(Xen_is_XtAppContext(arg1), arg1, 1, "XtDestroyApplicationContext", "XtAppContext"); XtDestroyApplicationContext(Xen_to_C_XtAppContext(arg1)); return(Xen_false); } static Xen gxm_XtCreateApplicationContext(void) { #define H_XtCreateApplicationContext "XtAppContext XtCreateApplicationContext()" return(C_to_Xen_XtAppContext(XtCreateApplicationContext())); } static Xen gxm_argv_to_list(Xen lst, int argc, char **argv) { int i, loc; if (argc == 0) return(lst); loc = xm_protect(lst); for (i = argc - 1; i >= 0; i--) lst = Xen_cons(C_string_to_Xen_string(argv[i]), lst); free(argv); xm_unprotect_at(loc); return(lst); } static Xen gxm_XtOpenDisplay(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg7, Xen arg8) { #define H_XtOpenDisplay "Display *XtOpenDisplay(app_context, display_string, application_name, application_class, argc, argv) \ calls XOpenDisplay the specified display name." /* DIFF: XtOpenDisplay ignore arg5 6, argc is int, argv is list of strings, returns (list dpy argv ...) */ char **argv = NULL; int argc; Xen lst = Xen_empty_list; Display *dpy; Xen_check_type(Xen_is_XtAppContext(arg1), arg1, 1, "XtOpenDisplay", "XtAppContext"); Xen_check_type(Xen_is_string(arg2) || Xen_is_false(arg2), arg2, 2, "XtOpenDisplay", "char*"); Xen_check_type(Xen_is_string(arg3), arg3, 3, "XtOpenDisplay", "char*"); Xen_check_type(Xen_is_string(arg4), arg4, 4, "XtOpenDisplay", "char*"); Xen_check_type(Xen_is_integer(arg7), arg7, 5, "XtOpenDisplay", "int"); Xen_check_type(Xen_is_list(arg8), arg8, 6, "XtOpenDisplay", "list of char*"); argc = Xen_integer_to_C_int(arg7); if (Xen_list_length(arg8) != argc) return(Xen_false); /* error? */ if (argc > 0) argv = Xen_to_C_Strings(arg8, argc); dpy = XtOpenDisplay(Xen_to_C_XtAppContext(arg1), (Xen_is_false(arg2)) ? NULL : (char *)Xen_string_to_C_string(arg2), (char *)Xen_string_to_C_string(arg3), (char *)Xen_string_to_C_string(arg4), NULL, 0, &argc, argv); if (dpy) lst = Xen_cons(C_to_Xen_Display(dpy), lst); else lst = Xen_cons(Xen_false, lst); return(gxm_argv_to_list(lst, argc, argv)); } static Xen gxm_XtAppSetFallbackResources(Xen app, Xen specs) { #define H_XtAppSetFallbackResources "XtAppSetFallbackResources(app, list-of-strings) sets the app's default resource values \ from the list of strings" char **fallbacks; int i, len; Xen lst; Xen_check_type(Xen_is_XtAppContext(app), app, 1, "XtAppSetFallbackResources", "XtAppContext"); Xen_check_type(Xen_is_list(specs), specs, 2, "XtAppSetFallbackResources", "list of char*"); len = Xen_list_length(specs); lst = Xen_copy_arg(specs); fallbacks = (char **)calloc(len + 1, sizeof(char *)); /* +1 for null termination */ for (i = 0; i < len; i++, lst = Xen_cdr(lst)) fallbacks[i] = (char *)Xen_string_to_C_string(Xen_car(lst)); XtAppSetFallbackResources(Xen_to_C_XtAppContext(app), fallbacks); free(fallbacks); return(app); } static Xen gxm_XtVaAppInitialize(Xen arg2, Xen arg5, Xen arg6, Xen arg8, Xen specs) { #define H_XtVaAppInitialize "Widget XtVaAppInitialize(application_class, argc_in_out, argv_in_out, args, fallbacks) -- the order \ of the arguments is slightly different from the C Xt call. The final arg is an (optional) list of strings." /* DIFF: XtVaAppInitialize [app] class {options numopts} {argc} argv resources -> (list widget app (new argv)), argc is int not int* options/num ignored Arg *args; app is returned not passed (list widget app) */ XtAppContext app; Arg *args; Widget res; int i, len = 0, argc, arglen; char **argv = NULL; char **fallbacks = NULL; Xen_check_type(Xen_is_string(arg2), arg2, 1, "XtVaAppInitialize", "char*"); Xen_check_type(Xen_is_integer(arg5), arg5, 2, "XtVaAppInitialize", "int"); Xen_check_type(Xen_is_list(arg6), arg6, 3, "XtVaAppInitialize", "list of String"); Xen_check_type(Xen_is_list(arg8), arg8, 4, "XtVaAppInitialize", "arg list"); Xen_check_type(Xen_is_list(specs) || !Xen_is_bound(specs), specs, 5, "XtVaAppInitialize", "list of char*"); argc = Xen_integer_to_C_int(arg5); if (Xen_list_length(arg6) != argc) return(Xen_false); /* error? */ if (argc > 0) argv = Xen_to_C_Strings(arg6, argc); if (Xen_is_list(specs)) { Xen lst; int gcloc; len = Xen_list_length(specs); if (len <= 0) return(Xen_false); lst = Xen_copy_arg(specs); gcloc = xm_protect(lst); fallbacks = (char **)calloc(len + 1, sizeof(char *)); /* +1 for null termination */ for (i = 0; i < len; i++, lst = Xen_cdr(lst)) { if (!Xen_is_string(Xen_car(lst))) { free(fallbacks); xm_unprotect_at(gcloc); return(Xen_false); } fallbacks[i] = xen_strdup(Xen_string_to_C_string(Xen_car(lst))); } xm_unprotect_at(gcloc); } args = Xen_to_C_Args(arg8); arglen = Xen_list_length(arg8) / 2; res = XtAppInitialize(&app, (char *)Xen_string_to_C_string(arg2), NULL, 0, &argc, argv, fallbacks, args, arglen); if (args) { fixup_args(res, args, arglen); free_args(args, arglen); } if (fallbacks) { for (i = 0; i < len; i++) if (fallbacks[i]) free(fallbacks[i]); free(fallbacks); } return(Xen_list_3(C_to_Xen_Widget(res), C_to_Xen_XtAppContext(app), gxm_argv_to_list(Xen_empty_list, argc, argv))); } static Xen gxm_XtAppInitialize(Xen arg2, Xen arg5, Xen arg6, Xen arg8, Xen arg9) { #define H_XtAppInitialize "Widget XtAppInitialize(application_class, argc_in_out, argv_in_out, \ args, num_args) calls XtToolkitInitialize followed by XtCreateApplicationContext ,then calls XtOpenDisplay with \ display_string NULL and application_name NULL, and finally calls XtAppCreateShell with appcation_name NULL, widget_class applicationShellWidgetClass , \ and the specified args and num_args and returns the created shell. The num_args argument can be list of strings = fallback resources" /* DIFF: XtAppInitialize [app] class {options numopts} {argc} argv resources args numargs -> (list widget app), argc is int not int* options/num ignored Arg *args; app is returned not passed (list widget app) */ XtAppContext app; Arg *args; Widget res; int argc, arglen; char **argv = NULL; char **fallbacks = NULL; int i, len = 0; Xen_check_type(Xen_is_string(arg2), arg2, 1, "XtAppInitialize", "char*"); Xen_check_type(Xen_is_integer(arg5), arg5, 2, "XtAppInitialize", "int"); Xen_check_type(Xen_is_list(arg6), arg6, 3, "XtAppInitialize", "list of String*"); Xen_check_type(Xen_is_list(arg8), arg8, 4, "XtAppInitialize", "ArgList"); Xen_check_type(Xen_is_integer(arg9) || Xen_is_list(arg9) || !Xen_is_bound(arg9), arg9, 5, "XtAppInitialize", "int or list of strings"); /* num_args */ argc = Xen_integer_to_C_int(arg5); if (Xen_list_length(arg6) != argc) return(Xen_false); /* error? */ if (argc > 0) argv = Xen_to_C_Strings(arg6, argc); args = Xen_to_C_Args(arg8); if (Xen_is_integer(arg9)) arglen = Xen_integer_to_C_int(arg9); else arglen = Xen_list_length(arg8) / 2; if (Xen_is_list(arg9)) { Xen lst; int gcloc; len = Xen_list_length(arg9); lst = Xen_copy_arg(arg9); gcloc = xm_protect(lst); fallbacks = (char **)calloc(len + 1, sizeof(char *)); /* +1 for null termination */ for (i = 0; i < len; i++, lst = Xen_cdr(lst)) fallbacks[i] = xen_strdup(Xen_string_to_C_string(Xen_car(lst))); xm_unprotect_at(gcloc); } res = XtAppInitialize(&app, (char *)Xen_string_to_C_string(arg2), NULL, 0, &argc, argv, fallbacks, args, arglen); if (args) { fixup_args(res, args, arglen); free_args(args, arglen); } if (fallbacks) { for (i = 0; i < len; i++) if (fallbacks[i]) free(fallbacks[i]); free(fallbacks); } return(Xen_list_3(C_to_Xen_Widget(res), C_to_Xen_XtAppContext(app), gxm_argv_to_list(Xen_empty_list, argc, argv))); } static Xen gxm_XtVaOpenApplication(Xen arg1, Xen arg4, Xen arg5, Xen arg7, Xen arg8, Xen specs) { #define H_XtVaOpenApplication "Widget XtVaOpenApplication(application_class, argc_in_out, argv_in_out, widget_class, args, fallbacks)" /* DIFF: XtVaOpenApplication [app] name {options numopts} {argc} argv resources class args -> (list widget app), argc is int not int* options/num ignored Arg *args; app is returned not passed (list widget app) */ XtAppContext app; Arg *args; Widget res; int argc, arglen; char **argv = NULL; char **fallbacks = NULL; int i, len = 0; Xen_check_type(Xen_is_string(arg1), arg1, 1, "XtVaOpenApplication", "char*"); Xen_check_type(Xen_is_integer(arg4), arg4, 2, "XtVaOpenApplication", "int"); /* was arg3 by mistake, 11-Oct-02 */ Xen_check_type(Xen_is_list(arg5), arg5, 3, "XtVaOpenApplication", "list of String"); Xen_check_type(Xen_is_WidgetClass(arg7), arg7, 4, "XtVaOpenApplication", "WidgetClass"); Xen_check_type(Xen_is_list(arg8), arg8, 5, "XtVaOpenApplication", "arg list"); Xen_check_type(Xen_is_list(specs) || !Xen_is_bound(specs), specs, 5, "XtVaOpenApplication", "list of char*"); argc = Xen_integer_to_C_int(arg4); if (Xen_list_length(arg5) != argc) return(Xen_false); /* error? */ if (argc > 0) argv = Xen_to_C_Strings(arg5, argc); if (Xen_is_list(specs)) { Xen lst; int gcloc; len = Xen_list_length(specs); lst = Xen_copy_arg(specs); gcloc = xm_protect(lst); fallbacks = (char **)calloc(len + 1, sizeof(char *)); /* +1 for null termination */ for (i = 0; i < len; i++, lst = Xen_cdr(lst)) fallbacks[i] = xen_strdup(Xen_string_to_C_string(Xen_car(lst))); xm_unprotect_at(gcloc); } args = Xen_to_C_Args(arg8); arglen = Xen_list_length(arg8) / 2; res = XtOpenApplication(&app, (char *)Xen_string_to_C_string(arg1), NULL, 0, &argc, argv, fallbacks, Xen_to_C_WidgetClass(arg7), args, arglen); if (args) { fixup_args(res, args, arglen); free_args(args, arglen); } if (fallbacks) { for (i = 0; i < len; i++) if (fallbacks[i]) free(fallbacks[i]); free(fallbacks); } return(Xen_list_3(C_to_Xen_Widget(res), C_to_Xen_XtAppContext(app), gxm_argv_to_list(Xen_empty_list, argc, argv))); } static Xen gxm_XtOpenApplication(Xen arg1, Xen arg4, Xen arg5, Xen arg7, Xen arg8, Xen arg9) { #define H_XtOpenApplication "Widget XtOpenApplication(application_class, argc_in_out, argv_in_out, \ widget_class, args, num_args) calls XtToolkitInitialize followed by XtCreateApplicationContext , then calls XtOpenDisplay \ with display_string NULL and application_name NULL, and finally calls XtAppCreateShell with appcation_name NULL, widget_class \ applicationShellWidgetClass ,and the specified args and num_args and returns the created shell. num_args can also be a list \ of fallback resources." /* DIFF: XtOpenApplication [app] name {options numopts} {argc} argv resources class args argnum -> (list widget app), argc is int not int* options/num ignored */ XtAppContext app; Arg *args; Widget res; int argc, arglen; char **argv; char **fallbacks = NULL; int i, len = 0; Xen_check_type(Xen_is_string(arg1), arg1, 1, "XtOpenApplication", "char*"); Xen_check_type(Xen_is_integer(arg4), arg4, 2, "XtOpenApplication", "int"); Xen_check_type(Xen_is_list(arg5), arg5, 3, "XtOpenApplication", "list of String*"); Xen_check_type(Xen_is_WidgetClass(arg7), arg7, 4, "XtOpenApplication", "WidgetClass"); Xen_check_type(Xen_is_list(arg8), arg8, 8, "XtOpenApplication", "ArgList"); Xen_check_type(Xen_is_integer(arg9) || Xen_is_list(arg9) || !Xen_is_bound(arg9), arg9, 5, "XtOpenApplication", "int or list of strings"); /* num_args */ argc = Xen_integer_to_C_int(arg4); argv = Xen_to_C_Strings(arg5, argc); args = Xen_to_C_Args(arg8); if (Xen_is_integer(arg9)) arglen = Xen_integer_to_C_int(arg9); else arglen = Xen_list_length(arg8) / 2; if (Xen_is_list(arg9)) { Xen lst; int gcloc; len = Xen_list_length(arg9); lst = Xen_copy_arg(arg9); gcloc = xm_protect(lst); fallbacks = (char **)calloc(len + 1, sizeof(char *)); /* +1 for null termination */ for (i = 0; i < len; i++, lst = Xen_cdr(lst)) fallbacks[i] = (char *)Xen_string_to_C_string(Xen_car(lst)); xm_unprotect_at(gcloc); } res = XtOpenApplication(&app, (char *)Xen_string_to_C_string(arg1), NULL, 0, &argc, argv, fallbacks, Xen_to_C_WidgetClass(arg7), args, arglen); if (args) { fixup_args(res, args, arglen); free_args(args, arglen); } if (fallbacks) { for (i = 0; i < len; i++) if (fallbacks[i]) free(fallbacks[i]); free(fallbacks); } return(Xen_list_3(C_to_Xen_Widget(res), C_to_Xen_XtAppContext(app), gxm_argv_to_list(Xen_empty_list, argc, argv))); } static Xen gxm_XtDisplayInitialize(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg7, Xen arg8) { #define H_XtDisplayInitialize "void XtDisplayInitialize(app_context, display, application_name, application_class, argc, argv) \ builds the resource database, calls the Xlib XrmParseCommand to parse the command line, and performs other per display initialization." /* DIFF: XtDisplayInitialize arg 5 6 ignored, argc is normal int, argv is list of strings, returns argv */ char **argv; int argc; Xen_check_type(Xen_is_XtAppContext(arg1), arg1, 1, "XtDisplayInitialize", "XtAppContext"); Xen_check_type(Xen_is_Display(arg2), arg2, 2, "XtDisplayInitialize", "Display*"); Xen_check_type(Xen_is_string(arg3), arg3, 3, "XtDisplayInitialize", "char*"); Xen_check_type(Xen_is_string(arg4), arg4, 4, "XtDisplayInitialize", "char*"); Xen_check_type(Xen_is_integer(arg7), arg7, 5, "XtDisplayInitialize", "int"); Xen_check_type(Xen_is_list(arg8), arg8, 6, "XtDisplayInitialize", "list of char*"); argc = Xen_integer_to_C_int(arg7); argv = Xen_to_C_Strings(arg8, argc); XtDisplayInitialize(Xen_to_C_XtAppContext(arg1), Xen_to_C_Display(arg2), (char *)Xen_string_to_C_string(arg3), (char *)Xen_string_to_C_string(arg4), NULL, 0, &argc, argv); return(gxm_argv_to_list(Xen_empty_list, argc, argv)); } /* -------- XtLanguage callback -------- */ /* (456) a global */ static Xen xm_language_proc; static String gxm_XtLanguageProc(Display* d, String s, XtPointer context) { char *res; res = (char *)Xen_string_to_C_string(Xen_call_with_3_args(xm_language_proc, C_to_Xen_Display(d), C_string_to_Xen_string(s), (Xen)context, __func__)); if (res) return(xen_strdup(res)); return(NULL); } static Xen gxm_XtSetLanguageProc(Xen arg1, Xen arg2, Xen arg3) { #define H_XtSetLanguageProc "Widget XtSetLanguageProc(app_context, proc, client_data)" /* arg can be null -> use default */ /* DIFF: XtSetLanguageProc args1 and 2 use #f for NULL, return of #f means none was set */ Xen previous_proc = Xen_false; Xen_check_type(Xen_is_false(arg1) || Xen_is_XtAppContext(arg1), arg1, 1, "XtSetLanguageProc", "XtAppContext"); Xen_check_type(Xen_is_false(arg2) || (Xen_is_procedure(arg2) && (Xen_is_aritable(arg2, 3))), arg2, 2, "XtSetLanguageProc", "XtLanguageProc"); previous_proc = xm_language_proc; if (Xen_is_procedure(previous_proc)) xm_unprotect(previous_proc); if (Xen_is_procedure(arg2)) xm_protect(arg2); if (Xen_is_false(arg1)) { if (Xen_is_false(arg2)) XtSetLanguageProc(NULL, NULL, NULL); else XtSetLanguageProc(NULL, (XtLanguageProc)gxm_XtLanguageProc, (XtPointer)arg3); } else { if (Xen_is_false(arg2)) XtSetLanguageProc(Xen_to_C_XtAppContext(arg1), NULL, NULL); else XtSetLanguageProc(Xen_to_C_XtAppContext(arg1), (XtLanguageProc)gxm_XtLanguageProc, (XtPointer)arg3); } return(previous_proc); } static Xen gxm_XtToolkitInitialize(void) { #define H_XtToolkitInitialize "void XtToolkitInitialize()" XtToolkitInitialize(); return(Xen_false); } static Xen gxm_XtVaAppCreateShell(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5) { #define H_XtVaAppCreateShell "Widget XtVaAppCreateShell(application_name, application_class, widget_class, display, ...)" Arg *args; Widget w; int arglen; Xen_check_type(Xen_is_string(arg1), arg1, 1, "XtVaAppCreateShell", "char*"); Xen_check_type(Xen_is_string(arg2), arg2, 2, "XtVaAppCreateShell", "char*"); Xen_check_type(Xen_is_WidgetClass(arg3), arg3, 3, "XtVaAppCreateShell", "WidgetClass"); Xen_check_type(Xen_is_Display(arg4), arg4, 4, "XtVaAppCreateShell", "Display*"); Xen_check_type(Xen_is_list(arg5), arg5, 5, "XtVaAppCreateShell", "List"); args = Xen_to_C_Args(arg5); arglen = Xen_list_length(arg5) / 2; w = XtAppCreateShell((char *)Xen_string_to_C_string(arg1), (char *)Xen_string_to_C_string(arg2), Xen_to_C_WidgetClass(arg3), Xen_to_C_Display(arg4), args, arglen); if (args) { fixup_args(w, args, arglen); free_args(args, arglen); } return(C_to_Xen_Widget(w)); } static Xen gxm_XtAppCreateShell(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6) { #define H_XtAppCreateShell "Widget XtAppCreateShell(application_name, application_class, widget_class, display, args, num_args) saves \ the specified application name and application class for qualifying all widget resource specifiers." Arg *args; Widget w; int arglen; Xen_check_type(Xen_is_string(arg1), arg1, 1, "XtAppCreateShell", "char*"); Xen_check_type(Xen_is_string(arg2), arg2, 2, "XtAppCreateShell", "char*"); Xen_check_type(Xen_is_WidgetClass(arg3), arg3, 3, "XtAppCreateShell", "WidgetClass"); Xen_check_type(Xen_is_Display(arg4), arg4, 4, "XtAppCreateShell", "Display*"); Xen_check_type(Xen_is_list(arg5), arg5, 5, "XtAppCreateShell", "ArgList"); Xen_check_type(Xen_is_integer_or_unbound(arg6), arg6, 6, "XtAppCreateShell", "int"); args = Xen_to_C_Args(arg5); arglen = Xen_to_C_INT_DEF(arg6, arg5); w = XtAppCreateShell((char *)Xen_string_to_C_string(arg1), (char *)Xen_string_to_C_string(arg2), Xen_to_C_WidgetClass(arg3), Xen_to_C_Display(arg4), args, arglen); if (args) { fixup_args(w, args, arglen); free_args(args, arglen); } return(C_to_Xen_Widget(w)); } static Xen gxm_XtVaCreateManagedWidget(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XtVaCreateManagedWidget "Widget XtVaCreateManagedWidget(name, widget_class, parent, ...)" Arg *args; Widget w; int arglen; Xen_check_type(Xen_is_string(arg1), arg1, 1, "XtVaCreateManagedWidget", "char*"); Xen_check_type(Xen_is_WidgetClass(arg2), arg2, 2, "XtVaCreateManagedWidget", "WidgetClass"); Xen_check_type(Xen_is_Widget(arg3), arg3, 3, "XtVaCreateManagedWidget", "Widget"); Xen_check_type(Xen_is_list(arg4), arg4, 4, "XtVaCreateManagedWidget", "List"); args = Xen_to_C_Args(arg4); arglen = Xen_list_length(arg4) / 2; w = XtCreateManagedWidget((char *)Xen_string_to_C_string(arg1), Xen_to_C_WidgetClass(arg2), Xen_to_C_Widget(arg3), args, arglen); if (args) { fixup_args(w, args, arglen); free_args(args, arglen); } return(C_to_Xen_Widget(w)); } static Xen gxm_XtVaCreateWidget(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XtVaCreateWidget "Widget XtVaCreateWidget(name, widget_class, parent, ...)" Arg *args; int arglen; Widget w; Xen_check_type(Xen_is_string(arg1), arg1, 1, "XtVaCreateWidget", "char*"); Xen_check_type(Xen_is_WidgetClass(arg2), arg2, 2, "XtVaCreateWidget", "WidgetClass"); Xen_check_type(Xen_is_Widget(arg3), arg3, 3, "XtVaCreateWidget", "Widget"); Xen_check_type(Xen_is_list(arg4), arg4, 4, "XtVaCreateWidget", "List"); args = Xen_to_C_Args(arg4); arglen = Xen_list_length(arg4) / 2; w = XtCreateWidget((char *)Xen_string_to_C_string(arg1), Xen_to_C_WidgetClass(arg2), Xen_to_C_Widget(arg3), args, arglen); if (args) { fixup_args(w, args, arglen); free_args(args, arglen); } return(C_to_Xen_Widget(w)); } static Xen gxm_XtCreateManagedWidget(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5) { #define H_XtCreateManagedWidget "Widget XtCreateManagedWidget(name, widget_class, parent, args, num_args) is a routine \ that calls XtCreateWidget and XtManageChild." Arg *args; Widget w; int arglen; Xen_check_type(Xen_is_string(arg1), arg1, 1, "XtCreateManagedWidget", "char*"); Xen_check_type(Xen_is_WidgetClass(arg2), arg2, 2, "XtCreateManagedWidget", "WidgetClass"); Xen_check_type(Xen_is_Widget(arg3), arg3, 3, "XtCreateManagedWidget", "Widget"); Xen_check_type(Xen_is_list(arg4), arg4, 4, "XtCreateManagedWidget", "ArgList"); Xen_check_type(Xen_is_integer_or_unbound(arg5), arg5, 5, "XtCreateManagedWidget", "int"); args = Xen_to_C_Args(arg4); arglen = Xen_to_C_INT_DEF(arg5, arg4); w = XtCreateManagedWidget((char *)Xen_string_to_C_string(arg1), Xen_to_C_WidgetClass(arg2), Xen_to_C_Widget(arg3), args, arglen); if (args) { fixup_args(w, args, arglen); free_args(args, arglen); } return(C_to_Xen_Widget(w)); } static Xen gxm_XtCreateWidget(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5) { #define H_XtCreateWidget "Widget XtCreateWidget(name, widget_class, parent, args, num_args) performs much of the boilerplate operations of widget creation." Arg *args; Widget w; int arglen; Xen_check_type(Xen_is_string(arg1), arg1, 1, "XtCreateWidget", "char*"); Xen_check_type(Xen_is_WidgetClass(arg2), arg2, 2, "XtCreateWidget", "WidgetClass"); Xen_check_type(Xen_is_Widget(arg3), arg3, 3, "XtCreateWidget", "Widget"); Xen_check_type(Xen_is_list(arg4), arg4, 4, "XtCreateWidget", "ArgList"); Xen_check_type(Xen_is_integer_or_unbound(arg5), arg5, 5, "XtCreateWidget", "int"); args = Xen_to_C_Args(arg4); arglen = Xen_to_C_INT_DEF(arg5, arg4); w = XtCreateWidget((char *)Xen_string_to_C_string(arg1), Xen_to_C_WidgetClass(arg2), Xen_to_C_Widget(arg3), args, arglen); if (args) { fixup_args(w, args, arglen); free_args(args, arglen); } return(C_to_Xen_Widget(w)); } static Xen gxm_XtCallbackPopdown(Xen arg1, Xen arg2, Xen arg3) { #define H_XtCallbackPopdown "void XtCallbackPopdown(w, client_data, call_data) calls XtPopdown with the specified shell_widget and then \ calls XtSetSensitive to resensitize the enable_widget." Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtCallbackPopdown", "Widget"); XtCallbackPopdown(Xen_to_C_Widget(arg1), (XtPointer)arg2, (XtPointer)arg3); return(Xen_false); } static Xen gxm_XtPopdown(Xen arg1) { #define H_XtPopdown "void XtPopdown(popup_shell)" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtPopdown", "Widget"); XtPopdown(Xen_to_C_Widget(arg1)); return(Xen_false); } static Xen gxm_XtCallbackExclusive(Xen arg1, Xen arg2, Xen arg3) { #define H_XtCallbackExclusive "void XtCallbackExclusive(w, client_data, call_data)" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtCallbackExclusive", "Widget"); XtCallbackExclusive(Xen_to_C_Widget(arg1), (XtPointer)arg2, (XtPointer)arg3); return(Xen_false); } static Xen gxm_XtCallbackNonexclusive(Xen arg1, Xen arg2, Xen arg3) { #define H_XtCallbackNonexclusive "void XtCallbackNonexclusive(w, client_data, call_data)" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtCallbackNonexclusive", "Widget"); XtCallbackNonexclusive(Xen_to_C_Widget(arg1), (XtPointer)arg2, (XtPointer)arg3); return(Xen_false); } static Xen gxm_XtCallbackNone(Xen arg1, Xen arg2, Xen arg3) { #define H_XtCallbackNone "void XtCallbackNone(w, client_data, call_data)" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtCallbackNone", "Widget"); XtCallbackNone(Xen_to_C_Widget(arg1), (XtPointer)arg2, (XtPointer)arg3); return(Xen_false); } static Xen gxm_XtPopupSpringLoaded(Xen arg1) { #define H_XtPopupSpringLoaded "void XtPopupSpringLoaded(popup_shell)" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtPopupSpringLoaded", "Widget"); XtPopupSpringLoaded(Xen_to_C_Widget(arg1)); return(Xen_false); } static Xen gxm_XtPopup(Xen arg1, Xen arg2) { #define H_XtPopup "void XtPopup(popup_shell, grab_kind)" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtPopup", "Widget"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XtPopup", "XtGrabKind"); XtPopup(Xen_to_C_Widget(arg1), (XtGrabKind)Xen_integer_to_C_int(arg2)); return(Xen_false); } static Xen gxm_XtVaCreatePopupShell(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XtVaCreatePopupShell "Widget XtVaCreatePopupShell(name, widget_class, parent, ...)" Arg *args; int arglen; Widget w; Xen_check_type(Xen_is_string(arg1), arg1, 1, "XtVaCreatePopupShell", "char*"); Xen_check_type(Xen_is_WidgetClass(arg2), arg2, 2, "XtVaCreatePopupShell", "WidgetClass"); Xen_check_type(Xen_is_Widget(arg3), arg3, 3, "XtVaCreatePopupShell", "Widget"); Xen_check_type(Xen_is_list(arg4), arg4, 4, "XtVaCreatePopupShell", "List"); args = Xen_to_C_Args(arg4); arglen = Xen_list_length(arg4) / 2; w = XtCreatePopupShell((char *)Xen_string_to_C_string(arg1), Xen_to_C_WidgetClass(arg2), Xen_to_C_Widget(arg3), args, arglen); if (args) { fixup_args(w, args, arglen); free_args(args, arglen); } return(C_to_Xen_Widget(w)); } static Xen gxm_XtCreatePopupShell(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5) { #define H_XtCreatePopupShell "Widget XtCreatePopupShell(name, widget_class, parent, args, num_args) ensures that the specified \ class is a subclass of Shell and, rather than using insert_child to attach the widget to the parent's children list, attaches the shell \ to the parent's pop-ups list directly." Widget w; Xen_check_type(Xen_is_string(arg1), arg1, 1, "XtCreatePopupShell", "char*"); Xen_check_type(Xen_is_WidgetClass(arg2), arg2, 2, "XtCreatePopupShell", "WidgetClass"); Xen_check_type(Xen_is_Widget(arg3), arg3, 3, "XtCreatePopupShell", "Widget"); Xen_check_type(Xen_is_list(arg4), arg4, 4, "XtCreatePopupShell", "ArgList"); Xen_check_type(Xen_is_integer_or_unbound(arg5), arg5, 5, "XtCreatePopupShell", "int"); { Arg *args; int arglen; args = Xen_to_C_Args(arg4); arglen = Xen_to_C_INT_DEF(arg5, arg4); w = XtCreatePopupShell((char *)Xen_string_to_C_string(arg1), Xen_to_C_WidgetClass(arg2), Xen_to_C_Widget(arg3), args, arglen); if (args) { fixup_args(w, args, arglen); free_args(args, arglen); } } return(C_to_Xen_Widget(w)); } static Xen gxm_XtHasCallbacks(Xen arg1, Xen arg2) { #define H_XtHasCallbacks "XtCallbackStatus XtHasCallbacks(w, callback_name) first checks to see if the widget has a callback \ list identified by callback_name; returns XtCallbackNoList or XtCallbackHasNone if none, else XtCallbackHasSome" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtHasCallbacks", "Widget"); Xen_check_type(Xen_is_string(arg2), arg2, 2, "XtHasCallbacks", "char*"); return(C_int_to_Xen_integer(XtHasCallbacks(Xen_to_C_Widget(arg1), (char *)Xen_string_to_C_string(arg2)))); } static Xen gxm_XtCallCallbacks(Xen arg1, Xen arg2, Xen arg3) { #define H_XtCallCallbacks "void XtCallCallbacks(w, callback_name, call_data) calls each procedure that is registered in the \ specified widget's callback list. The call_data arg is assumed to be a callback struct reference" XtPointer val = NULL; Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtCallCallbacks", "Widget"); Xen_check_type(Xen_is_string(arg2), arg2, 2, "XtCallCallbacks", "char*"); if (Xen_is_list(arg3)) val = (XtPointer)Xen_unwrap_C_pointer(Xen_cadr(arg3)); XtCallCallbacks(Xen_to_C_Widget(arg1), (char *)Xen_string_to_C_string(arg2), val); return(Xen_false); } static Xen gxm_XtRemoveAllCallbacks(Xen arg1, Xen arg2) { #define H_XtRemoveAllCallbacks "void XtRemoveAllCallbacks(w, callback_name) removes all the callback procedures from the specified widget's callback list." Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtRemoveAllCallbacks", "Widget"); Xen_check_type(Xen_is_string(arg2), arg2, 2, "XtRemoveAllCallbacks", "char*"); XtRemoveAllCallbacks(Xen_to_C_Widget(arg1), (char *)Xen_string_to_C_string(arg2)); return(Xen_false); } static Xen gxm_XtRemoveCallback(Xen arg1, Xen arg2, Xen arg4) { #define H_XtRemoveCallback "void XtRemoveCallback(w, callback_name, client_data) removes a callback" /* DIFF: XtRemoveCallback omits proc arg and is passed whatever XtAddCallback returned */ Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtRemoveCallback", "Widget"); Xen_check_type(Xen_is_string(arg2), arg2, 2, "XtRemoveCallback", "char*"); xm_unprotect_at(Xen_integer_to_C_int(Xen_list_ref(arg4, CALLBACK_GC_LOC))); XtRemoveCallback(Xen_to_C_Widget(arg1), (char *)Xen_string_to_C_string(arg2), gxm_XtCallbackProc, (XtPointer)arg4); return(Xen_false); } static Xen gxm_XtRemoveCallbacks(Xen arg1, Xen arg2, Xen arg3) { #define H_XtRemoveCallbacks "void XtRemoveCallbacks(w, callback_name, callbacks) removes the specified callback procedures from the \ specified widget's callback list. (The 3rd arg is a list of descriptors returned by XtAddCallback)." /* DIFF: XtRemoveCallbacks takes list of descriptors as arg3 */ Xen lst; int i, len; Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtRemoveCallbacks", "Widget"); Xen_check_type(Xen_is_string(arg2), arg2, 2, "XtRemoveCallbacks", "char*"); Xen_check_type(Xen_is_list(arg3), arg3, 3, "XtRemoveCallbacks", "list of XtCallbacks"); lst = Xen_copy_arg(arg3); len = Xen_list_length(lst); for (i = 0; i < len; i++, lst = Xen_cdr(lst)) gxm_XtRemoveCallback(arg1, arg2, Xen_car(lst)); return(Xen_false); } /* need these for all callback proc types, and locations to store the list of them */ enum { GXM_Any, GXM_Arrow, GXM_Combo, GXM_Command, GXM_Container_Outline, GXM_Container_Select, GXM_Convert, GXM_Destination, GXM_Display, GXM_Drag_Drop, GXM_Drag_Motion, GXM_Drag_Proc, GXM_Drag_Start, GXM_Drawing, GXM_Drawn, GXM_Drop_Finish, GXM_Drop_Proc, GXM_DropSite_Enter, GXM_DropSite_Leave, GXM_Drop_Start, GXM_File, GXM_List, GXM_Notebook, GXM_Operation, GXM_Popup, GXM_PushButton, GXM_RowColumn, GXM_Scale, GXM_ScrollBar, GXM_Selection, GXM_SpinBox, GXM_ToggleButton, GXM_TopLevel_Enter, GXM_TopLevel_Leave, GXM_Traverse, GXM_Verify }; static Xen wrap_callback_struct(int type, XtPointer info) { switch (type) { case GXM_Any: return(C_to_Xen_XmAnyCallbackStruct((XmAnyCallbackStruct *)info)); case GXM_Arrow: return(C_to_Xen_XmArrowButtonCallbackStruct((XmArrowButtonCallbackStruct *)info)); case GXM_Command: return(C_to_Xen_XmCommandCallbackStruct((XmCommandCallbackStruct *)info)); case GXM_Drag_Drop: return(C_to_Xen_XmDragDropFinishCallbackStruct((XmDragDropFinishCallbackStruct *)info)); case GXM_Drag_Motion: return(C_to_Xen_XmDragMotionCallbackStruct((XmDragMotionCallbackStruct *)info)); case GXM_Drag_Proc: return(C_to_Xen_XmDragProcCallbackStruct((XmDragProcCallbackStruct *)info)); case GXM_Drawing: return(C_to_Xen_XmDrawingAreaCallbackStruct((XmDrawingAreaCallbackStruct *)info)); case GXM_Drawn: return(C_to_Xen_XmDrawnButtonCallbackStruct((XmDrawnButtonCallbackStruct *)info)); case GXM_Drop_Finish: return(C_to_Xen_XmDropFinishCallbackStruct((XmDropFinishCallbackStruct *)info)); case GXM_Drop_Proc: return(C_to_Xen_XmDropProcCallbackStruct((XmDropProcCallbackStruct *)info)); case GXM_DropSite_Enter: return(C_to_Xen_XmDropSiteEnterCallbackStruct((XmDropSiteEnterCallbackStruct *)info)); case GXM_DropSite_Leave: return(C_to_Xen_XmDropSiteLeaveCallbackStruct((XmDropSiteLeaveCallbackStruct *)info)); case GXM_Drop_Start: return(C_to_Xen_XmDropStartCallbackStruct((XmDropStartCallbackStruct *)info)); case GXM_File: return(C_to_Xen_XmFileSelectionBoxCallbackStruct((XmFileSelectionBoxCallbackStruct *)info)); case GXM_List: return(C_to_Xen_XmListCallbackStruct((XmListCallbackStruct *)info)); case GXM_PushButton: return(C_to_Xen_XmPushButtonCallbackStruct((XmPushButtonCallbackStruct *)info)); case GXM_RowColumn: return(C_to_Xen_XmRowColumnCallbackStruct((XmRowColumnCallbackStruct *)info)); case GXM_Scale: return(C_to_Xen_XmScaleCallbackStruct((XmScaleCallbackStruct *)info)); case GXM_ScrollBar: return(C_to_Xen_XmScrollBarCallbackStruct((XmScrollBarCallbackStruct *)info)); case GXM_Selection: return(C_to_Xen_XmSelectionBoxCallbackStruct((XmSelectionBoxCallbackStruct *)info)); case GXM_ToggleButton: return(C_to_Xen_XmToggleButtonCallbackStruct((XmToggleButtonCallbackStruct *)info)); case GXM_Verify: return(C_to_Xen_XmTextVerifyCallbackStruct((XmTextVerifyCallbackStruct *)info)); case GXM_Popup: return(C_to_Xen_XmPopupHandlerCallbackStruct((XmPopupHandlerCallbackStruct *)info)); case GXM_Drag_Start: return(C_to_Xen_XmDragStartCallbackStruct((XmDragStartCallbackStruct *)info)); case GXM_Convert: return(C_to_Xen_XmConvertCallbackStruct((XmConvertCallbackStruct *)info)); case GXM_Container_Outline: return(C_to_Xen_XmContainerOutlineCallbackStruct((XmContainerOutlineCallbackStruct *)info)); case GXM_Container_Select: return(C_to_Xen_XmContainerSelectCallbackStruct((XmContainerSelectCallbackStruct *)info)); case GXM_Destination: return(C_to_Xen_XmDestinationCallbackStruct((XmDestinationCallbackStruct *)info)); case GXM_Display: return(C_to_Xen_XmDisplayCallbackStruct((XmDisplayCallbackStruct *)info)); case GXM_Combo: return(C_to_Xen_XmComboBoxCallbackStruct((XmComboBoxCallbackStruct *)info)); case GXM_Notebook: return(C_to_Xen_XmNotebookCallbackStruct((XmNotebookCallbackStruct *)info)); case GXM_Operation: return(C_to_Xen_XmOperationChangedCallbackStruct((XmOperationChangedCallbackStruct *)info)); case GXM_SpinBox: return(C_to_Xen_XmSpinBoxCallbackStruct((XmSpinBoxCallbackStruct *)info)); case GXM_TopLevel_Enter: return(C_to_Xen_XmTopLevelEnterCallbackStruct((XmTopLevelEnterCallbackStruct *)info)); case GXM_TopLevel_Leave: return(C_to_Xen_XmTopLevelLeaveCallbackStruct((XmTopLevelLeaveCallbackStruct *)info)); case GXM_Traverse: return(C_to_Xen_XmTraverseObscuredCallbackStruct((XmTraverseObscuredCallbackStruct *)info)); } return(Xen_false); } static int callback_struct_type(Widget w, const char *name) { if (strcmp(name, XmNdestinationCallback) == 0) return(GXM_Destination); if (strcmp(name, XmNpopupHandlerCallback) == 0) return(GXM_Popup); if (strcmp(name, XmNconvertCallback) == 0) return(GXM_Convert); if (strcmp(name, XmNdragStartCallback) == 0) return(GXM_Drag_Start); if (strcmp(name, XmNdropProc) == 0) return(GXM_Drop_Proc); if (strcmp(name, XmNdragProc) == 0) return(GXM_Drag_Proc); if (XmIsArrowButton(w)) return(GXM_Arrow); if (XmIsPushButton(w)) return(GXM_PushButton); if (XmIsScale(w)) return(GXM_Scale); if (XmIsRowColumn(w)) return(GXM_RowColumn); if (XmIsScrollBar(w)) return(GXM_ScrollBar); if (XmIsToggleButton(w)) return(GXM_ToggleButton); if (XmIsList(w)) return(GXM_List); if (XmIsFileSelectionBox(w)) return(GXM_File); if (XmIsDrawingArea(w)) return(GXM_Drawing); if (XmIsScrolledWindow(w)) return(GXM_Traverse); if (XmIsNotebook(w)) return(GXM_Notebook); if (XmIsComboBox(w)) return(GXM_Combo); if ((XmIsText(w)) || (XmIsTextField(w))) { if ((strcmp(name, XmNlosingFocusCallback) == 0) || (strcmp(name, XmNmodifyVerifyCallback) == 0) || (strcmp(name, XmNmotionVerifyCallback) == 0)) return(GXM_Verify); return(GXM_Any); } if (XmIsContainer(w)) { if (strcmp(name, XmNoutlineChangedCallback) == 0) return(GXM_Container_Outline); if ((strcmp(name, XmNselectionCallback) == 0) || (strcmp(name, XmNdefaultActionCallback) == 0)) return(GXM_Container_Select); return(GXM_Destination); } /* how to recognize a SpinBox? */ if (XmIsCommand(w)) return(GXM_Command); if (XmIsDisplay(w)) return(GXM_Display); if (XmIsSelectionBox(w)) return(GXM_Selection); if (XmIsDragContext(w)) { if (strcmp(name, XmNdragDropFinishCallback) == 0) return(GXM_Drag_Drop); if (strcmp(name, XmNdropFinishCallback) == 0) return(GXM_Drop_Finish); if (strcmp(name, XmNdragMotionCallback) == 0) return(GXM_Drag_Motion); if (strcmp(name, XmNdropSiteEnterCallback) == 0) return(GXM_DropSite_Enter); if (strcmp(name, XmNdropSiteLeaveCallback) == 0) return(GXM_DropSite_Leave); if (strcmp(name, XmNdropStartCallback) == 0) return(GXM_Drop_Start); if (strcmp(name, XmNoperationChangedCallback) == 0) return(GXM_Operation); if (strcmp(name, XmNtopLevelEnterCallback) == 0) return(GXM_TopLevel_Enter); if (strcmp(name, XmNtopLevelLeaveCallback) == 0) return(GXM_TopLevel_Leave); } if (XmIsDrawnButton(w)) return(GXM_Drawn); return(GXM_Any); } static Xen gxm_XtAddCallback(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XtAddCallback "void XtAddCallback(w, callback_name, callback, client_data) adds the specified callback procedure to \ the specified widget's callback list. In xm, the client-data is optional, defaulting to " PROC_FALSE ". The callback procedure takes \ 3 args: widget client-data callback-info. Returns a description of the callback suitable for use with XtRemoveCallback." /* DIFF: XtAddCallback returns the C-side "client-data" (for subsequent XtRemoveCallback) */ char *name; Widget w; int gc_loc; Xen call_descr = Xen_empty_list; Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtAddCallback", "Widget"); Xen_check_type(Xen_is_string(arg2), arg2, 2, "XtAddCallback", "char*"); Xen_check_type(Xen_is_procedure(arg3) && (Xen_is_aritable(arg3, 3)), arg3, 3, "XtAddCallback", "(XtCallbackProc widget data callb)"); w = Xen_to_C_Widget(arg1); name = (char *)Xen_string_to_C_string(arg2); call_descr = C_to_Xen_XM_XtCallback(arg3, (Xen_is_bound(arg4)) ? arg4 : Xen_false); gc_loc = xm_protect(call_descr); Xen_list_set(call_descr, CALLBACK_GC_LOC, C_int_to_Xen_integer(gc_loc)); Xen_list_set(call_descr, CALLBACK_STRUCT_TYPE, C_int_to_Xen_integer(callback_struct_type(w, name))); XtAddCallback(w, name, gxm_XtCallbackProc, (XtPointer)call_descr); return(call_descr); } static Xen gxm_XtAddCallbacks(Xen arg1, Xen arg2, Xen arg3) { #define H_XtAddCallbacks "void XtAddCallbacks(w, callback_name, callbacks) add the specified list of callbacks to the specified widget's callback list. \ It returns a list of callback descriptors for use with XtRemoveCallback(s)." /* DIFF: XtAddCallbacks takes list of (func data) pairs as arg3 */ Xen res = Xen_empty_list, lst; int i, len; Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtAddCallbacks", "Widget"); Xen_check_type(Xen_is_string(arg2), arg2, 2, "XtAddCallbacks", "char*"); Xen_check_type(Xen_is_list(arg3), arg3, 3, "XtAddCallbacks", "list of XtCallbacks"); len = Xen_list_length(arg3); lst = Xen_copy_arg(arg3); for (i = len - 1; i >= 0; i--, lst = Xen_cdr(lst)) res = Xen_cons(gxm_XtAddCallback(arg1, arg2, Xen_car(Xen_car(lst)), Xen_cadr(Xen_car(lst))), res); return(res); } static Xen gxm_XtParent(Xen arg1) { #define H_XtParent "Widget XtParent(w): returns the widget's parent widget ID." Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtParent", "Widget"); return(C_to_Xen_Widget(XtParent(Xen_to_C_Widget(arg1)))); } static Xen gxm_XtClass(Xen arg1) { #define H_XtClass "WidgetClass XtClass(w)" #define H_XtSuperclass "WidgetClass XtSuperclass(w): returns a pointer to the widget's superclass class structure." Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtClass", "Widget"); return(C_to_Xen_WidgetClass(XtClass(Xen_to_C_Widget(arg1)))); } static Xen gxm_XtSuperclass(Xen arg1) { Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtSuperclass", "Widget"); return(C_to_Xen_WidgetClass(XtSuperclass(Xen_to_C_Widget(arg1)))); } static Xen gxm_XtName(Xen arg1) { #define H_XtName "Widget XtName(w): returns the widget's name." Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtName", "Widget"); return(C_string_to_Xen_string(XtName(Xen_to_C_Widget(arg1)))); } static Xen gxm_XtWindowOfObject(Xen arg1) { #define H_XtWindowOfObject "Window XtWindowOfObject(object): returns the window of the specified object." Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtWindowOfObject", "Widget"); return(C_to_Xen_Window(XtWindowOfObject(Xen_to_C_Widget(arg1)))); } static Xen gxm_XtWindow(Xen arg1) { #define H_XtWindow "Window XtWindow(w): returns the window of the specified widget." Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtWindow", "Widget"); return(C_to_Xen_Window(XtWindow(Xen_to_C_Widget(arg1)))); } static Xen gxm_XtScreenOfObject(Xen arg1) { #define H_XtScreenOfObject "Screen *XtScreenOfObject(object): returns the screen pointer for the specified object." Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtScreenOfObject", "Widget"); return(C_to_Xen_Screen(XtScreenOfObject(Xen_to_C_Widget(arg1)))); } static Xen gxm_XtScreen(Xen arg1) { #define H_XtScreen "Screen* XtScreen(w): returns the screen pointer for the specified widget." Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtScreen", "Widget"); return(C_to_Xen_Screen(XtScreen(Xen_to_C_Widget(arg1)))); } static Xen gxm_XtDisplayOfObject(Xen arg1) { #define H_XtDisplayOfObject "Display *XtDisplayOfObject(object): returns the display pointer for the specified object." Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtDisplayOfObject", "Widget"); return(C_to_Xen_Display(XtDisplayOfObject(Xen_to_C_Widget(arg1)))); } static Xen gxm_XtDisplay(Xen arg1) { #define H_XtDisplay "Display* XtDisplay(w)" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtDisplay", "Widget"); return(C_to_Xen_Display(XtDisplay(Xen_to_C_Widget(arg1)))); } static Xen gxm_XtVaCreateArgsList(Xen arg1, Xen ignore2) { #define H_XtVaCreateArgsList "XtVarArgsList XtVaCreateArgsList(unused, ...) allocates memory and copies its arguments into a single \ list pointer, which may be used with XtVaNestedList." /* DIFF: XtVaCreateArgsList just returns its first arg */ return(arg1); } static Xen gxm_XtMergeArgLists(Xen arg1, Xen ignore2, Xen arg3, Xen ignore4) { #define H_XtMergeArgLists "ArgList XtMergeArgLists(args1, num_args1, args2, num_args2) allocates enough storage to hold the combined \ ArgList structures and copies them into it." /* just merges, not duplicate check, kinda dumb to drop into C for that */ Xen_check_type(Xen_is_list(arg1), arg1, 1, "XtMergeArgLists", "list"); Xen_check_type(Xen_is_list(arg3), arg3, 3, "XtMergeArgLists", "list"); return(Xen_append(arg1, arg3)); } static Xen gxm_XtWindowToWidget(Xen arg1, Xen arg2) { #define H_XtWindowToWidget "Widget XtWindowToWidget(display, window) translates the specified window and display pointer into the appropriate widget instance." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XtWindowToWidget", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XtWindowToWidget", "Window"); return(C_to_Xen_Widget(XtWindowToWidget(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2)))); } static Xen gxm_XtNameToWidget(Xen arg1, Xen arg2) { #define H_XtNameToWidget "Widget XtNameToWidget(reference, names) looks for a widget whose name is the first component in the specified names" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtNameToWidget", "Widget"); Xen_check_type(Xen_is_string(arg2), arg2, 2, "XtNameToWidget", "char*"); return(C_to_Xen_Widget(XtNameToWidget(Xen_to_C_Widget(arg1), (char *)Xen_string_to_C_string(arg2)))); } static Xen gxm_XtSetSensitive(Xen arg1, Xen arg2) { #define H_XtSetSensitive "void XtSetSensitive(w, sensitive)" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtSetSensitive", "Widget"); Xen_check_type(Xen_is_boolean(arg2), arg2, 2, "XtSetSensitive", "boolean"); XtSetSensitive(Xen_to_C_Widget(arg1), Xen_boolean_to_C_bool(arg2)); return(Xen_false); } static Xen gxm_XtDestroyWidget(Xen arg1) { #define H_XtDestroyWidget "void XtDestroyWidget(w) provides the only method of destroying a widget, including widgets that need to destroy themselves." Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtDestroyWidget", "Widget"); XtDestroyWidget(Xen_to_C_Widget(arg1)); return(Xen_false); } static Xen gxm_XtUnrealizeWidget(Xen arg1) { #define H_XtUnrealizeWidget "void XtUnrealizeWidget(w) destroys the windows of an existing widget and all of its children (recursively down the widget tree)." Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtUnrealizeWidget", "Widget"); XtUnrealizeWidget(Xen_to_C_Widget(arg1)); return(Xen_false); } static Xen gxm_XtRealizeWidget(Xen arg1) { #define H_XtRealizeWidget "void XtRealizeWidget(w) maps the widget window." Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtRealizeWidget", "Widget"); XtRealizeWidget(Xen_to_C_Widget(arg1)); return(Xen_false); } static Xen gxm_XtAppPending(Xen arg1) { #define H_XtAppPending "XtInputMask XtAppPending(app_context): returns a nonzero value if there are events pending from the X server, timer \ pending, or other input sources pending. " Xen_check_type(Xen_is_XtAppContext(arg1), arg1, 1, "XtAppPending", "XtAppContext"); return(C_ulong_to_Xen_ulong(XtAppPending(Xen_to_C_XtAppContext(arg1)))); } static Xen gxm_XtAppNextEvent(Xen arg1) { #define H_XtAppNextEvent "void XtAppNextEvent(app_context) flushes the X output buffers of each Display in the application \ context and waits for an event while looking at the other input sources, timeout timeout values, and signal handlers and calling any callback \ procedures triggered by them -> event." /* DIFF: XtAppNextEvent app [ev] -> ev */ XEvent *e; Xen_check_type(Xen_is_XtAppContext(arg1), arg1, 1, "XtAppNextEvent", "XtAppContext"); e = (XEvent *)calloc(1, sizeof(XEvent)); XtAppNextEvent(Xen_to_C_XtAppContext(arg1), e); return(C_to_Xen_XEvent_OBJ(e)); } /* -------- Input callback -------- */ /* (77) explicitly removed via XtRemoveInput */ #define C_to_Xen_XM_Input(Code, Context) \ Xen_list_5(C_string_to_Xen_symbol("Input"), Code, Context, Xen_integer_zero, Xen_integer_zero) #define XM_is_Input(Arg) is_wrapped("Input", Arg) static void gxm_XtInputCallbackProc(XtPointer cdata, int *fileno, XtInputId *id) { Xen descr = (Xen)cdata; /* (list 'Input function context gc-loc id) */ Xen_call_with_3_args(Xen_cadr(descr), Xen_caddr(descr), C_ulong_to_Xen_ulong(*fileno), C_to_Xen_XtInputId(*id), __func__); } static bool unprotect_inputproc(Xen val, int loc, unsigned long id) { if ((XM_is_Input(val)) && ((XtInputId)Xen_ulong_to_C_ulong(Xen_list_ref(val, 4)) == id)) { xm_unprotect_at(loc); return(true); } return(false); } static Xen gxm_XtRemoveInput(Xen arg1) { #define H_XtRemoveInput "void XtRemoveInput(id) causes the read routine to stop watching for input from the input source." XtInputId id; Xen_check_type(Xen_is_XtInputId(arg1), arg1, 1, "XtRemoveInput", "XtInputId"); id = Xen_to_C_XtInputId(arg1); XtRemoveInput(id); map_over_protected_elements(unprotect_inputproc, id); return(Xen_false); } static Xen gxm_XtAppAddInput(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5) { #define H_XtAppAddInput "XtInputId XtAppAddInput(app_context, source, condition, proc, client_data) registers with the read routine a \ new source of events, which is usually file input but can also be file output." XtInputId id; int gc_loc; Xen descr; Xen_check_type(Xen_is_XtAppContext(arg1), arg1, 1, "XtAppAddInput", "XtAppContext"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XtAppAddInput", "int"); Xen_check_type(Xen_is_integer(arg3), arg3, 3, "XtAppAddInput", "int"); Xen_check_type(Xen_is_procedure(arg4) && (Xen_is_aritable(arg4, 3)), arg4, 4, "XtAppAddInput", "(XtInputCallbackProc data fileno id)"); descr = C_to_Xen_XM_Input(arg4, (Xen_is_bound(arg5)) ? arg5 : Xen_false); gc_loc = xm_protect(descr); id = XtAppAddInput(Xen_to_C_XtAppContext(arg1), Xen_integer_to_C_int(arg2), #if (SIZEOF_VOID_P == 4) (XtPointer)((int)Xen_ulong_to_C_ulong(arg3)), #else (XtPointer)Xen_llong_to_C_llong(arg3), #endif gxm_XtInputCallbackProc, (XtPointer)descr); Xen_list_set(descr, 3, C_int_to_Xen_integer(gc_loc)); Xen_list_set(descr, 4, C_ulong_to_Xen_ulong(id)); return(C_to_Xen_XtInputId(id)); } /* -------- Timer Callback -------- */ /* (79) protect the function, then unprotect after invocation */ #define C_to_Xen_XM_TimeOut(Code, Context) \ Xen_list_5(C_string_to_Xen_symbol("TimeOut"), Code, Context, Xen_integer_zero, Xen_integer_zero) #define XM_is_TimeOut(Arg) is_wrapped("TimeOut", Arg) static void gxm_XtTimerCallbackProc(XtPointer cdata, XtIntervalId* i) { Xen descr = (Xen)cdata; /* (list 'TimeOut function context gc-loc id) */ int gc_loc; gc_loc = Xen_integer_to_C_int(Xen_list_ref(descr, 3)); Xen_call_with_2_args(Xen_cadr(descr), Xen_caddr(descr), C_to_Xen_XtIntervalId(*i), __func__); xm_unprotect_at(gc_loc); } static bool unprotect_timeoutproc(Xen val, int loc, unsigned long id) { if ((XM_is_TimeOut(val)) && ((XtIntervalId)Xen_ulong_to_C_ulong(Xen_list_ref(val, 4)) == id)) { xm_unprotect_at(loc); return(true); } return(false); } static Xen gxm_XtRemoveTimeOut(Xen arg1) { #define H_XtRemoveTimeOut "void XtRemoveTimeOut(timer) removes the timeout." XtIntervalId id; Xen_check_type(Xen_is_XtIntervalId(arg1), arg1, 1, "XtRemoveTimeOut", "XtIntervalId"); id = Xen_to_C_XtIntervalId(arg1); XtRemoveTimeOut(id); map_over_protected_elements(unprotect_timeoutproc, id); return(Xen_false); } static Xen gxm_XtAppAddTimeOut(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XtAppAddTimeOut "XtIntervalId XtAppAddTimeOut(app_context, interval, proc, client_data) creates a timeout and returns an identifier for it." XtIntervalId id; int gc_loc; Xen descr; Xen_check_type(Xen_is_XtAppContext(arg1), arg1, 1, "XtAppAddTimeOut", "XtAppContext"); Xen_check_type(Xen_is_ulong(arg2), arg2, 2, "XtAppAddTimeOut", "ulong"); Xen_check_type(Xen_is_procedure(arg3) && (Xen_is_aritable(arg3, 2)), arg3, 3, "XtAppAddTimeOut", "(XtTimerCallbackProc data id)"); descr = C_to_Xen_XM_TimeOut(arg3, (Xen_is_bound(arg4)) ? arg4 : Xen_false); gc_loc = xm_protect(descr); id = XtAppAddTimeOut(Xen_to_C_XtAppContext(arg1), Xen_ulong_to_C_ulong(arg2), gxm_XtTimerCallbackProc, (XtPointer)descr); Xen_list_set(descr, 3, C_int_to_Xen_integer(gc_loc)); Xen_list_set(descr, 4, C_ulong_to_Xen_ulong(id)); return(C_to_Xen_XtIntervalId(id)); } static Xen gxm_XtLastTimestampProcessed(Xen arg1) { #define H_XtLastTimestampProcessed "Time XtLastTimestampProcessed(display): returns the timestamp of the last event" Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XtLastTimestampProcessed", "Display*"); return(C_to_Xen_Time(XtLastTimestampProcessed(Xen_to_C_Display(arg1)))); } static Xen gxm_XtLastEventProcessed(Xen arg1) { #define H_XtLastEventProcessed "XEvent* XtLastEventProcessed(display): returns the last event passed to XtDispatchEvent for the \ specified display and NULL if there has been no event. " Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XtLastEventProcessed", "Display*"); return(C_to_Xen_XEvent(XtLastEventProcessed(Xen_to_C_Display(arg1)))); } static Xen gxm_XtGetKeyboardFocusWidget(Xen arg1) { #define H_XtGetKeyboardFocusWidget "Widget XtGetKeyboardFocusWidget(widget): returns the widget that would be the end result of keyboard \ event forwarding for a keyboard event for the specified widget." Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtGetKeyboardFocusWidget", "Widget"); return(C_to_Xen_Widget(XtGetKeyboardFocusWidget(Xen_to_C_Widget(arg1)))); } static Xen gxm_XtSetKeyboardFocus(Xen arg1, Xen arg2) { #define H_XtSetKeyboardFocus "XtSetKeyboardFocus(subtree descendant) causes XtDispatchEvent to remap and send the event to the specified \ descendant widget." Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtSetKeyboardFocus", "Widget"); Xen_check_type(Xen_is_Widget(arg2), arg2, 2, "XtSetKeyboardFocus", "Widget"); XtSetKeyboardFocus(Xen_to_C_Widget(arg1), Xen_to_C_Widget(arg2)); return(Xen_false); } static Xen gxm_XtAddExposureToRegion(Xen arg1, Xen arg2) { #define H_XtAddExposureToRegion "void XtAddExposureToRegion(event, region) computes the union of the rectangle defined by the exposure event \ and the specified region. Then, it stores the results back in region." Xen_check_type(Xen_is_XEvent(arg1), arg1, 1, "XtAddExposureToRegion", "XEvent*"); Xen_check_type(Xen_is_Region(arg2), arg2, 2, "XtAddExposureToRegion", "Region"); XtAddExposureToRegion(Xen_to_C_XEvent(arg1), Xen_to_C_Region(arg2)); return(Xen_false); } static Xen gxm_XtAppMainLoop(Xen arg1) { #define H_XtAppMainLoop "void XtAppMainLoop(app_context) first reads the next incoming X event by calling XtAppNextEvent and then it dispatches \ the event to the appropriate registered procedure by calling XtDispatchEvent." Xen_check_type(Xen_is_XtAppContext(arg1), arg1, 1, "XtAppMainLoop", "XtAppContext"); XtAppMainLoop(Xen_to_C_XtAppContext(arg1)); return(Xen_false); } static Xen gxm_XtAppProcessEvent(Xen arg1, Xen arg2) { #define H_XtAppProcessEvent "void XtAppProcessEvent(app_context, mask) processes one timer, alternate input, signal source, or X event. \ If there is nothing of the appropriate type to process, XtAppProcessEvent blocks until there is." Xen_check_type(Xen_is_XtAppContext(arg1), arg1, 1, "XtAppProcessEvent", "XtAppContext"); Xen_check_type(Xen_is_ulong(arg2), arg2, 2, "XtAppProcessEvent", "XtInputMask"); XtAppProcessEvent(Xen_to_C_XtAppContext(arg1), Xen_ulong_to_C_ulong(arg2)); return(Xen_false); } static Xen gxm_XtRemoveGrab(Xen arg1) { #define H_XtRemoveGrab "void XtRemoveGrab(w) removes widgets from the modal cascade starting at the most recent widget up to and \ including the specified widget. " Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtRemoveGrab", "Widget"); XtRemoveGrab(Xen_to_C_Widget(arg1)); return(Xen_false); } static Xen gxm_XtAddGrab(Xen arg1, Xen arg2, Xen arg3) { #define H_XtAddGrab "void XtAddGrab(w, exclusive, spring_loaded) appends the widget (and associated parameters) to the modal cascade and \ checks that exclusive is " PROC_TRUE " if spring_loaded is " PROC_TRUE "." Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtAddGrab", "Widget"); Xen_check_type(Xen_is_boolean(arg2), arg2, 2, "XtAddGrab", "boolean"); Xen_check_type(Xen_is_boolean(arg3), arg3, 3, "XtAddGrab", "boolean"); XtAddGrab(Xen_to_C_Widget(arg1), Xen_boolean_to_C_bool(arg2), Xen_boolean_to_C_bool(arg3)); return(Xen_false); } static Xen gxm_XtBuildEventMask(Xen arg1) { #define H_XtBuildEventMask "EventMask XtBuildEventMask(w): widget's event mask" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtBuildEventMask", "Widget"); return(C_ulong_to_Xen_ulong(XtBuildEventMask(Xen_to_C_Widget(arg1)))); } static Xen gxm_XtDispatchEventToWidget(Xen arg1, Xen arg2) { #define H_XtDispatchEventToWidget "Boolean XtDispatchEventToWidget(widget, event) scans the list of registered event handlers for the \ specified widget and calls each handler that has been registered for the specified event type, subject to the continue_to_dispatch value \ returned by each handler." Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtDispatchEventToWidget", "Widget"); Xen_check_type(Xen_is_XEvent(arg2), arg2, 2, "XtDispatchEventToWidget", "XEvent*"); return(C_bool_to_Xen_boolean(XtDispatchEventToWidget(Xen_to_C_Widget(arg1), Xen_to_C_XEvent(arg2)))); } enum {EVENT_HANDLER_TYPE, EVENT_HANDLER_FUNC, EVENT_HANDLER_DATA, EVENT_HANDLER_GC_LOC, EVENT_HANDLER_WIDGET, EVENT_HANDLER_MASK}; #define C_to_Xen_XM_XtEventHandler(Code, Context, Widget, Mask) \ Xen_list_6(C_string_to_Xen_symbol("XtEventHandler"), Code, Context, Xen_integer_zero, Widget, Mask) #define XM_is_XtEventHandler(Arg) is_wrapped("XtEventHandler", Arg) static void gxm_XtEventHandler(Widget w, XtPointer context, XEvent *event, Boolean *flag) { Xen result; Xen descr = (Xen)context; result = Xen_call_with_4_args(Xen_list_ref(descr, EVENT_HANDLER_FUNC), C_to_Xen_Widget(w), Xen_list_ref(descr, EVENT_HANDLER_DATA), C_to_Xen_XEvent(event), C_bool_to_Xen_boolean(*flag), __func__); if ((Xen_is_symbol(result)) && (strcmp("done", Xen_symbol_to_C_string(result)) == 0)) (*flag) = false; } static bool find_xteventproc_1(Xen val, int loc, unsigned long wd) { Xen lst = (Xen)wd; unsigned long w; Xen code; Xen data; w = Xen_ulong_to_C_ulong(Xen_car(lst)); code = Xen_cadr(lst); data = Xen_caddr(lst); return((XM_is_XtEventHandler(val)) && (Xen_is_Widget(Xen_list_ref(val, EVENT_HANDLER_WIDGET))) && (Xen_ulong_to_C_ulong(Xen_cadr(Xen_list_ref(val, EVENT_HANDLER_WIDGET))) == w) && (Xen_is_eq(code, Xen_list_ref(val, EVENT_HANDLER_FUNC))) && (Xen_is_eq(data, Xen_list_ref(val, EVENT_HANDLER_DATA)))); } static Xen find_xteventproc(Widget w, Xen code, Xen data) { /* here we again have to go by the widget */ Xen lst; int i, loc; lst = Xen_list_3(C_ulong_to_Xen_ulong((unsigned long)w),code, data); loc = xm_protect(lst); i = map_over_protected_elements(find_xteventproc_1, (unsigned long)lst); xm_unprotect_at(loc); if (i >= 0) return(xm_protected_element(i)); return(Xen_false); } static Xen gxm_XtInsertRawEventHandler(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6) { #define H_XtInsertRawEventHandler "void XtInsertRawEventHandler(w, event_mask, nonmaskable, proc, client_data, position) is similar to \ XtInsertEventHandler except that it does not modify the widget's event mask and never causes an XSelectInput for the specified events." Xen call_descr = Xen_empty_list; Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtInsertRawEventHandler", "Widget"); Xen_check_type(Xen_is_ulong(arg2), arg2, 2, "XtInsertRawEventHandler", "EventMask"); Xen_check_type(Xen_is_boolean(arg3), arg3, 3, "XtInsertRawEventHandler", "boolean"); Xen_check_type(Xen_is_procedure(arg4) && (Xen_is_aritable(arg4, 4)), arg4, 4, "XtInsertRawEventHandler", "XtEventHandler"); Xen_check_type(Xen_is_integer(arg6), arg6, 6, "XtInsertRawEventHandler", "XtListPosition"); call_descr = C_to_Xen_XM_XtEventHandler(arg4, (Xen_is_bound(arg5)) ? arg5 : Xen_false, arg1, arg2); Xen_list_set(call_descr, EVENT_HANDLER_GC_LOC, C_int_to_Xen_integer(xm_protect(call_descr))); XtInsertRawEventHandler(Xen_to_C_Widget(arg1), Xen_ulong_to_C_ulong(arg2), Xen_boolean_to_C_bool(arg3), gxm_XtEventHandler, (XtPointer)call_descr, (XtListPosition)Xen_integer_to_C_int(arg6)); return(Xen_false); } static Xen gxm_XtInsertEventHandler(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6) { #define H_XtInsertEventHandler "void XtInsertEventHandler(w, event_mask, nonmaskable, proc, client_data, position) is identical to \ XtAddEventHandler with the additional position argument. " Xen call_descr = Xen_empty_list; Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtInsertEventHandler", "Widget"); Xen_check_type(Xen_is_ulong(arg2), arg2, 2, "XtInsertEventHandler", "EventMask"); Xen_check_type(Xen_is_boolean(arg3), arg3, 3, "XtInsertEventHandler", "boolean"); Xen_check_type(Xen_is_procedure(arg4) && (Xen_is_aritable(arg4, 4)), arg4, 4, "XtInsertEventHandler", "XtEventHandler"); Xen_check_type(Xen_is_integer(arg6), arg6, 6, "XtInsertEventHandler", "XtListPosition"); call_descr = C_to_Xen_XM_XtEventHandler(arg4, (Xen_is_bound(arg5)) ? arg5 : Xen_false, arg1, arg2); Xen_list_set(call_descr, EVENT_HANDLER_GC_LOC, C_int_to_Xen_integer(xm_protect(call_descr))); XtInsertEventHandler(Xen_to_C_Widget(arg1), Xen_ulong_to_C_ulong(arg2), Xen_boolean_to_C_bool(arg3), gxm_XtEventHandler, (XtPointer)call_descr, (XtListPosition)Xen_integer_to_C_int(arg6)); return(Xen_false); } static Xen gxm_XtRemoveRawEventHandler(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5) { #define H_XtRemoveRawEventHandler "void XtRemoveRawEventHandler(w, event_mask, nonmaskable, proc, client_data) stops the specified \ procedure from receiving the specified events." Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtRemoveRawEventHandler", "Widget"); Xen_check_type(Xen_is_ulong(arg2), arg2, 2, "XtRemoveRawEventHandler", "EventMask"); Xen_check_type(Xen_is_boolean(arg3), arg3, 3, "XtRemoveRawEventHandler", "boolean"); Xen_check_type(Xen_is_procedure(arg4) && (Xen_is_aritable(arg4, 4)), arg4, 4, "XtRemoveRawEventHandler", "XtEventHandler"); XtRemoveRawEventHandler(Xen_to_C_Widget(arg1), Xen_ulong_to_C_ulong(arg2), Xen_boolean_to_C_bool(arg3), gxm_XtEventHandler, (XtPointer)find_xteventproc(Xen_to_C_Widget(arg1), arg4, arg5)); return(Xen_false); } static Xen gxm_XtAddRawEventHandler(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5) { #define H_XtAddRawEventHandler "void XtAddRawEventHandler(w, event_mask, nonmaskable, proc, client_data) is similar to XtAddEventHandler \ except that it does not affect the widget's mask and never causes an XSelectInput for its events." Xen call_descr = Xen_empty_list; Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtAddRawEventHandler", "Widget"); Xen_check_type(Xen_is_ulong(arg2), arg2, 2, "XtAddRawEventHandler", "EventMask"); Xen_check_type(Xen_is_boolean(arg3), arg3, 3, "XtAddRawEventHandler", "boolean"); Xen_check_type(Xen_is_procedure(arg4) && (Xen_is_aritable(arg4, 4)), arg4, 4, "XtAddRawEventHandler", "XtEventHandler"); call_descr = C_to_Xen_XM_XtEventHandler(arg4, (Xen_is_bound(arg5)) ? arg5 : Xen_false, arg1, arg2); Xen_list_set(call_descr, EVENT_HANDLER_GC_LOC, C_int_to_Xen_integer(xm_protect(call_descr))); XtAddRawEventHandler(Xen_to_C_Widget(arg1), Xen_ulong_to_C_ulong(arg2), Xen_boolean_to_C_bool(arg3), gxm_XtEventHandler, (XtPointer)call_descr); return(Xen_false); } static Xen gxm_XtRemoveEventHandler(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5) { #define H_XtRemoveEventHandler "XtRemoveEventHandler(w, event_mask, nonmaskable, proc, client_data)" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtRemoveEventHandler", "Widget"); Xen_check_type(Xen_is_ulong(arg2), arg2, 2, "XtRemoveEventHandler", "EventMask"); Xen_check_type(Xen_is_boolean(arg3), arg3, 3, "XtRemoveEventHandler", "boolean"); Xen_check_type(Xen_is_procedure(arg4) && (Xen_is_aritable(arg4, 4)), arg4, 4, "XtRemoveEventHandler", "XtEventHandler"); XtRemoveEventHandler(Xen_to_C_Widget(arg1), Xen_ulong_to_C_ulong(arg2), Xen_boolean_to_C_bool(arg3), gxm_XtEventHandler, (XtPointer)find_xteventproc(Xen_to_C_Widget(arg1), arg4, arg5)); return(Xen_false); } static Xen gxm_XtAddEventHandler(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5) { #define H_XtAddEventHandler "void XtAddEventHandler(w, event_mask, nonmaskable, proc, client_data) registers a procedure with the dispatch \ mechanism that is to be called when an event that matches the mask occurs on the specified widget. To set the 'continue_to_dispatch' \ flag to 'false', return the symbol 'done from the event handler." Xen call_descr = Xen_empty_list; Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtAddEventHandler", "Widget"); Xen_check_type(Xen_is_ulong(arg2), arg2, 2, "XtAddEventHandler", "EventMask"); Xen_check_type(Xen_is_boolean(arg3), arg3, 3, "XtAddEventHandler", "boolean"); Xen_check_type(Xen_is_procedure(arg4) && (Xen_is_aritable(arg4, 4)), arg4, 4, "XtAddEventHandler", "XtEventHandler"); call_descr = C_to_Xen_XM_XtEventHandler(arg4, (Xen_is_bound(arg5)) ? arg5 : Xen_false, arg1, arg2); Xen_list_set(call_descr, EVENT_HANDLER_GC_LOC, C_int_to_Xen_integer(xm_protect(call_descr))); XtAddEventHandler(Xen_to_C_Widget(arg1), Xen_ulong_to_C_ulong(arg2), Xen_boolean_to_C_bool(arg3), gxm_XtEventHandler, (XtPointer)call_descr); return(Xen_false); } static Xen gxm_XtConvertCase(Xen arg1, Xen arg2) { #define H_XtConvertCase "void XtConvertCase(display, keysym) calls the appropriate converter and returns the results." /* DIFF: XtConvertCase dpy keysym [k1 k2] -> (list k1 k2) */ KeySym k1, k2; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XtConvertCase", "Display*"); Xen_check_type(Xen_is_KeySym(arg2), arg2, 2, "XtConvertCase", "KeySym"); XtConvertCase(Xen_to_C_Display(arg1), Xen_to_C_KeySym(arg2), &k1, &k2); return(Xen_list_2(C_to_Xen_KeySym(k1), C_to_Xen_KeySym(k2))); } /* -------- case converter -------- */ /* (424) convert case XtRegisterCaseConverter global */ static Xen xm_XtCaseProc; static void gxm_XtCaseProc(Display* d, KeySym k1, KeySym* k2, KeySym* k3) { Xen val; int loc; val = Xen_call_with_2_args(xm_XtCaseProc, C_to_Xen_Display(d), C_to_Xen_KeySym(k1), __func__); loc = xm_protect(val); if (Xen_is_list(val)) { (*k2) = Xen_to_C_KeySym(Xen_car(val)); (*k3) = Xen_to_C_KeySym(Xen_cadr(val)); } xm_unprotect_at(loc); } static Xen gxm_XtRegisterCaseConverter(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { #define H_XtRegisterCaseConverter "void XtRegisterCaseConverter(display, proc, start, stop) registers the specified case converter." /* DIFF: XtRegisterCaseConverter user XtCaseProc should return the new KeySyms as a list (not as ref args) */ Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XtRegisterCaseConverter", "Display*"); Xen_check_type(Xen_is_procedure(arg2) && (Xen_is_aritable(arg2, 2)), arg2, 2, "XtRegisterCaseConverter", "(XtCaseProc dpy keysym)"); Xen_check_type(Xen_is_KeySym(arg3), arg3, 3, "XtRegisterCaseConverter", "KeySym"); Xen_check_type(Xen_is_KeySym(arg4), arg4, 4, "XtRegisterCaseConverter", "KeySym"); if (Xen_is_procedure(xm_XtCaseProc)) xm_unprotect(xm_XtCaseProc); xm_protect(arg2); xm_XtCaseProc = arg2; XtRegisterCaseConverter(Xen_to_C_Display(arg1), gxm_XtCaseProc, Xen_to_C_KeySym(arg3), Xen_to_C_KeySym(arg4)); return(Xen_false); } /* -------- keyproc -------- */ /* (454) XtSetKeyTranslator global */ static Xen xm_XtKeyProc; static void gxm_XtKeyProc(Display *dpy, KeyCode c, Modifiers m, Modifiers *mp, KeySym *sym) { Xen val; int loc; val = Xen_call_with_3_args(xm_XtKeyProc, C_to_Xen_Display(dpy), C_to_Xen_KeyCode(c), C_to_Xen_Modifiers(m), __func__); loc = xm_protect(val); if (Xen_is_list(val)) { /* KeySym is long, Modifier(s) is int, so these can actually work, I guess */ (*mp) = Xen_to_C_Modifiers(Xen_car(val)); (*sym) = Xen_to_C_KeySym(Xen_cadr(val)); } else XtTranslateKey(dpy, c, m, mp, sym); xm_unprotect_at(loc); } static Xen gxm_XtSetKeyTranslator(Xen arg1, Xen arg2) { #define H_XtSetKeyTranslator "void XtSetKeyTranslator(display, proc) sets the specified procedure as the current key translator. " /* DIFF: XtSetKeyTranslator user XtKeyProc should return the new Modifiers and KeySym as a list (not as ref arg), set arg2 #f to get default proc */ Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XtSetKeyTranslator", "Display*"); Xen_check_type(Xen_is_false(arg2) || (Xen_is_procedure(arg2) && (Xen_is_aritable(arg2, 3))), arg2, 2, "XtSetKeyTranslator", "(XtKeyProc dpy key mod)"); if (Xen_is_procedure(xm_XtKeyProc)) xm_unprotect(xm_XtKeyProc); xm_XtKeyProc = arg2; if (Xen_is_false(arg2)) XtSetKeyTranslator(Xen_to_C_Display(arg1), XtTranslateKey); else { xm_protect(arg2); XtSetKeyTranslator(Xen_to_C_Display(arg1), (XtKeyProc)gxm_XtKeyProc); } return(Xen_false); } static Xen gxm_XtTranslateKey(Xen arg1, Xen arg2, Xen arg3) { #define H_XtTranslateKey "XtTranslateKey(Display *, XtKeyCode, Modifiers): modifiers and keysym" /* DIFF: XtTranslateKey omit and rtn last 2 args */ Modifiers m; KeySym k; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XtTranslateKey", "Display*"); Xen_check_type(Xen_is_KeyCode(arg2), arg2, 2, "XtTranslateKey", "KeyCode"); Xen_check_type(Xen_is_Modifiers(arg3), arg3, 3, "XtTranslateKey", "Modifiers"); XtTranslateKey(Xen_to_C_Display(arg1), Xen_to_C_KeyCode(arg2), Xen_to_C_Modifiers(arg3), &m, &k); return(Xen_list_2(C_to_Xen_Modifiers(m), C_to_Xen_KeySym(k))); } static Xen gxm_XtTranslateKeycode(Xen arg1, Xen arg2, Xen arg3) { #define H_XtTranslateKeycode "void XtTranslateKeycode(display, keycode, modifiers) passes the specified \ arguments directly to the currently registered KeyCode to KeySym translator, returns (modifiers keysym)." /* DIFF: XtTranslateKeycode omit and rtn last 2 args */ Modifiers m; KeySym k; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XtTranslateKeycode", "Display*"); Xen_check_type(Xen_is_KeyCode(arg2), arg2, 2, "XtTranslateKeycode", "KeyCode"); Xen_check_type(Xen_is_Modifiers(arg3), arg3, 3, "XtTranslateKeycode", "Modifiers"); XtTranslateKeycode(Xen_to_C_Display(arg1), Xen_to_C_KeyCode(arg2), Xen_to_C_Modifiers(arg3), &m, &k); return(Xen_list_2(C_to_Xen_Modifiers(m), C_to_Xen_KeySym(k))); } static Xen gxm_XtGetActionKeysym(Xen arg1) { #define H_XtGetActionKeysym "KeySym XtGetActionKeysym(event): (keysym modifiers)" /* DIFF: XtGetActionKeysym omit and rtn last arg */ Modifiers m; KeySym k; Xen_check_type(Xen_is_XEvent(arg1), arg1, 1, "XtGetActionKeysym", "XEvent*"); k = XtGetActionKeysym(Xen_to_C_XEvent(arg1), &m); return(Xen_list_2(C_to_Xen_KeySym(k), C_to_Xen_Modifiers(m))); } static Xen gxm_XtGetResourceList(Xen widget_class) { #define H_XtGetResourceList "XtGetResourceList(widget-class): returns the widget class's resource list" Xen lst = Xen_empty_list; Cardinal len = 0; XtResourceList resources; Xen_check_type(Xen_is_WidgetClass(widget_class), widget_class, 1, "XtGetResourceList", "WidgetClass"); XtGetResourceList(Xen_to_C_WidgetClass(widget_class), &resources, &len); if (len > 0) { int i; for (i = len - 1; i >= 0; i--) lst = Xen_cons(Xen_list_7(C_string_to_Xen_string(resources[i].resource_name), C_string_to_Xen_string(resources[i].resource_class), C_string_to_Xen_string(resources[i].resource_type), C_int_to_Xen_integer((int)(resources[i].resource_size)), C_int_to_Xen_integer((int)(resources[i].resource_offset)), C_string_to_Xen_string(resources[i].default_type), Xen_wrap_C_pointer(resources[i].default_addr)), lst); XtFree((char *)resources); } return(lst); } static Xen gxm_XtGetMultiClickTime(Xen arg1) { #define H_XtGetMultiClickTime "int XtGetMultiClickTime(display): returns the time in milliseconds that the translation manager uses to \ determine if multiple events are to be interpreted as a repeated event " Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XtGetMultiClickTime", "Display*"); return(C_int_to_Xen_integer(XtGetMultiClickTime(Xen_to_C_Display(arg1)))); } static Xen gxm_XtSetMultiClickTime(Xen arg1, Xen arg2) { #define H_XtSetMultiClickTime "void XtSetMultiClickTime(display, time) sets the time interval used by the translation manager to determine \ when multiple events are interpreted as a repeated event." Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XtSetMultiClickTime", "Display*"); Xen_check_type(Xen_is_integer(arg2), arg2, 2, "XtSetMultiClickTime", "int"); XtSetMultiClickTime(Xen_to_C_Display(arg1), Xen_integer_to_C_int(arg2)); return(Xen_false); } static Xen register_proc; static void gxm_XtRegisterGrabActionProc(Widget w, XEvent* e, String* s, Cardinal* c) { Xen_call_with_3_args(register_proc, C_to_Xen_Widget(w), C_to_Xen_XEvent(e), C_to_Xen_Strings(s, *c), __func__); } static Xen gxm_XtRegisterGrabAction(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5) { #define H_XtRegisterGrabAction "void XtRegisterGrabAction(action_proc, owner_events, event_mask, pointer_mode, keyboard_mode) adds the \ specified action_proc to a list known to the translation manager." Xen_check_type(Xen_is_procedure(arg1) && (Xen_is_aritable(arg1, 3)), arg1, 1, "XtRegisterGrabAction", "XtActionProc"); Xen_check_type(Xen_is_boolean(arg2), arg2, 2, "XtRegisterGrabAction", "boolean"); Xen_check_type(Xen_is_ulong(arg3), arg3, 3, "XtRegisterGrabAction", "unsigned int"); Xen_check_type(Xen_is_integer(arg4), arg4, 4, "XtRegisterGrabAction", "int"); Xen_check_type(Xen_is_integer(arg5), arg5, 5, "XtRegisterGrabAction", "int"); xm_protect(arg1); register_proc = arg1; XtRegisterGrabAction(gxm_XtRegisterGrabActionProc, Xen_boolean_to_C_bool(arg2), Xen_ulong_to_C_ulong(arg3), Xen_integer_to_C_int(arg4), Xen_integer_to_C_int(arg5)); return(Xen_false); } static Xen gxm_XtCallActionProc(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5) { #define H_XtCallActionProc "void XtCallActionProc(widget, action, event, params, num_params) searches for the named action routine in the \ same manner and order as translation tables are bound. If found, the action routine is invoked with the specified widget, event pointer, \ and parameters." char **params = NULL; int i, len = 0; Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtCallActionProc", "Widget"); Xen_check_type(Xen_is_string(arg2), arg2, 2, "XtCallActionProc", "char*"); Xen_check_type(Xen_is_XEvent(arg3) || Xen_is_false(arg3), arg3, 3, "XtCallActionProc", "XEvent*"); Xen_check_type(Xen_is_list(arg4) || Xen_is_false(arg4), arg4, 4, "XtCallActionProc", "list of String"); Xen_check_type(Xen_is_integer_or_unbound(arg5), arg5, 5, "XtCallActionProc", "int"); if (Xen_is_list(arg4)) { if (Xen_is_integer(arg5)) len = Xen_integer_to_C_int(arg5); else len = Xen_list_length(arg4); } if (len > 0) { params = (char **)calloc(len, sizeof(char *)); for (i = 0; i < len; i++) params[i] = xen_strdup(Xen_string_to_C_string(Xen_list_ref(arg4, i))); } XtCallActionProc(Xen_to_C_Widget(arg1), (char *)Xen_string_to_C_string(arg2), (Xen_is_XEvent(arg3)) ? Xen_to_C_XEvent(arg3) : NULL, params, len); if (params) { for (i = 0; i < len; i++) if (params[i]) free(params[i]); free(params); } return(Xen_false); } static Xen gxm_XtGetActionList(Xen arg1) { #define H_XtGetActionList "void XtGetActionList(widget_class): list of actions" /* DIFF: XtGetActionList omit arg2 and 3, return list of lists */ unsigned int len; XtActionList act; Xen lst = Xen_empty_list; Xen_check_type(Xen_is_WidgetClass(arg1), arg1, 1, "XtGetActionList", "WidgetClass"); XtGetActionList(Xen_to_C_WidgetClass(arg1), &act, &len); if (len > 0) { int i; for (i = len - 1; i >= 0; i--) lst = Xen_cons(Xen_list_2(C_string_to_Xen_string(act[i].string), C_ulong_to_Xen_ulong(act[i].proc)), lst); free(act); } return(lst); } #define C_to_Xen_XM_ActionHook(Code, Context) \ Xen_list_5(C_string_to_Xen_symbol("ActionHook"), Code, Context, Xen_integer_zero, Xen_integer_zero) #define XM_is_ActionHook(Arg) is_wrapped("ActionHook", Arg) static bool unprotect_actionhook(Xen val, int loc, unsigned long id) { if ((XM_is_ActionHook(val)) && ((XtActionHookId)Xen_ulong_to_C_ulong(Xen_list_ref(val, 4)) == (XtActionHookId)id)) { xm_unprotect_at(loc); return(true); } return(false); } static Xen gxm_XtRemoveActionHook(Xen arg1) { #define H_XtRemoveActionHook "void XtRemoveActionHook(idP) removes the specified action hook procedure from the list in which it was registered." XtActionHookId id; Xen_check_type(Xen_is_XtActionHookId(arg1), arg1, 1, "XtRemoveActionHook", "XtActionHookId"); id = Xen_to_C_XtActionHookId(arg1); XtRemoveActionHook(id); map_over_protected_elements(unprotect_actionhook, (unsigned long)id); return(Xen_false); } static void gxm_XtActionHookProc(Widget w, XtPointer p, String s, XEvent* e, String* s1, Cardinal* c) { /* DIFF: XtActionHookProc takes 5 args (last is string list) */ Xen descr = (Xen)p; /* (list 'ActionHook function context gc-loc id) */ Xen_call_with_5_args(Xen_cadr(descr), C_to_Xen_Widget(w), Xen_caddr(descr), C_string_to_Xen_string(s), C_to_Xen_XEvent(e), C_to_Xen_Strings(s1, *c), __func__); } static Xen gxm_XtAppAddActionHook(Xen arg1, Xen arg2, Xen arg3) { #define H_XtAppAddActionHook "XtActionHookId XtAppAddActionHook(app_context, proc, client_data) adds the specified procedure to the front of \ a list maintained in the application context." XtActionHookId id; int gc_loc; Xen descr; Xen_check_type(Xen_is_XtAppContext(arg1), arg1, 1, "XtAppAddActionHook", "XtAppContext"); Xen_check_type(Xen_is_procedure(arg2) && (Xen_is_aritable(arg2, 5)), arg2, 2, "XtAppAddActionHook", "XtActionHookProc"); descr = C_to_Xen_XM_ActionHook(arg2, (Xen_is_bound(arg3)) ? arg3 : Xen_false); gc_loc = xm_protect(descr); id = XtAppAddActionHook(Xen_to_C_XtAppContext(arg1), gxm_XtActionHookProc, (XtPointer)descr); Xen_list_set(descr, 3, C_int_to_Xen_integer(gc_loc)); Xen_list_set(descr, 4, C_ulong_to_Xen_ulong(id)); return(C_to_Xen_XtActionHookId(id)); } /* (72) this is part of an actionrec */ /* this code is a horrible kludge, but what can I do? -- to vector to the procedure corresponding to * the action that triggered the action proc, I need to have some way to find that procedure, * and there's none I can see -- the args incoming (widget event args argn) give me no way to * trace back to the caller, or even to save that data at declaration time via clientData or * its equivalent -- I don't even get to see the affected widget. By the time install|augment|override * translations is called, my procedure info has been buried (or at least compiled into some unknown form). * * XtAppContext->action_table is a list of ActionLists * Widget struct has: XtTMRec tm: * XtTranslations translations; * XtBoundActions proc_table; -- list of XtActionProcs * struct _XtStateRec *current_state; */ static Xen xtactionprocs[9]; static void gxm_XtActionProc0(Widget w, XEvent *e, char **args, Cardinal *argn) { Xen_call_with_3_args(xtactionprocs[0], C_to_Xen_Widget(w), C_to_Xen_XEvent(e), C_to_Xen_Strings(args, *argn), __func__); } static void gxm_XtActionProc1(Widget w, XEvent *e, char **args, Cardinal *argn) { Xen_call_with_3_args(xtactionprocs[1], C_to_Xen_Widget(w), C_to_Xen_XEvent(e), C_to_Xen_Strings(args, *argn), __func__); } static void gxm_XtActionProc2(Widget w, XEvent *e, char **args, Cardinal *argn) { Xen_call_with_3_args(xtactionprocs[2], C_to_Xen_Widget(w), C_to_Xen_XEvent(e), C_to_Xen_Strings(args, *argn), __func__); } static void gxm_XtActionProc3(Widget w, XEvent *e, char **args, Cardinal *argn) { Xen_call_with_3_args(xtactionprocs[3], C_to_Xen_Widget(w), C_to_Xen_XEvent(e), C_to_Xen_Strings(args, *argn), __func__); } static void gxm_XtActionProc4(Widget w, XEvent *e, char **args, Cardinal *argn) { Xen_call_with_3_args(xtactionprocs[4], C_to_Xen_Widget(w), C_to_Xen_XEvent(e), C_to_Xen_Strings(args, *argn), __func__); } static void gxm_XtActionProc5(Widget w, XEvent *e, char **args, Cardinal *argn) { Xen_call_with_3_args(xtactionprocs[5], C_to_Xen_Widget(w), C_to_Xen_XEvent(e), C_to_Xen_Strings(args, *argn), __func__); } static void gxm_XtActionProc6(Widget w, XEvent *e, char **args, Cardinal *argn) { Xen_call_with_3_args(xtactionprocs[6], C_to_Xen_Widget(w), C_to_Xen_XEvent(e), C_to_Xen_Strings(args, *argn), __func__); } static void gxm_XtActionProc7(Widget w, XEvent *e, char **args, Cardinal *argn) { Xen_call_with_3_args(xtactionprocs[7], C_to_Xen_Widget(w), C_to_Xen_XEvent(e), C_to_Xen_Strings(args, *argn), __func__); } static void gxm_XtActionProc8(Widget w, XEvent *e, char **args, Cardinal *argn) { fprintf(stderr, "too many actions"); } static int xm_action_ctr = 0; static XtActionsRec *make_action_rec(int len, Xen larg2) { int i, gcloc; XtActionsRec *act; Xen arg2; arg2 = Xen_copy_arg(larg2); gcloc = xm_protect(arg2); act = (XtActionsRec *)calloc(len, sizeof(XtActionsRec)); for (i = 0; i < len; i++, arg2 = Xen_cdr(arg2)) { Xen pair; pair = Xen_car(arg2); act[i].string = (String)xen_strdup(Xen_string_to_C_string(Xen_car(pair))); if (xm_action_ctr >= 8) { fprintf(stderr,"too many actions..."); act[i].proc = (XtActionProc)gxm_XtActionProc8; xm_protect(Xen_cadr(pair)); xtactionprocs[8] = Xen_cadr(pair); } else { switch (xm_action_ctr) { case 0: act[i].proc = (XtActionProc)gxm_XtActionProc0; break; case 1: act[i].proc = (XtActionProc)gxm_XtActionProc1; break; case 2: act[i].proc = (XtActionProc)gxm_XtActionProc2; break; case 3: act[i].proc = (XtActionProc)gxm_XtActionProc3; break; case 4: act[i].proc = (XtActionProc)gxm_XtActionProc4; break; case 5: act[i].proc = (XtActionProc)gxm_XtActionProc5; break; case 6: act[i].proc = (XtActionProc)gxm_XtActionProc6; break; case 7: act[i].proc = (XtActionProc)gxm_XtActionProc7; break; } xm_protect(Xen_cadr(pair)); xtactionprocs[xm_action_ctr++] = Xen_cadr(pair); } } xm_unprotect_at(gcloc); return(act); } static Xen gxm_XtAppAddActions(Xen arg1, Xen arg2) { #define H_XtAppAddActions "void XtAppAddActions(app_context, actions, num_actions) adds the specified action table and registers it \ with the translation manager." /* DIFF: XtAddAppActions takes list of lists for arg2 (name proc) pairs, not XtActionList, omits arg3 (pointless) * and action proc itself takes 3 args (no need for trailing count) */ XtActionsRec *act; int i, len; Xen_check_type(Xen_is_XtAppContext(arg1), arg1, 1, "XtAppAddActions", "XtAppContext"); Xen_check_type(Xen_is_list(arg2), arg2, 2, "XtAppAddActions", "list of XtActions"); len = Xen_list_length(arg2); if (len <= 0) Xen_check_type(0, arg2, 2, "XtAppAddActions", "positive integer"); act = make_action_rec(len, arg2); XtAppAddActions(Xen_to_C_XtAppContext(arg1), act, len); for (i = 0; i < len; i++) if (act[i].string) free(act[i].string); free(act); return(arg1); } static Xen gxm_XtUninstallTranslations(Xen arg1) { #define H_XtUninstallTranslations "void XtUninstallTranslations(w) causes the entire translation table for widget to be removed." Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtUninstallTranslations", "Widget"); XtUninstallTranslations(Xen_to_C_Widget(arg1)); return(Xen_false); } static Xen gxm_XtInstallAllAccelerators(Xen arg1, Xen arg2) { #define H_XtInstallAllAccelerators "void XtInstallAllAccelerators(destination, source)" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtInstallAllAccelerators", "Widget"); Xen_check_type(Xen_is_Widget(arg2), arg2, 2, "XtInstallAllAccelerators", "Widget"); XtInstallAllAccelerators(Xen_to_C_Widget(arg1), Xen_to_C_Widget(arg2)); return(Xen_false); } static Xen gxm_XtInstallAccelerators(Xen arg1, Xen arg2) { #define H_XtInstallAccelerators "void XtInstallAccelerators(destination, source) installs the accelerators from source onto destination by \ augmenting the destination translations with the source accelerators." Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtInstallAccelerators", "Widget"); Xen_check_type(Xen_is_Widget(arg2), arg2, 2, "XtInstallAccelerators", "Widget"); XtInstallAccelerators(Xen_to_C_Widget(arg1), Xen_to_C_Widget(arg2)); return(Xen_false); } static Xen gxm_XtAugmentTranslations(Xen arg1, Xen arg2) { #define H_XtAugmentTranslations "void XtAugmentTranslations(w, translations) nondestructively merges the new translations into the existing \ widget translations." Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtAugmentTranslations", "Widget"); Xen_check_type(Xen_is_XtTranslations(arg2), arg2, 2, "XtAugmentTranslations", "XtTranslations"); XtAugmentTranslations(Xen_to_C_Widget(arg1), Xen_to_C_XtTranslations(arg2)); return(Xen_false); } static Xen gxm_XtOverrideTranslations(Xen arg1, Xen arg2) { #define H_XtOverrideTranslations "void XtOverrideTranslations(w, translations) destructively merges the new translations into the existing \ widget translations." Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtOverrideTranslations", "Widget"); Xen_check_type(Xen_is_XtTranslations(arg2), arg2, 2, "XtOverrideTranslations", "XtTranslations"); XtOverrideTranslations(Xen_to_C_Widget(arg1), Xen_to_C_XtTranslations(arg2)); return(Xen_false); } static Xen gxm_XtParseAcceleratorTable(Xen arg1) { #define H_XtParseAcceleratorTable "XtAccelerators XtParseAcceleratorTable(const char *source) compiles source" Xen_check_type(Xen_is_string(arg1), arg1, 1, "XtParseAcceleratorTable", "char*"); return(C_ulong_to_Xen_ulong(XtParseAcceleratorTable((char *)Xen_string_to_C_string(arg1)))); } static Xen gxm_XtParseTranslationTable(Xen arg1) { #define H_XtParseTranslationTable "XtTranslations XtParseTranslationTable(table) compiles the translation table into the opaque internal \ representation of type XtTranslations." Xen_check_type(Xen_is_string(arg1), arg1, 1, "XtParseTranslationTable", "char*"); return(C_to_Xen_XtTranslations(XtParseTranslationTable((char *)Xen_string_to_C_string(arg1)))); } static Xen gxm_XtKeysymToKeycodeList(Xen arg1, Xen arg2) { #define H_XtKeysymToKeycodeList "void XtKeysymToKeycodeList(display, keysym) procedure returns all the \ KeyCodes that have keysym in their entry for the keyboard mapping table associated with display -> (keycodes)." /* DIFF: XtKeysymToKeycodeList final 2 args omit, returns list */ unsigned int len; KeyCode *kr; Xen lst = Xen_empty_list; int loc; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XtKeysymToKeycodeList", "Display*"); Xen_check_type(Xen_is_KeySym(arg2), arg2, 2, "XtKeysymToKeycodeList", "KeySym"); XtKeysymToKeycodeList(Xen_to_C_Display(arg1), Xen_to_C_KeySym(arg2), &kr, &len); loc = xm_protect(lst); if (len > 0) { int i; for (i = len - 1; i >= 0; i--) lst = Xen_cons(C_to_Xen_KeyCode(kr[i]), lst); free(kr); } xm_unprotect_at(loc); return(lst); } static Xen gxm_XtTranslateCoords(Xen arg1, Xen arg2, Xen arg3) { #define H_XtTranslateCoords "void XtTranslateCoords(w, x, y): (root_x root_y)" /* DIFF: XtTranslateCoords omits and returns last 2 args */ Position x, y; Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtTranslateCoords", "Widget"); Xen_check_type(Xen_is_Position(arg2), arg2, 2, "XtTranslateCoords", "Position"); Xen_check_type(Xen_is_Position(arg3), arg3, 3, "XtTranslateCoords", "Position"); XtTranslateCoords(Xen_to_C_Widget(arg1), Xen_to_C_Position(arg2), Xen_to_C_Position(arg3), &x, &y); return(Xen_list_2(C_to_Xen_Position(x), C_to_Xen_Position(y))); } static Xen gxm_XtMakeResizeRequest(Xen arg1, Xen arg2, Xen arg3) { #define H_XtMakeResizeRequest "XtGeometryResult XtMakeResizeRequest(w, width, height): (res width height)" /* DIFF: XtMakeResizeRequest w wid hgt [rtnw rtn] -> (list res w h) */ Dimension w, h; int val; Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtMakeResizeRequest", "Widget"); Xen_check_type(Xen_is_Dimension(arg2), arg2, 2, "XtMakeResizeRequest", "Dimension"); Xen_check_type(Xen_is_Dimension(arg3), arg3, 3, "XtMakeResizeRequest", "Dimension"); val = XtMakeResizeRequest(Xen_to_C_Widget(arg1), Xen_to_C_Dimension(arg2), Xen_to_C_Dimension(arg3), &w, &h); return(Xen_list_3(C_int_to_Xen_integer(val), C_to_Xen_Dimension(w), C_to_Xen_Dimension(h))); } static Xen gxm_XtOwnSelectionIncremental(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6, Xen arg7, Xen arg8) { #define H_XtOwnSelectionIncremental "Boolean XtOwnSelectionIncremental(w, selection, time, convert_callback, lose_callback, \ done_callback, cancel_callback, client_data)" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtOwnSelectionIncremental", "Widget"); Xen_check_type(Xen_is_Atom(arg2), arg2, 2, "XtOwnSelectionIncremental", "Atom"); Xen_check_type(Xen_is_Time(arg3), arg3, 3, "XtOwnSelectionIncremental", "Time"); Xen_check_type(Xen_is_procedure(arg4) && (Xen_is_aritable(arg4, 10)), arg4, 4, "XtOwnSelectionIncremental", "XtConvertSelectionIncrProc"); Xen_check_type(Xen_is_procedure(arg5) && (Xen_is_aritable(arg5, 3)), arg5, 5, "XtOwnSelectionIncremental", "XtLoseSelectionIncrProc"); Xen_check_type(Xen_is_procedure(arg6) && (Xen_is_aritable(arg6, 5)), arg6, 6, "XtOwnSelectionIncremental", "XtSelectionDoneIncrProc"); Xen_check_type(Xen_is_procedure(arg7) && (Xen_is_aritable(arg7, 5)), arg7, 7, "XtOwnSelectionIncremental", "XtCancelConvertSelectionProc"); add_selmap(Xen_to_C_Widget(arg1), CONVERT_INCR, arg4); add_selmap(Xen_to_C_Widget(arg1), LOSE_INCR, arg5); add_selmap(Xen_to_C_Widget(arg1), DONE_INCR, arg6); add_selmap(Xen_to_C_Widget(arg1), CANCEL_CONVERT, arg7); return(C_bool_to_Xen_boolean(XtOwnSelectionIncremental(Xen_to_C_Widget(arg1), Xen_to_C_Atom(arg2), Xen_to_C_Time(arg3), (XtConvertSelectionIncrProc)gxm_XtConvertSelectionIncrProc, gxm_XtLoseSelectionIncrProc, gxm_XtSelectionDoneIncrProc, gxm_XtCancelConvertSelectionProc, (XtPointer)arg8))); } static Xen gxm_XtOwnSelection(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6) { #define H_XtOwnSelection "Boolean XtOwnSelection(w, selection, time, convert_proc, lose_selection, done_proc) informs the selection \ mechanism that a widget believes it owns a selection." Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtOwnSelection", "Widget"); Xen_check_type(Xen_is_Atom(arg2), arg2, 2, "XtOwnSelection", "Atom"); Xen_check_type(Xen_is_Time(arg3), arg3, 3, "XtOwnSelection", "Time"); Xen_check_type(Xen_is_procedure(arg4) && (Xen_is_aritable(arg4, 7)), arg4, 4, "XtOwnSelection", "XtConvertSelectionProc"); Xen_check_type(Xen_is_procedure(arg5) && (Xen_is_aritable(arg5, 2)), arg5, 5, "XtOwnSelection", "XtLoseSelectionProc"); Xen_check_type(Xen_is_procedure(arg6) && (Xen_is_aritable(arg6, 3)), arg6, 6, "XtOwnSelection", "XtSelectionDoneProc"); add_selmap(Xen_to_C_Widget(arg1), CONVERT, arg4); add_selmap(Xen_to_C_Widget(arg1), LOSE, arg5); add_selmap(Xen_to_C_Widget(arg1), DONE, arg6); return(C_bool_to_Xen_boolean(XtOwnSelection(Xen_to_C_Widget(arg1), Xen_to_C_Atom(arg2), Xen_to_C_Time(arg3), (XtConvertSelectionProc)gxm_XtConvertSelectionProc, gxm_XtLoseSelectionProc, gxm_XtSelectionDoneProc))); } static Xen gxm_XtIsSensitive(Xen arg1) { #define H_XtIsSensitive "Boolean XtIsSensitive(w): returns " PROC_TRUE " if user input events are being dispatched." Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtIsSensitive", "Widget"); return(C_bool_to_Xen_boolean(XtIsSensitive(Xen_to_C_Widget(arg1)))); } static Xen gxm_XtIsRealized(Xen arg1) { #define H_XtIsRealized "Boolean XtIsRealized(w): returns " PROC_TRUE " if the widget has been realized," Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtIsRealized", "Widget"); return(C_bool_to_Xen_boolean(XtIsRealized(Xen_to_C_Widget(arg1)))); } static Xen gxm_XtIsManaged(Xen arg1) { #define H_XtIsManaged "Boolean XtIsManaged(widget): returns " PROC_TRUE " if the specified widget is of class RectObj or any subclass thereof and is managed." Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtIsManaged", "Widget"); return(C_bool_to_Xen_boolean(XtIsManaged(Xen_to_C_Widget(arg1)))); } static Xen gxm_XtIsObject(Xen arg1) { #define H_XtIsObject "Boolean XtIsObject(w)" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtIsObject", "Widget"); return(C_bool_to_Xen_boolean(XtIsObject(Xen_to_C_Widget(arg1)))); } static Xen gxm_XtIsSubclass(Xen arg1, Xen arg2) { #define H_XtIsSubclass "Boolean XtIsSubclass(w, widget_class): returns " PROC_TRUE " if the class of the specified widget is equal to or is a \ subclass of the specified class." Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtIsSubclass", "Widget"); Xen_check_type(Xen_is_WidgetClass(arg2), arg2, 2, "XtIsSubclass", "WidgetClass"); return(C_bool_to_Xen_boolean(XtIsSubclass(Xen_to_C_Widget(arg1), Xen_to_C_WidgetClass(arg2)))); } static Xen gxm_XtAppPeekEvent(Xen arg1) { #define H_XtAppPeekEvent "Boolean XtAppPeekEvent(app_context) fills in the event and returns a nonzero value. If no X \ input is on the queue, XtAppPeekEvent flushes the output buffer and blocks until input is available." /* DIFF: XtAppPeekEvent app [ev] -> (list val ev) */ XEvent *e; int val; Xen_check_type(Xen_is_XtAppContext(arg1), arg1, 1, "XtAppPeekEvent", "XtAppContext"); e = (XEvent *)calloc(1, sizeof(XEvent)); val = XtAppPeekEvent(Xen_to_C_XtAppContext(arg1), e); return(Xen_list_2(C_bool_to_Xen_boolean(val), C_to_Xen_XEvent_OBJ(e))); } static Xen gxm_XtCallAcceptFocus(Xen arg1, Xen arg2) { #define H_XtCallAcceptFocus "Boolean XtCallAcceptFocus(w, time) calls the specified widget's accept_focus procedure, passing it the \ specified widget and time, and returns what the accept_focus procedure returns." /* DIFF: XtCallAcceptFocus takes Time arg (not Time*) */ Time tm; Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtCallAcceptFocus", "Widget"); Xen_check_type(Xen_is_Time(arg2), arg2, 2, "XtCallAcceptFocus", "Time"); tm = Xen_to_C_Time(arg2); return(C_bool_to_Xen_boolean(XtCallAcceptFocus(Xen_to_C_Widget(arg1), &tm))); } static Xen gxm_XtDispatchEvent(Xen arg1) { #define H_XtDispatchEvent "Boolean XtDispatchEvent(event) sends those events to the event handler functions that have been previously \ registered with the dispatch routine." Xen_check_type(Xen_is_XEvent(arg1), arg1, 1, "XtDispatchEvent", "XEvent*"); return(C_bool_to_Xen_boolean(XtDispatchEvent(Xen_to_C_XEvent(arg1)))); } static Xen gxm_XtUnmanageChild(Xen arg1) { #define H_XtUnmanageChild "void XtUnmanageChild(child)" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtUnmanageChild", "Widget"); XtUnmanageChild(Xen_to_C_Widget(arg1)); return(Xen_false); } static Xen gxm_XtUnmanageChildren(Xen arg1, Xen arg2) { #define H_XtUnmanageChildren "void XtUnmanageChildren(children, num_children)" /* DIFF: XtUnmanageChildren arg1 is list of widgets */ int len; Xen_check_type(Xen_is_list(arg1), arg1, 1, "XtUnmanageChildren", "WidgetList"); Xen_check_type(Xen_is_integer_or_unbound(arg2), arg2, 2, "XtUnmanageChildren", "int"); if (Xen_is_integer(arg2)) len = Xen_integer_to_C_int(arg2); else len = Xen_list_length(arg1); if (len > 0) { if (len > Xen_list_length(arg1)) Xen_out_of_range_error("XmContainerReorder", 2, arg2, "len too large"); else { WidgetList ws1; ws1 = Xen_to_C_Widgets(arg1, len); XtUnmanageChildren(ws1, len); if (ws1) free(ws1); } } return(Xen_false); } static Xen gxm_XtManageChild(Xen arg1) { #define H_XtManageChild "void XtManageChild(child)" Xen_check_type(Xen_is_Widget(arg1), arg1, 1, "XtManageChild", "Widget"); XtManageChild(Xen_to_C_Widget(arg1)); return(Xen_false); } static Xen gxm_XtManageChildren(Xen arg1, Xen arg2) { #define H_XtManageChildren "void XtManageChildren(children, num_children)" /* DIFF: XtManageChildren arg1 is list of widgets */ int len; Xen_check_type(Xen_is_list(arg1), arg1, 1, "XtManageChildren", "WidgetList"); Xen_check_type(Xen_is_integer_or_unbound(arg2), arg2, 2, "XtManageChildren", "int"); if (Xen_is_integer(arg2)) len = Xen_integer_to_C_int(arg2); else len = Xen_list_length(arg1); if (len > 0) { if (len > Xen_list_length(arg1)) Xen_out_of_range_error("XmContainerReorder", 2, arg2, "len too large"); else { WidgetList ws1; ws1 = Xen_to_C_Widgets(arg1, len); XtManageChildren(ws1, len); if (ws1) free(ws1); } } return(Xen_false); } static Xen gxm_XtIsRectObj(Xen arg) { #define H_XtIsRectObj "Boolean XtIsRectObj(w)" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XtIsRectObj", "Widget"); return(C_bool_to_Xen_boolean(XtIsRectObj(Xen_to_C_Widget(arg)))); } static Xen gxm_XtIsWidget(Xen arg) { #define H_XtIsWidget "Boolean XtIsWidget(w)" return(C_bool_to_Xen_boolean(is_wrapped("Widget", arg) && (XtIsWidget(Xen_to_C_Widget(arg))))); } static Xen gxm_XtIsComposite(Xen arg) { #define H_XtIsComposite "Boolean XtIsComposite(w)" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XtIsComposite", "Widget"); return(C_bool_to_Xen_boolean(XtIsComposite(Xen_to_C_Widget(arg)))); } static Xen gxm_XtIsConstraint(Xen arg) { #define H_XtIsConstraint "Boolean XtIsConstraint(w)" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XtIsConstraint", "Widget"); return(C_bool_to_Xen_boolean(XtIsConstraint(Xen_to_C_Widget(arg)))); } static Xen gxm_XtIsShell(Xen arg) { #define H_XtIsShell "Boolean XtIsShell(w)" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XtIsShell", "Widget"); return(C_bool_to_Xen_boolean(XtIsShell(Xen_to_C_Widget(arg)))); } static Xen gxm_XtIsOverrideShell(Xen arg) { #define H_XtIsOverrideShell "Boolean XtIsOverrideShell(w)" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XtIsOverrideShell", "Widget"); return(C_bool_to_Xen_boolean(XtIsOverrideShell(Xen_to_C_Widget(arg)))); } static Xen gxm_XtIsWMShell(Xen arg) { #define H_XtIsWMShell "Boolean XtIsWMShell(w)" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XtIsWMShell", "Widget"); return(C_bool_to_Xen_boolean(XtIsWMShell(Xen_to_C_Widget(arg)))); } static Xen gxm_XtIsVendorShell(Xen arg) { #define H_XtIsVendorShell "Boolean XtIsVendorShell(w)" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XtIsVendorShell", "Widget"); return(C_bool_to_Xen_boolean(XtIsVendorShell(Xen_to_C_Widget(arg)))); } static Xen gxm_XtIsTransientShell(Xen arg) { #define H_XtIsTransientShell "Boolean XtIsTransientShell(w)" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XtIsTransientShell", "Widget"); return(C_bool_to_Xen_boolean(XtIsTransientShell(Xen_to_C_Widget(arg)))); } static Xen gxm_XtIsTopLevelShell(Xen arg) { #define H_XtIsTopLevelShell "Boolean XtIsTopLevelShell(w)" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XtIsTopLevelShell", "Widget"); return(C_bool_to_Xen_boolean(XtIsTopLevelShell(Xen_to_C_Widget(arg)))); } static Xen gxm_XtIsApplicationShell(Xen arg) { #define H_XtIsApplicationShell "Boolean XtIsApplicationShell(w)" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XtIsApplicationShell", "Widget"); return(C_bool_to_Xen_boolean(XtIsApplicationShell(Xen_to_C_Widget(arg)))); } static Xen gxm_XtIsSessionShell(Xen arg) { #define H_XtIsSessionShell "Boolean XtIsSessionShell(w)" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XtIsSessionShell", "Widget"); return(C_bool_to_Xen_boolean(XtIsSessionShell(Xen_to_C_Widget(arg)))); } static Xen gxm_XtMapWidget(Xen arg) { #define H_XtMapWidget "XtMapWidget(w)" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XtMapWidget", "Widget"); XtMapWidget(Xen_to_C_Widget(arg)); return(Xen_false); } static Xen gxm_XtUnmapWidget(Xen arg) { #define H_XtUnmapWidget "XtUnmapWidget(w)" Xen_check_type(Xen_is_Widget(arg), arg, 0, "XtUnmapWidget", "Widget"); XtUnmapWidget(Xen_to_C_Widget(arg)); return(Xen_false); } static Xen gxm_XtSetArg(Xen arg1, Xen arg2, Xen arg3) { #define H_XtSetArg "XtSetArg in xm is useless -- it returns its arguments as a list" return(Xen_list_3(arg1, arg2, arg3)); } /* ---------------------------------------------------------------------------------------------------- */ Xm_type_ptr_no_c2x(XpmImage, XpmImage *) Xm_type_ptr_no_c2x(XpmAttributes, XpmAttributes *) /* _OBJ?? */ Xm_type_ptr_no_c2x(XpmColorSymbol, XpmColorSymbol *) static Xen gxm_XpmCreateXpmImageFromPixmap(Xen arg1, Xen arg2, Xen arg3, Xen arg5) { XpmImage *image; int val; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XpmCreateXpmImageFromPixmap", "Display*"); Xen_check_type(Xen_is_Pixmap(arg2), arg2, 2, "XpmCreateXpmImageFromPixmap", "Pixmap"); Xen_check_type(Xen_is_Pixmap(arg3), arg3, 3, "XpmCreateXpmImageFromPixmap", "Pixmap"); Xen_check_type(Xen_is_XpmAttributes(arg5) || Xen_is_false(arg5), arg5, 5, "XpmCreateXpmImageFromPixmap", "XpmAttributes*"); image = (XpmImage *)calloc(1, sizeof(XpmImage)); val = XpmCreateXpmImageFromPixmap(Xen_to_C_Display(arg1), Xen_to_C_Pixmap(arg2), Xen_to_C_Pixmap(arg3), image, (Xen_is_false(arg5)) ? NULL : Xen_to_C_XpmAttributes(arg5)); if (val == XpmSuccess) return(wrap_for_Xen_obj("XpmImage", image)); free(image); return(C_int_to_Xen_integer(val)); } static Xen gxm_XpmCreatePixmapFromXpmImage(Xen arg1, Xen arg2, Xen arg3, Xen arg4) { /* DIFF: XpmCreatePixmapFromXpmImage omits and returns pixmap args */ Pixmap p1, p2; int val; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XpmCreatePixmapFromXpmImage", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XpmCreatePixmapFromXpmImage", "Drawable"); Xen_check_type(Xen_is_XpmImage(arg3), arg3, 3, "XpmCreatePixmapFromXpmImage", "XpmImage*"); Xen_check_type(Xen_is_XpmAttributes(arg4) || Xen_is_false(arg4), arg4, 4, "XpmCreatePixmapFromXpmImage", "XpmAttributes*"); val = XpmCreatePixmapFromXpmImage(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), Xen_to_C_XpmImage(arg3), &p1, &p2, (Xen_is_false(arg4)) ? NULL : Xen_to_C_XpmAttributes(arg4)); return(Xen_list_3(C_int_to_Xen_integer(val), C_to_Xen_Pixmap(p1), C_to_Xen_Pixmap(p2))); } static Xen gxm_XpmReadFileToPixmap(Xen arg1, Xen arg2, Xen arg3, Xen arg6) { /* DIFF: XpmReadFileToPixmap omits and returns pixmap args */ Pixmap p1, p2; int val; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XpmReadFileToPixmap", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XpmReadFileToPixmap", "Drawable"); Xen_check_type(Xen_is_string(arg3), arg3, 3, "XpmReadFileToPixmap", "char*"); Xen_check_type(Xen_is_XpmAttributes(arg6) || Xen_is_false(arg6), arg6, 6, "XpmReadFileToPixmap", "XpmAttributes*"); val = XpmReadFileToPixmap(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), (char *)Xen_string_to_C_string(arg3), &p1, &p2, (Xen_is_false(arg6)) ? NULL : Xen_to_C_XpmAttributes(arg6)); return(Xen_list_3(C_int_to_Xen_integer(val), C_to_Xen_Pixmap(p1), C_to_Xen_Pixmap(p2))); } static Xen gxm_XpmReadFileToXpmImage(Xen arg1) { int val; XpmImage *image; Xen_check_type(Xen_is_string(arg1), arg1, 1, "XpmReadFileToXpmImage", "char*"); image = (XpmImage *)calloc(1, sizeof(XpmImage)); val = XpmReadFileToXpmImage((char *)Xen_string_to_C_string(arg1), image, NULL); if (val == XpmSuccess) return(wrap_for_Xen_obj("XpmImage", image)); free(image); return(C_int_to_Xen_integer(val)); } static Xen gxm_XpmCreatePixmapFromData(Xen arg1, Xen arg2, Xen larg3, Xen arg6) { /* DIFF: XpmCreatePixmapFromData omits and returns pixmap args, arg3 (bits) is list of strings */ Pixmap p1, p2; int val, i, len; char **bits; Xen arg3; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XpmCreatePixmapFromData", "Display*"); Xen_check_type(Xen_is_Window(arg2), arg2, 2, "XpmCreatePixmapFromData", "Drawable"); Xen_check_type(Xen_is_list(larg3), larg3, 3, "XpmCreatePixmapFromData", "list of char*"); Xen_check_type(Xen_is_XpmAttributes(arg6) || Xen_is_false(arg6), arg6, 6, "XpmCreatePixmapFromData", "XpmAttributes*"); arg3 = Xen_copy_arg(larg3); len = Xen_list_length(arg3); if (len <= 0) Xen_check_type(0, arg3, 3, "XpmCreatePixmapFromData", "positive integer"); bits = (char **)calloc(len, sizeof(char *)); for (i = 0; i < len; i++, arg3 = Xen_cdr(arg3)) bits[i] = xen_strdup(Xen_string_to_C_string(Xen_car(arg3))); val = XpmCreatePixmapFromData(Xen_to_C_Display(arg1), Xen_to_C_Window(arg2), bits, &p1, &p2, (Xen_is_false(arg6)) ? NULL : Xen_to_C_XpmAttributes(arg6)); for (i = 0; i < len; i++) if (bits[i]) free(bits[i]); free(bits); return(Xen_list_3(C_int_to_Xen_integer(val), C_to_Xen_Pixmap(p1), C_to_Xen_Pixmap(p2))); } static Xen gxm_XpmWriteFileFromPixmap(Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5) { Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XpmWriteFileFromPixmap", "Display*"); Xen_check_type(Xen_is_string(arg2), arg2, 2, "XpmWriteFileFromPixmap", "char*"); Xen_check_type(Xen_is_Pixmap(arg3), arg3, 3, "XpmWriteFileFromPixmap", "Pixmap"); Xen_check_type(Xen_is_Pixmap(arg4), arg4, 4, "XpmWriteFileFromPixmap", "Pixmap"); Xen_check_type(Xen_is_XpmAttributes(arg5) || Xen_is_false(arg5), arg5, 5, "XpmWriteFileFromPixmap", "XpmAttributes*"); return(C_int_to_Xen_integer(XpmWriteFileFromPixmap(Xen_to_C_Display(arg1), (char *)Xen_string_to_C_string(arg2), Xen_to_C_Pixmap(arg3), Xen_to_C_Pixmap(arg4), (Xen_is_false(arg5)) ? NULL : Xen_to_C_XpmAttributes(arg5)))); } static Xen gxm_XpmCreateDataFromPixmap(Xen arg1, Xen arg3, Xen arg4, Xen arg5) { /* DIFF: XpmCreateDataFromPixmap arg2 omitted and rtn'd */ char **buf = NULL; int val; Xen_check_type(Xen_is_Display(arg1), arg1, 1, "XpmCreateDataFromPixmap", "Display*"); Xen_check_type(Xen_is_Pixmap(arg3), arg3, 3, "XpmCreateDataFromPixmap", "Pixmap"); Xen_check_type(Xen_is_Pixmap(arg4), arg4, 4, "XpmCreateDataFromPixmap", "Pixmap"); Xen_check_type(Xen_is_XpmAttributes(arg5) || Xen_is_false(arg5), arg5, 5, "XpmCreateDataFromPixmap", "XpmAttributes*"); val = XpmCreateDataFromPixmap(Xen_to_C_Display(arg1), &buf, Xen_to_C_Pixmap(arg3), Xen_to_C_Pixmap(arg4), (Xen_is_false(arg5)) ? NULL : Xen_to_C_XpmAttributes(arg5)); return(Xen_list_2(C_int_to_Xen_integer(val), Xen_wrap_C_pointer(buf))); } static Xen gxm_XpmGetErrorString(Xen err) { #define H_XpmGetErrorString "(XpmGetErrorString err): string describing error" Xen_check_type(Xen_is_integer(err), err, 1, "XpmGetErrorString", "an Xpm status code"); return(C_string_to_Xen_string(XpmGetErrorString(Xen_integer_to_C_int(err)))); } static Xen gxm_XpmColorSymbol(Xen name, Xen value, Xen pixel) { XpmColorSymbol *r; #define H_XpmColorSymbol "(XpmColorSymbol name val pix): new XpmColorSymbol struct" Xen_check_type(Xen_is_string(name), name, 1, "XpmColorSymbol", "char*"); Xen_check_type(Xen_is_false(value) || Xen_is_string(value), value, 2, "XpmColorSymbol", "char*"); Xen_check_type(Xen_is_Pixel(pixel), pixel, 3, "XpmColorSymbol", "Pixel"); r = (XpmColorSymbol *)calloc(1, sizeof(XpmColorSymbol)); r->name = (char *)Xen_string_to_C_string(name); r->value = (Xen_is_false(value)) ? NULL : (char *)Xen_string_to_C_string(value); r->pixel = Xen_to_C_Pixel(pixel); return(wrap_for_Xen_obj("XpmColorSymbol",r)); } static Xen gxm_XpmImage(Xen width, Xen height, Xen cpp, Xen ncolors, Xen data) { XpmImage *r; #define H_XpmImage "(XpmImage w h cpp n data): new XpmImage struct" Xen_check_type(Xen_is_ulong(width), width, 1, "XpmImage", "ulong"); Xen_check_type(Xen_is_ulong(height), height, 2, "XpmImage", "ulong"); Xen_check_type(Xen_is_ulong(cpp), cpp, 3, "XpmImage", "ulong"); Xen_check_type(Xen_is_ulong(ncolors), ncolors, 4, "XpmImage", "ulong"); Xen_check_type(Xen_is_ulong(data), data, 5, "XpmImage", "ulong"); r = (XpmImage *)calloc(1, sizeof(XpmImage)); r->width = Xen_ulong_to_C_ulong(width); r->height = Xen_ulong_to_C_ulong(height); r->cpp = Xen_ulong_to_C_ulong(cpp); r->ncolors = Xen_ulong_to_C_ulong(ncolors); r->data = (unsigned int *)Xen_ulong_to_C_ulong(data); return(wrap_for_Xen_obj("XpmImage", r)); } static Xen gxm_XpmAttributes(void) { #define H_XpmAttributes "(XpmAttributes): new XpmAttributes struct" return(wrap_for_Xen_obj("XpmAttributes", (XpmAttributes *)calloc(1, sizeof(XpmAttributes)))); } static Xen gxm_cpp(Xen ptr) { XM_field_assert_type((Xen_is_XpmImage(ptr)) || (Xen_is_XpmAttributes(ptr)), ptr, 1, "cpp", "XpmImage"); if (Xen_is_XpmImage(ptr)) return(C_ulong_to_Xen_ulong((unsigned long)((Xen_to_C_XpmImage(ptr))->cpp))); return(C_ulong_to_Xen_ulong((unsigned long)((Xen_to_C_XpmAttributes(ptr))->cpp))); } static Xen gxm_set_cpp(Xen ptr, Xen val) { XM_set_field_assert_type((Xen_is_XpmImage(ptr)) || (Xen_is_XpmAttributes(ptr)), ptr, 1, "cpp", "XpmImage"); if (Xen_is_XpmImage(ptr)) (Xen_to_C_XpmImage(ptr))->cpp = Xen_ulong_to_C_ulong(val); (Xen_to_C_XpmAttributes(ptr))->cpp = Xen_ulong_to_C_ulong(val); return(val); } static Xen gxm_ncolors(Xen ptr) { XM_field_assert_type((Xen_is_XpmImage(ptr)) || (Xen_is_XpmAttributes(ptr)), ptr, 1, "ncolors", "XpmImage"); if (Xen_is_XpmImage(ptr)) return(C_ulong_to_Xen_ulong((unsigned long)((Xen_to_C_XpmImage(ptr))->ncolors))); return(C_ulong_to_Xen_ulong((unsigned long)((Xen_to_C_XpmAttributes(ptr))->ncolors))); } static Xen gxm_set_ncolors(Xen ptr, Xen val) { XM_set_field_assert_type((Xen_is_XpmImage(ptr)) || (Xen_is_XpmAttributes(ptr)), ptr, 1, "ncolors", "XpmImage"); if (Xen_is_XpmImage(ptr)) (Xen_to_C_XpmImage(ptr))->ncolors = Xen_ulong_to_C_ulong(val); else (Xen_to_C_XpmAttributes(ptr))->ncolors = Xen_ulong_to_C_ulong(val); return(val); } #if 0 static Xen gxm_set_data(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_XpmImage(ptr), ptr, 1, "data", "XpmImage"); (Xen_to_C_XpmImage(ptr))->data = (unsigned int *)Xen_unwrap_C_pointer(val); return(val); } #endif static Xen gxm_valuemask(Xen ptr) { XM_field_assert_type(Xen_is_XpmAttributes(ptr), ptr, 1, "valuemask", "XpmAttributes"); return(C_ulong_to_Xen_ulong((unsigned long)((Xen_to_C_XpmAttributes(ptr))->valuemask))); } static Xen gxm_set_valuemask(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_XpmAttributes(ptr), ptr, 1, "valuemask", "XpmAttributes"); (Xen_to_C_XpmAttributes(ptr))->valuemask = Xen_ulong_to_C_ulong(val); return(val); } static Xen gxm_x_hotspot(Xen ptr) { XM_field_assert_type(Xen_is_XpmAttributes(ptr), ptr, 1, "x_hotspot", "XpmAttributes"); return(C_ulong_to_Xen_ulong((unsigned long)((Xen_to_C_XpmAttributes(ptr))->x_hotspot))); } static Xen gxm_set_x_hotspot(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_XpmAttributes(ptr), ptr, 1, "x_hotspot", "XpmAttributes"); (Xen_to_C_XpmAttributes(ptr))->x_hotspot = Xen_ulong_to_C_ulong(val); return(val); } static Xen gxm_y_hotspot(Xen ptr) { XM_field_assert_type(Xen_is_XpmAttributes(ptr), ptr, 1, "y_hotspot", "XpmAttributes"); return(C_ulong_to_Xen_ulong((unsigned long)((Xen_to_C_XpmAttributes(ptr))->y_hotspot))); } static Xen gxm_set_y_hotspot(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_XpmAttributes(ptr), ptr, 1, "y_hotspot", "XpmAttributes"); (Xen_to_C_XpmAttributes(ptr))->y_hotspot = Xen_ulong_to_C_ulong(val); return(val); } static Xen gxm_colorsymbols(Xen ptr) { XpmAttributes *atr; int len; Xen lst = Xen_empty_list; XM_field_assert_type(Xen_is_XpmAttributes(ptr), ptr, 1, "colorsymbols", "XpmAttributes"); atr = Xen_to_C_XpmAttributes(ptr); len = atr->numsymbols; if (len > 0) { int i; XpmColorSymbol *cols; cols = atr->colorsymbols; for (i = len - 1; i >= 0; i--) lst = Xen_cons(wrap_for_Xen("XpmColorSymbol", &(cols[i])), lst); } return(lst); } static Xen gxm_set_colorsymbols(Xen ptr, Xen vals) { XpmAttributes *atr; int len; XM_set_field_assert_type(Xen_is_XpmAttributes(ptr), ptr, 1, "colorsymbols", "XpmAttributes"); XM_set_field_assert_type(Xen_is_list(vals), vals, 2, "colorsymbols", "list of XpmColorSymbols"); atr = Xen_to_C_XpmAttributes(ptr); len = Xen_list_length(vals); if (len > 0) { Xen lst; int i; XpmColorSymbol *cols = NULL, *cur; cols = (XpmColorSymbol *)calloc(len, sizeof(XpmColorSymbol)); for (lst = Xen_copy_arg(vals), i = 0; i < len; i++, lst = Xen_cdr(lst)) { cur = Xen_to_C_XpmColorSymbol(Xen_car(lst)); if (cur->name) cols[i].name = xen_strdup(cur->name); if (cur->value) cols[i].value = xen_strdup(cur->value); cols[i].pixel = cur->pixel; } atr->colorsymbols = cols; } return(vals); } static Xen gxm_numsymbols(Xen ptr) { XM_field_assert_type(Xen_is_XpmAttributes(ptr), ptr, 1, "numsymbols", "XpmAttributes"); return(C_ulong_to_Xen_ulong((unsigned long)((Xen_to_C_XpmAttributes(ptr))->numsymbols))); } static Xen gxm_set_numsymbols(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_XpmAttributes(ptr), ptr, 1, "numsymbols", "XpmAttributes"); XM_set_field_assert_type(Xen_is_integer(val), val, 2, "numsymbols", "integer"); (Xen_to_C_XpmAttributes(ptr))->numsymbols = Xen_integer_to_C_int(val); return(val); } /* pixels is the list -- not sure what good npixels is without pixels */ static Xen gxm_npixels(Xen ptr) { XM_field_assert_type(Xen_is_XpmAttributes(ptr), ptr, 1, "npixels", "XpmAttributes"); return(C_ulong_to_Xen_ulong((unsigned long)((Xen_to_C_XpmAttributes(ptr))->npixels))); } static Xen gxm_set_npixels(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_XpmAttributes(ptr), ptr, 1, "npixels", "XpmAttributes"); XM_set_field_assert_type(Xen_is_integer(val), val, 2, "npixels", "integer"); (Xen_to_C_XpmAttributes(ptr))->npixels = Xen_integer_to_C_int(val); return(val); } #if WITH_EDITRES static Xen gxm_XEditResCheckMessages(Xen widget, Xen data, Xen event, Xen cont) { Boolean flag; Xen_check_type(Xen_is_Widget(widget), widget, 1, "widget", "_XEditResCheckMessages"); Xen_check_type(Xen_is_XEvent(event), event, 3, "XEvent", "_XEditResCheckMessages"); Xen_check_type(Xen_is_boolean(cont), cont, 4, "boolean", "_XEditResCheckMessages"); flag = Xen_boolean_to_C_bool(cont); _XEditResCheckMessages(Xen_to_C_Widget(widget), (XtPointer)data, Xen_to_C_XEvent(event), &flag); return(Xen_false); } #endif /* -------------------------------- struct handlers -------------------------------- */ /* XRectangle */ static Xen gxm_XRectangle(Xen x, Xen y, Xen width, Xen height) { #define H_XRectangle "(XRectangle x y width height): returns the given XRectangle" XRectangle *r; Xen_check_type(Xen_is_integer(x), x, 1, "XRectangle", "short"); Xen_check_type(Xen_is_integer(y), y, 2, "XRectangle", "short"); Xen_check_type(Xen_is_integer(width), width, 3, "XRectangle", "INT"); Xen_check_type(Xen_is_integer(height), height, 4, "XRectangle", "INT"); r = (XRectangle *)calloc(1, sizeof(XRectangle)); r->x = (short)Xen_integer_to_C_int(x); r->y = (short)Xen_integer_to_C_int(y); r->width = Xen_integer_to_C_int(width); r->height = Xen_integer_to_C_int(height); return(C_to_Xen_XRectangle(r)); } /* XSegment */ static Xen gxm_XSegment(Xen x1, Xen y1, Xen x2, Xen y2) { XSegment *r; #define H_XSegment "(XSegment x1 y1 x2 y2): new XSegment struct" Xen_check_type(Xen_is_integer(x1), x1, 1, "XSegment", "short"); Xen_check_type(Xen_is_integer(y1), y1, 2, "XSegment", "short"); Xen_check_type(Xen_is_integer(x2), x2, 3, "XSegment", "short"); Xen_check_type(Xen_is_integer(y2), y2, 4, "XSegment", "short"); r = (XSegment *)calloc(1, sizeof(XSegment)); r->x1 = (short)Xen_integer_to_C_int(x1); r->y1 = (short)Xen_integer_to_C_int(y1); r->x2 = (short)Xen_integer_to_C_int(x2); r->y2 = (short)Xen_integer_to_C_int(y2); return(C_to_Xen_XSegment(r)); } static Xen gxm_y2(Xen ptr) { if (Xen_is_XSegment(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XSegment(ptr))->y2))); XM_field_assert_type(0, ptr, 1, "y2", "XSegment"); return(Xen_false); } static Xen gxm_set_y2(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_integer(val), val, 1, "y2", "an integer"); XM_set_field_assert_type(Xen_is_XSegment(ptr), ptr, 2, "y2", "XSegment"); (Xen_to_C_XSegment(ptr))->y2 = (short)Xen_integer_to_C_int(val); return(val); } static Xen gxm_x2(Xen ptr) { if (Xen_is_XSegment(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XSegment(ptr))->x2))); XM_field_assert_type(0, ptr, 1, "x2", "XSegment"); return(Xen_false); } static Xen gxm_set_x2(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_integer(val), val, 1, "x2", "an integer"); XM_set_field_assert_type(Xen_is_XSegment(ptr), ptr, 2, "x2", "XSegment"); (Xen_to_C_XSegment(ptr))->x2 = (short)Xen_integer_to_C_int(val); return(val); } static Xen gxm_y1(Xen ptr) { if (Xen_is_XSegment(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XSegment(ptr))->y1))); XM_field_assert_type(0, ptr, 1, "y1", "XSegment"); return(Xen_false); } static Xen gxm_set_y1(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_integer(val), val, 1, "y1", "an integer"); XM_set_field_assert_type(Xen_is_XSegment(ptr), ptr, 2, "y1", "XSegment"); (Xen_to_C_XSegment(ptr))->y1 = (short)Xen_integer_to_C_int(val); return(val); } static Xen gxm_x1(Xen ptr) { if (Xen_is_XSegment(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XSegment(ptr))->x1))); XM_field_assert_type(0, ptr, 1, "x1", "XSegment"); return(Xen_false); } static Xen gxm_set_x1(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_integer(val), val, 1, "x1", "an integer"); XM_set_field_assert_type(Xen_is_XSegment(ptr), ptr, 2, "x1", "XSegment"); (Xen_to_C_XSegment(ptr))->x1 = (short)Xen_integer_to_C_int(val); return(val); } /* XPoint */ static Xen gxm_XPoint(Xen x, Xen y) { XPoint *r; #define H_XPoint "(XPoint x y): new XPoint struct" Xen_check_type(Xen_is_integer(x), x, 1, "XPoint", "short"); Xen_check_type(Xen_is_integer(y), y, 2, "XPoint", "short"); r = (XPoint *)calloc(1, sizeof(XPoint)); r->x = (short)Xen_integer_to_C_int(x); r->y = (short)Xen_integer_to_C_int(y); return(C_to_Xen_XPoint(r)); } /* XArc */ static Xen gxm_XArc(Xen x, Xen y, Xen width, Xen height, Xen angle1, Xen angle2) { XArc *r; #define H_XArc "(XArc x y w h ang1 ang2): new XArc struct" Xen_check_type(Xen_is_integer(x), x, 1, "XArc", "short"); Xen_check_type(Xen_is_integer(y), y, 2, "XArc", "short"); Xen_check_type(Xen_is_integer(width), width, 3, "XArc", "INT"); Xen_check_type(Xen_is_integer(height), height, 4, "XArc", "INT"); Xen_check_type(Xen_is_integer(angle1), angle1, 5, "XArc", "short"); Xen_check_type(Xen_is_integer(angle2), angle2, 6, "XArc", "short"); r = (XArc *)calloc(1, sizeof(XArc)); r->x = (short)Xen_integer_to_C_int(x); r->y = (short)Xen_integer_to_C_int(y); r->width = Xen_integer_to_C_int(width); r->height = Xen_integer_to_C_int(height); r->angle1 = (short)Xen_integer_to_C_int(angle1); r->angle2 = (short)Xen_integer_to_C_int(angle2); return(C_to_Xen_XArc(r)); } static Xen gxm_angle2(Xen ptr) { XM_field_assert_type(Xen_is_XArc(ptr), ptr, 1, "angle2", "XArc"); return(C_int_to_Xen_integer((int)((Xen_to_C_XArc(ptr))->angle2))); } static Xen gxm_set_angle2(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_integer(val), val, 1, "angle2", "an integer"); XM_set_field_assert_type(Xen_is_XArc(ptr), ptr, 2, "angle2", "XArc"); (Xen_to_C_XArc(ptr))->angle2 = (short)Xen_integer_to_C_int(val); return(val); } static Xen gxm_angle1(Xen ptr) { XM_field_assert_type(Xen_is_XArc(ptr), ptr, 1, "angle1", "XArc"); return(C_int_to_Xen_integer((int)((Xen_to_C_XArc(ptr))->angle1))); } static Xen gxm_set_angle1(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_integer(val), val, 1, "angle1", "an integer"); XM_set_field_assert_type(Xen_is_XArc(ptr), ptr, 2, "angle1", "XArc"); (Xen_to_C_XArc(ptr))->angle1 = (short)Xen_integer_to_C_int(val); return(val); } /* XColor */ static Xen gxm_XColor(Xen pixel, Xen red, Xen green, Xen blue, Xen flags, Xen pad) { XColor *r; #define H_XColor "(XColor pixel red green blue flags pad): new XColor struct" Xen_check_type(Xen_is_ulong(pixel) || !Xen_is_bound(pixel), pixel, 1, "XColor", "ulong"); Xen_check_type(Xen_is_integer_or_unbound(red), red, 2, "XColor", "int"); Xen_check_type(Xen_is_integer_or_unbound(green), green, 3, "XColor", "int"); Xen_check_type(Xen_is_integer_or_unbound(blue), blue, 4, "XColor", "int"); Xen_check_type(Xen_is_integer_or_unbound(flags), flags, 5, "XColor", "char"); Xen_check_type(Xen_is_integer_or_unbound(pad), pad, 6, "XColor", "char"); r = (XColor *)calloc(1, sizeof(XColor)); if (Xen_is_bound(pixel)) r->pixel = Xen_ulong_to_C_ulong(pixel); if (Xen_is_bound(red)) r->red = Xen_integer_to_C_int(red); if (Xen_is_bound(green)) r->green = Xen_integer_to_C_int(green); if (Xen_is_bound(blue)) r->blue = Xen_integer_to_C_int(blue); if (Xen_is_bound(flags)) r->flags = (char)Xen_integer_to_C_int(flags); if (Xen_is_bound(pad)) r->pad = (char)Xen_integer_to_C_int(pad); return(C_to_Xen_XColor(r)); } static Xen gxm_pad(Xen ptr) { XM_field_assert_type(Xen_is_XColor(ptr), ptr, 1, "pad", "XColor"); return(C_int_to_Xen_integer((char)((Xen_to_C_XColor(ptr))->pad))); } static Xen gxm_set_pad(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_XColor(ptr), ptr, 1, "pad", "XColor"); XM_set_field_assert_type(Xen_is_integer(val), val, 2, "pad", "char"); (Xen_to_C_XColor(ptr))->pad = (char)Xen_integer_to_C_int(val); return(val); } static Xen gxm_blue(Xen ptr) { if (Xen_is_XColor(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XColor(ptr))->blue))); XM_field_assert_type(0, ptr, 1, "blue", "XColor"); return(Xen_false); } static Xen gxm_set_blue(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_integer(val), val, 2, "blue", "an integer"); if (Xen_is_XColor(ptr)) (Xen_to_C_XColor(ptr))->blue = Xen_integer_to_C_int(val); else XM_set_field_assert_type(0, ptr, 1, "blue", "XColor"); return(val); } static Xen gxm_green(Xen ptr) { if (Xen_is_XColor(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XColor(ptr))->green))); XM_field_assert_type(0, ptr, 1, "green", "XColor"); return(Xen_false); } static Xen gxm_set_green(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_integer(val), val, 2, "green", "an integer"); if (Xen_is_XColor(ptr)) (Xen_to_C_XColor(ptr))->green = Xen_integer_to_C_int(val); else XM_set_field_assert_type(0, ptr, 1, "green", "XColor"); return(val); } static Xen gxm_red(Xen ptr) { if (Xen_is_XColor(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XColor(ptr))->red))); XM_field_assert_type(0, ptr, 1, "red", "XColor"); return(Xen_false); } static Xen gxm_set_red(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_integer(val), val, 2, "red", "an integer"); if (Xen_is_XColor(ptr)) (Xen_to_C_XColor(ptr))->red = Xen_integer_to_C_int(val); else XM_set_field_assert_type(0, ptr, 1, "red", "XColor"); return(val); } static Xen gxm_XWindowChanges(Xen x, Xen y, Xen width, Xen height, Xen border_width, Xen sibling, Xen stack_mode) { XWindowChanges *r; #define H_XWindowChanges "(XWindowChanges x y w h border sib stack_mode): new XWindowChanges struct" Xen_check_type(Xen_is_integer_or_unbound(x), x, 1, "XWindowChanges", "int"); Xen_check_type(Xen_is_integer_or_unbound(y), y, 2, "XWindowChanges", "int"); Xen_check_type(Xen_is_integer_or_unbound(width), width, 3, "XWindowChanges", "int"); Xen_check_type(Xen_is_integer_or_unbound(height), height, 4, "XWindowChanges", "int"); Xen_check_type(Xen_is_integer_or_unbound(border_width), border_width, 5, "XWindowChanges", "int"); Xen_check_type(Xen_is_Window(sibling) || !Xen_is_bound(sibling), sibling, 6, "XWindowChanges", "Window"); Xen_check_type(Xen_is_integer_or_unbound(stack_mode), stack_mode, 7, "XWindowChanges", "int"); r = (XWindowChanges *)calloc(1, sizeof(XWindowChanges)); if (Xen_is_bound(x)) r->x = Xen_integer_to_C_int(x); if (Xen_is_bound(y)) r->y = Xen_integer_to_C_int(y); if (Xen_is_bound(width)) r->width = Xen_integer_to_C_int(width); if (Xen_is_bound(height)) r->height = Xen_integer_to_C_int(height); if (Xen_is_bound(border_width)) r->border_width = Xen_integer_to_C_int(border_width); if (Xen_is_bound(sibling)) r->sibling = Xen_to_C_Window(sibling); if (Xen_is_bound(stack_mode)) r->stack_mode = Xen_integer_to_C_int(stack_mode); return(C_to_Xen_XWindowChanges(r)); } static Xen gxm_XSetWindowAttributes(Xen arglist) { int len; XSetWindowAttributes *r; #define H_XSetWindowAttributes "(XSetWindowAttributes args): new XSetWindowAttributes struct (14 or more args!)" r = (XSetWindowAttributes *)calloc(1, sizeof(XSetWindowAttributes)); len = Xen_list_length(arglist); if ((len > 0) && (Xen_is_Pixmap(Xen_list_ref(arglist, 0)))) r->background_pixmap = Xen_to_C_Pixmap(Xen_list_ref(arglist, 0)); if ((len > 1) && (Xen_is_Pixel(Xen_list_ref(arglist, 1)))) r->background_pixel = Xen_to_C_Pixel(Xen_list_ref(arglist, 1)); if ((len > 2) && (Xen_is_Pixmap(Xen_list_ref(arglist, 2)))) r->border_pixmap = Xen_to_C_Pixmap(Xen_list_ref(arglist, 2)); if ((len > 3) && (Xen_is_Pixel(Xen_list_ref(arglist, 3)))) r->border_pixel = Xen_to_C_Pixel(Xen_list_ref(arglist, 3)); if ((len > 4) && (Xen_is_integer(Xen_list_ref(arglist, 4)))) r->bit_gravity = Xen_integer_to_C_int(Xen_list_ref(arglist, 4)); if ((len > 5) && (Xen_is_integer(Xen_list_ref(arglist, 5)))) r->win_gravity = Xen_integer_to_C_int(Xen_list_ref(arglist, 5)); if ((len > 6) && (Xen_is_integer(Xen_list_ref(arglist, 6)))) r->backing_store = Xen_integer_to_C_int(Xen_list_ref(arglist, 6)); if ((len > 7) && (Xen_is_ulong(Xen_list_ref(arglist, 7)))) r->backing_planes = Xen_ulong_to_C_ulong(Xen_list_ref(arglist, 7)); if ((len > 8) && (Xen_is_Pixel(Xen_list_ref(arglist, 8)))) r->backing_pixel = Xen_to_C_Pixel(Xen_list_ref(arglist, 8)); if ((len > 9) && (Xen_is_boolean(Xen_list_ref(arglist, 9)))) r->save_under = Xen_boolean_to_C_bool(Xen_list_ref(arglist, 9)); if ((len > 10) && (Xen_is_integer(Xen_list_ref(arglist, 10)))) r->event_mask = Xen_integer_to_C_int(Xen_list_ref(arglist, 10)); if ((len > 11) && (Xen_is_integer(Xen_list_ref(arglist, 11)))) r->do_not_propagate_mask = Xen_integer_to_C_int(Xen_list_ref(arglist, 11)); if ((len > 12) && (Xen_is_boolean(Xen_list_ref(arglist, 12)))) r->override_redirect = Xen_boolean_to_C_bool(Xen_list_ref(arglist, 12)); if ((len > 13) && (Xen_is_Colormap(Xen_list_ref(arglist, 13)))) r->colormap = Xen_to_C_Colormap(Xen_list_ref(arglist, 13)); if ((len > 14) && (Xen_is_Cursor(Xen_list_ref(arglist, 14)))) r->cursor = Xen_to_C_Cursor(Xen_list_ref(arglist, 14)); return(C_to_Xen_XSetWindowAttributes(r)); } static Xen gxm_stack_mode(Xen ptr) { XM_field_assert_type(Xen_is_XWindowChanges(ptr), ptr, 1, "stack_mode", "XWindowChanges"); return(C_int_to_Xen_integer((int)((Xen_to_C_XWindowChanges(ptr))->stack_mode))); } static Xen gxm_sibling(Xen ptr) { XM_field_assert_type(Xen_is_XWindowChanges(ptr), ptr, 1, "sibling", "XWindowChanges"); return(C_to_Xen_Window((Window)((Xen_to_C_XWindowChanges(ptr))->sibling))); } static Xen gxm_obdata(Xen ptr) { XM_field_assert_type(Xen_is_XImage(ptr), ptr, 1, "obdata", "XImage"); return(Xen_wrap_C_pointer((XPointer)((Xen_to_C_XImage(ptr))->obdata))); } static Xen gxm_bytes_per_line(Xen ptr) { XM_field_assert_type(Xen_is_XImage(ptr), ptr, 1, "bytes_per_line", "XImage"); return(C_int_to_Xen_integer((int)((Xen_to_C_XImage(ptr))->bytes_per_line))); } static Xen gxm_bitmap_pad(Xen ptr) { XM_field_assert_type(Xen_is_XImage(ptr), ptr, 1, "bitmap_pad", "XImage"); return(C_int_to_Xen_integer((int)((Xen_to_C_XImage(ptr))->bitmap_pad))); } static Xen gxm_bitmap_bit_order(Xen ptr) { XM_field_assert_type(Xen_is_XImage(ptr), ptr, 1, "bitmap_bit_order", "XImage"); return(C_int_to_Xen_integer((int)((Xen_to_C_XImage(ptr))->bitmap_bit_order))); } static Xen gxm_bitmap_unit(Xen ptr) { XM_field_assert_type(Xen_is_XImage(ptr), ptr, 1, "bitmap_unit", "XImage"); return(C_int_to_Xen_integer((int)((Xen_to_C_XImage(ptr))->bitmap_unit))); } static Xen gxm_byte_order(Xen ptr) { if (Xen_is_XImage(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XImage(ptr))->byte_order))); XM_field_assert_type(0, ptr, 1, "byte_order", "XImage"); return(Xen_false); } static Xen gxm_xoffset(Xen ptr) { XM_field_assert_type(Xen_is_XImage(ptr), ptr, 1, "xoffset", "XImage"); return(C_int_to_Xen_integer((int)((Xen_to_C_XImage(ptr))->xoffset))); } static Xen gxm_screen(Xen ptr) { if (Xen_is_XWindowAttributes(ptr)) return(C_to_Xen_Screen((Screen *)((Xen_to_C_XWindowAttributes(ptr))->screen))); if (Xen_is_XmTopLevelEnterCallbackStruct(ptr)) return(C_to_Xen_Screen((Screen *)((Xen_to_C_XmTopLevelEnterCallbackStruct(ptr))->screen))); if (Xen_is_XmTopLevelLeaveCallbackStruct(ptr)) return(C_to_Xen_Screen((Screen *)((Xen_to_C_XmTopLevelLeaveCallbackStruct(ptr))->screen))); if (Xen_is_XVisualInfo(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XVisualInfo(ptr))->screen))); XM_field_assert_type(0, ptr, 1, "screen", "a struct with a screen field"); return(Xen_false); } static Xen gxm_your_event_mask(Xen ptr) { XM_field_assert_type(Xen_is_XWindowAttributes(ptr), ptr, 1, "your_event_mask", "XWindowAttributes"); return(C_int_to_Xen_integer((long)((Xen_to_C_XWindowAttributes(ptr))->your_event_mask))); } static Xen gxm_all_event_masks(Xen ptr) { XM_field_assert_type(Xen_is_XWindowAttributes(ptr), ptr, 1, "all_event_masks", "XWindowAttributes"); return(C_int_to_Xen_integer((long)((Xen_to_C_XWindowAttributes(ptr))->all_event_masks))); } static Xen gxm_map_state(Xen ptr) { XM_field_assert_type(Xen_is_XWindowAttributes(ptr), ptr, 1, "map_state", "XWindowAttributes"); return(C_int_to_Xen_integer((int)((Xen_to_C_XWindowAttributes(ptr))->map_state))); } static Xen gxm_map_installed(Xen ptr) { XM_field_assert_type(Xen_is_XWindowAttributes(ptr), ptr, 1, "map_installed", "XWindowAttributes"); return(C_bool_to_Xen_boolean((Bool)((Xen_to_C_XWindowAttributes(ptr))->map_installed))); } static Xen gxm_set_visual(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_Visual(val), val, 2, "visual", "Visual"); XM_set_field_assert_type(Xen_is_XpmAttributes(ptr), ptr, 1, "visual", "Visual"); (Xen_to_C_XpmAttributes(ptr))->visual = (Visual *)Xen_to_C_Visual(val); return(val); } static Xen gxm_visual(Xen ptr) { if (Xen_is_XWindowAttributes(ptr)) return(C_to_Xen_Visual((Visual *)((Xen_to_C_XWindowAttributes(ptr))->visual))); if (Xen_is_XpmAttributes(ptr)) return(C_to_Xen_Visual((Visual *)((Xen_to_C_XpmAttributes(ptr))->visual))); XM_field_assert_type(0, ptr, 1, "visual", "a struct with a visual field"); return(Xen_false); } static Xen gxm_cursor(Xen ptr) { if (Xen_is_XSetWindowAttributes(ptr)) return(C_to_Xen_Cursor((Cursor)((Xen_to_C_XSetWindowAttributes(ptr))->cursor))); XM_field_assert_type(0, ptr, 1, "cursor", "XSetWindowAttributes"); return(Xen_false); } static Xen gxm_set_cursor(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_XSetWindowAttributes(ptr), ptr, 1, "cursor", "XSetWindowAttributes"); XM_set_field_assert_type(Xen_is_Cursor(val), val, 2, "cursor", "a Cursor"); (Xen_to_C_XSetWindowAttributes(ptr))->cursor = Xen_to_C_Cursor(val); return(val); } static Xen gxm_do_not_propagate_mask(Xen ptr) { XM_field_assert_type(Xen_is_XWindowAttributes(ptr) || Xen_is_XSetWindowAttributes(ptr), ptr, 1, "do_not_propagate_mask", "a struct with a do_not_propagate_mask field"); if (Xen_is_XWindowAttributes(ptr)) return(C_int_to_Xen_integer((long)((Xen_to_C_XWindowAttributes(ptr))->do_not_propagate_mask))); return(C_int_to_Xen_integer((long)((Xen_to_C_XSetWindowAttributes(ptr))->do_not_propagate_mask))); } static Xen gxm_event_mask(Xen ptr) { if (Xen_is_XSetWindowAttributes(ptr)) return(C_int_to_Xen_integer((long)((Xen_to_C_XSetWindowAttributes(ptr))->event_mask))); XM_field_assert_type(0, ptr, 1, "event_mask", "XSetWindowAttributes"); return(Xen_false); } static Xen gxm_set_event_mask(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_XSetWindowAttributes(ptr), ptr, 1, "event_mask", "XSetWindowAttributes"); XM_set_field_assert_type(Xen_is_integer(val), val, 2, "event_mask", "an integer"); (Xen_to_C_XSetWindowAttributes(ptr))->event_mask = Xen_integer_to_C_int(val); return(val); } static Xen gxm_save_under(Xen ptr) { XM_field_assert_type(Xen_is_XWindowAttributes(ptr) || Xen_is_XSetWindowAttributes(ptr), ptr, 1, "save_under", "a struct with a save_under field"); if (Xen_is_XWindowAttributes(ptr)) return(C_bool_to_Xen_boolean((Bool)((Xen_to_C_XWindowAttributes(ptr))->save_under))); return(C_bool_to_Xen_boolean((Bool)((Xen_to_C_XSetWindowAttributes(ptr))->save_under))); } static Xen gxm_set_save_under(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_XWindowAttributes(ptr) || Xen_is_XSetWindowAttributes(ptr), ptr, 1, "save_under", "a struct with a save_under field"); XM_set_field_assert_type(Xen_is_boolean(val), val, 2, "save_under", "a Boolean"); if (Xen_is_XWindowAttributes(ptr)) (Xen_to_C_XWindowAttributes(ptr))->save_under = Xen_boolean_to_C_bool(val); else (Xen_to_C_XSetWindowAttributes(ptr))->save_under = Xen_boolean_to_C_bool(val); return(val); } static Xen gxm_backing_pixel(Xen ptr) { XM_field_assert_type(Xen_is_XWindowAttributes(ptr) || Xen_is_XSetWindowAttributes(ptr), ptr, 1, "backing_pixel", "a struct with a backing_pixel field"); if (Xen_is_XWindowAttributes(ptr)) return(C_to_Xen_Pixel((unsigned long)((Xen_to_C_XWindowAttributes(ptr))->backing_pixel))); return(C_to_Xen_Pixel((unsigned long)((Xen_to_C_XSetWindowAttributes(ptr))->backing_pixel))); } static Xen gxm_backing_planes(Xen ptr) { XM_field_assert_type(Xen_is_XWindowAttributes(ptr) || Xen_is_XSetWindowAttributes(ptr), ptr, 1, "backing_planes", "a struct with a backing_planes field"); if (Xen_is_XWindowAttributes(ptr)) return(C_ulong_to_Xen_ulong((unsigned long)((Xen_to_C_XWindowAttributes(ptr))->backing_planes))); return(C_ulong_to_Xen_ulong((unsigned long)((Xen_to_C_XSetWindowAttributes(ptr))->backing_planes))); } static Xen gxm_win_gravity(Xen ptr) { if (Xen_is_XWindowAttributes(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XWindowAttributes(ptr))->win_gravity))); if (Xen_is_XWindowAttributes(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XSetWindowAttributes(ptr))->win_gravity))); XM_field_assert_type(0, ptr, 1, "win_gravity", "a struct with a win_gravity field"); return(Xen_false); } static Xen gxm_bit_gravity(Xen ptr) { XM_field_assert_type(Xen_is_XWindowAttributes(ptr) || Xen_is_XSetWindowAttributes(ptr), ptr, 1, "bit_gravity", "a struct with a bit_gravity field"); if (Xen_is_XWindowAttributes(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XWindowAttributes(ptr))->bit_gravity))); return(C_int_to_Xen_integer((int)((Xen_to_C_XSetWindowAttributes(ptr))->bit_gravity))); } static Xen gxm_set_bit_gravity(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_XWindowAttributes(ptr) || Xen_is_XSetWindowAttributes(ptr), ptr, 1, "bit_gravity", "a struct with a bit_gravity field"); XM_set_field_assert_type(Xen_is_integer(val), val, 2, "bit_gravity", "an integer"); if (Xen_is_XWindowAttributes(ptr)) (Xen_to_C_XWindowAttributes(ptr))->bit_gravity = Xen_integer_to_C_int(val); else (Xen_to_C_XSetWindowAttributes(ptr))->bit_gravity = Xen_integer_to_C_int(val); return(val); } static Xen gxm_border_pixel(Xen ptr) { XM_field_assert_type(Xen_is_XSetWindowAttributes(ptr), ptr, 1, "border_pixel", "XSetWindowAttributes"); return(C_to_Xen_Pixel((unsigned long)((Xen_to_C_XSetWindowAttributes(ptr))->border_pixel))); } static Xen gxm_set_border_pixel(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_XSetWindowAttributes(ptr), ptr, 1, "border_pixel", "XSetWindowAttributes"); XM_set_field_assert_type(Xen_is_Pixel(val), val, 2, "border_pixel", "a Pixel"); (Xen_to_C_XSetWindowAttributes(ptr))->border_pixel = Xen_to_C_Pixel(val); return(val); } static Xen gxm_border_pixmap(Xen ptr) { XM_field_assert_type(Xen_is_XSetWindowAttributes(ptr), ptr, 1, "border_pixmap", "XSetWindowAttributes"); return(C_to_Xen_Pixmap((Pixmap)((Xen_to_C_XSetWindowAttributes(ptr))->border_pixmap))); } static Xen gxm_background_pixel(Xen ptr) { XM_field_assert_type(Xen_is_XSetWindowAttributes(ptr), ptr, 1, "background_pixel", "XSetWindowAttributes"); return(C_to_Xen_Pixel((unsigned long)((Xen_to_C_XSetWindowAttributes(ptr))->background_pixel))); } static Xen gxm_set_background_pixel(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_XSetWindowAttributes(ptr), ptr, 1, "background_pixel", "XSetWindowAttributes"); XM_set_field_assert_type(Xen_is_Pixel(val), val, 2, "background_pixel", "a Pixel"); (Xen_to_C_XSetWindowAttributes(ptr))->background_pixel = Xen_to_C_Pixel(val); return(val); } static Xen gxm_background_pixmap(Xen ptr) { XM_field_assert_type(Xen_is_XSetWindowAttributes(ptr), ptr, 1, "background_pixmap", "XSetWindowAttributes"); return(C_to_Xen_Pixmap((Pixmap)((Xen_to_C_XSetWindowAttributes(ptr))->background_pixmap))); } static Xen gxm_bits_per_pixel(Xen ptr) { if (Xen_is_XImage(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XImage(ptr))->bits_per_pixel))); XM_field_assert_type(0, ptr, 1, "bits_per_pixel", "XImage"); return(Xen_false); } static Xen gxm_visuals(Xen ptr) { Depth *dps; int len; Xen lst = Xen_empty_list; XM_field_assert_type(Xen_is_Depth(ptr), ptr, 1, "visuals", "Depth"); dps = Xen_to_C_Depth(ptr); len = dps->nvisuals; if (len > 0) { int i; Visual *vs; vs = dps->visuals; for (i = len - 1; i >= 0; i--) lst = Xen_cons(wrap_for_Xen("Visual", &(vs[i])), lst); } return(lst); } static Xen gxm_nvisuals(Xen ptr) { XM_field_assert_type(Xen_is_Depth(ptr), ptr, 1, "nvisuals", "Depth"); return(C_int_to_Xen_integer((int)((Xen_to_C_Depth(ptr))->nvisuals))); } static Xen gxm_set_depth(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_XpmAttributes(ptr), ptr, 1, "depth", "XpmAttributes"); (Xen_to_C_XpmAttributes(ptr))->depth = Xen_ulong_to_C_ulong(val); return(val); } static Xen gxm_depth(Xen ptr) { if (Xen_is_XImage(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XImage(ptr))->depth))); if (Xen_is_XWindowAttributes(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XWindowAttributes(ptr))->depth))); if (Xen_is_Depth(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_Depth(ptr))->depth))); if (Xen_is_XVisualInfo(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XVisualInfo(ptr))->depth))); if (Xen_is_XpmAttributes(ptr)) return(C_ulong_to_Xen_ulong((unsigned long)((Xen_to_C_XpmAttributes(ptr))->depth))); XM_field_assert_type(0, ptr, 1, "depth", "a struct with a depth field"); return(Xen_false); } static Xen gxm_map_entries(Xen ptr) { XM_field_assert_type(Xen_is_Visual(ptr), ptr, 1, "map_entries", "Visual"); return(C_int_to_Xen_integer((int)((Xen_to_C_Visual(ptr))->map_entries))); } static Xen gxm_bits_per_rgb(Xen ptr) { if (Xen_is_XVisualInfo(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XVisualInfo(ptr))->bits_per_rgb))); if (Xen_is_Visual(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_Visual(ptr))->bits_per_rgb))); XM_field_assert_type(0, ptr, 1, "bits_per_rgb", "Visual or XVisualInfo"); return(Xen_false); } static Xen gxm_blue_mask(Xen ptr) { if (Xen_is_XImage(ptr)) return(C_ulong_to_Xen_ulong((unsigned long)((Xen_to_C_XImage(ptr))->blue_mask))); if (Xen_is_XVisualInfo(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XVisualInfo(ptr))->blue_mask))); if (Xen_is_Visual(ptr)) return(C_int_to_Xen_integer((long)((Xen_to_C_Visual(ptr))->blue_mask))); XM_field_assert_type(0, ptr, 1, "blue_mask", "a struct with a blue_mask field"); return(Xen_false); } static Xen gxm_green_mask(Xen ptr) { if (Xen_is_XImage(ptr)) return(C_ulong_to_Xen_ulong((unsigned long)((Xen_to_C_XImage(ptr))->green_mask))); if (Xen_is_XVisualInfo(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XVisualInfo(ptr))->green_mask))); if (Xen_is_Visual(ptr)) return(C_int_to_Xen_integer((long)((Xen_to_C_Visual(ptr))->green_mask))); XM_field_assert_type(0, ptr, 1, "green_mask", "a struct with a green_mask field"); return(Xen_false); } static Xen gxm_red_mask(Xen ptr) { if (Xen_is_XImage(ptr)) return(C_ulong_to_Xen_ulong((unsigned long)((Xen_to_C_XImage(ptr))->red_mask))); if (Xen_is_XVisualInfo(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XVisualInfo(ptr))->red_mask))); if (Xen_is_Visual(ptr)) return(C_ulong_to_Xen_ulong((unsigned long)((Xen_to_C_Visual(ptr))->red_mask))); XM_field_assert_type(0, ptr, 1, "red_mask", "a struct with a red_mask field"); return(Xen_false); } static Xen gxm_colormap_size(Xen ptr) { if (Xen_is_XVisualInfo(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XVisualInfo(ptr))->colormap_size))); XM_field_assert_type(0, ptr, 1, "colormap_size", "XVisualInfo*"); return(Xen_false); } static Xen gxm_class(Xen ptr) { #ifndef __cplusplus if (Xen_is_XWindowAttributes(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XWindowAttributes(ptr))->class))); if (Xen_is_Visual(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_Visual(ptr))->class))); if (Xen_is_XVisualInfo(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XVisualInfo(ptr))->class))); XM_field_assert_type(0, ptr, 1, "class", "a struct with a class field"); #endif return(Xen_false); } static Xen gxm_visualid(Xen ptr) { if (Xen_is_Visual(ptr)) return(C_ulong_to_Xen_ulong((VisualID)((Xen_to_C_Visual(ptr))->visualid))); if (Xen_is_XStandardColormap(ptr)) return(C_ulong_to_Xen_ulong((VisualID)((Xen_to_C_XStandardColormap(ptr))->visualid))); if (Xen_is_XVisualInfo(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XVisualInfo(ptr))->visualid))); XM_field_assert_type(0, ptr, 1, "visualid", "a struct with a visualid field"); return(Xen_false); } static Xen gxm_set_pixel(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_Pixel(val), val, 2, "pixel", "a Pixel"); if (Xen_is_XColor(ptr)) (Xen_to_C_XColor(ptr))->pixel = Xen_to_C_Pixel(val); else if (Xen_is_XpmColorSymbol(ptr)) (Xen_to_C_XpmColorSymbol(ptr))->pixel = Xen_to_C_Pixel(val); return(val); } static Xen gxm_pixel(Xen ptr) { if (Xen_is_XColor(ptr)) return(C_to_Xen_Pixel((Pixel)((Xen_to_C_XColor(ptr))->pixel))); if (Xen_is_XmScrollBarCallbackStruct(ptr)) return(C_to_Xen_Pixel((Pixel)((Xen_to_C_XmScrollBarCallbackStruct(ptr))->pixel))); if (Xen_is_XpmColorSymbol(ptr)) return(C_to_Xen_Pixel((Pixel)((Xen_to_C_XpmColorSymbol(ptr))->pixel))); XM_field_assert_type(0, ptr, 1, "pixel", "a struct with a pixel field"); return(Xen_false); } static Xen gxm_window_group(Xen ptr) { XM_field_assert_type(Xen_is_XWMHints(ptr), ptr, 1, "window_group", "XWMHints"); return(C_ulong_to_Xen_ulong((XID)((Xen_to_C_XWMHints(ptr))->window_group))); } static Xen gxm_icon_mask(Xen ptr) { XM_field_assert_type(Xen_is_XWMHints(ptr), ptr, 1, "icon_mask", "XWMHints"); return(C_to_Xen_Pixmap((Pixmap)((Xen_to_C_XWMHints(ptr))->icon_mask))); } static Xen gxm_icon_y(Xen ptr) { XM_field_assert_type(Xen_is_XWMHints(ptr), ptr, 1, "icon_y", "XWMHints"); return(C_int_to_Xen_integer((int)((Xen_to_C_XWMHints(ptr))->icon_y))); } static Xen gxm_icon_x(Xen ptr) { XM_field_assert_type(Xen_is_XWMHints(ptr), ptr, 1, "icon_x", "XWMHints"); return(C_int_to_Xen_integer((int)((Xen_to_C_XWMHints(ptr))->icon_x))); } static Xen gxm_icon_window(Xen ptr) { XM_field_assert_type(Xen_is_XWMHints(ptr), ptr, 1, "icon_window", "XWMHints"); return(C_to_Xen_Window((Window)((Xen_to_C_XWMHints(ptr))->icon_window))); } static Xen gxm_icon_pixmap(Xen ptr) { XM_field_assert_type(Xen_is_XWMHints(ptr), ptr, 1, "icon_pixmap", "XWMHints"); return(C_to_Xen_Pixmap((Pixmap)((Xen_to_C_XWMHints(ptr))->icon_pixmap))); } static Xen gxm_initial_state(Xen ptr) { XM_field_assert_type(Xen_is_XWMHints(ptr), ptr, 1, "initial_state", "XWMHints"); return(C_int_to_Xen_integer((int)((Xen_to_C_XWMHints(ptr))->initial_state))); } static Xen gxm_set_initial_state(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_XWMHints(ptr), ptr, 1, "initial_state", "XWMHints"); XM_set_field_assert_type(Xen_is_integer(val), val, 2, "initial_state", "an integer"); (Xen_to_C_XWMHints(ptr))->initial_state = Xen_integer_to_C_int(val); return(val); } static Xen gxm_input(Xen ptr) { XM_field_assert_type(Xen_is_XWMHints(ptr), ptr, 1, "input", "XWMHints"); return(C_bool_to_Xen_boolean((Bool)((Xen_to_C_XWMHints(ptr))->input))); } static Xen gxm_set_input(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_XWMHints(ptr), ptr, 1, "input", "XWMHints"); XM_set_field_assert_type(Xen_is_boolean(val), val, 2, "input", "a boolean"); (Xen_to_C_XWMHints(ptr))->input = Xen_boolean_to_C_bool(val); return(val); } static Xen gxm_flags(Xen ptr) { if (Xen_is_XColor(ptr)) return(C_int_to_Xen_integer((char)((Xen_to_C_XColor(ptr))->flags))); if (Xen_is_XmSelectionCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmSelectionCallbackStruct(ptr))->flags))); if (Xen_is_XmDestinationCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmDestinationCallbackStruct(ptr))->flags))); if (Xen_is_XmConvertCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmConvertCallbackStruct(ptr))->flags))); if (Xen_is_XWMHints(ptr)) return(C_int_to_Xen_integer((long)((Xen_to_C_XWMHints(ptr))->flags))); XM_field_assert_type(0, ptr, 1, "flags", "a struct with a flags field"); return(Xen_false); } static Xen gxm_set_flags(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_XColor(ptr) || Xen_is_XWMHints(ptr), ptr, 1, "flags", "XColor or XWMHints"); XM_set_field_assert_type(Xen_is_integer(val), val, 2, "input", "a char (int)"); if (Xen_is_XColor(ptr)) (Xen_to_C_XColor(ptr))->flags = (char)Xen_integer_to_C_int(val); else if (Xen_is_XWMHints(ptr)) (Xen_to_C_XWMHints(ptr))->flags = (char)Xen_integer_to_C_int(val); return(val); } static Xen gxm_per_char(Xen ptr) { XM_field_assert_type(Xen_is_XFontStruct(ptr), ptr, 1, "per_char", "XFontStruct"); return(C_to_Xen_XCharStruct((XCharStruct *)((Xen_to_C_XFontStruct(ptr))->per_char))); } static Xen gxm_max_bounds(Xen ptr) { XM_field_assert_type(Xen_is_XFontStruct(ptr), ptr, 1, "max_bounds", "XFontStruct"); return(C_to_Xen_XCharStruct((XCharStruct *)(&(Xen_to_C_XFontStruct(ptr))->max_bounds))); } static Xen gxm_min_bounds(Xen ptr) { XM_field_assert_type(Xen_is_XFontStruct(ptr), ptr, 1, "min_bounds", "XFontStruct"); return(C_to_Xen_XCharStruct((XCharStruct *)(&(Xen_to_C_XFontStruct(ptr))->min_bounds))); } static Xen gxm_min_height(Xen ptr) { if (Xen_is_XIconSize(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XIconSize(ptr))->min_height))); XM_field_assert_type(0, ptr, 1, "min_height", "XIconSize"); return(Xen_false); } static Xen gxm_min_width(Xen ptr) { if (Xen_is_XIconSize(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XIconSize(ptr))->min_width))); XM_field_assert_type(0, ptr, 1, "min_width", "XIconSize"); return(Xen_false); } static Xen gxm_max_height(Xen ptr) { if (Xen_is_XIconSize(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XIconSize(ptr))->max_height))); XM_field_assert_type(0, ptr, 1, "max_height", "XIconSize"); return(Xen_false); } static Xen gxm_max_width(Xen ptr) { if (Xen_is_XIconSize(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XIconSize(ptr))->max_width))); XM_field_assert_type(0, ptr, 1, "max_width", "XIconSize"); return(Xen_false); } static Xen gxm_height_inc(Xen ptr) { if (Xen_is_XIconSize(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XIconSize(ptr))->height_inc))); XM_field_assert_type(0, ptr, 1, "height_inc", "XIconSize"); return(Xen_false); } static Xen gxm_width_inc(Xen ptr) { if (Xen_is_XIconSize(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XIconSize(ptr))->width_inc))); XM_field_assert_type(0, ptr, 1, "width_inc", "XIconSize"); return(Xen_false); } static Xen gxm_properties(Xen ptr) { int i, len; XFontStruct *fs; XFontProp *props; Xen lst = Xen_empty_list; XM_field_assert_type(Xen_is_XFontStruct(ptr), ptr, 1, "properties", "XFontStruct"); fs = Xen_to_C_XFontStruct(ptr); len = fs->n_properties; props = fs->properties; for (i = 0; i < len; i++) lst = Xen_cons(C_to_Xen_XFontProp(&(props[i])), lst); return(lst); } static Xen gxm_fid(Xen ptr) { XM_field_assert_type(Xen_is_XFontStruct(ptr), ptr, 1, "fid", "XFontStruct"); return(C_to_Xen_Font((Font)((Xen_to_C_XFontStruct(ptr))->fid))); } static Xen gxm_card32(Xen ptr) { XM_field_assert_type(Xen_is_XFontProp(ptr), ptr, 1, "card32", "XFontProp"); return(C_ulong_to_Xen_ulong((unsigned long)((Xen_to_C_XFontProp(ptr))->card32))); } static Xen gxm_set_name(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_string(val), val, 2, "name", "a string"); XM_set_field_assert_type(Xen_is_XpmColorSymbol(ptr), ptr, 1, "name", "XpmColorSymbol"); (Xen_to_C_XpmColorSymbol(ptr))->name = xen_strdup(Xen_string_to_C_string(val)); return(val); } static Xen gxm_name(Xen ptr) { if (Xen_is_XFontProp(ptr)) return(C_to_Xen_Atom((Atom)((Xen_to_C_XFontProp(ptr))->name))); if (Xen_is_XpmColorSymbol(ptr)) return(C_string_to_Xen_string((char *)((Xen_to_C_XpmColorSymbol(ptr))->name))); XM_field_assert_type(0, ptr, 1, "name", "a struct with a name field"); return(Xen_false); } static Xen gxm_attributes(Xen ptr) { XM_field_assert_type(Xen_is_XCharStruct(ptr), ptr, 1, "attributes", "XCharStruct"); return(C_int_to_Xen_integer((int)((Xen_to_C_XCharStruct(ptr))->attributes))); } static Xen gxm_descent(Xen ptr) { if (Xen_is_XFontStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XFontStruct(ptr))->descent))); if (Xen_is_XCharStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XCharStruct(ptr))->descent))); XM_field_assert_type(0, ptr, 1, "descent", "a struct with a descent field"); return(Xen_false); } static Xen gxm_ascent(Xen ptr) { if (Xen_is_XFontStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XFontStruct(ptr))->ascent))); if (Xen_is_XCharStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XCharStruct(ptr))->ascent))); XM_field_assert_type(0, ptr, 1, "ascent", "a struct with an ascent field"); return(Xen_false); } static Xen gxm_rbearing(Xen ptr) { XM_field_assert_type(Xen_is_XCharStruct(ptr), ptr, 1, "rbearing", "XCharStruct"); return(C_int_to_Xen_integer((int)((Xen_to_C_XCharStruct(ptr))->rbearing))); } static Xen gxm_lbearing(Xen ptr) { XM_field_assert_type(Xen_is_XCharStruct(ptr), ptr, 1, "lbearing", "XCharStruct"); return(C_int_to_Xen_integer((int)((Xen_to_C_XCharStruct(ptr))->lbearing))); } static Xen gxm_request_code(Xen ptr) { XM_field_assert_type(Xen_is_XErrorEvent(ptr), ptr, 1, "request_code", "XErrorEvent"); return(C_int_to_Xen_integer((int)((Xen_to_C_XErrorEvent(ptr))->request_code))); } static Xen gxm_set_request_code(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_integer(val), val, 2, "request_code", "an integer"); XM_set_field_assert_type(Xen_is_XErrorEvent(ptr), ptr, 1, "request_code", "XErrorEvent"); (Xen_to_C_XErrorEvent(ptr))->request_code = Xen_integer_to_C_int(val); return(val); } static Xen gxm_error_code(Xen ptr) { XM_field_assert_type(Xen_is_XErrorEvent(ptr), ptr, 1, "error_code", "XErrorEvent"); return(C_int_to_Xen_integer((int)((Xen_to_C_XErrorEvent(ptr))->error_code))); } static Xen gxm_set_error_code(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_integer(val), val, 2, "error_code", "an integer"); XM_set_field_assert_type(Xen_is_XErrorEvent(ptr), ptr, 1, "error_code", "XErrorEvent"); (Xen_to_C_XErrorEvent(ptr))->error_code = Xen_integer_to_C_int(val); return(val); } static Xen gxm_resourceid(Xen ptr) { XM_field_assert_type(Xen_is_XErrorEvent(ptr), ptr, 1, "resourceid", "XErrorEvent"); return(C_ulong_to_Xen_ulong((XID)((Xen_to_C_XErrorEvent(ptr))->resourceid))); } static Xen gxm_set_resourceid(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_ulong(val), val, 2, "resourceid", "an XID"); XM_set_field_assert_type(Xen_is_XErrorEvent(ptr), ptr, 1, "resourceid", "XErrorEvent"); (Xen_to_C_XErrorEvent(ptr))->resourceid = (XID)Xen_ulong_to_C_ulong(val); return(val); } static Xen gxm_first_keycode(Xen ptr) { XM_field_assert_type(Xen_is_XMappingEvent(ptr), ptr, 1, "first_keycode", "XMappingEvent"); return(C_int_to_Xen_integer((int)((Xen_to_C_XMappingEvent(ptr))->first_keycode))); } static Xen gxm_set_first_keycode(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_integer(val), val, 2, "first_keycode", "an integer"); XM_set_field_assert_type(Xen_is_XMappingEvent(ptr), ptr, 1, "first_keycode", "XMappingEvent"); (Xen_to_C_XMappingEvent(ptr))->first_keycode = Xen_integer_to_C_int(val); return(val); } static Xen gxm_request(Xen ptr) { XM_field_assert_type(Xen_is_XMappingEvent(ptr), ptr, 1, "request", "XMappingEvent"); return(C_int_to_Xen_integer((int)((Xen_to_C_XMappingEvent(ptr))->request))); } static Xen gxm_set_request(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_integer(val), val, 2, "request", "an integer"); XM_set_field_assert_type(Xen_is_XMappingEvent(ptr), ptr, 1, "request", "XMappingEvent"); (Xen_to_C_XMappingEvent(ptr))->request = Xen_integer_to_C_int(val); return(val); } static Xen gxm_format(Xen ptr) { if (Xen_is_XImage(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XImage(ptr))->format))); if (Xen_is_XmSelectionCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmSelectionCallbackStruct(ptr))->format))); if (Xen_is_XmConvertCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmConvertCallbackStruct(ptr))->format))); if (Xen_is_XmTextBlock(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmTextBlock(ptr))->format))); if (Xen_is_XClientMessageEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XClientMessageEvent(ptr))->format))); XM_field_assert_type(0, ptr, 1, "format", "XClientMessageEvent"); return(Xen_false); } static Xen gxm_set_format(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_integer(val), val, 2, "format", "an integer"); if (Xen_is_XClientMessageEvent(ptr)) (Xen_to_C_XClientMessageEvent(ptr))->format = Xen_integer_to_C_int(val); else if (Xen_is_XmTextBlock(ptr)) (Xen_to_C_XmTextBlock(ptr))->format = Xen_integer_to_C_int(val); else XM_set_field_assert_type(0, ptr, 1, "format", "XClientMessageEvent or XmTextBlock"); return(val); } static Xen gxm_message_type(Xen ptr) { XM_field_assert_type(Xen_is_XClientMessageEvent(ptr), ptr, 1, "message_type", "XClientMessageEvent"); return(C_to_Xen_Atom((Atom)((Xen_to_C_XClientMessageEvent(ptr))->message_type))); } static Xen gxm_set_message_type(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_Atom(val), val, 2, "message_type", "an Atom"); XM_set_field_assert_type(Xen_is_XClientMessageEvent(ptr), ptr, 1, "message_type", "XClientMessageEvent"); (Xen_to_C_XClientMessageEvent(ptr))->message_type = Xen_to_C_Atom(val); return(val); } static Xen gxm_new(Xen ptr) { #ifndef __cplusplus XM_field_assert_type(Xen_is_XColormapEvent(ptr), ptr, 1, "new", "XColormapEvent"); return(C_bool_to_Xen_boolean((Bool)((Xen_to_C_XColormapEvent(ptr))->new))); #endif return(Xen_false); } static Xen gxm_set_new(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_boolean(val), val, 2, "new", "a boolean"); #ifndef __cplusplus if (Xen_is_XColormapEvent(ptr)) (Xen_to_C_XColormapEvent(ptr))->new = Xen_boolean_to_C_bool(val); else XM_set_field_assert_type(0, ptr, 1, "new", "XColormapEvent"); #endif return(val); } static Xen gxm_colormap(Xen ptr) { if (Xen_is_XWindowAttributes(ptr)) return(C_to_Xen_Colormap((Colormap)((Xen_to_C_XWindowAttributes(ptr))->colormap))); if (Xen_is_XSetWindowAttributes(ptr)) return(C_to_Xen_Colormap((Colormap)((Xen_to_C_XSetWindowAttributes(ptr))->colormap))); if (Xen_is_XColormapEvent(ptr)) return(C_to_Xen_Colormap((Colormap)((Xen_to_C_XColormapEvent(ptr))->colormap))); if (Xen_is_XStandardColormap(ptr)) return(C_to_Xen_Colormap((Colormap)((Xen_to_C_XStandardColormap(ptr))->colormap))); if (Xen_is_XpmAttributes(ptr)) return(C_to_Xen_Colormap((Colormap)((Xen_to_C_XpmAttributes(ptr))->colormap))); XM_field_assert_type(0, ptr, 1, "colormap", "a struct with a colormap field"); return(Xen_false); } static Xen gxm_set_colormap(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_Colormap(val), val, 2, "colormap", "a Colormap"); if (Xen_is_XpmAttributes(ptr)) (Xen_to_C_XpmAttributes(ptr))->colormap = Xen_to_C_Colormap(val); else { if (Xen_is_XColormapEvent(ptr)) (Xen_to_C_XColormapEvent(ptr))->colormap = Xen_to_C_Colormap(val); else XM_set_field_assert_type(0, ptr, 1, "colormap", "XpmAttributes or XColormapEvent"); } return(val); } static Xen gxm_property(Xen ptr) { if (Xen_is_XSelectionEvent(ptr)) return(C_to_Xen_Atom((Atom)((Xen_to_C_XSelectionEvent(ptr))->property))); if (Xen_is_XSelectionRequestEvent(ptr)) return(C_to_Xen_Atom((Atom)((Xen_to_C_XSelectionRequestEvent(ptr))->property))); XM_field_assert_type(0, ptr, 1, "property", "a struct with a property field"); return(Xen_false); } static Xen gxm_set_property(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_Atom(val), val, 2, "property", "an Atom"); if (Xen_is_XSelectionEvent(ptr)) (Xen_to_C_XSelectionEvent(ptr))->property = Xen_to_C_Atom(val); else if (Xen_is_XSelectionRequestEvent(ptr)) (Xen_to_C_XSelectionRequestEvent(ptr))->property = Xen_to_C_Atom(val); else XM_set_field_assert_type(0, ptr, 1, "property", "XSelection(Request)Event"); return(val); } static Xen gxm_target(Xen ptr) { if (Xen_is_XmPopupHandlerCallbackStruct(ptr)) return(C_to_Xen_Widget((Widget)((Xen_to_C_XmPopupHandlerCallbackStruct(ptr))->target))); if (Xen_is_XmSelectionCallbackStruct(ptr)) return(C_to_Xen_Atom((Atom)((Xen_to_C_XmSelectionCallbackStruct(ptr))->target))); if (Xen_is_XmConvertCallbackStruct(ptr)) return(C_to_Xen_Atom((Atom)((Xen_to_C_XmConvertCallbackStruct(ptr))->target))); if (Xen_is_XSelectionEvent(ptr)) return(C_to_Xen_Atom((Atom)((Xen_to_C_XSelectionEvent(ptr))->target))); if (Xen_is_XSelectionRequestEvent(ptr)) return(C_to_Xen_Atom((Atom)((Xen_to_C_XSelectionRequestEvent(ptr))->target))); XM_field_assert_type(0, ptr, 1, "target", "a struct with a target field"); return(Xen_false); } static Xen gxm_set_target(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_Atom(val), val, 2, "target", "an Atom"); if (Xen_is_XSelectionEvent(ptr)) (Xen_to_C_XSelectionEvent(ptr))->target = Xen_to_C_Atom(val); else if (Xen_is_XSelectionRequestEvent(ptr)) (Xen_to_C_XSelectionRequestEvent(ptr))->target = Xen_to_C_Atom(val); else XM_set_field_assert_type(0, ptr, 1, "target", "XSelection(Request)Event"); return(val); } static Xen gxm_requestor(Xen ptr) { if (Xen_is_XSelectionEvent(ptr)) return(C_to_Xen_Window((Window)((Xen_to_C_XSelectionEvent(ptr))->requestor))); if (Xen_is_XSelectionRequestEvent(ptr)) return(C_to_Xen_Window((Window)((Xen_to_C_XSelectionRequestEvent(ptr))->requestor))); XM_field_assert_type(0, ptr, 1, "requestor", "a struct with a requestor field"); return(Xen_false); } static Xen gxm_set_requestor(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_Window(val), val, 2, "requestor", "a Window"); if (Xen_is_XSelectionEvent(ptr)) (Xen_to_C_XSelectionEvent(ptr))->requestor = Xen_to_C_Window(val); else if (Xen_is_XSelectionRequestEvent(ptr)) (Xen_to_C_XSelectionRequestEvent(ptr))->requestor = Xen_to_C_Window(val); else XM_set_field_assert_type(0, ptr, 1, "requestor", "XSelection(Request)Event"); return(val); } static Xen gxm_owner(Xen ptr) { XM_field_assert_type(Xen_is_XSelectionRequestEvent(ptr), ptr, 1, "owner", "XSelectionRequestEvent"); return(C_to_Xen_Window((Window)((Xen_to_C_XSelectionRequestEvent(ptr))->owner))); } static Xen gxm_set_owner(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_Window(val), val, 2, "owner", "a Window"); XM_set_field_assert_type(Xen_is_XSelectionRequestEvent(ptr), ptr, 1, "owner", "XSelectionRequestEvent"); (Xen_to_C_XSelectionRequestEvent(ptr))->owner = Xen_to_C_Window(val); return(val); } static Xen gxm_selection(Xen ptr) { if (Xen_is_XmTransferDoneCallbackStruct(ptr)) return(C_to_Xen_Atom((Atom)((Xen_to_C_XmTransferDoneCallbackStruct(ptr))->selection))); if (Xen_is_XmSelectionCallbackStruct(ptr)) return(C_to_Xen_Atom((Atom)((Xen_to_C_XmSelectionCallbackStruct(ptr))->selection))); if (Xen_is_XmDestinationCallbackStruct(ptr)) return(C_to_Xen_Atom((Atom)((Xen_to_C_XmDestinationCallbackStruct(ptr))->selection))); if (Xen_is_XmConvertCallbackStruct(ptr)) return(C_to_Xen_Atom((Atom)((Xen_to_C_XmConvertCallbackStruct(ptr))->selection))); if (Xen_is_XSelectionEvent(ptr)) return(C_to_Xen_Atom((Atom)((Xen_to_C_XSelectionEvent(ptr))->selection))); if (Xen_is_XSelectionRequestEvent(ptr)) return(C_to_Xen_Atom((Atom)((Xen_to_C_XSelectionRequestEvent(ptr))->selection))); if (Xen_is_XSelectionClearEvent(ptr)) return(C_to_Xen_Atom((Atom)((Xen_to_C_XSelectionClearEvent(ptr))->selection))); XM_field_assert_type(0, ptr, 1, "selection", "a struct with a selection field"); return(Xen_false); } static Xen gxm_set_selection(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_Atom(val), val, 2, "selection", "an Atom"); if (Xen_is_XSelectionEvent(ptr)) (Xen_to_C_XSelectionEvent(ptr))->selection = Xen_to_C_Atom(val); else if (Xen_is_XSelectionRequestEvent(ptr)) (Xen_to_C_XSelectionRequestEvent(ptr))->selection = Xen_to_C_Atom(val); else if (Xen_is_XSelectionClearEvent(ptr)) (Xen_to_C_XSelectionClearEvent(ptr))->selection = Xen_to_C_Atom(val); else XM_set_field_assert_type(0, ptr, 1, "selection", "XSelection(Request|Clear)Event"); return(val); } static Xen gxm_atom(Xen ptr) { if (Xen_is_XPropertyEvent(ptr)) return(C_to_Xen_Atom((Atom)((Xen_to_C_XPropertyEvent(ptr))->atom))); XM_field_assert_type(0, ptr, 1, "atom", "XPropertyEvent"); return(Xen_false); } static Xen gxm_set_atom(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_Atom(val), val, 2, "atom", "an Atom"); XM_set_field_assert_type(Xen_is_XPropertyEvent(ptr), ptr, 1, "atom", "XPropertyEvent"); (Xen_to_C_XPropertyEvent(ptr))->atom = Xen_to_C_Atom(val); return(val); } static Xen gxm_place(Xen ptr) { XM_field_assert_type(Xen_is_XCirculateRequestEvent(ptr) || Xen_is_XCirculateEvent(ptr), ptr, 1, "place", "a struct with a place field"); if (Xen_is_XCirculateRequestEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XCirculateRequestEvent(ptr))->place))); return(C_int_to_Xen_integer((int)((Xen_to_C_XCirculateEvent(ptr))->place))); } static Xen gxm_set_place(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_integer(val), val, 2, "place", "an integer"); if (Xen_is_XCirculateRequestEvent(ptr)) (Xen_to_C_XCirculateRequestEvent(ptr))->place = Xen_integer_to_C_int(val); else if (Xen_is_XCirculateEvent(ptr)) (Xen_to_C_XCirculateEvent(ptr))->place = Xen_integer_to_C_int(val); else XM_set_field_assert_type(0, ptr, 1, "place", "a struct with a place field"); return(val); } static Xen gxm_value_mask(Xen ptr) { XM_field_assert_type(Xen_is_XConfigureRequestEvent(ptr), ptr, 1, "value_mask", "XConfigureRequestEvent"); return(C_ulong_to_Xen_ulong((unsigned long)((Xen_to_C_XConfigureRequestEvent(ptr))->value_mask))); } static Xen gxm_set_value_mask(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_ulong(val), val, 2, "value_mask", "an unsigned long"); XM_set_field_assert_type(Xen_is_XConfigureRequestEvent(ptr), ptr, 1, "value_mask", "XConfigureRequestEvent"); (Xen_to_C_XConfigureRequestEvent(ptr))->value_mask = Xen_ulong_to_C_ulong(val); return(val); } static Xen gxm_above(Xen ptr) { XM_field_assert_type(Xen_is_XConfigureRequestEvent(ptr) || Xen_is_XConfigureEvent(ptr), ptr, 1, "above", "a struct with an above field"); if (Xen_is_XConfigureRequestEvent(ptr)) return(C_to_Xen_Window((Window)((Xen_to_C_XConfigureRequestEvent(ptr))->above))); return(C_to_Xen_Window((Window)((Xen_to_C_XConfigureEvent(ptr))->above))); } static Xen gxm_set_above(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_Window(val), val, 2, "above", "a Window"); if (Xen_is_XConfigureRequestEvent(ptr)) (Xen_to_C_XConfigureRequestEvent(ptr))->above = Xen_to_C_Window(val); else if (Xen_is_XConfigureEvent(ptr)) (Xen_to_C_XConfigureEvent(ptr))->above = Xen_to_C_Window(val); else XM_set_field_assert_type(0, ptr, 1, "above", "a struct with an above field"); return(val); } static Xen gxm_from_configure(Xen ptr) { XM_field_assert_type(Xen_is_XUnmapEvent(ptr), ptr, 1, "from_configure", "XUnmapEvent"); return(C_bool_to_Xen_boolean((Bool)((Xen_to_C_XUnmapEvent(ptr))->from_configure))); } static Xen gxm_set_from_configure(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_boolean(val), val, 2, "from_configure", "a boolean"); XM_set_field_assert_type(Xen_is_XUnmapEvent(ptr), ptr, 1, "from_configure", "XUnmapEvent"); (Xen_to_C_XUnmapEvent(ptr))->from_configure = Xen_boolean_to_C_bool(val); return(val); } static Xen gxm_event(Xen ptr) { /* Xlib.h says event is a window in these cases -- kinda strange looking */ if (Xen_is_XCirculateEvent(ptr)) return(C_to_Xen_Window((Window)((Xen_to_C_XCirculateEvent(ptr))->event))); if (Xen_is_XGravityEvent(ptr)) return(C_to_Xen_Window((Window)((Xen_to_C_XGravityEvent(ptr))->event))); if (Xen_is_XConfigureEvent(ptr)) return(C_to_Xen_Window((Window)((Xen_to_C_XConfigureEvent(ptr))->event))); if (Xen_is_XReparentEvent(ptr)) return(C_to_Xen_Window((Window)((Xen_to_C_XReparentEvent(ptr))->event))); if (Xen_is_XMapEvent(ptr)) return(C_to_Xen_Window((Window)((Xen_to_C_XMapEvent(ptr))->event))); if (Xen_is_XUnmapEvent(ptr)) return(C_to_Xen_Window((Window)((Xen_to_C_XUnmapEvent(ptr))->event))); if (Xen_is_XDestroyWindowEvent(ptr)) return(C_to_Xen_Window((Window)((Xen_to_C_XDestroyWindowEvent(ptr))->event))); if (Xen_is_AnyCallbackStruct(ptr)) return(C_to_Xen_XEvent((XEvent *)((Xen_to_C_XmAnyCallbackStruct(ptr))->event))); XM_field_assert_type(0, ptr, 1, "event", "a struct with an event field"); return(Xen_false); } static Xen gxm_set_event(Xen ptr, Xen val) { if (Xen_is_XCirculateEvent(ptr)) (Xen_to_C_XCirculateEvent(ptr))->event = Xen_to_C_Window(val); else if (Xen_is_XGravityEvent(ptr)) (Xen_to_C_XGravityEvent(ptr))->event = Xen_to_C_Window(val); else if (Xen_is_XConfigureEvent(ptr)) (Xen_to_C_XConfigureEvent(ptr))->event = Xen_to_C_Window(val); else if (Xen_is_XReparentEvent(ptr)) (Xen_to_C_XReparentEvent(ptr))->event = Xen_to_C_Window(val); else if (Xen_is_XMapEvent(ptr)) (Xen_to_C_XMapEvent(ptr))->event = Xen_to_C_Window(val); else if (Xen_is_XUnmapEvent(ptr)) (Xen_to_C_XUnmapEvent(ptr))->event = Xen_to_C_Window(val); else if (Xen_is_XDestroyWindowEvent(ptr)) (Xen_to_C_XDestroyWindowEvent(ptr))->event = Xen_to_C_Window(val); else if (Xen_is_AnyCallbackStruct(ptr)) (Xen_to_C_XmAnyCallbackStruct(ptr))->event = Xen_to_C_XEvent(val); else XM_set_field_assert_type(0, ptr, 1, "event", "a struct with an event field"); return(val); } static Xen gxm_override_redirect(Xen ptr) { if (Xen_is_XWindowAttributes(ptr)) return(C_bool_to_Xen_boolean((Bool)((Xen_to_C_XWindowAttributes(ptr))->override_redirect))); if (Xen_is_XSetWindowAttributes(ptr)) return(C_bool_to_Xen_boolean((Bool)((Xen_to_C_XSetWindowAttributes(ptr))->override_redirect))); if (Xen_is_XConfigureEvent(ptr)) return(C_bool_to_Xen_boolean((Bool)((Xen_to_C_XConfigureEvent(ptr))->override_redirect))); if (Xen_is_XReparentEvent(ptr)) return(C_bool_to_Xen_boolean((Bool)((Xen_to_C_XReparentEvent(ptr))->override_redirect))); if (Xen_is_XMapEvent(ptr)) return(C_bool_to_Xen_boolean((Bool)((Xen_to_C_XMapEvent(ptr))->override_redirect))); if (Xen_is_XCreateWindowEvent(ptr)) return(C_bool_to_Xen_boolean((Bool)((Xen_to_C_XCreateWindowEvent(ptr))->override_redirect))); XM_field_assert_type(0, ptr, 1, "override_redirect", "a struct with an override_redirect field"); return(Xen_false); } static Xen gxm_set_override_redirect(Xen ptr, Xen val) { Bool b; XM_set_field_assert_type(Xen_is_boolean(val), val, 2, "override_redirect", "a boolean"); b = (Bool)Xen_boolean_to_C_bool(val); if (Xen_is_XConfigureEvent(ptr)) (Xen_to_C_XConfigureEvent(ptr))->override_redirect = b; else if (Xen_is_XReparentEvent(ptr)) (Xen_to_C_XReparentEvent(ptr))->override_redirect = b; else if (Xen_is_XMapEvent(ptr)) (Xen_to_C_XMapEvent(ptr))->override_redirect = b; else if (Xen_is_XCreateWindowEvent(ptr)) (Xen_to_C_XCreateWindowEvent(ptr))->override_redirect = b; else XM_set_field_assert_type(0, ptr, 1, "override_redirect", "a struct with an override_redirect field"); return(val); } static Xen gxm_border_width(Xen ptr) { if (Xen_is_XWindowChanges(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XWindowChanges(ptr))->border_width))); if (Xen_is_XWindowAttributes(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XWindowAttributes(ptr))->border_width))); if (Xen_is_XConfigureRequestEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XConfigureRequestEvent(ptr))->border_width))); if (Xen_is_XConfigureEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XConfigureEvent(ptr))->border_width))); if (Xen_is_XCreateWindowEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XCreateWindowEvent(ptr))->border_width))); XM_field_assert_type(0, ptr, 1, "border_width", "a struct with a border_width field"); return(Xen_false); } static Xen gxm_set_border_width(Xen ptr, Xen val) { int wid; XM_set_field_assert_type(Xen_is_integer(val), val, 2, "border_width", "an integer"); wid = Xen_integer_to_C_int(val); if (Xen_is_XConfigureRequestEvent(ptr)) (Xen_to_C_XConfigureRequestEvent(ptr))->border_width = wid; else if (Xen_is_XConfigureEvent(ptr)) (Xen_to_C_XConfigureEvent(ptr))->border_width = wid; else if (Xen_is_XCreateWindowEvent(ptr)) (Xen_to_C_XCreateWindowEvent(ptr))->border_width = wid; else XM_set_field_assert_type(0, ptr, 1, "border_width", "a struct with a border_width field"); return(val); } static Xen gxm_parent(Xen ptr) { if (Xen_is_XCirculateRequestEvent(ptr)) return(C_to_Xen_Window((Window)((Xen_to_C_XCirculateRequestEvent(ptr))->parent))); if (Xen_is_XConfigureRequestEvent(ptr)) return(C_to_Xen_Window((Window)((Xen_to_C_XConfigureRequestEvent(ptr))->parent))); if (Xen_is_XReparentEvent(ptr)) return(C_to_Xen_Window((Window)((Xen_to_C_XReparentEvent(ptr))->parent))); if (Xen_is_XMapRequestEvent(ptr)) return(C_to_Xen_Window((Window)((Xen_to_C_XMapRequestEvent(ptr))->parent))); if (Xen_is_XCreateWindowEvent(ptr)) return(C_to_Xen_Window((Window)((Xen_to_C_XCreateWindowEvent(ptr))->parent))); XM_field_assert_type(0, ptr, 1, "parent", "a struct with a parent field"); return(Xen_false); } static Xen gxm_set_parent(Xen ptr, Xen val) { Window w; XM_set_field_assert_type(Xen_is_Window(val), val, 2, "parent", "a Window"); w = Xen_to_C_Window(val); if (Xen_is_XCirculateRequestEvent(ptr)) (Xen_to_C_XCirculateRequestEvent(ptr))->parent = w; else if (Xen_is_XConfigureRequestEvent(ptr)) (Xen_to_C_XConfigureRequestEvent(ptr))->parent = w; else if (Xen_is_XReparentEvent(ptr)) (Xen_to_C_XReparentEvent(ptr))->parent = w; else if (Xen_is_XMapRequestEvent(ptr)) (Xen_to_C_XMapRequestEvent(ptr))->parent = w; else if (Xen_is_XCreateWindowEvent(ptr)) (Xen_to_C_XCreateWindowEvent(ptr))->parent= w; else XM_set_field_assert_type(0, ptr, 1, "parent", "a struct with a parent field"); return(val); } static Xen gxm_minor_code(Xen ptr) { if (Xen_is_XErrorEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XErrorEvent(ptr))->minor_code))); if (Xen_is_XNoExposeEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XNoExposeEvent(ptr))->minor_code))); if (Xen_is_XGraphicsExposeEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XGraphicsExposeEvent(ptr))->minor_code))); XM_field_assert_type(0, ptr, 1, "minor_code", "a struct with a minor_code field"); return(Xen_false); } static Xen gxm_set_minor_code(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_integer(val), val, 2, "minor_code", "an integer"); if (Xen_is_XErrorEvent(ptr)) (Xen_to_C_XErrorEvent(ptr))->minor_code = Xen_integer_to_C_int(val); else if (Xen_is_XNoExposeEvent(ptr)) (Xen_to_C_XNoExposeEvent(ptr))->minor_code = Xen_integer_to_C_int(val); else if (Xen_is_XGraphicsExposeEvent(ptr)) (Xen_to_C_XGraphicsExposeEvent(ptr))->minor_code = Xen_integer_to_C_int(val); else XM_set_field_assert_type(0, ptr, 1, "minor_code", "a struct with a minor_code field"); return(val); } static Xen gxm_major_code(Xen ptr) { XM_field_assert_type(Xen_is_XNoExposeEvent(ptr) || Xen_is_XGraphicsExposeEvent(ptr), ptr, 1, "major_code", "a struct with a major_code field"); if (Xen_is_XNoExposeEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XNoExposeEvent(ptr))->major_code))); return(C_int_to_Xen_integer((int)((Xen_to_C_XGraphicsExposeEvent(ptr))->major_code))); } static Xen gxm_set_major_code(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_integer(val), val, 2, "major_code", "an integer"); if (Xen_is_XNoExposeEvent(ptr)) (Xen_to_C_XNoExposeEvent(ptr))->major_code = Xen_integer_to_C_int(val); else if (Xen_is_XGraphicsExposeEvent(ptr)) (Xen_to_C_XGraphicsExposeEvent(ptr))->major_code = Xen_integer_to_C_int(val); else XM_set_field_assert_type(0, ptr, 1, "major_code", "a struct with a major_code field"); return(val); } static Xen gxm_drawable(Xen ptr) { XM_field_assert_type(Xen_is_XNoExposeEvent(ptr) || Xen_is_XGraphicsExposeEvent(ptr), ptr, 1, "drawable", "a struct with a drawable field"); if (Xen_is_XNoExposeEvent(ptr)) return(C_to_Xen_Window((Window)((Xen_to_C_XNoExposeEvent(ptr))->drawable))); return(C_to_Xen_Window((Window)((Xen_to_C_XGraphicsExposeEvent(ptr))->drawable))); } static Xen gxm_set_drawable(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_Window(val), val, 2, "drawable", "a Window"); if (Xen_is_XNoExposeEvent(ptr)) (Xen_to_C_XNoExposeEvent(ptr))->drawable = Xen_to_C_Window(val); else if (Xen_is_XGraphicsExposeEvent(ptr)) (Xen_to_C_XGraphicsExposeEvent(ptr))->drawable = Xen_to_C_Window(val); else XM_set_field_assert_type(0, ptr, 1, "drawable", "a struct with a drawable field"); return(val); } static Xen gxm_count(Xen ptr) { if (Xen_is_XMappingEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XMappingEvent(ptr))->count))); if (Xen_is_XGraphicsExposeEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XGraphicsExposeEvent(ptr))->count))); if (Xen_is_XExposeEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XExposeEvent(ptr))->count))); XM_field_assert_type(0, ptr, 1, "count", "a struct with a count field"); return(Xen_false); } static Xen gxm_set_count(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_integer(val), val, 2, "count", "an integer"); if (Xen_is_XMappingEvent(ptr)) (Xen_to_C_XMappingEvent(ptr))->count = Xen_integer_to_C_int(val); else if (Xen_is_XGraphicsExposeEvent(ptr)) (Xen_to_C_XGraphicsExposeEvent(ptr))->count = Xen_integer_to_C_int(val); else if (Xen_is_XExposeEvent(ptr)) (Xen_to_C_XExposeEvent(ptr))->count = Xen_integer_to_C_int(val); else XM_set_field_assert_type(0, ptr, 1, "count", "a struct with a count field"); return(val); } static Xen gxm_key_vector(Xen ptr) { XM_field_assert_type(Xen_is_XKeymapEvent(ptr), ptr, 1, "key_vector", "XKeymapEvent"); return(C_string_to_Xen_string((char *)((Xen_to_C_XKeymapEvent(ptr))->key_vector))); } static Xen gxm_set_key_vector(Xen ptr, Xen val) { char *keys; int lim = 0; XM_set_field_assert_type(Xen_is_string(val), val, 2, "key_vector", "a string"); keys = (char *)Xen_string_to_C_string(val); if (keys) lim = strlen(keys); if (lim > 32) lim = 32; if (lim > 0) { if (Xen_is_XKeymapEvent(ptr)) { int i; for (i = 0; i < lim; i++) (Xen_to_C_XKeymapEvent(ptr))->key_vector[i] = keys[i]; } else XM_set_field_assert_type(0, ptr, 1, "key_vector", "XKeymapEvent"); } return(val); } static Xen gxm_focus(Xen ptr) { if (Xen_is_XCrossingEvent(ptr)) return(C_bool_to_Xen_boolean((Bool)((Xen_to_C_XCrossingEvent(ptr))->focus))); XM_field_assert_type(0, ptr, 1, "focus", "XCrossingEvent"); return(Xen_false); } static Xen gxm_set_focus(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_boolean(val), val, 2, "focus", "a boolean"); XM_set_field_assert_type(Xen_is_XCrossingEvent(ptr), ptr, 1, "focus", "XCrossingEvent"); (Xen_to_C_XCrossingEvent(ptr))->focus = (Bool)Xen_boolean_to_C_bool(val); return(val); } static Xen gxm_detail(Xen ptr) { if (Xen_is_XConfigureRequestEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XConfigureRequestEvent(ptr))->detail))); if (Xen_is_XFocusChangeEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XFocusChangeEvent(ptr))->detail))); if (Xen_is_XCrossingEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XCrossingEvent(ptr))->detail))); XM_field_assert_type(0, ptr, 1, "detail", "a struct with a detail field"); return(Xen_false); } static Xen gxm_set_detail(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_integer(val), val, 2, "detail", "an integer"); if (Xen_is_XConfigureRequestEvent(ptr)) (Xen_to_C_XConfigureRequestEvent(ptr))->detail = Xen_integer_to_C_int(val); else if (Xen_is_XFocusChangeEvent(ptr)) (Xen_to_C_XFocusChangeEvent(ptr))->detail = Xen_integer_to_C_int(val); else if (Xen_is_XCrossingEvent(ptr)) (Xen_to_C_XCrossingEvent(ptr))->detail = Xen_integer_to_C_int(val); else XM_set_field_assert_type(0, ptr, 1, "detail", "a struct with a detail field"); return(val); } static Xen gxm_mode(Xen ptr) { if (Xen_is_XFocusChangeEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XFocusChangeEvent(ptr))->mode))); if (Xen_is_XCrossingEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XCrossingEvent(ptr))->mode))); XM_field_assert_type(0, ptr, 1, "mode", "a struct with a mode field"); return(Xen_false); } static Xen gxm_set_mode(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_integer(val), val, 2, "mode", "an integer"); if (Xen_is_XFocusChangeEvent(ptr)) (Xen_to_C_XFocusChangeEvent(ptr))->mode = Xen_integer_to_C_int(val); else if (Xen_is_XCrossingEvent(ptr)) (Xen_to_C_XCrossingEvent(ptr))->mode = Xen_integer_to_C_int(val); else XM_set_field_assert_type(0, ptr, 1, "mode", "a struct with a mode field"); return(val); } static Xen gxm_is_hint(Xen ptr) { if (Xen_is_XMotionEvent(ptr)) return(C_int_to_Xen_integer((char)((Xen_to_C_XMotionEvent(ptr))->is_hint))); XM_field_assert_type(0, ptr, 1, "is_hint", "XMotionEvent"); return(Xen_false); } static Xen gxm_set_is_hint(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_integer(val), val, 2, "is_hint", "an integer"); XM_set_field_assert_type(Xen_is_XMotionEvent(ptr), ptr, 1, "is_hint", "XMotionEvent"); (Xen_to_C_XMotionEvent(ptr))->is_hint = (char)Xen_integer_to_C_int(val); return(val); } static Xen gxm_button(Xen ptr) { if (Xen_is_XButtonEvent(ptr)) return(C_ulong_to_Xen_ulong((unsigned long)((Xen_to_C_XButtonEvent(ptr))->button))); XM_field_assert_type(0, ptr, 1, "button", "XButtonEvent"); return(Xen_false); } static Xen gxm_set_button(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_ulong(val), val, 2, "button", "an unsigned long"); XM_set_field_assert_type(Xen_is_XButtonEvent(ptr), ptr, 1, "button", "XButtonEvent"); (Xen_to_C_XButtonEvent(ptr))->button = Xen_ulong_to_C_ulong(val); return(val); } static Xen gxm_same_screen(Xen ptr) { if (Xen_is_XCrossingEvent(ptr)) return(C_bool_to_Xen_boolean((Bool)((Xen_to_C_XCrossingEvent(ptr))->same_screen))); if (Xen_is_XMotionEvent(ptr)) return(C_bool_to_Xen_boolean((Bool)((Xen_to_C_XMotionEvent(ptr))->same_screen))); if (Xen_is_XButtonEvent(ptr)) return(C_bool_to_Xen_boolean((Bool)((Xen_to_C_XButtonEvent(ptr))->same_screen))); if (Xen_is_XKeyEvent(ptr)) return(C_bool_to_Xen_boolean((Bool)((Xen_to_C_XKeyEvent(ptr))->same_screen))); XM_field_assert_type(0, ptr, 1, "same_screen", "a struct with a same_screen field"); return(Xen_false); } static Xen gxm_set_same_screen(Xen ptr, Xen val) { Bool b; XM_set_field_assert_type(Xen_is_boolean(val), val, 2, "same_screen", "a boolean"); b = (Bool)Xen_boolean_to_C_bool(val); if (Xen_is_XCrossingEvent(ptr)) (Xen_to_C_XCrossingEvent(ptr))->same_screen = b; else if (Xen_is_XMotionEvent(ptr)) (Xen_to_C_XMotionEvent(ptr))->same_screen = b; else if (Xen_is_XButtonEvent(ptr)) (Xen_to_C_XButtonEvent(ptr))->same_screen = b; else if (Xen_is_XKeyEvent(ptr)) (Xen_to_C_XKeyEvent(ptr))->same_screen = b; else XM_set_field_assert_type(0, ptr, 1, "same_screen", "a struct with a same_screen field"); return(val); } static Xen gxm_keycode(Xen ptr) { if (Xen_is_XKeyEvent(ptr)) return(C_to_Xen_KeyCode((Xen_to_C_XKeyEvent(ptr))->keycode)); XM_field_assert_type(0, ptr, 1, "keycode", "XKeyEvent"); return(Xen_false); } static Xen gxm_set_keycode(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_KeyCode(val), val, 2, "keycode", "a KeyCode"); XM_set_field_assert_type(Xen_is_XKeyEvent(ptr), ptr, 1, "keycode", "XKeyEvent"); (Xen_to_C_XKeyEvent(ptr))->keycode = Xen_to_C_KeyCode(val); return(val); } static Xen gxm_state(Xen ptr) { if (Xen_is_XColormapEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XColormapEvent(ptr))->state))); if (Xen_is_XPropertyEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XPropertyEvent(ptr))->state))); if (Xen_is_XVisibilityEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XVisibilityEvent(ptr))->state))); if (Xen_is_XCrossingEvent(ptr)) return(C_ulong_to_Xen_ulong((unsigned long)((Xen_to_C_XCrossingEvent(ptr))->state))); if (Xen_is_XMotionEvent(ptr)) return(C_ulong_to_Xen_ulong((unsigned long)((Xen_to_C_XMotionEvent(ptr))->state))); if (Xen_is_XButtonEvent(ptr)) return(C_ulong_to_Xen_ulong((unsigned long)((Xen_to_C_XButtonEvent(ptr))->state))); if (Xen_is_XKeyEvent(ptr)) return(C_ulong_to_Xen_ulong((unsigned long)((Xen_to_C_XKeyEvent(ptr))->state))); XM_field_assert_type(0, ptr, 1, "state", "a struct with a state field"); return(Xen_false); } static Xen gxm_set_state(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_integer(val) || Xen_is_ulong(val), val, 2, "state", "an integer"); if (Xen_is_XColormapEvent(ptr)) (Xen_to_C_XColormapEvent(ptr))->state = Xen_integer_to_C_int(val); else if (Xen_is_XPropertyEvent(ptr)) (Xen_to_C_XPropertyEvent(ptr))->state = Xen_integer_to_C_int(val); else if (Xen_is_XVisibilityEvent(ptr)) (Xen_to_C_XVisibilityEvent(ptr))->state = Xen_integer_to_C_int(val); else if (Xen_is_XCrossingEvent(ptr)) (Xen_to_C_XCrossingEvent(ptr))->state = Xen_ulong_to_C_ulong(val); else if (Xen_is_XMotionEvent(ptr)) (Xen_to_C_XMotionEvent(ptr))->state = Xen_ulong_to_C_ulong(val); else if (Xen_is_XButtonEvent(ptr)) (Xen_to_C_XButtonEvent(ptr))->state = Xen_ulong_to_C_ulong(val); else if (Xen_is_XKeyEvent(ptr)) (Xen_to_C_XKeyEvent(ptr))->state = Xen_ulong_to_C_ulong(val); else XM_set_field_assert_type(0, ptr, 1, "state", "a struct with a state field"); return(val); } static Xen gxm_y_root(Xen ptr) { if (Xen_is_XCrossingEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XCrossingEvent(ptr))->y_root))); if (Xen_is_XMotionEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XMotionEvent(ptr))->y_root))); if (Xen_is_XButtonEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XButtonEvent(ptr))->y_root))); if (Xen_is_XKeyEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XKeyEvent(ptr))->y_root))); XM_field_assert_type(0, ptr, 1, "y_root", "a struct with a y_root field"); return(Xen_false); } static Xen gxm_set_y_root(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_integer(val), val, 2, "y_root", "an integer"); if (Xen_is_XCrossingEvent(ptr)) (Xen_to_C_XCrossingEvent(ptr))->y_root = Xen_integer_to_C_int(val); else if (Xen_is_XMotionEvent(ptr)) (Xen_to_C_XMotionEvent(ptr))->y_root = Xen_integer_to_C_int(val); else if (Xen_is_XButtonEvent(ptr)) (Xen_to_C_XButtonEvent(ptr))->y_root = Xen_integer_to_C_int(val); else if (Xen_is_XKeyEvent(ptr)) (Xen_to_C_XKeyEvent(ptr))->y_root = Xen_integer_to_C_int(val); else XM_set_field_assert_type(0, ptr, 1, "y_root", "a struct with a y_root field"); return(val); } static Xen gxm_x_root(Xen ptr) { if (Xen_is_XCrossingEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XCrossingEvent(ptr))->x_root))); if (Xen_is_XMotionEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XMotionEvent(ptr))->x_root))); if (Xen_is_XButtonEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XButtonEvent(ptr))->x_root))); if (Xen_is_XKeyEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XKeyEvent(ptr))->x_root))); XM_field_assert_type(0, ptr, 1, "x_root", "a struct with an x_root field"); return(Xen_false); } static Xen gxm_set_x_root(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_integer(val), val, 2, "x_root", "an integer"); if (Xen_is_XCrossingEvent(ptr)) (Xen_to_C_XCrossingEvent(ptr))->x_root = Xen_integer_to_C_int(val); else if (Xen_is_XMotionEvent(ptr)) (Xen_to_C_XMotionEvent(ptr))->x_root = Xen_integer_to_C_int(val); else if (Xen_is_XButtonEvent(ptr)) (Xen_to_C_XButtonEvent(ptr))->x_root = Xen_integer_to_C_int(val); else if (Xen_is_XKeyEvent(ptr)) (Xen_to_C_XKeyEvent(ptr))->x_root = Xen_integer_to_C_int(val); else XM_set_field_assert_type(0, ptr, 1, "x_root", "a struct with a x_root field"); return(val); } static Xen gxm_set_x(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_integer(val), val, 2, "x", "an integer"); if (Xen_is_XRectangle(ptr)) (Xen_to_C_XRectangle(ptr))->x = (short)Xen_integer_to_C_int(val); else if (Xen_is_XPoint(ptr)) (Xen_to_C_XPoint(ptr))->x = (short)Xen_integer_to_C_int(val); else if (Xen_is_XArc(ptr)) (Xen_to_C_XArc(ptr))->x = (short)Xen_integer_to_C_int(val); else if (Xen_is_XConfigureRequestEvent(ptr)) (Xen_to_C_XConfigureRequestEvent(ptr))->x = Xen_integer_to_C_int(val); else if (Xen_is_XGravityEvent(ptr)) (Xen_to_C_XGravityEvent(ptr))->x = Xen_integer_to_C_int(val); else if (Xen_is_XConfigureEvent(ptr)) (Xen_to_C_XConfigureEvent(ptr))->x = Xen_integer_to_C_int(val); else if (Xen_is_XReparentEvent(ptr)) (Xen_to_C_XReparentEvent(ptr))->x = Xen_integer_to_C_int(val); else if (Xen_is_XCreateWindowEvent(ptr)) (Xen_to_C_XCreateWindowEvent(ptr))->x = Xen_integer_to_C_int(val); else if (Xen_is_XGraphicsExposeEvent(ptr)) (Xen_to_C_XGraphicsExposeEvent(ptr))->x = Xen_integer_to_C_int(val); else if (Xen_is_XExposeEvent(ptr)) (Xen_to_C_XExposeEvent(ptr))->x = Xen_integer_to_C_int(val); else if (Xen_is_XCrossingEvent(ptr)) (Xen_to_C_XCrossingEvent(ptr))->x = Xen_integer_to_C_int(val); else if (Xen_is_XMotionEvent(ptr)) (Xen_to_C_XMotionEvent(ptr))->x = Xen_integer_to_C_int(val); else if (Xen_is_XButtonEvent(ptr)) (Xen_to_C_XButtonEvent(ptr))->x = Xen_integer_to_C_int(val); else if (Xen_is_XKeyEvent(ptr)) (Xen_to_C_XKeyEvent(ptr))->x = Xen_integer_to_C_int(val); else XM_set_field_assert_type(0, ptr, 1, "x", "a struct with an x field"); return(val); } static Xen gxm_set_y(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_integer(val), val, 2, "y", "an integer"); if (Xen_is_XRectangle(ptr)) (Xen_to_C_XRectangle(ptr))->y = (short)Xen_integer_to_C_int(val); else if (Xen_is_XPoint(ptr)) (Xen_to_C_XPoint(ptr))->y = (short)Xen_integer_to_C_int(val); else if (Xen_is_XArc(ptr)) (Xen_to_C_XArc(ptr))->y = (short)Xen_integer_to_C_int(val); else if (Xen_is_XConfigureRequestEvent(ptr)) (Xen_to_C_XConfigureRequestEvent(ptr))->y = Xen_integer_to_C_int(val); else if (Xen_is_XGravityEvent(ptr)) (Xen_to_C_XGravityEvent(ptr))->y = Xen_integer_to_C_int(val); else if (Xen_is_XConfigureEvent(ptr)) (Xen_to_C_XConfigureEvent(ptr))->y = Xen_integer_to_C_int(val); else if (Xen_is_XReparentEvent(ptr)) (Xen_to_C_XReparentEvent(ptr))->y = Xen_integer_to_C_int(val); else if (Xen_is_XCreateWindowEvent(ptr)) (Xen_to_C_XCreateWindowEvent(ptr))->y = Xen_integer_to_C_int(val); else if (Xen_is_XGraphicsExposeEvent(ptr)) (Xen_to_C_XGraphicsExposeEvent(ptr))->y = Xen_integer_to_C_int(val); else if (Xen_is_XExposeEvent(ptr)) (Xen_to_C_XExposeEvent(ptr))->y = Xen_integer_to_C_int(val); else if (Xen_is_XCrossingEvent(ptr)) (Xen_to_C_XCrossingEvent(ptr))->y = Xen_integer_to_C_int(val); else if (Xen_is_XMotionEvent(ptr)) (Xen_to_C_XMotionEvent(ptr))->y = Xen_integer_to_C_int(val); else if (Xen_is_XButtonEvent(ptr)) (Xen_to_C_XButtonEvent(ptr))->y = Xen_integer_to_C_int(val); else if (Xen_is_XKeyEvent(ptr)) (Xen_to_C_XKeyEvent(ptr))->y = Xen_integer_to_C_int(val); else XM_set_field_assert_type(0, ptr, 1, "y", "a struct with a y field"); return(val); } static Xen gxm_y(Xen ptr) { if (Xen_is_XRectangle(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XRectangle(ptr))->y))); if (Xen_is_XPoint(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XPoint(ptr))->y))); if (Xen_is_XArc(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XArc(ptr))->y))); if (Xen_is_XWindowChanges(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XWindowChanges(ptr))->y))); if (Xen_is_XWindowAttributes(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XWindowAttributes(ptr))->y))); if (Xen_is_XmDropProcCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmDropProcCallbackStruct(ptr))->y))); if (Xen_is_XmDragProcCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmDragProcCallbackStruct(ptr))->y))); if (Xen_is_XmDropStartCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmDropStartCallbackStruct(ptr))->y))); if (Xen_is_XmDragMotionCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmDragMotionCallbackStruct(ptr))->y))); if (Xen_is_XmDropSiteEnterCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmDropSiteEnterCallbackStruct(ptr))->y))); if (Xen_is_XmTopLevelEnterCallbackStruct(ptr)) return(C_to_Xen_Position((Position)((Xen_to_C_XmTopLevelEnterCallbackStruct(ptr))->y))); if (Xen_is_XConfigureRequestEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XConfigureRequestEvent(ptr))->y))); if (Xen_is_XGravityEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XGravityEvent(ptr))->y))); if (Xen_is_XConfigureEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XConfigureEvent(ptr))->y))); if (Xen_is_XReparentEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XReparentEvent(ptr))->y))); if (Xen_is_XCreateWindowEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XCreateWindowEvent(ptr))->y))); if (Xen_is_XGraphicsExposeEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XGraphicsExposeEvent(ptr))->y))); if (Xen_is_XExposeEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XExposeEvent(ptr))->y))); if (Xen_is_XCrossingEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XCrossingEvent(ptr))->y))); if (Xen_is_XMotionEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XMotionEvent(ptr))->y))); if (Xen_is_XButtonEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XButtonEvent(ptr))->y))); if (Xen_is_XKeyEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XKeyEvent(ptr))->y))); XM_field_assert_type(0, ptr, 1, "y", "a struct with a y field"); return(Xen_false); } static Xen gxm_x(Xen ptr) { if (Xen_is_XRectangle(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XRectangle(ptr))->x))); if (Xen_is_XPoint(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XPoint(ptr))->x))); if (Xen_is_XArc(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XArc(ptr))->x))); if (Xen_is_XWindowChanges(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XWindowChanges(ptr))->x))); if (Xen_is_XWindowAttributes(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XWindowAttributes(ptr))->x))); if (Xen_is_XmDropProcCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmDropProcCallbackStruct(ptr))->x))); if (Xen_is_XmDragProcCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmDragProcCallbackStruct(ptr))->x))); if (Xen_is_XmDropStartCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmDropStartCallbackStruct(ptr))->x))); if (Xen_is_XmDragMotionCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmDragMotionCallbackStruct(ptr))->x))); if (Xen_is_XmDropSiteEnterCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmDropSiteEnterCallbackStruct(ptr))->x))); if (Xen_is_XmTopLevelEnterCallbackStruct(ptr)) return(C_to_Xen_Position((Position)((Xen_to_C_XmTopLevelEnterCallbackStruct(ptr))->x))); if (Xen_is_XConfigureRequestEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XConfigureRequestEvent(ptr))->x))); if (Xen_is_XGravityEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XGravityEvent(ptr))->x))); if (Xen_is_XConfigureEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XConfigureEvent(ptr))->x))); if (Xen_is_XReparentEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XReparentEvent(ptr))->x))); if (Xen_is_XCreateWindowEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XCreateWindowEvent(ptr))->x))); if (Xen_is_XGraphicsExposeEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XGraphicsExposeEvent(ptr))->x))); if (Xen_is_XExposeEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XExposeEvent(ptr))->x))); if (Xen_is_XCrossingEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XCrossingEvent(ptr))->x))); if (Xen_is_XMotionEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XMotionEvent(ptr))->x))); if (Xen_is_XButtonEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XButtonEvent(ptr))->x))); if (Xen_is_XKeyEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XKeyEvent(ptr))->x))); XM_field_assert_type(0, ptr, 1, "x", "a struct with an x field"); return(Xen_false); } static Xen gxm_time(Xen ptr) { if (Xen_is_XmDestinationCallbackStruct(ptr)) return(C_to_Xen_Time((Time)((Xen_to_C_XmDestinationCallbackStruct(ptr))->time))); if (Xen_is_XSelectionEvent(ptr)) return(C_to_Xen_Time((Time)((Xen_to_C_XSelectionEvent(ptr))->time))); if (Xen_is_XSelectionRequestEvent(ptr)) return(C_to_Xen_Time((Time)((Xen_to_C_XSelectionRequestEvent(ptr))->time))); if (Xen_is_XSelectionClearEvent(ptr)) return(C_to_Xen_Time((Time)((Xen_to_C_XSelectionClearEvent(ptr))->time))); if (Xen_is_XPropertyEvent(ptr)) return(C_to_Xen_Time((Time)((Xen_to_C_XPropertyEvent(ptr))->time))); if (Xen_is_XCrossingEvent(ptr)) return(C_to_Xen_Time((Time)((Xen_to_C_XCrossingEvent(ptr))->time))); if (Xen_is_XMotionEvent(ptr)) return(C_to_Xen_Time((Time)((Xen_to_C_XMotionEvent(ptr))->time))); if (Xen_is_XButtonEvent(ptr)) return(C_to_Xen_Time((Time)((Xen_to_C_XButtonEvent(ptr))->time))); if (Xen_is_XKeyEvent(ptr)) return(C_to_Xen_Time((Time)((Xen_to_C_XKeyEvent(ptr))->time))); XM_field_assert_type(0, ptr, 1, "time", "a struct with a time field"); return(Xen_false); } static Xen gxm_set_time(Xen ptr, Xen val) { Time tm; XM_set_field_assert_type(Xen_is_Time(val), val, 2, "time", "Time"); tm = Xen_to_C_Time(val); if (Xen_is_XSelectionEvent(ptr)) (Xen_to_C_XSelectionEvent(ptr))->time = tm; else if (Xen_is_XSelectionRequestEvent(ptr)) (Xen_to_C_XSelectionRequestEvent(ptr))->time = tm; else if (Xen_is_XSelectionClearEvent(ptr)) (Xen_to_C_XSelectionClearEvent(ptr))->time = tm; else if (Xen_is_XPropertyEvent(ptr)) (Xen_to_C_XPropertyEvent(ptr))->time = tm; else if (Xen_is_XCrossingEvent(ptr)) (Xen_to_C_XCrossingEvent(ptr))->time = tm; else if (Xen_is_XMotionEvent(ptr)) (Xen_to_C_XMotionEvent(ptr))->time = tm; else if (Xen_is_XButtonEvent(ptr)) (Xen_to_C_XButtonEvent(ptr))->time = tm; else if (Xen_is_XKeyEvent(ptr)) (Xen_to_C_XKeyEvent(ptr))->time = tm; else XM_set_field_assert_type(0, ptr, 1, "time", "a struct with a time field"); return(val); } static Xen gxm_subwindow(Xen ptr) { if (Xen_is_XCrossingEvent(ptr)) return(C_to_Xen_Window((Window)((Xen_to_C_XCrossingEvent(ptr))->subwindow))); if (Xen_is_XMotionEvent(ptr)) return(C_to_Xen_Window((Window)((Xen_to_C_XMotionEvent(ptr))->subwindow))); if (Xen_is_XButtonEvent(ptr)) return(C_to_Xen_Window((Window)((Xen_to_C_XButtonEvent(ptr))->subwindow))); if (Xen_is_XKeyEvent(ptr)) return(C_to_Xen_Window((Window)((Xen_to_C_XKeyEvent(ptr))->subwindow))); XM_field_assert_type(0, ptr, 1, "subwindow", "a struct with a subwindow field"); return(Xen_false); } static Xen gxm_set_subwindow(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_Window(val), val, 2, "subwindow", "a Window"); if (Xen_is_XCrossingEvent(ptr)) (Xen_to_C_XCrossingEvent(ptr))->subwindow = Xen_to_C_Window(val); else if (Xen_is_XMotionEvent(ptr)) (Xen_to_C_XMotionEvent(ptr))->subwindow = Xen_to_C_Window(val); else if (Xen_is_XButtonEvent(ptr)) (Xen_to_C_XButtonEvent(ptr))->subwindow = Xen_to_C_Window(val); else if (Xen_is_XKeyEvent(ptr)) (Xen_to_C_XKeyEvent(ptr))->subwindow = Xen_to_C_Window(val); else XM_set_field_assert_type(0, ptr, 1, "subwindow", "a struct with a subwindow field"); return(val); } static Xen gxm_window(Xen ptr) { if (Xen_is_XmDrawnButtonCallbackStruct(ptr)) return(C_to_Xen_Window((Window)((Xen_to_C_XmDrawnButtonCallbackStruct(ptr))->window))); if (Xen_is_XmDrawingAreaCallbackStruct(ptr)) return(C_to_Xen_Window((Window)((Xen_to_C_XmDrawingAreaCallbackStruct(ptr))->window))); if (Xen_is_XmDropStartCallbackStruct(ptr)) return(C_to_Xen_Window((Window)((Xen_to_C_XmDropStartCallbackStruct(ptr))->window))); if (Xen_is_XmTopLevelEnterCallbackStruct(ptr)) return(C_to_Xen_Window((Window)((Xen_to_C_XmTopLevelEnterCallbackStruct(ptr))->window))); if (Xen_is_XmTopLevelLeaveCallbackStruct(ptr)) return(C_to_Xen_Window((Window)((Xen_to_C_XmTopLevelLeaveCallbackStruct(ptr))->window))); if (Xen_is_XEvent(ptr)) return(C_to_Xen_Window((Window)((Xen_to_C_XAnyEvent(ptr))->window))); XM_field_assert_type(0, ptr, 1, "window", "a struct with a window field"); return(Xen_false); } static Xen gxm_set_window(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_Window(val), val, 2, "window", "a Window"); XM_set_field_assert_type(Xen_is_XEvent(ptr), ptr, 1, "window", "XEvent"); (Xen_to_C_XAnyEvent(ptr))->window = Xen_to_C_Window(val); return(val); } static Xen gxm_send_event(Xen ptr) { if (Xen_is_XEvent(ptr)) return(C_bool_to_Xen_boolean((Bool)((Xen_to_C_XAnyEvent(ptr))->send_event))); XM_field_assert_type(0, ptr, 1, "send_event", "XEvent"); return(Xen_false); } static Xen gxm_set_send_event(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_boolean(val), val, 2, "send_event", "a boolean"); XM_set_field_assert_type(Xen_is_XEvent(ptr), ptr, 1, "send_event", "XEvent"); (Xen_to_C_XAnyEvent(ptr))->send_event = (Bool)Xen_boolean_to_C_bool(val); return(val); } static Xen gxm_serial(Xen ptr) { XM_field_assert_type(Xen_is_XEvent(ptr), ptr, 1, "serial", "XEvent"); return(C_ulong_to_Xen_ulong((unsigned long)((Xen_to_C_XAnyEvent(ptr))->serial))); } static Xen gxm_set_serial(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_XEvent(ptr), ptr, 1, "serial", "XEvent"); (Xen_to_C_XAnyEvent(ptr))->serial = Xen_ulong_to_C_ulong(val); return(val); } static Xen gxm_type(Xen ptr) { if (Xen_is_XmSelectionCallbackStruct(ptr)) return(C_to_Xen_Atom((Atom)((Xen_to_C_XmSelectionCallbackStruct(ptr))->type))); if (Xen_is_XmConvertCallbackStruct(ptr)) return(C_to_Xen_Atom((Atom)((Xen_to_C_XmConvertCallbackStruct(ptr))->type))); if (Xen_is_XEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XAnyEvent(ptr))->type))); XM_field_assert_type(0, ptr, 1, "type", "a struct with a type field"); return(Xen_false); } static Xen gxm_set_type(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_XEvent(ptr), ptr, 1, "type", "XEvent"); XM_set_field_assert_type(Xen_is_integer(val), val, 2, "type", "integer"); (Xen_to_C_XAnyEvent(ptr))->type = Xen_integer_to_C_int(val); return(val); } static Xen gxm_root_input_mask(Xen ptr) { XM_field_assert_type(Xen_is_Screen(ptr), ptr, 1, "root_input_mask", "Screen"); return(C_int_to_Xen_integer((long)((Xen_to_C_Screen(ptr))->root_input_mask))); } static Xen gxm_save_unders(Xen ptr) { XM_field_assert_type(Xen_is_Screen(ptr), ptr, 1, "save_unders", "Screen"); return(C_bool_to_Xen_boolean((Bool)((Xen_to_C_Screen(ptr))->save_unders))); } static Xen gxm_backing_store(Xen ptr) { if (Xen_is_XWindowAttributes(ptr)) return(C_bool_to_Xen_boolean((int)((Xen_to_C_XWindowAttributes(ptr))->backing_store))); if (Xen_is_XSetWindowAttributes(ptr)) return(C_bool_to_Xen_boolean((int)((Xen_to_C_XSetWindowAttributes(ptr))->backing_store))); if (Xen_is_Screen(ptr)) return(C_bool_to_Xen_boolean((int)((Xen_to_C_Screen(ptr))->backing_store))); XM_field_assert_type(0, ptr, 1, "backing_store", "a struct with a backing_store field"); return(Xen_false); } static Xen gxm_set_backing_store(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_XSetWindowAttributes(ptr) || Xen_is_XWindowAttributes(ptr) || Xen_is_Screen(ptr), ptr, 1, "backing_store", "a struct with a backing_store field"); XM_set_field_assert_type(Xen_is_boolean(val), val, 2, "backing_store", "a Boolean"); if (Xen_is_XWindowAttributes(ptr)) (Xen_to_C_XWindowAttributes(ptr))->backing_store = Xen_boolean_to_C_bool(val); else if (Xen_is_XSetWindowAttributes(ptr)) (Xen_to_C_XSetWindowAttributes(ptr))->backing_store = Xen_boolean_to_C_bool(val); else if (Xen_is_Screen(ptr)) (Xen_to_C_Screen(ptr))->backing_store = Xen_boolean_to_C_bool(val); return(val); } static Xen gxm_min_maps(Xen ptr) { XM_field_assert_type(Xen_is_Screen(ptr), ptr, 1, "min_maps", "Screen"); return(C_int_to_Xen_integer((int)((Xen_to_C_Screen(ptr))->min_maps))); } static Xen gxm_max_maps(Xen ptr) { XM_field_assert_type(Xen_is_Screen(ptr), ptr, 1, "max_maps", "Screen"); return(C_int_to_Xen_integer((int)((Xen_to_C_Screen(ptr))->max_maps))); } static Xen gxm_black_pixel(Xen ptr) { XM_field_assert_type(Xen_is_Screen(ptr), ptr, 1, "black_pixel", "Screen"); return(C_to_Xen_Pixel((Xen_to_C_Screen(ptr))->black_pixel)); } static Xen gxm_white_pixel(Xen ptr) { XM_field_assert_type(Xen_is_Screen(ptr), ptr, 1, "white_pixel", "Screen"); return(C_to_Xen_Pixel((Xen_to_C_Screen(ptr))->white_pixel)); } static Xen gxm_cmap(Xen ptr) { XM_field_assert_type(Xen_is_Screen(ptr), ptr, 1, "cmap", "Screen"); return(C_to_Xen_Colormap((Colormap)((Xen_to_C_Screen(ptr))->cmap))); } static Xen gxm_default_gc(Xen ptr) { XM_field_assert_type(Xen_is_Screen(ptr), ptr, 1, "default_gc", "Screen"); return(C_to_Xen_GC((GC)((Xen_to_C_Screen(ptr))->default_gc))); } static Xen gxm_root_visual(Xen ptr) { XM_field_assert_type(Xen_is_Screen(ptr), ptr, 1, "root_visual", "Screen"); return(C_to_Xen_Visual((Visual *)((Xen_to_C_Screen(ptr))->root_visual))); } static Xen gxm_root_depth(Xen ptr) { XM_field_assert_type(Xen_is_Screen(ptr), ptr, 1, "root_depth", "Screen"); return(C_int_to_Xen_integer((int)((Xen_to_C_Screen(ptr))->root_depth))); } static Xen gxm_depths(Xen ptr) { Screen *scr; int len; Xen lst = Xen_empty_list; XM_field_assert_type(Xen_is_Screen(ptr), ptr, 1, "depths", "Screen"); scr = Xen_to_C_Screen(ptr); len = scr->ndepths; if (len > 0) { Depth *dps; int i; dps = scr->depths; for (i = len - 1; i >= 0; i--) lst = Xen_cons(wrap_for_Xen("Depth", &(dps[i])), lst); } return(lst); } static Xen gxm_ndepths(Xen ptr) { XM_field_assert_type(Xen_is_Screen(ptr), ptr, 1, "ndepths", "Screen"); return(C_int_to_Xen_integer((int)((Xen_to_C_Screen(ptr))->ndepths))); } static Xen gxm_mheight(Xen ptr) { XM_field_assert_type(Xen_is_Screen(ptr), ptr, 1, "mheight", "Screen"); return(C_int_to_Xen_integer((int)((Xen_to_C_Screen(ptr))->mheight))); } static Xen gxm_mwidth(Xen ptr) { XM_field_assert_type(Xen_is_Screen(ptr), ptr, 1, "mwidth", "Screen"); return(C_int_to_Xen_integer((int)((Xen_to_C_Screen(ptr))->mwidth))); } static Xen gxm_set_height(Xen ptr, Xen val) { if (Xen_is_XRectangle(ptr)) (Xen_to_C_XRectangle(ptr))->height = Xen_integer_to_C_int(val); else if (Xen_is_XArc(ptr)) (Xen_to_C_XArc(ptr))->height = Xen_integer_to_C_int(val); else if (Xen_is_XpmImage(ptr)) (Xen_to_C_XpmImage(ptr))->height = Xen_ulong_to_C_ulong(val); else if (Xen_is_XpmAttributes(ptr)) (Xen_to_C_XpmAttributes(ptr))->height = Xen_ulong_to_C_ulong(val); else if (Xen_is_XConfigureRequestEvent(ptr)) (Xen_to_C_XConfigureRequestEvent(ptr))->height = Xen_integer_to_C_int(val); else if (Xen_is_XResizeRequestEvent(ptr)) (Xen_to_C_XResizeRequestEvent(ptr))->height = Xen_integer_to_C_int(val); else if (Xen_is_XConfigureEvent(ptr)) (Xen_to_C_XConfigureEvent(ptr))->height = Xen_integer_to_C_int(val); else if (Xen_is_XCreateWindowEvent(ptr)) (Xen_to_C_XCreateWindowEvent(ptr))->height = Xen_integer_to_C_int(val); else if (Xen_is_XGraphicsExposeEvent(ptr)) (Xen_to_C_XGraphicsExposeEvent(ptr))->height = Xen_integer_to_C_int(val); else if (Xen_is_XExposeEvent(ptr)) (Xen_to_C_XExposeEvent(ptr))->height = Xen_integer_to_C_int(val); else XM_set_field_assert_type(0, ptr, 1, "height", "a struct with a height field"); return(val); } static Xen gxm_set_width(Xen ptr, Xen val) { if (Xen_is_XRectangle(ptr)) (Xen_to_C_XRectangle(ptr))->width = Xen_integer_to_C_int(val); else if (Xen_is_XArc(ptr)) (Xen_to_C_XArc(ptr))->width = Xen_integer_to_C_int(val); else if (Xen_is_XpmImage(ptr)) (Xen_to_C_XpmImage(ptr))->width = Xen_ulong_to_C_ulong(val); else if (Xen_is_XpmAttributes(ptr)) (Xen_to_C_XpmAttributes(ptr))->width = Xen_ulong_to_C_ulong(val); else if (Xen_is_XConfigureRequestEvent(ptr)) (Xen_to_C_XConfigureRequestEvent(ptr))->width = Xen_integer_to_C_int(val); else if (Xen_is_XResizeRequestEvent(ptr)) (Xen_to_C_XResizeRequestEvent(ptr))->width = Xen_integer_to_C_int(val); else if (Xen_is_XConfigureEvent(ptr)) (Xen_to_C_XConfigureEvent(ptr))->width = Xen_integer_to_C_int(val); else if (Xen_is_XCreateWindowEvent(ptr)) (Xen_to_C_XCreateWindowEvent(ptr))->width = Xen_integer_to_C_int(val); else if (Xen_is_XGraphicsExposeEvent(ptr)) (Xen_to_C_XGraphicsExposeEvent(ptr))->width = Xen_integer_to_C_int(val); else if (Xen_is_XExposeEvent(ptr)) (Xen_to_C_XExposeEvent(ptr))->width = Xen_integer_to_C_int(val); else XM_set_field_assert_type(0, ptr, 1, "width", "a struct with a width field"); return(val); } static Xen gxm_height(Xen ptr) { if (Xen_is_XRectangle(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XRectangle(ptr))->height))); if (Xen_is_XArc(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XArc(ptr))->height))); if (Xen_is_XWindowChanges(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XWindowChanges(ptr))->height))); if (Xen_is_XImage(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XImage(ptr))->height))); if (Xen_is_XWindowAttributes(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XWindowAttributes(ptr))->height))); if (Xen_is_XConfigureRequestEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XConfigureRequestEvent(ptr))->height))); if (Xen_is_XResizeRequestEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XResizeRequestEvent(ptr))->height))); if (Xen_is_XConfigureEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XConfigureEvent(ptr))->height))); if (Xen_is_XCreateWindowEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XCreateWindowEvent(ptr))->height))); if (Xen_is_XGraphicsExposeEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XGraphicsExposeEvent(ptr))->height))); if (Xen_is_XExposeEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XExposeEvent(ptr))->height))); if (Xen_is_Screen(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_Screen(ptr))->height))); if (Xen_is_XpmImage(ptr)) return(C_ulong_to_Xen_ulong((unsigned long)((Xen_to_C_XpmImage(ptr))->height))); if (Xen_is_XpmAttributes(ptr)) return(C_ulong_to_Xen_ulong((unsigned long)((Xen_to_C_XpmAttributes(ptr))->height))); XM_field_assert_type(0, ptr, 1, "height", "a struct with a height field"); return(Xen_false); } static Xen gxm_width(Xen ptr) { if (Xen_is_XRectangle(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XRectangle(ptr))->width))); if (Xen_is_XArc(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XArc(ptr))->width))); if (Xen_is_XWindowChanges(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XWindowChanges(ptr))->width))); if (Xen_is_XImage(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XImage(ptr))->width))); if (Xen_is_XWindowAttributes(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XWindowAttributes(ptr))->width))); if (Xen_is_XCharStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XCharStruct(ptr))->width))); if (Xen_is_XConfigureRequestEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XConfigureRequestEvent(ptr))->width))); if (Xen_is_XResizeRequestEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XResizeRequestEvent(ptr))->width))); if (Xen_is_XConfigureEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XConfigureEvent(ptr))->width))); if (Xen_is_XCreateWindowEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XCreateWindowEvent(ptr))->width))); if (Xen_is_XGraphicsExposeEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XGraphicsExposeEvent(ptr))->width))); if (Xen_is_XExposeEvent(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XExposeEvent(ptr))->width))); if (Xen_is_Screen(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_Screen(ptr))->width))); if (Xen_is_XpmImage(ptr)) return(C_ulong_to_Xen_ulong((unsigned long)((Xen_to_C_XpmImage(ptr))->width))); if (Xen_is_XpmAttributes(ptr)) return(C_ulong_to_Xen_ulong((unsigned long)((Xen_to_C_XpmAttributes(ptr))->width))); XM_field_assert_type(0, ptr, 1, "width", "a struct with a width field"); return(Xen_false); } static Xen gxm_root(Xen ptr) { if (Xen_is_XWindowAttributes(ptr)) return(C_to_Xen_Window((Window)((Xen_to_C_XWindowAttributes(ptr))->root))); if (Xen_is_XCrossingEvent(ptr)) return(C_to_Xen_Window((Window)((Xen_to_C_XCrossingEvent(ptr))->root))); if (Xen_is_XMotionEvent(ptr)) return(C_to_Xen_Window((Window)((Xen_to_C_XMotionEvent(ptr))->root))); if (Xen_is_XButtonEvent(ptr)) return(C_to_Xen_Window((Window)((Xen_to_C_XButtonEvent(ptr))->root))); if (Xen_is_XKeyEvent(ptr)) return(C_to_Xen_Window((Window)((Xen_to_C_XKeyEvent(ptr))->root))); if (Xen_is_Screen(ptr)) return(C_to_Xen_Window((Window)((Xen_to_C_Screen(ptr))->root))); XM_field_assert_type(0, ptr, 1, "root", "a struct with a root field"); return(Xen_false); } static Xen gxm_set_root(Xen ptr, Xen val) { Window w; XM_set_field_assert_type(Xen_is_Window(val), val, 2, "root", "a Window"); w = Xen_to_C_Window(val); if (Xen_is_XWindowAttributes(ptr)) (Xen_to_C_XWindowAttributes(ptr))->root = w; else if (Xen_is_XCrossingEvent(ptr)) (Xen_to_C_XCrossingEvent(ptr))->root = w; else if (Xen_is_XMotionEvent(ptr)) (Xen_to_C_XMotionEvent(ptr))->root = w; else if (Xen_is_XButtonEvent(ptr)) (Xen_to_C_XButtonEvent(ptr))->root = w; else if (Xen_is_XKeyEvent(ptr)) (Xen_to_C_XKeyEvent(ptr))->root = w; else if (Xen_is_Screen(ptr)) (Xen_to_C_Screen(ptr))->root = w; else XM_set_field_assert_type(0, ptr, 1, "root", "a struct with a root field"); return(val); } static Xen gxm_display(Xen ptr) { XM_field_assert_type(Xen_is_XEvent(ptr) || Xen_is_Screen(ptr), ptr, 1, "display", "XEvent or Screen"); if (Xen_is_XEvent(ptr)) return(C_to_Xen_Display((Display *)((Xen_to_C_XAnyEvent(ptr))->display))); return(C_to_Xen_Display((Display *)((Xen_to_C_Screen(ptr))->display))); } static Xen gxm_set_display(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_Display(val), val, 2, "display", "a Display*"); XM_set_field_assert_type(Xen_is_XEvent(ptr), ptr, 1, "display", "XEvent"); (Xen_to_C_XAnyEvent(ptr))->display = Xen_to_C_Display(val); return(val); } static Xen gxm_function(Xen ptr) { if (Xen_is_XGCValues(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XGCValues(ptr))->function))); XM_field_assert_type(0, ptr, 1, "function", "XGCValues"); return(Xen_false); } static Xen gxm_set_function(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_integer(val), val, 2, "function", "an integer"); XM_set_field_assert_type(Xen_is_XGCValues(ptr), ptr, 1, "function", "XGCValues"); (Xen_to_C_XGCValues(ptr))->function = Xen_integer_to_C_int(val); return(val); } static Xen gxm_plane_mask(Xen ptr) { XM_field_assert_type(Xen_is_XGCValues(ptr), ptr, 1, "plane_mask", "XGCValues"); return(C_ulong_to_Xen_ulong((unsigned long)((Xen_to_C_XGCValues(ptr))->plane_mask))); } static Xen gxm_set_plane_mask(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_XGCValues(ptr), ptr, 1, "plane_mask", "XGCValues"); (Xen_to_C_XGCValues(ptr))->plane_mask = Xen_ulong_to_C_ulong(val); return(val); } static Xen gxm_foreground(Xen ptr) { if (Xen_is_XGCValues(ptr)) return(C_to_Xen_Pixel((Pixel)((Xen_to_C_XGCValues(ptr))->foreground))); XM_field_assert_type(0, ptr, 1, "foreground", "a struct with a foreground field"); return(Xen_false); } static Xen gxm_set_foreground(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_Pixel(val), val, 2, "foreground", "a Pixel"); XM_field_assert_type(Xen_is_XGCValues(ptr), ptr, 1, "foreground", "XGCValues"); (Xen_to_C_XGCValues(ptr))->foreground = Xen_to_C_Pixel(val); return(val); } static Xen gxm_background(Xen ptr) { if (Xen_is_XGCValues(ptr)) return(C_to_Xen_Pixel((Pixel)((Xen_to_C_XGCValues(ptr))->background))); XM_field_assert_type(0, ptr, 1, "background", "a struct with a background field"); return(Xen_false); } static Xen gxm_set_background(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_Pixel(val), val, 2, "background", "a Pixel"); XM_set_field_assert_type(Xen_is_XGCValues(ptr), ptr, 1, "background", "XGCValues"); (Xen_to_C_XGCValues(ptr))->background = Xen_to_C_Pixel(val); return(val); } static Xen gxm_line_width(Xen ptr) { if (Xen_is_XGCValues(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XGCValues(ptr))->line_width))); XM_field_assert_type(0, ptr, 1, "line_width", "XGCValues"); return(Xen_false); } static Xen gxm_set_line_width(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_integer(val), val, 2, "line_width", "an integer"); XM_set_field_assert_type(Xen_is_XGCValues(ptr), ptr, 1, "line_width", "XGCValues"); (Xen_to_C_XGCValues(ptr))->line_width = Xen_integer_to_C_int(val); return(val); } static Xen gxm_line_style(Xen ptr) { if (Xen_is_XGCValues(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XGCValues(ptr))->line_style))); XM_field_assert_type(0, ptr, 1, "line_style", "XGCValues"); return(Xen_false); } static Xen gxm_set_line_style(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_integer(val), val, 2, "line_style", "an integer"); XM_set_field_assert_type(Xen_is_XGCValues(ptr), ptr, 1, "line_style", "XGCValues"); (Xen_to_C_XGCValues(ptr))->line_style = Xen_integer_to_C_int(val); return(val); } static Xen gxm_cap_style(Xen ptr) { if (Xen_is_XGCValues(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XGCValues(ptr))->cap_style))); XM_field_assert_type(0, ptr, 1, "cap_style", "XGCValues"); return(Xen_false); } static Xen gxm_set_cap_style(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_integer(val), val, 2, "cap_style", "an integer"); XM_set_field_assert_type(Xen_is_XGCValues(ptr), ptr, 1, "cap_style", "XGCValues"); (Xen_to_C_XGCValues(ptr))->cap_style = Xen_integer_to_C_int(val); return(val); } static Xen gxm_join_style(Xen ptr) { if (Xen_is_XGCValues(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XGCValues(ptr))->join_style))); XM_field_assert_type(0, ptr, 1, "join_style", "XGCValues"); return(Xen_false); } static Xen gxm_set_join_style(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_integer(val), val, 2, "join_style", "an integer"); XM_set_field_assert_type(Xen_is_XGCValues(ptr), ptr, 1, "join_style", "XGCValues"); (Xen_to_C_XGCValues(ptr))->join_style = Xen_integer_to_C_int(val); return(val); } static Xen gxm_fill_style(Xen ptr) { XM_field_assert_type(Xen_is_XGCValues(ptr), ptr, 1, "fill_style", "XGCValues"); return(C_int_to_Xen_integer((int)((Xen_to_C_XGCValues(ptr))->fill_style))); } static Xen gxm_set_fill_style(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_integer(val), val, 2, "fill_style", "an integer"); XM_set_field_assert_type(Xen_is_XGCValues(ptr), ptr, 1, "fill_style", "XGCValues"); (Xen_to_C_XGCValues(ptr))->fill_style = Xen_integer_to_C_int(val); return(val); } static Xen gxm_fill_rule(Xen ptr) { XM_field_assert_type(Xen_is_XGCValues(ptr), ptr, 1, "fill_rule", "XGCValues"); return(C_int_to_Xen_integer((int)((Xen_to_C_XGCValues(ptr))->fill_rule))); } static Xen gxm_set_fill_rule(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_integer(val), val, 2, "fill_rule", "an integer"); XM_set_field_assert_type(Xen_is_XGCValues(ptr), ptr, 1, "fill_rule", "XGCValues"); (Xen_to_C_XGCValues(ptr))->fill_rule = Xen_integer_to_C_int(val); return(val); } static Xen gxm_arc_mode(Xen ptr) { XM_field_assert_type(Xen_is_XGCValues(ptr), ptr, 1, "arc_mode", "XGCValues"); return(C_int_to_Xen_integer((int)((Xen_to_C_XGCValues(ptr))->arc_mode))); } static Xen gxm_set_arc_mode(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_integer(val), val, 2, "arc_mode", "an integer"); XM_set_field_assert_type(Xen_is_XGCValues(ptr), ptr, 1, "arc_mode", "XGCValues"); (Xen_to_C_XGCValues(ptr))->arc_mode = Xen_integer_to_C_int(val); return(val); } static Xen gxm_tile(Xen ptr) { if (Xen_is_XGCValues(ptr)) return(C_to_Xen_Pixmap((Pixmap)((Xen_to_C_XGCValues(ptr))->tile))); XM_field_assert_type(0, ptr, 1, "tile", "XGCValues"); return(Xen_false); } static Xen gxm_set_tile(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_Pixmap(val), val, 2, "tile", "a Pixmap"); XM_set_field_assert_type(Xen_is_XGCValues(ptr), ptr, 1, "tile", "XGCValues"); (Xen_to_C_XGCValues(ptr))->tile = Xen_to_C_Pixmap(val); return(val); } static Xen gxm_stipple(Xen ptr) { if (Xen_is_XGCValues(ptr)) return(C_to_Xen_Pixmap((Pixmap)((Xen_to_C_XGCValues(ptr))->stipple))); XM_field_assert_type(0, ptr, 1, "stipple", "XGCValues"); return(Xen_false); } static Xen gxm_set_stipple(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_Pixmap(val), val, 2, "stipple", "a Pixmap"); XM_set_field_assert_type(Xen_is_XGCValues(ptr), ptr, 1, "stipple", "XGCValues"); (Xen_to_C_XGCValues(ptr))->stipple = Xen_to_C_Pixmap(val); return(val); } static Xen gxm_ts_x_origin(Xen ptr) { if (Xen_is_XGCValues(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XGCValues(ptr))->ts_x_origin))); XM_field_assert_type(0, ptr, 1, "ts_x_origin", "XGCValues"); return(Xen_false); } static Xen gxm_set_ts_x_origin(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_integer(val), val, 2, "ts_x_origin", "an integer"); XM_set_field_assert_type(Xen_is_XGCValues(ptr), ptr, 1, "ts_x_origin", "XGCValues"); (Xen_to_C_XGCValues(ptr))->ts_x_origin = Xen_integer_to_C_int(val); return(val); } static Xen gxm_ts_y_origin(Xen ptr) { if (Xen_is_XGCValues(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XGCValues(ptr))->ts_y_origin))); XM_field_assert_type(0, ptr, 1, "ts_y_origin", "XGCValues"); return(Xen_false); } static Xen gxm_set_ts_y_origin(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_integer(val), val, 2, "ts_y_origin", "an integer"); XM_set_field_assert_type(Xen_is_XGCValues(ptr), ptr, 1, "ts_y_origin", "XGCValues"); (Xen_to_C_XGCValues(ptr))->ts_y_origin = Xen_integer_to_C_int(val); return(val); } static Xen gxm_font(Xen ptr) { if (Xen_is_XGCValues(ptr)) return(C_to_Xen_Font((Font)((Xen_to_C_XGCValues(ptr))->font))); if (Xen_is_XTextItem(ptr)) return(C_to_Xen_Font((Font)((Xen_to_C_XTextItem(ptr))->font))); XM_field_assert_type(0, ptr, 1, "font", "a struct with a font field"); return(Xen_false); } static Xen gxm_set_font(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_Font(val), val, 2, "font", "a font"); if (Xen_is_XGCValues(ptr)) (Xen_to_C_XGCValues(ptr))->font = Xen_to_C_Font(val); else if (Xen_is_XTextItem(ptr)) (Xen_to_C_XTextItem(ptr))->font = Xen_to_C_Font(val); else XM_set_field_assert_type(0, ptr, 1, "font", "a struct with a font field"); return(val); } static Xen gxm_subwindow_mode(Xen ptr) { if (Xen_is_XGCValues(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XGCValues(ptr))->subwindow_mode))); XM_field_assert_type(0, ptr, 1, "subwindow_mode", "XGCValues"); return(Xen_false); } static Xen gxm_set_subwindow_mode(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_integer(val), val, 2, "subwindow_mode", "an integer"); XM_set_field_assert_type(Xen_is_XGCValues(ptr), ptr, 1, "subwindow_mode", "XGCValues"); (Xen_to_C_XGCValues(ptr))->subwindow_mode = Xen_integer_to_C_int(val); return(val); } static Xen gxm_graphics_exposures(Xen ptr) { if (Xen_is_XGCValues(ptr)) return(C_bool_to_Xen_boolean((Bool)((Xen_to_C_XGCValues(ptr))->graphics_exposures))); XM_field_assert_type(0, ptr, 1, "graphics_exposures", "XGCValues"); return(Xen_false); } static Xen gxm_set_graphics_exposures(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_boolean(val), val, 2, "graphics_exposures", "a boolean"); XM_set_field_assert_type(Xen_is_XGCValues(ptr), ptr, 1, "graphics_exposure", "XGCValues"); (Xen_to_C_XGCValues(ptr))->graphics_exposures = Xen_boolean_to_C_bool(val); return(val); } static Xen gxm_clip_x_origin(Xen ptr) { if (Xen_is_XGCValues(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XGCValues(ptr))->clip_x_origin))); XM_field_assert_type(0, ptr, 1, "clip_x_origin", "XGCValues"); return(Xen_false); } static Xen gxm_set_clip_x_origin(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_integer(val), val, 2, "clip_x_origin", "an integer"); XM_set_field_assert_type(Xen_is_XGCValues(ptr), ptr, 1, "clip_x_origin", "XGCValues"); (Xen_to_C_XGCValues(ptr))->clip_x_origin = Xen_integer_to_C_int(val); return(val); } static Xen gxm_clip_y_origin(Xen ptr) { if (Xen_is_XGCValues(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XGCValues(ptr))->clip_y_origin))); XM_field_assert_type(0, ptr, 1, "clip_y_origin", "XGCValues"); return(Xen_false); } static Xen gxm_set_clip_y_origin(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_integer(val), val, 2, "clip_y_origin", "an integer"); XM_set_field_assert_type(Xen_is_XGCValues(ptr), ptr, 1, "clip_y_origin", "XGCValues"); (Xen_to_C_XGCValues(ptr))->clip_y_origin = Xen_integer_to_C_int(val); return(val); } static Xen gxm_clip_mask(Xen ptr) { if (Xen_is_XGCValues(ptr)) return(C_to_Xen_Pixmap((Pixmap)((Xen_to_C_XGCValues(ptr))->clip_mask))); XM_field_assert_type(0, ptr, 1, "clip_mask", "XGCValues"); return(Xen_false); } static Xen gxm_set_clip_mask(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_Pixmap(val), val, 2, "clip_mask", "a Pixmap"); XM_set_field_assert_type(Xen_is_XGCValues(ptr), ptr, 1, "clip_mask", "XGCValues"); (Xen_to_C_XGCValues(ptr))->clip_mask = Xen_to_C_Pixmap(val); return(val); } static Xen gxm_dash_offset(Xen ptr) { XM_field_assert_type(Xen_is_XGCValues(ptr), ptr, 1, "dash_offset", "XGCValues"); return(C_int_to_Xen_integer((int)((Xen_to_C_XGCValues(ptr))->dash_offset))); } static Xen gxm_set_dash_offset(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_integer(val), val, 2, "dash_offset", "an integer"); XM_set_field_assert_type(Xen_is_XGCValues(ptr), ptr, 1, "dash_offset", "XGCValues"); (Xen_to_C_XGCValues(ptr))->dash_offset = Xen_integer_to_C_int(val); return(val); } static Xen gxm_dashes(Xen ptr) { XM_field_assert_type(Xen_is_XGCValues(ptr), ptr, 1, "dashes", "XGCValues"); return(C_int_to_Xen_integer((char)((Xen_to_C_XGCValues(ptr))->dashes))); } static Xen gxm_set_dashes(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_XGCValues(ptr), ptr, 1, "dashes", "XGCValues"); (Xen_to_C_XGCValues(ptr))->dashes = (char)Xen_integer_to_C_int(val); return(val); } static Xen gxm_killid(Xen ptr) { XM_field_assert_type(Xen_is_XStandardColormap(ptr), ptr, 1, "killid", "XStandardColormap"); return(C_int_to_Xen_integer((long)((Xen_to_C_XStandardColormap(ptr))->killid))); } static Xen gxm_base_pixel(Xen ptr) { XM_field_assert_type(Xen_is_XStandardColormap(ptr), ptr, 1, "base_pixel", "XStandardColormap"); return(C_to_Xen_Pixel((unsigned long)((Xen_to_C_XStandardColormap(ptr))->base_pixel))); } static Xen gxm_blue_mult(Xen ptr) { XM_field_assert_type(Xen_is_XStandardColormap(ptr), ptr, 1, "blue_mult", "XStandardColormap"); return(C_ulong_to_Xen_ulong((unsigned long)((Xen_to_C_XStandardColormap(ptr))->blue_mult))); } static Xen gxm_blue_max(Xen ptr) { XM_field_assert_type(Xen_is_XStandardColormap(ptr), ptr, 1, "blue_max", "XStandardColormap"); return(C_ulong_to_Xen_ulong((unsigned long)((Xen_to_C_XStandardColormap(ptr))->blue_max))); } static Xen gxm_green_mult(Xen ptr) { XM_field_assert_type(Xen_is_XStandardColormap(ptr), ptr, 1, "green_mult", "XStandardColormap"); return(C_ulong_to_Xen_ulong((unsigned long)((Xen_to_C_XStandardColormap(ptr))->green_mult))); } static Xen gxm_green_max(Xen ptr) { XM_field_assert_type(Xen_is_XStandardColormap(ptr), ptr, 1, "green_max", "XStandardColormap"); return(C_ulong_to_Xen_ulong((unsigned long)((Xen_to_C_XStandardColormap(ptr))->green_max))); } static Xen gxm_red_mult(Xen ptr) { XM_field_assert_type(Xen_is_XStandardColormap(ptr), ptr, 1, "red_mult", "XStandardColormap"); return(C_ulong_to_Xen_ulong((unsigned long)((Xen_to_C_XStandardColormap(ptr))->red_mult))); } static Xen gxm_red_max(Xen ptr) { XM_field_assert_type(Xen_is_XStandardColormap(ptr), ptr, 1, "red_max", "XStandardColormap"); return(C_ulong_to_Xen_ulong((unsigned long)((Xen_to_C_XStandardColormap(ptr))->red_max))); } static Xen gxm_XTextItem(Xen chars, Xen nchars, Xen delta, Xen font) { XTextItem *r; #define H_XTextItem "(XTextItem chars len delta font): new XTextItem struct" Xen_check_type(Xen_is_string(chars), chars, 1, "XTextItem", "char*"); Xen_check_type(Xen_is_integer(nchars), nchars, 2, "XTextItem", "int"); Xen_check_type(Xen_is_integer(delta), delta, 3, "XTextItem", "int"); Xen_check_type(Xen_is_Font(font), font, 4, "XTextItem", "Font"); r = (XTextItem *)calloc(1, sizeof(XTextItem)); r->chars = (char *)Xen_string_to_C_string(chars); r->nchars = Xen_integer_to_C_int(nchars); r->delta = Xen_integer_to_C_int(delta); r->font = Xen_to_C_Font(font); return(wrap_for_Xen_obj("XTextItem", (XTextItem *)r)); } static Xen gxm_chars(Xen ptr) { XM_field_assert_type(Xen_is_XTextItem(ptr), ptr, 1, "chars", "XTextItem"); return(C_string_to_Xen_string((char *)((Xen_to_C_XTextItem(ptr))->chars))); } static Xen gxm_set_chars(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_string(val), val, 2, "chars", "a string"); XM_set_field_assert_type(Xen_is_XTextItem(ptr), ptr, 1, "chars", "XTextItem"); (Xen_to_C_XTextItem(ptr))->chars = xen_strdup(Xen_string_to_C_string(val)); return(val); } static Xen gxm_nchars(Xen ptr) { XM_field_assert_type(Xen_is_XTextItem(ptr), ptr, 1, "nchars", "XTextItem"); return(C_int_to_Xen_integer((int)((Xen_to_C_XTextItem(ptr))->nchars))); } static Xen gxm_set_nchars(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_integer(val), val, 2, "nchars", "an integer"); XM_set_field_assert_type(Xen_is_XTextItem(ptr), ptr, 1, "nchars", "XTextItem"); (Xen_to_C_XTextItem(ptr))->nchars = Xen_integer_to_C_int(val); return(val); } static Xen gxm_delta(Xen ptr) { XM_field_assert_type(Xen_is_XTextItem(ptr), ptr, 1, "delta", "XTextItem"); return(C_int_to_Xen_integer((int)((Xen_to_C_XTextItem(ptr))->delta))); } static Xen gxm_set_delta(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_integer(val), val, 2, "delta", "an integer"); XM_set_field_assert_type(Xen_is_XTextItem(ptr), ptr, 1, "delta", "XTextItem"); (Xen_to_C_XTextItem(ptr))->delta = Xen_integer_to_C_int(val); return(val); } static Xen gxm_data(Xen ptr) { if (Xen_is_XImage(ptr)) return(C_string_to_Xen_string((char *)((Xen_to_C_XImage(ptr))->data))); if (Xen_is_XClientMessageEvent(ptr)) return(C_string_to_Xen_string((char *)((Xen_to_C_XClientMessageEvent(ptr))->data.b))); if (Xen_is_XmRowColumnCallbackStruct(ptr)) return(C_string_to_Xen_string((char *)((Xen_to_C_XmRowColumnCallbackStruct(ptr))->data))); if (Xen_is_XpmImage(ptr)) return(Xen_wrap_C_pointer((Xen_to_C_XpmImage(ptr))->data)); XM_field_assert_type(0, ptr, 1, "data", "XpmImage"); return(Xen_false); } static Xen gxm_set_data(Xen ptr, Xen val) { char *str; XM_set_field_assert_type(Xen_is_string(val) || Xen_is_list(val), val, 2, "data", "a string or a list of longs"); XM_set_field_assert_type(Xen_is_XClientMessageEvent(ptr), ptr, 1, "data", "XClientMessageEvent"); if (Xen_is_string(val)) { int i, len = 0; str = (char *)Xen_string_to_C_string(val); if (str) len = strlen(str); if (len > 19) len = 19; for (i = 0; i < len; i++) (Xen_to_C_XClientMessageEvent(ptr))->data.b[i] = str[i]; } else { int i, len; len = Xen_list_length(val); if (len > 5) len = 5; /* only room here for 5 ints */ for (i = 0; i < len; i++) (Xen_to_C_XClientMessageEvent(ptr))->data.l[i] = Xen_integer_to_C_int(Xen_list_ref(val, i)); } return(val); } /* -------------------------------------------------------------------------------- */ static Xen gxm_text(Xen ptr) { /* DIFF: TextVerifyCallbackStruct text field returns list (string format) */ XmTextBlock tb; if (Xen_is_XmTextVerifyCallbackStruct(ptr)) { tb = (XmTextBlock)(Xen_to_C_XmTextVerifyCallbackStruct(ptr))->text; if ((tb) && (tb->length > 0)) return(Xen_list_2(C_string_to_Xen_string(tb->ptr), C_ulong_to_Xen_ulong(tb->format))); return(Xen_false); } XM_field_assert_type(0, ptr, 1, "text", "an XmTextVerifyCallbackStruct"); return(Xen_false); } static Xen gxm_endPos(Xen ptr) { XM_field_assert_type(Xen_is_XmTextVerifyCallbackStruct(ptr), ptr, 1, "endPos", "XmTextVerifyCallbackStruct"); return(C_int_to_Xen_integer((long)((Xen_to_C_XmTextVerifyCallbackStruct(ptr))->endPos))); } static Xen gxm_startPos(Xen ptr) { XM_field_assert_type(Xen_is_XmTextVerifyCallbackStruct(ptr), ptr, 1, "startPos", "XmTextVerifyCallbackStruct"); return(C_int_to_Xen_integer((long)((Xen_to_C_XmTextVerifyCallbackStruct(ptr))->startPos))); } static Xen gxm_newInsert(Xen ptr) { XM_field_assert_type(Xen_is_XmTextVerifyCallbackStruct(ptr), ptr, 1, "newInsert", "XmTextVerifyCallbackStruct"); return(C_int_to_Xen_integer((long)((Xen_to_C_XmTextVerifyCallbackStruct(ptr))->newInsert))); } static Xen gxm_currInsert(Xen ptr) { XM_field_assert_type(Xen_is_XmTextVerifyCallbackStruct(ptr), ptr, 1, "currInsert", "XmTextVerifyCallbackStruct"); return(C_int_to_Xen_integer((long)((Xen_to_C_XmTextVerifyCallbackStruct(ptr))->currInsert))); } static Xen gxm_crossed_boundary(Xen ptr) { XM_field_assert_type(Xen_is_XmSpinBoxCallbackStruct(ptr), ptr, 1, "crossed_boundary", "XmSpinBoxCallbackStruct"); return(C_bool_to_Xen_boolean((Boolean)((Xen_to_C_XmSpinBoxCallbackStruct(ptr))->crossed_boundary))); } static Xen gxm_position(Xen ptr) { XM_field_assert_type(Xen_is_XmSpinBoxCallbackStruct(ptr), ptr, 1, "position", "XmSpinBoxCallbackStruct"); return(C_int_to_Xen_integer((int)((Xen_to_C_XmSpinBoxCallbackStruct(ptr))->position))); } static Xen gxm_tag(Xen ptr) { XM_field_assert_type(Xen_is_XmDisplayCallbackStruct(ptr), ptr, 1, "tag", "XmDisplayCallbackStruct"); return(C_string_to_Xen_string((XmStringTag)((Xen_to_C_XmDisplayCallbackStruct(ptr))->tag))); } static Xen gxm_render_table(Xen ptr) { XM_field_assert_type(Xen_is_XmDisplayCallbackStruct(ptr), ptr, 1, "render_table", "XmDisplayCallbackStruct"); return(C_to_Xen_XmRenderTable((XmRenderTable)((Xen_to_C_XmDisplayCallbackStruct(ptr))->render_table))); } static Xen gxm_font_name(Xen ptr) { XM_field_assert_type(Xen_is_XmDisplayCallbackStruct(ptr), ptr, 1, "font_name", "XmDisplayCallbackStruct"); return(C_string_to_Xen_string((char *)((Xen_to_C_XmDisplayCallbackStruct(ptr))->font_name))); } static Xen gxm_rendition(Xen ptr) { XM_field_assert_type(Xen_is_XmDisplayCallbackStruct(ptr), ptr, 1, "rendition", "XmDisplayCallbackStruct"); return(C_to_Xen_XmRendition((XmRendition)((Xen_to_C_XmDisplayCallbackStruct(ptr))->rendition))); } static Xen gxm_prev_page_widget(Xen ptr) { XM_field_assert_type(Xen_is_XmNotebookCallbackStruct(ptr), ptr, 1, "prev_page_widget", "XmNotebookCallbackStruct"); return(C_to_Xen_Widget((Widget)((Xen_to_C_XmNotebookCallbackStruct(ptr))->prev_page_widget))); } static Xen gxm_prev_page_number(Xen ptr) { XM_field_assert_type(Xen_is_XmNotebookCallbackStruct(ptr), ptr, 1, "prev_page_number", "XmNotebookCallbackStruct"); return(C_int_to_Xen_integer((int)((Xen_to_C_XmNotebookCallbackStruct(ptr))->prev_page_number))); } static Xen gxm_new_outline_state(Xen ptr) { XM_field_assert_type(Xen_is_XmContainerOutlineCallbackStruct(ptr), ptr, 1, "new_outline_state", "XmContainerOutlineCallbackStruct"); return(C_int_to_Xen_integer((int)((Xen_to_C_XmContainerOutlineCallbackStruct(ptr))->new_outline_state))); } static Xen gxm_postIt(Xen ptr) { XM_field_assert_type(Xen_is_XmPopupHandlerCallbackStruct(ptr), ptr, 1, "postIt", "XmPopupHandlerCallbackStruct"); return(C_bool_to_Xen_boolean((Boolean)((Xen_to_C_XmPopupHandlerCallbackStruct(ptr))->postIt))); } static Xen gxm_menuToPost(Xen ptr) { XM_field_assert_type(Xen_is_XmPopupHandlerCallbackStruct(ptr), ptr, 1, "menuToPost", "XmPopupHandlerCallbackStruct"); return(C_to_Xen_Widget((Widget)((Xen_to_C_XmPopupHandlerCallbackStruct(ptr))->menuToPost))); } static Xen gxm_set_postIt(Xen ptr, Xen post) { XM_set_field_assert_type(Xen_is_boolean(post), post, 2, "postIt", "a boolean"); XM_set_field_assert_type(Xen_is_XmPopupHandlerCallbackStruct(ptr), ptr, 1, "postIt", "XmPopupHandler"); (Xen_to_C_XmPopupHandlerCallbackStruct(ptr))->postIt = Xen_boolean_to_C_bool(post); return(post); } static Xen gxm_set_menuToPost(Xen ptr, Xen menu) { XM_set_field_assert_type(Xen_is_Widget(menu), menu, 2, "menuToPost", "a Widget"); XM_set_field_assert_type(Xen_is_XmPopupHandlerCallbackStruct(ptr), ptr, 1, "menuToPost", "XmPopupHandler"); (Xen_to_C_XmPopupHandlerCallbackStruct(ptr))->menuToPost = (Widget)Xen_to_C_Widget(menu); return(menu); } static Xen gxm_pattern_length(Xen ptr) { XM_field_assert_type(Xen_is_XmFileSelectionBoxCallbackStruct(ptr), ptr, 1, "pattern_length", "XmFileSelectionBoxCallbackStruct"); return(C_int_to_Xen_integer((int)((Xen_to_C_XmFileSelectionBoxCallbackStruct(ptr))->pattern_length))); } static Xen gxm_pattern(Xen ptr) { XM_field_assert_type(Xen_is_XmFileSelectionBoxCallbackStruct(ptr), ptr, 1, "pattern", "XmFileSelectionBoxCallbackStruct"); return(C_to_Xen_XmString((XmString)((Xen_to_C_XmFileSelectionBoxCallbackStruct(ptr))->pattern))); } static Xen gxm_dir_length(Xen ptr) { XM_field_assert_type(Xen_is_XmFileSelectionBoxCallbackStruct(ptr), ptr, 1, "dir_length", "XmFileSelectionBoxCallbackStruct"); return(C_int_to_Xen_integer((int)((Xen_to_C_XmFileSelectionBoxCallbackStruct(ptr))->dir_length))); } static Xen gxm_dir(Xen ptr) { XM_field_assert_type(Xen_is_XmFileSelectionBoxCallbackStruct(ptr), ptr, 1, "dir", "XmFileSelectionBoxCallbackStruct"); return(C_to_Xen_XmString((XmString)((Xen_to_C_XmFileSelectionBoxCallbackStruct(ptr))->dir))); } static Xen gxm_mask_length(Xen ptr) { XM_field_assert_type(Xen_is_XmFileSelectionBoxCallbackStruct(ptr), ptr, 1, "mask_length", "XmFileSelectionBoxCallbackStruct"); return(C_int_to_Xen_integer((int)((Xen_to_C_XmFileSelectionBoxCallbackStruct(ptr))->mask_length))); } static Xen gxm_mask(Xen ptr) { XM_field_assert_type(Xen_is_XmFileSelectionBoxCallbackStruct(ptr), ptr, 1, "mask", "XmFileSelectionBoxCallbackStruct"); return(C_to_Xen_XmString((XmString)((Xen_to_C_XmFileSelectionBoxCallbackStruct(ptr))->mask))); } static Xen gxm_auto_selection_type(Xen ptr) { XM_field_assert_type(Xen_is_XmContainerSelectCallbackStruct(ptr) || Xen_is_XmListCallbackStruct(ptr), ptr, 1, "auto_selection_type", "a struct with an auto_selection_type field"); if (Xen_is_XmContainerSelectCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmContainerSelectCallbackStruct(ptr))->auto_selection_type))); return(C_int_to_Xen_integer((char)((Xen_to_C_XmListCallbackStruct(ptr))->auto_selection_type))); } static Xen gxm_selection_type(Xen ptr) { XM_field_assert_type(Xen_is_XmListCallbackStruct(ptr), ptr, 1, "selection_type", "XmListCallbackStruct"); return(C_int_to_Xen_integer((char)((Xen_to_C_XmListCallbackStruct(ptr))->selection_type))); } static Xen gxm_selected_item_positions(Xen ptr) { /* DIFF: selected_item_positions is a list of ints */ if (Xen_is_XmListCallbackStruct(ptr)) return(C_to_Xen_Ints((int *)((Xen_to_C_XmListCallbackStruct(ptr))->selected_item_positions), ((int)((Xen_to_C_XmListCallbackStruct(ptr))->selected_item_count)))); XM_field_assert_type(0, ptr, 1, "selected_item_positions", "a struct with a selected_item_positions field"); return(Xen_false); } static Xen gxm_selected_item_count(Xen ptr) { if (Xen_is_XmContainerSelectCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmContainerSelectCallbackStruct(ptr))->selected_item_count))); if (Xen_is_XmListCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmListCallbackStruct(ptr))->selected_item_count))); XM_field_assert_type(0, ptr, 1, "selected_item_count", "XmListCallbackStruct"); return(Xen_false); } static Xen gxm_selected_items(Xen ptr) { /* DIFF selected_items field returns list */ if (Xen_is_XmContainerSelectCallbackStruct(ptr)) return(C_to_Xen_Widgets((WidgetList)((Xen_to_C_XmContainerSelectCallbackStruct(ptr))->selected_items), (Xen_to_C_XmContainerSelectCallbackStruct(ptr))->selected_item_count)); if (Xen_is_XmListCallbackStruct(ptr)) return(C_to_Xen_XmStringTable((XmStringTable)((Xen_to_C_XmListCallbackStruct(ptr))->selected_items), (Xen_to_C_XmListCallbackStruct(ptr))->selected_item_count)); XM_field_assert_type(0, ptr, 1, "selected_items", "a struct with a selected_items field"); return(Xen_false); } static Xen gxm_item_length(Xen ptr) { XM_field_assert_type(Xen_is_XmListCallbackStruct(ptr), ptr, 1, "item_length", "XmListCallbackStruct"); return(C_int_to_Xen_integer((int)((Xen_to_C_XmListCallbackStruct(ptr))->item_length))); } static Xen gxm_item(Xen ptr) { if (Xen_is_XmContainerOutlineCallbackStruct(ptr)) return(C_to_Xen_Widget((Widget)((Xen_to_C_XmContainerOutlineCallbackStruct(ptr))->item))); if (Xen_is_XmListCallbackStruct(ptr)) return(C_to_Xen_XmString((XmString)((Xen_to_C_XmListCallbackStruct(ptr))->item))); XM_field_assert_type(0, ptr, 1, "item", "XmListCallbackStruct"); return(Xen_false); } /* in Motif 2, this field is an int: XmSET to XmINDETERMINATE -- should we change? */ static Xen gxm_set(Xen ptr) { XM_field_assert_type(Xen_is_XmToggleButtonCallbackStruct(ptr), ptr, 1, "set", "XmToggleButtonCallbackStruct"); return(C_bool_to_Xen_boolean((int)((Xen_to_C_XmToggleButtonCallbackStruct(ptr))->set))); } static Xen gxm_set_set(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_boolean(val) || Xen_is_integer(val), val, 2, "set", "a boolean"); XM_set_field_assert_type(Xen_is_XmToggleButtonCallbackStruct(ptr), ptr, 1, "set", "XmToggleButtonCallbackStruct"); (Xen_to_C_XmToggleButtonCallbackStruct(ptr))->set = Xen_boolean_to_C_bool(val); return(val); } static Xen gxm_callbackstruct(Xen ptr) { XM_field_assert_type(Xen_is_XmRowColumnCallbackStruct(ptr), ptr, 1, "callbackstruct", "XmRowColumnCallbackStruct"); return(C_string_to_Xen_string((char *)((Xen_to_C_XmRowColumnCallbackStruct(ptr))->callbackstruct))); } static Xen gxm_item_position(Xen ptr) { if (Xen_is_XmListCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmListCallbackStruct(ptr))->item_position))); if (Xen_is_XmComboBoxCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmComboBoxCallbackStruct(ptr))->item_position))); XM_field_assert_type(0, ptr, 1, "item_position", "a struct with an item_position field"); return(Xen_false); } static Xen gxm_item_or_text(Xen ptr) { XM_field_assert_type(Xen_is_XmComboBoxCallbackStruct(ptr), ptr, 1, "item_or_text", "XmComboBoxCallbackStruct"); return(C_to_Xen_XmString((XmString)((Xen_to_C_XmComboBoxCallbackStruct(ptr))->item_or_text))); } static Xen gxm_doit(Xen ptr) { if (Xen_is_XmTextVerifyCallbackStruct(ptr)) return(C_bool_to_Xen_boolean((Boolean)((Xen_to_C_XmTextVerifyCallbackStruct(ptr))->doit))); if (Xen_is_XmSpinBoxCallbackStruct(ptr)) return(C_bool_to_Xen_boolean((Boolean)((Xen_to_C_XmSpinBoxCallbackStruct(ptr))->doit))); if (Xen_is_XmDragStartCallbackStruct(ptr)) return(C_bool_to_Xen_boolean((Boolean)((Xen_to_C_XmDragStartCallbackStruct(ptr))->doit))); XM_field_assert_type(0, ptr, 1, "doit", "a struct with a doit field"); return(Xen_false); } static Xen gxm_set_doit(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_boolean(val), val, 2, "doit", "a boolean"); if (Xen_is_XmTextVerifyCallbackStruct(ptr)) (Xen_to_C_XmTextVerifyCallbackStruct(ptr))->doit = Xen_boolean_to_C_bool(val); else if (Xen_is_XmSpinBoxCallbackStruct(ptr)) (Xen_to_C_XmSpinBoxCallbackStruct(ptr))->doit = Xen_boolean_to_C_bool(val); else if (Xen_is_XmDragStartCallbackStruct(ptr)) (Xen_to_C_XmDragStartCallbackStruct(ptr))->doit = Xen_boolean_to_C_bool(val); else XM_set_field_assert_type(0, ptr, 1, "doit", "a struct with a doit field"); return(val); } static Xen gxm_widget(Xen ptr) { if (Xen_is_XmSpinBoxCallbackStruct(ptr)) return(C_to_Xen_Widget((Widget)((Xen_to_C_XmSpinBoxCallbackStruct(ptr))->widget))); if (Xen_is_XmDragStartCallbackStruct(ptr)) return(C_to_Xen_Widget((Widget)((Xen_to_C_XmDragStartCallbackStruct(ptr))->widget))); if (Xen_is_XmRowColumnCallbackStruct(ptr)) return(C_to_Xen_Widget((Widget)((Xen_to_C_XmRowColumnCallbackStruct(ptr))->widget))); XM_field_assert_type(0, ptr, 1, "widget", "a struct with a widget field"); return(Xen_false); } static Xen gxm_click_count(Xen ptr) { if (Xen_is_XmPushButtonCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmPushButtonCallbackStruct(ptr))->click_count))); if (Xen_is_XmDrawnButtonCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmDrawnButtonCallbackStruct(ptr))->click_count))); if (Xen_is_XmArrowButtonCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmArrowButtonCallbackStruct(ptr))->click_count))); XM_field_assert_type(0, ptr, 1, "click_count", "a struct with a click_count field"); return(Xen_false); } static Xen gxm_set_click_count(Xen ptr, Xen val) { int count; XM_set_field_assert_type(Xen_is_integer(val), val, 2, "click_count", "int"); count = Xen_integer_to_C_int(val); if (Xen_is_XmPushButtonCallbackStruct(ptr)) (Xen_to_C_XmPushButtonCallbackStruct(ptr))->click_count = count; else if (Xen_is_XmDrawnButtonCallbackStruct(ptr)) (Xen_to_C_XmDrawnButtonCallbackStruct(ptr))->click_count = count; else if (Xen_is_XmArrowButtonCallbackStruct(ptr)) (Xen_to_C_XmArrowButtonCallbackStruct(ptr))->click_count = count; else XM_set_field_assert_type(0, ptr, 1, "click_count", "a struct with a click_count field"); return(val); } static Xen gxm_remaining(Xen ptr) { XM_field_assert_type(Xen_is_XmSelectionCallbackStruct(ptr), ptr, 1, "remaining", "XmSelectionCallbackStruct"); return(C_int_to_Xen_integer((int)((Xen_to_C_XmSelectionCallbackStruct(ptr))->remaining))); } static Xen gxm_destination_data(Xen ptr) { /* widget-class specific interpretation -- is it worth untangling? */ XM_field_assert_type(Xen_is_XmDestinationCallbackStruct(ptr), ptr, 1, "destination_data", "XmDestinationCallbackStruct"); return(Xen_wrap_C_pointer(((Xen_to_C_XmDestinationCallbackStruct(ptr))->destination_data))); } static Xen gxm_transfer_id(Xen ptr) { if (Xen_is_XmTransferDoneCallbackStruct(ptr)) return(Xen_wrap_C_pointer(((Xen_to_C_XmTransferDoneCallbackStruct(ptr))->transfer_id))); if (Xen_is_XmSelectionCallbackStruct(ptr)) return(Xen_wrap_C_pointer(((Xen_to_C_XmSelectionCallbackStruct(ptr))->transfer_id))); if (Xen_is_XmDestinationCallbackStruct(ptr)) return(Xen_wrap_C_pointer(((Xen_to_C_XmDestinationCallbackStruct(ptr))->transfer_id))); XM_field_assert_type(0, ptr, 1, "transfer_id", "a struct with a transfer_id field"); return(Xen_false); } static Xen gxm_length(Xen ptr) { if (Xen_is_XmFileSelectionBoxCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmFileSelectionBoxCallbackStruct(ptr))->length))); if (Xen_is_XmCommandCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmCommandCallbackStruct(ptr))->length))); if (Xen_is_XmTextBlock(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmTextBlock(ptr))->length))); if (Xen_is_XmSelectionBoxCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmSelectionBoxCallbackStruct(ptr))->length))); if (Xen_is_XmSelectionCallbackStruct(ptr)) return(C_ulong_to_Xen_ulong((unsigned long)((Xen_to_C_XmSelectionCallbackStruct(ptr))->length))); if (Xen_is_XmConvertCallbackStruct(ptr)) return(C_ulong_to_Xen_ulong((unsigned long)((Xen_to_C_XmConvertCallbackStruct(ptr))->length))); XM_field_assert_type(0, ptr, 1, "length", "a struct with a length field"); return(Xen_false); } static Xen gxm_set_length(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_XmTextBlock(ptr), ptr, 1, "length", "XmTextBlock"); XM_set_field_assert_type(Xen_is_integer(val), val, 2, "length", "int"); (Xen_to_C_XmTextBlock(ptr))->length = Xen_integer_to_C_int(val); return(val); } static Xen gxm_ptr(Xen ptr) { XM_field_assert_type(Xen_is_XmTextBlock(ptr), ptr, 1, "ptr", "XmTextBlock"); return(C_string_to_Xen_string((Xen_to_C_XmTextBlock(ptr))->ptr)); } static Xen gxm_set_ptr(Xen pt, Xen val) { XM_set_field_assert_type(Xen_is_XmTextBlock(pt), pt, 1, "ptr", "XmTextBlock"); XM_set_field_assert_type(Xen_is_string(val), val, 2, "length", "char*"); (Xen_to_C_XmTextBlock(pt))->ptr = xen_strdup(Xen_string_to_C_string(val)); return(val); } static Xen gxm_value(Xen ptr) { if (Xen_is_XmSpinBoxCallbackStruct(ptr)) return(C_to_Xen_XmString((XmString)((Xen_to_C_XmSpinBoxCallbackStruct(ptr))->value))); if (Xen_is_XmSelectionBoxCallbackStruct(ptr)) return(C_to_Xen_XmString((XmString)((Xen_to_C_XmSelectionBoxCallbackStruct(ptr))->value))); if (Xen_is_XmConvertCallbackStruct(ptr)) return(Xen_wrap_C_pointer((XtPointer)((Xen_to_C_XmConvertCallbackStruct(ptr))->value))); if (Xen_is_XmSelectionCallbackStruct(ptr)) return(Xen_wrap_C_pointer((XtPointer)((Xen_to_C_XmSelectionCallbackStruct(ptr))->value))); if (Xen_is_XmScaleCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmScaleCallbackStruct(ptr))->value))); if (Xen_is_XmFileSelectionBoxCallbackStruct(ptr)) return(C_to_Xen_XmString((XmString)((Xen_to_C_XmFileSelectionBoxCallbackStruct(ptr))->value))); if (Xen_is_XmCommandCallbackStruct(ptr)) return(C_to_Xen_XmString((XmString)((Xen_to_C_XmCommandCallbackStruct(ptr))->value))); if (Xen_is_XmScrollBarCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmScrollBarCallbackStruct(ptr))->value))); if (Xen_is_XpmColorSymbol(ptr)) return(C_string_to_Xen_string((char *)((Xen_to_C_XpmColorSymbol(ptr))->value))); XM_field_assert_type(0, ptr, 1, "value", "a struct with a value field"); return(Xen_false); } static Xen gxm_set_value(Xen ptr, Xen val) { if (Xen_is_XmScaleCallbackStruct(ptr)) (Xen_to_C_XmScaleCallbackStruct(ptr))->value = Xen_integer_to_C_int(val); else if (Xen_is_XmFileSelectionBoxCallbackStruct(ptr)) (Xen_to_C_XmFileSelectionBoxCallbackStruct(ptr))->value = Xen_to_C_XmString(val); else if (Xen_is_XmCommandCallbackStruct(ptr)) (Xen_to_C_XmCommandCallbackStruct(ptr))->value = Xen_to_C_XmString(val); else if (Xen_is_XmScrollBarCallbackStruct(ptr)) (Xen_to_C_XmScrollBarCallbackStruct(ptr))->value = Xen_integer_to_C_int(val); else if (Xen_is_XmConvertCallbackStruct(ptr)) (Xen_to_C_XmConvertCallbackStruct(ptr))->value = (XtPointer)Xen_unwrap_C_pointer(val); else if (Xen_is_XmSpinBoxCallbackStruct(ptr)) (Xen_to_C_XmSpinBoxCallbackStruct(ptr))->value = Xen_to_C_XmString(val); else if (Xen_is_XmSelectionBoxCallbackStruct(ptr)) (Xen_to_C_XmSelectionBoxCallbackStruct(ptr))->value = Xen_to_C_XmString(val); else if (Xen_is_XmSelectionCallbackStruct(ptr)) (Xen_to_C_XmSelectionCallbackStruct(ptr))->value = (XtPointer)Xen_unwrap_C_pointer(val); else if (Xen_is_XpmColorSymbol(ptr)) (Xen_to_C_XpmColorSymbol(ptr))->value = xen_strdup(Xen_string_to_C_string(val)); else XM_set_field_assert_type(0, ptr, 1, "value", "a struct with a value field"); return(val); } static Xen gxm_status(Xen ptr) { XM_field_assert_type(Xen_is_XmTransferDoneCallbackStruct(ptr) || Xen_is_XmConvertCallbackStruct(ptr), ptr, 1, "status", "a struct with a status field"); if (Xen_is_XmTransferDoneCallbackStruct(ptr)) return(C_int_to_Xen_integer((XmTransferStatus)((Xen_to_C_XmTransferDoneCallbackStruct(ptr))->status))); return(C_int_to_Xen_integer((int)((Xen_to_C_XmConvertCallbackStruct(ptr))->status))); } static Xen gxm_parm_type(Xen ptr) { XM_field_assert_type(Xen_is_XmConvertCallbackStruct(ptr), ptr, 1, "parm_type", "XmConvertCallbackStruct"); return(C_to_Xen_Atom((Atom)((Xen_to_C_XmConvertCallbackStruct(ptr))->parm_type))); } static Xen gxm_parm_length(Xen ptr) { XM_field_assert_type(Xen_is_XmConvertCallbackStruct(ptr), ptr, 1, "parm_length", "XmConvertCallbackStruct"); return(C_ulong_to_Xen_ulong((unsigned long)((Xen_to_C_XmConvertCallbackStruct(ptr))->parm_length))); } static Xen gxm_parm_format(Xen ptr) { XM_field_assert_type(Xen_is_XmConvertCallbackStruct(ptr), ptr, 1, "parm_format", "XmConvertCallbackStruct"); return(C_int_to_Xen_integer((int)((Xen_to_C_XmConvertCallbackStruct(ptr))->parm_format))); } static Xen gxm_parm(Xen ptr) { XM_field_assert_type(Xen_is_XmConvertCallbackStruct(ptr), ptr, 1, "parm", "XmConvertCallbackStruct"); return(Xen_wrap_C_pointer((XtPointer)((Xen_to_C_XmConvertCallbackStruct(ptr))->parm))); } static Xen gxm_location_data(Xen ptr) { /* widget-class specific interpretation -- is it worth untangling? */ XM_field_assert_type(Xen_is_XmDestinationCallbackStruct(ptr) || Xen_is_XmConvertCallbackStruct(ptr), ptr, 1, "location_data", "a struct with a location_data field"); if (Xen_is_XmDestinationCallbackStruct(ptr)) return(Xen_wrap_C_pointer((XtPointer)((Xen_to_C_XmDestinationCallbackStruct(ptr))->location_data))); return(Xen_wrap_C_pointer((XtPointer)((Xen_to_C_XmConvertCallbackStruct(ptr))->location_data))); } static Xen gxm_source_data(Xen ptr) { XM_field_assert_type(Xen_is_XmConvertCallbackStruct(ptr), ptr, 1, "source_data", "XmConvertCallbackStruct"); return(Xen_wrap_C_pointer((XtPointer)((Xen_to_C_XmConvertCallbackStruct(ptr))->source_data))); } static Xen gxm_client_data(Xen ptr) { XM_field_assert_type(Xen_is_XmTransferDoneCallbackStruct(ptr), ptr, 1, "client_data", "XmTransferDoneCallbackStruct"); return(Xen_wrap_C_pointer((XtPointer)((Xen_to_C_XmTransferDoneCallbackStruct(ptr))->client_data))); } static Xen gxm_animate(Xen ptr) { XM_field_assert_type(Xen_is_XmDragProcCallbackStruct(ptr), ptr, 1, "animate", "XmDragProcCallbackStruct"); return(C_bool_to_Xen_boolean((Boolean)((Xen_to_C_XmDragProcCallbackStruct(ptr))->animate))); } static Xen gxm_dragContext(Xen ptr) { XM_field_assert_type(Xen_is_XmDropProcCallbackStruct(ptr) || Xen_is_XmDragProcCallbackStruct(ptr), ptr, 1, "dragContext", "a struct with a dragContext field"); if (Xen_is_XmDropProcCallbackStruct(ptr)) return(C_to_Xen_Widget((Widget)((Xen_to_C_XmDropProcCallbackStruct(ptr))->dragContext))); return(C_to_Xen_Widget((Widget)((Xen_to_C_XmDragProcCallbackStruct(ptr))->dragContext))); } static Xen gxm_completionStatus(Xen ptr) { XM_field_assert_type(Xen_is_XmDropFinishCallbackStruct(ptr), ptr, 1, "completionStatus", "XmDropFinishCallbackStruct"); return(C_int_to_Xen_integer((int)((Xen_to_C_XmDropFinishCallbackStruct(ptr))->completionStatus))); } static Xen gxm_iccHandle(Xen ptr) { if (Xen_is_XmDropStartCallbackStruct(ptr)) return(C_to_Xen_Atom((Atom)((Xen_to_C_XmDropStartCallbackStruct(ptr))->iccHandle))); if (Xen_is_XmTopLevelEnterCallbackStruct(ptr)) return(C_to_Xen_Atom((Atom)((Xen_to_C_XmTopLevelEnterCallbackStruct(ptr))->iccHandle))); XM_field_assert_type(0, ptr, 1, "iccHandle", "a struct with an iccHandle field"); return(Xen_false); } static Xen gxm_dropAction(Xen ptr) { if (Xen_is_XmDropProcCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmDropProcCallbackStruct(ptr))->dropAction))); if (Xen_is_XmDropFinishCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmDropFinishCallbackStruct(ptr))->dropAction))); if (Xen_is_XmDropStartCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmDropStartCallbackStruct(ptr))->dropAction))); XM_field_assert_type(0, ptr, 1, "dropAction", "a struct with a dropAction field"); return(Xen_false); } static Xen gxm_dropSiteStatus(Xen ptr) { if (Xen_is_XmDropProcCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmDropProcCallbackStruct(ptr))->dropSiteStatus))); if (Xen_is_XmDragProcCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmDragProcCallbackStruct(ptr))->dropSiteStatus))); if (Xen_is_XmDropFinishCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmDropFinishCallbackStruct(ptr))->dropSiteStatus))); if (Xen_is_XmDropStartCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmDropStartCallbackStruct(ptr))->dropSiteStatus))); if (Xen_is_XmOperationChangedCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmOperationChangedCallbackStruct(ptr))->dropSiteStatus))); if (Xen_is_XmDragMotionCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmDragMotionCallbackStruct(ptr))->dropSiteStatus))); if (Xen_is_XmDropSiteEnterCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmDropSiteEnterCallbackStruct(ptr))->dropSiteStatus))); XM_field_assert_type(0, ptr, 1, "dropSiteStatus", "a struct with a dropSiteStatus field"); return(Xen_false); } static Xen gxm_set_dropSiteStatus(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_integer(val), val, 2, "dropSiteStatus", "an integer"); if (Xen_is_XmDropProcCallbackStruct(ptr)) (Xen_to_C_XmDropProcCallbackStruct(ptr))->dropSiteStatus = Xen_integer_to_C_int(val); else if (Xen_is_XmDragProcCallbackStruct(ptr)) (Xen_to_C_XmDragProcCallbackStruct(ptr))->dropSiteStatus = Xen_integer_to_C_int(val); else if (Xen_is_XmDropFinishCallbackStruct(ptr)) (Xen_to_C_XmDropFinishCallbackStruct(ptr))->dropSiteStatus = Xen_integer_to_C_int(val); else if (Xen_is_XmDropStartCallbackStruct(ptr)) (Xen_to_C_XmDropStartCallbackStruct(ptr))->dropSiteStatus = Xen_integer_to_C_int(val); else if (Xen_is_XmOperationChangedCallbackStruct(ptr)) (Xen_to_C_XmOperationChangedCallbackStruct(ptr))->dropSiteStatus = Xen_integer_to_C_int(val); else if (Xen_is_XmDragMotionCallbackStruct(ptr)) (Xen_to_C_XmDragMotionCallbackStruct(ptr))->dropSiteStatus = Xen_integer_to_C_int(val); else if (Xen_is_XmDropSiteEnterCallbackStruct(ptr)) (Xen_to_C_XmDropSiteEnterCallbackStruct(ptr))->dropSiteStatus = Xen_integer_to_C_int(val); else XM_set_field_assert_type(0, ptr, 1, "dropSiteStatus", "a struct with a dropSiteStatus field"); return(val); } static Xen gxm_operations(Xen ptr) { if (Xen_is_XmDropProcCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmDropProcCallbackStruct(ptr))->operations))); if (Xen_is_XmDragProcCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmDragProcCallbackStruct(ptr))->operations))); if (Xen_is_XmDropFinishCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmDropFinishCallbackStruct(ptr))->operations))); if (Xen_is_XmDropStartCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmDropStartCallbackStruct(ptr))->operations))); if (Xen_is_XmOperationChangedCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmOperationChangedCallbackStruct(ptr))->operations))); if (Xen_is_XmDragMotionCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmDragMotionCallbackStruct(ptr))->operations))); if (Xen_is_XmDropSiteEnterCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmDropSiteEnterCallbackStruct(ptr))->operations))); XM_field_assert_type(0, ptr, 1, "operations", "a struct with an operations field"); return(Xen_false); } static Xen gxm_operation(Xen ptr) { if (Xen_is_XmDestinationCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmDestinationCallbackStruct(ptr))->operation))); if (Xen_is_XmDropProcCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmDropProcCallbackStruct(ptr))->operation))); if (Xen_is_XmDragProcCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmDragProcCallbackStruct(ptr))->operation))); if (Xen_is_XmDropFinishCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmDropFinishCallbackStruct(ptr))->operation))); if (Xen_is_XmDropStartCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmDropStartCallbackStruct(ptr))->operation))); if (Xen_is_XmOperationChangedCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmOperationChangedCallbackStruct(ptr))->operation))); if (Xen_is_XmDragMotionCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmDragMotionCallbackStruct(ptr))->operation))); if (Xen_is_XmDropSiteEnterCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmDropSiteEnterCallbackStruct(ptr))->operation))); XM_field_assert_type(0, ptr, 1, "operation", "a struct with an operation field"); return(Xen_false); } static Xen gxm_set_operation(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_integer(val), val, 2, "operation", "an integer"); if (Xen_is_XmDestinationCallbackStruct(ptr)) (Xen_to_C_XmDestinationCallbackStruct(ptr))->operation = Xen_integer_to_C_int(val); else if (Xen_is_XmDropProcCallbackStruct(ptr)) (Xen_to_C_XmDropProcCallbackStruct(ptr))->operation = Xen_integer_to_C_int(val); else if (Xen_is_XmDragProcCallbackStruct(ptr)) (Xen_to_C_XmDragProcCallbackStruct(ptr))->operation = Xen_integer_to_C_int(val); else if (Xen_is_XmDropFinishCallbackStruct(ptr)) (Xen_to_C_XmDropFinishCallbackStruct(ptr))->operation = Xen_integer_to_C_int(val); else if (Xen_is_XmDropStartCallbackStruct(ptr)) (Xen_to_C_XmDropStartCallbackStruct(ptr))->operation = Xen_integer_to_C_int(val); else if (Xen_is_XmOperationChangedCallbackStruct(ptr)) (Xen_to_C_XmOperationChangedCallbackStruct(ptr))->operation = Xen_integer_to_C_int(val); else if (Xen_is_XmDragMotionCallbackStruct(ptr)) (Xen_to_C_XmDragMotionCallbackStruct(ptr))->operation = Xen_integer_to_C_int(val); else if (Xen_is_XmDropSiteEnterCallbackStruct(ptr)) (Xen_to_C_XmDropSiteEnterCallbackStruct(ptr))->operation = Xen_integer_to_C_int(val); else XM_set_field_assert_type(0, ptr, 1, "operation", "a struct with an operation field"); return(val); } static Xen gxm_timeStamp(Xen ptr) { if (Xen_is_XmDropProcCallbackStruct(ptr)) return(C_to_Xen_Time((Time)((Xen_to_C_XmDropProcCallbackStruct(ptr))->timeStamp))); if (Xen_is_XmDragProcCallbackStruct(ptr)) return(C_to_Xen_Time((Time)((Xen_to_C_XmDragProcCallbackStruct(ptr))->timeStamp))); if (Xen_is_XmDragDropFinishCallbackStruct(ptr)) return(C_to_Xen_Time((Time)((Xen_to_C_XmDragDropFinishCallbackStruct(ptr))->timeStamp))); if (Xen_is_XmDropFinishCallbackStruct(ptr)) return(C_to_Xen_Time((Time)((Xen_to_C_XmDropFinishCallbackStruct(ptr))->timeStamp))); if (Xen_is_XmDropStartCallbackStruct(ptr)) return(C_to_Xen_Time((Time)((Xen_to_C_XmDropStartCallbackStruct(ptr))->timeStamp))); if (Xen_is_XmOperationChangedCallbackStruct(ptr)) return(C_to_Xen_Time((Time)((Xen_to_C_XmOperationChangedCallbackStruct(ptr))->timeStamp))); if (Xen_is_XmDragMotionCallbackStruct(ptr)) return(C_to_Xen_Time((Time)((Xen_to_C_XmDragMotionCallbackStruct(ptr))->timeStamp))); if (Xen_is_XmDropSiteLeaveCallbackStruct(ptr)) return(C_to_Xen_Time((Time)((Xen_to_C_XmDropSiteLeaveCallbackStruct(ptr))->timeStamp))); if (Xen_is_XmDropSiteEnterCallbackStruct(ptr)) return(C_to_Xen_Time((Time)((Xen_to_C_XmDropSiteEnterCallbackStruct(ptr))->timeStamp))); if (Xen_is_XmTopLevelEnterCallbackStruct(ptr)) return(C_to_Xen_Time((Time)((Xen_to_C_XmTopLevelEnterCallbackStruct(ptr))->timeStamp))); if (Xen_is_XmTopLevelLeaveCallbackStruct(ptr)) return(C_to_Xen_Time((Time)((Xen_to_C_XmTopLevelLeaveCallbackStruct(ptr))->timeStamp))); XM_field_assert_type(0, ptr, 1, "timeStamp", "a struct with a timeStamp field"); return(Xen_false); } static Xen gxm_reason(Xen ptr) { XM_field_assert_type(Xen_is_AnyCallbackStruct(ptr), ptr, 1, "reason", "a callbackstruct"); return(C_int_to_Xen_integer((int)((Xen_to_C_XmAnyCallbackStruct(ptr))->reason))); } static Xen gxm_set_reason(Xen ptr, Xen val) { XM_set_field_assert_type(Xen_is_integer(val), val, 2, "reason", "integer"); XM_set_field_assert_type(Xen_is_AnyCallbackStruct(ptr), ptr, 1, "reason", "a callbackstruct"); (Xen_to_C_XmAnyCallbackStruct(ptr))->reason = Xen_integer_to_C_int(val); return(val); } static Xen gxm_direction(Xen ptr) { XM_field_assert_type(Xen_is_XmTraverseObscuredCallbackStruct(ptr), ptr, 1, "direction", "XmTraverseObscuredCallbackStruct"); return(C_int_to_Xen_integer((int)((Xen_to_C_XmTraverseObscuredCallbackStruct(ptr))->direction))); } static Xen gxm_dragProtocolStyle(Xen ptr) { XM_field_assert_type(Xen_is_XmTopLevelEnterCallbackStruct(ptr), ptr, 1, "dragProtocolStyle", "XmTopLevelEnterCallbackStruct"); return(C_int_to_Xen_integer((int)((Xen_to_C_XmTopLevelEnterCallbackStruct(ptr))->dragProtocolStyle))); } static Xen gxm_traversal_destination(Xen ptr) { XM_field_assert_type(Xen_is_XmTraverseObscuredCallbackStruct(ptr), ptr, 1, "traversal_destination", "XmTraverseObscuredCallbackStruct"); return(C_to_Xen_Widget((Widget)((Xen_to_C_XmTraverseObscuredCallbackStruct(ptr))->traversal_destination))); } static Xen gxm_minor_tab_widget(Xen ptr) { XM_field_assert_type(Xen_is_XmNotebookPageInfo(ptr), ptr, 1, "minor_tab_widget", "XmNotebookPageInfo"); return(C_to_Xen_Widget((Widget)((Xen_to_C_XmNotebookPageInfo(ptr))->minor_tab_widget))); } static Xen gxm_major_tab_widget(Xen ptr) { XM_field_assert_type(Xen_is_XmNotebookPageInfo(ptr), ptr, 1, "major_tab_widget", "XmNotebookPageInfo"); return(C_to_Xen_Widget((Widget)((Xen_to_C_XmNotebookPageInfo(ptr))->major_tab_widget))); } static Xen gxm_status_area_widget(Xen ptr) { XM_field_assert_type(Xen_is_XmNotebookPageInfo(ptr), ptr, 1, "status_area_widget", "XmNotebookPageInfo"); return(C_to_Xen_Widget((Widget)((Xen_to_C_XmNotebookPageInfo(ptr))->status_area_widget))); } static Xen gxm_page_widget(Xen ptr) { XM_field_assert_type(Xen_is_XmNotebookCallbackStruct(ptr) || Xen_is_XmNotebookPageInfo(ptr), ptr, 1, "page_widget", "a struct with a page_widget field"); if (Xen_is_XmNotebookCallbackStruct(ptr)) return(C_to_Xen_Widget((Widget)((Xen_to_C_XmNotebookCallbackStruct(ptr))->page_widget))); return(C_to_Xen_Widget((Widget)((Xen_to_C_XmNotebookPageInfo(ptr))->page_widget))); } static Xen gxm_page_number(Xen ptr) { XM_field_assert_type(Xen_is_XmNotebookCallbackStruct(ptr) || Xen_is_XmNotebookPageInfo(ptr), ptr, 1, "page_number", "a struct with a page_number field"); if (Xen_is_XmNotebookCallbackStruct(ptr)) return(C_int_to_Xen_integer((int)((Xen_to_C_XmNotebookCallbackStruct(ptr))->page_number))); return(C_int_to_Xen_integer((int)((Xen_to_C_XmNotebookPageInfo(ptr))->page_number))); } Xen_wrap_3_args(gxm_XtSetArg_w, gxm_XtSetArg) Xen_wrap_2_optional_args(gxm_XtManageChildren_w, gxm_XtManageChildren) Xen_wrap_1_arg(gxm_XtManageChild_w, gxm_XtManageChild) Xen_wrap_2_optional_args(gxm_XtUnmanageChildren_w, gxm_XtUnmanageChildren) Xen_wrap_1_arg(gxm_XtUnmanageChild_w, gxm_XtUnmanageChild) Xen_wrap_1_arg(gxm_XtDispatchEvent_w, gxm_XtDispatchEvent) Xen_wrap_2_args(gxm_XtCallAcceptFocus_w, gxm_XtCallAcceptFocus) Xen_wrap_1_arg(gxm_XtAppPeekEvent_w, gxm_XtAppPeekEvent) Xen_wrap_2_args(gxm_XtIsSubclass_w, gxm_XtIsSubclass) Xen_wrap_2_args(gxm_XtAppSetFallbackResources_w, gxm_XtAppSetFallbackResources) Xen_wrap_1_arg(gxm_XtIsObject_w, gxm_XtIsObject) Xen_wrap_1_arg(gxm_XtIsManaged_w, gxm_XtIsManaged) Xen_wrap_1_arg(gxm_XtIsRealized_w, gxm_XtIsRealized) Xen_wrap_1_arg(gxm_XtIsSensitive_w, gxm_XtIsSensitive) Xen_wrap_6_args(gxm_XtOwnSelection_w, gxm_XtOwnSelection) Xen_wrap_8_args(gxm_XtOwnSelectionIncremental_w, gxm_XtOwnSelectionIncremental) Xen_wrap_3_args(gxm_XtMakeResizeRequest_w, gxm_XtMakeResizeRequest) Xen_wrap_3_args(gxm_XtTranslateCoords_w, gxm_XtTranslateCoords) Xen_wrap_2_args(gxm_XtKeysymToKeycodeList_w, gxm_XtKeysymToKeycodeList) Xen_wrap_1_arg(gxm_XtParseTranslationTable_w, gxm_XtParseTranslationTable) Xen_wrap_1_arg(gxm_XtParseAcceleratorTable_w, gxm_XtParseAcceleratorTable) Xen_wrap_2_args(gxm_XtOverrideTranslations_w, gxm_XtOverrideTranslations) Xen_wrap_2_args(gxm_XtAugmentTranslations_w, gxm_XtAugmentTranslations) Xen_wrap_2_args(gxm_XtInstallAccelerators_w, gxm_XtInstallAccelerators) Xen_wrap_2_args(gxm_XtInstallAllAccelerators_w, gxm_XtInstallAllAccelerators) Xen_wrap_1_arg(gxm_XtUninstallTranslations_w, gxm_XtUninstallTranslations) Xen_wrap_2_args(gxm_XtAppAddActions_w, gxm_XtAppAddActions) Xen_wrap_3_optional_args(gxm_XtAppAddActionHook_w, gxm_XtAppAddActionHook) Xen_wrap_1_arg(gxm_XtRemoveActionHook_w, gxm_XtRemoveActionHook) Xen_wrap_1_arg(gxm_XtGetActionList_w, gxm_XtGetActionList) Xen_wrap_5_optional_args(gxm_XtCallActionProc_w, gxm_XtCallActionProc) Xen_wrap_5_args(gxm_XtRegisterGrabAction_w, gxm_XtRegisterGrabAction) Xen_wrap_2_args(gxm_XtSetMultiClickTime_w, gxm_XtSetMultiClickTime) Xen_wrap_1_arg(gxm_XtGetMultiClickTime_w, gxm_XtGetMultiClickTime) Xen_wrap_1_arg(gxm_XtGetResourceList_w, gxm_XtGetResourceList) Xen_wrap_1_arg(gxm_XtGetActionKeysym_w, gxm_XtGetActionKeysym) Xen_wrap_3_args(gxm_XtTranslateKeycode_w, gxm_XtTranslateKeycode) Xen_wrap_3_args(gxm_XtTranslateKey_w, gxm_XtTranslateKey) Xen_wrap_2_args(gxm_XtSetKeyTranslator_w, gxm_XtSetKeyTranslator) Xen_wrap_4_args(gxm_XtRegisterCaseConverter_w, gxm_XtRegisterCaseConverter) Xen_wrap_2_args(gxm_XtConvertCase_w, gxm_XtConvertCase) Xen_wrap_5_optional_args(gxm_XtAddEventHandler_w, gxm_XtAddEventHandler) Xen_wrap_5_args(gxm_XtRemoveEventHandler_w, gxm_XtRemoveEventHandler) Xen_wrap_5_args(gxm_XtAddRawEventHandler_w, gxm_XtAddRawEventHandler) Xen_wrap_5_args(gxm_XtRemoveRawEventHandler_w, gxm_XtRemoveRawEventHandler) Xen_wrap_6_args(gxm_XtInsertEventHandler_w, gxm_XtInsertEventHandler) Xen_wrap_6_args(gxm_XtInsertRawEventHandler_w, gxm_XtInsertRawEventHandler) Xen_wrap_2_args(gxm_XtDispatchEventToWidget_w, gxm_XtDispatchEventToWidget) Xen_wrap_1_arg(gxm_XtBuildEventMask_w, gxm_XtBuildEventMask) Xen_wrap_3_args(gxm_XtAddGrab_w, gxm_XtAddGrab) Xen_wrap_1_arg(gxm_XtRemoveGrab_w, gxm_XtRemoveGrab) Xen_wrap_2_args(gxm_XtAppProcessEvent_w, gxm_XtAppProcessEvent) Xen_wrap_1_arg(gxm_XtAppMainLoop_w, gxm_XtAppMainLoop) Xen_wrap_2_args(gxm_XtAddExposureToRegion_w, gxm_XtAddExposureToRegion) Xen_wrap_2_args(gxm_XtSetKeyboardFocus_w, gxm_XtSetKeyboardFocus) Xen_wrap_1_arg(gxm_XtGetKeyboardFocusWidget_w, gxm_XtGetKeyboardFocusWidget) Xen_wrap_1_arg(gxm_XtLastEventProcessed_w, gxm_XtLastEventProcessed) Xen_wrap_1_arg(gxm_XtLastTimestampProcessed_w, gxm_XtLastTimestampProcessed) Xen_wrap_4_optional_args(gxm_XtAppAddTimeOut_w, gxm_XtAppAddTimeOut) Xen_wrap_1_arg(gxm_XtRemoveTimeOut_w, gxm_XtRemoveTimeOut) Xen_wrap_5_optional_args(gxm_XtAppAddInput_w, gxm_XtAppAddInput) Xen_wrap_1_arg(gxm_XtRemoveInput_w, gxm_XtRemoveInput) Xen_wrap_1_arg(gxm_XtAppNextEvent_w, gxm_XtAppNextEvent) Xen_wrap_1_arg(gxm_XtAppPending_w, gxm_XtAppPending) Xen_wrap_1_arg(gxm_XtRealizeWidget_w, gxm_XtRealizeWidget) Xen_wrap_1_arg(gxm_XtUnrealizeWidget_w, gxm_XtUnrealizeWidget) Xen_wrap_1_arg(gxm_XtDestroyWidget_w, gxm_XtDestroyWidget) Xen_wrap_2_args(gxm_XtSetSensitive_w, gxm_XtSetSensitive) Xen_wrap_2_args(gxm_XtNameToWidget_w, gxm_XtNameToWidget) Xen_wrap_2_args(gxm_XtWindowToWidget_w, gxm_XtWindowToWidget) Xen_wrap_4_args(gxm_XtMergeArgLists_w, gxm_XtMergeArgLists) Xen_wrap_2_args(gxm_XtVaCreateArgsList_w, gxm_XtVaCreateArgsList) Xen_wrap_1_arg(gxm_XtDisplay_w, gxm_XtDisplay) Xen_wrap_1_arg(gxm_XtDisplayOfObject_w, gxm_XtDisplayOfObject) Xen_wrap_1_arg(gxm_XtScreen_w, gxm_XtScreen) Xen_wrap_1_arg(gxm_XtScreenOfObject_w, gxm_XtScreenOfObject) Xen_wrap_1_arg(gxm_XtWindow_w, gxm_XtWindow) Xen_wrap_1_arg(gxm_XtWindowOfObject_w, gxm_XtWindowOfObject) Xen_wrap_1_arg(gxm_XtName_w, gxm_XtName) Xen_wrap_1_arg(gxm_XtSuperclass_w, gxm_XtSuperclass) Xen_wrap_1_arg(gxm_XtClass_w, gxm_XtClass) Xen_wrap_1_arg(gxm_XtParent_w, gxm_XtParent) Xen_wrap_4_optional_args(gxm_XtAddCallback_w, gxm_XtAddCallback) Xen_wrap_3_args(gxm_XtRemoveCallback_w, gxm_XtRemoveCallback) Xen_wrap_3_args(gxm_XtAddCallbacks_w, gxm_XtAddCallbacks) Xen_wrap_3_args(gxm_XtRemoveCallbacks_w, gxm_XtRemoveCallbacks) Xen_wrap_2_args(gxm_XtRemoveAllCallbacks_w, gxm_XtRemoveAllCallbacks) Xen_wrap_3_args(gxm_XtCallCallbacks_w, gxm_XtCallCallbacks) Xen_wrap_2_args(gxm_XtHasCallbacks_w, gxm_XtHasCallbacks) Xen_wrap_5_optional_args(gxm_XtCreatePopupShell_w, gxm_XtCreatePopupShell) Xen_wrap_4_args(gxm_XtVaCreatePopupShell_w, gxm_XtVaCreatePopupShell) Xen_wrap_2_args(gxm_XtPopup_w, gxm_XtPopup) Xen_wrap_1_arg(gxm_XtPopupSpringLoaded_w, gxm_XtPopupSpringLoaded) Xen_wrap_3_args(gxm_XtCallbackNone_w, gxm_XtCallbackNone) Xen_wrap_3_args(gxm_XtCallbackNonexclusive_w, gxm_XtCallbackNonexclusive) Xen_wrap_3_args(gxm_XtCallbackExclusive_w, gxm_XtCallbackExclusive) Xen_wrap_1_arg(gxm_XtPopdown_w, gxm_XtPopdown) Xen_wrap_3_args(gxm_XtCallbackPopdown_w, gxm_XtCallbackPopdown) Xen_wrap_5_optional_args(gxm_XtCreateWidget_w, gxm_XtCreateWidget) Xen_wrap_5_optional_args(gxm_XtCreateManagedWidget_w, gxm_XtCreateManagedWidget) Xen_wrap_4_args(gxm_XtVaCreateWidget_w, gxm_XtVaCreateWidget) Xen_wrap_4_args(gxm_XtVaCreateManagedWidget_w, gxm_XtVaCreateManagedWidget) Xen_wrap_6_optional_args(gxm_XtAppCreateShell_w, gxm_XtAppCreateShell) Xen_wrap_5_args(gxm_XtVaAppCreateShell_w, gxm_XtVaAppCreateShell) Xen_wrap_no_args(gxm_XtToolkitInitialize_w, gxm_XtToolkitInitialize) Xen_wrap_3_args(gxm_XtSetLanguageProc_w, gxm_XtSetLanguageProc) Xen_wrap_6_args(gxm_XtDisplayInitialize_w, gxm_XtDisplayInitialize) Xen_wrap_6_optional_args(gxm_XtOpenApplication_w, gxm_XtOpenApplication) Xen_wrap_6_optional_args(gxm_XtVaOpenApplication_w, gxm_XtVaOpenApplication) Xen_wrap_5_optional_args(gxm_XtAppInitialize_w, gxm_XtAppInitialize) Xen_wrap_5_optional_args(gxm_XtVaAppInitialize_w, gxm_XtVaAppInitialize) Xen_wrap_6_args(gxm_XtOpenDisplay_w, gxm_XtOpenDisplay) Xen_wrap_no_args(gxm_XtCreateApplicationContext_w, gxm_XtCreateApplicationContext) Xen_wrap_1_arg(gxm_XtDestroyApplicationContext_w, gxm_XtDestroyApplicationContext) Xen_wrap_1_arg(gxm_XtInitializeWidgetClass_w, gxm_XtInitializeWidgetClass) Xen_wrap_1_arg(gxm_XtWidgetToApplicationContext_w, gxm_XtWidgetToApplicationContext) Xen_wrap_1_arg(gxm_XtDisplayToApplicationContext_w, gxm_XtDisplayToApplicationContext) Xen_wrap_1_arg(gxm_XtCloseDisplay_w, gxm_XtCloseDisplay) Xen_wrap_3_optional_args(gxm_XtSetValues_w, gxm_XtSetValues) Xen_wrap_2_args(gxm_XtVaSetValues_w, gxm_XtVaSetValues) Xen_wrap_3_optional_args(gxm_XtGetValues_w, gxm_XtGetValues) Xen_wrap_2_args(gxm_XtVaGetValues_w, gxm_XtVaGetValues) Xen_wrap_2_args(gxm_XtAppSetErrorMsgHandler_w, gxm_XtAppSetErrorMsgHandler) Xen_wrap_2_args(gxm_XtAppSetWarningMsgHandler_w, gxm_XtAppSetWarningMsgHandler) Xen_wrap_7_args(gxm_XtAppErrorMsg_w, gxm_XtAppErrorMsg) Xen_wrap_7_args(gxm_XtAppWarningMsg_w, gxm_XtAppWarningMsg) Xen_wrap_2_args(gxm_XtAppSetErrorHandler_w, gxm_XtAppSetErrorHandler) Xen_wrap_2_args(gxm_XtAppSetWarningHandler_w, gxm_XtAppSetWarningHandler) Xen_wrap_2_args(gxm_XtAppError_w, gxm_XtAppError) Xen_wrap_1_arg(gxm_XtMalloc_w, gxm_XtMalloc) Xen_wrap_2_args(gxm_XtCalloc_w, gxm_XtCalloc) Xen_wrap_2_args(gxm_XtRealloc_w, gxm_XtRealloc) Xen_wrap_1_arg(gxm_XtFree_w, gxm_XtFree) Xen_wrap_3_optional_args(gxm_XtAppAddWorkProc_w, gxm_XtAppAddWorkProc) Xen_wrap_1_arg(gxm_XtRemoveWorkProc_w, gxm_XtRemoveWorkProc) Xen_wrap_3_args(gxm_XtGetGC_w, gxm_XtGetGC) Xen_wrap_6_args(gxm_XtAllocateGC_w, gxm_XtAllocateGC) Xen_wrap_1_arg(gxm_XtDestroyGC_w, gxm_XtDestroyGC) Xen_wrap_2_args(gxm_XtReleaseGC_w, gxm_XtReleaseGC) Xen_wrap_4_args(gxm_XtFindFile_w, gxm_XtFindFile) Xen_wrap_8_args(gxm_XtResolvePathname_w, gxm_XtResolvePathname) Xen_wrap_3_args(gxm_XtDisownSelection_w, gxm_XtDisownSelection) Xen_wrap_6_args(gxm_XtGetSelectionValue_w, gxm_XtGetSelectionValue) Xen_wrap_7_args(gxm_XtGetSelectionValues_w, gxm_XtGetSelectionValues) Xen_wrap_2_args(gxm_XtAppSetSelectionTimeout_w, gxm_XtAppSetSelectionTimeout) Xen_wrap_1_arg(gxm_XtAppGetSelectionTimeout_w, gxm_XtAppGetSelectionTimeout) Xen_wrap_3_args(gxm_XtGetSelectionRequest_w, gxm_XtGetSelectionRequest) Xen_wrap_6_args(gxm_XtGetSelectionValueIncremental_w, gxm_XtGetSelectionValueIncremental) Xen_wrap_7_args(gxm_XtGetSelectionValuesIncremental_w, gxm_XtGetSelectionValuesIncremental) Xen_wrap_2_args(gxm_XtCreateSelectionRequest_w, gxm_XtCreateSelectionRequest) Xen_wrap_3_args(gxm_XtSendSelectionRequest_w, gxm_XtSendSelectionRequest) Xen_wrap_2_args(gxm_XtCancelSelectionRequest_w, gxm_XtCancelSelectionRequest) Xen_wrap_6_args(gxm_XtGrabKey_w, gxm_XtGrabKey) Xen_wrap_3_args(gxm_XtUngrabKey_w, gxm_XtUngrabKey) Xen_wrap_5_args(gxm_XtGrabKeyboard_w, gxm_XtGrabKeyboard) Xen_wrap_2_args(gxm_XtUngrabKeyboard_w, gxm_XtUngrabKeyboard) Xen_wrap_9_args(gxm_XtGrabButton_w, gxm_XtGrabButton) Xen_wrap_3_args(gxm_XtUngrabButton_w, gxm_XtUngrabButton) Xen_wrap_8_args(gxm_XtGrabPointer_w, gxm_XtGrabPointer) Xen_wrap_2_args(gxm_XtUngrabPointer_w, gxm_XtUngrabPointer) Xen_wrap_1_arg(gxm_XtGetApplicationNameAndClass_w, gxm_XtGetApplicationNameAndClass) Xen_wrap_1_arg(gxm_XtGetDisplays_w, gxm_XtGetDisplays) Xen_wrap_no_args(gxm_XtToolkitThreadInitialize_w, gxm_XtToolkitThreadInitialize) Xen_wrap_1_arg(gxm_XtAppLock_w, gxm_XtAppLock) Xen_wrap_1_arg(gxm_XtAppUnlock_w, gxm_XtAppUnlock) Xen_wrap_1_arg(gxm_XtIsRectObj_w, gxm_XtIsRectObj) Xen_wrap_1_arg(gxm_XtIsWidget_w, gxm_XtIsWidget) Xen_wrap_1_arg(gxm_XtIsComposite_w, gxm_XtIsComposite) Xen_wrap_1_arg(gxm_XtIsConstraint_w, gxm_XtIsConstraint) Xen_wrap_1_arg(gxm_XtIsShell_w, gxm_XtIsShell) Xen_wrap_1_arg(gxm_XtIsOverrideShell_w, gxm_XtIsOverrideShell) Xen_wrap_1_arg(gxm_XtIsWMShell_w, gxm_XtIsWMShell) Xen_wrap_1_arg(gxm_XtIsVendorShell_w, gxm_XtIsVendorShell) Xen_wrap_1_arg(gxm_XtIsTransientShell_w, gxm_XtIsTransientShell) Xen_wrap_1_arg(gxm_XtIsTopLevelShell_w, gxm_XtIsTopLevelShell) Xen_wrap_1_arg(gxm_XtIsApplicationShell_w, gxm_XtIsApplicationShell) Xen_wrap_1_arg(gxm_XtIsSessionShell_w, gxm_XtIsSessionShell) Xen_wrap_1_arg(gxm_XtMapWidget_w, gxm_XtMapWidget) Xen_wrap_1_arg(gxm_XtUnmapWidget_w, gxm_XtUnmapWidget) Xen_wrap_2_args(gxm_XLoadQueryFont_w, gxm_XLoadQueryFont) Xen_wrap_2_args(gxm_XQueryFont_w, gxm_XQueryFont) Xen_wrap_4_args(gxm_XGetMotionEvents_w, gxm_XGetMotionEvents) Xen_wrap_3_args(gxm_XDeleteModifiermapEntry_w, gxm_XDeleteModifiermapEntry) Xen_wrap_1_arg(gxm_XGetModifierMapping_w, gxm_XGetModifierMapping) Xen_wrap_3_args(gxm_XInsertModifiermapEntry_w, gxm_XInsertModifiermapEntry) Xen_wrap_1_arg(gxm_XNewModifiermap_w, gxm_XNewModifiermap) Xen_wrap_any_args(gxm_XCreateImage_w, gxm_XCreateImage) Xen_wrap_8_args(gxm_XGetImage_w, gxm_XGetImage) Xen_wrap_any_args(gxm_XGetSubImage_w, gxm_XGetSubImage) Xen_wrap_1_arg(gxm_XOpenDisplay_w, gxm_XOpenDisplay) Xen_wrap_1_arg(gxm_XFetchBytes_w, gxm_XFetchBytes) Xen_wrap_2_args(gxm_XFetchBuffer_w, gxm_XFetchBuffer) Xen_wrap_2_args(gxm_XGetAtomName_w, gxm_XGetAtomName) Xen_wrap_1_arg(gxm_XDisplayName_w, gxm_XDisplayName) Xen_wrap_1_arg(gxm_XKeysymToString_w, gxm_XKeysymToString) Xen_wrap_2_args(gxm_XSynchronize_w, gxm_XSynchronize) Xen_wrap_2_args(gxm_XSetAfterFunction_w, gxm_XSetAfterFunction) Xen_wrap_3_args(gxm_XInternAtom_w, gxm_XInternAtom) Xen_wrap_2_args(gxm_XCopyColormapAndFree_w, gxm_XCopyColormapAndFree) Xen_wrap_4_args(gxm_XCreateColormap_w, gxm_XCreateColormap) Xen_wrap_7_args(gxm_XCreatePixmapCursor_w, gxm_XCreatePixmapCursor) Xen_wrap_7_args(gxm_XCreateGlyphCursor_w, gxm_XCreateGlyphCursor) Xen_wrap_2_args(gxm_XCreateFontCursor_w, gxm_XCreateFontCursor) Xen_wrap_2_args(gxm_XLoadFont_w, gxm_XLoadFont) Xen_wrap_4_args(gxm_XCreateGC_w, gxm_XCreateGC) Xen_wrap_2_args(gxm_XFlushGC_w, gxm_XFlushGC) Xen_wrap_5_args(gxm_XCreatePixmap_w, gxm_XCreatePixmap) Xen_wrap_5_args(gxm_XCreateBitmapFromData_w, gxm_XCreateBitmapFromData) Xen_wrap_8_args(gxm_XCreatePixmapFromBitmapData_w, gxm_XCreatePixmapFromBitmapData) Xen_wrap_9_args(gxm_XCreateSimpleWindow_w, gxm_XCreateSimpleWindow) Xen_wrap_2_args(gxm_XGetSelectionOwner_w, gxm_XGetSelectionOwner) Xen_wrap_any_args(gxm_XCreateWindow_w, gxm_XCreateWindow) Xen_wrap_2_args(gxm_XListInstalledColormaps_w, gxm_XListInstalledColormaps) Xen_wrap_3_args(gxm_XListFonts_w, gxm_XListFonts) Xen_wrap_3_args(gxm_XListFontsWithInfo_w, gxm_XListFontsWithInfo) Xen_wrap_1_arg(gxm_XGetFontPath_w, gxm_XGetFontPath) Xen_wrap_1_arg(gxm_XListExtensions_w, gxm_XListExtensions) Xen_wrap_2_args(gxm_XListProperties_w, gxm_XListProperties) #if 0 Xen_wrap_3_args(gxm_XKeycodeToKeysym_w, gxm_XKeycodeToKeysym) #endif Xen_wrap_2_args(gxm_XLookupKeysym_w, gxm_XLookupKeysym) Xen_wrap_3_args(gxm_XGetKeyboardMapping_w, gxm_XGetKeyboardMapping) Xen_wrap_1_arg(gxm_XStringToKeysym_w, gxm_XStringToKeysym) Xen_wrap_1_arg(gxm_XMaxRequestSize_w, gxm_XMaxRequestSize) Xen_wrap_1_arg(gxm_XExtendedMaxRequestSize_w, gxm_XExtendedMaxRequestSize) Xen_wrap_1_arg(gxm_XDisplayMotionBufferSize_w, gxm_XDisplayMotionBufferSize) Xen_wrap_1_arg(gxm_XVisualIDFromVisual_w, gxm_XVisualIDFromVisual) Xen_wrap_2_args(gxm_XRootWindow_w, gxm_XRootWindow) Xen_wrap_1_arg(gxm_XDefaultRootWindow_w, gxm_XDefaultRootWindow) Xen_wrap_1_arg(gxm_XRootWindowOfScreen_w, gxm_XRootWindowOfScreen) Xen_wrap_2_args(gxm_XDefaultVisual_w, gxm_XDefaultVisual) Xen_wrap_1_arg(gxm_XDefaultVisualOfScreen_w, gxm_XDefaultVisualOfScreen) Xen_wrap_2_args(gxm_XDefaultGC_w, gxm_XDefaultGC) Xen_wrap_1_arg(gxm_XDefaultGCOfScreen_w, gxm_XDefaultGCOfScreen) Xen_wrap_2_args(gxm_XBlackPixel_w, gxm_XBlackPixel) Xen_wrap_2_args(gxm_XWhitePixel_w, gxm_XWhitePixel) Xen_wrap_no_args(gxm_XAllPlanes_w, gxm_XAllPlanes) Xen_wrap_1_arg(gxm_XBlackPixelOfScreen_w, gxm_XBlackPixelOfScreen) Xen_wrap_1_arg(gxm_XWhitePixelOfScreen_w, gxm_XWhitePixelOfScreen) Xen_wrap_1_arg(gxm_XNextRequest_w, gxm_XNextRequest) Xen_wrap_1_arg(gxm_XLastKnownRequestProcessed_w, gxm_XLastKnownRequestProcessed) Xen_wrap_1_arg(gxm_XServerVendor_w, gxm_XServerVendor) Xen_wrap_1_arg(gxm_XDisplayString_w, gxm_XDisplayString) Xen_wrap_2_args(gxm_XDefaultColormap_w, gxm_XDefaultColormap) Xen_wrap_1_arg(gxm_XDefaultColormapOfScreen_w, gxm_XDefaultColormapOfScreen) Xen_wrap_1_arg(gxm_XDisplayOfScreen_w, gxm_XDisplayOfScreen) Xen_wrap_2_args(gxm_XScreenOfDisplay_w, gxm_XScreenOfDisplay) Xen_wrap_1_arg(gxm_XDefaultScreenOfDisplay_w, gxm_XDefaultScreenOfDisplay) Xen_wrap_1_arg(gxm_XEventMaskOfScreen_w, gxm_XEventMaskOfScreen) Xen_wrap_1_arg(gxm_XScreenNumberOfScreen_w, gxm_XScreenNumberOfScreen) Xen_wrap_1_arg(gxm_XSetErrorHandler_w, gxm_XSetErrorHandler) Xen_wrap_1_arg(gxm_XSetIOErrorHandler_w, gxm_XSetIOErrorHandler) Xen_wrap_1_arg(gxm_XListPixmapFormats_w, gxm_XListPixmapFormats) Xen_wrap_2_args(gxm_XListDepths_w, gxm_XListDepths) Xen_wrap_5_args(gxm_XReconfigureWMWindow_w, gxm_XReconfigureWMWindow) Xen_wrap_2_args(gxm_XGetWMProtocols_w, gxm_XGetWMProtocols) Xen_wrap_4_args(gxm_XSetWMProtocols_w, gxm_XSetWMProtocols) Xen_wrap_3_args(gxm_XIconifyWindow_w, gxm_XIconifyWindow) Xen_wrap_3_args(gxm_XWithdrawWindow_w, gxm_XWithdrawWindow) Xen_wrap_2_args(gxm_XGetCommand_w, gxm_XGetCommand) Xen_wrap_2_args(gxm_XGetWMColormapWindows_w, gxm_XGetWMColormapWindows) Xen_wrap_4_args(gxm_XSetWMColormapWindows_w, gxm_XSetWMColormapWindows) Xen_wrap_3_args(gxm_XSetTransientForHint_w, gxm_XSetTransientForHint) Xen_wrap_1_arg(gxm_XActivateScreenSaver_w, gxm_XActivateScreenSaver) Xen_wrap_3_args(gxm_XAllocColor_w, gxm_XAllocColor) Xen_wrap_5_args(gxm_XAllocColorCells_w, gxm_XAllocColorCells) Xen_wrap_any_args(gxm_XAllocColorPlanes_w, gxm_XAllocColorPlanes) Xen_wrap_5_args(gxm_XAllocNamedColor_w, gxm_XAllocNamedColor) Xen_wrap_3_args(gxm_XAllowEvents_w, gxm_XAllowEvents) Xen_wrap_1_arg(gxm_XAutoRepeatOff_w, gxm_XAutoRepeatOff) Xen_wrap_1_arg(gxm_XAutoRepeatOn_w, gxm_XAutoRepeatOn) Xen_wrap_2_args(gxm_XBell_w, gxm_XBell) Xen_wrap_1_arg(gxm_XBitmapBitOrder_w, gxm_XBitmapBitOrder) Xen_wrap_1_arg(gxm_XBitmapPad_w, gxm_XBitmapPad) Xen_wrap_1_arg(gxm_XBitmapUnit_w, gxm_XBitmapUnit) Xen_wrap_1_arg(gxm_XCellsOfScreen_w, gxm_XCellsOfScreen) Xen_wrap_4_args(gxm_XChangeActivePointerGrab_w, gxm_XChangeActivePointerGrab) Xen_wrap_4_args(gxm_XChangeGC_w, gxm_XChangeGC) Xen_wrap_3_args(gxm_XChangeKeyboardControl_w, gxm_XChangeKeyboardControl) Xen_wrap_5_args(gxm_XChangeKeyboardMapping_w, gxm_XChangeKeyboardMapping) Xen_wrap_6_args(gxm_XChangePointerControl_w, gxm_XChangePointerControl) Xen_wrap_8_optional_args(gxm_XChangeProperty_w, gxm_XChangeProperty) Xen_wrap_4_args(gxm_XChangeWindowAttributes_w, gxm_XChangeWindowAttributes) Xen_wrap_3_args(gxm_XCheckIfEvent_w, gxm_XCheckIfEvent) Xen_wrap_2_args(gxm_XCheckMaskEvent_w, gxm_XCheckMaskEvent) Xen_wrap_2_args(gxm_XCheckTypedEvent_w, gxm_XCheckTypedEvent) Xen_wrap_3_args(gxm_XCheckTypedWindowEvent_w, gxm_XCheckTypedWindowEvent) Xen_wrap_3_args(gxm_XCheckWindowEvent_w, gxm_XCheckWindowEvent) Xen_wrap_3_args(gxm_XCirculateSubwindows_w, gxm_XCirculateSubwindows) Xen_wrap_2_args(gxm_XCirculateSubwindowsDown_w, gxm_XCirculateSubwindowsDown) Xen_wrap_2_args(gxm_XCirculateSubwindowsUp_w, gxm_XCirculateSubwindowsUp) Xen_wrap_7_args(gxm_XClearArea_w, gxm_XClearArea) Xen_wrap_2_args(gxm_XClearWindow_w, gxm_XClearWindow) Xen_wrap_1_arg(gxm_XCloseDisplay_w, gxm_XCloseDisplay) Xen_wrap_4_args(gxm_XConfigureWindow_w, gxm_XConfigureWindow) Xen_wrap_1_arg(gxm_XConnectionNumber_w, gxm_XConnectionNumber) Xen_wrap_6_args(gxm_XConvertSelection_w, gxm_XConvertSelection) Xen_wrap_any_args(gxm_XCopyArea_w, gxm_XCopyArea) Xen_wrap_4_args(gxm_XCopyGC_w, gxm_XCopyGC) Xen_wrap_any_args(gxm_XCopyPlane_w, gxm_XCopyPlane) Xen_wrap_2_args(gxm_XDefaultDepth_w, gxm_XDefaultDepth) Xen_wrap_1_arg(gxm_XDefaultDepthOfScreen_w, gxm_XDefaultDepthOfScreen) Xen_wrap_1_arg(gxm_XDefaultScreen_w, gxm_XDefaultScreen) Xen_wrap_3_args(gxm_XDefineCursor_w, gxm_XDefineCursor) Xen_wrap_3_args(gxm_XDeleteProperty_w, gxm_XDeleteProperty) Xen_wrap_2_args(gxm_XDestroyWindow_w, gxm_XDestroyWindow) Xen_wrap_2_args(gxm_XDestroySubwindows_w, gxm_XDestroySubwindows) Xen_wrap_1_arg(gxm_XDoesBackingStore_w, gxm_XDoesBackingStore) Xen_wrap_1_arg(gxm_XDoesSaveUnders_w, gxm_XDoesSaveUnders) Xen_wrap_1_arg(gxm_XDisableAccessControl_w, gxm_XDisableAccessControl) Xen_wrap_2_args(gxm_XDisplayCells_w, gxm_XDisplayCells) Xen_wrap_2_args(gxm_XDisplayHeight_w, gxm_XDisplayHeight) Xen_wrap_2_args(gxm_XDisplayHeightMM_w, gxm_XDisplayHeightMM) Xen_wrap_1_arg(gxm_XDisplayKeycodes_w, gxm_XDisplayKeycodes) Xen_wrap_2_args(gxm_XDisplayPlanes_w, gxm_XDisplayPlanes) Xen_wrap_2_args(gxm_XDisplayWidth_w, gxm_XDisplayWidth) Xen_wrap_2_args(gxm_XDisplayWidthMM_w, gxm_XDisplayWidthMM) Xen_wrap_9_args(gxm_XDrawArc_w, gxm_XDrawArc) Xen_wrap_5_args(gxm_XDrawArcs_w, gxm_XDrawArcs) Xen_wrap_7_args(gxm_XDrawImageString_w, gxm_XDrawImageString) Xen_wrap_7_args(gxm_XDrawLine_w, gxm_XDrawLine) Xen_wrap_6_args(gxm_XDrawLines_w, gxm_XDrawLines) Xen_wrap_6_args(gxm_XDrawLinesDirect_w, gxm_XDrawLinesDirect) Xen_wrap_1_arg(gxm_FreeXPoints_w, gxm_FreeXPoints) Xen_wrap_1_arg(gxm_Vector2XPoints_w, gxm_Vector2XPoints) Xen_wrap_5_args(gxm_XDrawPoint_w, gxm_XDrawPoint) Xen_wrap_6_args(gxm_XDrawPoints_w, gxm_XDrawPoints) Xen_wrap_7_args(gxm_XDrawRectangle_w, gxm_XDrawRectangle) Xen_wrap_5_args(gxm_XDrawRectangles_w, gxm_XDrawRectangles) Xen_wrap_5_args(gxm_XDrawSegments_w, gxm_XDrawSegments) Xen_wrap_7_args(gxm_XDrawString_w, gxm_XDrawString) Xen_wrap_7_optional_args(gxm_XDrawText_w, gxm_XDrawText) Xen_wrap_1_arg(gxm_XEnableAccessControl_w, gxm_XEnableAccessControl) Xen_wrap_2_args(gxm_XEventsQueued_w, gxm_XEventsQueued) Xen_wrap_2_args(gxm_XFetchName_w, gxm_XFetchName) Xen_wrap_9_args(gxm_XFillArc_w, gxm_XFillArc) Xen_wrap_5_args(gxm_XFillArcs_w, gxm_XFillArcs) Xen_wrap_7_args(gxm_XFillPolygon_w, gxm_XFillPolygon) Xen_wrap_7_args(gxm_XFillRectangle_w, gxm_XFillRectangle) Xen_wrap_5_args(gxm_XFillRectangles_w, gxm_XFillRectangles) Xen_wrap_1_arg(gxm_XFlush_w, gxm_XFlush) Xen_wrap_2_args(gxm_XForceScreenSaver_w, gxm_XForceScreenSaver) Xen_wrap_1_arg(gxm_XFree_w, gxm_XFree) Xen_wrap_2_args(gxm_XFreeColormap_w, gxm_XFreeColormap) Xen_wrap_5_args(gxm_XFreeColors_w, gxm_XFreeColors) Xen_wrap_2_args(gxm_XFreeCursor_w, gxm_XFreeCursor) Xen_wrap_1_arg(gxm_XFreeExtensionList_w, gxm_XFreeExtensionList) Xen_wrap_2_args(gxm_XFreeFont_w, gxm_XFreeFont) Xen_wrap_3_args(gxm_XFreeFontInfo_w, gxm_XFreeFontInfo) Xen_wrap_1_arg(gxm_XFreeFontNames_w, gxm_XFreeFontNames) Xen_wrap_1_arg(gxm_XFreeFontPath_w, gxm_XFreeFontPath) Xen_wrap_2_args(gxm_XFreeGC_w, gxm_XFreeGC) Xen_wrap_1_arg(gxm_XFreeModifiermap_w, gxm_XFreeModifiermap) Xen_wrap_2_args(gxm_XFreePixmap_w, gxm_XFreePixmap) Xen_wrap_any_args(gxm_XGeometry_w, gxm_XGeometry) Xen_wrap_4_args(gxm_XGetErrorText_w, gxm_XGetErrorText) Xen_wrap_2_args(gxm_XGetFontProperty_w, gxm_XGetFontProperty) Xen_wrap_3_args(gxm_XGetGCValues_w, gxm_XGetGCValues) Xen_wrap_no_args(gxm_XGCValues_w, gxm_XGCValues) Xen_wrap_1_optional_arg(gxm_XEvent_w, gxm_XEvent) Xen_wrap_2_args(gxm_XGetGeometry_w, gxm_XGetGeometry) Xen_wrap_2_args(gxm_XGetIconName_w, gxm_XGetIconName) Xen_wrap_1_arg(gxm_XGetInputFocus_w, gxm_XGetInputFocus) Xen_wrap_1_arg(gxm_XGetKeyboardControl_w, gxm_XGetKeyboardControl) Xen_wrap_1_arg(gxm_XGetPointerControl_w, gxm_XGetPointerControl) Xen_wrap_3_args(gxm_XGetPointerMapping_w, gxm_XGetPointerMapping) Xen_wrap_1_arg(gxm_XGetScreenSaver_w, gxm_XGetScreenSaver) Xen_wrap_2_args(gxm_XGetTransientForHint_w, gxm_XGetTransientForHint) Xen_wrap_any_args(gxm_XGetWindowProperty_w, gxm_XGetWindowProperty) Xen_wrap_2_args(gxm_XGetWindowAttributes_w, gxm_XGetWindowAttributes) Xen_wrap_any_args(gxm_XGrabButton_w, gxm_XGrabButton) Xen_wrap_7_args(gxm_XGrabKey_w, gxm_XGrabKey) Xen_wrap_6_args(gxm_XGrabKeyboard_w, gxm_XGrabKeyboard) Xen_wrap_9_args(gxm_XGrabPointer_w, gxm_XGrabPointer) Xen_wrap_1_arg(gxm_XGrabServer_w, gxm_XGrabServer) Xen_wrap_1_arg(gxm_XHeightMMOfScreen_w, gxm_XHeightMMOfScreen) Xen_wrap_1_arg(gxm_XHeightOfScreen_w, gxm_XHeightOfScreen) Xen_wrap_3_args(gxm_XIfEvent_w, gxm_XIfEvent) Xen_wrap_1_arg(gxm_XImageByteOrder_w, gxm_XImageByteOrder) Xen_wrap_2_args(gxm_XInstallColormap_w, gxm_XInstallColormap) Xen_wrap_2_args(gxm_XKeysymToKeycode_w, gxm_XKeysymToKeycode) Xen_wrap_2_args(gxm_XKillClient_w, gxm_XKillClient) Xen_wrap_5_args(gxm_XLookupColor_w, gxm_XLookupColor) Xen_wrap_2_args(gxm_XLowerWindow_w, gxm_XLowerWindow) Xen_wrap_2_args(gxm_XMapRaised_w, gxm_XMapRaised) Xen_wrap_2_args(gxm_XMapSubwindows_w, gxm_XMapSubwindows) Xen_wrap_2_args(gxm_XMapWindow_w, gxm_XMapWindow) Xen_wrap_2_args(gxm_XMaskEvent_w, gxm_XMaskEvent) Xen_wrap_1_arg(gxm_XMaxCmapsOfScreen_w, gxm_XMaxCmapsOfScreen) Xen_wrap_1_arg(gxm_XMinCmapsOfScreen_w, gxm_XMinCmapsOfScreen) Xen_wrap_6_args(gxm_XMoveResizeWindow_w, gxm_XMoveResizeWindow) Xen_wrap_4_args(gxm_XMoveWindow_w, gxm_XMoveWindow) Xen_wrap_1_arg(gxm_XNextEvent_w, gxm_XNextEvent) Xen_wrap_1_arg(gxm_XNoOp_w, gxm_XNoOp) Xen_wrap_4_args(gxm_XParseColor_w, gxm_XParseColor) Xen_wrap_1_arg(gxm_XParseGeometry_w, gxm_XParseGeometry) Xen_wrap_1_arg(gxm_XPeekEvent_w, gxm_XPeekEvent) Xen_wrap_3_args(gxm_XPeekIfEvent_w, gxm_XPeekIfEvent) Xen_wrap_1_arg(gxm_XPending_w, gxm_XPending) Xen_wrap_1_arg(gxm_XPlanesOfScreen_w, gxm_XPlanesOfScreen) Xen_wrap_1_arg(gxm_XProtocolRevision_w, gxm_XProtocolRevision) Xen_wrap_1_arg(gxm_XProtocolVersion_w, gxm_XProtocolVersion) Xen_wrap_2_args(gxm_XPutBackEvent_w, gxm_XPutBackEvent) Xen_wrap_any_args(gxm_XPutImage_w, gxm_XPutImage) Xen_wrap_1_arg(gxm_XQLength_w, gxm_XQLength) Xen_wrap_4_args(gxm_XQueryBestCursor_w, gxm_XQueryBestCursor) Xen_wrap_5_args(gxm_XQueryBestSize_w, gxm_XQueryBestSize) Xen_wrap_4_args(gxm_XQueryBestStipple_w, gxm_XQueryBestStipple) Xen_wrap_4_args(gxm_XQueryBestTile_w, gxm_XQueryBestTile) Xen_wrap_3_args(gxm_XQueryColor_w, gxm_XQueryColor) Xen_wrap_4_optional_args(gxm_XQueryColors_w, gxm_XQueryColors) Xen_wrap_2_args(gxm_XQueryExtension_w, gxm_XQueryExtension) Xen_wrap_1_arg(gxm_XQueryKeymap_w, gxm_XQueryKeymap) Xen_wrap_2_args(gxm_XQueryPointer_w, gxm_XQueryPointer) Xen_wrap_3_args(gxm_XQueryTextExtents_w, gxm_XQueryTextExtents) Xen_wrap_2_args(gxm_XQueryTree_w, gxm_XQueryTree) Xen_wrap_2_args(gxm_XRaiseWindow_w, gxm_XRaiseWindow) Xen_wrap_3_args(gxm_XReadBitmapFile_w, gxm_XReadBitmapFile) Xen_wrap_1_arg(gxm_XReadBitmapFileData_w, gxm_XReadBitmapFileData) Xen_wrap_6_args(gxm_XRebindKeysym_w, gxm_XRebindKeysym) Xen_wrap_4_args(gxm_XRecolorCursor_w, gxm_XRecolorCursor) Xen_wrap_1_arg(gxm_XRefreshKeyboardMapping_w, gxm_XRefreshKeyboardMapping) Xen_wrap_5_args(gxm_XReparentWindow_w, gxm_XReparentWindow) Xen_wrap_1_arg(gxm_XResetScreenSaver_w, gxm_XResetScreenSaver) Xen_wrap_4_args(gxm_XResizeWindow_w, gxm_XResizeWindow) Xen_wrap_3_args(gxm_XRestackWindows_w, gxm_XRestackWindows) Xen_wrap_2_args(gxm_XRotateBuffers_w, gxm_XRotateBuffers) Xen_wrap_5_args(gxm_XRotateWindowProperties_w, gxm_XRotateWindowProperties) Xen_wrap_1_arg(gxm_XScreenCount_w, gxm_XScreenCount) Xen_wrap_3_args(gxm_XSelectInput_w, gxm_XSelectInput) Xen_wrap_5_args(gxm_XSendEvent_w, gxm_XSendEvent) Xen_wrap_2_args(gxm_XSetAccessControl_w, gxm_XSetAccessControl) Xen_wrap_3_args(gxm_XSetArcMode_w, gxm_XSetArcMode) Xen_wrap_3_args(gxm_XSetBackground_w, gxm_XSetBackground) Xen_wrap_3_args(gxm_XSetClipMask_w, gxm_XSetClipMask) Xen_wrap_4_args(gxm_XSetClipOrigin_w, gxm_XSetClipOrigin) Xen_wrap_7_args(gxm_XSetClipRectangles_w, gxm_XSetClipRectangles) Xen_wrap_2_args(gxm_XSetCloseDownMode_w, gxm_XSetCloseDownMode) Xen_wrap_4_args(gxm_XSetCommand_w, gxm_XSetCommand) Xen_wrap_5_optional_args(gxm_XSetDashes_w, gxm_XSetDashes) Xen_wrap_3_args(gxm_XSetFillRule_w, gxm_XSetFillRule) Xen_wrap_3_args(gxm_XSetFillStyle_w, gxm_XSetFillStyle) Xen_wrap_3_args(gxm_XSetFont_w, gxm_XSetFont) Xen_wrap_3_args(gxm_XSetFontPath_w, gxm_XSetFontPath) Xen_wrap_3_args(gxm_XSetForeground_w, gxm_XSetForeground) Xen_wrap_3_args(gxm_XSetFunction_w, gxm_XSetFunction) Xen_wrap_3_args(gxm_XSetGraphicsExposures_w, gxm_XSetGraphicsExposures) Xen_wrap_3_args(gxm_XSetIconName_w, gxm_XSetIconName) Xen_wrap_4_args(gxm_XSetInputFocus_w, gxm_XSetInputFocus) Xen_wrap_6_args(gxm_XSetLineAttributes_w, gxm_XSetLineAttributes) Xen_wrap_2_args(gxm_XSetModifierMapping_w, gxm_XSetModifierMapping) Xen_wrap_3_args(gxm_XSetPlaneMask_w, gxm_XSetPlaneMask) Xen_wrap_3_optional_args(gxm_XSetPointerMapping_w, gxm_XSetPointerMapping) Xen_wrap_5_args(gxm_XSetScreenSaver_w, gxm_XSetScreenSaver) Xen_wrap_4_args(gxm_XSetSelectionOwner_w, gxm_XSetSelectionOwner) Xen_wrap_6_args(gxm_XSetState_w, gxm_XSetState) Xen_wrap_3_args(gxm_XSetStipple_w, gxm_XSetStipple) Xen_wrap_3_args(gxm_XSetSubwindowMode_w, gxm_XSetSubwindowMode) Xen_wrap_4_args(gxm_XSetTSOrigin_w, gxm_XSetTSOrigin) Xen_wrap_3_args(gxm_XSetTile_w, gxm_XSetTile) Xen_wrap_3_args(gxm_XSetWindowBackground_w, gxm_XSetWindowBackground) Xen_wrap_3_args(gxm_XSetWindowBackgroundPixmap_w, gxm_XSetWindowBackgroundPixmap) Xen_wrap_3_args(gxm_XSetWindowBorder_w, gxm_XSetWindowBorder) Xen_wrap_3_args(gxm_XSetWindowBorderPixmap_w, gxm_XSetWindowBorderPixmap) Xen_wrap_3_args(gxm_XSetWindowBorderWidth_w, gxm_XSetWindowBorderWidth) Xen_wrap_3_args(gxm_XSetWindowColormap_w, gxm_XSetWindowColormap) Xen_wrap_4_args(gxm_XStoreBuffer_w, gxm_XStoreBuffer) Xen_wrap_3_args(gxm_XStoreBytes_w, gxm_XStoreBytes) Xen_wrap_3_args(gxm_XStoreColor_w, gxm_XStoreColor) Xen_wrap_4_args(gxm_XStoreColors_w, gxm_XStoreColors) Xen_wrap_3_args(gxm_XStoreName_w, gxm_XStoreName) Xen_wrap_5_args(gxm_XStoreNamedColor_w, gxm_XStoreNamedColor) Xen_wrap_2_args(gxm_XSync_w, gxm_XSync) Xen_wrap_3_args(gxm_XTextExtents_w, gxm_XTextExtents) Xen_wrap_3_args(gxm_XTextWidth_w, gxm_XTextWidth) Xen_wrap_5_args(gxm_XTranslateCoordinates_w, gxm_XTranslateCoordinates) Xen_wrap_2_args(gxm_XUndefineCursor_w, gxm_XUndefineCursor) Xen_wrap_4_args(gxm_XUngrabButton_w, gxm_XUngrabButton) Xen_wrap_4_args(gxm_XUngrabKey_w, gxm_XUngrabKey) Xen_wrap_2_args(gxm_XUngrabKeyboard_w, gxm_XUngrabKeyboard) Xen_wrap_2_args(gxm_XUngrabPointer_w, gxm_XUngrabPointer) Xen_wrap_1_arg(gxm_XUngrabServer_w, gxm_XUngrabServer) Xen_wrap_2_args(gxm_XUninstallColormap_w, gxm_XUninstallColormap) Xen_wrap_2_args(gxm_XUnloadFont_w, gxm_XUnloadFont) Xen_wrap_2_args(gxm_XUnmapSubwindows_w, gxm_XUnmapSubwindows) Xen_wrap_2_args(gxm_XUnmapWindow_w, gxm_XUnmapWindow) Xen_wrap_1_arg(gxm_XVendorRelease_w, gxm_XVendorRelease) Xen_wrap_9_args(gxm_XWarpPointer_w, gxm_XWarpPointer) Xen_wrap_1_arg(gxm_XWidthMMOfScreen_w, gxm_XWidthMMOfScreen) Xen_wrap_1_arg(gxm_XWidthOfScreen_w, gxm_XWidthOfScreen) Xen_wrap_3_args(gxm_XWindowEvent_w, gxm_XWindowEvent) Xen_wrap_7_args(gxm_XWriteBitmapFile_w, gxm_XWriteBitmapFile) Xen_wrap_no_args(gxm_XSupportsLocale_w, gxm_XSupportsLocale) Xen_wrap_1_arg(gxm_XSetLocaleModifiers_w, gxm_XSetLocaleModifiers) Xen_wrap_2_args(gxm_XCreateFontSet_w, gxm_XCreateFontSet) Xen_wrap_2_args(gxm_XFreeFontSet_w, gxm_XFreeFontSet) Xen_wrap_1_arg(gxm_XFontsOfFontSet_w, gxm_XFontsOfFontSet) Xen_wrap_1_arg(gxm_XBaseFontNameListOfFontSet_w, gxm_XBaseFontNameListOfFontSet) Xen_wrap_1_arg(gxm_XLocaleOfFontSet_w, gxm_XLocaleOfFontSet) Xen_wrap_1_arg(gxm_XContextDependentDrawing_w, gxm_XContextDependentDrawing) Xen_wrap_1_arg(gxm_XDirectionalDependentDrawing_w, gxm_XDirectionalDependentDrawing) Xen_wrap_1_arg(gxm_XContextualDrawing_w, gxm_XContextualDrawing) Xen_wrap_2_args(gxm_XFilterEvent_w, gxm_XFilterEvent) Xen_wrap_no_args(gxm_XAllocIconSize_w, gxm_XAllocIconSize) Xen_wrap_no_args(gxm_XAllocStandardColormap_w, gxm_XAllocStandardColormap) Xen_wrap_no_args(gxm_XAllocWMHints_w, gxm_XAllocWMHints) Xen_wrap_1_arg(gxm_XClipBox_w, gxm_XClipBox) Xen_wrap_no_args(gxm_XCreateRegion_w, gxm_XCreateRegion) Xen_wrap_no_args(gxm_XDefaultString_w, gxm_XDefaultString) Xen_wrap_3_args(gxm_XDeleteContext_w, gxm_XDeleteContext) Xen_wrap_1_arg(gxm_XDestroyRegion_w, gxm_XDestroyRegion) Xen_wrap_1_arg(gxm_XEmptyRegion_w, gxm_XEmptyRegion) Xen_wrap_2_args(gxm_XEqualRegion_w, gxm_XEqualRegion) Xen_wrap_3_args(gxm_XFindContext_w, gxm_XFindContext) Xen_wrap_2_args(gxm_XGetIconSizes_w, gxm_XGetIconSizes) Xen_wrap_3_args(gxm_XGetRGBColormaps_w, gxm_XGetRGBColormaps) Xen_wrap_3_args(gxm_XGetVisualInfo_w, gxm_XGetVisualInfo) Xen_wrap_2_args(gxm_XGetWMHints_w, gxm_XGetWMHints) Xen_wrap_3_args(gxm_XIntersectRegion_w, gxm_XIntersectRegion) Xen_wrap_1_arg(gxm_XConvertCase_w, gxm_XConvertCase) Xen_wrap_1_arg(gxm_XLookupString_w, gxm_XLookupString) Xen_wrap_4_args(gxm_XMatchVisualInfo_w, gxm_XMatchVisualInfo) Xen_wrap_3_args(gxm_XOffsetRegion_w, gxm_XOffsetRegion) Xen_wrap_3_args(gxm_XPointInRegion_w, gxm_XPointInRegion) Xen_wrap_3_args(gxm_XPolygonRegion_w, gxm_XPolygonRegion) Xen_wrap_5_args(gxm_XRectInRegion_w, gxm_XRectInRegion) Xen_wrap_4_args(gxm_XSaveContext_w, gxm_XSaveContext) Xen_wrap_no_args(gxm_XUniqueContext_w, gxm_XUniqueContext) Xen_wrap_5_args(gxm_XSetRGBColormaps_w, gxm_XSetRGBColormaps) Xen_wrap_3_args(gxm_XSetWMHints_w, gxm_XSetWMHints) Xen_wrap_3_args(gxm_XSetRegion_w, gxm_XSetRegion) Xen_wrap_8_args(gxm_XSetWMProperties_w, gxm_XSetWMProperties) Xen_wrap_3_args(gxm_XShrinkRegion_w, gxm_XShrinkRegion) Xen_wrap_3_args(gxm_XSubtractRegion_w, gxm_XSubtractRegion) Xen_wrap_3_args(gxm_XUnionRectWithRegion_w, gxm_XUnionRectWithRegion) Xen_wrap_3_args(gxm_XUnionRegion_w, gxm_XUnionRegion) Xen_wrap_3_args(gxm_XXorRegion_w, gxm_XXorRegion) Xen_wrap_1_arg(gxm_DefaultScreen_w, gxm_DefaultScreen) Xen_wrap_1_arg(gxm_DefaultRootWindow_w, gxm_DefaultRootWindow) Xen_wrap_1_arg(gxm_QLength_w, gxm_QLength) Xen_wrap_1_arg(gxm_ScreenCount_w, gxm_ScreenCount) Xen_wrap_1_arg(gxm_ServerVendor_w, gxm_ServerVendor) Xen_wrap_1_arg(gxm_ProtocolVersion_w, gxm_ProtocolVersion) Xen_wrap_1_arg(gxm_ProtocolRevision_w, gxm_ProtocolRevision) Xen_wrap_1_arg(gxm_VendorRelease_w, gxm_VendorRelease) Xen_wrap_1_arg(gxm_DisplayString_w, gxm_DisplayString) Xen_wrap_1_arg(gxm_BitmapUnit_w, gxm_BitmapUnit) Xen_wrap_1_arg(gxm_BitmapBitOrder_w, gxm_BitmapBitOrder) Xen_wrap_1_arg(gxm_BitmapPad_w, gxm_BitmapPad) Xen_wrap_1_arg(gxm_ImageByteOrder_w, gxm_ImageByteOrder) Xen_wrap_1_arg(gxm_NextRequest_w, gxm_NextRequest) Xen_wrap_1_arg(gxm_LastKnownRequestProcessed_w, gxm_LastKnownRequestProcessed) Xen_wrap_1_arg(gxm_DefaultScreenOfDisplay_w, gxm_DefaultScreenOfDisplay) Xen_wrap_1_arg(gxm_DisplayOfScreen_w, gxm_DisplayOfScreen) Xen_wrap_1_arg(gxm_RootWindowOfScreen_w, gxm_RootWindowOfScreen) Xen_wrap_1_arg(gxm_BlackPixelOfScreen_w, gxm_BlackPixelOfScreen) Xen_wrap_1_arg(gxm_WhitePixelOfScreen_w, gxm_WhitePixelOfScreen) Xen_wrap_1_arg(gxm_DefaultColormapOfScreen_w, gxm_DefaultColormapOfScreen) Xen_wrap_1_arg(gxm_DefaultDepthOfScreen_w, gxm_DefaultDepthOfScreen) Xen_wrap_1_arg(gxm_DefaultGCOfScreen_w, gxm_DefaultGCOfScreen) Xen_wrap_1_arg(gxm_DefaultVisualOfScreen_w, gxm_DefaultVisualOfScreen) Xen_wrap_1_arg(gxm_WidthOfScreen_w, gxm_WidthOfScreen) Xen_wrap_1_arg(gxm_HeightOfScreen_w, gxm_HeightOfScreen) Xen_wrap_1_arg(gxm_WidthMMOfScreen_w, gxm_WidthMMOfScreen) Xen_wrap_1_arg(gxm_HeightMMOfScreen_w, gxm_HeightMMOfScreen) Xen_wrap_1_arg(gxm_PlanesOfScreen_w, gxm_PlanesOfScreen) Xen_wrap_1_arg(gxm_CellsOfScreen_w, gxm_CellsOfScreen) Xen_wrap_1_arg(gxm_MinCmapsOfScreen_w, gxm_MinCmapsOfScreen) Xen_wrap_1_arg(gxm_MaxCmapsOfScreen_w, gxm_MaxCmapsOfScreen) Xen_wrap_1_arg(gxm_DoesSaveUnders_w, gxm_DoesSaveUnders) Xen_wrap_1_arg(gxm_DoesBackingStore_w, gxm_DoesBackingStore) Xen_wrap_1_arg(gxm_EventMaskOfScreen_w, gxm_EventMaskOfScreen) Xen_wrap_2_args(gxm_RootWindow_w, gxm_RootWindow) Xen_wrap_2_args(gxm_DefaultVisual_w, gxm_DefaultVisual) Xen_wrap_2_args(gxm_DefaultGC_w, gxm_DefaultGC) Xen_wrap_2_args(gxm_BlackPixel_w, gxm_BlackPixel) Xen_wrap_2_args(gxm_WhitePixel_w, gxm_WhitePixel) Xen_wrap_2_args(gxm_DisplayWidth_w, gxm_DisplayWidth) Xen_wrap_2_args(gxm_DisplayHeight_w, gxm_DisplayHeight) Xen_wrap_2_args(gxm_DisplayWidthMM_w, gxm_DisplayWidthMM) Xen_wrap_2_args(gxm_DisplayHeightMM_w, gxm_DisplayHeightMM) Xen_wrap_2_args(gxm_DisplayPlanes_w, gxm_DisplayPlanes) Xen_wrap_2_args(gxm_DisplayCells_w, gxm_DisplayCells) Xen_wrap_2_args(gxm_DefaultColormap_w, gxm_DefaultColormap) Xen_wrap_2_args(gxm_ScreenOfDisplay_w, gxm_ScreenOfDisplay) Xen_wrap_2_args(gxm_DefaultDepth_w, gxm_DefaultDepth) Xen_wrap_1_arg(gxm_IsKeypadKey_w, gxm_IsKeypadKey) Xen_wrap_1_arg(gxm_IsPrivateKeypadKey_w, gxm_IsPrivateKeypadKey) Xen_wrap_1_arg(gxm_IsCursorKey_w, gxm_IsCursorKey) Xen_wrap_1_arg(gxm_IsPFKey_w, gxm_IsPFKey) Xen_wrap_1_arg(gxm_IsFunctionKey_w, gxm_IsFunctionKey) Xen_wrap_1_arg(gxm_IsMiscFunctionKey_w, gxm_IsMiscFunctionKey) Xen_wrap_1_arg(gxm_IsModifierKey_w, gxm_IsModifierKey) Xen_wrap_1_arg(g_is_XButtonEvent_w, g_is_XButtonEvent) Xen_wrap_1_arg(g_is_XCirculateEvent_w, g_is_XCirculateEvent) Xen_wrap_1_arg(g_is_XCirculateRequestEvent_w, g_is_XCirculateRequestEvent) Xen_wrap_1_arg(g_is_XClientMessageEvent_w, g_is_XClientMessageEvent) Xen_wrap_1_arg(g_is_XColormapEvent_w, g_is_XColormapEvent) Xen_wrap_1_arg(g_is_XConfigureEvent_w, g_is_XConfigureEvent) Xen_wrap_1_arg(g_is_XConfigureRequestEvent_w, g_is_XConfigureRequestEvent) Xen_wrap_1_arg(g_is_XCreateWindowEvent_w, g_is_XCreateWindowEvent) Xen_wrap_1_arg(g_is_XCrossingEvent_w, g_is_XCrossingEvent) Xen_wrap_1_arg(g_is_XDestroyWindowEvent_w, g_is_XDestroyWindowEvent) Xen_wrap_1_arg(g_is_XErrorEvent_w, g_is_XErrorEvent) Xen_wrap_1_arg(g_is_XExposeEvent_w, g_is_XExposeEvent) Xen_wrap_1_arg(g_is_XFocusChangeEvent_w, g_is_XFocusChangeEvent) Xen_wrap_1_arg(g_is_XGraphicsExposeEvent_w, g_is_XGraphicsExposeEvent) Xen_wrap_1_arg(g_is_XGravityEvent_w, g_is_XGravityEvent) Xen_wrap_1_arg(g_is_XKeyEvent_w, g_is_XKeyEvent) Xen_wrap_1_arg(g_is_XKeymapEvent_w, g_is_XKeymapEvent) Xen_wrap_1_arg(g_is_XMapEvent_w, g_is_XMapEvent) Xen_wrap_1_arg(g_is_XMapRequestEvent_w, g_is_XMapRequestEvent) Xen_wrap_1_arg(g_is_XMappingEvent_w, g_is_XMappingEvent) Xen_wrap_1_arg(g_is_XMotionEvent_w, g_is_XMotionEvent) Xen_wrap_1_arg(g_is_XNoExposeEvent_w, g_is_XNoExposeEvent) Xen_wrap_1_arg(g_is_XPropertyEvent_w, g_is_XPropertyEvent) Xen_wrap_1_arg(g_is_XReparentEvent_w, g_is_XReparentEvent) Xen_wrap_1_arg(g_is_XResizeRequestEvent_w, g_is_XResizeRequestEvent) Xen_wrap_1_arg(g_is_XSelectionClearEvent_w, g_is_XSelectionClearEvent) Xen_wrap_1_arg(g_is_XSelectionEvent_w, g_is_XSelectionEvent) Xen_wrap_1_arg(g_is_XSelectionRequestEvent_w, g_is_XSelectionRequestEvent) Xen_wrap_1_arg(g_is_XSetWindowAttributes_w, g_is_XSetWindowAttributes) Xen_wrap_1_arg(g_is_XUnmapEvent_w, g_is_XUnmapEvent) Xen_wrap_1_arg(g_is_XVisibilityEvent_w, g_is_XVisibilityEvent) Xen_wrap_1_arg(g_is_XIconSize_w, g_is_XIconSize) Xen_wrap_4_optional_args(gxm_XmCreateMessageBox_w, gxm_XmCreateMessageBox) Xen_wrap_4_optional_args(gxm_XmCreateMessageDialog_w, gxm_XmCreateMessageDialog) Xen_wrap_4_optional_args(gxm_XmCreateErrorDialog_w, gxm_XmCreateErrorDialog) Xen_wrap_4_optional_args(gxm_XmCreateInformationDialog_w, gxm_XmCreateInformationDialog) Xen_wrap_4_optional_args(gxm_XmCreateQuestionDialog_w, gxm_XmCreateQuestionDialog) Xen_wrap_4_optional_args(gxm_XmCreateWarningDialog_w, gxm_XmCreateWarningDialog) Xen_wrap_4_optional_args(gxm_XmCreateWorkingDialog_w, gxm_XmCreateWorkingDialog) Xen_wrap_4_optional_args(gxm_XmCreateTemplateDialog_w, gxm_XmCreateTemplateDialog) Xen_wrap_2_args(gxm_XmMessageBoxGetChild_w, gxm_XmMessageBoxGetChild) Xen_wrap_4_optional_args(gxm_XmCreateArrowButtonGadget_w, gxm_XmCreateArrowButtonGadget) Xen_wrap_4_optional_args(gxm_XmCreateArrowButton_w, gxm_XmCreateArrowButton) Xen_wrap_4_optional_args(gxm_XmCreateNotebook_w, gxm_XmCreateNotebook) Xen_wrap_2_args(gxm_XmNotebookGetPageInfo_w, gxm_XmNotebookGetPageInfo) Xen_wrap_5_args(gxm_XmTransferSetParameters_w, gxm_XmTransferSetParameters) Xen_wrap_2_args(gxm_XmTransferDone_w, gxm_XmTransferDone) Xen_wrap_5_args(gxm_XmTransferValue_w, gxm_XmTransferValue) Xen_wrap_1_arg(gxm_XmTransferStartRequest_w, gxm_XmTransferStartRequest) Xen_wrap_2_args(gxm_XmTransferSendRequest_w, gxm_XmTransferSendRequest) Xen_wrap_4_optional_args(gxm_XmCreateComboBox_w, gxm_XmCreateComboBox) Xen_wrap_4_optional_args(gxm_XmCreateDropDownComboBox_w, gxm_XmCreateDropDownComboBox) Xen_wrap_4_optional_args(gxm_XmCreateDropDownList_w, gxm_XmCreateDropDownList) Xen_wrap_4_args(gxm_XmComboBoxAddItem_w, gxm_XmComboBoxAddItem) Xen_wrap_2_args(gxm_XmComboBoxDeletePos_w, gxm_XmComboBoxDeletePos) Xen_wrap_2_args(gxm_XmComboBoxSelectItem_w, gxm_XmComboBoxSelectItem) Xen_wrap_2_args(gxm_XmComboBoxSetItem_w, gxm_XmComboBoxSetItem) Xen_wrap_1_arg(gxm_XmComboBoxUpdate_w, gxm_XmComboBoxUpdate) Xen_wrap_4_optional_args(gxm_XmCreateContainer_w, gxm_XmCreateContainer) Xen_wrap_2_args(gxm_XmContainerGetItemChildren_w, gxm_XmContainerGetItemChildren) Xen_wrap_1_arg(gxm_XmContainerRelayout_w, gxm_XmContainerRelayout) Xen_wrap_3_args(gxm_XmContainerReorder_w, gxm_XmContainerReorder) Xen_wrap_2_args(gxm_XmContainerCut_w, gxm_XmContainerCut) Xen_wrap_2_args(gxm_XmContainerCopy_w, gxm_XmContainerCopy) Xen_wrap_1_arg(gxm_XmContainerPaste_w, gxm_XmContainerPaste) Xen_wrap_2_args(gxm_XmContainerCopyLink_w, gxm_XmContainerCopyLink) Xen_wrap_1_arg(gxm_XmContainerPasteLink_w, gxm_XmContainerPasteLink) Xen_wrap_4_optional_args(gxm_XmCreateSpinBox_w, gxm_XmCreateSpinBox) Xen_wrap_1_arg(gxm_XmSpinBoxValidatePosition_w, gxm_XmSpinBoxValidatePosition) Xen_wrap_4_optional_args(gxm_XmCreateSimpleSpinBox_w, gxm_XmCreateSimpleSpinBox) Xen_wrap_3_args(gxm_XmSimpleSpinBoxAddItem_w, gxm_XmSimpleSpinBoxAddItem) Xen_wrap_2_args(gxm_XmSimpleSpinBoxDeletePos_w, gxm_XmSimpleSpinBoxDeletePos) Xen_wrap_2_args(gxm_XmSimpleSpinBoxSetItem_w, gxm_XmSimpleSpinBoxSetItem) Xen_wrap_1_arg(gxm_XmDropSiteRegistered_w, gxm_XmDropSiteRegistered) Xen_wrap_2_args(gxm_XmTextFieldCopyLink_w, gxm_XmTextFieldCopyLink) Xen_wrap_1_arg(gxm_XmTextFieldPasteLink_w, gxm_XmTextFieldPasteLink) Xen_wrap_1_arg(gxm_XmTextGetCenterline_w, gxm_XmTextGetCenterline) Xen_wrap_3_args(gxm_XmToggleButtonGadgetSetValue_w, gxm_XmToggleButtonGadgetSetValue) Xen_wrap_4_optional_args(gxm_XmCreateIconGadget_w, gxm_XmCreateIconGadget) Xen_wrap_4_optional_args(gxm_XmCreateIconHeader_w, gxm_XmCreateIconHeader) Xen_wrap_3_args(gxm_XmObjectAtPoint_w, gxm_XmObjectAtPoint) Xen_wrap_4_args(gxm_XmConvertStringToUnits_w, gxm_XmConvertStringToUnits) Xen_wrap_4_optional_args(gxm_XmCreateGrabShell_w, gxm_XmCreateGrabShell) Xen_wrap_3_args(gxm_XmToggleButtonSetValue_w, gxm_XmToggleButtonSetValue) Xen_wrap_1_arg(gxm_XmTextPasteLink_w, gxm_XmTextPasteLink) Xen_wrap_2_args(gxm_XmTextCopyLink_w, gxm_XmTextCopyLink) Xen_wrap_7_args(gxm_XmScaleSetTicks_w, gxm_XmScaleSetTicks) Xen_wrap_3_args(gxm_XmInternAtom_w, gxm_XmInternAtom) Xen_wrap_2_args(gxm_XmGetAtomName_w, gxm_XmGetAtomName) Xen_wrap_4_optional_args(gxm_XmCreatePanedWindow_w, gxm_XmCreatePanedWindow) Xen_wrap_4_optional_args(gxm_XmCreateBulletinBoard_w, gxm_XmCreateBulletinBoard) Xen_wrap_4_optional_args(gxm_XmCreateBulletinBoardDialog_w, gxm_XmCreateBulletinBoardDialog) Xen_wrap_4_optional_args(gxm_XmCreateCascadeButtonGadget_w, gxm_XmCreateCascadeButtonGadget) Xen_wrap_2_args(gxm_XmCascadeButtonGadgetHighlight_w, gxm_XmCascadeButtonGadgetHighlight) Xen_wrap_4_optional_args(gxm_XmAddProtocols_w, gxm_XmAddProtocols) Xen_wrap_3_optional_args(gxm_XmAddWMProtocols_w, gxm_XmAddWMProtocols) Xen_wrap_4_optional_args(gxm_XmRemoveProtocols_w, gxm_XmRemoveProtocols) Xen_wrap_3_optional_args(gxm_XmRemoveWMProtocols_w, gxm_XmRemoveWMProtocols) Xen_wrap_5_args(gxm_XmAddProtocolCallback_w, gxm_XmAddProtocolCallback) Xen_wrap_4_args(gxm_XmAddWMProtocolCallback_w, gxm_XmAddWMProtocolCallback) Xen_wrap_5_args(gxm_XmRemoveProtocolCallback_w, gxm_XmRemoveProtocolCallback) Xen_wrap_4_args(gxm_XmRemoveWMProtocolCallback_w, gxm_XmRemoveWMProtocolCallback) Xen_wrap_3_args(gxm_XmActivateProtocol_w, gxm_XmActivateProtocol) Xen_wrap_3_args(gxm_XmDeactivateProtocol_w, gxm_XmDeactivateProtocol) Xen_wrap_2_args(gxm_XmActivateWMProtocol_w, gxm_XmActivateWMProtocol) Xen_wrap_2_args(gxm_XmDeactivateWMProtocol_w, gxm_XmDeactivateWMProtocol) Xen_wrap_7_args(gxm_XmSetProtocolHooks_w, gxm_XmSetProtocolHooks) Xen_wrap_6_args(gxm_XmSetWMProtocolHooks_w, gxm_XmSetWMProtocolHooks) Xen_wrap_4_optional_args(gxm_XmCreateCascadeButton_w, gxm_XmCreateCascadeButton) Xen_wrap_2_args(gxm_XmCascadeButtonHighlight_w, gxm_XmCascadeButtonHighlight) Xen_wrap_4_optional_args(gxm_XmCreatePushButtonGadget_w, gxm_XmCreatePushButtonGadget) Xen_wrap_4_optional_args(gxm_XmCreatePushButton_w, gxm_XmCreatePushButton) Xen_wrap_4_optional_args(gxm_XmCreateCommand_w, gxm_XmCreateCommand) Xen_wrap_2_args(gxm_XmCommandGetChild_w, gxm_XmCommandGetChild) Xen_wrap_2_args(gxm_XmCommandSetValue_w, gxm_XmCommandSetValue) Xen_wrap_2_args(gxm_XmCommandAppendValue_w, gxm_XmCommandAppendValue) Xen_wrap_2_args(gxm_XmCommandError_w, gxm_XmCommandError) Xen_wrap_4_optional_args(gxm_XmCreateCommandDialog_w, gxm_XmCreateCommandDialog) Xen_wrap_2_args(gxm_XmMenuPosition_w, gxm_XmMenuPosition) Xen_wrap_4_optional_args(gxm_XmCreateRowColumn_w, gxm_XmCreateRowColumn) Xen_wrap_4_optional_args(gxm_XmCreateWorkArea_w, gxm_XmCreateWorkArea) Xen_wrap_4_optional_args(gxm_XmCreateRadioBox_w, gxm_XmCreateRadioBox) Xen_wrap_4_optional_args(gxm_XmCreateOptionMenu_w, gxm_XmCreateOptionMenu) Xen_wrap_1_arg(gxm_XmOptionLabelGadget_w, gxm_XmOptionLabelGadget) Xen_wrap_1_arg(gxm_XmOptionButtonGadget_w, gxm_XmOptionButtonGadget) Xen_wrap_4_optional_args(gxm_XmCreateMenuBar_w, gxm_XmCreateMenuBar) Xen_wrap_4_optional_args(gxm_XmCreatePopupMenu_w, gxm_XmCreatePopupMenu) Xen_wrap_4_optional_args(gxm_XmCreatePulldownMenu_w, gxm_XmCreatePulldownMenu) Xen_wrap_1_arg(gxm_XmGetPostedFromWidget_w, gxm_XmGetPostedFromWidget) Xen_wrap_1_arg(gxm_XmGetTearOffControl_w, gxm_XmGetTearOffControl) Xen_wrap_2_args(gxm_XmScaleSetValue_w, gxm_XmScaleSetValue) Xen_wrap_1_arg(gxm_XmScaleGetValue_w, gxm_XmScaleGetValue) Xen_wrap_4_optional_args(gxm_XmCreateScale_w, gxm_XmCreateScale) Xen_wrap_5_args(gxm_XmClipboardBeginCopy_w, gxm_XmClipboardBeginCopy) Xen_wrap_6_args(gxm_XmClipboardStartCopy_w, gxm_XmClipboardStartCopy) Xen_wrap_7_args(gxm_XmClipboardCopy_w, gxm_XmClipboardCopy) Xen_wrap_3_args(gxm_XmClipboardEndCopy_w, gxm_XmClipboardEndCopy) Xen_wrap_3_args(gxm_XmClipboardCancelCopy_w, gxm_XmClipboardCancelCopy) Xen_wrap_3_args(gxm_XmClipboardWithdrawFormat_w, gxm_XmClipboardWithdrawFormat) Xen_wrap_6_args(gxm_XmClipboardCopyByName_w, gxm_XmClipboardCopyByName) Xen_wrap_2_args(gxm_XmClipboardUndoCopy_w, gxm_XmClipboardUndoCopy) Xen_wrap_2_args(gxm_XmClipboardLock_w, gxm_XmClipboardLock) Xen_wrap_3_args(gxm_XmClipboardUnlock_w, gxm_XmClipboardUnlock) Xen_wrap_3_args(gxm_XmClipboardStartRetrieve_w, gxm_XmClipboardStartRetrieve) Xen_wrap_2_args(gxm_XmClipboardEndRetrieve_w, gxm_XmClipboardEndRetrieve) Xen_wrap_4_args(gxm_XmClipboardRetrieve_w, gxm_XmClipboardRetrieve) Xen_wrap_2_args(gxm_XmClipboardInquireCount_w, gxm_XmClipboardInquireCount) Xen_wrap_4_args(gxm_XmClipboardInquireFormat_w, gxm_XmClipboardInquireFormat) Xen_wrap_3_args(gxm_XmClipboardInquireLength_w, gxm_XmClipboardInquireLength) Xen_wrap_3_args(gxm_XmClipboardInquirePendingItems_w, gxm_XmClipboardInquirePendingItems) Xen_wrap_3_args(gxm_XmClipboardRegisterFormat_w, gxm_XmClipboardRegisterFormat) Xen_wrap_1_arg(gxm_XmGetXmScreen_w, gxm_XmGetXmScreen) Xen_wrap_4_optional_args(gxm_XmCreateScrollBar_w, gxm_XmCreateScrollBar) Xen_wrap_1_arg(gxm_XmScrollBarGetValues_w, gxm_XmScrollBarGetValues) Xen_wrap_6_args(gxm_XmScrollBarSetValues_w, gxm_XmScrollBarSetValues) Xen_wrap_4_optional_args(gxm_XmCreateDialogShell_w, gxm_XmCreateDialogShell) Xen_wrap_4_optional_args(gxm_XmCreateScrolledWindow_w, gxm_XmCreateScrolledWindow) Xen_wrap_4_args(gxm_XmScrollVisible_w, gxm_XmScrollVisible) Xen_wrap_2_args(gxm_XmGetDragContext_w, gxm_XmGetDragContext) Xen_wrap_1_arg(gxm_XmGetXmDisplay_w, gxm_XmGetXmDisplay) Xen_wrap_2_args(gxm_XmSelectionBoxGetChild_w, gxm_XmSelectionBoxGetChild) Xen_wrap_4_optional_args(gxm_XmCreateSelectionBox_w, gxm_XmCreateSelectionBox) Xen_wrap_4_optional_args(gxm_XmCreateSelectionDialog_w, gxm_XmCreateSelectionDialog) Xen_wrap_4_optional_args(gxm_XmCreatePromptDialog_w, gxm_XmCreatePromptDialog) Xen_wrap_4_optional_args(gxm_XmDragStart_w, gxm_XmDragStart) Xen_wrap_1_arg(gxm_XmDragCancel_w, gxm_XmDragCancel) Xen_wrap_5_args(gxm_XmTargetsAreCompatible_w, gxm_XmTargetsAreCompatible) Xen_wrap_4_optional_args(gxm_XmCreateSeparatorGadget_w, gxm_XmCreateSeparatorGadget) Xen_wrap_4_optional_args(gxm_XmCreateDragIcon_w, gxm_XmCreateDragIcon) Xen_wrap_4_optional_args(gxm_XmCreateSeparator_w, gxm_XmCreateSeparator) Xen_wrap_4_optional_args(gxm_XmCreateDrawingArea_w, gxm_XmCreateDrawingArea) Xen_wrap_4_optional_args(gxm_XmCreateDrawnButton_w, gxm_XmCreateDrawnButton) Xen_wrap_3_optional_args(gxm_XmDropSiteRegister_w, gxm_XmDropSiteRegister) Xen_wrap_1_arg(gxm_XmDropSiteUnregister_w, gxm_XmDropSiteUnregister) Xen_wrap_1_arg(gxm_XmDropSiteStartUpdate_w, gxm_XmDropSiteStartUpdate) Xen_wrap_3_optional_args(gxm_XmDropSiteUpdate_w, gxm_XmDropSiteUpdate) Xen_wrap_1_arg(gxm_XmDropSiteEndUpdate_w, gxm_XmDropSiteEndUpdate) Xen_wrap_3_optional_args(gxm_XmDropSiteRetrieve_w, gxm_XmDropSiteRetrieve) Xen_wrap_1_arg(gxm_XmDropSiteQueryStackingOrder_w, gxm_XmDropSiteQueryStackingOrder) Xen_wrap_3_args(gxm_XmDropSiteConfigureStackingOrder_w, gxm_XmDropSiteConfigureStackingOrder) Xen_wrap_3_optional_args(gxm_XmDropTransferStart_w, gxm_XmDropTransferStart) Xen_wrap_2_args(gxm_XmDropTransferAdd_w, gxm_XmDropTransferAdd) Xen_wrap_1_arg(gxm_XmTextFieldGetString_w, gxm_XmTextFieldGetString) Xen_wrap_3_args(gxm_XmTextFieldGetSubstring_w, gxm_XmTextFieldGetSubstring) Xen_wrap_1_arg(gxm_XmTextFieldGetLastPosition_w, gxm_XmTextFieldGetLastPosition) Xen_wrap_2_args(gxm_XmTextFieldSetString_w, gxm_XmTextFieldSetString) Xen_wrap_4_args(gxm_XmTextFieldReplace_w, gxm_XmTextFieldReplace) Xen_wrap_3_args(gxm_XmTextFieldInsert_w, gxm_XmTextFieldInsert) Xen_wrap_2_args(gxm_XmTextFieldSetAddMode_w, gxm_XmTextFieldSetAddMode) Xen_wrap_1_arg(gxm_XmTextFieldGetAddMode_w, gxm_XmTextFieldGetAddMode) Xen_wrap_1_arg(gxm_XmTextFieldGetEditable_w, gxm_XmTextFieldGetEditable) Xen_wrap_2_args(gxm_XmTextFieldSetEditable_w, gxm_XmTextFieldSetEditable) Xen_wrap_1_arg(gxm_XmTextFieldGetMaxLength_w, gxm_XmTextFieldGetMaxLength) Xen_wrap_2_args(gxm_XmTextFieldSetMaxLength_w, gxm_XmTextFieldSetMaxLength) Xen_wrap_1_arg(gxm_XmTextFieldGetCursorPosition_w, gxm_XmTextFieldGetCursorPosition) Xen_wrap_1_arg(gxm_XmTextFieldGetInsertionPosition_w, gxm_XmTextFieldGetInsertionPosition) Xen_wrap_2_args(gxm_XmTextFieldSetCursorPosition_w, gxm_XmTextFieldSetCursorPosition) Xen_wrap_2_args(gxm_XmTextFieldSetInsertionPosition_w, gxm_XmTextFieldSetInsertionPosition) Xen_wrap_1_arg(gxm_XmTextFieldGetSelectionPosition_w, gxm_XmTextFieldGetSelectionPosition) Xen_wrap_1_arg(gxm_XmTextFieldGetSelection_w, gxm_XmTextFieldGetSelection) Xen_wrap_1_arg(gxm_XmTextFieldRemove_w, gxm_XmTextFieldRemove) Xen_wrap_2_args(gxm_XmTextFieldCopy_w, gxm_XmTextFieldCopy) Xen_wrap_2_args(gxm_XmTextFieldCut_w, gxm_XmTextFieldCut) Xen_wrap_1_arg(gxm_XmTextFieldPaste_w, gxm_XmTextFieldPaste) Xen_wrap_2_args(gxm_XmTextFieldClearSelection_w, gxm_XmTextFieldClearSelection) Xen_wrap_4_args(gxm_XmTextFieldSetSelection_w, gxm_XmTextFieldSetSelection) Xen_wrap_3_args(gxm_XmTextFieldXYToPos_w, gxm_XmTextFieldXYToPos) Xen_wrap_2_args(gxm_XmTextFieldPosToXY_w, gxm_XmTextFieldPosToXY) Xen_wrap_2_args(gxm_XmTextFieldShowPosition_w, gxm_XmTextFieldShowPosition) Xen_wrap_4_args(gxm_XmTextFieldSetHighlight_w, gxm_XmTextFieldSetHighlight) Xen_wrap_1_arg(gxm_XmTextFieldGetBaseline_w, gxm_XmTextFieldGetBaseline) Xen_wrap_4_optional_args(gxm_XmCreateTextField_w, gxm_XmCreateTextField) Xen_wrap_2_args(gxm_XmFileSelectionBoxGetChild_w, gxm_XmFileSelectionBoxGetChild) Xen_wrap_2_args(gxm_XmFileSelectionDoSearch_w, gxm_XmFileSelectionDoSearch) Xen_wrap_4_optional_args(gxm_XmCreateFileSelectionBox_w, gxm_XmCreateFileSelectionBox) Xen_wrap_4_optional_args(gxm_XmCreateFileSelectionDialog_w, gxm_XmCreateFileSelectionDialog) Xen_wrap_4_args(gxm_XmTextSetHighlight_w, gxm_XmTextSetHighlight) Xen_wrap_4_optional_args(gxm_XmCreateScrolledText_w, gxm_XmCreateScrolledText) Xen_wrap_4_optional_args(gxm_XmCreateText_w, gxm_XmCreateText) Xen_wrap_3_args(gxm_XmTextGetSubstring_w, gxm_XmTextGetSubstring) Xen_wrap_1_arg(gxm_XmTextGetString_w, gxm_XmTextGetString) Xen_wrap_1_arg(gxm_XmTextGetLastPosition_w, gxm_XmTextGetLastPosition) Xen_wrap_2_args(gxm_XmTextSetString_w, gxm_XmTextSetString) Xen_wrap_4_args(gxm_XmTextReplace_w, gxm_XmTextReplace) Xen_wrap_3_args(gxm_XmTextInsert_w, gxm_XmTextInsert) Xen_wrap_2_args(gxm_XmTextSetAddMode_w, gxm_XmTextSetAddMode) Xen_wrap_1_arg(gxm_XmTextGetAddMode_w, gxm_XmTextGetAddMode) Xen_wrap_1_arg(gxm_XmTextGetEditable_w, gxm_XmTextGetEditable) Xen_wrap_2_args(gxm_XmTextSetEditable_w, gxm_XmTextSetEditable) Xen_wrap_1_arg(gxm_XmTextGetMaxLength_w, gxm_XmTextGetMaxLength) Xen_wrap_2_args(gxm_XmTextSetMaxLength_w, gxm_XmTextSetMaxLength) Xen_wrap_1_arg(gxm_XmTextGetTopCharacter_w, gxm_XmTextGetTopCharacter) Xen_wrap_2_args(gxm_XmTextSetTopCharacter_w, gxm_XmTextSetTopCharacter) Xen_wrap_1_arg(gxm_XmTextGetCursorPosition_w, gxm_XmTextGetCursorPosition) Xen_wrap_1_arg(gxm_XmTextGetInsertionPosition_w, gxm_XmTextGetInsertionPosition) Xen_wrap_2_args(gxm_XmTextSetInsertionPosition_w, gxm_XmTextSetInsertionPosition) Xen_wrap_2_args(gxm_XmTextSetCursorPosition_w, gxm_XmTextSetCursorPosition) Xen_wrap_1_arg(gxm_XmTextRemove_w, gxm_XmTextRemove) Xen_wrap_2_args(gxm_XmTextCopy_w, gxm_XmTextCopy) Xen_wrap_2_args(gxm_XmTextCut_w, gxm_XmTextCut) Xen_wrap_1_arg(gxm_XmTextPaste_w, gxm_XmTextPaste) Xen_wrap_1_arg(gxm_XmTextGetSelection_w, gxm_XmTextGetSelection) Xen_wrap_4_args(gxm_XmTextSetSelection_w, gxm_XmTextSetSelection) Xen_wrap_2_args(gxm_XmTextClearSelection_w, gxm_XmTextClearSelection) Xen_wrap_1_arg(gxm_XmTextGetSelectionPosition_w, gxm_XmTextGetSelectionPosition) Xen_wrap_3_args(gxm_XmTextXYToPos_w, gxm_XmTextXYToPos) Xen_wrap_2_args(gxm_XmTextPosToXY_w, gxm_XmTextPosToXY) Xen_wrap_1_arg(gxm_XmTextGetSource_w, gxm_XmTextGetSource) Xen_wrap_4_args(gxm_XmTextSetSource_w, gxm_XmTextSetSource) Xen_wrap_2_args(gxm_XmTextShowPosition_w, gxm_XmTextShowPosition) Xen_wrap_2_args(gxm_XmTextScroll_w, gxm_XmTextScroll) Xen_wrap_1_arg(gxm_XmTextGetBaseline_w, gxm_XmTextGetBaseline) Xen_wrap_1_arg(gxm_XmTextDisableRedisplay_w, gxm_XmTextDisableRedisplay) Xen_wrap_1_arg(gxm_XmTextEnableRedisplay_w, gxm_XmTextEnableRedisplay) Xen_wrap_4_args(gxm_XmTextFindString_w, gxm_XmTextFindString) Xen_wrap_4_optional_args(gxm_XmCreateForm_w, gxm_XmCreateForm) Xen_wrap_4_optional_args(gxm_XmCreateFormDialog_w, gxm_XmCreateFormDialog) Xen_wrap_4_optional_args(gxm_XmCreateFrame_w, gxm_XmCreateFrame) Xen_wrap_1_arg(gxm_XmToggleButtonGadgetGetState_w, gxm_XmToggleButtonGadgetGetState) Xen_wrap_3_args(gxm_XmToggleButtonGadgetSetState_w, gxm_XmToggleButtonGadgetSetState) Xen_wrap_4_optional_args(gxm_XmCreateToggleButtonGadget_w, gxm_XmCreateToggleButtonGadget) Xen_wrap_1_arg(gxm_XmToggleButtonGetState_w, gxm_XmToggleButtonGetState) Xen_wrap_3_args(gxm_XmToggleButtonSetState_w, gxm_XmToggleButtonSetState) Xen_wrap_4_optional_args(gxm_XmCreateToggleButton_w, gxm_XmCreateToggleButton) Xen_wrap_4_optional_args(gxm_XmCreateLabelGadget_w, gxm_XmCreateLabelGadget) Xen_wrap_4_optional_args(gxm_XmCreateLabel_w, gxm_XmCreateLabel) Xen_wrap_1_arg(gxm_XmIsMotifWMRunning_w, gxm_XmIsMotifWMRunning) Xen_wrap_3_args(gxm_XmListAddItem_w, gxm_XmListAddItem) Xen_wrap_4_args(gxm_XmListAddItems_w, gxm_XmListAddItems) Xen_wrap_4_args(gxm_XmListAddItemsUnselected_w, gxm_XmListAddItemsUnselected) Xen_wrap_3_args(gxm_XmListAddItemUnselected_w, gxm_XmListAddItemUnselected) Xen_wrap_2_args(gxm_XmListDeleteItem_w, gxm_XmListDeleteItem) Xen_wrap_3_optional_args(gxm_XmListDeleteItems_w, gxm_XmListDeleteItems) Xen_wrap_3_optional_args(gxm_XmListDeletePositions_w, gxm_XmListDeletePositions) Xen_wrap_2_args(gxm_XmListDeletePos_w, gxm_XmListDeletePos) Xen_wrap_3_args(gxm_XmListDeleteItemsPos_w, gxm_XmListDeleteItemsPos) Xen_wrap_1_arg(gxm_XmListDeleteAllItems_w, gxm_XmListDeleteAllItems) Xen_wrap_4_args(gxm_XmListReplaceItems_w, gxm_XmListReplaceItems) Xen_wrap_4_args(gxm_XmListReplaceItemsPos_w, gxm_XmListReplaceItemsPos) Xen_wrap_4_args(gxm_XmListReplaceItemsUnselected_w, gxm_XmListReplaceItemsUnselected) Xen_wrap_4_args(gxm_XmListReplaceItemsPosUnselected_w, gxm_XmListReplaceItemsPosUnselected) Xen_wrap_4_args(gxm_XmListReplacePositions_w, gxm_XmListReplacePositions) Xen_wrap_3_args(gxm_XmListSelectItem_w, gxm_XmListSelectItem) Xen_wrap_3_args(gxm_XmListSelectPos_w, gxm_XmListSelectPos) Xen_wrap_2_args(gxm_XmListDeselectItem_w, gxm_XmListDeselectItem) Xen_wrap_2_args(gxm_XmListDeselectPos_w, gxm_XmListDeselectPos) Xen_wrap_1_arg(gxm_XmListDeselectAllItems_w, gxm_XmListDeselectAllItems) Xen_wrap_2_args(gxm_XmListSetPos_w, gxm_XmListSetPos) Xen_wrap_2_args(gxm_XmListSetBottomPos_w, gxm_XmListSetBottomPos) Xen_wrap_2_args(gxm_XmListSetItem_w, gxm_XmListSetItem) Xen_wrap_2_args(gxm_XmListSetBottomItem_w, gxm_XmListSetBottomItem) Xen_wrap_2_args(gxm_XmListSetAddMode_w, gxm_XmListSetAddMode) Xen_wrap_2_args(gxm_XmListItemExists_w, gxm_XmListItemExists) Xen_wrap_2_args(gxm_XmListItemPos_w, gxm_XmListItemPos) Xen_wrap_1_arg(gxm_XmListGetKbdItemPos_w, gxm_XmListGetKbdItemPos) Xen_wrap_2_args(gxm_XmListSetKbdItemPos_w, gxm_XmListSetKbdItemPos) Xen_wrap_2_args(gxm_XmListYToPos_w, gxm_XmListYToPos) Xen_wrap_2_args(gxm_XmListPosToBounds_w, gxm_XmListPosToBounds) Xen_wrap_2_args(gxm_XmListGetMatchPos_w, gxm_XmListGetMatchPos) Xen_wrap_2_args(gxm_XmListSetHorizPos_w, gxm_XmListSetHorizPos) Xen_wrap_1_arg(gxm_XmListUpdateSelectedList_w, gxm_XmListUpdateSelectedList) Xen_wrap_2_args(gxm_XmListPosSelected_w, gxm_XmListPosSelected) Xen_wrap_4_optional_args(gxm_XmCreateList_w, gxm_XmCreateList) Xen_wrap_4_optional_args(gxm_XmCreateScrolledList_w, gxm_XmCreateScrolledList) Xen_wrap_3_args(gxm_XmTranslateKey_w, gxm_XmTranslateKey) Xen_wrap_4_optional_args(gxm_XmCreateMainWindow_w, gxm_XmCreateMainWindow) Xen_wrap_2_args(gxm_XmInstallImage_w, gxm_XmInstallImage) Xen_wrap_1_arg(gxm_XmUninstallImage_w, gxm_XmUninstallImage) Xen_wrap_4_args(gxm_XmGetPixmap_w, gxm_XmGetPixmap) Xen_wrap_5_args(gxm_XmGetPixmapByDepth_w, gxm_XmGetPixmapByDepth) Xen_wrap_2_args(gxm_XmDestroyPixmap_w, gxm_XmDestroyPixmap) Xen_wrap_1_arg(gxm_XmUpdateDisplay_w, gxm_XmUpdateDisplay) Xen_wrap_1_arg(gxm_XmWidgetGetBaselines_w, gxm_XmWidgetGetBaselines) Xen_wrap_2_args(gxm_XmRegisterSegmentEncoding_w, gxm_XmRegisterSegmentEncoding) Xen_wrap_1_arg(gxm_XmMapSegmentEncoding_w, gxm_XmMapSegmentEncoding) Xen_wrap_1_arg(gxm_XmCvtCTToXmString_w, gxm_XmCvtCTToXmString) Xen_wrap_1_arg(gxm_XmCvtXmStringToCT_w, gxm_XmCvtXmStringToCT) Xen_wrap_5_args(gxm_XmConvertUnits_w, gxm_XmConvertUnits) Xen_wrap_4_optional_args(gxm_XmCreateSimpleMenuBar_w, gxm_XmCreateSimpleMenuBar) Xen_wrap_4_optional_args(gxm_XmCreateSimplePopupMenu_w, gxm_XmCreateSimplePopupMenu) Xen_wrap_4_optional_args(gxm_XmCreateSimplePulldownMenu_w, gxm_XmCreateSimplePulldownMenu) Xen_wrap_4_optional_args(gxm_XmCreateSimpleOptionMenu_w, gxm_XmCreateSimpleOptionMenu) Xen_wrap_4_optional_args(gxm_XmCreateSimpleRadioBox_w, gxm_XmCreateSimpleRadioBox) Xen_wrap_4_optional_args(gxm_XmCreateSimpleCheckBox_w, gxm_XmCreateSimpleCheckBox) Xen_wrap_3_args(gxm_XmVaCreateSimpleMenuBar_w, gxm_XmVaCreateSimpleMenuBar) Xen_wrap_4_args(gxm_XmVaCreateSimplePopupMenu_w, gxm_XmVaCreateSimplePopupMenu) Xen_wrap_5_args(gxm_XmVaCreateSimplePulldownMenu_w, gxm_XmVaCreateSimplePulldownMenu) Xen_wrap_7_args(gxm_XmVaCreateSimpleOptionMenu_w, gxm_XmVaCreateSimpleOptionMenu) Xen_wrap_5_args(gxm_XmVaCreateSimpleRadioBox_w, gxm_XmVaCreateSimpleRadioBox) Xen_wrap_4_args(gxm_XmVaCreateSimpleCheckBox_w, gxm_XmVaCreateSimpleCheckBox) Xen_wrap_3_args(gxm_XmTrackingEvent_w, gxm_XmTrackingEvent) Xen_wrap_1_arg(gxm_XmSetColorCalculation_w, gxm_XmSetColorCalculation) Xen_wrap_no_args(gxm_XmGetColorCalculation_w, gxm_XmGetColorCalculation) Xen_wrap_3_args(gxm_XmGetColors_w, gxm_XmGetColors) Xen_wrap_2_args(gxm_XmChangeColor_w, gxm_XmChangeColor) Xen_wrap_2_args(gxm_XmStringCreate_w, gxm_XmStringCreate) Xen_wrap_1_arg(gxm_XmStringCreateLocalized_w, gxm_XmStringCreateLocalized) Xen_wrap_1_arg(gxm_XmStringDirectionCreate_w, gxm_XmStringDirectionCreate) Xen_wrap_no_args(gxm_XmStringSeparatorCreate_w, gxm_XmStringSeparatorCreate) Xen_wrap_1_arg(gxm_XmStringInitContext_w, gxm_XmStringInitContext) Xen_wrap_1_arg(gxm_XmStringFreeContext_w, gxm_XmStringFreeContext) Xen_wrap_2_args(gxm_XmStringConcatAndFree_w, gxm_XmStringConcatAndFree) Xen_wrap_1_arg(gxm_XmStringIsVoid_w, gxm_XmStringIsVoid) Xen_wrap_1_arg(gxm_XmStringPeekNextTriple_w, gxm_XmStringPeekNextTriple) Xen_wrap_1_arg(gxm_XmStringGetNextTriple_w, gxm_XmStringGetNextTriple) Xen_wrap_3_args(gxm_XmStringComponentCreate_w, gxm_XmStringComponentCreate) Xen_wrap_7_args(gxm_XmStringUnparse_w, gxm_XmStringUnparse) Xen_wrap_7_args(gxm_XmStringParseText_w, gxm_XmStringParseText) Xen_wrap_2_args(gxm_XmStringToXmStringTable_w, gxm_XmStringToXmStringTable) Xen_wrap_3_args(gxm_XmStringTableToXmString_w, gxm_XmStringTableToXmString) Xen_wrap_8_args(gxm_XmStringTableUnparse_w, gxm_XmStringTableUnparse) Xen_wrap_7_args(gxm_XmStringTableParseStringArray_w, gxm_XmStringTableParseStringArray) Xen_wrap_1_arg(gxm_XmDirectionToStringDirection_w, gxm_XmDirectionToStringDirection) Xen_wrap_1_arg(gxm_XmStringDirectionToDirection_w, gxm_XmStringDirectionToDirection) Xen_wrap_4_args(gxm_XmStringGenerate_w, gxm_XmStringGenerate) Xen_wrap_2_args(gxm_XmStringPutRendition_w, gxm_XmStringPutRendition) Xen_wrap_2_optional_args(gxm_XmParseMappingCreate_w, gxm_XmParseMappingCreate) Xen_wrap_3_optional_args(gxm_XmParseMappingSetValues_w, gxm_XmParseMappingSetValues) Xen_wrap_3_optional_args(gxm_XmParseMappingGetValues_w, gxm_XmParseMappingGetValues) Xen_wrap_1_arg(gxm_XmParseMappingFree_w, gxm_XmParseMappingFree) Xen_wrap_2_optional_args(gxm_XmParseTableFree_w, gxm_XmParseTableFree) Xen_wrap_5_args(gxm_XmStringTableProposeTablist_w, gxm_XmStringTableProposeTablist) Xen_wrap_2_args(gxm_XmTabSetValue_w, gxm_XmTabSetValue) Xen_wrap_1_arg(gxm_XmTabGetValues_w, gxm_XmTabGetValues) Xen_wrap_1_arg(gxm_XmTabFree_w, gxm_XmTabFree) Xen_wrap_1_arg(gxm_XmTabListFree_w, gxm_XmTabListFree) Xen_wrap_5_args(gxm_XmTabCreate_w, gxm_XmTabCreate) Xen_wrap_1_arg(gxm_XmTabListTabCount_w, gxm_XmTabListTabCount) Xen_wrap_3_optional_args(gxm_XmTabListRemoveTabs_w, gxm_XmTabListRemoveTabs) Xen_wrap_4_optional_args(gxm_XmTabListReplacePositions_w, gxm_XmTabListReplacePositions) Xen_wrap_2_args(gxm_XmTabListGetTab_w, gxm_XmTabListGetTab) Xen_wrap_3_args(gxm_XmTabListCopy_w, gxm_XmTabListCopy) Xen_wrap_4_args(gxm_XmTabListInsertTabs_w, gxm_XmTabListInsertTabs) Xen_wrap_3_args(gxm_XmRenderTableCvtFromProp_w, gxm_XmRenderTableCvtFromProp) Xen_wrap_2_args(gxm_XmRenderTableCvtToProp_w, gxm_XmRenderTableCvtToProp) Xen_wrap_3_optional_args(gxm_XmRenditionUpdate_w, gxm_XmRenditionUpdate) Xen_wrap_3_optional_args(gxm_XmRenditionRetrieve_w, gxm_XmRenditionRetrieve) Xen_wrap_1_arg(gxm_XmRenditionFree_w, gxm_XmRenditionFree) Xen_wrap_4_optional_args(gxm_XmRenditionCreate_w, gxm_XmRenditionCreate) Xen_wrap_3_optional_args(gxm_XmRenderTableGetRenditions_w, gxm_XmRenderTableGetRenditions) Xen_wrap_2_args(gxm_XmRenderTableGetRendition_w, gxm_XmRenderTableGetRendition) Xen_wrap_1_arg(gxm_XmRenderTableGetTags_w, gxm_XmRenderTableGetTags) Xen_wrap_1_arg(gxm_XmRenderTableFree_w, gxm_XmRenderTableFree) Xen_wrap_3_optional_args(gxm_XmRenderTableCopy_w, gxm_XmRenderTableCopy) Xen_wrap_3_optional_args(gxm_XmRenderTableRemoveRenditions_w, gxm_XmRenderTableRemoveRenditions) Xen_wrap_4_args(gxm_XmRenderTableAddRenditions_w, gxm_XmRenderTableAddRenditions) Xen_wrap_2_args(gxm_XmStringConcat_w, gxm_XmStringConcat) Xen_wrap_1_arg(gxm_XmStringCopy_w, gxm_XmStringCopy) Xen_wrap_2_args(gxm_XmStringCompare_w, gxm_XmStringCompare) Xen_wrap_1_arg(gxm_XmStringEmpty_w, gxm_XmStringEmpty) Xen_wrap_2_args(gxm_XmStringHasSubstring_w, gxm_XmStringHasSubstring) Xen_wrap_1_arg(gxm_XmStringFree_w, gxm_XmStringFree) Xen_wrap_2_args(gxm_XmStringBaseline_w, gxm_XmStringBaseline) Xen_wrap_2_args(gxm_XmStringWidth_w, gxm_XmStringWidth) Xen_wrap_2_args(gxm_XmStringHeight_w, gxm_XmStringHeight) Xen_wrap_2_args(gxm_XmStringExtent_w, gxm_XmStringExtent) Xen_wrap_1_arg(gxm_XmStringLineCount_w, gxm_XmStringLineCount) Xen_wrap_any_args(gxm_XmStringDraw_w, gxm_XmStringDraw) Xen_wrap_any_args(gxm_XmStringDrawImage_w, gxm_XmStringDrawImage) Xen_wrap_any_args(gxm_XmStringDrawUnderline_w, gxm_XmStringDrawUnderline) Xen_wrap_1_arg(gxm_XmGetDestination_w, gxm_XmGetDestination) Xen_wrap_1_arg(gxm_XmIsTraversable_w, gxm_XmIsTraversable) Xen_wrap_1_arg(gxm_XmGetVisibility_w, gxm_XmGetVisibility) Xen_wrap_1_arg(gxm_XmGetTabGroup_w, gxm_XmGetTabGroup) Xen_wrap_1_arg(gxm_XmGetFocusWidget_w, gxm_XmGetFocusWidget) Xen_wrap_2_args(gxm_XmProcessTraversal_w, gxm_XmProcessTraversal) Xen_wrap_4_optional_args(gxm_XmCreateMenuShell_w, gxm_XmCreateMenuShell) Xen_wrap_1_arg(gxm_XmIsMessageBox_w, gxm_XmIsMessageBox) Xen_wrap_1_arg(gxm_XmIsArrowButtonGadget_w, gxm_XmIsArrowButtonGadget) Xen_wrap_1_arg(gxm_XmIsArrowButton_w, gxm_XmIsArrowButton) Xen_wrap_1_arg(gxm_XmCvtXmStringToByteStream_w, gxm_XmCvtXmStringToByteStream) Xen_wrap_1_arg(gxm_XmCvtByteStreamToXmString_w, gxm_XmCvtByteStreamToXmString) Xen_wrap_1_arg(gxm_XmStringByteStreamLength_w, gxm_XmStringByteStreamLength) Xen_wrap_1_arg(gxm_XmIsNotebook_w, gxm_XmIsNotebook) Xen_wrap_1_arg(gxm_XmIsComboBox_w, gxm_XmIsComboBox) Xen_wrap_1_arg(gxm_XmIsContainer_w, gxm_XmIsContainer) Xen_wrap_1_arg(gxm_XmIsGrabShell_w, gxm_XmIsGrabShell) Xen_wrap_1_arg(gxm_XmIsIconGadget_w, gxm_XmIsIconGadget) Xen_wrap_1_arg(gxm_XmIsIconHeader_w, gxm_XmIsIconHeader) Xen_wrap_1_arg(gxm_XmIsPanedWindow_w, gxm_XmIsPanedWindow) Xen_wrap_1_arg(gxm_XmIsBulletinBoard_w, gxm_XmIsBulletinBoard) Xen_wrap_1_arg(gxm_XmIsPrimitive_w, gxm_XmIsPrimitive) Xen_wrap_1_arg(gxm_XmIsCascadeButtonGadget_w, gxm_XmIsCascadeButtonGadget) Xen_wrap_1_arg(gxm_XmIsCascadeButton_w, gxm_XmIsCascadeButton) Xen_wrap_1_arg(gxm_XmIsPushButtonGadget_w, gxm_XmIsPushButtonGadget) Xen_wrap_1_arg(gxm_XmIsPushButton_w, gxm_XmIsPushButton) Xen_wrap_1_arg(gxm_XmIsCommand_w, gxm_XmIsCommand) Xen_wrap_1_arg(gxm_XmIsRowColumn_w, gxm_XmIsRowColumn) Xen_wrap_1_arg(gxm_XmIsScale_w, gxm_XmIsScale) Xen_wrap_1_arg(gxm_XmIsScreen_w, gxm_XmIsScreen) Xen_wrap_1_arg(gxm_XmIsScrollBar_w, gxm_XmIsScrollBar) Xen_wrap_1_arg(gxm_XmIsDialogShell_w, gxm_XmIsDialogShell) Xen_wrap_1_arg(gxm_XmIsScrolledWindow_w, gxm_XmIsScrolledWindow) Xen_wrap_1_arg(gxm_XmIsDisplay_w, gxm_XmIsDisplay) Xen_wrap_1_arg(gxm_XmIsSelectionBox_w, gxm_XmIsSelectionBox) Xen_wrap_1_arg(gxm_XmIsDragContext_w, gxm_XmIsDragContext) Xen_wrap_1_arg(gxm_XmIsSeparatorGadget_w, gxm_XmIsSeparatorGadget) Xen_wrap_1_arg(gxm_XmIsDragIconObjectClass_w, gxm_XmIsDragIconObjectClass) Xen_wrap_1_arg(gxm_XmIsSeparator_w, gxm_XmIsSeparator) Xen_wrap_1_arg(gxm_XmIsDrawingArea_w, gxm_XmIsDrawingArea) Xen_wrap_1_arg(gxm_XmIsDrawnButton_w, gxm_XmIsDrawnButton) Xen_wrap_1_arg(gxm_XmIsDropSiteManager_w, gxm_XmIsDropSiteManager) Xen_wrap_1_arg(gxm_XmIsDropTransfer_w, gxm_XmIsDropTransfer) Xen_wrap_1_arg(gxm_XmIsTextField_w, gxm_XmIsTextField) Xen_wrap_1_arg(gxm_XmIsFileSelectionBox_w, gxm_XmIsFileSelectionBox) Xen_wrap_1_arg(gxm_XmIsText_w, gxm_XmIsText) Xen_wrap_1_arg(gxm_XmIsForm_w, gxm_XmIsForm) Xen_wrap_1_arg(gxm_XmIsFrame_w, gxm_XmIsFrame) Xen_wrap_1_arg(gxm_XmIsGadget_w, gxm_XmIsGadget) Xen_wrap_1_arg(gxm_XmIsToggleButtonGadget_w, gxm_XmIsToggleButtonGadget) Xen_wrap_1_arg(gxm_XmIsToggleButton_w, gxm_XmIsToggleButton) Xen_wrap_1_arg(gxm_XmIsLabelGadget_w, gxm_XmIsLabelGadget) Xen_wrap_1_arg(gxm_XmIsLabel_w, gxm_XmIsLabel) Xen_wrap_1_arg(gxm_XmIsVendorShell_w, gxm_XmIsVendorShell) Xen_wrap_1_arg(gxm_XmIsList_w, gxm_XmIsList) Xen_wrap_1_arg(gxm_XmIsMainWindow_w, gxm_XmIsMainWindow) Xen_wrap_1_arg(gxm_XmIsManager_w, gxm_XmIsManager) Xen_wrap_1_arg(gxm_XmIsMenuShell_w, gxm_XmIsMenuShell) Xen_wrap_1_arg(gxm_XmListGetSelectedPos_w, gxm_XmListGetSelectedPos) Xen_wrap_1_arg(gxm_XmWidgetGetDisplayRect_w, gxm_XmWidgetGetDisplayRect) Xen_wrap_4_args(gxm_XpmCreatePixmapFromData_w, gxm_XpmCreatePixmapFromData) Xen_wrap_4_args(gxm_XpmCreateDataFromPixmap_w, gxm_XpmCreateDataFromPixmap) Xen_wrap_4_args(gxm_XpmReadFileToPixmap_w, gxm_XpmReadFileToPixmap) Xen_wrap_1_arg(gxm_XpmReadFileToXpmImage_w, gxm_XpmReadFileToXpmImage) Xen_wrap_5_args(gxm_XpmWriteFileFromPixmap_w, gxm_XpmWriteFileFromPixmap) Xen_wrap_4_args(gxm_XpmCreatePixmapFromXpmImage_w, gxm_XpmCreatePixmapFromXpmImage) Xen_wrap_4_args(gxm_XpmCreateXpmImageFromPixmap_w, gxm_XpmCreateXpmImageFromPixmap) Xen_wrap_1_arg(gxm_XpmGetErrorString_w, gxm_XpmGetErrorString) Xen_wrap_3_args(gxm_XGetPixel_w, gxm_XGetPixel) Xen_wrap_1_arg(gxm_XDestroyImage_w, gxm_XDestroyImage) Xen_wrap_4_args(gxm_XPutPixel_w, gxm_XPutPixel) Xen_wrap_5_args(gxm_XSubImage_w, gxm_XSubImage) Xen_wrap_2_args(gxm_XAddPixel_w, gxm_XAddPixel) Xen_wrap_1_arg(g_is_XtAppContext_w, g_is_XtAppContext) Xen_wrap_1_arg(g_is_XtRequestId_w, g_is_XtRequestId) Xen_wrap_1_arg(g_is_XtWorkProcId_w, g_is_XtWorkProcId) Xen_wrap_1_arg(g_is_XtInputId_w, g_is_XtInputId) Xen_wrap_1_arg(g_is_XtIntervalId_w, g_is_XtIntervalId) Xen_wrap_1_arg(g_is_Screen_w, g_is_Screen) Xen_wrap_1_arg(g_is_XEvent_w, g_is_XEvent) Xen_wrap_1_arg(g_is_XRectangle_w, g_is_XRectangle) Xen_wrap_1_arg(g_is_XArc_w, g_is_XArc) Xen_wrap_1_arg(g_is_XPoint_w, g_is_XPoint) Xen_wrap_1_arg(g_is_XSegment_w, g_is_XSegment) Xen_wrap_1_arg(g_is_XColor_w, g_is_XColor) Xen_wrap_1_arg(g_is_Atom_w, g_is_Atom) Xen_wrap_1_arg(g_is_Colormap_w, g_is_Colormap) Xen_wrap_1_arg(g_is_XModifierKeymap_w, g_is_XModifierKeymap) Xen_wrap_1_arg(g_is_Depth_w, g_is_Depth) Xen_wrap_1_arg(g_is_Display_w, g_is_Display) Xen_wrap_1_arg(g_is_Font_w, g_is_Font) Xen_wrap_1_arg(g_is_GC_w, g_is_GC) Xen_wrap_1_arg(g_is_KeySym_w, g_is_KeySym) Xen_wrap_1_arg(g_is_Pixel_w, g_is_Pixel) Xen_wrap_1_arg(g_is_Pixmap_w, g_is_Pixmap) Xen_wrap_1_arg(g_is_Region_w, g_is_Region) Xen_wrap_1_arg(g_is_Time_w, g_is_Time) Xen_wrap_1_arg(g_is_Visual_w, g_is_Visual) Xen_wrap_1_arg(g_is_Window_w, g_is_Window) Xen_wrap_1_arg(g_is_Widget_w, g_is_Widget) Xen_wrap_1_arg(g_is_XmStringContext_w, g_is_XmStringContext) Xen_wrap_1_arg(g_is_XFontProp_w, g_is_XFontProp) Xen_wrap_1_arg(g_is_XFontSet_w, g_is_XFontSet) Xen_wrap_1_arg(g_is_XFontStruct_w, g_is_XFontStruct) Xen_wrap_1_arg(g_is_XGCValues_w, g_is_XGCValues) Xen_wrap_1_arg(g_is_XImage_w, g_is_XImage) Xen_wrap_1_arg(g_is_XVisualInfo_w, g_is_XVisualInfo) Xen_wrap_1_arg(g_is_XWMHints_w, g_is_XWMHints) Xen_wrap_1_arg(g_is_XWindowAttributes_w, g_is_XWindowAttributes) Xen_wrap_1_arg(g_is_XWindowChanges_w, g_is_XWindowChanges) Xen_wrap_1_arg(g_is_KeyCode_w, g_is_KeyCode) Xen_wrap_1_arg(g_is_XContext_w, g_is_XContext) Xen_wrap_1_arg(g_is_XCharStruct_w, g_is_XCharStruct) Xen_wrap_1_arg(g_is_XTextItem_w, g_is_XTextItem) Xen_wrap_1_arg(g_is_XStandardColormap_w, g_is_XStandardColormap) Xen_wrap_1_arg(g_is_Cursor_w, g_is_Cursor) Xen_wrap_1_arg(g_is_WidgetClass_w, g_is_WidgetClass) Xen_wrap_1_arg(g_is_XmString_w, g_is_XmString) Xen_wrap_1_arg(g_is_XmTab_w, g_is_XmTab) Xen_wrap_1_arg(g_is_XmRendition_w, g_is_XmRendition) Xen_wrap_1_arg(g_is_XmRenderTable_w, g_is_XmRenderTable) Xen_wrap_1_arg(g_is_XmTabList_w, g_is_XmTabList) Xen_wrap_1_arg(g_is_XmParseMapping_w, g_is_XmParseMapping) Xen_wrap_1_arg(g_is_XmTextSource_w, g_is_XmTextSource) Xen_wrap_1_arg(g_is_XpmAttributes_w, g_is_XpmAttributes) Xen_wrap_1_arg(g_is_XpmImage_w, g_is_XpmImage) Xen_wrap_1_arg(g_is_XpmColorSymbol_w, g_is_XpmColorSymbol) #if WITH_EDITRES Xen_wrap_4_args(gxm_XEditResCheckMessages_w, gxm_XEditResCheckMessages) #endif #if HAVE_XSHAPEQUERYEXTENSION Xen_wrap_1_arg(gxm_XShapeQueryExtension_w, gxm_XShapeQueryExtension) Xen_wrap_1_arg(gxm_XShapeQueryVersion_w, gxm_XShapeQueryVersion) Xen_wrap_2_args(gxm_XShapeQueryExtents_w, gxm_XShapeQueryExtents) Xen_wrap_3_args(gxm_XShapeGetRectangles_w, gxm_XShapeGetRectangles) Xen_wrap_5_args(gxm_XShapeOffsetShape_w, gxm_XShapeOffsetShape) Xen_wrap_7_args(gxm_XShapeCombineRegion_w, gxm_XShapeCombineRegion) Xen_wrap_7_args(gxm_XShapeCombineMask_w, gxm_XShapeCombineMask) Xen_wrap_8_args(gxm_XShapeCombineShape_w, gxm_XShapeCombineShape) Xen_wrap_9_args(gxm_XShapeCombineRectangles_w, gxm_XShapeCombineRectangles) #endif Xen_wrap_4_args(gxm_XSegment_w, gxm_XSegment) Xen_wrap_4_args(gxm_XRectangle_w, gxm_XRectangle) Xen_wrap_6_optional_args(gxm_XColor_w, gxm_XColor) Xen_wrap_6_args(gxm_XArc_w, gxm_XArc) Xen_wrap_7_args(gxm_XWindowChanges_w, gxm_XWindowChanges) Xen_wrap_any_args(gxm_XSetWindowAttributes_w, gxm_XSetWindowAttributes) Xen_wrap_2_args(gxm_XPoint_w, gxm_XPoint) Xen_wrap_4_args(gxm_XTextItem_w, gxm_XTextItem) Xen_wrap_1_arg(gxm_pixel_w, gxm_pixel) Xen_wrap_2_args(gxm_set_pixel_w, gxm_set_pixel) Xen_wrap_1_arg(gxm_red_w, gxm_red) Xen_wrap_2_args(gxm_set_red_w, gxm_set_red) Xen_wrap_1_arg(gxm_green_w, gxm_green) Xen_wrap_2_args(gxm_set_green_w, gxm_set_green) Xen_wrap_1_arg(gxm_blue_w, gxm_blue) Xen_wrap_2_args(gxm_set_blue_w, gxm_set_blue) Xen_wrap_1_arg(gxm_flags_w, gxm_flags) Xen_wrap_2_args(gxm_set_flags_w, gxm_set_flags) Xen_wrap_1_arg(gxm_pad_w, gxm_pad) Xen_wrap_2_args(gxm_set_pad_w, gxm_set_pad) Xen_wrap_1_arg(gxm_x_w, gxm_x) Xen_wrap_2_args(gxm_set_x_w, gxm_set_x) Xen_wrap_1_arg(gxm_y_w, gxm_y) Xen_wrap_2_args(gxm_set_y_w, gxm_set_y) Xen_wrap_1_arg(gxm_width_w, gxm_width) Xen_wrap_2_args(gxm_set_width_w, gxm_set_width) Xen_wrap_1_arg(gxm_height_w, gxm_height) Xen_wrap_2_args(gxm_set_height_w, gxm_set_height) Xen_wrap_1_arg(gxm_angle1_w, gxm_angle1) Xen_wrap_2_args(gxm_set_angle1_w, gxm_set_angle1) Xen_wrap_1_arg(gxm_angle2_w, gxm_angle2) Xen_wrap_2_args(gxm_set_angle2_w, gxm_set_angle2) Xen_wrap_1_arg(gxm_x1_w, gxm_x1) Xen_wrap_2_args(gxm_set_x1_w, gxm_set_x1) Xen_wrap_1_arg(gxm_y1_w, gxm_y1) Xen_wrap_2_args(gxm_set_y1_w, gxm_set_y1) Xen_wrap_1_arg(gxm_x2_w, gxm_x2) Xen_wrap_2_args(gxm_set_x2_w, gxm_set_x2) Xen_wrap_1_arg(gxm_y2_w, gxm_y2) Xen_wrap_2_args(gxm_set_y2_w, gxm_set_y2) Xen_wrap_1_arg(gxm_dashes_w, gxm_dashes) Xen_wrap_2_args(gxm_set_dashes_w, gxm_set_dashes) Xen_wrap_1_arg(gxm_dash_offset_w, gxm_dash_offset) Xen_wrap_2_args(gxm_set_dash_offset_w, gxm_set_dash_offset) Xen_wrap_1_arg(gxm_clip_mask_w, gxm_clip_mask) Xen_wrap_2_args(gxm_set_clip_mask_w, gxm_set_clip_mask) Xen_wrap_1_arg(gxm_clip_y_origin_w, gxm_clip_y_origin) Xen_wrap_2_args(gxm_set_clip_y_origin_w, gxm_set_clip_y_origin) Xen_wrap_1_arg(gxm_clip_x_origin_w, gxm_clip_x_origin) Xen_wrap_2_args(gxm_set_clip_x_origin_w, gxm_set_clip_x_origin) Xen_wrap_1_arg(gxm_graphics_exposures_w, gxm_graphics_exposures) Xen_wrap_2_args(gxm_set_graphics_exposures_w, gxm_set_graphics_exposures) Xen_wrap_1_arg(gxm_subwindow_mode_w, gxm_subwindow_mode) Xen_wrap_2_args(gxm_set_subwindow_mode_w, gxm_set_subwindow_mode) Xen_wrap_1_arg(gxm_font_w, gxm_font) Xen_wrap_2_args(gxm_set_font_w, gxm_set_font) Xen_wrap_1_arg(gxm_ts_y_origin_w, gxm_ts_y_origin) Xen_wrap_2_args(gxm_set_ts_y_origin_w, gxm_set_ts_y_origin) Xen_wrap_1_arg(gxm_ts_x_origin_w, gxm_ts_x_origin) Xen_wrap_2_args(gxm_set_ts_x_origin_w, gxm_set_ts_x_origin) Xen_wrap_1_arg(gxm_stipple_w, gxm_stipple) Xen_wrap_2_args(gxm_set_stipple_w, gxm_set_stipple) Xen_wrap_1_arg(gxm_tile_w, gxm_tile) Xen_wrap_2_args(gxm_set_tile_w, gxm_set_tile) Xen_wrap_1_arg(gxm_arc_mode_w, gxm_arc_mode) Xen_wrap_2_args(gxm_set_arc_mode_w, gxm_set_arc_mode) Xen_wrap_1_arg(gxm_fill_rule_w, gxm_fill_rule) Xen_wrap_2_args(gxm_set_fill_rule_w, gxm_set_fill_rule) Xen_wrap_1_arg(gxm_fill_style_w, gxm_fill_style) Xen_wrap_2_args(gxm_set_fill_style_w, gxm_set_fill_style) Xen_wrap_1_arg(gxm_join_style_w, gxm_join_style) Xen_wrap_2_args(gxm_set_join_style_w, gxm_set_join_style) Xen_wrap_1_arg(gxm_cap_style_w, gxm_cap_style) Xen_wrap_2_args(gxm_set_cap_style_w, gxm_set_cap_style) Xen_wrap_1_arg(gxm_line_style_w, gxm_line_style) Xen_wrap_2_args(gxm_set_line_style_w, gxm_set_line_style) Xen_wrap_1_arg(gxm_line_width_w, gxm_line_width) Xen_wrap_2_args(gxm_set_line_width_w, gxm_set_line_width) Xen_wrap_1_arg(gxm_background_w, gxm_background) Xen_wrap_2_args(gxm_set_background_w, gxm_set_background) Xen_wrap_1_arg(gxm_foreground_w, gxm_foreground) Xen_wrap_2_args(gxm_set_foreground_w, gxm_set_foreground) Xen_wrap_1_arg(gxm_plane_mask_w, gxm_plane_mask) Xen_wrap_2_args(gxm_set_plane_mask_w, gxm_set_plane_mask) Xen_wrap_1_arg(gxm_function_w, gxm_function) Xen_wrap_2_args(gxm_set_function_w, gxm_set_function) Xen_wrap_1_arg(gxm_delta_w, gxm_delta) Xen_wrap_2_args(gxm_set_delta_w, gxm_set_delta) Xen_wrap_1_arg(gxm_nchars_w, gxm_nchars) Xen_wrap_2_args(gxm_set_nchars_w, gxm_set_nchars) Xen_wrap_1_arg(gxm_chars_w, gxm_chars) Xen_wrap_2_args(gxm_set_chars_w, gxm_set_chars) Xen_wrap_1_arg(gxm_name_w, gxm_name) Xen_wrap_2_args(gxm_set_name_w, gxm_set_name) Xen_wrap_1_arg(gxm_depth_w, gxm_depth) Xen_wrap_2_args(gxm_set_depth_w, gxm_set_depth) Xen_wrap_1_arg(gxm_visual_w, gxm_visual) Xen_wrap_2_args(gxm_set_visual_w, gxm_set_visual) Xen_wrap_1_arg(gxm_display_w, gxm_display) Xen_wrap_1_arg(gxm_root_w, gxm_root) Xen_wrap_1_arg(gxm_mwidth_w, gxm_mwidth) Xen_wrap_1_arg(gxm_mheight_w, gxm_mheight) Xen_wrap_1_arg(gxm_ndepths_w, gxm_ndepths) Xen_wrap_1_arg(gxm_depths_w, gxm_depths) Xen_wrap_1_arg(gxm_root_depth_w, gxm_root_depth) Xen_wrap_1_arg(gxm_root_visual_w, gxm_root_visual) Xen_wrap_1_arg(gxm_default_gc_w, gxm_default_gc) Xen_wrap_1_arg(gxm_cmap_w, gxm_cmap) Xen_wrap_1_arg(gxm_white_pixel_w, gxm_white_pixel) Xen_wrap_1_arg(gxm_black_pixel_w, gxm_black_pixel) Xen_wrap_1_arg(gxm_max_maps_w, gxm_max_maps) Xen_wrap_1_arg(gxm_min_maps_w, gxm_min_maps) Xen_wrap_1_arg(gxm_backing_store_w, gxm_backing_store) Xen_wrap_1_arg(gxm_save_unders_w, gxm_save_unders) Xen_wrap_1_arg(gxm_root_input_mask_w, gxm_root_input_mask) Xen_wrap_1_arg(gxm_type_w, gxm_type) Xen_wrap_1_arg(gxm_serial_w, gxm_serial) Xen_wrap_1_arg(gxm_send_event_w, gxm_send_event) Xen_wrap_1_arg(gxm_window_w, gxm_window) Xen_wrap_1_arg(gxm_subwindow_w, gxm_subwindow) Xen_wrap_1_arg(gxm_time_w, gxm_time) Xen_wrap_1_arg(gxm_x_root_w, gxm_x_root) Xen_wrap_1_arg(gxm_y_root_w, gxm_y_root) Xen_wrap_1_arg(gxm_state_w, gxm_state) Xen_wrap_1_arg(gxm_keycode_w, gxm_keycode) Xen_wrap_1_arg(gxm_same_screen_w, gxm_same_screen) Xen_wrap_1_arg(gxm_button_w, gxm_button) Xen_wrap_1_arg(gxm_is_hint_w, gxm_is_hint) Xen_wrap_1_arg(gxm_mode_w, gxm_mode) Xen_wrap_1_arg(gxm_detail_w, gxm_detail) Xen_wrap_1_arg(gxm_focus_w, gxm_focus) Xen_wrap_1_arg(gxm_key_vector_w, gxm_key_vector) Xen_wrap_1_arg(gxm_count_w, gxm_count) Xen_wrap_1_arg(gxm_drawable_w, gxm_drawable) Xen_wrap_1_arg(gxm_major_code_w, gxm_major_code) Xen_wrap_1_arg(gxm_minor_code_w, gxm_minor_code) Xen_wrap_1_arg(gxm_parent_w, gxm_parent) Xen_wrap_1_arg(gxm_border_width_w, gxm_border_width) Xen_wrap_1_arg(gxm_override_redirect_w, gxm_override_redirect) Xen_wrap_1_arg(gxm_event_w, gxm_event) Xen_wrap_1_arg(gxm_from_configure_w, gxm_from_configure) Xen_wrap_1_arg(gxm_above_w, gxm_above) Xen_wrap_1_arg(gxm_value_mask_w, gxm_value_mask) Xen_wrap_1_arg(gxm_place_w, gxm_place) Xen_wrap_1_arg(gxm_atom_w, gxm_atom) Xen_wrap_1_arg(gxm_selection_w, gxm_selection) Xen_wrap_1_arg(gxm_owner_w, gxm_owner) Xen_wrap_1_arg(gxm_requestor_w, gxm_requestor) Xen_wrap_1_arg(gxm_target_w, gxm_target) Xen_wrap_1_arg(gxm_property_w, gxm_property) Xen_wrap_1_arg(gxm_new_w, gxm_new) Xen_wrap_1_arg(gxm_message_type_w, gxm_message_type) Xen_wrap_1_arg(gxm_format_w, gxm_format) Xen_wrap_1_arg(gxm_request_w, gxm_request) Xen_wrap_1_arg(gxm_first_keycode_w, gxm_first_keycode) Xen_wrap_1_arg(gxm_resourceid_w, gxm_resourceid) Xen_wrap_1_arg(gxm_error_code_w, gxm_error_code) Xen_wrap_1_arg(gxm_request_code_w, gxm_request_code) Xen_wrap_1_arg(gxm_lbearing_w, gxm_lbearing) Xen_wrap_1_arg(gxm_rbearing_w, gxm_rbearing) Xen_wrap_1_arg(gxm_ascent_w, gxm_ascent) Xen_wrap_1_arg(gxm_descent_w, gxm_descent) Xen_wrap_1_arg(gxm_attributes_w, gxm_attributes) Xen_wrap_1_arg(gxm_card32_w, gxm_card32) Xen_wrap_1_arg(gxm_fid_w, gxm_fid) Xen_wrap_1_arg(gxm_properties_w, gxm_properties) Xen_wrap_1_arg(gxm_min_bounds_w, gxm_min_bounds) Xen_wrap_1_arg(gxm_max_bounds_w, gxm_max_bounds) Xen_wrap_1_arg(gxm_per_char_w, gxm_per_char) Xen_wrap_1_arg(gxm_input_w, gxm_input) Xen_wrap_1_arg(gxm_initial_state_w, gxm_initial_state) Xen_wrap_1_arg(gxm_icon_pixmap_w, gxm_icon_pixmap) Xen_wrap_1_arg(gxm_icon_window_w, gxm_icon_window) Xen_wrap_1_arg(gxm_icon_x_w, gxm_icon_x) Xen_wrap_1_arg(gxm_icon_y_w, gxm_icon_y) Xen_wrap_1_arg(gxm_icon_mask_w, gxm_icon_mask) Xen_wrap_1_arg(gxm_window_group_w, gxm_window_group) Xen_wrap_1_arg(gxm_visualid_w, gxm_visualid) Xen_wrap_1_arg(gxm_class_w, gxm_class) Xen_wrap_1_arg(gxm_red_mask_w, gxm_red_mask) Xen_wrap_1_arg(gxm_green_mask_w, gxm_green_mask) Xen_wrap_1_arg(gxm_blue_mask_w, gxm_blue_mask) Xen_wrap_1_arg(gxm_bits_per_rgb_w, gxm_bits_per_rgb) Xen_wrap_1_arg(gxm_map_entries_w, gxm_map_entries) Xen_wrap_1_arg(gxm_colormap_size_w, gxm_colormap_size) Xen_wrap_1_arg(gxm_nvisuals_w, gxm_nvisuals) Xen_wrap_1_arg(gxm_visuals_w, gxm_visuals) Xen_wrap_1_arg(gxm_bits_per_pixel_w, gxm_bits_per_pixel) Xen_wrap_1_arg(gxm_background_pixmap_w, gxm_background_pixmap) Xen_wrap_1_arg(gxm_background_pixel_w, gxm_background_pixel) Xen_wrap_1_arg(gxm_border_pixmap_w, gxm_border_pixmap) Xen_wrap_1_arg(gxm_border_pixel_w, gxm_border_pixel) Xen_wrap_1_arg(gxm_bit_gravity_w, gxm_bit_gravity) Xen_wrap_1_arg(gxm_win_gravity_w, gxm_win_gravity) Xen_wrap_1_arg(gxm_backing_planes_w, gxm_backing_planes) Xen_wrap_1_arg(gxm_backing_pixel_w, gxm_backing_pixel) Xen_wrap_1_arg(gxm_save_under_w, gxm_save_under) Xen_wrap_1_arg(gxm_event_mask_w, gxm_event_mask) Xen_wrap_1_arg(gxm_do_not_propagate_mask_w, gxm_do_not_propagate_mask) Xen_wrap_1_arg(gxm_cursor_w, gxm_cursor) Xen_wrap_1_arg(gxm_map_installed_w, gxm_map_installed) Xen_wrap_1_arg(gxm_map_state_w, gxm_map_state) Xen_wrap_1_arg(gxm_all_event_masks_w, gxm_all_event_masks) Xen_wrap_1_arg(gxm_your_event_mask_w, gxm_your_event_mask) Xen_wrap_1_arg(gxm_screen_w, gxm_screen) Xen_wrap_1_arg(gxm_xoffset_w, gxm_xoffset) Xen_wrap_1_arg(gxm_byte_order_w, gxm_byte_order) Xen_wrap_1_arg(gxm_bitmap_unit_w, gxm_bitmap_unit) Xen_wrap_1_arg(gxm_bitmap_bit_order_w, gxm_bitmap_bit_order) Xen_wrap_1_arg(gxm_bitmap_pad_w, gxm_bitmap_pad) Xen_wrap_1_arg(gxm_bytes_per_line_w, gxm_bytes_per_line) Xen_wrap_1_arg(gxm_obdata_w, gxm_obdata) Xen_wrap_1_arg(gxm_sibling_w, gxm_sibling) Xen_wrap_1_arg(gxm_stack_mode_w, gxm_stack_mode) Xen_wrap_1_arg(gxm_red_max_w, gxm_red_max) Xen_wrap_1_arg(gxm_red_mult_w, gxm_red_mult) Xen_wrap_1_arg(gxm_green_max_w, gxm_green_max) Xen_wrap_1_arg(gxm_green_mult_w, gxm_green_mult) Xen_wrap_1_arg(gxm_blue_max_w, gxm_blue_max) Xen_wrap_1_arg(gxm_blue_mult_w, gxm_blue_mult) Xen_wrap_1_arg(gxm_base_pixel_w, gxm_base_pixel) Xen_wrap_1_arg(gxm_killid_w, gxm_killid) Xen_wrap_1_arg(gxm_data_w, gxm_data) Xen_wrap_2_args(gxm_set_request_code_w, gxm_set_request_code) Xen_wrap_2_args(gxm_set_error_code_w, gxm_set_error_code) Xen_wrap_2_args(gxm_set_first_keycode_w, gxm_set_first_keycode) Xen_wrap_2_args(gxm_set_request_w, gxm_set_request) Xen_wrap_2_args(gxm_set_resourceid_w, gxm_set_resourceid) Xen_wrap_2_args(gxm_set_format_w, gxm_set_format) Xen_wrap_2_args(gxm_set_message_type_w, gxm_set_message_type) Xen_wrap_2_args(gxm_set_new_w, gxm_set_new) Xen_wrap_2_args(gxm_set_property_w, gxm_set_property) Xen_wrap_2_args(gxm_set_display_w, gxm_set_display) Xen_wrap_2_args(gxm_set_target_w, gxm_set_target) Xen_wrap_2_args(gxm_set_requestor_w, gxm_set_requestor) Xen_wrap_2_args(gxm_set_owner_w, gxm_set_owner) Xen_wrap_2_args(gxm_set_selection_w, gxm_set_selection) Xen_wrap_2_args(gxm_set_atom_w, gxm_set_atom) Xen_wrap_2_args(gxm_set_place_w, gxm_set_place) Xen_wrap_2_args(gxm_set_value_mask_w, gxm_set_value_mask) Xen_wrap_2_args(gxm_set_above_w, gxm_set_above) Xen_wrap_2_args(gxm_set_from_configure_w, gxm_set_from_configure) Xen_wrap_2_args(gxm_set_event_w, gxm_set_event) Xen_wrap_2_args(gxm_set_override_redirect_w, gxm_set_override_redirect) Xen_wrap_2_args(gxm_set_border_width_w, gxm_set_border_width) Xen_wrap_2_args(gxm_set_parent_w, gxm_set_parent) Xen_wrap_2_args(gxm_set_minor_code_w, gxm_set_minor_code) Xen_wrap_2_args(gxm_set_major_code_w, gxm_set_major_code) Xen_wrap_2_args(gxm_set_drawable_w, gxm_set_drawable) Xen_wrap_2_args(gxm_set_count_w, gxm_set_count) Xen_wrap_2_args(gxm_set_key_vector_w, gxm_set_key_vector) Xen_wrap_2_args(gxm_set_focus_w, gxm_set_focus) Xen_wrap_2_args(gxm_set_detail_w, gxm_set_detail) Xen_wrap_2_args(gxm_set_mode_w, gxm_set_mode) Xen_wrap_2_args(gxm_set_is_hint_w, gxm_set_is_hint) Xen_wrap_2_args(gxm_set_button_w, gxm_set_button) Xen_wrap_2_args(gxm_set_same_screen_w, gxm_set_same_screen) Xen_wrap_2_args(gxm_set_keycode_w, gxm_set_keycode) Xen_wrap_2_args(gxm_set_state_w, gxm_set_state) Xen_wrap_2_args(gxm_set_y_root_w, gxm_set_y_root) Xen_wrap_2_args(gxm_set_x_root_w, gxm_set_x_root) Xen_wrap_2_args(gxm_set_root_w, gxm_set_root) Xen_wrap_2_args(gxm_set_time_w, gxm_set_time) Xen_wrap_2_args(gxm_set_subwindow_w, gxm_set_subwindow) Xen_wrap_2_args(gxm_set_window_w, gxm_set_window) Xen_wrap_2_args(gxm_set_send_event_w, gxm_set_send_event) Xen_wrap_2_args(gxm_set_serial_w, gxm_set_serial) Xen_wrap_2_args(gxm_set_type_w, gxm_set_type) Xen_wrap_1_arg(gxm_colormap_w, gxm_colormap) Xen_wrap_2_args(gxm_set_colormap_w, gxm_set_colormap) Xen_wrap_2_args(gxm_set_input_w, gxm_set_input) Xen_wrap_2_args(gxm_set_initial_state_w, gxm_set_initial_state) Xen_wrap_1_arg(gxm_min_height_w, gxm_min_height) Xen_wrap_1_arg(gxm_max_height_w, gxm_max_height) Xen_wrap_1_arg(gxm_min_width_w, gxm_min_width) Xen_wrap_1_arg(gxm_max_width_w, gxm_max_width) Xen_wrap_1_arg(gxm_height_inc_w, gxm_height_inc) Xen_wrap_1_arg(gxm_width_inc_w, gxm_width_inc) Xen_wrap_2_args(gxm_set_data_w, gxm_set_data) Xen_wrap_2_args(gxm_set_backing_store_w, gxm_set_backing_store) Xen_wrap_2_args(gxm_set_background_pixel_w, gxm_set_background_pixel) Xen_wrap_2_args(gxm_set_border_pixel_w, gxm_set_border_pixel) Xen_wrap_2_args(gxm_set_bit_gravity_w, gxm_set_bit_gravity) Xen_wrap_2_args(gxm_set_save_under_w, gxm_set_save_under) Xen_wrap_2_args(gxm_set_event_mask_w, gxm_set_event_mask) Xen_wrap_2_args(gxm_set_cursor_w, gxm_set_cursor) Xen_wrap_2_args(gxm_set_set_w, gxm_set_set) Xen_wrap_2_args(gxm_set_click_count_w, gxm_set_click_count) Xen_wrap_2_args(gxm_set_length_w, gxm_set_length) Xen_wrap_1_arg(gxm_ptr_w, gxm_ptr) Xen_wrap_2_args(gxm_set_ptr_w, gxm_set_ptr) Xen_wrap_2_args(gxm_set_reason_w, gxm_set_reason) Xen_wrap_1_arg(gxm_page_number_w, gxm_page_number) Xen_wrap_1_arg(gxm_page_widget_w, gxm_page_widget) Xen_wrap_1_arg(gxm_status_area_widget_w, gxm_status_area_widget) Xen_wrap_1_arg(gxm_major_tab_widget_w, gxm_major_tab_widget) Xen_wrap_1_arg(gxm_minor_tab_widget_w, gxm_minor_tab_widget) Xen_wrap_1_arg(gxm_source_data_w, gxm_source_data) Xen_wrap_1_arg(gxm_location_data_w, gxm_location_data) Xen_wrap_1_arg(gxm_parm_w, gxm_parm) Xen_wrap_1_arg(gxm_parm_format_w, gxm_parm_format) Xen_wrap_1_arg(gxm_parm_length_w, gxm_parm_length) Xen_wrap_1_arg(gxm_parm_type_w, gxm_parm_type) Xen_wrap_1_arg(gxm_transfer_id_w, gxm_transfer_id) Xen_wrap_1_arg(gxm_destination_data_w, gxm_destination_data) Xen_wrap_1_arg(gxm_remaining_w, gxm_remaining) Xen_wrap_1_arg(gxm_item_or_text_w, gxm_item_or_text) Xen_wrap_1_arg(gxm_auto_selection_type_w, gxm_auto_selection_type) Xen_wrap_1_arg(gxm_new_outline_state_w, gxm_new_outline_state) Xen_wrap_1_arg(gxm_prev_page_number_w, gxm_prev_page_number) Xen_wrap_1_arg(gxm_prev_page_widget_w, gxm_prev_page_widget) Xen_wrap_1_arg(gxm_rendition_w, gxm_rendition) Xen_wrap_1_arg(gxm_render_table_w, gxm_render_table) Xen_wrap_1_arg(gxm_crossed_boundary_w, gxm_crossed_boundary) Xen_wrap_1_arg(gxm_client_data_w, gxm_client_data) Xen_wrap_1_arg(gxm_status_w, gxm_status) Xen_wrap_1_arg(gxm_font_name_w, gxm_font_name) Xen_wrap_1_arg(gxm_tag_w, gxm_tag) Xen_wrap_1_arg(gxm_traversal_destination_w, gxm_traversal_destination) Xen_wrap_1_arg(gxm_dragProtocolStyle_w, gxm_dragProtocolStyle) Xen_wrap_1_arg(gxm_direction_w, gxm_direction) Xen_wrap_1_arg(gxm_reason_w, gxm_reason) Xen_wrap_1_arg(gxm_timeStamp_w, gxm_timeStamp) Xen_wrap_1_arg(gxm_operation_w, gxm_operation ) Xen_wrap_2_args(gxm_set_operation_w, gxm_set_operation) Xen_wrap_1_arg(gxm_operations_w, gxm_operations) Xen_wrap_1_arg(gxm_dropSiteStatus_w, gxm_dropSiteStatus ) Xen_wrap_2_args(gxm_set_dropSiteStatus_w, gxm_set_dropSiteStatus) Xen_wrap_1_arg(gxm_dropAction_w, gxm_dropAction) Xen_wrap_1_arg(gxm_iccHandle_w, gxm_iccHandle) Xen_wrap_1_arg(gxm_completionStatus_w, gxm_completionStatus) Xen_wrap_1_arg(gxm_dragContext_w, gxm_dragContext) Xen_wrap_1_arg(gxm_animate_w, gxm_animate) Xen_wrap_1_arg(gxm_length_w, gxm_length) Xen_wrap_1_arg(gxm_click_count_w, gxm_click_count) Xen_wrap_1_arg(gxm_widget_w, gxm_widget) Xen_wrap_1_arg(gxm_item_position_w, gxm_item_position) Xen_wrap_1_arg(gxm_callbackstruct_w, gxm_callbackstruct) Xen_wrap_1_arg(gxm_set_w, gxm_set) Xen_wrap_1_arg(gxm_item_w, gxm_item) Xen_wrap_1_arg(gxm_item_length_w, gxm_item_length) Xen_wrap_1_arg(gxm_selected_items_w, gxm_selected_items) Xen_wrap_1_arg(gxm_selected_item_count_w, gxm_selected_item_count) Xen_wrap_1_arg(gxm_selected_item_positions_w, gxm_selected_item_positions) Xen_wrap_1_arg(gxm_selection_type_w, gxm_selection_type) Xen_wrap_1_arg(gxm_mask_w, gxm_mask) Xen_wrap_1_arg(gxm_mask_length_w, gxm_mask_length) Xen_wrap_1_arg(gxm_dir_w, gxm_dir) Xen_wrap_1_arg(gxm_dir_length_w, gxm_dir_length) Xen_wrap_1_arg(gxm_pattern_w, gxm_pattern) Xen_wrap_1_arg(gxm_pattern_length_w, gxm_pattern_length) Xen_wrap_1_arg(gxm_position_w, gxm_position) Xen_wrap_1_arg(gxm_currInsert_w, gxm_currInsert) Xen_wrap_1_arg(gxm_newInsert_w, gxm_newInsert) Xen_wrap_1_arg(gxm_startPos_w, gxm_startPos) Xen_wrap_1_arg(gxm_endPos_w, gxm_endPos) Xen_wrap_1_arg(gxm_text_w, gxm_text) Xen_wrap_1_arg(gxm_value_w, gxm_value) Xen_wrap_2_args(gxm_set_value_w, gxm_set_value) Xen_wrap_1_arg(gxm_doit_w, gxm_doit) Xen_wrap_2_args(gxm_set_doit_w, gxm_set_doit) Xen_wrap_1_arg(gxm_menuToPost_w, gxm_menuToPost) Xen_wrap_2_args(gxm_set_menuToPost_w, gxm_set_menuToPost) Xen_wrap_1_arg(gxm_postIt_w, gxm_postIt) Xen_wrap_2_args(gxm_set_postIt_w, gxm_set_postIt) Xen_wrap_1_arg(gxm_valuemask_w, gxm_valuemask) Xen_wrap_2_args(gxm_set_valuemask_w, gxm_set_valuemask) Xen_wrap_1_arg(gxm_ncolors_w, gxm_ncolors) Xen_wrap_2_args(gxm_set_ncolors_w, gxm_set_ncolors) Xen_wrap_1_arg(gxm_cpp_w, gxm_cpp) Xen_wrap_2_args(gxm_set_cpp_w, gxm_set_cpp) Xen_wrap_1_arg(gxm_numsymbols_w, gxm_numsymbols) Xen_wrap_2_args(gxm_set_numsymbols_w, gxm_set_numsymbols) Xen_wrap_1_arg(gxm_colorsymbols_w, gxm_colorsymbols) Xen_wrap_2_args(gxm_set_colorsymbols_w, gxm_set_colorsymbols) Xen_wrap_1_arg(gxm_npixels_w, gxm_npixels) Xen_wrap_2_args(gxm_set_npixels_w, gxm_set_npixels) Xen_wrap_1_arg(gxm_y_hotspot_w, gxm_y_hotspot) Xen_wrap_2_args(gxm_set_y_hotspot_w, gxm_set_y_hotspot) Xen_wrap_1_arg(gxm_x_hotspot_w, gxm_x_hotspot) Xen_wrap_2_args(gxm_set_x_hotspot_w, gxm_set_x_hotspot) Xen_wrap_5_args(gxm_XpmImage_w, gxm_XpmImage) Xen_wrap_3_args(gxm_XpmColorSymbol_w, gxm_XpmColorSymbol) Xen_wrap_no_args(gxm_XpmAttributes_w, gxm_XpmAttributes) #if HAVE_SCHEME Xen_wrap_2_args(c_to_xen_strings_w, c_to_xen_strings) Xen_wrap_2_args(c_to_xen_ints_w, c_to_xen_ints) Xen_wrap_2_args(c_to_xen_atoms_w, c_to_xen_atoms) Xen_wrap_2_args(c_to_xen_xrectangles_w, c_to_xen_xrectangles) #endif static void define_procedures(void) { #define XM_define_procedure(Name, Value, A1, A2, A3, Help) Xen_define_safe_procedure(XM_PREFIX #Name XM_POSTFIX, Value, A1, A2, A3, Help) xm_gc_table = Xen_make_vector(1, Xen_false); Xen_GC_protect(xm_gc_table); xm_protected_size = 512; xm_protected = Xen_make_vector(xm_protected_size, Xen_false); Xen_vector_set(xm_gc_table, 0, xm_protected); XM_define_procedure(XtSetArg, gxm_XtSetArg_w, 3, 0, 0, H_XtSetArg); XM_define_procedure(XtManageChildren, gxm_XtManageChildren_w, 1, 1, 0, H_XtManageChildren); XM_define_procedure(XtManageChild, gxm_XtManageChild_w, 1, 0, 0, H_XtManageChild); XM_define_procedure(XtUnmanageChildren, gxm_XtUnmanageChildren_w, 1, 1, 0, H_XtUnmanageChildren); XM_define_procedure(XtUnmanageChild, gxm_XtUnmanageChild_w, 1, 0, 0, H_XtUnmanageChild); XM_define_procedure(XtDispatchEvent, gxm_XtDispatchEvent_w, 1, 0, 0, H_XtDispatchEvent); XM_define_procedure(XtCallAcceptFocus, gxm_XtCallAcceptFocus_w, 2, 0, 0, H_XtCallAcceptFocus); XM_define_procedure(XtAppPeekEvent, gxm_XtAppPeekEvent_w, 1, 0, 0, H_XtAppPeekEvent); XM_define_procedure(XtIsSubclass, gxm_XtIsSubclass_w, 2, 0, 0, H_XtIsSubclass); XM_define_procedure(XtIsObject, gxm_XtIsObject_w, 1, 0, 0, H_XtIsObject); XM_define_procedure(XtIsManaged, gxm_XtIsManaged_w, 1, 0, 0, H_XtIsManaged); XM_define_procedure(XtIsRealized, gxm_XtIsRealized_w, 1, 0, 0, H_XtIsRealized); XM_define_procedure(XtIsSensitive, gxm_XtIsSensitive_w, 1, 0, 0, H_XtIsSensitive); XM_define_procedure(XtOwnSelection, gxm_XtOwnSelection_w, 6, 0, 0, H_XtOwnSelection); XM_define_procedure(XtOwnSelectionIncremental, gxm_XtOwnSelectionIncremental_w, 8, 0, 0, H_XtOwnSelectionIncremental); XM_define_procedure(XtMakeResizeRequest, gxm_XtMakeResizeRequest_w, 3, 0, 0, H_XtMakeResizeRequest); XM_define_procedure(XtTranslateCoords, gxm_XtTranslateCoords_w, 3, 0, 0, H_XtTranslateCoords); XM_define_procedure(XtKeysymToKeycodeList, gxm_XtKeysymToKeycodeList_w, 2, 0, 0, H_XtKeysymToKeycodeList); XM_define_procedure(XtParseTranslationTable, gxm_XtParseTranslationTable_w, 1, 0, 0, H_XtParseTranslationTable); XM_define_procedure(XtParseAcceleratorTable, gxm_XtParseAcceleratorTable_w, 1, 0, 0, H_XtParseAcceleratorTable); XM_define_procedure(XtOverrideTranslations, gxm_XtOverrideTranslations_w, 2, 0, 0, H_XtOverrideTranslations); XM_define_procedure(XtAugmentTranslations, gxm_XtAugmentTranslations_w, 2, 0, 0, H_XtAugmentTranslations); XM_define_procedure(XtInstallAccelerators, gxm_XtInstallAccelerators_w, 2, 0, 0, H_XtInstallAccelerators); XM_define_procedure(XtInstallAllAccelerators, gxm_XtInstallAllAccelerators_w, 2, 0, 0, H_XtInstallAllAccelerators); XM_define_procedure(XtUninstallTranslations, gxm_XtUninstallTranslations_w, 1, 0, 0, H_XtUninstallTranslations); XM_define_procedure(XtAppAddActions, gxm_XtAppAddActions_w, 2, 0, 0, H_XtAppAddActions); XM_define_procedure(XtAppAddActionHook, gxm_XtAppAddActionHook_w, 2, 1, 0, H_XtAppAddActionHook); XM_define_procedure(XtRemoveActionHook, gxm_XtRemoveActionHook_w, 1, 0, 0, H_XtRemoveActionHook); XM_define_procedure(XtGetActionList, gxm_XtGetActionList_w, 1, 0, 0, H_XtGetActionList); XM_define_procedure(XtCallActionProc, gxm_XtCallActionProc_w, 4, 1, 0, H_XtCallActionProc); XM_define_procedure(XtRegisterGrabAction, gxm_XtRegisterGrabAction_w, 5, 0, 0, H_XtRegisterGrabAction); XM_define_procedure(XtSetMultiClickTime, gxm_XtSetMultiClickTime_w, 2, 0, 0, H_XtSetMultiClickTime); XM_define_procedure(XtGetMultiClickTime, gxm_XtGetMultiClickTime_w, 1, 0, 0, H_XtGetMultiClickTime); XM_define_procedure(XtGetResourceList, gxm_XtGetResourceList_w, 1, 0, 0, H_XtGetResourceList); XM_define_procedure(XtGetActionKeysym, gxm_XtGetActionKeysym_w, 1, 0, 0, H_XtGetActionKeysym); XM_define_procedure(XtTranslateKeycode, gxm_XtTranslateKeycode_w, 3, 0, 0, H_XtTranslateKeycode); XM_define_procedure(XtTranslateKey, gxm_XtTranslateKey_w, 3, 0, 0, H_XtTranslateKey); XM_define_procedure(XtSetKeyTranslator, gxm_XtSetKeyTranslator_w, 2, 0, 0, H_XtSetKeyTranslator); XM_define_procedure(XtRegisterCaseConverter, gxm_XtRegisterCaseConverter_w, 4, 0, 0, H_XtRegisterCaseConverter); XM_define_procedure(XtConvertCase, gxm_XtConvertCase_w, 2, 0, 0, H_XtConvertCase); XM_define_procedure(XtAddEventHandler, gxm_XtAddEventHandler_w, 4, 1, 0, H_XtAddEventHandler); XM_define_procedure(XtRemoveEventHandler, gxm_XtRemoveEventHandler_w, 5, 0, 0, H_XtRemoveEventHandler); XM_define_procedure(XtAddRawEventHandler, gxm_XtAddRawEventHandler_w, 5, 0, 0, H_XtAddRawEventHandler); XM_define_procedure(XtRemoveRawEventHandler, gxm_XtRemoveRawEventHandler_w, 5, 0, 0, H_XtRemoveRawEventHandler); XM_define_procedure(XtInsertEventHandler, gxm_XtInsertEventHandler_w, 6, 0, 0, H_XtInsertEventHandler); XM_define_procedure(XtInsertRawEventHandler, gxm_XtInsertRawEventHandler_w, 6, 0, 0, H_XtInsertRawEventHandler); XM_define_procedure(XtDispatchEventToWidget, gxm_XtDispatchEventToWidget_w, 2, 0, 0, H_XtDispatchEventToWidget); XM_define_procedure(XtBuildEventMask, gxm_XtBuildEventMask_w, 1, 0, 0, H_XtBuildEventMask); XM_define_procedure(XtAddGrab, gxm_XtAddGrab_w, 3, 0, 0, H_XtAddGrab); XM_define_procedure(XtRemoveGrab, gxm_XtRemoveGrab_w, 1, 0, 0, H_XtRemoveGrab); XM_define_procedure(XtAppProcessEvent, gxm_XtAppProcessEvent_w, 2, 0, 0, H_XtAppProcessEvent); XM_define_procedure(XtAppMainLoop, gxm_XtAppMainLoop_w, 1, 0, 0, H_XtAppMainLoop); XM_define_procedure(XtAddExposureToRegion, gxm_XtAddExposureToRegion_w, 2, 0, 0, H_XtAddExposureToRegion); XM_define_procedure(XtSetKeyboardFocus, gxm_XtSetKeyboardFocus_w, 2, 0, 0, H_XtSetKeyboardFocus); XM_define_procedure(XtGetKeyboardFocusWidget, gxm_XtGetKeyboardFocusWidget_w, 1, 0, 0, H_XtGetKeyboardFocusWidget); XM_define_procedure(XtLastEventProcessed, gxm_XtLastEventProcessed_w, 1, 0, 0, H_XtLastEventProcessed); XM_define_procedure(XtLastTimestampProcessed, gxm_XtLastTimestampProcessed_w, 1, 0, 0, H_XtLastTimestampProcessed); XM_define_procedure(XtAppAddTimeOut, gxm_XtAppAddTimeOut_w, 3, 1, 0, H_XtAppAddTimeOut); XM_define_procedure(XtRemoveTimeOut, gxm_XtRemoveTimeOut_w, 1, 0, 0, H_XtRemoveTimeOut); XM_define_procedure(XtAppAddInput, gxm_XtAppAddInput_w, 4, 1, 0, H_XtAppAddInput); XM_define_procedure(XtRemoveInput, gxm_XtRemoveInput_w, 1, 0, 0, H_XtRemoveInput); XM_define_procedure(XtAppNextEvent, gxm_XtAppNextEvent_w, 1, 0, 0, H_XtAppNextEvent); XM_define_procedure(XtAppPending, gxm_XtAppPending_w, 1, 0, 0, H_XtAppPending); XM_define_procedure(XtRealizeWidget, gxm_XtRealizeWidget_w, 1, 0, 0, H_XtRealizeWidget); XM_define_procedure(XtUnrealizeWidget, gxm_XtUnrealizeWidget_w, 1, 0, 0, H_XtUnrealizeWidget); XM_define_procedure(XtDestroyWidget, gxm_XtDestroyWidget_w, 1, 0, 0, H_XtDestroyWidget); XM_define_procedure(XtSetSensitive, gxm_XtSetSensitive_w, 2, 0, 0, H_XtSetSensitive); XM_define_procedure(XtNameToWidget, gxm_XtNameToWidget_w, 2, 0, 0, H_XtNameToWidget); XM_define_procedure(XtWindowToWidget, gxm_XtWindowToWidget_w, 2, 0, 0, H_XtWindowToWidget); XM_define_procedure(XtMergeArgLists, gxm_XtMergeArgLists_w, 4, 0, 0, H_XtMergeArgLists); XM_define_procedure(XtVaCreateArgsList, gxm_XtVaCreateArgsList_w, 2, 0, 0, H_XtVaCreateArgsList); XM_define_procedure(XtDisplay, gxm_XtDisplay_w, 1, 0, 0, H_XtDisplay); XM_define_procedure(XtDisplayOfObject, gxm_XtDisplayOfObject_w, 1, 0, 0, H_XtDisplayOfObject); XM_define_procedure(XtScreen, gxm_XtScreen_w, 1, 0, 0, H_XtScreen); XM_define_procedure(XtScreenOfObject, gxm_XtScreenOfObject_w, 1, 0, 0, H_XtScreenOfObject); XM_define_procedure(XtWindow, gxm_XtWindow_w, 1, 0, 0, H_XtWindow); XM_define_procedure(XtWindowOfObject, gxm_XtWindowOfObject_w, 1, 0, 0, H_XtWindowOfObject); XM_define_procedure(XtName, gxm_XtName_w, 1, 0, 0, H_XtName); XM_define_procedure(XtSuperclass, gxm_XtSuperclass_w, 1, 0, 0, H_XtSuperclass); XM_define_procedure(XtClass, gxm_XtClass_w, 1, 0, 0, H_XtClass); XM_define_procedure(XtParent, gxm_XtParent_w, 1, 0, 0, H_XtParent); XM_define_procedure(XtAddCallback, gxm_XtAddCallback_w, 3, 1, 0, H_XtAddCallback); XM_define_procedure(XtRemoveCallback, gxm_XtRemoveCallback_w, 3, 0, 0, H_XtRemoveCallback); XM_define_procedure(XtAddCallbacks, gxm_XtAddCallbacks_w, 3, 0, 0, H_XtAddCallbacks); XM_define_procedure(XtRemoveCallbacks, gxm_XtRemoveCallbacks_w, 3, 0, 0, H_XtRemoveCallbacks); XM_define_procedure(XtRemoveAllCallbacks, gxm_XtRemoveAllCallbacks_w, 2, 0, 0, H_XtRemoveAllCallbacks); XM_define_procedure(XtCallCallbacks, gxm_XtCallCallbacks_w, 3, 0, 0, H_XtCallCallbacks); XM_define_procedure(XtHasCallbacks, gxm_XtHasCallbacks_w, 2, 0, 0, H_XtHasCallbacks); XM_define_procedure(XtCreatePopupShell, gxm_XtCreatePopupShell_w, 4, 1, 0, H_XtCreatePopupShell); XM_define_procedure(XtVaCreatePopupShell, gxm_XtVaCreatePopupShell_w, 4, 0, 0, H_XtVaCreatePopupShell); XM_define_procedure(XtPopup, gxm_XtPopup_w, 2, 0, 0, H_XtPopup); XM_define_procedure(XtPopupSpringLoaded, gxm_XtPopupSpringLoaded_w, 1, 0, 0, H_XtPopupSpringLoaded); XM_define_procedure(XtCallbackNone, gxm_XtCallbackNone_w, 3, 0, 0, H_XtCallbackNone); XM_define_procedure(XtCallbackNonexclusive, gxm_XtCallbackNonexclusive_w, 3, 0, 0, H_XtCallbackNonexclusive); XM_define_procedure(XtCallbackExclusive, gxm_XtCallbackExclusive_w, 3, 0, 0, H_XtCallbackExclusive); XM_define_procedure(XtPopdown, gxm_XtPopdown_w, 1, 0, 0, H_XtPopdown); XM_define_procedure(XtCallbackPopdown, gxm_XtCallbackPopdown_w, 3, 0, 0, H_XtCallbackPopdown); XM_define_procedure(XtCreateWidget, gxm_XtCreateWidget_w, 4, 1, 0, H_XtCreateWidget); XM_define_procedure(XtCreateManagedWidget, gxm_XtCreateManagedWidget_w, 4, 1, 0, H_XtCreateManagedWidget); XM_define_procedure(XtVaCreateWidget, gxm_XtVaCreateWidget_w, 4, 0, 0, H_XtVaCreateWidget); XM_define_procedure(XtVaCreateManagedWidget, gxm_XtVaCreateManagedWidget_w, 4, 0, 0, H_XtVaCreateManagedWidget); XM_define_procedure(XtAppCreateShell, gxm_XtAppCreateShell_w, 5, 1, 0, H_XtAppCreateShell); XM_define_procedure(XtVaAppCreateShell, gxm_XtVaAppCreateShell_w, 5, 0, 0, H_XtVaAppCreateShell); XM_define_procedure(XtToolkitInitialize, gxm_XtToolkitInitialize_w, 0, 0, 0, H_XtToolkitInitialize); XM_define_procedure(XtSetLanguageProc, gxm_XtSetLanguageProc_w, 3, 0, 0, H_XtSetLanguageProc); XM_define_procedure(XtDisplayInitialize, gxm_XtDisplayInitialize_w, 6, 0, 0, H_XtDisplayInitialize); XM_define_procedure(XtOpenApplication, gxm_XtOpenApplication_w, 5, 1, 0, H_XtOpenApplication); XM_define_procedure(XtVaOpenApplication, gxm_XtVaOpenApplication_w, 5, 1, 0, H_XtVaOpenApplication); XM_define_procedure(XtAppInitialize, gxm_XtAppInitialize_w, 4, 1, 0, H_XtAppInitialize); XM_define_procedure(XtVaAppInitialize, gxm_XtVaAppInitialize_w, 4, 1, 0, H_XtVaAppInitialize); XM_define_procedure(XtOpenDisplay, gxm_XtOpenDisplay_w, 6, 0, 0, H_XtOpenDisplay); XM_define_procedure(XtCreateApplicationContext, gxm_XtCreateApplicationContext_w, 0, 0, 0, H_XtCreateApplicationContext); XM_define_procedure(XtDestroyApplicationContext, gxm_XtDestroyApplicationContext_w, 1, 0, 0, H_XtDestroyApplicationContext); XM_define_procedure(XtAppSetFallbackResources, gxm_XtAppSetFallbackResources_w, 2, 0, 0, H_XtAppSetFallbackResources); XM_define_procedure(XtInitializeWidgetClass, gxm_XtInitializeWidgetClass_w, 1, 0, 0, H_XtInitializeWidgetClass); XM_define_procedure(XtWidgetToApplicationContext, gxm_XtWidgetToApplicationContext_w, 1, 0, 0, H_XtWidgetToApplicationContext); XM_define_procedure(XtDisplayToApplicationContext, gxm_XtDisplayToApplicationContext_w, 1, 0, 0, H_XtDisplayToApplicationContext); XM_define_procedure(XtCloseDisplay, gxm_XtCloseDisplay_w, 1, 0, 0, H_XtCloseDisplay); XM_define_procedure(XtSetValues, gxm_XtSetValues_w, 2, 1, 0, H_XtSetValues); XM_define_procedure(XtVaSetValues, gxm_XtVaSetValues_w, 2, 0, 0, H_XtVaSetValues); XM_define_procedure(XtGetValues, gxm_XtGetValues_w, 2, 1, 0, H_XtGetValues); XM_define_procedure(XtVaGetValues, gxm_XtVaGetValues_w, 2, 0, 0, H_XtVaGetValues); XM_define_procedure(XtAppSetErrorMsgHandler, gxm_XtAppSetErrorMsgHandler_w, 2, 0, 0, H_XtAppSetErrorMsgHandler); XM_define_procedure(XtAppSetWarningMsgHandler, gxm_XtAppSetWarningMsgHandler_w, 2, 0, 0, H_XtAppSetWarningMsgHandler); XM_define_procedure(XtAppErrorMsg, gxm_XtAppErrorMsg_w, 7, 0, 0, H_XtAppErrorMsg); XM_define_procedure(XtAppWarningMsg, gxm_XtAppWarningMsg_w, 7, 0, 0, H_XtAppWarningMsg); XM_define_procedure(XtAppSetErrorHandler, gxm_XtAppSetErrorHandler_w, 2, 0, 0, H_XtAppSetErrorHandler); XM_define_procedure(XtAppSetWarningHandler, gxm_XtAppSetWarningHandler_w, 2, 0, 0, H_XtAppSetWarningHandler); XM_define_procedure(XtAppError, gxm_XtAppError_w, 2, 0, 0, H_XtAppError); XM_define_procedure(XtMalloc, gxm_XtMalloc_w, 1, 0, 0, H_XtMalloc); XM_define_procedure(XtCalloc, gxm_XtCalloc_w, 2, 0, 0, H_XtCalloc); XM_define_procedure(XtRealloc, gxm_XtRealloc_w, 2, 0, 0, H_XtRealloc); XM_define_procedure(XtFree, gxm_XtFree_w, 1, 0, 0, H_XtFree); XM_define_procedure(XtAppAddWorkProc, gxm_XtAppAddWorkProc_w, 2, 1, 0, H_XtAppAddWorkProc); XM_define_procedure(XtRemoveWorkProc, gxm_XtRemoveWorkProc_w, 1, 0, 0, H_XtRemoveWorkProc); XM_define_procedure(XtGetGC, gxm_XtGetGC_w, 3, 0, 0, H_XtGetGC); XM_define_procedure(XtAllocateGC, gxm_XtAllocateGC_w, 6, 0, 0, H_XtAllocateGC); XM_define_procedure(XtDestroyGC, gxm_XtDestroyGC_w, 1, 0, 0, H_XtDestroyGC); XM_define_procedure(XtReleaseGC, gxm_XtReleaseGC_w, 2, 0, 0, H_XtReleaseGC); XM_define_procedure(XtFindFile, gxm_XtFindFile_w, 4, 0, 0, H_XtFindFile); XM_define_procedure(XtResolvePathname, gxm_XtResolvePathname_w, 8, 0, 0, H_XtResolvePathname); XM_define_procedure(XtDisownSelection, gxm_XtDisownSelection_w, 3, 0, 0, H_XtDisownSelection); XM_define_procedure(XtGetSelectionValue, gxm_XtGetSelectionValue_w, 6, 0, 0, H_XtGetSelectionValue); XM_define_procedure(XtGetSelectionValues, gxm_XtGetSelectionValues_w, 7, 0, 0, H_XtGetSelectionValues); XM_define_procedure(XtAppSetSelectionTimeout, gxm_XtAppSetSelectionTimeout_w, 2, 0, 0, H_XtAppSetSelectionTimeout); XM_define_procedure(XtAppGetSelectionTimeout, gxm_XtAppGetSelectionTimeout_w, 1, 0, 0, H_XtAppGetSelectionTimeout); XM_define_procedure(XtGetSelectionRequest, gxm_XtGetSelectionRequest_w, 3, 0, 0, H_XtGetSelectionRequest); XM_define_procedure(XtGetSelectionValueIncremental, gxm_XtGetSelectionValueIncremental_w, 6, 0, 0, H_XtGetSelectionValueIncremental); XM_define_procedure(XtGetSelectionValuesIncremental, gxm_XtGetSelectionValuesIncremental_w, 7, 0, 0, H_XtGetSelectionValuesIncremental); XM_define_procedure(XtCreateSelectionRequest, gxm_XtCreateSelectionRequest_w, 2, 0, 0, H_XtCreateSelectionRequest); XM_define_procedure(XtSendSelectionRequest, gxm_XtSendSelectionRequest_w, 3, 0, 0, H_XtSendSelectionRequest); XM_define_procedure(XtCancelSelectionRequest, gxm_XtCancelSelectionRequest_w, 2, 0, 0, H_XtCancelSelectionRequest); XM_define_procedure(XtGrabKey, gxm_XtGrabKey_w, 6, 0, 0, H_XtGrabKey); XM_define_procedure(XtUngrabKey, gxm_XtUngrabKey_w, 3, 0, 0, H_XtUngrabKey); XM_define_procedure(XtGrabKeyboard, gxm_XtGrabKeyboard_w, 5, 0, 0, H_XtGrabKeyboard); XM_define_procedure(XtUngrabKeyboard, gxm_XtUngrabKeyboard_w, 2, 0, 0, H_XtUngrabKeyboard); XM_define_procedure(XtGrabButton, gxm_XtGrabButton_w, 9, 0, 0, H_XtGrabButton); XM_define_procedure(XtUngrabButton, gxm_XtUngrabButton_w, 3, 0, 0, H_XtUngrabButton); XM_define_procedure(XtGrabPointer, gxm_XtGrabPointer_w, 8, 0, 0, H_XtGrabPointer); XM_define_procedure(XtUngrabPointer, gxm_XtUngrabPointer_w, 2, 0, 0, H_XtUngrabPointer); XM_define_procedure(XtGetApplicationNameAndClass, gxm_XtGetApplicationNameAndClass_w, 1, 0, 0, H_XtGetApplicationNameAndClass); XM_define_procedure(XtGetDisplays, gxm_XtGetDisplays_w, 1, 0, 0, H_XtGetDisplays); XM_define_procedure(XtToolkitThreadInitialize, gxm_XtToolkitThreadInitialize_w, 0, 0, 0, H_XtToolkitThreadInitialize); XM_define_procedure(XtAppLock, gxm_XtAppLock_w, 1, 0, 0, H_XtAppLock); XM_define_procedure(XtAppUnlock, gxm_XtAppUnlock_w, 1, 0, 0, H_XtAppUnlock); XM_define_procedure(XtIsRectObj, gxm_XtIsRectObj_w, 1, 0, 0, H_XtIsRectObj); XM_define_procedure(XtIsWidget, gxm_XtIsWidget_w, 1, 0, 0, H_XtIsWidget); XM_define_procedure(XtIsComposite, gxm_XtIsComposite_w, 1, 0, 0, H_XtIsComposite); XM_define_procedure(XtIsConstraint, gxm_XtIsConstraint_w, 1, 0, 0, H_XtIsConstraint); XM_define_procedure(XtIsShell, gxm_XtIsShell_w, 1, 0, 0, H_XtIsShell); XM_define_procedure(XtIsOverrideShell, gxm_XtIsOverrideShell_w, 1, 0, 0, H_XtIsOverrideShell); XM_define_procedure(XtIsWMShell, gxm_XtIsWMShell_w, 1, 0, 0, H_XtIsWMShell); XM_define_procedure(XtIsVendorShell, gxm_XtIsVendorShell_w, 1, 0, 0, H_XtIsVendorShell); XM_define_procedure(XtIsTransientShell, gxm_XtIsTransientShell_w, 1, 0, 0, H_XtIsTransientShell); XM_define_procedure(XtIsTopLevelShell, gxm_XtIsTopLevelShell_w, 1, 0, 0, H_XtIsTopLevelShell); XM_define_procedure(XtIsApplicationShell, gxm_XtIsApplicationShell_w, 1, 0, 0, H_XtIsApplicationShell); XM_define_procedure(XtIsSessionShell, gxm_XtIsSessionShell_w, 1, 0, 0, H_XtIsSessionShell); XM_define_procedure(XtMapWidget, gxm_XtMapWidget_w, 1, 0, 0, H_XtMapWidget); XM_define_procedure(XtUnmapWidget, gxm_XtUnmapWidget_w, 1, 0, 0, H_XtUnmapWidget); XM_define_procedure(XUniqueContext, gxm_XUniqueContext_w, 0, 0, 0, H_XUniqueContext); XM_define_procedure(XLoadQueryFont, gxm_XLoadQueryFont_w, 2, 0, 0, H_XLoadQueryFont); XM_define_procedure(XQueryFont, gxm_XQueryFont_w, 2, 0, 0, H_XQueryFont); XM_define_procedure(XGetMotionEvents, gxm_XGetMotionEvents_w, 4, 0, 0, H_XGetMotionEvents); XM_define_procedure(XDeleteModifiermapEntry, gxm_XDeleteModifiermapEntry_w, 3, 0, 0, H_XDeleteModifiermapEntry); XM_define_procedure(XGetModifierMapping, gxm_XGetModifierMapping_w, 1, 0, 0, H_XGetModifierMapping); XM_define_procedure(XInsertModifiermapEntry, gxm_XInsertModifiermapEntry_w, 3, 0, 0, H_XInsertModifiermapEntry); XM_define_procedure(XNewModifiermap, gxm_XNewModifiermap_w, 1, 0, 0, H_XNewModifiermap); XM_define_procedure(XCreateImage, gxm_XCreateImage_w, 0, 0, 1, H_XCreateImage); XM_define_procedure(XGetImage, gxm_XGetImage_w, 8, 0, 0, H_XGetImage); XM_define_procedure(XGetSubImage, gxm_XGetSubImage_w, 0, 0, 1, H_XGetSubImage); XM_define_procedure(XOpenDisplay, gxm_XOpenDisplay_w, 1, 0, 0, H_XOpenDisplay); XM_define_procedure(XFetchBytes, gxm_XFetchBytes_w, 1, 0, 0, H_XFetchBytes); XM_define_procedure(XFetchBuffer, gxm_XFetchBuffer_w, 2, 0, 0, H_XFetchBuffer); XM_define_procedure(XGetAtomName, gxm_XGetAtomName_w, 2, 0, 0, H_XGetAtomName); XM_define_procedure(XDisplayName, gxm_XDisplayName_w, 1, 0, 0, H_XDisplayName); XM_define_procedure(XKeysymToString, gxm_XKeysymToString_w, 1, 0, 0, H_XKeysymToString); XM_define_procedure(XSynchronize, gxm_XSynchronize_w, 2, 0, 0, H_XSynchronize); XM_define_procedure(XSetAfterFunction, gxm_XSetAfterFunction_w, 2, 0, 0, H_XSetAfterFunction); XM_define_procedure(XInternAtom, gxm_XInternAtom_w, 3, 0, 0, H_XInternAtom); XM_define_procedure(XCopyColormapAndFree, gxm_XCopyColormapAndFree_w, 2, 0, 0, H_XCopyColormapAndFree); XM_define_procedure(XCreateColormap, gxm_XCreateColormap_w, 4, 0, 0, H_XCreateColormap); XM_define_procedure(XCreatePixmapCursor, gxm_XCreatePixmapCursor_w, 7, 0, 0, H_XCreatePixmapCursor); XM_define_procedure(XCreateGlyphCursor, gxm_XCreateGlyphCursor_w, 7, 0, 0, H_XCreateGlyphCursor); XM_define_procedure(XCreateFontCursor, gxm_XCreateFontCursor_w, 2, 0, 0, H_XCreateFontCursor); XM_define_procedure(XLoadFont, gxm_XLoadFont_w, 2, 0, 0, H_XLoadFont); XM_define_procedure(XCreateGC, gxm_XCreateGC_w, 4, 0, 0, H_XCreateGC); XM_define_procedure(XFlushGC, gxm_XFlushGC_w, 2, 0, 0, H_XFlushGC); XM_define_procedure(XCreatePixmap, gxm_XCreatePixmap_w, 5, 0, 0, H_XCreatePixmap); XM_define_procedure(XCreateBitmapFromData, gxm_XCreateBitmapFromData_w, 5, 0, 0, H_XCreateBitmapFromData); XM_define_procedure(XCreatePixmapFromBitmapData, gxm_XCreatePixmapFromBitmapData_w, 8, 0, 0, H_XCreatePixmapFromBitmapData); XM_define_procedure(XCreateSimpleWindow, gxm_XCreateSimpleWindow_w, 9, 0, 0, H_XCreateSimpleWindow); XM_define_procedure(XGetSelectionOwner, gxm_XGetSelectionOwner_w, 2, 0, 0, H_XGetSelectionOwner); XM_define_procedure(XCreateWindow, gxm_XCreateWindow_w, 0, 0, 1, H_XCreateWindow); XM_define_procedure(XListInstalledColormaps, gxm_XListInstalledColormaps_w, 2, 0, 0, H_XListInstalledColormaps); XM_define_procedure(XListFonts, gxm_XListFonts_w, 3, 0, 0, H_XListFonts); XM_define_procedure(XListFontsWithInfo, gxm_XListFontsWithInfo_w, 3, 0, 0, H_XListFontsWithInfo); XM_define_procedure(XGetFontPath, gxm_XGetFontPath_w, 1, 0, 0, H_XGetFontPath); XM_define_procedure(XListExtensions, gxm_XListExtensions_w, 1, 0, 0, H_XListExtensions); XM_define_procedure(XListProperties, gxm_XListProperties_w, 2, 0, 0, H_XListProperties); #if 0 XM_define_procedure(XKeycodeToKeysym, gxm_XKeycodeToKeysym_w, 3, 0, 0, H_XKeycodeToKeysym); #endif XM_define_procedure(XLookupKeysym, gxm_XLookupKeysym_w, 2, 0, 0, H_XLookupKeysym); XM_define_procedure(XGetKeyboardMapping, gxm_XGetKeyboardMapping_w, 3, 0, 0, H_XGetKeyboardMapping); XM_define_procedure(XStringToKeysym, gxm_XStringToKeysym_w, 1, 0, 0, H_XStringToKeysym); XM_define_procedure(XMaxRequestSize, gxm_XMaxRequestSize_w, 1, 0, 0, H_XMaxRequestSize); XM_define_procedure(XExtendedMaxRequestSize, gxm_XExtendedMaxRequestSize_w, 1, 0, 0, H_XExtendedMaxRequestSize); XM_define_procedure(XDisplayMotionBufferSize, gxm_XDisplayMotionBufferSize_w, 1, 0, 0, H_XDisplayMotionBufferSize); XM_define_procedure(XVisualIDFromVisual, gxm_XVisualIDFromVisual_w, 1, 0, 0, H_XVisualIDFromVisual); XM_define_procedure(XRootWindow, gxm_XRootWindow_w, 2, 0, 0, H_RootWindow); XM_define_procedure(XDefaultRootWindow, gxm_XDefaultRootWindow_w, 1, 0, 0, H_DefaultRootWindow); XM_define_procedure(XRootWindowOfScreen, gxm_XRootWindowOfScreen_w, 1, 0, 0, H_RootWindowOfScreen); XM_define_procedure(XDefaultVisual, gxm_XDefaultVisual_w, 2, 0, 0, H_DefaultVisual); XM_define_procedure(XDefaultVisualOfScreen, gxm_XDefaultVisualOfScreen_w, 1, 0, 0, H_DefaultVisualOfScreen); XM_define_procedure(XDefaultGC, gxm_XDefaultGC_w, 2, 0, 0, H_DefaultGC); XM_define_procedure(XDefaultGCOfScreen, gxm_XDefaultGCOfScreen_w, 1, 0, 0, H_DefaultGCOfScreen); XM_define_procedure(XBlackPixel, gxm_XBlackPixel_w, 2, 0, 0, H_BlackPixel); XM_define_procedure(XWhitePixel, gxm_XWhitePixel_w, 2, 0, 0, H_WhitePixel); XM_define_procedure(XAllPlanes, gxm_XAllPlanes_w, 0, 0, 0, H_AllPlanes); XM_define_procedure(XBlackPixelOfScreen, gxm_XBlackPixelOfScreen_w, 1, 0, 0, H_BlackPixelOfScreen); XM_define_procedure(XWhitePixelOfScreen, gxm_XWhitePixelOfScreen_w, 1, 0, 0, H_WhitePixelOfScreen); XM_define_procedure(XNextRequest, gxm_XNextRequest_w, 1, 0, 0, H_NextRequest); XM_define_procedure(XLastKnownRequestProcessed, gxm_XLastKnownRequestProcessed_w, 1, 0, 0, H_LastKnownRequestProcessed); XM_define_procedure(XServerVendor, gxm_XServerVendor_w, 1, 0, 0, H_ServerVendor); XM_define_procedure(XDisplayString, gxm_XDisplayString_w, 1, 0, 0, H_DisplayString); XM_define_procedure(XDefaultColormap, gxm_XDefaultColormap_w, 2, 0, 0, H_DefaultColormap); XM_define_procedure(XDefaultColormapOfScreen, gxm_XDefaultColormapOfScreen_w, 1, 0, 0, H_DefaultColormapOfScreen); XM_define_procedure(XDisplayOfScreen, gxm_XDisplayOfScreen_w, 1, 0, 0, H_DisplayOfScreen); XM_define_procedure(XScreenOfDisplay, gxm_XScreenOfDisplay_w, 2, 0, 0, H_ScreenOfDisplay); XM_define_procedure(XDefaultScreenOfDisplay, gxm_XDefaultScreenOfDisplay_w, 1, 0, 0, H_XDefaultScreenOfDisplay); XM_define_procedure(XEventMaskOfScreen, gxm_XEventMaskOfScreen_w, 1, 0, 0, H_EventMaskOfScreen); XM_define_procedure(XScreenNumberOfScreen, gxm_XScreenNumberOfScreen_w, 1, 0, 0, H_XScreenNumberOfScreen); XM_define_procedure(XSetErrorHandler, gxm_XSetErrorHandler_w, 1, 0, 0, H_XSetErrorHandler); XM_define_procedure(XSetIOErrorHandler, gxm_XSetIOErrorHandler_w, 1, 0, 0, H_XSetIOErrorHandler); XM_define_procedure(XListPixmapFormats, gxm_XListPixmapFormats_w, 1, 0, 0, H_XListPixmapFormats); XM_define_procedure(XListDepths, gxm_XListDepths_w, 2, 0, 0, H_XListDepths); XM_define_procedure(XReconfigureWMWindow, gxm_XReconfigureWMWindow_w, 5, 0, 0, H_XReconfigureWMWindow); XM_define_procedure(XGetWMProtocols, gxm_XGetWMProtocols_w, 2, 0, 0, H_XGetWMProtocols); XM_define_procedure(XSetWMProtocols, gxm_XSetWMProtocols_w, 4, 0, 0, H_XSetWMProtocols); XM_define_procedure(XIconifyWindow, gxm_XIconifyWindow_w, 3, 0, 0, H_XIconifyWindow); XM_define_procedure(XWithdrawWindow, gxm_XWithdrawWindow_w, 3, 0, 0, H_XWithdrawWindow); XM_define_procedure(XGetCommand, gxm_XGetCommand_w, 2, 0, 0, H_XGetCommand); XM_define_procedure(XGetWMColormapWindows, gxm_XGetWMColormapWindows_w, 2, 0, 0, H_XGetWMColormapWindows); XM_define_procedure(XSetWMColormapWindows, gxm_XSetWMColormapWindows_w, 4, 0, 0, H_XSetWMColormapWindows); XM_define_procedure(XSetTransientForHint, gxm_XSetTransientForHint_w, 3, 0, 0, H_XSetTransientForHint); XM_define_procedure(XActivateScreenSaver, gxm_XActivateScreenSaver_w, 1, 0, 0, H_XActivateScreenSaver); XM_define_procedure(XAllocColor, gxm_XAllocColor_w, 3, 0, 0, H_XAllocColor); XM_define_procedure(XAllocColorCells, gxm_XAllocColorCells_w, 5, 0, 0, H_XAllocColorCells); XM_define_procedure(XAllocColorPlanes, gxm_XAllocColorPlanes_w, 0, 0, 1, H_XAllocColorPlanes); XM_define_procedure(XAllocNamedColor, gxm_XAllocNamedColor_w, 5, 0, 0, H_XAllocNamedColor); XM_define_procedure(XAllowEvents, gxm_XAllowEvents_w, 3, 0, 0, H_XAllowEvents); XM_define_procedure(XAutoRepeatOff, gxm_XAutoRepeatOff_w, 1, 0, 0, H_XAutoRepeatOff); XM_define_procedure(XAutoRepeatOn, gxm_XAutoRepeatOn_w, 1, 0, 0, H_XAutoRepeatOn); XM_define_procedure(XBell, gxm_XBell_w, 2, 0, 0, H_XBell); XM_define_procedure(XBitmapBitOrder, gxm_XBitmapBitOrder_w, 1, 0, 0, H_BitmapBitOrder); XM_define_procedure(XBitmapPad, gxm_XBitmapPad_w, 1, 0, 0, H_BitmapPad); XM_define_procedure(XBitmapUnit, gxm_XBitmapUnit_w, 1, 0, 0, H_BitmapUnit); XM_define_procedure(XCellsOfScreen, gxm_XCellsOfScreen_w, 1, 0, 0, H_CellsOfScreen); XM_define_procedure(XChangeActivePointerGrab, gxm_XChangeActivePointerGrab_w, 4, 0, 0, H_XChangeActivePointerGrab); XM_define_procedure(XChangeGC, gxm_XChangeGC_w, 4, 0, 0, H_XChangeGC); XM_define_procedure(XChangeKeyboardControl, gxm_XChangeKeyboardControl_w, 3, 0, 0, H_XChangeKeyboardControl); XM_define_procedure(XChangeKeyboardMapping, gxm_XChangeKeyboardMapping_w, 5, 0, 0, H_XChangeKeyboardMapping); XM_define_procedure(XChangePointerControl, gxm_XChangePointerControl_w, 6, 0, 0, H_XChangePointerControl); XM_define_procedure(XChangeProperty, gxm_XChangeProperty_w, 7, 1, 0, H_XChangeProperty); XM_define_procedure(XChangeWindowAttributes, gxm_XChangeWindowAttributes_w, 4, 0, 0, H_XChangeWindowAttributes); XM_define_procedure(XCheckIfEvent, gxm_XCheckIfEvent_w, 3, 0, 0, H_XCheckIfEvent); XM_define_procedure(XCheckMaskEvent, gxm_XCheckMaskEvent_w, 2, 0, 0, H_XCheckMaskEvent); XM_define_procedure(XCheckTypedEvent, gxm_XCheckTypedEvent_w, 2, 0, 0, H_XCheckTypedEvent); XM_define_procedure(XCheckTypedWindowEvent, gxm_XCheckTypedWindowEvent_w, 3, 0, 0, H_XCheckTypedWindowEvent); XM_define_procedure(XCheckWindowEvent, gxm_XCheckWindowEvent_w, 3, 0, 0, H_XCheckWindowEvent); XM_define_procedure(XCirculateSubwindows, gxm_XCirculateSubwindows_w, 3, 0, 0, H_XCirculateSubwindows); XM_define_procedure(XCirculateSubwindowsDown, gxm_XCirculateSubwindowsDown_w, 2, 0, 0, H_XCirculateSubwindowsDown); XM_define_procedure(XCirculateSubwindowsUp, gxm_XCirculateSubwindowsUp_w, 2, 0, 0, H_XCirculateSubwindowsUp); XM_define_procedure(XClearArea, gxm_XClearArea_w, 7, 0, 0, H_XClearArea); XM_define_procedure(XClearWindow, gxm_XClearWindow_w, 2, 0, 0, H_XClearWindow); XM_define_procedure(XCloseDisplay, gxm_XCloseDisplay_w, 1, 0, 0, H_XCloseDisplay); XM_define_procedure(XConfigureWindow, gxm_XConfigureWindow_w, 4, 0, 0, H_XConfigureWindow); XM_define_procedure(XConnectionNumber, gxm_XConnectionNumber_w, 1, 0, 0, H_XConnectionNumber); XM_define_procedure(XConvertSelection, gxm_XConvertSelection_w, 6, 0, 0, H_XConvertSelection); XM_define_procedure(XCopyArea, gxm_XCopyArea_w, 0, 0, 1, H_XCopyArea); XM_define_procedure(XCopyGC, gxm_XCopyGC_w, 4, 0, 0, H_XCopyGC); XM_define_procedure(XCopyPlane, gxm_XCopyPlane_w, 0, 0, 1, H_XCopyPlane); XM_define_procedure(XDefaultDepth, gxm_XDefaultDepth_w, 2, 0, 0, H_XDefaultDepth); XM_define_procedure(XDefaultDepthOfScreen, gxm_XDefaultDepthOfScreen_w, 1, 0, 0, H_XDefaultDepthOfScreen); XM_define_procedure(XDefaultScreen, gxm_XDefaultScreen_w, 1, 0, 0, H_XDefaultScreen); XM_define_procedure(XDefineCursor, gxm_XDefineCursor_w, 3, 0, 0, H_XDefineCursor); XM_define_procedure(XDeleteProperty, gxm_XDeleteProperty_w, 3, 0, 0, H_XDeleteProperty); XM_define_procedure(XDestroyWindow, gxm_XDestroyWindow_w, 2, 0, 0, H_XDestroyWindow); XM_define_procedure(XDestroySubwindows, gxm_XDestroySubwindows_w, 2, 0, 0, H_XDestroySubwindows); XM_define_procedure(XDoesBackingStore, gxm_XDoesBackingStore_w, 1, 0, 0, H_XDoesBackingStore); XM_define_procedure(XDoesSaveUnders, gxm_XDoesSaveUnders_w, 1, 0, 0, H_XDoesSaveUnders); XM_define_procedure(XDisableAccessControl, gxm_XDisableAccessControl_w, 1, 0, 0, H_XDisableAccessControl); XM_define_procedure(XDisplayCells, gxm_XDisplayCells_w, 2, 0, 0, H_XDisplayCells); XM_define_procedure(XDisplayHeight, gxm_XDisplayHeight_w, 2, 0, 0, H_XDisplayHeight); XM_define_procedure(XDisplayHeightMM, gxm_XDisplayHeightMM_w, 2, 0, 0, H_XDisplayHeightMM); XM_define_procedure(XDisplayKeycodes, gxm_XDisplayKeycodes_w, 1, 0, 0, H_XDisplayKeycodes); XM_define_procedure(XDisplayPlanes, gxm_XDisplayPlanes_w, 2, 0, 0, H_XDisplayPlanes); XM_define_procedure(XDisplayWidth, gxm_XDisplayWidth_w, 2, 0, 0, H_XDisplayWidth); XM_define_procedure(XDisplayWidthMM, gxm_XDisplayWidthMM_w, 2, 0, 0, H_XDisplayWidthMM); XM_define_procedure(XDrawArc, gxm_XDrawArc_w, 9, 0, 0, H_XDrawArc); XM_define_procedure(XDrawArcs, gxm_XDrawArcs_w, 5, 0, 0, H_XDrawArcs); XM_define_procedure(XDrawImageString, gxm_XDrawImageString_w, 7, 0, 0, H_XDrawImageString); XM_define_procedure(XDrawLine, gxm_XDrawLine_w, 7, 0, 0, H_XDrawLine); XM_define_procedure(XDrawLines, gxm_XDrawLines_w, 6, 0, 0, H_XDrawLines); XM_define_procedure(XDrawLinesDirect, gxm_XDrawLinesDirect_w, 6, 0, 0, H_XDrawLinesDirect); XM_define_procedure(freeXPoints, gxm_FreeXPoints_w, 1, 0, 0, H_freeXPoints); XM_define_procedure(vector->XPoints, gxm_Vector2XPoints_w, 1, 0, 0, H_vector2XPoints); XM_define_procedure(XDrawPoint, gxm_XDrawPoint_w, 5, 0, 0, H_XDrawPoint); XM_define_procedure(XDrawPoints, gxm_XDrawPoints_w, 6, 0, 0, H_XDrawPoints); XM_define_procedure(XDrawRectangle, gxm_XDrawRectangle_w, 7, 0, 0, H_XDrawRectangle); XM_define_procedure(XDrawRectangles, gxm_XDrawRectangles_w, 5, 0, 0, H_XDrawRectangles); XM_define_procedure(XDrawSegments, gxm_XDrawSegments_w, 5, 0, 0, H_XDrawSegments); XM_define_procedure(XDrawString, gxm_XDrawString_w, 7, 0, 0, H_XDrawString); XM_define_procedure(XDrawText, gxm_XDrawText_w, 6, 1, 0, H_XDrawText); XM_define_procedure(XEnableAccessControl, gxm_XEnableAccessControl_w, 1, 0, 0, H_XEnableAccessControl); XM_define_procedure(XEventsQueued, gxm_XEventsQueued_w, 2, 0, 0, H_XEventsQueued); XM_define_procedure(XFetchName, gxm_XFetchName_w, 2, 0, 0, H_XFetchName); XM_define_procedure(XFillArc, gxm_XFillArc_w, 9, 0, 0, H_XFillArc); XM_define_procedure(XFillArcs, gxm_XFillArcs_w, 5, 0, 0, H_XFillArcs); XM_define_procedure(XFillPolygon, gxm_XFillPolygon_w, 7, 0, 0, H_XFillPolygon); XM_define_procedure(XFillRectangle, gxm_XFillRectangle_w, 7, 0, 0, H_XFillRectangle); XM_define_procedure(XFillRectangles, gxm_XFillRectangles_w, 5, 0, 0, H_XFillRectangles); XM_define_procedure(XFlush, gxm_XFlush_w, 1, 0, 0, H_XFlush); XM_define_procedure(XForceScreenSaver, gxm_XForceScreenSaver_w, 2, 0, 0, H_XForceScreenSaver); XM_define_procedure(XFree, gxm_XFree_w, 1, 0, 0, H_XFree); XM_define_procedure(XFreeColormap, gxm_XFreeColormap_w, 2, 0, 0, H_XFreeColormap); XM_define_procedure(XFreeColors, gxm_XFreeColors_w, 5, 0, 0, H_XFreeColors); XM_define_procedure(XFreeCursor, gxm_XFreeCursor_w, 2, 0, 0, H_XFreeCursor); XM_define_procedure(XFreeExtensionList, gxm_XFreeExtensionList_w, 1, 0, 0, "XFreeExtensionList(list) frees list (from XListExtensions)"); XM_define_procedure(XFreeFont, gxm_XFreeFont_w, 2, 0, 0, H_XFreeFont); XM_define_procedure(XFreeFontInfo, gxm_XFreeFontInfo_w, 3, 0, 0, H_XFreeFontInfo); XM_define_procedure(XFreeFontNames, gxm_XFreeFontNames_w, 1, 0, 0, H_XFreeFontNames); XM_define_procedure(XFreeFontPath, gxm_XFreeFontPath_w, 1, 0, 0, H_XFreeFontPath); XM_define_procedure(XFreeGC, gxm_XFreeGC_w, 2, 0, 0, H_XFreeGC); XM_define_procedure(XFreeModifiermap, gxm_XFreeModifiermap_w, 1, 0, 0, H_XFreeModifiermap); XM_define_procedure(XFreePixmap, gxm_XFreePixmap_w, 2, 0, 0, H_XFreePixmap); XM_define_procedure(XGeometry, gxm_XGeometry_w, 0, 0, 1, H_XGeometry); XM_define_procedure(XGetErrorText, gxm_XGetErrorText_w, 4, 0, 0, H_XGetErrorText); XM_define_procedure(XGetFontProperty, gxm_XGetFontProperty_w, 2, 0, 0, H_XGetFontProperty); XM_define_procedure(XGetGCValues, gxm_XGetGCValues_w, 3, 0, 0, H_XGetGCValues); XM_define_procedure(XGCValues, gxm_XGCValues_w, 0, 0, 0, "XGCValues returns a new XGCValue struct"); XM_define_procedure(XEvent, gxm_XEvent_w, 0, 1, 0, "XEvent returns a new XEvent struct"); XM_define_procedure(XGetGeometry, gxm_XGetGeometry_w, 2, 0, 0, H_XGetGeometry); XM_define_procedure(XGetIconName, gxm_XGetIconName_w, 2, 0, 0, H_XGetIconName); XM_define_procedure(XGetInputFocus, gxm_XGetInputFocus_w, 1, 0, 0, H_XGetInputFocus); XM_define_procedure(XGetKeyboardControl, gxm_XGetKeyboardControl_w, 1, 0, 0, H_XGetKeyboardControl); XM_define_procedure(XGetPointerControl, gxm_XGetPointerControl_w, 1, 0, 0, H_XGetPointerControl); XM_define_procedure(XGetPointerMapping, gxm_XGetPointerMapping_w, 3, 0, 0, H_XGetPointerMapping); XM_define_procedure(XGetScreenSaver, gxm_XGetScreenSaver_w, 1, 0, 0, H_XGetScreenSaver); XM_define_procedure(XGetTransientForHint, gxm_XGetTransientForHint_w, 2, 0, 0, H_XGetTransientForHint); XM_define_procedure(XGetWindowProperty, gxm_XGetWindowProperty_w, 0, 0, 1, H_XGetWindowProperty); XM_define_procedure(XGetWindowAttributes, gxm_XGetWindowAttributes_w, 2, 0, 0, H_XGetWindowAttributes); XM_define_procedure(XGrabButton, gxm_XGrabButton_w, 0, 0, 1, H_XGrabButton); XM_define_procedure(XGrabKey, gxm_XGrabKey_w, 7, 0, 0, H_XGrabKey); XM_define_procedure(XGrabKeyboard, gxm_XGrabKeyboard_w, 6, 0, 0, H_XGrabKeyboard); XM_define_procedure(XGrabPointer, gxm_XGrabPointer_w, 9, 0, 0, H_XGrabPointer); XM_define_procedure(XGrabServer, gxm_XGrabServer_w, 1, 0, 0, H_XGrabServer); XM_define_procedure(XHeightMMOfScreen, gxm_XHeightMMOfScreen_w, 1, 0, 0, H_HeightMMOfScreen); XM_define_procedure(XHeightOfScreen, gxm_XHeightOfScreen_w, 1, 0, 0, H_HeightOfScreen); XM_define_procedure(XIfEvent, gxm_XIfEvent_w, 3, 0, 0, H_XIfEvent); XM_define_procedure(XImageByteOrder, gxm_XImageByteOrder_w, 1, 0, 0, H_ImageByteOrder); XM_define_procedure(XInstallColormap, gxm_XInstallColormap_w, 2, 0, 0, H_XInstallColormap); XM_define_procedure(XKeysymToKeycode, gxm_XKeysymToKeycode_w, 2, 0, 0, H_XKeysymToKeycode); XM_define_procedure(XKillClient, gxm_XKillClient_w, 2, 0, 0, H_XKillClient); XM_define_procedure(XLookupColor, gxm_XLookupColor_w, 5, 0, 0, H_XLookupColor); XM_define_procedure(XLowerWindow, gxm_XLowerWindow_w, 2, 0, 0, H_XLowerWindow); XM_define_procedure(XMapRaised, gxm_XMapRaised_w, 2, 0, 0, H_XMapRaised); XM_define_procedure(XMapSubwindows, gxm_XMapSubwindows_w, 2, 0, 0, H_XMapSubwindows); XM_define_procedure(XMapWindow, gxm_XMapWindow_w, 2, 0, 0, H_XMapWindow); XM_define_procedure(XMaskEvent, gxm_XMaskEvent_w, 2, 0, 0, H_XMaskEvent); XM_define_procedure(XMaxCmapsOfScreen, gxm_XMaxCmapsOfScreen_w, 1, 0, 0, H_MaxCmapsOfScreen); XM_define_procedure(XMinCmapsOfScreen, gxm_XMinCmapsOfScreen_w, 1, 0, 0, H_MinCmapsOfScreen); XM_define_procedure(XMoveResizeWindow, gxm_XMoveResizeWindow_w, 6, 0, 0, H_XMoveResizeWindow); XM_define_procedure(XMoveWindow, gxm_XMoveWindow_w, 4, 0, 0, H_XMoveWindow); XM_define_procedure(XNextEvent, gxm_XNextEvent_w, 1, 0, 0, H_XNextEvent); XM_define_procedure(XNoOp, gxm_XNoOp_w, 1, 0, 0, H_XNoOp); XM_define_procedure(XParseColor, gxm_XParseColor_w, 4, 0, 0, H_XParseColor); XM_define_procedure(XParseGeometry, gxm_XParseGeometry_w, 1, 0, 0, H_XParseGeometry); XM_define_procedure(XPeekEvent, gxm_XPeekEvent_w, 1, 0, 0, H_XPeekEvent); XM_define_procedure(XPeekIfEvent, gxm_XPeekIfEvent_w, 3, 0, 0, H_XPeekIfEvent); XM_define_procedure(XPending, gxm_XPending_w, 1, 0, 0, H_XPending); XM_define_procedure(XPlanesOfScreen, gxm_XPlanesOfScreen_w, 1, 0, 0, H_PlanesOfScreen); XM_define_procedure(XProtocolRevision, gxm_XProtocolRevision_w, 1, 0, 0, H_ProtocolRevision); XM_define_procedure(XProtocolVersion, gxm_XProtocolVersion_w, 1, 0, 0, H_ProtocolVersion); XM_define_procedure(XPutBackEvent, gxm_XPutBackEvent_w, 2, 0, 0, H_XPutBackEvent); XM_define_procedure(XPutImage, gxm_XPutImage_w, 0, 0, 1, H_XPutImage); XM_define_procedure(XQLength, gxm_XQLength_w, 1, 0, 0, H_QLength); XM_define_procedure(XQueryBestCursor, gxm_XQueryBestCursor_w, 4, 0, 0, H_XQueryBestCursor); XM_define_procedure(XQueryBestSize, gxm_XQueryBestSize_w, 5, 0, 0, H_XQueryBestSize); XM_define_procedure(XQueryBestStipple, gxm_XQueryBestStipple_w, 4, 0, 0, H_XQueryBestStipple); XM_define_procedure(XQueryBestTile, gxm_XQueryBestTile_w, 4, 0, 0, H_XQueryBestTile); XM_define_procedure(XQueryColor, gxm_XQueryColor_w, 3, 0, 0, H_XQueryColor); XM_define_procedure(XQueryColors, gxm_XQueryColors_w, 3, 1, 0, H_XQueryColors); XM_define_procedure(XQueryExtension, gxm_XQueryExtension_w, 2, 0, 0, H_XQueryExtension); XM_define_procedure(XQueryKeymap, gxm_XQueryKeymap_w, 1, 0, 0, H_XQueryKeymap); XM_define_procedure(XQueryPointer, gxm_XQueryPointer_w, 2, 0, 0, H_XQueryPointer); XM_define_procedure(XQueryTextExtents, gxm_XQueryTextExtents_w, 3, 0, 0, H_XQueryTextExtents); XM_define_procedure(XQueryTree, gxm_XQueryTree_w, 2, 0, 0, H_XQueryTree); XM_define_procedure(XRaiseWindow, gxm_XRaiseWindow_w, 2, 0, 0, H_XRaiseWindow); XM_define_procedure(XReadBitmapFile, gxm_XReadBitmapFile_w, 3, 0, 0, H_XReadBitmapFile); XM_define_procedure(XReadBitmapFileData, gxm_XReadBitmapFileData_w, 1, 0, 0, H_XReadBitmapFileData); XM_define_procedure(XRebindKeysym, gxm_XRebindKeysym_w, 6, 0, 0, H_XRebindKeysym); XM_define_procedure(XRecolorCursor, gxm_XRecolorCursor_w, 4, 0, 0, H_XRecolorCursor); XM_define_procedure(XRefreshKeyboardMapping, gxm_XRefreshKeyboardMapping_w, 1, 0, 0, H_XRefreshKeyboardMapping); XM_define_procedure(XReparentWindow, gxm_XReparentWindow_w, 5, 0, 0, H_XReparentWindow); XM_define_procedure(XResetScreenSaver, gxm_XResetScreenSaver_w, 1, 0, 0, H_XResetScreenSaver); XM_define_procedure(XResizeWindow, gxm_XResizeWindow_w, 4, 0, 0, H_XResizeWindow); XM_define_procedure(XRestackWindows, gxm_XRestackWindows_w, 3, 0, 0, H_XRestackWindows); XM_define_procedure(XRotateBuffers, gxm_XRotateBuffers_w, 2, 0, 0, H_XRotateBuffers); XM_define_procedure(XRotateWindowProperties, gxm_XRotateWindowProperties_w, 5, 0, 0, H_XRotateWindowProperties); XM_define_procedure(XScreenCount, gxm_XScreenCount_w, 1, 0, 0, H_ScreenCount); XM_define_procedure(XSelectInput, gxm_XSelectInput_w, 3, 0, 0, H_XSelectInput); XM_define_procedure(XSendEvent, gxm_XSendEvent_w, 5, 0, 0, H_XSendEvent); XM_define_procedure(XSetAccessControl, gxm_XSetAccessControl_w, 2, 0, 0, H_XSetAccessControl); XM_define_procedure(XSetArcMode, gxm_XSetArcMode_w, 3, 0, 0, H_XSetArcMode); XM_define_procedure(XSetBackground, gxm_XSetBackground_w, 3, 0, 0, H_XSetBackground); XM_define_procedure(XSetClipMask, gxm_XSetClipMask_w, 3, 0, 0, H_XSetClipMask); XM_define_procedure(XSetClipOrigin, gxm_XSetClipOrigin_w, 4, 0, 0, H_XSetClipOrigin); XM_define_procedure(XSetClipRectangles, gxm_XSetClipRectangles_w, 7, 0, 0, H_XSetClipRectangles); XM_define_procedure(XSetCloseDownMode, gxm_XSetCloseDownMode_w, 2, 0, 0, H_XSetCloseDownMode); XM_define_procedure(XSetCommand, gxm_XSetCommand_w, 4, 0, 0, H_XSetCommand); XM_define_procedure(XSetDashes, gxm_XSetDashes_w, 4, 1, 0, H_XSetDashes); XM_define_procedure(XSetFillRule, gxm_XSetFillRule_w, 3, 0, 0, H_XSetFillRule); XM_define_procedure(XSetFillStyle, gxm_XSetFillStyle_w, 3, 0, 0, H_XSetFillStyle); XM_define_procedure(XSetFont, gxm_XSetFont_w, 3, 0, 0, H_XSetFont); XM_define_procedure(XSetFontPath, gxm_XSetFontPath_w, 3, 0, 0, H_XSetFontPath); XM_define_procedure(XSetForeground, gxm_XSetForeground_w, 3, 0, 0, H_XSetForeground); XM_define_procedure(XSetFunction, gxm_XSetFunction_w, 3, 0, 0, H_XSetFunction); XM_define_procedure(XSetGraphicsExposures, gxm_XSetGraphicsExposures_w, 3, 0, 0, H_XSetGraphicsExposures); XM_define_procedure(XSetIconName, gxm_XSetIconName_w, 3, 0, 0, H_XSetIconName); XM_define_procedure(XSetInputFocus, gxm_XSetInputFocus_w, 4, 0, 0, H_XSetInputFocus); XM_define_procedure(XSetLineAttributes, gxm_XSetLineAttributes_w, 6, 0, 0, H_XSetLineAttributes); XM_define_procedure(XSetModifierMapping, gxm_XSetModifierMapping_w, 2, 0, 0, H_XSetModifierMapping); XM_define_procedure(XSetPlaneMask, gxm_XSetPlaneMask_w, 3, 0, 0, H_XSetPlaneMask); XM_define_procedure(XSetPointerMapping, gxm_XSetPointerMapping_w, 2, 1, 0, H_XSetPointerMapping); XM_define_procedure(XSetScreenSaver, gxm_XSetScreenSaver_w, 5, 0, 0, H_XSetScreenSaver); XM_define_procedure(XSetSelectionOwner, gxm_XSetSelectionOwner_w, 4, 0, 0, H_XSetSelectionOwner); XM_define_procedure(XSetState, gxm_XSetState_w, 6, 0, 0, H_XSetState); XM_define_procedure(XSetStipple, gxm_XSetStipple_w, 3, 0, 0, H_XSetStipple); XM_define_procedure(XSetSubwindowMode, gxm_XSetSubwindowMode_w, 3, 0, 0, H_XSetSubwindowMode); XM_define_procedure(XSetTSOrigin, gxm_XSetTSOrigin_w, 4, 0, 0, H_XSetTSOrigin); XM_define_procedure(XSetTile, gxm_XSetTile_w, 3, 0, 0, H_XSetTile); XM_define_procedure(XSetWindowBackground, gxm_XSetWindowBackground_w, 3, 0, 0, H_XSetWindowBackground); XM_define_procedure(XSetWindowBackgroundPixmap, gxm_XSetWindowBackgroundPixmap_w, 3, 0, 0, H_XSetWindowBackgroundPixmap); XM_define_procedure(XSetWindowBorder, gxm_XSetWindowBorder_w, 3, 0, 0, H_XSetWindowBorder); XM_define_procedure(XSetWindowBorderPixmap, gxm_XSetWindowBorderPixmap_w, 3, 0, 0, H_XSetWindowBorderPixmap); XM_define_procedure(XSetWindowBorderWidth, gxm_XSetWindowBorderWidth_w, 3, 0, 0, H_XSetWindowBorderWidth); XM_define_procedure(XSetWindowColormap, gxm_XSetWindowColormap_w, 3, 0, 0, H_XSetWindowColormap); XM_define_procedure(XStoreBuffer, gxm_XStoreBuffer_w, 4, 0, 0, H_XStoreBuffer); XM_define_procedure(XStoreBytes, gxm_XStoreBytes_w, 3, 0, 0, H_XStoreBytes); XM_define_procedure(XStoreColor, gxm_XStoreColor_w, 3, 0, 0, H_XStoreColor); XM_define_procedure(XStoreColors, gxm_XStoreColors_w, 4, 0, 0, H_XStoreColors); XM_define_procedure(XStoreName, gxm_XStoreName_w, 3, 0, 0, H_XStoreName); XM_define_procedure(XStoreNamedColor, gxm_XStoreNamedColor_w, 5, 0, 0, H_XStoreNamedColor); XM_define_procedure(XSync, gxm_XSync_w, 2, 0, 0, H_XSync); XM_define_procedure(XTextExtents, gxm_XTextExtents_w, 3, 0, 0, H_XTextExtents); XM_define_procedure(XTextWidth, gxm_XTextWidth_w, 3, 0, 0, H_XTextWidth); XM_define_procedure(XTranslateCoordinates, gxm_XTranslateCoordinates_w, 5, 0, 0, H_XTranslateCoordinates); XM_define_procedure(XUndefineCursor, gxm_XUndefineCursor_w, 2, 0, 0, H_XUndefineCursor); XM_define_procedure(XUngrabButton, gxm_XUngrabButton_w, 4, 0, 0, H_XUngrabButton); XM_define_procedure(XUngrabKey, gxm_XUngrabKey_w, 4, 0, 0, H_XUngrabKey); XM_define_procedure(XUngrabKeyboard, gxm_XUngrabKeyboard_w, 2, 0, 0, H_XUngrabKeyboard); XM_define_procedure(XUngrabPointer, gxm_XUngrabPointer_w, 2, 0, 0, H_XUngrabPointer); XM_define_procedure(XUngrabServer, gxm_XUngrabServer_w, 1, 0, 0, H_XUngrabServer); XM_define_procedure(XUninstallColormap, gxm_XUninstallColormap_w, 2, 0, 0, H_XUninstallColormap); XM_define_procedure(XUnloadFont, gxm_XUnloadFont_w, 2, 0, 0, H_XUnloadFont); XM_define_procedure(XUnmapSubwindows, gxm_XUnmapSubwindows_w, 2, 0, 0, H_XUnmapSubwindows); XM_define_procedure(XUnmapWindow, gxm_XUnmapWindow_w, 2, 0, 0, H_XUnmapWindow); XM_define_procedure(XVendorRelease, gxm_XVendorRelease_w, 1, 0, 0, H_VendorRelease); XM_define_procedure(XWarpPointer, gxm_XWarpPointer_w, 9, 0, 0, H_XWarpPointer); XM_define_procedure(XWidthMMOfScreen, gxm_XWidthMMOfScreen_w, 1, 0, 0, H_WidthMMOfScreen); XM_define_procedure(XWidthOfScreen, gxm_XWidthOfScreen_w, 1, 0, 0, H_WidthOfScreen); XM_define_procedure(XWindowEvent, gxm_XWindowEvent_w, 3, 0, 0, H_XWindowEvent); XM_define_procedure(XWriteBitmapFile, gxm_XWriteBitmapFile_w, 7, 0, 0, H_XWriteBitmapFile); XM_define_procedure(XSupportsLocale, gxm_XSupportsLocale_w, 0, 0, 0, H_XSupportsLocale); XM_define_procedure(XSetLocaleModifiers, gxm_XSetLocaleModifiers_w, 1, 0, 0, H_XSetLocaleModifiers); XM_define_procedure(XCreateFontSet, gxm_XCreateFontSet_w, 2, 0, 0, H_XCreateFontSet); XM_define_procedure(XFreeFontSet, gxm_XFreeFontSet_w, 2, 0, 0, H_XFreeFontSet); XM_define_procedure(XFontsOfFontSet, gxm_XFontsOfFontSet_w, 1, 0, 0, H_XFontsOfFontSet); XM_define_procedure(XBaseFontNameListOfFontSet, gxm_XBaseFontNameListOfFontSet_w, 1, 0, 0, H_XBaseFontNameListOfFontSet); XM_define_procedure(XLocaleOfFontSet, gxm_XLocaleOfFontSet_w, 1, 0, 0, H_XLocaleOfFontSet); XM_define_procedure(XContextDependentDrawing, gxm_XContextDependentDrawing_w, 1, 0, 0, H_XContextDependentDrawing); XM_define_procedure(XDirectionalDependentDrawing, gxm_XDirectionalDependentDrawing_w, 1, 0, 0, H_XDirectionalDependentDrawing); XM_define_procedure(XContextualDrawing, gxm_XContextualDrawing_w, 1, 0, 0, H_XContextualDrawing); XM_define_procedure(XFilterEvent, gxm_XFilterEvent_w, 2, 0, 0, H_XFilterEvent); XM_define_procedure(XAllocIconSize, gxm_XAllocIconSize_w, 0, 0, 0, H_XAllocIconSize); XM_define_procedure(XAllocStandardColormap, gxm_XAllocStandardColormap_w, 0, 0, 0, H_XAllocStandardColormap); XM_define_procedure(XAllocWMHints, gxm_XAllocWMHints_w, 0, 0, 0, H_XAllocWMHints); XM_define_procedure(XClipBox, gxm_XClipBox_w, 1, 0, 0, H_XClipBox); XM_define_procedure(XCreateRegion, gxm_XCreateRegion_w, 0, 0, 0, H_XCreateRegion); XM_define_procedure(XDefaultString, gxm_XDefaultString_w, 0, 0, 0, H_XDefaultString); XM_define_procedure(XDeleteContext, gxm_XDeleteContext_w, 3, 0, 0, H_XDeleteContext); XM_define_procedure(XDestroyRegion, gxm_XDestroyRegion_w, 1, 0, 0, H_XDestroyRegion); XM_define_procedure(XEmptyRegion, gxm_XEmptyRegion_w, 1, 0, 0, H_XEmptyRegion); XM_define_procedure(XEqualRegion, gxm_XEqualRegion_w, 2, 0, 0, H_XEqualRegion); XM_define_procedure(XFindContext, gxm_XFindContext_w, 3, 0, 0, H_XFindContext); XM_define_procedure(XGetIconSizes, gxm_XGetIconSizes_w, 2, 0, 0, H_XGetIconSizes); XM_define_procedure(XGetRGBColormaps, gxm_XGetRGBColormaps_w, 3, 0, 0, H_XGetRGBColormaps); XM_define_procedure(XGetVisualInfo, gxm_XGetVisualInfo_w, 3, 0, 0, H_XGetVisualInfo); XM_define_procedure(XGetWMHints, gxm_XGetWMHints_w, 2, 0, 0, H_XGetWMHints); XM_define_procedure(XIntersectRegion, gxm_XIntersectRegion_w, 3, 0, 0, H_XIntersectRegion); XM_define_procedure(XConvertCase, gxm_XConvertCase_w, 1, 0, 0, H_XConvertCase); XM_define_procedure(XLookupString, gxm_XLookupString_w, 1, 0, 0, H_XLookupString); XM_define_procedure(XMatchVisualInfo, gxm_XMatchVisualInfo_w, 4, 0, 0, H_XMatchVisualInfo); XM_define_procedure(XOffsetRegion, gxm_XOffsetRegion_w, 3, 0, 0, H_XOffsetRegion); XM_define_procedure(XPointInRegion, gxm_XPointInRegion_w, 3, 0, 0, H_XPointInRegion); XM_define_procedure(XPolygonRegion, gxm_XPolygonRegion_w, 3, 0, 0, H_XPolygonRegion); XM_define_procedure(XRectInRegion, gxm_XRectInRegion_w, 5, 0, 0, H_XRectInRegion); XM_define_procedure(XSaveContext, gxm_XSaveContext_w, 4, 0, 0, H_XSaveContext); XM_define_procedure(XSetRGBColormaps, gxm_XSetRGBColormaps_w, 5, 0, 0, H_XSetRGBColormaps); XM_define_procedure(XSetWMHints, gxm_XSetWMHints_w, 3, 0, 0, H_XSetWMHints); XM_define_procedure(XSetRegion, gxm_XSetRegion_w, 3, 0, 0, H_XSetRegion); XM_define_procedure(XSetWMProperties, gxm_XSetWMProperties_w, 8, 0, 0, H_XSetWMProperties); XM_define_procedure(XShrinkRegion, gxm_XShrinkRegion_w, 3, 0, 0, H_XShrinkRegion); XM_define_procedure(XSubtractRegion, gxm_XSubtractRegion_w, 3, 0, 0, H_XSubtractRegion); XM_define_procedure(XUnionRectWithRegion, gxm_XUnionRectWithRegion_w, 3, 0, 0, H_XUnionRectWithRegion); XM_define_procedure(XUnionRegion, gxm_XUnionRegion_w, 3, 0, 0, H_XUnionRegion); XM_define_procedure(XXorRegion, gxm_XXorRegion_w, 3, 0, 0, H_XXorRegion); XM_define_procedure(DefaultScreen, gxm_DefaultScreen_w, 1, 0, 0, H_DefaultScreen); XM_define_procedure(DefaultRootWindow, gxm_DefaultRootWindow_w, 1, 0, 0, H_DefaultRootWindow); XM_define_procedure(QLength, gxm_QLength_w, 1, 0, 0, H_QLength); XM_define_procedure(ScreenCount, gxm_ScreenCount_w, 1, 0, 0, H_ScreenCount); XM_define_procedure(ServerVendor, gxm_ServerVendor_w, 1, 0, 0, H_ServerVendor); XM_define_procedure(ProtocolVersion, gxm_ProtocolVersion_w, 1, 0, 0, H_ProtocolVersion); XM_define_procedure(ProtocolRevision, gxm_ProtocolRevision_w, 1, 0, 0, H_ProtocolRevision); XM_define_procedure(VendorRelease, gxm_VendorRelease_w, 1, 0, 0, H_VendorRelease); XM_define_procedure(DisplayString, gxm_DisplayString_w, 1, 0, 0, H_DisplayString); XM_define_procedure(BitmapUnit, gxm_BitmapUnit_w, 1, 0, 0, H_BitmapUnit); XM_define_procedure(BitmapBitOrder, gxm_BitmapBitOrder_w, 1, 0, 0, H_BitmapBitOrder); XM_define_procedure(BitmapPad, gxm_BitmapPad_w, 1, 0, 0, H_BitmapPad); XM_define_procedure(ImageByteOrder, gxm_ImageByteOrder_w, 1, 0, 0, H_ImageByteOrder); XM_define_procedure(NextRequest, gxm_NextRequest_w, 1, 0, 0, H_NextRequest); XM_define_procedure(LastKnownRequestProcessed, gxm_LastKnownRequestProcessed_w, 1, 0, 0, H_LastKnownRequestProcessed); XM_define_procedure(DefaultScreenOfDisplay, gxm_DefaultScreenOfDisplay_w, 1, 0, 0, H_DefaultScreenOfDisplay); XM_define_procedure(DisplayOfScreen, gxm_DisplayOfScreen_w, 1, 0, 0, H_DisplayOfScreen); XM_define_procedure(RootWindowOfScreen, gxm_RootWindowOfScreen_w, 1, 0, 0, H_RootWindowOfScreen); XM_define_procedure(BlackPixelOfScreen, gxm_BlackPixelOfScreen_w, 1, 0, 0, H_BlackPixelOfScreen); XM_define_procedure(WhitePixelOfScreen, gxm_WhitePixelOfScreen_w, 1, 0, 0, H_WhitePixelOfScreen); XM_define_procedure(DefaultColormapOfScreen, gxm_DefaultColormapOfScreen_w, 1, 0, 0, H_DefaultColormapOfScreen); XM_define_procedure(DefaultDepthOfScreen, gxm_DefaultDepthOfScreen_w, 1, 0, 0, H_DefaultDepthOfScreen); XM_define_procedure(DefaultGCOfScreen, gxm_DefaultGCOfScreen_w, 1, 0, 0, H_DefaultGCOfScreen); XM_define_procedure(DefaultVisualOfScreen, gxm_DefaultVisualOfScreen_w, 1, 0, 0, H_DefaultVisualOfScreen); XM_define_procedure(WidthOfScreen, gxm_WidthOfScreen_w, 1, 0, 0, H_WidthOfScreen); XM_define_procedure(HeightOfScreen, gxm_HeightOfScreen_w, 1, 0, 0, H_HeightOfScreen); XM_define_procedure(WidthMMOfScreen, gxm_WidthMMOfScreen_w, 1, 0, 0, H_WidthMMOfScreen); XM_define_procedure(HeightMMOfScreen, gxm_HeightMMOfScreen_w, 1, 0, 0, H_HeightMMOfScreen); XM_define_procedure(PlanesOfScreen, gxm_PlanesOfScreen_w, 1, 0, 0, H_PlanesOfScreen); XM_define_procedure(CellsOfScreen, gxm_CellsOfScreen_w, 1, 0, 0, H_CellsOfScreen); XM_define_procedure(MinCmapsOfScreen, gxm_MinCmapsOfScreen_w, 1, 0, 0, H_MinCmapsOfScreen); XM_define_procedure(MaxCmapsOfScreen, gxm_MaxCmapsOfScreen_w, 1, 0, 0, H_MaxCmapsOfScreen); XM_define_procedure(DoesSaveUnders, gxm_DoesSaveUnders_w, 1, 0, 0, H_DoesSaveUnders); XM_define_procedure(DoesBackingStore, gxm_DoesBackingStore_w, 1, 0, 0, H_DoesBackingStore); XM_define_procedure(EventMaskOfScreen, gxm_EventMaskOfScreen_w, 1, 0, 0, H_EventMaskOfScreen); XM_define_procedure(RootWindow, gxm_RootWindow_w, 2, 0, 0, H_RootWindow); XM_define_procedure(DefaultVisual, gxm_DefaultVisual_w, 2, 0, 0, H_DefaultVisual); XM_define_procedure(DefaultGC, gxm_DefaultGC_w, 2, 0, 0, H_DefaultGC); XM_define_procedure(BlackPixel, gxm_BlackPixel_w, 2, 0, 0, H_BlackPixel); XM_define_procedure(WhitePixel, gxm_WhitePixel_w, 2, 0, 0, H_WhitePixel); XM_define_procedure(DisplayWidth, gxm_DisplayWidth_w, 2, 0, 0, H_DisplayWidth); XM_define_procedure(DisplayHeight, gxm_DisplayHeight_w, 2, 0, 0, H_DisplayHeight); XM_define_procedure(DisplayWidthMM, gxm_DisplayWidthMM_w, 2, 0, 0, H_DisplayWidthMM); XM_define_procedure(DisplayHeightMM, gxm_DisplayHeightMM_w, 2, 0, 0, H_DisplayHeightMM); XM_define_procedure(DisplayPlanes, gxm_DisplayPlanes_w, 2, 0, 0, H_DisplayPlanes); XM_define_procedure(DisplayCells, gxm_DisplayCells_w, 2, 0, 0, H_DisplayCells); XM_define_procedure(DefaultColormap, gxm_DefaultColormap_w, 2, 0, 0, H_DefaultColormap); XM_define_procedure(ScreenOfDisplay, gxm_ScreenOfDisplay_w, 2, 0, 0, H_ScreenOfDisplay); XM_define_procedure(DefaultDepth, gxm_DefaultDepth_w, 2, 0, 0, H_DefaultDepth); XM_define_procedure(IsKeypadKey, gxm_IsKeypadKey_w, 1, 0, 0, H_IsKeypadKey); XM_define_procedure(IsPrivateKeypadKey, gxm_IsPrivateKeypadKey_w, 1, 0, 0, H_IsPrivateKeypadKey); XM_define_procedure(IsCursorKey, gxm_IsCursorKey_w, 1, 0, 0, H_IsCursorKey); XM_define_procedure(IsPFKey, gxm_IsPFKey_w, 1, 0, 0, H_IsPFKey); XM_define_procedure(IsFunctionKey, gxm_IsFunctionKey_w, 1, 0, 0, H_IsFunctionKey); XM_define_procedure(IsMiscFunctionKey, gxm_IsMiscFunctionKey_w, 1, 0, 0, H_IsMiscFunctionKey); XM_define_procedure(IsModifierKey, gxm_IsModifierKey_w, 1, 0, 0, H_IsModifierKey); XM_define_procedure(XButtonEvent?, g_is_XButtonEvent_w, 1, 0, 0, PROC_TRUE " if arg is a XButtonEvent"); XM_define_procedure(XCirculateEvent?, g_is_XCirculateEvent_w, 1, 0, 0, PROC_TRUE " if arg is a XCirculateEvent"); XM_define_procedure(XCirculateRequestEvent?, g_is_XCirculateRequestEvent_w, 1, 0, 0, PROC_TRUE " if arg is a XCirculateRequestEvent"); XM_define_procedure(XClientMessageEvent?, g_is_XClientMessageEvent_w, 1, 0, 0, PROC_TRUE " if arg is a XClientMessageEvent"); XM_define_procedure(XColormapEvent?, g_is_XColormapEvent_w, 1, 0, 0, PROC_TRUE " if arg is a XColormapEvent"); XM_define_procedure(XConfigureEvent?, g_is_XConfigureEvent_w, 1, 0, 0, PROC_TRUE " if arg is a XConfigureEvent"); XM_define_procedure(XConfigureRequestEvent?, g_is_XConfigureRequestEvent_w, 1, 0, 0, PROC_TRUE " if arg is a XConfigureRequestEvent"); XM_define_procedure(XCreateWindowEvent?, g_is_XCreateWindowEvent_w, 1, 0, 0, PROC_TRUE " if arg is a XCreateWindowEvent"); XM_define_procedure(XCrossingEvent?, g_is_XCrossingEvent_w, 1, 0, 0, PROC_TRUE " if arg is a XCrossingEvent"); XM_define_procedure(XDestroyWindowEvent?, g_is_XDestroyWindowEvent_w, 1, 0, 0, PROC_TRUE " if arg is a XDestroyWindowEvent"); XM_define_procedure(XErrorEvent?, g_is_XErrorEvent_w, 1, 0, 0, PROC_TRUE " if arg is a XErrorEvent"); XM_define_procedure(XExposeEvent?, g_is_XExposeEvent_w, 1, 0, 0, PROC_TRUE " if arg is a XExposeEvent"); XM_define_procedure(XFocusChangeEvent?, g_is_XFocusChangeEvent_w, 1, 0, 0, PROC_TRUE " if arg is a XFocusChangeEvent"); XM_define_procedure(XGraphicsExposeEvent?, g_is_XGraphicsExposeEvent_w, 1, 0, 0, PROC_TRUE " if arg is a XGraphicsExposeEvent"); XM_define_procedure(XGravityEvent?, g_is_XGravityEvent_w, 1, 0, 0, PROC_TRUE " if arg is a XGravityEvent"); XM_define_procedure(XKeyEvent?, g_is_XKeyEvent_w, 1, 0, 0, PROC_TRUE " if arg is a XKeyEvent"); XM_define_procedure(XKeymapEvent?, g_is_XKeymapEvent_w, 1, 0, 0, PROC_TRUE " if arg is a XKeymapEvent"); XM_define_procedure(XMapEvent?, g_is_XMapEvent_w, 1, 0, 0, PROC_TRUE " if arg is a XMapEvent"); XM_define_procedure(XMapRequestEvent?, g_is_XMapRequestEvent_w, 1, 0, 0, PROC_TRUE " if arg is a XMapRequestEvent"); XM_define_procedure(XMappingEvent?, g_is_XMappingEvent_w, 1, 0, 0, PROC_TRUE " if arg is a XMappingEvent"); XM_define_procedure(XMotionEvent?, g_is_XMotionEvent_w, 1, 0, 0, PROC_TRUE " if arg is a XMotionEvent"); XM_define_procedure(XNoExposeEvent?, g_is_XNoExposeEvent_w, 1, 0, 0, PROC_TRUE " if arg is a XNoExposeEvent"); XM_define_procedure(XPropertyEvent?, g_is_XPropertyEvent_w, 1, 0, 0, PROC_TRUE " if arg is a XPropertyEvent"); XM_define_procedure(XReparentEvent?, g_is_XReparentEvent_w, 1, 0, 0, PROC_TRUE " if arg is a XReparentEvent"); XM_define_procedure(XResizeRequestEvent?, g_is_XResizeRequestEvent_w, 1, 0, 0, PROC_TRUE " if arg is a XResizeRequestEvent"); XM_define_procedure(XSelectionClearEvent?, g_is_XSelectionClearEvent_w, 1, 0, 0, PROC_TRUE " if arg is a XSelectionClearEvent"); XM_define_procedure(XSelectionEvent?, g_is_XSelectionEvent_w, 1, 0, 0, PROC_TRUE " if arg is a XSelectionEvent"); XM_define_procedure(XSelectionRequestEvent?, g_is_XSelectionRequestEvent_w, 1, 0, 0, PROC_TRUE " if arg is a XSelectionRequestEvent"); XM_define_procedure(XSetWindowAttributes?, g_is_XSetWindowAttributes_w, 1, 0, 0, PROC_TRUE " if arg is a XSetWindowAttributes"); XM_define_procedure(XUnmapEvent?, g_is_XUnmapEvent_w, 1, 0, 0, PROC_TRUE " if arg is a XUnmapEvent"); XM_define_procedure(XVisibilityEvent?, g_is_XVisibilityEvent_w, 1, 0, 0, PROC_TRUE " if arg is a XVisibilityEvent"); XM_define_procedure(XIconSize?, g_is_XIconSize_w, 1, 0, 0, PROC_TRUE " if arg is a XIconSize object"); XM_define_procedure(XmCreateMessageBox, gxm_XmCreateMessageBox_w, 3, 1, 0, H_XmCreateMessageBox); XM_define_procedure(XmCreateMessageDialog, gxm_XmCreateMessageDialog_w, 3, 1, 0, H_XmCreateMessageDialog); XM_define_procedure(XmCreateErrorDialog, gxm_XmCreateErrorDialog_w, 3, 1, 0, H_XmCreateErrorDialog); XM_define_procedure(XmCreateInformationDialog, gxm_XmCreateInformationDialog_w, 3, 1, 0, H_XmCreateInformationDialog); XM_define_procedure(XmCreateQuestionDialog, gxm_XmCreateQuestionDialog_w, 3, 1, 0, H_XmCreateQuestionDialog); XM_define_procedure(XmCreateWarningDialog, gxm_XmCreateWarningDialog_w, 3, 1, 0, H_XmCreateWarningDialog); XM_define_procedure(XmCreateWorkingDialog, gxm_XmCreateWorkingDialog_w, 3, 1, 0, H_XmCreateWorkingDialog); XM_define_procedure(XmCreateTemplateDialog, gxm_XmCreateTemplateDialog_w, 3, 1, 0, H_XmCreateTemplateDialog); XM_define_procedure(XmMessageBoxGetChild, gxm_XmMessageBoxGetChild_w, 2, 0, 0, H_XmMessageBoxGetChild); XM_define_procedure(XmCreateArrowButtonGadget, gxm_XmCreateArrowButtonGadget_w, 3, 1, 0, H_XmCreateArrowButtonGadget); XM_define_procedure(XmCreateArrowButton, gxm_XmCreateArrowButton_w, 3, 1, 0, H_XmCreateArrowButton); XM_define_procedure(XmCreateNotebook, gxm_XmCreateNotebook_w, 3, 1, 0, H_XmCreateNotebook); XM_define_procedure(XmNotebookGetPageInfo, gxm_XmNotebookGetPageInfo_w, 2, 0, 0, H_XmNotebookGetPageInfo); XM_define_procedure(XmTransferSetParameters, gxm_XmTransferSetParameters_w, 5, 0, 0, H_XmTransferSetParameters); XM_define_procedure(XmTransferDone, gxm_XmTransferDone_w, 2, 0, 0, H_XmTransferDone); XM_define_procedure(XmTransferValue, gxm_XmTransferValue_w, 5, 0, 0, H_XmTransferValue); XM_define_procedure(XmTransferStartRequest, gxm_XmTransferStartRequest_w, 1, 0, 0, H_XmTransferStartRequest); XM_define_procedure(XmTransferSendRequest, gxm_XmTransferSendRequest_w, 2, 0, 0, H_XmTransferSendRequest); XM_define_procedure(XmCreateComboBox, gxm_XmCreateComboBox_w, 3, 1, 0, H_XmCreateComboBox); XM_define_procedure(XmCreateDropDownComboBox, gxm_XmCreateDropDownComboBox_w, 3, 1, 0, H_XmCreateDropDownComboBox); XM_define_procedure(XmCreateDropDownList, gxm_XmCreateDropDownList_w, 3, 1, 0, H_XmCreateDropDownList); XM_define_procedure(XmComboBoxAddItem, gxm_XmComboBoxAddItem_w, 4, 0, 0, H_XmComboBoxAddItem); XM_define_procedure(XmComboBoxDeletePos, gxm_XmComboBoxDeletePos_w, 2, 0, 0, H_XmComboBoxDeletePos); XM_define_procedure(XmComboBoxSelectItem, gxm_XmComboBoxSelectItem_w, 2, 0, 0, H_XmComboBoxSelectItem); XM_define_procedure(XmComboBoxSetItem, gxm_XmComboBoxSetItem_w, 2, 0, 0, H_XmComboBoxSetItem); XM_define_procedure(XmComboBoxUpdate, gxm_XmComboBoxUpdate_w, 1, 0, 0, H_XmComboBoxUpdate); XM_define_procedure(XmCreateContainer, gxm_XmCreateContainer_w, 3, 1, 0, H_XmCreateContainer); XM_define_procedure(XmContainerGetItemChildren, gxm_XmContainerGetItemChildren_w, 2, 0, 0, H_XmContainerGetItemChildren); XM_define_procedure(XmContainerRelayout, gxm_XmContainerRelayout_w, 1, 0, 0, H_XmContainerRelayout); XM_define_procedure(XmContainerReorder, gxm_XmContainerReorder_w, 3, 0, 0, H_XmContainerReorder); XM_define_procedure(XmContainerCut, gxm_XmContainerCut_w, 2, 0, 0, H_XmContainerCut); XM_define_procedure(XmContainerCopy, gxm_XmContainerCopy_w, 2, 0, 0, H_XmContainerCopy); XM_define_procedure(XmContainerPaste, gxm_XmContainerPaste_w, 1, 0, 0, H_XmContainerPaste); XM_define_procedure(XmContainerCopyLink, gxm_XmContainerCopyLink_w, 2, 0, 0, H_XmContainerCopyLink); XM_define_procedure(XmContainerPasteLink, gxm_XmContainerPasteLink_w, 1, 0, 0, H_XmContainerPasteLink); XM_define_procedure(XmCreateSpinBox, gxm_XmCreateSpinBox_w, 3, 1, 0, H_XmCreateSpinBox); XM_define_procedure(XmSpinBoxValidatePosition, gxm_XmSpinBoxValidatePosition_w, 1, 0, 0, H_XmSpinBoxValidatePosition); XM_define_procedure(XmCreateSimpleSpinBox, gxm_XmCreateSimpleSpinBox_w, 3, 1, 0, H_XmCreateSimpleSpinBox); XM_define_procedure(XmSimpleSpinBoxAddItem, gxm_XmSimpleSpinBoxAddItem_w, 3, 0, 0, H_XmSimpleSpinBoxAddItem); XM_define_procedure(XmSimpleSpinBoxDeletePos, gxm_XmSimpleSpinBoxDeletePos_w, 2, 0, 0, H_XmSimpleSpinBoxDeletePos); XM_define_procedure(XmSimpleSpinBoxSetItem, gxm_XmSimpleSpinBoxSetItem_w, 2, 0, 0, H_XmSimpleSpinBoxSetItem); XM_define_procedure(XmDropSiteRegistered, gxm_XmDropSiteRegistered_w, 1, 0, 0, H_XmDropSiteRegistered); XM_define_procedure(XmTextFieldCopyLink, gxm_XmTextFieldCopyLink_w, 2, 0, 0, H_XmTextFieldCopyLink); XM_define_procedure(XmTextFieldPasteLink, gxm_XmTextFieldPasteLink_w, 1, 0, 0, H_XmTextFieldPasteLink); XM_define_procedure(XmTextGetCenterline, gxm_XmTextGetCenterline_w, 1, 0, 0, H_XmTextGetCenterline); XM_define_procedure(XmToggleButtonGadgetSetValue, gxm_XmToggleButtonGadgetSetValue_w, 3, 0, 0, H_XmToggleButtonGadgetSetValue); XM_define_procedure(XmCreateIconGadget, gxm_XmCreateIconGadget_w, 3, 1, 0, H_XmCreateIconGadget); XM_define_procedure(XmCreateIconHeader, gxm_XmCreateIconHeader_w, 3, 1, 0, H_XmCreateIconHeader); XM_define_procedure(XmObjectAtPoint, gxm_XmObjectAtPoint_w, 3, 0, 0, H_XmObjectAtPoint); XM_define_procedure(XmConvertStringToUnits, gxm_XmConvertStringToUnits_w, 4, 0, 0, H_XmConvertStringToUnits); XM_define_procedure(XmCreateGrabShell, gxm_XmCreateGrabShell_w, 3, 1, 0, H_XmCreateGrabShell); XM_define_procedure(XmToggleButtonSetValue, gxm_XmToggleButtonSetValue_w, 3, 0, 0, H_XmToggleButtonSetValue); XM_define_procedure(XmTextPasteLink, gxm_XmTextPasteLink_w, 1, 0, 0, H_XmTextPasteLink); XM_define_procedure(XmTextCopyLink, gxm_XmTextCopyLink_w, 2, 0, 0, H_XmTextCopyLink); XM_define_procedure(XmScaleSetTicks, gxm_XmScaleSetTicks_w, 7, 0, 0, H_XmScaleSetTicks); XM_define_procedure(XmInternAtom, gxm_XmInternAtom_w, 3, 0, 0, H_XmInternAtom); XM_define_procedure(XmGetAtomName, gxm_XmGetAtomName_w, 2, 0, 0, H_XmGetAtomName); XM_define_procedure(XmCreatePanedWindow, gxm_XmCreatePanedWindow_w, 3, 1, 0, H_XmCreatePanedWindow); XM_define_procedure(XmCreateBulletinBoard, gxm_XmCreateBulletinBoard_w, 3, 1, 0, H_XmCreateBulletinBoard); XM_define_procedure(XmCreateBulletinBoardDialog, gxm_XmCreateBulletinBoardDialog_w, 3, 1, 0, H_XmCreateBulletinBoardDialog); XM_define_procedure(XmCreateCascadeButtonGadget, gxm_XmCreateCascadeButtonGadget_w, 3, 1, 0, H_XmCreateCascadeButtonGadget); XM_define_procedure(XmCascadeButtonGadgetHighlight, gxm_XmCascadeButtonGadgetHighlight_w, 2, 0, 0, H_XmCascadeButtonGadgetHighlight); XM_define_procedure(XmAddProtocols, gxm_XmAddProtocols_w, 3, 1, 0, H_XmAddProtocols); XM_define_procedure(XmAddWMProtocols, gxm_XmAddWMProtocols_w, 2, 1, 0, H_XmAddWMProtocols); XM_define_procedure(XmRemoveProtocols, gxm_XmRemoveProtocols_w, 3, 1, 0, H_XmRemoveProtocols); XM_define_procedure(XmRemoveWMProtocols, gxm_XmRemoveWMProtocols_w, 2, 1, 0, H_XmRemoveWMProtocols); XM_define_procedure(XmAddProtocolCallback, gxm_XmAddProtocolCallback_w, 5, 0, 0, H_XmAddProtocolCallback); XM_define_procedure(XmAddWMProtocolCallback, gxm_XmAddWMProtocolCallback_w, 4, 0, 0, H_XmAddWMProtocolCallback); XM_define_procedure(XmRemoveProtocolCallback, gxm_XmRemoveProtocolCallback_w, 5, 0, 0, H_XmRemoveProtocolCallback); XM_define_procedure(XmRemoveWMProtocolCallback, gxm_XmRemoveWMProtocolCallback_w, 4, 0, 0, H_XmRemoveWMProtocolCallback); XM_define_procedure(XmActivateProtocol, gxm_XmActivateProtocol_w, 3, 0, 0, H_XmActivateProtocol); XM_define_procedure(XmDeactivateProtocol, gxm_XmDeactivateProtocol_w, 3, 0, 0, H_XmDeactivateProtocol); XM_define_procedure(XmActivateWMProtocol, gxm_XmActivateWMProtocol_w, 2, 0, 0, H_XmActivateWMProtocol); XM_define_procedure(XmDeactivateWMProtocol, gxm_XmDeactivateWMProtocol_w, 2, 0, 0, H_XmDeactivateWMProtocol); XM_define_procedure(XmSetProtocolHooks, gxm_XmSetProtocolHooks_w, 7, 0, 0, H_XmSetProtocolHooks); XM_define_procedure(XmSetWMProtocolHooks, gxm_XmSetWMProtocolHooks_w, 6, 0, 0, H_XmSetWMProtocolHooks); XM_define_procedure(XmCreateCascadeButton, gxm_XmCreateCascadeButton_w, 3, 1, 0, H_XmCreateCascadeButton); XM_define_procedure(XmCascadeButtonHighlight, gxm_XmCascadeButtonHighlight_w, 2, 0, 0, H_XmCascadeButtonHighlight); XM_define_procedure(XmCreatePushButtonGadget, gxm_XmCreatePushButtonGadget_w, 3, 1, 0, H_XmCreatePushButtonGadget); XM_define_procedure(XmCreatePushButton, gxm_XmCreatePushButton_w, 3, 1, 0, H_XmCreatePushButton); XM_define_procedure(XmCreateCommand, gxm_XmCreateCommand_w, 3, 1, 0, H_XmCreateCommand); XM_define_procedure(XmCommandGetChild, gxm_XmCommandGetChild_w, 2, 0, 0, H_XmCommandGetChild); XM_define_procedure(XmCommandSetValue, gxm_XmCommandSetValue_w, 2, 0, 0, H_XmCommandSetValue); XM_define_procedure(XmCommandAppendValue, gxm_XmCommandAppendValue_w, 2, 0, 0, H_XmCommandAppendValue); XM_define_procedure(XmCommandError, gxm_XmCommandError_w, 2, 0, 0, H_XmCommandError); XM_define_procedure(XmCreateCommandDialog, gxm_XmCreateCommandDialog_w, 3, 1, 0, H_XmCreateCommandDialog); XM_define_procedure(XmMenuPosition, gxm_XmMenuPosition_w, 2, 0, 0, H_XmMenuPosition); XM_define_procedure(XmCreateRowColumn, gxm_XmCreateRowColumn_w, 3, 1, 0, H_XmCreateRowColumn); XM_define_procedure(XmCreateWorkArea, gxm_XmCreateWorkArea_w, 3, 1, 0, H_XmCreateWorkArea); XM_define_procedure(XmCreateRadioBox, gxm_XmCreateRadioBox_w, 3, 1, 0, H_XmCreateRadioBox); XM_define_procedure(XmCreateOptionMenu, gxm_XmCreateOptionMenu_w, 3, 1, 0, H_XmCreateOptionMenu); XM_define_procedure(XmOptionLabelGadget, gxm_XmOptionLabelGadget_w, 1, 0, 0, H_XmOptionLabelGadget); XM_define_procedure(XmOptionButtonGadget, gxm_XmOptionButtonGadget_w, 1, 0, 0, H_XmOptionButtonGadget); XM_define_procedure(XmCreateMenuBar, gxm_XmCreateMenuBar_w, 3, 1, 0, H_XmCreateMenuBar); XM_define_procedure(XmCreatePopupMenu, gxm_XmCreatePopupMenu_w, 3, 1, 0, H_XmCreatePopupMenu); XM_define_procedure(XmCreatePulldownMenu, gxm_XmCreatePulldownMenu_w, 3, 1, 0, H_XmCreatePulldownMenu); XM_define_procedure(XmGetPostedFromWidget, gxm_XmGetPostedFromWidget_w, 1, 0, 0, H_XmGetPostedFromWidget); XM_define_procedure(XmGetTearOffControl, gxm_XmGetTearOffControl_w, 1, 0, 0, H_XmGetTearOffControl); XM_define_procedure(XmScaleSetValue, gxm_XmScaleSetValue_w, 2, 0, 0, H_XmScaleSetValue); XM_define_procedure(XmScaleGetValue, gxm_XmScaleGetValue_w, 1, 0, 0, H_XmScaleGetValue); XM_define_procedure(XmCreateScale, gxm_XmCreateScale_w, 3, 1, 0, H_XmCreateScale); XM_define_procedure(XmClipboardBeginCopy, gxm_XmClipboardBeginCopy_w, 5, 0, 0, H_XmClipboardBeginCopy); XM_define_procedure(XmWidgetGetDisplayRect, gxm_XmWidgetGetDisplayRect_w, 1, 0, 0, H_XmWidgetGetDisplayRect); XM_define_procedure(XmClipboardStartCopy, gxm_XmClipboardStartCopy_w, 6, 0, 0, H_XmClipboardStartCopy); XM_define_procedure(XmClipboardCopy, gxm_XmClipboardCopy_w, 7, 0, 0, H_XmClipboardCopy); XM_define_procedure(XmClipboardEndCopy, gxm_XmClipboardEndCopy_w, 3, 0, 0, H_XmClipboardEndCopy); XM_define_procedure(XmClipboardCancelCopy, gxm_XmClipboardCancelCopy_w, 3, 0, 0, H_XmClipboardCancelCopy); XM_define_procedure(XmClipboardWithdrawFormat, gxm_XmClipboardWithdrawFormat_w, 3, 0, 0, H_XmClipboardWithdrawFormat); XM_define_procedure(XmClipboardCopyByName, gxm_XmClipboardCopyByName_w, 6, 0, 0, H_XmClipboardCopyByName); XM_define_procedure(XmClipboardUndoCopy, gxm_XmClipboardUndoCopy_w, 2, 0, 0, H_XmClipboardUndoCopy); XM_define_procedure(XmClipboardLock, gxm_XmClipboardLock_w, 2, 0, 0, H_XmClipboardLock); XM_define_procedure(XmClipboardUnlock, gxm_XmClipboardUnlock_w, 3, 0, 0, H_XmClipboardUnlock); XM_define_procedure(XmClipboardStartRetrieve, gxm_XmClipboardStartRetrieve_w, 3, 0, 0, H_XmClipboardStartRetrieve); XM_define_procedure(XmClipboardEndRetrieve, gxm_XmClipboardEndRetrieve_w, 2, 0, 0, H_XmClipboardEndRetrieve); XM_define_procedure(XmClipboardRetrieve, gxm_XmClipboardRetrieve_w, 4, 0, 0, H_XmClipboardRetrieve); XM_define_procedure(XmClipboardInquireCount, gxm_XmClipboardInquireCount_w, 2, 0, 0, H_XmClipboardInquireCount); XM_define_procedure(XmClipboardInquireFormat, gxm_XmClipboardInquireFormat_w, 4, 0, 0, H_XmClipboardInquireFormat); XM_define_procedure(XmClipboardInquireLength, gxm_XmClipboardInquireLength_w, 3, 0, 0, H_XmClipboardInquireLength); XM_define_procedure(XmClipboardInquirePendingItems, gxm_XmClipboardInquirePendingItems_w, 3, 0, 0, H_XmClipboardInquirePendingItems); XM_define_procedure(XmClipboardRegisterFormat, gxm_XmClipboardRegisterFormat_w, 3, 0, 0, H_XmClipboardRegisterFormat); XM_define_procedure(XmGetXmScreen, gxm_XmGetXmScreen_w, 1, 0, 0, H_XmGetXmScreen); XM_define_procedure(XmCreateScrollBar, gxm_XmCreateScrollBar_w, 3, 1, 0, H_XmCreateScrollBar); XM_define_procedure(XmScrollBarGetValues, gxm_XmScrollBarGetValues_w, 1, 0, 0, H_XmScrollBarGetValues); XM_define_procedure(XmScrollBarSetValues, gxm_XmScrollBarSetValues_w, 6, 0, 0, H_XmScrollBarSetValues); XM_define_procedure(XmCreateDialogShell, gxm_XmCreateDialogShell_w, 3, 1, 0, H_XmCreateDialogShell); XM_define_procedure(XmCreateScrolledWindow, gxm_XmCreateScrolledWindow_w, 3, 1, 0, H_XmCreateScrolledWindow); XM_define_procedure(XmScrollVisible, gxm_XmScrollVisible_w, 4, 0, 0, H_XmScrollVisible); XM_define_procedure(XmGetDragContext, gxm_XmGetDragContext_w, 2, 0, 0, H_XmGetDragContext); XM_define_procedure(XmGetXmDisplay, gxm_XmGetXmDisplay_w, 1, 0, 0, H_XmGetXmDisplay); XM_define_procedure(XmSelectionBoxGetChild, gxm_XmSelectionBoxGetChild_w, 2, 0, 0, H_XmSelectionBoxGetChild); XM_define_procedure(XmCreateSelectionBox, gxm_XmCreateSelectionBox_w, 3, 1, 0, H_XmCreateSelectionBox); XM_define_procedure(XmCreateSelectionDialog, gxm_XmCreateSelectionDialog_w, 3, 1, 0, H_XmCreateSelectionDialog); XM_define_procedure(XmCreatePromptDialog, gxm_XmCreatePromptDialog_w, 3, 1, 0, H_XmCreatePromptDialog); XM_define_procedure(XmDragStart, gxm_XmDragStart_w, 3, 1, 0, H_XmDragStart); XM_define_procedure(XmDragCancel, gxm_XmDragCancel_w, 1, 0, 0, H_XmDragCancel); XM_define_procedure(XmTargetsAreCompatible, gxm_XmTargetsAreCompatible_w, 5, 0, 0, H_XmTargetsAreCompatible); XM_define_procedure(XmCreateSeparatorGadget, gxm_XmCreateSeparatorGadget_w, 3, 1, 0, H_XmCreateSeparatorGadget); XM_define_procedure(XmCreateDragIcon, gxm_XmCreateDragIcon_w, 3, 1, 0, H_XmCreateDragIcon); XM_define_procedure(XmCreateSeparator, gxm_XmCreateSeparator_w, 3, 1, 0, H_XmCreateSeparator); XM_define_procedure(XmCreateDrawingArea, gxm_XmCreateDrawingArea_w, 3, 1, 0, H_XmCreateDrawingArea); XM_define_procedure(XmCreateDrawnButton, gxm_XmCreateDrawnButton_w, 3, 1, 0, H_XmCreateDrawnButton); XM_define_procedure(XmDropSiteRegister, gxm_XmDropSiteRegister_w, 2, 1, 0, H_XmDropSiteRegister); XM_define_procedure(XmDropSiteUnregister, gxm_XmDropSiteUnregister_w, 1, 0, 0, H_XmDropSiteUnregister); XM_define_procedure(XmDropSiteStartUpdate, gxm_XmDropSiteStartUpdate_w, 1, 0, 0, H_XmDropSiteStartUpdate); XM_define_procedure(XmDropSiteUpdate, gxm_XmDropSiteUpdate_w, 2, 1, 0, H_XmDropSiteUpdate); XM_define_procedure(XmDropSiteEndUpdate, gxm_XmDropSiteEndUpdate_w, 1, 0, 0, H_XmDropSiteEndUpdate); XM_define_procedure(XmDropSiteRetrieve, gxm_XmDropSiteRetrieve_w, 2, 1, 0, H_XmDropSiteRetrieve); XM_define_procedure(XmDropSiteQueryStackingOrder, gxm_XmDropSiteQueryStackingOrder_w, 1, 0, 0, H_XmDropSiteQueryStackingOrder); XM_define_procedure(XmDropSiteConfigureStackingOrder, gxm_XmDropSiteConfigureStackingOrder_w, 3, 0, 0, H_XmDropSiteConfigureStackingOrder); XM_define_procedure(XmDropTransferStart, gxm_XmDropTransferStart_w, 2, 1, 0, H_XmDropTransferStart); XM_define_procedure(XmDropTransferAdd, gxm_XmDropTransferAdd_w, 2, 0, 0, H_XmDropTransferAdd); XM_define_procedure(XmTextFieldGetString, gxm_XmTextFieldGetString_w, 1, 0, 0, H_XmTextFieldGetString); XM_define_procedure(XmTextFieldGetSubstring, gxm_XmTextFieldGetSubstring_w, 3, 0, 0, H_XmTextFieldGetSubstring); XM_define_procedure(XmTextFieldGetLastPosition, gxm_XmTextFieldGetLastPosition_w, 1, 0, 0, H_XmTextFieldGetLastPosition); XM_define_procedure(XmTextFieldSetString, gxm_XmTextFieldSetString_w, 2, 0, 0, H_XmTextFieldSetString); XM_define_procedure(XmTextFieldReplace, gxm_XmTextFieldReplace_w, 4, 0, 0, H_XmTextFieldReplace); XM_define_procedure(XmTextFieldInsert, gxm_XmTextFieldInsert_w, 3, 0, 0, H_XmTextFieldInsert); XM_define_procedure(XmTextFieldSetAddMode, gxm_XmTextFieldSetAddMode_w, 2, 0, 0, H_XmTextFieldSetAddMode); XM_define_procedure(XmTextFieldGetAddMode, gxm_XmTextFieldGetAddMode_w, 1, 0, 0, H_XmTextFieldGetAddMode); XM_define_procedure(XmTextFieldGetEditable, gxm_XmTextFieldGetEditable_w, 1, 0, 0, H_XmTextFieldGetEditable); XM_define_procedure(XmTextFieldSetEditable, gxm_XmTextFieldSetEditable_w, 2, 0, 0, H_XmTextFieldSetEditable); XM_define_procedure(XmTextFieldGetMaxLength, gxm_XmTextFieldGetMaxLength_w, 1, 0, 0, H_XmTextFieldGetMaxLength); XM_define_procedure(XmTextFieldSetMaxLength, gxm_XmTextFieldSetMaxLength_w, 2, 0, 0, H_XmTextFieldSetMaxLength); XM_define_procedure(XmTextFieldGetCursorPosition, gxm_XmTextFieldGetCursorPosition_w, 1, 0, 0, H_XmTextFieldGetCursorPosition); XM_define_procedure(XmTextFieldGetInsertionPosition, gxm_XmTextFieldGetInsertionPosition_w, 1, 0, 0, H_XmTextFieldGetInsertionPosition); XM_define_procedure(XmTextFieldSetCursorPosition, gxm_XmTextFieldSetCursorPosition_w, 2, 0, 0, H_XmTextFieldSetCursorPosition); XM_define_procedure(XmTextFieldSetInsertionPosition, gxm_XmTextFieldSetInsertionPosition_w, 2, 0, 0, H_XmTextFieldSetInsertionPosition); XM_define_procedure(XmTextFieldGetSelectionPosition, gxm_XmTextFieldGetSelectionPosition_w, 1, 0, 0, H_XmTextFieldGetSelectionPosition); XM_define_procedure(XmTextFieldGetSelection, gxm_XmTextFieldGetSelection_w, 1, 0, 0, H_XmTextFieldGetSelection); XM_define_procedure(XmTextFieldRemove, gxm_XmTextFieldRemove_w, 1, 0, 0, H_XmTextFieldRemove); XM_define_procedure(XmTextFieldCopy, gxm_XmTextFieldCopy_w, 2, 0, 0, H_XmTextFieldCopy); XM_define_procedure(XmTextFieldCut, gxm_XmTextFieldCut_w, 2, 0, 0, H_XmTextFieldCut); XM_define_procedure(XmTextFieldPaste, gxm_XmTextFieldPaste_w, 1, 0, 0, H_XmTextFieldPaste); XM_define_procedure(XmTextFieldClearSelection, gxm_XmTextFieldClearSelection_w, 2, 0, 0, H_XmTextFieldClearSelection); XM_define_procedure(XmTextFieldSetSelection, gxm_XmTextFieldSetSelection_w, 4, 0, 0, H_XmTextFieldSetSelection); XM_define_procedure(XmTextFieldXYToPos, gxm_XmTextFieldXYToPos_w, 3, 0, 0, H_XmTextFieldXYToPos); XM_define_procedure(XmTextFieldPosToXY, gxm_XmTextFieldPosToXY_w, 2, 0, 0, H_XmTextFieldPosToXY); XM_define_procedure(XmTextFieldShowPosition, gxm_XmTextFieldShowPosition_w, 2, 0, 0, H_XmTextFieldShowPosition); XM_define_procedure(XmTextFieldSetHighlight, gxm_XmTextFieldSetHighlight_w, 4, 0, 0, H_XmTextFieldSetHighlight); XM_define_procedure(XmTextFieldGetBaseline, gxm_XmTextFieldGetBaseline_w, 1, 0, 0, H_XmTextFieldGetBaseline); XM_define_procedure(XmCreateTextField, gxm_XmCreateTextField_w, 3, 1, 0, H_XmCreateTextField); XM_define_procedure(XmFileSelectionBoxGetChild, gxm_XmFileSelectionBoxGetChild_w, 2, 0, 0, H_XmFileSelectionBoxGetChild); XM_define_procedure(XmFileSelectionDoSearch, gxm_XmFileSelectionDoSearch_w, 2, 0, 0, H_XmFileSelectionDoSearch); XM_define_procedure(XmCreateFileSelectionBox, gxm_XmCreateFileSelectionBox_w, 3, 1, 0, H_XmCreateFileSelectionBox); XM_define_procedure(XmCreateFileSelectionDialog, gxm_XmCreateFileSelectionDialog_w, 3, 1, 0, H_XmCreateFileSelectionDialog); XM_define_procedure(XmTextSetHighlight, gxm_XmTextSetHighlight_w, 4, 0, 0, H_XmTextSetHighlight); XM_define_procedure(XmCreateScrolledText, gxm_XmCreateScrolledText_w, 3, 1, 0, H_XmCreateScrolledText); XM_define_procedure(XmCreateText, gxm_XmCreateText_w, 3, 1, 0, H_XmCreateText); XM_define_procedure(XmTextGetSubstring, gxm_XmTextGetSubstring_w, 3, 0, 0, H_XmTextGetSubstring); XM_define_procedure(XmTextGetString, gxm_XmTextGetString_w, 1, 0, 0, H_XmTextGetString); XM_define_procedure(XmTextGetLastPosition, gxm_XmTextGetLastPosition_w, 1, 0, 0, H_XmTextGetLastPosition); XM_define_procedure(XmTextSetString, gxm_XmTextSetString_w, 2, 0, 0, H_XmTextSetString); XM_define_procedure(XmTextReplace, gxm_XmTextReplace_w, 4, 0, 0, H_XmTextReplace); XM_define_procedure(XmTextInsert, gxm_XmTextInsert_w, 3, 0, 0, H_XmTextInsert); XM_define_procedure(XmTextSetAddMode, gxm_XmTextSetAddMode_w, 2, 0, 0, H_XmTextSetAddMode); XM_define_procedure(XmTextGetAddMode, gxm_XmTextGetAddMode_w, 1, 0, 0, H_XmTextGetAddMode); XM_define_procedure(XmTextGetEditable, gxm_XmTextGetEditable_w, 1, 0, 0, H_XmTextGetEditable); XM_define_procedure(XmTextSetEditable, gxm_XmTextSetEditable_w, 2, 0, 0, H_XmTextSetEditable); XM_define_procedure(XmTextGetMaxLength, gxm_XmTextGetMaxLength_w, 1, 0, 0, H_XmTextGetMaxLength); XM_define_procedure(XmTextSetMaxLength, gxm_XmTextSetMaxLength_w, 2, 0, 0, H_XmTextSetMaxLength); XM_define_procedure(XmTextGetTopCharacter, gxm_XmTextGetTopCharacter_w, 1, 0, 0, H_XmTextGetTopCharacter); XM_define_procedure(XmTextSetTopCharacter, gxm_XmTextSetTopCharacter_w, 2, 0, 0, H_XmTextSetTopCharacter); XM_define_procedure(XmTextGetCursorPosition, gxm_XmTextGetCursorPosition_w, 1, 0, 0, H_XmTextGetCursorPosition); XM_define_procedure(XmTextGetInsertionPosition, gxm_XmTextGetInsertionPosition_w, 1, 0, 0, H_XmTextGetInsertionPosition); XM_define_procedure(XmTextSetInsertionPosition, gxm_XmTextSetInsertionPosition_w, 2, 0, 0, H_XmTextSetInsertionPosition); XM_define_procedure(XmTextSetCursorPosition, gxm_XmTextSetCursorPosition_w, 2, 0, 0, H_XmTextSetCursorPosition); XM_define_procedure(XmTextRemove, gxm_XmTextRemove_w, 1, 0, 0, H_XmTextRemove); XM_define_procedure(XmTextCopy, gxm_XmTextCopy_w, 2, 0, 0, H_XmTextCopy); XM_define_procedure(XmTextCut, gxm_XmTextCut_w, 2, 0, 0, H_XmTextCut); XM_define_procedure(XmTextPaste, gxm_XmTextPaste_w, 1, 0, 0, H_XmTextPaste); XM_define_procedure(XmTextGetSelection, gxm_XmTextGetSelection_w, 1, 0, 0, H_XmTextGetSelection); XM_define_procedure(XmTextSetSelection, gxm_XmTextSetSelection_w, 4, 0, 0, H_XmTextSetSelection); XM_define_procedure(XmTextClearSelection, gxm_XmTextClearSelection_w, 2, 0, 0, H_XmTextClearSelection); XM_define_procedure(XmTextGetSelectionPosition, gxm_XmTextGetSelectionPosition_w, 1, 0, 0, H_XmTextGetSelectionPosition); XM_define_procedure(XmTextXYToPos, gxm_XmTextXYToPos_w, 3, 0, 0, H_XmTextXYToPos); XM_define_procedure(XmTextPosToXY, gxm_XmTextPosToXY_w, 2, 0, 0, H_XmTextPosToXY); XM_define_procedure(XmTextGetSource, gxm_XmTextGetSource_w, 1, 0, 0, H_XmTextGetSource); XM_define_procedure(XmTextSetSource, gxm_XmTextSetSource_w, 4, 0, 0, H_XmTextSetSource); XM_define_procedure(XmTextShowPosition, gxm_XmTextShowPosition_w, 2, 0, 0, H_XmTextShowPosition); XM_define_procedure(XmTextScroll, gxm_XmTextScroll_w, 2, 0, 0, H_XmTextScroll); XM_define_procedure(XmTextGetBaseline, gxm_XmTextGetBaseline_w, 1, 0, 0, H_XmTextGetBaseline); XM_define_procedure(XmTextDisableRedisplay, gxm_XmTextDisableRedisplay_w, 1, 0, 0, H_XmTextDisableRedisplay); XM_define_procedure(XmTextEnableRedisplay, gxm_XmTextEnableRedisplay_w, 1, 0, 0, H_XmTextEnableRedisplay); XM_define_procedure(XmTextFindString, gxm_XmTextFindString_w, 4, 0, 0, H_XmTextFindString); XM_define_procedure(XmCreateForm, gxm_XmCreateForm_w, 3, 1, 0, H_XmCreateForm); XM_define_procedure(XmCreateFormDialog, gxm_XmCreateFormDialog_w, 3, 1, 0, H_XmCreateFormDialog); XM_define_procedure(XmCreateFrame, gxm_XmCreateFrame_w, 3, 1, 0, H_XmCreateFrame); XM_define_procedure(XmToggleButtonGadgetGetState, gxm_XmToggleButtonGadgetGetState_w, 1, 0, 0, H_XmToggleButtonGadgetGetState); XM_define_procedure(XmToggleButtonGadgetSetState, gxm_XmToggleButtonGadgetSetState_w, 3, 0, 0, H_XmToggleButtonGadgetSetState); XM_define_procedure(XmCreateToggleButtonGadget, gxm_XmCreateToggleButtonGadget_w, 3, 1, 0, H_XmCreateToggleButtonGadget); XM_define_procedure(XmToggleButtonGetState, gxm_XmToggleButtonGetState_w, 1, 0, 0, H_XmToggleButtonGetState); XM_define_procedure(XmToggleButtonSetState, gxm_XmToggleButtonSetState_w, 3, 0, 0, H_XmToggleButtonSetState); XM_define_procedure(XmCreateToggleButton, gxm_XmCreateToggleButton_w, 3, 1, 0, H_XmCreateToggleButton); XM_define_procedure(XmCreateLabelGadget, gxm_XmCreateLabelGadget_w, 3, 1, 0, H_XmCreateLabelGadget); XM_define_procedure(XmCreateLabel, gxm_XmCreateLabel_w, 3, 1, 0, H_XmCreateLabel); XM_define_procedure(XmIsMotifWMRunning, gxm_XmIsMotifWMRunning_w, 1, 0, 0, H_XmIsMotifWMRunning); XM_define_procedure(XmListAddItem, gxm_XmListAddItem_w, 3, 0, 0, H_XmListAddItem); XM_define_procedure(XmListAddItems, gxm_XmListAddItems_w, 4, 0, 0, H_XmListAddItems); XM_define_procedure(XmListAddItemsUnselected, gxm_XmListAddItemsUnselected_w, 4, 0, 0, H_XmListAddItemsUnselected); XM_define_procedure(XmListAddItemUnselected, gxm_XmListAddItemUnselected_w, 3, 0, 0, H_XmListAddItemUnselected); XM_define_procedure(XmListDeleteItem, gxm_XmListDeleteItem_w, 2, 0, 0, H_XmListDeleteItem); XM_define_procedure(XmListDeleteItems, gxm_XmListDeleteItems_w, 2, 1, 0, H_XmListDeleteItems); XM_define_procedure(XmListDeletePositions, gxm_XmListDeletePositions_w, 2, 1, 0, H_XmListDeletePositions); XM_define_procedure(XmListDeletePos, gxm_XmListDeletePos_w, 2, 0, 0, H_XmListDeletePos); XM_define_procedure(XmListDeleteItemsPos, gxm_XmListDeleteItemsPos_w, 3, 0, 0, H_XmListDeleteItemsPos); XM_define_procedure(XmListDeleteAllItems, gxm_XmListDeleteAllItems_w, 1, 0, 0, H_XmListDeleteAllItems); XM_define_procedure(XmListReplaceItems, gxm_XmListReplaceItems_w, 4, 0, 0, H_XmListReplaceItems); XM_define_procedure(XmListReplaceItemsPos, gxm_XmListReplaceItemsPos_w, 4, 0, 0, H_XmListReplaceItemsPos); XM_define_procedure(XmListReplaceItemsUnselected, gxm_XmListReplaceItemsUnselected_w, 4, 0, 0, H_XmListReplaceItemsUnselected); XM_define_procedure(XmListReplaceItemsPosUnselected, gxm_XmListReplaceItemsPosUnselected_w, 4, 0, 0, H_XmListReplaceItemsPosUnselected); XM_define_procedure(XmListReplacePositions, gxm_XmListReplacePositions_w, 4, 0, 0, H_XmListReplacePositions); XM_define_procedure(XmListSelectItem, gxm_XmListSelectItem_w, 3, 0, 0, H_XmListSelectItem); XM_define_procedure(XmListSelectPos, gxm_XmListSelectPos_w, 3, 0, 0, H_XmListSelectPos); XM_define_procedure(XmListDeselectItem, gxm_XmListDeselectItem_w, 2, 0, 0, H_XmListDeselectItem); XM_define_procedure(XmListDeselectPos, gxm_XmListDeselectPos_w, 2, 0, 0, H_XmListDeselectPos); XM_define_procedure(XmListDeselectAllItems, gxm_XmListDeselectAllItems_w, 1, 0, 0, H_XmListDeselectAllItems); XM_define_procedure(XmListSetPos, gxm_XmListSetPos_w, 2, 0, 0, H_XmListSetPos); XM_define_procedure(XmListSetBottomPos, gxm_XmListSetBottomPos_w, 2, 0, 0, H_XmListSetBottomPos); XM_define_procedure(XmListSetItem, gxm_XmListSetItem_w, 2, 0, 0, H_XmListSetItem); XM_define_procedure(XmListSetBottomItem, gxm_XmListSetBottomItem_w, 2, 0, 0, H_XmListSetBottomItem); XM_define_procedure(XmListSetAddMode, gxm_XmListSetAddMode_w, 2, 0, 0, H_XmListSetAddMode); XM_define_procedure(XmListItemExists, gxm_XmListItemExists_w, 2, 0, 0, H_XmListItemExists); XM_define_procedure(XmListItemPos, gxm_XmListItemPos_w, 2, 0, 0, H_XmListItemPos); XM_define_procedure(XmListGetKbdItemPos, gxm_XmListGetKbdItemPos_w, 1, 0, 0, H_XmListGetKbdItemPos); XM_define_procedure(XmListSetKbdItemPos, gxm_XmListSetKbdItemPos_w, 2, 0, 0, H_XmListSetKbdItemPos); XM_define_procedure(XmListYToPos, gxm_XmListYToPos_w, 2, 0, 0, H_XmListYToPos); XM_define_procedure(XmListPosToBounds, gxm_XmListPosToBounds_w, 2, 0, 0, H_XmListPosToBounds); XM_define_procedure(XmListGetMatchPos, gxm_XmListGetMatchPos_w, 2, 0, 0, H_XmListGetMatchPos); XM_define_procedure(XmListSetHorizPos, gxm_XmListSetHorizPos_w, 2, 0, 0, H_XmListSetHorizPos); XM_define_procedure(XmListUpdateSelectedList, gxm_XmListUpdateSelectedList_w, 1, 0, 0, H_XmListUpdateSelectedList); XM_define_procedure(XmListPosSelected, gxm_XmListPosSelected_w, 2, 0, 0, H_XmListPosSelected); XM_define_procedure(XmCreateList, gxm_XmCreateList_w, 3, 1, 0, H_XmCreateList); XM_define_procedure(XmCreateScrolledList, gxm_XmCreateScrolledList_w, 3, 1, 0, H_XmCreateScrolledList); XM_define_procedure(XmTranslateKey, gxm_XmTranslateKey_w, 3, 0, 0, H_XmTranslateKey); XM_define_procedure(XmCreateMainWindow, gxm_XmCreateMainWindow_w, 3, 1, 0, H_XmCreateMainWindow); XM_define_procedure(XmInstallImage, gxm_XmInstallImage_w, 2, 0, 0, H_XmInstallImage); XM_define_procedure(XmUninstallImage, gxm_XmUninstallImage_w, 1, 0, 0, H_XmUninstallImage); XM_define_procedure(XmGetPixmap, gxm_XmGetPixmap_w, 4, 0, 0, H_XmGetPixmap); XM_define_procedure(XmGetPixmapByDepth, gxm_XmGetPixmapByDepth_w, 5, 0, 0, H_XmGetPixmapByDepth); XM_define_procedure(XmDestroyPixmap, gxm_XmDestroyPixmap_w, 2, 0, 0, H_XmDestroyPixmap); XM_define_procedure(XmUpdateDisplay, gxm_XmUpdateDisplay_w, 1, 0, 0, H_XmUpdateDisplay); XM_define_procedure(XmWidgetGetBaselines, gxm_XmWidgetGetBaselines_w, 1, 0, 0, H_XmWidgetGetBaselines); XM_define_procedure(XmRegisterSegmentEncoding, gxm_XmRegisterSegmentEncoding_w, 2, 0, 0, H_XmRegisterSegmentEncoding); XM_define_procedure(XmMapSegmentEncoding, gxm_XmMapSegmentEncoding_w, 1, 0, 0, H_XmMapSegmentEncoding); XM_define_procedure(XmCvtCTToXmString, gxm_XmCvtCTToXmString_w, 1, 0, 0, H_XmCvtCTToXmString); XM_define_procedure(XmCvtXmStringToCT, gxm_XmCvtXmStringToCT_w, 1, 0, 0, H_XmCvtXmStringToCT); XM_define_procedure(XmConvertUnits, gxm_XmConvertUnits_w, 5, 0, 0, H_XmConvertUnits); XM_define_procedure(XmCreateSimpleMenuBar, gxm_XmCreateSimpleMenuBar_w, 3, 1, 0, H_XmCreateSimpleMenuBar); XM_define_procedure(XmCreateSimplePopupMenu, gxm_XmCreateSimplePopupMenu_w, 3, 1, 0, H_XmCreateSimplePopupMenu); XM_define_procedure(XmCreateSimplePulldownMenu, gxm_XmCreateSimplePulldownMenu_w, 3, 1, 0, H_XmCreateSimplePulldownMenu); XM_define_procedure(XmCreateSimpleOptionMenu, gxm_XmCreateSimpleOptionMenu_w, 3, 1, 0, H_XmCreateSimpleOptionMenu); XM_define_procedure(XmCreateSimpleRadioBox, gxm_XmCreateSimpleRadioBox_w, 3, 1, 0, H_XmCreateSimpleRadioBox); XM_define_procedure(XmCreateSimpleCheckBox, gxm_XmCreateSimpleCheckBox_w, 3, 1, 0, H_XmCreateSimpleCheckBox); XM_define_procedure(XmVaCreateSimpleMenuBar, gxm_XmVaCreateSimpleMenuBar_w, 3, 0, 0, H_XmVaCreateSimpleMenuBar); XM_define_procedure(XmVaCreateSimplePopupMenu, gxm_XmVaCreateSimplePopupMenu_w, 4, 0, 0, H_XmVaCreateSimplePopupMenu); XM_define_procedure(XmVaCreateSimplePulldownMenu, gxm_XmVaCreateSimplePulldownMenu_w, 5, 0, 0, H_XmVaCreateSimplePulldownMenu); XM_define_procedure(XmVaCreateSimpleOptionMenu, gxm_XmVaCreateSimpleOptionMenu_w, 7, 0, 0, H_XmVaCreateSimpleOptionMenu); XM_define_procedure(XmVaCreateSimpleRadioBox, gxm_XmVaCreateSimpleRadioBox_w, 5, 0, 0, H_XmVaCreateSimpleRadioBox); XM_define_procedure(XmVaCreateSimpleCheckBox, gxm_XmVaCreateSimpleCheckBox_w, 4, 0, 0, H_XmVaCreateSimpleCheckBox); XM_define_procedure(XmTrackingEvent, gxm_XmTrackingEvent_w, 3, 0, 0, H_XmTrackingEvent); XM_define_procedure(XmSetColorCalculation, gxm_XmSetColorCalculation_w, 1, 0, 0, H_XmSetColorCalculation); XM_define_procedure(XmGetColorCalculation, gxm_XmGetColorCalculation_w, 0, 0, 0, H_XmGetColorCalculation); XM_define_procedure(XmGetColors, gxm_XmGetColors_w, 3, 0, 0, H_XmGetColors); XM_define_procedure(XmChangeColor, gxm_XmChangeColor_w, 2, 0, 0, H_XmChangeColor); XM_define_procedure(XmStringCreate, gxm_XmStringCreate_w, 2, 0, 0, H_XmStringCreate); XM_define_procedure(XmStringCreateLocalized, gxm_XmStringCreateLocalized_w, 1, 0, 0, H_XmStringCreateLocalized); XM_define_procedure(XmStringDirectionCreate, gxm_XmStringDirectionCreate_w, 1, 0, 0, H_XmStringDirectionCreate); XM_define_procedure(XmStringSeparatorCreate, gxm_XmStringSeparatorCreate_w, 0, 0, 0, H_XmStringSeparatorCreate); XM_define_procedure(XmStringInitContext, gxm_XmStringInitContext_w, 1, 0, 0, H_XmStringInitContext); XM_define_procedure(XmStringFreeContext, gxm_XmStringFreeContext_w, 1, 0, 0, H_XmStringFreeContext); XM_define_procedure(XmCvtXmStringToByteStream, gxm_XmCvtXmStringToByteStream_w, 1, 0, 0, H_XmCvtXmStringToByteStream); XM_define_procedure(XmCvtByteStreamToXmString, gxm_XmCvtByteStreamToXmString_w, 1, 0, 0, H_XmCvtByteStreamToXmString); XM_define_procedure(XmStringByteStreamLength, gxm_XmStringByteStreamLength_w, 1, 0, 0, H_XmStringByteStreamLength); XM_define_procedure(XmStringConcatAndFree, gxm_XmStringConcatAndFree_w, 2, 0, 0, H_XmStringConcatAndFree); XM_define_procedure(XmStringIsVoid, gxm_XmStringIsVoid_w, 1, 0, 0, H_XmStringIsVoid); XM_define_procedure(XmStringPeekNextTriple, gxm_XmStringPeekNextTriple_w, 1, 0, 0, H_XmStringPeekNextTriple); XM_define_procedure(XmStringGetNextTriple, gxm_XmStringGetNextTriple_w, 1, 0, 0, H_XmStringGetNextTriple); XM_define_procedure(XmStringComponentCreate, gxm_XmStringComponentCreate_w, 3, 0, 0, H_XmStringComponentCreate); XM_define_procedure(XmStringUnparse, gxm_XmStringUnparse_w, 7, 0, 0, H_XmStringUnparse); XM_define_procedure(XmStringParseText, gxm_XmStringParseText_w, 7, 0, 0, H_XmStringParseText); XM_define_procedure(XmStringToXmStringTable, gxm_XmStringToXmStringTable_w, 2, 0, 0, H_XmStringToXmStringTable); XM_define_procedure(XmStringTableToXmString, gxm_XmStringTableToXmString_w, 3, 0, 0, H_XmStringTableToXmString); XM_define_procedure(XmStringTableUnparse, gxm_XmStringTableUnparse_w, 8, 0, 0, H_XmStringTableUnparse); XM_define_procedure(XmStringTableParseStringArray, gxm_XmStringTableParseStringArray_w, 7, 0, 0, H_XmStringTableParseStringArray); XM_define_procedure(XmDirectionToStringDirection, gxm_XmDirectionToStringDirection_w, 1, 0, 0, H_XmDirectionToStringDirection); XM_define_procedure(XmStringDirectionToDirection, gxm_XmStringDirectionToDirection_w, 1, 0, 0, H_XmStringDirectionToDirection); XM_define_procedure(XmStringGenerate, gxm_XmStringGenerate_w, 4, 0, 0, H_XmStringGenerate); XM_define_procedure(XmStringPutRendition, gxm_XmStringPutRendition_w, 2, 0, 0, H_XmStringPutRendition); XM_define_procedure(XmParseMappingCreate, gxm_XmParseMappingCreate_w, 1, 1, 0, H_XmParseMappingCreate); XM_define_procedure(XmParseMappingSetValues, gxm_XmParseMappingSetValues_w, 2, 1, 0, H_XmParseMappingSetValues); XM_define_procedure(XmParseMappingGetValues, gxm_XmParseMappingGetValues_w, 2, 1, 0, H_XmParseMappingGetValues); XM_define_procedure(XmParseMappingFree, gxm_XmParseMappingFree_w, 1, 0, 0, H_XmParseMappingFree); XM_define_procedure(XmParseTableFree, gxm_XmParseTableFree_w, 1, 1, 0, H_XmParseTableFree); XM_define_procedure(XmStringTableProposeTablist, gxm_XmStringTableProposeTablist_w, 5, 0, 0, H_XmStringTableProposeTablist); XM_define_procedure(XmTabSetValue, gxm_XmTabSetValue_w, 2, 0, 0, H_XmTabSetValue); XM_define_procedure(XmTabGetValues, gxm_XmTabGetValues_w, 1, 0, 0, H_XmTabGetValues); XM_define_procedure(XmTabFree, gxm_XmTabFree_w, 1, 0, 0, H_XmTabFree); XM_define_procedure(XmTabListFree, gxm_XmTabListFree_w, 1, 0, 0, H_XmTabListFree); XM_define_procedure(XmTabCreate, gxm_XmTabCreate_w, 5, 0, 0, H_XmTabCreate); XM_define_procedure(XmTabListTabCount, gxm_XmTabListTabCount_w, 1, 0, 0, H_XmTabListTabCount); XM_define_procedure(XmTabListRemoveTabs, gxm_XmTabListRemoveTabs_w, 2, 1, 0, H_XmTabListRemoveTabs); XM_define_procedure(XmTabListReplacePositions, gxm_XmTabListReplacePositions_w, 3, 1, 0, H_XmTabListReplacePositions); XM_define_procedure(XmTabListGetTab, gxm_XmTabListGetTab_w, 2, 0, 0, H_XmTabListGetTab); XM_define_procedure(XmTabListCopy, gxm_XmTabListCopy_w, 3, 0, 0, H_XmTabListCopy); XM_define_procedure(XmTabListInsertTabs, gxm_XmTabListInsertTabs_w, 4, 0, 0, H_XmTabListInsertTabs); XM_define_procedure(XmRenderTableCvtFromProp, gxm_XmRenderTableCvtFromProp_w, 3, 0, 0, H_XmRenderTableCvtFromProp); XM_define_procedure(XmRenderTableCvtToProp, gxm_XmRenderTableCvtToProp_w, 2, 0, 0, H_XmRenderTableCvtToProp); XM_define_procedure(XmRenditionUpdate, gxm_XmRenditionUpdate_w, 2, 1, 0, H_XmRenditionUpdate); XM_define_procedure(XmRenditionRetrieve, gxm_XmRenditionRetrieve_w, 2, 1, 0, H_XmRenditionRetrieve); XM_define_procedure(XmRenditionFree, gxm_XmRenditionFree_w, 1, 0, 0, H_XmRenditionFree); XM_define_procedure(XmRenditionCreate, gxm_XmRenditionCreate_w, 3, 1, 0, H_XmRenditionCreate); XM_define_procedure(XmRenderTableGetRenditions, gxm_XmRenderTableGetRenditions_w, 0, 3, 0, H_XmRenderTableGetRenditions); XM_define_procedure(XmRenderTableGetRendition, gxm_XmRenderTableGetRendition_w, 2, 0, 0, H_XmRenderTableGetRendition); XM_define_procedure(XmRenderTableGetTags, gxm_XmRenderTableGetTags_w, 1, 0, 0, H_XmRenderTableGetTags); XM_define_procedure(XmRenderTableFree, gxm_XmRenderTableFree_w, 1, 0, 0, H_XmRenderTableFree); XM_define_procedure(XmRenderTableCopy, gxm_XmRenderTableCopy_w, 0, 3, 0, H_XmRenderTableCopy); XM_define_procedure(XmRenderTableRemoveRenditions, gxm_XmRenderTableRemoveRenditions_w, 0, 3, 0, H_XmRenderTableRemoveRenditions); XM_define_procedure(XmRenderTableAddRenditions, gxm_XmRenderTableAddRenditions_w, 4, 0, 0, H_XmRenderTableAddRenditions); XM_define_procedure(XmStringConcat, gxm_XmStringConcat_w, 2, 0, 0, H_XmStringConcat); XM_define_procedure(XmStringCopy, gxm_XmStringCopy_w, 1, 0, 0, H_XmStringCopy); XM_define_procedure(XmStringCompare, gxm_XmStringCompare_w, 2, 0, 0, H_XmStringCompare); XM_define_procedure(XmStringEmpty, gxm_XmStringEmpty_w, 1, 0, 0, H_XmStringEmpty); XM_define_procedure(XmStringHasSubstring, gxm_XmStringHasSubstring_w, 2, 0, 0, H_XmStringHasSubstring); XM_define_procedure(XmStringFree, gxm_XmStringFree_w, 1, 0, 0, H_XmStringFree); XM_define_procedure(XmStringBaseline, gxm_XmStringBaseline_w, 2, 0, 0, H_XmStringBaseline); XM_define_procedure(XmStringWidth, gxm_XmStringWidth_w, 2, 0, 0, H_XmStringWidth); XM_define_procedure(XmStringHeight, gxm_XmStringHeight_w, 2, 0, 0, H_XmStringHeight); XM_define_procedure(XmStringExtent, gxm_XmStringExtent_w, 2, 0, 0, H_XmStringExtent); XM_define_procedure(XmStringLineCount, gxm_XmStringLineCount_w, 1, 0, 0, H_XmStringLineCount); XM_define_procedure(XmStringDraw, gxm_XmStringDraw_w, 0, 0, 1, H_XmStringDraw); XM_define_procedure(XmStringDrawImage, gxm_XmStringDrawImage_w, 0, 0, 1, H_XmStringDrawImage); XM_define_procedure(XmStringDrawUnderline, gxm_XmStringDrawUnderline_w, 0, 0, 1, H_XmStringDrawUnderline); XM_define_procedure(XmGetDestination, gxm_XmGetDestination_w, 1, 0, 0, H_XmGetDestination); XM_define_procedure(XmIsTraversable, gxm_XmIsTraversable_w, 1, 0, 0, H_XmIsTraversable); XM_define_procedure(XmGetVisibility, gxm_XmGetVisibility_w, 1, 0, 0, H_XmGetVisibility); XM_define_procedure(XmGetTabGroup, gxm_XmGetTabGroup_w, 1, 0, 0, H_XmGetTabGroup); XM_define_procedure(XmGetFocusWidget, gxm_XmGetFocusWidget_w, 1, 0, 0, H_XmGetFocusWidget); XM_define_procedure(XmProcessTraversal, gxm_XmProcessTraversal_w, 2, 0, 0, H_XmProcessTraversal); XM_define_procedure(XmCreateMenuShell, gxm_XmCreateMenuShell_w, 3, 1, 0, H_XmCreateMenuShell); XM_define_procedure(XmIsMessageBox, gxm_XmIsMessageBox_w, 1, 0, 0, H_XmIsMessageBox); XM_define_procedure(XmIsArrowButtonGadget, gxm_XmIsArrowButtonGadget_w, 1, 0, 0, H_XmIsArrowButtonGadget); XM_define_procedure(XmIsArrowButton, gxm_XmIsArrowButton_w, 1, 0, 0, H_XmIsArrowButton); XM_define_procedure(XmIsNotebook, gxm_XmIsNotebook_w, 1, 0, 0, H_XmIsNotebook); XM_define_procedure(XmIsComboBox, gxm_XmIsComboBox_w, 1, 0, 0, H_XmIsComboBox); XM_define_procedure(XmIsContainer, gxm_XmIsContainer_w, 1, 0, 0, H_XmIsContainer); XM_define_procedure(XmIsGrabShell, gxm_XmIsGrabShell_w, 1, 0, 0, H_XmIsGrabShell); XM_define_procedure(XmIsIconGadget, gxm_XmIsIconGadget_w, 1, 0, 0, H_XmIsIconGadget); XM_define_procedure(XmIsIconHeader, gxm_XmIsIconHeader_w, 1, 0, 0, H_XmIsIconHeader); XM_define_procedure(XmIsPanedWindow, gxm_XmIsPanedWindow_w, 1, 0, 0, H_XmIsPanedWindow); XM_define_procedure(XmIsBulletinBoard, gxm_XmIsBulletinBoard_w, 1, 0, 0, H_XmIsBulletinBoard); XM_define_procedure(XmIsPrimitive, gxm_XmIsPrimitive_w, 1, 0, 0, H_XmIsPrimitive); XM_define_procedure(XmIsCascadeButtonGadget, gxm_XmIsCascadeButtonGadget_w, 1, 0, 0, H_XmIsCascadeButtonGadget); XM_define_procedure(XmIsCascadeButton, gxm_XmIsCascadeButton_w, 1, 0, 0, H_XmIsCascadeButton); XM_define_procedure(XmIsPushButtonGadget, gxm_XmIsPushButtonGadget_w, 1, 0, 0, H_XmIsPushButtonGadget); XM_define_procedure(XmIsPushButton, gxm_XmIsPushButton_w, 1, 0, 0, H_XmIsPushButton); XM_define_procedure(XmIsCommand, gxm_XmIsCommand_w, 1, 0, 0, H_XmIsCommand); XM_define_procedure(XmIsRowColumn, gxm_XmIsRowColumn_w, 1, 0, 0, H_XmIsRowColumn); XM_define_procedure(XmIsScale, gxm_XmIsScale_w, 1, 0, 0, H_XmIsScale); XM_define_procedure(XmIsScreen, gxm_XmIsScreen_w, 1, 0, 0, H_XmIsScreen); XM_define_procedure(XmIsScrollBar, gxm_XmIsScrollBar_w, 1, 0, 0, H_XmIsScrollBar); XM_define_procedure(XmIsDialogShell, gxm_XmIsDialogShell_w, 1, 0, 0, H_XmIsDialogShell); XM_define_procedure(XmIsScrolledWindow, gxm_XmIsScrolledWindow_w, 1, 0, 0, H_XmIsScrolledWindow); XM_define_procedure(XmIsDisplay, gxm_XmIsDisplay_w, 1, 0, 0, H_XmIsDisplay); XM_define_procedure(XmIsSelectionBox, gxm_XmIsSelectionBox_w, 1, 0, 0, H_XmIsSelectionBox); XM_define_procedure(XmIsDragContext, gxm_XmIsDragContext_w, 1, 0, 0, H_XmIsDragContext); XM_define_procedure(XmIsSeparatorGadget, gxm_XmIsSeparatorGadget_w, 1, 0, 0, H_XmIsSeparatorGadget); XM_define_procedure(XmIsDragIconObjectClass, gxm_XmIsDragIconObjectClass_w, 1, 0, 0, H_XmIsDragIconObjectClass); XM_define_procedure(XmIsSeparator, gxm_XmIsSeparator_w, 1, 0, 0, H_XmIsSeparator); XM_define_procedure(XmIsDrawingArea, gxm_XmIsDrawingArea_w, 1, 0, 0, H_XmIsDrawingArea); XM_define_procedure(XmIsDrawnButton, gxm_XmIsDrawnButton_w, 1, 0, 0, H_XmIsDrawnButton); XM_define_procedure(XmIsDropSiteManager, gxm_XmIsDropSiteManager_w, 1, 0, 0, H_XmIsDropSiteManager); XM_define_procedure(XmIsDropTransfer, gxm_XmIsDropTransfer_w, 1, 0, 0, H_XmIsDropTransfer); XM_define_procedure(XmIsTextField, gxm_XmIsTextField_w, 1, 0, 0, H_XmIsTextField); XM_define_procedure(XmIsFileSelectionBox, gxm_XmIsFileSelectionBox_w, 1, 0, 0, H_XmIsFileSelectionBox); XM_define_procedure(XmIsText, gxm_XmIsText_w, 1, 0, 0, H_XmIsText); XM_define_procedure(XmIsForm, gxm_XmIsForm_w, 1, 0, 0, H_XmIsForm); XM_define_procedure(XmIsFrame, gxm_XmIsFrame_w, 1, 0, 0, H_XmIsFrame); XM_define_procedure(XmIsGadget, gxm_XmIsGadget_w, 1, 0, 0, H_XmIsGadget); XM_define_procedure(XmIsToggleButtonGadget, gxm_XmIsToggleButtonGadget_w, 1, 0, 0, H_XmIsToggleButtonGadget); XM_define_procedure(XmIsToggleButton, gxm_XmIsToggleButton_w, 1, 0, 0, H_XmIsToggleButton); XM_define_procedure(XmIsLabelGadget, gxm_XmIsLabelGadget_w, 1, 0, 0, H_XmIsLabelGadget); XM_define_procedure(XmIsLabel, gxm_XmIsLabel_w, 1, 0, 0, H_XmIsLabel); XM_define_procedure(XmIsVendorShell, gxm_XmIsVendorShell_w, 1, 0, 0, H_XmIsVendorShell); XM_define_procedure(XmIsList, gxm_XmIsList_w, 1, 0, 0, H_XmIsList); XM_define_procedure(XmIsMainWindow, gxm_XmIsMainWindow_w, 1, 0, 0, H_XmIsMainWindow); XM_define_procedure(XmIsManager, gxm_XmIsManager_w, 1, 0, 0, H_XmIsManager); XM_define_procedure(XmIsMenuShell, gxm_XmIsMenuShell_w, 1, 0, 0, H_XmIsMenuShell); XM_define_procedure(XmListGetSelectedPos, gxm_XmListGetSelectedPos_w, 1, 0, 0, H_XmListGetSelectedPos); XM_define_procedure(XpmCreatePixmapFromData, gxm_XpmCreatePixmapFromData_w, 4, 0, 0, NULL); XM_define_procedure(XpmCreateDataFromPixmap, gxm_XpmCreateDataFromPixmap_w, 4, 0, 0, NULL); XM_define_procedure(XpmReadFileToPixmap, gxm_XpmReadFileToPixmap_w, 4, 0, 0, NULL); XM_define_procedure(XpmReadFileToXpmImage, gxm_XpmReadFileToXpmImage_w, 1, 0, 0, NULL); XM_define_procedure(XpmGetErrorString, gxm_XpmGetErrorString_w, 1, 0, 0, H_XpmGetErrorString); XM_define_procedure(XpmReadPixmapFile, gxm_XpmReadFileToPixmap_w, 4, 0, 0, NULL); XM_define_procedure(XpmWriteFileFromPixmap, gxm_XpmWriteFileFromPixmap_w, 5, 0, 0, NULL); XM_define_procedure(XpmWritePixmapFile, gxm_XpmWriteFileFromPixmap_w, 5, 0, 0, NULL); XM_define_procedure(XpmCreatePixmapFromXpmImage, gxm_XpmCreatePixmapFromXpmImage_w, 4, 0, 0, NULL); XM_define_procedure(XpmCreateXpmImageFromPixmap, gxm_XpmCreateXpmImageFromPixmap_w, 4, 0, 0, NULL); XM_define_procedure(XGetPixel, gxm_XGetPixel_w, 3, 0, 0, H_XGetPixel); XM_define_procedure(XDestroyImage, gxm_XDestroyImage_w, 1, 0, 0, H_XDestroyImage); XM_define_procedure(XPutPixel, gxm_XPutPixel_w, 4, 0, 0, H_XPutPixel); XM_define_procedure(XSubImage, gxm_XSubImage_w, 5, 0, 0, H_XSubImage); XM_define_procedure(XAddPixel, gxm_XAddPixel_w, 2, 0, 0, H_XAddPixel); XM_define_procedure(XtAppContext?, g_is_XtAppContext_w, 1, 0, 0, PROC_TRUE " if arg is a XtAppContext"); XM_define_procedure(XtRequestId?, g_is_XtRequestId_w, 1, 0, 0, PROC_TRUE " if arg is a XtRequestId"); XM_define_procedure(XtWorkProcId?, g_is_XtWorkProcId_w, 1, 0, 0, PROC_TRUE " if arg is a XtWorkProcId"); XM_define_procedure(XtInputId?, g_is_XtInputId_w, 1, 0, 0, PROC_TRUE " if arg is a XtInputId"); XM_define_procedure(XtIntervalId?, g_is_XtIntervalId_w, 1, 0, 0, PROC_TRUE " if arg is a XtIntervalId"); XM_define_procedure(Screen?, g_is_Screen_w, 1, 0, 0, PROC_TRUE " if arg is a Screen"); XM_define_procedure(XEvent?, g_is_XEvent_w, 1, 0, 0, PROC_TRUE " if arg is a XEvent"); XM_define_procedure(XRectangle?, g_is_XRectangle_w, 1, 0, 0, PROC_TRUE " if arg is a XRectangle"); XM_define_procedure(XArc?, g_is_XArc_w, 1, 0, 0, PROC_TRUE " if arg is a XArc"); XM_define_procedure(XPoint?, g_is_XPoint_w, 1, 0, 0, PROC_TRUE " if arg is a XPoint"); XM_define_procedure(XSegment?, g_is_XSegment_w, 1, 0, 0, PROC_TRUE " if arg is a XSegment"); XM_define_procedure(XColor?, g_is_XColor_w, 1, 0, 0, PROC_TRUE " if arg is a XColor"); XM_define_procedure(Atom?, g_is_Atom_w, 1, 0, 0, PROC_TRUE " if arg is an Atom"); XM_define_procedure(Colormap?, g_is_Colormap_w, 1, 0, 0, PROC_TRUE " if arg is a Colormap"); XM_define_procedure(XModifierKeymap?, g_is_XModifierKeymap_w, 1, 0, 0, PROC_TRUE " if arg is a XModifierKeymap"); XM_define_procedure(Depth?, g_is_Depth_w, 1, 0, 0, PROC_TRUE " if arg is a Depth"); XM_define_procedure(Display?, g_is_Display_w, 1, 0, 0, PROC_TRUE " if arg is a Display"); XM_define_procedure(Drawable?, g_is_Window_w, 1, 0, 0, PROC_TRUE " if arg is a Drawable"); XM_define_procedure(Font?, g_is_Font_w, 1, 0, 0, PROC_TRUE " if arg is a Font"); XM_define_procedure(GC?, g_is_GC_w, 1, 0, 0, PROC_TRUE " if arg is a GC"); XM_define_procedure(KeySym?, g_is_KeySym_w, 1, 0, 0, PROC_TRUE " if arg is a KeySym"); XM_define_procedure(Pixel?, g_is_Pixel_w, 1, 0, 0, PROC_TRUE " if arg is a Pixel"); XM_define_procedure(Pixmap?, g_is_Pixmap_w, 1, 0, 0, PROC_TRUE " if arg is a Pixmap"); XM_define_procedure(Region?, g_is_Region_w, 1, 0, 0, PROC_TRUE " if arg is a Region"); XM_define_procedure(Time?, g_is_Time_w, 1, 0, 0, PROC_TRUE " if arg is a Time"); XM_define_procedure(Visual?, g_is_Visual_w, 1, 0, 0, PROC_TRUE " if arg is a Visual"); XM_define_procedure(Window?, g_is_Window_w, 1, 0, 0, PROC_TRUE " if arg is a Window"); XM_define_procedure(Widget?, g_is_Widget_w, 1, 0, 0, PROC_TRUE " if arg is a Widget"); XM_define_procedure(XmStringContext?, g_is_XmStringContext_w, 1, 0, 0, PROC_TRUE " if arg is a XmStringContext"); XM_define_procedure(XFontProp?, g_is_XFontProp_w, 1, 0, 0, PROC_TRUE " if arg is a XFontProp"); XM_define_procedure(XFontSet?, g_is_XFontSet_w, 1, 0, 0, PROC_TRUE " if arg is a XFontSet"); XM_define_procedure(XFontStruct?, g_is_XFontStruct_w, 1, 0, 0, PROC_TRUE " if arg is a XFontStruct"); XM_define_procedure(XGCValues?, g_is_XGCValues_w, 1, 0, 0, PROC_TRUE " if arg is a XGCValues"); XM_define_procedure(XImage?, g_is_XImage_w, 1, 0, 0, PROC_TRUE " if arg is a XImage"); XM_define_procedure(XVisualInfo?, g_is_XVisualInfo_w, 1, 0, 0, PROC_TRUE " if arg is a XVisualInfo"); XM_define_procedure(XWMHints?, g_is_XWMHints_w, 1, 0, 0, PROC_TRUE " if arg is a XWMHints"); XM_define_procedure(XWindowAttributes?, g_is_XWindowAttributes_w, 1, 0, 0, PROC_TRUE " if arg is a XWindowAttributes"); XM_define_procedure(XWindowChanges?, g_is_XWindowChanges_w, 1, 0, 0, PROC_TRUE " if arg is a XWindowChanges"); XM_define_procedure(KeyCode?, g_is_KeyCode_w, 1, 0, 0, PROC_TRUE " if arg is a KeyCode"); XM_define_procedure(XContext?, g_is_XContext_w, 1, 0, 0, PROC_TRUE " if arg is a XContext"); XM_define_procedure(XCharStruct?, g_is_XCharStruct_w, 1, 0, 0, PROC_TRUE " if arg is a XCharStruct"); XM_define_procedure(XTextItem?, g_is_XTextItem_w, 1, 0, 0, PROC_TRUE " if arg is a XTextItem"); XM_define_procedure(XStandardColormap?, g_is_XStandardColormap_w, 1, 0, 0, PROC_TRUE " if arg is a XStandardColormap"); XM_define_procedure(Cursor?, g_is_Cursor_w, 1, 0, 0, PROC_TRUE " if arg is a Cursor"); XM_define_procedure(WidgetClass?, g_is_WidgetClass_w, 1, 0, 0, PROC_TRUE " if arg is a WidgetClass"); XM_define_procedure(XmString?, g_is_XmString_w, 1, 0, 0, PROC_TRUE " if arg is a XmString"); XM_define_procedure(XmToggleButton?, gxm_XmIsToggleButton_w, 1, 0, 0, H_XmIsToggleButton); XM_define_procedure(XmDrawingArea?, gxm_XmIsDrawingArea_w, 1, 0, 0, H_XmIsDrawingArea); XM_define_procedure(XmPushButton?, gxm_XmIsPushButton_w, 1, 0, 0, H_XmIsPushButton); XM_define_procedure(XmTextField?, gxm_XmIsTextField_w, 1, 0, 0, H_XmIsTextField); XM_define_procedure(XmFileSelectionBox?, gxm_XmIsFileSelectionBox_w, 1, 0, 0, H_XmIsFileSelectionBox); XM_define_procedure(XmText?, gxm_XmIsText_w, 1, 0, 0, H_XmIsText); XM_define_procedure(XmFrame?, gxm_XmIsFrame_w, 1, 0, 0, H_XmIsFrame); XM_define_procedure(XmLabel?, gxm_XmIsLabel_w, 1, 0, 0, H_XmIsLabel); XM_define_procedure(XmList?, gxm_XmIsList_w, 1, 0, 0, H_XmIsList); XM_define_procedure(XmArrowButton?, gxm_XmIsArrowButton_w, 1, 0, 0, H_XmIsArrowButton); XM_define_procedure(XmScrollBar?, gxm_XmIsScrollBar_w, 1, 0, 0, H_XmIsScrollBar); XM_define_procedure(XmCommand?, gxm_XmIsCommand_w, 1, 0, 0, H_XmIsCommand); XM_define_procedure(XmScale?, gxm_XmIsScale_w, 1, 0, 0, H_XmIsScale); XM_define_procedure(XmRowColumn?, gxm_XmIsRowColumn_w, 1, 0, 0, H_XmIsRowColumn); XM_define_procedure(XmTab?, g_is_XmTab_w, 1, 0, 0, PROC_TRUE " if arg is a Tab"); XM_define_procedure(XmNotebook?, gxm_XmIsNotebook_w, 1, 0, 0, H_XmIsNotebook); XM_define_procedure(XmComboBox?, gxm_XmIsComboBox_w, 1, 0, 0, H_XmIsComboBox); XM_define_procedure(XmContainer?, gxm_XmIsContainer_w, 1, 0, 0, H_XmIsContainer); XM_define_procedure(XmIconHeader?, gxm_XmIsIconHeader_w, 1, 0, 0, H_XmIsIconHeader); XM_define_procedure(XmGrabShell?, gxm_XmIsGrabShell_w, 1, 0, 0, H_XmIsGrabShell); XM_define_procedure(XmRendition?, g_is_XmRendition_w, 1, 0, 0, PROC_TRUE " if arg is a Rendition"); XM_define_procedure(XmRenderTable?, g_is_XmRenderTable_w, 1, 0, 0, PROC_TRUE " if arg is a RenderTable"); XM_define_procedure(XmIconGadget?, gxm_XmIsIconGadget_w, 1, 0, 0, H_XmIsIconGadget); XM_define_procedure(XmTabList?, g_is_XmTabList_w, 1, 0, 0, PROC_TRUE " if arg is a TabList"); XM_define_procedure(XmParseMapping?, g_is_XmParseMapping_w, 1, 0, 0, PROC_TRUE " if arg is a ParseMapping"); XM_define_procedure(XmPanedWindow?, gxm_XmIsPanedWindow_w, 1, 0, 0, H_XmIsPanedWindow); XM_define_procedure(XmScrolledWindow?, gxm_XmIsScrolledWindow_w, 1, 0, 0, H_XmIsScrolledWindow); XM_define_procedure(XmCascadeButton?, gxm_XmIsCascadeButton_w, 1, 0, 0, H_XmIsCascadeButton); XM_define_procedure(XmForm?, gxm_XmIsForm_w, 1, 0, 0, H_XmIsForm); XM_define_procedure(XmBulletinBoard?, gxm_XmIsBulletinBoard_w, 1, 0, 0, H_XmIsBulletinBoard); XM_define_procedure(XmScreen?, gxm_XmIsScreen_w, 1, 0, 0, H_XmIsScreen); XM_define_procedure(XmDialogShell?, gxm_XmIsDialogShell_w, 1, 0, 0, H_XmIsDialogShell); XM_define_procedure(XmDisplay?, gxm_XmIsDisplay_w, 1, 0, 0, H_XmIsDisplay); XM_define_procedure(XmSelectionBox?, gxm_XmIsSelectionBox_w, 1, 0, 0, H_XmIsSelectionBox); XM_define_procedure(XmDragContext?, gxm_XmIsDragContext_w, 1, 0, 0, H_XmIsDragContext); XM_define_procedure(XmDragIconObjectClass?, gxm_XmIsDragIconObjectClass_w, 1, 0, 0, H_XmIsDragIconObjectClass); XM_define_procedure(XmSeparator?, gxm_XmIsSeparator_w, 1, 0, 0, H_XmIsSeparator); XM_define_procedure(XmDropSiteManager?, gxm_XmIsDropSiteManager_w, 1, 0, 0, H_XmIsDropSiteManager); XM_define_procedure(XmDropTransfer?, gxm_XmIsDropTransfer_w, 1, 0, 0, H_XmIsDropTransfer); XM_define_procedure(XmVendorShell?, gxm_XmIsVendorShell_w, 1, 0, 0, H_XmIsVendorShell); XM_define_procedure(XmMainWindow?, gxm_XmIsMainWindow_w, 1, 0, 0, H_XmIsMainWindow); XM_define_procedure(XmMessageBox?, gxm_XmIsMessageBox_w, 1, 0, 0, H_XmIsMessageBox); XM_define_procedure(XmManager?, gxm_XmIsManager_w, 1, 0, 0, H_XmIsManager); XM_define_procedure(XmMenuShell?, gxm_XmIsMenuShell_w, 1, 0, 0, H_XmIsMenuShell); XM_define_procedure(XmLabelGadget?, gxm_XmIsLabelGadget_w, 1, 0, 0, H_XmIsLabelGadget); XM_define_procedure(XmPushButtonGadget?, gxm_XmIsPushButtonGadget_w, 1, 0, 0, H_XmIsPushButtonGadget); XM_define_procedure(XmSeparatorGadget?, gxm_XmIsSeparatorGadget_w, 1, 0, 0, H_XmIsSeparatorGadget); XM_define_procedure(XmArrowButtonGadget?, gxm_XmIsArrowButtonGadget_w, 1, 0, 0, H_XmIsArrowButtonGadget); XM_define_procedure(XmCascadeButtonGadget?, gxm_XmIsCascadeButtonGadget_w, 1, 0, 0, H_XmIsCascadeButtonGadget); XM_define_procedure(XmToggleButtonGadget?, gxm_XmIsToggleButtonGadget_w, 1, 0, 0, H_XmIsToggleButtonGadget); XM_define_procedure(XmDrawnButton?, gxm_XmIsDrawnButton_w, 1, 0, 0, H_XmIsDrawnButton); XM_define_procedure(XmPrimitive?, gxm_XmIsPrimitive_w, 1, 0, 0, H_XmIsPrimitive); XM_define_procedure(XmTextSource?, g_is_XmTextSource_w, 1, 0, 0, PROC_TRUE " if arg is a TextSource"); XM_define_procedure(XpmAttributes?, g_is_XpmAttributes_w, 1, 0, 0, PROC_TRUE " if arg is a XpmAttributes"); XM_define_procedure(XpmImage?, g_is_XpmImage_w, 1, 0, 0, PROC_TRUE " if arg is a XpmImage"); XM_define_procedure(XpmColorSymbol?, g_is_XpmColorSymbol_w, 1, 0, 0, PROC_TRUE " if arg is a XpmColorSymbol"); #if HAVE_SCHEME Xen_define_safe_procedure("->strings", c_to_xen_strings_w, 2, 0, 0, H_to_strings); Xen_define_safe_procedure("->ints", c_to_xen_ints_w, 2, 0, 0, H_to_ints); Xen_define_safe_procedure("->Atoms", c_to_xen_atoms_w, 2, 0, 0, H_to_Atoms); Xen_define_safe_procedure("->XRectangles", c_to_xen_xrectangles_w, 2, 0, 0, H_to_XRectangles); #endif #if WITH_EDITRES XM_define_procedure(_XEditResCheckMessages, gxm_XEditResCheckMessages_w, 4, 0, 0, NULL); #endif #if HAVE_XSHAPEQUERYEXTENSION XM_define_procedure(XShapeQueryExtension, gxm_XShapeQueryExtension_w, 1, 0, 0, H_XShapeQueryExtension); XM_define_procedure(XShapeQueryVersion, gxm_XShapeQueryVersion_w, 1, 0, 0, H_XShapeQueryVersion); XM_define_procedure(XShapeQueryExtents, gxm_XShapeQueryExtents_w, 2, 0, 0, H_XShapeQueryExtents); XM_define_procedure(XShapeGetRectangles, gxm_XShapeGetRectangles_w, 3, 0, 0, H_XShapeGetRectangles); XM_define_procedure(XShapeOffsetShape, gxm_XShapeOffsetShape_w, 5, 0, 0, H_XShapeOffsetShape); XM_define_procedure(XShapeCombineRegion, gxm_XShapeCombineRegion_w, 7, 0, 0, H_XShapeCombineRegion); XM_define_procedure(XShapeCombineMask, gxm_XShapeCombineMask_w, 7, 0, 0, H_XShapeCombineMask); XM_define_procedure(XShapeCombineShape, gxm_XShapeCombineShape_w, 8, 0, 0, H_XShapeCombineShape); XM_define_procedure(XShapeCombineRectangles, gxm_XShapeCombineRectangles_w, 9, 0, 0, H_XShapeCombineRectangles); #endif } static void define_structs(void) { #define XM_define_accessor(Name, Value, SetName, SetValue, A1, A2, A3, A4) \ Xen_define_dilambda(XM_FIELD_PREFIX #Name XM_POSTFIX, Value, #Name " field accessor", XM_FIELD_PREFIX #SetName XM_POSTFIX, SetValue, A1, A2, A3, A4) #define XM_define_reader(Name, Value, A1, A2, A3) Xen_define_safe_procedure(XM_FIELD_PREFIX #Name XM_POSTFIX, Value, A1, A2, A3, #Name " field reader") XM_define_accessor(pixel, gxm_pixel_w, set_pixel, gxm_set_pixel_w, 1, 0, 2, 0); XM_define_accessor(red, gxm_red_w, set_red, gxm_set_red_w, 1, 0, 2, 0); XM_define_accessor(green, gxm_green_w, set_green, gxm_set_green_w, 1, 0, 2, 0); XM_define_accessor(blue, gxm_blue_w, set_blue, gxm_set_blue_w, 1, 0, 2, 0); XM_define_accessor(flags, gxm_flags_w, set_flags, gxm_set_flags_w, 1, 0, 2, 0); XM_define_accessor(pad, gxm_pad_w, set_pad, gxm_set_pad_w, 1, 0, 2, 0); XM_define_procedure(XColor, gxm_XColor_w, 0, 6, 0, H_XColor); XM_define_accessor(x, gxm_x_w, set_x, gxm_set_x_w, 1, 0, 2, 0); XM_define_accessor(y, gxm_y_w, set_y, gxm_set_y_w, 1, 0, 2, 0); XM_define_accessor(width, gxm_width_w, set_width, gxm_set_width_w, 1, 0, 2, 0); XM_define_accessor(height, gxm_height_w, set_height, gxm_set_height_w, 1, 0, 2, 0); XM_define_accessor(angle1, gxm_angle1_w, set_angle1, gxm_set_angle1_w, 1, 0, 2, 0); XM_define_accessor(angle2, gxm_angle2_w, set_angle2, gxm_set_angle2_w, 1, 0, 2, 0); XM_define_procedure(XArc, gxm_XArc_w, 6, 0, 0, H_XArc); XM_define_procedure(XWindowChanges, gxm_XWindowChanges_w, 7, 0, 0, H_XWindowChanges); XM_define_procedure(XSetWindowAttributes, gxm_XSetWindowAttributes_w, 0, 0, 1, H_XSetWindowAttributes); XM_define_procedure(XPoint, gxm_XPoint_w, 2, 0, 0, H_XPoint); XM_define_accessor(x1, gxm_x1_w, set_x1, gxm_set_x1_w, 1, 0, 2, 0); XM_define_accessor(y1, gxm_y1_w, set_y1, gxm_set_y1_w, 1, 0, 2, 0); XM_define_accessor(x2, gxm_x2_w, set_x2, gxm_set_x2_w, 1, 0, 2, 0); XM_define_accessor(y2, gxm_y2_w, set_y2, gxm_set_y2_w, 1, 0, 2, 0); XM_define_procedure(XSegment, gxm_XSegment_w, 4, 0, 0, H_XSegment); XM_define_procedure(XRectangle, gxm_XRectangle_w, 4, 0, 0, H_XRectangle); XM_define_accessor(dashes, gxm_dashes_w, set_dashes, gxm_set_dashes_w, 1, 0, 2, 0); XM_define_accessor(dash_offset, gxm_dash_offset_w, set_dash_offset, gxm_set_dash_offset_w, 1, 0, 2, 0); XM_define_accessor(clip_mask, gxm_clip_mask_w, set_clip_mask, gxm_set_clip_mask_w, 1, 0, 2, 0); XM_define_accessor(clip_y_origin, gxm_clip_y_origin_w, set_clip_y_origin, gxm_set_clip_y_origin_w, 1, 0, 2, 0); XM_define_accessor(clip_x_origin, gxm_clip_x_origin_w, set_clip_x_origin, gxm_set_clip_x_origin_w, 1, 0, 2, 0); XM_define_accessor(graphics_exposures, gxm_graphics_exposures_w, set_graphics_exposures, gxm_set_graphics_exposures_w, 1, 0, 2, 0); XM_define_accessor(subwindow_mode, gxm_subwindow_mode_w, set_subwindow_mode, gxm_set_subwindow_mode_w, 1, 0, 2, 0); XM_define_accessor(font, gxm_font_w, set_font, gxm_set_font_w, 1, 0, 2, 0); XM_define_accessor(ts_y_origin, gxm_ts_y_origin_w, set_ts_y_origin, gxm_set_ts_y_origin_w, 1, 0, 2, 0); XM_define_accessor(ts_x_origin, gxm_ts_x_origin_w, set_ts_x_origin, gxm_set_ts_x_origin_w, 1, 0, 2, 0); XM_define_accessor(stipple, gxm_stipple_w, set_stipple, gxm_set_stipple_w, 1, 0, 2, 0); XM_define_accessor(tile, gxm_tile_w, set_tile, gxm_set_tile_w, 1, 0, 2, 0); XM_define_accessor(arc_mode, gxm_arc_mode_w, set_arc_mode, gxm_set_arc_mode_w, 1, 0, 2, 0); XM_define_accessor(fill_rule, gxm_fill_rule_w, set_fill_rule, gxm_set_fill_rule_w, 1, 0, 2, 0); XM_define_accessor(fill_style, gxm_fill_style_w, set_fill_style, gxm_set_fill_style_w, 1, 0, 2, 0); XM_define_accessor(join_style, gxm_join_style_w, set_join_style, gxm_set_join_style_w, 1, 0, 2, 0); XM_define_accessor(cap_style, gxm_cap_style_w, set_cap_style, gxm_set_cap_style_w, 1, 0, 2, 0); XM_define_accessor(line_style, gxm_line_style_w, set_line_style, gxm_set_line_style_w, 1, 0, 2, 0); XM_define_accessor(line_width, gxm_line_width_w, set_line_width, gxm_set_line_width_w, 1, 0, 2, 0); XM_define_accessor(background, gxm_background_w, set_background, gxm_set_background_w, 1, 0, 2, 0); XM_define_accessor(foreground, gxm_foreground_w, set_foreground, gxm_set_foreground_w, 1, 0, 2, 0); XM_define_accessor(plane_mask, gxm_plane_mask_w, set_plane_mask, gxm_set_plane_mask_w, 1, 0, 2, 0); XM_define_accessor(function, gxm_function_w, set_function, gxm_set_function_w, 1, 0, 2, 0); XM_define_accessor(delta, gxm_delta_w, set_delta, gxm_set_delta_w, 1, 0, 2, 0); XM_define_accessor(nchars, gxm_nchars_w, set_nchars, gxm_set_nchars_w, 1, 0, 2, 0); XM_define_accessor(chars, gxm_chars_w, set_chars, gxm_set_chars_w, 1, 0, 2, 0); XM_define_procedure(XTextItem, gxm_XTextItem_w, 4, 0, 0, H_XTextItem); XM_define_accessor(name, gxm_name_w, set_name, gxm_set_name_w, 1, 0, 2, 0); XM_define_accessor(depth, gxm_depth_w, set_depth, gxm_set_depth_w, 1, 0, 2, 0); XM_define_accessor(visual, gxm_visual_w, set_visual, gxm_set_visual_w, 1, 0, 2, 0); XM_define_reader(mwidth, gxm_mwidth_w, 1, 0, 0); XM_define_reader(mheight, gxm_mheight_w, 1, 0, 0); XM_define_reader(ndepths, gxm_ndepths_w, 1, 0, 0); XM_define_reader(depths, gxm_depths_w, 1, 0, 0); XM_define_reader(root_depth, gxm_root_depth_w, 1, 0, 0); XM_define_reader(root_visual, gxm_root_visual_w, 1, 0, 0); XM_define_reader(default_gc, gxm_default_gc_w, 1, 0, 0); XM_define_reader(cmap, gxm_cmap_w, 1, 0, 0); XM_define_reader(white_pixel, gxm_white_pixel_w, 1, 0, 0); XM_define_reader(black_pixel, gxm_black_pixel_w, 1, 0, 0); XM_define_reader(max_maps, gxm_max_maps_w, 1, 0, 0); XM_define_reader(min_maps, gxm_min_maps_w, 1, 0, 0); XM_define_accessor(backing_store, gxm_backing_store_w, set_backing_store, gxm_set_backing_store_w, 1, 0, 2, 0); XM_define_reader(save_unders, gxm_save_unders_w, 1, 0, 0); XM_define_reader(root_input_mask, gxm_root_input_mask_w, 1, 0, 0); XM_define_reader(lbearing, gxm_lbearing_w, 1, 0, 0); XM_define_reader(rbearing, gxm_rbearing_w, 1, 0, 0); XM_define_reader(ascent, gxm_ascent_w, 1, 0, 0); XM_define_reader(descent, gxm_descent_w, 1, 0, 0); XM_define_reader(attributes, gxm_attributes_w, 1, 0, 0); XM_define_reader(card32, gxm_card32_w, 1, 0, 0); XM_define_reader(fid, gxm_fid_w, 1, 0, 0); XM_define_reader(properties, gxm_properties_w, 1, 0, 0); XM_define_reader(min_bounds, gxm_min_bounds_w, 1, 0, 0); XM_define_reader(max_bounds, gxm_max_bounds_w, 1, 0, 0); XM_define_reader(per_char, gxm_per_char_w, 1, 0, 0); XM_define_accessor(input, gxm_input_w, set_input, gxm_set_input_w, 1, 0, 2, 0); XM_define_accessor(initial_state, gxm_initial_state_w, set_initial_state, gxm_set_initial_state_w, 1, 0, 2, 0); XM_define_reader(icon_pixmap, gxm_icon_pixmap_w, 1, 0, 0); XM_define_reader(icon_window, gxm_icon_window_w, 1, 0, 0); XM_define_reader(icon_x, gxm_icon_x_w, 1, 0, 0); XM_define_reader(icon_y, gxm_icon_y_w, 1, 0, 0); XM_define_reader(icon_mask, gxm_icon_mask_w, 1, 0, 0); XM_define_reader(window_group, gxm_window_group_w, 1, 0, 0); XM_define_reader(visualid, gxm_visualid_w, 1, 0, 0); XM_define_reader(class, gxm_class_w, 1, 0, 0); XM_define_reader(red_mask, gxm_red_mask_w, 1, 0, 0); XM_define_reader(green_mask, gxm_green_mask_w, 1, 0, 0); XM_define_reader(blue_mask, gxm_blue_mask_w, 1, 0, 0); XM_define_reader(bits_per_rgb, gxm_bits_per_rgb_w, 1, 0, 0); XM_define_reader(colormap_size, gxm_colormap_size_w, 1, 0, 0); XM_define_reader(map_entries, gxm_map_entries_w, 1, 0, 0); XM_define_reader(nvisuals, gxm_nvisuals_w, 1, 0, 0); XM_define_reader(visuals, gxm_visuals_w, 1, 0, 0); XM_define_reader(bits_per_pixel, gxm_bits_per_pixel_w, 1, 0, 0); XM_define_reader(background_pixmap, gxm_background_pixmap_w, 1, 0, 0); XM_define_accessor(background_pixel, gxm_background_pixel_w, set_background_pixel, gxm_set_background_pixel_w, 1, 0, 2, 0); XM_define_reader(border_pixmap, gxm_border_pixmap_w, 1, 0, 0); XM_define_accessor(border_pixel, gxm_border_pixel_w, set_border_pixel, gxm_set_border_pixel_w, 1, 0, 2, 0); XM_define_accessor(bit_gravity, gxm_bit_gravity_w, set_bit_gravity, gxm_set_bit_gravity_w, 1, 0, 2, 0); XM_define_reader(win_gravity, gxm_win_gravity_w, 1, 0, 0); XM_define_reader(backing_planes, gxm_backing_planes_w, 1, 0, 0); XM_define_reader(backing_pixel, gxm_backing_pixel_w, 1, 0, 0); XM_define_accessor(save_under, gxm_save_under_w, set_save_under, gxm_set_save_under_w, 1, 0, 2, 0); XM_define_accessor(event_mask, gxm_event_mask_w, set_event_mask, gxm_set_event_mask_w, 1, 0, 2, 0); XM_define_reader(do_not_propagate_mask, gxm_do_not_propagate_mask_w, 1, 0, 0); XM_define_accessor(cursor, gxm_cursor_w, set_cursor, gxm_set_cursor_w, 1, 0, 2, 0); XM_define_reader(map_installed, gxm_map_installed_w, 1, 0, 0); XM_define_reader(map_state, gxm_map_state_w, 1, 0, 0); XM_define_reader(all_event_masks, gxm_all_event_masks_w, 1, 0, 0); XM_define_reader(your_event_mask, gxm_your_event_mask_w, 1, 0, 0); XM_define_reader(screen, gxm_screen_w, 1, 0, 0); XM_define_reader(xoffset, gxm_xoffset_w, 1, 0, 0); XM_define_reader(byte_order, gxm_byte_order_w, 1, 0, 0); XM_define_reader(bitmap_unit, gxm_bitmap_unit_w, 1, 0, 0); XM_define_reader(bitmap_bit_order, gxm_bitmap_bit_order_w, 1, 0, 0); XM_define_reader(bitmap_pad, gxm_bitmap_pad_w, 1, 0, 0); XM_define_reader(bytes_per_line, gxm_bytes_per_line_w, 1, 0, 0); XM_define_reader(obdata, gxm_obdata_w, 1, 0, 0); XM_define_reader(sibling, gxm_sibling_w, 1, 0, 0); XM_define_reader(stack_mode, gxm_stack_mode_w, 1, 0, 0); XM_define_reader(red_max, gxm_red_max_w, 1, 0, 0); XM_define_reader(red_mult, gxm_red_mult_w, 1, 0, 0); XM_define_reader(green_max, gxm_green_max_w, 1, 0, 0); XM_define_reader(green_mult, gxm_green_mult_w, 1, 0, 0); XM_define_reader(blue_max, gxm_blue_max_w, 1, 0, 0); XM_define_reader(blue_mult, gxm_blue_mult_w, 1, 0, 0); XM_define_reader(base_pixel, gxm_base_pixel_w, 1, 0, 0); XM_define_reader(killid, gxm_killid_w, 1, 0, 0); XM_define_reader(min_height, gxm_min_height_w, 1, 0, 0); XM_define_reader(max_height, gxm_max_height_w, 1, 0, 0); XM_define_reader(min_width, gxm_min_width_w, 1, 0, 0); XM_define_reader(max_width, gxm_max_width_w, 1, 0, 0); XM_define_reader(height_inc, gxm_height_inc_w, 1, 0, 0); XM_define_reader(width_inc, gxm_width_inc_w, 1, 0, 0); XM_define_reader(page_number, gxm_page_number_w, 1, 0, 0); XM_define_reader(page_widget, gxm_page_widget_w, 1, 0, 0); XM_define_reader(status_area_widget, gxm_status_area_widget_w, 1, 0, 0); XM_define_reader(major_tab_widget, gxm_major_tab_widget_w, 1, 0, 0); XM_define_reader(minor_tab_widget, gxm_minor_tab_widget_w, 1, 0, 0); XM_define_reader(source_data, gxm_source_data_w, 1, 0, 0); XM_define_reader(location_data, gxm_location_data_w, 1, 0, 0); XM_define_reader(parm, gxm_parm_w, 1, 0, 0); XM_define_reader(parm_format, gxm_parm_format_w, 1, 0, 0); XM_define_reader(parm_length, gxm_parm_length_w, 1, 0, 0); XM_define_reader(parm_type, gxm_parm_type_w, 1, 0, 0); XM_define_reader(transfer_id, gxm_transfer_id_w, 1, 0, 0); XM_define_reader(destination_data, gxm_destination_data_w, 1, 0, 0); XM_define_reader(remaining, gxm_remaining_w, 1, 0, 0); XM_define_reader(item_or_text, gxm_item_or_text_w, 1, 0, 0); XM_define_reader(auto_selection_type, gxm_auto_selection_type_w, 1, 0, 0); XM_define_reader(new_outline_state, gxm_new_outline_state_w, 1, 0, 0); XM_define_reader(prev_page_number, gxm_prev_page_number_w, 1, 0, 0); XM_define_reader(prev_page_widget, gxm_prev_page_widget_w, 1, 0, 0); XM_define_reader(rendition, gxm_rendition_w, 1, 0, 0); XM_define_reader(render_table, gxm_render_table_w, 1, 0, 0); XM_define_reader(crossed_boundary, gxm_crossed_boundary_w, 1, 0, 0); XM_define_reader(client_data, gxm_client_data_w, 1, 0, 0); XM_define_reader(status, gxm_status_w, 1, 0, 0); XM_define_reader(font_name, gxm_font_name_w, 1, 0, 0); XM_define_reader(tag, gxm_tag_w, 1, 0, 0); XM_define_reader(traversal_destination, gxm_traversal_destination_w, 1, 0, 0); XM_define_reader(dragProtocolStyle, gxm_dragProtocolStyle_w, 1, 0, 0); XM_define_reader(direction, gxm_direction_w, 1, 0, 0); XM_define_reader(position, gxm_position_w, 1, 0, 0); XM_define_accessor(menuToPost, gxm_menuToPost_w, set_menuToPost, gxm_set_menuToPost_w, 1, 0, 2, 0); XM_define_accessor(postIt, gxm_postIt_w, set_postIt, gxm_set_postIt_w, 1, 0, 2, 0); XM_define_reader(timeStamp, gxm_timeStamp_w, 1, 0, 0); XM_define_accessor(operation, gxm_operation_w, set_operation, gxm_set_operation_w, 1, 0, 2, 0); XM_define_accessor(reason, gxm_reason_w, set_reason, gxm_set_reason_w, 1, 0, 2, 0); XM_define_reader(operations, gxm_operations_w, 1, 0, 0); XM_define_accessor(dropSiteStatus, gxm_dropSiteStatus_w, set_dropSiteStatus, gxm_set_dropSiteStatus_w, 1, 0, 2, 0); XM_define_accessor(set, gxm_set_w, set_set, gxm_set_set_w, 1, 0, 2, 0); XM_define_accessor(click_count, gxm_click_count_w, set_click_count, gxm_set_click_count_w, 1, 0, 2, 0); XM_define_accessor(length, gxm_length_w, set_length, gxm_set_length_w, 1, 0, 2, 0); XM_define_accessor(ptr, gxm_ptr_w, set_ptr, gxm_set_ptr_w, 1, 0, 2, 0); XM_define_reader(dropAction, gxm_dropAction_w, 1, 0, 0); XM_define_reader(iccHandle, gxm_iccHandle_w, 1, 0, 0); XM_define_reader(completionStatus, gxm_completionStatus_w, 1, 0, 0); XM_define_reader(dragContext, gxm_dragContext_w, 1, 0, 0); XM_define_reader(animate, gxm_animate_w, 1, 0, 0); XM_define_reader(widget, gxm_widget_w, 1, 0, 0); XM_define_reader(item_position, gxm_item_position_w, 1, 0, 0); XM_define_reader(callbackstruct, gxm_callbackstruct_w, 1, 0, 0); XM_define_reader(item, gxm_item_w, 1, 0, 0); XM_define_reader(item_length, gxm_item_length_w, 1, 0, 0); XM_define_reader(selected_items, gxm_selected_items_w, 1, 0, 0); XM_define_reader(selected_item_count, gxm_selected_item_count_w, 1, 0, 0); XM_define_reader(selected_item_positions, gxm_selected_item_positions_w, 1, 0, 0); XM_define_reader(selection_type, gxm_selection_type_w, 1, 0, 0); XM_define_reader(mask, gxm_mask_w, 1, 0, 0); XM_define_reader(mask_length, gxm_mask_length_w, 1, 0, 0); XM_define_reader(dir, gxm_dir_w, 1, 0, 0); XM_define_reader(dir_length, gxm_dir_length_w, 1, 0, 0); XM_define_reader(pattern, gxm_pattern_w, 1, 0, 0); XM_define_reader(pattern_length, gxm_pattern_length_w, 1, 0, 0); XM_define_reader(currInsert, gxm_currInsert_w, 1, 0, 0); XM_define_reader(newInsert, gxm_newInsert_w, 1, 0, 0); XM_define_reader(startPos, gxm_startPos_w, 1, 0, 0); XM_define_reader(endPos, gxm_endPos_w, 1, 0, 0); XM_define_reader(text, gxm_text_w, 1, 0, 0); XM_define_accessor(value, gxm_value_w, set_value, gxm_set_value_w, 1, 0, 2, 0); XM_define_accessor(doit, gxm_doit_w, set_doit, gxm_set_doit_w, 1, 0, 2, 0); XM_define_accessor(valuemask, gxm_valuemask_w, set_valuemask, gxm_set_valuemask_w, 1, 0, 2, 0); XM_define_accessor(ncolors, gxm_ncolors_w, set_ncolors, gxm_set_ncolors_w, 1, 0, 2, 0); XM_define_accessor(cpp, gxm_cpp_w, set_cpp, gxm_set_cpp_w, 1, 0, 2, 0); XM_define_procedure(XpmImage, gxm_XpmImage_w, 5, 0, 0, H_XpmImage); XM_define_accessor(numsymbols, gxm_numsymbols_w, set_numsymbols, gxm_set_numsymbols_w, 1, 0, 2, 0); XM_define_accessor(colorsymbols, gxm_colorsymbols_w, set_colorsymbols, gxm_set_colorsymbols_w, 1, 0, 2, 0); XM_define_accessor(npixels, gxm_npixels_w, set_npixels, gxm_set_npixels_w, 1, 0, 2, 0); XM_define_accessor(y_hotspot, gxm_y_hotspot_w, set_y_hotspot, gxm_set_y_hotspot_w, 1, 0, 2, 0); XM_define_accessor(x_hotspot, gxm_x_hotspot_w, set_x_hotspot, gxm_set_x_hotspot_w, 1, 0, 2, 0); XM_define_procedure(XpmColorSymbol, gxm_XpmColorSymbol_w, 3, 0, 0, H_XpmColorSymbol); XM_define_procedure(XpmAttributes, gxm_XpmAttributes_w, 0, 0, 0, H_XpmAttributes); XM_define_accessor(request_code, gxm_request_code_w, set_request_code, gxm_set_request_code_w, 1, 0, 2, 0); XM_define_accessor(error_code, gxm_error_code_w, set_error_code, gxm_set_error_code_w, 1, 0, 2, 0); XM_define_accessor(first_keycode, gxm_first_keycode_w, set_first_keycode, gxm_set_first_keycode_w, 1, 0, 2, 0); XM_define_accessor(request, gxm_request_w, set_request, gxm_set_request_w, 1, 0, 2, 0); XM_define_accessor(resourceid, gxm_resourceid_w, set_resourceid, gxm_set_resourceid_w, 1, 0, 2, 0); XM_define_accessor(format, gxm_format_w, set_format, gxm_set_format_w, 1, 0, 2, 0); XM_define_accessor(data, gxm_data_w, set_data, gxm_set_data_w, 1, 0, 2, 0); XM_define_accessor(message_type, gxm_message_type_w, set_message_type, gxm_set_message_type_w, 1, 0, 2, 0); XM_define_accessor(new, gxm_new_w, set_new, gxm_set_new_w, 1, 0, 2, 0); XM_define_accessor(property, gxm_property_w, set_property, gxm_set_property_w, 1, 0, 2, 0); XM_define_accessor(display, gxm_display_w, set_display, gxm_set_display_w, 1, 0, 2, 0); XM_define_accessor(target, gxm_target_w, set_target, gxm_set_target_w, 1, 0, 2, 0); XM_define_accessor(requestor, gxm_requestor_w, set_requestor, gxm_set_requestor_w, 1, 0, 2, 0); XM_define_accessor(owner, gxm_owner_w, set_owner, gxm_set_owner_w, 1, 0, 2, 0); XM_define_accessor(selection, gxm_selection_w, set_selection, gxm_set_selection_w, 1, 0, 2, 0); XM_define_accessor(atom, gxm_atom_w, set_atom, gxm_set_atom_w, 1, 0, 2, 0); XM_define_accessor(place, gxm_place_w, set_place, gxm_set_place_w, 1, 0, 2, 0); XM_define_accessor(value_mask, gxm_value_mask_w, set_value_mask, gxm_set_value_mask_w, 1, 0, 2, 0); XM_define_accessor(above, gxm_above_w, set_above, gxm_set_above_w, 1, 0, 2, 0); XM_define_accessor(from_configure, gxm_from_configure_w, set_from_configure, gxm_set_from_configure_w, 1, 0, 2, 0); XM_define_accessor(event, gxm_event_w, set_event, gxm_set_event_w, 1, 0, 2, 0); XM_define_accessor(override_redirect, gxm_override_redirect_w, set_override_redirect, gxm_set_override_redirect_w, 1, 0, 2, 0); XM_define_accessor(border_width, gxm_border_width_w, set_border_width, gxm_set_border_width_w, 1, 0, 2, 0); XM_define_accessor(parent, gxm_parent_w, set_parent, gxm_set_parent_w, 1, 0, 2, 0); XM_define_accessor(minor_code, gxm_minor_code_w, set_minor_code, gxm_set_minor_code_w, 1, 0, 2, 0); XM_define_accessor(major_code, gxm_major_code_w, set_major_code, gxm_set_major_code_w, 1, 0, 2, 0); XM_define_accessor(drawable, gxm_drawable_w, set_drawable, gxm_set_drawable_w, 1, 0, 2, 0); XM_define_accessor(count, gxm_count_w, set_count, gxm_set_count_w, 1, 0, 2, 0); XM_define_accessor(key_vector, gxm_key_vector_w, set_key_vector, gxm_set_key_vector_w, 1, 0, 2, 0); XM_define_accessor(focus, gxm_focus_w, set_focus, gxm_set_focus_w, 1, 0, 2, 0); XM_define_accessor(detail, gxm_detail_w, set_detail, gxm_set_detail_w, 1, 0, 2, 0); XM_define_accessor(mode, gxm_mode_w, set_mode, gxm_set_mode_w, 1, 0, 2, 0); XM_define_accessor(is_hint, gxm_is_hint_w, set_is_hint, gxm_set_is_hint_w, 1, 0, 2, 0); XM_define_accessor(button, gxm_button_w, set_button, gxm_set_button_w, 1, 0, 2, 0); XM_define_accessor(same_screen, gxm_same_screen_w, set_same_screen, gxm_set_same_screen_w, 1, 0, 2, 0); XM_define_accessor(keycode, gxm_keycode_w, set_keycode, gxm_set_keycode_w, 1, 0, 2, 0); XM_define_accessor(state, gxm_state_w, set_state, gxm_set_state_w, 1, 0, 2, 0); XM_define_accessor(y_root, gxm_y_root_w, set_y_root, gxm_set_y_root_w, 1, 0, 2, 0); XM_define_accessor(x_root, gxm_x_root_w, set_x_root, gxm_set_x_root_w, 1, 0, 2, 0); XM_define_accessor(root, gxm_root_w, set_root, gxm_set_root_w, 1, 0, 2, 0); XM_define_accessor(time, gxm_time_w, set_time, gxm_set_time_w, 1, 0, 2, 0); XM_define_accessor(subwindow, gxm_subwindow_w, set_subwindow, gxm_set_subwindow_w, 1, 0, 2, 0); XM_define_accessor(window, gxm_window_w, set_window, gxm_set_window_w, 1, 0, 2, 0); XM_define_accessor(send_event, gxm_send_event_w, set_send_event, gxm_set_send_event_w, 1, 0, 2, 0); XM_define_accessor(serial, gxm_serial_w, set_serial, gxm_set_serial_w, 1, 0, 2, 0); XM_define_accessor(type, gxm_type_w, set_type, gxm_set_type_w, 1, 0, 2, 0); XM_define_accessor(colormap, gxm_colormap_w, set_colormap, gxm_set_colormap_w, 1, 0, 2, 0); } /* -------------------------------- string constants -------------------------------- */ /* can't get hcreate in glibc to work so... */ typedef struct { const char *name; xm_resource_t type; } hdata; static int alphabet_compare(const void *a, const void *b) { hdata *d1 = *(hdata **)a; hdata *d2 = *(hdata **)b; return(strcmp(d1->name, d2->name)); } #define XM_HASH_SIZE 750 /* 616 resources predefined */ static hdata **xm_hash = NULL; static int hd_ctr = 0; #define LINKS_SIZE 27 static int hd_links[LINKS_SIZE]; static void hash_resource(const char *name, xm_resource_t type) { xm_hash[hd_ctr] = (hdata *)malloc(sizeof(hdata)); xm_hash[hd_ctr]->name = name; xm_hash[hd_ctr++]->type = type; if (hd_ctr >= XM_HASH_SIZE) fprintf(stderr, "overflowed hash table!"); } static xm_resource_t resource_type(const char *name) { int i, start, end, ind; ind = (int)(name[0]) - 97; /* all the resource names are supposed to start with a lower case alphabetic char */ /* (char->integer #\a): 97 */ /* unfortunately, we have names like 100DPIString in the newer Motif widgets... */ if ((ind < 0) || (ind >= LINKS_SIZE)) { Xen_error(Xen_make_error_type("no-such-resource"), Xen_list_2(C_string_to_Xen_string("no such resource: ~A"), C_string_to_Xen_string(name))); return(XM_NOT_A_RESOURCE); } start = hd_links[ind]; if (start < 0) return(XM_ULONG); end = hd_links[ind + 1]; for (i = start; i < end; i++) if (strcmp(name, xm_hash[i]->name) == 0) return(xm_hash[i]->type); return(XM_ULONG); } static void define_strings(void) { #define define_string(Name) Xen_define(XM_PREFIX #Name XM_POSTFIX, C_string_to_Xen_string(Name)) #define define_resource(Name, Type) \ Xen_define(XM_PREFIX #Name XM_POSTFIX, C_string_to_Xen_string(Name)); \ hash_resource(Name, Type) xm_hash = (hdata **)calloc(XM_HASH_SIZE, sizeof(hdata *)); define_string(XmSTRING_DEFAULT_CHARSET); define_string(XmFONTLIST_DEFAULT_TAG); define_string(XmFONTLIST_DEFAULT_TAG_STRING); /* these define special XmVaCreateSimple... arg possibilities */ define_string(XmVaCASCADEBUTTON); define_string(XmVaCHECKBUTTON); define_string(XmVaDOUBLE_SEPARATOR); define_string(XmVaPUSHBUTTON); define_string(XmVaRADIOBUTTON); define_string(XmVaSEPARATOR); define_string(XmVaSINGLE_SEPARATOR); define_string(XmVaTOGGLEBUTTON); define_string(XmVaTITLE); #if 0 define_string(XtVaNestedList); define_string(XtVaTypedArg); #endif /* XM_CALLBACK is used where the resource type is XtCallbackList */ define_resource(XmNaccelerator, XM_STRING); define_resource(XmNacceleratorText, XM_XMSTRING); define_resource(XmNaccelerators, XM_ULONG); define_resource(XmNactivateCallback, XM_CALLBACK); define_resource(XmNadjustLast, XM_BOOLEAN); define_resource(XmNadjustMargin, XM_BOOLEAN); define_resource(XmNalignment, XM_UCHAR); define_resource(XmNallowOverlap, XM_BOOLEAN); define_resource(XmNallowResize, XM_BOOLEAN); define_resource(XmNallowShellResize, XM_BOOLEAN); define_resource(XmNancestorSensitive, XM_BOOLEAN); define_resource(XmNanimationMask, XM_PIXMAP); define_resource(XmNanimationPixmap, XM_PIXMAP); define_resource(XmNanimationPixmapDepth, XM_INT); define_resource(XmNanimationStyle, XM_UCHAR); define_resource(XmNapplyCallback, XM_CALLBACK); define_resource(XmNapplyLabelString, XM_XMSTRING); define_resource(XmNargc, XM_INT); define_resource(XmNargv, XM_STRING_LIST); define_resource(XmNarmCallback, XM_CALLBACK); define_resource(XmNarmColor, XM_PIXEL); define_resource(XmNarmPixmap, XM_PIXMAP); define_resource(XmNarrowDirection, XM_UCHAR); define_resource(XmNattachment, XM_UCHAR); define_resource(XmNaudibleWarning, XM_UCHAR); define_resource(XmNautoShowCursorPosition, XM_BOOLEAN); define_resource(XmNautoUnmanage, XM_BOOLEAN); define_resource(XmNautomaticSelection, XM_UCHAR); define_resource(XmNbackground, XM_PIXEL); define_resource(XmNbackgroundPixmap, XM_PIXMAP); define_resource(XmNbaseHeight, XM_INT); define_resource(XmNbaseWidth, XM_INT); define_resource(XmNbitmap, XM_PIXMAP); define_resource(XmNblendModel, XM_ULONG); define_resource(XmNblinkRate, XM_INT); /* define_resource(XmNborder, XM_ULONG); */ define_resource(XmNborderColor, XM_PIXEL); define_resource(XmNborderPixmap, XM_PIXMAP); define_resource(XmNborderWidth, XM_DIMENSION); define_resource(XmNbottomAttachment, XM_UCHAR); define_resource(XmNbottomOffset, XM_INT); define_resource(XmNbottomPosition, XM_INT); define_resource(XmNbottomShadowColor, XM_PIXEL); define_resource(XmNbottomShadowPixmap, XM_PIXMAP); define_resource(XmNbottomWidget, XM_WIDGET); define_resource(XmNbrowseSelectionCallback, XM_CALLBACK); define_resource(XmNbuttonAcceleratorText, XM_STRING_TABLE); define_resource(XmNbuttonAccelerators, XM_STRING_TABLE); define_resource(XmNbuttonCount, XM_INT); define_resource(XmNbuttonMnemonicCharSets, XM_CHARSET_TABLE); define_resource(XmNbuttonMnemonics, XM_KEYSYM_TABLE); define_resource(XmNbuttonSet, XM_INT); define_resource(XmNbuttonType, XM_ULONG); define_resource(XmNbuttons, XM_STRING_TABLE); define_resource(XmNcancelButton, XM_WIDGET); define_resource(XmNcancelCallback, XM_CALLBACK); define_resource(XmNcancelLabelString, XM_XMSTRING); define_resource(XmNcascadePixmap, XM_PIXMAP); define_resource(XmNcascadingCallback, XM_CALLBACK); define_resource(XmNchildHorizontalAlignment, XM_UCHAR); define_resource(XmNchildHorizontalSpacing, XM_DIMENSION); define_resource(XmNchildPlacement, XM_UCHAR); define_resource(XmNchildVerticalAlignment, XM_UCHAR); define_resource(XmNchildren, XM_WIDGET_LIST); define_resource(XmNclientData, XM_XTPOINTER); define_resource(XmNclipWindow, XM_WIDGET); define_resource(XmNcolormap, XM_COLORMAP); define_resource(XmNcolumns, XM_SHORT); define_resource(XmNcommand, XM_XMSTRING); define_resource(XmNcommandChangedCallback, XM_CALLBACK); define_resource(XmNcommandEnteredCallback, XM_CALLBACK); define_resource(XmNcommandWindow, XM_WIDGET); define_resource(XmNcommandWindowLocation, XM_UCHAR); define_resource(XmNconvertProc, XM_CONVERT_CALLBACK); define_resource(XmNcreatePopupChildProc, XM_POPUP_CALLBACK); define_resource(XmNcursorBackground, XM_PIXEL); define_resource(XmNcursorForeground, XM_PIXEL); define_resource(XmNcursorPosition, XM_INT); define_resource(XmNcursorPositionVisible, XM_BOOLEAN); define_resource(XmNdarkThreshold, XM_INT); define_resource(XmNdecimalPoints, XM_SHORT); define_resource(XmNdecrementCallback, XM_CALLBACK); define_resource(XmNdefaultActionCallback, XM_CALLBACK); define_resource(XmNdefaultButton, XM_WIDGET); define_resource(XmNdefaultButtonShadowThickness, XM_DIMENSION); define_resource(XmNdefaultButtonType, XM_UCHAR); define_resource(XmNdefaultCopyCursorIcon, XM_WIDGET); define_resource(XmNdefaultInvalidCursorIcon, XM_WIDGET); define_resource(XmNdefaultLinkCursorIcon, XM_WIDGET); define_resource(XmNdefaultMoveCursorIcon, XM_WIDGET); define_resource(XmNdefaultNoneCursorIcon, XM_WIDGET); define_resource(XmNdefaultPosition, XM_BOOLEAN); define_resource(XmNdefaultSourceCursorIcon, XM_WIDGET); define_resource(XmNdefaultValidCursorIcon, XM_WIDGET); define_resource(XmNdeleteResponse, XM_UCHAR); define_resource(XmNdepth, XM_INT); define_resource(XmNdestroyCallback, XM_CALLBACK); define_resource(XmNdialogStyle, XM_UCHAR); define_resource(XmNdialogTitle, XM_XMSTRING); define_resource(XmNdialogType, XM_UCHAR); define_resource(XmNdirListItemCount, XM_INT); define_resource(XmNdirListItems, XM_STRING_TABLE); define_resource(XmNdirListLabelString, XM_XMSTRING); define_resource(XmNdirMask, XM_XMSTRING); define_resource(XmNdirSearchProc, XM_SEARCH_CALLBACK); define_resource(XmNdirSpec, XM_XMSTRING); define_resource(XmNdirectory, XM_XMSTRING); define_resource(XmNdirectoryValid, XM_BOOLEAN); define_resource(XmNdisarmCallback, XM_CALLBACK); define_resource(XmNdoubleClickInterval, XM_INT); define_resource(XmNdragCallback, XM_CALLBACK); /* scale slider etc */ define_resource(XmNdragDropFinishCallback, XM_CALLBACK); define_resource(XmNdragInitiatorProtocolStyle, XM_UCHAR); define_resource(XmNdragMotionCallback, XM_CALLBACK); define_resource(XmNdragOperations, XM_UCHAR); define_resource(XmNdragProc, XM_DRAG_CALLBACK); /* drag and drop, not scale drag */ define_resource(XmNdragReceiverProtocolStyle, XM_UCHAR); define_resource(XmNdropFinishCallback, XM_CALLBACK); define_resource(XmNdropProc, XM_DROP_CALLBACK); define_resource(XmNdropRectangles, XM_RECTANGLE_LIST); define_resource(XmNdropSiteActivity, XM_UCHAR); define_resource(XmNdropSiteEnterCallback, XM_CALLBACK); define_resource(XmNdropSiteLeaveCallback, XM_CALLBACK); define_resource(XmNdropSiteOperations, XM_UCHAR); define_resource(XmNdropSiteType, XM_UCHAR); define_resource(XmNdropStartCallback, XM_CALLBACK); define_resource(XmNdropTransfers, XM_TRANSFER_ENTRY_LIST); define_resource(XmNeditMode, XM_INT); define_resource(XmNeditable, XM_BOOLEAN); define_resource(XmNentryAlignment, XM_UCHAR); define_resource(XmNentryBorder, XM_DIMENSION); define_resource(XmNentryCallback, XM_CALLBACK); define_resource(XmNentryClass, XM_WIDGET_CLASS); define_resource(XmNentryVerticalAlignment, XM_UCHAR); define_resource(XmNexportTargets, XM_ATOM_LIST); define_resource(XmNexposeCallback, XM_CALLBACK); define_resource(XmNextendedSelectionCallback, XM_CALLBACK); define_resource(XmNfileListItemCount, XM_INT); define_resource(XmNfileListItems, XM_STRING_TABLE); define_resource(XmNfileListLabelString, XM_XMSTRING); define_resource(XmNfileSearchProc, XM_SEARCH_CALLBACK); define_resource(XmNfileTypeMask, XM_UCHAR); define_resource(XmNfillOnArm, XM_BOOLEAN); define_resource(XmNfillOnSelect, XM_BOOLEAN); define_resource(XmNfilterLabelString, XM_XMSTRING); define_resource(XmNfocusCallback, XM_CALLBACK); define_resource(XmNfont, XM_XFONTSTRUCT); define_resource(XmNforeground, XM_PIXEL); define_resource(XmNforegroundThreshold, XM_INT); define_resource(XmNfractionBase, XM_INT); define_resource(XmNgainPrimaryCallback, XM_CALLBACK); define_resource(XmNgeometry, XM_STRING); define_resource(XmNheight, XM_DIMENSION); define_resource(XmNheightInc, XM_INT); define_resource(XmNhelpCallback, XM_CALLBACK); define_resource(XmNhelpLabelString, XM_XMSTRING); define_resource(XmNhighlightColor, XM_PIXEL); define_resource(XmNhighlightOnEnter, XM_BOOLEAN); define_resource(XmNhighlightPixmap, XM_PIXMAP); define_resource(XmNhighlightThickness, XM_DIMENSION); define_resource(XmNhistoryItemCount, XM_INT); define_resource(XmNhistoryItems, XM_STRING_TABLE); define_resource(XmNhistoryMaxItems, XM_INT); define_resource(XmNhistoryVisibleItemCount, XM_INT); define_resource(XmNhorizontalFontUnit, XM_INT); define_resource(XmNhorizontalScrollBar, XM_WIDGET); define_resource(XmNhorizontalSpacing, XM_DIMENSION); define_resource(XmNhotX, XM_POSITION); define_resource(XmNhotY, XM_POSITION); define_resource(XmNiconMask, XM_PIXMAP); define_resource(XmNiconName, XM_STRING); define_resource(XmNiconNameEncoding, XM_ATOM); define_resource(XmNiconPixmap, XM_PIXMAP); define_resource(XmNiconWindow, XM_WIDGET); define_resource(XmNiconX, XM_INT); define_resource(XmNiconY, XM_INT); define_resource(XmNiconic, XM_BOOLEAN); define_resource(XmNimportTargets, XM_ATOM_LIST); define_resource(XmNincrement, XM_INT); define_resource(XmNincrementCallback, XM_CALLBACK); define_resource(XmNincremental, XM_BOOLEAN); define_resource(XmNindicatorOn, XM_INT); define_resource(XmNindicatorSize, XM_DIMENSION); define_resource(XmNindicatorType, XM_UCHAR); define_resource(XmNinitialDelay, XM_INT); define_resource(XmNinitialFocus, XM_WIDGET); define_resource(XmNinitialResourcesPersistent, XM_BOOLEAN); define_resource(XmNinitialState, XM_INT); define_resource(XmNinput, XM_BOOLEAN); define_resource(XmNinputCallback, XM_CALLBACK); define_resource(XmNinputMethod, XM_STRING); define_resource(XmNinsertPosition, XM_ORDER_CALLBACK); define_resource(XmNinvalidCursorForeground, XM_PIXEL); define_resource(XmNisAligned, XM_BOOLEAN); define_resource(XmNisHomogeneous, XM_BOOLEAN); define_resource(XmNitemCount, XM_INT); define_resource(XmNitems, XM_STRING_TABLE); define_resource(XmNkeyboardFocusPolicy, XM_UCHAR); define_resource(XmNlabelInsensitivePixmap, XM_PIXMAP); define_resource(XmNlabelPixmap, XM_PIXMAP); define_resource(XmNlabelString, XM_XMSTRING); define_resource(XmNlabelType, XM_UCHAR); define_resource(XmNleftAttachment, XM_UCHAR); define_resource(XmNleftOffset, XM_INT); define_resource(XmNleftPosition, XM_INT); define_resource(XmNleftWidget, XM_WIDGET); define_resource(XmNlightThreshold, XM_INT); define_resource(XmNlistItemCount, XM_INT); define_resource(XmNlistItems, XM_STRING_TABLE); define_resource(XmNlistLabelString, XM_XMSTRING); define_resource(XmNlistMarginHeight, XM_DIMENSION); define_resource(XmNlistMarginWidth, XM_DIMENSION); define_resource(XmNlistSizePolicy, XM_UCHAR); define_resource(XmNlistSpacing, XM_DIMENSION); define_resource(XmNlistUpdated, XM_BOOLEAN); define_resource(XmNlistVisibleItemCount, XM_INT); define_resource(XmNlosePrimaryCallback, XM_CALLBACK); define_resource(XmNlosingFocusCallback, XM_CALLBACK); define_resource(XmNmainWindowMarginHeight, XM_DIMENSION); define_resource(XmNmainWindowMarginWidth, XM_DIMENSION); define_resource(XmNmapCallback, XM_CALLBACK); define_resource(XmNmappedWhenManaged, XM_BOOLEAN); define_resource(XmNmappingDelay, XM_INT); define_resource(XmNmargin, XM_DIMENSION); define_resource(XmNmarginBottom, XM_DIMENSION); define_resource(XmNmarginHeight, XM_DIMENSION); define_resource(XmNmarginLeft, XM_DIMENSION); define_resource(XmNmarginRight, XM_DIMENSION); define_resource(XmNmarginTop, XM_DIMENSION); define_resource(XmNmarginWidth, XM_DIMENSION); define_resource(XmNmask, XM_PIXMAP); define_resource(XmNmaxAspectX, XM_INT); define_resource(XmNmaxAspectY, XM_INT); define_resource(XmNmaxHeight, XM_INT); define_resource(XmNmaxLength, XM_INT); define_resource(XmNmaxWidth, XM_INT); define_resource(XmNmaximum, XM_INT); define_resource(XmNmenuAccelerator, XM_STRING); define_resource(XmNmenuBar, XM_WIDGET); define_resource(XmNmenuCursor, XM_STRING); define_resource(XmNmenuHelpWidget, XM_WIDGET); define_resource(XmNmenuHistory, XM_WIDGET); define_resource(XmNmenuPost, XM_STRING); define_resource(XmNmessageAlignment, XM_UCHAR); define_resource(XmNmessageString, XM_XMSTRING); define_resource(XmNmessageWindow, XM_WIDGET); define_resource(XmNminAspectX, XM_INT); define_resource(XmNminAspectY, XM_INT); define_resource(XmNminHeight, XM_INT); define_resource(XmNminWidth, XM_INT); define_resource(XmNminimizeButtons, XM_BOOLEAN); define_resource(XmNminimum, XM_INT); define_resource(XmNmnemonic, XM_KEYSYM); define_resource(XmNmnemonicCharSet, XM_STRING); define_resource(XmNmodifyVerifyCallback, XM_CALLBACK); define_resource(XmNmotionVerifyCallback, XM_CALLBACK); define_resource(XmNmoveOpaque, XM_BOOLEAN); define_resource(XmNmultiClick, XM_UCHAR); define_resource(XmNmultipleSelectionCallback, XM_CALLBACK); define_resource(XmNmustMatch, XM_BOOLEAN); define_resource(XmNmwmDecorations, XM_INT); define_resource(XmNmwmFunctions, XM_INT); define_resource(XmNmwmInputMode, XM_INT); define_resource(XmNmwmMenu, XM_STRING); define_resource(XmNnavigationType, XM_UCHAR); define_resource(XmNnoMatchCallback, XM_CALLBACK); define_resource(XmNnoMatchString, XM_XMSTRING); define_resource(XmNnoResize, XM_BOOLEAN); define_resource(XmNnoneCursorForeground, XM_PIXEL); define_resource(XmNnumChildren, XM_INT); define_resource(XmNnumColumns, XM_SHORT); define_resource(XmNnumDropRectangles, XM_INT); define_resource(XmNnumDropTransfers, XM_INT); define_resource(XmNnumExportTargets, XM_INT); define_resource(XmNnumImportTargets, XM_INT); define_resource(XmNoffsetX, XM_POSITION); define_resource(XmNoffsetY, XM_POSITION); define_resource(XmNokCallback, XM_CALLBACK); define_resource(XmNokLabelString, XM_XMSTRING); define_resource(XmNoperationChangedCallback, XM_CALLBACK); define_resource(XmNoperationCursorIcon, XM_WIDGET); define_resource(XmNoptionLabel, XM_XMSTRING); define_resource(XmNoptionMnemonic, XM_KEYSYM); define_resource(XmNorientation, XM_UCHAR); define_resource(XmNoverrideRedirect, XM_BOOLEAN); define_resource(XmNpacking, XM_UCHAR); define_resource(XmNpageDecrementCallback, XM_CALLBACK); define_resource(XmNpageIncrement, XM_INT); define_resource(XmNpageIncrementCallback, XM_CALLBACK); define_resource(XmNpaneMaximum, XM_DIMENSION); define_resource(XmNpaneMinimum, XM_DIMENSION); define_resource(XmNpattern, XM_STRING_OR_XMSTRING); define_resource(XmNpendingDelete, XM_BOOLEAN); define_resource(XmNpixmap, XM_PIXMAP); define_resource(XmNpopdownCallback, XM_CALLBACK); define_resource(XmNpopupCallback, XM_CALLBACK); define_resource(XmNpopupEnabled, XM_INT); /* docs say boolean, but that is incorrect -- see rowcolumn docs */ define_resource(XmNpositionIndex, XM_SHORT); define_resource(XmNpostFromButton, XM_INT); define_resource(XmNpreeditType, XM_STRING); define_resource(XmNprocessingDirection, XM_UCHAR); define_resource(XmNpromptString, XM_XMSTRING); define_resource(XmNpushButtonEnabled, XM_BOOLEAN); define_resource(XmNqualifySearchDataProc, XM_QUALIFY_CALLBACK); define_resource(XmNradioAlwaysOne, XM_BOOLEAN); define_resource(XmNradioBehavior, XM_BOOLEAN); define_resource(XmNrecomputeSize, XM_BOOLEAN); define_resource(XmNrefigureMode, XM_BOOLEAN); define_resource(XmNrepeatDelay, XM_INT); define_resource(XmNresizable, XM_BOOLEAN); define_resource(XmNresizeCallback, XM_CALLBACK); define_resource(XmNresizeHeight, XM_BOOLEAN); define_resource(XmNresizePolicy, XM_UCHAR); define_resource(XmNresizeWidth, XM_BOOLEAN); define_resource(XmNrightAttachment, XM_UCHAR); define_resource(XmNrightOffset, XM_INT); define_resource(XmNrightPosition, XM_INT); define_resource(XmNrightWidget, XM_WIDGET); define_resource(XmNrowColumnType, XM_UCHAR); define_resource(XmNrows, XM_SHORT); define_resource(XmNrubberPositioning, XM_BOOLEAN); define_resource(XmNsashHeight, XM_DIMENSION); define_resource(XmNsashIndent, XM_POSITION); define_resource(XmNsashShadowThickness, XM_DIMENSION); define_resource(XmNsashWidth, XM_DIMENSION); define_resource(XmNsaveUnder, XM_BOOLEAN); define_resource(XmNscaleHeight, XM_DIMENSION); define_resource(XmNscaleMultiple, XM_INT); define_resource(XmNscaleWidth, XM_DIMENSION); define_resource(XmNscreen, XM_SCREEN); define_resource(XmNscrollBarDisplayPolicy, XM_UCHAR); define_resource(XmNscrollBarPlacement, XM_UCHAR); define_resource(XmNscrollHorizontal, XM_BOOLEAN); define_resource(XmNscrollLeftSide, XM_BOOLEAN); define_resource(XmNscrollTopSide, XM_BOOLEAN); define_resource(XmNscrollVertical, XM_BOOLEAN); define_resource(XmNscrolledWindowMarginHeight, XM_DIMENSION); define_resource(XmNscrolledWindowMarginWidth, XM_DIMENSION); define_resource(XmNscrollingPolicy, XM_UCHAR); define_resource(XmNselectColor, XM_PIXEL); define_resource(XmNselectInsensitivePixmap, XM_PIXMAP); define_resource(XmNselectPixmap, XM_PIXMAP); define_resource(XmNselectThreshold, XM_INT); define_resource(XmNselectedItemCount, XM_INT); define_resource(XmNselectedItems, XM_STRING_TABLE); define_resource(XmNselectionArray, XM_INT_TABLE); define_resource(XmNselectionArrayCount, XM_INT); define_resource(XmNselectionLabelString, XM_XMSTRING); define_resource(XmNselectionPolicy, XM_UCHAR); define_resource(XmNsensitive, XM_BOOLEAN); define_resource(XmNseparatorOn, XM_BOOLEAN); define_resource(XmNseparatorType, XM_UCHAR); define_resource(XmNset, XM_UCHAR); define_resource(XmNshadowThickness, XM_DIMENSION); define_resource(XmNshadowType, XM_UCHAR); define_resource(XmNshowArrows, XM_BOOLEAN); define_resource(XmNshowAsDefault, XM_DIMENSION); define_resource(XmNshowSeparator, XM_BOOLEAN); define_resource(XmNshowValue, XM_BOOLEAN_OR_INT); /* should be int, but that's incompatible with tons of existing code */ define_resource(XmNsimpleCallback, XM_CALLBACK); /* doc p905 calls this an XtCallbackProc (not list), but next pages says it's a list, Motif sources appear to treat it as a proc */ define_resource(XmNsingleSelectionCallback, XM_CALLBACK); define_resource(XmNskipAdjust, XM_BOOLEAN); define_resource(XmNsliderSize, XM_INT); define_resource(XmNsliderVisual, XM_INT); define_resource(XmNslidingMode, XM_INT); define_resource(XmNsource, XM_TEXT_SOURCE); define_resource(XmNsourceCursorIcon, XM_WIDGET); define_resource(XmNsourcePixmapIcon, XM_WIDGET); define_resource(XmNspacing, XM_DIMENSION); define_resource(XmNspotLocation, XM_INT); define_resource(XmNstateCursorIcon, XM_WIDGET); define_resource(XmNsubMenuId, XM_WIDGET); define_resource(XmNsymbolPixmap, XM_PIXMAP); define_resource(XmNtearOffMenuActivateCallback, XM_CALLBACK); define_resource(XmNtearOffMenuDeactivateCallback, XM_CALLBACK); define_resource(XmNtearOffModel, XM_UCHAR); define_resource(XmNtextAccelerators, XM_ULONG); define_resource(XmNtextColumns, XM_SHORT); define_resource(XmNtextString, XM_XMSTRING); define_resource(XmNtextTranslations, XM_CALLBACK); define_resource(XmNtitle, XM_STRING); define_resource(XmNtitleEncoding, XM_ATOM); define_resource(XmNtitleString, XM_XMSTRING); #ifdef XmNtoolTipString define_resource((char *)XmNtoolTipString, XM_XMSTRING); define_resource((char *)XmNtoolTipPostDelay, XM_INT); define_resource((char *)XmNtoolTipPostDuration, XM_INT); define_resource((char *)XmNtoolTipEnable, XM_BOOLEAN); define_resource((char *)XmNanimate, XM_BOOLEAN); #endif define_resource(XmNtoBottomCallback, XM_CALLBACK); define_resource(XmNtoTopCallback, XM_CALLBACK); define_resource(XmNtopAttachment, XM_UCHAR); define_resource(XmNtopCharacter, XM_INT); define_resource(XmNtopItemPosition, XM_INT); define_resource(XmNtopLevelEnterCallback, XM_CALLBACK); define_resource(XmNtopLevelLeaveCallback, XM_CALLBACK); define_resource(XmNtopOffset, XM_INT); define_resource(XmNtopPosition, XM_INT); define_resource(XmNtopShadowColor, XM_PIXEL); define_resource(XmNtopShadowPixmap, XM_PIXMAP); define_resource(XmNtopWidget, XM_WIDGET); define_resource(XmNtransferProc, XM_TRANSFER_CALLBACK); define_resource(XmNtransferStatus, XM_UCHAR); define_resource(XmNtransient, XM_BOOLEAN); define_resource(XmNtransientFor, XM_WIDGET); define_resource(XmNtranslations, XM_CALLBACK); define_resource(XmNtraversalOn, XM_BOOLEAN); define_resource(XmNtraverseObscuredCallback, XM_CALLBACK); define_resource(XmNtroughColor, XM_PIXEL); define_resource(XmNunitType, XM_UCHAR); define_resource(XmNunmapCallback, XM_CALLBACK); define_resource(XmNunpostBehavior, XM_UCHAR); define_resource(XmNuseAsyncGeometry, XM_BOOLEAN); define_resource(XmNuserData, XM_XTPOINTER); define_resource(XmNvalidCursorForeground, XM_PIXEL); define_resource(XmNvalue, XM_STRING_OR_INT); define_resource(XmNvalueChangedCallback, XM_CALLBACK); define_resource(XmNverifyBell, XM_BOOLEAN); define_resource(XmNverticalFontUnit, XM_INT); define_resource(XmNverticalScrollBar, XM_WIDGET); define_resource(XmNverticalSpacing, XM_DIMENSION); define_resource(XmNvisibleItemCount, XM_INT); define_resource(XmNvisibleWhenOff, XM_BOOLEAN); define_resource(XmNvisual, XM_VISUAL); define_resource(XmNvisualPolicy, XM_UCHAR); define_resource(XmNwidth, XM_DIMENSION); define_resource(XmNwidthInc, XM_INT); define_resource(XmNwinGravity, XM_INT); define_resource(XmNwindow, XM_WIDGET); define_resource(XmNwindowGroup, XM_WINDOW); define_resource(XmNwmTimeout, XM_INT); define_resource(XmNwordWrap, XM_BOOLEAN); define_resource(XmNworkWindow, XM_WIDGET); define_resource(XmNx, XM_POSITION); define_resource(XmNy, XM_POSITION); define_resource(XmNarrowLayout, XM_UCHAR); define_resource(XmNarrowOrientation, XM_UCHAR); define_resource(XmNarrowSensitivity, XM_UCHAR); define_resource(XmNarrowSize, XM_INT); define_resource(XmNarrowSpacing, XM_INT); define_resource(XmNautoDragModel, XM_INT); define_resource(XmNbackPageBackground, XM_PIXEL); define_resource(XmNbackPageForeground, XM_PIXEL); define_resource(XmNbackPageNumber, XM_INT); define_resource(XmNbackPagePlacement, XM_UCHAR); define_resource(XmNbackPageSize, XM_DIMENSION); define_resource(XmNbindingPixmap, XM_PIXMAP); define_resource(XmNbindingType, XM_UCHAR); define_resource(XmNbindingWidth, XM_INT); define_resource(XmNbitmapConversionModel, XM_INT); define_resource(XmNbuttonRenderTable, XM_RENDER_TABLE); define_resource(XmNcollapsedStatePixmap, XM_PIXMAP); define_resource(XmNcolorAllocationProc, XM_ALLOC_COLOR_CALLBACK); define_resource(XmNcolorCalculationProc, XM_SCREEN_COLOR_CALLBACK); define_resource(XmNcomboBoxType, XM_UCHAR); define_resource(XmNconvertCallback, XM_CALLBACK); define_resource(XmNcurrentPageNumber, XM_INT); define_resource(XmNdecimal, XM_STRING); define_resource(XmNdefaultArrowSensitivity, XM_UCHAR); define_resource(XmNdefaultButtonEmphasis, XM_INT); define_resource(XmNdefaultVirtualBindings, XM_STRING); define_resource(XmNdestinationCallback, XM_CALLBACK); define_resource(XmNdetail, XM_STRING_TABLE); define_resource(XmNdetailColumnHeading, XM_INT); define_resource(XmNdetailColumnHeadingCount, XM_INT); define_resource(XmNdetailCount, XM_INT); define_resource(XmNdetailOrder, XM_INT_TABLE); define_resource(XmNdetailOrderCount, XM_INT); define_resource(XmNdetailShadowThickness, XM_INT); define_resource(XmNdetailTabList, XM_TAB_LIST); define_resource(XmNdirTextLabelString, XM_XMSTRING); define_resource(XmNdragStartCallback, XM_CALLBACK); define_resource(XmNenableBtn1Transfer, XM_INT); define_resource(XmNenableButtonTab, XM_BOOLEAN); define_resource(XmNenableDragIcon, XM_BOOLEAN); define_resource(XmNenableEtchedInMenu, XM_BOOLEAN); define_resource(XmNenableMultiKeyBindings, XM_BOOLEAN); define_resource(XmNenableThinThickness, XM_BOOLEAN); define_resource(XmNenableToggleColor, XM_BOOLEAN); define_resource(XmNenableToggleVisual, XM_BOOLEAN); define_resource(XmNenableUnselectableDrag, XM_BOOLEAN); define_resource(XmNenableWarp, XM_INT); #if HAVE_XP define_resource(XmNendJobCallback, XM_CALLBACK); #endif define_resource(XmNentryParent, XM_WIDGET); define_resource(XmNentryViewType, XM_UCHAR); define_resource(XmNexpandedStatePixmap, XM_PIXMAP); define_resource(XmNfileFilterStyle, XM_INT); define_resource(XmNfirstPageNumber, XM_INT); define_resource(XmNfontName, XM_STRING); define_resource(XmNfontType, XM_UCHAR); define_resource(XmNframeBackground, XM_PIXEL); define_resource(XmNframeChildType, XM_UCHAR); define_resource(XmNframeShadowThickness, XM_DIMENSION); define_resource(XmNgrabStyle, XM_INT); define_resource(XmNincludeStatus, XM_INT); define_resource(XmNincrementValue, XM_INT); define_resource(XmNindeterminateInsensitivePixmap, XM_PIXMAP); define_resource(XmNindeterminatePixmap, XM_PIXMAP); define_resource(XmNinnerMarginHeight, XM_DIMENSION); define_resource(XmNinnerMarginWidth, XM_DIMENSION); define_resource(XmNinputPolicy, XM_ULONG); define_resource(XmNinsensitiveStippleBitmap, XM_PIXMAP); define_resource(XmNinvokeParseProc, XM_PARSE_CALLBACK); define_resource(XmNlabelRenderTable, XM_RENDER_TABLE); define_resource(XmNlargeCellHeight, XM_DIMENSION); define_resource(XmNlargeCellWidth, XM_DIMENSION); define_resource(XmNlargeIconMask, XM_PIXMAP); define_resource(XmNlargeIconPixmap, XM_PIXMAP); define_resource(XmNlargeIconX, XM_FLOAT); define_resource(XmNlargeIconY, XM_FLOAT); define_resource(XmNlastPageNumber, XM_INT); define_resource(XmNlayoutDirection, XM_UCHAR); define_resource(XmNlayoutType, XM_UCHAR); define_resource(XmNlist, XM_WIDGET); define_resource(XmNloadModel, XM_UCHAR); define_resource(XmNmajorTabSpacing, XM_DIMENSION); define_resource(XmNmatchBehavior, XM_UCHAR); #if HAVE_XP define_resource(XmNmaxX, XM_DIMENSION); define_resource(XmNmaxY, XM_DIMENSION); define_resource(XmNminX, XM_DIMENSION); define_resource(XmNminY, XM_DIMENSION); #endif define_resource(XmNmaximumValue, XM_INT); define_resource(XmNminimumValue, XM_INT); define_resource(XmNminorTabSpacing, XM_DIMENSION); define_resource(XmNmotifVersion, XM_INT); define_resource(XmNnoFontCallback, XM_CALLBACK); define_resource(XmNnoRenditionCallback, XM_CALLBACK); define_resource(XmNnotebookChildType, XM_UCHAR); define_resource(XmNnumValues, XM_INT); define_resource(XmNoutlineButtonPolicy, XM_UCHAR); define_resource(XmNoutlineChangedCallback, XM_CALLBACK); define_resource(XmNoutlineColumnWidth, XM_DIMENSION); define_resource(XmNoutlineIndentation, XM_DIMENSION); define_resource(XmNoutlineLineStyle, XM_UCHAR); define_resource(XmNoutlineState, XM_UCHAR); define_resource(XmNpageChangedCallback, XM_CALLBACK); define_resource(XmNpageNumber, XM_INT); #if HAVE_XP define_resource(XmNpageSetupCallback, XM_CALLBACK); #endif define_resource(XmNpathMode, XM_INT); define_resource(XmNpatternType, XM_UCHAR); #if HAVE_XP define_resource(XmNpdmNotificationCallback, XM_CALLBACK); #endif define_resource(XmNpopupHandlerCallback, XM_CALLBACK); define_resource(XmNposition, XM_INT); define_resource(XmNpositionMode, XM_INT); define_resource(XmNpositionType, XM_UCHAR); define_resource(XmNprimaryOwnership, XM_UCHAR); define_resource(XmNrenderTable, XM_RENDER_TABLE); define_resource(XmNrenditionBackground, XM_PIXEL); define_resource(XmNrenditionForeground, XM_PIXEL); define_resource(XmNscrolledWindowChildType, XM_UCHAR); define_resource(XmNselectedItem, XM_XMSTRING); define_resource(XmNselectedObjectCount, XM_INT); define_resource(XmNselectedObjects, XM_WIDGET_LIST); define_resource(XmNselectedPosition, XM_INT); define_resource(XmNselectedPositionCount, XM_INT); define_resource(XmNselectedPositions, XM_INT_TABLE); define_resource(XmNselectionCallback, XM_CALLBACK); define_resource(XmNselectionMode, XM_UCHAR); define_resource(XmNselectionTechnique, XM_UCHAR); define_resource(XmNsliderMark, XM_INT); define_resource(XmNsmallCellHeight, XM_DIMENSION); define_resource(XmNsmallCellWidth, XM_DIMENSION); define_resource(XmNsmallIconMask, XM_PIXMAP); define_resource(XmNsmallIconPixmap, XM_PIXMAP); define_resource(XmNsmallIconX, XM_FLOAT); define_resource(XmNsmallIconY, XM_FLOAT); define_resource(XmNsnapBackMultiple, XM_SHORT); define_resource(XmNspatialIncludeModel, XM_UCHAR); define_resource(XmNspatialResizeModel, XM_UCHAR); define_resource(XmNspatialSnapModel, XM_UCHAR); define_resource(XmNspatialStyle, XM_UCHAR); define_resource(XmNspinBoxChildType, XM_UCHAR); #if HAVE_XP define_resource(XmNstartJobCallback, XM_CALLBACK); #endif define_resource(XmNstrikethruType, XM_UCHAR); define_resource(XmNsubstitute, XM_XMSTRING); define_resource(XmNtabList, XM_TAB_LIST); define_resource(XmNtag, XM_STRING); define_resource(XmNtearOffTitle, XM_XMSTRING); define_resource(XmNtextField, XM_WIDGET); define_resource(XmNtextRenderTable, XM_RENDER_TABLE); define_resource(XmNtoggleMode, XM_UCHAR); define_resource(XmNunderlineType, XM_UCHAR); define_resource(XmNunselectColor, XM_PIXEL); define_resource(XmNtabValue, XM_FLOAT); define_resource(XmNoffsetModel, XM_INT); define_resource(XmNcallback, XM_CALLBACK); define_resource(XmNwaitForWm, XM_BOOLEAN); define_resource(XmNuseColorObj, XM_BOOLEAN); define_resource(XmNvalues, XM_STRING_TABLE); /* define_resource(XmNverifyPreedit, XM_BOOLEAN); */ define_resource(XmNviewType, XM_UCHAR); define_resource(XmNvisualEmphasis, XM_UCHAR); define_resource(XmNwrap, XM_BOOLEAN); qsort((void *)xm_hash, hd_ctr, sizeof(hdata *), alphabet_compare); { int i; for (i = 0; i < LINKS_SIZE; i++) hd_links[i] = hd_ctr; for (i = 0; i < hd_ctr; i++) { int n; n = (int)(xm_hash[i]->name[0]) - 97; /* (char->integer #\a) */ if (hd_links[n] > i) hd_links[n] = i; } } } #define S_add_resource "add-resource" static Xen g_add_resource(Xen nam, Xen typ) { #define H_add_resource "(" S_add_resource " name type) adds the resource 'name' with the libxm type 'type'. \ The types are defined in xm.c around line 679. To add XmNhiho as an integer: \n\ (define XmNhiho (add-resource \"hiho\" 0))" Xen_check_type(Xen_is_string(nam), nam, 1, S_add_resource, "a string"); Xen_check_type(Xen_is_integer(typ), typ, 2, S_add_resource, "an integer"); hash_resource(Xen_string_to_C_string(nam), (xm_resource_t)Xen_integer_to_C_int(typ)); return(nam); } Xen_wrap_2_args(g_add_resource_w, g_add_resource) /* -------------------------------- integer constants -------------------------------- */ static void define_integers(void) { #define define_integer(Name) Xen_define(XM_PREFIX #Name XM_POSTFIX, C_int_to_Xen_integer(Name)) #define define_ulong(Name) Xen_define(XM_PREFIX #Name XM_POSTFIX, C_ulong_to_Xen_ulong(Name)) define_ulong(AllPlanes); define_integer(XC_num_glyphs); define_integer(XC_X_cursor); define_integer(XC_arrow); define_integer(XC_based_arrow_down); define_integer(XC_based_arrow_up); define_integer(XC_boat); define_integer(XC_bogosity); define_integer(XC_bottom_left_corner); define_integer(XC_bottom_right_corner); define_integer(XC_bottom_side); define_integer(XC_bottom_tee); define_integer(XC_box_spiral); define_integer(XC_center_ptr); define_integer(XC_circle); define_integer(XC_clock); define_integer(XC_coffee_mug); define_integer(XC_cross); define_integer(XC_cross_reverse); define_integer(XC_crosshair); define_integer(XC_diamond_cross); define_integer(XC_dot); define_integer(XC_dotbox); define_integer(XC_double_arrow); define_integer(XC_draft_large); define_integer(XC_draft_small); define_integer(XC_draped_box); define_integer(XC_exchange); define_integer(XC_fleur); define_integer(XC_gobbler); define_integer(XC_gumby); define_integer(XC_hand1); define_integer(XC_hand2); define_integer(XC_heart); define_integer(XC_icon); define_integer(XC_iron_cross); define_integer(XC_left_ptr); define_integer(XC_left_side); define_integer(XC_left_tee); define_integer(XC_leftbutton); define_integer(XC_ll_angle); define_integer(XC_lr_angle); define_integer(XC_man); define_integer(XC_middlebutton); define_integer(XC_mouse); define_integer(XC_pencil); define_integer(XC_pirate); define_integer(XC_plus); define_integer(XC_question_arrow); define_integer(XC_right_ptr); define_integer(XC_right_side); define_integer(XC_right_tee); define_integer(XC_rightbutton); define_integer(XC_rtl_logo); define_integer(XC_sailboat); define_integer(XC_sb_down_arrow); define_integer(XC_sb_h_double_arrow); define_integer(XC_sb_left_arrow); define_integer(XC_sb_right_arrow); define_integer(XC_sb_up_arrow); define_integer(XC_sb_v_double_arrow); define_integer(XC_shuttle); define_integer(XC_sizing); define_integer(XC_spider); define_integer(XC_spraycan); define_integer(XC_star); define_integer(XC_target); define_integer(XC_tcross); define_integer(XC_top_left_arrow); define_integer(XC_top_left_corner); define_integer(XC_top_right_corner); define_integer(XC_top_side); define_integer(XC_top_tee); define_integer(XC_trek); define_integer(XC_ul_angle); define_integer(XC_umbrella); define_integer(XC_ur_angle); define_integer(XC_watch); define_integer(XC_xterm); define_integer(None); define_integer(ParentRelative); define_integer(CopyFromParent); define_integer(PointerWindow); define_integer(InputFocus); define_integer(PointerRoot); define_integer(AnyPropertyType); define_integer(AnyKey); define_integer(AnyButton); define_integer(AllTemporary); define_integer(CurrentTime); define_integer(NoSymbol); define_integer(NoEventMask); define_integer(KeyPressMask); define_integer(KeyReleaseMask); define_integer(ButtonPressMask); define_integer(ButtonReleaseMask); define_integer(EnterWindowMask); define_integer(LeaveWindowMask); define_integer(PointerMotionMask); define_integer(PointerMotionHintMask); define_integer(Button1MotionMask); define_integer(Button2MotionMask); define_integer(Button3MotionMask); define_integer(Button4MotionMask); define_integer(Button5MotionMask); define_integer(ButtonMotionMask); define_integer(KeymapStateMask); define_integer(ExposureMask); define_integer(VisibilityChangeMask); define_integer(StructureNotifyMask); define_integer(ResizeRedirectMask); define_integer(SubstructureNotifyMask); define_integer(SubstructureRedirectMask); define_integer(FocusChangeMask); define_integer(PropertyChangeMask); define_integer(ColormapChangeMask); define_integer(OwnerGrabButtonMask); define_integer(KeyPress); define_integer(KeyRelease); define_integer(ButtonPress); define_integer(ButtonRelease); define_integer(MotionNotify); define_integer(EnterNotify); define_integer(LeaveNotify); define_integer(FocusIn); define_integer(FocusOut); define_integer(KeymapNotify); define_integer(Expose); define_integer(GraphicsExpose); define_integer(NoExpose); define_integer(VisibilityNotify); define_integer(CreateNotify); define_integer(DestroyNotify); define_integer(UnmapNotify); define_integer(MapNotify); define_integer(MapRequest); define_integer(ReparentNotify); define_integer(ConfigureNotify); define_integer(ConfigureRequest); define_integer(GravityNotify); define_integer(ResizeRequest); define_integer(CirculateNotify); define_integer(CirculateRequest); define_integer(PropertyNotify); define_integer(SelectionClear); define_integer(SelectionRequest); define_integer(SelectionNotify); define_integer(ColormapNotify); define_integer(ClientMessage); define_integer(MappingNotify); define_integer(ShiftMask); define_integer(LockMask); define_integer(ControlMask); define_integer(Mod1Mask); define_integer(Mod2Mask); define_integer(Mod3Mask); define_integer(Mod4Mask); define_integer(Mod5Mask); define_integer(ShiftMapIndex); define_integer(LockMapIndex); define_integer(ControlMapIndex); define_integer(Mod1MapIndex); define_integer(Mod2MapIndex); define_integer(Mod3MapIndex); define_integer(Mod4MapIndex); define_integer(Mod5MapIndex); define_integer(Button1Mask); define_integer(Button2Mask); define_integer(Button3Mask); define_integer(Button4Mask); define_integer(Button5Mask); define_integer(AnyModifier); define_integer(Button1); define_integer(Button2); define_integer(Button3); define_integer(Button4); define_integer(Button5); define_integer(NotifyNormal); define_integer(NotifyGrab); define_integer(NotifyUngrab); define_integer(NotifyWhileGrabbed); define_integer(NotifyHint); define_integer(NotifyAncestor); define_integer(NotifyVirtual); define_integer(NotifyInferior); define_integer(NotifyNonlinear); define_integer(NotifyNonlinearVirtual); define_integer(NotifyPointer); define_integer(NotifyPointerRoot); define_integer(NotifyDetailNone); define_integer(VisibilityUnobscured); define_integer(VisibilityPartiallyObscured); define_integer(VisibilityFullyObscured); define_integer(PlaceOnTop); define_integer(PlaceOnBottom); define_integer(FamilyInternet); define_integer(FamilyDECnet); define_integer(FamilyChaos); define_integer(PropertyNewValue); define_integer(PropertyDelete); define_integer(ColormapUninstalled); define_integer(ColormapInstalled); define_integer(GrabModeSync); define_integer(GrabModeAsync); define_integer(GrabSuccess); define_integer(AlreadyGrabbed); define_integer(GrabInvalidTime); define_integer(GrabNotViewable); define_integer(GrabFrozen); define_integer(AsyncPointer); define_integer(SyncPointer); define_integer(ReplayPointer); define_integer(AsyncKeyboard); define_integer(SyncKeyboard); define_integer(ReplayKeyboard); define_integer(AsyncBoth); define_integer(SyncBoth); define_integer(RevertToNone); define_integer(RevertToPointerRoot); define_integer(RevertToParent); define_integer(Success); define_integer(BadRequest); define_integer(BadValue); define_integer(BadWindow); define_integer(BadPixmap); define_integer(BadAtom); define_integer(BadCursor); define_integer(BadFont); define_integer(BadMatch); define_integer(BadDrawable); define_integer(BadAccess); define_integer(BadAlloc); define_integer(BadColor); define_integer(BadGC); define_integer(BadIDChoice); define_integer(BadName); define_integer(BadLength); define_integer(BadImplementation); define_integer(InputOutput); define_integer(InputOnly); define_integer(UnmapGravity); define_integer(NotUseful); define_integer(WhenMapped); define_integer(Always); define_integer(IsUnmapped); define_integer(IsUnviewable); define_integer(IsViewable); define_integer(SetModeInsert); define_integer(SetModeDelete); define_integer(DestroyAll); define_integer(RetainPermanent); define_integer(RetainTemporary); define_integer(CWBackPixmap); define_integer(CWBackPixel); define_integer(CWBorderPixmap); define_integer(CWBorderPixel); define_integer(CWBitGravity); define_integer(CWWinGravity); define_integer(CWBackingStore); define_integer(CWBackingPlanes); define_integer(CWBackingPixel); define_integer(CWOverrideRedirect); define_integer(CWSaveUnder); define_integer(CWEventMask); define_integer(CWDontPropagate); define_integer(CWColormap); define_integer(CWCursor); define_integer(CWX); define_integer(CWY); define_integer(CWWidth); define_integer(CWHeight); define_integer(CWBorderWidth); define_integer(CWSibling); define_integer(CWStackMode); define_integer(ForgetGravity); define_integer(NorthWestGravity); define_integer(NorthGravity); define_integer(NorthEastGravity); define_integer(WestGravity); define_integer(CenterGravity); define_integer(EastGravity); define_integer(SouthWestGravity); define_integer(SouthGravity); define_integer(SouthEastGravity); define_integer(StaticGravity); define_integer(Above); define_integer(Below); define_integer(TopIf); define_integer(BottomIf); define_integer(Opposite); define_integer(RaiseLowest); define_integer(LowerHighest); define_integer(PropModeReplace); define_integer(PropModePrepend); define_integer(PropModeAppend); define_integer(KBKeyClickPercent); define_integer(KBBellPercent); define_integer(KBBellPitch); define_integer(KBBellDuration); define_integer(KBLed); define_integer(KBLedMode); define_integer(KBKey); define_integer(KBAutoRepeatMode); define_integer(AutoRepeatModeOff); define_integer(AutoRepeatModeOn); define_integer(AutoRepeatModeDefault); define_integer(LedModeOff); define_integer(LedModeOn); define_integer(GXclear); define_integer(GXand); define_integer(GXandReverse); define_integer(GXcopy); define_integer(GXandInverted); define_integer(GXnoop); define_integer(GXxor); define_integer(GXor); define_integer(GXnor); define_integer(GXequiv); define_integer(GXinvert); define_integer(GXorReverse); define_integer(GXcopyInverted); define_integer(GXorInverted); define_integer(GXnand); define_integer(GXset); define_integer(LineSolid); define_integer(LineOnOffDash); define_integer(LineDoubleDash); define_integer(CapNotLast); define_integer(CapButt); define_integer(CapRound); define_integer(CapProjecting); define_integer(JoinMiter); define_integer(JoinRound); define_integer(JoinBevel); define_integer(FillSolid); define_integer(FillTiled); define_integer(FillStippled); define_integer(FillOpaqueStippled); define_integer(EvenOddRule); define_integer(WindingRule); define_integer(ClipByChildren); define_integer(IncludeInferiors); define_integer(Unsorted); define_integer(YSorted); define_integer(YXSorted); define_integer(YXBanded); define_integer(CoordModeOrigin); define_integer(CoordModePrevious); define_integer(Complex); define_integer(Nonconvex); define_integer(Convex); define_integer(ArcChord); define_integer(ArcPieSlice); define_integer(GCFunction); define_integer(GCPlaneMask); define_integer(GCForeground); define_integer(GCBackground); define_integer(GCLineWidth); define_integer(GCLineStyle); define_integer(GCCapStyle); define_integer(GCJoinStyle); define_integer(GCFillStyle); define_integer(GCFillRule); define_integer(GCTile); define_integer(GCStipple); define_integer(GCTileStipXOrigin); define_integer(GCTileStipYOrigin); define_integer(GCFont); define_integer(GCSubwindowMode); define_integer(GCGraphicsExposures); define_integer(GCClipXOrigin); define_integer(GCClipYOrigin); define_integer(GCClipMask); define_integer(GCDashOffset); define_integer(GCDashList); define_integer(GCArcMode); define_integer(GCLastBit); define_integer(FontLeftToRight); define_integer(FontRightToLeft); define_integer(FontChange); define_integer(XYBitmap); define_integer(XYPixmap); define_integer(ZPixmap); define_integer(AllocNone); define_integer(AllocAll); define_integer(DoRed); define_integer(DoGreen); define_integer(DoBlue); define_integer(CursorShape); define_integer(TileShape); define_integer(StippleShape); define_integer(MappingSuccess); define_integer(MappingBusy); define_integer(MappingFailed); define_integer(MappingModifier); define_integer(MappingKeyboard); define_integer(MappingPointer); define_integer(DontPreferBlanking); define_integer(PreferBlanking); define_integer(DefaultBlanking); define_integer(DisableScreenSaver); define_integer(DisableScreenInterval); define_integer(DontAllowExposures); define_integer(AllowExposures); define_integer(DefaultExposures); define_integer(ScreenSaverReset); define_integer(ScreenSaverActive); define_integer(StaticGray); define_integer(GrayScale); define_integer(StaticColor); define_integer(PseudoColor); define_integer(TrueColor); define_integer(DirectColor); define_integer(XtInputNoneMask); define_integer(XtInputReadMask); define_integer(XtInputWriteMask); define_integer(XtInputExceptMask); /* XtAllEvents is unsigned long EventMask: #define XtAllEvents ((EventMask) -1L) * which I assume should be positive */ #if 0 define_integer(XtAllEvents); #else define_ulong(XtAllEvents); #endif define_integer(XtIMXEvent); define_integer(XtIMTimer); define_integer(XtIMAlternateInput); define_integer(XtIMSignal); define_integer(XtIMAll); define_integer(XtUnspecifiedPixmap); define_integer(XtUnspecifiedShellInt); define_integer(XtUnspecifiedWindow); define_integer(XtUnspecifiedWindowGroup); define_integer(XT_CONVERT_FAIL); define_integer(XlibSpecificationRelease); define_integer(QueuedAlready); define_integer(QueuedAfterReading); define_integer(QueuedAfterFlush); define_integer(XBufferOverflow); define_integer(XLookupNone); define_integer(XLookupChars); define_integer(XLookupKeySym); define_integer(XLookupBoth); define_integer(XK_VoidSymbol); define_integer(XK_BackSpace); define_integer(XK_Tab); define_integer(XK_Linefeed); define_integer(XK_Clear); define_integer(XK_Return); define_integer(XK_Pause); define_integer(XK_Scroll_Lock); define_integer(XK_Sys_Req); define_integer(XK_Escape); define_integer(XK_Delete); define_integer(XK_Home); define_integer(XK_Left); define_integer(XK_Up); define_integer(XK_Right); define_integer(XK_Down); define_integer(XK_Prior); define_integer(XK_Page_Up); define_integer(XK_Next); define_integer(XK_Page_Down); define_integer(XK_End); define_integer(XK_Begin); define_integer(XK_Select); define_integer(XK_Print); define_integer(XK_Execute); define_integer(XK_Insert); define_integer(XK_Undo); define_integer(XK_Redo); define_integer(XK_Menu); define_integer(XK_Find); define_integer(XK_Cancel); define_integer(XK_Help); define_integer(XK_Break); define_integer(XK_Mode_switch); define_integer(XK_script_switch); define_integer(XK_Num_Lock); define_integer(XK_KP_Space); define_integer(XK_KP_Tab); define_integer(XK_KP_Enter); define_integer(XK_KP_F1); define_integer(XK_KP_F2); define_integer(XK_KP_F3); define_integer(XK_KP_F4); define_integer(XK_KP_Home); define_integer(XK_KP_Left); define_integer(XK_KP_Up); define_integer(XK_KP_Right); define_integer(XK_KP_Down); define_integer(XK_KP_Prior); define_integer(XK_KP_Page_Up); define_integer(XK_KP_Next); define_integer(XK_KP_Page_Down); define_integer(XK_KP_End); define_integer(XK_KP_Begin); define_integer(XK_KP_Insert); define_integer(XK_KP_Delete); define_integer(XK_KP_Equal); define_integer(XK_KP_Multiply); define_integer(XK_KP_Add); define_integer(XK_KP_Separator); define_integer(XK_KP_Subtract); define_integer(XK_KP_Decimal); define_integer(XK_KP_Divide); define_integer(XK_KP_0); define_integer(XK_KP_1); define_integer(XK_KP_2); define_integer(XK_KP_3); define_integer(XK_KP_4); define_integer(XK_KP_5); define_integer(XK_KP_6); define_integer(XK_KP_7); define_integer(XK_KP_8); define_integer(XK_KP_9); define_integer(XK_F1); define_integer(XK_F2); define_integer(XK_F3); define_integer(XK_F4); define_integer(XK_F5); define_integer(XK_F6); define_integer(XK_F7); define_integer(XK_F8); define_integer(XK_F9); define_integer(XK_F10); define_integer(XK_F11); define_integer(XK_L1); define_integer(XK_F12); define_integer(XK_L2); define_integer(XK_F13); define_integer(XK_L3); define_integer(XK_F14); define_integer(XK_L4); define_integer(XK_F15); define_integer(XK_L5); define_integer(XK_F16); define_integer(XK_L6); define_integer(XK_F17); define_integer(XK_L7); define_integer(XK_F18); define_integer(XK_L8); define_integer(XK_F19); define_integer(XK_L9); define_integer(XK_F20); define_integer(XK_L10); define_integer(XK_F21); define_integer(XK_R1); define_integer(XK_F22); define_integer(XK_R2); define_integer(XK_F23); define_integer(XK_R3); define_integer(XK_F24); define_integer(XK_R4); define_integer(XK_F25); define_integer(XK_R5); define_integer(XK_F26); define_integer(XK_R6); define_integer(XK_F27); define_integer(XK_R7); define_integer(XK_F28); define_integer(XK_R8); define_integer(XK_F29); define_integer(XK_R9); define_integer(XK_F30); define_integer(XK_R10); define_integer(XK_F31); define_integer(XK_R11); define_integer(XK_F32); define_integer(XK_R12); define_integer(XK_F33); define_integer(XK_R13); define_integer(XK_F34); define_integer(XK_R14); define_integer(XK_F35); define_integer(XK_R15); define_integer(XK_Shift_L); define_integer(XK_Shift_R); define_integer(XK_Control_L); define_integer(XK_Control_R); define_integer(XK_Caps_Lock); define_integer(XK_Shift_Lock); define_integer(XK_Meta_L); define_integer(XK_Meta_R); define_integer(XK_Alt_L); define_integer(XK_Alt_R); define_integer(XK_Super_L); define_integer(XK_Super_R); define_integer(XK_Hyper_L); define_integer(XK_Hyper_R); define_integer(XK_space); define_integer(XK_exclam); define_integer(XK_quotedbl); define_integer(XK_numbersign); define_integer(XK_dollar); define_integer(XK_percent); define_integer(XK_ampersand); define_integer(XK_apostrophe); define_integer(XK_quoteright); define_integer(XK_parenleft); define_integer(XK_parenright); define_integer(XK_asterisk); define_integer(XK_plus); define_integer(XK_comma); define_integer(XK_minus); define_integer(XK_period); define_integer(XK_slash); define_integer(XK_0); define_integer(XK_1); define_integer(XK_2); define_integer(XK_3); define_integer(XK_4); define_integer(XK_5); define_integer(XK_6); define_integer(XK_7); define_integer(XK_8); define_integer(XK_9); define_integer(XK_colon); define_integer(XK_semicolon); define_integer(XK_less); define_integer(XK_equal); define_integer(XK_greater); define_integer(XK_question); define_integer(XK_at); define_integer(XK_A); define_integer(XK_B); define_integer(XK_C); define_integer(XK_D); define_integer(XK_E); define_integer(XK_F); define_integer(XK_G); define_integer(XK_H); define_integer(XK_I); define_integer(XK_J); define_integer(XK_K); define_integer(XK_L); define_integer(XK_M); define_integer(XK_N); define_integer(XK_O); define_integer(XK_P); define_integer(XK_Q); define_integer(XK_R); define_integer(XK_S); define_integer(XK_T); define_integer(XK_U); define_integer(XK_V); define_integer(XK_W); define_integer(XK_X); define_integer(XK_Y); define_integer(XK_Z); define_integer(XK_bracketleft); define_integer(XK_backslash); define_integer(XK_bracketright); define_integer(XK_asciicircum); define_integer(XK_underscore); define_integer(XK_grave); define_integer(XK_quoteleft); define_integer(XK_a); define_integer(XK_b); define_integer(XK_c); define_integer(XK_d); define_integer(XK_e); define_integer(XK_f); define_integer(XK_g); define_integer(XK_h); define_integer(XK_i); define_integer(XK_j); define_integer(XK_k); define_integer(XK_l); define_integer(XK_m); define_integer(XK_n); define_integer(XK_o); define_integer(XK_p); define_integer(XK_q); define_integer(XK_r); define_integer(XK_s); define_integer(XK_t); define_integer(XK_u); define_integer(XK_v); define_integer(XK_w); define_integer(XK_x); define_integer(XK_y); define_integer(XK_z); define_integer(XK_braceleft); define_integer(XK_bar); define_integer(XK_braceright); define_integer(XK_asciitilde); define_integer(XK_nobreakspace); define_integer(XK_exclamdown); define_integer(XK_cent); define_integer(XK_sterling); define_integer(XK_currency); define_integer(XK_yen); define_integer(XK_brokenbar); define_integer(XK_section); define_integer(XK_diaeresis); define_integer(XK_copyright); define_integer(XK_ordfeminine); define_integer(XK_guillemotleft); define_integer(XK_notsign); define_integer(XK_hyphen); define_integer(XK_registered); define_integer(XK_macron); define_integer(XK_degree); define_integer(XK_plusminus); define_integer(XK_twosuperior); define_integer(XK_threesuperior); define_integer(XK_acute); define_integer(XK_mu); define_integer(XK_paragraph); define_integer(XK_periodcentered); define_integer(XK_cedilla); define_integer(XK_onesuperior); define_integer(XK_masculine); define_integer(XK_guillemotright); define_integer(XK_onequarter); define_integer(XK_onehalf); define_integer(XK_threequarters); define_integer(XK_questiondown); define_integer(XK_Agrave); define_integer(XK_Aacute); define_integer(XK_Acircumflex); define_integer(XK_Atilde); define_integer(XK_Adiaeresis); define_integer(XK_Aring); define_integer(XK_AE); define_integer(XK_Ccedilla); define_integer(XK_Egrave); define_integer(XK_Eacute); define_integer(XK_Ecircumflex); define_integer(XK_Ediaeresis); define_integer(XK_Igrave); define_integer(XK_Iacute); define_integer(XK_Icircumflex); define_integer(XK_Idiaeresis); define_integer(XK_ETH); define_integer(XK_Eth); define_integer(XK_Ntilde); define_integer(XK_Ograve); define_integer(XK_Oacute); define_integer(XK_Ocircumflex); define_integer(XK_Otilde); define_integer(XK_Odiaeresis); define_integer(XK_multiply); define_integer(XK_Ooblique); define_integer(XK_Ugrave); define_integer(XK_Uacute); define_integer(XK_Ucircumflex); define_integer(XK_Udiaeresis); define_integer(XK_Yacute); define_integer(XK_THORN); define_integer(XK_Thorn); define_integer(XK_ssharp); define_integer(XK_agrave); define_integer(XK_aacute); define_integer(XK_acircumflex); define_integer(XK_atilde); define_integer(XK_adiaeresis); define_integer(XK_aring); define_integer(XK_ae); define_integer(XK_ccedilla); define_integer(XK_egrave); define_integer(XK_eacute); define_integer(XK_ecircumflex); define_integer(XK_ediaeresis); define_integer(XK_igrave); define_integer(XK_iacute); define_integer(XK_icircumflex); define_integer(XK_idiaeresis); define_integer(XK_eth); define_integer(XK_ntilde); define_integer(XK_ograve); define_integer(XK_oacute); define_integer(XK_ocircumflex); define_integer(XK_otilde); define_integer(XK_odiaeresis); define_integer(XK_division); define_integer(XK_oslash); define_integer(XK_ugrave); define_integer(XK_uacute); define_integer(XK_ucircumflex); define_integer(XK_udiaeresis); define_integer(XK_yacute); define_integer(XK_thorn); define_integer(XK_ydiaeresis); define_integer(XpmFormat); define_integer(XpmVersion); define_integer(XpmRevision); define_integer(XpmIncludeVersion); define_integer(XpmColorError); define_integer(XpmSuccess); define_integer(XpmOpenFailed); define_integer(XpmFileInvalid); define_integer(XpmNoMemory); define_integer(XpmColorFailed); define_integer(XpmVisual); define_integer(XpmColormap); define_integer(XpmDepth); define_integer(XpmSize); define_integer(XpmHotspot); define_integer(XpmCharsPerPixel); define_integer(XpmColorSymbols); define_integer(XpmRgbFilename); define_integer(XpmInfos); define_integer(XpmReturnInfos); define_integer(XpmReturnPixels); define_integer(XpmExtensions); define_integer(XpmReturnExtensions); define_integer(XpmExactColors); define_integer(XpmCloseness); define_integer(XpmRGBCloseness); define_integer(XpmColorKey); define_integer(XpmColorTable); define_integer(XpmReturnColorTable); #ifdef XpmReturnAllocPixels define_integer(XpmReturnAllocPixels); define_integer(XpmAllocCloseColors); define_integer(XpmBitmapFormat); define_integer(XpmAllocColor); define_integer(XpmFreeColors); define_integer(XpmColorClosure); #endif define_integer(XpmComments); define_integer(XpmReturnComments); define_integer(XpmUndefPixel); define_integer(NoValue); define_integer(XValue); define_integer(YValue); define_integer(WidthValue); define_integer(HeightValue); define_integer(AllValues); define_integer(XNegative); define_integer(YNegative); define_integer(InputHint); define_integer(StateHint); define_integer(IconPixmapHint); define_integer(IconWindowHint); define_integer(IconPositionHint); define_integer(IconMaskHint); define_integer(WindowGroupHint); define_integer(AllHints); define_integer(XUrgencyHint); define_integer(WithdrawnState); define_integer(NormalState); define_integer(IconicState); define_integer(DontCareState); define_integer(ZoomState); define_integer(InactiveState); define_integer(XNoMemory); define_integer(XLocaleNotSupported); define_integer(XConverterNotFound); define_integer(RectangleOut); define_integer(RectangleIn); define_integer(RectanglePart); define_integer(VisualNoMask); define_integer(VisualIDMask); define_integer(VisualScreenMask); define_integer(VisualDepthMask); define_integer(VisualClassMask); define_integer(VisualRedMaskMask); define_integer(VisualGreenMaskMask); define_integer(VisualBlueMaskMask); define_integer(VisualColormapSizeMask); define_integer(VisualBitsPerRGBMask); define_integer(VisualAllMask); define_integer(ReleaseByFreeingColormap); define_integer(BitmapSuccess); define_integer(BitmapOpenFailed); define_integer(BitmapFileInvalid); define_integer(BitmapNoMemory); define_integer(MWM_HINTS_FUNCTIONS); define_integer(MWM_HINTS_DECORATIONS); define_integer(MWM_HINTS_INPUT_MODE); define_integer(MWM_HINTS_STATUS); define_integer(MWM_FUNC_ALL); define_integer(MWM_FUNC_RESIZE); define_integer(MWM_FUNC_MOVE); define_integer(MWM_FUNC_MINIMIZE); define_integer(MWM_FUNC_MAXIMIZE); define_integer(MWM_FUNC_CLOSE); define_integer(MWM_DECOR_ALL); define_integer(MWM_DECOR_BORDER); define_integer(MWM_DECOR_RESIZEH); define_integer(MWM_DECOR_TITLE); define_integer(MWM_DECOR_MENU); define_integer(MWM_DECOR_MINIMIZE); define_integer(MWM_DECOR_MAXIMIZE); #ifdef XmCR_WM_PROTOCOLS define_integer(XmCR_WM_PROTOCOLS); #endif define_integer(MWM_INPUT_MODELESS); define_integer(MWM_INPUT_PRIMARY_APPLICATION_MODAL); define_integer(MWM_INPUT_SYSTEM_MODAL); define_integer(MWM_INPUT_FULL_APPLICATION_MODAL); define_integer(MWM_TEAROFF_WINDOW); define_integer(MWM_INPUT_APPLICATION_MODAL); define_integer(MWM_INFO_STARTUP_STANDARD); define_integer(MWM_INFO_STARTUP_CUSTOM); define_integer(PROP_MOTIF_WM_HINTS_ELEMENTS); define_integer(PROP_MWM_HINTS_ELEMENTS); define_integer(PROP_MOTIF_WM_INFO_ELEMENTS); define_integer(PROP_MWM_INFO_ELEMENTS); define_integer(ClipboardFail); define_integer(ClipboardSuccess); define_integer(ClipboardTruncate); define_integer(ClipboardLocked); define_integer(ClipboardBadFormat); define_integer(ClipboardNoData); define_integer(XmHELP); define_integer(XmDROP_NOOP); define_integer(XmDROP_MOVE); define_integer(XmDROP_COPY); define_integer(XmDROP_LINK); define_integer(XmCR_DROP_SITE_LEAVE_MESSAGE); define_integer(XmCR_DROP_SITE_ENTER_MESSAGE); define_integer(XmCR_DROP_SITE_MOTION_MESSAGE); define_integer(XmCR_DROP_MESSAGE); define_integer(XmNO_DROP_SITE); define_integer(XmINVALID_DROP_SITE); define_integer(XmVALID_DROP_SITE); define_integer(XmDROP_SITE_INVALID); define_integer(XmDROP_SITE_VALID); define_integer(XmTRANSFER_FAILURE); define_integer(XmTRANSFER_SUCCESS); define_integer(XmUNSPECIFIED_ICON_SIZE); define_integer(XmLARGE_ICON_SIZE); define_integer(XmMEDIUM_ICON_SIZE); define_integer(XmSMALL_ICON_SIZE); define_integer(XmTINY_ICON_SIZE); define_integer(XmUNSPECIFIED_POSITION); define_integer(XmINVALID_POSITION); define_integer(XmINDICATOR_3D_BOX); define_integer(XmINDICATOR_FLAT_BOX); define_integer(XmINDICATOR_CHECK_GLYPH); define_integer(XmINDICATOR_CROSS_GLYPH); define_integer(XmINITIAL); define_integer(XmADDITION); define_integer(XmMODIFICATION); define_integer(XmVERSION); define_integer(XmREVISION); define_integer(XmUPDATE_LEVEL); define_integer(XmVersion); define_integer(XmUNSPECIFIED_PIXMAP); define_integer(XmCOPY_FAILED); define_integer(XmCOPY_SUCCEEDED); define_integer(XmCOPY_TRUNCATED); define_integer(XmDIALOG_HISTORY_LIST); define_integer(XmDIALOG_PROMPT_LABEL); define_integer(XmDIALOG_VALUE_TEXT); define_integer(XmDIALOG_COMMAND_TEXT); define_integer(XmDIALOG_FILE_LIST); define_integer(XmDIALOG_FILE_LIST_LABEL); define_integer(XmDIALOG_APPLICATION_MODAL); define_integer(XmFILE_DIRECTORY); define_integer(XmFILE_REGULAR); define_integer(XmFILE_ANY_TYPE); define_integer(XmCHECKBUTTON); define_integer(XtCallbackNoList); define_integer(XtCallbackHasNone); define_integer(XtCallbackHasSome); define_integer(XtGeometryYes); define_integer(XtGeometryNo); define_integer(XtGeometryAlmost); define_integer(XtGeometryDone); define_integer(XtGrabNone); define_integer(XtGrabNonexclusive); define_integer(XtGrabExclusive); define_integer(XtListHead); define_integer(XtListTail); define_integer(XStringStyle); define_integer(XCompoundTextStyle); define_integer(XTextStyle); define_integer(XStdICCTextStyle); define_integer(XmClipboardFail); define_integer(XmClipboardSuccess); define_integer(XmClipboardTruncate); define_integer(XmClipboardLocked); define_integer(XmClipboardBadFormat); define_integer(XmClipboardNoData); define_integer(XmDRAG_NONE); define_integer(XmDRAG_DROP_ONLY); define_integer(XmDRAG_PREFER_PREREGISTER); define_integer(XmDRAG_PREREGISTER); define_integer(XmDRAG_PREFER_DYNAMIC); define_integer(XmDRAG_DYNAMIC); define_integer(XmDRAG_PREFER_RECEIVER); define_integer(XmTOP_LEVEL_ENTER); define_integer(XmTOP_LEVEL_LEAVE); define_integer(XmDRAG_MOTION); define_integer(XmDROP_SITE_ENTER); define_integer(XmDROP_SITE_LEAVE); define_integer(XmDROP_START); define_integer(XmDROP_FINISH); define_integer(XmDRAG_DROP_FINISH); define_integer(XmOPERATION_CHANGED); define_integer(XmDROP); define_integer(XmDROP_HELP); define_integer(XmDROP_CANCEL); define_integer(XmDROP_INTERRUPT); define_integer(XmBLEND_ALL); define_integer(XmBLEND_STATE_SOURCE); define_integer(XmBLEND_JUST_SOURCE); define_integer(XmBLEND_NONE); define_integer(XmDROP_FAILURE); define_integer(XmDROP_SUCCESS); define_integer(XmCR_TOP_LEVEL_ENTER); define_integer(XmCR_TOP_LEVEL_LEAVE); define_integer(XmCR_DRAG_MOTION); define_integer(XmCR_DROP_SITE_ENTER); define_integer(XmCR_DROP_SITE_LEAVE); define_integer(XmCR_DROP_START); define_integer(XmCR_DROP_FINISH); define_integer(XmCR_DRAG_DROP_FINISH); define_integer(XmCR_OPERATION_CHANGED); define_integer(XmATTACH_NORTH_WEST); define_integer(XmATTACH_NORTH); define_integer(XmATTACH_NORTH_EAST); define_integer(XmATTACH_EAST); define_integer(XmATTACH_SOUTH_EAST); define_integer(XmATTACH_SOUTH); define_integer(XmATTACH_SOUTH_WEST); define_integer(XmATTACH_WEST); define_integer(XmATTACH_CENTER); define_integer(XmATTACH_HOT); define_integer(XmDRAG_UNDER_NONE); define_integer(XmDRAG_UNDER_PIXMAP); define_integer(XmDRAG_UNDER_SHADOW_IN); define_integer(XmDRAG_UNDER_SHADOW_OUT); define_integer(XmDRAG_UNDER_HIGHLIGHT); define_integer(XmDROP_SITE_SIMPLE); define_integer(XmDROP_SITE_COMPOSITE); define_integer(XmDROP_SITE_SIMPLE_CLIP_ONLY); define_integer(XmDROP_SITE_COMPOSITE_CLIP_ONLY); define_integer(XmABOVE); define_integer(XmBELOW); define_integer(XmDROP_SITE_ACTIVE); define_integer(XmDROP_SITE_INACTIVE); define_integer(XmFONT_IS_FONT); define_integer(XmFONT_IS_FONTSET); define_integer(XmSTRING_DIRECTION_L_TO_R); define_integer(XmSTRING_DIRECTION_R_TO_L); define_integer(XmSTRING_DIRECTION_DEFAULT); define_integer(XmSTRING_COMPONENT_UNKNOWN); define_integer(XmSTRING_COMPONENT_TEXT); define_integer(XmSTRING_COMPONENT_DIRECTION); define_integer(XmSTRING_COMPONENT_SEPARATOR); define_integer(XmSTRING_COMPONENT_LOCALE_TEXT); define_integer(XmSTRING_COMPONENT_END); define_integer(XmPAGE_FOUND); define_integer(XmPAGE_INVALID); define_integer(XmPAGE_EMPTY); define_integer(XmPAGE_DUPLICATED); define_integer(XmMOVE); define_integer(XmCOPY); define_integer(XmLINK); define_integer(XmOTHER); define_integer(XmDROP_SITE_IGNORE); define_integer(XmTRANSFER_DONE_SUCCEED); define_integer(XmTRANSFER_DONE_FAIL); define_integer(XmTRANSFER_DONE_CONTINUE); define_integer(XmTRANSFER_DONE_DEFAULT); define_integer(XmSELECTION_DEFAULT); define_integer(XmSELECTION_INCREMENTAL); define_integer(XmSELECTION_PERSIST); define_integer(XmSELECTION_SNAPSHOT); define_integer(XmSELECTION_TRANSACT); define_integer(XmCONVERTING_NONE); define_integer(XmCONVERTING_SAME); define_integer(XmCONVERTING_TRANSACT); define_integer(XmCONVERTING_PARTIAL); define_integer(XmCONVERT_DEFAULT); define_integer(XmCONVERT_MORE); define_integer(XmCONVERT_MERGE); define_integer(XmCONVERT_REFUSE); define_integer(XmCONVERT_DONE); define_integer(XmSTRING_DIRECTION_UNSET); define_integer(XmSTRING_COMPONENT_LOCALE); define_integer(XmSTRING_COMPONENT_WIDECHAR_TEXT); define_integer(XmSTRING_COMPONENT_LAYOUT_PUSH); define_integer(XmSTRING_COMPONENT_LAYOUT_POP); define_integer(XmSTRING_COMPONENT_RENDITION_BEGIN); define_integer(XmSTRING_COMPONENT_RENDITION_END); define_integer(XmSTRING_COMPONENT_TAB); define_integer(XmSTRING_COMPONENT_TAG); define_integer(XmCHARSET_TEXT); define_integer(XmMULTIBYTE_TEXT); define_integer(XmWIDECHAR_TEXT); define_integer(XmNO_TEXT); define_integer(XmOUTPUT_ALL); define_integer(XmOUTPUT_BETWEEN); define_integer(XmOUTPUT_BEGINNING); define_integer(XmOUTPUT_END); define_integer(XmOUTPUT_BOTH); define_integer(XmINSERT); define_integer(XmTERMINATE); define_integer(XmINVOKE); define_integer(XmSTYLE_STRING); define_integer(XmSTYLE_COMPOUND_TEXT); define_integer(XmSTYLE_TEXT); define_integer(XmSTYLE_STANDARD_ICC_TEXT); define_integer(XmSTYLE_LOCALE); define_integer(XmSTYLE_COMPOUND_STRING); define_integer(XmABSOLUTE); define_integer(XmRELATIVE); define_integer(XmSKIP); define_integer(XmMERGE_REPLACE); define_integer(XmMERGE_OLD); define_integer(XmMERGE_NEW); define_integer(XmDUPLICATE); define_integer(XmAS_IS); define_integer(XmFORCE_COLOR); /* the next 4 are dependent on (Pixel)(~0) which is unsigned long in X terminology, but we then subtract from it -- * that is, XmHIGHLIGHT_COLOR is: ((Pixel)(~0)) - 2, which I assume is intended to be a positive number */ #if 0 define_integer(XmUNSPECIFIED_PIXEL); define_integer(XmDEFAULT_SELECT_COLOR); define_integer(XmREVERSED_GROUND_COLORS); define_integer(XmHIGHLIGHT_COLOR); #else define_ulong(XmUNSPECIFIED_PIXEL); define_ulong(XmDEFAULT_SELECT_COLOR); define_ulong(XmREVERSED_GROUND_COLORS); define_ulong(XmHIGHLIGHT_COLOR); #endif define_integer(XmUNSPECIFIED_LOAD_MODEL); define_integer(XmLOAD_DEFERRED); define_integer(XmLOAD_IMMEDIATE); define_integer(XmCHANGE_ALL); define_integer(XmCHANGE_NONE); define_integer(XmCHANGE_WIDTH); define_integer(XmCHANGE_HEIGHT); define_integer(XmDYNAMIC_DEFAULT_TAB_GROUP); define_integer(XmPIXELS); define_integer(Xm100TH_MILLIMETERS); define_integer(Xm1000TH_INCHES); define_integer(Xm100TH_POINTS); define_integer(Xm100TH_FONT_UNITS); define_integer(XmDESTROY); define_integer(XmUNMAP); define_integer(XmDO_NOTHING); define_integer(XmEXPLICIT); define_integer(XmPOINTER); define_integer(XmNONE); define_integer(XmTAB_GROUP); define_integer(XmSTICKY_TAB_GROUP); define_integer(XmEXCLUSIVE_TAB_GROUP); define_integer(XmBELL); define_integer(XmNO_ORIENTATION); define_integer(XmVERTICAL); define_integer(XmHORIZONTAL); define_integer(XmWORK_AREA); define_integer(XmMENU_BAR); define_integer(XmMENU_PULLDOWN); define_integer(XmMENU_POPUP); define_integer(XmMENU_OPTION); define_integer(XmNO_PACKING); define_integer(XmPACK_TIGHT); define_integer(XmPACK_COLUMN); define_integer(XmPACK_NONE); define_integer(XmALIGNMENT_CONTENTS_TOP); define_integer(XmALIGNMENT_CONTENTS_BOTTOM); define_integer(XmTEAR_OFF_ENABLED); define_integer(XmTEAR_OFF_DISABLED); define_integer(XmUNPOST); define_integer(XmUNPOST_AND_REPLAY); define_integer(XmLAST_POSITION); define_integer(XmFIRST_POSITION); define_integer(XmINCHES); define_integer(XmCENTIMETERS); define_integer(XmMILLIMETERS); define_integer(XmPOINTS); define_integer(XmFONT_UNITS); define_integer(XmPER_SHELL); define_integer(XmPER_WIDGET); define_integer(XmINHERIT_POLICY); define_integer(XmPOPUP_DISABLED); define_integer(XmPOPUP_KEYBOARD); define_integer(XmPOPUP_AUTOMATIC); define_integer(XmPOPUP_AUTOMATIC_RECURSIVE); define_integer(XmCOMBO_BOX); define_integer(XmDROP_DOWN_COMBO_BOX); define_integer(XmDROP_DOWN_LIST); define_integer(XmQUICK_NAVIGATE); define_integer(XmINVALID_MATCH_BEHAVIOR); define_integer(XmZERO_BASED); define_integer(XmONE_BASED); define_integer(XmALIGNMENT_CHILD_TOP); define_integer(XmALIGNMENT_CHILD_BOTTOM); define_integer(XmONE_OF_MANY_ROUND); define_integer(XmONE_OF_MANY_DIAMOND); define_integer(XmALIGNMENT_BEGINNING); define_integer(XmALIGNMENT_CENTER); define_integer(XmALIGNMENT_END); define_integer(XmALIGNMENT_BASELINE_TOP); define_integer(XmALIGNMENT_BASELINE_BOTTOM); define_integer(XmALIGNMENT_WIDGET_TOP); define_integer(XmALIGNMENT_WIDGET_BOTTOM); #ifdef XmALIGNMENT_UNSPECIFIED define_integer(XmALIGNMENT_UNSPECIFIED); #endif define_integer(XmFRAME_GENERIC_CHILD); define_integer(XmFRAME_WORKAREA_CHILD); define_integer(XmFRAME_TITLE_CHILD); define_integer(XmN_OF_MANY); define_integer(XmONE_OF_MANY); define_integer(XmATTACH_NONE); define_integer(XmATTACH_FORM); define_integer(XmATTACH_OPPOSITE_FORM); define_integer(XmATTACH_WIDGET); define_integer(XmATTACH_OPPOSITE_WIDGET); define_integer(XmATTACH_POSITION); define_integer(XmATTACH_SELF); define_integer(XmRESIZE_NONE); define_integer(XmRESIZE_GROW); define_integer(XmRESIZE_ANY); define_integer(XmCR_NONE); define_integer(XmCR_HELP); define_integer(XmCR_VALUE_CHANGED); define_integer(XmCR_INCREMENT); define_integer(XmCR_DECREMENT); define_integer(XmCR_PAGE_INCREMENT); define_integer(XmCR_PAGE_DECREMENT); define_integer(XmCR_TO_TOP); define_integer(XmCR_TO_BOTTOM); define_integer(XmCR_DRAG); define_integer(XmCR_ACTIVATE); define_integer(XmCR_ARM); define_integer(XmCR_DISARM); define_integer(XmCR_MAP); define_integer(XmCR_UNMAP); define_integer(XmCR_FOCUS); define_integer(XmCR_LOSING_FOCUS); define_integer(XmCR_MODIFYING_TEXT_VALUE); define_integer(XmCR_MOVING_INSERT_CURSOR); define_integer(XmCR_EXECUTE); define_integer(XmCR_SINGLE_SELECT); define_integer(XmCR_MULTIPLE_SELECT); define_integer(XmCR_EXTENDED_SELECT); define_integer(XmCR_BROWSE_SELECT); define_integer(XmCR_DEFAULT_ACTION); define_integer(XmCR_CLIPBOARD_DATA_REQUEST); define_integer(XmCR_CLIPBOARD_DATA_DELETE); define_integer(XmCR_CASCADING); define_integer(XmCR_OK); define_integer(XmCR_CANCEL); define_integer(XmCR_APPLY); define_integer(XmCR_NO_MATCH); define_integer(XmCR_COMMAND_ENTERED); define_integer(XmCR_COMMAND_CHANGED); define_integer(XmCR_EXPOSE); define_integer(XmCR_RESIZE); define_integer(XmCR_INPUT); define_integer(XmCR_GAIN_PRIMARY); define_integer(XmCR_LOSE_PRIMARY); define_integer(XmCR_CREATE); define_integer(XmCR_TEAR_OFF_ACTIVATE); define_integer(XmCR_TEAR_OFF_DEACTIVATE); define_integer(XmCR_OBSCURED_TRAVERSAL); define_integer(XmCR_FOCUS_MOVED); define_integer(XmCR_REPOST); define_integer(XmCR_COLLAPSED); define_integer(XmCR_EXPANDED); define_integer(XmCR_SELECT); define_integer(XmCR_DRAG_START); define_integer(XmCR_NO_FONT); define_integer(XmCR_NO_RENDITION); define_integer(XmCR_POST); define_integer(XmCR_SPIN_NEXT); define_integer(XmCR_SPIN_PRIOR); define_integer(XmCR_SPIN_FIRST); define_integer(XmCR_SPIN_LAST); define_integer(XmCR_PAGE_SCROLLER_INCREMENT); define_integer(XmCR_PAGE_SCROLLER_DECREMENT); define_integer(XmCR_MAJOR_TAB); define_integer(XmCR_MINOR_TAB); define_integer(XmCR_START_JOB); define_integer(XmCR_END_JOB); define_integer(XmCR_PAGE_SETUP); define_integer(XmCR_PDM_NONE); define_integer(XmCR_PDM_UP); define_integer(XmCR_PDM_START_ERROR); define_integer(XmCR_PDM_START_VXAUTH); define_integer(XmCR_PDM_START_PXAUTH); define_integer(XmCR_PDM_OK); define_integer(XmCR_PDM_CANCEL); define_integer(XmCR_PDM_EXIT_ERROR); define_integer(XmCR_PROTOCOLS); define_integer(XmEACH_SIDE); define_integer(XmMAX_SIDE); define_integer(XmMIN_SIDE); define_integer(XmBACKGROUND_COLOR); define_integer(XmFOREGROUND_COLOR); define_integer(XmTROUGH_COLOR); define_integer(XmSHADOWED_BACKGROUND); define_integer(XmTHUMB_MARK); define_integer(XmROUND_MARK); define_integer(XmNEAR_SLIDER); define_integer(XmNEAR_BORDER); define_integer(XmHOR_SCROLLBAR); define_integer(XmVERT_SCROLLBAR); define_integer(XmCOMMAND_WINDOW); define_integer(XmMESSAGE_WINDOW); define_integer(XmSCROLL_HOR); define_integer(XmSCROLL_VERT); define_integer(XmNO_SCROLL); define_integer(XmCLIP_WINDOW); define_integer(XmGENERIC_CHILD); define_integer(XmAUTO_DRAG_ENABLED); define_integer(XmAUTO_DRAG_DISABLED); define_integer(XmENABLE_WARP_ON); define_integer(XmENABLE_WARP_OFF); define_integer(XmOFF); define_integer(XmBUTTON2_ADJUST); define_integer(XmBUTTON2_TRANSFER); define_integer(XmAUTO_UNSET); define_integer(XmAUTO_BEGIN); define_integer(XmAUTO_MOTION); define_integer(XmAUTO_CANCEL); define_integer(XmAUTO_NO_CHANGE); define_integer(XmAUTO_CHANGE); define_integer(XmDRAG_WINDOW); define_integer(XmSLIDER); define_integer(XmTHERMOMETER); define_integer(XmETCHED_LINE); define_integer(XmMULTICLICK_DISCARD); define_integer(XmMULTICLICK_KEEP); define_integer(XmSHADOW_IN); define_integer(XmSHADOW_OUT); define_integer(XmARROW_UP); define_integer(XmARROW_DOWN); define_integer(XmARROW_LEFT); define_integer(XmARROW_RIGHT); define_integer(XmNO_LINE); define_integer(XmSINGLE_LINE); define_integer(XmDOUBLE_LINE); define_integer(XmSINGLE_DASHED_LINE); define_integer(XmDOUBLE_DASHED_LINE); define_integer(XmSHADOW_ETCHED_IN); define_integer(XmSHADOW_ETCHED_OUT); define_integer(XmSHADOW_ETCHED_IN_DASH); define_integer(XmSHADOW_ETCHED_OUT_DASH); define_integer(XmINVALID_SEPARATOR_TYPE); define_integer(XmPIXMAP); define_integer(XmSTRING); define_integer(XmWINDOW); define_integer(XmCURSOR); define_integer(XmMAX_ON_TOP); define_integer(XmMAX_ON_BOTTOM); define_integer(XmMAX_ON_LEFT); define_integer(XmMAX_ON_RIGHT); define_integer(XmSINGLE_SELECT); define_integer(XmMULTIPLE_SELECT); define_integer(XmEXTENDED_SELECT); define_integer(XmBROWSE_SELECT); define_integer(XmSTATIC); define_integer(XmDYNAMIC); define_integer(XmNORMAL_MODE); define_integer(XmADD_MODE); define_integer(XmNO_AUTO_SELECT); define_integer(XmAUTO_SELECT); define_integer(XmSINGLE); define_integer(XmANY_ICON); define_integer(XmAPPEND); define_integer(XmCLOSEST); define_integer(XmFIRST_FIT); define_integer(XmOUTLINE); define_integer(XmSPATIAL); define_integer(XmDETAIL); define_integer(XmOUTLINE_BUTTON_PRESENT); define_integer(XmOUTLINE_BUTTON_ABSENT); define_integer(XmGRID); define_integer(XmCELLS); define_integer(XmOWN_NEVER); define_integer(XmOWN_ALWAYS); define_integer(XmOWN_MULTIPLE); define_integer(XmOWN_POSSIBLE_MULTIPLE); define_integer(XmGROW_MINOR); define_integer(XmGROW_MAJOR); define_integer(XmGROW_BALANCED); define_integer(XmMARQUEE); define_integer(XmMARQUEE_EXTEND_START); define_integer(XmMARQUEE_EXTEND_BOTH); define_integer(XmTOUCH_ONLY); define_integer(XmTOUCH_OVER); define_integer(XmSNAP_TO_GRID); define_integer(XmCENTER); define_integer(XmCOLLAPSED); define_integer(XmEXPANDED); define_integer(XmLARGE_ICON); define_integer(XmSMALL_ICON); define_integer(XmSELECTED); define_integer(XmNOT_SELECTED); define_integer(XmSOLID); define_integer(XmSPIRAL); define_integer(XmPIXMAP_OVERLAP_ONLY); define_integer(XmPAGE); define_integer(XmMAJOR_TAB); define_integer(XmMINOR_TAB); define_integer(XmSTATUS_AREA); define_integer(XmPAGE_SCROLLER); define_integer(XmARROWS_VERTICAL); define_integer(XmARROWS_HORIZONTAL); define_integer(XmARROWS_END); define_integer(XmARROWS_BEGINNING); define_integer(XmARROWS_SPLIT); define_integer(XmARROWS_FLAT_END); define_integer(XmARROWS_FLAT_BEGINNING); define_integer(XmARROWS_INSENSITIVE); define_integer(XmARROWS_INCREMENT_SENSITIVE); define_integer(XmARROWS_DECREMENT_SENSITIVE); define_integer(XmARROWS_SENSITIVE); define_integer(XmARROWS_DEFAULT_SENSITIVITY); define_integer(XmPOSITION_INDEX); define_integer(XmPOSITION_VALUE); define_integer(XmNUMERIC); define_integer(XmVALID_VALUE); define_integer(XmCURRENT_VALUE); define_integer(XmMAXIMUM_VALUE); define_integer(XmMINIMUM_VALUE); define_integer(XmINCREMENT_VALUE); define_integer(XmSELECT_OUT_LINE); define_integer(XmSEE_DETAIL); define_integer(XmVARIABLE); define_integer(XmCONSTANT); define_integer(XmRESIZE_IF_POSSIBLE); define_integer(XmAUTOMATIC); define_integer(XmAPPLICATION_DEFINED); define_integer(XmAS_NEEDED); define_integer(XmCOMMAND_ABOVE_WORKSPACE); define_integer(XmCOMMAND_BELOW_WORKSPACE); define_integer(XmMULTI_LINE_EDIT); define_integer(XmSINGLE_LINE_EDIT); define_integer(XmTEXT_FORWARD); define_integer(XmTEXT_BACKWARD); define_integer(XmSELECT_POSITION); define_integer(XmSELECT_WHITESPACE); define_integer(XmSELECT_WORD); define_integer(XmSELECT_LINE); define_integer(XmSELECT_ALL); define_integer(XmSELECT_PARAGRAPH); define_integer(XmHIGHLIGHT_NORMAL); define_integer(XmHIGHLIGHT_SELECTED); define_integer(XmHIGHLIGHT_SECONDARY_SELECTED); define_integer(XmDIALOG_NONE); define_integer(XmDIALOG_APPLY_BUTTON); define_integer(XmDIALOG_CANCEL_BUTTON); define_integer(XmDIALOG_DEFAULT_BUTTON); define_integer(XmDIALOG_OK_BUTTON); define_integer(XmDIALOG_FILTER_LABEL); define_integer(XmDIALOG_FILTER_TEXT); define_integer(XmDIALOG_HELP_BUTTON); define_integer(XmDIALOG_LIST); define_integer(XmDIALOG_LIST_LABEL); define_integer(XmDIALOG_MESSAGE_LABEL); define_integer(XmDIALOG_SELECTION_LABEL); define_integer(XmDIALOG_SYMBOL_LABEL); define_integer(XmDIALOG_TEXT); define_integer(XmDIALOG_SEPARATOR); define_integer(XmDIALOG_DIR_LIST); define_integer(XmDIALOG_DIR_LIST_LABEL); define_integer(XmDIALOG_MODELESS); define_integer(XmDIALOG_PRIMARY_APPLICATION_MODAL); define_integer(XmDIALOG_FULL_APPLICATION_MODAL); define_integer(XmDIALOG_SYSTEM_MODAL); define_integer(XmPLACE_TOP); define_integer(XmPLACE_ABOVE_SELECTION); define_integer(XmPLACE_BELOW_SELECTION); define_integer(XmDIALOG_WORK_AREA); define_integer(XmDIALOG_PROMPT); define_integer(XmDIALOG_SELECTION); define_integer(XmDIALOG_COMMAND); define_integer(XmDIALOG_FILE_SELECTION); define_integer(XmDIALOG_TEMPLATE); define_integer(XmDIALOG_ERROR); define_integer(XmDIALOG_INFORMATION); define_integer(XmDIALOG_MESSAGE); define_integer(XmDIALOG_QUESTION); define_integer(XmDIALOG_WARNING); define_integer(XmDIALOG_WORKING); define_integer(XmVISIBILITY_UNOBSCURED); define_integer(XmVISIBILITY_PARTIALLY_OBSCURED); define_integer(XmVISIBILITY_FULLY_OBSCURED); define_integer(XmTRAVERSE_CURRENT); define_integer(XmTRAVERSE_NEXT); define_integer(XmTRAVERSE_PREV); define_integer(XmTRAVERSE_HOME); define_integer(XmTRAVERSE_NEXT_TAB_GROUP); define_integer(XmTRAVERSE_PREV_TAB_GROUP); define_integer(XmTRAVERSE_UP); define_integer(XmTRAVERSE_DOWN); define_integer(XmTRAVERSE_LEFT); define_integer(XmTRAVERSE_RIGHT); define_integer(XmPUSHBUTTON); define_integer(XmTOGGLEBUTTON); define_integer(XmRADIOBUTTON); define_integer(XmCASCADEBUTTON); define_integer(XmSEPARATOR); define_integer(XmDOUBLE_SEPARATOR); define_integer(XmTITLE); define_integer(XmBOTTOM_RIGHT); define_integer(XmBOTTOM_LEFT); define_integer(XmTOP_RIGHT); define_integer(XmTOP_LEFT); define_integer(XmTRAVERSE_GLOBALLY_FORWARD); define_integer(XmTRAVERSE_GLOBALLY_BACKWARD); define_integer(XmMATCH_DEPTH); define_integer(XmDYNAMIC_DEPTH); define_integer(XmPDM_NOTIFY_FAIL); define_integer(XmPDM_NOTIFY_SUCCESS); define_integer(XmINDICATOR_NONE); define_integer(XmINDICATOR_FILL); define_integer(XmINDICATOR_BOX); define_integer(XmINDICATOR_CHECK); define_integer(XmINDICATOR_CHECK_BOX); define_integer(XmINDICATOR_CROSS); define_integer(XmINDICATOR_CROSS_BOX); define_integer(XmUNSET); define_integer(XmSET); define_integer(XmINDETERMINATE); define_integer(XmTOGGLE_BOOLEAN); define_integer(XmTOGGLE_INDETERMINATE); define_integer(XmPATH_MODE_FULL); define_integer(XmPATH_MODE_RELATIVE); define_integer(XmFILTER_NONE); define_integer(XmFILTER_HIDDEN_FILES); #if HAVE_XSHAPEQUERYEXTENSION define_integer(ShapeSet); define_integer(ShapeUnion); define_integer(ShapeIntersect); define_integer(ShapeSubtract); define_integer(ShapeInvert); define_integer(ShapeBounding); define_integer(ShapeClip); #endif } /* -------------------------------- pointer constants -------------------------------- */ static void define_pointers(void) { #define define_pointer(Name) Xen_define(XM_PREFIX #Name XM_POSTFIX, C_to_Xen_WidgetClass(Name)) define_pointer(compositeWidgetClass); define_pointer(constraintWidgetClass); define_pointer(coreWidgetClass); define_pointer(widgetClass); define_pointer(objectClass); define_pointer(rectObjClass); define_pointer(shellWidgetClass); define_pointer(overrideShellWidgetClass); define_pointer(wmShellWidgetClass); define_pointer(transientShellWidgetClass); define_pointer(topLevelShellWidgetClass); define_pointer(applicationShellWidgetClass); define_pointer(sessionShellWidgetClass); define_pointer(vendorShellWidgetClass); define_pointer(xmArrowButtonGadgetClass); define_pointer(xmArrowButtonWidgetClass); define_pointer(xmBulletinBoardWidgetClass); define_pointer(xmCascadeButtonGadgetClass); define_pointer(xmCascadeButtonWidgetClass); define_pointer(xmCommandWidgetClass); define_pointer(xmDialogShellWidgetClass); define_pointer(xmDragContextClass); define_pointer(xmDragIconObjectClass); define_pointer(xmDragOverShellWidgetClass); define_pointer(xmDrawingAreaWidgetClass); define_pointer(xmDrawnButtonWidgetClass); define_pointer(xmDropSiteManagerObjectClass); define_pointer(xmDropTransferObjectClass); define_pointer(xmFileSelectionBoxWidgetClass); define_pointer(xmFormWidgetClass); define_pointer(xmFrameWidgetClass); define_pointer(xmGadgetClass); define_pointer(xmLabelGadgetClass); define_pointer(xmLabelWidgetClass); define_pointer(xmListWidgetClass); define_pointer(xmMainWindowWidgetClass); define_pointer(xmManagerWidgetClass); define_pointer(xmMenuShellWidgetClass); define_pointer(xmMessageBoxWidgetClass); define_pointer(xmPanedWindowWidgetClass); define_pointer(xmPrimitiveWidgetClass); define_pointer(xmPushButtonGadgetClass); define_pointer(xmPushButtonWidgetClass); define_pointer(xmRowColumnWidgetClass); define_pointer(xmScaleWidgetClass); define_pointer(xmScrollBarWidgetClass); define_pointer(xmScrolledWindowWidgetClass); define_pointer(xmSelectionBoxWidgetClass); define_pointer(xmSeparatorGadgetClass); define_pointer(xmSeparatorWidgetClass); define_pointer(xmTextFieldWidgetClass); define_pointer(xmTextWidgetClass); define_pointer(xmToggleButtonGadgetClass); define_pointer(xmToggleButtonWidgetClass); define_pointer(xmContainerWidgetClass); define_pointer(xmComboBoxWidgetClass); define_pointer(xmGrabShellWidgetClass); define_pointer(xmNotebookWidgetClass); define_pointer(xmIconGadgetClass); define_pointer(xmSpinBoxWidgetClass); define_pointer(xmSimpleSpinBoxWidgetClass); } /* -------------------------------- predefined Atoms -------------------------------- */ static void define_Atoms(void) { #define define_atom(Name) Xen_define(XM_PREFIX #Name XM_POSTFIX, C_to_Xen_Atom(Name)) define_atom(XA_PRIMARY); define_atom(XA_SECONDARY); define_atom(XA_ARC); define_atom(XA_ATOM); define_atom(XA_BITMAP); define_atom(XA_CARDINAL); define_atom(XA_COLORMAP); define_atom(XA_CURSOR); define_atom(XA_CUT_BUFFER0); define_atom(XA_CUT_BUFFER1); define_atom(XA_CUT_BUFFER2); define_atom(XA_CUT_BUFFER3); define_atom(XA_CUT_BUFFER4); define_atom(XA_CUT_BUFFER5); define_atom(XA_CUT_BUFFER6); define_atom(XA_CUT_BUFFER7); define_atom(XA_DRAWABLE); define_atom(XA_FONT); define_atom(XA_INTEGER); define_atom(XA_PIXMAP); define_atom(XA_POINT); define_atom(XA_RECTANGLE); define_atom(XA_RESOURCE_MANAGER); define_atom(XA_RGB_COLOR_MAP); define_atom(XA_RGB_BEST_MAP); define_atom(XA_RGB_BLUE_MAP); define_atom(XA_RGB_DEFAULT_MAP); define_atom(XA_RGB_GRAY_MAP); define_atom(XA_RGB_GREEN_MAP); define_atom(XA_RGB_RED_MAP); define_atom(XA_STRING); define_atom(XA_VISUALID); define_atom(XA_WINDOW); define_atom(XA_WM_COMMAND); define_atom(XA_WM_HINTS); define_atom(XA_WM_CLIENT_MACHINE); define_atom(XA_WM_ICON_NAME); define_atom(XA_WM_ICON_SIZE); define_atom(XA_WM_NAME); define_atom(XA_WM_NORMAL_HINTS); define_atom(XA_WM_SIZE_HINTS); define_atom(XA_WM_ZOOM_HINTS); define_atom(XA_MIN_SPACE); define_atom(XA_NORM_SPACE); define_atom(XA_MAX_SPACE); define_atom(XA_END_SPACE); define_atom(XA_SUPERSCRIPT_X); define_atom(XA_SUPERSCRIPT_Y); define_atom(XA_SUBSCRIPT_X); define_atom(XA_SUBSCRIPT_Y); define_atom(XA_UNDERLINE_POSITION); define_atom(XA_UNDERLINE_THICKNESS); define_atom(XA_STRIKEOUT_ASCENT); define_atom(XA_STRIKEOUT_DESCENT); define_atom(XA_ITALIC_ANGLE); define_atom(XA_X_HEIGHT); define_atom(XA_QUAD_WIDTH); define_atom(XA_WEIGHT); define_atom(XA_POINT_SIZE); define_atom(XA_RESOLUTION); define_atom(XA_COPYRIGHT); define_atom(XA_NOTICE); define_atom(XA_FONT_NAME); define_atom(XA_FAMILY_NAME); define_atom(XA_FULL_NAME); define_atom(XA_CAP_HEIGHT); define_atom(XA_WM_CLASS); define_atom(XA_WM_TRANSIENT_FOR); } /* -------------------------------- initialization -------------------------------- */ static bool xm_already_inited = false; void Init_libxm(void); void Init_libxm(void) { /* perhaps nicer here to check the features list for 'xm */ if (!xm_already_inited) { xm_XmColorAllocationProc = Xen_false; xm_XmColorCalculationProc = Xen_false; xm_XmColorProc = Xen_false; xm_XmCutPasteProc = Xen_false; xm_XmVoidProc = Xen_false; xm_XtSelectionCallback_Descr = Xen_false; xm_XtConvertSelectionIncr_Descr = Xen_false; xm_protected = Xen_false; xm_gc_table = Xen_false; xm_XPeekIfEventProc = Xen_false; xm_XIOErrorHandler = Xen_false; xm_XErrorHandler = Xen_false; xm_AfterFunction = Xen_false; xm_XtErrorHandler = Xen_false; xm_XtWarningHandler = Xen_false; xm_XtErrorMsgHandler = Xen_false; xm_XtWarningMsgHandler = Xen_false; xm_language_proc = Xen_false; xm_XtCaseProc = Xen_false; xm_XtKeyProc = Xen_false; register_proc = Xen_false; define_xm_obj(); define_makes(); define_strings(); define_Atoms(); define_integers(); define_pointers(); define_procedures(); define_structs(); Xen_define_safe_procedure(S_add_resource, g_add_resource_w, 2, 0, 0, H_add_resource); Xen_provide_feature("xm"); Xen_define("xm-version", C_string_to_Xen_string(XM_DATE)); xm_already_inited = true; } } #else void Init_libxm(void); void Init_libxm(void) { } #endif /* end HAVE_EXTENSION_LANGUAGE */ snd-16.1/snd-gl.scm0000644000076400007640000005513712446652237012251 0ustar bilbil;;; examples of using the GL bindings (provide 'snd-snd-gl.scm) (with-let *gl* ;;; ---------------- gl-info ---------------- (define gl-info ;; taken loosely from glxvisuals.c (let ((documentation "(gl-info) prints out GL-related info")) (lambda () (define (class-of n) (and (number? n) (cond ((= n (*motif* 'StaticGray)) "static-gray") ((= n (*motif* 'GrayScale)) "gray-scale") ((= n (*motif* 'StaticColor)) "static-color") ((= n (*motif* 'PseudoColor)) "pseudo-color") ((= n (*motif* 'TrueColor)) "true-color") ((= n (*motif* 'DirectColor)) "direct-color") (#t "??")))) (let* ((cx (snd-gl-context)) (dpy ((*motif* 'XtDisplay) (cadr (main-widgets)))) (version (glXQueryVersion dpy 0 0))) (if (car version) (let ((visuals ((*motif* 'XGetVisualInfo) dpy 0 (list 'XVisualInfo 0)))) (glXMakeCurrent dpy ((*motif* 'XtWindow) (cadr (main-widgets))) cx) (snd-print (format #f "GL version: ~A.~A, (~A ~A ~A)~%" (cadr version) (caddr version) (glGetString GL_VENDOR) (glGetString GL_RENDERER) (glGetString GL_VERSION))) (snd-print (format #f " with: ~A~A~%" (glXQueryExtensionsString dpy ((*motif* 'XScreenNumberOfScreen) ((*motif* 'DefaultScreenOfDisplay) dpy))) (if (glXIsDirect dpy cx) ", direct rendering support" ""))) (for-each (lambda (visual) (if (= (cadr (glXGetConfig dpy visual GLX_USE_GL)) 1) ;; found a visual that can support GL (let ((buffersize (cadr (glXGetConfig dpy visual GLX_BUFFER_SIZE))) (level (cadr (glXGetConfig dpy visual GLX_LEVEL))) (rgba (cadr (glXGetConfig dpy visual GLX_RGBA))) (doublebuffer (cadr (glXGetConfig dpy visual GLX_DOUBLEBUFFER))) (stereo (cadr (glXGetConfig dpy visual GLX_STEREO))) (auxbuffers (cadr (glXGetConfig dpy visual GLX_AUX_BUFFERS))) (redsize (cadr (glXGetConfig dpy visual GLX_RED_SIZE))) (bluesize (cadr (glXGetConfig dpy visual GLX_BLUE_SIZE))) (greensize (cadr (glXGetConfig dpy visual GLX_GREEN_SIZE))) (alphasize (cadr (glXGetConfig dpy visual GLX_ALPHA_SIZE))) (depthsize (cadr (glXGetConfig dpy visual GLX_DEPTH_SIZE))) (stencilsize (cadr (glXGetConfig dpy visual GLX_STENCIL_SIZE))) (acredsize (cadr (glXGetConfig dpy visual GLX_ACCUM_RED_SIZE))) (acgreensize (cadr (glXGetConfig dpy visual GLX_ACCUM_GREEN_SIZE))) (acbluesize (cadr (glXGetConfig dpy visual GLX_ACCUM_BLUE_SIZE))) (acalphasize (cadr (glXGetConfig dpy visual GLX_ACCUM_ALPHA_SIZE)))) (snd-print (format #f " id: #x~X depth: ~D class: ~S~%" ((*motif* '.visualid) visual) ((*motif* '.depth) visual) (class-of ((*motif* '.class) visual)))) (snd-print (format #f " buffersize: ~D, level: ~D, rgba: ~A, doublebuffer: ~A, stereo: ~A~%" buffersize level (if (= rgba 1) "#t" "#f") (if (= doublebuffer 1) "#t" "#f") (if (= stereo 1) "#t" "#f"))) (snd-print (format #f " r: ~A, g: ~D, b: ~D, alpha: ~D, accum-r: ~D, accum-g: ~D, accum-b: ~D, accum-alpha: ~D~%" redsize greensize bluesize alphasize acredsize acgreensize acbluesize acalphasize)) (snd-print (format #f " auxbuffs: ~D, depth: ~D, acalpha: ~D~%" auxbuffers depthsize stencilsize)) ))) visuals)) (snd-print "no GL found!")))))) ;;; -------- dump GL state (define (gl-dump-state) ;; based on Mesa/util/dumpstate.c by Stephane Rehel (format #t "GL_CURRENT_COLOR: ~A~%" (glGetFloatv GL_CURRENT_COLOR)) (format #t "GL_CURRENT_INDEX: ~A~%" (glGetIntegerv GL_CURRENT_INDEX)) (format #t "GL_CURRENT_TEXTURE_COORDS: ~A~%" (glGetFloatv GL_CURRENT_TEXTURE_COORDS)) (format #t "GL_CURRENT_NORMAL: ~A~%" (glGetFloatv GL_CURRENT_NORMAL)) (format #t "GL_CURRENT_RASTER_POSITION: ~A~%" (glGetFloatv GL_CURRENT_RASTER_POSITION)) (format #t "GL_CURRENT_RASTER_DISTANCE: ~A~%" (glGetFloatv GL_CURRENT_RASTER_DISTANCE)) (format #t "GL_CURRENT_RASTER_COLOR: ~A~%" (glGetFloatv GL_CURRENT_RASTER_COLOR)) (format #t "GL_CURRENT_RASTER_INDEX: ~A~%" (glGetIntegerv GL_CURRENT_RASTER_INDEX)) (format #t "GL_CURRENT_RASTER_TEXTURE_COORDS: ~A~%" (glGetFloatv GL_CURRENT_RASTER_TEXTURE_COORDS)) (format #t "GL_CURRENT_RASTER_POSITION_VALID: ~A~%" (glGetBooleanv GL_CURRENT_RASTER_POSITION_VALID)) (format #t "GL_EDGE_FLAG: ~A~%" (glGetBooleanv GL_EDGE_FLAG)) (format #t "GL_VERTEX_ARRAY: ~A~%" (glGetBooleanv GL_VERTEX_ARRAY)) (format #t "GL_VERTEX_ARRAY_SIZE: ~A~%" (glGetIntegerv GL_VERTEX_ARRAY_SIZE)) (format #t "GL_VERTEX_ARRAY_TYPE: ~A~%" (glGetIntegerv GL_VERTEX_ARRAY_TYPE)) (format #t "GL_VERTEX_ARRAY_STRIDE: ~A~%" (glGetIntegerv GL_VERTEX_ARRAY_STRIDE)) (format #t "GL_VERTEX_ARRAY_POINTER: ~A~%" (glGetPointerv GL_VERTEX_ARRAY_POINTER)) (format #t "GL_NORMAL_ARRAY: ~A~%" (glGetBooleanv GL_NORMAL_ARRAY)) (format #t "GL_NORMAL_ARRAY_TYPE: ~A~%" (glGetIntegerv GL_NORMAL_ARRAY_TYPE)) (format #t "GL_NORMAL_ARRAY_STRIDE: ~A~%" (glGetIntegerv GL_NORMAL_ARRAY_STRIDE)) (format #t "GL_NORMAL_ARRAY_POINTER: ~A~%" (glGetPointerv GL_NORMAL_ARRAY_POINTER)) (format #t "GL_COLOR_ARRAY: ~A~%" (glGetBooleanv GL_COLOR_ARRAY)) (format #t "GL_COLOR_ARRAY_SIZE: ~A~%" (glGetIntegerv GL_COLOR_ARRAY_SIZE)) (format #t "GL_COLOR_ARRAY_TYPE: ~A~%" (glGetIntegerv GL_COLOR_ARRAY_TYPE)) (format #t "GL_COLOR_ARRAY_STRIDE: ~A~%" (glGetIntegerv GL_COLOR_ARRAY_STRIDE)) (format #t "GL_COLOR_ARRAY_POINTER: ~A~%" (glGetPointerv GL_COLOR_ARRAY_POINTER)) (format #t "GL_INDEX_ARRAY: ~A~%" (glGetBooleanv GL_INDEX_ARRAY)) (format #t "GL_INDEX_ARRAY_TYPE: ~A~%" (glGetIntegerv GL_INDEX_ARRAY_TYPE)) (format #t "GL_INDEX_ARRAY_STRIDE: ~A~%" (glGetIntegerv GL_INDEX_ARRAY_STRIDE)) (format #t "GL_INDEX_ARRAY_POINTER: ~A~%" (glGetPointerv GL_INDEX_ARRAY_POINTER)) (format #t "GL_TEXTURE_COORD_ARRAY: ~A~%" (glGetBooleanv GL_TEXTURE_COORD_ARRAY)) (format #t "GL_TEXTURE_COORD_ARRAY_SIZE: ~A~%" (glGetIntegerv GL_TEXTURE_COORD_ARRAY_SIZE)) (format #t "GL_TEXTURE_COORD_ARRAY_TYPE: ~A~%" (glGetIntegerv GL_TEXTURE_COORD_ARRAY_TYPE)) (format #t "GL_TEXTURE_COORD_ARRAY_STRIDE: ~A~%" (glGetIntegerv GL_TEXTURE_COORD_ARRAY_STRIDE)) (format #t "GL_TEXTURE_COORD_ARRAY_POINTER: ~A~%" (glGetPointerv GL_TEXTURE_COORD_ARRAY_POINTER)) (format #t "GL_EDGE_FLAG_ARRAY: ~A~%" (glGetBooleanv GL_EDGE_FLAG_ARRAY)) (format #t "GL_EDGE_FLAG_ARRAY_STRIDE: ~A~%" (glGetIntegerv GL_EDGE_FLAG_ARRAY_STRIDE)) (format #t "GL_EDGE_FLAG_ARRAY_POINTER: ~A~%" (glGetPointerv GL_EDGE_FLAG_ARRAY_POINTER)) (format #t "GL_MODELVIEW_MATRIX: ~A~%" (glGetFloatv GL_MODELVIEW_MATRIX)) (format #t "GL_PROJECTION_MATRIX: ~A~%" (glGetFloatv GL_PROJECTION_MATRIX)) (format #t "GL_TEXTURE_MATRIX: ~A~%" (glGetFloatv GL_TEXTURE_MATRIX)) (format #t "GL_VIEWPORT: ~A~%" (glGetIntegerv GL_VIEWPORT)) (format #t "GL_DEPTH_RANGE: ~A~%" (glGetFloatv GL_DEPTH_RANGE)) (format #t "GL_MODELVIEW_STACK_DEPTH: ~A~%" (glGetIntegerv GL_MODELVIEW_STACK_DEPTH)) (format #t "GL_PROJECTION_STACK_DEPTH: ~A~%" (glGetIntegerv GL_PROJECTION_STACK_DEPTH)) (format #t "GL_TEXTURE_STACK_DEPTH: ~A~%" (glGetIntegerv GL_TEXTURE_STACK_DEPTH)) (format #t "GL_MATRIX_MODE: ~A~%" (glGetIntegerv GL_MATRIX_MODE)) (format #t "GL_NORMALIZE: ~A~%" (glGetBooleanv GL_NORMALIZE)) (format #t "GL_CLIP_PLANE0: ~A~%" (glGetBooleanv GL_CLIP_PLANE0)) (format #t "GL_CLIP_PLANE1: ~A~%" (glGetBooleanv GL_CLIP_PLANE1)) (format #t "GL_CLIP_PLANE2: ~A~%" (glGetBooleanv GL_CLIP_PLANE2)) (format #t "GL_CLIP_PLANE3: ~A~%" (glGetBooleanv GL_CLIP_PLANE3)) (format #t "GL_CLIP_PLANE4: ~A~%" (glGetBooleanv GL_CLIP_PLANE4)) (format #t "GL_CLIP_PLANE5: ~A~%" (glGetBooleanv GL_CLIP_PLANE5)) (format #t "GL_FOG_COLOR: ~A~%" (glGetFloatv GL_FOG_COLOR)) (format #t "GL_FOG_INDEX: ~A~%" (glGetIntegerv GL_FOG_INDEX)) (format #t "GL_FOG_DENSITY: ~A~%" (glGetFloatv GL_FOG_DENSITY)) (format #t "GL_FOG_START: ~A~%" (glGetFloatv GL_FOG_START)) (format #t "GL_FOG_END: ~A~%" (glGetFloatv GL_FOG_END)) (format #t "GL_FOG_MODE: ~A~%" (glGetIntegerv GL_FOG_MODE)) (format #t "GL_FOG: ~A~%" (glGetBooleanv GL_FOG)) (format #t "GL_SHADE_MODEL: ~A~%" (glGetIntegerv GL_SHADE_MODEL)) (format #t "GL_LIGHTING: ~A~%" (glGetBooleanv GL_LIGHTING)) (format #t "GL_COLOR_MATERIAL: ~A~%" (glGetBooleanv GL_COLOR_MATERIAL)) (format #t "GL_COLOR_MATERIAL_PARAMETER: ~A~%" (glGetIntegerv GL_COLOR_MATERIAL_PARAMETER)) (format #t "GL_COLOR_MATERIAL_FACE: ~A~%" (glGetIntegerv GL_COLOR_MATERIAL_FACE)) (format #t "GL_BACK GL_AMBIENT: ~A~%" (glGetMaterialfv GL_BACK GL_AMBIENT)) (format #t "GL_FRONT GL_AMBIENT: ~A~%" (glGetMaterialfv GL_FRONT GL_AMBIENT)) (format #t "GL_BACK GL_DIFFUSE: ~A~%" (glGetMaterialfv GL_BACK GL_DIFFUSE)) (format #t "GL_FRONT GL_DIFFUSE: ~A~%" (glGetMaterialfv GL_FRONT GL_DIFFUSE)) (format #t "GL_BACK GL_SPECULAR: ~A~%" (glGetMaterialfv GL_BACK GL_SPECULAR)) (format #t "GL_FRONT GL_SPECULAR: ~A~%" (glGetMaterialfv GL_FRONT GL_SPECULAR)) (format #t "GL_BACK GL_EMISSION: ~A~%" (glGetMaterialfv GL_BACK GL_EMISSION)) (format #t "GL_FRONT GL_EMISSION: ~A~%" (glGetMaterialfv GL_FRONT GL_EMISSION)) (format #t "GL_BACK GL_SHININESS: ~A~%" (glGetMaterialfv GL_BACK GL_SHININESS)) (format #t "GL_FRONT GL_SHININESS: ~A~%" (glGetMaterialfv GL_FRONT GL_SHININESS)) (format #t "GL_LIGHT_MODEL_AMBIENT: ~A~%" (glGetFloatv GL_LIGHT_MODEL_AMBIENT)) (format #t "GL_LIGHT_MODEL_LOCAL_VIEWER: ~A~%" (glGetBooleanv GL_LIGHT_MODEL_LOCAL_VIEWER)) (format #t "GL_LIGHT_MODEL_TWO_SIDE: ~A~%" (glGetBooleanv GL_LIGHT_MODEL_TWO_SIDE)) (let ((nlights (car (glGetIntegerv GL_MAX_LIGHTS)))) (do ((i 0 (+ 1 i))) ((= i nlights)) (if (car (glGetBooleanv (+ GL_LIGHT0 i))) (begin (glGetFloatv i AMBIENT) (glGetFloatv i DIFFUSE) (glGetFloatv i SPECULAR) (glGetLightfv i POSITION) (glGetLightfv i CONSTANT_ATTENUATION) (glGetLightfv i LINEAR_ATTENUATION) (glGetLightfv i QUADRATIC_ATTENUATION) (glGetLightfv i SPOT_DIRECTION) (glGetLightfv i SPOT_EXPONENT) (glGetLightfv i SPOT_CUTOFF) )))) (format #t "GL_POINT_SIZE: ~A~%" (glGetFloatv GL_POINT_SIZE)) (format #t "GL_POINT_SMOOTH: ~A~%" (glGetBooleanv GL_POINT_SMOOTH)) (format #t "GL_LINE_WIDTH: ~A~%" (glGetFloatv GL_LINE_WIDTH)) (format #t "GL_LINE_SMOOTH: ~A~%" (glGetBooleanv GL_LINE_SMOOTH)) (format #t "GL_LINE_STIPPLE_PATTERN: ~A~%" (glGetIntegerv GL_LINE_STIPPLE_PATTERN)) (format #t "GL_LINE_STIPPLE_REPEAT: ~A~%" (glGetIntegerv GL_LINE_STIPPLE_REPEAT)) (format #t "GL_LINE_STIPPLE: ~A~%" (glGetBooleanv GL_LINE_STIPPLE)) (format #t "GL_CULL_FACE: ~A~%" (glGetBooleanv GL_CULL_FACE)) (format #t "GL_CULL_FACE_MODE: ~A~%" (glGetIntegerv GL_CULL_FACE_MODE)) (format #t "GL_FRONT_FACE: ~A~%" (glGetIntegerv GL_FRONT_FACE)) (format #t "GL_POLYGON_SMOOTH: ~A~%" (glGetBooleanv GL_POLYGON_SMOOTH)) (format #t "GL_POLYGON_MODE: ~A~%" (glGetIntegerv GL_POLYGON_MODE)) (format #t "GL_POLYGON_OFFSET_FACTOR: ~A~%" (glGetFloatv GL_POLYGON_OFFSET_FACTOR)) (format #t "GL_POLYGON_OFFSET_UNITS: ~A~%" (glGetFloatv GL_POLYGON_OFFSET_UNITS)) (format #t "GL_POLYGON_OFFSET_POINT: ~A~%" (glGetBooleanv GL_POLYGON_OFFSET_POINT)) (format #t "GL_POLYGON_OFFSET_LINE: ~A~%" (glGetBooleanv GL_POLYGON_OFFSET_LINE)) (format #t "GL_POLYGON_OFFSET_FILL: ~A~%" (glGetBooleanv GL_POLYGON_OFFSET_FILL)) (format #t "GL_POLYGON_STIPPLE: ~A~%" (glGetBooleanv GL_POLYGON_STIPPLE)) (format #t "GL_TEXTURE_1D: ~A~%" (glGetBooleanv GL_TEXTURE_1D)) (format #t "GL_TEXTURE_2D: ~A~%" (glGetBooleanv GL_TEXTURE_2D)) (format #t "GL_TEXTURE_BINDING_1D: ~A~%" (glGetIntegerv GL_TEXTURE_BINDING_1D)) (format #t "GL_TEXTURE_BINDING_2D: ~A~%" (glGetIntegerv GL_TEXTURE_BINDING_2D)) (format #t "GL_TEXTURE_GEN_S: ~A~%" (glGetBooleanv GL_TEXTURE_GEN_S)) (format #t "GL_TEXTURE_GEN_T: ~A~%" (glGetBooleanv GL_TEXTURE_GEN_T)) (format #t "GL_TEXTURE_GEN_R: ~A~%" (glGetBooleanv GL_TEXTURE_GEN_R)) (format #t "GL_TEXTURE_GEN_Q: ~A~%" (glGetBooleanv GL_TEXTURE_GEN_Q)) (format #t "GL_SCISSOR_TEST: ~A~%" (glGetBooleanv GL_SCISSOR_TEST)) (format #t "GL_SCISSOR_BOX: ~A~%" (glGetIntegerv GL_SCISSOR_BOX)) (format #t "GL_ALPHA_TEST: ~A~%" (glGetBooleanv GL_ALPHA_TEST)) (format #t "GL_ALPHA_TEST_FUNC: ~A~%" (glGetIntegerv GL_ALPHA_TEST_FUNC)) (format #t "GL_ALPHA_TEST_REF: ~A~%" (glGetFloatv GL_ALPHA_TEST_REF)) (format #t "GL_STENCIL_TEST: ~A~%" (glGetBooleanv GL_STENCIL_TEST)) (format #t "GL_STENCIL_FUNC: ~A~%" (glGetIntegerv GL_STENCIL_FUNC)) (format #t "GL_STENCIL_VALUE_MASK: ~A~%" (glGetIntegerv GL_STENCIL_VALUE_MASK)) (format #t "GL_STENCIL_REF: ~A~%" (glGetIntegerv GL_STENCIL_REF)) (format #t "GL_STENCIL_FAIL: ~A~%" (glGetIntegerv GL_STENCIL_FAIL)) (format #t "GL_STENCIL_PASS_DEPTH_FAIL: ~A~%" (glGetIntegerv GL_STENCIL_PASS_DEPTH_FAIL)) (format #t "GL_STENCIL_PASS_DEPTH_PASS: ~A~%" (glGetIntegerv GL_STENCIL_PASS_DEPTH_PASS)) (format #t "GL_DEPTH_TEST: ~A~%" (glGetBooleanv GL_DEPTH_TEST)) (format #t "GL_DEPTH_FUNC: ~A~%" (glGetIntegerv GL_DEPTH_FUNC)) (format #t "GL_BLEND: ~A~%" (glGetBooleanv GL_BLEND)) (format #t "GL_BLEND_SRC: ~A~%" (glGetIntegerv GL_BLEND_SRC)) (format #t "GL_BLEND_DST: ~A~%" (glGetIntegerv GL_BLEND_DST)) (format #t "GL_DITHER: ~A~%" (glGetBooleanv GL_DITHER)) (format #t "GL_LOGIC_OP: ~A~%" (glGetBooleanv GL_LOGIC_OP)) (format #t "GL_COLOR_LOGIC_OP: ~A~%" (glGetBooleanv GL_COLOR_LOGIC_OP)) (format #t "GL_DRAW_BUFFER: ~A~%" (glGetIntegerv GL_DRAW_BUFFER)) (format #t "GL_INDEX_WRITEMASK: ~A~%" (glGetIntegerv GL_INDEX_WRITEMASK)) (format #t "GL_COLOR_WRITEMASK: ~A~%" (glGetBooleanv GL_COLOR_WRITEMASK)) (format #t "GL_DEPTH_WRITEMASK: ~A~%" (glGetBooleanv GL_DEPTH_WRITEMASK)) (format #t "GL_STENCIL_WRITEMASK: ~A~%" (glGetIntegerv GL_STENCIL_WRITEMASK)) (format #t "GL_COLOR_CLEAR_VALUE: ~A~%" (glGetFloatv GL_COLOR_CLEAR_VALUE)) (format #t "GL_INDEX_CLEAR_VALUE: ~A~%" (glGetIntegerv GL_INDEX_CLEAR_VALUE)) (format #t "GL_DEPTH_CLEAR_VALUE: ~A~%" (glGetFloatv GL_DEPTH_CLEAR_VALUE)) (format #t "GL_STENCIL_CLEAR_VALUE: ~A~%" (glGetIntegerv GL_STENCIL_CLEAR_VALUE)) (format #t "GL_ACCUM_CLEAR_VALUE: ~A~%" (glGetFloatv GL_ACCUM_CLEAR_VALUE)) (format #t "GL_UNPACK_SWAP_BYTES: ~A~%" (glGetBooleanv GL_UNPACK_SWAP_BYTES)) (format #t "GL_UNPACK_LSB_FIRST: ~A~%" (glGetBooleanv GL_UNPACK_LSB_FIRST)) (format #t "GL_UNPACK_ROW_LENGTH: ~A~%" (glGetIntegerv GL_UNPACK_ROW_LENGTH)) (format #t "GL_UNPACK_SKIP_ROWS: ~A~%" (glGetIntegerv GL_UNPACK_SKIP_ROWS)) (format #t "GL_UNPACK_SKIP_PIXELS: ~A~%" (glGetIntegerv GL_UNPACK_SKIP_PIXELS)) (format #t "GL_UNPACK_ALIGNMENT: ~A~%" (glGetIntegerv GL_UNPACK_ALIGNMENT)) (format #t "GL_PACK_SWAP_BYTES: ~A~%" (glGetBooleanv GL_PACK_SWAP_BYTES)) (format #t "GL_PACK_LSB_FIRST: ~A~%" (glGetBooleanv GL_PACK_LSB_FIRST)) (format #t "GL_PACK_ROW_LENGTH: ~A~%" (glGetIntegerv GL_PACK_ROW_LENGTH)) (format #t "GL_PACK_SKIP_ROWS: ~A~%" (glGetIntegerv GL_PACK_SKIP_ROWS)) (format #t "GL_PACK_SKIP_PIXELS: ~A~%" (glGetIntegerv GL_PACK_SKIP_PIXELS)) (format #t "GL_PACK_ALIGNMENT: ~A~%" (glGetIntegerv GL_PACK_ALIGNMENT)) (format #t "GL_MAP_COLOR: ~A~%" (glGetBooleanv GL_MAP_COLOR)) (format #t "GL_MAP_STENCIL: ~A~%" (glGetBooleanv GL_MAP_STENCIL)) (format #t "GL_INDEX_SHIFT: ~A~%" (glGetIntegerv GL_INDEX_SHIFT)) (format #t "GL_INDEX_OFFSET: ~A~%" (glGetIntegerv GL_INDEX_OFFSET)) (format #t "GL_RED_SCALE: ~A~%" (glGetFloatv GL_RED_SCALE)) (format #t "GL_GREEN_SCALE: ~A~%" (glGetFloatv GL_GREEN_SCALE)) (format #t "GL_BLUE_SCALE: ~A~%" (glGetFloatv GL_BLUE_SCALE)) (format #t "GL_ALPHA_SCALE: ~A~%" (glGetFloatv GL_ALPHA_SCALE)) (format #t "GL_DEPTH_SCALE: ~A~%" (glGetFloatv GL_DEPTH_SCALE)) (format #t "GL_RED_BIAS: ~A~%" (glGetFloatv GL_RED_BIAS)) (format #t "GL_GREEN_BIAS: ~A~%" (glGetFloatv GL_GREEN_BIAS)) (format #t "GL_BLUE_BIAS: ~A~%" (glGetFloatv GL_BLUE_BIAS)) (format #t "GL_ALPHA_BIAS: ~A~%" (glGetFloatv GL_ALPHA_BIAS)) (format #t "GL_DEPTH_BIAS: ~A~%" (glGetFloatv GL_DEPTH_BIAS)) (format #t "GL_ZOOM_X: ~A~%" (glGetFloatv GL_ZOOM_X)) (format #t "GL_ZOOM_Y: ~A~%" (glGetFloatv GL_ZOOM_Y)) (format #t "GL_READ_BUFFER: ~A~%" (glGetIntegerv GL_READ_BUFFER)) (format #t "GL_AUTO_NORMAL: ~A~%" (glGetBooleanv GL_AUTO_NORMAL)) (format #t "GL_PERSPECTIVE_CORRECTION_HINT: ~A~%" (glGetIntegerv GL_PERSPECTIVE_CORRECTION_HINT)) (format #t "GL_POINT_SMOOTH_HINT: ~A~%" (glGetIntegerv GL_POINT_SMOOTH_HINT)) (format #t "GL_LINE_SMOOTH_HINT: ~A~%" (glGetIntegerv GL_LINE_SMOOTH_HINT)) (format #t "GL_POLYGON_SMOOTH_HINT: ~A~%" (glGetIntegerv GL_POLYGON_SMOOTH_HINT)) (format #t "GL_FOG_HINT: ~A~%" (glGetIntegerv GL_FOG_HINT)) (format #t "GL_MAX_LIGHTS: ~A~%" (glGetIntegerv GL_MAX_LIGHTS)) (format #t "GL_MAX_CLIP_PLANES: ~A~%" (glGetIntegerv GL_MAX_CLIP_PLANES)) (format #t "GL_MAX_MODELVIEW_STACK_DEPTH: ~A~%" (glGetIntegerv GL_MAX_MODELVIEW_STACK_DEPTH)) (format #t "GL_MAX_PROJECTION_STACK_DEPTH: ~A~%" (glGetIntegerv GL_MAX_PROJECTION_STACK_DEPTH)) (format #t "GL_MAX_TEXTURE_STACK_DEPTH: ~A~%" (glGetIntegerv GL_MAX_TEXTURE_STACK_DEPTH)) (format #t "GL_SUBPIXEL_BITS: ~A~%" (glGetIntegerv GL_SUBPIXEL_BITS)) (format #t "GL_MAX_TEXTURE_SIZE: ~A~%" (glGetIntegerv GL_MAX_TEXTURE_SIZE)) (format #t "GL_MAX_PIXEL_MAP_TABLE: ~A~%" (glGetIntegerv GL_MAX_PIXEL_MAP_TABLE)) (format #t "GL_MAX_NAME_STACK_DEPTH: ~A~%" (glGetIntegerv GL_MAX_NAME_STACK_DEPTH)) (format #t "GL_MAX_LIST_NESTING: ~A~%" (glGetIntegerv GL_MAX_LIST_NESTING)) (format #t "GL_MAX_EVAL_ORDER: ~A~%" (glGetIntegerv GL_MAX_EVAL_ORDER)) (format #t "GL_MAX_VIEWPORT_DIMS: ~A~%" (glGetIntegerv GL_MAX_VIEWPORT_DIMS)) (format #t "GL_MAX_ATTRIB_STACK_DEPTH: ~A~%" (glGetIntegerv GL_MAX_ATTRIB_STACK_DEPTH)) (format #t "GL_MAX_CLIENT_ATTRIB_STACK_DEPTH: ~A~%" (glGetIntegerv GL_MAX_CLIENT_ATTRIB_STACK_DEPTH)) (format #t "GL_AUX_BUFFERS: ~A~%" (glGetIntegerv GL_AUX_BUFFERS)) (format #t "GL_RGBA_MODE: ~A~%" (glGetBooleanv GL_RGBA_MODE)) (format #t "GL_INDEX_MODE: ~A~%" (glGetBooleanv GL_INDEX_MODE)) (format #t "GL_DOUBLEBUFFER: ~A~%" (glGetBooleanv GL_DOUBLEBUFFER)) (format #t "GL_STEREO: ~A~%" (glGetBooleanv GL_STEREO)) (format #t "GL_LINE_WIDTH_RANGE: ~A~%" (glGetFloatv GL_LINE_WIDTH_RANGE)) (format #t "GL_LINE_WIDTH_GRANULARITY: ~A~%" (glGetFloatv GL_LINE_WIDTH_GRANULARITY)) (format #t "GL_RED_BITS: ~A~%" (glGetIntegerv GL_RED_BITS)) (format #t "GL_GREEN_BITS: ~A~%" (glGetIntegerv GL_GREEN_BITS)) (format #t "GL_BLUE_BITS: ~A~%" (glGetIntegerv GL_BLUE_BITS)) (format #t "GL_ALPHA_BITS: ~A~%" (glGetIntegerv GL_ALPHA_BITS)) (format #t "GL_INDEX_BITS: ~A~%" (glGetIntegerv GL_INDEX_BITS)) (format #t "GL_DEPTH_BITS: ~A~%" (glGetIntegerv GL_DEPTH_BITS)) (format #t "GL_STENCIL_BITS: ~A~%" (glGetIntegerv GL_STENCIL_BITS)) (format #t "GL_ACCUM_RED_BITS: ~A~%" (glGetIntegerv GL_ACCUM_RED_BITS)) (format #t "GL_ACCUM_GREEN_BITS: ~A~%" (glGetIntegerv GL_ACCUM_GREEN_BITS)) (format #t "GL_ACCUM_BLUE_BITS: ~A~%" (glGetIntegerv GL_ACCUM_BLUE_BITS)) (format #t "GL_ACCUM_ALPHA_BITS: ~A~%" (glGetIntegerv GL_ACCUM_ALPHA_BITS)) (format #t "GL_LIST_BASE: ~A~%" (glGetIntegerv GL_LIST_BASE)) (format #t "GL_LIST_INDEX: ~A~%" (glGetIntegerv GL_LIST_INDEX)) (format #t "GL_LIST_MODE: ~A~%" (glGetIntegerv GL_LIST_MODE)) (format #t "GL_ATTRIB_STACK_DEPTH: ~A~%" (glGetIntegerv GL_ATTRIB_STACK_DEPTH)) (format #t "GL_CLIENT_ATTRIB_STACK_DEPTH: ~A~%" (glGetIntegerv GL_CLIENT_ATTRIB_STACK_DEPTH)) (format #t "GL_NAME_STACK_DEPTH: ~A~%" (glGetIntegerv GL_NAME_STACK_DEPTH)) (format #t "GL_RENDER_MODE: ~A~%" (glGetIntegerv GL_RENDER_MODE)) (format #t "GL_SELECTION_BUFFER_POINTER: ~A~%" (glGetPointerv GL_SELECTION_BUFFER_POINTER)) (format #t "GL_SELECTION_BUFFER_SIZE: ~A~%" (glGetIntegerv GL_SELECTION_BUFFER_SIZE)) (format #t "GL_FEEDBACK_BUFFER_POINTER: ~A~%" (glGetPointerv GL_FEEDBACK_BUFFER_POINTER)) (format #t "GL_FEEDBACK_BUFFER_SIZE: ~A~%" (glGetIntegerv GL_FEEDBACK_BUFFER_SIZE)) (format #t "GL_FEEDBACK_BUFFER_TYPE: ~A~%" (glGetIntegerv GL_FEEDBACK_BUFFER_TYPE)) ) ;;; -------- complexify -------- (require snd-snd-motif.scm) (define complexify (let ((gl-list #f) (drawer #f)) (define (redraw-graph) (let ((win ((*motif* 'XtWindow) drawer)) (dpy ((*motif* 'XtDisplay) drawer)) (cx (snd-gl-context))) (glXMakeCurrent dpy win cx) (if gl-list (glDeleteLists gl-list 1)) (set! gl-list (glGenLists 1)) (glEnable GL_DEPTH_TEST) (glShadeModel GL_SMOOTH) (glClearDepth 1.0) (glClearColor 1.0 1.0 1.0 1.0) (glClear (logior GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT)) (let ((rl (channel->float-vector (left-sample) 512)) (im (make-float-vector 512 0.0))) (mus-fft rl im) (let ((peak (* 2 (max (float-vector-peak rl) (float-vector-peak im))))) (float-vector-scale! rl (/ 1.0 peak)) (float-vector-scale! im (/ 1.0 peak))) ;; display each element in the complex plane rotated to stack along the x axis (glNewList gl-list GL_COMPILE) (glBegin GL_LINES) (apply glColor3f (color->list *data-color*)) (do ((i 0 (+ 1 i))) ((= i 256)) (glVertex3f (/ i 256.0) 0.0 0.0) (glVertex3f (/ i 256.0) (rl i) (im i))) (glEnd) (glEndList)) (let ((vals ((*motif* 'XtVaGetValues) drawer (list (*motif* 'XmNwidth) 0 (*motif* 'XmNheight) 0)))) (glViewport 0 0 (list-ref vals 1) (list-ref vals 3))) (glMatrixMode GL_PROJECTION) (glLoadIdentity) (glOrtho -0.2 1.0 -1.5 1.0 -1.0 1.0) (glRotatef *spectro-x-angle* 1.0 0.0 0.0) (glRotatef *spectro-y-angle* 0.0 1.0 0.0) (glRotatef *spectro-z-angle* 0.0 0.0 1.0) (glScalef *spectro-x-scale* *spectro-y-scale* *spectro-z-scale*) (glCallList gl-list) (glXSwapBuffers dpy win) (glDrawBuffer GL_BACK))) (define (add-main-pane name type args) ((*motif* 'XtCreateManagedWidget) name type (list-ref (main-widgets) 3) args)) (lambda () (if (not drawer) (let ((outer (with-let (sublet *motif*) (add-main-pane "Waterfall" xmFormWidgetClass (list XmNbackground *basic-color* XmNpaneMinimum 320))))) (set! drawer (with-let (sublet *motif* 'outer outer) (XtCreateManagedWidget "draw" xmDrawingAreaWidgetClass outer (list XmNbackground *graph-color* XmNforeground *data-color* XmNleftAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM)))) (set! *spectro-x-angle* 210.0) (set! *spectro-y-angle* 60.0) (set! *spectro-z-angle* 30.0) (set! *spectro-x-scale* 3.0) ((*motif* 'XtAddCallback) drawer (*motif* 'XmNresizeCallback) (lambda (w context info) (redraw-graph))) ((*motif* 'XtAddCallback) drawer (*motif* 'XmNexposeCallback) (lambda (w context info) (redraw-graph))) (hook-push after-graph-hook (lambda (hook) (redraw-graph))) (hook-push orientation-hook (lambda (hook) (redraw-graph))) (hook-push color-hook (lambda (hook) (redraw-graph)))))))) ) (define complexify (*gl* 'complexify)) snd-16.1/snd-gfft.c0000644000076400007640000012004212512761107012210 0ustar bilbil/* transform settings dialog */ #include "snd.h" /* when options window expanded vertically, graph gets less than half (empty space in button box) * this is a table grid, so I don't think much is possible */ static slist *transform_list = NULL, *size_list = NULL, *window_list = NULL, *wavelet_list = NULL; static GtkWidget *transform_dialog = NULL; /* main dialog shell */ static GtkWidget *outer_table, *db_button, *peaks_button, *logfreq_button, *sono_button, *spectro_button, *normal_fft_button, *phases_button; static GtkWidget *normalize_button, *selection_button; static GtkWidget *alpha_label = NULL, *beta_label = NULL, *graph_drawer = NULL, *fft_window_label = NULL; static GtkAdjustment *beta_adj, *alpha_adj, *spectrum_start_adj, *spectrum_end_adj; static GtkWidget *spectrum_start_scale, *spectrum_end_scale; static GtkWidget *db_txt, *peaks_txt, *lf_txt; static gc_t *fft_gc = NULL, *fgc = NULL; static bool ignore_callbacks; #define NUM_TRANSFORM_SIZES 15 static const char *transform_size_names[NUM_TRANSFORM_SIZES] = {"32", "64", "128", "256", "512", "1024", "2048", "4096", "8192", "16384", "65536", "262144", "1048576", "4194304 ", "16777216"}; static mus_long_t transform_sizes[NUM_TRANSFORM_SIZES] = {32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 65536, 262144, 1048576, 4194304, 16777216}; /* ---------------- window graphs ---------------- */ #define GRAPH_SIZE 128 static mus_float_t graph_data[GRAPH_SIZE]; /* fft window graph in transform options dialog */ static mus_float_t graph_fftr[GRAPH_SIZE * 2]; static mus_float_t graph_ffti[GRAPH_SIZE * 2]; static mus_float_t fp_dB(mus_float_t py) { return((py <= ss->lin_dB) ? 0.0 : (1.0 - (20.0 * log10(py) / min_dB(ss)))); } static axis_info *axis_ap = NULL; static void graph_redisplay(void) { Drawable *wn; int ix0, iy0, ix1, iy1, i; mus_float_t xincr, x; graphics_context *ax; if (!(transform_dialog_is_active())) return; if (graph_drawer == NULL) return; wn = WIDGET_TO_WINDOW(graph_drawer); if (wn == NULL) return; if (!axis_ap) { axis_ap = (axis_info *)calloc(1, sizeof(axis_info)); ax = (graphics_context *)calloc(1, sizeof(graphics_context)); axis_ap->ax = ax; } else ax = axis_ap->ax; ax->wn = WIDGET_TO_WINDOW(graph_drawer); ax->w = graph_drawer; ax->gc = fft_gc; ax->current_font = TINY_FONT(ss); /* we're right on the edge; this changes if user makes dialog bigger */ axis_ap->xmin = 0.0; axis_ap->xmax = 1.0; axis_ap->x_ambit = 1.0; axis_ap->x0 = 0.0; axis_ap->x1 = 1.0; ss->cr = make_cairo(ax->wn); cairo_push_group(ss->cr); /* erase previous */ cairo_set_source_rgba(ss->cr, ax->gc->bg_color->red, ax->gc->bg_color->green, ax->gc->bg_color->blue, ax->gc->bg_color->alpha); cairo_rectangle(ss->cr, 0, 0, widget_width(graph_drawer), widget_height(graph_drawer)); cairo_fill(ss->cr); if (axis_ap->xlabel) free(axis_ap->xlabel); if (fft_beta_max(fft_window(ss)) != 1.0) axis_ap->xlabel = mus_format("(%d, beta: %.2f)", GRAPH_SIZE, fft_beta_max(fft_window(ss)) * fft_window_beta(ss)); else axis_ap->xlabel = mus_format("(%d)", GRAPH_SIZE); if (fft_window(ss) == MUS_FLAT_TOP_WINDOW) { axis_ap->ymin = -0.1; axis_ap->ymax = 1.0; axis_ap->y_ambit = 1.1; axis_ap->y0 = -0.1; axis_ap->y1 = 1.0; } else { axis_ap->ymin = 0.0; axis_ap->ymax = 1.0; axis_ap->y_ambit = 1.0; axis_ap->y0 = 0.0; axis_ap->y1 = 1.0; } axis_ap->width = widget_width(graph_drawer); axis_ap->window_width = axis_ap->width; axis_ap->y_offset = 0; axis_ap->height = widget_height(graph_drawer); axis_ap->graph_x0 = 0; make_axes_1(axis_ap, X_AXIS_IN_SECONDS, 1 /* "srate" */, SHOW_ALL_AXES, NOT_PRINTING, WITH_X_AXIS, NO_GRID, WITH_LINEAR_AXES, grid_density(ss)); ax->gc = fft_gc; ix1 = grf_x(0.0, axis_ap); iy1 = grf_y(graph_data[0], axis_ap); xincr = 1.0 / (mus_float_t)GRAPH_SIZE; for (i = 1, x = xincr; i < GRAPH_SIZE; i++, x += xincr) { ix0 = ix1; iy0 = iy1; ix1 = grf_x(x, axis_ap); iy1 = grf_y(graph_data[i], axis_ap); draw_line(ax, ix0, iy0, ix1, iy1); } ax->gc = fgc; ix1 = grf_x(0.0, axis_ap); iy1 = grf_y(graph_fftr[0], axis_ap); xincr = 1.0 / (mus_float_t)GRAPH_SIZE; for (i = 1, x = xincr; i < GRAPH_SIZE; i++, x += xincr) { ix0 = ix1; iy0 = iy1; ix1 = grf_x(x, axis_ap); if (fft_log_magnitude(ss)) iy1 = grf_y(fp_dB(graph_fftr[i]), axis_ap); else iy1 = grf_y(graph_fftr[i], axis_ap); draw_line(ax, ix0, iy0, ix1, iy1); } cairo_pop_group_to_source(ss->cr); cairo_paint(ss->cr); free_cairo(ss->cr); ss->cr = NULL; } static void get_fft_window_data(void) { int i; mus_make_fft_window_with_window(fft_window(ss), GRAPH_SIZE, fft_window_beta(ss) * fft_beta_max(fft_window(ss)), fft_window_alpha(ss), graph_data); memset((void *)graph_fftr, 0, GRAPH_SIZE * 2 * sizeof(mus_float_t)); memset((void *)graph_ffti, 0, GRAPH_SIZE * 2 * sizeof(mus_float_t)); memcpy((void *)graph_fftr, (void *)graph_data, GRAPH_SIZE * sizeof(mus_float_t)); mus_spectrum(graph_fftr, graph_ffti, NULL, GRAPH_SIZE * 2, MUS_SPECTRUM_IN_DB); for (i = 0; i < GRAPH_SIZE; i++) graph_fftr[i] = (graph_fftr[i] + 80.0) / 80.0; /* min dB -80.0 */ } /* ---------------- transform size ---------------- */ static void chans_transform_size(chan_info *cp, mus_long_t size) { cp->transform_size = size; if (cp->fft) cp->fft->size = size; } static void size_browse_callback(const char *name, int row, void *data) { for_each_chan(force_fft_clear); in_set_transform_size(transform_sizes[row]); for_each_chan_with_mus_long_t(chans_transform_size, transform_size(ss)); for_each_chan(calculate_fft); if (fft_window_label) gtk_label_set_text(GTK_LABEL(fft_window_label), mus_fft_window_name(fft_window(ss))); } void set_transform_size(mus_long_t val) { for_each_chan(force_fft_clear); in_set_transform_size(val); for_each_chan_with_mus_long_t(chans_transform_size, val); if (transform_dialog) { int i; for (i = 0; i < NUM_TRANSFORM_SIZES; i++) if (transform_sizes[i] == val) { slist_select(size_list, i); slist_moveto(size_list, i); break; } } if (!(ss->graph_hook_active)) for_each_chan(calculate_fft); } /* ---------------- wavelet choice ---------------- */ static void chans_wavelet_type(chan_info *cp, int value) { cp->wavelet_type = value; } static void wavelet_browse_callback(const char *name, int row, void *data) { in_set_wavelet_type(row); for_each_chan_with_int(chans_wavelet_type, row); if (transform_type(ss) == WAVELET) for_each_chan(calculate_fft); } void set_wavelet_type(int val) { if (transform_dialog) { slist_select(wavelet_list, val); slist_moveto(wavelet_list, val); } in_set_wavelet_type(val); for_each_chan_with_int(chans_wavelet_type, val); if ((transform_type(ss) == WAVELET) && (!(ss->graph_hook_active))) for_each_chan(calculate_fft); } /* ---------------- window choice ---------------- */ #if GTK_CHECK_VERSION(3, 0, 0) /* this won't work in gtk2 because it requires the alpha field (GdkRGBA not defined) */ static color_t not_so_black; static void alpha_beta_alpha(mus_fft_window_t val) { #if (!GTK_CHECK_VERSION(3, 16, 0)) if (fft_window_beta_in_use(val)) gtk_widget_override_color(beta_label, GTK_STATE_FLAG_ACTIVE, (GdkRGBA *)(ss->black)); else gtk_widget_override_color(beta_label, GTK_STATE_FLAG_ACTIVE, (GdkRGBA *)not_so_black); if (fft_window_alpha_in_use(val)) gtk_widget_override_color(alpha_label, GTK_STATE_FLAG_ACTIVE, (GdkRGBA *)(ss->black)); else gtk_widget_override_color(alpha_label, GTK_STATE_FLAG_ACTIVE, (GdkRGBA *)not_so_black); #endif } #endif static void window_browse_callback(const char *name, int row, void *data) { in_set_fft_window((mus_fft_window_t)row); for_each_chan(calculate_fft); if (fft_window_label) gtk_label_set_text(GTK_LABEL(fft_window_label), mus_fft_window_name(fft_window(ss))); get_fft_window_data(); graph_redisplay(); #if GTK_CHECK_VERSION(3, 0, 0) alpha_beta_alpha(fft_window(ss)); #endif } void set_fft_window(mus_fft_window_t val) { in_set_fft_window(val); if (!(ss->graph_hook_active)) for_each_chan(calculate_fft); if ((transform_dialog) && (graph_drawer)) { slist_select(window_list, (int)val); slist_moveto(window_list, (int)val); if (fft_window_label) gtk_label_set_text(GTK_LABEL(fft_window_label), mus_fft_window_name(val)); get_fft_window_data(); graph_redisplay(); #if GTK_CHECK_VERSION(3, 0, 0) alpha_beta_alpha(val); #endif } } /* ---------------- transform type ---------------- */ static void chans_transform_type(chan_info *cp, int value) { cp->transform_type = value; } static void transform_browse_callback(const char *name, int row, void *data) { for_each_chan(force_fft_clear); in_set_transform_type(row); for_each_chan_with_int(chans_transform_type, row); for_each_chan(calculate_fft); } void make_transform_type_list(void) { if (transform_dialog) { int i, j, num; const char **transform_names; num = max_transform_type(); transform_names = (const char **)calloc(num, sizeof(char *)); for (i = 0, j = 0; i < num; i++) if (is_transform(i)) { set_transform_position(i, j); transform_names[j++] = transform_name(i); } if (!transform_list) { transform_list = slist_new_with_title_and_table_data("type", outer_table, transform_names, j, TABLE_ATTACH, 0, 3, 0, 4); transform_list->select_callback = transform_browse_callback; } else { slist_clear(transform_list); for (i = 0; i < j; i++) slist_append(transform_list, transform_names[i]); slist_select(transform_list, transform_type_to_position(transform_type(ss))); } free(transform_names); } } void set_transform_type(int val) { if (is_transform(val)) { if (!(ss->graph_hook_active)) for_each_chan(force_fft_clear); in_set_transform_type(val); for_each_chan_with_int(chans_transform_type, val); if (!(ss->graph_hook_active)) for_each_chan(calculate_fft); if (transform_dialog) slist_select(transform_list, transform_type_to_position(val)); } } /* ---------------- graph type (sonogram etc) ---------------- */ static void normal_fft_callback(GtkWidget *w, gpointer context) { if (ignore_callbacks) return; if (TOGGLE_BUTTON_ACTIVE(w)) in_set_transform_graph_type(GRAPH_ONCE); else in_set_transform_graph_type(GRAPH_AS_SONOGRAM); for_each_chan(calculate_fft); } static void sonogram_callback(GtkWidget *w, gpointer context) { if (ignore_callbacks) return; if (TOGGLE_BUTTON_ACTIVE(w)) in_set_transform_graph_type(GRAPH_AS_SONOGRAM); else in_set_transform_graph_type(GRAPH_ONCE); for_each_chan(calculate_fft); } static void spectrogram_callback(GtkWidget *w, gpointer context) { if (ignore_callbacks) return; if (TOGGLE_BUTTON_ACTIVE(w)) in_set_transform_graph_type(GRAPH_AS_SPECTROGRAM); else in_set_transform_graph_type(GRAPH_ONCE); for_each_chan(calculate_fft); } void set_transform_graph_type(graph_type_t val) { in_set_transform_graph_type(val); if (transform_dialog) switch (val) { case GRAPH_ONCE: set_toggle_button(normal_fft_button, true, false, NULL); break; case GRAPH_AS_SONOGRAM: set_toggle_button(sono_button, true, false, NULL); break; case GRAPH_AS_SPECTROGRAM: set_toggle_button(spectro_button, true, false, NULL); break; case GRAPH_AS_WAVOGRAM: break; } if (!(ss->graph_hook_active)) for_each_chan(calculate_fft); } /* ---------------- show peaks ---------------- */ static void map_show_transform_peaks(chan_info *cp, bool value) { cp->show_transform_peaks = value; } static void peaks_callback(GtkWidget *w, gpointer context) { bool val; val = (bool)(TOGGLE_BUTTON_ACTIVE(w)); in_set_show_transform_peaks(val); for_each_chan_with_bool(map_show_transform_peaks, val); for_each_chan(calculate_fft); } static void max_peaks_callback(GtkWidget *w, gpointer data) { int new_peaks; new_peaks = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(data)); set_max_transform_peaks(new_peaks); for_each_chan(calculate_fft); } void reflect_peaks_in_transform_dialog(void) { if (transform_dialog) gtk_spin_button_set_value(GTK_SPIN_BUTTON(peaks_txt), max_transform_peaks(ss)); } void set_show_transform_peaks(bool val) { in_set_show_transform_peaks(val); for_each_chan_with_bool(map_show_transform_peaks, val); if (transform_dialog) set_toggle_button(peaks_button, val, false, NULL); if (!(ss->graph_hook_active)) for_each_chan(calculate_fft); } /* ---------------- log magnitude ---------------- */ static void chans_fft_log_magnitude(chan_info *cp, bool value) { cp->fft_log_magnitude = value; cp->fft_changed = FFT_CHANGE_LOCKED; } void set_fft_log_magnitude(bool val) { in_set_fft_log_magnitude(val); for_each_chan_with_bool(chans_fft_log_magnitude, val); if (transform_dialog) set_toggle_button(db_button, val, false, NULL); if (!(ss->graph_hook_active)) for_each_chan(calculate_fft); } /* ---------------- dB ---------------- */ static void db_callback(GtkWidget *w, gpointer context) { bool val; val = (bool)(TOGGLE_BUTTON_ACTIVE(w)); in_set_fft_log_magnitude(val); graph_redisplay(); for_each_chan_with_bool(chans_fft_log_magnitude, val); for_each_chan(calculate_fft); } static void min_db_callback(GtkWidget *w, gpointer data) { mus_float_t new_db; new_db = gtk_spin_button_get_value(GTK_SPIN_BUTTON(data)); set_min_db(-new_db); } void reflect_min_db_in_transform_dialog(void) { if (transform_dialog) gtk_spin_button_set_value(GTK_SPIN_BUTTON(db_txt), (gfloat)(-(min_dB(ss)))); } /* ---------------- log frequency ---------------- */ static void chans_fft_log_frequency(chan_info *cp, bool value) { cp->fft_log_frequency = value; cp->fft_changed = FFT_CHANGE_LOCKED; } static void logfreq_callback(GtkWidget *w, gpointer context) { bool val; val = (bool)(TOGGLE_BUTTON_ACTIVE(w)); in_set_fft_log_frequency(val); for_each_chan_with_bool(chans_fft_log_frequency, val); for_each_chan(calculate_fft); } static void log_freq_callback(GtkWidget *w, gpointer data) { mus_float_t new_lfb; new_lfb = gtk_spin_button_get_value(GTK_SPIN_BUTTON(data)); set_log_freq_start(new_lfb); } void reflect_log_freq_start_in_transform_dialog(void) { if (transform_dialog) gtk_spin_button_set_value(GTK_SPIN_BUTTON(lf_txt), log_freq_start(ss)); } void set_fft_log_frequency(bool val) { in_set_fft_log_frequency(val); for_each_chan_with_bool(chans_fft_log_frequency, val); if (transform_dialog) set_toggle_button(logfreq_button, val, false, NULL); if (!(ss->graph_hook_active)) for_each_chan(calculate_fft); } /* ---------------- normalization ---------------- */ static void chans_transform_normalization(chan_info *cp, int value) { cp->transform_normalization = (fft_normalize_t)value; cp->fft_changed = FFT_CHANGE_LOCKED; } static void normalize_callback(GtkWidget *w, gpointer context) { fft_normalize_t choice; if (TOGGLE_BUTTON_ACTIVE(w)) choice = NORMALIZE_BY_CHANNEL; else choice = DONT_NORMALIZE; in_set_transform_normalization(choice); for_each_chan_with_int(chans_transform_normalization, (int)choice); for_each_chan(calculate_fft); } void set_transform_normalization(fft_normalize_t val) { in_set_transform_normalization(val); for_each_chan_with_int(chans_transform_normalization, (int)val); if (transform_dialog) set_toggle_button(normalize_button, (val != DONT_NORMALIZE), false, NULL); if (!(ss->graph_hook_active)) for_each_chan(calculate_fft); } /* ---------------- show selection ---------------- */ static void selection_callback(GtkWidget *w, gpointer context) { in_set_show_selection_transform(TOGGLE_BUTTON_ACTIVE(w)); for_each_chan(calculate_fft); } void set_show_selection_transform(bool show) { in_set_show_selection_transform(show); if (transform_dialog) set_toggle_button(selection_button, show, false, NULL); if (!(ss->graph_hook_active)) for_each_chan(calculate_fft); } /* ---------------- phases ---------------- */ static void chans_fft_with_phases(chan_info *cp, bool value) { cp->fft_with_phases = value; cp->fft_changed = FFT_CHANGE_LOCKED; } static void phases_callback(GtkWidget *w, gpointer context) { bool val; val = (bool)(TOGGLE_BUTTON_ACTIVE(w)); in_set_fft_with_phases(val); graph_redisplay(); for_each_chan_with_bool(chans_fft_with_phases, val); for_each_chan(calculate_fft); } void set_fft_with_phases(bool val) { in_set_fft_with_phases(val); for_each_chan_with_bool(chans_fft_with_phases, val); if (!(ss->graph_hook_active)) for_each_chan(calculate_fft); } /* ---------------- beta ---------------- */ static void beta_callback(GtkAdjustment *adj, gpointer context) { in_set_fft_window_beta((mus_float_t)(ADJUSTMENT_VALUE(adj))); chans_field(FCP_BETA, (mus_float_t)(ADJUSTMENT_VALUE(adj))); if (fft_window_beta_in_use(fft_window(ss))) { get_fft_window_data(); graph_redisplay(); if (transform_type(ss) == FOURIER) for_each_chan(calculate_fft); } } void set_fft_window_beta(mus_float_t val) { in_set_fft_window_beta(val); chans_field(FCP_BETA, val); if (transform_dialog) { ADJUSTMENT_SET_VALUE(beta_adj, val); get_fft_window_data(); graph_redisplay(); } if (!(ss->graph_hook_active)) for_each_chan(calculate_fft); } /* ---------------- alpha ---------------- */ static void alpha_callback(GtkAdjustment *adj, gpointer context) { in_set_fft_window_alpha((mus_float_t)(ADJUSTMENT_VALUE(adj))); chans_field(FCP_ALPHA, (mus_float_t)(ADJUSTMENT_VALUE(adj))); if (fft_window_alpha_in_use(fft_window(ss))) { get_fft_window_data(); graph_redisplay(); if (transform_type(ss) == FOURIER) for_each_chan(calculate_fft); } } void set_fft_window_alpha(mus_float_t val) { in_set_fft_window_alpha(val); chans_field(FCP_ALPHA, val); if (transform_dialog) { ADJUSTMENT_SET_VALUE(alpha_adj, val); get_fft_window_data(); graph_redisplay(); } if (!(ss->graph_hook_active)) for_each_chan(calculate_fft); } /* ---------------- spectrum start/end ---------------- */ static void chans_spectrum_changed(chan_info *cp) { cp->fft_changed = FFT_CHANGE_LOCKED; update_graph(cp); } static void set_spectrum_start_scale(mus_float_t val) { ADJUSTMENT_SET_VALUE(spectrum_start_adj, val); } static void set_spectrum_end_scale(mus_float_t val) { ADJUSTMENT_SET_VALUE(spectrum_end_adj, val); } static void check_spectrum_start(mus_float_t end) { /* don't display chans, but do reset if necessary */ if (spectrum_start(ss) > end) { in_set_spectrum_start(end); if (transform_dialog) set_spectrum_start_scale(end); chans_field(FCP_SPECTRUM_START, end); } } static void check_spectrum_end(mus_float_t start) { /* don't display chans, but do reset if necessary */ if (spectrum_end(ss) < start) { in_set_spectrum_end(start); if (transform_dialog) set_spectrum_end_scale(start); chans_field(FCP_SPECTRUM_END, start); } } void set_spectrum_start(mus_float_t val) { if (transform_dialog) set_spectrum_start_scale(val); in_set_spectrum_start(val); check_spectrum_end(val); chans_field(FCP_SPECTRUM_START, val); for_each_chan(chans_spectrum_changed); } void set_spectrum_end(mus_float_t val) { if (transform_dialog) set_spectrum_end_scale(val); in_set_spectrum_end(val); check_spectrum_start(val); chans_field(FCP_SPECTRUM_END, val); for_each_chan(chans_spectrum_changed); } static void spectrum_start_callback(GtkAdjustment *adj, gpointer context) { mus_float_t start; start = ADJUSTMENT_VALUE(adj); in_set_spectrum_start(start); check_spectrum_end(start); chans_field(FCP_SPECTRUM_START, start); for_each_chan(chans_spectrum_changed); } static void spectrum_end_callback(GtkAdjustment *adj, gpointer context) { mus_float_t end; end = ADJUSTMENT_VALUE(adj); in_set_spectrum_end(end); check_spectrum_start(end); chans_field(FCP_SPECTRUM_END, end); for_each_chan(chans_spectrum_changed); } /* ---------------- dialog buttons ---------------- */ static gboolean graph_configure_callback(GtkWidget *w, GdkEventConfigure *ev, gpointer data) { graph_redisplay(); return(false); } static gboolean graph_expose_callback(GtkWidget *w, GdkEventExpose *ev, gpointer data) { graph_redisplay(); return(false); } static void dismiss_transform_callback(GtkWidget *w, gpointer context) { gtk_widget_hide(transform_dialog); } static void color_orientation_transform_callback(GtkWidget *w, gpointer context) { make_color_orientation_dialog(true); } static gint delete_transform_dialog(GtkWidget *w, GdkEvent *event, gpointer context) { gtk_widget_hide(transform_dialog); return(true); } static void help_transform_callback(GtkWidget *w, gpointer context) { transform_dialog_help(); } gboolean spin_button_focus_callback(GtkWidget *w, GdkEventCrossing *ev, gpointer unknown) { widget_modify_base(w, GTK_STATE_NORMAL, ss->white); return(false); } gboolean spin_button_unfocus_callback(GtkWidget *w, GdkEventCrossing *ev, gpointer unknown) { widget_modify_base(w, GTK_STATE_NORMAL, ss->basic_color); return(false); } #define RIGHT_SEP_SIZE 10 GtkWidget *make_transform_dialog(bool managed) { bool need_callback = false, need_moveto = true; if (!transform_dialog) { GtkWidget *buttons; GtkWidget *display_frame, *help_button, *dismiss_button; GtkWidget *color_button; GtkWidget *se_box, *se_frame, *se_label; GtkWidget *end_box, *end_label, *start_box, *start_label; #if GTK_CHECK_VERSION(3, 0, 0) not_so_black = rgb_to_color(0.0, 0.0, 0.0); not_so_black->alpha = 0.5; #endif transform_dialog = snd_gtk_dialog_new(); #if GTK_CHECK_VERSION(3, 14, 0) gtk_window_set_transient_for(GTK_WINDOW(transform_dialog), GTK_WINDOW(MAIN_SHELL(ss))); #endif gtk_widget_set_name(transform_dialog, "fft_dialog"); SG_SIGNAL_CONNECT(transform_dialog, "delete_event", delete_transform_dialog, NULL); gtk_window_set_title(GTK_WINDOW(transform_dialog), "Transform Options"); sg_make_resizable(transform_dialog); gtk_container_set_border_width(GTK_CONTAINER(transform_dialog), 6); gtk_widget_realize(transform_dialog); /* gtk_window_resize(GTK_WINDOW(transform_dialog), 400, 500); */ help_button = gtk_dialog_add_button(GTK_DIALOG(transform_dialog), "Help", GTK_RESPONSE_NONE); dismiss_button = gtk_dialog_add_button(GTK_DIALOG(transform_dialog), "Go away", GTK_RESPONSE_NONE); color_button = gtk_dialog_add_button(GTK_DIALOG(transform_dialog), "Color/Orientation", GTK_RESPONSE_NONE); gtk_widget_set_name(help_button, "dialog_button"); gtk_widget_set_name(dismiss_button, "dialog_button"); gtk_widget_set_name(color_button, "dialog_button"); #if GTK_CHECK_VERSION(3, 0, 0) add_highlight_button_style(dismiss_button); add_highlight_button_style(color_button); add_highlight_button_style(help_button); #endif SG_SIGNAL_CONNECT(dismiss_button, "clicked", dismiss_transform_callback, NULL); SG_SIGNAL_CONNECT(color_button, "clicked", color_orientation_transform_callback, NULL); SG_SIGNAL_CONNECT(help_button, "clicked", help_transform_callback, NULL); gtk_widget_show(dismiss_button); gtk_widget_show(color_button); gtk_widget_show(help_button); outer_table = gtk_table_new(16, 11, false); /* rows cols */ gtk_container_add(GTK_CONTAINER(DIALOG_CONTENT_AREA(transform_dialog)), outer_table); gtk_table_set_row_spacings(GTK_TABLE(outer_table), 16); gtk_table_set_col_spacings(GTK_TABLE(outer_table), 16); gtk_table_set_homogeneous(GTK_TABLE(outer_table), true); /* now 8 boxes within the main box: type (list) | size (list) | display (button column) wavelet (list) | window (list) | graph (fft?) of current window alpha/beta ========================== spectrum start/end ================== */ /* TYPE */ make_transform_type_list(); /* SIZE */ size_list = slist_new_with_title_and_table_data("size", outer_table, transform_size_names, NUM_TRANSFORM_SIZES, TABLE_ATTACH, 3, 6, 0, 6); size_list->select_callback = size_browse_callback; /* DISPLAY */ display_frame = gtk_frame_new(NULL); gtk_table_attach_defaults(GTK_TABLE(outer_table), display_frame, 6, 11, 0, 7); gtk_frame_set_shadow_type(GTK_FRAME(display_frame), GTK_SHADOW_IN); { GtkWidget *label, *vbb, *hb; GtkWidget *pk_lab, *db_lab, *lf_lab; GtkAdjustment *pk_vals, *db_vals, *lf_vals; GtkWidget *vb, *sep1, *sep2; #define DISPLAY_MARGIN 2 #define LEFT_MARGIN 8 vbb = gtk_vbox_new(false, 6); gtk_container_add(GTK_CONTAINER(display_frame), vbb); gtk_widget_show(vbb); label = snd_gtk_highlight_label_new("display"); gtk_box_pack_start(GTK_BOX(vbb), label, false, false, 0); gtk_widget_show(label); hb = gtk_hbox_new(false, 15); gtk_box_pack_start(GTK_BOX(vbb), hb, false, false, 0); gtk_widget_show(hb); buttons = gtk_vbox_new(false, 0); gtk_container_add(GTK_CONTAINER(hb), buttons); normal_fft_button = gtk_radio_button_new_with_label(NULL, "single transform"); widget_set_margin_left(normal_fft_button, LEFT_MARGIN); add_check_button_style(normal_fft_button); gtk_box_pack_start(GTK_BOX(buttons), normal_fft_button, false, false, DISPLAY_MARGIN); gtk_widget_show(normal_fft_button); SG_SIGNAL_CONNECT(normal_fft_button, "clicked", normal_fft_callback, NULL); sono_button = gtk_radio_button_new_with_label(gtk_radio_button_get_group(GTK_RADIO_BUTTON(normal_fft_button)), "sonogram"); widget_set_margin_left(sono_button, LEFT_MARGIN); add_check_button_style(sono_button); gtk_box_pack_start(GTK_BOX(buttons), sono_button, false, false, DISPLAY_MARGIN); gtk_widget_show(sono_button); SG_SIGNAL_CONNECT(sono_button, "clicked", sonogram_callback, NULL); spectro_button = gtk_radio_button_new_with_label(gtk_radio_button_get_group(GTK_RADIO_BUTTON(normal_fft_button)), "spectrogram"); widget_set_margin_left(spectro_button, LEFT_MARGIN); add_check_button_style(spectro_button); gtk_box_pack_start(GTK_BOX(buttons), spectro_button, false, false, DISPLAY_MARGIN); gtk_widget_show(spectro_button); SG_SIGNAL_CONNECT(spectro_button, "clicked", spectrogram_callback, NULL); peaks_button = gtk_check_button_new_with_label("peaks"); widget_set_margin_left(peaks_button, LEFT_MARGIN); add_check_button_style(peaks_button); gtk_box_pack_start(GTK_BOX(buttons), peaks_button, false, false, DISPLAY_MARGIN); gtk_widget_show(peaks_button); SG_SIGNAL_CONNECT(peaks_button, "toggled", peaks_callback, NULL); db_button = gtk_check_button_new_with_label("dB"); widget_set_margin_left(db_button, LEFT_MARGIN); add_check_button_style(db_button); gtk_box_pack_start(GTK_BOX(buttons), db_button, false, false, DISPLAY_MARGIN); gtk_widget_show(db_button); SG_SIGNAL_CONNECT(db_button, "toggled", db_callback, NULL); logfreq_button = gtk_check_button_new_with_label("log freq"); widget_set_margin_left(logfreq_button, LEFT_MARGIN); add_check_button_style(logfreq_button); gtk_box_pack_start(GTK_BOX(buttons), logfreq_button, false, false, DISPLAY_MARGIN); gtk_widget_show(logfreq_button); SG_SIGNAL_CONNECT(logfreq_button, "toggled", logfreq_callback, NULL); normalize_button = gtk_check_button_new_with_label("normalize"); widget_set_margin_left(normalize_button, LEFT_MARGIN); add_check_button_style(normalize_button); gtk_box_pack_start(GTK_BOX(buttons), normalize_button, false, false, DISPLAY_MARGIN); gtk_widget_show(normalize_button); SG_SIGNAL_CONNECT(normalize_button, "toggled", normalize_callback, NULL); selection_button = gtk_check_button_new_with_label("selection"); widget_set_margin_left(selection_button, LEFT_MARGIN); add_check_button_style(selection_button); gtk_box_pack_start(GTK_BOX(buttons), selection_button, false, false, DISPLAY_MARGIN); gtk_widget_show(selection_button); SG_SIGNAL_CONNECT(selection_button, "toggled", selection_callback, NULL); phases_button = gtk_check_button_new_with_label("with phases"); widget_set_margin_left(phases_button, LEFT_MARGIN); add_check_button_style(phases_button); gtk_box_pack_end(GTK_BOX(buttons), phases_button, false, false, DISPLAY_MARGIN); gtk_widget_show(phases_button); SG_SIGNAL_CONNECT(phases_button, "toggled", phases_callback, NULL); vb = gtk_vbox_new(false, 0); gtk_container_add(GTK_CONTAINER(hb), vb); pk_lab = snd_gtk_highlight_label_new("max peaks"); gtk_box_pack_start(GTK_BOX(vb), pk_lab, false, false, 0); gtk_widget_show(pk_lab); pk_vals = (GtkAdjustment *)gtk_adjustment_new(max_transform_peaks(ss), 2, 1000, 2, 10, 0); peaks_txt = gtk_spin_button_new(GTK_ADJUSTMENT(pk_vals), 0.0, 0); gtk_box_pack_start(GTK_BOX(vb), peaks_txt, false, false, 0); gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(peaks_txt), true); SG_SIGNAL_CONNECT(pk_vals, "value_changed", max_peaks_callback, (gpointer)peaks_txt); SG_SIGNAL_CONNECT(peaks_txt, "enter_notify_event", spin_button_focus_callback, NULL); SG_SIGNAL_CONNECT(peaks_txt, "leave_notify_event", spin_button_unfocus_callback, NULL); gtk_widget_show(peaks_txt); sep1 = gtk_vseparator_new(); gtk_box_pack_start(GTK_BOX(vb), sep1, false, false, RIGHT_SEP_SIZE); gtk_widget_show(sep1); db_lab = snd_gtk_highlight_label_new("min dB"); gtk_box_pack_start(GTK_BOX(vb), db_lab, false, false, 0); gtk_widget_show(db_lab); db_vals = (GtkAdjustment *)gtk_adjustment_new((int)(-(min_dB(ss))), 2, 1000, 2, 10, 0); /* can't be negative!! */ db_txt = gtk_spin_button_new(GTK_ADJUSTMENT(db_vals), 0.0, 0); gtk_box_pack_start(GTK_BOX(vb), db_txt, false, false, 0); gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(db_txt), true); SG_SIGNAL_CONNECT(db_vals, "value_changed", min_db_callback, (gpointer)db_txt); SG_SIGNAL_CONNECT(db_txt, "enter_notify_event", spin_button_focus_callback, NULL); SG_SIGNAL_CONNECT(db_txt, "leave_notify_event", spin_button_unfocus_callback, NULL); gtk_widget_show(db_txt); sep2 = gtk_vseparator_new(); gtk_box_pack_start(GTK_BOX(vb), sep2, false, false, RIGHT_SEP_SIZE); gtk_widget_show(sep2); lf_lab = snd_gtk_highlight_label_new("log freq start"); gtk_box_pack_start(GTK_BOX(vb), lf_lab, false, false, 0); gtk_widget_show(lf_lab); lf_vals = (GtkAdjustment *)gtk_adjustment_new((int)(log_freq_start(ss)), 1, 1000, 1, 10, 0); lf_txt = gtk_spin_button_new(GTK_ADJUSTMENT(lf_vals), 0.0, 0); gtk_box_pack_start(GTK_BOX(vb), lf_txt, false, false, 0); gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(lf_txt), true); SG_SIGNAL_CONNECT(lf_vals, "value_changed", log_freq_callback, (gpointer)lf_txt); SG_SIGNAL_CONNECT(lf_txt, "enter_notify_event", spin_button_focus_callback, NULL); SG_SIGNAL_CONNECT(lf_txt, "leave_notify_event", spin_button_unfocus_callback, NULL); gtk_widget_show(lf_txt); gtk_widget_show(vb); } gtk_widget_show(buttons); gtk_widget_show(display_frame); /* WINDOWS */ window_list = slist_new_with_title_and_table_data("window", outer_table, (const char **)mus_fft_window_names(), MUS_NUM_FFT_WINDOWS, TABLE_ATTACH, 0, 3, 6, 12); window_list->select_callback = window_browse_callback; /* WAVELETS */ wavelet_list = slist_new_with_title_and_table_data("wavelet", outer_table, (const char **)wavelet_names(), NUM_WAVELETS, TABLE_ATTACH, 3, 6, 6, 12); wavelet_list->select_callback = wavelet_browse_callback; /* ALPHA/BETA */ { GtkWidget *alpha_box, *beta_box; GtkWidget *alpha_scale, *beta_scale, *ab_box, *ab_frame, *ab_label; ab_frame = gtk_frame_new(NULL); gtk_table_attach_defaults(GTK_TABLE(outer_table), ab_frame, 0, 6, 12, 14); gtk_frame_set_shadow_type(GTK_FRAME(ab_frame), GTK_SHADOW_IN); ab_box = gtk_vbox_new(false, 2); gtk_container_add(GTK_CONTAINER(ab_frame), ab_box); ab_label = snd_gtk_highlight_label_new("window parameter"); gtk_box_pack_start(GTK_BOX(ab_box), ab_label, false, false, 1); gtk_widget_show(ab_label); alpha_box = gtk_hbox_new(false, 0); gtk_box_pack_start(GTK_BOX(ab_box), alpha_box, false, false, 1); gtk_widget_show(alpha_box); alpha_label = gtk_label_new("alpha: "); gtk_box_pack_start(GTK_BOX(alpha_box), alpha_label, false, false, 8); gtk_widget_show(alpha_label); alpha_adj = (GtkAdjustment *)gtk_adjustment_new(0.0, 0.0, 1.01, 0.001, 0.01, .01); alpha_scale = gtk_hscale_new(GTK_ADJUSTMENT(alpha_adj)); UNSET_CAN_FOCUS(alpha_scale); gtk_range_set_update_policy(GTK_RANGE(GTK_SCALE(alpha_scale)), GTK_UPDATE_CONTINUOUS); gtk_scale_set_digits(GTK_SCALE(alpha_scale), 2); gtk_scale_set_value_pos(GTK_SCALE(alpha_scale), GTK_POS_LEFT); gtk_scale_set_draw_value(GTK_SCALE(alpha_scale), true); SG_SIGNAL_CONNECT(alpha_adj, "value_changed", alpha_callback, NULL); SG_SIGNAL_CONNECT(alpha_scale, "format-value", scale_double_format_callback, NULL); gtk_box_pack_start(GTK_BOX(alpha_box), alpha_scale, true, true, 1); beta_box = gtk_hbox_new(false, 0); gtk_box_pack_start(GTK_BOX(ab_box), beta_box, false, false, 1); gtk_widget_show(beta_box); beta_label = gtk_label_new("beta: "); gtk_box_pack_start(GTK_BOX(beta_box), beta_label, false, false, 8); gtk_widget_show(beta_label); beta_adj = (GtkAdjustment *)gtk_adjustment_new(0.0, 0.0, 1.01, 0.001, 0.01, .01); beta_scale = gtk_hscale_new(GTK_ADJUSTMENT(beta_adj)); UNSET_CAN_FOCUS(beta_scale); gtk_range_set_update_policy(GTK_RANGE(GTK_SCALE(beta_scale)), GTK_UPDATE_CONTINUOUS); gtk_scale_set_digits(GTK_SCALE(beta_scale), 2); gtk_scale_set_value_pos(GTK_SCALE(beta_scale), GTK_POS_LEFT); gtk_scale_set_draw_value(GTK_SCALE(beta_scale), true); SG_SIGNAL_CONNECT(beta_adj, "value_changed", beta_callback, NULL); SG_SIGNAL_CONNECT(beta_scale, "format-value", scale_double_format_callback, NULL); gtk_box_pack_start(GTK_BOX(beta_box), beta_scale, true, true, 1); gtk_widget_show(alpha_scale); gtk_widget_show(beta_scale); gtk_widget_show(ab_box); gtk_widget_show(ab_frame); } /* SPECTRUM_START/END */ se_frame = gtk_frame_new(NULL); gtk_table_attach_defaults(GTK_TABLE(outer_table), se_frame, 0, 6, 14, 16); gtk_frame_set_shadow_type(GTK_FRAME(se_frame), GTK_SHADOW_IN); se_box = gtk_vbox_new(false, 2); gtk_container_add(GTK_CONTAINER(se_frame), se_box); se_label = snd_gtk_highlight_label_new("spectrum start/end"); gtk_box_pack_start(GTK_BOX(se_box), se_label, false, false, 1); gtk_widget_show(se_label); start_box = gtk_hbox_new(false, 0); gtk_box_pack_start(GTK_BOX(se_box), start_box, false, false, 1); gtk_widget_show(start_box); start_label = gtk_label_new("start: "); gtk_box_pack_start(GTK_BOX(start_box), start_label, false, false, 8); gtk_widget_show(start_label); spectrum_start_adj = (GtkAdjustment *)gtk_adjustment_new(0.0, 0.0, 1.01, 0.001, 0.01, .01); spectrum_start_scale = gtk_hscale_new(GTK_ADJUSTMENT(spectrum_start_adj)); UNSET_CAN_FOCUS(spectrum_start_scale); gtk_range_set_update_policy(GTK_RANGE(GTK_SCALE(spectrum_start_scale)), GTK_UPDATE_CONTINUOUS); gtk_scale_set_digits(GTK_SCALE(spectrum_start_scale), 2); gtk_scale_set_value_pos(GTK_SCALE(spectrum_start_scale), GTK_POS_LEFT); gtk_scale_set_draw_value(GTK_SCALE(spectrum_start_scale), true); SG_SIGNAL_CONNECT(spectrum_start_adj, "value_changed", spectrum_start_callback, NULL); SG_SIGNAL_CONNECT(spectrum_start_scale, "format-value", scale_double_format_callback, NULL); gtk_box_pack_start(GTK_BOX(start_box), spectrum_start_scale, true, true, 1); end_box = gtk_hbox_new(false, 0); gtk_box_pack_start(GTK_BOX(se_box), end_box, false, false, 1); gtk_widget_show(end_box); end_label = gtk_label_new("end: "); gtk_box_pack_start(GTK_BOX(end_box), end_label, false, false, 8); gtk_widget_show(end_label); spectrum_end_adj = (GtkAdjustment *)gtk_adjustment_new(0.0, 0.0, 1.01, 0.001, 0.01, .01); spectrum_end_scale = gtk_hscale_new(GTK_ADJUSTMENT(spectrum_end_adj)); UNSET_CAN_FOCUS(spectrum_end_scale); gtk_range_set_update_policy(GTK_RANGE(GTK_SCALE(spectrum_end_scale)), GTK_UPDATE_CONTINUOUS); gtk_scale_set_digits(GTK_SCALE(spectrum_end_scale), 2); gtk_scale_set_value_pos(GTK_SCALE(spectrum_end_scale), GTK_POS_LEFT); gtk_scale_set_draw_value(GTK_SCALE(spectrum_end_scale), true); SG_SIGNAL_CONNECT(spectrum_end_adj, "value_changed", spectrum_end_callback, NULL); SG_SIGNAL_CONNECT(spectrum_end_scale, "format-value", scale_double_format_callback, NULL); gtk_box_pack_start(GTK_BOX(end_box), spectrum_end_scale, true, true, 1); gtk_widget_show(spectrum_start_scale); gtk_widget_show(spectrum_end_scale); gtk_widget_show(se_box); gtk_widget_show(se_frame); /* GRAPH */ { GtkWidget *graph_frame, *g_vbox; graph_frame = gtk_frame_new(NULL); gtk_table_attach_defaults(GTK_TABLE(outer_table), graph_frame, 6, 11, 7, 16); gtk_frame_set_label_align(GTK_FRAME(graph_frame), 0.5, 0.0); gtk_frame_set_shadow_type(GTK_FRAME(graph_frame), GTK_SHADOW_IN); g_vbox = gtk_vbox_new(false, 2); gtk_container_add(GTK_CONTAINER(graph_frame), g_vbox); fft_window_label = snd_gtk_highlight_label_new(mus_fft_window_name(fft_window(ss))); gtk_box_pack_start(GTK_BOX(g_vbox), fft_window_label, false, false, 1); gtk_widget_show(fft_window_label); graph_drawer = gtk_drawing_area_new(); gtk_box_pack_end(GTK_BOX(g_vbox), graph_drawer, true, true, 0); widget_modify_bg(graph_drawer, GTK_STATE_NORMAL, ss->white); gtk_widget_show(g_vbox); fgc = gc_new(); gc_set_background(fgc, ss->white); gc_set_foreground(fgc, ss->enved_waveform_color); fft_gc = gc_new(); gc_set_background(fft_gc, ss->white); gc_set_foreground(fft_gc, ss->black); gtk_widget_show(graph_drawer); gtk_widget_show(graph_frame); } ignore_callbacks = true; if (transform_graph_type(ss) == GRAPH_ONCE) set_toggle_button(normal_fft_button, true, false, NULL); if (transform_graph_type(ss) == GRAPH_AS_SONOGRAM) set_toggle_button(sono_button, true, false, NULL); if (transform_graph_type(ss) == GRAPH_AS_SPECTROGRAM) set_toggle_button(spectro_button, true, false, NULL); ignore_callbacks = false; set_toggle_button(peaks_button, show_transform_peaks(ss), false, NULL); set_toggle_button(db_button, fft_log_magnitude(ss), false, NULL); set_toggle_button(logfreq_button, fft_log_frequency(ss), false, NULL); set_toggle_button(normalize_button, (transform_normalization(ss) != DONT_NORMALIZE), false, NULL); set_toggle_button(selection_button, show_selection_transform(ss), false, NULL); set_toggle_button(phases_button, fft_with_phases(ss), false, NULL); if (spectrum_start(ss) != 0.0) set_spectrum_start_scale(spectrum_start(ss)); if (spectrum_end(ss) != 0.0) set_spectrum_end_scale(spectrum_end(ss)); if (fft_window_alpha(ss) != 0.0) ADJUSTMENT_SET_VALUE(alpha_adj, fft_window_alpha(ss)); if (fft_window_beta(ss) != 0.0) ADJUSTMENT_SET_VALUE(beta_adj, fft_window_beta(ss)); #if GTK_CHECK_VERSION(3, 0, 0) alpha_beta_alpha(fft_window(ss)); #endif need_callback = true; gtk_widget_show(outer_table); set_dialog_widget(TRANSFORM_DIALOG, transform_dialog); } else { raise_dialog(transform_dialog); need_moveto = false; } if (managed) { gtk_widget_show(transform_dialog); if (need_moveto) { int i; slist_select(window_list, (int)fft_window(ss)); slist_moveto(window_list, (int)fft_window(ss)); slist_select(wavelet_list, wavelet_type(ss)); slist_moveto(wavelet_list, wavelet_type(ss)); slist_select(transform_list, transform_type_to_position(transform_type(ss))); for (i = 0; i < NUM_TRANSFORM_SIZES; i++) if (transform_sizes[i] == transform_size(ss)) { slist_select(size_list, i); slist_moveto(size_list, i); break; } } } if (need_callback) { get_fft_window_data(); SG_SIGNAL_CONNECT(graph_drawer, DRAW_SIGNAL, graph_expose_callback, NULL); SG_SIGNAL_CONNECT(graph_drawer, "configure_event", graph_configure_callback, NULL); } return(transform_dialog); } bool transform_dialog_is_active(void) { return((transform_dialog) && (widget_is_active(transform_dialog))); } snd-16.1/extensions.fs0000644000076400007640000006646712462674025013117 0ustar bilbil\ extensions.fs -- extensions.scm -> extensions.fs \ Translator/Author: Michael Scholz \ Created: 05/12/18 19:21:00 \ Changed: 14/12/03 17:15:55 \ \ @(#)extensions.fs 1.50 12/3/14 \ With comments and doc strings from extensions.scm. \ \ remove-sound-property ( key :optional snd -- props ) \ set-sound-property-save-state-ignore ( key snd -- val ) \ remove-channel-property ( key :optional snd chn -- props ) \ set-channel-property-save-state-ignore ( key snd chn -- val ) \ channel-sync ( snd chn -- val ) \ set-channel-sync ( snd chn val -- ) \ \ normalize-mix ( filename beg in-chn snd chn -- scl ) \ enveloped-mix ( filename beg env -- ) \ map-sound-files ( func :optional dir -- lst ) \ for-each-sound-file ( func :optional dir -- ) \ match-sound-files ( func :optional dir -- ary ) \ selection-members ( -- array-of-arrays ) \ make-selection ( :optional beg end snd chn -- ) \ \ mix-channel ( fdata :optional beg dur s c edp -- val ) \ insert-channel ( fdata :optional beg 0 dur s c edp -- val ) \ redo-channel ( :optional edits snd chn -- ) \ undo-channel ( :optional edits snd chn -- ) \ any-env-channel ( en fc :optional beg dur s c edp or -- val ) \ sine-ramp ( r0 r1 :optional beg dur s c edpos -- val ) \ sine-env-channel ( en :optional beg dur s c edpos -- val ) \ blackman4-ramp ( r0 r1 :optional beg dur s c ep -- val ) \ blackman4-env-channel ( en :optional beg dur s c ep -- val ) \ ramp-squared ( r0 r1 :optional sym beg dur s c ep -- val ) \ env-squared-channel ( en :optional sym beg dur s c ep -- val ) \ ramp-expt ( rmp0 rmp1 exponent ... ) \ env-expt-channel ( en exponent ... ) \ offset-channel ( amount :optional beg dur s c ep -- val ) \ offset-sound ( offset :optional beg dur snd -- ) \ pad-sound ( beg dur :optional snd -- ) \ dither-channel ( :optional amount beg dur s c ep -- val ) \ dither-sound ( :optional amount beg dur s -- ) \ contrast-channel ( index :optional beg dur s c ep -- val ) \ contrast-sound ( index :optional beg dur snd -- ) \ scale-sound ( scl :optional beg dur snd -- ) \ normalize-sound ( amp :optional beg dur snd -- ) \ \ channels= ( s1 c1 s2 c2 :optional allowable-diff -- f ) \ channels-equal? ( s1 c1 s2 c2 :optional allowable-diff -- f ) \ mono->stereo ( new-name snd1 chn1 snd2 chn2 -- snd ) \ mono-files->stereo ( new-name chan1-name chan2-name -- snd ) \ stereo->mono ( orig-s c1-name c2-name -- snd0 snd1 ) \ \ with-reopen-menu ( -- ) \ with-buffers-menu ( -- ) \ \ if-cursor-follows-play-it-stays-where-play-stopped ( :optional enable -- ) require clm require examp \ ;;; -------- sound-property : remove-sound-property <{ key :optional snd #f -- props }> doc" Remove key-value pair in the given sound's \ property list and return altered list." snd sound-properties key array-assoc-remove! ; \ 'save-state-ignore key snd set-sound-property : set-sound-property-save-state-ignore <{ key :optional snd #f -- val }> 'save-state-ignore snd sound-property { ign } ign array? if ign key array-push else #( 'save-state-ignore key ) then to ign 'save-state-ignore ign snd set-sound-property ; \ ;;; -------- channel-property : remove-channel-property <{ key :optional snd #f chn #f -- props }> doc" Remove key-value pair in the given channel's \ property list and return altered list." snd chn channel-properties key array-assoc-remove! ; : set-channel-property-save-state-ignore <{ key :optional snd #f chn #f -- val }> 'save-state-ignore snd chn channel-property { ign } ign array? if ign key array-push else #( 'save-state-ignore key ) then to ign 'save-state-ignore ign snd chn set-channel-property ; : channel-sync { snd chn -- val } 'sync snd chn channel-property ; : set-channel-sync { snd chn val -- } 'sync val snd chn set-channel-property drop ; \ ;;; -------- mix with result at original peak amp : normalize-mix ( filename beg in-chn snd chn -- scl ) doc" It is like mix but the mix result has same peak \ amp as unmixed SND/CHN (returns scaler)." { filename beg in-chan snd chn } snd chn #f maxamp { original-maxamp } filename beg in-chan snd chn undef undef undef mix drop snd chn #f maxamp { new-maxamp } original-maxamp new-maxamp f<> if original-maxamp new-maxamp f/ { scaler } snd sync { old-sync } 0 snd set-sync drop scaler snd chn scale-by drop old-sync snd set-sync drop scaler else 1.0 then ; \ ;;;-------- mix with envelope on mixed-in file \ ;;; \ ;;; there are lots of ways to do this; this version uses functions \ ;;; from Snd, CLM, and Sndlib. hide : em-cb { amp-env rd -- prc; y self -- val } 1 proc-create ( prc ) amp-env , rd , does> { y self -- val } self @ { amp-env } self cell+ @ { rd } amp-env env rd readin f* y f+ ; set-current : enveloped-mix ( filename beg en -- ) doc" Mix FILENAME starting at BEG with amplitude envelope EN.\n\ \"pistol.snd\" 0 #( 0 0 1 1 2 0 ) enveloped-mix." { filename beg en } filename framples { len } :envelope en :length len make-env { amp-env } filename make-readin { rd } amp-env rd em-cb beg len map-channel drop ; previous \ ;;; -------- map-sound-files, match-sound-files \ ;;; \ ;;; apply a function to each sound in dir \ ;;; \ ;;; (map-sound-files (lambda (n) (if (> (mus-sound-duration n) 10.0) \ ;;; (snd-print n)))) : map-sound-files <{ func :optional dir "." -- lst }> doc" Apply FUNC to each sound file in DIR." dir sound-files-in-directory map func #( *key* ) run-proc end-map ; \ lambda: <{ n -- str|#f }> \ n mus-sound-duration 10.0 f> if \ n snd-print ( n remains on stack ) \ cr \ else \ #f \ then \ ; map-sound-files : for-each-sound-file <{ func :optional dir "." -- }> doc" Apply FUNC to each sound file in DIR." dir sound-files-in-directory each { f } func #( f ) run-proc drop end-each ; 0 [if] "/home/bil/sf" value loop-path lambda: <{ n -- }> loop-path "/" $+ n $+ <'> mus-sound-loop-info #t nil fth-catch if stack-reset else ( loop-list ) empty? unless n snd-print drop cr then then ; loop-path for-each-sound-file [then] : match-sound-files <{ func :optional dir "." -- ary }> doc" Apply FUNC to each sound file in DIR and \ returns an array of files for which FUNC does not return #f." #() { matches } dir sound-files-in-directory each { f } func #( f ) run-proc if matches f array-push drop then end-each matches ; \ lambda: <{ n -- f }> /\.(wav?|snd)$/ n regexp-match ; "." match-sound-files \ ;;; -------- selection-members \ ;;; \ ;;; returns a list of lists of (snd chn): channels in current selection : selection-members ( -- array-of-lists ) doc" Return an array of lists of #( snd chn ) indicating \ the channels participating in the current selection." #() { sndlist } undef selection? if sounds each { snd } snd channels 0 ?do snd i selection-member? if sndlist #( snd i ) array-push drop then loop end-each then sndlist ; \ ;;; -------- make-selection \ ;;; \ ;;; the regularized form of this would use dur not end hide : add-chan-to-selection { beg end snd chn -- } beg integer? unless 0 to beg then end integer? if end 1+ else snd chn #f framples then beg - to end #t snd chn set-selection-member? drop beg snd chn set-selection-position drop end snd chn set-selection-framples drop ; set-current : make-selection <{ :optional beg 0 end #f snd #f chn #f -- }> doc" Make a selection like make-region but without creating a region. \ It follows SND's sync field, and applies to all SND's \ channels if CHN is not specified. \ END defaults to end of channel, BEG defaults to 0, \ SND defaults to the currently selected sound." snd snd-snd { current-sound } current-sound sound? unless 'no-such-sound #( "%s: can't find sound %s" get-func-name snd ) fth-throw then current-sound sync { current-sync } unselect-all drop chn integer? if beg end snd chn add-chan-to-selection else sounds each { s } snd #t = s current-sound = || current-sync 0<> current-sync s sync = && || if s channels 0 ?do beg end s i add-chan-to-selection loop then end-each then ; previous \ ;;; -------- mix-channel, insert-channel, c-channel hide : mc-cb { rd -- prc; y self -- val } 1 proc-create ( prc ) rd , does> { y self -- val } self @ ( rd ) next-sample y f+ ; set-current : mix-channel <{ file :optional beg 0 dur #f snd #f chn #f edpos #f -- r }> doc" Mix in FILE. \ FILE can be the file name or a list #( file-name [beg [channel]] )." file string? if file else file 0 array-ref then { file-name } file-name find-file to file-name file-name unless 'no-such-file #( "%s: %S" get-func-name file-name ) fth-throw then file string? file length 2 < || if 0 else file 1 array-ref then { file-beg } file string? file length 3 < || if 0 else file 2 array-ref then { file-channel } dur file-name mus-sound-framples file-beg - || { len } beg 0< if 'no-such-sample #( "%s: %s" get-func-name beg ) fth-throw then len 0> if file-beg file-name file-channel 1 #f make-sampler { reader } "%S %s %s %s" #( file beg dur get-func-name ) string-format { origin } reader mc-cb beg len snd chn edpos origin map-channel else #f then ; previous : insert-channel <{ file :optional beg 0 dur #f snd #f chn #f edpos #f -- r }> doc" Insert the FILE. \ FILE can be the file name or a list #( file-name [beg [channel]] )." file string? if file else file 0 array-ref then { file-name } file-name find-file to file-name file-name unless 'no-such-file #( "%s: %S" get-func-name file-name ) fth-throw then file string? file length 2 < || if 0 else file 1 array-ref then { file-beg } file string? file length 3 < || if 0 else file 2 array-ref then { file-channel } dur file-name mus-sound-framples file-beg - || { len } beg 0< if 'no-such-sample #( "%s: %s" get-func-name beg ) fth-throw then len 0> if file-beg file-name file-channel 1 #f make-sampler { reader } len 0.0 make-vct map! reader next-sample end-map { data } reader free-sampler drop "%S %s %s %s" #( file beg dur get-func-name ) string-format { origin } beg len data snd chn edpos #f origin insert-samples else #f then ; \ ;;; -------- redo-channel, undo-channel : redo-channel <{ :optional edits 1 snd #f chn #f -- }> doc" It's the regularized version of redo." snd fixnum? snd sync 0<> && chn fixnum? && if snd chn edit-position edits + snd chn set-edit-position drop else edits snd chn redo drop then ; : undo-channel <{ :optional edits 1 snd #f chn #f -- }> doc" It's the regularized version of undo." snd fixnum? snd sync 0<> && chn fixnum? && if snd chn edit-position edits - 0 max snd chn set-edit-position drop else edits snd chn undo drop then ; \ ;;; -------- any-env-channel hide : aec-cb { en func beg dur snd chn edpos -- prc; self -- val } 0 proc-create ( prc ) en , func , beg , dur , snd , chn , edpos , does> { self -- val } self @ { en } self cell+ @ { func } self 2 cells + @ { beg } self 3 cells + @ { dur } self 4 cells + @ { snd } self 5 cells + @ { chn } self 6 cells + @ { edpos } 0.0 0.0 { x0 y0 } en 0 array-ref { x1 } en 1 array-ref { y1 } en envelope-last-x en 0 array-ref f- { xrange } beg { ramp-beg } 0 { ramp-dur } en length 1- 2 ?do x1 to x0 y1 to y0 en i array-ref to x1 en i 1+ array-ref to y1 x1 x0 f- xrange f/ dur f* fround->s to ramp-dur y0 y1 f= if y0 ramp-beg ramp-dur snd chn edpos scale-channel else func #( y0 y1 ramp-beg ramp-dur snd chn edpos ) run-proc then ramp-dur +to ramp-beg 2 +loop ; set-current : any-env-channel <{ en func :optional beg 0 dur #f snd #f chn #f edpos #f origin #f -- val }> en nil? if #f exit then en envelope-length ( pts ) 1 = if en 0 array-ref beg dur snd chn edpos scale-channel else dur integer? unless snd chn #f framples to dur then en func beg dur snd chn edpos aec-cb origin as-one-edit then ; previous \ ;;; -------- sine-ramp sine-env-channel hide : sine-ramp-cb { rmp0 rmpd incr -- prc; y self -- val } 1 proc-create ( prc ) rmp0 , rmpd , pi fnegate ( angle ) , incr , does> { y self -- val } self @ { rmp0 } self 1 cells + @ { rmpd } self 2 cells + @ { angle } self 3 cells + @ { incr } angle fcos 0.5 f* 0.5 f+ rmpd f* rmp0 f+ y f* ( val ) angle incr f+ self 2 cells + ! ( angle += incr ) ( val ) ; set-current : sine-ramp <{ rmp0 rmp1 :optional beg 0 dur #f snd #f chn #f edpos #f -- val }> doc" Produce a sinsusoidal connection from RMP0 to RMP1." "%s %s %s %s %s" #( rmp0 rmp1 beg dur get-func-name ) string-format { origin } dur number? if dur else snd chn edpos framples beg f- then pi swap f/ { incr } rmp0 rmp1 rmp0 f- incr sine-ramp-cb beg dur snd chn edpos origin map-channel ; previous : sine-env-channel <{ en :optional beg 0 dur #f snd #f chn #f edpos #f -- val }> doc" Connect ENV's dots with sinusoids." "%s %s %s %s" #( en beg dur get-func-name ) string-format { origin } en <'> sine-ramp beg dur snd chn edpos origin any-env-channel ; \ #( 0 0 1 1 2 -0.5 3 1 ) sine-env-channel \ ;;; an obvious extension of this idea is to use the blackman fft \ ;;; window formulas to get sharper sinusoids (i.e. use the sum of n \ ;;; cosines, rather than just 1) \ \ ;;; -------- blackman4-ramp, blackman4-env-channel hide : b4r-cb { rmp0 rmpd incr -- prc; y self -- val } 1 proc-create ( prc ) rmp0 , rmpd , 0.0 ( angle ) , incr , does> { y self -- val } self @ { rmp0 } self 1 cells + @ { rmpd } self 2 cells + @ { angle } self 3 cells + @ { incr } angle fcos { cx } cx 0.041194 f* -0.20762 f+ cx f* 0.375696 f+ cx f* -0.29145 f+ cx f* 0.084037 f+ rmpd f* rmp0 f+ y f* ( val ) angle incr f+ self 2 cells + ! ( angle += incr ) ( val ) ; set-current : blackman4-ramp <{ rm0 rm1 :optional beg 0 dur #f snd #f chn #f ep #f -- val }> "%s %s %s %s %s" #( rm0 rm1 beg dur get-func-name ) string-format { origin } dur number? if dur else snd chn ep framples beg f- then pi swap f/ { incr } rm0 rm1 rm0 f- incr b4r-cb beg dur snd chn ep origin map-channel ; previous : blackman4-env-channel <{ en :optional beg 0 dur #f snd #f chn #f ep #f -- r }> "%s %s %s %s" #( en beg dur get-func-name ) string-format { origin } en <'> blackman4-ramp beg dur snd chn ep origin any-env-channel ; \ ;;; -------- ramp-squared, env-squared-channel hide : rsq-cb { rmp0 rmpd incr -- prc; y self -- val } 1 proc-create ( prc ) rmp0 , rmpd , 0.0 ( angle ) , incr , does> { y self -- val } self @ { rmp0 } self 1 cells + @ { rmpd } self 2 cells + @ { angle } self 3 cells + @ { incr } angle dup f* rmpd f* rmp0 f+ y f* ( val ) angle incr f+ self 2 cells + ! ( angle += incr ) ( val ) ; set-current : ramp-squared <{ r0 r1 :optional sy #t beg 0 dur #f snd #f chn #f ep #f -- r }> doc" Connect R0 and R1 with an x^2 curve." "%s %s %s %s %s %s" #( r0 r1 sy beg dur get-func-name ) string-format { origin } dur number? if dur else snd chn ep framples beg f- then 1/f { incr } r0 r1 r0 f- incr rsq-cb beg dur snd chn ep origin map-channel ; previous hide : esqc-cb { symmetric -- prc; r0 r1 b d s c e self -- val } 7 proc-create ( prc ) symmetric , does> { r0 r1 b d s c e self -- val } r0 r1 self @ ( symmetric ) b d s c e ramp-squared ; set-current : env-squared-channel <{ en :optional sy #t beg 0 dur #f s #f c #f ep #f -- r }> doc" Connect ENV's dots with x^2 curves." "%s %s %s %s %s" #( en sy beg dur get-func-name ) string-format { origin } en sy esqc-cb beg dur s c ep origin any-env-channel ; previous \ #( 0 0 1 1 2 -0.5 3 1 ) env-squared-channel \ ;;; -------- ramp-expt, env-expt-channel : ramp-expt <{ rmp0 rmp1 expt :optional sym #t beg 0 dur #f snd #f chn #f ep #f -- r }> doc" Connect RMP0 and RMP1 with an x^EXPT curve." \ ;; a^x = exp(x * log(a)) "%s %s %s %s %s %s %s" #( rmp0 rmp1 expt sym beg dur get-func-name ) string-format { origin } dur number? if dur else snd chn ep framples beg d- then { len } len 1/f { incr } beg len snd chn ep samples { data } rmp1 rmp0 f- { scl } 0.0 { angle } sym rmp1 rmp0 f< && if scl fnegate to scl 1.0 to angle len 0 ?do data i data i vct-ref rmp1 scl angle expt f** f* f+ f* vct-set! drop angle incr f- to angle loop else 0.0 to angle len 0 ?do data i data i vct-ref rmp0 scl angle expt f** f* f+ f* vct-set! drop angle incr f+ to angle loop then data beg len snd chn current-edit-position origin vct->channel ; hide : expc-cb { sym expt -- prc; r0 r1 b d s c e self -- val } 7 proc-create ( prc ) expt , sym , does> { r0 r1 b d s c e self -- val } r0 r1 self @ ( expt ) self cell+ @ ( sym ) b d s c e ramp-expt ; set-current : env-expt-channel <{ en ex :optional sym #t beg 0 dur #f snd #f chn #f ep #f -- r }> doc" Connect ENV's dots with x^exponent curves." ex 1.0 f= if en beg dur snd chn ep env-channel else "%s %s %s %s %s %s" #( en ex sym beg dur get-func-name ) string-format { origin } sym ex expc-cb { prc } en prc beg dur snd chn ep origin any-env-channel then ; previous \ ;;; -------- offset-channel hide : offc-cb { dc -- prc; y self -- val } 1 proc-create ( prc ) dc , does> { y self -- val } self @ ( dc ) y f+ ; set-current : offset-channel <{ amount :optional beg 0 dur #f snd #f chn #f edpos #f -- r }> doc" Add AMOUNT to each sample." "%s %s %s %s" #( amount beg dur get-func-name ) string-format { origin } amount offc-cb beg dur snd chn edpos origin map-channel ; previous : offset-sound <{ offset :optional beg 0 dur #f snd #f -- }> doc" Add OFFSET to every sample in SND." snd snd-snd to snd snd sound? if snd channels 0 ?do offset beg dur snd i ( chn ) #f offset-channel drop loop else 'no-such-sound #( "%s: %s" get-func-name snd ) fth-throw then ; \ ;;; -------- pad-sound : pad-sound <{ beg dur :optional snd #f -- }> doc" Place a block of DUR zeros in every \ channel of SND starting at BEG." snd snd-snd to snd snd sound? if snd channels 0 ?do beg dur snd i ( chn ) #f pad-channel drop loop else 'no-such-sound #( "%s: %s" get-func-name snd ) fth-throw then ; \ ;;; -------- dither-channel hide : dith-cb { dither -- prc; y self -- val } 1 proc-create ( prc ) dither , does> { y self -- val } self @ ( dither ) dup mus-random swap mus-random f+ y f+ ; set-current : dither-channel <{ :optional amount 0.00006 beg 0 dur #f snd #f chn #f ep #f -- r }> doc" Add AMOUNT dither to each sample." "%s %s %s %s" #( amount beg dur get-func-name ) string-format { origin } amount f2/ dith-cb beg dur snd chn ep origin map-channel ; previous : dither-sound <{ :optional amount 0.00006 beg 0 dur #f snd #f -- }> doc" Add dithering to every sample of SND." snd snd-snd to snd snd sound? if snd channels 0 ?do amount beg dur snd i ( chn ) #f dither-channel drop loop else 'no-such-sound #( "%s: %s" get-func-name snd ) fth-throw then ; \ ;;; -------- contrast-channel hide : cntr-cb { index -- prc; y self -- val } 1 proc-create ( prc ) index , does> { y self -- val } y two-pi f* fsin self @ ( index ) f* y half-pi f* f+ fsin ; set-current : contrast-channel <{ idx :optional beg 0 dur #f snd #f chn #f edpos #f -- r }> doc" Apply contrast-enhancement to the sound." "%s %s %s %s" #( idx beg dur get-func-name ) string-format { origin } idx cntr-cb beg dur snd chn edpos origin map-channel ; previous : contrast-sound <{ index :optional beg 0 dur #f snd #f -- }> doc" Apply contrast-enhancement to every channel of SND." snd snd-snd to snd snd sound? if snd channels 0 ?do index beg dur snd i ( chn ) #f contrast-channel drop loop else 'no-such-sound #( "%s: %s" get-func-name snd ) fth-throw then ; \ ;;; -------- scale-sound : scale-sound <{ scl :optional beg 0 dur #f snd #f -- }> doc" Multiply every sample in SND by SCL." snd snd-snd to snd snd sound? if snd channels 0 ?do scl beg dur snd i ( chn ) #f scale-channel drop loop else 'no-such-sound #( "%s: %s" get-func-name snd ) fth-throw then ; \ ;;; -------- normalize-sound : normalize-sound <{ amp :optional beg 0 dur #f snd #f -- }> doc" Scale SND to peak amplitude AMP." snd snd-snd to snd snd sound? if amp 0.0 snd #t #f maxamp each ( mx ) fabs fmax end-each f/ { scl } snd channels 0 ?do scl beg dur snd i ( chn ) #f scale-channel drop loop else 'no-such-sound #( "%s: %s" get-func-name snd ) fth-throw then ; \ ;;; -------- channels-equal hide : c-equal-cb { rd diff -- prc; y self -- f } 1 proc-create ( prc ) rd , diff , does> { y self -- f } self @ ( rd ) read-sample y f- fabs self cell+ @ ( diff ) f> ; set-current : channels= <{ snd1 chn1 snd2 chn2 :optional allowable-difference 0.0 -- f }> doc" Return #t if the two channels are the \ same (within diff) modulo trailing 0's." snd1 snd2 = chn1 chn2 = && if #t else snd1 chn1 #f maxamp { mx1 } snd2 chn2 #f maxamp { mx2 } mx1 mx2 f- fabs allowable-difference f> if #f else snd1 chn1 #f framples { len1 } snd2 chn2 #f framples { len2 } len1 len2 >= if len1 snd1 snd2 chn1 chn2 else len2 snd2 snd1 chn2 chn1 then { len s1 s2 c1 c2 } 0 s2 c2 1 #f make-sampler { read2 } read2 allowable-difference c-equal-cb 0 len s1 c1 #f #f scan-channel not then then ; previous : channels-equal? <{ s1 c1 s2 c2 :optional allowable-difference 0.0 -- f }> doc" Return #t if the two channels are the same (within diff)." s1 c1 #f framples s2 c2 #f framples <> if #f else s1 c1 s2 c2 allowable-difference channels= then ; \ ;;; -------- mono->stereo, mono-files->stereo : mono->stereo ( new-name snd1 chn1 snd2 chn2 -- snd ) doc" Take the two channels and combine \ them into a stereo sound NEW-NAME." { new-name snd1 chn1 snd2 chn2 } snd1 chn1 edit-position { old-ed1 } snd2 chn2 edit-position { old-ed2 } :file new-name :channels 2 :srate snd1 srate new-sound { ind } ind 0 snd1 chn1 0 #f #f swap-channels drop ind 1 snd2 chn2 0 #f #f swap-channels drop old-ed1 snd1 chn1 set-edit-position drop old-ed2 snd2 chn2 set-edit-position drop ind ; \ "test.snd" 0 0 1 0 mono->stereo : mono-files->stereo ( new-name chan1-name chan2-name -- snd ) doc" Combine two mono files into the stereo file NEW-NAME." { new-name chan1-name chan2-name } chan1-name find-file to chan1-name chan1-name unless 'no-such-file #( "%s: %S" get-func-name chan1-name ) fth-throw then chan1-name open-sound { ind1 } chan2-name find-file to chan2-name chan2-name unless 'no-such-file #( "%s: %S" get-func-name chan2-name ) fth-throw then chan2-name open-sound { ind2 } new-name ind1 0 ind2 0 mono->stereo { ind3 } ind1 close-sound drop ind2 close-sound drop ind3 ; \ "test.snd" "oboe.snd" "pistol.snd" mono-files->stereo : stereo->mono ( orig-snd chan1-name chan2-name -- snd0 snd1 ) doc" Split a stereo sound into two mono sounds \ named CHAN1-NAME and CHAN2-NAME." { orig-snd chan1-name chan2-name } orig-snd 0 edit-position { old-ed0 } orig-snd 1 edit-position { old-ed1 } :file chan1-name :srate orig-snd srate new-sound { chan1 } :file chan2-name :srate orig-snd srate new-sound { chan2 } orig-snd 0 chan1 0 0 #f #f swap-channels drop orig-snd 1 chan2 0 0 #f #f swap-channels drop old-ed0 orig-snd 0 set-edit-position drop old-ed1 orig-snd 1 set-edit-position drop chan1 chan2 ; \ 0 "hi1.snd" "hi2.snd" stereo->mono \ === PREFERENCES DIALOG === \ --- reopen menu --- hide "empty" value reopen-empty #() value reopen-names #f value reopen-menu 16 value reopen-max-length <'> noop 0 make-proc constant extensions-noop : reopen-select-cb { brief-name long-name -- prc; self -- } 0 proc-create ( prc ) long-name , brief-name , does> ( self -- ) { self } self @ { long-name } self cell+ @ { brief-name } reopen-menu brief-name remove-from-menu drop long-name file-exists? if long-name open-sound drop then ; : add-to-reopen-menu <{ snd -- #f }> snd short-file-name { brief-name } snd file-name { long-name } reopen-names brief-name array-member? if #f exit then reopen-names reopen-empty array-member? if reopen-menu reopen-empty remove-from-menu drop #() to reopen-names then reopen-menu brief-name brief-name long-name reopen-select-cb 0 add-to-menu drop reopen-names brief-name array-push to reopen-names reopen-names length reopen-max-length > if reopen-menu reopen-names array-shift remove-from-menu drop then #f ; : check-reopen-menu <{ file -- }> file #f file-basename { brief-name } reopen-names brief-name array-member? if reopen-menu brief-name remove-from-menu drop reopen-names brief-name array-index { idx } idx 0>= if reopen-names idx array-delete! drop then then reopen-names empty? if reopen-menu reopen-empty extensions-noop undef add-to-menu drop reopen-names reopen-empty array-push to reopen-names then ; set-current #f value including-reopen-menu \ for prefs : with-reopen-menu ( -- ) including-reopen-menu unless #() to reopen-names reopen-menu false? if "Reopen" extensions-noop add-to-main-menu to reopen-menu then reopen-menu reopen-empty extensions-noop 0 add-to-menu drop reopen-names reopen-empty array-push to reopen-names #t to including-reopen-menu close-hook <'> add-to-reopen-menu add-hook! open-hook <'> check-reopen-menu add-hook! then ; previous \ --- buffers menu --- hide "empty" value buffer-empty #() value buffer-names #f value buffer-menu : buffer-select-cb { file -- prc ; self -- } 0 proc-create ( prc ) file , does> { self -- } self @ ( file ) 0 find-sound dup sound? if select-sound then drop ; : open-buffer <{ file -- }> buffer-names buffer-empty array-member? if buffer-menu buffer-empty remove-from-menu drop #() to buffer-names then buffer-menu file file buffer-select-cb -1 add-to-menu drop buffer-names file array-push to buffer-names ; : close-buffer <{ snd -- #f }> buffer-menu snd file-name remove-from-menu drop buffer-names snd file-name array-index { idx } idx 0>= if buffer-names idx array-delete! drop then buffer-names empty? if buffer-menu buffer-empty extensions-noop 0 add-to-menu drop buffer-names buffer-empty array-push to buffer-names then #f ; set-current #f value including-buffers-menu \ for prefs : with-buffers-menu ( -- ) including-buffers-menu unless #() to buffer-names buffer-menu unless "Buffers" extensions-noop add-to-main-menu to buffer-menu then buffer-menu buffer-empty extensions-noop 0 add-to-menu drop buffer-names buffer-empty array-push to buffer-names #t to including-buffers-menu open-hook <'> open-buffer add-hook! close-hook <'> close-buffer add-hook! then ; previous \ ;;; -------- cursor-follows-play and stays where it was when the play ended \ moved from examp.fs to extensions.fs [ms] hide : current-cursor { snd chn -- cur } 'cursor snd chn channel-property ; : set-current-cursor { snd chn val -- } 'cursor val snd chn set-channel-property ; : original-cursor { snd chn -- cur } 'original-cursor snd chn channel-property ; : set-original-cursor { snd chn val -- } 'original-cursor val snd chn set-channel-property ; : local-start-playing-func <{ snd -- val }> snd channels 0 ?do snd i #f cursor { cur } snd i cur set-original-cursor snd i cur set-current-cursor loop #f ; : local-stop-playing-func <{ snd -- val }> snd 0 current-cursor snd #t #f set-cursor ; set-current : if-cursor-follows-play-it-stays-where-play-stopped <{ :optional enable #t }> enable if start-playing-hook <'> local-start-playing-func add-hook! stop-playing-hook <'> local-stop-playing-func add-hook! else start-playing-hook <'> local-start-playing-func remove-hook! drop stop-playing-hook <'> local-stop-playing-func remove-hook! drop then ; previous \ extensions.fs ends here snd-16.1/new-backgrounds.scm0000644000076400007640000076012012306421671014140 0ustar bilbil(provide 'snd-new-backgrounds.scm) ;;; some backgrounds -- wood granite rough blueish smoke (define wood (list " 96 96 254 2" ".. c #9c4a34" ".# c #a4825c" ".a c #bc5e2c" ".b c #d48432" ".c c #dc9f51" ".d c #bc6e1c" ".e c #d4855d" ".f c #94664c" ".g c #bc714e" ".h c #8c6664" ".i c #d4923c" ".j c #bc8444" ".k c #d49360" ".l c #d4794e" ".m c #ecaf68" ".n c #bc8365" ".o c #d47439" ".p c #a46954" ".q c #dc9f70" ".r c #e48544" ".s c #bc7b51" ".t c #a47761" ".u c #bc7b42" ".v c #a4523c" ".w c #e4945e" ".x c #9c784c" ".y c #d4844a" ".z c #eca053" ".A c #bc614c" ".B c #e4855c" ".C c #bc8350" ".D c #c48e68" ".E c #b16634" ".F c #e49339" ".G c #bc703a" ".H c #bc7c67" ".I c #a45f34" ".J c #cc714d" ".K c #d48c5f" ".L c #a47057" ".M c #cc703a" ".N c #dca674" ".O c #b47859" ".P c #bc6729" ".Q c #d49475" ".R c #d48b4a" ".S c #cc8351" ".T c #cc8466" ".U c #ac6841" ".V c #e4a651" ".W c #e49576" ".X c #d47d31" ".Y c #ac6e4b" ".Z c #c07650" ".0 c #e48c43" ".1 c #e49452" ".2 c #9c745f" ".3 c #e47e54" ".4 c #cc7c4f" ".5 c #cc7c32" ".6 c #b46133" ".7 c #d49a68" ".8 c #d67e4f" ".9 c #bc7643" "#. c #b47056" "## c #d48b3a" "#a c #dc9f5e" "#b c #e49a60" "#c c #cc6a31" "#d c #8c6244" "#e c #dc9a41" "#f c #eca753" "#g c #bc8a58" "#h c #d48c76" "#i c #bc693f" "#j c #bc715d" "#k c #9c6857" "#l c #f4b171" "#m c #bc8a6a" "#n c #eca16d" "#o c #a87e58" "#p c #a4613f" "#q c #a48569" "#r c #d4846d" "#s c #dc935f" "#t c #c47c50" "#u c #dc8449" "#v c #bc6950" "#w c #cc9678" "#x c #c4703a" "#y c #cc7b67" "#z c #dc8c5e" "#A c #ac7067" "#B c #eca86e" "#C c #b4786d" "#D c #dc8c4a" "#E c #b46842" "#F c #d47c41" "#G c #e48d51" "#H c #e59a52" "#I c #9c6e3f" "#J c #d49351" "#K c #cc843b" "#L c #ecb678" "#M c #9c5a38" "#N c #d4795c" "#O c #c47b39" "#P c #ec9560" "#Q c #ac764c" "#R c #c48351" "#S c #c48e74" "#T c #cc7650" "#U c #cc8a84" "#V c #bc6a5c" "#W c #e4af74" "#X c #b46855" "#Y c #e4a06e" "#Z c #ac775b" "#0 c #e48d5d" "#1 c #c47d65" "#2 c #cc763f" "#3 c #b47e5d" "#4 c #cc8a55" "#5 c #cc8a67" "#6 c #bf622f" "#7 c #dc853b" "#8 c #e49f4a" "#9 c #9c505c" "a. c #8c5644" "a# c #cc7329" "aa c #a45a51" "ab c #b48264" "ac c #9c7a7c" "ad c #9c5f4f" "ae c #b4844c" "af c #a46749" "ag c #dca664" "ah c #b46e1c" "ai c #c4762c" "aj c #a45a3c" "ak c #dc9a74" "al c #ac7e46" "am c #ac6a6c" "an c #eca862" "ao c #e49a41" "ap c #e49a78" "aq c #bc7660" "ar c #d57e5e" "as c #9c6e5c" "at c #ab7e65" "au c #cc8a44" "av c #9c6240" "aw c #bc6244" "ax c #bc5d3f" "ay c #e48550" "az c #eca060" "aA c #cc7160" "aB c #cc7c42" "aC c #b46241" "aD c #b4726c" "aE c #eca67f" "aF c #9c6a3c" "aG c #94685a" "aH c #c48240" "aI c #c48465" "aJ c #dc7640" "aK c #cc8f54" "aL c #e4a76f" "aM c #c4692e" "aN c #dc9474" "aO c #ac6050" "aP c #b47048" "aQ c #94614b" "aR c #ac836c" "aS c #a47048" "aT c #b4764a" "aU c #ec8e5c" "aV c #dc9a53" "aW c #cc765e" "aX c #b48a64" "aY c #dc9a63" "aZ c #c47640" "a0 c #ec9a60" "a1 c #c48a54" "a2 c #c48a67" "a3 c #ac5a3c" "a4 c #ac8458" "a5 c #dc855d" "a6 c #c4714d" "a7 c #dc9243" "a8 c #dc794e" "a9 c #ac6955" "b. c #cc8f67" "b# c #ac6032" "ba c #ac7056" "bb c #dc7a34" "bc c #ec9553" "bd c #dc8d3b" "be c #e4a060" "bf c #f4a654" "bg c #c46842" "bh c #c46f62" "bi c #ac613d" "bj c #dc866c" "bk c #c4694e" "bl c #dc7d42" "bm c #ec8d4f" "bn c #dc9351" "bo c #cc9177" "bp c #c4695f" "bq c #ecb075" "br c #e4a75f" "bs c #d4843c" "bt c #bc722c" "bu c #d4936c" "bv c #d47644" "bw c #bc7d5c" "bx c #ac563c" "by c #e4956c" "bz c #a47a4c" "bA c #d48454" "bB c #bc825c" "bC c #e49544" "bD c #bc7044" "bE c #bc7e74" "bF c #d48d6c" "bG c #cc7144" "bH c #b47864" "bI c #bc6a34" "bJ c #d49684" "bK c #d48b54" "bL c #cc845c" "bM c #cc8474" "bN c #ac684c" "bO c #cc7d5c" "bP c #eca27c" "bQ c #dc946c" "bR c #c47c5c" "bS c #dc8554" "bT c #c47244" "bU c #dc8c6c" "bV c #dc8c54" "bW c #b4684c" "bX c #cc8344" "bY c #c47b44" "bZ c #c4825c" "b0 c #e4a17c" "b1 c #ac7a64" "b2 c #e48c6c" "b3 c #c47a74" "b4 c #e49f54" "b5 c #9c674c" "b6 c #946764" "b7 c #c48674" "#u#G#G#P#G#G#G.1#G#G.1.1.1.w#G.r#D.1.1.1#D#DbVbV.K.K.K.KbO.Z.Z#TaP.GaT.Z.O.O.O.H.9aP.ZaPaPaPbZbo.i.k#J.k#JbKbnbn#b#sbVbV#G#G.r.ray.r.0#G.0#G.1bc.r.0.0bc.0.0.0.r.1.1.1.1#G#D.0#D.0.0.0bcbcbc.1.0" "#aagaLbrag#a#a#a#DbVbn#G#0.1#0#Da5#za5.4.J.Jbk#vbt.G#x.9bY.4#tbYbw.saPaP.Ub#af.Y.s.s.Z.saP#E.gbw.U.U.UaObWbWbWaPb#b#.E#t.K.K#z#s#s#sbQ#s#sbn#s#sbn#s.w#s.w#s#sbn.ybV#s#sbV#s#sbQ#aak.7.k.7.k.k.k" "#..g#.#.#j#.#XbW#Z#o.O.O#3.n.n.Halalalala4aXaXa4#t.u.9#R#5bu.k#5bob7aIaI.nbwbw#m#5aIa2#5#5aIb7#5.DbBbB#3bwbw.C.O#oabab.naI.C#t#R.9#tbY#tbY.ZbY.s#t#t#t#R.sbY.s#tbD.Z.Z#t.9.Z#t.4bBbw.s.saT.9aTaT" ".ybS.ybSbVbVbVbVbl#u#u#ubSaybSay#s#za5#z#z#z.KbA.Qb.aIbZbZbB.g.U.gaP#.aP#.aPaP.O.9aP.g.s.O.ZaP.Z#CaD#Aamamamam#X#3#Z.OaPaPaPaP.saZbY#t#t#tbY#tbY#t#tbLbZ.SbR#t#tbZbRbZbRbR.sbRbR.4aBaB.4bY.4.4.4" "bKbV#zbKbA.ybK#zbV#z#0bS#0#0#0aya5bA.4.4.4#T#xbgbwaq.O.g.O#j#.aPaCaC#v.g.gaPaP.Z#R#R#t#t#t.Z.s.Z#O#O.5aH#KbY.S#4bD.G#xaZaZ#2.SbVbV#s.wbV#zbSbAa5.e.KbQbQbU#s#z.K#5.K#5.T#4#5.Kb..4bZbL.T.ebL.K.K" "#A#A#C#C#AaD#CbEatataRb1b1abb1.t#I.f#IaSbz.x.#.##v.g.g#1bR.T#5#hbObO.T.K.K#5.KbubL.4.4#t.4.Z#tbL.e#r.K.K.e.e.T#r.K#z.K#z#sbVbS#zbV#u#ubVbl#F.8.l#2.4.8bAbA.l.4bva6.g#x.g#x#i#i#i.L.Lba#Z#Z#Z#Zba" "aPaT.u.u.s.C.C.C.SbA.S.4.SbA.8.8#r#rbF#h.TbO.T#h.KbF.e.e.S.S.S.S#u.y.8bA.e.4bA.e.K#zbQ#s.K.KbUbQ.y.R.y.yaB#O#xbT#t.4bLbLbL.4bL.S.4.S.4#T.Za6.Z.JbD.g.Z.g.Z.g.Z.ZaP.g#iaP#i#E#EaC.Obababa.ObH#Z.O" "#zbSbA.e#za5.e.8bV.KbV.ybAbK#zbK.8.ybV#z.y#F.y#sbKbA.Rbn#sbn#b#b#Y.w#sbV.y.4.lbA.y.y.ybA#T.MbG.4bObO.4.SbLbOaq#..O.Yaf#p#p.I.U.UaT.Z.O.Oaq.O.H.Hb1b1#Z#Z.L#Zat#3bw.s.HbBb7aIaIaIbA.l.4aBbAbA.e.e" "#DbVbn.w#s.w#sbVbAbSbSbV#D#GbS#0.1#H#H#H#b.1bn.1#4.S#t#t.S.TbL.S.K.K.K.S.SbK.e.S#t.4#t#tbDaPb#b#.U#E.9.S.ebVbS#G.K.K#r.l#y#T.Z.Z#2aB.S.ybS#u.8#F#Kau.y.S.y.y.R.y#z#z#sbn.1bna7bd#F#DbVbVbV#s.w#s" ".1#s.1#s.1bVbS.y.K#z#sbVbVbA.8#FbA.8ar.8.e#r.e#NbKbA.S.S.S.SbLbLaBaBaB#2aB.SbKbAbVbVbV#s.w#YbebQ.KbA.e.KbV.ybl.ybsbsbs#D#u#D#u.R.y#D#DbVbV#s#0.wbebe#b#bbQ.wbn#GbV#G#D#G#D#GbV#D.ybV#sbV#s#s.w#s" ".wbn.w.w#bbQbVbV.4.4.ybKbnbV#z#z#G#D#D#D#u#D.y.R#2aB#2.M#x.M#2#2#z#s.w#sbV#s.w#s.1.w.w#b.w.1#G#G#s#zbVbVbVbSbVbVbd#ubd.r#D#D#D#D.1bC.1.1.1.1#D.1bV#G#0#0#G.w.1a0bC#G.0aybS.Ba5a5bVbVbV.w#z.w#sbV" "#ubVbVbVbV#GbV#D#s#sbn#b.w.w.1bVb2b2a5#z#z.K#zbA.w#s.w#sbV#s#z#s.w#b.w.w#GbV.w.w.X#Da0a0#G.1bcaz#G#GbS#GbV#ubV#0#z#0#0a5#0#0b2#0.0.r.0.0#u#u#F.o.M.M.M#F#ubV#G.1#b#P.w.w.w#0aya5.y#u.y.ybVbnbVbV" ".wbV#GbV#G#s#G#0.1#G.1.1.1#G#G.0#0#0.w.wby.wbQbn.w.w#G.w.wa0#b#P#u#G#G#0#G#G#G.w#baz#Yaz.1.0#D.0#G#G#G#GbVbl.8blbva8.8.B#z.Ba5#0ay#G#G#z#G#z#z#z#zbU#z#z#zbQbybQ#zbK#z#s#sbn.R.y#2#2aB.8bVbV#0bV" ".w.w.w#z.w.w.w.w#GbV.r.0.0#G#G#Gbda7a7#H#8#8#8#H#u#u#F#u#D#GbV#u#G#G.w.1.w#G.wa0bV#D#DbV.w#baz.w#G#G#G#G#0.BbSa5#u#u#D.1.1bn.0#7#z#0bSbSbSa5#z#z#r.e.e.4.4#2#2bT.4.4.4.S.R.Rbn.i#s.K#zbV#s#0bV.w" "#u.8#u#u#ubV#GbVby.wbQ.w#b.wbVbl#T#T.l.ear.Ba5.8.w#G#G#G.w.1.1.1.1#G#G.w.1#G#G.w#P.w#G.1.w#P.w#0#D#DbV.w.w#0#0#0.w#b#baVaVbn.1#G.y.y#F#F#2.obv#Fay#z#GbVbV#z.e.e#z#z#zbV#s#s#s#sbQbQ#sbQ.wbV#G#0" "#0#0#0#G#0#u#ublbDbT.4#4#zbQ.e.e#s#s#s#z.w#0#0aU#DbSbVbV#D#D#D#G.w#G#G.w#P.w.w.w#Gbmbmbmay#u#G.waz#b.w.w#Ga5bl#uaraW#i#i#ia6.4.ebVbnbQ#b.w.w#GbV#u.r.r#G#G#G#0a5.1.wbV#zbSar.J.JbT#x#2.y#F.8#u#G" "#5.TbL#tbD#i.g.Z.SbA#zbAbKbSbSbA#u#D#G#u#u#u#DbV#GbVay#G#0#G#G.r#D#Gbn.w#b#b#HaY.1bVbV.y#u.y#F#Fbv.o.M#2#2#2aBbG.9#OaB.y#D.1.1.1.w#s.1.w#G#G#G.rbdbda7bdbnbn#sbQ.nbw.s.Z.4.8.8.8.obl#u#zbV#z.K.K" "#i#x.Z#tbL.K.kbQbAbVbK#u.ybSbV#z#G.w.w#G#D#G#0#G.1#G#D.1.1.1.1.1bVbV#z.yaBaM.M.5.y.y.y#ubV.w#P.w.w.w#b.1.1.w.wby#b.w#b.w#b.w.1.1#u#u#ubVbAbK#z.S.T.TbO.Z#vbga3axbD#xaZ.8bAbAbAbA.e#4bA#ta6.P.6.6" ".S.4bL.e.e.e.ebA.8bSbSbSbVay#0#G.1.1a0.1#ba0#H#bbc#Hbc#Ha0bc.1.0#z.8#T.J.l.ebVbV#G#G#G.w.w.w.w#P.w#b#n#b.1.1.w#n.1.1.1#G#G#D#ublbl#2.4.4.g.Z#ZbN#9#9aa#X.g.ZbOar.Mbvbla5#z#zbA.laPbNbi.U.U#..Zbw" "bL.e.e.e#zbSbSbl#u#DbS#G#G#0#G#G.1.1.1.1bc#Ha0.1#G.1.1a0#b.1#u#F.e.4#T.8by#b#na0a0#b.w.w.w.w#P#0bVbV.1.1#G#G#u#G.1#G#G#ubS.8.l#T.Z.g#ibW.UbNa9#p.UaP.9.S.ybVbV#Dayay#z#z.e.4bT#i.pad#pbN#.bRaI.T" ".4.e.KbS.8blblbSbSbS#GbV#G#0#G#G#G.0.1.1bcaz#H.1#G.1.w#P.w.w#z.8bK.KbQbQbV#u#D.1#0#G#G#G#G#G.1#P.1.1beazbe.1#G#u#zbK.K.4bO.Z#j#v#A#ka9.YbW.ZbL.4.R.R.ibn#D#u#F#FbS.S.4aqaPbNbi.I#.bWaP.gbObL.8bL" ".K.K#z.e#F.lbv#F#z#GbS#u#u#G.w#G#u#G#G#G.1a0bc.1#P#P#P.w#GbVarar.R#J#HaY.1.1.1#H#H#b.1.1bc.1#P.1.w#b#bazbe.w#zbA#t#t.Z.Z.Z.g#.#.b1ba#..Z.Z.lbS#u.y#u#ubSbS#N.laA#j.ga9#kad#ka9#..g.g#tbO.e.e.ebA" ".l.l.8.y.8bAbAa5bSbS#ubSbS#0.w#G#G#G#G#G.1bc.1bCbm.1.1.0#Dblbv#T#D.R.ybVbe#nazanananbeaz#b#bbc#H.wa0.1#sbV.S.S#t#t.s.Z.sbwaIaIaI#t#t.4bA.lbl#ubl.3a5a5.e.4bh#V#XbN#k#kaG#k.L.OaIbL.e.K.ebA.y.4.8" "bSbAbAa5.ebA.8.4.8.ybS#z#G.w#0bSay#0bm#G#G.0.1.0bc#H.zbf.zbe.1#z.KbVbSbA.y#D#D.1bebebe#HbeazazazazazbebV.S.4#1bMbZbR.Z.Z.Z#t#tbYbl.o#ubS#Gay#0#uarbl.laB#t.uaT.Oad#kaGb6#ka9.g.Z#t#t.4.4#t.4bK.K" "aBbs.y.ybA.l.lar.4aBaB.8.y#F#u.wbn#D#D#G.0.0a7.FbdbCbc.1.1.0.1bc.F#8#H.1.ybG.4.ebn#s#s#baY#saYaV#b.w#s#J.SaZbD.sbR#t.S#z#ubs#F.R#D#D.0#G#G#G#G.0#D.R.yaBbDbDaP.g#Zb1.L.fb6.h.hac.I.YaT.u#t.Z.Z#2" "b3bR#1.4.4.4bX.R.K.KbV.ybl#F#F#F#za5a5.B#z#0#sby.1#G.1.1.1bm#G.1a0a0#H#H#b#b#s.ya#.X.y.ybVbn.w#bbebeaY#sbAbRbZa2au.S.R#s#z.y.e#zbs#ubn.1.1.1#G#D.0#D#D.RbA.4bO.4aPbD#Eb#af.I#Maf.2.x.L.L#Z.O.n#S" "aObi#Xbw.s.sbY.SbXbK#z#z.w.w.wa0#z#za5bS.l.l.8bVbSbVbS#G#G#G.w#Pbe.w#b#bazbrb4#Hbebebe.1#u#F.5.X#F.y#s#Y.NaN.Q.Q.T.Tbu.w#sbn.1be#sbVbV.y.y.ybn#b#G#G#G#G#0bn#zbSbn#bbn#D.R.RaBbX#3.O.Yaf.I.Ibi#E" "aVbX.G.6a3aCb3#U.y#z#s#0#z.w.w#s#H#H.1.1.0#G#Hb4bVbV#u#u#u#D.0#D.1.1.1#D#7#D#Hb4bCbc.1.w#b#b#n#nbe.1#u.yaBbX.S.kb4.cb4aYbA#T.4#r.4.K.K#s#s#s#D.y#GaybV.w.w.w.w.w#G.w.w.w#b.1bn.1#P.w.w#0#0aybS#G" "bnaVaYbeaNarbp.A.P#2#F.y#u#s.w#sb4b4.1.1.1.1#H#H#nbeaz#b#HbnbCa7.zbe.z.1#D#D.w#Baz.z#H.w#P.w.w.wbebeanbrbebn.RbX.4bQb0aL#BaYa7.bbA.4#xaMaZ.ybK.kbA.4.4#F.8.ybA.ybv#u#ubS#sbV#D#zbl.ray#G#G#P.w#P" ".w#0bSbVbV#D#D.1aY#b.w#zbS#FaBaB#x.M.l.8a5byap#bbn.1bebebebebeaza7.0bd#u#ubSbS.BbC#D.0#D#G.w.w.1anazb4bebebebr#B.V.c#D#Oai.S#s.WaE#Y#Y#YaY.kaB#x#4.S.S.4aBbX.y.y.y.K#z.KbV#z.ybV.ybKbKbK.K.K#z.k" ".8.8#u#G.w#HaV.1#s.w#s#0#zbV.wbQ#na0by#0a5bSbvbg.M#F.y#ubSbA#z.k.w.w.w.wa0a0.w.w#H.w#HbV#D#u#G.1.1.1#b.w.1.1#D#DbVakaLaLaLbq#B.VaB.XaB.ybKbQaLaL.q.qaY#a#b.w#b#b#b#b.wbn#s#D.y#D#s#s#s#JbKau.SbA" "b4#Hbe#baY#s.K.S.y#F.ybSbS.R#zbe#H#H.1#Gbc#b#bbn.w#bbybQ.4#xbga6#T.l#za5bV#G#Gbc.w#b#b.wbV#D.1beby.wbVbV#z#s.w#Y#bbeaY#J#s#Ybe.1#B#B#Bbr#s.RbA.KbKbnaV.w#b.w#Ha0b4anbe#Hbe.1.1#bbC#8bc#Ha0a0#Pbc" "b4#8#8#H#HbCbC.1b4#b.w.1#P#G#G.0akbVbXaB#2#2.4bAbA.KbAbV#s#b#YaY.1bV.8aZ.GbYaB.S.RaV#abebn.1#8az#b.w.w#b#ba0by.w.1#Hazbebe.1#s#b#ebnbnbnaVaVaYbnbnb4bebe#abe#abebnbnbnbn.ibnbnbn##a7#8#8#ea7beaL" "#Y.w.w#s.w#0#z#0#D#DbVbVbVbV#bana7#D.1.1#b.1#D#D#u#u#Fa#.o.y#D#D.r.r.w#b#Y#b#b.w.gbkbg#Tar#za5a5####.5.b.Ra7.1bn#HaV#H#Hbn#D#D.ybQbQ#z.K.e.K.e.ea7bnaVa7bnaY#aaL.m#Wbrbr#Ybr#W.m#L#L#L.mbeb4.w#b" "#sbK.ybS#z#zbSbS.k.k.K.S.SbAbKbn.w.1#D#GbV#GbV.w#G#G#G#u#u#ubl#7.r#G#G#0#zayay.0#Y.wa5bS#zbS.8.M.4.Z#xbka6#TbObO#D.Rbn#s#bbebebebV.R.R.y.R#D#DbVbebe#BbqaLbebn.Rbnbnbebr#BbrbeaV#Da7bran.mbr.1#D" "anazbean#Banbe#H.y#O#x#x.ybKbK.R.Jbvar.ebja5#N#TbvbS#z#0#0.1#0bV#G#u#u.o#Fbb#7bm#F#7#u#D#Dbn#bbe#s#s#sbn.w#zbVbVbkbpbpbpbhbhbhbhaAaAaWaW#N#r#rbFbs.ybKbn#b#YaLbq#Bbrbebebebr#BbqbeaLbe#Y#B#B#B#B" "a7#DbCb4azananan#BaL#b#Yby#b#G#ub0aN.e#x#i#xaWbObAa5.e.8.4#2.4.4.w.wbQ#zbSbSbVbV.w#z#zbS.JbGbG.l#D#GbV.1.w.1#G#G#H#8#8#8aoa7#8#8#D#Dbn.1bnbC.1bC#b.w#D#D.y.5bs.y##a7#Hbranbe.1.i#sbn#D.Rbsbs#ubs" "#b#0.y.8#2#2#2#2#F#u#G.w#0#G#Pazb4b4beb4bnbn##.5#xaB.4.4.4.e#z.K.e.SbA.8bA.ebK.K#zbV.y#ubVbVbVbVar.8ara8ara8a5ar.RbV#zbVbA.y#D#sbSa5a5bV#zbSbVbS#G#DbV#b#b.1bn#bananbeb4b4anananbean#B#B#Bazbebe" "#0a5bSbV.w#Y#BaE.1#0.wbSay#uay#Gbd.FbCbC#H.zanaz#b#b#b.w#zbA#2#c.P#6#6.M#2.e.K.k#KaB.Xbsbn.1.1#7#Hbna7#D#D#D#D.0#0#zbVbV#u#F#FblbdbCbC.1bC#G.1.1bV#u#D#G#Hbean.manbeanan#B.manan.mbebe.1bV.1.1.1" ".zbCa7#Hazanb4#8#Y.w.y.8#z.w#G#D#G#0#P#0#0#0#uaJ#D#u#ubl#D#0.wb2.w.1#0#0.w#z.4.G#vbhbRbO#rar#N.l#4bL.S.4.4.4.4bLay#D#uay.1#Ha0.w.1.w.1.w#G#s#0.w#G.1.1an#Bazb4b4anazb4b4.zananan#f#f#8#b#H.w.1#b" "b4#Hbd#Ha7#H.1.0a7#H#b.wbV#s.w#0#D#D#D#D#G#u#u#G#G#G#GbV#u.8.y#ubs#7#G.1.1bn#D.y#xbXbAbAbYbt.Z#RbXbK#s.k.R.S.RbAbl#F.o.o#Fbv.yblbV#u#7#G.1.z.z.z.w.1#G#u#D.0#G#nb4#H.1.1#b.zb4.z#H.1.1.1#Hbe.m#B" "#Y.w#D.1ay.w.w#Ga7#H#H.w#G#G#G#G#D.wbV#G.1.w#G.1#D#D#ubSbA#u.KbV#s#G#u#u#ubVbn#s.zb4b4#sbO.g#V#X.MaB.yaBaB#2aZ#2.y.y.R.KbQ.KbQbu#zbAbK#s#bbe#Ybea0be#bbn.w#D.y#G.1bC.1.1a0#b.z.z.zbc#H.zbCao#HbC" ".wbS#0.wa0a0#na0azaz#b#H.1#G.0.0.w#P.w#G#0#G#uay#D#DbAbK#z.KbSbK.l.4bv.8#F.l.e.S#ubAbA.RbK.K.K#s.4bAa5#z#z#z#z#z#w#m#3ba.p.p.L.L.ZaZbD#t#R.SaKaKakap#Y#bak#s#zakbn#D#u#D.y#7bs#7#F#F#u#0#0#0by.w" "bna7anbran#8az#8.1#ba0#bbcbeaza0a0.w#G#G.1bm#G#0.1#z#GbV#z#0#s#G.e#z#z#za5.8bGbgaAbv#T.l#F#Da7a7bQbybQ#z.e#z.ebAblblay.0ay.raJ.obR.s#tbR#t.s.s#tbDaZa6bT.Z.gbT.SbA.S.S.KbQ.q.q#YbqaLbeaV#D#u#D#u" "auauaL#W#Wbr#L#Wbe#nbe.w.w.w.1a7.1#H.1.0#u#7#7.r.0#ubl#uay#Gay#u#z#za5#u#ubS#za5#D#u#u.8.8.8.8#r.4bYaZ.G.GaZaZaZ#t.SbLbFb.#5bO.Z#t.Z.Z#t.Z#iaC.E.Z#1.g.ga6#ibWbR.C.s#..OaPbNbi.Ua9ajaO#X#v#y#r#h" "bL#1b.aI.g.I.UaP.GaZ#t.4.SbK#sbQbe#Bbe#b.1#D#D.w#G#DbSbl.8bl#u#F.8aB#F#F#F#ubV.w.ybSbS#u.8.8a5#z.k.K.KbK.KbQaYakbu.K.S.4.4.4.S.e.4.8.4.ebF.Kb.#h.gbR#taq.ZbW#E.gaP.YbNba#.babaaP#3.u.s#R#R.S.KbK" "a6a6.Z.ebO.T.QaNa2a2aIaT.Ub#.6.EbIaZaZ.4.S.SbA.kakbQ.k.KbF.ebA.y.e.ebSbS#u.8#FbG#r#r#r.e#F.ybsbdbV#zbV.yaBaB#2#2#MavaS#Z.O.O.OaPa6#i#i.ZbRaI.H.n.ZaIaI.T#5aIbRb.b.bLaIbRbR.gbWaP.g#v.g.Z#x.gbT#i" "#H.1#DaY.ybV.SaB.Y.O.O#.#X.ObBaIbR.T#1#t#1.Z.g.ZaP.U.U#EbW.g.g.g#T#T.4.l.l.8bS.e#F.8#F.l.8arararblbSa5#0bS.BbS#ubV#u#ubl#ublblbl#5bZ.gaP#.babN.pb##E#E#E.Z.g.gaIaB#2.ZbL.T.e.e.K#z.kby#b#b#Y#Baz" "brbrb4#Hb4.1#D.0.R.y.y#F.yaBbvaB.Z.g.g.g#jaOaxbxaFaS.Y.O.s.s#ta2#Fbla5bSay#ua8bl.y.y.RbK#J.KbKbK.S#F.y.8.8bA#F.l.y.y.8.8.4.4.4.4aPbtaPaP#E.YaPbNaP.Z.sbwbw.C.CbZbB.C.Z#..O.H.OaP#RbX.SbK#JbnaV#a" "aZ#taZ.Z.4bLbO.ebLbR.S.TbL.T#4buaK.S#R#R#4.Sbw#t#3aT.Z.ZbD#i.E#i#Z#ZafafbN#Z.na2.3ay.B.Bay.B.8a8bn.y.4.4.4.8.8bAbl.y.ybKbS.e.e.8#F.K#s#s.k.KbLbObL#t.Z.9.G.GbI.E.G.9aP.g.ZbZbZ#tbJaI#.#EbW#E.g.Z" "aKaKaH.u.C.C.sbw.O.O.O.O.Y.Uba.O.uaPbtaT.u.s.s#Rb.#4#5bLbL#T.Z.4.4#t.4.4#t.4.y.ebKbAbV.KbAbAbA.K.KbVbAa5#z#z#z.y#z#zbS.8aB#2.M#2.o#F#ubl#F#u#G.wbQbKbKbnbQ#YaL#Y#saY.KbAbYaBaBbY#.bibiaPaI.Tb7bR" "#h#5#1#X#jaOaaaa#M#paf.Ybaba.n#S.H#.#.aDaqaqaq.HaPbW#x.Z.4.Z.4bR#RbLb.b..k#4#R.4#RaH.u.u.u.ja1aK#F.S.4.K#zbQ#zbVbSbSbS.ybS#DbVbVayayayblbbbl#u#G#D#u#u#D.1.1#b#H#H#b#b#GbV#s#b.1#L#WaL#WbqaLbK#K" ".zanbeb4be#aaY#aak.k#4bL#t.G.G#i#1#j#j.gaq#j#.bW.ZaT#tbRbObRbLb.#u.r.r.r.r.rbmbm#za5bv.la5a5a5a5.K.4#xbg#xbg.MaM#2.8bV#s.w#sbV#ubS#z.1#z#G#G.1#G.1.1.1.1.1.1bc.1.1.1.1#G.wazaz#Bb4#8bC#Hbebe#H#b" "#D#G#G#u#0#zbSbSbVbVbAbAbV#z#z#s#JbK.R#s#saYaVaYb.#4.SbL.4.Z#t#t.L.LaS.Lba.O.n#mbQ#z.K#zbQ#0.e#2bQ.K.K.K#z#s#z#D.y#F#F#F#F#F.oaB.8.y.8.y#ubV#0#D#u.r#G.0#G#G#Gbc.1#G#G#G#G#Hbc.1#naz#b.w.1#0#0#P" ".z.zbcbCbcbC.0.0be#b#ba0#H.1.1.w#Dbdbdbn#H#8.z.z#BaL#b.w#sbV#z#s.K.K.K#z.K.K#z.K#R.C.j#RauaubYbt.6#6a6bL#zak#bak#D#D#D.y#u#u#0#0.w#sbV#u#F#Fbl#u.w#0#G#G.1#G.1#G.r#GbV#GbV.1bc#H.w.w.wa0#0bS#G#0" ".w.w.1#G.1#P#G#P.w.1#H.1.1#D#D.1by#0#0#G#P.w.w#b#Hbc#Gay#G.r.1.wbv#F.l#F.laJbvblbA.8.l.8a5#z#zbS.K#4bO.4#TaBaB#Fb4#baz#b#P#zbl.o#F#D#0#G#G#GaU#0.B#u#u#u#G#G#0.1.w.w.w.w#0#G.1.1b4anbraz#8.1#8az" "b4.1bnbC.1b4.zaz#f#fbr#fb4#8.Van#f#8#8ananbe#G#u.1#G#DbC.1.1.w.1.w.1#G#G#GbS#ubSaiaB.SbXaB#2.4bKbvar.ebF.T#1#j.gah#O##bnbn#D#baY.1#D#DbS#u#D#7#7.o#u#0.wbya0a0#0.wbn#0bSbAbS#z#0#8#8an.z.1bd.1a0" "#b.1.1bn.1bebran#W.man.manbran.m.m#Bbebe.1#D#D#bbCbCbC#GbC#G.1#G#u.8#ubSbVbS#z#z.w#s#D#ubV.1.w.w#Da7bd#Dbs.5.5#O.Q.Q.K#N.Jbgawax#O.y#z#s#z#z#b#B.zazaz.1#GbC.0bd#7#D#ubSbV#G.wbebr.Vbe#8#D#7#7#G" "#b#b#b#b.w#b#bbeb4#H.cbebe#bbnbK.e#z#z#sbVbs#D#G#z#z#za5a5#za5a5#sbn#z#z#z.y.8bAbl#F.o.o#u#G#G.r.1bnbn#D#DbV#z.w#T#x.MbGbla5a5.eaB.S.SbT.6.a#2bK.1bn.1bn.1bean#lazazbe.1.R#F.5a#.S.e.ebUbU.W.Wap" ".ybAbAbKbK#DbV.waV#HbebebeaYbnbn#z#FaB#F.y#D#Dbnbe#H.1bn.1#Dbnbn#8#eao#e#8#8#8#8#0#0#0.w#G#G.ray#2.J#2#2.la5#z.w#b.1#u#Gbnbn#D#DbAbA.4.4.8bA#z#z.e.8#T.J#x.l.K#z#D#0.w.w#b.qbraLanbr.Vbr#8bd.b.b" "#B#B#Bazbrbebebe#8brbrbrbe.zbrbr.mbrb4#H#b#sbVbV#NaW#T#T.J.JbkbkaAbp#Vbpbhbpbpbp.e#zbQ.w.w#s.1.w#H#b.1#G#D#7#7#FbS.8.l.l.8a5#sbybV#G#0.w#0#z#Fa#.4#NbOar#r#r#z#za8.ybS.8.4aB.SbK.cb4anan.mbeanan" "brbrbebrazbr#f.Vbr#f.manb4bebean.V.V.m.maL.1bA.y.Rbnbnbnbnbn#Hb4#Y.w#saYbQbnbK.RbT.GaM#2.4bVbVbK.8#F#u#z.wbybyby#G#G#zbV#u#F#F.obb#uay#0#0.w.w.w#b#b#sbn#D.X.5.b#z#0#za5bAbA.K#s#TaAbObO#T#T#raN" "bnbnbnbeanbq#l#Lan.maLbrbebebrbeaVb4b4aVbnbn.wbe#T.4.ybAbK.KbQbQ#D.R#D.1.1#H.1#H#Y#s#zbVbV#z#u.ya5a5ar.l#T.J#vawa7#Hb4be#b.1.0.0#G#ublbv#c#c#2#u#Dbd#D.1.w#Hbean#b.w.wbVbSbVbVbVbVbV#D.1bV.1#ban" "#Bbebe#abebeaVbnbn#sbn#D#s#a#b.w.q#b.q#Y#Ybe#HbnaY#baY#baVbnaVaV#bbn.w#bbebeaV#H#D.1bebe.w#G.wa0.z.z#HaV#HaYbnaV.ebLa6a6a6bOa5b2.w#b.w#zbU#s#s#zbA.lbv#T#T.l.y#0#8.1#D.1.wazaza0.w#P.wbebe#H#baz" "az.1bcbc.1.1bCa0#H#8b4b4#H#Hbebr#b#bbn.ybXbK#s.c.ia7bebe#zbV.8a5bnaY.caLaLbe#H#H.kbKbKbK#s#b#b#H#bbV#DbV.wbe.w.1bCbCbn#D#2bg#i#i.J.lbA#s#b#bbQbQ#JbVbVbS#G#u.R.R.SaB#2#2aB#Fbd#H.z.1.wa0#b#Ybe#Y" "au.S.S#J.k.R.kaY#DbVbV#sbn#s#s#b#Y#Y#Y#Yak.q#Y.N#Y#Y#a.R.y.y.ybV#ebrbq#WaL#B#bbV.i.RbVbn.1#bb4b4#s#D.y#ubV.1#b#H.1.1#bbe#Y#b#s#z#z#z#D#7bs#u.y.lai.5#F#u#0.wbebe.qakbQbQ#baY#b#b.1.1.0#G#D#ubb#F" ".k#s.k.k.K.KbK.KbA.KbK.K#z#s#z.K.5aBbX.4bY#RaHbY.Z.4.e#s#sbnb4#H.q#Y#sai.dbs#8anbeanan#Ybe#H#H#8#b#H.wbV#G#G.0.1.wbV#u#F#7#D.1b4#bbebebeazb4.1bVbebe.w#z#u#FaBai.4#2.4.ebQbQ.w#Y.w#G#GbVay#u#z.w" "bm#G#Gaybl#ublblbAbA.8bSbAa5bS#F#D.1#zbnbVbK.K.K.K.e.4aB.y#Dbnbea7#8brbq#Y.K.ebU#Hbe#Yanazbeazanazaz#n#n.w.1.1.1.w.w.1#Pa0#b.1.0bV#G.1.1az#b.w#s#sbVbV#ubVbV.1#s#z.yaB#2bG.M#xbgbG.8#z#Yb0#b#s#z" "bS#GaybS#G.w#b#b#zbV#0bV.w.w#G#G#G#G.1#G#zbV#D#u.y#D#z#s#s.K.8aiar.4.4bV#sbn.cbr#s#u#2.M#x.y#D#b.1#b#b#b#na0a0a0a0.1.0.X#7#u.1a0#z#D#u#F#u#ubVbV#n#n#b#Pby#b#Y#n#bbn#D#DbV.KbV#z.K#1#i.6.6bDbL.Q" "#Ebi#p.U.Y#Z#C#3bAbAbKbV#s#G#s#0#D#G.w.w#0bc#Gay.1#D#7#F.ya5#s.WaV.cbebn#sbQ#h.T.K.kbQb0aE#YbV.X.y.y.y.ybV.w#b.1#8.1azazaza0a0.wa0.w#0#GbV#z#z#0#F#F#F#F#F#u#ubVbe#b.1aY.wbV.ybAbRbR.Zaq.Z#E.U.U" ".n#Z.p.Las.faQ.fafaf.U.UaPbD.Z#t.4bK#za5#z#G#G#G#G#G.w#G#GbV#u.ybUbQ#z#zbV#JbKbYb.#R.Z#tbA.wbe#n.R#D.y.y.8#Dbn#D#Y.w.wbn.w.waza0.1.1#H#b#P.w#GbV.w#0bV#u#u#u#u#ubv.o#F.y#DbK#z.K#z#4.4.S.TbL#t#t" "bLaZbD#R#taP.U#Z.hb6as.L#k.pba#ZbD.s.ZbTbG.8bS#Gay.B#G#0#G#D.0#D#s.y.ybVbV.4.ZbL.s.s#R#4#s.w#H.1aY.qbebQ#s#s#sbnar.l.l#u.1#HbC.FbC.1bC.1.1.1.1.1aybVbV.w#s.w#s#0by#za5#u.y.4.l#r.y.8#F.8.K.e.4#T" "#4#4.S.4#taZ#T#2aZaTbNaQ#daQ.fasaS#QaT.s.4.8ararbl#ubVbV#ubl#F.XbT.G#t.S#tbkbT.T.uaH#OaB#D.1.zaz.z#f.z.zb4.za0.z#Jbn#JbK.ybAbK#s#z#baz.z.z.zaobc.0.1#G.0#G#u#G#G#ubS#0bVa5bS#uaBaB.y.y#u#F#FbA.K" "#zbK.e.S.8.S.S.T.O#Z.LaQaQaQb5af#..Z#t.4#F.yblblbl#ubVbVbK.S#t.saI#tbwbZaI#t#t.S.n#1.TbF#zbQby.wbebranbraz#b.1.wan#nbe.w#z.y#FaB.8.ybn#Haobcbcbc.1.1.1.1#G#G#G#0#G#0#GbV#ubVbVbV.8bAblbAbSbS.K.K" "#F.l.8.4bLbRbRbR#Z.L#kafafbN#..Zbg.Jbv.8#u#D.0#7#ubS.y#t.s.Obaas#3baaP.Z.sbD.Z.Z.y#JaY#a#Ybe#b.wb4#b#bbebebebe#bbm.0#u#G.w.w#0bVbGbAbVbV.1.1.w#P.1#Ha0bc.1#Day#D#0.1bS#u#ubV#zbVar.8.l.8a5a5.e#N" "#T.4.4bObw#.bNad#k.pba#.bR.4bAa5ara5#zbVbV#u.y.4.K#t.gbi#pb5.p#k.ZaP.Z#t.S.y#Dbna7bCb4.zazb4ao.1#b.1.1bVaybV#G.wa0.w#G#z#0#z.K.y.8bV.w.1.1.1bc.1bcbc#Ha0.1.0#G#G#G#G#G#G#GbVbV#ubla8a8blbSa5.8.4" ".e.T#1bw#..paQa.#E#v.Z.8.ebSbSay#FblbA.y.S.T.TaIaDbN#paj.U#v.g#ta6#TbAbSbS#G.1bc#GaU#P.w#0#GbSbS#G#Gay.r#D#G.w#P#D.y.8.4.4.e.e.e#u.1#P.1bc.1.1.1.0#Ha0#Hbc.1.1.way#0.w#0bV#GbV.ybl#F#u#zbVbKbA.y" ".g#.bW.UaOa9#..O.4.8bAbSbS#u.lbv.K.K.S#x#Eb#.v...Yba#..Z#T.4#Fbvbl#ubS#G.0#GbCbc#Pbc#P#P#G.w.w#P#Gbc.w.w.w.w#P.wb0.qbQ.K#r.S.S.S#G.1b4#P#H.1bc.1.1bca0.1#P.w.w.w#G#z#GbVbVbSbSbS#DbV#s.K#4.S.4.4" "#EaC#i.gbT.4.4bAbAbAbSbAbA.4.ZaPa3.6#6#E#x.4bLbL.4bAbKbAbSbS#ubS#0#P#P.w.w.1.w.1#H.1a7bCbn#H#H#Hbybyby#z#z.8.4.4aM#xaZ#2.8.y#GbV#Gbc.w.1#G.w.1.wbcbC#G#G.1#G#GaybSbSbS.8bla5bA.8#z#z.KbZbRaT.ZaP" ".4#r.K#z#z#G#ubb.8.y.y.y#R.O#Z.tbMbM#5.ebA.R#D#Day.rayaybV#G.wby.1#G.w#G.w.wbV#u.TbObO.Z.Za6bD#ia6bTbDbD#iaP.s#t.K#s.wbya0#P.1bm#G#0#0.BbSayb2#0.1#G#u#GbVay.8.8blbSa5bSa5#za5bAar.Z.gbaa9baba.O" "b2bS.8#N#T.Ja6bk.M.M.lbS#z#G#z.w#ubV#GbV.1#G#D.ra7bnaV#H#Hbnbn#D.l.4#2.E.6.6bT.T.X.X#u#D.1.1b4be.1#G#G#G.0#Gbcbc.1.1.w.1.w.1#D#G#D.0.0#D#GbVaybS#G.1.1#Dbn#DbnbV.SbA.KbVbK.4aZbD#F#ubVbSaybV.wbn" "#D.0#Dbn.1#sbQ#s#za5#z.w#zbS.y#ubV.kbVbVbVbVbVbnaW.l.l.4#Narar.8bCbn#HaVbnaVbebea0.w.w.1.1a7#u#7.1#s#H.1.w#Ha0#b#G.w.w.w.1.w#G#G.0#G.1#0.w#0#0.wbS.ebS.e.l.4.JbG.y#u#D.w.w.w#sbQbV#s#0ay#ubV#D#D" ".0bn#Gbn#D.R.R.RbV#G#z#0bV#u#u.y.SaBbYaB#t.4bA.ea5#zb2bSbSbVbV.w.0.0a7#Hb4#Hbn#7a5#z#z.w.wa0a0#bbeaz#b#b#bbn#D.y.1#G#G#G#G#u#G#u.1.1#b.1aybl#Fa8bG#T.8.eby.Wb0bP#G#Gbm#Gbm#G#G#G#sbn.w#z#G#G#zbn" "#z.w.w#zar.4#T.Jbv#F.ybSbV#ubSbVaY#s#s.Ka5.K#z.Kbl#u#D#G#D.rbd.ra5#0bS.BbVa5#ua8.ybla8#u#0#G#G#G.0#D#G.wbe#B#Ybe#P.w.w.w.1#0#G#G#G.1#P.w.w#0#0.w#baY#s.wbn.0#D#7ay.rbm.r#G#G#G#GbV#0#z#0#G#z.1.w" ".8ara5.Ka5.ear.e.w.w.wa0#bby.w#b#0#0bV#u#F#FbGbv.8.8ay#z#0#0#0#0#z#0a5aya5ayb2#0bV#GbV#D#u#u#D#Ga0a0bc.1bc#G#D#u#Day#D#GbV#G.w#s.w.w.w.w.w#z.w.waBbs.y#D#DbC.1bCbV#G#0.1#0#G#0#zbKbSbSbS#u#ubVbV" "#Hb4bebeazbeaz#Y#ubV#u#z#u.y.8#F.w.w.w.w#0.w#0#z#G#ubl#F#u#u#u#Fbd#u#D.0#7#7#7#D#u#D#GbV#G.w#bbebc.1#G#G.1.w#P.w#b.wby#s.w.w#s.w#z#z.KbA.4#F#T#2ar.e.ebA.ebAbAbSbQ.w#s.w#z#zbK.4.y.8bSbS#0bSbVbn" "bn.1a7bnbn#D###u.1#0bn.w#G#z#D#0#0bV.w.w.w#bbe#bb4b4#HbCa7#Dbd.ybs.R#D#u#u#F#7bs#u#u#u.ybA.S.4bLap#b.WbQ#z#s#z#z.8.4.8#2#2bG.MbT.4.SbA.S.4.S.K.Kararar.ea5.ebS.e.8.8.ybS#z#z#s.KbAbla5#0#0.w#s.w" "#s#z#s#z#z#z#za5#D#D#GbV.wbV#z#0.Ka5bKbAau.R.S.R.lbAa5.e#r#NaAaAa6.ZaW#N#N.e.e.e.BbSa5.earbOa6#Ebi#EbDbDa6#t.4.4.ebA.SbA.e.K.K#zbL.T.KbL#t#TbL.Kbn.1.1.1.w#Hbeb4bV#z#z#G.w#z#z.K#za5#zby#0bVbV#z" "#u#D#DbV#u#ua8#ubXau.y.y.ybs#DbsbK.SbL#RaIaI.C#3bw#t#R#R.S.S.S.y#t.gaPaP.gaT.Z.ObabaaP.Z.Z.Z.4.l#F#2#2#O.S.ebA.8.S#2aB.y#zbKbS.y#u#D.1.w.1bnbVbn#zbK.y.SbK#4.S#tbSbV#u.8.8#u.8#ubV.y.y.y#ubA#ubV" ".##q#qat.tas.2.2#A#A#AbH.H#C.H#CaMbI#x.GaZ.9bD.G.9bD.GbT#2#2aBaBbK.ybAbKbK.S.S.S#t.Z.Z.4bAbK#zbV#sbV.K.K.K#s.KbV.K.y.SbA.KbK.y.S.4.ybAbK.K.K.K.K.K.K.e.K#4.K#4bLa2#5.D#5a2aIaIa2aIbBbZbwbw.s.OaP" "ba.O.Obaba#.#.#..A.A#v.Abkbkbk.A.y.8.SbA.e.S.S.4.K.e.e.e.e#z#z#0bS#ubV#zbV.y.ybS#4.SbY.S.y.yaBaB.4#t#t#t#t.S.S.S.e.4.4.S.K.KbL.S#hbF.TbR.gaPbWaP#Z#ZbaaS.p#kb5b5bNa9#..O.O.Oaq.ObaaP.O.O#Zba.Y.Y" "#D#u#u#uaybSbS#u#s#s#z.w#s#s.1bnbQbQbQbQbQ.Q.K.T#t.4.Z#2#T.4.4.4bAbA.SbA.S.S.K.KbQ.K.K.K#5bLbL.SbO#R.T#5b.#5.K.kb.#5bLbZbZbR.Z.gaP#.aPbNbNbN.O.Hbwbwbwbw#3.O.O.O#2.4.8.8.8.8.ybAbA.e#z#s#z#s#z#s" "#5.TbLbL.TbLbLbL#m#gae.CaX.Caeae.Z.4#tbLbLbZbR#tbObR#tbR.4.4.4#t.saP.U#E.YaP.U#..UbWbibWbNbNa9#..gbW.Z.sbwaP.G.9aP#E.U#E#EaPaP.U.Y#3bBaIbw.Cb.#w.ybSa5bVbSbV#z.w#z#z#z.K.K.e.ea5bAa5.ea5.ea5a5.e" ".U.Y.YaTaT.Z.O.gbRbRbwbw#tbB.s.ZbTbT.Z#t.4.4.4a6#t.Z#t#t#t#ta6bDaIbZbB.n#m.n#3#3#X#.aq.HbH#..H#m.TbRaIa2.DaI.T#4bwbRbwbwbZb.bob.#4b.buaK#R.s.9#t#3.O.O.Obw.sbw.sbwbwbwbw#tbwbRbB.Z.gaP.gaP.gaP.g" "aB#FbSbVbV#D#ubVaya8bl.8aybS#u#u#zbVbV#zbV#zbK#u#u#u.y.8.ybA.ybA.4bY.4.4#t#tbDaZ#tbR.4#t.4#t#tbL.K#tbwaI#5aIbLbFaIaIbwbD.U#E.Ubi#EbDbD.ZbT#xbT#xabaRaR#oabat.O#Z.s#t.SbLaI#4aKb.b.b..Kbu.7.Qbub." ".w#b#b#Y.w#0.1#G#z#G#z#G#b#b#b#s.1#G#G#G.1bc#G#G#G#Day#G#G#G#G#G.w#G#GbV.1#z.w#b.kbnbKbn#s#DbVbV.K#t#iaP.ZbW.g.Z.s.s.gaPaP.Zbw.Za6.Z.Z.8#r#z#ra5#D.r.r.r#Gbcbmbm#G.1.w.wbc.w#G#G#G#G#G#Ga0#P.1.r" )) (define granite (list " 384 384 16 1" ". c #000000" "# c #111111" "a c #222222" "b c #333333" "c c #444444" "d c #555555" "e c #666666" "f c #777777" "g c #888888" "h c #999999" "i c #aaaaaa" "j c #bbbbbb" "k c #cccccc" "l c #dddddd" "m c #eeeeee" "n c #ffffff" "aacfedbbcbbaaaaaaaaabaabaaaaabcbcbbbabbchfdcccbbabbbaaabaabcbaa#aa#######a#aaaabcddeefhec##dgbabbaaadabbcfbaa##########aaabbaaa#a#####a#aa###a#aaabbbbcbbbccdedaaaaa#aaaaa#a#abaaabbabbbeddbbaaaaaca##a#aaaba########aaaadcababbabdehd.##.a######.cgdcb###b##.##.##aaaaa####abcba######a##aac#a##a####aa#aa##babbbcfccbbbcdccccecbbbcbbbcdccddcbcdfeecbhhjihhgffc.aaa####.#######aaaaaaaabbaaaaa" "aaacedccbbcbaaaaaa#bbaabbbaaaabcaabbbbbbafhfccbbbbbbabacbacbaaaaa##########a###abbcdeghhhcagb#ababaaccbacdfca#a####aa###aaaaabaaa#####aca#aabaababbcccccccbcdfdaaaa###aaaaaaaaaaabbbbbbccccccbbcbcaaa##aaaaabaaaa###abdaccceebaaaabehja####a######..#aeec#bb##########aa#####abba#########aaca########aa#aa###aaaabddbbbbbbbbbbccbbabbbbabbabbabcbcbcefhfeddccefhhijheecb#...a####aaaaaaaabaaaaa" "aaabccccccdbabcbaaa#aaaaaaaaaaabbabbbbbccabefdccabcbbabacccbaaabaa######a######aaabceiiiihije#bbabbaaeaabcedcaabaa########aaaabaa##a###ab#aabcababbccccccdeeeecc#a##a##aaaaaaaaaabbbbbbbcccbbbdcbbcdaa#a#aabbaaaaa###acbaa#bccaa#abcfig.#######.#######acddgefdda#######a########a#######aaaaaa#a######aaaa#####aaacdcbabbaaabbbcaaaaaaaaabbbaaabbaabbbcbcbabbabcdeefghjkjgc#..####aaaaaaaaaaaa#" "#aaaaaacbccbcabbbaaaaaabcaaaaabbbbbbabbbcbaabffccbccbccbbcbaaaabaaaa#aa#aa##a#aaaaabbikkjhijicabbbcc#faaacdebcbda#########aaaaaaaaa####aa##cacccabcccdccccdddfdcbaa##a##abbbabccbbcbbbccccaaa#abbaaba#a##abbbbbaaaaaaaaaaccaaca##aabcfic.###aa#######a####bddeeddb####.##.###aaa#########aaaa###aa####aaaa#######aabdbbbbcabbbaaaa#aaaaaaaaabaaabbbaabbbbdbbaaabccccccdcefhhkhda##aaaa#a#aaaaa##" "#aaabaabcecbaa##bcaaaaaaaababbabaaabbabbaabb#chhfdccccbcbecaaabaaaaaaaaaa####aaaaaaabdgjkkijijdabbdcabfaabcecbbec###########a#aaaabaa#######abbaaaadddedddeeefeccaa###a#aabcccdcbcbbbbccbbbbaaaaa#aabbaaaabbbbbbaaaaaaabbbbbaaa####acegha##a#aabbb####a##adccdedbcc#######.###a###a#######aaa#a#aa##..#aa#########abdbaabbabbbaa###aaaaaaaaaaaaacbaaababbdbabbabcbbcbcbccbbdegjkgb#aa#aa#aaaaaaa" "##aa#aabccccaaaaaaaa#aaaaaabbaabbbaaaaabbbcbbcfhhgfcccbbbbccbaabbaaaaaaabaa#aaaabaaaabbcehkljjdabacccbgbaaccdb#adea#########aa#abaaaaa#####ac#ba##accdedddefffeaba##a#aaaaacccccccbbbcccaabaaaaaaaaa#aaaaabcbbaaa#bbbbaaefccdbaaa#aaacdei##aa##aabbbaaa#a#cdcccccbcea.#########bbaaa######a###a#aaaa.#aaba####.###abcbaaabaabbbaa###aaaaaaaaaaaabbaaaaaaaaaaababcbbcbbaabbbdddeghheba##ab#abaa##" "#####bbaaaaabaaaaa##aa#adccaabaaabbbbabbabbbabccbccfdbccbbbbbcaabcaabaaabbaaaaaaaaaaaabbbcglli#accbbbddgabcddbbaacea#a##########aaa#aaa##aaaa####aabcddeeefffgdbbaaaa###baabbbbbbcdabdcbcaaabaaaaaaa#aaaaaabcbbbbadfbbbaejhhebbccaaaaaccfi.aba##abaaaba####ecbbccba#fc.####.##.bba#a#######aaaaaaaaaaa##aaaa######abcdaa#aaaabaaa###aaaaabaaabbbaaba##aaababcbbcbbbbbcbaaabbccccddgggeb#aadca###" "#####bcaaaaaabcbaaa#aaaabcccaaaaaaabaaabbbbbbbaacbabeeddddccbcbbcccbabaaaabaabaaaaaaaaabbbbglmdbcbaabebdgdbcecbbaabdbaa#########aabbaaaa#aa#a##a#aabbdceeedccdcbbaaaaa##aaabbcbbbabaaabbababbaaaa#aaaaaaaabcdccbbbabcbbbcfijfbcdcabb#abcbif#abb##aaabaaaa##fcccbbcaa#db#..##.##.aaa#########ab#aaaaaa#aabaaaaa#####abdbbaaaabbaaaa###b#a#aaaabaaaaaaaaaaaaaabbabbbbaabbbaaaabbbbbbbceffecccbaa##" "#####abaaaaa#accbbbbaaabaaaaaaaaaaadcbaabbabbbabbdcaacgfddddcdddcadfcaaaabcbbabaaaaaabcabbbdjliacbababcbdfcdeeaaaaaabba########a##aa#aabaa##a######abddeggca#bcbaaaaaa####aaaaaabbbbbcbbbbbaaa##a#aaaaaaaabcbccbbaaaabaabfgfiecccccbbaaaccicbbbcbaaabaaabb#ceccccdca##aacdb######aaa###a###aabaaaaaa#aabca#abba#####abca##aaaaaaaaa##a##aaaaaaabaaaaaaabaaaacbcbacdbaaabaaaaaabaaaaabbcddccbaa##" "####aa#aaaaaaabccbabbaaaaaaaaaaaaabfaaabbcbbbbbabdebaabdffddedefedccecccdcbbbbbccbccbbbbbbccekldaabaaabccbfaaaaaaaaaaaba########aaaaaaaaba##aaa###aabbccfgfaababbbaaaaa#aabbaabaaccaabcccbcbaa##aaaaaabaabbbccbbbaabbbbbbdddghdbbbcccb#abcdebcccbaabbbabbcbaecddddbaa##.#acdeca#######a#aaaaaaaaaaaaaaabba##abba####aacba##aaaaaaaaaaaaa##aba#abaaaaaaabaaaabbbbbbcbabbaabbaaaaabaaaaaaaaccbaa##" ".####aa#aabaa##bccbaabbbba#aaaaabbaefdaabbbbccbbbaddaaabadeeffhhhffdedddeecbbbbcccbbabcbabbcfjjlkeaaaaacdadcaa#aaaaaaa#ab######ba#aaabbabcaa#aa###babcddcedba##acbaaaaaa#ababbbacbbbcccdfffbaa#aaaacbaabcbabccbbcbbbbbbcbbccedbbbccdccbaabcgb#bccbbbababbbcccdededcb#a####...addcba##aabbbbbbbbaaaaabba#aaa##abba####abbaa###a#aa#aa##aaa#a##abaaaaaaaaabababbcdbcb#baaaaaaaaaaaaaaaaaa#aaaaa###" "######a##aaaaaa#accbaaabbbaaa#aaababdcaaabbbbcccbbbdbabbbacdccgecadbbbcdccddeddcccccbaabcbbcgjhhjgeb#aacdcccaa#aa#aaa#a#aaa##aaaaa#aaabbaabb#aa###aabccddeccbbbaabcbbbcbbb#aacbbadbabcccddbaaa#aaaaabbbbabbbbcdbbbabbcddcbbbccaabbbccbbaaaadi##abbbbbbbaabbbacdeedbd######aa####bceda#aabbabaaaaaaaaba#aaaaa#aabaaa###acaaaa####aa##aaaaaaaa#aaaaaaaaaaababaaaaabcaaaaaaabbcbaaaaaaaaa###aaaa###" "##########aabaa#accbbabbbbbba##aaaabbcbbbbbbbbcbaaabdbbbbbbddccbbbbaaaabbabbbbcefefdcbaadbcddje#debgfbabecdc####aa##a###a#aa#aa##a##aaabbcabbaa###aabbcceedbcbaaaabdcccbabaaabbbbabbccbbaaaaaa#aaaaaaaabbbbbcbccabcccccdcccbbbbabbababbba#abfe#aaaaaaaabccbbaaaedddc######adcaaaa##dfcaaaaaaaaaa#aaaaa##aabcaaabbaa#aaab###aa###aaaaaaaaaaaa##aaaaaaaaaabaaabaaabcabaaaaaaabcbaabaaa##a###aa####" "#########aaaaaaabbcbbbbabcbaacbaa##aaabaaabccccccbaabecabbbcddbacdeba#aaaaabaaabbdfgedcbaccdcgica#aadghdbddd#aa#aaa#a###aaaabaa#####aaaaabbbbbba#aaabccceecbddbaa#bbccabcbbbbbacccdbbdabbaaaaaaa#aaaa#aabbbbcccdcbcbbccccccbcaababbdbabbba#bbgaabaaa#aaacccdcddbeedba#a##a#aba#aaaa##decbaaba#aaa###a#a###abba#bba###aaba####a####aaaaaaaaaaaa#aaabbbaaabbaabbaabbaaa#aa#a#abbaabbbaaa#aaaa#####" "############aaaaaaacbbbbbbbaa#aaa#a##aaaaaaaacbbbbbbabdcabbbcdbaccdba#aaaaaababbcbbdddedccddefihaa#aaahiiiffd#aaaa#abaa##aaaaacaa##a#bcaaaabbbcaaaabccdddecabaaaaacbbbabbccccccbbdbdfdaabbaaa###a#aaaaaaaabbbbbbbaaabdcddccbbbbabbbccaabbbaabfdaaabaa#aa##aabbbbbddba##aa#a#aa##aaaaaabcdbbaaa##aa#####a#aaabbaaaaa##abb######aa###aaaaaaaaaaaaaaaaabaaaaaaaabbbbaaabaaa#aaaaaaabbbaaaaaaaaa####" "###########aa#aa#aaaccabbaaaaaaabb#######a#aaabcbbbabbaeebbccbcbacdaaa##a#aabbbbccbbcbcdegifdfgifba##aaaagigha#aaaaabbaaaaaaaaabaaa##acaaaaabbbbbbabcdddefeba####abbaabccccbbbcbadcbcbaabba#aaaa#aaaaaababacccbaadbabbccedcccbbccbbabaaaaa##ade###abba#aa##abbba#cebb.#a####.#a#aaaaaaaaacfca#aaa###aa###abaabaaaaaaaabbaa#######aaaaa#aa#aaaaaaaaaaababdaaabbbbbababaaaaaa#aaaaaabbaaabaaaaa###" "##########a#aaabaaaaccaaaaaaabaaaaaaba###a##abaaabbababaccbcbbcccaaba#a###aaabbccdccccccdeegggfigaabb#aaa#fffcba#abbaaaaaaaaaaa#abba##aaa##aabbbcbbbbcdeegfeb####aabaabacbbbcbccaabbabaaaaaaa##aa#aaaaababbabbcbcdbbcccbddcdcccabcbbababba###afba#aabba#acaaabbbbaddb##aa####.####aabbaaaabffcaaaaaa##a##bcabbaaaaaaabbbc#a#a#######aaaaa#####a##ababbbbbaaaabbcbaaaaaaaaaaa#aaaaaabaaababaaaaa#" "#######a#####a#aaaaabcbaaaaaa#aabaaaaaa###abbabaaaaaccaaabdbccbccbaaca#####accddcccccccddeeefikjeabcca#a#abfifbaa#abbbbbaaaaaaaaa#bbba#bcaaaaaaaccbcccceffeccaa##aaabbbcabbacbddbbaabdbaaaaaaaaaaaaaaabbbaabbbbbbbbbcbbccccdcdcccabbbbbaaba###dcaaaabbaaabaabcbccaadba#aaa########aaaa##aaaacgdbaaaa####cfffda#a#aaaabbdbaa#aaa########aaaa#aa##aaabbabbbaaabbbaaaaaabaaaaaaaa#aaaaabaaaaaaaaa#a" "a###########aaaaaaaabbaabaaa###abaaa#a##a###a#aaaaabacaaabccbbbcbbbcbb####a#bdfbbccccccdefecdgiiddaabbaaaabacfeaaaaaabcccbaaaaaaabaaacaa##aaaaaaabccddcfgfgbabaaa#aaabbcccbccbcddbbacabbbbbbbbaaacbaaaabcbabbbbbcbbcbccbccdccdccdcbaabbbaabaaade#aa#baaabaa##abbcbacdb#.#abbccc#.##aaa####aa#aeeaaaaaaabbabddfgfba#aabcd#aaaa########aa##a##aaaaaababbaabbbbbabccbababaaaaaaa##a#aaaabbaaaaaaaa#" "#a###a######aaaaaaaacdaaaaaaaa#aaaaaaaaaa#####a###abbbbaaaaccbbbcbbbbaa#aaaaaeecabcccbccdedcdfgigeaaaacbaaabaacbaaaaaaabcbbbaaaaaaaaabccaaaaaaaaaacccceffffbabb#a####aaaabcccccddcdedbbbbaabcabbbccbccbcbcbbbbbbbbbcecbccccceccccdccbbaaaaaaabce#bbaaa###aaa##ababcacda#abb##a#######a#########bfdca#abcbaabaabcffddbabdc#aaaaa##########aa####aaaaaaabbabbbbbbbcbbbcbaaaaaaaa#aa#aaaaaabaa##b##" "##a#########aabaaaabcdbabaaaaa##aaaaabaaba######a##ababbbbbabbbbcbcdddbbaa#abceecabccccccdddfedgjgdbaaabaaabbbaaba#aabaabaccaaaaaaaabbccbbbaaabaaabcddefgfebbbb#aa####aaaabbcccccbbfeccbbbaaababbbbbbbccba#abbbabbcdccdcbddcddcccdcddcbaaaaaabcfbadaa#######a#abbacbbcc###a#a########a######a##aabdcabccbbababaaaacdfededbbaa#aa##aa######ba#aa#aaabbabaababcbbcbcbbbabbaaaaaaaa##aaabaaacba#a##" "##########a#abaaaaabbbcbbbcaa###a#aaaaa##aba#######aaaaaabbdccbaabccdddecaaaabccdbbacccddcdefdfgiifcba#bbaaabbaaaababbbbbbbabbaabaaaacbbbcbbaaaaaaaceeeefffbaaaa###a##aaaabbcbbbddcddddcbcbbaaabbbbababbabaaabababbbbcccdccddcddccccdecaaaa#abccfbbaaa#######aabbaacabe###a#aa#a#a##.aa#######a#aa#cfeecdcccccabbbabacggcabbaaabbaaaa####aabb#aaaabbababbbbbbcccbbbbbcccbbbaaaa#aaaaaababbaaaa##" "######a####abcbaaaaabbccbcbaa###a##aaa##a###aa######aaaaaabdgebaaabbbccacbaaaaabbbaaabccddcdeeffgigbaaaaaabaabcaaababbbbaabbacbaaabbaaaababccbabbabbdffefhdcaaa###aaabba#aababcbdeeccceccccbababbbbabbabbaaaaaabbaabbcbcccccdcddddccccdcaaaababcdeaba#####.###aaabaab#b####a####a##aa#b########aaaaabedddcccccaaaabbcabeaaaabbccbaaa#abbaaabbbaaaabbbaaacbcbcbbdccbaabbacbbbbbaaaaaaaaabbaa#####" "######aaa#abbcbaaaaabdccbbaaa#######aaa#####aaa##a#a##aaaababcbbaaaaabdebbbaaa##aaaaaaaabccddeefggieaaaaaaaacabaabbbabbbbaaaabbaaaaaaabbbabbccbaabbbdfgghebbbaa#####abba#aabbbcbccdcbbbcddcccbbbabbabbbabbabaaaaaaacbbabcbbccccddddccbcccaaaaaabbdcbc##########aaacbbaa####a####aa###a#aa###aaa###abbceddedcccbaaaacccdca##a#abbbabaaaabaaabbba#aabbbbbbccbbbbaaacccbbcbbaaabbbbbbabaaabaaaa####" "#######aa#aaccabbabaabdecbb#a########aaaa####aaa#aba##a#aaaaaaabbdcaabdcbcaacb####abb#abaabccdeffghfdabaaaa#acbbbbcbabcabcbaaaabbbabaaaabbbbbcccbbbccdfedccbbb#########aaaababbacccbcbbbddbdcccccbbbbaaaabbaabbaaaaabaabbbbccdcceedccccacbaaaabbbbddb####aa######aabbaa####a####aa#aa###a#####aa#aabbddeccddccbbbabbbbceb###aa#aaaaaa##aa####aaaa#abbbbbccacccbaa#accbbbbbaaababbabaaaaaaaaa####" "##a#####aaaaaabbbbabacdddccaa########aa#a#####aaa#aa#aaaaaaaaaaaabcabbcbbbbababa###baaaaaaabccdeeehifbabaaa###abbcbbcaccbcbbbaabbbbabaaabbbbbbbbcccccddbccbbbbba#######aaabbbaabbcccbdcbbdbbddcdcccbabaabaaaaaaaaaaaaaaaabbcccddecccbbacccbbbaabbbceca############aaaaa#############a#############aaaaabccddcbbbabbbbbbba#####a##a####aaa#######aaa#babaabbcbaaa##abbbaabbcbbbbaaaaaaaabbaaa####" "#########abaaabbabbbbbddeccca##aa######a#aa####bbaaaaaaaaaaaaaaaaaabccbcccebacfdb#####aaaaaaabcdddcfgfccbaa##a##abcbbcbbdcccccabbabaababbbbbbbbbbcdccddbabbbbbba########aaababbbacdccccaabcbbcabddddbbaaabbabbbaaaaaaaaabbbddcddecbccbbbdcbabbbaabbcda#############abaaaa############a####bb##a####aaaaabcffdcccbbbbbbbb#######aaa###aaaa#######aabaaaabbcbaaaaaaaa#aaaaaabbccbbaaaaaabbbaaa####" "#########aaabbabcbbbbbdddcbaaaaa###############aabaaaa#aaaaaaaaaaabbabbdefffccbba###aa##aaaaaabcdceecggdcbbaa##aa#aacbb#bcdddddabbbbbabbbabbbbbbbccfeedbbbbbbcbba#a#####a#acababbbdcbcbabbabaabaabeedcaaaaaaaabcbbaaaaaaabbcdfdddccbbbbcbccbabbbaaabcda########a#aaaaaaa#aa#####aaabaaaaaaacb##aaa#aaababbcdefddbbcbccbaa#####aaaaaaaab##a########aa#abbcccbaaaaaa###aaaaabaabccbbbaaaaaaaaa####" "########aaaaaaabbbbbbcdedbbbbabaa##########aa###bbb###a##aaaaaaabbaabbbdfeedb##a#a##aa###aaabbbbccdefbfecbbbaaa####a#adb#acdecdfcbaabcbbbbcbbbbbbcdeffbcccabbcdbbba#a###a#aabaaaaaccccbaaaaabbbbaabdfedaaaababbbbbaaaaaaababbcedcccbbbbaccccbaaaccbbabeb######aaaaa#aaa###a######aaaaaaabacbca#aaaaaabbbbccdegfeccccccbcbaaa#####aaaa#aaaaa###a###aaaabbbcccb##a#aaa#aaaaaaaabbdeddcbabaaaaa####" "#########a#aabbbbbbbbdddccbbba#aaaa##aa##a####a#bba#a#a#aaaabaabbbabbeedeeefdaaaa#####bb##aaabbabcddehgifffdcbaaaa#aa#aaaaaccdeddcabbbcbbbccbabbccdceeecdcaaaabbcccaaaaaaaaaaaaaabacdddbaabaabbbbcccccfdbaabbaabbcaaaaaaababbcccccbbbbbbbccbcca#acbbbbbda#####aaaa####ab##a######aaaaaaabaccbaaaaabbbbbbccceffcdeedcbbbbaaaa#aaaaaaaaa#aaabaaaaaa##aaaabbbcbbcbaa#####aaaaaabbbcccddcbbaaaaa####" "##########a#aabbcbcbbcecccbbbabaaaaaa#####a#aaaabbaa##ba#acaaababbbbbbbcdcfgdbbbaa####aba##aaaabbbccdfefhfgedecaaa##abaaaaacbabebbbbbbbbcccbcbbbbddbedbddcaaaaaabdccaaba#aaaaaa#bbbbbaddccaaabcbbdcbbcbddabbbbbbbccaaaaaaaaabcddcbbbbbbbbbbbbbbaaaabbaabe#########a####bb#aa#####aa#aaaabccdbbbbabbcbbbccccdccbaaeffdbca#aaaa#aaaaaaa#aaaaabaaaa#aaaabaabbccbbcceb#bcaaaaaaaabbbbcdcbbbaaaaa####" "#######aa#aaaaabbccbbcdccddcabaaaaaaaaa###aaa#aabcaaa#bba#aabaabbbbbbabcccdfedcaa##aaa######aaaabbbbcdddghhgfedcbaaaa#aaaaabcbbbccbbbbbbbcbccdcccccbeebccbbbaaaaaccccccba#aaaaaaabaaabbbddbbbbcccbcccbaceeacbbbcbccbaaabbabbbbceccbbbbbabbbbbbbab#aabbbbcc#.######a####.bcbcba####aaaa#bedccbbbbbbbaabccddedaaaaa##beeda#aaaaaaaaaaaaaaaaaaaaabba##babbabbbbcbbbccccbbaaaaabbabaabddcbbbaaaa####" "##########aaaabbbbccccbcddddbaaaa##a#a#a###aaaa#baabbaaaaaaaabbbabcbaabccbddfebaaba#ba######aaaabbbbbcddfiiigggedbaaaaaaaaaabcbabccbbbbbbbcccddddccceecccccbbaaaabccddbbba#aaaaaaaaabcbbbcccdccbcbabcbabceecbabbbbbbaaaabaabbbcddbbbbbbbbaabbbcbbbbaaabcbdc########..####ccccba#abbaaaabddbabbbcabbbbcccceeca###aaa##aaa##a#aaaaaaaaaaaaaaaaaaaaa##aabcbbbbbbbccbbbbcddaaaaacbaaaabddbbaaaaaa###" "############aaabbabcddccdbcdcbcbbbaaaaa##a##aaaa##abaaabaaaaaaabbaacaabddabcefc#aabaaa###a####aaabbbbbbddgihhfffgeaaaaaaaaaaaaabbbcbbbbbbbbbcddeeedceccdcccccaaaaabcbddbaa#a#ab#aaacbbbbbbddebbbbccbbbabbbedbaaaaaaaaaaaabbabbccecbbbbccbbbbaabbbbcc#aaabbcc######a#####.bccabbacbababaabdcabbbabbabbbcbdecabaa##aaaa####aaaaba##aaaaabaaababa##aa#aaabbbbbbbbcbbbbacbedbaaa#bbaaaabcbbbbaaaa#aa" "#######a####aaaaabaabbcccbabbbbbbbcbaaa######a#aa######aaaa#aaa#acbbbabeeebabddbaaabaa####aa#a#aababbbbbcehhgeeffdca##aaaaaaaaaabbbbabbbbbbcdcdddfgfhcbbcbbbcbaaaaabcccdbba###baaaabcbbaabcdeecaaabbbbbbaabddecaaaaaaaabbbbbbbccfcbcbbbbbbbaaaaabbbcca#aabacc#######a####acdcbbbbbbaaaabbccaabbbbbbbabbceecabb#aa#aaaa#######aaa##aaaaaaabbaaaaaaaaaaaabbbaabccbbcbaaacgdaaaa#aababbbabbbbaaaaa#" "###a#####a#aaaaaabcbacbbddcaaabbbbbbbaaaaaa##a#####a####aaaaa#aaabdbcbbedefcaaabaaaaabaaa#a##abaaaaababbbcfgggfeefea##aaaaaaaaaaabcbbbbbbbbcdcdddefgeabbbbaabccaabaaceddeeaaa##aaaaaabbbabbcdedbabbbaaaaaaaacfecaaaaabaabbbbbbcdfdbccbbbbbaaaaaabbbcdbaa#aabdb#########a#acdcccbaaab#aabccbbbbbbabbbceedccbcbbaaaa#baa#a###a#a##aa###aaaabaaaaaaaa##aaaabbaaabcbbbbbabbdfeaaaa#ababbcbbaabaaaaaa" "#####a#####aaaaaabbbbbbbcddcbabccaaabbaaaaa#a##a##a######aaaaaabaaaaacbbbffeaaaababbabbbbbaa##bbaaaabbbbcccghghgeffbaaabbaaaaaabbabccbbbbbbcdddefggecccbabaaabbbacbabbdddecbaa####aabaababbcccdcabaa#aaa###abceedcaaaaabbbbccddefdccdccbcbbaaaaabbccdccdb#abbd###a#####a#a#cddcccaaaaaaaaabccbbbbdeefbba##aabaaa#aaaaaa#aa###aaa##a####aaaaaaaaaaaa##aaaabacbabbbbbcbbbbcfgbaaa#aa#abbab#aaaabba" "##########abaaabbbbbcbcdcccdcbbbcbbbbbba#aaaaa#a############aa#aaaaaaababbdeaaaacbbbbbddcbaaa##abaaaabbbbcccghhhedecababcbaaaaaababcbbbbbccbddceggffecccbbbaaabca#aaaadddedcb#a##aaaabbbabbbbcccdd###aaaa#aa##bcefeddcddccefdddfdcccccccccbbaaaaaabccccdddaabbda########ab##bbbddcbbaa#aaaabcbbbcdddccaaaaa#abaaaaaaaaaa#aa#aaaabaa#####aaaaaaaa#######aabaacbabbbbbbcbbbbdfbbaaaa###baabaabaaba" "###########aaaabbcbbbcccbddbcdccbbbbcabbaaaaaaaaa###a##aa###aaaabaaababbccbbdb#abccabddbbbba#aaaabdbbaabbbbcdehihbaabbbbcdcbbbbaababbedcbbaccdddeeefedabbabaaa#aaa#aa#beeeeffca###aaabbbcbbbbbbcced#a###a##aaa#abffgfedcccfhcbdebcbccdccccbbaaaaaabbcccccddbaabdcb#.#aa#aaa##abdddcbbbaaababbbbbcbdbabbbbbb##ababbbaaaaa#aa#aa##aaa######ababaaa#####a#aabcbbbabbbbbbcccbbbeabcbba###aaaaaaaaaab" "b#########aaaaababbbbabbbbdebcccccbbbabaaaaaaaaaaaa########aa#abbaaabbabbdbcbbbaaadcbcbdbabba##aa##abcb#aaabcdcfhgdabbbccdcbcbbbbbbabcgdcbdbbdedeeehfgdbbbbbaaaa#aaa#abddddgeedcaaaaaabbbdccccccbceeaa###a###aaaacfghhgedccggefbccccccccccbbbbbbaabbcccccccdaabaaccb#aaa###a##adedccbcbaaabbbbcbbcddbaaabbbbaadbbaabbaaa##abaaa#aaaaaaaa#aaabaa########abbadccaaabbbcccccbbdcbcbbba###aaaaaaaabb" "aa##########aaabbbbbbbaabbaccbceeebbaabbaabaaabbbbaaa###aaaba#aabaaaaababbccggcbaabccbbbccbca##aaaabdbbabbabbcdddghbabbccddcbbbcbbbbbccgfcbccceddddeddedddcbababaaaaaa#accdeffedbaaaaaaaacccccbbbccffb#a#####aaaaabfhgghhhhgghecbccbccccccccbbbbaaabbbbcbbbcdcbbabbcb#####abca#abccccccabbbbbbbbbdddbaaaaabab#cdba#aabaaaaaaaa#aaa#a#aa#####aaaa#######aabbbbccbbbabbdeddcbbeaabbcb###aaaaaaaaab" "baaa######a#aaabaabdbbcbabbaccccedaaaaaaaaaaaaaaadbaa#aaaa##aaaaaaaaabbbcbcccdbaaaaabdcbacbcdcaaaaaaaabaaccbbccdddhgcabcccdecbcbbcbbabadedbbcdedcddeeccdddeeedcbbcbaabbbabbcddddec#aaaaaabbcccccbccdffc##a##a#aaaaaafheffhgeccefcbbcbcccccccbbbbaaabbbbccbbddedbabbcc.##a##abc###cdcccbcbbbabbbaddccababbbaaabaddba##aaaaaa#aaa#a#aaaaa##aa##aaaa#######abbbbccbcbbbbdefeeccecaaaaa####aabaaaaaa" "bb#a########aabbbaaababcccdaacdbbaba#aaaaaa#aaa##acaa###aa#aaaaaaaaaaabcdcccaaaaaaaaadbcbbbbacc###aaaaaaaacbbccdcdfggbbbcccdecccddcbbbacdfdbcdebbbcccdcccccdcbefccbaaaaabcbbccabdfcaaaaaaabbdddccccccefe##a##aaaaaaaadfghhhdbbcccccbcbbccdccbbbcaaaabbbbdccddeeba#bbda######.acabbddccabcbbbbbbbddccaaaaaaaaaaabdca#a#aaa#aaaaa##a#aaaaa##aa##aaa#a##a##abbbbccbbdbbccefffeccd#a########abaaaaaa" "aa##########aaaaabaabbaaccdcaacbbaab####aaaa#aaaaaa#a####abaaaaaaabcaaabddcacda#aaabacbbbbddddcbaaa##aaaaa#abbdcccdegfbbcdcdefccddccccbcbbfdccecabccbcbbbcdddcbffdcccb#aacbaabcbbeecaa#aaaabcedddccccddfeb#####aaaaaabbehhfcccbcccccbbccccccbcbcbbaaabbbcdcceddcbbabba########bcbbcdcbbbbbbbbaacccccaaaaaaaaaaaabcba####aba##aaaaaa#aaaaaa##a#aaaaaaa#aaabaabbcbbbbbbbdffffeeeaa########aabcaaaa" "aba#a#aa####aaaaabbabbabbaccaaabaaaa#######a####aaaaa####aaa#bbaaaabaaacbddcbccaaaaaaaaaaacdeabcbba#a###a#aaabccccdeegfcbcdddeedcdccddccccfedddcbbccbbbbbbccddedecccdca#aaaaaaabacedcddcbabaabccccccccceccd####aaaaaabaacdghhfecccccbbccccccccbcbbbaabbbcccccddcddceaca########cdccdccbbbbbbbbbccbcdcaaaaaaaaaaaaaaba#####aaaaaaa###aaaaa##a####aaaa###aabbbbbbccbdbbbcdefffgaa#a#######aabaaaaa" "aa#####aa###aaababbccccbbbbcbaaababa#######a#aabaaaaaa####aa#abbaaaabbaabbdcbbcdbbbbaaaaaabcddbcbba#####a#aaabcdccceefhgbbdcceeeeccccccddeefeeecccacccbcbabbccdefdbcebaaaabaababbbcdcdfffdabbbbbcccccccecade#aa#aabaaaabaackijkidbbbcbccccccccbcbbbbaabbccccccccddegfdaa#######ceedcbbcaacccccbcccccbaaaaaaaaaabaaaaaaaaa####aaa.baa######aaaa####baaa#aaaabbbbbccdcbbcddedfgfb##########abbaaa#" "#a########aaaaaaccbbcdcccbbbba#aaaaaa#####aa#aaab#aaaa#.###aa#aabababcbabaccbccdedaaaa#aaaaabccacbaa#a######aacbcccdffhigeccccdeedddccbcddffdefcbabbbcdecbabbbbcddecddbbaaabbabbbcccddeeffabbabbbbcccccdecdedb#a#aaabbaaaaahifgikfcbcccccccccccbbaaabbcbbbccbbbbcccdhea#a#####aedfebccccbbcbcccccccbaaaaaabaa#aaaaaaaaaba#b###aaa#b#######a####aa##abbbabaaabbbbbcdecbbcdedefghc#########abcedcb" "a############a#abcbbbcddccbbbcaaaaaa#a####a#a###ba#aa#######aaba#bbbbbccaabcccddeebaaaa##aaaabaaabaaaa#####a#aaaabcbdeggihfccccdddffdcbcccdfcbcbbbbbbccbbbbabaabcdfebcbbca##aabbbbcdcdfffeeaabbbccbbcccdeeddeed##aaabaaaaachgcccfijebbcccccccccbbaaaaabbbaabbaabbcbbcfecaaa#aaadcddbbdcccabbcccbbbabbaaaa#aaa###aaaaaaaaaaaaa##aaaaba######a######a#abbbbbbabbcbbbddcabcddddefgfa########aacedcc" "#######aaa#####aaaccccddcdcccbbaaaaa####a####a#aaaa#aa#######abaaabbccacdaadccdddccba#aa#bbaaabaaabaaaaaa#aaaaaababbbdeffiiebcccdddeedcccdcfbcbbbbaabcbbbbbbaaaabcdeefeeddedbaaabcbdccefffffabbbbbbbbbcdcdddddefbaabbbbabaeidccddcejgbbccccccccbbbbaaabaaaaabaaabccccdffebaabbaaddcc#cdccabcccccbbbbbaaaaa#aaaa##aa#aaaaaaaaabaaaba#b##a####a#a#a##a#aabbabbaabbbbddecbbdcccddeega.##.#a##aab###" "#########a#####ababccbbbdcccccabbb##aaaaaa#aaaaa##aaaaaa#..###aaaaaaccbbdcbbccdbccdaa##a#a#aaaaaa#ba###a#a#aaaaaaabbbcdeefhgeccedbbcdedeedgebbbbbbbbcdcbbbaabaaabacccddccccbdcaabbadddeefffgfbabbbbccccccccdddbggbaabbbbabhefcccddddihdccccccccbbbababaaa###aa#aabbbcdeeffa.##abcfedabccbcccabcbbbbbbabaaaaa###aaaaaaaabaaaaaaaaaaaaba#######aaab#####aaabaaaabbbaceffecbccddccdec#####.##aa#aa#" "#aa########a####abbccbbccdcccbbbbba#a##aaaaabaa#aa####aaba#.##baaaabccdabdbabbbbbcccbaa####aaaaaaa#aaaa######aaaabbabccdfeehihfggfdbceedddeddfdccbbcbbbbbbbbbbaaabaccccbbccdddecababedefffffhgdaaabccbcccccdddbfhfbbbcbbackdeeccdddccfhgbccccbbbaabaaabba#####a#aabbbdeddeda.###aeddcbaaccccccccbbbbbabaaaaaaaaaa##aba##abbaaaaaaaaaab######aa##aa###aaabbbaaaaabbbeffffdcdcdeffda######.###aaa#" "#aaa############aabcdcbcdcfedeecbbaba##aaaaabaa###b#a##aaaa####abaaacdcaacdaacbcaaaaaaaabc##aaaabaaaaaa######aaaaabbbdddeddfhhhhhhfcccffffdbaabcbdbabbbbbbbbbbaaaaabbcccbbbbcfdedbbadeddeefdefhffecbbcbcccccceddgibbbbbbdecccbbccccddddhidccccbbaacaaabba########aabccedddeda####cdcecbccccddddcbbbbbabbaaa#a#####a#######abaaaaaaa#aaaa#a##aaaa#a####aabaaaaaaaaabccddfgfddefge################" "##aaaaa#aa######aaabdccbccdeefebbaccb###aaabcbaa########aa######aaba#bdbbbcabbbbbbaaba##aba#####ababaaa##a#a##aaaabbcddedddeeefhghfddccdhecbbbaaaababbbabbabcbaaaaaabbccbbbbbbeefdbbbddbddffdggihiebbbcbbcccccedeicbcbbcdccccccccddddddcfifccbbbbabbabbbaaa####aa#aabcedddefeb##.bdcdeccbcccdddcbabbbbaaaaaa#aa############abaa#aaaaa#aaaaaaaaaa#######aabaaaaaaaabbabbcefgecbcc############a#a#" "##aaaa####aa##a##aaabcdcbbccdcdccbcaba##aaaabbbaa#aa#a####a######aabaaabaaaaaaaabbba#aa###a##a###abbbaa#aaaa#a##aabbcededddddeghggcdfedffddcbbbaaabbbbbccabbbbbcaaaaabccbbbbbbeccefdbcdbcbcefefhgghdbbcbcccccccdcefedbadccbbcccccddddddddeggcbbbaacaabbbaaa######aaaabdcdeedefbaa#deddcdcbbcdedccbbbcbaaaaaa##################aaaaa#aa##abaaaa#aaa#aa##aaaaaaaaaabaabbacdbacbaaba###############" "##a#aaa####aa##a##aaabbbbbcdeccbbaaaaabbaaabbaabaa###aaaa#########aaab#aaaaaaaaabbaaaa#a#a#aa#a#aabaaaa###abb##aaaaabcdeeddefghhhebbbfebbdddccbbbbbaaabdcbcbcbacbaaabbabcbbcccddbbcefecdcbbbcddehgggcbbcbcccccccdddffbbdbbbbbccccddddddddddegcbbaabaaabbbaaa######aaabbbcdefdeca#ddedcdddbacadedccbbbbbabaaaa###############.####aaa##a###a##aaa#aaa#abaabaaaaaaaaaaaaabcdbaaaa#a########a##a###" "a##a#aaaa#####aaaaaaabcccbbcdebbaaba#a#bbaaabbaaaa####aaa#####aa#abaaaaaaaabaaaaaabbbaaaaaa#aaaaaababaaa####aaaaaaaabcddddefedhhgbbbbcefbcdedcedabbbababbbcbbbbbbaaabbaabbbbbcbcddbbbcdcebbbbdcabehhebbbbcccccccceddhfddbbbbbccccddddddddddcdfdaaaaaababbaaaaaaaaaaabbbbccddcdfededffddddcbcabcddccbbcbbaaaaa#####################aa##a#a#######aa###aaaaaa###aaaaaaaaaabbccaabaaaa######a######" "aaaabaa##aa####aaaaaabbccccbcccaabbba#a##aaaabbb######aaaaba##aaaaababb##aaaaaa#aabaaaa#aaa#aabaaaaaacbaa####aaaaaaabcdeddefefhheabbbbbdfgfgedcfaaabbbbbbaaaaaacabaa#baaabbabaabbdeeeccabdccbbbcaachifbbbcccccbcccddejkeabbbbccccddddddddddccceebabbaabaaaaaaa#aaaabbbcbbcccddefgedfedddcccbaabcdcccbcbcaabaaaa########.##.########aa###a########aaaaa#a###a###aaaaaaaaababccaabaa#########aa#a#" "##aaaacb########aaaaabbbbcccbdcddbbcbc#aaaca##a#aba######abca#aaaa#aa###aa###aaaaaabbaaa#a###aaaaaaa##bcbba###a#aaaabbceedddehgfdaaabaccbfhiihffcaaaaccbaaaaaaacabaaabbaabcbbbbbbbcbdeffedfdb#acaabafjgbbcbcccbccccdefiicbbbbacccddddddddccccbbcfbbbbbabaaaaaaaaaabbbcbbbbccccdegfecfdbaabdabbbbcccdcccbbbbaaaa###################a#aa##a#a##a####a#aaaaa###########aaaaaabbbbbaabaa#######aa###" "###aaacba#######abaabbdcbbcdcbbefcbabcbbaaaaa####aa#a#a#a#a##aaab###a#aa####abb#a#aacbaa####aaaaaaa#aaabdcbaaaaaaaaabaceefeeffffbaaabbabccehigfeeddefdbabaaaaabbbabaabaaaaabbbbbbabccbabdedda##aaabbachhbbcbccccbbcccdeghebbbaccddddddddddccccbacecbabaaaaaa#aaaaabbbccbbbbcccdcdgfdfebbbbbcccbcbcddccccccbbaaaaa################aabbaaaa####aa###a##aba#############aaaaabbbddbbaba##########.#" "####aaaba#######aaaaabdfdbbcccbbdebbaaaab#aaa#a###aa###aaa###aba#####aaa#####aba#aaa#baaa#####aaaaa###aabcccaabbbbbcbbbdfffgeccebaaabbbbcbbeffedccfghhebaaaaaabbaaaaaaaabaabbabbbbbacbbbbcbdda####abbabghabbbccccbbccddddghdaabcddddeedddddcccbbabdfdaaaaa##aaaaaabccccccbbccddcbefdffdcbbbcdccbbccddcccccbbbaaaa################bbccbaabaa#aaaaaa#aabba##a#########a#aaaaabbccbcabaa###########" "#####aaaba#######aaacccefcccbcdccbcbbaaaaa#abcba#########aaaaaaa######aaaa####aa##aaa#aaaaaaa##aaaaa##aaaccddcccdddddcceeffdccdccbaaaaabbbbcfggdddfffggfebaaaaaaaaaabaaabccbbbbbbbabccbbbbbcbdb###aabbbbghbacccccccccccdddfigdbcddddddeddddcccbbbabbfeabaa#####aaaabcccccbcbdddecegfffcccabbccccbbccdcccccbbbbaaaa############a#aaaababaaaaaaa#aaa##aaaa#aaa##########aaaaaabbcccbbdba#########." "#####aaaaa######aaabddefcccbabdccccbaaaaaa###aaa######aaabaabbba#######aaaa####a###aaaaaa#a##a#aaaaaaaaaabcddddcdeeedefgfefecdaabbaaaaabbbbbadfebcfdfgffeeecaaaaaaabaaacabdbaaabbbcdcbbbbbbbbccb#a###abbaegcabccccdcccccdddcfihfdccdddddddddcccbaaaaaddbaa######aaabccccbcbccdddhfcfgecccbbbbcbccbccbccbcccbbbbaaaa#a##########aaaaaabccbcba#aa#aa#aaaaa#aaaaa###########aaaabbaddedaa##a#.#####" "####aaaaaa#######cffdabcbcdcbbadfbcbbaa###a#aaa#aaaaaaabaaaababaa#######a##a#########aaa##aa##aa#aaaaaaaaabdeddccddddddffeeeec#a#aaabbbaaabbbcggdcfeeeeegfdccbabccbbaaabbbcaaaaabbbcdbbbbccbbbdbaaa###abbccebabbccccbcccccddcdfhjhedddddddddccbbaaaaaabdda#######aaabbddccbbdddedccdgeeedccbbccdccbccbcbccccbbbaaaaa#########.##aaabbaabbbcbaaa###aaaaaaa#a#a#a########aaaaabbaccddeb###########" "########aaa######acddbabcbbcccabcddcaabbaaa##aaaaaabbbcaaaabbaaaaaba########aaa#aa###aaa###aa##abaaaaaacbbbcdffeddeccdffffeddbaaaa#abbaaaabaabegebdfeddeffeddddcdddcabbacbcbccbaabbacccbcdbbbcdb#aa##aabbbbbffbbccccbccccccdddedfkkidddddddcccbbaaaaabbabdb#a#####abcccdbccccddfcccdfgeedccbbbcbccccbbabbcccbbbbbbaaa############a#a#aaaacacbaaa####aaa#aa###a##a######aaabaabbbbbbdfa##########" "#################abbcbaacccccbccaacbcaaaaaaaaaaaaaaabccabbbbaaab##bb######a#aba##aa##aaaaa##a#a#acabbbacdcbcddffffdgeefefeddcb#a##aaaaabaaaaaaddfdcfdccccccdcbcbcccecbbabccdddddcbbbbccccccbbbceb#aa###aaaabbfgbacccbcccdcdddeedgjkihccddcccccbbaaaabaabaadca####aabbcccbcddccefdcdeeeedddcacbccccccbabaaabbbbbbbaaaa###########.#####aaaabacbba##aaaaaaa####a####a######abbabbcbcbcdb###a##.##." "###########aa#####bdbaaaaccddbbdcba#bbaa##aa#aaaabbbbbbaaabaaaaba##aa.####aaa##a#aaaaaabbbaa#####abaabbbbbccdddeefeffddefdccaa####aaaaaaaaaabaeefdedeccbabbbdddbbccccabbbbbbbbcdcccbcccccccccbaaaa#a####aaaabacgcabbcccdddefffedgijfehdcccccccbbbaa#aaaaaaabcbaaaaaabbccdcdddefgecddeefedccbbbabccbbbbaaaaaabbbbaaaaaa################aaabcbabbaa#aaaaa#aaa###a####a####aaabaabcbbbcbba###aa####" "############a#####abaaaaaabddccbcdddbaaaa###aaaabaaabbbaaaabbabba###b######aa######a##aacbcbba##a##babbccccdddddeeefgfeedccdb####a#aaaaaaaaaaadefedecbabbbbbcddddbcddcaabaaaaaabbbbbaabbccdcccbbbcb#a##aa#aaabbbfdbbccddddeffffefggeedjhedcdcccbbaaaaaaaaaaabbcaaaaabbcdcccdeefgdcccdefeccbbbbbbbccbbbbaaaaaaabbbaaaaa#######aa######aaabbbcab#a#aaaaaaaa#a##a#####abaaa#abaabbbbbbdccc####aa#.#" "###aaa###a#a#a####aabaaaaaabdbbbcecdcbaaaaaaaa#aaaaaaaaaaaaabccbb###a########a#a#aaaaa##aaaabca#a##aabbccccccdcccbbbbcbcabbbb#a#a#a#aaaabaaaabbeffddeabcbbbbcccccdccbbbaaaaa#abaaaaaaaaaababbbbbcbb#a##a##a#aaaabefcbdeeddeffffffeddfbchjieccccbbbaaaaaaaaaaaacfcabbbbcdddcdehggffeeddgfecbbccbbbccbcbbaaaaaaaaabaaa######a##aaa####aaaaaaabbaa##aaaaaaa#aaaa#####aabbaaaabbbbbbccccddbaaaa####." "####aaaaa#aaaa#aaaaaaabbaaabccbbbcddbbdcbaaaaaabaaaaaabbbbaaaaabaaa###############aaaaa##a#aaaaaaaaaaabbccccdcbbbaaaaaaaabaaa#######aaaaabbbabaacffffbbbbbbbbbbbbccccbaaaaaaaaaaaa##aaaaaaabbccca#######aa###aaaabcgfcdeeefgggggggeffcbbehkjebbcbbaa##aaaa#aaaadheabbbcdddcegfbccdfffgggedccccbbbbbabbbaaaaaaaaabaaaaaa######aaaaa#aa##aaaabaaaaaaaaaaaaa##aaa##aaa#acbaaabababbcccdecbaaaa###a#" "#######a###abaaaaaaaaaaabbdccccbbbceefebcaaaaaa#aaaaaabbbcccaabaaa###aaa#######a###aaaba##aaaaaaa#aaaabccccccbbbaaaaaaaaabaa###a###a#aaaaacbababa#eeedbbbbcddbcbccbccccaaaaaaaa#a#aaaaaaaabbbbcba########aa####aabbbghdeeegggggghggfedbbbcdikgbbbbbaa#aaaaaaaaaabheaabccddegdccccdddccfffddbbabbbcbbbbbbbbbbbaaaaaaaa########a###aaaa#a#abaaaaaaaaaaabbabaaaaaaa#a##ccaaaaaaaaaabcccbacaaabaa###" "##a#aa#####aaaaaaaaaa#aabbbabbcbbabcdeedcbbbaaaaaaabbbccdddccccbbccbdcbcca########aa####aa##a#aaa###aabbccdccbbbaaaaaabaaaaa#########aaaaabcaaabaa#dfcccbcccbcccccdccccdbbaaaaaa###aaaaaaabbbcb######aa###aaaa###abbcfheeffghhghhijifcbbbbbehjhcbbba##aaaa##aaa##afgdbbcefecdcdccddddddeedcbabbcbbabbcbbbaaaaaaaabaa######a#a#a###aaaa#aaabaaaaa#aaaaaaaaaaaaaaaa#a#bcaaaaabaaaaabbcccbcabbbaaa#" "aaaaaaaaaa#aaaaaaaaaaaa#abaa#aaaaaaaaabcbbaabbbabbbbccddddddefdbcdccdecddcaa##aab######baaaa##ab###aaaabbbcccbbaaaaaaaaaaaaaa########aaaaaacdbaabaa#dcabccdddcccccdeeddddddbaaaaaa###aaaaabbbca#a#########a###a##aaabcegefgfhhggiiihddbbccbbfegihfb###aaaaa#aaaa##adgfefecbddccccddcedccefdcbabcdcaabbbbbbbaaaaaaaaaa#a####aaa#aa###aaaabaaaa#aaaaaaa#aaa##aaabaa##abcbaaa#aaaaaaabbbbdddbbbaaaa" "aaaabbabaaaaabaaaaa#a#aaa#abaaaaabaaaaaaaaababbbbccdddeeefdfffedccbbbbcccccaaaaacb#abaab#aaba#aaa###a#aaaabccbaaaa##aaa#abaa###a##a#aa#aaaaacca#abaaadbabddddfededcbbcaaabcddcaaaaaa###aabbbcdca######a####aa##aaaaabbcdkgghhhhhgiigecabbbccffedgiida#aaaaaaa#aaaaaabfecbccccbbbabbbddddddccbaaacdcbbcbbbbbbbaaaaaaaaa##################baaaaaaaa######aa#aaaaa#a##abbbbaaaaabbaaaababbddcbbbbaa" "aaaaabcccbbbaabaaaaa#aaaaa#aaaaaaaaaaaaabaaabaaabbbcdffefgffdcccdddcccccbaabaaacbab#aa##aaabb#a#a##aaaaaaabbbcaaa###aaaa#aaa#a###aaa#abaaaaaacccbaaaabcbaaccbbdccbbbababba#abccbaaaaaaaaaabdeabaa##########aa####aaaabbceghghhihiihhgcbbbbbbegdcdedhhdd#aaaaaaaaaaaaabdccccccaaabbbbcddddfeffdbbabcbbbbbbbbbaaaaaa###a#########aa#######acbaaa#####aaaa##aaaaaaaaa#a#aaaaaaaaaabbbbaabbccddbbbba" "aaaababbbccbbcbaaaaaa#aaabba#aaaaabaaaaababbbbbaaaaaa#aabbcaaabbbbbbbbbcbaaaaaabaaaa####a##aaaa######aaaaaabbbbb#######a#aaa#a###a##a#aaa#aaacbbcbabbabcabbbcddbaaabbaaaa##aaaabbaaaaaaaabbcdbaaa###########a####aaaaabbbcfihghhhihhhdabbbbbbeeccccbdehfaa##aaaa#aaaaaabedccbaaaabcdcddcbfeffddeedccbbbbbbabbaaaaa#############aa########ababaa###aaaaa###aaaaaaaaa##abaaaaabbbbbbbbbbbbcdffabaa" "aaaaabbacbbbabaaaa#aaa#aaaacba###aaabaaaaaababaaaaaaaaaa##aaaaaaaaababbccc###aabaaaa##a##aaaaa#aa##aa#abaaaacccb##a#a#a#aaaaa####aaaa###a#aa#ababdbbbabcbabbbbbbbbbcbbaaaaaaaaaaba#a###aaacbcdaaaa#########.#####aaaaaabbccfkjgfhhifdfdaaababbffcbbbbbacgda#aaaaaaaaaaaaaddcba#aabccccdbbdeefeddfdfecbbacaaaabbaa##############aaaaa#######a#aa###aaa####aaaaaabaaaaaaaba#aaababbbcccddddgihcabb" "baaaaababccccbbaaa##aaaaaaa#cddb#####aabbbbaaaaaaaaaaa#####aaa##aa#aabadedca#abbaaaaaa####aaaa#a#aaaaa##aababcbca#aaaa#####aa###a#aa##aaaaa#a#aaacbaabbbcbabcccbbbbcbabba#aaaaaaaa#bbaaaaabbadb###################aaaaaabacbgkkihhggfedaaaaaaaceecbaaaaabffgeca#aaaaaa###acdca#aaacbbccbcbeeefffdabdfecabaaababbaa#a##########aaaaaa#######abaa##aaaa#####aaaaaaaaaaaaaabaaabaabbbbbcdegghffdabb" "bbaaaaaabbcccccbbaaaaaaabaaaabccca###aabcceebaaaaaaaaaaa#a##a#####aa#aaaddbbaaabaaaaaaaaaaaaabb##abb#aaaaaaabcbba##aaa###aaa#########a#aaaaaaaaaaaaaabbbccbaabccbcbbbbbaaaaaaaaa##aaabaaaaccbed#################.##aaa#aaaaacekljihhhdbaaaaaaabdeedbaaaaaabceffdaaaaa#####abdd##abbbbccccbcedfeddbbbbdddbbaaababaaa#################aa#aa.###aa##ba##aa###aaaaaaabaaaaabaaaaababbabbbdfhjifeecba" "bbbaaababaabbcccbaaaaaa#aaaaa#aaba##aaabcbbccbaaaaaaaaaaaaa#aa####aaaaaabccbaaa#aaaabaabaaaa#abdca#acaaaaabaabbaba#aaaaaaabba##aaaaaaaaaaaa##a#aabbbbbbbccbbbacbcbabbbbbaaa#aaa##aaaaaacbccccdbbba#a########a#.####aaaaabaaaaafklljhfcaaaaaaaa#dcgfcbbaaabccccdggcbaaaaa#aaaacdaabbbbbbbbcbddeeddccccbbcecbaaaaaaaa#a##############aaa##a####aa##b###aa#aaaaaaaaaaaaaa#aabaaaaaabaabbdggghhfbdeb" "bbabbaaaaaabbcbccbabba#aaaa##a#aaa#a#aaabbabbbaaaaaabbabaaaa#a#####aaaaaadcba###aaaaaaaaaaaaaaabbaa#abaaaabbbcbaa#aaaaaaaaaaaa#aaaaaaaaaa#aaaaaaaabbbbbbbcbababbbcbbbbaaaa###a###aaaaaaaccddcddbaaba#aaaa####a#.#.#aaaaabbaaa##djlljc#aaaaaaaa#afdfebaaaabccccddegfdbaabbbbbbabddbbbbbbbbbadceedcdcccbbabdebaaaa#aaa#############aaaaaa#ab####a##ba#####aaaaaaaaaaaaaaaaaaaaaaaaaabcdfebbbabbbcc" "ecabbaaaaababcdcccbbbcdbaaaabbaa#aaaa##aabcbbbaabaaabbaabaaa#aa###aaaaaabecbaa#a#a#aaaaaaaaaa#aaaaaaaaaaaabbcbaa###aaaaabaaaaaaa#a####aaa#aabaaaaaabbbbbbdcbbabbbcbbaaaaa####aaa#aa###aaabcccccbaabbba##a####aa#####aaaabaaaaa##ahlkfa#aaaaaaa##fbbecaaaabccbcdddceghecbbccccbbbccddbbabaa#ccedddddccbbaaacfbaa#a##a############a##aaaaaaaaa##a###ca#aa###aaaaaaaaabaaaacabbaaabbbbddea###aaaabc" "abbcbbbbaaaabbccbbbbaaaa#a#aaaabcaaaaaa#aabbbbaabaaccbbabaaaaaaaaaaaabbabdcbaaaaa###aaaaaaaa#aaaaaabbbaabbbabaa#aaaaaa#aaacbbaaa##aa##aaaaabcbaaaaabacbccccabaabaacbcbaaa####aaaaa####aaaabdccdba#abbaaa#######a######aaaaaba#####dljfa#aaaaaaa#ddaadcbccbbbbccccdccehihfddccccccbbdfaaaabbbceefedddcbbbbaaaecaaaaa##a###a####a##a##aaaaaa####a###ba#aa###aaaaaaaaabbbbacbbbbbaaacccdd#####aaaab" "babbbcccbbbaacdbccbbbaaaaa######aaaaaaaa##abbbbabaaabbaaaaaaaaaaaa##abbbdcccbaa#aa#####aa#aaaaaaaaaaabcbabbabaa##aaaaaab#accbaaaaa#aaaaaaabcddbaaaaabbbccccbaabbbbaabbbbaa###aaaaa#####a#abceeeaaa#aaaaba#######a#######aaaaaaa###.cgjgb#aaaaaaaafcaacdcdcbcbbcbbccdeefeeghfeccccbcddc#aabaaaeffeccccbbbbbaaacdcaaba##aa##a#aa#aaaa#aa###a####a####b#a##aaaaaaaaaaaaabbbbcababbbbcdddeb#a#####aa" "bacbbcddcbbbbacddccbabbaaaaaa#a##aaaaaa####aabbaaaaaaabaaaaabaaaaaaaaabbcccbbabaaaaa#a#aaaaaaaaaaaaaaaabbccbbba##aaa#aaaaaabbbaaaa#aaa##abbaabbcbaabbcccccbbbbbabbbabbbbaa#############aaabbcedbaaaaaa#aaa######a########a#aaaa##a##adhjc#aaaaaaacdb##bddcbbbbaabbccefgecceffgfcbceccedabbaaacffdccbbbbbbbbbaabccbbaaa#aa####a###aaaaa#a##bb##a###ab##a###aaaaaaaaaaabaaabbbcbcbbbcefeb#####aa#a" "aaccbcddcbbabcbcddcbbbcbaaaaaaaa#aaaabaa##a#aaaa##aaaaaaaaaaaaaa#aaaaaaaaabbccaaaaaaa#aaabbaaaaaaaaaa##aabccccbaa#aaaa#abaaaaaaaaaaaaaabbbbaabbaccbddedcbbbbbabbbcbcbbcaaaa############a#aacbcba##aaaaaa#aaa#a###########a###aaaaa####adid#aaaaa##eca##addcbbaaaabbcddefddefddgiedccccffbaaaaaefeccbbbbbbbbbaabacdbbba####aa#a##a##aaaaaaccbba###.aa#aa#ba#a#aa#aaaaabbabcbccbcbcccegc######ba#a" "abcbbccdedcbbbabdddcbabbbbbaa##aa#aaabaa######aaaaaaaaaaaaaaa#aa#######aa#aabcbbaaaaaaaaabcaaa###abaaa#aaabcbcb#aa##aa#abbaaaaaaaabbcaaaaaabbgecbbbbccbbbbbabcabbcbbbbaaaaa##############aaabaaaa#aaba#######a###########ba#aaa#aaa###aabffcaaaaaabeb####cdcbaaaaaaabbccdeffeeegihfddddffcaaaabefeccaabbbbbbbaaaabdba#aa####aaaaa###aaaacccbbba#######aaaa#aa#a##aabbbbbbbccccccccddgf#aa##a#aaa" "aabcdddddddbbbccabcdccbaaaaaa#####bbaaaa#######aaaaaaa###a#####a#########aaaacbbbaaaa#accdddba#a#aaaaaaaaabbbcbaaaaa#aaaabaaaaabba#bdaaaaabeecbbcbcbccbbbbabbbbbbbabbbbaa#aa####a########aaaaacaabaabaa#######aa########abbbbaa##aaaa###aaegfb#aa##dcaaaabddbaaa##a##aaabcdfgffgiggfffedefea#aabffccbaaabbaaabaaaaacbaaaaaaa####a##aaaaaabbabaaa##aa##aaaaa######aabcbaabbccccbbddedeeaaaaa#baaa" "aabbdeedeedddaccbbbcbcccbaaaaaabbaccaaa#a#aa###aa#aaaa#########aa#a#####a##babbbbbcbbcfdccccbbaabaaaaabaabbbccbbaaaaaaaaaabaaaaaaaaacfcaaabcbbaaababbcaabbbabbbbbaaacbabaaa####a##.########a#abd##baaaaaa##.###aa#######abbadb#a#########aaeiib####bca#aabadcba########aabccdgghgfeddddeedegdaaabdedbbaaabbabbaaaaa#cbaaaaaaaa#a##a#aaa#abbbbaaa#aa##aaaaaaa#####aaabaabbbbccbbbcdecef######acaa" "baabcccddedddbacccbccdcbbbbaa####aa##aaa###a###aaaa#a#####aaaa#a#aaa###aaaaabbbbbabcgjfdccbbbaaaaaaaaaaaabbacccba###aaaaaaab##aaaabbbdfdbaabdecbbbabaabbbbbbbbbbbbababbaaaaaa######.########a#acdb#aaaaaaa######aa######abbccb####aa######afiifa###bca#aaaabcbba#a######aaabcdeefcbcedccccceffaaaaacdbaaabbbaabbabaaabcbbaaaaaaaaa##a#a##abbaaaa#ba##aaa###a####aaaaaaaaaaccbbbcccdeff.######aaa" "a#aabbbcdeddcccbcccccdcbbabaaaa##a###aa#a#a#####aa##a###a##aaa####aa#a#a#aaabbaabbbbbffdccbbbabbaaaabbbbbabcbbbaaa##aaaaaaaaa###aabcbbcdfdaacebbbbbaaabbbbbbbbbaaaaabbabaaaa###aa############abcdcaaaabbaaa######aa#####abbbdc#############adghf###cdaa##aaaabbaa##.##.##aaabcdecedbbcdecbbbccebaabacdaaaaabbbbbbbaaaaabdcbaaabaaaaa##aa#aaabaaa#bcaaaaaa###aa#a#a#aaaaaaaaababccdceec##########" "###bbbbcdeddddcccccbccbccbbbaaa#####.#a##aa######a##aaaa###aaaaa##a###aaaaaabbbbbbbccddcdcbbbbbcdbbbadecccccbcb###a###aaaabaaaa###accbbccfhcacbbbabbabbbbbbbbaaabbbaabbbaa####aa#########.####aabcbaaaabbaaaa#####a#####aabacfb###############dhhc.ddb###a###bbca#.#....##aaabcdccecbbccedbbcccedbabbdcbaaaaaaaabaaabaaaacccaabaaaaaaaaaaa#abaaabbcaaaaaa###########aaaaaaababbbceeda.#####a###a" "#baaabbcdeddddddddbbcccbcbbbbaaaa################aaababba####aaaaaa###aaaaaaabbaabbdecbccccccbbbccccbcbbbcbbddeeca###aaaabccaaaaaa##abbbbcdedbbabbaaaaabbbbbbbbaaaaaaabbaa#######aaa##########aabbbaaabbaabaaa########aaaaaabdfb####aa#########cghhceba###a##aabaa#.....###aaabcdceebbbbbddcbccbcdcabcedbbaaaaaaaabaaaaaa#cddbbbaaaaaaaaaaaaaaaaccbaaaaaba#a#a######a##a#aaaaaaccdeed####aa####a" "aaabaabccceeddeedcabbbcbbcbbbbbbaaaaa#########a##aaaaabbcbaa#aa#aaaaa#aaaaaaaaaaabbcddcbbbbbbbbbbbbbabbbbbbaabbdgfba#aaaaabbaaa##aaaaaabbbcceedaaaaabbabbbabbbbbbaaaaaabba#######aba#########a##abbcaabcbaabbba########aabbaabddca#aaaaa#########adjhaaa#aa#####aaa#...####aaabbcccfdabbbbbddcccbbccacffccbaaaaaaaaababaaa##bccccbabaaaaaa#aaaaabdcaabbaaaaa#########a#a#aaa###bcddhga####aa####" "##aabbbbcdffeddeebdcbbbbbcbbcbcbaaaaaa##.##aa######aabbbbaaaa#aaaaaaa##aaabb#aaaaacddfbcbabbccbccbbbaabbaaba#abadfdbbaaaabcaaaaaaaaabbbababbceedaaaabbabbbbbbbbbbaaaaaaaaa##.#####aa#########aaa#aacdabbbaaaaaaaa#######bbbbccdcddbaabbaaa####aa###bhgea#######.##aaa#####aaaababbbcebababbabdeccbbbceffeecbaaaaaaaaabaaaaaaa#bcccbbbbaaaaaaababbbbbaaaabaaa#######a##a#aa#aaaaabddhg###########" "#a#aaabcdddffdddeeedbbbbbcbbbbcbbbaabaaa#a##a##aacaaaaaaaaaa#a##aaaaacdaaaabaaaa#accdeaaaaabbbbccbbbbaaaaabbbababcdddcccbbaaaa#aaaabbbaaaaaabdeeeaaaaaababbbbbbaaaaaaaaaaaa###a####ba####a####aaaaaabecaa######aaa#####a#ababccccbcbabaaaaaaa###a####dijdb########a#a###aa##a#abbbbddbaaaaabbabdddcfeffffeccbbaaaaa#aaaaaaaaaa#abccbcabaaaaaaaabbaaababaaaaa#aaaa###aaa#aaaaaaaaabchga#####aaa##" "#a#a###abccdddefdeeecbbbbbbaabbbbbbbbba#########abaa#aaaaaaa##a#aaaaaccbaaabbabbcbbccfbcaaaababbbbbaaaaaaaaaaaabbbabbabaabaaa#aaaaaabbabaaa#abcdfea#aaaabbbbaaaaaaaaaaaaaaaa#######bba##########aaaabcedbb#######aa#####a##abdcbbccbaaaaaa#aaaaa#aa###bgjjga#######aba#aadba##aabbbccbaaaaabbaaabedffeffffdcbbaaaaaaaaaaaaaaaa#aaaccbbbaaaaaaaaaaaababbbaaaa#aaa#####aaaaaaaaaaabbbghc#####aaaaa" "a##a#aa#aabccbdfgeefeccababbbaabaabbbaa#a##.######aaaaaaabba##aa##abbbcbcbbccacbbdedgheccbbabbaaaaaaaaabbaaaaaaaaaaaaaaaaaacbbba#ababbbbaaaaaaabdeeca#aabcbaaaaaaaa#aaabaaaaa####.##ba###########aaabbceeba########a#########cbbbabbbaaa#aa#aaaaaaaaa###djkjb#b#..#abbcaaabcba##aaabbcaaa#aaaaabaacfffffedffccbaaaaaaaaaaaaaaaaaaaabcbbaaaaaa##aaaaabaaabaa#aaaaaaa#a#a#a#aaaabbbbccgc######aaa#" "##aaaaaa##aaccbaeihfgggcbabbbaaaaacbbceceeca########aaaaaabaaaaaaaabbbdcccdebbcbbabacedecbbbabaa#aaaaaabbbbaaaaaaaaaa#aaaaa#abbbbacbbbbbbaaaaaaaccddbbbbbbbaaaaaaaaa##aaa#a##a#####aa#############aaabbceeea########a########aaaaaaaabbaa###a###aaa######agjkhgfb.#aabddaaaaaaa###aabdb##b###aaaaa#cffffeeeeeccbaaaaa#aaaaaaaaaaaaaabcbaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaabbbbbdfeba####aaa#" "#a#aaaaa###aacca#cjjhhjebcbaa##a##acegebdcbdb#.#cbcaaaaaaaaaaaaaaaaaabbcdgiecbbaaabbbcbcdcbbbbbaaaa#aabaabcbaaaaa#aa#aa#aaa###aaaaaa####a###aaaabcddbcbbbaaaaaaa#aaaa#aaaaa##a#####baa#.#######a##aabbcdddffa##.####aa##.####aaaaaaaaaabaaa###########a####chhiihc..ceffbabaaabaaaaabccaacc###aaccbbegfffededdccbaa#a#aaaaaaaaaaaaaaaabcbbaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaabcccefeaaa###aa#a" "aaa#abaaaa##aaba##eiiikhccbddefeeffgecccdccdeffefddc#aaaba#aaabaabbaaaabcdhfbbbbaaacdecbbaabbbcbbbbaaaabbbbbbaaaaaa#######a###aaa#aaaaa######aaaaaccbcbaaaaaaa####aa##aaaaa#####a##############a##aaabcccccdfb##.#####a######aaa#aaaaaaaaaaa##########aaa##.#aejjifb#cffacbbbaaa#acbbcc##ddda##cddeefgfffeedddcabbaa#aaaaaaaaaaaaaaaaaaacbbaaaaaaabbabbbcaabaaaabbabbbbabbbbbbbbbbbdfc####a##aa#" "#aaa#a#a##a####b###dgkkjgccfiifdfdeeccddddcdcccccbca#aa##aa#aaaaabbbaababeggdbaaaaadfcbbbbbbcccbabcbaaaaabcabbbcbaaaaaa##########a#a########aa##a#accbbaaa#########aa###aaaa###aaa####.#########b##aabcbbcddfb###############aaaa###abbaaba#aaa#########aa#####djjjifbcebccdcba#bbacbcb##addccdcdeeefgfffeecbccbbbaaaaaaaa#aaaaaaaaaaaaaabbaaaaaaabaabbbbbaabababbbbbbbbbccccbbbbcced####a###aa#" "a##aaaaaaaaa#a#ba..#agkgfecfikgddcccdcccbcccbcbcbbdba##bccaaa#bbccccbaabbefffcaaaabdfbbbbbbbbccaaabaaaaaaabcbbbabbbbaaaa#######aaa############aa###abbaaa####a############a####a#######.#####a##aaa####aaaacfa#######..######aaaa###a#cdcbbbabcbaa#aab#########.chiiihfcddeghhgdccdabdaa#addcddceefeeffeeeedbbcccbbaaaaa#aaaaaaaaaaaaaaaaabbbbaaaaaaabaabbaaaababbbbbbbcccdccdcbbceea####aa###aa" "a####aaaabaaabbab#.#aaeecdhfijfcccddcccbbbbccbbbccaaa###.a#abccccbcbcbbbbbff#a###abcebabbbbccbcaabbaaaaabccbbbbbbbbbbbaaa#aa####aa##############aaaa#ababaa##############a#a######a####################aabbcacaaab#####.#.##abbaa###aaabcacbcaaaaaaa#aa#########.bgihiifcdgijjjiidaaabe#a#bdcbccccddddddecdecbbbccbbaaaaa##aabbaaaaaaaaaaabbbbbabbbaaaabbbbbaaabbbbbbbccdddedddefeffa####a#####a" "#######aaaaaaaaaa#.#abcdaahkkjgbbcccbbbbbcbbcbbbbaaaa#a######abddedccccbbacffcbb##acccacdcabbdccdbabaaaa#abbbbbaabbbbcba###a############.##.###########ababaa##################a##a###.################aaabcbcdbbbaa##.#.#.#aabaa###abcdcaabaa####aa#aabbb###a###.#bgjhacegijjjjjjhedfgea##cbbbccbbbcccccdcccbbbccaabaaaaaaaaaaaaaaaaaaaaaabcbabaaabaaabbbbbaababbbbbbccddddedffceedb######aa###" "aaa#a####a##aaa##a.##acda#cejjfdbbbbbabcbaabbcbbaa#aaa##a#a###baecbdfedddefhhgefea#cedbafecbbcbecbbccbbbbabbbbbbbccabbcdcaa####################.#######aaaaca##########################.########a######aaaaccccbbca#a########aaaa####bedcaabaa##aaaabaaabc########..#figefhikjihhhhiijiihd##bbcdbcccbcccddebcbbbbcdbaaaaaaaaaaaaaaaa#aaaaaabbcbbbbbbbabbbbbbbabbbbbccddedeedffa###a#####aaaaaaa#" "###aa############a#.##bccbbbbehhaabbbaaabbabbcbaba#aaa#######becdda#fgecddeehghegdabdecaabedbcaacbbddbbbbbbcbbbbbbdbaaccccba#########a################aaaaabcaba###############################a#####.###aaaabccbcb##a######aab##a###accbca#b#####aaaaaaaaa###.####...diihiiihfgeffeffhijid##ddcdccccccddddccbbaabddcaaaaaaabaaaaaaaaaaaaaaabbcbbabbababbbbbbbabbcbccdddedefc.##########aa#aaaa#" "#aaaaa#aaa##a######.#abbccaaaabgfb#ababa#aaaacbaaaaabbbab####edeefeccgedcddehhfacebadecaaaabcccbbbbcbabbbbbcbbcbccccccabccdb#######abb###a##############aaaacbccba##########a######.########a###a#########aabcceccb###a#####aaaa##aaaaacbb##ac######aaaaa##aaa#######..diihffffffdeddddefiigaaeddddbbcdddccdccbaaabcedbbbaababaaaaaaaaaaaaaaaabdcbaabbababbbbbbbbbbbbcceeegc.#############aaaaaa" "aabcbbaaaaaaaa########bbcdbaaaaaffa#aaaaa#aaabbaaaabcdeddabaefcdddefcgfddddeghcccffddbaaabbbbbccbccdbcbabbbbbbcbbbbbdcabbbddb########bca#a#######a##a###aaaaaaabdbaa#aaa####aca##...###aa####a##a########aaabbbdecc##aaa############aa#abba##a#########aa#aaaaa########.bgiedcccdccccccccdhigdeeeeedcdddccbcebaaaaaaceebbbbbbbababaaaaaaaaaaaabcccccfedcbbbbbbbbbbbbabcfffe############a###aaaaa" "a#aaedbbbbaaa#a#######abddca#aaaadcaa##aa####aabababbbccccfggcbcccccfgeccccdddffedfecddcbbbbccbbccdcddbbbbbbcbbbaabbcc#abaacba########aa##..#######aa####aaaaa###bbaaa#aaaaa#cc###a.####aa##aaa#########aaabbbbadcdaaabba##########a#aa#bbaa##a#######a#aa#aaaaaa#######.ageccbbbbbbbbbbbcbehigffeedddddccbcccbbaaa#accdcbbbbbbaaaaaaaaaaaaaabbcbccdbaadfdcbbbbbbbcbcefccba#################aaa#" "#aaacbaabbcbbbaa#######abcca##aaabbcba########abbaaabaabccdcbabbbccbcedccccccccccccedbbcdbbbccbcbbcbcbbbbbbbbbbabbbbcccbbaaaaaa##a####a#aa####.#####aa##a#aaaaa##abbcaaaabbbabcaaa#.#.###aa#a##a########aaabccabbddbaabaa####.##.aaaaaa##bba##############aaaa##a########.#bddbbbbbbbbbaaaaabfhhgfeedddccbccbdabaaabbbccddcbbbbbbaaaaaaaaaaabacbbcceb#a#babcbbbbbbcbce##.####################aa#" "aaaaaa#aaaababba#######abcccb#a#aaacddb######aaaaa#aaaaabbbbbbbcbbbbcdcbcbccbccccddbababcccccccccbbbbaaabbbbccbdcbbbbabcbbaa######aa#aaa############aa#####aaaaa#acbabaa#baabbcb#a##.#####baaa#########aaaabcdcccccbaaaa##########abaaa###aa##############a####aaa########.##dcbbbbbbbaaaaaaaabghgffedccccccbbcabbaaabbcbdedbbbbbbaaaaaaaaaabaaabccdecbcabbbcbbbbbcbeea###aa####################" "aaaaaaaaaaaaaa##########acceeba###bbbcda#######a####aaaaabbbabbabbbbbcccccccccbcbbcdcbaabbcbcccccbbbbbcabbbbddegebbbbbbbcaaaaa#########a######aba#####aa#####abaaaabcbb#aa##abaaba#####a##aaaaa######aaaaaaacccccbccaa##a#######aa#aabaa##aaa####aa########a#aaaaaa###########addcbbbaaaaaaaaaa#fieeeddcccbbbbbaaabaabbaaabdedcccbaaaabaaaaabbaabbbcdebaaccbbdddcbbcdc#aaaa###########.########b" "aaaaa#aaa#aa#############abcdfdaaaabcdf###aaaa##a#####aaaaabbccabbaaaabbbcccccbcbabbccbbbbbbbbbbbccbbcccbbbcdcdedecabbbbaaaaaaa########abb##aa#aaabaa#aba###a#aa#aabcccbabb###aa#aaa######aa##aa######aaaaaaaccccdaba###########aaa#aaba#aaaa#aa##a########aca##aaa######a######cffaaaaaaaaaaaaa#ehfeeedcbbbbbbcbaabbbbbbbaadeeefedcbaabbabbccbabbdcbcaabdcccccceedffb##aa####################a#" "aaaaa###aaaaaa#####.####aabccfgbaabbcfeda##aaabaaaaaa#aaaaaaaccbccbaaabcccbbccbbbbbbcbbbbbbbcbbbbbcabcccbababccdeccbabbbbaaaaa#aa########aaaaaaaabedaa##a#aaabaaaaabaccbaaaca###aaaaaa#####a###aa###a##aaa#aaaccbbabaa############aaaaaaaaaaaaa#########a##acdaabaaaa############acecaaaaaaaaaaaaafhffeddcbbabbcbbabbbbbbbbaabbdeddfeddbabbbdcabbabbababbbcbcbccddffcdaaaa##a###################" "aa#a#####aa#aaaa#########abcdcfeaaacbdccfcbbbdddbbbbbaaaaa#aaaabcbaabbbcccbbbcbbcccccccccbbcbcccbbbbbcccbbabbacddedcaabbabaaaaa##aa########cb##aa#cfdaa##aaababbbbaaaabbbbaabaaa#abaaa#####a#bbaaaa##a##aaaaaabbccdaaaaa#####bb#####aa##aaaaaaaa############aabbbbaaaa##aa##########deaaa###aaaaabcgiggddccccccccabbbbbabbaba#aabcaacccccbbcdbaacbbabbbbabcbcdddd####abaa#a##a#a#aa############a" "aaa#####aa#a#aaaaaaa######abccdfa#bbcddbcccdcdaaccdecbbbbbbbaabccbaaabbcccbbbccbccccddccccccddccbbbbbbcccbbbbbcccdddbabbbabaaaa########.####bba##a#aca###aaaaaaaaaaaaaabbbaabaabaaabba#######ababba.##aaaaaaaaabcdcb#aaaa#####a##########aaaaaa#a####aaaa##.##abbba#aab#aba#aa#a#####cgeaa####aa#aabfiigdccccbccccbbbbaabbbbaaaaaabccbbccccdabcbccaaaaabbbccdebdbaaaaaaaaa#a######aaaaa#########" "#aa#a###aaa####aa##a#####aabbbbeb#abbceeba#a####aaaba##cdbbbcccdccbbbbbbccbbabcbbbcbcddccccccddddddccdcabbbcbccbbbddcbbbbbbbaaaa#########.####aaa####a#a#aaaaaaaaaaaaaabbbbaaabaaaaaaba####a#.a##ab##.a##a##aaaabbddb##aa#####aa######.##aaaaaa#aa####a#aaa###abbb###acaacaaaa##a#####bff###a##aaa#aacghhfccbcbcbbcbbbbbbbcaaaabababbdccccddbbccccaaaaaabbccee##aaaabbacaaaa######aaa#aaaaaaa###" "#aaa##########aaaaa########bbbbbea#babcea#a######aaa####bccddcddedcccccccccbcbccbbbcbcddddcccbbbcccdefedcbaacbbcbbbbbbbbababaaaa############.###aa#a##aaa#aaaaaacbba##abbcbaaa#aaa#aa#########a#######a##aa#a#abbcbcc#a############aa####aaaaaaaaaa#######aa###aabaa##bbaaaa#a##aa######dea#####aaaaaa#behhdccbccacbbbbbbbcbbbaabbabbbcdcccdddbbbba#aaaaabbddb#######bcaaaaaa######aaaabbbaaaaaa" "aa#aa##########aaa########aabbbbbedbaabddcb#aaaa#aaaa####cccaacdeeggecccccccbbabbbbbbbbccddcccbbbbcbcddeedcbaaabbabbbbcbbbabaaaa###########.#####aba#######aaaaaabbba#aabbbbaa###aa##a#####.#a#.#.####aa##aa#aaabccbca#aa#..########a######aaa##aaa#########aaa#aaaaaabcaaaa##a##a###a#a#bdb#aaaaaaaaaaabcfhfccccabbcbbbbcbcbbbaabaabbabcddcdcccbba##a#a#abddb########aaaaa#aaa####aaaaaaaabbaaa" "aaa#aa##########aa#a#a#######abbabgebaabacca#ba#aaabaa#########a##bdeddeedddcbbbbbbbcbabacdddcccccbbbcdcdcdcabbbbbbababbbccbabaa###############aaabb####aa##aaaaabbbaaaa#abbbaa###aaaa###a###a##....###a##aa##aaabbbca##aa#.#######aaa##aa######aaa#########abaabaaaaaacbaaaaaa##a###a##a#afb##a##aabbbaaaaeggecebcbbbabbbcbbabaabbbbbbabbdddccccccabaaaaaaccc#####a#aaaa#a#####aaaaaaabbbaaabaa" "aaaaa############aa#a########.#abbcffcabbceccaaaaaaaaa###a###aa#######aaeebccccccbbbbcbbccbdddccccccbbbccbbbbbbbcbbabbbbbccbbbbaaa########.#aaa#a##aba#aa##aaabbbabbbaaa###abaaa#########aa##a############aa###aabcc#aa#aaa#######.##aaba#aaaaaa##aaaaa######baaaaaaa#aaaaaaaaaa###aaaaaa###ebaaaaaaaaaaaaabbfhgedbbbbbcbbbbbbabbbbbbbabbbbddecbcbbbbbbcbbbceaa#####aabca#a#a#a##a#aaaaaabbbbbaa" "aaaaaaa####aaaa#aa###########..#aabdddbbcccccaaaaaaaaaa##a##aaa###aa#####eddedddcddccbccbccccbbcbbcedbbcccccbbbbbbbbababbbcbbcbaaaaa############a#a#aa#aaaaabbaabaabaaa#aaa#abaaa#######aaaa#a###########.#aab##aacc#aa####a######..##aa#aaabbaaa##aaaaaaabbaabaccbaa###aaaaaaaaaa##aaaaa##a#ccbaaaaaa###aaaadgggfeababbcbcbcbbaabbbbaaabbbccddbcbbbbbcdccccca#a#a###aaaaaaaaaaaa#aaaaaaababccba" "aaabaaa#a#######a#aaa####aa###.###bcdcbcbabddbaacbbababaa#a##aaaa#aa#aacdccbddddddbbbbbaa#aaa######bfggfdcccbabbbbabaaabcbccabbaaaa#########a#aaaaa#######aabaaabbabbaa####aaaabaaa##aa##aaa#b####.#########abb#aaee##a###.##.##.###..####abccccbaaaaaaaaabcdaabbccba##a#aa#aaaaa#a#aa#aaaaaaaabebaaaaa#a##aabbfghhgedaaabbbccababcccbbbaabccbcccbbcbbcdcdcaaa########aaaaaaaaaaa#aaaaaaababbccb" "abaaaaaaaaaa######aaa########aa####bbccbbaabceaa#cbbbbbba#a##aaaa#aa###debacb#aacabaa##aa###########.#afhgeecbccbbbabaacbcccbbbbbbaa#a#########aa#aaaa####aaaaaabbbbbbbaa###aaabbba###a##aaa###.#######ba##aaadbaabeaa##aa#..###.##########abaaabdbaaababababbaabddbaa##aaaaaaaaaaa#aaaaaaaaaaa#aecaaaaa#aa#aaabdghhhfecccbcbbabbacccccbbbbbcbbbbbcbabbdcbcba########aaabaaaa##a###aaaaaaaaaabbb" "baaabbaaaaaaaaaaaa###########aaa####acccbaaaabcbcabbbbbbba#####aaaba#acbcaa#aaaa#abaa############.#####.dhihgeefccbbbbaabccbbbbbbaaaa##########a#aa#aa####aaa#aabaabcbbaa####a#aaaa###a#aaa################abbeebbbdd##a#######..####.######aaaaabcbbbbbbbbbbb#abcccbaaa#aaa#aaaaaa###aaabaaaaaaa#bcbaaaaaaaaaaaabehhhfedaaabaaabbccccbabbbbccbbabccbbbdcbbaaa#######a#aabaaaaa#aabaaaaaaaaaaabb" "bbaaaaaaaaaaaaaaaaaaa#########a#a####bbcbaaaaabeecbbaaabbaba###a#aaa##cedb#aaabaaaaa##a#########.##.###a#bfgedeffdccccbaaacdccccbbaa###########aaa######aaba###aabaabbbaaaa#####aa#a##abbaa####.##.####aaa#acbddddfega#a#######.######.##a#aaaa#aaaaaaaabccddebaba#bcba##aaaaaaaaab#aaaaabbbcaabaaaaccaaaaaaaabaabbehhfgebaaaaaaacdcccaabbcbbcbbbbbcdcbbcaaa#a######aa#abbaaaaaa#abbaaaaa#aaaaab" "bbbaaaaabbbaaabaa#aaaa###.#######a####abb#aa#a#cfecaabbaaaba#######aaa#bddcdaaabaaaa#a#aa######.########ba.a####bfddcccbbacdccccccaa############aaa######adb###aaaaaaabaaaaaa###aaaa##abaaa#####..#####aaaaabbcdeedfgd#aa########.#######a##aa#aaaa#a###a#abeedecc##aaba#aaaaaaaa#bbaaaaabbbbaaaaaaaaaccbaabaaababbadgggfdb#aaaaaabcbbbbbbccccdcaabbcdcccbaaa#######aaaaaaaa##aa###aaaaaaaaaaaba" "bbbbaa#aaaabaaaaaaaaaba#a######.#######abbbca##acdedcaabca#a#.###a######bddcfcaabaaa##a##a#####...##aa####a####a#abbccddcbbddedccccbaa####a######aaa#####acb###aaaaaaaaaaaaaa###########aaa####.####a##aaaaacdeceeeedc##aa########..#########aaaaa##a###aaaaaabcdedcb##aa#aaaaaaaaacbaaaaabbbbaaaaaaaaadfdaabaaaabbbbcdggfebaaaaaaacccbbbbbbccdcccbbbdcecba#####a####abbaaa#######a#aaabbaabaabb" "bbaacbabaabaaaabbaaabbaabb#.####.#######abbcba#aabecdbaccaa#a#.##aa##a###acacecbaaaaaa##########..######..abaa#aa####aceeddceggeddccbaa##########a#aaaa##aaa##a##aaaaaaaaaaaaa#########aaa####a#aaa####aaaabbdffffgebca#ab#######.#..#aa######aa###aa####aaaa#baabbdcc##b##aaaaaaaaabaaaaaabbbbaaaaaaaabcegcabaababbbbabgfgfdaaaaaabbabbbabbbcdddbcbccccdbaaa#a##a###aaaaaaa#########abbbbccbaab" "baaabbaaababaabbaaaaaaaaaaa##############abbaa##aadd##abbaaaa#.##aaa##a####aabcbaaa#aaa###a######..####.#..cdcbbbaa###abdcdedfghffddcbba###########aaaaaaaaaaaaaaaaaaaaaaa#aaaa########a#aaa#####aaa#a#aabbccddghhhfcca#aa##########...##########aa#aa###aaa##aaaa#a#bb####aaaaba#a#aaaaaaaabbcbbaaabaaabbefdabaabbbbbbbbfgggfdcaaaaabbbbbbbccdbdbcbcccbcbba##aaaaaa###aa#aaaa########bbabbbbaaa" "aa#a#aaaaaaaaaaaaaaaaaabbabaa#######.#.####aaaaaaabdeb#aababaa####aaa#abba#####aaaaa###a##bdba##a######....acdbabbaaaa#####cddaeggffedcba##########aaaa###aaa#abaaaababaaaaaaaaa##a###abaaaa###.#bbaaaaabdcddeefhhifdda#bb#aa##aa######..########ab##a###a##a#aaaa#abaabaaa#aaaaaaaaaaaa#aaaababbbbaaaaaaabcffbbbabaabbbaacefggdba#aabbbbcbacddccecbbbcccbba##aaaaaaaaaaa#a##a#a#######aaaabaa#a" "ba###aaaaa#cbaaaaa#abababa#a################aabbbbbbbea#aaabbaa#####a##adc##aaaaaaba##a####a########.#####...aca###########.####cffdcdecaaa#######aaabaa##aaaaaaa#aaabbbaaaaaabaaaba##babba######accbbbbbfccdeegdgfggeb#dc#####aaa#####...#######aaaa#aa##a#aaabaaa#bbaaaaa##aaaaaaaaaaaaaaabaabbbbbaaaaababbegdbbaaababbaabffffecb#aabbbbcbbcdddecbaabcbaaba#aaaaaaaaaaaaa###a########a#abbaabc" "a#######a###aa#abaaaabbccba###.##############abcbcbbcbea#aaaaaaa#######.##ba#a#aa#a#a#a##a####.###########..###ba##############a#aeedbadfcdddcbb##aaaaaaa#aa#aaaa#aaccbbbaabbbbbabcbbcdccb######abcdbddeeefddddb#afdcfebdca#####aaa######.#####aaca####abaa#aa#abcb#accaaaa##aa#aabbaaaaaaaaaaaabbbaaaaaaabbbbbgdbaaabbbbaaaccffgfdcaabbccccccddddfcbaaaaaaaaa#aaabbaaaaaa#a#aab####aa##aaa#bcc#" "aa###########aa#aaaaabbabbaaaa##..###########abdcccccbcdcaaaaaa#a##########aabb#abaa##########...#.########.######################.bfdaaccefddddbaaaaaaaaaaaaaa#aaababcccbbbbbccbbcddcabca####aaacdcabeggfdda.##.#cc#aefdbaaa###aaa###.##.####aaaaa#a###abd##a###ababbdc#aa#aaaaaaaabaaaaaaaaaaabbcbbaaaaaaabbbbgfbaaabbbbaabbbcefffddbabbcdccccedcabaaaaaaaaaaaaaaaaaaaaaaaaaaa#####aaa#aaaaaaa" "aaaa##########a######.#a#abbaa##########a####abdedcccccccba##########a######aaaa#abaaaaa#######..################aa#aa###############ddabedcgededbbbaabbabaaaaaaaaaaabbccccccbccdddba###abacbbcccba####aaaaaaaa##.###acfcaaa##aa#a############aa#####a#a##aea#aaa#aabbcda##aaa#aa#aaaaaaabaaaaaaababcbaaaaaaaabbbgfbabbbabaabcdcbdefffdbbcccccccdda#aaaaaaa##abaabbaaaaaaaabbbaaaa####a##aaaabaa" "aaaaabaa#######a###a##.###abbaa###############acdeccbbccdga##########a######.#aabaaaaaaaaa#a############.###aa###aaaaa###############.cdbbdefhhhfdccccbbbaaabaaaabbbbbccccdddcdccdb#####bbcbcddba####aa####a#a#####.##aedaaaa###aaa#######..#########a###a#bbbbbaaabbbbaba#aaaaaaa#aa#aaaabbaaababbabccbaaaabaabbbggdabbbbcbbbddcbcbdffdcaccccacccd#aaaaaaaaaa#abbbaaaaaaaabbabbabaa#aa####aabaa" "aaaa#aaa##########a###.##aaaaaaa####.##aa#####abccdcaabccffa##########a###aa####aabaaabaa#aaa####a######..###a#####aaa############aa###bdddeeddfgfeeeddcabaaabbbbbbbbbbcdddddeeeecaa####abbaaaa#######a#a########.###aaadaaaa#####aa########.#..##.##a######aaabbba#bbca##a###aaaaaaaaaaaabbaaaabbbaabddcaaaaaaaaabfgdaaabbbabdacdbcbdfffdbbdccbc#cbaa##aaaaaaa#aaaaaababaaaa#abbaaaaa#aaaaaaa#a" "###a#aaaaaaa######accbaaab#####aaaa####a#######accccabacccfe##.############aa####aa###aaa#aa####.#########.##########a############abca##bfcfabbbcaafffffdbbbbbbbbbabbcccdeeedefcaaaaaa##aaaaaaaa################a#.###abbcaa#aa#aaaaa#######....########aa####a#abba#bbbbaaaaaaaaaaaaaaaaaaabcabbbbbbabeedaaaaaaaaacfgecaabbabbacdbabcffffccccdda##aaaaaaaaababaaaaaaabaaaaaaaaaabaabaa##abb####" "a########aaa#######cddebba########aaaaaa#######abccccbabcdefea#.########aaaaabb##aaa#####aaa##.....#.##.##############a#####.#####aabcbaabfc######.afggggcbbbcbcccbbbccceeeeffhgccbaaa#aaabbaa#a######aaa########a#.##aacdba##ab#aabb##.#.####...########aa#####aaaaaaaabbaaaaaaaaaaaaaaaaaaccbabbbbbbabefdaaaaaaaaabeffabaaababdedabbcfffecccddaaaaaaaaababaaaa#aaaabbbaaaaaaaabbaaa#aa##ba###b" "#####aa#####aaaabbaaaacdb.#a#########aaa########abcbbbbbcdeeeefc.######aaaabaacbaaaaa##########..#..#....##############a###########abbbba#bd#a######aabbcfedccdddccccdddeeeeefgiedeebaaaaaabaaaa#aaaaa#aaaa###########aabcca##aabaaabba#....#....##.###.#aaa#######a#abaabbaaaaaaaaaaaaaaaaaaddbbbabaabbbddaaaaaaaa##adfecbbbbacddedbbccdffdccddaaa#aaa#bbaabca##a#aaabbaaaaaaaaaaaabb#aaaa###a#" "####aaba######aa#abbaaaba###aa#############.####aabcabcbbdegfebc.########abbbaaaaaaaaaa#########.....#.#.######.#######aa#####.#.##aaabbbbbc##a#######..##ehfeeeedddcedeffeeeeehf#abcecccbabbbbbaabaaaaaaaa########a###aacdba#aaaabaaaaa#..##..##.#..####aaa##a####aa#aaaabaaaaaaaaaaa#aaaaaabeeccbababbbbbaaaaaaaaaaaabcffbbbbcdccdcbbbcdfgfedcabaaaa##bbababa#####abbaaaaaaaaaaaaaaaa#aaaaaa##" "#a###aabaaaa###ba###ab##ba###a#############..###aaabcaabbdedefgb####aaa###aaaaaaaaabaaaa###########...#.############################aabbbadcaaa#####.######bfhhgggffffffffeeeefhhcaa##acfffeedddbaabaaaabaa########a####abebaaaa#a#a#aa############.###..#aa##a###aba##aaaaba#aaaaaaaaaaaaaaaaccdcdcbbbbabbbaaaaaaaaaaaaacfeaabbbbccdabccbdfffed#aaaaabaaaaaa#aa###aaaaabaaaaaaaaaaaaaaaaaaaaa##" "###aaa#aaaa#a##.a##a#aba#aa###########.#.#....####abcbbbbccdffegb...##aa###abaaaaaaaa#a#aa#######aaa###.####.#####################a##abbcfda#aaa###########.#acfhihhhijiiiihgfhhgcaaaa#..acccddccecccbaaabcb#######aa###abcdbaaaaa#aaa#aa##########.##########aa##aaa#aaaa########aaaaaabaaabbaaababaacbbabbbaaaaaabaaaaa#cefdabbbabbcbbbccdfggeb#aaaaaa###aaa#a###aabbaaaaaaaaa#aaaaaaaaaaaaaa#" "#aaaaaaaaaa##aaaaaaaa#aaaaaa##.###aa###.###...####aabdbbabbcfeced.#########aaaba#aaaaaa##ca#######aaaa######.########.########a#####aaabdhgfeaaaa#############.#aaba#addfghiiiiheb###aaaa###.####bdbcdcdcbbca##a##a##a##aabbdbaa####aaaaaaa#############a#.##aaaaaaaaa##aaa##a#a#acbaabbabbbaaaaaaaabbbbbaabbbaaaabaaaaa#a#bfgebaaababbbbbbbcggfeaaaaaaaaaaaaaaaa####aabaaaba###aaaabaaaaaaaaaaa" "a##ba#abaaaaaaaa####aa###bbaa##.#######b#####.#.###aacbbaabcdeccc##.########aabbba#a##aaa#bba######aaaaa#################.######aa##aabbfhhihdabaa##############aa######.##a#bgfb###aaaaaa########cbacccdfeecaa###aa##a#aaabcdbab##ababaaaaa##########aaa#####aaaaaaaa#a#aaba##aabfdaa#aaaaabbbabaaababdbbbbbbbbbbbbbaaaaaaa#dffcbaabbbbbbbbbcefgdba#abaaaaaaaaa#aa##abbbaaacba##a###aaaaaa##aaa" "aaaaaaaaaaaaaaaaaa#####a##aaaa########ab##.####..###aadccbbacdcaa###.######aabaaabb#aaaa###############aa#####a#####.##############aabbbehhhfcaaaa#####.########aaaa##aaa##a#.#caa####aa##########cdbbbbbcedefdcbbaa##aaaababbdbaaaaaaaaa#aba#########aa######aaaaaa#a#aa##aaa##addbbaaaaa#aaaaabaaaaaaccccdcbbabbbcbaabaaaaa#cfgdbabbbbabbbbbcfgedda#aaaaaaaaaab#a##aabbbaaaba#aa###a#aaaaaa#aa" "aaaaaabaaaaaaaa#accb#########babaa###aaa##.##a##.####abcbccabdeaaab#..######aaaaaaa#####################aaa####a#####.############aaaabdgihgcbaaa################aaaaaaaaa#aa###a######a##########dbaaaaaaaacbcefgfddcccddegdcbdbaabaaaaaaaaaaa######aaa####aaaaaaaaa#############aaaaaaaaaaaacaaaaaaaaabbbbdeccdccbbbbaabaaaaabefecbbbabbbbcbcegededcaabaaaabaaaaaa##aabbbaaaa#aa#aaa#bbaaaaa#a" "a##a#aaaaaa###aa#bbcbaa##aaa#aaaca##abb########a#####aacbbccbdeaaaba#########aaa##a#a####.################ba#########.##..######.bbabaaehhhgbaaaa#################aab#aabaa#aa###a##########a.###.ab#aa#abababbbcbcdcaacecccdefdc##abaaaaa##aa########aaba#aaa#a#aaaaba#a#aa#a##.##abaaaaaaaaabbabbaaaaaaaaaaccbbbcdbbbbaaabbbabbdgfdbbbabcbcccdddeeedcaaaaaaaabaaaaa##aabbaaaaa##aa####aaaaaaa#" "####aaaaaaa######abbcca##aaaaa##abbabba#a#####aaa######aabccedfaaaab#########aaa###.#######################b########.#ba#...##.#acbccccfgggebaaaa##a###############aababaaaa#a##a#a####a##a########c#aaaaaaaabbaaaaabccdebabbbdgeaaabbbaaaaa##a#######aaab##a##aaaaaabaaa###aaaa####ba#a##aaaaaabbaaaaabbaaaaacbbbcbbbcbbaaabbbbcbcfgecbcbbbccddccceddccaaaaaa#bbaaaaaaaaaaaa#aaa##a#aa#a#aa####" "##a###aaaaa#######aaaaaaaaaaaaa#aabbcaaaaa#a###aa########aabeeea###aaa#######aabb#####a######.#######aa##.######aaaabedccbbb##bbbbaabbbbccdeaa##a##a########aaa#####aabbbba#a#aaa#a####a###########caba###ababbbaabbabcdcddcbabehcaaaaaaaaaa############ab##aaaaaaaaaaaaaa#baaaaa###bb#a##aaaabbbbbaaaaabbbaabbbbcccbabbbaaaabbccccbfffcccbccccbccccddeedaab#aaaabaaabaaabaaa###aaa###bb##a#####" "aaaa##aaaaa#aa#######a#abbaaaab######aaaaa#aaaa#aa#######aabdefb#aaa#bc#######abcb#####a#################aa#a..###aabcdfffggfdcbbbbbaaaaaabdeaaa###########aaaa#####aabbbbbaaa#aaa#####aa#a##.#####aaaaaa##abaabcbbbaaabaabbbbcdefaaaabaaaaaa##a######aaa######aaaaa#aaaaaa##aaaa###aa#aaabbbabbaabbaaaaaaaabbbbbacccbaaaaaabbccdccdefegffdccecbccccdeeddcbaaaaaaabbbcbaaabaaaaaa#######aa######" "#aaaa##aaaa#############abaaaaaba##aaaaaaaabaaaaaba#####a##abdgca#aaadeb########bba#####aa#aaaaaa###aaa#ab#aa#.###.#acfhfddgccbaa#aaaaaa#abcfaaaa#######aaabbaaa#####aaaaaaaaa#aaaaa#aaaa##########aaaa#aa##aaa#acccabaaba#a###acdbaaaaaaaaaaa###a##.##aaaa###a###aaaaaaaaa###aaaa#abb#aaaabbbbbbbabaaaaaaaaaacbbbccbbbbaabaaacccccdfdbdfgeefcddabccbcedddccbbaaaaaabbbababbaa#aaaa#a##ab##a####" "##aaaa#############aa#####abaaabda##abaaaababbaaaaba####aa#abbdeaaaaaadf###############a#aaabbbbba#aa#aaaa#baba.#accbffffgddcbbaa#####aa##acfeabaaaaa###aabcdcbba######aaaaaaaaaaaaaaa#aaa##########dbaa########bbdcaab#abaaa##abceaaaa#a#aaaaaa#a###.######a#####aabaabb#aa#####a#bcbaaaaa#aaaabbbbbaaaaaaaaaaccccbccabacaaaabceeeeggdcdfffccccca#bbcbddeccccca#abbbbbbbaaabaaa#a#aaaaab#######" "##aaaa####.##########baaa##aaaaabda#aaaabbaaccbaaaa#####aaaaabbcbbaaabdgfe###aaa#######a##aaabbabbb#a#a#aabdceeedcabcaeddcfhecdb#########aacdhcbccbbbbbbbbdehhedba##aaaabbbbbaaaaaabbaaaaaaa########cba#######a#abbda#aabcbaa##aabceaaa######aaa##aa########aaa##aaaaaa#aaa###.###aabaaa#aaa#aa##abbbaa#baaaaaaabbbbbbdbbabaaaacaddacbbbbddccccbbda#cbbcdcddeccccbaabbbbca#aabaaaaaaaaaaaaa#####" "#aa###a####.##########aa#a##aaabaccaba#aabbaccbaaaaaaaaaaaaaabbccabaabeffeebbcb#.####.#aaabbaabbccccccccdddcec.#aaaaaaadccbbcccca.#######aabdhecdddeeeddeefecbbeedcaaaaabbbbbbabbbbcbbaaaaaaaaaba##aba####a####aacdccaa#ccbbaa##aabcdaa########a##aa########aaaa##aaaaa##aaa#########aaa##aa#aba#aabbbaaaaaa#aaaaaabaaaccbaaaaabccababbbb###bcbcbbecabbccdcddcdcccaaababbbbaaaaaaaa#aaaaaaaaa###" "#aa#aa##########a######a#####aaaaabc#abaaaabbcbbaa#a##aa#baaabbbbbabbcfffgghebdcbbacacbbbbbbbcbccdccfdaaabdedcaaabaaaaacccbbbbbbcb########abcfgedeffeeeegfcbbcbadgdddaabbbbbbbbbbcccccbbaabababbbaacbaa#########abcccbabccbbbaa##aabcb#a#######aa######a#a##abbbbabaa###a#aa########.bbaaa#aaaaaa#aaabbbccbaaaaabbbbbbbaaaaaaaaabbbccccaaa###bcdbabcbbbabcdddcbddccbbaaaabcccabaaaa#aabaaaaaaba#" "#aaaaa#######a####a###aa##.###aaaaabc#abaaabbcbba###aa####a#aaabbbaabcdcdeccdecccccba##aaabbaaaaaa##beaaabacfdeaabdecb#bdcbbbbbbaca#######abcdegeeeeffgfdabbccddeehhhfdbbbddeeccdcccdccbbbbbbcccbcca##a###a########aa#.aceccbbaa#aa#acb###.#####aa#####aba###abcdcbcbaaaaaaa#####a###bc#abaaaa#aaa#ababbbbccbaaaaabbcccbcbaaaaaabccdacccb#a###abddbbbbbbabbcebcbbdcccbbaabbabcabaaaaabcbaaaa#aaa" "aaaaaaaaaaa####aa#####aaaaa.###a#aaaccaaabaabccaa##aa#######aaaaaaaaadc##abaaaaa###a#######a#########cb#aaaacdddb#bbdda#becbbbbbbac#######abceffhffffda##babcccdeeddbddeecdcdebdeeccdddeddcccdeba#b###aa##a#########a###bedbbbbaa#a##aca###.#####aa####aaa####bbcdddbaaaaaaaaa#######adbbabaaa##aaaaaaacbabbccbaabaabbccccaaabbcbdcbcecccaa#a#a#adcabbbbbcbbcbccaabccdcbbbbcacbaabbaabcbaaaabaab" "bdbaaaabbaaaa#aa##a#aba#############abcaabababcba##aa#########aaaaaaabdb##aaaaaa###a##################b####aaccdeaabcbbaaeddbabbbabb#######bdfhghhgda###aabbcccecbbbdcccefdbbcbcb#eefgghggfeegdaa##a###aa#######aaa#####bedcabbaa#####acb##########a##aaaa####acbccccaaabaabbbba####a##dbba#aaaaa##aaaabdababbccbabaabbcddcbacbbccdacdbba#####aaaabcbbbbbbbccbbababbcddcbabbbabaaabcaaabaaacabaa" "aacdbaa##.##a##aa#aa#aba###.#########abca##aabbbca#..###########aaa##aab######aaaa#########aaa#a###aa#######aaccdfbabbaaaeeddbbcbbbdbaa#abcdfhjigca######abccbadb###cfbcbbecabbba#begfhggddcggdbbaaa##############a#aa#.cddccbaaaa#####ab##########aaaaaba####accbbbbaaabaabbbabb#######aba###aaa#aa#aaabcaaaaabccbabbcccdedcbdbbacdcdccaa##a#aaaaabcbbbbbacccbaaaabaccccbaaaaaaaabbbbaaaaababba" "aababbaa#####a##a##a###a####.##########aba###abbbbba####.#.#######a###aab######aa#a#########aaa#####aaaaa#####bbceebbbba#ceedccedcegdcbcddedbcbed#######aabccdbdda##adeeb##abbaaaaacbadeddfdghdcbbbaaa###########abbbcdbbdcbbca##aa#####bd###.#.###aaaaaaaba##abbbbbbbaaaaaaaabbaaa#######aa###aaa#aaaaaabcaabb##abcbbaabcedccdcbaaccccba####a#aaababcbaaaabbccbbaaababccbaa##aa##aaabaaaaaaabaa" "aabaaaaa#a#####a###aa##########..######aaba####aaaabb#.###############aaab##.###a#a#######aaaaaaaaa#a#aa###a##aacdceddfgfcfffgdccdeeefggdbaabbbbdcaa###aaabbcddeb##a#adfeaaaaaaaaa#bbaaccbeedhecbabbaaa#########.adccbcdbdbbcbba#######a#cda########abbaaaba##abbacbbaabaaaaabaaaaaa########aba##aaaaaaaaabcaaa#a##abca#aaabdefecbaadbbbaa##aa#aaaaaabdcbaaaaabcbaa#aaaabbbaaaaaaaaaaaaaaaaaaaaa" "aaabbaaa#########a##aaa###########.##.##aaaa#####aa#cba################abcb.####aaaaaa##aaaabbabaabbbaaa##aaaaaccgghggecdfihhg#a####a#a#abbccccacdcabbbbbacccdfeba#####aaaaaaa###a#ababbccadcgedccbaaa############ccbabccbcacabaa#####a#bacd###.####aaaaaaa###aaabbccaaaaaabbabbaaaa###.##..#bbb###aaaa#aaaaaaa########a#aabccceecbbdbbbbaa#aaaaaabbaadccbaabaabba#####aaaabaabaaa##aaba#aaa#aaa" "aaaa#aa##############bba##########..#.############aaaaaa#####.##########abca..####abaaaaabbbcccbbccddbbabbbbbcdefebdfd##a#.bedaa#########aabbbcbcddddcbbbcdeffd#########aaaaaaaa#aa#baaabcbacegedbbaaa##########bcdbaabbcccbbbaaaaa#####abbcca####.##aaa####aaabbcccdbaaaaaaabaaaaaaaa####.###abba##aaaa#aa##a############aaaa##cfebdcabcb###a##aaaabbabacbaaaaaba#a####aaa#aaaaaaa####aaaaaaaaa" "abbaaaa####a##########aa###################aaa####abaa#a################aabc#.#####aaaabbbcdddcdfffefgffeddfgdcdcb####aaaa###bb#######a##aabacdcddbdccacdefecc#a##a#####aaaaaaaaaa##aaaaabbbabfgdcbaa########aaacbbbbabbbbcdaba##a#####a#abccda####aaaaa#aaa#abaaaccbbbaaaababbaa##aaa#########bbba##abaa#####aa#a##aaa#a###aaa##defdcabbbaa##aa#aaaabbbaaccaaaaab######aaba#aaaaab####abaaaaaaa" "aaabaaa#################abba###############aaaaa##aaaaa#a###############aacaca.#####aabbbbccddfda#adeca#####b###aa#aa#aaaa##aaba#a####aa#aabccdccedebaacccb####aaaa###a###abaaabaaaaa#aaaaaababdgdbb##########cabbdbbbaaaaaccaaaaaaa##aaa##acdc#.#aaaaa##a##aabaa#ccaaabaabbaaacbb##abaa######..abca##aaaa#####aa#aaaaaa######abaabdggcaaa#aaaaaaaaaaacba##bbaaaabba#aa#aaaaa##aaaba###aa#aaaaa#" "#########.#################aaaa#.#.##aaa###aaa##aaa##a##aa###############abbbba#.##.#aabbbbcefc####...#####aa#####aa###aa####aa#######a#aaacbacbbdddbbccdfecbcc###aa####aa#aaaaaa###aaaaaaa##aaacfdaaa#####aaaabbabbbbaaabbabbaaa###aaaaaaa#abce..##ababc####aaaaabdaabbbbbbaaabbbaaa#a##.#######abaa#aaaba##aaaaa#a##aaa###aaa##ababehcaaaa##aaaaaaaadc####abaaaaaba###aaaaaaa###aaaaa#aaa#####" "####a######################aab#....##aacaaa#aabbaaaaa#####a##############aabbbcb##.###abbcceca###################aaaaaa#a#aa##a#aaaaaabaabbbbbacaaabbabaafddcbcb###aaa#aab##aaaa######a#######a##cfeaaa#####abcbbbbaaaaaabbabba###aaaaa#aaaabaaee#.##ddaaa####aaaaacaaabdcbbbbaabaaba#aa##.#######aaaa#aaabaaaaaaa##aaa#a##a#aaaaaaabbcgebbba#aaaaabaabbaba###aaaaabbaaaaaaaa#aaa##aa#a##baa#a##" "####a##aa##################aabda#.#####bcaa#abaabaaaaaa###################aaabcdb.####bbbdea##########.###########aaaaa##aaaaa##aaabbbbcbccbbaaaaaaaabbbaaaacdcbbbaaaaaaaabaa#aaa################abecaa####aadcabcaaaaaaabbaab#####aab#aaaaabaaade#..#ca.#a####abcbbb#abbccaaabbbabbbb#a############aa#aaaaaaaaaacaa##aaa##a#aaaaaacabccfebbbbaaaaabbbbaaba####ababacbaaabaaaa##a#aaaaaa##aaa###" "#####aaaa###.#a######a#######aab##..####abbbbbbbbaaa#aaa####aaaaa##########aabddea.###abda#################a#########a#####aaa###aaabbcdcbdbbaaaaaaaaabbbaaaaacddcbaaaa###abaa######..############abeda###ababbbccbaa#aaaaaabaa##a###ab#aa#aaaaaacec##ab.########babbaaaabbababababbcda###############a#aa###aaabcbbaaaaa###aaaa#ababbcdcdecaabaaababbaaa#######aaabbbbaaaaaabaaaa######a#aaaaa#" "a#######aa#a######aa#a#aaa###aaac#########abddccbbaaaaaaa####aa#aa########.abehghhc##abca##aaa##################################a#aabccb#aabaaaaaabbbaaaaaabaaabbbdba#aa###aaa##################aa#abefccaabbbcbabbaaaa#aaaaaaaa#aa###abaa##aaaabbcfdaba.#a######bacc##aaaabaababaabcbca##.#####a#####a#aaa#####aaaaab##aa##aaaa#aaaabccebbffbaaaaaabcaa###a#####bbbbbbbaaaaabaa#aa######aa#aa#a" "#baa#aaaaa###a#a#aaaaaaa####b#aaba#########aacbdcccaaa##a###aaa#aa##########bbfikjicacc###aa#aaaa#############a###################aaabccca##aaaaaabbaaaaabbbbaa#aabcbbaa####a#################a#aabaabdfbdcccbbbbbbbbaaaaaaaabbaaaaa#a#aaa#aaaaaabbcfdbb#######a#aaac##a#ababaaaabbcdaaaa##########a#aaaa#a#aa##a#aaaaaa#aaaaaaaaaaabbccdcaaegcbaaaaacaa#####a####bbbbbbbaaaabba##a###aaaaaa####" "####aa#aaaa##a#aaaaaaaaa##a#####aba##########aadcbbba####a####a#aa##########abcdfhiigc#a##aaaaaaaa#aa#####################a#######aadccccaba##aa#abaaaabbbcaabaaba#aaaaaa####a###a#a###.#####acbbcbaabcehfdccccbbbbbbbaaaaaaabaaaaaabaaaa###a#aaaabbcddca####.#####aa##aaacbabbbbaabcba#bc############aaa##aa##aaaaa#baaaaaa#aaaaaaaabccdeba#cgfbaaabca#a###aa#a###bcbbbbbbaabbba##b###aaaa#a###" "###a#aaaaa#aa######aaaaaaaa######aaaa#######a##aaaa####.###aaaaa#a###########abacdhiiga##abbaaaaaaaa##############a########a##a##abbcabc#abbaaaaaaaaaaaaaacaaabaa###a###aa###a###aaa########bbbbcbbbbddceihebbcbbbbbabbaaaaaaaa#aaaaaab#a#####aaaabbcccfb#.########aa##abaaaaaaabbaaaabbcbc#####a######ba##aaa###aa###aa##abbaa#aaaabbbdcccbbabdhebcbaaaaa####a#####accbbbbcbaacba#aa###a#aaa###" "#a####a#aaaaa#aaaaaaaaaaaaaa#######aba#######a####ab########aaaa##a#a##.#..#####aehhjihb#abacba#aaaaaa############a#a########aa#aabdcc####abaa##a##aaaaaa#ababa#a##aaaa#######a#aaaaaaaa##aacaabcccbcbabbcghgdbbabbbccba##aaaaaaaaaaaabaaa####aaaabcbcdccaa#########.##aaaaaaaaabababbabaa#######a#a##abbba#a######a###aa#aaaaaabbaabbcdbbbbabbadffbbaaaaaa#a##a####aabcbbbccabbabaaaba##baaaa##" "##aa###a#aaa#a##aaabbaaaaaaaaa##aa###a#############bba#.###aa#aaaaaa#######.####adfehjif###aaaaaaaabbaaa#a########aaa###a######abbbbcca.###a###########a###aa###a#############aaabbbbbaaceb#aaabbbccbaaabbbdggdcbbabbbbaa###aaaaaaaaaaba#aa#a###aabbbbcdc#####aa#######aaaabbbaaabbbbbbba#aa#######a##aabbaa#######aa###aa#aaaaaabbbbbccaaccbbbccdfgedaaaaaaaaaaaa##aaaccbcccbbccba##aa##abaaa##" "########a#aaaaa#aaaaaaaaaaaaa#aa#ba###########a####aaaaa#.##aaaaaaa##a#a########bbceeijfc####bbababaaaaaaa#########aa##a#aaaaabbadcccba####.############aaa#aa#############a##abbabbbaa##ceaaa#aaaabbbaaaaabbdgfbbbbbabba####aaaaaa#aaaaa#####a#aabbbccdccca#aaaa######aaaaababbaaabcabba##ba##a##a#aaaaaaaaa#######a#a##aaaaaaaabbbcccaabbddcaabbabdffdbbbaaa#aa####aabbccbbcbbddbaaa####acbaa#" "#######aa#a#aabbaaaaabaaaaaaaaaa##aa#a#############abaaaa####abb###aaa#a########babcfhiiea###acbbabbaaaaaaaaa####aaba#aaaaa#aaabaccbcbaa###############aaaa###a##############aabaaaaaa####bbbabaaaabbbbaaaabbbcffbbbbbbbbaa##aa##a###aaaa####aa##aabccefcadda##aaaabb#aaaaaaaaaabbbbbbbba##abb######aaaabbba###############aa#aabbcccbabbaabdccccaabacfggccbaaaaaa##a#aabccbbcaabdbacba####bbaaa" "aaa####aaaaaaaaaaaaababaaaaaaaaaaa#aa##############abbbbaaaaa##bbbaaaaaaa######ab#bccehiic###abcaabbbaaaa#aaaaaaaa#aaaaaaaaabcbccacba########.##########aa###############a#aaa#aa#a##a#####acbddcbaaabbbbbaaaabbefcbbbabaaaaaaaa######aaa###aa#####abcdghedcbbbbbcccdcbbaaaaaaaabbbbbbabaa#.acca#a###aaaaaaa########a##a###aaabbcdcaaaaaabbaccddaaaaacaadggfdbaaaaa#aaaaaabccbbaacbaababaaaabbaa" "aaa#a#####aaaaaabaaaabbbaaa#aaaaaaa###aa#######.#a###abbbaabbbbaaaaaaaaaaaa####a##ababchie###aabbbaaaaaa#aaaaa#aaaaaaaaaaaabccccbccb####a#############aa######.###########aa###aa#aaaa#a###abcccdbbbbaaaabbaaaabbceebbaabbaaaaa#########aaa##aa#####acdfdefebcddcbbdffdcbaabbaabbbbbcdbbaaa##abca#####aaaa#a##a#aa####a#a##aabbdedaaaaaa#aaccbeda#aabbaaaacefgfdbaaaa#aaaaabcccbccabaaabbaaaacc#" "##a##aa###aaabbbaaaaabcbaaa#aaaaaaa#a##########a#####aabbaaabaabaaaaaabcccca########aaacfhc##aaabccba#aaaaaabbaaa##abbababbcccbeecba#####a########a####a#a#####.##########b######a##a##aa###aababaaabbaaaaabaaaaaabdfcababbaaaa##############.#######bddcbdeffcbbba##dihdcbaaaaacaabbbdcaaabaa#aba#####aaa######aa##a###aa#abcdccdb#aa###aaaccdcbaaaaaaabbaaabehhebaaaaaaabaccbcbbbaaaaaaaaaaacb" "a##aa#####aaaabbbaaaaaababaaa#abaaa#############.###aaaabcaabaaaabbbbacdedaaaa######a##bccdccaaaaaacdcaaababbbaababbbccbcbbcdcceedc####a##a###########a#aaa######..####.####.###aa######abbaaaabaaaaaaaaaaaaaaaaaaaacfeedbbaa############.######aaaa#abbaaaaccbabaaa###igdccbbbaaaaaaabcbabcbcb##a######a####a#aaaaa####aaaacb#abdcaaa#a###a#acddcbaabaaaaaaaaadfhhedaaabbabbcccbbaaaaaaaaaaaaaa" "ba##a##a#aaaaa#aaabaaaaaaacaabcbaaaa#aa#########.#########aaaaaa##ababdefcab#aa########aabdfgbaaaaaacdcaaabaaaaabbbbabbcbbbcccddaaaa####aa#aa########a#aa#########..##.##..###.###aaba###aaaaa#abaaaaaaa#aa#aaaaaa#aaaegdcbbbaa###########.######aaa##aaaaab#abaaaaaa#.febaaabcccbcbbcbbaaadbcecbaa#####a#aaaaa###aaa#aaaaabaaaabccaaaaaa#aa###adbbbcbbaaaabaaaabbchifbabcccabbccaacbaaa##a#aaba" "#ba########a###aaaaaaa#a#aaa#abaaaaabaa##a#aa###############aab####aaaaabccaaa##a#.#####abcdfb#aaaaaaaaabaabbbcbbbbbababbcdddfedcb#a##aaa#aaaaa###aaaa##aaa##.######.###.###########a#########aaaabbaaaaaaa###aaa##a###bfedcbbaaa############a####a######a#aaabcbbbaaa#gdaaa###bcddcecccca#addefgfddca###a##aaaaaaa##aabaacb####bbdcaaaaaa#aa###ccbbbccbaaaaaaaaabaadhieabaabbccdcbabbaa#####aaa" "#aab####aa###aaaaaaaaaaaaaaaa#aaaaaaa#####aaa#a##.############aa#abaaaaaaabaaaaa########abccdfcaaaaaaabbbaa#abbcbbaacabbbbcddecdcc####aaa#aaaaa#aaaaaaa##aaaa###..######.#####a########aaa#a####aaaaa#aaaaa########aa####dedbbbaaa##############a###a#####ababccbaaaaa#gcaaaa####bdebbbbbca#bddcbaabccaa##a##aa#aaaaaaabbaca####abdbaaaaaaaaaa#a#ccbbbbbbbaaabbaabba#adhgcbaccccccdccba######aaa" "a##aa#a###aaaaaaaaaaaaaaaaaaaaaaaaa#aa###aaaaa###.#############a##abababbaaaaaba######aaabbcddhcaaab##baaababaabaaabbabbbbcdddffeeb###aaabcaaaaaaaa###aaa#aa####.######a#######b#####aaacb#######ababaa#aaa##aa########a#aaeecbbbaa##################a##a##bbaabb#aaaa#cd#aaaaaaaace.aaa#bdccdcaaabcacbaba###aaaaaaaabaabccaa#aaabbd#aaaaaaaaaaa#bcccbbbcbbaaaaaaabbaabbhidbbcccbdeddaaa#aa#aa#a" "aaaa#aaaa##aaaaaaaaaa#aaaaaaaaaaa######aa#aaa####..#########.###aaabbbcbbbaaaaaaba#####aabbcccegcbaaaaaaaacbaabbaaabaaaabcccdeeffddaaaaabcbbbcfffecdcba#abb#############aa#a##acbbcba#bbaa########aabba###a##########aa#aaa#eedccbaaa#####a#a###########aaa#aaa#bcaaaaaafaaaaaaaaacfa##a#aaaba#abaaccbcbbccbaaaaaaabbbbbbaaaa#a#abccc#aaaaabaaaaaadcbbbcbcabbbbaaaaabaaccfjgbccbcccccaa##aabaa#a" "#a#aa#aabbaa#aaaaaa##abaaaaaaaaa##aaabaa##aa#a###.#.##############aabbbcacbaca#aaca#####aabbccdeedbaabbaaaabbabababaaaabbccdddffedffb###bbccefebccbdeda#aaabbaaa#######aaaaa###aabcca#adaaa#####aba#aaaa##aa################.cedcbbbbaaaaaaaaa##a######aa####aa#bbaaaaaadc#aaaaaabbee####abaaa#aa##abaaabbabdcccdcbbaccbcb##aaaaabbcdbaaaaababaaaacbccbbccbaaabbbbaabababadjiedccccbbbaaaa#aa#a#" "aaaaa###aaaa##aaaaa####abaa#aaa#a###aaaa######aa#################a##abbbcccbbbaaabba##.#aabbbbddedd#aacb#aaaaaaaaaaaaabbbccdddggffghecbbaabbbddabaa#aaaabaaa#bbbaaaaa##a##aba###aaabb##bbaa####aaaa###########a########.#####aaeecbaabbaaaaaaaaaaaaaa###aaa##a##aa###aaabeabaaaaaabchca###a#aa#a###a##aa####bca#abdecbcdbaaba#aaabbdcaaaaaaaabbaaaaccbbbccdbabaaabbbabbbabacjkjgfdccbaaaabbaaa##" "#a#aaaa###caa#####aaadb#aaa#aaaa#aaa##aaa###aaaa#a####a##a######a#a##aabbbbabba##aabaa##aaaabacdececaaaba#aaaabaaaa#aaaaccdeeefgeeefbcbbbcbbbcbaaaaaaabaaaaaa##abba##a#####aaa###aaaa##.#ba##.###aa############.##.#############dedcbaabbaaaaaaabaa###a###aa##aa#aaaaaaa#dbbbbbbbaacgg#b####a####a##aaabaaabbcaa#abacdcaaaabaaaaabbccaaaaaaaabbbbcbabcacccccbabbaabbbabcbbaaejklhfcbcbbaaaa#aaaa" "####aaaaa##aaaaabaaaaabbaaa##aaaa###aabbaa###aa#aaaa###aa#######aa#a##bcccaaabbaa#acaa###aaaabbcdcdcbaabaaaaaabaa##aaaabbccdfffghffdaabbaabccddbabaaaaaaaaaaaaaaaaa##a#######a####aaa###.aba######a#################a############bfedbaabbbbbaaaaabaa##a#########abbbba##dcbabbbaaabcgdc#####aabaa###a#bbbbbbbbbbaaabbcbbabbbaaaabbbdebaabbbaabcbbbbacbabbabbbbabbbaababbbbbghillgcbbbbbaabbaaa#" "###aaaaaaccdcaaaaaaba##aaaaa##aabaabaaab########aaaba####a###a##aaaaaabccbba##bbba#bca###aaaaabdcddcda#abaaabaaaaccaaabbbccefgfghffaaaabbaaabefbcbaaaaaaaaaaaabaaaa##aa#########a########aaa###a##############.##.#.############a#abdebabcdcbbcbaabba############acdea#abecbaabbbaabbdfc##aaaa#a#aaa##abbbcaba#adebaecabbaccdcbbabbcbdddbabbbabccccbbacbbbbbabccbbbbbaaaabcbcfijjkjfddcbabdebaaa" "db#bdccbbcb##aabbbbaa###aaabbbbaccaaaabca####.#####baba##a#aaaaa#aba#accbbbbaaaaaaaacbaaaaaaaaacccdccc##abaabbaaabdbabbcccdffffhggbaaaaabdbaaaababbaaaaa#a#a#aaaaba#a#a################aabaaaaa###########.#####...#####.##.####aaaa#bedcccaaaaabbaaaaa##a#####aaaaddaabdebabbbbbabbbbgcaa#a#aaaa###aaabdaddabaadcfdfgdacbaabcbbbcccbdcdffdacdcedccbbbacbbbbcccccbbbbabacabbdgigbbgjjedcbbbccaaa" "#bbbaaaaaabaaabbbea#aaa#abbbbabaaaaaaaaba#############b####aaaaaabaa###abbbbbaaaaaaaacbaaaaaaabbcccccdd##cbcbcaaaaaaabcdeffgggiigabbbbbaabcaaaaaaaaaaaaaa#aaa##aaaaaaa################aaba###baaaa#######.#####....#########.#a##aa##a#adfca###abbaaaaaaa#####a####bdbacfdaaaaaabbaacedfa#aa#########abefeddcccdebccfggfedaaccbacddecdccdeddccefddcccccccabaabbabaabbaabacbbhijgdbacfkjeedcba#a#" "###aaaaa#abbaaaaaaa#a####bcaaaba###a#aaaa######a####aa######aaababaaaa##aabbaaaaaaaaabcaabbaaaaabcbccccbcbaaaaababbcccdefgfgghkgbaabbcbccbaaaaaabaaaaaaaa#aaaa#aaaaaaaaa####a########aaabba#aaaa#####a#.###.######.#####.####.##a#abaaa#aaddaaabbaaaaaaaa#########aabgggfbaaaaaabbbabbcfea#a#####aa##afghhfggghhgccddffhfffcccbccdfgeeeceec#aabcddcdddccebaaabaaabaaacbbbb#ejhjgbbceceikibbceba#" "aaa##a#aabbabbaaaaaaab####bc#aaaa#aaaaaa#ab##aaaa##a#aa######aa#baaaaaaaaaaaaaaaa#aaaaacbaabaaaabbcccccdbaaaabbbbccddeeefeegjheb#a#aabaccdcaaaaaaabbabaa#aa##aaaaaaaaaaaa#######a###aaaabba#abaa####..###.###.####..#####.#######aa##ba#####bcbaaabbaaaaaa########abdfggebabaaaaaabbbbbchfaaa######abbfegggefgghgffeecefggfhheecdddeeefdcefcabaabccbaabcbcbaaaaaaabbabbbbbbfghggdbcbcbbgkjfbbecb" "#aa#a###aababbbaaaaaaac###.acaaaba#aba####ac#aba###aaaaaaa#aa##a#a########aaaaa#aaaaabbbbbaabbaaabbbccccebaaaabbccddddedegggfhbaaa##aaabcccaaa#aaabbbbcbaaa#####aaaaaa#aaaaa#####a###aaaaaabbdaaa########...##.###..########.#####aa#aba###a#accbaaaaaaa#######aaaaabccdeeccbbaabaabbbbegfgeca#####adefffefgggfghggfeeccegihijigedbccfeceddfeaaabcacbbaaabbaaabaaaabbbbbcbchgghfgdabbaa#bgkjgcdd" "d#a#a####aaaabbbabaaaaaa####abaabaaaaaaa###acdbaa#a###aaaaaaaa###########aa#a####aaa#abbbbbaabaaaaaabcbccdaaaaabccddeefefhgefgbaaaaaaabaabbaa##ababbaaabcca#aa#aaaaaa##aabaaa####a####aacba#bcb#aa#.####.#...##.##..################a########a#adbaaaabaa#aa##aaaaabbbcdeddddcbabebbcbbffeefdec##adeeefeffefghgghghhgfedfheabfghhfdcegecbbbbccaaaabcaaaaaabaaabaabbbbabbcdfffgffffabbbbbcabgkjec" "cdaa##aa#aaababbbaabbaaaa####bbabcaaaaaaa##.acaaaaaaaa#aaaaa#ba###########aaa#a###aaaababbaabaaaaaaaabcccdgbbbccccddeffefgfeffbaa###a#aaaaaa#aaaaaaabbbccaaabaaaaa##a###aaabfd#####aaaabbaba#aa########.###.##.###############################bacedcbbbbabaaaaaaaaabcccccddedddbbdeecdefeededdeeffdegffeddefgfgggggcb##abbca###bbefeefeddcdcbeeaaaaab#a###babbbbbababcbccfgfeeefegcbaaabbca#afkh" "gdcbaaaaaabbbaaabaaabbbbaaa###bbcbaa#aaaa#####a###aaaaaa#aaa#aaaaa##a#####a#aa#aa#a#aaaabbaaacaaabaaaabccdfgddddddccdfhhffddfbaaa####aaaaaaa##a#aaaaaabbdb#aaaaba#a#######aacegdbaa#aaabaabbb########.#.##.##..#...####.#######################babedededcbaaaaaaaaabccddeedefecfffeeffddddddeddeeeddeggfddeeffbaaaaaaaabdb#baa#a##cbdfeaaabbcdfbaaaaa####a##abbbbaabbbbdcgfgeeedeefabba#aaaaaabg" "gjgccbaaaaabbbbbbbbaacbaaaaa###aaaaaaaaaaa####aaa#####aaa##aaa#a#a#######aaaaaa##aaaaaaaabba#acaacbaaa#acccfgdefefcdecfhhddbcaaa#a#####aaa#aa###aaaaaaabbeebaaaaaaa####.###aaacdcbaaaa#aaabba#############.#.#.#...###########..###############aacddeeededceeedccefggfgggfedggghfdfecdddccccddeeeeefddfffddddbabbbaaaaabefcdb#aa##aaabcaaaaa#bdgb#abaa#######ba#bbaabaaeegfgfeeeecfcaaa#aa#aaaa#" "#bgifcbaaabbbcbbbbaabbbaba#a#aa##aaaaaaaa######aaaa##a#aabaaaaaaaaabaaaba##aaba###aaaaaaaaabbabbabaa#a#abcceffeecb#cddeeggcdb##a##aa##aa#########aaaaaaa#bedaaaaaa##########abaa#aaaaaa#aaabaa#####a####################..######.#a##.#########aabcccbcda##afgggffdbbbabdhheghifedddeecbccdcdefffeeffdfggfdbaaaaa#aababbacdddb#bb#aaa#a####ababbdebbbaaa####a#babbaaacddfgffeefeeddcbabbaaaa#aaa" "a##ehiecbbbccdccbbbbaabbaaa#aaa##aabaaaaaaa####aaaa#####aaba#aabcbbbaabbba##abaaa######aa#abbacbaaaaaaaaabcccdfcaa##bbbbceabaa######aa##a##aa####aaaaaaaa#abaaaaaa###a######abbbaba##aaa#a####aaa###a############.########################a####aa#dcddcdb#a#dedeedcaa#baacgegiifedddddddcdddefeffggfgeedbba#aaaabbaabaaaaabceebbdaaaaa######aaaaabdddb#aaaaaabacbbbaabdfffgfgfeeeeddgcbaaaaa####" "#b##adiifdbcefedccccbaabaaaa#aaaaaaaaaaaaaaaa##abaa######aabbaabbcbbaaaaaaa#abaaa#######aaaaabcca#aaa##aaaabbccc#########a###aa##a###aa########aaa##aaa#aaa#aa#aba##a#######aabbabcaa#ababbca##aa####a#####a.#########################a###a##acba.ddeecccba#cfeeedcaaaaabccbaigfeeeddddcbcdcddfeffggeedaabaaaabaaabbabaaaaa##cffedeaa#a#aaa#aaaaaa#abfebabaaaaaacadcaaffecffffgfffeeggaaabaa####" "#caaa#.ahjgffefgggffecbbbabaaaaaaaa#aaaaaaaaababaa#aa#a#aaaabaaaacccaaaaaa#a#aaabaa######aaababaaaaaaaaa#aaaabccb####aaa##ab###aa#####a#a####.#aabaaaa########a##aba########acbbaaaaaaaaaabbbaaa################a###a####aa############aaccb#adcbbdddccbcdebdedccba#a#aabdcbaggeeddedcbbbccdeeffffhggfcbaaaabbbcaabaaaba####a#debceea#aaabaaaaaba#aaa#cfgcaa##aabcbcbdffedfeeeefefeedhcaaaa#a###" "####aa##.behhgfeeeddefedbbbbaaabaaaaabaaaaaaaabaaaa#aaaa#a#abbaaabbcbbaaaaaaaaaaaba####aa#aaabaaaa##a#aa#a#aaabbcc.##ab##aabca##aaaa############aabaaaaa#a#a#####aaa#bb#.####bccbaa##aaaa###aaaaa######a#######bbabba####bb###a#a###a###bcccccdcdccddcbbabcdcddccba####bdddb#bdcecdedcbbbbbcceeeeehhcdaaaababcbcaaaaabaaa#####ab#aabb###bb##abcaa###a##adfeba###aabaaefefffedddeedefefhbaaa###.#" "#####aaaa###chikjiigedcegcccbabbaaaaaabbaaaaabaa#aaa#a#a##aaaaaaaaabaa#aaaaaaabbbaa######aaaaabaaaaaa##aaba##aaabab.###aaaaaabaa#aa#a#############a###aaba########aa#cbb####abcbaaa##aaa#a######a#.####aa###bbccbbdccbaaabb###a#aaaaa###cbbbaccccbbcccaaaabbccccbbaaa#accdcb##bacgeeedccccbccdeeefggebdaaaaabbbbbbaaabaa#####a#a#aa#####aaaa##ca#####a####beeca#b#abadgefffedeedfdcffeff#a#a###." "..######a#aaadd#acdhihecdgecbcaa#aa####ba#aaa##aa##aaa###aaaaaaa##ababaaa#aaaaabbbaa######aaaaaaaabaaaa##baa##a#a#b######aaaaaaaaa#################a#aa#bcb#####aba##a######bbbcbaabcaa#################a#abcdbdefededcbcbaa##aaa#a###bcbababbccbbbbbcaaaaabcccbaabaaaabcdbba###bhhfhgeddccbccddfhhhfbbaaaaaabbbccaaaabaa####aa#a#####b####aa#aa#ab###a##aaabefd#a#abbfgfeeeeeedeeddefggbaaa####" "##.######aaba#abaaaabeiiebceddcbaaaaa###aaba#########a##aaaaaaaa###aaaaaaaaabaabbbbaaa###aaaaabbbaaabbaaaaa###a###bb#####aa###########a######a#####aa#baaaba##abcedcbaa##a##bcccbaaaddccaa##############a##bbceffgfededdedcbaa#a#aaa#bcabaaabbbccbbbbbbaaaabbcbbbbaaaaabbcda#a##ehgfeeeeecddbcddfhhgcbbbbbbaaaabcbbbaaaaa###.#a#a#a####aaa###aa##a########aabbbedbacfegggfeeefeddccddgihdaaa####" "##.###a####aaaa#bacbaa#chidccdfdbbabaaa#ababaaa###a###aa#aaaaaaaaaba#aaaabccccbcccccabb###aabaabbbcbaabaa########aaab.####aaa##################a####b##aaaabb#aacdddcbb#######bccaaaabdbba#####aa#a#########abccccccddcffhigcbaaa#aa#acaabaabbbbaaabbbbbaaaabbbbaaaaaabcccdda#a#higheddefedeecdffffeeaaabbbbaaabcbaabaaaa#########a####aaaa######a#######aaabdcbadgfdeddegfgfeedcccccehigaaa####" "###########aa#####aacdb##ejgcbbfedcaaaaaacbabaa#####aaaa#aaaaaaaaaaa##abbbbbbaaabbcddddbccdcccbababaaaaaab#########aba..####aa###################aa########aa##aaaabbbba##a####ccaababdaa#aa#####aa##########aaaaabbccdfgjjihdcaa#aaaacbaabbababbaabbbabaabbbbbbbbbbbbbcccddebadhggfffeeffffeeeffdccddaaaabaaabbabbbbaaaa######..######aaaaaa#a###a#aaa###aaaccc#ceggedddcffffedcbabccdfgebaa###" "#########aabaaa####a#aabbachjgbacdedcccbabaaaaaaa#####aa#######aaaaaa#aaaaaaabaaaabbccdccddcbbbabaaaaaabbaa########aabb.#######a##################aaa##########aa##abaaaaa######bbaaaaba#a#a#.##.#a#aa###aa###aaaaaabcddgijijjigeba#abdcbbcdcabbbbaabbabaaabbbbaaabbbbbcacddee#dfeeeffeccdghhfffebccccaaaaababbbbaaabba#a########.###a##aaaa##aa##aaaaa####aababbddceggfedcdffedcbaabcdeeffaaaa#" "#######a#aaaaaa#a#####aaaabcdiibaaacecddcbaaaaaaaaaa##aaa########a#aa###aaaaaaaaaaaaabcccbbaaaaaaaaabaabbaaa######aaaaca.###.##a#a####a########aaaaaaa##...###a###a##a#aaaa#####bdaaaaaa########a########a##a##aaaaabbbbegfeedeghgeccddeeefgcbbaaaabbbbaaaabbbaababbbbcccbceeebegdddeffedbdeiihecbcbdbaabaaababcbbaaabaaa#a#.############aaaa##b#a##aaaaa##aabbbbccdceghgeddefedcaaaaccdedfaaaa#" "########bcaaaaa##########aaaa#gidaaabedcccbbbaabdbaa####aba#a#############aaaa###aaaaaaacbbaaaaabbabbbbbcbbabaa######aabb..##.####aa#aaa######aaaaaaa####a#.####aa##ba#aaaba#####dbaaaaa######aaa#aa######aa###aaa#aaabccebabaabbdfhhhgfghggdbaaabbcaaabbaaabaaaaaaabccccccedchigdcdddcedccabghdbaaabcaaabaaaaabbbbcbbaa##a########a##.#aaaaaaaaa#aaaaaaaca#acbbbbbcccdefeddeecdcbaababcfdfeaa##" "########baaaaba#aaaa#####a####aciib#aacdddbabbaabbb#aa#####aa#############aaaa##aaaabaaaabaa##aabababbbbccbbbcb#######aaaa#...##.#####aa########aaaaa######a############a#aaaab##abbaaaa#######cb############aa#aa#aaaaabaaa#######bfhigihhfbaabaaaaaabaaaabbaaaabaaaccbccdcchiihhdbcddcddccbbeeaaaabbbaaaababaabbbeeeaa#####.###.aaaa#aaaaaa#aaa#aaaaaa#bbadccbbbbccccbcddddcbcccbaaaaddddge###" "########a##abbaaa#########a#aaabcfjhaaabcdecaabaaaaaaa#######a########a#aa#abaa#####aaabaabaa##ba#abbccbaccaaca########abcb..######################aa###ceb#######aaa#####a#aaa###acaa#aa#######b############a#a##aaaaaabaa########abacfhhfcbbaaaabaaabaaaaccaaaaaaaacbcbbcffgfgcegeddeddcdccbcd#aaababbbaaababcaabaaccba########a#abaa##aaaa##aaaaaaaaaababcbbbaccbbcbccdddcbbbcbbcbbadcdeehd##" "########bb####aaba#########a####aabfjfbbcbcfdbabaaaaaaba######aa######aaaaaaaaa##a#####aaa######aaaabacbbaaabaa#########aadc...#######.##########aaaaaa#ddeb#a####aaaabeb######a###bbaaaa##b####aa#.##########a#a#a#aaaabaaa##b###.adbaabeecbaaaaaababaaaaabcabaaaabbbbbcdcfgeddgbbggeedddcccccc####aabaaaaabbaabaaa#acda############aaaaaa#aaabaaaaaaaaaabcbabbbabcbbbbcddccbcbbbabbbbccdfggf#a" "aaaa####bc##a#aaaaaaa###.#####.####aciiecccbceebaabbabbb######a#a####a##aaaaaaa########aaa#######aaabcbbabbaaaaa#########acfc..####.#.###.###aa###a#a#aaabcaaaa###aaaa##########a##bdcaaaa#ba###baa##########aaa####aaa#bbababdcbaacbbbaaaabbaaa##aaaaaaa#aabbbaaabbbbbbcdcccddcdec#adfedddcccbe#####aaaaaaaaaabbbaaa#bdb##.#######.####aaaaa###aaaaa##aaabccbbbaababbbbbcdccccbcbbbcbbbdcefghc#" "########a#####aa#bbaaaba######...####adhifegfddfdcabccbaa###aaaaaaa######aaaa##aa##a###b##########aa#aaaaaabaaa######a###abdfb..#######.##.#####aaa#a###baaa####aaa#########a####a#bddcbaaaa####aaaa####ad##aaaaaa#######abadddccccdcba##a#ababa###aaaaaaaaabaaabbbbbcbbcbbccdccbaba##afedddccbfa######a#aaaaaabbabaaaaab#####.##..#..a###aaaaa#aabbaaaaaabcccbbbabbbbbbbbddccbbcbbbcbbcfdeeffha" "##############aababaaaa##########.##.#..chjjhjifffdeccdbaa#aaa###aa#####.##aa#######.#######a#########aaaaaaaaaac########acchc.....#..###########aa##aa#abaaa##aba##a######aaaa##a##bdcbaaaa#####a#aa###bd###aaaa#aa##a####adgdcbbcddbb###aaa#a#####aaa##aaa##abbaabbbbcbbbcccddeccc#a#bhggfedaec##########aa#aaababaaaaaa#####.##.##.####aaaaaaaaaaaaaaaabdcbbbababbabbbabddcbbbbbbccbbdifdefge" "a###a##########abb#aaab#a#######...#####.##a#acgkigfeefdcaaa##aa#aaba####..######.#a###a#aa#aa##.#######aaaaaa##ba#####aaabbeha...###.###.#######a##aaa#aaa#a#aaaa###aa#a###aa###a###cdcaaa######a#####abb####aaaaa####a####deebbbccdbba##aaa#aa####aabaa#a#aabbbaaaaabcbcbbccbcedbba###cdffffeefba###########aaaaaabcaba#####.####.#######a#aaaaaaaaaaaaacdccabbababbabbaabcccbbbbbbbccdeeedefh" "f#######aa##a##aaa#aa#bba#########..############afkjgfgfeeeba#aaa##a#######.####.#.#####abbbaa##########aaaa##a#a#######abbcdhe#...######.##a####aa#a###aa#a#aaaaa######aaa###########bdbbaaa####a######aa##.##aaab####aabdecdcbaabbbaba##aaa#########abaaa##abbbaaaaabbbcdbaccbcebaa####adghfedeeba#############aaaaabbcb##########.######aa#aaaaaaa###bcdccbbabbbacbaabbbbbbdcccbbbbbcccccddeh" "hc#####aa######aa####aaaa#####a###.......##aa##a###gijhhhggeb##baaaa####...#####.#..a###acccaaa##########aa#####aaa####aacdddhf#..###.#..####aaaaaaaaaa###a#aa#aaaaa#####aabb##########cecaaa####a##############aabb##aabacddbcbbabbbaaaaaaaa##a#######baaaaa#abbaaa#abbbabcbbbcdgd####a##adcgfecdeb######a########aaaa#baaba########.######aaaaabbbbbbcbccbbbbbbbbbaaaaabbbbbbccbcbbbbcccccdeed" "egb##baaaaa####a##aa#aaa#a#######.#..###.###########adfilkhfca#abaaa#####..##....#....###bbccaa##a##aa####aaaaa##a##a##abbcfhjfb#..#####.######aaaaaaa######aa##a#abbbba###aba#aa#######cecaaaa###a#.#######aa##aa#aa###aaabcbcbbcbbaaabb##aaaaa#######abaaaaaabbaaa#abbbbbabbabdfeaaaa##a#ca#eecccfcaaaaaaaaa#a#a######aaaaabca########a####aaaabababbbbbbbbbbbbbbbaaaaaaabababccccbcccdccbdffd" "cfhd#acaaaa##a#######a#a##a###a##.....######.##########bddjkidca#########..###....######acaacbbb#a###ab##aaaaaaaaaaaaa#aabcfgejfa#.###a######a##aaaa#aaa#a###aa##a#abbcba#####aa####a###aeedbaaa##aa####...#aaaa#bcaccbaaaabcdccabcbbbaaca#aaaaa#########aaaaaaabaaaaabbbbbbbaaabbecbbcaaaaaa#adecccedcaaaaaaaaa##a###########abaa######a####aaaabdbbbbbbbaabbbbbabbaaaaaaaabbaabccbccbccdccdefg" "fedfea#a####a##a#a#######a####a#.##..#.####...########aaaaaeikhea#####################aaacbabbdfdbbaa#aaabbcbbaabaaaaaaabcdfbbeica..#a########aabaaaaaba#a###aa#######aaa#####aaa#.aa###adffdbaaa##ca####.#########abbcdeeeefcdcbabbbbbaacbbaaaaaa##a##a##baa##aa###aaaabbabbaabaadfb#bbbbbaa###feccbeecbbabaabaaaaaaa#aa###a####a########a##aaaaabbbbbbcbabbaaaaaabbbaaaaaaabbbabccccccddddeeee" "fggehdaaa######a##########aaaaa#.##.####..#..##.#######aabbaadjljgda.#################aaaccbccddcccccccccccccdcbbccbcbaabbcfdcbgf#...#aa######abcbaaaaabaaaaa############.##aa##a########dffedcbaa#cc##########a####bbbbcdffeedaaabbbbbcbabbaaaaaaa#######abaaaaaaaaaaaabbabbaa#a#bdcbbbaaaaa###cfeeehhecabbbbbbaaaaaa##aaa##a###a########aa#aaaa#bbcbbbabbbbaaaaabbbbbabaaaaaaaabbbbbcccddddeee" "edehhg#aaa######a#a#####a##abbaa###.###################aaabbcaacjllkhbaa#######a######bbaefddddcbbbaaaababefeedddccffdccdfgeeeefec#...#ab#.####abccbbba#aaaaaa###########..###a##########bfdfdccaaacfb.######aababaaaccccbdffebbbbcbbaacccbabbabaaaa######aaaaaaaaab#aaabaaaabaaaabbeffcaaaa####aeeeefiihfcabbbbbbabaaaaaaaa##a######aaaa####abbabbabcbaaaaccbbbbbbbbcbcaaaaaaaaaaaacbbcdddddede" "eefgghcaa#######a##aa######abbbcc#.############.###a#aaaaaaaaccbafjllkjecbaaaaaaaa##aabcccgefeecccbba#aaaa.acffffffcacdccbbbfffefda#.##########aabcedba##aa#a#####a#####..#####aa###.####bceecccbaabdfa##aabbbaabbbbdcbbccdcceebabbbaaabcdcbbbbbaaaa######a##aaaaaaacaaaaabbaba###acdeegcbbb#####aeffgfgijkgcbbbbbbbbabbaaaaa##a#aaa#abaaaa##aacdbabbccbaaa#bbbbaabaabccbaaaabbaaaaabbbccdeedddd" "deeffdfd#####a######a#######aaaca#a############bdca###aca##aaaceddfijjnligdcbbcbaaaaabcddchgedddbccaaa#aaaaa##accfbbbaa####bdhfedhd#.###########bbcccdba###aaa#####a##a#.#####a####.####.#abedebdcbbcfe#####adcbcddbbdbaaacbcbccbbbaaa#bbcbbbbbbaba#a############aaaaaaaaaabaaaaaaabdfcccbbba#####aceffgiijihedccbbbbbabbaaaaaaaaaaaaaaaaa#####aabaaabbbaaaaaabbaabbbbbcabaaaaaaaaabbbbcccdddddd" "ddddecbdca###a###a##baa#aa##abaaba#a###.#####.#aabaaa#aaa##aa#acdhilmklmlmkheegecbbbbccbcefgedcdcbbbbaaaaa#aba#a#cdabcbaaa#achihggfa############abdb#bcaa##aaa#########a###.######..########beddecbcdffc###.#acdfffdabcca#aabacbbbbbaa#abbbbbbbbbaa#############a#aaa#baaaaaba###aaadfd#babacababbbcegfhhiihgfdddcccbbbaabbaaaaaaaaaaba#aaa###a#aaaaaaaaaaaabbabbaabaaabcbbbaaaaaaababbccdddddcd" "deddddcacaba###a####aaaaaa#aaaa#aaa###aa#########a##aa#aaa##aba#.cfehhjkjllmllihfedcccbbdefgdcccecbbbccbaaaaaaaaabdbbbcbaaaabhjjhggea#.####a##a#accaa#cdaa#aaa#.#############a##a##.###a####.cedccccefbbaa#####deffeaacdaaaa#aabbbbbaaaaaabbaaabbaba#####a.###a###a#a#aaaaaaa#a##aaacdecaaaabaa#aa#bdgfeeefhhfdccccddcbbaaababaaa##aaaaaaaaa###aaaaaaaaaaaaaaaabbaaababbbbabbbaaaaaabbbbcdcdccdd" "dddcccdbbbcba#bb#aa###aa##a##a####a##.####aaa##a#aa##a#a#ba######.fffkjlhkkljmmmlieeddccefaeeeccdedbcdccbcbaaaaaabaccbccaaaabeijjigieba.#######aacbaa#accaaaaa##########a#a###aaa#############decabdeeeaba###..adeddcaabcbba##aabbbaaaaaaaaaaaaaaaaa#####a###########aa#abaaaa##a#abbcdeba#b#aa#####cefedcbbdeedcccdddcbbbaabbaaaaaaaaaaabaaa###aaaa#aaaaa###aaaaaaaaaabbbaabbcbaaaaaabcccccccdd" "ddccbcccbcedaddaaaaaaaaaa#aa#a######...###########aaaaaaaaaa####..cfhjjkmlmklkklmnjfeedeefebdeddegheeedddccbbbaaabbccbcbbaabbbgjkjjhifda.#######aaaaa###abaaaa####aaa###########aa##########..adccaddcecbabbaa##dedddcbabcbca#aaaabbaaaaaaaaaaaaaaaaaa###############aabaa##a####aacbcddebaaa########cffecdcbceeefdddddcbbbaabbbaaaabaaaaaaaaaa###aaa#a#aaaaaaaaaaaaaaaabbbaaaacbbaaabbbbcdcdccb" "cdcccccbbcdbaacbbbbbbaaa#aa#aaaa#####..#..##.#####a#aaa####aa######eigfcfgijjjlmmmmnlhfhiggdddeefgegfgffdeddcdcbaaccccbcbaaabbcfjkkkijgfb#######a#aa######a#############a###aaaaaba############abcc#ddcccbdecdcaddddddecbbbccaa###aabaaabaaaaaa#aaa#########.####a##a##a#aa#a######abccdgbb#ba#a######cffgfdefffehgdddeccccbaabbbaaabbabaaaaaaaaa###aa##aaaaaaaaaaaaaaaaaaaaaaaabbba#aabbacddccc" "cddcccbbcccaabbabaacbaaaaa#aa#aa#.#...#...#..###a###a#########aa##adeaaa#abedefijlkmnnlkkjdddfdcebb#degfaefgfeddcbdcddbacbbbbbbdjjklkkihgc#aa#####aa################aaa##a#aaabaaaaa###########aabdbedcabdddeeddddedcccddccbbbca###aaaaabba#a#####a#a###aaa###.###a#######aaaaa###aabbbbcdaaabaa##a####aeghhhggghhhfedddcccccbbbbbbbbbbbbbbaaaaaa####aaba#aca#aaaaaaaaaaaaaaaaaaaaabaaaaabbbcddd" "dddcccbbdedaabdaaaabbabbbbaaaaaa#.##.##.#.#####################aaaddbbaa#aa##a##aceejnllkkhfhfccfbbaaaabafabdeffgfcdddcabbbbabacgjkkllkhjhbaa#####aa############a##aaaa###aaa#aa#a#####.####a##aa#deedcabdeeeedeeddeedbccdcccdcb####aaabbbaaa#####a##a##a####################aa####aabbbcdea##a########aaabehiiiiiihfedfdccccccbacbbabbbcbbbbaaaaaaaa##ab##bbaaaaaaaaaabaaaaaaaabbbaaaaaabbbbbdd" "ddccdbcbedcaabbbbaaaaaabbababbaa#################a##########a###a#ecbaababaaaa#####abkllllljgbaaccbababbabaaaa#cedfheedcabbbbbbbchkkkklkhggeba###aba####.####a####a##aa##aaaaaaa##aa####.####a####dfdcba#bdeeeeeefedddcbbcdbbadcba###abaaacaaa###a##a###aa#####.####a######.##a####abbbbccbbc#ab##a#aa#ca###cfggihhihffffedcccccbbabccccdccbbbaaaaaaa#aa#aa#aaababaaabbaaaaaaaaaaaaaa#aa#abbcccc" "dedcccbcecaaacbababbbaabbbbbcbaaa#..###.#########a##############.cdabbbbbbbba###aabcddilmmljeaaabcbbbbbbbbbbbabaabcefgfecbbbbbbcdfjjkkkmkhfgecbaaabb########a######aaaaa####aaa###################befcbaabbadfeeeeffededcbbccabccccaa#aaa#abaa#######a########...###########.##..###abbbbcbbf#aa###abaa#a#####acfgffgfggefddcccccbbabcecbbbcbbaaaaaaaa##aa#aaaaababbbabbbbbcbbabaaaaa##aaaaabbcc" "cddecccccdcaaaaaabbbbaaaabbbbaaaa########.####################..aaababaaacbba#abddbcdfeejmllf#aabbbaabbbbbbaaaaaaa#afffdedcbbbddffjfijjkkkhgfed####aba#######a####aaaa#aa#####a######a############adffddcaa#befefedeeddccccbcbaacbaabbaa###aba####a###############.###########.######aabcddcefbb###bbaaaaaabba#cffffghhgfffedccccccbcbbebbbbbbbaaaaaaaa####aaba#aaaabbbbbbcbaaaaabbcbaaaaaaaabcc" "dddddfebdfeba##aaaaaaabbbbabaaaa####.#########################.abbaaaaaaaaabbaaabba##aceeilmme#aaaaaaaabbbbaaaaabbbbbefgeddcddddegiighiiggjggfdba##aaaa##############ba#b###aaaa#######a##a#aaa####dfgffgcaabefeeededccccdddcbbbbbaaacbab###aaaaaa########a#a########.#########..####aaabdcdecbdc#aa###aabbcccaacegggfgghggfeeeddddcccbccbbbbaaaaaaaaaaba#aaaabaaaaaaaaaaaaaaaaaaabbaaaaabbabbbc" "bcdeeeeedeeda##aaaaaaaccbbaaaaaaa####..##.#########a##########aaaaaaaaaaaaababba#aa####abbdhkmgbbbaaaaabbabaaaaababbbaehfcdeeeegghkkjjigdeehfeccaaaabcba########a####aaa#####aa####a####aa###baba##adfgfffdeeffdcddddddbcccdccbbbbbbb##bdb###aadb#a##############.##.######.##########abcdcedecegdb#a#aaabbcddaa#adfghfghgffefeefeeddcccccbbcbaaaaaaaaaaa#aa###aaaaaa#aaaab##aaaabbbabaaaabaaabb" "cbceeeefffffd#aaaaaaaaaddbaaaaaaaa#############.#############cbbaabaaaaaaabaaaaaaaaa###aaa#achlkigdaabbabbbbaabcaacaababccdbbdedcdfehkkjgeceheccda#aabbba###.######a#aaa#####aa######.#a#aa##aa#aa##adgggfeeggffdcccddcccbbcbccbbbaaa####ca##abcba#aa##########.#####a######.#.#######abbcbddbdfhgeaaa##abbcdcaaa##aaceghdfgffffffeeddddcccbbbaaaaaaaaaaaa##aa#aaaaaaaaaaab##a#baabbabbbaaaababb" "ccddefgfefffd#a##aaaaaabccbabaabaaa##########...############acbaabaabaaaaaaa#aaa#aabaaaa#aaaabgkjiifbabbabbaaaabaaabbabaaaaaaabcc#####cgkmjgfhfcbcaaaabcbaa########a#aa###a###########.####a######aa##bghfefgeddeccbbbccccccbcdcaaa#a##a#aa#a#aaaacbaa##.############aa########.#######bbbccddddggfbaa###abbcbaaaa#aaabeeeeggghgggffeedcccbbbbbcbaaaaaaaaaa###aaaba#aaaabbaa#a#abbbbbbabdbbaaaab" "bcceddefhgfcbaa#a#aaa###aaabbbaaaaa#######################aababaaaaa#aaaaaaaaaaa#aaaaaaaa#aa###cefllgabaaaaabbbaaaaabaaabbabaaa#ba######bfjljhghcac##aaacaa########a###############aa#.##a#############afgfgfedcccccbbccccccddcccaa##a####aa#aaaaaabaa#################a#a##.#########aaabccccddeegfbaa###abbaaa#aaaaaabdfceghhhhhhgfedddcbbbbbbbbaaaaaaaaaa###a##aaaaaaabbbaaacbbabbbbbcccdaaaa" "bbcccdefhiea###a##aaa######aaaa#aacb##############a####aaabcbbabbaaaaabaaaaaaaaa##a#aaabaaaaaaaaabekljbaaabbaabaabaaaaaaaabbaaaa#a#aa#####aekkhhiba###aabbbb#####a.#########a#a#####a#######aa####.#aba##gggfeedccbbbbbbcbaabccbcbaa##a###aa##abaaa#aa###..###########.###a##.#######aaaabbbcdddcefgaaaaa##abaabaaaabbaabdeffghighhgfffeeccbababbbbbaaaaa#aaaa#a####aaaaaabbaabbbbbbbcccbcccdbaa" "bcccccdefgeaaaaaaaaa#a#a#a##aaa#a#aba#######a#.###aa######bcaaaaaaaaaaabaaaaaaaa###aaaaaabbaa#aaabbchkkc#aaaaaaaaaaaaaaaaaaaaa#a#aaa#a#######dkklibca#aaabcdca#a#aa#################a######aaaa######aab#cghhgfddcbbbbaabaaaaabbca##a##abaaa##abaaba#a#aa############...##.###.#..####aaacbbcdccdcdedbaaa#a#acbaaa#aaaaaaabcffffghhhfggfeddbcbbbaaaabbaaaaaaaaaaa#aa#aa#aaabbbcccbbbbbbbbbbcdccb" "bbbccccdfcec##aaaaaa####a####aa#aa#aca##a####baa#######a##bbbaaaaaaaabbbbbaaaa#aaaa##aaaaabbba#aaaaaadijgaabaabbaaaaaa###aaaaaaaaaaaaaa#######behlidcdbaaabbcecaa######a###aaa###########a####a#######aaacghihgfedcbaaaaaaaaaababbbaa###aaa####a#aba##a#a#####..######......#...#.#.####aaccbcccdcdehhdaa####bcba###aaaaaaabaaadfeeegihgecdedcbcbaaaabbaaabaaaaaaa##aaaa#aaabcbbbccbbbbbbbbbcbbb" "babbcdddddde######aaa###########aaaabda##a####abaaa#####abbaaaaaaaaaaaaaaabbbaaa#aa##aaaaaaaaabaaaaaabcdkib#aaaabbaaaaaa####aaaaa#aaaaaa##a##a##acgjhfgefcbbacccbaa####a######aaaa########a#############bfffhjigedddbaaaaaabaabbbbccaa####aa###a##aa#################a##.....#..#########aabbbbcccddfheaaa####bba####abba#aaaa##bca.#bghfedecbccbbbaaaaaabaaaaaaaaa#a#aaaaabbbbbbbbbbbbbbbbbbaba" "bbabbdcdddcec#####aaaa#a####a###abaaaaaa##bda##aaa######aaaaa#######aabbbaaaaaa##a##aa#a#aaaaaaaabaabacbdjjbaaaaaabaaaaaa##########a#aa##aaa##a#a##cfhhededabbdcbcca##########aaaaa############a######a##dffgjiiheedcbaa###bbaabbbddba#########aaa####################a###..###..##..###aaaabbbbcbcfffebaaaa#aabaa##a#aaaaaaa#####aa#.bdegfeccbbaabbaaaaaaaaaaaaaa#aaaaaaaababccbcbaabbbbbbcbbab" "dbbbbcdcdcdcea###a####a#aab#aaaa##aaaaaaa##a####aaa###.##aa###########aaaabaa#aaaaaaaaaaaaa#aaaaaaabbaabbbhkfcaaaaabbaaaaa##########aaa###aaba######.ekjgddbabbaabccbba########aaa####.#######aa##aaa#####dgfgghgggedcbbaaa#aabbbcbedba#######aaa#a####################aa#.......##..####aabbbbcbcdefeebb#aaa#aaa##ab###aaa#######a###.##cgefdccbbabbbaaaaaaa#aaaa#a#aaaabbccbbcbbbaabbbbcbccbbb" "bcabbcceffabbc########aaa#aaaaaaba#aaaaaaaa########.#####aa######aa####aabbbaaaaaaa##aaaaaa###aa#aa#aaaaabbfkjhdaaaabaaa#aa##aa#####aa#a#a#aaaa######aikjjhbaaabbaacbaaa###############.###################bfhggggggfedcabaaaaabbcdeccaa########aa##########aa######a#a##a##..#.#...#####aabbbbbcccecdgccb##a####a##a############aaa######agfedccccbbaaaababaaaaaaa####aabbaaaaabbababbbccccbbcb" "ababbccdffdbbbba###aa#aaaaaaa#baaaaaaaaaaaa#########.####ab###########aaaaaaabcbbbaa###aaaa#ba###aaa###abbbbflljeaaaaaaaaa###########aa##aaaaa#######.afikkiba#abbaaba##########a############################ehffgggfeedcccbaabababcccbaa######aa##aa###.###aa####...#########...########abbbbcbbbcdecfgdaa#######################aa##a####bfeeddccbbbbbaaaaaabaaa#abaaaaaaaaabaaaabbbbbbccccccc" "adbbbbcdddecbaba#a#######a#a##aaaaaaaaa#aa##########.###aac##########a##aa#aaaabcbbaaaa##aaa####aa#aaba#abbbbdillhcaaaaa####aa####aa#aaaa##aa#########.#chkli#aaaaabbaaa########a#aa###a###############.###aa#fggffgffedeecbbbaaabbbbcbaaa#####aa###a############################.######aababbcbbbccedcfccaaaaaaaa###############.####a#####bffeddccbbaaaaaaaabaaa###aabaaaaaaaaaaababbbbbbbcccc" "ccbbccddeeeccaaca##a####aaaaaa##aaaaa#a#aaaa#########.###ab####.#a###aaa##aaa#aaaabbaaaaaaaaaaba#abaaaaaaaaaaachkklfbaaaa##########a##abaaa############..#bimiaaaaaabaaba##########aa#babaa##############.##a##aegfcbdeedfedbbbabbabbcbbbaa#####a#####aa######################.#########aabbbbbcbbacddddccaaa#aaaaaa###a#####################afgeecdccbaaaaaaa#abccbaaaaaaa#aaaaaaaaaaaabbbccbcc" "ccedcdddeeeccbbbcba#a###aaa#a#a#aaa#####aa#a#############ab#####.#####aa#a#aabaaaabbbbabbba##aa###acb#aaaaaaaaacfihkida##a#a###.####aaaaaaaa##a###aa######.ahljc#abaaaaaaa###.####a######abaaa############.#####.bababeedegdcbccbcbabaaabba#a##aa####aba#aba#a###################.####a##ababbbcbbbcdddedea#aaa#a####aa#######.###.######a##a##fgfedddbbaaaa#bcdccbbba####aaaaaaaabbabbbbbbbcbbc" "cddeddddeefddcbbcc#a#aa#aaaaaaa#aaaa####aaa######aa######ab#a########aa#a#aaaaaaaaaaabbaabba#aab###abb######aaabbcfheihc######a#####aa#aaaaaaa####aaaaaa###.aikjcaaaaaaaa#################aaccbaa#a################aaaaaaabdddcbccbaaaaaaaaaaa##b####abbcccb##.###a#############..###aaaaaabbbbbccbbccccddecaaa#aaaa###a########################effedccaabbaccbbaaaacc####a#aaaa#aabbbbbbbbbbbcc" "dcdcdcdeddfecdcbcdaa#aaa##a###a###aa##############aaaa###aba#############aaaabaaabaaaabbabbaaa#aba####a##a###aaabccefadhhb##aaa#####aaaaa#aa#a##aaa#aaa#####.aflkcaaaabaa####################ddcbaaa#################a#aaa#bdddbbcbaaaabaaaaaaa#a####a#baa####a###a###aa#############aaaabccccbcccbbcdcdedefb##a###aa##aa###############a##aa####efddcbcecbccabbaa#aacc###a##aa#aaaabbababbbbccc" "ccdddcbcfhfddcdcbbc#####a#aaa##a########a#a#aaa#####aaa##abaaa##.#######aabbaabbaaaaaaaababbaaa#aaaaa###a#a#a#aaabccdha#diga##aba#####ca##aa####aaaaa#a#######acildaababbaa###########a#######abccbaa#########.#########a###cdedbbdcbbabba#aaa###a####aaaa#aab###a##a#aa######aaa######aabbccccccccccddddeddfca#aa##aaa#aaa#####a####.###aa#a##a#cfeddedacaaabcaa###aacc###########aaaaaabbbbbcc" "ccccddccdeffdcccdccb########aa##########a#aaabaa#####aa##ab#aa###########aaaaaaababaaaaaaaabaabcabba############aaabcffb.afjfa#aba####a#a########a#a########aa#abhjb#aaaba#a##########a#######aabcccbb####.#..###aba#########abddbcecbbcbba#aaa########aaaa#a#a###aaa########aaaaa#####aabccdcddccccccccddedcec###ba#a####a#a##########.######aa#adedcbbaabaaabbaa###aabca##aaa#a##aaaaaaabbbbbc" "cccccdcedcddfebbdcbdb#######################abcbba#######bbaa######.######aaaaaabbabaaaa##aaabababaaaaa########aaaabbcfiea#bgjeaaa######aa#a#############a####a#acgigaaabb##########.##a#######aaa#adcba##########ba#a#a#####a#adfcddbcccbaa#aaa######aaaaaa##aa#aabbab#aa####aaaa#####aaabbccdddcdcbbbbcccddegd##baaaaa#########a################abbcccbbbbabbbba#####abca##aaa####aa#aaabbbbbb" "bbbccddcdcddefdbcdadcaaa#####################aabbbba#a#aabba#aa##########aaaaaabbaaaaaaaaa#a#aaabbbbbaaaa###a#aaaaaaaabfifa##ejgbaaa########a##################acbcfigba#aa###########a#########a#aaabbbba#######.#a#a#######aaaaffddccbccba##aaa##########a######aabaaa#.####aa######aaabbbccdeeefggecdedcdfedcbaacbaaaa##a#a####a############a##aa#accdcbcbbbbbba#####aaca#aaaaaaa###a#aaabaab" "bbbbcccccddddfecbccbdc#a############a###aaaa#aaa#aa##aabcccc###########aa#aaaaaabaaaaaaaaaa#aaa#aaabbbbbbaa###a#aabaaabbbhie#.bfhfbaaaa###aaaaaaaaa#######a####aaabdhifbaa########aabaa###a######aa#####bccaa#####.#####a########afgeddccdcba###aa########a#a#######aa######.##########aabcbcccdffghihgdcddcbacbbeabaaaaaa#a###################a##aaaa#bcddcdcbbbab##a##aaaba#aabcaa####a#aaaaba" "bbbbbbcccccdefedbbcacdc####aa##a#.##a#.##abb######a##aabbccc###########aa#aaaabbbbaaabaaaaaaaaaaaaaaabbbccbaa##aaabaabba##diic##adhebaaaa#aaa#aa##aa##########aabaaagjjf#a######a#aaaaaaa#a#######aa#a###bdddaa#a###.#a###########adcdddddcba#aaaaa#a###a##a##ba#b###aa####.###aa#####a#abcdcbbcdghihhgdcaaaaaabcfdccaaaaa#aa###################a##a#a##acbcdcbbcba#a#####aaba##abaaaa###aaaaaaa" "aaaaabbbbbcddeedccebaccb###a####a####a#..aba##########aaaaccb.############aaaabbaabbaabbaaaaaaaaaa#baaaccbbaaaa#aaaaaaaa####fjfb###egebaabcb##aaa##############aaa#achkjbaa######aaaaaba#a#aa###a###########abba###################abaceddcbaaaaaaaa#####a#####a####a##a######.###a##abaaccddedeeffdghfaaaaaaaabbdfcabbaaaaa###############.#########a###bccbedcbdaa######a#abaaaba########a#aaa" "#a#aaaabbbbbbcdedcccbabbb##aa######.######ba#############abcc##############aaaaababaaaaabbaaaaaaaaaaaaabbcbbccba#aaaaaaaaaaa#beihb##afgdbbcba#aaaaa######a######aa#abcilheba#####aaaaabaaaaaa#########a####a##a#aaa###############a#aaadedbbaaaaaaaaa##aa##a#######a##aab######.##aaaababceefcddcb#.#gfaaa#aaaaabcfgcaaaaaba########.#####################aabddcbcabaa##a##aaabaaaa######a######" "##a#aaaabbaabbccdcbcbbbacb###a###########.aba#######aa###aacf#######.#######aaaaaabcaaa#acaabbaaaaaaaaabababbbcdcbaabba#abaaaaabfje#a#aehdaaaaaaaaba#####ab#a####aabaabijiebaa##aaaaaabaaaba##aa#####a#a###########a###a###########aaaaaabbbaaaaaabaaa#aaaaa#####a##abaaaaaa########abbabcdgeba##.##.bdaaa#a#aaaacfgcaaaaaa########.a########.#######a#aa###abccbbbaaaa#aa#abbab#abaa####aa#####" "#####aaabbaaaabcbccccbbbcca###a############a#########aa##aaacb###.#.########aaaaaaaaabcbaaabaaaaaaaabaaaaaaaaaabcaaaaabaaaaabaabaejhbaa#aggcaaaaaaaaa####abb#a###aa##aabhigddbababba#acbabaaa###aa####a#c#a#############a#a########aaaaaaaabbaaaaaaaaaa#aa##a#####aaaaaa###aaa######aabbabege##b#######aa#a##aaaaaceecbaaa############################aaaa##aaacbbbaaa##aaa#aaaaa##aa#####a#####" "####aaaaaaaabbabbdcbcdccbbba#aa####a##a####a######..##aaaaabab###.###########aaaaaaabbbbbbaaaaa#aaaabcbaabaaabbaaaaaaabbaaabbabab#bghcaba#dhfaabaaaaaa#aa###aa##aaaaaaaabeegbccbaaabcbbbaababa######aa#aaaaa##aa#.######aaa#########b#aaaaaabaaaaaaaaaaa#a##aa#aaa#aaabbab##a####ab#aabbbbcfhaaca##############abbabddbbaa####################.###a##a#aaaaa#aabbbbbaaaaaa###aaaaaaaa#######a###" "#####aaaaaabbbbbccdbccdcbcca##########a#####aa##a######a#aaaabc###############aaacaabbabbbbbaaaaaaabccbbaaaaaaababcaa#bbaaaaaaaa#ba#eiebabaafhb#aaa###a#a####aaabbaa#baabbbigcebaaabcbbcdbbbcca#a##a###acbbaa#ab##########aaaa########aababbbaaaaabaaaaa##a###a#aa###aaaca##a#aa.bc#abbdccbdga#####.###########abbbbcdebaa##a##a##########a####.###a#aa###aaa##aabbabbba#a#####aaaaaa########aa#" "#####bbbabbbabbcddddcccbbbcca#a##aa###a#################aaaaabb#a####.########aaaacaaaaaacaaaaabcaaabbcdcbbbcbabbbabbaaaaaaaaa####aa#cijdbababhfa#aa###aa##a##a#aaaaa#aabbbflggfaabacbaabbbaacbba##aa#abccbbaa###aaa#####a#aaaba###a#aaaaabbacbaaaaaaaaaaaa###aaaaaaaaaacaaaa#bbab#abbcccccbdc#################aabdceedebaa#########################b#####aa#####bbbabbaa#a####a#aa##ba########a" "aa##aaabbbbccbbcccddcdccabbdfa####a###########aa######a#a#aacc#######.#########aaabababbaaaabbaaaaaaaabbbbaaaaaaabaabbbaaabaaaaacba#a#beijbaaaaehfa###########aa#abaaaabbbbdhjghffedccaaabaabaabbaaaacbcbcccbaa#aaaaaaaa#aaaaaaaa####aaaabbaadebbaaaaaaaaaaa###aaabaa#a#aaaaabbbbbbbabcdcccefe####.##.#######.##a#aacccccaa#aa#####.###############aaa###.#a###a##bbbbbaa#a########aaaaa##a#####" "###ab#ababbccbcbccdddccccbbbeda##aaa######aa###abaa####a###abdb#a###.######aaa#aaabbbaaaaaa#abbbaa#aaaaabdaabbcbabb#aaaaaaaabaaacbcba####ejdbbbacgjd##aa#aa#####aaabbaabaabbejiiiihhggfbaabbbaabcba#bcdcdddddcaabbbbcbaaaaabaaaaaaa##aaabbbbcdedbcbaaaaabbaa#aa#aabbaaaaaaabccbbbbbcdccddffebb####################aabccccca###########.#########a####aaa####a##aa#abbaaaaaa########aaa####a#####" "#aaaaabbbabbcccccdedccccedccdebabaa#aa###########baa##.##aaa#aca#######.#####aaa#aaabaaaaaabaaaacbaaaaaaabaaaabcbaabaa##aaabaaaaabaaaa###.cjgcbbbadiib##aaaaa####aaabbaaaaabdhlijjiiihfefcbaabbbbbbababdedfddedccbccdccbccdccccbaa#aaaaababcccdddcccbaaabbaaba#aaaabbaabbaccdddcdefffedeeed..################.######abcbdfbab#a###########################a#a#####aaaaaaaa##aaaa######a##.#a####" "###aaaaabcbabccccdcddcccccbbccebaaaa##############a#a####aaa##abb##############aabaaababaaabaaaabbaaaaaaaaaaaaaabbcbabbaabaaaaaaaaaaaa####.afhdbbaabfihb.#aa###aa###aaba#aaacclljjiijigddecbaabccbabbbdbadcbeffffeffgghhhighgfhgffcaaababdbbbbcfddddcbbbbbccabaaaaaaababddehggfegjiedaaaa#a####a##############.######bcdcddbaaa##a###################a#a#####aa####aaaa#aaa#a########a#######aaa" "aa##aaaabaaabbbdddccdbcddcccccdd##a#aa##aa########a######aaba###ab##############abaaaaacbaaaabaaaaaaaaaaaaaabbaabbaccbaaaaaaaaaaaaaa#########bfgbaabbdije.######aa#abbaaaaaaabellkkkkllkiiigfdcdcbabbcbcdcbcgijkjhhhhijjic#dcbcbddghffeeeihiggfgddedcccbcdcdcbcbcbabadeeffghhhebegdddb#########a#a####################babbbcbbb##a##################aa##a####aa#a###aa#a#aaa##a#######aaaaa##aa#" "a#aaaaabaaaaaabcdcceccefcadgeceebba###a#aaa########a#####aabaa#aabda########a####aaaaaaabbaaaabaaaaaabbaaaabbbbaaaaaabbcbaaaabaaaaaaa#aa######.eiebbbbcfihc#.###abaaa#aa##aaaabellkjlkjklmnnmlkgfccbbdddeefghjijkkllkhd#cfeabcbbcbbdgjjhgecccehieeededccceeedddddefcdffcedbacdec#bbaba#########aaaba#########.#######aaaacccdbbaa####################aa##a####aaaaa#aaaaa#a####aa######aa#aa##aa" "a#aaaabaaaaaaaabcccdddggedbdfccecaaa###aaba#a#######aa#.##aabba#aabc###########aaaaabcbaaaabaabaabbbabaaaaaabbcccaaaabbbbbbaaabaaaaaa#aa#aba###.bigbbbccdilid.##aaaaaa####aabbbcekmljgdfiijikmlmnkgdeefeeegieeddgdcghgdbabcfdebcccceffggfcbbbbbcefgedddcceeefdedcbccefgb####babedcaa##aa#######aabcda##.#############aaaaabcdcdbaa#########a########a###a###aabbbbaa#aa#aaaaa##aa######aaa##aaa#" "##aaaaabbaaaaaaabcdceeffedccfgedcaaa##aaaa###a#a#####aa..##abaaaabbd#########aaaaa#a#bbbbbbaaaaaaabbbbbaaaaaabccbbaaabaabbbbab#aaaaaaaaa#aaaaa###ahibbcdccgjkg####a#aa####aabbcddegkhddgihhghiibdilmljjjjiiihfaaa##aeeedcbbdghfdbbdfedfedccbbbbdbffhfededeefhhfc#####cea#####aaabdfda.a######.##abdfb##########.###a##aaaabadefecb#a##########aaa####a##aa####acbbbaa##aaaaaaaaaaa#####a######a#" "a##aaaaaabaaaaaabacddeddfdccefffd#aaaaabbaa#a#####a#.aaa###aaaa#abbdb########aaaaba#aaaaababbaabbbbbbbbbaaaaaaa#abcbaaababbbbcb#aa#abaaa###########fhdcccdcehihb###aa######a#bccdefggiglkjjhiihba#cglkjhiihgebcaaaaaa#aacdbbdefhfdbbeedbccbbbabdcbgjifefedeggfgfa#aa#a.aa######aaaacffba####.###abdeca######a###########aabbegffgedaaa##########aa####a##aaa#####aaaab#aaa##aaa#aa######a#######" "##aaaaa#aaaaaaaaabbcdddceddeeecdfbaaaaabbbaa#####ab#########aaaaaabbc########aababbaaaaaaaabbbaaaabcbbabbaaabaaaaaaabbbbaaabaabbbcaaaaaaa##########.bhfcccdddefigc#abaa#aaaaaacccdegeiihkihhjhbbaa#.#a##a#..##aaaaaaaaaaaacaabaacefedefbbedcbaccdbcfgiihhfdec.addb#ba###aa######aaaaadgeca#######aceaaa#################aaabdgeeghffb########a######aa####abaa#####a#aaaaaaa#aa###a#.######aaaa#" "a##a####aa#aaaaaaabccbccdedefebbef#baaaaaabaa#####a#aaa####aaa##aaaada########aaabbbaaaaabbaaaaccbbcabbbbaaaabaaaaaaaabbbbabbbbaabcb#a##a#########a##bifdccdddefgjeaaabaaaa##accbbcddfhehijhdb#aaaaa#a####a#abaa#aa##aa#aaaaaabbbaabefigffefdbcccdcbaacbbdhhfeaacbabb##a##########aaaaadhgb#####aabecaa########a###########baegfefgfeca##a#######a##aaaaa#aaaaa####aa#aabbaa#aaa###a#.#####a#aaa" "#aa#####a#a#aaaaaaacccbbccdcdedbcfcaaabbbaaaaa####a###a###abdb####aaeda######a#aa#aabbbabbaaaaacddbaaaaabaaaaaaabcbaabbbaabbbbbbababa####aa###aaa#####dihecccdedeejgaabcbaaaaabcbbbcdeheggeabaaa####aa########aa###aaaaaaaaaaaaaaccbaabdegedddddddccbbbba#abaabcbbaaaa##a##.#.#####a#a#abefb#####abdfaaa#####aaaa#a########aaadfeeffffc#######a######aa#aaaaaaa#aa##aa#aaabaaaaaa#######.###a#aa" "aaaaaa#aaaaaabaaaaabbcbbabbbcceedffdbaabcaaaa##abaa##aa###acefa####abdaa###.####a##aabbbcbcbaaaaabba##aaabaaaabaabbbaabbbaabbbbabbcbba#a##aa###aaa#####bhjgccdddefdhheabbaaababcbbabcdehfcaaaaaaaaa#aaaa#######aa###a##aaaaaabcdaabbbbabbbefedeccddcbbbaababbbcccca#a####aa#############aaceda###aabfebaa####aaaaa##########aaadefedegca########aaa##aaa#aaaaaaa##aaa##aaaaaaa#bcba#########aa##" "#aaa#aaa#aaaababcbbbbccbaaabbbbdgffgbaabbbaaaa#aaa####a##abbgea##aa##bca#########a#a#bcbabbbbaaaaaaaa##aabaababbbaabaabbbbbbbbbaaaabbaa##a#####aaa######adhidddddfhdfigbcba#aaaaaaaacbcfdabaaaaaa#aaaaaaa#######bb#####aaa##aabccaaabdcaaaeeefeddefcbbbbaaaabcbbbcdba#####a####..#######a##abdb#aabcefdaa####a#aaaaa#######aaaaaabacefc#########a###aaaaaa##aaaaaaaaaaaaabaaaa##aaaa###.#####aa#" "#############aabaaaabcbbaaaabbcceeeeeaaabbaa##a###ab#####abddb#####a##cb#######aa#a##aabbbbbbbaaaaabaaa##bbabbbaaabaabbbacbcbbbcbbbbaaa###a######aa##a#baaagkecdeegfeehfcbba##aaaaaaaaccdcbaccbaaaa#aaa##aaa#########a##a###aaabcaaaadeddbbdcdeigfdbcccbaa##cbabcbcdaaa####aaa######.######aa#debaacfdcaa#####aaaabaa########a##aabccdd#############aaaaaaa###aaaaaaaaaaaaaa###aaaaaa#########aa" "#############aabbbcbbccbaaaabbccddeedca#abaaa#aa###a##.##aaaa#######aaaca############aaaaaabaabaaaaaa##a#aaaaabbaaaaabbbabbbcbbccbccbaba##########a##aaabaabejfddddehddhgdbbba##aaaaabbbcccaabaaaaa#a#a##a#aaa###############aabcaaaaaegeddcecacdghfdccbaaa#cbabcbac#######bba#################bcdcbeebaaa###aaaa#aa#a###a####abaabdcdcba#a##a####aa###aaaaa##aaaa#aaaaaaaaaaa#aaa##aa#########a" "aca##########a#aaabdbcccbaaaabbccddeedbaaaaaa#aa#########abca#######a#aca############aaaaaaaaaaaaaaaaaaaaaaaaabbabaabbbbbabbbcbbbbcabbbba##########aa###aabbbeidbbccehefhhcbbaaa#aaabbaaabbcaaa#abcaaaaaaaaaaaaa#####.########aaabaacbedfdbbbdccccfhebaabaaa##a#acaba######daa###.######a####aa##acfdfdaa####aaaaaaaa###aca#aaaabaabccdeaaa###aa#aaaa##a#aaaaaa#abaaaaaaaabaaa##############.aab" "aa#bb#####.######aaabcccbbaaaabbbcddeebaaaa########.#####abca##########abaa####a#####aaaaaaaaaaaaaa#aaaaaaaaabcbbaaaaaaaabbbbbbbbbccabbaa#a#########a#####aaaachdbccdefehgiebbbaaaaabaaabccacbaaaacbaaaaaaa#aaaaaa#############a#baaaaceddbaabcbebbefdcaaaaa###ba#baa#####.aba##############a#a##aacfghdcaaaa#abaaaaaa######acbababbbdbaa###aaa#aaaa#a#aa#aa#aa##abaaaaaaabaaaaa##############ba" "a#aa#a#####.###a#aaabbcccbbbaabbbccccge#aa#######.#######abbba#######aaabbaa####bba###aaaaaaaaaaaaa#######aaaaabbbbabaabbaabbbbcbbbcbabbbaaa#a##a##########aaaabeccccddfgefhgaccaa#abbabbbbabbbba#aa#aaaaaaaaaaaaa#######a#####aaaaaabacdccabbbcecaacdfecbbaaaa#aaabaaa#####aa########aaab####a###aabeggbaaaaaaaaaaaaa#a##a###aaaabcccccaa###aaaaaaa#aa#aaaaaaaa#abaaaabaaaaaaa#a###########a#aa" "###aaaa###a######aaaacccbbbbbbbabccccehb#a########..#####abbca#######aaaacaa####cca###aaaaaaaaaaaaa#######aaaabaaaacdbaaabbbbbbbaabbbbcbccaa############a#aaaaabaccbdccegeccffbbaa######.#abaabbbaaaaaaaa#aaa#aaaaaaa#a##########aaaabbcc#abbabaabaddcbceebbba#aaaaaba######a############aba###a##aaaccggbaaaaaaabaaaaabaaaaa#a#bbabbccdb#aa###aa#aa#aaa#a#aaabaaaaab###abbabaaa###a#a########aa" "###aa#a######.######aacccbbbbbabbbccccfheaaaa#############bbcaa#######aaabcaa#####aa####aaaaaabaaaaa#aaa##aaabaaaaaacdcbaabcbbcbbbabbaabbbbca#a######aaa##a##a#aaacabccdeggacge.#aa####a#baaaabbabaaaaababbaaaaaaaaaaaa#########aaaaaaabda#aaabbbacbcdbbcdeca#a#aaaaa#a#aa#aa#############aa#####a#aaabcfgcabaaaaabaaaa#aaa#####babbbcccc##aa#a#aa#aaaa###aa#aaaaaaaaaaa#aabbaaaa###a#a#####abba" "###aa##aa##########a#acbcccbbbbbbbbbcceffebaa#############accbaaa######a#bdcaaa####aa##aaaaaaaaabaaaaaaaa#abbbaaaababcddccbcccccbaabaaabbbbbca####a######aaaaa##a##bbabcbdgefeed########a#a###ab#aabbbaaaaaaaaaaabaaabba#####a#.#a##aaaabca##abbbaccbbdcbcdedb#aaaaabaaa###aaa#########aa#aaaaaaaaaaaaabceecc##aaaaaa#a#aa########abbacccc##aaa#aa##aaaa###aabaaaaabaaaaaaabaaaa####aa#####a#a#a" "b###aaaaa#######.##a##abbdcbaabbbbaabccdegea########a#####abcbba###aa####acccaa######a#####aaaacbbbabbccbbaaccaaaaabbbcccbcbccbbaaaababaaaaabc###a#aa#####a#aa#a#aabdaaacbbafhgbfa.#####aaaaaaaaa#aabaaaaaaaaaaaabbbaaba###a###########baba##aaaabacaabccbccdeeaaaa#aaab####.########.##aabbbaaaaaaaaaaabccaccba##abbaa###a##a###a#aabbccca#aaa#a#abaaaaaaaaacaaaa#aaaabbaaaaa#aaaa#a#######a##a" "baabaa#######aaa#####aabbccbbaaabbaaabccdfeba#######aaa###abcabbaa##aaa####ddbaa######a###aaaaaaaaaabbcbbbbbccaaaaaabbbbbcccccbbbaaaaaaaaaa#abca##a#aaaaaa##aaaaaaabcaaaabaabgicce##.#a##aa#a#aaaaabaccbaabaaaaaaaaabbbaaa#aabb##########aa#aaaaaaaaaaabccccddfebaaaaabbaa################bbbbbbaaaaaaaabbbc##acbbaaaaaa####a#####aabbbcccb###aaaaaabbaaaa#a##aa####aba#bbaaaaaaabaaa#######a##a" "baaaaa#######aa#######aabccbabaabbbaabbbcdgdb#a########a##abdbbaaaa##aaa##abdcbaa#############aaaabbbbbbbbbabccaaaaaaaacbbbcccbccccbbaaaaaaaabbca#aaa#a#aaaaaacbabaa#aaaaaccbbjgabc###bb######abaaabbcccbabbbaaaaaaaaaaaaa##aaaaaa#######aa###aabcbaaaabbbccdeeefebaccbbbbb#.####a####.###abaabbbbbcbaa#aaabca.##acccbaaaa########aaababbcba##abaaaaaaaaaaaaaaaa#aaa#baaababa#bbaaaaaaa#######aa" "aa##aaa###############a#abcbabbaaaabaabbbcffcaa##aa##aaaa#abbbbaaaaaaa##a##abdbaa##############aaaaabbaacbabbbcaaaaaaaabbbaaabacbccbbbaaa#aaa#aabb#aaaaaaaaaaabbbbaaaa##aabbbadiabbc.##c#######aaaaaabbccbbabbaaababaaaaaaaaaa##aa#######a#####aabbaaaabcbbbcddcefhgceeaabba##############abbbbbbcbaa###.###aca####aacdba#a#a######aaaabbcbbaa##aaaaaaaaaaaa#aaaaaaaaaaaaaa#bababaaaabaaaaaaa#ab" "cb####aa################abcbbbaaaaabbaabbbdgdb##a#aa#aaaaa#abaabaaa#bba####aaddba#######a#########a#abbaaccccccbaaaaabaabccbbabaabcbbbbaaa#aa###acda####aaaabaaabbcbbaaaaa#bcbcebbccd#.aba######aaa#a#acbaaabbbbbaaabbdbbca##ba###abc.#.####.##a#bbaaaaaaccccdecdefghgfccccb#.####.#...###aaaabbabddba###...##bb#####a#bcba##########aaabbccaa###aaaaaaaaaaaaa##a#aa#aaaaaaaa##ababbaabaaaaaaaab" "ec##########a##aa#.#####abbcbbaaa#aa#ababccfffcaaa#aabaaaaaabbaaaaa#aba###aabbfdaa###.#############a#aaabbccbbccaabbaabbbbbbbbabaaabbbbbaaa#a###aacdba##aa#abbacbbcbbbaabaaabbceabccde.#c#aa######aaa#aaa#aaababbabaabbdefecd#aaaaaaec#.#########aaaaaa#aacdcbdbabdfegddffdba##.#.###.###aabbbbabbccbba###.#.##bc#######abbba########aaabbbddcaa##aaa##aaaaaaaaaa#aaa#aaaa#aaaaaababaabbaaaa##ab" "bca######.#####aa#######abbbbac#a##aa##abcdcehfaaaabbbaa#abcbbbaaa#aaba#####acegdaa####.############aaaaabbbbccccbabababcbbbbbaabbcbbabaa##aaa###aacebba###bffcdbcbbcbbcaaaabbbhbabbcee.##aa##aaa#acaabbaaaaaaabccaaaaaabdefge##aaaacea###########a######abdfdabaaaaababaceeb###.#...#.##aaabbbabbbaabaaa###..##bea###a##a#aca#a#a#####aaababb####aaaa##aaaaaaaaaaaabaaaaa#aaaaaababaaaaaaa###ab" ".#a###########.b########aacaaaacaaaaaaa##acdffgbaaabaaa##aaehdbaaaa#aaaa#####acfgbaa#########.########aaaabbabcdecbaabbabbbbbbbaaababaaaa######a##aaddbaaaaab##a##abccccccbbaabfhaababgd.######aa#aaaaaaaaaaaaabacdddbaaaaaaddeda#aa#ba######..##a########abdcaaaaababcabbbcddb#a###..#.##aaabccbbaaaaa#########abed#########cb#a#a####a#aaaaacb###a#aaa##aaaaaaaaaaaabaa#aaaaabaaaababaaa######" "#########aaa###a########abbaaaaaaa#a#aaaaaacdegeaabaaccbaa#acefcaa###aabba###aadfdbbaa####.#############ababaaabcccaaaaabbbbbbbabaaabbbbaaa#####aaaabdeaabbba########aabdedcbabbffaababhd########a#aaaaaaaaaaaaaaacedbabaaba#bfggcaaa#########..#.########aabcb#aaaaaabaababccddba#..##.####aaabbaaaaaa##...#####acecb########abba#aa#a#aaaaabbca##aa#aa#aabbaaaaaaaaaaaaaaaaaaabaaaaaabaaa#aa##" "##########aa###a#####aaaaaaa##aaaacc#a###aabbcefbabbcfcddddbabgfa#a#aaaadbaa##abdedcaaaaaa#############a#aaaabbbbaacbbabbaabbaaababbaabababa##a##aaaaaccbbbb########.###abbacdcccgbabbbcida####aa#a#baaaaaaaa##aaabccaaaaaacbbabggb#a#####aa##..##aa######aabbcbaaaaaaaba#aabbcccca#.########aaaaaaaaa###...#######abdec########abb#aaaaaaaaaaabcbaaa#####aabbbb#aaaaaa#abba#aaaaaabaaaaaaaaabb#" "###########aaaaba###aaaaaa####aaabdebca###aabbcfgfbacdccdeheaadgea###a##dcabaaaabdedcbaa##################aaaaabbbccbaabcbaabbbbabbabbbaaabaa#####aa#abddbcb##a########a##.##accdeedbcccejcbaa####aaaaaa#a#aaaa###aabbbbaa#bdbb#chfa####a########.###########babbaaaaaabaa#aaaaabbcdc#..######aa#aaaaaa###.#..#####a#abdeba#######bbbbaaa#aaaaaabcca#aaaa#aaaabbbaabaaaaaaaba#aa#bbaabbaaaa#####" "######a##a###a#aaaaa#aabaaa##aaacddbbcaa##aaaabdifdadeeddfffaabdddbaaaaabd#aaaaaacfedcaa#################aa###aaaacccbbabbbbaaabbbbbbbbbaaaaa######a#aaacdddaaa#########a######aabbicceedghcbb##aa#aaaaaa#aaa#a####aaabbaa#adffbafgd####aa###################aaaaaaaaaaaaa#ababaaabbbcb#.####aaaa#a#a#a##..########a#aabbcdd#.###a##bbaaaaaaaaabbbbba######aaaacbb#abaaabaa#a#aaaabaabbbabaa####" "######aaaaa####aaaaba#abaaa###a#bddccaaa######abcfgghhhfdfffcacbabdecca#bca#aba##aeffeba##############.########aaaaccbbbabcbbbaaaababbbbbbbaaaa######aaaabeeaa#aaa######a###a#aaaabfgdbbddhhccb###aaaaaabaaa###aa##aaaaaaaa#bffgd#cda##a#a######a#a###########aaaa#aaaaabb#abaaaa#aaaabbca####aa#aaaa####.#############aaabcdc#####a#abba###aaabababc#aaa##aaabcaaaaabaaaaaaacaaaabaabbbbbaaa###" "a######aaaa##a#aabbaaaaacba##a##acccddbaa#a##aaaaacccdefefefdacaaaacgebcdb#a##aacbbegfdba#aba##############aa###aaabcdbccbbabcbbbbbbbaabbabaaa###a###aaaabcdb#baa#a###########aaabddgcdcbbcfidbcb#aaaaabaaa#a#a#abaa###a#aa##dfffeaa#####a#####aa##b.######.###aaaaaaaaaacbacaabaaaa#aaaacccaa####################a########abceca###aa#abaa#aaabaaaacda#aa###aacaaaaaabaaa#aaabaaaacbbbbacaaaaaa" "aa##a###aaaa#a##aaaaabbbbbbba####bbbacbaaaa##aaaaaabccbdedcefaccaaa#accccaa##aaabcddfgefeeffea################aaaaaabbcbcbbcbabbbaabbaacaaaa#a#######a#aaaacfcaaa##a############aacdee#a####eifccc#aaa#ccaa###aaa#ba###a###a#befffd######aaab###aa############aaaaaaaaaabbcbcdbbaa###abbaaabccdca...#######aa#a####a######aaaabcdc######aaaaaaaaaaabbcdbaaa##aababaa##aabaaaaaabaa#abbbbaaba#aaa" "#aaaaa##a#.###a#aaaaaceccbbbab##aaaaaaaaaba#aaaa#aaabccbcdddgfdaaaa######aa##a#aaaeggihgeefeddeca###############aaaaababcbbbbaabaaaaabacbaaa##a#####ba#aaabadgeaa#a##a####a##a##aabbeeaa#####bhibaca##aadbaaaaaca###########aadfddfda###abaabb#aaba#####a######baa#aaaa#abdc#bccbaaaa###ba#aaabdfeec#########aa#aaaa####aa#aaaaabde###a###aaaaba#aaaabbccbaaaaaaaaaa#a#aaabaaabbaaaababbbbaabaaa" "##aa####a#####aaaaabcccbbbcbbaa##aaaaaaaaabb#baa##aaabbcccdefgiecbaaa##aabba###a#affghihfccdddddeca################aaabaaaabaaaaaaaaa#aaaabaa########aaaabaabcgcaaaadda#aa#######aacdde#######aegbbdbaa#adbbaabcaa#aa#########acfeeecaaaaaaaabbaaaba###########aaaaaaaaabddfbaaababaaaaaaa##aba#acefgca###aa#####abb######aaaaaaabcfa##a###aaaabdaaaabbbbdb###aa#aaaaaaaaaabcbbbbbbabaabbbbbbaa#" "####aaaa#a#####aaabccccbaabcbcca##aaababbabbabaaaaaabcccbacddefffdccabccdedaaaabdeeffgggeccddccdcdca#a##############aaacaaaabaabaaaaaaaaaaaaaaaa###aa###aaaaacdgcaaabaaa#######a##abdchaa######.cfcbcb#a.bffcbbbab###aaaa###a###ceedddabcbaaaabbabbaaaa##..#####aa##aaaa#acecbbcbaaaaabaaaa##aba#aecbccdcabaaa##abbaa#a##aaaa##aaaabdd##aa##aaa#aaababbbbbdb#a##aabaaaaaaaaaaaaabbbbbbcbbbbcbbaa" "aaabaaaa####aaaacccbbcbbbaaaabdaaaaabcaabcbbbbbaa##abcddcbcdefedffedbdccdeec#aafffdddeffcccbcdcccccccaa#############aaaab##aacaaaaaaaaaaaaaaaaaaa###aba#aaababdefaaaaaaa##a###aaaaabccgcaa#######bgcdeca##bhgbabaac##a#aaa##a###befddfdddbddbaacabbbbaa####.#######a#aaaaaacbaabbbaa##ababa##aa##acaaaabbcb#aa#a#aaa##aa#####a#a#aaaabeca#aaaaaaaaabaabbbbbdb#aaa#abaaaaaaaaaaaaaaaaaabcbaababaa" "aaaaaa#aa#####abbbcbbabcccbbaaabbccccdbabccbbbbbaaabbcddcbceeeddeggddfbcdeec###dffedddeddcccedccccbbcdb#################aa#aaabaaaa#baabaaa#aaa######aaaaaaaabbcdfaaaaaaa#a####a#aaaabge##########bhcbccaabdeeaaaa###a###aaaaaabceedefeeedeeccabbabcbbaaaaa##.#.#######aaaabbb#aaaaaaaaaabaa##a##aaa#acbcabca###aa####aa#########a##aaaedb#abaaaaaaabbabababccb#aaaaba#aaaaaaaaaaaaaaaaabbbbbaaa" "aaabaaaaaa###aaabbbbbaaaacbbbbbcccddefdaabbbbccbbbbabbccbcdddddeeeffefcedffedbabeeecddcbcccbdbbbabbbabba#aaaaa##a######aa#a##aaaaa#a##aaaaaaaaa###aa##aa###aaabbdedaaaaab#a####aaaaabbgha#a########becaccdfgddda#aa#aaaabaaa#a#addeecdcdfeeeddcacbbbcbbaaaaaa###########aabacbaaaaabaaba#baba#aa##bbbdbacaabcb##aaaaaaaaaa#########a#aaabddbaaaaababbbbbaaabcccbabaaaabaaaaaaaaaabaaabaaaabbbbaa" "abbabbaaaaaaaaaaaabbabaaaaabbcbbcdedfggccbaaabbbbccccbccddeddccdddcddecddeffddecddccacbaacbbbbaabaabaaaaaaaaaaaaaba####a###ba#ba#aa#####aa#aaaaa############aabbcdebbbaaaa########ababdhf#a#########afecfffebceaa###aaa#aaaaa##abeeddddeegffdcfdbbabcccbaaaaba###########aaaabaaaabbaaabbbaabbaaaaacdcaacaaaabca##aaa#aa#aa#aa#######aaaaacee#bbaababbbbbbbbbccdcaaaabbaaaabbbaaaaaaaaaabaaaaaab" "babbaaabaaa#aaa#aaaaaaaaaaaabbbbcdbadccdbbbaabbbbbcbbccdeeedeabcccccccccdeedfddcccdbcbaaaaaaabbbaaaaaaaaaccaaa#aa##aaaabbaab#a####aa####aa##aaa###############abcdedbcba#####aaaa#aabbdhie.#####a#####fgffececeda###aaa#aaaaaa#cddecddcddefeegefeccbccccbaa##aaa#.#####.##aaaabaa#aaaaa#aab#bcccbbccbbaab#aaaabcbbaa#aaaa#a#a######aaa##aaabdfdbbbbabbbbbbbbbbccccaaaaaaaaaaabbbbbaaaaaaaaaaba#b" "bbaaabbaaaaaaaaaaabaabbbaaaabbabcedcbbabccaaaaabbbaabbceffcccbbcbbbbbbbbddcdddbbbabbbbaa####aaabaaaaa##aacfeaa######a##aaabbbaaa##aa#a#####bcca#a##aab##aaa#aaaacccgdbbb#######aaaaabbbdhhb###########aeifddbbceda#aaa##aaabaabefffcdddccdeeeedeffefeddccbaa##aaa###.###..aa##aba##aaa#aaabaaabccddcccaabaababaabcca###aa#aaaaa####aa#####aaacffbbbbbbbbbbbbbbbbcdcaaaabbaaaaaabbaacbaaaaaabbbab" "babbbabbaaaaaaaaaaaaabbbaaaaabbbceddcbaaabbbbbaaaaaaabcdffdcabbccbbaaaabbbbbbbbaaaaaabaaa#a##aaaaaaa####aadd######a########abbaaaa##a#####a#aa########aaaaaa#aabbbbdgcaaa###aa##aaaaabadfgb######aa###aadidcdbaceca#aaaaaa#abcdeeeccdeddccddeadeefffffffecbaba#######.###.##aa#abaaaaaaaaabcaaabaabcbd#abaabbbbaaabdba#a#a##a###aaaa#########aacefdbbbbbbbbbbbbcbcccaaaabaaabbaabaaccaaabbaabbaa" "baababbbbabaaaa#a##aaabbbaaaaabccehdbaaaaaaabbaaaa##aabdgieccccbcbaaaaabaaaaaaaaaabaaaaaaaaabaaaaa###a###aaa################aaaaaacba######a#a##########aaaa#abbbbbcdhb##a####aaaaaaaacbfe.##aaaaa#####aadhcbbaaefbdb##aaccddfgedbddccccbbcdedceceggfeefefdcbaaaa#####.###.###aaaaaaaaa##aba#aaaaababdb#aa#aaabaa###bcbaa#######aa#############abdffcabbbabbcbbcbcbcdcbbaaabbbbbbbaacabaaaaaaaaa" "bbbbabbbbbbbaaaaabdcabdcaaaaaabbcdffcbaabaaabbbaaaaa##bcgjfbbbcdddcbbbbbbbbbaaabaabbbaaaaaaaaaaaba#########a#a###############aaaaaabaa#######a######aa#a##aaaabcbabbcceda#aaaaaaaaaaabbbec.a#aaaaaaa####aadhcabbbeecbaaadefggfeddcddcccccbccdccdddeghggeeeddcbaaaaa############abbaabaa#aaaaaaaaba#ba#aaaa#abaaaaa##aabbb###aa#a#a##a##########abbcffdcabbcbbbcccbbccccbaaaaaabbbbaabbabaaaaabba" "bbbbbbbbbbbbbbaaabfdcccbcbaaaaacdceebaa####aaabbbbaa##bdghfcbaaacdddccccccccccbbababbbaaaaaaabbbaa#a##aa#a#b##a#aa###a#######abaa###aaaa##a################aaaaabbbcbbcffaaa#cbaaaaaaaacec.#####aadea##a#aabgdababdfda#adfggeddccccbbbaccbbcbcddddgghigffffbabbaaaa##########ab#aaaaaaaaaaaaa####aaaabaaaaaaaaaa####a##aaca##a######a#########acbbbbcdefdabbaabccbbbbccccbcbaaabbbaaaababaaaabcc" "bcbbbbbbbbbcbbbbbcecccbaccedaaabddcaaa#######aabcbbbaabdfhfdcaa###acdcabdfeeedcccccbbcbbaaaaaaacbaa###aaaa#aaa#####a#aa##aa###ba###aaaaaaaba############aa#aaaaaaaaaabbbfgaa#adbaaa#aaaaehaa###aa#adea#a#aaabgbabacefdb#dfffedccbbaaaaaaccbbcdecdggihihhfdffcbbaaaa###aa###..#aa####baaabaaaaaa#####aaaaaaaa#aba#a###abaa#cbaa##.##aa####aa##aa#baaaacccefdbbabbcccbbbdccdbaabbbbbbbaaabbaaaaabc" "cabaabbbbbbcbcccccddb##abaccbabbdbcaa#a##a####aabdcdbbcdddghcbaaa####bcacigggecbbbcbcbbabcaaaaaabaaa#a##abb#########a##aaaaaaaaaa###aaaaaaa########aa##aaaa#####aaaaa#acegfaaa#aac##aaaachfc###aa###aabb###a#bbabccddefdceffedbcaaaaa#aaabbbbcdegihhhhgggdcffecabaaaa##a##.###abca#aaa##aaaaaaaa######a###b###baa####aaaaaaaaabca###############aaaabbbbbbdfebbabcccbcdcbbdcbbaababbabaabaaaabbb" "febaaaabbbbcdcccccb#####abbabbcccbbaaa####aa#a#abdeccbddeeehgcaa#a#aa#addhifdddbbccbcccbbbbaaaaaababaaa#aaba####a##a#a##aaaa#aaaaa#a##baaaaaaa#####b###aaaaaa##a##aaaabcefihefc##aaaaaabbdha####aaaa#ab######aaaabbccdefegffdcccaa#a##aaaaaabbehhhhffffcddbdcdbbba#ac######..###bb###a#abaaaaaabba#####aaa######a#aa#####a#####bbca###########a##aaabbbaaaabdfdbaccbccbcbbccdcbbbbaaaabaaaaaaabb" "dedbbbbbbccbcdccddb#####bbbaacccacbaaaa###aaaaaaacfdcbcdegghigbaa#aaaaaadfhgedcccccbbbbbbbbbbbbbbbbaaaaaabbba########aa#aaaa#abaaa####aaaaaa############aaaaaaa###aaaabcfghgihfbcb#abaaabbge####aaaaab######a#aaaaaaccdeeddfdbcbaaa##a##aabaafhgggfedccccdccbaaabaaaaaa#########a#####a##aabaabcaa#aaa#a#####.####a###########a#aaaba##a####a#aba#aaaabbaaaaabdeecccbbcbbccccdcbabaaabbbaaaabbba" "bccdcbbbcccccbcdfda#####acbabcbaabaaa#a###aa#aabbbefedcdffiihhcaaaaaaaabacfffefedcbbbbbaaaabbbbbbbbcaaaaaabaaa####a###a##aaaaaaaaba#####aabaa###########a#a####a###baabccghfhiieaa##aaaaabdga##a#a#aaaa######aabbaaabbbcddegdcbbaa##aaaaaaabbfedfddecbbbbbbaabbabbaaaaaaaaaa####aa####a#a#aaaabcbaaaaaaaa##############.######a#a#aabbba#a####a#aaaabaaabaaabbabcfedcbbbcbccccccbabbabaaaaabbccb" "bbccccbbcccccdddeca####aabbccca##aaaa##a#####abbbbeeffeeccfjjifbaabaaabbbcdecdeffdbcbbbaabbbccccbbdcbaaaaa###########a#a#aaaaaba#a######aaabcaaabaa###aa#aaa######acedbcdfihfhifba####aaaadhc###aaa###########a#bbaaabbccccfecaaacca##aaaaaccffdfccedbbab#a#aaaabbaaabababaa###########aaa###bbaa#aaa#abaa##########.########aa####a#aabba#a###a###aaaaabaabaaabbbcdfedbcccbcccccabbbbbbabbbbbbc" "bcdcbbcccccddddddba####abbbbdca#a###a###aa####aaabcededcbbgiijjhcabbaaaaaccddddcceedddddddeeefedbbcbcccbbbbaaa#a###aaaaa###aaaacaaa##a###a##acca############acaaaaa#abbccdghccggfcaba#aaaacggdaaa###############abbbaabbdeefedbaaaadda##aabbchedeefedbaaab#####aabbaabacbabaaaa########aa#a###aa####aaabba##a##.#############a#a####aaa##abdba#########aabbaabbabbaabdeddcbbbcccccbbbbaabbbccbba" "bbddccbccdccdcebcbb#####abccbcd######aa##a######abcddcdddeggiihhhdaaaabcccceedccbbcbbccbccdeeeggfeddccdeccbbaaaaaaa#a##aaa###aaaba#a##aa######a#####a######aaaaaaabaaababcehb#adcbdbba#aaabdceaa#################abbbbbacgeeecca###bedcaa#adfhccdffbbbba###a####aaaaabbbbaaaba###aaaa##########aa#.##aaaaa#aa#b######a#######aaaa##aaaa###abcdb######a#aabcbaabaabbaaabcdedbbbcddcbbbbcabbbccbbb" "bcdfdddcccdddcecbb####a#aabccabaa#####aaaaa#####abbccdedeedcijfggfabaabbbbccddccbbbabaaaaaaaaabbbgihihffedccbbbbbbbba#a#aa####aaaaaaa##aa#######a###aaaa########abaabbbbaccega#cdaaabaaaaabbfea#a#################abbbbbaeedddcbaaabacceccefihdccedcbaa##########aaaaaaabbbaaaa#####aaa##a############aa####aaaa######a#####aa##a##aaa###aaa#a#abc#aa###aabcaaaabbbbbbbbbbcddcbccddcbbbbabcccdcc" "ccbcffhfdddddccadbaa#####aabbaaba##########a##aaabbaacdddfeehjifgha#aabcbacddccbbbbbabbaaa#aabcccefgdddeffeecdedbbbbcba###aa####a##aaaaa##a###aa###aba#aa######a#aaabbba#abbfcbcccccbaaa#abbfjg#aa###########aaabbaaabbcbdedcdbbaaabbbcceghhiiedcedbbaa######a###aaaa#abaaaaaaaa##aaa##a##############aa####aaaaa#####ab#####aa##a###aa#aa#a#####aaaa##aaaaabbbbabbbbbbbbbbbbdddccddccbcbbbcccdd" "eecbdggfdddedcacda####a###abbaaca######aa##aaa#aabcababcdeeedgigdfgbbcbbbbbcccbbbbbaaaaaaaaaccddddefdecccbbcbbddcbccddedcaaa#a#aa##########a########adbaa#########aabbbcbcabbdcdcbbbcbaa##abbfiaaa##############baaabbbbccedcccbaa#abbbbbefgihfdcccbaaaa###a######aaba#abaaaaaabaa#aaaaaa######...#a#.#####aa#aaaa########a##aaa###a###aa#aa#aaaa#aabbabaaaaabcbbbbbbbbbbbbbbbccdeddcccbdccccdde" "eedfhhfcba#abb##a#####a#aabcaaccbc#####a#aa#aa###ccbbbabcdfffhgifehfebbbabbcccbbbbbbbbaaaa#ccdcddfghfeccccbbbbabcddegcbccdcaaaaaa###a###a######a#a##accba#########aaaabbccbbcbcehb###cbba##bdehe###############aa##aabbbccdcbccba##aacccbcceffedcbbaaa#####a######aaba##aaaa#ababcbbbbcbaa########.#.##a####a####aa######aaa###aa####a###a##a#aaa####aaadbbaaacccbbbbbbccbcbcccbcceeeeededcdbccd" "dgghigdb##a#a########baaa#abbcbdbbb#####aa#aaaaaaabaababcdegiihdggffdcbaabbbbabbbbbabaaaaa#ccdccdegedccbbbbbbcbbbbaadbabaacdb###aa###############aaaab#aa##a#######aaaaababbbabbfieaaaa#aaa#chke.#########..#aaaaaaaaababbccbbcbaa#aabbcbabcdeedcba###a#####a#a##.###baabbaaaaaaaabbaaba#########....#.#######ab#a#######a######a#########a##aabba###aaabbbbbbacdcbbbbcbcccccbdddeededegeddddcdc" "dhghhfa##a######a######aabaacccedaaa#######aaaaaaaababbbccdghgfedgfgcabaaaaaaabababaabaaaaabdcceeeecdbbbababbbbccbbbbbabdbabcba#a############aa##aaaaab#aa###########aababcbbaabeggh######aaagj##############aa#####abbaabbbbbabbbabcabbaaaabcddccba#######.###########ccaaa###aa##aaaa###a###..##....#.aa##a############aaa#####a#####a###aaa#aaaa#aaacaabbbbbbeccccbbccddccdegghhgfeegd#bddccc" "ffhhhe###########a#####b#bcadddcbaaaa#####abcca#aaaaaaaaabdhihgddfgfgcaaaaaaabbbabbbaabaaaabedcefecbbbbbbabbbaaabbacdca#aaa#bbdb#aaa#########aa####aa#a###a#####.###aaaaadbbaabaddcggbaaaa#bbdia#a##########aaa###aaabaaaabbbbbbaacefebaa#aaaabcccbaaaa###########.#.##ad#####.##aaa#aa#aa#####...#...###ab#ba######a###a##ab#####a###aaa##aa#aaaaaaaabbbbbbbbbbceddeeccbccccddfhijjhggghb#bba##" "#afhgcaa###########a#a##aabcddca###aa######abbbabaaaaabaaaeiiihgbbgeddaaaaaaaaabbaabbbaaaaabdcccddddccabbbbacaaaaabbbaaabaa##acdd###a######..a#a#####a#aa##a########a##aaecb#abbbcccfgaaaaaaaeia#a#a##############aabbaaaababbababdgeca####aaaaabcbbba#####a####.#######da##############aaaa#######.##.#.#ba########.#a#aa##abba##aa#aa#aa###aaaaaaaaaabbbbbcbccccefgeeccbccbbbbdfiihgggeb#aaaa#" "##bhgd###############ab#ababcdd###aaaa####aaaaaaaaababaaaadhhigebabfddcaaaaaaaaaaaabaaaaaaabcbbbcbbcecbbbabbbaaaabbaaaaaba###abadea#########.#a##########aa#a###a###a####aabbabbaadccghbbbaaabfi#a##a###aa####a##a#aaabaaaaaaaabbacfdba##a#aaa#aaaabbb######a######.##a#######aa#a##a#a####aa#####a#.#a####aa#########aaaaa##aaa###aa#aaaaa#aaaaabaaaabcbbbbccccceeceeeefedddcbbceeffhgfebaa####" "##.dhdb#########ab###bdababaddc######a###.#a######aabacaaaadghfdbbabecdba###aaa#aaaaccabaaacababbbbbbbcbcbbcbaaaaababaaaba####abbcfbaa#aaa###.###ab#####aaaa##a######aa#ba#aabbbabdcabefbcaababhe#a##aa##aa###a#####aabba#aaaaabbbefcba###aaaa#aaaaaaaa#########a#.##############aa#bb#aaa##a####.###########aaaaa#######aaaa###a####a##aabaabaaaaaaaaaabbbcccddebbbbdedefdcccccbceeghgfdaaba#aa" "aa#aeea##########c####ba###aca#####aba#############abcabaa#acdefccbacdbdc##aaaaa###aabdbaaabbcccbbbbbbbccbabcabaabbabbaaaaa###addbcdba#a################a####aaaa#aaaaaaaa#aaacbabdcbbbehca#abbeh#aa######aa######aa#aacfbaaaaaabbdgdbaa###aaaa#aaaa########.###aa#a.###########aaa#bbaaaaaa####a#.##.#######aba#####a#############a#aaaaabbba#bbbbaaaaabbcddddddbaabcedccbaadfdcceeggdbaaaaaaa#" "aa##ada#a########aaaa###a###a######abaa#########aa#abbbaaaabbcddeeebcdbabb#aaaaaa####aaaabcccbccbaabbbabccbaaaaaaaabbaaaaaaa##aabcccfeb##############a####ab#aaa##aaabbaacababaaaabcdbccffc##abeh.##aa###a#########aaaaacbabaaaccddfgdbaaa##aaaaaaa#######.##.#######.#########aaabaab########a#a##.#########aaa#####aa##a#aa###bdaaba#aa#aabaaaabbbabbbbcddefecbcbaabbdcbaabcecccefgcaaaaaaaaa#" "aaa#aaaa#aaaaa#####aaaaaa###########a#####a##ab#a##aacabaaabcccbdhedfdbbabc#aaaaaaaba##aaaeheaaaaaaabbbacddbbaaabbbaaaaaaabc#aa#a###cfgb#a#########aa###aaaccaaaaaaaacbabcdaacbaaabcddcccgfcaabeg.#a#aa#a###aaaa####aaaaabaaaaaaceefhfdbaa###aaaaaa########.####.###.####.####aa#abcbaaa####aaa#############aaaaaaaa#aaaa#ba#babffb#acb#aaaabaaabbccabbcccfgdaa##bcbbaaacbcbacebbbcddbbaaa#a####" "accccedaa#aa#aaa##a#aabda#################a#a#a##aaaabbbabbcccdcccfcfecbaaceca#aacdbcccba#ahgabaaaaababbbccccbaabbbbbbbaaabcb###aca#aabcc##a##########a###a#abaaa#aaabbddddbbbcbaaaaabcdddhecccg######ba#a##.#a###aaceca#cbaaaaacdefhgfcaaa#aaaabba#########..#####...#.#######aaabccbaaa####aa########.####abb##aa#aaa#a#ba#abbefba##bbbaaaaaabbccc#ccddeffcaaaa#baaaaabebbbbcbbbbcbbbbbaa##a##" "#abeeebaaa###aa###aa###aaa###################aa###a#aabbbbcddddccefegfcca#adhbaacccaaabcbcdecaaa##aaacabdabdcbaabbabbaaababbcb#aabb#aa##dea##aa#######aaa##a##aabaaaacacdfebbbbbbabccccfeddfgfed...#a##aa###########acdbabbb#aa#acddegfecbaaaaaaabaa#########...#####.#########a#abbbabba##aa#####.##....#####a##aaaaaaaa#baaaceeebaaaaeedbbbabbbccb#cedddcccbaaaaaaabaa#bebbbbbbbbbbbbbaaaa####" "##aadba#aa##a#######abbda################a#######aaaa#ababccdeeddffhhgccbaabefdbbaaa#aabcbbabca#aaaababbbbcccbaaacaabaaabaaaabbaaaab#aaaaefaaaaaaa#.###a#a#a######bbbaabccabbdcbabbcbcdbbaaaefeiiffa####a#######a##aaaaabbcba#baabdddefffdcaaaaaaaaaa##########...##############aabbbbbdabaaa###.....########aaaaaaaaaaaaabcccbdfebaaaaaacfdccbcddc##baabcbabaaaaaaaaabaaaedbcbcccccbbccbaaaaaaa" "a##aba#a####.######a##bgb#######a########aa#######aaa##aabbcceedddeghiebaaabccebaaaaaaaabaabaaabbaaabbaaabbbbbaaabbaaaaaaaaabbccbbcba#####cfebbabbbacaaaaaa#aaaa###acbbbbbbbbcbaabbbccbaaab#.aceffdfghfa#a####aa#aa##acbacbbbaaaaabcedcddedbaaabaaaaaa#######..#.################aabccccdbbb####.#..#..#.#..########aa#aaa#aaabdddbcababbbdeddedeeb####aaaaaa#ba#aababcbbbaeccbcbcbcbbbbaaaa###a" "ba#a#####a#############cb#########aa##a###a####ab#aabaaaabbbbedcdccehihcbbbbbbccaaa#a#aaaaabbaaaabbbcbbaaabbbccaaabbaaaaaaaaaabbbbacda####aaedbaaabddba#aaab###aa####aaddcceebabbbcbcdca#aaba#aaabaabfmka##aabaaaaaa#abbabbbbaaa#acccdddccedbbbbaaaaaaaa##a####.#.###############aabddcbbcaaa####.#......aa###aa####aaaa#aa##aacccccbbbabbcdedddea####a##aa#a#bccbccbcbbaaaadddccbbbbbbaa#aa####" "ab##aaaa######a##########aa###b##aaaaa##a#a#####ababbbaababbbccccdcdgjifbbabbcccca#aaaaaaaaacaaaaabcccbaaa#bbbcaaaaaaaaaaaaaaaaccbaabbaa#a#a#bcbbaa##a###aaba######aaaaaaddfhgccddddacacaaaaa#aaaaaaabhnk.aabbb##aa####aa#acaabb#aabccddeecccbbbabaa##aa###aa#######.######a###aaaabdddcdedda#########...#####aaaaaaaaa##a###aabcbbccbbbbcddeeefc##a####aaaaaacdccbbaababaaabccdccccbbbbaa#a####" "#####a#aaaaa###aaa######ba###aa#bba#aa#abca##bb#abaabbbbbbaabbbbdccceihgecbcdccbcd#ababa##aaabaaaaaabccbaabbddbbaa#aaaaaaaaaaaaaccbaaa#a######aabdcb##aaa##a#a#####aaaa##aabffebccddcb#aa#######aaaaaadlnd#aabbabaaaaa##aaaa####aaaabccdeedbb#aa##a###############.##..#.#####aaaaabccdeecdaa#####.########.###aaa#aa###aaaa#aaabcbccccbbccddeef##aaaaa####aaaccbaabaaaaaaaaba#bcddcbbbbbb#aaa#a" "abaa###aaaaa##a#a##a#############a#a#ababda#aaaaaaaabbaabbbbcbbbddbddgifhedbcccbbcc##aabbaa#aaaaaaabaabbbccccdebaa##aa#aaaaaaaaaabedaaaa##########becaaaaa#a#########aaa##abceffdccb##aa########a#abbabilk#a#a######ab#aa#aa#####aaabbcddedbaa#a######a#####################a#aaaaaabdddfgfc##########...a#a###aaa#a#aa##a###aaaabbbbbcbbbcceghfaaaaaaaabbabccbbbaaaaaaaa#abba#aacedcccbaaaaa#aa" "bbaa##aa#aaaa#aaaaaaaaa#aaa##########abaaaa#baaaaabbbbbabbbbccccddbddggghhfdbbcaabbbbbaabbaaaa#aaabbaaabbb#bbbaaa#####a#aaaaaaaaaabb##aa##########aabdcbabaaaa####aa###aa#abbcdhhcaba#baaa#######aaaaabhlmc#a#####aaaaa#a##abba#aabaaabcdgfbb################################aabbaabbccdhigca#########.########aaa########aa#a##aaabbbbccbccdgfha#caaa.##fedbbcbaaaaaaaaa#aaa###aaadecccbbaaaaaa" "#aa###aaa#a#aaabbbbbcbaa##a#######aaabaababaa#aaaaabbbbbaaababccdecdfhhiihgfdbccbbcbabaaaaaadca##abbaaaaaaa#bb##aaa####aa#aaa#aaaabbda.##########aaaabddcbbaa#a##aa#aaa##aaabbdecca#a#aa#a########aaaaaeili##a######abaa###aaaaaacfeaabddcdbaa##############################aaabbbbbbcdfgjieba####.#####aa#aa############aaaaa###aaabcbbcbbcefggcbbfeedbedbcbabbaaaaaaaaaaaaaaa#aaa#cdcddcbbaaaa" "aa#a###aa#a##a#aaaabbccaa#aaa########bacbaaaaaaaaaaaabcbbbbbbcedcdccfhfhkhggfdbbccbbabaabaabdda###aaa#aaaaaaacb#########aaaaaa#aaaabec##########aaaaaaabddcbaaaaaaaaaaaa##aabacbaaaba#####a##a######aaabgklbaaa#####aaaaaaaaaaabbbfdaacddeddcbaaa#########aaab##########a##aaaabbcbbbbeffhjifdcb#####.##acbb#aaaa###########aaaa#aaacbcbbcbcegfaccgghgffdcbbaabbbaaa#aaaaaaaaaba#aaaabeecccbaaaa" "aaaa########aaaabbabbbbcbbbaaaa#####.##aaaaaaaaaaaaabbbbaaaaadedcdccegijkifddebccbbccaabaaa##aa######aaaaaaba#aa#########aaaaaaaaa#bccda#######aaaaabbaaabddcba#aaaaaaaaaaaaabcdaaaaa##abaaa#a#a#a##aaaafhlg.aa#a#a###ba##b#acaabcdfaaaccdccedba##########adcbca#########a#aaabbcddccbdefggiigecb########aaaa#abba###########aaaaaa#bdbccbccef#abdeddeeddccba#bbbbbaaaaaaaaaaabcaaaaaa#eedccbbba" "aa#aaaaa###aaaaaaaaabbbbbbbbaaaa#######aabaaaaaaaaaabbaaaaabbbfeccccdfiljigcdeccccbccbccbbaaaa#######a#aa##aaa#####..#..#aaabaaaaaaabacb######aaaaaaabbaaaacddcbaaa##cbabaaaaabcbaaaaa###a##a####a##aababchl#.###a#####aaaaaa#aabbdeaaacbbbbdfdccbabb####a#ddbbbba##########abbbccdcccddefghhfcaaa######aab#abaaddaa########ab###aaaacccccdefd#dbgebcccdcaabbbaaaaaaababbbaaabacaaaaaba#eeddcbba" "aa#aaaaba#a#a##aaababbccbabbbbba########aa#a#aaaaaaaababbaaaaadcccaddfhkjigdcdecccbbcdcecbaaaa######aca####aa#####a#####.#aaaaa#aabababb######aaaaaabbabaaaaabcdcbaaaaaaaaaabbbcaaaa#a####aa####a#aaaaaababjh.####a#####aaa##aaaabdabaaaabbabdeeeddddcb#.##debaaabaaaba####aaabbccdcccddeffgfgcaa##aa###aaaaaccaddca########a#a###aaaccbbceffbaacgeaabbbbabaaaaaaaaaaabaaaabbcaaabaaaabbbccdedcb" "ba#a#aaaaa####aaaaaaaaaaccbcbbaa#######aaaa###aa##aaaaaaaabbbabbcbbefffhjihfcbfcbcbbbcfhgcaaa#####a#deaa##aaaa###############a##a###aaaaa###aaaabbaaaababbbbbbbbedcbaa#abbbbbcccaa##a######aa##aaa##abaa#aabja##.#######a#a###aaabecaaaaaaacccbcaaaabbdddefedcbaa###aaaa#aaaabbbcccccccddfggghdba####aababababcbbddba###a###a#aaa##aabbcccegfbaabcaaaaaaabbaaaaabbaabaacaabbbabbadbaaaaabba#aefc" "ba#a#aa#######aaaaaaabaabbebdbbb######aa####a###a####aaaabbaabcabcccddffjhfdbaefcdbbbbdjkjebaa#####bccb##baba#####aa######a###a#a####aaaaa##a##aabaaaaaaabbbbbbabefdbbcbbbcbbbcbaa####aa#######aaaaadaaaaabbdg###a#a####a#aa#aabccccaaaaaabcdbccaaaaabbdeeedcdcba###aa#aabaaabbbcbcccddddeffffdbaa####abccbb#bbccdbccaa###a#aaaa#a#aabbdcdfgdaaaccaaaaaa#aaaaababbaaabbbbbabbbbbcbcbaaaabaa###be" "fcb#############aa#aaaaaaadegdacbaa###aa####aaa#a####aaaabbaaabaabddccehieabaabecccbbbbbikkgca####acbb###baba#####aa####aaaaaaaa######aa###aaaaaaabaaaaaaaacbbbbbbeffedccbcddddbaaa##aaaa###a##aaa#adba#aaabbie.#.#aa##aaaaaaacecaaaba###a##aabdb#a#aaccccccccbbba###aaa###aaabbbbcccdddedegcddcbbaaaabbabbabbaabbaaddbaa#####aa##aaabbddefgcabagbaaaaaaaaaaaabbaaacabaaaaabbbbabbaaaaaaaaaaaa#a" "bdeba#########aaaaa###aaaaacfebbbbaa###aa#####aa########aaababaacbdeccehhbaaaaaddcbbbbbcgijhea####acb########a##aa#a##a#aaaaabaaaa####aaab###aaaaaaaaaababbccbbbbacbedffedcdeeaaaab#aaa#aa##a##aa#a###aa#aabackc.#.##aaaaaabdefb#a#aaaaa#a####abc####abcbbeecbbaaabb#aaaaaaaabbbbcbcdededdefdcaccbca##aaaa###aaaaabaaeccaaa###aaa#aaabcccdffbbacfc#a#a#aaaaaaabbaaaaeabcbbabbbbcbbabb#aaaaaaa#aa" "##aba######aaaaaaaa##a#aaa#fdaabbccb###################a#aaaabbabccccdehibabbbbcfdcbbbabgihc#a####abbaa##a###aa##a#aaaa##aaa##aaaaba###daaa###abcaaabaaabbbbbccbcbcdcdddggfedbcbaaaaa##a#####aaaa#aa#####abbbbdjb.a##aaaaabeecabba##aabda######aa####aaabbdcdcbaa#bcbbaaaaaaaabbbcccddedefffdcbccbab####a#####a#aaabaabeeba######aaacbcddegebbacccba##a#aaaaaaaaaaaaccbbbbbabaaa#aaabbaaaaaaaaaa" "aa##baa####aaabaaaaa#####aacaababbccbaa##################aaaaaaaabbccbegifaaaabbcecbbbbaadgb#####aeeabc#.######aa##aaaaa#aaaaa###abaa##edaaaa##aabbaaaabbbbbbbccbbdccccdddehhdabbaaaaaa##a###aaaabb######cebcbcgj#aa##abdfggcbbbaaaabdfea####aaaaa##aa###aaa#aaaa#aaabbaaaaaaaabbccddeeddeffeeeefcabaa#aa#####aa#aabbbacccbaaaaaaaabcccdegfbbbceaacb#####aaaaaaaaaaaacccabaaaaa#a#abbccaabbaaaa#" "#aaa#daaaaaaaabbbaaaa####abbaabaabcbbbbb##aa################aaaaabbbddehecacbaaaabecbbbbabaa#####adcca#########a#a##daaaaacaaaaaa###aa#aca#aa##aaaabbbaabccbbbbcddaccdeddecfhgcabaaa#ab#a####a####aaa#aaaabbbcbcijdchihgighedbcbbcdfdabbbbccaaaaaa###caa#aaaa#a#a##aaaaaaaaaaaaabcccdddddeeedeeeffbaaaaaa##aa###aaabbbabcdeabaaaabbbbcdegibabbfaabca####a#acca#aaaaaaababbbaaaa##aaababbaaabaaaa" "#####adcbbbaabbbaaaa#a#a#####aaaabbaaabcbaa#################aa#aaaaabddgeadbcaaaaabccbbbbba#####a#a##aaaaa###aa#aa#bccaabaac#aaa#####a#..#####aaaaaabcbaaabbbbcdccdcddedceefgfccbaaaaaa#aa###aa##accaaaaaaaabbbbdjkfdfgjjhgfeeeeeedcaabaabaaaaa#####ab#a#aaaa###a####aaaaaaaaaaabbccddccccdccdeeegfbcbcaaa#aaba#aaabdcbbbababbbaabbcccdghg#aadbaabbaa###a##acdaaa#a#aa#baaaaaaaaa#a#aaaccbaabaaa" "a##a#aaedbbcbabaaaa##a##aa####aaaababbaabacaaa###a#######a####aaaaaaaccehbbbbcbaaaaacdbbbcb#a#a#a#.####aaa##a#aaaaaaabaaaaab##aaaaaaaa#####aaa##aa##abbaaabbbccbccbcdcdcddeffcaabaaaabba#aa####a##bcbaaaabababbbbejib#abccdcbbccba##a##aaaa##a######a##aaaaa#a###a#####aaaaaaaaabbccccccccccccdeegfcdabbaaaaaaa#aaaabccbbbaccbabbbcddefedea#cd##a#aaab#aaa##bcb###aaa##abaaaa#####aaaaabbcbaabbb" "aa##aa#bhgccbbccbbaaaaa########aaaaabcbaaaabbaaaa###aa#####a#a#aaaabbbbcega##acbabababecccdabaa##########aaaaaaaaaaaaaabaaa####aaaaaaaa##.##abaaa#aaaaabbbbbbbbcdbbccddcdcegeaaaab#aaaaaaaaa####aabbabbcbbbcaaabbcegiaaaaaa##abbcbca##.###aaaaa####aaa##abbaa#aaaaa####aaaabbaaabbbbccccbcccdddedfddcaaaaaaaaaaaaabbccdbbbcecbbccdefged#a###fa######aaaaaaaabaa#######aab#aaaa#aa#aaaaaabcccabaa" "aa##aadafhhfeccbbbaa#aaa##a####a#aaaaaaaaaaaaaaaaabaaaabaa#aa###aaaaaabbcfd#a#acbaaaaabeecdcc#############abbaaaaaaaababbba###aaaaaaa#a#####aa#aaaaaa#aaaabbbabcccehgeecdegebaaaaaaaaa#aaa#aa###aaaaababccbbaa#aabceggaaaaaa#aaaabcb####a###aaba######a#a#####aaaaba#####aabbaaaabcbbbbcbbacceeddeebabdbabbaaaaaababcdccdccdcbbccefecb#####cc#########aaaaaaaaaa##ba#aaaaabbbbaaa#aaaaaabcccdgdb" "##aaacdggggghgdbbbbbaaaaa#aa###a###aa##aaaaaaaaaaaaabcbbaaaaaa#aaaaaaabbbdfd#aaacdaaaaaadgefc#######a#a###abb##a#aaabaaaaaa#######aaa#a########aaaaa##aabbbbbbbbccefhfeeegfbbba#aaaaaaaaaaaa####aa##abbcdacbaa##aabcehfaaaa###aaababa##.##a#aaaca#a#aaaaaa#aaaa#aabcc#####aaaabbbbbadcabbbbbbceedefcaabcecaaabaaababccdcdddccbbcceda#####baeaa#aaa#####ab##aaaaa##aaa##abbbbbbbbaaaaaaaaabbbagig" "f#aaaehhfffeffhfbccbbaaaaaaa####a#aaaaa###aaa#a#abaabccabcbabbbbabbaabbbbcehdaaaaaaaaaab#dgeaa##a###########aa####aaaaaaa######a####aaaa###a###aaaaa###aabbbbbacccdedddfgebcbaaaaabbbaabaaba#########abcbdabaaa#aabcdeibaaa######aaaca######aabbb####aaaaaaaaaaa##bbdb####aabbbbaaaacdcaabbbbcceddeccccaba#aaabaaaabccddddddceddeec#aca#aabebaaa#######aaaba#######aaaaabbbabbbbbaaaaaaaaaba#dii" "hd#aaejiedefeeddedccbaaaaaa########aaa#######a#a#aaaabbaacbbababccbbabbbbbceidbaaaaaaaacbcgeca#############aaaaaaaaaaaba######.a############a##aaaaaaaaaaaacbbbccccedbcfcbbbbaaabbbbaaaaaaababaaa#baaaabababbabaaaaabdfhaaaaa#aa##b#bbaa#####abb##a##aaaabbba#aaaaaacda#####abbbbaa####a#abaabccbdecdbbaaaaaaaaaaaabccceeedcdfgffeba#aa#aa#bcaaa##########aa##a####aaaaa#aaabbbbaaaaabbbcbbbeefh" "ggecdhjkiefeeddcdefdababaaa########aa##a########abaabaabcdabbcdccbcbabbbbccchiecaa#abbbaaaadeca#####a#######aabaaaaaabba###a##.#############a##aaaaaaaaaaabbbccdddbbeccdbbcbbbabbbbbbcbbaaaabccaaaabaabcabbabaaaabaabcefeabaaaaa####aaccb####aaa###a###aabbab#a#aaa##aaa#####acbba#a######aaaabbbbfefdaaaacaaaaaaaabbbcefffeefbed########a##dbaaa#######a#############a########aaaaaaaaaccfgfhdf" "efddegijmkfeeeddccdgdbcccbaaa####a#aaa#####a####a###aabbcbabacccdccbbbbbcbbdfijhbaaaaabb###cedbaa###aaa#####aabbccbaaaaa###accb###a##########aaaaaaaaaaaabcbbccddddcddaaaabbbabbbbbbcbaabbbbbaaaabbaaaaabbbbaaa#ccaabbddheabaaaaa####abca#####ba##a####abcaaaaaaaaaa#aaaa#####bbaaa##aaaa##aaabbaaadfdbaabcbaaaaaaabbacehhhhcaaaa#####a#ab##ccaa########aa#############ba#a#aaaa#aaabdaaeffghgff" "eddcbcdefijgeedcccbbdeccccbaaaaaaaaaa#a#########aaa##a#abcaacccccccbcbbccccdefikibaaaaaaaabbdddca#a#a#aa####aaabbbaaaa##a##aaaba##aa##a######aaaaaaaaaaabbbbbccccddddaabbaabcdbbbccbacbabcbbccbaa#aaaa###baaaaa#a#aaabcdfjb#aaaaaa####abaa.####a##aa####bcbbaaaaaaaa#####aa##abaaa#a##aaaaaaaaaaaaabecbaababaaaaabbbcbcehhcaaa##aaa#######b#.cbabaa#####aa##a#####a#########aa#a#aaabdefffggfefe" "ddcaaabdefhihecdbbbbacdecccbbaaaaaaaa############aa##aa#ababbcbcbbbababccdceeegijgaaaaaba###bfcdc##aaaaa######aaaaaaaaa#aaaaaacba#aaa#a#ba#aa#aaaaaaaababcbbbbbcedabbaabbaaabbbabbdccbbbaabbbbbaaa#aaaaa##aaaaaa#####abcehka##aaa#####aaaa###..a#aba#####abcaaaaaaa#a##a##a###ba########aaaa####aa#deaaa#aaaaaaabbbbbccefcbaba##abaaaa.#a#ba##dc#a#a####abaabb#a##aa##a###a###aaaaabaceecddhhedd" "cccbabbcdfffhheccbbbbbcdfccbbbbaaaaaa###############a##aaaabacbbbbaaaacccddcdefhjjhbaaaabaa##dfbbc###aa#aa######aabaabaabbbbbabdb#aa#a###bba#a##aaaabbabbbbbcbbcedbaaaaaaaaabbbbbcbccbcebbbbaaaaaaaaaa#####aaa####aa#aabdegj.############a##a##a#aba####a##baaaaaa#a###aa#aa########a##a#aaaa####a#eeaa###aaaaaaaaabbcdgfdbaa####aabbcb#aabc###cda#aa##aababcbb#a#aa###a##aab#aaaaababdecbcdheed" "cbbaccbcddeffeedcbbbbbbccffdbbcbabbaaa#aa########a###ca#abaabbbabaaaaabcccddcdgiikjgbaaaaba##afcacba###aa########abbbbaabbbbbbbcbbbb#aa#a###aa##aaaaababbbbcbccdca#a##aaaaabaaabcccbbcbcbaabba##aaaaaba#####aa####aabbbddcdjd.#########.#..#######aba######aaaaaba########aa#######aaa#aba#aaa###aacaaaa##aabaaaaaaabbcefcbbaaaaa##aaacabaaaa###bca#####aaaaacaa#a###a##a#aaa#a#aabbbbcddcccegdd" "cbbabbbbccddeedddcbbbbbbbbdfheccccbaaaa###########aa#bd##baaaabaaaaaababcddcccggijjjbaaabbaa##bcbabba##aa#######aaaaaaabbbbbbbbbcccaaaa##a##aaa##aaaabbbdbcbbcdfbaaa#aaabbbbbbbbbcccbccdedaaa#aaaabbaaaa#a#aa####a#abcccdccfi###########....#######aa##aaaaaaaaaaa##########a###a##aa#aa#aaa#####aaa#aaaa##abbbaaaaabcdefbbaaaaabaa####aa####a#a#dba#####bb##b###########aaaaa#aaabbaabbbccddede" "baabbbbbccccdeedcccbbccbcbbcdiheccbbbaaaaa#aab##aa###aa###aaaacbaaaaaababccccdfhjjjl#abbbaaba#abeaabb######a#####bbaa#aaaabbbcbbabbaa###aa####a###aaaabacdcccdceaaaaaaaaaababbbbbbbcbbbcbdba###aabbbaaa#aa##########aabbabccgb.###.#########.########a#aaaa#abaa#########a##aa#####bcaabaaba###aaaaaaaa#####aaaaaabbbdhidabaaaaaaaa###########a###ebbb###aaa####a###aa#aabcaabbaaababaaabbbbbdcb" "abcbbbbbbbccbbcddbcbbbbbbbbbcfeghfccbbabaaaaabaaaa####a#b##aaaabbaa#aaaaabccbceefhegdedaaaaaaa#abdaaba#aa##a#####aaaabaaaaaaabbbaacc###aa#aa####a#aaaaaaabcccddfbba#aaaaaabbbbabbccccccbcbdaa#####ac#####a##########aa#aabcbdh..#########.#####.####aaa#aaa###abb###########accaa###a##aaabbbba#a##a#abba####aaaaaccegcbbaaaaaaa#aa###.##a########aeaaaa###a#a######aaa##aaaaaaaabbaabbaacaacced" "cadbbbbbbcbccbbacbbbbbbbbabccdeehgffccbcbaaabaaaaaa###a####aaa#aaaaaaaaaaabccbdeeffeehgcaabaaa##adb#aca##aaa#####aaabaaaaaaaaaabaacdb##aaaaaaa#abbaaabbbabbdecffbaaaaaaaaaaaaaabbaccbcbcccdcaa#############aabb######aaaaabbbehd..###d#.#.######.####adbaaaa##abba########aaaaaaaaaaaaa#aaaaaaa#a#aa#abaaa####aaacdeheaaaaaaaaa##aa#aa#####a####a#.cdaa######a##a###########aa##aabb#aabaaabbadf" "cabdabbbabcccdccbccbbbbbbaabdcdefdcfgccbbbbaabcbaaa###aa##aca####aaa##aabbbccccddffhihhfbaba#c###bdaaagaaa#a######aabaabaaaaaaaa#a#aa####aaaa#aabbaaaabbbbbcddfeca###aaaaabbaabbabbcbccbbbccdada###aa######aaba####a###abaabcafjlf..defe##...#########bbaaa###aab#a#######aaabcb#aaaaaca##aaaa####a##aab###a##aabdfiida###aaaaa##ca#aa#####a####a###ecaaa########a##a#####a####a###aaaaaaaaaabab" "ccbbbbabbaaabccdcbbbbbbaaaabcdbbbeeadgeccbbbbabbbaaa##aa#abedbaa####a####bbbcbccddehhhfdaa###da#a#ddaabhaa###########a#abaabbaa######a####aaaaaaaaaabbbbbbcbdeefcb###aaaaaaaaaabbbbccccbbaabbcaaa############aacbaabaaaaaaabccbdejkbd..bgccdcba########aa######aaa#a#######aaaccaba#bcaaba#a##aaa#####abba#aa#aabdgkjkihgdb#.cedcbb#.###dc########b##ebaaaa#########################aaa#aaaaaaba" "abeecbbaababbbabbdbabbbbbaaabcccbdcb#ehedccbbaabbbaaa#abaaaedba###########acbbbcceeeggdaaa#bacaa#aadabbdf#######.#######aaaaaa######bca###aaaaaaaaaabbbbbbbccfffbaaaa#aaaaa#aaaabbccabbcccbbbbaaaaa#######a#aa#acaaaaaaaaaaaabccceglh.#....#baacca..####ab########aaa####a##ababbbba#ceaaaaaa###a######aa##acbbbbchgcddfgjihddigefegfffba#affeecbbaaabda#aa######a#a################aaaa#aaaaaab" "babfdcbcbabaabababbbaaaaaaaabcccdbaaaacifddcbbbbbbbabaabaacecabaaaaa######aaabbcdeeedifba#adcbaaba#bcabbfe#aa####aaa###a#abaaaa######aaaac#aaaaaaaabbbdbbbbcceebbba##aaaaaaa#aaabbbbbbcccdcabaaaaab##a#aaaaaaa######abaaaaa#abbbbddei#####a####.#ee######aa######aaaba######abaaaa#a##bc##aa#a####a###a#aaaabcbbbceecbbcbdeffgfdccccdefeefgffedcefeb##cdbcba########a###########a###aaaabaaaaaaa" )) (define rough (list " 128 128 6 1" ". c #7fafaf" "# c #aaaaaa" "a c #b3b3b3" "b c #cdcdcd" "c c #a2a2a2" "d c #dddddd" "...#a...aaa#.a.a..aaaa.aa...##aaa#a#....aaa.a.aa.ba.....a.a#aaaaaaaa..aaa.aaa#a.aaa.aaaaaaaaaaaa..b..aaa.a.aaaaa.a.a#a....a.a.aa" "aa.a.aa#aaa.b.....aaaaaa..aa#a..##..b.a.aa.a.bbbbaaaa.a#aaaa.aa...aaa..abaaaaa..aaaa#a...a#aaa.aa.a.a...a.a.a..a.aa#a#a.aaaaaaaa" "..aaaa#aaa.....a.a##a##...a#aaaaa.ab..aa...bbb....aaa.aaaaaaaa.baa...b...aaaa.a.aaa.aa.aaaaaa..a...a.#aaa......a.aa##a.baaa..aaa" ".aaa.a.aaa.aaaa.a.aaaa.aa.caaaaaaa.ba.a....b...aaa...aaaaaa...b..a..a.a#aaa...aaaa..aa..aaaa.aaaa.a.a...a...aaaaaacaa...#a..#a.." "..aba#.#..a#a#.a.aa#aaa#a#aaaa.#aab....a....a.a....a.a#aa......aa..a.a#aa#.a.a.#a..aaa..aaaa.aa#aaa...aaab.aaaaa#a#a.aaaa.aaa.aa" "aaaa#aa.b..a.aaaaa##aaa.a....a..a.a.aaaaaa.aaa#a..a##aa..a..aaa.....a.a....a#aa...a.a.b...aa...ab.baba.a....aaaa.a..aba..b.a.a.." "aa...a..baaaa#aaa###a.a..b..aaaa....a.a.aaaa#aa..aaa#...a#b.a..aba.aa.a....#aaaa.#ab..ba.a.a.a.ab..a..aaa..aaaa....#b.....aaa#a." "aa.aaa.a#aaaa.a.aa#a.a......a#.a.....a.aaa.aaa..aaaa.a..a.a..aaa..aa.a...aaa.a..a...a...aaa.aba..b..bbaa.aa.aa..a.a#aa.#..a##a.." "#aaa.a.aa.a#aa.a.#a.a.a.baaa#a.a....a..a#aa#a.a.aaaaaaaaaa.b#a#a.a..aaa..aa.aa..a....bba.aaa.........aaaaaaaaa...aaaa.aaa.aa#..a" "aaaaaaaa.a..aa...a.b...baaaa.aa.a.aa....#aa...aaaaaaaaa....aa#...a......aaa#aa..aa.a..a.aaa.b.......aa.aa..aaaa#aa....ab.b#.aaa." "a#..aaaa..aa....a#a.....a..baaba....a.aaaaaa..aaa#aaaab.aa.aaaaba.aaaa.aa##.#..aa.a#.a.#.a.ba.b..aaaaaa.aaaa..aaaaa.aabb..a..a.a" "aa...a.a..aa#.aaaab...a.a.a.aaa..ab...aaaa.a.a#aa...aa......aab..a..#.a#a..#.a.aba.........b.....a...aaa#a.a..aa.a.aaabaaa..a.aa" "aa..a..aaaaa.aaaaab.a.b..aa.a.....aa..a.aa..a##.aa.a.abb...a....aaaaa.aaaa#a.a..a.a....a..b.a...aaaaaaaaa...aa#.aa.aab.aa#aaaa.." "a...a......aa.aaa...aa.#aa...a...a..b....a.a#a..aa...ab...a.........ba..b.a...a....a.a........a.a....a.....a.a.aa.....aaaaaaaa#a" ".a.a.baaaaa#..aaaa.aa.#a#...aa.a.a.b.....a##aa.aa...aa.a.aa..a.b.b.b.a...aa.aaab...#.a...aa..a.a.a..aa..b.aaa.....a..#a.aaaaaa#a" "..aaa.a...aaa##aaa...a.a...aa..a.a...a.a#.aaaab.aa.....bbb..b.b....aa...aaaa.....a...a....b.aaa..b.b......a..aaaaaa##aa#aaaaa#a#" ".aaab.a.a.##aaaa#.aa.a.a...a..a.aa...aa#..aa....a..babbd.ba....b.baaa.aaaaababb.a..a.a....a.aaaaa.b.a.b..b...#aaaa##aaaaaaaaa#aa" "a...aa..aaaaaaaa.aaaa.a..b.aba#aaa.aa.a..#a#aa.aaa....b.a.aab...b....aaa..ba..a.a...aa.ba..a#..ab...a.aab.#a#a.a..aa...b.aaaaa.a" "..aa.a#aa.#aa.aa.#.a.a.a....a#aaaba..b.aaa#..a.#a......a..a....b.b..a.a....a..a.........aaaaa..........ab.aa#aaa.aa..a...##aaa.." "aaaa.a....aaaa#a#a..#a..a.aa#a.bb.aa.a.a..a.#aa...aabb...ba...aaa..aa...b.a..aa..a.a.a..a..a.ab.....a.a..aa#.a.a...a.b..a.a.a..." "aaa#.a.......aa#.a.aa..a.a#aa..ab.a..aaaaaa.a.aaa..........a..a...a#.b...a..aa..a......a.aa.a.....aaabab..aaaaa..a.....aaa..a..a" "a....b...aaaaa.....b..b.b..a.......a..a.aaaa........bb.....a.....aa.a...a#aa..aa.aaa.#a.a.....b..a.a....aa.aa.a..a.a.a.a..a.aaa." ".aaabb...aaaa#...a....b...a.aa..ba.aa...a.a..#a.....bb.ab.......ba..b.aa##a....a..aaaaaa..b..b...aa....a.aaa.a......a#aaba...a.." "a.a.b..aa#aaa#b.a......b.a.....b.b..a.#.....a.b.a...bb.a.b.a.........a.aaa.aaaaa.aa..........aa.a.......#.a.....b.aaa....a#aaaa." "a#a....aaaaaaa.a.ab...bbaa..aa....a.aa.a.aa....a.b.b...ab.b......a.a.aa.#a.aa.aa.a.....baa..ab....b.a..aaa...a...#.a.a...aa.a..a" "..b..ba.aaa......a...a..aa.a.a..bbaaa.a.aa..a..ab.b.......a.a...bb.....#.aa.b.aa.a.aa....a.a.aaaa.a.a..aaa.aaaaaa.ab.abb.a....a." "aab..baa##.....a..aa...a.a..a.bb..aa...a...baaaa...a..a..aa.....b...bbaa#a.b..a..a.a........a.aa.a..a.........a.#...aa...a...b.b" "aab..a.#a#..a.aa.aaaa..aa...b....a#aaaa...baaa.b..a.....a....a......aaaa...aaaaaa.a...a...aa.aa..baa.aaaaaaa.a.aba..aab.a...b.aa" "a..aa.a#aa..aa.a.a#a#a..a...b.b.aaaaaa....aaa....a....a..ab.....ba..a.a.....a.#aaa.b.....a.aaa..aa.ba.aaaa.a..a..a..a..a.b.b...." "..a.aa#a......aaa..a.ba.#a.aaaa#aaaaa.b.aa.aa..aa.....a......a....aa.a.aaaaa.a.a.aaaaa.a.a#a.......aa..aa.a.aaaaaaaaa.....aaaaa." "aa....a.aaa.aa.a.d.....a.a.a.###..aa.b.a..#a..aaaa.aa#a.aa.baa..a..aa..#aa.aaa.aaaa.a..aaaa#baaa...aaaa.aa.a.aaaaaaa...a.aaaaaaa" ".aaa#aaa..a..aa....a..a..aa.#aaa..aa.a#a.a#a....a.a#a..a.bb.aa...b.a.a#aaaaa..aa#aaa....a..a......aa.a.aa#.aaaaaaa.a..a.a.aaaaaa" ".aaaa.a.aa...aa..b.ab..aaa.a#.aa.aaaa.a.aaa...aa..a......bba.a..bbaa.#aaa..a.a.#a#a...a.a..a......a.aaaaa.a.aaaaa..a.b..a#aaaa.a" "aaaaaaa#aa.aaab..b.aa.a..aa......aaa.aaaaaaa.aaaaa....b.bba.a...b.aaaababaa.a.#aa#.a...a.a..aa..a.aa.a.aaa..a..a..a...#a#aa.#..a" "aaaaa.aa#a..a......a.a...a.....aaaa.aa.aaaaaaaaa...a.bb..a....bb..a.ab..a.a..ba##aa.b..aaa..aa..aaa.aaa#aba..aaa...a..aa...aa.a#" ".aaa..aa.abaaab.aaa..aaa#a.a.aaaaa....a....a..a...abb.a...bb.b.b.....aa..aaaba#aa.bb.baa...a#aa....aa.#..aa..a..baaa..aaaa..b..a" "a.aaa....a.a.ba....aaaaa......aaaa...a...a.a.....a.b.......b..b.........aaa.aa#aa.....aa.a..aa...aaaaaaaa.ab.a.ba....aaa.....aa." ".aaa..a.aa.b..aaa.a..aaaa.aa.aaaa..a..a.aa#.aa..aa..a.....ba.baa.a.#.#a.a.aaaa..##.a...........ba.aa.aaa.aaaaa.aa.aaaa..a.a.#a.." ".......aaa.b.b.a...aaa....aaaa#.a.aa.a.aa#..a....a..a...........aaaaaaaa.aaaa.a#.a.aa.aa.a.....b..aaaa.baaa.aaa#.a..aa.a.aa#.aaa" "..aaaaa#...aaaaa..a.a.a#..#aaa..aa...baaa...a.a.a..a...aa...a.aaaa..a...a.#a.aaaa#..b.aa...b....aaa...aaa.aa..a...aa#a..a..a...a" ".a#.aaa.a...aaa..aa...a.a.#..a.a....b.a.aa....aa......a.a.aaa.a#....a.aa.a..aa.aaaab..a.......baaa......a#a.aaa..aa.a....a...aa." "aa..a.aa.aa#a..a#a..aaaa..aaaa.a.a.ba.a..a..a.a.baaa...a.........aaaaa..aaaa##..aabab.a.aaba.aaaa...a.aaaa.a..b......aa...a.a.a." "a.aa.a.a.aaa...##aa.a.#...aa..aaaa..bb.aa#b..a.ba#.ba.aa....b.....aa....a#a.aaaaa....a....aaa#aaa.....a.a..a..b.aa.aaa...aa.a..a" "aa..a#a..a#..a#a....a.a..aaaa...ab..a.a.aabba..aaa..aa.ab.....a.aa.a.aaaaaaa#ab...aa.....a..a....aa#aaa#aa.a...baa..aaa..a.a..#." "...a.a.a.aaa.aa..a.aabaa.aa..a.......baaa.b....aa.baaa.a....a..ba.a.a.aaaaa#a.a.a...aa..aaa.....aa#.aa##..a.b.b..b.aaaaaa.a.a..." "#a.a#aaa...a.b.aaa.b..a...aaa..a.aaa.a..aa.b.a.aaa.aa...a.ba..ab#aa..a..a.a......a....b...aaaaaaa...b.a......bb....#a...b......a" "aa##aa.....b...aaa.......a.aaa.aaaaaa.a..aba.a.aa.a....a..a..a..a.a...a.a..aa..ba..ab....aaa#aaa..aaaaa.a..bbbb...##a...a.a.baaa" "a.a..aa.aaaaa.aaa.b.a.a.aa#a.aaaa#a#a.a.aa..a.a.a#aa.aaaaa.a....aa..a..aaa.....ba......a...aba.bbb.a.#...bbbb.a.a.#.aa.aaaaaa..a" "a...#a...aa.a.a#..aa...aaa..#aaaaaa.a.a.aaa.a.a.#aa.aaa........a.a.b..ab...b......b.bb.a.aa.aab..a.aaa...........aa#....a...aa.." ".#aa.aa.a..aa.a....b..a..aaa..a.aa..a..ab..a..aa#a.....a........aa.aaa..aab.a....aa.#a#.aaa.a.b.a.a.a...ab..aa.a..#a.a.baaa.a..a" "aaaaa#ab..aa....b.....a.a#a..aaab..#b..baa.aaaa#a.b..b..b.a.aaaaa.aaaa.a.a.aaa.a.aaaaaa.aaa..a.aaa.a..b......a...aa.....a..a...a" "aaaa...aaaa..a..a.a.a..aa.baa.a..a...a........#..a..a........a..aaaaa...a...aa..a..a...a#..baa..aa..ba....a.#..aa.a.a.a.a.a.aaa." "aaa.aa...aab......a....a..a..a....aa...bab..a.a..ab..b...aa.a.a#.aaa.b...baa...a..a..aaaa...aba.a..a...b....aa.a..aa....aaaaaaa." "a..a.a.aaa.b..aa..aa....a.aaaaa.....a.ba.a.aaaa..aa.aaaa...aaaa.a.........#...ab.ba.aa..b......a.....a.a....a.a.aa..aaa........." "aaa.a#aaaa..a....ba...aaa..aa.a..aa#b.aaa.a#aaab##..aaaaaaa.aa.#b..a.b..a.a..a.b.b..a...b..b.b.aaa.a..a.....a#.a.aaa.aa..a.a...." "aaa.aaa.aa.....ab.....aaa.......aaaa.aa..aaa.a.aa.baaaa.a..aaaa...aa.aaaaa..#.a...aa.ab.aa....aa.a.....a..aaa..baa.aa...a#..aa.." "aa.a.....a...a.............a...aaaaa.a....a.#aa.aaaaaaa.....a..a.a..a.aaa.aaa.....a.aaaa......a.a.........#aaaba..a#a.a#aa.aa..a" "aa.aa#aaaa.ba.a.#..a#.aaa...aaaaaaaa..aa.a.a.ab...a......aaaa#....aa.a.....a.ab.a.aa.a....b...a.a..aa.a....aaaaaaaa.aaa.a..aaaaa" "aa##a.a.#.....aa..aa.a.a...aaaaaaaab.a.....a....a#...a.a.aaaaa.baa...a.b.aaa.b....aa.........aaaaa.a.b.........a..aa......aa..a." "aa##....a...a...b......aa..aaaa.a...#a...aaa..aa#........a..a..a.a...b.aa..bb...aaab.b....b.a.a........a..aaaa.ab.aa.aaaaaaaa.a#" "##aaaa.aa...a..b.a..a.a#.aa.aaa.a...a...aaaa...aa......a.a...a...b..ba.aa.b..a.ba..b.......a.#..a..a..aaaa.aaaaa..aaa##a.aaa.a##" ".#a........a....aab..aa..a.a...ab..a.........aaa.....#.#aa..a.....a............aa..aa.aa..a.a.....a.aa...ba.a...aaa.aa...a.aa#aa" "a#.....a.......aa.....aaaa..a...b.aa...a.b...a.abbb.a#aaaa...bb..b.a.a....a..a.aaaa#..aaa..aa.aaaaa.a...bba.a.aaab..a...aaaaaaa." "##..a.aa...a.....a..a.aabab...aa..aa.bab..a.#ab...aaaa..ab......ba#aa.aaaa..aaa..a...aa.baaa.a..aaaa..b...#......a##aa.a#aa..aaa" "a#aa.a...aa.ab....a.a....ab..aa..aa......b.a...a.baaaa.a...b.b...#.a.aa#a..aa.a.aaaaaaa..aa..aaa.a.ab....a.a...aaaaa..aaaa..aaaa" "..ba....ab..b.ba...bbb..aa..a....bb..b.bb...a...b.aaa.....b.b.a.a.a.aa..b.aa..baaa.baa...a.aaa..aa....a.a..a.aaaaa...aaa.a.aaa#." "aaaa..a.bb.bb.a..a.b..aaa....baa.....a.ba..aaa.b...a....bb.bbaaaa.a...a....b.b.aa....b...aaaaa..aa...b.abbaa...#...aaaa.a.aaaa.." "aaa..bb.bbbbbb.b...ba.a...b..a.abaaaa.b.b..aaa...a..b.bb..ba..a..a.a.a.a.aa.aaa#..a....ab.aaaa.aa...aaa.b.aa..##.aa.a.a.aa..a#aa" "aaa...b..bb..bbb..bb.a.........aaa..a....aaa.bba.a.a...b.b.ab..a.aa...aaaa.aaaaaa.a..a...aaaab.aaaa..a....a.aaa...aaaaa.a#aa#aaa" "aab.bba.ba......a...a....a.aa..a.....b.b.a.a..a....a....a.ba..aa....aaaa........b...aa.aaa.ab.aa..ba....aa.aaaa.a.aaa....a..aaaa" "a..ab..a..b.aa.aaa.aaa...#.aaaaab.a.....a.ab...b..........aaa..aaaa.#aaaa.b....a.aaaa.aaa.a...aa..aaa...a.a#aaaa..a...a.aa.aa#aa" "......a...aa..a..a.a...#aaa.aaa.b..aa.b.aa..a...aa.......b#aaaa.aa.aaabb..b..a.aaaaaaaaaaa.a...a..a...a..aaa.a..a.aa#a.aaa.aaa.." ".a.b..a..a..a.a.a.....aaaaaaaa.b..a..b.a...aa..a...b...b..aa.aa.a..#aa...bb.a.aa..aaa.aaaa..aa.a.......aaaa....a.a##.aaa..a.aaa." ".a..a...aab.........aa#aaaa...a..ab..a.a..abb.b......ab.a.a.aa.aa.a...b.b.aaaa#.aa.a.ab.....aa.a...a.aa.aa..a..aa...a.....aaaaba" "...b.baa.a.ab......aaaa.aa....b.....aa....bb..b....a...a...aaaaa.aa.a.b..aa.aa....aa.....a..aa.a.aaaa.aba.aa.ba#.a...ba..aaaa..a" "a.baba.aa.a..aa..a..aaaaa.a.#aa.b...aa.ba...a..aaa.ab.a..a##.a..ba.a.a.b...aaa...a.a..b.aab...a..b.a...a.#b..a#abbb.......#....a" "a.....a.aaaaa.b...aa.aa.a.aa...b.aa.a.bb.bb.....aa.a.ab..aaaaab..a....b..aaa#aa.aaa....a.ab.aa.b..a.bb..aaaa.aa...b.....##.b..aa" "a....aaa.ab.b..a.a...aa#aa...b..a..a....aaa...aaa....aa.aa.aaaa.a.a..a.....aa..aa.a...aa..aa.a..b.a.....aaa.a..ab.aaa.aaa#aaa.aa" "...a.#.a.a..ba.a....a#a#aa...ba...aa..a.aa....aaaa.aaaaaa#aaaaa.a....a.a.aaaa..aa#aba#a.aa.a.........a#aaaaaa.a...#a.aaa#aa.a..#" "ab.a#a..a.a.aaaa...#aaa...ab........a...a....aaa..aa.#..#..aa......a.a.a..aaa.aaab......a..b..a...aaaa##a....aaa.aaaaa#a#a.a.aa." "...#..ab....aaaa..aa#....a.....a..aaba..aa..a.a.aaa.a#aa..a#.aba.babaaaa..aaa..aa...#aa.a.........aa###..a.#.#aaaaaaa.a#aaa.a.aa" "a.#.a#.a...aaa..b.aaa.aaaab...aa.a..a.a..a.aaaaa.aa.a....b#....b.aaaaa..baaaa.aaaa#aaa.a##baaaaa.a.a.....baa#.aa.aa.a.#aaab...aa" "aaaaaa....a.aa..b.##..a#...a..aa..a.aaaaaa..aa.aaaa.a...b..ab...aaa.a.b...#a..aaaaaaaaa##aa.a....aa.aa...aa#..aa..aaa.#....aa.a." "aa.aaa....a#.a....aa.aaab.a..aa#..aaa..ba...aaa.a#...a....#ab...#ab.a#.aaaaa.aaaa#a.a.aa.....b.....aaaa.aaaaa.a..a...aa#a.aa.a.a" "aaa#.a..aaa.a....a#aaaab..a.aa#a.a.aa..b...a.aaaaa..a..a.aa.a.aaaaaa#.aaaaaaaaa.##..aa....bbba.b.a.aa.aaa##a..aaaa..a.aa..a.a.a." "##aaa..baa.a.aaa......b.a..ab.....a..a.aa.#a##a.aa..a.a...a..aaaa#.a.aaaaaaaa.aaaaaaa.a..a..a...a.a.aa#aaaa.aaaaaaaa.#aaaaaaaaaa" "a..a....#aabaaa.a.aa..a........aba.b.aa..aaaaa..aa.aaa...a..##aaaa..a#aaa#aaaaaaaaa.a...aa.a..b.aaa.aaa#.a.baaa#aaaaa##aaa..a..a" ".a.....a.a.aa.aaa.....b..aa..a#aa..aaa.aaaaaa.a.##a...aa..aa#a.aaa.a#.a#aaa.a.a..a...aa.abb....#aaaa##.aaa.aaaaaa.aaa.aaaaaaa..a" ".a.#.aa.aa.aa....bba.a.aaa..aa.a.aa.a.aa.a..a.aaa....a..aa##aa.aaaa#a..aaaaa.aa..aa.aa...b..a.aaa.aaa.a.aaa#a###.aa#.aaaaaaa.aaa" "aa#a#.a.aaa.b.a.......aa..a.a......ab.#a..aa.a.aaa.a.aa#.aaaa.#.aaaaaa#.a......aaa.aa....baa.a.aaa..aaaa#aaa.a#aaaaa..aa.aa..aaa" "aaaaaa..aa....a.bb..aa..aaaa...a....aa..a...aaa#...aaa#aaaaa.aa.aaaaa#aa..a#..#aa.aa..ab..aa.aaa..aaa#a#a.a#.aaaaaaaaa..a.aaa.aa" "aaa.....a.aa.a.......a.aaa.a.aa..aa..a.a..aa.a....aaa.aa.a#a#aaa.aaaaa..a.a...#a.a...a...aaa.a...aaa#aa.aa#a#aa#.aaaaaa#aaa#aaaa" "aa.....aaa..aa..b.aaaaaaa.aa....aa..a....aa.aa.abaaaa.a.aa#a#.a.aaaaaaaaa.aaaaaaaa...a.a..a......aa#aa.a#aaaa##aaaa#a..aaaaaaa.a" "a...aaa..a.a...b....aaa..aaa..aaaa.abaa.a.aaa.aba..a..aa.aaab.a.aaa...aa.aaa.aaaaa.a#aa...aaa#a#aaaa#aa.aaaaaab...aa.aa.aaa#a.aa" "a...#aaaaa..bbb..a.aaa...aaa..aa.b.a...a..a.a#......aa..aa...aaaaa..aaa.aaa#.a.aaaaaaa...aaaaaaaa###.aaa..a.aa.a...a....aa#a..a." "b.a#aaab..bb..a.aaa.aa..aa...aa.b.a..aaa.aaaaa.aaa.aaa.aaaaaa.aaaaaaaa.aaa#a.aaaa#aa.a....a#.aaaa.#a.aaa#.aaaaa..a#..a.##.a...a." "aaaaaa.b.a...a...aaaaa..a....aab..aa.aa.abaaaaaaa.aaaaaaaaaaaaaaaaaa.aaa.aa.aaaa##.a#aa.aa#aaaaaaaa.##a#a.aaaa.a.a.a.aaaaa.a..bb" "aa#a....aa.aa...aaaaa..a.aa.#a....a......aaaa......aaa.aa..aaaaaa#aa..a#aa.a.#a#aa.a..a.a.a#.a.aaa....a...aa.#aaa#aa.aaaaa..aaaa" "#aaa.b..a#a#..aaaaa#.a..a.aaa.bbab.....aaaaa.aabbbaaaa.aaaaaa.#a#aa.a.a..aaaa##aaaaa..a.ab##aa.#aa.a...a..aa##.aaa#aaaaaa..aa#aa" ".aa...aaaa.b..aaaaa.ab.a...b.b..ba.a.......a...aa.aa.a...a.aa.aaa.....a#aaa#aaaa.abbaa...a#aaaaa......aaaaa#.aaa#aaaa..a.a.aa#.a" "aa.a...#aa..aaaa##a#b..aaa...b.baa.a..aa.a...a...a.a..aa.aa.aaaaa....#a#a#ac##a..a.aa...aa#aaa#aaa.aaaa.a.aa#aaaaaaa...aaaaa##aa" "a....aa...aa#.#.a.a.aaaa.aa....aa.a.a.a.aaaaa#..a.a..a.aa.aa#a.aa..aaaa.a.ab..a.a.a.aa..a.aa..aaaaaaa.aaa##aaa####a...a.aa..#a.a" "...aa.a..#.aaa.baa...aa#aaaa...aa...aa..aa.aaa...a..aaaaaaaaa..a..aaa#..a...aab......a..a.a.a#aa...a.a.###aa.a.aa....a..aa.aaa.a" "a.a..a.a.a#aaa.aaaa.aaa.aa..ba...aaa.aaaa.aaa#..a..aaaaaaaa.a..a...aa.a.aaa...a..a.aa....a..aa....aa..a..aaa#a##.a....aaa#..a..a" "..aaaa.a.#aaaa.aa...aaaaa..b....a.aaaaa.a.a#aa....a#aaaaa.aa.aa..aa...aba...aab.aaa...b..a.aa...aaa....a##a#aaa#aaaaa.#.a..aa.aa" ".a...a.aa.#a.a..a..aaaaaba...aaaaaaaa.a.a#aaa.b...a#....aa#a#.aa#..#aaaaaa#.a#a.aa..a.aaaa.aa#.aa.a..#aa#aaa.#...a...b.aaa.aaaaa" "...aa#.a.a#.aa.a...a....aa.b...a.a##aa.aaaa..a.a.aaa.ba#.a#.aaaaa.aaaaaa##a.#a.aaa.a...aa.##aaaaaa.a.##aa#aaa#aaaa..bba#a.aa.aa." "aaa.#a..aa.#.a...a#a...a....aaaa..#..#..#a.a##....#.b.aaaa.a.aa.aaa.a.aaaab.#aaa.aa.aaaa..a...a.aaa.aa.aaa.aaa...a.b..a...a..a#a" "..aaaaaaa##a...aaaa.a..a...a.a...#aaaaaa#aa#aa...aa...aa.a.aa.aaaaa...aa...aaaaaaa.aaaaaa..aaa.#..a.aa#aa.a.aa.baabbbaa.....aaa." "aaaa.aaa.a.....aa..a..a...a.bb.aaaaa..aaaaaa..bb...aa.a..#.#a.a....a.a.aaa.a#.a...aa....ba.aaa.....aaa.a.a.a.........aaaaaaaaa.a" "aaaaaaa.a....ba#..aaaaa...b.b.aa#aaaaaa#aaaa..ba..aaa...a#aaaa.a.a.a..aa...#aa.a.aaa.a.baa#aaa.aa..aaaa..aa..a..aabaaaaa#aa##.a#" "aaa..a..a.aaa.aa..aa..ba.aa.#a#aaaa.baaaa.#aa.a..baa...##aa#...a.aaa...aaaaaa...b.....aaaaa.aa...a#aa...#...a#.aa.a..aaa.aaa.a##" ".#.aa..a.a.aa.aa.#ab..aaa..a....a.a..a.a.aa....b..a.a.a#aa..a.a.a....aaaaaa.........aaaaa.aaa...aaaaaaaaa.a.aaaa...aa.aa.aaa.###" "a...aa#aa....aaaaa......a...aaaaaa..aaaaa#..b.bb.a.a.aaaaa.a.aba.a.a.aaaaa...a.a..aaa.aab.a.a.aaa..a..a.a.aaaa........#.aaa##.a." ".a..a#aa...aaaaa.a.baa.a...a.a.aaa..aa.a#ab...ba.a.aaaaa.a.a..b...aaaaa#a..baaaa.aaa.a..a.a.a...aa..b....a.a##.b......a..#aaaaa." "aa..#a....aaaa.#aa.aaaaa.a#.a..aa.a.a#a##a.b..a...aaaaaa#.aba.b..a.a.aaa.aaaaaaba.aa.a#.aaaa.a.aa.a.aa.aa##a.a....a#aaa.#aaaa.a." "aaa##a.a.baaaa#aaa.a...a.#a.a.a....aaa#aa.b...b..a..#...aaba.....a..#.a.aaaaaa...aa.#aaaaaaa.a.a..aaa.#aaaa.a.b.aa#aaa.aaaa..a.." "aa#a.ab....aaa.a...baaa.a......aa.aaa..a...a..a.#a.a.aa.aaa.a...aaaa#a.aaa.aa.#.aaaa##aaa..aaaa.aaaaa#aaa#...aa.a.aaaa#a.a.#.aaa" "a#..a.....aaa.a.a..a..aa.......aa.a...a...a...aaa.aaaaa.aa....aa..a#a.aaaaa.a..aa#aaaaaa...#aa.a.aaaaaa.##..aab..a##aa..aaaaaaa#" "a..a.a...aa#.aa..aa..#a...aaaa#a.#.aa.aa.aaaaa...a.a..b.aab..a...aa..aaaaa...a..a..a.aa...#.aa.aaa##a.aaaa..a...#a#aaaaaaa#a.#aa" "a...a..a.aa..a..aa..aaa..aaaa#aaaaaa..aaaaa.ab.a.a..b......a...a......a..a...a.a.a.aaa..a#a.aaa#aa#aa#aaaa..a..#aaaa.a.a#a#aaaa." ".a.a..aaa.#aaa..a.a..a..aaaa.b.a..aa##aaa..a..a.#a.a.a.a..a.......aaaaaaaa..aa..a.a.aaa#a..##aaaa..#..aaaab.aaaa.aaaaa.a.a##aaaa" ".a...a.a.aaa..aaa......#.aaa.aaa.a.aa.aa..aaaa..a.aa..aaaaa..aaa..a..aa.a#aaa.aa.a..aa.#..##aa.#..aaaaaaa...aaaa.aa.a#aaaaaaa.a." "a.a.aaaa..aaaaaa#aaa.aa..aaa..aaaaaaa#a.a#a#..a.aa....#........ab.aa.a.aaab..b.aa.aaaa..a.#aaaa..aa#..a....baa..a..aa#....#a.aa." "aa..aaaaa#aaaaa#a.aa.aaaa.a...a.#aaa.aa.aaaaa.....a.aa...b.b..a.aaa..a.#aa..a.aaaa.aab.aaa..a.aa.aaa.a....b.aa...a.aa#..aa#aa#.." ".a.a.#..a#..aa.ab.aa..aa.aa.a.aaaaa.aaa.aa.......a.aaa..b..aaaa..aaaaa#a#.aa.aaa#.aaba#aaaaaa...a...a..aaa#.#aa.a.aaaa..aa.abb.a" ".a.aaaaa##aaaa...a..a#aaa#.aa.a#.a.aaa.a#aa....aaaaaa..b..aaaa..a..#aaaaaaa.aa##a.aa.a#aa.aa..aa..aab.aaaa.a#aaaaaaaaa.a.aa..a.a" "..aa#a#aaab.aa..#.a.#a#a.....#aaa#aaa.a.a.aaaa.a...ab....a.aa.aa.aaaaaaa.a.aaa#aaaaaaaa...aa.a.a..a..aaa.aa#.....a....a.aab.aaaa" )) (define blueish (list "64 64 2 1" " c None" ". c #0D5483" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" "................................................................" )) (define smoke (list "244 244 63 1" " c None" ". c #BBBBBB" "+ c #BCBCBC" "@ c #BABABA" "# c #BDBDBD" "$ c #BFBFBF" "% c #BEBEBE" "& c #C0C0C0" "* c #C1C1C1" "= c #C2C2C2" "- c #C3C3C3" "; c #C4C4C4" "> c #B8B8B8" ", c #B9B9B9" "' c #B7B7B7" ") c #B6B6B6" "! c #B5B5B5" "~ c #B4B4B4" "{ c #B3B3B3" "] c #C5C5C5" "^ c #C6C6C6" "/ c #B2B2B2" "( c #B1B1B1" "_ c #C8C8C8" ": c #B0B0B0" "< c #AFAFAF" "[ c #C7C7C7" "} c #AEAEAE" "| c #ADADAD" "1 c #ACACAC" "2 c #ABABAB" "3 c #AAAAAA" "4 c #A9A9A9" "5 c #A8A8A8" "6 c #A7A7A7" "7 c #A5A5A5" "8 c #A6A6A6" "9 c #A4A4A4" "0 c #A3A3A3" "a c #A2A2A2" "b c #A1A1A1" "c c #A0A0A0" "d c #9E9E9E" "e c #9F9F9F" "f c #9D9D9D" "g c #9C9C9C" "h c #C9C9C9" "i c #CACACA" "j c #CBCBCB" "k c #CCCCCC" "l c #CDCDCD" "m c #CECECE" "n c #D0D0D0" "o c #CFCFCF" "p c #D2D2D2" "q c #D3D3D3" "r c #D1D1D1" "s c #D4D4D4" "t c #D5D5D5" "u c #D6D6D6" "v c #D7D7D7" "w c #D8D8D8" "x c #D9D9D9" "..+++.@.#$$%%%#####%$$$$$$%%%%###########%%%$$$$$$&&&$$%%++$.@....@@.#..%########%$$$$$$***==--;;;;;;;;-;-===*$$$$$$#+%$$#..+#....+#####++...++++...+++...>,>>>>,@@@@@@@,,>>>,,@@.++#&##+#%#..#$#+%###############++..@>>'')))))))'>>>,@@.@@@@@>@+#." "@@@...@@@+#########%%%%%%%%%%%#############%%$$$$$&&&$$$%%##.@..+###%+.##########%$$$$$$&***==-------;;;;-====*$$%%##$*#.#.+####+..+#####++++####+..+++..@>,>>>>,,@@@@@@,,>>>>>,@...+#.@@.###%$#+#+++++++++++++++++..@@>>'))))))))))'>>,,@>>')'@@>'@" ">,@@@@@.##++###############%%%##############%%%%%$&&&&$$$%$#+##..#$&&..%+########%$$$$$$$&***=======--;;;;==*&$$$&&**%##%##%%$$%#%$%###%#########+.+#++..@,>,>>>>,,@@@@@,,>>>>>>>@@@.@.##.@.%$$..#....@@@@..........@@@>>)))!!!!!))!!!!~~~))>>,')'>," "'>>>@@@@....+#+################+################%$$$&&&$$%$#$%%##.$*&+.#########%%$$$$$$$$&**========-;;;;=*=-;;-=*$%$$$$%#%$$$$$$%%##%%##########++#++..,@>,,,>>>,,@@@@,,>>>')'>,@@.@#.+.@@#$$.@..@@@@,,,@@@@@@....@@@>>))!!~~~~)~~~{~)'>>'!~~~!))'" "))''>>,@@@@...++++####+++######+#####.#.#+#######%$$$&***$$$$%%##.#**$..#####%$$$$$$$$$$$$&***====-==--;--;]^]];*&&***$$$$$$$&$$$$$$$%###############++.@@@@@@@>,>,>,,,,>>>>'))'>>>,@@@....,@%%.,>,>>>>>>>,@@@@@..@@@@@>>'))!!~~{~//~))))!{(/~~~!!!!" "~!)))'>>,,,@@@....+#+....+####++#####.#.#+#######%%$$$&&&$$$$%%###+&*$#+#####%$$$$$%%%%%$$$&***===-=====-^___^-**===**&&&&&&&&$$$&&$$$%%%%%%%%#######++..@@@.@@>,>,>,,,>>>>>')))'>>>@@@@@@@,>#%#@>>>>>>>>>>>,@@@@.@@@@@>>'))!!~{/:(~)))~(<:///{~~~~~" "/{~~!)))'''>>,,@@@....@...++++++#####.#.#+++++#####%$$$$$$$$$%%####&*&&&$####%$$$$$%####%$$$&***==-===*=][_^;-=-];--=*****=***&&&**&$$$$$$$$$%#######++........,,>,>>>>>>>>>'))))'>>,@,,,,,>>.+...@>>''''''>>>,@@@@@@@@>>'))!!~/(({!!~(<}<(((((/{{{{" "(//{{~!)))))'>>,@@@.@@@@........+####+++#+..+++#####%$$$$$$$$%%###%&$$*$####%%$$$%%%####%%$$&***=====*=;^^];=-;];;;;-=======********&&$$$$$$$%#######++........@,>@>>>>>''''')))))'>>,,>>>>',.@..@>>')))))''>>>,@@@@@@,>>'))!)~((~)~/:||<<<<:(((////" "((((({~~!!!)))'>>,@@@@@@@........+####..+#..++++++###%%$$$$$$%%###%#.#&%+%%%%$$$$%##%%%%%%$$&&**====**;]];==;]]]]];;;------=====*****&&$$$$%########+++........@>@@>)))))))))))))))'>>>>>>''>))>@')>')))))''''>>,@@@@,>>''))!)/(~)~(<}}<<<<<<::(((((" "<<<<(({~~~~~!)))'>>>>>>,,@@.......++++@++@........+####%$$$$$%%##+#++#%%#%%%%$$$$%##%%%%%%$$$&&*****%=];**=;]]]]]]];;;-----=====*****&&$$$$%########+++........@>@@')))))))))))))))))''''))))~~~'')'))))))))))'>,@@@,>>''))!!{({)~:}<<<<<<<<<<<<::::" "|||}<((/{{{~~~!!)))))))>>>,@@@@@......@..>@........+#+##%$$$$%%####%%++##%%%%$$$$%##%%%%%%$$$$&&***%*-;*&*-;;;]]]]]];;;;;;======*****&&$$$$%########+++........@@>>')))))))))))!!!!!))))))!!!')))'))))!!!!!!!!)'>,@,>>''))!!~({!~(<<<<<}||||||}<<<<<" "||||<<((///{{~~~~~!!!)))'>>,,@@@@.....+,,.@....@@@....+#%$$$$%%#######+##%%$$$%%%%##%%%%%%$$$$$$$$$$-;*$====--;;]]]];;;;;;-====******&&$$$$$$%%######++........@.>),)))))))!))~~~~~~!))))!~!!~)!!))))!)!~~~~~!))'>>>>')))))~{(~)(<<<<}||||||||||}}}}" "|||||<<:((///{~~~~~~~~!)))'>>,,,@@@..+@+#,.....@@@@@+.+#%$$$$#%%########%%$$$$%%%%%%$$$$$$$%%%%%$$#&;=&&=====-;;]]]];;;;;-;-==***&&&&&$$$&&$$$%######..........@>.@)))))))!)~~!~~~~~~!))!!!!!!!!!!)))!)!~{{~~~!)))'''))))!!~({!{<<<<<|||1111||||||||" "1111||<<::((((//////{~~!!))>>>>,,@@..+.>>@.....@@,,++.###%%%%#%%%%%%%%#%%%$$$$%%%%%%$$$$$$$%###%%%#*;$&*=====-;;]]]];;;;-=;-==***&&&&&$$$&&$$$%######.........@@,)!>)))))!!~(!~/{{{{~~~!!~~~~~!!!!))!!~~{/(/{{~~!)))))!!!~~{:{~<<:<<}|||111111111111" "222221|}<<:::(((((((//{~~~)'>>>>,@@..+.........@@>.#@+####%%%#%%%$$$$%%%%%$$$$%%%%%%$$$$$$$#####%#+&&$*=**===-;;]]]];;;-==;-==***&&&&&$$$&&$$$%######....@@@@@@@>,>')))!!!~({~(/{////{~~~~~~~~~!!!!!!~~{(((((/{~~~!!!~~~~{{/<{:<<:<<||||111112222222" "3333321||<<<<:(((((((/{~~!))'>>>>,@@.........@@@@@@#@####%%%%###%$$$$$%$$%$$$$%%%%%%%%%%%$%######%#$#****===-;;;]]]];;==---===***&&*&$$$$&&$$$%####++....@@@@@@,>'))))!!!!~{/~>,@@@......@@@@@@>+..+#%####+##%$$$$$%$$%%%%%%%########%$%###+####%#&****==-;;;]]];;;---;-==****&&$$$$$$$$$$%####+......@@,@@@,>>))))))!~~~(~/(((((//{{(/{~~!!~~!!~{/(:<<<<:(((//(((::::(:(:(<(:<<}}||11|1233223333" "44444333121|}<<:::::(((/{{~!)))''>>>,@,,,,@@@@,,,@>@#@.+#####+##%$$$$$%$%################%#+##+++#+##%&&***==-;;;];;--;;;;-==****&$$&$$&$$$$%###++.......@@,@@,>)))))))!~~~~((~:<((((///((/{~~~~~{~{/((<}|}}<<<<::((<<}}}<<:<:<:}<}}|||1112233343333" "5445443341|2||<::::::((((/~!!)))'>>>>,')))>>,,,,,,@>##++#+++++##%$$$$$%$%################+@@##+..#..#+$&&**===-;;]]]-=;;;;-==*****#&=$$%$$$%%##++........@@,,,>>~~~~!!!!~~{{~@,>>'!~',)>'>+$#+.###++##%%%$$$$$%####+++##+.###+..##+++..+..#+#$$&***==-;]]]-=-;;--==****&*=&$$$$$%####+..@.#....@@@@@@)>@,>)!~/~!/{((!'{(:::(((((//{{{/((((::<||1||||}}}}|1|1211|||||}||||||||1333333675444" "5555555446521||}}<<::::<::({{~~!!))'!>>)~!~!)')),!),+#@@.##.@+##%#%%$$$%%%%%#####...@@@.#$%++++++++.###$$$&****=;;;;]];;;;-===****$#$&&$$$%####+...+++++..@@,@>,,'!!~)))~~!::{!!<|<(:<<((((((((((:::<<}|12133122221||333211112|111111122333355445555" "66666665444311||}}<<<<<<<:((//{~~~!!~){/{!!!!!)!>))@..@.+.+#$######%%$%##%%%####.#$$###%#...+++++++.###%$$$$$&**=--;;;;;];;-==********&&$$%####+..+#####+..@,,>,)!)''))!){!((~!~<<(:((/(((((((:<<}<<}}||2333|<}}}|2564433222231332222333443456666666" "666666665533211||}<<<<<<<<:(((/{{~~/!//~~~~~!)){@!))>>>...++########%%###%%%%%%%%&$+...@@+##.+..+...###%%$$$$$&*==-;;];]];;;-==*****==*&$$%####+..#######..@@>@>>>>'))!!)('((((:<(::::<::::<<<<}}||}|||123312433445334544333332333333344544555556666" "668866666654432||<<<|<|<<<<::((///(/~({{{{{~~!~)!'>>''>@...++.+#########%$$$$%$$*$###+++####+..@+.@.+##%%$$$$$&=**--]]]]]];;-=====*****$$$%###.#.########+.@>>@>,>>)))!!~!{~~{(<}::<<<<<<<}}|||||1||||1233|35433433343555634333333345555635656556886" "6877888866654321|}<<}:|<<<<<<:::<<(~((/////{~!~)~'>,@>,@....+..+########%$$$$$$$##%$$$%###++#@......+##%%$$$$&&=*==-;]]]]];;-=========*&$$%###+%.########+.@,.>>@>>)))!!~~/~~~~/::(:<<<<<}}||1112321111233664212333455576645433334556555646666566886" "8779777786665331|}<<<(1<<<}}}<}|}<({(<(((((/~~{!~)'>@>>,.@......++++####%$$&$$$&**&$$%%%%##+..+.+...+##%%$$$&***====;;;]]];;-=----====*$$%%####$@#######+.@>@+@>,>>)))!~{~({~~~/<<(:<<<<}}|122333443211233333333343456876866644446666666666666686886" "79999999866865332|}|:<|<<<}|}}||<:(({:<<:((/{~{!{)'>>>)>@@.@....+++++#+#%$&**&&$&**$$%##.....++.#+@#+##%%$$&****====-;;;];;;-=;;----=*&$$%###.%#.#######.@.....>>>>'))!!/~({~~{(|<(::<<}}||233446554322233333444566888788966856456688666666666686786" "990ab09789965531112}<|<<<<}}<||<((}}<::}}<<((/:)/'>>''>>'>@@.........#+$%$&******&$$$$$$$%#..+++##.$.%%%$&&***=====----=-];;-==-;];====**&$#+%$.####%%#+.+#.,>>>>>')))!~(!:{~{((((<<:<}}|12335667466533333445555544668877988758466867888666666688998" "990000aa096799832|<}2}}}}}||}||<(}1|||<<}|}<:(/)/~)!),..@'>@@..@@..++.#*#$&******$%&$$%####+.+####.%.##%$&***=======-*--*];-==--===-;=$$%$$&*$.#########.+#@>>>>>>'!~~~{{!:((::/~~/}}:}||333458974986544443454666677879777777695666888886666668998a7" "990acb099900844665543}||||||}}1}(}|<:}|}<}<<(/~{:({~>>))>,',@.@,>>@@.%$$+$&*****&$$&*&&$%%####+##+.%@###$$**==========]]-=-==**=-;;-*&*=*$%##..$########..#@>@@>'>>'))!!){<<}>)'~,>>..@,,.#%%**%#$&&&&&&$&&$*&&&$$$%%####.#+@#+#&$*=====----=-=*;=========**=--****&$%%%%#######..%.>@@>,)!)'>)~(<}<<}/(<<1<}|||3664456459a978666665566666688799999a879588488668866666868989" "aaaabbbbac099766533211|1|||||}<<<(<<<<<<|1|}}|}({~!~)')'>>@>..@,@#$$$*&##&&$&$$$$$$$$$$$$$%%%%$%#+%..@.$*%$&*=---;--======*****====*=--==***&$$$%%%%%%###...@,,>>')~~~/::(:((<((<::<<1}13653233569c9777786666666668799999900899995287666666668889999" "bbbbbbbaacb09786643332211|||||}}}}:|<<<<|12|||>>@.@,.$%%%$$%#$$$$$$$$$$$$$$$$$%%%%##.$#@.@$*&##%$*======---;==*****======--===***$$$$$$$%####.@,@>,>'')~(/(<((((((<(:<|<}1|13651345880c09999777777777779999900c88a9053379997868888887609" "bcbcbbbbcdeb0978654433321111|||<:<<:<}<<|12|||<(~~~))))>@,)>,.@,.$#++#$%#$$$$$$$$$$$$$$$$$%%###++$#..%$#+%*=-;-=-;-=---==&*&&**===***=-====**&$$$$$$$##+...@,@,''')~(/:<(((:((((<(/:1|11365268897aeba0009999999999999900abb68b963678633466656888899a" "bcbcbabcecccb7786655543321211|}<<:<<(<|11311|||({~~))')!!))>,@@>.#.@@.##.$$#%%%%%%%%$$$$$#%**$@@+$$#%$#..$=*&*=;-**======**$*&====*==&*-===**&&$$$$$###+....@,@')~~/(((:<(((::((<}|}||12265389aa9adbaaaa0999999999999669ce0668548996368765677888899a" "bac0accc0099ba986655544533311|}<<::<}(<33222|||<({~)))))'))>,,,>.#,@@@+#.%%#########%%%%%##$$$+..#$$$#@@+*$%$$$$&*========&*$=*=**;]];=*====**&$$#$$###+...@.>',>{//(:::}<<:::::<<<}||122654990ca0dcbbbaa0999999999097990ba75546ab958977900788888790" "0c0abca9bdc99b086655544633211|}<<:<(|((11|11}(((((~!!)))!)'>>>,>@.>@.@.%#+######++++######+$*$#..#&&%.,@#&%*===**==========&***&=;-==;;&*-===*&$$#$#%##+..@@@@),>{/{(<:/{:<<<<<<<}||||113645099cb0cccccbaa0000000090a7689aa94459ca869856679868886899" "0aa09889cddc89086655544523|11|}<<:<:}(<|<<:}>>>'@@>..@.%%.######....######.###+@.%$*$+.+$#&***==-=========***==;];=***]-*--==*&$$#$.###+.@@@@,',)~!~~((~/<<<<<<}|}}}||113848979cc9adccccbbaaaaaaaa00ca990c08546709576566666668886879" "9aca86689acc089a8865433323|1||}<<:(}<(}<:(::((<((//{~!!~{~)>>>')@>,@.>@$$..##+...@@@.+.....@,.++#%##$$#$%#&&**==============&&;;;]]-**-;**-==**&$%#.##+..@@,@'>@!~!!~{/(<<<<<<<}}132|||14847777cb89cebccbbaabbaaaaaabcea0098976685695566666668888799" "909990aa0990a867966544333311||}<<:<:(}}<:(::((:(//{~~{~!'~~~'''@'>,@@>@$&#.#...@@@,,@.@@@@@@>@+###.+%$%+.%$$*==========---****=***-;;--;]-=-=**&$##+#+.@@@@,>,@)!!!~~{/(:<<<}}}||<<123134268779cc87becccbbabccbbbbbbbceb0979a07667966655556666668879" "7999a09990a989989866544533321||<<::(<<((((((::((((/{~!~/)')~~),)'>,,,>>+$+@..@@@,>>>>,,,@@@,',###...##+..%%$$****======----=****=====;]=-;==***&$#%#++.@@@,>,,')))!~~{/((:<<}}}<|1}<|332|686879bc07becccbbbcccccccccccdc979bcc090a066666666666666887" "00979999999980b78966654633332||}<<<(<:(/((((::((((((/{~~(!>,>,!)'>>>>@>,.,,.@@,>>>'))>>>>>>>)>##..+$$$+.##$$%#%&*=======-====-========-*$=-**=*&$+$#...@@,,>>>''>')!~{/(((:<<}}|}|3}::<|56566779cc0cebccbbbccceeecccccec99acb979aa885689978556666687" "7779999999908a09798866565|331|||<<((:<:////(((((::::(/{/()'>>~~)'''>>,>>''>@@,>>)'!)!)>>>>>>>).##%%%++%.###%#$-=%=======;==-;-=======*;$*&===****%+&.@.+@,@@@,>))')!){/(((:<<<}<<}|<(<<466688779acddecccccccccfeeedecccf99009bca9b886676459566666869" "9787999999977779798886686|}<<22|<<:<:/~(///((((:<<<::(((~))'>{!)))''>,,>>>,@>>>'))~!!)''>>>>').+##@@.++#++##%==-$**====*;==-;;======*****&=*==**&#+&$$$.,@@@@,>@,))))~{//((:<<<}||}<|<<55488879990bbbbccccccccdccedecccf0990egfca0088973649866666769" "a9999999999778897987886862}<23}}<<}<((({://((::<<<<<:<({/((~){~)!))''>>>>>>>>'))!)~~~))''''''!@.#.>.##+##.++$&$;$*******;=&=--=====***$=**=*==**&#.$&$+@+...,@.@>,!))~~~{{/(:<<|}<|13|}555688799990aabcccccccccccedecccga09cgcbbc0099966949766667967" "cb009999999989999979786664|<|31|}<::(({/{:/(((:<<<<<:::(/~{/~~/!)!)))))')))))))!!!~~~)))))'''!@..@>.+##+#%#$*$%=&******$;=%&*=-==*****&=****==**&$+#$&%.....+.@.@>>!)~!~~~{(:<<<}||||323666687799000acccccccccccceeccccgc9acfeb0ab799669a69768889069" "caaaa000999779900999786563}<(<}<<<:((//({({/(((:<<<<:((/{{~~/){~!!!!!!))))))))!~~~~{~!))))'')'.+.@>@.++.%=*&###=&=****$&=$%&**==****************&$#%***&%#++.....@>)))!!~~/((:<}}||||2426566689999990bbcccbbacccccccccce079bdcb99c94360ab6977777998a" "99acdc09099999900999786562<<|||}<<:(//{({/{{/(((:<<<:((/{{~{(!~{~!!~{~{{~~~~~~~~~{~/~~!)))''',@@.#+@@@.#$&$#+$$*$*****%*$&**&$%$**&*************&&%&**$######+++.@@>>''))~~/(:<<}||||24256688909abbabcccccabacccbcccccb009990bbbb97669b9069777779809" "990cec99a9999900099978646||22|<::((//{~/~{~{{/(((:<:(((/{/{/(!~(~~/{!'!~{{{{/{{~~{~(~~!!))'>>>'',+###+++%$*%#$%*$*&&&&$&$****$%$**$**&************%**%%%%%%%####+@.@@,>>')~~/(:<}||||2414868998689abbbbbba0a0bbbbbbbbbbccca9777999964899069777777999" "909beea907909000099976536|23|<<<(///{~~{~~~~{{/(((((((((///(/)~((((~~(/~)))!~({{{{{(/{~!!)''''>>>>,@@.+##+$*$%%*$*$$$$$%$$*&*&%#&*$**&&&&&********$-$#&*&$$%%###+....@@,>)!~{((<}}|||33|387908600986870baa000bbcabb0abbbaccccba99799869a089888888999" "9a0cce09a0990000999986554|32|}<:(/{{~~~~~~~~~{{{{//((((((/(~~{/(:<(!~<<({{(:{({///(({(/~!))'>>,@>>@.+######$*&$*$*$$$%%$$&*$&%#+$&%$$$$$$&&&&&**=*&-$$**&$$$$%%##++++.@@>')!~{(:<<}13|134690958bc077ab9b00090a9ccb000099990a099788887867779886668779" "99acbb0870990000999986662341||<:(/{~~~!~~{~~~~~~~{//(((:::((<<<(/((~~~{/~/<:{(/(((((!{~))!)'>>,,@@..+#######$==*$&$$%%%$$&$$$%$$&=*$$$$$$$$$$$&**&==$****&$$$$%%%####+..@>')!~{((<<|||26666798668868ba9a90999a79a79a09777799777866666775670866666877" "99a879a09900000099998666263|||<:(/~~~!)!~{~~~~~~~~{//((<<:(<(/::(:<(((/{{~{~~:(((((:)))~{!)'>>,>,@..+######$#%*#&$$%%#%$$&$$$=-*$$$$$$$$$$$$$$$&&&-**==***&$$$$%$$##%#+..,>')!~~/(<<<223666876776664668a99999066670978888879888666666699899666666687" "700669ceca0000009999866346311|<<({~~~~)~~{{~~{~~~~{{/(::<<}:(/(<(:{~!~{((({~(((//(<(~)~((~))''>'',...+#####$%+##$$$$%##%$%$$$;-*%#%$$$$$$$$$$$$*$=*&*=====**&*&$&$%####...@>))!~{(<<||||3868543458866699779998668cb988887999686666666680098655558667" "90a99bbbba0000009997796685321|<<(/{~~{{{))(/~~~~{(:::(::<<:((((}((~~~~~{{(::>>@...+####%+#$$$$$$%%#%$#$$$**$$$&&&&$$$$$$$$&$=*&*=---===****&$$**#+#+..>)~~~~{(:<<}||2666333344579708898976868bb099886677666655555699666654448667" "90cbcca0ba0000009999069785321|<<:(//{/~~>)~~/~)!//{~~{::(::((((::(~~!~~~{:<(}@...###++##%$$$$$%%##%%$$#$$$*****&$$$&&&&$$=***=;;;;-===***&**-=&#..+@')>>>)~(/(:<}}13642223333897a968996aa8588544455338666544445688665543336687" "90efda0aba0000009990997853321|<<:::~:(:(!{~!(~!~{(/)~((((::(((((<(!!)!~~{(/{(<:::(:((:~)'')~//{>@)>@@..####$&%$$$$$$%%###$%$++#******&$$$&&&&*****==-;;;;-==*;**$$=&&&..+.>)>@>!~~{/(:<<|153|1|12236556999789990633346799428655444443224644333335687" "00cde0aaaa0900000907098653321|}<<(>@@..+##+%+#$%$$$$$%%%##$%%#+%*=*****&&&&**$=&====---;;;---*-=&**&$#$#.+.@>>@@!)!~{((<<<|321||11234568598697887953467864236333332332653433322334669" "9779cc90aa0900009099078664331|}}<((((/////(/{~!!!~{/~((/((////{((/!!~)!~~/(:<''>@@..##.+$.#$#$$$$$$$%%%$&&**$$=-==*********=*====--=-;;---===**&$$##+##..@>>@)))!~/((:<|11||1|122356885388676876545685|23322222233|421322211233667" "aba99eeeec0900099a9a998865432||}<::(((////((/!~~~!!(~////{{{{~~{(:~!!)!~~{/((|<<|:((((::((((~)>!'@@@..+++.$**%#%%%%$$$%#%$##$**%$$$*******=*-===--=====------===*&$$%#+##+..@',')))~~/(((<|2|||||1233447689556666765564}|43|11111122}<<1311111123887" "acc969cabcca00099c9c9988654321||<<:((((((((/{~~~~~){~/{{/~~~~~~~~)~!))!~~~/(/<<<|<<(((:}<:(:('>!)>,@..++#.@+.@+%%%%$$$$#..#.#&=*****&*****-*]*;=---=====-------=*&$$##+##+.@.>,>')))~~/((<<(}|<|||123336869564566986656|<3211|||||}23|232111||12270a" "0b97899799abaaa00baca99786543221|}<:(////(((/{~~!!~~~~~~!!!!!!~~!~~!!!~~~~~/(<(/|}(:/(<<:/~~~~'>>,@>,@...+...#$%$$%%%%#+###+%*=*=;--**====--]-;;;--======----==*&$$%######+..@,>>''))!!~/((<<<<<}||123365366343468531134|<}}}||||11|1|||||||12236799" "6560bca9b0abaaabcaeca99976653322||<:(////(((/{~~~!~~~~~~!!!!!)!!)!)))!~~~!~{(:/~<|<:<<}|:{{~!{~))'>@@.++..######%$%%%%+#&&***&$%*-=-=*===-=]=;]];;--=====---===*&$$%#######+.@@>>>')))!~{((:::<<||1123463146436568522223321||<<<<}||<<<<||||11136645" "390a0ccb09ccaaabccec0009786643321|}<(((//(((/{{~~~~~~~~!))))))!))))''')))!~{{(((}1|}}({(:(~~~!)'>>,,,,,##@..+++##%%%%%#%&=*&%#&$$*-;*$===--;-]]];;;--=========**&$$%%%%%%###..@,>>>'))))~{{/(:::<}|1233653676653|253111||||<<<<<<((||||1||||||125532" "609099bc089c000baecb0009986643331|}<:(((((((//{{~~~~~~!!)))))))))''>>'))))~~~((<<<<}////{((/{~!'>>,@@@@@$###$$%+#%%%%%$#%=$#%&$*&$=;=&==-=;=]]]];;;;-========***&$$$$$$%%###+.@@,>>>')))!~~~/(::<}||12366665462222243332||}<:((((<~(((((:||||||12562" "697a09ac999c909bbbbbba09766643321|}<:(::((((((~~~{/{~~~!))''')'''''>>>>')))!~~{{((:<{<<((({~{{~~!)'>>,>.%&#########%$$$$#&&#$&$&&$-==$==-=;;]]]]];;;---===****&*$$$$$$$%###+..@@@>>''))!!!!~{((:<}|||123333334|43333212331|<<<:<<(~!{::<<<|111111365" "607990b09a90aaabbbbba097866543211||<:<<:(((((({{{//{~~~!))''')''''>>>>>>')))!~~{{{((/,@@@##$#.####%$###%$%$$$$#$*&&$*=&***==--]]]]]];;;---==***$&*$$$$$$$%%###+..@@@>>''))!!!!~~/((<<}|||12333334|3|||232|<<<<:(/(/~~~(:(::<<<|11112256" "4090ab07beb8abb0aaaa009766553311||}<<<<:((((((/////{~~~!))''')'''>>,,,>>>'))!!~~~~/({((:(~~//~)!!)'>>,@#$.+###$$#####%%%#%*#$$$$&=*$$;***;;]]]]]];;;---==**&$$$$$$$$$%#####+..@@@>>''))!!!!!~{/(:<<}||1123333422||2||32|}||<<((((~~<(((:(<}}|1111356" "28799978cdc60c9900a009986543321|||||}<::((((((((((/{~~~!))'')')''>>,,,,>>>')!!~~~~{((//{{{~~~/{!'>>@@.,+#.#%%%%$%####%$#+$=$&&**==$%$;*&--]]^]]]];;;;--=***$%#%$$$$$%#####+++..@@>>'')))!)!!~{/(:<<<}||123333422||11|}|21}<:((/{://:/((::<<<|1111364" "3589755679870b9099a99976643211|||}:(<<:((:((((((((/{~~!)))>')>)>>,,,,,,,>'''))!!!~~{{{{{{~~~:~~~)>,@@+@+.+%$$$$%#####%%%#&&&$$*-;-=*--&&;=]]]]]];;;;;-===*$$$$%########++...+..@@>>'))!)!))!~{/((<<<}|||12333321|||||<3||}:(((({<((((<<<<<<}|1122463" "69bb9669999999699997788653311||||}|1|<:((:(((((((({~~~!))>>')>',,,,,,,,,,>>'>>)!!!~~~~~~~~~~~)'!)>@@@..++##%%%%######%%#+$$#..%*=&&*****;;;]]]];;;;;-===**$$#..#######++.......@@>>'))))~))!~{/((<<<}|||||333321||||}<<((:(((///(((((<<<<<<}||111353" "5798689997886888777866654321|||}<<<<:::((:(((((((/~~~~!))>'>,')>>,,,,,,,,,,,>')))!!!!!!!!~~{~~~))>,@@@#.#########++##%##.$#..#&$$$&***=--;;]]];;;---===****$#########+....@@..@@@>>>)!){/~!!~{/((<<<<}||11333321|||}<<(<<(((/{~(/(((:<<<<<<}}||1|342" "23335666666666767886666533311|<<<:<:((((((((((((({~~!!!))'',>)!)>,,,,@>@)>>@,>')))))))))!!~~~!!!)>>,@@.+########..++#####*$%%$$%$&&&*====;=;;;;---===*&&=*$$%###++++++..@@@@@@@@@,>)!)~(:(~~~{//:(|||:<<|3223311||}<<((((((/{~~(((/((::<<<<<}}||132|" "|235555566666365666666643452}}<<:(::(((((((((((/{~!!!!))))>>'''>,@@@@@'.',>)>')''''')))))!~~~!)!)>>,@@.########+...+####$$$%#+#%$$$&***-=-=-;;--=-=*&*=**&$$$%##+++++...@,>,@@@@@,>))~{/((~~{{//)>@,@....@@>+,>''))>>>>>>>>>'))))))))'>>@@@@.###++++.@.++###%#+######%$$$&&*=*-*=---====**=*$$$$$%##+.......@,>>>>>>,,>)))/~~~{~{{/((<(}|2|1|}|||11|||}}<<:(///{~~~~{{((/(((:::::<<}}|}|2" "|||11111222324426843333333113}<<:(::((/{{{{{{{~~!))))))))>)),@@@.......@.+@>)'>>>>>>>>>>>'''>')'>>>@@@@@+##+++.@@.++#####%$%#+###%$$$$*$&=$$======***&#&$$$%##++......@@>>>>>>>>>')>~{~~~~{//((((<:(}|1|<<||||||}}}<<(/{{{~~~~~~~((//(((:::::<<}}|||" "||||||11|11234236864333212|21|}<<::(((//{{/{{~~~!)))))))!,)),@@..++++##+@+%.@'>,>>>>,,,,>>>)'')>>>,@@..#@.....@.@+.+++###%######%$$$$$$%&$##%&====*&*$%$$$%##+.@.@@@@@@,>>''''')''~>~{~{{{//////(:}(/:<|<<<}}|}}}<<<((/{{{~~~~~~{~(((((:<(:(::<}}}}<" "}}}}||||||133|3666454311|1|21}<<<:::(((//{/{~~~!))))))'')'@)@@...#######.#%#+,,,>>>>,,,>>@>~))>>>,@@..@+#@@,,,@.@+.++++##%######%$%%%%%*#..+%%&==**&&%%$%%##+.@@@,,>>>>>>'))))))))~!)/~{////////((<(//(}<<<<<}<<<<}(<|<({~~~~~~~{~!~(::<:/:/(:<}<<<<" "<<<<<}}|||12<34332|14||||1|21}<<<:<::(((//{~~~!)))''''>>>>>.,...+###########%+@@,,,,,,,,,>>))@,>>,@@..@+$%#++++@..+++++##%####+#######$+...+$$%****$&##%%##+..@,>>''>>>>')))))))!!!!~!////////{//((/(/~/<::<<<<<<<<<}|}{//~~~~!~{~''!~~{{(((/(<<<<<<" "<<<<<<<}||1|(|322|:(2<|||||21}<<<:<<:((((/~~~!)))'>>>>>,,>>@@..+#%%%#####+.+$$@@@@@,,,,>>>,@)>,>>,@@..@##%.@@@,).@+++++##%####++######&+@.+$*=%*&**$$#####++..@,')))''''))))!!!!~~!~~{{///////{{//((<(!!<:(:<<<<<<<<<(<(//~~~!!!~)')~((:<}{(/(:<<<<<" "::((<:///(}|<<<<(//(|<<<<<||}|<<<<:::<({({~~!)!~))''>>>>@@@,.@#.#%%%#####+#+$$.@.@@@,,>>@@@@,>>>>>>,@@@>,@..@>''@....++########+$&&*$##%%#$&*=%**&$$%%%#%#+...,''>!)))))))'))))!~!~!~{~//////{{{{{{/((~)((/(<<::<<((((((/{{~~~!!~{{{{{(:<}://(((:((:" "((((:(:@@@@.@.@###%%%###%$%%%$#%++#+.@@,,@@@@,>>>>>>,,@@..,>,@..@,,@@@..###+#+.@##.$%.##+.#+%$&%&&$$$%%%###+..@>)>>~)!!!!!!)!~{~~{~~~{/{(((((//{{{~~~~{)~~(((((((:(((((((//{{~!!!!)!~{/{~{(::((((((((" "/~{(/{<<(<|<<<:<|({:<:::<<<<:<::::<}}<{!({~~!!)!!)'@>>,@@@+@@.+%#%%%###$$$$$$..####...@@@@@@,>>>>>>>,,@,@@@>>>>,,@@@@..#+#++.@.#@@%#+%###.@%&#%$$$$%######..,'!)'>{~~~~~~~~~!)~{/{{///(((((((///{~))!~~<(~((((((//////(/{~~!))))))))){/((((/{/(//{{/" "{~~(~~:{(<:<<:((>),@@@..#.@.+$#%%%###$$$$$#$%##+++...@@@@@@,>>>>>>>,,>>>>>,,@,,@@@@..+.+..@,#.,+++####%#.$#+%%$$%%###+#+.@>)~!),~({{{{~~/!~/~~(//(/(:::::((((/~~!!~~~!/:{{((//{~{{{///{~~~!))))))!~~~{{/(/{{/{{~~{" "!~~(~!/~:<(<<:(((((//((:::::((////:<<<:{)({~)))))'>>@.>@......+##%%$#$#$$&%&$$$$+$$#+++...@@@,>'''')'>>>>''>>>>>,@@@@......@@>@..#..#+###..++###%%##+##++.@@>)~{{~):(/////({~~~{((/((::<<<::(((~~!~)~!~~~~(~~/{~~~~~{/(((/{~!!!)))))!~~~~{{{~~~~~~~~" "!~~(~)~~<<(::((/(({{{/((((((//{///((((((~!{~)))))))>>,@.......+##%%$%&%$$&$&$$$$$#+####+...@@,>>')))))''''''>>>>,@@@@.....@@@>@@.+,@#+###+..########..#..@@>>')~{/{~:(((((((/~/({{/(((::::::(((~{~~!~!!!~~~(//~~~~~~~{////{{~~!))))))!~~~{{{~~~~~~~~" "!~~/!~{~{:<<<:(((/~~{{//////~{~{{{{{{{/((){~)))))')),@........+##%%$%*$&*$*$*&&&&$$$$%##+...@,>>'))!!)))))))'>>>,@@@@.@@@@@,,'@,,..@@.......#######+..+@@@>>'))!~/:/<::::(((((/{{{{/(((((((:(((~(~!~!~)!!~)){)))!!!~~~{{{~~~~~!)))))))!~~{{{~~~~!!!!" ")~{~~(:::::(:(((/~~~~{{{{~{~~~~~~~{{{{/{(~~~))''''>>@@...+..@.+##%$$%*$$&**$****$&&*&$##++..@@>>>)))!~~))))'''>>>,,@@@@@@@@>>>>')>,@@.....++.++++#+.@@.@@,>')!~~{{:(<<:<(((///{~~{~{/((((((:(/(~({~!!~))!!!~))'))!!!~~~~~))!!))))))))))!~~~~~~~~!!!)" "~{~{((((:::::((/{~~~~~~~~~~~~{~~~~~~{{//((!/~!)))'>,@..++##....+#%$$%*&$&=$&&*****$%$$%##+..@@@>>)))!~~>)~~))'>>>>,@@@@@>>')>>!))>,,@@...........+..@,@>,>'))!~~{/(!~~~~!~~/{~~~~~{~" "!!~/{{/(((((((//{~~~~~~~~~~~~{~~~~~{//(/((!//~)))))>@@.+###+..+##%$$$=&*-*$=*****$$$$%####+.@@@>>))~~~)>')!~~!)'>,@@@@,>>>,,>))'>>>,@@@@@@........@@,>,>>>))!~~~{/(<{<}<(((((/~~~~~~~{/{{//~/(/)~!>)~')))))!~))))))))!))))))'!))'@>)~{{~~~~~~~~~{((~" ")~(~~{((((((//{{{~~~~~~~~~~~~{{{{{{//((((:!!/{~~~)>@...+#####+###$$%$$#$-*$=****&$*-&$#####.@@@>>))')~~~({!)))!~)'>>>>>@.@@>~'>''>>,,@@@@@@@@@@@@@@,>>>>>')!~~~{{/(<~/<<<<<(~~~{~~!~~~~~{{{~/(~{~~,'~'))))!!>@>>''>')))'>>>>',>)~!~{~)!~{((/(((((~))" ":<{/////((((///{(({~~~!~~~{~~{{////(::<<:())~~{)>>'>'@+##%######%$%$%%%$*=*&&*&&*;-&$$$%##+..@@>',!~~~)!)!~)>,@@,,@@@@.+.,!~))))'>>>>,@@,,>'>@>>@,>>>>>')))!~{((((((~~(<)!!!!!'@@''>>>>>>>>>>>>@>'>''''!~)'>>)!~~{{{!))~" "::{/{{{////////(~)({!~!~~{/~/{/(((((<(//{!)'>>>,,')@....#%##%#%%$$%&%$*$$*--**=--=*%&$$%##++..@>@)))))!)))!!,@>')))'>>@@@>~!)))))''>>,@,>)@@'>>>>>>))>))))!~~{(/~~~!)~~~~!~(({~~~~~~/{!~~~~~/~{!')~)@>)'>@@,')>@@@@@@@,,,>.,,@,,>>')~!>>'~/(((/{~~~{" "::{/{{{////////~/(~/~~{~~{(~({(((((((~//{!)>,@@,>))>..+###%$$$$$&&$&$***&&*=--==*&$%&&$$####+.@@@!>''))))))!>@)))',,>))'>'~!))))))''>>>>>,')@'>>)'')!'~)!!~~~/{!~~{~!)))'){(:(~~~~~~~~!!!!!~~~~)'')!)>@,>>>')),@.@...@@@@@@>.@@,>>>')!>>~{~~~~(<<({/" "::{/{{{/(((////({~(~{!~~~{(~:{(((((<(~<<(~'>>>@@,>>>@.+##$&$$$&**&*&****=*&$$$&*&*&#*&&$%####..+'>>>>>''''')),))>>>>>@>))'~!)))))))''>''))'>)))))))~{'{)!~~~~({~(:(/!!!!))!{((/{{~~!!~{!!!)~!~!))'>')!))))'>')@..........#,@.@@@,>,,>)!>~{!!~~~~(:(/" "(<({~{(~~~{(({(/~~(){!!~~~:{:(::::(::{:(~'')'>@+#++##$%######%*******=*=-=***=*&$&$#*&$$$%###..@>>',>>>>>>>>)'>),>>,,,,))>)~~)')!>)'>))'))>'!'!)))!~(!~!~~~~~((~(({~~{{~!))))!!)~{{{/{({!!!!!!)')'>>>'>>>''>>'@......+....,....@@,,,>)))'~)))~~{/:(~" "~(:///~~({/{~~(/~{/!~!!!~~:/(::::::(:{~~))~~!>.++#%%$##$$*=*&#**=***=*=;-==-;;;-=*&$**&$$$$%#+...>>,>>>>>>>>>)>!>>>>>>,)',>!~~)!))!)~)))~!))~'!)))!~(~~~~~~~~/({{{{{(<(~))!)))!~~~!))'~/)))))))))>>>>,@@.@@,,,@.+++++++++##@@..@@@@@,>')>~)!!!~~!(/~" "'!/(((~~(!~{:<<(/{{~~))!~~(/((((((((((!))~(/!,.@@@@..+#%$$*==$===---;;=====;;]]];;-==****&$%%#.#..+.@,,,,,,>>'))>>>>>>,)>@@>~{~~)))'~~//(~~~!)~))!~~:{//{{{{{/(({~/<}}:~!/((((({~~~~!>'~>''>>>>>''>>>@@.++.....+#+###+#++#.###+.@@@@@,>)'))~!!!~~(~>" "''~((((~{~~!/({~{~)~{))!~~({/((((((/((~)!{{~>@>>,@@.#%%$$*$&-$=-;;;;;]-*;=**-;]]]];-===****%$#.+##..@@@@@@@,>'')''>>>>'>@@@,){~~~'~!)){/~~~~'!~!)~~~:/((//////(<(/(||}(~(<<:({))!)))~)>),>>,,,>@>),>)',.+++++########+$#+###.....@@@@,,>')')))!~~~>'" ")>)//{({~{~!/)!{{{~({~~{/((~{{{////(~(/~)!~>@>)>@@@.##%$&***;*=;;;;]]];;]-*=-;^^^]];--===**$$$#%%.##..@,,,,>>!>)))'>>>'>))>>)~~)~!)~~~/~!~~~~(//{((:<(((////{/{<:(:}|(/(<((((~!!))''))@)>@@@@@@@@@@,)',@++###########+#$$$$+#$##.@@@@>,),)'''))!!)){" ")>)(~~{{/!~:)~{!!!!~(/{~{{~~(/~{{{{/~(~)''',,'>@@@@@+#%$&***===;];]]]]]]];---][[^]]];;--==**%#$$.###+.@@,,,>>!>!)))))))~!{)>)/~)~~{!~(~~{~~~~{::(((((/:({///{{/<:((<:/(<<(:::(~))))''),>>@.@@@@@...@>>,.############%#+#*&#$$$%#+...@,,'@)>''')))~{~" ")>!(~!~!~{)'!~))!!!!/)'))))~(~~~~~~~//)'>>@@,')>@#$$++#%$*===-=;]]]]^^^^[^];;][[[^]]]];;-===*$##.####..@@,,>>!'~))))))!)>()'~(~)!)~{)))/!!~~~~:~~{{~~('>,>@.......+++@@@.###########%%$$$#%#$$$$##+...@@>@'>>>''))'){" ">)/({~{~~/~>!~!)))))~'~((/{(/)~~~~~~/{'>@@@@@,@++...+##%$*==*;--]]]^[[[[[[[];][[[[^^]]];;-==*$%$=$$%#+..@@,>>!'~!!!~~~)){!>~(({)!!~/~>~~~!!!!~(~<||}<|<{(/////<<(/{{{{(:(~~//{!))))'>''@,,.....+####.@@.##########%%$$$$$&=*&&$%##+..@@>@>>>>>''>>))" "~(((:({~!/~>)~~!))))~>{(//!~//~~{~~/{),@@,@..+#.@.#######**=*]]-=][^[_____[[[]_[[[^^^]]];;-=*$**$$$$$%#..@,,>)'!~)!{!{{{~)~(:(({~)){~>!{~!!!!~/~<}}}:<<<:(/{(::/~{{~{{{{{(({~!!))!)>>>).#,,.#.######+++.%#%%#######%$&$$&$$$&&&$$##+.@@,@>>@,'>>'''>" ")!/!)~{{(~!~!!!!))))!'~{/'>'))!~~/{)>,@@@@..++@,.####++$#$$&=][][[[[h___h__hi[[_[[^]]];-==***=**=**&$%#+.@@,>'>!{)!~){/(~{/~(!')~~/~)~!~!)!!!~{~(<|(/(((((/((/~~~~~~~~~~(<{~~!!!!>))))>.##$#.++######$*#%$$$%####++##%$&&&&****&$$%#+.@,@>'@,>@,>',)" ">)~!~~~!)!~{~~!!))))))'!'>~~~~~~)'''>>,>>,..+.>@+.###%#%*$&=]]]][_^_h_______ih[_[[^^]-==;;;;=*===***&$%#+.@@'>>)~!){{!~)/~!~{>!!!)))~{~!!)!!!~{~~({{<<:<:/~)~~~~~{{~~~~~:(~{~!!)~!>))>.#++##.########%&&#$$$$%%+.#%$&*$%********&$$%##@@@>>,@,,...>)" ">~)!!~~{~{{!~/~!!!))))>>'~~!))!{(/~~),'!!>@@..@>.++####+&=;;-===;[^______h_^[h[_[[^]];;^];;;-=--==**&$%#+.@,@>)))!))~{/({~~/!~))!~!~~)~~!!!!!~~{!)~::(///(<:(({~/((/~~~!(<{~~!!!!~>@@@@>>,@#+#%####%#.#&$$$$$$$#$*&$$$$&&&&*******&%###.@.+..+.@@>,," ">)>!)))~{~~~~(~~~!)!)~,>)~)!)))!{((~))~{/>,>,..,,.####..$==*$*-;]^[[______[][[[_[[^];;;;]]];;;---==*&$#%#@,@@>>>)))!~~~!!!~()~)))))))!)~~~~~~!!/))/:(((({{(<<(~(:<}/{((~~(({~~!!~~',,>',,@.+#+#####%..%$$$$$$$$$&&&&&&&&&********=*$%%+##++++++...@@" "''>!)))!!!!!~/{{~!)!!{>,!~)!))!~/(())/~~{)'!)>.+@@@....+&**&$-;]]][[____[__[[[[[[^]]];;]]]]];;;--==**$##+.@@@>>>)))!~~~!!!~()~)))))))))!)!!!!!!/))/:/(((//:<<~~<(:<((<<(~~/((/{{{!>>'))@..++#+#######%%$$$&&&&&$&**********==*******&$%%######++..@@" "')>!)))))!!~//!~~!)!!/'>)~!!))~{/(()!~!)~))~~)@#.@@@.+#$*=*&&;]]]]^^[[[[[[__[[[[^]]]]]]]]]]]];;;-===*$%##.@@@>>>)))!~~~!!!~()~!)''))))!)')))))!/))~(((((((:<:~((((<((}|:~)~((//~)'>>>))@..++#+######$&$$$$*******=********=========**&$$%######++.@@" ">!))!~!))!{/{~~~~!!!~/))))~~!!~~/(/)~)))~!'~{)@####%$$&*=-=**=]];]]^[[[[[^];][[^^]];]]]]]]]]];;;;-==*$%##.@.@,>>)))!!~!!~~~(!)~!)>)))!'>))')))){)!!{(:((/{(<:{(///:((<|:~))!!!)'>,@@,>',...+#####%$#++%$$&*****=======***===--==--==***&$%%####+..@," ">)!))!{))!//)~~~!!!~~{!~(!))!)''!/{!~)))!!>>',.++##$$**==;-=*&*;]]]^[[[[^[]^[[[[^]]]]]]]]]]];;;;;;;=*&$##+.@@,>>'))))))!!~)/(~))~'''!),''>>>'))~){:(/(({)){:({(/((((//({!!!!)'>,@@..@@>)>@..+###%$$$#%$$&&***==============-;-----==**&$$$%####+.@@," ">>)~~'/)))~!!{!!!!!!!~!{~!)>,>'>)//!~))))))>@.@@@.#&***=-;;;;]]]]]]^[[[[][^]]^^^^^]]]]]]]]]]]]]]];;-=&$##+.@@@,>>'))))))!!!!~/~>~''>)>,>>,>>>')~)//(({~!!)~::{(/((/(({!)~{/~)>,@...+........+###%$$$$#$$&&**==============-;;;;;;--==**$$$%####+.@@," ">>))~)~)))~)!~!!!!!!)~)~')!!,,>>~(/!~)))''))>>>'>.#***==;-;]]];;;]]^[[[[[[;]^[[[[[^]]]]]]]]]]]]]]]];=*$##+..@@@>>>''''))))!!!!~)!)'>',,@,,,>>>'!)~){(:~!~!/<:{(/(/{{(:{{/:({),@.++######..@.+###%$$&##$$&&*==============-;;;;;;;;--==*&$$%####+.@@," "')>)!!~!))!!~!!~!!)!!~)))))!>,>)/(/!~))))'')>>>),+#$&**=--;]];=;^]^[[[[[[[^[[^[[[^]]]]]]]]^^^^^^]]];=&$%#+...@@,>>>))>'))~~/~~~)!)'>>,,,@,,>>>'))!~{/:/!~(<<:/((//{{/(/{/:/)',@..+#####.@.######%$$$$$&$&**=======--;-===-;;;;;;-;;-==*&$$$#%###..@>" "'!')!)~!!!!~~~~~!))!!!!''')''~~(((/!~)!))'>,@...#%##%$**=-;];-=]^^^[[[[[[[[[^^[[[^]]]]]]]]^[[[[^]]];=&$$%#+#+..@,,'>)'')!!!{!)~!)'>>,>>@,,,,,>>)))~~/((<<}<<:/((///{~~!!!!)'))>@..#####@,.######%$$$$$$&***=======-;;;-------;;;-;;---=*&$$###...@,," "+>!))!!!!!!~~~~~!))))))>>>)))~~~~({~!!))))'>,,>@@..@.#$==-;;;=*;]^^[[[[[[[[[[[[^^^]]]]]]]]^[[[[^]]];=*&&$%###+.@@@>'>>))>.@!/~)))>>,,,,@@@@@@,>'))!~/((<(((<((////////{{{~~~~{~'@+#####.@+######%$$$$$$&***==-----;;;;;;;;---;;;;];;;-=**&$%#++.@@.#" "#+''>~)!!!!~~~~~!))))))>>>>)))))~~!~!!)))'>>@@@.++##..$===;;;=*;]^^[[[[[[[[[[[^^^^]]]]]]]]^[[[[^]]]-==**&$%###+..@@,>@@.++.@)'>)>>>,@,@@@@@@@,>')))~~((/{~(({({/{//{{~~~)))))'!)@++####.@+######%$$$$$$&***==----;;;];;;;;---;;]]]];;;==**$$$#+#+#%#" "##+.>))!!!~~~~~!!)))))'>>>>'))!){!!!!!!!))>>,@@@..+%++&***-;;=*=]]][[[[[[[[[[^]]^]]];;]]]]]^[[[^]]];==**&$$%##++++..@@+##.++..>',,,,@@@@@@@@@@,>>')~~{//({({//{{{/((//{~~~!!))!)@..+#$%+@.%#####%$$$$&&***======;;]]]];;;--;;;;]]];;;;-==*&$%%#+%$$#" "#%#.>))!)!~~~~~!))))))'>>>>>'))){!!)))!!))>>>,@@..+#+%#+%&=;;-*=;]^[[[[[[[[[[^]]]]];;;;;;]]^^^^^]]];-=**&&$%######+..@..++##+.@>@,,@@@.....@@@,,>')!~~{//{({//{{/((((//{~~!!)))>,''@#%%#.@+##%##%$$$&***=======-;]]]]];;--;;;;;;;;;;;;-===*&$%#+.+#+" "$$%#@>')))!!~~~!))))))'''''>'))){!!)))!!))'>>>,@@@.++##+.#&=--=*=;]^^^^[[[[[[^]]]]];;;;;;;]]]]]]]]];;==**&$$%########.@.##%%##@,,,@@........@@@,,>)!!~~{{~(~{{//(((:((/{~~!)))))))'>@###.@@##%%%$$$&**===-----;;;]]]]];;-;;;]];;;;;;;;;-==*&$$%#@.##" "$$$%#@,')))!~~~!))))))'''''>'))){!!)))!!))''>>,,@@@.+##%%+$*===***-]^]]^[[[[[^]]]]];;;--;;;]]]]]]]];;-=***&$$%%%%%###+.+$&$$%%%++@@@.+......@@@@,>)))~~~{~/~{{//((::(((/~~!))'))>>>)>+#..@@.+#%%$$&***=-;;]]]]]]]]]]]];;-;;]]];;;;;;;;;;-=**$$$#.#$*" "+..@>>)!)))!!)!~!!!!)!!!)))))))'~)!)!!~~!))'>>,,@@@..##%%#%*$&$*==*=;^;;[[[[[^]]]];;;;----;;]]^^]]];;-==*&$$$$%%%%%%#.%$$#+..@,@>>@.+++#+..@,@@@,>'))!!~!!~~~~{/(((((((/~~!!)))'''''>.,,@...@.#&&$**=--;;;;;]]]]]]]];]]]];;;;;;;]]]]];;;;-==*&%+%$$#" "++..@,)~~))~~~~~!!!!))))))))))))!!!!!~~~~!))>>>,,@@..+##%##%###$*==;];;^][[[[^]]]];;;;----;;]]^^]]];;--==*&$$$$%#####$&#.#++....>>>@...+....@..@@>>)))!!!!~~~~{/((((((/{~~!)))''''''>>')>,@+#$*$$***=--;;;;]]]]]]]]]]]]]]];;;]]]]]]]]]];;-**&$$&*#.#" "%###.@>>>'!~~!~~!!!!))))))'''''!)~!!~~{~~~!)'>>>,,@..+#######$$$%*-]^=-^][[[[^]]]];;;;----;;]]^^]]];;-===*$%##+##%$&&###%#%####.@.+...+#+.......@,>')))!!!~~~~{/(((((//{~~!))'>>''''>'>@@,,+$*=%%***=--;;;]]]^^^^^^]]]]]]]]]]]]]]]]]];-=*==-=-=$#$$%" "%###+@@,>')!!)!!!!!)))))))'>>''!)~!~~{{{~~!))''>>,@@..+##+##$%$$$$=]]==]^[[[^^]]]];;;;---;;;]]]]]];;;-==*$%#%&***&$###%$%%%####+++++###%#+++++..@@>>''))!!~~~~{/((((//{~~!))''>>'>>'>'@,@@@.$==$%***=--;;]]]^^^^^^^^]]]]]]]]]]]]]]]];;;]]]];=*$$$&$$" "$%#+.@,,>>))!!!!))))))))))'>>')!!))~~/{/~~))))''>>@@..+++++##$$&&$&;;-=-]^^^^]]];;;;;;;;;;;]]]];;;;---=*$$$*===*$%#%$$$$$$$%##+++#########+++++...@,>>'))!!~~~~(/({////{~!))))))'>>>>>>,@..@+*=&%%&**=-;]]]]^^]]]]]]]]]]]]]]]]]]^];;;^[[^;=&****&&$$" "$%#+.@,,>>)))))))))))))))''>>')!!))~~/{/~~!!))''>>@@......+##$$$&$$;];;;]]]]]]]];;;;;;;;;;;;;;;;;--===&%$*==-*$$%$$$$$$$$$$$%##################+...@,>')))!!!~~/{/~{{{{~~!))))))'>>>>,,,@....&=*$%$&*=-;]]]]^^]]]^^^^^]]]]]]]^^]];][[[[]=**===***&$$" "$%#+.@,,>>))))))))))))))'>>>>')!!))~~/{/~~~!!)''>>@@......+##%$$$$$;;;[_[^^^^]]];;;;;;;;;;;;;;;;--===*$$*==*$$%$*****&$$$$$$$%###%%%%%%%%%######++..@,>')))!)!!{~{!~~~~~~!))))))'>>>,,@@@.+..&**==*&*=-;]]]]^^]]]^[[[[^^^^^^^[^]]][__[;=*=;-===**&$$" "$%#+.@@,>>'''))))))))))''>>>>')!!))~~{{/{~~~!))'>>@@...@@.+##%%$$$*;;][^]]]]]]]];;;;;;;;;;-------===*$$=-=&$%$***==***&&&&$$$%###%%%$$$$$$$%%%####+.@@>>'')))!!~!~!!~~~~!!)))))''>>,,@@@..+.#&&&=*$$*=-;]]]]^^]]^^[[[[^^^^^^^[[]]___^;==--=====**&$$" "%##...@,>>>'''))))))'''>>>>>')))))!~~{{{~~~~)))''>@@...@@.+###%$$$***-[]][[[^]]];;;;--;;;----------=$$=-=&%%$&***=******&&$$$%#####%$$$$$$$$$%%##++..@@,>>'))))!~)))!~~!!!!))))'''',@@@....+%#+%*&%&*=;;]]]]]]]^^[[[[[^^^^^^^[];[h_^;;;---====***&$$" "%##++.@@,>>>>''))))'''>>>>>>')))))!~~{(~~{~!))''>,@......+####%$$$&&&*;]]^^^^]]];;-===-;--=========&$*;=$#$&&****=******&&$$%%#####%$$$&&&&$$$%##++..@@@,>>>''))!''!)!!)!!!)))))'>>@@....+++#++#$$$*==;;]]]]]]^^[[[[[[[[[[[[[[;_ih];;;;;--====****&$" "%##+#..@@,>>>>'''''>>>>>>>>>')))))!~~{{{~~!!)''>>@......+###%#%$$$*=-=-]]]]]]]]];-=====--==========$*--$#%$&&&&**=******&&$%#######%$$&&***&$$%##++...@@@@,>>>>'''))')))!!!))))))>>@....+##+#$$%%&&*=-;;]]]]]^^[[_____[[[[[[[][hi[]]]];;--====*****&" "$%#+#..@@@@,>>>>>>>>>>,,,,,>>'))))!~~~!{{)))'>>>,@@....+###%%$$$$&**=--;]]]]]]]];;==============**&$=;$##$&$$$&***====**&$$%#######%$$$&***&&$%###+....@@@@@@,>>,')>>''))))))))))>>@..+++####%$$$&**=-;]]]]]^^[[______[[[[[[[^ij_^^^^]];;-=====*=**&" "$$###..@@@@@,,,,,,,>,,@@@@@,>>>'))!!!!{)'~)'>>>,@@,@#+####%$$$$$&***=--;]]]]]]];;;-====*====*****&%&-*%%%$$$$$$&***===*&$$$%########%$$$&&&&&$%%###+....@@@@@@@,>..>>>>'''''!)>)'>,@..++++##%%$$$&*==-]]]]]^^[[___hhh____[_[[_kh[[[[^]];;;-======**&" "&$%##+.....@@@@@@@@@@@....@@@,>>>')))))~~>>,,@@@@@@%%##%%$$&*******==--;;;;;]];;;;-===***********$#&=#%$$%#%%%$&&**===*&$$$%########%%$$$&&&&$$%%%##+........@@@@''@,,>>>>>)!>>)'>,@..++++#%%$$$&&*=-;]]]]^^[[___hiiih______[ik[__h_[]]];;;---===**&" "&$%###.............@........@@@,>>)))))>>>@@..@..@#$#%$$$***=****====--;;;;;;;;;;;-==**&&&&&*****$#$$#$$$%%%%%%$&**===*&$$$%########%%%$$&&&&$$$%%%##.........@@@..@@@@,>>>)>,)'>,@@..++++#%$$$$&*==-;]]]]^[[___hiiiii______[ii_ihh_[^]]];;-;;-==**&" "&$$%##+..+....+......++++++...@@,>>'')>>>@@....+#+#$+$&***==========-=-];;;-;;-;;-==**&$$$$$$&&&$$#$.%%$$$%%%%$$&*******&$$$%######%##%$$$&&&$$$$%%###++......@@@@@@@@,>>>>''@)>>,@@..+..+#%$&*&&*=-;]]]^^^[[__hiiiiih_____i_j_iih__[^]]];;;;;;-==**" "&&$$%%###..++++.....++########..@@,>>>,@@@..+++##%.&$$&*===---==-;;;;-;;;;----=-;-==**$$%$$$$$&&$$#$+%%$$$$$$$$$&****=***&$$$%%%%#%#+%#%$$$$$$$$$$%%###+++++...@@@@@@@@,>>>,)@>'>,@@..+...#%$&**&*=-;]]]^^[[[_hiiijjih_____i_i_iih__[]]];;;;]];;-===" "***&$$$##+####+++++++##########+...@@@,@@@.+#####$#$=$&*=-;;;;;;;;;;;;;;;;---==---==**$$###%$$$$$$#%#%%$$$$$$$$$&*$$$&****&$$$$$$%#+#%##%$$$$$$$$$$%%%######+...@@@@.@@@,>,@>>.''>,@..+...#%$&**&*=-;]]]^^[[__iiijjjih_____i_hhihh__[]]];;;;;;-=-;-=" "==**&&$$+%$##+#########%%%%%%%%###+..@>>,@.+####%$*%;----;;]]];;]]]]]];-;;--====--==**$$%#.+%$$$$$##%##$$$$$$$$$&***&$*=**&&$$$$$$+#%.###%%%%$$$$$$$%%%######+..@,,,.@@@@,,@@'+.@,>@..+...#%$&**&*=-;]]]^^[__hiijjji[[_____i__ih_h__[]]];;;;^];=;;;-" "--===*&$$*%#$%%#######%%%%%$$$$%####+@.###++..#$#$$$;^];-;;]]];;]]]]]]];;;--====--=**&$%#+#%#%$$%###$##%%%%$$$$$&**&$$&*****&$$$%##$..#####%%$$$$$#$&$$%######.@+##+.@>>@.>@,>+$.@@@..+.+##%$$&**=-;;]]]^^[___ijjjihihhiiihih_hhh__[^]]];;]]^^;=;]];" ";;---=**&#$&$$$%%%%$$$$$$$$$$$$$$%#%.+#+...#%$##&#%*;]-=;]]];]]]]]]]]]];;;;-=====*&&$$##$$%##%$$$%##$##%%%%$$$$$&&$$&=&*****&$$$%#+@@+#####%%$$$$%%$$$$$%%###%.#%+.....+@@+>,.##,>,...++###%$$&**=-;;]]]^^_[[[_hhhjkjih_iihhh_hhh__[^]]];;]]]]]^]]]]" "]];;;-=******&&$$$$$$$$$$$$&&&&&$$$%##+.+#%%%#$#&%$=;]=-];]^[]]]]]]]]]];;;;;--=*$*=-=*&&$..##%$$$$%#$##%%%%$$$$$&&&$$$$&*&**&$$$%##########%%$$$$$$&&&$$$$%####%..+####+#@#..#%#@@...+####%%$$&**=-;]]]]^^]_jkklmkj__hiihhhhh_hhh__[^]]];]^^]]];]]^]" "^]]];;-===-=***&&&&*&*&*********&&&%&++%##%%%%$+=%$$*=&-;]^]]]^^]]]]]]];]];;--=**-=$%#+..####%$$$$$#$##%%%%$$$$&&$&&$&$&&&**&$$$%%#########%$$$$$$&&&&&$$$%##.%..########@*.....@#+.+####%%$$$&*==;]]]]]^^[ii[_hhh_iiiihhhiih_hhh__[^]]];]^^^^^^]^^]" "[^]]]];;---========*$=$=**********$$&#%$$$$$$$$&$***&&*-;;]]^]^^]]]]]]];]];;;==-;*$$$%#####%%$$%$#$%%%%%%%%$$$$*$%$$$$$$$&$$$$$$$$########%$$$%*%$$$&&&$$$%#+##.#######%#$#$%#.@.##++++###%$$**===;]]]]]]]i_[__hhijjjjii__ihhh_____[^]]];[]][[[[[^[[" "[[[^^]];;;;;;;;----=*-$==*****===**=$$&&&&$$$&$&$**=-==-;;]]^]^^]]]]]]];]];;;;-*$$***&$%####$#$$$%%%%%%%%%%$$$$*$%$$$$$$$&$$$$$$$$$%#%%%%%$$$$%*%&&&&&&$$$%##$++######%$#$#$$$%%#%#######%%$&**===;]]]^^^^]^_iiijjjjjjjhhhihhh_____[^]]]][^[_[[[[[[_" "__[[[[^]]]];;;;;]]]==;*=========**=;=&*==*****$*$**=-=*=;;]]^]^^]]]]]]];]];;---====*&$%%$$$%%%$%$$%$$$$$$$$$$$$$$%%%%#%$$&$$$$$$$&$$$%%%%$$$&$$*#****&&$$%#+#&#.#####%%$%$%$$$$$##%#####%%$$**=---;]]][[[[___iiiijjjjiihh_h________[^]^^[[_____[___h" "h____[[]]^]]]]]]]]]=];*--==--=*=;;;;]*====****&=$**==*$*=;]]]]]]]]]]]];;]]];;-=-===&&$%####%%$$#$$%&$$$$$$$$$$$$$%%%##$%$&$$$$&&$$&&$%%$$%$$&#&*%****&&$##%%%$$++##%%%$$$&#$$$$$##%$%%%%$$&&*==;-;]]]^[[[[____hhiihiii_h_[h__i_h_h_[^^[[[[hh____h_hi" "ih_______[[_____[];^[=;];;--;==;^]-*=--==;-==*$-$===**=;=-^]]]]]]]]];];^;]];;;;;-=*&*&&&=*&$$&&&*&$=%&$$%$$$$$$$%%%%###+#$%%%%%$***$$*****&$%&*$*******$#$$#..+#%##$$$&$#*#&&&&$&&#$&$$$$&**==--=]]]^^[[[[____hiijkjiiihh_hh_j_ihh_[[[[[__hhih_h_[_i" "iiiiih_[[_ih[[[_____]]]]]];;];-]^;==--;;-===**=;*==**-;]]-;^]];;-;;]];;[-]];;;;;;=*=&&$$$$&&$&****$=%&$%$%$$$$$%%####.+%.%$%%$$$$$$&=*$%%&**=*#&*******$##$+@.+##$%#%%$$$=%$$$$=;;-&&=***&&*=--=-[;]^^[[__i__ihhiiiiih_hhh___i[ih________hhiiih[hi[j" "jjjihiiiii__iji_[^]][[^[^]]]]^]^_;=]^;=;]]-==-]-&&&*;;==]]-]]];=**=-;^[[=]];;;;;=====*********&***&=%&$%$#$%%%%%#####+$$%#$%%%#%$&&*$$*=*&$###%**====**&#%&+@+%#.%$%$$&*=&##%%==&&-;&===*&$$&**;]]-]^^[___ihhiijjjjjhhh_[__[[h^hh_h_hhhhhhiiiiihjjih" "jjjjjjiih_hjjjjjih_h_[_[[[[[[[^_j_;]]][;-;]^];=&*=*&;=*=&;;-]];=*-;]^__]-]];;;;;---===**********=&**%&%#&#%########+++#.$#%%%$$$$$$$&==**=**&&***=====*&%$=$.###%##%*==*$##$%$-=*=&;==;;=&&=;;]_[;-]^^[[__hhiijjjkkkji__[__^_[]h__j_iiiiiiijjiiih[i_" "jjjkkkkjjjjkkkkjjiiihh____[______h[^^^^]];-;-=*=-;-=--==-;]=]];*=;]^[[[;=]];;;;;;======*****&**=**=&$##$*++######%#+...+#%##%%%$$&&*=====*******======*&&$%$#+#####+#$$%%$&***=-=--;]=];-*=;]^[_[;;^^^[[_hhhijjjjkkjii____[[_[^^^ik_hjjjjjjjjiiiiiij" "jjkkkkkkkjjkkkkkjjjiiiiiihhhhhh__[h^[[[[^;=-=*-;]]];;;-=*;;-];;*=]]]]]];=;];;;;;-=*===******&&**$=*#%+&*$.....+#++..+++%+%+##%%$$&***========**==----==**$##$.#####++#%#$***=-=;;-=]];]];=;[^]]^^;-]^[[__hiiijjjjjjjih_[[[;__]^]ikjhh_hiijiiiijjjkij" "kkkklllkkjjkkkkkkkjijjjjjiiiiihiih_h_[[[[]=-=*;]]]]]];=;^]=;;;-*=];==-;-*-;;;;;;==**=******&$&&$$-*#%**%+#$$$$#+#%+.++#+#+++##%$$&$$$*===========-----=*&&&%#%#####+.#%#$&**=-;;;][[;]]]]-][]--;];-]^[__hiiiijjjjjjih__[[]]h[][iji_ijllkjjjkjjjjjjki" "kjkllmmlkmljkmmkkkkkkkkkjjijjjjjjjhhi_[^^;-];--]^]]]]];--==;;;-*=;=*&*-=*;;-;;;;==****&&&$*--*##$==&**%..%&#++###.+####+#++.##%&*$$**$*-====-===--;;--==**&$%%&##+#.+#$##&**==;];;;;;]];];][;==-;;=][[__iijjjjkkjjihiji_]-]___ijh__jljiijkkjjkkkkkkj" "kmkmmlkmnnnomlmlkkkllkkjkjjjjjjjjjjihji^]];]]];]]^^^]]]]];;;;--*=;&***==*--=----==****&$$$&==-*$$=-*=$.@.$#@..@,@+########+#.$%%$&=-;=**===------=-==-==***&&$#&$.+#+#%%#$&*==;;]]^]]]]]^;][-=;-;]-]^[_hiijjjjkjjjihhiii_]^_iiji[[hkjhiih_hjkkkkkkkk" "llommmonolmnnlmommmmmmkjkkkkkkkkkkjkhkj[[[[]^__[^^^]]]]];]];---*==$*=&*-=*========****&$$$$=--*$$*;=*%@.#$.+%%#.@##########+%%##$*&$*==$*==--;;;-*-=---==***&*#**##$##$***$&*=-;]];]]]]]^;[^=;;=;]];^[_hiijjjjjjjiih_iji[^[_jkjh[_jkikllkjikllllmmmm" "mmmnnpqrmmlmpnmoooooomlkmjlllllllllljljhiii[_jh[[[[^^];;;]];;--*=*&==$*;-*========****&$$$$&==*$$=--=$+#&#%%###########%%%###$&==*%#%$-=*==--;;;;=;=];--==****$*$%&*$$&=*&&**==-;;;;]]^]]][];[;=;[^;]__hiijjjjjjiiih[_hh[^_ijkki_iljkkkkkkkkllllmmmm" "omlorpqqpnoorqnorrrnoomlkkmmmmmmmmmklmkjjjjhii_hh_[[]^];=-;;;;=*;**==&*];*&=*====**&*&$$$&$$$**&*=&&**$*$#%####%#######%%%##+#*===*&%$*=&$==-;;;-=-=];;;;-===$*=&&**&&&*&*****=--=*=;]]];;[]]]]=-_[]][_hiijiihjiihhh__^[__ijijklkmkikkkkkkkklmmmmmmm" "mmonrrnrqqqqrssrnprnnomllkmooooommmonkkkkkjiiiiji__[^]][[;==;==;*====$*]]=$*****=**&*&$$$$$$#$***&$%&*&%+%%%###########%%%##%$$$%%&*=**=;=*-=----=-=;;;;;-====;****=*****===**===;]-=-;;][;]]]]=;_h^][__hhiih_ihh_____][hiii_iklkjikkmllkkkkmmmooooo" "noonrpqqqqqstqqqrrrrnoolmmmoooooomoolkmmlkkjjjjjih_[^[];][]-=-]==;--=**;;=$&&********&$$$$$%#%**&%##%$#..$$%###########%%%$$%%%$$&&&&=-**=&*=----=;=-;;;;-====&&*=======-=====-;=*;^;-=;[;;]]]];-[_]]^[[______________][iji___jjjiilkmlkkklmmmoooooo" "oorpqqqqqqqqsrnpqnrrnnolommmmoooooonmmoolklkkkkkji_[[]^]-^__[_;;]];;-=&*=*$*&*******&&$$$$%%+#**$#$$$$+.%#$##..++#######%###$$&&$$&***=$#**$=---;=;-=;;;;-===-**==------;;-===---;*][[[[;;]]]]];=-];;]^[[[[[[[[[__[[[_][jjh_hjkkiilkmlkjkklmoooonono" "nrppqqsssssqsrrrqrnnnoollrolornonnnnmklnmomkkklkkjih_[^];_i__];]^]];;;=&$$&*******&*$*$$$$%#++&*&$$###$.######&%@%######$##$$$$$$&&&&$*$$$*$===--==];=;];-;;;-*&*---;-;;];-====-;;=]_[_;;]];;;]];===;]]^[[^^][^[[[[[[[[]hiijjh_ikikkllkonokooonnnnrn" "nrqqqsssssstqqqrqrrnnnollrrprnonnnnoonnmooolkklkkjih_[]][_[h_]][]]]];;;-====**&&&*$*$*$$$$%#++$&*$.@@...@####&$&.+#####+$##$$$$$$$&&&&$&$%*$===--*=][_[--]]]];-;;=;;;-;;];;-----==][][[-;];;;;;;;];;]]]]]^]^][][[[[[[[^]_ijj_[[hjjikkkmnnrloonnnnnpn" "npqsssttttttssqrpnrrnnnomnproonnnnonronnmoomlklkkjii__[[^];[h]][^^]]]];;--==**&$&*$&$*$$$$%#+.#$$#,.+.@....+%%+&.+####+.$#.#$$$$$$$$$*$&&%*$===--==;^[;=]]]];;];;]=;];;]]]];;;;=-;;;=]^-;];;;;;;;];;;;;;]]]]][]^[^^^^[]]_ii_^hiiijijjkommrmmonnrrnsp" "npsssttttttttssqpnrrrnnnmorproonnnrnnrrormomlkkkkjjihh_[[[[][[][[^]]]];--====*&$$&$&$*$$$$%%+.#$%.,.++.@+..$&#.&++####.@%+@.##%%%%$$$&&&&$*&===-;;==][]=;;;;];;]];]=];]]]]]];;;;;;]]]-];=;;;-;;-;;;----;;;;]]^]^^^]]]^];[ih[^_iiiikjjonkknlmnnrrrrsp" "rqqqssstttuutssqprrrrrrrmnpqsqrrnnnrrrrnnoommlkkjjjihhh____[]h[[[^]];=-;;--==*&$$$*$$$$&$$$#++&*$#@..++>.$$%...$+#####..#@@...+###%#$$&&$$**==-;;;=-^[_^];;;;]]]]]];]]]]]]]];;;]]]]]];-]-;;;;-==-;;===----;]]]]]^]]]]];]_ii_[_ijkhkoookkknmnonrrpqsr" "sssqpqtutuuttsqqprrrrrrrorqqrnnrrrpqqqqrrnnommkkkkjjiiiihhh_[i_[[^]-======****&$$$&%$$$$$$%##$$$$$#.@@@.+##.@#+$+#####.#@....@>@+##%$$&&$$**==-;;;=;^[;-;--;]]^^[]^]]]]]]]]]]]]]]]]]];-];;];;=*=*******===-;]]]]]]]]]]][[_hii__hijkmmlklknmnonrrrsqq" "stttqsuvtuutssqqprrrrrrrorpoonppppqqqsqpprrnoomkkjkkkkjjjiih[jh[_[;;][]==******&&$$#$%$$$%####..+%$##+.@..%.@+.%+%####+......@>,+#+%$$&&$$**==-;;]=]]-=-;];]]^^[[^[^[[[[^^^^^^^^^^^]];-[]-;;==;];=*&&&&*===-;;;]]]]]];;;;;[hijjjjjkmnmlmlnmnonrrpqqs" "ttuussuututssqqpprrrrrrrornorppqqqqqqsqpqprnoolllkkkkkkkjji_hji[[^;]]=*-;;;-=&&&$$%#%#%$#%###++.@@@@@....@.#+@.##%####+..@...@>>.#+%$$$&$&**==-;;;=];=;];;;]]^[[_[[[[[[[[[[[[[^^^^^]];;_^--;=;;**==-==*&**====;;;];;];;;];;]^[_ikkkkmoommnmnonrpqqst" "ttttsstusttsqqppprrrrrrnoponprpqqqqsssqqqqrrnommllllllkkkkijjih[]]][]*$&=*&&=$&$$$%#$+.#######++@@@.++++...+%#########..@@@@@,''.+.+%%$$$&***=-;;-=]=-]]]]]]]][[____________[[[^^]]^;[[^];;==];$#&**$%*$*&*===]===;;=;;]]^]][hijkkkllmnoonornrrppqss" "stssttuvusssqqppprrrrrrnrrmnrpqqqqqssssqqpprnnoommmmmmlkkjkih_[[_^]^^^-==*$$*$&$$$##&%#%#..##++.....+++++++..$$#.####..@@,,@>>,@.####%$$$&***==--=;]*;]]]]]]]][[________hhh__[[[^]];]]]--;]-=;;;===&#%*$&$****];;;;=-;;]]^^[_hijkkklmmmpqnorrrpppqss" "stswwvtttssqqqppprrrrrrnpoorrqqqqqqssssqqpqqrrnoommmmmmlllkjki_[_[]];-===**=*%$$%%#+*&$#.++#++.@@...+++++###.+#.+###+.@@,,>,'.#...+##%$$$&***====-]=-]]]]]]]]][[_______hiiih__[[[]]]];^];;];===****=***%$$&***]]];=-];;]]]][_hijkkklmomormnnpppppqss" "tttxxvspqssqqqqqprrrrpnpnonrrqqqqqqqqqsqqrqqrnnnoommmlmmlkjkkjh[[^[[]]=*&$**%$$$%%+%$$%@@.##+.@>',@...+++###+@.+####..@@@>>>>##.,>@.#%$$$&&****-=;;=]]]]]]]]]][[_____ihiiiih___[^^]];]]^];;;;;-=*$$$**$$$&$*$=;;;**;;];]];;]_hiijkkllooloorpqqqqpqss" "tttvvsqsqqqqqqqqprrrrorronrrpqqqqqqqqqpptsrrrrnnmkkkkmmlklkkjjh[^^[[];-**%#%#$%#%+#%#$%@@.@@@@@@>>@@...++###++#####+..@@@>>>>..@@@..#%%$$$&&**=&--=;];]]]]]]]][[[[ii_hijii_[^]^[[]]]]]]]];-;];-==*&%%$#**$$%$-*;;**=---;]]]][_iijkklmmkmrrpqqqqqpsss" "ttstsqsqqqqqqqqqprrrnronnnrpqqqsssqqqrqqttsqnrrnmloornmkklkjiii[]][^];-**%##++##.+$@@+$##%##..@..>>@@..++##+#######+..@@@>>>)>>>@...##%%$$$&&&*=**=;];]]]]]];^^^_hkjih_ii_[[__h_^]]^^^^^];=-;;===**%#$#$**$$&$$=];;][^]]^[_^[_iijjkkkklmnrpqqqqqqqss" "stqprsqqpppqqqqqprrrnnnrrrrqqqssssrtrnnnqqssnrrromornmmmllkiihh[;]^];;-*&%$$%.+..+...,+%##+,'))>@)'@@@.++##$$%#####+..@@@>'>!~),@@..###%%$$$$&&**=;]];]]]]]];[]]][iiii__ih[][i_^]^^^^^^^^;*=;-===*&$&*&#%%$*%$$$-]^^]=*==^_][hiijjjkkmnmorpqqqqqsqqq" "qqprrqqqqqqqqqqqrpnronnrrrpqqqsssspsqrrprnnqrrqprnorrlmmllkih__^;]]]];==*$%#+#..+@..@,>.+.@''>>,>)>>>,@+++%.+$#%#####+@@,>')!~)@@@...##%%%$$%*$*==-;;]]^^^^^;]^][__][ii_hh_[[__]^[^^^]]]];=-;-==**&$$$$*%$&#$&&&$-;;=*=;][[][_iijjjjkjknorpqqqqqqqqq" "qqsqrpqsqqpqpppqrrnnonnrrppqqqssssqqqpprrpnrrpqprrnormmmlkjih_[];;]];-=*&$#+..#%.@.@@,>,@@>>'>.>)'>>>,@...%.#$#%######@@,,,,@@'>.+...+##%%%%%&$**==;;]]^^^^^]]]^_^[h_h_hh___[^_^^^^^^]]]];==;-*=**&&$$#%*=$%$$*&$*=-===;[]]^[_hijjiikikomnrpppppqqqq" "rnrppnnnnrpqpppprnronnrrppqqqqsssssqqqrqqrrnrqprrrrmnmmmkkji_[[]=*-;--=*$$###>.@>@@@@,>)'>'>>.@~)>'>>,@@@@#%$#+%######.@,@))'@@'>,>@.#######$%&*===;;;]]]]]]^]][[[_hh__h___[[;[^^^^^^]]];;=&=-===**&&$&#$$+$$$&&$$&*==;[[-][[__iiiiikmommonrrrrrrrnr" "mlmrqrrrrrnrppprrnpmrnrppqqqqqsssssssqsqrrrrrpprrnroolmlkkji_[^;=]==-==*$%###@@@)@,@@,>~!))))@@))))>>,,@.@,@..#%#######@)'>!)@.@@.@@@.+###++$#*&===;;;;]]]]]]^^[[___hi____[^[][^^^^^^]];;-=]==-===**&$&%#$+%#$&&$#%&*=*^[;;]^[_hiijhhjjjlonnrrrrrolm" "lmnrqpqsqqrrpppqnrnonrrppppqqqqqssqqqqqprnnnnnnnnoommmmkkjih_[];;**==**&$$%#+@@.>>.@@>)!'>,,'),@,>>)'>,>>@@@.#%%%#####@>>>'',.+.+###..####+#%#$*===-;;;]]]]]]]^^[__i____[[[^]]]^^^^^^]]];;;======***&&&%$*%#&&*&%#&=;;-;[[[[[]^[__hiijjkmooonnnnmmmo" "nnnnoorqpqqrppprnrnnrrrppppqqqqqqsqqqqqprnnnnnnnooomlkkjjih_[^;-=*****&$$$%#.,.+,',@>>)!',,>>'))'))>,@.@,,.+###%%%%###@@...#+@@,+%+#+.###+#%#%&**==-;;;;]]]]]]^^[[______[[[^]]]^^^^^]]]];;;----==****&&$*=$%&&$$$%*;;]];;]]]]^[_hiiijkklmmmoommmlmnn" "nommnoorqsrnppprrrnrpppqqqqqqqppqqqqqqqprnnnnnnoommkkjjih_[^]^;-==*&&&$$$%#+.>@@>)>>>@.@)>@,>@,>>>,,,,,.+>@@..#%%%%###..+##@,@.@@+%$..###+###$***==---;;]]]]]]^^[[[_____[[[^]]]^^^^]]];];-;---;;;-==***%$*%#%#$*==*-]]]^[^^^^]^[[ijhiijjklmmmmmmlmor" "mkmnnrnnqsqrpqqprnrqqqpqqqqqqpppqqqqqqqprnnnnnnoomlkjjih_[^]];=***&$$$$%%%#+.>>>''>).@@@@''>>>,,,@@....@%++#%$$%#%%####.@%@>@..#.@#$#.#####+%&***==---;;;]]]]]^[[[[[[[[[[[[^^^^^[^^]];;;--;;;;;;;;===**$$$$%$$===-;=-;]]^^^^^^[__[kkkkmomkklllllmkkn" "okmoonnosqqrrqprppqqqqqqqqqqqppqqqqqqqprrrrnnnooomlkjji_[^]];-=**&$%%#####++.@@@@@>>.>'>>>>,>')>>,@@@@,.%&%###%%#%%%%%##.#.,@+.#..$$$.##%###%$&*===---;;;;]]]^[[[^^[[[[[[[[[^^^[[^]];;;;;;;;;;;;;;;====******&-**==;]];;;]];;]^[^hkmlkklllkkkkllmlkm" "mkmnnnonqnprnrrprqqqqqqqqqqqqppppprpprrrrrrnnooommkkjih[^]];-=**&$$####++++.@@,,,,,>@>.@@>>,@.@@@..+.+%$$#+##%#%&%#%%%##+++@.##+.+$#%###+###$$&*===---;;;]]]^^^[[^^[[[[[[[[[[[[[[^]]]]]];;];;;;;;;;;-===******=*;-;;]][[[[[[^_[_jkkjjkkmllmkkklllmll" "okmooonrnooqnnrqpqqqqqqqqqqqqprrrrnrpnrrrrrnnoommlkjih_[];;-=&&&&$%###+..+..@,,>>,,>@@.,@..,>@@@,@@....$$.##%$$$%$%%%%##.+#@@...+%+@+&###%#%$$&*===---;;]]]^[[^^^^^[[[[[[[[[[[[[[^]]]]]]]]]]]]]]]]];;;-==**=**--];;^];;]^]]]^[[[_kkijkkllkkllklllmlm" "nooonnrpommqnoqpsqsqqqqqqqqqqprrrrnnnrrrrrnnoommlkkji__^];-=*&$$$$####+..+..@,>>>>,,@@@@.@@.@>>@...+##.%#+$#%$$$$$%###%#.#&#++##%$.,.*#+$$$$$$&**==---;;]]^^^^[[[[^^^^^^[[[[[[[[[^^^^^]]]]]]]]]]]]]]];;-=====*;;;]]]]]];]^[[___i_jjilkkkkkllkkllmlko" "onoonqqqprppnnqrsqsqqqqqqqqqqqprnrrrnonrrrnommmkkkkji_[^]-=*$&$$$%###+..@@..@@,>>>>,@@@.....>@@@..++##+######%$$%%######+%%#++#$&$%#$$##&$&&$$&***==-;;;]]^^_h_[[[^^]]]^[[[[[[[[^^^^[[][]]]]]]]]]]];;;]];-====;]]]]]]^=]^^[__h_i_iijkkkkkkkkkkllmlko" "mlklopqrnrnnnrsqqqqqqqqqqqqqqprrnnnoonrrrnoommlkjjkih_[];;=&$&%$$%##+...@@@@.@,>>>>,@@@......%#..++##########%$%%#######+%+,>>.$##+###%%*&$&&$&***==-;;]]^[[^][[[[[^^^^[[[[[[[[[[[[[[[[[][^]]]]]]]^]];]]]];--;]]]]]]]^^hh[___hhihijkkkkkkkkkklmmmmko" "mlloprrrrrrppqqqpqqqqqqqqqqqprrrrnnnnonnnnoomlkkjjji_[[];=&$*#+%%%##+..@@@@,>>>>>>>,@@@....@.@@.++#%##%######%%%########+#+,>.##+++##%&$**$**&&***==-;]]^[[[______[[[[[[[[[[[[[[[[[_[[_^][^^^^^^^^^^^^]]]];;;;]]^^^^^][[[___hii_jijkkkkkkkkklmmmmmln" "nonprrpqpppqpqrqrqqqqqqpppprnnpnnnnrrrrnnoommlkkjjji_[^]-*$*$..#####+.@.'>'@@@,>>>>>,@@@......+..+#%####%##############+#$%##%#+###%$$$&$*$**&****==-;;][[[_________[[[[[[[[[[_[____[_[;-]^[[[^[]_;]]__^];]]]]^^[[[[[[[[___hhii_hijjkkkkkkllmmmommmr" "nnnnrrpprrrppqrqrpqqqqqqprnrqrrnnnnnnnnnnoomlkkjjjih_[]]=**$%#######..>.)>))@>>,>>>>,@@@...@.+#..+###%#%################%$%#+.###%%$$$$*&=******=====;^][[______________[[[[[____h__h_^];][[[[[[;h][]]^^]]^^^^[[[[[[[[[____hhhh__ijjkkkkkkklmmmomoon" "onrrpprrrrrrqqrqrrqqqqqsprrqpnnnnnnnnnnnoommkkkjiii_[[];=**#$$$$%##+.@>@')!))',,,,,,@@@......++++###%#%################$$#.+####%$$$$$**&=**=**==-;=;[]]^[__hhhhhhhh____[[[[[___hh_hi[__[[[____[]_]^]]]]]^[[[[[[[[[[[[[____hh__hhhijkkkkkkkklmmmonnm" "rrrrpprrrrrrpnrqoorqqqqqprprorrnnnnnnnnooomlkkjjiii_[[];*=$%$$$%##+..@,'>@'))>,@@@@@@@......++.+###%$#$++################%#####%$$$$&**&*-$$*=====;;;];[[[__hhhhhhhh____[[[[[__hii_j_[___[[____[_[_h[]]]^[[[[[[[[[[[[[__[__hh__hh_ijkkkkkjkkklmmoooo" "nnrrpprrrrrrrnrnooonqqqpprprnrrrnonnoooommkkjjjiihh_[^;-&=$#&$$%##+.@@@>'@.@@>,@@@@@....@@.@##++##%%$%#%.++###+#.%########+##%%$$$$&**=*-=$$$*===-;;;;]^]^[_hiiiihhh____[[[[[__hii_j_[h________[_[[ij_[][[[[[[[[[[^[_[_[[________i__jjjjjkjlklmmooon" "nnrrprrrrrnnnpnoomoonpppqrpnrrrrnonooommmlkkjjiihh_[^];-*&=#$$%%##..@@,>',...,@@@@@@....@..>..+###%#%#+#%..@@@.#.%###########%%$$$&****;**&$*$&==-;;;;]^^^[_hiiiihhh_____[[[____hh_hj[____________[hjih^[[[[[[[[[[^_[;]^[________hiihhhhikikkklmmooo" "nnrrrrnnnnoopomnoornopppqrprrpprrnooommlkkkkjjihh__[^];;=*$*#%%##+.@@,>>>@,@+.@..........@.@@#+.##%###+#&$%####.#############%%$$&****;*&=**;*$==-;;;;]^^^[_hiiiihhh______[[_____h___i[____hhh_____ih_i_[[[[[[[[[[[^];;_[^[[[[[[[[kkjkkkkiijkkklmooo" "nnrrrrnoooonqommorqqnqrpqrprrqqprnoommlkkkkkjjih__[[]];;-*$&%###+..@,,>>>>)@##@........@@..#.+#+##%###.##%.@@@,>%+###########%%$$$$&&=]=*==;]]&-=-;;;;]^^^[_hiiiihhh_______[_____hh__h_____hhhh_____[_jj^[_[[[[[[[[^[[][[^[[[[[[[iiiiiiih_kjkkkkmooo" "nrrronppprnonrprqqqsnqppqqqqqpqprnnomkkokkkjjii__[[]]^;;-=*$$##+...@@,>>>>>>+#@@.@@@.....+##++#+...+++.>,,@@>>>,.###%%###+###$$&=;;-=*=;^^[[[]*;--;;;;]]^^[_hiih_j_ihhhi____h_h__hhh_______hhiiiiiihh_ij_[h_[___[[[[[[[[[[[[[[[[[^[_ijih__ikkkklkmon" "nrrrnrnmrnlmooonnrppnrrppqppqpprrnomlkmojkkjjih_[^];;;;;==*$$##+...@@@,,@,@,.@.@@...@....++####.....++++.,>>,@....+##%#######%$**&;-&===-;;][]=;;;;;;;]][[[_ih__ij[hhhhh_____[_hh________hhhiiiiijjiihjhh[[_h_____[[[[[[[[[[[[[[[[___hjkkjiijjklkoon" "nrrorrmormmnoooolnpnnnrrrprrqrrrnnmkjkonjkkjji_[^]][]--;==*&%##+...@@@@@@@@@.)>@,@@@@@....++#######+++...@@>>>>@@.+#####%#%%%#&=$$==&--;;;=]];;;;;;]]]^^[[___[[hjj[_hhhhh_[_iji__hih____hhiiiiiijjkjjii^[h[_h_____[[[____[[[[[[[[[_iiiijjjjkkjkllooo" "nrnornmnomooooonmromnnrrrprrprrrnomjjkmnlkkjih_[][];]]==-=**%##+...@@@@@@@@,@.@>,>>>>@@....+++++++++++.@@@@>>>,@@@.+###%%#%$%#*=$-=*=--;;];^;;]]];]]]][[[[_h_^^_hj__hiihh_[ijhjjh_______hiiiijiijkkkkjiji_h_____h___[_____[[[______hiijkkkjkkkkllomo" "ooomrpnnmmomooooooooonnnnnnrrnnnoomkjjklojjjih_[]^^;;]**==*&$++.....,.,...@@@@@@'@@,,,@@@@..........+++..@,,,,,,,@..####%$$$$#&=*-**-=-;;;]];;;;]]]]]][[___h_[[[[ii[_iiihh_iiiij_hi____hhiiiiihkjkkkjjjjii_iih______[[[[[[[[[______hijjkkkkkllllmmoo" "ooomnrnnklmmmmmmoooooonnnnnnnonoommmlkkjkljjih_[];;;====***$$++.....,.,..@@@@@,,>))'>,,@@@@.............@@,>>>>>,,@.+###%$$$$#&===$*-=-;;];;]]]]]^^^]][[_________^ih_hihh___hjhi_hihhhhhiiiiiihjjkkkkkkjjji_[[______[[[[[__________hijjkkkkkllllmmmo" "mommnnonomklmmmmooomooononooommmmmlllmkjiliiih_[]];===*=*&&$%++.....,.,..@@,@,,>>))'>>,,,@@@@@@........@@@,>>>>>>,@..###%$$$$#***==**===-;;]^]]]^[^[^][[_[_______[[i__h___hh__hiiiiiiiiiiijiiihjikkkkllkkkji_hhhhh__[[[[[__________hijjkkkkklllllmmm" "mmlonmkllllmmmmmooommooooommmlmmllllkkkkijiii__[]]];-=***&$$%#+..@@.>.>@,@@>,,>>))))'>>>>,@@@@@...+..@@@,>>>>'''>>,@.+##$$$%%$&%$$&*===-;-;]]]]]^[[[^^[[[[[_[[[[[_]_[_____hiihhhiihiiiiijjjiiihjhijllmmlkkjjiiihh___[[[[[_hhhh_____hijjkkkkkllllklmm" "llomkklllllllmmmooooooooommllkllllllkkkkihj__[[^]]]-=****&$$%#+..@@@>.>,>@>>,>>>))~{!)>>>,,@@.....+.@,,.@'!)))''''>,.+###%+#$$#%$$&&**==;;]]]]]]^[^[^^[[[[[[[[[[[[[^_][[[[__hh_iih_iiiijjjjiijhkjhkmkkllkkkji__hhh__[[[___hhii_[[ji_[_ijkkkkkllllkkl" "ooolkmomlllllmmmooommmmmmmkkkkkkkkkkkkjji_j_[[_[];===*&**&$%##..@@@,@+@@+>'>>>'')~~~!)'>,,@@@..++.@@@@@+.>)!!))'>,,@.....#%$$%$&*$&***==;;]]]]]]]]]]]][^[^^^^^^^^[^]_]][[[[[[[___hihhiijjjjjjjikjkokjmllkkki_________[[____hh____jji_[_hijklllllkjjm" "nmkmmmllllllmmmmooommmmllkkjjjjkkkkkkjji_[ih]];;--;--*&&$$$##+.@@@,>@,>>+>)>''')!~)>)''>,@@@@........@>,))'>'))!)>>,@@@+%$$%.$$&$$****==-;;;]]]]]];];]^]^]]]]]]]]]];[[;;;;][_h____h__hijjjjkjikjijmljmllkkjijkih__h__[[_____hih[[[^[___hh_ijjjjjjlon" "lkommmmmlllllmmmlkmmmlkkkjjjjjjjjjjjii__[[ih^;-;];==$&**$&$##..@,@>>>)'),@>)))!~)>>!!)>,@@@@@...@#@@@..@.>)',@.@@@....#$$#@@%#%$&&$&***=====-;;;;;;;;]]]]];;;;=-=-;]__];;^_[[[[_hh_h_hjjjjjkijjiijkmkjkkjjjlk__hiih__[[__[_i_[[_h_i_^_ijklkllkkkmnno" "klomommmlllllllkookllkkkkiiiijjjjjji_iihhiih_[]]]=*==*$%$$#++..@,>',)'>>)>@,'''>>'!~))>>@@@@@@@@#@.+...@.,))@.@>'>,@@.+##.,@%#%$$$$$&***=*;;*====;;==;;];];;-=*-;]^____[[__^^___[_h__hiiijjjjjijkjikmmkkklmki[hhhh__[[[[[[h_______h_^[ijih_hiijklmmm" "kkommmmlllllkkkmkjokkkkjjh_j_jiiiiihiji______[^]-*$&**&$%####.@,>>'>'>>>'!>,,,>))!~~)'>,,,,@@@@@+,##+...@@>)@.>)>,@.,>>@..>@##%%$$$$$$&&*-&$-****==**;=;;;--=*=];;]^[__h__[]]_[____[hjiiijjjjjjkkkjijlomkkji_______[[[[[[[h]h_[[[__[[^ij__iijjiiikll" "kkmmmmlkkkkkkkkjkljkkjjii_[j[i_hhhi[_i^]][_[]]]]-*$%$%$$$%%#.@@,>'')''''''))!~!!!)!~'>>,,,,,@@@.>+###+..@@@''@>),@@@..@,@.>@###%%%%$$$$$&$$&%&&&***&$;&-=-===&=;**=][[[[__[^]]^[[__hiihiijjjjjkkkkkjiihh___h_[____[[[[^^^_][_[[[[[[[[][j__ijjjkljjjl" "kjkmmkkmmkkjjlkklkjkjiiiih[i_______[[_]]^_];==;];-=**&$##+.@>>,,>''))'''>>)''))~!!~~'>,>>>>>>,@,>.@+#+...@@>'>>>@@@@@@.,@.@,.#%##$$$$%#$$$$$#*$&$&&&#*&*=====&*-**;]]]]^[______ih__[[[[hiijjjjjkkkkkjjiii_[[[^___[[[[^]^^[;[[[[[[[^[[^^_i_iijjjjkikm" "mkjkkjkkjkjjkljjkkikiiiihi[h___[[[[^][[[[^=**=--=***$$%%%#++,',@>>'))))>>>'>>>>'))))>>,>>>>>>,,@.@....+..@,,>'>>,@@@@@.>@+#@@+#+#%+##%$$##$%#&%$$$$$#&&**====**==-;;=*=;^[[_______hijjh_iijjjjjjkkkkjjjjji__[[[[[[^^^^]]][_]]]]^^^^^^[[[i[iiiijjlijm" "oljijjjkjkkjiiijjjijhiihhh[_[[[[^]]];;^_^-*$&**$%#++.####..#.',@>>>'>'!)'')'>,,>>>>'>,@,,,,>,>,.@.##++...@@,>'>>>@@@@@.>@#$#.@..##.%%#...+###$#%$$%$+$$$********-;;=$$*;]-=-;;][[___ijj_iijjjjjjjjkkjjjjjih__[[[[^]]]]]]]^]^[[[]]]]^[[[[__ihiiijjiko" "mmjiiiikjjjkiikkjkki_ii___^_[[[]]]];;=;;-*$$*=$+...#%%####@..',@>>>>)>)~'!~!'>,,,>>>>@@@@@@>@>>@......+...@,,>'>',@@@@,@##%$+@...#.+##.+####$#+#%###.%#$$&&&***$*-=*$&-]=&*==;[[___h_hj_iijjjjikjhkihiijii__[[[[]]]]];^;;]]^;;]]];]^[[[___ihiiiiijmm" "kljhijjjjiij_kkjjii[___[[[^_[]]]];;-;*===*$**$+#+..#%#####.@.>>@,,>>'>''>'~!)',,,>>>,,@@@@@,@.@.+@#+.......@@>,'>,@@@@@@,@+#+@@+.+#..#+%%#++#..+#....##%$%$&*&=$$*=**-;-*====][[[__i__j_hijjjjijjjkj____ih__[[^]]]]]];;^^]]-]]];;;;]][[[_[_hhiiiijii" "jlj_jkjjiji[ijiiihh_^^[_[[__]]];;;---**===*=*###+...#%####.@.,>@,,>>>>>>>>)))>@@,,,,,@@@....@,..,.#........@.>@'>,@@@@>>,).#+>.#+.@#+@##++++++@@.+..+#+###$$&&*$&*===];*=-=**=][[__h__i_hiiiiijjjkkkh___i_[[[^]];;;;;;-=]]-;];;;;;;]][[[_[__hhhhh__[" "jji_jkjkjikki_iiih__]hihhii^;;;--===*&======$.@@#$&&%#####+@@.>@@,>>>>>>>@'''>@@@@@@@@@....+#.,,>@.....++++..>@'>,,,,,,,@'.+@'.+.+..%$%.%#####@#$##%%..#+#%$$&$$*=;;]]-*$&=]][]^[___h__i_hiiiijjkkkki_[[h_[^]]];;;;;;;];*=*--;;;;;;]]^[^_^_______hj^" "jh__ijjjjhil___hh___^h^;;]]==;====*=$$====-*$##$$#+.#######@,.>@@>>>>>>,,@>''>@@@@@@@@..#####.@.#++...+####.+,@'>,,>,,,@>,.@>',.@@.@+&+.######.%.>>,@,@%##%$$&%$=-;;];-==];--;^[[___h_[i__iijijjkkkki_[[__^]]]];;;;;-;;;;;];---;;;;]]]^]_^[_____hh[_" "_^^[_hiji_ili[___[[[][-;--];=*****&$$*-=======*%+#%%###.+#+.>.#>''>'>>>,@,>>>).@.......#%###+.#+...+#######+.@@>>,>)@>>@@.>)'>>,@..@#*#.##++++@#,,,,..@@+#%$$%$*--;];;;]]-=;]]][_[__h_[ij[[ijikjjjkkih_^_[^]]]];-----;-=;;---;;;;;;]]]];[]^_[^_[___i" "[_^jjii_[_i[_[[[[[^]][;-=^^];==*&$$&=--======*$+%$$%%#+%..@>,.#@.@>'>>>>,>>..@@...++.+....#+#$##%%%########..@@>),>'@>>>@>>>)@.@@,>.#.#+##++++.+.,>#########%&=-];;;;;;;=*;]]]]^[i_[[^[jkijkijkjjjkjijj[[[^]];;;=*****-];-;;;;;;;;;;]]]][];[[^_^[[_[" "ii_jhhiiii_^[[[[^]]];]];]]=**&$*=-=*===***===*#%&$$$%$##$+..+..@.@)>>'>>>>,@..,..++##.@.%%%%###############.,@@')>>)'@@.>>@,>@>,@..+.@+###++++.+#.##.....#&***=--=-;;;;;*=;;]]][^[i__ijjjjkkikkjjjjjiiih][^]]];=&&==----;;;;;-----;;;;-;[;;^[]]__h^[" "i[__h__[[[[_[[[]]]];;-^^]*==-=&$%%$$*=*$%$***=$+$$$$$%#.%$$#@>)))>)>)''>>,,)>.@.++###.#$%%%%%%%%%%%%%#####...@>>>>>,>>,'>,,),'>>,,@@.#.++++++#..$$%..#######$$*;*&*;;;;;=&;;]]]^[^hjjjih___ijkkjjjjji[[h[[]]]];==;==*=--;----====---==;;;;]][[]]^][_" "_[i[h__[[[[[_^[]]];;-*]]-*==***&%+#&=&##+$&$$*&##$$$$$#.#%#@>>>>'''''''>'>'),@..+#####%%$$$$$$$$$$$$$##$#..+@@@,,>,@@@@@@@>),)>,@@@.##%.+++++++@$$#.#####%#+#&=*%%$====;;**;;]]^]^_iii__hiiiijjjjjii_[__[[]]]]--=========--==****-=**-=;;]]]]]]][[__" "[^h_____[[[[^]];;;;-=&;]*&=**&$$#.+&&##%#$$++$*&$#%%%#+#%%.>>@@,>''''''>'>,,,@..+##%%#%$&&**&&&&&&&&$%#####+.@@@,,,@@@,,,,>),)>,@.++##+.#++++++@$&#.%#####++#**$$$$**$$*--***==-;^_hh_[ijjiiiijjjjiiih__[^]];;;==-==========**&&***====-;;]]]]]]^[[_" "[]i[__[[[^];;;;;;-=*=$--=$&&$$%#+..&$%$$#%%..#&=*$%%%%%$$#.,'@@,>''''''>>'@.@@..+##%$$$&**=**********$$%####...@@,,@@@>>>>>)@'>,@.+++...#.+++++@$&$+#####++.#*$$&*$&&++$=;=*&**=;[hhh_[ijjihiiiiiih_ii_[^]]];--=-========***&&&&&***====;;;]]]]]^^[[" "[]h__[[[]];=;;-====**$=***$#%%%%+.#&%&$$%%$+.#*==***==**$%#@'>@,'''))''>>>>'@..++##%$&***===========*&$$%###...@@@@,,,>>>>'!,,>>@...@@.+.+#####.$%$#+.#####+#&#$&&%%&+.$*-;---;;^[_hh_[_iihhhiiiiii_[[[[[]];;=-;==*********&$$$$$****=*=--;;]]]]]^[[" "_^^[_[]^]]-=];===****$*$#$$$#$**%+#&%$$$$$&&$*=======-=**$#.,''>>>'))'>>>@,@...++#%$$&*=============***$$%##+..@@@@,>>>>>>>))>@>>@..>,#+@#####%.%.@+###$&*$##$#$$$%#$$#&*===-;;]^[__hh_]^_hhhhhhhhh___[[^]];;-===*****&&&&&$$$%%$$&&*&&**=-;]]]]]^[[" "[_[][_]^]]--;===***&&$&#%%%$&&$*$.#$#$$$$$$*=-*$$*=---=**$%#.@+.,>>>>>>>>@@,@@@.+#%$&*====---------==**&$%##+..@@@@,>>>'''>>>'>.>...@...+######+#@..+%$&$*&.+$#%%%###$**&$$*=;;]][[hiihhh___________[]]]];;;;-==**&&&&$$$$$$$%##%$$$$$$&**=-;]]]]^[[" "^__[][]]]]--===***&$$%$#&%#+$$$$#.+$#%%$$&$%**$%$*=;;-=**$$%%.@,>@,,>>>,@@,,...+##$$**==--;;;;;;;;;===**&$%#+..@@@@,>>'''''>@@>.@..+@..+#########.%+..$$$$#@.%######+.###+#&*-;]]^[__hh_[^][[[[[[[_[];]]]]];;-***&$$$$$$$$$$%#####%%$$$&&&*=-;]]]^[[" "]][^]^]];;-===***&$&&$$$$##.%$$#..+%##%%$$&$**$#$=-;-==**$$%#.>@.@@@@,@@@@@...+##%$&**==-;;;;;;;;--==***&$%#+...@@@>>>>>)!)'@>,.@..+...########++##..@#$%+@@.#+#####+..+..#&==;;;]^[[_[^;][^^^^^^^^]]]]]]]];-==**$$$%$$$$%%%#######%%#%$$**===;]]^^]" "];]];];;--=**=**&$$*&$$$$%###@@@@.+####%$$**===*=-=*****&$$#+@>@.@@@@@@@@@....+##%$&&**==;;];;;;;--===***$%##+...@,@>>>')))),,,.@......########++#++...@,>>,@++####+.+#%%#$*&&*=-;]^[[^;=]]]]]]]]]]]]]]]]];;===*&$$%##%%%#####++######%$$&***=*=];;;" "_]=-;;;-===****&&$$&&$$&$$###....@+####%$$$&**&*&&$##$**&$$#+@>@..............+##%$$$&**=-;;;;;;;---====*&$###+...@,@>)),+.>)>@@.......########++++.@.@,@@,>@.++##+.......+##+#$=;]]]^]-*;];;;;;;;;;;;;;;;;-=***$$%#######++++++#######%$$$&**==*=;_" "_[-;;====**&**&&&$$$&&&&&$$#####..####%%$$&*=====***%#$*&$$#+@>@...........+..+##%$$$$&*=-;;;;;;;----===*&$%###+....@.@.++#.>@.@.......########+.....@@...>,.@+.#+....+#####%$##*;;;]];=*-;;;;;;;;---------==**&$%###++++....++++++++###%%$$$$&==;^^" "^[^]=*=***&&**&$$$$$$&&*&$%###++.%#####%$$&**==****&##$&%#%%#@>@.....+....++######%$$$&**=-----;;;;--====*&$%#####++..+##.+###.@.......#######+...@@@@@@,@>@@@..........+#++##+#*;==;;-=$*==================*&&$$%##+...@@@..++++...+####%%%%$$$=;;;" "]]];*$&$&$$$&&&$$$$$$$&&$$%%###+.%#####%%$&*******&$#$#.+##%#+@,..#++++..+++######%$$$&**==----;;;;-----=**&$%#####++...++#%$%+.+......#######+...@@@@@@@@>@@@@.............++.%$#%&=-==$$******************&$$$%%##+..@@@@@@....@@..++#######%#$==-" "-;;=*$$%%$$$$$$$%%%%$$$$$$$$%###.#+#####%%$&*****&&$%##.@@+%%#.@@.###.+++#########%$$$&&**==---;;;;;;;;;==***$$%%%###+@.##%$$$#....++++#######+...@@....@.>,,@@@@@@@@@@@.......@.#+#$===$%%$&**$$$$$$$$$$$$$$$$%%###+.@@,,,,>,,,,,@@@...+#######.%$*" "*====&$##%$$$$$%%%%%%$$$$$$$$%%#.#+######%$$&****&$$$%%##@.%$+..@@.++..+##########%$&&&&&*==---;;;;;;;;;-===*&$$$$%%%#.+$&$&&&*$$#.+##+++++++++..@@.......>,>,@@@@@@@@@@@@@@@.@@+##.#**&$####$$$$$$$$$$$$$$$$$%%####+.@,,,>>'>>>>>>,@@@..+++....,#$*" )) snd-16.1/snd14.scm0000644000076400007640000002362212462431710011775 0ustar bilbil(define trap-segfault (dilambda (lambda () #f) (lambda (val) val))) (define* (if-cursor-follows-play-it-stays-where-play-stopped (enable #t)) (set! *with-tracking-cursor* (and enable :track-and-stay))) (define* (find-channel func (beg 0) snd chn edpos) (scan-channel func beg #f snd chn edpos)) (define scan-chan scan-channel) (define* (map-chan proc beg end origin snd chn edpos) (map-channel proc beg (+ (- end beg) 1) snd chn edpos origin)) (define smooth-vct smooth-float-vector) (define vct-polynomial float-vector-polynomial) (define mix->vct mix->float-vector) (define pan-mix-vct pan-mix-float-vector) (define vct-size float-vector-size) #| ;;; -------- sound segmentation ;;; ;;; this code was used to return note on and off points for the Iowa Musical Instrument Sound library ;;; the main function takes the top level directory of the sounds, and returns (eventually) a text ;;; file containing the start times (in samples) and durations of all the notes (each sound file in ;;; this library can have about 12 notes). The results of this function need to be fixed up by hand ;;; in some cases (violin notes in particular). ;;; this code needs closedir, readdir and opendir (Guile-isms, I think) (define* (sounds->segment-data main-dir (output-file "sounds.data")) (define (lower-case-and-no-spaces name) (let* ((new-name (string-downcase name)) (len (length new-name))) (do ((i 0 (+ i 1))) ((= i len) new-name) (if (char=? (new-name i) #\space) (set! (new-name i) #\-))))) (define (directory->list dir) (let ((dport (opendir dir)) (ctr 0)) ; try to avoid infinite loop in the broken cases (let loop ((entry (readdir dport)) (files ())) (set! ctr (+ ctr 1)) (if (and (< ctr 2000) (not (eof-object? entry))) (loop (readdir dport) (cons entry files)) (begin (closedir dport) (reverse! files)))))) (define (segment-maxamp name beg dur) (float-vector-peak (samples beg dur name))) (define (segment-sound name high low) (let* ((end (framples name)) (reader (make-sampler 0 name)) ; no need to open the sound and display it (avg (make-moving-average :size 128)) (lavg (make-moving-average :size 2048)) ; to distinguish between slow pulse train (low horn) and actual silence (segments (make-float-vector 100)) (segctr 0) (possible-end 0) (in-sound #f)) ;; this block is where 99% of the time goes (do ((i 0 (+ i 1))) ((= i end)) (let* ((samp (abs (next-sample reader))) (val (moving-average avg samp)) (lval (moving-average lavg samp))) (if in-sound (if (< val low) (begin (set! possible-end i) (if (< lval low) (begin (set! (segments segctr) (+ possible-end 128)) (set! segctr (+ segctr 1)) (set! in-sound #f))))) (if (> val high) (begin (set! (segments segctr) (- i 128)) (set! segctr (+ segctr 1)) (set! in-sound #t)))))) (if in-sound (begin (set! (segments segctr) end) (list (+ 1 segctr) segments)) (list segctr segments)))) (define* (do-one-directory fd dir-name ins-name (high .01) (low .001)) (snd-print (format #f ";~A~%" dir-name)) (for-each (lambda (sound) (let* ((sound-name (string-append dir-name "/" sound)) (boundary-data (segment-sound sound-name high low)) (boundaries (cadr boundary-data)) (segments (car boundary-data))) (format fd "~%~%;;; ~A" sound) (format fd "~%(~A ~S" ins-name (string-append dir-name "/" sound)) (do ((bnd 0 (+ bnd 2))) ((>= bnd segments)) (let* ((segbeg (floor (boundaries bnd))) (segdur (floor (- (boundaries (+ 1 bnd)) segbeg)))) (format fd " (~A ~A ~A)" segbeg segdur (segment-maxamp sound-name segbeg segdur)))) (format fd ")") (mus-sound-forget (string-append dir-name "/" sound)))) (sound-files-in-directory dir-name))) (call-with-output-file output-file (lambda (fd) (let ((old-fam (with-file-monitor))) (set! (with-file-monitor) #f) ; no need to monitor these guys (format fd ";;; sound data from ~S" main-dir) (if (not (char=? (main-dir (- (length main-dir) 1)) #\/)) (set! main-dir (string-append main-dir "/"))) (for-each (lambda (dir) (if (not (char=? (dir 0) #\.)) (let ((ins-name (lower-case-and-no-spaces dir))) (format fd "~%~%;;; ---------------- ~A ----------------" dir) (if (string=? dir "Piano") (for-each (lambda (inner-dir) (if (not (char=? (inner-dir 0) #\.)) (do-one-directory fd (string-append main-dir dir "/" inner-dir) ins-name .001 .0001))) ; pp piano notes are .01 maxamp and short (directory->list (string-append main-dir dir))) (do-one-directory fd (string-append main-dir dir) ins-name))))) (directory->list main-dir)) (set! (with-file-monitor) old-fam))))) ;;; (sounds->segment-data "/home/bil/test/iowa/sounds/" "iowa.data") |# ;;; not replaced: ;;; dac-hook stop-dac-hook with-level-meters make-level-meter save-mixes ;;; mus-sound-close-input mus-sound-close-output mus-sound-open-input mus-sound-open-output ;;; mus-sound-read mus-sound-reopen-output mus-sound-seek-frame mus-sound-write (define continue-float-vector->file continue-frample->file) (define continue-frame->file continue-frample->file) (define file->float-vector file->frample) (define file->float-vector? file->frample?) (define file->frame file->frample) (define file->frame? file->frample?) (define float-vector->file frample->file) (define float-vector->file? frample->file?) (define (float-vector-mix f m o) (frample->frample m f o)) (define frame float-vector) (define (frame* f1 f2 outf) (float-vector-multiply! (copy f1 (or outf (make-float-vector (length f1)))) f2)) (define (frame+ f1 f2 outf) (float-vector-add! (copy f1 (or outf (make-float-vector (length f1)))) f2)) (define frame->file frample->file) (define frame->file? frample->file?) (define (frame->frame a b c) (if (> (length a) (length b)) (frample->frample a b c) (frample->frample b a c))) (define (frame->list a) (copy a (make-list (length a)))) (define frame->sample dot-product) (define sample->frame frame*) (define frame-ref float-vector-ref) (define frame-set! float-vector-set!) (define (frame? obj) (and (float-vector? obj) (= (vector-rank obj) 1))) (define frames framples) (define make-file->float-vector make-file->frample) (define make-file->frame make-file->frample) (define make-float-vector->file make-frample->file) (define (make-frame chans . args) (let ((v (make-float-vector chans))) (do ((i 0 (+ i 1)) (arg args (cdr args))) ((null? arg) v) (set! (v i) (car arg))))) (define make-frame! make-frame) (define make-frame->file make-frample->file) (define (mixer-rows mx) (floor (sqrt (length mx)))) (define (make-mixer chans . args) (let ((v (make-float-vector (* chans chans)))) (do ((i 0 (+ i 1)) (arg args (cdr args))) ((null? arg) v) (set! (v i) (car arg))))) (define make-mixer! make-mixer) (define (make-scalar-mixer chans val) (let ((m (make-float-vector (* chans chans) 0.0))) (do ((i 0 (+ i 1))) ((= i chans) m) (set! (m (+ (* i chans) i)) val)))) (define (make-sound-data c f) (make-float-vector (list c f))) (define (mixer . args) (apply make-mixer (floor (sqrt (length args))) args)) (define mixer+ frame+) (define (mixer-ref mx i j) (mx (+ (* i (mixer-rows mx)) j))) (define (mixer-set! mx i j val) (set! (mx (+ (* i (mixer-rows mx)) j)) val)) (define (mixer? obj) (and (float-vector? obj) (= (vector-rank obj) 1) (let ((d (mixer-rows mx))) (= (* d d) (length obj))))) (define* (mixer* m1 m2 m3) (let ((rows (mixer-rows m1)) (m4 (or m3 (make-float-vector (length m1))))) (do ((i 0 (+ i 1))) ((= i rows) m4) (do ((j 0 (+ j 1))) ((= j rows)) (let ((sum 0.0)) (do ((k 0 (+ k 1))) ((= k rows)) (set! sum (+ sum (* (m1 (+ (* i rows) k)) (m2 (+ (* k rows) j)))))) (set! (m4 (+ (* i rows) j)) sum)))))) (define multiply-arrays float-vector-multiply!) (define mus-sound-frames mus-sound-framples) (define region-frames region-framples) (define selection-frames selection-framples) (define (sound-data+ x1 x2) (if (real? x1) (if (real? x2) (+ x1 x2) (float-vector-offset! x2 x1)) (if (real? x2) (float-vector-offset! x1 x2) (float-vector-add! x1 x2)))) (define (sound-data* x1 x2) (if (real? x1) (if (real? x2) (* x1 x2) (float-vector-scale! x2 x1)) (if (real? x2) (float-vector-scale! x1 x2) (float-vector-multiply! x1 x2)))) (define sound-data-add! float-vector-add!) (define (sound-data-chans s) ((vector-dimensions s) 0)) (define sound-data-copy copy) (define sound-data-fill! fill!) (define (sound-data-length s) ((vector-dimensions s) 1)) (define (sound-data-maxamp s) (let* ((chans (sound-data-chans s)) (maxamps (make-list chans))) (do ((i 0 (+ i 1))) ((= i chans) maxamps) (set! (maxamps i) (float-vector-peak (s i)))))) (define sound-data-multiply! float-vector-multiply!) (define sound-data-offset! float-vector-offset!) (define sound-data-peak float-vector-peak) (define sound-data-ref float-vector-ref) (define (sound-data-reverse! s) (let ((chans (sound-data-chans s))) (do ((i 0 (+ i 1))) ((= i chans) s) (reverse! (s i))))) (define sound-data-scale! float-vector-scale!) (define sound-data-set! float-vector-set!) (define (sound-data? s) (and (float-vector? s) (= (vector-rank s) 2))) (define transform-frames transform-framples) (define vct-copy copy) (define vct-fill! fill!) (define vct float-vector) (define vct-length length) (define vct-reverse! reverse!) ; slight difference: no optional length arg (use make-shared-vector) (define vct->list vector->list) (define (list->vct x) (apply float-vector x)) (define make-vct make-float-vector) (define (vector->vct v) (copy v (make-float-vector (length v)))) (define (vct->vector v) (copy v (make-vector (length v)))) (define vct? float-vector?) snd-16.1/sndlib2xen.h0000644000076400007640000000156112362235504012561 0ustar bilbil#ifndef SNDLIB2XEN_H #define SNDLIB2XEN_H #include "xen.h" /* error indications */ #define NO_SUCH_CHANNEL Xen_make_error_type("no-such-channel") #define NO_SUCH_FILE Xen_make_error_type("no-such-file") #define BAD_TYPE Xen_make_error_type("bad-type") #define NO_DATA Xen_make_error_type("no-data") #define BAD_HEADER Xen_make_error_type("bad-header") #ifdef __cplusplus extern "C" { #endif MUS_EXPORT void mus_sndlib_xen_initialize (void); MUS_EXPORT Xen g_mus_sound_srate(Xen filename); /* snd-snd.c */ MUS_EXPORT Xen g_mus_sound_chans(Xen filename); /* snd-snd.c */ MUS_EXPORT Xen g_mus_sound_framples(Xen filename); /* snd-chn.c */ MUS_EXPORT Xen g_mus_expand_filename(Xen file); /* snd-snd.c */ MUS_EXPORT Xen g_mus_sound_maxamp(Xen file); /* snd-chn.c */ MUS_EXPORT Xen g_mus_sound_path(void); #ifdef __cplusplus } #endif #endif snd-16.1/mus-config.h.in0000644000076400007640000000534512504621660013171 0ustar bilbil#ifndef MUS_CONFIG_H_LOADED #define MUS_CONFIG_H_LOADED /* --disable-deprecated */ #undef DISABLE_DEPRECATED /* --with-temp-dir */ #undef MUS_DEFAULT_TEMP_DIR /* --with-save-dir */ #undef MUS_DEFAULT_SAVE_DIR /* --with-doc-dir */ #undef MUS_DEFAULT_DOC_DIR /* --with-gmp */ #undef WITH_GMP /* --with-pulseaudio */ #undef MUS_PULSEAUDIO /* --with-portaudio -- obsolete? hard to tell from the website */ #undef MUS_PORTAUDIO /* --with-ladspa */ #undef HAVE_LADSPA /* --with-fftw or if fftw.pc exists */ #undef HAVE_FFTW3 /* --with-gsl or if gsl.pc exists */ #undef HAVE_GSL /* --with-gl, also glu if glu.pc exists */ #undef HAVE_GL #undef HAVE_GLU /* --with-gl2ps */ #undef WITH_GL2PS /* the default or --with-s7 */ #undef HAVE_SCHEME /* --with-ruby */ #undef HAVE_RUBY /* --with-forth */ #undef HAVE_FORTH /* the default or --with-gtk */ #undef USE_GTK /* --with-motif */ #undef USE_MOTIF /* --with-editres (requires --with-motif) */ #undef WITH_EDITRES /* --without-gui */ #undef USE_NO_GUI /* --with-oss */ #undef HAVE_OSS /* --with-alsa and default in linux */ #undef HAVE_ALSA /* --with-jack */ #undef MUS_JACK /* --without-audio */ #undef WITH_AUDIO /* paths to various audio decoders */ #undef HAVE_OGG #undef PATH_OGGDEC #undef PATH_OGGENC /* ogg.pc, exec_prefix/bin/ogg* */ #undef HAVE_FLAC #undef PATH_FLAC #undef HAVE_SPEEX #undef PATH_SPEEXDEC #undef PATH_SPEEXENC #undef HAVE_TIMIDITY #undef PATH_TIMIDITY #undef HAVE_MPEG #undef PATH_MPG123 #undef HAVE_MPG321 #undef PATH_MPG321 #undef HAVE_TTA #undef PATH_TTA #undef HAVE_WAVPACK #undef PATH_WAVPACK #undef PATH_WVUNPACK #undef WORDS_BIGENDIAN /* __LITTLE_ENDIAN__ = 1 if gcc osx, but not linux __x86_64? I think it's worth a try to simply use __BIG_ENDIAN__ here it won't work everywhere, but neither will the rest of the code */ #ifdef __SIZEOF__POINTER__ #define SIZEOF_VOID_P __SIZEOF_POINTER__ #else #undef SIZEOF_VOID_P #endif /* ---------------------------------------- */ #ifndef USE_SND #define USE_SND 1 #endif #if HAVE_SCHEME #define WITH_SYSTEM_EXTRAS 1 #endif #ifndef HAVE_EXTENSION_LANGUAGE #define HAVE_EXTENSION_LANGUAGE (HAVE_SCHEME || HAVE_RUBY || HAVE_FORTH) #endif #define HAVE_COMPLEX_NUMBERS ((!_MSC_VER) && ((!HAVE_FORTH) || HAVE_COMPLEX)) /* the latter defined in fth-lib.h I think */ #define HAVE_COMPLEX_TRIG ((!_MSC_VER) && (!__cplusplus) && (!__FreeBSD__)) /* this assumes sys/param.h has been included */ #define HAVE_MAKE_RATIO (HAVE_SCHEME) #ifdef _MSC_VER #define ssize_t int #define snprintf _snprintf #define strtoll strtol #if _MSC_VER > 1200 #define _CRT_SECURE_NO_DEPRECATE 1 #define _CRT_NONSTDC_NO_DEPRECATE 1 #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1 #endif #endif #endif snd-16.1/spectr.scm0000644000076400007640000061552212306421671012354 0ustar bilbil;;; Spectra courtesy J.A. Moorer ;;; ;;; I removed phase information and omitted any partials with amplitude below ;;; 0.0001, although this may have thrown away good data, because the original ;;; data was not normalized. (provide 'snd-spectr.scm) ;;; bass clarinet? (define bc-c2 '( 1.00 .0370 1.98 .0037 2.99 .0862 3.98 .0011 4.97 .0270 5.98 .0030 6.97 .0586 7.95 .0031 8.96 .0363 9.95 .0076 10.93 .0310 11.95 .0097 12.93 .0206 13.92 .0045 14.93 .0044 15.91 .0021 16.90 .0220 17.91 .0082 18.90 .0227 19.88 .0049 20.90 .0090 21.87 .0004 22.87 .0051 23.88 .0010 24.86 .0072 25.85 .0026 26.86 .0044 27.84 .0035 28.85 .0031 29.84 .0025 30.83 .0042 31.84 .0024 32.83 .0022 33.81 .0021 34.82 .0011 35.81 .0008 36.79 .0013 37.80 .0024 38.78 .0028 39.78 .0016 40.79 .0024 41.77 .0005 42.76 .0005 43.77 .0003 44.76 .0002 45.74 .0005 46.75 .0003 47.74 .0006 48.73 .0003 49.74 .0009 50.72 .0002 51.71 .0007 52.72 .0004 53.70 .0005 54.70 .0004 55.71 .0005 56.69 .0002 57.68 .0003 58.69 .0002 59.68 .0002 60.68 .0003 61.68 .0002 62.66 .0002 63.66 .0002 65.65 .0001 67.64 .0002 69.63 .0002 70.63 .0002 71.60 .0002 72.62 .0002 73.60 .0002 75.59 .0002 76.59 .0002 77.58 .0001 78.59 .0001 79.57 .0002 80.57 .0002 81.57 .0002 82.54 .0001 83.56 .0002 84.54 .0001 85.53 .0001 87.53 .0002 89.53 .0002)) (define bc-cs2 '( 1.02 .0306 2.00 .0016 2.99 .0926 4.00 .0027 5.01 .0305 5.99 .0006 6.99 .0158 8.00 .0025 9.01 .0072 10.01 .0057 10.99 .0203 12.00 .0078 13.01 .0147 14.02 .0036 15.00 .0103 16.07 .0007 17.01 .0070 18.01 .0053 19.00 .0049 20.02 .0027 21.01 .0024 22.01 .0014 23.00 .0011 24.02 .0023 25.00 .0031 26.01 .0021 27.00 .0029 28.02 .0010 29.02 .0026 30.04 .0011 31.00 .0019 32.01 .0010 33.03 .0004 34.02 .0002 36.02 .0004 37.05 .0002 38.04 .0004 39.00 .0003 40.02 .0002 41.01 .0002 42.01 .0002 43.00 .0001 44.02 .0001 45.01 .0002 47.01 .0002 48.03 .0001 49.00 .0002 50.03 .0001 51.02 .0001 55.00 .0001 56.99 .0002 73.98 .0001 75.02 .0001 75.98 .0001)) (define bc-d2 '( 1.01 .1419 1.97 .0009 3.00 .0865 4.01 .0008 5.00 .0059 6.00 .0009 7.00 .0110 8.00 .0014 9.00 .0050 10.00 .0057 11.01 .0267 12.01 .0091 13.00 .0238 14.02 .0023 15.01 .0069 16.01 .0033 17.00 .0064 18.01 .0036 18.99 .0067 20.01 .0026 21.01 .0047 22.01 .0037 22.99 .0040 24.00 .0038 25.01 .0036 26.01 .0032 27.00 .0036 27.99 .0019 29.00 .0034 30.00 .0014 31.00 .0007 31.98 .0003 33.04 .0002 34.05 .0003 35.04 .0003 35.95 .0002 37.05 .0003 37.98 .0002 39.07 .0002 40.02 .0002 40.95 .0001 42.01 .0003 42.98 .0002 44.02 .0004 44.99 .0002 46.03 .0002 46.98 .0002 48.04 .0001 49.01 .0001 51.02 .0002 52.03 .0002 53.01 .0002 54.01 .0001 55.01 .0002 56.02 .0001 65.00 .0002 66.99 .0001 69.01 .0001 71.00 .0002 73.00 .0001 74.99 .0001)) (define bc-ds2 '( 1.01 .2718 2.01 .0016 3.01 .0476 4.01 .0022 5.01 .0228 6.00 .0005 7.01 .0466 8.01 .0014 9.00 .0179 10.01 .0059 11.00 .0254 12.01 .0099 13.00 .0176 14.01 .0031 15.02 .0109 16.00 .0007 17.02 .0090 18.03 .0038 19.02 .0036 20.02 .0029 21.02 .0045 22.02 .0026 23.02 .0060 24.02 .0031 25.02 .0023 26.02 .0033 27.02 .0041 28.02 .0033 29.02 .0034 30.03 .0007 31.04 .0005 32.03 .0005 33.05 .0005 34.03 .0006 35.05 .0002 36.04 .0004 37.03 .0002 38.03 .0003 39.03 .0004 40.03 .0002 41.03 .0004 42.03 .0003 43.03 .0006 44.04 .0002 45.05 .0005 46.04 .0001 47.05 .0003 48.04 .0002 49.05 .0003 50.04 .0001 51.04 .0003 52.04 .0002 53.04 .0001 55.04 .0002 57.05 .0002 59.06 .0002 61.07 .0002 62.06 .0001 63.06 .0002 64.05 .0001 65.06 .0001 66.06 .0002 67.06 .0002 68.06 .0002 70.06 .0002 72.06 .0001 74.08 .0001)) (define bc-e2 '( 1.01 .1365 2.01 .0009 3.03 .0219 3.99 .0004 5.04 .0239 6.03 .0013 7.02 .0284 8.04 .0029 9.03 .0167 10.06 .0042 11.05 .0059 12.03 .0012 13.07 .0095 14.07 .0013 15.08 .0109 16.06 .0038 17.06 .0042 18.09 .0006 19.07 .0034 20.10 .0036 21.09 .0018 22.08 .0025 23.11 .0054 24.08 .0008 25.12 .0035 26.09 .0013 27.13 .0022 28.13 .0009 29.12 .0006 30.14 .0004 31.13 .0005 32.15 .0003 33.15 .0003 35.15 .0002 36.13 .0001 37.17 .0003 38.19 .0002 39.16 .0006 40.21 .0001 41.17 .0005 42.18 .0002 43.19 .0003 44.18 .0001 45.21 .0002 46.19 .0002 47.22 .0004 48.22 .0002 49.20 .0002 50.23 .0001 55.24 .0001 56.23 .0001 57.26 .0002 59.26 .0001 61.25 .0002 62.29 .0002 64.27 .0001)) (define bc-f2 '( .99 .1014 2.00 .0021 3.02 .0301 4.02 .0012 5.00 .0893 6.02 .0028 7.03 .0333 8.04 .0046 9.05 .0109 10.03 .0033 11.03 .0174 12.05 .0075 13.06 .0085 14.06 .0037 15.04 .0133 16.08 .0021 17.07 .0017 18.07 .0009 19.05 .0015 20.07 .0002 21.08 .0068 22.09 .0033 23.10 .0060 24.07 .0031 25.08 .0036 26.10 .0009 27.11 .0001 28.11 .0010 29.10 .0007 30.10 .0004 31.12 .0005 32.13 .0002 33.11 .0005 34.11 .0003 35.12 .0004 36.13 .0002 37.14 .0005 38.12 .0001 39.14 .0005 40.14 .0002 41.16 .0002 43.14 .0003 45.17 .0004 46.18 .0002 47.16 .0002 49.18 .0002 51.18 .0001 53.19 .0002 55.22 .0001 56.19 .0002 57.21 .0001 58.22 .0002 60.23 .0002 62.22 .0001)) (define bc-fs2 '( 1.01 .0724 2.02 .0045 3.01 .0626 4.01 .0014 5.00 .1104 6.00 .0041 7.00 .0216 8.03 .0017 9.03 .0255 10.02 .0011 11.02 .0152 12.02 .0019 13.01 .0061 14.02 .0018 15.04 .0077 16.05 .0009 17.04 .0031 18.04 .0014 19.02 .0058 20.04 .0005 21.03 .0030 22.03 .0030 23.05 .0048 24.06 .0013 25.04 .0009 26.04 .0002 27.03 .0008 28.05 .0005 29.05 .0003 30.06 .0002 31.06 .0004 32.05 .0005 33.05 .0003 34.04 .0002 35.05 .0004 37.08 .0006 38.06 .0002 39.07 .0003 41.06 .0003 42.07 .0001 43.07 .0003 44.09 .0002 45.10 .0001 47.07 .0001 51.10 .0002 53.10 .0002 54.10 .0001 56.09 .0002 57.09 .0001 58.12 .0001 62.11 .0001 64.11 .0001)) (define bc-g2 '( 1.00 .0567 1.99 .0037 3.00 .1114 3.98 .0030 4.99 .1112 5.98 .0041 6.99 .0195 7.99 .0061 8.98 .0081 9.97 .0084 10.98 .0139 11.98 .0038 12.98 .0092 13.97 .0038 14.97 .0042 15.97 .0003 16.97 .0012 17.96 .0019 18.97 .0040 19.95 .0032 20.97 .0088 21.95 .0022 22.96 .0025 23.94 .0004 24.94 .0003 25.92 .0005 26.95 .0005 27.91 .0003 28.95 .0003 29.90 .0002 30.94 .0006 31.89 .0001 32.93 .0007 34.92 .0005 35.89 .0002 36.92 .0003 37.89 .0001 38.91 .0002 39.88 .0002 40.90 .0004 41.88 .0002 43.88 .0002 50.90 .0001 51.89 .0002 52.93 .0001 53.89 .0003 55.87 .0002)) (define bc-gs2 '( .99 .0794 2.00 .0021 3.00 .1294 3.98 .0015 4.98 .0849 5.98 .0058 6.99 .0389 7.97 .0113 8.97 .0154 9.98 .0026 10.98 .0172 11.95 .0048 12.95 .0099 13.98 .0011 14.97 .0029 15.95 .0013 16.95 .0055 17.97 .0014 18.96 .0052 19.94 .0040 20.94 .0038 21.96 .0006 22.94 .0003 23.92 .0005 24.93 .0005 25.93 .0002 26.94 .0006 27.92 .0003 28.91 .0007 29.91 .0004 30.93 .0006 31.90 .0003 32.90 .0006 33.90 .0003 34.91 .0004 35.89 .0001 36.89 .0003 37.90 .0003 38.90 .0003 40.88 .0002 42.89 .0001 45.89 .0002 47.87 .0001 49.87 .0003 50.86 .0002 51.85 .0002 53.86 .0001)) (define bc-a2 '( .99 .1177 1.99 .0047 2.99 .2346 3.99 .0023 4.98 .0538 5.99 .0060 6.98 .0493 7.99 .0062 8.99 .0103 9.99 .0030 10.99 .0146 11.99 .0126 12.99 .0042 13.99 .0016 14.99 .0060 15.98 .0034 16.96 .0039 17.96 .0036 18.96 .0076 19.96 .0018 20.96 .0025 22.95 .0018 23.95 .0005 24.94 .0003 25.95 .0005 26.95 .0006 27.95 .0008 28.96 .0005 29.96 .0005 30.96 .0007 31.95 .0005 32.95 .0005 33.95 .0001 34.95 .0003 35.93 .0002 36.94 .0003 38.92 .0002 42.93 .0001 44.93 .0001 46.93 .0002 47.92 .0001)) (define bc-as2 '( 1.00 .1279 1.99 .0028 2.99 .1611 3.98 .0034 4.97 .0322 5.97 .0085 6.98 .0274 7.97 .0068 8.96 .0245 9.97 .0022 10.94 .0254 11.93 .0010 12.93 .0078 13.95 .0022 14.94 .0035 15.92 .0022 16.92 .0033 17.91 .0039 18.90 .0037 19.92 .0012 20.92 .0003 21.91 .0008 22.89 .0005 23.88 .0007 24.87 .0007 25.87 .0005 26.88 .0007 27.86 .0001 28.86 .0014 29.84 .0004 30.85 .0005 31.85 .0001 32.85 .0004 33.84 .0004 34.84 .0003 36.82 .0003 40.81 .0003 42.80 .0001 43.79 .0002 44.79 .0002 45.79 .0003 46.79 .0001 47.79 .0002 49.77 .0001)) (define bc-b2 '( 1.00 .1161 1.98 .0036 2.97 .1813 3.98 .0038 4.96 .0298 5.95 .0073 6.95 .0125 7.95 .0064 8.92 .0175 9.94 .0087 10.91 .0117 11.91 .0025 12.91 .0055 13.92 .0027 14.88 .0069 15.88 .0034 16.88 .0052 17.85 .0038 18.88 .0003 19.83 .0005 20.83 .0005 21.78 .0002 22.82 .0004 23.74 .0002 24.81 .0008 25.76 .0003 26.78 .0005 27.78 .0006 28.78 .0005 29.74 .0002 30.75 .0001 31.75 .0004 32.72 .0002 33.73 .0002 34.73 .0002 41.69 .0002 42.68 .0002 43.67 .0002 44.68 .0002 45.67 .0001)) (define bc-c3 '( 1.00 .1579 1.99 .0068 2.99 .1885 3.99 .0022 4.97 .0384 5.96 .0054 6.97 .0247 7.97 .0023 8.96 .0114 9.95 .0096 10.93 .0054 11.95 .0030 12.94 .0036 13.92 .0075 14.93 .0033 15.92 .0052 16.91 .0010 17.91 .0011 18.90 .0004 19.89 .0006 20.90 .0005 21.89 .0003 22.87 .0004 23.88 .0004 24.87 .0005 25.86 .0008 26.87 .0005 27.85 .0002 28.84 .0002 29.85 .0003 30.83 .0002 31.84 .0002 32.83 .0002 35.83 .0001 36.80 .0002 38.81 .0002 39.78 .0002 40.78 .0003 41.79 .0001)) (define bc-cs3 '( 1.00 .2106 1.98 .0073 2.99 .1027 3.98 .0038 4.97 .0191 5.98 .0036 6.97 .0256 7.95 .0035 8.97 .0347 9.95 .0039 10.94 .0048 11.95 .0026 12.94 .0089 13.93 .0011 14.93 .0052 15.93 .0033 16.96 .0002 17.93 .0003 18.94 .0001 19.92 .0002 20.91 .0007 21.91 .0006 22.89 .0005 23.90 .0005 24.90 .0005 25.87 .0005 26.89 .0003 27.88 .0005 28.87 .0003 29.87 .0003 31.85 .0002 33.84 .0001 34.84 .0001 36.82 .0003 37.83 .0001 38.83 .0003)) (define bc-d3 '( 1.01 .2039 2.00 .0041 3.00 .0640 3.99 .0062 5.00 .0192 6.00 .0013 7.01 .0225 8.00 .0034 9.01 .0245 10.00 .0038 11.02 .0028 12.01 .0030 13.02 .0042 14.00 .0021 15.01 .0049 16.02 .0006 17.02 .0003 18.02 .0007 19.00 .0001 20.03 .0005 21.02 .0010 22.05 .0002 23.04 .0012 24.05 .0003 25.02 .0002 26.03 .0003 27.02 .0004 28.03 .0001 29.05 .0002 30.05 .0001 33.03 .0001 34.04 .0001 35.04 .0001 36.04 .0003 38.05 .0001 40.04 .0001)) (define bc-ds3 '( 1.01 .1501 2.00 .0036 3.00 .0682 4.00 .0069 4.99 .0142 5.98 .0017 6.99 .0322 7.99 .0063 8.98 .0019 10.00 .0010 11.00 .0046 11.99 .0023 12.99 .0035 13.98 .0041 14.98 .0020 15.97 .0001 16.98 .0003 17.98 .0008 18.98 .0009 20.03 .0002 21.00 .0007 21.99 .0006 22.99 .0006 23.99 .0003 24.98 .0004 25.98 .0003 26.97 .0001 27.98 .0001 29.97 .0001 30.98 .0002 32.96 .0003 33.97 .0003 34.95 .0002 35.96 .0002 36.97 .0001)) (define bc-e3 '( .99 .1413 1.99 .0047 3.00 .0710 4.01 .0016 5.01 .0154 6.01 .0063 7.01 .0122 8.02 .0179 9.00 .0044 10.00 .0082 11.01 .0058 12.01 .0031 13.02 .0045 14.02 .0027 15.02 .0004 16.03 .0010 17.01 .0008 18.04 .0002 19.04 .0004 20.03 .0006 21.04 .0004 22.03 .0003 23.04 .0004 24.04 .0002 25.04 .0003 26.06 .0001 27.04 .0003 28.03 .0002 29.02 .0003 30.99 .0002 32.04 .0006 33.03 .0002 34.04 .0003 36.04 .0001)) (define bc-f3 '( .99 .2534 1.99 .0057 3.00 .0476 3.98 .0101 4.98 .0334 5.97 .0066 6.98 .0489 7.96 .0038 8.96 .0096 9.95 .0008 10.96 .0056 11.95 .0049 12.95 .0029 13.95 .0002 14.95 .0006 15.96 .0002 16.96 .0008 17.94 .0004 18.93 .0002 19.94 .0009 20.94 .0002 21.93 .0004 22.94 .0004 23.93 .0004 25.90 .0004 26.90 .0003 27.89 .0001 28.91 .0004 29.87 .0001 30.89 .0005 32.89 .0002 33.87 .0001)) (define bc-fs3 '( 1.00 .3131 1.99 .0095 3.00 .0885 3.99 .0194 4.98 .0653 5.99 .0049 6.98 .0528 7.99 .0038 8.98 .0129 9.97 .0042 10.98 .0063 11.97 .0023 12.97 .0016 13.98 .0002 14.97 .0004 15.97 .0005 16.97 .0006 17.96 .0001 18.96 .0008 20.95 .0007 21.96 .0001 22.95 .0001 23.94 .0003 25.94 .0004 26.95 .0004 27.94 .0005 28.93 .0003 29.94 .0003 31.93 .0002 33.92 .0002)) (define bc-g3 '( 1.00 .2177 2.01 .0024 3.01 .0126 4.02 .0067 5.02 .0577 6.02 .0083 7.02 .0215 8.03 .0034 9.03 .0047 10.04 .0046 11.05 .0143 12.04 .0037 13.04 .0010 14.05 .0005 15.06 .0005 16.06 .0003 17.06 .0002 18.06 .0004 19.09 .0001 20.08 .0003 21.08 .0002 23.08 .0003 24.08 .0003 25.08 .0001 26.10 .0010 27.11 .0002 28.10 .0004 30.12 .0003 32.13 .0003)) (define bc-gs3 '( 1.01 .1420 2.01 .0026 3.01 .0289 4.03 .0162 5.03 .0373 6.02 .0015 7.03 .0112 8.05 .0068 9.05 .0063 10.04 .0027 11.06 .0022 12.07 .0004 13.06 .0008 14.07 .0011 15.08 .0003 16.08 .0002 17.09 .0005 19.11 .0003 23.12 .0004 24.12 .0003 25.14 .0002 26.14 .0003 27.14 .0002 28.14 .0002 29.16 .0002 30.16 .0001 34.18 .0002)) (define bc-a3 '( 1.01 .2365 2.02 .0034 3.03 .0242 4.04 .0251 5.04 .0203 6.06 .0078 7.06 .0213 8.08 .0162 9.09 .0121 10.10 .0053 11.11 .0024 12.12 .0028 13.14 .0010 14.13 .0006 15.15 .0009 16.16 .0008 17.17 .0009 18.18 .0006 19.19 .0003 20.20 .0003 21.20 .0003 22.22 .0004 23.22 .0002 24.24 .0007 26.26 .0003 27.26 .0001 29.29 .0003)) (define bc-as3 '( 1.00 .1078 2.01 .0072 3.02 .0487 4.04 .0332 5.05 .0329 6.06 .0069 7.07 .0153 8.08 .0061 9.08 .0082 10.09 .0023 11.10 .0003 12.11 .0009 13.12 .0008 14.13 .0007 15.15 .0003 16.16 .0006 17.16 .0007 18.16 .0003 19.17 .0003 20.18 .0005 21.19 .0005 22.20 .0005 23.22 .0004 24.23 .0001 26.25 .0001 27.25 .0001 28.26 .0001)) (define bc-b3 '( 1.01 .0572 2.02 .0086 3.03 .0724 4.04 .0057 5.04 .0365 6.05 .0058 7.06 .0083 8.07 .0113 9.08 .0102 10.09 .0022 11.10 .0012 12.11 .0005 13.11 .0014 14.12 .0003 15.13 .0008 16.14 .0009 17.15 .0003 18.16 .0002 19.17 .0006 20.18 .0009 21.19 .0002 22.19 .0006 23.20 .0004 24.21 .0004 25.22 .0001)) (define bc-c4 '( 1.01 .0509 2.02 .0146 3.02 .0344 4.03 .0126 5.04 .0254 6.05 .0004 7.05 .0134 8.06 .0069 9.08 .0007 10.09 .0005 11.09 .0006 12.09 .0004 13.11 .0010 14.12 .0001 15.12 .0008 16.13 .0001 17.14 .0003 18.15 .0002 19.17 .0001 20.16 .0004 21.17 .0002)) (define bc-cs4 '( 1.00 .1853 2.00 .0169 3.01 .0922 4.01 .0035 5.01 .0204 6.01 .0046 7.02 .0077 8.02 .0085 9.02 .0028 10.05 .0002 11.02 .0003 12.03 .0006 13.05 .0002 14.03 .0006 15.04 .0006 16.04 .0004 17.02 .0003 18.04 .0006 19.04 .0004 20.04 .0003 21.06 .0001 22.04 .0001 23.06 .0002)) (define bc-d4 '( 1.00 .3391 2.00 .0134 2.99 .0186 3.99 .0424 4.98 .0122 5.98 .0055 6.97 .0197 7.98 .0034 8.97 .0017 9.98 .0004 10.96 .0008 11.96 .0009 12.96 .0003 13.96 .0007 14.95 .0004 15.94 .0002 16.95 .0003 17.94 .0008 18.93 .0002 19.93 .0001)) (define bc-ds4 '( .99 .3684 1.98 .0187 2.98 .0647 3.97 .0186 4.97 .0070 5.96 .0127 6.95 .0173 7.94 .0011 8.94 .0011 9.93 .0014 10.92 .0013 11.90 .0001 12.90 .0006 13.91 .0003 14.89 .0003 15.89 .0001 16.88 .0010 17.88 .0004 18.86 .0001 19.86 .0002 20.85 .0001)) (define bc-e4 '( 1.00 .5390 3.01 .0188 4.00 .0247 5.00 .0129 6.01 .0050 7.01 .0014 8.01 .0012 9.01 .0012 10.01 .0010 11.02 .0005 12.02 .0002 13.03 .0004)) (define bc-f4 '( 1.01 .5398 2.01 .0309 3.01 .0727 4.01 .0062 5.01 .0041 6.02 .0280 7.02 .0005 8.02 .0014 9.02 .0013 10.02 .0030 11.03 .0006 12.03 .0004 14.03 .0003 15.04 .0003 16.04 .0007)) (define bc-fs4 '( 1.00 .6398 2.01 .0314 3.01 .0423 4.01 .0292 5.01 .0093 6.02 .0088 7.02 .0010 8.03 .0043 9.02 .0004 10.03 .0013 11.03 .0003 12.04 .0003 13.02 .0002 14.04 .0010 15.04 .0006 16.05 .0001 17.04 .0003)) (define bc-g4 '( 1.00 .5985 1.99 .0192 2.99 .0346 3.99 .0257 4.98 .0082 5.98 .0037 6.98 .0008 7.99 .0013 8.97 .0014 9.98 .0016 10.98 .0010 11.98 .0005 12.97 .0005 13.97 .0008 14.95 .0002 15.96 .0003)) (define bc-gs4 '( 1.00 .2635 1.99 .0230 2.99 .0936 3.99 .0214 4.99 .0320 5.99 .0013 6.99 .0020 7.99 .0004 8.99 .0014 9.99 .0003 10.99 .0003 11.98 .0005 12.98 .0015 13.98 .0005 14.98 .0003 15.98 .0003 18.98 .0001)) (define bc-a4 '( 1.00 .1539 2.00 .0355 3.00 .0834 4.01 .0210 5.01 .0103 6.00 .0035 7.02 .0004 8.01 .0008 9.00 .0002 10.01 .0001 11.01 .0005 12.01 .0007 13.02 .0011 14.01 .0003 15.02 .0003 18.02 .0002)) (define bc-as4 '( 1.00 .1843 2.01 .0229 3.00 .0348 4.01 .0157 5.01 .0170 6.01 .0037 7.02 .0012 8.02 .0027 9.02 .0003 10.02 .0011 11.03 .0010 12.03 .0007 13.03 .0004 14.03 .0002 15.03 .0002 17.04 .0002)) (define bc-b4 '( 1.00 .5063 2.01 .0563 3.01 .0376 4.01 .0383 5.01 .0135 6.02 .0081 7.02 .0011 8.02 .0049 9.03 .0007 10.03 .0006 11.04 .0013 12.04 .0007 13.04 .0004 14.05 .0002 15.05 .0002 17.05 .0002 19.06 .0001)) (define bc-c5 '( 1.00 .5459 2.00 .0278 3.01 .0456 4.01 .0648 5.02 .0035 6.02 .0050 7.02 .0025 8.02 .0021 9.02 .0005 10.03 .0007 11.03 .0016 12.03 .0007 13.04 .0001 14.03 .0002 15.04 .0002 18.05 .0002 19.05 .0001 20.05 .0002)) (define bc-cs5 '( 1.00 .2584 2.01 .0583 3.02 .1090 4.02 .0290 5.02 .0020 6.03 .0018 7.03 .0016 8.03 .0001 9.04 .0005 10.05 .0017 11.05 .0010 12.05 .0002 13.06 .0001 14.06 .0001 17.08 .0002 18.08 .0001 19.08 .0001)) (define bc-d5 '( 1.00 .1626 2.00 .0485 3.01 .0856 4.00 .0023 5.01 .0096 6.01 .0042 7.01 .0015 8.01 .0004 9.02 .0019 10.02 .0016 11.02 .0003 12.02 .0002 13.02 .0002 16.03 .0001 17.03 .0001 18.03 .0002 19.03 .0001)) (define bc-ds5 '( 1.00 .1756 1.99 .1645 2.99 .0381 3.98 .0028 4.98 .0042 5.98 .0004 6.97 .0025 7.97 .0006 8.96 .0022 9.96 .0011 10.96 .0002 13.94 .0002 14.94 .0002 15.94 .0001 16.93 .0001 17.93 .0001)) (define bc-e5 '( .99 .2661 1.99 .1398 2.99 .0589 3.99 .0048 4.98 .0022 5.98 .0015 6.97 .0021 7.97 .0008 8.96 .0011 9.96 .0009 10.95 .0004 11.94 .0001 13.94 .0001 14.94 .0001 15.94 .0001)) (define bc-f5 '( 1.00 .1378 2.00 .0654 3.00 .1301 4.00 .0049 5.00 .0030 6.01 .0018 7.01 .0030 8.01 .0015 9.01 .0008 10.01 .0001 11.01 .0003 12.01 .0002 13.01 .0001 14.01 .0002 15.01 .0002 16.02 .0001)) (define bc-fs5 '( 1.00 .3952 2.01 .1124 3.01 .0326 4.02 .0104 5.03 .0013 6.03 .0010 7.03 .0009 8.04 .0009 9.05 .0002 10.05 .0003 11.05 .0001 13.06 .0002 14.07 .0003 15.08 .0002)) (define bc-g5 '( 1.01 .3434 2.01 .0390 3.02 .0051 4.03 .0057 5.04 .0042 6.05 .0017 7.06 .0022 8.06 .0012 9.07 .0002 10.07 .0001 11.08 .0002 12.09 .0002 13.10 .0002 14.11 .0002 15.12 .0001)) (define bc-gs5 '( 1.00 .1109 1.99 .0911 2.98 .0061 3.98 .0062 4.98 .0020 5.97 .0006 6.96 .0008 7.96 .0013 8.95 .0002 10.94 .0002 11.94 .0002 12.93 .0002 13.93 .0001)) (define bc-a5 '( 1.00 .1585 2.00 .0562 3.00 .0039 4.00 .0064 5.00 .0016 6.00 .0022 7.00 .0009 8.00 .0004 9.00 .0002 11.00 .0003 12.00 .0003 13.00 .0002 14.00 .0002)) (define bc-as5 '( .99 .1211 1.98 .0394 2.97 .0093 3.96 .0024 4.95 .0030 5.94 .0027 6.93 .0006 8.92 .0002 10.90 .0001 12.88 .0001)) ;;; ;;; ;;; ;;; ;;; bassoon? (define bsn-as1 '( 1.00 .0038 2.02 .0235 3.04 .0511 4.06 .0348 5.07 .0491 6.09 .0518 7.11 .0184 8.12 .0381 9.11 .1027 10.13 .0412 11.15 .0112 12.17 .0144 13.18 .0097 14.20 .0074 15.21 .0081 16.23 .0067 17.22 .0108 18.24 .0113 19.25 .0114 20.28 .0066 21.30 .0065 22.32 .0035 23.33 .0041 24.33 .0036 25.34 .0025 26.35 .0010 27.37 .0021 28.39 .0007 29.42 .0006 30.42 .0009 31.43 .0005 32.43 .0003 33.46 .0005 34.46 .0002 35.48 .0002 36.48 .0004 37.52 .0003 38.53 .0003 39.55 .0002 40.56 .0002 51.69 .0001 54.72 .0002)) (define bsn-b1 '( 1.01 .0039 2.02 .0230 3.02 .0517 4.03 .0473 5.03 .0443 6.03 .0691 7.03 .0664 8.04 .0408 9.04 .1283 10.06 .0429 11.07 .0339 12.08 .0223 13.08 .0207 14.08 .0256 15.08 .0171 16.09 .0106 17.09 .0136 18.09 .0082 19.12 .0052 20.12 .0041 21.13 .0015 22.13 .0023 23.12 .0021 24.12 .0009 25.13 .0029 26.14 .0014 27.15 .0003 28.15 .0010 29.17 .0013 30.18 .0003 31.19 .0005 32.19 .0007 33.19 .0004 34.20 .0005 35.19 .0005 36.19 .0003 37.21 .0003 38.23 .0002 39.23 .0001 40.23 .0001 43.23 .0001 46.26 .0002 49.27 .0002 51.27 .0003 52.27 .0002 53.28 .0002)) (define bsn-c2 '( 1.01 .0047 2.03 .0390 3.04 .0460 4.04 .0217 5.05 .0464 6.05 .0631 7.06 .0874 8.07 .1167 9.08 .0339 10.09 .0209 11.11 .0133 12.12 .0088 13.11 .0092 14.14 .0032 15.15 .0026 16.16 .0061 17.17 .0019 18.17 .0051 19.18 .0161 20.18 .0048 21.20 .0044 22.21 .0035 23.23 .0010 24.24 .0028 25.25 .0006 26.26 .0013 27.27 .0016 28.26 .0002 29.28 .0006 30.28 .0006 31.30 .0004 32.32 .0012 33.33 .0003 34.34 .0003 35.35 .0002 36.34 .0001 43.41 .0001 46.43 .0001 48.44 .0001 51.48 .0001)) (define bsn-cs2 '( 1.01 .0090 2.02 .0531 3.01 .0318 4.01 .0199 5.02 .0211 6.04 .0629 7.04 .1340 8.05 .0925 9.04 .0206 10.04 .0584 11.05 .0140 12.07 .0066 13.08 .0068 14.08 .0011 15.07 .0028 16.07 .0015 17.08 .0041 18.10 .0106 19.10 .0034 20.10 .0033 21.10 .0020 22.10 .0021 23.11 .0040 24.13 .0001 25.12 .0004 26.13 .0003 28.13 .0004 29.14 .0002 30.16 .0001 31.17 .0001 43.20 .0001 46.22 .0002)) (define bsn-d2 '( 1.01 .0616 2.00 .0436 3.00 .0430 3.99 .0491 5.01 .0358 6.01 .1695 7.00 .1562 7.99 .0174 8.99 .0062 10.01 .0054 11.00 .0104 12.00 .0055 12.99 .0052 13.99 .0018 15.00 .0021 16.00 .0019 16.99 .0087 17.98 .0025 18.99 .0027 20.00 .0015 21.00 .0024 21.98 .0015 22.99 .0002 24.00 .0006 25.99 .0001 26.95 .0001 28.00 .0001 28.94 .0001 30.01 .0002)) (define bsn-ds2 '( 1.01 .0769 2.01 .0341 3.00 .0240 4.00 .0633 5.00 .0124 5.99 .0850 6.99 .1044 7.99 .0115 8.99 .0046 10.00 .0048 11.00 .0054 12.00 .0082 13.00 .0033 14.00 .0080 15.00 .0022 15.99 .0081 16.99 .0028 17.98 .0038 18.98 .0028 19.99 .0032 20.99 .0007 22.00 .0003 22.98 .0004 23.99 .0001 24.98 .0005 25.98 .0002 26.97 .0003 28.98 .0001 38.97 .0001 40.97 .0001)) (define bsn-e2 '( 1.00 .0369 1.98 .0190 3.00 .0291 3.98 .0844 5.00 .0730 5.98 .0856 7.00 .0563 7.98 .0792 9.00 .0139 9.97 .0127 10.99 .0046 11.96 .0052 12.99 .0043 13.97 .0030 14.99 .0102 15.98 .0020 16.97 .0029 17.98 .0010 18.96 .0040 19.98 .0008 20.97 .0004 21.99 .0001 23.98 .0004 25.96 .0002 26.93 .0001 36.94 .0001)) (define bsn-f2 '( .99 .0208 2.00 .0164 3.01 .0576 4.02 .0547 5.02 .0965 5.99 .1701 7.00 .0206 8.01 .0040 9.02 .0075 10.02 .0033 11.00 .0067 12.00 .0021 13.01 .0010 14.02 .0072 15.03 .0014 16.01 .0028 17.01 .0034 18.02 .0026 19.03 .0007 20.05 .0004 20.43 .0001 22.02 .0001 24.01 .0003 26.03 .0001)) (define bsn-fs2 '( 1.00 .0112 1.99 .0211 2.98 .0379 3.97 .0630 4.98 .0727 5.97 .1555 6.95 .0348 7.94 .0362 8.96 .0083 9.94 .0145 10.92 .0070 11.91 .0031 12.93 .0059 13.92 .0054 14.91 .0024 15.89 .0024 16.88 .0045 17.90 .0013 18.91 .0007 19.87 .0005 20.87 .0004 21.88 .0002 22.85 .0007 23.84 .0003 24.83 .0002 26.84 .0001 28.80 .0002 29.80 .0001 30.81 .0003 31.81 .0001 32.78 .0003 33.77 .0001 34.79 .0002)) (define bsn-g2 '( .98 .0330 1.99 .0314 2.95 .0487 3.95 .0272 4.95 .2864 5.91 .0849 6.92 .0047 7.89 .0049 8.88 .0015 9.88 .0060 10.85 .0051 11.85 .0013 12.83 .0083 13.82 .0018 14.82 .0010 15.78 .0032 16.79 .0007 17.77 .0004 18.76 .0005 19.76 .0008 20.72 .0004 21.72 .0009 22.72 .0003 23.69 .0002)) (define bsn-gs2 '( .98 .0321 1.98 .0281 2.99 .0196 3.99 .0683 4.96 .2698 5.95 .0125 6.95 .0153 7.96 .0034 8.96 .0050 9.93 .0056 10.92 .0049 11.92 .0160 12.92 .0072 13.91 .0013 14.89 .0028 15.91 .0005 16.86 .0004 17.89 .0006 18.89 .0009 19.87 .0005 20.85 .0001 21.87 .0003 27.83 .0001 28.82 .0002)) (define bsn-a2 '( .99 .0170 2.00 .0296 3.00 .0324 4.01 .1542 5.02 .1393 6.02 .0249 7.03 .0041 8.03 .0022 9.01 .0043 10.02 .0077 11.03 .0092 12.04 .0021 13.04 .0027 14.05 .0026 15.06 .0007 16.05 .0001 17.05 .0003 18.04 .0006 19.04 .0004 20.05 .0002 26.06 .0003 27.06 .0002 29.07 .0001)) (define bsn-as2 '( 1.01 .0153 2.00 .0261 3.00 .0305 3.99 .1573 4.97 .0908 5.98 .0053 6.97 .0054 7.98 .0159 8.99 .0031 9.99 .0015 10.96 .0124 11.96 .0020 12.95 .0026 13.94 .0034 14.94 .0005 16.95 .0007 17.93 .0002 18.94 .0003 24.92 .0002 25.91 .0002 27.89 .0002 28.89 .0001)) (define bsn-b2 '( 1.01 .0061 2.00 .0199 2.99 .0393 3.98 .2060 5.00 .0178 5.99 .0340 6.98 .0029 7.98 .0065 8.99 .0102 9.99 .0271 10.98 .0068 11.97 .0032 12.97 .0060 13.99 .0002 14.98 .0005 15.96 .0008 16.96 .0008 17.98 .0006 18.98 .0001 21.96 .0001 22.96 .0002 23.95 .0002 24.94 .0002 25.94 .0001 26.95 .0001 28.95 .0001)) (define bsn-c3 '( 1.00 .0082 1.98 .0489 2.99 .1248 3.98 .1892 4.97 .0149 5.98 .0017 6.96 .0172 7.95 .0072 8.96 .0028 9.95 .0114 10.93 .0055 11.94 .0029 12.96 .0005 13.92 .0017 14.93 .0008 15.91 .0012 16.90 .0005 17.91 .0001 20.90 .0001 21.88 .0003 22.87 .0001 24.85 .0002 28.85 .0001)) (define bsn-cs3 '( 1.01 .0191 2.00 .0451 2.99 .2847 4.00 .0925 5.00 .0143 5.99 .0024 7.00 .0055 8.00 .0131 8.99 .0286 9.98 .0021 10.99 .0020 11.99 .0010 12.96 .0003 13.97 .0005 14.98 .0009 15.97 .0005 20.97 .0003 21.97 .0003)) (define bsn-d3 '( 1.01 .0218 2.01 .0560 3.01 .1696 4.01 .0504 5.00 .0268 6.02 .0018 7.03 .0081 8.03 .0035 9.04 .0026 10.04 .0023 11.02 .0045 12.04 .0002 13.04 .0004 14.04 .0007 15.05 .0004 16.06 .0001 21.06 .0001 22.07 .0003)) (define bsn-ds3 '( 1.00 .0185 1.99 .0627 2.98 .2037 3.97 .0211 4.98 .0204 5.97 .0434 6.95 .0056 7.94 .0171 8.95 .0014 9.94 .0062 10.93 .0007 11.91 .0006 12.91 .0004 13.90 .0004 14.90 .0003 16.88 .0001 17.89 .0002 18.88 .0002 20.86 .0004 21.84 .0002 22.85 .0001)) (define bsn-e3 '( 1.00 .0167 2.00 .0801 3.01 .2223 4.02 .0252 5.02 .0098 6.01 .0058 7.02 .0073 8.03 .0032 9.03 .0066 10.04 .0011 10.66 .0001 12.04 .0013 13.04 .0013 14.05 .0010 15.05 .0004 18.07 .0002 20.06 .0003 23.07 .0001)) (define bsn-f3 '( 1.00 .0152 2.01 .0471 3.00 .1985 4.00 .0345 5.01 .0136 6.00 .0064 7.01 .0153 8.00 .0011 9.00 .0093 10.02 .0006 11.01 .0006 12.00 .0001 13.01 .0008 14.01 .0006 16.02 .0001 17.01 .0003 19.01 .0002 22.01 .0001 23.02 .0002)) (define bsn-fs3 '( 1.01 .0363 2.01 .1019 3.01 .3226 4.01 .1274 5.03 .0397 6.03 .0061 7.02 .0117 8.03 .0099 9.04 .0006 10.04 .0026 11.04 .0020 12.04 .0008 13.05 .0001 14.06 .0002 15.05 .0002 19.07 .0002)) (define bsn-g3 '( .99 .0358 1.99 .0535 2.99 .1072 3.99 .0270 4.99 .0106 5.98 .0010 6.97 .0007 7.97 .0041 8.95 .0002 9.94 .0002 10.97 .0002 12.96 .0001)) (define bsn-gs3 '( 1.00 .0382 1.99 .0923 2.99 .0199 3.99 .0156 4.96 .0044 5.98 .0130 6.97 .0020 7.97 .0033 8.97 .0007 9.95 .0002 10.95 .0001 12.95 .0001)) (define bsn-a3 '( 1.00 .0469 2.00 .2187 3.00 .0287 4.01 .0121 5.01 .0114 6.01 .0022 7.01 .0044 8.02 .0008 9.02 .0004 10.01 .0003 13.02 .0001)) (define bsn-as3 '( 1.01 .0298 2.01 .2016 3.02 .0058 4.00 .0258 5.00 .0008 6.00 .0029 7.00 .0031 8.01 .0010 9.01 .0004 10.00 .0001 13.01 .0001)) (define bsn-b3 '( 1.01 .0341 2.01 .2100 3.01 .0390 4.02 .0044 5.02 .0213 6.02 .0044 7.02 .0006 8.03 .0012 9.04 .0002 12.05 .0002 13.05 .0002)) (define bsn-c4 '( 1.00 .0684 2.00 .2934 3.00 .0096 4.00 .0084 5.00 .0039 6.00 .0059 7.00 .0010 8.00 .0006)) (define bsn-cs4 '( 1.01 .0848 2.01 .3334 3.02 .0152 4.03 .0032 5.03 .0059 6.03 .0032 7.05 .0013 8.05 .0007 9.05 .0001 10.06 .0001 11.06 .0002)) (define bsn-d4 '( 1.00 .1020 2.00 .1065 3.00 .0086 3.99 .0013 5.00 .0038 6.00 .0011 7.00 .0003 8.00 .0002 11.01 .0003)) (define bsn-ds4 '( 1.00 .0469 1.99 .0248 2.96 .0045 3.99 .0163 4.99 .0042 6.00 .0004 6.98 .0003)) (define bsn-e4 '( 1.00 .0389 2.01 .0439 3.01 .0110 4.01 .0072 5.02 .0041 6.02 .0005 7.02 .0006 9.03 .0003)) (define bsn-f4 '( 1.00 .0229 2.00 .0331 2.99 .0138 4.00 .0008 4.99 .0010 5.99 .0004)) (define bsn-fs4 '( 1.00 .1522 1.99 .0563 3.00 .0126 3.99 .0035 4.28 .0002 4.35 .0002 4.43 .0001 4.98 .0001 5.99 .0001 6.98 .0002)) (define bsn-g4 '( 1.00 .0415 2.00 .0486 3.00 .0068 4.00 .0148 5.00 .0016 6.00 .0001)) (define bsn-gs4 '( 1.01 .0811 2.01 .0402 3.03 .0114 4.04 .0044 5.03 .0004)) (define bsn-a4 '( 1.00 .0399 2.01 .0195 3.00 .0069 4.01 .0005 5.01 .0009 6.01 .0002 7.01 .0003)) (define bsn-as4 '( 1.01 .1259 2.01 .0811 3.01 .0051 4.01 .0027 5.01 .0008 6.02 .0002 7.02 .0003)) (define bsn-b4 '( 1.01 .1159 2.02 .0380 3.03 .0089 4.04 .0038 5.05 .0006 6.05 .0002)) (define bsn-c5 '( 1.02 .0871 2.03 .0356 3.04 .0192 4.06 .0063 6.09 .0003 7.11 .0002)) (define bsn-cs5 '( 1.01 .2418 2.02 .0674 3.02 .0067 4.03 .0021 5.03 .0004 6.05 .0003 7.05 .0005 8.06 .0001)) (define bsn-d5 '( 1.01 .1931 2.01 .0462 3.02 .0118 4.02 .0014 5.03 .0006 6.03 .0008 8.04 .0001)) ;;; ;;; ;;; ;;; ;;; cello (define c-c2 '( 1.00 .0047 1.99 .0251 2.99 .0546 4.01 .1041 4.99 .0279 5.97 .0219 6.93 .0137 7.94 .0349 8.91 .0151 10.04 .0565 11.00 .0458 12.00 .0216 12.97 .0151 14.52 .0025 14.95 .0088 16.03 .0103 17.02 .0027 17.98 .0089 19.00 .0052 20.03 .0048 20.93 .0051 22.04 .0023 23.01 .0072 24.01 .0022 24.99 .0027 26.03 .0036 27.47 .0011 27.99 .0011 29.02 .0012 29.86 .0005 30.97 .0020 31.88 .0006 33.02 .0021 33.98 .0011 35.02 .0010 36.01 .0028 37.00 .0022 37.99 .0014 39.00 .0014 40.01 .0022 41.04 .0021 42.02 .0008 43.01 .0024 44.02 .0007 45.01 .0003 46.00 .0002 48.03 .0002 48.85 .0002 51.01 .0001 51.98 .0001 54.89 .0002 55.39 .0002 56.38 .0001 58.02 .0002 58.98 .0002 62.00 .0001 64.09 .0001 65.02 .0002)) (define c-cs2 '( 1.01 .0160 2.02 .0737 3.02 .0287 4.02 .0183 5.02 .0669 6.04 .0520 7.05 .0043 8.06 .0066 9.06 .0194 10.05 .0193 11.05 .0254 12.06 .0153 13.08 .0041 14.11 .0037 15.09 .0098 16.09 .0022 17.09 .0053 18.10 .0135 19.12 .0118 20.13 .0057 21.15 .0039 22.14 .0023 23.14 .0027 24.15 .0026 25.16 .0012 26.16 .0011 27.17 .0020 28.17 .0015 29.14 .0020 30.19 .0013 31.19 .0019 32.20 .0007 33.21 .0005 34.22 .0004 35.19 .0012 36.20 .0005 37.25 .0015 38.25 .0018 39.26 .0014 40.40 .0007 41.25 .0010 42.24 .0009 43.28 .0003 44.31 .0002 45.28 .0002 46.30 .0001 48.29 .0002 49.31 .0004 50.34 .0001 51.35 .0002 52.32 .0003 53.50 .0001 54.28 .0001 57.34 .0001 58.35 .0002)) (define c-d2 '( 1.00 .0368 2.02 .1070 3.03 .0107 4.04 .0445 5.04 .0477 6.04 .0281 7.07 .0191 8.06 .0205 9.06 .0456 10.07 .0283 11.07 .0320 12.08 .0094 13.35 .0009 14.11 .0042 15.11 .0066 16.12 .0075 17.13 .0117 18.14 .0043 19.16 .0067 20.14 .0020 21.16 .0046 22.16 .0011 23.17 .0029 24.17 .0010 25.18 .0011 26.19 .0013 27.18 .0029 28.20 .0039 29.21 .0048 30.23 .0020 31.23 .0006 32.25 .0018 33.23 .0009 34.24 .0012 35.28 .0016 36.27 .0018 37.28 .0019 38.28 .0031 39.28 .0008 40.25 .0001 41.30 .0002 42.31 .0002 43.32 .0001 44.32 .0002 45.33 .0002 46.34 .0004 48.37 .0002 49.37 .0006 50.37 .0004 51.35 .0001 52.35 .0001 53.40 .0001 54.39 .0002 55.41 .0003 56.43 .0002 57.41 .0001 64.49 .0001 65.50 .0001)) (define c-ds2 '( 1.01 .0485 2.01 .1800 3.01 .0143 4.02 .1265 5.03 .1372 6.03 .0102 7.02 .0261 8.03 .0216 9.02 .0145 10.04 .0292 11.05 .0133 12.06 .0038 13.06 .0026 14.04 .0041 15.06 .0053 16.06 .0014 17.08 .0051 18.06 .0048 19.07 .0026 20.07 .0025 21.09 .0039 22.08 .0018 23.08 .0031 24.11 .0023 25.10 .0035 26.10 .0037 27.10 .0019 28.10 .0030 29.11 .0020 30.10 .0036 31.13 .0020 32.10 .0011 33.13 .0013 34.12 .0027 35.11 .0022 36.13 .0018 37.15 .0005 38.13 .0002 39.17 .0002 40.16 .0006 41.13 .0002 43.16 .0002 44.16 .0002 45.15 .0002 46.18 .0003 47.17 .0001 48.18 .0001 49.16 .0002 50.19 .0001 58.35 .0001)) (define c-e2 '( 1.02 .0293 2.00 .1425 3.04 .0549 4.03 .0364 5.03 .1171 6.07 .0100 7.04 .0253 8.06 .0448 9.08 .0115 10.06 .0116 11.08 .0048 12.09 .0174 13.09 .0037 14.11 .0029 15.11 .0104 16.12 .0036 17.14 .0046 18.13 .0016 19.16 .0027 20.13 .0036 21.14 .0012 22.18 .0027 23.17 .0011 24.18 .0033 25.20 .0019 26.20 .0016 26.99 .0005 28.22 .0009 29.19 .0052 30.23 .0021 31.21 .0015 32.24 .0014 33.23 .0019 34.22 .0033 35.27 .0009 36.27 .0002 38.30 .0004 39.27 .0005 40.26 .0004 41.25 .0003 42.31 .0002 43.34 .0007 44.32 .0006 45.32 .0003 46.36 .0002 47.36 .0001 48.34 .0002 49.37 .0002 54.40 .0002 55.40 .0001)) (define c-f2 '( .99 .0765 2.00 .0311 3.02 .0635 4.02 .0223 5.15 .0022 6.01 .0457 7.03 .0278 8.04 .0188 9.04 .0344 10.02 .0093 11.00 .0034 12.05 .0172 13.06 .0106 14.07 .0020 15.02 .0011 16.06 .0022 17.08 .0027 18.08 .0007 19.05 .0016 20.07 .0015 21.07 .0057 22.10 .0010 23.07 .0030 24.07 .0013 25.07 .0019 26.09 .0018 27.10 .0042 28.10 .0020 29.09 .0015 30.12 .0027 31.11 .0021 32.13 .0035 33.08 .0003 34.12 .0005 35.12 .0004 36.15 .0008 37.15 .0003 39.14 .0005 40.17 .0003 41.15 .0003 42.14 .0002 43.14 .0001 44.17 .0002 51.84 .0001 53.18 .0001 54.22 .0001)) (define c-fs2 '( 1.02 .0680 2.02 .0790 3.03 .0722 4.03 .0851 5.03 .0169 6.03 .0073 7.02 .0859 8.02 .0250 9.04 .0073 10.07 .0037 11.04 .0035 12.01 .0009 13.09 .0056 14.05 .0059 15.05 .0031 16.07 .0050 17.07 .0034 18.07 .0010 19.47 .0004 20.10 .0045 21.10 .0028 22.09 .0039 23.10 .0032 24.11 .0007 25.09 .0017 26.10 .0041 27.16 .0006 28.12 .0021 29.13 .0021 30.39 .0004 31.11 .0013 32.17 .0004 33.13 .0005 34.14 .0014 35.07 .0002 36.06 .0001 37.16 .0002 39.18 .0007 40.18 .0002 41.22 .0001 42.21 .0002 43.24 .0003 49.15 .0001 51.22 .0001 52.23 .0002)) (define c-g2 '( 1.00 .0434 2.00 .0983 2.99 .0548 3.98 .0364 4.98 .0228 5.97 .0390 6.97 .0091 7.96 .0154 9.03 .0078 9.96 .0174 10.98 .0110 11.96 .0125 12.97 .0039 13.94 .0028 14.95 .0057 15.94 .0020 16.95 .0046 17.94 .0011 18.97 .0017 19.94 .0010 20.98 .0025 21.94 .0040 22.94 .0030 23.91 .0064 24.95 .0013 25.96 .0009 26.94 .0015 27.92 .0014 28.93 .0017 29.91 .0015 30.92 .0010 31.49 .0002 32.83 .0002 33.89 .0003 34.92 .0002 36.91 .0003 37.91 .0002 40.84 .0002 41.87 .0002 42.89 .0002)) (define c-gs2 '( .98 .0579 1.97 .0445 2.97 .1178 3.97 .0806 4.96 .1095 5.94 .0245 6.92 .0203 7.91 .0153 8.92 .0186 9.93 .0129 10.92 .0154 11.89 .0040 12.87 .0036 13.88 .0033 14.74 .0006 15.85 .0011 16.86 .0020 17.85 .0026 18.84 .0040 19.84 .0022 20.83 .0022 21.82 .0020 22.80 .0060 23.79 .0073 24.81 .0023 25.80 .0030 26.79 .0008 27.77 .0005 28.75 .0012 29.73 .0017 30.75 .0003 31.74 .0005 32.74 .0003 33.71 .0003 34.70 .0005 35.72 .0002 36.67 .0003 38.69 .0002 39.71 .0002 40.65 .0001)) (define c-a2 '( .99 .0612 1.98 .0094 2.98 .0435 3.98 .0098 4.97 .0550 5.97 .0775 6.96 .0337 7.96 .0330 8.97 .0137 9.95 .0122 10.95 .0080 11.94 .0082 13.00 .0009 13.95 .0034 14.96 .0029 15.94 .0011 16.94 .0041 17.95 .0060 18.92 .0008 19.97 .0026 20.94 .0009 21.94 .0041 22.92 .0050 23.92 .0056 24.93 .0030 25.92 .0015 26.22 .0002 27.90 .0011 28.90 .0004 29.89 .0007 30.89 .0009 31.90 .0004 32.91 .0002 33.88 .0005 34.86 .0001 35.89 .0003 36.87 .0006 37.89 .0003 38.93 .0002 46.84 .0001 54.82 .0001)) (define c-as2 '( 1.00 .0401 1.99 .0101 2.98 .0769 3.96 .0345 4.96 .0696 5.97 .0342 6.95 .0413 7.95 .0130 8.92 .0147 9.93 .0034 10.94 .0135 11.94 .0007 12.92 .0013 13.91 .0017 14.89 .0026 15.88 .0019 16.89 .0039 17.88 .0034 18.86 .0037 19.84 .0009 20.85 .0021 21.86 .0021 22.85 .0049 23.82 .0042 24.82 .0007 25.80 .0007 26.82 .0003 27.81 .0004 28.79 .0009 29.79 .0007 30.77 .0005 31.18 .0001 31.66 .0001 32.76 .0002 33.78 .0002 34.76 .0004 35.75 .0002 36.74 .0002)) (define c-b2 '( 1.00 .0486 1.99 .0621 2.98 .0627 3.98 .0145 4.98 .0494 5.97 .0353 6.96 .0287 7.96 .0169 8.95 .0167 9.95 .0039 10.94 .0075 11.94 .0043 12.95 .0018 13.92 .0040 14.94 .0054 15.93 .0046 16.93 .0035 17.92 .0037 18.93 .0036 19.91 .0055 20.89 .0055 21.89 .0058 22.89 .0039 23.88 .0005 24.87 .0009 25.87 .0003 26.87 .0007 27.78 .0002 28.86 .0004 29.86 .0004 30.85 .0004 31.86 .0001 32.83 .0009 33.83 .0003 34.82 .0001 37.81 .0002 43.79 .0001 48.71 .0001)) (define c-c3 '( .99 .0486 1.98 .1268 2.99 .0920 3.98 .0752 4.96 .1515 5.95 .0086 6.97 .0102 7.95 .0108 8.95 .0120 9.94 .0034 10.95 .0029 11.94 .0007 12.91 .0029 13.92 .0077 14.90 .0028 15.89 .0027 16.90 .0038 17.92 .0034 18.87 .0115 19.89 .0039 20.89 .0023 21.86 .0023 22.88 .0008 23.88 .0006 24.86 .0004 26.05 .0002 26.84 .0003 27.84 .0005 28.84 .0003 29.80 .0004 30.82 .0007 31.58 .0001 31.79 .0001 32.52 .0001 33.80 .0001 34.80 .0001 39.78 .0002)) (define c-cs3 '( 1.01 .0839 1.99 .0414 2.99 .1265 4.00 .0196 5.00 .0377 6.00 .0117 6.99 .0111 8.00 .0151 9.00 .0207 9.98 .0033 10.99 .0090 11.99 .0039 13.00 .0039 14.01 .0031 14.99 .0038 16.02 .0023 17.00 .0026 17.98 .0069 19.00 .0020 20.01 .0017 21.02 .0007 22.02 .0006 22.22 .0002 22.93 .0001 24.05 .0003 25.04 .0002 25.99 .0003 27.00 .0003 29.03 .0003)) (define c-d3 '( 1.01 .1033 2.00 .0588 3.00 .0184 4.00 .0725 5.00 .0720 6.01 .0251 7.01 .0292 8.02 .0069 9.00 .0094 10.00 .0159 11.02 .0134 12.00 .0008 13.01 .0053 14.01 .0204 15.01 .0122 16.02 .0024 17.03 .0044 18.02 .0069 19.03 .0043 20.01 .0024 21.02 .0020 22.03 .0006 23.03 .0005 24.02 .0006 25.01 .0011 26.01 .0006 27.03 .0007 28.04 .0005 29.04 .0003 30.02 .0001 31.03 .0002 32.04 .0003 36.02 .0002 38.03 .0001 39.06 .0002 40.01 .0002 42.09 .0001 43.08 .0001 44.05 .0002)) (define c-ds3 '( 1.01 .1622 2.01 .1721 3.02 .0068 4.02 .0256 5.03 .0568 6.02 .0438 7.03 .0061 8.04 .0086 9.04 .0050 10.06 .0045 11.07 .0012 12.10 .0025 13.08 .0028 14.11 .0014 15.07 .0060 16.07 .0014 17.13 .0026 18.08 .0015 19.13 .0007 20.13 .0003 21.15 .0003 22.06 .0004 23.10 .0002 24.15 .0001 25.12 .0001 26.16 .0002 27.20 .0001)) (define c-e3 '( 1.00 .1620 2.01 .0201 3.01 .0224 4.02 .0903 5.03 .0425 6.01 .0323 7.02 .0089 8.11 .0023 9.02 .0050 10.03 .0055 11.05 .0038 12.04 .0099 13.04 .0062 14.03 .0027 15.06 .0040 16.07 .0035 17.07 .0089 18.06 .0013 19.05 .0012 20.08 .0004 21.06 .0008 22.09 .0002 23.08 .0008 24.09 .0005 25.08 .0006 26.65 .0001 27.13 .0001 29.10 .0002 30.10 .0001 31.10 .0002 32.11 .0001 35.12 .0003 36.10 .0002 37.15 .0003 38.17 .0001)) (define c-f3 '( .99 .0412 1.99 .0398 2.99 .1009 3.99 .0605 4.97 .0481 5.96 .0358 6.96 .0065 7.83 .0052 7.97 .0050 8.95 .0042 9.94 .0038 10.95 .0044 11.94 .0120 12.93 .0044 13.92 .0074 14.92 .0037 15.92 .0030 16.92 .0017 17.90 .0021 18.90 .0016 19.89 .0016 20.89 .0002 22.86 .0013 23.87 .0014 24.87 .0006 25.86 .0003 26.88 .0001 29.84 .0004 30.83 .0002 31.82 .0001 32.83 .0001 33.81 .0001 34.81 .0002 35.82 .0003 37.80 .0002)) (define c-fs3 '( 1.00 .0386 2.00 .0915 3.00 .0406 4.01 .0601 5.00 .0460 5.99 .0213 7.01 .0148 8.00 .0085 9.00 .0073 10.00 .0017 11.01 .0191 12.00 .0069 13.00 .0057 14.02 .0023 15.01 .0059 16.00 .0010 17.02 .0006 18.01 .0019 19.00 .0012 20.02 .0002 20.99 .0004 22.01 .0013 23.02 .0007 24.02 .0002 24.94 .0001 27.03 .0001 28.02 .0002 29.00 .0001 31.01 .0001 32.01 .0001 33.02 .0003 34.03 .0002)) (define c-g3 '( 1.01 .0124 1.99 .0359 2.98 .0602 3.98 .0390 4.98 .0496 5.98 .0070 6.98 .0121 7.97 .0089 8.97 .0044 9.97 .0068 10.97 .0085 11.96 .0110 12.95 .0034 13.95 .0099 14.95 .0059 15.95 .0003 16.94 .0014 17.94 .0005 18.94 .0008 19.95 .0004 20.94 .0007 21.39 .0001 22.95 .0002 24.93 .0001 25.92 .0002 27.91 .0001 29.91 .0005 30.94 .0001 31.93 .0002 33.90 .0001)) (define c-gs3 '( 1.00 .0509 1.99 .1477 3.00 .0407 4.00 .0514 5.00 .0367 6.00 .0032 7.02 .0097 8.00 .0090 9.07 .0009 10.03 .0069 10.99 .0020 12.03 .0010 13.02 .0019 14.06 .0010 15.02 .0010 16.03 .0008 17.03 .0003 18.05 .0002 18.98 .0004 20.09 .0002 21.03 .0001 28.01 .0001)) (define c-a3 '( 1.00 .0110 2.01 .0315 3.02 .1476 4.03 .0358 5.01 .0391 6.02 .0638 7.03 .0692 8.02 .0039 9.04 .0218 10.04 .0342 11.05 .0335 12.04 .0187 13.05 .0167 14.06 .0168 15.06 .0035 16.07 .0019 17.07 .0014 18.08 .0040 19.07 .0070 20.08 .0014 21.09 .0015 22.08 .0003 23.10 .0003 24.08 .0011 25.10 .0003 26.12 .0013 27.13 .0009 28.13 .0006 29.12 .0003 30.11 .0002 31.13 .0002 33.15 .0002 34.13 .0001 36.15 .0001 41.16 .0002 44.18 .0001 47.17 .0001)) (define c-as3 '( 1.00 .0140 2.00 .0411 3.00 .0723 4.00 .1057 5.00 .0044 6.00 .0248 6.98 .0048 8.00 .0014 9.00 .0304 9.99 .0184 10.99 .0130 12.00 .0159 13.00 .0107 13.99 .0021 15.00 .0015 15.99 .0020 17.00 .0028 18.00 .0067 19.00 .0005 20.04 .0003 21.00 .0003 22.02 .0001 23.98 .0003 25.01 .0007 26.01 .0009 27.00 .0003 28.02 .0002 28.98 .0002 30.00 .0002 31.01 .0002 32.01 .0002 32.99 .0003 33.99 .0001 35.02 .0002 37.00 .0002 38.98 .0003 43.98 .0001 44.99 .0001)) (define c-b3 '( 1.00 .0648 2.00 .0397 3.00 .0872 4.01 .0429 5.00 .0213 6.01 .0524 7.00 .0064 8.03 .0162 9.02 .0212 10.01 .0175 11.02 .0256 12.03 .0038 13.03 .0039 14.04 .0056 15.03 .0008 16.08 .0005 17.03 .0032 18.04 .0010 19.04 .0011 20.04 .0002 21.06 .0010 22.05 .0002 23.08 .0011 24.09 .0005 25.12 .0003 26.07 .0002 27.03 .0001 39.10 .0002)) (define c-c4 '( 1.00 .0472 2.00 .1961 3.00 .1030 4.00 .0974 5.00 .0183 6.00 .0397 7.00 .0158 8.00 .0170 8.99 .0253 10.00 .0129 10.99 .0121 11.99 .0103 12.98 .0055 14.03 .0004 14.99 .0012 15.99 .0051 16.99 .0009 17.99 .0012 19.00 .0004 19.98 .0015 21.02 .0002 22.00 .0009 22.99 .0007 24.01 .0004 25.00 .0002 26.00 .0003 28.00 .0002 28.97 .0002 31.00 .0002 32.98 .0003 33.98 .0001 34.97 .0001 35.98 .0002 37.97 .0002 38.97 .0001)) (define c-cs4 '( 1.00 .1199 2.00 .0345 3.01 .0978 4.00 .0466 5.02 .0070 6.01 .0258 7.02 .0241 8.01 .0070 9.02 .0161 10.02 .0124 11.02 .0145 12.02 .0101 13.02 .0026 14.03 .0011 15.02 .0028 16.03 .0011 17.04 .0005 18.02 .0003 19.05 .0012 20.07 .0004 21.06 .0011 22.06 .0007 23.04 .0007 24.05 .0005 26.07 .0003 27.04 .0002 28.05 .0002 29.06 .0001 32.05 .0001 33.06 .0002 35.07 .0002 36.07 .0001 37.07 .0002)) (define c-d4 '( 1.00 .0657 2.00 .0681 3.00 .1031 3.99 .0157 4.99 .0570 5.98 .0160 6.99 .0236 7.98 .0259 8.99 .0144 9.98 .0154 10.98 .0046 11.97 .0104 12.98 .0024 13.97 .0020 14.97 .0012 15.97 .0010 16.97 .0004 17.95 .0008 18.97 .0005 19.98 .0007 20.98 .0009 21.93 .0004 22.00 .0003 22.94 .0002 23.95 .0002 24.98 .0001 25.97 .0002 26.96 .0001 28.94 .0002 29.94 .0002 30.94 .0002 32.97 .0001 33.97 .0001 34.95 .0001 36.93 .0001)) (define c-ds4 '( 1.00 .3562 1.99 .0664 2.99 .1446 3.98 .0393 4.97 .0363 5.97 .0237 6.96 .0366 7.95 .0079 8.96 .0127 9.95 .0148 10.95 .0143 11.94 .0031 12.96 .0022 13.94 .0032 14.92 .0004 15.92 .0007 16.90 .0007 17.92 .0007 18.92 .0012 19.94 .0005 20.89 .0003 21.88 .0001 22.89 .0005 23.87 .0004 24.87 .0001 25.89 .0007 26.87 .0001 29.85 .0001 30.83 .0001 31.82 .0001 32.82 .0002 33.82 .0001)) (define c-e4 '( 1.00 .0390 2.01 .1863 3.02 .0265 4.02 .0184 5.02 .0319 6.03 .0456 7.04 .0122 8.04 .0149 9.05 .0159 10.05 .0067 11.06 .0044 12.06 .0053 13.08 .0012 14.08 .0008 15.08 .0007 16.09 .0021 17.09 .0005 18.09 .0021 19.13 .0016 20.12 .0004 21.12 .0003 22.14 .0003 23.12 .0003 24.13 .0003 25.14 .0005 26.14 .0002 27.15 .0002 28.16 .0002 29.18 .0002 30.17 .0002 31.16 .0002 36.21 .0001)) (define c-f4 '( 1.00 .1183 1.99 .1142 2.99 .1085 3.98 .0306 4.99 .0252 5.97 .0272 6.97 .0290 7.97 .0142 8.97 .0112 9.96 .0079 10.96 .0038 11.97 .0026 12.96 .0014 13.95 .0007 14.94 .0011 15.95 .0008 16.94 .0011 17.03 .0001 17.94 .0001 18.95 .0004 19.94 .0003 20.94 .0007 21.92 .0002 23.92 .0002 24.92 .0002 25.90 .0002 26.90 .0002 27.89 .0001 28.89 .0002 30.89 .0001)) (define c-fs4 '( 1.00 .1140 2.00 .0935 3.00 .0504 3.99 .0715 4.99 .0063 6.00 .0808 6.99 .0099 8.00 .0093 9.00 .0093 9.99 .0019 10.99 .0050 11.99 .0017 12.99 .0021 14.00 .0003 14.99 .0010 16.00 .0015 17.00 .0019 17.95 .0002 18.00 .0002 18.99 .0002 19.99 .0003 21.00 .0002 21.99 .0003 23.99 .0001 24.98 .0001 26.02 .0001 27.01 .0001 28.00 .0002)) (define c-g4 '( 1.00 .0809 1.99 .1377 2.99 .0348 3.99 .0337 4.98 .0177 5.98 .0295 6.98 .0266 7.98 .0063 8.98 .0105 9.97 .0016 10.97 .0022 11.98 .0029 12.97 .0018 13.96 .0008 14.99 .0023 15.97 .0012 16.96 .0009 17.97 .0002 18.95 .0006 20.94 .0002 20.99 .0002 22.95 .0002 23.94 .0002 24.94 .0003 25.97 .0003 26.95 .0002)) (define c-gs4 '( 1.00 .2601 1.99 .1726 2.99 .0722 3.99 .0276 4.99 .0535 5.99 .0103 6.99 .0244 7.99 .0046 8.98 .0035 9.99 .0088 10.98 .0038 11.98 .0008 12.96 .0006 13.98 .0020 14.98 .0016 15.98 .0008 16.97 .0003 17.97 .0005 18.98 .0006 19.96 .0005 20.96 .0001 21.96 .0003 23.96 .0002 24.96 .0003 25.96 .0002)) (define c-a4 '( .99 .0363 1.98 .2481 2.98 .0514 3.97 .0365 4.97 .0468 5.95 .0182 6.95 .0333 7.94 .0106 8.93 .0048 9.92 .0048 10.92 .0016 11.90 .0010 12.89 .0011 13.92 .0023 14.90 .0014 15.88 .0007 16.87 .0002 17.89 .0001 18.85 .0004 19.84 .0002 20.84 .0003 21.84 .0004 22.83 .0003 23.86 .0002 24.84 .0002 26.82 .0001)) (define c-as4 '( .99 .0564 1.99 .1983 2.98 .0520 3.97 .0442 4.97 .0260 5.96 .0139 6.96 .0099 7.94 .0046 8.94 .0178 9.94 .0032 10.93 .0021 11.00 .0002 11.93 .0001 12.92 .0038 13.91 .0011 14.90 .0006 15.92 .0004 16.89 .0004 17.89 .0002 18.87 .0005 19.87 .0003 20.86 .0003 21.85 .0003 22.85 .0001 23.85 .0001 24.85 .0001 25.85 .0002 26.84 .0002)) (define c-b4 '( .99 .0774 1.98 .1289 2.96 .1071 3.95 .0216 4.94 .0346 5.93 .0108 6.91 .0239 7.90 .0056 8.88 .0045 9.88 .0014 10.87 .0057 11.85 .0018 12.85 .0035 13.83 .0007 14.84 .0003 15.80 .0003 16.79 .0008 17.78 .0003 18.78 .0002 19.76 .0004 20.75 .0005 21.73 .0002 23.71 .0001 24.68 .0001)) (define c-c5 '( .99 .4933 1.97 .1293 2.95 .0971 4.92 .0189 5.91 .0031 6.88 .0093 7.87 .0143 8.85 .0063 9.84 .0010 10.82 .0023 11.81 .0015 12.79 .0006 13.78 .0009 14.76 .0007 15.75 .0004 16.72 .0007 17.71 .0002 18.68 .0008 19.67 .0004 20.66 .0003)) (define c-cs5 '( .99 .1576 1.99 .0760 2.98 .0560 3.97 .1172 4.96 .0433 5.96 .0029 6.95 .0079 7.95 .0058 8.93 .0025 9.93 .0014 10.93 .0054 11.92 .0005 12.92 .0004 13.90 .0009 14.90 .0015 15.89 .0003 16.87 .0002 17.87 .0004 18.87 .0002 19.86 .0002 20.86 .0002 21.86 .0003 22.85 .0002)) (define c-d5 '( 1.01 .1243 2.02 .0648 3.03 .0586 4.04 .0543 5.05 .0183 6.07 .0046 7.08 .0080 8.09 .0027 9.10 .0053 10.12 .0036 11.14 .0014 12.14 .0004 13.16 .0004 14.15 .0007 15.17 .0005 17.20 .0006 18.22 .0002 19.22 .0002 21.24 .0001)) (define c-ds5 '( 1.01 .1367 2.02 .0170 3.02 .0192 4.03 .0425 5.04 .0143 6.05 .0064 7.06 .0057 8.06 .0028 9.08 .0027 10.09 .0051 11.09 .0009 12.09 .0001 13.10 .0014 14.11 .0005 15.13 .0003 16.13 .0003 17.14 .0002 19.15 .0003 20.17 .0004 21.17 .0001)) (define c-e5 '( 1.02 .2402 2.03 .0419 3.05 .1068 5.08 .0164 6.10 .0019 7.11 .0044 8.13 .0018 9.15 .0044 10.17 .0021 11.18 .0003 12.20 .0007 13.21 .0011 14.24 .0003 15.24 .0008 16.27 .0001 17.28 .0001 18.31 .0001)) (define c-f5 '( 1.01 .1166 2.03 .0750 3.04 .0532 4.05 .0620 5.06 .0054 6.07 .0141 7.08 .0027 8.10 .0015 9.09 .0021 10.13 .0006 11.13 .0009 12.14 .0004 13.15 .0008 14.17 .0003 15.18 .0002 17.19 .0003 18.20 .0002)) (define c-fs5 '( 1.00 .1595 2.00 .0985 3.01 .1045 4.01 .0147 5.01 .0078 6.01 .0016 7.01 .0020 8.02 .0007 9.02 .0015 10.03 .0008 11.03 .0006 12.02 .0004 13.02 .0009 14.03 .0006 15.02 .0005 16.03 .0002 17.04 .0001)) (define c-g5 '( 1.00 .1740 1.99 .0431 2.99 .1899 3.99 .0201 4.98 .0009 5.98 .0031 6.98 .0055 7.97 .0051 8.97 .0007 9.96 .0007 10.95 .0006 11.95 .0009 12.95 .0008 13.96 .0002 14.94 .0001 15.95 .0002)) (define c-gs5 '( 1.00 .1902 1.99 .0327 2.98 .0551 3.98 .0157 4.97 .0078 5.97 .0030 6.96 .0035 7.96 .0020 8.95 .0017 9.94 .0011 10.94 .0005 11.93 .0007 12.93 .0004 13.92 .0002 14.93 .0003)) (define c-a5 '( .99 .4175 1.99 .0209 2.98 .0274 3.97 .0220 4.96 .0061 5.96 .0020 6.96 .0038 7.95 .0009 8.95 .0014 9.93 .0005 10.93 .0005 11.91 .0007 12.91 .0002 13.91 .0001 14.91 .0001)) (define c-as5 '( 1.00 .4648 2.00 .0475 3.01 .1268 4.01 .0164 5.02 .0035 6.02 .0018 7.02 .0033 8.03 .0028 9.03 .0008 10.03 .0006 11.03 .0005 12.04 .0006 13.05 .0003 14.04 .0001)) (define c-b5 '( 1.01 .2812 2.02 .1380 3.02 .0722 4.03 .0215 5.04 .0036 6.06 .0018 7.05 .0005 8.07 .0015 9.08 .0013 10.08 .0003 11.10 .0002 12.11 .0003 13.11 .0002)) (define c-c6 '( 1.01 .2553 2.01 .1160 3.02 .0171 4.02 .0272 5.02 .0020 6.03 .0062 7.03 .0012 8.04 .0011 9.05 .0007 10.05 .0007 11.06 .0002 12.06 .0001 12.08 .0001)) (define c-cs6 '( 1.01 .1045 2.02 .1220 3.04 .0220 4.05 .0094 5.06 .0021 6.07 .0031 7.09 .0018 8.10 .0020 9.11 .0014 10.12 .0003 11.13 .0006)) (define c-d6 '( 1.00 .0653 1.99 .2499 2.99 .0334 3.98 .0098 4.98 .0091 5.98 .0007 6.97 .0011 7.97 .0008 8.96 .0042 9.96 .0003 10.95 .0004)) (define c-ds6 '( .99 .0485 1.99 .1325 2.98 .0152 3.98 .0064 4.97 .0043 5.97 .0007 6.96 .0007 7.97 .0006 8.96 .0003 9.95 .0004)) (define c-e6 '( 1.01 .1797 2.01 .0750 4.03 .0065 5.04 .0018 6.04 .0012 7.04 .0004 8.06 .0003 9.06 .0003)) ;;; ;;; ;;; ;;; ;;; clarinet? (define cl-d3 '( 1.01 .1722 2.00 .0056 2.99 .1609 3.99 .0333 5.00 .1157 5.99 .1149 6.98 .0079 7.98 .0620 8.99 .0601 9.99 .0104 10.98 .0134 11.97 .0122 12.99 .0058 13.98 .0110 14.98 .0029 15.97 .0045 16.98 .0023 17.98 .0010 18.97 .0016 19.96 .0021 20.96 .0008 21.97 .0021 22.96 .0001 23.96 .0012 24.95 .0003 25.97 .0002 26.96 .0003 27.95 .0002 30.96 .0002 32.94 .0002 34.96 .0001 35.95 .0002 37.93 .0001)) (define cl-ds3 '( .99 .1038 1.98 .0043 2.96 .0953 3.97 .0013 4.94 .1057 5.93 .0145 6.93 .0787 7.91 .0328 8.89 .0086 9.90 .0088 10.88 .0128 11.86 .0005 12.86 .0085 13.84 .0026 14.83 .0051 15.81 .0030 16.82 .0008 17.79 .0026 18.78 .0013 19.78 .0015 20.76 .0011 22.74 .0012 23.72 .0002 24.71 .0006 25.70 .0003 26.70 .0002 28.67 .0002 30.64 .0002 31.64 .0001 32.63 .0001 33.61 .0003 35.59 .0002)) (define cl-e3 '( 1.00 .0825 1.99 .0024 2.97 .0406 3.96 .0042 4.94 .0683 6.40 .0010 6.92 .0709 7.92 .0099 8.91 .0059 9.89 .0055 10.88 .0111 11.90 .0009 12.86 .0126 13.87 .0021 14.84 .0110 15.83 .0010 16.83 .0057 17.81 .0007 18.80 .0037 19.78 .0008 20.78 .0016 21.75 .0006 22.75 .0008 23.73 .0005 24.74 .0007 26.72 .0004 27.68 .0002 29.67 .0003 31.66 .0003 33.64 .0002)) (define cl-f3 '( .99 .0685 1.98 .0012 2.98 .0854 3.98 .0029 4.96 .0507 5.97 .0017 6.96 .0507 7.94 .0027 8.94 .0092 9.94 .0084 10.92 .0116 11.91 .0018 12.92 .0039 13.92 .0003 14.89 .0013 15.88 .0019 16.87 .0012 17.86 .0010 18.87 .0011 19.86 .0008 20.85 .0008 21.83 .0002 23.81 .0004 24.83 .0002 25.80 .0003 27.78 .0002 29.78 .0001)) (define cl-fs3 '( 1.00 .1546 1.99 .0015 2.99 .0594 4.00 .0014 5.00 .0268 6.00 .0019 7.00 .0170 7.97 .0005 9.00 .0110 9.99 .0006 10.99 .0077 11.99 .0013 12.99 .0025 14.01 .0004 14.99 .0018 15.98 .0001 16.98 .0013 17.97 .0003 18.98 .0013 20.97 .0001 21.97 .0004 22.96 .0002 23.98 .0002 25.99 .0001)) (define cl-g3 '( .99 .1660 2.00 .0016 2.99 .0889 3.99 .0017 4.99 .0430 6.00 .0009 6.98 .0128 8.00 .0040 8.98 .0077 9.99 .0017 10.98 .0052 11.98 .0011 12.98 .0012 13.97 .0008 14.98 .0010 15.97 .0005 16.98 .0005 17.96 .0007 18.97 .0002 19.96 .0004 20.96 .0003 22.94 .0003 23.95 .0002 24.96 .0002 25.93 .0001 26.94 .0002 27.95 .0001)) (define cl-gs3 '( 1.00 .1107 2.00 .0016 2.99 .0872 3.99 .0028 4.98 .0293 5.97 .0020 6.96 .0202 7.99 .0019 8.95 .0118 9.94 .0028 10.95 .0040 11.92 .0006 12.95 .0030 13.92 .0002 14.92 .0010 15.91 .0005 16.91 .0015 18.90 .0004 19.89 .0004 20.89 .0002 21.88 .0004 22.87 .0002 23.88 .0001 24.87 .0001)) (define cl-a3 '( 1.00 .0842 2.01 .0017 3.00 .0420 4.01 .0029 5.00 .0251 6.02 .0041 6.99 .0115 7.96 .0006 8.99 .0032 9.98 .0003 11.00 .0018 11.96 .0003 12.96 .0006 14.00 .0001 14.97 .0001 15.97 .0005 17.95 .0002 18.96 .0001 19.07 .0001 22.06 .0001)) (define cl-as3 '( 1.00 .1118 1.99 .0006 2.98 .0383 3.98 .0019 4.98 .0335 5.98 .0034 6.97 .0131 7.94 .0005 8.95 .0024 9.96 .0028 10.96 .0019 11.94 .0012 12.94 .0012 13.93 .0003 14.94 .0007 16.92 .0004 17.90 .0003 18.93 .0002 20.89 .0002 21.90 .0001)) (define cl-b3 '( 1.00 .1324 1.99 .0011 3.00 .0693 4.01 .0012 4.99 .0279 5.98 .0044 6.98 .0149 7.97 .0009 8.97 .0028 9.97 .0009 10.98 .0026 11.96 .0003 12.96 .0006 13.95 .0003 15.95 .0001 16.94 .0001)) (define cl-c4 '( 1.00 .2335 1.99 .0017 2.99 .1253 4.01 .0023 4.99 .0343 6.01 .0028 6.98 .0023 7.98 .0014 8.98 .0041 10.01 .0003 10.96 .0004 11.94 .0008 12.94 .0002 14.94 .0003 15.94 .0004 16.93 .0002 17.91 .0002 18.91 .0002 19.91 .0001 20.90 .0001)) (define cl-cs4 '( .99 .2609 2.00 .0016 2.99 .1469 3.99 .0040 4.99 .0143 5.97 .0091 6.97 .0055 7.97 .0024 8.96 .0041 9.96 .0015 10.96 .0021 11.95 .0005 12.94 .0011 13.93 .0004 14.94 .0006 15.94 .0004 16.92 .0004 17.93 .0002 18.93 .0001 19.91 .0001 20.91 .0001 21.90 .0002 22.91 .0001)) (define cl-d4 '( 1.00 .2056 1.99 .0006 2.99 .1715 3.99 .0010 4.98 .0194 5.99 .0028 6.98 .0106 7.98 .0007 8.97 .0022 9.97 .0005 10.96 .0011 11.97 .0006 12.96 .0006 13.96 .0003 14.95 .0005 15.95 .0003 17.95 .0002 18.94 .0002 20.94 .0001)) (define cl-ds4 '( 1.00 .2590 1.98 .0019 2.99 .1336 3.97 .0034 4.97 .0442 5.97 .0017 6.96 .0108 7.96 .0006 8.95 .0031 9.94 .0003 11.93 .0003 12.93 .0004 13.93 .0005 14.92 .0001 15.91 .0003 16.90 .0004 17.90 .0002 18.89 .0001)) (define cl-e4 '( 1.00 .2560 2.00 .0013 3.00 .0878 4.00 .0053 5.00 .0304 6.00 .0009 7.00 .0060 7.99 .0007 9.00 .0011 9.99 .0006 10.99 .0006 11.98 .0001 13.99 .0001)) (define cl-f4 '( .99 .1966 1.99 .0021 2.98 .0812 3.96 .0018 4.97 .0248 5.96 .0032 6.96 .0060 7.95 .0024 8.95 .0019 9.94 .0008 10.94 .0007 11.92 .0005 12.91 .0002 13.94 .0001 14.90 .0002 15.91 .0002)) (define cl-fs4 '( 1.00 .1555 2.01 .0022 3.01 .1755 4.01 .0005 5.01 .0127 6.02 .0004 7.02 .0031 8.02 .0007 9.02 .0005 10.02 .0002 11.03 .0003 12.02 .0002 14.02 .0001 15.03 .0001 16.04 .0001)) (define cl-g4 '( 1.00 .0470 2.00 .0016 3.00 .0787 4.00 .0041 5.00 .0046 6.00 .0010 7.00 .0036 8.00 .0011 9.00 .0012 10.00 .0002 11.00 .0003 13.00 .0001)) (define cl-gs4 '( 1.00 .1205 1.99 .0014 2.99 .0145 3.99 .0015 4.99 .0030 5.99 .0005 6.98 .0006 9.00 .0001 9.98 .0001)) (define cl-a4 '( 1.00 .2677 2.00 .0592 3.01 .0961 4.01 .0083 5.02 .0075 6.02 .0027 7.03 .0048 8.03 .0031 9.02 .0007 10.03 .0003 11.03 .0001)) (define cl-as4 '( 1.00 .1363 2.01 .0056 3.00 .0168 4.01 .0026 5.01 .0112 6.00 .0011 7.01 .0011 8.01 .0003 10.00 .0002 12.02 .0001)) (define cl-b4 '( 1.01 .0312 2.01 .0042 3.02 .0061 4.02 .0127 5.03 .0090 6.04 .0002 7.04 .0021 8.05 .0008 11.06 .0001)) (define cl-c5 '( 1.00 .2597 2.00 .0052 3.00 .0337 4.00 .0012 5.00 .0025 6.00 .0014 7.00 .0007 7.99 .0004 8.99 .0003 10.00 .0004)) (define cl-cs5 '( 1.00 .1894 2.00 .0060 3.00 .0250 4.01 .0022 5.01 .0048 6.00 .0004 8.01 .0001 10.01 .0001)) (define cl-d5 '( 1.00 .1727 2.01 .0013 3.00 .0066 4.01 .0011 5.00 .0013 5.99 .0008 8.02 .0001)) (define cl-ds5 '( 1.00 .3538 2.00 .0053 3.01 .0757 4.01 .0009 5.01 .0045 6.02 .0008 7.02 .0011 8.01 .0003 9.02 .0005 10.01 .0002 11.02 .0001 12.02 .0002)) (define cl-e5 '( 1.00 .1647 2.00 .0048 3.00 .0524 3.99 .0055 4.99 .0030 5.98 .0011 6.99 .0004 7.99 .0003)) (define cl-f5 '( .99 .1880 1.99 .0126 2.99 .0222 3.98 .0070 4.98 .0135 5.97 .0020 6.97 .0012 7.96 .0001 8.96 .0007 9.95 .0003)) (define cl-fs5 '( 1.00 .3103 2.00 .0104 3.00 .0335 4.00 .0078 5.00 .0026 6.01 .0005 7.01 .0006 8.00 .0003)) (define cl-g5 '( 1.01 .4163 2.01 .0446 3.02 .0290 4.03 .0031 5.02 .0004 6.03 .0002 7.05 .0001 8.05 .0001)) (define cl-gs5 '( 1.01 .2150 2.00 .0334 3.00 .0012 4.02 .0003 5.02 .0002)) (define cl-a5 '( 1.01 .5463 2.01 .0429 3.02 .0317 4.02 .0159 5.03 .0012 6.04 .0005 7.04 .0005 8.05 .0002)) (define cl-as5 '( 1.00 .3802 2.00 .0397 3.01 .0186 4.01 .0102 5.01 .0020 6.01 .0001 7.01 .0002 8.02 .0003 9.02 .0002 10.02 .0001 11.02 .0001 12.02 .0002)) (define cl-b5 '( 1.00 .0896 2.00 .0851 3.00 .0081 4.00 .0024 5.00 .0010 6.00 .0001 7.00 .0002)) (define cl-c6 '( 1.00 .1740 2.00 .0081 3.01 .0111 4.01 .0087 5.01 .0005 6.01 .0007 7.01 .0001 9.01 .0002 10.02 .0002)) (define cl-cs6 '( 1.00 .1295 1.99 .0270 2.99 .0012 3.99 .0004)) (define cl-d6 '( 1.00 .1700 2.01 .0603 3.01 .0169 4.01 .0031 5.01 .0007 6.01 .0002)) (define cl-ds6 '( 1.01 .2624 2.02 .0042 3.03 .0049 4.03 .0015 5.04 .0001)) (define cl-e6 '( 1.02 .0632 2.03 .0115 3.04 .0011 4.06 .0006)) (define cl-f6 '( 1.02 .0748 2.03 .0535 3.05 .0044 4.07 .0009 5.08 .0001 7.12 .0001 8.13 .0001)) (define cl-fs6 '( 1.02 .0305 2.03 .0175 3.04 .0005 4.05 .0002)) (define cl-g6 '( 1.03 .0026 2.04 .0008)) (define cl-gs6 '( 1.03 .0015 2.00 .0002)) (define cl-a6 '( 1.03 .0043 2.05 .0010)) (define cl-as6 '( 1.05 .0008 2.00 .0001)) ;;; ;;; ;;; ;;; ;;; french horn? (define fh-as1 '( 1.01 .0041 2.00 .0015 3.01 .0121 4.02 .0111 5.02 .0343 6.03 .0165 7.04 .0066 8.03 .0064 9.05 .0049 10.06 .0012 11.05 .0093 12.07 .0029 13.07 .0042 14.08 .0040 15.08 .0019 16.09 .0013 17.10 .0009 18.04 .0002 19.03 .0002 20.12 .0003 21.13 .0003 22.13 .0002 23.13 .0002)) (define fh-b1 '( 1.01 .0035 2.03 .0064 3.04 .0087 4.08 .0087 5.12 .0049 6.08 .0189 7.10 .0304 8.12 .0205 9.16 .0026 10.18 .0039 11.20 .0006 12.11 .0029 13.15 .0037 14.24 .0014 15.26 .0010 16.29 .0005 17.19 .0003 18.21 .0007 19.23 .0005 20.25 .0004 21.33 .0003 22.36 .0001 23.32 .0002 24.33 .0002 25.33 .0001 26.39 .0002 27.42 .0002)) (define fh-c2 '( 1.02 .0034 2.02 .0059 3.01 .0083 4.02 .0274 5.03 .0206 6.03 .0155 7.04 .0131 8.03 .0073 9.05 .0014 10.03 .0064 11.05 .0055 12.06 .0109 13.08 .0037 14.10 .0012 15.10 .0010 16.01 .0004 17.05 .0009 18.06 .0008 19.06 .0006 20.09 .0004 21.11 .0002 22.14 .0002 23.09 .0002 24.08 .0001 25.08 .0002 26.07 .0002 27.12 .0002 28.16 .0001 32.11 .0001)) (define fh-cs2 '( 1.01 .0038 1.99 .0124 2.98 .0065 4.00 .0260 5.00 .0138 5.99 .0093 6.97 .0077 7.95 .0055 8.97 .0061 9.97 .0016 10.95 .0034 11.96 .0036 12.14 .0010 12.94 .0009 13.97 .0008 14.86 .0004 15.89 .0006 16.91 .0007 17.93 .0004 18.94 .0002 19.95 .0001 20.77 .0001 21.78 .0002 22.86 .0001 23.89 .0002)) (define fh-d2 '( 1.01 .0153 2.01 .0192 3.01 .0216 4.01 .0371 5.01 .0259 6.02 .0188 7.02 .0076 8.04 .0009 9.03 .0038 10.03 .0065 11.03 .0075 12.03 .0026 13.03 .0005 14.04 .0009 15.06 .0008 16.04 .0006 17.03 .0004 18.03 .0003 19.04 .0002 23.03 .0002)) (define fh-ds2 '( 1.00 .0234 1.98 .0227 2.96 .0129 3.97 .0333 4.96 .0315 5.95 .0252 6.93 .0076 7.94 .0061 8.91 .0028 9.89 .0096 10.90 .0089 11.89 .0024 12.88 .0022 13.88 .0019 14.87 .0010 15.79 .0006 16.79 .0003 17.79 .0002 18.69 .0002 19.68 .0003 20.70 .0002 21.70 .0002)) (define fh-e2 '( 1.00 .0150 1.99 .0230 3.01 .0204 4.00 .0298 5.02 .0112 6.03 .0135 7.02 .0019 8.03 .0061 9.01 .0099 10.04 .0053 11.03 .0006 12.04 .0028 13.04 .0016 14.04 .0015 15.03 .0009 16.02 .0005 17.05 .0002 20.02 .0002 21.02 .0001 24.00 .0002 25.03 .0001)) (define fh-f2 '( .97 .0088 1.96 .0127 2.97 .0179 3.96 .0163 4.94 .0421 5.91 .0165 6.96 .0019 7.93 .0020 8.91 .0112 9.85 .0035 10.91 .0017 12.02 .0004 12.83 .0014 13.79 .0010 14.79 .0007 15.75 .0002 16.73 .0003 17.74 .0007 18.74 .0005 19.73 .0001 20.68 .0002 21.66 .0002 22.65 .0002 23.63 .0001 24.65 .0001)) (define fh-fs2 '( 1.00 .0035 1.99 .0136 2.97 .0394 3.96 .0379 4.98 .0330 5.97 .0111 6.94 .0156 7.94 .0108 8.96 .0076 9.95 .0025 10.95 .0021 11.93 .0026 12.93 .0014 13.89 .0008 14.87 .0006 15.78 .0001 16.94 .0001 17.93 .0001 18.93 .0001 19.89 .0001)) (define fh-g2 '( 1.01 .0150 2.01 .0182 3.04 .1047 4.04 .0662 5.03 .0448 6.06 .0018 7.06 .0034 8.06 .0202 9.09 .0051 10.09 .0070 11.08 .0060 12.11 .0022 13.12 .0011 14.13 .0005 15.20 .0001 16.09 .0002 17.14 .0002 18.14 .0002 19.14 .0002 20.16 .0002 21.15 .0001 22.15 .0001)) (define fh-gs2 '( .99 .0092 2.00 .0177 3.00 .0664 3.98 .0447 4.99 .0223 5.99 .0144 7.00 .0124 7.97 .0096 8.97 .0046 9.96 .0011 10.99 .0021 12.00 .0010 12.99 .0007 13.93 .0007 14.92 .0007 15.94 .0005 16.94 .0003 17.90 .0002 18.88 .0001 19.87 .0002 20.86 .0002 21.86 .0001)) (define fh-a2 '( 1.00 .0063 2.01 .0609 3.03 .0699 4.05 .1365 5.04 .0249 6.05 .0103 7.07 .0200 8.08 .0059 9.10 .0063 10.09 .0046 11.10 .0015 12.13 .0008 13.14 .0006 14.07 .0004 15.05 .0004 16.08 .0004 17.10 .0002 18.12 .0002 19.10 .0001)) (define fh-as2 '( 1.00 .0026 2.02 .0329 3.03 .0926 4.04 .0530 5.07 .0041 6.07 .0072 7.09 .0076 8.10 .0053 9.11 .0057 10.13 .0017 11.16 .0005 12.21 .0001 13.09 .0003 14.11 .0003 15.18 .0003 16.17 .0001)) (define fh-b2 '( 1.01 .0154 2.02 .0506 3.05 .1042 4.05 .0643 5.06 .0151 6.08 .0102 7.09 .0045 8.11 .0040 9.12 .0033 10.12 .0015 11.13 .0006 12.16 .0004 13.18 .0003 14.95 .0001 15.98 .0001 16.99 .0001 18.02 .0001)) (define fh-c3 '( 1.01 .0147 2.02 .0897 3.01 .1180 4.01 .0323 5.02 .0133 6.04 .0226 7.04 .0033 8.06 .0023 9.02 .0019 10.03 .0010 11.04 .0009 12.06 .0003 13.04 .0002 14.05 .0002 15.05 .0002 16.01 .0002 16.94 .0001)) (define fh-cs3 '( 1.01 .0345 2.00 .1083 2.99 .0911 4.01 .0280 5.01 .0071 6.00 .0123 7.00 .0043 8.01 .0034 9.01 .0014 10.02 .0004 10.94 .0003 11.96 .0003 12.96 .0002 14.89 .0001 15.92 .0001)) (define fh-d3 '( 1.01 .0488 2.02 .1313 3.03 .1606 4.03 .0029 5.04 .0187 6.05 .0059 7.05 .0018 8.05 .0023 9.05 .0007 10.06 .0003 11.07 .0001 12.08 .0002)) (define fh-ds3 '( 1.00 .0619 2.00 .1230 3.01 .0981 4.02 .0299 5.02 .0210 6.03 .0054 7.03 .0023 8.04 .0010 9.04 .0005 10.06 .0002)) (define fh-e3 '( 1.00 .0500 2.01 .1076 3.03 .1077 4.04 .0167 5.03 .0138 6.06 .0058 7.07 .0036 8.06 .0007 9.09 .0004 10.07 .0002 11.03 .0001 12.05 .0002)) (define fh-f3 '( 1.01 .0368 2.02 .1311 3.02 .0405 4.03 .0139 5.03 .0080 6.04 .0052 7.05 .0015 8.04 .0004 9.06 .0002 10.06 .0002 12.08 .0001)) (define fh-fs3 '( 1.01 .0430 2.02 .1877 3.05 .0299 4.05 .0218 5.07 .0067 6.08 .0054 7.10 .0012 8.11 .0010 9.12 .0004 10.13 .0002 11.15 .0001)) (define fh-g3 '( 1.01 .0339 2.04 .1965 4.07 .0541 5.08 .0113 6.10 .0049 7.10 .0022 8.13 .0014 9.14 .0008 10.16 .0005)) (define fh-gs3 '( 1.02 .0596 2.02 .1865 3.03 .0629 4.04 .0304 5.05 .0087 6.05 .0035 7.07 .0008 8.09 .0004 9.09 .0005 10.10 .0005 11.11 .0002 12.12 .0001)) (define fh-a3 '( 1.00 .1160 2.02 .2642 3.02 .0259 4.02 .0127 5.04 .0095 6.04 .0022 7.04 .0013 8.06 .0008 9.04 .0003 10.01 .0001)) (define fh-as3 '( 1.01 .0585 2.01 .1648 3.02 .0229 4.02 .0150 5.03 .0084 6.03 .0016 7.06 .0003 9.01 .0002)) (define fh-b3 '( 1.01 .0741 2.00 .1581 3.00 .0490 4.01 .0133 5.01 .0045 6.02 .0013 7.03 .0002 8.00 .0001)) (define fh-c4 '( .99 .1378 2.00 .0872 2.99 .0736 3.99 .0065 4.99 .0025 5.97 .0009 6.98 .0002 7.98 .0005 8.98 .0002)) (define fh-cs4 '( 1.01 .2826 2.02 .0676 3.02 .0523 4.03 .0208 5.04 .0069 6.04 .0009 7.05 .0009 8.06 .0011 9.07 .0004 10.07 .0001 11.08 .0002 12.09 .0001)) (define fh-d4 '( 1.01 .2849 2.02 .0068 3.03 .0144 4.04 .0066 5.05 .0032 6.07 .0007 7.07 .0003 8.09 .0003)) (define fh-ds4 '( 1.00 .2321 2.01 .0612 3.02 .0150 4.03 .0042 5.03 .0007 6.04 .0005 7.05 .0002 8.06 .0001)) (define fh-e4 '( 1.01 .1701 2.01 .0303 3.02 .0156 4.03 .0021 5.04 .0009 6.04 .0003 7.04 .0001)) (define fh-f4 '( 1.01 .1957 2.01 .0196 3.01 .0087 4.01 .0022 5.01 .0006 6.02 .0002)) (define fh-fs4 '( 1.01 .3622 2.02 .0601 3.03 .0187 4.04 .0043 5.05 .0011 6.06 .0005)) (define fh-g4 '( 1.00 .2782 2.01 .0918 3.01 .0080 4.03 .0013 5.03 .0010 6.03 .0003)) (define fh-gs4 '( 1.01 .2703 2.02 .0548 3.02 .0083 4.03 .0011 5.03 .0009 6.04 .0003)) (define fh-a4 '( 1.01 .4575 2.02 .0245 3.03 .0049 4.04 .0019 5.05 .0008 6.06 .0002)) (define fh-as4 '( 1.00 .2524 2.01 .0291 3.02 .0022 4.03 .0011 5.03 .0003)) (define fh-b4 '( 1.00 .3254 2.00 .0428 3.00 .0026 4.00 .0006)) (define fh-c5 '( 1.00 .1672 2.00 .0223 3.00 .0010 4.00 .0005)) (define fh-cs5 '( 1.00 .1209 2.00 .0340 3.00 .0014 4.01 .0004)) (define fh-d5 '( 1.01 .0150 2.01 .0313 3.02 .0023 4.03 .0007)) (define fh-ds5 '( 1.00 .1633 2.00 .0260 3.00 .0012 4.00 .0002)) (define fh-e5 '( 1.00 .1001 2.00 .0146 3.00 .0019 4.00 .0001)) (define fh-f5 '( 1.01 .0944 2.01 .0114 3.02 .0016 4.02 .0002)) (define fh-fs5 '( 1.01 .1904 2.02 .0076 3.02 .0025 4.03 .0003)) (define fh-g5 '( 1.00 .2511 2.00 .0017 3.01 .0010 4.01 .0004)) (define fh-gs5 '( 1.00 .1029 1.99 .0050 2.99 .0007 3.99 .0002)) ;;; ;;; ;;; ;;; ;;; (define fhf-as1 '( 1.01 .0025 1.99 .0008 3.01 .0057 4.02 .0063 5.03 .0268 6.04 .0198 7.04 .0157 8.03 .0160 9.05 .0056 10.05 .0016 11.06 .0059 12.09 .0009 13.10 .0023 14.08 .0022 15.09 .0011 16.10 .0011 17.11 .0012 18.16 .0009 19.16 .0008 20.15 .0005 21.16 .0002 22.15 .0001 23.15 .0001)) (define fhf-b1 '( 1.03 .0025 2.07 .0054 5.15 .0276 6.18 .0379 7.21 .0389 8.23 .0176 9.26 .0020 10.29 .0039 11.24 .0002 12.26 .0010 13.28 .0015 14.34 .0010 15.37 .0009 16.42 .0010 17.47 .0027 18.49 .0015 19.52 .0010 20.56 .0005 21.57 .0004 22.59 .0004 23.60 .0003 24.61 .0003 25.65 .0002 26.67 .0002 27.66 .0001 28.71 .0002 29.75 .0001)) (define fhf-c2 '( 1.02 .0023 2.03 .0041 3.03 .0059 4.05 .0291 5.05 .0280 6.06 .0396 7.06 .0428 8.07 .0111 9.08 .0018 10.10 .0049 11.12 .0052 12.12 .0075 13.12 .0021 14.15 .0009 15.18 .0008 16.21 .0009 17.22 .0012 18.23 .0008 19.23 .0003 20.24 .0003 21.23 .0002 22.22 .0002 23.22 .0002 24.25 .0001 25.27 .0002 26.27 .0001 28.25 .0001 30.29 .0001 32.31 .0001)) (define fhf-cs2 '( 1.03 .0031 2.02 .0111 3.02 .0074 4.01 .0370 5.01 .0307 6.03 .0330 7.03 .0281 8.02 .0089 9.02 .0097 9.21 .0016 10.03 .0014 11.04 .0044 12.03 .0039 12.96 .0004 14.09 .0011 15.10 .0006 16.10 .0014 17.09 .0011 18.09 .0006 19.10 .0005 20.10 .0004 21.08 .0002 22.10 .0003 22.28 .0002 23.07 .0001 24.04 .0002 25.09 .0001 26.10 .0001 27.10 .0001 32.10 .0001)) (define fhf-d2 '( 1.00 .0154 2.01 .0193 3.01 .0257 4.00 .0566 5.00 .0570 6.01 .0680 7.01 .0222 8.03 .0023 9.02 .0036 10.05 .0043 11.07 .0037 12.07 .0010 12.97 .0005 13.99 .0014 14.99 .0022 15.98 .0023 16.97 .0011 17.96 .0007 18.95 .0004 19.12 .0003 19.89 .0002 20.92 .0003 21.11 .0002 21.92 .0002 22.91 .0002 23.88 .0002 24.92 .0002 25.89 .0003 26.88 .0003 27.84 .0001)) (define fhf-ds2 '( 1.00 .0204 2.02 .0234 3.03 .0132 4.04 .0416 5.05 .0425 6.04 .0258 7.06 .0086 8.07 .0067 9.14 .0009 10.17 .0030 11.20 .0008 12.09 .0016 13.11 .0015 14.12 .0029 15.11 .0028 16.11 .0011 17.11 .0006 18.09 .0003 19.13 .0004 19.29 .0002 20.10 .0002 21.13 .0002 21.29 .0002 22.26 .0001 23.11 .0003 24.11 .0003 25.08 .0002 26.10 .0002 27.08 .0002 28.10 .0001 28.28 .0001)) (define fhf-e2 '( 1.00 .0097 1.99 .0146 3.00 .0159 4.00 .0246 5.02 .0137 6.06 .0177 7.02 .0017 8.05 .0029 9.04 .0058 10.06 .0041 10.96 .0009 12.03 .0029 13.08 .0021 14.12 .0008 15.14 .0002 16.11 .0002 26.90 .0001)) (define fhf-f2 '( 1.00 .0039 2.02 .0070 3.04 .0156 4.06 .0113 5.08 .0222 6.07 .0065 7.07 .0046 8.12 .0018 9.13 .0081 10.13 .0014 11.17 .0012 12.17 .0014 13.21 .0007 13.98 .0005 14.24 .0003 14.98 .0003 15.96 .0002 17.21 .0001 18.97 .0002 20.02 .0001 21.05 .0001)) (define fhf-fs2 '( 1.02 .0030 2.03 .0096 3.04 .0372 4.06 .0225 5.09 .0048 6.17 .0019 7.19 .0014 8.20 .0014 9.19 .0023 10.22 .0008 11.09 .0003 12.23 .0006 13.25 .0004 14.25 .0002 15.14 .0001 16.19 .0002 17.20 .0002 18.24 .0002 19.23 .0001 20.27 .0001 21.29 .0001 23.26 .0001)) (define fhf-g2 '( 1.03 .0067 2.02 .0055 3.06 .0282 5.01 .0043 5.20 .0033 6.05 .0006 7.09 .0009 8.13 .0070 9.17 .0006 10.20 .0010 11.23 .0007 12.28 .0002 13.16 .0001 14.23 .0001)) (define fhf-gs2 '( .99 .0029 2.02 .0054 3.01 .0149 4.03 .0101 5.03 .0047 6.02 .0035 7.02 .0028 8.04 .0026 9.03 .0010 10.03 .0003 11.07 .0004 11.89 .0001 12.98 .0001 13.99 .0002)) (define fhf-a2 '( .99 .0020 2.00 .0131 3.00 .0085 4.01 .0199 4.99 .0044 5.98 .0020 7.00 .0029 8.01 .0009 9.02 .0010 9.99 .0007 10.94 .0003)) (define fhf-as2 '( 1.00 .0013 2.01 .0042 3.01 .0101 3.99 .0132 4.98 .0011 5.97 .0007 6.96 .0031 7.99 .0009 9.10 .0003 9.99 .0003 10.92 .0002 11.88 .0002 12.85 .0001)) (define fhf-b2 '( 1.01 .0038 2.00 .0081 2.98 .0138 3.96 .0105 4.96 .0021 5.95 .0034 6.89 .0013 7.91 .0006 8.86 .0005 9.87 .0001)) (define fhf-c3 '( 1.00 .0033 2.01 .0162 3.00 .0168 4.00 .0069 5.00 .0033 6.01 .0061 7.01 .0006 8.01 .0003 8.98 .0003 9.97 .0002 10.98 .0001)) (define fhf-cs3 '( 1.01 .0161 2.01 .0404 3.01 .0208 4.02 .0039 5.02 .0013 6.02 .0041 7.02 .0019 8.01 .0011 9.01 .0003)) (define fhf-d3 '( 1.01 .0238 2.01 .0582 3.02 .0679 4.02 .0022 5.03 .0081 6.03 .0024 7.03 .0012 8.05 .0010 9.05 .0001 10.08 .0001)) (define fhf-ds3 '( 1.00 .0295 2.01 .0519 3.02 .0343 4.04 .0119 5.05 .0067 6.07 .0011 7.08 .0013 8.09 .0004)) (define fhf-e3 '( 1.01 .0251 2.04 .0479 3.03 .0741 4.04 .0054 5.05 .0049 6.04 .0029 7.06 .0021 8.10 .0006 9.11 .0004 10.10 .0002 11.13 .0002)) (define fhf-f3 '( 1.02 .0143 2.02 .0453 3.04 .0115 4.05 .0021 5.08 .0007 6.10 .0007 7.07 .0006 8.04 .0001)) (define fhf-fs3 '( 1.01 .0220 2.03 .0843 3.04 .0119 4.06 .0062 5.09 .0022 6.12 .0016 7.14 .0003 9.13 .0001)) (define fhf-g3 '( 1.02 .0145 2.03 .0700 3.03 .0010 5.13 .0013 6.14 .0007 7.14 .0002)) (define fhf-gs3 '( 1.02 .0273 2.03 .0703 3.04 .0176 4.07 .0073 5.08 .0021 6.09 .0004 7.09 .0002 8.09 .0001)) (define fhf-a3 '( 1.00 .0529 2.02 .0982 3.02 .0066 4.04 .0034 5.05 .0029 6.04 .0003 7.03 .0002)) (define fhf-as3 '( 1.01 .0274 2.01 .0613 3.02 .0056 4.03 .0056 5.03 .0024 6.03 .0003)) (define fhf-b3 '( 1.01 .0468 2.01 .0884 3.01 .0246 4.02 .0058 5.03 .0016 6.03 .0005 7.02 .0002 8.01 .0001)) (define fhf-c4 '( 1.01 .0972 2.01 .0455 3.02 .0442 4.03 .0073 5.03 .0017 6.03 .0005 7.04 .0008 8.05 .0003 9.05 .0001)) (define fhf-cs4 '( 1.01 .1452 2.01 .0382 3.02 .0285 4.02 .0080 5.02 .0019 6.01 .0002 7.03 .0003 8.04 .0002)) (define fhf-d4 '( 1.01 .1930 2.02 .0066 3.03 .0070 4.05 .0041 5.05 .0016 6.07 .0003)) (define fhf-ds4 '( 1.00 .1433 2.01 .0414 3.02 .0101 4.03 .0020 5.02 .0002 6.03 .0003 7.06 .0001)) (define fhf-e4 '( 1.00 .1373 2.01 .0256 3.01 .0164 4.02 .0026 5.02 .0014 6.02 .0004 7.03 .0002)) (define fhf-f4 '( 1.01 .1930 2.01 .0192 3.02 .0124 4.02 .0030 5.03 .0013 6.03 .0006 7.03 .0002)) (define fhf-fs4 '( 1.01 .2352 2.01 .0485 3.02 .0135 4.03 .0035 5.03 .0010 6.04 .0004)) (define fhf-g4 '( 1.01 .1991 2.03 .0655 3.04 .0065 4.04 .0015 5.06 .0006 6.07 .0002)) (define fhf-gs4 '( 1.01 .2177 2.02 .0422 3.03 .0038 4.05 .0014 5.06 .0006)) (define fhf-a4 '( 1.01 .3779 2.02 .0161 3.03 .0026 4.04 .0009 5.05 .0005)) (define fhf-as4 '( 1.00 .1879 2.01 .0205 3.02 .0006 4.03 .0006)) (define fhf-b4 '( .99 .2910 1.99 .0363 2.99 .0019 3.99 .0001 4.98 .0001)) (define fhf-c5 '( 1.00 .0690 2.01 .0086 3.01 .0002 4.00 .0002)) (define fhf-cs5 '( 1.01 .0872 2.02 .0247 3.03 .0008 4.05 .0002)) (define fhf-d5 '( 1.01 .0213 2.02 .0275 3.03 .0031 4.04 .0008 5.05 .0002 6.07 .0001)) (define fhf-ds5 '( 1.01 .1852 2.01 .0224 3.01 .0043 4.02 .0006 5.03 .0001)) (define fhf-e5 '( 1.01 .1063 2.02 .0144 3.03 .0018 4.04 .0006 5.05 .0001)) (define fhf-f5 '( 1.02 .1058 2.04 .0062 3.06 .0023 4.08 .0005)) (define fhf-fs5 '( 1.01 .1683 2.03 .0099 3.04 .0026 4.05 .0004 5.07 .0003)) (define fhf-g5 '( 1.01 .3271 2.02 .0090 3.03 .0022 4.04 .0007)) ;;; ;;; ;;; ;;; ;;; flute? (define fl-c4 '( 1.01 .0602 2.02 .0954 3.03 .0270 4.03 .0199 5.05 .0177 6.06 .0104 7.07 .0040 8.08 .0040 9.08 .0035 10.10 .0017 11.10 .0009 12.12 .0004 13.11 .0002 14.13 .0006 15.14 .0003 17.15 .0002 18.16 .0001)) (define fl-cs4 '( 1.01 .0672 2.01 .0689 3.02 .0604 4.02 .0410 5.02 .0130 6.03 .0040 7.03 .0210 8.03 .0078 9.04 .0010 10.07 .0002 11.05 .0005 12.05 .0008 13.05 .0004 14.06 .0002 15.07 .0001 19.08 .0001)) (define fl-d4 '( 1.01 .0747 2.01 .2106 3.01 .0522 4.02 .0208 5.01 .0138 6.02 .0024 7.03 .0071 8.03 .0038 8.17 .0002 8.74 .0001 10.03 .0004 11.04 .0014 12.03 .0001 13.06 .0002 14.05 .0003 15.06 .0001 16.07 .0001 17.06 .0002 18.06 .0002)) (define fl-ds4 '( 1.00 .0256 2.00 .1167 3.00 .0241 4.01 .0159 5.01 .0200 6.00 .0167 7.01 .0069 8.04 .0004 9.00 .0009 10.01 .0010 11.00 .0004 12.00 .0003 13.00 .0002 14.01 .0002 16.00 .0002 17.01 .0002)) (define fl-e4 '( 1.00 .0572 2.01 .1769 3.01 .0622 4.00 .0323 5.01 .0210 6.01 .0163 7.02 .0068 8.01 .0007 8.13 .0002 8.39 .0001 10.02 .0011 11.02 .0004 12.02 .0003 15.03 .0002 16.03 .0001 17.04 .0001 18.04 .0001)) (define fl-f4 '( 1.01 .0438 2.01 .0964 3.01 .0569 4.01 .0096 5.01 .0164 6.01 .0194 7.02 .0024 8.01 .0005 9.03 .0007 10.04 .0005 12.05 .0002 13.04 .0001 14.05 .0002)) (define fl-fs4 '( 1.00 .0952 2.00 .1432 3.01 .0299 4.01 .0371 5.02 .0189 6.02 .0092 7.03 .0060 8.03 .0003 9.04 .0025 10.04 .0006 11.04 .0003 13.05 .0002 14.06 .0002)) (define fl-g4 '( 1.00 .2831 2.01 .1781 3.01 .0370 4.02 .0191 5.02 .0313 6.02 .0048 7.04 .0007 8.03 .0022 9.04 .0015 9.13 .0001 10.04 .0001 11.05 .0002 12.05 .0002 14.07 .0001 15.06 .0001)) (define fl-gs4 '( 1.00 .2598 2.00 .2241 3.01 .0407 4.01 .0354 5.01 .0398 6.01 .0111 7.03 .0007 8.01 .0030 9.01 .0018 10.02 .0002 12.02 .0004 13.02 .0001 14.03 .0002 15.03 .0001)) (define fl-a4 '( 1.00 .2580 2.01 .1605 3.00 .0236 4.01 .0281 5.02 .0047 6.02 .0024 7.02 .0010 8.02 .0027 9.02 .0004 10.03 .0002 11.03 .0003 12.04 .0001 13.04 .0002 14.04 .0002)) (define fl-as4 '( 1.01 .1855 2.01 .1041 3.01 .0480 4.02 .0416 5.02 .0059 6.02 .0016 7.03 .0004 8.03 .0016 9.03 .0003 10.04 .0004 11.05 .0003 16.07 .0002)) (define fl-b4 '( 1.01 .0564 2.01 .1996 3.02 .0219 4.02 .0108 5.03 .0183 6.04 .0005 7.04 .0009 8.05 .0014 10.06 .0006 11.07 .0003)) (define fl-c5 '( 1.01 .0245 2.02 .1674 3.04 .0228 4.05 .0229 5.06 .0087 6.09 .0004 7.09 .0004 8.10 .0003 9.11 .0002 10.14 .0002 11.15 .0001)) (define fl-cs5 '( 1.00 .0885 2.01 .0661 3.01 .0281 4.02 .0068 5.02 .0038 6.02 .0010 7.02 .0008 8.03 .0007 9.03 .0005 10.04 .0002 11.04 .0003)) (define fl-d5 '( 1.01 .3830 2.01 .1043 3.01 .0372 4.02 .0175 5.03 .0035 6.03 .0011 7.04 .0010 8.04 .0004 9.04 .0002 10.05 .0001)) (define fl-ds5 '( 1.00 .2294 2.01 .0606 3.01 .0238 4.01 .0050 5.01 .0041 6.02 .0007 7.02 .0007 8.02 .0006 10.03 .0002 12.03 .0001)) (define fl-e5 '( 1.01 .3759 2.03 .0529 3.03 .0595 4.05 .0010 5.06 .0077 6.07 .0008 7.09 .0007 8.09 .0005 9.11 .0001 10.12 .0002 12.14 .0001)) (define fl-f5 '( 1.01 .1982 2.02 .0204 3.02 .0554 4.03 .0064 5.04 .0040 6.05 .0016 7.06 .0007 8.07 .0006 9.07 .0001 10.08 .0001 12.10 .0001)) (define fl-fs5 '( 1.01 .3241 2.02 .0548 3.03 .0082 4.04 .0022 5.05 .0038 6.06 .0004 7.07 .0009 8.09 .0001 9.09 .0003 10.10 .0001)) (define fl-g5 '( 1.01 .4049 2.01 .0301 3.02 .0229 4.03 .0047 5.04 .0029 6.05 .0014 7.05 .0009 8.06 .0003 9.07 .0002 10.07 .0002 11.09 .0001 12.09 .0001)) (define fl-gs5 '( 1.00 .5433 2.01 .0536 3.01 .0411 4.02 .0074 5.02 .0014 6.02 .0011 7.03 .0004 8.03 .0003 9.04 .0001)) (define fl-a5 '( 1.01 .3063 2.01 .0346 3.02 .0102 4.03 .0031 5.03 .0007 6.04 .0010 7.03 .0003 8.06 .0001 9.05 .0002 11.06 .0002)) (define fl-as5 '( 1.01 .1962 2.03 .0355 3.04 .0128 4.06 .0020 5.07 .0021 6.08 .0003 7.10 .0003 8.11 .0002)) (define fl-b5 '( 1.01 .3829 2.02 .0120 3.03 .0037 4.04 .0030 5.05 .0016 6.06 .0006 7.07 .0002 8.08 .0004 9.09 .0001)) (define fl-c6 '( 1.01 .3072 2.02 .0248 3.04 .0012 4.05 .0006 5.06 .0011 6.07 .0009 7.08 .0003 8.10 .0001 10.12 .0001)) (define fl-cs6 '( 1.01 .1262 2.02 .0030 3.03 .0012 4.04 .0005 5.06 .0010 6.07 .0002 7.08 .0004 8.09 .0002)) (define fl-d6 '( 1.01 .3050 2.03 .0071 3.04 .0107 4.06 .0005 5.07 .0015 6.08 .0002 7.10 .0003 8.11 .0002 9.13 .0001)) (define fl-ds6 '( 1.02 .0954 2.05 .0025 3.06 .0047 4.09 .0007 5.11 .0017 6.13 .0001 7.15 .0002)) (define fl-e6 '( 1.02 .2864 2.05 .0057 3.08 .0023 5.13 .0007 6.16 .0001 8.21 .0001)) (define fl-f6 '( 1.03 .0675 2.05 .0049 3.08 .0024 5.13 .0008 6.16 .0002 7.18 .0002 8.21 .0001)) (define fl-fs6 '( 1.02 .2553 2.05 .0044 3.07 .0032 5.12 .0007 6.14 .0002 8.19 .0001)) (define fl-g6 '( 1.02 .1190 2.05 .0069 3.07 .0046 5.12 .0010 6.14 .0001 7.17 .0007 7.26 .0001)) (define fl-gs6 '( 1.02 .3872 2.05 .0093 3.07 .0051 5.12 .0008 6.15 .0001 7.17 .0002 7.18 .0001)) (define fl-a6 '( 1.02 .2920 2.04 .0122 3.06 .0052 4.08 .0007 5.10 .0003 6.31 .0002 7.15 .0003)) (define fl-as6 '( 1.02 .5687 2.04 .0090 3.06 .0075 4.08 .0007 5.10 .0010 6.15 .0002 6.21 .0002 6.40 .0001 6.47 .0001)) (define fl-b6 '( 1.03 .2752 2.06 .0061 3.09 .0039 5.14 .0002 5.86 .0002 6.18 .0001 6.24 .0001 6.45 .0001)) (define fl-c7 '( 1.04 .2720 2.07 .0046 5.18 .0003 5.40 .0002 6.02 .0002)) (define fl-cs7 '( 1.03 .3752 2.06 .0156 5.16 .0007 5.20 .0003 5.40 .0001 5.41 .0001 5.57 .0001)) (define fl-d7 '( 1.04 .2861 2.07 .0147 5.18 .0012 5.27 .0002 5.30 .0001)) ;;; ;;; ;;; ;;; ;;; oboe? (define ob-as3 '( 1.00 .0504 2.00 .0724 2.99 .1036 3.99 .1215 4.99 .1360 5.99 .0852 6.98 .0593 7.97 .0230 8.98 .0077 9.97 .0063 10.97 .0016 11.96 .0008 12.97 .0017 13.97 .0017 14.96 .0020 15.96 .0007 16.96 .0006 17.96 .0002 21.95 .0001 22.95 .0001 23.94 .0002 24.94 .0002 25.94 .0001)) (define ob-b3 '( .99 .0587 1.99 .0820 2.98 .0673 3.98 .1069 4.97 .1336 5.97 .0948 6.96 .0455 7.96 .0070 8.95 .0017 9.95 .0023 10.95 .0063 11.93 .0031 12.93 .0021 13.92 .0009 14.92 .0005 15.92 .0003 16.89 .0001 21.88 .0001 23.88 .0001)) (define ob-c4 '( 1.00 .0784 2.00 .0494 2.99 .0668 3.99 .0785 4.99 .1406 5.99 .0747 6.99 .0460 7.98 .0147 8.98 .0115 9.97 .0083 10.98 .0058 11.98 .0059 12.97 .0027 13.98 .0010 14.96 .0006 15.97 .0002 16.96 .0001 17.96 .0002 19.95 .0001 20.96 .0002 21.95 .0001)) (define ob-cs4 '( 1.00 .0801 2.00 .0526 2.99 .0568 3.99 .0713 4.99 .1811 5.99 .0721 6.99 .0491 7.98 .0201 8.98 .0128 9.98 .0132 10.98 .0104 11.98 .0081 12.97 .0055 13.97 .0026 14.97 .0010 15.97 .0003 16.97 .0004 17.96 .0003 18.97 .0004 19.95 .0006 20.96 .0003 21.96 .0002)) (define ob-d4 '( 1.00 .0775 2.00 .0853 3.01 .0538 4.01 .0600 5.00 .1853 6.01 .0714 7.01 .0247 8.01 .0265 9.01 .0028 10.01 .0116 11.02 .0078 12.02 .0060 13.01 .0036 14.02 .0010 15.03 .0005 16.01 .0002 17.02 .0002 18.01 .0004 19.02 .0004 20.02 .0002 21.02 .0001)) (define ob-ds4 '( 1.00 .0922 1.99 .0922 2.99 .0912 3.99 .0337 4.98 .1696 5.97 .0481 6.98 .0184 7.97 .0104 8.96 .0185 9.96 .0147 10.96 .0057 11.95 .0039 12.95 .0012 13.94 .0006 14.94 .0009 15.94 .0005 16.93 .0005 17.93 .0003 18.93 .0001 19.92 .0001)) (define ob-e4 '( 1.00 .0970 2.01 .0554 3.01 .0624 4.02 .1806 5.02 .1392 6.02 .0367 7.03 .0165 8.04 .0102 9.04 .0159 10.04 .0077 11.04 .0092 12.05 .0027 13.06 .0004 14.06 .0007 15.06 .0003 16.07 .0006 17.07 .0003 18.08 .0003 19.08 .0001 20.09 .0002)) (define ob-f4 '( 1.00 .0988 2.01 .0364 3.00 .0573 4.01 .2291 5.01 .0802 6.02 .0188 7.02 .0160 8.02 .0143 9.02 .0152 10.02 .0140 11.03 .0054 12.01 .0003 13.03 .0012 14.03 .0008 15.04 .0008 16.04 .0006 17.04 .0006 18.04 .0003 19.05 .0001)) (define ob-fs4 '( 1.01 .0340 2.01 .0618 3.02 .0923 4.03 .1479 5.03 .1058 6.04 .0281 7.05 .0071 8.05 .0157 9.06 .0018 10.07 .0014 11.07 .0005 12.08 .0013 13.09 .0012 14.10 .0005 15.10 .0003 16.11 .0005 17.12 .0002)) (define ob-g4 '( 1.01 .0606 2.01 .0774 3.02 .0552 4.03 .0700 5.04 .0194 6.04 .0066 7.05 .0147 8.06 .0134 9.07 .0055 10.08 .0035 11.08 .0004 12.10 .0004 13.10 .0008 14.11 .0011 15.10 .0004)) (define ob-gs4 '( 1.01 .0573 2.01 .0346 3.03 .0608 4.03 .0675 5.04 .0643 6.05 .0193 7.06 .0125 8.07 .0109 9.07 .0010 10.09 .0003 11.09 .0016 12.10 .0015 13.11 .0006 14.11 .0003 15.13 .0002 16.13 .0002)) (define ob-a4 '( 1.00 .0923 2.00 .0358 3.00 .0726 4.00 .2111 5.00 .0316 5.99 .0016 7.00 .0080 8.00 .0075 9.00 .0031 10.01 .0007 11.01 .0008 12.00 .0005 13.00 .0003 14.01 .0005 15.01 .0001)) (define ob-as4 '( 1.00 .0753 2.00 .0693 3.00 .3731 4.01 .0810 5.01 .0245 6.00 .0142 7.00 .0061 8.01 .0025 9.01 .0004 10.01 .0005 11.01 .0005 12.02 .0005 13.02 .0003)) (define ob-b4 '( 1.00 .0618 2.01 .0377 3.02 .0642 4.02 .0401 5.02 .0165 6.03 .0176 7.03 .0079 8.04 .0016 9.04 .0003 10.06 .0003 11.05 .0006 12.06 .0003 13.06 .0001)) (define ob-c5 '( 1.01 .0484 2.02 .0490 3.02 .0364 4.03 .0166 5.03 .0172 6.04 .0261 7.05 .0120 8.06 .0021 9.06 .0035 10.07 .0021 11.08 .0008 12.08 .0003)) (define ob-cs5 '( 1.01 .1071 2.02 .0487 3.03 .1175 4.04 .0329 5.05 .0231 6.06 .0136 7.07 .0047 8.07 .0009 9.09 .0011 10.10 .0016 11.10 .0010 12.12 .0002)) (define ob-d5 '( 1.01 .1893 2.01 .0986 3.02 .1665 4.02 .0326 5.03 .0275 6.04 .0155 7.04 .0029 8.05 .0013 9.06 .0016 10.07 .0010 11.07 .0004 12.08 .0001)) (define ob-ds5 '( 1.00 .2003 2.00 .0265 3.00 .1047 4.00 .0138 5.00 .0391 6.00 .0094 6.99 .0023 8.00 .0018 8.99 .0011 9.99 .0006 10.99 .0002 11.99 .0001)) (define ob-e5 '( 1.00 .0906 2.00 .4215 3.00 .1046 3.99 .0081 4.99 .0118 5.99 .0054 6.99 .0005 7.99 .0014 8.99 .0005 9.99 .0002)) (define ob-f5 '( 1.00 .0657 2.00 .4134 2.99 .0463 3.99 .0144 4.99 .0277 5.99 .0047 6.98 .0005 7.98 .0004 8.98 .0003)) (define ob-fs5 '( 1.01 .0957 2.03 .2943 3.04 .0855 4.06 .0568 5.07 .0247 6.08 .0013 7.10 .0024 8.12 .0011 9.13 .0006 10.15 .0002 11.16 .0001 12.17 .0001)) (define ob-g5 '( 1.01 .0975 2.02 .1012 3.04 .0543 4.05 .0298 5.06 .0083 6.07 .0026 7.08 .0017 8.09 .0003 9.11 .0001)) (define ob-gs5 '( 1.01 .0400 2.01 .0481 3.02 .0403 4.02 .0169 5.03 .0002 6.04 .0030 7.04 .0008)) (define ob-a5 '( 1.01 .0725 2.02 .1474 3.03 .0327 4.04 .0281 5.05 .0013 6.06 .0028 7.07 .0004)) (define ob-as5 '( 1.00 .0837 2.00 .1039 3.00 .0366 4.01 .0118 5.01 .0021 6.01 .0012)) (define ob-b5 '( 1.02 .0812 2.04 .0709 3.06 .0658 4.08 .0099 5.10 .0069 6.12 .0007 7.14 .0001 8.16 .0001)) (define ob-c6 '( 1.01 .0799 2.02 .0161 3.02 .0476 4.03 .0084 5.04 .0029 6.05 .0002)) (define ob-cs6 '( 1.01 .2331 2.02 .1151 3.03 .0163 4.04 .0013 5.05 .0004 6.07 .0003)) (define ob-d6 '( 1.02 .2469 2.03 .0288 3.05 .0144 4.06 .0012 5.08 .0008)) (define ob-ds6 '( 1.00 .2770 2.00 .0028 3.00 .0095 4.00 .0042 5.00 .0006 5.99 .0002)) (define ob-e6 '( 1.00 .3019 2.01 .0125 3.01 .0049 4.02 .0008 5.02 .0001 6.02 .0001)) (define ob-f6 '( 1.01 .0898 2.01 .0089 3.02 .0067 4.02 .0010 5.03 .0002 6.03 .0001)) (define ob-fs6 '( 1.01 .1330 2.03 .0090 3.05 .0031 4.06 .0001)) (define ob-g6 '( 1.00 .1046 1.99 .0228 2.99 .0004 3.98 .0001)) ;;; ;;; ;;; ;;; ;;; piano (define p-c1 '( 1.97 .0326 2.99 .0086 3.95 .0163 4.97 .0178 5.98 .0177 6.95 .0315 8.02 .0001 8.94 .0076 9.96 .0134 10.99 .0284 11.98 .0229 13.02 .0229 13.89 .0010 15.06 .0090 16.00 .0003 17.08 .0078 18.16 .0064 19.18 .0129 20.21 .0085 21.27 .0225 22.32 .0061 23.41 .0102 24.48 .0005 25.56 .0016 26.64 .0018 27.70 .0113 28.80 .0111 29.91 .0158 31.06 .0093 32.17 .0017 33.32 .0002 34.42 .0018 35.59 .0027 36.74 .0055 37.90 .0037 39.06 .0064 40.25 .0033 41.47 .0014 42.53 .0004 43.89 .0010 45.12 .0039 46.33 .0039 47.64 .0009 48.88 .0016 50.13 .0006 51.37 .0010 52.70 .0002 54.00 .0004 55.30 .0008 56.60 .0025 57.96 .0010 59.30 .0012 60.67 .0011 61.99 .0003 62.86 .0001 64.36 .0005 64.86 .0001 66.26 .0004 67.70 .0006 68.94 .0002 70.10 .0001 70.58 .0002 72.01 .0007 73.53 .0006 75.00 .0002 77.03 .0005 78.00 .0002 79.57 .0006 81.16 .0005 82.70 .0005 84.22 .0003 85.41 .0002 87.46 .0001 90.30 .0001 94.02 .0001 95.26 .0002 109.39 .0003)) (define p-cs1 '( 1.98 .0194 2.99 .0210 3.97 .0276 4.96 .0297 5.96 .0158 6.99 .0207 8.01 .0009 9.00 .0101 10.00 .0297 11.01 .0289 12.02 .0211 13.04 .0127 14.07 .0061 15.08 .0174 16.13 .0009 17.12 .0093 18.16 .0117 19.21 .0122 20.29 .0108 21.30 .0077 22.38 .0132 23.46 .0073 24.14 .0002 25.58 .0026 26.69 .0035 27.77 .0053 28.88 .0024 30.08 .0027 31.13 .0075 32.24 .0027 33.36 .0004 34.42 .0004 35.64 .0019 36.78 .0037 38.10 .0009 39.11 .0027 40.32 .0010 41.51 .0013 42.66 .0019 43.87 .0007 45.13 .0017 46.35 .0019 47.65 .0021 48.89 .0014 50.18 .0023 51.42 .0015 52.73 .0002 54.00 .0005 55.34 .0006 56.60 .0010 57.96 .0016 58.86 .0005 59.30 .0004 60.75 .0005 62.22 .0003 63.55 .0005 64.82 .0003 66.24 .0003 67.63 .0011 69.09 .0007 70.52 .0004 72.00 .0005 73.50 .0008 74.95 .0003 77.13 .0013 78.02 .0002 79.48 .0004 82.59 .0004 84.10 .0003)) (define p-d1 '( 2.00 .0313 2.99 .0109 4.00 .0215 5.00 .0242 5.98 .0355 7.01 .0132 8.01 .0009 9.01 .0071 10.00 .0258 11.03 .0221 12.02 .0056 13.06 .0196 14.05 .0160 15.11 .0107 16.11 .0003 17.14 .0111 18.21 .0085 19.23 .0010 20.28 .0048 21.31 .0128 22.36 .0051 23.41 .0041 24.05 .0006 25.54 .0019 26.62 .0028 27.72 .0034 28.82 .0062 29.89 .0039 30.98 .0058 32.08 .0011 33.21 .0002 34.37 .0008 35.46 .0018 36.62 .0036 37.77 .0018 38.92 .0042 40.07 .0037 41.23 .0011 42.67 .0003 43.65 .0018 44.68 .0025 45.99 .0044 47.21 .0051 48.40 .0044 49.67 .0005 50.88 .0019 52.15 .0003 53.42 .0008 54.69 .0010 55.98 .0005 57.26 .0013 58.53 .0027 59.83 .0011 61.21 .0027 62.54 .0003 63.78 .0003 65.20 .0001 66.60 .0006 67.98 .0008 69.37 .0019 70.73 .0007 72.14 .0004 73.62 .0002 74.40 .0003 76.52 .0006 77.97 .0002 79.49 .0004 80.77 .0003 81.00 .0001 82.47 .0005 83.97 .0001 87.27 .0002)) (define p-ds1 '( 2.00 .0257 2.99 .0142 3.97 .0202 4.95 .0148 5.95 .0420 6.95 .0037 7.94 .0004 8.94 .0172 9.95 .0191 10.96 .0115 11.97 .0059 12.98 .0140 14.00 .0178 15.03 .0121 16.09 .0002 17.07 .0066 18.08 .0033 19.15 .0022 20.18 .0057 21.22 .0077 22.29 .0037 23.33 .0066 24.97 .0002 25.49 .0019 26.55 .0042 27.61 .0043 28.73 .0038 29.81 .0084 30.91 .0040 32.03 .0025 33.14 .0005 34.26 .0003 35.38 .0019 36.56 .0037 37.68 .0049 38.86 .0036 40.11 .0011 41.28 .0008 42.50 .0004 43.60 .0002 44.74 .0022 45.99 .0050 47.20 .0009 48.40 .0036 49.68 .0004 50.92 .0009 52.17 .0005 53.46 .0007 54.76 .0006 56.06 .0005 57.34 .0011 58.67 .0005 59.95 .0015 61.37 .0008 62.72 .0004 65.42 .0009 66.96 .0003 68.18 .0003 69.78 .0003 71.21 .0004 72.45 .0002 74.22 .0003 75.44 .0001 76.53 .0003 78.31 .0004 79.83 .0003 80.16 .0001 81.33 .0003 82.44 .0001 83.17 .0002 84.81 .0003 85.97 .0003 89.08 .0001 90.70 .0002 92.30 .0002 95.59 .0002 97.22 .0003 98.86 .0001 108.37 .0001 125.54 .0001)) (define p-e1 '( 1.99 .0650 3.03 .0040 4.03 .0059 5.02 .0090 5.97 .0227 6.98 .0050 8.04 .0020 9.00 .0082 9.96 .0078 11.01 .0056 12.01 .0095 13.02 .0050 14.04 .0093 15.08 .0064 16.14 .0017 17.06 .0020 18.10 .0025 19.14 .0023 20.18 .0015 21.24 .0032 22.29 .0029 23.32 .0014 24.37 .0005 25.43 .0030 26.50 .0022 27.60 .0027 28.64 .0024 29.76 .0035 30.81 .0136 31.96 .0025 33.02 .0003 34.13 .0005 35.25 .0007 36.40 .0014 37.51 .0020 38.64 .0012 39.80 .0019 40.97 .0004 42.09 .0003 43.24 .0003 44.48 .0002 45.65 .0024 46.86 .0005 48.07 .0013 49.27 .0008 50.49 .0006 52.95 .0001 54.23 .0005 55.45 .0004 56.73 .0001 58.03 .0003 59.29 .0002 60.59 .0003 62.04 .0002 65.89 .0002 67.23 .0002 68.61 .0002 69.97 .0004 71.36 .0005 85.42 .0001)) (define p-f1 '( 1.98 .0256 2.96 .0158 3.95 .0310 4.94 .0411 5.95 .0238 6.94 .0152 7.93 .0011 8.95 .0185 9.92 .0166 10.93 .0306 11.94 .0258 12.96 .0202 13.97 .0403 14.95 .0228 15.93 .0005 17.01 .0072 18.02 .0034 19.06 .0028 20.08 .0124 21.13 .0137 22.16 .0102 23.19 .0058 23.90 .0013 25.30 .0039 26.36 .0039 27.41 .0025 28.47 .0071 29.64 .0031 30.60 .0027 31.71 .0021 32.84 .0003 33.82 .0002 35.07 .0019 36.09 .0054 37.20 .0038 38.33 .0024 39.47 .0055 40.55 .0016 41.77 .0006 42.95 .0002 43.27 .0018 44.03 .0006 45.25 .0019 46.36 .0033 47.50 .0024 48.87 .0012 50.03 .0016 51.09 .0004 53.52 .0017 54.74 .0012 56.17 .0003 57.40 .0011 58.42 .0020 59.70 .0007 61.29 .0008 62.56 .0003 63.48 .0002 64.83 .0002 66.12 .0012 67.46 .0017 68.81 .0003 69.13 .0003 70.53 .0002 71.84 .0001 73.28 .0002 75.52 .0010 76.96 .0005 77.93 .0003 78.32 .0003 79.73 .0003 81.69 .0002 82.52 .0001 84.01 .0001 84.61 .0002 86.88 .0001 88.36 .0002 89.85 .0002 91.35 .0003 92.86 .0002 93.40 .0001 105.28 .0002 106.22 .0002 107.45 .0001 108.70 .0003 122.08 .0002)) (define p-fs1 '( 1.97 .0264 2.97 .0211 3.98 .0234 4.98 .0307 5.96 .0085 6.94 .0140 7.93 .0005 8.96 .0112 9.96 .0209 10.98 .0194 11.98 .0154 12.99 .0274 13.99 .0127 15.01 .0101 15.99 .0002 17.04 .0011 18.08 .0032 19.14 .0028 20.12 .0054 21.20 .0053 22.13 .0028 23.22 .0030 24.32 .0006 25.24 .0004 26.43 .0028 27.53 .0048 28.52 .0039 29.54 .0047 30.73 .0044 31.82 .0007 32.94 .0008 34.04 .0012 35.13 .0018 36.29 .0007 37.35 .0075 38.51 .0045 39.66 .0014 40.90 .0004 41.90 .0002 43.08 .0002 44.24 .0017 45.36 .0013 46.68 .0020 47.79 .0015 48.98 .0010 50.21 .0012 51.34 .0001 53.82 .0003 55.09 .0004 56.23 .0005 57.53 .0004 58.79 .0005 59.30 .0002 60.03 .0002 61.40 .0003 62.84 .0001 66.64 .0001 67.97 .0001 69.33 .0001 70.68 .0001 73.57 .0002 75.76 .0002 76.45 .0001 79.27 .0001 80.44 .0002 81.87 .0002)) (define p-g1 '( 2.00 .0311 2.99 .0086 3.99 .0266 4.97 .0123 5.98 .0235 6.97 .0161 7.97 .0008 8.96 .0088 9.96 .0621 10.99 .0080 11.99 .0034 12.99 .0300 14.03 .0228 15.04 .0105 16.03 .0004 17.06 .0036 18.09 .0094 18.95 .0009 20.17 .0071 21.21 .0161 22.25 .0106 23.28 .0104 24.33 .0008 25.38 .0030 26.46 .0035 27.50 .0026 28.59 .0028 29.66 .0128 30.75 .0139 31.81 .0038 32.93 .0006 34.04 .0004 35.16 .0005 36.25 .0023 37.35 .0012 38.46 .0021 39.59 .0035 40.71 .0006 41.86 .0007 42.42 .0001 43.46 .0003 44.17 .0032 45.29 .0013 46.57 .0004 47.72 .0011 48.79 .0005 50.11 .0005 51.29 .0003 52.47 .0002 53.68 .0004 55.02 .0005 56.18 .0003 57.41 .0003 58.75 .0007 59.33 .0009 60.00 .0004 61.34 .0001 64.97 .0003 65.20 .0002 66.48 .0002 67.83 .0002 68.90 .0003 70.25 .0003 71.59 .0002 73.68 .0001 75.92 .0001 77.08 .0002 78.45 .0002 81.56 .0002 82.99 .0001 88.39 .0001)) (define p-gs1 '( .97 .0059 1.98 .0212 2.99 .0153 3.99 .0227 4.96 .0215 5.97 .0153 6.98 .0085 7.98 .0007 8.97 .0179 9.98 .0512 10.98 .0322 12.00 .0098 13.02 .0186 14.00 .0099 15.05 .0109 15.88 .0011 17.07 .0076 18.11 .0071 19.12 .0045 20.16 .0038 21.23 .0213 22.27 .0332 23.34 .0082 24.34 .0014 25.42 .0024 26.47 .0012 27.54 .0014 28.60 .0024 29.72 .0026 30.10 .0008 31.91 .0021 32.13 .0011 33.02 .0007 34.09 .0014 35.17 .0007 36.27 .0024 37.39 .0029 38.58 .0014 39.65 .0017 40.95 .0012 41.97 .0004 42.43 .0002 43.49 .0001 44.31 .0012 45.42 .0031 46.62 .0017 47.82 .0013 49.14 .0013 50.18 .0010 51.54 .0003 53.90 .0006 55.06 .0010 56.31 .0003 57.63 .0001 59.02 .0003 60.09 .0004 60.35 .0004 61.62 .0009 63.97 .0001 65.19 .0001 65.54 .0002 66.92 .0002 67.94 .0002 69.17 .0003 69.60 .0004 70.88 .0002 72.24 .0002 76.12 .0001 78.94 .0001 81.75 .0001 82.06 .0001 83.53 .0001 90.29 .0002 91.75 .0001 92.09 .0002 93.28 .0001 97.07 .0001)) (define p-a1 '( 1.98 .0159 2.98 .1008 3.98 .0365 4.98 .0133 5.97 .0101 6.97 .0115 7.97 .0007 8.99 .0349 10.01 .0342 11.01 .0236 12.00 .0041 13.02 .0114 14.05 .0137 15.06 .0100 16.05 .0007 17.04 .0009 18.12 .0077 19.15 .0023 20.12 .0017 21.24 .0113 22.26 .0126 23.30 .0093 24.36 .0007 25.43 .0007 26.47 .0009 27.55 .0013 28.59 .0025 29.61 .0010 30.77 .0021 31.86 .0023 32.96 .0003 34.03 .0007 35.06 .0005 36.20 .0006 37.34 .0006 38.36 .0009 39.60 .0016 40.69 .0005 41.77 .0002 42.92 .0002 44.02 .0003 45.24 .0006 46.33 .0004 47.50 .0007 48.71 .0007 49.87 .0002 51.27 .0002 53.42 .0003 55.88 .0003 57.10 .0004 58.34 .0002 59.86 .0003 61.13 .0003 67.18 .0001 68.50 .0001 71.17 .0001 83.91 .0001 90.55 .0001)) (define p-as1 '( .98 .0099 2.00 .0181 2.99 .0353 3.98 .0285 4.97 .0514 5.96 .0402 6.96 .0015 7.98 .0012 8.98 .0175 9.98 .0264 10.98 .0392 11.98 .0236 13.00 .0153 14.04 .0049 15.00 .0089 16.01 .0001 17.03 .0106 18.03 .0028 19.05 .0024 20.08 .0040 21.11 .0103 22.12 .0104 23.20 .0017 24.19 .0008 25.20 .0007 26.24 .0011 27.36 .0009 27.97 .0030 29.40 .0044 30.37 .0019 31.59 .0017 32.65 .0008 33.59 .0005 34.79 .0009 35.75 .0027 36.88 .0035 37.93 .0039 39.00 .0031 40.08 .0025 41.16 .0010 43.25 .0004 44.52 .0012 45.62 .0023 45.85 .0012 47.00 .0006 47.87 .0008 48.99 .0003 50.48 .0003 51.62 .0001 52.43 .0001 53.56 .0002 54.76 .0002 56.04 .0002 56.68 .0006 57.10 .0003 58.28 .0005 59.47 .0003 59.96 .0002 60.67 .0001 63.08 .0002 64.29 .0002 66.72 .0001 67.97 .0001 68.65 .0001 70.43 .0001 79.38 .0001 80.39 .0001 82.39 .0001)) (define p-b1 '( 1.00 .0765 1.99 .0151 2.99 .0500 3.99 .0197 5.00 .0260 6.00 .0145 6.98 .0128 7.97 .0004 8.98 .0158 9.99 .0265 11.02 .0290 12.02 .0053 13.03 .0242 14.03 .0103 15.06 .0054 16.04 .0006 17.08 .0008 18.10 .0058 19.16 .0011 20.16 .0055 21.18 .0040 22.20 .0019 23.22 .0014 24.05 .0005 25.31 .0019 26.38 .0018 27.44 .0022 28.45 .0024 29.57 .0073 30.58 .0032 31.66 .0071 32.73 .0015 33.85 .0005 34.96 .0003 36.00 .0020 37.11 .0018 38.18 .0055 39.23 .0006 40.33 .0004 41.52 .0003 43.41 .0028 45.05 .0003 45.99 .0002 47.07 .0003 48.52 .0002 49.48 .0003 50.63 .0003 51.81 .0002 54.05 .0002 55.24 .0001 56.62 .0001 57.81 .0004 59.16 .0013 60.23 .0003 66.44 .0001 68.99 .0004 75.49 .0001 87.56 .0004)) (define p-c2 '( .98 .0629 1.99 .0232 2.98 .0217 4.00 .0396 4.98 .0171 5.97 .0098 6.99 .0167 7.99 .0003 8.98 .0192 9.98 .0266 10.99 .0256 12.01 .0061 13.02 .0135 14.02 .0062 15.05 .0158 16.06 .0018 17.08 .0101 18.09 .0053 19.11 .0074 20.13 .0020 21.17 .0052 22.22 .0077 23.24 .0035 24.00 .0009 25.32 .0016 26.40 .0022 27.43 .0005 28.55 .0026 29.60 .0026 30.65 .0010 31.67 .0019 32.77 .0008 33.81 .0003 34.91 .0003 36.01 .0005 37.11 .0010 38.20 .0014 39.29 .0039 40.43 .0012 41.50 .0006 43.38 .0017 43.75 .0002 44.94 .0005 46.13 .0002 47.11 .0003 48.28 .0005 48.42 .0005 49.44 .0003 50.76 .0004 51.93 .0002 54.15 .0003 55.31 .0005 55.50 .0003 56.98 .0003 57.90 .0004 60.33 .0002 61.39 .0001 61.59 .0001 65.09 .0002 66.34 .0001 68.85 .0001 70.42 .0002 71.72 .0001 73.05 .0003 79.65 .0001 85.28 .0002 93.52 .0001)) (define p-cs2 '( 1.02 .0185 1.99 .0525 2.98 .0613 3.99 .0415 4.98 .0109 5.97 .0248 6.99 .0102 7.98 .0005 8.98 .0124 9.99 .0103 10.99 .0124 12.00 .0016 13.01 .0029 14.03 .0211 15.04 .0128 16.07 .0021 17.09 .0009 18.09 .0043 19.14 .0022 20.13 .0016 21.20 .0045 22.21 .0088 23.26 .0046 24.29 .0013 25.35 .0009 26.39 .0028 27.49 .0009 28.51 .0006 29.58 .0012 30.70 .0010 31.74 .0019 32.75 .0002 33.85 .0001 34.95 .0005 36.02 .0003 37.16 .0009 38.25 .0018 39.35 .0008 40.54 .0004 41.61 .0002 43.40 .0004 43.74 .0003 45.05 .0001 46.11 .0003 47.40 .0002 48.36 .0004 49.55 .0004 50.72 .0002 52.00 .0001 55.58 .0002 57.02 .0001 57.98 .0002 59.13 .0003 61.56 .0001 66.56 .0001 87.65 .0002)) (define p-d2 '( 1.00 .0473 1.99 .0506 2.99 .0982 3.99 .0654 5.00 .0196 5.99 .0094 6.99 .0118 7.93 .0001 8.99 .0057 10.01 .0285 11.01 .0142 12.03 .0032 13.03 .0056 14.06 .0064 15.06 .0059 16.11 .0005 17.09 .0033 18.14 .0027 19.15 .0014 20.17 .0010 21.21 .0059 22.26 .0043 23.31 .0031 24.31 .0018 25.33 .0009 26.41 .0005 27.47 .0015 28.53 .0015 29.58 .0041 30.65 .0025 31.73 .0011 32.83 .0010 34.98 .0003 36.07 .0009 37.23 .0001 38.26 .0020 39.41 .0014 40.53 .0005 41.40 .0003 42.80 .0002 43.48 .0028 43.93 .0001 45.03 .0003 46.18 .0007 47.41 .0001 48.57 .0002 49.67 .0001 50.83 .0002 54.39 .0001 55.58 .0002 57.97 .0005 58.11 .0002 59.21 .0001 60.42 .0002 61.66 .0001)) (define p-ds2 '( 1.00 .0503 2.00 .0963 2.99 .1304 3.99 .0218 4.98 .0041 5.98 .0292 6.98 .0482 7.99 .0005 8.99 .0280 10.00 .0237 11.00 .0152 12.02 .0036 12.95 .0022 14.06 .0111 15.07 .0196 16.08 .0016 17.11 .0044 18.13 .0073 19.17 .0055 20.19 .0028 21.20 .0012 22.27 .0068 23.30 .0036 24.35 .0012 25.35 .0002 26.46 .0005 27.47 .0005 28.59 .0009 29.65 .0021 30.70 .0020 31.78 .0012 32.89 .0010 35.06 .0005 36.16 .0008 37.27 .0010 38.36 .0010 39.47 .0014 40.58 .0004 41.43 .0007 41.82 .0003 43.48 .0008 44.53 .0001 45.25 .0003 46.43 .0002 47.46 .0002 48.76 .0005 49.95 .0004 50.96 .0002 51.12 .0002 52.33 .0001 54.75 .0001 55.75 .0002 56.90 .0002 58.17 .0002 59.40 .0004 60.62 .0002 65.65 .0001 66.91 .0002 69.91 .0001 71.25 .0002)) (define p-e2 '( 1.00 .1243 1.98 .1611 3.00 .0698 3.98 .0390 5.00 .0138 5.99 .0154 7.01 .0287 8.01 .0014 9.01 .0049 10.00 .0144 11.01 .0055 12.05 .0052 13.01 .0011 14.05 .0118 15.07 .0154 16.12 .0028 17.14 .0061 18.25 .0007 19.22 .0020 20.24 .0011 21.27 .0029 22.30 .0046 23.34 .0049 24.35 .0004 25.45 .0003 26.47 .0007 27.59 .0008 28.16 .0009 29.12 .0002 29.81 .0006 30.81 .0009 31.95 .0004 33.00 .0011 34.12 .0005 35.18 .0003 36.30 .0008 37.38 .0003 38.55 .0003 39.64 .0006 40.77 .0007 41.52 .0006 41.89 .0006 43.04 .0011 43.60 .0009 44.31 .0002 45.68 .0002 46.56 .0003 47.60 .0001 48.83 .0006 50.01 .0003 51.27 .0003 56.04 .0005 57.21 .0003 58.56 .0004 59.83 .0003 61.05 .0001 62.20 .0001 67.37 .0002 76.53 .0001)) (define p-f2 '( .99 .0222 1.99 .0678 2.99 .0683 4.00 .0191 5.00 .0119 6.01 .0232 6.98 .0336 7.99 .0082 9.01 .0201 10.01 .0189 11.01 .0041 12.01 .0053 13.05 .0154 14.04 .0159 15.06 .0092 16.11 .0038 17.12 .0014 18.15 .0091 19.16 .0006 20.30 .0012 21.25 .0061 22.28 .0099 23.34 .0028 24.38 .0012 25.43 .0016 26.49 .0048 27.55 .0025 28.62 .0015 29.71 .0032 30.78 .0077 31.88 .0011 32.97 .0007 34.08 .0006 35.16 .0008 36.28 .0004 37.41 .0006 38.54 .0005 39.62 .0002 40.80 .0003 41.93 .0001 43.06 .0002 44.21 .0003 45.38 .0002 46.54 .0007 47.78 .0003 48.95 .0004 50.10 .0003 51.37 .0002 53.79 .0003 56.20 .0001 58.71 .0002 66.47 .0003)) (define p-fs2 '( 1.01 .0241 1.99 .1011 2.98 .0938 3.98 .0081 4.99 .0062 5.99 .0291 6.99 .0676 7.59 .0004 8.98 .0127 9.99 .0112 10.99 .0142 12.00 .0029 13.02 .0071 14.02 .0184 15.03 .0064 16.07 .0010 17.09 .0011 18.11 .0010 19.15 .0060 20.19 .0019 21.24 .0025 22.29 .0013 23.31 .0050 25.41 .0030 26.50 .0018 27.53 .0006 28.63 .0012 29.66 .0013 30.77 .0020 31.84 .0006 34.04 .0001 35.14 .0001 36.32 .0004 37.41 .0007 38.53 .0007 39.67 .0009 40.85 .0003 45.49 .0002 46.65 .0001 47.81 .0004 49.01 .0002 53.91 .0002 55.14 .0002 57.69 .0002)) (define p-g2 '( 1.00 .0326 2.00 .1066 2.99 .1015 4.00 .0210 4.97 .0170 5.99 .0813 6.98 .0820 7.96 .0011 8.99 .0248 10.03 .0107 11.01 .0126 12.01 .0027 13.01 .0233 14.04 .0151 15.05 .0071 16.04 .0002 17.10 .0061 18.12 .0059 19.15 .0087 20.23 .0005 21.25 .0040 22.30 .0032 23.35 .0004 24.40 .0001 25.45 .0030 26.54 .0022 27.60 .0003 28.70 .0009 29.80 .0029 30.85 .0006 31.97 .0006 34.19 .0004 35.30 .0003 36.43 .0007 37.56 .0005 38.68 .0019 39.88 .0013 41.00 .0003 43.35 .0003 44.51 .0002 45.68 .0006 46.93 .0010 48.11 .0006 49.29 .0003 55.58 .0002)) (define p-gs2 '( .98 .0113 1.99 .0967 3.00 .0719 3.98 .0345 4.98 .0121 6.00 .0621 7.00 .0137 7.98 .0006 9.01 .0314 10.01 .0171 11.02 .0060 12.03 .0024 13.05 .0077 14.07 .0040 15.12 .0032 16.13 .0004 17.15 .0011 18.20 .0028 19.18 .0003 20.26 .0003 21.31 .0025 22.35 .0021 23.39 .0005 25.55 .0002 26.62 .0014 27.70 .0003 28.78 .0005 29.90 .0030 31.01 .0011 32.12 .0005 34.31 .0001 35.50 .0002 36.62 .0002 37.76 .0005 38.85 .0002 40.09 .0004 43.60 .0001 44.73 .0002 46.02 .0002 47.25 .0004 48.44 .0004)) (define p-a2 '( .99 .0156 1.98 .0846 2.98 .0178 3.98 .0367 4.98 .0448 5.98 .0113 6.99 .0189 8.00 .0011 9.01 .0247 10.02 .0089 11.01 .0184 12.03 .0105 13.00 .0039 14.07 .0116 15.09 .0078 16.13 .0008 17.14 .0064 18.19 .0029 19.22 .0028 20.25 .0017 21.32 .0043 22.37 .0055 23.42 .0034 24.48 .0004 25.54 .0002 26.61 .0017 27.70 .0011 28.80 .0002 29.89 .0019 30.97 .0028 32.09 .0007 34.30 .0002 35.44 .0003 36.55 .0001 37.69 .0004 38.93 .0002 40.05 .0005 41.20 .0005 42.37 .0002 43.54 .0003 44.73 .0001 45.95 .0002 47.16 .0001 48.43 .0005 49.65 .0004 55.90 .0002 59.81 .0004)) (define p-as2 '( 1.01 .0280 2.00 .0708 2.99 .0182 3.99 .0248 4.98 .0245 5.98 .0279 6.98 .0437 7.99 .0065 8.99 .0299 10.00 .0073 10.99 .0011 12.03 .0122 13.03 .0028 14.08 .0044 15.11 .0097 16.15 .0010 17.17 .0025 18.19 .0017 19.24 .0008 20.28 .0040 21.32 .0024 22.38 .0008 23.46 .0032 24.52 .0010 25.59 .0008 26.68 .0009 27.76 .0012 28.88 .0003 29.95 .0005 31.05 .0017 32.14 .0002 33.29 .0003 37.88 .0002 39.03 .0002 40.19 .0004 41.37 .0003 43.74 .0002 46.20 .0001 48.68 .0001 49.93 .0001 51.19 .0002)) (define p-b2 '( 1.00 .0225 1.99 .0921 2.98 .0933 3.99 .0365 4.99 .0100 5.98 .0213 6.98 .0049 7.98 .0041 8.98 .0090 9.99 .0068 11.01 .0040 12.03 .0086 13.02 .0015 14.04 .0071 15.09 .0082 16.14 .0011 17.15 .0014 18.18 .0010 19.26 .0013 20.26 .0005 21.33 .0006 22.36 .0011 23.46 .0016 24.52 .0004 25.59 .0002 26.70 .0006 27.78 .0007 28.87 .0002 30.03 .0008 31.14 .0010 32.24 .0006 33.37 .0002 35.67 .0003 37.99 .0004 39.17 .0004 40.35 .0005 41.53 .0001 46.42 .0001)) (define p-c3 '( 1.00 .0465 1.99 .0976 2.98 .0678 4.00 .0727 4.99 .0305 5.98 .0210 6.98 .0227 8.00 .0085 9.01 .0183 10.02 .0258 11.05 .0003 12.06 .0061 13.05 .0021 14.10 .0089 15.12 .0077 16.16 .0016 17.21 .0061 18.23 .0011 19.29 .0031 20.36 .0031 21.41 .0007 22.48 .0013 23.55 .0020 24.64 .0004 25.74 .0005 26.81 .0006 27.95 .0006 29.03 .0001 30.22 .0010 31.30 .0004 32.48 .0001 33.60 .0002 38.30 .0003)) (define p-cs3 '( 1.00 .0674 1.99 .0841 2.98 .0920 3.99 .0328 4.99 .0368 5.98 .0206 6.99 .0246 8.01 .0048 9.01 .0218 10.03 .0155 11.05 .0048 12.06 .0077 13.00 .0020 14.10 .0083 15.15 .0084 16.18 .0015 17.22 .0039 18.27 .0032 19.34 .0026 20.40 .0012 21.47 .0009 22.54 .0008 23.62 .0016 24.71 .0005 25.82 .0004 26.91 .0002 28.03 .0008 29.17 .0002 30.32 .0028 31.45 .0004 32.61 .0005 33.77 .0001 36.14 .0003 37.32 .0002 38.54 .0005 39.75 .0002 42.23 .0002 48.65 .0001)) (define p-d3 '( 1.01 .0423 1.99 .0240 2.98 .0517 4.00 .0493 5.00 .0324 6.00 .0094 6.99 .0449 7.99 .0050 9.00 .0197 10.03 .0132 11.03 .0009 12.07 .0017 13.08 .0023 14.12 .0094 15.16 .0071 16.21 .0020 17.25 .0005 18.30 .0027 19.04 .0004 20.43 .0022 21.51 .0002 22.59 .0006 23.72 .0018 24.80 .0002 25.88 .0002 27.03 .0002 28.09 .0006 29.31 .0002 30.46 .0004 31.61 .0007 32.78 .0005 33.95 .0001 36.34 .0002 37.56 .0001 38.80 .0001 40.02 .0001 44.14 .0001)) (define p-ds3 '( 1.00 .0669 1.99 .0909 2.99 .0410 3.98 .0292 4.98 .0259 5.98 .0148 6.98 .0319 7.99 .0076 9.01 .0056 10.02 .0206 11.04 .0032 12.05 .0085 13.08 .0040 14.12 .0037 15.16 .0030 16.20 .0013 17.24 .0021 18.30 .0010 19.36 .0015 20.44 .0013 21.50 .0009 22.60 .0015 23.69 .0014 24.80 .0006 25.87 .0002 27.02 .0006 28.12 .0002 29.28 .0003 30.43 .0002 31.59 .0007 32.79 .0001 35.14 .0001 37.57 .0001 40.03 .0002 41.28 .0004 44.10 .0001)) (define p-e3 '( .99 .0421 1.99 .1541 2.98 .0596 3.98 .0309 4.98 .0301 5.99 .0103 7.00 .0240 8.01 .0073 9.01 .0222 10.04 .0140 11.05 .0033 12.08 .0045 13.13 .0009 14.13 .0015 15.21 .0026 16.24 .0003 17.30 .0004 18.35 .0010 19.39 .0003 20.50 .0015 21.57 .0003 22.68 .0011 23.80 .0005 24.90 .0008 26.02 .0002 27.16 .0001 28.30 .0006 29.48 .0002 31.81 .0005 33.00 .0003 34.21 .0001 37.89 .0001)) (define p-f3 '( .99 .0389 2.00 .2095 3.00 .0835 3.99 .0289 5.00 .0578 5.99 .0363 7.01 .0387 8.01 .0056 9.04 .0173 10.05 .0175 11.08 .0053 12.10 .0056 13.15 .0064 14.19 .0036 15.22 .0019 16.29 .0010 17.36 .0017 18.43 .0018 19.51 .0004 20.60 .0011 21.70 .0003 22.82 .0003 23.95 .0001 25.05 .0004 26.17 .0001 28.50 .0003 29.68 .0001 32.07 .0003 33.28 .0004 34.52 .0001)) (define p-fs3 '( 1.00 .1238 1.99 .2270 3.00 .0102 3.99 .0181 4.98 .0415 6.00 .0165 7.01 .0314 8.02 .0148 9.04 .0203 10.05 .0088 11.07 .0062 12.11 .0070 13.14 .0054 14.19 .0028 15.24 .0044 16.30 .0029 17.38 .0009 18.45 .0026 19.56 .0003 20.65 .0025 21.74 .0014 22.87 .0013 23.99 .0007 25.15 .0002 27.46 .0004 28.39 .0006 28.65 .0004 29.85 .0001 31.05 .0002 32.27 .0003 33.52 .0002 34.76 .0003)) (define p-g3 '( 1.00 .1054 2.00 .2598 2.99 .0369 3.98 .0523 4.99 .0020 5.99 .0051 7.00 .0268 8.01 .0027 9.04 .0029 10.05 .0081 11.08 .0047 12.12 .0051 13.16 .0091 14.19 .0015 15.27 .0030 16.34 .0017 17.42 .0006 18.51 .0003 19.61 .0007 20.72 .0003 21.84 .0001 22.99 .0010 24.13 .0001 28.44 .0001 30.09 .0001)) (define p-gs3 '( .99 .0919 2.00 .0418 2.99 .0498 3.99 .0135 4.99 .0026 6.00 .0155 7.01 .0340 8.02 .0033 9.04 .0218 10.08 .0084 11.11 .0057 12.15 .0051 13.21 .0043 14.25 .0015 15.31 .0023 16.40 .0008 17.48 .0004 18.59 .0016 19.71 .0010 20.84 .0018 21.98 .0002 23.11 .0013 24.26 .0003 26.67 .0002 29.12 .0002 30.37 .0002 31.62 .0003 32.92 .0001)) (define p-a3 '( .99 .1174 1.99 .1126 2.99 .0370 3.99 .0159 5.01 .0472 6.01 .0091 7.03 .0211 8.05 .0015 9.07 .0098 10.11 .0038 11.15 .0042 12.20 .0018 13.24 .0041 14.32 .0033 15.41 .0052 16.49 .0001 17.61 .0004 18.71 .0004 19.84 .0004 20.99 .0002 22.14 .0006 23.31 .0006 24.50 .0004 25.70 .0002 28.09 .0002 28.66 .0002 32.00 .0001)) (define p-as3 '( 1.00 .1085 2.00 .1400 2.99 .0173 3.99 .0229 5.00 .0272 6.02 .0077 7.03 .0069 8.04 .0017 9.08 .0045 10.10 .0030 11.15 .0040 12.20 .0007 13.25 .0019 14.32 .0008 15.42 .0024 16.50 .0002 17.59 .0005 18.71 .0003 19.83 .0002 20.98 .0005 23.29 .0008)) (define p-b3 '( 1.00 .0985 2.00 .1440 2.99 .0364 3.99 .0425 5.00 .0190 6.01 .0089 7.03 .0278 8.04 .0006 9.07 .0083 10.10 .0021 11.14 .0050 12.18 .0005 13.26 .0036 14.33 .0005 15.41 .0026 17.62 .0004 18.75 .0004 19.89 .0003 21.04 .0012 22.21 .0002 23.38 .0004 27.04 .0001)) (define p-c4 '( .99 .1273 2.00 .1311 2.99 .0120 4.00 .0099 5.00 .0235 6.02 .0068 7.03 .0162 8.06 .0009 9.08 .0083 10.12 .0014 11.17 .0050 12.24 .0010 13.29 .0013 14.39 .0022 15.48 .0011 16.59 .0002 17.70 .0003 18.84 .0010 20.00 .0003 21.17 .0003 23.56 .0004 28.79 .0003)) (define p-cs4 '( 1.00 .1018 2.00 .1486 3.00 .0165 4.00 .0186 5.01 .0194 6.02 .0045 7.04 .0083 8.06 .0012 9.10 .0066 10.15 .0009 11.19 .0008 12.26 .0011 13.34 .0028 14.45 .0006 15.53 .0009 16.66 .0002 17.79 .0006 18.94 .0005 20.11 .0003 21.29 .0005 22.49 .0003 23.73 .0005 26.22 .0001 27.52 .0001 28.88 .0002)) (define p-d4 '( 1.00 .1889 1.99 .1822 3.00 .0363 4.00 .0047 5.01 .0202 6.03 .0053 7.05 .0114 8.01 .0002 9.13 .0048 10.17 .0010 11.23 .0033 12.30 .0010 13.38 .0006 14.50 .0002 15.62 .0010 20.27 .0001 21.47 .0001)) (define p-ds4 '( 1.00 .0522 1.99 .0763 2.99 .0404 4.00 .0139 5.01 .0185 6.01 .0021 7.06 .0045 8.09 .0002 9.11 .0003 10.17 .0006 11.25 .0004 12.32 .0005 13.40 .0003 14.53 .0003 15.65 .0007 16.80 .0001 17.95 .0002 19.14 .0006 20.34 .0002 21.56 .0003)) (define p-e4 '( .99 .1821 1.99 .0773 3.00 .0125 4.01 .0065 5.01 .0202 6.03 .0071 7.05 .0090 8.08 .0006 9.13 .0008 10.18 .0013 11.25 .0010 12.33 .0012 13.42 .0006 14.54 .0005 15.65 .0004 17.97 .0002 19.15 .0001)) (define p-f4 '( 1.00 .1868 2.00 .0951 3.00 .0147 4.01 .0134 5.02 .0184 6.04 .0132 7.06 .0011 8.11 .0008 9.15 .0010 10.22 .0012 11.30 .0011 12.40 .0003 13.11 .0004 13.49 .0002 14.62 .0003 15.77 .0001)) (define p-fs4 '( 1.00 .1933 2.00 .0714 3.00 .0373 4.00 .0108 5.02 .0094 6.02 .0010 7.07 .0022 8.11 .0002 9.16 .0065 10.23 .0015 11.31 .0023 12.40 .0003 13.53 .0014 14.66 .0002 15.81 .0011 18.20 .0002 19.41 .0001)) (define p-g4 '( .99 .2113 1.99 .0877 3.00 .0492 4.01 .0094 5.02 .0144 6.04 .0103 7.07 .0117 8.12 .0006 9.19 .0019 10.25 .0007 11.35 .0017 12.45 .0010 13.58 .0003 14.74 .0003 15.91 .0003 19.57 .0002)) (define p-gs4 '( .99 .2455 1.99 .0161 3.00 .0215 4.01 .0036 5.03 .0049 6.04 .0012 7.09 .0036 8.14 .0011 9.21 .0009 10.30 .0001 11.40 .0012 12.50 .0001 13.66 .0005 14.84 .0001)) (define p-a4 '( 1.00 .1132 2.00 .0252 3.00 .0292 4.01 .0136 5.03 .0045 6.06 .0022 7.11 .0101 8.17 .0004 9.23 .0010 10.33 .0012 11.44 .0013 12.58 .0011 13.75 .0002 14.93 .0005 16.14 .0002)) (define p-as4 '( 1.00 .1655 2.00 .0445 3.00 .0120 4.00 .0038 5.02 .0015 6.07 .0038 7.11 .0003 8.19 .0002 9.25 .0010 10.36 .0011 11.48 .0005 12.63 .0002 13.79 .0003 16.24 .0002)) (define p-b4 '( .99 .3637 1.99 .0259 3.01 .0038 4.01 .0057 5.03 .0040 6.07 .0067 7.12 .0014 8.19 .0004 9.27 .0003 10.38 .0002 12.67 .0001)) (define p-c5 '( 1.00 .1193 2.00 .0230 3.00 .0104 4.01 .0084 5.04 .0047 6.08 .0035 7.13 .0041 8.20 .0002 9.29 .0005 10.40 .0005 11.53 .0003 12.70 .0002 13.91 .0002)) (define p-cs5 '( 1.00 .0752 2.00 .0497 3.00 .0074 4.02 .0076 5.05 .0053 6.09 .0043 7.15 .0024 8.22 .0001 9.32 .0006 10.45 .0002 11.58 .0001 12.78 .0001 15.22 .0001)) (define p-d5 '( 1.00 .2388 2.00 .0629 3.01 .0159 4.04 .0063 5.07 .0051 6.12 .0045 7.19 .0026 8.29 .0015 9.43 .0001 11.75 .0002)) (define p-ds5 '( 1.00 .1919 2.01 .0116 3.01 .0031 4.03 .0090 5.07 .0061 6.13 .0036 7.19 .0013 8.30 .0016 9.13 .0001 10.59 .0002 11.78 .0002)) (define p-e5 '( 1.00 .1296 2.00 .0135 3.01 .0041 4.04 .0045 5.09 .0028 6.14 .0046 7.23 .0007 8.32 .0007 9.50 .0001)) (define p-f5 '( 1.00 .0692 2.00 .0209 3.02 .0025 4.05 .0030 5.09 .0047 6.17 .0022 7.25 .0015 8.36 .0015 9.53 .0010 10.69 .0001 13.40 .0001)) (define p-fs5 '( 1.00 .1715 2.00 .0142 3.01 .0024 4.03 .0015 5.07 .0017 6.13 .0018 7.22 .0009 8.33 .0014 9.51 .0007 10.69 .0002)) (define p-g5 '( 1.00 .1555 2.01 .0148 3.02 .0007 4.06 .0006 5.10 .0005 6.16 .0008 7.26 .0009 8.39 .0008 9.58 .0002)) (define p-gs5 '( 1.00 .1357 2.00 .0116 3.02 .0026 4.04 .0009 5.09 .0004 6.17 .0005 7.27 .0002 8.40 .0001)) (define p-a5 '( 1.00 .2185 2.01 .0087 3.03 .0018 4.06 .0025 5.11 .0020 6.20 .0012 7.32 .0005 8.46 .0001 9.66 .0003)) (define p-as5 '( 1.00 .2735 2.00 .0038 3.02 .0008 4.06 .0012 5.12 .0008 6.22 .0011 7.35 .0003 8.50 .0002)) (define p-b5 '( 1.00 .1441 1.99 .0062 3.01 .0023 4.05 .0011 5.11 .0012 6.20 .0003 7.33 .0004 8.50 .0001)) (define p-c6 '( 1.00 .0726 2.01 .0293 3.03 .0022 5.14 .0005 6.26 .0011 7.41 .0002 8.63 .0002)) (define p-cs6 '( 1.00 .0516 2.00 .0104 3.02 .0029 5.15 .0002 6.27 .0001)) (define p-d6 '( 1.00 .0329 2.00 .0033 3.03 .0013 4.10 .0005 5.19 .0004 6.32 .0002)) (define p-ds6 '( 1.00 .0179 1.99 .0012 3.04 .0005 4.10 .0017 5.20 .0005 6.35 .0001)) (define p-e6 '( 1.00 .0334 2.01 .0033 3.04 .0011 4.13 .0003 5.22 .0003)) (define p-f6 '( .99 .0161 2.01 .0100 3.04 .0020 4.13 .0003)) (define p-fs6 '( 1.00 .0475 1.99 .0045 3.03 .0035 4.12 .0011)) (define p-g6 '( 1.00 .0593 2.00 .0014 4.17 .0002)) (define p-gs6 '( 1.00 .0249 2.01 .0016)) (define p-a6 '( 1.00 .0242 2.00 .0038 4.19 .0002)) (define p-as6 '( 1.00 .0170 2.02 .0030)) (define p-b6 '( 1.00 .0381 2.00 .0017 3.09 .0002)) (define p-c7 '( 1.00 .0141 2.03 .0005 3.11 .0003 4.26 .0001)) (define p-cs7 '( 1.00 .0122 2.03 .0024)) (define p-d7 '( 1.00 .0107 2.07 .0007 3.12 .0004)) (define p-ds7 '( 1.00 .0250 2.02 .0026 3.15 .0002)) (define p-e7 '( 1.01 .0092)) (define p-f7 '( 1.01 .0102 2.09 .0005)) (define p-fs7 '( 1.00 .0080 2.00 .0005 3.19 .0001)) (define p-g7 '( 1.01 .0298 2.01 .0005)) ;;; ;;; ;;; ;;; ;;; sax (define sax-cs3 '( 1.01 .0565 2.01 .0374 3.00 .0377 4.00 .0498 5.02 .0907 6.02 .0361 7.02 .0250 8.01 .0036 9.02 .0181 10.03 .0319 11.03 .0075 12.03 .0068 13.03 .0037 14.03 .0015 15.05 .0021 16.04 .0034 17.04 .0076 18.04 .0101 19.06 .0056 20.06 .0051 21.05 .0046 22.05 .0029 23.05 .0015 24.07 .0026 25.07 .0023 26.06 .0025 27.06 .0010 28.08 .0011 29.08 .0005 30.07 .0017 31.07 .0025 32.07 .0032 33.09 .0026 34.09 .0023 35.09 .0038 36.09 .0023 37.09 .0018 38.11 .0023 39.11 .0017 40.10 .0015 41.10 .0010 42.10 .0008 43.13 .0004 45.13 .0001 46.11 .0005 47.12 .0004 48.12 .0006 49.11 .0004 50.12 .0008 51.13 .0006 52.14 .0009 53.13 .0006 54.13 .0008 55.13 .0007 56.15 .0005 57.16 .0002 58.13 .0001 59.17 .0001 61.15 .0001 62.15 .0002 63.16 .0002 65.17 .0004 66.18 .0005 67.18 .0003 68.17 .0002 69.17 .0005 70.18 .0003 71.18 .0002 72.18 .0005 73.18 .0003 74.18 .0003 75.20 .0003 76.19 .0003 77.19 .0002 78.19 .0004 80.20 .0002 81.19 .0001 82.21 .0001 89.23 .0002 90.23 .0002 91.23 .0003 92.22 .0001)) (define sax-d3 '( 1.00 .0423 1.99 .0487 2.98 .0259 3.99 .0630 4.99 .1026 5.97 .0532 6.97 .0259 7.98 .0110 8.97 .0076 9.96 .0123 10.97 .0162 11.96 .0128 12.95 .0178 13.94 .0114 14.96 .0134 15.95 .0186 16.94 .0180 17.93 .0087 18.94 .0084 19.93 .0064 20.92 .0033 21.93 .0025 22.93 .0041 23.91 .0041 24.90 .0034 25.91 .0012 26.90 .0013 27.90 .0020 28.89 .0036 29.90 .0054 30.89 .0054 31.88 .0038 32.89 .0059 33.89 .0037 34.88 .0024 35.86 .0024 36.87 .0023 37.87 .0017 38.86 .0020 39.85 .0019 40.86 .0021 41.86 .0007 42.84 .0012 43.84 .0007 44.84 .0010 45.85 .0005 46.82 .0006 47.84 .0009 48.82 .0009 49.82 .0006 50.81 .0008 51.82 .0012 52.80 .0012 54.81 .0005 55.78 .0003 56.79 .0003 57.78 .0003 58.79 .0003 59.80 .0004 60.77 .0003 61.78 .0004 62.77 .0005 63.77 .0001 64.75 .0004 65.76 .0003 66.77 .0003 67.76 .0006 68.75 .0006 69.75 .0007 70.74 .0004 71.74 .0010 72.73 .0008 73.74 .0007 75.74 .0002 76.72 .0004 77.72 .0002 78.71 .0004 79.70 .0001 80.71 .0001 81.70 .0002 82.70 .0001 83.70 .0004 84.69 .0003 85.68 .0008 86.68 .0003 87.69 .0001 88.69 .0002 90.66 .0001)) (define sax-ds3 '( 1.00 .0338 1.99 .0765 2.97 .0602 3.96 .0870 4.97 .1666 5.96 .0394 6.95 .0067 7.94 .0199 8.94 .0418 9.93 .0110 10.92 .0101 11.91 .0077 12.90 .0052 13.91 .0148 14.90 .0172 15.88 .0218 16.87 .0110 17.88 .0086 18.87 .0045 19.86 .0009 20.85 .0014 21.85 .0045 22.84 .0037 23.83 .0010 24.82 .0028 25.81 .0013 26.82 .0032 27.81 .0040 28.79 .0067 29.78 .0035 30.79 .0041 31.78 .0028 32.76 .0017 33.75 .0011 34.76 .0015 35.75 .0018 36.73 .0021 37.72 .0017 38.71 .0019 39.72 .0014 40.71 .0015 41.70 .0016 42.69 .0006 43.69 .0021 44.69 .0024 45.67 .0003 46.66 .0014 47.66 .0002 48.66 .0011 49.65 .0010 50.63 .0002 51.62 .0008 52.63 .0007 53.62 .0008 54.60 .0004 56.59 .0005 57.59 .0003 58.58 .0007 60.56 .0004 61.56 .0002 62.55 .0004 63.54 .0004 64.53 .0008 65.54 .0011 66.53 .0003 67.52 .0009 68.51 .0008 69.51 .0013 70.50 .0002 71.49 .0004 72.47 .0004 73.47 .0002 74.48 .0002 75.46 .0002 76.45 .0005 77.45 .0003 78.45 .0008 79.44 .0003 80.42 .0008 81.41 .0005 82.41 .0001 83.42 .0001)) (define sax-e3 '( 1.00 .0225 1.99 .0627 2.99 .0834 3.98 .0804 4.98 .0984 5.97 .0393 6.96 .0345 7.96 .0102 8.95 .0084 9.94 .0129 10.93 .0214 11.93 .0154 12.92 .0184 13.91 .0167 14.91 .0213 15.90 .0116 16.89 .0090 17.88 .0045 18.88 .0008 19.87 .0024 20.86 .0045 21.86 .0058 22.85 .0012 23.84 .0012 24.84 .0030 25.83 .0035 26.82 .0067 27.83 .0048 28.82 .0016 29.82 .0012 30.81 .0015 31.81 .0032 32.80 .0033 33.80 .0038 34.79 .0032 35.78 .0025 36.78 .0008 37.77 .0007 38.76 .0020 39.75 .0009 40.75 .0007 41.74 .0018 42.73 .0024 43.72 .0012 44.72 .0016 45.71 .0015 46.70 .0019 47.69 .0005 48.69 .0007 49.68 .0006 50.67 .0003 51.68 .0006 52.67 .0002 53.66 .0004 54.65 .0004 55.65 .0005 56.64 .0004 57.64 .0006 58.64 .0004 59.64 .0004 60.63 .0011 61.62 .0004 62.62 .0003 63.61 .0005 64.60 .0011 65.60 .0010 65.74 .0001 66.59 .0001 67.58 .0006 68.57 .0007 69.56 .0003 70.56 .0002 71.56 .0002 72.55 .0007 73.54 .0009 74.53 .0008 75.52 .0007 76.52 .0006 77.51 .0002 79.50 .0002)) (define sax-f3 '( .98 .0394 1.98 .0562 2.97 .0897 3.96 .0683 4.96 .0231 5.95 .0309 6.94 .0308 7.91 .0176 8.91 .0089 9.90 .0084 10.89 .0141 11.89 .0045 12.88 .0070 13.87 .0083 14.85 .0142 15.84 .0089 16.83 .0048 17.82 .0015 18.82 .0028 19.82 .0027 20.81 .0015 21.79 .0012 22.77 .0015 23.76 .0050 24.76 .0041 25.75 .0048 26.75 .0015 27.74 .0007 28.73 .0011 29.71 .0016 30.70 .0020 31.69 .0019 32.68 .0032 33.68 .0026 34.67 .0014 35.66 .0013 36.64 .0009 37.63 .0014 38.62 .0009 39.61 .0018 40.61 .0008 41.60 .0013 42.59 .0007 43.57 .0010 44.56 .0006 45.57 .0002 46.54 .0009 47.53 .0005 48.51 .0002 49.53 .0001 50.52 .0005 51.49 .0002 52.49 .0006 53.47 .0001 54.48 .0002 55.46 .0003 56.47 .0002 57.45 .0006 58.43 .0004 59.42 .0003 60.41 .0006 61.41 .0005 62.40 .0005 63.40 .0002 64.38 .0003 65.37 .0001 66.35 .0002 68.34 .0005 69.33 .0003 70.33 .0005 71.32 .0001 72.30 .0002 75.27 .0001)) (define sax-fs3 '( .99 .0784 1.99 .0550 2.97 .0439 3.97 .0998 4.95 .0679 5.95 .0244 6.93 .0178 7.94 .0130 8.92 .0186 9.92 .0204 10.90 .0091 11.90 .0102 12.88 .0166 13.88 .0130 14.86 .0079 15.86 .0039 16.86 .0023 17.84 .0052 18.84 .0049 19.82 .0042 20.82 .0027 21.81 .0027 22.80 .0057 23.78 .0042 24.79 .0042 25.77 .0015 26.77 .0008 27.75 .0020 28.75 .0021 29.73 .0032 30.73 .0036 31.71 .0022 32.71 .0011 33.71 .0015 34.69 .0011 35.69 .0012 36.67 .0013 37.67 .0014 38.65 .0006 39.65 .0013 40.64 .0004 41.63 .0010 42.62 .0002 43.62 .0010 44.60 .0003 45.59 .0003 46.58 .0004 47.59 .0005 48.57 .0002 49.55 .0005 50.55 .0002 51.54 .0002 52.53 .0005 53.53 .0006 54.52 .0006 55.51 .0002 56.50 .0008 57.47 .0003 58.48 .0007 59.47 .0003 60.46 .0002 61.44 .0002 62.45 .0002 63.43 .0001 64.43 .0004 65.42 .0005 66.41 .0007 67.40 .0002 68.39 .0002 69.39 .0002 70.37 .0001)) (define sax-g3 '( 1.00 .1076 1.99 .0463 2.98 .1092 3.97 .0816 4.95 .0831 5.94 .0118 6.93 .0095 7.94 .0104 8.93 .0148 9.92 .0144 10.91 .0117 11.90 .0196 12.89 .0153 13.88 .0107 14.87 .0052 15.86 .0033 16.86 .0058 17.85 .0042 18.83 .0013 19.83 .0029 20.82 .0067 21.81 .0040 22.80 .0057 23.79 .0022 24.79 .0019 25.78 .0009 26.78 .0017 27.76 .0025 28.76 .0024 29.74 .0020 30.73 .0011 31.72 .0010 32.73 .0007 33.72 .0013 34.70 .0019 35.69 .0017 36.69 .0011 37.67 .0006 38.67 .0008 39.67 .0005 40.66 .0005 41.65 .0011 42.64 .0003 43.63 .0004 44.62 .0007 45.60 .0007 46.60 .0006 47.59 .0006 48.59 .0003 49.59 .0007 50.57 .0006 51.57 .0007 52.55 .0003 53.54 .0008 54.53 .0005 55.53 .0005 56.51 .0003 57.52 .0005 59.50 .0001 60.48 .0002 61.47 .0006 62.46 .0005 63.46 .0003 64.46 .0002 65.45 .0002)) (define sax-gs3 '( .98 .0781 1.97 .0393 2.96 .0842 3.94 .0434 4.93 .0378 5.91 .0141 6.89 .0201 7.87 .0294 8.86 .0169 9.85 .0124 10.84 .0137 11.81 .0238 12.80 .0172 13.78 .0094 14.77 .0040 15.76 .0036 16.74 .0061 17.72 .0032 18.70 .0035 19.69 .0086 20.68 .0065 21.66 .0097 22.65 .0036 23.63 .0010 24.62 .0006 25.61 .0018 26.59 .0026 27.58 .0023 28.56 .0017 29.54 .0010 30.52 .0012 31.50 .0018 32.50 .0021 33.48 .0025 34.46 .0010 35.45 .0028 36.42 .0018 37.41 .0009 38.41 .0007 39.38 .0006 40.37 .0004 41.36 .0005 42.34 .0007 43.31 .0001 44.29 .0002 45.29 .0006 46.28 .0005 47.26 .0005 48.25 .0006 49.22 .0006 50.21 .0003 51.20 .0007 52.18 .0004 53.16 .0003 54.15 .0004 55.14 .0001 56.10 .0001 57.11 .0005 58.09 .0007 59.07 .0005 59.22 .0001 61.04 .0004 63.02 .0002)) (define sax-a3 '( .99 .0950 1.97 .0374 2.95 .0738 3.94 .0772 4.93 .0103 5.92 .0135 6.90 .0099 7.88 .0088 8.88 .0151 9.86 .0150 10.84 .0177 11.83 .0121 12.82 .0071 13.81 .0049 14.79 .0025 15.77 .0046 16.77 .0023 17.75 .0020 18.73 .0079 19.71 .0057 20.70 .0068 21.69 .0036 22.67 .0007 23.65 .0003 24.65 .0006 25.64 .0016 26.62 .0013 27.60 .0006 28.59 .0005 29.59 .0005 30.56 .0013 31.55 .0015 32.53 .0013 33.52 .0009 34.51 .0016 35.48 .0002 36.47 .0007 37.46 .0002 38.46 .0003 39.43 .0002 40.42 .0003 41.40 .0006 42.40 .0006 43.39 .0002 44.36 .0009 45.35 .0008 46.34 .0010 47.32 .0003 48.30 .0009 49.29 .0006 50.28 .0002 51.27 .0004 52.25 .0002 54.23 .0003 55.21 .0001 56.19 .0002 58.17 .0002)) (define sax-as3 '( .99 .0856 1.98 .0365 2.97 .0409 3.96 .0666 4.94 .0192 5.94 .0263 6.92 .0311 7.91 .0175 8.90 .0203 9.89 .0358 10.87 .0214 11.87 .0177 12.85 .0068 13.84 .0071 14.83 .0068 15.82 .0040 16.80 .0040 17.80 .0126 18.78 .0101 19.77 .0086 20.75 .0053 21.75 .0012 22.73 .0026 23.73 .0019 24.71 .0018 25.71 .0026 26.68 .0023 27.68 .0022 28.66 .0015 29.66 .0031 30.64 .0008 31.63 .0023 32.61 .0029 33.61 .0007 34.59 .0016 35.59 .0009 36.57 .0006 37.56 .0012 38.54 .0004 39.53 .0005 40.52 .0007 41.52 .0006 42.50 .0009 43.50 .0015 44.48 .0005 45.47 .0012 46.46 .0007 47.45 .0003 48.44 .0007 49.41 .0003 50.41 .0003 51.40 .0011 52.39 .0007 53.37 .0005 54.36 .0005 55.34 .0002 56.34 .0002)) (define sax-b3 '( .99 .1015 1.99 .0817 2.98 .0315 3.98 .0386 4.97 .0424 5.96 .0104 6.96 .0144 7.94 .0361 8.94 .0182 9.93 .0238 10.93 .0139 11.93 .0063 12.91 .0058 13.91 .0071 14.91 .0051 15.89 .0035 16.90 .0114 17.88 .0097 18.88 .0081 19.87 .0043 20.86 .0014 21.86 .0009 22.85 .0012 23.86 .0006 24.84 .0013 25.83 .0006 26.83 .0010 27.82 .0015 28.80 .0008 29.80 .0012 30.80 .0017 31.77 .0002 32.78 .0016 33.78 .0006 34.77 .0003 35.77 .0009 36.76 .0006 37.75 .0011 38.75 .0006 39.74 .0011 40.74 .0011 41.73 .0006 42.72 .0015 43.72 .0008 44.70 .0002 45.71 .0005 46.70 .0004 47.69 .0003 48.69 .0005 49.67 .0005 50.64 .0001 51.66 .0003)) (define sax-c4 '( .99 .1462 1.98 .0760 2.98 .0464 3.97 .0292 4.95 .0393 5.95 .0117 6.94 .0150 7.93 .0251 8.93 .0238 9.92 .0182 10.90 .0142 11.89 .0100 12.89 .0108 13.88 .0029 14.87 .0060 15.86 .0116 16.85 .0066 17.84 .0072 18.84 .0034 19.83 .0010 20.82 .0013 21.81 .0015 22.80 .0012 23.80 .0011 24.79 .0004 25.77 .0027 26.76 .0021 27.75 .0018 28.75 .0013 29.74 .0015 30.73 .0008 31.72 .0004 32.71 .0007 33.71 .0011 34.70 .0002 35.68 .0010 36.67 .0002 37.66 .0003 38.67 .0010 39.66 .0008 40.64 .0019 41.64 .0005 42.62 .0010 43.62 .0003 45.60 .0005 46.59 .0002 47.59 .0002 48.58 .0002 49.57 .0002 50.55 .0001)) (define sax-cs4 '( .99 .0832 1.97 .0162 2.96 .0337 3.95 .0272 4.94 .0264 5.93 .0256 6.93 .0180 7.92 .0206 8.90 .0167 9.89 .0172 10.88 .0075 11.86 .0087 12.85 .0048 13.85 .0051 14.83 .0134 15.83 .0091 16.82 .0065 17.80 .0008 18.80 .0018 19.78 .0023 20.77 .0025 21.76 .0021 22.74 .0013 23.74 .0011 24.72 .0032 25.72 .0006 26.72 .0005 27.69 .0026 28.69 .0009 29.68 .0006 30.66 .0003 31.65 .0007 32.64 .0003 33.62 .0014 34.61 .0007 35.60 .0007 36.59 .0005 37.60 .0004 38.56 .0006 39.54 .0004 40.55 .0004 41.55 .0003 42.50 .0002 43.51 .0005 44.50 .0003 45.50 .0002 46.48 .0002 47.48 .0002)) (define sax-d4 '( .98 .0860 1.97 .0143 2.95 .0061 3.94 .0407 4.93 .0204 5.91 .0066 6.90 .0372 7.89 .0217 8.87 .0220 9.86 .0147 10.85 .0042 11.83 .0072 12.82 .0023 13.81 .0074 14.79 .0104 15.78 .0050 16.76 .0005 17.74 .0036 18.73 .0056 19.71 .0022 20.70 .0040 21.69 .0021 22.68 .0018 23.66 .0026 24.65 .0035 25.64 .0021 26.62 .0011 27.61 .0013 28.59 .0006 29.58 .0002 30.57 .0010 31.69 .0001 32.54 .0004 33.52 .0009 34.50 .0005 35.49 .0004 36.47 .0013 37.46 .0015 38.45 .0009 39.43 .0003 40.42 .0004 41.41 .0008 42.40 .0005 43.38 .0004 44.37 .0006)) (define sax-ds4 '( .98 .0870 1.97 .0204 2.96 .0184 3.94 .0494 4.92 .0500 5.91 .0163 6.90 .0267 7.88 .0158 8.86 .0159 9.85 .0095 10.84 .0095 11.82 .0039 12.81 .0053 13.79 .0074 14.78 .0054 15.77 .0004 16.75 .0027 17.73 .0034 18.71 .0035 19.70 .0019 20.69 .0028 21.67 .0032 22.65 .0016 23.64 .0018 24.63 .0033 25.61 .0006 26.59 .0015 27.58 .0005 28.57 .0010 29.56 .0006 30.54 .0010 31.52 .0009 32.51 .0004 33.50 .0012 34.47 .0006 35.46 .0009 36.45 .0007 37.44 .0002 38.42 .0006 39.41 .0003 40.38 .0003 41.38 .0005 42.36 .0003)) (define sax-e4 '( .99 .0111 1.97 .0520 2.96 .0287 3.94 .0704 4.93 .0240 5.91 .0286 6.89 .0516 7.89 .0184 8.87 .0076 9.86 .0113 10.84 .0049 11.83 .0044 12.81 .0111 13.79 .0080 14.78 .0008 15.76 .0031 16.76 .0042 17.74 .0016 18.73 .0021 19.71 .0010 20.69 .0048 21.68 .0014 22.66 .0020 23.66 .0016 24.64 .0011 25.62 .0011 26.61 .0001 27.59 .0011 28.58 .0013 29.56 .0011 30.55 .0004 31.54 .0015 32.52 .0023 33.51 .0015 34.49 .0004 35.48 .0003 36.46 .0007 37.45 .0003 38.43 .0003 39.42 .0009)) (define sax-f4 '( 1.00 .0896 2.00 .1802 3.00 .0636 4.00 .0344 5.01 .0214 6.01 .0196 7.01 .0241 8.01 .0118 9.01 .0057 10.01 .0060 11.01 .0059 12.01 .0032 13.02 .0055 14.02 .0023 15.01 .0020 16.02 .0027 17.02 .0022 18.02 .0017 19.02 .0015 20.02 .0020 21.03 .0014 22.03 .0010 23.02 .0006 24.03 .0007 25.03 .0005 27.03 .0006 28.03 .0005 29.04 .0003 30.04 .0009 31.03 .0006 32.04 .0003 33.04 .0002 34.04 .0003 35.04 .0001 36.04 .0002 37.05 .0003)) (define sax-fs4 '( .99 .0786 1.99 .1613 2.99 .0550 3.98 .0380 4.98 .0201 5.98 .0245 6.97 .0212 7.96 .0069 8.96 .0130 9.96 .0029 10.95 .0084 11.95 .0093 12.94 .0026 13.94 .0015 14.93 .0022 15.93 .0025 16.93 .0022 17.92 .0015 18.91 .0011 19.91 .0011 20.91 .0006 21.90 .0010 22.89 .0003 23.89 .0003 24.89 .0004 25.89 .0003 26.88 .0011 26.95 .0003 27.87 .0003 28.87 .0012 29.87 .0002 30.86 .0004 31.85 .0003 32.85 .0005 33.84 .0006 34.84 .0002 34.90 .0001)) (define sax-g4 '( 1.00 .0747 2.00 .1351 3.00 .0384 4.00 .0519 5.00 .0376 6.00 .0323 7.00 .0212 8.00 .0091 9.00 .0086 10.00 .0060 11.00 .0132 12.00 .0038 13.00 .0016 14.00 .0044 15.00 .0023 16.00 .0029 17.00 .0031 18.00 .0011 19.00 .0008 20.00 .0006 21.01 .0005 22.00 .0006 23.00 .0007 24.00 .0008 25.01 .0003 26.01 .0017 27.00 .0012 28.00 .0005 29.03 .0001 30.00 .0004 31.00 .0005 32.00 .0001 33.00 .0003 34.00 .0001)) (define sax-gs4 '( 1.00 .0671 1.99 .0676 2.98 .0664 3.97 .0207 4.97 .0170 5.96 .0406 6.96 .0157 7.95 .0093 8.94 .0032 9.93 .0117 10.93 .0059 11.93 .0034 12.92 .0052 13.91 .0036 14.90 .0010 15.89 .0023 16.89 .0019 17.89 .0011 18.88 .0013 19.87 .0009 20.86 .0005 21.86 .0006 22.86 .0011 23.85 .0006 24.85 .0008 25.83 .0010 26.83 .0010 27.82 .0007 28.80 .0002 29.82 .0006 31.80 .0001)) (define sax-a4 '( .99 .0707 1.99 .1376 2.99 .0767 3.98 .0191 4.98 .0316 5.97 .0241 6.97 .0070 7.97 .0095 8.96 .0085 9.96 .0109 10.96 .0012 11.95 .0047 12.94 .0051 13.94 .0022 14.93 .0020 15.93 .0007 16.93 .0016 17.92 .0014 18.92 .0008 19.92 .0005 20.91 .0008 21.91 .0005 22.91 .0002 23.90 .0008 24.89 .0015 25.89 .0004 26.89 .0003 27.88 .0002 28.88 .0002 29.88 .0002)) (define sax-as4 '( .99 .0652 1.98 .0768 2.97 .0399 3.96 .0314 4.95 .0539 5.94 .0282 6.93 .0048 7.93 .0059 8.91 .0163 9.90 .0039 10.89 .0052 11.88 .0086 12.87 .0025 13.86 .0011 14.85 .0069 15.84 .0006 16.84 .0018 17.82 .0008 18.80 .0004 19.81 .0004 20.78 .0002 21.79 .0010 22.78 .0038 23.76 .0018 24.75 .0010 25.74 .0002 26.73 .0005 27.72 .0006 28.71 .0003)) (define sax-b4 '( 1.00 .1365 1.99 .0773 2.98 .0370 3.97 .0399 4.97 .0441 5.96 .0193 6.95 .0055 7.95 .0036 8.94 .0106 9.93 .0050 10.93 .0075 11.92 .0047 12.91 .0013 13.90 .0034 14.90 .0024 15.89 .0018 16.89 .0005 17.87 .0006 18.87 .0014 19.87 .0011 20.86 .0017 21.84 .0018 22.84 .0007 23.83 .0003 24.82 .0006 25.83 .0002 26.81 .0002)) (define sax-c5 '( .99 .1197 1.98 .0661 2.97 .0448 3.96 .0398 4.96 .0311 5.95 .0167 6.93 .0068 7.93 .0249 8.92 .0065 9.91 .0104 10.90 .0081 11.89 .0032 12.88 .0060 13.87 .0037 14.86 .0020 15.86 .0008 16.84 .0005 17.84 .0025 18.83 .0010 19.81 .0020 20.81 .0017 21.80 .0013 22.79 .0016 23.78 .0009 24.77 .0006 25.76 .0002)) (define sax-cs5 '( .98 .0251 1.97 .0316 2.95 .0599 3.93 .0403 4.92 .0418 5.90 .0065 6.89 .0047 7.86 .0085 8.85 .0061 9.84 .0097 10.82 .0033 10.87 .0006 12.26 .0004 12.78 .0040 13.77 .0023 14.75 .0020 15.73 .0003 16.72 .0011 17.71 .0012 18.69 .0013 19.67 .0008 20.66 .0013 21.64 .0005 22.62 .0004 23.60 .0005)) (define sax-d5 '( .99 .0055 1.97 .0823 2.95 .0106 3.94 .0646 4.93 .0345 5.91 .0069 6.90 .0201 7.89 .0165 8.87 .0171 9.86 .0114 10.85 .0050 11.82 .0053 12.82 .0107 13.81 .0033 14.78 .0026 15.78 .0016 16.76 .0019 17.74 .0011 18.72 .0030 19.73 .0009 20.70 .0021 21.67 .0003 22.67 .0003 23.65 .0001)) (define sax-ds5 '( .98 .0699 1.97 .0761 2.95 .0777 3.93 .0573 4.92 .0236 5.90 .0082 6.88 .0195 7.87 .0108 8.85 .0205 9.83 .0042 10.82 .0112 11.80 .0039 12.78 .0018 13.77 .0027 14.75 .0017 15.73 .0015 16.72 .0019 17.70 .0047 18.68 .0011 19.67 .0020 20.65 .0027 21.63 .0002)) (define sax-e5 '( .99 .1082 1.99 .1222 2.99 .0874 3.98 .0436 4.98 .0208 5.98 .0141 6.97 .0193 7.97 .0172 8.97 .0118 9.96 .0082 10.96 .0133 11.96 .0062 12.95 .0058 13.95 .0013 14.94 .0017 15.94 .0029 16.94 .0032 17.93 .0006 18.93 .0028 19.92 .0004)) (define sax-f5 '( 1.00 .1462 2.00 .0665 3.01 .0741 4.01 .0382 5.01 .0262 6.02 .0172 7.02 .0168 8.02 .0172 9.02 .0087 10.02 .0145 11.03 .0046 12.03 .0033 13.03 .0032 14.03 .0030 15.03 .0040 16.04 .0059 17.04 .0026 18.04 .0005 19.05 .0009)) (define sax-fs5 '( 1.00 .0652 2.00 .0563 3.00 .0939 3.99 .0334 5.00 .0109 5.99 .0258 6.99 .0213 7.99 .0135 8.99 .0018 9.99 .0205 10.99 .0043 11.99 .0004 12.99 .0037 13.98 .0017 14.98 .0071 15.98 .0035 16.98 .0029 17.98 .0005)) (define sax-g5 '( 1.00 .0918 1.99 .0493 2.99 .0565 3.98 .0225 4.98 .0118 5.98 .0184 6.97 .0138 7.99 .0042 8.98 .0077 9.95 .0104 10.96 .0018 11.94 .0022 12.98 .0061 13.96 .0032 14.96 .0023 15.96 .0016 16.90 .0008)) (define sax-gs5 '( .99 .1447 1.98 .0908 2.97 .0522 3.96 .0607 4.96 .0316 5.95 .0115 6.94 .0147 7.93 .0148 8.92 .0221 9.91 .0097 10.90 .0087 11.90 .0078 12.89 .0127 13.88 .0042 14.87 .0007 15.86 .0012)) (define sax-a5 '( .97 .1089 1.94 .0491 4.85 .0162 5.82 .0156 6.78 .0130 7.75 .0174 8.72 .0104 8.75 .0087 8.77 .0024 8.80 .0019 8.82 .0014 9.72 .0010 10.66 .0033 11.63 .0092 11.66 .0045 12.59 .0028 12.65 .0015 12.67 .0011 13.64 .0007 14.56 .0017 14.59 .0017 14.61 .0010 14.62 .0008 14.64 .0005 15.50 .0003 15.53 .0002 15.56 .0002 15.58 .0001)) ;;; ;;; ;;; ;;; ;;; soprano sax? (define ssax-gs3 '( 1.01 .0846 2.02 .0851 3.03 .0782 4.03 .0250 5.04 .0513 6.05 .0121 7.07 .0065 8.08 .0409 9.09 .0134 10.09 .0032 11.10 .0168 12.12 .0076 13.13 .0054 14.13 .0091 15.14 .0078 16.15 .0029 17.16 .0103 18.18 .0103 19.18 .0071 20.19 .0105 21.20 .0063 22.20 .0054 23.21 .0011 24.22 .0008 25.24 .0003 26.23 .0001 27.26 .0002 28.25 .0006 29.27 .0004 30.29 .0008 31.29 .0004 32.31 .0002 33.32 .0003 34.32 .0003 35.33 .0001 36.34 .0002 37.35 .0005 38.36 .0003 39.37 .0003 40.37 .0002 41.39 .0002 42.40 .0002 43.41 .0002 44.43 .0001 45.43 .0007 46.43 .0004 47.44 .0002 48.46 .0001 49.48 .0001 50.48 .0002 51.49 .0002 52.49 .0002 53.50 .0002 54.51 .0002 55.53 .0003 56.54 .0003 57.54 .0002 58.55 .0002 59.55 .0001)) (define ssax-a3 '( .99 .1143 1.99 .0599 2.99 .0780 3.99 .0629 4.99 .0063 5.99 .0066 6.99 .0283 7.99 .0134 8.98 .0083 9.97 .0114 10.97 .0087 11.97 .0171 12.97 .0109 13.97 .0149 14.97 .0075 15.97 .0164 16.97 .0174 17.94 .0021 18.97 .0139 19.96 .0073 20.95 .0122 21.95 .0018 22.95 .0022 23.94 .0002 24.95 .0014 25.94 .0006 26.95 .0007 27.94 .0012 28.94 .0013 29.93 .0009 30.94 .0014 31.92 .0012 32.93 .0008 33.93 .0015 34.93 .0021 35.92 .0009 36.93 .0011 37.93 .0011 38.94 .0005 39.92 .0008 41.93 .0004 42.91 .0012 43.87 .0002 44.93 .0006 45.92 .0006 46.91 .0002 47.92 .0002 48.91 .0004 49.89 .0004 50.89 .0003 51.89 .0003 52.90 .0003 53.90 .0003 54.91 .0003 55.90 .0003 56.89 .0002)) (define ssax-as3 '( 1.00 .0772 1.99 .0797 2.98 .0350 3.99 .1086 4.98 .0418 5.97 .0170 6.98 .0247 7.97 .0288 8.96 .0041 9.95 .0047 10.95 .0120 11.95 .0176 12.93 .0128 13.95 .0151 14.94 .0162 15.92 .0152 16.93 .0077 17.93 .0111 18.92 .0092 19.91 .0079 20.91 .0053 21.89 .0009 22.90 .0008 24.88 .0004 25.88 .0009 26.88 .0009 27.87 .0014 28.87 .0008 29.87 .0023 30.87 .0013 31.85 .0012 32.87 .0015 33.85 .0011 34.85 .0024 35.84 .0021 36.86 .0024 37.87 .0008 38.82 .0007 39.85 .0009 40.79 .0007 41.83 .0009 42.84 .0007 43.84 .0006 44.82 .0001 46.83 .0004 47.83 .0003 48.81 .0003 49.82 .0002 50.82 .0001 51.82 .0002 52.81 .0002 54.81 .0004 55.80 .0002)) (define ssax-b3 '( .99 .0413 1.98 .0949 2.98 .0746 3.96 .0636 4.96 .0383 5.95 .0300 6.93 .0190 7.93 .0159 8.92 .0172 9.90 .0159 10.90 .0047 11.89 .0087 12.88 .0153 13.87 .0129 14.87 .0112 15.85 .0054 16.84 .0076 17.84 .0060 18.82 .0064 19.81 .0050 20.81 .0009 21.80 .0013 22.78 .0003 23.79 .0005 24.78 .0005 25.76 .0020 26.75 .0020 27.75 .0016 28.73 .0012 29.72 .0009 30.72 .0017 31.70 .0018 32.69 .0012 33.69 .0022 34.67 .0014 35.67 .0015 36.66 .0009 37.65 .0013 38.64 .0019 39.63 .0010 40.62 .0012 41.61 .0003 42.61 .0003 43.60 .0003 44.58 .0004 45.58 .0003 47.55 .0004 48.54 .0002 49.54 .0003 50.53 .0002 51.52 .0002)) (define ssax-c4 '( .99 .1251 1.98 .0932 2.97 .1614 3.97 .0801 4.96 .0100 5.94 .0183 6.94 .0221 7.93 .0060 8.92 .0055 9.91 .0162 10.90 .0171 11.89 .0181 12.88 .0135 13.88 .0102 14.87 .0071 15.86 .0066 16.84 .0071 17.83 .0057 18.83 .0027 19.82 .0006 20.82 .0008 21.80 .0003 22.78 .0007 23.78 .0011 24.77 .0019 25.77 .0010 26.76 .0016 27.74 .0008 28.74 .0013 29.73 .0025 30.72 .0019 31.71 .0029 32.70 .0022 33.69 .0011 34.68 .0014 35.68 .0010 36.67 .0014 37.65 .0007 38.64 .0005 39.62 .0001 40.63 .0004 41.62 .0006 42.61 .0005 43.60 .0003 44.58 .0003 45.58 .0003 46.58 .0006 47.57 .0003 48.56 .0002)) (define ssax-cs4 '( .98 .0809 1.97 .0745 2.96 .1141 3.95 .0537 4.95 .0028 5.92 .0112 6.93 .0029 7.90 .0117 8.89 .0101 9.89 .0091 10.87 .0113 11.86 .0048 12.85 .0076 13.84 .0054 14.82 .0089 15.81 .0068 16.80 .0065 17.79 .0031 18.77 .0009 19.76 .0007 20.75 .0005 21.73 .0010 22.72 .0016 23.71 .0009 24.70 .0016 25.68 .0010 26.68 .0018 27.66 .0018 28.65 .0009 29.64 .0012 30.63 .0017 31.61 .0016 32.60 .0008 33.59 .0012 34.58 .0014 35.57 .0005 36.56 .0006 37.54 .0008 38.53 .0005 39.52 .0004 40.50 .0004 41.49 .0001 42.47 .0004 43.46 .0002)) (define ssax-d4 '( .99 .0919 1.98 .0711 2.98 .0924 3.97 .0396 4.95 .0407 5.94 .0357 6.93 .0035 7.93 .0079 8.91 .0110 9.90 .0191 10.89 .0103 11.89 .0134 12.88 .0025 13.86 .0014 14.86 .0082 15.85 .0084 16.84 .0024 17.82 .0011 18.82 .0011 19.81 .0010 20.80 .0002 21.79 .0015 22.78 .0011 23.76 .0025 24.77 .0018 25.75 .0027 26.74 .0036 27.73 .0023 28.73 .0034 29.72 .0032 30.70 .0011 31.70 .0017 32.69 .0014 33.68 .0013 34.66 .0004 35.65 .0003 36.64 .0002 37.63 .0002 38.62 .0004 39.62 .0008 40.61 .0004 41.60 .0005 42.59 .0005 43.59 .0003 44.56 .0002)) (define ssax-ds4 '( .99 .0684 1.98 .0744 2.97 .1315 3.96 .0137 4.94 .0352 5.94 .0195 6.93 .0148 7.91 .0275 8.91 .0191 9.90 .0268 10.88 .0194 11.86 .0044 12.86 .0046 13.85 .0090 14.84 .0072 15.83 .0049 16.82 .0015 17.80 .0017 18.80 .0006 19.79 .0008 20.77 .0020 21.76 .0010 22.75 .0025 23.74 .0033 24.73 .0023 25.72 .0041 26.71 .0051 27.70 .0043 28.69 .0033 29.68 .0010 30.66 .0013 31.65 .0013 32.64 .0013 33.63 .0008 34.64 .0001 35.61 .0002 36.60 .0003 37.62 .0002 38.58 .0006 39.57 .0005 40.58 .0001 41.55 .0002)) (define ssax-e4 '( 1.00 .0363 1.98 .1101 2.98 .1009 3.96 .0168 4.95 .0610 5.95 .0099 6.94 .0066 7.93 .0157 8.92 .0162 9.91 .0154 10.90 .0131 11.89 .0061 12.88 .0029 13.87 .0058 14.86 .0040 15.85 .0015 16.84 .0012 17.84 .0005 18.82 .0005 19.81 .0008 20.85 .0007 21.80 .0005 22.78 .0016 23.77 .0017 24.76 .0022 25.76 .0010 26.80 .0006 27.74 .0012 28.72 .0007 29.71 .0004 30.70 .0004 31.69 .0001 32.68 .0001 33.67 .0003 34.65 .0004 35.65 .0003 36.64 .0003 37.63 .0002 38.61 .0002)) (define ssax-f4 '( 1.00 .0607 1.99 .1291 3.00 .0576 3.99 .0530 4.99 .0330 5.98 .0364 6.98 .0116 7.98 .0252 8.97 .0175 9.97 .0166 10.97 .0147 11.97 .0096 12.96 .0060 13.96 .0022 14.95 .0018 15.95 .0018 16.96 .0003 17.94 .0012 18.94 .0021 19.94 .0051 20.94 .0018 21.93 .0034 22.93 .0038 23.93 .0035 24.92 .0041 25.92 .0015 26.91 .0024 27.92 .0019 28.92 .0008 29.91 .0005 30.92 .0003 31.91 .0005 32.91 .0006 33.90 .0003 34.89 .0002 35.89 .0005 36.89 .0002)) (define ssax-fs4 '( .99 .0502 1.98 .0678 2.96 .0319 3.95 .0589 4.93 .0093 5.93 .0072 6.91 .0063 7.89 .0224 8.88 .0185 9.87 .0096 10.86 .0046 11.84 .0060 12.83 .0052 13.82 .0008 14.80 .0022 15.79 .0009 16.79 .0008 17.76 .0011 18.75 .0024 19.74 .0013 20.71 .0009 21.71 .0038 22.70 .0037 23.68 .0023 24.66 .0010 25.66 .0007 26.64 .0009 27.64 .0007 28.61 .0002 29.61 .0006 30.60 .0004 31.58 .0008 32.56 .0004 33.55 .0005 35.53 .0002)) (define ssax-g4 '( 1.00 .0253 1.99 .0803 2.98 .0107 3.97 .0688 4.96 .0361 5.96 .0208 6.96 .0172 7.95 .0172 8.94 .0189 9.93 .0080 10.92 .0114 11.92 .0059 12.91 .0058 13.90 .0007 14.89 .0011 15.89 .0011 16.88 .0023 17.87 .0046 18.87 .0024 19.85 .0043 20.86 .0087 21.83 .0023 22.84 .0043 23.84 .0039 24.83 .0020 25.81 .0017 26.81 .0009 27.82 .0006 28.80 .0004 29.79 .0007 30.80 .0005 31.78 .0011 32.78 .0004 33.76 .0001)) (define ssax-gs4 '( 1.00 .0453 2.00 .1198 2.99 .0370 3.99 .1319 4.98 .0327 5.97 .0018 6.98 .0199 7.97 .0362 8.97 .0196 9.96 .0065 10.96 .0061 11.96 .0025 12.95 .0026 13.95 .0010 14.94 .0005 15.94 .0027 16.94 .0031 17.93 .0037 18.92 .0019 19.92 .0034 20.92 .0087 21.92 .0034 22.91 .0029 23.91 .0024 24.90 .0006 25.90 .0002 26.90 .0009 27.90 .0003 28.90 .0015 29.89 .0011 30.89 .0004 31.88 .0001)) (define ssax-a4 '( 1.00 .0568 1.99 .1275 2.98 .0496 3.98 .0504 4.97 .0277 5.96 .0064 6.95 .0205 7.95 .0244 8.94 .0067 9.93 .0133 10.92 .0045 11.92 .0035 12.91 .0028 13.90 .0010 14.90 .0011 15.89 .0035 16.89 .0034 17.88 .0037 18.87 .0052 19.86 .0027 20.86 .0028 21.86 .0003 22.84 .0011 23.84 .0005 24.83 .0010 25.82 .0005 26.81 .0003 27.81 .0007 28.80 .0005 29.79 .0004)) (define ssax-as4 '( .99 .0497 1.98 .0814 2.97 .0351 3.96 .0207 4.95 .0068 5.93 .0241 6.92 .0219 7.91 .0187 8.90 .0053 9.88 .0026 10.88 .0026 11.87 .0027 12.85 .0011 13.85 .0018 14.84 .0029 15.84 .0013 16.83 .0014 17.81 .0036 18.80 .0042 19.79 .0015 20.78 .0021 21.77 .0018 22.76 .0011 23.75 .0004 24.66 .0003 25.73 .0006 26.72 .0005 27.71 .0002)) (define ssax-b4 '( .99 .0161 1.98 .0825 2.96 .0846 3.95 .0304 4.94 .0112 5.93 .0158 6.91 .0362 7.90 .0085 8.89 .0147 9.87 .0047 10.85 .0016 11.85 .0044 12.84 .0024 13.83 .0044 14.82 .0015 15.80 .0066 16.79 .0061 17.78 .0135 18.77 .0107 19.75 .0020 20.75 .0008 21.73 .0010 22.71 .0014 23.70 .0007 24.69 .0009 25.68 .0008 26.67 .0002)) (define ssax-c5 '( 1.00 .1378 1.99 .1932 2.99 .0181 3.98 .0213 4.97 .0472 5.97 .0302 6.97 .0099 7.96 .0039 8.96 .0052 9.95 .0031 10.95 .0007 11.94 .0010 12.93 .0015 13.93 .0009 14.93 .0013 15.92 .0018 16.92 .0015 17.91 .0030 18.91 .0013 19.90 .0008 20.90 .0008 21.89 .0006 22.89 .0006 23.89 .0003)) (define ssax-cs5 '( .99 .1332 1.97 .2232 2.96 .1240 3.95 .0080 4.94 .0398 5.93 .0194 6.92 .0059 7.90 .0022 8.91 .0008 9.88 .0017 10.87 .0005 11.85 .0004 12.84 .0008 13.83 .0009 14.82 .0032 15.81 .0009 16.81 .0017 17.78 .0009 18.77 .0003 19.76 .0002 20.75 .0006 21.74 .0004 22.73 .0002)) (define ssax-d5 '( .99 .1242 1.98 .0414 2.97 .0487 3.96 .0182 4.95 .0225 5.94 .0112 6.93 .0012 7.92 .0035 8.87 .0004 9.90 .0011 10.89 .0006 11.88 .0004 12.81 .0008 13.87 .0011 14.86 .0015 15.84 .0005 16.83 .0002 17.82 .0005 18.46 .0002 19.82 .0002 20.81 .0002 21.66 .0001)) (define ssax-ds5 '( .99 .1419 1.98 .0180 2.98 .0683 3.96 .0172 4.95 .0329 5.94 .0093 6.93 .0017 7.91 .0014 8.91 .0022 9.90 .0018 10.88 .0004 11.89 .0011 12.88 .0009 13.87 .0010 14.83 .0007 15.85 .0004 16.85 .0002 17.85 .0003 18.85 .0003 20.81 .0001)) (define ssax-e5 '( 1.00 .2435 1.99 .0422 2.99 .0422 3.98 .0137 4.97 .0155 5.97 .0127 6.96 .0024 7.96 .0014 8.95 .0017 9.95 .0011 10.94 .0006 11.94 .0009 12.93 .0022 13.92 .0048 14.92 .0004 15.91 .0006 16.91 .0003 17.90 .0002 18.89 .0002 19.89 .0002)) (define ssax-f5 '( 1.00 .2095 2.00 .0502 3.01 .0783 4.01 .0216 5.01 .0293 6.01 .0080 7.01 .0043 8.02 .0036 9.02 .0019 10.02 .0002 11.02 .0013 12.02 .0010 13.02 .0007 14.03 .0010 15.03 .0003 16.03 .0013 17.04 .0009 18.04 .0005)) (define ssax-fs5 '( .99 .1379 1.98 .0339 2.98 .0480 3.97 .0340 4.96 .0264 5.95 .0126 6.94 .0046 7.93 .0030 8.92 .0013 9.91 .0010 10.90 .0009 11.89 .0007 12.88 .0007 13.88 .0018 14.87 .0012 15.86 .0006 16.85 .0004 17.84 .0007)) (define ssax-g5 '( .99 .0699 1.98 .0273 2.96 .0227 3.95 .0133 4.94 .0151 5.92 .0023 6.92 .0024 7.91 .0011 8.90 .0009 9.89 .0018 10.87 .0009 11.88 .0016 12.86 .0007 13.84 .0008 14.83 .0007 15.82 .0005 16.81 .0003)) (define ssax-gs5 '( 1.00 .1830 1.99 .0897 2.99 .0456 3.99 .0296 4.99 .0125 5.98 .0059 6.98 .0105 7.98 .0027 8.97 .0044 9.97 .0096 10.97 .0011 11.97 .0027 12.97 .0006 13.97 .0024 14.96 .0014 15.95 .0002)) (define ssax-a5 '( .99 .2010 1.98 .0677 2.97 .0195 3.97 .0363 4.96 .0191 5.95 .0092 6.94 .0047 7.93 .0021 7.96 .0004 8.91 .0004 9.92 .0039 10.90 .0023 11.91 .0005 12.88 .0008 12.91 .0002 13.86 .0002 14.87 .0007)) (define ssax-as5 '( 1.00 .1011 1.99 .0696 2.99 .0359 3.98 .0008 4.99 .0111 5.98 .0027 6.98 .0005 7.98 .0038 8.98 .0032 9.98 .0037 10.97 .0024 11.97 .0012 12.97 .0009 13.97 .0004)) (define ssax-b5 '( .98 .0933 1.95 .0632 2.93 .0226 4.89 .0036 5.86 .0133 6.84 .0018 7.82 .0036 8.79 .0037 9.77 .0111 10.75 .0011 11.72 .0009 12.70 .0013)) (define ssax-c6 '( 1.01 .0218 1.98 .0033 3.00 .0037 3.99 .0010 4.03 .0009 4.77 .0002 4.95 .0002 6.01 .0001 7.00 .0002 8.02 .0004 9.03 .0004 10.03 .0003 12.03 .0001)) (define ssax-cs6 '( .99 .1143 1.99 .0478 2.99 .0259 3.97 .0101 4.97 .0058 5.96 .0010 6.95 .0012 7.98 .0017 8.95 .0024 8.98 .0016 9.96 .0007 10.93 .0019 10.96 .0010 11.90 .0003 11.95 .0002)) (define ssax-d6 '( 1.01 .0247 2.02 .0062 3.02 .0036 4.03 .0052 5.05 .0006 6.07 .0004 7.06 .0013 8.07 .0027 11.11 .0001)) ;;; ;;; ;;; ;;; ;;; (define tbf-e2 '( 1.01 .0028 2.00 .0192 3.04 .0188 4.02 .0134 5.02 .0319 6.05 .0335 7.04 .0136 8.06 .0074 9.07 .0527 10.06 .0217 11.05 .0025 12.09 .0068 13.08 .0278 14.10 .0125 15.09 .0152 16.13 .0101 17.13 .0088 18.11 .0094 19.14 .0084 20.20 .0008 21.13 .0031 22.16 .0097 23.14 .0053 24.17 .0030 25.20 .0013 26.17 .0055 27.20 .0049 28.19 .0040 29.21 .0010 30.21 .0030 31.20 .0032 32.24 .0031 33.21 .0006 34.23 .0015 35.25 .0020 36.23 .0012 37.25 .0010 38.29 .0007 39.26 .0017 40.29 .0014 41.27 .0015 42.29 .0005 43.32 .0012 44.30 .0014 45.32 .0010 46.32 .0005 47.31 .0003 48.34 .0009 49.32 .0005 50.34 .0005 51.35 .0001 52.35 .0005 53.37 .0006 54.37 .0006 55.38 .0001 56.38 .0002 57.39 .0006 58.41 .0005 59.42 .0004 60.42 .0001 61.43 .0004 62.41 .0004 63.42 .0003 64.45 .0002 65.46 .0001 66.45 .0003 67.48 .0003 68.46 .0001 69.50 .0001 70.49 .0004 71.48 .0002 72.47 .0001 74.52 .0002 75.51 .0002 76.51 .0002 79.55 .0002 80.56 .0002 81.55 .0001 83.58 .0002 84.57 .0001 85.59 .0002 87.60 .0002 88.59 .0001 89.61 .0002 92.62 .0001 93.64 .0001 96.67 .0001 98.69 .0001)) (define tbf-f2 '( .99 .0062 2.00 .0189 3.01 .0059 4.03 .0167 5.01 .0454 6.01 .0190 7.03 .0261 8.04 .0495 9.04 .0195 10.01 .0059 11.02 .0030 12.05 .0247 13.04 .0097 14.05 .0122 15.04 .0076 16.03 .0044 17.05 .0063 18.06 .0045 19.06 .0011 20.05 .0028 21.07 .0056 22.07 .0019 22.55 .0004 23.17 .0001 24.07 .0026 25.08 .0016 26.10 .0017 27.11 .0006 28.09 .0011 29.10 .0014 30.10 .0011 31.13 .0007 32.12 .0006 33.11 .0009 34.10 .0004 35.15 .0002 36.15 .0004 37.13 .0006 38.11 .0004 39.11 .0002 40.15 .0003 41.13 .0004 42.13 .0003 43.17 .0002 44.20 .0002 45.16 .0002 46.18 .0003 48.16 .0001 49.20 .0002 50.20 .0002 51.21 .0001 54.20 .0001)) (define tbf-fs2 '( 1.02 .0056 2.01 .0355 3.01 .0221 3.99 .0130 4.99 .0606 6.00 .0189 7.01 .0127 8.02 .0612 9.01 .0211 10.01 .0079 10.99 .0134 11.99 .0205 13.00 .0282 14.03 .0114 15.02 .0079 16.01 .0116 17.00 .0082 18.02 .0015 19.00 .0052 20.03 .0082 21.03 .0057 22.05 .0011 23.02 .0048 24.01 .0035 25.01 .0032 26.02 .0012 27.04 .0033 28.01 .0015 29.03 .0013 30.05 .0008 31.03 .0024 32.02 .0010 33.02 .0007 34.05 .0007 35.05 .0013 36.04 .0008 37.03 .0004 38.02 .0004 39.03 .0008 40.03 .0005 42.07 .0005 43.05 .0006 44.05 .0003 45.10 .0002 46.05 .0003 47.05 .0003 48.05 .0002 50.08 .0003 51.07 .0003 52.06 .0002 53.09 .0001 54.00 .0001 55.06 .0002 56.09 .0002 57.10 .0001 58.08 .0001 59.05 .0001 60.09 .0001 62.09 .0001 63.06 .0001 66.13 .0001)) (define tbf-g2 '( .99 .0059 1.98 .0515 2.98 .0305 3.98 .0081 4.97 .0448 5.98 .0160 6.97 .0397 7.97 .0418 8.93 .0079 9.96 .0086 10.95 .0358 11.96 .0207 12.94 .0116 13.94 .0070 14.93 .0156 15.94 .0120 16.98 .0013 17.94 .0060 18.91 .0074 19.94 .0070 20.94 .0013 21.92 .0060 22.91 .0043 23.89 .0014 24.95 .0017 25.91 .0031 26.90 .0022 27.90 .0009 28.91 .0017 29.89 .0016 30.88 .0012 31.86 .0004 32.88 .0013 33.89 .0008 34.85 .0005 35.83 .0005 36.85 .0008 37.87 .0006 38.87 .0001 39.86 .0004 40.90 .0008 41.86 .0005 42.88 .0003 43.86 .0005 44.84 .0005 45.89 .0003 46.92 .0002 47.86 .0003 48.77 .0002 49.85 .0002 50.86 .0002 51.81 .0003 52.88 .0001 53.87 .0001 54.80 .0002 55.77 .0001 56.88 .0002 58.76 .0001 59.82 .0001 62.83 .0001 63.88 .0001 73.81 .0001)) (define tbf-gs2 '( .99 .0058 1.98 .0327 2.99 .0282 3.99 .0353 4.98 .0348 5.96 .0451 6.97 .0549 7.97 .0183 8.96 .0096 9.94 .0221 10.94 .0110 11.93 .0102 12.92 .0074 13.92 .0109 14.91 .0080 15.15 .0013 15.91 .0003 16.90 .0034 17.88 .0030 18.88 .0036 19.14 .0004 20.05 .0003 20.86 .0029 21.87 .0014 22.84 .0008 23.85 .0021 24.83 .0011 25.81 .0007 26.80 .0003 27.81 .0010 28.82 .0003 29.84 .0003 30.77 .0006 31.75 .0002 32.78 .0005 33.79 .0003 34.77 .0003 35.78 .0003 37.75 .0002 38.72 .0002 41.75 .0001 42.73 .0001 45.69 .0001)) (define tbf-a2 '( 1.00 .0085 1.99 .0291 2.99 .0151 4.00 .0554 5.00 .0164 6.02 .0087 7.00 .0365 8.06 .0023 9.02 .0098 9.98 .0165 10.97 .0176 11.97 .0107 12.98 .0081 13.97 .0077 14.97 .0012 15.99 .0038 16.98 .0028 17.97 .0017 18.97 .0024 19.98 .0014 20.95 .0017 21.92 .0009 23.01 .0009 23.98 .0006 24.94 .0004 25.95 .0013 26.95 .0003 27.99 .0002 28.97 .0006 29.96 .0002 30.90 .0003 31.89 .0003 32.83 .0002 33.02 .0001 33.78 .0001 34.94 .0001 35.94 .0002 38.91 .0002 39.88 .0001)) (define tbf-as2 '( 1.00 .0251 2.05 .0009 3.02 .0385 4.03 .0997 5.03 .0337 6.04 .1061 7.04 .0539 8.05 .0357 9.06 .0635 10.06 .0233 11.05 .0153 12.07 .0218 13.07 .0235 14.08 .0092 15.08 .0135 16.09 .0104 17.09 .0055 18.10 .0130 19.11 .0059 20.12 .0030 21.12 .0060 22.12 .0029 23.12 .0032 24.13 .0022 25.14 .0016 26.14 .0007 27.15 .0032 28.15 .0014 29.16 .0012 30.15 .0015 31.18 .0011 32.19 .0008 33.18 .0014 34.19 .0007 35.19 .0003 36.18 .0009 37.16 .0004 39.21 .0007 40.22 .0006 41.23 .0001 42.20 .0004 43.24 .0007 45.25 .0007 46.26 .0004 47.32 .0001 48.26 .0004 49.26 .0003 51.29 .0003 52.28 .0002 54.30 .0003 55.32 .0002 57.31 .0002 58.32 .0001 60.31 .0002 61.30 .0001 63.35 .0001 64.34 .0001 66.37 .0001)) (define tbf-b2 '( 1.02 .0294 2.03 .0276 3.03 .0170 4.05 .0409 5.06 .0434 6.06 .0552 7.06 .0128 8.08 .0076 9.07 .0216 10.08 .0169 11.07 .0035 12.09 .0094 13.10 .0046 14.12 .0021 15.12 .0059 16.13 .0023 17.15 .0039 18.16 .0035 19.17 .0015 20.18 .0020 21.19 .0023 22.19 .0005 23.22 .0022 24.24 .0010 25.27 .0006 26.26 .0008 27.27 .0010 28.28 .0003 29.28 .0006 30.27 .0005 31.32 .0003 32.30 .0004 33.29 .0004 35.37 .0004 36.34 .0002 37.38 .0002 38.38 .0003 39.48 .0002 41.43 .0003 42.40 .0001 44.50 .0001 45.47 .0001 47.46 .0001)) (define tbf-c3 '( 1.01 .0167 2.00 .0116 3.00 .0033 3.99 .0432 5.01 .0116 6.00 .0573 7.00 .0128 8.00 .0582 9.02 .0354 10.01 .0203 11.00 .0226 12.00 .0167 13.03 .0055 14.02 .0174 15.01 .0088 16.01 .0083 17.03 .0066 18.03 .0022 19.01 .0058 20.01 .0049 21.03 .0016 22.03 .0053 23.03 .0028 24.01 .0013 25.03 .0028 26.03 .0015 27.00 .0003 28.02 .0026 28.39 .0002 29.70 .0002 30.03 .0014 31.03 .0010 32.04 .0007 33.03 .0010 34.03 .0007 35.04 .0004 36.03 .0009 37.03 .0004 38.05 .0006 39.04 .0008 40.03 .0003 41.04 .0004 42.04 .0005 43.06 .0003 44.02 .0004 45.03 .0002 46.08 .0001 47.05 .0004 48.03 .0002 49.06 .0001 50.05 .0003 51.06 .0002 52.07 .0002 53.04 .0002 54.05 .0001 55.05 .0002 56.05 .0001 58.05 .0002 59.06 .0001 61.05 .0002)) (define tbf-cs3 '( 1.00 .0192 1.98 .0300 2.99 .0565 3.98 .0329 4.97 .0791 5.98 .0457 6.96 .0053 7.95 .0405 8.96 .0260 9.95 .0146 10.93 .0283 11.95 .0038 12.93 .0205 13.92 .0086 14.93 .0028 15.91 .0069 16.91 .0030 17.91 .0095 18.89 .0058 19.90 .0023 20.89 .0048 21.87 .0015 22.89 .0033 23.88 .0021 24.87 .0003 25.87 .0030 26.86 .0014 27.85 .0016 28.86 .0021 29.85 .0005 30.83 .0019 31.84 .0014 32.83 .0005 33.82 .0012 34.82 .0006 35.81 .0008 36.82 .0011 37.81 .0004 38.78 .0004 39.80 .0005 40.79 .0004 41.77 .0007 42.77 .0002 43.78 .0004 44.76 .0005 45.77 .0003 46.76 .0003 47.75 .0002 48.75 .0002 49.75 .0005 50.74 .0002 51.73 .0002 52.73 .0002 53.72 .0002 54.73 .0003 55.70 .0001 56.70 .0001 57.71 .0003 58.71 .0001 59.70 .0002 60.70 .0001 61.69 .0002 62.69 .0003 64.67 .0001 65.67 .0001 67.64 .0001 69.65 .0001 70.63 .0001 75.62 .0001)) (define tbf-d3 '( 1.01 .0462 2.01 .0592 3.00 .1127 3.99 .0398 5.00 .1221 6.02 .0099 7.01 .0396 8.01 .0429 9.00 .0249 10.00 .0223 10.27 .0015 11.03 .0010 12.01 .0146 13.01 .0097 14.00 .0008 15.00 .0064 16.01 .0020 17.02 .0066 18.02 .0043 19.02 .0021 20.01 .0035 21.02 .0009 22.02 .0022 23.03 .0022 24.00 .0007 25.02 .0025 26.02 .0002 27.03 .0017 27.30 .0003 28.73 .0002 29.03 .0016 30.02 .0012 31.02 .0006 32.04 .0013 33.04 .0005 34.02 .0006 35.01 .0004 36.03 .0007 37.03 .0009 38.05 .0003 39.05 .0006 40.04 .0003 41.04 .0003 42.04 .0005 43.05 .0002 44.06 .0003 45.05 .0001 46.05 .0002 47.04 .0003 48.06 .0002 49.06 .0003 50.06 .0001 51.06 .0001 52.04 .0001 53.06 .0001 54.06 .0002 57.06 .0001 58.07 .0001 59.06 .0002 66.09 .0001)) (define tbf-ds3 '( 1.00 .0462 2.01 .0546 3.03 .1220 4.04 .0672 5.06 .0575 6.07 .0310 7.08 .0402 8.09 .0228 9.09 .0345 10.10 .0204 11.11 .0134 12.12 .0171 13.13 .0056 14.15 .0087 15.16 .0035 16.17 .0068 17.18 .0027 18.18 .0061 19.20 .0018 20.20 .0037 21.22 .0030 22.24 .0013 23.24 .0028 23.58 .0004 24.91 .0002 25.26 .0031 26.26 .0008 27.27 .0022 28.28 .0021 29.29 .0013 30.31 .0017 31.31 .0006 32.34 .0015 33.34 .0008 34.35 .0012 35.36 .0012 36.36 .0008 37.37 .0012 38.38 .0006 39.40 .0008 40.39 .0002 41.43 .0004 42.44 .0003 43.45 .0004 44.45 .0004 45.45 .0004 46.46 .0006 47.46 .0002 48.48 .0004 49.47 .0002 50.52 .0003 51.52 .0002 52.53 .0003 53.53 .0003 54.54 .0002 55.55 .0003 57.58 .0002 58.58 .0001 59.60 .0002 60.60 .0002 61.62 .0002 62.63 .0002 63.62 .0001 64.64 .0002 66.67 .0001 68.68 .0001 69.70 .0001 71.70 .0001)) (define tbf-e3 '( 1.00 .0427 2.02 .0329 3.03 .0739 4.03 .0442 5.05 .0547 6.06 .0547 7.06 .0357 8.07 .0307 9.09 .0344 10.10 .0088 11.10 .0255 12.12 .0049 13.13 .0161 14.13 .0032 15.14 .0087 16.16 .0028 17.15 .0054 18.17 .0018 19.18 .0048 20.20 .0025 21.19 .0033 22.21 .0032 23.22 .0009 24.22 .0017 25.25 .0004 26.24 .0011 26.54 .0002 27.27 .0002 28.26 .0012 28.54 .0002 29.26 .0001 30.29 .0009 31.29 .0003 32.30 .0007 33.32 .0005 34.32 .0007 35.32 .0005 36.35 .0004 37.36 .0004 38.38 .0002 39.37 .0004 41.39 .0004 42.42 .0001 43.40 .0002 45.43 .0002 47.45 .0002 48.45 .0001 49.46 .0001 50.48 .0002 51.49 .0001 52.49 .0001 54.52 .0001 56.54 .0001)) (define tbf-f3 '( 1.01 .0430 2.02 .0658 3.02 .0533 4.02 .1351 5.04 .0653 6.03 .0900 7.05 .0410 8.05 .0344 9.07 .0169 10.07 .0220 11.08 .0159 12.08 .0180 13.08 .0045 14.09 .0098 15.08 .0023 16.10 .0022 17.12 .0040 18.12 .0030 19.13 .0031 20.14 .0014 21.14 .0019 22.15 .0012 23.16 .0015 24.16 .0007 25.16 .0010 26.17 .0009 27.19 .0009 28.19 .0004 29.20 .0009 30.19 .0002 31.21 .0007 32.23 .0003 33.23 .0005 35.24 .0004 36.33 .0001 37.25 .0003 38.26 .0002 39.27 .0003 41.29 .0002 42.29 .0001 43.30 .0002 45.31 .0001 46.33 .0001)) (define tbf-fs3 '( 1.00 .0676 1.99 .0337 3.00 .0651 4.00 .0928 4.99 .0773 6.00 .0359 6.99 .0266 7.99 .0183 9.00 .0246 9.99 .0092 10.98 .0144 11.99 .0027 12.98 .0112 13.98 .0019 14.99 .0058 15.97 .0010 16.97 .0024 17.98 .0033 18.97 .0025 19.97 .0024 20.98 .0018 21.97 .0030 22.98 .0013 23.97 .0026 24.19 .0004 24.97 .0003 25.97 .0026 26.96 .0003 27.96 .0018 28.97 .0006 29.96 .0012 30.96 .0012 31.97 .0011 32.96 .0012 33.95 .0006 34.96 .0008 35.95 .0003 36.95 .0009 37.95 .0002 38.95 .0005 39.95 .0002 40.95 .0005 41.95 .0003 42.95 .0005 43.95 .0002 44.94 .0003 45.95 .0003 46.94 .0001 47.94 .0002 49.94 .0003 50.94 .0001 51.94 .0003 53.93 .0002 55.93 .0002 56.93 .0001 57.93 .0002 58.93 .0001 59.93 .0001 60.93 .0001 62.93 .0001 64.91 .0001)) (define tbf-g3 '( 1.01 .1108 2.02 .0159 3.03 .0749 4.03 .0774 5.05 .0554 6.06 .0287 7.06 .0529 8.08 .0167 9.09 .0172 10.09 .0181 11.10 .0072 12.12 .0148 13.11 .0028 14.13 .0060 15.14 .0012 16.14 .0047 17.15 .0034 18.17 .0009 19.17 .0041 20.18 .0007 21.20 .0016 22.20 .0011 23.21 .0022 24.23 .0010 25.24 .0008 26.24 .0015 27.25 .0003 28.26 .0011 29.26 .0009 30.28 .0009 31.29 .0007 32.29 .0002 33.31 .0005 34.32 .0001 35.32 .0006 36.33 .0002 37.35 .0003 38.34 .0004 40.37 .0003 42.39 .0002 43.40 .0002 44.40 .0001 45.41 .0002 47.44 .0002 50.47 .0001 52.48 .0001 54.49 .0001)) (define tbf-gs3 '( 1.01 .0962 2.01 .0925 3.01 .0770 4.03 .0479 5.03 .1190 6.03 .0237 7.03 .0168 8.05 .0283 9.05 .0100 10.05 .0292 11.06 .0097 12.07 .0103 13.07 .0121 14.07 .0042 15.08 .0012 16.09 .0051 17.09 .0023 18.09 .0058 19.11 .0009 20.11 .0029 21.11 .0028 22.12 .0011 23.13 .0028 24.12 .0013 25.13 .0016 26.14 .0014 27.14 .0009 28.15 .0016 29.16 .0007 30.16 .0007 31.16 .0010 32.17 .0004 33.18 .0006 34.18 .0005 35.18 .0003 36.19 .0006 37.20 .0003 38.20 .0003 39.21 .0004 40.22 .0002 41.22 .0004 42.23 .0001 43.23 .0002 44.24 .0002 46.25 .0003 47.25 .0001 48.26 .0002 49.26 .0001 51.28 .0001 54.29 .0001)) (define tbf-a3 '( .99 .0880 1.99 .1784 2.99 .0966 3.99 .0789 4.99 .0440 5.99 .0574 6.99 .0067 7.99 .0384 8.98 .0270 9.98 .0089 10.97 .0152 11.97 .0039 12.97 .0092 13.97 .0081 14.97 .0020 15.97 .0030 16.96 .0051 17.96 .0014 18.96 .0031 19.96 .0026 20.95 .0004 21.95 .0028 22.95 .0006 23.94 .0012 24.94 .0021 25.94 .0009 26.94 .0010 27.94 .0010 28.94 .0006 29.94 .0008 30.93 .0009 31.93 .0001 32.92 .0007 33.92 .0005 34.91 .0002 35.92 .0005 36.91 .0003 37.92 .0002 38.92 .0004 40.91 .0002 41.90 .0002 43.89 .0002 44.89 .0002 46.89 .0001 49.89 .0001 52.88 .0001)) (define tbf-as3 '( 1.00 .0084 2.02 .2204 3.02 .1914 4.03 .0999 5.03 .0302 6.04 .0574 7.04 .0432 8.05 .0168 9.05 .0414 10.06 .0213 11.06 .0024 12.07 .0063 13.08 .0058 14.08 .0014 15.09 .0031 16.09 .0067 17.10 .0026 18.10 .0026 19.11 .0039 20.11 .0016 21.12 .0015 22.12 .0032 23.13 .0017 24.13 .0010 25.14 .0020 26.14 .0016 27.15 .0002 28.16 .0013 29.16 .0009 31.17 .0009 32.18 .0008 33.18 .0004 34.19 .0005 35.19 .0008 36.20 .0002 37.20 .0004 38.21 .0005 39.21 .0002 40.22 .0002 41.22 .0003 42.23 .0002 43.23 .0001 44.24 .0002 45.25 .0001 47.26 .0002 48.26 .0001 50.28 .0001 51.28 .0001)) (define tbf-b3 '( 1.00 .0475 2.00 .1146 3.01 .1513 4.01 .0759 5.00 .0441 6.01 .0348 7.01 .0462 8.01 .0291 9.02 .0056 10.02 .0281 11.01 .0178 12.02 .0016 13.02 .0054 14.02 .0082 15.03 .0051 16.02 .0014 17.02 .0053 18.03 .0050 19.03 .0017 20.03 .0024 21.04 .0037 22.03 .0025 23.03 .0008 24.04 .0028 25.04 .0023 26.04 .0007 27.04 .0007 28.04 .0018 29.04 .0017 30.05 .0003 31.04 .0011 32.04 .0013 33.05 .0004 34.05 .0005 35.05 .0009 36.06 .0007 37.05 .0002 38.06 .0004 39.06 .0006 40.06 .0004 41.07 .0003 42.06 .0005 43.06 .0004 44.07 .0001 45.07 .0003 46.07 .0003 47.08 .0001 48.07 .0001 49.07 .0003 50.08 .0002 52.08 .0001 53.08 .0001)) (define tbf-c4 '( 1.01 .0092 2.01 .0918 3.01 .1218 4.03 .1524 5.03 .0561 6.03 .0196 7.05 .0312 8.05 .0481 9.05 .0292 10.07 .0048 11.07 .0035 12.07 .0096 13.08 .0079 14.09 .0040 15.09 .0017 16.09 .0054 17.11 .0080 18.11 .0039 19.11 .0010 20.13 .0034 21.13 .0028 22.13 .0027 23.14 .0004 24.15 .0015 25.15 .0024 26.16 .0021 27.17 .0006 28.17 .0008 29.17 .0013 30.19 .0015 31.19 .0005 32.19 .0002 33.21 .0009 34.21 .0010 35.21 .0006 36.23 .0003 37.23 .0005 38.23 .0009 39.24 .0007 40.25 .0002 41.25 .0004 42.26 .0006 43.27 .0004 44.27 .0002 45.27 .0003 46.29 .0004 47.29 .0003 48.29 .0001)) (define tbf-cs4 '( 1.00 .0881 2.00 .1170 3.00 .0852 4.00 .0643 5.00 .0778 6.00 .0489 6.99 .0269 8.00 .0107 8.99 .0292 10.00 .0159 10.99 .0082 12.00 .0066 12.99 .0009 14.00 .0050 14.99 .0064 15.99 .0059 17.00 .0044 17.99 .0024 19.00 .0042 19.99 .0040 21.00 .0027 21.99 .0023 22.99 .0018 23.99 .0024 24.99 .0025 25.99 .0019 26.99 .0007 27.99 .0004 28.99 .0012 29.99 .0014 30.99 .0012 31.99 .0004 32.99 .0002 33.99 .0007 34.98 .0009 35.99 .0008 36.98 .0005 37.99 .0002 38.98 .0005 39.99 .0007 40.98 .0007 41.98 .0004 42.98 .0001 43.98 .0003 44.99 .0004 45.98 .0003)) (define tbf-d4 '( 1.01 .1228 2.02 .1247 3.02 .1142 4.03 .0474 5.04 .0335 6.04 .0332 7.05 .0302 8.06 .0222 9.07 .0090 10.08 .0030 11.09 .0027 12.09 .0054 13.10 .0059 14.10 .0040 15.11 .0038 16.12 .0029 17.13 .0011 18.14 .0020 19.15 .0021 20.15 .0023 21.16 .0016 22.17 .0012 23.17 .0008 24.18 .0003 25.19 .0006 26.20 .0008 27.21 .0008 28.22 .0008 29.22 .0004 30.23 .0002 31.23 .0002 32.24 .0003 33.26 .0004 34.26 .0004 35.27 .0004 36.28 .0002 39.29 .0002 40.30 .0002 41.32 .0001)) (define tbf-ds4 '( 1.01 .1133 2.01 .1562 3.02 .1429 4.02 .0366 5.02 .0219 6.03 .0212 7.03 .0142 8.04 .0216 9.04 .0101 10.04 .0063 11.05 .0076 12.05 .0081 13.06 .0050 14.06 .0030 15.07 .0010 16.07 .0011 17.07 .0019 18.08 .0022 19.08 .0029 20.09 .0028 21.09 .0021 22.09 .0016 23.10 .0016 24.10 .0010 25.11 .0005 26.11 .0003 27.11 .0002 28.12 .0006 29.12 .0004 30.13 .0005 31.13 .0004 32.13 .0006 33.14 .0003 34.14 .0003 35.15 .0002 37.15 .0002 38.15 .0001 39.16 .0002 40.16 .0002 41.17 .0002)) (define tbf-e4 '( .99 .0906 1.99 .1338 2.99 .1235 3.98 .0833 4.98 .0601 5.98 .0264 6.98 .0126 7.97 .0051 8.97 .0026 9.97 .0014 10.96 .0018 11.96 .0025 12.96 .0031 13.96 .0021 14.95 .0034 15.95 .0035 16.95 .0037 17.94 .0031 18.94 .0021 19.93 .0021 20.93 .0016 21.92 .0010 22.92 .0012 23.92 .0011 24.91 .0007 25.91 .0004 26.91 .0002 28.91 .0001 30.89 .0001 31.90 .0002 32.90 .0002 33.89 .0002 34.89 .0002 35.88 .0002 36.88 .0002 37.88 .0002 38.87 .0001)) (define tbf-f4 '( 1.01 .1228 2.01 .3008 3.01 .1922 4.01 .0927 5.01 .0581 6.02 .0447 7.02 .0207 8.03 .0106 9.02 .0057 10.02 .0018 11.03 .0040 12.03 .0041 13.04 .0040 14.04 .0039 15.04 .0042 16.04 .0034 17.05 .0035 18.05 .0038 19.06 .0033 20.06 .0029 21.06 .0024 22.06 .0020 23.07 .0018 24.07 .0015 25.07 .0012 26.07 .0009 27.07 .0006 28.08 .0005 29.08 .0003 30.09 .0003 31.10 .0003 32.10 .0004 33.11 .0004 34.11 .0004 35.10 .0004 36.10 .0004 37.11 .0003 38.11 .0002)) (define tbf-fs4 '( 1.01 .0765 2.01 .2561 3.02 .0803 4.03 .0653 5.03 .0230 6.04 .0093 7.05 .0035 8.05 .0042 9.06 .0040 10.07 .0052 11.07 .0056 12.08 .0049 13.09 .0039 14.09 .0035 15.10 .0031 16.10 .0021 17.11 .0012 18.12 .0010 19.12 .0005 20.13 .0003 21.14 .0001 22.14 .0001 23.15 .0003 24.16 .0002 25.16 .0003 26.17 .0003 27.18 .0003 28.18 .0003 29.19 .0003 30.20 .0002 31.20 .0001)) (define tbf-g4 '( 1.01 .0092 2.02 .2167 3.02 .0668 4.02 .0254 5.03 .0210 6.04 .0282 7.04 .0151 8.05 .0130 9.05 .0054 10.06 .0031 11.07 .0014 12.08 .0020 13.08 .0020 14.09 .0020 15.09 .0021 16.10 .0015 17.10 .0007 18.11 .0003 19.13 .0002 20.13 .0004 21.13 .0005 22.14 .0004 23.14 .0003 24.15 .0003 25.15 .0001 29.18 .0001 30.19 .0001)) (define tbf-gs4 '( 1.00 .1758 2.01 .1249 3.01 .0253 4.02 .0471 5.02 .0478 6.03 .0217 7.03 .0025 8.04 .0044 9.05 .0066 10.05 .0060 11.05 .0030 12.06 .0021 13.09 .0005 14.07 .0008 15.07 .0014 16.08 .0010 17.08 .0005 18.10 .0002 19.09 .0003 20.10 .0003 21.10 .0003 22.10 .0001 24.13 .0001 25.13 .0001 26.13 .0001)) (define tbf-a4 '( 1.00 .3944 2.01 .1441 3.00 .0979 4.01 .0595 5.01 .0218 6.01 .0057 7.01 .0131 8.01 .0053 9.01 .0018 10.02 .0029 11.01 .0042 12.02 .0032 13.01 .0001 14.02 .0014 15.02 .0017 16.02 .0006 17.03 .0003 18.02 .0006 19.03 .0009 20.03 .0003 21.04 .0002 22.03 .0004 23.03 .0004 25.04 .0002 26.04 .0003 27.04 .0001)) (define tbf-as4 '( 1.01 .3895 2.03 .1550 3.03 .0985 4.05 .0153 5.06 .0280 6.07 .0103 7.08 .0028 8.10 .0069 9.10 .0023 10.12 .0025 11.13 .0029 12.14 .0011 13.15 .0011 14.16 .0009 15.17 .0002 16.19 .0007 17.20 .0004 18.22 .0002 19.22 .0003 20.23 .0001 22.26 .0001)) (define tbf-b4 '( 1.00 .2165 2.01 .1597 3.00 .0717 4.01 .0353 5.01 .0332 6.01 .0024 7.01 .0088 8.02 .0009 9.02 .0039 10.02 .0016 11.02 .0015 12.02 .0014 13.03 .0003 14.03 .0007 16.03 .0004 17.04 .0002 18.03 .0002 19.04 .0001)) (define tbf-c5 '( 1.01 .1699 2.01 .2670 3.03 .0349 4.03 .0454 5.05 .0024 6.05 .0069 7.06 .0021 8.07 .0015 9.08 .0011 10.09 .0007 11.09 .0007 12.10 .0001 13.11 .0004 15.13 .0002)) (define tbf-cs5 '( 1.00 .2017 2.00 .0920 3.00 .0598 3.99 .0086 4.99 .0120 5.99 .0063 6.99 .0034 7.99 .0029 8.99 .0008 9.99 .0014 10.98 .0008 11.97 .0007 12.98 .0006 13.96 .0001 14.97 .0003 15.97 .0001)) ;;; ;;; ;;; ;;; ;;; (define tbp-e2 '( 1.00 .0179 2.00 .0770 2.99 .0532 3.99 .0183 4.97 .0494 5.98 .0137 6.95 .0121 7.97 .0153 8.94 .0012 9.96 .0040 10.97 .0030 11.93 .0021 12.93 .0034 13.94 .0007 14.91 .0004 16.01 .0002 16.93 .0003 17.92 .0008 18.94 .0004 19.96 .0002 21.00 .0001 22.95 .0001 25.89 .0001)) (define tbp-f2 '( .99 .0137 2.01 .0473 3.03 .0362 4.01 .0117 5.02 .0565 6.04 .0247 7.06 .0348 8.04 .0251 9.05 .0143 10.07 .0146 11.09 .0020 12.07 .0048 13.09 .0013 14.12 .0012 15.12 .0009 16.12 .0004 17.10 .0010 18.11 .0003 19.13 .0004 20.13 .0001 22.14 .0001 24.17 .0001)) (define tbp-fs2 '( 1.02 .0110 2.02 .0470 3.02 .0038 4.02 .0343 5.01 .0442 6.02 .0198 7.01 .0600 8.02 .0144 9.05 .0468 10.05 .0112 11.05 .0137 12.05 .0078 13.05 .0041 14.05 .0040 15.05 .0012 16.05 .0018 17.05 .0007 18.08 .0011 19.08 .0003 20.09 .0005 21.08 .0004 22.08 .0002 23.07 .0003 25.07 .0001)) (define tbp-g2 '( 1.01 .0148 2.00 .0544 3.02 .0144 4.01 .0848 5.03 .0334 6.02 .0703 7.01 .0546 8.03 .0242 9.02 .0235 10.04 .0054 11.02 .0079 12.04 .0009 13.03 .0032 14.02 .0011 15.04 .0013 16.02 .0005 17.06 .0005 18.01 .0001 19.01 .0002 20.07 .0002 21.08 .0001)) (define tbp-gs2 '( .99 .0357 2.00 .0505 3.00 .0158 3.99 .0999 4.99 .0473 6.00 .0633 7.00 .0187 7.98 .0536 8.99 .0153 9.99 .0238 10.98 .0049 11.98 .0045 12.99 .0018 13.98 .0031 14.97 .0011 15.97 .0009 16.98 .0005 17.97 .0007 18.97 .0006 19.95 .0003 20.96 .0001)) (define tbp-a2 '( 1.00 .0295 1.99 .1044 2.98 .0380 3.96 .1223 4.95 .0652 5.93 .0906 6.93 .0212 7.91 .0492 8.91 .0034 9.88 .0180 10.87 .0036 11.86 .0050 12.85 .0005 13.85 .0016 14.84 .0009 15.81 .0014 16.80 .0002 17.77 .0003 20.73 .0001 21.73 .0002 22.73 .0002 24.70 .0001)) (define tbp-as2 '( 1.00 .0228 2.01 .0987 3.02 .0160 4.03 .0517 5.03 .0818 6.04 .0522 7.06 .0447 8.06 .0171 9.07 .0228 10.06 .0032 11.08 .0065 12.06 .0008 13.09 .0023 14.11 .0008 15.09 .0004 16.11 .0004 17.10 .0003 18.13 .0002 20.07 .0001)) (define tbp-b2 '( 1.01 .0076 1.99 .0810 2.98 .0345 3.98 .0341 4.99 .0653 5.99 .0085 6.96 .0538 7.97 .0030 8.97 .0204 9.96 .0059 10.95 .0026 11.96 .0028 12.96 .0006 13.94 .0014 14.92 .0002 15.94 .0007 16.95 .0002)) (define tbp-c3 '( 1.02 .0300 2.02 .0703 3.03 .1222 4.04 .0495 5.04 .0810 6.04 .0372 7.05 .0371 8.06 .0353 9.08 .0026 10.09 .0078 11.10 .0065 12.11 .0027 13.11 .0030 14.12 .0006 15.12 .0013 16.13 .0006 17.14 .0002 18.16 .0002 19.18 .0001 20.19 .0001 21.19 .0001)) (define tbp-cs3 '( .99 .0466 1.97 .0094 2.97 .0953 3.95 .0427 4.96 .0520 5.94 .0187 6.94 .0127 7.92 .0075 8.90 .0015 9.90 .0017 10.88 .0009 11.89 .0002 12.85 .0002)) (define tbp-d3 '( 1.01 .0634 2.02 .0187 3.02 .0987 4.02 .0742 5.02 .0182 6.03 .0331 7.03 .0132 8.03 .0025 9.04 .0026 10.06 .0016 11.07 .0002 12.08 .0001)) (define tbp-ds3 '( 1.01 .1106 2.01 .0100 3.00 .0866 4.00 .0859 5.00 .0217 6.00 .0251 6.99 .0134 7.99 .0022 8.99 .0026 9.99 .0021 11.00 .0005 14.99 .0001 16.99 .0001)) (define tbp-e3 '( 1.00 .1452 1.99 .0464 2.98 .0553 3.97 .1114 4.96 .0181 5.95 .0077 6.94 .0033 7.93 .0043 8.92 .0023 9.92 .0003 10.90 .0006 11.89 .0003 14.88 .0001 15.87 .0002 19.83 .0001)) (define tbp-f3 '( .99 .0923 2.00 .0191 3.00 .0745 3.99 .1014 5.00 .0547 6.00 .0129 6.99 .0032 8.00 .0023 9.00 .0018 9.98 .0007 10.38 .0001 12.98 .0001)) (define tbp-fs3 '( 1.01 .0781 2.00 .0346 2.99 .0441 4.01 .0196 5.00 .0310 5.99 .0213 7.00 .0062 7.99 .0021 9.00 .0003 9.99 .0002)) (define tbp-g3 '( 1.01 .0733 2.03 .0883 3.03 .0772 4.05 .0148 5.06 .0055 6.06 .0033 7.09 .0026 8.09 .0015 9.11 .0003 10.12 .0002)) (define tbp-gs3 '( 1.02 .0885 2.03 .1115 3.05 .0480 4.06 .0466 5.07 .0106 6.09 .0018 7.10 .0009)) (define tbp-a3 '( 1.01 .1416 2.02 .1418 3.02 .0683 4.03 .0464 5.04 .0178 6.04 .0037 7.06 .0018 8.07 .0006 9.05 .0004)) (define tbp-as3 '( 1.01 .1361 2.01 .0839 3.00 .0761 4.00 .0211 5.00 .0045 6.00 .0018 7.00 .0004)) (define tbp-b3 '( 1.01 .0960 2.01 .0594 3.01 .0315 4.01 .0078 5.01 .0021 6.01 .0009 7.02 .0005 8.03 .0003)) (define tbp-c4 '( 1.00 .0855 2.00 .1172 3.00 .0276 4.00 .0135 5.00 .0053 6.00 .0021 6.99 .0003)) (define tbp-cs4 '( 1.01 .0033 2.00 .0982 2.99 .0491 3.99 .0185 4.99 .0043 5.98 .0004 6.99 .0001)) (define tbp-d4 '( 1.01 .0485 2.01 .1552 3.01 .0547 4.01 .0136 5.03 .0026 6.04 .0010 7.05 .0001)) (define tbp-ds4 '( 1.01 .0030 2.01 .1892 3.01 .0563 4.01 .0025 5.02 .0034 5.97 .0001 7.03 .0003)) (define tbp-e4 '( 1.01 .0508 2.02 .0934 3.02 .0147 4.03 .0111 5.05 .0014 6.06 .0014 8.08 .0001)) (define tbp-f4 '( 1.00 .0260 2.02 .2047 3.02 .0550 4.03 .0165 5.04 .0051 6.04 .0005 7.05 .0002)) (define tbp-fs4 '( 1.02 .0971 2.03 .0635 3.04 .0254 4.05 .0023 5.07 .0002 6.08 .0003 7.09 .0001)) (define tbp-g4 '( 1.02 .3176 2.03 .0734 3.04 .0332 4.05 .0152 5.06 .0048 6.08 .0007)) (define tbp-gs4 '( 1.01 .3321 2.01 .1320 3.01 .0072 4.02 .0028 5.03 .0009 6.04 .0002 7.04 .0002)) (define tbp-a4 '( 1.00 .5149 2.00 .2025 3.00 .0392 3.99 .0117 4.99 .0035 5.99 .0008 6.99 .0002 7.98 .0001)) (define tbp-as4 '( 1.01 .3188 2.01 .2130 3.02 .0427 4.03 .0024 5.05 .0004 6.05 .0007 7.06 .0002 8.06 .0002)) (define tbp-b4 '( 1.00 .1685 1.99 .0732 2.99 .0056 3.99 .0042 4.99 .0009 5.99 .0005)) (define tbp-c5 '( 1.01 .3386 2.02 .0634 3.02 .0212 4.03 .0019 5.04 .0004)) (define tbp-cs5 '( 1.00 .2958 2.00 .0843 3.01 .0058 4.01 .0027 5.01 .0003)) (define tbp-d5 '( 1.00 .4237 2.01 .0453 3.01 .0045 4.02 .0007 5.02 .0004)) ;;; ;;; ;;; ;;; ;;; trumpet (define trp-fs3 '( 1.01 .0533 2.03 .0559 3.05 .0505 4.06 .0542 5.08 .0382 6.10 .0570 7.12 .0321 8.14 .0393 9.15 .0277 10.17 .0157 11.19 .0165 12.20 .0152 13.22 .0081 14.23 .0089 15.24 .0035 16.26 .0045 17.28 .0052 18.29 .0020 19.31 .0021 20.33 .0017 21.35 .0014 22.37 .0010 23.38 .0009 24.40 .0004 25.42 .0005 26.44 .0004 27.45 .0004 28.46 .0004 29.48 .0002 30.49 .0002 31.51 .0002 32.53 .0001 33.55 .0001)) (define trp-g3 '( .99 .0459 1.99 .0931 3.00 .0517 4.00 .0496 5.00 .0576 6.00 .0452 7.00 .0263 8.00 .0125 9.01 .0131 10.01 .0136 11.00 .0066 12.00 .0081 13.00 .0032 14.00 .0039 14.99 .0026 16.00 .0017 16.99 .0017 17.99 .0009 19.01 .0013 20.01 .0008 21.01 .0006 22.00 .0006 23.00 .0003 24.01 .0004 25.01 .0003 26.01 .0002 27.02 .0002 28.02 .0001 29.02 .0001 31.04 .0001)) (define trp-gs3 '( .99 .0455 1.99 .0969 2.97 .0487 3.97 .0296 4.97 .0186 5.95 .0219 6.95 .0075 7.94 .0176 8.93 .0202 9.93 .0175 10.91 .0156 11.91 .0097 12.91 .0066 13.89 .0065 14.89 .0051 15.88 .0037 16.86 .0015 17.87 .0016 18.85 .0010 19.85 .0006 20.84 .0006 21.84 .0006 22.84 .0005 23.82 .0003 24.82 .0003 25.80 .0002 26.79 .0002 27.79 .0001 28.79 .0001)) (define trp-a3 '( .99 .0420 1.99 .0954 2.99 .0579 3.99 .0722 4.98 .0813 5.98 .0399 6.98 .0379 7.98 .0181 8.98 .0188 9.98 .0147 10.97 .0100 11.97 .0091 12.96 .0048 13.96 .0091 14.96 .0048 15.96 .0016 16.96 .0027 17.97 .0020 18.96 .0014 19.96 .0007 20.95 .0007 21.95 .0006 22.94 .0003 23.95 .0005 24.95 .0002 25.95 .0002 26.95 .0002 27.96 .0002 28.95 .0002 29.94 .0001)) (define trp-as3 '( 1.01 .0487 2.01 .0236 3.01 .0599 4.01 .0397 5.01 .0525 6.01 .0426 7.00 .0144 8.01 .0134 9.01 .0274 10.01 .0087 11.01 .0041 12.00 .0052 13.01 .0080 14.01 .0028 15.02 .0022 16.01 .0014 17.04 .0005 18.04 .0003 19.03 .0005 20.02 .0003 21.02 .0003 22.02 .0003 23.03 .0002 24.03 .0002 25.02 .0001)) (define trp-b3 '( 1.00 .0534 2.00 .0362 3.00 .0698 4.00 .0793 4.99 .0301 6.00 .0216 7.00 .0130 8.00 .0151 9.00 .0172 10.00 .0062 11.00 .0041 11.99 .0022 13.00 .0017 14.00 .0012 14.99 .0013 15.95 .0002 16.99 .0001 18.00 .0003 19.00 .0003 20.00 .0003 21.01 .0001)) (define trp-c4 '( 1.01 .0410 2.03 .0543 3.03 .0487 4.04 .0354 5.05 .0408 6.06 .0221 7.08 .0099 8.09 .0248 9.09 .0107 10.11 .0037 11.11 .0087 12.13 .0035 13.14 .0012 14.16 .0013 15.17 .0002 16.18 .0002 17.19 .0003 18.20 .0002 19.21 .0002 20.22 .0002 21.23 .0001 22.24 .0001)) (define trp-cs4 '( 1.01 .0199 2.03 .0437 3.03 .0142 4.04 .0534 5.04 .0310 6.06 .0194 7.06 .0124 8.06 .0071 9.07 .0061 10.06 .0037 11.09 .0022 12.12 .0007 13.11 .0005 14.12 .0003 15.10 .0002 16.12 .0002 17.13 .0001 18.13 .0001)) (define trp-d4 '( 1.01 .0320 2.02 .0510 3.04 .0747 4.05 .0619 5.06 .0404 6.07 .0195 7.08 .0221 8.09 .0112 9.11 .0073 10.13 .0031 11.13 .0026 12.15 .0017 13.16 .0013 14.17 .0009 15.18 .0007 16.18 .0004 17.19 .0003 18.22 .0002 19.23 .0002 20.23 .0002 21.25 .0001)) (define trp-ds4 '( 1.00 .0471 2.01 .0466 3.02 .0304 4.02 .0166 5.02 .0187 6.02 .0086 7.03 .0064 8.03 .0067 9.03 .0033 10.02 .0016 11.05 .0013 12.06 .0008 13.06 .0005 14.05 .0002 15.04 .0002 16.05 .0002 17.05 .0001)) (define trp-e4 '( 1.01 .0365 2.01 .0352 3.02 .0462 4.02 .0230 5.02 .0092 6.02 .0078 7.02 .0059 8.04 .0034 9.04 .0011 10.05 .0010 11.07 .0003 12.07 .0003 13.06 .0002 14.06 .0001 15.07 .0001)) (define trp-f4 '( 1.00 .0412 2.00 .0621 3.00 .0180 3.99 .0631 4.99 .0245 5.99 .0369 6.99 .0093 7.99 .0126 8.99 .0027 9.99 .0035 10.99 .0021 11.99 .0016 12.99 .0010 13.98 .0009 14.98 .0006 15.98 .0004 16.98 .0002)) (define trp-fs4 '( .99 .0581 1.98 .0494 2.98 .0614 3.97 .0316 4.96 .0151 5.96 .0095 6.95 .0022 7.93 .0022 8.93 .0013 9.94 .0008 10.93 .0003 11.92 .0002 12.92 .0001 13.93 .0001)) (define trp-g4 '( 1.00 .0979 1.99 .0344 2.99 .0374 3.99 .0179 4.98 .0148 5.98 .0059 6.98 .0029 7.95 .0005 8.97 .0004 9.97 .0002 10.96 .0002)) (define trp-gs4 '( 1.00 .0670 2.00 .0138 3.00 .0100 4.01 .0076 4.99 .0070 5.99 .0037 6.97 .0023 7.97 .0007 8.97 .0002 9.98 .0001 10.97 .0002)) (define trp-a4 '( 1.00 .0403 2.01 .0211 3.00 .0107 4.00 .0052 4.99 .0022 6.00 .0013 7.00 .0006 8.01 .0002 9.02 .0001 10.03 .0001)) (define trp-as4 '( 1.00 .0128 2.01 .0154 3.00 .0269 3.99 .0098 4.99 .0021 5.98 .0016 6.99 .0004 8.00 .0003 9.02 .0002)) (define trp-b4 '( 1.01 .0287 2.01 .0583 3.01 .0386 4.00 .0098 5.01 .0068 6.02 .0012 7.02 .0012 8.03 .0003 9.02 .0003 10.01 .0001)) (define trp-c5 '( 1.01 .0190 2.01 .0057 3.01 .0039 4.01 .0051 5.03 .0005 6.02 .0002 7.03 .0001)) (define trp-cs5 '( 1.01 .0087 2.01 .0050 3.01 .0011 4.01 .0002)) (define trp-d5 '( 1.01 .0145 2.01 .0098 3.01 .0013 4.01 .0003)) (define trp-ds5 '( 1.00 .0231 2.00 .0053 2.98 .0077 3.97 .0021 4.96 .0003 6.98 .0001)) (define trp-e5 '( 1.01 .0520 2.02 .0187 3.00 .0009 4.04 .0011 5.02 .0001)) (define trp-f5 '( 1.02 .0332 2.02 .0074 3.03 .0031)) (define trp-fs5 '( 1.01 .1718 2.02 .1098 3.02 .0288 4.02 .0047 5.04 .0026 6.04 .0008 7.06 .0004 8.06 .0002)) (define trp-g5 '( 1.02 .0825 2.03 .0364 3.04 .0160 4.06 .0045 5.07 .0011 6.09 .0005 7.10 .0002)) (define trp-gs5 '( 1.02 .0114 2.02 .0346 3.02 .0045 4.04 .0013 5.06 .0002)) (define trp-a5 '( 1.02 .0821 2.03 .0089 3.04 .0023 4.06 .0003 5.05 .0001)) (define trp-as5 '( 1.01 .1554 2.01 .0287 3.02 .0084 4.02 .0035 5.03 .0007 6.04 .0002 7.04 .0001)) (define trp-b5 '( 1.01 .0559 2.01 .0017 3.01 .0013 4.02 .0001)) (define trp-c6 '( 1.01 .0291 2.00 .0150 3.01 .0032 4.02 .0004 5.02 .0002)) ;;; ;;; ;;; ;;; ;;; (define trpf-fs3 '( 1.00 .0292 1.99 .0424 3.00 .0242 4.00 .0413 4.99 .0315 6.00 .0454 7.00 .0143 7.98 .0108 8.99 .0077 9.99 .0084 10.99 .0071 11.98 .0078 12.97 .0085 13.98 .0032 14.97 .0035 15.97 .0052 16.96 .0021 17.96 .0033 18.96 .0024 19.97 .0016 20.95 .0015 21.95 .0011 22.95 .0006 23.95 .0007 24.94 .0006 25.94 .0004 26.94 .0003 27.93 .0004 28.93 .0003 29.93 .0002 30.92 .0003 31.92 .0001 32.93 .0001 33.91 .0002)) (define trpf-g3 '( .99 .0286 1.97 .0669 2.95 .0456 3.95 .0345 4.94 .0617 5.91 .0341 6.90 .0225 7.89 .0264 8.88 .0155 9.86 .0160 10.84 .0150 11.83 .0085 12.82 .0112 13.80 .0054 14.78 .0042 15.77 .0056 16.76 .0023 17.73 .0027 18.71 .0010 19.73 .0014 20.69 .0014 21.68 .0007 22.67 .0007 23.64 .0007 24.63 .0004 25.62 .0005 26.59 .0003 27.62 .0002 28.56 .0003 29.55 .0001 30.53 .0002 31.51 .0002 32.50 .0001 33.48 .0002 35.47 .0001)) (define trpf-gs3 '( .99 .0306 1.99 .0608 2.97 .0495 3.97 .0557 4.97 .0228 5.95 .0337 6.95 .0177 7.94 .0112 8.92 .0146 9.93 .0022 10.91 .0069 11.89 .0053 12.89 .0047 13.88 .0031 14.87 .0063 15.87 .0042 16.86 .0033 17.84 .0031 18.84 .0028 19.83 .0018 20.83 .0015 21.82 .0010 22.80 .0010 23.80 .0005 24.79 .0007 25.77 .0004 26.77 .0005 27.76 .0003 28.75 .0003 29.74 .0002 30.74 .0002 32.73 .0001)) (define trpf-a3 '( .99 .0331 2.00 .0607 3.00 .0463 4.00 .0350 5.00 .0480 6.00 .0294 7.00 .0318 7.99 .0150 8.98 .0166 9.98 .0148 10.98 .0109 11.99 .0052 13.02 .0012 13.99 .0070 14.98 .0054 15.98 .0035 16.97 .0035 17.96 .0021 18.96 .0019 19.96 .0008 20.96 .0010 21.97 .0006 22.96 .0005 23.96 .0007 24.96 .0004 25.95 .0006 26.95 .0004 27.94 .0003 28.94 .0002 29.94 .0001 30.94 .0002 31.93 .0002 32.93 .0001)) (define trpf-as3 '( 1.00 .0250 2.00 .0182 2.99 .0170 3.97 .0199 4.97 .0223 5.97 .0224 6.95 .0094 7.95 .0070 8.94 .0069 9.92 .0064 10.91 .0030 11.92 .0028 12.90 .0024 13.01 .0007 14.00 .0003 14.89 .0008 15.89 .0007 16.91 .0002 17.88 .0002 18.86 .0001 20.83 .0001)) (define trpf-b3 '( 1.00 .0379 1.99 .0221 2.99 .0480 3.99 .0721 4.97 .0322 5.98 .0203 6.97 .0220 7.97 .0170 8.96 .0150 9.96 .0042 10.95 .0040 11.93 .0049 12.94 .0038 14.00 .0011 14.95 .0021 15.95 .0008 16.93 .0004 16.98 .0004 17.90 .0004 18.00 .0003 18.99 .0003 19.89 .0003 20.88 .0003 21.89 .0002 22.97 .0002 23.97 .0002)) (define trpf-c4 '( 1.01 .0330 2.02 .0365 3.02 .0430 4.03 .0164 5.05 .0234 6.04 .0138 7.05 .0110 8.06 .0202 9.07 .0098 10.08 .0030 11.09 .0065 12.11 .0027 13.11 .0009 14.13 .0014 15.15 .0003 16.12 .0002 17.13 .0002 18.12 .0002 19.14 .0002 20.13 .0002 21.14 .0001)) (define trpf-cs4 '( 1.01 .0082 2.02 .0191 3.02 .0152 4.01 .0324 5.02 .0129 6.03 .0050 7.01 .0093 8.01 .0031 9.01 .0036 10.00 .0017 11.01 .0010 12.00 .0004 13.02 .0004 14.03 .0003 15.02 .0002 16.03 .0001)) (define trpf-d4 '( 1.01 .0190 2.03 .0431 3.04 .0481 4.05 .0399 5.07 .0179 6.08 .0198 7.09 .0136 8.10 .0081 9.12 .0041 10.10 .0011 11.15 .0016 12.16 .0014 13.17 .0007 14.18 .0005 15.20 .0003 16.20 .0002 17.22 .0002 19.24 .0001)) (define trpf-ds4 '( 1.00 .0239 2.01 .0207 3.02 .0113 4.00 .0083 5.00 .0145 5.97 .0054 6.99 .0031 7.98 .0026 8.97 .0027 9.98 .0010 11.01 .0004 11.99 .0004 13.00 .0003 13.97 .0002 14.98 .0002 15.97 .0002)) (define trpf-e4 '( 1.02 .0134 2.03 .0124 3.04 .0117 4.05 .0041 5.08 .0007 6.06 .0009 7.08 .0006 8.06 .0002 9.11 .0002)) (define trpf-f4 '( 1.03 .0045 2.03 .0019 3.03 .0006 4.04 .0012 5.02 .0004 6.08 .0001)) (define trpf-fs4 '( 1.00 .0501 2.00 .0385 3.00 .0509 3.99 .0156 4.98 .0099 5.98 .0063 6.99 .0017 7.97 .0020 8.97 .0017 9.96 .0012 10.96 .0004 11.95 .0004 12.97 .0001 13.94 .0002)) (define trpf-g4 '( 1.00 .0998 2.00 .0632 3.01 .0506 4.01 .0395 5.00 .0265 6.01 .0137 7.01 .0058 8.01 .0017 9.02 .0010 10.02 .0007 11.02 .0007 12.03 .0004 13.03 .0004 14.03 .0002 15.05 .0001)) (define trpf-gs4 '( 1.00 .0589 2.00 .0237 2.99 .0208 3.98 .0103 4.98 .0087 5.98 .0053 6.97 .0039 7.98 .0017 8.98 .0006 10.00 .0003 10.97 .0002 12.00 .0001)) (define trpf-a4 '( 1.01 .0482 2.01 .0264 3.02 .0127 4.01 .0108 5.01 .0039 6.01 .0012 7.00 .0012 8.01 .0004 9.02 .0002 10.02 .0002 11.00 .0001)) (define trpf-as4 '( 1.00 .0176 2.01 .0156 3.00 .0312 3.99 .0057 5.00 .0055 5.99 .0036 6.99 .0007 7.99 .0005 8.99 .0003 9.99 .0001 10.99 .0001)) (define trpf-b4 '( 1.01 .0051 1.99 .0340 2.98 .0087 3.97 .0121 4.97 .0018 5.94 .0018 6.95 .0005 7.93 .0002 8.94 .0004)) (define trpf-c5 '( 1.01 .0110 1.99 .0059 3.00 .0200 3.99 .0059 5.00 .0016 5.99 .0005 6.98 .0002 7.96 .0002 8.99 .0002)) (define trpf-cs5 '( 1.01 .0257 2.01 .0215 3.02 .0022 4.00 .0027 5.01 .0007 6.00 .0007 7.02 .0002)) (define trpf-d5 '( 1.01 .0616 2.01 .0423 3.01 .0140 4.01 .0061 4.99 .0034 5.99 .0008 6.98 .0006 8.00 .0003 8.97 .0002)) (define trpf-ds5 '( .99 .0763 1.99 .0800 2.98 .0329 3.97 .0255 4.96 .0110 5.95 .0041 6.95 .0018 7.94 .0006 8.93 .0005 9.90 .0002 9.93 .0002 10.91 .0002)) (define trpf-e5 '( 1.01 .0196 2.00 .0085 2.98 .0039 3.97 .0007 4.98 .0003)) (define trpf-f5 '( 1.02 .0735 2.03 .0526 3.04 .0168 4.05 .0064 5.07 .0009 6.07 .0008 7.09 .0002 8.09 .0001 9.12 .0001)) (define trpf-fs5 '( 1.01 .1101 2.02 .0477 3.03 .0090 4.04 .0024 5.05 .0012 6.06 .0015 7.07 .0004 8.08 .0002)) (define trpf-g5 '( 1.02 .1148 2.03 .0215 3.04 .0185 4.06 .0077 5.07 .0023 6.08 .0007 7.09 .0004 8.12 .0002)) (define trpf-gs5 '( 1.01 .0538 2.02 .0584 3.03 .0156 4.04 .0028 5.06 .0009 6.07 .0006 7.07 .0002)) (define trpf-a5 '( 1.01 .1885 2.02 .0789 3.04 .0214 4.05 .0086 5.06 .0049 6.07 .0010 7.08 .0007 8.10 .0003 9.11 .0003 10.12 .0001 11.13 .0001)) (define trpf-as5 '( 1.01 .0233 2.02 .0033 3.01 .0008 4.03 .0002)) (define trpf-b5 '( 1.00 .1077 2.01 .0158 3.01 .0039 4.01 .0011 5.01 .0003 6.02 .0002 7.02 .0001)) (define trpf-c6 '( 1.01 .0873 2.02 .0519 3.03 .0156 4.04 .0042 5.04 .0019 6.05 .0006 7.06 .0004 8.07 .0002)) (define trpf-cs6 '( 1.01 .0852 2.02 .0049 3.03 .0007 4.05 .0001)) ;;; ;;; ;;; ;;; ;;; violin? (define vl-g3 '( .99 .0159 1.99 .1898 3.00 .0499 3.99 .0352 5.00 .0192 6.00 .0100 7.00 .0173 8.00 .0142 8.99 .0045 10.01 .0178 11.00 .0108 12.00 .0081 12.99 .0254 13.99 .0074 14.99 .0062 16.00 .0122 17.00 .0049 17.99 .0022 19.01 .0041 20.01 .0048 21.01 .0037 22.01 .0016 23.01 .0001 24.00 .0002 25.00 .0006 26.00 .0010 27.00 .0015 28.03 .0004 29.02 .0007 30.01 .0006 32.00 .0002 33.01 .0001 34.00 .0001 35.01 .0004 36.02 .0003 37.02 .0001 40.02 .0001 40.99 .0002 42.01 .0003 48.01 .0001 51.01 .0001)) (define vl-gs3 '( .99 .0185 1.99 .1881 2.97 .0463 3.97 .0528 4.97 .0309 5.95 .0316 6.95 .0104 7.93 .0422 8.94 .0114 9.90 .0018 10.92 .0088 11.89 .0021 12.90 .0077 13.91 .0044 14.86 .0029 14.93 .0028 15.91 .0011 16.88 .0082 17.89 .0022 18.88 .0043 19.86 .0024 20.84 .0012 21.84 .0007 22.87 .0008 23.85 .0006 24.84 .0004 25.82 .0010 26.81 .0006 27.81 .0012 28.79 .0002 29.78 .0002 30.77 .0001 31.78 .0003 33.75 .0001 34.76 .0002 35.75 .0002 36.75 .0002 37.77 .0001 40.74 .0001)) (define vl-a3 '( .99 .0215 2.00 .1550 2.99 .0293 4.00 .0298 5.00 .0211 6.00 .0389 7.00 .0057 7.99 .0235 8.99 .0172 9.99 .0040 11.00 .0026 12.00 .0074 12.99 .0065 13.99 .0192 14.99 .0026 15.98 .0063 16.99 .0045 18.01 .0036 18.99 .0050 20.00 .0012 20.98 .0011 21.99 .0007 22.99 .0014 23.99 .0003 25.00 .0011 26.00 .0008 26.99 .0007 27.98 .0002 28.99 .0001 29.97 .0004 31.00 .0002 31.99 .0002 32.99 .0002 33.98 .0001 35.03 .0001 36.00 .0002 36.98 .0003 37.99 .0002 38.99 .0001 39.99 .0002 41.01 .0001 41.99 .0001 43.04 .0001 43.99 .0001)) (define vl-as3 '( 1.00 .0210 2.00 .1015 3.00 .0450 3.99 .0210 4.99 .0266 6.00 .0143 7.00 .0661 7.99 .0367 8.99 .0149 9.99 .0037 10.99 .0344 11.99 .0069 12.99 .0110 13.98 .0088 14.98 .0052 15.98 .0066 16.99 .0038 17.98 .0027 18.98 .0007 19.98 .0018 20.98 .0009 21.99 .0011 22.99 .0013 23.99 .0006 24.97 .0004 25.98 .0001 26.98 .0003 27.97 .0002 28.99 .0002 29.97 .0002 31.00 .0002 31.97 .0004 32.97 .0001 33.99 .0003 34.97 .0002 35.97 .0003 36.94 .0001 37.99 .0001 38.96 .0001 41.97 .0001)) (define vl-b3 '( 1.00 .0532 1.99 .0205 3.00 .0342 3.99 .0312 5.00 .0493 5.99 .0062 6.99 .0103 7.99 .0240 8.99 .0134 9.99 .0046 10.98 .0154 11.99 .0077 12.98 .0084 13.99 .0028 14.99 .0026 15.98 .0054 16.98 .0031 17.99 .0004 18.98 .0009 19.99 .0005 20.52 .0001 21.98 .0011 22.97 .0010 23.99 .0004 24.96 .0003 26.00 .0001 27.99 .0006 28.99 .0001 30.97 .0003 32.00 .0002 32.99 .0001 33.97 .0002 36.99 .0001)) (define vl-c4 '( .99 .1156 2.00 .0827 3.00 .0458 4.00 .0163 5.00 .0256 6.01 .0103 7.02 .0032 8.00 .0025 8.98 .0056 10.00 .0072 10.98 .0016 11.98 .0036 13.02 .0013 14.00 .0021 15.00 .0024 15.99 .0013 16.99 .0003 18.01 .0001 19.01 .0003 19.99 .0001 21.02 .0001 22.03 .0002 29.00 .0001)) (define vl-cs4 '( 1.00 .3269 2.00 .0869 2.99 .0386 4.00 .0117 4.99 .0062 6.00 .0264 7.00 .0099 8.00 .0038 9.01 .0040 10.00 .0057 11.03 .0040 12.02 .0017 13.00 .0009 14.02 .0026 15.02 .0009 15.95 .0002 16.99 .0002 18.01 .0001 19.01 .0005 20.00 .0001 21.03 .0002 22.03 .0001)) (define vl-d4 '( 1.00 .2473 2.00 .0621 2.98 .0073 3.99 .0178 5.00 .0070 5.98 .0041 7.02 .0054 8.01 .0114 9.05 .0034 10.05 .0024 10.93 .0003 11.99 .0011 13.00 .0011 14.03 .0010 15.01 .0002 15.96 .0001 17.02 .0001 18.01 .0005 21.00 .0001 22.00 .0002)) (define vl-ds4 '( 1.00 .0394 2.00 .0358 2.99 .0119 3.99 .0208 4.99 .0064 5.98 .0126 6.96 .0028 7.03 .0017 8.01 .0006 8.92 .0005 9.97 .0048 10.97 .0004 11.99 .0005 12.97 .0005 13.96 .0002 14.92 .0001 15.92 .0001 19.93 .0001 22.92 .0001 23.96 .0001)) (define vl-e4 '( 1.00 .0649 2.00 .0412 3.01 .0315 4.00 .0446 5.01 .0414 6.01 .0209 7.02 .0189 8.01 .0101 9.03 .0012 10.03 .0029 11.02 .0041 12.00 .0012 13.04 .0004 14.05 .0005 15.03 .0009 16.06 .0005 17.09 .0004 18.07 .0006 19.08 .0004 20.10 .0001 21.09 .0001 22.09 .0004 23.11 .0002 24.06 .0002 25.07 .0002 26.07 .0002 27.08 .0002 30.10 .0001)) (define vl-f4 '( 1.00 .0700 2.00 .0235 3.00 .0294 4.00 .0101 4.99 .0173 5.99 .0081 6.99 .0023 7.99 .0006 8.97 .0101 9.98 .0060 11.00 .0063 11.99 .0038 13.00 .0011 13.98 .0003 15.01 .0009 16.02 .0005 17.01 .0004 18.06 .0002 19.01 .0004 20.01 .0004 21.03 .0005 22.04 .0002 23.00 .0003 24.00 .0001 25.99 .0001 29.04 .0001 31.04 .0001)) (define vl-fs4 '( 1.01 .1897 2.02 .0152 3.02 .0312 4.03 .0224 5.03 .0483 6.04 .0217 7.05 .0184 8.07 .0051 9.06 .0031 10.08 .0047 11.09 .0040 12.10 .0021 13.10 .0006 14.11 .0010 15.14 .0012 16.14 .0009 17.15 .0004 18.16 .0010 19.18 .0003 20.19 .0005 21.14 .0002 22.17 .0002 23.18 .0002 24.18 .0002 26.22 .0001 29.25 .0002 30.26 .0002)) (define vl-g4 '( 1.01 .0788 2.01 .0144 2.99 .0064 3.99 .0078 5.02 .0053 6.00 .0045 7.01 .0011 7.98 .0025 9.03 .0010 10.02 .0014 11.02 .0002 12.02 .0001 13.02 .0003 14.05 .0002 15.07 .0002 17.05 .0001 18.02 .0002 19.07 .0001)) (define vl-gs4 '( 1.00 .2902 2.01 .0644 3.01 .0378 4.02 .0473 5.02 .0027 6.03 .0278 7.04 .0077 8.04 .0105 9.04 .0026 10.04 .0106 11.05 .0011 12.05 .0014 13.06 .0045 14.09 .0015 15.09 .0010 16.09 .0008 17.09 .0011 18.10 .0010 19.09 .0011 20.09 .0004 21.10 .0010 22.10 .0006 23.11 .0003 24.10 .0002 24.14 .0002 25.15 .0002 26.14 .0005 27.14 .0003 30.13 .0002 31.14 .0001)) (define vl-a4 '( 1.00 .3420 2.02 .0045 3.00 .0160 4.00 .0105 5.01 .0370 6.02 .0193 7.01 .0342 8.02 .0178 9.02 .0146 10.04 .0025 11.03 .0011 12.02 .0010 13.03 .0009 14.03 .0003 15.05 .0031 16.04 .0009 17.04 .0004 18.04 .0004 19.03 .0004 20.06 .0005 21.05 .0001 22.04 .0001 24.06 .0001 25.07 .0002 26.08 .0001)) (define vl-as4 '( 1.00 .1478 2.00 .0159 3.00 .0033 3.99 .0600 5.00 .0291 5.99 .0028 7.01 .0118 8.00 .0115 8.99 .0039 9.99 .0020 10.99 .0024 11.99 .0012 12.99 .0009 14.01 .0011 15.00 .0015 16.01 .0004 17.02 .0001 18.01 .0001 19.01 .0002 20.00 .0002 20.98 .0001 22.00 .0001 24.02 .0002 25.00 .0002)) (define vl-b4 '( 1.00 .0247 2.01 .0570 3.01 .0115 4.02 .0167 5.02 .0162 6.02 .0154 7.02 .0056 8.04 .0021 9.04 .0003 10.04 .0023 11.04 .0003 12.07 .0005 13.09 .0005 14.06 .0003 15.06 .0004 16.09 .0003 17.07 .0002 18.10 .0003 19.10 .0002)) (define vl-c5 '( 1.00 .0690 1.99 .0372 2.99 .0326 3.99 .0222 4.99 .0107 5.97 .0033 6.99 .0029 7.98 .0013 8.97 .0005 9.98 .0008 10.97 .0004 11.97 .0006 12.99 .0003 13.99 .0002 14.97 .0001 16.95 .0001 16.98 .0001 17.97 .0001 19.96 .0001)) (define vl-cs5 '( 1.00 .1446 2.01 .0499 3.01 .0768 4.02 .0436 5.02 .0287 6.03 .0204 7.03 .0301 7.11 .0011 8.04 .0010 9.04 .0036 10.05 .0030 11.05 .0023 12.06 .0008 13.06 .0005 14.07 .0009 15.08 .0005 16.09 .0009 17.08 .0003 18.10 .0006 19.09 .0008 20.13 .0002 21.11 .0001 22.14 .0001 23.11 .0002)) (define vl-d5 '( 1.00 .0614 1.99 .0194 2.99 .0196 3.99 .0159 5.00 .0057 6.00 .0031 7.01 .0024 8.00 .0004 9.00 .0003 9.98 .0003 11.01 .0005 11.99 .0003 12.99 .0002 16.99 .0001 17.98 .0001)) (define vl-ds5 '( .99 .1393 1.99 .0875 2.99 .1163 3.98 .0152 4.98 .0551 5.97 .0214 6.97 .0072 7.96 .0017 8.95 .0028 9.96 .0034 10.95 .0015 11.94 .0010 12.95 .0009 13.91 .0008 14.94 .0011 15.93 .0005 16.93 .0007 17.92 .0004 17.97 .0002 18.94 .0002 19.93 .0003 20.92 .0004 21.90 .0001)) (define vl-e5 '( 1.00 .1926 2.00 .0731 3.00 .0543 4.00 .0258 5.02 .0238 6.02 .0177 7.03 .0206 8.03 .0081 9.03 .0030 10.05 .0043 11.03 .0011 12.06 .0007 13.08 .0013 14.10 .0007 15.11 .0004 16.14 .0002)) (define vl-f5 '( 1.00 .0684 2.00 .0409 3.00 .0344 4.00 .0439 5.00 .0686 6.00 .0504 7.00 .0045 8.00 .0056 9.00 .0094 10.00 .0028 11.00 .0015 11.99 .0010 13.00 .0032 14.00 .0017 15.00 .0010 16.01 .0011 16.99 .0003 18.01 .0006 19.00 .0003)) (define vl-fs5 '( 1.00 .0291 2.01 .0323 3.01 .0110 4.02 .0071 5.04 .0028 6.04 .0010 7.08 .0007 8.08 .0003 9.09 .0004 10.12 .0002 11.06 .0003)) (define vl-g5 '( 1.00 .0980 1.99 .0303 3.00 .0044 4.01 .0107 5.03 .0027 6.03 .0011 7.00 .0010 8.02 .0011 8.06 .0004 9.04 .0003 10.04 .0001)) (define vl-gs5 '( 1.01 .1116 2.01 .0200 3.03 .0147 4.03 .0034 5.08 .0061 6.10 .0012 7.06 .0005 8.14 .0005 9.14 .0004)) (define vl-a5 '( 1.00 .0211 2.01 .0180 3.01 .0158 4.02 .0057 5.03 .0013 6.03 .0006 7.02 .0001)) (define vl-as5 '( 1.00 .0442 2.01 .0922 3.01 .0102 4.00 .0031 5.03 .0053 6.01 .0004 7.04 .0018 7.08 .0009 8.06 .0004 9.06 .0006 10.06 .0003 11.06 .0003 12.09 .0002 13.09 .0002)) (define vl-b5 '( 1.01 .0061 2.01 .0016 3.01 .0014 4.03 .0005 5.04 .0005 5.06 .0001)) (define vl-c6 '( 1.01 .0039 2.00 .0005 3.02 .0006 4.03 .0001)) (define vl-cs6 '( 1.00 .0754 2.00 .1620 3.00 .1551 4.00 .0277 5.00 .0466 6.00 .0408 7.00 .0025 8.00 .0055 9.00 .0048 9.99 .0034 10.99 .0039 11.99 .0005)) (define vl-d6 '( 1.00 .0905 2.00 .0808 3.00 .0909 4.00 .0616 5.00 .0172 5.99 .0043 7.01 .0044 8.00 .0036 9.00 .0043 10.01 .0015 11.03 .0014)) (define vl-ds6 '( 1.00 .1772 2.00 .1029 3.00 .0398 4.01 .0602 5.00 .0222 6.01 .0073 7.01 .0037 8.01 .0044 9.01 .0019 10.01 .0028 11.01 .0006 11.03 .0001)) (define vl-e6 '( 1.00 .1865 2.00 .2083 2.99 .0822 3.99 .0298 4.99 .0227 6.00 .0023 6.98 .0049 7.99 .0021 8.98 .0022 9.98 .0003 9.99 .0003)) (define vl-f6 '( 1.01 .0841 2.01 .0654 3.02 .1346 4.03 .0041 5.04 .0077 6.05 .0088 7.05 .0016 8.06 .0017 9.06 .0012 9.08 .0003 9.10 .0002 9.11 .0001)) (define vl-fs6 '( 1.00 .1693 2.02 .0779 3.03 .0411 4.03 .0147 5.04 .0085 6.05 .0080 7.06 .0088 8.06 .0032 9.06 .0010 9.08 .0007 9.10 .0004)) (define vl-g6 '( 1.01 .2123 2.02 .2854 3.03 .0552 4.04 .0246 5.05 .0058 6.06 .0022 7.07 .0017 8.09 .0029 9.10 .0001)) (define vl-gs6 '( 1.02 .1270 2.03 .0961 3.05 .0347 4.06 .0032 5.08 .0083 6.09 .0050 7.11 .0020 8.12 .0013 8.14 .0002)) (define vl-a6 '( 1.02 .3359 2.03 .1252 3.05 .0238 4.07 .0155 5.09 .0053 6.10 .0051 7.12 .0025 7.18 .0001)) (define vl-as6 '( 1.01 .2037 2.03 .0456 3.05 .0029 4.06 .0053 5.07 .0041 6.09 .0043 7.11 .0026 7.13 .0006 7.14 .0001)) (define vl-b6 '( 1.02 .4213 2.04 .1379 3.06 .0067 4.06 .0041 4.08 .0039 5.09 .0026 6.11 .0027 7.13 .0002)) (define vl-c7 '( 1.01 .1299 2.02 .1571 3.03 .0461 4.04 .0033 5.05 .0057 6.06 .0015)) (define vl-cs7 '( 1.01 .1471 2.03 .0526 3.05 .0161 4.06 .0037 5.08 .0017 6.09 .0005)) (define vl-d7 '( 1.01 .0321 2.02 .0529 3.03 .0046 4.03 .0054 4.04 .0021 5.04 .0010)) (define vl-ds7 '( 1.00 .1220 2.00 .0667 2.99 .0319 4.00 .0020 4.99 .0052 5.03 .0002)) (define vl-e7 '( 1.01 .1110 2.02 .0588 3.03 .0143 4.04 .0068 5.05 .0011)) (define vl-f7 '( 1.01 .0798 2.02 .0111 3.03 .0125 4.03 .0036 4.50 .0002 5.04 .0001)) (define vl-fs7 '( 1.02 .1071 2.04 .0117 3.06 .0148 4.08 .0092 4.11 .0007 4.13 .0005 4.16 .0003 4.23 .0002 4.24 .0002 4.28 .0002 4.34 .0001 4.39 .0001)) (define vl-g7 '( 1.02 .2741 2.05 .0256 3.07 .0122 4.11 .0002 4.14 .0001)) (define vl-gs7 '( 1.02 .1027 2.05 .0192 3.07 .0091)) (define vl-a7 '( 1.02 .0796 2.04 .0112 3.06 .0030)) (define vl-as7 '( 1.06 .1256)) (define vl-b7 '( 1.08 .1494 3.24 .0003)) (define vl-c8 '( 1.07 .0582 3.25 .0004)) (define vl-cs8 '( 1.08 .0889)) (define vl-d8 '( 1.07 .0573)) ;;; ;;; ;;; ;;; ;;; (define almf-c3 '( 1.01 .0037 2.01 .0482 3.01 .0275 4.01 .0182 5.03 .0047 6.03 .0032 7.03 .0005 8.03 .0050 9.05 .0044 10.02 .0016 11.06 .0011 12.06 .0004 13.06 .0006 14.16 .0001 15.12 .0001 16.12 .0004 17.12 .0004 19.08 .0003 20.11 .0004 23.11 .0002 24.14 .0003 25.14 .0003 27.12 .0002 28.13 .0001 30.17 .0001)) (define almf-cs3 '( 1.01 .0043 2.01 .0357 3.02 .0452 4.01 .0156 5.02 .0152 6.04 .0022 7.04 .0039 8.06 .0078 9.06 .0049 10.09 .0046 11.24 .0004 12.08 .0016 13.09 .0015 14.10 .0021 15.12 .0006 16.12 .0012 17.12 .0002 18.16 .0004 19.16 .0006 20.15 .0006 21.15 .0007 22.16 .0005 23.17 .0005 24.13 .0004 25.48 .0003 26.19 .0002 27.18 .0002 28.20 .0002 30.26 .0001 31.25 .0002 34.23 .0001)) (define almf-d3 '( 1.01 .0052 2.03 .0062 3.01 .0292 4.05 .0043 5.02 .0149 5.97 .0018 7.02 .0016 8.05 .0029 9.04 .0005 10.06 .0012 11.04 .0006 12.12 .0002 13.05 .0005 14.10 .0004 15.08 .0004 15.99 .0001 17.18 .0001 18.07 .0004 19.06 .0001 20.08 .0003 22.11 .0003 24.13 .0002 25.15 .0001 26.12 .0001)) (define almf-ds3 '( 1.01 .0043 2.01 .0532 3.01 .0389 4.00 .0094 5.01 .0031 6.00 .0038 7.00 .0219 8.00 .0122 8.99 .0129 10.00 .0014 11.00 .0021 12.01 .0037 13.01 .0021 14.01 .0017 15.02 .0015 16.01 .0023 17.03 .0024 18.00 .0008 19.03 .0011 20.04 .0003 21.04 .0009 22.04 .0003 23.00 .0012 24.00 .0011 25.01 .0007 27.02 .0002 28.02 .0004 29.03 .0003 30.04 .0002 31.04 .0001 46.55 .0001 48.01 .0001)) (define almf-e3 '( 1.00 .0123 2.00 .0733 2.99 .0330 4.00 .0098 5.00 .0171 6.00 .0013 7.01 .0117 7.99 .0020 9.00 .0044 10.01 .0012 11.01 .0014 12.00 .0021 13.02 .0002 14.02 .0016 15.03 .0012 16.03 .0028 17.02 .0007 18.02 .0019 19.03 .0008 20.04 .0013 21.03 .0005 22.03 .0005 23.03 .0003 24.04 .0003 26.03 .0005 27.04 .0001 28.06 .0001 29.04 .0002)) (define almf-f3 '( 1.00 .0185 2.00 .0813 3.00 .0142 3.99 .0132 5.00 .0066 5.99 .0027 6.93 .0009 8.01 .0042 8.99 .0018 9.97 .0002 10.97 .0010 12.00 .0008 13.00 .0012 13.98 .0003 14.96 .0006 16.00 .0004 17.01 .0005 18.00 .0003 18.98 .0005 19.99 .0002 20.99 .0002 22.00 .0002)) (define almf-fs3 '( 1.01 .0480 2.01 .0778 3.01 .0124 4.01 .0204 5.05 .0008 6.03 .0068 7.05 .0052 8.06 .0017 9.07 .0017 10.05 .0008 11.07 .0010 12.08 .0008 13.11 .0002 14.08 .0006 15.10 .0002 16.09 .0013 17.12 .0003 18.10 .0003 19.11 .0004 20.14 .0001 23.17 .0001)) (define almf-g3 '( 1.00 .0526 2.00 .0242 2.99 .0351 3.99 .0076 4.98 .0062 5.99 .0085 6.99 .0061 8.04 .0006 8.98 .0005 10.01 .0006 10.97 .0003 11.96 .0004 13.07 .0004 13.95 .0003 14.99 .0003 15.20 .0002 17.93 .0002 18.02 .0002 24.96 .0001)) (define almf-gs3 '( .99 .0523 1.99 .0560 2.98 .0166 3.98 .0183 4.96 .0005 5.98 .0066 6.99 .0026 7.96 .0011 8.95 .0013 9.95 .0026 10.95 .0019 11.96 .0017 12.94 .0005 13.92 .0002 14.94 .0006 15.95 .0007 16.94 .0007 17.96 .0002 18.92 .0002 19.93 .0002 20.92 .0002 21.94 .0001)) (define almf-a3 '( 1.00 .1590 2.00 .0394 3.02 .0076 3.99 .0222 5.00 .0063 5.93 .0008 6.97 .0016 7.95 .0002 8.94 .0002 9.94 .0003 10.05 .0002 10.15 .0001 12.00 .0005 12.12 .0002 12.95 .0001 15.98 .0002)) (define almf-as3 '( 1.00 .2533 2.00 .0498 3.00 .0178 3.99 .0108 5.00 .0245 6.00 .0112 6.99 .0066 8.00 .0010 8.98 .0074 9.99 .0042 10.99 .0025 12.00 .0015 13.01 .0006 14.00 .0012 15.00 .0004 16.02 .0004 17.00 .0010 18.00 .0005 18.99 .0002 19.98 .0002)) (define almf-b3 '( 1.00 .1639 2.00 .0436 3.01 .0584 4.01 .0080 5.01 .0117 6.01 .0208 7.02 .0062 8.02 .0035 9.03 .0037 10.03 .0022 11.04 .0023 12.04 .0048 13.04 .0022 14.04 .0005 15.04 .0007 16.05 .0012 17.05 .0010 18.06 .0005 19.05 .0001 20.06 .0005 21.07 .0002 24.07 .0002 25.08 .0002 27.08 .0002 28.10 .0001 33.12 .0001)) (define almf-c4 '( 1.00 .0931 2.00 .0251 3.00 .0077 4.00 .0129 5.00 .0115 6.00 .0055 7.00 .0041 8.01 .0046 9.00 .0013 10.00 .0067 11.02 .0011 12.02 .0021 12.99 .0002 14.01 .0007 15.02 .0008 16.03 .0007 17.02 .0004 19.02 .0003 20.05 .0001 24.04 .0001)) (define almf-cs4 '( 1.01 .0587 2.01 .0263 3.02 .0299 4.03 .0306 5.04 .0172 6.04 .0097 7.05 .0024 8.06 .0034 9.06 .0053 10.07 .0065 11.08 .0025 12.09 .0005 13.10 .0016 14.11 .0011 15.11 .0009 16.12 .0004 17.13 .0002 18.13 .0003 21.15 .0002 23.17 .0001 24.18 .0001 25.19 .0002 30.23 .0001 32.25 .0001)) (define almf-d4 '( 1.00 .0619 2.00 .0432 3.01 .0479 4.01 .0136 5.00 .0220 6.01 .0064 7.02 .0138 8.02 .0033 9.02 .0066 10.06 .0006 11.02 .0019 12.01 .0013 13.02 .0008 14.01 .0004 15.03 .0007 16.04 .0003 17.03 .0001 18.02 .0001 21.04 .0003)) (define almf-ds4 '( 1.00 .0762 1.99 .0071 2.99 .0085 3.99 .0120 4.98 .0064 5.98 .0018 6.98 .0039 7.99 .0027 8.96 .0017 9.95 .0007 10.98 .0006 11.95 .0003 12.98 .0006 13.98 .0007 15.97 .0002 19.96 .0001)) (define almf-e4 '( .99 .0726 1.99 .0195 2.99 .0147 3.98 .0106 4.99 .0069 6.00 .0026 6.99 .0046 7.99 .0105 8.97 .0017 10.01 .0007 10.97 .0022 11.99 .0009 12.99 .0011 13.98 .0001 14.96 .0002 15.96 .0001 16.99 .0001 17.95 .0002 18.98 .0002 20.98 .0001 21.97 .0001)) (define almf-f4 '( 1.00 .0772 2.00 .0150 3.00 .0166 4.01 .0118 4.99 .0024 6.01 .0067 7.03 .0017 8.00 .0012 9.02 .0017 10.02 .0011 11.03 .0008 12.04 .0004 13.04 .0007 14.03 .0002 15.04 .0002 16.04 .0001)) (define almf-fs4 '( .99 .1309 1.99 .0550 2.98 .0321 3.98 .0270 4.97 .0070 5.97 .0099 6.96 .0041 7.96 .0033 8.95 .0023 9.94 .0017 10.94 .0023 11.93 .0015 12.93 .0006 13.95 .0002 14.93 .0002 15.91 .0002 16.91 .0003 17.92 .0001 18.90 .0003 19.93 .0001 22.87 .0001 23.88 .0001)) (define almf-g4 '( .99 .0515 2.00 .0153 3.00 .0281 4.00 .0071 5.01 .0020 6.00 .0045 7.02 .0006 8.00 .0054 8.99 .0020 10.00 .0031 11.01 .0023 12.02 .0003 13.00 .0004 14.01 .0002 15.02 .0003 15.98 .0002 16.02 .0002 18.03 .0002 19.01 .0001)) (define almf-gs4 '( 1.00 .0592 2.00 .0287 3.00 .0196 3.99 .0175 4.99 .0168 6.00 .0071 6.07 .0008 7.00 .0003 7.99 .0019 8.98 .0007 9.98 .0012 10.99 .0012 11.98 .0004 12.98 .0003 13.99 .0002 14.96 .0001 15.98 .0001 16.97 .0002 17.96 .0002)) (define almf-a4 '( 1.01 .0784 2.01 .0480 3.02 .0131 4.02 .0074 5.03 .0141 6.03 .0173 7.04 .0070 8.04 .0033 9.06 .0154 9.12 .0016 10.07 .0011 11.07 .0013 12.07 .0009 13.09 .0008 14.07 .0006 15.09 .0002 16.10 .0005 17.10 .0003 19.12 .0001 23.14 .0001)) (define almf-as4 '( 1.00 .0507 2.00 .0304 3.00 .0303 4.00 .0084 5.00 .0072 6.00 .0098 6.99 .0058 8.01 .0036 9.01 .0023 10.00 .0010 11.00 .0008 12.00 .0007 12.97 .0005 13.02 .0004 14.00 .0003 14.99 .0003 16.01 .0001 17.01 .0002 18.00 .0001 20.01 .0001)) (define almf-b4 '( 1.00 .0340 2.00 .0113 3.01 .0098 4.02 .0033 5.03 .0013 6.05 .0008 7.02 .0007 8.07 .0006 9.01 .0001)) (define almf-c5 '( 1.00 .0384 2.00 .0426 3.01 .0092 4.02 .0239 5.02 .0184 6.02 .0031 7.03 .0029 8.04 .0016 8.10 .0006 9.04 .0005 10.04 .0003 11.05 .0006 12.05 .0007 13.06 .0002 15.07 .0002)) (define almf-cs5 '( 1.00 .0159 2.00 .0592 3.00 .0390 4.00 .0272 5.00 .0121 6.00 .0032 7.01 .0124 8.01 .0055 9.00 .0009 10.01 .0016 11.01 .0007 12.01 .0006 13.02 .0020 14.02 .0010 15.02 .0007 16.03 .0004 17.03 .0002 18.02 .0001 19.03 .0001 20.03 .0003 21.03 .0002 22.03 .0003 23.03 .0002)) (define almf-d5 '( 1.01 .0376 2.01 .0409 3.02 .0136 4.03 .0016 5.05 .0080 6.05 .0044 7.06 .0036 8.07 .0018 9.07 .0007 10.08 .0011 11.09 .0002 12.09 .0004 13.12 .0003 14.11 .0001 16.15 .0002 17.16 .0001 20.18 .0001)) (define almf-ds5 '( 1.00 .0391 2.01 .0445 3.01 .0188 4.02 .0329 5.02 .0185 6.02 .0311 7.03 .0107 8.03 .0032 9.03 .0010 10.03 .0009 11.04 .0019 12.04 .0019 13.05 .0005 14.06 .0004 15.05 .0007 16.06 .0002 17.07 .0002 18.08 .0002 19.07 .0005 20.07 .0003 21.08 .0001)) (define almf-e5 '( 1.00 .0869 2.00 .0181 3.01 .0252 4.01 .0520 5.01 .0040 6.02 .0336 7.02 .0108 8.03 .0070 9.03 .0023 10.03 .0009 11.03 .0017 12.02 .0004 13.04 .0012 14.04 .0006 15.05 .0016 16.06 .0007 17.06 .0003 18.06 .0012 19.07 .0001 20.06 .0001)) (define almf-f5 '( 1.01 .0905 2.02 .0649 3.02 .0406 4.03 .0295 5.04 .0038 6.05 .0088 7.06 .0009 8.07 .0021 9.07 .0037 10.09 .0022 11.09 .0014 12.09 .0018 13.11 .0006 14.12 .0009 15.13 .0004 16.12 .0003 17.14 .0006 18.15 .0002)) (define almf-fs5 '( .99 .0868 1.98 .0447 2.98 .0303 3.97 .0092 4.96 .0183 5.95 .0121 6.94 .0033 7.95 .0010 8.92 .0022 9.92 .0007 10.91 .0007 11.90 .0007 12.89 .0014 13.87 .0004 14.88 .0006 14.91 .0003 15.87 .0002 16.85 .0003)) (define almf-g5 '( 1.00 .0467 2.00 .0739 3.00 .0255 4.00 .0277 5.00 .0349 6.00 .0119 7.00 .0024 8.00 .0085 9.00 .0016 9.99 .0012 11.00 .0004 11.99 .0014 12.99 .0024 13.99 .0017 14.99 .0007 15.99 .0004 16.98 .0001)) (define almf-gs5 '( .99 .0605 1.99 .0384 2.98 .0154 3.98 .0036 4.97 .0164 5.96 .0039 6.96 .0036 7.95 .0040 8.94 .0012 9.94 .0006 10.93 .0015 11.93 .0012 12.93 .0008 13.91 .0010 14.90 .0005 15.91 .0001)) (define almf-a5 '( 1.00 .1051 2.01 .0322 3.02 .0393 4.03 .0112 5.03 .0099 6.04 .0074 7.05 .0054 8.05 .0030 9.06 .0019 10.07 .0006 11.07 .0023 12.08 .0004 13.08 .0005 14.09 .0006 14.11 .0001 15.11 .0001)) (define almf-as5 '( 1.00 .0284 2.01 .0161 3.02 .0248 4.03 .0414 5.03 .0135 6.04 .0028 7.05 .0021 8.06 .0006 9.07 .0009 10.07 .0010 11.08 .0012 12.10 .0003 13.09 .0010 14.10 .0003)) (define almf-b5 '( .99 .0354 1.98 .0173 2.97 .0086 3.96 .0204 3.99 .0077 4.03 .0067 4.06 .0037 4.95 .0034 5.93 .0030 5.96 .0015 5.98 .0009 6.92 .0007 7.92 .0008 8.91 .0017 9.90 .0008 9.93 .0006 10.88 .0003 11.91 .0003 12.86 .0004 12.90 .0002)) (define almf-c6 '( 1.01 .0675 2.01 .0578 3.02 .0346 4.03 .0170 5.03 .0082 6.04 .0050 7.06 .0032 8.03 .0009 9.06 .0009 10.07 .0008 11.09 .0010 12.03 .0002)) (define almf-cs6 '( 1.00 .0896 1.99 .0634 3.01 .0037 3.98 .0105 4.98 .0030 5.98 .0019 6.97 .0020 7.97 .0014 8.00 .0007 8.99 .0005 9.96 .0005 10.95 .0008 10.98 .0005 11.00 .0003 11.02 .0003 11.03 .0002 11.06 .0002 11.95 .0001 11.98 .0001)) (define almf-d6 '( 1.00 .0593 2.00 .0364 3.01 .0142 4.01 .0065 5.02 .0063 6.01 .0024 7.02 .0010 8.02 .0019 9.02 .0015 10.03 .0007 11.02 .0002)) (define almf-ds6 '( 1.00 .0410 1.99 .0353 2.99 .0291 3.99 .0089 4.99 .0066 5.98 .0023 6.99 .0012 7.96 .0011 7.99 .0006 8.94 .0004 8.98 .0003 9.95 .0001)) (define almf-e6 '( 1.01 .0254 2.01 .0252 3.02 .0365 4.03 .0034 5.02 .0013 6.02 .0010 7.08 .0006 8.02 .0010 9.03 .0007 9.12 .0004)) (define almf-f6 '( 1.00 .1896 2.00 .0411 3.00 .0216 4.00 .0019 5.00 .0032 6.01 .0012 7.02 .0007 7.99 .0026 9.00 .0003 9.03 .0002)) (define almf-fs6 '( 1.01 .0285 2.01 .0189 3.02 .0213 4.02 .0033 5.03 .0024 6.03 .0010 7.04 .0016 8.05 .0015 9.05 .0003 9.06 .0002)) (define almf-g6 '( 1.00 .1939 2.00 .0339 3.00 .0219 4.01 .0079 5.01 .0025 6.01 .0017 7.01 .0014 7.95 .0009 8.00 .0006 8.02 .0003)) (define almf-gs6 '( 1.00 .1069 2.00 .0146 3.00 .0220 4.00 .0046 5.00 .0020 6.00 .0027 6.99 .0011 8.00 .0003)) (define almf-a6 '( 1.00 .0952 1.99 .0201 3.00 .0015 3.99 .0064 4.98 .0021 5.97 .0009 6.98 .0010)) (define almf-as6 '( 1.00 .0132 1.99 .0635 2.99 .0057 3.98 .0054 3.99 .0034 4.99 .0011 5.96 .0012 5.98 .0008 5.99 .0007 6.96 .0004 6.98 .0004)) (define almf-b6 '( 1.00 .0241 2.01 .0417 3.02 .0098 3.99 .0016 4.02 .0016 5.03 .0016 6.04 .0012)) ;;; ;;; ;;; ;;; ;;; snd-16.1/snd-gsnd.c0000644000076400007640000024316712512761107012233 0ustar bilbil#include "snd.h" /* gtk's paned window is so buggy that perhaps I should simply replace all of them * with boxes. Especially the control panel. */ #define sound_env_editor(Sp) ((env_editor *)(sp->flt)) enum {W_pane, W_pane_box, W_control_panel, W_name_form, W_name, W_name_event, W_name_pix, W_stop_pix, W_info, W_play, W_sync, W_unite, W_close, W_amp_form, W_amp_event, W_amp, W_amp_label, W_amp_number, W_amp_sep, W_speed_form, W_speed, W_speed_event, W_speed_label, W_speed_label_event, W_speed_number, W_speed_pix, W_expand_form, W_expand, W_expand_event, W_expand_label, W_expand_number, W_expand_button, W_contrast_form, W_contrast, W_contrast_event, W_contrast_label, W_contrast_number, W_contrast_button, W_reverb_form, W_revscl, W_revscl_event, W_revscl_label, W_revscl_number, W_revlen, W_revlen_event, W_revlen_label, W_revlen_number, W_reverb_button, W_filter_form, W_filter_label, W_filter_order, W_filter_env, W_filter, W_filter_button, W_filter_dB, W_filter_hz, W_filter_frame, NUM_SND_WIDGETS }; enum {W_amp_adj, W_speed_adj, W_contrast_adj, W_expand_adj, W_revscl_adj, W_revlen_adj, W_filter_adj, NUM_SND_ADJS }; GtkWidget *unite_button(snd_info *sp) {return(sp->snd_widgets[W_unite]);} GtkWidget *w_snd_pane(snd_info *sp) {return(sp->snd_widgets[W_pane]);} GtkWidget *w_snd_pane_box(snd_info *sp) {return(sp->snd_widgets[W_pane_box]);} #define SND_PANE(Sp) Sp->snd_widgets[W_pane] #define PANE_BOX(Sp) Sp->snd_widgets[W_pane_box] #define NAME_HBOX(Sp) Sp->snd_widgets[W_name_form] #define NAME_BUTTON(Sp) Sp->snd_widgets[W_name] #define NAME_EVENT_BOX(Sp) Sp->snd_widgets[W_name_event] #define NAME_SEPARATOR(Sp) Sp->snd_widgets[W_amp_sep] #define CLOSE_BUTTON(Sp) Sp->snd_widgets[W_close] #define STATUS_AREA(Sp) Sp->snd_widgets[W_info] #define NAME_PIX(Sp) Sp->snd_widgets[W_name_pix] #define STOP_PIX(Sp) Sp->snd_widgets[W_stop_pix] #define SYNC_BUTTON(Sp) Sp->snd_widgets[W_sync] #define PLAY_BUTTON(Sp) Sp->snd_widgets[W_play] #define UNITE_BUTTON(Sp) Sp->snd_widgets[W_unite] #define CLOCK_PIX(Sp, Chan) Sp->clock_widgets[Chan] #define CONTROL_PANEL(Sp) Sp->snd_widgets[W_control_panel] #define AMP_HBOX(Sp) Sp->snd_widgets[W_amp_form] #define AMP_LABEL(Sp) Sp->snd_widgets[W_amp_number] #define AMP_BUTTON(Sp) Sp->snd_widgets[W_amp_label] #define AMP_EVENT_BOX(Sp) Sp->snd_widgets[W_amp_event] #define AMP_SCROLLBAR(Sp) Sp->snd_widgets[W_amp] #define SPEED_HBOX(Sp) Sp->snd_widgets[W_speed_form] #define SPEED_ARROW(Sp) Sp->snd_widgets[W_speed_pix] #define SPEED_LABEL(Sp) Sp->snd_widgets[W_speed_number] #define SPEED_EVENT_BOX(Sp) Sp->snd_widgets[W_speed_event] #define SPEED_LABEL_EVENT_BOX(Sp) Sp->snd_widgets[W_speed_label_event] #define SPEED_BUTTON(Sp) Sp->snd_widgets[W_speed_label] #define SPEED_SCROLLBAR(Sp) Sp->snd_widgets[W_speed] #define EXPAND_HBOX(Sp) Sp->snd_widgets[W_expand_form] #define EXPAND_LEFT_BUTTON(Sp) Sp->snd_widgets[W_expand_label] #define EXPAND_EVENT_BOX(Sp) Sp->snd_widgets[W_expand_event] #define EXPAND_SCROLLBAR(Sp) Sp->snd_widgets[W_expand] #define EXPAND_LABEL(Sp) Sp->snd_widgets[W_expand_number] #define EXPAND_RIGHT_BUTTON(Sp) Sp->snd_widgets[W_expand_button] #define CONTRAST_HBOX(Sp) Sp->snd_widgets[W_contrast_form] #define CONTRAST_LEFT_BUTTON(Sp) Sp->snd_widgets[W_contrast_label] #define CONTRAST_EVENT_BOX(Sp) Sp->snd_widgets[W_contrast_event] #define CONTRAST_SCROLLBAR(Sp) Sp->snd_widgets[W_contrast] #define CONTRAST_LABEL(Sp) Sp->snd_widgets[W_contrast_number] #define CONTRAST_RIGHT_BUTTON(Sp) Sp->snd_widgets[W_contrast_button] #define REVSCL_EVENT_BOX(Sp) Sp->snd_widgets[W_revscl_event] #define REVSCL_SCROLLBAR(Sp) Sp->snd_widgets[W_revscl] #define REVSCL_BUTTON(Sp) Sp->snd_widgets[W_revscl_label] #define REVSCL_LABEL(Sp) Sp->snd_widgets[W_revscl_number] #define REVLEN_EVENT_BOX(Sp) Sp->snd_widgets[W_revlen_event] #define REVLEN_BUTTON(Sp) Sp->snd_widgets[W_revlen_label] #define REVLEN_SCROLLBAR(Sp) Sp->snd_widgets[W_revlen] #define REVLEN_LABEL(Sp) Sp->snd_widgets[W_revlen_number] #define REVERB_RIGHT_BUTTON(Sp) Sp->snd_widgets[W_reverb_button] #define REVERB_HBOX(Sp) Sp->snd_widgets[W_reverb_form] #define FILTER_HBOX(Sp) Sp->snd_widgets[W_filter_form] #define FILTER_LEFT_BUTTON(Sp) Sp->snd_widgets[W_filter_label] #define FILTER_ORDER_TEXT(Sp) Sp->snd_widgets[W_filter_order] #define FILTER_COEFFS_TEXT(Sp) Sp->snd_widgets[W_filter] #define FILTER_RIGHT_BUTTON(Sp) Sp->snd_widgets[W_filter_button] #define FILTER_DB_BUTTON(Sp) Sp->snd_widgets[W_filter_dB] #define FILTER_HZ_BUTTON(Sp) Sp->snd_widgets[W_filter_hz] #define FILTER_FRAME(Sp) Sp->snd_widgets[W_filter_frame] #define FILTER_ENV(Sp) Sp->snd_widgets[W_filter_env] #define AMP_ADJUSTMENT(Sp) Sp->snd_adjs[W_amp_adj] #define SPEED_ADJUSTMENT(Sp) Sp->snd_adjs[W_speed_adj] #define EXPAND_ADJUSTMENT(Sp) Sp->snd_adjs[W_expand_adj] #define CONTRAST_ADJUSTMENT(Sp) Sp->snd_adjs[W_contrast_adj] #define REVSCL_ADJUSTMENT(Sp) Sp->snd_adjs[W_revscl_adj] #define REVLEN_ADJUSTMENT(Sp) Sp->snd_adjs[W_revlen_adj] #define FILTER_ADJUSTMENT(Sp) Sp->snd_adjs[W_filter_adj] static bool mini_lock_allocated = false; static picture_t *mini_lock = NULL, *speed_r = NULL, *speed_l = NULL, *blank = NULL, *stop_sign = NULL; static picture_t *bomb = NULL; void show_lock(snd_info *sp) { if (mini_lock) { draw_picture(sp->name_pix_ax, mini_lock, 0, 0, 0, 0, 16, 16); gtk_widget_show(NAME_PIX(sp)); } } void hide_lock(snd_info *sp) { if (mini_lock) gtk_widget_hide(NAME_PIX(sp)); } static void show_stop_sign(snd_info *sp) { if (!has_widgets(sp)) return; if (stop_sign) draw_picture(sp->stop_pix_ax, stop_sign, 0, 0, 0, 0, 16, 16); gtk_widget_show(STOP_PIX(sp)); } static void hide_stop_sign(snd_info *sp) { if (!has_widgets(sp)) return; gtk_widget_hide(STOP_PIX(sp)); } static void show_bomb(snd_info *sp) { if (!has_widgets(sp)) return; draw_picture(sp->name_pix_ax, bomb, 0, 0, 0, 0, 16, 16); gtk_widget_show(NAME_PIX(sp)); } static void hide_bomb(snd_info *sp) { if (!has_widgets(sp)) return; gtk_widget_hide(NAME_PIX(sp)); } #define BOMB_TIME 200 static gint tick_bomb(gpointer data) { snd_info *sp = (snd_info *)data; if (!has_widgets(sp)) return(0); if (sp->need_update || sp->file_unreadable) { show_bomb(sp); g_timeout_add_full(0, (guint32)BOMB_TIME, tick_bomb, data, NULL); } else { hide_bomb(sp); sp->bomb_in_progress = false; } return(0); } void start_bomb(snd_info *sp) { if (!has_widgets(sp)) return; if (!(sp->bomb_in_progress)) { sp->bomb_in_progress = true; g_timeout_add_full(0, (guint32)BOMB_TIME, tick_bomb, (gpointer)sp, NULL); } } void stop_bomb(snd_info *sp) { if (!has_widgets(sp)) return; hide_bomb(sp); sp->bomb_in_progress = false; } static Drawable *sound_pix_wn(chan_info *cp) { snd_info *sp = NULL; if (cp) sp = cp->sound; if (!has_widgets(sp)) return(NULL); if ((cp->chan < sp->num_clock_widgets) && (CLOCK_PIX(sp, cp->chan)) && (sp->clock_pix_ax[cp->chan])) return(DRAWABLE(WIDGET_TO_WINDOW(CLOCK_PIX(sp, cp->chan)))); return(DRAWABLE(WIDGET_TO_WINDOW(CLOCK_PIX(sp, 0)))); } static void show_happy_face(Drawable *wn, mus_float_t pct) { cairo_t *cr; cr = make_cairo(wn); /* overall background */ cairo_translate(cr, 0, 0); cairo_push_group(cr); cairo_set_source_rgba(cr, ss->basic_color->red, ss->basic_color->green, ss->basic_color->blue, ss->basic_color->alpha); cairo_rectangle(cr, 0, 0, 16, 16); cairo_fill(cr); /* round face */ cairo_set_source_rgb(cr, 1.0, pct, 0.0); cairo_arc(cr, 8, 8, 8, 0.0, 2 * M_PI); cairo_fill(cr); /* eyes */ cairo_set_source_rgb(cr, 0.0, 0.0, 0.0); cairo_arc(cr, 5, 6, 1.5, 0, 2 * M_PI); cairo_fill(cr); cairo_arc(cr, 11, 6, 1.5, 0, 2 * M_PI); cairo_fill(cr); /* mouth */ cairo_set_line_width(cr, 1.0); if (pct < 0.2) cairo_arc(cr, 8, 14, 4, 17.0/16.0 * M_PI, -1.0/16.0 * M_PI); else if (pct < 0.35) cairo_arc(cr, 8, 14, 4, 18.3/16.0 * M_PI, -2.3/16.0 * M_PI); else if (pct < 0.5) cairo_arc(cr, 8, 14, 4, 19.0/16.0 * M_PI, -3.0/16.0 * M_PI); else if (pct < 0.6) { cairo_move_to(cr, 4, 12); cairo_rel_line_to(cr, 8, 0); } else if (pct < 0.75) cairo_arc(cr, 8, 7, 5, 4.00/16.0 * M_PI, 12.0/16.0 * M_PI); else if (pct < 0.9) cairo_arc(cr, 8, 7, 5, 3.0/16.0 * M_PI, 13.0/16.0 * M_PI); else cairo_arc(cr, 8, 8, 5, 1.0/16.0 * M_PI, 15.0/16.0 * M_PI); cairo_stroke(cr); cairo_pop_group_to_source(cr); cairo_paint(cr); free_cairo(cr); } static void hide_happy_face(Drawable *wn) { cairo_t *cr; cr = make_cairo(wn); cairo_set_source_rgba(cr, ss->basic_color->red, ss->basic_color->green, ss->basic_color->blue, ss->basic_color->alpha); cairo_rectangle(cr, 0, 0, 24, 24); cairo_fill(cr); free_cairo(cr); } static void make_pixmaps(void) { if (!mini_lock_allocated) { mini_lock = snd_icon(SND_PNG_LOCK); stop_sign = snd_icon(SND_PNG_STOP); blank = snd_icon(SND_PNG_BLANK); speed_r = snd_icon(SND_PNG_RIGHT_ARROW); speed_l = snd_icon(SND_PNG_LEFT_ARROW); bomb = snd_icon(SND_PNG_BOMB); mini_lock_allocated = true; } } /* lock stop blank bomb as 16x16 * bomb (warning) is also 22x22 24x24 32x32 * lock (changes-prevent) and stop (stop) also * but 24x24 doesn't look larger? */ static gboolean name_pix_expose(GtkWidget *w, GdkEventExpose *ev, gpointer data) { snd_info *sp = (snd_info *)data; if ((has_widgets(sp)) && (NAME_PIX(sp)) && (sp->name_pix_ax)) { if ((sp->user_read_only == FILE_READ_ONLY) || (sp->file_read_only == FILE_READ_ONLY)) draw_picture(sp->name_pix_ax, mini_lock, 0, 0, 0, 0, 16, 16); else draw_picture(sp->name_pix_ax, blank, 0, 0, 0, 0, 16, 16); } return(false); } static gboolean clock_pix_expose(GtkWidget *w, GdkEventExpose *ev, gpointer data) { chan_info *cp = (chan_info *)data; snd_info *sp = NULL; if (cp) sp = cp->sound; if ((has_widgets(sp)) && (cp->chan < sp->num_clock_widgets) && (CLOCK_PIX(sp, cp->chan)) && (sp->clock_pix_ax[cp->chan])) { if (cp->progress_pct >= 0.0) show_happy_face(sound_pix_wn(cp), cp->progress_pct); else draw_picture(sp->clock_pix_ax[cp->chan], blank, 0, 0, 0, 0, 16, 16); } return(false); } /* -------- STATUS AREA CALLBACKS -------- */ static char stupid[1] = {'\0'}; void set_status(snd_info *sp, const char *str, bool update) { if ((sp->inuse != SOUND_NORMAL) || (!has_widgets(sp))) return; if (str) set_label(STATUS_AREA(sp), str); else set_label(STATUS_AREA(sp), stupid); } /* -------- PLAY BUTTON -------- */ static void set_button_base(GtkWidget *w, color_info *col) { widget_modify_base(w, GTK_STATE_NORMAL, col); widget_modify_base(w, GTK_STATE_PRELIGHT, col); } void set_play_button(snd_info *sp, bool val) { #if WITH_AUDIO if (has_widgets(sp)) set_toggle_button(PLAY_BUTTON(sp), val, false, (void *)sp); #endif } void set_control_panel_play_button(snd_info *sp) { #if WITH_AUDIO if (has_widgets(sp)) { set_toggle_button(PLAY_BUTTON(sp), false, false, sp); set_button_base(PLAY_BUTTON(sp), ss->white); } #endif } #if WITH_AUDIO static int last_play_state = 0; /* these "last-*-state" variables are trying to catch C-M-click info which is then used * presumably by the immediately following value-changed callback for the given button. */ static gboolean play_button_callback(GtkWidget *w, GdkEventButton *ev, gpointer data) { last_play_state = EVENT_STATE(ev); return(false); } static void play_button_click_callback(GtkWidget *w, gpointer data) { snd_info *sp = (snd_info *)data; chan_info *cp; bool on; on = (bool)(TOGGLE_BUTTON_ACTIVE(w)); if (sp->playing) stop_playing_sound_no_toggle(sp, PLAY_BUTTON_UNSET); ss->tracking = ((with_tracking_cursor(ss) != DONT_TRACK) || ((on) && (last_play_state & (snd_ControlMask | snd_MetaMask)))); cp = any_selected_channel(sp); goto_graph(cp); if (on) { if (ss->tracking) set_button_base(w, ss->green); else set_button_base(w, ss->white); play_sound(sp, 0, NO_END_SPECIFIED); } else set_button_base(w, ss->white); } typedef struct {bool pausing; } pause_data; static void set_play_button_pause(snd_info *sp, void *ptr) { if (sp->playing) { pause_data *pd = (pause_data *)ptr; GtkWidget *w; w = PLAY_BUTTON(sp); if (pd->pausing) set_button_base(w, ss->red); else if (ss->tracking) set_button_base(w, ss->green); else set_button_base(w, ss->white); } } #endif void play_button_pause(bool pausing) { #if WITH_AUDIO pause_data *pd; pd = (pause_data *)calloc(1, sizeof(pause_data)); pd->pausing = pausing; for_each_sound_with_void(set_play_button_pause, (void *)pd); free(pd); #endif } static void set_sync_color(snd_info *sp) { GtkWidget *syb; syb = SYNC_BUTTON(sp); switch (sp->sync) { case 0: set_button_base(syb, ss->white); break; case 1: set_button_base(syb, ss->selection_color); break; case 2: set_button_base(syb, ss->green); break; case 3: set_button_base(syb, ss->yellow); break; case 4: set_button_base(syb, ss->red); break; default: set_button_base(syb, ss->black); break; } } void syncb(snd_info *sp, int on) { sp->sync = on; if (on > ss->sound_sync_max) ss->sound_sync_max = on; if (has_widgets(sp)) { set_sync_color(sp); set_toggle_button(SYNC_BUTTON(sp), (on != 0), false, (void *)sp); } } static int last_sync_state = 0; static gboolean sync_button_callback(GtkWidget *w, GdkEventButton *ev, gpointer data) { last_sync_state = EVENT_STATE(ev); return(false); } static void sync_button_click(GtkWidget *w, gpointer data) { snd_info *sp = (snd_info *)data; bool on; on = (bool)(TOGGLE_BUTTON_ACTIVE(w)); if (on) if (last_sync_state & snd_ControlMask) if (last_sync_state & snd_MetaMask) if (last_sync_state & snd_ShiftMask) sp->sync = 4; else sp->sync = 3; else sp->sync = 2; else sp->sync = 1; else sp->sync = 0; set_sync_color(sp); if (sp->sync != 0) { chan_info *cp; if (sp->sync > ss->sound_sync_max) ss->sound_sync_max = sp->sync; cp = sp->lacp; if (cp == NULL) cp = any_selected_channel(sp); goto_graph(cp); if (cp->cursor_on) sync_cursors(cp, cursor_sample(cp)); apply_x_axis_change(cp); } } static int last_combine_state = 0; static gboolean unite_button_callback(GtkWidget *w, GdkEventButton *ev, gpointer data) { /* click if set unsets, click if unset->combine, ctrl-click->superimpose */ last_combine_state = EVENT_STATE(ev); return(false); } static void unite_button_click(GtkWidget *w, gpointer data) { channel_style_t val; bool on; snd_info *sp = (snd_info *)data; on = (bool)(TOGGLE_BUTTON_ACTIVE(w)); if (on) { if (last_combine_state & (snd_ControlMask | snd_MetaMask)) val = CHANNELS_SUPERIMPOSED; else val = CHANNELS_COMBINED; } else val = CHANNELS_SEPARATE; set_sound_channel_style(sp, val); } static gboolean name_click_callback(GtkWidget *w, GdkEventButton *ev, gpointer data) { char *str; snd_info *sp = (snd_info *)data; str = sp_name_click(sp); if (str) { status_report(sp, "%s", str); free(str); } return(false); } static gboolean name_button_tooltip(GtkWidget *w, gint x, gint y, gboolean keyboard_tip, GtkTooltip *tooltip, gpointer data) { char *str; snd_info *sp = (snd_info *)data; str = sp_name_click(sp); if (str) { gtk_tooltip_set_text(tooltip, str); free(str); } else gtk_tooltip_set_text(tooltip, "nothing known about this sound!"); return(true); } /* -------- AMP CALLBACKS -------- */ mus_float_t amp_to_scroll(mus_float_t minval, mus_float_t val, mus_float_t maxval) { if (val <= minval) return(0.0); if (val >= maxval) return(0.9); if (val >= 1.0) return(0.9 * 0.5 * (1.0 + (val - 1.0) / (maxval - 1.0))); return(0.9 * 0.5 * ((val - minval) / (1.0 - minval))); } static mus_float_t scroll_to_amp(snd_info *sp, mus_float_t val) { char amp_number_buffer[6]; if (val <= 0.0) sp->amp_control = sp->amp_control_min; else { if (val >= 0.9) sp->amp_control = sp->amp_control_max; else { if (val > (0.5 * 0.9)) sp->amp_control = (((val / (0.5 * 0.9)) - 1.0) * (sp->amp_control_max - 1.0)) + 1.0; else sp->amp_control = (val * (1.0 - sp->amp_control_min) / (0.5 * 0.9)) + sp->amp_control_min; } } snprintf(amp_number_buffer, 6, "%.3f", sp->amp_control); gtk_label_set_text(GTK_LABEL(AMP_LABEL(sp)), amp_number_buffer); return(val); } void set_amp(snd_info *sp, mus_float_t amp) { if (!has_widgets(sp)) sp->amp_control = amp; else { mus_float_t scrollval; GtkAdjustment *adj; scroll_to_amp(sp, scrollval = amp_to_scroll(sp->amp_control_min, amp, sp->amp_control_max)); adj = AMP_ADJUSTMENT(sp); ADJUSTMENT_SET_VALUE(adj, scrollval); /* gtk_adjustment_value_changed(GTK_ADJUSTMENT(adj)); */ } } static gboolean amp_click_callback(GtkWidget *w, GdkEventButton *ev, gpointer data) { snd_info *sp = (snd_info *)data; if (EVENT_STATE(ev) & (snd_ControlMask | snd_MetaMask)) set_amp(sp, sp->last_amp_control); else set_amp(sp, 1.0); return(false); } static void amp_changed_callback(GtkAdjustment *adj, gpointer data) { scroll_to_amp((snd_info *)data, (mus_float_t)(ADJUSTMENT_VALUE(adj))); } static gboolean amp_release_callback(GtkWidget *w, GdkEventButton *ev, gpointer data) { snd_info *sp = (snd_info *)data; sp->last_amp_control = sp->saved_amp_control; sp->saved_amp_control = sp->amp_control; return(false); } /* -------- SPEED CALLBACKS -------- */ static mus_float_t speed_to_scroll(mus_float_t minval, mus_float_t val, mus_float_t maxval) { if (val <= minval) return(0.0); if (val >= maxval) return(0.9); return(0.9 * ((log(val) - log(minval)) / (log(maxval) - log(minval)))); } static mus_float_t scroll_to_speed(snd_info *sp, mus_float_t ival) { char speed_number_buffer[6]; sp->speed_control = speed_changed(exp((ival * (log(sp->speed_control_max) - log(sp->speed_control_min)) / 0.9) + log(sp->speed_control_min)), speed_number_buffer, sp->speed_control_style, sp->speed_control_tones, 6); gtk_label_set_text(GTK_LABEL(SPEED_LABEL(sp)), speed_number_buffer); return(ival); } static bool ignore_callback = false; void set_speed(snd_info *sp, mus_float_t val) { if (!has_widgets(sp)) sp->speed_control = val; else { GtkAdjustment *adj; adj = SPEED_ADJUSTMENT(sp); ignore_callback = true; ADJUSTMENT_SET_VALUE(adj, scroll_to_speed(sp, speed_to_scroll(sp->speed_control_min, val, sp->speed_control_max))); /* gtk_adjustment_value_changed(GTK_ADJUSTMENT(adj)); */ ignore_callback = false; } } static gboolean speed_click_callback(GtkWidget *w, GdkEventButton *ev, gpointer data) { snd_info *sp = (snd_info *)data; if (EVENT_STATE(ev) & (snd_ControlMask | snd_MetaMask)) set_speed(sp, sp->last_speed_control); else set_speed(sp, 1.0); #if XEN_HAVE_RATIOS if (sp->speed_control_style == SPEED_CONTROL_AS_RATIO) snd_rationalize(sp->speed_control, &(sp->speed_control_numerator), &(sp->speed_control_denominator)); #endif return(false); } static gboolean speed_label_click_callback(GtkWidget *w, GdkEventButton *ev, gpointer data) { snd_info *sp = (snd_info *)data; switch (sp->speed_control_style) { default: case SPEED_CONTROL_AS_FLOAT: sp->speed_control_style = SPEED_CONTROL_AS_RATIO; break; case SPEED_CONTROL_AS_RATIO: sp->speed_control_style = SPEED_CONTROL_AS_SEMITONE; break; case SPEED_CONTROL_AS_SEMITONE: sp->speed_control_style = SPEED_CONTROL_AS_FLOAT; break; } set_speed(sp, sp->speed_control); /* remake label */ return(false); } static void speed_changed_callback(GtkAdjustment *adj, gpointer data) { snd_info *sp = (snd_info *)data; if (ignore_callback) return; scroll_to_speed(sp, ADJUSTMENT_VALUE(adj)); #if XEN_HAVE_RATIOS if (sp->speed_control_style == SPEED_CONTROL_AS_RATIO) snd_rationalize(sp->speed_control, &(sp->speed_control_numerator), &(sp->speed_control_denominator)); #endif } static gboolean speed_release_callback(GtkWidget *w, GdkEventButton *ev, gpointer data) { snd_info *sp = (snd_info *)data; sp->last_speed_control = sp->saved_speed_control; sp->saved_speed_control = sp->speed_control; return(false); } static void draw_speed_arrow(snd_info *sp) { if (sp->speed_control_direction == 1) draw_picture(sp->speed_arrow_ax, speed_r, 0, 0, 0, 0, 16, 16); else draw_picture(sp->speed_arrow_ax, speed_l, 0, 0, 0, 0, 16, 16); } static gboolean speed_arrow_press(GtkWidget *w, GdkEventButton *ev, gpointer data) { snd_info *sp = (snd_info *)data; if (sp->speed_control_direction == 1) sp->speed_control_direction = -1; else sp->speed_control_direction = 1; gtk_widget_hide(SPEED_ARROW(sp)); gtk_widget_show(SPEED_ARROW(sp)); /* draw_speed_arrow(sp); */ return(false); } static gboolean speed_arrow_expose(GtkWidget *w, GdkEventExpose *ev, gpointer data) { draw_speed_arrow((snd_info *)data); return(false); } void toggle_direction_arrow(snd_info *sp, bool state) { /* this is part of the apply-controls junk */ int dir = 1; if (state) dir = -1; sp->speed_control_direction = dir; if (has_widgets(sp)) draw_speed_arrow(sp); } /* -------- EXPAND CALLBACKS -------- */ static mus_float_t expand_to_scroll(mus_float_t minval, mus_float_t val, mus_float_t maxval) { if (val <= minval) return(0.0); if (val >= maxval) return(0.9); return(0.9 * ((log(val) - log(minval)) / (log(maxval) - log(minval)))); } static mus_float_t scroll_to_expand(snd_info *sp, mus_float_t val) { char expand_number_buffer[6]; if (val <= 0.0) sp->expand_control = sp->expand_control_min; else { if (val >= 0.9) sp->expand_control = sp->expand_control_max; else sp->expand_control = exp((val * (log(sp->expand_control_max) - log(sp->expand_control_min)) / 0.9) + log(sp->expand_control_min)); } if (sp->playing) dac_set_expand(sp, sp->expand_control); snprintf(expand_number_buffer, 6, "%.3f", sp->expand_control); gtk_label_set_text(GTK_LABEL(EXPAND_LABEL(sp)), expand_number_buffer); return(val); } void set_expand(snd_info *sp, mus_float_t val) { if (!has_widgets(sp)) sp->expand_control = val; else { GtkAdjustment *adj; adj = EXPAND_ADJUSTMENT(sp); ignore_callback = true; ADJUSTMENT_SET_VALUE(adj, scroll_to_expand(sp, expand_to_scroll(sp->expand_control_min, val, sp->expand_control_max))); /* gtk_adjustment_value_changed(GTK_ADJUSTMENT(adj)); */ ignore_callback = false; } } static void expand_changed_callback(GtkAdjustment *adj, gpointer data) { if (ignore_callback) return; scroll_to_expand((snd_info *)data, ADJUSTMENT_VALUE(adj)); } static gboolean expand_release_callback(GtkWidget *w, GdkEventButton *ev, gpointer data) { snd_info *sp = (snd_info *)data; sp->last_expand_control = sp->saved_expand_control; sp->saved_expand_control = sp->expand_control; return(false); } static gboolean expand_click_callback(GtkWidget *w, GdkEventButton *ev, gpointer data) { snd_info *sp = (snd_info *)data; if (EVENT_STATE(ev) & (snd_ControlMask | snd_MetaMask)) set_expand(sp, sp->last_expand_control); else set_expand(sp, 1.0); return(false); } static void expand_button_callback(GtkWidget *w, gpointer context) { snd_info *sp = (snd_info *)context; sp->expand_control_on = TOGGLE_BUTTON_ACTIVE(w); /* to change the trough color: (widget_modify_bg (list-ref (channel-widgets) 3) GTK_STATE_ACTIVE (zoom-color)) */ /* and the slider color: (widget_modify_bg (list-ref (channel-widgets) 3) GTK_STATE_PRELIGHT (highlight-color)) */ } void toggle_expand_button(snd_info *sp, bool state) { if (!has_widgets(sp)) sp->expand_control_on = state; else set_toggle_button(EXPAND_RIGHT_BUTTON(sp), state, true, (void *)sp); } /* -------- CONTRAST CALLBACKS -------- */ static mus_float_t contrast_to_scroll(mus_float_t minval, mus_float_t val, mus_float_t maxval) { if (val <= minval) return(0.0); if (val >= maxval) return(0.9); return((val - minval) / (maxval - minval) * 0.9); } static mus_float_t scroll_to_contrast(snd_info *sp, mus_float_t val) { char contrast_number_buffer[6]; sp->contrast_control = sp->contrast_control_min + val * (sp->contrast_control_max - sp->contrast_control_min) / 0.9; snprintf(contrast_number_buffer, 6, "%.3f", sp->contrast_control); gtk_label_set_text(GTK_LABEL(CONTRAST_LABEL(sp)), contrast_number_buffer); return(val); } void set_contrast(snd_info *sp, mus_float_t val) { if (!has_widgets(sp)) sp->contrast_control = val; else { GtkAdjustment *adj; adj = CONTRAST_ADJUSTMENT(sp); ignore_callback = true; ADJUSTMENT_SET_VALUE(adj, scroll_to_contrast(sp, contrast_to_scroll(sp->contrast_control_min, val, sp->contrast_control_max))); /* gtk_adjustment_value_changed(GTK_ADJUSTMENT(adj)); */ ignore_callback = false; } } static gboolean contrast_click_callback(GtkWidget *w, GdkEventButton *ev, gpointer data) { snd_info *sp = (snd_info *)data; if (EVENT_STATE(ev) & (snd_ControlMask | snd_MetaMask)) set_contrast(sp, sp->last_contrast_control); else set_contrast(sp, 0.0); return(false); } static void contrast_changed_callback(GtkAdjustment *adj, gpointer data) { snd_info *sp = (snd_info *)data; if (ignore_callback) return; scroll_to_contrast(sp, ADJUSTMENT_VALUE(adj)); } static gboolean contrast_release_callback(GtkWidget *w, GdkEventButton *ev, gpointer data) { snd_info *sp = (snd_info *)data; sp->last_contrast_control = sp->saved_contrast_control; sp->saved_contrast_control = sp->contrast_control; return(false); } static void contrast_button_callback(GtkWidget *w, gpointer context) { snd_info *sp = (snd_info *)context; sp->contrast_control_on = TOGGLE_BUTTON_ACTIVE(w); } void toggle_contrast_button(snd_info *sp, bool state) { if (!has_widgets(sp)) sp->contrast_control_on = state; else set_toggle_button(CONTRAST_RIGHT_BUTTON(sp), state, true, (void *)sp); } /* -------- REVERB CALLBACKS -------- */ static mus_float_t revscl_to_scroll(mus_float_t minval, mus_float_t val, mus_float_t maxval) { if (val <= minval) return(0.0); if (val >= maxval) return(0.9); return(0.9 * (pow(val, 0.333) - pow(minval, 0.333)) / (pow(maxval, 0.333) - pow(minval, 0.333))); } static mus_float_t cube(mus_float_t a) {return(a*a*a);} static mus_float_t scroll_to_revscl(snd_info *sp, mus_float_t val) { char revscl_number_buffer[7]; if (val <= 0.0) sp->reverb_control_scale = sp->reverb_control_scale_min; else { if (val >= 0.9) sp->reverb_control_scale = sp->reverb_control_scale_max; else sp->reverb_control_scale = cube((val * (pow(sp->reverb_control_scale_max, 0.333) - pow(sp->reverb_control_scale_min, 0.333)) / 0.9) + pow(sp->reverb_control_scale_min, 0.333)); } snprintf(revscl_number_buffer, 7, "%.4f", sp->reverb_control_scale); gtk_label_set_text(GTK_LABEL(REVSCL_LABEL(sp)), revscl_number_buffer); return(val); } void set_revscl(snd_info *sp, mus_float_t val) { if (!has_widgets(sp)) sp->reverb_control_scale = val; else { GtkAdjustment *adj; adj = REVSCL_ADJUSTMENT(sp); ignore_callback = true; ADJUSTMENT_SET_VALUE(adj, scroll_to_revscl(sp, revscl_to_scroll(sp->reverb_control_scale_min, val, sp->reverb_control_scale_max))); /* gtk_adjustment_value_changed(GTK_ADJUSTMENT(adj)); */ ignore_callback = false; } } static gboolean revscl_click_callback(GtkWidget *w, GdkEventButton *ev, gpointer data) { snd_info *sp = (snd_info *)data; if (EVENT_STATE(ev) & (snd_ControlMask | snd_MetaMask)) set_revscl(sp, sp->last_reverb_control_scale); else set_revscl(sp, 0.0); return(false); } static void revscl_changed_callback(GtkAdjustment *adj, gpointer data) { if (ignore_callback) return; scroll_to_revscl((snd_info *)data, ADJUSTMENT_VALUE(adj)); } static gboolean revscl_release_callback(GtkWidget *w, GdkEventButton *ev, gpointer data) { snd_info *sp = (snd_info *)data; sp->last_reverb_control_scale = sp->saved_reverb_control_scale; sp->saved_reverb_control_scale = sp->reverb_control_scale; return(false); } static mus_float_t revlen_to_scroll(mus_float_t minval, mus_float_t val, mus_float_t maxval) { if (val <= minval) return(0.0); if (val >= maxval) return(0.9); return((val - minval) / (maxval - minval) * 0.9); } static mus_float_t scroll_to_revlen(snd_info *sp, mus_float_t val) { char revlen_number_buffer[5]; sp->reverb_control_length = sp->reverb_control_length_min + (sp->reverb_control_length_max - sp->reverb_control_length_min) * (mus_float_t)val / 0.9; snprintf(revlen_number_buffer, 5, "%.2f", sp->reverb_control_length); gtk_label_set_text(GTK_LABEL(REVLEN_LABEL(sp)), revlen_number_buffer); return(val); } void set_revlen(snd_info *sp, mus_float_t val) { if (!has_widgets(sp)) sp->reverb_control_length = val; else { GtkAdjustment *adj; adj = REVLEN_ADJUSTMENT(sp); ignore_callback = true; ADJUSTMENT_SET_VALUE(adj, scroll_to_revlen(sp, revlen_to_scroll(sp->reverb_control_length_min, val, sp->reverb_control_length_max))); /* gtk_adjustment_value_changed(GTK_ADJUSTMENT(adj)); */ ignore_callback = false; } } static gboolean revlen_click_callback(GtkWidget *w, GdkEventButton *ev, gpointer data) { snd_info *sp = (snd_info *)data; if (EVENT_STATE(ev) & (snd_ControlMask | snd_MetaMask)) set_revlen(sp, sp->last_reverb_control_length); else set_revlen(sp, 1.0); return(false); } static void revlen_changed_callback(GtkAdjustment *adj, gpointer data) { if (ignore_callback) return; scroll_to_revlen((snd_info *)data, ADJUSTMENT_VALUE(adj)); } static gboolean revlen_release_callback(GtkWidget *w, GdkEventButton *ev, gpointer data) { snd_info *sp = (snd_info *)data; sp->last_reverb_control_length = sp->saved_reverb_control_length; sp->saved_reverb_control_length = sp->reverb_control_length; return(false); } static void reverb_button_callback(GtkWidget *w, gpointer context) { snd_info *sp = (snd_info *)context; sp->reverb_control_on = TOGGLE_BUTTON_ACTIVE(w); } void toggle_reverb_button(snd_info *sp, bool state) { if (!has_widgets(sp)) sp->reverb_control_on = state; else set_toggle_button(REVERB_RIGHT_BUTTON(sp), state, true, (void *)sp); } /* -------- FILTER CALLBACKS -------- */ #define MIN_FILTER_GRAPH_HEIGHT 20 void display_filter_env(snd_info *sp) { graphics_context *ax; int height, width; GtkWidget *drawer; env_editor *edp; if (!has_widgets(sp)) return; edp = sp->flt; drawer = FILTER_ENV(sp); height = widget_height(drawer); if (height < MIN_FILTER_GRAPH_HEIGHT) return; width = widget_width(drawer); if (sp->filter_ax == NULL) { ax = (graphics_context *)calloc(1, sizeof(graphics_context)); ax->wn = WIDGET_TO_WINDOW(drawer); ax->w = drawer; sp->filter_ax = ax; } else { ax = sp->filter_ax; } ax->gc = ss->fltenv_basic_gc; ss->cr = make_cairo(ax->wn); cairo_push_group(ss->cr); /* erase previous */ cairo_set_source_rgba(ss->cr, ax->gc->bg_color->red, ax->gc->bg_color->green, ax->gc->bg_color->blue, ax->gc->bg_color->alpha); cairo_rectangle(ss->cr, 0, 0, width, height); cairo_fill(ss->cr); edp->in_dB = sp->filter_control_in_dB; edp->with_dots = true; if (sp->filter_control_envelope == NULL) sp->filter_control_envelope = default_env(sp->filter_control_xmax, 1.0); env_editor_display_env(edp, sp->filter_control_envelope, ax, "frequency response", 0, 0, width, height, NOT_PRINTING); if (edp->edited) { ax->gc = ss->fltenv_data_gc; display_frequency_response(sp->filter_control_envelope, (sound_env_editor(sp))->axis, ax, sp->filter_control_order, sp->filter_control_in_dB); } cairo_pop_group_to_source(ss->cr); cairo_paint(ss->cr); free_cairo(ss->cr); ss->cr = NULL; } static gboolean filter_drawer_button_motion(GtkWidget *w, GdkEventMotion *ev, gpointer data) { if (BUTTON1_PRESSED(EVENT_STATE(ev))) { snd_info *sp = (snd_info *)data; int evx, evy; GdkModifierType state; env_editor *edp; if (EVENT_IS_HINT(ev)) window_get_pointer(ev, &evx, &evy, &state); else { evx = (int)(EVENT_X(ev)); evy = (int)(EVENT_Y(ev)); } edp = sp->flt; edp->in_dB = sp->filter_control_in_dB; env_editor_button_motion(edp, evx, evy, EVENT_TIME(ev), sp->filter_control_envelope); display_filter_env(sp); sp->filter_control_changed = true; } return(false); } static gboolean filter_drawer_button_press(GtkWidget *w, GdkEventButton *ev, gpointer data) { snd_info *sp = (snd_info *)data; env_editor *edp; edp = sp->flt; edp->in_dB = sp->filter_control_in_dB; if (env_editor_button_press(edp, (int)(EVENT_X(ev)), (int)(EVENT_Y(ev)), EVENT_TIME(ev), sp->filter_control_envelope)) display_filter_env(sp); return(false); } static gboolean filter_drawer_button_release(GtkWidget *w, GdkEventButton *ev, gpointer data) { char *tmpstr = NULL; snd_info *sp = (snd_info *)data; env_editor_button_release(sound_env_editor(sp), sp->filter_control_envelope); display_filter_env(sp); set_filter_text(sp, tmpstr = env_to_string(sp->filter_control_envelope)); if (tmpstr) free(tmpstr); sp->filter_control_changed = true; return(false); } void set_filter_text(snd_info *sp, const char *str) { if (has_widgets(sp)) { if (str) gtk_entry_set_text(GTK_ENTRY(FILTER_COEFFS_TEXT(sp)), str); else gtk_entry_set_text(GTK_ENTRY(FILTER_COEFFS_TEXT(sp)), stupid); } } static gboolean filter_drawer_expose(GtkWidget *w, GdkEventExpose *ev, gpointer data) { snd_info *sp = (snd_info *)data; display_filter_env(sp); return(false); } static gboolean filter_drawer_resize(GtkWidget *w, GdkEventConfigure *ev, gpointer data) { snd_info *sp = (snd_info *)data; display_filter_env(sp); return(false); } static void filter_button_callback(GtkWidget *w, gpointer context) { snd_info *sp = (snd_info *)context; sp->filter_control_on = TOGGLE_BUTTON_ACTIVE(w); } void toggle_filter_button(snd_info *sp, bool state) { if (!has_widgets(sp)) sp->filter_control_on = state; else set_toggle_button(FILTER_RIGHT_BUTTON(sp), state, true, (void *)sp); } static void filter_db_callback(GtkWidget *w, gpointer context) { snd_info *sp = (snd_info *)context; sp->filter_control_in_dB = TOGGLE_BUTTON_ACTIVE(w); display_filter_env(sp); } void set_filter_in_dB(snd_info *sp, bool val) { sp->filter_control_in_dB = val; if (has_widgets(sp)) { set_toggle_button(FILTER_DB_BUTTON(sp), val, false, (void *)sp); display_filter_env(sp); } } static void new_in_hz(snd_info *sp, bool val) { sp->filter_control_in_hz = val; if (val) sp->filter_control_xmax = (mus_float_t)(snd_srate(sp) / 2); else sp->filter_control_xmax = 1.0; if (sp->filter_control_envelope) free_env(sp->filter_control_envelope); sp->filter_control_envelope = default_env(sp->filter_control_xmax, 1.0); } static void filter_hz_callback(GtkWidget *w, gpointer context) { snd_info *sp = (snd_info *)context; new_in_hz(sp, TOGGLE_BUTTON_ACTIVE(w)); display_filter_env(sp); } void set_filter_in_hz(snd_info *sp, bool val) { new_in_hz(sp, val); if (has_widgets(sp)) { set_toggle_button(FILTER_HZ_BUTTON(sp), val, false, (void *)sp); display_filter_env(sp); } } static void set_filter_order_1(snd_info *sp, int order, bool setadj) { sp->filter_control_order = order; if (setadj) gtk_spin_button_set_value(GTK_SPIN_BUTTON(FILTER_ORDER_TEXT(sp)), (gfloat)order); display_filter_env(sp); sp->filter_control_changed = true; } void set_filter_order(snd_info *sp, int order) { if (!has_widgets(sp)) sp->filter_control_order = order; else set_filter_order_1(sp, order, true); } static void filter_order_callback(GtkWidget *w, gpointer data) { int order; snd_info *sp = (snd_info *)data; order = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(FILTER_ORDER_TEXT(sp))); if (order & 1) order++; if (order <= 0) order = 2; sp->filter_control_order = order; set_filter_order_1(sp, order, false); } static void filter_activate_callback(GtkWidget *w, gpointer context) { /* make an envelope out of the data */ snd_info *sp = (snd_info *)context; char *str = NULL; str = (char *)gtk_entry_get_text(GTK_ENTRY(w)); if (sp->filter_control_envelope) sp->filter_control_envelope = free_env(sp->filter_control_envelope); redirect_errors_to(errors_to_status_area, (void *)sp); sp->filter_control_envelope = string_to_env((const char *)str); redirect_errors_to(NULL, NULL); if (!(sp->filter_control_envelope)) /* maybe user cleared text field? */ sp->filter_control_envelope = default_env(sp->filter_control_xmax, 1.0); (sound_env_editor(sp))->edited = true; display_filter_env(sp); sp->filter_control_changed = true; } void filter_env_changed(snd_info *sp, env *e) { /* turn e back into a string for textfield widget */ if (has_widgets(sp)) { char *tmpstr; tmpstr = env_to_string(e); if (tmpstr) { gtk_entry_set_text(GTK_ENTRY(FILTER_COEFFS_TEXT(sp)), tmpstr); free(tmpstr); } else gtk_entry_set_text(GTK_ENTRY(FILTER_COEFFS_TEXT(sp)), stupid); (sound_env_editor(sp))->edited = true; display_filter_env(sp); /* this is called also from snd-scm.c */ } sp->filter_control_changed = true; } void color_filter_waveform(color_info *color) { int i; gc_set_foreground(ss->fltenv_data_gc, color); for (i = 0; i < ss->max_sounds; i++) { snd_info *sp; sp = ss->sounds[i]; if ((sp) && (sp->inuse == SOUND_NORMAL)) display_filter_env(sp); } } /* -------- AMP ENVS ETC -------- */ static int cant_write(char *name) { #ifndef _MSC_VER return((access(name, W_OK)) != 0); #else return(0); #endif } static gint close_sound_dialog(GtkWidget *w, GdkEvent *event, gpointer context) { snd_info *sp = (snd_info *)context; if (sp) { snd_close_file(sp); gtk_widget_hide(sp->dialog); } return(true); } static gboolean stop_sign_press(GtkWidget *w, GdkEventButton *ev, gpointer data) { snd_info *sp = (snd_info *)data; if ((ss->checking_explicitly) || (play_in_progress())) ss->stopped_explicitly = true; stop_playing_all_sounds(PLAY_C_G); if (sp->applying) stop_applying(sp); for_each_sound_chan(sp, stop_fft_in_progress); return(false); } static void show_sync_button(snd_info *sp) { gtk_widget_show(SYNC_BUTTON(sp)); } static Xen reflect_file_close_in_sync(Xen hook_or_reason) { int reason; #if HAVE_SCHEME reason = Xen_integer_to_C_int(s7_let_ref(s7, hook_or_reason, s7_make_symbol(s7, "reason"))); #else reason = Xen_integer_to_C_int(hook_or_reason); #endif if ((reason == FILE_CLOSED) && /* snd-file.c */ (ss->active_sounds == 1)) { snd_info *sp; sp = any_selected_sound(); if ((sp) && (sp->nchans == 1)) gtk_widget_hide(SYNC_BUTTON(sp)); } return(Xen_false); } Xen_wrap_1_arg(reflect_file_close_in_sync_w, reflect_file_close_in_sync) static void close_button_callback(GtkWidget *w, gpointer context) { snd_close_file((snd_info *)context); } static gboolean close_button_tooltip(GtkWidget *w, gint x, gint y, gboolean keyboard_tip, GtkTooltip *tooltip, gpointer data) { snd_info *sp = (snd_info *)data; char *tip; tip = mus_format("close %s", sp->short_filename); gtk_tooltip_set_text(tooltip, tip); free(tip); return(true); } /* -------- SOUND PANE -------- */ #define BUTTON_SPACE 6 static bool currently_showing_controls = false; snd_info *add_sound_window(char *filename, read_only_t read_only, file_info *hdr) { snd_info *sp, *osp; int snd_slot, nchans, i, old_chans; bool free_filename = false, make_widgets; char *old_name = NULL; int app_y, app_dy, chan_min_y; /* these dimensions are used to try to get a reasonable channel graph size without falling off the screen bottom */ if (ss->translated_filename) { old_name = filename; filename = ss->translated_filename; ss->translated_filename = NULL; free_filename = true; } nchans = hdr->chans; if (nchans <= 0) nchans = 1; app_y = widget_y(MAIN_SHELL(ss)); app_dy = widget_height(MAIN_SHELL(ss)); if (auto_resize(ss)) { int screen_y; screen_y = gdk_screen_height(); app_dy = (screen_y - app_y - app_dy - 20 * nchans); } else app_dy -= listener_height(); chan_min_y = app_dy / nchans; if (chan_min_y > ss->channel_min_height) chan_min_y = ss->channel_min_height; else if (chan_min_y < 5) chan_min_y = 5; snd_slot = find_free_sound_slot(nchans); /* expands sound list if needed */ if (ss->sounds[snd_slot]) /* we're trying to re-use an old, inactive set of widgets and whatnot */ { osp = ss->sounds[snd_slot]; old_chans = osp->allocated_chans; } else old_chans = 0; make_widgets = (ss->sounds[snd_slot] == NULL); ss->sounds[snd_slot] = make_snd_info(ss->sounds[snd_slot], filename, hdr, snd_slot, read_only); sp = ss->sounds[snd_slot]; sp->inuse = SOUND_NORMAL; sp->write_date = file_write_date(filename); /* needed early in this process by the peak-env handlers */ make_pixmaps(); if (sp->snd_widgets == NULL) { sp->snd_widgets = (GtkWidget **)calloc(NUM_SND_WIDGETS, sizeof(GtkWidget *)); sp->snd_adjs = (GtkAdjustment **)calloc(NUM_SND_ADJS, sizeof(GtkAdjustment *)); } if (!(auto_resize(ss))) gtk_window_set_resizable(GTK_WINDOW(MAIN_SHELL(ss)), false); if ((!make_widgets) && (old_chans < nchans)) { for (i = old_chans; i < nchans; i++) add_channel_window(sp, i, chan_min_y, 1, NULL, WITH_FW_BUTTONS, WITH_EVENTS); } if (make_widgets) { SND_PANE(sp) = gtk_vpaned_new(); add_paned_style(SND_PANE(sp)); set_user_int_data(G_OBJECT(SND_PANE(sp)), sp->index); gtk_container_set_border_width(GTK_CONTAINER(SND_PANE(sp)), 4); /* this is the outer margin of each sound's box -- 6 seems slightly large */ /* I tried putting a frame around the entire pane, but it looked fussy, and the frame bottom cut into the filter widget! */ if (sound_style(ss) == SOUNDS_IN_SEPARATE_WINDOWS) { sp->dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL); sg_make_resizable(sp->dialog); gtk_container_add(GTK_CONTAINER(sp->dialog), SND_PANE(sp)); gtk_widget_show(sp->dialog); SG_SIGNAL_CONNECT(sp->dialog, "delete_event", close_sound_dialog, sp); } else { if (sound_style(ss) == SOUNDS_IN_NOTEBOOK) { GtkWidget *tablab; tablab = gtk_label_new(sp->short_filename); gtk_widget_show(tablab); gtk_notebook_append_page(GTK_NOTEBOOK(SOUND_PANE_BOX(ss)), SND_PANE(sp), tablab); } else gtk_box_pack_start(GTK_BOX(SOUND_PANE_BOX(ss)), SND_PANE(sp), true, true, 0); /* child2 is listener */ } PANE_BOX(sp) = gtk_vbox_new(false, 0); gtk_paned_add1(GTK_PANED(SND_PANE(sp)), PANE_BOX(sp)); gtk_widget_show(PANE_BOX(sp)); NAME_HBOX(sp) = gtk_hbox_new(false, 0); gtk_box_pack_end(GTK_BOX(PANE_BOX(sp)), NAME_HBOX(sp), false, false, 0); for (i = 0; i < nchans; i++) add_channel_window(sp, i, chan_min_y, 0, NULL, WITH_FW_BUTTONS, WITH_EVENTS); /* controls etc */ CONTROL_PANEL(sp) = gtk_vbox_new(false, 0); gtk_paned_pack2(GTK_PANED(SND_PANE(sp)), CONTROL_PANEL(sp), false, true); /* add2 but resize=false */ /* -------- NAME FIELDS -------- */ CLOSE_BUTTON(sp) = gtk_button_new(); #if GTK_CHECK_VERSION(3, 0, 0) add_highlight_button_style(CLOSE_BUTTON(sp)); #endif add_tooltip(CLOSE_BUTTON(sp), "close current sound"); gtk_button_set_relief(GTK_BUTTON(CLOSE_BUTTON(sp)), GTK_RELIEF_NONE); gtk_button_set_image(GTK_BUTTON(CLOSE_BUTTON(sp)), image_new_with_icon(ICON_CLOSE, GTK_ICON_SIZE_MENU)); gtk_box_pack_start(GTK_BOX(NAME_HBOX(sp)), CLOSE_BUTTON(sp), false, false, 8); SG_SIGNAL_CONNECT(CLOSE_BUTTON(sp), "clicked", close_button_callback, sp); g_signal_connect(CLOSE_BUTTON(sp), "query-tooltip", G_CALLBACK(close_button_tooltip), (gpointer)sp); gtk_widget_show(CLOSE_BUTTON(sp)); NAME_EVENT_BOX(sp) = gtk_event_box_new(); #if GTK_CHECK_VERSION(3, 0, 0) add_highlight_button_style(NAME_EVENT_BOX(sp)); #endif add_tooltip(NAME_EVENT_BOX(sp), "name of current sound"); /* just a placeholder */ gtk_box_pack_start(GTK_BOX(NAME_HBOX(sp)), NAME_EVENT_BOX(sp), false, false, 5); gtk_widget_show(NAME_EVENT_BOX(sp)); SG_SIGNAL_CONNECT(NAME_EVENT_BOX(sp), "button_press_event", name_click_callback, sp); g_signal_connect(NAME_EVENT_BOX(sp), "query-tooltip", G_CALLBACK(name_button_tooltip), (gpointer)sp); NAME_BUTTON(sp) = gtk_label_new(shortname_indexed(sp)); gtk_container_add(GTK_CONTAINER(NAME_EVENT_BOX(sp)), NAME_BUTTON(sp)); gtk_widget_show(NAME_BUTTON(sp)); NAME_PIX(sp) = gtk_drawing_area_new(); gtk_widget_set_events(NAME_PIX(sp), GDK_EXPOSURE_MASK); gtk_widget_set_size_request(NAME_PIX(sp), 16, 16); gtk_box_pack_start(GTK_BOX(NAME_HBOX(sp)), NAME_PIX(sp), false, false, 2); gtk_widget_show(NAME_PIX(sp)); sp->name_pix_ax = (graphics_context *)calloc(1, sizeof(graphics_context)); sp->name_pix_ax->wn = WIDGET_TO_WINDOW(NAME_PIX(sp)); sp->name_pix_ax->gc = ss->basic_gc; SG_SIGNAL_CONNECT(NAME_PIX(sp), DRAW_SIGNAL, name_pix_expose, sp); STOP_PIX(sp) = gtk_drawing_area_new(); gtk_widget_set_events(STOP_PIX(sp), GDK_BUTTON_PRESS_MASK); gtk_widget_set_size_request(STOP_PIX(sp), 16, 16); gtk_box_pack_start(GTK_BOX(NAME_HBOX(sp)), STOP_PIX(sp), false, false, 2); gtk_widget_show(STOP_PIX(sp)); sp->stop_pix_ax = (graphics_context *)calloc(1, sizeof(graphics_context)); sp->stop_pix_ax->wn = WIDGET_TO_WINDOW(STOP_PIX(sp)); sp->stop_pix_ax->gc = ss->basic_gc; SG_SIGNAL_CONNECT(STOP_PIX(sp), "button_press_event", stop_sign_press, sp); { int i; sp->clock_widgets = (GtkWidget **)calloc(sp->nchans, sizeof(GtkWidget *)); sp->clock_pix_ax = (graphics_context **)calloc(sp->nchans, sizeof(graphics_context *)); sp->num_clock_widgets = sp->nchans; for (i = 0; i < sp->nchans; i++) { CLOCK_PIX(sp, i) = gtk_drawing_area_new(); gtk_widget_set_size_request(CLOCK_PIX(sp, i), 16, 16); gtk_box_pack_start(GTK_BOX(NAME_HBOX(sp)), CLOCK_PIX(sp, i), false, false, 2); gtk_widget_show(CLOCK_PIX(sp, i)); sp->clock_pix_ax[i] = (graphics_context *)calloc(1, sizeof(graphics_context)); sp->clock_pix_ax[i]->wn = WIDGET_TO_WINDOW(CLOCK_PIX(sp, i)); sp->clock_pix_ax[i]->gc = ss->basic_gc; SG_SIGNAL_CONNECT(CLOCK_PIX(sp, i), DRAW_SIGNAL, clock_pix_expose, sp->chans[i]); } } STATUS_AREA(sp) = gtk_label_new(NULL); #if GTK_CHECK_VERSION(3, 0, 0) gtk_widget_set_halign(STATUS_AREA(sp), GTK_ALIGN_FILL); gtk_widget_set_hexpand(STATUS_AREA(sp), true); #endif gtk_box_pack_start(GTK_BOX(NAME_HBOX(sp)), STATUS_AREA(sp), true, true, 2); gtk_widget_show(STATUS_AREA(sp)); /* now fill from other end */ #if WITH_AUDIO PLAY_BUTTON(sp) = gtk_check_button_new_with_label("play"); gtk_box_pack_end(GTK_BOX(NAME_HBOX(sp)), PLAY_BUTTON(sp), false, false, BUTTON_SPACE); /* need space here or "play" hits window edge */ SG_SIGNAL_CONNECT(PLAY_BUTTON(sp), "button_press_event", play_button_callback, sp); SG_SIGNAL_CONNECT(PLAY_BUTTON(sp), "toggled", play_button_click_callback, sp); gtk_widget_show(PLAY_BUTTON(sp)); #endif SYNC_BUTTON(sp) = gtk_check_button_new_with_label("sync"); add_tooltip(SYNC_BUTTON(sp), "group this sound with anything sharing its sync value"); gtk_box_pack_end(GTK_BOX(NAME_HBOX(sp)), SYNC_BUTTON(sp), false, false, BUTTON_SPACE); SG_SIGNAL_CONNECT(SYNC_BUTTON(sp), "button_press_event", sync_button_callback, sp); SG_SIGNAL_CONNECT(SYNC_BUTTON(sp), "toggled", sync_button_click, sp); gtk_widget_show(SYNC_BUTTON(sp)); UNITE_BUTTON(sp) = gtk_check_button_new_with_label("unite"); add_tooltip(UNITE_BUTTON(sp), "combine channel graphs in one window"); gtk_box_pack_end(GTK_BOX(NAME_HBOX(sp)), UNITE_BUTTON(sp), false, false, BUTTON_SPACE); SG_SIGNAL_CONNECT(UNITE_BUTTON(sp), "button_press_event", unite_button_callback, sp); SG_SIGNAL_CONNECT(UNITE_BUTTON(sp), "toggled", unite_button_click, sp); gtk_widget_show(UNITE_BUTTON(sp)); gtk_widget_show(NAME_HBOX(sp)); /* if control-panel */ /* -------- AMP FIELDS -------- */ NAME_SEPARATOR(sp) = gtk_hseparator_new(); gtk_box_pack_start(GTK_BOX(CONTROL_PANEL(sp)), NAME_SEPARATOR(sp), false, false, 4); gtk_widget_show(NAME_SEPARATOR(sp)); AMP_HBOX(sp) = gtk_hbox_new(false, 2); gtk_box_pack_start(GTK_BOX(CONTROL_PANEL(sp)), AMP_HBOX(sp), false, false, 0); AMP_EVENT_BOX(sp) = gtk_event_box_new(); gtk_box_pack_start(GTK_BOX(AMP_HBOX(sp)), AMP_EVENT_BOX(sp), false, false, 4); gtk_widget_show(AMP_EVENT_BOX(sp)); SG_SIGNAL_CONNECT(AMP_EVENT_BOX(sp), "button_press_event", amp_click_callback, sp); AMP_BUTTON(sp) = gtk_label_new("amp:"); gtk_container_add(GTK_CONTAINER(AMP_EVENT_BOX(sp)), AMP_BUTTON(sp)); gtk_widget_show(AMP_BUTTON(sp)); AMP_LABEL(sp) = gtk_label_new("1.00 "); gtk_box_pack_start(GTK_BOX(AMP_HBOX(sp)), AMP_LABEL(sp), false, false, 0); gtk_widget_show(AMP_LABEL(sp)); AMP_ADJUSTMENT(sp) = (GtkAdjustment *)gtk_adjustment_new(amp_to_scroll(sp->amp_control_min, 1.0, sp->amp_control_max), 0.0, 1.0, 0.001, 0.01, .1); AMP_SCROLLBAR(sp) = gtk_hscrollbar_new(GTK_ADJUSTMENT(AMP_ADJUSTMENT(sp))); gtk_box_pack_start(GTK_BOX(AMP_HBOX(sp)), AMP_SCROLLBAR(sp), true, true, 4); SG_SIGNAL_CONNECT(AMP_ADJUSTMENT(sp), "value_changed", amp_changed_callback, sp); SG_SIGNAL_CONNECT(AMP_SCROLLBAR(sp), "button_release_event", amp_release_callback, sp); gtk_widget_show(AMP_SCROLLBAR(sp)); gtk_widget_show(AMP_HBOX(sp)); /* -------- SPEED FIELDS -------- */ SPEED_HBOX(sp) = gtk_hbox_new(false, 2); gtk_box_pack_start(GTK_BOX(CONTROL_PANEL(sp)), SPEED_HBOX(sp), false, false, 0); SPEED_EVENT_BOX(sp) = gtk_event_box_new(); gtk_box_pack_start(GTK_BOX(SPEED_HBOX(sp)), SPEED_EVENT_BOX(sp), false, false, 4); gtk_widget_show(SPEED_EVENT_BOX(sp)); SG_SIGNAL_CONNECT(SPEED_EVENT_BOX(sp), "button_press_event", speed_click_callback, sp); SPEED_BUTTON(sp) = gtk_label_new("speed:"); gtk_container_add(GTK_CONTAINER(SPEED_EVENT_BOX(sp)), SPEED_BUTTON(sp)); gtk_widget_show(SPEED_BUTTON(sp)); SPEED_LABEL_EVENT_BOX(sp) = gtk_event_box_new(); gtk_box_pack_start(GTK_BOX(SPEED_HBOX(sp)), SPEED_LABEL_EVENT_BOX(sp), false, false, 4); gtk_widget_show(SPEED_LABEL_EVENT_BOX(sp)); SG_SIGNAL_CONNECT(SPEED_LABEL_EVENT_BOX(sp), "button_press_event", speed_label_click_callback, sp); switch (sp->speed_control_style) { case SPEED_CONTROL_AS_RATIO: SPEED_LABEL(sp) = gtk_label_new(" 1/1"); break; case SPEED_CONTROL_AS_SEMITONE: SPEED_LABEL(sp) = gtk_label_new(" 0"); break; default: SPEED_LABEL(sp) = gtk_label_new("1.00 "); break; } gtk_container_add(GTK_CONTAINER(SPEED_LABEL_EVENT_BOX(sp)), SPEED_LABEL(sp)); gtk_widget_show(SPEED_LABEL(sp)); SPEED_ADJUSTMENT(sp) = (GtkAdjustment *)gtk_adjustment_new(speed_to_scroll(sp->speed_control_min, 1.0, sp->speed_control_max), 0.0, 1.0, 0.001, 0.01, .1); SPEED_SCROLLBAR(sp) = gtk_hscrollbar_new(GTK_ADJUSTMENT(SPEED_ADJUSTMENT(sp))); gtk_box_pack_start(GTK_BOX(SPEED_HBOX(sp)), SPEED_SCROLLBAR(sp), true, true, 4); SG_SIGNAL_CONNECT(SPEED_ADJUSTMENT(sp), "value_changed", speed_changed_callback, sp); SG_SIGNAL_CONNECT(SPEED_SCROLLBAR(sp), "button_release_event", speed_release_callback, sp); gtk_widget_show(SPEED_SCROLLBAR(sp)); SPEED_ARROW(sp) = gtk_drawing_area_new(); gtk_widget_set_events(SPEED_ARROW(sp), GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK); gtk_box_pack_start(GTK_BOX(SPEED_HBOX(sp)), SPEED_ARROW(sp), false, false, 2); gtk_widget_set_size_request(SPEED_ARROW(sp), 16, 16); gtk_widget_show(SPEED_ARROW(sp)); sp->speed_arrow_ax = (graphics_context *)calloc(1, sizeof(graphics_context)); sp->speed_arrow_ax->wn = WIDGET_TO_WINDOW(SPEED_ARROW(sp)); sp->speed_arrow_ax->gc = ss->basic_gc; SG_SIGNAL_CONNECT(SPEED_ARROW(sp), DRAW_SIGNAL, speed_arrow_expose, sp); SG_SIGNAL_CONNECT(SPEED_ARROW(sp), "button_press_event", speed_arrow_press, sp); gtk_widget_show(SPEED_HBOX(sp)); /* -------- EXPAND FIELDS -------- */ EXPAND_HBOX(sp) = gtk_hbox_new(false, 2); gtk_box_pack_start(GTK_BOX(CONTROL_PANEL(sp)), EXPAND_HBOX(sp), false, false, 0); EXPAND_EVENT_BOX(sp) = gtk_event_box_new(); gtk_box_pack_start(GTK_BOX(EXPAND_HBOX(sp)), EXPAND_EVENT_BOX(sp), false, false, 4); gtk_widget_show(EXPAND_EVENT_BOX(sp)); SG_SIGNAL_CONNECT(EXPAND_EVENT_BOX(sp), "button_press_event", expand_click_callback, sp); EXPAND_LEFT_BUTTON(sp) = gtk_label_new("expand:"); gtk_container_add(GTK_CONTAINER(EXPAND_EVENT_BOX(sp)), EXPAND_LEFT_BUTTON(sp)); gtk_widget_show(EXPAND_LEFT_BUTTON(sp)); EXPAND_LABEL(sp) = gtk_label_new("1.00 "); gtk_box_pack_start(GTK_BOX(EXPAND_HBOX(sp)), EXPAND_LABEL(sp), false, false, 0); gtk_widget_show(EXPAND_LABEL(sp)); EXPAND_ADJUSTMENT(sp) = (GtkAdjustment *)gtk_adjustment_new(expand_to_scroll(sp->expand_control_min, 1.0, sp->expand_control_max), 0.0, 1.0, 0.001, 0.01, .1); EXPAND_SCROLLBAR(sp) = gtk_hscrollbar_new(GTK_ADJUSTMENT(EXPAND_ADJUSTMENT(sp))); gtk_box_pack_start(GTK_BOX(EXPAND_HBOX(sp)), EXPAND_SCROLLBAR(sp), true, true, 4); SG_SIGNAL_CONNECT(EXPAND_ADJUSTMENT(sp), "value_changed", expand_changed_callback, sp); SG_SIGNAL_CONNECT(EXPAND_SCROLLBAR(sp), "button_release_event", expand_release_callback, sp); gtk_widget_show(EXPAND_SCROLLBAR(sp)); EXPAND_RIGHT_BUTTON(sp) = gtk_check_button_new(); gtk_box_pack_start(GTK_BOX(EXPAND_HBOX(sp)), EXPAND_RIGHT_BUTTON(sp), false, false, 3); SG_SIGNAL_CONNECT(EXPAND_RIGHT_BUTTON(sp), "clicked", expand_button_callback, sp); gtk_widget_show(EXPAND_RIGHT_BUTTON(sp)); gtk_widget_show(EXPAND_HBOX(sp)); /* -------- CONTRAST FIELDS -------- */ CONTRAST_HBOX(sp) = gtk_hbox_new(false, 2); gtk_box_pack_start(GTK_BOX(CONTROL_PANEL(sp)), CONTRAST_HBOX(sp), false, false, 0); CONTRAST_EVENT_BOX(sp) = gtk_event_box_new(); gtk_box_pack_start(GTK_BOX(CONTRAST_HBOX(sp)), CONTRAST_EVENT_BOX(sp), false, false, 4); gtk_widget_show(CONTRAST_EVENT_BOX(sp)); SG_SIGNAL_CONNECT(CONTRAST_EVENT_BOX(sp), "button_press_event", contrast_click_callback, sp); CONTRAST_LEFT_BUTTON(sp) = gtk_label_new("contrast:"); gtk_container_add(GTK_CONTAINER(CONTRAST_EVENT_BOX(sp)), CONTRAST_LEFT_BUTTON(sp)); gtk_widget_show(CONTRAST_LEFT_BUTTON(sp)); CONTRAST_LABEL(sp) = gtk_label_new("0.00 "); gtk_box_pack_start(GTK_BOX(CONTRAST_HBOX(sp)), CONTRAST_LABEL(sp), false, false, 0); gtk_widget_show(CONTRAST_LABEL(sp)); CONTRAST_ADJUSTMENT(sp) = (GtkAdjustment *)gtk_adjustment_new(0.0, 0.0, 1.0, 0.001, 0.01, .1); CONTRAST_SCROLLBAR(sp) = gtk_hscrollbar_new(GTK_ADJUSTMENT(CONTRAST_ADJUSTMENT(sp))); gtk_box_pack_start(GTK_BOX(CONTRAST_HBOX(sp)), CONTRAST_SCROLLBAR(sp), true, true, 4); SG_SIGNAL_CONNECT(CONTRAST_ADJUSTMENT(sp), "value_changed", contrast_changed_callback, sp); SG_SIGNAL_CONNECT(CONTRAST_SCROLLBAR(sp), "button_release_event", contrast_release_callback, sp); gtk_widget_show(CONTRAST_SCROLLBAR(sp)); CONTRAST_RIGHT_BUTTON(sp) = gtk_check_button_new(); gtk_box_pack_start(GTK_BOX(CONTRAST_HBOX(sp)), CONTRAST_RIGHT_BUTTON(sp), false, false, 3); SG_SIGNAL_CONNECT(CONTRAST_RIGHT_BUTTON(sp), "clicked", contrast_button_callback, sp); gtk_widget_show(CONTRAST_RIGHT_BUTTON(sp)); gtk_widget_show(CONTRAST_HBOX(sp)); /* -------- REVERB FIELDS -------- */ REVERB_HBOX(sp) = gtk_hbox_new(false, 2); gtk_box_pack_start(GTK_BOX(CONTROL_PANEL(sp)), REVERB_HBOX(sp), false, false, 0); REVSCL_EVENT_BOX(sp) = gtk_event_box_new(); gtk_box_pack_start(GTK_BOX(REVERB_HBOX(sp)), REVSCL_EVENT_BOX(sp), false, false, 4); gtk_widget_show(REVSCL_EVENT_BOX(sp)); SG_SIGNAL_CONNECT(REVSCL_EVENT_BOX(sp), "button_press_event", revscl_click_callback, sp); REVSCL_BUTTON(sp) = gtk_label_new("reverb:"); gtk_container_add(GTK_CONTAINER(REVSCL_EVENT_BOX(sp)), REVSCL_BUTTON(sp)); gtk_widget_show(REVSCL_BUTTON(sp)); REVSCL_LABEL(sp) = gtk_label_new("0.000 "); gtk_box_pack_start(GTK_BOX(REVERB_HBOX(sp)), REVSCL_LABEL(sp), false, false, 0); gtk_widget_show(REVSCL_LABEL(sp)); REVSCL_ADJUSTMENT(sp) = (GtkAdjustment *)gtk_adjustment_new(0.0, 0.0, 1.0, 0.001, 0.01, .1); REVSCL_SCROLLBAR(sp) = gtk_hscrollbar_new(GTK_ADJUSTMENT(REVSCL_ADJUSTMENT(sp))); gtk_box_pack_start(GTK_BOX(REVERB_HBOX(sp)), REVSCL_SCROLLBAR(sp), true, true, 4); SG_SIGNAL_CONNECT(REVSCL_ADJUSTMENT(sp), "value_changed", revscl_changed_callback, sp); SG_SIGNAL_CONNECT(REVSCL_SCROLLBAR(sp), "button_release_event", revscl_release_callback, sp); gtk_widget_show(REVSCL_SCROLLBAR(sp)); REVLEN_EVENT_BOX(sp) = gtk_event_box_new(); gtk_box_pack_start(GTK_BOX(REVERB_HBOX(sp)), REVLEN_EVENT_BOX(sp), false, false, 4); gtk_widget_show(REVLEN_EVENT_BOX(sp)); SG_SIGNAL_CONNECT(REVLEN_EVENT_BOX(sp), "button_press_event", revlen_click_callback, sp); REVLEN_BUTTON(sp) = gtk_label_new("len:"); gtk_container_add(GTK_CONTAINER(REVLEN_EVENT_BOX(sp)), REVLEN_BUTTON(sp)); gtk_widget_show(REVLEN_BUTTON(sp)); REVLEN_LABEL(sp) = gtk_label_new("1.0 "); gtk_box_pack_start(GTK_BOX(REVERB_HBOX(sp)), REVLEN_LABEL(sp), false, false, 0); gtk_widget_show(REVLEN_LABEL(sp)); REVLEN_ADJUSTMENT(sp) = (GtkAdjustment *)gtk_adjustment_new(revlen_to_scroll(sp->reverb_control_length_min, sp->reverb_control_length, sp->reverb_control_length_max), 0.0, 1.0, 0.001, 0.01, .1); REVLEN_SCROLLBAR(sp) = gtk_hscrollbar_new(GTK_ADJUSTMENT(REVLEN_ADJUSTMENT(sp))); gtk_box_pack_start(GTK_BOX(REVERB_HBOX(sp)), REVLEN_SCROLLBAR(sp), true, true, 4); SG_SIGNAL_CONNECT(REVLEN_ADJUSTMENT(sp), "value_changed", revlen_changed_callback, sp); SG_SIGNAL_CONNECT(REVLEN_SCROLLBAR(sp), "button_release_event", revlen_release_callback, sp); gtk_widget_show(REVLEN_SCROLLBAR(sp)); REVERB_RIGHT_BUTTON(sp) = gtk_check_button_new(); gtk_box_pack_start(GTK_BOX(REVERB_HBOX(sp)), REVERB_RIGHT_BUTTON(sp), false, false, 3); SG_SIGNAL_CONNECT(REVERB_RIGHT_BUTTON(sp), "clicked", reverb_button_callback, sp); gtk_widget_show(REVERB_RIGHT_BUTTON(sp)); gtk_widget_show(REVERB_HBOX(sp)); /* -------- FILTER FIELDS -------- */ FILTER_HBOX(sp) = gtk_hbox_new(false, 2); gtk_box_pack_start(GTK_BOX(CONTROL_PANEL(sp)), FILTER_HBOX(sp), false, false, 0); FILTER_LEFT_BUTTON(sp) = gtk_label_new("filter:"); gtk_box_pack_start(GTK_BOX(FILTER_HBOX(sp)), FILTER_LEFT_BUTTON(sp), false, false, 4); gtk_widget_show(FILTER_LEFT_BUTTON(sp)); FILTER_ADJUSTMENT(sp) = (GtkAdjustment *)gtk_adjustment_new(20, 2, 100000, 2, 10, 0); FILTER_ORDER_TEXT(sp) = gtk_spin_button_new(GTK_ADJUSTMENT(FILTER_ADJUSTMENT(sp)), 0.0, 0); gtk_box_pack_start(GTK_BOX(FILTER_HBOX(sp)), FILTER_ORDER_TEXT(sp), false, false, 2); gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(FILTER_ORDER_TEXT(sp)), true); SG_SIGNAL_CONNECT(FILTER_ADJUSTMENT(sp), "value_changed", filter_order_callback, sp); SG_SIGNAL_CONNECT(FILTER_ORDER_TEXT(sp), "enter_notify_event", spin_button_focus_callback, NULL); SG_SIGNAL_CONNECT(FILTER_ORDER_TEXT(sp), "leave_notify_event", spin_button_unfocus_callback, NULL); gtk_widget_show(FILTER_ORDER_TEXT(sp)); FILTER_COEFFS_TEXT(sp) = snd_entry_new(FILTER_HBOX(sp), NULL, WITH_DEFAULT_BACKGROUND); SG_SIGNAL_CONNECT(FILTER_COEFFS_TEXT(sp), "activate", filter_activate_callback, sp); FILTER_HZ_BUTTON(sp) = gtk_check_button_new_with_label("hz"); gtk_box_pack_start(GTK_BOX(FILTER_HBOX(sp)), FILTER_HZ_BUTTON(sp), false, false, 2); SG_SIGNAL_CONNECT(FILTER_HZ_BUTTON(sp), "clicked", filter_hz_callback, sp); gtk_widget_show(FILTER_HZ_BUTTON(sp)); FILTER_DB_BUTTON(sp) = gtk_check_button_new_with_label("dB"); gtk_box_pack_start(GTK_BOX(FILTER_HBOX(sp)), FILTER_DB_BUTTON(sp), false, false, 2); SG_SIGNAL_CONNECT(FILTER_DB_BUTTON(sp), "clicked", filter_db_callback, sp); gtk_widget_show(FILTER_DB_BUTTON(sp)); FILTER_RIGHT_BUTTON(sp) = gtk_check_button_new(); gtk_box_pack_start(GTK_BOX(FILTER_HBOX(sp)), FILTER_RIGHT_BUTTON(sp), false, false, 3); SG_SIGNAL_CONNECT(FILTER_RIGHT_BUTTON(sp), "clicked", filter_button_callback, sp); gtk_widget_show(FILTER_RIGHT_BUTTON(sp)); gtk_widget_show(FILTER_HBOX(sp)); { GtkWidget *fbox; fbox = gtk_hbox_new(false, 4); gtk_box_pack_start(GTK_BOX(CONTROL_PANEL(sp)), fbox, true, true, 0); gtk_widget_show(fbox); /* -------- FILTER GRAPH -------- */ FILTER_FRAME(sp) = gtk_frame_new(NULL); gtk_box_pack_start(GTK_BOX(fbox), FILTER_FRAME(sp), true, true, 30); FILTER_ENV(sp) = gtk_drawing_area_new(); gtk_widget_set_events(FILTER_ENV(sp), GDK_ALL_EVENTS_MASK); widget_modify_bg(FILTER_ENV(sp), GTK_STATE_NORMAL, ss->highlight_color); gtk_container_add(GTK_CONTAINER(FILTER_FRAME(sp)), FILTER_ENV(sp)); gtk_widget_show(FILTER_ENV(sp)); SG_SIGNAL_CONNECT(FILTER_ENV(sp), DRAW_SIGNAL, filter_drawer_expose, sp); SG_SIGNAL_CONNECT(FILTER_ENV(sp), "configure_event", filter_drawer_resize, sp); SG_SIGNAL_CONNECT(FILTER_ENV(sp), "button_press_event", filter_drawer_button_press, sp); SG_SIGNAL_CONNECT(FILTER_ENV(sp), "button_release_event", filter_drawer_button_release, sp); SG_SIGNAL_CONNECT(FILTER_ENV(sp), "motion_notify_event", filter_drawer_button_motion, sp); gtk_widget_show(FILTER_FRAME(sp)); sp->flt = new_env_editor(); } /* end if control-panel */ gtk_widget_show(CONTROL_PANEL(sp)); gtk_widget_show(SND_PANE(sp)); #if GTK_CHECK_VERSION(3, 0, 0) set_basic_color(ss->basic_color); #endif } /* new sound ss */ else { int k; /* re-manage currently inactive chan */ if (sound_style(ss) == SOUNDS_IN_SEPARATE_WINDOWS) raise_dialog(sp->dialog); gtk_widget_show(UNITE_BUTTON(sp)); gtk_widget_show(SND_PANE(sp)); for (k = 0; k < nchans; k++) add_channel_window(sp, k, chan_min_y, 0, NULL, WITH_FW_BUTTONS, WITH_EVENTS); gtk_label_set_text(GTK_LABEL(NAME_BUTTON(sp)), shortname_indexed(sp)); reset_user_int_data(G_OBJECT(SND_PANE(sp)), sp->index); /* is this necessary? */ if (sound_style(ss) == SOUNDS_IN_NOTEBOOK) gtk_notebook_set_tab_label_text(GTK_NOTEBOOK(SOUND_PANE_BOX(ss)), SND_PANE(sp), sp->short_filename); else reset_controls(sp); /* segfault here in notebook case! */ } gtk_window_set_resizable(GTK_WINDOW(MAIN_SHELL(ss)), true); if (currently_showing_controls) show_controls(sp); else hide_controls(sp); if (sound_style(ss) == SOUNDS_IN_SEPARATE_WINDOWS) { char *title; title = (char *)calloc(PRINT_BUFFER_SIZE, sizeof(char)); snprintf(title, PRINT_BUFFER_SIZE, "%d: %s", snd_slot, sp->short_filename); gtk_window_set_title(GTK_WINDOW(sp->dialog), title); free(title); } if (sp->nchans == 1) { gtk_widget_hide(UNITE_BUTTON(sp)); if (ss->active_sounds == 0) gtk_widget_hide(SYNC_BUTTON(sp)); else { for_each_sound(show_sync_button); } } else { for_each_sound(show_sync_button); } add_sound_data(filename, sp, WITH_GRAPH); if (cant_write(sp->filename)) sp->file_read_only = FILE_READ_ONLY; if ((sp->user_read_only == FILE_READ_ONLY) || (sp->file_read_only == FILE_READ_ONLY)) show_lock(sp); else hide_lock(sp); if (old_name) status_report(sp, "(translated %s)", old_name); after_open(sp); if (sound_style(ss) == SOUNDS_IN_NOTEBOOK) { sp->page = gtk_notebook_page_num(GTK_NOTEBOOK(SOUND_PANE_BOX(ss)), SND_PANE(sp)); reset_controls(sp); } if (free_filename) free(filename); #if GTK_CHECK_VERSION(3, 0, 0) if (listener_exists()) gtk_paned_set_position(GTK_PANED(SOUND_PANE(ss)), 50); /* actually we haven't reached full size here at start-up */ #endif return(sp); } void set_sound_pane_file_label(snd_info *sp, const char *str) { if ((sp->name_string == NULL) || (strcmp(sp->name_string, str) != 0)) { if (sp->name_string) free(sp->name_string); sp->name_string = mus_strdup(str); set_label(NAME_BUTTON(sp), str); } } void update_sound_label(snd_info *sp) { if (has_widgets(sp)) gtk_label_set_text(GTK_LABEL(NAME_BUTTON(sp)), shortname_indexed(sp)); } void snd_info_cleanup(snd_info *sp) { if (has_widgets(sp)) { clear_status_area(sp); if (SYNC_BUTTON(sp)) { set_toggle_button(SYNC_BUTTON(sp), false, false, (void *)sp); set_sync_color(sp); set_toggle_button(EXPAND_RIGHT_BUTTON(sp), false, false, (void *)sp); set_toggle_button(CONTRAST_RIGHT_BUTTON(sp), false, false, (void *)sp); set_toggle_button(FILTER_RIGHT_BUTTON(sp), false, false, (void *)sp); set_toggle_button(REVERB_RIGHT_BUTTON(sp), false, false, (void *)sp); set_toggle_button(UNITE_BUTTON(sp), false, false, (void *)sp); } if ((sp->dialog) && (widget_is_active(sp->dialog))) gtk_widget_hide(sp->dialog); if ((sp->snd_widgets) && (SND_PANE(sp))) gtk_widget_hide(SND_PANE(sp)); sp->channel_style = CHANNELS_SEPARATE; } } /* ---------------- normalize sounds ---------------- */ void show_controls(snd_info *sp) { gtk_widget_show_all(CONTROL_PANEL(sp)); /* control panel is pane 2 of SND_PANE(sp); PANE_BOX is pane 1 */ /* gtk_paned_set_position(GTK_PANED(SOUND_PANE(ss)), (gint)(widget_height(SOUND_PANE(ss)) * .75)); (glistener) */ } void hide_controls(snd_info *sp) { #if GTK_CHECK_VERSION(3, 0, 0) gtk_widget_hide(CONTROL_PANEL(sp)); #else gtk_widget_hide_all(CONTROL_PANEL(sp)); #endif } bool showing_controls(snd_info *sp) { #if ((!HAVE_GTK_WIDGET_GET_VISIBLE) || (!HAVE_GTK_WIDGET_GET_MAPPED)) return((GTK_WIDGET_MAPPED(CONTROL_PANEL(sp))) && (widget_is_active(CONTROL_PANEL(sp)))); #else return((gtk_widget_get_mapped(CONTROL_PANEL(sp))) && (gtk_widget_get_visible(CONTROL_PANEL(sp)))); #endif } void show_all_controls(void) { int i; currently_showing_controls = true; for (i = 0; i < ss->max_sounds; i++) { snd_info *sp; sp = ss->sounds[i]; if ((sp) && (sp->inuse == SOUND_NORMAL)) show_controls(sp); } } void hide_all_controls(void) { int i; currently_showing_controls = false; for (i = 0; i < ss->max_sounds; i++) { snd_info *sp; sp = ss->sounds[i]; if ((sp) && (sp->inuse == SOUND_NORMAL)) hide_controls(sp); } } int control_panel_height(snd_info *sp) { return(widget_height(CONTROL_PANEL(sp))); } /* -------- PROGRESS REPORT -------- */ void progress_report(chan_info *cp, mus_float_t pct) { snd_info *sp; sp = cp->sound; if ((!sp) || (sp->inuse != SOUND_NORMAL) || (cp->chan != 0) || (sp->channel_style == CHANNELS_SUPERIMPOSED)) return; { cp->progress_pct = pct; show_happy_face(sound_pix_wn(cp), pct); } check_for_event(); } void finish_progress_report(chan_info *cp) { snd_info *sp; sp = cp->sound; if ((!sp) || (sp->inuse != SOUND_NORMAL) || (cp->chan != 0) || (sp->channel_style == CHANNELS_SUPERIMPOSED)) return; { cp->progress_pct = -1.0; hide_happy_face(sound_pix_wn(cp)); } hide_stop_sign(sp); } void start_progress_report(chan_info *cp) { snd_info *sp; sp = cp->sound; if ((!sp) || (sp->inuse != SOUND_NORMAL) || (cp->chan != 0) || (sp->channel_style == CHANNELS_SUPERIMPOSED)) return; { cp->progress_pct = 0.0; show_happy_face(sound_pix_wn(cp), 0.0); } show_stop_sign(sp); } void reflect_sound_selection(snd_info *sp) { snd_info *osp = NULL; if (ss->selected_sound != NO_SELECTION) osp = ss->sounds[ss->selected_sound]; if ((osp) && (sp != osp) && (osp->inuse == SOUND_NORMAL)) widget_modify_fg(NAME_BUTTON(osp), GTK_STATE_NORMAL, ss->black); if ((NAME_BUTTON(sp)) && (sp->selected_channel != NO_SELECTION)) widget_modify_fg(NAME_BUTTON(sp), GTK_STATE_NORMAL, ss->red); if (sound_style(ss) == SOUNDS_IN_NOTEBOOK) { int page, current_page; current_page = gtk_notebook_get_current_page(GTK_NOTEBOOK(SOUND_PANE_BOX(ss))); page = sp->page; if ((page != current_page) && (current_page >= 0)) { ss->selected_sound = sp->index; /* break infinite recursion here */ gtk_notebook_set_current_page(GTK_NOTEBOOK(SOUND_PANE_BOX(ss)), page); } } } /* -------- controls dialog -------- */ static GtkWidget *controls_dialog = NULL; enum {EXPAND_HOP, EXPAND_LENGTH, EXPAND_RAMP, EXPAND_JITTER, CONTRAST_AMP, REVERB_LOWPASS, REVERB_FEEDBACK}; static GtkAdjustment *controls[7]; static void reset_all_sliders(void) { expand_control_set_hop(DEFAULT_EXPAND_CONTROL_HOP); expand_control_set_length(DEFAULT_EXPAND_CONTROL_LENGTH); expand_control_set_ramp(DEFAULT_EXPAND_CONTROL_RAMP); expand_control_set_jitter(DEFAULT_EXPAND_CONTROL_JITTER); contrast_control_set_amp(DEFAULT_CONTRAST_CONTROL_AMP); reverb_control_set_lowpass(DEFAULT_REVERB_CONTROL_LOWPASS); reverb_control_set_feedback(DEFAULT_REVERB_CONTROL_FEEDBACK); ADJUSTMENT_SET_VALUE(controls[EXPAND_HOP], expand_control_hop(ss)); ADJUSTMENT_SET_VALUE(controls[EXPAND_LENGTH], expand_control_length(ss)); ADJUSTMENT_SET_VALUE(controls[EXPAND_RAMP], expand_control_ramp(ss)); ADJUSTMENT_SET_VALUE(controls[EXPAND_JITTER], expand_control_jitter(ss)); ADJUSTMENT_SET_VALUE(controls[CONTRAST_AMP], contrast_control_amp(ss)); ADJUSTMENT_SET_VALUE(controls[REVERB_LOWPASS], reverb_control_lowpass(ss)); ADJUSTMENT_SET_VALUE(controls[REVERB_FEEDBACK], reverb_control_feedback(ss)); } static void controls_reset_callback(GtkWidget *w, gpointer context) { reset_all_sliders(); } static void controls_help_callback(GtkWidget *w, gpointer context) { snd_help("More controls", "This dialog controls all the otherwise hidden control-panel variables.\n\ Expand-hop sets the time in seconds between successive grains.\n\ Expand-length sets the length of each grain.\n\ Expand-ramp sets the ramp-time in the grain envelope.\n\ Expand-jitter sets the grain timing jitter.\n\ Contrast-amp sets the prescaler for contrast-enhancement.\n\ Reverb-lowpass sets the feedback lowpass filter coeficient.\n\ Reverb-feedback sets the scaler on the feedback.", WITHOUT_WORD_WRAP); } static void controls_dismiss_callback(GtkWidget *w, gpointer context) { gtk_widget_hide(controls_dialog); } static gint delete_controls_dialog(GtkWidget *w, GdkEvent *event, gpointer context) { gtk_widget_hide(controls_dialog); return(true); } static void expand_hop_callback(GtkAdjustment *adj, gpointer context) { expand_control_set_hop(ADJUSTMENT_VALUE(adj)); } static void expand_length_callback(GtkAdjustment *adj, gpointer context) { expand_control_set_length(ADJUSTMENT_VALUE(adj)); } static void expand_ramp_callback(GtkAdjustment *adj, gpointer context) { expand_control_set_ramp(ADJUSTMENT_VALUE(adj)); } static void expand_jitter_callback(GtkAdjustment *adj, gpointer context) { expand_control_set_jitter(ADJUSTMENT_VALUE(adj)); } static void contrast_amp_callback(GtkAdjustment *adj, gpointer context) { contrast_control_set_amp(ADJUSTMENT_VALUE(adj)); } static void reverb_lowpass_callback(GtkAdjustment *adj, gpointer context) { reverb_control_set_lowpass(ADJUSTMENT_VALUE(adj)); } static void reverb_feedback_callback(GtkAdjustment *adj, gpointer context) { reverb_control_set_feedback(ADJUSTMENT_VALUE(adj)); } static void add_control(GtkWidget *main, const char *name, int loc, mus_float_t init, mus_float_t low, mus_float_t high, void (*callback)(GtkAdjustment *adj, gpointer context)) { GtkWidget *scale, *frame; GtkAdjustment *scale_adj; frame = gtk_frame_new(name); gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN); gtk_box_pack_start(GTK_BOX(main), frame, true, true, 10); gtk_widget_show(frame); scale_adj = (GtkAdjustment *)gtk_adjustment_new(init, low, high, 0.001, 0.001, .1); scale = gtk_hscale_new(GTK_ADJUSTMENT(scale_adj)); UNSET_CAN_FOCUS(scale); gtk_range_set_update_policy(GTK_RANGE(GTK_SCALE(scale)), GTK_UPDATE_CONTINUOUS); gtk_scale_set_digits(GTK_SCALE(scale), 3); gtk_scale_set_value_pos(GTK_SCALE(scale), GTK_POS_TOP); gtk_scale_set_draw_value(GTK_SCALE(scale), true); gtk_container_add(GTK_CONTAINER(frame), scale); SG_SIGNAL_CONNECT(scale_adj, "value_changed", callback, NULL); gtk_widget_show(scale); controls[loc] = scale_adj; } void make_controls_dialog(void) { if (!controls_dialog) { GtkWidget* mainbox, *help_button, *dismiss_button, *reset_button; controls_dialog = snd_gtk_dialog_new(); #if GTK_CHECK_VERSION(3, 14, 0) gtk_window_set_transient_for(GTK_WINDOW(controls_dialog), GTK_WINDOW(MAIN_SHELL(ss))); #endif SG_SIGNAL_CONNECT(controls_dialog, "delete_event", delete_controls_dialog, NULL); gtk_window_set_title(GTK_WINDOW(controls_dialog), "Controls"); sg_make_resizable(controls_dialog); gtk_container_set_border_width (GTK_CONTAINER(controls_dialog), 4); gtk_widget_realize(controls_dialog); gtk_window_resize(GTK_WINDOW(controls_dialog), 400, 500); help_button = gtk_dialog_add_button(GTK_DIALOG(controls_dialog), "Help", GTK_RESPONSE_NONE); reset_button = gtk_dialog_add_button(GTK_DIALOG(controls_dialog), "Revert", GTK_RESPONSE_NONE); dismiss_button = gtk_dialog_add_button(GTK_DIALOG(controls_dialog), "Go away", GTK_RESPONSE_NONE); gtk_widget_set_name(help_button, "dialog_button"); gtk_widget_set_name(dismiss_button, "dialog_button"); gtk_widget_set_name(reset_button, "dialog_button"); #if GTK_CHECK_VERSION(3, 0, 0) add_highlight_button_style(dismiss_button); add_highlight_button_style(reset_button); add_highlight_button_style(help_button); #endif SG_SIGNAL_CONNECT(dismiss_button, "clicked", controls_dismiss_callback, NULL); SG_SIGNAL_CONNECT(help_button, "clicked", controls_help_callback, NULL); SG_SIGNAL_CONNECT(reset_button, "clicked", controls_reset_callback, NULL); gtk_widget_show(dismiss_button); gtk_widget_show(reset_button); gtk_widget_show(help_button); mainbox = DIALOG_CONTENT_AREA(GTK_DIALOG(controls_dialog)); add_control(mainbox, "expand hop", EXPAND_HOP, expand_control_hop(ss), .001, .3, expand_hop_callback); add_control(mainbox, "expand length", EXPAND_LENGTH, expand_control_length(ss), .01, .5, expand_length_callback); add_control(mainbox, "expand ramp", EXPAND_RAMP, expand_control_ramp(ss), .01, .5, expand_ramp_callback); add_control(mainbox, "expand jitter", EXPAND_JITTER, expand_control_jitter(ss), 0.0, 2.0, expand_jitter_callback); add_control(mainbox, "contrast amp", CONTRAST_AMP, contrast_control_amp(ss), 0.0, 2.0, contrast_amp_callback); add_control(mainbox, "reverb lowpass", REVERB_LOWPASS, reverb_control_lowpass(ss), 0.0, 1.0, reverb_lowpass_callback); add_control(mainbox, "reverb feedback", REVERB_FEEDBACK, reverb_control_feedback(ss), 0.0, 1.25, reverb_feedback_callback); set_dialog_widget(CONTROLS_DIALOG, controls_dialog); } else raise_dialog(controls_dialog); gtk_widget_show(controls_dialog); } /* ---------------------------------------- */ static Xen g_sound_widgets(Xen snd) { #define H_sound_widgets "(" S_sound_widgets " :optional snd): a list of \ widgets: ((0)pane (1)name (2)control-panel (3)status area (4)play-button (5)filter-env (6)unite-button (7)name-label (8)name-icon) (9)\ pane-box (10)name-form" snd_info *sp; Snd_assert_sound(S_sound_widgets, snd, 1); sp = get_sp(snd); if (sp == NULL) return(snd_no_such_sound_error(S_sound_widgets, snd)); if (!has_widgets(sp)) return(Xen_empty_list); return(Xen_cons(Xen_wrap_widget(SND_PANE(sp)), Xen_cons(Xen_wrap_widget(NAME_BUTTON(sp)), Xen_cons(Xen_wrap_widget(CONTROL_PANEL(sp)), Xen_cons(Xen_wrap_widget(STATUS_AREA(sp)), #if WITH_AUDIO Xen_cons(Xen_wrap_widget(PLAY_BUTTON(sp)), #else Xen_cons(Xen_false, #endif Xen_cons(Xen_wrap_widget(FILTER_ENV(sp)), /* this is the (filter) drawingarea widget */ Xen_cons(Xen_wrap_widget(UNITE_BUTTON(sp)), Xen_cons(Xen_false, Xen_cons(Xen_wrap_widget(NAME_PIX(sp)), Xen_cons(Xen_wrap_widget(PANE_BOX(sp)), Xen_cons(Xen_wrap_widget(NAME_HBOX(sp)), Xen_empty_list)))))))))))); } Xen_wrap_1_optional_arg(g_sound_widgets_w, g_sound_widgets) /* -------------------------------------------------------------------------------- */ static Xen mouse_enter_text_hook; static Xen mouse_leave_text_hook; static gboolean mouse_enter_text_callback(GtkWidget *w, GdkEventCrossing *ev, gpointer unknown) { if (with_pointer_focus(ss)) goto_window(w); widget_modify_base(w, GTK_STATE_NORMAL, ss->white); if (Xen_hook_has_list(mouse_enter_text_hook)) run_hook(mouse_enter_text_hook, Xen_list_1(Xen_wrap_widget(w)), S_mouse_enter_text_hook); cursor_set_blinks(w, true); return(false); } static gboolean mouse_leave_text_callback(GtkWidget *w, GdkEventCrossing *ev, gpointer unknown) { widget_modify_base(w, GTK_STATE_NORMAL, ss->basic_color); if (Xen_hook_has_list(mouse_leave_text_hook)) run_hook(mouse_leave_text_hook, Xen_list_1(Xen_wrap_widget(w)), S_mouse_leave_text_hook); cursor_set_blinks(w, false); return(false); } void connect_mouse_to_text(GtkWidget *text) { SG_SIGNAL_CONNECT(text, "enter_notify_event", mouse_enter_text_callback, NULL); SG_SIGNAL_CONNECT(text, "leave_notify_event", mouse_leave_text_callback, NULL); } static bool bindings_ok = false; GtkWidget *snd_entry_new(GtkWidget *container, GtkWidget *prev, snd_entry_bg_t with_white_background) { GtkWidget *text; GtkSettings *settings; text = gtk_entry_new(); gtk_editable_set_editable(GTK_EDITABLE(text), true); add_entry_style(text); settings = gtk_widget_get_settings(text); g_object_set(settings, "gtk-entry-select-on-focus", false, NULL); #if HAVE_GTK_GRID_NEW if (prev) { g_object_set(text, "margin", 2, NULL); gtk_widget_set_halign(text, GTK_ALIGN_FILL); gtk_widget_set_hexpand(text, true); gtk_grid_attach_next_to(GTK_GRID(container), text, prev, GTK_POS_RIGHT, 1, 1); } else gtk_box_pack_start(GTK_BOX(container), text, true, true, 2); #else gtk_box_pack_start(GTK_BOX(container), text, true, true, 2); #endif if (!bindings_ok) { bindings_ok = true; glistener_key_bindings(ss->listener, GTK_ENTRY_GET_CLASS(GTK_ENTRY(text))); } gtk_widget_show(text); #if (!GTK_CHECK_VERSION(3, 0, 0)) if (with_white_background == WITH_WHITE_BACKGROUND) { widget_modify_bg(text, GTK_STATE_NORMAL, ss->white); widget_modify_base(text, GTK_STATE_SELECTED, ss->white); } #endif connect_mouse_to_text(text); return(text); } GtkWidget *snd_entry_new_with_size(GtkWidget *container, int size) { GtkWidget *text; GtkSettings *settings; text = gtk_entry_new(); gtk_editable_set_editable(GTK_EDITABLE(text), true); gtk_entry_set_width_chars(GTK_ENTRY(text), size); add_entry_style(text); settings = gtk_widget_get_settings(text); g_object_set(settings, "gtk-entry-select-on-focus", false, NULL); gtk_box_pack_start(GTK_BOX(container), text, false, false, 4); if (!bindings_ok) { bindings_ok = true; glistener_key_bindings(ss->listener, GTK_ENTRY_GET_CLASS(GTK_ENTRY(text))); } gtk_widget_show(text); #if (!GTK_CHECK_VERSION(3, 0, 0)) widget_modify_bg(text, GTK_STATE_NORMAL, ss->white); widget_modify_base(text, GTK_STATE_SELECTED, ss->white); #endif connect_mouse_to_text(text); return(text); } void g_init_gxsnd(void) { Xen_add_to_hook_list(ss->snd_open_file_hook, reflect_file_close_in_sync_w, "sync-open-file-watcher", "sound sync open-file-hook handler"); Xen_define_procedure(S_sound_widgets, g_sound_widgets_w, 0, 1, 0, H_sound_widgets); #if HAVE_SCHEME #define H_mouse_enter_text_hook S_mouse_enter_text_hook " (widget): called when the mouse enters a text widget:\n\ (hook-push " S_mouse_enter_text_hook "\n\ (lambda (w)\n\ (" S_focus_widget " w)))" #endif #if HAVE_RUBY #define H_mouse_enter_text_hook S_mouse_enter_text_hook " (widget): called when the mouse enters a text widget:\n\ $mouse_enter_text_hook.add_hook!(\"enter\") do |w|\n\ focus_widget(w)\n\ end" #endif #if HAVE_FORTH #define H_mouse_enter_text_hook S_mouse_enter_text_hook " (widget): called when the mouse enters a text widget:\n\ " S_mouse_enter_text_hook " lambda: <{ wid }> wid " S_focus_widget " ; add-hook!" #endif #define H_mouse_leave_text_hook S_mouse_leave_text_hook " (widget): called when the mouse leaves a text widget" mouse_enter_text_hook = Xen_define_hook(S_mouse_enter_text_hook, "(make-hook 'widget)", 1, H_mouse_enter_text_hook); mouse_leave_text_hook = Xen_define_hook(S_mouse_leave_text_hook, "(make-hook 'widget)", 1, H_mouse_leave_text_hook); } snd-16.1/io.c0000644000076400007640000030537212602344275011125 0ustar bilbil#include "mus-config.h" #if (defined(__GNUC__)) && (!(defined(__cplusplus))) #define _GNU_SOURCE /* this is needed to get the vasprintf declaration */ #endif #if USE_SND #include "snd.h" #endif #include #include #include #include #include #include #ifndef _MSC_VER #include #else #include #pragma warning(disable: 4244) #endif #include #include #ifdef _MSC_VER #include #endif #include #include "_sndlib.h" #define HAVE_BYTESWAP_H __linux__ #define MUS_BYTE_TO_SAMPLE(n) (((mus_float_t)(n) / (mus_float_t)(1 << 7))) #define MUS_SHORT_TO_SAMPLE(n) (((mus_float_t)(n) / (mus_float_t)(1 << 15))) #define MUS_INT_TO_SAMPLE(n) (((mus_float_t)(n) / (mus_float_t)(1 << 23))) #define MUS_INT24_TO_SAMPLE(n) (((mus_float_t)(n) / (mus_float_t)(1 << 23))) #define MUS_SAMPLE_TO_INT(n) ((int)((n) * (1 << 23))) #define MUS_SAMPLE_TO_INT24(n) ((int)((n) * (1 << 23))) #define MUS_SAMPLE_TO_SHORT(n) ((short)((n) * (1 << 15))) #define MUS_SAMPLE_TO_BYTE(n) ((char)((n) * (1 << 7))) #if defined(__x86_64__) || defined(__i386__) #define BINT24_TO_SAMPLE(n) ((mus_float_t)(big_endian_int(jchar) >> 8) / (mus_float_t)(1 << 23)) #define INT24_TO_SAMPLE(n) ((mus_float_t)(little_endian_int(jchar) >> 8) / (mus_float_t)(1 << 23)) #else #define BINT24_TO_SAMPLE(n) ((mus_float_t)(mus_char_to_bint(jchar) >> 8) / (mus_float_t)(1 << 23)) #define INT24_TO_SAMPLE(n) ((mus_float_t)(mus_char_to_lint(jchar) >> 8) / (mus_float_t)(1 << 23)) #endif static mus_long_t mus_maximum_malloc = MUS_MAX_MALLOC_DEFAULT; mus_long_t mus_max_malloc(void) { return(mus_maximum_malloc); } mus_long_t mus_set_max_malloc(mus_long_t new_max) { mus_maximum_malloc = new_max; return(new_max); } static mus_long_t mus_maximum_table_size = MUS_MAX_TABLE_SIZE_DEFAULT; mus_long_t mus_max_table_size(void) { return(mus_maximum_table_size); } mus_long_t mus_set_max_table_size(mus_long_t new_max) { mus_maximum_table_size = new_max; return(new_max); } void mus_bint_to_char(unsigned char *j, int x) { unsigned char *ox = (unsigned char *)&x; #if MUS_LITTLE_ENDIAN j[0] = ox[3]; j[1] = ox[2]; j[2] = ox[1]; j[3] = ox[0]; #else memcpy((void *)j, (void *)ox, 4); #endif } int mus_char_to_bint(const unsigned char *inp) { int o; unsigned char *outp = (unsigned char *)&o; #if MUS_LITTLE_ENDIAN outp[0] = inp[3]; outp[1] = inp[2]; outp[2] = inp[1]; outp[3] = inp[0]; #else memcpy((void *)outp, (void *)inp, 4); #endif return(o); } void mus_lint_to_char(unsigned char *j, int x) { unsigned char *ox = (unsigned char *)&x; #if (!MUS_LITTLE_ENDIAN) j[0] = ox[3]; j[1] = ox[2]; j[2] = ox[1]; j[3] = ox[0]; #else memcpy((void *)j, (void *)ox, 4); #endif } int mus_char_to_lint(const unsigned char *inp) { int o; unsigned char *outp = (unsigned char *)&o; #if (!MUS_LITTLE_ENDIAN) outp[0] = inp[3]; outp[1] = inp[2]; outp[2] = inp[1]; outp[3] = inp[0]; #else memcpy((void *)outp, (void *)inp, 4); #endif return(o); } void mus_blong_to_char(unsigned char *j, mus_long_t x) { unsigned char *ox = (unsigned char *)&x; #if (!MUS_LITTLE_ENDIAN) memcpy((void *)j, (void *)ox, 8); #else j[0] = ox[7]; j[1] = ox[6]; j[2] = ox[5]; j[3] = ox[4]; j[4] = ox[3]; j[5] = ox[2]; j[6] = ox[1]; j[7] = ox[0]; #endif } mus_long_t mus_char_to_blong(const unsigned char *inp) { mus_long_t o; unsigned char *outp = (unsigned char *)&o; #if MUS_LITTLE_ENDIAN outp[0] = inp[7]; outp[1] = inp[6]; outp[2] = inp[5]; outp[3] = inp[4]; outp[4] = inp[3]; outp[5] = inp[2]; outp[6] = inp[1]; outp[7] = inp[0]; #else memcpy((void *)outp, (void *)inp, 8); #endif return(o); } void mus_llong_to_char(unsigned char *j, mus_long_t x) { unsigned char *ox = (unsigned char *)&x; #if (MUS_LITTLE_ENDIAN) memcpy((void *)j, (void *)ox, 8); #else j[0] = ox[7]; j[1] = ox[6]; j[2] = ox[5]; j[3] = ox[4]; j[4] = ox[3]; j[5] = ox[2]; j[6] = ox[1]; j[7] = ox[0]; #endif } mus_long_t mus_char_to_llong(const unsigned char *inp) { mus_long_t o; unsigned char *outp = (unsigned char *)&o; #if (!MUS_LITTLE_ENDIAN) outp[0] = inp[7]; outp[1] = inp[6]; outp[2] = inp[5]; outp[3] = inp[4]; outp[4] = inp[3]; outp[5] = inp[2]; outp[6] = inp[1]; outp[7] = inp[0]; #else memcpy((void *)outp, (void *)inp, 8); #endif return(o); } void mus_bfloat_to_char(unsigned char *j, float x) { unsigned char *ox = (unsigned char *)&x; #if MUS_LITTLE_ENDIAN j[0] = ox[3]; j[1] = ox[2]; j[2] = ox[1]; j[3] = ox[0]; #else memcpy((void *)j, (void *)ox, 4); #endif } float mus_char_to_bfloat(const unsigned char *inp) { float o; unsigned char *outp = (unsigned char *)&o; #if MUS_LITTLE_ENDIAN outp[0] = inp[3]; outp[1] = inp[2]; outp[2] = inp[1]; outp[3] = inp[0]; #else memcpy((void *)outp, (void *)inp, 4); #endif return(o); } void mus_lfloat_to_char(unsigned char *j, float x) { unsigned char *ox = (unsigned char *)&x; #if (!MUS_LITTLE_ENDIAN) j[0] = ox[3]; j[1] = ox[2]; j[2] = ox[1]; j[3] = ox[0]; #else memcpy((void *)j, (void *)ox, 4); #endif } float mus_char_to_lfloat(const unsigned char *inp) { float o; unsigned char *outp = (unsigned char *)&o; #if (!MUS_LITTLE_ENDIAN) outp[0] = inp[3]; outp[1] = inp[2]; outp[2] = inp[1]; outp[3] = inp[0]; #else memcpy((void *)outp, (void *)inp, 4); #endif return(o); } void mus_bshort_to_char(unsigned char *j, short x) { unsigned char *ox = (unsigned char *)&x; #if MUS_LITTLE_ENDIAN j[0] = ox[1]; j[1] = ox[0]; #else memcpy((void *)j, (void *)ox, 2); /* I wonder if this is faster */ #endif } short mus_char_to_bshort(const unsigned char *inp) { short o; unsigned char *outp = (unsigned char *)&o; #if MUS_LITTLE_ENDIAN outp[0] = inp[1]; outp[1] = inp[0]; #else memcpy((void *)outp, (void *)inp, 2); #endif return(o); } void mus_lshort_to_char(unsigned char *j, short x) { unsigned char *ox = (unsigned char *)&x; #if (!MUS_LITTLE_ENDIAN) j[0] = ox[1]; j[1] = ox[0]; #else memcpy((void *)j, (void *)ox, 2); #endif } short mus_char_to_lshort(const unsigned char *inp) { short o; unsigned char *outp = (unsigned char *)&o; #if (!MUS_LITTLE_ENDIAN) outp[0] = inp[1]; outp[1] = inp[0]; #else memcpy((void *)outp, (void *)inp, 2); #endif return(o); } #if ((MUS_LITTLE_ENDIAN) && (!HAVE_BYTESWAP_H)) || ((!MUS_LITTLE_ENDIAN) && (HAVE_SUN)) static void mus_ubshort_to_char(unsigned char *j, unsigned short x) { unsigned char *ox = (unsigned char *)&x; #if MUS_LITTLE_ENDIAN j[0] = ox[1]; j[1] = ox[0]; #else memcpy((void *)j, (void *)ox, 2); #endif } #endif unsigned short mus_char_to_ubshort(const unsigned char *inp) { unsigned short o; unsigned char *outp = (unsigned char *)&o; #if MUS_LITTLE_ENDIAN outp[0] = inp[1]; outp[1] = inp[0]; #else memcpy((void *)outp, (void *)inp, 2); #endif return(o); } #if (!MUS_LITTLE_ENDIAN) && (!HAVE_BYTESWAP_H) static void mus_ulshort_to_char(unsigned char *j, unsigned short x) { unsigned char *ox = (unsigned char *)&x; #if (!MUS_LITTLE_ENDIAN) j[0] = ox[1]; j[1] = ox[0]; #else memcpy((void *)j, (void *)ox, 2); #endif } #endif unsigned short mus_char_to_ulshort(const unsigned char *inp) { unsigned short o; unsigned char *outp = (unsigned char *)&o; #if (!MUS_LITTLE_ENDIAN) outp[0] = inp[1]; outp[1] = inp[0]; #else memcpy((void *)outp, (void *)inp, 2); #endif return(o); } void mus_bdouble_to_char(unsigned char *j, double x) { unsigned char *ox = (unsigned char *)&x; #if (MUS_LITTLE_ENDIAN) j[0] = ox[7]; j[1] = ox[6]; j[2] = ox[5]; j[3] = ox[4]; j[4] = ox[3]; j[5] = ox[2]; j[6] = ox[1]; j[7] = ox[0]; #else memcpy((void *)j, (void *)ox, 8); #endif } double mus_char_to_ldouble(const unsigned char *inp) { double o; unsigned char *outp = (unsigned char *)&o; #if (MUS_LITTLE_ENDIAN) memcpy((void *)outp, (void *)inp, 8); #else outp[0] = inp[7]; outp[1] = inp[6]; outp[2] = inp[5]; outp[3] = inp[4]; outp[4] = inp[3]; outp[5] = inp[2]; outp[6] = inp[1]; outp[7] = inp[0]; #endif return(o); } #if (!MUS_LITTLE_ENDIAN) static void mus_ldouble_to_char(unsigned char *j, double x) { unsigned char *ox = (unsigned char *)&x; #if (MUS_LITTLE_ENDIAN) memcpy((void *)j, (void *)ox, 8); #else j[0] = ox[7]; j[1] = ox[6]; j[2] = ox[5]; j[3] = ox[4]; j[4] = ox[3]; j[5] = ox[2]; j[6] = ox[1]; j[7] = ox[0]; #endif } #endif double mus_char_to_bdouble(const unsigned char *inp) { double o; unsigned char *outp = (unsigned char *)&o; #if (MUS_LITTLE_ENDIAN) outp[0] = inp[7]; outp[1] = inp[6]; outp[2] = inp[5]; outp[3] = inp[4]; outp[4] = inp[3]; outp[5] = inp[2]; outp[6] = inp[1]; outp[7] = inp[0]; #else memcpy((void *)outp, (void *)inp, 8); #endif return(o); } int mus_char_to_uninterpreted_int(const unsigned char *inp) { int o; unsigned char *outp = (unsigned char *)&o; memcpy((void *)outp, (void *)inp, 4); return(o); } unsigned int mus_char_to_ubint(const unsigned char *inp) { unsigned int o; unsigned char *outp = (unsigned char *)&o; #if MUS_LITTLE_ENDIAN outp[0] = inp[3]; outp[1] = inp[2]; outp[2] = inp[1]; outp[3] = inp[0]; #else memcpy((void *)outp, (void *)inp, 4); #endif return(o); } unsigned int mus_char_to_ulint(const unsigned char *inp) { unsigned int o; unsigned char *outp = (unsigned char *)&o; #if (!MUS_LITTLE_ENDIAN) outp[0] = inp[3]; outp[1] = inp[2]; outp[2] = inp[1]; outp[3] = inp[0]; #else memcpy((void *)outp, (void *)inp, 4); #endif return(o); } #if HAVE_BYTESWAP_H #include #endif #if MUS_LITTLE_ENDIAN #if HAVE_BYTESWAP_H #define big_endian_short(n) ((short)(bswap_16((*((unsigned short *)n))))) #define big_endian_int(n) ((int)(bswap_32((*((unsigned int *)n))))) #define big_endian_unsigned_short(n) ((unsigned short)(bswap_16((*((unsigned short *)n))))) #else #define big_endian_short(n) (mus_char_to_bshort(n)) #define big_endian_int(n) (mus_char_to_bint(n)) #define big_endian_unsigned_short(n) (mus_char_to_ubshort(n)) #endif #if __GNUC__ && HAVE_BYTESWAP_H /* these work, but newer versions of gcc complain about strict aliasing rules * #define big_endian_float(n) ({unsigned int x; x = bswap_32((*((unsigned int *)n))); (*((float *)&x));}) * #define big_endian_double(n) ({unsigned long long int x; x = bswap_64((*((unsigned long long int *)n))); (*((double *)&x));}) */ typedef struct {union {unsigned int i; float f;} u;} uiflt; typedef struct {union {unsigned long long int l; double d;} u;} uidbl; #define big_endian_float(n) ({uiflt x; x.u.i = bswap_32((*((unsigned int *)n))); x.u.f;}) #define big_endian_double(n) ({uidbl x; x.u.l = bswap_64((*((unsigned long long int *)n))); x.u.d;}) #else #define big_endian_float(n) (mus_char_to_bfloat(n)) #define big_endian_double(n) (mus_char_to_bdouble(n)) #endif #define little_endian_short(n) (*((short *)n)) #define little_endian_int(n) (*((int *)n)) #define little_endian_float(n) (*((float *)n)) #define little_endian_double(n) (*((double *)n)) #define little_endian_unsigned_short(n) (*((unsigned short *)n)) #if HAVE_BYTESWAP_H #define set_big_endian_short(n, x) (*((short *)n)) = ((short)(bswap_16(x))) #define set_big_endian_int(n, x) (*((int *)n)) = ((int)(bswap_32(x))) #define set_big_endian_unsigned_short(n, x) (*((unsigned short *)n)) = ((unsigned short)(bswap_16(x))) #else #define set_big_endian_short(n, x) mus_bshort_to_char(n, x) #define set_big_endian_int(n, x) mus_bint_to_char(n, x) #define set_big_endian_unsigned_short(n, x) mus_ubshort_to_char(n, x) #endif #define set_big_endian_float(n, x) mus_bfloat_to_char(n, x) #define set_big_endian_double(n, x) mus_bdouble_to_char(n, x) #define set_little_endian_short(n, x) (*((short *)n)) = x #define set_little_endian_int(n, x) (*((int *)n)) = x #define set_little_endian_float(n, x) (*((float *)n)) = x #define set_little_endian_double(n, x) (*((double *)n)) = x #define set_little_endian_unsigned_short(n, x) (*((unsigned short *)n)) = x #else #if (!HAVE_SUN) #define big_endian_short(n) (*((short *)n)) #define big_endian_int(n) (*((int *)n)) #define big_endian_float(n) (*((float *)n)) #define big_endian_double(n) (*((double *)n)) #define big_endian_unsigned_short(n) (*((unsigned short *)n)) #define set_big_endian_short(n, x) (*((short *)n)) = x #define set_big_endian_int(n, x) (*((int *)n)) = x #define set_big_endian_float(n, x) (*((float *)n)) = x #define set_big_endian_double(n, x) (*((double *)n)) = x #define set_big_endian_unsigned_short(n, x) (*((unsigned short *)n)) = x #else #define big_endian_short(n) (mus_char_to_bshort(n)) #define big_endian_int(n) (mus_char_to_bint(n)) #define big_endian_float(n) (mus_char_to_bfloat(n)) #define big_endian_double(n) (mus_char_to_bdouble(n)) #define big_endian_unsigned_short(n) (mus_char_to_ubshort(n)) #define set_big_endian_short(n, x) mus_bshort_to_char(n, x) #define set_big_endian_int(n, x) mus_bint_to_char(n, x) #define set_big_endian_float(n, x) mus_bfloat_to_char(n, x) #define set_big_endian_double(n, x) mus_bdouble_to_char(n, x) #define set_big_endian_unsigned_short(n, x) mus_ubshort_to_char(n, x) #endif #if HAVE_BYTESWAP_H #define little_endian_short(n) ((short)(bswap_16((*((unsigned short *)n))))) #define little_endian_int(n) ((int)(bswap_32((*((unsigned int *)n))))) #define little_endian_unsigned_short(n) ((unsigned short)(bswap_16((*((unsigned short *)n))))) #else #define little_endian_short(n) (mus_char_to_lshort(n)) #define little_endian_int(n) (mus_char_to_lint(n)) #define little_endian_unsigned_short(n) (mus_char_to_ulshort(n)) #endif #if __GNUC__ && HAVE_BYTESWAP_H #define little_endian_float(n) ({unsigned int x; x = bswap_32((*((unsigned int *)n))); (*((float *)&x));}) #define little_endian_double(n) ({unsigned long long int x; x = bswap_64((*((unsigned long long int *)n))); (*((double *)&x));}) #else #define little_endian_float(n) (mus_char_to_lfloat(n)) #define little_endian_double(n) (mus_char_to_ldouble(n)) #endif #if HAVE_BYTESWAP_H #define set_little_endian_short(n, x) (*((short *)n)) = ((short)(bswap_16(x))) #define set_little_endian_int(n, x) (*((int *)n)) = ((int)(bswap_32(x))) #define set_little_endian_unsigned_short(n, x) (*((unsigned short *)n)) = ((unsigned short)(bswap_16(x))) #else #define set_little_endian_short(n, x) mus_lshort_to_char(n, x) #define set_little_endian_int(n, x) mus_lint_to_char(n, x) #define set_little_endian_unsigned_short(n, x) mus_ulshort_to_char(n, x) #endif #define set_little_endian_float(n, x) mus_lfloat_to_char(n, x) #define set_little_endian_double(n, x) mus_ldouble_to_char(n, x) #endif /* ---------------- file descriptors ---------------- */ static bool clipping_default = false; bool mus_clipping(void) {return(clipping_default);} bool mus_set_clipping(bool new_value) {clipping_default = new_value; return(new_value);} typedef struct { char *name; mus_sample_t sample_type; mus_header_t header_type; int bytes_per_sample, chans; bool clipping; mus_long_t data_location; bool saved; mus_long_t framples; mus_float_t **saved_data; void *next; } io_fd; static io_fd *io_fd_free_list = NULL; static io_fd *io_fd_alloc(void) { if (io_fd_free_list) { io_fd *p; p = io_fd_free_list; io_fd_free_list = (io_fd *)(p->next); return(p); } return((io_fd *)malloc(sizeof(io_fd))); } static void io_fd_free(io_fd *p) { p->next = (void *)io_fd_free_list; io_fd_free_list = p; } static int io_fd_size = 0; static io_fd **io_fds = NULL; #define IO_FD_ALLOC_SIZE 8 int mus_file_open_descriptors(int tfd, const char *name, mus_sample_t samp_type, int size /* datum size */, mus_long_t location, int chans, mus_header_t type) { int err = MUS_NO_ERROR; if (io_fd_size == 0) { io_fd_size = tfd + IO_FD_ALLOC_SIZE; io_fds = (io_fd **)calloc(io_fd_size, sizeof(io_fd *)); } if (io_fds) { if (io_fd_size <= tfd) { int i, lim; lim = io_fd_size; io_fd_size = tfd + IO_FD_ALLOC_SIZE; io_fds = (io_fd **)realloc(io_fds, io_fd_size * sizeof(io_fd *)); for (i = lim; i < io_fd_size; i++) io_fds[i] = NULL; } if (io_fds[tfd] == NULL) io_fds[tfd] = io_fd_alloc(); if (io_fds[tfd]) { io_fd *fd; fd = io_fds[tfd]; fd->framples = 0; fd->sample_type = samp_type; fd->bytes_per_sample = size; fd->data_location = location; fd->clipping = clipping_default; fd->header_type = type; fd->chans = chans; fd->saved = false; fd->saved_data = NULL; if (name) { int len; len = strlen(name); fd->name = (char *)malloc((len + 1) * sizeof(char)); strcpy(fd->name, name); fd->name[len] = 0; } else fd->name = NULL; } else err = MUS_MEMORY_ALLOCATION_FAILED; } else err = MUS_MEMORY_ALLOCATION_FAILED; return(err); } void scan_io_fds_for_saved_data(mus_float_t **data); void scan_io_fds_for_saved_data(mus_float_t **data) { if ((io_fds) && (io_fd_size > 0)) { int i; for (i = 0; i < io_fd_size; i++) { io_fd *fd; fd = io_fds[i]; if ((fd) && (fd->saved) && (fd->saved_data == data)) { fd->saved = false; fd->saved_data = NULL; } } } } bool mus_file_clipping(int tfd) { io_fd *fd; if ((io_fds == NULL) || (tfd >= io_fd_size) || (tfd < 0) || (io_fds[tfd] == NULL)) return(false); fd = io_fds[tfd]; return(fd->clipping); } int mus_file_set_clipping(int tfd, bool clipped) { io_fd *fd; if ((io_fds == NULL) || (tfd >= io_fd_size) || (tfd < 0) || (io_fds[tfd] == NULL)) return(MUS_FILE_DESCRIPTORS_NOT_INITIALIZED); fd = io_fds[tfd]; fd->clipping = clipped; return(MUS_NO_ERROR); } int mus_file_set_header_type(int tfd, mus_header_t type) { io_fd *fd; if ((io_fds == NULL) || (tfd >= io_fd_size) || (tfd < 0) || (io_fds[tfd] == NULL)) return(MUS_FILE_DESCRIPTORS_NOT_INITIALIZED); fd = io_fds[tfd]; fd->header_type = type; return(MUS_NO_ERROR); } mus_header_t mus_file_header_type(int tfd) { io_fd *fd; if ((io_fds == NULL) || (tfd >= io_fd_size) || (tfd < 0) || (io_fds[tfd] == NULL)) return(MUS_UNKNOWN_HEADER); fd = io_fds[tfd]; return(fd->header_type); } char *mus_file_fd_name(int tfd) { io_fd *fd; if ((io_fds == NULL) || (tfd >= io_fd_size) || (tfd < 0) || (io_fds[tfd] == NULL)) return(NULL); fd = io_fds[tfd]; return(fd->name); } int mus_file_set_chans(int tfd, int chans) { io_fd *fd; if ((io_fds == NULL) || (tfd >= io_fd_size) || (tfd < 0) || (io_fds[tfd] == NULL)) return(MUS_FILE_DESCRIPTORS_NOT_INITIALIZED); fd = io_fds[tfd]; fd->chans = chans; return(MUS_NO_ERROR); } void mus_file_save_data(int tfd, mus_long_t framples, mus_float_t **data) { io_fd *fd; fd = io_fds[tfd]; if (!fd->saved) { /* fprintf(stderr, "mus_file_save_data %d\n", tfd); */ fd->saved = true; fd->framples = framples; fd->saved_data = data; } } /* ---------------- open, creat, close ---------------- */ int mus_file_open_read(const char *arg) { int fd; #if (defined(_MSC_VER) || __CYGWIN__) fd = OPEN(arg, O_RDONLY | O_BINARY, 0); #else fd = OPEN(arg, O_RDONLY, 0); #endif return(fd); } bool mus_file_probe(const char *arg) { #ifndef _MSC_VER if (!arg) return(false); return(access(arg, F_OK) == 0); #else int fd; #ifdef O_NONBLOCK fd = OPEN(arg, O_RDONLY, O_NONBLOCK); #else fd = OPEN(arg, O_RDONLY, 0); #endif if (fd == -1) return(false); CLOSE(fd, arg); return(true); #endif } int mus_file_open_write(const char *arg) { int fd; #if (defined(_MSC_VER) || __CYGWIN__) if ((fd = OPEN(arg, O_RDWR | O_BINARY, 0)) == -1) fd = CREAT(arg, S_IREAD | S_IWRITE); /* 0x0100 | 0x0080 */ #else if ((fd = OPEN(arg, O_RDWR, 0)) == -1) fd = CREAT(arg, 0666); /* equivalent to the new open(arg, O_RDWR | O_CREAT | O_TRUNC, 0666) */ #endif else lseek(fd, 0L, SEEK_END); return(fd); } int mus_file_create(const char *arg) { #if (defined(_MSC_VER ) || __CYGWIN__) return(CREAT(arg, S_IREAD | S_IWRITE)); #else return(CREAT(arg, 0666)); #endif } int mus_file_reopen_write(const char *arg) { int fd; #if (defined(_MSC_VER) || __CYGWIN__) fd = OPEN(arg, O_RDWR | O_BINARY, 0); #else fd = OPEN(arg, O_RDWR, 0); #endif return(fd); } int mus_file_close(int fd) { io_fd *fdp; #if (!USE_SND) int close_result = 0; #endif if ((io_fds == NULL) || (fd >= io_fd_size) || (fd < 0) || (io_fds[fd] == NULL)) return(MUS_FILE_DESCRIPTORS_NOT_INITIALIZED); fdp = io_fds[fd]; #if USE_SND CLOSE(fd, fdp->name); #else close_result = close(fd); #endif if (fdp->name) {free(fdp->name); fdp->name = NULL;} io_fd_free(fdp); io_fds[fd] = NULL; #if (!USE_SND) if (close_result < 0) return(MUS_CANT_CLOSE_FILE); #endif return(MUS_NO_ERROR); } /* ---------------- seek ---------------- */ mus_long_t mus_file_seek_frample(int tfd, mus_long_t frample) { io_fd *fd; if (io_fds == NULL) return(mus_error(MUS_FILE_DESCRIPTORS_NOT_INITIALIZED, "mus_file_seek_frample: no file descriptors!")); if (tfd >= io_fd_size) return(mus_error(MUS_FILE_DESCRIPTORS_NOT_INITIALIZED, "mus_file_seek_frample: file descriptors not realloc'd? (tfd: %d, io_fd_size: %d)", tfd, io_fd_size)); if ((tfd < 0) || (io_fds[tfd] == NULL)) return(mus_error(MUS_FILE_DESCRIPTORS_NOT_INITIALIZED, "mus_file_seek_frample: file descriptor = %d?", tfd)); fd = io_fds[tfd]; if (fd->sample_type == MUS_UNKNOWN_SAMPLE) return(mus_error(MUS_NOT_A_SOUND_FILE, "mus_file_seek_frample: invalid sample type for %s", fd->name)); return(lseek(tfd, fd->data_location + (fd->chans * frample * fd->bytes_per_sample), SEEK_SET)); } /* ---------------- mulaw/alaw conversions ---------------- * * x : input signal with max value 32767 * mu : compression parameter (mu = 255 used for telephony) * y = (32767/log(1+mu))*log(1+mu*abs(x)/32767)*sign(x); -- this isn't right -- typo? */ /* from sox g711.c */ #define QUANT_MASK (0xf) /* Quantization field mask. */ #define SEG_SHIFT (4) /* Left shift for segment number. */ static short seg_end[8] = {0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF}; static int search(int val, short *table, int size) { int i; for (i = 0; i < size; i++) {if (val <= *table++) return(i);} return(size); } static unsigned char to_alaw(int pcm_val) { int mask, seg; if (pcm_val >= 0) mask = 0xD5; else {mask = 0x55; pcm_val = -pcm_val - 8;} seg = search(pcm_val, seg_end, 8); if (seg >= 8) return(0x7F ^ mask); else { unsigned char aval; aval = seg << SEG_SHIFT; if (seg < 2) aval |= (pcm_val >> 4) & QUANT_MASK; else aval |= (pcm_val >> (seg + 3)) & QUANT_MASK; return(aval ^ mask); } } #define A_(a) MUS_SHORT_TO_SAMPLE(a) static const mus_float_t mus_alaw[256] = { A_(-5504), A_(-5248), A_(-6016), A_(-5760), A_(-4480), A_(-4224), A_(-4992), A_(-4736), A_(-7552), A_(-7296), A_(-8064), A_(-7808), A_(-6528), A_(-6272), A_(-7040), A_(-6784), A_(-2752), A_(-2624), A_(-3008), A_(-2880), A_(-2240), A_(-2112), A_(-2496), A_(-2368), A_(-3776), A_(-3648), A_(-4032), A_(-3904), A_(-3264), A_(-3136), A_(-3520), A_(-3392), A_(-22016), A_(-20992), A_(-24064), A_(-23040), A_(-17920), A_(-16896), A_(-19968), A_(-18944), A_(-30208), A_(-29184), A_(-32256), A_(-31232), A_(-26112), A_(-25088), A_(-28160), A_(-27136), A_(-11008), A_(-10496), A_(-12032), A_(-11520), A_(-8960), A_(-8448), A_(-9984), A_(-9472), A_(-15104), A_(-14592), A_(-16128), A_(-15616), A_(-13056), A_(-12544), A_(-14080), A_(-13568), A_(-344), A_(-328), A_(-376), A_(-360), A_(-280), A_(-264), A_(-312), A_(-296), A_(-472), A_(-456), A_(-504), A_(-488), A_(-408), A_(-392), A_(-440), A_(-424), A_(-88), A_(-72), A_(-120), A_(-104), A_(-24), A_(-8), A_(-56), A_(-40), A_(-216), A_(-200), A_(-248), A_(-232), A_(-152), A_(-136), A_(-184), A_(-168), A_(-1376), A_(-1312), A_(-1504), A_(-1440), A_(-1120), A_(-1056), A_(-1248), A_(-1184), A_(-1888), A_(-1824), A_(-2016), A_(-1952), A_(-1632), A_(-1568), A_(-1760), A_(-1696), A_(-688), A_(-656), A_(-752), A_(-720), A_(-560), A_(-528), A_(-624), A_(-592), A_(-944), A_(-912), A_(-1008), A_(-976), A_(-816), A_(-784), A_(-880), A_(-848), A_(5504), A_(5248), A_(6016), A_(5760), A_(4480), A_(4224), A_(4992), A_(4736), A_(7552), A_(7296), A_(8064), A_(7808), A_(6528), A_(6272), A_(7040), A_(6784), A_(2752), A_(2624), A_(3008), A_(2880), A_(2240), A_(2112), A_(2496), A_(2368), A_(3776), A_(3648), A_(4032), A_(3904), A_(3264), A_(3136), A_(3520), A_(3392), A_(22016), A_(20992), A_(24064), A_(23040), A_(17920), A_(16896), A_(19968), A_(18944), A_(30208), A_(29184), A_(32256), A_(31232), A_(26112), A_(25088), A_(28160), A_(27136), A_(11008), A_(10496), A_(12032), A_(11520), A_(8960), A_(8448), A_(9984), A_(9472), A_(15104), A_(14592), A_(16128), A_(15616), A_(13056), A_(12544), A_(14080), A_(13568), A_(344), A_(328), A_(376), A_(360), A_(280), A_(264), A_(312), A_(296), A_(472), A_(456), A_(504), A_(488), A_(408), A_(392), A_(440), A_(424), A_(88), A_(72), A_(120), A_(104), A_(24), A_(8), A_(56), A_(40), A_(216), A_(200), A_(248), A_(232), A_(152), A_(136), A_(184), A_(168), A_(1376), A_(1312), A_(1504), A_(1440), A_(1120), A_(1056), A_(1248), A_(1184), A_(1888), A_(1824), A_(2016), A_(1952), A_(1632), A_(1568), A_(1760), A_(1696), A_(688), A_(656), A_(752), A_(720), A_(560), A_(528), A_(624), A_(592), A_(944), A_(912), A_(1008), A_(976), A_(816), A_(784), A_(880), A_(848) }; #define BIAS (0x84) /* Bias for linear code. */ static unsigned char to_mulaw(int pcm_val) { int mask; int seg; if (pcm_val < 0) {pcm_val = BIAS - pcm_val; mask = 0x7F;} else {pcm_val += BIAS; mask = 0xFF;} seg = search(pcm_val, seg_end, 8); if (seg >= 8) return(0x7F ^ mask); else { unsigned char uval; uval = (seg << 4) | ((pcm_val >> (seg + 3)) & 0xF); return(uval ^ mask); } } #define MU_(a) MUS_SHORT_TO_SAMPLE(a) static const mus_float_t mus_mulaw[256] = { MU_(-32124), MU_(-31100), MU_(-30076), MU_(-29052), MU_(-28028), MU_(-27004), MU_(-25980), MU_(-24956), MU_(-23932), MU_(-22908), MU_(-21884), MU_(-20860), MU_(-19836), MU_(-18812), MU_(-17788), MU_(-16764), MU_(-15996), MU_(-15484), MU_(-14972), MU_(-14460), MU_(-13948), MU_(-13436), MU_(-12924), MU_(-12412), MU_(-11900), MU_(-11388), MU_(-10876), MU_(-10364), MU_(-9852), MU_(-9340), MU_(-8828), MU_(-8316), MU_(-7932), MU_(-7676), MU_(-7420), MU_(-7164), MU_(-6908), MU_(-6652), MU_(-6396), MU_(-6140), MU_(-5884), MU_(-5628), MU_(-5372), MU_(-5116), MU_(-4860), MU_(-4604), MU_(-4348), MU_(-4092), MU_(-3900), MU_(-3772), MU_(-3644), MU_(-3516), MU_(-3388), MU_(-3260), MU_(-3132), MU_(-3004), MU_(-2876), MU_(-2748), MU_(-2620), MU_(-2492), MU_(-2364), MU_(-2236), MU_(-2108), MU_(-1980), MU_(-1884), MU_(-1820), MU_(-1756), MU_(-1692), MU_(-1628), MU_(-1564), MU_(-1500), MU_(-1436), MU_(-1372), MU_(-1308), MU_(-1244), MU_(-1180), MU_(-1116), MU_(-1052), MU_(-988), MU_(-924), MU_(-876), MU_(-844), MU_(-812), MU_(-780), MU_(-748), MU_(-716), MU_(-684), MU_(-652), MU_(-620), MU_(-588), MU_(-556), MU_(-524), MU_(-492), MU_(-460), MU_(-428), MU_(-396), MU_(-372), MU_(-356), MU_(-340), MU_(-324), MU_(-308), MU_(-292), MU_(-276), MU_(-260), MU_(-244), MU_(-228), MU_(-212), MU_(-196), MU_(-180), MU_(-164), MU_(-148), MU_(-132), MU_(-120), MU_(-112), MU_(-104), MU_(-96), MU_(-88), MU_(-80), MU_(-72), MU_(-64), MU_(-56), MU_(-48), MU_(-40), MU_(-32), MU_(-24), MU_(-16), MU_(-8), MU_(0), MU_(32124), MU_(31100), MU_(30076), MU_(29052), MU_(28028), MU_(27004), MU_(25980), MU_(24956), MU_(23932), MU_(22908), MU_(21884), MU_(20860), MU_(19836), MU_(18812), MU_(17788), MU_(16764), MU_(15996), MU_(15484), MU_(14972), MU_(14460), MU_(13948), MU_(13436), MU_(12924), MU_(12412), MU_(11900), MU_(11388), MU_(10876), MU_(10364), MU_(9852), MU_(9340), MU_(8828), MU_(8316), MU_(7932), MU_(7676), MU_(7420), MU_(7164), MU_(6908), MU_(6652), MU_(6396), MU_(6140), MU_(5884), MU_(5628), MU_(5372), MU_(5116), MU_(4860), MU_(4604), MU_(4348), MU_(4092), MU_(3900), MU_(3772), MU_(3644), MU_(3516), MU_(3388), MU_(3260), MU_(3132), MU_(3004), MU_(2876), MU_(2748), MU_(2620), MU_(2492), MU_(2364), MU_(2236), MU_(2108), MU_(1980), MU_(1884), MU_(1820), MU_(1756), MU_(1692), MU_(1628), MU_(1564), MU_(1500), MU_(1436), MU_(1372), MU_(1308), MU_(1244), MU_(1180), MU_(1116), MU_(1052), MU_(988), MU_(924), MU_(876), MU_(844), MU_(812), MU_(780), MU_(748), MU_(716), MU_(684), MU_(652), MU_(620), MU_(588), MU_(556), MU_(524), MU_(492), MU_(460), MU_(428), MU_(396), MU_(372), MU_(356), MU_(340), MU_(324), MU_(308), MU_(292), MU_(276), MU_(260), MU_(244), MU_(228), MU_(212), MU_(196), MU_(180), MU_(164), MU_(148), MU_(132), MU_(120), MU_(112), MU_(104), MU_(96), MU_(88), MU_(80), MU_(72), MU_(64), MU_(56), MU_(48), MU_(40), MU_(32), MU_(24), MU_(16), MU_(8), MU_(0) }; #define B_(a) MUS_BYTE_TO_SAMPLE(a) static const mus_float_t mus_byte[256] = { B_(0), B_(1), B_(2), B_(3), B_(4), B_(5), B_(6), B_(7), B_(8), B_(9), B_(10), B_(11), B_(12), B_(13), B_(14), B_(15), B_(16), B_(17), B_(18), B_(19), B_(20), B_(21), B_(22), B_(23), B_(24), B_(25), B_(26), B_(27), B_(28), B_(29), B_(30), B_(31), B_(32), B_(33), B_(34), B_(35), B_(36), B_(37), B_(38), B_(39), B_(40), B_(41), B_(42), B_(43), B_(44), B_(45), B_(46), B_(47), B_(48), B_(49), B_(50), B_(51), B_(52), B_(53), B_(54), B_(55), B_(56), B_(57), B_(58), B_(59), B_(60), B_(61), B_(62), B_(63), B_(64), B_(65), B_(66), B_(67), B_(68), B_(69), B_(70), B_(71), B_(72), B_(73), B_(74), B_(75), B_(76), B_(77), B_(78), B_(79), B_(80), B_(81), B_(82), B_(83), B_(84), B_(85), B_(86), B_(87), B_(88), B_(89), B_(90), B_(91), B_(92), B_(93), B_(94), B_(95), B_(96), B_(97), B_(98), B_(99), B_(100), B_(101), B_(102), B_(103), B_(104), B_(105), B_(106), B_(107), B_(108), B_(109), B_(110), B_(111), B_(112), B_(113), B_(114), B_(115), B_(116), B_(117), B_(118), B_(119), B_(120), B_(121), B_(122), B_(123), B_(124), B_(125), B_(126), B_(127), B_(-128), B_(-127), B_(-126), B_(-125), B_(-124), B_(-123), B_(-122), B_(-121), B_(-120), B_(-119), B_(-118), B_(-117), B_(-116), B_(-115), B_(-114), B_(-113), B_(-112), B_(-111), B_(-110), B_(-109), B_(-108), B_(-107), B_(-106), B_(-105), B_(-104), B_(-103), B_(-102), B_(-101), B_(-100), B_(-99), B_(-98), B_(-97), B_(-96), B_(-95), B_(-94), B_(-93), B_(-92), B_(-91), B_(-90), B_(-89), B_(-88), B_(-87), B_(-86), B_(-85), B_(-84), B_(-83), B_(-82), B_(-81), B_(-80), B_(-79), B_(-78), B_(-77), B_(-76), B_(-75), B_(-74), B_(-73), B_(-72), B_(-71), B_(-70), B_(-69), B_(-68), B_(-67), B_(-66), B_(-65), B_(-64), B_(-63), B_(-62), B_(-61), B_(-60), B_(-59), B_(-58), B_(-57), B_(-56), B_(-55), B_(-54), B_(-53), B_(-52), B_(-51), B_(-50), B_(-49), B_(-48), B_(-47), B_(-46), B_(-45), B_(-44), B_(-43), B_(-42), B_(-41), B_(-40), B_(-39), B_(-38), B_(-37), B_(-36), B_(-35), B_(-34), B_(-33), B_(-32), B_(-31), B_(-30), B_(-29), B_(-28), B_(-27), B_(-26), B_(-25), B_(-24), B_(-23), B_(-22), B_(-21), B_(-20), B_(-19), B_(-18), B_(-17), B_(-16), B_(-15), B_(-14), B_(-13), B_(-12), B_(-11), B_(-10), B_(-9), B_(-8), B_(-7), B_(-6), B_(-5), B_(-4), B_(-3), B_(-2), B_(-1) }; #define UB_(a) MUS_BYTE_TO_SAMPLE(a) static const mus_float_t mus_ubyte[256] = { UB_(-128), UB_(-127), UB_(-126), UB_(-125), UB_(-124), UB_(-123), UB_(-122), UB_(-121), UB_(-120), UB_(-119), UB_(-118), UB_(-117), UB_(-116), UB_(-115), UB_(-114), UB_(-113), UB_(-112), UB_(-111), UB_(-110), UB_(-109), UB_(-108), UB_(-107), UB_(-106), UB_(-105), UB_(-104), UB_(-103), UB_(-102), UB_(-101), UB_(-100), UB_(-99), UB_(-98), UB_(-97), UB_(-96), UB_(-95), UB_(-94), UB_(-93), UB_(-92), UB_(-91), UB_(-90), UB_(-89), UB_(-88), UB_(-87), UB_(-86), UB_(-85), UB_(-84), UB_(-83), UB_(-82), UB_(-81), UB_(-80), UB_(-79), UB_(-78), UB_(-77), UB_(-76), UB_(-75), UB_(-74), UB_(-73), UB_(-72), UB_(-71), UB_(-70), UB_(-69), UB_(-68), UB_(-67), UB_(-66), UB_(-65), UB_(-64), UB_(-63), UB_(-62), UB_(-61), UB_(-60), UB_(-59), UB_(-58), UB_(-57), UB_(-56), UB_(-55), UB_(-54), UB_(-53), UB_(-52), UB_(-51), UB_(-50), UB_(-49), UB_(-48), UB_(-47), UB_(-46), UB_(-45), UB_(-44), UB_(-43), UB_(-42), UB_(-41), UB_(-40), UB_(-39), UB_(-38), UB_(-37), UB_(-36), UB_(-35), UB_(-34), UB_(-33), UB_(-32), UB_(-31), UB_(-30), UB_(-29), UB_(-28), UB_(-27), UB_(-26), UB_(-25), UB_(-24), UB_(-23), UB_(-22), UB_(-21), UB_(-20), UB_(-19), UB_(-18), UB_(-17), UB_(-16), UB_(-15), UB_(-14), UB_(-13), UB_(-12), UB_(-11), UB_(-10), UB_(-9), UB_(-8), UB_(-7), UB_(-6), UB_(-5), UB_(-4), UB_(-3), UB_(-2), UB_(-1), UB_(0), UB_(1), UB_(2), UB_(3), UB_(4), UB_(5), UB_(6), UB_(7), UB_(8), UB_(9), UB_(10), UB_(11), UB_(12), UB_(13), UB_(14), UB_(15), UB_(16), UB_(17), UB_(18), UB_(19), UB_(20), UB_(21), UB_(22), UB_(23), UB_(24), UB_(25), UB_(26), UB_(27), UB_(28), UB_(29), UB_(30), UB_(31), UB_(32), UB_(33), UB_(34), UB_(35), UB_(36), UB_(37), UB_(38), UB_(39), UB_(40), UB_(41), UB_(42), UB_(43), UB_(44), UB_(45), UB_(46), UB_(47), UB_(48), UB_(49), UB_(50), UB_(51), UB_(52), UB_(53), UB_(54), UB_(55), UB_(56), UB_(57), UB_(58), UB_(59), UB_(60), UB_(61), UB_(62), UB_(63), UB_(64), UB_(65), UB_(66), UB_(67), UB_(68), UB_(69), UB_(70), UB_(71), UB_(72), UB_(73), UB_(74), UB_(75), UB_(76), UB_(77), UB_(78), UB_(79), UB_(80), UB_(81), UB_(82), UB_(83), UB_(84), UB_(85), UB_(86), UB_(87), UB_(88), UB_(89), UB_(90), UB_(91), UB_(92), UB_(93), UB_(94), UB_(95), UB_(96), UB_(97), UB_(98), UB_(99), UB_(100), UB_(101), UB_(102), UB_(103), UB_(104), UB_(105), UB_(106), UB_(107), UB_(108), UB_(109), UB_(110), UB_(111), UB_(112), UB_(113), UB_(114), UB_(115), UB_(116), UB_(117), UB_(118), UB_(119), UB_(120), UB_(121), UB_(122), UB_(123), UB_(124), UB_(125), UB_(126), UB_(127) }; /* ---------------- read ---------------- */ #define BUFLIM (64 * 1024) #define UBYTE_ZERO 128 #define USHORT_ZERO 32768 #define MUS_SAMPLE_UNSCALED(n) ((n) / 32768.0) /* see note in _sndlib.h" values are "unscaled" from the DAC's point of view */ static mus_float_t *swapped_shorts = NULL; static void initialize_swapped_shorts(void) { int i; swapped_shorts = (mus_float_t *)malloc(65536 * sizeof(mus_float_t)); for (i = 0; i < 65536; i++) { signed short x; x = (signed short)(((i >> 8) & 0xff) | ((i & 0xff) << 8)); swapped_shorts[i] = MUS_SHORT_TO_SAMPLE(x); } } static mus_long_t mus_read_any_1(int tfd, mus_long_t beg, int chans, mus_long_t nints, mus_float_t **bufs, mus_float_t **cm, char *inbuf) { /* beg no longer means buffer-relative start point (that is assumed to be 0): changed 18-Dec-13 * beg is now the starting frample number in the file data (first frample = 0) * so old form * mus_read_any_1(f, 0, ...) * is now * mus_read_any_1(f, frample, ...) */ mus_sample_t samp_type; int siz, siz_chans; mus_long_t bytes, lim, leftover, total_read, k, loc, buflim; unsigned char *jchar; static char *ur_charbuf = NULL; char *charbuf = NULL; mus_float_t *buffer; if (nints <= 0) return(0); if (!inbuf) { io_fd *fd; if ((io_fds == NULL) || (tfd >= io_fd_size) || (tfd < 0) || (io_fds[tfd] == NULL)) return(mus_error(MUS_FILE_DESCRIPTORS_NOT_INITIALIZED, "mus_read: no file descriptors!")); fd = io_fds[tfd]; if (fd->sample_type == MUS_UNKNOWN_SAMPLE) return(mus_error(MUS_FILE_CLOSED, "mus_read: invalid sample type for %s", fd->name)); samp_type = fd->sample_type; siz = fd->bytes_per_sample; if ((samp_type == MUS_OUT_SAMPLE_TYPE) && (chans == 1)) /* (beg == 0)) */ { ssize_t total; bytes = nints * siz; total = read(tfd, (char *)(bufs[0]), bytes); if (total != bytes) { if (total <= 0) memset((void *)(bufs[0]), 0, bytes); else { int i; for (i = total / siz; i < nints; i++) bufs[0][i] = 0.0; } } return(total / siz); } if (fd->saved) { /* fprintf(stderr, "mus_read_any_1 %d use saved data\n", tfd); */ lim = nints; if (lim > fd->framples) lim = fd->framples; bytes = lim * sizeof(mus_float_t); if (beg < 0) beg = 0; if ((chans == 1) && ((!cm) || (cm[0]))) { buffer = (mus_float_t *)(bufs[0]); if (buffer) { memcpy((void *)buffer, (void *)(fd->saved_data[0] + beg), bytes); if (lim < nints) memset((void *)(buffer + lim), 0, (nints - lim) * sizeof(mus_float_t)); } } else { for (k = 0; k < chans; k++) if ((cm == NULL) || (cm[k])) { buffer = (mus_float_t *)(bufs[k]); if (buffer) { memcpy((void *)buffer, (void *)(fd->saved_data[k] + beg), bytes); if (lim < nints) memset((void *)(buffer + lim), 0, (nints - lim) * sizeof(mus_float_t)); } } } return(lim); } if (ur_charbuf == NULL) ur_charbuf = (char *)malloc(BUFLIM * sizeof(char)); charbuf = ur_charbuf; } else { charbuf = inbuf; siz = mus_bytes_per_sample((mus_sample_t)tfd); samp_type = (mus_sample_t)tfd; } siz_chans = siz * chans; leftover = (nints * siz_chans); k = (BUFLIM) % siz_chans; if (k != 0) /* for example, 3 channel output of 1-byte (mulaw) samples will need a mod 3 buffer */ buflim = (BUFLIM) - k; else buflim = BUFLIM; total_read = 0; loc = 0; #if MUS_LITTLE_ENDIAN if ((samp_type == MUS_BSHORT) && (!swapped_shorts)) initialize_swapped_shorts(); #else if ((samp_type == MUS_LSHORT) && (!swapped_shorts)) initialize_swapped_shorts(); #endif while (leftover > 0) { mus_long_t oldloc, loclim; mus_float_t *bufnow, *bufend, *bufend4; bytes = leftover; if (bytes > buflim) { leftover = (bytes - buflim); bytes = buflim; } else leftover = 0; if (!inbuf) { ssize_t total; total = read(tfd, charbuf, bytes); if (total <= 0) { /* zero out trailing section (some callers don't check the returned value) -- this added 9-May-99 */ if (loc < nints) for (k = 0; k < chans; k++) if ((cm == NULL) || (cm[k])) { mus_float_t *p; p = bufs[k]; memset((void *)(p + loc), 0, (nints - loc) * sizeof(mus_float_t)); } return(total_read); } lim = (int) (total / siz_chans); /* this divide must be exact (hence the buflim calc above) */ } else { lim = nints; /* framples in this case */ leftover = 0; } total_read += lim; oldloc = loc; if ((chans == 1) && ((!cm) || (cm[0]))) { buffer = (mus_float_t *)(bufs[0]); if (buffer) { loc = oldloc; loclim = loc + lim; bufnow = (mus_float_t *)(buffer + loc); bufend = (mus_float_t *)(buffer + loclim - 1); bufend4 = (mus_float_t *)(bufend - 4); jchar = (unsigned char *)charbuf; switch (samp_type) { case MUS_BSHORT: #if MUS_LITTLE_ENDIAN while (bufnow <= bufend4) { (*bufnow++) = swapped_shorts[(*((unsigned short *)jchar))]; jchar += 2; (*bufnow++) = swapped_shorts[(*((unsigned short *)jchar))]; jchar += 2; (*bufnow++) = swapped_shorts[(*((unsigned short *)jchar))]; jchar += 2; (*bufnow++) = swapped_shorts[(*((unsigned short *)jchar))]; jchar += 2; } for (; bufnow <= bufend; jchar += 2) /* unsigned short here as charbuf loc is slower */ (*bufnow++) = swapped_shorts[(*((unsigned short *)jchar))]; /* bswap16 is much slower here because of the subsequent short->double conversion */ #else for (; bufnow <= bufend; jchar += 2) (*bufnow++) = MUS_SHORT_TO_SAMPLE(big_endian_short(jchar)); #endif break; case MUS_LSHORT: #if (!MUS_LITTLE_ENDIAN) for (; bufnow <= bufend; jchar += 2) (*bufnow++) = swapped_shorts[(*((unsigned short *)jchar))]; #else while (bufnow <= bufend4) { (*bufnow++) = MUS_SHORT_TO_SAMPLE(little_endian_short(jchar)); jchar += 2; (*bufnow++) = MUS_SHORT_TO_SAMPLE(little_endian_short(jchar)); jchar += 2; (*bufnow++) = MUS_SHORT_TO_SAMPLE(little_endian_short(jchar)); jchar += 2; (*bufnow++) = MUS_SHORT_TO_SAMPLE(little_endian_short(jchar)); jchar += 2; } for (; bufnow <= bufend; jchar += 2) (*bufnow++) = MUS_SHORT_TO_SAMPLE(little_endian_short(jchar)); #endif break; case MUS_BINT: while (bufnow <= bufend4) { (*bufnow++) = MUS_INT_TO_SAMPLE(big_endian_int(jchar)); jchar += 4; (*bufnow++) = MUS_INT_TO_SAMPLE(big_endian_int(jchar)); jchar += 4; (*bufnow++) = MUS_INT_TO_SAMPLE(big_endian_int(jchar)); jchar += 4; (*bufnow++) = MUS_INT_TO_SAMPLE(big_endian_int(jchar)); jchar += 4; } for (; bufnow <= bufend; jchar += 4) (*bufnow++) = MUS_INT_TO_SAMPLE(big_endian_int(jchar)); break; case MUS_LINT: while (bufnow <= bufend4) { (*bufnow++) = MUS_INT_TO_SAMPLE(little_endian_int(jchar)); jchar += 4; (*bufnow++) = MUS_INT_TO_SAMPLE(little_endian_int(jchar)); jchar += 4; (*bufnow++) = MUS_INT_TO_SAMPLE(little_endian_int(jchar)); jchar += 4; (*bufnow++) = MUS_INT_TO_SAMPLE(little_endian_int(jchar)); jchar += 4; } for (; bufnow <= bufend; jchar += 4) (*bufnow++) = MUS_INT_TO_SAMPLE(little_endian_int(jchar)); break; case MUS_BINTN: for (; bufnow <= bufend; jchar += 4) (*bufnow++) = MUS_INT_TO_SAMPLE((big_endian_int(jchar) >> 8)); break; case MUS_LINTN: for (; bufnow <= bufend; jchar += 4) (*bufnow++) = MUS_INT_TO_SAMPLE((little_endian_int(jchar) >> 8)); break; case MUS_MULAW: while (bufnow <= bufend4) { (*bufnow++) = mus_mulaw[*jchar++]; (*bufnow++) = mus_mulaw[*jchar++]; (*bufnow++) = mus_mulaw[*jchar++]; (*bufnow++) = mus_mulaw[*jchar++]; } for (; bufnow <= bufend; jchar++) (*bufnow++) = mus_mulaw[*jchar]; break; case MUS_ALAW: while (bufnow <= bufend4) { (*bufnow++) = mus_alaw[*jchar++]; (*bufnow++) = mus_alaw[*jchar++]; (*bufnow++) = mus_alaw[*jchar++]; (*bufnow++) = mus_alaw[*jchar++]; } for (; bufnow <= bufend; jchar++) (*bufnow++) = mus_alaw[*jchar]; break; case MUS_BYTE: while (bufnow <= bufend4) { (*bufnow++) = mus_byte[(unsigned char)(*jchar++)]; (*bufnow++) = mus_byte[(unsigned char)(*jchar++)]; (*bufnow++) = mus_byte[(unsigned char)(*jchar++)]; (*bufnow++) = mus_byte[(unsigned char)(*jchar++)]; } for (; bufnow <= bufend; jchar++) (*bufnow++) = mus_byte[(unsigned char)(*jchar)]; break; case MUS_UBYTE: while (bufnow <= bufend4) { (*bufnow++) = mus_ubyte[(unsigned char)(*jchar++)]; (*bufnow++) = mus_ubyte[(unsigned char)(*jchar++)]; (*bufnow++) = mus_ubyte[(unsigned char)(*jchar++)]; (*bufnow++) = mus_ubyte[(unsigned char)(*jchar++)]; } for (; bufnow <= bufend; jchar++) (*bufnow++) = mus_ubyte[(unsigned char)(*jchar)]; break; case MUS_BFLOAT: while (bufnow <= bufend4) { (*bufnow++) = (mus_float_t)(big_endian_float(jchar)); jchar += 4; (*bufnow++) = (mus_float_t)(big_endian_float(jchar)); jchar += 4; (*bufnow++) = (mus_float_t)(big_endian_float(jchar)); jchar += 4; (*bufnow++) = (mus_float_t)(big_endian_float(jchar)); jchar += 4; } for (; bufnow <= bufend; jchar += 4) (*bufnow++) = (mus_float_t)(big_endian_float(jchar)); break; case MUS_BFLOAT_UNSCALED: for (; bufnow <= bufend; jchar += 4) (*bufnow++) = (mus_float_t)(MUS_SAMPLE_UNSCALED(big_endian_float(jchar))); break; case MUS_BDOUBLE: while (bufnow <= bufend4) { (*bufnow++) = (mus_float_t)(big_endian_double(jchar)); jchar += 8; (*bufnow++) = (mus_float_t)(big_endian_double(jchar)); jchar += 8; (*bufnow++) = (mus_float_t)(big_endian_double(jchar)); jchar += 8; (*bufnow++) = (mus_float_t)(big_endian_double(jchar)); jchar += 8; } for (; bufnow <= bufend; jchar += 8) (*bufnow++) = (mus_float_t)(big_endian_double(jchar)); break; case MUS_BDOUBLE_UNSCALED: for (; bufnow <= bufend; jchar += 8) (*bufnow++) = (mus_float_t)(MUS_SAMPLE_UNSCALED(big_endian_double(jchar))); break; case MUS_LFLOAT: while (bufnow <= bufend4) { (*bufnow++) = (mus_float_t)(little_endian_float(jchar)); jchar += 4; (*bufnow++) = (mus_float_t)(little_endian_float(jchar)); jchar += 4; (*bufnow++) = (mus_float_t)(little_endian_float(jchar)); jchar += 4; (*bufnow++) = (mus_float_t)(little_endian_float(jchar)); jchar += 4; } for (; bufnow <= bufend; jchar += 4) (*bufnow++) = (mus_float_t)(little_endian_float(jchar)); break; case MUS_LFLOAT_UNSCALED: for (; bufnow <= bufend; jchar += 4) (*bufnow++) = (mus_float_t)(MUS_SAMPLE_UNSCALED(little_endian_float(jchar))); break; case MUS_LDOUBLE: for (; bufnow <= bufend; jchar += 8) (*bufnow++) = (mus_float_t)(little_endian_double(jchar)); break; case MUS_LDOUBLE_UNSCALED: for (; bufnow <= bufend; jchar += 8) (*bufnow++) = (mus_float_t)(MUS_SAMPLE_UNSCALED(little_endian_double(jchar))); break; case MUS_UBSHORT: while (bufnow <= bufend4) { (*bufnow++) = MUS_SHORT_TO_SAMPLE((int)(big_endian_unsigned_short(jchar)) - USHORT_ZERO); jchar += 2; (*bufnow++) = MUS_SHORT_TO_SAMPLE((int)(big_endian_unsigned_short(jchar)) - USHORT_ZERO); jchar += 2; (*bufnow++) = MUS_SHORT_TO_SAMPLE((int)(big_endian_unsigned_short(jchar)) - USHORT_ZERO); jchar += 2; (*bufnow++) = MUS_SHORT_TO_SAMPLE((int)(big_endian_unsigned_short(jchar)) - USHORT_ZERO); jchar += 2; } for (; bufnow <= bufend; jchar += 2) (*bufnow++) = MUS_SHORT_TO_SAMPLE((int)(big_endian_unsigned_short(jchar)) - USHORT_ZERO); break; case MUS_ULSHORT: while (bufnow <= bufend4) { (*bufnow++) = MUS_SHORT_TO_SAMPLE((int)(little_endian_unsigned_short(jchar)) - USHORT_ZERO); jchar += 2; (*bufnow++) = MUS_SHORT_TO_SAMPLE((int)(little_endian_unsigned_short(jchar)) - USHORT_ZERO); jchar += 2; (*bufnow++) = MUS_SHORT_TO_SAMPLE((int)(little_endian_unsigned_short(jchar)) - USHORT_ZERO); jchar += 2; (*bufnow++) = MUS_SHORT_TO_SAMPLE((int)(little_endian_unsigned_short(jchar)) - USHORT_ZERO); jchar += 2; } for (; bufnow <= bufend; jchar += 2) (*bufnow++) = MUS_SHORT_TO_SAMPLE((int)(little_endian_unsigned_short(jchar)) - USHORT_ZERO); break; case MUS_B24INT: while (bufnow <= bufend4) { (*bufnow++) = BINT24_TO_SAMPLE(jchar); jchar += 3; (*bufnow++) = BINT24_TO_SAMPLE(jchar); jchar += 3; (*bufnow++) = BINT24_TO_SAMPLE(jchar); jchar += 3; (*bufnow++) = BINT24_TO_SAMPLE(jchar); jchar += 3; } for (; bufnow <= bufend; jchar += 3) (*bufnow++) = BINT24_TO_SAMPLE(jchar); break; case MUS_L24INT: { int val; val = (jchar[2] << 16) + (jchar[1] << 8) + jchar[0]; if (val >= (1 << 23)) val -= (1 << 24); (*bufnow++) = MUS_INT24_TO_SAMPLE(val); jchar += 2; } while (bufnow <= bufend4) { (*bufnow++) = INT24_TO_SAMPLE(jchar); jchar += 3; (*bufnow++) = INT24_TO_SAMPLE(jchar); jchar += 3; (*bufnow++) = INT24_TO_SAMPLE(jchar); jchar += 3; (*bufnow++) = INT24_TO_SAMPLE(jchar); jchar += 3; } for (; bufnow <= bufend; jchar += 3) (*bufnow++) = INT24_TO_SAMPLE(jchar); break; default: break; } loc = loclim; } } else { for (k = 0; k < chans; k++) { if ((cm == NULL) || (cm[k])) { buffer = (mus_float_t *)(bufs[k]); if (buffer) { loc = oldloc; loclim = loc + lim; bufnow = (mus_float_t *)(buffer + loc); bufend = (mus_float_t *)(buffer + loclim - 1); bufend4 = (mus_float_t *)(bufend - 4); jchar = (unsigned char *)charbuf; jchar += (k * siz); switch (samp_type) { case MUS_BSHORT: #if MUS_LITTLE_ENDIAN while (bufnow <= bufend4) { (*bufnow++) = swapped_shorts[(*((unsigned short *)jchar))]; jchar += siz_chans; (*bufnow++) = swapped_shorts[(*((unsigned short *)jchar))]; jchar += siz_chans; (*bufnow++) = swapped_shorts[(*((unsigned short *)jchar))]; jchar += siz_chans; (*bufnow++) = swapped_shorts[(*((unsigned short *)jchar))]; jchar += siz_chans; } for (; bufnow <= bufend; jchar += siz_chans) (*bufnow++) = swapped_shorts[(*((unsigned short *)jchar))]; #else for (; bufnow <= bufend; jchar += siz_chans) (*bufnow++) = MUS_SHORT_TO_SAMPLE(big_endian_short(jchar)); #endif break; case MUS_LSHORT: #if (!MUS_LITTLE_ENDIAN) for (; bufnow <= bufend; jchar += siz_chans) (*bufnow++) = swapped_shorts[(*((unsigned short *)jchar))]; #else while (bufnow <= bufend4) { (*bufnow++) = MUS_SHORT_TO_SAMPLE(little_endian_short(jchar)); jchar += siz_chans; (*bufnow++) = MUS_SHORT_TO_SAMPLE(little_endian_short(jchar)); jchar += siz_chans; (*bufnow++) = MUS_SHORT_TO_SAMPLE(little_endian_short(jchar)); jchar += siz_chans; (*bufnow++) = MUS_SHORT_TO_SAMPLE(little_endian_short(jchar)); jchar += siz_chans; } for (; bufnow <= bufend; jchar += siz_chans) (*bufnow++) = MUS_SHORT_TO_SAMPLE(little_endian_short(jchar)); #endif break; case MUS_BINT: for (; bufnow <= bufend; jchar += siz_chans) (*bufnow++) = MUS_INT_TO_SAMPLE(big_endian_int(jchar)); break; case MUS_LINT: for (; bufnow <= bufend; jchar += siz_chans) (*bufnow++) = MUS_INT_TO_SAMPLE(little_endian_int(jchar)); break; case MUS_BINTN: for (; bufnow <= bufend; jchar += siz_chans) (*bufnow++) = MUS_INT_TO_SAMPLE((big_endian_int(jchar) >> 8)); break; case MUS_LINTN: for (; bufnow <= bufend; jchar += siz_chans) (*bufnow++) = MUS_INT_TO_SAMPLE((little_endian_int(jchar) >> 8)); break; case MUS_MULAW: for (; bufnow <= bufend; jchar += siz_chans) (*bufnow++) = mus_mulaw[*jchar]; break; case MUS_ALAW: for (; bufnow <= bufend; jchar += siz_chans) (*bufnow++) = mus_alaw[*jchar]; break; case MUS_BYTE: for (; bufnow <= bufend; jchar += siz_chans) (*bufnow++) = mus_byte[(unsigned char)(*jchar)]; break; case MUS_UBYTE: for (; bufnow <= bufend; jchar += siz_chans) (*bufnow++) = mus_ubyte[(unsigned char)(*jchar)]; break; case MUS_BFLOAT: for (; bufnow <= bufend; jchar += siz_chans) (*bufnow++) = (mus_float_t)(big_endian_float(jchar)); break; case MUS_BFLOAT_UNSCALED: for (; bufnow <= bufend; jchar += siz_chans) (*bufnow++) = (mus_float_t)(MUS_SAMPLE_UNSCALED(big_endian_float(jchar))); break; case MUS_BDOUBLE: for (; bufnow <= bufend; jchar += siz_chans) (*bufnow++) = (mus_float_t)(big_endian_double(jchar)); break; case MUS_BDOUBLE_UNSCALED: for (; bufnow <= bufend; jchar += siz_chans) (*bufnow++) = (mus_float_t)(MUS_SAMPLE_UNSCALED(big_endian_double(jchar))); break; case MUS_LFLOAT: while (bufnow <= bufend4) { (*bufnow++) = (mus_float_t)(little_endian_float(jchar)); jchar += siz_chans; (*bufnow++) = (mus_float_t)(little_endian_float(jchar)); jchar += siz_chans; (*bufnow++) = (mus_float_t)(little_endian_float(jchar)); jchar += siz_chans; (*bufnow++) = (mus_float_t)(little_endian_float(jchar)); jchar += siz_chans; } for (; bufnow <= bufend; jchar += siz_chans) (*bufnow++) = (mus_float_t)(little_endian_float(jchar)); break; case MUS_LFLOAT_UNSCALED: for (; bufnow <= bufend; jchar += siz_chans) (*bufnow++) = (mus_float_t)(MUS_SAMPLE_UNSCALED(little_endian_float(jchar))); break; case MUS_LDOUBLE: while (bufnow <= bufend4) { (*bufnow++) = (mus_float_t)(little_endian_double(jchar)); jchar += siz_chans; (*bufnow++) = (mus_float_t)(little_endian_double(jchar)); jchar += siz_chans; (*bufnow++) = (mus_float_t)(little_endian_double(jchar)); jchar += siz_chans; (*bufnow++) = (mus_float_t)(little_endian_double(jchar)); jchar += siz_chans; } for (; bufnow <= bufend; jchar += siz_chans) (*bufnow++) = (mus_float_t)(little_endian_double(jchar)); break; case MUS_LDOUBLE_UNSCALED: for (; bufnow <= bufend; jchar += siz_chans) (*bufnow++) = (mus_float_t)(MUS_SAMPLE_UNSCALED(little_endian_double(jchar))); break; case MUS_UBSHORT: for (; bufnow <= bufend; jchar += siz_chans) (*bufnow++) = MUS_SHORT_TO_SAMPLE((int)(big_endian_unsigned_short(jchar)) - USHORT_ZERO); break; case MUS_ULSHORT: for (; bufnow <= bufend; jchar += siz_chans) (*bufnow++) = MUS_SHORT_TO_SAMPLE((int)(little_endian_unsigned_short(jchar)) - USHORT_ZERO); break; case MUS_B24INT: for (; bufnow <= bufend; jchar += siz_chans) (*bufnow++) = BINT24_TO_SAMPLE(jchar); break; case MUS_L24INT: { /*align for little_endian_int as above */ int val; val = (jchar[2] << 16) + (jchar[1] << 8) + jchar[0]; if (val >= (1 << 23)) val -= (1 << 24); (*bufnow++) = MUS_INT24_TO_SAMPLE(val); jchar += siz_chans - 1; } for (; bufnow <= bufend; jchar += siz_chans) (*bufnow++) = INT24_TO_SAMPLE(jchar); break; default: break; } loc = loclim; } } } } } return(total_read); } mus_long_t mus_file_read_any(int tfd, mus_long_t beg, int chans, mus_long_t nints, mus_float_t **bufs, mus_float_t **cm) { return(mus_read_any_1(tfd, beg, chans, nints, bufs, cm, NULL)); } mus_long_t mus_file_read_file(int tfd, mus_long_t beg, int chans, mus_long_t nints, mus_float_t **bufs) { /* not currently used anywhere */ return(mus_read_any_1(tfd, beg, chans, nints, bufs, NULL, NULL)); } mus_long_t mus_file_read_buffer(int charbuf_sample_type, mus_long_t beg, int chans, mus_long_t nints, mus_float_t **bufs, char *charbuf) { return(mus_read_any_1(charbuf_sample_type, beg, chans, nints, bufs, NULL, charbuf)); } /* the next two were changed 19-Dec-13 (sndlib.h version 23.1) * "end" is now actually "dur" -- the number of samples to read, not the end point in the buffer * "beg" is the frample number to start at in the data, not the buffer location * so old form * mus_file_read(f, 0, 99...) * is now * mus_file_read(f, frample, 100...) */ mus_long_t mus_file_read(int tfd, mus_long_t beg, mus_long_t num, int chans, mus_float_t **bufs) { mus_long_t rtn; rtn = mus_read_any_1(tfd, beg, chans, num, bufs, NULL, NULL); if (rtn == MUS_ERROR) return(MUS_ERROR); if (rtn < num) { mus_long_t k; /* this zeroing can be fooled if the file is chunked and has trailing, non-data chunks */ for (k = 0; k < chans; k++) { mus_float_t *buffer; buffer = bufs[k]; /* this happens routinely in mus_outa + initial write (reads ahead in effect) */ /* fprintf(stderr, "clear from %lld for %lld\n", rtn, num-rtn); */ memset((void *)(buffer + rtn), 0, (num - rtn) * sizeof(mus_float_t)); } } return(num); } mus_long_t mus_file_read_chans(int tfd, mus_long_t beg, mus_long_t num, int chans, mus_float_t **bufs, mus_float_t **cm) { /* an optimization of mus_file_read -- just reads the desired channels */ mus_long_t rtn, k; rtn = mus_read_any_1(tfd, beg, chans, num, bufs, cm, NULL); if (rtn == MUS_ERROR) return(MUS_ERROR); if (rtn < num) for (k = 0; k < chans; k++) if ((cm == NULL) || (cm[k])) { mus_float_t *buffer; buffer = bufs[k]; memset((void *)(buffer + rtn), 0, (num - rtn) * sizeof(mus_float_t)); } return(num); } /* ---------------- write ---------------- */ static int checked_write(int tfd, char *buf, mus_long_t chars) { long long int bytes; bytes = (long long int)write(tfd, buf, chars); if (bytes != chars) { io_fd *fd; if ((io_fds == NULL) || (tfd >= io_fd_size) || (tfd < 0) || (io_fds[tfd] == NULL)) return(mus_error(MUS_FILE_DESCRIPTORS_NOT_INITIALIZED, "mus_write: no file descriptors!")); fd = io_fds[tfd]; if (fd->sample_type == MUS_UNKNOWN_SAMPLE) return(mus_error(MUS_FILE_CLOSED, "attempt to write closed file %s", fd->name)); else return(mus_error(MUS_WRITE_ERROR, "mus_write: write error for %s%s%s: only %lld of %lld" " bytes written", fd->name, (errno) ? ": " : "", (errno) ? STRERROR(errno) : "", bytes, chars)); } return(MUS_NO_ERROR); } static mus_clip_handler_t *mus_clip_handler = NULL; static bool (*clip_checker)(void) = NULL; mus_clip_handler_t *mus_clip_set_handler(mus_clip_handler_t *new_clip_handler) { mus_clip_handler_t *old_handler; old_handler = mus_clip_handler; mus_clip_handler = new_clip_handler; return(old_handler); } mus_clip_handler_t *mus_clip_set_handler_and_checker(mus_clip_handler_t *new_clip_handler, bool (*checker)(void)) { mus_clip_handler_t *old_handler; old_handler = mus_clip_handler; mus_clip_handler = new_clip_handler; clip_checker = checker; return(old_handler); } static int mus_write_1(int tfd, mus_long_t beg, mus_long_t end, int chans, mus_float_t **bufs, char *inbuf, bool clipped) { int err, siz, siz_chans, val; mus_sample_t sample_type; mus_long_t bytes, k, lim, leftover, loc, buflim; bool clipping = false; unsigned char *jchar; static char *ur_charbuf = NULL; char *charbuf = NULL; mus_float_t *buffer; if (chans <= 0) return(MUS_NO_ERROR); /* ?? */ if (!inbuf) { io_fd *fd; if ((io_fds == NULL) || (tfd >= io_fd_size) || (tfd < 0) || (io_fds[tfd] == NULL)) return(mus_error(MUS_FILE_DESCRIPTORS_NOT_INITIALIZED, "mus_write: no file descriptors!")); fd = io_fds[tfd]; if (fd->sample_type == MUS_UNKNOWN_SAMPLE) return(mus_error(MUS_FILE_CLOSED, "mus_write: invalid sample type for %s", fd->name)); siz = fd->bytes_per_sample; sample_type = fd->sample_type; clipping = fd->clipping; if ((sample_type == MUS_OUT_SAMPLE_TYPE) && (chans == 1) && (!clipping) && (beg == 0)) { bytes = (end + 1) * siz; return(checked_write(tfd, (char *)(bufs[0]), bytes)); } } else { siz = mus_bytes_per_sample((mus_sample_t)tfd); sample_type = (mus_sample_t)tfd; /* in this case, tfd is the sample type (see mus_file_write_buffer below) -- this should be changed! */ clipping = clipped; } lim = (end - beg + 1); siz_chans = siz * chans; leftover = lim * siz_chans; k = (BUFLIM) % siz_chans; if (k != 0) buflim = (BUFLIM) - k; else buflim = BUFLIM; loc = beg; if (inbuf) charbuf = inbuf; while (leftover > 0) { int oldloc; bytes = leftover; if (bytes > buflim) { leftover = (bytes - buflim); bytes = buflim; } else leftover = 0; lim = (int)(bytes / siz_chans); /* see note above */ oldloc = loc; for (k = 0; k < chans; k++) { mus_long_t loclim; mus_float_t *bufnow, *bufend, *bufend4; if (bufs[k] == NULL) continue; loc = oldloc; buffer = (mus_float_t *)(bufs[k]); if (clipping) { int clipend; mus_float_t sample; clipend = oldloc + lim; bufnow = (mus_float_t *)(buffer + oldloc); bufend = (mus_float_t *)(buffer + clipend - 1); bufend4 = (mus_float_t *)(bufend - 4); if (clip_checker) clip_checker(); if (mus_clip_handler) { for (; bufnow <= bufend; bufnow++) { sample = (*bufnow); if ((sample >= 1.0) || (sample < -1.0)) (*bufnow) = (*mus_clip_handler)(sample); } } else { while (bufnow <= bufend4) { sample = (*bufnow); if (sample >= 1.0) (*bufnow) = 0.99999; else if (sample < -1.0) (*bufnow) = -1.0; bufnow++; sample = (*bufnow); if (sample >= 1.0) (*bufnow) = 0.99999; else if (sample < -1.0) (*bufnow) = -1.0; bufnow++; sample = (*bufnow); if (sample >= 1.0) (*bufnow) = 0.99999; else if (sample < -1.0) (*bufnow) = -1.0; bufnow++; sample = (*bufnow); if (sample >= 1.0) (*bufnow) = 0.99999; else if (sample < -1.0) (*bufnow) = -1.0; bufnow++; } for (; bufnow <= bufend; bufnow++) { sample = (*bufnow); if (sample >= 1.0) (*bufnow) = 0.99999; else if (sample < -1.0) (*bufnow) = -1.0; } } } if ((sample_type == MUS_OUT_SAMPLE_TYPE) && (chans == 1) && (beg == 0) && (!inbuf)) /* "tfd" can be sample type */ { bytes = (end + 1) * siz; return(checked_write(tfd, (char *)(bufs[0]), bytes)); } loclim = loc + lim; if (!charbuf) { if (ur_charbuf == NULL) ur_charbuf = (char *)malloc(BUFLIM * sizeof(char)); /* ur_charbuf = (char *)calloc(BUFLIM, sizeof(char)); else memset((void *)ur_charbuf, 0, BUFLIM); */ charbuf = ur_charbuf; } bufnow = (mus_float_t *)(buffer + loc); bufend = (mus_float_t *)(buffer + loclim - 1); bufend4 = (mus_float_t *)(bufend - 4); jchar = (unsigned char *)charbuf; /* if to_buffer we should add the loop offset here, or never loop */ jchar += (k * siz); switch (sample_type) { case MUS_BSHORT: while (bufnow <= bufend4) { set_big_endian_short(jchar, MUS_SAMPLE_TO_SHORT(*bufnow++)); jchar += siz_chans; set_big_endian_short(jchar, MUS_SAMPLE_TO_SHORT(*bufnow++)); jchar += siz_chans; set_big_endian_short(jchar, MUS_SAMPLE_TO_SHORT(*bufnow++)); jchar += siz_chans; set_big_endian_short(jchar, MUS_SAMPLE_TO_SHORT(*bufnow++)); jchar += siz_chans; } for (; bufnow <= bufend; jchar += siz_chans) set_big_endian_short(jchar, MUS_SAMPLE_TO_SHORT(*bufnow++)); break; case MUS_LSHORT: for (; bufnow <= bufend; jchar += siz_chans) set_little_endian_short(jchar, MUS_SAMPLE_TO_SHORT(*bufnow++)); break; case MUS_BINT: for (; bufnow <= bufend; jchar += siz_chans) set_big_endian_int(jchar, MUS_SAMPLE_TO_INT(*bufnow++)); break; case MUS_LINT: for (; bufnow <= bufend; jchar += siz_chans) set_little_endian_int(jchar, MUS_SAMPLE_TO_INT(*bufnow++)); break; case MUS_BINTN: for (; bufnow <= bufend; jchar += siz_chans) set_big_endian_int(jchar, MUS_SAMPLE_TO_INT(*bufnow++) << 8); break; case MUS_LINTN: for (; bufnow <= bufend; jchar += siz_chans) set_little_endian_int(jchar, MUS_SAMPLE_TO_INT(*bufnow++) << 8); break; case MUS_MULAW: for (; bufnow <= bufend; jchar += siz_chans) (*jchar) = to_mulaw(MUS_SAMPLE_TO_SHORT(*bufnow++)); break; case MUS_ALAW: for (; bufnow <= bufend; jchar += siz_chans) (*jchar) = to_alaw(MUS_SAMPLE_TO_SHORT(*bufnow++)); break; case MUS_BYTE: for (; bufnow <= bufend; jchar += siz_chans) (*((signed char *)jchar)) = MUS_SAMPLE_TO_BYTE(*bufnow++); break; case MUS_UBYTE: for (; bufnow <= bufend; jchar += siz_chans) (*jchar) = MUS_SAMPLE_TO_BYTE(*bufnow++) + UBYTE_ZERO; break; case MUS_BFLOAT: for (; bufnow <= bufend; jchar += siz_chans) set_big_endian_float(jchar, *bufnow++); break; case MUS_LFLOAT: while (bufnow <= bufend4) { set_little_endian_float(jchar, *bufnow++); jchar += siz_chans; set_little_endian_float(jchar, *bufnow++); jchar += siz_chans; set_little_endian_float(jchar, *bufnow++); jchar += siz_chans; set_little_endian_float(jchar, *bufnow++); jchar += siz_chans; } for (; bufnow <= bufend; jchar += siz_chans) set_little_endian_float(jchar, *bufnow++); break; case MUS_BDOUBLE: for (; bufnow <= bufend; jchar += siz_chans) set_big_endian_double(jchar, *bufnow++); break; case MUS_LDOUBLE: while (bufnow <= bufend4) { set_little_endian_double(jchar, *bufnow++); jchar += siz_chans; set_little_endian_double(jchar, *bufnow++); jchar += siz_chans; set_little_endian_double(jchar, *bufnow++); jchar += siz_chans; set_little_endian_double(jchar, *bufnow++); jchar += siz_chans; } for (; bufnow <= bufend; jchar += siz_chans) set_little_endian_double(jchar, *bufnow++); break; case MUS_BFLOAT_UNSCALED: for (; bufnow <= bufend; jchar += siz_chans) set_big_endian_float(jchar, 32768.0 * (*bufnow++)); break; case MUS_LFLOAT_UNSCALED: for (; bufnow <= bufend; jchar += siz_chans) set_little_endian_float(jchar, 32768.0 * (*bufnow++)); break; case MUS_BDOUBLE_UNSCALED: for (; bufnow <= bufend; jchar += siz_chans) set_big_endian_double(jchar, 32768.0 * (*bufnow++)); break; case MUS_LDOUBLE_UNSCALED: for (; bufnow <= bufend; jchar += siz_chans) set_little_endian_double(jchar, 32768.0 * (*bufnow++)); break; case MUS_UBSHORT: for (; bufnow <= bufend; jchar += siz_chans) set_big_endian_unsigned_short(jchar, (unsigned short)(MUS_SAMPLE_TO_SHORT(*bufnow++) + USHORT_ZERO)); break; case MUS_ULSHORT: for (; bufnow <= bufend; jchar += siz_chans) set_little_endian_unsigned_short(jchar, (unsigned short)(MUS_SAMPLE_TO_SHORT(*bufnow++) + USHORT_ZERO)); break; case MUS_B24INT: { int c3; mus_long_t bk; bk = (k * 3); c3 = chans * 3; for (; bufnow <= bufend; bk += c3) { val = MUS_SAMPLE_TO_INT24(*bufnow++); charbuf[bk] = (val >> 16); charbuf[bk + 1] = (val >> 8); charbuf[bk + 2] = (val & 0xFF); } } break; case MUS_L24INT: { int c3; mus_long_t bk; bk = (k * 3); c3 = chans * 3; for (; bufnow <= bufend; bk += c3) { val = MUS_SAMPLE_TO_INT24(*bufnow++); charbuf[bk + 2] = (val >> 16); charbuf[bk + 1] = (val >> 8); charbuf[bk] = (val & 0xFF); } } break; default: break; } loc = loclim; } if (!inbuf) { err = checked_write(tfd, charbuf, bytes); if (err == MUS_ERROR) return(MUS_ERROR); } } return(MUS_NO_ERROR); } int mus_file_write(int tfd, mus_long_t beg, mus_long_t end, int chans, mus_float_t **bufs) { return(mus_write_1(tfd, beg, end, chans, bufs, NULL, false)); /* if inbuf is NULL (as here), clipped is ignored, so the "false" could be anything */ } int mus_file_write_file(int tfd, mus_long_t beg, mus_long_t end, int chans, mus_float_t **bufs) { return(mus_write_1(tfd, beg, end, chans, bufs, NULL, false)); } int mus_file_write_buffer(int charbuf_sample_type, mus_long_t beg, mus_long_t end, int chans, mus_float_t **bufs, char *charbuf, bool clipped) { return(mus_write_1(charbuf_sample_type, beg, end, chans, bufs, charbuf, clipped)); } /* for CLM */ void mus_reset_io_c(void) { io_fd_size = 0; io_fds = NULL; clipping_default = false; mus_clip_set_handler(NULL); } #if !(defined(_MSC_VER) && (!(defined(__CYGWIN__)))) static int sndlib_strlen(const char *str) { /* strlen(NULL) -> seg fault! */ if ((str) && (*str)) return(strlen(str)); return(0); } #endif static char *saved_cwd = NULL; char *mus_getcwd(void) { int i, path_max = 0; char *pwd = NULL; if (saved_cwd) return(saved_cwd); #ifndef _MSC_VER path_max = pathconf("/", _PC_PATH_MAX); #endif if (path_max < 1024) { #if defined(PATH_MAX) path_max = PATH_MAX; #endif if (path_max < 1024) path_max = 1024; } for (i = path_max;; i *= 2) { char *res; if (pwd) free(pwd); pwd = (char *)calloc(i, sizeof(char)); #if (defined(_MSC_VER) || __CYGWIN__) res = _getcwd(pwd, i); #else res = getcwd(pwd, i); #endif if (res) break; /* NULL is returned if failure, but what about success? should I check errno=ERANGE? */ } saved_cwd = pwd; return(pwd); } #if HAVE_EXTENSION_LANGUAGE #include "sndlib2xen.h" /* for g_mus_sound_path */ #endif char *mus_expand_filename(const char *filename) { /* fill out under-specified library pathnames etc */ #if defined(_MSC_VER) && (!(defined(__CYGWIN__))) return(mus_strdup(filename)); #else char *file_name_buf; char *tok, *orig; int i, j, len, orig_len; /* realpath does not speed this up */ if ((filename) && (*filename)) len = strlen(filename); else return(NULL); if ((len == 1) && (filename[0] == '.')) { orig = mus_getcwd(); orig_len = sndlib_strlen(orig); file_name_buf = (char *)malloc((orig_len + 4) * sizeof(char)); strcpy(file_name_buf, orig); file_name_buf[orig_len] = '/'; file_name_buf[orig_len + 1] = '\0'; /* fprintf(stderr, "%d: %s -> %s\n", __LINE__, filename, file_name_buf); */ return(file_name_buf); } tok = (char *)strchr(filename, (int)'/'); if (!tok) { orig = mus_getcwd(); orig_len = sndlib_strlen(orig); file_name_buf = (char *)malloc((len + orig_len + 4) * sizeof(char)); strcpy(file_name_buf, orig); file_name_buf[orig_len] = '/'; strncpy((char *)(file_name_buf + orig_len + 1), filename, len + 1); /* fprintf(stderr, "%d: %s -> %s\n", __LINE__, filename, file_name_buf); */ #if HAVE_EXTENSION_LANGUAGE if (!mus_file_probe(file_name_buf)) { Xen p; for (p = g_mus_sound_path(); Xen_is_pair(p); p = Xen_cdr(p)) { char *nfile; const char *path; int path_len; path = Xen_string_to_C_string(Xen_car(p)); path_len = sndlib_strlen(path); nfile = (char *)malloc((len + path_len + 4) * sizeof(char)); strcpy(nfile, path); if (nfile[path_len - 1] != '/') { nfile[path_len] = '/'; strncpy((char *)(nfile + path_len + 1), filename, len + 1); } else strncpy((char *)(nfile + path_len), filename, len + 1); /* fprintf(stderr, "%d: %s -> %s\n", __LINE__, filename, nfile); */ if (mus_file_probe(nfile)) { free(file_name_buf); return(nfile); } free(nfile); } } #endif return(file_name_buf); } orig = mus_strdup(filename); tok = orig; /* get rid of "//" */ for (i = 0, j = 0; i < len - 1; i++) { if ((tok[i] == '/') && (tok[i + 1] == '/')) j = i + 1; } if (j > 0) { for (i = 0; j < len; i++, j++) tok[i] = tok[j]; tok[i] ='\0'; } /* get rid of "~/" at start */ if (tok[0] != '/') { char *home = NULL; if ((tok[0] == '~') && (home = getenv("HOME"))) { file_name_buf = (char *)malloc((len + sndlib_strlen(home) + 8) * sizeof(char)); strcpy(file_name_buf, home); strcat(file_name_buf, ++tok); } else { char *pwd; pwd = mus_getcwd(); file_name_buf = (char *)malloc((len + sndlib_strlen(pwd) + 8) * sizeof(char)); strcpy(file_name_buf, pwd); strcat(file_name_buf, "/"); if (tok[0]) strcat(file_name_buf, tok); } } else { file_name_buf = (char *)malloc((len + 8) * sizeof(char)); strcpy(file_name_buf, tok); } /* get rid of "/../" and "/./" also "/." at end */ { int slash_at = -1; bool found_one = true; while (found_one) { found_one = false; len = strlen(file_name_buf); for (i = 0; i < len - 3; i++) if (file_name_buf[i] == '/') { if ((file_name_buf[i + 1] == '.') && (file_name_buf[i + 2] == '.') && (file_name_buf[i + 3] == '/')) { i += 4; for (j = slash_at + 1; i < len; i++, j++) file_name_buf[j] = file_name_buf[i]; file_name_buf[j] = '\0'; found_one = true; break; } else { if ((file_name_buf[i + 1] == '.') && (file_name_buf[i + 2] == '/')) { for (j = i + 3, i = i + 1; j < len; i++, j++) file_name_buf[i] = file_name_buf[j]; file_name_buf[i] = '\0'; found_one = true; } else slash_at = i; } } } len = strlen(file_name_buf); if ((len > 1) && (file_name_buf[len - 1] == '.') && (file_name_buf[len - 2] == '/')) file_name_buf[len - 1] = '\0'; } free(orig); return(file_name_buf); #endif } char *mus_format(const char *format, ...) { /* caller should free result */ #ifndef _MSC_VER va_list ap; int bytes; char *result = NULL; va_start(ap, format); bytes = vasprintf(&result, format, ap); va_end(ap); if (bytes == -1) return(NULL); return(result); #else #define MUS_FORMAT_BUFFER_SIZE 256 char *buf = NULL; int needed_bytes = 0; va_list ap; buf = (char *)calloc(MUS_FORMAT_BUFFER_SIZE, sizeof(char)); va_start(ap, format); needed_bytes = vsnprintf(buf, MUS_FORMAT_BUFFER_SIZE, format, ap); va_end(ap); if (needed_bytes >= MUS_FORMAT_BUFFER_SIZE) /* "=" here because we need room for the trailing 0 */ { free(buf); buf = (char *)calloc(needed_bytes + 1, sizeof(char)); va_start(ap, format); vsnprintf(buf, needed_bytes + 1, format, ap); va_end(ap); } return(buf); #endif } mus_float_t mus_fclamp(mus_float_t lo, mus_float_t val, mus_float_t hi) { if (val > hi) return(hi); else if (val < lo) return(lo); else return(val); } int mus_iclamp(int lo, int val, int hi) { if (val > hi) return(hi); else if (val < lo) return(lo); else return(val); } mus_long_t mus_oclamp(mus_long_t lo, mus_long_t val, mus_long_t hi) { if (val > hi) return(hi); else if (val < lo) return(lo); else return(val); } /* raw sample data peak value (without per-sample conversion) */ /* ---------------- short ---------------- */ #define SHORT_BYTES 2 static void min_max_shorts(unsigned char *data, int bytes, int chan, int chans, mus_float_t *min_samp, mus_float_t *max_samp) { short cur_min, cur_max, tmp; short *sbuf; int i, len, len2; sbuf = (short *)data; len = bytes / SHORT_BYTES; cur_min = sbuf[chan]; cur_max = cur_min; len2 = len - 2 * chans; i = chan; /* we read the first sample above, but we're reading by twos below */ while (i <= len2) { tmp = sbuf[i]; if (tmp < cur_min) cur_min = tmp; else if (tmp > cur_max) cur_max = tmp; i += chans; tmp = sbuf[i]; if (tmp < cur_min) cur_min = tmp; else if (tmp > cur_max) cur_max = tmp; i += chans; } if (i < len) { tmp = sbuf[i]; if (tmp < cur_min) cur_min = tmp; else if (tmp > cur_max) cur_max = tmp; } (*min_samp) = (mus_float_t)cur_min / (mus_float_t)(1 << 15); (*max_samp) = (mus_float_t)cur_max / (mus_float_t)(1 << 15); } static void min_max_switch_shorts(unsigned char *data, int bytes, int chan, int chans, mus_float_t *min_samp, mus_float_t *max_samp) { short cur_min, cur_max; /* frample based */ unsigned char *samp, *eod, *eod2; int bytes_per_frample; bytes_per_frample = chans * SHORT_BYTES; eod = (unsigned char *)(data + bytes); eod2 = (unsigned char *)(eod - 2 * bytes_per_frample); #if MUS_LITTLE_ENDIAN cur_min = big_endian_short((unsigned char *)(data + (chan * SHORT_BYTES))); #else cur_min = little_endian_short((unsigned char *)(data + (chan * SHORT_BYTES))); #endif cur_max = cur_min; samp = (unsigned char *)(data + (chan * SHORT_BYTES)); while (samp <= eod2) { short val; #if MUS_LITTLE_ENDIAN val = big_endian_short(samp); if (val < cur_min) cur_min = val; else if (val > cur_max) cur_max = val; samp += bytes_per_frample; val = big_endian_short(samp); if (val < cur_min) cur_min = val; else if (val > cur_max) cur_max = val; samp += bytes_per_frample; #else val = little_endian_short(samp); if (val < cur_min) cur_min = val; else if (val > cur_max) cur_max = val; samp += bytes_per_frample; val = little_endian_short(samp); if (val < cur_min) cur_min = val; else if (val > cur_max) cur_max = val; samp += bytes_per_frample; #endif } if (samp < eod) { short val; #if MUS_LITTLE_ENDIAN val = big_endian_short(samp); if (val < cur_min) cur_min = val; else if (val > cur_max) cur_max = val; #else val = little_endian_short(samp); if (val < cur_min) cur_min = val; else if (val > cur_max) cur_max = val; #endif } (*min_samp) = (mus_float_t)cur_min / (mus_float_t)(1 << 15); (*max_samp) = (mus_float_t)cur_max / (mus_float_t)(1 << 15); } /* ---------------- unsigned short ---------------- */ static void min_max_ushorts(unsigned char *data, int bytes, int chan, int chans, mus_float_t *min_samp, mus_float_t *max_samp) { unsigned short cur_min, cur_max; unsigned short *sbuf; int i, len, len2; sbuf = (unsigned short *)data; len = bytes / SHORT_BYTES; len2 = len - 2 * chans; cur_min = sbuf[chan]; cur_max = cur_min; i = chan; while (i <= len2) { if (sbuf[i] < cur_min) cur_min = sbuf[i]; else if (sbuf[i] > cur_max) cur_max = sbuf[i]; i += chans; if (sbuf[i] < cur_min) cur_min = sbuf[i]; else if (sbuf[i] > cur_max) cur_max = sbuf[i]; i += chans; } if (i < len) { if (sbuf[i] < cur_min) cur_min = sbuf[i]; else if (sbuf[i] > cur_max) cur_max = sbuf[i]; } (*min_samp) = (mus_float_t)(cur_min - USHORT_ZERO) / (mus_float_t)(1 << 15); (*max_samp) = (mus_float_t)(cur_max - USHORT_ZERO) / (mus_float_t)(1 << 15); } static void min_max_switch_ushorts(unsigned char *data, int bytes, int chan, int chans, mus_float_t *min_samp, mus_float_t *max_samp) { unsigned short cur_min, cur_max; /* frample based */ unsigned char *samp, *eod, *eod2; int bytes_per_frample; bytes_per_frample = chans * SHORT_BYTES; eod = (unsigned char *)(data + bytes); eod2 = (unsigned char *)(eod - 2 * bytes_per_frample); #if MUS_LITTLE_ENDIAN cur_min = big_endian_unsigned_short((unsigned char *)(data + (chan * SHORT_BYTES))); #else cur_min = little_endian_unsigned_short((unsigned char *)(data + (chan * SHORT_BYTES))); #endif cur_max = cur_min; samp = (unsigned char *)(data + (chan * SHORT_BYTES)); while (samp <= eod2) { unsigned short val; #if MUS_LITTLE_ENDIAN val = big_endian_unsigned_short(samp); if (val < cur_min) cur_min = val; else if (val > cur_max) cur_max = val; samp += bytes_per_frample; val = big_endian_unsigned_short(samp); if (val < cur_min) cur_min = val; else if (val > cur_max) cur_max = val; samp += bytes_per_frample; #else val = little_endian_unsigned_short(samp); if (val < cur_min) cur_min = val; else if (val > cur_max) cur_max = val; samp += bytes_per_frample; val = little_endian_unsigned_short(samp); if (val < cur_min) cur_min = val; else if (val > cur_max) cur_max = val; samp += bytes_per_frample; #endif } if (samp < eod) { unsigned short val; #if MUS_LITTLE_ENDIAN val = big_endian_unsigned_short(samp); #else val = little_endian_unsigned_short(samp); #endif if (val < cur_min) cur_min = val; else if (val > cur_max) cur_max = val; } (*min_samp) = (mus_float_t)(cur_min - USHORT_ZERO) / (mus_float_t)(1 << 15); (*max_samp) = (mus_float_t)(cur_max - USHORT_ZERO) / (mus_float_t)(1 << 15); } /* ---------------- int ---------------- */ #define INT_BYTES 4 static void min_max_ints(unsigned char *data, int bytes, int chan, int chans, mus_float_t *min_samp, mus_float_t *max_samp, bool standard) { int cur_min, cur_max; int *sbuf; int i, len, len2; sbuf = (int *)data; len = bytes / INT_BYTES; len2 = len - 2 *chans; cur_min = sbuf[chan]; cur_max = cur_min; i = chan; while (i <= len2) { if (sbuf[i] < cur_min) cur_min = sbuf[i]; else if (sbuf[i] > cur_max) cur_max = sbuf[i]; i += chans; if (sbuf[i] < cur_min) cur_min = sbuf[i]; else if (sbuf[i] > cur_max) cur_max = sbuf[i]; i += chans; } if (i < len) { if (sbuf[i] < cur_min) cur_min = sbuf[i]; else if (sbuf[i] > cur_max) cur_max = sbuf[i]; } (*min_samp) = (mus_float_t)cur_min / (mus_float_t)(1 << 23); (*max_samp) = (mus_float_t)cur_max / (mus_float_t)(1 << 23); if (!standard) { (*min_samp) = (mus_float_t)(*min_samp) / (mus_float_t)(1 << 8); (*max_samp) = (mus_float_t)(*max_samp) / (mus_float_t)(1 << 8); } } /* (with-sound (:sample-type mus-lintn :statistics #t) (fm-violin 0 1 440 .1)) */ static void min_max_switch_ints(unsigned char *data, int bytes, int chan, int chans, mus_float_t *min_samp, mus_float_t *max_samp, bool standard) { int cur_min, cur_max; /* frample based */ unsigned char *samp, *eod, *eod2; int bytes_per_frample; bytes_per_frample = chans * INT_BYTES; eod = (unsigned char *)(data + bytes); eod2 = (unsigned char *)(eod - 2 * bytes_per_frample); #if MUS_LITTLE_ENDIAN cur_min = big_endian_int((unsigned char *)(data + (chan * INT_BYTES))); #else cur_min = little_endian_int((unsigned char *)(data + (chan * INT_BYTES))); #endif cur_max = cur_min; samp = (unsigned char *)(data + (chan * INT_BYTES)); while (samp <= eod2) { int val; #if MUS_LITTLE_ENDIAN val = big_endian_int(samp); if (val < cur_min) cur_min = val; else if (val > cur_max) cur_max = val; samp += bytes_per_frample; val = big_endian_int(samp); if (val < cur_min) cur_min = val; else if (val > cur_max) cur_max = val; samp += bytes_per_frample; #else val = little_endian_int(samp); if (val < cur_min) cur_min = val; else if (val > cur_max) cur_max = val; samp += bytes_per_frample; val = little_endian_int(samp); if (val < cur_min) cur_min = val; else if (val > cur_max) cur_max = val; samp += bytes_per_frample; #endif } if (samp < eod) { int val; #if MUS_LITTLE_ENDIAN val = big_endian_int(samp); if (val < cur_min) cur_min = val; else if (val > cur_max) cur_max = val; #else val = little_endian_int(samp); if (val < cur_min) cur_min = val; else if (val > cur_max) cur_max = val; #endif } (*min_samp) = (mus_float_t)cur_min / (mus_float_t)(1 << 23); (*max_samp) = (mus_float_t)cur_max / (mus_float_t)(1 << 23); if (!standard) { (*min_samp) = (mus_float_t)(*min_samp) / (mus_float_t)(1 << 8); (*max_samp) = (mus_float_t)(*max_samp) / (mus_float_t)(1 << 8); } } /* ---------------- float ---------------- */ #define FLOAT_BYTES 4 static void min_max_floats(unsigned char *data, int bytes, int chan, int chans, mus_float_t *min_samp, mus_float_t *max_samp, bool unscaled) { float cur_min, cur_max; float *sbuf; int i, len, len2; sbuf = (float *)data; len = bytes / FLOAT_BYTES; len2 = len - 2 *chans; cur_min = sbuf[chan]; cur_max = cur_min; i = chan; while (i < len2) { if (sbuf[i] < cur_min) cur_min = sbuf[i]; else if (sbuf[i] > cur_max) cur_max = sbuf[i]; i += chans; if (sbuf[i] < cur_min) cur_min = sbuf[i]; else if (sbuf[i] > cur_max) cur_max = sbuf[i]; i += chans; } while (i < len) { if (sbuf[i] < cur_min) cur_min = sbuf[i]; else if (sbuf[i] > cur_max) cur_max = sbuf[i]; i += chans; } if (unscaled) { (*min_samp) = cur_min / 32768.0; (*max_samp) = cur_max / 32768.0; } else { (*min_samp) = cur_min; (*max_samp) = cur_max; } } static void min_max_switch_floats(unsigned char *data, int bytes, int chan, int chans, mus_float_t *min_samp, mus_float_t *max_samp, bool unscaled) { float cur_min, cur_max; /* frample based */ unsigned char *samp, *eod, *eod2; int bytes_per_frample; bytes_per_frample = chans * FLOAT_BYTES; eod = (unsigned char *)(data + bytes); eod2 = (unsigned char *)(eod - 2 * bytes_per_frample); #if MUS_LITTLE_ENDIAN cur_min = big_endian_float((unsigned char *)(data + (chan * FLOAT_BYTES))); #else cur_min = little_endian_float((unsigned char *)(data + (chan * FLOAT_BYTES))); #endif cur_max = cur_min; samp = (unsigned char *)(data + (chan * FLOAT_BYTES)); while (samp <= eod2) { float val; #if MUS_LITTLE_ENDIAN val = big_endian_float(samp); if (val < cur_min) cur_min = val; else if (val > cur_max) cur_max = val; samp += bytes_per_frample; val = big_endian_float(samp); if (val < cur_min) cur_min = val; else if (val > cur_max) cur_max = val; samp += bytes_per_frample; #else val = little_endian_float(samp); if (val < cur_min) cur_min = val; else if (val > cur_max) cur_max = val; samp += bytes_per_frample; val = little_endian_float(samp); if (val < cur_min) cur_min = val; else if (val > cur_max) cur_max = val; samp += bytes_per_frample; #endif } if (samp < eod) { float val; #if MUS_LITTLE_ENDIAN val = big_endian_float(samp); if (val < cur_min) cur_min = val; else if (val > cur_max) cur_max = val; #else val = little_endian_float(samp); if (val < cur_min) cur_min = val; else if (val > cur_max) cur_max = val; #endif } if (unscaled) { (*min_samp) = cur_min / 32768.0; (*max_samp) = cur_max / 32768.0; } else { (*min_samp) = cur_min; (*max_samp) = cur_max; } } /* ---------------- double ---------------- */ #define DOUBLE_BYTES 8 static void min_max_doubles(unsigned char *data, int bytes, int chan, int chans, mus_float_t *min_samp, mus_float_t *max_samp, bool unscaled) { double cur_min, cur_max; double *sbuf; int i, len, len2; sbuf = (double *)data; len = bytes / DOUBLE_BYTES; len2 = len - 2 * chans; cur_min = sbuf[chan]; cur_max = cur_min; i = chan; while (i <= len2) { if (sbuf[i] < cur_min) cur_min = sbuf[i]; else if (sbuf[i] > cur_max) cur_max = sbuf[i]; i += chans; if (sbuf[i] < cur_min) cur_min = sbuf[i]; else if (sbuf[i] > cur_max) cur_max = sbuf[i]; i += chans; } if (i < len) { if (sbuf[i] < cur_min) cur_min = sbuf[i]; else if (sbuf[i] > cur_max) cur_max = sbuf[i]; } if (unscaled) { (*min_samp) = cur_min / 32768.0; (*max_samp) = cur_max / 32768.0; } else { (*min_samp) = cur_min; (*max_samp) = cur_max; } } static void min_max_switch_doubles(unsigned char *data, int bytes, int chan, int chans, mus_float_t *min_samp, mus_float_t *max_samp, bool unscaled) { double cur_min, cur_max; /* frample based */ unsigned char *samp, *eod, *eod2; int bytes_per_frample; bytes_per_frample = chans * DOUBLE_BYTES; eod = (unsigned char *)(data + bytes); eod2 = (unsigned char *)(eod - 2 * bytes_per_frample); #if MUS_LITTLE_ENDIAN cur_min = big_endian_double((unsigned char *)(data + (chan * DOUBLE_BYTES))); #else cur_min = little_endian_double((unsigned char *)(data + (chan * DOUBLE_BYTES))); #endif cur_max = cur_min; samp = (unsigned char *)(data + (chan * DOUBLE_BYTES)); while (samp <= eod2) { double val; #if MUS_LITTLE_ENDIAN val = big_endian_double(samp); if (val < cur_min) cur_min = val; else if (val > cur_max) cur_max = val; samp += bytes_per_frample; val = big_endian_double(samp); if (val < cur_min) cur_min = val; else if (val > cur_max) cur_max = val; samp += bytes_per_frample; #else val = little_endian_double(samp); if (val < cur_min) cur_min = val; else if (val > cur_max) cur_max = val; samp += bytes_per_frample; val = little_endian_double(samp); if (val < cur_min) cur_min = val; else if (val > cur_max) cur_max = val; samp += bytes_per_frample; #endif } if (samp < eod) { double val; #if MUS_LITTLE_ENDIAN val = big_endian_double(samp); if (val < cur_min) cur_min = val; else if (val > cur_max) cur_max = val; #else val = little_endian_double(samp); if (val < cur_min) cur_min = val; else if (val > cur_max) cur_max = val; #endif } if (unscaled) { (*min_samp) = cur_min / 32768.0; (*max_samp) = cur_max / 32768.0; } else { (*min_samp) = cur_min; (*max_samp) = cur_max; } } /* ---------------- 3-byte samples ---------------- */ #define THREE_BYTES 3 static int big_three(unsigned char *data, int loc) { int val; val = (data[loc + 0] << 16) + (data[loc + 1] << 8) + data[loc + 2]; if (val >= (1 << 23)) val -= (1 << 24); return(val); } static int little_three(unsigned char *data, int loc) { int val; val = (data[loc + 2] << 16) + (data[loc + 1] << 8) + data[loc + 0]; if (val >= (1 << 23)) val -= (1 << 24); return(val); } static void min_max_24s(unsigned char *data, int bytes, int chan, int chans, mus_float_t *min_samp, mus_float_t *max_samp, bool big_endian) { int cur_min, cur_max; int i, k, bytes_per_frample, len, len2, offset; bytes_per_frample = chans * THREE_BYTES; len = bytes / bytes_per_frample; len2 = len - 2 * bytes_per_frample; offset = chan * THREE_BYTES; k = offset; if (big_endian) { cur_min = big_three(data, k); cur_max = cur_min; i = 0; /* k += bytes_per_frample; */ while (i <= len2) { int val; val = big_three(data, k); if (val < cur_min) cur_min = val; else if (val > cur_max) cur_max = val; i++; k += bytes_per_frample; val = big_three(data, k); if (val < cur_min) cur_min = val; else if (val > cur_max) cur_max = val; i++; k += bytes_per_frample; } while (i < len) { int val; val = big_three(data, k); if (val < cur_min) cur_min = val; else if (val > cur_max) cur_max = val; i++; k += bytes_per_frample; } } else { cur_min = little_three(data, k); cur_max = cur_min; i = 0; /* k += bytes_per_frample; */ while (i <= len2) { int val; val = little_three(data, k); if (val < cur_min) cur_min = val; else if (val > cur_max) cur_max = val; i++; k += bytes_per_frample; val = little_three(data, k); if (val < cur_min) cur_min = val; else if (val > cur_max) cur_max = val; i++; k += bytes_per_frample; } while (i < len) { int val; val = little_three(data, k); if (val < cur_min) cur_min = val; else if (val > cur_max) cur_max = val; i++; k += bytes_per_frample; } } (*min_samp) = (mus_float_t)cur_min / (mus_float_t)(1 << 23); (*max_samp) = (mus_float_t)cur_max / (mus_float_t)(1 << 23); } /* ---------------- mulaw, alaw, byte ---------------- */ static void min_max_mulaw(unsigned char *data, int bytes, int chan, int chans, mus_float_t *min_samp, mus_float_t *max_samp) { mus_float_t cur_min, cur_max; int i, b2; cur_min = mus_mulaw[(int)data[chan]]; cur_max = cur_min; i = chan; b2 = bytes - 2 * chans; while (i <= b2) { mus_float_t val; val = mus_mulaw[(int)data[i]]; if (val < cur_min) cur_min = val; else if (val > cur_max) cur_max = val; i += chans; val = mus_mulaw[(int)data[i]]; if (val < cur_min) cur_min = val; else if (val > cur_max) cur_max = val; i += chans; } if (i < bytes) { mus_float_t val; val = mus_mulaw[(int)data[i]]; if (val < cur_min) cur_min = val; else if (val > cur_max) cur_max = val; } (*min_samp) = cur_min; (*max_samp) = cur_max; } static void min_max_alaw(unsigned char *data, int bytes, int chan, int chans, mus_float_t *min_samp, mus_float_t *max_samp) { mus_float_t cur_min, cur_max; int i, b2; cur_min = mus_alaw[(int)data[chan]]; cur_max = cur_min; i = chan; b2 = bytes - 2 * chans; while (i <= b2) { mus_float_t val; val = mus_alaw[(int)data[i]]; if (val < cur_min) cur_min = val; else if (val > cur_max) cur_max = val; i += chans; val = mus_alaw[(int)data[i]]; if (val < cur_min) cur_min = val; else if (val > cur_max) cur_max = val; i += chans; } if (i < bytes) { mus_float_t val; val = mus_alaw[(int)data[i]]; if (val < cur_min) cur_min = val; else if (val > cur_max) cur_max = val; } (*min_samp) = cur_min; (*max_samp) = cur_max; } static void min_max_bytes(unsigned char *data, int bytes, int chan, int chans, mus_float_t *min_samp, mus_float_t *max_samp) { signed char cur_min, cur_max; int i, b2; cur_min = (signed char)(data[chan]); cur_max = cur_min; i = chan; b2 = bytes - 2 * chans; while (i <= b2) { signed char val; val = (signed char)(data[i]); if (val < cur_min) cur_min = val; else if (val > cur_max) cur_max = val; i += chans; val = (signed char)(data[i]); if (val < cur_min) cur_min = val; else if (val > cur_max) cur_max = val; i += chans; } if (i < bytes) { signed char val; val = (signed char)(data[i]); if (val < cur_min) cur_min = val; else if (val > cur_max) cur_max = val; } (*min_samp) = (mus_float_t)cur_min / (mus_float_t)(1 << 7); (*max_samp) = (mus_float_t)cur_max / (mus_float_t)(1 << 7); } static void min_max_ubytes(unsigned char *data, int bytes, int chan, int chans, mus_float_t *min_samp, mus_float_t *max_samp) { unsigned char cur_min, cur_max; int i, b2; cur_min = data[chan]; cur_max = cur_min; i = chan; b2 = bytes - 2 * chans; while (i <= b2) { if (data[i] < cur_min) cur_min = data[i]; else if (data[i] > cur_max) cur_max = data[i]; i += chans; if (data[i] < cur_min) cur_min = data[i]; else if (data[i] > cur_max) cur_max = data[i]; i += chans; } if (i < bytes) { if (data[i] < cur_min) cur_min = data[i]; else if (data[i] > cur_max) cur_max = data[i]; } (*min_samp) = (mus_float_t)(cur_min - UBYTE_ZERO) / (mus_float_t)(1 << 7); (*max_samp) = (mus_float_t)(cur_max - UBYTE_ZERO) / (mus_float_t)(1 << 7); } int mus_samples_bounds(unsigned char *data, int bytes, int chan, int chans, mus_sample_t samp_type, mus_float_t *min_samp, mus_float_t *max_samp) { switch (samp_type) { case MUS_MULAW: min_max_mulaw(data, bytes, chan, chans, min_samp, max_samp); break; case MUS_ALAW: min_max_alaw(data, bytes, chan, chans, min_samp, max_samp); break; case MUS_BYTE: min_max_bytes(data, bytes, chan, chans, min_samp, max_samp); break; case MUS_UBYTE: min_max_ubytes(data, bytes, chan, chans, min_samp, max_samp); break; case MUS_L24INT: min_max_24s(data, bytes, chan, chans, min_samp, max_samp, false); break; case MUS_B24INT: min_max_24s(data, bytes, chan, chans, min_samp, max_samp, true); break; #if MUS_LITTLE_ENDIAN case MUS_LSHORT: min_max_shorts(data, bytes, chan, chans, min_samp, max_samp); break; case MUS_BSHORT: min_max_switch_shorts(data, bytes, chan, chans, min_samp, max_samp); break; case MUS_ULSHORT: min_max_ushorts(data, bytes, chan, chans, min_samp, max_samp); break; case MUS_UBSHORT: min_max_switch_ushorts(data, bytes, chan, chans, min_samp, max_samp); break; case MUS_LINT: case MUS_LINTN: min_max_ints(data, bytes, chan, chans, min_samp, max_samp, samp_type == MUS_LINT); break; case MUS_BINT: case MUS_BINTN: min_max_switch_ints(data, bytes, chan, chans, min_samp, max_samp, samp_type == MUS_BINT); break; case MUS_LFLOAT: case MUS_LFLOAT_UNSCALED: min_max_floats(data, bytes, chan, chans, min_samp, max_samp, samp_type == MUS_LFLOAT_UNSCALED); break; case MUS_BFLOAT: case MUS_BFLOAT_UNSCALED: min_max_switch_floats(data, bytes, chan, chans, min_samp, max_samp, samp_type == MUS_BFLOAT_UNSCALED); break; case MUS_LDOUBLE: case MUS_LDOUBLE_UNSCALED: min_max_doubles(data, bytes, chan, chans, min_samp, max_samp, samp_type == MUS_LDOUBLE_UNSCALED); break; case MUS_BDOUBLE: case MUS_BDOUBLE_UNSCALED: min_max_switch_doubles(data, bytes, chan, chans, min_samp, max_samp, samp_type == MUS_BDOUBLE_UNSCALED); break; #else /* big endian */ case MUS_LSHORT: min_max_switch_shorts(data, bytes, chan, chans, min_samp, max_samp); break; case MUS_BSHORT: min_max_shorts(data, bytes, chan, chans, min_samp, max_samp); break; case MUS_ULSHORT: min_max_switch_ushorts(data, bytes, chan, chans, min_samp, max_samp); break; case MUS_UBSHORT: min_max_ushorts(data, bytes, chan, chans, min_samp, max_samp); break; case MUS_LINT: case MUS_LINTN: min_max_switch_ints(data, bytes, chan, chans, min_samp, max_samp, samp_type == MUS_LINT); break; case MUS_BINT: case MUS_BINTN: min_max_ints(data, bytes, chan, chans, min_samp, max_samp, samp_type == MUS_BINT); break; case MUS_LFLOAT: case MUS_LFLOAT_UNSCALED: min_max_switch_floats(data, bytes, chan, chans, min_samp, max_samp, samp_type == MUS_LFLOAT_UNSCALED); break; case MUS_BFLOAT: case MUS_BFLOAT_UNSCALED: min_max_floats(data, bytes, chan, chans, min_samp, max_samp, samp_type == MUS_BFLOAT_UNSCALED); break; case MUS_LDOUBLE: case MUS_LDOUBLE_UNSCALED: min_max_switch_doubles(data, bytes, chan, chans, min_samp, max_samp, samp_type == MUS_LDOUBLE_UNSCALED); break; case MUS_BDOUBLE: case MUS_BDOUBLE_UNSCALED: min_max_doubles(data, bytes, chan, chans, min_samp, max_samp, samp_type == MUS_BDOUBLE_UNSCALED); break; #endif default: return(MUS_ERROR); break; } return(MUS_NO_ERROR); } char *mus_strdup(const char *str) { char *newstr = NULL; int len; if ((!str) || (!(*str))) return(NULL); len = strlen(str); newstr = (char *)malloc(len + 1); strcpy(newstr, str); newstr[len] = '\0'; return(newstr); } int mus_strlen(const char *str) { /* strlen(NULL) -> seg fault! */ if ((str) && (*str)) return(strlen(str)); return(0); } bool mus_strcmp(const char *s1, const char *s2) { if ((!s1) || (!s2)) return(s1 == s2); while (true) { unsigned char c1, c2; c1 = (unsigned char) *s1++; c2 = (unsigned char) *s2++; if (c1 != c2) return(false); if (c1 == '\0') break; } return(true); #if 0 return((str1 == str2) || ((str1) && (str2) && (strcmp(str1, str2) == 0))); #endif } char *mus_strcat(char *errmsg, const char *str, int *size) { int new_len, err_size; new_len = (mus_strlen(str) + mus_strlen(errmsg)); err_size = size[0]; if (new_len >= err_size) { if ((err_size * 2) > new_len) err_size = err_size * 2; else err_size = new_len * 2; errmsg = (char *)realloc(errmsg, err_size * sizeof(char)); size[0] = err_size; } strcat(errmsg, str); return(errmsg); } snd-16.1/mkinstalldirs0000755000076400007640000000653510330501342013141 0ustar bilbil#! /bin/sh # mkinstalldirs --- make directory hierarchy scriptversion=2004-02-15.20 # Original author: Noah Friedman # Created: 1993-05-16 # Public domain. # # This file is maintained in Automake, please report # bugs to or send patches to # . errstatus=0 dirmode="" usage="\ Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ... Create each directory DIR (with mode MODE, if specified), including all leading file name components. Report bugs to ." # process command line arguments while test $# -gt 0 ; do case $1 in -h | --help | --h*) # -h for help echo "$usage" exit 0 ;; -m) # -m PERM arg shift test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } dirmode=$1 shift ;; --version) echo "$0 $scriptversion" exit 0 ;; --) # stop option processing shift break ;; -*) # unknown option echo "$usage" 1>&2 exit 1 ;; *) # first non-opt arg break ;; esac done for file do if test -d "$file"; then shift else break fi done case $# in 0) exit 0 ;; esac # Solaris 8's mkdir -p isn't thread-safe. If you mkdir -p a/b and # mkdir -p a/c at the same time, both will detect that a is missing, # one will create a, then the other will try to create a and die with # a "File exists" error. This is a problem when calling mkinstalldirs # from a parallel make. We use --version in the probe to restrict # ourselves to GNU mkdir, which is thread-safe. case $dirmode in '') if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then echo "mkdir -p -- $*" exec mkdir -p -- "$@" else # On NextStep and OpenStep, the `mkdir' command does not # recognize any option. It will interpret all options as # directories to create, and then abort because `.' already # exists. test -d ./-p && rmdir ./-p test -d ./--version && rmdir ./--version fi ;; *) if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 && test ! -d ./--version; then echo "mkdir -m $dirmode -p -- $*" exec mkdir -m "$dirmode" -p -- "$@" else # Clean up after NextStep and OpenStep mkdir. for d in ./-m ./-p ./--version "./$dirmode"; do test -d $d && rmdir $d done fi ;; esac for file do set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` shift pathcomp= for d do pathcomp="$pathcomp$d" case $pathcomp in -*) pathcomp=./$pathcomp ;; esac if test ! -d "$pathcomp"; then echo "mkdir $pathcomp" mkdir "$pathcomp" || lasterr=$? if test ! -d "$pathcomp"; then errstatus=$lasterr else if test ! -z "$dirmode"; then echo "chmod $dirmode $pathcomp" lasterr="" chmod "$dirmode" "$pathcomp" || lasterr=$? if test ! -z "$lasterr"; then errstatus=$lasterr fi fi fi fi pathcomp="$pathcomp/" done done exit $errstatus # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-end: "$" # End: snd-16.1/draw.rb0000644000076400007640000001544412434353162011630 0ustar bilbil# draw.rb -- draw.scm --> draw.rb # Translator: Michael Scholz # Created: 05/04/05 00:17:04 # Changed: 14/11/13 03:06:52 # examples of extensions to Snd's graphics # # module Draw # display_colored_samples(color, beg, dur, snd = false, chn = false) # display_samples_in_color(snd, chn) # color_samples(color, beg = 0, dur = false, snd = Snd.snd, chn = Snd.chn) # uncolor_samples(snd = Snd.snd, chn = Snd.chn) # display_previous_edits(snd, chn) # overlay_sounds(*rest) # samples_via_colormap(snd, chn) # click_for_listener_help(pos) require "extensions" module Draw add_help(:display_colored_samples, "display_colored_samples(color, beg, dur, snd=false, chn=false) \ Displays samples from beg for dur in color \ whenever they're in the current view.") def display_colored_samples(color, beg, dur, snd = false, chn = false) unless array?(color) and number?(beg) and number?(dur) return end left = left_sample(snd, chn) right = right_sample(snd, chn) len = beg + dur old_color = foreground_color(snd, chn) if left < len and right > beg cr = make_cairo(channel_widgets(snd, chn)[0]) if vct?(data = make_graph_data(snd, chn)) samps = [right, len].min - [left, beg].max offset = [0, beg - left].max new_data = data.subseq(offset, offset + samps) set_foreground_color(color, snd, chn) graph_data(new_data, snd, chn, Copy_context, [beg, left].max, [len, right].min, Graph_lines, cr) set_foreground_color(old_color, snd, chn) else low_data, high_data = data[0, 2] size = low_data.length samps = right - left left_offset = [0, beg - left].max left_bin = ((size.to_f * left_offset) / samps).floor right_offset = [len, right].min - left right_bin = ((size.to_f * right_offset) / samps).floor new_low_data = low_data.subseq(left_bin, right_bin) new_high_data = high_data.subseq(left_bin, right_bin) set_foreground_color(color, snd, chn) graph_data([new_low_data, new_high_data], snd, chn, Copy_context, left_bin, right_bin, Graph_lines, cr) set_foreground_color(old_color, snd, chn) end free_cairo(cr) end end def display_samples_in_color(snd, chn) col, beg, dur = channel_property(:colored_samples, snd, chn) display_colored_samples(col, beg, dur, snd, chn) end add_help(:color_samples, "color_samples(color, beg=0, dur=false, snd=false, chn=false) \ Causes samples from BEG to BEG+DUR to be displayed in COLOR.") def color_samples(color, beg = 0, dur = false, snd = Snd.snd, chn = Snd.chn) unless $after_graph_hook.member?("display-samples-in-color") $after_graph_hook.add_hook!("display-samples-in-color") do |s, c| display_samples_in_color(s, c) end end unless dur then dur = framples(snd, chn) - beg end set_channel_property(:colored_samples, [color, beg, dur], snd, chn) update_time_graph(snd, chn) end add_help(:uncolor_samples, "uncolor_samples(snd=false, chn=false) \ Cancels sample coloring in the given channel.") def uncolor_samples(snd = Snd.snd, chn = Snd.chn) set_channel_property(:colored_samples, [], snd, chn) update_time_graph(snd, chn) end add_help(:display_previous_edits, "display_previous_edits(snd, chn) \ Displays all edits of the current sound, \ with older versions gradually fading away.") def display_previous_edits(snd, chn) edits = edit_position(snd, chn) if edits > 0 old_color = foreground_color(snd, chn) clist = color2list(old_color) r = clist[0] g = clist[1] b = clist[2] rinc = (1.0 - r) / (edits + 1) ginc = (1.0 - g) / (edits + 1) binc = (1.0 - b) / (edits + 1) cr = make_cairo(channel_widgets(snd, chn)[0]) re = 1.0 - rinc ge = 1.0 - ginc be = 1.0 - binc 0.upto(edits) do |pos| data = make_graph_data(snd, chn, pos) set_foreground_color(make_color(re, ge, be), snd, chn) graph_data(data, snd, chn, Copy_context, false, false, time_graph_style(snd, chn), cr) re -= rinc ge -= ginc be -= binc end set_foreground_color(old_color, snd, chn) free_cairo(cr) end end add_help(:overlay_sounds, "overlay_sounds(*rest) \ Overlays onto its first argument all \ subsequent arguments: overlay_sounds(1, 0, 3)") def overlay_sounds(*rest) base = rest.shift if integer?(base) base = integer2sound(base) end $after_graph_hook.add_hook!(get_func_name) do |snd, chn| if snd == base cr = make_cairo(channel_widgets(snd, chn)[0]) rest.each do |s| graph_data(make_graph_data(s, chn), base, chn, Copy_context, false, false, Graph_dots, cr) end free_cairo(cr) end end end add_help(:samples_via_colormap, "samples_via_colormap(snd, chn) \ Displays time domain graph using current \ colormap (just an example of colormap_ref).") def samples_via_colormap(snd, chn) left = left_sample(snd, chn) old_color = foreground_color(snd, chn) if data = make_graph_data(snd, chn) cr = make_cairo(channel_widgets(snd, chn)[0]) if vct?(data) data = [data] end data.each do |cur_data| x0 = x2position(left / srate(snd)) y0 = y2position(cur_data[0]) colors = make_array(colormap_size) j = 1 (left + 1).upto(left + cur_data.length - 1) do |i| x1 = x2position(i / srate(snd)) y1 = y2position(cur_data[j]) x = cur_data[j].abs ref = (colormap_size * x).floor unless colors[ref] colors[ref] = make_color(*colormap_ref(colormap, x)) end set_foreground_color(colors[ref], snd, chn) draw_line(x0, y0, x1, y1, snd, chn, Time_graph, cr) x0, y0 = x1, y1 j += 1 end end free_cairo(cr) set_foreground_color(old_color, snd, chn) end end # click-for-listener-help $last_click_time = 0.0 def click_for_listener_help(pos) time = Time.now.to_f if time - $last_click_time < 0.2 $last_click_time = 0.0 text = widget_text(main_widgets[4]) if string?(text) subject = text.slice(text.rindex(/\b/m, pos)...text.index(/\b/m, pos)) if string?(subject) help = snd_help(subject, false) if string?(help) help_dialog(subject, help) end end end else $last_click_time = time end end # $listener_click_hook.add_hook!("listener-help", # &method(:click_for_listener_help).to_proc) end include Draw # draw.rb ends here snd-16.1/snd-strings.h0000644000076400007640000011626412524201705012767 0ustar bilbil#ifndef SND_STRINGS_H #define SND_STRINGS_H #define S_abort "abort" #define S_add_colormap "add-colormap" #define S_add_directory_to_view_files_list "add-directory-to-view-files-list" #define S_add_file_filter "add-file-filter" #define S_add_file_sorter "add-file-sorter" #define S_add_file_to_view_files_list "add-file-to-view-files-list" #define S_add_mark "add-mark" #define S_add_player "add-player" #define S_add_sound_file_extension "add-sound-file-extension" #define S_add_source_file_extension "add-source-file-extension" #define S_add_to_main_menu "add-to-main-menu" #define S_add_to_menu "add-to-menu" #define S_add_transform "add-transform" #define S_after_apply_controls_hook "after-apply-controls-hook" #define S_after_edit_hook "after-edit-hook" #define S_after_graph_hook "after-graph-hook" #define S_after_lisp_graph_hook "after-lisp-graph-hook" #define S_after_open_hook "after-open-hook" #define S_after_save_as_hook "after-save-as-hook" #define S_after_save_state_hook "after-save-state-hook" #define S_after_transform_hook "after-transform-hook" #define S_amp_control "amp-control" #define S_amp_control_bounds "amp-control-bounds" #define S_apply_controls "apply-controls" #define S_as_one_edit "as-one-edit" #define S_ask_before_overwrite "ask-before-overwrite" #define S_ask_about_unsaved_edits "ask-about-unsaved-edits" #define S_auto_resize "auto-resize" #define S_auto_update "auto-update" #define S_auto_update_interval "auto-update-interval" #define S_autocorrelation "autocorrelation" #define S_axis_color "axis-color" #define S_axis_info "axis-info" #define S_axis_label_font "axis-label-font" #define S_axis_numbers_font "axis-numbers-font" #define S_background_gradient "background-gradient" #define S_bad_header_hook "bad-header-hook" #define S_basic_color "basic-color" #define S_beats_per_measure "beats-per-measure" #define S_beats_per_minute "beats-per-minute" #define S_before_close_hook "before-close-hook" #define S_before_exit_hook "before-exit-hook" #define S_before_save_as_hook "before-save-as-hook" #define S_before_save_state_hook "before-save-state-hook" #define S_before_transform_hook "before-transform-hook" #define S_bind_key "bind-key" #define S_bold_peaks_font "bold-peaks-font" #if (!HAVE_SCHEME) #define S_c_g "c-g?" #endif #define S_cepstrum "cepstrum" #define S_channel_amp_envs "channel-amp-envs" #define S_channel_data "channel-data" #define S_channel_properties "channel-properties" #define S_channel_property "channel-property" #define S_channel_style "channel-style" #define S_channel_widgets "channel-widgets" #define S_channels "channels" #define S_channels_combined "channels-combined" #define S_channels_separate "channels-separate" #define S_channels_superimposed "channels-superimposed" #define S_chans "chans" #define S_clear_listener "clear-listener" #define S_clip_hook "clip-hook" #define S_clipping "clipping" #define S_clm_channel "clm-channel" #define S_close_hook "close-hook" #define S_close_sound "close-sound" #define S_color_cutoff "color-cutoff" #define S_color_orientation_dialog "color-orientation-dialog" #define S_color_hook "color-hook" #define S_color_inverted "color-inverted" #define S_is_color "color?" #define S_color_scale "color-scale" #define S_color_to_list "color->list" #define S_colormap "colormap" #define S_colormap_name "colormap-name" #define S_is_colormap "colormap?" #define S_colormap_ref "colormap-ref" #define S_colormap_size "colormap-size" #define S_colormap_to_integer "colormap->integer" #define S_combined_data_color "combined-data-color" #define S_comment "comment" #define S_contrast_control "contrast-control" #define S_contrast_control_amp "contrast-control-amp" #define S_contrast_control_bounds "contrast-control-bounds" #define S_contrast_control_on "contrast-control?" #define S_controls_to_channel "controls->channel" #define S_convolve_selection_with "convolve-selection-with" #define S_convolve_with "convolve-with" #define S_copy_context "copy-context" #define S_copy_sampler "copy-sampler" #define S_count_matches "count-matches" #define S_current_edit_position "current-edit-position" #define S_current_font "current-font" #define S_cursor "cursor" #define S_cursor_color "cursor-color" #define S_cursor_context "cursor-context" #define S_cursor_cross "cursor-cross" #define S_cursor_in_middle "cursor-in-middle" #define S_cursor_in_view "cursor-in-view" #define S_cursor_line "cursor-line" #define S_cursor_location_offset "cursor-location-offset" #define S_cursor_on_left "cursor-on-left" #define S_cursor_on_right "cursor-on-right" #define S_cursor_position "cursor-position" #define S_cursor_size "cursor-size" #define S_cursor_style "cursor-style" #define S_cursor_update_interval "cursor-update-interval" #define S_dac_combines_channels "dac-combines-channels" #define S_dac_size "dac-size" #define S_data_color "data-color" #define S_sample_type "sample-type" #define S_data_location "data-location" #define S_data_size "data-size" #define S_default_output_chans "default-output-chans" #define S_default_output_sample_type "default-output-sample-type" #define S_default_output_srate "default-output-srate" #define S_default_output_header_type "default-output-header-type" #define S_define_envelope "define-envelope" #define S_delete_colormap "delete-colormap" #define S_delete_file_filter "delete-file-filter" #define S_delete_file_sorter "delete-file-sorter" #define S_delete_mark "delete-mark" #define S_delete_marks "delete-marks" #define S_delete_sample "delete-sample" #define S_delete_samples "delete-samples" #define S_delete_samples_and_smooth "delete-samples-and-smooth" #define S_delete_selection "delete-selection" #define S_delete_selection_and_smooth "delete-selection-and-smooth" #define S_delete_transform "delete-transform" #define S_dialog_widgets "dialog-widgets" #define S_display_edits "display-edits" #define S_dont_normalize "dont-normalize" #define S_dot_size "dot-size" #define S_draw_axes "draw-axes" #define S_draw_dot "draw-dot" #define S_draw_dots "draw-dots" #define S_draw_line "draw-line" #define S_draw_lines "draw-lines" #define S_draw_mark_hook "draw-mark-hook" #define S_draw_mix_hook "draw-mix-hook" #define S_draw_string "draw-string" #define S_drop_hook "drop-hook" #define S_during_open_hook "during-open-hook" #define S_edit_fragment "edit-fragment" #define S_edit_header_dialog "edit-header-dialog" #define S_edit_hook "edit-hook" #define S_edit_list_to_function "edit-list->function" #define S_edit_position "edit-position" #define S_edit_properties "edit-properties" #define S_edit_property "edit-property" #define S_edit_tree "edit-tree" #define S_edits "edits" #define S_effects_hook "effects-hook" #define S_env_channel "env-channel" #define S_env_channel_with_base "env-channel-with-base" #define S_env_selection "env-selection" #define S_env_sound "env-sound" #define S_enved_add_point "enved-add-point" #define S_enved_amplitude "enved-amplitude" #define S_enved_base "enved-base" #define S_enved_clipping "enved-clip?" #define S_enved_delete_point "enved-delete-point" #define S_enved_dialog "enved-dialog" #define S_enved_envelope "enved-envelope" #define S_enved_filter "enved-filter" #define S_enved_filter_order "enved-filter-order" #define S_enved_hook "enved-hook" #define S_enved_in_dB "enved-in-dB" #define S_enved_move_point "enved-move-point" #define S_enved_power "enved-power" #define S_enved_spectrum "enved-spectrum" #define S_enved_srate "enved-srate" #define S_enved_style "enved-style" #define S_enved_target "enved-target" #define S_enved_with_wave "enved-wave?" #define S_enved_waveform_color "enved-waveform-color" #define S_envelope_exponential "envelope-exponential" #define S_envelope_linear "envelope-linear" #define S_eps_bottom_margin "eps-bottom-margin" #define S_eps_file "eps-file" #define S_eps_left_margin "eps-left-margin" #define S_eps_size "eps-size" #define S_exit "exit" #define S_exit_hook "exit-hook" #define S_expand_control "expand-control" #define S_expand_control_bounds "expand-control-bounds" #define S_expand_control_hop "expand-control-hop" #define S_expand_control_jitter "expand-control-jitter" #define S_expand_control_length "expand-control-length" #define S_expand_control_on "expand-control?" #define S_expand_control_ramp "expand-control-ramp" #define S_fft "fft" #define S_fft_log_frequency "fft-log-frequency" #define S_fft_log_magnitude "fft-log-magnitude" #define S_fft_window "fft-window" #define S_fft_window_alpha "fft-window-alpha" #define S_fft_window_beta "fft-window-beta" #define S_fft_with_phases "fft-with-phases" #define S_file_name "file-name" #define S_fill_polygon "fill-polygon" #define S_fill_rectangle "fill-rectangle" #define S_filter_channel "filter-channel" #define S_filter_control_coeffs "filter-control-coeffs" #define S_filter_control_envelope "filter-control-envelope" #define S_filter_control_in_dB "filter-control-in-dB" #define S_filter_control_in_hz "filter-control-in-hz" #define S_filter_control_order "filter-control-order" #define S_filter_control_on "filter-control?" #define S_filter_control_waveform_color "filter-control-waveform-color" #define S_filter_selection "filter-selection" #define S_filter_sound "filter-sound" #define S_find_channel "find-channel" #define S_find_dialog "find-dialog" #define S_find_mark "find-mark" #define S_find_sound "find-sound" #define S_finish_progress_report "finish-progress-report" #define S_focus_widget "focus-widget" #define S_foreground_color "foreground-color" #define S_forget_region "forget-region" #define S_fourier_transform "fourier-transform" #define S_framples "framples" #define S_free_cairo "free-cairo" #define S_free_player "free-player" #define S_free_sampler "free-sampler" #define S_gl_graph_to_ps "gl-graph->ps" #define S_goto_listener_end "goto-listener-end" #define S_graph "graph" #define S_graph_as_sonogram "graph-as-sonogram" #define S_graph_as_spectrogram "graph-as-spectrogram" #define S_graph_as_wavogram "graph-as-wavogram" #define S_graph_color "graph-color" #define S_graph_cursor "graph-cursor" #define S_graph_data "graph-data" #define S_graph_dots "graph-dots" #define S_graph_dots_and_lines "graph-dots-and-lines" #define S_graph_filled "graph-filled" #define S_graph_hook "graph-hook" #define S_graph_lines "graph-lines" #define S_graph_lollipops "graph-lollipops" #define S_graph_once "graph-once" #define S_graph_style "graph-style" #define S_graph_to_ps "graph->ps" #define S_graphs_horizontal "graphs-horizontal" #define S_grid_density "grid-density" #define S_haar_transform "haar-transform" #define S_header_type "header-type" #define S_help_dialog "help-dialog" #define S_help_hook "help-hook" #define S_hide_widget "hide-widget" #define S_highlight_color "highlight-color" #define S_html_dir "html-dir" #define S_html_program "html-program" #if HAVE_RUBY #define S_in "call-in" #else #define S_in "in" #endif #define S_info_dialog "info-dialog" #define S_initial_beg "initial-beg" #define S_initial_dur "initial-dur" #define S_initial_graph_hook "initial-graph-hook" #define S_insert_file_dialog "insert-file-dialog" #define S_insert_region "insert-region" #define S_insert_sample "insert-sample" #define S_insert_samples "insert-samples" #define S_insert_selection "insert-selection" #define S_insert_silence "insert-silence" #define S_insert_sound "insert-sound" #define S_integer_to_colormap "integer->colormap" #define S_integer_to_mark "integer->mark" #define S_integer_to_mix "integer->mix" #define S_integer_to_region "integer->region" #define S_integer_to_sound "integer->sound" #define S_integer_to_transform "integer->transform" #define S_just_sounds "just-sounds" #define S_key "key" #define S_key_binding "key-binding" #define S_key_press_hook "key-press-hook" #define S_keyboard_no_action "keyboard-no-action" #define S_ladspa_dir "ladspa-dir" #define S_left_sample "left-sample" #define S_lisp_graph "lisp-graph" #define S_lisp_graph_hook "lisp-graph-hook" #define S_lisp_graph_on "lisp-graph?" #define S_lisp_graph_style "lisp-graph-style" #define S_listener_click_hook "listener-click-hook" #define S_listener_color "listener-color" #define S_listener_colorized "listener-colorized" #define S_listener_font "listener-font" #define S_listener_prompt "listener-prompt" #define S_listener_selection "listener-selection" #define S_listener_text_color "listener-text-color" #define S_log_freq_start "log-freq-start" #define S_main_menu "main-menu" #define S_main_widgets "main-widgets" #define S_make_cairo "make-cairo" #define S_make_color "make-color" #define S_make_graph_data "make-graph-data" #define S_make_mix_sampler "make-mix-sampler" #define S_make_player "make-player" #define S_make_region "make-region" #define S_make_region_sampler "make-region-sampler" #define S_make_sampler "make-sampler" #define S_make_snd_to_sample "make-snd->sample" #define S_make_variable_graph "make-variable-graph" #define S_map_chan "map-chan" #define S_map_channel "map-channel" #define S_mark_click_hook "mark-click-hook" #define S_mark_color "mark-color" #define S_mark_context "mark-context" #define S_mark_drag_hook "mark-drag-hook" #define S_mark_home "mark-home" #define S_mark_hook "mark-hook" #define S_mark_name "mark-name" #define S_mark_properties "mark-properties" #define S_mark_property "mark-property" #define S_is_mark "mark?" #define S_mark_sample "mark-sample" #define S_mark_sync "mark-sync" #define S_mark_sync_max "mark-sync-max" #define S_mark_tag_height "mark-tag-height" #define S_mark_tag_width "mark-tag-width" #define S_mark_to_integer "mark->integer" #define S_marks "marks" #define S_max_regions "max-regions" #define S_max_transform_peaks "max-transform-peaks" #define S_maxamp "maxamp" #define S_maxamp_position "maxamp-position" #define S_menu_widgets "menu-widgets" #define S_min_dB "min-dB" #define S_mix "mix" #define S_mix_amp "mix-amp" #define S_mix_amp_env "mix-amp-env" #define S_mix_click_hook "mix-click-hook" #define S_mix_color "mix-color" #define S_mix_dialog_mix "mix-dialog-mix" #define S_mix_drag_hook "mix-drag-hook" #define S_mix_file_dialog "mix-file-dialog" #define S_mix_length "mix-length" #define S_mix_home "mix-home" #define S_is_mix "mix?" #define S_mix_name "mix-name" #define S_mix_position "mix-position" #define S_mix_properties "mix-properties" #define S_mix_property "mix-property" #define S_mix_region "mix-region" #define S_mix_release_hook "mix-release-hook" #define S_is_mix_sampler "mix-sampler?" #define S_mix_selection "mix-selection" #define S_mix_speed "mix-speed" #define S_mix_sync "mix-sync" #define S_mix_sync_max "mix-sync-max" #define S_mix_tag_height "mix-tag-height" #define S_mix_tag_width "mix-tag-width" #define S_mix_tag_y "mix-tag-y" #define S_mix_to_integer "mix->integer" #define S_mix_waveform_height "mix-waveform-height" #define S_mixes "mixes" #define S_mouse_click_hook "mouse-click-hook" #define S_mouse_drag_hook "mouse-drag-hook" #define S_mouse_enter_graph_hook "mouse-enter-graph-hook" #define S_mouse_enter_label_hook "mouse-enter-label-hook" #define S_mouse_enter_listener_hook "mouse-enter-listener-hook" #define S_mouse_enter_text_hook "mouse-enter-text-hook" #define S_mouse_leave_graph_hook "mouse-leave-graph-hook" #define S_mouse_leave_label_hook "mouse-leave-label-hook" #define S_mouse_leave_listener_hook "mouse-leave-listener-hook" #define S_mouse_leave_text_hook "mouse-leave-text-hook" #define S_mouse_press_hook "mouse-press-hook" #define S_mus_error_hook "mus-error-hook" #define S_name_click_hook "name-click-hook" #define S_new_sound "new-sound" #define S_new_sound_dialog "new-sound-dialog" #define S_new_widget_hook "new-widget-hook" #define S_next_sample "next-sample" #define S_normalize_by_channel "normalize-by-channel" #define S_normalize_by_sound "normalize-by-sound" #define S_normalize_channel "normalize-channel" #define S_normalize_globally "normalize-globally" #define S_open_file_dialog "open-file-dialog" #define S_open_file_dialog_directory "open-file-dialog-directory" #define S_open_hook "open-hook" #define S_open_raw_sound "open-raw-sound" #define S_open_raw_sound_hook "open-raw-sound-hook" #define S_open_sound "open-sound" #define S_orientation_hook "orientation-hook" #define S_output_comment_hook "output-comment-hook" #define S_pad_channel "pad-channel" #define S_pausing "pausing" #define S_peak_env_dir "peak-env-dir" #define S_peaks "peaks" #define S_peaks_font "peaks-font" #define S_play "play" #define S_play_arrow_size "play-arrow-size" #define S_play_hook "play-hook" #define S_playing "playing" #define S_player_home "player-home" #define S_is_player "player?" #define S_players "players" #define S_position_color "position-color" #define S_position_to_x "position->x" #define S_position_to_y "position->y" #define S_preferences_dialog "preferences-dialog" #define S_previous_sample "previous-sample" #define S_print_dialog "print-dialog" #define S_print_length "print-length" #define S_progress_report "progress-report" #define S_ramp_channel "ramp-channel" #define S_read_hook "read-hook" #define S_read_mix_sample "read-mix-sample" #define S_read_only "read-only" #define S_read_region_sample "read-region-sample" #define S_read_sample "read-sample" #if HAVE_RUBY #define S_redo "redo-edit" #else #define S_redo "redo" #endif #define S_region_chans "region-chans" #define S_region_framples "region-framples" #define S_region_graph_style "region-graph-style" #define S_region_home "region-home" #define S_region_maxamp "region-maxamp" #define S_region_maxamp_position "region-maxamp-position" #define S_is_region "region?" #define S_region_position "region-position" #define S_region_sample "region-sample" #define S_is_region_sampler "region-sampler?" #define S_region_srate "region-srate" #define S_region_to_integer "region->integer" #define S_regions "regions" #define S_remember_sound_state "remember-sound-state" #define S_remove_from_menu "remove-from-menu" #define S_reset_controls "reset-controls" #define S_reset_listener_cursor "reset-listener-cursor" #define S_restore_controls "restore-controls" #define S_restore_region "restore-region" #define S_reverb_control_decay "reverb-control-decay" #define S_reverb_control_feedback "reverb-control-feedback" #define S_reverb_control_length "reverb-control-length" #define S_reverb_control_length_bounds "reverb-control-length-bounds" #define S_reverb_control_lowpass "reverb-control-lowpass" #define S_reverb_control_on "reverb-control?" #define S_reverb_control_scale "reverb-control-scale" #define S_reverb_control_scale_bounds "reverb-control-scale-bounds" #define S_reverse_channel "reverse-channel" #define S_reverse_selection "reverse-selection" #define S_reverse_sound "reverse-sound" #define S_revert_sound "revert-sound" #define S_right_sample "right-sample" #define S_sample "sample" #define S_is_sampler_at_end "sampler-at-end?" #define S_sampler_home "sampler-home" #define S_is_sampler "sampler?" #define S_sampler_position "sampler-position" #define S_samples "samples" #define S_sash_color "sash-color" #define S_save_as_dialog_src "save-as-dialog-src" #define S_save_as_dialog_auto_comment "save-as-dialog-auto-comment" #define S_save_controls "save-controls" #define S_save_dir "save-dir" #define S_save_edit_history "save-edit-history" #define S_save_envelopes "save-envelopes" #define S_save_hook "save-hook" #define S_save_listener "save-listener" #define S_save_marks "save-marks" #define S_save_mix "save-mix" #define S_save_region "save-region" #define S_save_region_dialog "save-region-dialog" #define S_save_selection "save-selection" #define S_save_selection_dialog "save-selection-dialog" #define S_save_sound "save-sound" #define S_save_sound_as "save-sound-as" #define S_save_sound_dialog "save-sound-dialog" #define S_save_state "save-state" #define S_save_state_file "save-state-file" #define S_save_state_hook "save-state-hook" #define S_scale_by "scale-by" #define S_scale_channel "scale-channel" #define S_scale_selection_by "scale-selection-by" #define S_scale_selection_to "scale-selection-to" #define S_scale_to "scale-to" #define S_scan_chan "scan-chan" #define S_scan_channel "scan-channel" #define S_script_arg "script-arg" #define S_script_args "script-args" #define S_search_procedure "search-procedure" #define S_select_all "select-all" #define S_select_channel "select-channel" #define S_select_channel_hook "select-channel-hook" #define S_select_sound "select-sound" #define S_select_sound_hook "select-sound-hook" #define S_selected_channel "selected-channel" #define S_selected_data_color "selected-data-color" #define S_selected_graph_color "selected-graph-color" #define S_selected_sound "selected-sound" #define S_selection "selection" #define S_selection_chans "selection-chans" #define S_selection_color "selection-color" #define S_selection_context "selection-context" #define S_selection_creates_region "selection-creates-region" #define S_selection_framples "selection-framples" #define S_selection_maxamp "selection-maxamp" #define S_selection_maxamp_position "selection-maxamp-position" #define S_selection_member "selection-member?" #define S_selection_to_mix "selection->mix" #define S_is_selection "selection?" #define S_selection_position "selection-position" #define S_selection_srate "selection-srate" #define S_short_file_name "short-file-name" #define S_show_all_axes "show-all-axes" #define S_show_all_axes_unlabelled "show-all-axes-unlabelled" #define S_show_axes "show-axes" #define S_show_bare_x_axis "show-bare-x-axis" #define S_show_controls "show-controls" #define S_show_full_duration "show-full-duration" #define S_show_full_range "show-full-range" #define S_show_grid "show-grid" #define S_show_indices "show-indices" #define S_show_listener "show-listener" #define S_show_marks "show-marks" #define S_show_mix_waveforms "show-mix-waveforms" #define S_show_no_axes "show-no-axes" #define S_show_selection "show-selection" #define S_show_selection_transform "show-selection-transform" #define S_show_sonogram_cursor "show-sonogram-cursor" #define S_show_transform_peaks "show-transform-peaks" #define S_show_widget "show-widget" #define S_show_x_axis "show-x-axis" #define S_show_x_axis_unlabelled "show-x-axis-unlabelled" #define S_show_y_zero "show-y-zero" #define S_sinc_width "sinc-width" #define S_smooth_channel "smooth-channel" #define S_smooth_selection "smooth-selection" #define S_smooth_sound "smooth-sound" #define S_snd_color "snd-color" #define S_snd_error "snd-error" #define S_snd_error_hook "snd-error-hook" #define S_snd_font "snd-font" #define S_snd_gcs "snd-gcs" #define S_snd_help "snd-help" #if HAVE_RUBY #define S_snd_opened_sound "snd-opened-sound" #else #define S_snd_opened_sound "*snd-opened-sound*" #endif #define S_snd_print "snd-print" #define S_snd_spectrum "snd-spectrum" #define S_snd_tempnam "snd-tempnam" #define S_snd_to_sample "snd->sample" #define S_is_snd_to_sample "snd->sample?" #define S_snd_url "snd-url" #define S_snd_urls "snd-urls" #define S_snd_version "snd-version" #define S_snd_warning "snd-warning" #define S_snd_warning_hook "snd-warning-hook" #define S_sound_file_extensions "sound-file-extensions" #define S_is_sound_file "sound-file?" #define S_sound_files_in_directory "sound-files-in-directory" #define S_sound_loop_info "sound-loop-info" #define S_is_sound "sound?" #define S_sound_properties "sound-properties" #define S_sound_property "sound-property" #define S_sound_widgets "sound-widgets" #define S_sound_to_integer "sound->integer" #define S_soundfont_info "soundfont-info" #define S_sounds "sounds" #define S_spectro_hop "spectro-hop" #define S_spectro_x_angle "spectro-x-angle" #define S_spectro_x_scale "spectro-x-scale" #define S_spectro_y_angle "spectro-y-angle" #define S_spectro_y_scale "spectro-y-scale" #define S_spectro_z_angle "spectro-z-angle" #define S_spectro_z_scale "spectro-z-scale" #define S_spectrum_end "spectrum-end" #define S_spectrum_start "spectrum-start" #define S_speed_control "speed-control" #define S_speed_control_as_float "speed-control-as-float" #define S_speed_control_as_ratio "speed-control-as-ratio" #define S_speed_control_as_semitone "speed-control-as-semitone" #define S_speed_control_bounds "speed-control-bounds" #define S_speed_control_style "speed-control-style" #define S_speed_control_tones "speed-control-tones" #define S_squelch_update "squelch-update" #define S_srate "srate" #define S_src_channel "src-channel" #define S_src_selection "src-selection" #define S_src_sound "src-sound" #define S_start_hook "start-hook" #define S_start_playing "start-playing" #define S_start_playing_hook "start-playing-hook" #define S_start_playing_selection_hook "start-playing-selection-hook" #define S_start_progress_report "start-progress-report" #define S_status_report "status-report" #define S_stop_player "stop-player" #define S_stop_playing "stop-playing" #define S_stop_playing_hook "stop-playing-hook" #define S_stop_playing_selection_hook "stop-playing-selection-hook" #define S_swap_channels "swap-channels" #define S_sync "sync" #define S_sync_all "sync-all" #define S_sync_by_sound "sync-by-sound" #define S_sync_max "sync-max" #define S_sync_none "sync-none" #define S_sync_style "sync-style" #define S_syncd_marks "syncd-marks" #define S_temp_dir "temp-dir" #define S_text_focus_color "text-focus-color" #define S_time_graph "time-graph" #define S_time_graph_on "time-graph?" #define S_time_graph_style "time-graph-style" #define S_time_graph_type "time-graph-type" #define S_tiny_font "tiny-font" #define S_tracking_cursor_style "tracking-cursor-style" #define S_transform_dialog "transform-dialog" #define S_transform_framples "transform-framples" #define S_transform_graph "transform-graph" #define S_transform_graph_on "transform-graph?" #define S_transform_graph_style "transform-graph-style" #define S_transform_graph_type "transform-graph-type" #define S_transform_normalization "transform-normalization" #define S_is_transform "transform?" #define S_transform_sample "transform-sample" #define S_transform_size "transform-size" #define S_transform_to_integer "transform->integer" #define S_transform_type "transform-type" #define S_unbind_key "unbind-key" #define S_undo "undo" #define S_undo_hook "undo-hook" #define S_unselect_all "unselect-all" #define S_update_hook "update-hook" #define S_update_lisp_graph "update-lisp-graph" #define S_update_sound "update-sound" #define S_update_time_graph "update-time-graph" #define S_update_transform_graph "update-transform-graph" #define S_is_variable_graph "variable-graph?" #define S_view_files_amp "view-files-amp" #define S_view_files_amp_env "view-files-amp-env" #define S_view_files_dialog "view-files-dialog" #define S_view_files_files "view-files-files" #define S_view_files_selected_files "view-files-selected-files" #define S_view_files_select_hook "view-files-select-hook" #define S_view_files_sort "view-files-sort" #define S_view_files_speed "view-files-speed" #define S_view_files_speed_style "view-files-speed-style" #define S_view_mixes_dialog "view-mixes-dialog" #define S_view_regions_dialog "view-regions-dialog" #define S_view_sound "view-sound" #define S_walsh_transform "walsh-transform" #define S_wavelet_transform "wavelet-transform" #define S_wavelet_type "wavelet-type" #define S_wavo_hop "wavo-hop" #define S_wavo_trace "wavo-trace" #define S_widget_position "widget-position" #define S_widget_size "widget-size" #define S_widget_text "widget-text" #define S_window_height "window-height" #define S_window_width "window-width" #define S_window_x "window-x" #define S_window_y "window-y" #define S_with_background_processes "with-background-processes" #define S_with_file_monitor "with-file-monitor" #define S_with_gl "with-gl" #define S_with_inset_graph "with-inset-graph" #define S_with_interrupts "with-interrupts" #define S_with_menu_icons "with-menu-icons" #define S_with_mix_tags "with-mix-tags" #define S_with_pointer_focus "with-pointer-focus" #define S_with_relative_panes "with-relative-panes" #define S_with_smpte_label "with-smpte-label" #define S_with_toolbar "with-toolbar" #define S_with_tooltips "with-tooltips" #define S_with_tracking_cursor "with-tracking-cursor" #define S_with_verbose_cursor "with-verbose-cursor" #define S_x_axis_as_clock "x-axis-as-clock" #define S_x_axis_as_percentage "x-axis-as-percentage" #define S_x_axis_in_beats "x-axis-in-beats" #define S_x_axis_in_measures "x-axis-in-measures" #define S_x_axis_in_samples "x-axis-in-samples" #define S_x_axis_in_seconds "x-axis-in-seconds" #define S_x_axis_label "x-axis-label" #define S_x_axis_style "x-axis-style" #define S_x_bounds "x-bounds" #define S_x_position_slider "x-position-slider" #define S_x_to_position "x->position" #define S_x_zoom_slider "x-zoom-slider" #define S_xramp_channel "xramp-channel" #define S_y_axis_label "y-axis-label" #define S_y_bounds "y-bounds" #define S_y_position_slider "y-position-slider" #define S_y_to_position "y->position" #define S_y_zoom_slider "y-zoom-slider" #define S_zero_pad "zero-pad" #define S_zoom_color "zoom-color" #define S_zoom_focus_active "zoom-focus-active" #define S_zoom_focus_left "zoom-focus-left" #define S_zoom_focus_middle "zoom-focus-middle" #define S_zoom_focus_right "zoom-focus-right" #define S_zoom_focus_style "zoom-focus-style" #if HAVE_SCHEME #define S_channel_to_vct "channel->float-vector" #define S_mix_vct "mix-float-vector" #define S_region_to_vct "region->float-vector" #define S_transform_to_vct "transform->float-vector" #define S_vct_to_channel "float-vector->channel" #else #define S_channel_to_vct "channel->vct" #define S_mix_vct "mix-vct" #define S_region_to_vct "region->vct" #define S_transform_to_vct "transform->vct" #define S_vct_to_channel "vct->channel" #endif #endif snd-16.1/snd-motif.c0000644000076400007640000411065512611215776012423 0ustar bilbil#include "snd.h" #include #if __GNUC__ #ifdef LESSTIF_VERSION /* moved the warning here so it only is displayed once */ #warning You appear to be using Lesstif: this is not recommended! Expect bugs... #endif #if (XmVERSION == 1) #warning Motif 1 is no longer supported -- this has little chance of working... #endif #endif static XmRenderTable get_xm_font(XFontStruct *ignore, const char *font, const char *tag) { XmRendition tmp; XmRenderTable tabl; int n; Arg args[12]; n = 0; XtSetArg(args[n], XmNfontName, font); n++; XtSetArg(args[n], XmNfontType, XmFONT_IS_FONT); n++; XtSetArg(args[n], XmNloadModel, XmLOAD_IMMEDIATE); n++; tmp = XmRenditionCreate(MAIN_SHELL(ss), (char *)tag, args, n); tabl = XmRenderTableAddRenditions(NULL, &tmp, 1, XmMERGE_NEW); /* XmRenditionFree(tmp); */ /* valgrind thinks this is a bad idea */ return(tabl); } /* to see all fonts: (format #f "~{~A~%~}" (XListFonts (XtDisplay (cadr (main-widgets))) "*" 10000)) */ bool set_tiny_font(const char *font) { XFontStruct *fs = NULL; fs = XLoadQueryFont(MAIN_DISPLAY(ss), font); if (fs) { /* it's not clear to me whether this is safe -- what if two fontstructs are pointing to the same font? */ if (TINY_FONT(ss)) XFreeFont(MAIN_DISPLAY(ss), TINY_FONT(ss)); if (tiny_font(ss)) free(tiny_font(ss)); in_set_tiny_font(mus_strdup(font)); TINY_FONT(ss) = fs; if (ss->tiny_fontlist) XM_FONT_FREE(ss->tiny_fontlist); ss->tiny_fontlist = get_xm_font(TINY_FONT(ss), font, "tiny_font"); return(true); } return(false); } bool set_listener_font(const char *font) { XFontStruct *fs = NULL; fs = XLoadQueryFont(MAIN_DISPLAY(ss), font); if (fs) { if (LISTENER_FONT(ss)) XFreeFont(MAIN_DISPLAY(ss), LISTENER_FONT(ss)); if (listener_font(ss)) free(listener_font(ss)); in_set_listener_font(mus_strdup(font)); LISTENER_FONT(ss) = fs; if (ss->listener_fontlist) XM_FONT_FREE(ss->listener_fontlist); ss->listener_fontlist = get_xm_font(LISTENER_FONT(ss), font, "listener_font"); set_listener_text_font(); return(true); } return(false); } bool set_peaks_font(const char *font) { XFontStruct *fs = NULL; fs = XLoadQueryFont(MAIN_DISPLAY(ss), font); if (fs) { if (PEAKS_FONT(ss)) XFreeFont(MAIN_DISPLAY(ss), PEAKS_FONT(ss)); if (peaks_font(ss)) free(peaks_font(ss)); in_set_peaks_font(mus_strdup(font)); PEAKS_FONT(ss) = fs; if (ss->peaks_fontlist) XM_FONT_FREE(ss->peaks_fontlist); ss->peaks_fontlist = get_xm_font(PEAKS_FONT(ss), font, "peaks_font"); return(true); } return(false); } bool set_bold_peaks_font(const char *font) { XFontStruct *fs = NULL; fs = XLoadQueryFont(MAIN_DISPLAY(ss), font); if (fs) { if (BOLD_PEAKS_FONT(ss)) XFreeFont(MAIN_DISPLAY(ss), BOLD_PEAKS_FONT(ss)); if (bold_peaks_font(ss)) free(bold_peaks_font(ss)); in_set_bold_peaks_font(mus_strdup(font)); BOLD_PEAKS_FONT(ss) = fs; if (ss->bold_peaks_fontlist) XM_FONT_FREE(ss->bold_peaks_fontlist); ss->bold_peaks_fontlist = get_xm_font(BOLD_PEAKS_FONT(ss), font, "bold_peaks_font"); return(true); } return(false); } bool set_axis_label_font(const char *font) { XFontStruct *fs = NULL; fs = XLoadQueryFont(MAIN_DISPLAY(ss), font); if (fs) { if (AXIS_LABEL_FONT(ss)) XFreeFont(MAIN_DISPLAY(ss), AXIS_LABEL_FONT(ss)); if (axis_label_font(ss)) free(axis_label_font(ss)); in_set_axis_label_font(mus_strdup(font)); AXIS_LABEL_FONT(ss) = fs; #if HAVE_GL reload_label_font(); #endif return(true); } return(false); } bool set_axis_numbers_font(const char *font) { XFontStruct *fs = NULL; fs = XLoadQueryFont(MAIN_DISPLAY(ss), font); if (fs) { if (AXIS_NUMBERS_FONT(ss)) XFreeFont(MAIN_DISPLAY(ss), AXIS_NUMBERS_FONT(ss)); if (axis_numbers_font(ss)) free(axis_numbers_font(ss)); in_set_axis_numbers_font(mus_strdup(font)); AXIS_NUMBERS_FONT(ss) = fs; #if HAVE_GL reload_number_font(); #endif return(true); } return(false); } int mark_name_width(const char *txt) { if (txt) return(XTextWidth(PEAKS_FONT(ss), txt, strlen(txt))); return(0); } int label_width(const char *txt, bool use_tiny_font) { if (txt) return(XTextWidth((use_tiny_font) ? TINY_FONT(ss) : AXIS_LABEL_FONT(ss), txt, strlen(txt))); else return(0); } int number_width(const char *num, bool use_tiny_font) { if (num) return(XTextWidth((use_tiny_font) ? TINY_FONT(ss) : AXIS_NUMBERS_FONT(ss), num, strlen(num))); return(0); } int number_height(XFontStruct *numbers_font) { return(numbers_font->ascent); } int label_height(bool use_tiny_font) { XFontStruct *label_font; if (use_tiny_font) label_font = TINY_FONT(ss); else label_font = AXIS_LABEL_FONT(ss); return(label_font->ascent + label_font->descent); } void clear_window(graphics_context *ax) { if ((ax) && (ax->dp) && (ax->wn)) XClearWindow(ax->dp, ax->wn); } static void map_over_children(Widget w, void (*func)(Widget uw)) { /* apply func to each child in entire tree beneath top widget */ /* taken from Douglas Young, "Motif Debugging and Performance Tuning" Prentice-Hall 1995 */ /* used mostly to get colors right in environments with "convenience" widgets */ if (w) { unsigned int i; (*func)(w); if (XtIsComposite(w)) { CompositeWidget cw = (CompositeWidget)w; for (i = 0; i < cw->composite.num_children; i++) map_over_children(cw->composite.children[i], func); } if (XtIsWidget(w)) for (i = 0; i < w->core.num_popups; i++) map_over_children(w->core.popup_list[i], func); } } void map_over_children_with_color(Widget w, void (*func)(Widget uw, color_t color), color_t color) { if (w) { unsigned int i; (*func)(w, color); if (XtIsComposite(w)) { CompositeWidget cw = (CompositeWidget)w; for (i = 0; i < cw->composite.num_children; i++) map_over_children_with_color(cw->composite.children[i], func, color); } if (XtIsWidget(w)) for (i = 0; i < w->core.num_popups; i++) map_over_children_with_color(w->core.popup_list[i], func, color); } } static void raise_dialog(Widget w) { /* since we're using non-transient message dialogs, the dialog window can become completely * hidden behind other windows, with no easy way to raise it back to the top, so... */ if ((w) && (XtIsManaged(w))) { Widget parent; parent = XtParent(w); if ((parent) && (XtIsSubclass(parent, xmDialogShellWidgetClass))) XtPopup(parent, XtGrabNone); /* XtGrabNone means don't lock out events to rest of App (i.e. modeless dialog) */ } } static void set_main_color_of_widget(Widget w) { if (XtIsWidget(w)) { if (XmIsScrollBar(w)) XmChangeColor(w, (Pixel)ss->position_color); else { Pixel cur_color; XtVaGetValues(w, XmNbackground, &cur_color, NULL); if ((cur_color != ss->highlight_color) && (cur_color != ss->white)) XmChangeColor(w, (Pixel)ss->basic_color); } } } void set_label(Widget label, const char *str) { XmString s1; s1 = XmStringCreateLocalized((char *)str); XtVaSetValues(label, XmNlabelString, s1, NULL); XmStringFree(s1); } static char *get_label(Widget label) { char *text; XmString str = NULL; XtVaGetValues(label, XmNlabelString, &str, NULL); if (XmStringEmpty(str)) return(NULL); text = (char *)XmStringUnparse(str, NULL, XmCHARSET_TEXT, XmCHARSET_TEXT, NULL, 0, XmOUTPUT_ALL); XmStringFree(str); return(text); } void set_button_label(Widget label, const char *str) { set_label(label, str); } void set_title(const char *title) { XtVaSetValues(MAIN_SHELL(ss), XmNtitle, (char *)title, NULL); } void goto_window(Widget text) { if (XmIsTraversable(text)) XmProcessTraversal(text, XmTRAVERSE_CURRENT); } static XtCallbackList make_callback_list(XtCallbackProc callback, XtPointer closure) { XtCallbackList nlist; nlist = (XtCallbackList)calloc(2, sizeof(XtCallbackRec)); nlist[0].callback = callback; nlist[0].closure = closure; nlist[1].callback = NULL; nlist[1].closure = NULL; return(nlist); } #include static void color_sashes(Widget w) { if ((XtIsWidget(w)) && (XtIsSubclass(w, xmSashWidgetClass))) XmChangeColor(w, (Pixel)ss->sash_color); } void check_for_event(void) { /* this is needed to force label updates and provide interrupts from long computations */ XEvent event; XtInputMask msk = 0; XtAppContext app; if (ss->checking_explicitly) return; ss->checking_explicitly = true; app = MAIN_APP(ss); while (true) { msk = XtAppPending(app); /* if (msk & (XtIMXEvent | XtIMAlternateInput)) */ if (msk & XtIMXEvent) /* was also tracking alternate input events, but these are problematic if libfam is in use (even with check) */ { XtAppNextEvent(app, &event); XtDispatchEvent(&event); /* widget = XtWindowToWidget(event.xany.display, event.xany.window); */ } else break; } ss->checking_explicitly = false; } void color_cursor(Pixel color) { ss->cursor_color = color; #if HAVE_SCHEME s7_symbol_set_value(s7, ss->cursor_color_symbol, Xen_wrap_pixel(color)); #endif XSetForeground(MAIN_DISPLAY(ss), ss->cursor_gc, (Pixel)(XOR(color, ss->graph_color))); XSetForeground(MAIN_DISPLAY(ss), ss->selected_cursor_gc, (Pixel)(XOR(color, ss->selected_graph_color))); } void color_marks(Pixel color) { ss->mark_color = color; #if HAVE_SCHEME s7_symbol_set_value(s7, ss->mark_color_symbol, Xen_wrap_pixel(color)); #endif XSetForeground(MAIN_DISPLAY(ss), ss->mark_gc, (Pixel)(XOR(color, ss->graph_color))); XSetForeground(MAIN_DISPLAY(ss), ss->selected_mark_gc, (Pixel)(XOR(color, ss->selected_graph_color))); } void color_selection(Pixel color) { ss->selection_color = color; #if HAVE_SCHEME s7_symbol_set_value(s7, ss->selection_color_symbol, Xen_wrap_pixel(color)); #endif XSetForeground(MAIN_DISPLAY(ss), ss->selection_gc, (Pixel)(XOR(color, ss->graph_color))); XSetForeground(MAIN_DISPLAY(ss), ss->selected_selection_gc, (Pixel)(XOR(color, ss->selected_graph_color))); } void color_graph(Pixel color) { Display *dpy; dpy = MAIN_DISPLAY(ss); XSetBackground(dpy, ss->basic_gc, color); XSetForeground(dpy, ss->erase_gc, color); XSetForeground(dpy, ss->selection_gc, (Pixel)(XOR(ss->selection_color, color))); XSetForeground(dpy, ss->cursor_gc, (Pixel)(XOR(ss->cursor_color, color))); XSetForeground(dpy, ss->mark_gc, (Pixel)(XOR(ss->mark_color, color))); } void color_selected_graph(Pixel color) { Display *dpy; dpy = MAIN_DISPLAY(ss); XSetBackground(dpy, ss->selected_basic_gc, color); XSetForeground(dpy, ss->selected_erase_gc, color); XSetForeground(dpy, ss->selected_selection_gc, (Pixel)(XOR(ss->selection_color, color))); XSetForeground(dpy, ss->selected_cursor_gc, (Pixel)(XOR(ss->cursor_color, color))); XSetForeground(dpy, ss->selected_mark_gc, (Pixel)(XOR(ss->mark_color, color))); } void color_data(Pixel color) { Display *dpy; dpy = MAIN_DISPLAY(ss); XSetForeground(dpy, ss->basic_gc, color); XSetBackground(dpy, ss->erase_gc, color); } void color_selected_data(Pixel color) { Display *dpy; dpy = MAIN_DISPLAY(ss); XSetForeground(dpy, ss->selected_basic_gc, color); XSetBackground(dpy, ss->selected_erase_gc, color); } void recolor_graph(chan_info *cp, bool selected) { XtVaSetValues(channel_graph(cp), XmNbackground, (selected) ? ss->selected_graph_color : ss->graph_color, NULL); } void set_mix_color(Pixel color) { Display *dpy; dpy = MAIN_DISPLAY(ss); ss->mix_color = color; #if HAVE_SCHEME s7_symbol_set_value(s7, ss->mix_color_symbol, Xen_wrap_pixel(color)); #endif XSetForeground(dpy, ss->mix_gc, color); } void set_sensitive(Widget wid, bool val) { if (wid) XtSetSensitive(wid, val); } void set_toggle_button(Widget wid, bool val, bool passed, void *ignore) { XmToggleButtonSetState(wid, (Boolean)val, (Boolean)passed); } Dimension widget_height(Widget w) { Dimension height; XtVaGetValues(w, XmNheight, &height, NULL); return(height); } Dimension widget_width(Widget w) { Dimension width; XtVaGetValues(w, XmNwidth, &width, NULL); return(width); } void set_widget_height(Widget w, Dimension height) { XtVaSetValues(w, XmNheight, height, NULL); } void set_widget_width(Widget w, Dimension width) { XtVaSetValues(w, XmNwidth, width, NULL); } void set_widget_size(Widget w, Dimension width, Dimension height) { XtVaSetValues(w, XmNwidth, width, XmNheight, height, NULL); } Position widget_x(Widget w) { Position x; XtVaGetValues(w, XmNx, &x, NULL); return(x); } Position widget_y(Widget w) { Position y; XtVaGetValues(w, XmNy, &y, NULL); return(y); } void set_widget_x(Widget w, Position x) { XtVaSetValues(w, XmNx, x, NULL); } void set_widget_y(Widget w, Position y) { XtVaSetValues(w, XmNy, y, NULL); } void set_widget_position(Widget w, Position x, Position y) { XtVaSetValues(w, XmNx, x, XmNy, y, NULL); } idle_t add_work_proc(XtWorkProc func, XtPointer data) { /* during auto-testing I need to force the background procs to run to completion */ if (with_background_processes(ss)) return(XtAppAddWorkProc(MAIN_APP(ss), func, data)); else { while (((*func)(data)) == BACKGROUND_CONTINUE) ; return((idle_t)0); } } static int attach_all_sides(Arg *args, int n) { XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; return(n); } static void widget_int_to_text(Widget w, int val) { char *str; str = (char *)calloc(8, sizeof(char)); snprintf(str, 8, "%d", val); XmTextFieldSetString(w, str); free(str); } static void widget_mus_long_t_to_text(Widget w, mus_long_t val) { char *str; str = (char *)calloc(32, sizeof(char)); snprintf(str, 32, "%lld", val); XmTextFieldSetString(w, str); free(str); } static Pixmap rotate_text(Widget w, const char *str, XFontStruct *font, mus_float_t angle_in_degrees, int *nw, int *nh, Pixel bg, Pixel fg, GC d_gc) { /* rotate clockwise by angle_in_degrees degrees (i.e. 45 points text south-east), * new bounding box (text centered in it) returned in nw and nh * bg = background color, fg = foreground (text) color) */ mus_float_t matrix[4]; mus_float_t angle_in_radians; XImage *before, *after; Pixmap pix, rotpix; unsigned int width, height, depth, nwidth, nheight, x, y, nx, ny, tx, ty, depth_bytes; char *data; unsigned long px; Display *dp; Drawable wn; Visual *vis; int scr; int bx0 = 0, bx1 = 0, by0 = 0, by1 = 0, b; if (str == NULL) return(BadPixmap); angle_in_radians = mus_degrees_to_radians(angle_in_degrees); matrix[0] = cos(angle_in_radians); matrix[1] = sin(angle_in_radians); matrix[2] = -sin(angle_in_radians); matrix[3] = cos(angle_in_radians); dp = XtDisplay(w); wn = XtWindow(w); scr = DefaultScreen(dp); vis = DefaultVisual(dp, scr); XtVaGetValues(w, XmNdepth, &depth, NULL); depth_bytes = (depth >> 3); if (depth_bytes == 0) depth_bytes = 1; /* unsigned so can't be negative */ /* find extent of original text, expand out to byte boundaries */ XSetFont(dp, d_gc, font->fid); width = XTextWidth(font, str, strlen(str)) + 8; height = (font->ascent + font->descent) + 8; if (width % 8) width = 8 * (1 + (int)(width / 8)); if (height % 8) height = 8 * (1 + (int)(height / 8)); /* get bounding box of rotated text (this could be simplfied -- used to involve scaling) */ b = (int)(width * matrix[0]); if (b < 0) bx0 = b; else bx1 = b; b = (int)(height * matrix[2]); if (b < 0) bx0 += b; else bx1 += b; b = (int)(width * matrix[1]); if (b < 0) by0 = b; else by1 = b; b = (int)(height * matrix[3]); if (b < 0) by0 += b; else by1 += b; /* set translation vector so we're centered in the resultant pixmap */ if (bx0 < 0) tx = -bx0; else tx = 0; if (by0 < 0) ty = -by0; else ty = 0; nx = bx1 - bx0; ny = by1 - by0; /* expand result bounds to byte boundaries */ if (nx % 8) nwidth = 8 * (1 + (int)(nx / 8)); else nwidth = nx; if (ny % 8) nheight = 8 * (1 + (int)(ny / 8)); else nheight = ny; (*nw) = nwidth; (*nh) = nheight; XSetBackground(dp, d_gc, bg); XSetForeground(dp, d_gc, bg); /* create pixmaps, fill with background color, write string to pix */ pix = XCreatePixmap(dp, wn, width, height, depth); rotpix= XCreatePixmap(dp, wn, nwidth, nheight, depth); XFillRectangle(dp, pix, d_gc, 0, 0, width, height); XFillRectangle(dp, rotpix, d_gc, 0, 0, nwidth, nheight); #if HAVE_SUN XSync(dp, 0); /* needed to get the numbers drawn at all */ #endif XSetForeground(dp, d_gc, fg); XDrawImageString(dp, pix, d_gc, 4, height - 4, str, strlen(str)); /* dump pixmap bits into an image; image data will be freed automatically later */ data = (char *)calloc((width + 1) * (height + 1) * depth_bytes, sizeof(char)); /* not calloc since X will free this */ before = XCreateImage(dp, vis, depth, XYPixmap, 0, data, width, height, 8, 0); XGetSubImage(dp, pix, 0, 0, width, height, AllPlanes, XYPixmap, before, 0, 0); data = (char *)calloc((nwidth + 1) * (nheight + 1) * depth_bytes, sizeof(char)); after = XCreateImage(dp, vis, depth, XYPixmap, 0, data, nwidth, nheight, 8, 0); /* clear background of result image */ for (x = 0; x < nwidth; x++) for (y = 0; y < nheight; y++) XPutPixel(after, x, y, bg); /* write rotated pixels to result image */ for (x = 0; x < width; x++) for (y = 0; y < height; y++) { px = XGetPixel(before, x, y); if (px != bg) XPutPixel(after, mus_iclamp(0, (int)snd_round(tx + x * matrix[0] + y * matrix[2]), nwidth - 1), mus_iclamp(0, (int)snd_round(ty + x * matrix[1] + y * matrix[3]), nheight - 1), px); } /* dump image into result pixmap (needed for later display) */ XPutImage(dp, rotpix, d_gc, after, 0, 0, 0, 0, nwidth, nheight); /* cleanup */ XDestroyImage(before); /* frees data as well */ XDestroyImage(after); XFreePixmap(dp, pix); return(rotpix); } void draw_rotated_axis_label(chan_info *cp, graphics_context *ax, const char *text, int x0, int y0) { Pixmap pix; int h = 0, w = 0; XGCValues gv; Display *dp; Widget widget; if ((cp->chan > 0) && (cp->sound->channel_style == CHANNELS_COMBINED)) widget = channel_graph(cp->sound->chans[0]); else widget = channel_graph(cp); dp = XtDisplay(widget); XGetGCValues(MAIN_DISPLAY(ss), ax->gc, GCForeground | GCBackground, &gv); pix = rotate_text(widget, text, AXIS_LABEL_FONT(ss), -90.0, &w, &h, gv.background, gv.foreground, ax->gc); XCopyArea(dp, pix, XtWindow(widget), ax->gc, 0, 0, w, h, x0, y0); /* XtWindow?? */ XFreePixmap(dp, pix); } static void ensure_list_row_visible(widget_t list, int pos) { if (pos >= 0) { int top, visible, num_rows; XtVaGetValues(list, XmNtopItemPosition, &top, XmNvisibleItemCount, &visible, XmNitemCount, &num_rows, NULL); if (pos <= top) XmListSetPos(list, pos); /* was pos+1?? (new file dialog sample type list off by 1 in that case) */ else { if (pos >= (top + visible)) { if ((pos + visible) > num_rows) XmListSetBottomPos(list, num_rows); else XmListSetPos(list, pos); } } } } static void ensure_scrolled_window_row_visible(widget_t list, int row, int num_rows) { int minimum, maximum, value, size, new_value, increment, page_increment; Widget scrollbar, work_window; XtVaGetValues(list, XmNverticalScrollBar, &scrollbar, XmNworkWindow, &work_window, NULL); XtVaGetValues(scrollbar, XmNminimum, &minimum, XmNmaximum, &maximum, XmNvalue, &value, XmNsliderSize, &size, XmNincrement, &increment, /* needed for XmScrollBarSetValues which is needed to force list display update */ XmNpageIncrement, &page_increment, NULL); maximum -= size; if (row == 0) new_value = 0; else { if (row >= (num_rows - 1)) new_value = maximum; else new_value = (int)((row + 0.5) * ((float)(maximum - minimum) / (float)(num_rows - 1))); } XmScrollBarSetValues(scrollbar, new_value, size, increment, page_increment, true); } static XmString multi_line_label(const char *s, int *lines) { /* taken from the Motif FAQ */ XmString xms1, xms2, line, separator; char *p, *tmp; (*lines) = 1; tmp = mus_strdup(s); separator = XmStringSeparatorCreate(); p = strtok(tmp, "\n"); xms1 = XmStringCreateLocalized(p); p = strtok(NULL, "\n"); while (p) { (*lines)++; line = XmStringCreateLocalized(p); xms2 = XmStringConcat(xms1, separator); XmStringFree(xms1); xms1 = XmStringConcat(xms2, line); XmStringFree(xms2); XmStringFree(line); p = strtok(NULL, "\n"); } XmStringFree(separator); free(tmp); return(xms1); } #include /* needed to set the scale title background */ void draw_line(graphics_context *ax, int x0, int y0, int x1, int y1) { XDrawLine(ax->dp, ax->wn, ax->gc, x0, y0, x1, y1); } void fill_rectangle(graphics_context *ax, int x0, int y0, int width, int height) { XFillRectangle(ax->dp, ax->wn, ax->gc, x0, y0, width, height); } void erase_rectangle(chan_info *cp, graphics_context *ax, int x0, int y0, int width, int height) { XFillRectangle(ax->dp, ax->wn, erase_GC(cp), x0, y0, width, height); } void draw_string(graphics_context *ax, int x0, int y0, const char *str, int len) { if ((str) && (*str)) XDrawString(ax->dp, ax->wn, ax->gc, x0, y0, str, len); } void gtk_style_draw_string(graphics_context *ax, int x0, int y0, const char *str, int len) { /* for callers of Scheme-level draw-string, the Motif and Gtk versions should agree on where "y0" is */ XGCValues gv; static XFontStruct *fs = NULL; XGetGCValues(MAIN_DISPLAY(ss), ax->gc, GCFont, &gv); /* now gv.font is the default font */ if (fs) XFree(fs); /* this doesn't free all the space */ /* but this: */ /* if (fs) XFreeFont(MAIN_DISPLAY(ss), fs); */ /* gets: X Error of failed request: BadFont (invalid Font parameter) Major opcode of failed request: 56 (X_ChangeGC) Resource id in failed request: 0x4e0035c Serial number of failed request: 8479111 Current serial number in output stream: 8479240 */ fs = XQueryFont(MAIN_DISPLAY(ss), gv.font); if (fs) XDrawString(ax->dp, ax->wn, ax->gc, x0, y0 + fs->ascent, str, len); else XDrawString(ax->dp, ax->wn, ax->gc, x0, y0, str, len); /* not sure why this happens... */ /* XFreeFont here is trouble, but handling it as above seems ok -- Font.c in xlib does allocate new space */ } static void draw_polygon_va(graphics_context *ax, bool filled, int points, va_list ap) { int i; XPoint *pts; pts = (XPoint *)calloc(points, sizeof(XPoint)); for (i = 0; i < points; i++) { pts[i].x = va_arg(ap, int); pts[i].y = va_arg(ap, int); } if (filled) XFillPolygon(ax->dp, ax->wn, ax->gc, pts, points, Convex, CoordModeOrigin); else XDrawLines(ax->dp, ax->wn, ax->gc, pts, points, CoordModeOrigin); free(pts); } void fill_polygon(graphics_context *ax, int points, ...) { /* currently used only in snd-marks.c */ va_list ap; if (points == 0) return; va_start(ap, points); draw_polygon_va(ax, true, points, ap); va_end(ap); } #if 0 void draw_polygon(graphics_context *ax, int points, ...) { va_list ap; if (points == 0) return; va_start(ap, points); draw_polygon_va(ax, false, points, ap); va_end(ap); } #endif void draw_lines(graphics_context *ax, point_t *points, int num) { if (num == 0) return; XDrawLines(ax->dp, ax->wn, ax->gc, points, num, CoordModeOrigin); } void draw_points(graphics_context *ax, point_t *points, int num, int size) { if (num == 0) return; if (size == 1) XDrawPoints(ax->dp, ax->wn, ax->gc, points, num, CoordModeOrigin); else { int i, size2; XArc *rs; /* create squares or whatever centered on each point */ size2 = size / 2; rs = (XArc *)calloc(num, sizeof(XArc)); for (i = 0; i < num; i++) { rs[i].x = points[i].x - size2; rs[i].y = points[i].y - size2; rs[i].angle1 = 0; rs[i].angle2 = 360 * 64; rs[i].width = size; rs[i].height = size; } XFillArcs(ax->dp, ax->wn, ax->gc, rs, num); free(rs); } } #if 0 void draw_point(graphics_context *ax, point_t point, int size) { if (size == 1) XDrawPoint(ax->dp, ax->wn, ax->gc, point.x, point.y); else XFillArc(ax->dp, ax->wn, ax->gc, point.x - size / 2, point.y - size / 2, size, size, 0, 360 * 64); } #endif void draw_dot(graphics_context *ax, int x, int y, int size) { XFillArc(ax->dp, ax->wn, ax->gc, x - size / 2, y - size / 2, size, size, 0, 360 * 64); } void fill_polygons(graphics_context *ax, point_t *points, int num, int y0) { XPoint polypts[4]; int i; for (i = 1; i < num; i++) { polypts[0].x = points[i - 1].x; polypts[0].y = points[i - 1].y; polypts[1].x = points[i].x; polypts[1].y = points[i].y; polypts[2].x = polypts[1].x; polypts[2].y = y0; polypts[3].x = points[i - 1].x; polypts[3].y = y0; XFillPolygon(ax->dp, ax->wn, ax->gc, polypts, 4, Convex, CoordModeOrigin); } } void fill_two_sided_polygons(graphics_context *ax, point_t *points, point_t *points1, int num) { XPoint polypts[4]; int i; for (i = 1; i < num; i++) { polypts[0].x = points[i - 1].x; polypts[0].y = points[i - 1].y; polypts[1].x = points[i].x; polypts[1].y = points[i].y; polypts[2].x = points1[i].x; polypts[2].y = points1[i].y; polypts[3].x = points1[i - 1].x; polypts[3].y = points1[i - 1].y; XFillPolygon(ax->dp, ax->wn, ax->gc, polypts, 4, Convex, CoordModeOrigin); } } void setup_graphics_context(chan_info *cp, graphics_context *ax) { Widget w; w = channel_to_widget(cp); ax->dp = XtDisplay(w); ax->gc = copy_GC(cp); ax->wn = XtWindow(w); } /* colormaps */ static int sono_bins = 0; /* tracks total_bins -- each sono_data[i] is an array of total_bins rectangles */ static Pixel *current_colors = NULL; static int current_colors_size = 0; static int current_colormap = BLACK_AND_WHITE_COLORMAP; static XRectangle **sono_data = NULL; /* each entry in sono_data is an array of colormap_size arrays: sono_data[colormap_size][total_bins] */ static int sono_colors = 0; /* tracks colormap_size */ static GC colormap_GC; void check_colormap_sizes(int colors) { int i, old_size; if (current_colors_size > 0) { if (current_colormap != BLACK_AND_WHITE_COLORMAP) { int scr; Colormap cmap; Display *dpy; dpy = XtDisplay(MAIN_SHELL(ss)); scr = DefaultScreen(dpy); cmap = DefaultColormap(dpy, scr); XFreeColors(dpy, cmap, current_colors, current_colors_size, 0); current_colormap = BLACK_AND_WHITE_COLORMAP; } if ((current_colors) && (current_colors_size < colors)) { old_size = current_colors_size; current_colors_size = colors; current_colors = (Pixel *)realloc(current_colors, current_colors_size * sizeof(Pixel)); for (i = old_size; i < current_colors_size; i++) current_colors[i] = 0; } } if ((sono_data) && (sono_colors < colors) && (sono_bins > 0)) { old_size = sono_colors; sono_colors = colors; sono_data = (XRectangle **)realloc(sono_data, sono_colors * sizeof(XRectangle *)); for (i = old_size; i < sono_colors; i++) sono_data[i] = (XRectangle *)calloc(sono_bins, sizeof(XRectangle)); } } static void initialize_colormap(void) { XGCValues gv; gv.background = ss->white; gv.foreground = ss->data_color; colormap_GC = XCreateGC(MAIN_DISPLAY(ss), XtWindow(MAIN_SHELL(ss)), GCForeground | GCBackground, &gv); sono_colors = color_map_size(ss); sono_data = (XRectangle **)calloc(sono_colors, sizeof(XRectangle *)); current_colors_size = color_map_size(ss); current_colors = (Pixel *)calloc(current_colors_size, sizeof(Pixel)); } void draw_spectro_line(graphics_context *ax, int color, int x0, int y0, int x1, int y1) { XSetForeground(ax->dp, colormap_GC, current_colors[color]); XDrawLine(ax->dp, ax->wn, colormap_GC, x0, y0, x1, y1); } void draw_sono_rectangles(graphics_context *ax, int color, int jmax) { XSetForeground(ax->dp, colormap_GC, current_colors[color]); XFillRectangles(ax->dp, ax->wn, colormap_GC, sono_data[color], jmax); } void set_sono_rectangle(int j, int color, int x, int y, int width, int height) { XRectangle *r; r = sono_data[color]; r[j].x = x; r[j].y = y; r[j].width = width; r[j].height = height; } void allocate_sono_rects(int bins) { if (bins != sono_bins) { int i; for (i = 0; i < sono_colors; i++) { if ((sono_bins > 0) && (sono_data[i])) free(sono_data[i]); /* each is array of XRectangle structs, but it's the wrong size */ sono_data[i] = (XRectangle *)calloc(bins, sizeof(XRectangle)); } sono_bins = bins; } } void allocate_color_map(int colormap) { static bool warned_color = false; if (current_colormap != colormap) { int i; Colormap cmap; XColor tmp_color; Display *dpy; int scr; tmp_color.flags = DoRed | DoGreen | DoBlue; dpy = XtDisplay(MAIN_SHELL(ss)); scr = DefaultScreen(dpy); cmap = DefaultColormap(dpy, scr); /* 8-bit color displays can't handle all these colors, apparently, so we have to check status */ if (current_colormap != BLACK_AND_WHITE_COLORMAP) XFreeColors(dpy, cmap, current_colors, current_colors_size, 0); for (i = 0; i < current_colors_size; i++) { get_current_color(colormap, i, &(tmp_color.red), &(tmp_color.green), &(tmp_color.blue)); if ((XAllocColor(dpy, cmap, &tmp_color)) == 0) /* 0 = failure -- try black as a fallback */ { tmp_color.red = 0; tmp_color.green = 0; tmp_color.blue = 0; if ((XAllocColor(dpy, cmap, &tmp_color)) == 0) { if (!warned_color) snd_error_without_format("can't even allocate black?!?"); warned_color = true; } } current_colors[i] = tmp_color.pixel; } current_colormap = colormap; } } void draw_colored_lines(chan_info *cp, graphics_context *ax, point_t *points, int num, int *colors, int axis_y0, color_t default_color) { int i, x0, y0, y2 = 0, y00 = -1, cur, prev; color_t old_color; if (num <= 0) return; old_color = get_foreground_color(ax); x0 = points[0].x; y0 = points[0].y; if (abs(y0 - axis_y0) < 5) prev = -1; else prev = colors[0]; set_foreground_color(ax, (prev == -1) ? default_color : current_colors[prev]); for (i = 1; i < num; i++) { int x1, y1; x1 = points[i].x; y1 = points[i].y; if (i < num - 1) y2 = points[i + 1].y; else y2 = y1; if ((abs(y0 - axis_y0) < 5) && (abs(y1 - axis_y0) < 5)) cur = -1; else { if ((y00 > y0) && (y00 > y1) && (i > 1)) cur = colors[i - 2]; else { if ((y2 > y1) && (y2 > y0)) cur = colors[i + 1]; else { if (y0 > y1) cur = colors[i]; else cur = colors[i - 1]; /* coords are upside down */ } } } if (cur != prev) { set_foreground_color(ax, (cur == -1) ? default_color : current_colors[cur]); prev = cur; } if (cp->transform_graph_style == GRAPH_DOTS) draw_dot(ax, x0, y0, cp->dot_size); else draw_line(ax, x0, y0, x1, y1); y00 = y0; x0 = x1; y0 = y1; } set_foreground_color(ax, old_color); } /* -------- color/orientation browser -------- */ static Xen color_hook; static void check_color_hook(void) { if (Xen_hook_has_list(color_hook)) run_hook(color_hook, Xen_empty_list, S_color_hook); } static Widget ccd_dialog = NULL, ccd_list, ccd_scale, ccd_invert, ccd_cutoff; static void update_graph_setting_fft_changed(chan_info *cp) { cp->fft_changed = FFT_CHANGE_LOCKED; update_graph(cp); } static void invert_color_callback(Widget w, XtPointer context, XtPointer info) { XmToggleButtonCallbackStruct *cb = (XmToggleButtonCallbackStruct *)info; in_set_color_inverted(cb->set); check_color_hook(); for_each_chan(update_graph_setting_fft_changed); } void set_color_inverted(bool val) { in_set_color_inverted(val); if (ccd_dialog) XmToggleButtonSetState(ccd_invert, (Boolean)val, false); check_color_hook(); if (!(ss->graph_hook_active)) for_each_chan(update_graph_setting_fft_changed); } static void scale_color_callback(Widget w, XtPointer context, XtPointer info) { mus_float_t val; int scale_val; XmScaleCallbackStruct *cbs = (XmScaleCallbackStruct *)info; scale_val = cbs->value; if (scale_val <= 50) val = (mus_float_t)(scale_val + 1) / 51.0; else val = 1.0 + (mus_float_t)((scale_val - 50) * (scale_val - 50)) / 12.5; in_set_color_scale(val); check_color_hook(); for_each_chan(update_graph_setting_fft_changed); } static void reflect_color_scale(mus_float_t val) { if (val < 0.02) XmScaleSetValue(ccd_scale, 0); else { if (val <= 1.0) XmScaleSetValue(ccd_scale, mus_iclamp(0, (int)(val * 51.0 - 1), 100)); else XmScaleSetValue(ccd_scale, mus_iclamp(0, 50 + (int)sqrt((val - 1.0) * 12.5), 100)); } } void set_color_scale(mus_float_t val) { in_set_color_scale(val); if (ccd_dialog) reflect_color_scale(color_scale(ss)); if (!(ss->graph_hook_active)) for_each_chan(update_graph_setting_fft_changed); } static void list_color_callback(Widget w, XtPointer context, XtPointer info) { XmListCallbackStruct *cbs = (XmListCallbackStruct *)info; if (is_colormap(cbs->item_position - 1)) { in_set_color_map(cbs->item_position - 1); check_color_hook(); for_each_chan(update_graph_setting_fft_changed); } } void set_color_map(int val) { in_set_color_map(val); if ((ccd_dialog) && (val >= 0)) XmListSelectPos(ccd_list, val + 1, false); check_color_hook(); if (!(ss->graph_hook_active)) for_each_chan(update_graph_setting_fft_changed); } static XmString fscale_label(const char *orig_label, mus_float_t value) { XmString x; char *lab; lab = mus_format("%s: %.3f", orig_label, value); x = XmStringCreateLocalized(lab); free(lab); return(x); } static void fscale_set_label(const char *orig_label, Widget w, mus_float_t value) { XmString x; char *lab; lab = mus_format("%s: %.3f", orig_label, value); x = XmStringCreateLocalized(lab); XtVaSetValues(w, XmNtitleString, x, NULL); free(lab); XmStringFree(x); } static void cutoff_color_callback(Widget w, XtPointer context, XtPointer info) /* cutoff point */ { /* cutoff point for color chooser */ XmScaleCallbackStruct *cbs = (XmScaleCallbackStruct *)info; in_set_color_cutoff((mus_float_t)(cbs->value) / 1000.0); fscale_set_label("data cutoff", w, color_cutoff(ss)); check_color_hook(); for_each_chan(update_graph_setting_fft_changed); } void set_color_cutoff(mus_float_t val) { in_set_color_cutoff(val); if (ccd_dialog) XmScaleSetValue(ccd_cutoff, (int)(val * 1000.0)); if (!(ss->graph_hook_active)) for_each_chan(update_graph_setting_fft_changed); } static void dismiss_color_orientation_callback(Widget w, XtPointer context, XtPointer info) { XtUnmanageChild(ccd_dialog); } static void help_color_orientation_callback(Widget w, XtPointer context, XtPointer info) { color_orientation_dialog_help(); } void reflect_color_list(bool setup_time) { if ((ccd_dialog) && (ccd_list)) { int i, size; XmString *cmaps; size = num_colormaps(); cmaps = (XmString *)calloc(size, sizeof(XmString)); for (i = 0; i < size; i++) cmaps[i] = XmStringCreateLocalized(colormap_name(i)); XtVaSetValues(ccd_list, XmNitems, cmaps, XmNitemCount, size, NULL); if (setup_time) XtVaSetValues(ccd_list, XmNvisibleItemCount, 6, NULL); for (i = 0; i < size; i++) XmStringFree(cmaps[i]); free(cmaps); } } static Xen orientation_hook; static void check_orientation_hook(void) { if (Xen_hook_has_list(orientation_hook)) run_hook(orientation_hook, Xen_empty_list, S_orientation_hook); } static Widget oid_ax, oid_ay, oid_az, oid_sx, oid_sy, oid_sz, oid_hop; #if HAVE_GL static Widget oid_glbutton; #endif #define HOP_MAX 20 static XmString scale_label(const char *orig_label, int value, bool dec) { XmString x; char *lab; if (!dec) lab = mus_format("%s: %d", orig_label, value); else lab = mus_format("%s: %.2f", orig_label, value * 0.01); x = XmStringCreateLocalized(lab); free(lab); return(x); } static void scale_set_label(const char *orig_label, Widget w, int value, bool dec) { /* in new motif (after version 2.1), showValue not XmNONE clobbers XmScale title! * also XmNEAR_BORDER has no effect -- same as XmNEAR_SLIDER * so... * we create the full label by hand here. */ XmString x; char *lab; if (!dec) lab = mus_format("%s: %d", orig_label, value); else lab = mus_format("%s: %.2f", orig_label, value * 0.01); x = XmStringCreateLocalized(lab); XtVaSetValues(w, XmNtitleString, x, NULL); free(lab); XmStringFree(x); } static void ax_orientation_callback(Widget w, XtPointer context, XtPointer info) { XmScaleCallbackStruct *cbs = (XmScaleCallbackStruct *)info; scale_set_label("x angle", w, cbs->value, false); in_set_spectro_x_angle((mus_float_t)(cbs->value)); chans_field(FCP_X_ANGLE, (mus_float_t)(cbs->value)); check_orientation_hook(); for_each_chan(update_graph); } void set_spectro_x_angle(mus_float_t val) { if (val < 0.0) val += 360.0; else if (val >= 360.0) val = fmod(val, 360.0); in_set_spectro_x_angle(val); if (ccd_dialog) { XmScaleSetValue(oid_ax, (int)val); scale_set_label("x angle", oid_ax, (int)val, false); } chans_field(FCP_X_ANGLE, val); check_orientation_hook(); if (!(ss->graph_hook_active)) for_each_chan(update_graph); } static void ay_orientation_callback(Widget w, XtPointer context, XtPointer info) { XmScaleCallbackStruct *cbs = (XmScaleCallbackStruct *)info; scale_set_label("y angle", w, cbs->value, false); in_set_spectro_y_angle((mus_float_t)(cbs->value)); chans_field(FCP_Y_ANGLE, (mus_float_t)(cbs->value)); check_orientation_hook(); for_each_chan(update_graph); } void set_spectro_y_angle(mus_float_t val) { if (val < 0.0) val += 360.0; else if (val >= 360.0) val = fmod(val, 360.0); in_set_spectro_y_angle(val); if (ccd_dialog) { XmScaleSetValue(oid_ay, (int)val); scale_set_label("y angle", oid_ay, (int)val, false); } chans_field(FCP_Y_ANGLE, val); check_orientation_hook(); if (!(ss->graph_hook_active)) for_each_chan(update_graph); } static void az_orientation_callback(Widget w, XtPointer context, XtPointer info) { XmScaleCallbackStruct *cbs = (XmScaleCallbackStruct *)info; scale_set_label("z angle", w, cbs->value, false); in_set_spectro_z_angle((mus_float_t)(cbs->value)); chans_field(FCP_Z_ANGLE, (mus_float_t)(cbs->value)); check_orientation_hook(); for_each_chan(update_graph); } void set_spectro_z_angle(mus_float_t val) { if (val < 0.0) val += 360.0; else if (val >= 360.0) val = fmod(val, 360.0); in_set_spectro_z_angle(val); if (ccd_dialog) { XmScaleSetValue(oid_az, (int)val); scale_set_label("z angle", oid_az, (int)val, false); } chans_field(FCP_Z_ANGLE, val); check_orientation_hook(); if (!(ss->graph_hook_active)) for_each_chan(update_graph); } static void sx_orientation_callback(Widget w, XtPointer context, XtPointer info) { XmScaleCallbackStruct *cbs = (XmScaleCallbackStruct *)info; scale_set_label("x scale", w, cbs->value, true); in_set_spectro_x_scale((mus_float_t)(cbs->value) * 0.01); chans_field(FCP_X_SCALE, (mus_float_t)(cbs->value) * 0.01); check_orientation_hook(); for_each_chan(update_graph); } void set_spectro_x_scale(mus_float_t val) { in_set_spectro_x_scale(val); if (ccd_dialog) { int value; value = mus_iclamp(0, (int)(val * 100), (int)(100 * SPECTRO_X_SCALE_MAX)); XmScaleSetValue(oid_sx, value); scale_set_label("x scale", oid_sx, value, true); } chans_field(FCP_X_SCALE, val); check_orientation_hook(); if (!(ss->graph_hook_active)) for_each_chan(update_graph); } static void sy_orientation_callback(Widget w, XtPointer context, XtPointer info) { XmScaleCallbackStruct *cbs = (XmScaleCallbackStruct *)info; scale_set_label("y scale", w, cbs->value, true); in_set_spectro_y_scale((mus_float_t)(cbs->value) * 0.01); chans_field(FCP_Y_SCALE, (mus_float_t)(cbs->value) * 0.01); check_orientation_hook(); for_each_chan(update_graph); } void set_spectro_y_scale(mus_float_t val) { in_set_spectro_y_scale(val); if (ccd_dialog) { int value; value = mus_iclamp(0, (int)(val * 100), (int)(100 * SPECTRO_Y_SCALE_MAX)); XmScaleSetValue(oid_sy, value); scale_set_label("y scale", oid_sy, value, true); } chans_field(FCP_Y_SCALE, val); check_orientation_hook(); if (!(ss->graph_hook_active)) for_each_chan(update_graph); } static void sz_orientation_callback(Widget w, XtPointer context, XtPointer info) { XmScaleCallbackStruct *cbs = (XmScaleCallbackStruct *)info; scale_set_label("z scale", w, cbs->value, true); in_set_spectro_z_scale((mus_float_t)(cbs->value) * 0.01); chans_field(FCP_Z_SCALE, (mus_float_t)(cbs->value) * 0.01); check_orientation_hook(); for_each_chan(update_graph); } void set_spectro_z_scale(mus_float_t val) { in_set_spectro_z_scale(val); if (ccd_dialog) { int value; value = mus_iclamp(0, (int)(val * 100), (int)(100 * SPECTRO_Z_SCALE_MAX)); XmScaleSetValue(oid_sz, value); scale_set_label("z scale", oid_sz, value, true); } chans_field(FCP_Z_SCALE, val); check_orientation_hook(); if (!(ss->graph_hook_active)) for_each_chan(update_graph); } static void chans_spectro_hop(chan_info *cp, int value) { cp->spectro_hop = value; } static void hop_orientation_callback(Widget w, XtPointer context, XtPointer info) { int val; XmScaleCallbackStruct *cbs = (XmScaleCallbackStruct *)info; scale_set_label("hop", w, cbs->value, false); val = mus_iclamp(1, cbs->value, HOP_MAX); in_set_spectro_hop(val); for_each_chan_with_int(chans_spectro_hop,val); check_orientation_hook(); for_each_chan(update_graph); } void set_spectro_hop(int val) { if (val > 0) { in_set_spectro_hop(val); if (ccd_dialog) { int value; value = mus_iclamp(1, val, HOP_MAX); XmScaleSetValue(oid_hop, value); scale_set_label("hop", oid_hop, value, false); } for_each_chan_with_int(chans_spectro_hop, val); check_orientation_hook(); if (!(ss->graph_hook_active)) for_each_chan(update_graph); } } static int fixup_angle(mus_float_t ang) { int na; na = (int)ang; if (na < 0) na += 360; na = na % 360; return(na); } void reflect_spectro(void) { /* set color/orientaton widget values */ if (ccd_dialog) { XmToggleButtonSetState(ccd_invert, (Boolean)(color_inverted(ss)), false); XtVaSetValues(ccd_cutoff, XmNvalue, (int)((color_cutoff(ss)) * 1000), NULL); reflect_color_scale(color_scale(ss)); XtVaSetValues(oid_ax, XmNvalue, fixup_angle(spectro_x_angle(ss)), NULL); XtVaSetValues(oid_ay, XmNvalue, fixup_angle(spectro_y_angle(ss)), NULL); XtVaSetValues(oid_az, XmNvalue, fixup_angle(spectro_z_angle(ss)), NULL); XtVaSetValues(oid_sx, XmNvalue, mus_iclamp(0, (int)(spectro_x_scale(ss) * 100), 100), NULL); XtVaSetValues(oid_sy, XmNvalue, mus_iclamp(0, (int)(spectro_y_scale(ss) * 100), 100), NULL); XtVaSetValues(oid_sz, XmNvalue, mus_iclamp(0, (int)(spectro_z_scale(ss) * 100), 100), NULL); XtVaSetValues(oid_hop, XmNvalue, mus_iclamp(1, spectro_hop(ss), HOP_MAX), NULL); check_orientation_hook(); } } void set_with_gl(bool val, bool with_dialogs) { #if HAVE_GL sgl_save_currents(); #endif in_set_with_gl(val); #if HAVE_GL sgl_set_currents(with_dialogs); if ((ccd_dialog) && (with_dialogs)) XmToggleButtonSetState(oid_glbutton, val, false); #endif } #if HAVE_GL static void with_gl_callback(Widget w, XtPointer context, XtPointer info) { XmToggleButtonCallbackStruct *cb = (XmToggleButtonCallbackStruct *)info; sgl_save_currents(); in_set_with_gl(cb->set); sgl_set_currents(true); /* this only sets the slider positions -- it doesn't update the labels! */ /* and reflect_spectro() doesn't help! */ if (ccd_dialog) { scale_set_label("x angle", oid_ax, spectro_x_angle(ss), false); scale_set_label("y angle", oid_ay, spectro_y_angle(ss), false); scale_set_label("z angle", oid_az, spectro_z_angle(ss), false); scale_set_label("x scale", oid_sx, spectro_x_scale(ss), false); scale_set_label("y scale", oid_sy, spectro_y_scale(ss), false); scale_set_label("z scale", oid_sz, spectro_z_scale(ss), false); } for_each_chan(update_graph); } #endif static void reset_color_orientation_callback(Widget w, XtPointer context, XtPointer info) { /* put everything back the way it was at the start. * this sets everything to the startup defaults -- should they be the dialog startup values instead? */ set_color_cutoff(DEFAULT_COLOR_CUTOFF); set_color_inverted(DEFAULT_COLOR_INVERTED); set_color_scale(DEFAULT_COLOR_SCALE); set_color_map(DEFAULT_COLOR_MAP); reset_spectro(); reflect_spectro(); for_each_chan(update_graph); } /* I tried a scrolled window with each colormap name in an appropriate color, but it looked kinda dumb */ Widget make_color_orientation_dialog(bool managed) { if (!ccd_dialog) { Arg args[32]; int n, initial_value; XmString xhelp, xdismiss, xinvert, titlestr, xreset, xstr; Widget mainform, light_label, lsep, rsep, sep1, tsep, color_frame, orientation_frame, color_form, orientation_form; Widget color_title, orientation_title; #if HAVE_GL XmString glstr; #endif xdismiss = XmStringCreateLocalized((char *)I_GO_AWAY); /* needed by template dialog */ xhelp = XmStringCreateLocalized((char *)I_HELP); xreset = XmStringCreateLocalized((char *)"Reset"); titlestr = XmStringCreateLocalized((char *)"Color and Orientation"); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNcancelLabelString, xdismiss); n++; XtSetArg(args[n], XmNhelpLabelString, xhelp); n++; XtSetArg(args[n], XmNokLabelString, xreset); n++; XtSetArg(args[n], XmNautoUnmanage, false); n++; XtSetArg(args[n], XmNdialogTitle, titlestr); n++; XtSetArg(args[n], XmNresizePolicy, XmRESIZE_GROW); n++; XtSetArg(args[n], XmNnoResize, false); n++; XtSetArg(args[n], XmNtransient, false); n++; ccd_dialog = XmCreateTemplateDialog(MAIN_SHELL(ss), (char *)"Color and Orientation", args, n); XtAddCallback(ccd_dialog, XmNcancelCallback, dismiss_color_orientation_callback, NULL); XtAddCallback(ccd_dialog, XmNhelpCallback, help_color_orientation_callback, NULL); XtAddCallback(ccd_dialog, XmNokCallback, reset_color_orientation_callback, NULL); XmStringFree(xhelp); XmStringFree(xdismiss); XmStringFree(titlestr); XmStringFree(xreset); XtVaSetValues(XmMessageBoxGetChild(ccd_dialog, XmDIALOG_CANCEL_BUTTON), XmNarmColor, ss->selection_color, NULL); XtVaSetValues(XmMessageBoxGetChild(ccd_dialog, XmDIALOG_HELP_BUTTON), XmNarmColor, ss->selection_color, NULL); XtVaSetValues(XmMessageBoxGetChild(ccd_dialog, XmDIALOG_CANCEL_BUTTON), XmNbackground, ss->highlight_color, NULL); XtVaSetValues(XmMessageBoxGetChild(ccd_dialog, XmDIALOG_HELP_BUTTON), XmNbackground, ss->highlight_color, NULL); XtVaSetValues(XmMessageBoxGetChild(ccd_dialog, XmDIALOG_OK_BUTTON), XmNarmColor, ss->selection_color, NULL); XtVaSetValues(XmMessageBoxGetChild(ccd_dialog, XmDIALOG_OK_BUTTON), XmNbackground, ss->highlight_color, NULL); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNbottomWidget, XmMessageBoxGetChild(ccd_dialog, XmDIALOG_SEPARATOR)); n++; mainform = XtCreateManagedWidget("formd", xmFormWidgetClass, ccd_dialog, args, n); /* color section */ n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNborderWidth, 10); n++; XtSetArg(args[n], XmNborderColor, ss->basic_color); n++; color_frame = XtCreateManagedWidget("color", xmFrameWidgetClass, mainform, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; color_form = XtCreateManagedWidget("cform", xmFormWidgetClass, color_frame, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_CENTER); n++; color_title = XtCreateManagedWidget("colors", xmLabelWidgetClass, color_form, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_POSITION); n++; XtSetArg(args[n], XmNleftPosition, 60); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, color_title); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNlistMarginWidth, 3); n++; ccd_list = XmCreateScrolledList(color_form, (char *)"colormap-list", args, n); XtVaSetValues(ccd_list, XmNbackground, ss->white, XmNforeground, ss->black, NULL); reflect_color_list(true); XtAddCallback(ccd_list, XmNbrowseSelectionCallback, list_color_callback, NULL); XtManageChild(ccd_list); XmListSelectPos(ccd_list, color_map(ss) + 1, false); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, color_title); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNseparatorType, XmNO_LINE); n++; XtSetArg(args[n], XmNorientation, XmVERTICAL); n++; XtSetArg(args[n], XmNwidth, 10); n++; lsep = XtCreateManagedWidget("sep", xmSeparatorWidgetClass, color_form, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNrightWidget, ccd_list); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, color_title); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNseparatorType, XmNO_LINE); n++; XtSetArg(args[n], XmNorientation, XmVERTICAL); n++; XtSetArg(args[n], XmNwidth, 10); n++; rsep = XtCreateManagedWidget("sep", xmSeparatorWidgetClass, color_form, args, n); /* this horizontal separator exists solely to keep the "light" label from clobbering the "dark" label! */ n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, lsep); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNrightWidget, rsep); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, color_title); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNseparatorType, XmNO_LINE); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNwidth, 250); n++; XtSetArg(args[n], XmNheight, 10); n++; sep1 = XtCreateManagedWidget("sep1", xmSeparatorWidgetClass, color_form, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, lsep); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNrightWidget, rsep); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, sep1); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNshowValue, XmNEAR_SLIDER); n++; XtSetArg(args[n], XmNvalue, 50); n++; ccd_scale = XtCreateManagedWidget("ccdscl", xmScaleWidgetClass, color_form, args, n); XtAddCallback(ccd_scale, XmNvalueChangedCallback, scale_color_callback, NULL); XtAddCallback(ccd_scale, XmNdragCallback, scale_color_callback, NULL); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, lsep); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, ccd_scale); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; light_label = XtCreateManagedWidget("light", xmLabelWidgetClass, color_form, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNrightWidget, rsep); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, ccd_scale); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtCreateManagedWidget("dark", xmLabelWidgetClass, color_form, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, lsep); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNrightWidget, rsep); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, light_label); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNseparatorType, XmNO_LINE); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNwidth, 250); n++; XtSetArg(args[n], XmNheight, 10); n++; tsep = XtCreateManagedWidget("tsep", xmSeparatorWidgetClass, color_form, args, n); n = 0; xstr = fscale_label("data cutoff", color_cutoff(ss)); XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, lsep); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNrightWidget, rsep); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, tsep); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNshowValue, XmNONE); n++; XtSetArg(args[n], XmNmaximum, 250); n++; XtSetArg(args[n], XmNdecimalPoints, 3); n++; XtSetArg(args[n], XmNtitleString, xstr); n++; XtSetArg(args[n], XmNvalue, (int)(color_cutoff(ss) * 1000)); n++; ccd_cutoff = XtCreateManagedWidget("cutoff", xmScaleWidgetClass, color_form, args, n); XtAddCallback(ccd_cutoff, XmNvalueChangedCallback, cutoff_color_callback, NULL); XtAddCallback(ccd_cutoff, XmNdragCallback, cutoff_color_callback, NULL); XmStringFree(xstr); XtVaSetValues(((XmScaleWidget)ccd_cutoff)->composite.children[0], XmNbackground, ss->basic_color, NULL); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNselectColor, ss->selection_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, lsep); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, ccd_cutoff); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNset, color_inverted(ss)); n++; xinvert = XmStringCreateLocalized((char *)"invert"); XtSetArg(args[n], XmNlabelString, xinvert); n++; ccd_invert = make_togglebutton_widget("invert", color_form, args, n); XtAddCallback(ccd_invert, XmNvalueChangedCallback, invert_color_callback, NULL); XmStringFree(xinvert); /* orientation section */ n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, color_frame); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNborderWidth, 10); n++; XtSetArg(args[n], XmNborderColor, ss->basic_color); n++; orientation_frame = XtCreateManagedWidget("color", xmFrameWidgetClass, mainform, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; orientation_form = XtCreateManagedWidget("oform", xmFormWidgetClass, orientation_frame, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_CENTER); n++; orientation_title = XtCreateManagedWidget("orientation", xmLabelWidgetClass, orientation_form, args, n); #define SCALE_BORDER_WIDTH 6 n = 0; initial_value = fixup_angle(spectro_x_angle(ss)); xstr = scale_label("x angle", initial_value, false); XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNshowValue, XmNONE); n++; XtSetArg(args[n], XmNvalue, initial_value); n++; XtSetArg(args[n], XmNmaximum, 360); n++; XtSetArg(args[n], XmNtitleString, xstr); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n++; XtSetArg(args[n], XmNrightPosition, 48); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, orientation_title); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNborderWidth, SCALE_BORDER_WIDTH); n++; XtSetArg(args[n], XmNborderColor, ss->basic_color); n++; oid_ax = XtCreateManagedWidget("ax", xmScaleWidgetClass, orientation_form, args, n); XtAddCallback(oid_ax, XmNvalueChangedCallback, ax_orientation_callback, NULL); XtAddCallback(oid_ax, XmNdragCallback, ax_orientation_callback, NULL); XmStringFree(xstr); XtVaSetValues(((XmScaleWidget)oid_ax)->composite.children[0], XmNbackground, ss->basic_color, NULL); n = 0; initial_value = mus_iclamp(0, (int)(spectro_x_scale(ss) * 100), (int)(100 * SPECTRO_X_SCALE_MAX)); xstr = scale_label("x scale", initial_value, true); XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNshowValue, XmNONE); n++; XtSetArg(args[n], XmNmaximum, (int)(100 * SPECTRO_X_SCALE_MAX)); n++; XtSetArg(args[n], XmNvalue, initial_value); n++; XtSetArg(args[n], XmNtitleString, xstr); n++; XtSetArg(args[n], XmNdecimalPoints, 2); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_POSITION); n++; XtSetArg(args[n], XmNleftPosition, 52); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, oid_ax); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNborderWidth, SCALE_BORDER_WIDTH); n++; XtSetArg(args[n], XmNborderColor, ss->basic_color); n++; oid_sx = XtCreateManagedWidget("xs", xmScaleWidgetClass, orientation_form, args, n); XtAddCallback(oid_sx, XmNvalueChangedCallback, sx_orientation_callback, NULL); XtAddCallback(oid_sx, XmNdragCallback, sx_orientation_callback, NULL); XmStringFree(xstr); XtVaSetValues(((XmScaleWidget)oid_sx)->composite.children[0], XmNbackground, ss->basic_color, NULL); n = 0; initial_value = fixup_angle(spectro_y_angle(ss)); xstr = scale_label("y angle", initial_value, false); XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNshowValue, XmNONE); n++; XtSetArg(args[n], XmNvalue, initial_value); n++; XtSetArg(args[n], XmNmaximum, 360); n++; XtSetArg(args[n], XmNtitleString, xstr); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n++; XtSetArg(args[n], XmNrightPosition, 48); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, oid_ax); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNborderWidth, SCALE_BORDER_WIDTH); n++; XtSetArg(args[n], XmNborderColor, ss->basic_color); n++; oid_ay = XtCreateManagedWidget("ay", xmScaleWidgetClass, orientation_form, args, n); XtAddCallback(oid_ay, XmNvalueChangedCallback, ay_orientation_callback, NULL); XtAddCallback(oid_ay, XmNdragCallback, ay_orientation_callback, NULL); XmStringFree(xstr); XtVaSetValues(((XmScaleWidget)oid_ay)->composite.children[0], XmNbackground, ss->basic_color, NULL); n = 0; initial_value = mus_iclamp(0, (int)(spectro_y_scale(ss) * 100), (int)(100 * SPECTRO_Y_SCALE_MAX)); xstr = scale_label("y scale", initial_value, true); XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNshowValue, XmNONE); n++; XtSetArg(args[n], XmNmaximum, (int)(100 * SPECTRO_Y_SCALE_MAX)); n++; XtSetArg(args[n], XmNvalue, initial_value); n++; XtSetArg(args[n], XmNtitleString, xstr); n++; XtSetArg(args[n], XmNdecimalPoints, 2); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_POSITION); n++; XtSetArg(args[n], XmNleftPosition, 52); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, oid_sx); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNborderWidth, SCALE_BORDER_WIDTH); n++; XtSetArg(args[n], XmNborderColor, ss->basic_color); n++; oid_sy = XtCreateManagedWidget("ys", xmScaleWidgetClass, orientation_form, args, n); XtAddCallback(oid_sy, XmNvalueChangedCallback, sy_orientation_callback, NULL); XtAddCallback(oid_sy, XmNdragCallback, sy_orientation_callback, NULL); XmStringFree(xstr); XtVaSetValues(((XmScaleWidget)oid_sy)->composite.children[0], XmNbackground, ss->basic_color, NULL); n = 0; initial_value = fixup_angle(spectro_z_angle(ss)); xstr = scale_label("z angle", initial_value, false); XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNtitleString, xstr); n++; XtSetArg(args[n], XmNshowValue, XmNONE); n++; XtSetArg(args[n], XmNvalue, initial_value); n++; XtSetArg(args[n], XmNmaximum, 360); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n++; XtSetArg(args[n], XmNrightPosition, 48); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, oid_ay); n++; XtSetArg(args[n], XmNborderWidth, SCALE_BORDER_WIDTH); n++; XtSetArg(args[n], XmNborderColor, ss->basic_color); n++; oid_az = XtCreateManagedWidget("az", xmScaleWidgetClass, orientation_form, args, n); XtAddCallback(oid_az, XmNvalueChangedCallback, az_orientation_callback, NULL); XtAddCallback(oid_az, XmNdragCallback, az_orientation_callback, NULL); XmStringFree(xstr); XtVaSetValues(((XmScaleWidget)oid_az)->composite.children[0], XmNbackground, ss->basic_color, NULL); n = 0; initial_value = mus_iclamp(0, (int)(spectro_z_scale(ss) * 100), (int)(100 * SPECTRO_Z_SCALE_MAX)); xstr = scale_label("z scale", initial_value, true); XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNshowValue, XmNONE); n++; XtSetArg(args[n], XmNdecimalPoints, 2); n++; XtSetArg(args[n], XmNmaximum, (int)(100 * SPECTRO_Z_SCALE_MAX)); n++; XtSetArg(args[n], XmNvalue, initial_value); n++; XtSetArg(args[n], XmNtitleString, xstr); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_POSITION); n++; XtSetArg(args[n], XmNleftPosition, 52); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, oid_sy); n++; XtSetArg(args[n], XmNborderWidth, SCALE_BORDER_WIDTH); n++; XtSetArg(args[n], XmNborderColor, ss->basic_color); n++; oid_sz = XtCreateManagedWidget("zs", xmScaleWidgetClass, orientation_form, args, n); XtAddCallback(oid_sz, XmNvalueChangedCallback, sz_orientation_callback, NULL); XtAddCallback(oid_sz, XmNdragCallback, sz_orientation_callback, NULL); XmStringFree(xstr); XtVaSetValues(((XmScaleWidget)oid_sz)->composite.children[0], XmNbackground, ss->basic_color, NULL); n = 0; initial_value = mus_iclamp(1, spectro_hop(ss), HOP_MAX); xstr = scale_label("hop", initial_value, false); XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNshowValue, XmNONE); n++; XtSetArg(args[n], XmNvalue, initial_value); n++; XtSetArg(args[n], XmNmaximum, HOP_MAX); n++; XtSetArg(args[n], XmNtitleString, xstr); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n++; XtSetArg(args[n], XmNrightPosition, 48); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, oid_az); n++; #if HAVE_GL XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; #else XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; #endif XtSetArg(args[n], XmNborderWidth, SCALE_BORDER_WIDTH); n++; XtSetArg(args[n], XmNborderColor, ss->basic_color); n++; oid_hop = XtCreateManagedWidget("hop", xmScaleWidgetClass, orientation_form, args, n); XtAddCallback(oid_hop, XmNvalueChangedCallback, hop_orientation_callback, NULL); XtAddCallback(oid_hop, XmNdragCallback, hop_orientation_callback, NULL); XmStringFree(xstr); XtVaSetValues(((XmScaleWidget)oid_hop)->composite.children[0], XmNbackground, ss->basic_color, NULL); #if HAVE_GL n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNselectColor, ss->selection_color); n++; XtSetArg(args[n], XmNset, with_gl(ss)); n++; glstr = XmStringCreateLocalized((char *)"use OpenGL"); XtSetArg(args[n], XmNlabelString, glstr); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, oid_hop); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; oid_glbutton = make_togglebutton_widget("use OpenGL", orientation_form, args, n); XtAddCallback(oid_glbutton, XmNvalueChangedCallback, with_gl_callback, NULL); XmStringFree(glstr); #endif if (color_scale(ss) != 1.0) reflect_color_scale(color_scale(ss)); map_over_children(ccd_dialog, set_main_color_of_widget); set_dialog_widget(COLOR_ORIENTATION_DIALOG, ccd_dialog); if (managed) XtManageChild(ccd_dialog); } else { if (managed) { if (!XtIsManaged(ccd_dialog)) XtManageChild(ccd_dialog); raise_dialog(ccd_dialog); } } return(ccd_dialog); } static void view_color_orientation_callback(Widget w, XtPointer context, XtPointer info) { make_color_orientation_dialog(true); } bool color_orientation_dialog_is_active(void) { return((ccd_dialog) && (XtIsManaged(ccd_dialog))); } void g_init_gxdraw(void) { #define H_orientation_hook S_orientation_hook " (): called whenever one of the variables associated with the \ orientation dialog changes" #define H_color_hook S_color_hook " (): called whenever one of the variables associated with the \ color dialog changes" orientation_hook = Xen_define_hook(S_orientation_hook, "(make-hook)", 0, H_orientation_hook); color_hook = Xen_define_hook(S_color_hook, "(make-hook)", 0, H_color_hook); } #define HELP_ROWS 10 #define HELP_XREFS 8 #define HELP_COLUMNS 72 /* these set the initial size of the help dialog text area */ static Widget help_dialog = NULL; static Widget help_text = NULL; static char *original_help_text = NULL; static with_word_wrap_t outer_with_wrap = WITHOUT_WORD_WRAP; static const char **help_urls = NULL; /* shouldn't this be static char* const char*? */ static int old_help_text_width = 0; static void help_expose(Widget w, XtPointer context, XEvent *event, Boolean *cont) { int curwid; curwid = widget_width(help_text); if (old_help_text_width == 0) old_help_text_width = curwid; else { if ((outer_with_wrap == WITH_WORD_WRAP) && (abs(curwid - old_help_text_width) > 10)) { char *cur_help_str, *new_help_str = NULL; cur_help_str = XmTextGetString(help_text); new_help_str = word_wrap(original_help_text, curwid); XmTextSetString(help_text, new_help_str); if (new_help_str) free(new_help_str); if (cur_help_str) XtFree(cur_help_str); old_help_text_width = curwid; } } } static XmString parse_crossref(const char *xref) { XmString xs = NULL, tmp; int i, len, start = 0, j, k; char *str; /* crossref has text for scrolled list entry, but url is in '{}'. It is displayed via the texts rendition */ len = strlen(xref); for (i = 0; i < len; i++) { if (xref[i] == '{') { if (i > 0) { str = (char *)calloc(i - start + 1, sizeof(char)); for (k = 0, j = start; j < i; k++, j++) str[k] = xref[j]; tmp = XmStringGenerate(str, NULL, XmCHARSET_TEXT, (char *)"normal_text"); free(str); if (xs) xs = XmStringConcatAndFree(xs, tmp); else xs = tmp; } start = i + 1; } else { if (xref[i] == '}') { str = (char *)calloc(i - start + 1, sizeof(char)); for (k = 0, j = start; j < i; k++, j++) str[k] = xref[j]; if (xs) xs = XmStringConcatAndFree(xs, XmStringGenerate(str, NULL, XmCHARSET_TEXT, (char *)"url_text")); else xs = XmStringGenerate(str, NULL, XmCHARSET_TEXT, (char *)"url_text"); free(str); start = i + 1; } } } if (start < len) { str = (char *)calloc(len - start + 1, sizeof(char)); for (k = 0, j = start; j < len; k++, j++) str[k] = xref[j]; if (xs) xs = XmStringConcatAndFree(xs, XmStringGenerate(str, NULL, XmCHARSET_TEXT, (char *)"normal_text")); else xs = XmStringGenerate(str, NULL, XmCHARSET_TEXT, (char *)"normal_text"); free(str); } return(xs); } static char *find_highlighted_text(XmString xs) { /* search xs for text in "url_text" rendition, returning first such portion */ XtPointer text; bool in_red_text = false; unsigned int len; char *result; XmStringComponentType type; XmStringContext ctx; XmStringInitContext(&ctx, xs); while ((type = XmStringGetNextTriple(ctx, &len, &text)) != XmSTRING_COMPONENT_END) { switch (type) { case XmSTRING_COMPONENT_RENDITION_BEGIN: in_red_text = mus_strcmp((char *)text, "url_text"); break; case XmSTRING_COMPONENT_RENDITION_END: in_red_text = false; break; case XmSTRING_COMPONENT_TEXT: if (in_red_text) { result = mus_strdup((char *)text); XtFree((char *)text); XmStringFreeContext(ctx); return(result); } } /* this from the Motif docs, though it looks odd to me */ if (text) XtFree((char *)text); text = NULL; } XmStringFreeContext(ctx); return(NULL); } static Widget related_items = NULL; static char *help_completer(widget_t w, const char *text, void *data) { return(expression_completer(w, text, data)); /* might want to look at help topics too */ } static bool new_help(const char *pattern, bool complain) { const char *url = NULL; const char **xrefs; url = snd_url(pattern); if (url) { /* given name, find doc string, if any */ Xen xstr; xstr = g_snd_help(C_string_to_Xen_string(pattern), 0); if (Xen_is_string(xstr)) { int gc_loc; gc_loc = snd_protect(xstr); xrefs = help_name_to_xrefs(pattern); snd_help_with_xrefs(pattern, Xen_string_to_C_string(xstr), WITH_WORD_WRAP, xrefs, NULL); snd_unprotect_at(gc_loc); if (xrefs) free(xrefs); return(true); } url_to_html_viewer(url); return(true); } if ((!(snd_topic_help(pattern))) && (complain)) { xrefs = help_name_to_xrefs(pattern); if (xrefs) { snd_help_with_xrefs(pattern, "(no help found)", WITH_WORD_WRAP, xrefs, NULL); free(xrefs); return(true); } else snd_help_with_xrefs(pattern, "(no help found)", WITH_WORD_WRAP, NULL, NULL); } return(false); } static void help_browse_callback(Widget w, XtPointer context, XtPointer info) { /* single-click to select item in "related items" list */ XmListCallbackStruct *cbs = (XmListCallbackStruct *)info; if ((help_urls) && (help_urls[cbs->item_position - 1])) url_to_html_viewer(help_urls[cbs->item_position - 1]); else { char *red_text; red_text = find_highlighted_text(cbs->item); if (red_text) { name_to_html_viewer(red_text); free(red_text); } else { red_text = (char *)XmStringUnparse(cbs->item, NULL, XmCHARSET_TEXT, XmCHARSET_TEXT, NULL, 0, XmOUTPUT_ALL); if (red_text) { new_help(red_text, true); XtFree(red_text); } } } } static void help_double_click_callback(Widget w, XtPointer context, XtPointer info) { /* double-click item in "related items" list */ XmListCallbackStruct *cbs = (XmListCallbackStruct *)info; if ((help_urls) && (help_urls[cbs->item_position - 1])) url_to_html_viewer(help_urls[cbs->item_position - 1]); else { char *red_text; red_text = find_highlighted_text(cbs->selected_items[0]); if (red_text) { name_to_html_viewer(red_text); free(red_text); } else { red_text = (char *)XmStringUnparse(cbs->selected_items[0], NULL, XmCHARSET_TEXT, XmCHARSET_TEXT, NULL, 0, XmOUTPUT_ALL); if (red_text) { name_to_html_viewer(red_text); XtFree(red_text); } } } } static Widget help_search = NULL; static void help_quit_callback(Widget w, XtPointer context, XtPointer info) { /* this focus widget check is actually needed! */ if (XmGetFocusWidget(help_dialog) == XmMessageBoxGetChild(help_dialog, XmDIALOG_CANCEL_BUTTON)) XtUnmanageChild(help_dialog); } static void text_release_callback(Widget w, XtPointer context, XEvent *event, Boolean *flag) { char *help_str; help_str = XmTextGetSelection(w); if (help_str) { int i, len; bool one_word = true; len = mus_strlen(help_str); for (i = 0; i < len; i++) if (isspace(help_str[i])) { one_word = false; break; } if (one_word) new_help(help_str, false); XtFree(help_str); } } static void help_search_callback(Widget w, XtPointer context, XtPointer info) { char *pattern = NULL; pattern = XmTextFieldGetString(w); if (new_help(pattern, true)) XmTextFieldSetString(w, (char *)""); if (pattern) XtFree(pattern); } static XmRendition texts[2]; static void create_help_monolog(void) { /* create scrollable but not editable text window */ Arg args[20]; int n; XmString titlestr, go_away; Widget holder, xref_label; /* documentation says this isn't needed, but it is */ Widget frame, label, inner_holder, sep, parent; XmRenderTable rs = NULL; titlestr = XmStringCreateLocalized((char *)I_HELP); go_away = XmStringCreateLocalized((char *)I_GO_AWAY); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNdialogTitle, titlestr); n++; /* this window should be resizable by the user (i.e. have the resize bars), but not resize itself */ XtSetArg(args[n], XmNautoUnmanage, false); n++; XtSetArg(args[n], XmNresizePolicy, XmRESIZE_GROW); n++; XtSetArg(args[n], XmNnoResize, false); n++; XtSetArg(args[n], XmNtransient, false); n++; XtSetArg(args[n], XmNcancelLabelString, go_away); n++; help_dialog = XmCreateMessageDialog(MAIN_PANE(ss), (char *)"snd-help", args, n); XtAddEventHandler(help_dialog, ExposureMask, false, help_expose, NULL); XtAddCallback(help_dialog, XmNcancelCallback, help_quit_callback, NULL); XtUnmanageChild(XmMessageBoxGetChild(help_dialog, XmDIALOG_OK_BUTTON)); XtUnmanageChild(XmMessageBoxGetChild(help_dialog, XmDIALOG_HELP_BUTTON)); XtUnmanageChild(XmMessageBoxGetChild(help_dialog, XmDIALOG_SYMBOL_LABEL)); XtVaSetValues(XmMessageBoxGetChild(help_dialog, XmDIALOG_MESSAGE_LABEL), XmNbackground, ss->highlight_color, NULL); XmStringFree(titlestr); holder = XtCreateManagedWidget("holder", xmFormWidgetClass, help_dialog, NULL, 0); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNeditMode, XmMULTI_LINE_EDIT); n++; XtSetArg(args[n], XmNeditable, false); n++; XtSetArg(args[n], XmNcolumns, HELP_COLUMNS); n++; XtSetArg(args[n], XmNrows, HELP_ROWS); n++; XtSetArg(args[n], XmNforeground, ss->black); n++; /* needed if color allocation fails completely */ XtSetArg(args[n], XmNbackground, ss->white); n++; help_text = XmCreateScrolledText(holder, (char *)"help-text", args, n); XtAddEventHandler(help_text, ButtonReleaseMask, false, text_release_callback, NULL); XtManageChild(help_text); /* to display the url-related portion of the text in red, we need a rendition for it in the rendertable */ /* try to find the current default render table. */ parent = help_text; while ((parent != NULL) && (rs == NULL)) { XtVaGetValues(parent, XmNrenderTable, &rs, NULL); parent = XtParent(parent); } n = 0; if (rs == NULL) { /* failed to find a rendertable to specialize, so we need an explicit font */ XtSetArg(args[n], XmNfontName, listener_font(ss)); n++; XtSetArg(args[n], XmNfontType, XmFONT_IS_FONT); n++; XtSetArg(args[n], XmNloadModel, XmLOAD_IMMEDIATE); n++; } XtSetArg(args[n], XmNrenditionBackground, ss->white); n++; XtSetArg(args[n], XmNrenditionForeground, ss->red); n++; texts[0] = XmRenditionCreate(help_text, (char *)"url_text", args, n); XtSetArg(args[n - 1], XmNrenditionForeground, ss->black); texts[1] = XmRenditionCreate(help_text, (char *)"normal_text", args, n); rs = XmRenderTableCopy(XmRenderTableAddRenditions(rs, texts, 2, XmMERGE_NEW), NULL, 0); /* * valgrind says this data is used later * XmRenditionFree(texts[0]); * XmRenditionFree(texts[1]); */ n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, XtParent(help_text)); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNheight, 6); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNseparatorType, XmNO_LINE); n++; sep = XtCreateManagedWidget("sep", xmSeparatorWidgetClass, holder, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNheight, 24); n++; /* XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; */ label = XtCreateManagedWidget("help topic:", xmLabelWidgetClass, holder, args, n); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, label); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; help_search = make_textfield_widget("help-search", holder, args, n, ACTIVATABLE, add_completer_func(help_completer, NULL)); XtAddCallback(help_search, XmNactivateCallback, help_search_callback, NULL); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, sep); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNbottomWidget, help_search); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNshadowThickness, 4); n++; frame = XtCreateManagedWidget("frame", xmFrameWidgetClass, holder, args, n); inner_holder = XtCreateManagedWidget("inner-holder", xmFormWidgetClass, frame, NULL, 0); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; xref_label = XtCreateManagedWidget("related topics:", xmLabelWidgetClass, inner_holder, args, n); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, xref_label); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; /* in operton-based solaris 10 this (next) line causes an X server error (with no stack...): * complaint is X_ChangeGC got an invalid font. * Do I need a configure test program for this? Is there some other way to force the render table to take effect? */ #if (!HAVE_SUN) || (!MUS_LITTLE_ENDIAN) XtSetArg(args[n], XmNfontList, 0); n++; /* needed or new rendertable doesn't take effect! */ /* also, 0, not NULL so types match */ XtSetArg(args[n], XmNrenderTable, rs); n++; #endif XtSetArg(args[n], XmNvisibleItemCount, HELP_XREFS); n++; /* appears to be a no-op */ XtSetArg(args[n], XmNheight, 150); n++; XtSetArg(args[n], XmNscrollBarDisplayPolicy, XmAS_NEEDED); n++; related_items = XmCreateScrolledList(inner_holder, (char *)"help-list", args, n); XtManageChild(related_items); XtAddCallback(related_items, XmNbrowseSelectionCallback, help_browse_callback, NULL); XtAddCallback(related_items, XmNdefaultActionCallback, help_double_click_callback, NULL); XtManageChild(help_dialog); map_over_children(help_dialog, set_main_color_of_widget); XtVaSetValues(help_text, XmNbackground, ss->white, XmNforeground, ss->black, NULL); XtVaSetValues(related_items, XmNbackground, ss->highlight_color, XmNforeground, ss->black, NULL); XtVaSetValues(xref_label, XmNbackground, ss->highlight_color, XmNforeground, ss->black, NULL); XtVaSetValues(XmMessageBoxGetChild(help_dialog, XmDIALOG_CANCEL_BUTTON), XmNarmColor, ss->selection_color, NULL); XtVaSetValues(XmMessageBoxGetChild(help_dialog, XmDIALOG_CANCEL_BUTTON), XmNbackground, ss->highlight_color, NULL); set_dialog_widget(HELP_DIALOG, help_dialog); } int help_text_width(const char *txt, int start, int end) { #if 0 /* this is full of problems... -- adding renditions below makes everything else flakey */ if ((help_text) && (end > start)) { char *msg; int i, j; XmString s1; Dimension text_wid = 0; XmFontList fonts; XtVaGetValues(help_text, XmNfontList, &fonts, NULL); msg = (char *)calloc(end - start + 1, sizeof(char)); for (i = start, j = 0; i < end; i++, j++) msg[j] = txt[i]; s1 = XmStringCreateLocalized(msg); text_wid = XmStringWidth(fonts, s1); XmStringFree(s1); free(msg); return((int)text_wid); } #endif return((end - start) * 8); } Widget snd_help(const char *subject, const char *helpstr, with_word_wrap_t with_wrap) { /* place help string in scrollable help window */ /* if window is already active, add this help at the top and reposition */ XmString xstr1; outer_with_wrap = with_wrap; if (!(help_dialog)) create_help_monolog(); else raise_dialog(help_dialog); xstr1 = XmStringCreateLocalized((char *)subject); XtVaSetValues(help_dialog, XmNmessageString, xstr1, NULL); original_help_text = (char *)helpstr; if (with_wrap == WITH_WORD_WRAP) { char *new_help_str = NULL; new_help_str = word_wrap(helpstr, widget_width(help_text)); XmTextSetString(help_text, new_help_str); if (new_help_str) free(new_help_str); } else XmTextSetString(help_text, (char *)helpstr); if (!XtIsManaged(help_dialog)) XtManageChild(help_dialog); XmStringFree(xstr1); XtVaSetValues(related_items, XmNitems, NULL, XmNitemCount, 0, NULL); return(help_dialog); } Widget snd_help_with_xrefs(const char *subject, const char *helpstr, with_word_wrap_t with_wrap, const char **xrefs, const char **urls) { Widget w; w = snd_help(subject, helpstr, with_wrap); help_urls = urls; /* can't associate the url with the help item in any "natural" way in Motif (no user-data per item) */ if (xrefs) { int i, len; for (i = 0; ; i++) if (!xrefs[i]) { len = i; break; } if (len > 0) { XmString *strs; strs = (XmString *)calloc(len, sizeof(XmString)); for (i = 0; i < len; i++) strs[i] = parse_crossref((const char *)(xrefs[i])); XtVaSetValues(related_items, XmNitems, strs, XmNitemCount, len, NULL); for (i = 0; i < len; i++) XmStringFree(strs[i]); free(strs); } } return(w); } void snd_help_append(const char *text) { if (help_text) XmTextInsert(help_text, XmTextGetLastPosition(help_text), (char *)text); } void snd_help_back_to_top(void) { if (help_text) XmTextShowPosition(help_text, 0); } static Widget edit_find_dialog, edit_find_text, cancelB, edit_find_label, previousB; static Widget find_error_frame = NULL, find_error_label = NULL; static chan_info *find_channel = NULL; /* sigh */ static void clear_find_error(void); static void edit_find_modify_callback(Widget w, XtPointer context, XtPointer info) { clear_find_error(); } static void clear_find_error(void) { if ((find_error_frame) && (XtIsManaged(find_error_frame))) XtUnmanageChild(find_error_frame); XtRemoveCallback(edit_find_text, XmNmodifyVerifyCallback, edit_find_modify_callback, NULL); /* squeezing out the error label room here moves the text widget, which is irritating since it * means the text we're typing gets lost */ } void find_dialog_stop_label(bool show_stop) { XmString s1; if (show_stop) s1 = XmStringCreateLocalized((char *)I_STOP); else s1 = XmStringCreateLocalized((char *)I_GO_AWAY); XtVaSetValues(cancelB, XmNlabelString, s1, NULL); XmStringFree(s1); } void errors_to_find_text(const char *msg, void *data) { Dimension find_height = 0; int lines = 0; XmString label; find_dialog_set_label("error"); label = multi_line_label(msg, &lines); XtVaSetValues(find_error_label, XmNlabelString, label, XmNheight, lines * 20, NULL); XtVaSetValues(find_error_frame, XmNheight, lines * 20, NULL); XtVaGetValues(edit_find_dialog, XmNheight, &find_height, NULL); if (find_height < (lines * 20 + 140)) { XtUnmanageChild(edit_find_dialog); XtVaSetValues(edit_find_dialog, XmNheight, 140 + 20 * lines, NULL); XtManageChild(edit_find_dialog); } XmStringFree(label); XtManageChild(find_error_frame); XtAddCallback(edit_find_text, XmNmodifyVerifyCallback, edit_find_modify_callback, NULL); } void stop_search_if_error(const char *msg, void *data) { errors_to_find_text(msg, data); ss->stopped_explicitly = true; /* should be noticed in global_search in snd-find.c */ } static void edit_find_help_callback(Widget w, XtPointer context, XtPointer info) { find_dialog_help(); } static void edit_find_ok_callback(read_direction_t direction, Widget w, XtPointer context, XtPointer info) { char *str; str = XmTextGetString(edit_find_text); #if HAVE_EXTENSION_LANGUAGE find_dialog_find(str, direction, find_channel); #endif if (str) free(str); } void find_dialog_set_label(const char *str) { if (edit_find_label) set_label(edit_find_label, str); } static void edit_find_next_callback(Widget w, XtPointer context, XtPointer info) { edit_find_ok_callback(READ_FORWARD, w, context, info); } static void edit_find_previous_callback(Widget w, XtPointer context, XtPointer info) { edit_find_ok_callback(READ_BACKWARD, w, context, info); } static void find_dialog_close(Widget w, XtPointer context, XtPointer info) { clear_find_error(); } static void edit_find_cancel_callback(Widget w, XtPointer context, XtPointer info) { if (ss->checking_explicitly) ss->stopped_explicitly = true; else { XtUnmanageChild(edit_find_dialog); clear_find_error(); } } static void make_edit_find_dialog(bool managed, chan_info *cp) { find_channel = cp; if (!edit_find_dialog) { Widget dl, rc; Arg args[20]; int n; XmString go_away, next; n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; go_away = XmStringCreateLocalized((char *)I_GO_AWAY); next = XmStringCreateLocalized((char *)I_NEXT); XtSetArg(args[n], XmNokLabelString, next); n++; XtSetArg(args[n], XmNcancelLabelString, go_away); n++; XtSetArg(args[n], XmNautoUnmanage, false); n++; XtSetArg(args[n], XmNresizePolicy, XmRESIZE_GROW); n++; XtSetArg(args[n], XmNnoResize, false); n++; XtSetArg(args[n], XmNtransient, false); n++; edit_find_dialog = XmCreateMessageDialog(MAIN_SHELL(ss), (char *)I_FIND, args, n); XmStringFree(go_away); XmStringFree(next); XtUnmanageChild(XmMessageBoxGetChild(edit_find_dialog, XmDIALOG_SYMBOL_LABEL)); XtUnmanageChild(XmMessageBoxGetChild(edit_find_dialog, XmDIALOG_MESSAGE_LABEL)); XtAddCallback(edit_find_dialog, XmNhelpCallback, edit_find_help_callback, NULL); XtAddCallback(edit_find_dialog, XmNcancelCallback, edit_find_cancel_callback, NULL); XtAddCallback(edit_find_dialog, XmNokCallback, edit_find_next_callback, NULL); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNarmColor, ss->selection_color); n++; previousB = XtCreateManagedWidget(I_PREVIOUS, xmPushButtonGadgetClass, edit_find_dialog, args, n); XtAddCallback(previousB, XmNactivateCallback, edit_find_previous_callback, NULL); rc = XtCreateManagedWidget("row", xmFormWidgetClass, edit_find_dialog, NULL, 0); n = 0; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; dl = XtCreateManagedWidget(I_find, xmLabelWidgetClass, rc, args, n); n = 0; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, dl); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; edit_find_text = make_textfield_widget("text", rc, args, n, ACTIVATABLE, add_completer_func(expression_completer, NULL)); n = 0; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, edit_find_text); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNmarginHeight, 10); n++; edit_find_label = XtCreateManagedWidget(" ", xmLabelWidgetClass, rc, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, edit_find_label); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNallowResize, true); n++; XtSetArg(args[n], XmNshadowType, XmSHADOW_ETCHED_IN); n++; XtSetArg(args[n], XmNshadowThickness, 2); n++; find_error_frame = XtCreateManagedWidget("find-error-frame", xmFrameWidgetClass, rc, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; find_error_label = XtCreateManagedWidget("", xmLabelWidgetClass, find_error_frame, args, n); map_over_children(edit_find_dialog, set_main_color_of_widget); XtVaSetValues(XmMessageBoxGetChild(edit_find_dialog, XmDIALOG_OK_BUTTON), XmNarmColor, ss->selection_color, NULL); XtVaSetValues(XmMessageBoxGetChild(edit_find_dialog, XmDIALOG_CANCEL_BUTTON), XmNarmColor, ss->selection_color, NULL); XtVaSetValues(XmMessageBoxGetChild(edit_find_dialog, XmDIALOG_HELP_BUTTON), XmNarmColor, ss->selection_color, NULL); XtVaSetValues(XmMessageBoxGetChild(edit_find_dialog, XmDIALOG_OK_BUTTON), XmNbackground, ss->highlight_color, NULL); XtVaSetValues(XmMessageBoxGetChild(edit_find_dialog, XmDIALOG_CANCEL_BUTTON), XmNbackground, ss->highlight_color, NULL); XtVaSetValues(XmMessageBoxGetChild(edit_find_dialog, XmDIALOG_HELP_BUTTON), XmNbackground, ss->highlight_color, NULL); cancelB = XmMessageBoxGetChild(edit_find_dialog, XmDIALOG_CANCEL_BUTTON); set_dialog_widget(FIND_DIALOG, edit_find_dialog); XtUnmanageChild(find_error_frame); if (managed) XtManageChild(edit_find_dialog); { Atom wm_delete_window; wm_delete_window = XmInternAtom(MAIN_DISPLAY(ss), (char *)"WM_DELETE_WINDOW", false); XmAddWMProtocolCallback(XtParent(edit_find_dialog), wm_delete_window, find_dialog_close, NULL); } } else { if (managed) { if (!XtIsManaged(edit_find_dialog)) XtManageChild(edit_find_dialog); raise_dialog(edit_find_dialog); } } { XmString titlestr; if (cp) titlestr = XmStringCreateLocalized(mus_format("%s in %s channel %d", (char *)I_FIND, cp->sound->short_filename, cp->chan)); else titlestr = XmStringCreateLocalized((char *)I_FIND); XtVaSetValues(edit_find_dialog, XmNdialogTitle, titlestr, NULL); XmStringFree(titlestr); } } static void edit_find_callback(Widget w, XtPointer context, XtPointer info) { make_edit_find_dialog(true, NULL); } void find_dialog(chan_info *cp) { make_edit_find_dialog(true, cp); } bool find_dialog_is_active(void) { return((edit_find_dialog) && (XtIsManaged(edit_find_dialog))); } void save_find_dialog_state(FILE *fd) { if (find_dialog_is_active()) { char *text = NULL; text = XmTextGetString(edit_find_text); if ((text) && (*text)) { #if HAVE_SCHEME fprintf(fd, "(%s #t \"%s\")\n", S_find_dialog, text); #endif #if HAVE_RUBY fprintf(fd, "%s(true, \"%s\")\n", to_proc_name(S_find_dialog), text); #endif #if HAVE_FORTH fprintf(fd, "#t \"%s\" %s drop\n", text, S_find_dialog); #endif XtFree(text); } else { #if HAVE_SCHEME if (ss->search_expr) fprintf(fd, "(%s #t \"%s\")\n", S_find_dialog, ss->search_expr); else fprintf(fd, "(%s #t)\n", S_find_dialog); #endif #if HAVE_RUBY if (ss->search_expr) fprintf(fd, "%s(true, \"%s\")\n", to_proc_name(S_find_dialog), ss->search_expr); else fprintf(fd, "%s(true)\n", to_proc_name(S_find_dialog)); #endif #if HAVE_FORTH if (ss->search_expr) fprintf(fd, "#t \"%s\" %s drop\n", ss->search_expr, S_find_dialog); else fprintf(fd, "#t %s drop\n", S_find_dialog); #endif } } } static Xen g_find_dialog(Xen managed, Xen text) { #define H_find_dialog "(" S_find_dialog " :optional managed text): create and activate the Edit:Find dialog, return the dialog widget. \ If 'text' is included, it is preloaded into the find dialog text widget." Xen_check_type(Xen_is_boolean_or_unbound(managed), managed, 1, S_find_dialog, "a boolean"); Xen_check_type(Xen_is_string_or_unbound(text), text, 2, S_find_dialog, "a string"); make_edit_find_dialog(Xen_boolean_to_C_bool(managed), NULL); if ((edit_find_text) && (Xen_is_string(text))) XmTextSetString(edit_find_text, (char *)Xen_string_to_C_string(text)); return(Xen_wrap_widget(edit_find_dialog)); } static Xen g_find_dialog_widgets(void) { if (edit_find_dialog) return(Xen_cons(Xen_wrap_widget(edit_find_dialog), Xen_cons(Xen_wrap_widget(edit_find_text), Xen_cons(Xen_wrap_widget(XmMessageBoxGetChild(edit_find_dialog, XmDIALOG_OK_BUTTON)), /* find next */ Xen_cons(Xen_wrap_widget(previousB), /* find previous */ Xen_cons(Xen_wrap_widget(XmMessageBoxGetChild(edit_find_dialog, XmDIALOG_CANCEL_BUTTON)), /* go away */ Xen_empty_list)))))); return(Xen_empty_list); } Xen_wrap_2_optional_args(g_find_dialog_w, g_find_dialog) Xen_wrap_no_args(g_find_dialog_widgets_w, g_find_dialog_widgets) void g_init_gxfind(void) { Xen_define_safe_procedure(S_find_dialog, g_find_dialog_w, 0, 2, 0, H_find_dialog); Xen_define_safe_procedure("find-dialog-widgets", g_find_dialog_widgets_w, 0, 0, 0, "internal auto-test function"); } #define NAME_COLUMNS 8 /* ---------------- mix dialog ---------------- */ static Widget mix_dialog = NULL; static int mix_dialog_id = INVALID_MIX_ID, old_mix_dialog_id = INVALID_MIX_ID; static env *dialog_env = NULL; static bool dragging = false; static int edpos_before_drag; static with_hook_t hookable_before_drag; static mus_long_t drag_beg = 0, drag_end = 0; static void start_dragging(int mix_id) { chan_info *cp; cp = mix_chan_info_from_id(mix_id); edpos_before_drag = cp->edit_ctr; hookable_before_drag = cp->hookable; cp->hookable = WITHOUT_HOOK; dragging = true; drag_beg = mix_position_from_id(mix_id); drag_end = drag_beg + mix_length_from_id(mix_id); start_dragging_syncd_mixes(mix_id); } static void keep_dragging(int mix_id) { chan_info *cp; cp = mix_chan_info_from_id(mix_id); cp->edit_ctr = edpos_before_drag; keep_dragging_syncd_mixes(mix_id); } static void stop_dragging(int mix_id) { chan_info *cp; cp = mix_chan_info_from_id(mix_id); undo_edit(cp, 1); cp->hookable = hookable_before_drag; dragging = false; stop_dragging_syncd_mixes(mix_id); } /* -------- speed -------- */ static Widget w_speed_number, w_speed_label, w_speed; static speed_style_t xmix_speed_control_style = SPEED_CONTROL_AS_FLOAT; static int speed_to_scrollbar(mus_float_t minval, mus_float_t val, mus_float_t maxval) { if (val <= minval) return(0); if (val >= maxval) return((int)(0.9 * SCROLLBAR_MAX)); return(snd_round(0.9 * SCROLLBAR_MAX * ((log(val) - log(minval)) / (log(maxval) - log(minval))))); } static mus_float_t set_speed_label(Widget speed_number, int ival) { char speed_number_buffer[6]; mus_float_t speed; speed = speed_changed(exp((ival * (log(speed_control_max(ss)) - log(speed_control_min(ss))) / (0.9 * SCROLLBAR_MAX)) + log(speed_control_min(ss))), speed_number_buffer, xmix_speed_control_style, speed_control_tones(ss), 6); set_label(speed_number, speed_number_buffer); return(speed); } static void mix_speed_click_callback(Widget w, XtPointer context, XtPointer info) { char speed_number_buffer[6]; mus_float_t speed; if (!(mix_is_active(mix_dialog_id))) return; speed = speed_changed(1.0, speed_number_buffer, xmix_speed_control_style, speed_control_tones(ss), 6); drag_beg = mix_position_from_id(mix_dialog_id); drag_end = drag_beg + mix_length_from_id(mix_dialog_id); mix_set_speed_edit(mix_dialog_id, speed); syncd_mix_set_speed(mix_dialog_id, speed); after_mix_edit(mix_dialog_id); set_label(w_speed_number, speed_number_buffer); XtVaSetValues(w_speed, XmNvalue, speed_to_scrollbar(speed_control_min(ss), 1.0, speed_control_max(ss)), NULL); } static void mix_speed_label_click_callback(Widget w, XtPointer context, XtPointer info) { char speed_number_buffer[6]; if (!(mix_is_active(mix_dialog_id))) return; switch (xmix_speed_control_style) { default: case SPEED_CONTROL_AS_FLOAT: xmix_speed_control_style = SPEED_CONTROL_AS_RATIO; break; case SPEED_CONTROL_AS_RATIO: xmix_speed_control_style = SPEED_CONTROL_AS_SEMITONE; break; case SPEED_CONTROL_AS_SEMITONE: xmix_speed_control_style = SPEED_CONTROL_AS_FLOAT; break; } speed_changed(mix_speed_from_id(mix_dialog_id), speed_number_buffer, xmix_speed_control_style, speed_control_tones(ss), 6); set_label(w_speed_number, speed_number_buffer); } static void mix_speed_drag_callback(Widget w, XtPointer context, XtPointer info) { int ival; mus_float_t speed; mus_long_t beg, end; if (!(mix_is_active(mix_dialog_id))) return; ival = ((XmScrollBarCallbackStruct *)info)->value; if (!dragging) start_dragging(mix_dialog_id); else keep_dragging(mix_dialog_id); speed = set_speed_label(w_speed_number, ival); mix_set_speed_edit(mix_dialog_id, speed); beg = mix_position_from_id(mix_dialog_id); end = beg + mix_length_from_id(mix_dialog_id); if (drag_beg > beg) drag_beg = beg; if (drag_end < end) drag_end = end; mix_display_during_drag(mix_dialog_id, drag_beg, drag_end); syncd_mix_set_speed(mix_dialog_id, speed); } static void mix_speed_valuechanged_callback(Widget w, XtPointer context, XtPointer info) { XmScrollBarCallbackStruct *cb = (XmScrollBarCallbackStruct *)info; mus_float_t speed; if (!(mix_is_active(mix_dialog_id))) return; if (dragging) stop_dragging(mix_dialog_id); speed = set_speed_label(w_speed_number, cb->value); mix_set_speed_edit(mix_dialog_id, speed); syncd_mix_set_speed(mix_dialog_id, speed); after_mix_edit(mix_dialog_id); after_syncd_mix_edit(mix_dialog_id); } /* -------- amp -------- */ static Widget w_amp_number, w_amp_label, w_amp; static mus_float_t scrollbar_to_amp(int val) { if (val <= 0) return(amp_control_min(ss)); if (val >= (0.9 * SCROLLBAR_MAX)) return(amp_control_max(ss)); if (val > (0.5 * 0.9 * SCROLLBAR_MAX)) return((((val / (0.5 * 0.9 * SCROLLBAR_MAX)) - 1.0) * (amp_control_max(ss) - 1.0)) + 1.0); else return((val * (1.0 - amp_control_min(ss)) / (0.5 * 0.9 * SCROLLBAR_MAX)) + amp_control_min(ss)); } static int amp_to_scrollbar(Widget amp_number, mus_float_t amp) { char sfs[6]; snprintf(sfs, 6, "%.2f", amp); set_label(amp_number, sfs); return(amp_to_scroll(amp_control_min(ss), amp, amp_control_max(ss))); } static void change_mix_amp(int mix_id, mus_float_t val) { char sfs[6]; mix_set_amp_edit(mix_id, val); syncd_mix_set_amp(mix_id, val); snprintf(sfs, 6, "%.2f", val); set_label(w_amp_number, sfs); } static void mix_amp_click_callback(Widget w, XtPointer context, XtPointer info) { if (!(mix_is_active(mix_dialog_id))) return; change_mix_amp(mix_dialog_id, 1.0); after_mix_edit(mix_dialog_id); XtVaSetValues(w_amp, XmNvalue, amp_to_scroll(amp_control_min(ss), 1.0, amp_control_max(ss)), NULL); } static void mix_amp_drag_callback(Widget w, XtPointer context, XtPointer info) { int ival; if (!(mix_is_active(mix_dialog_id))) return; ival = ((XmScrollBarCallbackStruct *)info)->value; if (!dragging) start_dragging(mix_dialog_id); else keep_dragging(mix_dialog_id); change_mix_amp(mix_dialog_id, scrollbar_to_amp(ival)); mix_display_during_drag(mix_dialog_id, drag_beg, drag_end); } static void mix_amp_valuechanged_callback(Widget w, XtPointer context, XtPointer info) { int ival; if (!(mix_is_active(mix_dialog_id))) return; ival = ((XmScrollBarCallbackStruct *)info)->value; if (dragging) stop_dragging(mix_dialog_id); change_mix_amp(mix_dialog_id, scrollbar_to_amp(ival)); after_mix_edit(mix_dialog_id); after_syncd_mix_edit(mix_dialog_id); } /* -------- amp-env -------- */ static Widget w_env_frame, w_env; static graphics_context *ax = NULL; static GC cur_gc; static env_editor *spf = NULL; static bool with_mix_background_wave = false; static void show_mix_background_wave(int mix_id) { int pts; bool two_sided = false; if (spf == NULL) return; pts = prepare_mix_dialog_waveform(mix_id, spf->axis, &two_sided); if (pts > 0) { XSetForeground(MAIN_DISPLAY(ss), ax->gc, ss->enved_waveform_color); if (two_sided) draw_both_grf_points(1, ax, pts, GRAPH_LINES); else draw_grf_points(1, ax, pts, spf->axis, ungrf_y(spf->axis, 0.0), GRAPH_LINES); XSetForeground(MAIN_DISPLAY(ss), ax->gc, ss->black); } } static void mix_amp_env_resize(Widget w, XtPointer context, XtPointer info) { env *cur_env; if (!(mix_is_active(mix_dialog_id))) return; if (ax == NULL) { XGCValues gv; gv.function = GXcopy; XtVaGetValues(w_env, XmNbackground, &gv.background, XmNforeground, &gv.foreground, NULL); cur_gc = XtGetGC(w_env, GCForeground | GCFunction, &gv); ax = (graphics_context *)calloc(1, sizeof(graphics_context)); ax->wn = XtWindow(w_env); ax->dp = XtDisplay(w_env); ax->gc = cur_gc; } else clear_window(ax); cur_env = dialog_env; spf->with_dots = true; env_editor_display_env(spf, cur_env, ax, "mix env", 0, 0, widget_width(w), widget_height(w), NOT_PRINTING); if (with_mix_background_wave) show_mix_background_wave(mix_dialog_id); } #ifdef __APPLE__ static int press_x, press_y; #endif static void mix_drawer_button_motion(Widget w, XtPointer context, XEvent *event, Boolean *cont) { XMotionEvent *ev = (XMotionEvent *)event; if (!(mix_is_active(mix_dialog_id))) return; #ifdef __APPLE__ if ((press_x == ev->x) && (press_y == ev->y)) return; #endif env_editor_button_motion(spf, ev->x, ev->y, ev->time, dialog_env); mix_amp_env_resize(w, NULL, NULL); } static void mix_drawer_button_press(Widget w, XtPointer context, XEvent *event, Boolean *cont) { XButtonEvent *ev = (XButtonEvent *)event; if (!(mix_is_active(mix_dialog_id))) return; #ifdef __APPLE__ press_x = ev->x; press_y = ev->y; #endif if (env_editor_button_press(spf, ev->x, ev->y, ev->time, dialog_env)) mix_amp_env_resize(w, NULL, NULL); } static void mix_drawer_button_release(Widget w, XtPointer context, XEvent *event, Boolean *cont) { if (!(mix_is_active(mix_dialog_id))) return; env_editor_button_release(spf, dialog_env); mix_amp_env_resize(w, NULL, NULL); } static Widget w_id = NULL, w_beg = NULL; #if WITH_AUDIO static Widget mix_play = NULL; #endif static Widget error_frame = NULL, error_label = NULL; static void clear_mix_error(void) { if ((error_frame) && (XtIsManaged(error_frame))) XtUnmanageChild(error_frame); } static void unpost_mix_error(XtPointer data, XtIntervalId *id) { clear_mix_error(); } static void errors_to_mix_text(const char *msg, void *data) { int lines = 0; XmString label; label = multi_line_label(msg, &lines); XtVaSetValues(error_label, XmNlabelString, label, XmNheight, lines * 20, NULL); XtVaSetValues(error_frame, XmNheight, lines * 20, NULL); XmStringFree(label); XtManageChild(error_frame); /* since the offending text is automatically overwritten, we can't depend on subsequent text modify callbacks * to clear things, so we'll just use a timer */ XtAppAddTimeOut(MAIN_APP(ss), 5000, (XtTimerCallbackProc)unpost_mix_error, NULL); } static void widget_mix_to_text(Widget w, int id) { if (mix_name(id)) XmTextFieldSetString(w, (char *)mix_name(id)); else widget_int_to_text(w, id); } static bool id_changed = false; static void id_activated(void) { char *val; id_changed = false; val = XmTextGetString(w_id); if (val) { int id; /* look for a mix name first, then a number */ id = mix_name_to_id(val); if (id < 0) { redirect_errors_to(errors_to_mix_text, NULL); id = string_to_int(val, 0, "id"); redirect_errors_to(NULL, NULL); } if (mix_is_active(id)) { mix_dialog_id = id; reflect_mix_change(id); } XtFree(val); } } static void id_modify_callback(Widget w, XtPointer context, XtPointer info) { id_changed = true; } static void id_check_callback(Widget w, XtPointer context, XtPointer info) { if (id_changed) id_activated(); } static void beg_activated(void) { char *val; if (!(mix_is_active(mix_dialog_id))) return; val = XmTextGetString(w_beg); if (val) { chan_info *cp; char *up_to_colon; mus_float_t beg; cp = mix_chan_info_from_id(mix_dialog_id); up_to_colon = string_to_colon(val); redirect_errors_to(errors_to_mix_text, NULL); beg = string_to_mus_float_t(up_to_colon, 0.0, "begin time"); redirect_errors_to(NULL, NULL); if (beg >= 0.0) { mus_long_t pos, old_pos; old_pos = mix_position_from_id(mix_dialog_id); pos = (mus_long_t)(beg * snd_srate(cp->sound)); mix_set_position_edit(mix_dialog_id, pos); syncd_mix_change_position(mix_dialog_id, pos - old_pos); } after_mix_edit(mix_dialog_id); free(up_to_colon); XtFree(val); } } static void apply_mix_dialog_callback(Widget w, XtPointer context, XtPointer info) { if (!(mix_is_active(mix_dialog_id))) return; if ((dialog_env) && (!(is_default_env(dialog_env)))) { mix_set_amp_env_edit(mix_dialog_id, dialog_env); syncd_mix_set_amp_env(mix_dialog_id, dialog_env); } else { mix_set_amp_env_edit(mix_dialog_id, NULL); syncd_mix_set_amp_env(mix_dialog_id, NULL); } mix_amp_env_resize(w_env, NULL, NULL); after_mix_edit(mix_dialog_id); } static void copy_mix_dialog_callback(Widget w, XtPointer context, XtPointer info) { Widget active_widget; active_widget = XmGetFocusWidget(mix_dialog); if (active_widget == XmMessageBoxGetChild(mix_dialog, XmDIALOG_OK_BUTTON)) { copy_mix(mix_dialog_id); after_mix_edit(mix_dialog_id); } else { if (active_widget == w_id) id_activated(); else { if (active_widget == w_beg) beg_activated(); } } } static void quit_mix_dialog_callback(Widget w, XtPointer context, XtPointer info) { clear_mix_error(); XtUnmanageChild(mix_dialog); } static void help_mix_dialog_callback(Widget w, XtPointer context, XtPointer info) { mix_dialog_help(); } /* -------- play -------- */ #if WITH_AUDIO static bool mix_playing = false; #endif void reflect_mix_play_stop(void) { #if WITH_AUDIO if (mix_play) XmChangeColor(mix_play, ss->basic_color); mix_playing = false; #endif } #if WITH_AUDIO static void mix_dialog_play_callback(Widget w, XtPointer context, XtPointer info) { if (mix_playing) reflect_mix_play_stop(); else { if (!(mix_exists(mix_dialog_id))) return; if (mix_play) XmChangeColor(mix_play, ss->selection_color); /* this needs to happen before trying to play */ syncd_mix_play(mix_dialog_id); mix_playing = true; /* don't use the return value here */ play_mix_from_id(mix_dialog_id); } } #endif /* -------- dB -------- */ static void mix_dB_callback(Widget w, XtPointer context, XtPointer info) { XmToggleButtonCallbackStruct *cb = (XmToggleButtonCallbackStruct *)info; spf->in_dB = cb->set; mix_amp_env_resize(w_env, NULL, NULL); } /* -------- sync -------- */ static void mix_sync_callback(Widget w, XtPointer context, XtPointer info) { XmToggleButtonCallbackStruct *cb = (XmToggleButtonCallbackStruct *)info; if ((cb->set) && (mix_sync_from_id(mix_dialog_id) == 0)) { mix_set_sync_from_id(mix_dialog_id, GET_ORIGINAL_SYNC); /* choose a new sync val or return to previous */ /* check for resync */ syncd_mix_set_color(mix_dialog_id, ss->red); } else { if ((!(cb->set)) && (mix_sync_from_id(mix_dialog_id) != 0)) { syncd_mix_unset_color(mix_dialog_id); /* unset colors of any syncd mixes */ mix_set_sync_from_id(mix_dialog_id, 0); } } for_each_normal_chan(display_channel_mixes); } /* -------- clip -------- */ static void mix_clip_callback(Widget w, XtPointer context, XtPointer info) { XmToggleButtonCallbackStruct *cb = (XmToggleButtonCallbackStruct *)info; spf->clipping = cb->set; mix_amp_env_resize(w_env, NULL, NULL); } /* -------- wave -------- */ static void mix_wave_callback(Widget w, XtPointer context, XtPointer info) { XmToggleButtonCallbackStruct *cb = (XmToggleButtonCallbackStruct *)info; with_mix_background_wave = cb->set; mix_amp_env_resize(w_env, NULL, NULL); } /* -------- next/previous -------- */ static Widget mix_next_button, mix_previous_button; static void mix_next_callback(Widget w, XtPointer context, XtPointer info) { int id; clear_mix_error(); id = next_mix_id(mix_dialog_id); if (id != INVALID_MIX_ID) { mix_dialog_id = id; reflect_mix_change(id); if (next_mix_id(id) == INVALID_MIX_ID) set_sensitive(mix_next_button, false); } } static void mix_previous_callback(Widget w, XtPointer context, XtPointer info) { int id; clear_mix_error(); id = previous_mix_id(mix_dialog_id); if (id != INVALID_MIX_ID) { mix_dialog_id = id; reflect_mix_change(id); if (previous_mix_id(id) == INVALID_MIX_ID) set_sensitive(mix_previous_button, false); } } static Pixmap make_pixmap(unsigned char *bits, int width, int height, int depth, GC gc) { Pixmap rb, nr; rb = XCreateBitmapFromData(MAIN_DISPLAY(ss), RootWindowOfScreen(XtScreen(MAIN_PANE(ss))), (const char *)bits, width, height); nr = XCreatePixmap(MAIN_DISPLAY(ss), RootWindowOfScreen(XtScreen(MAIN_PANE(ss))), width, height, depth); XCopyPlane(MAIN_DISPLAY(ss), rb, nr, gc, 0, 0, width, height, 0, 0, 1); XFreePixmap(MAIN_DISPLAY(ss), rb); return(nr); } #define p_speaker_width 12 #define p_speaker_height 12 static unsigned char p_speaker_bits[] = { 0x00, 0x07, 0xc0, 0x04, 0x30, 0x04, 0x0e, 0x04, 0x06, 0x04, 0x06, 0x04, 0x06, 0x04, 0x06, 0x04, 0x0e, 0x04, 0x30, 0x04, 0xc0, 0x04, 0x00, 0x07}; static int mixer_depth; static GC gc; static Pixmap speaker_r; void make_mixer_icons_transparent_again(Pixel old_color, Pixel new_color) { if (mix_dialog) { XFreePixmap(XtDisplay(mix_dialog), speaker_r); XSetBackground(XtDisplay(mix_dialog), gc, new_color); speaker_r = make_pixmap(p_speaker_bits, p_speaker_width, p_speaker_height, mixer_depth, gc); #if WITH_AUDIO XtVaSetValues(mix_play, XmNlabelPixmap, speaker_r, NULL); #endif } } static Widget w_sync; Widget make_mix_dialog(void) { if (mix_dialog == NULL) { Widget mainform, mix_row, mix_frame, sep, w_sep1; Widget w_dB_frame, w_dB, w_clip, w_wave, w_dB_row, env_button, copy_button; XmString xgo_away, xhelp, xtitle, s1, xcopy; int n; Arg args[20]; XtCallbackList n1, n2; XGCValues v; char amplab[LABEL_BUFFER_SIZE]; xmix_speed_control_style = speed_control_style(ss); mix_dialog_id = any_mix_id(); xgo_away = XmStringCreateLocalized((char *)I_GO_AWAY); xcopy = XmStringCreateLocalized((char *)"Copy mix"); xhelp = XmStringCreateLocalized((char *)I_HELP); xtitle = XmStringCreateLocalized((char *)"Mixes"); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNokLabelString, xcopy); n++; XtSetArg(args[n], XmNcancelLabelString, xgo_away); n++; XtSetArg(args[n], XmNhelpLabelString, xhelp); n++; XtSetArg(args[n], XmNautoUnmanage, false); n++; XtSetArg(args[n], XmNdialogTitle, xtitle); n++; XtSetArg(args[n], XmNresizePolicy, XmRESIZE_GROW); n++; XtSetArg(args[n], XmNnoResize, false); n++; XtSetArg(args[n], XmNtransient, false); n++; mix_dialog = XmCreateTemplateDialog(MAIN_SHELL(ss), (char *)"Mixes", args, n); copy_button = XmMessageBoxGetChild(mix_dialog, XmDIALOG_OK_BUTTON); /* XtAddCallback(mix_dialog, XmNokCallback, copy_mix_dialog_callback, NULL); */ XtAddCallback(copy_button, XmNactivateCallback, copy_mix_dialog_callback, NULL); XtAddCallback(mix_dialog, XmNcancelCallback, quit_mix_dialog_callback, NULL); XtAddCallback(mix_dialog, XmNhelpCallback, help_mix_dialog_callback, NULL); XmStringFree(xhelp); XmStringFree(xcopy); XmStringFree(xgo_away); XmStringFree(xtitle); XtVaSetValues(XmMessageBoxGetChild(mix_dialog, XmDIALOG_CANCEL_BUTTON), XmNarmColor, ss->selection_color, NULL); XtVaSetValues(XmMessageBoxGetChild(mix_dialog, XmDIALOG_OK_BUTTON), XmNarmColor, ss->selection_color, NULL); XtVaSetValues(XmMessageBoxGetChild(mix_dialog, XmDIALOG_HELP_BUTTON), XmNarmColor, ss->selection_color, NULL); XtVaSetValues(XmMessageBoxGetChild(mix_dialog, XmDIALOG_CANCEL_BUTTON), XmNbackground, ss->highlight_color, NULL); XtVaSetValues(XmMessageBoxGetChild(mix_dialog, XmDIALOG_OK_BUTTON), XmNbackground, ss->highlight_color, NULL); XtVaSetValues(XmMessageBoxGetChild(mix_dialog, XmDIALOG_HELP_BUTTON), XmNbackground, ss->highlight_color, NULL); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNarmColor, ss->selection_color); n++; env_button = XtCreateManagedWidget("Apply env", xmPushButtonGadgetClass, mix_dialog, args, n); XtAddCallback(env_button, XmNactivateCallback, apply_mix_dialog_callback, NULL); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNbottomWidget, XmMessageBoxGetChild(mix_dialog, XmDIALOG_SEPARATOR)); n++; mainform = XtCreateManagedWidget("formd", xmFormWidgetClass, mix_dialog, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNallowResize, true); n++; XtSetArg(args[n], XmNshadowType, XmSHADOW_ETCHED_IN); n++; XtSetArg(args[n], XmNshadowThickness, 2); n++; mix_frame = XtCreateManagedWidget("mix-frame", xmFrameWidgetClass, mainform, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; mix_row = XtCreateManagedWidget("mix-dialog-row", xmRowColumnWidgetClass, mix_frame, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtCreateManagedWidget("mix:", xmLabelWidgetClass, mix_row, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNresizeWidth, false); n++; XtSetArg(args[n], XmNcolumns, NAME_COLUMNS); n++; XtSetArg(args[n], XmNrecomputeSize, false); n++; w_id = make_textfield_widget("mix-id", mix_row, args, n, ACTIVATABLE, NO_COMPLETER); XtAddCallback(w_id, XmNlosingFocusCallback, id_check_callback, NULL); XtAddCallback(w_id, XmNmodifyVerifyCallback, id_modify_callback, NULL); XmTextSetString(w_id, (char *)"0"); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; w_beg = make_textfield_widget("mix-times", mix_row, args, n, ACTIVATABLE, NO_COMPLETER); XmTextSetString(w_beg, (char *)"0.000 : 1.000"); XtVaGetValues(mix_row, XmNforeground, &v.foreground, XmNbackground, &v.background, XmNdepth, &mixer_depth, NULL); gc = XtGetGC(mix_row, GCForeground | GCBackground, &v); speaker_r = make_pixmap(p_speaker_bits, p_speaker_width, p_speaker_height, mixer_depth, gc); #if WITH_AUDIO n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNlabelType, XmPIXMAP); n++; XtSetArg(args[n], XmNlabelPixmap, speaker_r); n++; XtSetArg(args[n], XmNarmColor, ss->selection_color); n++; mix_play = XtCreateManagedWidget("mix-play", xmPushButtonWidgetClass, mix_row, args, n); XtAddCallback(mix_play, XmNactivateCallback, mix_dialog_play_callback, NULL); #endif n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNarmColor, ss->selection_color); n++; mix_previous_button = XtCreateManagedWidget(I_PREVIOUS, xmPushButtonWidgetClass, mix_row, args, n); if (previous_mix_id(mix_dialog_id) == INVALID_MIX_ID) set_sensitive(mix_previous_button, false); XtAddCallback(mix_previous_button, XmNactivateCallback, mix_previous_callback, NULL); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNarmColor, ss->selection_color); n++; mix_next_button = XtCreateManagedWidget(I_NEXT, xmPushButtonWidgetClass, mix_row, args, n); if (next_mix_id(mix_dialog_id) == INVALID_MIX_ID) set_sensitive(mix_next_button, false); XtAddCallback(mix_next_button, XmNactivateCallback, mix_next_callback, NULL); /* separator before sliders */ n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, mix_row); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNheight, 10); n++; XtSetArg(args[n], XmNseparatorType, XmNO_LINE); n++; sep = XtCreateManagedWidget("mix-dialog-sep", xmSeparatorWidgetClass, mainform, args, n); /* SPEED */ n = 0; s1 = XmStringCreateLocalized((char *)"speed:"); XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, sep); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNlabelString, s1); n++; XtSetArg(args[n], XmNrecomputeSize, false); n++; XtSetArg(args[n], XmNshadowThickness, 0); n++; XtSetArg(args[n], XmNhighlightThickness, 0); n++; XtSetArg(args[n], XmNfillOnArm, false); n++; w_speed_label = make_pushbutton_widget("mix-speed-label", mainform, args, n); XtAddCallback(w_speed_label, XmNactivateCallback, mix_speed_click_callback, NULL); XmStringFree(s1); n = 0; s1 = initial_speed_label(xmix_speed_control_style); XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, w_speed_label); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, w_speed_label); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNlabelString, s1); n++; XtSetArg(args[n], XmNrecomputeSize, false); n++; XtSetArg(args[n], XmNshadowThickness, 0); n++; XtSetArg(args[n], XmNhighlightThickness, 0); n++; XtSetArg(args[n], XmNfillOnArm, false); n++; w_speed_number = make_pushbutton_widget("mix-speed-number", mainform, args, n); XtAddCallback(w_speed_number, XmNactivateCallback, mix_speed_label_click_callback, NULL); XmStringFree(s1); n = 0; XtSetArg(args[n], XmNbackground, ss->position_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, w_speed_number); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, w_speed_number); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNmaximum, SCROLLBAR_MAX); n++; XtSetArg(args[n], XmNvalue, speed_to_scrollbar(speed_control_min(ss), 1.0, speed_control_max(ss))); n++; XtSetArg(args[n], XmNheight, 16); n++; XtSetArg(args[n], XmNdragCallback, n1 = make_callback_list(mix_speed_drag_callback, NULL)); n++; XtSetArg(args[n], XmNvalueChangedCallback, n2 = make_callback_list(mix_speed_valuechanged_callback, NULL)); n++; w_speed = XtCreateManagedWidget("mix-speed", xmScrollBarWidgetClass, mainform, args, n); free(n1); free(n2); n = 0; snprintf(amplab, LABEL_BUFFER_SIZE, "%s", "amp:"); s1 = XmStringCreateLocalized(amplab); XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, w_speed_label); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNlabelString, s1); n++; XtSetArg(args[n], XmNrecomputeSize, false); n++; XtSetArg(args[n], XmNshadowThickness, 0); n++; XtSetArg(args[n], XmNhighlightThickness, 0); n++; XtSetArg(args[n], XmNfillOnArm, false); n++; w_amp_label = make_pushbutton_widget("mix-amp-label", mainform, args, n); XtAddCallback(w_amp_label, XmNactivateCallback, mix_amp_click_callback, NULL); XmStringFree(s1); n = 0; s1 = XmStringCreateLocalized((char *)"1.00"); XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, w_speed_number); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, w_amp_label); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNlabelString, s1); n++; XtSetArg(args[n], XmNrecomputeSize, false); n++; w_amp_number = XtCreateManagedWidget("mix-amp-number", xmLabelWidgetClass, mainform, args, n); XmStringFree(s1); n = 0; XtSetArg(args[n], XmNbackground, ss->position_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, w_amp_number); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, w_amp_number); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNmaximum, SCROLLBAR_MAX); n++; XtSetArg(args[n], XmNvalue, 0); n++; XtSetArg(args[n], XmNdragCallback, n1 = make_callback_list(mix_amp_drag_callback, NULL)); n++; XtSetArg(args[n], XmNvalueChangedCallback, n2 = make_callback_list(mix_amp_valuechanged_callback, NULL)); n++; w_amp = XtCreateManagedWidget("mix-amp", xmScrollBarWidgetClass, mainform, args, n); free(n1); free(n2); /* separator before envelopes */ n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, w_amp_label); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNheight, 8); n++; XtSetArg(args[n], XmNseparatorType, XmNO_LINE); n++; w_sep1 = XtCreateManagedWidget("mix-dialog-sep1", xmSeparatorWidgetClass, mainform, args, n); /* button box for dB clip wave sync */ n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, w_sep1); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNshadowType, XmSHADOW_ETCHED_IN); n++; XtSetArg(args[n], XmNshadowThickness, 4); n++; w_dB_frame = XtCreateManagedWidget("mix-dB-frame", xmFrameWidgetClass, mainform, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; w_dB_row = XtCreateManagedWidget("mix-dB-row", xmRowColumnWidgetClass, w_dB_frame, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNselectColor, ss->selection_color); n++; if (ss->toggle_size > 0) {XtSetArg(args[n], XmNindicatorSize, ss->toggle_size); n++;} w_clip = make_togglebutton_widget("clip", w_dB_row, args, n); XtAddCallback(w_clip, XmNvalueChangedCallback, mix_clip_callback, NULL); XmToggleButtonSetState(w_clip, true, false); w_wave = make_togglebutton_widget("wave", w_dB_row, args, n); XtAddCallback(w_wave, XmNvalueChangedCallback, mix_wave_callback, NULL); w_dB = make_togglebutton_widget("dB", w_dB_row, args, n); XtAddCallback(w_dB, XmNvalueChangedCallback, mix_dB_callback, NULL); if (mix_sync_from_id(mix_dialog_id) != 0) {XtSetArg(args[n], XmNset, true); n++;} w_sync = make_togglebutton_widget("sync", w_dB_row, args, n); XtAddCallback(w_sync, XmNvalueChangedCallback, mix_sync_callback, NULL); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNallowResize, true); n++; XtSetArg(args[n], XmNshadowType, XmSHADOW_ETCHED_IN); n++; XtSetArg(args[n], XmNshadowThickness, 2); n++; error_frame = XtCreateManagedWidget("error-frame", xmFrameWidgetClass, mainform, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; error_label = XtCreateManagedWidget("", xmLabelWidgetClass, error_frame, args, n); /* amp env */ n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, w_sep1); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_POSITION); n++; XtSetArg(args[n], XmNleftPosition, 4); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNrightWidget, w_dB_frame); n++; XtSetArg(args[n], XmNallowResize, true); n++; XtSetArg(args[n], XmNshadowType, XmSHADOW_ETCHED_IN); n++; XtSetArg(args[n], XmNshadowThickness, 4); n++; w_env_frame = XtCreateManagedWidget("mix-amp-env-frame", xmFrameWidgetClass, mainform, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNallowResize, true); n++; w_env = XtCreateManagedWidget("mix-amp-env-window", xmDrawingAreaWidgetClass, w_env_frame, args, n); XtManageChild(mix_dialog); XtAddCallback(w_env, XmNresizeCallback, mix_amp_env_resize, NULL); XtAddCallback(w_env, XmNexposeCallback, mix_amp_env_resize, NULL); spf = new_env_editor(); XtAddEventHandler(w_env, ButtonPressMask, false, mix_drawer_button_press, NULL); XtAddEventHandler(w_env, ButtonMotionMask, false, mix_drawer_button_motion, NULL); XtAddEventHandler(w_env, ButtonReleaseMask, false, mix_drawer_button_release, NULL); set_dialog_widget(MIX_DIALOG, mix_dialog); XtUnmanageChild(error_frame); } else { if (!(XtIsManaged(mix_dialog))) XtManageChild(mix_dialog); raise_dialog(mix_dialog); } reflect_mix_change(mix_dialog_id); return(mix_dialog); } void reflect_mix_change(int mix_id) { if ((mix_dialog) && (XtIsManaged(mix_dialog))) { if (mix_id != ANY_MIX_ID) mix_dialog_id = mix_id; if (!(mix_exists(mix_dialog_id))) { mix_dialog_id = any_mix_id(); mix_id = mix_dialog_id; } if ((mix_id == mix_dialog_id) || (mix_id == ANY_MIX_ID)) { mus_float_t val; set_sensitive(mix_next_button, (next_mix_id(mix_dialog_id) != INVALID_MIX_ID)); set_sensitive(mix_previous_button, (previous_mix_id(mix_dialog_id) != INVALID_MIX_ID)); /* now reflect current mix state in mix dialog controls */ if (mix_exists(mix_dialog_id)) { chan_info *cp = NULL; mus_long_t beg, len; char lab[LABEL_BUFFER_SIZE]; /* syncd mixes have the same color (red) reverting to old color when sync changes */ cp = mix_chan_info_from_id(mix_dialog_id); if (old_mix_dialog_id != INVALID_MIX_ID) { mix_unset_color_from_id(old_mix_dialog_id); syncd_mix_unset_color(old_mix_dialog_id); } old_mix_dialog_id = mix_dialog_id; mix_set_color_from_id(mix_dialog_id, ss->red); syncd_mix_set_color(mix_dialog_id, ss->red); for_each_normal_chan(display_channel_mixes); if (!dragging) { val = mix_speed_from_id(mix_dialog_id); XtVaSetValues(w_speed, XmNvalue, speed_to_scrollbar(speed_control_min(ss), val, speed_control_max(ss)), NULL); speed_changed(val, lab, xmix_speed_control_style, speed_control_tones(ss), 6); set_label(w_speed_number, lab); } widget_mix_to_text(w_id, mix_dialog_id); beg = mix_position_from_id(mix_dialog_id); len = mix_length_from_id(mix_dialog_id); snprintf(lab, LABEL_BUFFER_SIZE, "%.3f : %.3f%s", (float)((double)beg / (float)snd_srate(cp->sound)), (float)((double)(beg + len) / (float)snd_srate(cp->sound)), (mix_is_active(mix_dialog_id)) ? "" : " (locked)"); XmTextSetString(w_beg, lab); set_sensitive(XmMessageBoxGetChild(mix_dialog, XmDIALOG_OK_BUTTON), true); } else { XmTextSetString(w_id, (char *)"-1"); XmTextSetString(w_beg, (char *)"no active mixes"); set_sensitive(XmMessageBoxGetChild(mix_dialog, XmDIALOG_OK_BUTTON), false); } if (!dragging) { if (mix_is_active(mix_dialog_id)) val = mix_amp_from_id(mix_dialog_id); else val = 1.0; XtVaSetValues(w_amp, XmNvalue, amp_to_scrollbar(w_amp_number, val), NULL); } if (mix_amp_env_from_id(mix_dialog_id)) { if (dialog_env) free_env(dialog_env); dialog_env = copy_env(mix_amp_env_from_id(mix_dialog_id)); } /* copy here else we're editing it directly afterwards (and we free old in mix_set_amp_env_edit) */ if (!dialog_env) dialog_env = default_env(1.0, 1.0); mix_amp_env_resize(w_env, NULL, NULL); set_toggle_button(w_sync, (mix_sync_from_id(mix_dialog_id) != 0), false, NULL); } } } int mix_dialog_mix(void) { return(mix_dialog_id); } void mix_dialog_set_mix(int id) { mix_dialog_id = id; reflect_mix_change(mix_dialog_id); } /* envelope editor and viewer */ static Widget enved_dialog = NULL; static Widget apply_button, apply2_button, cancel_button, drawer, show_button, save_button, revert_button, undo_button, redo_button; static Widget brkptL, graph_button, flt_button, amp_button, src_button, clip_button; static Widget nameL, textL, screnvlst, dB_button, orderL, reset_button, fir_button = NULL; static Widget baseScale, baseValue, selection_button; static GC gc1, rgc, ggc; static const char *env_names[3] = {"amp env:", "flt env:", "src env:"}; static bool showing_all_envs = false; /* edit one env (0), or view all currently defined envs (1) */ static bool apply_to_selection = false, we_turned_selection_off = false; static int env_window_width = 0; static int env_window_height = 0; static chan_info *active_channel = NULL, *last_active_channel = NULL; static env* selected_env = NULL; /* if during view, one env is clicked, it is "selected" and can be pasted elsewhere */ static env* active_env = NULL; /* env currently being edited */ static axis_info *axis = NULL; static axis_info *gray_ap = NULL; static bool is_FIR = true; static bool old_clipping = false; static bool ignore_button_release = false; static bool cancelling = true; static void fixup_graphics_context(graphics_context *ax, Widget w, GC gc) { ax->dp = XtDisplay(w); ax->wn = XtWindow(w); if (gc) ax->gc = gc; } axis_info *enved_make_axis(const char *name, graphics_context *ax, int ex0, int ey0, int width, int height, mus_float_t xmin, mus_float_t xmax, mus_float_t ymin, mus_float_t ymax, printing_t printing) { /* conjure up minimal context for axis drawer in snd-axis.c */ if (!axis) { axis = (axis_info *)calloc(1, sizeof(axis_info)); axis->ax = (graphics_context *)calloc(1, sizeof(graphics_context)); fixup_graphics_context(axis->ax, drawer, ax->gc); } if (!gray_ap) { gray_ap = (axis_info *)calloc(1, sizeof(axis_info)); gray_ap->ax = (graphics_context *)calloc(1, sizeof(graphics_context)); gray_ap->graph_active = true; fixup_graphics_context(gray_ap->ax, drawer, ggc); } init_env_axes(axis, name, ex0, ey0, width, height, xmin, xmax, ymin, ymax, printing); return(axis); } static void display_env(env *e, const char *name, GC cur_gc, int x0, int y0, int width, int height, bool dots, printing_t printing) { graphics_context *ax = NULL; ax = (graphics_context *)calloc(1, sizeof(graphics_context)); ax->wn = XtWindow(drawer); if (!(ax->wn)) {free(ax); return;} ax->dp = XtDisplay(drawer); ax->gc = cur_gc; ss->enved->with_dots = dots; env_editor_display_env(ss->enved, e, ax, name, x0, y0, width, height, printing); free(ax); } void display_enved_env_with_selection(env *e, const char *name, int x0, int y0, int width, int height, bool dots, printing_t printing) { display_env(e, name, (selected_env == e) ? rgc : gc1, x0, y0, width, height, dots, printing); } static void reflect_segment_state(void) { if ((enved_dialog) && (active_env) && (!(showing_all_envs))) env_redisplay(); } static void prepare_env_edit(env *new_env) { prepare_enved_edit(new_env); if (new_env->base == 1.0) set_enved_style(ENVELOPE_LINEAR); else { set_enved_base(new_env->base); set_enved_style(ENVELOPE_EXPONENTIAL); } reflect_segment_state(); } void set_enved_redo_sensitive(bool val) {set_sensitive(redo_button, val);} void set_enved_revert_sensitive(bool val) {set_sensitive(revert_button, val);} void set_enved_undo_sensitive(bool val) {set_sensitive(undo_button, val);} void set_enved_save_sensitive(bool val) {set_sensitive(save_button, val);} void set_enved_show_sensitive(bool val) {set_sensitive(show_button, val);} static bool use_listener_font = false; void make_scrolled_env_list(void) { XmString *strs; int n, size; size = enved_all_envs_top(); XtVaSetValues(screnvlst, XmNbackground, ss->highlight_color, NULL); strs = (XmString *)calloc(size, sizeof(XmString)); for (n = 0; n < size; n++) strs[n] = XmStringCreate(enved_all_names(n), (char *)((use_listener_font) ? "listener_font" : XmFONTLIST_DEFAULT_TAG)); XtVaSetValues(screnvlst, XmNitems, strs, XmNitemCount, size, NULL); for (n = 0; n < size; n++) XmStringFree(strs[n]); free(strs); } void enved_reflect_peak_env_completion(snd_info *sp) { if ((enved_dialog) && (active_channel) && (enved_with_wave(ss))) if (active_channel->sound == sp) env_redisplay(); } void new_active_channel_alert(void) { if (enved_dialog) { /* if showing current active channel in gray, update */ active_channel = current_channel(); env_redisplay(); } } static void dismiss_enved_callback(Widget w, XtPointer context, XtPointer info) { if (!cancelling) { if (ss->checking_explicitly) ss->stopped_explicitly = true; } else XtUnmanageChild(enved_dialog); } static void help_enved_callback(Widget w, XtPointer context, XtPointer info) { envelope_editor_dialog_help(); } static bool within_selection_src = false; static void apply_enved(void) { if (active_env) { active_channel = current_channel(); if (active_channel) { int i, j; char *origin = NULL, *estr = NULL; env *max_env = NULL; set_sensitive(apply_button, false); set_sensitive(apply2_button, false); set_button_label(cancel_button, I_STOP); cancelling = false; check_for_event(); switch (enved_target(ss)) { case ENVED_AMPLITUDE: #if HAVE_FORTH origin = mus_format("%s%s %s drop", estr = env_to_string(active_env), (apply_to_selection) ? "" : " 0 " PROC_FALSE, (apply_to_selection) ? S_env_selection : S_env_channel); #else origin = mus_format("%s" PROC_OPEN "%s%s", to_proc_name((apply_to_selection) ? S_env_selection : S_env_channel), estr = env_to_string(active_env), (apply_to_selection) ? "" : PROC_SEP "0" PROC_SEP PROC_FALSE); #endif apply_env(active_channel, active_env, 0, current_samples(active_channel), apply_to_selection, origin, NULL, C_int_to_Xen_integer(AT_CURRENT_EDIT_POSITION), 0); /* calls update_graph, I think, but in short files that doesn't update the amp-env */ if (estr) free(estr); if (origin) free(origin); break; case ENVED_SPECTRUM: #if HAVE_FORTH origin = mus_format("%s %d%s %s drop", estr = env_to_string(active_env), enved_filter_order(ss), (apply_to_selection) ? "" : " 0 " PROC_FALSE, (apply_to_selection) ? S_filter_selection : S_filter_channel); #else origin = mus_format("%s" PROC_OPEN "%s" PROC_SEP "%d%s", to_proc_name((apply_to_selection) ? S_filter_selection : S_filter_channel), estr = env_to_string(active_env), enved_filter_order(ss), (apply_to_selection) ? "" : PROC_SEP "0" PROC_SEP PROC_FALSE); #endif apply_filter(active_channel, (is_FIR) ? enved_filter_order(ss) : 0, active_env, origin, NULL, apply_to_selection, NULL, NULL, C_int_to_Xen_integer(AT_CURRENT_EDIT_POSITION), 0, false); if (estr) free(estr); if (origin) free(origin); break; case ENVED_SRATE: /* mus_src no longer protects against 0 srate */ max_env = copy_env(active_env); for (i = 0, j = 1; i < max_env->pts; i++, j += 2) if (max_env->data[j] < .01) max_env->data[j] = .01; within_selection_src = true; src_env_or_num(active_channel, max_env, 0.0, false, "Enved: src", apply_to_selection, NULL, C_int_to_Xen_integer(AT_CURRENT_EDIT_POSITION), 0); within_selection_src = false; max_env = free_env(max_env); break; } if (enved_with_wave(ss)) env_redisplay(); set_sensitive(apply_button, true); set_sensitive(apply2_button, true); set_button_label(cancel_button, I_GO_AWAY); cancelling = true; } } } static void env_redisplay_1(printing_t printing) { if (enved_dialog_is_active()) { XClearWindow(XtDisplay(drawer), XtWindow(drawer)); if (showing_all_envs) view_envs(env_window_width, env_window_height, printing); else { char *name = NULL; name = XmTextGetString(textL); if (!name) name = mus_strdup("noname"); /* active_env can be null here if just showing axes (empty initial graph) */ if ((enved_with_wave(ss)) && (active_channel) && (!(active_channel->squelch_update))) { if ((enved_target(ss) == ENVED_SPECTRUM) && (active_env) && (is_FIR) && (printing == NOT_PRINTING)) display_frequency_response(active_env, axis, gray_ap->ax, enved_filter_order(ss), enved_in_dB(ss)); enved_show_background_waveform(axis, gray_ap, apply_to_selection, (enved_target(ss) == ENVED_SPECTRUM), printing); } display_env(active_env, name, gc1, 0, 0, env_window_width, env_window_height, true, printing); if (name) XtFree(name); } } } void env_redisplay(void) { env_redisplay_1(NOT_PRINTING); } void env_redisplay_with_print(void) { env_redisplay_1(PRINTING); } void update_enved_background_waveform(chan_info *cp) { if ((enved_dialog_is_active()) && (enved_with_wave(ss)) && (enved_target(ss) == ENVED_AMPLITUDE) && (cp == active_channel) && ((!apply_to_selection) || (selection_is_active_in_channel(cp)))) env_redisplay(); } static void enved_reset(void) { set_enved_clipping(DEFAULT_ENVED_CLIPPING); set_enved_style(ENVELOPE_LINEAR); set_enved_power(DEFAULT_ENVED_POWER); set_enved_base(DEFAULT_ENVED_BASE); set_enved_target(DEFAULT_ENVED_TARGET); set_enved_with_wave(DEFAULT_ENVED_WITH_WAVE); set_enved_in_dB(DEFAULT_ENVED_IN_DB); XmTextSetString(textL, NULL); set_enved_filter_order(DEFAULT_ENVED_FILTER_ORDER); if (active_env) active_env = free_env(active_env); #if HAVE_SCHEME active_env = string_to_env("'(0 0 1 0)"); #endif #if HAVE_FORTH active_env = string_to_env("'( 0 0 1 0 )"); #endif #if HAVE_RUBY active_env = string_to_env("[0, 0, 1, 0]"); #endif set_enved_env_list_top(0); prepare_env_edit(active_env); set_sensitive(save_button, true); reflect_enved_style(); env_redisplay(); } static void clear_point_label(void); static void clear_xenv_error(void) { if (brkptL) clear_point_label(); } static void unpost_xenv_error(XtPointer data, XtIntervalId *id) { clear_xenv_error(); } static void errors_to_xenv_text(const char *msg, void *data) { set_button_label(brkptL, msg); XtAppAddTimeOut(MAIN_APP(ss), 5000, (XtTimerCallbackProc)unpost_xenv_error, NULL); } static void order_field_activated(void) { /* return in order text field */ char *str = NULL; str = XmTextGetString(orderL); if ((str) && (*str)) { int order; redirect_errors_to(errors_to_xenv_text, NULL); order = string_to_int(str, 1, "order"); redirect_errors_to(NULL, NULL); if (order & 1) order++; if ((order > 0) && (order < 2000)) set_enved_filter_order(order); else widget_int_to_text(orderL, enved_filter_order(ss)); } if (str) XtFree(str); } static void text_field_activated(void) { /* might be breakpoints to load or an envelope name ( in enved text field) */ char *name = NULL; name = XmTextGetString(textL); if ((name) && (*name)) { char *str; env *e = NULL; str = name; while (isspace((int)(*str))) str++; e = name_to_env(str); if (!e) { if (isalpha((int)(str[0]))) { alert_envelope_editor(str, copy_env(active_env)); add_or_edit_symbol(str, active_env); set_sensitive(save_button, false); env_redisplay(); /* updates label */ /* e is null here */ } else { redirect_errors_to(errors_to_xenv_text, NULL); e = string_to_env(str); redirect_errors_to(NULL, NULL); } } if (e) { if (active_env) { #define ENVED_TEMP_NAME "enved-backup" /* save current under a temp name! -- user might have mistakenly reused a name */ alert_envelope_editor((char *)ENVED_TEMP_NAME, copy_env(active_env)); add_or_edit_symbol(ENVED_TEMP_NAME, active_env); active_env = free_env(active_env); } active_env = copy_env(e); set_enved_env_list_top(0); prepare_env_edit(active_env); set_sensitive(save_button, true); set_sensitive(undo_button, false); set_sensitive(revert_button, false); env_redisplay(); e = free_env(e); } } if (name) XtFree(name); } static void enved_text_activate_callback(Widget w, XtPointer context, XtPointer info) { text_field_activated(); } static void order_activate_callback(Widget w, XtPointer context, XtPointer info) { order_field_activated(); } static void save_button_pressed(Widget w, XtPointer context, XtPointer info) { char *name = NULL; if (active_env == NULL) return; name = XmTextGetString(textL); if ((!name) || (!(*name))) name = mus_strdup("unnamed"); alert_envelope_editor(name, copy_env(active_env)); add_or_edit_symbol(name, active_env); set_sensitive(save_button, false); env_redisplay(); if (name) XtFree(name); } static void apply_enved_callback(Widget w, XtPointer context, XtPointer info) { /* apply current envs to currently sync'd channels */ Widget active_widget; active_widget = XmGetFocusWidget(enved_dialog); if (active_widget == XmMessageBoxGetChild(enved_dialog, XmDIALOG_OK_BUTTON)) { apply_enved(); last_active_channel = active_channel; } } static void undo_and_apply_enved_callback(Widget w, XtPointer context, XtPointer info) { /* undo previous amp env, then apply */ /* this blindly undoes the previous edit (assumed to be an envelope) -- if the user made some other change in the meantime, too bad */ if ((active_channel) && (active_channel == last_active_channel)) { active_channel->squelch_update = true; undo_edit_with_sync(active_channel, 1); active_channel->squelch_update = false; clear_status_area(active_channel->sound); } apply_enved(); last_active_channel = active_channel; } static void select_or_edit_env(int pos) { if (showing_all_envs) { showing_all_envs = false; set_button_label(show_button, "view envs"); } if (active_env) active_env = free_env(active_env); selected_env = position_to_env(pos); if (!selected_env) return; active_env = selected_env; XmTextSetString(textL, enved_all_names(pos)); set_enved_env_list_top(0); prepare_env_edit(active_env); set_sensitive(undo_button, false); set_sensitive(revert_button, false); set_sensitive(save_button, false); env_redisplay(); } static void clear_point_label(void) { XtVaSetValues(brkptL, XmNlabelType, XmSTRING, XmNlabelString, NULL, NULL); } static void enved_display_point_label(mus_float_t x, mus_float_t y) { char brkpt_buf[LABEL_BUFFER_SIZE]; if ((enved_in_dB(ss)) && (min_dB(ss) < -60)) snprintf(brkpt_buf, LABEL_BUFFER_SIZE, "%.3f : %.5f", x, y); else snprintf(brkpt_buf, LABEL_BUFFER_SIZE, "%.3f : %.3f", x, y); set_button_label(brkptL, brkpt_buf); } static void drawer_button_motion(Widget w, XtPointer context, XEvent *event, Boolean *cont) { XMotionEvent *ev = (XMotionEvent *)event; ignore_button_release = false; if (!showing_all_envs) { mus_float_t x, y; #ifdef __APPLE__ if ((ev->x == press_x) && (ev->y == press_y)) return; #endif env_editor_button_motion_with_xy(ss->enved, ev->x, ev->y, ev->time, active_env, &x, &y); enved_display_point_label(x, y); env_redisplay(); } } static void drawer_button_press(Widget w, XtPointer context, XEvent *event, Boolean *cont) { XButtonEvent *ev = (XButtonEvent *)event; #ifdef __APPLE__ press_x = ev->x; press_y = ev->y; #endif ss->enved->down_time = ev->time; ss->enved->env_dragged = false; if (showing_all_envs) { int pos; pos = hit_env(ev->x, ev->y, env_window_width, env_window_height); XmListSelectPos(screnvlst, pos + 1, false); if ((pos >= 0) && (pos < enved_all_envs_top())) { select_or_edit_env(pos); ignore_button_release = true; } } else { if (!active_env) { active_env = default_env(1.0, 0.0); active_env->base = enved_base(ss); env_redisplay(); /* needed to get current_xs set up correctly */ } if (env_editor_button_press(ss->enved, ev->x, ev->y, ev->time, active_env)) env_redisplay(); enved_display_point_label(ungrf_x(ss->enved->axis, ev->x), env_editor_ungrf_y_dB(ss->enved, ev->y)); set_sensitive(save_button, true); set_sensitive(undo_button, true); set_sensitive(revert_button, true); } } static void drawer_button_release(Widget w, XtPointer context, XEvent *event, Boolean *cont) { if (ignore_button_release) ignore_button_release = false; else { if ((active_env) && (!showing_all_envs)) { env_editor_button_release(ss->enved, active_env); env_redisplay(); clear_point_label(); } } } static void drawer_resize(Widget w, XtPointer context, XtPointer info) { /* update display, can be either view of all envs or sequence of current envs */ env_window_width = widget_width(w); env_window_height = widget_height(w); env_redisplay(); } static void show_button_pressed(Widget w, XtPointer context, XtPointer info) { /* if show all (as opposed to show current), loop through loaded LV_LISTs */ showing_all_envs = (!showing_all_envs); set_button_label(show_button, (showing_all_envs) ? "edit env" : "view envs"); env_redisplay(); } static void selection_button_pressed(Widget s, XtPointer context, XtPointer info) { we_turned_selection_off = false; apply_to_selection = (!apply_to_selection); XmChangeColor(selection_button, (apply_to_selection) ? ((Pixel)ss->yellow) : ((Pixel)ss->highlight_color)); set_sensitive(apply2_button, true); if ((enved_with_wave(ss)) && (!showing_all_envs)) env_redisplay(); } static void revert_button_pressed(Widget w, XtPointer context, XtPointer info) { revert_env_edit(); if (active_env) active_env = free_env(active_env); active_env = enved_next_env(); if (active_env == NULL) text_field_activated(); env_redisplay(); } static void undo_button_pressed(Widget w, XtPointer context, XtPointer info) { undo_env_edit(); if (active_env) active_env = free_env(active_env); active_env = enved_next_env(); env_redisplay(); } static void redo_button_pressed(Widget w, XtPointer context, XtPointer info) { redo_env_edit(); if (active_env) active_env = free_env(active_env); active_env = enved_next_env(); env_redisplay(); } static void reflect_apply_state(void) { set_label(nameL, env_names[enved_target(ss)]); XmChangeColor(amp_button, (enved_target(ss) == ENVED_AMPLITUDE) ? ((Pixel)ss->yellow) : ((Pixel)ss->highlight_color)); XmChangeColor(flt_button, (enved_target(ss) == ENVED_SPECTRUM) ? ((Pixel)ss->yellow) : ((Pixel)ss->highlight_color)); XmChangeColor(src_button, (enved_target(ss) == ENVED_SRATE) ? ((Pixel)ss->yellow) : ((Pixel)ss->highlight_color)); if ((!showing_all_envs) && (enved_with_wave(ss))) env_redisplay(); } static void freq_button_callback(Widget w, XtPointer context, XtPointer info) { in_set_enved_target(ENVED_SPECTRUM); old_clipping = enved_clipping(ss); set_enved_clipping(true); reflect_apply_state(); } static void amp_button_callback(Widget w, XtPointer context, XtPointer info) { if (enved_target(ss) == ENVED_SPECTRUM) set_enved_clipping(old_clipping); in_set_enved_target(ENVED_AMPLITUDE); reflect_apply_state(); } static void src_button_callback(Widget w, XtPointer context, XtPointer info) { if (enved_target(ss) == ENVED_SPECTRUM) set_enved_clipping(old_clipping); in_set_enved_target(ENVED_SRATE); reflect_apply_state(); } static void reset_button_callback(Widget w, XtPointer context, XtPointer info) { enved_reset(); } static void enved_print(char *name) { print_enved(name, env_window_height); } static void env_browse_callback(Widget w, XtPointer context, XtPointer info) { XmListCallbackStruct *cb = (XmListCallbackStruct *)info; select_or_edit_env(cb->item_position - 1); } static void graph_button_callback(Widget w, XtPointer context, XtPointer info) { XmToggleButtonCallbackStruct *cb = (XmToggleButtonCallbackStruct *)info; in_set_enved_with_wave(cb->set); env_redisplay(); } static void dB_button_callback(Widget w, XtPointer context, XtPointer info) { XmToggleButtonCallbackStruct *cb = (XmToggleButtonCallbackStruct *)info; in_set_enved_in_dB(cb->set); env_redisplay(); } static void clip_button_callback(Widget w, XtPointer context, XtPointer info) { XmToggleButtonCallbackStruct *cb = (XmToggleButtonCallbackStruct *)info; in_set_enved_clipping(cb->set); } #define BASE_MAX 400 #define BASE_MID 200 /* these two just set the granularity of the scale widget, not the user-visible bounds */ static void make_base_label(mus_float_t bval) { char *sfs, *buf; int i, len, scale_len; len = (int)(enved_power(ss) * 4); if (len < 32) len = 32; sfs = (char *)calloc(len, sizeof(char)); snprintf(sfs, len, "%.3f", bval); scale_len = (int)(enved_power(ss) + 3); if (scale_len < 32) scale_len = 32; buf = (char *)calloc(scale_len, sizeof(char)); for (i = 0; i < scale_len - 1; i++) buf[i] = sfs[i]; set_button_label(baseValue, buf); free(sfs); free(buf); in_set_enved_base(bval); if ((active_env) && (!(showing_all_envs))) { active_env->base = enved_base(ss); if (active_env->base == 1.0) set_enved_style(ENVELOPE_LINEAR); else set_enved_style(ENVELOPE_EXPONENTIAL); env_redisplay(); } } static void base_changed(int val) { mus_float_t bval; if (val == 0) bval = 0.0; else { if (val == BASE_MID) bval = 1.0; else { if (val > BASE_MID) bval = pow(1.0 + (10.0 * ((mus_float_t)(val - BASE_MID) / (mus_float_t)BASE_MID)), enved_power(ss)); else bval = pow(((mus_float_t)val / (mus_float_t)BASE_MID), enved_power(ss) - 1.0); } } make_base_label(bval); if (active_env) set_sensitive(save_button, true); /* what about undo/redo here? */ } static void reflect_changed_base(mus_float_t val) { int ival; if (val <= 0.0) ival = 0; else { if (val == 1.0) ival = BASE_MID; else { if (val <= 1.0) ival = (int)(pow(val, 1.0 / (enved_power(ss) - 1.0)) * BASE_MID); else ival = (int)(BASE_MID + ((BASE_MID * (pow(val, (1.0 / (enved_power(ss)))) - 1)) / 10.0)); } } XtVaSetValues(baseScale, XmNvalue, mus_iclamp(0, ival, (int)(BASE_MAX * .9)), NULL); make_base_label(val); } static void base_drag_callback(Widget w, XtPointer context, XtPointer info) { XmScrollBarCallbackStruct *sb = (XmScrollBarCallbackStruct *)info; base_changed(sb->value); } static int base_last_value = BASE_MID; static void base_valuechanged_callback(Widget w, XtPointer context, XtPointer info) { XmScrollBarCallbackStruct *sb = (XmScrollBarCallbackStruct *)info; base_last_value = sb->value; base_changed(sb->value); } static void base_click_callback(Widget w, XtPointer context, XtPointer info) { XmPushButtonCallbackStruct *cb = (XmPushButtonCallbackStruct *)info; XButtonEvent *ev; int val; ev = (XButtonEvent *)(cb->event); if (ev->state & (snd_ControlMask | snd_MetaMask)) val = base_last_value; else val = BASE_MID; /* this is supposedly 1.0 */ base_changed(val); XtVaSetValues(baseScale, XmNvalue, val, NULL); } static void FIR_click_callback(Widget w, XtPointer context, XtPointer info) { is_FIR = (!is_FIR); set_label(w, (is_FIR) ? "fir" : "fft"); if (enved_with_wave(ss)) env_redisplay(); } static void reflect_sound_state(void) { bool file_on; file_on = (bool)(any_selected_sound()); set_sensitive(apply_button, file_on); set_sensitive(apply2_button, file_on); } static Xen reflect_file_in_enved(Xen hook_or_reason) { if (enved_dialog) reflect_sound_state(); return(Xen_false); } Xen_wrap_1_arg(reflect_file_in_enved_w, reflect_file_in_enved) Widget create_envelope_editor(void) { if (!enved_dialog) { int n; Arg args[32]; Widget colE, colD, colB, colF; Widget spacer, spacer1, aform, mainform, screnvname, baseSep, baseLabel; XmString xhelp, xdismiss, xapply, titlestr, s1; XGCValues gv; XtCallbackList n1, n2; char str[LABEL_BUFFER_SIZE]; /* -------- DIALOG -------- */ xdismiss = XmStringCreateLocalized((char *)I_GO_AWAY); xhelp = XmStringCreateLocalized((char *)I_HELP); titlestr = XmStringCreateLocalized((char *)"Edit Envelope"); xapply = XmStringCreateLocalized((char *)"Apply"); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNautoUnmanage, false); n++; XtSetArg(args[n], XmNcancelLabelString, xdismiss); n++; XtSetArg(args[n], XmNhelpLabelString, xhelp); n++; XtSetArg(args[n], XmNokLabelString, xapply); n++; XtSetArg(args[n], XmNdialogTitle, titlestr); n++; XtSetArg(args[n], XmNresizePolicy, XmRESIZE_GROW); n++; XtSetArg(args[n], XmNnoResize, false); n++; XtSetArg(args[n], XmNtransient, false); n++; enved_dialog = XmCreateTemplateDialog(MAIN_SHELL(ss), (char *)"envelope editor", args, n); XtAddCallback(enved_dialog, XmNcancelCallback, dismiss_enved_callback, NULL); XtAddCallback(enved_dialog, XmNhelpCallback, help_enved_callback, NULL); XtAddCallback(enved_dialog, XmNokCallback, apply_enved_callback, NULL); XmStringFree(xhelp); XmStringFree(xdismiss); XmStringFree(titlestr); XmStringFree(xapply); XtVaSetValues(XmMessageBoxGetChild(enved_dialog, XmDIALOG_CANCEL_BUTTON), XmNarmColor, ss->selection_color, NULL); XtVaSetValues(XmMessageBoxGetChild(enved_dialog, XmDIALOG_HELP_BUTTON), XmNarmColor, ss->selection_color, NULL); XtVaSetValues(XmMessageBoxGetChild(enved_dialog, XmDIALOG_OK_BUTTON), XmNarmColor, ss->selection_color, NULL); XtVaSetValues(XmMessageBoxGetChild(enved_dialog, XmDIALOG_CANCEL_BUTTON), XmNbackground, ss->highlight_color, NULL); XtVaSetValues(XmMessageBoxGetChild(enved_dialog, XmDIALOG_HELP_BUTTON), XmNbackground, ss->highlight_color, NULL); XtVaSetValues(XmMessageBoxGetChild(enved_dialog, XmDIALOG_OK_BUTTON), XmNbackground, ss->highlight_color, NULL); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNarmColor, ss->selection_color); n++; apply2_button = XtCreateManagedWidget("Undo&Apply", xmPushButtonGadgetClass, enved_dialog, args, n); XtAddCallback(apply2_button, XmNactivateCallback, undo_and_apply_enved_callback, NULL); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNforeground, ss->black); n++; XtSetArg(args[n], XmNarmColor, ss->selection_color); n++; reset_button = XtCreateManagedWidget("Clear graph", xmPushButtonGadgetClass, enved_dialog, args, n); XtAddCallback(reset_button, XmNactivateCallback, reset_button_callback, NULL); /* -------- MAIN WIDGET -------- */ n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNbottomWidget, XmMessageBoxGetChild(enved_dialog, XmDIALOG_SEPARATOR)); n++; mainform = XtCreateManagedWidget("formd", xmFormWidgetClass, enved_dialog, args, n); /* the order in which widgets are defined matters a lot here: * we need to build from the bottom up so that the graph portion expands * when the window is resized (if top-down, the slider at the bottom expands!) */ /* -------- EXP SLIDER AT BOTTOM -------- */ n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNrecomputeSize, false); n++; XtSetArg(args[n], XmNshadowThickness, 0); n++; XtSetArg(args[n], XmNhighlightThickness, 0); n++; XtSetArg(args[n], XmNfillOnArm, false); n++; baseLabel = make_pushbutton_widget("exp:", mainform, args, n); XtAddCallback(baseLabel, XmNactivateCallback, base_click_callback, NULL); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; s1 = XmStringCreateLocalized((char *)"1.000"); XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, baseLabel); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, baseLabel); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; /* XtSetArg(args[n], XmNrecomputeSize, false); n++; */ XtSetArg(args[n], XmNlabelString, s1); n++; baseValue = XtCreateManagedWidget("base-label", xmLabelWidgetClass, mainform, args, n); XmStringFree(s1); /* -------- filter order -------- */ n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNcolumns, 3); n++; XtSetArg(args[n], XmNrecomputeSize, false); n++; XtSetArg(args[n], XmNheight, 24); n++; XtSetArg(args[n], XmNresizeWidth, false); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(args[n], XmNmarginHeight, 0); n++; XtSetArg(args[n], XmNmarginBottom, 0); n++; snprintf(str, LABEL_BUFFER_SIZE, "%d", enved_filter_order(ss)); XtSetArg(args[n], XmNvalue, str); n++; orderL = make_textfield_widget("orderL", mainform, args, n, ACTIVATABLE, NO_COMPLETER); XtAddCallback(orderL, XmNactivateCallback, order_activate_callback, NULL); /* -------- fft/fir choice -------- */ n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNrightWidget, orderL); n++; XtSetArg(args[n], XmNrecomputeSize, false); n++; XtSetArg(args[n], XmNshadowThickness, 0); n++; XtSetArg(args[n], XmNhighlightThickness, 0); n++; XtSetArg(args[n], XmNfillOnArm, false); n++; fir_button = make_pushbutton_widget((char *)((is_FIR) ? "fir" : "fft"), mainform, args, n); XtAddCallback(fir_button, XmNactivateCallback, FIR_click_callback, NULL); /* -------- exp base scale -------- */ n = 0; XtSetArg(args[n], XmNbackground, ss->position_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, baseLabel); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, baseValue); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNrightWidget, fir_button); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNmaximum, BASE_MAX); n++; XtSetArg(args[n], XmNvalue, BASE_MID); n++; XtSetArg(args[n], XmNincrement, 1); n++; XtSetArg(args[n], XmNpageIncrement, 1); n++; XtSetArg(args[n], XmNdragCallback, n1 = make_callback_list(base_drag_callback, NULL)); n++; XtSetArg(args[n], XmNvalueChangedCallback, n2 = make_callback_list(base_valuechanged_callback, NULL)); n++; baseScale = XtCreateManagedWidget("expscl", xmScrollBarWidgetClass, mainform, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNbottomWidget, baseScale); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNmargin, LINE_MARGIN); n++; XtSetArg(args[n], XmNheight, LINE_MARGIN); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNseparatorType, XmNO_LINE); n++; XtSetArg(args[n], XmNheight, 5); n++; baseSep = XtCreateManagedWidget("snd-rec-sep", xmSeparatorWidgetClass, mainform, args, n); /* -------- AMP ENV NAME -------- */ n = 0; s1 = XmStringCreateLocalized((char *)"amp env:"); XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNbottomWidget, baseSep); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNlabelString, s1); n++; XtSetArg(args[n], XmNshadowThickness, 0); n++; XtSetArg(args[n], XmNhighlightThickness, 0); n++; nameL = XtCreateManagedWidget("nameL", xmLabelWidgetClass, mainform, args, n); XmStringFree(s1); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNbottomWidget, baseSep); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, nameL); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; textL = make_textfield_widget("textL", mainform, args, n, ACTIVATABLE, add_completer_func(env_name_completer, NULL)); XtAddCallback(textL, XmNactivateCallback, enved_text_activate_callback, NULL); /* -------- dB, GRAPH ('wave') AND CLIP BUTTONS -------- */ n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNselectColor, ss->selection_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNbottomWidget, baseSep); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; if (ss->toggle_size > 0) {XtSetArg(args[n], XmNindicatorSize, ss->toggle_size); n++;} dB_button = make_togglebutton_widget("dB", mainform, args, n); XtAddCallback(dB_button, XmNvalueChangedCallback, dB_button_callback, NULL); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNselectColor, ss->selection_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNbottomWidget, baseSep); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNrightWidget, dB_button); n++; if (ss->toggle_size > 0) {XtSetArg(args[n], XmNindicatorSize, ss->toggle_size); n++;} graph_button = make_togglebutton_widget("wave", mainform, args, n); XtAddCallback(graph_button, XmNvalueChangedCallback, graph_button_callback, NULL); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNselectColor, ss->selection_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNbottomWidget, baseSep); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNrightWidget, graph_button); n++; if (ss->toggle_size > 0) {XtSetArg(args[n], XmNindicatorSize, ss->toggle_size); n++;} clip_button = make_togglebutton_widget("clip", mainform, args, n); XtAddCallback(clip_button, XmNvalueChangedCallback, clip_button_callback, NULL); /* -------- BREAKPOINT DATA DISPLAY LABEL -------- */ n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNbottomWidget, baseSep); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, textL); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNrightWidget, clip_button); n++; XtSetArg(args[n], XmNrecomputeSize, false); n++; XtSetArg(args[n], XmNlabelType, XmSTRING); n++; brkptL = XtCreateManagedWidget(" ", xmLabelWidgetClass, mainform, args, n); /* -------- SPACERS TO DIVIDE WINDOW IN TWO -------- */ n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNbottomWidget, textL); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNheight, 4); n++; XtSetArg(args[n], XmNseparatorType, XmNO_LINE); n++; spacer = XtCreateManagedWidget("spacer", xmSeparatorWidgetClass, mainform, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNbottomWidget, spacer); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNseparatorType, XmSHADOW_ETCHED_IN); n++; spacer1 = XtCreateManagedWidget("spacer1", xmSeparatorWidgetClass, mainform, args, n); /* second separator needed because marginTop seems to be broken or non-existent for these widgets */ /* -------- WINDOW LEFT WIDGET HOLDER -------- */ n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNbottomWidget, spacer1); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; aform = XtCreateManagedWidget("aform", xmFormWidgetClass, mainform, args, n); /* -------- BUTTON BOX AT TOP LEFT -------- */ n = 0; XtSetArg(args[n], XmNbackground, ss->zoom_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNshadowThickness, 4); n++; XtSetArg(args[n], XmNshadowType, XmSHADOW_ETCHED_IN); n++; colF = XtCreateManagedWidget("env-button-frame", xmFrameWidgetClass, aform, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->lighter_blue); n++; colB = XtCreateManagedWidget("env-button-holder", xmFormWidgetClass, colF, args, n); /* VIEW ENVS */ n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNarmColor, ss->selection_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_CENTER); n++; show_button = XtCreateManagedWidget("view envs", xmPushButtonWidgetClass, colB, args, n); XtAddCallback(show_button, XmNactivateCallback, show_button_pressed, NULL); /* SAVE PRINT */ n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNarmColor, ss->selection_color); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_CENTER); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, show_button); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; save_button = XtCreateManagedWidget("define it", xmPushButtonWidgetClass, colB, args, n); XtAddCallback(save_button, XmNactivateCallback, save_button_pressed, NULL); /* REVERT */ n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNarmColor, ss->selection_color); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_CENTER); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, save_button); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; revert_button = XtCreateManagedWidget("revert", xmPushButtonWidgetClass, colB, args, n); XtAddCallback(revert_button, XmNactivateCallback, revert_button_pressed, NULL); /* UNDO REDO */ n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNarmColor, ss->selection_color); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_CENTER); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, revert_button); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n++; XtSetArg(args[n], XmNrightPosition, 50); n++; undo_button = XtCreateManagedWidget("undo", xmPushButtonWidgetClass, colB, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNarmColor, ss->selection_color); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_CENTER); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, undo_button); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, undo_button); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; redo_button = XtCreateManagedWidget("redo", xmPushButtonWidgetClass, colB, args, n); XtAddCallback(undo_button, XmNactivateCallback, undo_button_pressed, NULL); XtAddCallback(redo_button, XmNactivateCallback, redo_button_pressed, NULL); /* AMP FLT SRC */ /* enved_function (target) choice (a row of three push buttons that acts like a "radio box") */ n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNarmColor, ss->yellow); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_CENTER); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, undo_button); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n++; XtSetArg(args[n], XmNrightPosition, 33); n++; amp_button = XtCreateManagedWidget("amp", xmPushButtonWidgetClass, colB, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNarmColor, ss->yellow); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_CENTER); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, amp_button); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, amp_button); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n++; XtSetArg(args[n], XmNrightPosition, 67); n++; flt_button = XtCreateManagedWidget("flt", xmPushButtonWidgetClass, colB, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNarmColor, ss->yellow); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_CENTER); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, flt_button); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, flt_button); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; src_button = XtCreateManagedWidget("src", xmPushButtonWidgetClass, colB, args, n); XtAddCallback(flt_button, XmNactivateCallback, freq_button_callback, NULL); XtAddCallback(amp_button, XmNactivateCallback, amp_button_callback, NULL); XtAddCallback(src_button, XmNactivateCallback, src_button_callback, NULL); /* SELECTION */ n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNarmColor, ss->selection_color); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_CENTER); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, amp_button); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; selection_button = make_pushbutton_widget("selection", colB, args, n); XtAddCallback(selection_button, XmNactivateCallback, selection_button_pressed, NULL); /* -------- ENV LIST AT LEFT UNDER BUTTONS -------- */ n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, colF); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNshadowThickness, 4); n++; XtSetArg(args[n], XmNshadowType, XmSHADOW_ETCHED_IN); n++; colE = XtCreateManagedWidget("env-list-frame", xmFrameWidgetClass, aform, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; colD = XtCreateManagedWidget("env-list-holder", xmFormWidgetClass, colE, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; screnvname = XtCreateManagedWidget("envs:", xmLabelWidgetClass, colD, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, screnvname); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; if (ss->listener_fontlist) { XtSetArg(args[n], XmNfontList, 0); n++; XtSetArg(args[n], XM_FONT_RESOURCE, ss->listener_fontlist); n++; use_listener_font = true; } screnvlst = XmCreateScrolledList(colD, (char *)"scrolled-env-list", args, n); XtManageChild(screnvlst); XtAddCallback(screnvlst, XmNbrowseSelectionCallback, env_browse_callback, NULL); map_over_children(screnvlst, set_main_color_of_widget); if (enved_all_envs_top() > 0) make_scrolled_env_list(); /* -------- MAIN GRAPH -------- */ n = 0; XtSetArg(args[n], XmNbackground, ss->graph_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNbottomWidget, spacer1 /* textL */); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, aform); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNheight, 350); n++; XtSetArg(args[n], XmNallowResize, true); n++; drawer = XtCreateManagedWidget("drawer", xmDrawingAreaWidgetClass, mainform, args, n); gv.function = GXcopy; XtVaGetValues(drawer, XmNbackground, &gv.background, XmNforeground, &gv.foreground, NULL); gc1 = XtGetGC(drawer, GCForeground | GCFunction, &gv); gv.foreground = ss->red; rgc = XtGetGC(drawer, GCBackground | GCForeground | GCFunction, &gv); gv.foreground = ss->enved_waveform_color; ggc = XtGetGC(drawer, GCBackground | GCForeground | GCFunction, &gv); XtManageChild(enved_dialog); /* needed so that window is valid when resize callback is invoked */ apply_button = XmMessageBoxGetChild(enved_dialog, XmDIALOG_OK_BUTTON); cancel_button = XmMessageBoxGetChild(enved_dialog, XmDIALOG_CANCEL_BUTTON); cancelling = true; XtAddCallback(drawer, XmNresizeCallback, drawer_resize, NULL); XtAddCallback(drawer, XmNexposeCallback, drawer_resize, NULL); XtAddEventHandler(drawer, ButtonPressMask, false, drawer_button_press, NULL); XtAddEventHandler(drawer, ButtonMotionMask, false, drawer_button_motion, NULL); XtAddEventHandler(drawer, ButtonReleaseMask, false, drawer_button_release, NULL); if (enved_all_envs_top() == 0) set_sensitive(show_button, false); set_sensitive(revert_button, false); set_sensitive(undo_button, false); set_sensitive(redo_button, false); set_sensitive(save_button, false); if (!(selection_is_active())) set_sensitive(selection_button, false); XmToggleButtonSetState(clip_button, (Boolean)(enved_clipping(ss)), false); XmToggleButtonSetState(graph_button, (Boolean)(enved_with_wave(ss)), false); XmToggleButtonSetState(dB_button, (Boolean)(enved_in_dB(ss)), false); free(n1); free(n2); reflect_apply_state(); reflect_segment_state(); reflect_sound_state(); set_dialog_widget(ENVED_DIALOG, enved_dialog); Xen_add_to_hook_list(ss->snd_open_file_hook, reflect_file_in_enved_w, "enved-file-open-handler", "enved dialog's file-open-hook handler"); } else raise_dialog(enved_dialog); if (!XtIsManaged(enved_dialog)) XtManageChild(enved_dialog); active_channel = current_channel(); return(enved_dialog); } void set_enved_clipping(bool val) { in_set_enved_clipping(val); if (enved_dialog) XmToggleButtonSetState(clip_button, (Boolean)val, false); } void reflect_enved_style(void) { reflect_segment_state(); } void set_enved_target(enved_target_t val) { in_set_enved_target(val); if (enved_dialog) reflect_apply_state(); } void set_enved_with_wave(bool val) { in_set_enved_with_wave(val); if (enved_dialog) XmToggleButtonSetState(graph_button, (Boolean)val, false); } void set_enved_in_dB(bool val) { in_set_enved_in_dB(val); if (enved_dialog) XmToggleButtonSetState(dB_button, (Boolean)val, false); } void set_enved_base(mus_float_t val) { in_set_enved_base(val); if (enved_dialog) reflect_changed_base(val); } bool enved_dialog_is_active(void) { return((enved_dialog) && (XtIsManaged(enved_dialog))); } void set_enved_filter_order(int order) { if ((order > 0) && (order < 2000)) { if (order & 1) {in_set_enved_filter_order(order + 1);} else {in_set_enved_filter_order(order);} if (enved_dialog) { widget_int_to_text(orderL, enved_filter_order(ss)); if ((enved_dialog) && (enved_target(ss) == ENVED_SPECTRUM) && (enved_with_wave(ss)) && (!showing_all_envs)) env_redisplay(); } } } void enved_reflect_selection(bool on) { if ((enved_dialog) && (!within_selection_src)) { set_sensitive(selection_button, on); if ((apply_to_selection) && (!on)) { apply_to_selection = false; we_turned_selection_off = true; } if ((on) && (we_turned_selection_off)) { apply_to_selection = true; } XmChangeColor(selection_button, (apply_to_selection) ? ((Pixel)ss->yellow) : ((Pixel)ss->highlight_color)); if ((enved_target(ss) != ENVED_SPECTRUM) && (enved_with_wave(ss)) && (!showing_all_envs)) env_redisplay(); } } void color_enved_waveform(Pixel pix) { if (enved_dialog) { XSetForeground(MAIN_DISPLAY(ss), ggc, pix); if ((enved_with_wave(ss)) && (enved_dialog)) env_redisplay(); } } static Xen g_enved_envelope(void) { #define H_enved_envelope "(" S_enved_envelope "): current envelope editor displayed (active) envelope" return(env_to_xen(active_env)); } static Xen g_set_enved_envelope(Xen e) { Xen_check_type(Xen_is_list(e) || Xen_is_string(e) || Xen_is_symbol(e), e, 1, S_set S_enved_envelope, "a list, symbol, or string"); if (active_env) active_env = free_env(active_env); if ((Xen_is_string(e)) || (Xen_is_symbol(e))) active_env = name_to_env((Xen_is_string(e)) ? Xen_string_to_C_string(e) : Xen_symbol_to_C_string(e)); /* xen_to_env in name_to_env, so no copy */ else active_env = xen_to_env(e); if ((!active_env) && (!(Xen_is_list(e)))) Xen_error(NO_SUCH_ENVELOPE, Xen_list_2(C_string_to_Xen_string(S_set S_enved_envelope ": bad envelope arg: ~A"), e)); if (enved_dialog) env_redisplay(); return(e); } static Xen g_enved_filter(void) { #define H_enved_filter "(" S_enved_filter "): envelope editor FIR/FFT filter choice (" PROC_TRUE ": FIR)" return(C_bool_to_Xen_boolean(is_FIR)); } static Xen g_set_enved_filter(Xen type) { Xen_check_type(Xen_is_boolean(type), type, 1, S_set S_enved_filter, "boolean"); is_FIR = Xen_boolean_to_C_bool(type); if (fir_button) set_label(fir_button, (is_FIR) ? "fir" : "fft"); return(type); } Xen_wrap_no_args(g_enved_filter_w, g_enved_filter) Xen_wrap_1_arg(g_set_enved_filter_w, g_set_enved_filter) Xen_wrap_no_args(g_enved_envelope_w, g_enved_envelope) Xen_wrap_1_arg(g_set_enved_envelope_w, g_set_enved_envelope) void g_init_gxenv(void) { Xen_define_dilambda(S_enved_filter, g_enved_filter_w, H_enved_filter, S_set S_enved_filter, g_set_enved_filter_w, 0, 0, 1, 0); Xen_define_dilambda(S_enved_envelope, g_enved_envelope_w, H_enved_envelope, S_set S_enved_envelope, g_set_enved_envelope_w, 0, 0, 1, 0); } /* Transform settings dialog */ static Widget transform_dialog = NULL; /* main dialog shell */ static Widget type_list, size_list, wavelet_list, window_list; static Widget beta_scale, alpha_scale, start_scale, end_scale, alpha_number, beta_number, start_number, end_number; static Widget db_button, peaks_button, logfreq_button, sono_button, spectro_button, normo_button, normalize_button, selection_button1, phases_button; static Widget graph_label, graph_drawer; static Widget peak_txt, db_txt, freq_base_txt; static Widget error_frame1, error_label1; #define NUM_TRANSFORM_SIZES 15 static const char *transform_size_names[NUM_TRANSFORM_SIZES] = {"32", "64", "128", "256", "512", "1024", "2048", "4096", "8192", "16384", "65536", "262144", "1048576", "4194304 ", "16777216"}; static mus_long_t transform_sizes[NUM_TRANSFORM_SIZES] = {32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 65536, 262144, 1048576, 4194304, 16777216}; /* ---------------- fft window graph ---------------- */ static GC gc2, fgc; #define GRAPH_SIZE 128 static mus_float_t graph_data[GRAPH_SIZE]; /* fft window graph in transform options dialog */ static mus_float_t graph_fftr[GRAPH_SIZE * 2]; static mus_float_t graph_ffti[GRAPH_SIZE * 2]; /* I goofed around with making the graph size dependent on the drawer's width, but there's really nothing gained */ /* also tried linear/db+min-dB distinction, but linear looks dumb and min-dB is a bother */ static mus_float_t fp_dB(mus_float_t py) { return((py <= ss->lin_dB) ? 0.0 : (1.0 - (20.0 * log10(py) / min_dB(ss)))); } static int local_grf_x(double val, axis_info *ap) { if (val >= ap->x1) return(ap->x_axis_x1); if (val <= ap->x0) return(ap->x_axis_x0); return((int)(ap->x_base + val * ap->x_scale)); } static int local_grf_y(mus_float_t val, axis_info *ap) { if (val >= ap->y1) return(ap->y_axis_y1); if (val <= ap->y0) return(ap->y_axis_y0); return((int)(ap->y_base + val * ap->y_scale)); } static axis_info *axis_ap = NULL; static void graph_redisplay(void) { /* fft_window(ss) is the current choice */ int ix0, iy0, ix1, iy1, i; mus_float_t xincr, x; graphics_context *ax; if (axis_ap == NULL) { axis_ap = (axis_info *)calloc(1, sizeof(axis_info)); ax = (graphics_context *)calloc(1, sizeof(graphics_context)); axis_ap->ax = ax; ax->dp = XtDisplay(graph_drawer); ax->wn = XtWindow(graph_drawer); } else ax = axis_ap->ax; axis_ap->xmin = 0.0; axis_ap->xmax = 1.0; axis_ap->x_ambit = 1.0; axis_ap->x0 = 0.0; axis_ap->x1 = 1.0; if (axis_ap->xlabel) free(axis_ap->xlabel); if (fft_beta_max(fft_window(ss)) != 1.0) axis_ap->xlabel = mus_format("(%d, beta: %.2f)", GRAPH_SIZE, fft_beta_max(fft_window(ss)) * fft_window_beta(ss)); else axis_ap->xlabel = mus_format("(%d)", GRAPH_SIZE); if (fft_window(ss) == MUS_FLAT_TOP_WINDOW) { axis_ap->ymin = -0.1; axis_ap->ymax = 1.0; axis_ap->y_ambit = 1.1; axis_ap->y0 = -0.1; axis_ap->y1 = 1.0; } else { axis_ap->ymin = 0.0; axis_ap->ymax = 1.0; axis_ap->y_ambit = 1.0; axis_ap->y0 = 0.0; axis_ap->y1 = 1.0; } axis_ap->width = widget_width(graph_drawer); axis_ap->window_width = axis_ap->width; axis_ap->y_offset = 0; axis_ap->height = widget_height(graph_drawer); axis_ap->graph_x0 = 0; clear_window(ax); ax->gc = gc2; make_axes_1(axis_ap, X_AXIS_IN_SECONDS, 1 /* "srate" */, SHOW_ALL_AXES, NOT_PRINTING, WITH_X_AXIS, NO_GRID, WITH_LINEAR_AXES, grid_density(ss)); ix1 = local_grf_x(0.0, axis_ap); iy1 = local_grf_y(graph_data[0], axis_ap); xincr = 1.0 / (mus_float_t)GRAPH_SIZE; for (i = 1, x = xincr; i < GRAPH_SIZE; i++, x += xincr) { ix0 = ix1; iy0 = iy1; ix1 = local_grf_x(x, axis_ap); iy1 = local_grf_y(graph_data[i], axis_ap); XDrawLine(ax->dp, ax->wn, gc2, ix0, iy0, ix1, iy1); } ax->gc = fgc; ix1 = local_grf_x(0.0, axis_ap); iy1 = local_grf_y(graph_fftr[0], axis_ap); xincr = 1.0 / (mus_float_t)GRAPH_SIZE; for (i = 1, x = xincr; i < GRAPH_SIZE; i++, x += xincr) { ix0 = ix1; iy0 = iy1; ix1 = local_grf_x(x, axis_ap); if (fft_log_magnitude(ss)) iy1 = local_grf_y(fp_dB(graph_fftr[i]), axis_ap); else iy1 = local_grf_y(graph_fftr[i], axis_ap); XDrawLine(ax->dp, ax->wn, fgc, ix0, iy0, ix1, iy1); } } static void get_fft_window_data(void) { int i; mus_make_fft_window_with_window(fft_window(ss), GRAPH_SIZE, fft_window_beta(ss) * fft_beta_max(fft_window(ss)), fft_window_alpha(ss), graph_data); memset((void *)graph_fftr, 0, GRAPH_SIZE * 2 * sizeof(mus_float_t)); memset((void *)graph_ffti, 0, GRAPH_SIZE * 2 * sizeof(mus_float_t)); memcpy((void *)graph_fftr, (void *)graph_data, GRAPH_SIZE * sizeof(mus_float_t)); mus_spectrum(graph_fftr, graph_ffti, NULL, GRAPH_SIZE * 2, MUS_SPECTRUM_IN_DB); for (i = 0; i < GRAPH_SIZE; i++) graph_fftr[i] = (graph_fftr[i] + 80.0) / 80.0; /* min dB here is -80 */ } static void widget_float_to_text(Widget w, mus_float_t val) { char *str; str = (char *)calloc(16, sizeof(char)); snprintf(str, 16, "%.2f", val); XmTextFieldSetString(w, str); free(str); } /* ---------------- errors ---------------- */ static void clear_fft_error(void) { if ((error_frame1) && (XtIsManaged(error_frame1))) XtUnmanageChild(error_frame1); } static void unpost_fft_error(XtPointer data, XtIntervalId *id) { clear_fft_error(); } static void errors_to_fft_text(const char *msg, void *data) { int lines = 0; XmString label; label = multi_line_label(msg, &lines); XtVaSetValues(error_label1, XmNlabelString, label, XmNheight, lines * 20, NULL); XtVaSetValues(error_frame1, XmNheight, lines * 20, NULL); XmStringFree(label); XtManageChild(error_frame1); /* since the offending text is automatically overwritten, we can't depend on subsequent text modify callbacks * to clear things, so we'll just use a timer */ XtAppAddTimeOut(MAIN_APP(ss), 5000, (XtTimerCallbackProc)unpost_fft_error, NULL); } /* ---------------- transform size ---------------- */ static void chans_transform_size(chan_info *cp, mus_long_t size) { cp->transform_size = size; if (cp->fft) cp->fft->size = size; } void set_transform_size(mus_long_t val) { for_each_chan(force_fft_clear); in_set_transform_size(val); for_each_chan_with_mus_long_t(chans_transform_size, val); if (transform_dialog) { int i; for (i = 0; i < NUM_TRANSFORM_SIZES; i++) if (transform_sizes[i] == val) { XmListSelectPos(size_list, i + 1, false); break; } } if (!(ss->graph_hook_active)) for_each_chan(calculate_fft); } static void size_browse_callback(Widget w, XtPointer context, XtPointer info) { XmListCallbackStruct *cbs = (XmListCallbackStruct *)info; for_each_chan(force_fft_clear); in_set_transform_size(transform_sizes[cbs->item_position - 1]); for_each_chan_with_mus_long_t(chans_transform_size, transform_size(ss)); for_each_chan(calculate_fft); set_label(graph_label, mus_fft_window_name(fft_window(ss))); } /* ---------------- wavelet choice ---------------- */ static void chans_wavelet_type(chan_info *cp, int value) { cp->wavelet_type = value; } void set_wavelet_type(int val) { if (transform_dialog) XmListSelectPos(wavelet_list, val, false); in_set_wavelet_type(val); for_each_chan_with_int(chans_wavelet_type, val); if ((transform_type(ss) == WAVELET) && (!(ss->graph_hook_active))) for_each_chan(calculate_fft); } static void wavelet_browse_callback(Widget w, XtPointer context, XtPointer info) { int val; XmListCallbackStruct *cbs = (XmListCallbackStruct *)info; in_set_wavelet_type(val = (cbs->item_position - 1)); /* make these numbers 0-based as in mus.lisp */ for_each_chan_with_int(chans_wavelet_type, val); if (transform_type(ss) == WAVELET) for_each_chan(calculate_fft); } /* ---------------- fft window choice ---------------- */ static void highlight_alpha_beta_scales(mus_fft_window_t val) { if (fft_window_beta_in_use(val)) { XtVaSetValues(beta_scale, XmNbackground, ss->highlight_color, NULL); XtVaSetValues(beta_number, XmNbackground, ss->highlight_color, NULL); } else { XtVaSetValues(beta_scale, XmNbackground, ss->basic_color, NULL); XtVaSetValues(beta_number, XmNbackground, ss->basic_color, NULL); } if (fft_window_alpha_in_use(val)) { XtVaSetValues(alpha_scale, XmNbackground, ss->highlight_color, NULL); XtVaSetValues(alpha_number, XmNbackground, ss->highlight_color, NULL); } else { XtVaSetValues(alpha_scale, XmNbackground, ss->basic_color, NULL); XtVaSetValues(alpha_number, XmNbackground, ss->basic_color, NULL); } } void set_fft_window(mus_fft_window_t val) { in_set_fft_window(val); if (!(ss->graph_hook_active)) for_each_chan(calculate_fft); if (transform_dialog) { XmListSelectPos(window_list, (int)val + 1, false); set_label(graph_label, mus_fft_window_name(val)); get_fft_window_data(); if (XtIsManaged(transform_dialog)) graph_redisplay(); highlight_alpha_beta_scales(val); } } static void window_browse_callback(Widget w, XtPointer context, XtPointer info) { XmListCallbackStruct *cbs = (XmListCallbackStruct *)info; mus_fft_window_t fft_window_choice; fft_window_choice = (mus_fft_window_t)(cbs->item_position - 1); /* make these numbers 0-based as in mus.lisp */ in_set_fft_window(fft_window_choice); for_each_chan(calculate_fft); set_label(graph_label, mus_fft_window_name(fft_window(ss))); get_fft_window_data(); graph_redisplay(); highlight_alpha_beta_scales(fft_window_choice); } /* ---------------- transform choice ---------------- */ static void chans_transform_type(chan_info *cp, int value) { cp->transform_type = value; } void set_transform_type(int val) { if (is_transform(val)) { if (!(ss->graph_hook_active)) for_each_chan(force_fft_clear); in_set_transform_type(val); for_each_chan_with_int(chans_transform_type, val); if (!(ss->graph_hook_active)) for_each_chan(calculate_fft); if (transform_dialog) XmListSelectPos(type_list, transform_type_to_position(val) + 1, false); } } static void transform_type_browse_callback(Widget w, XtPointer context, XtPointer info) { int type; XmListCallbackStruct *cbs = (XmListCallbackStruct *)info; type = transform_position_to_type(cbs->item_position - 1); for_each_chan(force_fft_clear); in_set_transform_type(type); for_each_chan_with_int(chans_transform_type, type); for_each_chan(calculate_fft); } void make_transform_type_list(void) { int num; num = max_transform_type(); if (transform_dialog) { XmString *types; int i, j; types = (XmString *)calloc(num, sizeof(XmString)); for (i = 0, j = 0; i < num; i++) if (is_transform(i)) { set_transform_position(i, j); types[j++] = XmStringCreateLocalized((char *)transform_name(i)); } XtVaSetValues(type_list, XmNitems, types, XmNitemCount, j, XmNvisibleItemCount, 6, NULL); for (i = 0; i < j; i++) XmStringFree(types[i]); free(types); } } /* ---------------- transform "graph type" (i.e. sonogram etc) ---------------- */ void set_transform_graph_type(graph_type_t val) { in_set_transform_graph_type(val); if (transform_dialog) switch (val) { case GRAPH_ONCE: XmToggleButtonSetState(normo_button, true, false); XmToggleButtonSetState(spectro_button, false, false); XmToggleButtonSetState(sono_button, false, false); break; case GRAPH_AS_SONOGRAM: XmToggleButtonSetState(normo_button, false, false); XmToggleButtonSetState(spectro_button, false, false); XmToggleButtonSetState(sono_button, true, false); break; case GRAPH_AS_SPECTROGRAM: XmToggleButtonSetState(normo_button, false, false); XmToggleButtonSetState(spectro_button, true, false); XmToggleButtonSetState(sono_button, false, false); break; case GRAPH_AS_WAVOGRAM: break; } if (!(ss->graph_hook_active)) for_each_chan(calculate_fft); } static void graph_transform_once_callback(Widget w, XtPointer context, XtPointer info) { graph_type_t old_type; old_type = transform_graph_type(ss); XmToggleButtonSetState(normo_button, true, false); XmToggleButtonSetState(sono_button, false, false); XmToggleButtonSetState(spectro_button, false, false); in_set_transform_graph_type(GRAPH_ONCE); if (old_type != GRAPH_ONCE) for_each_chan(calculate_fft); } static void sonogram_callback(Widget w, XtPointer context, XtPointer info) { graph_type_t old_type; old_type = transform_graph_type(ss); XmToggleButtonSetState(sono_button, true, false); XmToggleButtonSetState(normo_button, false, false); XmToggleButtonSetState(spectro_button, false, false); in_set_transform_graph_type(GRAPH_AS_SONOGRAM); if (old_type != GRAPH_AS_SONOGRAM) for_each_chan(calculate_fft); } static void spectrogram_callback(Widget w, XtPointer context, XtPointer info) { graph_type_t old_type; old_type = transform_graph_type(ss); XmToggleButtonSetState(spectro_button, true, false); XmToggleButtonSetState(normo_button, false, false); XmToggleButtonSetState(sono_button, false, false); in_set_transform_graph_type(GRAPH_AS_SPECTROGRAM); if (old_type != GRAPH_AS_SPECTROGRAM) for_each_chan(calculate_fft); } /* ---------------- show peaks ---------------- */ static void map_show_transform_peaks(chan_info *cp, bool value) { cp->show_transform_peaks = value; } static void peaks_callback(Widget w, XtPointer context, XtPointer info) { bool val; XmToggleButtonCallbackStruct *cb = (XmToggleButtonCallbackStruct *)info; val = (cb->set); in_set_show_transform_peaks(val); for_each_chan_with_bool(map_show_transform_peaks, val); for_each_chan(calculate_fft); } void set_show_transform_peaks(bool val) { in_set_show_transform_peaks(val); for_each_chan_with_bool(map_show_transform_peaks, val); if (transform_dialog) set_toggle_button(peaks_button, val, false, NULL); if (!(ss->graph_hook_active)) for_each_chan(calculate_fft); } void reflect_peaks_in_transform_dialog(void) { if (transform_dialog) widget_int_to_text(peak_txt, max_transform_peaks(ss)); } static void peaks_activate_callback(Widget w, XtPointer context, XtPointer info) { char *str; str = XmTextFieldGetString(w); if ((str) && (*str)) { int new_peaks; redirect_errors_to(errors_to_fft_text, NULL); new_peaks = string_to_int(str, 1, "peaks"); redirect_errors_to(NULL, NULL); if (new_peaks >= 1) { set_max_transform_peaks(new_peaks); for_each_chan(calculate_fft); } else widget_int_to_text(w, max_transform_peaks(ss)); XtFree(str); } } /* ---------------- log magnitude ---------------- */ static void chans_fft_log_magnitude(chan_info *cp, bool value) { cp->fft_log_magnitude = value; cp->fft_changed = FFT_CHANGE_LOCKED; } void set_fft_log_magnitude(bool val) { in_set_fft_log_magnitude(val); for_each_chan_with_bool(chans_fft_log_magnitude, val); if (transform_dialog) set_toggle_button(db_button, val, false, NULL); if (!(ss->graph_hook_active)) for_each_chan(calculate_fft); } /* ---------------- dB ---------------- */ static void fft_db_callback(Widget w, XtPointer context, XtPointer info) { bool val; XmToggleButtonCallbackStruct *cb = (XmToggleButtonCallbackStruct *)info; val = cb->set; in_set_fft_log_magnitude(val); graph_redisplay(); for_each_chan_with_bool(chans_fft_log_magnitude, val); for_each_chan(calculate_fft); } void reflect_min_db_in_transform_dialog(void) { if (transform_dialog) widget_float_to_text(db_txt, min_dB(ss)); } static void min_db_activate_callback(Widget w, XtPointer context, XtPointer info) { char *str; str = XmTextFieldGetString(w); if ((str) && (*str)) { mus_float_t new_db; redirect_errors_to(errors_to_fft_text, NULL); new_db = string_to_mus_float_t(str, -10000.0, "dB"); redirect_errors_to(NULL, NULL); if (new_db < 0.0) set_min_db(new_db); else widget_float_to_text(w, min_dB(ss)); XtFree(str); } } /* ---------------- log frequency ---------------- */ static void chans_fft_log_frequency(chan_info *cp, bool value) { cp->fft_log_frequency = value; cp->fft_changed = FFT_CHANGE_LOCKED; } static void logfreq_callback(Widget w, XtPointer context, XtPointer info) { bool val; XmToggleButtonCallbackStruct *cb = (XmToggleButtonCallbackStruct *)info; val = cb->set; in_set_fft_log_frequency(val); for_each_chan_with_bool(chans_fft_log_frequency, val); for_each_chan(calculate_fft); } void set_fft_log_frequency(bool val) { in_set_fft_log_frequency(val); for_each_chan_with_bool(chans_fft_log_frequency, val); if (transform_dialog) set_toggle_button(logfreq_button, val, false, NULL); if (!(ss->graph_hook_active)) for_each_chan(calculate_fft); } void reflect_log_freq_start_in_transform_dialog(void) { if (transform_dialog) widget_float_to_text(freq_base_txt, log_freq_start(ss)); } static void log_freq_start_activate_callback(Widget w, XtPointer context, XtPointer info) { char *str; str = XmTextFieldGetString(w); if ((str) && (*str)) { mus_float_t new_lfb; redirect_errors_to(errors_to_fft_text, NULL); new_lfb = string_to_mus_float_t(str, 0.0, "log freq start"); redirect_errors_to(NULL, NULL); if (new_lfb > 0.0) set_log_freq_start(new_lfb); else widget_float_to_text(w, log_freq_start(ss)); XtFree(str); } } /* ---------------- normalization choice ---------------- */ static void chans_transform_normalization(chan_info *cp, int value) { cp->transform_normalization = (fft_normalize_t)value; cp->fft_changed = FFT_CHANGE_LOCKED; } static void normalize_callback(Widget w, XtPointer context, XtPointer info) { fft_normalize_t choice; XmToggleButtonCallbackStruct *cb = (XmToggleButtonCallbackStruct *)info; choice = (cb->set) ? NORMALIZE_BY_CHANNEL : DONT_NORMALIZE; in_set_transform_normalization(choice); for_each_chan_with_int(chans_transform_normalization, (int)choice); for_each_chan(calculate_fft); } void set_transform_normalization(fft_normalize_t val) { in_set_transform_normalization(val); for_each_chan_with_int(chans_transform_normalization, (int)val); if (transform_dialog) set_toggle_button(normalize_button, (val != DONT_NORMALIZE), false, NULL); if (!(ss->graph_hook_active)) for_each_chan(calculate_fft); } /* ---------------- show selection transform ---------------- */ static void selection_callback(Widget w, XtPointer context, XtPointer info) { XmToggleButtonCallbackStruct *cb = (XmToggleButtonCallbackStruct *)info; in_set_show_selection_transform(cb->set); for_each_chan(calculate_fft); } void set_show_selection_transform(bool show) { in_set_show_selection_transform(show); if (transform_dialog) set_toggle_button(selection_button1, show, false, NULL); if (!(ss->graph_hook_active)) for_each_chan(calculate_fft); } /* ---------------- show phases (via color) ---------------- */ static void chans_fft_with_phases(chan_info *cp, bool value) { cp->fft_with_phases = value; cp->fft_changed = FFT_CHANGE_LOCKED; } static void phases_callback(Widget w, XtPointer context, XtPointer info) { bool val; XmToggleButtonCallbackStruct *cb = (XmToggleButtonCallbackStruct *)info; val = cb->set; in_set_fft_with_phases(val); graph_redisplay(); for_each_chan_with_bool(chans_fft_with_phases, val); for_each_chan(calculate_fft); } void set_fft_with_phases(bool val) { in_set_fft_with_phases(val); for_each_chan_with_bool(chans_fft_with_phases, val); if (!(ss->graph_hook_active)) for_each_chan(calculate_fft); } /* ---------------- window alpha parameter ---------------- */ static void alpha_drag_callback(Widget w, XtPointer context, XtPointer info) { char alpha_number_buffer[11]; mus_float_t alpha; alpha = (((XmScrollBarCallbackStruct *)info)->value) / 90.0; in_set_fft_window_alpha(alpha); chans_field(FCP_ALPHA, alpha); snprintf(alpha_number_buffer, 11, "alpha:%.3f", alpha); set_label(alpha_number, alpha_number_buffer); if (fft_window_alpha_in_use(fft_window(ss))) { get_fft_window_data(); graph_redisplay(); if (transform_type(ss) == FOURIER) for_each_chan(calculate_fft); } } static void set_alpha_scale(mus_float_t val) { char alpha_number_buffer[11]; XtVaSetValues(alpha_scale, XmNvalue, (int)(val * 90), NULL); snprintf(alpha_number_buffer, 11, "alpha:%.3f", val); set_label(alpha_number, alpha_number_buffer); } void set_fft_window_alpha(mus_float_t val) { in_set_fft_window_alpha(val); chans_field(FCP_ALPHA, val); if (transform_dialog) { set_alpha_scale(val); get_fft_window_data(); if (XtIsManaged(transform_dialog)) graph_redisplay(); } if (!(ss->graph_hook_active)) for_each_chan(calculate_fft); } /* ---------------- window beta parameter ---------------- */ static void beta_drag_callback(Widget w, XtPointer context, XtPointer info) { char beta_number_buffer[11]; mus_float_t beta; beta = (((XmScrollBarCallbackStruct *)info)->value) / 90.0; in_set_fft_window_beta(beta); chans_field(FCP_BETA, beta); snprintf(beta_number_buffer, 11, "beta: %.3f", beta); set_label(beta_number, beta_number_buffer); if (fft_window_beta_in_use(fft_window(ss))) { get_fft_window_data(); graph_redisplay(); if (transform_type(ss) == FOURIER) for_each_chan(calculate_fft); } } static void set_beta_scale(mus_float_t val) { char beta_number_buffer[11]; XtVaSetValues(beta_scale, XmNvalue, (int)(val * 90), NULL); snprintf(beta_number_buffer, 11, "beta: %.3f", val); set_label(beta_number, beta_number_buffer); } void set_fft_window_beta(mus_float_t val) { in_set_fft_window_beta(val); chans_field(FCP_BETA, val); if (transform_dialog) { set_beta_scale(val); get_fft_window_data(); if (XtIsManaged(transform_dialog)) graph_redisplay(); } if (!(ss->graph_hook_active)) for_each_chan(calculate_fft); } /* ---------------- spectrum start/end ---------------- */ static void chans_spectrum_changed(chan_info *cp) { cp->fft_changed = FFT_CHANGE_LOCKED; update_graph(cp); } static void set_spectrum_start_scale(mus_float_t val) { char start_number_buffer[11]; XtVaSetValues(start_scale, XmNvalue, (int)(val * 90), NULL); snprintf(start_number_buffer, 11, "start:%.3f", val); set_label(start_number, start_number_buffer); } static void check_spectrum_start(mus_float_t end) { /* don't display chans, but do reset if necessary */ if (spectrum_start(ss) > end) { in_set_spectrum_start(end); if (transform_dialog) set_spectrum_start_scale(end); chans_field(FCP_SPECTRUM_START, end); } } static void check_spectrum_end(mus_float_t start); void set_spectrum_start(mus_float_t val) { if (transform_dialog) set_spectrum_start_scale(val); in_set_spectrum_start(val); check_spectrum_end(val); chans_field(FCP_SPECTRUM_START, val); for_each_chan(chans_spectrum_changed); } static void start_drag_callback(Widget w, XtPointer context, XtPointer info) { char start_number_buffer[11]; mus_float_t start; start = (((XmScrollBarCallbackStruct *)info)->value) / 90.0; snprintf(start_number_buffer, 11, "start:%.3f", start); set_label(start_number, start_number_buffer); in_set_spectrum_start(start); check_spectrum_end(start); chans_field(FCP_SPECTRUM_START, start); for_each_chan(chans_spectrum_changed); } static void set_spectrum_end_scale(mus_float_t val) { char end_number_buffer[11]; XtVaSetValues(end_scale, XmNvalue, (int)(val * 90), NULL); snprintf(end_number_buffer, 11, "end: %.3f", val); set_label(end_number, end_number_buffer); } static void check_spectrum_end(mus_float_t start) { /* don't display chans, but do reset if necessary */ if (spectrum_end(ss) < start) { in_set_spectrum_end(start); if (transform_dialog) set_spectrum_end_scale(start); chans_field(FCP_SPECTRUM_END, start); } } void set_spectrum_end(mus_float_t val) { if (transform_dialog) set_spectrum_end_scale(val); in_set_spectrum_end(val); check_spectrum_start(val); chans_field(FCP_SPECTRUM_END, val); for_each_chan(chans_spectrum_changed); } static void end_drag_callback(Widget w, XtPointer context, XtPointer info) { char end_number_buffer[11]; mus_float_t end; end = (((XmScrollBarCallbackStruct *)info)->value) / 90.0; snprintf(end_number_buffer, 11, "end: %.3f", end); set_label(end_number, end_number_buffer); in_set_spectrum_end(end); check_spectrum_start(end); chans_field(FCP_SPECTRUM_END, end); for_each_chan(chans_spectrum_changed); } /* ---------------- dialog buttons etc ---------------- */ static void graph_resize_callback(Widget w, XtPointer context, XtPointer info) { graph_redisplay(); } static void dismiss_transform_callback(Widget w, XtPointer context, XtPointer info) { if (XmGetFocusWidget(transform_dialog) == XmMessageBoxGetChild(transform_dialog, XmDIALOG_CANCEL_BUTTON)) XtUnmanageChild(transform_dialog); } static void color_orientation_callback(Widget w, XtPointer context, XtPointer info) { make_color_orientation_dialog(true); } static void help_transform_callback(Widget w, XtPointer context, XtPointer info) { transform_dialog_help(); } static void fft_blue_textfield_unfocus_callback(Widget w, XtPointer context, XtPointer info) { XtVaSetValues(w, XmNbackground, ss->lighter_blue, NULL); XtVaSetValues(w, XmNcursorPositionVisible, false, NULL); } static void fft_blue_mouse_leave_text_callback(Widget w, XtPointer context, XEvent *event, Boolean *flag) { XtVaSetValues(w, XmNbackground, ss->lighter_blue, NULL); XtVaSetValues(w, XmNcursorPositionVisible, false, NULL); } static void fft_white_mouse_enter_text_callback(Widget w, XtPointer context, XEvent *event, Boolean *flag) { XtVaSetValues(w, XmNbackground, ss->text_focus_color, NULL); XtVaSetValues(w, XmNcursorPositionVisible, true, NULL); } /* ---------------- transform options dialog ---------------- */ #define FRAME_BORDER_WIDTH 6 static bool need_callback = true; Widget make_transform_dialog(bool managed) { if (!transform_dialog) { Widget mainform, type_frame, type_form, type_label, size_frame, size_form, size_label, display_frame, display_form, display_label; Widget window_frame, window_form, window_label, wavelet_frame, wavelet_form, wavelet_label, graph_frame, graph_form, gsep; Widget ab_form, ab_frame, ab_title, ab_sep; Widget se_form, se_frame, se_title, se_sep, ok_button; XmString s1; XmString xhelp, xgo_away, xtitle, bstr, xorient; Arg args[32]; XmString sizes[NUM_TRANSFORM_SIZES]; XmString wavelets[NUM_WAVELETS]; XmString windows[MUS_NUM_FFT_WINDOWS]; XGCValues gv; XtCallbackList n1, n2, n3, n4; int size_pos = 1; int n, i; for (i = 0; i < NUM_TRANSFORM_SIZES; i++) if (transform_sizes[i] == transform_size(ss)) { size_pos = i + 1; break; } xgo_away = XmStringCreateLocalized((char *)I_GO_AWAY); /* needed by template dialog */ xhelp = XmStringCreateLocalized((char *)I_HELP); xtitle = XmStringCreateLocalized((char *)"Transform Options"); xorient = XmStringCreateLocalized((char *)"Color/Orientation"); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNcancelLabelString, xgo_away); n++; XtSetArg(args[n], XmNokLabelString, xorient); n++; XtSetArg(args[n], XmNhelpLabelString, xhelp); n++; XtSetArg(args[n], XmNautoUnmanage, false); n++; XtSetArg(args[n], XmNdialogTitle, xtitle); n++; XtSetArg(args[n], XmNresizePolicy, XmRESIZE_GROW); n++; XtSetArg(args[n], XmNnoResize, false); n++; XtSetArg(args[n], XmNtransient, false); n++; transform_dialog = XmCreateTemplateDialog(MAIN_SHELL(ss), (char *)"Transform Options", args, n); ok_button = XmMessageBoxGetChild(transform_dialog, XmDIALOG_OK_BUTTON); XtAddCallback(transform_dialog, XmNcancelCallback, dismiss_transform_callback, NULL); /* XtAddCallback(transform_dialog, XmNokCallback, color_orientation_callback, NULL); */ /* in dialog calls this! */ XtAddCallback(ok_button, XmNactivateCallback, color_orientation_callback, NULL); XtAddCallback(transform_dialog, XmNhelpCallback, help_transform_callback, NULL); XmStringFree(xhelp); XmStringFree(xgo_away); XmStringFree(xtitle); XmStringFree(xorient); XtVaSetValues(XmMessageBoxGetChild(transform_dialog, XmDIALOG_CANCEL_BUTTON), XmNarmColor, ss->selection_color, NULL); XtVaSetValues(XmMessageBoxGetChild(transform_dialog, XmDIALOG_HELP_BUTTON), XmNarmColor, ss->selection_color, NULL); XtVaSetValues(XmMessageBoxGetChild(transform_dialog, XmDIALOG_OK_BUTTON), XmNarmColor, ss->selection_color, NULL); XtVaSetValues(XmMessageBoxGetChild(transform_dialog, XmDIALOG_CANCEL_BUTTON), XmNbackground, ss->highlight_color, NULL); XtVaSetValues(XmMessageBoxGetChild(transform_dialog, XmDIALOG_HELP_BUTTON), XmNbackground, ss->highlight_color, NULL); XtVaSetValues(XmMessageBoxGetChild(transform_dialog, XmDIALOG_OK_BUTTON), XmNbackground, ss->highlight_color, NULL); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNbottomWidget, XmMessageBoxGetChild(transform_dialog, XmDIALOG_SEPARATOR)); n++; mainform = XtCreateManagedWidget("mainform", xmFormWidgetClass, transform_dialog, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNallowResize, true); n++; XtSetArg(args[n], XmNshadowType, XmSHADOW_ETCHED_IN); n++; XtSetArg(args[n], XmNshadowThickness, 2); n++; error_frame1 = XtCreateManagedWidget("error-frame", xmFrameWidgetClass, mainform, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; error_label1 = XtCreateManagedWidget("", xmLabelWidgetClass, error_frame1, args, n); /* now 7 or 8 boxes within the main box: type (list) | size (list) | display (button column) wavelet (list) | window (list) | graph (fft?) of current window alpha/beta ------------------------ | start/end ------------------------- | each box has a frame, label, and contents */ /* -------- SPECTRUM START/END -------- */ n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n++; XtSetArg(args[n], XmNrightPosition, 60); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNborderWidth, FRAME_BORDER_WIDTH); n++; XtSetArg(args[n], XmNborderColor, ss->basic_color); n++; se_frame = XtCreateManagedWidget("se-frame", xmFrameWidgetClass, mainform, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; n = attach_all_sides(args, n); se_form = XtCreateManagedWidget("se-form", xmFormWidgetClass, se_frame, args, n); /* needed because XmFrame only accepts one child */ n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_CENTER); n++; se_title = XtCreateManagedWidget("spectrum start/end", xmLabelWidgetClass, se_form, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, se_title); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNseparatorType, XmSHADOW_ETCHED_IN); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; se_sep = XtCreateManagedWidget("se_sep", xmSeparatorWidgetClass, se_form, args, n); n = 0; s1 = XmStringCreateLocalized((char *)"start:0.0 "); XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, se_sep); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNlabelString, s1); n++; XtSetArg(args[n], XmNrecomputeSize, false); n++; XtSetArg(args[n], XmNshadowThickness, 0); n++; XtSetArg(args[n], XmNhighlightThickness, 0); n++; start_number = XtCreateManagedWidget("start-number", xmLabelWidgetClass, se_form, args, n); XmStringFree(s1); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, start_number); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, start_number); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNmaximum, 100); n++; XtSetArg(args[n], XmNvalue, 0); n++; XtSetArg(args[n], XmNheight, 16); n++; XtSetArg(args[n], XmNdragCallback, n3 = make_callback_list(start_drag_callback, NULL)); n++; XtSetArg(args[n], XmNvalueChangedCallback, n3); n++; start_scale = XtCreateManagedWidget("start-scale", xmScrollBarWidgetClass, se_form, args, n); n = 0; s1 = XmStringCreateLocalized((char *)"end: 1.0 "); XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, start_number); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNlabelString, s1); n++; XtSetArg(args[n], XmNrecomputeSize, false); n++; XtSetArg(args[n], XmNshadowThickness, 0); n++; XtSetArg(args[n], XmNhighlightThickness, 0); n++; end_number = XtCreateManagedWidget("end-number", xmLabelWidgetClass, se_form, args, n); XmStringFree(s1); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, end_number); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, end_number); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNmaximum, 100); n++; XtSetArg(args[n], XmNvalue, 90); n++; XtSetArg(args[n], XmNheight, 16); n++; XtSetArg(args[n], XmNdragCallback, n4 = make_callback_list(end_drag_callback, NULL)); n++; XtSetArg(args[n], XmNvalueChangedCallback, n4); n++; end_scale = XtCreateManagedWidget("end-scale", xmScrollBarWidgetClass, se_form, args, n); /* -------- WINDOW ALPHA/BETA -------- */ n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n++; XtSetArg(args[n], XmNrightPosition, 60); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNbottomWidget, se_frame); n++; XtSetArg(args[n], XmNborderWidth, FRAME_BORDER_WIDTH); n++; XtSetArg(args[n], XmNborderColor, ss->basic_color); n++; ab_frame = XtCreateManagedWidget("ab-frame", xmFrameWidgetClass, mainform, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; n = attach_all_sides(args, n); ab_form = XtCreateManagedWidget("ab-form", xmFormWidgetClass, ab_frame, args, n); /* needed because XmFrame only accepts one child */ n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_CENTER); n++; ab_title = XtCreateManagedWidget("window parameter", xmLabelWidgetClass, ab_form, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, ab_title); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNseparatorType, XmSHADOW_ETCHED_IN); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; ab_sep = XtCreateManagedWidget("ab_sep", xmSeparatorWidgetClass, ab_form, args, n); n = 0; s1 = XmStringCreateLocalized((char *)"alpha:0.0 "); XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, ab_sep); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNlabelString, s1); n++; XtSetArg(args[n], XmNrecomputeSize, false); n++; XtSetArg(args[n], XmNshadowThickness, 0); n++; XtSetArg(args[n], XmNhighlightThickness, 0); n++; alpha_number = XtCreateManagedWidget("alpha-number", xmLabelWidgetClass, ab_form, args, n); XmStringFree(s1); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, alpha_number); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, alpha_number); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNmaximum, 100); n++; XtSetArg(args[n], XmNvalue, 0); n++; XtSetArg(args[n], XmNheight, 16); n++; XtSetArg(args[n], XmNdragCallback, n1 = make_callback_list(alpha_drag_callback, NULL)); n++; XtSetArg(args[n], XmNvalueChangedCallback, n1); n++; alpha_scale = XtCreateManagedWidget("alpha-scale", xmScrollBarWidgetClass, ab_form, args, n); n = 0; s1 = XmStringCreateLocalized((char *)"beta: 0.0 "); XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, alpha_number); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNlabelString, s1); n++; XtSetArg(args[n], XmNrecomputeSize, false); n++; XtSetArg(args[n], XmNshadowThickness, 0); n++; XtSetArg(args[n], XmNhighlightThickness, 0); n++; beta_number = XtCreateManagedWidget("beta-number", xmLabelWidgetClass, ab_form, args, n); XmStringFree(s1); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, beta_number); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, beta_number); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNmaximum, 100); n++; XtSetArg(args[n], XmNvalue, 0); n++; XtSetArg(args[n], XmNheight, 16); n++; XtSetArg(args[n], XmNdragCallback, n2 = make_callback_list(beta_drag_callback, NULL)); n++; XtSetArg(args[n], XmNvalueChangedCallback, n2); n++; beta_scale = XtCreateManagedWidget("beta-scale", xmScrollBarWidgetClass, ab_form, args, n); /* -------- WINDOW -------- */ n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n++; XtSetArg(args[n], XmNrightPosition, 30); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_POSITION); n++; XtSetArg(args[n], XmNtopPosition, 35); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNbottomWidget, ab_frame); n++; XtSetArg(args[n], XmNborderWidth, FRAME_BORDER_WIDTH); n++; XtSetArg(args[n], XmNborderColor, ss->basic_color); n++; window_frame = XtCreateManagedWidget("window-frame", xmFrameWidgetClass, mainform, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; n = attach_all_sides(args, n); window_form = XtCreateManagedWidget("window-form", xmFormWidgetClass, window_frame, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_CENTER); n++; window_label = XtCreateManagedWidget("window", xmLabelWidgetClass, window_form, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomWidget, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, window_label); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopItemPosition, ((int)fft_window(ss) > 2) ? ((int)fft_window(ss) - 1) : ((int)fft_window(ss) + 1)); n++; window_list = XmCreateScrolledList(window_form, (char *)"window-list", args, n); XtVaSetValues(window_list, XmNbackground, ss->white, XmNforeground, ss->black, NULL); for (i = 0; i < MUS_NUM_FFT_WINDOWS; i++) windows[i] = XmStringCreateLocalized((char *)mus_fft_window_name((mus_fft_window_t)i)); XtVaSetValues(window_list, XmNitems, windows, XmNitemCount, MUS_NUM_FFT_WINDOWS, XmNvisibleItemCount, 8, NULL); for (i = 0; i < MUS_NUM_FFT_WINDOWS; i++) XmStringFree(windows[i]); XtManageChild(window_list); XtAddCallback(window_list, XmNbrowseSelectionCallback, window_browse_callback, NULL); /* -------- WAVELET -------- */ n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, window_frame); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n++; XtSetArg(args[n], XmNrightPosition, 60); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_POSITION); n++; XtSetArg(args[n], XmNtopPosition, 35); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNbottomWidget, ab_frame); n++; XtSetArg(args[n], XmNborderWidth, FRAME_BORDER_WIDTH); n++; XtSetArg(args[n], XmNborderColor, ss->basic_color); n++; wavelet_frame = XtCreateManagedWidget("wavelet-frame", xmFrameWidgetClass, mainform, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; n = attach_all_sides(args, n); wavelet_form = XtCreateManagedWidget("wavelet-form", xmFormWidgetClass, wavelet_frame, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_CENTER); n++; wavelet_label = XtCreateManagedWidget("wavelet", xmLabelWidgetClass, wavelet_form, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomWidget, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, wavelet_label); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; wavelet_list = XmCreateScrolledList(wavelet_form, (char *)"wavelet-list", args, n); XtVaSetValues(wavelet_list, XmNbackground, ss->white, XmNforeground, ss->black, NULL); for (i = 0; i < NUM_WAVELETS; i++) wavelets[i] = XmStringCreateLocalized((char *)wavelet_name(i)); XtVaSetValues(wavelet_list, XmNitems, wavelets, XmNitemCount, NUM_WAVELETS, XmNvisibleItemCount, 8, NULL); for (i = 0; i < NUM_WAVELETS; i++) XmStringFree(wavelets[i]); XtManageChild(wavelet_list); XtAddCallback(wavelet_list, XmNbrowseSelectionCallback, wavelet_browse_callback, NULL); /* -------- TRANSFORM TYPE -------- */ n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n++; XtSetArg(args[n], XmNrightPosition, 30); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_POSITION); n++; XtSetArg(args[n], XmNbottomPosition, 35); n++; XtSetArg(args[n], XmNborderWidth, FRAME_BORDER_WIDTH); n++; XtSetArg(args[n], XmNborderColor, ss->basic_color); n++; type_frame = XtCreateManagedWidget("type-frame", xmFrameWidgetClass, mainform, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; n = attach_all_sides(args, n); type_form = XtCreateManagedWidget("type-form", xmFormWidgetClass, type_frame, args, n); /* needed because XmFrame only accepts one child */ n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_CENTER); n++; type_label = XtCreateManagedWidget("type", xmLabelWidgetClass, type_form, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, type_label); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; type_list = XmCreateScrolledList(type_form, (char *)"type-list", args, n); XtVaSetValues(type_list, XmNbackground, ss->white, XmNforeground, ss->black, NULL); make_transform_type_list(); XtManageChild(type_list); XtAddCallback(type_list, XmNbrowseSelectionCallback, transform_type_browse_callback, NULL); /* -------- SIZE -------- */ n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, type_frame); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n++; XtSetArg(args[n], XmNrightPosition, 60); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNbottomWidget, type_frame); n++; XtSetArg(args[n], XmNborderWidth, FRAME_BORDER_WIDTH); n++; XtSetArg(args[n], XmNborderColor, ss->basic_color); n++; size_frame = XtCreateManagedWidget("size-frame", xmFrameWidgetClass, mainform, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; n = attach_all_sides(args, n); size_form = XtCreateManagedWidget("size-form", xmFormWidgetClass, size_frame, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_CENTER); n++; size_label = XtCreateManagedWidget("size", xmLabelWidgetClass, size_form, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, size_label); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopItemPosition, (size_pos > 2) ? (size_pos - 2) : size_pos); n++; size_list = XmCreateScrolledList(size_form, (char *)"size-list", args, n); XtVaSetValues(size_list, XmNbackground, ss->white, XmNforeground, ss->black, NULL); for (i = 0; i < NUM_TRANSFORM_SIZES; i++) sizes[i] = XmStringCreateLocalized((char *)transform_size_names[i]); XtVaSetValues(size_list, XmNitems, sizes, XmNitemCount, NUM_TRANSFORM_SIZES, XmNvisibleItemCount, 6, NULL); for (i = 0; i < NUM_TRANSFORM_SIZES; i++) XmStringFree(sizes[i]); XtManageChild(size_list); XtAddCallback(size_list, XmNbrowseSelectionCallback, size_browse_callback, NULL); /* -------- DISPLAY BOX BUTTONS -------- */ n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, size_frame); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNborderWidth, FRAME_BORDER_WIDTH); n++; XtSetArg(args[n], XmNborderColor, ss->basic_color); n++; display_frame = XtCreateManagedWidget("display-frame", xmFrameWidgetClass, mainform, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->zoom_color); n++; n = attach_all_sides(args, n); display_form = XtCreateManagedWidget("display-form", xmFormWidgetClass, display_frame, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_CENTER); n++; display_label = XtCreateManagedWidget("display", xmLabelWidgetClass, display_form, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->lighter_blue); n++; XtSetArg(args[n], XmNselectColor, ss->red); n++; bstr = XmStringCreateLocalized((char *)"single transform"); XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, display_label); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNlabelString, bstr); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(args[n], XmNindicatorType, XmONE_OF_MANY); n++; normo_button = make_togglebutton_widget("normo-button", display_form, args, n); XtAddCallback(normo_button, XmNdisarmCallback, graph_transform_once_callback, NULL); XmStringFree(bstr); n = 0; XtSetArg(args[n], XmNbackground, ss->lighter_blue); n++; XtSetArg(args[n], XmNselectColor, ss->red); n++; bstr = XmStringCreateLocalized((char *)"sonogram"); XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, normo_button); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNlabelString, bstr); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(args[n], XmNindicatorType, XmONE_OF_MANY); n++; sono_button = make_togglebutton_widget("sono-button", display_form, args, n); XtAddCallback(sono_button, XmNdisarmCallback, sonogram_callback, NULL); XmStringFree(bstr); n = 0; XtSetArg(args[n], XmNbackground, ss->lighter_blue); n++; XtSetArg(args[n], XmNselectColor, ss->red); n++; bstr = XmStringCreateLocalized((char *)"spectrogram"); XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, sono_button); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNlabelString, bstr); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(args[n], XmNindicatorType, XmONE_OF_MANY); n++; spectro_button = make_togglebutton_widget("spectro-button", display_form, args, n); XtAddCallback(spectro_button, XmNdisarmCallback, spectrogram_callback, NULL); XmStringFree(bstr); n = 0; XtSetArg(args[n], XmNbackground, ss->lighter_blue); n++; XtSetArg(args[n], XmNselectColor, ss->red); n++; bstr = XmStringCreateLocalized((char *)"peaks"); XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n++; XtSetArg(args[n], XmNrightPosition, 67); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, spectro_button); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNlabelString, bstr); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; peaks_button = make_togglebutton_widget("peaks-button", display_form, args, n); XtAddCallback(peaks_button, XmNvalueChangedCallback, peaks_callback, NULL); XmStringFree(bstr); n = 0; XtSetArg(args[n], XmNbackground, ss->lighter_blue); n++; XtSetArg(args[n], XmNresizeWidth, false); n++; XtSetArg(args[n], XmNcolumns, 6); n++; XtSetArg(args[n], XmNrecomputeSize, false); n++; /* XtSetArg(args[n], XmNmarginHeight, 1); n++; */ XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, peaks_button); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, peaks_button); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNbottomWidget, peaks_button); n++; XtSetArg(args[n], XmNborderWidth, 0); n++; XtSetArg(args[n], XmNshadowThickness, 0); n++; peak_txt = make_textfield_widget("max-peaks", display_form, args, n, ACTIVATABLE, NO_COMPLETER); XtRemoveCallback(peak_txt, XmNlosingFocusCallback, textfield_unfocus_callback, NULL); XtAddCallback(peak_txt, XmNlosingFocusCallback, fft_blue_textfield_unfocus_callback, NULL); XtAddEventHandler(peak_txt, LeaveWindowMask, false, fft_blue_mouse_leave_text_callback, NULL); XtAddEventHandler(peak_txt, EnterWindowMask, false, fft_white_mouse_enter_text_callback, NULL); widget_int_to_text(peak_txt, max_transform_peaks(ss)); XtAddCallback(peak_txt, XmNactivateCallback, peaks_activate_callback, NULL); n = 0; XtSetArg(args[n], XmNbackground, ss->lighter_blue); n++; XtSetArg(args[n], XmNselectColor, ss->red); n++; bstr = XmStringCreateLocalized((char *)"dB"); XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n++; XtSetArg(args[n], XmNrightPosition, 67); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, peaks_button); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNlabelString, bstr); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; db_button = make_togglebutton_widget("db-button", display_form, args, n); XtAddCallback(db_button, XmNvalueChangedCallback, fft_db_callback, NULL); XmStringFree(bstr); n = 0; XtSetArg(args[n], XmNbackground, ss->lighter_blue); n++; XtSetArg(args[n], XmNresizeWidth, false); n++; XtSetArg(args[n], XmNcolumns, 6); n++; XtSetArg(args[n], XmNrecomputeSize, false); n++; /* XtSetArg(args[n], XmNmarginHeight, 1); n++; */ XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, db_button); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, db_button); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNbottomWidget, db_button); n++; XtSetArg(args[n], XmNborderWidth, 0); n++; XtSetArg(args[n], XmNshadowThickness, 0); n++; db_txt = make_textfield_widget("db", display_form, args, n, ACTIVATABLE, NO_COMPLETER); XtRemoveCallback(db_txt, XmNlosingFocusCallback, textfield_unfocus_callback, NULL); XtAddCallback(db_txt, XmNlosingFocusCallback, fft_blue_textfield_unfocus_callback, NULL); XtAddEventHandler(db_txt, LeaveWindowMask, false, fft_blue_mouse_leave_text_callback, NULL); XtAddEventHandler(db_txt, EnterWindowMask, false, fft_white_mouse_enter_text_callback, NULL); widget_float_to_text(db_txt, min_dB(ss)); XtAddCallback(db_txt, XmNactivateCallback, min_db_activate_callback, NULL); n = 0; XtSetArg(args[n], XmNbackground, ss->lighter_blue); n++; XtSetArg(args[n], XmNselectColor, ss->red); n++; bstr = XmStringCreateLocalized((char *)"log freq"); XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n++; XtSetArg(args[n], XmNrightPosition, 67); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, db_button); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNlabelString, bstr); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; logfreq_button = make_togglebutton_widget("logfreq-button", display_form, args, n); XtAddCallback(logfreq_button, XmNvalueChangedCallback, logfreq_callback, NULL); XmStringFree(bstr); n = 0; XtSetArg(args[n], XmNbackground, ss->lighter_blue); n++; XtSetArg(args[n], XmNresizeWidth, false); n++; XtSetArg(args[n], XmNcolumns, 6); n++; XtSetArg(args[n], XmNrecomputeSize, false); n++; /* XtSetArg(args[n], XmNmarginHeight, 1); n++; */ XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, logfreq_button); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, logfreq_button); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNbottomWidget, logfreq_button); n++; XtSetArg(args[n], XmNborderWidth, 0); n++; XtSetArg(args[n], XmNshadowThickness, 0); n++; freq_base_txt = make_textfield_widget("lfb", display_form, args, n, ACTIVATABLE, NO_COMPLETER); XtRemoveCallback(freq_base_txt, XmNlosingFocusCallback, textfield_unfocus_callback, NULL); XtAddCallback(freq_base_txt, XmNlosingFocusCallback, fft_blue_textfield_unfocus_callback, NULL); XtAddEventHandler(freq_base_txt, LeaveWindowMask, false, fft_blue_mouse_leave_text_callback, NULL); XtAddEventHandler(freq_base_txt, EnterWindowMask, false, fft_white_mouse_enter_text_callback, NULL); widget_float_to_text(freq_base_txt, log_freq_start(ss)); XtAddCallback(freq_base_txt, XmNactivateCallback, log_freq_start_activate_callback, NULL); n = 0; XtSetArg(args[n], XmNbackground, ss->lighter_blue); n++; XtSetArg(args[n], XmNselectColor, ss->red); n++; bstr = XmStringCreateLocalized((char *)"normalize"); XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, logfreq_button); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNlabelString, bstr); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; normalize_button = make_togglebutton_widget("normalize-button", display_form, args, n); XtAddCallback(normalize_button, XmNvalueChangedCallback, normalize_callback, NULL); XmStringFree(bstr); n = 0; XtSetArg(args[n], XmNbackground, ss->lighter_blue); n++; XtSetArg(args[n], XmNselectColor, ss->red); n++; bstr = XmStringCreateLocalized((char *)"selection"); XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, normalize_button); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNlabelString, bstr); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; selection_button1 = make_togglebutton_widget("selection-button", display_form, args, n); XtAddCallback(selection_button1, XmNvalueChangedCallback, selection_callback, NULL); XmStringFree(bstr); n = 0; XtSetArg(args[n], XmNbackground, ss->lighter_blue); n++; XtSetArg(args[n], XmNselectColor, ss->red); n++; bstr = XmStringCreateLocalized((char *)"with phases"); XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, selection_button1); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNlabelString, bstr); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; phases_button = make_togglebutton_widget("phases-button", display_form, args, n); XtAddCallback(phases_button, XmNvalueChangedCallback, phases_callback, NULL); XmStringFree(bstr); /* -------- GRAPH -------- */ n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, wavelet_frame); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, display_frame); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNborderWidth, FRAME_BORDER_WIDTH); n++; XtSetArg(args[n], XmNborderColor, ss->basic_color); n++; graph_frame = XtCreateManagedWidget("graph-frame", xmFrameWidgetClass, mainform, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; n = attach_all_sides(args, n); graph_form = XtCreateManagedWidget("graph-form", xmFormWidgetClass, graph_frame, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_CENTER); n++; graph_label = XtCreateManagedWidget("window", xmLabelWidgetClass, graph_form, args, n); /* label should change according to what is being displayed */ n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, graph_label); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNseparatorType, XmSHADOW_ETCHED_IN); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; gsep = XtCreateManagedWidget("gsep", xmSeparatorWidgetClass, graph_form, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->graph_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, gsep); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNallowResize, true); n++; graph_drawer = XtCreateManagedWidget("graph-drawer", xmDrawingAreaWidgetClass, graph_form, args, n); gv.function = GXcopy; XtVaGetValues(graph_drawer, XmNbackground, &gv.background, XmNforeground, &gv.foreground, NULL); gc2 = XtGetGC(graph_drawer, GCForeground | GCFunction, &gv); gv.foreground = ss->enved_waveform_color; fgc = XtGetGC(graph_drawer, GCForeground | GCFunction, &gv); XmToggleButtonSetState(normo_button, (Boolean)(transform_graph_type(ss) == GRAPH_ONCE), false); XmToggleButtonSetState(sono_button, (Boolean)(transform_graph_type(ss) == GRAPH_AS_SONOGRAM), false); XmToggleButtonSetState(spectro_button, (Boolean)(transform_graph_type(ss) == GRAPH_AS_SPECTROGRAM), false); XmToggleButtonSetState(peaks_button, (Boolean)(show_transform_peaks(ss)), false); XmToggleButtonSetState(db_button, (Boolean)(fft_log_magnitude(ss)), false); XmToggleButtonSetState(logfreq_button, (Boolean)(fft_log_frequency(ss)), false); XmToggleButtonSetState(normalize_button, (Boolean)(transform_normalization(ss) != DONT_NORMALIZE), false); XmToggleButtonSetState(selection_button1, (Boolean)(show_selection_transform(ss)), false); XmToggleButtonSetState(phases_button, (Boolean)(fft_with_phases(ss)), false); /* select current list choices */ /* display current windowing choice unless wavelet in force */ XmListSelectPos(type_list, transform_type_to_position(transform_type(ss)) + 1, false); XmListSelectPos(wavelet_list, wavelet_type(ss) + 1, false); XmListSelectPos(size_list, size_pos, false); XmListSelectPos(window_list, (int)fft_window(ss) + 1, false); if (spectrum_start(ss) != 0.0) set_spectrum_start_scale(spectrum_start(ss)); if (spectrum_end(ss) != 1.0) set_spectrum_end_scale(spectrum_end(ss)); if (fft_window_alpha(ss) != 0.0) set_alpha_scale(fft_window_alpha(ss)); if (fft_window_beta(ss) != 0.0) set_beta_scale(fft_window_beta(ss)); highlight_alpha_beta_scales(fft_window(ss)); free(n1); free(n2); free(n3); free(n4); set_dialog_widget(TRANSFORM_DIALOG, transform_dialog); XtUnmanageChild(error_frame1); } else { if (managed) raise_dialog(transform_dialog); } if (managed) { if (!XtIsManaged(transform_dialog)) XtManageChild(transform_dialog); } else XtUnmanageChild(transform_dialog); if ((need_callback) && (XtIsManaged(transform_dialog))) { set_label(graph_label, mus_fft_window_name(fft_window(ss))); get_fft_window_data(); XtAddCallback(graph_drawer, XmNresizeCallback, graph_resize_callback, NULL); XtAddCallback(graph_drawer, XmNexposeCallback, graph_resize_callback, NULL); need_callback = false; } return(transform_dialog); } bool transform_dialog_is_active(void) { return((transform_dialog) && (XtIsManaged(transform_dialog))); } /* -------- region browser -------- */ typedef struct { Widget rw, nm, pl; int pos; } regrow; static Widget region_dialog = NULL, region_list, region_grf; static regrow **region_rows = NULL; static int region_rows_size = 0; static snd_info *rsp = NULL; static int current_region = -1; static Widget reg_srtxt, reg_lentxt, reg_chntxt, reg_maxtxt; static Widget region_ww = NULL; static Widget mix_button = NULL, save_as_button = NULL, insert_button = NULL; static regrow *region_row(int n); static void set_current_region(int rg) { bool reg_ok = false; current_region = rg; reflect_region_in_save_as_dialog(); if (rg >= 0) reg_ok = region_ok(region_list_position_to_id(rg)); if (save_as_button) XtSetSensitive(save_as_button, reg_ok); if (mix_button) XtSetSensitive(mix_button, reg_ok); if (insert_button) XtSetSensitive(insert_button, reg_ok); } void reflect_regions_in_region_browser(void) { if (rsp) { int i; rsp->active = true; if (rsp->chans) for (i = 0; i < rsp->nchans; i++) rsp->chans[i]->active = CHANNEL_HAS_AXES; } } void reflect_no_regions_in_region_browser(void) { if (rsp) { int i; rsp->active = false; if (rsp->chans) for (i = 0; i < rsp->nchans; i++) rsp->chans[i]->active = CHANNEL_INACTIVE; } } static void region_update_graph(chan_info *cp) { if (current_region == -1) return; rsp->nchans = region_chans(region_list_position_to_id(current_region)); if (rsp->nchans == 0) return; update_graph(cp); rsp->nchans = 1; } void reflect_region_graph_style(void) { if (current_region == -1) return; if ((rsp) && (rsp->chans) && (rsp->chans[0]) && (region_dialog_is_active())) { rsp->chans[0]->time_graph_style = region_graph_style(ss); rsp->chans[0]->dot_size = dot_size(ss); /* update_graph(rsp->chans[0]); */ update_region_browser(true); } } static void unhighlight_region(void) { if (current_region != -1) { regrow *oldr; oldr = region_row(current_region); XtVaSetValues(oldr->rw, XmNbackground, ss->highlight_color, NULL); XtVaSetValues(oldr->nm, XmNbackground, ss->highlight_color, NULL); } } static void highlight_region(void) { if (current_region != -1) { regrow *oldr; oldr = region_row(current_region); XtVaSetValues(oldr->rw, XmNbackground, ss->zoom_color, NULL); XtVaSetValues(oldr->nm, XmNbackground, ss->zoom_color, NULL); } } static void make_region_labels(file_info *hdr) { char *str; if (hdr == NULL) return; str = (char *)calloc(PRINT_BUFFER_SIZE, sizeof(char)); snprintf(str, PRINT_BUFFER_SIZE, "srate: %d", hdr->srate); set_label(reg_srtxt, str); snprintf(str, PRINT_BUFFER_SIZE, "chans: %d", hdr->chans); set_label(reg_chntxt, str); snprintf(str, PRINT_BUFFER_SIZE, "length: %.3f", (float)((double)(hdr->samples) / (float)(hdr->chans * hdr->srate))); set_label(reg_lentxt, str); snprintf(str, PRINT_BUFFER_SIZE, "maxamp: %.3f", region_maxamp(region_list_position_to_id(current_region))); set_label(reg_maxtxt, str); free(str); } int update_region_browser(bool grf_too) { int i, len; region_state *rs; rs = region_report(); len = rs->len; for (i = 0; i < len; i++) { regrow *r; r = region_row(i); set_button_label(r->nm, rs->name[i]); #if WITH_AUDIO XmToggleButtonSetState(r->pl, false, false); #endif XtManageChild(r->rw); } for (i = len; i < max_regions(ss); i++) if (region_rows[i]) XtUnmanageChild(region_rows[i]->rw); free_region_state(rs); if (len == 0) return(0); XtManageChild(region_list); if (grf_too) { chan_info *cp; unhighlight_region(); set_current_region(0); highlight_region(); goto_window(region_rows[0]->nm); cp = rsp->chans[0]; if (cp) { cp->sound = rsp; cp->chan = 0; set_sensitive(channel_f(cp), false); set_sensitive(channel_w(cp), (region_chans(region_list_position_to_id(0)) > 1)); rsp->hdr = fixup_region_data(cp, 0, 0); make_region_labels(rsp->hdr); region_update_graph(cp); } } return(len); } static void region_quit_callback(Widget w, XtPointer context, XtPointer info) { XtUnmanageChild(region_dialog); } bool region_browser_is_active(void) { return((region_dialog) && (XtIsRealized(region_dialog))); } static void region_resize_callback(Widget w, XtPointer context, XtPointer info) { region_update_graph((chan_info *)context); } void delete_region_and_update_browser(int pos) { int act; unhighlight_region(); act = remove_region_from_list(pos); if (act == INVALID_REGION) return; if (region_dialog) { if (act != NO_REGIONS) { set_current_region(0); highlight_region(); goto_window(region_rows[0]->nm); } else set_current_region(-1); update_region_browser(1); } } static void region_help_callback(Widget w, XtPointer context, XtPointer info) { region_dialog_help(); } static void region_insert_callback(Widget w, XtPointer context, XtPointer info) { if ((current_region != -1) && (selected_channel())) paste_region(region_list_position_to_id(current_region), selected_channel()); } static void region_mix_callback(Widget w, XtPointer context, XtPointer info) { if ((current_region != -1) && (selected_channel())) add_region(region_list_position_to_id(current_region), selected_channel()); } static void region_save_callback(Widget w, XtPointer context, XtPointer info) { if ((current_region != -1) && (XmGetFocusWidget(region_dialog) == XmMessageBoxGetChild(region_dialog, XmDIALOG_OK_BUTTON))) make_region_save_as_dialog(true); } static void region_up_arrow_callback(Widget w, XtPointer context, XtPointer info) { chan_info *cp; cp = rsp->chans[0]; cp->sound = rsp; if (cp->chan > 0) { cp->chan--; set_sensitive(channel_f(cp), (cp->chan > 0)); set_sensitive(channel_w(cp), true); fixup_region_data(cp, cp->chan, current_region); region_update_graph(cp); } } static void region_down_arrow_callback(Widget w, XtPointer context, XtPointer info) { chan_info *cp; cp = rsp->chans[0]; cp->sound = rsp; if ((cp->chan + 1) < region_chans(region_list_position_to_id(current_region))) { cp->chan++; set_sensitive(channel_f(cp), true); set_sensitive(channel_w(cp), (region_chans(region_list_position_to_id(current_region)) > (cp->chan + 1))); fixup_region_data(cp, cp->chan, current_region); region_update_graph(cp); } } static void region_focus_callback(Widget w, XtPointer context, XtPointer info) { static oclock_t mouse_down_time = 0; XmPushButtonCallbackStruct *cb = (XmPushButtonCallbackStruct *)info; XButtonEvent *ev; chan_info *cp; regrow *r = (regrow *)context; ev = (XButtonEvent *)(cb->event); if (mouse_down_time != 0) { if ((ev->time - mouse_down_time) < ss->click_time) /* edit region if double clicked */ { mouse_down_time = ev->time; if (current_region != -1) region_edit(current_region); return; } } mouse_down_time = ev->time; unhighlight_region(); if (region_list_position_to_id(r->pos) == INVALID_REGION) return; /* needed by auto-tester */ set_current_region(r->pos); cp = rsp->chans[0]; cp->sound = rsp; cp->chan = 0; highlight_region(); set_sensitive(channel_f(cp), false); set_sensitive(channel_w(cp), (region_chans(region_list_position_to_id(current_region)) > 1)); rsp->hdr = fixup_region_data(cp, 0, current_region); if (rsp->hdr == NULL) return; make_region_labels(rsp->hdr); region_update_graph(cp); } void reflect_play_region_stop(int n) { #if WITH_AUDIO if (region_rows) { regrow *rg; rg = region_row(region_id_to_list_position(n)); if (rg) XmToggleButtonSetState(rg->pl, false, false); } #endif } static void region_play_callback(Widget w, XtPointer context, XtPointer info) { #if WITH_AUDIO regrow *r = (regrow *)context; if (XmToggleButtonGetState(r->pl)) play_region(region_list_position_to_id(r->pos), IN_BACKGROUND); else stop_playing_region(region_list_position_to_id(r->pos), PLAY_BUTTON_UNSET); #endif } static Xen reflect_file_in_region_browser(Xen hook_or_reason) { if (region_dialog) { bool file_on; file_on = (bool)(any_selected_sound()); set_sensitive(mix_button, file_on); set_sensitive(insert_button, file_on); } return(Xen_false); } Xen_wrap_1_arg(reflect_file_in_region_browser_w, reflect_file_in_region_browser) static char *regrow_get_label(void *ur) { regrow *r = (regrow *)ur; return(get_label(r->nm)); } static int regrow_get_pos(void *ur) { regrow *r = (regrow *)ur; return(r->pos); } static void regrow_mouse_enter_label(Widget w, XtPointer context, XEvent *event, Boolean *flag) { mouse_enter_label(context, REGION_VIEWER); } static void regrow_mouse_leave_label(Widget w, XtPointer context, XEvent *event, Boolean *flag) { mouse_leave_label(context, REGION_VIEWER); } static regrow *make_regrow(Widget ww, Widget last_row, XtCallbackProc play_callback, XtCallbackProc name_callback) { int n; Arg args[32]; regrow *r; XmString s1; #if WITH_AUDIO XtCallbackList n1; #endif XtCallbackList n3; s1 = XmStringCreateLocalized((char *)""); r = (regrow *)calloc(1, sizeof(regrow)); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, (last_row) ? XmATTACH_WIDGET : XmATTACH_FORM); n++; if (last_row) {XtSetArg(args[n], XmNtopWidget, last_row); n++;} XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNheight, 18); n++; r->rw = XtCreateWidget("rw", xmFormWidgetClass, ww, args, n); #if WITH_AUDIO n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNselectColor, ss->selection_color); n++; XtSetArg(args[n], XmNlabelString, s1); n++; XtSetArg(args[n], XmNvalueChangedCallback, n1 = make_callback_list(play_callback, (XtPointer)r)); n++; if (ss->toggle_size > 0) {XtSetArg(args[n], XmNindicatorSize, ss->toggle_size); n++;} XtSetArg(args[n], XmNmarginWidth, 8); n++; r->pl = make_togglebutton_widget("pl", r->rw, args, n); #endif n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; #if WITH_AUDIO XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, r->pl); n++; #else XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; #endif XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNshadowThickness, 0); n++; XtSetArg(args[n], XmNhighlightThickness, 0); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(args[n], XmNfillOnArm, false); n++; XtSetArg(args[n], XmNrecomputeSize, false); n++; XtSetArg(args[n], XmNwidth, 300); n++; XtSetArg(args[n], XmNactivateCallback, n3 = make_callback_list(name_callback, (XtPointer)r)); n++; r->nm = XtCreateManagedWidget("nm", xmPushButtonWidgetClass, r->rw, args, n); XmStringFree(s1); XtAddEventHandler(r->nm, EnterWindowMask, false, regrow_mouse_enter_label, (XtPointer)r); XtAddEventHandler(r->nm, LeaveWindowMask, false, regrow_mouse_leave_label, (XtPointer)r); #if WITH_AUDIO free(n1); #endif free(n3); return(r); } static void make_region_dialog(void) { int n, i, id; Arg args[32]; Widget formw, last_row, infosep; Widget panes, toppane, sep1 = NULL, sep2; #if WITH_AUDIO Widget plw; #endif XmString xgo_away, xhelp, titlestr, xsave_as; regrow *r; chan_info *cp; xgo_away = XmStringCreateLocalized((char *)I_GO_AWAY); xhelp = XmStringCreateLocalized((char *)I_HELP); titlestr = XmStringCreateLocalized((char *)"Regions"); xsave_as = XmStringCreateLocalized((char *)"Save as"); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNcancelLabelString, xgo_away); n++; XtSetArg(args[n], XmNhelpLabelString, xhelp); n++; XtSetArg(args[n], XmNokLabelString, xsave_as); n++; XtSetArg(args[n], XmNautoUnmanage, false); n++; XtSetArg(args[n], XmNdialogTitle, titlestr); n++; XtSetArg(args[n], XmNresizePolicy, XmRESIZE_GROW); n++; XtSetArg(args[n], XmNnoResize, false); n++; XtSetArg(args[n], XmNtransient, false); n++; region_dialog = XmCreateTemplateDialog(MAIN_SHELL(ss), (char *)"Regions", args, n); save_as_button = XmMessageBoxGetChild(region_dialog, XmDIALOG_OK_BUTTON); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNarmColor, ss->selection_color); n++; insert_button = XtCreateManagedWidget("Insert", xmPushButtonGadgetClass, region_dialog, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNarmColor, ss->selection_color); n++; mix_button = XtCreateManagedWidget("Mix", xmPushButtonGadgetClass, region_dialog, args, n); /* XtAddCallback(region_dialog, XmNokCallback, region_save_callback, NULL); */ XtAddCallback(save_as_button, XmNactivateCallback, region_save_callback, NULL); XtAddCallback(region_dialog, XmNcancelCallback, region_quit_callback, NULL); XtAddCallback(region_dialog, XmNhelpCallback, region_help_callback, NULL); XtAddCallback(mix_button, XmNactivateCallback, region_mix_callback, NULL); XtAddCallback(insert_button, XmNactivateCallback, region_insert_callback, NULL); XmStringFree(xhelp); XmStringFree(xgo_away); XmStringFree(xsave_as); XmStringFree(titlestr); XtVaSetValues(XmMessageBoxGetChild(region_dialog, XmDIALOG_OK_BUTTON), XmNarmColor, ss->selection_color, NULL); XtVaSetValues(XmMessageBoxGetChild(region_dialog, XmDIALOG_CANCEL_BUTTON), XmNarmColor, ss->selection_color, NULL); XtVaSetValues(XmMessageBoxGetChild(region_dialog, XmDIALOG_HELP_BUTTON), XmNarmColor, ss->selection_color, NULL); XtVaSetValues(XmMessageBoxGetChild(region_dialog, XmDIALOG_OK_BUTTON), XmNbackground, ss->highlight_color, NULL); XtVaSetValues(XmMessageBoxGetChild(region_dialog, XmDIALOG_CANCEL_BUTTON), XmNbackground, ss->highlight_color, NULL); XtVaSetValues(XmMessageBoxGetChild(region_dialog, XmDIALOG_HELP_BUTTON), XmNbackground, ss->highlight_color, NULL); insert_button = XmMessageBoxGetChild(region_dialog, XmDIALOG_CANCEL_BUTTON); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNbottomWidget, XmMessageBoxGetChild(region_dialog, XmDIALOG_SEPARATOR)); n++; formw = XtCreateManagedWidget("formw", xmFormWidgetClass, region_dialog, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, sep1); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNallowResize, true); n++; XtSetArg(args[n], XmNpaneMaximum, LOTSA_PIXELS); n++; panes = XtCreateManagedWidget("panes", xmPanedWindowWidgetClass, formw, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; n = attach_all_sides(args, n); XtSetArg(args[n], XmNpaneMinimum, 40); n++; toppane = XtCreateManagedWidget("toppane", xmFormWidgetClass, panes, args, n); #if WITH_AUDIO n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; plw = XtCreateManagedWidget("play", xmLabelWidgetClass, toppane, args, n); #endif n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNseparatorType, XmNO_LINE); n++; XtSetArg(args[n], XmNheight, 8); n++; sep2 = XtCreateManagedWidget("sep2", xmSeparatorWidgetClass, toppane, args, n); n = 0; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n++; XtSetArg(args[n], XmNrightPosition, 70); n++; #if WITH_AUDIO XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, plw); n++; #else XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; #endif XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNbottomWidget, sep2); n++; XtSetArg(args[n], XmNscrollingPolicy, XmAUTOMATIC); n++; XtSetArg(args[n], XmNscrollBarDisplayPolicy, XmSTATIC); n++; region_list = XmCreateScrolledWindow(toppane, (char *)"reglist", args, n); n = attach_all_sides(args, 0); region_ww = XtCreateManagedWidget("ww", xmFormWidgetClass, region_list, args, n); XtVaSetValues(region_list, XmNworkWindow, region_ww, NULL); map_over_children(region_list, set_main_color_of_widget); last_row = NULL; region_rows = (regrow **)calloc(max_regions(ss), sizeof(regrow *)); region_rows_size = max_regions(ss); for (i = 0; i < max_regions(ss); i++) { r = make_regrow(region_ww, last_row, region_play_callback, region_focus_callback); region_rows[i] = r; r->pos = i; last_row = r->rw; } update_region_browser(0); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, region_list); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; #if WITH_AUDIO XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, plw); n++; #else XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; #endif XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNorientation, XmVERTICAL); n++; XtSetArg(args[n], XmNseparatorType, XmNO_LINE); n++; XtSetArg(args[n], XmNwidth, 8); n++; infosep = XtCreateManagedWidget("infosep", xmSeparatorWidgetClass, toppane, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, infosep); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; #if WITH_AUDIO XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, plw); n++; #else XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; #endif XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; reg_srtxt = XtCreateManagedWidget("srate:", xmLabelWidgetClass, toppane, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, infosep); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, reg_srtxt); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; reg_chntxt = XtCreateManagedWidget("chans:", xmLabelWidgetClass, toppane, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, infosep); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, reg_chntxt); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; reg_lentxt = XtCreateManagedWidget("length:", xmLabelWidgetClass, toppane, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, infosep); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, reg_lentxt); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; reg_maxtxt = XtCreateManagedWidget("maxamp:", xmLabelWidgetClass, toppane, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->white); n++; n = attach_all_sides(args, n); XtSetArg(args[n], XmNpaneMinimum, 150); n++; region_grf = XtCreateManagedWidget("grf", xmFormWidgetClass, panes, args, n); XtManageChild(region_dialog); if (widget_width(region_dialog) < 400) set_widget_width(region_dialog, 400); id = region_list_position_to_id(0); rsp = make_simple_channel_display(region_srate(id), region_len(id), WITH_ARROWS, region_graph_style(ss), region_grf, WITHOUT_EVENTS); rsp->inuse = SOUND_REGION; set_current_region(0); cp = rsp->chans[0]; XtVaSetValues(region_rows[0]->nm, XmNbackground, ss->white, XmNforeground, ss->black, NULL); map_over_children(panes, color_sashes); XtVaSetValues(toppane, XmNpaneMinimum, 1, NULL); XtVaSetValues(region_grf, XmNpaneMinimum, 1, NULL); XtAddCallback(channel_graph(cp), XmNresizeCallback, region_resize_callback, (XtPointer)cp); XtAddCallback(channel_graph(cp), XmNexposeCallback, region_resize_callback, (XtPointer)cp); /* channel_f is up arrow, channel_w is down arrow */ XtAddCallback(channel_f(cp), XmNactivateCallback, region_up_arrow_callback, NULL); XtAddCallback(channel_w(cp), XmNactivateCallback, region_down_arrow_callback, NULL); set_sensitive(channel_f(cp), false); set_sensitive(channel_w(cp), (region_chans(region_list_position_to_id(0)) > 1)); cp->chan = 0; rsp->hdr = fixup_region_data(cp, 0, 0); make_region_labels(rsp->hdr); highlight_region(); region_update_graph(cp); Xen_add_to_hook_list(ss->snd_open_file_hook, reflect_file_in_region_browser_w, "region-dialog-open-file-watcher", "region dialog open-file-hook handler"); set_dialog_widget(REGION_DIALOG, region_dialog); } static void view_region_callback(Widget w, XtPointer context, XtPointer info) { /* put up scrollable dialog describing/playing/editing the region list */ if (region_dialog == NULL) make_region_dialog(); else raise_dialog(region_dialog); if (!XtIsManaged(region_dialog)) { set_current_region(0); XtManageChild(region_dialog); } } bool region_dialog_is_active(void) { return((region_dialog != NULL) && (XtIsManaged(region_dialog))); } void allocate_region_rows(int n) { if ((region_dialog) && (n > region_rows_size)) { int i; region_rows = (regrow **)realloc(region_rows, n * sizeof(regrow *)); for (i = region_rows_size; i < n; i++) region_rows[i] = NULL; region_rows_size = n; } } static regrow *region_row(int n) { if (n < region_rows_size) { regrow *r; if (region_rows[n] == NULL) { r = make_regrow(region_ww, (n > 0) ? (region_rows[n - 1]->rw) : NULL, region_play_callback, region_focus_callback); region_rows[n] = r; r->pos = n; } return(region_rows[n]); } return(NULL); } static int region_dialog_region(void) { return(region_list_position_to_id(current_region)); } static Xen g_view_regions_dialog(void) { #define H_view_regions_dialog "(" S_view_regions_dialog "): start the region dialog" if (snd_regions() > 0) view_region_callback(MAIN_PANE(ss), NULL, NULL); return(Xen_wrap_widget(region_dialog)); } Xen_wrap_no_args(g_view_regions_dialog_w, g_view_regions_dialog) void g_init_gxregion(void) { Xen_define_safe_procedure(S_view_regions_dialog, g_view_regions_dialog_w, 0, 0, 0, H_view_regions_dialog); } #include "snd-file.h" /* various file-related dialogs: File|Edit:Save-as File:Open|View File|Edit:Mix File:Insert File:Edit-Header File:New Info and Raw View:Files */ static void snd_sort(int sorter, sort_info **data, int len); /* -------------------------------- sorters -------------------------------- */ static mus_long_t file_bytes(const char *filename) { #ifndef _MSC_VER struct stat statbuf; if (stat(filename, &statbuf) >= 0) return(statbuf.st_size); return(0); #else int chan; mus_long_t bytes; chan = mus_file_open_read(filename); if (chan == -1) return(0); bytes = lseek(chan, 0L, SEEK_END); snd_close(chan, filename); return(bytes); #endif } /* sort files list by name (aphabetical), or some number (date written, size), or by xen proc */ static int sort_a_to_z(const void *a, const void *b) { sort_info *d1 = *(sort_info **)a; sort_info *d2 = *(sort_info **)b; return(strcmp(d1->filename, d2->filename)); } static int sort_z_to_a(const void *a, const void *b) { return(-sort_a_to_z(a, b)); } static int sort_small_to_big(const void *a, const void *b) { sort_info *d1 = *(sort_info **)a; sort_info *d2 = *(sort_info **)b; if (d1->samps > d2->samps) return(1); else { if (d1->samps == d2->samps) return(0); else return(-1); } } static int sort_big_to_small(const void *a, const void *b) { return(-sort_small_to_big(a, b)); } static int sort_new_to_old(const void *a, const void *b) { sort_info *d1 = *(sort_info **)a; sort_info *d2 = *(sort_info **)b; if (d1->time < d2->time) return(1); else { if (d1->time == d2->time) return(0); else return(-1); } } static int sort_old_to_new(const void *a, const void *b) { return(-sort_new_to_old(a, b)); } static Xen sorter_func; static int sort_xen(const void *a, const void *b) { /* sorter function gets two names, returns -1, 0, or 1 just like the other comparators */ sort_info *d1 = *(sort_info **)a; sort_info *d2 = *(sort_info **)b; return(Xen_integer_to_C_int(Xen_call_with_2_args(sorter_func, C_string_to_Xen_string(d1->full_filename), C_string_to_Xen_string(d2->full_filename), "sort func"))); } static void snd_sort(int sorter, sort_info **data, int len) { int i, sorter_pos; switch (sorter) { case SORT_A_TO_Z: qsort((void *)data, len, sizeof(sort_info *), sort_a_to_z); break; case SORT_Z_TO_A: qsort((void *)data, len, sizeof(sort_info *), sort_z_to_a); break; case SORT_NEW_TO_OLD: for (i = 0; i < len; i++) data[i]->time = file_write_date(data[i]->full_filename); qsort((void *)data, len, sizeof(sort_info *), sort_new_to_old); break; case SORT_OLD_TO_NEW: for (i = 0; i < len; i++) data[i]->time = file_write_date(data[i]->full_filename); qsort((void *)data, len, sizeof(sort_info *), sort_old_to_new); break; case SORT_SMALL_TO_BIG: for (i = 0; i < len; i++) data[i]->samps = file_bytes(data[i]->full_filename); qsort((void *)data, len, sizeof(sort_info *), sort_small_to_big); break; case SORT_BIG_TO_SMALL: for (i = 0; i < len; i++) data[i]->samps = file_bytes(data[i]->full_filename); qsort((void *)data, len, sizeof(sort_info *), sort_big_to_small); break; default: case SORT_XEN: /* sorter is SORT_XEN + index into file_sorters list */ /* that list is a vector of pairs (name proc) */ sorter_pos = sorter - SORT_XEN; if ((sorter_pos >= 0) && (sorter_pos < ss->file_sorters_size)) { if (Xen_is_list(Xen_vector_ref(ss->file_sorters, sorter_pos))) { sorter_func = Xen_cadr(Xen_vector_ref(ss->file_sorters, sorter_pos)); qsort((void *)data, len, sizeof(sort_info *), sort_xen); return; } } snd_warning("no such file-sorter (%d)", sorter_pos); break; } } static void dialog_set_title(widget_t dialog, const char *titlestr) { XmString title; title = XmStringCreateLocalized((char *)titlestr); XtVaSetValues(dialog, XmNdialogTitle, title, NULL); XmStringFree(title); } void cleanup_file_monitor(void) {} static bool initialize_file_monitor(void) {return(false);} void *unmonitor_file(void *watcher) {return(NULL);} void monitor_sound(snd_info *sp) {} /* -------------------------------------------------------------------------------- */ #define FSB_BOX(Dialog, Child) XmFileSelectionBoxGetChild(Dialog, Child) #define MSG_BOX(Dialog, Child) XmMessageBoxGetChild(Dialog, Child) /* ---------------- open/mix/insert/save-as dialogs ---------------- */ static void color_file_selection_box(Widget w) { /* overwrite most Motif-default colors */ Widget wtmp; map_over_children(w, set_main_color_of_widget); XtVaSetValues(FSB_BOX(w, XmDIALOG_DIR_LIST), XmNbackground, ss->white, XmNforeground, ss->black, NULL); XtVaSetValues(FSB_BOX(w, XmDIALOG_LIST), XmNbackground, ss->white, XmNforeground, ss->black, NULL); XtVaSetValues(FSB_BOX(w, XmDIALOG_CANCEL_BUTTON), XmNarmColor, ss->selection_color, NULL); XtVaSetValues(FSB_BOX(w, XmDIALOG_HELP_BUTTON), XmNarmColor, ss->selection_color, NULL); XtVaSetValues(FSB_BOX(w, XmDIALOG_OK_BUTTON), XmNarmColor, ss->selection_color, NULL); XtVaSetValues(FSB_BOX(w, XmDIALOG_CANCEL_BUTTON), XmNbackground, ss->highlight_color, NULL); XtVaSetValues(FSB_BOX(w, XmDIALOG_HELP_BUTTON), XmNbackground, ss->highlight_color, NULL); XtVaSetValues(FSB_BOX(w, XmDIALOG_OK_BUTTON), XmNbackground, ss->highlight_color, NULL); wtmp = FSB_BOX(w, XmDIALOG_TEXT); if (wtmp) { XtVaSetValues(wtmp, XmNhighlightThickness, 1, NULL); XtAddCallback(wtmp, XmNfocusCallback, textfield_focus_callback, NULL); XtAddCallback(wtmp, XmNlosingFocusCallback, textfield_unfocus_callback, NULL); XtAddEventHandler(wtmp, EnterWindowMask, false, mouse_enter_text_callback, NULL); XtAddEventHandler(wtmp, LeaveWindowMask, false, mouse_leave_text_callback, NULL); } wtmp = FSB_BOX(w, XmDIALOG_FILTER_TEXT); if (wtmp) { XtVaSetValues(wtmp, XmNhighlightThickness, 1, NULL); XtAddCallback(wtmp, XmNfocusCallback, textfield_focus_callback, NULL); XtAddCallback(wtmp, XmNlosingFocusCallback, textfield_unfocus_callback, NULL); XtAddEventHandler(wtmp, EnterWindowMask, false, mouse_enter_text_callback, NULL); XtAddEventHandler(wtmp, LeaveWindowMask, false, mouse_leave_text_callback, NULL); } } static void force_directory_reread(Widget dialog) { /* force update, but make sure the filename is not reset to its (dumb) default */ XmString dirmask; Widget name_field; char *filename = NULL; name_field = FSB_BOX(dialog, XmDIALOG_TEXT); filename = XmTextGetString(name_field); XtVaGetValues(dialog, XmNdirMask, &dirmask, NULL); XmFileSelectionDoSearch(dialog, dirmask); XmStringFree(dirmask); XmTextSetString(name_field, filename); if (filename) { XmTextSetCursorPosition(name_field, mus_strlen(filename)); XtFree(filename); } } static void force_directory_reread_and_let_filename_change(Widget dialog) { XmString dirmask; XtVaGetValues(dialog, XmNdirMask, &dirmask, NULL); XmFileSelectionDoSearch(dialog, dirmask); XmStringFree(dirmask); } /* -------------------------------- file list positioning -------------------------------- */ typedef struct { char *directory_name; position_t list_top; } dirpos_info; typedef struct { dirpos_info **dirs; int size, top; } dirpos_list; void dirpos_update(dirpos_list *dl, const char *dir, position_t pos); position_t dirpos_list_top(dirpos_list *dl, const char *dirname); dirpos_list *make_dirpos_list(void); static dirpos_info *make_dirpos_info(const char *dir, position_t pos) { dirpos_info *dp; dp = (dirpos_info *)calloc(1, sizeof(dirpos_info)); dp->directory_name = mus_strdup(dir); dp->list_top = pos; return(dp); } dirpos_list *make_dirpos_list(void) { dirpos_list *dl; dl = (dirpos_list *)calloc(1, sizeof(dirpos_list)); dl->size = 8; dl->top = 0; dl->dirs = (dirpos_info **)calloc(dl->size, sizeof(dirpos_info *)); return(dl); } void dirpos_update(dirpos_list *dl, const char *dir, position_t pos) { int i; if (!dl) return; for (i = 0; i < dl->top; i++) { if ((dl->dirs[i]) && (mus_strcmp(dir, dl->dirs[i]->directory_name))) { dirpos_info *dp; dp = dl->dirs[i]; dp->list_top = pos; return; } } if (dl->top >= dl->size) { int old_size; old_size = dl->size; dl->size += 8; dl->dirs = (dirpos_info **)realloc(dl->dirs, dl->size * sizeof(dirpos_info *)); for (i = old_size; i < dl->size; i++) dl->dirs[i] = NULL; } dl->dirs[dl->top++] = make_dirpos_info(dir, pos); } position_t dirpos_list_top(dirpos_list *dl, const char *dirname) { int i; if (dl) for (i = 0; i < dl->top; i++) if ((dl->dirs[i]) && (mus_strcmp(dirname, dl->dirs[i]->directory_name))) return(dl->dirs[i]->list_top); return(POSITION_UNKNOWN); } /* -------- popups -------- */ /* I think there is no way to get a key action to popup one of these menus -- Xm/RowColumn.c * appears to insist on a button event, and any change to that via XmNmenuPost gets an * error. Perhaps we should notice the POPUP_BUTTON setting however? */ typedef struct file_pattern_info { /* just-sounds file lists */ bool reread_directory; bool in_just_sounds_update; Widget dialog, just_sounds_button; char *last_dir; dir_info *current_files; void *directory_watcher; int filter_choice, sorter_choice; dirpos_list *dir_list; } file_pattern_info; /* popups: * text: history of previous choices, * list: sort and filter choices * dir: higher level dir choices * filter: history of previous choices */ typedef struct file_popup_info { Widget dialog; Widget file_text_popup, file_list_popup, file_dir_popup, file_filter_popup; Widget file_text_popup_label, file_filter_popup_label, file_dir_popup_label, file_list_popup_label; /* file_filter here refers to the dialog filter field, not file-filters */ char **file_text_names, **file_filter_names; /* history of choices as array of strings */ Widget *file_text_items, *file_filter_items, *file_dir_items, *file_list_items; /* menu items */ int file_list_items_size; file_pattern_info *fp; } file_popup_info; /* file popup */ static void file_text_item_activate_callback(Widget w, XtPointer context, XtPointer info) { file_popup_info *fd = (file_popup_info *)context; char *filename; snd_info *sp; filename = get_label(w); XmTextFieldSetString(FSB_BOX(fd->dialog, XmDIALOG_TEXT), filename); ss->open_requestor = FROM_OPEN_DIALOG_POPUP; ss->open_requestor_data = NULL; sp = snd_open_file(filename, FILE_READ_WRITE); if (sp) select_channel(sp, 0); XtUnmanageChild(fd->dialog); if (filename) XtFree(filename); } #define FILE_TEXT_POPUP_LABEL "previous files" static void file_text_popup_callback(Widget w, XtPointer context, XtPointer info) { file_popup_info *fd = (file_popup_info *)context; XmPopupHandlerCallbackStruct *cb = (XmPopupHandlerCallbackStruct *)info; XEvent *e; e = cb->event; if (e->type == ButtonPress) { /* position menu to match current text widget, show previous choices, if any else "[no previous choices]" */ /* XmMenuPosition(popup_menu, event) happens automatically */ char *current_filename; int i, filenames_to_display = 0; if (fd->file_text_items == NULL) { int n = 0; Arg args[12]; fd->file_text_items = (Widget *)calloc(FILENAME_LIST_SIZE, sizeof(Widget)); XtSetArg(args[n], XmNbackground, ss->lighter_blue); n++; for (i = 0; i < FILENAME_LIST_SIZE; i++) { fd->file_text_items[i] = XtCreateWidget("", xmPushButtonWidgetClass, fd->file_text_popup, args, n); XtAddCallback(fd->file_text_items[i], XmNactivateCallback, file_text_item_activate_callback, (void *)fd); } } current_filename = XmTextFieldGetString(FSB_BOX(fd->dialog, XmDIALOG_TEXT)); /* w is probably ok here (assumes only text triggers this) */ for (i = 0; i < FILENAME_LIST_SIZE; i++) if ((fd->file_text_names[i]) && (mus_file_probe(fd->file_text_names[i])) && (!(mus_strcmp(fd->file_text_names[i], current_filename)))) { set_label(fd->file_text_items[filenames_to_display], fd->file_text_names[i]); XtManageChild(fd->file_text_items[filenames_to_display]); filenames_to_display++; } for (i = filenames_to_display; i < FILENAME_LIST_SIZE; i++) if ((fd->file_text_items[i]) && (XtIsManaged(fd->file_text_items[i]))) XtUnmanageChild(fd->file_text_items[i]); XtFree(current_filename); /* why was this commented out? */ if (filenames_to_display == 0) set_label(fd->file_text_popup_label, "no " FILE_TEXT_POPUP_LABEL); else set_label(fd->file_text_popup_label, FILE_TEXT_POPUP_LABEL); cb->menuToPost = fd->file_text_popup; } } /* filter popup */ static void file_filter_text_activate_callback(Widget w, XtPointer context, XtPointer info) { file_popup_info *fd = (file_popup_info *)context; char *filter; filter = XmTextFieldGetString(w); if (filter) { remember_filename(filter, fd->file_filter_names); XtFree(filter); force_directory_reread_and_let_filename_change(fd->dialog); } } static void file_filter_item_activate_callback(Widget w, XtPointer context, XtPointer info) { file_popup_info *fd = (file_popup_info *)context; Widget text; char *filtername; filtername = get_label(w); text = FSB_BOX(fd->dialog, XmDIALOG_FILTER_TEXT); XmTextFieldSetString(text, filtername); force_directory_reread(fd->dialog); if (filtername) XtFree(filtername); } #define FILE_FILTER_POPUP_LABEL "previous filters" static void file_filter_popup_callback(Widget w, XtPointer context, XtPointer info) { file_popup_info *fd = (file_popup_info *)context; XmPopupHandlerCallbackStruct *cb = (XmPopupHandlerCallbackStruct *)info; XEvent *e; e = cb->event; if (e->type == ButtonPress) { char *current_filtername; int i, filternames_to_display = 0; if (fd->file_filter_items == NULL) { int n = 0; Arg args[12]; fd->file_filter_items = (Widget *)calloc(FILENAME_LIST_SIZE, sizeof(Widget)); XtSetArg(args[n], XmNbackground, ss->lighter_blue); n++; for (i = 0; i < FILENAME_LIST_SIZE; i++) { fd->file_filter_items[i] = XtCreateWidget("", xmPushButtonWidgetClass, fd->file_filter_popup, args, n); XtAddCallback(fd->file_filter_items[i], XmNactivateCallback, file_filter_item_activate_callback, (void *)fd); } } current_filtername = XmTextFieldGetString(FSB_BOX(fd->dialog, XmDIALOG_FILTER_TEXT)); for (i = 0; i < FILENAME_LIST_SIZE; i++) if ((fd->file_filter_names[i]) && (!(mus_strcmp(fd->file_filter_names[i], current_filtername)))) { set_label(fd->file_filter_items[filternames_to_display], fd->file_filter_names[i]); XtManageChild(fd->file_filter_items[filternames_to_display]); filternames_to_display++; } for (i = filternames_to_display; i < FILENAME_LIST_SIZE; i++) if ((fd->file_filter_items[i]) && (XtIsManaged(fd->file_filter_items[i]))) XtUnmanageChild(fd->file_filter_items[i]); XtFree(current_filtername); /* if (filternames_to_display == 0) set_label(fd->file_filter_popup_label, "no " FILE_FILTER_POPUP_LABEL); else set_label(fd->file_filter_popup_label, FILE_FILTER_POPUP_LABEL); */ cb->menuToPost = fd->file_filter_popup; } } /* dir list popup */ static void update_dir_list(Widget dialog, char *filter) { Widget text; text = FSB_BOX(dialog, XmDIALOG_FILTER_TEXT); XmTextFieldSetString(text, filter); force_directory_reread(dialog); } static void file_dir_item_activate_callback(Widget w, XtPointer context, XtPointer info) { file_popup_info *fd = (file_popup_info *)context; char *name, *filter; name = get_label(w); filter = mus_format("%s/*", name); update_dir_list(fd->dialog, filter); if (name) XtFree(name); free(filter); } #define FILE_DIR_POPUP_LABEL "dirs" /* dir_items, but strs generated on the fly, current in filter text */ static void file_dir_popup_callback(Widget w, XtPointer context, XtPointer info) { file_popup_info *fd = (file_popup_info *)context; XmPopupHandlerCallbackStruct *cb = (XmPopupHandlerCallbackStruct *)info; XEvent *e; e = cb->event; if (e->type == ButtonPress) { char *current_filename = NULL; int i, dirs_to_display = 0; if (fd->file_dir_items == NULL) { int n = 0; Arg args[12]; fd->file_dir_items = (Widget *)calloc(FILENAME_LIST_SIZE, sizeof(Widget)); XtSetArg(args[n], XmNbackground, ss->lighter_blue); n++; for (i = 0; i < FILENAME_LIST_SIZE; i++) { fd->file_dir_items[i] = XtCreateWidget("", xmPushButtonWidgetClass, fd->file_dir_popup, args, n); XtAddCallback(fd->file_dir_items[i], XmNactivateCallback, file_dir_item_activate_callback, (void *)fd); } } { XmStringTable items; int num_dirs; XtVaGetValues(fd->dialog, XmNdirListItems, &items, XmNdirListItemCount, &num_dirs, NULL); if (num_dirs > 0) current_filename = (char *)XmStringUnparse(items[0], NULL, XmCHARSET_TEXT, XmCHARSET_TEXT, NULL, 0, XmOUTPUT_ALL); } if (!current_filename) { current_filename = XmTextFieldGetString(FSB_BOX(fd->dialog, XmDIALOG_FILTER_TEXT)); if (!current_filename) current_filename = XmTextFieldGetString(FSB_BOX(fd->dialog, XmDIALOG_TEXT)); } if (current_filename) { int len; len = strlen(current_filename); for (i = 0; i < len; i++) if (current_filename[i] == '/') dirs_to_display++; if (dirs_to_display > FILENAME_LIST_SIZE) dirs_to_display = FILENAME_LIST_SIZE; if (dirs_to_display > 0) { char **dirs; int j = 1; dirs = (char **)calloc(dirs_to_display, sizeof(char *)); dirs[0] = mus_strdup("/"); for (i = 1; i < len; i++) if (current_filename[i] == '/') { dirs[j] = (char *)calloc(i + 1, sizeof(char)); strncpy(dirs[j], (const char *)current_filename, i); j++; } for (i = 0; i < dirs_to_display; i++) { set_label(fd->file_dir_items[i], dirs[i]); XtManageChild(fd->file_dir_items[i]); free(dirs[i]); } free(dirs); } } for (i = dirs_to_display; i < FILENAME_LIST_SIZE; i++) if ((fd->file_dir_items[i]) && (XtIsManaged(fd->file_dir_items[i]))) XtUnmanageChild(fd->file_dir_items[i]); XtFree(current_filename); cb->menuToPost = fd->file_dir_popup; } } #define FILE_LIST_POPUP_LABEL "sort/filter" #define NO_FILTER_LABEL "no filter" #define FILE_FILTER_OFFSET 1024 #define NO_FILE_FILTER_OFFSET 2048 static void sort_files_and_redisplay(file_pattern_info *fp); static void file_list_item_activate_callback(Widget w, XtPointer context, XtPointer info) { file_popup_info *fd = (file_popup_info *)context; pointer_or_int_t data; int choice; XtVaGetValues(w, XmNuserData, &data, NULL); choice = (int)data; if (choice >= FILE_FILTER_OFFSET) { XmToggleButtonSetState(fd->fp->just_sounds_button, false, false); if (choice == NO_FILE_FILTER_OFFSET) fd->fp->filter_choice = NO_FILE_FILTER; else fd->fp->filter_choice = choice - FILE_FILTER_OFFSET + 2; fd->fp->in_just_sounds_update = true; force_directory_reread(fd->fp->dialog); fd->fp->in_just_sounds_update = false; } else { fd->fp->sorter_choice = choice; sort_files_and_redisplay(fd->fp); } } static Widget make_file_list_item(file_popup_info *fd, int choice) { int n; Arg args[12]; const char *item_label; Widget w; n = 0; XtSetArg(args[n], XmNbackground, ss->lighter_blue); n++; switch (choice) { case 0: item_label = "a..z"; break; case 1: item_label = "z..a"; break; case 2: item_label = "new..old"; break; case 3: item_label = "old..new"; break; case 4: item_label = "small..big"; break; case 5: item_label = "big..small"; break; default: item_label = "unused"; break; } XtSetArg(args[n], XmNuserData, choice); /* userData is index into sorters list */ w = XtCreateManagedWidget(item_label, xmPushButtonWidgetClass, fd->file_list_popup, args, n + 1); XtAddCallback(w, XmNactivateCallback, file_list_item_activate_callback, (void *)fd); return(w); } static void file_list_popup_callback(Widget w, XtPointer context, XtPointer info) { file_popup_info *fd = (file_popup_info *)context; XmPopupHandlerCallbackStruct *cb = (XmPopupHandlerCallbackStruct *)info; XEvent *e; e = cb->event; if (e->type == ButtonPress) { int i; if (fd->file_list_items == NULL) { /* set up the default menu items */ fd->file_list_items = (Widget *)calloc(SORT_XEN, sizeof(Widget)); fd->file_list_items_size = SORT_XEN; for (i = 0; i < SORT_XEN; i++) fd->file_list_items[i] = make_file_list_item(fd, i); } /* clear any trailers just in case */ if (fd->file_list_items_size > SORT_XEN) for (i = SORT_XEN; i < fd->file_list_items_size; i++) XtUnmanageChild(fd->file_list_items[i]); /* check for added sort and filter functions (allocate more items if needed) */ { int extra_sorters = 0, extra_filters = 0, items_len; for (i = 0; i < ss->file_sorters_size; i++) if (!(Xen_is_false(Xen_vector_ref(ss->file_sorters, i)))) extra_sorters++; for (i = 0; i < ss->file_filters_size; i++) if (!(Xen_is_false(Xen_vector_ref(ss->file_filters, i)))) extra_filters++; items_len = SORT_XEN + extra_sorters + extra_filters; if (fd->fp->filter_choice != NO_FILE_FILTER) items_len++; if (items_len > fd->file_list_items_size) { fd->file_list_items = (Widget *)realloc(fd->file_list_items, items_len * sizeof(Widget)); for (i = fd->file_list_items_size; i < items_len; i++) fd->file_list_items[i] = make_file_list_item(fd, i); fd->file_list_items_size = items_len; } } /* make sure all the added sorter labels are correct, bg blue, and items active */ if (fd->file_list_items_size > SORT_XEN) { int k = SORT_XEN; /* sorters */ for (i = 0; i < ss->file_sorters_size; i++) { if (!(Xen_is_false(Xen_vector_ref(ss->file_sorters, i)))) { set_label(fd->file_list_items[k], Xen_string_to_C_string(Xen_car(Xen_vector_ref(ss->file_sorters, i)))); XtVaSetValues(fd->file_list_items[k], XmNbackground, ss->lighter_blue, XmNuserData, SORT_XEN + i, NULL); if (!(XtIsManaged(fd->file_list_items[k]))) XtManageChild(fd->file_list_items[k]); k++; } } for (i = 0; i < ss->file_filters_size; i++) { if (!(Xen_is_false(Xen_vector_ref(ss->file_filters, i)))) { set_label(fd->file_list_items[k], Xen_string_to_C_string(Xen_car(Xen_vector_ref(ss->file_filters, i)))); XtVaSetValues(fd->file_list_items[k], XmNbackground, ss->light_blue, XmNuserData, i + FILE_FILTER_OFFSET, NULL); if (!(XtIsManaged(fd->file_list_items[k]))) XtManageChild(fd->file_list_items[k]); k++; } } /* add "no filter" item if currently filtered */ if (fd->fp->filter_choice != NO_FILE_FILTER) { set_label(fd->file_list_items[k], NO_FILTER_LABEL); XtVaSetValues(fd->file_list_items[k], XmNbackground, ss->light_blue, XmNuserData, NO_FILE_FILTER_OFFSET, NULL); if (!(XtIsManaged(fd->file_list_items[k]))) XtManageChild(fd->file_list_items[k]); } } cb->menuToPost = fd->file_list_popup; } } static void add_file_popups(file_popup_info *fd) { int n; Arg args[20]; /* from lib/Xm.RCPopup.c: * When a user creates a new popup menu then we will install a particular * event handler on the menu's widget parent. Along with this we install * a grab on the button specified in XmNmenuPost or XmNwhichButton. [XmNmenuPost is a string = translation table syntax, is default] * [XmNwhichButton is obsolete] * The posting algorithm is as follows: * * 1. On receipt of a posting event, the handler will search the child * list for a candidate widget or gadget, and track the most specific * popup menu available (these can be found in the popup list). The * criteria for a match includes matching the XmNmenuPost information. * * 2. Matching criteria include: * * * The menu must have XmNpopupEnabled set to either * XmPOPUP_AUTOMATIC or XmPOPUP_AUTOMATIC_RECURSIVE. * * * The popup menu is chosen according to creation order. If there is * more than one, the first correct match is chosen. * * * If the popup menu is found in a parent of the target widget, and * the popup menu must also have XmNpopupEnabled set to * XmPOPUP_AUTOMATIC_RECURSIVE to match. [sigh -- no one actually reads comments...] * * 3. Once a selection is made, if the menu's parent widget has a * popupHandlerCallback, it is invoked. The callback allows the user to * determine if a more specific menu is necessary, such as would be the * case in a graphical manipulation environment, and includes all the * necessary information. * */ n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNpopupEnabled, XmPOPUP_AUTOMATIC); n++; /* file text */ XtAddCallback(FSB_BOX(fd->dialog, XmDIALOG_TEXT), XmNpopupHandlerCallback, file_text_popup_callback, (void *)fd); fd->file_text_popup = XmCreatePopupMenu(FSB_BOX(fd->dialog, XmDIALOG_TEXT), (char *)"file-text-popup", args, n); fd->file_text_names = make_filename_list(); fd->file_text_popup_label = XtCreateManagedWidget(FILE_TEXT_POPUP_LABEL, xmLabelWidgetClass, fd->file_text_popup, args, n); XtCreateManagedWidget("sep", xmSeparatorWidgetClass, fd->file_text_popup, args, n); /* filter text */ XtAddCallback(FSB_BOX(fd->dialog, XmDIALOG_FILTER_TEXT), XmNpopupHandlerCallback, file_filter_popup_callback, (void *)fd); fd->file_filter_popup = XmCreatePopupMenu(FSB_BOX(fd->dialog, XmDIALOG_FILTER_TEXT), (char *)"file-filter-popup", args, n); fd->file_filter_names = make_filename_list(); fd->file_filter_popup_label = XtCreateManagedWidget(FILE_FILTER_POPUP_LABEL, xmLabelWidgetClass, fd->file_filter_popup, args, n); XtCreateManagedWidget("sep", xmSeparatorWidgetClass, fd->file_filter_popup, args, n); { char *startup_filter; startup_filter = XmTextFieldGetString(FSB_BOX(fd->dialog, XmDIALOG_FILTER_TEXT)); if (startup_filter) { remember_filename(startup_filter, fd->file_filter_names); XtFree(startup_filter); } } XtAddCallback(FSB_BOX(fd->dialog, XmDIALOG_FILTER_TEXT), XmNactivateCallback, file_filter_text_activate_callback, (void *)fd); /* file directory */ XtAddCallback(FSB_BOX(fd->dialog, XmDIALOG_DIR_LIST), XmNpopupHandlerCallback, file_dir_popup_callback, (void *)fd); fd->file_dir_popup = XmCreatePopupMenu(FSB_BOX(fd->dialog, XmDIALOG_DIR_LIST), (char *)"file-dir-popup", args, n); fd->file_dir_popup_label = XtCreateManagedWidget(FILE_DIR_POPUP_LABEL, xmLabelWidgetClass, fd->file_dir_popup, args, n); XtCreateManagedWidget("sep", xmSeparatorWidgetClass, fd->file_dir_popup, args, n); /* file list */ XtAddCallback(FSB_BOX(fd->dialog, XmDIALOG_LIST), XmNpopupHandlerCallback, file_list_popup_callback, (void *)fd); fd->file_list_popup = XmCreatePopupMenu(FSB_BOX(fd->dialog, XmDIALOG_LIST), (char *)"file-list-popup", args, n); fd->file_list_popup_label = XtCreateManagedWidget(FILE_LIST_POPUP_LABEL, xmLabelWidgetClass, fd->file_list_popup, args, n); XtCreateManagedWidget("sep", xmSeparatorWidgetClass, fd->file_list_popup, args, n); } /* ---------------- just-sounds (file-filters) ---------------- */ static void file_change_directory_callback(Widget w, XtPointer context, XtPointer info) { /* click in directory list */ file_pattern_info *fp = (file_pattern_info *)context; char *leaving_dir; { /* save current directory list position */ position_t position = 0; XmString *strs; XtVaGetValues(w, XmNtopItemPosition, &position, XmNselectedItems, &strs, NULL); if (position > 1) /* 1 = .. */ { char *filename = NULL; filename = (char *)XmStringUnparse(strs[0], NULL, XmCHARSET_TEXT, XmCHARSET_TEXT, NULL, 0, XmOUTPUT_ALL); dirpos_update(fp->dir_list, filename, position); XtFree(filename); } } leaving_dir = mus_strdup(fp->last_dir); if ((leaving_dir) && (leaving_dir[strlen(leaving_dir) - 1] == '/')) leaving_dir[strlen(leaving_dir) - 1] = 0; fp->reread_directory = true; force_directory_reread_and_let_filename_change(fp->dialog); fp->reread_directory = false; if (leaving_dir) { position_t pos; pos = dirpos_list_top(fp->dir_list, leaving_dir); if (pos != POSITION_UNKNOWN) XmListSetPos(w, pos); free(leaving_dir); } } static void sort_files_and_redisplay(file_pattern_info *fp) { /* if just sorting, no need to read the directory */ dir_info *cur_dir; cur_dir = fp->current_files; if (cur_dir->len > 0) { XmString *names; int i, new_selected_position = -1; char *selected_filename = NULL; { XmString *strs; int selections = 0; XtVaGetValues(XmFileSelectionBoxGetChild(fp->dialog, XmDIALOG_LIST), XmNselectedItems, &strs, XmNselectedItemCount, &selections, NULL); if ((selections > 0) && (strs[0])) selected_filename = (char *)XmStringUnparse(strs[0], NULL, XmCHARSET_TEXT, XmCHARSET_TEXT, NULL, 0, XmOUTPUT_ALL); } snd_sort(fp->sorter_choice, cur_dir->files, cur_dir->len); /* here we could use colored text to mark sound files, perhaps different colors for * different chans (as in install-searcher-with-colors), but I would rather have * used different background colors (less intrusive I think). As far as I can tell, * this is impossible given the current XmList widget -- each item is an internal * "Element", not a label widget or whatever, and the selection color, for example, * is done by hand. */ names = (XmString *)calloc(cur_dir->len, sizeof(XmString)); for (i = 0; i < cur_dir->len; i++) { names[i] = XmStringCreateLocalized(cur_dir->files[i]->full_filename); if ((new_selected_position == -1) && (mus_strcmp(selected_filename, cur_dir->files[i]->full_filename))) new_selected_position = i; } XtVaSetValues(fp->dialog, XmNfileListItems, names, XmNfileListItemCount, cur_dir->len, XmNlistUpdated, true, NULL); if (new_selected_position >= 0) ensure_list_row_visible(XmFileSelectionBoxGetChild(fp->dialog, XmDIALOG_LIST), new_selected_position); for (i = 0; i < cur_dir->len; i++) if (names[i]) XmStringFree(names[i]); free(names); } else { /* nothing to sort, but make sure the files list is actually empty */ XtVaSetValues(fp->dialog, XmNfileListItems, NULL, XmNfileListItemCount, 0, XmNlistUpdated, true, NULL); } } static void snd_directory_reader(Widget dialog, XmFileSelectionBoxCallbackStruct *info) { /* replaces the FSB searchProc */ file_pattern_info *fp; dir_info *cur_dir = NULL; char *pattern = NULL, *our_dir = NULL; XtVaGetValues(dialog, XmNuserData, &fp, NULL); if (!(fp->dialog)) fp->dialog = dialog; /* can be null at initialization */ pattern = (char *)XmStringUnparse(info->pattern, NULL, XmCHARSET_TEXT, XmCHARSET_TEXT, NULL, 0, XmOUTPUT_ALL); our_dir = (char *)XmStringUnparse(info->dir, NULL, XmCHARSET_TEXT, XmCHARSET_TEXT, NULL, 0, XmOUTPUT_ALL); /* get current directory contents, given filter and pattern */ if (mus_strcmp(pattern, "*")) { if (fp->filter_choice == NO_FILE_FILTER) cur_dir = find_files_in_dir(our_dir); else cur_dir = find_filtered_files_in_dir(our_dir, fp->filter_choice); } else cur_dir = find_filtered_files_in_dir_with_pattern(our_dir, fp->filter_choice, pattern); if (fp->current_files) free_dir_info(fp->current_files); fp->current_files = cur_dir; if (pattern) XtFree(pattern); /* set file_pattern_info->selected_filename list_slider_position from history */ { position_t list_pos; Widget file_list; file_list = XmFileSelectionBoxGetChild(dialog, XmDIALOG_LIST); list_pos = dirpos_list_top(fp->dir_list, our_dir); /* post the sorted list in the dialog -- alphabetize by default */ sort_files_and_redisplay(fp); if (list_pos != POSITION_UNKNOWN) XmListSetPos(file_list, list_pos); } if ((fp->last_dir == NULL) || (!mus_strcmp(our_dir, fp->last_dir))) { if (fp->directory_watcher) unmonitor_file(fp->directory_watcher); fp->directory_watcher = NULL; if (fp->last_dir) free(fp->last_dir); fp->last_dir = mus_strdup(our_dir); fp->reread_directory = false; } if (our_dir) XtFree(our_dir); } static void just_sounds_callback(Widget w, XtPointer context, XtPointer info) { XmToggleButtonCallbackStruct *cb = (XmToggleButtonCallbackStruct *)info; file_pattern_info *fp = (file_pattern_info *)context; if (cb->set) fp->filter_choice = JUST_SOUNDS_FILTER; else fp->filter_choice = NO_FILE_FILTER; fp->in_just_sounds_update = true; force_directory_reread(fp->dialog); fp->in_just_sounds_update = false; } /* -------- play selected file handlers -------- */ typedef struct { Widget dialog, play_button; snd_info *player; } dialog_play_info; static void file_dialog_stop_playing(dialog_play_info *dp) { #if WITH_AUDIO if ((dp->player) && (dp->player->playing)) { stop_playing_sound(dp->player, PLAY_BUTTON_UNSET); dp->player = NULL; } #endif } void clear_deleted_snd_info(void *udp) { dialog_play_info *dp = (dialog_play_info *)udp; #if WITH_AUDIO dp->player = NULL; #endif } #if WITH_AUDIO static void play_selected_callback(Widget w, XtPointer context, XtPointer info) { XmToggleButtonCallbackStruct *cb = (XmToggleButtonCallbackStruct *)info; dialog_play_info *dp = (dialog_play_info *)context; if (cb->set) { Widget wtmp; char *filename = NULL; if ((dp->player) && (dp->player->playing)) stop_playing_sound(dp->player, PLAY_BUTTON_UNSET); wtmp = FSB_BOX(dp->dialog, XmDIALOG_TEXT); filename = XmTextGetString(wtmp); if (filename) { if (mus_file_probe(filename)) { dp->player = make_sound_readable(filename, false); dp->player->delete_me = (void *)dp; if (dp->player) play_sound(dp->player, 0, NO_END_SPECIFIED); } XtFree(filename); } } else file_dialog_stop_playing(dp); } #endif static void add_play_and_just_sounds_buttons(Widget dialog, Widget parent, file_pattern_info *fp, dialog_play_info *dp) { Widget rc; int n; Arg args[12]; n = 0; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; rc = XtCreateManagedWidget("filebuttons-rc", xmRowColumnWidgetClass, parent, args, n); n = 0; XtSetArg(args[n], XmNset, just_sounds(ss)); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; fp->just_sounds_button = XtCreateManagedWidget("sound files only", xmToggleButtonWidgetClass, rc, args, n); XtAddCallback(fp->just_sounds_button, XmNvalueChangedCallback, just_sounds_callback, (XtPointer)fp); #if WITH_AUDIO n = 0; XtSetArg(args[n], XmNorientation, XmVERTICAL); n++; XtSetArg(args[n], XmNwidth, 20); n++; XtSetArg(args[n], XmNseparatorType, XmNO_LINE); n++; XtCreateManagedWidget("sep1", xmSeparatorWidgetClass, rc, args, n); n = 0; /* XmNmarginLeft here refers to the space between the button and its label! */ XtSetArg(args[n], XmNalignment, XmALIGNMENT_END); n++; dp->play_button = XtCreateWidget("play selected sound", xmToggleButtonWidgetClass, rc, args, n); XtAddCallback(dp->play_button, XmNvalueChangedCallback, play_selected_callback, (XtPointer)dp); #endif } /* -------- File Open/View/Mix Dialogs -------- */ typedef struct file_dialog_info { read_only_t file_dialog_read_only; Widget dialog; Widget info_frame, info1, info2; /* labels giving info on selected file, or an error message */ file_pattern_info *fp; dialog_play_info *dp; void *unsound_directory_watcher; /* started if file doesn't exist, not a sound file, bogus header, etc (clears error msg if problem changed) */ void *info_filename_watcher; /* watch for change in selected file and repost info */ char *unsound_dirname, *unsound_filename; char *info_filename; file_popup_info *fpop; } file_dialog_info; static void open_file_help_callback(Widget w, XtPointer context, XtPointer info) { open_file_dialog_help(); } static void file_cancel_callback(Widget w, XtPointer context, XtPointer info) { file_dialog_stop_playing((dialog_play_info *)context); XtUnmanageChild (w); } static void file_wm_delete_callback(Widget w, XtPointer context, XtPointer info) { file_dialog_stop_playing((dialog_play_info *)context); } static void post_sound_info(Widget info1, Widget info2, const char *filename, bool with_filename) { /* filename is known[strongly believed] to be a sound file, etc */ XmString label; char *buf; buf = (char *)calloc(LABEL_BUFFER_SIZE, sizeof(char)); snprintf(buf, LABEL_BUFFER_SIZE, "%s%s%d chan%s, %d Hz, %.3f secs", (with_filename) ? filename_without_directory(filename) : "", (with_filename) ? ": " : "", mus_sound_chans(filename), (mus_sound_chans(filename) > 1) ? "s" : "", mus_sound_srate(filename), mus_sound_duration(filename)); label = XmStringCreateLocalized(buf); XtVaSetValues(info1, XmNlabelString, label, NULL); XmStringFree(label); snprintf(buf, LABEL_BUFFER_SIZE, "%s, %s%s", mus_header_type_name(mus_sound_header_type(filename)), short_sample_type_name(mus_sound_sample_type(filename), filename), snd_strftime(", %d-%b-%Y", mus_sound_write_date(filename))); label = XmStringCreateLocalized(buf); XtVaSetValues(info2, XmNlabelString, label, NULL); XmStringFree(label); free(buf); } static void post_file_info(file_dialog_info *fd, const char *filename) { #if WITH_AUDIO XtManageChild(fd->dp->play_button); #endif post_sound_info(fd->info1, fd->info2, filename, true); if (!(XtIsManaged(fd->info1))) XtManageChild(fd->info1); if (!(XtIsManaged(fd->info2))) XtManageChild(fd->info2); if (!(XtIsManaged(fd->info_frame))) XtManageChild(fd->info_frame); } static void unpost_file_info(file_dialog_info *fd) { #if WITH_AUDIO if (XtIsManaged(fd->dp->play_button)) XtUnmanageChild(fd->dp->play_button); #endif if (XtIsManaged(fd->info_frame)) XtUnmanageChild(fd->info_frame); if (fd->info_filename_watcher) { fd->info_filename_watcher = unmonitor_file(fd->info_filename_watcher); if (fd->info_filename) {free(fd->info_filename); fd->info_filename = NULL;} } } static bool is_empty_file(const char *filename) { #ifndef _MSC_VER struct stat statbuf; if (stat(filename, &statbuf) >= 0) return(statbuf.st_size == (mus_long_t)0); #endif return(false); } static int local_error = MUS_NO_ERROR; static char *local_error_msg = NULL; static mus_error_handler_t *old_error_handler; static void local_error2snd(int type, char *msg) { local_error = type; if (local_error_msg) free(local_error_msg); if (msg) local_error_msg = mus_strdup(msg); else local_error_msg = NULL; } static bool is_plausible_sound_file(const char *name) { int err = MUS_NO_ERROR; if (is_empty_file(name)) return(false); old_error_handler = mus_error_set_handler(local_error2snd); err = mus_header_read(name); mus_error_set_handler(old_error_handler); return((err == MUS_NO_ERROR) && (mus_header_type() != MUS_RAW)); } static void file_dialog_select_callback(Widget w, XtPointer context, XtPointer info) { file_dialog_info *fd = (file_dialog_info *)context; XmString *strs; char *filename = NULL; XtVaGetValues(w, XmNselectedItems, &strs, NULL); filename = (char *)XmStringUnparse(strs[0], NULL, XmCHARSET_TEXT, XmCHARSET_TEXT, NULL, 0, XmOUTPUT_ALL); if (filename) { if (is_plausible_sound_file(filename)) /* forces header read to avoid later unwanted error possibility */ post_file_info(fd, filename); XtFree(filename); } else unpost_file_info(fd); { /* save current list position */ position_t position = 0; XtVaGetValues(w, XmNtopItemPosition, &position, NULL); dirpos_update(fd->fp->dir_list, fd->fp->current_files->dir_name, position); } } static void unpost_if_filter_changed(Widget w, XtPointer context, XtPointer info) { unpost_file_info((file_dialog_info *)context); } static void watch_filename_change(Widget w, XtPointer context, XtPointer info) { /* try to move file list to show possible matches, * if a sound file, show info */ file_dialog_info *fd = (file_dialog_info *)context; char *filename = NULL; filename = XmTextGetString(w); if ((filename) && (*filename)) { XmStringTable files; Widget file_list; int num_files = 0, pos = -1, l, u; file_list = FSB_BOX(fd->dialog, XmDIALOG_LIST); XtVaGetValues(fd->dialog, XmNfileListItemCount, &num_files, XmNfileListItems, &files, /* do not free */ NULL); l = 0; /* hooray for Knuth... */ u = num_files - 1; while (true) { int i, comp; char *file_list_file = NULL; if (u < l) break; i = (l + u) / 2; file_list_file = (char *)XmStringUnparse(files[i], NULL, XmCHARSET_TEXT, XmCHARSET_TEXT, NULL, 0, XmOUTPUT_ALL); /* p453 */ comp = strcmp(file_list_file, filename); XtFree(file_list_file); pos = i + 1; if (comp == 0) break; if (comp < 0) /* files[i] less than filename */ l = i + 1; else u = i - 1; } if (pos > 0) ensure_list_row_visible(file_list, pos); if ((mus_file_probe(filename)) && (!is_directory(filename))) { if (is_sound_file(filename)) post_file_info(fd, filename); } } if (filename) XtFree(filename); } static void focus_filename_text_callback(Widget w, XtPointer context, XtPointer info) { XtAddCallback(w, XmNvalueChangedCallback, watch_filename_change, context); } static void unfocus_filename_text_callback(Widget w, XtPointer context, XtPointer info) { XtRemoveCallback(w, XmNvalueChangedCallback, watch_filename_change, context); } static bool file_is_directory(Widget dialog) { char *filename = NULL; bool is_dir = false; filename = XmTextGetString(FSB_BOX(dialog, XmDIALOG_TEXT)); if (filename) { is_dir = is_directory(filename); XtFree(filename); } return(is_dir); } static bool file_is_nonexistent_directory(Widget dialog) { char *filename = NULL; bool is_nonexistent_dir = false; filename = XmTextGetString(FSB_BOX(dialog, XmDIALOG_TEXT)); if (filename) { int len; len = strlen(filename); if ((!mus_file_probe(filename)) && (filename[len - 1] == '/')) { int i; /* check that there's some hope of making this directory */ for (i = len - 2; i > 0; i--) if (filename[i] == '/') { filename[i] = '\0'; is_nonexistent_dir = is_directory(filename); break; } } XtFree(filename); } return(is_nonexistent_dir); } static void reflect_text_in_open_button(Widget w, XtPointer context, XtPointer info) { file_dialog_info *fd = (file_dialog_info *)context; /* w here is the text widget, not the button */ XtSetSensitive(FSB_BOX(fd->dialog, XmDIALOG_OK_BUTTON), (!(file_is_directory(fd->dialog)))); } static void multifile_completer(widget_t w, void *data) { watch_filename_change(w, (XtPointer)data, NULL); } #define FILE_DIALOG_WIDTH 500 #define FILE_DIALOG_HEIGHT 500 static file_dialog_info *make_file_dialog(read_only_t read_only, char *title, char *select_title, XtCallbackProc file_ok_proc, XtCallbackProc file_help_proc) { /* file selection dialog box with added "Just Sound Files" and "Play selected" toggle buttons and info area, * popups, and so on. This applies to the Open, Mix, and Insert dialogs. The save-as * dialogs are handled by make_save_as_dialog below */ Widget w; file_dialog_info *fd; Arg args[32]; int n; XmString s1, s2, ok_label, filter_list_label, cancel_label; Widget wtmp = NULL, rc1, rc2; fd = (file_dialog_info *)calloc(1, sizeof(file_dialog_info)); fd->fp = (file_pattern_info *)calloc(1, sizeof(file_pattern_info)); fd->fp->in_just_sounds_update = false; if (just_sounds(ss)) fd->fp->filter_choice = JUST_SOUNDS_FILTER; else fd->fp->filter_choice = NO_FILE_FILTER; fd->dp = (dialog_play_info *)calloc(1, sizeof(dialog_play_info)); fd->file_dialog_read_only = read_only; fd->fpop = (file_popup_info *)calloc(1, sizeof(file_popup_info)); fd->fpop->fp = fd->fp; fd->fp->dir_list = make_dirpos_list(); w = MAIN_SHELL(ss); s1 = XmStringCreateLocalized(select_title); s2 = XmStringCreateLocalized(title); ok_label = XmStringCreateLocalized(title); filter_list_label = XmStringCreateLocalized((char *)"files listed:"); cancel_label = XmStringCreateLocalized((char *)I_GO_AWAY); n = 0; if (open_file_dialog_directory(ss)) { XmString dirstr; dirstr = XmStringCreateLocalized(open_file_dialog_directory(ss)); XtSetArg(args[n], XmNdirectory, dirstr); n++; } XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNokLabelString, ok_label); n++; XtSetArg(args[n], XmNselectionLabelString, s1); n++; /* "open", "mix", "insert", "open read-only:" */ XtSetArg(args[n], XmNdialogTitle, s2); n++; XtSetArg(args[n], XmNfilterLabelString, filter_list_label); n++; /* default label 'Filter' is confusing in this context */ XtSetArg(args[n], XmNfileFilterStyle, XmFILTER_HIDDEN_FILES); n++; /* the dot files mostly just get in the way */ XtSetArg(args[n], XmNcancelLabelString, cancel_label); n++; XtSetArg(args[n], XmNuserData, (XtPointer)(fd->fp)); n++; XtSetArg(args[n], XmNfileSearchProc, snd_directory_reader); n++; /* over-ride Motif's directory reader altogether */ XtSetArg(args[n], XmNwidth, FILE_DIALOG_WIDTH); n++; XtSetArg(args[n], XmNheight, FILE_DIALOG_HEIGHT); n++; XtSetArg(args[n], XmNresizePolicy, XmRESIZE_GROW); n++; XtSetArg(args[n], XmNnoResize, false); n++; fd->dialog = XmCreateFileSelectionDialog(w, title, args, n); fd->fp->dialog = fd->dialog; fd->dp->dialog = fd->dialog; fd->fpop->dialog = fd->dialog; XtUnmanageChild(FSB_BOX(fd->dialog, XmDIALOG_DIR_LIST_LABEL)); /* these are obvious */ XtUnmanageChild(FSB_BOX(fd->dialog, XmDIALOG_LIST_LABEL)); XtUnmanageChild(FSB_BOX(fd->dialog, XmDIALOG_APPLY_BUTTON)); /* "Filter" button is useless */ XtVaSetValues(FSB_BOX(fd->dialog, XmDIALOG_FILTER_LABEL), XmNbackground, ss->basic_color, NULL); XtVaSetValues(FSB_BOX(fd->dialog, XmDIALOG_SELECTION_LABEL), XmNbackground, ss->basic_color, NULL); XmStringFree(s1); XmStringFree(s2); XmStringFree(ok_label); XmStringFree(filter_list_label); XmStringFree(cancel_label); /* -------- play and just-sounds buttons and info area */ rc1 = XtVaCreateManagedWidget("filebuttons-rc1", xmRowColumnWidgetClass, fd->dialog, XmNorientation, XmVERTICAL, NULL); add_play_and_just_sounds_buttons(fd->dialog, rc1, fd->fp, fd->dp); fd->info_frame = XtVaCreateWidget("", xmFrameWidgetClass, rc1, NULL); rc2 = XtVaCreateManagedWidget("info-rc2", xmRowColumnWidgetClass, fd->info_frame, XmNorientation, XmVERTICAL, XmNbackground, ss->highlight_color, NULL); fd->info1 = XtVaCreateManagedWidget("", xmLabelWidgetClass, rc2, XmNbackground, ss->highlight_color, NULL); fd->info2 = XtVaCreateManagedWidget("", xmLabelWidgetClass, rc2, XmNbackground, ss->highlight_color, NULL); /* -------- Snd-like color schemes */ color_file_selection_box(fd->dialog); XtVaSetValues(fd->fp->just_sounds_button, XmNselectColor, ss->selection_color, NULL); #if WITH_AUDIO XtVaSetValues(fd->dp->play_button, XmNselectColor, ss->selection_color, NULL); #endif /* -------- completions */ wtmp = FSB_BOX(fd->dialog, XmDIALOG_TEXT); add_completer_to_builtin_textfield(wtmp, add_completer_func_with_multicompleter(sound_filename_completer, (void *)fd, multifile_completer)); XtAddCallback(wtmp, XmNfocusCallback, focus_filename_text_callback, (XtPointer)fd); XtAddCallback(wtmp, XmNlosingFocusCallback, unfocus_filename_text_callback, (XtPointer)fd); wtmp = FSB_BOX(fd->dialog, XmDIALOG_FILTER_TEXT); add_completer_to_builtin_textfield(wtmp, add_completer_func(filename_completer, NULL)); XtAddCallback(wtmp, XmNvalueChangedCallback, unpost_if_filter_changed, (XtPointer)fd); /* -------- base button callbacks */ XtAddCallback(fd->dialog, XmNokCallback, file_ok_proc, (XtPointer)fd); XtAddCallback(fd->dialog, XmNcancelCallback, file_cancel_callback, (XtPointer)(fd->dp)); XtAddCallback(fd->dialog, XmNhelpCallback, file_help_proc, NULL); XtAddCallback(FSB_BOX(fd->dialog, XmDIALOG_LIST), XmNbrowseSelectionCallback, file_dialog_select_callback, (XtPointer)fd); /* -------- single click in directory list */ XtAddCallback(FSB_BOX(fd->dialog, XmDIALOG_DIR_LIST), XmNbrowseSelectionCallback, file_change_directory_callback, (XtPointer)(fd->fp)); /* -------- the WM 'close' button */ { Atom wm_delete_window; wm_delete_window = XmInternAtom(MAIN_DISPLAY(ss), (char *)"WM_DELETE_WINDOW", false); XmAddWMProtocolCallback(XtParent(fd->dialog), wm_delete_window, file_wm_delete_callback, (XtPointer)(fd->dp)); } /* -------- special popups */ add_file_popups(fd->fpop); XtSetSensitive(FSB_BOX(fd->dialog, XmDIALOG_OK_BUTTON), (!(file_is_directory(fd->dialog)))); XtAddCallback(FSB_BOX(fd->dialog, XmDIALOG_TEXT), XmNvalueChangedCallback, reflect_text_in_open_button, (void *)fd); return(fd); } /* -------- File:Open/View dialogs -------- */ static void file_open_error(const char *error_msg, file_dialog_info *fd) { XmString msg; msg = XmStringCreateLocalized((char *)error_msg); XtVaSetValues(fd->info1, XmNlabelString, msg, NULL); XmStringFree(msg); if (XtIsManaged(fd->info2)) XtUnmanageChild(fd->info2); if (!(XtIsManaged(fd->info_frame))) XtManageChild(fd->info_frame); } static void redirect_file_open_error(const char *error_msg, void *ufd) { /* called from snd_error, redirecting error handling to the dialog */ file_open_error(error_msg, (file_dialog_info *)ufd); } static void open_modify_callback(Widget w, XtPointer context, XtPointer info); static void unpost_open_modify_error(file_dialog_info *fd) { Widget dialog_filename_text; if (XtIsManaged(fd->info_frame)) XtUnmanageChild(fd->info_frame); dialog_filename_text = FSB_BOX(fd->dialog, XmDIALOG_TEXT); if (dialog_filename_text) XtRemoveCallback(dialog_filename_text, XmNmodifyVerifyCallback, open_modify_callback, (XtPointer)fd); if (fd->unsound_directory_watcher) { fd->unsound_directory_watcher = unmonitor_file(fd->unsound_directory_watcher); if (fd->unsound_dirname) {free(fd->unsound_dirname); fd->unsound_dirname = NULL;} if (fd->unsound_filename) {free(fd->unsound_filename); fd->unsound_filename = NULL;} } } static void open_modify_callback(Widget w, XtPointer context, XtPointer info) { file_dialog_info *fd = (file_dialog_info *)context; XmTextVerifyCallbackStruct *cbs = (XmTextVerifyCallbackStruct *)info; if (!(fd->fp->in_just_sounds_update)) /* auto trigger from just_sounds button -- unwanted! */ unpost_open_modify_error(fd); cbs->doit = true; /* fixup filename elsewhere -- returning false here makes the thing beep! */ } static void clear_error_if_open_changes(Widget dialog, file_dialog_info *data) { Widget dialog_filename_text; dialog_filename_text = FSB_BOX(dialog, XmDIALOG_TEXT); if (dialog_filename_text) XtAddCallback(dialog_filename_text, XmNmodifyVerifyCallback, open_modify_callback, (XtPointer)data); } static void file_open_ok_callback(Widget w, XtPointer context, XtPointer info) { file_dialog_info *fd = (file_dialog_info *)context; XmFileSelectionBoxCallbackStruct *cbs = (XmFileSelectionBoxCallbackStruct *)info; char *filename = NULL; if (XmGetFocusWidget(fd->dialog) == FSB_BOX(fd->dialog, XmDIALOG_FILTER_TEXT)) return; filename = (char *)XmStringUnparse(cbs->value, NULL, XmCHARSET_TEXT, XmCHARSET_TEXT, NULL, 0, XmOUTPUT_ALL); if ((!filename) || (!(*filename))) { file_open_error("no filename given", fd); clear_error_if_open_changes(fd->dialog, fd); } else { file_dialog_stop_playing(fd->dp); if (!(is_directory(filename))) /* this can be a directory name if the user clicked 'ok' when he meant 'cancel' */ { snd_info *sp; redirect_snd_error_to(redirect_file_open_error, (void *)fd); ss->requestor_dialog = w; ss->open_requestor = FROM_OPEN_DIALOG; ss->open_requestor_data = NULL; sp = snd_open_file(filename, fd->file_dialog_read_only); redirect_snd_error_to(NULL, NULL); if (sp) { XtUnmanageChild(w); remember_filename(filename, fd->fpop->file_text_names); select_channel(sp, 0); } else { if (ss->open_requestor != FROM_RAW_DATA_DIALOG) { clear_error_if_open_changes(fd->dialog, fd); /* whatever the error was, I think it is correct here to unpost the error * if the underlying file is either changed or created. */ } } if (filename) XtFree(filename); } else { char *str; str = mus_format("%s is a directory", filename); file_open_error(str, fd); clear_error_if_open_changes(fd->dialog, fd); free(str); } } } static file_dialog_info *odat = NULL; widget_t make_open_file_dialog(read_only_t read_only, bool managed) { char *title, *select_title; if (read_only == FILE_READ_ONLY) { title = (char *)"View"; select_title = (char *)"open read-only:"; } else { title = (char *)"Open"; select_title = (char *)"open:"; } if (!odat) { XmString cancel_label; odat = make_file_dialog(read_only, title, select_title, file_open_ok_callback, open_file_help_callback); set_dialog_widget(FILE_OPEN_DIALOG, odat->dialog); /* now preload last n files opened before this point */ preload_filenames(odat->fpop->file_text_names); cancel_label = XmStringCreateLocalized((char *)I_GO_AWAY); XtVaSetValues(odat->dialog, XmNcancelLabelString, cancel_label, NULL); XmStringFree(cancel_label); } else { if (odat->file_dialog_read_only != read_only) { XmString s1, s2; s1 = XmStringCreateLocalized(select_title); s2 = XmStringCreateLocalized(title); XtVaSetValues(odat->dialog, XmNselectionLabelString, s1, XmNdialogTitle, s2, XmNokLabelString, s2, /* "ok" button label can be either "View" or "Open" */ NULL); XmStringFree(s1); XmStringFree(s2); } odat->file_dialog_read_only = read_only; if (odat->fp->reread_directory) { force_directory_reread(odat->dialog); odat->fp->reread_directory = false; } } if ((managed) && (!(XtIsManaged(odat->dialog)))) XtManageChild(odat->dialog); return(odat->dialog); } /* -------- File:Mix dialog -------- */ static void file_mix_ok_callback(Widget w, XtPointer context, XtPointer info) { XmFileSelectionBoxCallbackStruct *cbs = (XmFileSelectionBoxCallbackStruct *)info; file_dialog_info *fd = (file_dialog_info *)context; char *filename = NULL; filename = (char *)XmStringUnparse(cbs->value, NULL, XmCHARSET_TEXT, XmCHARSET_TEXT, NULL, 0, XmOUTPUT_ALL); if ((!filename) || (!(*filename))) { file_open_error("no filename given", fd); clear_error_if_open_changes(fd->dialog, fd); } else { file_dialog_stop_playing(fd->dp); if (!(is_directory(filename))) /* this can be a directory name if the user clicked 'ok' when he meant 'cancel' */ { int id_or_error; snd_info *sp; sp = any_selected_sound(); redirect_snd_error_to(redirect_file_open_error, (void *)fd); ss->requestor_dialog = w; ss->open_requestor = FROM_MIX_DIALOG; ss->open_requestor_data = NULL; id_or_error = mix_complete_file_at_cursor(sp, filename); /* "id_or_error" here is either one of the mix id's or an error indication such as MIX_FILE_NO_MIX */ /* the possible error conditions have been checked already, or go through snd_error */ redirect_snd_error_to(NULL, NULL); if (id_or_error < 0) /* actually -1 .. -3 */ { if (ss->open_requestor != FROM_RAW_DATA_DIALOG) { clear_error_if_open_changes(fd->dialog, fd); } } else { status_report(sp, "%s mixed in at cursor", filename); remember_filename(filename, fd->fpop->file_text_names); } if (filename) XtFree(filename); } else { char *str; str = mus_format("%s is a directory", filename); file_open_error(str, fd); clear_error_if_open_changes(fd->dialog, fd); free(str); } } } static void mix_file_help_callback(Widget w, XtPointer context, XtPointer info) { mix_file_dialog_help(); } static file_dialog_info *mdat = NULL; static Xen mix_open_file_watcher(Xen hook_or_reason) { if ((mdat->dialog) && (XtIsManaged(mdat->dialog))) set_sensitive(FSB_BOX(mdat->dialog, XmDIALOG_OK_BUTTON), (bool)any_selected_sound()); return(Xen_false); } Xen_wrap_1_arg(mix_open_file_watcher_w, mix_open_file_watcher) widget_t make_mix_file_dialog(bool managed) { /* called from the menu */ if (!mdat) { mdat = make_file_dialog(FILE_READ_ONLY, (char *)"Mix Sound", (char *)"mix in:", file_mix_ok_callback, mix_file_help_callback); set_dialog_widget(FILE_MIX_DIALOG, mdat->dialog); Xen_add_to_hook_list(ss->snd_open_file_hook, mix_open_file_watcher_w, "mix-dialog-open-file-watcher", "mix dialog's open-file-hook handler"); } else { if (mdat->fp->reread_directory) { force_directory_reread(mdat->dialog); mdat->fp->reread_directory = false; } } if ((managed) && (!XtIsManaged(mdat->dialog))) XtManageChild(mdat->dialog); return(mdat->dialog); } /* -------- File:Insert dialog -------- */ static void file_insert_ok_callback(Widget w, XtPointer context, XtPointer info) { XmFileSelectionBoxCallbackStruct *cbs = (XmFileSelectionBoxCallbackStruct *)info; file_dialog_info *fd = (file_dialog_info *)context; char *filename = NULL; filename = (char *)XmStringUnparse(cbs->value, NULL, XmCHARSET_TEXT, XmCHARSET_TEXT, NULL, 0, XmOUTPUT_ALL); if ((!filename) || (!(*filename))) { file_open_error("no filename given", fd); clear_error_if_open_changes(fd->dialog, fd); } else { file_dialog_stop_playing(fd->dp); if (!(is_directory(filename))) /* this can be a directory name if the user clicked 'ok' when he meant 'cancel' */ { bool ok; snd_info *sp; sp = any_selected_sound(); ss->requestor_dialog = w; ss->open_requestor = FROM_INSERT_DIALOG; ss->open_requestor_data = NULL; redirect_snd_error_to(redirect_file_open_error, (void *)fd); ok = insert_complete_file_at_cursor(sp, filename); redirect_snd_error_to(NULL, NULL); if (!ok) { if (ss->open_requestor != FROM_RAW_DATA_DIALOG) { clear_error_if_open_changes(fd->dialog, fd); /* ideally insert_complete_file would return an indication of what the error was... */ } } else { status_report(sp, "%s inserted at cursor", filename); remember_filename(filename, fd->fpop->file_text_names); } if (filename) XtFree(filename); } else { char *str; str = mus_format("%s is a directory", filename); file_open_error(str, fd); clear_error_if_open_changes(fd->dialog, fd); free(str); } } } static void insert_file_help_callback(Widget w, XtPointer context, XtPointer info) { insert_file_dialog_help(); } static file_dialog_info *idat = NULL; static Xen insert_open_file_watcher(Xen hook_or_reason) { if ((idat->dialog) && (XtIsManaged(idat->dialog))) set_sensitive(FSB_BOX(idat->dialog, XmDIALOG_OK_BUTTON), (bool)any_selected_sound()); return(Xen_false); } Xen_wrap_1_optional_arg(insert_open_file_watcher_w, insert_open_file_watcher) widget_t make_insert_file_dialog(bool managed) { if (!idat) { idat = make_file_dialog(FILE_READ_ONLY, (char *)"Insert Sound", (char *)"insert:", file_insert_ok_callback, insert_file_help_callback); set_dialog_widget(FILE_INSERT_DIALOG, idat->dialog); Xen_add_to_hook_list(ss->snd_open_file_hook, insert_open_file_watcher_w, "insert-dialog-open-file-watcher", "insert dialog's open-file-hook handler"); } else { if (idat->fp->reread_directory) { force_directory_reread(idat->dialog); idat->fp->reread_directory = false; } } if ((managed) && (!XtIsManaged(idat->dialog))) XtManageChild(idat->dialog); return(idat->dialog); } /* -------- reflect outside changes -------- */ void set_open_file_play_button(bool val) { #if WITH_AUDIO if ((odat) && (odat->dp->play_button)) XmToggleButtonSetState(odat->dp->play_button, (Boolean)val, false); if ((mdat) && (mdat->dp->play_button)) XmToggleButtonSetState(mdat->dp->play_button, (Boolean)val, false); if ((idat) && (idat->dp->play_button)) XmToggleButtonSetState(idat->dp->play_button, (Boolean)val, false); #endif } void alert_new_file(void) { if (ss->file_monitor_ok) return; /* ideally this would include the save-as dialogs */ if (odat) { odat->fp->reread_directory = true; if (XtIsManaged(odat->dialog)) { force_directory_reread(odat->dialog); odat->fp->reread_directory = false; } } if (mdat) { mdat->fp->reread_directory = true; if (XtIsManaged(mdat->dialog)) { force_directory_reread(mdat->dialog); mdat->fp->reread_directory = false; } } if (idat) { idat->fp->reread_directory = true; if (XtIsManaged(idat->dialog)) { force_directory_reread(idat->dialog); idat->fp->reread_directory = false; } } } void reflect_just_sounds(void) { if ((odat) && (odat->fp->just_sounds_button)) XmToggleButtonSetState(odat->fp->just_sounds_button, just_sounds(ss), true); if ((mdat) && (mdat->fp->just_sounds_button)) XmToggleButtonSetState(mdat->fp->just_sounds_button, just_sounds(ss), true); if ((idat) && (idat->fp->just_sounds_button)) XmToggleButtonSetState(idat->fp->just_sounds_button, just_sounds(ss), true); } /* ---------------- file data panel ---------------- */ #define NUM_VISIBLE_HEADERS 5 char *get_file_dialog_sound_attributes(file_data *fdat, int *srate, int *chans, mus_header_t *header_type, mus_sample_t *sample_type, mus_long_t *location, mus_long_t *samples, int min_chan) { char *str; int n; int res; int *ns = NULL; fdat->error_widget = NOT_A_SCANF_WIDGET; fdat->scanf_widget = NOT_A_SCANF_WIDGET; if ((srate) && (fdat->srate_text)) { str = XmTextGetString(fdat->srate_text); fdat->scanf_widget = SRATE_WIDGET; if ((str) && (*str)) { (*srate) = string_to_int(str, 1, "srate"); XtFree(str); } else snd_error_without_format("no srate?"); } if ((chans) && (fdat->chans_text)) { str = XmTextGetString(fdat->chans_text); fdat->scanf_widget = CHANS_WIDGET; if ((str) && (*str)) { (*chans) = string_to_int(str, min_chan, "chans"); XtFree(str); } else { if (min_chan > 0) snd_error_without_format("no chans?"); } } if ((location) && (fdat->location_text)) { str = XmTextGetString(fdat->location_text); fdat->scanf_widget = DATA_LOCATION_WIDGET; if ((str) && (*str)) { (*location) = string_to_mus_long_t(str, 0, "data location"); XtFree(str); } else snd_error_without_format("no data location?"); } if ((samples) && (fdat->samples_text)) { str = XmTextGetString(fdat->samples_text); fdat->scanf_widget = SAMPLES_WIDGET; if ((str) && (*str)) { (*samples) = string_to_mus_long_t(str, 0, "samples"); XtFree(str); } else snd_error_without_format("no samples?"); } fdat->scanf_widget = SAMPLES_WIDGET; if ((header_type) && (fdat->header_type_list)) { res = XmListGetSelectedPos(fdat->header_type_list, &ns, &n); if (res) { (*header_type) = position_to_header_type(ns[0] - 1); fdat->current_header_type = (*header_type); free(ns); ns = NULL; } } if ((sample_type) && (fdat->sample_type_list)) { res = XmListGetSelectedPos(fdat->sample_type_list, &ns, &n); if (res) { (*sample_type) = position_to_sample_type(fdat->current_header_type, ns[0] - 1); fdat->current_sample_type = (*sample_type); free(ns); ns = NULL; } } if (fdat->comment_text) { char *comment = NULL; comment = XmTextGetString(fdat->comment_text); if (comment) { str = mus_strdup(comment); XtFree(comment); return(str); } } return(NULL); } #define IGNORE_DATA_LOCATION -1 #define IGNORE_SAMPLES MUS_UNKNOWN_SAMPLE #define IGNORE_CHANS -1 #define IGNORE_SRATE -1 #define IGNORE_HEADER_TYPE MUS_UNKNOWN_HEADER static void set_file_dialog_sound_attributes(file_data *fdat, mus_header_t header_type, mus_sample_t sample_type, int srate, int chans, mus_long_t location, mus_long_t samples, char *comment) { int i; const char **fl = NULL; XmString *strs; if (header_type != IGNORE_HEADER_TYPE) fdat->current_header_type = header_type; else fdat->current_header_type = MUS_RAW; fdat->current_sample_type = sample_type; fl = header_type_and_sample_type_to_position(fdat, fdat->current_header_type, fdat->current_sample_type); if (fl == NULL) return; if ((header_type != IGNORE_HEADER_TYPE) && (fdat->header_type_list)) { XmListSelectPos(fdat->header_type_list, fdat->header_type_pos + 1, false); ensure_list_row_visible(fdat->header_type_list, fdat->header_type_pos + 1); } strs = (XmString *)malloc(fdat->sample_types * sizeof(XmString)); for (i = 0; i < fdat->sample_types; i++) strs[i] = XmStringCreateLocalized((char *)fl[i]); XtVaSetValues(fdat->sample_type_list, XmNitems, strs, XmNitemCount, fdat->sample_types, NULL); for (i = 0; i < fdat->sample_types; i++) XmStringFree(strs[i]); free(strs); XmListSelectPos(fdat->sample_type_list, fdat->sample_type_pos + 1, false); ensure_list_row_visible(fdat->sample_type_list, fdat->sample_type_pos + 1); if ((srate != IGNORE_SRATE) && (fdat->srate_text)) widget_int_to_text(fdat->srate_text, srate); if ((chans != IGNORE_CHANS) && (fdat->chans_text)) widget_int_to_text(fdat->chans_text, chans); if (fdat->comment_text) XmTextSetString(fdat->comment_text, comment); if ((location != IGNORE_DATA_LOCATION) && (fdat->location_text)) widget_mus_long_t_to_text(fdat->location_text, location); if ((samples != IGNORE_SAMPLES) && (fdat->samples_text)) widget_mus_long_t_to_text(fdat->samples_text, samples); } /* -------- error handling -------- */ /* if an error occurs, a callback is added to the offending text widget, and an error is * posted in the error_text label. When the user modifies the bad entry, the callback * erases the error message, and removes itself from the text widget. */ static void clear_dialog_error(file_data *fd) { if (XtIsManaged(fd->error_text)) { XtUnmanageChild(fd->error_text); if (fd->comment_text) { XtVaSetValues(fd->comment_text, XmNbottomAttachment, XmATTACH_FORM, NULL); } } } static void show_dialog_error(file_data *fd) { if (!(XtIsManaged(fd->error_text))) { if (fd->comment_text) { XtVaSetValues(fd->comment_text, XmNbottomAttachment, XmATTACH_WIDGET, XmNbottomWidget, fd->error_text, NULL); } XtManageChild(fd->error_text); } } static void post_file_dialog_error(const char *error_msg, file_data *fd) { XmString msg; msg = XmStringCreateLocalized((char *)error_msg); XtVaSetValues(fd->error_text, XmNbackground, ss->yellow, XmNlabelString, msg, NULL); XmStringFree(msg); show_dialog_error(fd); } static void redirect_post_file_dialog_error(const char *error_msg, void *ufd) { post_file_dialog_error(error_msg, (file_data *)ufd); } static void filename_modify_callback(Widget w, XtPointer context, XtPointer info) { file_data *fd = (file_data *)context; XmTextVerifyCallbackStruct *cbs = (XmTextVerifyCallbackStruct *)info; Widget dialog_filename_text; clear_dialog_error(fd); dialog_filename_text = FSB_BOX(fd->dialog, XmDIALOG_TEXT); if (dialog_filename_text) XtRemoveCallback(dialog_filename_text, XmNmodifyVerifyCallback, filename_modify_callback, context); cbs->doit = true; } static void clear_error_if_filename_changes(Widget dialog, file_data *data) { Widget dialog_filename_text; dialog_filename_text = FSB_BOX(dialog, XmDIALOG_TEXT); if (dialog_filename_text) XtAddCallback(dialog_filename_text, XmNmodifyVerifyCallback, filename_modify_callback, (XtPointer)data); } static void chans_modify_callback(Widget w, XtPointer context, XtPointer info) { file_data *fd = (file_data *)context; XmTextVerifyCallbackStruct *cbs = (XmTextVerifyCallbackStruct *)info; clear_dialog_error(fd); XtRemoveCallback(fd->chans_text, XmNmodifyVerifyCallback, chans_modify_callback, context); cbs->doit = true; } static void clear_error_if_chans_changes(Widget dialog, file_data *fd) { if (fd->chans_text) XtAddCallback(fd->chans_text, XmNmodifyVerifyCallback, chans_modify_callback, (XtPointer)fd); } static void panel_modify_callback(Widget w, XtPointer context, XtPointer info) { file_data *fd = (file_data *)context; XmTextVerifyCallbackStruct *cbs = (XmTextVerifyCallbackStruct *)info; clear_dialog_error(fd); XtRemoveCallback(w, XmNmodifyVerifyCallback, panel_modify_callback, context); cbs->doit = true; } static void clear_error_if_panel_changes(Widget dialog, file_data *fd) { Widget baddy; switch (fd->error_widget) { case SRATE_WIDGET: baddy = fd->srate_text; break; case DATA_LOCATION_WIDGET: baddy = fd->location_text; break; case SAMPLES_WIDGET: baddy = fd->samples_text; break; default: baddy = fd->chans_text; break; } if (baddy) XtAddCallback(baddy, XmNmodifyVerifyCallback, panel_modify_callback, (XtPointer)fd); } static void post_file_panel_error(const char *error_msg, void *ufd) { file_data *fd = (file_data *)ufd; fd->error_widget = fd->scanf_widget; post_file_dialog_error(error_msg, fd); } static void file_data_type_callback(Widget w, XtPointer context, XtPointer info) { int pos; XmListCallbackStruct *cbs = (XmListCallbackStruct *)info; file_data *fd; XtVaGetValues(w, XmNuserData, &fd, NULL); pos = cbs->item_position - 1; if (position_to_header_type(pos) != fd->current_header_type) { position_to_header_type_and_sample_type(fd, pos); set_file_dialog_sound_attributes(fd, fd->current_header_type, fd->current_sample_type, IGNORE_SRATE, IGNORE_CHANS, IGNORE_DATA_LOCATION, IGNORE_SAMPLES, NULL); } } static void file_sample_type_callback(Widget w, XtPointer context, XtPointer info) { XmListCallbackStruct *cbs = (XmListCallbackStruct *)info; file_data *fd; XtVaGetValues(w, XmNuserData, &fd, NULL); fd->current_sample_type = position_to_sample_type(fd->current_header_type, cbs->item_position - 1); } static void file_data_src_callback(Widget w, XtPointer context, XtPointer info) { file_data *fd = (file_data *)context; XmToggleButtonCallbackStruct *cb = (XmToggleButtonCallbackStruct *)info; fd->src = cb->set; } static void file_data_auto_comment_callback(Widget w, XtPointer context, XtPointer info) { file_data *fd = (file_data *)context; XmToggleButtonCallbackStruct *cb = (XmToggleButtonCallbackStruct *)info; fd->auto_comment = cb->set; } /* ---------------- File Data Panel ---------------- */ #define PANEL_COMMENT_SPACE 16 #define WITHOUT_AUTO_COMMENT false #define WITH_SRATE true #define WITHOUT_SRATE false static file_data *make_file_data_panel(Widget parent, const char *name, Arg *in_args, int in_n, dialog_channels_t with_chan, mus_header_t header_type, mus_sample_t sample_type, dialog_data_location_t with_loc, dialog_samples_t with_samples, dialog_header_type_t with_header_type, dialog_comment_t with_comment, header_choice_t header_choice, bool with_src, bool with_auto_comment) { Widget form, header_label, data_label, srate_label, chans_label, sep1, sep2 = NULL, sep3, sep4; Widget comment_label = NULL, location_label, samples_label; file_data *fdat; Arg args[32]; int i, n; XmString *strs; int nsample_types = 0, nheaders = 0; const char **sample_types = NULL, **header_types = NULL; switch (header_choice) { case WITH_READABLE_HEADERS: header_types = short_readable_headers(&nheaders); break; case WITH_WRITABLE_HEADERS: header_types = short_writable_headers(&nheaders); break; case WITH_BUILTIN_HEADERS: header_types = short_builtin_headers(&nheaders); break; } fdat = (file_data *)calloc(1, sizeof(file_data)); fdat->src = save_as_dialog_src(ss); fdat->auto_comment = save_as_dialog_auto_comment(ss); fdat->saved_comment = NULL; fdat->current_header_type = header_type; fdat->current_sample_type = sample_type; sample_types = header_type_and_sample_type_to_position(fdat, header_type, sample_type); nsample_types = fdat->sample_types; /* pick up all args from caller -- args here are attachment points */ form = XtCreateManagedWidget(name, xmFormWidgetClass, parent, in_args, in_n); if (with_header_type == WITH_HEADER_TYPE_FIELD) { n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNorientation, XmVERTICAL); n++; XtSetArg(args[n], XmNwidth, 5); n++; XtSetArg(args[n], XmNseparatorType, XmNO_LINE); n++; sep1 = XtCreateManagedWidget("sep1", xmSeparatorWidgetClass, form, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, sep1); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; header_label = XtCreateManagedWidget("header", xmLabelWidgetClass, form, args, n); /* what is selected depends on current type */ strs = (XmString *)calloc(nheaders, sizeof(XmString)); for (i = 0; i < nheaders; i++) strs[i] = XmStringCreateLocalized((char *)header_types[i]); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, header_label); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, sep1); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNlistMarginWidth, 1); n++; XtSetArg(args[n], XmNuserData, (XtPointer)fdat); n++; XtSetArg(args[n], XmNitems, strs); n++; XtSetArg(args[n], XmNitemCount, nheaders); n++; XtSetArg(args[n], XmNvisibleItemCount, NUM_VISIBLE_HEADERS); n++; fdat->header_type_list = XmCreateScrolledList(form, (char *)"header-type", args, n); XtManageChild(fdat->header_type_list); for (i = 0; i < nheaders; i++) XmStringFree(strs[i]); free(strs); XmListSelectPos(fdat->header_type_list, fdat->header_type_pos + 1, false); XtAddCallback(fdat->header_type_list, XmNbrowseSelectionCallback, file_data_type_callback, NULL); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, fdat->header_type_list); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNorientation, XmVERTICAL); n++; XtSetArg(args[n], XmNwidth, 15); n++; XtSetArg(args[n], XmNseparatorType, XmNO_LINE); n++; sep2 = XtCreateManagedWidget("sep2", xmSeparatorWidgetClass, form, args, n); } n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; if (with_header_type == WITH_HEADER_TYPE_FIELD) { XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, sep2); n++; } else { XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; } XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; data_label = XtCreateManagedWidget("data", xmLabelWidgetClass, form, args, n); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, data_label); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; if (with_header_type == WITH_HEADER_TYPE_FIELD) { XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, sep2); n++; } else { XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; } XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNuserData, (XtPointer)fdat); n++; fdat->sample_type_list = XmCreateScrolledList(form, (char *)"sample-type", args, n); strs = (XmString *)calloc(nsample_types, sizeof(XmString)); for (i = 0; i < nsample_types; i++) strs[i] = XmStringCreateLocalized((char *)sample_types[i]); XtVaSetValues(fdat->sample_type_list, XmNitems, strs, XmNitemCount, nsample_types, NULL); for (i = 0; i < nsample_types; i++) XmStringFree(strs[i]); free(strs); XmListSelectPos(fdat->sample_type_list, fdat->sample_type_pos + 1, false); XtManageChild(fdat->sample_type_list); XtAddCallback(fdat->sample_type_list, XmNbrowseSelectionCallback, file_sample_type_callback, NULL); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, fdat->sample_type_list); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNorientation, XmVERTICAL); n++; XtSetArg(args[n], XmNwidth, 15); n++; XtSetArg(args[n], XmNseparatorType, XmNO_LINE); n++; sep3 = XtCreateManagedWidget("sep3", xmSeparatorWidgetClass, form, args, n); /* srate */ n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, sep3); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; srate_label = XtCreateManagedWidget("srate", xmLabelWidgetClass, form, args, n); n = 0; XtSetArg(args[n], XmNcolumns, 8); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, srate_label); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, sep3); n++; if (with_src) { XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; } else { XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; } XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; fdat->srate_text = make_textfield_widget("srate-text", form, args, n, NOT_ACTIVATABLE, add_completer_func(srate_completer, NULL)); if (with_src) { n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, srate_label); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, fdat->srate_text); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNselectColor, ss->selection_color); n++; /* this is probably clobbered by color_file_selection_box */ fdat->src_button = make_togglebutton_widget("src", form, args, n); XtAddCallback(fdat->src_button, XmNvalueChangedCallback, file_data_src_callback, (XtPointer)fdat); XmToggleButtonSetState(fdat->src_button, fdat->src, false); } if (with_chan != WITHOUT_CHANNELS_FIELD) { /* chans */ n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, fdat->srate_text); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, sep3); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; chans_label = XtCreateManagedWidget((char *)((with_chan == WITH_CHANNELS_FIELD) ? "channels" : "extract channel"), xmLabelWidgetClass, form, args, n); n = 0; XtSetArg(args[n], XmNcolumns, 6); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, chans_label); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, sep3); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; fdat->chans_text = make_textfield_widget("chans-text", form, args, n, NOT_ACTIVATABLE, NO_COMPLETER); XmTextFieldSetString(fdat->chans_text, (char *)"0"); if (with_loc == WITH_DATA_LOCATION_FIELD) { n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, fdat->chans_text); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, sep3); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; location_label = XtCreateManagedWidget("data location", xmLabelWidgetClass, form, args, n); n = 0; XtSetArg(args[n], XmNcolumns, 6); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, location_label); n++; XtSetArg(args[n], XmNbottomAttachment, (with_samples == WITHOUT_SAMPLES_FIELD) ? XmATTACH_FORM : XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, sep3); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; fdat->location_text = make_textfield_widget("location-text", form, args, n, NOT_ACTIVATABLE, NO_COMPLETER); } } if (with_samples == WITH_SAMPLES_FIELD) { n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, ((fdat->location_text) ? fdat->location_text : ((fdat->chans_text) ? fdat->chans_text : fdat->srate_text))); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, sep3); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; samples_label = XtCreateManagedWidget("samples", xmLabelWidgetClass, form, args, n); n = 0; XtSetArg(args[n], XmNcolumns, 8); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, samples_label); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, sep3); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; fdat->samples_text = make_textfield_widget("samples-text", form, args, n, NOT_ACTIVATABLE, NO_COMPLETER); } n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, form); n++; /* form is the internal XmForm widget holding the lists etc */ XtSetArg(args[n], XmNbottomAttachment, (with_comment != WITHOUT_COMMENT_FIELD) ? XmATTACH_NONE : XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNheight, (with_comment != WITHOUT_COMMENT_FIELD) ? PANEL_COMMENT_SPACE : 2); n++; XtSetArg(args[n], XmNseparatorType, XmNO_LINE); n++; sep4 = XtCreateManagedWidget("sep4", xmSeparatorWidgetClass, parent, args, n); /* try to make the comment field the one that grows */ n = 0; if (with_comment == WITHOUT_COMMENT_FIELD) { XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, sep4); n++; } else { XtSetArg(args[n], XmNtopAttachment, XmATTACH_NONE); n++; } XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; /* overridden later -> yellow */ XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNborderColor, ss->black); n++; XtSetArg(args[n], XmNborderWidth, 2); n++; XtSetArg(args[n], XmNmarginWidth, 10); n++; XtSetArg(args[n], XmNmarginHeight, 10); n++; fdat->error_text = XtCreateWidget("", xmLabelWidgetClass, parent, args, n); /* XtUnmanageChild(fdat->error_text); */ if (with_comment != WITHOUT_COMMENT_FIELD) { n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, sep4); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; comment_label = XtCreateManagedWidget("comment", xmLabelWidgetClass, parent, args, n); if (with_auto_comment) { n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, sep4); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNselectColor, ss->selection_color); n++; fdat->auto_comment_button = make_togglebutton_widget("auto", parent, args, n); XtAddCallback(fdat->auto_comment_button, XmNvalueChangedCallback, file_data_auto_comment_callback, (XtPointer)fdat); XmToggleButtonSetState(fdat->auto_comment_button, fdat->auto_comment, false); } n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; if (with_auto_comment) { XtSetArg(args[n], XmNtopWidget, fdat->auto_comment_button); n++; } else { XtSetArg(args[n], XmNtopWidget, comment_label); n++; } XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrows, 4); n++; /* XtSetArg(args[n], XmNcolumns, 16); n++; */ /* this sets the lower size, so we don't want it too big */ fdat->comment_text = make_text_widget("comment-text", parent, args, n); } else fdat->comment_text = NULL; return(fdat); } static void reflect_file_data_panel_change(file_data *fd, void *data, void (*change_action)(Widget w, XtPointer context, XtPointer info)) { if (fd->srate_text) XtAddCallback(fd->srate_text, XmNvalueChangedCallback, change_action, (XtPointer)data); if (fd->chans_text) XtAddCallback(fd->chans_text, XmNvalueChangedCallback, change_action, (XtPointer)data); if (fd->samples_text) XtAddCallback(fd->samples_text, XmNvalueChangedCallback, change_action, (XtPointer)data); if (fd->location_text) XtAddCallback(fd->location_text, XmNvalueChangedCallback, change_action, (XtPointer)data); if (fd->comment_text) XtAddCallback(fd->comment_text, XmNvalueChangedCallback, change_action, (XtPointer)data); if (fd->sample_type_list) XtAddCallback(fd->sample_type_list, XmNbrowseSelectionCallback, change_action, (XtPointer)data); if (fd->header_type_list) XtAddCallback(fd->header_type_list, XmNbrowseSelectionCallback, change_action, (XtPointer)data); } static void unreflect_file_data_panel_change(file_data *fd, void *data, void (*change_action)(Widget w, XtPointer context, XtPointer info)) { if (fd->srate_text) XtRemoveCallback(fd->srate_text, XmNvalueChangedCallback, change_action, (XtPointer)data); if (fd->chans_text) XtRemoveCallback(fd->chans_text, XmNvalueChangedCallback, change_action, (XtPointer)data); if (fd->samples_text) XtRemoveCallback(fd->samples_text, XmNvalueChangedCallback, change_action, (XtPointer)data); if (fd->location_text) XtRemoveCallback(fd->location_text, XmNvalueChangedCallback, change_action, (XtPointer)data); if (fd->comment_text) XtRemoveCallback(fd->comment_text, XmNvalueChangedCallback, change_action, (XtPointer)data); if (fd->sample_type_list) XtRemoveCallback(fd->sample_type_list, XmNbrowseSelectionCallback, change_action, (XtPointer)data); if (fd->header_type_list) XtRemoveCallback(fd->header_type_list, XmNbrowseSelectionCallback, change_action, (XtPointer)data); } /* -------- save as dialog (file and edit menus) -------- */ typedef struct { file_data *panel_data; Widget dialog, filename_widget, extractB, mkdirB; char *filename; /* output name (?) */ save_dialog_t type; file_pattern_info *fp; dialog_play_info *dp; void *file_watcher; file_popup_info *fpop; const char *original_filename; } save_as_dialog_info; static save_as_dialog_info *save_sound_as = NULL, *save_selection_as = NULL, *save_region_as = NULL; static save_as_dialog_info *new_save_as_dialog_info(save_dialog_t type) { save_as_dialog_info *sd; sd = (save_as_dialog_info *)calloc(1, sizeof(save_as_dialog_info)); sd->type = type; return(sd); } static void make_auto_comment(save_as_dialog_info *sd) { if ((sd == save_sound_as) && (XtIsManaged(sd->dialog))) { file_data *fd; fd = sd->panel_data; if (!(fd->auto_comment)) { /* don't erase typed-in comment, if any */ XmTextSetString(fd->comment_text, fd->saved_comment); } else { snd_info *sp; bool edits = false; int i; char *original_sound_comment, *comment, *orig_comment = NULL; sp = any_selected_sound(); original_sound_comment = mus_sound_comment(sp->filename); if (original_sound_comment) { if (*original_sound_comment) orig_comment = mus_format("\n%s comment:\n%s\n", sp->short_filename, original_sound_comment); free(original_sound_comment); original_sound_comment = NULL; } if (fd->saved_comment) XtFree(fd->saved_comment); fd->saved_comment = XmTextGetString(fd->comment_text); if ((fd->saved_comment) && (!(*(fd->saved_comment)))) { /* this is the norm in Motif */ XtFree(fd->saved_comment); fd->saved_comment = NULL; } for (i = 0; i < sp->nchans; i++) if (sp->chans[i]->edit_ctr != 0) { edits = true; break; } if (!edits) comment = mus_format("%s%ssaved %s from %s (no edits)\n%s", (fd->saved_comment) ? fd->saved_comment : "", (fd->saved_comment) ? "\n" : "", snd_local_time(), sp->filename, (orig_comment) ? orig_comment : ""); else { int len; char **edit_strs; char *time; time = snd_local_time(); len = 2 * mus_strlen(sp->filename) + mus_strlen(time) + 32 * sp->nchans + mus_strlen(fd->saved_comment) + mus_strlen(original_sound_comment); edit_strs = (char **)malloc(sp->nchans * sizeof(char *)); for (i = 0; i < sp->nchans; i++) { edit_strs[i] = edit_list_to_function(sp->chans[i], 1, sp->chans[i]->edit_ctr); len += mus_strlen(edit_strs[i]); } comment = (char *)calloc(len, sizeof(char)); snprintf(comment, len, "%s%ssaved %s from %s with edits:\n", (fd->saved_comment) ? fd->saved_comment : "", (fd->saved_comment) ? "\n" : "", snd_local_time(), sp->filename); for (i = 0; i < sp->nchans; i++) { if (sp->nchans > 1) { char buf[32]; snprintf(buf, 32, "\n-------- channel %d --------\n", i); strcat(comment, buf); } strcat(comment, edit_strs[i]); } if (orig_comment) strcat(comment, orig_comment); free(edit_strs); } XmTextSetString(fd->comment_text, comment); if (comment) free(comment); if (orig_comment) free(orig_comment); } } } static void auto_comment_callback(Widget w, XtPointer context, XtPointer info) { save_as_dialog_info *sd = (save_as_dialog_info *)context; XmToggleButtonCallbackStruct *cb = (XmToggleButtonCallbackStruct *)info; sd->panel_data->auto_comment = (cb->set); make_auto_comment(sd); } void reflect_save_as_src(bool val) { if (save_sound_as) XmToggleButtonSetState(save_sound_as->panel_data->src_button, val, true); if (save_selection_as) XmToggleButtonSetState(save_selection_as->panel_data->src_button, val, true); if (save_region_as) XmToggleButtonSetState(save_region_as->panel_data->src_button, val, true); } void reflect_save_as_auto_comment(bool val) { if (save_sound_as) XmToggleButtonSetState(save_sound_as->panel_data->auto_comment_button, val, true); } void reflect_save_as_sound_selection(const char *sound_name) { if ((save_sound_as) && (XtIsManaged(save_sound_as->dialog))) { XmString xmstr2; char *file_string; file_string = (char *)calloc(PRINT_BUFFER_SIZE, sizeof(char)); if (sound_name) snprintf(file_string, PRINT_BUFFER_SIZE, "save %s", sound_name); else { snd_info *sp; sp = any_selected_sound(); if (sp) snprintf(file_string, PRINT_BUFFER_SIZE, "save %s", sp->short_filename); else snprintf(file_string, PRINT_BUFFER_SIZE, "nothing to save!"); } xmstr2 = XmStringCreateLocalized(file_string); XtVaSetValues(save_sound_as->dialog, XmNdialogTitle, xmstr2, NULL); XmStringFree(xmstr2); free(file_string); } } void reflect_selection_in_save_as_dialog(bool on) { if ((on) && (save_selection_as) && (save_selection_as->panel_data)) clear_dialog_error(save_selection_as->panel_data); } void reflect_region_in_save_as_dialog(void) { if ((save_region_as) && (save_region_as->dialog) && (XtIsManaged(save_region_as->dialog)) && (region_ok(region_dialog_region()))) clear_dialog_error(save_region_as->panel_data); } static void save_as_filename_modify_callback(Widget w, XtPointer context, XtPointer info); static void save_as_undoit(save_as_dialog_info *sd) { XmString ok_label; ok_label = XmStringCreateLocalized((char *)"Save"); XtVaSetValues(sd->dialog, XmNokLabelString, ok_label, NULL); XmStringFree(ok_label); clear_dialog_error(sd->panel_data); XtRemoveCallback(sd->filename_widget, XmNmodifyVerifyCallback, save_as_filename_modify_callback, (XtPointer)(sd->panel_data)); sd->file_watcher = unmonitor_file(sd->file_watcher); } static void save_as_filename_modify_callback(Widget w, XtPointer context, XtPointer info) { XmTextVerifyCallbackStruct *cbs = (XmTextVerifyCallbackStruct *)info; save_as_undoit((save_as_dialog_info *)context); cbs->doit = true; } static void clear_error_if_save_as_filename_changes(Widget dialog, save_as_dialog_info *sd) { XtAddCallback(sd->filename_widget, XmNmodifyVerifyCallback, save_as_filename_modify_callback, (XtPointer)sd); } static bool srates_differ(int srate, save_as_dialog_info *sd) { switch (sd->type) { case SOUND_SAVE_AS: return(snd_srate(any_selected_sound()) != srate); case SELECTION_SAVE_AS: return(selection_srate() != srate); case REGION_SAVE_AS: return(region_srate(region_dialog_region()) != srate); } return(false); } static double srate_ratio(int srate, save_as_dialog_info *sd) { switch (sd->type) { case SOUND_SAVE_AS: return((double)(snd_srate(any_selected_sound())) / (double)srate); case SELECTION_SAVE_AS: return((double)selection_srate() / (double)srate); case REGION_SAVE_AS: return((double)region_srate(region_dialog_region()) / (double)srate); } return(1.0); } static void save_or_extract(save_as_dialog_info *sd, bool saving) { char *str = NULL, *comment = NULL, *msg = NULL, *fullname = NULL, *tmpfile = NULL; snd_info *sp = NULL; mus_header_t header_type = MUS_NEXT, output_type; mus_sample_t sample_type = DEFAULT_OUTPUT_SAMPLE_TYPE; int srate = DEFAULT_OUTPUT_SRATE; int chan = 0, extractable_chans = 0; bool file_exists = false; io_error_t io_err = IO_NO_ERROR; clear_dialog_error(sd->panel_data); if ((sd->type == SELECTION_SAVE_AS) && (!(selection_is_active()))) { if (saving) msg = (char *)"no selection to save"; else msg = (char *)"can't extract: no selection"; post_file_dialog_error((const char *)msg, sd->panel_data); return; } if ((sd->type == REGION_SAVE_AS) && (!(region_ok(region_dialog_region())))) { post_file_dialog_error("no region to save", sd->panel_data); return; } sp = any_selected_sound(); if ((!sp) && (sd->type != REGION_SAVE_AS)) { if (saving) msg = (char *)"nothing to save"; else msg = (char *)"nothing to extract"; post_file_dialog_error((const char *)msg, sd->panel_data); clear_error_if_filename_changes(sd->dialog, sd->panel_data); return; } /* get output filename */ str = XmTextGetString(sd->filename_widget); if ((!str) || (!*str)) { if (saving) msg = (char *)"can't save: no file name given"; else msg = (char *)"can't extract: no file name given"; post_file_dialog_error((const char *)msg, sd->panel_data); clear_error_if_filename_changes(sd->dialog, sd->panel_data); return; } /* get output file attributes */ redirect_snd_error_to(post_file_panel_error, (void *)(sd->panel_data)); { mus_long_t location = 28, samples = 0; int chans = 1; if (saving) comment = get_file_dialog_sound_attributes(sd->panel_data, &srate, &chans, &header_type, &sample_type, &location, &samples, 0); else comment = get_file_dialog_sound_attributes(sd->panel_data, &srate, &chan, &header_type, &sample_type, &location, &samples, 0); } output_type = header_type; redirect_snd_error_to(NULL, NULL); if (sd->panel_data->error_widget != NOT_A_SCANF_WIDGET) { clear_error_if_panel_changes(sd->dialog, sd->panel_data); if (comment) free(comment); XtFree(str); return; } switch (sd->type) { case SOUND_SAVE_AS: clear_status_area(sp); if (!saving) extractable_chans = sp->nchans; break; case SELECTION_SAVE_AS: if (!saving) extractable_chans = selection_chans(); break; default: break; } if (!saving) { if ((chan > extractable_chans) || (((extractable_chans > 1) && (chan == extractable_chans)) || (chan < 0))) { if (chan > extractable_chans) msg = mus_format("can't extract chan %d (%s has %d chan%s)", chan, (sd->type == SOUND_SAVE_AS) ? "sound" : "selection", extractable_chans, (extractable_chans > 1) ? "s" : ""); else msg = mus_format("can't extract chan %d (first chan is numbered 0)", chan); post_file_dialog_error((const char *)msg, sd->panel_data); clear_error_if_chans_changes(sd->dialog, sd->panel_data); free(msg); if (comment) free(comment); XtFree(str); return; } } fullname = mus_expand_filename(str); if (run_before_save_as_hook(sp, fullname, sd->type != SOUND_SAVE_AS, srate, sample_type, header_type, comment)) { msg = mus_format("%s cancelled by %s", (saving) ? "save" : "extract", S_before_save_as_hook); post_file_dialog_error((const char *)msg, sd->panel_data); clear_error_if_filename_changes(sd->dialog, sd->panel_data); free(msg); free(fullname); if (comment) free(comment); XtFree(str); return; } file_exists = mus_file_probe(fullname); if ((sd->type == SOUND_SAVE_AS) && (mus_strcmp(fullname, sp->filename))) { /* save-as here is the same as save */ if ((sp->user_read_only == FILE_READ_ONLY) || (sp->file_read_only == FILE_READ_ONLY)) { msg = mus_format("can't overwrite %s (it is write-protected)", sp->short_filename); post_file_dialog_error((const char *)msg, sd->panel_data); clear_error_if_filename_changes(sd->dialog, sd->panel_data); free(msg); free(fullname); if (comment) free(comment); XtFree(str); return; } } else { if (!(sd->file_watcher)) { /* check for overwrites that are questionable -- DoIt click will return here with sd->file_watcher active */ snd_info *parlous_sp = NULL; if ((file_exists) && ((ask_before_overwrite(ss)) || ((sd->type == SOUND_SAVE_AS) && (parlous_sp = file_is_open_elsewhere_and_has_unsaved_edits(sp, fullname))))) { XmString ok_label; msg = mus_format("%s exists%s. To overwrite it, click 'DoIt'", str, (parlous_sp) ? ", and has unsaved edits" : ""); post_file_dialog_error((const char *)msg, sd->panel_data); clear_error_if_save_as_filename_changes(sd->dialog, sd); ok_label = XmStringCreateLocalized((char *)"DoIt"); XtVaSetValues(sd->dialog, XmNokLabelString, ok_label, NULL); XmUpdateDisplay(FSB_BOX(sd->dialog, XmDIALOG_OK_BUTTON)); XmStringFree(ok_label); free(msg); free(fullname); if (comment) free(comment); XtFree(str); return; } } } /* try to save... if it exists already, first write as temp, then move */ if (sd->file_watcher) save_as_undoit(sd); ss->local_errno = 0; if (header_is_encoded(header_type)) { output_type = header_type; sample_type = MUS_LSHORT; header_type = MUS_RIFF; tmpfile = snd_tempnam(); } else { tmpfile = fullname; } redirect_snd_error_to(redirect_post_file_dialog_error, (void *)(sd->panel_data)); switch (sd->type) { case SOUND_SAVE_AS: if (saving) io_err = save_edits_without_display(sp, tmpfile, header_type, sample_type, srate, comment, AT_CURRENT_EDIT_POSITION); else io_err = save_channel_edits(sp->chans[chan], tmpfile, AT_CURRENT_EDIT_POSITION); /* protects if same name */ break; case SELECTION_SAVE_AS: { char *ofile; if (file_exists) /* file won't exist if we're encoding, so this isn't as wasteful as it looks */ ofile = snd_tempnam(); else ofile = mus_strdup(tmpfile); io_err = save_selection(ofile, srate, sample_type, header_type, comment, (saving) ? SAVE_ALL_CHANS : chan); if (io_err == IO_NO_ERROR) io_err = move_file(ofile, fullname); free(ofile); } break; case REGION_SAVE_AS: { if (region_ok(region_dialog_region())) { char *ofile; if (file_exists) ofile = snd_tempnam(); else ofile = mus_strdup(tmpfile); io_err = save_region(region_dialog_region(), ofile, sample_type, header_type, comment); if (io_err == IO_NO_ERROR) io_err = move_file(ofile, fullname); free(ofile); } } break; } redirect_snd_error_to(NULL, NULL); /* check for possible srate conversion */ if ((sd->panel_data->src) && (srates_differ(srate, sd))) { /* if src, and srates differ, do the sampling rate conversion. * this needs to happen before the snd_encode (->OGG etc) below * if we do it before the save-as above, then undo it later, it messes up the user's edit history list * so do it here to tmpfile (tmpfile is fullname unless we're doing a translation to something like OGG) */ src_file(tmpfile, srate_ratio(srate, sd)); } if (io_err == IO_NO_ERROR) { if (header_is_encoded(output_type)) { snd_encode(output_type, tmpfile, fullname); snd_remove(tmpfile, REMOVE_FROM_CACHE); free(tmpfile); } remember_filename(fullname, sd->fpop->file_text_names); if (!file_exists) force_directory_reread(sd->dialog); if (saving) { if (sd->type == SOUND_SAVE_AS) status_report(sp, "%s saved as %s", sp->short_filename, str); else status_report(sp, "%s saved as %s", (sd->type == SELECTION_SAVE_AS) ? "selection" : "region", str); } else { if (sd->type == SOUND_SAVE_AS) status_report(sp, "%s chan %d saved as %s", sp->short_filename, chan, str); else status_report(sp, "selection chan %d saved as %s", chan, str); } run_after_save_as_hook(sp, str, true); /* true => from dialog */ XtUnmanageChild(sd->dialog); } else { msg = mus_format("%s as %s: %s (%s)", (saving) ? "save" : "extract chan", str, io_error_name(io_err), snd_io_strerror()); post_file_dialog_error((const char *)msg, sd->panel_data); clear_error_if_filename_changes(sd->dialog, sd->panel_data); free(msg); } free(fullname); XtFree(str); if (comment) free(comment); } static void save_as_ok_callback(Widget w, XtPointer context, XtPointer info) { save_or_extract((save_as_dialog_info *)context, true); } static void save_as_extract_callback(Widget w, XtPointer context, XtPointer info) { save_or_extract((save_as_dialog_info *)context, false); } static void save_as_dialog_select_callback(Widget w, XtPointer context, XtPointer info) { #if WITH_AUDIO dialog_play_info *dp = (dialog_play_info *)context; char *filename = NULL; XmString *strs; XtVaGetValues(w, XmNselectedItems, &strs, NULL); filename = (char *)XmStringUnparse(strs[0], NULL, XmCHARSET_TEXT, XmCHARSET_TEXT, NULL, 0, XmOUTPUT_ALL); if ((filename) && (is_sound_file(filename))) XtManageChild(dp->play_button); else { if (XtIsManaged(dp->play_button)) XtUnmanageChild(dp->play_button); } if (filename) XtFree(filename); #endif } static void save_as_cancel_callback(Widget w, XtPointer context, XtPointer info) { save_as_dialog_info *sd = (save_as_dialog_info *)context; XtUnmanageChild(sd->dialog); } static void save_as_help_callback(Widget w, XtPointer context, XtPointer info) { save_as_dialog_help(); } static bool directory_exists(char *name) { char temp; bool result; int i, len, last_slash = -1; len = strlen(name); for (i = 0; i < len; i++) if (name[i] == '/') last_slash = i; if (last_slash <= 0) return(true); if (last_slash >= len - 1) /* can't be > */ return(is_directory(name)); temp = name[last_slash + 1]; name[last_slash + 1] = '\0'; result = is_directory(name); name[last_slash + 1] = temp; return(result); } static void save_as_file_exists_check(Widget w, XtPointer context, XtPointer info) { Widget dialog = (Widget)context; char *filename = NULL; XmString s1; filename = XmTextGetString(w); if ((filename) && (*filename)) { if ((mus_file_probe(filename)) && (!is_directory(filename))) { #ifndef _MSC_VER if (access(filename, W_OK) < 0) s1 = XmStringCreateLocalized((char *)"save as (file write-protected?):"); else #endif s1 = XmStringCreateLocalized((char *)"save as (overwriting):"); } else { if (!(directory_exists(filename))) s1 = XmStringCreateLocalized((char *)"save as (no such directory?):"); else s1 = XmStringCreateLocalized((char *)"save as:"); } } else s1 = XmStringCreateLocalized((char *)"save as:"); XtVaSetValues(dialog, XmNselectionLabelString, s1, NULL); if (filename) XtFree(filename); } static int snd_mkdir(const char *filename) { #ifdef __MINGW32__ return(mkdir(filename)); #else return(mkdir(filename, 0777)); #endif } static void save_as_mkdir_callback(Widget w, XtPointer context, XtPointer info) { save_as_dialog_info *sd = (save_as_dialog_info *)context; char *filename = NULL; filename = XmTextGetString(FSB_BOX(sd->dialog, XmDIALOG_TEXT)); if (snd_mkdir(filename) < 0) { /* could not make the directory */ char *str; str = mus_format("can't make %s: %s", filename, strerror(errno)); post_file_dialog_error((const char *)str, sd->panel_data); clear_error_if_filename_changes(sd->dialog, sd->panel_data); free(str); } else { /* set FSB to new dir and force update */ char *filter; filter = mus_format("%s*", filename); /* already has the "/" at the end */ update_dir_list(sd->dialog, filter); free(filter); XtSetSensitive(w, false); } XtFree(filename); } static void reflect_text_in_save_button(Widget w, XtPointer context, XtPointer info) { save_as_dialog_info *sd = (save_as_dialog_info *)context; /* w here is text widget, not button */ XtSetSensitive(FSB_BOX(sd->dialog, XmDIALOG_OK_BUTTON), (!(file_is_directory(sd->dialog)))); if (sd->mkdirB) XtSetSensitive(sd->mkdirB, file_is_nonexistent_directory(sd->dialog)); } static void reflect_text_in_extract_button(Widget w, XtPointer context, XtPointer info) { save_as_dialog_info *sd = (save_as_dialog_info *)context; /* w here is text widget, not button */ XtSetSensitive(sd->extractB, (!(file_is_directory(sd->dialog)))); } static void save_as_filter_text_activate_callback(Widget w, XtPointer context, XtPointer info) { save_as_dialog_info *sd = (save_as_dialog_info *)context; force_directory_reread_and_let_filename_change(sd->dialog); } static void make_save_as_dialog(save_as_dialog_info *sd, char *sound_name, mus_header_t header_type, mus_sample_t sample_type) { char *file_string; sd->original_filename = sound_name; if (!(sd->dialog)) { Arg args[32]; int n; XmString xmstr1, xmstr2, s1; XmString filter_list_label, cancel_label; Widget extractB, mainform; n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; s1 = XmStringCreateLocalized((char *)"save as:"); XtSetArg(args[n], XmNselectionLabelString, s1); n++; xmstr1 = XmStringCreateLocalized((char *)"Save"); XtSetArg(args[n], XmNokLabelString, xmstr1); n++; file_string = (char *)calloc(PRINT_BUFFER_SIZE, sizeof(char)); snprintf(file_string, PRINT_BUFFER_SIZE, "save %s", sound_name); xmstr2 = XmStringCreateLocalized(file_string); XtSetArg(args[n], XmNdialogTitle, xmstr2); n++; filter_list_label = XmStringCreateLocalized((char *)"files listed:"); XtSetArg(args[n], XmNfilterLabelString, filter_list_label); n++; cancel_label = XmStringCreateLocalized((char *)I_GO_AWAY); XtSetArg(args[n], XmNcancelLabelString, cancel_label); n++; sd->fp = (file_pattern_info *)calloc(1, sizeof(file_pattern_info)); sd->fp->in_just_sounds_update = false; if (just_sounds(ss)) sd->fp->filter_choice = JUST_SOUNDS_FILTER; else sd->fp->filter_choice = NO_FILE_FILTER; sd->dp = (dialog_play_info *)calloc(1, sizeof(dialog_play_info)); sd->fpop = (file_popup_info *)calloc(1, sizeof(file_popup_info)); sd->fpop->fp = sd->fp; XtSetArg(args[n], XmNresizePolicy, XmRESIZE_GROW); n++; XtSetArg(args[n], XmNnoResize, false); n++; XtSetArg(args[n], XmNautoUnmanage, false); n++; XtSetArg(args[n], XmNchildPlacement, XmPLACE_ABOVE_SELECTION); n++; XtSetArg(args[n], XmNallowOverlap, false); n++; XtSetArg(args[n], XmNheight, 600); n++; XtSetArg(args[n], XmNuserData, (XtPointer)sd->fp); n++; XtSetArg(args[n], XmNfileFilterStyle, XmFILTER_HIDDEN_FILES); n++; XtSetArg(args[n], XmNfileSearchProc, snd_directory_reader); n++; /* over-ride Motif's directory reader altogether */ sd->dialog = XmCreateFileSelectionDialog(MAIN_SHELL(ss), (char *)"save-as", args, n); sd->fp->dialog = sd->dialog; sd->dp->dialog = sd->dialog; sd->fpop->dialog = sd->dialog; free(file_string); XtUnmanageChild(FSB_BOX(sd->dialog, XmDIALOG_DIR_LIST_LABEL)); XtUnmanageChild(FSB_BOX(sd->dialog, XmDIALOG_LIST_LABEL)); XtUnmanageChild(FSB_BOX(sd->dialog, XmDIALOG_APPLY_BUTTON)); XtVaSetValues(FSB_BOX(sd->dialog, XmDIALOG_FILTER_LABEL), XmNbackground, ss->basic_color, NULL); XtVaSetValues(FSB_BOX(sd->dialog, XmDIALOG_SELECTION_LABEL), XmNbackground, ss->basic_color, NULL); XmStringFree(s1); XmStringFree(xmstr1); XmStringFree(xmstr2); XmStringFree(filter_list_label); XmStringFree(cancel_label); sd->filename_widget = FSB_BOX(sd->dialog, XmDIALOG_TEXT); XtAddCallback(sd->dialog, XmNhelpCallback, save_as_help_callback, (XtPointer)sd); XtAddCallback(sd->dialog, XmNcancelCallback, save_as_cancel_callback, (XtPointer)sd); XtAddCallback(sd->dialog, XmNokCallback, save_as_ok_callback, (XtPointer)sd); mainform = XtVaCreateManagedWidget("filebuttons-mainform", xmFormWidgetClass, sd->dialog, NULL); add_play_and_just_sounds_buttons(sd->dialog, mainform, sd->fp, sd->dp); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, sd->fp->just_sounds_button); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; sd->panel_data = make_file_data_panel(mainform, "data-form", args, n, (sd->type == REGION_SAVE_AS) ? WITHOUT_CHANNELS_FIELD : WITH_EXTRACT_CHANNELS_FIELD, header_type, sample_type, WITHOUT_DATA_LOCATION_FIELD, WITHOUT_SAMPLES_FIELD, WITH_HEADER_TYPE_FIELD, WITH_COMMENT_FIELD, WITH_WRITABLE_HEADERS, WITH_SRATE, sd->type == SOUND_SAVE_AS); /* auto comment */ sd->panel_data->dialog = sd->dialog; color_file_selection_box(sd->dialog); XtVaSetValues(sd->panel_data->sample_type_list, XmNbackground, ss->white, XmNforeground, ss->black, NULL); XtVaSetValues(sd->panel_data->header_type_list, XmNbackground, ss->white, XmNforeground, ss->black, NULL); XtVaSetValues(sd->fp->just_sounds_button, XmNselectColor, ss->selection_color, NULL); #if WITH_AUDIO XtVaSetValues(sd->dp->play_button, XmNselectColor, ss->selection_color, NULL); #endif XtVaSetValues(sd->panel_data->src_button, XmNselectColor, ss->selection_color, NULL); if (sd->type == SOUND_SAVE_AS) { XtVaSetValues(sd->panel_data->auto_comment_button, XmNselectColor, ss->selection_color, NULL); XtAddCallback(sd->panel_data->auto_comment_button, XmNvalueChangedCallback, auto_comment_callback, (XtPointer)sd); } XtAddCallback(FSB_BOX(sd->dialog, XmDIALOG_LIST), XmNbrowseSelectionCallback, save_as_dialog_select_callback, (XtPointer)(sd->dp)); XtAddCallback(sd->filename_widget, XmNvalueChangedCallback, save_as_file_exists_check, (XtPointer)(sd->dialog)); XtAddCallback(FSB_BOX(sd->dialog, XmDIALOG_FILTER_TEXT), XmNactivateCallback, save_as_filter_text_activate_callback, (void *)sd); { Widget wtmp; wtmp = FSB_BOX(sd->dialog, XmDIALOG_DIR_LIST); if (wtmp) XtAddCallback(wtmp, XmNbrowseSelectionCallback, file_change_directory_callback, (XtPointer)(sd->fp)); } add_file_popups(sd->fpop); /* this must come after the file data panel so that Motif puts it in the button box, not the main work area */ if (sd->type != REGION_SAVE_AS) { /* add "Extract" button */ n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNarmColor, ss->selection_color); n++; extractB = XtCreateManagedWidget("Extract", xmPushButtonGadgetClass, sd->dialog, args, n); XtAddCallback(extractB, XmNactivateCallback, save_as_extract_callback, (XtPointer)sd); sd->extractB = extractB; XtSetSensitive(extractB, (!(file_is_directory(sd->dialog)))); XtAddCallback(FSB_BOX(sd->dialog, XmDIALOG_TEXT), XmNvalueChangedCallback, reflect_text_in_extract_button, (void *)sd); } /* add "Mkdir" button */ n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNarmColor, ss->selection_color); n++; sd->mkdirB = XtCreateManagedWidget("Mkdir", xmPushButtonGadgetClass, sd->dialog, args, n); XtAddCallback(sd->mkdirB, XmNactivateCallback, save_as_mkdir_callback, (XtPointer)sd); XtSetSensitive(sd->mkdirB, false); XtSetSensitive(FSB_BOX(sd->dialog, XmDIALOG_OK_BUTTON), (!(file_is_directory(sd->dialog)))); XtAddCallback(FSB_BOX(sd->dialog, XmDIALOG_TEXT), XmNvalueChangedCallback, reflect_text_in_save_button, (void *)sd); XtManageChild(sd->dialog); switch (sd->type) { case SOUND_SAVE_AS: set_dialog_widget(SOUND_SAVE_AS_DIALOG, sd->dialog); break; case SELECTION_SAVE_AS: set_dialog_widget(SELECTION_SAVE_AS_DIALOG, sd->dialog); break; case REGION_SAVE_AS: set_dialog_widget(REGION_SAVE_AS_DIALOG, sd->dialog); break; default: snd_error("internal screw up"); break; } } else { XmString xmstr2; file_string = (char *)calloc(PRINT_BUFFER_SIZE, sizeof(char)); snprintf(file_string, PRINT_BUFFER_SIZE, "save %s", sound_name); xmstr2 = XmStringCreateLocalized(file_string); XtVaSetValues(sd->dialog, XmNdialogTitle, xmstr2, NULL); XmStringFree(xmstr2); free(file_string); } } static save_as_dialog_info *make_sound_save_as_dialog_1(bool managed, int chan) { /* should the save-as dialog, at least in the file case, reflect the current file attributes/comment? * or should we have a save-as-hook that can set up the dialog fields? */ snd_info *sp = NULL; char *com = NULL; file_info *hdr = NULL; save_as_dialog_info *sd; if (!save_sound_as) save_sound_as = new_save_as_dialog_info(SOUND_SAVE_AS); sd = save_sound_as; sp = any_selected_sound(); if (sp) hdr = sp->hdr; make_save_as_dialog(sd, (char *)((sp) ? sp->short_filename : ""), default_output_header_type(ss), default_output_sample_type(ss)); set_file_dialog_sound_attributes(sd->panel_data, sd->panel_data->current_header_type, sd->panel_data->current_sample_type, (hdr) ? hdr->srate : selection_srate(), IGNORE_CHANS, IGNORE_DATA_LOCATION, IGNORE_SAMPLES, com = output_comment(hdr)); if (com) free(com); if (chan >= 0) { char *chan_str; chan_str = (char *)calloc(8, sizeof(char)); snprintf(chan_str, 8, "%d", chan); XmTextFieldSetString(sd->panel_data->chans_text, chan_str); free(chan_str); } if (sd->fp->reread_directory) { force_directory_reread(sd->dialog); sd->fp->reread_directory = false; } if ((managed) && (!XtIsManaged(sd->dialog))) XtManageChild(sd->dialog); make_auto_comment(sd); return(sd); } widget_t make_sound_save_as_dialog(bool managed) { save_as_dialog_info *sd; sd = make_sound_save_as_dialog_1(managed, -1); return(sd->dialog); } void make_channel_extract_dialog(int chan) { make_sound_save_as_dialog_1(true, chan); } widget_t make_selection_save_as_dialog(bool managed) { save_as_dialog_info *sd; if (!save_selection_as) save_selection_as = new_save_as_dialog_info(SELECTION_SAVE_AS); sd = save_selection_as; make_save_as_dialog(sd, (char *)"current selection", default_output_header_type(ss), default_output_sample_type(ss)); set_file_dialog_sound_attributes(sd->panel_data, sd->panel_data->current_header_type, sd->panel_data->current_sample_type, selection_srate(), IGNORE_CHANS, IGNORE_DATA_LOCATION, IGNORE_SAMPLES, NULL); if (sd->fp->reread_directory) { force_directory_reread(sd->dialog); sd->fp->reread_directory = false; } if ((managed) && (!XtIsManaged(sd->dialog))) XtManageChild(sd->dialog); return(sd->dialog); } widget_t make_region_save_as_dialog(bool managed) { save_as_dialog_info *sd; char *comment = NULL; if (!save_region_as) save_region_as = new_save_as_dialog_info(REGION_SAVE_AS); sd = save_region_as; make_save_as_dialog(sd, (char *)"selected region", default_output_header_type(ss), default_output_sample_type(ss)); comment = region_description(region_dialog_region()); set_file_dialog_sound_attributes(sd->panel_data, sd->panel_data->current_header_type, sd->panel_data->current_sample_type, region_srate(region_dialog_region()), IGNORE_CHANS, IGNORE_DATA_LOCATION, IGNORE_SAMPLES, comment); if (sd->fp->reread_directory) { force_directory_reread(sd->dialog); sd->fp->reread_directory = false; } if ((managed) && (!XtIsManaged(sd->dialog))) XtManageChild(sd->dialog); if (comment) free(comment); return(sd->dialog); } /* -------- save/restore for all these dialogs -------- */ void save_file_dialog_state(FILE *fd) { if ((odat) && (XtIsManaged(odat->dialog))) { /* odat->file_dialog_read_only -> "view-sound" dialog -- this distinction currently ignored */ #if HAVE_SCHEME fprintf(fd, "(%s #t)\n", S_open_file_dialog); #endif #if HAVE_RUBY fprintf(fd, "%s(true)\n", to_proc_name(S_open_file_dialog)); #endif #if HAVE_FORTH fprintf(fd, "#t %s drop\n", S_open_file_dialog); #endif } if ((mdat) && (XtIsManaged(mdat->dialog))) { #if HAVE_SCHEME fprintf(fd, "(%s #t)\n", S_mix_file_dialog); #endif #if HAVE_RUBY fprintf(fd, "%s(true)\n", to_proc_name(S_mix_file_dialog)); #endif #if HAVE_FORTH fprintf(fd, "#t %s drop\n", S_mix_file_dialog); #endif } if ((idat) && (XtIsManaged(idat->dialog))) { #if HAVE_SCHEME fprintf(fd, "(%s #t)\n", S_insert_file_dialog); #endif #if HAVE_RUBY fprintf(fd, "%s(true)\n", to_proc_name(S_insert_file_dialog)); #endif #if HAVE_FORTH fprintf(fd, "#t %s drop\n", S_insert_file_dialog); #endif } if ((save_sound_as) && (XtIsManaged(save_sound_as->dialog))) { #if HAVE_SCHEME fprintf(fd, "(%s #t)\n", S_save_sound_dialog); #endif #if HAVE_RUBY fprintf(fd, "%s(true)\n", to_proc_name(S_save_sound_dialog)); #endif #if HAVE_FORTH fprintf(fd, "#t %s drop\n", S_save_sound_dialog); #endif } if ((save_selection_as) && (XtIsManaged(save_selection_as->dialog))) { #if HAVE_SCHEME fprintf(fd, "(%s #t)\n", S_save_selection_dialog); #endif #if HAVE_RUBY fprintf(fd, "%s(true)\n", to_proc_name(S_save_selection_dialog)); #endif #if HAVE_FORTH fprintf(fd, "#t %s drop\n", S_save_selection_dialog); #endif } if ((save_region_as) && (XtIsManaged(save_region_as->dialog))) { #if HAVE_SCHEME fprintf(fd, "(%s #t)\n", S_save_region_dialog); #endif #if HAVE_RUBY fprintf(fd, "%s(true)\n", to_proc_name(S_save_region_dialog)); #endif #if HAVE_FORTH fprintf(fd, "#t %s drop\n", S_save_region_dialog); #endif } } /* -------------------------------- New File -------------------------------- */ static Widget new_file_dialog = NULL; static file_data *ndat = NULL; static mus_long_t initial_samples = 1; static Widget new_file_text = NULL; static char *new_file_filename = NULL; static void *new_file_watcher = NULL; static void new_filename_modify_callback(Widget w, XtPointer context, XtPointer info); static void new_file_undoit(void) { XmString ok_label; ok_label = XmStringCreateLocalized((char *)"Ok"); XtVaSetValues(new_file_dialog, XmNokLabelString, ok_label, NULL); XmStringFree(ok_label); clear_dialog_error(ndat); XtRemoveCallback(new_file_text, XmNmodifyVerifyCallback, new_filename_modify_callback, NULL); new_file_watcher = unmonitor_file(new_file_watcher); } static void new_filename_modify_callback(Widget w, XtPointer context, XtPointer info) { XmTextVerifyCallbackStruct *cbs = (XmTextVerifyCallbackStruct *)info; new_file_undoit(); cbs->doit = true; } static void clear_error_if_new_filename_changes(Widget dialog) { XtAddCallback(new_file_text, XmNmodifyVerifyCallback, new_filename_modify_callback, NULL); } static void new_file_ok_callback(Widget w, XtPointer context, XtPointer info) { mus_long_t loc; char *newer_name = NULL, *msg; mus_header_t header_type; mus_sample_t sample_type; int srate, chans; newer_name = XmTextGetString(new_file_text); if ((!newer_name) || (!(*newer_name))) { msg = (char *)"new sound needs a file name ('New file:' field is empty)"; post_file_dialog_error((const char *)msg, ndat); clear_error_if_new_filename_changes(new_file_dialog); } else { char *comment; redirect_snd_error_to(post_file_panel_error, (void *)ndat); comment = get_file_dialog_sound_attributes(ndat, &srate, &chans, &header_type, &sample_type, &loc, &initial_samples, 1); redirect_snd_error_to(NULL, NULL); if (ndat->error_widget != NOT_A_SCANF_WIDGET) { clear_error_if_panel_changes(new_file_dialog, ndat); } else { /* handle the overwrite hook directly */ if (new_file_filename) free(new_file_filename); new_file_filename = mus_expand_filename(newer_name); if ((!new_file_watcher) && (ask_before_overwrite(ss)) && (mus_file_probe(new_file_filename))) { XmString ok_label; msg = mus_format("%s exists. If you want to overwrite it, click 'DoIt'", newer_name); post_file_dialog_error((const char *)msg, ndat); clear_error_if_new_filename_changes(new_file_dialog); ok_label = XmStringCreateLocalized((char *)"DoIt"); XtVaSetValues(new_file_dialog, XmNokLabelString, ok_label, NULL); XmUpdateDisplay(MSG_BOX(new_file_dialog, XmDIALOG_OK_BUTTON)); XmStringFree(ok_label); free(msg); } else { snd_info *sp; if (new_file_watcher) new_file_undoit(); ss->local_errno = 0; redirect_snd_error_to(redirect_post_file_dialog_error, (void *)ndat); sp = snd_new_file(new_file_filename, chans, srate, sample_type, header_type, comment, initial_samples); redirect_snd_error_to(NULL, NULL); if (!sp) { clear_error_if_new_filename_changes(new_file_dialog); } else { XtUnmanageChild(new_file_dialog); } } } XtFree(newer_name); if (comment) free(comment); } } static char *new_file_dialog_filename(mus_header_t header_type) { static int new_file_dialog_file_ctr = 1; char *filename = NULL; const char *extension = NULL; filename = (char *)calloc(64, sizeof(char)); switch (header_type) { case MUS_AIFC: extension = "aiff"; break; case MUS_AIFF: extension = "aiff"; break; case MUS_RIFF: extension = "wav"; break; case MUS_RF64: extension = "wav"; break; case MUS_CAFF: extension = "caf"; break; default: extension = "snd"; break; } snprintf(filename, 64, "new-%d.%s", new_file_dialog_file_ctr++, extension); return(filename); } static void load_new_file_defaults(char *newname) { char *new_comment = NULL; mus_header_t header_type; mus_sample_t sample_type; int chans, srate; header_type = default_output_header_type(ss); chans = default_output_chans(ss); sample_type = default_output_sample_type(ss); srate = default_output_srate(ss); new_comment = output_comment(NULL); if ((!newname) || (!(*newname))) newname = new_file_dialog_filename(header_type); mus_sound_forget(newname); set_file_dialog_sound_attributes(ndat, header_type, sample_type, srate, chans, IGNORE_DATA_LOCATION, initial_samples, new_comment); if (new_comment) free(new_comment); } static void new_file_reset_callback(Widget w, XtPointer context, XtPointer info) { char *current_name; current_name = XmTextGetString(new_file_text); load_new_file_defaults(current_name); if (current_name) XtFree(current_name); if (new_file_watcher) new_file_undoit(); } static void new_file_cancel_callback(Widget w, XtPointer context, XtPointer info) { XtUnmanageChild(w); } static void new_file_help_callback(Widget w, XtPointer context, XtPointer info) { new_file_dialog_help(); } widget_t make_new_file_dialog(bool managed) { if (!new_file_dialog) { Arg args[20]; int n; XmString xok, xcancel, xhelp; Widget name_label, form; XmString titlestr; Widget sep, reset_button; titlestr = XmStringCreateLocalized((char *)"New file"); xhelp = XmStringCreateLocalized((char *)I_HELP); xcancel = XmStringCreateLocalized((char *)I_GO_AWAY); xok = XmStringCreateLocalized((char *)"Ok"); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNresizePolicy, XmRESIZE_GROW); n++; XtSetArg(args[n], XmNcancelLabelString, xcancel); n++; XtSetArg(args[n], XmNhelpLabelString, xhelp); n++; XtSetArg(args[n], XmNokLabelString, xok); n++; XtSetArg(args[n], XmNdialogTitle, titlestr); n++; XtSetArg(args[n], XmNnoResize, false); n++; XtSetArg(args[n], XmNautoUnmanage, false); n++; new_file_dialog = XmCreateTemplateDialog(MAIN_SHELL(ss), (char *)"new", args, n); XmStringFree(titlestr); XmStringFree(xok); XmStringFree(xcancel); XmStringFree(xhelp); XtAddCallback(new_file_dialog, XmNhelpCallback, new_file_help_callback, NULL); XtAddCallback(new_file_dialog, XmNcancelCallback, new_file_cancel_callback, NULL); XtAddCallback(new_file_dialog, XmNokCallback, new_file_ok_callback, NULL); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNarmColor, ss->selection_color); n++; reset_button = XtCreateManagedWidget("Reset", xmPushButtonGadgetClass, new_file_dialog, args, n); XtAddCallback(reset_button, XmNactivateCallback, new_file_reset_callback, NULL); n = 0; form = XtCreateManagedWidget("newfile", xmFormWidgetClass, new_file_dialog, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNforeground, ss->black); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; name_label = XtCreateManagedWidget("New file:", xmLabelWidgetClass, form, args, n); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, name_label); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; new_file_text = make_textfield_widget("newtext", form, args, n, ACTIVATABLE, add_completer_func(filename_completer, NULL)); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, new_file_text); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNheight, 8); n++; XtSetArg(args[n], XmNseparatorType, XmNO_LINE); n++; sep = XtCreateManagedWidget("sep", xmSeparatorWidgetClass, form, args, n); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, sep); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; ndat = make_file_data_panel(form, "data-form", args, n, WITH_CHANNELS_FIELD, default_output_header_type(ss), default_output_sample_type(ss), WITHOUT_DATA_LOCATION_FIELD, WITH_SAMPLES_FIELD, WITH_HEADER_TYPE_FIELD, WITH_COMMENT_FIELD, WITH_BUILTIN_HEADERS, WITHOUT_SRATE, WITHOUT_AUTO_COMMENT); ndat->dialog = new_file_dialog; XtManageChild(ndat->error_text); XtManageChild(new_file_dialog); map_over_children(new_file_dialog, set_main_color_of_widget); XtVaSetValues(ndat->sample_type_list, XmNbackground, ss->white, XmNforeground, ss->black, NULL); XtVaSetValues(ndat->header_type_list, XmNbackground, ss->white, XmNforeground, ss->black, NULL); XtVaSetValues(MSG_BOX(new_file_dialog, XmDIALOG_OK_BUTTON), XmNarmColor, ss->selection_color, NULL); XtVaSetValues(MSG_BOX(new_file_dialog, XmDIALOG_CANCEL_BUTTON), XmNarmColor, ss->selection_color, NULL); XtVaSetValues(MSG_BOX(new_file_dialog, XmDIALOG_HELP_BUTTON), XmNarmColor, ss->selection_color, NULL); XtVaSetValues(MSG_BOX(new_file_dialog, XmDIALOG_OK_BUTTON), XmNbackground, ss->highlight_color, NULL); XtVaSetValues(MSG_BOX(new_file_dialog, XmDIALOG_CANCEL_BUTTON), XmNbackground, ss->highlight_color, NULL); XtVaSetValues(MSG_BOX(new_file_dialog, XmDIALOG_HELP_BUTTON), XmNbackground, ss->highlight_color, NULL); set_dialog_widget(NEW_FILE_DIALOG, new_file_dialog); XtUnmanageChild(ndat->error_text); load_new_file_defaults(NULL); } else { char *new_name; new_name = XmTextGetString(new_file_text); if (new_file_watcher) { /* if overwrite question pends, but file has been deleted in the meantime, go back to normal state */ if ((!new_name) || (!(*new_name)) || (!(mus_file_probe(new_name)))) new_file_undoit(); } if (strncmp(new_name, "new-", 4) == 0) { /* if file is open with currently posted new-file dialog name, and it's our name (new-%d), then tick the counter */ snd_info *sp; sp = find_sound(new_name, 0); if (sp) { char *filename; filename = new_file_dialog_filename(default_output_header_type(ss)); XmTextSetString(new_file_text, filename); mus_sound_forget(filename); free(filename); } } if (new_name) XtFree(new_name); } if ((managed) && (!(XtIsManaged(new_file_dialog)))) XtManageChild(new_file_dialog); return(new_file_dialog); } /* ---------------- Edit Header ---------------- */ typedef struct edhead_info { Widget dialog; file_data *edat; snd_info *sp; bool panel_changed; void *file_ro_watcher; int sp_ro_watcher_loc; } edhead_info; static int edhead_info_size = 0; static edhead_info **edhead_infos = NULL; static edhead_info *new_edhead_dialog(void) { int loc = -1; if (edhead_info_size == 0) { loc = 0; edhead_info_size = 4; edhead_infos = (edhead_info **)calloc(edhead_info_size, sizeof(edhead_info *)); } else { int i; for (i = 0; i < edhead_info_size; i++) if ((!edhead_infos[i]) || (!(XtIsManaged(edhead_infos[i]->dialog)))) { loc = i; break; } if (loc == -1) { loc = edhead_info_size; edhead_info_size += 4; edhead_infos = (edhead_info **)realloc(edhead_infos, edhead_info_size * sizeof(edhead_info *)); for (i = loc; i < edhead_info_size; i++) edhead_infos[i] = NULL; } } if (!edhead_infos[loc]) { edhead_infos[loc] = (edhead_info *)calloc(1, sizeof(edhead_info)); edhead_infos[loc]->dialog = NULL; edhead_infos[loc]->panel_changed = false; } edhead_infos[loc]->sp = NULL; edhead_infos[loc]->file_ro_watcher = NULL; return(edhead_infos[loc]); } static XmString make_header_dialog_title(edhead_info *ep, snd_info *sp) { /* dialog may not yet exist */ char *str; XmString xstr; str = (char *)calloc(PRINT_BUFFER_SIZE, sizeof(char)); if ((sp->user_read_only == FILE_READ_ONLY) || (sp->file_read_only == FILE_READ_ONLY)) { if (sp->hdr->type == MUS_RAW) snprintf(str, PRINT_BUFFER_SIZE, "Add header to (write-protected) %s", sp->short_filename); else snprintf(str, PRINT_BUFFER_SIZE, "Edit header of (write-protected) %s", sp->short_filename); if (ep->dialog) set_sensitive(MSG_BOX(ep->dialog, XmDIALOG_OK_BUTTON), (sp->hdr->type == MUS_RAW)); } else { if (sp->hdr->type == MUS_RAW) snprintf(str, PRINT_BUFFER_SIZE, "Add header to %s", sp->short_filename); else snprintf(str, PRINT_BUFFER_SIZE, "Edit header of %s", sp->short_filename); if (ep->dialog) set_sensitive(MSG_BOX(ep->dialog, XmDIALOG_OK_BUTTON), ep->panel_changed); } xstr = XmStringCreateLocalized(str); free(str); return(xstr); } static void edit_header_help_callback(Widget w, XtPointer context, XtPointer info) { edit_header_dialog_help(); } static void edit_header_set_ok_sensitive(Widget w, XtPointer context, XtPointer info) { edhead_info *ep = (edhead_info *)context; if (ep->sp->file_read_only == FILE_READ_WRITE) set_sensitive(MSG_BOX(ep->dialog, XmDIALOG_OK_BUTTON), true); ep->panel_changed = true; } static void eh_cancel(edhead_info *ep) { unreflect_file_data_panel_change(ep->edat, (void *)ep, edit_header_set_ok_sensitive); ep->panel_changed = false; if ((ep->file_ro_watcher) && (ep->sp) && (ep->sp->active) && (ep->sp->filename)) ep->file_ro_watcher = unmonitor_file(ep->file_ro_watcher); } static void edit_header_cancel_callback(Widget w, XtPointer context, XtPointer info) { edhead_info *ep = (edhead_info *)context; XtUnmanageChild(ep->dialog); eh_cancel(ep); } static void edit_header_wm_delete_callback(Widget w, XtPointer context, XtPointer info) { eh_cancel((edhead_info *)context); } static void edit_header_ok_callback(Widget w, XtPointer context, XtPointer info) { edhead_info *ep = (edhead_info *)context; if ((ep->sp) && (ep->sp->active)) { if (XmGetFocusWidget(ep->dialog) == MSG_BOX(ep->dialog, XmDIALOG_OK_BUTTON)) { bool ok; redirect_snd_error_to(redirect_post_file_dialog_error, (void *)(ep->edat)); ok = edit_header_callback(ep->sp, ep->edat, redirect_post_file_dialog_error, post_file_panel_error); /* edit_header_callback, if all goes well, writes the header, recopies the data, * then calls snd_update which closes the sound and reopens it, to force the * new_header to take effect. The read-only watcher is disabled during that * process to keep it from getting a SOUND_IS_CLOSING message from close. */ redirect_snd_error_to(NULL, NULL); if (ep->edat->error_widget != NOT_A_SCANF_WIDGET) { clear_error_if_panel_changes(ep->dialog, ep->edat); return; } else { if (!ok) { set_sensitive(MSG_BOX(ep->dialog, XmDIALOG_OK_BUTTON), false); return; } } ep->file_ro_watcher = unmonitor_file(ep->file_ro_watcher); XtUnmanageChild(ep->dialog); unreflect_file_data_panel_change(ep->edat, (void *)ep, edit_header_set_ok_sensitive); } } } Widget edit_header(snd_info *sp) { file_info *hdr; XmString xstr4; Widget main_w; edhead_info *ep = NULL; if (!sp) return(NULL); /* look for a dialog already editing this sound, raise if found, else make a new one */ if (edhead_info_size > 0) { int i; for (i = 0; i < edhead_info_size; i++) if ((edhead_infos[i]) && ((edhead_infos[i]->sp == sp) || ((edhead_infos[i]->sp) && /* maybe same sound open twice -- only one edit header dialog for it */ (edhead_infos[i]->sp->inuse == SOUND_NORMAL) && (mus_strcmp(sp->filename, edhead_infos[i]->sp->filename))))) { ep = edhead_infos[i]; break; } } if (!ep) ep = new_edhead_dialog(); ep->sp = sp; hdr = sp->hdr; ep->panel_changed = (hdr->type == MUS_RAW); xstr4 = make_header_dialog_title(ep, sp); if (!ep->dialog) { int n; Arg args[20]; XmString xstr1, xstr2, xstr3, titlestr; n = 0; xstr1 = XmStringCreateLocalized((char *)I_GO_AWAY); /* needed by template dialog */ xstr2 = XmStringCreateLocalized((char *)I_HELP); xstr3 = XmStringCreateLocalized((char *)"Save"); titlestr = XmStringCreateLocalized((char *)"Edit Header"); XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNcancelLabelString, xstr1); n++; XtSetArg(args[n], XmNhelpLabelString, xstr2); n++; XtSetArg(args[n], XmNokLabelString, xstr3); n++; XtSetArg(args[n], XmNmessageString, xstr4); n++; XtSetArg(args[n], XmNdialogTitle, titlestr); n++; XtSetArg(args[n], XmNautoUnmanage, false); n++; XtSetArg(args[n], XmNresizePolicy, XmRESIZE_GROW); n++; XtSetArg(args[n], XmNnoResize, false); n++; XtSetArg(args[n], XmNtransient, false); n++; ep->dialog = XmCreateTemplateDialog(MAIN_SHELL(ss), (char *)"Edit Header", args, n); XtAddCallback(ep->dialog, XmNcancelCallback, edit_header_cancel_callback, (XtPointer)ep); XtAddCallback(ep->dialog, XmNhelpCallback, edit_header_help_callback, (XtPointer)ep); XtAddCallback(ep->dialog, XmNokCallback, edit_header_ok_callback, (XtPointer)ep); XmStringFree(xstr1); XmStringFree(xstr2); XmStringFree(xstr3); XmStringFree(titlestr); n = 0; main_w = XtCreateManagedWidget("eh-main", xmFormWidgetClass, ep->dialog, args, n); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; ep->edat = make_file_data_panel(main_w, "Edit Header", args, n, WITH_CHANNELS_FIELD, hdr->type, hdr->sample_type, WITH_DATA_LOCATION_FIELD, WITH_SAMPLES_FIELD, WITH_HEADER_TYPE_FIELD, WITH_COMMENT_FIELD, WITH_BUILTIN_HEADERS, WITHOUT_SRATE, WITHOUT_AUTO_COMMENT); ep->edat->dialog = ep->dialog; if (hdr->type == MUS_RAW) set_file_dialog_sound_attributes(ep->edat, default_output_header_type(ss), hdr->sample_type, hdr->srate, hdr->chans, hdr->data_location, hdr->samples, hdr->comment); else set_file_dialog_sound_attributes(ep->edat, hdr->type, hdr->sample_type, hdr->srate, hdr->chans, hdr->data_location, hdr->samples, hdr->comment); XtManageChild(ep->edat->error_text); XtManageChild(ep->dialog); map_over_children(ep->dialog, set_main_color_of_widget); XtVaSetValues(MSG_BOX(ep->dialog, XmDIALOG_OK_BUTTON), XmNarmColor, ss->selection_color, NULL); XtVaSetValues(MSG_BOX(ep->dialog, XmDIALOG_CANCEL_BUTTON), XmNarmColor, ss->selection_color, NULL); XtVaSetValues(MSG_BOX(ep->dialog, XmDIALOG_HELP_BUTTON), XmNarmColor, ss->selection_color, NULL); XtVaSetValues(MSG_BOX(ep->dialog, XmDIALOG_OK_BUTTON), XmNbackground, ss->highlight_color, NULL); XtVaSetValues(MSG_BOX(ep->dialog, XmDIALOG_CANCEL_BUTTON), XmNbackground, ss->highlight_color, NULL); XtVaSetValues(MSG_BOX(ep->dialog, XmDIALOG_HELP_BUTTON), XmNbackground, ss->highlight_color, NULL); XtVaSetValues(ep->edat->header_type_list, XmNbackground, ss->white, XmNforeground, ss->black, NULL); XtVaSetValues(ep->edat->sample_type_list, XmNbackground, ss->white, XmNforeground, ss->black, NULL); XtVaSetValues(MSG_BOX(ep->dialog, XmDIALOG_MESSAGE_LABEL), XmNbackground, ss->basic_color, NULL); set_dialog_widget(EDIT_HEADER_DIALOG, ep->dialog); { Atom wm_delete_window; wm_delete_window = XmInternAtom(MAIN_DISPLAY(ss), (char *)"WM_DELETE_WINDOW", false); XmAddWMProtocolCallback(XtParent(ep->dialog), wm_delete_window, edit_header_wm_delete_callback, (XtPointer)ep); } XtUnmanageChild(ep->edat->error_text); } else { XtVaSetValues(ep->dialog, XmNmessageString, xstr4, NULL); if (hdr->type == MUS_RAW) set_file_dialog_sound_attributes(ep->edat, default_output_header_type(ss), hdr->sample_type, hdr->srate, hdr->chans, hdr->data_location, hdr->samples, hdr->comment); else set_file_dialog_sound_attributes(ep->edat, hdr->type, hdr->sample_type, hdr->srate, hdr->chans, hdr->data_location, hdr->samples, hdr->comment); raise_dialog(ep->dialog); clear_dialog_error(ep->edat); } set_sensitive(MSG_BOX(ep->dialog, XmDIALOG_OK_BUTTON), (hdr->type == MUS_RAW)); /* nothing needs to be saved when we start */ XmStringFree(xstr4); if (!(XtIsManaged(ep->dialog))) XtManageChild(ep->dialog); reflect_file_data_panel_change(ep->edat, (void *)ep, edit_header_set_ok_sensitive); return(ep->dialog); } void save_edit_header_dialog_state(FILE *fd) { int i; for (i = 0; i < edhead_info_size; i++) if (edhead_infos[i]) { edhead_info *ep; ep = edhead_infos[i]; if ((ep->dialog) && (XtIsManaged(ep->dialog)) && (snd_ok(ep->sp))) { #if HAVE_SCHEME fprintf(fd, "(%s (%s \"%s\"))\n", S_edit_header_dialog, S_find_sound, ep->sp->short_filename); #endif #if HAVE_RUBY fprintf(fd, "%s(%s(\"%s\"))\n", to_proc_name(S_edit_header_dialog), to_proc_name(S_find_sound), ep->sp->short_filename); #endif #if HAVE_FORTH fprintf(fd, "\"%s\" %s %s drop\n", ep->sp->short_filename, S_find_sound, S_edit_header_dialog); #endif break; } } } typedef enum {VF_AT_CURSOR, VF_AT_END, VF_AT_BEGINNING, VF_AT_MARK, VF_AT_SAMPLE} vf_location_t; typedef struct { widget_t rw; widget_t nm; #if WITH_AUDIO widget_t pl; #endif int pos; void *vdat; } vf_row; typedef struct { vf_row **file_list_entries; int index, size; char **names; char **full_names; int end; int sorter; int *selected_files; int selected_files_size; int currently_selected_files; mus_float_t amp; vf_location_t location_choice; mus_float_t speed; graphics_context *env_ax; env_editor *spf; env *amp_env; bool has_error; int sort_items_size; speed_style_t speed_style; mus_long_t beg; int dirs_size; void *dirs; char **dir_names; bool need_update; widget_t dialog; widget_t file_list; widget_t file_list_holder; widget_t left_title; widget_t info1; widget_t info2; widget_t mixB; widget_t insertB; widget_t at_cursor_button; widget_t at_end_button; widget_t at_beginning_button; widget_t at_mark_button; widget_t at_sample_button; widget_t at_sample_text; widget_t at_mark_text; widget_t amp_number; widget_t amp_scrollbar; widget_t speed_number; widget_t speed_scrollbar; widget_t env_drawer; widget_t a_to_z; widget_t z_to_a; widget_t new_to_old; widget_t old_to_new; widget_t small_to_big; widget_t big_to_small; widget_t smenu; widget_t current_play_button; widget_t amp_event; widget_t speed_event; widget_t speed_label_event; widget_t add_text; widget_t* sort_items; GC env_gc; } view_files_info; static void vf_unhighlight_row(widget_t nm, widget_t rw); static void vf_highlight_row(widget_t nm, widget_t rw); static void vf_post_info(view_files_info *vdat, int pos); static void vf_unpost_info(view_files_info *vdat); static mus_long_t vf_location(view_files_info *vdat); static void vf_post_error(const char *error_msg, view_files_info *data); static void redirect_vf_post_error(const char *error_msg, void *data); static void redirect_vf_post_location_error(const char *error_msg, void *data); static void vf_post_add_error(const char *error_msg, view_files_info *data); static widget_t make_view_files_dialog_1(view_files_info *vdat, bool managed); static void vf_post_selected_files_list(view_files_info *vdat); static void view_files_add_file_or_directory(view_files_info *vdat, const char *file_or_dir); static void vf_reflect_sort_choice_in_menu(view_files_info *vdat); static vf_row *view_files_make_row(view_files_info *vdat, widget_t last_row); static void vf_flash_row(vf_row *r); static void vf_set_amp(view_files_info *vdat, mus_float_t val); static void vf_set_speed(view_files_info *vdat, mus_float_t val); static void vf_set_amp_env(view_files_info *vdat, env *new_e); static void vf_clear_error(view_files_info *vdat); static void vf_mix_insert_buttons_set_sensitive(view_files_info *vdat, bool sensitive); static int vf_mix(view_files_info *vdat); static bool vf_insert(view_files_info *vdat); static void view_files_display_list(view_files_info *vdat); static void view_files_unmonitor_directories(view_files_info *vdat) {} static void view_files_monitor_directory(view_files_info *vdat, const char *dirname) {} /* -------------------------------- Raw Data Dialog -------------------------------- */ /* we keep an array of raw data dialogs so that any number can be active at once */ typedef struct raw_info { Widget dialog; mus_long_t location; file_data *rdat; read_only_t read_only; bool selected; char *filename; char *help; open_requestor_t requestor; void *requestor_data; Widget requestor_dialog; } raw_info; static int raw_info_size = 0; static raw_info **raw_infos = NULL; static raw_info *new_raw_dialog(void) { int loc = -1; if (raw_info_size == 0) { loc = 0; raw_info_size = 4; raw_infos = (raw_info **)calloc(raw_info_size, sizeof(raw_info *)); } else { int i; for (i = 0; i < raw_info_size; i++) if ((!raw_infos[i]) || (!(XtIsManaged(raw_infos[i]->dialog)))) { loc = i; break; } if (loc == -1) { loc = raw_info_size; raw_info_size += 4; raw_infos = (raw_info **)realloc(raw_infos, raw_info_size * sizeof(raw_info *)); for (i = loc; i < raw_info_size; i++) raw_infos[i] = NULL; } } if (!raw_infos[loc]) { raw_infos[loc] = (raw_info *)calloc(1, sizeof(raw_info)); raw_infos[loc]->dialog = NULL; raw_infos[loc]->filename = NULL; raw_infos[loc]->help = NULL; } raw_infos[loc]->requestor = NO_REQUESTOR; raw_infos[loc]->requestor_data = NULL; raw_infos[loc]->location = 0; return(raw_infos[loc]); } static void raw_data_ok_callback(Widget w, XtPointer context, XtPointer info) { raw_info *rp = (raw_info *)context; int raw_srate = 0, raw_chans = 0; mus_sample_t raw_sample_type = MUS_UNKNOWN_SAMPLE; redirect_snd_error_to(post_file_panel_error, (void *)(rp->rdat)); get_file_dialog_sound_attributes(rp->rdat, &raw_srate, &raw_chans, NULL, &raw_sample_type, &(rp->location), NULL, 1); redirect_snd_error_to(NULL, NULL); if (rp->rdat->error_widget != NOT_A_SCANF_WIDGET) { clear_error_if_panel_changes(rp->dialog, rp->rdat); } else { mus_header_set_raw_defaults(raw_srate, raw_chans, raw_sample_type); mus_sound_override_header(rp->filename, raw_srate, raw_chans, raw_sample_type, MUS_RAW, rp->location, mus_bytes_to_samples(raw_sample_type, mus_sound_length(rp->filename) - rp->location)); /* choose action based on how we got here */ if ((rp->requestor_dialog) && ((rp->requestor == FROM_MIX_DIALOG) || (rp->requestor == FROM_INSERT_DIALOG) || (rp->requestor == FROM_VIEW_FILES_MIX_DIALOG) || (rp->requestor == FROM_VIEW_FILES_INSERT_DIALOG))) { ss->reloading_updated_file = true; /* don't reread lack-of-header! */ /* redirection may be still set here, but I'll make it obvious */ switch (rp->requestor) { case FROM_MIX_DIALOG: redirect_snd_error_to(redirect_file_open_error, (void *)mdat); mix_complete_file_at_cursor(any_selected_sound(), rp->filename); break; case FROM_INSERT_DIALOG: redirect_snd_error_to(redirect_file_open_error, (void *)idat); insert_complete_file_at_cursor(any_selected_sound(), rp->filename); break; case FROM_VIEW_FILES_MIX_DIALOG: { view_files_info *vdat = (view_files_info *)(rp->requestor_data); redirect_snd_error_to(redirect_vf_post_error, rp->requestor_data); vf_mix(vdat); } break; case FROM_VIEW_FILES_INSERT_DIALOG: { view_files_info *vdat = (view_files_info *)(rp->requestor_data); redirect_snd_error_to(redirect_vf_post_error, rp->requestor_data); vf_insert(vdat); } break; default: snd_error("wrong requestor type in raw data dialog? %d\n", (int)(rp->requestor)); break; } redirect_snd_error_to(NULL, NULL); ss->reloading_updated_file = false; } else { /* FROM_OPEN_DIALOG (has requestor_dialog) * FROM_KEYBOARD (has sp = requestor_data) * FROM_DRAG_AND_DROP (just open, no needed side effects) * FROM_VIEW_FILES (ditto) * FROM_VIEW_FILES_MIX_DIALOG or INSERT -- requestor_data contains needed info to complete the action */ file_info *hdr; hdr = (file_info *)calloc(1, sizeof(file_info)); hdr->name = mus_strdup(rp->filename); hdr->type = MUS_RAW; hdr->srate = raw_srate; hdr->chans = raw_chans; hdr->sample_type = raw_sample_type; hdr->samples = mus_bytes_to_samples(raw_sample_type, mus_sound_length(rp->filename) - rp->location); hdr->data_location = rp->location; hdr->comment = NULL; if (rp->requestor == FROM_KEYBOARD) { clear_status_area((snd_info *)(rp->requestor_data)); rp->selected = true; } finish_opening_sound(add_sound_window(rp->filename, rp->read_only, hdr), rp->selected); } XtUnmanageChild(rp->dialog); } } static void raw_data_cancel_callback(Widget w, XtPointer context, XtPointer info) { raw_info *rp = (raw_info *)context; XtUnmanageChild(rp->dialog); if ((rp->requestor_dialog) && ((rp->requestor == FROM_OPEN_DIALOG) || (rp->requestor == FROM_MIX_DIALOG))) XtManageChild(rp->requestor_dialog); } static void raw_data_reset_callback(Widget w, XtPointer context, XtPointer info) { raw_info *rp = (raw_info *)context; int raw_srate, raw_chans; mus_sample_t raw_sample_type; rp->location = 0; mus_header_raw_defaults(&raw_srate, &raw_chans, &raw_sample_type); /* pick up defaults */ set_file_dialog_sound_attributes(rp->rdat, IGNORE_HEADER_TYPE, raw_sample_type, raw_srate, raw_chans, rp->location, IGNORE_SAMPLES, NULL); if (XtIsManaged(rp->rdat->error_text)) XtUnmanageChild(rp->rdat->error_text); } static void raw_data_help_callback(Widget w, XtPointer context, XtPointer info) { raw_info *rp = (raw_info *)context; raw_data_dialog_help(rp->help); } static void make_raw_data_dialog(raw_info *rp, const char *title) { XmString go_away, xhelp, xok, xtitle, titlestr; int n; int raw_srate, raw_chans; mus_sample_t raw_sample_type; Arg args[20]; Widget reset_button, main_w; go_away = XmStringCreateLocalized((char *)I_GO_AWAY); /* needed by template dialog */ xhelp = XmStringCreateLocalized((char *)I_HELP); xok = XmStringCreateLocalized((char *)"Ok"); if (!title) titlestr = XmStringCreateLocalized((char *)"No header on file"); else titlestr = XmStringCreateLocalized((char *)title); xtitle = XmStringCreateLocalized((char *)title); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNcancelLabelString, go_away); n++; XtSetArg(args[n], XmNhelpLabelString, xhelp); n++; XtSetArg(args[n], XmNokLabelString, xok); n++; XtSetArg(args[n], XmNmessageString, xtitle); n++; XtSetArg(args[n], XmNdialogTitle, titlestr); n++; XtSetArg(args[n], XmNresizePolicy, XmRESIZE_GROW); n++; XtSetArg(args[n], XmNallowShellResize, true); n++; XtSetArg(args[n], XmNnoResize, false); n++; XtSetArg(args[n], XmNautoUnmanage, false); n++; /* not transient -- we want this window to remain visible if possible */ rp->dialog = XmCreateWarningDialog(MAIN_SHELL(ss), (char *)"raw data", args, n); XtAddCallback(rp->dialog, XmNcancelCallback, raw_data_cancel_callback, (XtPointer)rp); XtAddCallback(rp->dialog, XmNhelpCallback, raw_data_help_callback, (XtPointer)rp); XtAddCallback(rp->dialog, XmNokCallback, raw_data_ok_callback, (XtPointer)rp); XmStringFree(go_away); XmStringFree(xhelp); XmStringFree(xok); XmStringFree(xtitle); XmStringFree(titlestr); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNarmColor, ss->selection_color); n++; reset_button = XtCreateManagedWidget("Reset", xmPushButtonGadgetClass, rp->dialog, args, n); XtAddCallback(reset_button, XmNactivateCallback, raw_data_reset_callback, (XtPointer)rp); mus_header_raw_defaults(&raw_srate, &raw_chans, &raw_sample_type); /* pick up defaults */ n = 0; XtSetArg(args[n], XmNallowResize, true); n++; XtSetArg(args[n], XmNresizePolicy, XmRESIZE_NONE); n++; main_w = XtCreateManagedWidget("raw-main", xmFormWidgetClass, rp->dialog, args, n); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; rp->rdat = make_file_data_panel(main_w, "data-form", args, n, WITH_CHANNELS_FIELD, MUS_RAW, raw_sample_type, WITH_DATA_LOCATION_FIELD, WITHOUT_SAMPLES_FIELD, WITHOUT_HEADER_TYPE_FIELD, WITHOUT_COMMENT_FIELD, WITH_READABLE_HEADERS, WITHOUT_SRATE, WITHOUT_AUTO_COMMENT); rp->rdat->dialog = rp->dialog; set_file_dialog_sound_attributes(rp->rdat, IGNORE_HEADER_TYPE, raw_sample_type, raw_srate, raw_chans, rp->location, IGNORE_SAMPLES, NULL); map_over_children(rp->dialog, set_main_color_of_widget); XtVaSetValues(MSG_BOX(rp->dialog, XmDIALOG_OK_BUTTON), XmNarmColor, ss->selection_color, NULL); XtVaSetValues(MSG_BOX(rp->dialog, XmDIALOG_CANCEL_BUTTON), XmNarmColor, ss->selection_color, NULL); XtVaSetValues(MSG_BOX(rp->dialog, XmDIALOG_HELP_BUTTON), XmNarmColor, ss->selection_color, NULL); XtVaSetValues(MSG_BOX(rp->dialog, XmDIALOG_OK_BUTTON), XmNbackground, ss->highlight_color, NULL); XtVaSetValues(MSG_BOX(rp->dialog, XmDIALOG_CANCEL_BUTTON), XmNbackground, ss->highlight_color, NULL); XtVaSetValues(MSG_BOX(rp->dialog, XmDIALOG_HELP_BUTTON), XmNbackground, ss->highlight_color, NULL); XtVaSetValues(reset_button, XmNselectColor, ss->selection_color, NULL); XtVaSetValues(rp->rdat->sample_type_list, XmNbackground, ss->white, XmNforeground, ss->black, NULL); /* * this line makes the dialog take up all vertical space on the screen * XtManageChild(rp->rdat->error_text); */ XtVaSetValues(MSG_BOX(rp->dialog, XmDIALOG_MESSAGE_LABEL), XmNbackground, ss->basic_color, NULL); XtManageChild(rp->dialog); XtUnmanageChild(rp->rdat->error_text); set_dialog_widget(RAW_DATA_DIALOG, rp->dialog); } void raw_data_dialog_to_file_info(const char *filename, char *title, char *info, read_only_t read_only, bool selected) { /* put up dialog for srate, chans, sample type */ raw_info *rp; rp = new_raw_dialog(); rp->read_only = read_only; rp->selected = selected; if (rp->filename) free(rp->filename); rp->filename = mus_strdup(filename); rp->requestor = ss->open_requestor; rp->requestor_data = ss->open_requestor_data; rp->requestor_dialog = ss->requestor_dialog; ss->open_requestor = NO_REQUESTOR; ss->requestor_dialog = NULL; ss->open_requestor_data = NULL; if ((rp->requestor_dialog) && ((rp->requestor == FROM_OPEN_DIALOG) || (rp->requestor == FROM_MIX_DIALOG))) XtUnmanageChild(rp->requestor_dialog); if (!title) title = mus_format("no header found on %s\n", filename); if (!(rp->dialog)) make_raw_data_dialog(rp, title); else { XmString xstr4; xstr4 = XmStringCreateLocalized(title); XtVaSetValues(rp->dialog, XmNmessageString, xstr4, NULL); XmStringFree(xstr4); } free(title); if (rp->help) free(rp->help); if (info) { XtVaSetValues(MSG_BOX(rp->dialog, XmDIALOG_HELP_BUTTON), XmNbackground, ss->green, NULL); rp->help = mus_strdup(info); free(info); } else { XtVaSetValues(MSG_BOX(rp->dialog, XmDIALOG_HELP_BUTTON), XmNbackground, ss->highlight_color, NULL); rp->help = NULL; } raise_dialog(rp->dialog); if (!XtIsManaged(rp->dialog)) XtManageChild(rp->dialog); } /* ---------------- INFO MONOLOG ---------------- */ #define POST_IT_ROWS 12 #define POST_IT_COLUMNS 56 static Widget post_it_dialog = NULL; static Widget post_it_text = NULL; static void create_post_it_monolog(void) { /* create scrollable but not editable text window; used for fft peaks, sp info, and raw data help displays */ Arg args[20]; int n; n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNresizePolicy, XmRESIZE_GROW); n++; XtSetArg(args[n], XmNnoResize, false); n++; XtSetArg(args[n], XmNtransient, false); n++; post_it_dialog = XmCreateMessageDialog(MAIN_PANE(ss), (char *)"info", args, n); XtUnmanageChild(MSG_BOX(post_it_dialog, XmDIALOG_CANCEL_BUTTON)); XtUnmanageChild(MSG_BOX(post_it_dialog, XmDIALOG_HELP_BUTTON)); XtUnmanageChild(MSG_BOX(post_it_dialog, XmDIALOG_SYMBOL_LABEL)); XtVaSetValues(MSG_BOX(post_it_dialog, XmDIALOG_MESSAGE_LABEL), XmNbackground, ss->highlight_color, NULL); n = 0; XtSetArg(args[n], XmNeditMode, XmMULTI_LINE_EDIT); n++; XtSetArg(args[n], XmNeditable, false); n++; XtSetArg(args[n], XmNcolumns, POST_IT_COLUMNS); n++; XtSetArg(args[n], XmNrows, POST_IT_ROWS); n++; XtSetArg(args[n], XmNforeground, ss->black); n++; /* needed if color allocation fails completely */ XtSetArg(args[n], XmNbackground, ss->white); n++; post_it_text = XmCreateScrolledText(post_it_dialog, (char *)"post-it-text", args, n); XtManageChild(post_it_text); XtManageChild(post_it_dialog); map_over_children(post_it_dialog, set_main_color_of_widget); XtVaSetValues(post_it_text, XmNbackground, ss->white, XmNforeground, ss->black, NULL); XtVaSetValues(MSG_BOX(post_it_dialog, XmDIALOG_OK_BUTTON), XmNarmColor, ss->selection_color, NULL); XtVaSetValues(MSG_BOX(post_it_dialog, XmDIALOG_OK_BUTTON), XmNbackground, ss->highlight_color, NULL); set_dialog_widget(POST_IT_DIALOG, post_it_dialog); } widget_t post_it(const char *subject, const char *str) { /* place string in scrollable help window */ XmString xstr1, xstr2; if (ss == NULL) return(NULL); /* an attempt to call this before X/Motif is ready */ if (!(post_it_dialog)) create_post_it_monolog(); else raise_dialog(post_it_dialog); xstr1 = XmStringCreateLocalized((char *)subject); xstr2 = XmStringCreateLocalized((char *)subject); XtVaSetValues(post_it_dialog, XmNmessageString, xstr1, XmNdialogTitle, xstr2, NULL); XmTextSetString(post_it_text, (char *)str); if (!XtIsManaged(post_it_dialog)) XtManageChild(post_it_dialog); XmStringFree(xstr1); XmStringFree(xstr2); return(post_it_dialog); } void post_it_append(const char *str) { if (post_it_dialog) XmTextInsert(post_it_text, XmTextGetLastPosition(post_it_text), (char *)str); } void save_post_it_dialog_state(FILE *fd) { if ((post_it_dialog) && (XtIsManaged(post_it_dialog))) { char *subject = NULL, *text = NULL; subject = dialog_get_title(post_it_dialog); text = XmTextGetString(post_it_text); #if HAVE_SCHEME fprintf(fd, "(%s \"%s\" \"%s\")\n", S_info_dialog, subject, text); #endif #if HAVE_RUBY fprintf(fd, "%s(\"%s\", \"%s\")\n", to_proc_name(S_info_dialog), subject, text); #endif #if HAVE_FORTH fprintf(fd, "\"%s\" \"%s\" %s drop\n", subject, text, S_info_dialog); #endif if (subject) free(subject); if (text) XtFree(text); } } /* ---------------- unsaved edits dialog ---------------- */ static int num_unsaved_edits_dialogs = 0; static Widget *unsaved_edits_dialogs = NULL; static snd_info **unsaved_edits_sounds = NULL; static Widget unsaved_edits_dialog(snd_info *sp) { int i; /* are there any such dialogs? */ if (num_unsaved_edits_dialogs == 0) return(NULL); /* now see if we've already prompted about this sound */ for (i = 0; i < num_unsaved_edits_dialogs; i++) if (unsaved_edits_sounds[i] == sp) return(unsaved_edits_dialogs[i]); /* try to find a free unmanaged dialog */ for (i = 0; i < num_unsaved_edits_dialogs; i++) if ((unsaved_edits_dialogs[i]) && (!XtIsManaged(unsaved_edits_dialogs[i]))) return(unsaved_edits_dialogs[i]); return(NULL); } static void save_unsaved_edits_dialog(Widget d, snd_info *sp) { if (num_unsaved_edits_dialogs == 0) { unsaved_edits_dialogs = (Widget *)calloc(1, sizeof(Widget)); unsaved_edits_sounds = (snd_info **)calloc(1, sizeof(snd_info *)); } else { unsaved_edits_dialogs = (Widget *)realloc(unsaved_edits_dialogs, (num_unsaved_edits_dialogs + 1) * sizeof(Widget)); unsaved_edits_sounds = (snd_info **)realloc(unsaved_edits_sounds, (num_unsaved_edits_dialogs + 1) * sizeof(snd_info *)); } unsaved_edits_dialogs[num_unsaved_edits_dialogs] = d; unsaved_edits_sounds[num_unsaved_edits_dialogs] = sp; num_unsaved_edits_dialogs++; } void unpost_unsaved_edits_if_any(snd_info *sp) { int i; for (i = 0; i < num_unsaved_edits_dialogs; i++) if (((unsaved_edits_sounds[i] == sp) || (!snd_ok(unsaved_edits_sounds[i]))) && (XtIsManaged(unsaved_edits_dialogs[i]))) XtUnmanageChild(unsaved_edits_dialogs[i]); } static void zero_edits(chan_info *cp) { cp->edit_ctr = 0; } static void unsaved_edits_no_callback(Widget w, XtPointer context, XtPointer info) { snd_info *sp = (snd_info *)context; for_each_sound_chan(sp, zero_edits); snd_close_file(sp); } static void unsaved_edits_yes_callback(Widget w, XtPointer context, XtPointer info) { snd_info *sp = (snd_info *)context; save_edits(sp); snd_close_file(sp); } static void unsaved_edits_help_callback(Widget w, XtPointer context, XtPointer info) { snd_help("save edits?", "You have set " S_ask_about_unsaved_edits " to " PROC_TRUE ", so you will be asked whether you want \ to save edits if you try to close a sound that has unsaved edits.", WITH_WORD_WRAP); } void save_edits_now(snd_info *sp) { char *question; XmString q; Widget dialog; question = mus_format("%s has unsaved edits. Save them?", sp->short_filename); q = XmStringCreateLocalized(question); dialog = unsaved_edits_dialog(sp); if (!dialog) { Arg args[20]; int n; XmString yes, no; yes = XmStringCreateLocalized((char *)"yes"); no = XmStringCreateLocalized((char *)"no"); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNokLabelString, yes); n++; XtSetArg(args[n], XmNcancelLabelString, no); n++; XtSetArg(args[n], XmNmessageString, q); n++; dialog = XmCreateQuestionDialog(MAIN_PANE(ss), sp->filename, args, n); save_unsaved_edits_dialog(dialog, sp); XtAddCallback(dialog, XmNhelpCallback, unsaved_edits_help_callback, (XtPointer)sp); XtAddCallback(dialog, XmNokCallback, unsaved_edits_yes_callback, (XtPointer)sp); XtAddCallback(dialog, XmNcancelCallback, unsaved_edits_no_callback, (XtPointer)sp); XmStringFree(yes); XmStringFree(no); map_over_children(dialog, set_main_color_of_widget); XtVaSetValues(MSG_BOX(dialog, XmDIALOG_OK_BUTTON), XmNarmColor, ss->selection_color, NULL); XtVaSetValues(MSG_BOX(dialog, XmDIALOG_OK_BUTTON), XmNbackground, ss->highlight_color, NULL); XtVaSetValues(MSG_BOX(dialog, XmDIALOG_CANCEL_BUTTON), XmNarmColor, ss->selection_color, NULL); XtVaSetValues(MSG_BOX(dialog, XmDIALOG_CANCEL_BUTTON), XmNbackground, ss->highlight_color, NULL); XtVaSetValues(MSG_BOX(dialog, XmDIALOG_HELP_BUTTON), XmNarmColor, ss->selection_color, NULL); XtVaSetValues(MSG_BOX(dialog, XmDIALOG_HELP_BUTTON), XmNbackground, ss->highlight_color, NULL); } else { XtVaSetValues(dialog, XmNmessageString, q, NULL); } XmStringFree(q); free(question); XtManageChild(dialog); } /* ---------------- file has changed dialog ---------------- */ static int num_file_has_changed_dialogs = 0; static Widget *file_has_changed_dialogs = NULL; static snd_info **file_has_changed_sounds = NULL; static Widget file_has_changed_dialog(snd_info *sp) { int i; /* are there any such dialogs? */ if (num_file_has_changed_dialogs == 0) return(NULL); /* now see if we've already prompted about this sound */ for (i = 0; i < num_file_has_changed_dialogs; i++) if (file_has_changed_sounds[i] == sp) return(file_has_changed_dialogs[i]); /* try to find a free unmanaged dialog */ for (i = 0; i < num_file_has_changed_dialogs; i++) if ((file_has_changed_dialogs[i]) && (!XtIsManaged(file_has_changed_dialogs[i]))) return(file_has_changed_dialogs[i]); return(NULL); } static void save_file_has_changed_dialog(Widget d, snd_info *sp) { if (num_file_has_changed_dialogs == 0) { file_has_changed_dialogs = (Widget *)calloc(1, sizeof(Widget)); file_has_changed_sounds = (snd_info **)calloc(1, sizeof(snd_info *)); } else { file_has_changed_dialogs = (Widget *)realloc(file_has_changed_dialogs, (num_file_has_changed_dialogs + 1) * sizeof(Widget)); file_has_changed_sounds = (snd_info **)realloc(file_has_changed_sounds, (num_file_has_changed_dialogs + 1) * sizeof(snd_info *)); } file_has_changed_dialogs[num_file_has_changed_dialogs] = d; file_has_changed_sounds[num_file_has_changed_dialogs] = sp; num_file_has_changed_dialogs++; } void unpost_file_has_changed_if_any(snd_info *sp) { int i; for (i = 0; i < num_file_has_changed_dialogs; i++) if (((file_has_changed_sounds[i] == sp) || (!snd_ok(file_has_changed_sounds[i]))) && (XtIsManaged(file_has_changed_dialogs[i]))) XtUnmanageChild(file_has_changed_dialogs[i]); } static void file_has_changed_no_callback(Widget w, XtPointer context, XtPointer info) { } static void file_has_changed_yes_callback(Widget w, XtPointer context, XtPointer info) { snd_info *sp = (snd_info *)context; save_edits_without_asking(sp); sp->need_update = false; stop_bomb(sp); /* in case Snd already noticed the problem */ clear_status_area(sp); } static void file_has_changed_help_callback(Widget w, XtPointer context, XtPointer info) { snd_help("save edits?", "The file has changed unexpectedly, so in most cases, saving the current edits can't do anything useful. But you can try anyway!", WITH_WORD_WRAP); } void changed_file_dialog(snd_info *sp) { char *question; XmString q; Widget dialog; question = mus_format("%s has changed! Save edits anyway?", sp->short_filename); q = XmStringCreateLocalized(question); dialog = file_has_changed_dialog(sp); if (!dialog) { Arg args[20]; int n; XmString yes, no; yes = XmStringCreateLocalized((char *)"yes"); no = XmStringCreateLocalized((char *)"no"); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNokLabelString, yes); n++; XtSetArg(args[n], XmNcancelLabelString, no); n++; XtSetArg(args[n], XmNmessageString, q); n++; dialog = XmCreateQuestionDialog(MAIN_PANE(ss), sp->filename, args, n); save_file_has_changed_dialog(dialog, sp); XtAddCallback(dialog, XmNhelpCallback, file_has_changed_help_callback, (XtPointer)sp); XtAddCallback(dialog, XmNokCallback, file_has_changed_yes_callback, (XtPointer)sp); XtAddCallback(dialog, XmNcancelCallback, file_has_changed_no_callback, (XtPointer)sp); XmStringFree(yes); XmStringFree(no); map_over_children(dialog, set_main_color_of_widget); XtVaSetValues(MSG_BOX(dialog, XmDIALOG_OK_BUTTON), XmNarmColor, ss->selection_color, NULL); XtVaSetValues(MSG_BOX(dialog, XmDIALOG_OK_BUTTON), XmNbackground, ss->highlight_color, NULL); XtVaSetValues(MSG_BOX(dialog, XmDIALOG_CANCEL_BUTTON), XmNarmColor, ss->selection_color, NULL); XtVaSetValues(MSG_BOX(dialog, XmDIALOG_CANCEL_BUTTON), XmNbackground, ss->highlight_color, NULL); XtVaSetValues(MSG_BOX(dialog, XmDIALOG_HELP_BUTTON), XmNarmColor, ss->selection_color, NULL); XtVaSetValues(MSG_BOX(dialog, XmDIALOG_HELP_BUTTON), XmNbackground, ss->highlight_color, NULL); } else { XtVaSetValues(dialog, XmNmessageString, q, NULL); } XmStringFree(q); free(question); XtManageChild(dialog); } /* ---------------- view files dialog ---------------- */ /* -------- view files shared code -------- */ static void view_files_clear_selected_files(view_files_info *vdat); static int view_files_add_selected_file(view_files_info *vdat, vf_row *r); static int view_files_find_row(view_files_info *vdat, const char *name); static int view_files_info_size = 0; static view_files_info **view_files_infos = NULL; static Xen vf_open_file_watcher(Xen hook_or_reason) { int k; /* reasons are FILE_OPENED|CLOSED, but it's not worth the trouble of splitting them out here */ /* loop through all vf dialogs ... */ for (k = 0; k < view_files_info_size; k++) if ((view_files_infos[k]) && (view_files_infos[k]->dialog) && (widget_is_active(view_files_infos[k]->dialog))) { view_files_info *vdat; vdat = view_files_infos[k]; vf_mix_insert_buttons_set_sensitive(vdat, ((vdat->currently_selected_files > 0) && (any_selected_sound()))); } return(Xen_false); } Xen_wrap_1_arg(vf_open_file_watcher_w, vf_open_file_watcher) int view_files_dialog_list_length(void) { int i, n = 0; for (i = 0; i < view_files_info_size; i++) if ((view_files_infos[i]) && (view_files_infos[i]->dialog)) n++; return(n); } char **view_files_dialog_titles(void) { int n; n = view_files_dialog_list_length(); if (n > 0) { char **titles; int i, j = 0; titles = (char **)calloc(n + 1, sizeof(char *)); for (i = 0; i < view_files_info_size; i++) if ((view_files_infos[i]) && (view_files_infos[i]->dialog)) titles[j++] = dialog_get_title(view_files_infos[i]->dialog); return(titles); } return(NULL); } void view_files_start_dialog_with_title(const char *title) { int i; for (i = 0; i < view_files_info_size; i++) if ((view_files_infos[i]) && (view_files_infos[i]->dialog)) { char *dialog_title = NULL; dialog_title = dialog_get_title(view_files_infos[i]->dialog); if (mus_strcmp(title, dialog_title)) /* this includes NULL == NULL */ { if (dialog_title) free(dialog_title); make_view_files_dialog_1(view_files_infos[i], true); return; } if (dialog_title) free(dialog_title); } } static view_files_info *new_view_files_dialog(void) { /* always returns a new (empty) file viewer -- changed 8-Jan-08 */ int loc = -1; view_files_info *vdat; if (view_files_info_size == 0) { loc = 0; view_files_info_size = 4; view_files_infos = (view_files_info **)calloc(view_files_info_size, sizeof(view_files_info *)); } else { int i; for (i = 0; i < view_files_info_size; i++) if (!view_files_infos[i]) { loc = i; break; } if (loc == -1) { loc = view_files_info_size; view_files_info_size += 4; view_files_infos = (view_files_info **)realloc(view_files_infos, view_files_info_size * sizeof(view_files_info *)); for (i = loc; i < view_files_info_size; i++) view_files_infos[i] = NULL; } } view_files_infos[loc] = (view_files_info *)calloc(1, sizeof(view_files_info)); vdat = view_files_infos[loc]; vdat->index = loc; vdat->dialog = NULL_WIDGET; vdat->file_list = NULL_WIDGET; vdat->file_list_holder = NULL_WIDGET; vdat->file_list_entries = NULL; vdat->size = 0; vdat->end = -1; vdat->names = NULL; vdat->full_names = NULL; vdat->selected_files = NULL; vdat->selected_files_size = 0; vdat->location_choice = VF_AT_CURSOR; vdat->has_error = false; vdat->need_update = false; vdat->dirs_size = 0; vdat->dirs = NULL; vdat->dir_names = NULL; vdat->amp = 1.0; vdat->speed = 1.0; vdat->amp_env = default_env(1.0, 1.0); vdat->sort_items_size = 0; vdat->sort_items = NULL; vdat->speed_style = speed_control_style(ss); /* don't clear at this point! */ view_files_infos[loc]->currently_selected_files = 0; view_files_infos[loc]->sorter = view_files_sort(ss); return(view_files_infos[loc]); } static int vf_dialog_to_index(widget_t dialog) { int i; if ((!dialog) && (view_files_infos[0]) && (view_files_infos[0]->dialog)) return(0); for (i = 0; i < view_files_info_size; i++) if ((view_files_infos[i]) && (view_files_infos[i]->dialog == dialog)) return(i); return(-1); } static view_files_info *vf_dialog_to_info(widget_t dialog) { int index; index = vf_dialog_to_index(dialog); if (index >= 0) return(view_files_infos[index]); return(NULL); } static char **vf_selected_files(view_files_info *vdat) { int len; char **files = NULL; len = vdat->currently_selected_files; if (len > 0) { int i; files = (char **)calloc(len, sizeof(char *)); for (i = 0; i < len; i++) files[i] = mus_strdup(vdat->full_names[vdat->selected_files[i]]); } return(files); } static char **view_files_selected_files(widget_t dialog, int *len) { /* free result */ view_files_info *vdat; vdat = vf_dialog_to_info(dialog); if (vdat) { (*len) = vdat->currently_selected_files; return(vf_selected_files(vdat)); } (*len) = 0; return(NULL); } static void view_files_run_select_hook(widget_t dialog, const char *selected_file); static char **view_files_set_selected_files(widget_t dialog, char **files, int len) { view_files_info *vdat; vdat = vf_dialog_to_info(dialog); if (vdat) { int i; view_files_clear_selected_files(vdat); for (i = 0; i < len; i++) if (files[i]) { int loc; loc = view_files_find_row(vdat, (const char *)(files[i])); if (loc >= 0) { view_files_add_selected_file(vdat, vdat->file_list_entries[loc]); view_files_run_select_hook(vdat->dialog, (const char *)(files[i])); } } vf_mix_insert_buttons_set_sensitive(vdat, ((vdat->currently_selected_files > 0) && (any_selected_sound()))); } return(files); } static char **view_files_files(widget_t dialog, int *len) { /* don't free result! */ view_files_info *vdat; vdat = vf_dialog_to_info(dialog); if (vdat) { (*len) = vdat->end + 1; return(vdat->full_names); } (*len) = 0; return(NULL); } static void view_files_clear_list(view_files_info *vdat); static char **view_files_set_files(widget_t dialog, char **files, int len) { view_files_info *vdat; vdat = vf_dialog_to_info(dialog); if (vdat) { view_files_clear_selected_files(vdat); view_files_clear_list(vdat); if (len > 0) { int i; for (i = 0; i < len; i++) if (files[i]) view_files_add_file_or_directory(vdat, (const char *)(files[i])); } view_files_display_list(vdat); } return(files); } static void vf_mix_insert_buttons_set_sensitive(view_files_info *vdat, bool sensitive) { if (vdat->mixB) { set_sensitive(vdat->mixB, sensitive); set_sensitive(vdat->insertB, sensitive); } } static void view_files_clear_selected_files(view_files_info *vdat) { int len; len = vdat->currently_selected_files; if (len > 0) { int i; for (i = 0; i < len; i++) { vf_row *r; r = vdat->file_list_entries[vdat->selected_files[i]]; if (r) vf_unhighlight_row(r->nm, r->rw); } } vdat->currently_selected_files = 0; vf_mix_insert_buttons_set_sensitive(vdat, false); } static void view_files_unselect_file(view_files_info *vdat, vf_row *r) { vf_unhighlight_row(r->nm, r->rw); if (vdat->currently_selected_files > 1) { /* need to fixup selected_files list */ int i, new_loc = 0; for (i = 0; i < vdat->currently_selected_files; i++) if (vdat->selected_files[i] != r->pos) vdat->selected_files[new_loc++] = vdat->selected_files[i]; } vdat->currently_selected_files--; if (vdat->currently_selected_files < 0) vdat->currently_selected_files = 0; if (vdat->currently_selected_files == 0) { vf_mix_insert_buttons_set_sensitive(vdat, false); vf_unpost_info(vdat); } } static int view_files_add_selected_file(view_files_info *vdat, vf_row *r) { /* returns how many are now selected (counting new) */ if (vdat->selected_files_size == 0) { vdat->selected_files_size = 4; vdat->selected_files = (int *)calloc(vdat->selected_files_size, sizeof(int)); vdat->selected_files[0] = r->pos; vdat->currently_selected_files = 1; } else { if (vdat->currently_selected_files >= vdat->selected_files_size) { vdat->selected_files_size += 4; vdat->selected_files = (int *)realloc(vdat->selected_files, vdat->selected_files_size * sizeof(int)); vdat->selected_files[vdat->currently_selected_files++] = r->pos; } else { vdat->selected_files[vdat->currently_selected_files++] = r->pos; } } vf_highlight_row(r->nm, r->rw); return(vdat->currently_selected_files); } static void vf_fixup_selected_files(view_files_info *vdat, char **saved_selected_files, int len) { /* various things change the order or contents of the files list, so the selected locs list needs to reflect that */ int i, newly_selected = 0; for (i = 0; i < len; i++) { int j; for (j = 0; j <= vdat->end; j++) if ((vdat->full_names[j]) && (mus_strcmp(vdat->full_names[j], saved_selected_files[i]))) { vf_row *old_r, *new_r; /* fprintf(stderr,"old %d at %d -> %d at %d\n", vdat->selected_files[i], i, j, newly_selected); */ old_r = vdat->file_list_entries[vdat->selected_files[i]]; vdat->selected_files[newly_selected++] = j; new_r = vdat->file_list_entries[j]; if (new_r != old_r) { vf_highlight_row(new_r->nm, new_r->rw); vf_unhighlight_row(old_r->nm, old_r->rw); } break; } } vdat->currently_selected_files = newly_selected; } static int view_files_find_row(view_files_info *vdat, const char *name) { int i; if (vdat->names) for (i = 0; i <= vdat->end; i++) if ((vdat->names[i]) && (mus_strcmp(vdat->names[i], name))) return(i); if (vdat->full_names) for (i = 0; i <= vdat->end; i++) if ((vdat->full_names[i]) && (mus_strcmp(vdat->full_names[i], name))) return(i); return(-1); } static void view_files_select(vf_row *r, bool add_to_selected) { view_files_info *vdat = (view_files_info *)(r->vdat); int i, curloc = -1; for (i = 0; i < vdat->currently_selected_files; i++) if (vdat->selected_files[i] == r->pos) { curloc = r->pos; break; } if (curloc == -1) { /* file not currently selected */ if (!add_to_selected) /* not shift click, so remove all currently selected files first */ view_files_clear_selected_files(vdat); view_files_add_selected_file(vdat, r); view_files_run_select_hook(vdat->dialog, vdat->full_names[r->pos]); } else { /* file already selected, so remove from selected files list */ view_files_unselect_file(vdat, r); } if ((vdat->currently_selected_files == 0) || ((vdat->currently_selected_files == 1) && (!(is_plausible_sound_file(vdat->full_names[vdat->selected_files[0]]))))) vf_unpost_info(vdat); else { if (vdat->currently_selected_files == 1) vf_post_info(vdat, vdat->selected_files[0]); else vf_post_selected_files_list(vdat); } vf_mix_insert_buttons_set_sensitive(vdat, ((vdat->currently_selected_files > 0) && (any_selected_sound()))); } static bool view_files_play(view_files_info *vdat, int pos, bool play) { static snd_info *play_sp; if (play) { if (play_sp) { if (play_sp->playing) return(true); /* can't play two of these at once */ if ((vdat->names[pos] == NULL) || (!mus_strcmp(play_sp->short_filename, vdat->names[pos]))) { completely_free_snd_info(play_sp); play_sp = NULL; } } if ((!play_sp) && (vdat->full_names[pos])) play_sp = make_sound_readable(vdat->full_names[pos], false); if (play_sp) { play_sp->short_filename = vdat->names[pos]; play_sp->filename = NULL; /* pass view files dialog settings to play */ play_sp->speed_control = vdat->speed; play_sp->amp_control = vdat->amp; play_sound(play_sp, 0, NO_END_SPECIFIED); } else return(true); /* can't find or setup file */ } else { /* play toggled off */ if ((play_sp) && (play_sp->playing)) { stop_playing_sound(play_sp, PLAY_BUTTON_UNSET); vdat->current_play_button = NULL_WIDGET; } } return(false); } void view_files_unplay(void) { int k; for (k = 0; k < view_files_info_size; k++) if ((view_files_infos[k]) && (view_files_infos[k]->dialog) && (widget_is_active(view_files_infos[k]->dialog))) { view_files_info *vdat; vdat = view_files_infos[k]; if ((vdat->current_play_button) && (XmToggleButtonGetState(vdat->current_play_button) != XmUNSET)) { set_toggle_button(vdat->current_play_button, false, true, (void *)vdat); vdat->current_play_button = NULL_WIDGET; } } } static void view_files_reflect_sort_items(void) { int i; view_files_info *vdat; int j = 0, k; if (view_files_info_size == 0) return; for (i = 0; i < ss->file_sorters_size; i++) { Xen ref; ref = Xen_vector_ref(ss->file_sorters, i); if (Xen_is_pair(ref)) { XmString s1; s1 = XmStringCreateLocalized((char *)Xen_string_to_C_string(Xen_car(ref))); for (k = 0; k < view_files_info_size; k++) if ((view_files_infos[k]) && (view_files_infos[k]->dialog)) { vdat = view_files_infos[k]; if (j >= vdat->sort_items_size) { int n = 0, k, old_size; Arg args[20]; old_size = vdat->sort_items_size; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; vdat->sort_items_size += 4; vdat->sort_items = (Widget *)realloc(vdat->sort_items, vdat->sort_items_size * sizeof(Widget)); for (k = old_size; k < vdat->sort_items_size; k++) vdat->sort_items[k] = XtCreateWidget("unused", xmPushButtonWidgetClass, vdat->smenu, args, n); } XtVaSetValues(vdat->sort_items[j], XmNlabelString, s1, XmNuserData, i + SORT_XEN, /* this is an index into the file_sorters list, not the widget list */ NULL); XtManageChild(vdat->sort_items[j]); } j++; XmStringFree(s1); } } } /* (add-file-sorter "duration" (lambda (lst) (sort lst (lambda (a b) (> (mus-sound-duration a) (mus-sound-duration b)))))) */ static void vf_add_file(view_files_info *vdat, const char *filename, const char *fullname) { vdat->end++; if (vdat->end >= vdat->size) { int new_size; new_size = vdat->size + 32; if (vdat->size == 0) { vdat->names = (char **)calloc(new_size, sizeof(char *)); vdat->full_names = (char **)calloc(new_size, sizeof(char *)); } else { int i; vdat->names = (char **)realloc(vdat->names, new_size * sizeof(char *)); vdat->full_names = (char **)realloc(vdat->full_names, new_size * sizeof(char *)); for (i = vdat->size; i < new_size; i++) { vdat->names[i] = NULL; vdat->full_names[i] = NULL; } } if (vdat->file_list_entries == NULL) vdat->file_list_entries = (vf_row **)calloc(new_size, sizeof(vf_row *)); else { int i; vdat->file_list_entries = (vf_row **)realloc(vdat->file_list_entries, new_size * sizeof(vf_row *)); for (i = vdat->size; i < new_size; i++) vdat->file_list_entries[i] = NULL; } vdat->size = new_size; } vdat->names[vdat->end] = mus_strdup(filename); vdat->full_names[vdat->end] = mus_strdup(fullname); } static void add_file_to_view_files_list(view_files_info *vdat, const char *filename, const char *fullname) { int row; row = view_files_find_row(vdat, filename); if (row != -1) { if ((vdat->dialog) && (widget_is_active(vdat->dialog)) && (vdat->file_list_entries[row])) { ensure_scrolled_window_row_visible(vdat->file_list, row, vdat->end + 1); vf_flash_row(vdat->file_list_entries[row]); } return; } errno = 0; if (!(mus_file_probe(fullname))) { if ((vdat->dialog) && (widget_is_active(vdat->dialog))) { char *msg; if (errno != 0) msg = mus_format("%s: %s", filename, strerror(errno)); else msg = mus_format("%s does not exist", filename); vf_post_add_error(msg, vdat); free(msg); } return; } vf_add_file(vdat, filename, fullname); } /* what about temps coming and going -- should we just add a need-update switch for later remanage? */ /* remanagement only through make_view_files_dialog -- this file */ /* perhaps ss->making|deleting_temp_file -> ignore this fam event? */ static void add_directory_to_view_files_list(view_files_info *vdat, const char *dirname) { /* I think all directory additions come through here */ if ((dirname) && (dirname[strlen(dirname) - 1] != '/')) { char *add_slash; add_slash = mus_format("%s/", dirname); add_directory_to_view_files_list(vdat, add_slash); free(add_slash); } else { dir_info *sound_files = NULL; #if (!USE_NO_GUI) view_files_monitor_directory(vdat, dirname); #endif sound_files = find_sound_files_in_dir(dirname); if ((sound_files) && (sound_files->len > 0)) { int i, dirs = 0, len = 16; for (i = 0; i < sound_files->len; i++) add_file_to_view_files_list(vdat, sound_files->files[i]->filename, sound_files->files[i]->full_filename); sound_files = free_dir_info(sound_files); /* fixup title */ for (i = 0; i < vdat->dirs_size; i++) if (vdat->dir_names[i]) { dirs++; len += mus_strlen(just_filename(vdat->dir_names[i])); } if ((dirs < 4) && (len < 512)) { int cur_dir = 0; char *titlestr = NULL, *dirstr; titlestr = (char *)calloc(len + dirs * 8, sizeof(char)); strcat(titlestr, "Files: "); for (i = 0; i < vdat->dirs_size; i++) if (vdat->dir_names[i]) { dirstr = just_filename(vdat->dir_names[i]); strcat(titlestr, dirstr); free(dirstr); cur_dir++; if (cur_dir < dirs) strcat(titlestr, ", "); } dialog_set_title(vdat->dialog, titlestr); free(titlestr); } } } } static void view_files_sort_list(view_files_info *vdat) { if (vdat->end >= 0) { sort_info **data; int i, len; len = vdat->end + 1; data = (sort_info **)calloc(len, sizeof(sort_info *)); for (i = 0; i < len; i++) { data[i] = (sort_info *)calloc(1, sizeof(sort_info)); data[i]->filename = vdat->names[i]; data[i]->full_filename = vdat->full_names[i]; } snd_sort(vdat->sorter, data, len); for (i = 0; i < len; i++) { vdat->names[i] = data[i]->filename; vdat->full_names[i] = data[i]->full_filename; free(data[i]); } free(data); } } static void view_files_display_list(view_files_info *vdat) { int i; vf_row *r; if (!vdat) return; if (!(vdat->dialog)) return; if (vdat->end >= 0) { int i, old_len; char **old_names = NULL; widget_t last_row = NULL_WIDGET; /* ignored in gtk version */ old_len = vdat->currently_selected_files; if (old_len > 0) old_names = vf_selected_files(vdat); view_files_sort_list(vdat); for (i = 0; i <= vdat->end; i++) { r = vdat->file_list_entries[i]; if (!r) { r = view_files_make_row(vdat, last_row); vdat->file_list_entries[i] = r; r->pos = i; } set_button_label(r->nm, vdat->names[r->pos]); #if WITH_AUDIO set_toggle_button(r->pl, false, false, (void *)vdat); #endif if (!(widget_is_active(r->rw))) activate_widget(r->rw); last_row = r->rw; } if (old_names) { vf_fixup_selected_files(vdat, old_names, old_len); for (i = 0; i < old_len; i++) free(old_names[i]); free(old_names); } } for (i = vdat->end + 1; i < vdat->size; i++) { r = vdat->file_list_entries[i]; if (r) { if (widget_is_active(r->rw)) deactivate_widget(r->rw); } } if (!(widget_is_active(vdat->file_list))) activate_widget(vdat->file_list); } static void view_files_clear_list(view_files_info *vdat) { #if (!USE_NO_GUI) view_files_unmonitor_directories(vdat); #endif if (vdat->names) { int i; for (i = 0; i < vdat->size; i++) if (vdat->names[i]) { free(vdat->names[i]); vdat->names[i] = NULL; free(vdat->full_names[i]); vdat->full_names[i] = NULL; } vdat->end = -1; vdat->currently_selected_files = 0; } } #if 0 static void view_files_update_list(view_files_info *vdat) { /* here we need the file's full name */ int i, old_len; char **old_names = NULL; old_len = vdat->currently_selected_files; if (old_len > 0) old_names = vf_selected_files(vdat); if (vdat->names) { int i, j; for (i = 0; i <= vdat->end; i++) if (vdat->names[i]) { if (!(mus_file_probe(vdat->full_names[i]))) { free(vdat->names[i]); vdat->names[i] = NULL; free(vdat->full_names[i]); vdat->full_names[i] = NULL; } } for (i = 0, j = 0; i <= vdat->end; i++) if (vdat->names[i]) { if (i != j) { vdat->names[j] = vdat->names[i]; vdat->names[i] = NULL; vdat->full_names[j] = vdat->full_names[i]; vdat->full_names[i] = NULL; } j++; } vdat->end = j - 1; } if (old_names) { vf_fixup_selected_files(vdat, old_names, old_len); for (i = 0; i < old_len; i++) free(old_names[i]); free(old_names); } } #endif static void vf_clear_error(view_files_info *vdat) { if (vdat->currently_selected_files == 1) vf_post_info(vdat, vdat->selected_files[0]); else { if (vdat->currently_selected_files == 0) vf_unpost_info(vdat); else vf_post_selected_files_list(vdat); } vdat->has_error = false; } static int vf_mix(view_files_info *vdat) { int len, id_or_error = 0; snd_info *sp; sp = any_selected_sound(); len = vdat->currently_selected_files; if ((len == 1) && (snd_feq(vdat->amp, 1.0)) && (snd_feq(vdat->speed, 1.0)) && (is_default_env(vdat->amp_env))) id_or_error = mix_complete_file(sp, vdat->beg, vdat->full_names[vdat->selected_files[0]], with_mix_tags(ss), DONT_DELETE_ME, MIX_SETS_SYNC_LOCALLY, NULL); else { int i; bool err = false; char *tempfile; char **selected_files; selected_files = vf_selected_files(vdat); tempfile = scale_and_src(selected_files, len, sp->nchans, vdat->amp, vdat->speed, vdat->amp_env, &err); if (err) { vf_post_error(tempfile, vdat); id_or_error = MIX_FILE_NO_TEMP_FILE; } else { if (sp->nchans > 1) remember_temp(tempfile, sp->nchans); id_or_error = mix_complete_file(sp, vdat->beg, tempfile, with_mix_tags(ss), (sp->nchans > 1) ? MULTICHANNEL_DELETION : DELETE_ME, MIX_SETS_SYNC_LOCALLY, NULL); } free(tempfile); for (i = 0; i < len; i++) free(selected_files[i]); free(selected_files); } return(id_or_error); } static void view_files_mix_selected_files(widget_t w, view_files_info *vdat) { vdat->has_error = false; redirect_snd_error_to(redirect_vf_post_location_error, (void *)vdat); vdat->beg = vf_location(vdat); redirect_snd_error_to(NULL, NULL); if (!(vdat->has_error)) { int id_or_error = 0; redirect_snd_error_to(redirect_vf_post_error, (void *)vdat); ss->requestor_dialog = w; ss->open_requestor_data = (void *)vdat; ss->open_requestor = FROM_VIEW_FILES_MIX_DIALOG; id_or_error = vf_mix(vdat); /* "id_or_error" here is either one of the mix id's or an error indication such as MIX_FILE_NO_MIX */ /* the possible error conditions have been checked already, or go through snd_error */ redirect_snd_error_to(NULL, NULL); if (id_or_error >= 0) { char *msg; if (vdat->currently_selected_files == 1) msg = mus_format("%s mixed in at %lld", vdat->names[vdat->selected_files[0]], vdat->beg); else msg = mus_format("selected files mixed in at %lld", vdat->beg); vf_post_error(msg, vdat); vdat->has_error = false; free(msg); } } } static bool vf_insert(view_files_info *vdat) { int len; bool ok = false; snd_info *sp; sp = any_selected_sound(); len = vdat->currently_selected_files; if ((len == 1) && (snd_feq(vdat->amp, 1.0)) && (snd_feq(vdat->speed, 1.0)) && (is_default_env(vdat->amp_env))) ok = insert_complete_file(sp, vdat->full_names[vdat->selected_files[0]], vdat->beg, DONT_DELETE_ME); else { int i; bool err = false; char *tempfile; char **selected_files; selected_files = vf_selected_files(vdat); tempfile = scale_and_src(selected_files, len, sp->nchans, vdat->amp, vdat->speed, vdat->amp_env, &err); if (err) { vf_post_error(tempfile, vdat); ok = false; } else { vf_clear_error(vdat); if (sp->nchans > 1) remember_temp(tempfile, sp->nchans); ok = insert_complete_file(sp, tempfile, vdat->beg, (sp->nchans > 1) ? MULTICHANNEL_DELETION : DELETE_ME); } free(tempfile); for (i = 0; i < len; i++) free(selected_files[i]); free(selected_files); } return(ok); } static void view_files_insert_selected_files(widget_t w, view_files_info *vdat) { vdat->has_error = false; redirect_snd_error_to(redirect_vf_post_location_error, (void *)vdat); vdat->beg = vf_location(vdat); redirect_snd_error_to(NULL, NULL); if (!(vdat->has_error)) { bool ok; redirect_snd_error_to(redirect_vf_post_error, (void *)vdat); redirect_snd_warning_to(redirect_vf_post_error, (void *)vdat); ss->requestor_dialog = w; ss->open_requestor = FROM_VIEW_FILES_INSERT_DIALOG; ss->open_requestor_data = (void *)vdat; ok = vf_insert(vdat); redirect_snd_error_to(NULL, NULL); redirect_snd_warning_to(NULL, NULL); if (ok) { char *msg; if (vdat->currently_selected_files == 1) msg = mus_format("%s inserted at %lld", vdat->names[vdat->selected_files[0]], vdat->beg); else msg = mus_format("selected files inserted at %lld", vdat->beg); vf_post_error(msg, vdat); vdat->has_error = false; free(msg); } /* else we've already posted whatever went wrong (make_file_info etc) */ } } static mus_float_t view_files_amp(widget_t dialog) { view_files_info *vdat; vdat = vf_dialog_to_info(dialog); if (vdat) return(vdat->amp); return(0.0); } static mus_float_t view_files_set_amp(widget_t dialog, mus_float_t new_amp) { view_files_info *vdat; vdat = vf_dialog_to_info(dialog); if (vdat) vf_set_amp(vdat, new_amp); return(new_amp); } static mus_float_t view_files_speed(widget_t dialog) { view_files_info *vdat; vdat = vf_dialog_to_info(dialog); if (vdat) return(vdat->speed); return(1.0); } static mus_float_t view_files_set_speed(widget_t dialog, mus_float_t new_speed) { view_files_info *vdat; vdat = vf_dialog_to_info(dialog); if (vdat) vf_set_speed(vdat, new_speed); return(new_speed); } static speed_style_t view_files_speed_style(widget_t dialog) { view_files_info *vdat; vdat = vf_dialog_to_info(dialog); if (vdat) return(vdat->speed_style); return(SPEED_CONTROL_AS_FLOAT); } static speed_style_t view_files_set_speed_style(widget_t dialog, speed_style_t speed_style) { view_files_info *vdat; vdat = vf_dialog_to_info(dialog); if (vdat) { vdat->speed_style = speed_style; vf_set_speed(vdat, vdat->speed); /* update label etc */ } return(speed_style); } static env *view_files_amp_env(widget_t dialog) { view_files_info *vdat; vdat = vf_dialog_to_info(dialog); if (vdat) return(vdat->amp_env); return(NULL); } static void view_files_set_amp_env(widget_t dialog, env *new_e) { vf_set_amp_env(vf_dialog_to_info(dialog), new_e); } static int view_files_local_sort(widget_t dialog) { view_files_info *vdat; vdat = vf_dialog_to_info(dialog); if (vdat) return(vdat->sorter); return(-1); } static int view_files_set_local_sort(widget_t dialog, int sort_choice) { view_files_info *vdat; vdat = vf_dialog_to_info(dialog); if (vdat) { vdat->sorter = sort_choice; view_files_display_list(vdat); vf_reflect_sort_choice_in_menu(vdat); } return(sort_choice); } static view_files_info *view_files_find_dialog(widget_t dialog) { int i; for (i = 0; i < view_files_info_size; i++) if ((view_files_infos[i]) && (view_files_infos[i]->dialog == dialog)) return(view_files_infos[i]); return(NULL); } widget_t make_view_files_dialog(bool managed, bool make_new) { int i; view_files_info *vdat = NULL; if (make_new) return(make_view_files_dialog_1(new_view_files_dialog(), managed)); for (i = 0; i < view_files_info_size; i++) if ((view_files_infos[i]) && (view_files_infos[i]->dialog)) { vdat = view_files_infos[i]; if (widget_is_active(vdat->dialog)) break; } if (vdat) return(make_view_files_dialog_1(vdat, managed)); return(make_view_files_dialog_1(new_view_files_dialog(), managed)); } void save_view_files_dialogs(FILE *fd) { #if HAVE_EXTENSION_LANGUAGE int i; view_files_info *vdat; for (i = 0; i < view_files_info_size; i++) if ((view_files_infos[i]) && (view_files_infos[i]->dialog) && (widget_is_active(view_files_infos[i]->dialog))) { vdat = view_files_infos[i]; #if HAVE_SCHEME fprintf(fd, "(let ((vf (" S_view_files_dialog " #t #t)))\n"); if (vdat->full_names) { int k; fprintf(fd, " (set! (" S_view_files_files " vf) (list"); for (k = 0; k <= vdat->end; k++) fprintf(fd, " \"%s\"", vdat->full_names[k]); fprintf(fd, "))\n"); if (vdat->currently_selected_files > 0) { fprintf(fd, " (set! (" S_view_files_selected_files " vf) (list"); for (k = 0; k < vdat->currently_selected_files; k++) fprintf(fd, " \"%s\"", vdat->full_names[vdat->selected_files[k]]); fprintf(fd, "))\n"); } } if (!(snd_feq(vdat->amp, 1.0))) fprintf(fd, " (set! (" S_view_files_amp " vf) %.3f)\n", vdat->amp); if (!(snd_feq(vdat->speed, 1.0))) fprintf(fd, " (set! (" S_view_files_speed " vf) %.3f)\n", vdat->speed); if (!(is_default_env(vdat->amp_env))) fprintf(fd, " (set! (" S_view_files_amp_env " vf) %s)\n", env_to_string(vdat->amp_env)); /* assume file-sorters are set up already */ fprintf(fd, " (set! (" S_view_files_sort " vf) %d)\n", vdat->sorter); fprintf(fd, ")\n"); #endif #if HAVE_RUBY fprintf(fd, "vf = view_files_dialog(true, true)\n"); if (vdat->full_names) { int k; fprintf(fd, " set_view_files_files(vf, ["); for (k = 0; k < vdat->end; k++) fprintf(fd, "\"%s\", ", vdat->full_names[k]); fprintf(fd, "\"%s\"])\n", vdat->full_names[vdat->end]); if (vdat->currently_selected_files > 0) { fprintf(fd, " set_view_files_selected_files(vf, ["); for (k = 0; k < vdat->currently_selected_files - 1; k++) fprintf(fd, "\"%s\", ", vdat->full_names[vdat->selected_files[k]]); fprintf(fd, "\"%s\"])\n", vdat->full_names[vdat->selected_files[vdat->currently_selected_files]]); } } if (!(snd_feq(vdat->amp, 1.0))) fprintf(fd, " set_view_files_amp(vf, %.3f)\n", vdat->amp); if (!(snd_feq(vdat->speed, 1.0))) fprintf(fd, " set_view_files_speed(vf, %.3f)\n", vdat->speed); if (!(is_default_env(vdat->amp_env))) fprintf(fd, " set_view_files_amp_env(vf, %s)\n", env_to_string(vdat->amp_env)); /* assume file-sorters are set up already */ fprintf(fd, " set_view_files_sort(vf, %d)\n", vdat->sorter); fprintf(fd, "\n"); #endif #if HAVE_FORTH fprintf(fd, "#t #t view-files-dialog value vf\n"); if (vdat->full_names) { int k; fprintf(fd, " vf '("); for (k = 0; k <= vdat->end; k++) fprintf(fd, " \"%s\"", vdat->full_names[k]); fprintf(fd, " ) set-view-files-files drop\n"); if (vdat->currently_selected_files > 0) { fprintf(fd, " vf '("); for (k = 0; k <= vdat->currently_selected_files; k++) fprintf(fd, " \"%s\"", vdat->full_names[vdat->selected_files[k]]); fprintf(fd, " ) set-view-files-selected-files drop\n"); } } if (!(snd_feq(vdat->amp, 1.0))) fprintf(fd, " vf %.3f set-view-files-amp drop\n", vdat->amp); if (!(snd_feq(vdat->speed, 1.0))) fprintf(fd, " vf %.3f set-view-files-speed drop\n", vdat->speed); if (!(is_default_env(vdat->amp_env))) fprintf(fd, " vf %s set-view-files-amp-env drop\n", env_to_string(vdat->amp_env)); /* assume file-sorters are set up already */ fprintf(fd, " vf %d set-view-files-sort drop\n\n", vdat->sorter); #endif } #endif } void view_files_add_directory(widget_t dialog, const char *dirname) { view_files_info *vdat = NULL; if (dialog) vdat = view_files_find_dialog(dialog); else { if (view_files_info_size > 0) vdat = view_files_infos[0]; else { vdat = new_view_files_dialog(); make_view_files_dialog_1(vdat, false); } } if (vdat) { char *full_filename; full_filename = mus_expand_filename((const char *)dirname); if (!(mus_file_probe(full_filename))) { if ((vdat->dialog) && (widget_is_active(vdat->dialog))) { char *msg; if (errno != 0) msg = mus_format("%s: %s", full_filename, strerror(errno)); else msg = mus_format("%s does not exist", full_filename); vf_post_add_error(msg, vdat); free(msg); } } else { add_directory_to_view_files_list(vdat, full_filename); } free(full_filename); } } static void view_files_add_file(widget_t dialog, const char *filename) { view_files_info *vdat = NULL; if (dialog) vdat = view_files_find_dialog(dialog); else { if (view_files_info_size > 0) vdat = view_files_infos[0]; else { vdat = new_view_files_dialog(); make_view_files_dialog_1(vdat, false); } } if (vdat) { char *full_filename; full_filename = mus_expand_filename((const char *)filename); add_file_to_view_files_list(vdat, filename, full_filename); free(full_filename); } } static void view_files_open_selected_files(view_files_info *vdat) { ss->open_requestor = FROM_VIEW_FILES; if (vdat->currently_selected_files > 0) { int i; snd_info *sp = NULL; for (i = 0; i < vdat->currently_selected_files; i++) sp = snd_open_file(vdat->full_names[vdat->selected_files[i]], FILE_READ_WRITE); if (sp) select_channel(sp, 0); } } char *view_files_find_any_directory(void) { /* find any active directory in any vf dialog */ if (view_files_info_size > 0) { int j; for (j = 0; j < view_files_info_size; j++) { view_files_info *vdat; vdat = view_files_infos[j]; if ((vdat) && (vdat->dir_names)) { int i; for (i = 0; i < vdat->dirs_size; i++) if (vdat->dir_names[i]) return(vdat->dir_names[i]); } } } return(NULL); } static Xen mouse_enter_label_hook; static Xen mouse_leave_label_hook; static char *vf_row_get_label(void *ur) { vf_row *r = (vf_row *)ur; return(((view_files_info *)(r->vdat))->full_names[r->pos]); } static int vf_row_get_pos(void *ur) { vf_row *r = (vf_row *)ur; return(r->pos); } static void mouse_enter_or_leave_label(void *r, int type, Xen hook, const char *caller) { if ((r) && (Xen_hook_has_list(hook))) { char *label = NULL; bool need_free = false; if (type == FILE_VIEWER) label = vf_row_get_label(r); else { label = regrow_get_label(r); if (label) need_free = true; } if (label) run_hook(hook, Xen_list_3(C_int_to_Xen_integer(type), C_int_to_Xen_integer((type == FILE_VIEWER) ? (vf_row_get_pos(r)) : (regrow_get_pos(r))), C_string_to_Xen_string(label)), caller); if (need_free) XtFree(label); } } void mouse_leave_label(void *r, int type) { mouse_enter_or_leave_label(r, type, mouse_leave_label_hook, S_mouse_leave_label_hook); } void mouse_enter_label(void *r, int type) { mouse_enter_or_leave_label(r, type, mouse_enter_label_hook, S_mouse_enter_label_hook); } static void vf_mouse_enter_label(Widget w, XtPointer context, XEvent *event, Boolean *flag) { mouse_enter_label(context, FILE_VIEWER); } static void vf_mouse_leave_label(Widget w, XtPointer context, XEvent *event, Boolean *flag) { mouse_leave_label(context, FILE_VIEWER); } static vf_row *make_vf_row(view_files_info *vdat, Widget last_row, XtCallbackProc play_callback, XtCallbackProc name_callback) { int n; Arg args[32]; vf_row *r; XmString s1; #if WITH_AUDIO XtCallbackList n1; #endif XtCallbackList n3; s1 = XmStringCreateLocalized((char *)""); r = (vf_row *)calloc(1, sizeof(vf_row)); r->vdat = (void *)vdat; n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, (last_row) ? XmATTACH_WIDGET : XmATTACH_FORM); n++; if (last_row) {XtSetArg(args[n], XmNtopWidget, last_row); n++;} XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNheight, 18); n++; r->rw = XtCreateWidget("rw", xmFormWidgetClass, vdat->file_list_holder, args, n); #if WITH_AUDIO n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNselectColor, ss->selection_color); n++; XtSetArg(args[n], XmNlabelString, s1); n++; XtSetArg(args[n], XmNvalueChangedCallback, n1 = make_callback_list(play_callback, (XtPointer)r)); n++; if (ss->toggle_size > 0) {XtSetArg(args[n], XmNindicatorSize, ss->toggle_size); n++;} XtSetArg(args[n], XmNmarginWidth, 8); n++; r->pl = make_togglebutton_widget("pl", r->rw, args, n); #endif n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; #if WITH_AUDIO XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, r->pl); n++; #else XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; #endif XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNshadowThickness, 0); n++; XtSetArg(args[n], XmNhighlightThickness, 0); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(args[n], XmNfillOnArm, false); n++; XtSetArg(args[n], XmNrecomputeSize, false); n++; XtSetArg(args[n], XmNwidth, 500); n++; /* this sets the max name length indirectly -- was 300 which truncates some long file names (29-Oct-07) */ XtSetArg(args[n], XmNactivateCallback, n3 = make_callback_list(name_callback, (XtPointer)r)); n++; r->nm = XtCreateManagedWidget("nm", xmPushButtonWidgetClass, r->rw, args, n); XmStringFree(s1); XtAddEventHandler(r->nm, EnterWindowMask, false, vf_mouse_enter_label, (XtPointer)r); XtAddEventHandler(r->nm, LeaveWindowMask, false, vf_mouse_leave_label, (XtPointer)r); #if WITH_AUDIO free(n1); #endif free(n3); return(r); } static void vf_unhighlight_row(widget_t nm, widget_t rw) { XtVaSetValues(rw, XmNbackground, ss->highlight_color, NULL); XtVaSetValues(nm, XmNbackground, ss->highlight_color, NULL); } static void vf_highlight_row(widget_t nm, widget_t rw) { XtVaSetValues(rw, XmNbackground, ss->zoom_color, NULL); XtVaSetValues(nm, XmNbackground, ss->zoom_color, NULL); } typedef struct { vf_row *r; color_t old_color; } vf_flash_data; static void vf_unflash_row(XtPointer data, XtIntervalId *id) { vf_flash_data *v = (vf_flash_data *)data; XtVaSetValues(v->r->rw, XmNbackground, v->old_color, NULL); XtVaSetValues(v->r->nm, XmNbackground, v->old_color, NULL); free(v); } static void vf_flash_row(vf_row *r) { vf_flash_data *v; v = (vf_flash_data *)calloc(1, sizeof(vf_flash_data)); v->r = r; XtVaGetValues(r->rw, XmNbackground, &(v->old_color), NULL); XtVaSetValues(r->rw, XmNbackground, ss->light_blue, NULL); XtVaSetValues(r->nm, XmNbackground, ss->light_blue, NULL); XtAppAddTimeOut(MAIN_APP(ss), 500, (XtTimerCallbackProc)vf_unflash_row, (void *)v); } static void vf_post_info(view_files_info *vdat, int pos) { char *title; XmString s3; title = mus_format("%s:", vdat->names[pos]); s3 = XmStringCreateLocalized(title); XtVaSetValues(vdat->left_title, XmNlabelString, s3, NULL); XmStringFree(s3); free(title); post_sound_info(vdat->info1, vdat->info2, vdat->full_names[pos], false); } static void vf_post_selected_files_list(view_files_info *vdat) { int len; char *msg1 = NULL, *msg2 = NULL, *title; XmString s1, s2, s3; len = vdat->currently_selected_files; title = mus_strdup("selected files:"); s3 = XmStringCreateLocalized(title); XtVaSetValues(vdat->left_title, XmNlabelString, s3, NULL); XmStringFree(s3); free(title); if (len == 2) { msg1 = mus_strdup(vdat->names[vdat->selected_files[0]]); msg2 = mus_strdup(vdat->names[vdat->selected_files[1]]); } else { if (len == 3) { msg1 = mus_format("%s, %s", vdat->names[vdat->selected_files[0]], vdat->names[vdat->selected_files[1]]); msg2 = mus_strdup(vdat->names[vdat->selected_files[2]]); } else { msg1 = mus_format("%s, %s", vdat->names[vdat->selected_files[0]], vdat->names[vdat->selected_files[1]]); msg2 = mus_format("%s, %s%s", vdat->names[vdat->selected_files[2]], vdat->names[vdat->selected_files[3]], (len == 4) ? "" : "..."); } } s1 = XmStringCreateLocalized(msg1); s2 = XmStringCreateLocalized(msg2); XtVaSetValues(vdat->info1, XmNlabelString, s1, NULL); XtVaSetValues(vdat->info2, XmNlabelString, s2, NULL); XmStringFree(s1); XmStringFree(s2); free(msg1); free(msg2); } static void vf_unpost_info(view_files_info *vdat) { XmString s1, s2, s3; char *title; title = mus_strdup("(no files selected)"); s3 = XmStringCreateLocalized(title); XtVaSetValues(vdat->left_title, XmNlabelString, s3, NULL); XmStringFree(s3); free(title); s1 = XmStringCreateLocalized((char *)"|"); s2 = XmStringCreateLocalized((char *)"|"); XtVaSetValues(vdat->info1, XmNlabelString, s1, NULL); XtVaSetValues(vdat->info2, XmNlabelString, s2, NULL); XmStringFree(s1); XmStringFree(s2); } static void view_files_select_callback(Widget w, XtPointer context, XtPointer info) { static oclock_t mouse_down_time = 0; XmPushButtonCallbackStruct *cb = (XmPushButtonCallbackStruct *)info; XButtonEvent *ev; ev = (XButtonEvent *)(cb->event); /* cb->click_count is always 1 so we can't detect a double-click that way * ss->click_time has the (very short!) multiclick time */ if (mouse_down_time != 0) { if ((ev->time - mouse_down_time) < ss->click_time) /* open file if double clicked */ { mouse_down_time = ev->time; view_files_open_selected_files((view_files_info *)(((vf_row *)context)->vdat)); return; } } mouse_down_time = ev->time; view_files_select((vf_row *)context, ev->state & snd_ShiftMask); } static void view_files_play_callback(Widget w, XtPointer context, XtPointer info) { #if WITH_AUDIO /* open and play -- close at end or when button off toggled */ vf_row *r = (vf_row *)context; view_files_info *vdat; XmToggleButtonCallbackStruct *cb = (XmToggleButtonCallbackStruct *)info; vdat = (view_files_info *)(r->vdat); if (view_files_play(vdat, r->pos, cb->set)) XmToggleButtonSetState(w, false, false); else vdat->current_play_button = w; #endif } static vf_row *view_files_make_row(view_files_info *vdat, widget_t last_row) { return(make_vf_row(vdat, last_row, view_files_play_callback, view_files_select_callback)); } static void view_files_help_callback(Widget w, XtPointer context, XtPointer info) { view_files_dialog_help(); } static void view_files_quit_callback(Widget w, XtPointer context, XtPointer info) { view_files_info *vdat = (view_files_info *)context; XtUnmanageChild(vdat->dialog); } static void view_files_new_viewer_callback(Widget w, XtPointer context, XtPointer info) { view_files_info *vdat = (view_files_info *)context; if ((vdat) && (vdat->dialog) && (XtIsManaged(vdat->dialog)) && (XmGetFocusWidget(vdat->dialog) == XmMessageBoxGetChild(vdat->dialog, XmDIALOG_OK_BUTTON))) { Position x = 0, y = 0; /* jog the current one over a bit -- otherwise the new one lands exactly on top of the old! */ XtVaGetValues(vdat->dialog, XmNx, &x, XmNy, &y, NULL); XtVaSetValues(vdat->dialog, XmNx, x + 30, XmNy, y - 30, NULL); vdat = new_view_files_dialog(); make_view_files_dialog_1(vdat, true); } } static void sort_vf(view_files_info *vdat, int sort_choice) { vdat->sorter = sort_choice; vf_reflect_sort_choice_in_menu(vdat); view_files_display_list(vdat); } static void sort_view_files_a_to_z(Widget w, XtPointer context, XtPointer info) { sort_vf((view_files_info *)context, SORT_A_TO_Z); } static void sort_view_files_z_to_a(Widget w, XtPointer context, XtPointer info) { sort_vf((view_files_info *)context, SORT_Z_TO_A); } static void sort_view_files_new_to_old(Widget w, XtPointer context, XtPointer info) { sort_vf((view_files_info *)context, SORT_NEW_TO_OLD); } static void sort_view_files_old_to_new(Widget w, XtPointer context, XtPointer info) { sort_vf((view_files_info *)context, SORT_OLD_TO_NEW); } static void sort_view_files_big_to_small(Widget w, XtPointer context, XtPointer info) { sort_vf((view_files_info *)context, SORT_BIG_TO_SMALL); } static void sort_view_files_small_to_big(Widget w, XtPointer context, XtPointer info) { sort_vf((view_files_info *)context, SORT_SMALL_TO_BIG); } static void sort_view_files_xen(Widget w, XtPointer context, XtPointer info) { pointer_or_int_t index; XtVaGetValues(w, XmNuserData, &index, NULL); /* index is location in list of file-sorters */ sort_vf((view_files_info *)context, (int)index); } static void vf_reflect_sort_choice_in_menu(view_files_info *vdat) { int i; set_sensitive(vdat->a_to_z, vdat->sorter != SORT_A_TO_Z); set_sensitive(vdat->z_to_a, vdat->sorter != SORT_Z_TO_A); set_sensitive(vdat->new_to_old, vdat->sorter != SORT_NEW_TO_OLD); set_sensitive(vdat->old_to_new, vdat->sorter != SORT_OLD_TO_NEW); set_sensitive(vdat->small_to_big, vdat->sorter != SORT_SMALL_TO_BIG); set_sensitive(vdat->big_to_small, vdat->sorter != SORT_BIG_TO_SMALL); for (i = 0; i < vdat->sort_items_size; i++) if (XtIsManaged(vdat->sort_items[i])) set_sensitive(vdat->sort_items[i], vdat->sorter != (SORT_XEN + i)); } static void view_files_add_file_or_directory(view_files_info *vdat, const char *file_or_dir) { char *filename; filename = mus_expand_filename((const char *)file_or_dir); if (filename) { int len; len = strlen(filename); if (filename[len - 1] == '*') filename[len - 1] = 0; if (is_directory(filename)) add_directory_to_view_files_list(vdat, (const char *)filename); else add_file_to_view_files_list(vdat, file_or_dir, filename); free(filename); } } static void view_files_add_files(Widget w, XtPointer context, XtPointer info) { view_files_info *vdat = (view_files_info *)context; char *file_or_dir; file_or_dir = XmTextFieldGetString(w); if ((file_or_dir) && (*file_or_dir)) { view_files_add_file_or_directory(vdat, (const char *)file_or_dir); XtFree(file_or_dir); view_files_display_list(vdat); } } static void view_files_drop_watcher(Widget w, const char *str, Position x, Position y, void *context) { view_files_info *vdat = (view_files_info *)context; /* incoming str is a single filename (drop watcher code splits the possible list and calls us on each one) */ view_files_add_file_or_directory(vdat, str); view_files_display_list(vdat); } static void view_files_drag_watcher(Widget w, const char *str, Position x, Position y, drag_style_t dtype, void *context) { view_files_info *vdat = (view_files_info *)context; switch (dtype) { case DRAG_ENTER: XmChangeColor(vdat->file_list, ss->selection_color); break; case DRAG_LEAVE: XmChangeColor(vdat->file_list, ss->basic_color); break; default: break; } } static mus_long_t vf_location(view_files_info *vdat) { mus_long_t pos = 0; snd_info *sp; chan_info *cp; char *str; switch (vdat->location_choice) { case VF_AT_CURSOR: sp = any_selected_sound(); if (sp) { cp = any_selected_channel(sp); return(cursor_sample(cp)); } break; case VF_AT_END: sp = any_selected_sound(); if (sp) { cp = any_selected_channel(sp); return(current_samples(cp)); } break; case VF_AT_BEGINNING: return(0); break; case VF_AT_MARK: str = XmTextGetString(vdat->at_mark_text); if ((str) && (*str)) { pos = mark_id_to_sample(string_to_int(str, 0, "mark")); XtFree(str); if (pos < 0) snd_error_without_format("no such mark"); } else snd_error_without_format("no mark?"); break; case VF_AT_SAMPLE: str = XmTextGetString(vdat->at_sample_text); if ((str) && (*str)) { pos = string_to_mus_long_t(str, 0, "sample"); XtFree(str); /* pos already checked for lower bound */ } else snd_error_without_format("no sample number?"); break; } return(pos); } static void vf_clear_sample(view_files_info *vdat); static void vf_sample_button_modify_callback(Widget w, XtPointer context, XtPointer info) { vf_clear_sample((view_files_info *)context); } static void vf_sample_text_modify_callback(Widget w, XtPointer context, XtPointer info) { XmTextVerifyCallbackStruct *cbs = (XmTextVerifyCallbackStruct *)info; vf_clear_sample((view_files_info *)context); cbs->doit = true; } static void vf_clear_sample(view_files_info *vdat) { vf_clear_error(vdat); XtRemoveCallback(vdat->at_sample_text, XmNmodifyVerifyCallback, vf_sample_text_modify_callback, (XtPointer)vdat); XtRemoveCallback(vdat->at_sample_button, XmNvalueChangedCallback, vf_sample_button_modify_callback, (XtPointer)vdat); } static void vf_clear_mark(view_files_info *vdat); static void vf_mark_button_modify_callback(Widget w, XtPointer context, XtPointer info) { vf_clear_mark((view_files_info *)context); } static void vf_mark_text_modify_callback(Widget w, XtPointer context, XtPointer info) { XmTextVerifyCallbackStruct *cbs = (XmTextVerifyCallbackStruct *)info; vf_clear_mark((view_files_info *)context); cbs->doit = true; } static void vf_clear_mark(view_files_info *vdat) { vf_clear_error(vdat); XtRemoveCallback(vdat->at_mark_text, XmNmodifyVerifyCallback, vf_mark_text_modify_callback, (XtPointer)vdat); XtRemoveCallback(vdat->at_mark_button, XmNvalueChangedCallback, vf_mark_button_modify_callback, (XtPointer)vdat); } static void vf_add_text_modify_callback(Widget w, XtPointer context, XtPointer info); static void remove_all_pending_clear_callbacks(view_files_info *vdat) { /* docs say this is a no-op if the indicated callback does not exist (i.e. not an error or segfault) */ XtRemoveCallback(vdat->at_mark_text, XmNmodifyVerifyCallback, vf_mark_text_modify_callback, (XtPointer)vdat); XtRemoveCallback(vdat->at_mark_button, XmNvalueChangedCallback, vf_mark_button_modify_callback, (XtPointer)vdat); XtRemoveCallback(vdat->at_sample_text, XmNmodifyVerifyCallback, vf_sample_text_modify_callback, (XtPointer)vdat); XtRemoveCallback(vdat->at_sample_button, XmNvalueChangedCallback, vf_sample_button_modify_callback, (XtPointer)vdat); XtRemoveCallback(vdat->add_text, XmNmodifyVerifyCallback, vf_add_text_modify_callback, (XtPointer)vdat); } static void vf_post_error(const char *error_msg, view_files_info *vdat) { XmString msg; remove_all_pending_clear_callbacks(vdat); vdat->has_error = true; msg = XmStringCreateLocalized((char *)error_msg); XtVaSetValues(vdat->info1, XmNlabelString, msg, NULL); XmStringFree(msg); msg = XmStringCreateLocalized((char *)""); XtVaSetValues(vdat->info2, XmNlabelString, msg, NULL); XmStringFree(msg); } static void redirect_vf_post_error(const char *error_msg, void *vdat) { vf_post_error(error_msg, (view_files_info *)vdat); } static void redirect_vf_post_location_error(const char *error_msg, void *data) { view_files_info *vdat = (view_files_info *)data; vf_post_error(error_msg, vdat); if (vdat->location_choice == VF_AT_SAMPLE) { /* watch at_sample_text or button (undo) */ XtAddCallback(vdat->at_sample_text, XmNmodifyVerifyCallback, vf_sample_text_modify_callback, (XtPointer)vdat); XtAddCallback(vdat->at_sample_button, XmNvalueChangedCallback, vf_sample_button_modify_callback, (XtPointer)vdat); } else { /* watch at_mark_text or button */ XtAddCallback(vdat->at_mark_text, XmNmodifyVerifyCallback, vf_mark_text_modify_callback, (XtPointer)vdat); XtAddCallback(vdat->at_mark_button, XmNvalueChangedCallback, vf_mark_button_modify_callback, (XtPointer)vdat); } } static void vf_add_text_modify_callback(Widget w, XtPointer context, XtPointer info) { XmTextVerifyCallbackStruct *cbs = (XmTextVerifyCallbackStruct *)info; view_files_info *vdat = (view_files_info *)context; vf_clear_error(vdat); XtRemoveCallback(vdat->add_text, XmNmodifyVerifyCallback, vf_add_text_modify_callback, (XtPointer)vdat); cbs->doit = true; } static void vf_post_add_error(const char *error_msg, view_files_info *vdat) { vf_post_error(error_msg, vdat); XtAddCallback(vdat->add_text, XmNmodifyVerifyCallback, vf_add_text_modify_callback, (XtPointer)vdat); /* what about other clearing actions? */ } static void view_files_mix_selected_callback(Widget w, XtPointer context, XtPointer info) { view_files_mix_selected_files(w, (view_files_info *)context); } static void view_files_insert_selected_callback(Widget w, XtPointer context, XtPointer info) { view_files_insert_selected_files(w, (view_files_info *)context); } static void view_files_at_cursor_callback(Widget w, XtPointer context, XtPointer info) { view_files_info *vdat = (view_files_info *)context; if (vdat->has_error) { if (vdat->location_choice == VF_AT_SAMPLE) vf_clear_sample(vdat); else vf_clear_mark(vdat); } XmToggleButtonSetState(vdat->at_cursor_button, true, false); XmToggleButtonSetState(vdat->at_end_button, false, false); XmToggleButtonSetState(vdat->at_beginning_button, false, false); XmToggleButtonSetState(vdat->at_mark_button, false, false); XmToggleButtonSetState(vdat->at_sample_button, false, false); vdat->location_choice = VF_AT_CURSOR; } static void view_files_at_end_callback(Widget w, XtPointer context, XtPointer info) { view_files_info *vdat = (view_files_info *)context; if (vdat->has_error) { if (vdat->location_choice == VF_AT_SAMPLE) vf_clear_sample(vdat); else vf_clear_mark(vdat); } XmToggleButtonSetState(vdat->at_cursor_button, false, false); XmToggleButtonSetState(vdat->at_end_button, true, false); XmToggleButtonSetState(vdat->at_beginning_button, false, false); XmToggleButtonSetState(vdat->at_mark_button, false, false); XmToggleButtonSetState(vdat->at_sample_button, false, false); vdat->location_choice = VF_AT_END; } static void view_files_at_beginning_callback(Widget w, XtPointer context, XtPointer info) { view_files_info *vdat = (view_files_info *)context; if (vdat->has_error) { if (vdat->location_choice == VF_AT_SAMPLE) vf_clear_sample(vdat); else vf_clear_mark(vdat); } XmToggleButtonSetState(vdat->at_cursor_button, false, false); XmToggleButtonSetState(vdat->at_end_button, false, false); XmToggleButtonSetState(vdat->at_beginning_button, true, false); XmToggleButtonSetState(vdat->at_mark_button, false, false); XmToggleButtonSetState(vdat->at_sample_button, false, false); vdat->location_choice = VF_AT_BEGINNING; } static void view_files_at_sample_callback(Widget w, XtPointer context, XtPointer info) { view_files_info *vdat = (view_files_info *)context; if ((vdat->has_error) && (vdat->location_choice == VF_AT_MARK)) vf_clear_mark(vdat); XmToggleButtonSetState(vdat->at_cursor_button, false, false); XmToggleButtonSetState(vdat->at_end_button, false, false); XmToggleButtonSetState(vdat->at_beginning_button, false, false); XmToggleButtonSetState(vdat->at_mark_button, false, false); XmToggleButtonSetState(vdat->at_sample_button, true, false); vdat->location_choice = VF_AT_SAMPLE; } static void view_files_at_mark_callback(Widget w, XtPointer context, XtPointer info) { view_files_info *vdat = (view_files_info *)context; if ((vdat->has_error) && (vdat->location_choice == VF_AT_SAMPLE)) vf_clear_sample(vdat); XmToggleButtonSetState(vdat->at_cursor_button, false, false); XmToggleButtonSetState(vdat->at_end_button, false, false); XmToggleButtonSetState(vdat->at_beginning_button, false, false); XmToggleButtonSetState(vdat->at_mark_button, true, false); XmToggleButtonSetState(vdat->at_sample_button, false, false); vdat->location_choice = VF_AT_MARK; } /* -------- speed -------- */ static int vf_speed_to_scroll(mus_float_t minval, mus_float_t val, mus_float_t maxval) { if (val <= minval) return(0); if (val >= maxval) return((int)(0.9 * SCROLLBAR_MAX)); return(snd_round(0.9 * SCROLLBAR_MAX * ((log(val) - log(minval)) / (log(maxval) - log(minval))))); } static void vf_set_speed(view_files_info *vdat, mus_float_t val) { char speed_number_buffer[6]; vdat->speed = speed_changed(val, speed_number_buffer, vdat->speed_style, speed_control_tones(ss), 6); set_label(vdat->speed_number, speed_number_buffer); XtVaSetValues(vdat->speed_scrollbar, XmNvalue, vf_speed_to_scroll(speed_control_min(ss), val, speed_control_max(ss)), NULL); } static void vf_speed_click_callback(Widget w, XtPointer context, XtPointer info) { view_files_info *vdat = (view_files_info *)context; vf_set_speed(vdat, 1.0); XtVaSetValues(vdat->speed_scrollbar, XmNvalue, vf_speed_to_scroll(speed_control_min(ss), 1.0, speed_control_max(ss)), NULL); } static void vf_speed_label_click_callback(Widget w, XtPointer context, XtPointer info) { char speed_number_buffer[6]; view_files_info *vdat = (view_files_info *)context; switch (vdat->speed_style) { default: case SPEED_CONTROL_AS_FLOAT: vdat->speed_style = SPEED_CONTROL_AS_RATIO; break; case SPEED_CONTROL_AS_RATIO: vdat->speed_style = SPEED_CONTROL_AS_SEMITONE; break; case SPEED_CONTROL_AS_SEMITONE: vdat->speed_style = SPEED_CONTROL_AS_FLOAT; break; } speed_changed(vdat->speed, speed_number_buffer, vdat->speed_style, speed_control_tones(ss), 6); set_label(vdat->speed_number, speed_number_buffer); } static void vf_speed_valuechanged_callback(Widget w, XtPointer context, XtPointer info) { view_files_info *vdat = (view_files_info *)context; XmScrollBarCallbackStruct *cb = (XmScrollBarCallbackStruct *)info; vf_set_speed(vdat, exp((cb->value * (log(speed_control_max(ss)) - log(speed_control_min(ss))) / (0.9 * SCROLLBAR_MAX)) + log(speed_control_min(ss)))); } static void vf_speed_drag_callback(Widget w, XtPointer context, XtPointer info) { view_files_info *vdat = (view_files_info *)context; XmScrollBarCallbackStruct *cb = (XmScrollBarCallbackStruct *)info; vf_set_speed(vdat, exp((cb->value * (log(speed_control_max(ss)) - log(speed_control_min(ss))) / (0.9 * SCROLLBAR_MAX)) + log(speed_control_min(ss)))); } /* -------- amp -------- */ static mus_float_t vf_scroll_to_amp(int val) { if (val <= 0) return(amp_control_min(ss)); if (val >= (0.9 * SCROLLBAR_MAX)) return(amp_control_max(ss)); if (val > (0.5 * 0.9 * SCROLLBAR_MAX)) return((((val / (0.5 * 0.9 * SCROLLBAR_MAX)) - 1.0) * (amp_control_max(ss) - 1.0)) + 1.0); else return((val * (1.0 - amp_control_min(ss)) / (0.5 * 0.9 * SCROLLBAR_MAX)) + amp_control_min(ss)); } static int vf_amp_to_scroll(mus_float_t amp) { return(amp_to_scroll(amp_control_min(ss), amp, amp_control_max(ss))); } static void vf_set_amp(view_files_info *vdat, mus_float_t val) { char sfs[6]; vdat->amp = val; snprintf(sfs, 6, "%.2f", val); set_label(vdat->amp_number, sfs); XtVaSetValues(vdat->amp_scrollbar, XmNvalue, amp_to_scroll(amp_control_min(ss), val, amp_control_max(ss)), NULL); } static void vf_amp_click_callback(Widget w, XtPointer context, XtPointer info) { vf_set_amp((view_files_info *)context, 1.0); } static void vf_amp_valuechanged_callback(Widget w, XtPointer context, XtPointer info) { vf_set_amp((view_files_info *)context, vf_scroll_to_amp(((XmScrollBarCallbackStruct *)info)->value)); } static void vf_amp_drag_callback(Widget w, XtPointer context, XtPointer info) { vf_set_amp((view_files_info *)context, vf_scroll_to_amp(((XmScrollBarCallbackStruct *)info)->value)); } /* -------- amp-envs -------- */ static void vf_amp_env_resize(Widget w, XtPointer context, XtPointer info) { view_files_info *vdat = (view_files_info *)context; if (vdat->env_ax == NULL) { XGCValues gv; gv.function = GXcopy; XtVaGetValues(vdat->env_drawer, XmNbackground, &gv.background, XmNforeground, &gv.foreground, NULL); vdat->env_gc = XtGetGC(vdat->env_drawer, GCForeground | GCFunction, &gv); vdat->env_ax = (graphics_context *)calloc(1, sizeof(graphics_context)); vdat->env_ax->wn = XtWindow(vdat->env_drawer); vdat->env_ax->dp = XtDisplay(vdat->env_drawer); vdat->env_ax->gc = vdat->env_gc; if (!(vdat->env_ax->wn)) return; } else { if (!(vdat->env_ax->wn)) { vdat->env_ax->wn = XtWindow(vdat->env_drawer); /* sometimes the dialog window is not ready when display_env gets called */ if (!(vdat->env_ax->wn)) return; } clear_window(vdat->env_ax); } vdat->spf->with_dots = true; env_editor_display_env(vdat->spf, vdat->amp_env, vdat->env_ax, "amp env", 0, 0, widget_width(w), widget_height(w), NOT_PRINTING); /* it might be nice to show the sound data in the background, but there are * complications involving multichannel and multiselection cases, also * how to get the "peak-func" and how to call g_channel_amp_envs. * Too many problems... * but perhaps something like the region browser display would work: * label saying file+chan and up/down arrows to see the rest + off button */ } static void vf_amp_env_redraw(Widget w, view_files_info *vdat) { vf_amp_env_resize(w, (void *)vdat, NULL); } static void vf_drawer_button_motion(Widget w, XtPointer context, XEvent *event, Boolean *cont) { view_files_info *vdat = (view_files_info *)context; XMotionEvent *ev = (XMotionEvent *)event; /* mus_float_t pos; */ #ifdef __APPLE__ if ((press_x == ev->x) && (press_y == ev->y)) return; #endif /* pos = (mus_float_t)(ev->x) / (mus_float_t)widget_width(w); */ env_editor_button_motion(vdat->spf, ev->x, ev->y, ev->time, vdat->amp_env); vf_amp_env_resize(w, context, NULL); } static void vf_drawer_button_press(Widget w, XtPointer context, XEvent *event, Boolean *cont) { view_files_info *vdat = (view_files_info *)context; XButtonEvent *ev = (XButtonEvent *)event; /* mus_float_t pos; */ #ifdef __APPLE__ press_x = ev->x; press_y = ev->y; #endif /* pos = (mus_float_t)(ev->x) / (mus_float_t)widget_width(w); */ if (env_editor_button_press(vdat->spf, ev->x, ev->y, ev->time, vdat->amp_env)) vf_amp_env_resize(w, context, NULL); } static void vf_drawer_button_release(Widget w, XtPointer context, XEvent *event, Boolean *cont) { view_files_info *vdat = (view_files_info *)context; /* XButtonEvent *ev = (XButtonEvent *)event; */ /* mus_float_t pos; */ /* pos = (mus_float_t)(ev->x) / (mus_float_t)widget_width(w); */ env_editor_button_release(vdat->spf, vdat->amp_env); vf_amp_env_resize(w, context, NULL); } static void vf_set_amp_env(view_files_info *vdat, env *new_e) { if (!vdat) return; if (vdat->amp_env) free_env(vdat->amp_env); vdat->amp_env = copy_env(new_e); if ((vdat->dialog) && (widget_is_active(vdat->dialog))) vf_amp_env_redraw(vdat->env_drawer, vdat); } static void blue_textfield_unfocus_callback(Widget w, XtPointer context, XtPointer info) { XtVaSetValues(w, XmNbackground, ss->lighter_blue, NULL); XtVaSetValues(w, XmNcursorPositionVisible, false, NULL); } static void blue_mouse_leave_text_callback(Widget w, XtPointer context, XEvent *event, Boolean *flag) { XtVaSetValues(w, XmNbackground, ss->lighter_blue, NULL); XtVaSetValues(w, XmNcursorPositionVisible, false, NULL); } static void white_mouse_enter_text_callback(Widget w, XtPointer context, XEvent *event, Boolean *flag) { XtVaSetValues(w, XmNbackground, ss->text_focus_color, NULL); XtVaSetValues(w, XmNcursorPositionVisible, true, NULL); } static void view_files_reset_callback(Widget w, XtPointer context, XtPointer info) { view_files_info *vdat = (view_files_info *)context; env *e; vf_set_amp(vdat, 1.0); vf_set_speed(vdat, 1.0); vf_set_amp_env(vdat, e = default_env(1.0, 1.0)); /* vf_set_amp_env copies the envelope */ free_env(e); sort_vf(vdat, view_files_sort(ss)); } static widget_t make_view_files_dialog_1(view_files_info *vdat, bool managed) { if (!(vdat->dialog)) { int i, n; Arg args[20]; XmString go_away, xhelp, titlestr, new_viewer_str, s1, bstr; Widget mainform, viewform, leftform, reset_button, new_viewer_button; Widget left_title_sep, add_label, sep1, sep3, sep4, sep6, sep7; #if WITH_AUDIO Widget plw; #endif Widget rlw, sbar; XtCallbackList n1, n2, n3, n4; Widget amp_label, speed_label, env_frame; Widget bframe, bform; go_away = XmStringCreateLocalized((char *)I_GO_AWAY); xhelp = XmStringCreateLocalized((char *)I_HELP); new_viewer_str = XmStringCreateLocalized((char *)"New Viewer"); { char *filestr = NULL; filestr = mus_format("%s %d", "Files", vdat->index + 1); titlestr = XmStringCreateLocalized(filestr); free(filestr); } n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNhelpLabelString, xhelp); n++; XtSetArg(args[n], XmNokLabelString, new_viewer_str); n++; XtSetArg(args[n], XmNcancelLabelString, go_away); n++; XtSetArg(args[n], XmNautoUnmanage, false); n++; XtSetArg(args[n], XmNdialogTitle, titlestr); n++; XtSetArg(args[n], XmNresizePolicy, XmRESIZE_GROW); n++; XtSetArg(args[n], XmNnoResize, false); n++; XtSetArg(args[n], XmNtransient, false); n++; vdat->dialog = XmCreateTemplateDialog(MAIN_SHELL(ss), (char *)"Files", args, n); new_viewer_button = MSG_BOX(vdat->dialog, XmDIALOG_OK_BUTTON); XtAddCallback(vdat->dialog, XmNhelpCallback, view_files_help_callback, (XtPointer)vdat); /* XtAddCallback(vdat->dialog, XmNokCallback, view_files_new_viewer_callback, (XtPointer)vdat); */ XtAddCallback(new_viewer_button, XmNactivateCallback, view_files_new_viewer_callback, (XtPointer)vdat); XtAddCallback(vdat->dialog, XmNcancelCallback, view_files_quit_callback, (XtPointer)vdat); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNarmColor, ss->selection_color); n++; reset_button = XtCreateManagedWidget("Reset", xmPushButtonGadgetClass, vdat->dialog, args, n); XtAddCallback(reset_button, XmNactivateCallback, view_files_reset_callback, (XtPointer)vdat); XmStringFree(xhelp); XmStringFree(go_away); XmStringFree(titlestr); XmStringFree(new_viewer_str); XtVaSetValues(MSG_BOX(vdat->dialog, XmDIALOG_OK_BUTTON), XmNarmColor, ss->selection_color, NULL); XtVaSetValues(MSG_BOX(vdat->dialog, XmDIALOG_HELP_BUTTON), XmNarmColor, ss->selection_color, NULL); XtVaSetValues(MSG_BOX(vdat->dialog, XmDIALOG_CANCEL_BUTTON), XmNarmColor, ss->selection_color, NULL); XtVaSetValues(MSG_BOX(vdat->dialog, XmDIALOG_OK_BUTTON), XmNbackground, ss->highlight_color, NULL); XtVaSetValues(MSG_BOX(vdat->dialog, XmDIALOG_HELP_BUTTON), XmNbackground, ss->highlight_color, NULL); XtVaSetValues(MSG_BOX(vdat->dialog, XmDIALOG_CANCEL_BUTTON), XmNbackground, ss->highlight_color, NULL); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNbottomWidget, MSG_BOX(vdat->dialog, XmDIALOG_SEPARATOR)); n++; XtSetArg(args[n], XmNsashIndent, 2); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNspacing, 24); n++; XtSetArg(args[n], XmNpaneMaximum, LOTSA_PIXELS); n++; mainform = XtCreateManagedWidget("formd", xmPanedWindowWidgetClass, vdat->dialog, args, n); /* -------- left side controls -------- */ n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; leftform = XtCreateManagedWidget("leftform", xmFormWidgetClass, mainform, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_CENTER); n++; vdat->left_title = XtCreateManagedWidget("(no files selected)", xmLabelWidgetClass, leftform, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->white); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, vdat->left_title); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNseparatorType, XmDOUBLE_LINE); n++; left_title_sep = XtCreateManagedWidget("sep", xmSeparatorWidgetClass, leftform, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, left_title_sep); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; vdat->info1 = XtCreateManagedWidget("|", xmLabelWidgetClass, leftform, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, vdat->info1); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; vdat->info2 = XtCreateManagedWidget("|", xmLabelWidgetClass, leftform, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, vdat->info2); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNheight, 8); n++; XtSetArg(args[n], XmNseparatorType, XmNO_LINE); n++; sep6 = XtCreateManagedWidget("dialog-sep1", xmSeparatorWidgetClass, leftform, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->zoom_color); n++; XtSetArg(args[n], XmNborderColor, ss->zoom_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, sep6); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNborderWidth, 2); n++; bframe = XtCreateManagedWidget("bframe", xmFrameWidgetClass, leftform, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->position_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; bform = XtCreateManagedWidget("bform", xmFormWidgetClass, bframe, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNmarginTop, 0); n++; XtSetArg(args[n], XmNmarginBottom, 0); n++; XtSetArg(args[n], XmNshadowThickness, 1); n++; XtSetArg(args[n], XmNhighlightThickness, 1); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n++; XtSetArg(args[n], XmNrightPosition, 50); n++; vdat->mixB = XtCreateManagedWidget("Mix", xmPushButtonWidgetClass, bform, args, n); XtAddCallback(vdat->mixB, XmNactivateCallback, view_files_mix_selected_callback, (XtPointer)vdat); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNmarginTop, 0); n++; XtSetArg(args[n], XmNmarginBottom, 0); n++; XtSetArg(args[n], XmNshadowThickness, 1); n++; XtSetArg(args[n], XmNhighlightThickness, 1); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, vdat->mixB); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; vdat->insertB = XtCreateManagedWidget("Insert", xmPushButtonWidgetClass, bform, args, n); XtAddCallback(vdat->insertB, XmNactivateCallback, view_files_insert_selected_callback, (XtPointer)vdat); n = 0; XtSetArg(args[n], XmNbackground, ss->lighter_blue); n++; XtSetArg(args[n], XmNselectColor, ss->red); n++; bstr = XmStringCreateLocalized((char *)"at cursor"); XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, vdat->mixB); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNlabelString, bstr); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(args[n], XmNindicatorType, XmONE_OF_MANY); n++; XtSetArg(args[n], XmNset, XmSET); n++; vdat->at_cursor_button = make_togglebutton_widget("at-cursor-button", bform, args, n); XtAddCallback(vdat->at_cursor_button, XmNdisarmCallback, view_files_at_cursor_callback, (XtPointer)vdat); XmStringFree(bstr); n = 0; XtSetArg(args[n], XmNbackground, ss->lighter_blue); n++; XtSetArg(args[n], XmNselectColor, ss->red); n++; bstr = XmStringCreateLocalized((char *)"at end"); XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, vdat->at_cursor_button); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNlabelString, bstr); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(args[n], XmNindicatorType, XmONE_OF_MANY); n++; vdat->at_end_button = make_togglebutton_widget("at-end-button", bform, args, n); XtAddCallback(vdat->at_end_button, XmNdisarmCallback, view_files_at_end_callback, (XtPointer)vdat); XmStringFree(bstr); n = 0; XtSetArg(args[n], XmNbackground, ss->lighter_blue); n++; XtSetArg(args[n], XmNselectColor, ss->red); n++; bstr = XmStringCreateLocalized((char *)"at beginning"); XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, vdat->at_end_button); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNlabelString, bstr); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(args[n], XmNindicatorType, XmONE_OF_MANY); n++; vdat->at_beginning_button = make_togglebutton_widget("at-beginning-button", bform, args, n); XtAddCallback(vdat->at_beginning_button, XmNdisarmCallback, view_files_at_beginning_callback, (XtPointer)vdat); XmStringFree(bstr); n = 0; XtSetArg(args[n], XmNbackground, ss->lighter_blue); n++; XtSetArg(args[n], XmNselectColor, ss->red); n++; bstr = XmStringCreateLocalized((char *)"at sample"); XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n++; XtSetArg(args[n], XmNrightPosition, 50); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, vdat->at_beginning_button); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNlabelString, bstr); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(args[n], XmNindicatorType, XmONE_OF_MANY); n++; vdat->at_sample_button = make_togglebutton_widget("at-sample-button", bform, args, n); XtAddCallback(vdat->at_sample_button, XmNdisarmCallback, view_files_at_sample_callback, (XtPointer)vdat); XmStringFree(bstr); n = 0; XtSetArg(args[n], XmNbackground, ss->lighter_blue); n++; XtSetArg(args[n], XmNborderWidth, 0); n++; XtSetArg(args[n], XmNshadowThickness, 0); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, vdat->at_beginning_button); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNbottomWidget, vdat->at_sample_button); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, vdat->at_sample_button); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; vdat->at_sample_text = make_textfield_widget("at-sample-text", bform, args, n, NOT_ACTIVATABLE, NO_COMPLETER); XtRemoveCallback(vdat->at_sample_text, XmNlosingFocusCallback, textfield_unfocus_callback, NULL); XtAddCallback(vdat->at_sample_text, XmNlosingFocusCallback, blue_textfield_unfocus_callback, NULL); XtAddEventHandler(vdat->at_sample_text, LeaveWindowMask, false, blue_mouse_leave_text_callback, NULL); XtAddEventHandler(vdat->at_sample_text, EnterWindowMask, false, white_mouse_enter_text_callback, NULL); n = 0; XtSetArg(args[n], XmNbackground, ss->lighter_blue); n++; XtSetArg(args[n], XmNselectColor, ss->red); n++; bstr = XmStringCreateLocalized((char *)"at mark"); XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n++; XtSetArg(args[n], XmNrightPosition, 50); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, vdat->at_sample_button); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNlabelString, bstr); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(args[n], XmNindicatorType, XmONE_OF_MANY); n++; vdat->at_mark_button = make_togglebutton_widget("at-mark-button", bform, args, n); XtAddCallback(vdat->at_mark_button, XmNdisarmCallback, view_files_at_mark_callback, (XtPointer)vdat); XmStringFree(bstr); n = 0; XtSetArg(args[n], XmNbackground, ss->lighter_blue); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, vdat->at_sample_text); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, vdat->at_mark_button); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNborderWidth, 0); n++; XtSetArg(args[n], XmNshadowThickness, 0); n++; vdat->at_mark_text = make_textfield_widget("at-mark-text", bform, args, n, NOT_ACTIVATABLE, NO_COMPLETER); XtRemoveCallback(vdat->at_mark_text, XmNlosingFocusCallback, textfield_unfocus_callback, NULL); XtAddCallback(vdat->at_mark_text, XmNlosingFocusCallback, blue_textfield_unfocus_callback, NULL); XtAddEventHandler(vdat->at_mark_text, LeaveWindowMask, false, blue_mouse_leave_text_callback, NULL); XtAddEventHandler(vdat->at_mark_text, EnterWindowMask, false, white_mouse_enter_text_callback, NULL); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, bframe); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNseparatorType, XmNO_LINE); n++; XtSetArg(args[n], XmNheight, 8); n++; sep4 = XtCreateManagedWidget("sep4", xmSeparatorWidgetClass, leftform, args, n); n = 0; /* AMP */ s1 = XmStringCreateLocalized((char *)"amp:"); XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, sep4); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNlabelString, s1); n++; /* XtSetArg(args[n], XmNmarginHeight, CONTROLS_MARGIN); n++; */ XtSetArg(args[n], XmNrecomputeSize, false); n++; XtSetArg(args[n], XmNshadowThickness, 0); n++; XtSetArg(args[n], XmNhighlightThickness, 0); n++; XtSetArg(args[n], XmNfillOnArm, false); n++; amp_label = make_pushbutton_widget("amp-label", leftform, args, n); XtAddCallback(amp_label, XmNactivateCallback, vf_amp_click_callback, (XtPointer)vdat); XmStringFree(s1); n = 0; s1 = XmStringCreateLocalized((char *)"1.0 "); XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, sep4); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, amp_label); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; /* XtSetArg(args[n], XmNmarginHeight, CONTROLS_MARGIN); n++; */ XtSetArg(args[n], XmNrecomputeSize, false); n++; XtSetArg(args[n], XmNlabelString, s1); n++; /* XtSetArg(args[n], XmNmarginRight, 3); n++; */ vdat->amp_number = XtCreateManagedWidget("amp-number", xmLabelWidgetClass, leftform, args, n); XmStringFree(s1); n = 0; XtSetArg(args[n], XmNbackground, ss->position_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, sep4); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNheight, 16); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, vdat->amp_number); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNmaximum, SCROLLBAR_MAX); n++; XtSetArg(args[n], XmNvalue, vf_amp_to_scroll(1.0)); n++; XtSetArg(args[n], XmNvalueChangedCallback, n2 = make_callback_list(vf_amp_valuechanged_callback, (XtPointer)vdat)); n++; XtSetArg(args[n], XmNdragCallback, n3 = make_callback_list(vf_amp_drag_callback, (XtPointer)vdat)); n++; vdat->amp_scrollbar = XtCreateManagedWidget("amp-scroll", xmScrollBarWidgetClass, leftform, args, n); n = 0; /* SPEED */ s1 = XmStringCreateLocalized((char *)"speed:"); XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, amp_label); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNlabelString, s1); n++; /* XtSetArg(args[n], XmNmarginHeight, CONTROLS_MARGIN); n++; */ XtSetArg(args[n], XmNrecomputeSize, false); n++; XtSetArg(args[n], XmNshadowThickness, 0); n++; XtSetArg(args[n], XmNhighlightThickness, 0); n++; XtSetArg(args[n], XmNfillOnArm, false); n++; speed_label = make_pushbutton_widget("speed-label", leftform, args, n); XtAddCallback(speed_label, XmNactivateCallback, vf_speed_click_callback, (XtPointer)vdat); XmStringFree(s1); n = 0; s1 = initial_speed_label(speed_control_style(ss)); XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, speed_label); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, speed_label); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNlabelString, s1); n++; /* XtSetArg(args[n], XmNmarginHeight, CONTROLS_MARGIN); n++; */ XtSetArg(args[n], XmNrecomputeSize, false); n++; /* XtSetArg(args[n], XmNmarginRight, 3); n++; */ XtSetArg(args[n], XmNshadowThickness, 0); n++; XtSetArg(args[n], XmNhighlightThickness, 0); n++; XtSetArg(args[n], XmNfillOnArm, false); n++; vdat->speed_number = make_pushbutton_widget("speed-number", leftform, args, n); XtAddCallback(vdat->speed_number, XmNactivateCallback, vf_speed_label_click_callback, (XtPointer)vdat); XmStringFree(s1); n = 0; XtSetArg(args[n], XmNbackground, ss->position_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, vdat->speed_number); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, vdat->speed_number); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNmaximum, SCROLLBAR_MAX); n++; XtSetArg(args[n], XmNvalue, vf_speed_to_scroll(speed_control_min(ss), 1.0, speed_control_max(ss))); n++; XtSetArg(args[n], XmNheight, 16); n++; XtSetArg(args[n], XmNvalueChangedCallback, n4 = make_callback_list(vf_speed_valuechanged_callback, (XtPointer)vdat)); n++; XtSetArg(args[n], XmNdragCallback, n1 = make_callback_list(vf_speed_drag_callback, (XtPointer)vdat)); n++; vdat->speed_scrollbar = XtCreateManagedWidget("speed-scroll", xmScrollBarWidgetClass, leftform, args, n); /* separator before envelope */ n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, speed_label); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNheight, 8); n++; XtSetArg(args[n], XmNseparatorType, XmNO_LINE); n++; sep7 = XtCreateManagedWidget("dialog-sep1", xmSeparatorWidgetClass, leftform, args, n); /* amp env */ n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, sep7); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_POSITION); n++; XtSetArg(args[n], XmNleftPosition, 4); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n++; XtSetArg(args[n], XmNrightPosition, 98); n++; XtSetArg(args[n], XmNheight, 100); n++; XtSetArg(args[n], XmNallowResize, true); n++; XtSetArg(args[n], XmNshadowType, XmSHADOW_ETCHED_IN); n++; XtSetArg(args[n], XmNshadowThickness, 4); n++; env_frame = XtCreateManagedWidget("amp-env-frame", xmFrameWidgetClass, leftform, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNallowResize, true); n++; XtSetArg(args[n], XmNheight, 100); n++; vdat->env_drawer = XtCreateManagedWidget("amp-env-window", xmDrawingAreaWidgetClass, env_frame, args, n); /* right side */ n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; viewform = XtCreateManagedWidget("viewform", xmFormWidgetClass, mainform, args, n); /* Add dir/file text entry at bottom */ n = 0; s1 = XmStringCreateLocalized((char *)"add:"); XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNlabelString, s1); n++; XtSetArg(args[n], XmNshadowThickness, 0); n++; XtSetArg(args[n], XmNhighlightThickness, 0); n++; add_label = XtCreateManagedWidget("add", xmLabelWidgetClass, viewform, args, n); XmStringFree(s1); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, add_label); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; vdat->add_text = make_textfield_widget("add-text", viewform, args, n, ACTIVATABLE, add_completer_func(filename_completer, NULL)); XtAddCallback(vdat->add_text, XmNactivateCallback, view_files_add_files, (XtPointer)vdat); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNbottomWidget, vdat->add_text); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNseparatorType, XmNO_LINE); n++; XtSetArg(args[n], XmNheight, 4); n++; sep3 = XtCreateManagedWidget("sep3", xmSeparatorWidgetClass, viewform, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_CENTER); n++; rlw = XtCreateManagedWidget("files", xmLabelWidgetClass, viewform, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->white); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, rlw); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNseparatorType, XmDOUBLE_LINE); n++; sep1 = XtCreateManagedWidget("sep1", xmSeparatorWidgetClass, viewform, args, n); #if WITH_AUDIO n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_POSITION); n++; XtSetArg(args[n], XmNleftPosition, 5); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, sep1); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; plw = XtCreateManagedWidget("play", xmLabelWidgetClass, viewform, args, n); #endif n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, sep1); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNshadowThickness, 0); n++; XtSetArg(args[n], XmNhighlightThickness, 0); n++; XtSetArg(args[n], XmNmarginHeight, 0); n++; sbar = XmCreateMenuBar(viewform, (char *)"menuBar", args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; vdat->smenu = XmCreatePulldownMenu(sbar, (char *)"sort-menu", args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNsubMenuId, vdat->smenu); n++; XtSetArg(args[n], XmNshadowThickness, 0); n++; XtSetArg(args[n], XmNhighlightThickness, 0); n++; XtSetArg(args[n], XmNmarginHeight, 1); n++; XtCreateManagedWidget("sort", xmCascadeButtonWidgetClass, sbar, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; vdat->a_to_z = XtCreateManagedWidget("a..z", xmPushButtonWidgetClass, vdat->smenu, args, n); vdat->z_to_a = XtCreateManagedWidget("z..a", xmPushButtonWidgetClass, vdat->smenu, args, n); vdat->new_to_old = XtCreateManagedWidget("new..old", xmPushButtonWidgetClass, vdat->smenu, args, n); vdat->old_to_new = XtCreateManagedWidget("old..new", xmPushButtonWidgetClass, vdat->smenu, args, n); vdat->small_to_big = XtCreateManagedWidget("small..big", xmPushButtonWidgetClass, vdat->smenu, args, n); vdat->big_to_small = XtCreateManagedWidget("big..small", xmPushButtonWidgetClass, vdat->smenu, args, n); vdat->sort_items_size = 4; vdat->sort_items = (Widget *)calloc(vdat->sort_items_size, sizeof(Widget)); for (i = 0; i < vdat->sort_items_size; i++) vdat->sort_items[i] = XtCreateWidget("unused", xmPushButtonWidgetClass, vdat->smenu, args, n); XtManageChild(sbar); n = 0; XtSetArg(args[n], XmNleftAttachment, XmATTACH_POSITION); n++; XtSetArg(args[n], XmNleftPosition, 5); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; #if WITH_AUDIO XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, plw); n++; #else XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, sep1); n++; #endif XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNbottomWidget, sep3); n++; XtSetArg(args[n], XmNscrollingPolicy, XmAUTOMATIC); n++; XtSetArg(args[n], XmNscrollBarDisplayPolicy, XmSTATIC); n++; vdat->file_list = XmCreateScrolledWindow(viewform, (char *)"file_list", args, n); n = attach_all_sides(args, 0); vdat->file_list_holder = XtCreateManagedWidget("file_list_holder", xmRowColumnWidgetClass, vdat->file_list, args, n); XtVaSetValues(vdat->file_list, XmNworkWindow, vdat->file_list_holder, NULL); add_drag_and_drop(vdat->file_list, view_files_drop_watcher, view_files_drag_watcher, (void *)vdat); if (managed) view_files_display_list(vdat); XtAddCallback(vdat->a_to_z, XmNactivateCallback, sort_view_files_a_to_z, (XtPointer)vdat); XtAddCallback(vdat->z_to_a, XmNactivateCallback, sort_view_files_z_to_a, (XtPointer)vdat); XtAddCallback(vdat->new_to_old, XmNactivateCallback, sort_view_files_new_to_old, (XtPointer)vdat); XtAddCallback(vdat->old_to_new, XmNactivateCallback, sort_view_files_old_to_new, (XtPointer)vdat); XtAddCallback(vdat->small_to_big, XmNactivateCallback, sort_view_files_small_to_big, (XtPointer)vdat); XtAddCallback(vdat->big_to_small, XmNactivateCallback, sort_view_files_big_to_small, (XtPointer)vdat); vf_reflect_sort_choice_in_menu(vdat); { int i; for (i = 0; i < vdat->sort_items_size; i++) XtAddCallback(vdat->sort_items[i], XmNactivateCallback, sort_view_files_xen, (XtPointer)vdat); } map_over_children(vdat->file_list, set_main_color_of_widget); set_dialog_widget(VIEW_FILES_DIALOG, vdat->dialog); if (managed) XtManageChild(vdat->dialog); XtAddCallback(vdat->env_drawer, XmNresizeCallback, vf_amp_env_resize, (XtPointer)vdat); XtAddCallback(vdat->env_drawer, XmNexposeCallback, vf_amp_env_resize, (XtPointer)vdat); vdat->spf = new_env_editor(); /* one global amp env */ XtAddEventHandler(vdat->env_drawer, ButtonPressMask, false, vf_drawer_button_press, (XtPointer)vdat); XtAddEventHandler(vdat->env_drawer, ButtonMotionMask, false, vf_drawer_button_motion, (XtPointer)vdat); XtAddEventHandler(vdat->env_drawer, ButtonReleaseMask, false, vf_drawer_button_release, (XtPointer)vdat); free(n1); free(n2); free(n3); free(n4); vf_mix_insert_buttons_set_sensitive(vdat, false); } else { if (managed) { if (!XtIsManaged(vdat->dialog)) XtManageChild(vdat->dialog); raise_dialog(vdat->dialog); view_files_display_list(vdat); } } if (managed) { vf_amp_env_resize(vdat->env_drawer, (XtPointer)vdat, NULL); view_files_reflect_sort_items(); } return(vdat->dialog); } /* -------- view-files variables -------- */ static Xen g_view_files_dialog(Xen managed, Xen make_new) { #define H_view_files_dialog "(" S_view_files_dialog " :optional managed create-new-dialog): start the View Files dialog" Xen_check_type(Xen_is_boolean_or_unbound(managed), managed, 1, S_view_files_dialog, "a boolean"); return(Xen_wrap_widget(make_view_files_dialog(Xen_boolean_to_C_bool(managed), Xen_is_true(make_new)))); } static Xen g_add_directory_to_view_files_list(Xen directory, Xen dialog) { #define H_add_directory_to_view_files_list "(" S_add_directory_to_view_files_list " dir :optional w): adds any sound files in 'dir' to the View:Files dialog" Xen_check_type(Xen_is_string(directory), directory, 1, S_add_directory_to_view_files_list, "a string"); Xen_check_type(Xen_is_widget(dialog) || !Xen_is_bound(dialog), dialog, 2, S_add_directory_to_view_files_list, "a view-files dialog widget"); if (!Xen_is_bound(dialog)) view_files_add_directory(NULL_WIDGET, Xen_string_to_C_string(directory)); else view_files_add_directory((widget_t)(Xen_unwrap_widget(dialog)), Xen_string_to_C_string(directory)); return(directory); } static Xen g_add_file_to_view_files_list(Xen file, Xen dialog) { #define H_add_file_to_view_files_list "(" S_add_file_to_view_files_list " file :optional w): adds file to the View:Files dialog's list" char *name = NULL; Xen_check_type(Xen_is_string(file), file, 1, S_add_file_to_view_files_list, "a string"); Xen_check_type(Xen_is_widget(dialog) || !Xen_is_bound(dialog), dialog, 2, S_add_file_to_view_files_list, "a view-files dialog widget"); name = mus_expand_filename(Xen_string_to_C_string(file)); if (mus_file_probe(name)) { if (!Xen_is_bound(dialog)) view_files_add_file(NULL_WIDGET, name); else view_files_add_file((widget_t)(Xen_unwrap_widget(dialog)), name); } if (name) free(name); return(file); } static Xen g_view_files_sort(Xen dialog) { #define H_view_files_sort "(" S_view_files_sort " :optional dialog): sort choice in View:files dialog." if (Xen_is_bound(dialog)) { Xen_check_type(Xen_is_widget(dialog), dialog, 1, S_view_files_sort, "a view-files dialog widget"); return(C_int_to_Xen_integer(view_files_local_sort((widget_t)(Xen_unwrap_widget(dialog))))); } return(C_int_to_Xen_integer(view_files_sort(ss))); } static Xen g_set_view_files_sort(Xen dialog, Xen val) { int choice; Xen sort_choice; if (Xen_is_bound(val)) sort_choice = val; else sort_choice = dialog; Xen_check_type(Xen_is_integer(sort_choice), sort_choice, 1, S_set S_view_files_sort, "an integer"); choice = Xen_integer_to_C_int(sort_choice); if ((choice < 0) || (choice >= (ss->file_sorters_size + SORT_XEN))) Xen_out_of_range_error(S_set S_view_files_sort, 2, sort_choice, "must be a valid file-sorter index"); if (Xen_is_bound(val)) { widget_t w; Xen_check_type(Xen_is_widget(dialog), dialog, 1, S_set S_view_files_sort, "a view-files dialog widget"); w = (widget_t)(Xen_unwrap_widget(dialog)); view_files_set_local_sort(w, choice); return(C_int_to_Xen_integer((int)view_files_sort(ss))); } /* else set global (default) sort choice */ set_view_files_sort(choice); return(C_int_to_Xen_integer((int)view_files_sort(ss))); } static Xen g_view_files_amp(Xen dialog) { #define H_view_files_amp "(" S_view_files_amp " dialog): amp setting in the given View:Files dialog" Xen_check_type(Xen_is_widget(dialog), dialog, 1, S_view_files_amp, "a view-files dialog widget"); return(C_double_to_Xen_real(view_files_amp((widget_t)(Xen_unwrap_widget(dialog))))); } static Xen g_view_files_set_amp(Xen dialog, Xen amp) { Xen_check_type(Xen_is_widget(dialog), dialog, 1, S_set S_view_files_amp, "a view-files dialog widget"); Xen_check_type(Xen_is_number(amp), amp, 2, S_set S_view_files_amp, "a number"); view_files_set_amp((widget_t)(Xen_unwrap_widget(dialog)), Xen_real_to_C_double(amp)); return(amp); } static Xen g_view_files_speed(Xen dialog) { #define H_view_files_speed "(" S_view_files_speed " dialog): speed setting in the given View:Files dialog" Xen_check_type(Xen_is_widget(dialog), dialog, 1, S_view_files_speed, "a view-files dialog widget"); return(C_double_to_Xen_real(view_files_speed((widget_t)(Xen_unwrap_widget(dialog))))); } static Xen g_view_files_set_speed(Xen dialog, Xen speed) { Xen_check_type(Xen_is_widget(dialog), dialog, 1, S_set S_view_files_speed, "a view-files dialog widget"); Xen_check_type(Xen_is_number(speed), speed, 2, S_set S_view_files_speed, "a number"); view_files_set_speed((widget_t)(Xen_unwrap_widget(dialog)), Xen_real_to_C_double(speed)); return(speed); } static Xen g_view_files_amp_env(Xen dialog) { #define H_view_files_amp_env "(" S_view_files_amp_env " dialog): amp env breakpoints in the given View:Files dialog" Xen_check_type(Xen_is_widget(dialog), dialog, 1, S_view_files_amp_env, "a view-files dialog widget"); return(env_to_xen(view_files_amp_env((widget_t)(Xen_unwrap_widget(dialog))))); } static Xen g_view_files_set_amp_env(Xen dialog, Xen amp_env) { Xen_check_type(Xen_is_widget(dialog), dialog, 1, S_set S_view_files_amp_env, "a view-files dialog widget"); Xen_check_type(Xen_is_list(amp_env), amp_env, 2, S_set S_view_files_amp_env, "an envelope"); view_files_set_amp_env((widget_t)(Xen_unwrap_widget(dialog)), xen_to_env(amp_env)); return(amp_env); } static Xen g_view_files_speed_style(Xen dialog) { #define H_view_files_speed_style "(" S_view_files_speed_style " dialog): speed_style in use in the given View:Files dialog" Xen_check_type(Xen_is_widget(dialog), dialog, 1, S_view_files_speed_style, "a view-files dialog widget"); return(C_int_to_Xen_integer((int)(view_files_speed_style((widget_t)(Xen_unwrap_widget(dialog)))))); } static Xen g_view_files_set_speed_style(Xen dialog, Xen speed_style) { Xen_check_type(Xen_is_widget(dialog), dialog, 1, S_set S_view_files_speed_style, "a view-files dialog widget"); Xen_check_type(Xen_is_integer(speed_style), speed_style, 2, S_set S_view_files_speed_style, "an int"); view_files_set_speed_style((widget_t)(Xen_unwrap_widget(dialog)), (speed_style_t)(Xen_integer_to_C_int(speed_style))); return(speed_style); } static Xen g_view_files_selected_files(Xen dialog) { #define H_view_files_selected_files "(" S_view_files_selected_files " dialog): list of files currently selected in the given View:Files dialog" Xen result = Xen_empty_list; char **selected_files; int len = 0; Xen_check_type(Xen_is_widget(dialog), dialog, 1, S_view_files_selected_files, "a view-files dialog widget"); selected_files = view_files_selected_files((widget_t)(Xen_unwrap_widget(dialog)), &len); if ((selected_files) && (len > 0)) { int i; for (i = 0; i < len; i++) { result = Xen_cons(C_string_to_Xen_string(selected_files[i]), result); free(selected_files[i]); } free(selected_files); } return(result); } static Xen g_view_files_set_selected_files(Xen dialog, Xen files) { int len; Xen_check_type(Xen_is_widget(dialog), dialog, 1, S_set S_view_files_selected_files, "a view-files dialog widget"); Xen_check_type(Xen_is_list(files), files, 2, S_set S_view_files_selected_files, "a list of files or directories"); len = Xen_list_length(files); if (len > 0) { char **cfiles = NULL; int i; for (i = 0; i < len; i++) if (!(Xen_is_string(Xen_list_ref(files, i)))) { Xen_check_type(0, Xen_list_ref(files, i), i, S_set S_view_files_selected_files, "a filename (string)"); return(Xen_false); } cfiles = (char **)calloc(len, sizeof(char *)); for (i = 0; i < len; i++) cfiles[i] = (char *)Xen_string_to_C_string(Xen_list_ref(files, i)); view_files_set_selected_files((widget_t)(Xen_unwrap_widget(dialog)), cfiles, len); free(cfiles); } return(files); } static Xen g_view_files_files(Xen dialog) { #define H_view_files_files "(" S_view_files_files " dialog): list of files currently available in the given View:Files dialog" Xen result = Xen_empty_list; char **files; int i, len = 0; Xen_check_type(Xen_is_widget(dialog), dialog, 1, S_view_files_files, "a view-files dialog widget"); files = view_files_files((widget_t)(Xen_unwrap_widget(dialog)), &len); if ((files) && (len > 0)) for (i = 0; i < len; i++) result = Xen_cons(C_string_to_Xen_string(files[i]), result); return(result); } static Xen g_view_files_set_files(Xen dialog, Xen files) { int len = 0; char **cfiles = NULL; Xen_check_type(Xen_is_widget(dialog), dialog, 1, S_set S_view_files_files, "a view-files dialog widget"); Xen_check_type(Xen_is_list(files), files, 2, S_set S_view_files_files, "a list of files or directories"); len = Xen_list_length(files); if (len > 0) { int i; for (i = 0; i < len; i++) if (!(Xen_is_string(Xen_list_ref(files, i)))) { Xen_check_type(0, Xen_list_ref(files, i), i, S_set S_view_files_files, "a filename (string)"); return(Xen_false); } cfiles = (char **)calloc(len, sizeof(char *)); for (i = 0; i < len; i++) cfiles[i] = (char *)Xen_string_to_C_string(Xen_list_ref(files, i)); } view_files_set_files((widget_t)(Xen_unwrap_widget(dialog)), cfiles, len); if (cfiles) free(cfiles); return(files); } static Xen view_files_select_hook; static void view_files_run_select_hook(widget_t dialog, const char *selected_file) { if (Xen_hook_has_list(view_files_select_hook)) run_hook(view_files_select_hook, Xen_list_2(Xen_wrap_widget(dialog), C_string_to_Xen_string(selected_file)), S_view_files_select_hook); } /* -------- file-filters and file-sorters -------- */ #define INITIAL_FILE_SORTERS_SIZE 4 static bool file_sorter_ok(Xen name, Xen proc, const char *caller) { char *errmsg; Xen_check_type(Xen_is_string(name), name, 1, caller, "a string"); Xen_check_type(Xen_is_procedure(proc), proc, 2, caller, "a procedure of 2 args (file1 and file2)"); errmsg = procedure_ok(proc, 2, caller, "file sort", 2); if (errmsg) { Xen errstr; errstr = C_string_to_Xen_string(errmsg); free(errmsg); snd_bad_arity_error(caller, errstr, proc); return(false); } return(true); } static Xen g_add_file_sorter(Xen name, Xen proc) { #define H_add_file_sorter "(" S_add_file_sorter " name proc) -- add proc with identifier name to file sorter list, returns its index" int choice = -1; /* type checks are redundant here */ if (file_sorter_ok(name, proc, S_add_file_sorter)) { int i, len; len = ss->file_sorters_size; for (i = 0; i < len; i++) { if (Xen_is_false(Xen_vector_ref(ss->file_sorters, i))) { Xen_vector_set(ss->file_sorters, i, Xen_list_2(name, proc)); choice = i; break; } } if (choice == -1) { ss->file_sorters_size = len * 2; ss->file_sorters = g_expand_vector(ss->file_sorters, ss->file_sorters_size); Xen_vector_set(ss->file_sorters, len, Xen_list_2(name, proc)); choice = len; } view_files_reflect_sort_items(); } return(C_int_to_Xen_integer(choice + SORT_XEN)); } static Xen g_delete_file_sorter(Xen index) { #define H_delete_file_sorter "(" S_delete_file_sorter " index) -- delete proc with identifier name from file sorter list" int pos; Xen_check_type(Xen_is_integer(index), index, 1, S_delete_file_sorter, "a file-sorter index"); pos = Xen_integer_to_C_int(index); if ((pos >= SORT_XEN) && ((pos - SORT_XEN) < ss->file_sorters_size)) Xen_vector_set(ss->file_sorters, pos - SORT_XEN, Xen_false); view_files_reflect_sort_items(); return(index); } /* -------- drop watcher lists -------- */ /* the rigamarole for dealing with a drop is so messed up that I think it's * worth the trouble of setting up a separate callback list -- hence the * drop watchers */ typedef struct { void (*drop_watcher)(Widget w, const char *message, Position x, Position y, void *data); void (*drag_watcher)(Widget w, const char *message, Position x, Position y, drag_style_t dtype, void *data); Widget caller; void *context; } drop_watcher_t; static drop_watcher_t **drop_watchers = NULL; static int drop_watchers_size = 0; #define DROP_WATCHER_SIZE_INCREMENT 2 static int add_drop_watcher(Widget w, void (*drop_watcher)(Widget w, const char *message, Position x, Position y, void *data), void (*drag_watcher)(Widget w, const char *message, Position x, Position y, drag_style_t dtype, void *data), void *context) { int loc = -1; if (!(drop_watchers)) { loc = 0; drop_watchers_size = DROP_WATCHER_SIZE_INCREMENT; drop_watchers = (drop_watcher_t **)calloc(drop_watchers_size, sizeof(drop_watcher_t *)); } else { int i; for (i = 0; i < drop_watchers_size; i++) if (!(drop_watchers[i])) { loc = i; break; } if (loc == -1) { loc = drop_watchers_size; drop_watchers_size += DROP_WATCHER_SIZE_INCREMENT; drop_watchers = (drop_watcher_t **)realloc(drop_watchers, drop_watchers_size * sizeof(drop_watcher_t *)); for (i = loc; i < drop_watchers_size; i++) drop_watchers[i] = NULL; } } drop_watchers[loc] = (drop_watcher_t *)calloc(1, sizeof(drop_watcher_t)); drop_watchers[loc]->drop_watcher = drop_watcher; drop_watchers[loc]->drag_watcher = drag_watcher; drop_watchers[loc]->context = context; drop_watchers[loc]->caller = w; return(loc); } #if 0 static bool remove_drop_watcher(int loc) { if ((drop_watchers) && (loc < drop_watchers_size) && (loc >= 0) && (drop_watchers[loc])) { free(drop_watchers[loc]); drop_watchers[loc] = NULL; return(true); } return(false); } #endif static drop_watcher_t *find_drop_watcher(Widget caller) { if (drop_watchers) { int i; for (i = 0; i < drop_watchers_size; i++) { if (drop_watchers[i]) { drop_watcher_t *d; d = drop_watchers[i]; if (d->caller == caller) return(d); } } } return(NULL); } /* can't move axes if icon dragged to end of graph because the entire system freezes! */ static Atom FILE_NAME; /* Sun uses this, SGI uses STRING */ static Atom COMPOUND_TEXT; /* various Motif widgets use this and the next */ static Atom _MOTIF_COMPOUND_STRING; static Atom text_plain; /* gtk uses this -- apparently a url */ static Atom uri_list; /* rox uses this -- looks just like text/plain to me */ static Atom TEXT; /* ditto */ static Xen drop_hook; static char *atom_to_string(Atom type, XtPointer value, unsigned long length) { char *str = NULL; if ((type == XA_STRING) || (type == FILE_NAME) || (type == text_plain) || (type == uri_list) || (type == TEXT)) { unsigned long i; str = (char *)calloc(length + 1, sizeof(char)); for (i = 0; i < length; i++) str[i] = ((char *)value)[i]; } else { if ((type == COMPOUND_TEXT) || (type == _MOTIF_COMPOUND_STRING)) { char *temp; XmString cvt, tmp; XmParseTable parser = (XmParseTable)XtCalloc(1, sizeof(XmParseMapping)); int n; Arg args[12]; /* create parse table to catch separator in XmString and insert "\n" in output */ /* multiple file names are passed this way in Motif */ tmp = XmStringSeparatorCreate(); n = 0; XtSetArg(args[n], XmNincludeStatus, XmINSERT); n++; XtSetArg(args[n], XmNsubstitute, tmp); n++; XtSetArg(args[n], XmNpattern, "\n"); n++; parser[0] = XmParseMappingCreate(args, n); if (type == _MOTIF_COMPOUND_STRING) cvt = XmCvtByteStreamToXmString((unsigned char *)value); else cvt = XmCvtCTToXmString((char *)value); temp = (char *)XmStringUnparse(cvt, NULL, XmCHARSET_TEXT, XmCHARSET_TEXT, parser, 1, XmOUTPUT_ALL); XmParseTableFree(parser, 1); XmStringFree(cvt); str = mus_strdup(temp); XtFree(temp); } } return(str); } static Position mx, my; static void massage_selection(Widget w, XtPointer context, Atom *selection, Atom *type, XtPointer value, unsigned long *length, int *format) { char *str = NULL; str = atom_to_string(*type, value, *length); /* str can contain more than one name (separated by cr) */ if (str) { if ((!(Xen_hook_has_list(drop_hook))) || (!(Xen_is_true(run_or_hook(drop_hook, Xen_list_1(C_string_to_Xen_string(str)), S_drop_hook))))) { Widget caller; /* "w" above is the transfer control widget, not the drop-receiver */ drop_watcher_t *d; caller = (Widget)((XmDropTransferEntry)context)->client_data; d = find_drop_watcher(caller); if (d) { /* loop through possible list of filenames, calling watcher on each */ char *filename; int len = 0, i, j = 0; len = mus_strlen(str); filename = (char *)calloc(len, sizeof(char)); for (i = 0; i < len; i++) { if ((str[i] == '\n') || (str[i] == '\r')) /* apparently the only space chars here are \n and \r? */ { if (j > 0) { filename[j] = '\0'; if (strncmp(filename, "file://", 7) == 0) { char *tmp; tmp = (char *)(filename + 7); (*(d->drop_watcher))(caller, (const char *)tmp, mx, my, d->context); } else (*(d->drop_watcher))(caller, (const char *)filename, mx, my, d->context); j = 0; } /* else ignore extra white space chars */ } else { filename[j++] = str[i]; } } free(filename); } } free(str); } } static void handle_drop(Widget w, XtPointer context, XtPointer info) { XmDropProcCallbackStruct *cb = (XmDropProcCallbackStruct *)info; Arg args[12]; int n, i, num_targets, k; Atom *targets; XmDropTransferEntryRec entries[2]; if ((cb->dropAction != XmDROP) || ((cb->operation != XmDROP_COPY) && (cb->operation != XmDROP_LINK))) { cb->dropSiteStatus = XmINVALID_DROP_SITE; return; } k = -1; XtVaGetValues(cb->dragContext, XmNexportTargets, &targets, XmNnumExportTargets, &num_targets, NULL); for (i = 0; i < num_targets; i++) if ((targets[i] == XA_STRING) || (targets[i] == FILE_NAME) || (targets[i] == COMPOUND_TEXT) || (targets[i] == _MOTIF_COMPOUND_STRING) || (targets[i] == TEXT) || (targets[i] == text_plain) || (targets[i] == uri_list)) { k = i; break; } if (k == -1) { #if 0 fprintf(stderr, "failed drop attempt:\n"); for (i = 0; i < num_targets; i++) fprintf(stderr, " target %d = %s\n", i, XGetAtomName(MAIN_DISPLAY(ss), targets[i])); #endif cb->dropSiteStatus = XmINVALID_DROP_SITE; cb->operation = XmDROP_NOOP; n = 0; XtSetArg(args[n], XmNnumDropTransfers, 0); n++; XtSetArg(args[n], XmNtransferStatus, XmTRANSFER_FAILURE); n++; XmDropTransferStart(cb->dragContext, args, n); return; } mx = cb->x; my = cb->y; entries[0].target = targets[k]; entries[0].client_data = (XtPointer)w; n = 0; XtSetArg(args[n], XmNdropTransfers, entries); n++; XtSetArg(args[n], XmNnumDropTransfers, 1); n++; XtSetArg(args[n], XmNtransferProc, massage_selection); n++; /* cb->operation = XmDROP_COPY; */ XmDropTransferStart(cb->dragContext, args, n); } static void handle_drag(Widget w, XtPointer context, XtPointer info) { XmDragProcCallbackStruct *cb = (XmDragProcCallbackStruct *)info; drop_watcher_t *d; d = find_drop_watcher(w); if ((d) && (d->drag_watcher)) { switch (cb->reason) { case XmCR_DROP_SITE_MOTION_MESSAGE: (*(d->drag_watcher))(w, NULL, cb->x, cb->y, DRAG_MOTION, d->context); break; case XmCR_DROP_SITE_ENTER_MESSAGE: (*(d->drag_watcher))(w, NULL, cb->x, cb->y, DRAG_ENTER, d->context); break; case XmCR_DROP_SITE_LEAVE_MESSAGE: (*(d->drag_watcher))(w, NULL, cb->x, cb->y, DRAG_LEAVE, d->context); break; } } } #define NUM_TARGETS 7 void add_drag_and_drop(Widget w, void (*drop_watcher)(Widget w, const char *message, Position x, Position y, void *data), void (*drag_watcher)(Widget w, const char *message, Position x, Position y, drag_style_t dtype, void *data), void *context) { Display *dpy; int n; Atom targets[NUM_TARGETS]; Arg args[12]; dpy = MAIN_DISPLAY(ss); targets[0] = XA_STRING; FILE_NAME = XInternAtom(dpy, "FILE_NAME", false); targets[1] = FILE_NAME; COMPOUND_TEXT = XInternAtom(dpy, "COMPOUND_TEXT", false); targets[2] = COMPOUND_TEXT; _MOTIF_COMPOUND_STRING = XInternAtom(dpy, "_MOTIF_COMPOUND_STRING", false); targets[3] = _MOTIF_COMPOUND_STRING; text_plain = XInternAtom(dpy, "text/plain", false); targets[4] = text_plain; TEXT = XInternAtom(dpy, "TEXT", false); targets[5] = TEXT; uri_list = XInternAtom(dpy, "text/uri-list", false); targets[6] = uri_list; n = 0; XtSetArg(args[n], XmNdropSiteOperations, XmDROP_COPY | XmDROP_LINK); n++; XtSetArg(args[n], XmNimportTargets, targets); n++; XtSetArg(args[n], XmNnumImportTargets, NUM_TARGETS); n++; XtSetArg(args[n], XmNdropProc, handle_drop); n++; XtSetArg(args[n], XmNdragProc, handle_drag); n++; XmDropSiteRegister(w, args, n); add_drop_watcher(w, drop_watcher, drag_watcher, context); } /* -------------------------------------------------------------------------------- */ Xen_wrap_1_optional_arg(g_view_files_sort_w, g_view_files_sort) Xen_wrap_2_optional_args(g_set_view_files_sort_w, g_set_view_files_sort) Xen_wrap_2_optional_args(g_add_directory_to_view_files_list_w, g_add_directory_to_view_files_list) Xen_wrap_2_optional_args(g_add_file_to_view_files_list_w, g_add_file_to_view_files_list) Xen_wrap_2_optional_args(g_view_files_dialog_w, g_view_files_dialog) Xen_wrap_1_arg(g_view_files_amp_w, g_view_files_amp) Xen_wrap_2_args(g_view_files_set_amp_w, g_view_files_set_amp) Xen_wrap_1_arg(g_view_files_speed_w, g_view_files_speed) Xen_wrap_2_args(g_view_files_set_speed_w, g_view_files_set_speed) Xen_wrap_1_arg(g_view_files_amp_env_w, g_view_files_amp_env) Xen_wrap_2_args(g_view_files_set_amp_env_w, g_view_files_set_amp_env) Xen_wrap_1_arg(g_view_files_speed_style_w, g_view_files_speed_style) Xen_wrap_2_args(g_view_files_set_speed_style_w, g_view_files_set_speed_style) Xen_wrap_1_arg(g_view_files_selected_files_w, g_view_files_selected_files) Xen_wrap_1_arg(g_view_files_files_w, g_view_files_files) Xen_wrap_2_args(g_view_files_set_selected_files_w, g_view_files_set_selected_files) Xen_wrap_2_args(g_view_files_set_files_w, g_view_files_set_files) Xen_wrap_1_arg(g_delete_file_sorter_w, g_delete_file_sorter) Xen_wrap_2_args(g_add_file_sorter_w, g_add_file_sorter) #if HAVE_SCHEME static s7_pointer acc_view_files_sort(s7_scheme *sc, s7_pointer args) {return(g_set_view_files_sort(s7_cadr(args), s7_undefined(sc)));} #endif void g_init_gxfile(void) { #if HAVE_SCHEME #define H_mouse_enter_label_hook S_mouse_enter_label_hook " (type position label): called when the mouse enters a file viewer or region label. \ The 'type' is 1 for view-files, and 2 for regions. The 'position' \ is the scrolled list position of the label. The label itself is 'label'. We could use the 'finfo' procedure in examp.scm \ to popup file info as follows: \n\ (hook-push " S_mouse_enter_label_hook "\n\ (lambda (type position name)\n\ (if (not (= type 2))\n\ (" S_info_dialog " name (finfo name)))))\n\ See also nb.scm." #endif #if HAVE_RUBY #define H_mouse_enter_label_hook S_mouse_enter_label_hook " (type position label): called when the mouse enters a file viewer or region label. \ The 'type' is 1 for view-files, and 2 for regions. The 'position' \ is the scrolled list position of the label. The label itself is 'label'. We could use the 'finfo' procedure in examp.rb \ to popup file info as follows: \n\ $mouse_enter_label_hook.add_hook!(\"finfo\") do |type, position, name|\n\ if type != 2\n\ " S_info_dialog "(name, finfo(name))\n\ end\n\ end\n\ See also nb.rb." #endif #if HAVE_FORTH #define H_mouse_enter_label_hook S_mouse_enter_label_hook " (type position label): called when the mouse enters a file viewer or region label. \ The 'type' is 1 for view-files, and 2 for regions. The 'position' \ is the scrolled list position of the label. The label itself is 'label'. We could use the 'finfo' procedure in examp.fs \ to popup file info as follows: \n\ " S_mouse_enter_label_hook " lambda: <{ type position name }>\n\ type 2 <> if\n\ name name finfo info-dialog\n\ else\n\ #f\n\ then\n\ ; add-hook!" #endif #define H_mouse_leave_label_hook S_mouse_leave_label_hook " (type position label): called when the mouse leaves a file viewer or region label" mouse_enter_label_hook = Xen_define_hook(S_mouse_enter_label_hook, "(make-hook 'type 'position 'label)", 3, H_mouse_enter_label_hook); mouse_leave_label_hook = Xen_define_hook(S_mouse_leave_label_hook, "(make-hook 'type 'position 'label)", 3, H_mouse_leave_label_hook); Xen_define_dilambda(S_view_files_amp, g_view_files_amp_w, H_view_files_amp, S_set S_view_files_amp, g_view_files_set_amp_w, 1, 0, 2, 0); Xen_define_dilambda(S_view_files_amp_env, g_view_files_amp_env_w, H_view_files_amp_env, S_set S_view_files_amp_env, g_view_files_set_amp_env_w, 1, 0, 2, 0); Xen_define_dilambda(S_view_files_speed_style, g_view_files_speed_style_w, H_view_files_speed_style, S_set S_view_files_speed_style, g_view_files_set_speed_style_w, 1, 0, 2, 0); Xen_define_dilambda(S_view_files_speed, g_view_files_speed_w, H_view_files_speed, S_set S_view_files_speed, g_view_files_set_speed_w, 1, 0, 2, 0); Xen_define_dilambda(S_view_files_files, g_view_files_files_w, H_view_files_files, S_set S_view_files_files, g_view_files_set_files_w, 1, 0, 2, 0); Xen_define_dilambda(S_view_files_selected_files, g_view_files_selected_files_w, H_view_files_selected_files, S_set S_view_files_selected_files, g_view_files_set_selected_files_w, 1, 0, 2, 0); Xen_define_safe_procedure(S_add_directory_to_view_files_list, g_add_directory_to_view_files_list_w, 1, 1, 0, H_add_directory_to_view_files_list); Xen_define_safe_procedure(S_add_file_to_view_files_list, g_add_file_to_view_files_list_w, 1, 1, 0, H_add_file_to_view_files_list); Xen_define_safe_procedure(S_view_files_dialog, g_view_files_dialog_w, 0, 2, 0, H_view_files_dialog); Xen_define_dilambda(S_view_files_sort, g_view_files_sort_w, H_view_files_sort, S_set S_view_files_sort, g_set_view_files_sort_w, 0, 1, 1, 1); Xen_add_to_hook_list(ss->snd_open_file_hook, vf_open_file_watcher_w, "view-files-dialog-open-file-handler", "view-files dialog open-file handler"); #define H_view_files_select_hook S_view_files_select_hook "(dialog name): called when a file is selected in the \ files list of the View Files dialog. If it returns " PROC_TRUE ", the default action, opening the file, is omitted." view_files_select_hook = Xen_define_hook(S_view_files_select_hook, "(make-hook 'dialog 'name)", 2, H_view_files_select_hook); /* file-filters and file-sorters are lists from user's point of view, but I want to * make sure they're gc-protected through add/delete/set, and want such code compatible * with current Ruby xen macros, so I'll use an array internally. */ ss->file_sorters_size = INITIAL_FILE_SORTERS_SIZE; ss->file_sorters = Xen_make_vector(ss->file_sorters_size, Xen_false); Xen_GC_protect(ss->file_sorters); Xen_define_safe_procedure(S_add_file_sorter, g_add_file_sorter_w, 2, 0, 0, H_add_file_sorter); Xen_define_safe_procedure(S_delete_file_sorter, g_delete_file_sorter_w, 1, 0, 0, H_delete_file_sorter); #define H_drop_hook S_drop_hook " (name): called whenever Snd receives a drag-and-drop \ event. If it returns " PROC_TRUE ", the file is not opened or mixed by Snd." drop_hook = Xen_define_hook(S_drop_hook, "(make-hook 'name)", 1, H_drop_hook); #if HAVE_SCHEME s7_symbol_set_access(s7, ss->view_files_sort_symbol, s7_make_function(s7, "[acc-" S_view_files_sort "]", acc_view_files_sort, 2, 0, false, "accessor")); #endif } #include "sndlib-strings.h" /* preferences dialog; layout design taken from webmail */ static Widget preferences_dialog = NULL, load_path_text_widget = NULL; static bool prefs_unsaved = false; static char *prefs_saved_filename = NULL; static char *include_load_path = NULL; #define MID_POSITION 50 #define PREFS_COLOR_POSITION 62 /* COLOR_POSITION is slider_choice_t in snd-0.h */ #define FIRST_COLOR_POSITION 6 #define SECOND_COLOR_POSITION 30 #define THIRD_COLOR_POSITION 55 #define MID_SPACE 16 #define INTER_TOPIC_SPACE 3 #define INTER_VARIABLE_SPACE 2 #define POWER_WAIT_TIME 100 #define POWER_INITIAL_WAIT_TIME 500 /* "power" is an old-timey name for auto-repeat */ #define ERROR_WAIT_TIME 5000 #define STARTUP_WIDTH 925 #define STARTUP_HEIGHT 800 typedef struct prefs_info { Widget label, text, arrow_up, arrow_down, arrow_right, error, toggle, scale, toggle2, toggle3; Widget color, rscl, gscl, bscl, rtxt, gtxt, btxt, list_menu, radio_button; Widget *radio_buttons; bool got_error; timeout_result_t power_id; const char *var_name, *saved_label; int num_buttons; mus_float_t scale_max; void (*toggle_func)(struct prefs_info *prf); void (*toggle2_func)(struct prefs_info *prf); void (*scale_func)(struct prefs_info *prf); void (*arrow_up_func)(struct prefs_info *prf); void (*arrow_down_func)(struct prefs_info *prf); void (*text_func)(struct prefs_info *prf); void (*list_func)(struct prefs_info *prf, char *value); void (*color_func)(struct prefs_info *prf, float r, float g, float b); void (*reflect_func)(struct prefs_info *prf); void (*save_func)(struct prefs_info *prf, FILE *fd); const char *(*help_func)(struct prefs_info *prf); void (*clear_func)(struct prefs_info *prf); void (*revert_func)(struct prefs_info *prf); } prefs_info; static void prefs_set_dialog_title(const char *filename); static void reflect_key(prefs_info *prf, const char *key_name); static void save_key(prefs_info *prf, FILE *fd, char *(*binder)(char *key, bool c, bool m, bool x)); static void key_bind(prefs_info *prf, char *(*binder)(char *key, bool c, bool m, bool x)); static void clear_prefs_dialog_error(void); static void scale_set_color(prefs_info *prf, color_t pixel); static color_t rgb_to_color(mus_float_t r, mus_float_t g, mus_float_t b); static void post_prefs_error(const char *msg, prefs_info *data); #ifdef __GNUC__ static void va_post_prefs_error(const char *msg, prefs_info *data, ...) __attribute__ ((format (printf, 1, 0))); #else static void va_post_prefs_error(const char *msg, prefs_info *data, ...); #endif /* used in snd-prefs */ #define GET_TOGGLE(Toggle) (XmToggleButtonGetState(Toggle) == XmSET) #define SET_TOGGLE(Toggle, Value) XmToggleButtonSetState(Toggle, Value, false) #define GET_TEXT(Text) XmTextFieldGetString(Text) #define SET_TEXT(Text, Val) XmTextFieldSetString(Text, (char *)Val) #define free_TEXT(Val) XtFree(Val) #define SET_SCALE(Value) XmScaleSetValue(prf->scale, (int)(100 * Value)) #define SET_SENSITIVE(Wid, Val) XtSetSensitive(Wid, Val) #define black_text(Prf) XtVaSetValues(Prf->label, XmNforeground, ss->black, NULL) #define red_text(Prf) XtVaSetValues(Prf->label, XmNforeground, ss->red, NULL) #define TIMEOUT(Func) XtAppAddTimeOut(MAIN_APP(ss), ERROR_WAIT_TIME, Func, (XtPointer)prf) static int get_scale_1(Widget scale) { int val = 0; XmScaleGetValue(scale, &val); return(val); } #define GET_SCALE() (get_scale_1(prf->scale) * 0.01) static void set_radio_button(prefs_info *prf, int which) { if ((which >= 0) && (which < prf->num_buttons)) { int i; for (i = 0; i < prf->num_buttons; i++) { if ((prf->radio_buttons[i]) && (XmIsToggleButton(prf->radio_buttons[i]))) XmToggleButtonSetState(prf->radio_buttons[i], (i == which), false); } prf->radio_button = prf->radio_buttons[which]; } } static int which_radio_button(prefs_info *prf) { pointer_or_int_t which = 0; XtVaGetValues(prf->radio_button, XmNuserData, &which, NULL); return(which); } #include "snd-prefs.c" static bool prefs_dialog_error_is_posted = false; static void post_prefs_dialog_error(const char *message, void *data) { XmString title; title = XmStringCreateLocalized((char *)message); XtVaSetValues(preferences_dialog, XmNmessageString, title, NULL); XmStringFree(title); prefs_dialog_error_is_posted = (message != NULL); } static void clear_prefs_dialog_error(void) { if (prefs_dialog_error_is_posted) { prefs_dialog_error_is_posted = false; post_prefs_dialog_error(NULL, NULL); } } static void prefs_change_callback(Widget w, XtPointer context, XtPointer info) { prefs_unsaved = true; prefs_set_dialog_title(NULL); clear_prefs_dialog_error(); } /* ---------------- row (main) label widget ---------------- */ static Widget make_row_label(prefs_info *prf, const char *label, Widget box, Widget top_widget) { Widget w; Arg args[20]; int n; n = 0; XtSetArg(args[n], XmNbackground, ss->white); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, top_widget); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n++; XtSetArg(args[n], XmNrightPosition, MID_POSITION); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_END); n++; w = XtCreateManagedWidget(label, xmLabelWidgetClass, box, args, n); prf->saved_label = label; return(w); } /* ---------------- row inner label widget ---------------- */ static Widget make_row_inner_label(prefs_info *prf, const char *label, Widget left_widget, Widget box, Widget top_widget) { Widget w; Arg args[20]; int n; n = 0; XtSetArg(args[n], XmNbackground, ss->white); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, top_widget); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, left_widget); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; w = XtCreateManagedWidget(label, xmLabelWidgetClass, box, args, n); return(w); } /* ---------------- row middle separator widget ---------------- */ static Widget make_row_middle_separator(Widget label, Widget box, Widget top_widget) { Arg args[20]; int n; n = 0; XtSetArg(args[n], XmNbackground, ss->white); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, top_widget); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNbottomWidget, label); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, label); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNorientation, XmVERTICAL); n++; XtSetArg(args[n], XmNwidth, MID_SPACE); n++; XtSetArg(args[n], XmNseparatorType, XmSHADOW_ETCHED_OUT); n++; return(XtCreateManagedWidget("sep", xmSeparatorWidgetClass, box, args, n)); } /* ---------------- row inner separator widget ---------------- */ static Widget make_row_inner_separator(int width, Widget left_widget, Widget box, Widget top_widget) { Arg args[20]; int n; n = 0; XtSetArg(args[n], XmNbackground, ss->white); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, top_widget); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, left_widget); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNwidth, width); n++; XtSetArg(args[n], XmNseparatorType, XmNO_LINE); n++; return(XtCreateManagedWidget("sep1", xmSeparatorWidgetClass, box, args, n)); } static Widget make_row_error(prefs_info *prf, Widget box, Widget left_widget, Widget top_widget) { Arg args[20]; int n; Widget w; n = 0; XtSetArg(args[n], XmNbackground, ss->white); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, top_widget); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNbottomWidget, left_widget); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, left_widget); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_END); n++; w = XtCreateManagedWidget("", xmLabelWidgetClass, box, args, n); return(w); } /* ---------------- row toggle widget ---------------- */ static Widget make_row_toggle_with_label(prefs_info *prf, bool current_value, Widget left_widget, Widget box, Widget top_widget, const char *label) { Widget w; Arg args[20]; int n; n = 0; XtSetArg(args[n], XmNbackground, ss->white); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, top_widget); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, left_widget); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNset, (current_value) ? XmSET : XmUNSET); n++; XtSetArg(args[n], XmNborderWidth, 0); n++; XtSetArg(args[n], XmNborderColor, ss->white); n++; XtSetArg(args[n], XmNmarginHeight, 0); n++; XtSetArg(args[n], XmNindicatorOn, XmINDICATOR_FILL); n++; XtSetArg(args[n], XmNindicatorSize, 14); n++; w = XtCreateManagedWidget(label, xmToggleButtonWidgetClass, box, args, n); return(w); } static Widget make_row_toggle(prefs_info *prf, bool current_value, Widget left_widget, Widget box, Widget top_widget) { return(make_row_toggle_with_label(prf, current_value, left_widget, box, top_widget, " ")); } /* ---------------- row arrows ---------------- */ static void remove_arrow_func(Widget w, XtPointer context, XtPointer info) { prefs_info *prf = (prefs_info *)context; if (prf->power_id != 0) { XtRemoveTimeOut(prf->power_id); prf->power_id = 0; } } static void arrow_func_up(XtPointer context, XtIntervalId *id) { prefs_info *prf = (prefs_info *)context; if (XtIsSensitive(prf->arrow_up)) { if ((prf) && (prf->arrow_up_func)) { (*(prf->arrow_up_func))(prf); prf->power_id = XtAppAddTimeOut(MAIN_APP(ss), POWER_WAIT_TIME, arrow_func_up, (XtPointer)prf); } else prf->power_id = 0; } } static void arrow_func_down(XtPointer context, XtIntervalId *id) { prefs_info *prf = (prefs_info *)context; if (XtIsSensitive(prf->arrow_down)) { if ((prf) && (prf->arrow_down_func)) { (*(prf->arrow_down_func))(prf); prf->power_id = XtAppAddTimeOut(MAIN_APP(ss), POWER_WAIT_TIME, arrow_func_down, (XtPointer)prf); } else prf->power_id = 0; } } static void call_arrow_down_press(Widget w, XtPointer context, XtPointer info) { prefs_info *prf = (prefs_info *)context; if ((prf) && (prf->arrow_down_func)) { (*(prf->arrow_down_func))(prf); if (XtIsSensitive(w)) prf->power_id = XtAppAddTimeOut(MAIN_APP(ss), POWER_INITIAL_WAIT_TIME, arrow_func_down, (XtPointer)prf); else prf->power_id = 0; } } static void call_arrow_up_press(Widget w, XtPointer context, XtPointer info) { prefs_info *prf = (prefs_info *)context; if ((prf) && (prf->arrow_up_func)) { (*(prf->arrow_up_func))(prf); if (XtIsSensitive(w)) prf->power_id = XtAppAddTimeOut(MAIN_APP(ss), POWER_INITIAL_WAIT_TIME, arrow_func_up, (XtPointer)prf); else prf->power_id = 0; } } static Widget make_row_arrows(prefs_info *prf, Widget box, Widget left_widget, Widget top_widget) { Arg args[20]; int n; n = 0; XtSetArg(args[n], XmNbackground, ss->white); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, top_widget); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, left_widget); n++; XtSetArg(args[n], XmNarrowDirection, XmARROW_DOWN); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; prf->arrow_down = XtCreateManagedWidget("arrow-down", xmArrowButtonWidgetClass, box, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->white); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, top_widget); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, prf->arrow_down); n++; XtSetArg(args[n], XmNarrowDirection, XmARROW_UP); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; prf->arrow_up = XtCreateManagedWidget("arrow-up", xmArrowButtonWidgetClass, box, args, n); XtAddCallback(prf->arrow_down, XmNarmCallback, call_arrow_down_press, (XtPointer)prf); XtAddCallback(prf->arrow_down, XmNdisarmCallback, remove_arrow_func, (XtPointer)prf); XtAddCallback(prf->arrow_up, XmNarmCallback, call_arrow_up_press, (XtPointer)prf); XtAddCallback(prf->arrow_up, XmNdisarmCallback, remove_arrow_func, (XtPointer)prf); XtAddCallback(prf->arrow_up, XmNactivateCallback, prefs_change_callback, NULL); XtAddCallback(prf->arrow_down, XmNactivateCallback, prefs_change_callback, NULL); return(prf->arrow_up); } /* ---------------- bool row ---------------- */ static void call_toggle_func(Widget w, XtPointer context, XtPointer info) { prefs_info *prf = (prefs_info *)context; if ((prf) && (prf->toggle_func)) (*(prf->toggle_func))(prf); } static prefs_info *prefs_row_with_toggle(const char *label, const char *varname, bool current_value, Widget box, Widget top_widget, void (*toggle_func)(prefs_info *prf)) { prefs_info *prf = NULL; Widget sep; prf = (prefs_info *)calloc(1, sizeof(prefs_info)); prf->var_name = varname; prf->toggle_func = toggle_func; prf->label = make_row_label(prf, label, box, top_widget); sep = make_row_middle_separator(prf->label, box, top_widget); prf->toggle = make_row_toggle(prf, current_value, sep, box, top_widget); XtAddCallback(prf->toggle, XmNvalueChangedCallback, call_toggle_func, (XtPointer)prf); return(prf); } /* ---------------- two toggles ---------------- */ static void call_toggle2_func(Widget w, XtPointer context, XtPointer info) { prefs_info *prf = (prefs_info *)context; if ((prf) && (prf->toggle2_func)) (*(prf->toggle2_func))(prf); } static prefs_info *prefs_row_with_two_toggles(const char *label, const char *varname, const char *label1, bool value1, const char *label2, bool value2, Widget box, Widget top_widget, void (*toggle_func)(prefs_info *prf), void (*toggle2_func)(prefs_info *prf)) { prefs_info *prf = NULL; Widget sep, sep1; prf = (prefs_info *)calloc(1, sizeof(prefs_info)); prf->var_name = varname; prf->toggle_func = toggle_func; prf->toggle2_func = toggle2_func; prf->label = make_row_label(prf, label, box, top_widget); sep = make_row_middle_separator(prf->label, box, top_widget); prf->toggle = make_row_toggle_with_label(prf, value1, sep, box, top_widget, label1); sep1 = make_row_inner_separator(20, prf->toggle, box, top_widget); prf->toggle2 = make_row_toggle_with_label(prf, value2, sep1, box, top_widget, label2); XtAddCallback(prf->toggle, XmNvalueChangedCallback, call_toggle_func, (XtPointer)prf); XtAddCallback(prf->toggle2, XmNvalueChangedCallback, call_toggle2_func, (XtPointer)prf); return(prf); } /* ---------------- toggle with text ---------------- */ static void call_text_func(Widget w, XtPointer context, XtPointer info) { prefs_info *prf = (prefs_info *)context; if ((prf) && (prf->text_func)) (*(prf->text_func))(prf); } /* earlier versions of this dialog assumed the user would type to save a new value * typed in a text widget, but no one does that anymore, so now, to catch these changes * but not be confused by automatic changes (such as in a scale widget's label), * we'll use XmNfocusCallback to set a text_focussed flag, XmNlosingFocusCallback to * unset it, XmNvalueChangedCallback to set a text_changed flag, XmNactivateCallback * to clear text_changed, and if XmNlosingFocusCallback sees that flag set, it * calls the activate function and unsets the flag. */ typedef struct { bool text_focussed, text_changed; prefs_info *prf; } text_info; static void text_change_callback(Widget w, XtPointer context, XtPointer info) { text_info *data = (text_info *)context; if (data->text_focussed) /* try to omit non-user actions that change the value */ data->text_changed = true; } static void text_activate_callback(Widget w, XtPointer context, XtPointer info) { text_info *data = (text_info *)context; data->text_changed = false; } static void text_grab_focus_callback(Widget w, XtPointer context, XtPointer info) { text_info *data = (text_info *)context; data->text_focussed = true; } static void text_lose_focus_callback(Widget w, XtPointer context, XtPointer info) { text_info *data = (text_info *)context; if ((data->text_focussed) && (data->text_changed) && (data->prf) && (data->prf->text_func)) { (*(data->prf->text_func))(data->prf); data->text_changed = false; } } static Widget make_row_text(prefs_info *prf, const char *text_value, int cols, Widget left_widget, Widget box, Widget top_widget) { Widget w; int n; Arg args[30]; text_info *info; n = 0; XtSetArg(args[n], XmNbackground, ss->white); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, top_widget); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, left_widget); n++; if (cols != 0) { XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNcolumns, cols); n++; } else { XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; } if (text_value) { XtSetArg(args[n], XmNvalue, text_value); n++; } XtSetArg(args[n], XmNmarginHeight, 1); n++; XtSetArg(args[n], XmNborderWidth, 0); n++; XtSetArg(args[n], XmNborderColor, ss->white); n++; XtSetArg(args[n], XmNbottomShadowColor, ss->white); n++; XtSetArg(args[n], XmNshadowThickness, 0); n++; XtSetArg(args[n], XmNtopShadowColor, ss->white); n++; w = make_textfield_widget("text", box, args, n, ACTIVATABLE_BUT_NOT_FOCUSED, NO_COMPLETER); XtAddCallback(w, XmNactivateCallback, prefs_change_callback, NULL); info = (text_info *)calloc(1, sizeof(text_info)); info->prf = prf; XtAddCallback(w, XmNactivateCallback, text_activate_callback, (XtPointer)info); XtAddCallback(w, XmNvalueChangedCallback, text_change_callback, (XtPointer)info); XtAddCallback(w, XmNfocusCallback, text_grab_focus_callback, (XtPointer)info); XtAddCallback(w, XmNlosingFocusCallback, text_lose_focus_callback, (XtPointer)info); return(w); } static prefs_info *prefs_row_with_toggle_with_text(const char *label, const char *varname, bool current_value, const char *text_label, const char *text_value, int cols, Widget box, Widget top_widget, void (*toggle_func)(prefs_info *prf), void (*text_func)(prefs_info *prf)) { prefs_info *prf = NULL; Widget sep, sep1, lab1; prf = (prefs_info *)calloc(1, sizeof(prefs_info)); prf->var_name = varname; prf->toggle_func = toggle_func; prf->text_func = text_func; prf->label = make_row_label(prf, label, box, top_widget); sep = make_row_middle_separator(prf->label, box, top_widget); prf->toggle = make_row_toggle(prf, current_value, sep, box, top_widget); sep1 = make_row_inner_separator(16, prf->toggle, box, top_widget); lab1 = make_row_inner_label(prf, text_label, sep1, box, top_widget); prf->text = make_row_text(prf, text_value, cols, lab1, box, top_widget); XtAddCallback(prf->toggle, XmNvalueChangedCallback, call_toggle_func, (XtPointer)prf); XtAddCallback(prf->text, XmNactivateCallback, call_text_func, (XtPointer)prf); return(prf); } static prefs_info *prefs_row_with_toggle_with_two_texts(const char *label, const char *varname, bool current_value, const char *label1, const char *text1, const char *label2, const char *text2, int cols, Widget box, Widget top_widget, void (*toggle_func)(prefs_info *prf), void (*text_func)(prefs_info *prf)) { prefs_info *prf = NULL; Widget sep, lab1, lab2, sep1; prf = (prefs_info *)calloc(1, sizeof(prefs_info)); prf->var_name = varname; prf->toggle_func = toggle_func; prf->text_func = text_func; prf->label = make_row_label(prf, label, box, top_widget); sep = make_row_middle_separator(prf->label, box, top_widget); prf->toggle = make_row_toggle(prf, current_value, sep, box, top_widget); sep1 = make_row_inner_separator(16, prf->toggle, box, top_widget); lab1 = make_row_inner_label(prf, label1, sep1, box, top_widget); prf->text = make_row_text(prf, text1, cols, lab1, box, top_widget); lab2 = make_row_inner_label(prf, label2, prf->text, box, top_widget); prf->rtxt = make_row_text(prf, text2, cols, lab2, box, top_widget); XtAddCallback(prf->toggle, XmNvalueChangedCallback, call_toggle_func, (XtPointer)prf); XtAddCallback(prf->text, XmNactivateCallback, call_text_func, (XtPointer)prf); XtAddCallback(prf->rtxt, XmNactivateCallback, call_text_func, (XtPointer)prf); return(prf); } /* ---------------- text with toggle ---------------- */ static prefs_info *prefs_row_with_text_with_toggle(const char *label, const char *varname, bool current_value, const char *toggle_label, const char *text_value, int cols, Widget box, Widget top_widget, void (*toggle_func)(prefs_info *prf), void (*text_func)(prefs_info *prf)) { prefs_info *prf = NULL; Widget sep, sep1, lab1; prf = (prefs_info *)calloc(1, sizeof(prefs_info)); prf->var_name = varname; prf->toggle_func = toggle_func; prf->text_func = text_func; prf->label = make_row_label(prf, label, box, top_widget); sep = make_row_middle_separator(prf->label, box, top_widget); prf->text = make_row_text(prf, text_value, cols, sep, box, top_widget); sep1 = make_row_inner_separator(8, prf->text, box, top_widget); lab1 = make_row_inner_label(prf, toggle_label, sep1, box, top_widget); prf->toggle = make_row_toggle(prf, current_value, lab1, box, top_widget); XtAddCallback(prf->toggle, XmNvalueChangedCallback, call_toggle_func, (XtPointer)prf); XtAddCallback(prf->text, XmNactivateCallback, call_text_func, (XtPointer)prf); return(prf); } /* ---------------- text with toggle ---------------- */ static prefs_info *prefs_row_with_text_and_three_toggles(const char *label, const char *varname, const char *text_label, int cols, const char *toggle1_label, const char *toggle2_label, const char *toggle3_label, const char *text_value, bool toggle1_value, bool toggle2_value, bool toggle3_value, Widget box, Widget top_widget, void (*text_func)(prefs_info *prf)) { prefs_info *prf = NULL; Widget sep, sep1, lab1, sep2, lab2, lab3, sep3, lab4; prf = (prefs_info *)calloc(1, sizeof(prefs_info)); prf->var_name = varname; prf->text_func = text_func; prf->label = make_row_label(prf, label, box, top_widget); sep = make_row_middle_separator(prf->label, box, top_widget); lab3 = make_row_inner_label(prf, text_label, sep, box, top_widget); prf->text = make_row_text(prf, text_value, cols, lab3, box, top_widget); sep1 = make_row_inner_separator(12, prf->text, box, top_widget); lab1 = make_row_inner_label(prf, toggle1_label, sep1, box, top_widget); prf->toggle = make_row_toggle(prf, toggle1_value, lab1, box, top_widget); sep2 = make_row_inner_separator(4, prf->toggle, box, top_widget); lab2 = make_row_inner_label(prf, toggle2_label, sep2, box, top_widget); prf->toggle2 = make_row_toggle(prf, toggle2_value, lab2, box, top_widget); sep3 = make_row_inner_separator(4, prf->toggle2, box, top_widget); lab4 = make_row_inner_label(prf, toggle3_label, sep3, box, top_widget); prf->toggle3 = make_row_toggle(prf, toggle3_value, lab4, box, top_widget); XtAddCallback(prf->text, XmNactivateCallback, call_text_func, (XtPointer)prf); return(prf); } /* ---------------- radio row ---------------- */ static void call_radio_func(Widget w, XtPointer context, XtPointer info) { prefs_info *prf = (prefs_info *)context; if ((prf) && (prf->toggle_func)) { prf->radio_button = w; (*(prf->toggle_func))(prf); } } static Widget make_row_radio_box(prefs_info *prf, const char **labels, int num_labels, int current_value, Widget box, Widget left_widget, Widget top_widget) { Arg args[20]; int i, n; Widget w; prf->radio_buttons = (Widget *)calloc(num_labels, sizeof(Widget)); prf->num_buttons = num_labels; n = 0; XtSetArg(args[n], XmNbackground, ss->white); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, top_widget); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, left_widget); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNborderWidth, 0); n++; XtSetArg(args[n], XmNborderColor, ss->white); n++; XtSetArg(args[n], XmNmarginHeight, 0); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNpacking, XmPACK_TIGHT); n++; w = XmCreateRadioBox(box, (char *)"radio-box", args, n); XtManageChild(w); for (i = 0; i < num_labels; i++) { Widget button; n = 0; XtSetArg(args[n], XmNbackground, ss->white); n++; XtSetArg(args[n], XmNset, (i == current_value) ? XmSET : XmUNSET); n++; XtSetArg(args[n], XmNborderWidth, 0); n++; XtSetArg(args[n], XmNborderColor, ss->white); n++; XtSetArg(args[n], XmNmarginHeight, 0); n++; XtSetArg(args[n], XmNindicatorOn, XmINDICATOR_FILL); n++; XtSetArg(args[n], XmNindicatorSize, 14); n++; XtSetArg(args[n], XmNselectColor, ss->green); n++; XtSetArg(args[n], XmNuserData, i); n++; button = XtCreateManagedWidget(labels[i], xmToggleButtonWidgetClass, w, args, n); prf->radio_buttons[i] = button; XtAddCallback(button, XmNvalueChangedCallback, call_radio_func, (XtPointer)prf); XtAddCallback(button, XmNvalueChangedCallback, prefs_change_callback, NULL); } return(w); } static prefs_info *prefs_row_with_radio_box(const char *label, const char *varname, const char **labels, int num_labels, int current_value, Widget box, Widget top_widget, void (*toggle_func)(prefs_info *prf)) { prefs_info *prf = NULL; Widget sep; prf = (prefs_info *)calloc(1, sizeof(prefs_info)); prf->var_name = varname; prf->toggle_func = toggle_func; prf->label = make_row_label(prf, label, box, top_widget); sep = make_row_middle_separator(prf->label, box, top_widget); prf->toggle = make_row_radio_box(prf, labels, num_labels, current_value, box, sep, top_widget); return(prf); } /* ---------------- radio box + number ---------------- */ static prefs_info *prefs_row_with_radio_box_and_number(const char *label, const char *varname, const char **labels, int num_labels, int current_value, const char *text_value, int text_cols, Widget box, Widget top_widget, void (*toggle_func)(prefs_info *prf), void (*arrow_up_func)(prefs_info *prf), void (*arrow_down_func)(prefs_info *prf), void (*text_func)(prefs_info *prf)) { prefs_info *prf = NULL; Widget sep; prf = (prefs_info *)calloc(1, sizeof(prefs_info)); prf->var_name = varname; prf->toggle_func = toggle_func; prf->text_func = text_func; prf->arrow_up_func = arrow_up_func; prf->arrow_down_func = arrow_down_func; prf->label = make_row_label(prf, label, box, top_widget); sep = make_row_middle_separator(prf->label, box, top_widget); prf->toggle = make_row_radio_box(prf, labels, num_labels, current_value, box, sep, top_widget); prf->text = make_row_text(prf, text_value, text_cols, prf->toggle, box, top_widget); prf->arrow_up = make_row_arrows(prf, box, prf->text, top_widget); XtAddCallback(prf->text, XmNactivateCallback, call_text_func, (XtPointer)prf); return(prf); } /* ---------------- scale row ---------------- */ static void call_scale_func(Widget w, XtPointer context, XtPointer info) { prefs_info *prf = (prefs_info *)context; if ((prf) && (prf->scale_func)) (*(prf->scale_func))(prf); } static void call_scale_text_func(Widget w, XtPointer context, XtPointer info) { prefs_info *prf = (prefs_info *)context; if ((prf) && (prf->text_func)) (*(prf->text_func))(prf); } static void prefs_scale_callback(Widget w, XtPointer context, XtPointer info) { prefs_info *prf = (prefs_info *)context; XmScaleCallbackStruct *cb = (XmScaleCallbackStruct *)info; float_to_textfield(prf->text, (cb->value * prf->scale_max) / 100.0); } static prefs_info *prefs_row_with_scale(const char *label, const char *varname, mus_float_t max_val, mus_float_t current_value, Widget box, Widget top_widget, void (*scale_func)(prefs_info *prf), void (*text_func)(prefs_info *prf)) { Arg args[20]; int n; prefs_info *prf = NULL; Widget sep; XtCallbackList n1, n2; char *str; prf = (prefs_info *)calloc(1, sizeof(prefs_info)); prf->var_name = varname; prf->scale_max = max_val; prf->label = make_row_label(prf, label, box, top_widget); sep = make_row_middle_separator(prf->label, box, top_widget); str = (char *)calloc(12, sizeof(char)); snprintf(str, 12, "%.3f", current_value); prf->text = make_row_text(prf, str, 6, sep, box, top_widget); free(str); n = 0; XtSetArg(args[n], XmNbackground, ss->white); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, top_widget); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, prf->text); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNborderWidth, 0); n++; XtSetArg(args[n], XmNborderColor, ss->white); n++; XtSetArg(args[n], XmNmarginHeight, 0); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNshowValue, XmNONE); n++; XtSetArg(args[n], XmNvalue, (int)(100 * current_value / max_val)); n++; XtSetArg(args[n], XmNdragCallback, n1 = make_callback_list(prefs_scale_callback, (XtPointer)prf)); n++; XtSetArg(args[n], XmNvalueChangedCallback, n2 = make_callback_list(prefs_scale_callback, (XtPointer)prf)); n++; prf->scale = XtCreateManagedWidget("", xmScaleWidgetClass, box, args, n); prf->scale_func = scale_func; prf->text_func = text_func; XtAddCallback(prf->scale, XmNvalueChangedCallback, call_scale_func, (XtPointer)prf); XtAddCallback(prf->text, XmNactivateCallback, call_scale_text_func, (XtPointer)prf); XtAddCallback(prf->scale, XmNvalueChangedCallback, prefs_change_callback, NULL); free(n1); free(n2); return(prf); } /* ---------------- text row ---------------- */ static prefs_info *prefs_row_with_text(const char *label, const char *varname, const char *value, Widget box, Widget top_widget, void (*text_func)(prefs_info *prf)) { prefs_info *prf = NULL; Widget sep; prf = (prefs_info *)calloc(1, sizeof(prefs_info)); prf->var_name = varname; prf->label = make_row_label(prf, label, box, top_widget); sep = make_row_middle_separator(prf->label, box, top_widget); prf->text = make_row_text(prf, value, 0, sep, box, top_widget); prf->text_func = text_func; XtAddCallback(prf->text, XmNactivateCallback, call_text_func, (XtPointer)prf); return(prf); } /* ---------------- two texts in a row ---------------- */ static prefs_info *prefs_row_with_two_texts(const char *label, const char *varname, const char *label1, const char *text1, const char *label2, const char *text2, int cols, Widget box, Widget top_widget, void (*text_func)(prefs_info *prf)) { prefs_info *prf = NULL; Widget sep, lab1, lab2; prf = (prefs_info *)calloc(1, sizeof(prefs_info)); prf->var_name = varname; prf->label = make_row_label(prf, label, box, top_widget); sep = make_row_middle_separator(prf->label, box, top_widget); lab1 = make_row_inner_label(prf, label1, sep, box, top_widget); prf->text = make_row_text(prf, text1, cols, lab1, box, top_widget); lab2 = make_row_inner_label(prf, label2, prf->text, box, top_widget); prf->rtxt = make_row_text(prf, text2, cols, lab2, box, top_widget); prf->text_func = text_func; XtAddCallback(prf->text, XmNactivateCallback, call_text_func, (XtPointer)prf); XtAddCallback(prf->rtxt, XmNactivateCallback, call_text_func, (XtPointer)prf); return(prf); } /* ---------------- number row ---------------- */ static prefs_info *prefs_row_with_number(const char *label, const char *varname, const char *value, int cols, Widget box, Widget top_widget, void (*arrow_up_func)(prefs_info *prf), void (*arrow_down_func)(prefs_info *prf), void (*text_func)(prefs_info *prf)) { prefs_info *prf = NULL; Widget sep; prf = (prefs_info *)calloc(1, sizeof(prefs_info)); prf->var_name = varname; prf->label = make_row_label(prf, label, box, top_widget); sep = make_row_middle_separator(prf->label, box, top_widget); prf->text = make_row_text(prf, value, cols, sep, box, top_widget); prf->arrow_up = make_row_arrows(prf, box, prf->text, top_widget); prf->error = make_row_error(prf, box, prf->arrow_up, top_widget); prf->text_func = text_func; prf->arrow_up_func = arrow_up_func; prf->arrow_down_func = arrow_down_func; XtAddCallback(prf->text, XmNactivateCallback, call_text_func, (XtPointer)prf); return(prf); } /* ---------------- list row ---------------- */ typedef struct { prefs_info *prf; char *value; } list_entry; static list_entry *make_list_entry(prefs_info *prf, const char *value) { list_entry *le; le = (list_entry *)calloc(1, sizeof(list_entry)); le->prf = prf; le->value = (char *)value; return(le); } static void prefs_list_callback(Widget w, XtPointer context, XtPointer info) { list_entry *le = (list_entry *)context; if ((le) && (le->prf->list_func)) (*(le->prf->list_func))(le->prf, le->value); } static prefs_info *prefs_row_with_list(const char *label, const char *varname, const char *value, const char **values, int num_values, Widget box, Widget top_widget, void (*text_func)(prefs_info *prf), char *(*completion_func)(widget_t w, const char *text, void *context), void *completion_context, void (*list_func)(prefs_info *prf, char *value)) { Arg args[20]; int n, i, cols = 0; prefs_info *prf = NULL; Widget sep, sbar; prf = (prefs_info *)calloc(1, sizeof(prefs_info)); prf->var_name = varname; prf->label = make_row_label(prf, label, box, top_widget); sep = make_row_middle_separator(prf->label, box, top_widget); /* get text widget size */ for (i = 0; i < num_values; i++) if (values[i]) { int len; len = strlen(values[i]); if (len > cols) cols = len; } n = 0; XtSetArg(args[n], XmNbackground, ss->white); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, top_widget); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, sep); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNcolumns, cols + 1); n++; XtSetArg(args[n], XmNvalue, value); n++; XtSetArg(args[n], XmNmarginHeight, 1); n++; XtSetArg(args[n], XmNborderWidth, 0); n++; XtSetArg(args[n], XmNborderColor, ss->white); n++; XtSetArg(args[n], XmNbottomShadowColor, ss->white); n++; XtSetArg(args[n], XmNshadowThickness, 0); n++; XtSetArg(args[n], XmNtopShadowColor, ss->white); n++; if (completion_func) prf->text = make_textfield_widget("text", box, args, n, ACTIVATABLE_BUT_NOT_FOCUSED, add_completer_func(completion_func, completion_context)); else prf->text = make_textfield_widget("text", box, args, n, ACTIVATABLE_BUT_NOT_FOCUSED, NO_COMPLETER); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, prf->text); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, top_widget); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNshadowThickness, 0); n++; XtSetArg(args[n], XmNhighlightThickness, 0); n++; XtSetArg(args[n], XmNmarginHeight, 0); n++; sbar = XmCreateMenuBar(box, (char *)"menuBar", args, n); XtManageChild(sbar); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; prf->list_menu = XmCreatePulldownMenu(sbar, (char *)"sort-menu", args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNsubMenuId, prf->list_menu); n++; XtSetArg(args[n], XmNshadowThickness, 0); n++; XtSetArg(args[n], XmNhighlightThickness, 0); n++; XtSetArg(args[n], XmNmarginHeight, 1); n++; XtSetArg(args[n], XmNbackground, ss->white); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, top_widget); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, prf->text); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; prf->arrow_right = XtCreateManagedWidget(">", xmCascadeButtonWidgetClass, sbar, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->white); n++; for (i = 0; i < num_values; i++) if (values[i]) { Widget tmp; tmp = XtCreateManagedWidget(values[i], xmPushButtonWidgetClass, prf->list_menu, args, n); XtAddCallback(tmp, XmNactivateCallback, prefs_list_callback, make_list_entry(prf, values[i])); XtAddCallback(tmp, XmNactivateCallback, prefs_change_callback, NULL); } prf->error = make_row_error(prf, box, prf->arrow_right, top_widget); prf->text_func = text_func; XtAddCallback(prf->text, XmNactivateCallback, call_text_func, (XtPointer)prf); XtAddCallback(prf->text, XmNactivateCallback, prefs_change_callback, NULL); XtAddCallback(prf->arrow_right, XmNactivateCallback, prefs_change_callback, NULL); prf->list_func = list_func; return(prf); } /* ---------------- color selector row(s) ---------------- */ static XColor *rgb_to_color_1(mus_float_t r, mus_float_t g, mus_float_t b) { Display *dpy; XColor *new_color; new_color = (XColor *)calloc(1, sizeof(XColor)); new_color->flags = DoRed | DoGreen | DoBlue; new_color->red = float_to_rgb(r); new_color->green = float_to_rgb(g); new_color->blue = float_to_rgb(b); dpy = MAIN_DISPLAY(ss); XAllocColor(dpy, DefaultColormap(dpy, DefaultScreen(dpy)), new_color); return(new_color); } #define COLOR_MAX 90 #define COLOR_MAXF 90.0 #define COLOR_MARGIN 1 static color_t rgb_to_color(mus_float_t r, mus_float_t g, mus_float_t b) { color_t temp; XColor *color; color = rgb_to_color_1(r, g, b); temp = color->pixel; free(color); return(temp); } static void pixel_to_rgb(Pixel pix, float *r, float *g, float *b) { XColor tmp_color; Display *dpy; dpy = XtDisplay(MAIN_SHELL(ss)); tmp_color.flags = DoRed | DoGreen | DoBlue; tmp_color.pixel = pix; XQueryColor(dpy, DefaultColormap(dpy, DefaultScreen(dpy)), &tmp_color); (*r) = rgb_to_float(tmp_color.red); (*g) = rgb_to_float(tmp_color.green); (*b) = rgb_to_float(tmp_color.blue); } static void XmScrollBarGetValue(Widget w, int *val) { XtVaGetValues(w, XmNvalue, val, NULL); } static void XmScrollBarSetValue(Widget w, int val) { XtVaSetValues(w, XmNvalue, val, NULL); } static void reflect_color(prefs_info *prf) { int ir = 0, ig = 0, ib = 0; mus_float_t r, g, b; XColor *current_color; Pixel pixel; XmScrollBarGetValue(prf->rscl, &ir); XmScrollBarGetValue(prf->gscl, &ig); XmScrollBarGetValue(prf->bscl, &ib); current_color = rgb_to_color_1(ir / COLOR_MAXF, ig / COLOR_MAXF, ib / COLOR_MAXF); r = rgb_to_float(current_color->red); g = rgb_to_float(current_color->green); b = rgb_to_float(current_color->blue); pixel = current_color->pixel; free(current_color); current_color = NULL; XtVaSetValues(prf->color, XmNbackground, pixel, NULL); float_to_textfield(prf->rtxt, r); float_to_textfield(prf->gtxt, g); float_to_textfield(prf->btxt, b); } static void prefs_color_callback(Widget w, XtPointer context, XtPointer info) { reflect_color((prefs_info *)context); } static void unpost_color_error(XtPointer data, XtIntervalId *id) { prefs_info *prf = (prefs_info *)data; reflect_color(prf); prf->got_error = false; black_text(prf); set_label(prf->label, prf->saved_label); } static void errors_to_color_text(const char *msg, void *data) { prefs_info *prf = (prefs_info *)data; prf->got_error = true; red_text(prf); set_label(prf->label, msg); XtAppAddTimeOut(MAIN_APP(ss), ERROR_WAIT_TIME, (XtTimerCallbackProc)unpost_color_error, data); } static void prefs_r_callback(Widget w, XtPointer context, XtPointer info) { prefs_info *prf = (prefs_info *)context; char *str; float r; str = XmTextFieldGetString(w); redirect_errors_to(errors_to_color_text, (void *)prf); r = (float)string_to_mus_float_t(str, 0.0, "red amount"); redirect_errors_to(NULL, NULL); XmScrollBarSetValue(prf->rscl, mus_iclamp(0, (int)(COLOR_MAX * r), COLOR_MAX)); if (!(prf->got_error)) reflect_color(prf); if (str) XtFree(str); } static void prefs_g_callback(Widget w, XtPointer context, XtPointer info) { prefs_info *prf = (prefs_info *)context; char *str; float r; str = XmTextFieldGetString(w); redirect_errors_to(errors_to_color_text, (void *)prf); r = (float)string_to_mus_float_t(str, 0.0, "green amount"); redirect_errors_to(NULL, NULL); XmScrollBarSetValue(prf->gscl, mus_iclamp(0, (int)(COLOR_MAX * r), COLOR_MAX)); if (!(prf->got_error)) reflect_color(prf); if (str) XtFree(str); } static void prefs_b_callback(Widget w, XtPointer context, XtPointer info) { prefs_info *prf = (prefs_info *)context; char *str; float r; str = XmTextFieldGetString(w); redirect_errors_to(errors_to_color_text, (void *)prf); r = (float)string_to_mus_float_t(str, 0.0, "blue amount"); redirect_errors_to(NULL, NULL); XmScrollBarSetValue(prf->bscl, mus_iclamp(0, (int)(COLOR_MAX * r), COLOR_MAX)); if (!(prf->got_error)) reflect_color(prf); if (str) XtFree(str); } static void prefs_call_color_func_callback(Widget w, XtPointer context, XtPointer info) { prefs_info *prf = (prefs_info *)context; if ((prf) && (prf->color_func)) { int ir = 0, ig = 0, ib = 0; XmScrollBarGetValue(prf->rscl, &ir); XmScrollBarGetValue(prf->gscl, &ig); XmScrollBarGetValue(prf->bscl, &ib); (*(prf->color_func))(prf, (float)ir / COLOR_MAXF, (float)ig / COLOR_MAXF, (float)ib / COLOR_MAXF); } } static void scale_set_color(prefs_info *prf, color_t pixel) { float r = 0.0, g = 0.0, b = 0.0; pixel_to_rgb(pixel, &r, &g, &b); float_to_textfield(prf->rtxt, r); XmScrollBarSetValue(prf->rscl, (int)(COLOR_MAX * r)); float_to_textfield(prf->gtxt, g); XmScrollBarSetValue(prf->gscl, (int)(COLOR_MAX * g)); float_to_textfield(prf->btxt, b); XmScrollBarSetValue(prf->bscl, (int)(COLOR_MAX * b)); XtVaSetValues(prf->color, XmNbackground, pixel, NULL); } static Pixel red, green, blue; static prefs_info *prefs_color_selector_row(const char *label, const char *varname, Pixel current_pixel, Widget box, Widget top_widget, void (*color_func)(prefs_info *prf, float r, float g, float b)) { Arg args[20]; int n; prefs_info *prf = NULL; Widget sep, sep1, frame; XtCallbackList n1; float r = 0.0, g = 0.0, b = 0.0; prf = (prefs_info *)calloc(1, sizeof(prefs_info)); prf->var_name = varname; pixel_to_rgb(current_pixel, &r, &g, &b); prf->label = make_row_label(prf, label, box, top_widget); sep = make_row_middle_separator(prf->label, box, top_widget); n = 0; XtSetArg(args[n], XmNbackground, current_pixel); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, top_widget); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNbottomWidget, sep); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, sep); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n++; XtSetArg(args[n], XmNrightPosition, PREFS_COLOR_POSITION); n++; XtSetArg(args[n], XmNshadowType, XmSHADOW_ETCHED_IN); n++; frame = XtCreateManagedWidget("frame", xmFrameWidgetClass, box, args, n); n = 0; XtSetArg(args[n], XmNbackground, current_pixel); n++; prf->color = XtCreateManagedWidget("", xmLabelWidgetClass, frame, args, n); sep1 = make_row_inner_separator(8, prf->color, box, top_widget); prf->rtxt = make_row_text(prf, NULL, 6, sep1, box, top_widget); float_to_textfield(prf->rtxt, r); prf->gtxt = make_row_text(prf, NULL, 6, prf->rtxt, box, top_widget); float_to_textfield(prf->gtxt, g); prf->btxt = make_row_text(prf, NULL, 6, prf->gtxt, box, top_widget); float_to_textfield(prf->btxt, b); /* second row = 3 scales */ n1 = make_callback_list(prefs_color_callback, (XtPointer)prf); n = 0; XtSetArg(args[n], XmNbackground, ss->white); n++; XtSetArg(args[n], XmNforeground, red); n++; XtSetArg(args[n], XmNsliderVisual, XmFOREGROUND_COLOR); n++; XtSetArg(args[n], XmNsliderMark, XmTHUMB_MARK); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, prf->label); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; if (FIRST_COLOR_POSITION == 0) { XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; } else { XtSetArg(args[n], XmNleftAttachment, XmATTACH_POSITION); n++; XtSetArg(args[n], XmNleftPosition, FIRST_COLOR_POSITION); n++; } XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n++; XtSetArg(args[n], XmNrightPosition, SECOND_COLOR_POSITION - COLOR_MARGIN); n++; XtSetArg(args[n], XmNmarginHeight, 0); n++; /* scale widget borders are messed up in some Motifs -- they aren't erased correctly in a scrolled window * so, try to use a scrollbar instead. */ XtSetArg(args[n], XmNmaximum, 100); n++; XtSetArg(args[n], XmNheight, 16); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNshowArrows, XmNONE); n++; XtSetArg(args[n], XmNvalue, (int)(COLOR_MAX * r)); n++; XtSetArg(args[n], XmNdragCallback, n1); n++; XtSetArg(args[n], XmNvalueChangedCallback, n1); n++; prf->rscl = XtCreateManagedWidget("", xmScrollBarWidgetClass, box, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->white); n++; XtSetArg(args[n], XmNforeground, green); n++; XtSetArg(args[n], XmNsliderVisual, XmFOREGROUND_COLOR); n++; XtSetArg(args[n], XmNsliderMark, XmTHUMB_MARK); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, prf->label); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_POSITION); n++; XtSetArg(args[n], XmNleftPosition, SECOND_COLOR_POSITION + COLOR_MARGIN); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n++; XtSetArg(args[n], XmNrightPosition, THIRD_COLOR_POSITION - COLOR_MARGIN); n++; XtSetArg(args[n], XmNmarginHeight, 0); n++; XtSetArg(args[n], XmNmaximum, 100); n++; XtSetArg(args[n], XmNheight, 16); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNshowArrows, XmNONE); n++; XtSetArg(args[n], XmNvalue, (int)(COLOR_MAX * g)); n++; XtSetArg(args[n], XmNdragCallback, n1); n++; XtSetArg(args[n], XmNvalueChangedCallback, n1); n++; prf->gscl = XtCreateManagedWidget("", xmScrollBarWidgetClass, box, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->white); n++; XtSetArg(args[n], XmNforeground, blue); n++; XtSetArg(args[n], XmNsliderVisual, XmFOREGROUND_COLOR); n++; XtSetArg(args[n], XmNsliderMark, XmTHUMB_MARK); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, prf->label); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_POSITION); n++; XtSetArg(args[n], XmNleftPosition, THIRD_COLOR_POSITION + COLOR_MARGIN); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n++; XtSetArg(args[n], XmNrightPosition, 80); n++; XtSetArg(args[n], XmNmarginHeight, 0); n++; XtSetArg(args[n], XmNmaximum, 100); n++; XtSetArg(args[n], XmNheight, 16); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNshowArrows, XmNONE); n++; XtSetArg(args[n], XmNvalue, (int)(COLOR_MAX * b)); n++; XtSetArg(args[n], XmNdragCallback, n1); n++; XtSetArg(args[n], XmNvalueChangedCallback, n1); n++; prf->bscl = XtCreateManagedWidget("", xmScrollBarWidgetClass, box, args, n); XtAddCallback(prf->rtxt, XmNactivateCallback, prefs_r_callback, (XtPointer)prf); XtAddCallback(prf->gtxt, XmNactivateCallback, prefs_g_callback, (XtPointer)prf); XtAddCallback(prf->btxt, XmNactivateCallback, prefs_b_callback, (XtPointer)prf); XtAddCallback(prf->rscl, XmNvalueChangedCallback, prefs_call_color_func_callback, (XtPointer)prf); XtAddCallback(prf->gscl, XmNvalueChangedCallback, prefs_call_color_func_callback, (XtPointer)prf); XtAddCallback(prf->bscl, XmNvalueChangedCallback, prefs_call_color_func_callback, (XtPointer)prf); XtAddCallback(prf->rscl, XmNvalueChangedCallback, prefs_change_callback, NULL); XtAddCallback(prf->gscl, XmNvalueChangedCallback, prefs_change_callback, NULL); XtAddCallback(prf->bscl, XmNvalueChangedCallback, prefs_change_callback, NULL); prf->color_func = color_func; free(n1); return(prf); } /* ---------------- topic separator ---------------- */ static Widget make_inter_topic_separator(Widget topics) { int n; Arg args[20]; n = 0; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNheight, INTER_TOPIC_SPACE); n++; XtSetArg(args[n], XmNseparatorType, XmNO_LINE); n++; return(XtCreateManagedWidget("sep", xmSeparatorWidgetClass, topics, args, n)); } /* ---------------- variable separator ---------------- */ static Widget make_inter_variable_separator(Widget topics, Widget top_widget) { int n; Arg args[20]; n = 0; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, top_widget); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNheight, INTER_VARIABLE_SPACE); n++; XtSetArg(args[n], XmNseparatorType, XmNO_LINE); n++; return(XtCreateManagedWidget("sep", xmSeparatorWidgetClass, topics, args, n)); } /* ---------------- top-level contents label ---------------- */ static Widget make_top_level_label(const char *label, Widget parent) { int n; Arg args[20]; n = 0; XtSetArg(args[n], XmNbackground, ss->light_blue); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(args[n], XmNheight, 32); n++; return(XtCreateManagedWidget(label, xmLabelWidgetClass, parent, args, n)); } static Widget make_top_level_box(Widget topics) { Widget frame; int n; Arg args[20]; n = 0; XtSetArg(args[n], XmNbackground, ss->white); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; frame = XtCreateManagedWidget("pref-frame", xmFrameWidgetClass, topics, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->white); n++; return(XtCreateManagedWidget("pref-box", xmFormWidgetClass, frame, args, n)); } static Widget make_inner_label(const char *label, Widget parent, Widget top_widget) { int n; Arg args[20]; n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, top_widget); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(args[n], XmNheight, 32); n++; return(XtCreateManagedWidget(label, xmLabelWidgetClass, parent, args, n)); } /* ---------------- base buttons ---------------- */ static void wm_delete_callback(Widget w, XtPointer context, XtPointer info) { clear_prefs_dialog_error(); } static void preferences_help_callback(Widget w, XtPointer context, XtPointer info) { snd_help("preferences", "This dialog sets various global variables. 'Save' then writes the new values \ to ~/.snd_prefs_ruby|forth|s7 so that they take effect the next time you start Snd. 'Revert' resets each variable either to \ its value when the Preferences dialog was started, or to the last saved value. 'Clear' resets each variable to its default value (its \ value when Snd starts, before loading initialization files). 'Help' starts this dialog, and as long as it's active, it will post helpful \ information if the mouse lingers over some variable -- sort of a tooltip that stays out of your way. \ You can also request help on a given topic by clicking the variable name on the far right.", WITH_WORD_WRAP); } static void preferences_quit_callback(Widget w, XtPointer context, XtPointer info) { clear_prefs_dialog_error(); if (XmGetFocusWidget(preferences_dialog) == XmMessageBoxGetChild(preferences_dialog, XmDIALOG_CANCEL_BUTTON)) XtUnmanageChild(preferences_dialog); } static void prefs_set_dialog_title(const char *filename) { XmString title; char *str; if (filename) { if (prefs_saved_filename) free(prefs_saved_filename); prefs_saved_filename = mus_strdup(filename); } if (prefs_saved_filename) str = mus_format("Preferences%s (saved in %s)\n", (prefs_unsaved) ? "*" : "", prefs_saved_filename); else str = mus_format("Preferences%s", (prefs_unsaved) ? "*" : ""); title = XmStringCreateLocalized(str); free(str); XtVaSetValues(preferences_dialog, XmNdialogTitle, title, NULL); XmStringFree(title); } static void preferences_revert_callback(Widget w, XtPointer context, XtPointer info) { preferences_revert_or_clear(true); } static void preferences_clear_callback(Widget w, XtPointer context, XtPointer info) { preferences_revert_or_clear(false); } #if HAVE_EXTENSION_LANGUAGE static void preferences_save_callback(Widget w, XtPointer context, XtPointer info) { clear_prefs_dialog_error(); redirect_snd_error_to(post_prefs_dialog_error, NULL); redirect_snd_warning_to(post_prefs_dialog_error, NULL); save_prefs(); redirect_snd_error_to(NULL, NULL); redirect_snd_warning_to(NULL, NULL); } #endif /* ---------------- errors ---------------- */ static void clear_prefs_error(Widget w, XtPointer context, XtPointer info) { prefs_info *prf = (prefs_info *)context; XtRemoveCallback(prf->text, XmNvalueChangedCallback, clear_prefs_error, context); set_label(prf->error, ""); } static void post_prefs_error(const char *msg, prefs_info *prf) { prf->got_error = true; set_label(prf->error, msg); XtAddCallback(prf->text, XmNvalueChangedCallback, clear_prefs_error, (XtPointer)prf); } static void va_post_prefs_error(const char *msg, prefs_info *data, ...) { char *buf; va_list ap; va_start(ap, data); buf = vstr(msg, ap); va_end(ap); post_prefs_error(buf, data); free(buf); } /* ---------------- preferences dialog ---------------- */ widget_t make_preferences_dialog(void) { Arg args[20]; Widget scroller, topics, current_sep; char *str; prefs_info *prf; if (preferences_dialog) { /* I don't think this should reflect current state except when it is created */ if (!(XtIsManaged(preferences_dialog))) XtManageChild(preferences_dialog); else raise_dialog(preferences_dialog); return(preferences_dialog); } /* -------- base buttons -------- */ { int n; XmString title, help, revert, clear, save, go_away; Widget clear_button, revert_button; #if HAVE_EXTENSION_LANGUAGE Widget save_button; save = XmStringCreateLocalized((char *)"Save"); #endif title = XmStringCreateLocalized((char *)"Preferences"); help = XmStringCreateLocalized((char *)I_HELP); revert = XmStringCreateLocalized((char *)"Revert"); clear = XmStringCreateLocalized((char *)"Clear"); go_away = XmStringCreateLocalized((char *)I_GO_AWAY); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNresizePolicy, XmRESIZE_GROW); n++; XtSetArg(args[n], XmNnoResize, false); n++; XtSetArg(args[n], XmNtransient, false); n++; XtSetArg(args[n], XmNcancelLabelString, go_away); n++; XtSetArg(args[n], XmNhelpLabelString, help); n++; XtSetArg(args[n], XmNokLabelString, revert); n++; XtSetArg(args[n], XmNdialogTitle, title); n++; XtSetArg(args[n], XmNallowShellResize, true); n++; XtSetArg(args[n], XmNautoUnmanage, false); n++; { Dimension width, height; width = XDisplayWidth(MAIN_DISPLAY(ss), DefaultScreen(MAIN_DISPLAY(ss))); height = XDisplayHeight(MAIN_DISPLAY(ss), DefaultScreen(MAIN_DISPLAY(ss))); XtSetArg(args[n], XmNwidth, (STARTUP_WIDTH < width) ? (Dimension)STARTUP_WIDTH : ((Dimension)(width - 50))); n++; XtSetArg(args[n], XmNheight, (STARTUP_HEIGHT < height) ? (Dimension)STARTUP_HEIGHT : ((Dimension)(height - 50))); n++; } preferences_dialog = XmCreateTemplateDialog(MAIN_PANE(ss), (char *)"preferences", args, n); revert_button = XmMessageBoxGetChild(preferences_dialog, XmDIALOG_OK_BUTTON); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNarmColor, ss->selection_color); n++; clear_button = XtCreateManagedWidget("Clear", xmPushButtonGadgetClass, preferences_dialog, args, n); #if HAVE_EXTENSION_LANGUAGE n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNarmColor, ss->selection_color); n++; save_button = XtCreateManagedWidget("Save", xmPushButtonGadgetClass, preferences_dialog, args, n); XtAddCallback(save_button, XmNactivateCallback, preferences_save_callback, NULL); #endif XtAddCallback(preferences_dialog, XmNcancelCallback, preferences_quit_callback, NULL); XtAddCallback(preferences_dialog, XmNhelpCallback, preferences_help_callback, NULL); /* XtAddCallback(preferences_dialog, XmNokCallback, preferences_revert_callback, NULL); */ XtAddCallback(revert_button, XmNactivateCallback, preferences_revert_callback, NULL); XtAddCallback(clear_button, XmNactivateCallback, preferences_clear_callback, NULL); XmStringFree(title); XmStringFree(help); #if HAVE_EXTENSION_LANGUAGE XmStringFree(save); #endif XmStringFree(go_away); XmStringFree(revert); XmStringFree(clear); map_over_children(preferences_dialog, set_main_color_of_widget); #if HAVE_EXTENSION_LANGUAGE XtVaSetValues(XmMessageBoxGetChild(preferences_dialog, XmDIALOG_CANCEL_BUTTON), XmNarmColor, ss->selection_color, NULL); XtVaSetValues(XmMessageBoxGetChild(preferences_dialog, XmDIALOG_CANCEL_BUTTON), XmNbackground, ss->highlight_color, NULL); #endif XtVaSetValues(XmMessageBoxGetChild(preferences_dialog, XmDIALOG_OK_BUTTON), XmNarmColor, ss->selection_color, NULL); XtVaSetValues(XmMessageBoxGetChild(preferences_dialog, XmDIALOG_HELP_BUTTON), XmNarmColor, ss->selection_color, NULL); XtVaSetValues(XmMessageBoxGetChild(preferences_dialog, XmDIALOG_OK_BUTTON), XmNbackground, ss->highlight_color, NULL); XtVaSetValues(XmMessageBoxGetChild(preferences_dialog, XmDIALOG_HELP_BUTTON), XmNbackground, ss->highlight_color, NULL); n = 0; XtSetArg(args[n], XmNbackground, ss->white); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNbottomWidget, XmMessageBoxGetChild(preferences_dialog, XmDIALOG_SEPARATOR)); n++; XtSetArg(args[n], XmNscrollingPolicy, XmAUTOMATIC); n++; XtSetArg(args[n], XmNscrollBarDisplayPolicy, XmSTATIC); n++; scroller = XmCreateScrolledWindow(preferences_dialog, (char *)"pref-scroller", args, n); XtManageChild(scroller); n = attach_all_sides(args, 0); XtSetArg(args[n], XmNbackground, ss->white); n++; XtSetArg(args[n], XmNorientation, XmVERTICAL); n++; topics = XtCreateManagedWidget("pref-topics", xmRowColumnWidgetClass, scroller, args, n); XtVaSetValues(scroller, XmNworkWindow, topics, NULL); } red = rgb_to_color(1.0, 0.0, 0.0); green = rgb_to_color(0.0, 1.0, 0.0); blue = rgb_to_color(0.0, 0.0, 1.0); /* ---------------- overall behavior ---------------- */ { Widget dpy_box, dpy_label, file_label, cursor_label, key_label; char *str1, *str2; /* ---------------- overall behavior ----------------*/ dpy_box = make_top_level_box(topics); dpy_label = make_top_level_label("overall behavior choices", dpy_box); current_sep = dpy_label; str1 = mus_format("%d", ss->init_window_width); str2 = mus_format("%d", ss->init_window_height); rts_init_window_width = ss->init_window_width; rts_init_window_height = ss->init_window_height; prf = prefs_row_with_two_texts("start up size", S_window_width, "width:", str1, "height:", str2, 6, dpy_box, current_sep, startup_size_text); remember_pref(prf, reflect_init_window_size, save_init_window_size, help_init_window_size, clear_init_window_size, revert_init_window_size); free(str2); free(str1); current_sep = make_inter_variable_separator(dpy_box, prf->label); prf = prefs_row_with_toggle("ask before overwriting anything", S_ask_before_overwrite, rts_ask_before_overwrite = ask_before_overwrite(ss), dpy_box, current_sep, overwrite_toggle); remember_pref(prf, reflect_ask_before_overwrite, save_ask_before_overwrite, help_ask_before_overwrite, NULL, revert_ask_before_overwrite); current_sep = make_inter_variable_separator(dpy_box, prf->label); prf = prefs_row_with_toggle("ask about unsaved edits before exiting", S_ask_about_unsaved_edits, rts_unsaved_edits = ask_about_unsaved_edits(ss), dpy_box, current_sep, unsaved_edits_toggle); remember_pref(prf, reflect_unsaved_edits, save_unsaved_edits, help_unsaved_edits, clear_unsaved_edits, revert_unsaved_edits); current_sep = make_inter_variable_separator(dpy_box, prf->label); prf = prefs_row_with_toggle("include thumbnail graph in upper right corner", S_with_inset_graph, rts_with_inset_graph = with_inset_graph(ss), dpy_box, current_sep, with_inset_graph_toggle); remember_pref(prf, reflect_with_inset_graph, save_with_inset_graph, help_inset_graph, clear_with_inset_graph, revert_with_inset_graph); current_sep = make_inter_variable_separator(dpy_box, prf->label); prf = prefs_row_with_toggle("resize main window as sounds open and close", S_auto_resize, rts_auto_resize = auto_resize(ss), dpy_box, current_sep, resize_toggle); remember_pref(prf, reflect_auto_resize, save_auto_resize, help_auto_resize, NULL, revert_auto_resize); current_sep = make_inter_variable_separator(dpy_box, prf->label); prf = prefs_row_with_toggle("pointer focus", S_with_pointer_focus, rts_with_pointer_focus = with_pointer_focus(ss), dpy_box, current_sep, with_pointer_focus_toggle); remember_pref(prf, reflect_with_pointer_focus, save_with_pointer_focus, help_pointer_focus, clear_with_pointer_focus, revert_with_pointer_focus); current_sep = make_inter_variable_separator(dpy_box, prf->label); rts_sync_style = sync_style(ss); prf = prefs_row_with_two_toggles("operate on all channels together", S_sync, "within each sound", rts_sync_style == SYNC_BY_SOUND, "across all sounds", rts_sync_style == SYNC_ALL, dpy_box, current_sep, sync1_choice, sync2_choice); remember_pref(prf, reflect_sync_style, save_sync_style, help_sync_style, clear_sync_style, revert_sync_style); current_sep = make_inter_variable_separator(dpy_box, prf->label); rts_remember_sound_state = remember_sound_state(ss); prf = prefs_row_with_toggle("restore a sound's state if reopened later", S_remember_sound_state, rts_remember_sound_state, dpy_box, current_sep, toggle_remember_sound_state); remember_pref(prf, reflect_remember_sound_state, save_remember_sound_state, help_remember_sound_state, clear_remember_sound_state, revert_remember_sound_state); current_sep = make_inter_variable_separator(dpy_box, prf->label); prf = prefs_row_with_toggle("show the control panel upon opening a sound", S_show_controls, rts_show_controls = in_show_controls(ss), dpy_box, current_sep, controls_toggle); remember_pref(prf, reflect_show_controls, save_show_controls, help_show_controls, NULL, revert_show_controls); current_sep = make_inter_variable_separator(dpy_box, prf->label); include_peak_env_directory = mus_strdup(peak_env_dir(ss)); rts_peak_env_directory = mus_strdup(include_peak_env_directory); include_peak_envs = find_peak_envs(); rts_peak_envs = include_peak_envs; prf = prefs_row_with_toggle_with_text("save peak envs to speed up initial display", S_peak_env_dir, include_peak_envs, "directory:", include_peak_env_directory, 25, dpy_box, current_sep, peak_envs_toggle, peak_envs_text); remember_pref(prf, reflect_peak_envs, save_peak_envs, help_peak_envs, clear_peak_envs, revert_peak_envs); current_sep = make_inter_variable_separator(dpy_box, prf->label); str = mus_format("%d", rts_max_regions = max_regions(ss)); prf = prefs_row_with_toggle_with_text("selection creates an associated region", S_selection_creates_region, rts_selection_creates_region = selection_creates_region(ss), "max regions:", str, 5, dpy_box, current_sep, selection_creates_region_toggle, max_regions_text); remember_pref(prf, reflect_selection_creates_region, save_selection_creates_region, help_selection_creates_region, NULL, revert_selection_creates_region); free(str); current_sep = make_inter_variable_separator(dpy_box, prf->label); rts_with_toolbar = with_toolbar(ss); prf = prefs_row_with_toggle("include a toolbar", S_with_toolbar, rts_with_toolbar, dpy_box, current_sep, toggle_with_toolbar); remember_pref(prf, reflect_with_toolbar, save_with_toolbar, help_with_toolbar, clear_with_toolbar, revert_with_toolbar); current_sep = make_inter_variable_separator(dpy_box, prf->label); rts_with_tooltips = with_tooltips(ss); prf = prefs_row_with_toggle("enable tooltips", S_with_tooltips, rts_with_tooltips, dpy_box, current_sep, toggle_with_tooltips); remember_pref(prf, reflect_with_tooltips, save_with_tooltips, help_with_tooltips, clear_with_tooltips, revert_with_tooltips); /* ---------------- file options ---------------- */ current_sep = make_inter_variable_separator(dpy_box, prf->label); file_label = make_inner_label(" file options", dpy_box, current_sep); rts_load_path = find_sources(); prf = prefs_row_with_text("directory containing Snd's " Xen_language " files", "load path", rts_load_path, dpy_box, file_label, load_path_text); remember_pref(prf, reflect_load_path, NULL, help_load_path, clear_load_path, revert_load_path); load_path_text_widget = prf->text; current_sep = make_inter_variable_separator(dpy_box, prf->label); prf = prefs_row_with_toggle("display only sound files in various file lists", S_just_sounds, rts_just_sounds = just_sounds(ss), dpy_box, current_sep, just_sounds_toggle); remember_pref(prf, prefs_reflect_just_sounds, save_just_sounds, help_just_sounds, NULL, revert_just_sounds); current_sep = make_inter_variable_separator(dpy_box, prf->label); rts_temp_dir = mus_strdup(temp_dir(ss)); prf = prefs_row_with_text("directory for temporary files", S_temp_dir, temp_dir(ss), dpy_box, current_sep, temp_dir_text); remember_pref(prf, reflect_temp_dir, save_temp_dir, help_temp_dir, NULL, revert_temp_dir); current_sep = make_inter_variable_separator(dpy_box, prf->label); rts_save_dir = mus_strdup(save_dir(ss)); prf = prefs_row_with_text("directory for save-state files", S_save_dir, save_dir(ss), dpy_box, current_sep, save_dir_text); remember_pref(prf, reflect_save_dir, save_save_dir, help_save_dir, NULL, revert_save_dir); current_sep = make_inter_variable_separator(dpy_box, prf->label); rts_save_state_file = mus_strdup(save_state_file(ss)); prf = prefs_row_with_text("default save-state filename", S_save_state_file, save_state_file(ss), dpy_box, current_sep, save_state_file_text); remember_pref(prf, reflect_save_state_file, save_save_state_file, help_save_state_file, NULL, revert_save_state_file); #if HAVE_LADSPA current_sep = make_inter_variable_separator(dpy_box, prf->label); rts_ladspa_dir = mus_strdup(ladspa_dir(ss)); prf = prefs_row_with_text("directory for ladspa plugins", S_ladspa_dir, ladspa_dir(ss), dpy_box, current_sep, ladspa_dir_text); remember_pref(prf, reflect_ladspa_dir, save_ladspa_dir, help_ladspa_dir, NULL, revert_ladspa_dir); #endif current_sep = make_inter_variable_separator(dpy_box, prf->label); rts_vf_directory = mus_strdup(view_files_find_any_directory()); prf = prefs_row_with_text("directory for view-files dialog", S_add_directory_to_view_files_list, rts_vf_directory, dpy_box, current_sep, view_files_directory_text); remember_pref(prf, reflect_view_files_directory, save_view_files_directory, help_view_files_directory, NULL, revert_view_files_directory); current_sep = make_inter_variable_separator(dpy_box, prf->label); rts_html_program = mus_strdup(html_program(ss)); prf = prefs_row_with_text("external program to read HTML files via snd-help", S_html_program, html_program(ss), dpy_box, current_sep, html_program_text); remember_pref(prf, reflect_html_program, save_html_program, help_html_program, NULL, revert_html_program); current_sep = make_inter_variable_separator(dpy_box, prf->label); rts_default_output_chans = default_output_chans(ss); prf = prefs_row_with_radio_box("default new sound attributes: chans", S_default_output_chans, output_chan_choices, NUM_OUTPUT_CHAN_CHOICES, -1, dpy_box, current_sep, default_output_chans_choice); remember_pref(prf, reflect_default_output_chans, save_default_output_chans, help_default_output_chans, NULL, revert_default_output_chans); reflect_default_output_chans(prf); rts_default_output_srate = default_output_srate(ss); prf = prefs_row_with_radio_box("srate", S_default_output_srate, output_srate_choices, NUM_OUTPUT_SRATE_CHOICES, -1, dpy_box, prf->label, default_output_srate_choice); remember_pref(prf, reflect_default_output_srate, save_default_output_srate, help_default_output_srate, NULL, revert_default_output_srate); reflect_default_output_srate(prf); rts_default_output_header_type = default_output_header_type(ss); prf = prefs_row_with_radio_box("header type", S_default_output_header_type, output_header_type_choices, NUM_OUTPUT_HEADER_TYPE_CHOICES, -1, dpy_box, prf->label, default_output_header_type_choice); output_header_type_prf = prf; remember_pref(prf, reflect_default_output_header_type, save_default_output_header_type, help_default_output_header_type, NULL, revert_default_output_header_type); rts_default_output_sample_type = default_output_sample_type(ss); prf = prefs_row_with_radio_box("sample type", S_default_output_sample_type, output_sample_type_choices, NUM_OUTPUT_SAMPLE_TYPE_CHOICES, -1, dpy_box, prf->label, default_output_sample_type_choice); output_sample_type_prf = prf; remember_pref(prf, reflect_default_output_sample_type, save_default_output_sample_type, help_default_output_sample_type, NULL, revert_default_output_sample_type); reflect_default_output_header_type(output_header_type_prf); reflect_default_output_sample_type(output_sample_type_prf); current_sep = make_inter_variable_separator(dpy_box, prf->label); { int i, srate = 0, chans = 0; mus_sample_t sample_type = MUS_UNKNOWN_SAMPLE; mus_header_raw_defaults(&srate, &chans, &sample_type); rts_raw_chans = chans; rts_raw_srate = srate; rts_raw_sample_type = sample_type; str = mus_format("%d", chans); str1 = mus_format("%d", srate); raw_sample_type_choices = (char **)calloc(MUS_NUM_SAMPLES - 1, sizeof(char *)); for (i = 1; i < MUS_NUM_SAMPLES; i++) raw_sample_type_choices[i - 1] = raw_sample_type_to_string((mus_sample_t)i); /* skip MUS_UNKNOWN_SAMPLE = 0 */ prf = prefs_row_with_text("default raw sound attributes: chans", S_mus_header_raw_defaults, str, dpy_box, current_sep, raw_chans_choice); remember_pref(prf, reflect_raw_chans, save_raw_chans, help_raw_chans, NULL, revert_raw_chans); prf = prefs_row_with_text("srate", S_mus_header_raw_defaults, str1, dpy_box, prf->label, raw_srate_choice); remember_pref(prf, reflect_raw_srate, save_raw_srate, help_raw_srate, NULL, revert_raw_srate); prf = prefs_row_with_list("sample type", S_mus_header_raw_defaults, raw_sample_type_choices[sample_type - 1], (const char **)raw_sample_type_choices, MUS_NUM_SAMPLES - 1, dpy_box, prf->label, raw_sample_type_from_text, NULL, NULL, raw_sample_type_from_menu); remember_pref(prf, reflect_raw_sample_type, save_raw_sample_type, help_raw_sample_type, NULL, revert_raw_sample_type); free(str); free(str1); } /* ---------------- additional keys ---------------- */ current_sep = make_inter_variable_separator(dpy_box, prf->label); key_label = make_inner_label(" additional keys", dpy_box, current_sep); { key_info *ki; ki = find_prefs_key("play-from-cursor"); prf = prefs_row_with_text_and_three_toggles("play all chans from cursor", S_play, "key:", 8, "ctrl:", "meta:", "C-x:", ki->key, ki->c, ki->m, ki->x, dpy_box, key_label, bind_play_from_cursor); remember_pref(prf, reflect_play_from_cursor, save_pfc, help_play_from_cursor, clear_play_from_cursor, NULL); free(ki); current_sep = make_inter_variable_separator(dpy_box, prf->label); ki = find_prefs_key("show-all"); prf = prefs_row_with_text_and_three_toggles("show entire sound", S_x_bounds, "key:", 8, "ctrl:", "meta:", "C-x:", ki->key, ki->c, ki->m, ki->x, dpy_box, current_sep, bind_show_all); remember_pref(prf, reflect_show_all, save_show_all, help_show_all, clear_show_all, NULL); free(ki); current_sep = make_inter_variable_separator(dpy_box, prf->label); ki = find_prefs_key("select-all"); prf = prefs_row_with_text_and_three_toggles("select entire sound", S_select_all, "key:", 8, "ctrl:", "meta:", "C-x:", ki->key, ki->c, ki->m, ki->x, dpy_box, current_sep, bind_select_all); remember_pref(prf, reflect_select_all, save_select_all, help_select_all, clear_select_all, NULL); free(ki); current_sep = make_inter_variable_separator(dpy_box, prf->label); ki = find_prefs_key("show-selection"); prf = prefs_row_with_text_and_three_toggles("show current selection", "show-selection", "key:", 8, "ctrl:", "meta:", "C-x:", ki->key, ki->c, ki->m, ki->x, dpy_box, current_sep, bind_show_selection); remember_pref(prf, reflect_show_selection, save_show_selection, help_show_selection, clear_show_selection, NULL); free(ki); current_sep = make_inter_variable_separator(dpy_box, prf->label); ki = find_prefs_key("revert-sound"); prf = prefs_row_with_text_and_three_toggles("undo all edits (revert)", S_revert_sound, "key:", 8, "ctrl:", "meta:", "C-x:", ki->key, ki->c, ki->m, ki->x, dpy_box, current_sep, bind_revert); remember_pref(prf, reflect_revert, save_revert, help_revert, clear_revert_sound, NULL); free(ki); current_sep = make_inter_variable_separator(dpy_box, prf->label); ki = find_prefs_key("exit"); prf = prefs_row_with_text_and_three_toggles("exit from Snd", S_exit, "key:", 8, "ctrl:", "meta:", "C-x:", ki->key, ki->c, ki->m, ki->x, dpy_box, current_sep, bind_exit); remember_pref(prf, reflect_exit, save_exit, help_exit, clear_exit, NULL); free(ki); current_sep = make_inter_variable_separator(dpy_box, prf->label); ki = find_prefs_key("goto-maxamp"); prf = prefs_row_with_text_and_three_toggles("move cursor to channel's maximum sample", S_maxamp_position, "key:", 8, "ctrl:", "meta:", "C-x:", ki->key, ki->c, ki->m, ki->x, dpy_box, current_sep, bind_goto_maxamp); remember_pref(prf, reflect_goto_maxamp, save_goto_maxamp, help_goto_maxamp, clear_goto_maxamp, NULL); free(ki); } /* ---------------- cursor options ---------------- */ current_sep = make_inter_variable_separator(dpy_box, prf->label); cursor_label = make_inner_label(" cursor options", dpy_box, current_sep); prf = prefs_row_with_toggle("report cursor location as it moves", S_with_verbose_cursor, rts_with_verbose_cursor = with_verbose_cursor(ss), dpy_box, cursor_label, with_verbose_cursor_toggle); remember_pref(prf, reflect_with_verbose_cursor, save_with_verbose_cursor, help_with_verbose_cursor, NULL, revert_with_verbose_cursor); current_sep = make_inter_variable_separator(dpy_box, prf->label); { char *str1; str = mus_format("%.2f", rts_cursor_update_interval = cursor_update_interval(ss)); str1 = mus_format("%d", rts_cursor_location_offset = cursor_location_offset(ss)); prf = prefs_row_with_toggle_with_two_texts("track current location while playing", S_with_tracking_cursor, (rts_with_tracking_cursor = with_tracking_cursor(ss)), "update:", str, "offset:", str1, 8, dpy_box, current_sep, with_tracking_cursor_toggle, cursor_location_text); remember_pref(prf, reflect_with_tracking_cursor, save_with_tracking_cursor, help_with_tracking_cursor, NULL, revert_with_tracking_cursor); free(str); free(str1); } current_sep = make_inter_variable_separator(dpy_box, prf->label); str = mus_format("%d", rts_cursor_size = cursor_size(ss)); prf = prefs_row_with_number("size", S_cursor_size, str, 4, dpy_box, current_sep, cursor_size_up, cursor_size_down, cursor_size_from_text); remember_pref(prf, reflect_cursor_size, save_cursor_size, help_cursor_size, NULL, revert_cursor_size); free(str); if (cursor_size(ss) <= 0) XtSetSensitive(prf->arrow_down, false); current_sep = make_inter_variable_separator(dpy_box, prf->label); prf = prefs_row_with_radio_box("shape", S_cursor_style, cursor_styles, NUM_CURSOR_STYLES, rts_cursor_style = cursor_style(ss), dpy_box, current_sep, cursor_style_choice); remember_pref(prf, reflect_cursor_style, save_cursor_style, help_cursor_style, NULL, revert_cursor_style); current_sep = make_inter_variable_separator(dpy_box, prf->label); prf = prefs_row_with_radio_box("tracking cursor shape", S_tracking_cursor_style, cursor_styles, NUM_CURSOR_STYLES, rts_tracking_cursor_style = tracking_cursor_style(ss), dpy_box, current_sep, tracking_cursor_style_choice); remember_pref(prf, reflect_tracking_cursor_style, save_tracking_cursor_style, help_tracking_cursor_style, NULL, revert_tracking_cursor_style); current_sep = make_inter_variable_separator(dpy_box, prf->label); saved_cursor_color = ss->cursor_color; prf = prefs_color_selector_row("color", S_cursor_color, ss->cursor_color, dpy_box, current_sep, cursor_color_func); remember_pref(prf, NULL, save_cursor_color, help_cursor_color, clear_cursor_color, revert_cursor_color); /* ---------------- (overall) colors ---------------- */ current_sep = make_inter_variable_separator(dpy_box, prf->rscl); cursor_label = make_inner_label(" colors", dpy_box, current_sep); saved_basic_color = ss->basic_color; prf = prefs_color_selector_row("main background color", S_basic_color, ss->basic_color, dpy_box, cursor_label, basic_color_func); remember_pref(prf, NULL, save_basic_color, help_basic_color, clear_basic_color, revert_basic_color); current_sep = make_inter_variable_separator(dpy_box, prf->rscl); saved_highlight_color = ss->highlight_color; prf = prefs_color_selector_row("main highlight color", S_highlight_color, ss->highlight_color, dpy_box, current_sep, highlight_color_func); remember_pref(prf, NULL, save_highlight_color, help_highlight_color, clear_highlight_color, revert_highlight_color); current_sep = make_inter_variable_separator(dpy_box, prf->rscl); saved_position_color = ss->position_color; prf = prefs_color_selector_row("second highlight color", S_position_color, ss->position_color, dpy_box, current_sep, position_color_func); remember_pref(prf, NULL, save_position_color, help_position_color, clear_position_color, revert_position_color); current_sep = make_inter_variable_separator(dpy_box, prf->rscl); saved_zoom_color = ss->zoom_color; prf = prefs_color_selector_row("third highlight color", S_zoom_color, ss->zoom_color, dpy_box, current_sep, zoom_color_func); remember_pref(prf, NULL, save_zoom_color, help_zoom_color, clear_zoom_color, revert_zoom_color); } current_sep = make_inter_topic_separator(topics); /* -------- graphs -------- */ { Widget grf_box, grf_label, colgrf_label; /* ---------------- graph options ---------------- */ grf_box = make_top_level_box(topics); grf_label = make_top_level_label("graph options", grf_box); prf = prefs_row_with_radio_box("how to connect the dots", S_graph_style, graph_styles, NUM_GRAPH_STYLES, rts_graph_style = graph_style(ss), grf_box, grf_label, graph_style_choice); remember_pref(prf, reflect_graph_style, save_graph_style, help_graph_style, NULL, revert_graph_style); current_sep = make_inter_variable_separator(grf_box, prf->label); str = mus_format("%d", rts_dot_size = dot_size(ss)); prf = prefs_row_with_number("dot size", S_dot_size, str, 4, grf_box, current_sep, dot_size_up, dot_size_down, dot_size_from_text); remember_pref(prf, reflect_dot_size, save_dot_size, help_dot_size, NULL, revert_dot_size); free(str); if (dot_size(ss) <= 0) XtSetSensitive(prf->arrow_down, false); current_sep = make_inter_variable_separator(grf_box, prf->label); rts_initial_beg = initial_beg(ss); rts_initial_dur = initial_dur(ss); str = mus_format("%.2f : %.2f", rts_initial_beg, rts_initial_dur); prf = prefs_row_with_text_with_toggle("initial graph x bounds", S_initial_graph_hook, (rts_full_duration = show_full_duration(ss)), "show full duration", str, 16, grf_box, current_sep, initial_bounds_toggle, initial_bounds_text); free(str); remember_pref(prf, reflect_initial_bounds, save_initial_bounds, help_initial_bounds, clear_initial_bounds, revert_initial_bounds); current_sep = make_inter_variable_separator(grf_box, prf->label); prf = prefs_row_with_radio_box("how to layout multichannel graphs", S_channel_style, channel_styles, NUM_CHANNEL_STYLES, rts_channel_style = channel_style(ss), grf_box, current_sep, channel_style_choice); remember_pref(prf, reflect_channel_style, save_channel_style, help_channel_style, NULL, revert_channel_style); current_sep = make_inter_variable_separator(grf_box, prf->label); prf = prefs_row_with_toggle("layout wave and fft graphs horizontally", S_graphs_horizontal, rts_graphs_horizontal = graphs_horizontal(ss), grf_box, current_sep, graphs_horizontal_toggle); remember_pref(prf, reflect_graphs_horizontal, save_graphs_horizontal, help_graphs_horizontal, NULL, revert_graphs_horizontal); current_sep = make_inter_variable_separator(grf_box, prf->label); prf = prefs_row_with_toggle("include y=0 line in sound graphs", S_show_y_zero, rts_show_y_zero = show_y_zero(ss), grf_box, current_sep, y_zero_toggle); remember_pref(prf, reflect_show_y_zero, save_show_y_zero, help_show_y_zero, NULL, revert_show_y_zero); current_sep = make_inter_variable_separator(grf_box, prf->label); rts_show_grid = show_grid(ss); prf = prefs_row_with_toggle("include a grid in sound graphs", S_show_grid, rts_show_grid == WITH_GRID, grf_box, current_sep, grid_toggle); remember_pref(prf, reflect_show_grid, save_show_grid, help_show_grid, NULL, revert_show_grid); current_sep = make_inter_variable_separator(grf_box, prf->label); prf = prefs_row_with_scale("grid density", S_grid_density, 2.0, rts_grid_density = grid_density(ss), grf_box, current_sep, grid_density_scale_callback, grid_density_text_callback); remember_pref(prf, reflect_grid_density, save_grid_density, help_grid_density, NULL, revert_grid_density); current_sep = make_inter_variable_separator(grf_box, prf->label); rts_show_axes = show_axes(ss); prf = prefs_row_with_list("what axes to display", S_show_axes, show_axes_choices[(int)rts_show_axes], show_axes_choices, NUM_SHOW_AXES, grf_box, current_sep, show_axes_from_text, NULL, NULL, show_axes_from_menu); remember_pref(prf, reflect_show_axes, save_show_axes, help_show_axes, clear_show_axes, revert_show_axes); current_sep = make_inter_variable_separator(grf_box, prf->label); rts_x_axis_style = x_axis_style(ss); prf = prefs_row_with_list("time division", S_x_axis_style, x_axis_styles[(int)rts_x_axis_style], x_axis_styles, NUM_X_AXIS_STYLES, grf_box, current_sep, x_axis_style_from_text, NULL, NULL, x_axis_style_from_menu); remember_pref(prf, reflect_x_axis_style, save_x_axis_style, help_x_axis_style, clear_x_axis_style, revert_x_axis_style); current_sep = make_inter_variable_separator(grf_box, prf->label); prf = prefs_row_with_toggle("include smpte info", "show-smpte-label", rts_with_smpte_label = with_smpte_label(ss), grf_box, current_sep, smpte_toggle); remember_pref(prf, reflect_smpte, save_smpte, help_smpte, clear_smpte, revert_smpte); /* ---------------- (graph) colors ---------------- */ current_sep = make_inter_variable_separator(grf_box, prf->label); colgrf_label = make_inner_label(" colors", grf_box, current_sep); saved_data_color = ss->data_color; prf = prefs_color_selector_row("unselected data (waveform) color", S_data_color, ss->data_color, grf_box, colgrf_label, data_color_func); remember_pref(prf, NULL, save_data_color, help_data_color, clear_data_color, revert_data_color); current_sep = make_inter_variable_separator(grf_box, prf->rscl); saved_graph_color = ss->graph_color; prf = prefs_color_selector_row("unselected graph (background) color", S_graph_color, ss->graph_color, grf_box, current_sep, graph_color_func); remember_pref(prf, NULL, save_graph_color, help_graph_color, clear_graph_color, revert_graph_color); current_sep = make_inter_variable_separator(grf_box, prf->rscl); saved_selected_data_color = ss->selected_data_color; prf = prefs_color_selector_row("selected channel data (waveform) color", S_selected_data_color, ss->selected_data_color, grf_box, current_sep, selected_data_color_func); remember_pref(prf, NULL, save_selected_data_color, help_selected_data_color, clear_selected_data_color, revert_selected_data_color); current_sep = make_inter_variable_separator(grf_box, prf->rscl); saved_selected_graph_color = ss->selected_graph_color; prf = prefs_color_selector_row("selected channel graph (background) color", S_selected_graph_color, ss->selected_graph_color, grf_box, current_sep, selected_graph_color_func); remember_pref(prf, NULL, save_selected_graph_color, help_selected_graph_color, clear_selected_graph_color, revert_selected_graph_color); current_sep = make_inter_variable_separator(grf_box, prf->rscl); saved_selection_color = ss->selection_color; prf = prefs_color_selector_row("selection color", S_selection_color, ss->selection_color, grf_box, current_sep, selection_color_func); remember_pref(prf, NULL, save_selection_color, help_selection_color, clear_selection_color, revert_selection_color); /* ---------------- (graph) fonts ---------------- */ current_sep = make_inter_variable_separator(grf_box, prf->rscl); colgrf_label = make_inner_label(" fonts", grf_box, current_sep); rts_axis_label_font = mus_strdup(axis_label_font(ss)); prf = prefs_row_with_text("axis label font", S_axis_label_font, axis_label_font(ss), grf_box, colgrf_label, axis_label_font_text); remember_pref(prf, reflect_axis_label_font, save_axis_label_font, help_axis_label_font, clear_axis_label_font, revert_axis_label_font); current_sep = make_inter_variable_separator(grf_box, prf->label); rts_axis_numbers_font = mus_strdup(axis_numbers_font(ss)); prf = prefs_row_with_text("axis number font", S_axis_numbers_font, axis_numbers_font(ss), grf_box, current_sep, axis_numbers_font_text); remember_pref(prf, reflect_axis_numbers_font, save_axis_numbers_font, help_axis_numbers_font, clear_axis_numbers_font, revert_axis_numbers_font); current_sep = make_inter_variable_separator(grf_box, prf->label); rts_peaks_font = mus_strdup(peaks_font(ss)); prf = prefs_row_with_text("fft peaks font", S_peaks_font, peaks_font(ss), grf_box, current_sep, peaks_font_text); remember_pref(prf, reflect_peaks_font, save_peaks_font, help_peaks_font, clear_peaks_font, revert_peaks_font); current_sep = make_inter_variable_separator(grf_box, prf->label); rts_bold_peaks_font = mus_strdup(bold_peaks_font(ss)); prf = prefs_row_with_text("fft peaks bold font (for main peaks)", S_bold_peaks_font, bold_peaks_font(ss), grf_box, current_sep, bold_peaks_font_text); remember_pref(prf, reflect_bold_peaks_font, save_bold_peaks_font, help_bold_peaks_font, clear_bold_peaks_font, revert_bold_peaks_font); current_sep = make_inter_variable_separator(grf_box, prf->label); rts_tiny_font = mus_strdup(tiny_font(ss)); prf = prefs_row_with_text("tiny font (for various annotations)", S_peaks_font, tiny_font(ss), grf_box, current_sep, tiny_font_text); remember_pref(prf, reflect_tiny_font, save_tiny_font, help_tiny_font, clear_tiny_font, revert_tiny_font); } current_sep = make_inter_topic_separator(topics); /* -------- transform -------- */ { Widget fft_box, fft_label; /* ---------------- transform options ---------------- */ fft_box = make_top_level_box(topics); fft_label = make_top_level_label("transform options", fft_box); rts_fft_size = transform_size(ss); str = mus_format("%lld", rts_fft_size); prf = prefs_row_with_number("size", S_transform_size, str, 12, fft_box, fft_label, fft_size_up, fft_size_down, fft_size_from_text); remember_pref(prf, reflect_fft_size, save_fft_size, help_fft_size, NULL, revert_fft_size); free(str); if (transform_size(ss) <= 2) XtSetSensitive(prf->arrow_down, false); current_sep = make_inter_variable_separator(fft_box, prf->label); prf = prefs_row_with_radio_box("transform graph choice", S_transform_graph_type, transform_graph_types, NUM_TRANSFORM_GRAPH_TYPES, rts_transform_graph_type = transform_graph_type(ss), fft_box, current_sep, transform_graph_type_choice); remember_pref(prf, reflect_transform_graph_type, save_transform_graph_type, help_transform_graph_type, NULL, revert_transform_graph_type); current_sep = make_inter_variable_separator(fft_box, prf->label); rts_transform_type = transform_type(ss); prf = prefs_row_with_list("transform", S_transform_type, transform_types[rts_transform_type], transform_types, NUM_BUILTIN_TRANSFORM_TYPES, fft_box, current_sep, transform_type_from_text, transform_type_completer, NULL, transform_type_from_menu); remember_pref(prf, reflect_transform_type, save_transform_type, help_transform_type, clear_transform_type, revert_transform_type); current_sep = make_inter_variable_separator(fft_box, prf->label); rts_fft_window = fft_window(ss); prf = prefs_row_with_list("data window", S_fft_window, mus_fft_window_name(rts_fft_window), mus_fft_window_names(), MUS_NUM_FFT_WINDOWS, fft_box, current_sep, fft_window_from_text, fft_window_completer, NULL, fft_window_from_menu); remember_pref(prf, reflect_fft_window, save_fft_window, help_fft_window, clear_fft_window, revert_fft_window); current_sep = make_inter_variable_separator(fft_box, prf->label); prf = prefs_row_with_scale("data window family parameter", S_fft_window_beta, 1.0, rts_fft_window_beta = fft_window_beta(ss), fft_box, current_sep, fft_window_beta_scale_callback, fft_window_beta_text_callback); remember_pref(prf, reflect_fft_window_beta, save_fft_window_beta, help_fft_window_beta, NULL, revert_fft_window_beta); current_sep = make_inter_variable_separator(fft_box, prf->label); str = mus_format("%d", rts_max_transform_peaks = max_transform_peaks(ss)); prf = prefs_row_with_toggle_with_text("show fft peak data", S_show_transform_peaks, rts_show_transform_peaks = show_transform_peaks(ss), "max peaks:", str, 5, fft_box, current_sep, transform_peaks_toggle, max_peaks_text); remember_pref(prf, reflect_transform_peaks, save_transform_peaks, help_transform_peaks, NULL, revert_transform_peaks); free(str); current_sep = make_inter_variable_separator(fft_box, prf->label); { const char **cmaps; int i, len; len = num_colormaps(); cmaps = (const char **)calloc(len, sizeof(const char *)); for (i = 0; i < len; i++) cmaps[i] = (const char *)colormap_name(i); rts_colormap = color_map(ss); prf = prefs_row_with_list("sonogram colormap", S_colormap, cmaps[rts_colormap], cmaps, len, fft_box, current_sep, colormap_from_text, colormap_completer, NULL, colormap_from_menu); remember_pref(prf, reflect_colormap, save_colormap, help_colormap, clear_colormap, revert_colormap); free(cmaps); } current_sep = make_inter_variable_separator(fft_box, prf->label); prf = prefs_row_with_toggle("y axis as log magnitude (dB)", S_fft_log_magnitude, rts_fft_log_magnitude = fft_log_magnitude(ss), fft_box, current_sep, log_magnitude_toggle); remember_pref(prf, reflect_fft_log_magnitude, save_fft_log_magnitude, help_fft_log_magnitude, NULL, revert_fft_log_magnitude); current_sep = make_inter_variable_separator(fft_box, prf->label); str = mus_format("%.1f", rts_min_dB = min_dB(ss)); prf = prefs_row_with_text("minimum y-axis dB value", S_min_dB, str, fft_box, current_sep, min_dB_text); remember_pref(prf, reflect_min_dB, save_min_dB, help_min_dB, NULL, revert_min_dB); free(str); current_sep = make_inter_variable_separator(fft_box, prf->label); prf = prefs_row_with_toggle("x axis as log freq", S_fft_log_frequency, rts_fft_log_frequency = fft_log_frequency(ss), fft_box, current_sep, log_frequency_toggle); remember_pref(prf, reflect_fft_log_frequency, save_fft_log_frequency, help_fft_log_frequency, NULL, revert_fft_log_frequency); current_sep = make_inter_variable_separator(fft_box, prf->label); prf = prefs_row_with_radio_box("normalization", S_transform_normalization, transform_normalizations, NUM_TRANSFORM_NORMALIZATIONS, rts_transform_normalization = transform_normalization(ss), fft_box, current_sep, transform_normalization_choice); remember_pref(prf, reflect_transform_normalization, save_transform_normalization, help_transform_normalization, NULL, revert_transform_normalization); } current_sep = make_inter_topic_separator(topics); /* -------- marks, mixes, and regions -------- */ { Widget mmr_box, mmr_label; char *str1, *str2; /* ---------------- marks and mixes ---------------- */ mmr_box = make_top_level_box(topics); mmr_label = make_top_level_label("marks and mixes", mmr_box); saved_mark_color = ss->mark_color; prf = prefs_color_selector_row("mark and mix tag color", S_mark_color, ss->mark_color, mmr_box, mmr_label, mark_color_func); remember_pref(prf, NULL, save_mark_color, help_mark_color, clear_mark_color, revert_mark_color); current_sep = make_inter_variable_separator(mmr_box, prf->rscl); str1 = mus_format("%d", rts_mark_tag_width = mark_tag_width(ss)); str2 = mus_format("%d", rts_mark_tag_height = mark_tag_height(ss)); prf = prefs_row_with_two_texts("mark tag size", S_mark_tag_width, "width:", str1, "height:", str2, 4, mmr_box, current_sep, mark_tag_size_text); remember_pref(prf, reflect_mark_tag_size, save_mark_tag_size, help_mark_tag_size, NULL, revert_mark_tag_size); free(str2); free(str1); current_sep = make_inter_variable_separator(mmr_box, prf->label); str1 = mus_format("%d", rts_mix_tag_width = mix_tag_width(ss)); str2 = mus_format("%d", rts_mix_tag_height = mix_tag_height(ss)); prf = prefs_row_with_two_texts("mix tag size", S_mix_tag_width, "width:", str1, "height:", str2, 4, mmr_box, current_sep, mix_tag_size_text); remember_pref(prf, reflect_mix_tag_size, save_mix_tag_size, help_mix_tag_size, NULL, revert_mix_tag_size); free(str2); free(str1); current_sep = make_inter_variable_separator(mmr_box, prf->label); saved_mix_color = ss->mix_color; prf = prefs_color_selector_row("mix waveform color", S_mix_color, ss->mix_color, mmr_box, current_sep, mix_color_func); remember_pref(prf, NULL, save_mix_color, help_mix_color, clear_mix_color, revert_mix_color); current_sep = make_inter_variable_separator(mmr_box, prf->rscl); str = mus_format("%d", rts_mix_waveform_height = mix_waveform_height(ss)); prf = prefs_row_with_toggle_with_text("show mix waveforms (attached to the mix tag)", S_show_mix_waveforms, rts_show_mix_waveforms = show_mix_waveforms(ss), "max waveform height:", str, 5, mmr_box, current_sep, show_mix_waveforms_toggle, mix_waveform_height_text); remember_pref(prf, reflect_mix_waveforms, save_mix_waveforms, help_mix_waveforms, NULL, revert_mix_waveforms); free(str); } current_sep = make_inter_topic_separator(topics); /* -------- clm -------- */ { Widget clm_box, clm_label; /* ---------------- clm options ---------------- */ clm_box = make_top_level_box(topics); clm_label = make_top_level_label("clm", clm_box); rts_speed_control_style = speed_control_style(ss); str = mus_format("%d", rts_speed_control_tones = speed_control_tones(ss)); prf = prefs_row_with_radio_box_and_number("speed control choice", S_speed_control_style, speed_control_styles, NUM_SPEED_CONTROL_STYLES, (int)speed_control_style(ss), str, 6, clm_box, clm_label, speed_control_choice, speed_control_up, speed_control_down, speed_control_text); XtSetSensitive(prf->arrow_down, (speed_control_tones(ss) > MIN_SPEED_CONTROL_SEMITONES)); remember_pref(prf, reflect_speed_control, save_speed_control, help_speed_control, NULL, revert_speed_control); free(str); current_sep = make_inter_variable_separator(clm_box, prf->label); str = mus_format("%d", rts_sinc_width = sinc_width(ss)); prf = prefs_row_with_text("sinc interpolation width in srate converter", S_sinc_width, str, clm_box, current_sep, sinc_width_text); remember_pref(prf, reflect_sinc_width, save_sinc_width, help_sinc_width, NULL, revert_sinc_width); free(str); } current_sep = make_inter_topic_separator(topics); /* -------- programming -------- */ { Widget prg_box, prg_label; /* ---------------- listener options ---------------- */ prg_box = make_top_level_box(topics); prg_label = make_top_level_label("listener options", prg_box); prf = prefs_row_with_toggle("show listener at start up", S_show_listener, rts_show_listener = listener_is_visible(), prg_box, prg_label, show_listener_toggle); remember_pref(prf, reflect_show_listener, save_show_listener, help_show_listener, clear_show_listener, revert_show_listener); current_sep = make_inter_variable_separator(prg_box, prf->label); rts_listener_prompt = mus_strdup(listener_prompt(ss)); prf = prefs_row_with_text("prompt", S_listener_prompt, listener_prompt(ss), prg_box, current_sep, listener_prompt_text); remember_pref(prf, reflect_listener_prompt, save_listener_prompt, help_listener_prompt, NULL, revert_listener_prompt); current_sep = make_inter_variable_separator(prg_box, prf->label); str = mus_format("%d", rts_print_length = print_length(ss)); prf = prefs_row_with_text("number of vector elements to display", S_print_length, str, prg_box, current_sep, print_length_text); remember_pref(prf, reflect_print_length, save_print_length, help_print_length, NULL, revert_print_length); free(str); current_sep = make_inter_variable_separator(prg_box, prf->label); rts_listener_font = mus_strdup(listener_font(ss)); prf = prefs_row_with_text("font", S_listener_font, listener_font(ss), prg_box, current_sep, listener_font_text); remember_pref(prf, reflect_listener_font, save_listener_font, help_listener_font, clear_listener_font, revert_listener_font); current_sep = make_inter_variable_separator(prg_box, prf->label); saved_listener_color = ss->listener_color; prf = prefs_color_selector_row("background color", S_listener_color, ss->listener_color, prg_box, current_sep, listener_color_func); remember_pref(prf, NULL, save_listener_color, help_listener_color, clear_listener_color, revert_listener_color); current_sep = make_inter_variable_separator(prg_box, prf->rscl); saved_listener_text_color = ss->listener_text_color; prf = prefs_color_selector_row("text color", S_listener_text_color, ss->listener_text_color, prg_box, current_sep, listener_text_color_func); remember_pref(prf, NULL, save_listener_text_color, help_listener_text_color, clear_listener_text_color, revert_listener_text_color); } current_sep = make_inter_topic_separator(topics); /* -------- audio -------- */ { Widget aud_box, aud_label; /* ---------------- audio options ---------------- */ aud_box = make_top_level_box(topics); aud_label = make_top_level_label("audio options", aud_box); str = mus_format("%d", rts_dac_size = dac_size(ss)); prf = prefs_row_with_text("dac buffer size", S_dac_size, str, aud_box, aud_label, dac_size_text); remember_pref(prf, reflect_dac_size, save_dac_size, help_dac_size, NULL, revert_dac_size); free(str); current_sep = make_inter_variable_separator(aud_box, prf->label); prf = prefs_row_with_toggle("fold in otherwise unplayable channels", S_dac_combines_channels, rts_dac_combines_channels = dac_combines_channels(ss), aud_box, current_sep, dac_combines_channels_toggle); remember_pref(prf, reflect_dac_combines_channels, save_dac_combines_channels, help_dac_combines_channels, NULL, revert_dac_combines_channels); } { Atom wm_delete_window; wm_delete_window = XmInternAtom(MAIN_DISPLAY(ss), (char *)"WM_DELETE_WINDOW", false); XmAddWMProtocolCallback(XtParent(preferences_dialog), wm_delete_window, wm_delete_callback, NULL); } XtManageChild(preferences_dialog); set_dialog_widget(PREFERENCES_DIALOG, preferences_dialog); return(preferences_dialog); } #include "snd-menu.h" #include /* X side of file print */ static Widget print_dialog = NULL; static Widget print_name = NULL; static Widget print_eps_or_lpr = NULL; static char print_string[PRINT_BUFFER_SIZE]; static Widget error_info_box, error_info_frame, error_info; static void print_help_callback(Widget w, XtPointer context, XtPointer info) { print_dialog_help(); } static void clear_print_error(void); static void print_cancel_callback(Widget w, XtPointer context, XtPointer info) { if (XmGetFocusWidget(print_dialog) == XmMessageBoxGetChild(print_dialog, XmDIALOG_CANCEL_BUTTON)) { ss->print_choice = PRINT_SND; clear_print_error(); XtUnmanageChild(print_dialog); } /* else it's the from the text widget probably */ } static int lpr(char *name) { /* make some desultory effort to print the file */ snprintf(print_string, PRINT_BUFFER_SIZE, "lpr %s", name); return(system(print_string)); } static void watch_print(Widget w, XtPointer context, XtPointer info) { clear_print_error(); } static Widget rc; static bool print_watching = false, print_error = false; static void clear_print_error(void) { XtUnmanageChild(rc); XtUnmanageChild(error_info_box); XtVaSetValues(print_eps_or_lpr, XmNbottomAttachment, XmATTACH_FORM, NULL); XtManageChild(rc); print_error = false; if (print_watching) { print_watching = false; XtRemoveCallback(print_name, XmNvalueChangedCallback, watch_print, NULL); XtRemoveCallback(print_eps_or_lpr, XmNvalueChangedCallback, watch_print, NULL); } } static void report_in_error_info(const char *msg, void *ignore) { XmString s1; if ((!msg) || (!(*msg))) return; print_error = true; s1 = XmStringCreateLocalized((char *)msg); XtVaSetValues(error_info, XmNlabelString, s1, NULL); if (!(XtIsManaged(error_info_box))) { Dimension text_wid = 0, dialog_wid = 0; XmFontList fonts; XtVaGetValues(error_info, XmNfontList, &fonts, NULL); XtVaGetValues(print_dialog, XmNwidth, &dialog_wid, NULL); text_wid = XmStringWidth(fonts, s1); XtUnmanageChild(rc); XtVaSetValues(print_eps_or_lpr, XmNbottomAttachment, XmATTACH_NONE, NULL); if (text_wid > dialog_wid) { XtUnmanageChild(print_dialog); XtVaSetValues(print_dialog, XmNwidth, text_wid + 40, NULL); XtManageChild(print_dialog); } XtManageChild(error_info_box); XtManageChild(rc); print_watching = true; XtAddCallback(print_name, XmNvalueChangedCallback, watch_print, NULL); XtAddCallback(print_eps_or_lpr, XmNvalueChangedCallback, watch_print, NULL); } XmStringFree(s1); } static printing_t printing = NOT_PRINTING; static void print_ok_callback(Widget w, XtPointer context, XtPointer info) { bool quit = false; XmString plab, slab; snd_info *nsp = NULL; if (printing) ss->stopped_explicitly = true; else { bool print_it; clear_print_error(); if (ss->print_choice == PRINT_SND) { plab = XmStringCreateLocalized((char *)I_STOP); nsp = any_selected_sound(); snprintf(print_string, PRINT_BUFFER_SIZE, "printing %s", nsp->short_filename); slab = XmStringCreateLocalized(print_string); XtVaSetValues(print_dialog, XmNokLabelString, plab, XmNmessageString, slab, NULL); XmStringFree(plab); XmStringFree(slab); } printing = PRINTING; print_it = (bool)XmToggleButtonGetState(print_eps_or_lpr); quit = (ss->print_choice == PRINT_ENV); if (print_it) { char *name; name = snd_tempnam(); redirect_snd_error_to(report_in_error_info, NULL); switch (ss->print_choice) { case PRINT_SND: snd_print(name); break; case PRINT_ENV: enved_print(name); break; } redirect_snd_error_to(NULL, NULL); if (!print_error) { int err; err = lpr(name); /* lpr apparently insists on printing to stderr? */ if (err != 0) report_in_error_info("can't print!", NULL); snd_remove(name, IGNORE_CACHE); } free(name); } else { char *str = NULL; redirect_snd_error_to(report_in_error_info, NULL); str = XmTextGetString(print_name); switch (ss->print_choice) { case PRINT_SND: if (snd_print(str)) status_report(nsp, "printed current view to %s", str); break; case PRINT_ENV: enved_print(str); break; } redirect_snd_error_to(NULL, NULL); if (str) XtFree(str); } } printing = NOT_PRINTING; if (ss->print_choice == PRINT_SND) { plab = XmStringCreateLocalized((char *)"Print"); snprintf(print_string, PRINT_BUFFER_SIZE, "print %s", nsp->short_filename); slab = XmStringCreateLocalized(print_string); XtVaSetValues(print_dialog, XmNokLabelString, plab, XmNmessageString, slab, NULL); XmStringFree(plab); XmStringFree(slab); } ss->print_choice = PRINT_SND; if (quit) XtUnmanageChild(print_dialog); } static void start_print_dialog(XmString xmstr4, bool managed) { if (!print_dialog) { Widget dl; XmString xmstr1, xmstr2, xmstr3, titlestr; Arg args[20]; int n; n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; xmstr1 = XmStringCreateLocalized((char *)"Print"); /* "ok" here is confusing -- might mean, ok I'm done */ xmstr2 = XmStringCreateLocalized((char *)I_HELP); xmstr3 = XmStringCreateLocalized((char *)I_GO_AWAY); titlestr = XmStringCreateLocalized((char *)"Print"); XtSetArg(args[n], XmNmessageString, xmstr4); n++; XtSetArg(args[n], XmNokLabelString, xmstr1); n++; XtSetArg(args[n], XmNhelpLabelString, xmstr2); n++; XtSetArg(args[n], XmNcancelLabelString, xmstr3); n++; XtSetArg(args[n], XmNautoUnmanage, false); n++; XtSetArg(args[n], XmNdialogTitle, titlestr); n++; XtSetArg(args[n], XmNresizePolicy, XmRESIZE_GROW); n++; XtSetArg(args[n], XmNallowResize, true); n++; XtSetArg(args[n], XmNnoResize, false); n++; XtSetArg(args[n], XmNtransient, false); n++; /* this gives us the resize handles */ print_dialog = XmCreateMessageDialog(MAIN_PANE(ss), (char *)"eps file:", args, n); XtVaSetValues(XmMessageBoxGetChild(print_dialog, XmDIALOG_MESSAGE_LABEL), XmNbackground, ss->basic_color, NULL); XmStringFree(xmstr1); XmStringFree(xmstr2); XmStringFree(xmstr3); XmStringFree(titlestr); XtUnmanageChild(XmMessageBoxGetChild(print_dialog, XmDIALOG_SYMBOL_LABEL)); XtAddCallback(print_dialog, XmNhelpCallback, print_help_callback, NULL); XtAddCallback(print_dialog, XmNcancelCallback, print_cancel_callback, NULL); XtAddCallback(print_dialog, XmNokCallback, print_ok_callback, NULL); n = 0; rc = XtCreateManagedWidget("form", xmFormWidgetClass, print_dialog, args, n); n = 0; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; dl = XtCreateManagedWidget("eps file:", xmLabelWidgetClass, rc, args, n); n = 0; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, dl); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNvalue, eps_file(ss)); n++; print_name = make_textfield_widget("text", rc, args, n, ACTIVATABLE, NO_COMPLETER); n = 0; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, print_name); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; print_eps_or_lpr = make_togglebutton_widget("direct to printer", rc, args, n); /* error display */ n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, print_eps_or_lpr); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNallowResize, true); n++; XtSetArg(args[n], XmNmargin, 0); n++; error_info_box = XtCreateWidget("error-box", xmRowColumnWidgetClass, rc, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNmarginHeight, 4); n++; error_info_frame = XtCreateManagedWidget("error-frame", xmFrameWidgetClass, error_info_box, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; error_info = XtCreateManagedWidget("error-info", xmLabelWidgetClass, error_info_frame, args, n); XtVaSetValues(print_eps_or_lpr, XmNbottomAttachment, XmATTACH_FORM, NULL); if (managed) XtManageChild(print_dialog); map_over_children(print_dialog, set_main_color_of_widget); XtVaSetValues(XmMessageBoxGetChild(print_dialog, XmDIALOG_OK_BUTTON), XmNarmColor, ss->selection_color, NULL); XtVaSetValues(XmMessageBoxGetChild(print_dialog, XmDIALOG_CANCEL_BUTTON), XmNarmColor, ss->selection_color, NULL); XtVaSetValues(XmMessageBoxGetChild(print_dialog, XmDIALOG_HELP_BUTTON), XmNarmColor, ss->selection_color, NULL); XtVaSetValues(XmMessageBoxGetChild(print_dialog, XmDIALOG_OK_BUTTON), XmNbackground, ss->highlight_color, NULL); XtVaSetValues(XmMessageBoxGetChild(print_dialog, XmDIALOG_CANCEL_BUTTON), XmNbackground, ss->highlight_color, NULL); XtVaSetValues(XmMessageBoxGetChild(print_dialog, XmDIALOG_HELP_BUTTON), XmNbackground, ss->highlight_color, NULL); XtVaSetValues(print_eps_or_lpr, XmNselectColor, ss->selection_color, NULL); set_dialog_widget(PRINT_DIALOG, print_dialog); } else { XtVaSetValues(print_dialog, XmNmessageString, xmstr4, NULL); if (managed) { if (!XtIsManaged(print_dialog)) XtManageChild(print_dialog); raise_dialog(print_dialog); /* a no-op unless already managed */ } } } widget_t make_file_print_dialog(bool managed, bool direct_to_printer) { XmString xmstr4; xmstr4 = XmStringCreateLocalized((char *)"print"); start_print_dialog(xmstr4, managed); XmStringFree(xmstr4); XmToggleButtonSetState(print_eps_or_lpr, direct_to_printer, false); return(print_dialog); } static void file_print_callback(Widget w, XtPointer context, XtPointer info) { XmString xmstr4; if (ss->print_choice == PRINT_SND) { snd_info *nsp; nsp = any_selected_sound(); if (!nsp) return; snprintf(print_string, PRINT_BUFFER_SIZE, "print %s", nsp->short_filename); xmstr4 = XmStringCreateLocalized(print_string); } else xmstr4 = XmStringCreateLocalized((char *)"print env"); start_print_dialog(xmstr4, true); XmStringFree(xmstr4); } void save_print_dialog_state(FILE *fd) { if ((print_dialog) && (XtIsManaged(print_dialog))) { #if HAVE_SCHEME fprintf(fd, "(%s #t %s)\n", S_print_dialog, ((bool)(XmToggleButtonGetState(print_eps_or_lpr))) ? "#t" : "#f"); #endif #if HAVE_RUBY fprintf(fd, "%s(true, %s)\n", to_proc_name(S_print_dialog), ((bool)(XmToggleButtonGetState(print_eps_or_lpr))) ? "true" : "false"); #endif #if HAVE_FORTH fprintf(fd, "#t %s %s drop\n", ((bool)(XmToggleButtonGetState(print_eps_or_lpr))) ? "#t" : "#f", S_print_dialog); #endif } } void set_menu_label(Widget w, const char *label) {if (w) set_button_label(w, label);} /* -------------------------------- FILE MENU -------------------------------- */ static Widget *recent_file_items = NULL; static int recent_file_items_size = 0; static void open_recent_file_callback(Widget w, XtPointer context, XtPointer info) { char *filename; snd_info *sp; filename = get_label(w); ss->open_requestor = FROM_OPEN_RECENT_MENU; ss->open_requestor_data = NULL; sp = snd_open_file(filename, FILE_READ_WRITE); if (sp) select_channel(sp, 0); } static void file_open_recent_callback(Widget w, XtPointer info, XtPointer context) { int size; size = recent_files_size(); if (size > 0) { int i; char **recent_file_names; if (size > recent_file_items_size) { if (recent_file_items_size == 0) recent_file_items = (Widget *)calloc(size, sizeof(Widget)); else { recent_file_items = (Widget *)realloc(recent_file_items, size * sizeof(Widget)); for (i = recent_file_items_size; i < size; i++) recent_file_items[i] = NULL; } recent_file_items_size = size; } recent_file_names = recent_files(); for (i = 0; i < size; i++) { if (recent_file_items[i] == NULL) { int n = 0; Arg args[6]; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; recent_file_items[i] = XtCreateManagedWidget(recent_file_names[i], xmPushButtonWidgetClass, file_open_recent_menu, args, n); XtAddCallback(recent_file_items[i], XmNactivateCallback, open_recent_file_callback, NULL); } else { set_label(recent_file_items[i], recent_file_names[i]); XtManageChild(recent_file_items[i]); } } for (i = size; i < recent_file_items_size; i++) /* maybe previous file was deleted */ if ((recent_file_items[i]) && (XtIsManaged(recent_file_items[i]))) XtUnmanageChild(recent_file_items[i]); } } static void make_open_recent_menu(void) { int n = 0; Arg args[6]; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNpositionIndex, 1); n++; /* just after "Open" menu */ file_open_recent_menu = XmCreatePulldownMenu(file_menu, (char *)"open-recent", args, n); XtSetArg(args[n], XmNsubMenuId, file_open_recent_menu); n++; file_open_recent_cascade_menu = XtCreateManagedWidget("Open recent", xmCascadeButtonWidgetClass, file_menu, args, n); XtAddCallback(file_open_recent_cascade_menu, XmNcascadingCallback, file_open_recent_callback, NULL); } static void file_menu_update_1(Widget w, XtPointer info, XtPointer context) { if (recent_files_size() > 0) { if (file_open_recent_menu == NULL) make_open_recent_menu(); else set_sensitive(file_open_recent_cascade_menu, true); } else { if (file_open_recent_menu) set_sensitive(file_open_recent_cascade_menu, false); } file_menu_update(); } static void file_open_callback(Widget w, XtPointer info, XtPointer context) {make_open_file_dialog(FILE_READ_WRITE, true);} static void file_view_callback(Widget w, XtPointer info, XtPointer context) {make_open_file_dialog(FILE_READ_ONLY, true);} static void file_new_callback(Widget w, XtPointer info, XtPointer context) {make_new_file_dialog(true);} static void file_close_callback(Widget w, XtPointer info, XtPointer context) {if (any_selected_sound()) snd_close_file(any_selected_sound());} static void file_close_all_callback(Widget w, XtPointer info, XtPointer context) {for_each_sound(snd_close_file);} static void file_save_callback(Widget w, XtPointer info, XtPointer context) {if (any_selected_sound()) save_edits_from_kbd(any_selected_sound());} static void file_update_callback(Widget w, XtPointer info, XtPointer context) {update_file_from_menu();} static void file_save_as_callback(Widget w, XtPointer info, XtPointer context) {make_sound_save_as_dialog(true);} static void file_revert_callback(Widget w, XtPointer info, XtPointer context) {revert_file_from_menu();} static void file_exit_callback(Widget w, XtPointer info, XtPointer context) {if (snd_exit_cleanly(EXIT_NOT_FORCED)) snd_exit(1);} static void file_mix_callback_1(Widget w, XtPointer info, XtPointer context) {make_mix_file_dialog(true);} static void file_insert_callback_1(Widget w, XtPointer info, XtPointer context) {make_insert_file_dialog(true);} static void file_print_callback_1(Widget w, XtPointer info, XtPointer context) {file_print_callback(w, info, context);} /* -------------------------------- EDIT MENU -------------------------------- */ static void edit_mix_callback(Widget w, XtPointer info, XtPointer context) {add_selection_or_region(0, selected_channel());} static void edit_envelope_callback(Widget w, XtPointer info, XtPointer context) {create_envelope_editor();} static void edit_cut_callback(Widget w, XtPointer info, XtPointer context) {delete_selection(UPDATE_DISPLAY);} static void edit_paste_callback(Widget w, XtPointer info, XtPointer context) {insert_selection_from_menu();} static void edit_save_as_callback(Widget w, XtPointer info, XtPointer context) {make_selection_save_as_dialog(true);} static void edit_select_all_callback(Widget w, XtPointer info, XtPointer context) {select_all(current_channel());} static void edit_unselect_callback(Widget w, XtPointer info, XtPointer context) {deactivate_selection();} static void edit_undo_callback(Widget w, XtPointer info, XtPointer context) {undo_edit_with_sync(current_channel(), 1);} static void edit_redo_callback(Widget w, XtPointer info, XtPointer context) {redo_edit_with_sync(current_channel(), 1);} static void edit_menu_update_1(Widget w, XtPointer info, XtPointer context) {edit_menu_update();} #if WITH_AUDIO static void edit_play_callback(Widget w, XtPointer info, XtPointer context) { if (ss->selection_play_stop) { stop_playing_all_sounds(PLAY_BUTTON_UNSET); reflect_play_selection_stop(); /* if there was an error, stop_playing might not remember to clear this */ } else { set_menu_label(edit_play_menu, I_STOP); ss->selection_play_stop = true; play_selection(IN_BACKGROUND); } } void reflect_play_selection_stop(void) { set_menu_label(edit_play_menu, "Play Selection"); ss->selection_play_stop = false; } #else void reflect_play_selection_stop(void) { } #endif static void edit_header_callback_1(Widget w, XtPointer info, XtPointer context) { snd_info *sp; sp = any_selected_sound(); if (sp) edit_header(sp); } #if HAVE_EXTENSION_LANGUAGE static void edit_find_callback_1(Widget w, XtPointer info, XtPointer context) { edit_find_callback(w, info, context); } #endif /* -------------------------------- VIEW MENU -------------------------------- */ static Widget *view_files_items = NULL; static Widget view_files_cascade_menu = NULL; static int view_files_items_size = 0; static void view_files_item_callback(Widget w, XtPointer context, XtPointer info) { view_files_start_dialog_with_title(get_label(w)); } static void view_files_callback(Widget w, XtPointer info, XtPointer context) { int size; size = view_files_dialog_list_length(); if (size == 0) make_view_files_dialog(true, true); /* managed and empty (brand-new) */ else { if (size == 1) make_view_files_dialog(true, false); /* raise current */ else { int i; char **view_files_names; if ((XmIsPushButton(view_files_menu)) && /* autotest check */ (!view_files_cascade_menu)) return; view_files_names = view_files_dialog_titles(); if (size > view_files_items_size) { if (view_files_items_size == 0) view_files_items = (Widget *)calloc(size, sizeof(Widget)); else { view_files_items = (Widget *)realloc(view_files_items, size * sizeof(Widget)); for (i = view_files_items_size; i < size; i++) view_files_items[i] = NULL; } view_files_items_size = size; } for (i = 0; i < size; i++) { if (view_files_items[i] == NULL) { int n = 0; Arg args[6]; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; view_files_items[i] = XtCreateManagedWidget(view_files_names[i], xmPushButtonWidgetClass, view_files_menu, args, n); XtAddCallback(view_files_items[i], XmNactivateCallback, view_files_item_callback, NULL); } else { set_label(view_files_items[i], view_files_names[i]); XtManageChild(view_files_items[i]); } free(view_files_names[i]); } free(view_files_names); } } } static void make_view_files_list_menu(void) { int n = 0, pos = 2; Arg args[6]; if ((view_files_menu) && (XmIsPushButton(view_files_menu))) { XtVaGetValues(view_files_menu, XmNpositionIndex, &pos, NULL); XtUnmanageChild(view_files_menu); } XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNpositionIndex, pos); n++; view_files_menu = XmCreatePulldownMenu(view_menu, (char *)"view-files", args, n); XtSetArg(args[n], XmNsubMenuId, view_files_menu); n++; view_files_cascade_menu = XtCreateManagedWidget("Files", xmCascadeButtonWidgetClass, view_menu, args, n); XtAddCallback(view_files_cascade_menu, XmNcascadingCallback, view_files_callback, NULL); } static void view_menu_update_1(Widget w, XtPointer info, XtPointer context) { if ((view_files_dialog_list_length() > 1) && (!view_files_cascade_menu)) make_view_files_list_menu(); view_menu_update(); } static void view_separate_callback(Widget w, XtPointer info, XtPointer context) {set_channel_style(CHANNELS_SEPARATE);} static void view_combined_callback(Widget w, XtPointer info, XtPointer context) {set_channel_style(CHANNELS_COMBINED);} static void view_superimposed_callback(Widget w, XtPointer info, XtPointer context) {set_channel_style(CHANNELS_SUPERIMPOSED);} static void view_dots_callback(Widget w, XtPointer info, XtPointer context) {set_graph_style(GRAPH_DOTS);} static void view_lines_callback(Widget w, XtPointer info, XtPointer context) {set_graph_style(GRAPH_LINES);} static void view_filled_callback(Widget w, XtPointer info, XtPointer context) {set_graph_style(GRAPH_FILLED);} static void view_dots_and_lines_callback(Widget w, XtPointer info, XtPointer context) {set_graph_style(GRAPH_DOTS_AND_LINES);} static void view_lollipops_callback(Widget w, XtPointer info, XtPointer context) {set_graph_style(GRAPH_LOLLIPOPS);} #if HAVE_EXTENSION_LANGUAGE static void view_listener_callback(Widget w, XtPointer info, XtPointer context) {handle_listener(!(listener_is_visible()));} #endif static void view_mix_dialog_callback(Widget w, XtPointer info, XtPointer context) {make_mix_dialog();} static void view_zero_callback(Widget w, XtPointer info, XtPointer context){set_show_y_zero((!(show_y_zero(ss))));} static void view_cursor_callback(Widget w, XtPointer info, XtPointer context){set_with_verbose_cursor((!(with_verbose_cursor(ss))));} #if HAVE_EXTENSION_LANGUAGE static void view_inset_callback(Widget w, XtPointer info, XtPointer context) { set_with_inset_graph((!(with_inset_graph(ss)))); for_each_chan(update_graph); } #endif static void view_controls_callback(Widget w, XtPointer info, XtPointer context) {set_show_controls(!in_show_controls(ss));} static void view_region_callback_1(Widget w, XtPointer info, XtPointer context) {view_region_callback(w, info, context);} static void view_color_orientation_callback_1(Widget w, XtPointer info, XtPointer context) {view_color_orientation_callback(w, info, context);} static void view_x_axis_seconds_callback(Widget w, XtPointer info, XtPointer context) {set_x_axis_style(X_AXIS_IN_SECONDS);} static void view_x_axis_clock_callback(Widget w, XtPointer info, XtPointer context) {set_x_axis_style(X_AXIS_AS_CLOCK);} static void view_x_axis_beats_callback(Widget w, XtPointer info, XtPointer context) {set_x_axis_style(X_AXIS_IN_BEATS);} static void view_x_axis_measures_callback(Widget w, XtPointer info, XtPointer context) {set_x_axis_style(X_AXIS_IN_MEASURES);} static void view_x_axis_samples_callback(Widget w, XtPointer info, XtPointer context) {set_x_axis_style(X_AXIS_IN_SAMPLES);} static void view_x_axis_percentage_callback(Widget w, XtPointer info, XtPointer context) {set_x_axis_style(X_AXIS_AS_PERCENTAGE);} static void view_no_axes_callback(Widget w, XtPointer info, XtPointer context) {set_show_axes(SHOW_NO_AXES);} static void view_all_axes_callback(Widget w, XtPointer info, XtPointer context) {set_show_axes(SHOW_ALL_AXES);} static void view_just_x_axis_callback(Widget w, XtPointer info, XtPointer context) {set_show_axes(SHOW_X_AXIS);} static void view_all_axes_unlabelled_callback(Widget w, XtPointer info, XtPointer context) {set_show_axes(SHOW_ALL_AXES_UNLABELLED);} static void view_just_x_axis_unlabelled_callback(Widget w, XtPointer info, XtPointer context) {set_show_axes(SHOW_X_AXIS_UNLABELLED);} static void view_bare_x_axis_callback(Widget w, XtPointer info, XtPointer context) {set_show_axes(SHOW_BARE_X_AXIS);} static void view_focus_right_callback(Widget w, XtPointer info, XtPointer context) {set_zoom_focus_style(ZOOM_FOCUS_RIGHT);} static void view_focus_left_callback(Widget w, XtPointer info, XtPointer context) {set_zoom_focus_style(ZOOM_FOCUS_LEFT);} static void view_focus_middle_callback(Widget w, XtPointer info, XtPointer context) {set_zoom_focus_style(ZOOM_FOCUS_MIDDLE);} static void view_focus_active_callback(Widget w, XtPointer info, XtPointer context) {set_zoom_focus_style(ZOOM_FOCUS_ACTIVE);} static void view_grid_callback(Widget w, XtPointer info, XtPointer context) { if (show_grid(ss) == NO_GRID) set_show_grid(WITH_GRID); else set_show_grid(NO_GRID); } /* -------------------------------- OPTIONS MENU -------------------------------- */ static void options_transform_callback(Widget w, XtPointer info, XtPointer context) {make_transform_dialog(true);} static void options_controls_callback(Widget w, XtPointer info, XtPointer context) {make_controls_dialog();} #if HAVE_EXTENSION_LANGUAGE static void options_save_state_callback(Widget w, XtPointer info, XtPointer context) {save_state_from_menu();} #endif static void options_preferences_callback(Widget w, XtPointer info, XtPointer context) {make_preferences_dialog();} /* -------------------------------- HELP MENU -------------------------------- */ static void help_about_snd_callback(Widget w, XtPointer info, XtPointer context) {about_snd_help();} static void help_fft_callback(Widget w, XtPointer info, XtPointer context) {fft_help();} #if HAVE_EXTENSION_LANGUAGE static void help_find_callback(Widget w, XtPointer info, XtPointer context) {find_help();} static void help_init_file_callback(Widget w, XtPointer info, XtPointer context) {init_file_help();} #endif static void help_undo_callback(Widget w, XtPointer info, XtPointer context) {undo_help();} static void help_sync_callback(Widget w, XtPointer info, XtPointer context) {sync_help();} static void help_debug_callback(Widget w, XtPointer info, XtPointer context) {debug_help();} static void help_controls_callback(Widget w, XtPointer info, XtPointer context) {controls_help();} static void help_env_callback(Widget w, XtPointer info, XtPointer context) {env_help();} static void help_marks_callback(Widget w, XtPointer info, XtPointer context) {marks_help();} static void help_mix_callback(Widget w, XtPointer info, XtPointer context) {mix_help();} static void help_sound_files_callback(Widget w, XtPointer info, XtPointer context) {sound_files_help();} static void help_keys_callback(Widget w, XtPointer info, XtPointer context) {key_help();} static void help_play_callback(Widget w, XtPointer info, XtPointer context) {play_help();} static void help_filter_callback(Widget w, XtPointer info, XtPointer context) {filter_help();} static void help_save_callback(Widget w, XtPointer info, XtPointer context) {save_help();} static void help_reverb_callback(Widget w, XtPointer info, XtPointer context) {reverb_help();} static void help_resample_callback(Widget w, XtPointer info, XtPointer context) {resample_help();} static void help_insert_callback(Widget w, XtPointer info, XtPointer context) {insert_help();} static void help_delete_callback(Widget w, XtPointer info, XtPointer context) {delete_help();} static void help_region_callback(Widget w, XtPointer info, XtPointer context) {region_help();} static void help_selection_callback(Widget w, XtPointer info, XtPointer context) {selection_help();} static void help_colors_callback(Widget w, XtPointer info, XtPointer context) {colors_help();} void check_menu_labels(int key, int state, bool extended) { /* user has redefined key, so erase old key binding info from the menu label */ if (extended) { if (state == snd_ControlMask) { if (key == snd_K_f) set_label(file_open_menu, "Open"); else if (key == snd_K_s) set_label(file_save_menu, "Save"); else if (key == snd_K_q) set_label(file_mix_menu, "Mix"); else if (key == snd_K_i) set_label(file_insert_menu, "Insert"); else if (key == snd_K_u) set_label(edit_undo_menu, "Undo"); else if (key == snd_K_r) set_label(edit_redo_menu, "Redo"); } else { if (key == snd_K_k) set_label(file_close_menu, "Close"); else if (key == snd_K_i) set_label(edit_paste_menu, "Insert Selection"); else if (key == snd_K_q) set_label(edit_mix_menu, "Mix Selection"); else #if WITH_AUDIO if (key == snd_K_p) set_label(edit_play_menu, "Play Selection"); else #endif if (key == snd_K_w) set_label(edit_save_as_menu, "Save Selection"); } } #if HAVE_EXTENSION_LANGUAGE else { if ((key == snd_K_s) && (state == snd_ControlMask)) set_label(edit_find_menu, I_FIND); } #endif } /* -------------------------------- MAIN MENU -------------------------------- */ static void menu_drag_watcher(Widget w, const char *str, Position x, Position y, drag_style_t dtype, void *data) { char *new_title; switch (dtype) { case DRAG_ENTER: new_title = mus_format("%s: drop to open file", ss->startup_title); XtVaSetValues(MAIN_SHELL(ss), XmNtitle, (char *)new_title, NULL); XmChangeColor(w, ss->selection_color); free(new_title); break; case DRAG_LEAVE: reflect_file_change_in_title(); XmChangeColor(w, ss->highlight_color); break; default: break; } } static void menu_drop_watcher(Widget w, const char *str, Position x, Position y, void *data) { snd_info *sp = NULL; ss->open_requestor = FROM_DRAG_AND_DROP; sp = snd_open_file(str, FILE_READ_WRITE); if (sp) select_channel(sp, 0); } void add_menu_drop(void) { add_drag_and_drop(main_menu, menu_drop_watcher, menu_drag_watcher, NULL); } Widget add_menu(void) { static Arg main_args[12]; static Arg in_args[12]; static Arg high_args[12]; Arg sep_args[12]; int in_n = 0, n, high_n = 0, main_n = 0, start_high_n, k, j; ss->mw = (Widget *)calloc(NUM_MENU_WIDGETS, sizeof(Widget)); XtSetArg(main_args[main_n], XmNbackground, ss->basic_color); main_n++; XtSetArg(high_args[high_n], XmNbackground, ss->highlight_color); high_n++; XtSetArg(in_args[in_n], XmNbackground, ss->basic_color); in_n++; start_high_n = high_n; XtSetArg(in_args[in_n], XmNsensitive, false); in_n++; n = high_n; XtSetArg(high_args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(high_args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(high_args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(high_args[n], XmNrightAttachment, XmATTACH_FORM); n++; main_menu = XmCreateMenuBar(MAIN_PANE(ss), (char *)"menuBar", high_args, n); /* FILE MENU */ XtSetArg(main_args[main_n], XmNuserData, (XtPointer)0); file_menu = XmCreatePulldownMenu(main_menu, (char *)"File", main_args, main_n + 1); high_n = start_high_n; XtSetArg(high_args[high_n], XmNsubMenuId, file_menu); high_n++; XtSetArg(high_args[high_n], XmNmnemonic, 'F'); high_n++; XtSetArg(high_args[high_n], XmNuserData, (XtPointer)0); high_n++; file_cascade_menu = XtCreateManagedWidget("File", xmCascadeButtonWidgetClass, main_menu, high_args, high_n); file_open_menu = XtCreateManagedWidget("Open", xmPushButtonWidgetClass, file_menu, main_args, main_n); XtAddCallback(file_open_menu, XmNactivateCallback, file_open_callback, NULL); XtVaSetValues(file_open_menu, XmNmnemonic, 'O', NULL); file_close_menu = XtCreateManagedWidget("Close", xmPushButtonWidgetClass, file_menu, in_args, in_n); XtAddCallback(file_close_menu, XmNactivateCallback, file_close_callback, NULL); XtVaSetValues(file_close_menu, XmNmnemonic, 'C', NULL); file_close_all_menu = XtCreateWidget("Close all", xmPushButtonWidgetClass, file_menu, main_args, main_n); XtAddCallback(file_close_all_menu, XmNactivateCallback, file_close_all_callback, NULL); file_save_menu = XtCreateManagedWidget("Save", xmPushButtonWidgetClass, file_menu, in_args, in_n); XtAddCallback(file_save_menu, XmNactivateCallback, file_save_callback, NULL); XtVaSetValues(file_save_menu, XmNmnemonic, 'S', NULL); file_save_as_menu = XtCreateManagedWidget("Save as", xmPushButtonWidgetClass, file_menu, in_args, in_n); XtAddCallback(file_save_as_menu, XmNactivateCallback, file_save_as_callback, NULL); XtVaSetValues(file_save_as_menu, XmNmnemonic, 'a', NULL); file_revert_menu = XtCreateManagedWidget("Revert", xmPushButtonWidgetClass, file_menu, in_args, in_n); XtAddCallback(file_revert_menu, XmNactivateCallback, file_revert_callback, NULL); XtVaSetValues(file_revert_menu, XmNmnemonic, 'R', NULL); file_mix_menu = XtCreateManagedWidget("Mix", xmPushButtonWidgetClass, file_menu, in_args, in_n); XtAddCallback(file_mix_menu, XmNactivateCallback, file_mix_callback_1, NULL); XtVaSetValues(file_mix_menu, XmNmnemonic, 'M', NULL); file_insert_menu = XtCreateManagedWidget("Insert", xmPushButtonWidgetClass, file_menu, in_args, in_n); XtAddCallback(file_insert_menu, XmNactivateCallback, file_insert_callback_1, NULL); XtVaSetValues(file_insert_menu, XmNmnemonic, 'I', NULL); file_update_menu = XtCreateManagedWidget("Update", xmPushButtonWidgetClass, file_menu, in_args, in_n); XtAddCallback(file_update_menu, XmNactivateCallback, file_update_callback, NULL); XtVaSetValues(file_update_menu, XmNmnemonic, 'U', NULL); file_new_menu = XtCreateManagedWidget("New", xmPushButtonWidgetClass, file_menu, main_args, main_n); XtAddCallback(file_new_menu, XmNactivateCallback, file_new_callback, NULL); XtVaSetValues(file_new_menu, XmNmnemonic, 'N', NULL); file_view_menu = XtCreateManagedWidget("View", xmPushButtonWidgetClass, file_menu, main_args, main_n); XtAddCallback(file_view_menu, XmNactivateCallback, file_view_callback, NULL); XtVaSetValues(file_view_menu, XmNmnemonic, 'V', NULL); file_print_menu = XtCreateManagedWidget("Print", xmPushButtonWidgetClass, file_menu, in_args, in_n); XtAddCallback(file_print_menu, XmNactivateCallback, file_print_callback_1, NULL); XtVaSetValues(file_print_menu, XmNmnemonic, 'P', NULL); j = 0; XtSetArg(sep_args[j], XmNbackground, ss->basic_color); j++; XtSetArg(sep_args[j], XmNseparatorType, XmSHADOW_ETCHED_IN); j++; file_sep_menu = XtCreateManagedWidget("", xmSeparatorWidgetClass, file_menu, sep_args, j); file_exit_menu = XtCreateManagedWidget("Exit", xmPushButtonWidgetClass, file_menu, main_args, main_n); XtAddCallback(file_exit_menu, XmNactivateCallback, file_exit_callback, NULL); XtVaSetValues(file_exit_menu, XmNmnemonic, 'E', NULL); /* EDIT MENU */ XtSetArg(main_args[main_n], XmNuserData, (XtPointer)1); edit_menu = XmCreatePulldownMenu(main_menu, (char *)"Edit", main_args, main_n + 1); high_n = start_high_n; XtSetArg(high_args[high_n], XmNsubMenuId, edit_menu); high_n++; XtSetArg(high_args[high_n], XmNmnemonic, 'E'); high_n++; XtSetArg(high_args[high_n], XmNuserData, (XtPointer)1); high_n++; edit_cascade_menu = XtCreateManagedWidget("Edit", xmCascadeButtonWidgetClass, main_menu, high_args, high_n); edit_undo_menu = XtCreateManagedWidget("Undo", xmPushButtonWidgetClass, edit_menu, in_args, in_n); XtAddCallback(edit_undo_menu, XmNactivateCallback, edit_undo_callback, NULL); XtVaSetValues(edit_undo_menu, XmNmnemonic, 'U', NULL); edit_redo_menu = XtCreateManagedWidget("Redo", xmPushButtonWidgetClass, edit_menu, in_args, in_n); XtAddCallback(edit_redo_menu, XmNactivateCallback, edit_redo_callback, NULL); XtVaSetValues(edit_redo_menu, XmNmnemonic, 'R', NULL); #if HAVE_EXTENSION_LANGUAGE edit_find_menu = XtCreateManagedWidget(I_FIND, xmPushButtonWidgetClass, edit_menu, in_args, in_n); XtAddCallback(edit_find_menu, XmNactivateCallback, edit_find_callback_1, NULL); XtVaSetValues(edit_find_menu, XmNmnemonic, 'F', NULL); #endif edit_select_sep_menu = XtCreateManagedWidget("", xmSeparatorWidgetClass, edit_menu, sep_args, j); edit_cut_menu = XtCreateManagedWidget("Delete selection", xmPushButtonWidgetClass, edit_menu, in_args, in_n); XtAddCallback(edit_cut_menu, XmNactivateCallback, edit_cut_callback, NULL); XtVaSetValues(edit_cut_menu, XmNmnemonic, 'C', NULL); edit_paste_menu = XtCreateManagedWidget("Insert selection", xmPushButtonWidgetClass, edit_menu, in_args, in_n); XtAddCallback(edit_paste_menu, XmNactivateCallback, edit_paste_callback, NULL); XtVaSetValues(edit_paste_menu, XmNmnemonic, 'P', NULL); edit_mix_menu = XtCreateManagedWidget("Mix selection", xmPushButtonWidgetClass, edit_menu, in_args, in_n); XtAddCallback(edit_mix_menu, XmNactivateCallback, edit_mix_callback, NULL); XtVaSetValues(edit_mix_menu, XmNmnemonic, 'M', NULL); #if WITH_AUDIO edit_play_menu = XtCreateManagedWidget("Play selection", xmPushButtonWidgetClass, edit_menu, in_args, in_n); XtAddCallback(edit_play_menu, XmNactivateCallback, edit_play_callback, NULL); XtVaSetValues(edit_play_menu, XmNmnemonic, 'P', NULL); #endif edit_save_as_menu = XtCreateManagedWidget("Save selection", xmPushButtonWidgetClass, edit_menu, in_args, in_n); XtAddCallback(edit_save_as_menu, XmNactivateCallback, edit_save_as_callback, NULL); XtVaSetValues(edit_save_as_menu, XmNmnemonic, 'S', NULL); edit_select_all_menu = XtCreateManagedWidget("Select all", xmPushButtonWidgetClass, edit_menu, in_args, in_n); XtAddCallback(edit_select_all_menu, XmNactivateCallback, edit_select_all_callback, NULL); edit_unselect_menu = XtCreateManagedWidget("Unselect all", xmPushButtonWidgetClass, edit_menu, in_args, in_n); XtAddCallback(edit_unselect_menu, XmNactivateCallback, edit_unselect_callback, NULL); edit_edit_sep_menu = XtCreateManagedWidget("", xmSeparatorWidgetClass, edit_menu, sep_args, j); edit_env_menu = XtCreateManagedWidget("Edit envelope", xmPushButtonWidgetClass, edit_menu, main_args, main_n); XtAddCallback(edit_env_menu, XmNactivateCallback, edit_envelope_callback, NULL); XtVaSetValues(edit_env_menu, XmNmnemonic, 'E', NULL); edit_header_menu = XtCreateManagedWidget("Edit header", xmPushButtonWidgetClass, edit_menu, in_args, in_n); XtAddCallback(edit_header_menu, XmNactivateCallback, edit_header_callback_1, NULL); XtVaSetValues(edit_header_menu, XmNmnemonic, 'H', NULL); /* VIEW MENU */ XtSetArg(main_args[main_n], XmNuserData, (XtPointer)2); view_menu = XmCreatePulldownMenu(main_menu, (char *)"View", main_args, main_n + 1); high_n = start_high_n; XtSetArg(high_args[high_n], XmNsubMenuId, view_menu); high_n++; XtSetArg(high_args[high_n], XmNmnemonic, 'V'); high_n++; XtSetArg(high_args[high_n], XmNuserData, (XtPointer)2); high_n++; view_cascade_menu = XtCreateManagedWidget("View", xmCascadeButtonWidgetClass, main_menu, high_args, high_n); #if HAVE_EXTENSION_LANGUAGE view_listener_menu = XtCreateManagedWidget("Open listener", xmPushButtonWidgetClass, view_menu, main_args, main_n); XtAddCallback(view_listener_menu, XmNactivateCallback, view_listener_callback, NULL); XtVaSetValues(view_listener_menu, XmNmnemonic, 'L', NULL); #endif view_files_menu = XtCreateManagedWidget("Files", xmPushButtonWidgetClass, view_menu, main_args, main_n); XtAddCallback(view_files_menu, XmNactivateCallback, view_files_callback, NULL); XtVaSetValues(view_files_menu, XmNmnemonic, 'F', NULL); view_mix_dialog_menu = XtCreateManagedWidget("Mixes", xmPushButtonWidgetClass, view_menu, main_args, main_n); XtAddCallback(view_mix_dialog_menu, XmNactivateCallback, view_mix_dialog_callback, NULL); view_region_menu = XtCreateManagedWidget("Regions", xmPushButtonWidgetClass, view_menu, in_args, in_n); XtAddCallback(view_region_menu, XmNactivateCallback, view_region_callback_1, NULL); XtVaSetValues(view_region_menu, XmNmnemonic, 'R', NULL); view_color_orientation_menu = XtCreateManagedWidget("Color/Orientation", xmPushButtonWidgetClass, view_menu, main_args, main_n); XtAddCallback(view_color_orientation_menu, XmNactivateCallback, view_color_orientation_callback_1, NULL); view_controls_menu = XtCreateManagedWidget("Show controls", xmPushButtonWidgetClass, view_menu, main_args, main_n); XtAddCallback(view_controls_menu, XmNactivateCallback, view_controls_callback, NULL); XtVaSetValues(view_controls_menu, XmNmnemonic, 'S', NULL); view_sep2_menu = XtCreateManagedWidget("", xmSeparatorWidgetClass, view_menu, sep_args, j); view_graph_style_menu = XmCreatePulldownMenu(view_menu, (char *)"graph-style", main_args, main_n); k = main_n; XtSetArg(main_args[k], XmNsubMenuId, view_graph_style_menu); k++; view_graph_style_cascade_menu = XtCreateManagedWidget(I_LINES_OR_DOTS, xmCascadeButtonWidgetClass, view_menu, main_args, k); view_lines_menu = XtCreateManagedWidget("lines", xmPushButtonWidgetClass, view_graph_style_menu, main_args, main_n); XtAddCallback(view_lines_menu, XmNactivateCallback, view_lines_callback, NULL); if (graph_style(ss) == GRAPH_LINES) set_sensitive(view_lines_menu, false); view_dots_menu = XtCreateManagedWidget("dots", xmPushButtonWidgetClass, view_graph_style_menu, main_args, main_n); XtAddCallback(view_dots_menu, XmNactivateCallback, view_dots_callback, NULL); if (graph_style(ss) == GRAPH_DOTS) set_sensitive(view_dots_menu, false); view_filled_menu = XtCreateManagedWidget("filled", xmPushButtonWidgetClass, view_graph_style_menu, main_args, main_n); XtAddCallback(view_filled_menu, XmNactivateCallback, view_filled_callback, NULL); if (graph_style(ss) == GRAPH_FILLED) set_sensitive(view_filled_menu, false); view_dots_and_lines_menu = XtCreateManagedWidget("dots and lines", xmPushButtonWidgetClass, view_graph_style_menu, main_args, main_n); XtAddCallback(view_dots_and_lines_menu, XmNactivateCallback, view_dots_and_lines_callback, NULL); if (graph_style(ss) == GRAPH_DOTS_AND_LINES) set_sensitive(view_dots_and_lines_menu, false); view_lollipops_menu = XtCreateManagedWidget("lollipops", xmPushButtonWidgetClass, view_graph_style_menu, main_args, main_n); XtAddCallback(view_lollipops_menu, XmNactivateCallback, view_lollipops_callback, NULL); if (graph_style(ss) == GRAPH_LOLLIPOPS) set_sensitive(view_lollipops_menu, false); view_cursor_menu = XtCreateManagedWidget("Verbose cursor", xmPushButtonWidgetClass, view_menu, main_args, main_n); XtAddCallback(view_cursor_menu, XmNactivateCallback, view_cursor_callback, NULL); #if HAVE_EXTENSION_LANGUAGE view_inset_menu = XtCreateManagedWidget("With inset graph", xmPushButtonWidgetClass, view_menu, main_args, main_n); XtAddCallback(view_inset_menu, XmNactivateCallback, view_inset_callback, NULL); #endif view_combine_menu = XmCreatePulldownMenu(view_menu, (char *)"combine", main_args, main_n); k = main_n; XtSetArg(main_args[k], XmNsubMenuId, view_combine_menu); k++; view_combine_cascade_menu = XtCreateManagedWidget(I_CHANNEL_LAYOUT, xmCascadeButtonWidgetClass, view_menu, main_args, k); view_combine_separate_menu = XtCreateManagedWidget("separate", xmPushButtonWidgetClass, view_combine_menu, main_args, main_n); XtAddCallback(view_combine_separate_menu, XmNactivateCallback, view_separate_callback, NULL); if (channel_style(ss) == CHANNELS_SEPARATE) set_sensitive(view_combine_separate_menu, false); view_combine_combined_menu = XtCreateManagedWidget("combined", xmPushButtonWidgetClass, view_combine_menu, main_args, main_n); XtAddCallback(view_combine_combined_menu, XmNactivateCallback, view_combined_callback, NULL); if (channel_style(ss) == CHANNELS_COMBINED) set_sensitive(view_combine_combined_menu, false); view_combine_superimposed_menu = XtCreateManagedWidget("superimposed", xmPushButtonWidgetClass, view_combine_menu, main_args, main_n); XtAddCallback(view_combine_superimposed_menu, XmNactivateCallback, view_superimposed_callback, NULL); if (channel_style(ss) == CHANNELS_SUPERIMPOSED) set_sensitive(view_combine_superimposed_menu, false); view_zero_menu = XtCreateManagedWidget("Show y = 0", xmPushButtonWidgetClass, view_menu, main_args, main_n); XtAddCallback(view_zero_menu, XmNactivateCallback, view_zero_callback, NULL); XtVaSetValues(view_zero_menu, XmNmnemonic, 'y', NULL); view_x_axis_menu = XmCreatePulldownMenu(view_menu, (char *)"xaxis", main_args, main_n); k = main_n; XtSetArg(main_args[k], XmNsubMenuId, view_x_axis_menu); k++; view_x_axis_cascade_menu = XtCreateManagedWidget("X axis units", xmCascadeButtonWidgetClass, view_menu, main_args, k); view_x_axis_seconds_menu = XtCreateManagedWidget("seconds", xmPushButtonWidgetClass, view_x_axis_menu, main_args, main_n); XtAddCallback(view_x_axis_seconds_menu, XmNactivateCallback, view_x_axis_seconds_callback, NULL); set_sensitive(view_x_axis_seconds_menu, false); view_x_axis_samples_menu = XtCreateManagedWidget("samples", xmPushButtonWidgetClass, view_x_axis_menu, main_args, main_n); XtAddCallback(view_x_axis_samples_menu, XmNactivateCallback, view_x_axis_samples_callback, NULL); view_x_axis_clock_menu = XtCreateManagedWidget("clock", xmPushButtonWidgetClass, view_x_axis_menu, main_args, main_n); XtAddCallback(view_x_axis_clock_menu, XmNactivateCallback, view_x_axis_clock_callback, NULL); view_x_axis_percentage_menu = XtCreateManagedWidget("percentage", xmPushButtonWidgetClass, view_x_axis_menu, main_args, main_n); XtAddCallback(view_x_axis_percentage_menu, XmNactivateCallback, view_x_axis_percentage_callback, NULL); view_x_axis_beats_menu = XtCreateManagedWidget("beats", xmPushButtonWidgetClass, view_x_axis_menu, main_args, main_n); XtAddCallback(view_x_axis_beats_menu, XmNactivateCallback, view_x_axis_beats_callback, NULL); view_x_axis_measures_menu = XtCreateManagedWidget("measures", xmPushButtonWidgetClass, view_x_axis_menu, main_args, main_n); XtAddCallback(view_x_axis_measures_menu, XmNactivateCallback, view_x_axis_measures_callback, NULL); view_axes_menu = XmCreatePulldownMenu(view_menu, (char *)"axes", main_args, main_n); k = main_n; XtSetArg(main_args[k], XmNsubMenuId, view_axes_menu); k++; view_axes_cascade_menu = XtCreateManagedWidget(I_AXIS_LAYOUT, xmCascadeButtonWidgetClass, view_menu, main_args, k); view_no_axes_menu = XtCreateManagedWidget("no axes", xmPushButtonWidgetClass, view_axes_menu, main_args, main_n); XtAddCallback(view_no_axes_menu, XmNactivateCallback, view_no_axes_callback, NULL); if (show_axes(ss) == SHOW_NO_AXES) set_sensitive(view_no_axes_menu, false); /* false because it is already chosen */ view_all_axes_menu = XtCreateManagedWidget("both axes", xmPushButtonWidgetClass, view_axes_menu, main_args, main_n); XtAddCallback(view_all_axes_menu, XmNactivateCallback, view_all_axes_callback, NULL); if (show_axes(ss) == SHOW_ALL_AXES) set_sensitive(view_all_axes_menu, false); view_just_x_axis_menu = XtCreateManagedWidget("just x axis", xmPushButtonWidgetClass, view_axes_menu, main_args, main_n); XtAddCallback(view_just_x_axis_menu, XmNactivateCallback, view_just_x_axis_callback, NULL); if (show_axes(ss) == SHOW_X_AXIS) set_sensitive(view_just_x_axis_menu, false); view_all_axes_unlabelled_menu = XtCreateManagedWidget("both axes, no labels", xmPushButtonWidgetClass, view_axes_menu, main_args, main_n); XtAddCallback(view_all_axes_unlabelled_menu, XmNactivateCallback, view_all_axes_unlabelled_callback, NULL); if (show_axes(ss) == SHOW_ALL_AXES_UNLABELLED) set_sensitive(view_all_axes_unlabelled_menu, false); view_just_x_axis_unlabelled_menu = XtCreateManagedWidget("just x axis, no label", xmPushButtonWidgetClass, view_axes_menu, main_args, main_n); XtAddCallback(view_just_x_axis_unlabelled_menu, XmNactivateCallback, view_just_x_axis_unlabelled_callback, NULL); if (show_axes(ss) == SHOW_X_AXIS_UNLABELLED) set_sensitive(view_just_x_axis_unlabelled_menu, false); view_bare_x_axis_menu = XtCreateManagedWidget("bare x axis", xmPushButtonWidgetClass, view_axes_menu, main_args, main_n); XtAddCallback(view_bare_x_axis_menu, XmNactivateCallback, view_bare_x_axis_callback, NULL); if (show_axes(ss) == SHOW_BARE_X_AXIS) set_sensitive(view_bare_x_axis_menu, false); view_focus_style_menu = XmCreatePulldownMenu(view_menu, (char *)"focusstyle", main_args, main_n); k = main_n; XtSetArg(main_args[k], XmNsubMenuId, view_focus_style_menu); k++; view_focus_cascade_menu = XtCreateManagedWidget(I_ZOOM_CENTERS_ON, xmCascadeButtonWidgetClass, view_menu, main_args, k); view_focus_left_menu = XtCreateManagedWidget("window left edge", xmPushButtonWidgetClass, view_focus_style_menu, main_args, main_n); XtAddCallback(view_focus_left_menu, XmNactivateCallback, view_focus_left_callback, NULL); view_focus_right_menu = XtCreateManagedWidget("window right edge", xmPushButtonWidgetClass, view_focus_style_menu, main_args, main_n); XtAddCallback(view_focus_right_menu, XmNactivateCallback, view_focus_right_callback, NULL); view_focus_middle_menu = XtCreateManagedWidget("window midpoint", xmPushButtonWidgetClass, view_focus_style_menu, main_args, main_n); XtAddCallback(view_focus_middle_menu, XmNactivateCallback, view_focus_middle_callback, NULL); view_focus_active_menu = XtCreateManagedWidget("cursor or selection", xmPushButtonWidgetClass, view_focus_style_menu, main_args, main_n); XtAddCallback(view_focus_active_menu, XmNactivateCallback, view_focus_active_callback, NULL); view_grid_menu = XtCreateManagedWidget("With grid", xmPushButtonWidgetClass, view_menu, main_args, main_n); XtAddCallback(view_grid_menu, XmNactivateCallback, view_grid_callback, NULL); /* OPTIONS MENU */ XtSetArg(main_args[main_n], XmNuserData, (XtPointer)3); options_menu = XmCreatePulldownMenu(main_menu, (char *)"Option", main_args, main_n + 1); high_n = start_high_n; XtSetArg(high_args[high_n], XmNsubMenuId, options_menu); high_n++; XtSetArg(high_args[high_n], XmNmnemonic, 'O'); high_n++; XtSetArg(high_args[high_n], XmNuserData, (XtPointer)3); high_n++; options_cascade_menu = XtCreateManagedWidget("Options", xmCascadeButtonWidgetClass, main_menu, high_args, high_n); options_transform_menu = XtCreateManagedWidget("Transform options", xmPushButtonWidgetClass, options_menu, main_args, main_n); XtAddCallback(options_transform_menu, XmNactivateCallback, options_transform_callback, NULL); XtVaSetValues(options_transform_menu, XmNmnemonic, 't', NULL); options_controls_menu = XtCreateManagedWidget("Control panel options", xmPushButtonWidgetClass, options_menu, main_args, main_n); XtAddCallback(options_controls_menu, XmNactivateCallback, options_controls_callback, NULL); XtVaSetValues(options_controls_menu, XmNmnemonic, 'c', NULL); #if HAVE_EXTENSION_LANGUAGE options_save_state_menu = XtCreateManagedWidget("Save session", xmPushButtonWidgetClass, options_menu, main_args, main_n); XtAddCallback(options_save_state_menu, XmNactivateCallback, options_save_state_callback, NULL); #endif options_sep_menu = XtCreateManagedWidget("", xmSeparatorWidgetClass, options_menu, sep_args, j); options_preferences_menu = XtCreateManagedWidget("Preferences", xmPushButtonWidgetClass, options_menu, main_args, main_n); XtAddCallback(options_preferences_menu, XmNactivateCallback, options_preferences_callback, NULL); /* HELP MENU */ XtSetArg(main_args[main_n], XmNuserData, (XtPointer)4); help_menu = XmCreatePulldownMenu(main_menu, (char *)I_HELP, main_args, main_n + 1); high_n = start_high_n; XtSetArg(high_args[high_n], XmNsubMenuId, help_menu); high_n++; XtSetArg(high_args[high_n], XmNmnemonic, 'H'); high_n++; XtSetArg(high_args[high_n], XmNuserData, (XtPointer)4); high_n++; help_cascade_menu = XtCreateManagedWidget(I_HELP, xmCascadeButtonWidgetClass, main_menu, high_args, high_n); help_about_snd_menu = XtCreateManagedWidget("About Snd", xmPushButtonWidgetClass, help_menu, main_args, main_n); XtAddCallback(help_about_snd_menu, XmNactivateCallback, help_about_snd_callback, NULL); XtVaSetValues(help_about_snd_menu, XmNmnemonic, 'O', NULL); #if HAVE_EXTENSION_LANGUAGE help_init_file_menu = XtCreateManagedWidget("Customization", xmPushButtonWidgetClass, help_menu, main_args, main_n); XtAddCallback(help_init_file_menu, XmNactivateCallback, help_init_file_callback, NULL); #endif help_controls_menu = XtCreateManagedWidget("Control panel", xmPushButtonWidgetClass, help_menu, main_args, main_n); XtAddCallback(help_controls_menu, XmNactivateCallback, help_controls_callback, NULL); help_keys_menu = XtCreateManagedWidget("Key bindings", xmPushButtonWidgetClass, help_menu, main_args, main_n); XtAddCallback(help_keys_menu, XmNactivateCallback, help_keys_callback, NULL); help_play_menu = XtCreateManagedWidget("Play", xmPushButtonWidgetClass, help_menu, main_args, main_n); XtAddCallback(help_play_menu, XmNactivateCallback, help_play_callback, NULL); help_save_menu = XtCreateManagedWidget("Save", xmPushButtonWidgetClass, help_menu, main_args, main_n); XtAddCallback(help_save_menu, XmNactivateCallback, help_save_callback, NULL); help_mix_menu = XtCreateManagedWidget("Mix", xmPushButtonWidgetClass, help_menu, main_args, main_n); XtAddCallback(help_mix_menu, XmNactivateCallback, help_mix_callback, NULL); help_resample_menu = XtCreateManagedWidget("Resample", xmPushButtonWidgetClass, help_menu, main_args, main_n); XtAddCallback(help_resample_menu, XmNactivateCallback, help_resample_callback, NULL); help_fft_menu = XtCreateManagedWidget("FFT", xmPushButtonWidgetClass, help_menu, main_args, main_n); XtAddCallback(help_fft_menu, XmNactivateCallback, help_fft_callback, NULL); help_filter_menu = XtCreateManagedWidget("Filter", xmPushButtonWidgetClass, help_menu, main_args, main_n); XtAddCallback(help_filter_menu, XmNactivateCallback, help_filter_callback, NULL); help_reverb_menu = XtCreateManagedWidget("Reverb", xmPushButtonWidgetClass, help_menu, main_args, main_n); XtAddCallback(help_reverb_menu, XmNactivateCallback, help_reverb_callback, NULL); help_env_menu = XtCreateManagedWidget("Envelope", xmPushButtonWidgetClass, help_menu, main_args, main_n); XtAddCallback(help_env_menu, XmNactivateCallback, help_env_callback, NULL); help_marks_menu = XtCreateManagedWidget("Mark", xmPushButtonWidgetClass, help_menu, main_args, main_n); XtAddCallback(help_marks_menu, XmNactivateCallback, help_marks_callback, NULL); help_insert_menu = XtCreateManagedWidget("Insert", xmPushButtonWidgetClass, help_menu, main_args, main_n); XtAddCallback(help_insert_menu, XmNactivateCallback, help_insert_callback, NULL); help_delete_menu = XtCreateManagedWidget("Delete", xmPushButtonWidgetClass, help_menu, main_args, main_n); XtAddCallback(help_delete_menu, XmNactivateCallback, help_delete_callback, NULL); help_undo_menu = XtCreateManagedWidget("Undo and redo", xmPushButtonWidgetClass, help_menu, main_args, main_n); XtAddCallback(help_undo_menu, XmNactivateCallback, help_undo_callback, NULL); #if HAVE_EXTENSION_LANGUAGE help_find_menu = XtCreateManagedWidget("Search", xmPushButtonWidgetClass, help_menu, main_args, main_n); XtAddCallback(help_find_menu, XmNactivateCallback, help_find_callback, NULL); #endif help_sync_menu = XtCreateManagedWidget("Sync and unite", xmPushButtonWidgetClass, help_menu, main_args, main_n); XtAddCallback(help_sync_menu, XmNactivateCallback, help_sync_callback, NULL); help_sound_files_menu = XtCreateManagedWidget("Headers and data", xmPushButtonWidgetClass, help_menu, main_args, main_n); XtAddCallback(help_sound_files_menu, XmNactivateCallback, help_sound_files_callback, NULL); help_debug_menu = XtCreateManagedWidget("Debugging", xmPushButtonWidgetClass, help_menu, main_args, main_n); XtAddCallback(help_debug_menu, XmNactivateCallback, help_debug_callback, NULL); help_region_menu = XtCreateManagedWidget("Regions", xmPushButtonWidgetClass, help_menu, main_args, main_n); XtAddCallback(help_region_menu, XmNactivateCallback, help_region_callback, NULL); help_selection_menu = XtCreateManagedWidget("Selections", xmPushButtonWidgetClass, help_menu, main_args, main_n); XtAddCallback(help_selection_menu, XmNactivateCallback, help_selection_callback, NULL); help_colors_menu = XtCreateManagedWidget("Colors", xmPushButtonWidgetClass, help_menu, main_args, main_n); XtAddCallback(help_colors_menu, XmNactivateCallback, help_colors_callback, NULL); XtVaSetValues(main_menu, XmNmenuHelpWidget, help_cascade_menu, NULL); XtAddCallback(file_cascade_menu, XmNcascadingCallback, file_menu_update_1, NULL); XtAddCallback(edit_cascade_menu, XmNcascadingCallback, edit_menu_update_1, NULL); XtAddCallback(view_cascade_menu, XmNcascadingCallback, view_menu_update_1, NULL); XtManageChild(main_menu); return(main_menu); } /* -------------------------------- POPUP MENU -------------------------------- */ static Widget basic_popup_menu = NULL, selection_popup_menu = NULL, fft_popup_menu = NULL; static Widget add_menu_item(Widget menu, const char *label, void (*callback)(Widget w, XtPointer info, XtPointer context)) { Arg args[20]; int n; Widget w; n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; w = XtCreateManagedWidget(label, xmPushButtonWidgetClass, menu, args, n); XtAddCallback(w, XmNactivateCallback, callback, NULL); return(w); } static void popup_info_callback(Widget w, XtPointer info, XtPointer context) { snd_info *sp; sp = any_selected_sound(); if (sp) display_info(sp); } static void popup_normalize_callback(Widget w, XtPointer info, XtPointer context) { mus_float_t scl[1]; scl[0] = 1.0; scale_to(any_selected_sound(), current_channel(), scl, 1, OVER_SOUND); } static void popup_reverse_callback(Widget w, XtPointer info, XtPointer context) { reverse_sound(current_channel(), OVER_SOUND, C_int_to_Xen_integer(AT_CURRENT_EDIT_POSITION), 0); } static void stop_everything_callback(Widget w, XtPointer info, XtPointer context) { control_g(any_selected_sound()); } static void play_channel_callback(Widget w, XtPointer info, XtPointer context) { chan_info *cp; cp = current_channel(); play_channel(cp, 0, current_samples(cp)); } static Widget popup_play; void post_basic_popup_menu(void *e) { XButtonPressedEvent *event = (XButtonPressedEvent *)e; snd_info *sp; if (!basic_popup_menu) { Arg args[20]; int n; n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNpopupEnabled, false); n++; /* this was XmPOPUP_AUTOMATIC_RECURSIVE */ basic_popup_menu = XmCreatePopupMenu(MAIN_PANE(ss), (char *)"basic-popup-menu", args, n); add_menu_item(basic_popup_menu, "Info", popup_info_callback); add_menu_item(basic_popup_menu, "Select all", edit_select_all_callback); popup_play = add_menu_item(basic_popup_menu, "Play channel", play_channel_callback); add_menu_item(basic_popup_menu, "Stop!", stop_everything_callback); add_menu_item(basic_popup_menu, "-> 1.0", popup_normalize_callback); add_menu_item(basic_popup_menu, "Reverse", popup_reverse_callback); } XmMenuPosition(basic_popup_menu, event); sp = any_selected_sound(); if ((!sp) || (sp->nchans == 1)) XtUnmanageChild(popup_play); else XtManageChild(popup_play); XtManageChild(basic_popup_menu); } /* -------- selection popup -------- */ static void popup_show_selection_callback(Widget w, XtPointer info, XtPointer context) { show_selection(); } static void popup_zero_selection_callback(Widget w, XtPointer info, XtPointer context) { mus_float_t scl[1]; scl[0] = 0.0; scale_by(NULL, scl, 1, OVER_SELECTION); } static void popup_normalize_selection_callback(Widget w, XtPointer info, XtPointer context) { mus_float_t scl[1]; scl[0] = 1.0; scale_to(NULL, NULL, scl, 1, OVER_SELECTION); } static void popup_error_handler(const char *msg, void *data) { redirect_snd_error_to(NULL, NULL); redirect_snd_warning_to(NULL, NULL); status_report(any_selected_sound(), "%s: %s", (char *)data, msg); } static void popup_cut_to_new_callback_1(bool cut) { char *temp_file; io_error_t io_err = IO_NO_ERROR; temp_file = snd_tempnam(); io_err = save_selection(temp_file, selection_srate(), default_output_sample_type(ss), default_output_header_type(ss), NULL, SAVE_ALL_CHANS); if (io_err == IO_NO_ERROR) { if (cut) delete_selection(UPDATE_DISPLAY); ss->open_requestor = FROM_POPUP_CUT_TO_NEW; redirect_snd_error_to(popup_error_handler, (void *)"popup cut->new"); snd_open_file(temp_file, FILE_READ_WRITE); redirect_snd_error_to(NULL, NULL); free(temp_file); } } static void popup_cut_to_new_callback(Widget w, XtPointer info, XtPointer context) {popup_cut_to_new_callback_1(true);} static void popup_copy_to_new_callback(Widget w, XtPointer info, XtPointer context) {popup_cut_to_new_callback_1(false);} static void crop(chan_info *cp) { if (selection_is_active_in_channel(cp)) { mus_long_t beg, end, framples; framples = current_samples(cp); beg = selection_beg(cp); end = selection_end(cp); if (beg > 0) delete_samples(0, beg, cp, cp->edit_ctr); if (end < (framples - 1)) delete_samples(end + 1, framples - end, cp, cp->edit_ctr); } } static void popup_crop_callback(Widget w, XtPointer info, XtPointer context) { for_each_chan(crop); } static void popup_cut_and_smooth_callback(Widget w, XtPointer info, XtPointer context) { for_each_chan(cut_and_smooth); } static void mark_selection(chan_info *cp) { if (selection_is_active_in_channel(cp)) { add_mark(selection_beg(cp), NULL, cp); add_mark(selection_end(cp), NULL, cp); } } static void popup_mark_selection_callback(Widget w, XtPointer info, XtPointer context) { for_each_chan(mark_selection); } static void popup_reverse_selection_callback(Widget w, XtPointer info, XtPointer context) { reverse_sound(current_channel(), OVER_SELECTION, C_int_to_Xen_integer(AT_CURRENT_EDIT_POSITION), 0); } static mus_float_t selection_max = 0.0; static void selection_info(chan_info *cp) { if ((selection_is_active_in_channel(cp)) && (selection_maxamp(cp) > selection_max)) selection_max = selection_maxamp(cp); } static void popup_selection_info_callback(Widget w, XtPointer info, XtPointer context) { selection_max = 0.0; for_each_chan(selection_info); status_report(any_selected_sound(), "selection max: %f", selection_max); } #if WITH_AUDIO static void popup_loop_play_callback(Widget w, XtPointer info, XtPointer context) { if (ss->selection_play_stop) { stop_playing_all_sounds(PLAY_BUTTON_UNSET); reflect_play_selection_stop(); } else { set_menu_label(edit_play_menu, I_STOP); ss->selection_play_stop = true; loop_play_selection(); } } #endif void post_selection_popup_menu(void *e) { XButtonPressedEvent *event = (XButtonPressedEvent *)e; if (!selection_popup_menu) { Arg args[20]; int n; n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNpopupEnabled, false); n++; /* this was XmPOPUP_AUTOMATIC_RECURSIVE */ selection_popup_menu = XmCreatePopupMenu(MAIN_PANE(ss), (char *)"selection-popup-menu", args, n); add_menu_item(selection_popup_menu, "Fill window", popup_show_selection_callback); add_menu_item(selection_popup_menu, "Cut", edit_cut_callback); add_menu_item(selection_popup_menu, "Cut and smooth", popup_cut_and_smooth_callback); add_menu_item(selection_popup_menu, "Cut -> new", popup_cut_to_new_callback); add_menu_item(selection_popup_menu, "Save as", edit_save_as_callback); #if WITH_AUDIO add_menu_item(selection_popup_menu, "Play", edit_play_callback); add_menu_item(selection_popup_menu, "Play looping", popup_loop_play_callback); #endif add_menu_item(selection_popup_menu, "Crop", popup_crop_callback); add_menu_item(selection_popup_menu, "Unselect all", edit_unselect_callback); add_menu_item(selection_popup_menu, "-> 0.0", popup_zero_selection_callback); add_menu_item(selection_popup_menu, "-> 1.0", popup_normalize_selection_callback); add_menu_item(selection_popup_menu, "Copy -> new", popup_copy_to_new_callback); add_menu_item(selection_popup_menu, "Paste", edit_paste_callback); add_menu_item(selection_popup_menu, "Mix", edit_mix_callback); add_menu_item(selection_popup_menu, "Mark", popup_mark_selection_callback); add_menu_item(selection_popup_menu, "Reverse", popup_reverse_selection_callback); add_menu_item(selection_popup_menu, "Info", popup_selection_info_callback); } XmMenuPosition(selection_popup_menu, event); XtManageChild(selection_popup_menu); } /* -------- fft popup -------- */ static void popup_peaks_callback(Widget w, XtPointer info, XtPointer context) { FILE *peaks_fd; peaks_fd = FOPEN("fft.txt", "w"); if (peaks_fd) { write_transform_peaks(peaks_fd, current_channel()); /* follows sync */ fclose(peaks_fd); } } static void fft_size_16_callback(Widget w, XtPointer info, XtPointer context) {set_transform_size(16);} static void fft_size_64_callback(Widget w, XtPointer info, XtPointer context) {set_transform_size(64);} static void fft_size_256_callback(Widget w, XtPointer info, XtPointer context) {set_transform_size(256);} static void fft_size_1024_callback(Widget w, XtPointer info, XtPointer context) {set_transform_size(1024);} static void fft_size_4096_callback(Widget w, XtPointer info, XtPointer context) {set_transform_size(4096);} static void fft_size_16384_callback(Widget w, XtPointer info, XtPointer context) {set_transform_size(16384);} static void fft_size_65536_callback(Widget w, XtPointer info, XtPointer context) {set_transform_size(65536);} static void fft_size_262144_callback(Widget w, XtPointer info, XtPointer context) {set_transform_size(262144);} static void fft_size_1048576_callback(Widget w, XtPointer info, XtPointer context) {set_transform_size(1048576);} static void fft_window_rectangular_callback(Widget w, XtPointer info, XtPointer context) {set_fft_window(MUS_RECTANGULAR_WINDOW);} static void fft_window_hann_callback(Widget w, XtPointer info, XtPointer context) {set_fft_window(MUS_HANN_WINDOW);} static void fft_window_welch_callback(Widget w, XtPointer info, XtPointer context) {set_fft_window(MUS_WELCH_WINDOW);} static void fft_window_parzen_callback(Widget w, XtPointer info, XtPointer context) {set_fft_window(MUS_PARZEN_WINDOW);} static void fft_window_bartlett_callback(Widget w, XtPointer info, XtPointer context) {set_fft_window(MUS_BARTLETT_WINDOW);} static void fft_window_blackman2_callback(Widget w, XtPointer info, XtPointer context) {set_fft_window(MUS_BLACKMAN2_WINDOW);} static void fft_window_blackman3_callback(Widget w, XtPointer info, XtPointer context) {set_fft_window(MUS_BLACKMAN3_WINDOW);} static void fft_window_blackman4_callback(Widget w, XtPointer info, XtPointer context) {set_fft_window(MUS_BLACKMAN4_WINDOW);} static void fft_window_hamming_callback(Widget w, XtPointer info, XtPointer context) {set_fft_window(MUS_HAMMING_WINDOW);} static void fft_window_exponential_callback(Widget w, XtPointer info, XtPointer context) {set_fft_window(MUS_EXPONENTIAL_WINDOW);} static void fft_window_riemann_callback(Widget w, XtPointer info, XtPointer context) {set_fft_window(MUS_RIEMANN_WINDOW);} static void fft_window_kaiser_callback(Widget w, XtPointer info, XtPointer context) {set_fft_window(MUS_KAISER_WINDOW);} static void fft_window_cauchy_callback(Widget w, XtPointer info, XtPointer context) {set_fft_window(MUS_CAUCHY_WINDOW);} static void fft_window_poisson_callback(Widget w, XtPointer info, XtPointer context) {set_fft_window(MUS_POISSON_WINDOW);} static void fft_window_gaussian_callback(Widget w, XtPointer info, XtPointer context) {set_fft_window(MUS_GAUSSIAN_WINDOW);} static void fft_window_tukey_callback(Widget w, XtPointer info, XtPointer context) {set_fft_window(MUS_TUKEY_WINDOW);} static void fft_window_dolph_chebyshev_callback(Widget w, XtPointer info, XtPointer context) {set_fft_window(MUS_DOLPH_CHEBYSHEV_WINDOW);} static void fft_window_blackman6_callback(Widget w, XtPointer info, XtPointer context) {set_fft_window(MUS_BLACKMAN6_WINDOW);} static void fft_window_blackman8_callback(Widget w, XtPointer info, XtPointer context) {set_fft_window(MUS_BLACKMAN8_WINDOW);} static void fft_window_blackman10_callback(Widget w, XtPointer info, XtPointer context) {set_fft_window(MUS_BLACKMAN10_WINDOW);} static void fft_type_fourier_callback(Widget w, XtPointer info, XtPointer context) {set_transform_type(FOURIER);} static void fft_type_wavelet_callback(Widget w, XtPointer info, XtPointer context) {set_transform_type(WAVELET);} static void fft_type_autocorrelation_callback(Widget w, XtPointer info, XtPointer context) {set_transform_type(AUTOCORRELATION);} static void fft_type_cepstrum_callback(Widget w, XtPointer info, XtPointer context) {set_transform_type(CEPSTRUM);} static void fft_graph_once_callback(Widget w, XtPointer info, XtPointer context) {set_transform_graph_type(GRAPH_ONCE);} static void fft_graph_sonogram_callback(Widget w, XtPointer info, XtPointer context) {set_transform_graph_type(GRAPH_AS_SONOGRAM);} static void fft_graph_spectrogram_callback(Widget w, XtPointer info, XtPointer context) {set_transform_graph_type(GRAPH_AS_SPECTROGRAM);} static void fft_gray_callback(Widget w, XtPointer info, XtPointer context) {set_color_map(GRAY_COLORMAP);} static void fft_hot_callback(Widget w, XtPointer info, XtPointer context) {set_color_map(HOT_COLORMAP);} static void fft_cool_callback(Widget w, XtPointer info, XtPointer context) {set_color_map(COOL_COLORMAP);} static void fft_bone_callback(Widget w, XtPointer info, XtPointer context) {set_color_map(BONE_COLORMAP);} static void fft_copper_callback(Widget w, XtPointer info, XtPointer context) {set_color_map(COPPER_COLORMAP);} static void fft_pink_callback(Widget w, XtPointer info, XtPointer context) {set_color_map(PINK_COLORMAP);} static void fft_jet_callback(Widget w, XtPointer info, XtPointer context) {set_color_map(JET_COLORMAP);} static void fft_prism_callback(Widget w, XtPointer info, XtPointer context) {set_color_map(PRISM_COLORMAP);} static void fft_autumn_callback(Widget w, XtPointer info, XtPointer context) {set_color_map(AUTUMN_COLORMAP);} static void fft_winter_callback(Widget w, XtPointer info, XtPointer context) {set_color_map(WINTER_COLORMAP);} static void fft_spring_callback(Widget w, XtPointer info, XtPointer context) {set_color_map(SPRING_COLORMAP);} static void fft_summer_callback(Widget w, XtPointer info, XtPointer context) {set_color_map(SUMMER_COLORMAP);} static void fft_rainbow_callback(Widget w, XtPointer info, XtPointer context) {set_color_map(RAINBOW_COLORMAP);} static void fft_flag_callback(Widget w, XtPointer info, XtPointer context) {set_color_map(FLAG_COLORMAP);} static void fft_phases_callback(Widget w, XtPointer info, XtPointer context) {set_color_map(PHASES_COLORMAP);} static void fft_black_and_white_callback(Widget w, XtPointer info, XtPointer context) {set_color_map(BLACK_AND_WHITE_COLORMAP);} void post_fft_popup_menu(void *e) { XButtonPressedEvent *event = (XButtonPressedEvent *)e; if (!fft_popup_menu) { Widget outer_menu; Arg args[20]; int n; n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNpopupEnabled, false); n++; /* this was XmPOPUP_AUTOMATIC_RECURSIVE */ fft_popup_menu = XmCreatePopupMenu(MAIN_PANE(ss), (char *)"fft-popup-menu", args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; outer_menu = XmCreatePulldownMenu(fft_popup_menu, (char *)"Size", args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNsubMenuId, outer_menu); n++; XtCreateManagedWidget("Size", xmCascadeButtonWidgetClass, fft_popup_menu, args, n); add_menu_item(outer_menu, "16", fft_size_16_callback); add_menu_item(outer_menu, "64", fft_size_64_callback); add_menu_item(outer_menu, "256", fft_size_256_callback); add_menu_item(outer_menu, "1024", fft_size_1024_callback); add_menu_item(outer_menu, "4096", fft_size_4096_callback); add_menu_item(outer_menu, "16384", fft_size_16384_callback); add_menu_item(outer_menu, "65536", fft_size_65536_callback); add_menu_item(outer_menu, "262144", fft_size_262144_callback); add_menu_item(outer_menu, "1048576", fft_size_1048576_callback); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; outer_menu = XmCreatePulldownMenu(fft_popup_menu, (char *)"Window", args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNsubMenuId, outer_menu); n++; XtCreateManagedWidget("Window", xmCascadeButtonWidgetClass, fft_popup_menu, args, n); add_menu_item(outer_menu, "rectangular", fft_window_rectangular_callback); add_menu_item(outer_menu, "hann", fft_window_hann_callback); add_menu_item(outer_menu, "welch", fft_window_welch_callback); add_menu_item(outer_menu, "parzen", fft_window_parzen_callback); add_menu_item(outer_menu, "bartlett", fft_window_bartlett_callback); add_menu_item(outer_menu, "hamming", fft_window_hamming_callback); add_menu_item(outer_menu, "blackman2", fft_window_blackman2_callback); add_menu_item(outer_menu, "blackman3", fft_window_blackman3_callback); add_menu_item(outer_menu, "blackman4", fft_window_blackman4_callback); add_menu_item(outer_menu, "exponential", fft_window_exponential_callback); add_menu_item(outer_menu, "riemann", fft_window_riemann_callback); add_menu_item(outer_menu, "kaiser", fft_window_kaiser_callback); add_menu_item(outer_menu, "cauchy", fft_window_cauchy_callback); add_menu_item(outer_menu, "poisson", fft_window_poisson_callback); add_menu_item(outer_menu, "gaussian", fft_window_gaussian_callback); add_menu_item(outer_menu, "tukey", fft_window_tukey_callback); add_menu_item(outer_menu, "dolph-chebyshev", fft_window_dolph_chebyshev_callback); add_menu_item(outer_menu, "blackman6", fft_window_blackman6_callback); add_menu_item(outer_menu, "blackman8", fft_window_blackman8_callback); add_menu_item(outer_menu, "blackman10" , fft_window_blackman10_callback); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; outer_menu = XmCreatePulldownMenu(fft_popup_menu, (char *)"Graph type", args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNsubMenuId, outer_menu); n++; XtCreateManagedWidget("Graph type", xmCascadeButtonWidgetClass, fft_popup_menu, args, n); add_menu_item(outer_menu, "one fft", fft_graph_once_callback); add_menu_item(outer_menu, "sonogram", fft_graph_sonogram_callback); add_menu_item(outer_menu, "spectrogram", fft_graph_spectrogram_callback); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; outer_menu = XmCreatePulldownMenu(fft_popup_menu, (char *)"Transform type", args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNsubMenuId, outer_menu); n++; XtCreateManagedWidget("Transform type", xmCascadeButtonWidgetClass, fft_popup_menu, args, n); add_menu_item(outer_menu, "fourier", fft_type_fourier_callback); add_menu_item(outer_menu, "wavelet", fft_type_wavelet_callback); add_menu_item(outer_menu, "autocorrelation", fft_type_autocorrelation_callback); add_menu_item(outer_menu, "cepstrum", fft_type_cepstrum_callback); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; outer_menu = XmCreatePulldownMenu(fft_popup_menu, (char *)"Colormap", args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNsubMenuId, outer_menu); n++; XtCreateManagedWidget("Colormap", xmCascadeButtonWidgetClass, fft_popup_menu, args, n); add_menu_item(outer_menu, "gray", fft_gray_callback); add_menu_item(outer_menu, "autumn", fft_autumn_callback); add_menu_item(outer_menu, "spring", fft_spring_callback); add_menu_item(outer_menu, "winter", fft_winter_callback); add_menu_item(outer_menu, "summer", fft_summer_callback); add_menu_item(outer_menu, "cool", fft_cool_callback); add_menu_item(outer_menu, "copper", fft_copper_callback); add_menu_item(outer_menu, "flag", fft_flag_callback); add_menu_item(outer_menu, "prism", fft_prism_callback); add_menu_item(outer_menu, "bone", fft_bone_callback); add_menu_item(outer_menu, "hot", fft_hot_callback); add_menu_item(outer_menu, "jet", fft_jet_callback); add_menu_item(outer_menu, "pink", fft_pink_callback); add_menu_item(outer_menu, "rainbow", fft_rainbow_callback); add_menu_item(outer_menu, "phases", fft_phases_callback); add_menu_item(outer_menu, "black and white", fft_black_and_white_callback); add_menu_item(fft_popup_menu, "Peaks->fft.txt", popup_peaks_callback); } XmMenuPosition(fft_popup_menu, event); XtManageChild(fft_popup_menu); } void post_lisp_popup_menu(void *e) {} /* ---------------- tooltips ---------------- */ static Widget tooltip_shell = NULL; static Widget tooltip_label = NULL; static timeout_result_t tool_proc = 0, quit_proc = 0; static Time tool_last_time = 0; static Position tool_x, tool_y; static Widget tool_w; static void leave_tooltip(XtPointer tooltip, XtIntervalId *id) { XtUnmanageChild(tooltip_shell); quit_proc = 0; } static void handle_tooltip(XtPointer tooltip, XtIntervalId *id) { char *tip = (char *)tooltip; Position rx, ry; XmString str; int lines = 0; if (!tooltip_shell) { tooltip_shell = XtVaCreatePopupShell(tip, overrideShellWidgetClass, MAIN_SHELL(ss), XmNallowShellResize, true, NULL); tooltip_label = XtVaCreateManagedWidget("tooltip", xmLabelWidgetClass, tooltip_shell, XmNrecomputeSize, true, XmNbackground, ss->lighter_blue, NULL); } str = multi_line_label(tip, &lines); XtVaSetValues(tooltip_label, XmNlabelString, str, NULL); XmStringFree(str); XtTranslateCoords(tool_w, tool_x, tool_y, &rx, &ry); XtVaSetValues(tooltip_shell, XmNx, rx, XmNy, ry, NULL); XtManageChild(tooltip_shell); quit_proc = XtAppAddTimeOut(MAIN_APP(ss), (unsigned long)10000, (XtTimerCallbackProc)leave_tooltip, NULL); } static void tool_starter(Widget w, XtPointer context, XEvent *event, Boolean *cont) { XEnterWindowEvent *ev = (XEnterWindowEvent *)event; char *tip = (char *)context; if ((with_tooltips(ss)) && ((ev->time - tool_last_time) > 2)) { tool_x = ev->x; tool_y = ev->y; tool_w = w; tool_last_time = ev->time; tool_proc = XtAppAddTimeOut(MAIN_APP(ss), (unsigned long)300, (XtTimerCallbackProc)handle_tooltip, (XtPointer)tip); } } static void tool_stopper(Widget w, XtPointer context, XEvent *event, Boolean *cont) { XLeaveWindowEvent *ev = (XLeaveWindowEvent *)event; tool_last_time = ev->time; if (tool_proc != 0) { XtRemoveTimeOut(tool_proc); tool_proc = 0; } if (quit_proc != 0) { XtRemoveTimeOut(quit_proc); quit_proc = 0; } if ((tooltip_shell) && (XtIsManaged(tooltip_shell))) XtUnmanageChild(tooltip_shell); } void add_tooltip(Widget w, const char *tip) { XtAddEventHandler(w, EnterWindowMask, false, tool_starter, (XtPointer)tip); XtAddEventHandler(w, LeaveWindowMask, false, tool_stopper, NULL); } /* ---------------- toolbar ---------------- */ static void add_to_toolbar(Widget bar, Pixmap icon, const char *tip, void (*callback)(Widget w, XtPointer info, XtPointer context)) { Widget w; w = XtVaCreateManagedWidget("icon", xmPushButtonWidgetClass, bar, XmNlabelPixmap, icon, XmNlabelType, XmPIXMAP, XmNwidth, 24, XmNheight, 24, XmNshadowThickness, 0, XmNhighlightThickness, 0, /* XmNmarginHeight, 0, */ XmNbackground, ss->basic_color, NULL); XtAddCallback(w, XmNactivateCallback, callback, NULL); add_tooltip(w, tip); } static void add_separator_to_toolbar(Widget bar) { XtVaCreateManagedWidget("icon", xmPushButtonWidgetClass, bar, XmNlabelPixmap, toolbar_icon(SND_XPM_SEPARATOR), XmNlabelType, XmPIXMAP, XmNwidth, 8, XmNheight, 24, XmNshadowThickness, 0, XmNhighlightThickness, 0, XmNbackground, ss->basic_color, NULL); } #if WITH_AUDIO static void play_from_start_callback(Widget w, XtPointer info, XtPointer context) { snd_info *sp; sp = any_selected_sound(); if (sp) play_sound(sp, 0, NO_END_SPECIFIED); } static void play_from_cursor_callback(Widget w, XtPointer info, XtPointer context) { snd_info *sp; sp = any_selected_sound(); if (sp) { chan_info *cp; cp = any_selected_channel(sp); if (cp) play_sound(sp, cursor_sample(cp), NO_END_SPECIFIED); } } static void stop_playing_callback(Widget w, XtPointer info, XtPointer context) { stop_playing_all_sounds(PLAY_C_G); reflect_play_selection_stop(); /* this sets ss->selection_play_stop = false; */ } #endif static void full_dur_callback(Widget w, XtPointer info, XtPointer context) { snd_info *sp; sp = any_selected_sound(); if (sp) { int i; for (i = 0; i < sp->nchans; i++) set_x_axis_x0x1(sp->chans[i], 0.0, sp->chans[i]->axis->xmax); } } static void zoom_out_callback(Widget w, XtPointer info, XtPointer context) { snd_info *sp; sp = any_selected_sound(); if (sp) { int i; for (i = 0; i < sp->nchans; i++) zx_incremented(sp->chans[i], 2.0); } } static void zoom_in_callback(Widget w, XtPointer info, XtPointer context) { snd_info *sp; sp = any_selected_sound(); if (sp) { int i; for (i = 0; i < sp->nchans; i++) zx_incremented(sp->chans[i], 0.5); } } static void goto_start_callback(Widget w, XtPointer info, XtPointer context) { snd_info *sp; sp = any_selected_sound(); if (sp) { int i; for (i = 0; i < sp->nchans; i++) set_x_axis_x0x1(sp->chans[i], 0.0, sp->chans[i]->axis->x1 - sp->chans[i]->axis->x0); } } static void go_back_callback(Widget w, XtPointer info, XtPointer context) { snd_info *sp; sp = any_selected_sound(); if (sp) { int i; for (i = 0; i < sp->nchans; i++) sx_incremented(sp->chans[i], -1.0); } } static void go_forward_callback(Widget w, XtPointer info, XtPointer context) { snd_info *sp; sp = any_selected_sound(); if (sp) { int i; for (i = 0; i < sp->nchans; i++) sx_incremented(sp->chans[i], 1.0); } } static void goto_end_callback(Widget w, XtPointer info, XtPointer context) { snd_info *sp; sp = any_selected_sound(); if (sp) { int i; for (i = 0; i < sp->nchans; i++) set_x_axis_x0x1(sp->chans[i], sp->chans[i]->axis->xmax - sp->chans[i]->axis->x1 + sp->chans[i]->axis->x0, sp->chans[i]->axis->xmax); } } static Widget toolbar = NULL; void show_toolbar(void) { if (!toolbar) { #define ICON_HEIGHT 28 Arg args[32]; int n; XtVaSetValues(MAIN_SHELL(ss), XmNallowShellResize, false, NULL); n = attach_all_sides(args, 0); XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNheight, ICON_HEIGHT); n++; XtSetArg(args[n], XmNpaneMaximum, ICON_HEIGHT); n++; /* Xm/Paned initializes each pane max to 1000 apparently! */ XtSetArg(args[n], XmNpositionIndex, 0); n++; XtSetArg(args[n], XmNshadowThickness, 0); n++; XtSetArg(args[n], XmNhighlightThickness, 0); n++; XtSetArg(args[n], XmNmarginHeight, 0); n++; if ((sound_style(ss) == SOUNDS_IN_NOTEBOOK) || (sound_style(ss) == SOUNDS_HORIZONTAL)) toolbar = XtCreateManagedWidget("toolbar", xmRowColumnWidgetClass, SOUND_PANE_BOX(ss), args, n); else toolbar = XtCreateManagedWidget("toolbar", xmRowColumnWidgetClass, SOUND_PANE(ss), args, n); ss->toolbar = toolbar; if (auto_resize(ss)) XtVaSetValues(MAIN_SHELL(ss), XmNallowShellResize, true, NULL); make_toolbar_icons(MAIN_SHELL(ss)); add_to_toolbar(toolbar, toolbar_icon(SND_XPM_NEW), "new sound", file_new_callback); add_to_toolbar(toolbar, toolbar_icon(SND_XPM_OPEN), "open sound", file_open_callback); add_to_toolbar(toolbar, toolbar_icon(SND_XPM_SAVE), "save current sound, overwriting it", file_save_callback); add_to_toolbar(toolbar, toolbar_icon(SND_XPM_SAVE_AS), "save current sound in a new file", file_save_as_callback); add_to_toolbar(toolbar, toolbar_icon(SND_XPM_REVERT), "revert to saved", file_revert_callback); add_to_toolbar(toolbar, toolbar_icon(SND_XPM_UNDO), "undo edit", edit_undo_callback); add_to_toolbar(toolbar, toolbar_icon(SND_XPM_REDO), "redo last (undone) edit", edit_redo_callback); add_to_toolbar(toolbar, toolbar_icon(SND_XPM_CLOSE), "close selected sound", file_close_callback); add_separator_to_toolbar(toolbar); #if WITH_AUDIO add_to_toolbar(toolbar, toolbar_icon(SND_XPM_PLAY), "play from the start", play_from_start_callback); add_to_toolbar(toolbar, toolbar_icon(SND_XPM_CURSOR_PLAY), "play from the cursor", play_from_cursor_callback); add_to_toolbar(toolbar, toolbar_icon(SND_XPM_STOP_PLAY), "stop playing", stop_playing_callback); add_separator_to_toolbar(toolbar); #endif add_to_toolbar(toolbar, toolbar_icon(SND_XPM_UP), "show full sound", full_dur_callback); add_to_toolbar(toolbar, toolbar_icon(SND_XPM_ZOOM_OUT), "zoom out", zoom_out_callback); add_to_toolbar(toolbar, toolbar_icon(SND_XPM_ZOOM_IN), "zoom in", zoom_in_callback); add_to_toolbar(toolbar, toolbar_icon(SND_XPM_BACK_ARROW), "go to start of sound", goto_start_callback); add_to_toolbar(toolbar, toolbar_icon(SND_XPM_BACK), "go back a window", go_back_callback); add_to_toolbar(toolbar, toolbar_icon(SND_XPM_NEXT), "go forward a window", go_forward_callback); add_to_toolbar(toolbar, toolbar_icon(SND_XPM_FORWARD_ARROW), "go to end of sound", goto_end_callback); add_separator_to_toolbar(toolbar); add_to_toolbar(toolbar, toolbar_icon(SND_XPM_CUT), "delete selection", edit_cut_callback); add_to_toolbar(toolbar, toolbar_icon(SND_XPM_PASTE), "insert selection at cursor", edit_paste_callback); add_to_toolbar(toolbar, toolbar_icon(SND_XPM_PREFERENCES), "open preferences dialog", options_preferences_callback); add_to_toolbar(toolbar, toolbar_icon(SND_XPM_STOP), "stop the current operation", stop_everything_callback); add_to_toolbar(toolbar, toolbar_icon(SND_XPM_EXIT), "exit Snd", file_exit_callback); } else { XtVaSetValues(MAIN_SHELL(ss), XmNallowShellResize, false, NULL); XtManageChild(toolbar); if (auto_resize(ss)) XtVaSetValues(MAIN_SHELL(ss), XmNallowShellResize, true, NULL); } } void hide_toolbar(void) { if (toolbar) { XtVaSetValues(MAIN_SHELL(ss), XmNallowShellResize, false, NULL); XtUnmanageChild(toolbar); if (auto_resize(ss)) XtVaSetValues(MAIN_SHELL(ss), XmNallowShellResize, true, NULL); } } /* ---------------- ext lang tie-ins ---------------- */ #define INVALID_MENU -1 #define call_index(Data) (Data >> 16) #define pack_menu_data(Slot, Menu) ((Slot << 16) | (Menu)) static void menu_callback(Widget w, XtPointer info, XtPointer context) { pointer_or_int_t callb; XtVaGetValues(w, XmNuserData, &callb, NULL); g_menu_callback(call_index(callb)); /* menu option activate callback */ } static void GHC_callback(Widget w, XtPointer info, XtPointer context) { pointer_or_int_t slot; XtVaGetValues(w, XmNuserData, &slot, NULL); g_menu_callback(call_index(slot)); /* main menu cascading callback */ } static Widget *main_menus = NULL; static int main_menus_size = 0; /* fancy code here looping through the main menus children hangs or segfaults in 86_64 unoptimized cases! */ Widget menu_widget(int which_menu) { switch (which_menu) { case 0: return(file_menu); break; case 1: return(edit_menu); break; case 2: return(view_menu); break; case 3: return(options_menu); break; case 4: return(help_menu); break; default: if (which_menu < main_menus_size) return(main_menus[which_menu]); break; } return(NULL); } static bool or_over_children(Widget w, bool (*func)(Widget uw, const char *ustr), const char *str) { if (w) { if ((*func)(w, str)) return(true); if (XtIsComposite(w)) { unsigned int i; CompositeWidget cw = (CompositeWidget)w; for (i = 0; i < cw->composite.num_children; i++) if (or_over_children(cw->composite.children[i], func, str)) return(true); } } return(false); } static bool clobber_menu(Widget w, const char *name) { char *wname; wname = XtName(w); if ((wname) && (mus_strcmp(name, wname)) && (XtIsManaged(w))) { pointer_or_int_t slot; XtVaGetValues(w, XmNuserData, &slot, NULL); unprotect_callback(call_index(slot)); XtUnmanageChild(w); } return(true); /* in any case, don't try to recurse into the children */ } int g_remove_from_menu(int which_menu, const char *label) { Widget top_menu; top_menu = menu_widget(which_menu); if (top_menu) { or_over_children(top_menu, clobber_menu, label); return(0); } return(INVALID_MENU); } static void set_widget_name(Widget w, const char *new_name) { /* based on XtName in Xt/Intrinsic.c, Xt/Create.c, and Xt/ResourceI.h */ w->core.xrm_name = XrmStringToName(new_name); } static int new_menu = 5; int g_add_to_main_menu(const char *label, int slot) { static Arg args[12]; Widget m, cas; int n; if (auto_resize(ss)) XtVaSetValues(MAIN_SHELL(ss), XmNallowShellResize, false, NULL); new_menu++; n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNuserData, pack_menu_data(slot, new_menu)); n++; m = XmCreatePulldownMenu(main_menu, (char *)label, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNsubMenuId, m); n++; XtSetArg(args[n], XmNuserData, pack_menu_data(slot, new_menu)); n++; cas = XtCreateManagedWidget(label, xmCascadeButtonWidgetClass, main_menu, args, n); if (slot >= 0) XtAddCallback(cas, XmNcascadingCallback, GHC_callback, NULL); if (auto_resize(ss)) XtVaSetValues(MAIN_SHELL(ss), XmNallowShellResize, true, NULL); if (main_menus_size == 0) { main_menus_size = 8; main_menus = (Widget *)calloc(main_menus_size, sizeof(Widget)); } else { if (new_menu >= main_menus_size) { main_menus_size = new_menu + 8; main_menus = (Widget *)realloc(main_menus, main_menus_size * sizeof(Widget)); } } main_menus[new_menu] = m; return(new_menu); } Widget g_add_to_menu(int which_menu, const char *label, int callb, int position) { Widget m, menw; Arg args[12]; int n = 0; menw = menu_widget(which_menu); if (menw == NULL) return(NULL); if (label) { unsigned int i; /* look for currently unused widget first */ /* but close-all and open-recent should be left alone! */ CompositeWidget cw = (CompositeWidget)menw; for (i = 0; i < cw->composite.num_children; i++) { m = cw->composite.children[i]; if ((m) && (!(XtIsManaged(m))) && (m != file_close_all_menu) && (m != file_open_recent_menu) && (m != file_open_recent_cascade_menu)) { if (!(mus_strcmp(XtName(m), label))) { set_widget_name(m, label); set_button_label(m, label); } if (position >= 0) XtVaSetValues(m, XmNpositionIndex, position, NULL); XtVaSetValues(m, XmNuserData, pack_menu_data(callb, which_menu), NULL); XtManageChild(m); return(m); } } XtSetArg(args[n], XmNbackground, ss->basic_color); n++; if (position >= 0) {XtSetArg(args[n], XmNpositionIndex, position); n++;} XtSetArg(args[n], XmNuserData, pack_menu_data(callb, which_menu)); n++; m = XtCreateManagedWidget(label, xmPushButtonWidgetClass, menw, args, n); XtAddCallback(m, XmNactivateCallback, menu_callback, NULL); } else { XtSetArg(args[n], XmNbackground, ss->basic_color); n++; if (position >= 0) {XtSetArg(args[n], XmNpositionIndex, position); n++;} m = XtCreateManagedWidget("sep", xmSeparatorWidgetClass, menw, args, n); } return(m); } static Xen g_menu_widgets(void) { #define H_menu_widgets "(" S_menu_widgets "): a list of top level menu widgets: ((0)main (1)file (2)edit (3)view (4)options (5)help)" return(Xen_cons(Xen_wrap_widget(main_menu), Xen_cons(Xen_wrap_widget(file_cascade_menu), Xen_cons(Xen_wrap_widget(edit_cascade_menu), Xen_cons(Xen_wrap_widget(view_cascade_menu), Xen_cons(Xen_wrap_widget(options_cascade_menu), Xen_cons(Xen_wrap_widget(help_cascade_menu), Xen_empty_list))))))); } Xen_wrap_no_args(g_menu_widgets_w, g_menu_widgets) void g_init_gxmenu(void) { Xen_define_safe_procedure(S_menu_widgets, g_menu_widgets_w, 0, 0, 0, H_menu_widgets); } /* Motif bug: the button backgrounds remain in the original highlight color? but the widget (if it is one) is not the child of any obvious widget */ /* motif case needs prompt length fixups, listener if no panes, minibuffer as label not text entry */ /* ---------------- listener text history ---------------- */ static char **listener_strings = NULL; static int listener_strings_size = 0, listener_strings_pos = 0; static bool listener_first_time = true; static void remember_listener_string(const char *str) { int i, top; if (!str) return; if (listener_strings_size == 0) { listener_strings_size = 8; listener_strings = (char **)calloc(listener_strings_size, sizeof(char *)); } listener_strings_pos = 0; listener_first_time = true; /* if str matches current history top entry, ignore it (as in tcsh) */ if ((listener_strings[0]) && (mus_strcmp(str, listener_strings[0]))) return; top = listener_strings_size - 1; if (listener_strings[top]) free(listener_strings[top]); for (i = top; i > 0; i--) listener_strings[i] = listener_strings[i - 1]; listener_strings[0] = mus_strdup(str); } static void restore_listener_string(bool back) { if (listener_strings) { char *str; if (!(listener_first_time)) { if (back) listener_strings_pos++; else listener_strings_pos--; } listener_first_time = false; if (listener_strings_pos < 0) listener_strings_pos = 0; if (listener_strings_pos > (listener_strings_size - 1)) listener_strings_pos = listener_strings_size - 1; str = listener_strings[listener_strings_pos]; if (str) append_listener_text(-1, str); } } static bool is_prompt(const char *str, int beg) { int i, j; /* fprintf(stderr, "check %s %s for %d at %d\n", str, ss->Listener_Prompt, ss->listener_prompt_length, beg); */ for (i = beg, j = ss->listener_prompt_length - 1; (i >= 0) && (j >= 0); i--, j--) if (str[i] != ss->Listener_Prompt[j]) { /* fprintf(stderr, "%c != %c at %d\n", str[i], ss->Listener_Prompt[j], j); */ return(false); } if (j != -1) { /* fprintf(stderr, "j: %d\n", j); */ return(false); } if ((i == -1) || (str[i] == '\n')) { /* fprintf(stderr, "found prompt!\n"); */ return(true); } /* fprintf(stderr, "i: %d, str[i]: %c\n", i, str[i]); */ return(false); } static void listener_help_at_cursor(char *buf, int name_curpos, int len, int prompt_pos) { int i, name_start, name_end; if (isspace(buf[name_curpos])) { for (i = name_curpos - 1; i >= 0; i--) if ((!isspace(buf[i])) && (buf[i] != '(') && (buf[i] != ')')) break; if (i > 0) name_curpos = i; } for (i = name_curpos; i >= 0; i--) if ((isspace(buf[i])) || (buf[i] == '(') || (buf[i] == ')')) break; name_start = i + 1; for (i = name_curpos + 1; i < len; i++) if ((isspace(buf[i])) || (buf[i] == '(') || (buf[i] == ')')) break; name_end = i - 1; if (name_end > name_start) { char *new_text; buf[name_end + 1] = '\0'; new_text = direct_completions((char *)(buf + name_start)); if (new_text) { int matches; matches = get_possible_completions_size(); if (matches == 1) { Xen help; help = g_snd_help(C_string_to_Xen_string(new_text), 0); if (Xen_is_string(help)) snd_help((char *)(buf + name_start), Xen_string_to_C_string(help), WITH_WORD_WRAP); } else { if (matches > 1) { char **buffer; char *help_str; int match_len = 0; buffer = get_possible_completions(); for (i = 0; i < matches; i++) match_len += mus_strlen(buffer[i]); help_str = (char *)calloc(match_len + matches * 8, sizeof(char)); for (i = 0; i < matches; i++) { strcat(help_str, buffer[i]); strcat(help_str, "\n"); } snd_help((char *)(buf + name_start), help_str, WITHOUT_WORD_WRAP); free(help_str); } } free(new_text); } } } static bool within_prompt(const char *str, int beg, int end) { /* search backwards up to prompt length for cr (or 0), check for prompt */ int i, lim; if ((beg + 1 == end) && (str[beg] == '\n')) return(false); /* end-of-page cr within double quotes probably */ lim = beg - ss->listener_prompt_length; if (lim < 0) return(true); for (i = beg; i >= lim; i--) if ((str[i] == '\n') || (i == 0)) { int j, k; for (j = 0, k = i + 1; (j < ss->listener_prompt_length) && (k < end); j++, k++) if (str[k] != ss->Listener_Prompt[j]) return(false); return(true); } return(false); } static char *trim(char *orig) { int i, j, start = -1, end = -1, len; char *str; len = mus_strlen(orig); if (len == 0) return(NULL); for (start = 0; start < len; start++) if ((!isspace(orig[start])) && (orig[start] != '(') && (orig[start] != ')')) break; if (start >= len) return(NULL); for (end = len - 1; end > start; end--) if ((!isspace(orig[end])) && (orig[end] != '(') && (orig[end] != ')')) break; if (start == end) return(NULL); len = end - start + 1; str = (char *)calloc(len + 1, sizeof(char)); for (i = start, j = 0; i <= end; i++, j++) str[j] = orig[i]; return(str); } static int find_matching_paren(const char *str, int parens, int pos, int *highlight_pos) { int i, j; bool quoting = false; int up_comment = -1; for (i = pos - 1; i > 0;) { if (is_prompt(str, i)) break; if (str[i] == '\"') { /* there could be any number of slashified slashes before this quote. */ int k, slashes = 0; for (k = i - 1; k >= 0; k--) { if (str[k] == '\\') slashes++; else break; } if ((slashes & 1) == 0) quoting = !quoting; } if (!quoting) { if ((i <= 1) || (str[i - 1] != '\\') || (str[i - 2] != '#')) { if (str[i] == ')') parens++; else if (str[i] == '(') parens--; else if (str[i] == '\n') { /* check for comment on next line up */ bool up_quoting = false; int quote_comment = -1; for (j = i - 1; j > 0; j--) { if (str[j] == '\n') break; if ((str[j] == '\"') && (str[j - 1] != '\\')) up_quoting = !up_quoting; if ((str[j] == ';') && ((j <= 1) || (str[j - 1] != '\\') || (str[j - 2] != '#'))) { if (!up_quoting) up_comment = j; else quote_comment = j; } } if (up_comment < i) { if (up_comment > 0) i = up_comment; else { if ((up_quoting) && (quote_comment > 0)) i = quote_comment; } } } } } if (parens == 0) { (*highlight_pos) = i; break; } i--; } return(parens); } #if (!HAVE_RUBY) && (!HAVE_FORTH) static bool highlight_unbalanced_paren(void); static int check_balance(const char *expr, int start, int end, bool in_listener) { int i; bool not_whitespace = false; int paren_count = 0; bool prev_separator = true; bool quote_wait = false; i = start; while (i < end) { switch (expr[i]) { case ';' : /* skip till newline. */ do { i++; } while ((expr[i] != '\n') && (i < end)); break; case ' ': case '\n': case '\t': case '\r': if ((not_whitespace) && (paren_count == 0) && (!quote_wait)) return(i); else { prev_separator = true; i++; } break; case '\"' : if ((not_whitespace) && (paren_count == 0) && (!quote_wait)) return(i); else { /* skip past ", ignoring \", some cases: * "\"\"" '("\"\"") "\\" "#\\(" "'(\"#\\\")" */ while (i < end) { i++; if (expr[i] == '\\') i++; else { if (expr[i] == '\"') break; } } i++; if (paren_count == 0) { if (i < end) return(i); else return(0); } else { prev_separator = true; not_whitespace = true; quote_wait = false; } } break; case '#': if ((i < end - 1) && (expr[i + 1] == '|')) { /* (+ #| a comment |# 2 1) */ i++; do { i++; } while (((expr[i] != '|') || (expr[i + 1] != '#')) && (i < end)); i++; break; } else { /* (set! *#readers* (cons (cons #\c (lambda (str) (apply make-rectangular (read)))) *#readers*)) */ if ((not_whitespace) && (paren_count == 0) && (!quote_wait)) return(i); else { bool found_it = false; if (prev_separator) { int k, incr = 0; for (k = i + 1; k < end; k++) { if (expr[k] == '(') { /* should we look at the readers here? I want to support #c(1 2) for example */ not_whitespace = false; prev_separator = false; incr = k - i; break; } else { if ((!isdigit(expr[k])) && /* #2d(...)? */ (!isalpha(expr[k])) && /* #c(1 2)? */ (expr[k] != 'D') && (expr[k] != 'd') && (expr[k] != '=') && /* what is this for? */ (expr[k] != '#')) /* perhaps #1d(#(1 2) 3) ? */ break; } } if (incr > 0) { i += incr; found_it = true; } } if (!found_it) { if ((i + 2 < end) && (expr[i + 1] == '\\') && ((expr[i + 2] == ')') || (expr[i + 2] == ';') || (expr[i + 2] == '\"') || (expr[i + 2] == '('))) i += 3; else { prev_separator = false; quote_wait = false; not_whitespace = true; i++; } } } } break; case '(' : if ((not_whitespace) && (paren_count == 0) && (!quote_wait)) return(i - 1); /* 'a(...) -- ignore the (...) */ else { i++; paren_count++; not_whitespace = true; prev_separator = true; quote_wait = false; } break; case ')' : paren_count--; if ((not_whitespace) && (paren_count == 0)) return(i + 1); else { i++; not_whitespace = true; prev_separator = true; quote_wait = false; } break; case '\'' : case '`' : /* `(1 2) */ if (prev_separator) quote_wait = true; not_whitespace = true; i++; break; case ',': /* `,(+ 1 2) */ case '@': /* `,@(list 1 2) */ prev_separator = false; not_whitespace = true; i++; break; default: prev_separator = false; quote_wait = false; not_whitespace = true; i++; break; } } if ((in_listener) && (!(highlight_unbalanced_paren()))) return(-1); return(0); } #endif static char listener_prompt_buffer[LABEL_BUFFER_SIZE]; static char *listener_prompt_with_cr(void) { snprintf(listener_prompt_buffer, LABEL_BUFFER_SIZE, "\n%s", listener_prompt(ss)); return(listener_prompt_buffer); } #define GUI_TEXT_END(w) XmTextGetLastPosition(w) #define GUI_TEXT_POSITION_TYPE XmTextPosition #define GUI_TEXT(w) XmTextGetString(w) #define GUI_TEXT_INSERTION_POSITION(w) XmTextGetInsertionPosition(w) #define GUI_TEXT_SET_INSERTION_POSITION(w, pos) XmTextSetInsertionPosition(w, pos) #define GUI_LISTENER_TEXT_INSERT(w, pos, text) XmTextInsert(w, pos, text) #define GUI_FREE(w) XtFree(w) #define GUI_SET_CURSOR(w, cursor) XUndefineCursor(XtDisplay(w), XtWindow(w)); XDefineCursor(XtDisplay(w), XtWindow(w), cursor) #define GUI_UNSET_CURSOR(w, cursor) XUndefineCursor(XtDisplay(w), XtWindow(w)); XDefineCursor(XtDisplay(w), XtWindow(w), None) #define GUI_UPDATE(w) XmUpdateDisplay(w) #define GUI_TEXT_GOTO(w, pos) XmTextShowPosition(w, pos) static int current_listener_position = -1, listener_positions_size = 0; static int *listener_positions = NULL; static void add_listener_position(int pos) { if (listener_positions_size == 0) { listener_positions_size = 32; listener_positions = (int *)calloc(listener_positions_size, sizeof(int)); current_listener_position = 0; } else { int i; if (pos > listener_positions[current_listener_position]) { current_listener_position++; if (current_listener_position >= listener_positions_size) { listener_positions_size += 32; listener_positions = (int *)realloc(listener_positions, listener_positions_size * sizeof(int)); for (i = current_listener_position + 1; i < listener_positions_size; i++) listener_positions[i] = 0; } } else { for (i = current_listener_position - 1; i >= 0; i--) if (listener_positions[i] < pos) break; current_listener_position = i + 1; } } listener_positions[current_listener_position] = pos; } static void backup_listener_to_previous_expression(void) { if (current_listener_position > 0) { current_listener_position--; listener_delete_text(listener_positions[current_listener_position]); } } #if HAVE_SCHEME static s7_pointer top_level_let = NULL; static s7_pointer g_top_level_let(s7_scheme *sc, s7_pointer args) { return(top_level_let); } static s7_pointer g_set_top_level_let(s7_scheme *sc, s7_pointer args) { top_level_let = s7_car(args); return(top_level_let); } #endif static void listener_return(widget_t w, int last_prompt) { #if (!USE_NO_GUI) /* try to find complete form either enclosing current cursor, or just before it */ GUI_TEXT_POSITION_TYPE cmd_eot = 0; char *str = NULL, *full_str = NULL; int i, j; Xen form = Xen_undefined; GUI_TEXT_POSITION_TYPE last_position = 0, current_position = 0; #if (!HAVE_RUBY && !HAVE_FORTH) GUI_TEXT_POSITION_TYPE end_of_text = 0, start_of_text = 0; int parens; #if USE_MOTIF GUI_TEXT_POSITION_TYPE new_eot = 0; #endif #endif full_str = GUI_TEXT(w); current_position = GUI_TEXT_INSERTION_POSITION(w); #if (!HAVE_RUBY && !HAVE_FORTH) start_of_text = current_position; end_of_text = current_position; #endif last_position = GUI_TEXT_END(w); add_listener_position(last_position); #if (!HAVE_SCHEME) if (have_read_hook()) { Xen result; int len; len = last_position - last_prompt; if (len > 0) { str = (char *)calloc(len + 1, sizeof(char)); for (i = last_prompt, j = 0; i < last_position; i++, j++) str[j] = full_str[i]; result = run_read_hook(str); free(str); if (Xen_is_true(result)) { if (full_str) GUI_FREE(full_str); return; } } } #endif /* prompt = listener_prompt(ss); */ /* first look for a form just before the current mouse location, * independent of everything (i.e. user may have made changes * in a form included in a comment, then typed return, expecting * us to use the new version, but the check_balance procedure * tries to ignore comments). */ str = NULL; #if HAVE_RUBY || HAVE_FORTH { int k, len, start, full_len; for (i = current_position - 1; i >= 0; i--) if (is_prompt(full_str, i)) { full_len = strlen(full_str); for (k = current_position - 1; k < full_len; k++) if (full_str[k] == '\n') break; start = i + 1; len = (k - start + 1); str = (char *)calloc(len, sizeof(char)); for (k = 0; k < len - 1; k++) str[k] = full_str[k + start]; break; } } #else if (last_position > end_of_text) { end_of_text = last_position; /* added 12-Nov-07 for first form */ for (i = current_position; i < last_position; i++) if (is_prompt(full_str, i + 1)) { /* fprintf(stderr, "set end to %d (%d)\n", i - ss->listener_prompt_length + 1, i); */ end_of_text = i - ss->listener_prompt_length + 1; break; } } if (start_of_text > 0) { for (i = end_of_text; i >= 0; i--) if (is_prompt(full_str, i)) { /* fprintf(stderr, "set start to %d\n", i + 1); */ start_of_text = i + 1; break; } } /* fprintf(stderr, "found %d %d\n", start_of_text, end_of_text); */ if (end_of_text > start_of_text) { int slen; parens = 0; slen = end_of_text - start_of_text + 2; str = (char *)calloc(slen, sizeof(char)); for (i = start_of_text, j = 0; i <= end_of_text; j++, i++) { str[j] = full_str[i]; if (str[j] == '(') parens++; } str[end_of_text - start_of_text + 1] = 0; end_of_text = mus_strlen(str); if (parens) { end_of_text = check_balance(str, 0, (int)end_of_text, true); /* last-arg->we are in the listener */ if ((end_of_text > 0) && (end_of_text < slen)) { if (end_of_text < (slen - 1)) str[end_of_text + 1] = 0; else str[end_of_text] = 0; if (str[end_of_text] == '\n') str[end_of_text] = 0; } else { free(str); str = NULL; if (end_of_text < 0) listener_append_and_prompt(NULL); else { #if USE_MOTIF new_eot = GUI_TEXT_END(w); GUI_LISTENER_TEXT_INSERT(w, new_eot, (char *)"\n"); #else GUI_LISTENER_TEXT_INSERT(w, 0, (char *)"\n"); #endif } if (full_str) GUI_FREE(full_str); return; } } else { /* no parens -- pick up closest entity */ int loc, k, len; char *tmp; loc = current_position - start_of_text - 1; for (i = loc; i >= 0; i--) if ((str[i] == '\n') || (i == 0)) { len = mus_strlen(str); tmp = (char *)calloc(len + 1, sizeof(char)); if (i != 0) i++; for (k = 0; i < len; i++, k++) if ((i > loc) && ((str[i] == '\n') || (str[i] == ' '))) break; else tmp[k] = str[i]; free(str); str = tmp; break; } } } #endif if (full_str) GUI_FREE(full_str); { bool need_eval = false; int i, len; /* fprintf(stderr, "return: %s\n", str); */ len = mus_strlen(str); for (i = 0; i < len; i++) if ((str[i] != ' ') && (str[i] != '\n') && (str[i] != '\r') && (str[i] != '\t')) { need_eval = true; break; } if (!need_eval) append_listener_text(-1, "\n"); else { if (str) { char *errmsg = NULL; if (current_position < (last_position - 2)) GUI_LISTENER_TEXT_INSERT(w, GUI_TEXT_END(w), str); GUI_SET_CURSOR(w, ss->wait_cursor); GUI_UPDATE(w); /* not sure about this... */ if ((mus_strlen(str) > 1) || (str[0] != '\n')) remember_listener_string(str); #if HAVE_RUBY || HAVE_FORTH form = Xen_eval_C_string(str); #endif #if HAVE_SCHEME /* very tricky -- we need the interface running to see C-g, and in ordinary (not-hung, but very slow-to-compute) code * we need to let other interface stuff run. We can't look at each event and flush all but the C-g we're waiting * for because that confuses the rest of the GUI, and some such interactions are expected. But if interface actions * are tied to scheme code, the check_for_event lets that code be evaluated, even though we're actually running * the evaluator already in a separate thread. If we block on the thread ID (pthread_self), bad stuff still gets * through somehow. * * s7 threads here only solves the s7 side of the problem. To make the Gtk calls thread-safe, * we have to use gdk threads, and that means either wrapping every gtk section thoughout Snd in * gdk_thread_enter/leave, or expecting the caller to do that in every expression he types in the listener. * * Using clone_s7 code in s7 for CL-like stack-groups is much trickier * than I thought -- it's basically importing all the pthread GC and alloc stuff into the main s7. * * So... set begin_hook to a func that calls gtk_main_iteration or check_for_event; * if C-g, the begin_hook func returns true, and s7 calls s7_quit, and C_g_typed is true here. * Otherwise, I think anything is safe because we're only looking at the block start, and * we're protected there by a stack barrier. * * But this polling at block starts is expensive, mainly because XtAppPending and gtk_events_pending * are very slow. So with_interrupts can turn off this check. */ if (s7_begin_hook(s7) != NULL) return; /* s7 is already running (user typed during computation) */ if ((mus_strlen(str) > 1) || (str[0] != '\n')) { int gc_loc; s7_pointer old_port; old_port = s7_set_current_error_port(s7, s7_open_output_string(s7)); gc_loc = s7_gc_protect(s7, old_port); if (with_interrupts(ss)) s7_set_begin_hook(s7, listener_begin_hook); if (have_read_hook()) form = run_read_hook(str); else form = s7_eval_c_string_with_environment(s7, str, top_level_let); s7_set_begin_hook(s7, NULL); if (ss->C_g_typed) { errmsg = mus_strdup("\nSnd interrupted!"); ss->C_g_typed = false; } else errmsg = mus_strdup(s7_get_output_string(s7, s7_current_error_port(s7))); s7_close_output_port(s7, s7_current_error_port(s7)); s7_set_current_error_port(s7, old_port); s7_gc_unprotect_at(s7, gc_loc); } #endif if (errmsg) { if (*errmsg) snd_display_result(errmsg, NULL); free(errmsg); } else snd_report_listener_result(form); /* used to check for unbound form here, but that's no good in Ruby */ free(str); str = NULL; GUI_UNSET_CURSOR(w, ss->arrow_cursor); } else { listener_append_and_prompt(NULL); } } } cmd_eot = GUI_TEXT_END(w); add_listener_position(cmd_eot); GUI_TEXT_GOTO(w, cmd_eot - 1); GUI_TEXT_SET_INSERTION_POSITION(w, cmd_eot + 1); #endif } /* -------------------------------------------------------------------------------- */ #define OVERRIDE_TOGGLE 1 /* Motif 2.0 defines control-button1 to be "take focus" -- this is not a good idea!! */ static void Tab_completion(Widget w, XEvent *event, char **str, Cardinal *num) { int completer; pointer_or_int_t data; XtVaGetValues(w, XmNuserData, &data, NULL); completer = (int)data; if (completer >= 0) { int matches; char *old_text, *new_text; old_text = XmTextGetString(w); if (mus_strlen(old_text) == 0) return; /* C-x C-f TAB in kbd??, for example */ new_text = complete_text(w, old_text, completer); if (mus_strlen(new_text) == 0) return; /* can this happen? */ XmTextSetString(w, new_text); XmTextSetCursorPosition(w, XmTextGetLastPosition(w)); matches = get_completion_matches(); if ((mus_strcmp(old_text, new_text)) && (matches != -1)) { Pixel old_color; XtVaGetValues(w, XmNforeground, &old_color, NULL); if (matches > 1) XtVaSetValues(w, XmNforeground, ss->green, NULL); else if (matches == 0) XtVaSetValues(w, XmNforeground, ss->red, NULL); if (matches != 1) { XmUpdateDisplay(w); sleep(1); XtVaSetValues(w, XmNforeground, old_color, NULL); XmUpdateDisplay(w); } if (matches > 1) /* there are several possible completions -- let the widget decide how to handle it */ handle_completions(w, completer); } if (old_text) XtFree(old_text); if (new_text) free(new_text); } } /* listener completions */ static Widget listener_text = NULL; static Widget listener_pane = NULL; /* form widget that hold the listener scrolled text widget */ static Widget completions_list = NULL; static Widget completions_pane = NULL; static void perform_completion(XmString selection) { int i, j, old_len, new_len; char *text = NULL, *old_text = NULL; text = (char *)XmStringUnparse(selection, NULL, XmCHARSET_TEXT, XmCHARSET_TEXT, NULL, 0, XmOUTPUT_ALL); save_completion_choice(text); old_text = XmTextGetString(listener_text); old_len = mus_strlen(old_text); new_len = mus_strlen(text); for (i = old_len - 1, j = new_len - 1; j >= 0; j--) { if (old_text[i] != text[j]) { i = old_len - 1; if (old_text[i] == text[j]) i--; /* this added 15-Apr-02 for case like map-chan(nel) */ /* probably should go back new_len and scan forwards instead */ } else i--; } append_listener_text(XmTextGetLastPosition(listener_text), (char *)(text - 1 + old_len - i)); if (text) XtFree(text); if (old_text) XtFree(old_text); } static void listener_completions_browse_callback(Widget w, XtPointer context, XtPointer info) { XmListCallbackStruct *cbs = (XmListCallbackStruct *)info; /* choice = cbs->item_position - 1; */ perform_completion(cbs->item); XtUnmanageChild(completions_pane); } static int alphabetize(const void *a, const void *b) { return(strcmp(*((const char **)a), (*(const char **)b))); } static int find_prompt(Widget w, XmTextPosition start) { Boolean found_prompt = false, found_newline; XmTextPosition loc = 0; if (start == 0) /* try to avoid strlen null in motif */ return(0); /* the prompt defaults to ">", so a naive backwards search for the prompt is easily confused. * (bugfix thanks to Tito Latini). */ while (!found_prompt) { found_newline = XmTextFindString(w, start, (char *)"\n", XmTEXT_BACKWARD, &loc); start = found_newline ? loc : 0; found_prompt = XmTextFindString(w, start, listener_prompt(ss), XmTEXT_FORWARD, &loc); if ((found_prompt && loc <= (start + 1)) || (start == 0)) break; start--; } if (!found_prompt) return(0); else return((int)loc + mus_strlen(listener_prompt(ss))); } static void motif_listener_completion(Widget w, XEvent *event, char **str, Cardinal *num) /* change name because emacs is confused */ { /* used only by the listener widget -- needs to be smart about text since overall string can be enormous * and we don't want to back up past the last prompt * also if at start of line (or all white-space to previous \n), indent */ int beg, end, replace_end, len; char *old_text; if ((completions_pane) && (XtIsManaged(completions_pane))) { XmString *strs; XtVaGetValues(completions_list, XmNselectedItems, &strs, NULL); perform_completion(strs[0]); XtUnmanageChild(completions_pane); return; } end = XmTextGetInsertionPosition(w); replace_end = end; beg = find_prompt(w, (XmTextPosition)end); len = end - beg + 1; old_text = (char *)calloc(len + 1, sizeof(char)); XmTextGetSubstring(w, beg, len, len + 1, old_text); /* now old_text is the stuff typed since the last prompt */ if (old_text[len - 1] == '\n') { old_text[len - 1] = 0; end--; } if (old_text) { int matches = 0; char *new_text = NULL, *file_text = NULL; bool try_completion = true; new_text = complete_listener_text(old_text, end, &try_completion, &file_text); if (!try_completion) { free(old_text); return; } if (mus_strcmp(old_text, new_text)) matches = get_completion_matches(); else XmTextReplace(w, beg, replace_end, new_text); if (new_text) { free(new_text); new_text = NULL; } if (matches > 1) { int num; clear_possible_completions(); set_save_completions(true); if (file_text) new_text = filename_completer(w, file_text, NULL); else new_text = expression_completer(w, old_text, NULL); if (new_text) { free(new_text); new_text = NULL; } num = get_possible_completions_size(); if (num > 0) { int i; XmString *match; char **buffer; if (!completions_list) { Arg args[20]; int n = 0; XtSetArg(args[n], XmNleftAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNscrollBarPlacement, XmBOTTOM_LEFT); n++; XtSetArg(args[n], XmNbackground, ss->white); n++; XtSetArg(args[n], XmNforeground, ss->black); n++; XtSetArg(args[n], XmNselectColor, ss->selection_color); n++; completions_list = XmCreateScrolledList(listener_pane, (char *)"completion-help-text", args, n); completions_pane = XtParent(completions_list); XtAddCallback(completions_list, XmNbrowseSelectionCallback, listener_completions_browse_callback, NULL); XtManageChild(completions_list); } buffer = get_possible_completions(); qsort((void *)buffer, num, sizeof(char *), alphabetize); match = (XmString *)calloc(num, sizeof(XmString)); for (i = 0; i < num; i++) match[i] = XmStringCreateLocalized(buffer[i]); XtVaSetValues(completions_list, XmNitems, match, XmNitemCount, num, XmNvisibleItemCount, mus_iclamp(1, num, 20), NULL); if (!(XtIsManaged(completions_pane))) XtManageChild(completions_pane); /* look at previous completions list first for a match, then * look back from "beg" for any member of the match list previously typed */ { int row; row = find_best_completion(buffer, num); XmListSelectPos(completions_list, row, false); ensure_list_row_visible(completions_list, row); } for (i = 0; i < num; i++) XmStringFree(match[i]); free(match); } set_save_completions(false); } if (file_text) free(file_text); if (old_text) free(old_text); } } /* ---------------- text widget specializations ---------------- */ void textfield_focus_callback(Widget w, XtPointer context, XtPointer info) { XtVaSetValues(w, XmNbackground, ss->text_focus_color, NULL); XtVaSetValues(w, XmNcursorPositionVisible, true, NULL); } void textfield_unfocus_callback(Widget w, XtPointer context, XtPointer info) { XtVaSetValues(w, XmNbackground, ss->basic_color, NULL); XtVaSetValues(w, XmNcursorPositionVisible, false, NULL); } static void textfield_no_color_focus_callback(Widget w, XtPointer context, XtPointer info) { XtVaSetValues(w, XmNcursorPositionVisible, true, NULL); } static void textfield_no_color_unfocus_callback(Widget w, XtPointer context, XtPointer info) { XtVaSetValues(w, XmNcursorPositionVisible, false, NULL); } /* -------- specialized action procs -------- */ static bool actions_loaded = false; #define CONTROL_KEY 4 static void No_op(Widget w, XEvent *ev, char **str, Cardinal *num) { /* return does not cause widget activation in many textfield cases -- it is a true no-op */ } #define snd_K_u XK_u #define snd_K_x XK_x static void Activate_keyboard(Widget w, XEvent *ev, char **str, Cardinal *num) { /* make the current channel active preloading kbd cmd with str[0]+ctrl bit */ chan_info *cp; cp = current_channel(); if (cp) { goto_graph(cp); keyboard_command(cp, (str[0][0] == 'u') ? snd_K_u : snd_K_x, CONTROL_KEY); } } static char *listener_selection = NULL; static void Kill_line(Widget w, XEvent *ev, char **str, Cardinal *num) { /* C-k with storage of killed text */ XmTextPosition curpos, loc; Boolean found; curpos = XmTextGetCursorPosition(w); found = XmTextFindString(w, curpos, (char *)"\n", XmTEXT_FORWARD, &loc); if (!found) loc = XmTextGetLastPosition(w); if (loc > curpos) { if (listener_selection) {XtFree(listener_selection); listener_selection = NULL;} XmTextSetSelection(w, curpos, loc, CurrentTime); listener_selection = XmTextGetSelection(w); /* xm manual p329 sez storage is allocated here */ XmTextCut(w, CurrentTime); } } static void Yank(Widget w, XEvent *ev, char **str, Cardinal *num) { /* copy current selection at current cursor position */ if (listener_selection) { XmTextPosition curpos; curpos = XmTextGetCursorPosition(w); XmTextInsert(w, curpos, listener_selection); curpos += strlen(listener_selection); XmTextShowPosition(w, curpos); XmTextSetCursorPosition(w, curpos); XmTextClearSelection(w, ev->xkey.time); /* so C-y + edit doesn't forbid the edit */ } } static void Begin_of_line(Widget w, XEvent *ev, char **ustr, Cardinal *num) { /* don't back up before listener prompt */ XmTextPosition curpos, loc; Boolean found; curpos = XmTextGetCursorPosition(w) - 1; found = XmTextFindString(w, curpos, (char *)"\n", XmTEXT_BACKWARD, &loc); if (curpos >= ss->listener_prompt_length - 1) { char *str = NULL; str = (char *)calloc(ss->listener_prompt_length + 3, sizeof(char)); loc = found ? loc + 1 : 0; XmTextGetSubstring(w, loc, ss->listener_prompt_length, ss->listener_prompt_length + 2, str); if (strncmp(listener_prompt(ss), str, ss->listener_prompt_length) == 0) XmTextSetCursorPosition(w, loc + ss->listener_prompt_length); else XmTextSetCursorPosition(w, loc); free(str); } else XmTextSetCursorPosition(w, 0); } static void Delete_region(Widget w, XEvent *ev, char **str, Cardinal *num) { XmTextCut(w, CurrentTime); } static XmTextPosition down_pos, last_pos; static Xen listener_click_hook; static void B1_press(Widget w, XEvent *event, char **str, Cardinal *num) { XmTextPosition pos; XButtonEvent *ev = (XButtonEvent *)event; XmProcessTraversal(w, XmTRAVERSE_CURRENT); /* we're replacing the built-in take_focus action here, so do it by hand, but leave listener blue, so to speak */ if (w != listener_text) XtVaSetValues(w, XmNbackground, ss->white, NULL); else XmTextClearSelection(listener_text, CurrentTime); /* should this happen in other windows as well? */ pos = XmTextXYToPos(w, (Position)(ev->x), (Position)(ev->y)); XmTextSetCursorPosition(w, pos); down_pos = pos; last_pos = pos; if (Xen_hook_has_list(listener_click_hook)) run_hook(listener_click_hook, Xen_list_1(C_int_to_Xen_integer((int)pos)), S_listener_click_hook); } static void B1_move(Widget w, XEvent *event, char **str, Cardinal *num) { XmTextPosition pos; XButtonEvent *ev = (XButtonEvent *)event; pos = XmTextXYToPos(w, (Position)(ev->x), (Position)(ev->y)); if (last_pos > pos) /* must have backed up the cursor */ XmTextSetHighlight(w, pos, last_pos, XmHIGHLIGHT_NORMAL); if (down_pos != pos) XmTextSetHighlight(w, down_pos, pos, XmHIGHLIGHT_SELECTED); last_pos = pos; } static void B1_release(Widget w, XEvent *event, char **str, Cardinal *num) { XmTextPosition pos; XButtonEvent *ev = (XButtonEvent *)event; pos = XmTextXYToPos(w, (Position)(ev->x), (Position)(ev->y)); XmTextSetCursorPosition(w, pos); if (down_pos != pos) { XmTextSetHighlight(w, down_pos, pos, XmHIGHLIGHT_SELECTED); if (listener_selection) {XtFree(listener_selection); listener_selection = NULL;} XmTextSetSelection(w, down_pos, pos, CurrentTime); listener_selection = XmTextGetSelection(w); } } static void Text_transpose(Widget w, XEvent *event, char **str, Cardinal *num) { XmTextPosition curpos; curpos = XmTextGetCursorPosition(w); if (curpos > 1) { char buf[3]; /* needs room for null */ char tmp; XmTextGetSubstring(w, (XmTextPosition)(curpos - 1), 2, 3, buf); tmp = buf[0]; buf[0] = buf[1]; buf[1] = tmp; XmTextReplace(w, curpos - 1, curpos + 1, buf); XmTextSetCursorPosition(w, curpos + 1); } } static void Complain(Widget w, XEvent *event, char **str, Cardinal *num) { char *old_text, *new_text; XmTextPosition curpos; int len; curpos = XmTextGetCursorPosition(w); old_text = XmTextGetString(w); len = mus_strlen(old_text) + 5; new_text = (char *)calloc(len, sizeof(char)); snprintf(new_text, len, "%s C-%c", (old_text) ? old_text : "", str[0][0]); XmTextSetString(w, new_text); XmTextSetCursorPosition(w, curpos); if (old_text) XtFree(old_text); free(new_text); } static void text_at_cursor(Widget w) { XmTextPosition curpos, endpos, start, end; int len, prompt_pos; char *buf; curpos = XmTextGetCursorPosition(w); if (curpos <= 1) curpos = XmTextGetInsertionPosition(w); if (curpos <= 1) { snd_help("Listener", "This is the 'listener', a text widget in which you can interact with Snd's extension language. See extsnd.html.", WITH_WORD_WRAP); return; } prompt_pos = find_prompt(w, curpos); if (curpos > 40) start = curpos - 40; else start = 0; if (start < prompt_pos) start = prompt_pos; endpos = XmTextGetLastPosition(w); if ((endpos - curpos) > 40) end = curpos + 40; else end = endpos; len = end - start + 1; buf = (char *)calloc(len + 1, sizeof(char)); XmTextGetSubstring(w, start, len, len + 1, buf); listener_help_at_cursor(buf, curpos - start - 1, len, prompt_pos); free(buf); } static void Help_At_Cursor(Widget w, XEvent *ev, char **str, Cardinal *num) { text_at_cursor(w); } static void Word_upper(Widget w, XEvent *event, char **str, Cardinal *num) { bool up, cap; XmTextPosition curpos, endpos; up = (str[0][0] == 'u'); cap = (str[0][0] == 'c'); curpos = XmTextGetCursorPosition(w); endpos = XmTextGetLastPosition(w); if (curpos < endpos) { int i, length, wstart, wend; char *buf = NULL; length = endpos - curpos; buf = (char *)calloc(length + 1, sizeof(char)); XmTextGetSubstring(w, curpos, length, length + 1, buf); wstart = 0; wend = length; for (i = 0; i < length; i++) if (!isspace((int)(buf[i]))) { wstart = i; break; } for (i = wstart + 1; i < length; i++) if (isspace((int)(buf[i]))) { wend = i; break; } if (cap) { buf[0] = toupper(buf[wstart]); buf[1] = '\0'; XmTextReplace(w, curpos + wstart, curpos + wstart + 1, buf); } else { int j; for (i = wstart, j = 0; i < wend; i++, j++) if (up) buf[j] = toupper(buf[i]); else buf[j] = tolower(buf[i]); buf[j] = '\0'; XmTextReplace(w, curpos + wstart, curpos + wend, buf); } XmTextSetCursorPosition(w, curpos + wend); if (buf) free(buf); } } void append_listener_text(int end, const char *msg) { if (listener_text) { if (end == -1) end = XmTextGetLastPosition(listener_text); XmTextInsert(listener_text, end, (char *)msg); XmTextSetCursorPosition(listener_text, XmTextGetLastPosition(listener_text)); } } static bool dont_check_motion = false; void listener_delete_text(int new_end) { int old_end; old_end = XmTextGetLastPosition(listener_text); if (old_end > new_end) { dont_check_motion = true; XmTextSetSelection(listener_text, new_end, old_end, CurrentTime); XmTextRemove(listener_text); dont_check_motion = false; } } static void Listener_Meta_P(Widget w, XEvent *event, char **str, Cardinal *num) { listener_delete_text(find_prompt(w, XmTextGetInsertionPosition(w))); restore_listener_string(true); } static void Listener_Meta_N(Widget w, XEvent *event, char **str, Cardinal *num) { listener_delete_text(find_prompt(w, XmTextGetInsertionPosition(w))); restore_listener_string(false); } int save_listener_text(FILE *fp) { /* return -1 if fwrite problem */ if (listener_text) { char *str = NULL; str = XmTextGetString(listener_text); if (str) { size_t bytes; bytes = fwrite((void *)str, sizeof(char), mus_strlen(str), fp); XtFree(str); if (bytes == 0) return(-1); } } return(0); } static void Listener_clear(Widget w, XEvent *event, char **str, Cardinal *num) { clear_listener(); } static void Listener_g(Widget w, XEvent *event, char **str, Cardinal *num) { ss->C_g_typed = true; control_g(any_selected_sound()); } static void Listener_Backup(Widget w, XEvent *event, char **str, Cardinal *num) { backup_listener_to_previous_expression(); } static void Listener_Arrow_Up(Widget w, XEvent *event, char **str, Cardinal *num) { if ((completions_pane) && (XtIsManaged(completions_pane))) { int *ns; int n; XmListGetSelectedPos(completions_list, &ns, &n); if (ns[0] > 1) XmListSelectPos(completions_list, ns[0] - 1, false); free(ns); } else XtCallActionProc(w, "previous-line", event, str, *num); } static void Listener_Arrow_Down(Widget w, XEvent *event, char **str, Cardinal *num) { if ((completions_pane) && (XtIsManaged(completions_pane))) { int *ns; int n; XmListGetSelectedPos(completions_list, &ns, &n); XmListSelectPos(completions_list, ns[0] + 1, false); free(ns); } else XtCallActionProc(w, "next-line", event, str, *num); } static void Listener_Return(Widget w, XEvent *event, char **str, Cardinal *num) { if ((completions_pane) && (XtIsManaged(completions_pane))) { XmString *strs; XtVaGetValues(completions_list, XmNselectedItems, &strs, NULL); perform_completion(strs[0]); XtUnmanageChild(completions_pane); } else XtCallActionProc(w, "activate", event, str, *num); } #define NUM_ACTS 24 static XtActionsRec acts[NUM_ACTS] = { {(char *)"no-op", No_op}, {(char *)"activate-keyboard", Activate_keyboard}, {(char *)"yank", Yank}, {(char *)"delete-region", Delete_region}, {(char *)"kill-line", Kill_line}, {(char *)"begin-of-line", Begin_of_line}, {(char *)"b1-press", B1_press}, {(char *)"b1-move", B1_move}, {(char *)"b1-release", B1_release}, {(char *)"text-transpose", Text_transpose}, {(char *)"word-upper", Word_upper}, {(char *)"tab-completion", Tab_completion}, {(char *)"listener-completion", motif_listener_completion}, {(char *)"listener-clear", Listener_clear}, {(char *)"listener-g", Listener_g}, {(char *)"listener-meta-p", Listener_Meta_P}, {(char *)"listener-meta-n", Listener_Meta_N}, {(char *)"listener-next-line", Listener_Arrow_Down}, {(char *)"listener-previous-line", Listener_Arrow_Up}, {(char *)"listener-return", Listener_Return}, {(char *)"delete-to-previous-command", Listener_Backup}, {(char *)"complain", Complain}, {(char *)"help-at-cursor", Help_At_Cursor}, }; /* translation tables for emacs compatibility and better inter-widget communication */ /* these values are listed in lib/Xm/Transltns.c */ /* for textfield (single-line) widgets */ static char TextTrans2[] = "Ctrl a: beginning-of-line()\n\ Ctrl b: backward-character()\n\ Mod1 b: backward-word()\n\ Mod1 c: word-upper(c)\n\ Ctrl c: complain(c)\n\ Ctrl d: delete-next-character()\n\ Mod1 d: delete-next-word()\n\ Ctrl e: end-of-line()\n\ Ctrl f: forward-character()\n\ Mod1 f: forward-word()\n\ Ctrl g: activate()\n\ Ctrl h: delete-previous-character()\n\ Ctrl i: complain(i)\n\ Ctrl j: complain(j)\n\ Ctrl k: delete-to-end-of-line()\n\ Mod1 l: word-upper(l)\n\ Ctrl m: complain(m)\n\ Ctrl n: complain(n)\n\ Mod1 n: activate()\n\ Ctrl o: complain(o)\n\ Mod1 p: activate()\n\ Ctrl p: complain(p)\n\ Ctrl q: complain(q)\n\ Ctrl r: activate()\n\ Ctrl s: activate()\n\ Ctrl t: text-transpose()\n\ Mod1 u: word-upper(u)\n\ Ctrl u: complain(u)\n\ Ctrl v: complain(v)\n\ Ctrl w: complain(w)\n\ Ctrl x: activate-keyboard(x)\n\ Ctrl y: complain(y)\n\ Ctrl z: complain(z)\n\ Mod1 <: beginning-of-line()\n\ Mod1 >: end-of-line()\n\ Delete: delete-previous-character()\n\ Mod1 Delete: delete-to-start-of-line()\n\ Tab: tab-completion()\n\ Return: activate()\n"; static XtTranslations transTable2 = NULL; /* same (but not activatable), try to avoid causing the currently active pushbutton widget to appear to be activated by in the text widget */ static char TextTrans6[] = "Ctrl a: beginning-of-line()\n\ Ctrl b: backward-character()\n\ Mod1 b: backward-word()\n\ Mod1 c: word-upper(c)\n\ Ctrl d: delete-next-character()\n\ Mod1 d: delete-next-word()\n\ Ctrl e: end-of-line()\n\ Ctrl f: forward-character()\n\ Mod1 f: forward-word()\n\ Ctrl g: no-op()\n\ Ctrl h: delete-previous-character()\n\ Ctrl k: delete-to-end-of-line()\n\ Mod1 l: word-upper(l)\n\ Ctrl t: text-transpose()\n\ Mod1 u: word-upper(u)\n\ Mod1 <: beginning-of-line()\n\ Mod1 >: end-of-line()\n\ Delete: delete-previous-character()\n\ Mod1 Delete: delete-to-start-of-line()\n\ Tab: tab-completion()\n\ Return: no-op()\n"; static XtTranslations transTable6 = NULL; /* for text (multi-line) widgets */ static char TextTrans3[] = "Ctrl a: beginning-of-line()\n\ Ctrl b: backward-character()\n\ Mod1 b: backward-word()\n\ Mod1 c: word-upper(c)\n\ Ctrl d: delete-next-character()\n\ Mod1 d: delete-next-word()\n\ Ctrl e: end-of-line()\n\ Ctrl f: forward-character()\n\ Mod1 f: forward-word()\n\ Ctrl g: activate()\n\ Ctrl h: delete-previous-character()\n\ Ctrl j: newline-and-indent()\n\ Ctrl k: kill-line()\n\ Mod1 l: word-upper(l)\n\ Ctrl n: next-line()\n\ Ctrl o: newline-and-backup()\n\ Ctrl p: previous-line()\n\ Ctrl t: text-transpose()\n\ Mod1 u: word-upper(u)\n\ Ctrl v: next-page()\n\ Mod1 v: previous-page()\n\ Ctrl w: delete-region()\n\ Ctrl y: yank()\n\ Ctrl z: activate()\n\ Mod1 [: backward-paragraph()\n\ Mod1 ]: forward-paragraph()\n\ Mod1 <: beginning-of-file()\n\ Mod1 >: end-of-file()\n\ Delete: delete-previous-character()\n\ Mod1 Delete: delete-to-start-of-line()\n\ Ctrl osfLeft: page-left()\n\ Ctrl osfRight: page-right()\n\ Ctrl osfDown: next-page()\n\ Ctrl osfUp: previous-page()\n\ Ctrl space: set-anchor()\n\ : b1-press()\n\ : b1-release()\n\ : b1-move()\n\ Return: newline()\n"; static XtTranslations transTable3 = NULL; /* for lisp listener */ static char TextTrans4[] = "Ctrl a: begin-of-line()\n\ Ctrl b: backward-character()\n\ Mod1 b: backward-word()\n\ Mod1 c: word-upper(c)\n\ Ctrl d: delete-next-character()\n\ Mod1 d: delete-next-word()\n\ Ctrl e: end-of-line()\n\ Ctrl f: forward-character()\n\ Mod1 f: forward-word()\n\ Ctrl Meta g: listener-clear()\n\ Ctrl g: listener-g()\n\ Ctrl h: delete-previous-character()\n\ Ctrl j: newline-and-indent()\n\ Ctrl k: kill-line()\n\ Ctrl l: redraw-display()\n\ Mod1 l: word-upper(l)\n\ Ctrl n: next-line()\n\ Mod1 n: listener-meta-n()\n\ Ctrl o: newline-and-backup()\n\ Ctrl p: previous-line()\n\ Mod1 p: listener-meta-p()\n\ Ctrl t: text-transpose()\n\ Ctrl u: activate-keyboard(u)\n\ Mod1 u: word-upper(u)\n\ Ctrl v: next-page()\n\ Mod1 v: previous-page()\n\ Ctrl w: delete-region()\n\ Ctrl x: activate-keyboard(x)\n\ Ctrl y: yank()\n\ Ctrl z: activate()\n\ Ctrl ?: help-at-cursor()\n\ Mod1 .: help-at-cursor()\n\ Mod1 [: backward-paragraph()\n\ Mod1 ]: forward-paragraph()\n\ Mod1 <: beginning-of-file()\n\ Mod1 >: end-of-file()\n\ Shift Ctrl -: delete-to-previous-command()\n\ Delete: delete-previous-character()\n\ Mod1 Delete: delete-to-start-of-line()\n\ Ctrl osfLeft: page-left()\n\ Ctrl osfRight: page-right()\n\ Ctrl osfDown: next-page()\n\ Ctrl osfUp: previous-page()\n\ osfDown: listener-next-line()\n\ osfUp: listener-previous-line()\n\ Ctrl space: set-anchor()\n\ : b1-press()\n\ : b1-release()\n\ : b1-move()\n\ Tab: listener-completion()\n\ Return: listener-return()\n"; static XtTranslations transTable4 = NULL; void add_completer_to_builtin_textfield(Widget w, int completer) { /* used to make file selection dialog's file and filter text widgets act like other text field widgets */ if (!actions_loaded) { XtAppAddActions(MAIN_APP(ss), acts, NUM_ACTS); actions_loaded = true; } if (!transTable2) transTable2 = XtParseTranslationTable(TextTrans2); XtOverrideTranslations(w, transTable2); XtVaSetValues(w, XmNuserData, completer, NULL); } /* -------- text related widgets -------- */ static Xen mouse_enter_text_hook; static Xen mouse_leave_text_hook; void mouse_enter_text_callback(Widget w, XtPointer context, XEvent *event, Boolean *flag) { if (with_pointer_focus(ss)) goto_window(w); if (Xen_hook_has_list(mouse_enter_text_hook)) run_hook(mouse_enter_text_hook, Xen_list_1(Xen_wrap_widget(w)), S_mouse_enter_text_hook); } void mouse_leave_text_callback(Widget w, XtPointer context, XEvent *event, Boolean *flag) { if (Xen_hook_has_list(mouse_leave_text_hook)) run_hook(mouse_leave_text_hook, Xen_list_1(Xen_wrap_widget(w)), S_mouse_leave_text_hook); } Widget make_textfield_widget(const char *name, Widget parent, Arg *args, int n, text_cr_t activatable, int completer) { /* white background when active, emacs translations */ Widget df; if (!actions_loaded) { XtAppAddActions(MAIN_APP(ss), acts, NUM_ACTS); actions_loaded = true; } XtSetArg(args[n], XmNuserData, completer); n++; XtSetArg(args[n], XmNhighlightThickness, 1); n++; XtSetArg(args[n], XmNcursorPositionVisible, false); n++; df = XtCreateManagedWidget(name, xmTextFieldWidgetClass, parent, args, n); if (activatable != ACTIVATABLE_BUT_NOT_FOCUSED) { XtAddCallback(df, XmNfocusCallback, textfield_focus_callback, NULL); XtAddCallback(df, XmNlosingFocusCallback, textfield_unfocus_callback, NULL); } else { XtAddCallback(df, XmNfocusCallback, textfield_no_color_focus_callback, NULL); XtAddCallback(df, XmNlosingFocusCallback, textfield_no_color_unfocus_callback, NULL); } XtAddEventHandler(df, EnterWindowMask, false, mouse_enter_text_callback, NULL); XtAddEventHandler(df, LeaveWindowMask, false, mouse_leave_text_callback, NULL); if ((activatable == ACTIVATABLE) || (activatable == ACTIVATABLE_BUT_NOT_FOCUSED)) { if (!transTable2) transTable2 = XtParseTranslationTable(TextTrans2); XtOverrideTranslations(df, transTable2); } else { if (!transTable6) transTable6 = XtParseTranslationTable(TextTrans6); XtOverrideTranslations(df, transTable6); } return(df); } Widget make_text_widget(const char *name, Widget parent, Arg *args, int n) { /* white background when active, emacs translations */ /* used only for comment widget in file data box (snd-xfile.c), but needs to be in this file to pick up actions etc */ Widget df; if (!actions_loaded) { XtAppAddActions(MAIN_APP(ss), acts, NUM_ACTS); actions_loaded = true; } XtSetArg(args[n], XmNeditMode, XmMULTI_LINE_EDIT); n++; /* XmNblinkRate 0 turns off the cursor blink */ XtSetArg(args[n], XmNcursorPositionVisible, false); n++; XtSetArg(args[n], XmNhighlightThickness, 1); n++; df = XmCreateScrolledText(parent, (char *)name, args, n); XtManageChild(df); XtAddCallback(df, XmNfocusCallback, textfield_focus_callback, NULL); XtAddCallback(df, XmNlosingFocusCallback, textfield_unfocus_callback, NULL); XtAddEventHandler(df, EnterWindowMask, false, mouse_enter_text_callback, NULL); XtAddEventHandler(df, LeaveWindowMask, false, mouse_leave_text_callback, NULL); if (!transTable3) transTable3 = XtParseTranslationTable(TextTrans3); XtOverrideTranslations(df, transTable3); return(df); } /* ---------------- listener widget ---------------- */ static Widget lisp_window = NULL; void listener_append(const char *msg) { if (listener_text) XmTextInsert(listener_text, XmTextGetLastPosition(listener_text), (char *)msg); } void listener_append_and_prompt(const char *msg) { if (listener_text) { XmTextPosition cmd_eot; if (msg) XmTextInsert(listener_text, XmTextGetLastPosition(listener_text), (char *)msg); cmd_eot = XmTextGetLastPosition(listener_text); XmTextInsert(listener_text, cmd_eot, listener_prompt_with_cr()); cmd_eot = XmTextGetLastPosition(listener_text); XmTextShowPosition(listener_text, cmd_eot - 1); } } static void listener_return_callback(Widget w, XtPointer context, XtPointer info) { listener_return(w, find_prompt(w, XmTextGetInsertionPosition(w))); /* prompt loc (last prompt pos) used only by read hook */ } #if (!HAVE_FORTH) && (!HAVE_RUBY) static int flashes = 0; static int paren_pos = -1; #define FLASH_TIME 150 static void flash_unbalanced_paren(XtPointer context, XtIntervalId *id) { flashes--; XmTextSetHighlight(listener_text, paren_pos, paren_pos + 1, (flashes & 1) ? XmHIGHLIGHT_NORMAL : XmHIGHLIGHT_SELECTED); if (flashes > 0) XtAppAddTimeOut(MAIN_APP(ss), (unsigned long)FLASH_TIME, (XtTimerCallbackProc)flash_unbalanced_paren, NULL); else { XmTextSetHighlight(listener_text, paren_pos, paren_pos + 1, XmHIGHLIGHT_NORMAL); paren_pos = -1; } } static bool highlight_unbalanced_paren(void) { /* if cursor is positioned at close paren, try to find reason for unbalanced expr and highlight it */ int pos; bool success = true; pos = XmTextGetInsertionPosition(listener_text); if (pos > 2) { char *str; str = XmTextGetString(listener_text); if ((str[pos - 1] == ')') && ((str[pos - 2] != '\\') || (str[pos - 3] != '#'))) { int parens; parens = find_matching_paren(str, 2, pos - 1, &paren_pos); if (parens == 0) { XmTextSetHighlight(listener_text, paren_pos, paren_pos + 1, XmHIGHLIGHT_SELECTED); flashes = 4; XtAppAddTimeOut(MAIN_APP(ss), (unsigned long)FLASH_TIME, (XtTimerCallbackProc)flash_unbalanced_paren, NULL); } else success = false; } if (str) XtFree(str); } return(success); } #endif static int last_highlight_position = -1; static void listener_motion_callback(Widget w, XtPointer context, XtPointer info) { XmTextVerifyCallbackStruct *cbs = (XmTextVerifyCallbackStruct *)info; int pos; cbs->doit = true; if (dont_check_motion) return; if (last_highlight_position != -1) { XmTextSetHighlight(w, last_highlight_position, last_highlight_position + 1, XmHIGHLIGHT_NORMAL); last_highlight_position = -1; } pos = cbs->newInsert - 1; if (pos > 0) { char *str = NULL; str = XmTextGetString(w); if ((str[pos] == ')') && ((pos <= 1) || (str[pos - 1] != '\\') || (str[pos - 2] != '#'))) { int parens; parens = find_matching_paren(str, 1, pos, &last_highlight_position); if (parens == 0) XmTextSetHighlight(w, last_highlight_position, last_highlight_position + 1, XmHIGHLIGHT_SECONDARY_SELECTED); } if (str) XtFree(str); } } static void listener_modify_callback(Widget w, XtPointer context, XtPointer info) { XmTextVerifyCallbackStruct *cbs = (XmTextVerifyCallbackStruct *)info; /* pure motion stuff (arrow keys) does not trigger this callback */ if ((completions_pane) && (XtIsManaged(completions_pane))) XtUnmanageChild(completions_pane); if (((cbs->text)->length > 0) || (dont_check_motion)) cbs->doit = true; else { char *str = NULL; int len; str = XmTextGetString(w); len = XmTextGetLastPosition(w); if (within_prompt(str, cbs->startPos, len)) cbs->doit = false; else cbs->doit = true; if (str) XtFree(str); } } static Xen mouse_enter_listener_hook; static Xen mouse_leave_listener_hook; static void listener_focus_callback(Widget w, XtPointer context, XEvent *event, Boolean *flag) { if (with_pointer_focus(ss)) goto_window(listener_text); if (Xen_hook_has_list(mouse_enter_listener_hook)) run_hook(mouse_enter_listener_hook, Xen_list_1(Xen_wrap_widget(listener_text)), /* not w */ S_mouse_enter_listener_hook); } static void listener_unfocus_callback(Widget w, XtPointer context, XEvent *event, Boolean *flag) { if (Xen_hook_has_list(mouse_leave_listener_hook)) run_hook(mouse_leave_listener_hook, Xen_list_1(Xen_wrap_widget(listener_text)), /* not w */ S_mouse_leave_listener_hook); } /* ---------------- popup callbacks ---------------- */ static Widget listener_popup = NULL; static void listener_help_callback(Widget w, XtPointer context, XtPointer info) { char *txt; txt = XmTextGetSelection(listener_text); if (txt) { char *trim_txt; trim_txt = trim(txt); if (trim_txt) { snd_help(trim_txt, Xen_string_to_C_string(g_snd_help(C_string_to_Xen_string(trim_txt), 0)), WITH_WORD_WRAP); free(trim_txt); } XtFree(txt); } else text_at_cursor(listener_text); } static void listener_save_callback(Widget w, XtPointer context, XtPointer info) { FILE *fp = NULL; fp = FOPEN("listener.txt", "w"); if (fp) { save_listener_text(fp); snd_fclose(fp, "listener.txt"); } } static void listener_clear_callback(Widget w, XtPointer context, XtPointer info) { clear_listener(); } #if HAVE_SCHEME static void listener_stacktrace_callback(Widget w, XtPointer context, XtPointer info) { s7_pointer str; str = s7_eval_c_string(s7, "(stacktrace)"); if (s7_string_length(str) == 0) str = s7_eval_c_string(s7, "(object->string (owlet))"); snd_display_result(s7_string(str), NULL); } #endif static void listener_stop_callback(Widget w, XtPointer context, XtPointer info) { control_g(any_selected_sound()); } #if HAVE_SCHEME static Widget stacktrace_popup_menu = NULL; #endif static void listener_popup_callback(Widget w, XtPointer context, XtPointer info) { XmPopupHandlerCallbackStruct *cb = (XmPopupHandlerCallbackStruct *)info; XEvent *e; e = cb->event; if (e->type == ButtonPress) { #if HAVE_SCHEME if (stacktrace_popup_menu) set_menu_label(stacktrace_popup_menu, (s7_is_null(s7, s7_curlet(s7))) ? "Error info" : "Stacktrace"); #endif cb->menuToPost = listener_popup; } } static void make_listener_widget(int height) { if (!listener_text) { Arg args[32]; Widget wv, wh, w; int n; if (!actions_loaded) {XtAppAddActions(MAIN_APP(ss), acts, NUM_ACTS); actions_loaded = true;} n = attach_all_sides(args, 0); XtSetArg(args[n], XmNheight, height); n++; XtSetArg(args[n], XmNpaneMaximum, LOTSA_PIXELS); n++; /* Xm/Paned initializes each pane max to 1000 apparently! */ if ((sound_style(ss) == SOUNDS_IN_NOTEBOOK) || (sound_style(ss) == SOUNDS_HORIZONTAL)) listener_pane = XtCreateManagedWidget("frm", xmFormWidgetClass, SOUND_PANE_BOX(ss), args, n); else listener_pane = XtCreateManagedWidget("frm", xmFormWidgetClass, SOUND_PANE(ss), args, n); /* this widget is not redundant at least in Metroworks Motif */ n = 0; XtSetArg(args[n], XmNbackground, ss->listener_color); n++; XtSetArg(args[n], XmNforeground, ss->listener_text_color); n++; if (ss->listener_fontlist) {XtSetArg(args[n], XM_FONT_RESOURCE, ss->listener_fontlist); n++;} n = attach_all_sides(args, n); XtSetArg(args[n], XmNeditMode, XmMULTI_LINE_EDIT); n++; XtSetArg(args[n], XmNskipAdjust, true); n++; XtSetArg(args[n], XmNvalue, listener_prompt(ss)); n++; XtSetArg(args[n], XmNpendingDelete, false); n++; /* don't cut selection upon paste */ XtSetArg(args[n], XmNpositionIndex, XmLAST_POSITION); n++; XtSetArg(args[n], XmNhighlightThickness, 1); n++; listener_text = XmCreateScrolledText(listener_pane, (char *)"lisp-listener", args, n); ss->listener_pane = listener_text; n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNpopupEnabled, XmPOPUP_AUTOMATIC); n++; listener_popup = XmCreatePopupMenu(listener_text, (char *)"listener-popup", args, n); w = XtCreateManagedWidget(I_STOP, xmPushButtonWidgetClass, listener_popup, args, n); XtAddCallback(w, XmNactivateCallback, listener_stop_callback, NULL); #if HAVE_SCHEME w = XtCreateManagedWidget("Stacktrace", xmPushButtonWidgetClass, listener_popup, args, n); XtAddCallback(w, XmNactivateCallback, listener_stacktrace_callback, NULL); stacktrace_popup_menu = w; #endif w = XtCreateManagedWidget(I_HELP, xmPushButtonWidgetClass, listener_popup, args, n); XtAddCallback(w, XmNactivateCallback, listener_help_callback, NULL); w = XtCreateManagedWidget("Clear", xmPushButtonWidgetClass, listener_popup, args, n); XtAddCallback(w, XmNactivateCallback, listener_clear_callback, NULL); w = XtCreateManagedWidget("Save", xmPushButtonWidgetClass, listener_popup, args, n); XtAddCallback(w, XmNactivateCallback, listener_save_callback, NULL); XtVaSetValues(MAIN_SHELL(ss), XmNallowShellResize, false, NULL); XtManageChild(listener_text); XmTextSetCursorPosition(listener_text, 1); if (!transTable4) transTable4 = XtParseTranslationTable(TextTrans4); XtOverrideTranslations(listener_text, transTable4); XtAddCallback(listener_text, XmNactivateCallback, listener_return_callback, NULL); XtAddCallback(listener_text, XmNmodifyVerifyCallback, listener_modify_callback, NULL); XtAddCallback(listener_text, XmNmotionVerifyCallback, listener_motion_callback, NULL); lisp_window = XtParent(listener_text); XtAddEventHandler(lisp_window, EnterWindowMask, false, listener_focus_callback, NULL); XtAddEventHandler(lisp_window, LeaveWindowMask, false, listener_unfocus_callback, NULL); XtAddCallback(listener_text, XmNpopupHandlerCallback, listener_popup_callback, NULL); XmChangeColor(lisp_window, ss->basic_color); XtVaGetValues(lisp_window, XmNverticalScrollBar, &wv, XmNhorizontalScrollBar, &wh, NULL); XmChangeColor(wv, ss->basic_color); XmChangeColor(wh, ss->basic_color); map_over_children(SOUND_PANE(ss), color_sashes); if (auto_resize(ss)) XtVaSetValues(MAIN_SHELL(ss), XmNallowShellResize, true, NULL); } } void goto_listener(void) { goto_window(listener_text); XmTextSetCursorPosition(listener_text, XmTextGetLastPosition(listener_text) + 1); XmTextSetInsertionPosition(listener_text, XmTextGetLastPosition(listener_text) + 1); } void color_listener(Pixel pix) { ss->listener_color = pix; #if HAVE_SCHEME s7_symbol_set_value(s7, ss->listener_color_symbol, Xen_wrap_pixel(pix)); #endif if (listener_text) XmChangeColor(listener_text, pix); } void color_listener_text(Pixel pix) { ss->listener_text_color = pix; #if HAVE_SCHEME s7_symbol_set_value(s7, ss->listener_text_color_symbol, Xen_wrap_pixel(pix)); #endif if (listener_text) XtVaSetValues(listener_text, XmNforeground, pix, NULL); } void handle_listener(bool open) { if (open) { if (!listener_text) make_listener_widget(100); else { XtManageChild(listener_pane); if (!(listener_is_visible())) { XtUnmanageChild(listener_pane); XtVaSetValues(listener_pane, XmNpaneMinimum, 100, XmNpaneMaximum, LOTSA_PIXELS, NULL); XtManageChild(listener_pane); XtVaSetValues(listener_pane, XmNpaneMinimum, 1, NULL); } } } else XtUnmanageChild(listener_pane); } bool listener_exists(void) { return((bool)listener_text); } int listener_height(void) { if ((listener_text) && (XtIsManaged(listener_pane))) return(widget_height(listener_text)); else return(0); } int listener_width(void) { if ((listener_text) && (XtIsManaged(listener_pane))) return(widget_width(listener_text)); else return(0); } #if OVERRIDE_TOGGLE static char ToggleTrans2[] = "c: ArmAndActivate()\n"; static XtTranslations toggleTable2 = NULL; static void override_toggle_translation(Widget w) { if (!toggleTable2) toggleTable2 = XtParseTranslationTable(ToggleTrans2); XtOverrideTranslations(w, toggleTable2); } #endif Widget make_togglebutton_widget(const char *name, Widget parent, Arg *args, int n) { Widget w; w = XtCreateManagedWidget(name, xmToggleButtonWidgetClass, parent, args, n); #if OVERRIDE_TOGGLE override_toggle_translation(w); #endif return(w); } Widget make_pushbutton_widget(const char *name, Widget parent, Arg *args, int n) { Widget w; w = XtCreateManagedWidget(name, xmPushButtonWidgetClass, parent, args, n); #if OVERRIDE_TOGGLE override_toggle_translation(w); /* ??? activate here (rather than armandactivate) fails? */ #endif return(w); } static Xen g_listener_selection(void) { #define H_listener_selection "(" S_listener_selection "): currently selected text in listener or " PROC_FALSE Xen res = Xen_false; if (listener_text) { char *txt; txt = XmTextGetSelection(listener_text); if (txt) { res = C_string_to_Xen_string(txt); XtFree(txt); } } return(res); } static Xen g_reset_listener_cursor(void) { #define H_reset_listener_cursor "(" S_reset_listener_cursor "): reset listener cursor to the default pointer" if (listener_text) XUndefineCursor(XtDisplay(listener_text), XtWindow(listener_text)); return(Xen_false); } void clear_listener(void) { if (listener_text) /* this can be called even when there is no listener */ { dont_check_motion = true; XmTextSetSelection(listener_text, 0, XmTextGetCursorPosition(listener_text), CurrentTime); XmTextRemove(listener_text); XmTextInsert(listener_text, 0, listener_prompt(ss)); XmTextShowPosition(listener_text, ss->listener_prompt_length); dont_check_motion = false; } } void set_listener_text_font(void) { if (listener_text) XtVaSetValues(listener_text, XM_FONT_RESOURCE, ss->listener_fontlist, NULL); } static Xen g_goto_listener_end(void) { #define H_goto_listener_end "(" S_goto_listener_end "): move cursor and scroll to bottom of listener pane" if (listener_text) { XmTextPosition eot; eot = XmTextGetLastPosition(listener_text); XmTextShowPosition(listener_text, eot); XmTextSetInsertionPosition(listener_text, eot); return(C_int_to_Xen_integer(eot)); } return(Xen_false); } Xen_wrap_no_args(g_listener_selection_w, g_listener_selection) Xen_wrap_no_args(g_reset_listener_cursor_w, g_reset_listener_cursor) Xen_wrap_no_args(g_goto_listener_end_w, g_goto_listener_end) void g_init_gxlistener(void) { #if HAVE_SCHEME top_level_let = s7_nil(s7); s7_define_variable(s7, "top-level-let", s7_dilambda(s7, "top-level-let", g_top_level_let, 0, 0, g_set_top_level_let, 1, 0, "listener environment")); #define H_mouse_enter_listener_hook S_mouse_enter_listener_hook " (widget): called when the mouse \ enters the lisp listener pane:\n\ (hook-push " S_mouse_enter_listener_hook "\n\ (lambda (hook)\n\ (" S_focus_widget " (hook 'widget))))" #endif #if HAVE_RUBY #define H_mouse_enter_listener_hook S_mouse_enter_listener_hook " (listener): called when the mouse \ enters the lisp listener pane:\n\ $mouse_enter_listener_hook.add-hook!(\"enter\") do |widget|\n\ focus_widget(widget)\n\ end" #endif #if HAVE_FORTH #define H_mouse_enter_listener_hook S_mouse_enter_listener_hook " (listener): called when the mouse \ enters the lisp listener pane:\n\ " S_mouse_enter_listener_hook " lambda: <{ wid }> wid " S_focus_widget " ; add-hook!" #endif #define H_mouse_leave_listener_hook S_mouse_leave_listener_hook " (widget): called when the mouse \ leaves the lisp listener pane" mouse_enter_listener_hook = Xen_define_hook(S_mouse_enter_listener_hook, "(make-hook 'widget)", 1, H_mouse_enter_listener_hook); mouse_leave_listener_hook = Xen_define_hook(S_mouse_leave_listener_hook, "(make-hook 'widget)", 1, H_mouse_leave_listener_hook); #if HAVE_SCHEME #define H_mouse_enter_text_hook S_mouse_enter_text_hook " (widget): called when the mouse enters a text widget:\n\ (hook-push " S_mouse_enter_text_hook "\n\ (lambda (w)\n\ (" S_focus_widget " w)))" #endif #if HAVE_RUBY #define H_mouse_enter_text_hook S_mouse_enter_text_hook " (widget): called when the mouse enters a text widget:\n\ $mouse_enter_text_hook.add_hook!(\"enter\") do |w|\n\ focus_widget(w)\n\ end" #endif #if HAVE_FORTH #define H_mouse_enter_text_hook S_mouse_enter_text_hook " (widget): called when the mouse enters a text widget:\n\ " S_mouse_enter_text_hook " lambda: <{ wid }> wid " S_focus_widget " ; add-hook!" #endif #define H_mouse_leave_text_hook S_mouse_leave_text_hook " (widget): called when the mouse leaves a text widget" mouse_enter_text_hook = Xen_define_hook(S_mouse_enter_text_hook, "(make-hook 'widget)", 1, H_mouse_enter_text_hook); mouse_leave_text_hook = Xen_define_hook(S_mouse_leave_text_hook, "(make-hook 'widget)", 1, H_mouse_leave_text_hook); Xen_define_safe_procedure(S_listener_selection, g_listener_selection_w, 0, 0, 0, H_listener_selection); Xen_define_safe_procedure(S_reset_listener_cursor, g_reset_listener_cursor_w, 0, 0, 0, H_reset_listener_cursor); Xen_define_safe_procedure(S_goto_listener_end, g_goto_listener_end_w, 0, 0, 0, H_goto_listener_end); #define H_listener_click_hook S_listener_click_hook " (position): called when listener clicked; position is text pos of click in listener" listener_click_hook = Xen_define_hook(S_listener_click_hook, "(make-hook 'position)", 1, H_listener_click_hook); preload_best_completions(); } #include enum {W_top, W_form, W_main_window, W_edhist, W_wf_buttons, W_f, W_w, W_left_scrollers, W_zy, W_sy, W_bottom_scrollers, W_sx, W_zx, W_graph, W_gzy, W_gsy, NUM_CHAN_WIDGETS }; #if ((XmVERSION >= 2) && (XmREVISION >= 3)) #define DEFAULT_EDIT_HISTORY_WIDTH 2 #else #define DEFAULT_EDIT_HISTORY_WIDTH 1 #endif Widget channel_main_pane(chan_info *cp) { if (cp) return(cp->chan_widgets[W_form]); return(NULL); } Widget channel_graph(chan_info *cp) {return(cp->chan_widgets[W_graph]);} static Widget channel_sx(chan_info *cp) {return(cp->chan_widgets[W_sx]);} static Widget channel_sy(chan_info *cp) {return(cp->chan_widgets[W_sy]);} static Widget channel_zx(chan_info *cp) {return(cp->chan_widgets[W_zx]);} static Widget channel_zy(chan_info *cp) {return(cp->chan_widgets[W_zy]);} static Widget channel_gsy(chan_info *cp) {return(cp->chan_widgets[W_gsy]);} static Widget channel_gzy(chan_info *cp) {return(cp->chan_widgets[W_gzy]);} Widget channel_w(chan_info *cp) {return(cp->chan_widgets[W_w]);} Widget channel_f(chan_info *cp) {return(cp->chan_widgets[W_f]);} bool channel_graph_is_visible(chan_info *cp) { return((cp) && (cp->chan_widgets) && (channel_graph(cp)) && (XtIsManaged(channel_graph(cp))) && (cp->sound) && /* here we may have a sound wrapper for variable display in which case the sound widgets are not implemented */ (((cp->sound->inuse == SOUND_WRAPPER) || (cp->sound->inuse == SOUND_REGION)) || ((cp->sound->inuse == SOUND_NORMAL) && /* other choice: SOUND_IDLE -> no display */ (w_snd_pane(cp->sound)) && (XtIsManaged(w_snd_pane(cp->sound)))))); } #define EDIT_HISTORY_LIST(Cp) (Cp)->chan_widgets[W_edhist] static mus_float_t sqr(mus_float_t a) {return(a * a);} static mus_float_t cube(mus_float_t a) {return(a * a * a);} static mus_float_t get_scrollbar(Widget w, int val, int scrollbar_max) { int size; if (val == 0) return(0.0); XtVaGetValues(w, XmNsliderSize, &size, NULL); return((mus_float_t)val / (mus_float_t)(scrollbar_max - size)); } static void sy_changed(int value, chan_info *cp) { axis_info *ap; mus_float_t low; ap = cp->axis; low = get_scrollbar(channel_sy(cp), value, SCROLLBAR_MAX); ap->sy = (1.0 - ap->zy) * low; apply_y_axis_change(cp); } static void sx_changed(int value, chan_info *cp) { /* treat as centered with non-slider trough as defining current bounds */ axis_info *ap; double low; ap = cp->axis; low = get_scrollbar(channel_sx(cp), value, SCROLLBAR_MAX); ap->sx = low * (1.0 - ap->zx); apply_x_axis_change(cp); } static void zy_changed(int value, chan_info *cp) { axis_info *ap; mus_float_t old_zy; ap = cp->axis; if (value < 1) value = 1; old_zy = ap->zy; ap->zy = sqr(get_scrollbar(channel_zy(cp), value, SCROLLBAR_MAX)); if (ap->zy < 1e-5) ap->zy = 1e-5; /* if this goes to 0, X can hang */ ap->sy += (.5 * (old_zy - ap->zy)); /* try to keep wave centered */ if (ap->sy < 0) ap->sy = 0; apply_y_axis_change(cp); resize_sy(cp); } #define X_RANGE_CHANGEOVER 20.0 static void zx_changed(int value, chan_info *cp) { /* scrollbar change */ axis_info *ap; static int old_zx_value = -1; #define ZX_MIN 20 if (value < ZX_MIN) value = ZX_MIN; /* less than this causes underflow in snd-axis describe_ticks */ /* snd-gchn uses .01 -- its equivalent here would be 100 */ /* perhaps the definition should be ((int)(0.002 * MAX_SCROLLBAR)) */ if (old_zx_value == value) return; /* try to keep click on slider from moving the window! */ old_zx_value = value; ap = cp->axis; if (ap->xmax == 0.0) return; if (ap->xmax <= ap->xmin) { ap->xmax = ap->xmin + .001; ap->x_ambit = .001; } if (ap->x_ambit < X_RANGE_CHANGEOVER) ap->zx = sqr(get_scrollbar(channel_zx(cp), value, SCROLLBAR_MAX)); else ap->zx = cube(get_scrollbar(channel_zx(cp), value, SCROLLBAR_MAX)); /* if cursor visible, focus on that, else selection, else mark, else left side */ focus_x_axis_change(cp, zoom_focus_style(ss)); resize_sx(cp); } static void set_scrollbar(Widget w, mus_float_t position, mus_float_t range, int scrollbar_max) /* position and range 0 to 1.0 */ { int size, val; size = (int)(scrollbar_max * range); if (size > scrollbar_max) size = scrollbar_max; /* this can't happen!?! */ if (size < 1) size = 1; val = (int)(scrollbar_max * position); if ((val + size) > scrollbar_max) val = scrollbar_max - size; if (val < 0) val = 0; XtVaSetValues(w, XmNsliderSize, size, XmNvalue, val, NULL); } static void change_gzy_1(mus_float_t val, chan_info *cp) { mus_float_t chan_frac, new_gsy, new_size; cp->gzy = val; chan_frac = 1.0 / ((mus_float_t)(((snd_info *)(cp->sound))->nchans)); new_size = chan_frac + ((1.0 - chan_frac) * cp->gzy); if ((cp->gsy + new_size) > 1.0) new_gsy = 1.0 - new_size; else new_gsy = cp->gsy; if (new_gsy < 0.0) new_gsy = 0.0; set_scrollbar(channel_gsy(cp), new_gsy, new_size, SCROLLBAR_MAX); } static void gzy_changed(int value, chan_info *cp) { change_gzy_1(get_scrollbar(channel_gzy(cp), value, SCROLLBAR_MAX), cp); for_each_sound_chan(cp->sound, update_graph_or_warn); } void change_gzy(mus_float_t val, chan_info *cp) { change_gzy_1(val, cp); set_scrollbar(channel_gzy(cp), val, 1.0 / (mus_float_t)(cp->sound->nchans), SCROLLBAR_MAX); } static void gsy_changed(int value, chan_info *cp) { mus_float_t low; low = get_scrollbar(channel_gsy(cp), value, SCROLLBAR_MAX); cp->gsy = (1.0 - cp->gzy) * low; for_each_sound_chan(cp->sound, update_graph_or_warn); } mus_float_t gsy_value(chan_info *cp) { Widget wcp; int ival; wcp = channel_gsy(cp); XtVaGetValues(wcp, XmNvalue, &ival, NULL); return((mus_float_t)ival / (mus_float_t)(SCROLLBAR_MAX)); } mus_float_t gsy_size(chan_info *cp) { Widget wcp; int ival; wcp = channel_gsy(cp); XtVaGetValues(wcp, XmNsliderSize, &ival, NULL); return((mus_float_t)ival / (mus_float_t)(SCROLLBAR_MAX)); } static void set_zx_scrollbar(chan_info *cp, axis_info *ap) { if (ap->x_ambit < X_RANGE_CHANGEOVER) set_scrollbar(channel_zx(cp), sqrt(ap->zx), .1, SCROLLBAR_MAX); /* assume size is 10% of scrollbar length */ else set_scrollbar(channel_zx(cp), pow(ap->zx, .333), .1, SCROLLBAR_MAX); } void set_z_scrollbars(chan_info *cp, axis_info *ap) { set_zx_scrollbar(cp, ap); set_scrollbar(channel_zy(cp), sqrt(ap->zy), .1, SCROLLBAR_MAX); } void initialize_scrollbars(chan_info *cp) { axis_info *ap; snd_info *sp; cp->gzy = 1.0; cp->gsy = 1.0; ap = cp->axis; sp = cp->sound; set_scrollbar(channel_sx(cp), ap->sx, ap->zx, SCROLLBAR_MAX); set_scrollbar(channel_sy(cp), ap->sy, ap->zy, SCROLLBAR_MAX); set_z_scrollbars(cp, ap); if ((sp->nchans > 1) && (cp->chan == 0) && (channel_gsy(cp))) { set_scrollbar(channel_gsy(cp), 1.0, 1.0, SCROLLBAR_MAX); set_scrollbar(channel_gzy(cp), 1.0, 1.0 / (mus_float_t)(sp->nchans), SCROLLBAR_MAX); } } void resize_sy(chan_info *cp) { /* something changed the y axis view, so the scale scroller needs to reflect that change (in size and position) */ axis_info *ap; ap = cp->axis; if (ap->y_ambit != 0.0) set_scrollbar(channel_sy(cp), (ap->y0 - ap->ymin) / ap->y_ambit, (ap->y1 - ap->y0) / ap->y_ambit, SCROLLBAR_MAX); } void resize_sy_and_zy(chan_info *cp) { resize_sy(cp); set_scrollbar(channel_zy(cp), sqrt(cp->axis->zy), .1, SCROLLBAR_MAX); } void resize_sx(chan_info *cp) { axis_info *ap; ap = cp->axis; if (ap->x_ambit != 0.0) set_scrollbar(channel_sx(cp), (ap->x0 - ap->xmin) / ap->x_ambit, (ap->x1 - ap->x0) / ap->x_ambit, SCROLLBAR_MAX); } void resize_sx_and_zx(chan_info *cp) { resize_sx(cp); /* change zx position (not its size) */ set_zx_scrollbar(cp, cp->axis); } void channel_open_pane(chan_info *cp) { XtManageChild(channel_main_pane(cp)); } void channel_unlock_pane(chan_info *cp) { XtVaSetValues(channel_main_pane(cp), XmNpaneMinimum, 5, XmNpaneMaximum, LOTSA_PIXELS, NULL); } static void channel_lock_pane(chan_info *cp, int val) { if (val < 6) val = 6; XtUnmanageChild(channel_main_pane(cp)); XtVaSetValues(channel_main_pane(cp), XmNpaneMinimum, val - 5, XmNpaneMaximum, val + 5, NULL); } static void sy_drag_callback(Widget w, XtPointer context, XtPointer info) { chan_info *cp = (chan_info *)(context); if (cp->active == CHANNEL_HAS_AXES) sy_changed(((XmScrollBarCallbackStruct *)info)->value, cp); } static void sy_valuechanged_callback(Widget w, XtPointer context, XtPointer info) { chan_info *cp = (chan_info *)(context); if (cp->active == CHANNEL_HAS_AXES) sy_changed(((XmScrollBarCallbackStruct *)info)->value, cp); } static void sx_drag_callback(Widget w, XtPointer context, XtPointer info) { chan_info *cp = (chan_info *)(context); if (cp->active == CHANNEL_HAS_AXES) sx_changed(((XmScrollBarCallbackStruct *)info)->value, cp); } static void sx_valuechanged_callback(Widget w, XtPointer context, XtPointer info) { chan_info *cp = (chan_info *)(context); if (cp->active == CHANNEL_HAS_AXES) sx_changed(((XmScrollBarCallbackStruct *)info)->value, cp); } static void sx_increment_callback(Widget w, XtPointer context, XtPointer info) { /* problem here is that in large files these increments, if determined via scrollbar values, are huge */ /* so, move ahead one-tenth window on each tick */ chan_info *cp = (chan_info *)(context); if (cp->active == CHANNEL_HAS_AXES) sx_incremented(cp, 0.1); } static void sx_decrement_callback(Widget w, XtPointer context, XtPointer info) { chan_info *cp = (chan_info *)(context); if (cp->active == CHANNEL_HAS_AXES) sx_incremented(cp, -0.1); } static void zy_drag_callback(Widget w, XtPointer context, XtPointer info) { chan_info *cp = (chan_info *)(context); if (cp->active == CHANNEL_HAS_AXES) zy_changed(((XmScrollBarCallbackStruct *)info)->value, cp); } static void zy_valuechanged_callback(Widget w, XtPointer context, XtPointer info) { chan_info *cp = (chan_info *)(context); if (cp->active == CHANNEL_HAS_AXES) zy_changed(((XmScrollBarCallbackStruct *)info)->value, cp); } static void zx_drag_callback(Widget w, XtPointer context, XtPointer info) { chan_info *cp = (chan_info *)(context); if (cp->active == CHANNEL_HAS_AXES) zx_changed(((XmScrollBarCallbackStruct *)info)->value, cp); } /* can't use value changed callback in scrollbars because they are called upon mouse release * even when nothing changed, and the value passed appears to be the right edge of the * slider -- this is too unpredictable, and the result is the window moves when the user * did not want it to. */ static void gzy_drag_callback(Widget w, XtPointer context, XtPointer info) { chan_info *cp = (chan_info *)(context); if (cp->active == CHANNEL_HAS_AXES) gzy_changed(((XmScrollBarCallbackStruct *)info)->value, cp); } static void gsy_drag_callback(Widget w, XtPointer context, XtPointer info) { chan_info *cp = (chan_info *)(context); if (cp->active == CHANNEL_HAS_AXES) gsy_changed(((XmScrollBarCallbackStruct *)info)->value, cp); } static void gsy_valuechanged_callback(Widget w, XtPointer context, XtPointer info) { chan_info *cp = (chan_info *)(context); if (cp->active == CHANNEL_HAS_AXES) gsy_changed(((XmScrollBarCallbackStruct *)info)->value, cp); } /* anything special for increment? XmNincrementCallback sx_increment_callback */ static void f_toggle_callback(Widget w, XtPointer context, XtPointer info) { XmToggleButtonCallbackStruct *cb = (XmToggleButtonCallbackStruct *)info; XButtonEvent *ev; ev = (XButtonEvent *)(cb->event); f_button_callback((chan_info *)context, cb->set, (ev->state & snd_ControlMask)); } static void w_toggle_callback(Widget w, XtPointer context, XtPointer info) { XmToggleButtonCallbackStruct *cb = (XmToggleButtonCallbackStruct *)info; XButtonEvent *ev; ev = (XButtonEvent *)(cb->event); w_button_callback((chan_info *)context, cb->set, (ev->state & snd_ControlMask)); } static void channel_expose_callback(Widget w, XtPointer context, XtPointer info) { static oclock_t last_expose_event_time = 0; static chan_info *last_cp = NULL; chan_info *cp = (chan_info *)context; XmDrawingAreaCallbackStruct *cb = (XmDrawingAreaCallbackStruct *)info; XExposeEvent *ev; oclock_t curtime; if ((cp == NULL) || (cp->active < CHANNEL_HAS_AXES) || (cp->sound == NULL)) return; ev = (XExposeEvent *)(cb->event); /* if multiple channels/sounds displayed, each gets an expose event, but the earlier ones * have count>0, and the last can get more than 1, causing our notion of last_cp to * be useless, and we'll drop the earlier ones anyway, so if cp != last_cp, expose * last_cp if last_count>0 or times equal (not sure which is safest). */ curtime = XtLastTimestampProcessed(MAIN_DISPLAY(ss)); if ((ev->count == 0) || (last_expose_event_time != curtime) || (cp != last_cp)) { snd_info *sp; sp = cp->sound; if (sp->channel_style != CHANNELS_SEPARATE) { if ((cp->chan == 0) && (ev->width > 10) && (ev->height > 10)) for_each_sound_chan(sp, update_graph_or_warn); } else update_graph_or_warn(cp); } last_cp = cp; last_expose_event_time = curtime; } static void channel_resize_callback(Widget w, XtPointer context, XtPointer info) { channel_resize((chan_info *)context); } static Xen mouse_enter_graph_hook; static Xen mouse_leave_graph_hook; static void graph_mouse_enter(Widget w, XtPointer context, XEvent *event, Boolean *flag) { pointer_or_int_t data; XEnterWindowEvent *ev = (XEnterWindowEvent *)event; if (with_pointer_focus(ss)) goto_window(w); XtVaGetValues(w, XmNuserData, &data, NULL); if (Xen_hook_has_list(mouse_enter_graph_hook)) run_hook(mouse_enter_graph_hook, Xen_list_2(C_int_to_Xen_sound(unpack_sound(data)), C_int_to_Xen_integer(unpack_channel(data))), S_mouse_enter_graph_hook); check_cursor_shape((chan_info *)context, ev->x, ev->y); } static void graph_mouse_leave(Widget w, XtPointer context, XEvent *event, Boolean *flag) { pointer_or_int_t data; XLeaveWindowEvent *ev = (XLeaveWindowEvent *)event; XtVaGetValues(w, XmNuserData, &data, NULL); if (Xen_hook_has_list(mouse_leave_graph_hook)) run_hook(mouse_leave_graph_hook, Xen_list_2(C_int_to_Xen_sound(unpack_sound(data)), C_int_to_Xen_integer(unpack_channel(data))), S_mouse_leave_graph_hook); /* XUndefineCursor(XtDisplay(w), XtWindow(w)); */ check_cursor_shape((chan_info *)context, ev->x, ev->y); } static void graph_button_press(Widget w, XtPointer context, XEvent *event, Boolean *cont) { XButtonEvent *ev = (XButtonEvent *)event; graph_button_press_callback((chan_info *)context, (void *)ev, ev->x, ev->y, ev->state, ev->button, ev->time); } static void graph_button_release(Widget w, XtPointer context, XEvent *event, Boolean *cont) /* cont = "continue to dispatch" */ { XButtonEvent *ev = (XButtonEvent *)event; graph_button_release_callback((chan_info *)context, ev->x, ev->y, ev->state, ev->button); } #if 0 static void graph_button_motion(Widget w, XtPointer context, XEvent *event, Boolean *cont) { /* mouse drag */ XMotionEvent *ev = (XMotionEvent *)event; graph_button_motion_callback((chan_info *)context, ev->x, ev->y, ev->time); } #endif static void graph_mouse_motion(Widget w, XtPointer context, XEvent *event, Boolean *cont) { /* mouse movement */ XMotionEvent *ev = (XMotionEvent *)event; if ((ev->state & Button1Mask) == 0) check_cursor_shape((chan_info *)context, ev->x, ev->y); else graph_button_motion_callback((chan_info *)context, ev->x, ev->y, ev->time); } static int no_padding(Arg *args, int n) { XtSetArg(args[n], XmNmarginHeight, 0); n++; XtSetArg(args[n], XmNmarginWidth, 0); n++; XtSetArg(args[n], XmNmarginTop, 0); n++; XtSetArg(args[n], XmNmarginBottom, 0); n++; XtSetArg(args[n], XmNmarginLeft, 0); n++; XtSetArg(args[n], XmNmarginRight, 0); n++; return(n); } static void hide_gz_scrollbars(snd_info *sp) { Widget w; w = channel_gsy(sp->chans[0]); if ((w) && (XtIsManaged(w))) XtUnmanageChild(w); w = channel_gzy(sp->chans[0]); if ((w) && (XtIsManaged(w))) XtUnmanageChild(w); } static void show_gz_scrollbars(snd_info *sp) { Widget w; w = channel_gsy(sp->chans[0]); if ((w) && (!XtIsManaged(w))) XtManageChild(w); w = channel_gzy(sp->chans[0]); if ((w) && (!XtIsManaged(w))) XtManageChild(w); } /* edit history support */ static void history_select_callback(Widget w, XtPointer context, XtPointer info) { /* undo/redo to reach selected position */ XmListCallbackStruct *cbs = (XmListCallbackStruct *)info; edit_history_select((chan_info *)context, cbs->item_position - 1); } #if WITH_RELATIVE_PANES /* using undocumented callback here, as in snd-xsnd.c */ static void remake_edit_history(Widget lst, chan_info *cp, int from_graph) { snd_info *sp; int i, eds; XmString *edits; if (cp->squelch_update) return; XmListDeleteAllItems(lst); sp = cp->sound; if (sp->channel_style != CHANNELS_SEPARATE) { chan_info *ncp; int k, all_eds = 0, ed, filelen; char *title; for (k = 0; k < sp->nchans; k++) { ncp = sp->chans[k]; eds = ncp->edit_ctr; while ((eds < (ncp->edit_size - 1)) && (ncp->edits[eds + 1])) eds++; all_eds += eds; } all_eds += 3 * sp->nchans; edits = (XmString *)calloc(all_eds, sizeof(XmString)); filelen = 16 + strlen(sp->filename); title = (char *)calloc(filelen, sizeof(char)); for (k = 0, ed = 0; k < sp->nchans; k++) { ncp = sp->chans[k]; ncp->edhist_base = ed; snprintf(title, filelen, "chan %d: %s", k + 1, sp->filename); edits[ed++] = XmStringCreateLocalized(title); eds = ncp->edit_ctr; while ((eds < (ncp->edit_size - 1)) && (ncp->edits[eds + 1])) eds++; for (i = 1; i <= eds; i++) { char *temp; temp = edit_to_string(ncp, i); edits[ed++] = XmStringCreateLocalized(temp); free(temp); } if (k < sp->nchans - 1) edits[ed++] = XmStringCreateLocalized((char *)"______________________________"); } free(title); XtVaSetValues(lst, XmNitems, edits, XmNitemCount, ed, NULL); for (i = 0; i < ed; i++) XmStringFree(edits[i]); free(edits); XmListSelectPos(lst, cp->edhist_base + cp->edit_ctr + 1, false); if (from_graph) goto_graph(cp); } else { int items = 0; eds = cp->edit_ctr; while ((eds < (cp->edit_size - 1)) && (cp->edits[eds + 1])) eds++; edits = (XmString *)calloc(eds + 1, sizeof(XmString)); edits[0] = XmStringCreateLocalized(sp->filename); for (i = 1; i <= eds; i++) { char *temp; temp = edit_to_string(cp, i); edits[i] = XmStringCreateLocalized(temp); free(temp); } XtVaSetValues(lst, XmNitems, edits, XmNitemCount, eds + 1, NULL); for (i = 0; i <= eds; i++) XmStringFree(edits[i]); free(edits); XmListSelectPos(lst, cp->edit_ctr + 1, false); XtVaGetValues(lst, XmNvisibleItemCount, &items, NULL); if (items <= eds) XtVaSetValues(lst, XmNtopItemPosition, eds - items + 2, NULL); if (from_graph) goto_graph(cp); } } static void watch_edit_history_sash(Widget w, XtPointer closure, XtPointer info) { SashCallData call_data = (SashCallData)info; /* call_data->params[0]: Commit, Move, Key, Start (as strings) */ if ((call_data->params) && (mus_strcmp(call_data->params[0], "Start"))) { chan_info *cp = (chan_info *)closure; Widget edhist; if ((cp) && (cp->chan_widgets)) { edhist = EDIT_HISTORY_LIST(cp); if (edhist) remake_edit_history(edhist, cp, false); } } } #endif void reflect_edit_history_change(chan_info *cp) { /* new edit so it is added, and any trailing lines removed */ snd_info *sp; Widget lst; if (cp->squelch_update) return; if (cp->in_as_one_edit > 0) return; sp = cp->sound; lst = EDIT_HISTORY_LIST(cp); #if WITH_RELATIVE_PANES if ((lst) && (widget_width(lst) > 1)) remake_edit_history(lst, cp, true); else { if ((cp->chan > 0) && (sp->channel_style != CHANNELS_SEPARATE)) { lst = EDIT_HISTORY_LIST(sp->chans[0]); if ((lst) && (widget_width(lst) > 1)) remake_edit_history(lst, sp->chans[0], true); } } #else /* old form */ if (lst) { int i, eds, items = 0; XmString *edits; eds = cp->edit_ctr; while ((eds < (cp->edit_size - 1)) && (cp->edits[eds + 1])) eds++; if (eds >= 0) { if ((eds == cp->edit_ctr) && (eds > 1)) /* need to force 0 (1) case to start list with sound file name */ { XmString edit; /* special common case -- we're appending a new edit description */ XtVaGetValues(lst, XmNitemCount, &items, NULL); if (items > eds ) XmListDeleteItemsPos(lst, cp->edit_size, eds + 1); /* cp->edit_size is too large, but the manual says this is the way to delete to the end */ { char *temp; temp = edit_to_string(cp, eds); edit = XmStringCreateLocalized(temp); free(temp); } XmListAddItemUnselected(lst, edit, eds + 1); XmStringFree(edit); } else { edits = (XmString *)calloc(eds + 1, sizeof(XmString)); edits[0] = XmStringCreateLocalized(sp->filename); for (i = 1; i <= eds; i++) { char *temp; temp = edit_to_string(cp, i); edits[i] = XmStringCreateLocalized(temp); free(temp); } XtVaSetValues(lst, XmNitems, edits, XmNitemCount, eds + 1, NULL); for (i = 0; i <= eds; i++) XmStringFree(edits[i]); free(edits); } XmListSelectPos(lst, cp->edit_ctr + 1, false); XtVaGetValues(lst, XmNvisibleItemCount, &items, NULL); if (items <= eds) XtVaSetValues(lst, XmNtopItemPosition, eds - items + 2, NULL); goto_graph(cp); } } #endif } void reflect_edit_counter_change(chan_info *cp) { /* undo/redo/revert -- change which line is highlighted */ Widget lst; if (cp->squelch_update) return; lst = EDIT_HISTORY_LIST(cp); if ((lst) && (widget_width(lst) > 1)) { int len, top; XmListSelectPos(lst, cp->edit_ctr + 1, false); XtVaGetValues(lst, XmNvisibleItemCount, &len, XmNtopItemPosition, &top, NULL); if ((cp->edit_ctr + 1) < top) XtVaSetValues(lst, XmNtopItemPosition, cp->edit_ctr + 1, NULL); else if ((cp->edit_ctr + 1) >= (top + len)) XtVaSetValues(lst, XmNtopItemPosition, cp->edit_ctr, NULL); goto_graph(cp); } } /* for combined cases, the incoming chan_info pointer is always chan[0], * but the actual channel depends on placement if mouse oriented. * virtual_selected_channel(cp) (snd-chn.c) retains the current selected channel */ void graph_key_press(Widget w, XtPointer context, XEvent *event, Boolean *cont) { XKeyEvent *ev = (XKeyEvent *)event; KeySym keysym; int key_state; snd_info *sp = (snd_info *)context; key_state = ev->state; keysym = XkbKeycodeToKeysym(XtDisplay(w), (int)(ev->keycode), 0, (key_state & snd_ShiftMask) ? 1 : 0); key_press_callback(any_selected_channel(sp), ev->x, ev->y, ev->state, keysym); } static void cp_graph_key_press(Widget w, XtPointer context, XEvent *event, Boolean *cont) { /* called by every key-intercepting widget in the entire sound pane */ XKeyEvent *ev = (XKeyEvent *)event; KeySym keysym; int key_state; chan_info *cp = (chan_info *)context; if ((cp == NULL) || (cp->sound == NULL)) return; /* can't happen */ key_state = ev->state; keysym = XkbKeycodeToKeysym(XtDisplay(w), (int)(ev->keycode), 0, (key_state & snd_ShiftMask) ? 1 : 0); key_press_callback(cp, ev->x, ev->y, ev->state, keysym); } static void channel_drop_watcher(Widget w, const char *str, Position x, Position y, void *context) { pointer_or_int_t data; data = (pointer_or_int_t)context; drag_and_drop_mix_at_x_y((int)data, str, x, y); } static void channel_drag_watcher(Widget w, const char *str, Position x, Position y, drag_style_t dtype, void *context) { int snd, chn; pointer_or_int_t data; snd_info *sp; XtVaGetValues(w, XmNuserData, &data, NULL); chn = unpack_channel(data); snd = unpack_sound(data); sp = ss->sounds[snd]; if (snd_ok(sp)) { float seconds; chan_info *cp; switch (dtype) { case DRAG_ENTER: case DRAG_MOTION: cp = sp->chans[chn]; if ((sp->nchans > 1) && (sp->channel_style == CHANNELS_COMBINED)) cp = which_channel(sp, y); seconds = (float)(ungrf_x(cp->axis, x)); if (seconds < 0.0) seconds = 0.0; if (sp->nchans > 1) status_report(sp, "drop to mix file in chan %d at %.4f", cp->chan + 1, seconds); else status_report(sp, "drop to mix file at %.4f", seconds); break; case DRAG_LEAVE: set_status(sp, " ", false); /* not clear_status_area here! => segfault */ break; } } } int add_channel_window(snd_info *sp, int channel, int chan_y, int insertion, Widget main, fw_button_t button_style, bool with_events) { bool need_extra_scrollbars; Widget *cw; chan_info *cp; graphics_context *cax; bool make_widgets; /* if ((main) && ((!(XmIsForm(main))) || (!(XtWindow(main))))) return(-1); */ /* new gcc complains about the XmIsForm for some reason */ if ((main) && (!(XtWindow(main)))) return(-1); /* can this happen? */ make_widgets = ((sp->chans[channel]) == NULL); sp->chans[channel] = make_chan_info(sp->chans[channel], channel, sp); cp = sp->chans[channel]; if (cp->chan_widgets == NULL) cp->chan_widgets = (Widget *)calloc(NUM_CHAN_WIDGETS, sizeof(Widget)); cw = cp->chan_widgets; need_extra_scrollbars = ((!main) && (channel == 0)); if (make_widgets) { XtCallbackList n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14, n15; int n; Arg args[32]; /* allocate the entire widget apparatus for this channel of this sound */ if (!main) { n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; if (insertion) {XtSetArg(args[n], XmNpositionIndex, (short)channel); n++;} XtSetArg(args[n], XmNpaneMinimum, chan_y); n++; cw[W_form] = XtCreateManagedWidget("chn-form", xmFormWidgetClass, w_snd_pane(sp), args, n); if ((sp->channel_style == CHANNELS_COMBINED) && (channel > 0)) XtUnmanageChild(cw[W_form]); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; /* n = no_padding(args, n); */ n = attach_all_sides(args, n); XtSetArg(args[n], XmNsashIndent, 2); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNpaneMaximum, LOTSA_PIXELS); n++; cw[W_top] = XtCreateManagedWidget("chn-top", xmPanedWindowWidgetClass, cw[W_form], args, n); XtAddEventHandler(cw[W_top], KeyPressMask, false, graph_key_press, (XtPointer)sp); n = 0; XtSetArg(args[n], XmNbackground, ss->white); n++; XtSetArg(args[n], XmNpaneMaximum, DEFAULT_EDIT_HISTORY_WIDTH); n++; XtSetArg(args[n], XmNlistSizePolicy, XmCONSTANT); n++; cw[W_edhist] = XmCreateScrolledList(cw[W_top], (char *)"chn-edhist", args, n); XtManageChild(cw[W_edhist]); XtAddCallback(cw[W_edhist], XmNbrowseSelectionCallback, history_select_callback, cp); XtAddEventHandler(cw[W_edhist], KeyPressMask, false, graph_key_press, (XtPointer)sp); XtAddEventHandler(XtParent(cw[W_edhist]), KeyPressMask, false, graph_key_press, (XtPointer)sp); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNpaneMaximum, LOTSA_PIXELS); n++; cw[W_main_window] = XtCreateManagedWidget("chn-main-window", xmFormWidgetClass, cw[W_top], args, n); XtAddEventHandler(cw[W_main_window], KeyPressMask, false, graph_key_press, (XtPointer)sp); #if WITH_RELATIVE_PANES { int k; Widget child; CompositeWidget w = (CompositeWidget)(cw[W_top]); for (k = w->composite.num_children - 1; k >= 0; k--) { child = w->composite.children[k]; if ((XtIsWidget(child)) && (XtIsSubclass(child, xmSashWidgetClass))) { XtAddCallback(child, XmNcallback, watch_edit_history_sash, (XtPointer)cp); break; /* there seems to be more than 1?? */ } } } #endif } else cw[W_main_window] = main; n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; n = no_padding(args, n); XtSetArg(args[n], XmNpacking, XmPACK_COLUMN); n++; XtSetArg(args[n], XmNnumColumns, 1); n++; XtSetArg(args[n], XmNorientation, XmVERTICAL); n++; cw[W_wf_buttons] = XtCreateManagedWidget("chn-buttons", xmRowColumnWidgetClass, cw[W_main_window], args, n); if (button_style == WITH_FW_BUTTONS) { n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNspacing, 1); n++; XtSetArg(args[n], XmNselectColor, ss->selection_color); n++; cw[W_f] = make_togglebutton_widget("f", cw[W_wf_buttons], args, n); XtAddCallback(cw[W_f], XmNvalueChangedCallback, f_toggle_callback, cp); XtAddEventHandler(cw[W_f], KeyPressMask, false, graph_key_press, (XtPointer)sp); XtSetArg(args[n], XmNset, true); n++; cw[W_w] = make_togglebutton_widget("w", cw[W_wf_buttons], args, n); XtAddCallback(cw[W_w], XmNvalueChangedCallback, w_toggle_callback, cp); XtAddEventHandler(cw[W_w], KeyPressMask, false, graph_key_press, (XtPointer)sp); } else { n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNarrowDirection, XmARROW_UP); n++; XtSetArg(args[n], XmNsensitive, false); n++; cw[W_f] = XtCreateManagedWidget("up", xmArrowButtonWidgetClass, cw[W_wf_buttons], args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNarrowDirection, XmARROW_DOWN); n++; XtSetArg(args[n], XmNsensitive, false); n++; cw[W_w] = XtCreateManagedWidget("down", xmArrowButtonWidgetClass, cw[W_wf_buttons], args, n); } n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNbottomWidget, cw[W_wf_buttons]); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNspacing, 0); n++; cw[W_left_scrollers] = XtCreateManagedWidget("chn-left", xmRowColumnWidgetClass, cw[W_main_window], args, n); XtAddEventHandler(cw[W_left_scrollers], KeyPressMask, false, graph_key_press, (XtPointer)sp); n = 0; XtSetArg(args[n], XmNbackground, ss->zoom_color); n++; XtSetArg(args[n], XmNwidth, ss->position_slider_width); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNorientation, XmVERTICAL); n++; XtSetArg(args[n], XmNmaximum, SCROLLBAR_MAX); n++; XtSetArg(args[n], XmNincrement, 1); n++; XtSetArg(args[n], XmNprocessingDirection, XmMAX_ON_TOP); n++; XtSetArg(args[n], XmNdragCallback, n1 = make_callback_list(zy_drag_callback, (XtPointer)cp)); n++; XtSetArg(args[n], XmNvalueChangedCallback, n2 = make_callback_list(zy_valuechanged_callback, (XtPointer)cp)); n++; cw[W_zy] = XtCreateManagedWidget("chn-zy", xmScrollBarWidgetClass, cw[W_left_scrollers], args, n); XtAddEventHandler(cw[W_zy], KeyPressMask, false, graph_key_press, (XtPointer)sp); n = 0; XtSetArg(args[n], XmNbackground, ss->position_color); n++; XtSetArg(args[n], XmNwidth, ss->zoom_slider_width); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, cw[W_zy]); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNorientation, XmVERTICAL); n++; XtSetArg(args[n], XmNmaximum, SCROLLBAR_MAX); n++; XtSetArg(args[n], XmNincrement, 1); n++; XtSetArg(args[n], XmNprocessingDirection, XmMAX_ON_TOP); n++; XtSetArg(args[n], XmNdragCallback, n3 = make_callback_list(sy_drag_callback, (XtPointer)cp)); n++; XtSetArg(args[n], XmNvalueChangedCallback, n4 = make_callback_list(sy_valuechanged_callback, (XtPointer)cp)); n++; cw[W_sy] = XtCreateManagedWidget("chn-sy", xmScrollBarWidgetClass, cw[W_left_scrollers], args, n); XtAddEventHandler(cw[W_sy], KeyPressMask, false, graph_key_press, (XtPointer)sp); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNorientation, XmVERTICAL); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, cw[W_wf_buttons]); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNspacing, 0); n++; cw[W_bottom_scrollers] = XtCreateManagedWidget("chn-bottom", xmRowColumnWidgetClass, cw[W_main_window], args, n); XtAddEventHandler(cw[W_bottom_scrollers], KeyPressMask, false, graph_key_press, (XtPointer)sp); n = 0; XtSetArg(args[n], XmNbackground, ss->position_color); n++; XtSetArg(args[n], XmNheight, ss->position_slider_width); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNmaximum, SCROLLBAR_MAX); n++; XtSetArg(args[n], XmNincrement, 1); n++; XtSetArg(args[n], XmNdragCallback, n5 = make_callback_list(sx_drag_callback, (XtPointer)cp)); n++; XtSetArg(args[n], XmNincrementCallback, n6 = make_callback_list(sx_increment_callback, (XtPointer)cp)); n++; XtSetArg(args[n], XmNdecrementCallback, n7 = make_callback_list(sx_decrement_callback, (XtPointer)cp)); n++; XtSetArg(args[n], XmNvalueChangedCallback, n8 = make_callback_list(sx_valuechanged_callback, (XtPointer)cp)); n++; cw[W_sx] = XtCreateManagedWidget("chn-sx", xmScrollBarWidgetClass, cw[W_bottom_scrollers], args, n); XtAddEventHandler(cw[W_sx], KeyPressMask, false, graph_key_press, (XtPointer)sp); n = 0; XtSetArg(args[n], XmNbackground, ss->zoom_color); n++; XtSetArg(args[n], XmNheight, ss->zoom_slider_width + 2); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNbottomWidget, cw[W_sx]); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNmaximum, SCROLLBAR_MAX); n++; XtSetArg(args[n], XmNincrement, 1); n++; XtSetArg(args[n], XmNdragCallback, n9 = make_callback_list(zx_drag_callback, (XtPointer)cp)); n++; XtSetArg(args[n], XmNincrementCallback, n10 = make_callback_list(zx_drag_callback, (XtPointer)cp)); n++; XtSetArg(args[n], XmNdecrementCallback, n11 = make_callback_list(zx_drag_callback, (XtPointer)cp)); n++; XtSetArg(args[n], XmNpageIncrementCallback, n12 = make_callback_list(zx_drag_callback, (XtPointer)cp)); n++; XtSetArg(args[n], XmNpageDecrementCallback, n13 = make_callback_list(zx_drag_callback, (XtPointer)cp)); n++; XtSetArg(args[n], XmNtoTopCallback, n14 = make_callback_list(zx_drag_callback, (XtPointer)cp)); n++; XtSetArg(args[n], XmNtoBottomCallback, n15 = make_callback_list(zx_drag_callback, (XtPointer)cp)); n++; cw[W_zx] = XtCreateManagedWidget("chn-zx", xmScrollBarWidgetClass, cw[W_bottom_scrollers], args, n); XtAddEventHandler(cw[W_zx], KeyPressMask, false, graph_key_press, (XtPointer)sp); n = 0; XtSetArg(args[n], XmNbackground, ss->graph_color); n++; XtSetArg(args[n], XmNforeground, ss->data_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNbottomWidget, cw[W_bottom_scrollers]); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, cw[W_left_scrollers]); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNuserData, pack_sound_and_channel(sp->index, cp->chan)); n++; /* this collides with W_gzy below, but a consistent version came up with half a window blank */ XtSetArg(args[n], XmNnavigationType, XmNONE); n++; cw[W_graph] = XtCreateManagedWidget("chn-graph", xmDrawingAreaWidgetClass, cw[W_main_window], args, n); if (with_events) { /* region regraph sets up its own callbacks */ XtAddCallback(cw[W_graph], XmNresizeCallback, channel_resize_callback, (XtPointer)cp); XtAddCallback(cw[W_graph], XmNexposeCallback, channel_expose_callback, (XtPointer)cp); } /* allow cursor in all cases (zoom to cursor in region window for example, or fft axis drag in variable display) */ XtAddEventHandler(cw[W_graph], ButtonPressMask, false, graph_button_press, (XtPointer)cp); XtAddEventHandler(cw[W_graph], ButtonReleaseMask, false, graph_button_release, (XtPointer)cp); /* XtAddEventHandler(cw[W_graph], ButtonMotionMask, false, graph_button_motion, (XtPointer)cp); */ XtAddEventHandler(cw[W_graph], PointerMotionMask, false, graph_mouse_motion, (XtPointer)cp); if (main == NULL) { pointer_or_int_t data; XtAddEventHandler(cw[W_graph], EnterWindowMask, false, graph_mouse_enter, (XtPointer)cp); XtAddEventHandler(cw[W_graph], LeaveWindowMask, false, graph_mouse_leave, (XtPointer)cp); XtAddEventHandler(cw[W_graph], KeyPressMask, false, cp_graph_key_press, (XtPointer)cp); data = (pointer_or_int_t)pack_sound_and_channel(sp->index, cp->chan); add_drag_and_drop(cw[W_graph], channel_drop_watcher, channel_drag_watcher, (void *)data); } free(n1); free(n2); free(n3); free(n4); free(n5); free(n6); free(n7); free(n8); free(n9); free(n10); free(n11); free(n12); free(n13); free(n14); free(n15); if (need_extra_scrollbars) { /* that is: not region browser chan, might need combined graph, channel 0 is the controller in that case */ /* this is independent of sp->nchans because these structs are re-used and added to as needed */ n = 0; XtSetArg(args[n], XmNbackground, ss->zoom_color); n++; XtSetArg(args[n], XmNwidth, ss->position_slider_width); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNbottomWidget, cw[W_bottom_scrollers]); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNorientation, XmVERTICAL); n++; XtSetArg(args[n], XmNmaximum, SCROLLBAR_MAX); n++; XtSetArg(args[n], XmNincrement, 1); n++; XtSetArg(args[n], XmNprocessingDirection, XmMAX_ON_TOP); n++; XtSetArg(args[n], XmNincrementCallback, n1 = make_callback_list(gzy_drag_callback, (XtPointer)cp)); n++; XtSetArg(args[n], XmNdecrementCallback, n2 = make_callback_list(gzy_drag_callback, (XtPointer)cp)); n++; XtSetArg(args[n], XmNpageIncrementCallback, n3 = make_callback_list(gzy_drag_callback, (XtPointer)cp)); n++; XtSetArg(args[n], XmNpageDecrementCallback, n4 = make_callback_list(gzy_drag_callback, (XtPointer)cp)); n++; XtSetArg(args[n], XmNtoTopCallback, n5 = make_callback_list(gzy_drag_callback, (XtPointer)cp)); n++; XtSetArg(args[n], XmNtoBottomCallback, n6 = make_callback_list(gzy_drag_callback, (XtPointer)cp)); n++; XtSetArg(args[n], XmNdragCallback, n7 = make_callback_list(gzy_drag_callback, (XtPointer)cp)); n++; cw[W_gzy] = XtCreateManagedWidget("chn-gzy", xmScrollBarWidgetClass, cw[W_main_window], args, n); XtAddEventHandler(cw[W_gzy], KeyPressMask, false, graph_key_press, (XtPointer)sp); n = 0; XtSetArg(args[n], XmNbackground, ss->position_color); n++; XtSetArg(args[n], XmNwidth, ss->position_slider_width); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNbottomWidget, cw[W_bottom_scrollers]); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNrightWidget, cw[W_gzy]); n++; XtSetArg(args[n], XmNorientation, XmVERTICAL); n++; XtSetArg(args[n], XmNmaximum, SCROLLBAR_MAX); n++; XtSetArg(args[n], XmNincrement, 1); n++; XtSetArg(args[n], XmNprocessingDirection, XmMAX_ON_TOP); n++; XtSetArg(args[n], XmNdragCallback, n8 = make_callback_list(gsy_drag_callback, (XtPointer)cp)); n++; XtSetArg(args[n], XmNvalueChangedCallback, n9 = make_callback_list(gsy_valuechanged_callback, (XtPointer)cp)); n++; cw[W_gsy] = XtCreateManagedWidget("chn-gsy", xmScrollBarWidgetClass, cw[W_main_window], args, n); XtAddEventHandler(cw[W_gsy], KeyPressMask, false, graph_key_press, (XtPointer)sp); free(n1); free(n2); free(n3); free(n4); free(n5); free(n6); free(n7); free(n8); free(n9); } else { cw[W_gsy] = NULL; cw[W_gzy] = NULL; } run_new_widget_hook(cw[W_main_window]); /* also position of current graph in overall sound as window */ } /* end alloc new chan */ else { int i; /* re-manage currently inactive chan */ XtVaSetValues(cw[W_main_window], XmNpaneMinimum, chan_y, NULL); if (cw[W_edhist]) XtVaSetValues(XtParent(cw[W_edhist]), XmNpaneMaximum, 1, NULL); if ((sp->channel_style != CHANNELS_COMBINED) || (channel == 0)) for (i = 0; i < NUM_CHAN_WIDGETS - 1; i++) if ((cw[i]) && (!XtIsManaged(cw[i]))) XtManageChild(cw[i]); recolor_graph(cp, false); /* in case selection color left over from previous use */ } if (cw[W_edhist]) XtVaSetValues(XtParent(cw[W_edhist]), XmNpaneMaximum, LOTSA_PIXELS, NULL); if ((need_extra_scrollbars) && (sp->channel_style != CHANNELS_COMBINED)) hide_gz_scrollbars(sp); /* default is on in this case */ cax = cp->ax; cax->wn = XtWindow(cw[W_graph]); cax->dp = XtDisplay(cw[W_graph]); cax->gc = ss->basic_gc; return(0); } static void set_graph_font(chan_info *cp, graphics_context *ax, XFontStruct *bf) { if (!ax) return; ax->current_font = bf->fid; XSetFont(XtDisplay(channel_to_widget(cp)), copy_GC(cp), bf->fid); } void set_peak_numbers_font(chan_info *cp, graphics_context *ax) {set_graph_font(cp, ax, PEAKS_FONT(ss));} void set_tiny_numbers_font(chan_info *cp, graphics_context *ax) {set_graph_font(cp, ax, TINY_FONT(ss));} void set_bold_peak_numbers_font(chan_info *cp, graphics_context *ax) {set_graph_font(cp, ax, BOLD_PEAKS_FONT(ss));} color_t get_foreground_color(graphics_context *ax) { XGCValues gv; XGetGCValues(MAIN_DISPLAY(ss), ax->gc, GCForeground, &gv); return(gv.foreground); } void set_foreground_color(graphics_context *ax, Pixel color) { XSetForeground(MAIN_DISPLAY(ss), ax->gc, color); } GC copy_GC(chan_info *cp) { if (cp->selected) return(ss->selected_basic_gc); return(ss->basic_gc); } GC erase_GC(chan_info *cp) { /* used only to clear partial bgs in chan graphs */ snd_info *sp; sp = cp->sound; if ((cp->selected) || ((sp) && (sp->channel_style == CHANNELS_SUPERIMPOSED) && (sp->index == ss->selected_sound))) return(ss->selected_erase_gc); return(ss->erase_gc); } void free_fft_pix(chan_info *cp) { if ((cp->fft_pix != None) && (channel_graph(cp))) XFreePixmap(XtDisplay(channel_graph(cp)), cp->fft_pix); cp->fft_pix = None; cp->fft_pix_ready = false; } bool restore_fft_pix(chan_info *cp, graphics_context *ax) { XCopyArea(ax->dp, cp->fft_pix, ax->wn, copy_GC(cp), 0, 0, /* source x y */ cp->fft_pix_width, cp->fft_pix_height, cp->fft_pix_x0, cp->fft_pix_y0); return(true); } void save_fft_pix(chan_info *cp, graphics_context *ax, int fwidth, int fheight, int x0, int y1) { if ((fwidth == 0) || (fheight == 0)) return; if (cp->fft_pix == None) { /* make new pixmap */ cp->fft_pix_width = fwidth; cp->fft_pix_height = fheight; cp->fft_pix_x0 = x0; cp->fft_pix_y0 = y1; cp->fft_pix_cutoff = cp->spectrum_end; cp->fft_pix = XCreatePixmap(ax->dp, RootWindowOfScreen(XtScreen(channel_graph(cp))), fwidth, fheight, DefaultDepthOfScreen(XtScreen(channel_graph(cp)))); } XCopyArea(ax->dp, ax->wn, cp->fft_pix, copy_GC(cp), cp->fft_pix_x0, cp->fft_pix_y0, cp->fft_pix_width, cp->fft_pix_height, 0, 0); cp->fft_pix_ready = true; } void cleanup_cw(chan_info *cp) { if (cp) { Widget *cw; free_fft_pix(cp); cp->selected = false; cw = cp->chan_widgets; if (cw) { if (cw[W_w]) { XtVaSetValues(cw[W_w], XmNset, true, NULL); XtVaSetValues(cw[W_f], XmNset, false, NULL); } if (channel_main_pane(cp)) XtUnmanageChild(channel_main_pane(cp)); } } } void change_channel_style(snd_info *sp, channel_style_t new_style) { if ((sp) && (sp->nchans > 1)) { channel_style_t old_style; chan_info *selected_cp; selected_cp = any_selected_channel(sp); /* chan 0 is none is selected */ old_style = sp->channel_style; sp->channel_style = new_style; if (new_style != old_style) { int i, height; #if WITH_RELATIVE_PANES if ((new_style == CHANNELS_SEPARATE) || (old_style == CHANNELS_SEPARATE)) { Widget lst; lst = EDIT_HISTORY_LIST(sp->chans[0]); if ((lst) && (widget_width(lst) > 1)) remake_edit_history(lst, sp->chans[0], true); } #endif if (old_style == CHANNELS_COMBINED) { hide_gz_scrollbars(sp); for (i = 1; i < sp->nchans; i++) channel_set_mix_tags_erased(sp->chans[i]); } else { if (new_style == CHANNELS_COMBINED) { show_gz_scrollbars(sp); for (i = 1; i < sp->nchans; i++) channel_set_mix_tags_erased(sp->chans[i]); } } if (old_style == CHANNELS_SUPERIMPOSED) { syncb(sp, sp->previous_sync); XtVaSetValues(unite_button(sp), XmNselectColor, ss->selection_color, NULL); } else { if (new_style == CHANNELS_SUPERIMPOSED) { sp->previous_sync = sp->sync; if (sp->sync == 0) syncb(sp, 1); XtVaSetValues(unite_button(sp), XmNselectColor, ss->green, NULL); apply_y_axis_change(selected_cp); apply_x_axis_change(selected_cp); for (i = 0; i < sp->nchans; i++) { if (i != selected_cp->chan) { chan_info *ncp; ncp = sp->chans[i]; cursor_sample(ncp) = cursor_sample(selected_cp); if (selected_cp->graph_transform_on != ncp->graph_transform_on) { ncp->graph_transform_on = selected_cp->graph_transform_on; set_toggle_button(channel_f(ncp), selected_cp->graph_transform_on, false, (void *)ncp); } if (selected_cp->graph_time_on != ncp->graph_time_on) { ncp->graph_time_on = selected_cp->graph_time_on; set_toggle_button(channel_w(ncp), selected_cp->graph_time_on, false, (void *)ncp); } } } } } height = widget_height(w_snd_pane(sp)) - control_panel_height(sp); if (old_style == CHANNELS_SEPARATE) { axis_info *ap; ap = selected_cp->axis; channel_lock_pane(sp->chans[0], height); for (i = 0; i < sp->nchans; i++) { if (i != selected_cp->chan) set_axes(sp->chans[i], ap->x0, ap->x1, ap->y0, ap->y1); if (i > 0) cleanup_cw(sp->chans[i]); } channel_open_pane(sp->chans[0]); channel_unlock_pane(sp->chans[0]); XmToggleButtonSetState(unite_button(sp), true, false); } else { if (new_style == CHANNELS_SEPARATE) { /* height = total space available */ height /= sp->nchans; for_each_sound_chan_with_int(sp, channel_lock_pane, height); for_each_sound_chan(sp, channel_open_pane); for_each_sound_chan(sp, channel_unlock_pane); for (i = 1; i < sp->nchans; i++) { Widget *cw; chan_info *cp; int j; cp = sp->chans[i]; cw = cp->chan_widgets; for (j = 0; j < NUM_CHAN_WIDGETS - 1; j++) if ((cw[j]) && (!XtIsManaged(cw[j]))) XtManageChild(cw[j]); XmToggleButtonSetState(cw[W_f], (Boolean)(cp->graph_transform_on), false); XmToggleButtonSetState(cw[W_w], (Boolean)(cp->graph_time_on), false); /* these can get out of sync if changes are made in the unseparated case */ } XmToggleButtonSetState(unite_button(sp), false, false); if (sp->selected_channel > 0) color_selected_channel(sp); } } if ((new_style == CHANNELS_COMBINED) && (sp->selected_channel > 0)) color_selected_channel(sp); } } } static Xen g_channel_widgets(Xen snd, Xen chn) { #define H_channel_widgets "(" S_channel_widgets " :optional snd chn): a list of widgets: ((0)graph (1)w (2)f (3)sx (4)sy (5)zx (6)zy (7)edhist)" chan_info *cp; Snd_assert_channel(S_channel_widgets, snd, chn, 1); cp = get_cp(snd, chn, S_channel_widgets); if (!cp) return(Xen_false); return(Xen_cons(Xen_wrap_widget(channel_graph(cp)), Xen_cons(Xen_wrap_widget(channel_w(cp)), Xen_cons(Xen_wrap_widget(channel_f(cp)), Xen_cons(Xen_wrap_widget(channel_sx(cp)), Xen_cons(Xen_wrap_widget(channel_sy(cp)), Xen_cons(Xen_wrap_widget(channel_zx(cp)), Xen_cons(Xen_wrap_widget(channel_zy(cp)), Xen_cons(Xen_wrap_widget(EDIT_HISTORY_LIST(cp)), Xen_cons(Xen_wrap_widget(channel_gsy(cp)), Xen_cons(Xen_wrap_widget(channel_gzy(cp)), Xen_cons(Xen_wrap_widget(channel_main_pane(cp)), Xen_empty_list)))))))))))); } /* previous snd-xxen.c contents) */ static void timed_eval(XtPointer in_code, XtIntervalId *id) { #if HAVE_EXTENSION_LANGUAGE Xen lst = (XEN)in_code; Xen_call_with_no_args(Xen_cadr(lst), "timed callback func"); snd_unprotect_at(Xen_integer_to_C_int(Xen_car(lst))); #endif } static Xen g_in(Xen ms, Xen code) { #define H_in "(" S_in " msecs thunk): invoke thunk in msecs milliseconds (named call_in in Ruby)" #if HAVE_EXTENSION_LANGUAGE Xen_check_type(Xen_is_number(ms), ms, 1, S_in, "a number"); Xen_check_type(Xen_is_procedure(code), code, 2, S_in, "a procedure"); if (Xen_is_aritable(code, 0)) { int secs; Xen_check_type(Xen_is_integer(ms), ms, 3, S_in, "an integer"); secs = Xen_integer_to_C_int(ms); if (secs < 0) Xen_out_of_range_error(S_in, 1, ms, "a positive integer"); else { Xen lst; lst = Xen_list_2(Xen_false, code); Xen_list_set(lst, 0, C_int_to_Xen_integer(snd_protect(lst))); XtAppAddTimeOut(MAIN_APP(ss), (unsigned long)secs, (XtTimerCallbackProc)timed_eval, (XtPointer)lst); } } else Xen_bad_arity_error(S_in, 2, code, "should take no args"); #endif return(ms); } void color_unselected_graphs(color_t color) { int i; for (i = 0; i < ss->max_sounds; i++) { snd_info *sp; int j; sp = ss->sounds[i]; if ((sp) && (sp->inuse != SOUND_WRAPPER)) for (j = 0; j < sp->allocated_chans; j++) { chan_info *cp; cp = sp->chans[j]; if ((cp) && ((i != ss->selected_sound) || (j != sp->selected_channel))) XtVaSetValues(channel_graph(cp), XmNbackground, color, NULL); } } } void color_chan_components(color_t color, slider_choice_t which_component) { int i; for (i = 0; i < ss->max_sounds; i++) { snd_info *sp; int j; sp = ss->sounds[i]; if ((sp) && (sp->inuse != SOUND_WRAPPER)) for (j = 0; j < sp->allocated_chans; j++) { chan_info *cp; cp = sp->chans[j]; if (cp) { if (which_component == COLOR_POSITION) { XtVaSetValues(channel_sx(cp), XmNbackground, color, NULL); XtVaSetValues(channel_sy(cp), XmNbackground, color, NULL); } else { XtVaSetValues(channel_zy(cp), XmNbackground, color, NULL); XtVaSetValues(channel_zx(cp), XmNbackground, color, NULL); } } } } } static Xen g_graph_cursor(void) { #define H_graph_cursor "(" S_graph_cursor "): current graph cursor shape" return(C_int_to_Xen_integer(in_graph_cursor(ss))); } static Xen g_set_graph_cursor(Xen curs) { int val; Xen_check_type(Xen_is_integer(curs), curs, 1, S_set S_graph_cursor, "an integer"); /* X11/cursorfont.h has various even-numbered glyphs, but the odd numbers are ok, and XC_num_glyphs is a lie */ /* if you use too high a number here, X dies */ val = Xen_integer_to_C_int(curs); if ((val >= 0) && (val <= XC_xterm)) { ss->Graph_Cursor = val; ss->graph_cursor = XCreateFontCursor(XtDisplay(MAIN_SHELL(ss)), in_graph_cursor(ss)); } else Xen_out_of_range_error(S_set S_graph_cursor, 1, curs, "invalid cursor"); return(curs); } Xen_wrap_2_args(g_in_w, g_in) Xen_wrap_no_args(g_graph_cursor_w, g_graph_cursor) Xen_wrap_1_arg(g_set_graph_cursor_w, g_set_graph_cursor) Xen_wrap_2_optional_args(g_channel_widgets_w, g_channel_widgets) #if HAVE_SCHEME static s7_pointer acc_graph_cursor(s7_scheme *sc, s7_pointer args) {return(g_set_graph_cursor(s7_cadr(args)));} #endif void g_init_gxchn(void) { Xen_define_procedure(S_in, g_in_w, 2, 0, 0, H_in); Xen_define_dilambda(S_graph_cursor, g_graph_cursor_w, H_graph_cursor, S_set S_graph_cursor, g_set_graph_cursor_w, 0, 0, 1, 0); Xen_define_safe_procedure(S_channel_widgets, g_channel_widgets_w, 0, 2, 0, H_channel_widgets); #if HAVE_SCHEME #define H_mouse_enter_graph_hook S_mouse_enter_graph_hook " (snd chn): called when the mouse \ enters the drawing area (graph pane) of the given channel.\n\ (hook-push " S_mouse_enter_graph_hook "\n\ (lambda (hook)\n\ (" S_focus_widget " (car (" S_channel_widgets " (hook 'snd) (hook 'chn))))))" #define H_mouse_leave_graph_hook S_mouse_leave_graph_hook " (snd chn): is called when the mouse \ leaves the drawing area (graph pane) of the given channel." #endif #if HAVE_RUBY #define H_mouse_enter_graph_hook S_mouse_enter_graph_hook " (snd chn): called when the mouse \ enters the drawing area (graph pane) of the given channel.\n\ $mouse_enter_graph_hook.add-hook!(\"focus\") do |snd chn|\n\ focus_widget(channel_widgets(snd, chn)[0])\n\ end" #define H_mouse_leave_graph_hook S_mouse_leave_graph_hook " (snd chn): called when the mouse \ leaves the drawing area (graph pane) of the given channel." #endif #if HAVE_FORTH #define H_mouse_enter_graph_hook S_mouse_enter_graph_hook " (snd chn): called when the mouse \ enters the drawing area (graph pane) of the given channel.\n\ " S_mouse_enter_graph_hook " lambda: <{ snd chn }>\n\ snd chn " S_channel_widgets " car " S_focus_widget "\n\ ; add-hook!" #define H_mouse_leave_graph_hook S_mouse_leave_graph_hook " (snd chn): is called when the mouse \ leaves the drawing area (graph pane) of the given channel." #endif mouse_enter_graph_hook = Xen_define_hook(S_mouse_enter_graph_hook, "(make-hook 'snd 'chn)", 2, H_mouse_enter_graph_hook); mouse_leave_graph_hook = Xen_define_hook(S_mouse_leave_graph_hook, "(make-hook 'snd 'chn)", 2, H_mouse_leave_graph_hook); #if HAVE_SCHEME s7_symbol_set_access(s7, ss->graph_cursor_symbol, s7_make_function(s7, "[acc-" S_graph_cursor "]", acc_graph_cursor, 2, 0, false, "accessor")); s7_symbol_set_documentation(s7, ss->graph_cursor_symbol, "*graph-cursor*: current graph cursor shape"); #endif } #include #define sound_env_editor(Sp) ((env_editor *)(sp->flt)) #define TOGGLE_MARGIN 0 enum {W_pane, W_name_form, W_amp_form, W_amp, W_amp_label, W_amp_number, W_speed, W_speed_label, W_speed_number, W_speed_arrow, W_expand, W_expand_label, W_expand_number, W_expand_button, W_contrast, W_contrast_label, W_contrast_number, W_contrast_button, W_revscl, W_revscl_label, W_revscl_number, W_revlen, W_revlen_label, W_revlen_number, W_reverb_button, W_filter_label, W_filter_order, W_filter_env, W_filter, W_filter_button, W_filter_dB, W_filter_hz, W_filter_frame, W_filter_order_down, W_filter_order_up, W_name, W_lock_or_bomb, W_stop_icon, W_info, W_play, W_sync, W_unite, W_close, NUM_SND_WIDGETS }; Widget unite_button(snd_info *sp) {return(sp->snd_widgets[W_unite]);} Widget w_snd_pane(snd_info *sp) {return(sp->snd_widgets[W_pane]);} #define SND_PANE(Sp) Sp->snd_widgets[W_pane] #define SND_NAME(Sp) Sp->snd_widgets[W_name] #define NAME_BOX(Sp) Sp->snd_widgets[W_name_form] #define LOCK_OR_BOMB(Sp) Sp->snd_widgets[W_lock_or_bomb] #define STOP_ICON(Sp) Sp->snd_widgets[W_stop_icon] #define NAME_LABEL(Sp) Sp->snd_widgets[W_name] #define STATUS_AREA(Sp) Sp->snd_widgets[W_info] #define SYNC_BUTTON(Sp) Sp->snd_widgets[W_sync] #define PLAY_BUTTON(Sp) Sp->snd_widgets[W_play] #define UNITE_BUTTON(Sp) Sp->snd_widgets[W_unite] #define CLOSE_BUTTON(Sp) Sp->snd_widgets[W_close] #define CONTROLS(Sp) Sp->snd_widgets[W_amp_form] #define AMP_SCROLLBAR(Sp) Sp->snd_widgets[W_amp] #define AMP_LABEL(Sp) Sp->snd_widgets[W_amp_number] #define AMP_BUTTON(Sp) Sp->snd_widgets[W_amp_label] #define SPEED_SCROLLBAR(Sp) Sp->snd_widgets[W_speed] #define SPEED_ARROW(Sp) Sp->snd_widgets[W_speed_arrow] #define SPEED_LABEL(Sp) Sp->snd_widgets[W_speed_number] #define SPEED_BUTTON(Sp) Sp->snd_widgets[W_speed_label] #define EXPAND_SCROLLBAR(Sp) Sp->snd_widgets[W_expand] #define EXPAND_LABEL(Sp) Sp->snd_widgets[W_expand_number] #define EXPAND_RIGHT_BUTTON(Sp) Sp->snd_widgets[W_expand_button] #define EXPAND_LEFT_BUTTON(Sp) Sp->snd_widgets[W_expand_label] #define CONTRAST_SCROLLBAR(Sp) Sp->snd_widgets[W_contrast] #define CONTRAST_LABEL(Sp) Sp->snd_widgets[W_contrast_number] #define CONTRAST_RIGHT_BUTTON(Sp) Sp->snd_widgets[W_contrast_button] #define CONTRAST_LEFT_BUTTON(Sp) Sp->snd_widgets[W_contrast_label] #define REVSCL_SCROLLBAR(Sp) Sp->snd_widgets[W_revscl] #define REVLEN_SCROLLBAR(Sp) Sp->snd_widgets[W_revlen] #define REVSCL_LABEL(Sp) Sp->snd_widgets[W_revscl_number] #define REVLEN_LABEL(Sp) Sp->snd_widgets[W_revlen_number] #define REVSCL_BUTTON(Sp) Sp->snd_widgets[W_revscl_label] #define REVLEN_BUTTON(Sp) Sp->snd_widgets[W_revlen_label] #define REVERB_BUTTON(Sp) Sp->snd_widgets[W_reverb_button] #define FILTER_ORDER_TEXT(Sp) Sp->snd_widgets[W_filter_order] #define FILTER_COEFFS_TEXT(Sp) Sp->snd_widgets[W_filter] #define FILTER_BUTTON(Sp) Sp->snd_widgets[W_filter_button] #define FILTER_DB_BUTTON(Sp) Sp->snd_widgets[W_filter_dB] #define FILTER_HZ_BUTTON(Sp) Sp->snd_widgets[W_filter_hz] #define FILTER_LABEL(Sp) Sp->snd_widgets[W_filter_label] #define FILTER_GRAPH(Sp) Sp->snd_widgets[W_filter_env] #define FILTER_ORDER_UP(Sp) Sp->snd_widgets[W_filter_order_up] #define FILTER_ORDER_DOWN(Sp) Sp->snd_widgets[W_filter_order_down] #define FILTER_FRAME(Sp) Sp->snd_widgets[W_filter_frame] #define PROGRESS_ICON(Cp) (Cp)->sound->progress_widgets[(Cp)->chan] int snd_pane_height(snd_info *sp) { Dimension height; XtVaGetValues(SND_PANE(sp), XmNheight, &height, NULL); return((int)height); } void set_status(snd_info *sp, const char *str, bool update) { if ((sp->inuse != SOUND_NORMAL) || (!has_widgets(sp))) return; XmTextSetString(STATUS_AREA(sp), (char *)str); /* updating clears the entire graph widget and triggers an expose event -- this is evil if we're currently displaying! */ /* there's also a bug in libxcb (fixed, but not propagated yet) that causes a segfault here if more than * one thread is affected by this global X queue flush. */ if (update) XmUpdateDisplay(STATUS_AREA(sp)); } static void name_click_callback(Widget w, XtPointer context, XtPointer info) { char *str; snd_info *sp = (snd_info *)context; str = sp_name_click(sp); if (str) { status_report(sp, "%s", str); free(str); } } static void stop_sign_click_callback(Widget w, XtPointer context, XtPointer info) { snd_info *sp = (snd_info *)context; if ((ss->checking_explicitly) || (play_in_progress())) ss->stopped_explicitly = true; stop_playing_all_sounds(PLAY_C_G); if (sp->applying) stop_applying(sp); for_each_sound_chan(sp, stop_fft_in_progress); } /* The 0.9 * SCROLLBAR_MAX reflects the fact that the slider is 10% of the trough, and the left edge of the slider is the readback value */ /* ---------------- AMP-CONTROL ---------------- */ int amp_to_scroll(mus_float_t minval, mus_float_t val, mus_float_t maxval) { if (val <= minval) return(0); if (val >= maxval) return((int)(0.9 * SCROLLBAR_MAX)); if (val >= 1.0) return(snd_round(0.9 * 0.5 * SCROLLBAR_MAX * (1.0 + (val - 1.0) / (maxval - 1.0)))); return(snd_round(0.9 * 0.5 * SCROLLBAR_MAX * ((val - minval) / (1.0 - minval)))); } static int scroll_to_amp(snd_info *sp, int val) { char amp_number_buffer[6]; if (val <= 0) sp->amp_control = sp->amp_control_min; else { if (val >= (0.9 * SCROLLBAR_MAX)) sp->amp_control = sp->amp_control_max; else { if (val > (0.5 * 0.9 * SCROLLBAR_MAX)) sp->amp_control = (((val / (0.5 * 0.9 * SCROLLBAR_MAX)) - 1.0) * (sp->amp_control_max - 1.0)) + 1.0; else sp->amp_control = (val * (1.0 - sp->amp_control_min) / (0.5 * 0.9 * SCROLLBAR_MAX)) + sp->amp_control_min; } } snprintf(amp_number_buffer, 6, "%.3f", sp->amp_control); set_label(AMP_LABEL(sp), amp_number_buffer); return(val); } void set_amp(snd_info *sp, mus_float_t val) { if (!has_widgets(sp)) sp->amp_control = val; else XtVaSetValues(AMP_SCROLLBAR(sp), XmNvalue, scroll_to_amp(sp, amp_to_scroll(sp->amp_control_min, val, sp->amp_control_max)), NULL); } static void amp_click_callback(Widget w, XtPointer context, XtPointer info) { XmPushButtonCallbackStruct *cb = (XmPushButtonCallbackStruct *)info; snd_info *sp = (snd_info *)context; XButtonEvent *ev; ev = (XButtonEvent *)(cb->event); if (ev->state & (snd_ControlMask | snd_MetaMask)) set_amp(sp, sp->last_amp_control); else set_amp(sp, 1.0); } static void amp_drag_callback(Widget w, XtPointer context, XtPointer info) { scroll_to_amp((snd_info *)context, ((XmScrollBarCallbackStruct *)info)->value); } static void amp_valuechanged_callback(Widget w, XtPointer context, XtPointer info) { XmScrollBarCallbackStruct *cb = (XmScrollBarCallbackStruct *)info; snd_info *sp = (snd_info *)context; scroll_to_amp(sp, cb->value); sp->last_amp_control = sp->saved_amp_control; sp->saved_amp_control = sp->amp_control; } /* ---------------- SPEED-CONTROL ---------------- */ XmString initial_speed_label(speed_style_t style) { /* used also in snd-xmix.c */ switch (style) { case SPEED_CONTROL_AS_RATIO: return(XmStringCreateLocalized((char *)" 1/1")); break; case SPEED_CONTROL_AS_SEMITONE: return(XmStringCreateLocalized((char *)" 0")); break; default: return(XmStringCreateLocalized((char *)" 1.00")); break; } } static int speed_to_scroll(mus_float_t minval, mus_float_t val, mus_float_t maxval) { if (val <= minval) return(0); if (val >= maxval) return((int)(0.9 * SCROLLBAR_MAX)); return(snd_round(0.9 * SCROLLBAR_MAX * ((log(val) - log(minval)) / (log(maxval) - log(minval))))); } static int scroll_to_speed(snd_info *sp, int ival) { char speed_number_buffer[6]; sp->speed_control = speed_changed(exp((ival * (log(sp->speed_control_max) - log(sp->speed_control_min)) / (0.9 * SCROLLBAR_MAX)) + log(sp->speed_control_min)), speed_number_buffer, sp->speed_control_style, sp->speed_control_tones, 6); set_label(SPEED_LABEL(sp), speed_number_buffer); /* set_label works with buttons or labels */ return(ival); } void set_speed(snd_info *sp, mus_float_t val) { if (!has_widgets(sp)) sp->speed_control = val; else XtVaSetValues(SPEED_SCROLLBAR(sp), XmNvalue, scroll_to_speed(sp, speed_to_scroll(sp->speed_control_min, val, sp->speed_control_max)), NULL); } static void speed_click_callback(Widget w, XtPointer context, XtPointer info) { XmPushButtonCallbackStruct *cb = (XmPushButtonCallbackStruct *)info; snd_info *sp = (snd_info *)context; XButtonEvent *ev; ev = (XButtonEvent *)(cb->event); if (ev->state & (snd_ControlMask | snd_MetaMask)) set_speed(sp, sp->last_speed_control); else set_speed(sp, 1.0); #if XEN_HAVE_RATIOS if (sp->speed_control_style == SPEED_CONTROL_AS_RATIO) snd_rationalize(sp->speed_control, &(sp->speed_control_numerator), &(sp->speed_control_denominator)); #endif } static void speed_label_click_callback(Widget w, XtPointer context, XtPointer info) { snd_info *sp = (snd_info *)context; switch (sp->speed_control_style) { default: case SPEED_CONTROL_AS_FLOAT: sp->speed_control_style = SPEED_CONTROL_AS_RATIO; break; case SPEED_CONTROL_AS_RATIO: sp->speed_control_style = SPEED_CONTROL_AS_SEMITONE; break; case SPEED_CONTROL_AS_SEMITONE: sp->speed_control_style = SPEED_CONTROL_AS_FLOAT; break; } set_speed(sp, sp->speed_control); /* remake label */ } static void speed_drag_callback(Widget w, XtPointer context, XtPointer info) { snd_info *sp = (snd_info *)context; scroll_to_speed(sp, ((XmScrollBarCallbackStruct *)info)->value); #if XEN_HAVE_RATIOS if (sp->speed_control_style == SPEED_CONTROL_AS_RATIO) snd_rationalize(sp->speed_control, &(sp->speed_control_numerator), &(sp->speed_control_denominator)); #endif } static void speed_valuechanged_callback(Widget w, XtPointer context, XtPointer info) { XmScrollBarCallbackStruct *cb = (XmScrollBarCallbackStruct *)info; snd_info *sp = (snd_info *)context; scroll_to_speed(sp, cb->value); #if XEN_HAVE_RATIOS if (sp->speed_control_style == SPEED_CONTROL_AS_RATIO) snd_rationalize(sp->speed_control, &(sp->speed_control_numerator), &(sp->speed_control_denominator)); #endif sp->last_speed_control = sp->saved_speed_control; sp->saved_speed_control = sp->speed_control; } void toggle_direction_arrow(snd_info *sp, bool state) { if (!has_widgets(sp)) sp->speed_control_direction = ((state) ? -1 : 1); else XmToggleButtonSetState(SPEED_ARROW(sp), (Boolean)state, true); } /* ---------------- EXPAND-CONTROL ---------------- */ static int expand_to_scroll(mus_float_t minval, mus_float_t val, mus_float_t maxval) { if (val <= minval) return(0); if (val >= maxval) return((int)(0.9 * SCROLLBAR_MAX)); return(snd_round(0.9 * SCROLLBAR_MAX * ((log(val) - log(minval)) / (log(maxval) - log(minval))))); } static int scroll_to_expand(snd_info *sp, int val) { char expand_number_buffer[6]; if (val <= 0) sp->expand_control = sp->expand_control_min; else { if (val >= (0.9 * SCROLLBAR_MAX)) sp->expand_control = sp->expand_control_max; else sp->expand_control = exp((val * (log(sp->expand_control_max) - log(sp->expand_control_min)) / (0.9 * SCROLLBAR_MAX)) + log(sp->expand_control_min)); } if (sp->playing) dac_set_expand(sp, sp->expand_control); snprintf(expand_number_buffer, 6, "%.3f", sp->expand_control); set_label(EXPAND_LABEL(sp), expand_number_buffer); return(val); } void set_expand(snd_info *sp, mus_float_t val) { if (!has_widgets(sp)) sp->expand_control = val; else XtVaSetValues(EXPAND_SCROLLBAR(sp), XmNvalue, scroll_to_expand(sp, expand_to_scroll(sp->expand_control_min, val, sp->expand_control_max)), NULL); } static void expand_click_callback(Widget w, XtPointer context, XtPointer info) { XmPushButtonCallbackStruct *cb = (XmPushButtonCallbackStruct *)info; snd_info *sp = (snd_info *)context; XButtonEvent *ev; ev = (XButtonEvent *)(cb->event); if (ev->state & (snd_ControlMask | snd_MetaMask)) set_expand(sp, sp->last_expand_control); else set_expand(sp, 1.0); } static void expand_drag_callback(Widget w, XtPointer context, XtPointer info) { scroll_to_expand((snd_info *)context, ((XmScrollBarCallbackStruct *)info)->value); } static void expand_valuechanged_callback(Widget w, XtPointer context, XtPointer info) { XmScrollBarCallbackStruct *cb = (XmScrollBarCallbackStruct *)info; snd_info *sp = (snd_info *)context; scroll_to_expand(sp, cb->value); sp->last_expand_control = sp->saved_expand_control; sp->saved_expand_control = sp->expand_control; } static void expand_button_callback(Widget w, XtPointer context, XtPointer info) { XmToggleButtonCallbackStruct *cb = (XmToggleButtonCallbackStruct *)info; snd_info *sp = (snd_info *)context; sp->expand_control_on = cb->set; XmChangeColor(EXPAND_SCROLLBAR(sp), (Pixel)((sp->expand_control_on) ? (ss->position_color) : (ss->basic_color))); } void toggle_expand_button(snd_info *sp, bool state) { if (!has_widgets(sp)) sp->expand_control_on = state; else XmToggleButtonSetState(EXPAND_RIGHT_BUTTON(sp), (Boolean)state, true); } /* ---------------- CONTRAST-CONTROL ---------------- */ static int contrast_to_scroll(mus_float_t minval, mus_float_t val, mus_float_t maxval) { if (val <= minval) return(0); if (val >= maxval) return((int)(0.9 * SCROLLBAR_MAX)); return(snd_round((val - minval) / (maxval - minval) * 0.9 * SCROLLBAR_MAX)); } static int scroll_to_contrast(snd_info *sp, int val) { char contrast_number_buffer[6]; sp->contrast_control = sp->contrast_control_min + val * (sp->contrast_control_max - sp->contrast_control_min) / (0.9 * SCROLLBAR_MAX); snprintf(contrast_number_buffer, 6, "%.3f", sp->contrast_control); set_label(CONTRAST_LABEL(sp), contrast_number_buffer); return(val); } void set_contrast(snd_info *sp, mus_float_t val) { if (!has_widgets(sp)) sp->contrast_control = val; else XtVaSetValues(CONTRAST_SCROLLBAR(sp), XmNvalue, scroll_to_contrast(sp, contrast_to_scroll(sp->contrast_control_min, val, sp->contrast_control_max)), NULL); } static void contrast_click_callback(Widget w, XtPointer context, XtPointer info) { XmPushButtonCallbackStruct *cb = (XmPushButtonCallbackStruct *)info; snd_info *sp = (snd_info *)context; XButtonEvent *ev; ev = (XButtonEvent *)(cb->event); if (ev->state & (snd_ControlMask | snd_MetaMask)) set_contrast(sp, sp->last_contrast_control); else set_contrast(sp, 0.0); } static void contrast_drag_callback(Widget w, XtPointer context, XtPointer info) { scroll_to_contrast((snd_info *)context, ((XmScrollBarCallbackStruct *)info)->value); } static void contrast_valuechanged_callback(Widget w, XtPointer context, XtPointer info) { XmScrollBarCallbackStruct *cb = (XmScrollBarCallbackStruct *)info; snd_info *sp = (snd_info *)context; scroll_to_contrast(sp, cb->value); sp->last_contrast_control = sp->saved_contrast_control; sp->saved_contrast_control = sp->contrast_control; } static void contrast_button_callback(Widget w, XtPointer context, XtPointer info) { snd_info *sp = (snd_info *)context; XmToggleButtonCallbackStruct *cb = (XmToggleButtonCallbackStruct *)info; sp->contrast_control_on = cb->set; XmChangeColor(CONTRAST_SCROLLBAR(sp), (Pixel)((sp->contrast_control_on) ? (ss->position_color) : (ss->basic_color))); } void toggle_contrast_button(snd_info *sp, bool state) { if (!has_widgets(sp)) sp->contrast_control_on = state; else XmToggleButtonSetState(CONTRAST_RIGHT_BUTTON(sp), (Boolean)state, true); } /* ---------------- REVERB-CONTROL-SCALE ---------------- */ static int revscl_to_scroll(mus_float_t minval, mus_float_t val, mus_float_t maxval) { if (val <= minval) return(0); if (val >= maxval) return((int)(0.9 * SCROLLBAR_MAX)); return(snd_round(0.9 * SCROLLBAR_MAX * (pow(val, 0.333) - pow(minval, 0.333)) / (pow(maxval, 0.333) - pow(minval, 0.333)))); } /* static mus_float_t cube(mus_float_t a) {return(a*a*a);} */ static int scroll_to_revscl(snd_info *sp, int val) { char revscl_number_buffer[7]; if (val <= 0) sp->reverb_control_scale = sp->reverb_control_scale_min; else { if (val >= (0.9 * SCROLLBAR_MAX)) sp->reverb_control_scale = sp->reverb_control_scale_max; else sp->reverb_control_scale = cube((val * (pow(sp->reverb_control_scale_max, 0.333) - pow(sp->reverb_control_scale_min, 0.333)) / (0.9 * SCROLLBAR_MAX)) + pow(sp->reverb_control_scale_min, 0.333)); } snprintf(revscl_number_buffer, 7, "%.4f", sp->reverb_control_scale); set_label(REVSCL_LABEL(sp), revscl_number_buffer); return(val); } void set_revscl(snd_info *sp, mus_float_t val) { if (!has_widgets(sp)) sp->reverb_control_scale = val; else XtVaSetValues(REVSCL_SCROLLBAR(sp), XmNvalue, scroll_to_revscl(sp, revscl_to_scroll(sp->reverb_control_scale_min, val, sp->reverb_control_scale_max)), NULL); } static void revscl_click_callback(Widget w, XtPointer context, XtPointer info) { XmPushButtonCallbackStruct *cb = (XmPushButtonCallbackStruct *)info; snd_info *sp = (snd_info *)context; XButtonEvent *ev; ev = (XButtonEvent *)(cb->event); if (ev->state & (snd_ControlMask | snd_MetaMask)) set_revscl(sp, sp->last_reverb_control_scale); else set_revscl(sp, 0.0); } static void revscl_drag_callback(Widget w, XtPointer context, XtPointer info) { scroll_to_revscl((snd_info *)context, ((XmScrollBarCallbackStruct *)info)->value); } static void revscl_valuechanged_callback(Widget w, XtPointer context, XtPointer info) { XmScrollBarCallbackStruct *cb = (XmScrollBarCallbackStruct *)info; snd_info *sp = (snd_info *)context; scroll_to_revscl(sp, cb->value); sp->last_reverb_control_scale = sp->saved_reverb_control_scale; sp->saved_reverb_control_scale = sp->reverb_control_scale; } /* ---------------- REVERB-CONTROL-LENGTH ---------------- */ static int revlen_to_scroll(mus_float_t minval, mus_float_t val, mus_float_t maxval) { if (val <= minval) return(0); if (val >= maxval) return((int)(0.9 * SCROLLBAR_MAX)); return(snd_round((val - minval) / (maxval - minval) * 0.9 * SCROLLBAR_MAX)); } static int scroll_to_revlen(snd_info *sp, int val) { char revlen_number_buffer[5]; sp->reverb_control_length = sp->reverb_control_length_min + (sp->reverb_control_length_max - sp->reverb_control_length_min) * (mus_float_t)val / (0.9 * SCROLLBAR_MAX); snprintf(revlen_number_buffer, 5, "%.2f", sp->reverb_control_length); set_label(REVLEN_LABEL(sp), revlen_number_buffer); return(val); } void set_revlen(snd_info *sp, mus_float_t val) { if (!has_widgets(sp)) sp->reverb_control_length = val; else XtVaSetValues(REVLEN_SCROLLBAR(sp), XmNvalue, scroll_to_revlen(sp, revlen_to_scroll(sp->reverb_control_length_min, val, sp->reverb_control_length_max)), NULL); } static void revlen_click_callback(Widget w, XtPointer context, XtPointer info) { XmPushButtonCallbackStruct *cb = (XmPushButtonCallbackStruct *)info; snd_info *sp = (snd_info *)context; XButtonEvent *ev; ev = (XButtonEvent *)(cb->event); if (ev->state & (snd_ControlMask | snd_MetaMask)) set_revlen(sp, sp->last_reverb_control_length); else set_revlen(sp, 1.0); } static void revlen_drag_callback(Widget w, XtPointer context, XtPointer info) { scroll_to_revlen((snd_info *)context, ((XmScrollBarCallbackStruct *)info)->value); } static void revlen_valuechanged_callback(Widget w, XtPointer context, XtPointer info) { XmScrollBarCallbackStruct *cb = (XmScrollBarCallbackStruct *)info; snd_info *sp = (snd_info *)context; scroll_to_revlen(sp, cb->value); sp->last_reverb_control_length = sp->saved_reverb_control_length; sp->saved_reverb_control_length = sp->reverb_control_length; } static void reverb_button_callback(Widget w, XtPointer context, XtPointer info) { snd_info *sp = (snd_info *)context; XmToggleButtonCallbackStruct *cb = (XmToggleButtonCallbackStruct *)info; sp->reverb_control_on = cb->set; XmChangeColor(REVLEN_SCROLLBAR(sp), (Pixel)((sp->reverb_control_on) ? (ss->position_color) : (ss->basic_color))); XmChangeColor(REVSCL_SCROLLBAR(sp), (Pixel)((sp->reverb_control_on) ? (ss->position_color) : (ss->basic_color))); } void toggle_reverb_button(snd_info *sp, bool state) { if (!has_widgets(sp)) sp->reverb_control_on = state; else XmToggleButtonSetState(REVERB_BUTTON(sp), (Boolean)state, true); } /* ---------------- FILTER_CONTROL ---------------- */ static void filter_button_callback(Widget w, XtPointer context, XtPointer info) { snd_info *sp = (snd_info *)context; XmToggleButtonCallbackStruct *cb = (XmToggleButtonCallbackStruct *)info; sp->filter_control_on = cb->set; } void toggle_filter_button(snd_info *sp, bool state) { if (!has_widgets(sp)) sp->filter_control_on = state; else XmToggleButtonSetState(FILTER_BUTTON(sp), (Boolean)state, true); } static void filter_textfield_deactivate(snd_info *sp) { chan_info *active_chan; active_chan = any_selected_channel(sp); if (active_chan) goto_window(channel_graph(active_chan)); } #define MIN_FILTER_GRAPH_HEIGHT 20 void display_filter_env(snd_info *sp) { graphics_context *ax; int height, width; Widget drawer; env_editor *edp; if (!(snd_ok(sp))) return; /* autotest close + lagging X updates */ edp = sp->flt; drawer = FILTER_GRAPH(sp); height = widget_height(drawer); if (height < MIN_FILTER_GRAPH_HEIGHT) return; width = widget_width(drawer); ax = (graphics_context *)calloc(1, sizeof(graphics_context)); ax->gc = ss->fltenv_basic_gc; ax->wn = XtWindow(drawer); ax->dp = XtDisplay(drawer); XClearWindow(ax->dp, ax->wn); edp->in_dB = sp->filter_control_in_dB; edp->with_dots = true; if (sp->filter_control_in_hz) sp->filter_control_xmax = (mus_float_t)(snd_srate(sp) / 2); else sp->filter_control_xmax = 1.0; if (sp->filter_control_envelope == NULL) sp->filter_control_envelope = default_env(sp->filter_control_xmax, 1.0); env_editor_display_env(edp, sp->filter_control_envelope, ax, "frequency response", 0, 0, width, height, NOT_PRINTING); if (edp->edited) { ax->gc = ss->fltenv_data_gc; display_frequency_response(sp->filter_control_envelope, (sound_env_editor(sp))->axis, ax, sp->filter_control_order, sp->filter_control_in_dB); } free(ax); } void set_filter_text(snd_info *sp, const char *str) { if (has_widgets(sp)) XmTextSetString(FILTER_COEFFS_TEXT(sp), (char *)str); } static void filter_drawer_button_motion(Widget w, XtPointer context, XEvent *event, Boolean *cont) { snd_info *sp = (snd_info *)context; XMotionEvent *ev = (XMotionEvent *)event; env_editor *edp; #ifdef __APPLE__ if ((press_x == ev->x) && (press_y == ev->y)) return; #endif edp = sp->flt; edp->in_dB = sp->filter_control_in_dB; env_editor_button_motion(edp, ev->x, ev->y, ev->time, sp->filter_control_envelope); display_filter_env(sp); sp->filter_control_changed = true; } static void filter_drawer_button_press(Widget w, XtPointer context, XEvent *event, Boolean *cont) { snd_info *sp = (snd_info *)context; XButtonEvent *ev = (XButtonEvent *)event; env_editor *edp; if (!(sp->filter_control_envelope)) return; #ifdef __APPLE__ press_x = ev->x; press_y = ev->y; #endif edp = sp->flt; edp->in_dB = sp->filter_control_in_dB; if (env_editor_button_press(edp, ev->x, ev->y, ev->time, sp->filter_control_envelope)) display_filter_env(sp); } static void filter_drawer_button_release(Widget w, XtPointer context, XEvent *event, Boolean *cont) { char *tmpstr = NULL; snd_info *sp = (snd_info *)context; env_editor_button_release(sound_env_editor(sp), sp->filter_control_envelope); display_filter_env(sp); set_filter_text(sp, tmpstr = env_to_string(sp->filter_control_envelope)); if (tmpstr) free(tmpstr); sp->filter_control_changed = true; } static void filter_drawer_resize(Widget w, XtPointer context, XtPointer info) { snd_info *sp = (snd_info *)context; display_filter_env(sp); } static void filter_dB_callback(Widget w, XtPointer context, XtPointer info) { snd_info *sp = (snd_info *)context; XmToggleButtonCallbackStruct *cb = (XmToggleButtonCallbackStruct *)info; sp->filter_control_in_dB = (cb->set); display_filter_env(sp); } void set_filter_in_dB(snd_info *sp, bool val) { sp->filter_control_in_dB = val; if (has_widgets(sp)) { XmToggleButtonSetState(FILTER_DB_BUTTON(sp), (Boolean)val, false); display_filter_env(sp); } } static void new_in_hz(snd_info *sp, bool val) { sp->filter_control_in_hz = val; if (val) sp->filter_control_xmax = (mus_float_t)(snd_srate(sp) / 2); else sp->filter_control_xmax = 1.0; if (sp->filter_control_envelope) free_env(sp->filter_control_envelope); sp->filter_control_envelope = default_env(sp->filter_control_xmax, 1.0); } static void filter_hz_callback(Widget w, XtPointer context, XtPointer info) { snd_info *sp = (snd_info *)context; XmToggleButtonCallbackStruct *cb = (XmToggleButtonCallbackStruct *)info; new_in_hz(sp, cb->set); display_filter_env(sp); } void set_filter_in_hz(snd_info *sp, bool val) { new_in_hz(sp, val); if (has_widgets(sp)) { XmToggleButtonSetState(FILTER_HZ_BUTTON(sp), (Boolean)val, false); display_filter_env(sp); } } void set_filter_order(snd_info *sp, int order) { if (order & 1) order++; if (order <= 0) order = 2; sp->filter_control_order = order; if (has_widgets(sp)) { widget_int_to_text(FILTER_ORDER_TEXT(sp), order); display_filter_env(sp); } sp->filter_control_changed = true; } static void filter_order_up_callback(Widget w, XtPointer context, XtPointer info) { snd_info *sp = (snd_info *)context; set_filter_order(sp, sp->filter_control_order + 2); } static void filter_order_down_callback(Widget w, XtPointer context, XtPointer info) { snd_info *sp = (snd_info *)context; if (sp->filter_control_order > 2) set_filter_order(sp, sp->filter_control_order - 2); } static void get_filter_order(snd_info *sp, char *str) { int order; redirect_errors_to(errors_to_status_area, (void *)sp); order = string_to_int(str, 1, "filter order"); redirect_errors_to(NULL, NULL); if (order & 1) order++; if (order <= 0) order = 2; sp->filter_control_order = order; } static void filter_activate_callback(Widget w, XtPointer context, XtPointer info) { /* make an envelope out of the data */ snd_info *sp = (snd_info *)context; char *str = NULL; str = XmTextGetString(w); if (sp->filter_control_envelope) sp->filter_control_envelope = free_env(sp->filter_control_envelope); redirect_errors_to(errors_to_status_area, (void *)sp); sp->filter_control_envelope = string_to_env((const char *)str); redirect_errors_to(NULL, NULL); if (str) XtFree(str); if (!(sp->filter_control_envelope)) /* maybe user cleared text field? */ sp->filter_control_envelope = default_env(sp->filter_control_xmax, 1.0); str = XmTextGetString(FILTER_ORDER_TEXT(sp)); if ((str) && (*str)) { get_filter_order(sp, str); XtFree(str); } (sound_env_editor(sp))->edited = true; display_filter_env(sp); filter_textfield_deactivate(sp); sp->filter_control_changed = true; } static void filter_order_activate_callback(Widget w, XtPointer context, XtPointer info) { char *str; snd_info *sp = (snd_info *)context; str = XmTextGetString(w); if ((str) && (*str)) { get_filter_order(sp, str); sp->filter_control_changed = true; display_filter_env(sp); XtFree(str); } filter_textfield_deactivate(sp); } void filter_env_changed(snd_info *sp, env *e) { /* turn e back into a string for textfield widget */ if (has_widgets(sp)) { char *tmpstr = NULL; XmTextSetString(FILTER_COEFFS_TEXT(sp), tmpstr = env_to_string(e)); if (tmpstr) free(tmpstr); (sound_env_editor(sp))->edited = true; display_filter_env(sp); } sp->filter_control_changed = true; } /* ---------------- PLAY BUTTON ---------------- */ void set_play_button(snd_info *sp, bool val) { #if WITH_AUDIO if (has_widgets(sp)) XmToggleButtonSetState(PLAY_BUTTON(sp), (Boolean)val, false); set_open_file_play_button(val); #endif } #if WITH_AUDIO static void play_button_callback(Widget w, XtPointer context, XtPointer info) { snd_info *sp = (snd_info *)context; chan_info *cp; XmToggleButtonCallbackStruct *cb = (XmToggleButtonCallbackStruct *)info; XButtonEvent *ev; ev = (XButtonEvent *)(cb->event); if (sp->playing) stop_playing_sound(sp, PLAY_BUTTON_UNSET); ss->tracking = ((with_tracking_cursor(ss) != DONT_TRACK) || ((cb->set) && (ev->state & (snd_ControlMask | snd_MetaMask)))); cp = any_selected_channel(sp); goto_graph(cp); if (cb->set) { XtVaSetValues(w, XmNselectColor, (ss->tracking) ? ss->green : ss->selection_color, NULL); play_sound(sp, 0, NO_END_SPECIFIED); } } #endif typedef struct {bool pausing; } pause_data; #if WITH_AUDIO static void set_play_button_pause(snd_info *sp, void *ptr) { if ((sp->playing) && (has_widgets(sp))) { pause_data *pd = (pause_data *)ptr; Widget w; w = PLAY_BUTTON(sp); if (pd->pausing) XtVaSetValues(w, XmNselectColor, ss->red, NULL); else XtVaSetValues(w, XmNselectColor, (ss->tracking) ? ss->green : ss->selection_color, NULL); } } #endif void play_button_pause(bool pausing) { #if WITH_AUDIO pause_data *pd; pd = (pause_data *)calloc(1, sizeof(pause_data)); pd->pausing = pausing; for_each_sound_with_void(set_play_button_pause, (void *)pd); free(pd); #endif } void set_control_panel_play_button(snd_info *sp) { #if WITH_AUDIO if (has_widgets(sp)) { set_toggle_button(PLAY_BUTTON(sp), false, false, sp); XtVaSetValues(PLAY_BUTTON(sp), XmNselectColor, ss->selection_color, NULL); } #endif } static void play_arrow_callback(Widget w, XtPointer context, XtPointer info) { #if WITH_AUDIO snd_info *sp = (snd_info *)context; XmToggleButtonCallbackStruct *cb = (XmToggleButtonCallbackStruct *)info; bool dir; dir = (bool)(cb->set); if (dir) sp->speed_control_direction = -1; else sp->speed_control_direction = 1; #endif } /* ---------------- SYNC BUTTON ---------------- */ static void set_sync_color(snd_info *sp) { Widget syb; syb = SYNC_BUTTON(sp); switch (sp->sync) { case 1: case 0: XtVaSetValues(syb, XmNselectColor, ss->selection_color, NULL); break; case 2: XtVaSetValues(syb, XmNselectColor, ss->green, NULL); break; case 3: XtVaSetValues(syb, XmNselectColor, ss->yellow, NULL); break; case 4: XtVaSetValues(syb, XmNselectColor, ss->red, NULL); break; default: XtVaSetValues(syb, XmNselectColor, ss->black, NULL); break; } } void syncb(snd_info *sp, int on) { sp->sync = on; if (on > ss->sound_sync_max) ss->sound_sync_max = on; if (has_widgets(sp)) { set_sync_color(sp); XmToggleButtonSetState(SYNC_BUTTON(sp), (on != 0), false); /* need actual bool here, not a cast! */ } } static void sync_button_callback(Widget w, XtPointer context, XtPointer info) { snd_info *sp = (snd_info *)context; XmToggleButtonCallbackStruct *cb = (XmToggleButtonCallbackStruct *)info; XButtonEvent *ev; ev = (XButtonEvent *)(cb->event); if (cb->set) if (ev->state & snd_ControlMask) if (ev->state & snd_MetaMask) if (ev->state & snd_ShiftMask) sp->sync = 4; else sp->sync = 3; else sp->sync = 2; else sp->sync = 1; else sp->sync = 0; set_sync_color(sp); if (sp->sync != 0) { chan_info *cp; if (sp->sync > ss->sound_sync_max) ss->sound_sync_max = sp->sync; cp = sp->lacp; if (cp == NULL) cp = any_selected_channel(sp); goto_graph(cp); if (cp->cursor_on) sync_cursors(cp, cursor_sample(cp)); apply_x_axis_change(cp); } } /* ---------------- UNITE BUTTON ---------------- */ static void unite_button_callback(Widget w, XtPointer context, XtPointer info) { /* click if set unsets, click if unset->combine, ctrl-click->superimpose */ snd_info *sp = (snd_info *)context; XmToggleButtonCallbackStruct *cb = (XmToggleButtonCallbackStruct *)info; XButtonEvent *ev; channel_style_t val; ev = (XButtonEvent *)(cb->event); if (cb->set) { if (ev->state & (snd_ControlMask | snd_MetaMask)) val = CHANNELS_SUPERIMPOSED; else val = CHANNELS_COMBINED; } else val = CHANNELS_SEPARATE; set_sound_channel_style(sp, val); } /* ---------------- CLOSE BUTTON ---------------- */ static void close_button_callback(Widget w, XtPointer context, XtPointer info) { snd_close_file((snd_info *)context); } /* apply is only safe if the DAC is currently inactive and remains safe only * if all other apply buttons are locked out (and play). */ /* relative panes needs to notice overall window resize, but there's no way to do so in Motif, as far as I can tell */ #if WITH_RELATIVE_PANES /* It would be nice if we could set a paned window to keep its children relative * amounts the same upon outside resize, but the Paned Window widget doesn't * have a resize callback, and no obvious way to advise the resize mechanism. * An attempt to get the same effect by wrapping w_pane in a drawingarea widget * ran into other troubles (the thing is seriously confused about its size). * You'd naively think the Actions "Start" and "Commit" could be used, since * XtActions are said to be a list of XtActionProcs, but I can't find a way to add * my action without deactivating the built-in action of the same name -- * XtAugmentTranslations ignores new actions if the old exists, XtOverride * replaces the old, etc. (And XtActions involve far more complexity than * anyone should have to endure). * * so... drop down into the sashes...(using undocumented stuff throughout this code) */ static void sash_lock_control_panel(snd_info *sp) { if (showing_controls(sp)) { /* lock to its current size */ int hgt; hgt = control_panel_height(sp); XtVaSetValues(CONTROLS(sp), XmNpaneMinimum, hgt, XmNpaneMaximum, hgt, NULL); } } static void sash_unlock_control_panel(snd_info *sp) { if (showing_controls(sp)) { XtVaSetValues(CONTROLS(sp), XmNpaneMinimum, 1, XmNpaneMaximum, LOTSA_PIXELS, NULL); } } static int outer_panes = 0; static int *inner_panes = NULL; static Dimension *outer_sizes = NULL; static Dimension **inner_sizes = NULL; static void watch_sash(Widget w, XtPointer closure, XtPointer info) { SashCallData call_data = (SashCallData)info; /* call_data->params[0]: Commit, Move, Key, Start (as strings) */ if ((call_data->params) && (call_data->params[0]) && (with_relative_panes(ss)) && (sound_style(ss) == SOUNDS_VERTICAL)) { int i, k; snd_info *sp; if (mus_strcmp(call_data->params[0], "Start")) { for (i = 0; i < ss->max_sounds; i++) { sp = ss->sounds[i]; if ((sp) && (sp->inuse == SOUND_NORMAL) && (sp->nchans > 1) && (sp->channel_style == CHANNELS_SEPARATE)) outer_panes++; } for_each_sound(sash_lock_control_panel); if (outer_panes > 0) { int outer_ctr; inner_panes = (int *)calloc(outer_panes, sizeof(int)); outer_sizes = (Dimension *)calloc(outer_panes, sizeof(Dimension)); inner_sizes = (Dimension **)calloc(outer_panes, sizeof(Dimension *)); outer_ctr = 0; for (i = 0; i < ss->max_sounds; i++) { sp = ss->sounds[i]; if ((sp) && (sp->inuse == SOUND_NORMAL) && (sp->nchans > 1) && (sp->channel_style == CHANNELS_SEPARATE)) { Widget child; child = SND_PANE(sp); inner_panes[outer_ctr] = sp->nchans; inner_sizes[outer_ctr] = (Dimension *)calloc(sp->nchans, sizeof(Dimension)); XtVaGetValues(child, XmNheight, &(outer_sizes[outer_ctr]), NULL); for (k = 0; k < sp->nchans; k++) XtVaGetValues(channel_main_pane(sp->chans[k]), XmNheight, &(inner_sizes[outer_ctr][k]), NULL); outer_ctr++; if (outer_ctr >= outer_panes) break; } } } } else { if (mus_strcmp(call_data->params[0], "Commit")) /* release sash */ { if (outer_panes > 0) { int outer_ctr = 0; Dimension cur_outer_size = 0; for (i = 0; i < ss->max_sounds; i++) { sp = ss->sounds[i]; if ((sp) && (sp->inuse == SOUND_NORMAL) && (sp->nchans > 1) && (sp->channel_style == CHANNELS_SEPARATE)) { XtVaGetValues(SND_PANE(sp), XmNheight, &cur_outer_size, NULL); if ((cur_outer_size > 40) && (abs(cur_outer_size - outer_sizes[outer_ctr]) > (sp->nchans * 2))) { /* this pane has multiple chans and its size has changed enough to matter */ Dimension total_inner = 0, diff; float ratio; for (k = 0; k < sp->nchans; k++) total_inner += inner_sizes[outer_ctr][k]; diff = outer_sizes[outer_ctr] - total_inner; /* this is non-channel stuff */ for (k = 0; k < sp->nchans; k++) XtUnmanageChild(channel_main_pane(sp->chans[k])); ratio = (float)(cur_outer_size - diff) / (float)(outer_sizes[outer_ctr] - diff); if (ratio > 0.0) { for (k = 0; k < sp->nchans; k++) { int size; size = (int)(ratio * inner_sizes[outer_ctr][k]); XtVaSetValues(channel_main_pane(sp->chans[k]), XmNpaneMinimum, size - 1, XmNpaneMaximum, size + 1, NULL); } for (k = 0; k < sp->nchans; k++) XtManageChild(channel_main_pane(sp->chans[k])); for (k = 0; k < sp->nchans; k++) XtVaSetValues(channel_main_pane(sp->chans[k]), XmNpaneMinimum, 1, XmNpaneMaximum, LOTSA_PIXELS, NULL); } } outer_ctr++; } } for (i = 0; i < outer_panes; i++) if (inner_sizes[i]) free(inner_sizes[i]); free(inner_panes); free(inner_sizes); free(outer_sizes); outer_panes = 0; } for_each_sound(sash_unlock_control_panel); } } } } static Widget *sashes = NULL; static int sashes_size = 0; static void remember_sash(Widget w) { /* add callback only once (means remembering which widgets already have our callback */ int loc = -1; if (sashes_size == 0) { sashes = (Widget *)calloc(16, sizeof(Widget)); sashes_size = 16; loc = 0; } else { int i; for (i = 0; i < sashes_size; i++) { if (sashes[i] == w) return; if (sashes[i] == NULL) { loc = i; break; } } if (loc == -1) { sashes = (Widget *)realloc(sashes, sashes_size * 2 * sizeof(Widget)); for (i = sashes_size; i < sashes_size * 2; i++) sashes[i] = NULL; loc = sashes_size; sashes_size *= 2; } } sashes[loc] = w; XtAddCallback(w, XmNcallback, watch_sash, NULL); } static void add_sash_watchers(Widget w) { /* if relative panes, add sash watchers to the outer paned window sashes (SOUND_PANE(ss)) */ unsigned int i; CompositeWidget cw = (CompositeWidget)w; for (i = 0; i < cw->composite.num_children; i++) /* only outermost sashes count here */ { Widget child; child = cw->composite.children[i]; if ((XtIsWidget(child)) && (XtIsManaged(child)) && (XtIsSubclass(child, xmSashWidgetClass))) remember_sash(child); } } #endif static bool cant_write(char *name) { #ifndef _MSC_VER return((access(name, W_OK)) != 0); #else return(false); #endif } /* bitmaps for the playback direction arrow */ static unsigned char speed_r_bits1[] = { 0x00, 0x04, 0x10, 0x08, 0x00, 0x10, 0x04, 0x20, 0x00, 0x40, 0xa5, 0xbf, 0x00, 0x40, 0x04, 0x20, 0x00, 0x10, 0x10, 0x08, 0x00, 0x04, 0x00, 0x00}; static unsigned char speed_l_bits1[] = { 0x20, 0x00, 0x10, 0x08, 0x08, 0x00, 0x04, 0x20, 0x02, 0x00, 0xfd, 0xa5, 0x02, 0x00, 0x04, 0x20, 0x08, 0x00, 0x10, 0x08, 0x20, 0x00, 0x00, 0x00}; #define NUM_BOMBS 15 static Pixmap mini_lock = 0; static Pixmap close_icon = 0; static Pixmap blank_pixmap = 0; static bool mini_lock_allocated = false; static Pixmap bombs[NUM_BOMBS]; static Pixmap hourglasses[NUM_HOURGLASSES]; static Pixmap stop_sign = 0; void show_lock(snd_info *sp) { if (!has_widgets(sp)) return; if (mini_lock) XtVaSetValues(LOCK_OR_BOMB(sp), XmNlabelPixmap, mini_lock, NULL); } void hide_lock(snd_info *sp) { if (!has_widgets(sp)) return; if (mini_lock) XtVaSetValues(LOCK_OR_BOMB(sp), XmNlabelPixmap, blank_pixmap, NULL); /* these Pixmaps can be null if the colormap is screwed up */ } static void show_stop_sign(snd_info *sp) { if (!has_widgets(sp)) return; if (stop_sign) XtVaSetValues(STOP_ICON(sp), XmNlabelPixmap, stop_sign, NULL); } static void hide_stop_sign(snd_info *sp) { if (!has_widgets(sp)) return; if (blank_pixmap) XtVaSetValues(STOP_ICON(sp), XmNlabelPixmap, blank_pixmap, NULL); } static void show_bomb(snd_info *sp) { if (!has_widgets(sp)) return; if (sp->bomb_ctr >= NUM_BOMBS) sp->bomb_ctr = 0; if (bombs[sp->bomb_ctr]) XtVaSetValues(LOCK_OR_BOMB(sp), XmNlabelPixmap, bombs[sp->bomb_ctr], NULL); sp->bomb_ctr++; } static void hide_bomb(snd_info *sp) { if (!has_widgets(sp)) return; XtVaSetValues(LOCK_OR_BOMB(sp), XmNlabelPixmap, blank_pixmap, NULL); sp->bomb_ctr = 0; } #define BOMB_TIME 200 static void tick_bomb(XtPointer context, XtIntervalId *id) { snd_info *sp = (snd_info *)context; if (!has_widgets(sp)) return; if ((sp->need_update) || (sp->file_unreadable)) { show_bomb(sp); XtAppAddTimeOut(MAIN_APP(ss), (unsigned long)BOMB_TIME, (XtTimerCallbackProc)tick_bomb, context); } else { hide_bomb(sp); sp->bomb_in_progress = false; } } void start_bomb(snd_info *sp) { if (!has_widgets(sp)) return; sp->bomb_ctr = 0; if (!(sp->bomb_in_progress)) { sp->bomb_in_progress = true; XtAppAddTimeOut(MAIN_APP(ss), (unsigned long)BOMB_TIME, (XtTimerCallbackProc)tick_bomb, (void *)sp); } } void stop_bomb(snd_info *sp) { if (!has_widgets(sp)) return; hide_bomb(sp); sp->bomb_in_progress = false; } static char *bits_to_string(const char **icon) { /* show first few lines */ char *buf; buf = (char *)calloc(128, sizeof(char)); snprintf(buf, 128, "\n%s\n%s\n%s...", icon[0], icon[1], icon[2]); return(buf); } static void allocate_icons(Widget w) { Pixmap shape1, shape2, shape3, shape4; XpmAttributes attributes; XpmColorSymbol symbols[1]; int scr, k, pixerr; Display *dp; Drawable wn; dp = XtDisplay(w); wn = XtWindow(w); scr = DefaultScreen(dp); XtVaGetValues(w, XmNdepth, &attributes.depth, XmNcolormap, &attributes.colormap, NULL); attributes.visual = DefaultVisual(dp, scr); symbols[0].name = (char *)"basiccolor"; symbols[0].value = NULL; symbols[0].pixel = ss->basic_color; attributes.colorsymbols = symbols; attributes.numsymbols = 1; attributes.valuemask = XpmColorSymbols | XpmDepth | XpmColormap | XpmVisual; pixerr = XpmCreatePixmapFromData(dp, wn, (char **)mini_lock_bits(), &mini_lock, &shape1, &attributes); if (pixerr != XpmSuccess) snd_error("lock pixmap trouble: %s from %s\n", XpmGetErrorString(pixerr), bits_to_string(mini_lock_bits())); pixerr = XpmCreatePixmapFromData(dp, wn, (char **)blank_bits(), &blank_pixmap, &shape1, &attributes); if (pixerr != XpmSuccess) snd_error("blank pixmap trouble: %s from %s\n", XpmGetErrorString(pixerr), bits_to_string(blank_bits())); pixerr = XpmCreatePixmapFromData(dp, wn, (char **)stop_sign_bits(), &stop_sign, &shape4, &attributes); if (pixerr != XpmSuccess) snd_error("stop sign pixmap trouble: %s from %s\n", XpmGetErrorString(pixerr), bits_to_string(stop_sign_bits())); pixerr = XpmCreatePixmapFromData(dp, wn, (char **)close_icon_bits(), &close_icon, &shape1, &attributes); if (pixerr != XpmSuccess) snd_error("stop sign pixmap trouble: %s from %s\n", XpmGetErrorString(pixerr), bits_to_string(close_icon_bits())); for (k = 0; k < NUM_BOMBS; k++) { pixerr = XpmCreatePixmapFromData(dp, wn, (char **)mini_bomb_bits(k), &(bombs[k]), &shape2, &attributes); if (pixerr != XpmSuccess) { snd_error("bomb pixmap trouble: %s from %s\n", XpmGetErrorString(pixerr), bits_to_string(mini_bomb_bits(k))); break; } pixerr = XpmCreatePixmapFromData(dp, wn, (char **)mini_glass_bits(k), &(hourglasses[k]), &shape3, &attributes); if (pixerr != XpmSuccess) { snd_error("glass pixmap trouble: %s from %s\n", XpmGetErrorString(pixerr), bits_to_string(mini_glass_bits(k))); break; } } mini_lock_allocated = true; } static void change_pixmap_background(Widget w, Pixmap orig, Pixel old_color, Pixel new_color, int width, int height) { XImage *before; Display *dp; Drawable wn; Visual *vis; XGCValues v; GC draw_gc; int depth, depth_bytes, x, y; char *data; dp = XtDisplay(w); wn = XtWindow(w); vis = DefaultVisual(dp, DefaultScreen(dp)); XtVaGetValues(w, XmNdepth, &depth, NULL); depth_bytes = (depth >> 3); data = (char *)calloc((width + 1) * (height + 1) * depth_bytes, sizeof(char)); /* not calloc since X will free this */ /* there's overflow in X here, apparently -- the +1's fix it according to valgrind */ /* perhaps this is supposed to be rounded up to byte boundaries? */ before = XCreateImage(dp, vis, depth, XYPixmap, 0, data, width, height, 8, 0); XGetSubImage(dp, orig, 0, 0, width, height, AllPlanes, XYPixmap, before, 0, 0); v.background = new_color; draw_gc = XCreateGC(dp, wn, GCBackground, &v); XSetBackground(dp, draw_gc, new_color); for (x = 0; x < width; x++) for (y = 0; y < height; y++) if (XGetPixel(before, x, y) == old_color) XPutPixel(before, x, y, new_color); XPutImage(dp, orig, draw_gc, before, 0, 0, 0, 0, width, height); XDestroyImage(before); /* frees data as well */ XFreeGC(dp, draw_gc); } void make_sound_icons_transparent_again(Pixel old_color, Pixel new_color) { int i; if (!mini_lock_allocated) allocate_icons(MAIN_SHELL(ss)); change_pixmap_background(MAIN_SHELL(ss), mini_lock, old_color, new_color, 16, 14); change_pixmap_background(MAIN_SHELL(ss), blank_pixmap, old_color, new_color, 16, 14); change_pixmap_background(MAIN_SHELL(ss), close_icon, old_color, new_color, 16, 14); /* change_pixmap_background(MAIN_SHELL(ss), stop_sign, old_color, new_color, 17, 17); */ /* memory corruption here! */ for (i = 0; i < NUM_BOMBS; i++) change_pixmap_background(MAIN_SHELL(ss), bombs[i], old_color, new_color, 16, 14); for (i = 0; i < NUM_HOURGLASSES; i++) change_pixmap_background(MAIN_SHELL(ss), hourglasses[i], old_color, new_color, 16, 14); } static Pixmap spd_r, spd_l; static bool spd_ok = false; static void close_sound_dialog(Widget w, XtPointer context, XtPointer info) { snd_info *sp = (snd_info *)context; if (sp) snd_close_file(sp); } static void manage_sync_button(snd_info *sp) { XtManageChild(SYNC_BUTTON(sp)); } static void attach_status_area(snd_info *sp) { XtUnmanageChild(STATUS_AREA(sp)); XtVaSetValues(STATUS_AREA(sp), XmNrightAttachment, XmATTACH_WIDGET, XmNrightWidget, (XtIsManaged(UNITE_BUTTON(sp))) ? UNITE_BUTTON(sp) : ((XtIsManaged(SYNC_BUTTON(sp))) ? SYNC_BUTTON(sp) : PLAY_BUTTON(sp)), NULL); XtManageChild(STATUS_AREA(sp)); } snd_info *add_sound_window(char *filename, read_only_t read_only, file_info *hdr) { snd_info *sp = NULL, *osp; Widget *sw; XmString s1; int snd_slot, nchans = 1, i, old_chans; bool make_widgets; Arg args[32]; char *old_name = NULL, *title; Dimension app_dy, screen_y, chan_min_y; Position app_y; /* these dimensions are used to try to get a reasonable channel graph size without falling off the screen bottom */ Pixmap rb, lb; int depth; bool free_filename = false; Widget form; XtCallbackList n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12; Atom sound_delete; if (ss->translated_filename) { old_name = filename; filename = ss->translated_filename; free_filename = true; ss->translated_filename = NULL; } nchans = hdr->chans; if (nchans <= 0) nchans = 1; XtVaGetValues(MAIN_SHELL(ss), XmNy, &app_y, XmNheight, &app_dy, NULL); screen_y = DisplayHeight(MAIN_DISPLAY(ss), DefaultScreen(MAIN_DISPLAY(ss))); app_dy = (screen_y - app_y - app_dy - 20 * nchans); chan_min_y = (Dimension)(app_dy / (Dimension)nchans); if (chan_min_y > (Dimension)(ss->channel_min_height)) chan_min_y = ss->channel_min_height; else if (chan_min_y < 5) chan_min_y = 5; snd_slot = find_free_sound_slot(nchans); /* expands sound list if needed */ if (ss->sounds[snd_slot]) /* we're trying to re-use an old, inactive set of widgets and whatnot */ { osp = ss->sounds[snd_slot]; old_chans = osp->allocated_chans; } else old_chans = 0; make_widgets = (ss->sounds[snd_slot] == NULL); ss->sounds[snd_slot] = make_snd_info(ss->sounds[snd_slot], filename, hdr, snd_slot, read_only); sp = ss->sounds[snd_slot]; sp->inuse = SOUND_NORMAL; sp->bomb_ctr = 0; sp->write_date = file_write_date(filename); /* needed early in this process by the peak-env handlers */ if (sp->snd_widgets == NULL) sp->snd_widgets = (Widget *)calloc(NUM_SND_WIDGETS, sizeof(Widget)); sw = sp->snd_widgets; if ((!make_widgets) && (old_chans < nchans)) { for (i = old_chans; i < nchans; i++) add_channel_window(sp, i, chan_min_y, 1, NULL, WITH_FW_BUTTONS, WITH_EVENTS); } if (make_widgets) { int n; if (sound_style(ss) == SOUNDS_IN_SEPARATE_WINDOWS) { title = (char *)calloc(PRINT_BUFFER_SIZE, sizeof(char)); snprintf(title, PRINT_BUFFER_SIZE, "%d: %s", snd_slot, sp->short_filename); if (sp->dialog == NULL) { n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNautoUnmanage, false); n++; XtSetArg(args[n], XmNresizePolicy, XmRESIZE_GROW); n++; XtSetArg(args[n], XmNnoResize, false); n++; XtSetArg(args[n], XmNtransient, false); n++; sp->dialog = XtCreatePopupShell(title, xmDialogShellWidgetClass, MAIN_SHELL(ss), args, n); /* using popup shell here gets around the problem that the shell passes resize requests to all its children * -- as a popup, it's not considered a child, but that means we don't inherit things like popup menus from * the main shell. */ sound_delete = XmInternAtom(XtDisplay(sp->dialog), (char *)"WM_DELETE_WINDOW", false); XmAddWMProtocolCallback(sp->dialog, sound_delete, close_sound_dialog, (XtPointer)sp); } else XtVaSetValues(sp->dialog, XmNtitle, title, NULL); free(title); if (!XtIsManaged(sp->dialog)) XtManageChild(sp->dialog); } n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; n = attach_all_sides(args, n); XtSetArg(args[n], XmNallowResize, true); n++; XtSetArg(args[n], XmNsashIndent, ss->channel_sash_indent); n++; XtSetArg(args[n], XmNpaneMaximum, LOTSA_PIXELS); n++; /* Xm/Paned.c initializes this to 1000! */ if (ss->channel_sash_size != 0) { XtSetArg(args[n], XmNsashHeight, ss->channel_sash_size); n++; XtSetArg(args[n], XmNsashWidth, ss->channel_sash_size); n++; } /* if (mumble_style(ss) == CHANNELS_HORIZONTAL) {XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++;} */ /* this doesn't work yet because the control panel is screwed up when trying to display itself horizontally */ /* Perhaps another layer of panes? */ if (sound_style(ss) == SOUNDS_VERTICAL) { if (ss->toolbar) XtSetArg(args[n], XmNpositionIndex, snd_slot + 1); else XtSetArg(args[n], XmNpositionIndex, snd_slot); n++; } XtSetArg(args[n], XmNuserData, sp->index); n++; if (sound_style(ss) == SOUNDS_IN_SEPARATE_WINDOWS) SND_PANE(sp) = XtCreateManagedWidget("snd-pane", xmPanedWindowWidgetClass, sp->dialog, args, n); else { unsigned int i; CompositeWidget cw = (CompositeWidget)SOUND_PANE(ss); SND_PANE(sp) = XtCreateManagedWidget("snd-pane", xmPanedWindowWidgetClass, SOUND_PANE(ss), args, n); /* try to make the division between sounds more obvious */ for (i = 0; i < cw->composite.num_children; i++) { Widget child; child = cw->composite.children[i]; if (((XtIsWidget(child))|| (XmIsGadget(child))) && (XtIsManaged(child)) && ((XmIsSeparator(child)) || (XmIsSeparatorGadget(child)))) XtVaSetValues(child, XmNseparatorType, XmDOUBLE_LINE, XmNbackground, ss->white, NULL); } } XtAddEventHandler(SND_PANE(sp), KeyPressMask, false, graph_key_press, (XtPointer)sp); /* if user clicks in controls, then starts typing, try to send key events to current active channel */ /* all widgets in the control-pane that would otherwise intercept the key events get this event handler */ for (i = 0; i < nchans; i++) add_channel_window(sp, i, chan_min_y, 0, NULL, WITH_FW_BUTTONS, WITH_EVENTS); /* creates channel (horizontal) paned window widget as child of w_snd_pane(sp) == SND_PANE(sp) */ /* -------- sound file name, status area, various buttons -------- */ n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNpaneMinimum, 20); n++; XtSetArg(args[n], XmNpaneMaximum, 20); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; NAME_BOX(sp) = XtCreateManagedWidget("snd-name-form", xmFormWidgetClass, SND_PANE(sp), args, n); XtAddEventHandler(NAME_BOX(sp), KeyPressMask, false, graph_key_press, (XtPointer)sp); if (!mini_lock_allocated) allocate_icons(NAME_BOX(sp)); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNlabelType, XmPIXMAP); n++; XtSetArg(args[n], XmNlabelPixmap, close_icon); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNwidth, 32); n++; XtSetArg(args[n], XmNshadowThickness, 0); n++; XtSetArg(args[n], XmNhighlightThickness, 0); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; CLOSE_BUTTON(sp) = XtCreateManagedWidget("close-button", xmPushButtonWidgetClass, NAME_BOX(sp), args, n); XtAddCallback(CLOSE_BUTTON(sp), XmNactivateCallback, close_button_callback, (XtPointer)sp); n = 0; s1 = XmStringCreateLocalized(shortname_indexed(sp)); XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; /* XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; */ XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, CLOSE_BUTTON(sp)); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNlabelString, s1); n++; XtSetArg(args[n], XmNshadowThickness, 0); n++; XtSetArg(args[n], XmNhighlightThickness, 0); n++; XtSetArg(args[n], XmNfillOnArm, false); n++; NAME_LABEL(sp) = XtCreateManagedWidget("snd-name", xmPushButtonWidgetClass, NAME_BOX(sp), args, n); XtAddEventHandler(NAME_LABEL(sp), KeyPressMask, false, graph_key_press, (XtPointer)sp); XtAddCallback(NAME_LABEL(sp), XmNactivateCallback, name_click_callback, (XtPointer)sp); XmStringFree(s1); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, NAME_LABEL(sp)); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; if (blank_pixmap) { /* if xpm failed (blank_pixmap == 0), this can cause X to kill Snd! */ XtSetArg(args[n], XmNlabelType, XmPIXMAP); n++; XtSetArg(args[n], XmNlabelPixmap, blank_pixmap); n++; } LOCK_OR_BOMB(sp) = XtCreateManagedWidget("", xmLabelWidgetClass, NAME_BOX(sp), args, n); { int i; Widget left_widget; left_widget = LOCK_OR_BOMB(sp); sp->progress_widgets = (Widget *)calloc(sp->nchans, sizeof(Widget)); sp->num_progress_widgets = sp->nchans; /* when an unused sound is reopened in snd-data.c, it's possible for its channel number * to be increased. If we then try to draw the clock icon in the new channel, its * widget will be unallocated -> segfault, so to keep things simple, we check this number. */ for (i = 0; i < sp->nchans; i++) { n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, left_widget); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; if (blank_pixmap) { /* if xpm failed (blank_pixmap == 0), this can cause X to kill Snd! */ XtSetArg(args[n], XmNlabelType, XmPIXMAP); n++; XtSetArg(args[n], XmNlabelPixmap, blank_pixmap); n++; } sp->progress_widgets[i] = XtCreateManagedWidget("", xmLabelWidgetClass, NAME_BOX(sp), args, n); left_widget = sp->progress_widgets[i]; } n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, left_widget); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; if (blank_pixmap) { XtSetArg(args[n], XmNlabelType, XmPIXMAP); n++; XtSetArg(args[n], XmNlabelPixmap, blank_pixmap); n++; } XtSetArg(args[n], XmNshadowThickness, 0); n++; XtSetArg(args[n], XmNhighlightThickness, 0); n++; XtSetArg(args[n], XmNfillOnArm, false); n++; STOP_ICON(sp) = XtCreateManagedWidget("", xmPushButtonWidgetClass, NAME_BOX(sp), args, n); XtAddCallback(STOP_ICON(sp), XmNactivateCallback, stop_sign_click_callback, (XtPointer)sp); } n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, STOP_ICON(sp)); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNresizeWidth, true); n++; XtSetArg(args[n], XmNmarginHeight, 1); n++; XtSetArg(args[n], XmNshadowThickness, 0); n++; XtSetArg(args[n], XmNeditable, false); n++; XtSetArg(args[n], XmNcursorPositionVisible, false); n++; STATUS_AREA(sp) = XtCreateManagedWidget("snd-info", xmTextFieldWidgetClass, NAME_BOX(sp), args, n); #if WITH_AUDIO n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; #ifdef TOGGLE_MARGIN XtSetArg(args[n], XmNmarginHeight, TOGGLE_MARGIN); n++; XtSetArg(args[n], XmNmarginTop, TOGGLE_MARGIN); n++; #endif XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrecomputeSize, false); n++; /* in Motif 2.2 this sets up a tooltip: XtSetArg(args[n], XmNtoolTipString, XmStringCreateLocalized((char *)"play this sound")); n++; */ XtSetArg(args[n], XmNselectColor, ss->selection_color); n++; PLAY_BUTTON(sp) = make_togglebutton_widget("play", NAME_BOX(sp), args, n); XtAddCallback(PLAY_BUTTON(sp), XmNvalueChangedCallback, play_button_callback, (XtPointer)sp); #endif n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; #ifdef TOGGLE_MARGIN XtSetArg(args[n], XmNmarginHeight, TOGGLE_MARGIN); n++; XtSetArg(args[n], XmNmarginTop, TOGGLE_MARGIN); n++; #endif XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_NONE); n++; #if WITH_AUDIO XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNrightWidget, PLAY_BUTTON(sp)); n++; #else XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; #endif XtSetArg(args[n], XmNselectColor, ss->selection_color); n++; SYNC_BUTTON(sp) = make_togglebutton_widget("sync", NAME_BOX(sp), args, n); XtAddEventHandler(SYNC_BUTTON(sp), KeyPressMask, false, graph_key_press, (XtPointer)sp); XtAddCallback(SYNC_BUTTON(sp), XmNvalueChangedCallback, sync_button_callback, (XtPointer)sp); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNbottomWidget, SYNC_BUTTON(sp)); n++; #ifdef TOGGLE_MARGIN XtSetArg(args[n], XmNmarginHeight, TOGGLE_MARGIN); n++; XtSetArg(args[n], XmNmarginTop, TOGGLE_MARGIN); n++; #endif XtSetArg(args[n], XmNleftAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNrightWidget, SYNC_BUTTON(sp)); n++; XtSetArg(args[n], XmNselectColor, ss->selection_color); n++; UNITE_BUTTON(sp) = make_togglebutton_widget("unite", NAME_BOX(sp), args, n); XtAddEventHandler(UNITE_BUTTON(sp), KeyPressMask, false, graph_key_press, (XtPointer)sp); XtAddCallback(UNITE_BUTTON(sp), XmNvalueChangedCallback, unite_button_callback, (XtPointer)sp); /* ---------------- control panel ---------------- */ n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; CONTROLS(sp) = XtCreateManagedWidget("snd-amp", xmFormWidgetClass, SND_PANE(sp), args, n); XtAddEventHandler(CONTROLS(sp), KeyPressMask, false, graph_key_press, (XtPointer)sp); n = 0; /* AMP */ s1 = XmStringCreateLocalized((char *)"amp:"); XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNlabelString, s1); n++; XtSetArg(args[n], XmNmarginHeight, CONTROLS_MARGIN); n++; XtSetArg(args[n], XmNrecomputeSize, false); n++; XtSetArg(args[n], XmNshadowThickness, 0); n++; XtSetArg(args[n], XmNhighlightThickness, 0); n++; XtSetArg(args[n], XmNfillOnArm, false); n++; AMP_BUTTON(sp) = make_pushbutton_widget("amp-label", CONTROLS(sp), args, n); XtAddEventHandler(AMP_BUTTON(sp), KeyPressMask, false, graph_key_press, (XtPointer)sp); XtAddCallback(AMP_BUTTON(sp), XmNactivateCallback, amp_click_callback, (XtPointer)sp); XmStringFree(s1); n = 0; s1 = XmStringCreateLocalized((char *)"1.0 "); XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, AMP_BUTTON(sp)); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, AMP_BUTTON(sp)); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNmarginHeight, CONTROLS_MARGIN); n++; XtSetArg(args[n], XmNrecomputeSize, false); n++; XtSetArg(args[n], XmNlabelString, s1); n++; XtSetArg(args[n], XmNmarginRight, 3); n++; AMP_LABEL(sp) = XtCreateManagedWidget("amp-number", xmLabelWidgetClass, CONTROLS(sp), args, n); XmStringFree(s1); n = 0; XtSetArg(args[n], XmNbackground, ss->position_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, AMP_BUTTON(sp)); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNheight, 16); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, AMP_LABEL(sp)); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNmaximum, SCROLLBAR_MAX); n++; XtSetArg(args[n], XmNvalue, amp_to_scroll(sp->amp_control_min, 1.0, sp->amp_control_max)); n++; XtSetArg(args[n], XmNdragCallback, n1 = make_callback_list(amp_drag_callback, (XtPointer)sp)); n++; XtSetArg(args[n], XmNvalueChangedCallback, n2 = make_callback_list(amp_valuechanged_callback, (XtPointer)sp)); n++; AMP_SCROLLBAR(sp) = XtCreateManagedWidget("amp", xmScrollBarWidgetClass, CONTROLS(sp), args, n); XtAddEventHandler(AMP_SCROLLBAR(sp), KeyPressMask, false, graph_key_press, (XtPointer)sp); n = 0; /* SPEED */ s1 = XmStringCreateLocalized((char *)"speed:"); XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, AMP_BUTTON(sp)); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNlabelString, s1); n++; XtSetArg(args[n], XmNmarginHeight, CONTROLS_MARGIN); n++; XtSetArg(args[n], XmNrecomputeSize, false); n++; XtSetArg(args[n], XmNshadowThickness, 0); n++; XtSetArg(args[n], XmNhighlightThickness, 0); n++; XtSetArg(args[n], XmNfillOnArm, false); n++; SPEED_BUTTON(sp) = make_pushbutton_widget("speed-label", CONTROLS(sp), args, n); XtAddEventHandler(SPEED_BUTTON(sp), KeyPressMask, false, graph_key_press, (XtPointer)sp); XtAddCallback(SPEED_BUTTON(sp), XmNactivateCallback, speed_click_callback, (XtPointer)sp); XmStringFree(s1); n = 0; s1 = initial_speed_label(sp->speed_control_style); XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, SPEED_BUTTON(sp)); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, SPEED_BUTTON(sp)); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNlabelString, s1); n++; XtSetArg(args[n], XmNmarginHeight, CONTROLS_MARGIN); n++; XtSetArg(args[n], XmNrecomputeSize, false); n++; XtSetArg(args[n], XmNmarginRight, 3); n++; XtSetArg(args[n], XmNshadowThickness, 0); n++; XtSetArg(args[n], XmNhighlightThickness, 0); n++; XtSetArg(args[n], XmNfillOnArm, false); n++; SPEED_LABEL(sp) = make_pushbutton_widget("speed-number", CONTROLS(sp), args, n); XtAddEventHandler(SPEED_LABEL(sp), KeyPressMask, false, graph_key_press, (XtPointer)sp); XtAddCallback(SPEED_LABEL(sp), XmNactivateCallback, speed_label_click_callback, (XtPointer)sp); XmStringFree(s1); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, SPEED_BUTTON(sp)); n++; XtSetArg(args[n], XmNindicatorOn, false); n++; XtSetArg(args[n], XmNlabelType, XmPIXMAP); n++; XtSetArg(args[n], XmNmarginHeight, 0); n++; XtSetArg(args[n], XmNmarginWidth, 0); n++; XtSetArg(args[n], XmNmarginTop, 0); n++; XtSetArg(args[n], XmNtopOffset, 0); n++; SPEED_ARROW(sp) = make_togglebutton_widget("dir", CONTROLS(sp), args, n); form = SPEED_ARROW(sp); if (!spd_ok) { rb = XCreateBitmapFromData(XtDisplay(form), RootWindowOfScreen(XtScreen(form)), (const char *)speed_r_bits1, 16, 12); lb = XCreateBitmapFromData(XtDisplay(form), RootWindowOfScreen(XtScreen(form)), (const char *)speed_l_bits1, 16, 12); XtVaGetValues(form, XmNdepth, &depth, NULL); spd_r = XCreatePixmap(XtDisplay(form), RootWindowOfScreen(XtScreen(form)), 16, 12, depth); spd_l = XCreatePixmap(XtDisplay(form), RootWindowOfScreen(XtScreen(form)), 16, 12, depth); XCopyPlane(XtDisplay(form), rb, spd_r, ss->fltenv_basic_gc, 0, 0, 16, 12, 0, 0, 1); XCopyPlane(XtDisplay(form), lb, spd_l, ss->fltenv_basic_gc, 0, 0, 16, 12, 0, 0, 1); XFreePixmap(XtDisplay(form), rb); XFreePixmap(XtDisplay(form), lb); spd_ok = true; } XtVaSetValues(form, XmNselectPixmap, spd_l, XmNlabelPixmap, spd_r, NULL); XtAddEventHandler(SPEED_ARROW(sp), KeyPressMask, false, graph_key_press, (XtPointer)sp); XtAddCallback(SPEED_ARROW(sp), XmNvalueChangedCallback, play_arrow_callback, (XtPointer)sp); n = 0; XtSetArg(args[n], XmNbackground, ss->position_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, SPEED_BUTTON(sp)); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, SPEED_LABEL(sp)); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNrightWidget, SPEED_ARROW(sp)); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNmaximum, SCROLLBAR_MAX); n++; XtSetArg(args[n], XmNvalue, speed_to_scroll(sp->speed_control_min, 1.0, sp->speed_control_max)); n++; XtSetArg(args[n], XmNheight, 16); n++; XtSetArg(args[n], XmNdragCallback, n3 = make_callback_list(speed_drag_callback, (XtPointer)sp)); n++; XtSetArg(args[n], XmNvalueChangedCallback, n4 = make_callback_list(speed_valuechanged_callback, (XtPointer)sp)); n++; SPEED_SCROLLBAR(sp) = XtCreateManagedWidget("speed-scroll", xmScrollBarWidgetClass, CONTROLS(sp), args, n); XtAddEventHandler(SPEED_SCROLLBAR(sp), KeyPressMask, false, graph_key_press, (XtPointer)sp); n = 0; /* EXPAND */ s1 = XmStringCreateLocalized((char *)"expand:"); XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, SPEED_BUTTON(sp)); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNlabelString, s1); n++; XtSetArg(args[n], XmNmarginHeight, CONTROLS_MARGIN); n++; XtSetArg(args[n], XmNrecomputeSize, false); n++; XtSetArg(args[n], XmNshadowThickness, 0); n++; XtSetArg(args[n], XmNhighlightThickness, 0); n++; XtSetArg(args[n], XmNfillOnArm, false); n++; EXPAND_LEFT_BUTTON(sp) = make_pushbutton_widget("expand-label", CONTROLS(sp), args, n); XtAddEventHandler(EXPAND_LEFT_BUTTON(sp), KeyPressMask, false, graph_key_press, (XtPointer)sp); XtAddCallback(EXPAND_LEFT_BUTTON(sp), XmNactivateCallback, expand_click_callback, (XtPointer)sp); XmStringFree(s1); n = 0; s1 = XmStringCreateLocalized((char *)"1.0 "); XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, EXPAND_LEFT_BUTTON(sp)); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, EXPAND_LEFT_BUTTON(sp)); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNmarginHeight, CONTROLS_MARGIN); n++; XtSetArg(args[n], XmNrecomputeSize, false); n++; XtSetArg(args[n], XmNlabelString, s1); n++; XtSetArg(args[n], XmNmarginRight, 3); n++; EXPAND_LABEL(sp) = XtCreateManagedWidget("expand-number", xmLabelWidgetClass, CONTROLS(sp), args, n); XmStringFree(s1); n = 0; s1 = XmStringCreateLocalized((char *)""); XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, EXPAND_LEFT_BUTTON(sp)); n++; XtSetArg(args[n], XmNheight, 16); n++; XtSetArg(args[n], XmNmarginHeight, CONTROLS_MARGIN); n++; XtSetArg(args[n], XmNmarginWidth, 0); n++; XtSetArg(args[n], XmNtopOffset, 1); n++; XtSetArg(args[n], XmNspacing, 0); n++; XtSetArg(args[n], XmNlabelString, s1); n++; if (ss->toggle_size > 0) {XtSetArg(args[n], XmNindicatorSize, ss->toggle_size); n++;} XtSetArg(args[n], XmNselectColor, ss->selection_color); n++; EXPAND_RIGHT_BUTTON(sp) = make_togglebutton_widget("expoff", CONTROLS(sp), args, n); XtAddEventHandler(EXPAND_RIGHT_BUTTON(sp), KeyPressMask, false, graph_key_press, (XtPointer)sp); XtAddCallback(EXPAND_RIGHT_BUTTON(sp), XmNvalueChangedCallback, expand_button_callback, (XtPointer)sp); XmStringFree(s1); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, EXPAND_LEFT_BUTTON(sp)); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, EXPAND_LABEL(sp)); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNrightWidget, EXPAND_RIGHT_BUTTON(sp)); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNmaximum, SCROLLBAR_MAX); n++; XtSetArg(args[n], XmNvalue, expand_to_scroll(sp->expand_control_min, 1.0, sp->expand_control_max)); n++; XtSetArg(args[n], XmNheight, 16); n++; XtSetArg(args[n], XmNmarginHeight, CONTROLS_MARGIN); n++; XtSetArg(args[n], XmNdragCallback, n5 = make_callback_list(expand_drag_callback, (XtPointer)sp)); n++; XtSetArg(args[n], XmNvalueChangedCallback, n6 = make_callback_list(expand_valuechanged_callback, (XtPointer)sp)); n++; EXPAND_SCROLLBAR(sp) = XtCreateManagedWidget("expand-scroll", xmScrollBarWidgetClass, CONTROLS(sp), args, n); XtAddEventHandler(EXPAND_SCROLLBAR(sp), KeyPressMask, false, graph_key_press, (XtPointer)sp); /* CONTRAST */ n = 0; s1 = XmStringCreateLocalized((char *)"contrast:"); XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, EXPAND_LEFT_BUTTON(sp)); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNlabelString, s1); n++; XtSetArg(args[n], XmNmarginHeight, CONTROLS_MARGIN); n++; XtSetArg(args[n], XmNrecomputeSize, false); n++; XtSetArg(args[n], XmNshadowThickness, 0); n++; XtSetArg(args[n], XmNhighlightThickness, 0); n++; XtSetArg(args[n], XmNfillOnArm, false); n++; CONTRAST_LEFT_BUTTON(sp) = make_pushbutton_widget("contrast-label", CONTROLS(sp), args, n); XtAddEventHandler(CONTRAST_LEFT_BUTTON(sp), KeyPressMask, false, graph_key_press, (XtPointer)sp); XtAddCallback(CONTRAST_LEFT_BUTTON(sp), XmNactivateCallback, contrast_click_callback, (XtPointer)sp); XmStringFree(s1); n = 0; s1 = XmStringCreateLocalized((char *)"1.0 "); XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, CONTRAST_LEFT_BUTTON(sp)); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, CONTRAST_LEFT_BUTTON(sp)); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNmarginHeight, CONTROLS_MARGIN); n++; XtSetArg(args[n], XmNrecomputeSize, false); n++; XtSetArg(args[n], XmNlabelString, s1); n++; XtSetArg(args[n], XmNmarginRight, 3); n++; CONTRAST_LABEL(sp) = XtCreateManagedWidget("contrast-number", xmLabelWidgetClass, CONTROLS(sp), args, n); XmStringFree(s1); n = 0; s1 = XmStringCreateLocalized((char *)""); XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, CONTRAST_LEFT_BUTTON(sp)); n++; XtSetArg(args[n], XmNheight, 16); n++; XtSetArg(args[n], XmNmarginHeight, CONTROLS_MARGIN); n++; XtSetArg(args[n], XmNmarginWidth, 0); n++; XtSetArg(args[n], XmNtopOffset, 1); n++; XtSetArg(args[n], XmNlabelString, s1); n++; XtSetArg(args[n], XmNspacing, 0); n++; if (ss->toggle_size > 0) {XtSetArg(args[n], XmNindicatorSize, ss->toggle_size); n++;} XtSetArg(args[n], XmNselectColor, ss->selection_color); n++; CONTRAST_RIGHT_BUTTON(sp) = make_togglebutton_widget("conoff", CONTROLS(sp), args, n); XtAddEventHandler(CONTRAST_RIGHT_BUTTON(sp), KeyPressMask, false, graph_key_press, (XtPointer)sp); XtAddCallback(CONTRAST_RIGHT_BUTTON(sp), XmNvalueChangedCallback, contrast_button_callback, (XtPointer)sp); XmStringFree(s1); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, CONTRAST_LEFT_BUTTON(sp)); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, CONTRAST_LABEL(sp)); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNrightWidget, CONTRAST_RIGHT_BUTTON(sp)); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNmaximum, SCROLLBAR_MAX); n++; XtSetArg(args[n], XmNheight, 16); n++; XtSetArg(args[n], XmNvalue, 0); n++; XtSetArg(args[n], XmNmarginHeight, CONTROLS_MARGIN); n++; XtSetArg(args[n], XmNdragCallback, n7 = make_callback_list(contrast_drag_callback, (XtPointer)sp)); n++; XtSetArg(args[n], XmNvalueChangedCallback, n8 = make_callback_list(contrast_valuechanged_callback, (XtPointer)sp)); n++; CONTRAST_SCROLLBAR(sp) = XtCreateManagedWidget("contrast-scroll", xmScrollBarWidgetClass, CONTROLS(sp), args, n); XtAddEventHandler(CONTRAST_SCROLLBAR(sp), KeyPressMask, false, graph_key_press, (XtPointer)sp); /* REVERB */ /* REVSCL */ n = 0; s1 = XmStringCreateLocalized((char *)"reverb:"); XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, CONTRAST_LEFT_BUTTON(sp)); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNlabelString, s1); n++; XtSetArg(args[n], XmNmarginHeight, CONTROLS_MARGIN); n++; XtSetArg(args[n], XmNrecomputeSize, false); n++; XtSetArg(args[n], XmNshadowThickness, 0); n++; XtSetArg(args[n], XmNhighlightThickness, 0); n++; XtSetArg(args[n], XmNfillOnArm, false); n++; REVSCL_BUTTON(sp) = make_pushbutton_widget("revscl-label", CONTROLS(sp), args, n); XtAddEventHandler(REVSCL_BUTTON(sp), KeyPressMask, false, graph_key_press, (XtPointer)sp); XtAddCallback(REVSCL_BUTTON(sp), XmNactivateCallback, revscl_click_callback, (XtPointer)sp); XmStringFree(s1); n = 0; s1 = XmStringCreateLocalized((char *)"0.0 "); XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, REVSCL_BUTTON(sp)); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, REVSCL_BUTTON(sp)); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNlabelString, s1); n++; XtSetArg(args[n], XmNmarginHeight, CONTROLS_MARGIN); n++; XtSetArg(args[n], XmNrecomputeSize, false); n++; XtSetArg(args[n], XmNmarginRight, 3); n++; REVSCL_LABEL(sp) = XtCreateManagedWidget("revscl-number", xmLabelWidgetClass, CONTROLS(sp), args, n); XmStringFree(s1); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, REVSCL_BUTTON(sp)); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, REVSCL_LABEL(sp)); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n++; XtSetArg(args[n], XmNrightPosition, 60); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNheight, 16); n++; XtSetArg(args[n], XmNmaximum, SCROLLBAR_MAX); n++; XtSetArg(args[n], XmNvalue, 0); n++; XtSetArg(args[n], XmNmarginHeight, CONTROLS_MARGIN); n++; XtSetArg(args[n], XmNdragCallback, n9 = make_callback_list(revscl_drag_callback, (XtPointer)sp)); n++; XtSetArg(args[n], XmNvalueChangedCallback, n10 = make_callback_list(revscl_valuechanged_callback, (XtPointer)sp)); n++; REVSCL_SCROLLBAR(sp) = XtCreateManagedWidget("revscl-scroll", xmScrollBarWidgetClass, CONTROLS(sp), args, n); XtAddEventHandler(REVSCL_SCROLLBAR(sp), KeyPressMask, false, graph_key_press, (XtPointer)sp); /* REVOFF */ n = 0; s1 = XmStringCreateLocalized((char *)""); XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, REVSCL_BUTTON(sp)); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNrightWidget, CONTRAST_RIGHT_BUTTON(sp)); n++; XtSetArg(args[n], XmNheight, 16); n++; XtSetArg(args[n], XmNmarginHeight, CONTROLS_MARGIN); n++; XtSetArg(args[n], XmNmarginWidth, 0); n++; XtSetArg(args[n], XmNtopOffset, 1); n++; XtSetArg(args[n], XmNspacing, 0); n++; XtSetArg(args[n], XmNlabelString, s1); n++; if (ss->toggle_size > 0) {XtSetArg(args[n], XmNindicatorSize, ss->toggle_size); n++;} XtSetArg(args[n], XmNselectColor, ss->selection_color); n++; REVERB_BUTTON(sp) = make_togglebutton_widget("revoff", CONTROLS(sp), args, n); XtAddEventHandler(REVERB_BUTTON(sp), KeyPressMask, false, graph_key_press, (XtPointer)sp); XtAddCallback(REVERB_BUTTON(sp), XmNvalueChangedCallback, reverb_button_callback, (XtPointer)sp); XmStringFree(s1); /* REVLEN */ n = 0; s1 = XmStringCreateLocalized((char *)"len:"); XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, REVSCL_SCROLLBAR(sp)); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_POSITION); n++; XtSetArg(args[n], XmNleftPosition, 60); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNlabelString, s1); n++; XtSetArg(args[n], XmNmarginHeight, CONTROLS_MARGIN); n++; XtSetArg(args[n], XmNrecomputeSize, false); n++; XtSetArg(args[n], XmNshadowThickness, 0); n++; XtSetArg(args[n], XmNhighlightThickness, 0); n++; XtSetArg(args[n], XmNfillOnArm, false); n++; REVLEN_BUTTON(sp) = make_pushbutton_widget("revlen-label", CONTROLS(sp), args, n); XtAddEventHandler(REVLEN_BUTTON(sp), KeyPressMask, false, graph_key_press, (XtPointer)sp); XtAddCallback(REVLEN_BUTTON(sp), XmNactivateCallback, revlen_click_callback, (XtPointer)sp); XmStringFree(s1); n = 0; s1 = XmStringCreateLocalized((char *)"1.0 "); XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, REVLEN_BUTTON(sp)); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, REVLEN_BUTTON(sp)); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNlabelString, s1); n++; XtSetArg(args[n], XmNmarginHeight, CONTROLS_MARGIN); n++; XtSetArg(args[n], XmNrecomputeSize, false); n++; XtSetArg(args[n], XmNmarginRight, 3); n++; REVLEN_LABEL(sp) = XtCreateManagedWidget("revlen-number", xmLabelWidgetClass, CONTROLS(sp), args, n); XmStringFree(s1); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, REVLEN_BUTTON(sp)); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, REVLEN_LABEL(sp)); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNrightWidget, REVERB_BUTTON(sp)); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNheight, 16); n++; XtSetArg(args[n], XmNmaximum, SCROLLBAR_MAX); n++; XtSetArg(args[n], XmNvalue, revlen_to_scroll(sp->reverb_control_length_min, 1.0, sp->reverb_control_length_max)); n++; XtSetArg(args[n], XmNmarginHeight, CONTROLS_MARGIN); n++; XtSetArg(args[n], XmNdragCallback, n11 = make_callback_list(revlen_drag_callback, (XtPointer)sp)); n++; XtSetArg(args[n], XmNvalueChangedCallback, n12 = make_callback_list(revlen_valuechanged_callback, (XtPointer)sp)); n++; REVLEN_SCROLLBAR(sp) = XtCreateManagedWidget("revlen-scroll", xmScrollBarWidgetClass, CONTROLS(sp), args, n); XtAddEventHandler(REVLEN_SCROLLBAR(sp), KeyPressMask, false, graph_key_press, (XtPointer)sp); /* FILTER */ n = 0; s1 = XmStringCreateLocalized((char *)"filter:"); XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, REVSCL_BUTTON(sp)); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNlabelString, s1); n++; XtSetArg(args[n], XmNmarginHeight, CONTROLS_MARGIN); n++; XtSetArg(args[n], XmNrecomputeSize, false); n++; XtSetArg(args[n], XmNshadowThickness, 0); n++; XtSetArg(args[n], XmNhighlightThickness, 0); n++; XtSetArg(args[n], XmNfillOnArm, false); n++; FILTER_LABEL(sp) = XtCreateManagedWidget("filter-label", xmLabelWidgetClass, CONTROLS(sp), args, n); XmStringFree(s1); /* filter order */ n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNresizeWidth, false); n++; XtSetArg(args[n], XmNcolumns, 3); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, FILTER_LABEL(sp)); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, FILTER_LABEL(sp)); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNmarginHeight, CONTROLS_MARGIN); n++; XtSetArg(args[n], XmNrecomputeSize, false); n++; FILTER_ORDER_TEXT(sp) = make_textfield_widget("filter-order", CONTROLS(sp), args, n, ACTIVATABLE, NO_COMPLETER); XmTextSetString(FILTER_ORDER_TEXT(sp), (char *)" 20"); XtAddCallback(FILTER_ORDER_TEXT(sp), XmNactivateCallback, filter_order_activate_callback, (XtPointer)sp); #define ARROW_SIZE 12 n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, FILTER_ORDER_TEXT(sp)); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, FILTER_ORDER_TEXT(sp)); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNheight, ARROW_SIZE); n++; XtSetArg(args[n], XmNwidth, ARROW_SIZE); n++; XtSetArg(args[n], XmNborderWidth, 0); n++; XtSetArg(args[n], XmNmarginWidth, 0); n++; XtSetArg(args[n], XmNarmColor, ss->selection_color); n++; FILTER_ORDER_DOWN(sp) = make_pushbutton_widget("", CONTROLS(sp), args, n); XtAddEventHandler(FILTER_ORDER_DOWN(sp), KeyPressMask, false, graph_key_press, (XtPointer)sp); XtAddCallback(FILTER_ORDER_DOWN(sp), XmNactivateCallback, filter_order_down_callback, (XtPointer)sp); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, FILTER_ORDER_DOWN(sp)); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, FILTER_ORDER_TEXT(sp)); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNheight, ARROW_SIZE); n++; XtSetArg(args[n], XmNwidth, ARROW_SIZE); n++; XtSetArg(args[n], XmNborderWidth, 0); n++; XtSetArg(args[n], XmNmarginWidth, 0); n++; XtSetArg(args[n], XmNarmColor, ss->selection_color); n++; FILTER_ORDER_UP(sp) = make_pushbutton_widget("", CONTROLS(sp), args, n); XtAddEventHandler(FILTER_ORDER_UP(sp), KeyPressMask, false, graph_key_press, (XtPointer)sp); XtAddCallback(FILTER_ORDER_UP(sp), XmNactivateCallback, filter_order_up_callback, (XtPointer)sp); n = 0; s1 = XmStringCreateLocalized((char *)""); XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, REVERB_BUTTON(sp)); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNheight, 16); n++; XtSetArg(args[n], XmNmarginWidth, 0); n++; XtSetArg(args[n], XmNtopOffset, 2); n++; XtSetArg(args[n], XmNspacing, 0); n++; XtSetArg(args[n], XmNlabelString, s1); n++; if (ss->toggle_size > 0) {XtSetArg(args[n], XmNindicatorSize, ss->toggle_size); n++;} XtSetArg(args[n], XmNselectColor, ss->selection_color); n++; FILTER_BUTTON(sp) = make_togglebutton_widget("fltoff", CONTROLS(sp), args, n); XtAddEventHandler(FILTER_BUTTON(sp), KeyPressMask, false, graph_key_press, (XtPointer)sp); XtAddCallback(FILTER_BUTTON(sp), XmNvalueChangedCallback, filter_button_callback, (XtPointer)sp); XmStringFree(s1); n = 0; s1 = XmStringCreateLocalized((char *)"hz"); XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, FILTER_BUTTON(sp)); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNrightWidget, FILTER_BUTTON(sp)); n++; XtSetArg(args[n], XmNlabelString, s1); n++; XtSetArg(args[n], XmNvalue, sp->filter_control_in_hz); n++; if (ss->toggle_size > 0) {XtSetArg(args[n], XmNindicatorSize, ss->toggle_size); n++;} XtSetArg(args[n], XmNselectColor, ss->selection_color); n++; FILTER_HZ_BUTTON(sp) = make_togglebutton_widget("flthz", CONTROLS(sp), args, n); XtAddEventHandler(FILTER_HZ_BUTTON(sp), KeyPressMask, false, graph_key_press, (XtPointer)sp); XtAddCallback(FILTER_HZ_BUTTON(sp), XmNvalueChangedCallback, filter_hz_callback, (XtPointer)sp); XmStringFree(s1); n = 0; s1 = XmStringCreateLocalized((char *)"dB"); XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, FILTER_HZ_BUTTON(sp)); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNrightWidget, FILTER_HZ_BUTTON(sp)); n++; XtSetArg(args[n], XmNlabelString, s1); n++; XtSetArg(args[n], XmNvalue, sp->filter_control_in_dB); n++; if (ss->toggle_size > 0) {XtSetArg(args[n], XmNindicatorSize, ss->toggle_size); n++;} XtSetArg(args[n], XmNselectColor, ss->selection_color); n++; FILTER_DB_BUTTON(sp) = make_togglebutton_widget("fltdB", CONTROLS(sp), args, n); XtAddEventHandler(FILTER_DB_BUTTON(sp), KeyPressMask, false, graph_key_press, (XtPointer)sp); XtAddCallback(FILTER_DB_BUTTON(sp), XmNvalueChangedCallback, filter_dB_callback, (XtPointer)sp); XmStringFree(s1); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, FILTER_ORDER_DOWN(sp)); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, FILTER_ORDER_DOWN(sp)); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNrightWidget, FILTER_DB_BUTTON(sp)); n++; XtSetArg(args[n], XmNmarginHeight, CONTROLS_MARGIN); n++; FILTER_COEFFS_TEXT(sp) = make_textfield_widget("filter-text", CONTROLS(sp), args, n, ACTIVATABLE, add_completer_func(filename_completer, NULL)); XtAddCallback(FILTER_COEFFS_TEXT(sp), XmNactivateCallback, filter_activate_callback, (XtPointer)sp); /* FILTER GRAPH */ n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, FILTER_COEFFS_TEXT(sp)); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_POSITION); n++; XtSetArg(args[n], XmNleftPosition, 4); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n++; XtSetArg(args[n], XmNrightPosition, 98); n++; XtSetArg(args[n], XmNallowResize, true); n++; XtSetArg(args[n], XmNshadowType, XmSHADOW_ETCHED_IN); n++; XtSetArg(args[n], XmNshadowThickness, 4); n++; FILTER_FRAME(sp) = XtCreateManagedWidget("filter-frame", xmFrameWidgetClass, CONTROLS(sp), args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->highlight_color); n++; n = attach_all_sides(args, n); XtSetArg(args[n], XmNallowResize, true); n++; FILTER_GRAPH(sp) = XtCreateManagedWidget("filter-window", xmDrawingAreaWidgetClass, FILTER_FRAME(sp), args, n); XtAddCallback(FILTER_GRAPH(sp), XmNresizeCallback, filter_drawer_resize, (XtPointer)sp); XtAddCallback(FILTER_GRAPH(sp), XmNexposeCallback, filter_drawer_resize, (XtPointer)sp); sp->flt = new_env_editor(); XtAddEventHandler(FILTER_GRAPH(sp), ButtonPressMask, false, filter_drawer_button_press, sp); XtAddEventHandler(FILTER_GRAPH(sp), ButtonMotionMask, false, filter_drawer_button_motion, sp); XtAddEventHandler(FILTER_GRAPH(sp), ButtonReleaseMask, false, filter_drawer_button_release, sp); XtAddEventHandler(FILTER_GRAPH(sp), KeyPressMask, false, graph_key_press, (XtPointer)sp); free(n1); free(n2); free(n3); free(n4); free(n5); free(n6); free(n7); free(n8); free(n9); free(n10); free(n11); free(n12); /* end if control-panel */ if (sound_style(ss) == SOUNDS_IN_NOTEBOOK) { char *name; name = just_filename(sp->short_filename); /* copies */ if (strlen(name) > 8) name[8] = '\0'; n = 0; XtSetArg(args[n], XmNbackground, ss->graph_color); n++; XtSetArg(args[n], XmNnotebookChildType, XmMAJOR_TAB); n++; XtSetArg(args[n], XmNuserData, sp->index); n++; sp->tab = XtCreateManagedWidget(name, xmPushButtonWidgetClass, SOUND_PANE(ss), args, n); free(name); } if (sound_style(ss) != SOUNDS_IN_SEPARATE_WINDOWS) run_new_widget_hook(SND_PANE(sp)); else run_new_widget_hook(sp->dialog); #if WITH_RELATIVE_PANES if (sound_style(ss) == SOUNDS_VERTICAL) add_sash_watchers(SOUND_PANE(ss)); /* add in any case since we might later change the sense of with_relative_panes */ #endif } /* new sound ss */ else { /* re-manage currently inactive chan */ int k; if (sound_style(ss) == SOUNDS_IN_SEPARATE_WINDOWS) { title = (char *)calloc(PRINT_BUFFER_SIZE, sizeof(char)); snprintf(title, PRINT_BUFFER_SIZE, "%d: %s", snd_slot, sp->short_filename); XtVaSetValues(sp->dialog, XmNtitle, title, NULL); free(title); if (!XtIsManaged(sp->dialog)) XtManageChild(sp->dialog); } for (i = 0; i < NUM_SND_WIDGETS - 1; i++) if ((sw[i]) && (!XtIsManaged(sw[i])) && (in_show_controls(ss) || (i != W_amp_form))) XtManageChild(sw[i]); for (k = 0; k < nchans; k++) add_channel_window(sp, k, chan_min_y, 0, NULL, WITH_FW_BUTTONS, WITH_EVENTS); set_button_label(NAME_LABEL(sp), shortname_indexed(sp)); XtVaSetValues(SND_PANE(sp), XmNuserData, sp->index, NULL); if (sound_style(ss) == SOUNDS_IN_NOTEBOOK) { char *name; name = just_filename(sp->short_filename); set_label(sp->tab, name); free(name); } } map_over_children(SOUND_PANE(ss), color_sashes); if (!(in_show_controls(ss))) hide_controls(sp); else show_controls(sp); if (sp->nchans == 1) { XmToggleButtonSetState(UNITE_BUTTON(sp), false, false); XtUnmanageChild(UNITE_BUTTON(sp)); if (ss->active_sounds == 0) /* ticked at the end in snd-file.c */ { XmToggleButtonSetState(SYNC_BUTTON(sp), false, false); XtUnmanageChild(SYNC_BUTTON(sp)); } else { for_each_sound(manage_sync_button); } } else { for_each_sound(manage_sync_button); } attach_status_area(sp); add_sound_data(filename, sp, WITH_GRAPH); if (cant_write(sp->filename)) sp->file_read_only = FILE_READ_ONLY; if ((sp->file_read_only == FILE_READ_ONLY) || (sp->user_read_only == FILE_READ_ONLY)) show_lock(sp); else hide_lock(sp); if (old_name) status_report(sp, "(translated %s)", old_name); if (sound_style(ss) != SOUNDS_IN_SEPARATE_WINDOWS) { reset_controls(sp); } else { XtVaSetValues(sp->dialog, XmNwidth, 100, XmNheight, 100, NULL); /* this is not redundant -- apparently they're trying to ignore size resets to the "current" */ /* value, but forgot that unmanage/remanage does not return to the previous size */ XtVaSetValues(sp->dialog, XmNwidth, (Dimension)(widget_width(MAIN_SHELL(ss))), XmNheight, (Dimension)(chan_min_y * nchans), /* bugfix thanks to Paul @pobox */ NULL); } after_open(sp); if (free_filename) free(filename); return(sp); } void update_sound_label(snd_info *sp) { if (has_widgets(sp)) set_button_label(NAME_LABEL(sp), shortname_indexed(sp)); } void snd_info_cleanup(snd_info *sp) { if (has_widgets(sp)) { clear_status_area(sp); if (SYNC_BUTTON(sp)) { XtVaSetValues(SYNC_BUTTON(sp), XmNset, false, NULL); XtVaSetValues(EXPAND_RIGHT_BUTTON(sp), XmNset, false, NULL); XtVaSetValues(CONTRAST_RIGHT_BUTTON(sp), XmNset, false, NULL); XtVaSetValues(SPEED_ARROW(sp), XmNset, false, NULL); XtVaSetValues(FILTER_BUTTON(sp), XmNset, false, NULL); XtVaSetValues(REVERB_BUTTON(sp), XmNset, false, NULL); XmToggleButtonSetState(UNITE_BUTTON(sp), false, false); sp->channel_style = CHANNELS_SEPARATE; if (sound_style(ss) == SOUNDS_IN_NOTEBOOK) { set_label(sp->tab, "none"); XmChangeColor(sp->tab, ss->graph_color); } XtUnmanageChild(SND_PANE(sp)); } if ((sp->dialog) && (XtIsManaged(sp->dialog))) XtUnmanageChild(sp->dialog); } } static Xen reflect_file_close_in_sync(Xen hook_or_reason) { int reason; #if HAVE_SCHEME reason = Xen_integer_to_C_int(s7_let_ref(s7, hook_or_reason, s7_make_symbol(s7, "reason"))); #else reason = Xen_integer_to_C_int(hook_or_reason); #endif if ((reason == FILE_CLOSED) && /* snd-file.c */ (ss->active_sounds == 1)) { snd_info *sp; sp = any_selected_sound(); if ((sp) && (sp->nchans == 1)) { XtUnmanageChild(SYNC_BUTTON(sp)); attach_status_area(sp); } } return(Xen_false); } Xen_wrap_1_arg(reflect_file_close_in_sync_w, reflect_file_close_in_sync) void set_sound_pane_file_label(snd_info *sp, const char *str) { if (!(mus_strcmp(sp->name_string, str))) { if (sp->name_string) free(sp->name_string); sp->name_string = mus_strdup(str); set_button_label(SND_NAME(sp), str); /* this causes an expose event, so it's worth minimizing */ } } void color_filter_waveform(Pixel color) { int i; XSetForeground(MAIN_DISPLAY(ss), ss->fltenv_data_gc, color); for (i = 0; i < ss->max_sounds; i++) { snd_info *sp; sp = ss->sounds[i]; if ((sp) && (sp->inuse == SOUND_NORMAL)) display_filter_env(sp); } } void show_controls(snd_info *sp) { Dimension hgt; XtVaGetValues(FILTER_LABEL(sp), XmNy, &hgt, NULL); if (XtIsManaged(CONTROLS(sp))) XtUnmanageChild(CONTROLS(sp)); XtVaSetValues(CONTROLS(sp), XmNpaneMinimum, hgt, XmNpaneMaximum, hgt, NULL); XtManageChild(CONTROLS(sp)); XtVaSetValues(CONTROLS(sp), XmNpaneMinimum, 1, XmNpaneMaximum, LOTSA_PIXELS, NULL); } void hide_controls(snd_info *sp) { XtUnmanageChild(CONTROLS(sp)); } bool showing_controls(snd_info *sp) { return((bool)(XtIsManaged(CONTROLS(sp)))); } void show_all_controls(void) { int i; for (i = 0; i < ss->max_sounds; i++) { snd_info *sp; sp = ss->sounds[i]; if ((sp) && (sp->inuse == SOUND_NORMAL)) show_controls(sp); } } void hide_all_controls(void) { int i; for (i = 0; i < ss->max_sounds; i++) { snd_info *sp; sp = ss->sounds[i]; if ((sp) && (sp->inuse == SOUND_NORMAL)) hide_controls(sp); } } int control_panel_height(snd_info *sp) { return(widget_height(CONTROLS(sp))); } /* -------- PROGRESS REPORT -------- */ void progress_report(chan_info *cp, mus_float_t pct) { int which; snd_info *sp; sp = cp->sound; if ((!has_widgets(sp)) || (sp->inuse != SOUND_NORMAL)) return; which = (int)(pct * NUM_HOURGLASSES); if (which >= NUM_HOURGLASSES) which = NUM_HOURGLASSES - 1; if (which < 0) which = 0; if ((hourglasses[which]) && (cp->chan < sp->num_progress_widgets) && ((cp->chan == 0) || (sp->channel_style != CHANNELS_SUPERIMPOSED))) { XtVaSetValues(PROGRESS_ICON(cp), XmNlabelPixmap, hourglasses[which], NULL); XmUpdateDisplay(PROGRESS_ICON(cp)); } check_for_event(); } void finish_progress_report(chan_info *cp) { snd_info *sp; sp = cp->sound; if ((!has_widgets(sp)) || (sp->inuse != SOUND_NORMAL)) return; if ((cp->chan < sp->num_progress_widgets) && ((cp->chan == 0) || (sp->channel_style != CHANNELS_SUPERIMPOSED))) { XtVaSetValues(PROGRESS_ICON(cp), XmNlabelPixmap, blank_pixmap, NULL); XmUpdateDisplay(PROGRESS_ICON(cp)); hide_stop_sign(sp); } } void start_progress_report(chan_info *cp) { snd_info *sp; sp = cp->sound; if ((!has_widgets(sp)) || (sp->inuse != SOUND_NORMAL)) return; if ((cp->chan < sp->num_progress_widgets) && ((cp->chan == 0) || (sp->channel_style != CHANNELS_SUPERIMPOSED))) { XtVaSetValues(PROGRESS_ICON(cp), XmNlabelPixmap, hourglasses[0], NULL); XmUpdateDisplay(PROGRESS_ICON(cp)); show_stop_sign(sp); } } void reflect_sound_selection(snd_info *sp) { /* sp is the newly selected sound, ss->selected_sound is the previous one */ snd_info *osp = NULL; if (ss->selected_sound != NO_SELECTION) osp = ss->sounds[ss->selected_sound]; if ((osp) && (sp != osp) && (osp->inuse == SOUND_NORMAL)) { XmChangeColor(SND_NAME(osp), ss->highlight_color); if (sound_style(ss) == SOUNDS_IN_NOTEBOOK) XmChangeColor(osp->tab, ss->graph_color); } if (sp->selected_channel != NO_SELECTION) { XmChangeColor(SND_NAME(sp), ss->white); if (sound_style(ss) == SOUNDS_IN_NOTEBOOK) { int page, current_page; XmNotebookPageStatus status; XmNotebookPageInfo info; XmChangeColor(sp->tab, ss->selected_graph_color); XtVaGetValues(SOUND_PANE(ss), XmNcurrentPageNumber, ¤t_page, NULL); XtVaGetValues(sp->tab, XmNpageNumber, &page, NULL); if (page != current_page) { status = XmNotebookGetPageInfo(SOUND_PANE(ss), page, &info); if (status == XmPAGE_FOUND) { XtVaSetValues(SOUND_PANE(ss), XmNcurrentPageNumber, page, NULL); } } } } } /* -------- controls dialog -------- */ static Widget controls_dialog = NULL; enum {EXPAND_HOP, EXPAND_LENGTH, EXPAND_RAMP, EXPAND_JITTER, CONTRAST_AMP, REVERB_LOWPASS, REVERB_FEEDBACK}; static Widget controls[7]; static void reset_all_sliders(void) { expand_control_set_hop(DEFAULT_EXPAND_CONTROL_HOP); expand_control_set_length(DEFAULT_EXPAND_CONTROL_LENGTH); expand_control_set_ramp(DEFAULT_EXPAND_CONTROL_RAMP); expand_control_set_jitter(DEFAULT_EXPAND_CONTROL_JITTER); contrast_control_set_amp(DEFAULT_CONTRAST_CONTROL_AMP); reverb_control_set_lowpass(DEFAULT_REVERB_CONTROL_LOWPASS); reverb_control_set_feedback(DEFAULT_REVERB_CONTROL_FEEDBACK); XtVaSetValues(controls[EXPAND_HOP], XmNvalue, (int)(expand_control_hop(ss) * 1000), NULL); XtVaSetValues(controls[EXPAND_LENGTH], XmNvalue, (int)(expand_control_length(ss) * 1000), NULL); XtVaSetValues(controls[EXPAND_RAMP], XmNvalue, (int)(expand_control_ramp(ss) * 1000), NULL); XtVaSetValues(controls[EXPAND_JITTER], XmNvalue, (int)(expand_control_jitter(ss) * 1000), NULL); XtVaSetValues(controls[CONTRAST_AMP], XmNvalue, (int)(contrast_control_amp(ss) * 1000), NULL); XtVaSetValues(controls[REVERB_LOWPASS], XmNvalue, (int)(reverb_control_lowpass(ss) * 1000), NULL); XtVaSetValues(controls[REVERB_FEEDBACK], XmNvalue, (int)(reverb_control_feedback(ss) * 1000), NULL); } static void controls_reset_callback(Widget w, XtPointer context, XtPointer info) { if (XmGetFocusWidget(controls_dialog) == XmMessageBoxGetChild(controls_dialog, XmDIALOG_OK_BUTTON)) reset_all_sliders(); } static void controls_help_callback(Widget w, XtPointer context, XtPointer info) { snd_help("More controls", "This dialog controls all the otherwise hidden control-panel variables.\n\ Expand-hop sets the time in seconds between successive grains.\n\ Expand-length sets the length of each grain.\n\ Expand-ramp sets the ramp-time in the grain envelope.\n\ Expand-jitter sets the grain timing jitter.\n\ Contrast-amp sets the prescaler for contrast-enhancement.\n\ Reverb-lowpass sets the feedback lowpass filter coeficient.\n\ Reverb-feedback sets the scaler on the feedback.", WITHOUT_WORD_WRAP); } static void controls_quit_callback(Widget w, XtPointer context, XtPointer info) { XtUnmanageChild(controls_dialog); } static void expand_hop_callback(Widget w, XtPointer context, XtPointer info) { XmScaleCallbackStruct *cbs = (XmScaleCallbackStruct *)info; expand_control_set_hop(cbs->value * 0.001); } static void expand_length_callback(Widget w, XtPointer context, XtPointer info) { XmScaleCallbackStruct *cbs = (XmScaleCallbackStruct *)info; expand_control_set_length(cbs->value * 0.001); } static void expand_ramp_callback(Widget w, XtPointer context, XtPointer info) { XmScaleCallbackStruct *cbs = (XmScaleCallbackStruct *)info; expand_control_set_ramp(cbs->value * 0.001); } static void expand_jitter_callback(Widget w, XtPointer context, XtPointer info) { XmScaleCallbackStruct *cbs = (XmScaleCallbackStruct *)info; expand_control_set_jitter(cbs->value * 0.001); } static void contrast_amp_callback(Widget w, XtPointer context, XtPointer info) { XmScaleCallbackStruct *cbs = (XmScaleCallbackStruct *)info; contrast_control_set_amp(cbs->value * 0.001); } static void reverb_lowpass_callback(Widget w, XtPointer context, XtPointer info) { XmScaleCallbackStruct *cbs = (XmScaleCallbackStruct *)info; reverb_control_set_lowpass(cbs->value * 0.001); } static void reverb_feedback_callback(Widget w, XtPointer context, XtPointer info) { XmScaleCallbackStruct *cbs = (XmScaleCallbackStruct *)info; reverb_control_set_feedback(cbs->value * 0.001); } void make_controls_dialog(void) { #define MSG_BOX(Dialog, Child) XmMessageBoxGetChild(Dialog, Child) if (!controls_dialog) { int n; Arg args[32]; XmString go_away, xhelp, titlestr, xreset; Widget mainform, slider, reset_button; go_away = XmStringCreateLocalized((char *)I_GO_AWAY); xhelp = XmStringCreateLocalized((char *)I_HELP); titlestr = XmStringCreateLocalized((char *)"More controls"); xreset = XmStringCreateLocalized((char *)"Reset"); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNhelpLabelString, xhelp); n++; XtSetArg(args[n], XmNokLabelString, xreset); n++; XtSetArg(args[n], XmNcancelLabelString, go_away); n++; XtSetArg(args[n], XmNautoUnmanage, false); n++; XtSetArg(args[n], XmNdialogTitle, titlestr); n++; XtSetArg(args[n], XmNresizePolicy, XmRESIZE_GROW); n++; XtSetArg(args[n], XmNnoResize, false); n++; XtSetArg(args[n], XmNtransient, false); n++; XtSetArg(args[n], XmNwidth, 400); n++; controls_dialog = XmCreateTemplateDialog(MAIN_SHELL(ss), (char *)"More controls", args, n); reset_button = MSG_BOX(controls_dialog, XmDIALOG_OK_BUTTON); XtAddCallback(controls_dialog, XmNhelpCallback, controls_help_callback, NULL); /* XtAddCallback(controls_dialog, XmNokCallback, controls_reset_callback, NULL); */ XtAddCallback(reset_button, XmNactivateCallback, controls_reset_callback, NULL); XtAddCallback(controls_dialog, XmNcancelCallback, controls_quit_callback, NULL); XmStringFree(xhelp); XmStringFree(go_away); XmStringFree(titlestr); XmStringFree(xreset); XtVaSetValues(MSG_BOX(controls_dialog, XmDIALOG_OK_BUTTON), XmNarmColor, ss->selection_color, NULL); XtVaSetValues(MSG_BOX(controls_dialog, XmDIALOG_HELP_BUTTON), XmNarmColor, ss->selection_color, NULL); XtVaSetValues(MSG_BOX(controls_dialog, XmDIALOG_CANCEL_BUTTON), XmNarmColor, ss->selection_color, NULL); XtVaSetValues(MSG_BOX(controls_dialog, XmDIALOG_OK_BUTTON), XmNbackground, ss->highlight_color, NULL); XtVaSetValues(MSG_BOX(controls_dialog, XmDIALOG_HELP_BUTTON), XmNbackground, ss->highlight_color, NULL); XtVaSetValues(MSG_BOX(controls_dialog, XmDIALOG_CANCEL_BUTTON), XmNbackground, ss->highlight_color, NULL); mainform = XtVaCreateManagedWidget("formd", xmRowColumnWidgetClass, controls_dialog, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, XmNtopAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_WIDGET, XmNbottomWidget, XmMessageBoxGetChild(controls_dialog, XmDIALOG_SEPARATOR), XmNorientation, XmVERTICAL, NULL); titlestr = XmStringCreateLocalized((char *)"expand hop"); slider = XtVaCreateManagedWidget("expand-hop", xmScaleWidgetClass, mainform, XmNorientation, XmHORIZONTAL, XmNshowValue, true, XmNminimum, 1, XmNmaximum, 300, XmNvalue, (int)(expand_control_hop(ss) * 1000), XmNdecimalPoints, 3, XmNtitleString, titlestr, XmNborderWidth, 1, XmNbackground, ss->basic_color, NULL); XmStringFree(titlestr); XtAddCallback(slider, XmNvalueChangedCallback, expand_hop_callback, NULL); XtAddCallback(slider, XmNdragCallback, expand_hop_callback, NULL); controls[EXPAND_HOP] = slider; titlestr = XmStringCreateLocalized((char *)"expand length"); slider = XtVaCreateManagedWidget("expand-length", xmScaleWidgetClass, mainform, XmNorientation, XmHORIZONTAL, XmNshowValue, true, XmNminimum, 10, XmNmaximum, 500, XmNvalue, (int)(expand_control_length(ss) * 1000), XmNdecimalPoints, 3, XmNtitleString, titlestr, XmNborderWidth, 1, XmNbackground, ss->basic_color, NULL); XmStringFree(titlestr); XtAddCallback(slider, XmNvalueChangedCallback, expand_length_callback, NULL); XtAddCallback(slider, XmNdragCallback, expand_length_callback, NULL); controls[EXPAND_LENGTH] = slider; titlestr = XmStringCreateLocalized((char *)"expand ramp"); slider = XtVaCreateManagedWidget("expand-ramp", xmScaleWidgetClass, mainform, XmNorientation, XmHORIZONTAL, XmNshowValue, true, XmNminimum, 10, XmNmaximum, 500, XmNvalue, (int)(expand_control_ramp(ss) * 1000), XmNdecimalPoints, 3, XmNtitleString, titlestr, XmNborderWidth, 1, XmNbackground, ss->basic_color, NULL); XmStringFree(titlestr); XtAddCallback(slider, XmNvalueChangedCallback, expand_ramp_callback, NULL); XtAddCallback(slider, XmNdragCallback, expand_ramp_callback, NULL); controls[EXPAND_RAMP] = slider; titlestr = XmStringCreateLocalized((char *)"expand jitter"); slider = XtVaCreateManagedWidget("expand-hop", xmScaleWidgetClass, mainform, XmNorientation, XmHORIZONTAL, XmNshowValue, true, XmNminimum, 0, XmNmaximum, 200, XmNvalue, (int)(expand_control_jitter(ss) * 1000), XmNdecimalPoints, 3, XmNtitleString, titlestr, XmNborderWidth, 1, XmNbackground, ss->basic_color, NULL); XmStringFree(titlestr); XtAddCallback(slider, XmNvalueChangedCallback, expand_jitter_callback, NULL); XtAddCallback(slider, XmNdragCallback, expand_jitter_callback, NULL); controls[EXPAND_JITTER] = slider; titlestr = XmStringCreateLocalized((char *)"contrast amp"); slider = XtVaCreateManagedWidget("contrast-amp", xmScaleWidgetClass, mainform, XmNorientation, XmHORIZONTAL, XmNshowValue, true, XmNminimum, 0, XmNmaximum, 2000, XmNvalue, (int)(contrast_control_amp(ss) * 1000), XmNdecimalPoints, 3, XmNtitleString, titlestr, XmNborderWidth, 1, XmNbackground, ss->basic_color, NULL); XmStringFree(titlestr); XtAddCallback(slider, XmNvalueChangedCallback, contrast_amp_callback, NULL); XtAddCallback(slider, XmNdragCallback, contrast_amp_callback, NULL); controls[CONTRAST_AMP] = slider; titlestr = XmStringCreateLocalized((char *)"reverb lowpass"); slider = XtVaCreateManagedWidget("reverb-lowpass", xmScaleWidgetClass, mainform, XmNorientation, XmHORIZONTAL, XmNshowValue, true, XmNminimum, 0, XmNmaximum, 1000, XmNvalue, (int)(reverb_control_lowpass(ss) * 1000), XmNdecimalPoints, 3, XmNtitleString, titlestr, XmNborderWidth, 1, XmNbackground, ss->basic_color, NULL); XmStringFree(titlestr); XtAddCallback(slider, XmNvalueChangedCallback, reverb_lowpass_callback, NULL); XtAddCallback(slider, XmNdragCallback, reverb_lowpass_callback, NULL); controls[REVERB_LOWPASS] = slider; titlestr = XmStringCreateLocalized((char *)"reverb feedback"); slider = XtVaCreateManagedWidget("reverb-feedback", xmScaleWidgetClass, mainform, XmNorientation, XmHORIZONTAL, XmNshowValue, true, XmNminimum, 0, XmNmaximum, 1250, XmNvalue, (int)(reverb_control_feedback(ss) * 1000), XmNdecimalPoints, 3, XmNtitleString, titlestr, XmNborderWidth, 1, XmNbackground, ss->basic_color, NULL); XmStringFree(titlestr); XtAddCallback(slider, XmNvalueChangedCallback, reverb_feedback_callback, NULL); XtAddCallback(slider, XmNdragCallback, reverb_feedback_callback, NULL); controls[REVERB_FEEDBACK] = slider; set_dialog_widget(CONTROLS_DIALOG, controls_dialog); } if (!XtIsManaged(controls_dialog)) XtManageChild(controls_dialog); } /* ---------------------------------------- */ static Xen g_sound_widgets(Xen snd) { #define H_sound_widgets "(" S_sound_widgets " :optional snd): a list of \ widgets: (0)pane (1)name (2)control-panel (3)status area (4)play-button (5)filter-env (6)unite-button (7)name-label (8)name-icon (9)sync-button" snd_info *sp; Snd_assert_sound(S_sound_widgets, snd, 1); sp = get_sp(snd); if (sp == NULL) return(snd_no_such_sound_error(S_sound_widgets, snd)); if (!has_widgets(sp)) return(Xen_empty_list); return(Xen_cons(Xen_wrap_widget(SND_PANE(sp)), Xen_cons(Xen_wrap_widget(SND_NAME(sp)), Xen_cons(Xen_wrap_widget(CONTROLS(sp)), Xen_cons(Xen_wrap_widget(STATUS_AREA(sp)), #if WITH_AUDIO Xen_cons(Xen_wrap_widget(PLAY_BUTTON(sp)), #else Xen_cons(Xen_false, #endif Xen_cons(Xen_wrap_widget(FILTER_GRAPH(sp)), /* this is the drawingarea widget */ Xen_cons(Xen_wrap_widget(UNITE_BUTTON(sp)), Xen_cons(Xen_false, Xen_cons(Xen_wrap_widget(LOCK_OR_BOMB(sp)), Xen_cons(Xen_wrap_widget(SYNC_BUTTON(sp)), Xen_empty_list))))))))))); } Xen_wrap_1_optional_arg(g_sound_widgets_w, g_sound_widgets) void g_init_gxsnd(void) { Xen_add_to_hook_list(ss->snd_open_file_hook, reflect_file_close_in_sync_w, "sync-open-file-watcher", "sound sync open-file-hook handler"); Xen_define_safe_procedure(S_sound_widgets, g_sound_widgets_w, 0, 1, 0, H_sound_widgets); } #define FALLBACK_FONT "fixed" #define DEFAULT_LISTENER_FONT "9x15" #define DEFAULT_FONTLIST "9x15" #define HIGHLIGHT_COLOR "ivory1" #define BASIC_COLOR "ivory2" #define POSITION_COLOR "ivory3" #define ZOOM_COLOR "ivory4" #define CURSOR_COLOR "red" #define SELECTION_COLOR "lightsteelblue1" #define ENVED_WAVEFORM_COLOR "blue" #define MIX_COLOR "darkgray" #define GRAPH_COLOR "white" #define SELECTED_GRAPH_COLOR "white" #define DATA_COLOR "black" #define SELECTED_DATA_COLOR "black" #define MARK_COLOR "red" #define LISTENER_COLOR "AliceBlue" #define LISTENER_TEXT_COLOR "black" #define LIGHT_BLUE_COLOR "lightsteelblue1" #define LIGHTER_BLUE_COLOR "AliceBlue" #define WHITE_COLOR "white" #define BLACK_COLOR "black" #define GREEN_COLOR "green2" #define RED_COLOR "red" #define YELLOW_COLOR "yellow" #define TEXT_FOCUS_COLOR "white" #define FILTER_CONTROL_WAVEFORM_COLOR "blue" #define SASH_COLOR "lightgreen" #define CHANNEL_SASH_INDENT -10 #define CHANNEL_SASH_SIZE 0 /* 0 means: use Motif default size */ #define POSITION_SLIDER_WIDTH 13 #define ZOOM_SLIDER_WIDTH 10 #if (!__linux__) && (!_LINUX__) #define TOGGLE_SIZE 0 #else #define TOGGLE_SIZE 15 #endif #define CHANNEL_MIN_HEIGHT 150 /* open size (set to 5 immediately thereafter) */ /* paned window default setup is not very smart, so we force these to be this size to begin with */ /* this number is only a first approximation -- we try not to expand below the screen */ /* if too small (i.e. 100), the scrollbars are sometimes messed up on the initial layout */ #define SASH_SIZE 16 #define SASH_INDENT -20 #define AUTO_RESIZE_DEFAULT 1 #define INITIAL_WINDOW_WIDTH 700 #define INITIAL_WINDOW_HEIGHT 300 static void window_close(Widget w, XtPointer context, XtPointer info) { /* this is called from the window manager close event, not (exit) or the File:Exit item */ snd_exit_cleanly(EXIT_FORCED); } static XtIntervalId auto_update_proc = 0; static void auto_update_check(XtPointer context, XtIntervalId *id) { if (auto_update_interval(ss) > 0.0) { if (!(play_in_progress())) for_each_sound(sound_not_current); auto_update_proc = XtAppAddTimeOut(MAIN_APP(ss), (unsigned long)(auto_update_interval(ss) * 1000), (XtTimerCallbackProc)auto_update_check, context); } else auto_update_proc = 0; } void auto_update_restart(void) { if (auto_update_proc == 0) auto_update_proc = XtAppAddTimeOut(MAIN_APP(ss), (unsigned long)(auto_update_interval(ss) * 1000), (XtTimerCallbackProc)auto_update_check, (XtPointer)NULL); } /* handle iconification */ static Widget *iconify_active_dialogs = NULL; static void minify_maxify_window(Widget w, XtPointer context, XEvent *event, Boolean *cont) { XMapEvent *ev = (XMapEvent *)event; int i; if ((!ss) || (!(ss->dialogs))) return; /* ev->type can be several things, but the ones we care about here are * MapNotify and UnmapNotify. Snd dialogs are "windows" in X-jargon, so * when the main window is minimized (iconified), other active dialogs * aren't also closed unless we mess with them explicitly here. We keep * a list of created dialogs, and depend on XtIsManaged to tell us which * ones need to be unmanaged. But, if the user has several "desks", a change * of desk can also generate an unmap event, and if we dismiss the dialogs, * they don't come back upon remap; if we save a list of live dialogs, they * don't return to their previous location upon being re-managed. We * need to see just iconfication events here, but there's no way I can * see to distinguish an iconify event from a desk event (WM_STATE atom state * of property changed event is identical etc), so I'll do what I can... * This problem may be a side-effect of using non-transient dialogs: * perhaps XSetTransientFor would handle this more cleanly? * * Also, ideally we'd equalize/relative-panes upon maxify, but ICCC thinks maxify * is the same as map (i.e. from iconified state), and the only difference * I can see in the mwm code is the window size. * * a rumor in the air that what we need is to catch StructureNotify event, then * check in that for UnmapNotify */ if (ev->type == UnmapNotify) { if (iconify_active_dialogs) free(iconify_active_dialogs); iconify_active_dialogs = (Widget *)calloc(ss->num_dialogs, sizeof(Widget)); for (i = 0; i < ss->num_dialogs; i++) if (ss->dialogs[i]) { if (XtIsManaged(ss->dialogs[i])) iconify_active_dialogs[i] = ss->dialogs[i]; XtUnmanageChild(ss->dialogs[i]); } } else { if (ev->type == MapNotify) { if (iconify_active_dialogs) { for (i = 0; i < ss->num_dialogs; i++) if (iconify_active_dialogs[i]) XtManageChild(iconify_active_dialogs[i]); free(iconify_active_dialogs); iconify_active_dialogs = NULL; } } } } #ifndef _MSC_VER #include static jmp_buf top_level_jump; void top_level_catch(int ignore); void top_level_catch(int ignore) { longjmp(top_level_jump, 1); } #endif static char **auto_open_file_names = NULL; static int auto_open_files = 0; static bool noglob = false, noinit = false, batch = false, nostdin = false; #if HAVE_EXTENSION_LANGUAGE static XtInputId stdin_id = 0; static void get_stdin_string(XtPointer context, int *fd, XtInputId *id) { int size; ssize_t bytes; char *buf; buf = (char *)calloc(1024, sizeof(char)); size = 1024; bytes = read(*fd, buf, 1024); if (bytes <= 0) { /* redirected to /dev/null?? -- apparently in kde/kfm the process is started without stdin? */ XtRemoveInput(stdin_id); stdin_id = 0; } else { while (bytes == 1024) { size += 1024; buf = (char *)realloc(buf, size); bytes = read(*fd, (char *)(buf + size - 1024), 1024); } snd_eval_stdin_str(buf); } free(buf); } #endif static void startup_funcs(void) { Atom wm_delete_window; Display *dpy; Widget shell; static int auto_open_ctr = 0; ss->file_monitor_ok = initialize_file_monitor(); shell = ss->mainshell; dpy = MAIN_DISPLAY(ss); #ifndef __alpha__ add_menu_drop(); #endif /* trap outer-level Close for cleanup check */ wm_delete_window = XmInternAtom(dpy, (char *)"WM_DELETE_WINDOW", false); XmAddWMProtocolCallback(shell, wm_delete_window, window_close, NULL); XtAddEventHandler(shell, StructureNotifyMask, false, minify_maxify_window, NULL); ss->graph_cursor = XCreateFontCursor(XtDisplay(MAIN_SHELL(ss)), in_graph_cursor(ss)); ss->wait_cursor = XCreateFontCursor(XtDisplay(MAIN_SHELL(ss)), XC_watch); ss->bounds_cursor = XCreateFontCursor(XtDisplay(MAIN_SHELL(ss)), XC_sb_h_double_arrow); ss->yaxis_cursor = XCreateFontCursor(XtDisplay(MAIN_SHELL(ss)), XC_sb_v_double_arrow); ss->play_cursor = XCreateFontCursor(XtDisplay(MAIN_SHELL(ss)), XC_sb_right_arrow); ss->loop_play_cursor = XCreateFontCursor(XtDisplay(MAIN_SHELL(ss)), XC_sb_left_arrow); #if HAVE_EXTENSION_LANGUAGE snd_load_init_file(noglob, noinit); #endif #if (!_MSC_VER) && HAVE_EXTENSION_LANGUAGE && !__MINGW32__ if (!nostdin) { signal(SIGTTIN, SIG_IGN); signal(SIGTTOU, SIG_IGN); /* these signals are sent by a shell if we start Snd as a background process, * but try to read stdin (needed to support the emacs subjob connection). If * we don't do this, the background job is suspended when the shell sends SIGTTIN. */ stdin_id = XtAppAddInput(MAIN_APP(ss), STDIN_FILENO, (XtPointer)XtInputReadMask, get_stdin_string, NULL); } #endif while (auto_open_ctr < auto_open_files) auto_open_ctr = handle_next_startup_arg(auto_open_ctr, auto_open_file_names, false, auto_open_files); if (ss->init_window_width > 0) set_widget_width(MAIN_SHELL(ss), ss->init_window_width); if (ss->init_window_height > 0) set_widget_height(MAIN_SHELL(ss), ss->init_window_height); if (ss->init_window_x != DEFAULT_INIT_WINDOW_X) set_widget_x(MAIN_SHELL(ss), ss->init_window_x); if (ss->init_window_y != DEFAULT_INIT_WINDOW_Y) set_widget_y(MAIN_SHELL(ss), ss->init_window_y); if (!ss->file_monitor_ok) { if (auto_update_interval(ss) > 0.0) XtAppAddTimeOut(MAIN_APP(ss), (unsigned long)(auto_update_interval(ss) * 1000), auto_update_check, NULL); } if ((ss->sounds) && (ss->selected_sound == NO_SELECTION)) { snd_info *sp; sp = ss->sounds[0]; if ((sp) && (sp->inuse == SOUND_NORMAL) && (sp->selected_channel == NO_SELECTION)) /* don't clobber possible select-channel in loaded startup files */ select_channel(sp, 0); } if ((ss->init_window_height == 0) && (sound_style(ss) == SOUNDS_HORIZONTAL)) set_widget_height(MAIN_SHELL(ss), 200); /* otherwise it's just a title bar! */ } static void SetupIcon(Widget shell) { Display *dpy; Window root; int scr; Pixmap pix, mask; XpmAttributes attributes; dpy = XtDisplay(shell); root = DefaultRootWindow(dpy); scr = DefaultScreen(dpy); XtVaGetValues(shell, XmNdepth, &attributes.depth, XmNcolormap, &attributes.colormap, NULL); attributes.visual = DefaultVisual(dpy, scr); attributes.valuemask = XpmDepth | XpmColormap | XpmVisual; XpmCreatePixmapFromData(dpy, root, (char **)snd_icon_bits(), &pix, &mask, &attributes); if (mask) XFreePixmap(dpy, mask); XtVaSetValues(shell, XmNiconPixmap, pix, NULL); } static void muffle_warning(char *name, char *type, char *klass, char *defaultp, char **params, unsigned int *num_params) { } static void notebook_page_changed_callback(Widget w, XtPointer context, XtPointer info) { /* if page chosen via major tab click, select that sound */ XmNotebookCallbackStruct *nb = (XmNotebookCallbackStruct *)info; Widget page; if ((nb->reason == XmCR_MAJOR_TAB) && (nb->page_widget)) { page = nb->page_widget; if (page) { int index; pointer_or_int_t data; XtVaGetValues(page, XmNuserData, &data, NULL); index = (int)data; if ((index < ss->max_sounds) && (snd_ok(ss->sounds[index]))) { snd_info *sp; sp = ss->sounds[index]; if (sp->selected_channel == NO_SELECTION) select_channel(ss->sounds[index], 0); else select_channel(ss->sounds[index], sp->selected_channel); } } } } color_t get_in_between_color(color_t fg, color_t bg) { Colormap cmap; Display *dpy; int scr; XColor fg_color, bg_color, new_color; dpy = MAIN_DISPLAY(ss); scr = DefaultScreen(dpy); cmap = DefaultColormap(dpy, scr); fg_color.flags = DoRed | DoGreen | DoBlue; fg_color.pixel = fg; XQueryColor(dpy, cmap, &fg_color); bg_color.flags = DoRed | DoGreen | DoBlue; bg_color.pixel = bg; XQueryColor(dpy, cmap, &bg_color); new_color.flags = DoRed | DoGreen | DoBlue; new_color.red = (rgb_t)((fg_color.red + (2 * bg_color.red)) / 3); new_color.green = (rgb_t)((fg_color.green + (2 * bg_color.green)) / 3); new_color.blue = (rgb_t)((fg_color.blue + (2 * bg_color.blue)) / 3); if ((XAllocColor(dpy, cmap, &new_color)) == 0) return(fg); return(new_color.pixel); } static Pixel get_color(Widget shell, const char *defined_color, const char *fallback_color, const char *second_fallback_color, bool use_white) { Colormap cmap; Display *dpy; int scr; XColor tmp_color, ignore; dpy = XtDisplay(shell); scr = DefaultScreen(dpy); cmap = DefaultColormap(dpy, scr); /* I suppose we could use XQueryColors and search for the closest available, or try yet again to get XCreateColormap to behave itself */ if ((!XAllocNamedColor(dpy, cmap, defined_color, &tmp_color, &ignore)) && ((!fallback_color) || (!XAllocNamedColor(dpy, cmap, fallback_color, &tmp_color, &ignore))) && ((!second_fallback_color) || (!XAllocNamedColor(dpy, cmap, second_fallback_color, &tmp_color, &ignore)))) { /* snd_error here causes a seg fault (it builds on mainpane which has not yet been created) */ if (use_white) { fprintf(stderr, "can't get color %s -- will use white\n", defined_color); return(WhitePixel(dpy, scr)); } else { fprintf(stderr, "can't get color %s -- will use black\n", defined_color); return(BlackPixel(dpy, scr)); } } return(tmp_color.pixel); } static void save_a_color(FILE *Fp, Display *dpy, Colormap cmap, const char *name, Pixel pix, const char *ext_name) { #if HAVE_EXTENSION_LANGUAGE Status lookup_ok; XColor default_color, ignore; lookup_ok = XLookupColor(dpy, cmap, name, &default_color, &ignore); if (lookup_ok) { XColor current_color; current_color.flags = DoRed | DoGreen | DoBlue; current_color.pixel = pix; XQueryColor(dpy, cmap, ¤t_color); if ((current_color.red != default_color.red) || (current_color.green != default_color.green) || (current_color.blue != default_color.blue)) #if HAVE_FORTH fprintf(Fp, "%.3f %.3f %.3f %s set-%s drop\n", rgb_to_float(current_color.red), rgb_to_float(current_color.green), rgb_to_float(current_color.blue), S_make_color, ext_name); #else #if HAVE_SCHEME fprintf(Fp, "(set! (%s) (%s %.3f %.3f %.3f))\n", #endif #if HAVE_RUBY fprintf(Fp, "set_%s(%s(%.3f, %.3f, %.3f))\n", #endif to_proc_name(ext_name), to_proc_name(S_make_color), rgb_to_float(current_color.red), rgb_to_float(current_color.green), rgb_to_float(current_color.blue)); #endif } #endif } void save_colors(FILE *Fp) { Colormap cmap; Display *dpy; int scr; dpy = XtDisplay(ss->mainshell); scr = DefaultScreen(dpy); cmap = DefaultColormap(dpy, scr); save_a_color(Fp, dpy, cmap, BASIC_COLOR, ss->basic_color, S_basic_color); save_a_color(Fp, dpy, cmap, CURSOR_COLOR, ss->cursor_color, S_cursor_color); save_a_color(Fp, dpy, cmap, DATA_COLOR, ss->data_color, S_data_color); save_a_color(Fp, dpy, cmap, SELECTED_DATA_COLOR, ss->selected_data_color, S_selected_data_color); save_a_color(Fp, dpy, cmap, HIGHLIGHT_COLOR, ss->highlight_color, S_highlight_color); save_a_color(Fp, dpy, cmap, POSITION_COLOR, ss->position_color, S_position_color); save_a_color(Fp, dpy, cmap, ZOOM_COLOR, ss->zoom_color, S_zoom_color); save_a_color(Fp, dpy, cmap, SELECTION_COLOR, ss->selection_color, S_selection_color); save_a_color(Fp, dpy, cmap, MIX_COLOR, ss->mix_color, S_mix_color); save_a_color(Fp, dpy, cmap, ENVED_WAVEFORM_COLOR, ss->enved_waveform_color, S_enved_waveform_color); save_a_color(Fp, dpy, cmap, LISTENER_COLOR, ss->listener_color, S_listener_color); save_a_color(Fp, dpy, cmap, LISTENER_TEXT_COLOR, ss->listener_text_color, S_listener_text_color); save_a_color(Fp, dpy, cmap, GRAPH_COLOR, ss->graph_color, S_graph_color); save_a_color(Fp, dpy, cmap, SELECTED_GRAPH_COLOR, ss->selected_graph_color, S_selected_graph_color); save_a_color(Fp, dpy, cmap, MARK_COLOR, ss->mark_color, S_mark_color); save_a_color(Fp, dpy, cmap, SASH_COLOR, ss->sash_color, S_sash_color); save_a_color(Fp, dpy, cmap, TEXT_FOCUS_COLOR, ss->text_focus_color, S_text_focus_color); save_a_color(Fp, dpy, cmap, FILTER_CONTROL_WAVEFORM_COLOR, ss->filter_control_waveform_color, S_filter_control_waveform_color); } static char *fallbacks[] = { (char *)"*fontList: " DEFAULT_FONTLIST, (char *)"*enableEtchedInMenu: True", (char *)"*enableThinThickness: True", (char *)"*enableToggleColor: True", (char *)"*enableToggleVisual: True", NULL }; void snd_doit(int argc, char **argv) { XtAppContext app; Widget shell; Display *dpy; Drawable wn; Arg args[32]; int i, n; Widget menu; XGCValues gv; char *app_title = NULL; int err = 0; XtSetLanguageProc(NULL, NULL, NULL); ss->channel_min_height = CHANNEL_MIN_HEIGHT; ss->Graph_Cursor = DEFAULT_GRAPH_CURSOR; #ifndef __alpha__ XtSetArg(args[0], XtNwidth, INITIAL_WINDOW_WIDTH); XtSetArg(args[1], XtNheight, INITIAL_WINDOW_HEIGHT); shell = XtAppInitialize(&app, "Snd", NULL, 0, &argc, argv, fallbacks, args, 2); #else shell = XtVaOpenApplication(&app, "Snd", NULL, 0, &argc, argv, fallbacks, applicationShellWidgetClass, XmNallowShellResize, AUTO_RESIZE_DEFAULT, NULL); #endif #ifndef _MSC_VER setlocale(LC_NUMERIC, "C"); #endif /* if user has *keyboardFocusPolicy: Pointer in .Xdefaults, it can screw up Snd's attempt to * keep the channel graphics window as the active widget in case of keyboard input. So, * we try to force Snd's focus policy to be XmEXPLICIT */ XtVaGetValues(shell, XmNkeyboardFocusPolicy, &err, NULL); if (err != XmEXPLICIT) XtVaSetValues(shell, XmNkeyboardFocusPolicy, XmEXPLICIT, NULL); auto_open_files = argc - 1; if (argc > 1) auto_open_file_names = (char **)(argv + 1); dpy = XtDisplay(shell); XtVaGetValues(shell, XmNtitle, &app_title, NULL); /* perhaps caller included -title arg */ if (app_title) ss->startup_title = mus_strdup(app_title); else ss->startup_title = mus_strdup("snd"); for (i = 1; i < argc; i++) if ((mus_strcmp(argv[i], "-h")) || (mus_strcmp(argv[i], "-horizontal")) || (mus_strcmp(argv[i], "--horizontal"))) set_sound_style(SOUNDS_HORIZONTAL); else if ((mus_strcmp(argv[i], "-v")) || (mus_strcmp(argv[i], "-vertical")) || (mus_strcmp(argv[i], "--vertical"))) set_sound_style(SOUNDS_VERTICAL); else if ((mus_strcmp(argv[i], "-notebook")) || (mus_strcmp(argv[i], "--notebook"))) { set_sound_style(SOUNDS_IN_NOTEBOOK); set_auto_resize(false); } else if ((mus_strcmp(argv[i], "-separate")) || (mus_strcmp(argv[i], "--separate"))) set_sound_style(SOUNDS_IN_SEPARATE_WINDOWS); else if (mus_strcmp(argv[i], "-noglob")) noglob = true; else if (mus_strcmp(argv[i], "-noinit")) noinit = true; else if (mus_strcmp(argv[i], "-nostdin")) nostdin = true; else if ((mus_strcmp(argv[i], "-b")) || (mus_strcmp(argv[i], "-batch")) || (mus_strcmp(argv[i], "--batch"))) batch = true; else if (mus_strcmp(argv[i], "--features")) /* testing (compsnd) */ check_features_list(argv[i + 1]); ss->batch_mode = batch; if (batch) XtSetMappedWhenManaged(shell, 0); ss->zoom_slider_width = ZOOM_SLIDER_WIDTH; ss->position_slider_width = POSITION_SLIDER_WIDTH; ss->channel_sash_indent = CHANNEL_SASH_INDENT; ss->channel_sash_size = CHANNEL_SASH_SIZE; ss->sash_size = SASH_SIZE; ss->sash_indent = SASH_INDENT; ss->toggle_size = TOGGLE_SIZE; ss->click_time = (oclock_t)XtGetMultiClickTime(dpy); #if HAVE_GL { /* this taken from glxmotif.c from xjournal/sgi */ XVisualInfo *vi = NULL; Colormap cmap; GLXContext cx; int dblBuf[] = {GLX_RGBA, GLX_DEPTH_SIZE, 16, GLX_DOUBLEBUFFER, None}; vi = glXChooseVisual(dpy, DefaultScreen(dpy), dblBuf); if (vi) ss->gl_has_double_buffer = true; else { int snglBuf[] = {GLX_RGBA, GLX_DEPTH_SIZE, 16, None}; ss->gl_has_double_buffer = false; vi = glXChooseVisual(dpy, DefaultScreen(dpy), snglBuf); } if (vi == NULL) fprintf(stderr, "%s", "no RGB visual with desired depth\n"); /* not snd_error -- shell not ready yet */ else { /* create an OpenGL rendering context */ cx = glXCreateContext(dpy, vi, /* no display list sharing */ None, /* favor direct */ GL_TRUE); if (cx == NULL) fprintf(stderr, "%s", "could not create rendering context\n"); else { /* create an X colormap since probably not using default visual */ cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual, AllocNone); XtVaSetValues(shell, XtNvisual, vi->visual, XtNdepth, vi->depth, XtNcolormap, cmap, NULL); ss->cx = cx; } XFree(vi); } } #endif XtAppSetWarningMsgHandler(app, muffle_warning); ss->mainapp = app; ss->mainshell = shell; ss->mdpy = dpy; ss->toolbar = NULL; ss->white = get_color(shell, WHITE_COLOR, NULL, NULL, true); ss->black = get_color(shell, BLACK_COLOR, NULL, NULL, false); ss->light_blue = get_color(shell, LIGHT_BLUE_COLOR, "blue", NULL, true); ss->lighter_blue = get_color(shell, LIGHTER_BLUE_COLOR, "blue", NULL, true); ss->red = get_color(shell, RED_COLOR, NULL, NULL, false); ss->green = get_color(shell, GREEN_COLOR, NULL, NULL, false); ss->blue = get_color(shell, "blue", NULL, NULL, false); ss->yellow = get_color(shell, YELLOW_COLOR, NULL, NULL, true); ss->highlight_color = get_color(shell, HIGHLIGHT_COLOR, "gray90", NULL, true); ss->basic_color = get_color(shell, BASIC_COLOR, "gray80", "gray", true); ss->position_color = get_color(shell, POSITION_COLOR, "gray60", "blue", false); ss->zoom_color = get_color(shell, ZOOM_COLOR, "gray20", "gray", false); ss->cursor_color = get_color(shell, CURSOR_COLOR, NULL, NULL, false); ss->selection_color = get_color(shell, SELECTION_COLOR, "gray80", NULL, false); ss->mix_color = get_color(shell, MIX_COLOR, "red", NULL, false); ss->enved_waveform_color = get_color(shell, ENVED_WAVEFORM_COLOR, "red", NULL, false); ss->filter_control_waveform_color = get_color(shell, FILTER_CONTROL_WAVEFORM_COLOR, "blue", NULL, false); ss->listener_color = get_color(shell, LISTENER_COLOR, NULL, NULL, true); ss->listener_text_color = get_color(shell, LISTENER_TEXT_COLOR, NULL, NULL, false); ss->graph_color = get_color(shell, GRAPH_COLOR, NULL, NULL, true); ss->selected_graph_color = get_color(shell, SELECTED_GRAPH_COLOR, NULL, NULL, true); ss->data_color = get_color(shell, DATA_COLOR, NULL, NULL, false); ss->selected_data_color = get_color(shell, SELECTED_DATA_COLOR, NULL, NULL, false); ss->mark_color = get_color(shell, MARK_COLOR, "red", NULL, false); ss->sash_color = get_color(shell, SASH_COLOR, NULL, NULL, false); ss->text_focus_color = get_color(shell, TEXT_FOCUS_COLOR, NULL, NULL, true); ss->grid_color = get_in_between_color(ss->data_color, ss->graph_color); ss->selected_grid_color = get_in_between_color(ss->selected_data_color, ss->selected_graph_color); #if HAVE_SCHEME s7_symbol_set_value(s7, ss->highlight_color_symbol, Xen_wrap_pixel(ss->highlight_color)); s7_symbol_set_value(s7, ss->basic_color_symbol, Xen_wrap_pixel(ss->basic_color)); s7_symbol_set_value(s7, ss->position_color_symbol, Xen_wrap_pixel(ss->position_color)); s7_symbol_set_value(s7, ss->zoom_color_symbol, Xen_wrap_pixel(ss->zoom_color)); s7_symbol_set_value(s7, ss->cursor_color_symbol, Xen_wrap_pixel(ss->cursor_color)); s7_symbol_set_value(s7, ss->selection_color_symbol, Xen_wrap_pixel(ss->selection_color)); s7_symbol_set_value(s7, ss->mix_color_symbol, Xen_wrap_pixel(ss->mix_color)); s7_symbol_set_value(s7, ss->enved_waveform_color_symbol, Xen_wrap_pixel(ss->enved_waveform_color)); s7_symbol_set_value(s7, ss->filter_control_waveform_color_symbol, Xen_wrap_pixel(ss->filter_control_waveform_color)); s7_symbol_set_value(s7, ss->listener_color_symbol, Xen_wrap_pixel(ss->listener_color)); s7_symbol_set_value(s7, ss->listener_text_color_symbol, Xen_wrap_pixel(ss->listener_text_color)); s7_symbol_set_value(s7, ss->graph_color_symbol, Xen_wrap_pixel(ss->graph_color)); s7_symbol_set_value(s7, ss->selected_graph_color_symbol, Xen_wrap_pixel(ss->selected_graph_color)); s7_symbol_set_value(s7, ss->data_color_symbol, Xen_wrap_pixel(ss->data_color)); s7_symbol_set_value(s7, ss->selected_data_color_symbol, Xen_wrap_pixel(ss->selected_data_color)); s7_symbol_set_value(s7, ss->mark_color_symbol, Xen_wrap_pixel(ss->mark_color)); s7_symbol_set_value(s7, ss->sash_color_symbol, Xen_wrap_pixel(ss->sash_color)); s7_symbol_set_value(s7, ss->text_focus_color_symbol, Xen_wrap_pixel(ss->text_focus_color)); #endif ss->axis_color_set = false; ss->orig_data_color = ss->data_color; ss->orig_selected_data_color = ss->selected_data_color; ss->orig_mark_color = ss->mark_color; ss->orig_mix_color = ss->mix_color; ss->orig_graph_color = ss->graph_color; ss->orig_selected_graph_color = ss->selected_graph_color; ss->orig_listener_color = ss->listener_color; ss->orig_listener_text_color = ss->listener_text_color; ss->orig_cursor_color = ss->cursor_color; ss->orig_basic_color = ss->basic_color; ss->orig_selection_color = ss->selection_color; ss->orig_zoom_color = ss->zoom_color; ss->orig_position_color = ss->position_color; ss->orig_highlight_color = ss->highlight_color; if ((!(set_peaks_font(DEFAULT_PEAKS_FONT))) && (!(set_peaks_font(FALLBACK_FONT)))) fprintf(stderr, "can't find peaks font %s", DEFAULT_PEAKS_FONT); if ((!(set_tiny_font(DEFAULT_TINY_FONT))) && (!(set_tiny_font(FALLBACK_FONT)))) fprintf(stderr, "can't find tiny font %s", DEFAULT_TINY_FONT); if ((!(set_bold_peaks_font(DEFAULT_BOLD_PEAKS_FONT))) && (!(set_bold_peaks_font(FALLBACK_FONT)))) fprintf(stderr, "can't find bold peaks font %s", DEFAULT_BOLD_PEAKS_FONT); if ((!(set_axis_label_font(DEFAULT_AXIS_LABEL_FONT))) && (!(set_axis_label_font(FALLBACK_FONT)))) fprintf(stderr, "can't find axis label font %s", DEFAULT_AXIS_LABEL_FONT); if ((!(set_axis_numbers_font(DEFAULT_AXIS_NUMBERS_FONT))) && (!(set_axis_numbers_font(FALLBACK_FONT)))) fprintf(stderr, "can't find axis numbers font %s", DEFAULT_AXIS_NUMBERS_FONT); set_listener_font(DEFAULT_LISTENER_FONT); /* we need some sort of font here! */ ss->orig_axis_label_font = mus_strdup(axis_label_font(ss)); ss->orig_axis_numbers_font = mus_strdup(axis_numbers_font(ss)); ss->orig_peaks_font = mus_strdup(peaks_font(ss)); ss->orig_bold_peaks_font = mus_strdup(bold_peaks_font(ss)); ss->orig_listener_font = mus_strdup(listener_font(ss)); ss->orig_tiny_font = mus_strdup(tiny_font(ss)); XtVaSetValues(shell, XmNbackground, ss->basic_color, NULL); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; n = attach_all_sides(args, n); XtSetArg(args[n], XmNallowResize, true); n++; ss->mainpane = XtCreateManagedWidget("mainpane", xmFormWidgetClass, shell, args, n); menu = add_menu(); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, menu); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNallowResize, true); n++; XtSetArg(args[n], XmNpaneMaximum, LOTSA_PIXELS); n++; switch (sound_style(ss)) { case SOUNDS_IN_SEPARATE_WINDOWS: ss->soundpane = XtCreateManagedWidget("soundpane", xmFormWidgetClass, ss->mainpane, args, n); break; case SOUNDS_HORIZONTAL: XtSetArg(args[n], XmNorientation, XmVERTICAL); n++; ss->soundpanebox = XtCreateManagedWidget("soundpane", xmPanedWindowWidgetClass, ss->mainpane, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNsashHeight, ss->sash_size); n++; XtSetArg(args[n], XmNsashWidth, ss->sash_size); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNsashIndent, ss->sash_indent); n++; ss->soundpane = XtCreateManagedWidget("soundpane", xmPanedWindowWidgetClass, ss->soundpanebox, args, n); break; case SOUNDS_VERTICAL: XtSetArg(args[n], XmNsashHeight, ss->sash_size); n++; XtSetArg(args[n], XmNsashWidth, ss->sash_size); n++; XtSetArg(args[n], XmNsashIndent, ss->sash_indent); n++; ss->soundpane = XtCreateManagedWidget("soundpane", xmPanedWindowWidgetClass, ss->mainpane, args, n); break; case SOUNDS_IN_NOTEBOOK: XtSetArg(args[n], XmNorientation, XmVERTICAL); n++; ss->soundpanebox = XtCreateManagedWidget("soundpane", xmPanedWindowWidgetClass, ss->mainpane, args, n); n = 0; XtSetArg(args[n], XmNbackground, ss->basic_color); n++; XtSetArg(args[n], XmNframeBackground, ss->zoom_color); n++; XtSetArg(args[n], XmNbindingType, XmNONE); n++; XtSetArg(args[n], XmNbackPagePlacement, XmTOP_RIGHT); n++; XtSetArg(args[n], XmNorientation, XmVERTICAL); n++; ss->soundpane = XtCreateWidget("nb", xmNotebookWidgetClass, ss->soundpanebox, args, n); { /* get rid of the useless spinbox */ n = 0; XtSetArg(args[n], XmNnotebookChildType, XmPAGE_SCROLLER); n++; XtCreateWidget("scroller", xmScrollBarWidgetClass, ss->soundpane, NULL, 0); } XtManageChild(ss->soundpane); XtAddCallback(ss->soundpane, XmNpageChangedCallback, notebook_page_changed_callback, NULL); map_over_children(ss->soundpane, set_main_color_of_widget); /* appears to be a no-op */ break; } SetupIcon(shell); XtRealizeWidget(shell); if (auto_resize(ss) != AUTO_RESIZE_DEFAULT) XtVaSetValues(shell, XmNallowShellResize, auto_resize(ss), NULL); wn = XtWindow(shell); gv.background = ss->graph_color; gv.foreground = ss->data_color; ss->basic_gc = XCreateGC(dpy, wn, GCForeground | GCBackground, &gv); gv.background = ss->graph_color; gv.foreground = ss->data_color; ss->combined_basic_gc = XCreateGC(dpy, wn, GCForeground | GCBackground, &gv); gv.background = ss->graph_color; gv.foreground = ss->mix_color; ss->mix_gc = XCreateGC(dpy, wn, GCForeground | GCBackground, &gv); gv.function = GXxor; gv.background = ss->graph_color; gv.foreground = (Pixel)(XOR(ss->cursor_color, gv.background)); ss->cursor_gc = XCreateGC(dpy, wn, GCForeground | GCFunction, &gv); gv.function = GXxor; gv.background = ss->graph_color; gv.foreground = (Pixel)(XOR(ss->selection_color, gv.background)); ss->selection_gc = XCreateGC(dpy, wn, GCForeground | GCFunction, &gv); gv.function = GXxor; gv.background = ss->graph_color; gv.foreground = (Pixel)(XOR(ss->mark_color, gv.background)); ss->mark_gc = XCreateGC(dpy, wn, GCForeground | GCFunction, &gv); gv.function = GXcopy; gv.background = ss->data_color; gv.foreground = ss->graph_color; ss->erase_gc = XCreateGC(dpy, wn, GCForeground | GCBackground | GCFunction, &gv); gv.background = ss->selected_graph_color; gv.foreground = ss->selected_data_color; ss->selected_basic_gc = XCreateGC(dpy, wn, GCForeground | GCBackground, &gv); gv.function = GXxor; gv.background = ss->selected_graph_color; gv.foreground = (Pixel)(XOR(ss->cursor_color, gv.background)); ss->selected_cursor_gc = XCreateGC(dpy, wn, GCForeground | GCFunction, &gv); gv.function = GXxor; gv.background = ss->selected_graph_color; gv.foreground = (Pixel)(XOR(ss->selection_color, gv.background)); ss->selected_selection_gc = XCreateGC(dpy, wn, GCForeground | GCFunction, &gv); gv.function = GXxor; gv.background = ss->selected_graph_color; gv.foreground = (Pixel)(XOR(ss->mark_color, gv.background)); ss->selected_mark_gc = XCreateGC(dpy, wn, GCForeground | GCFunction, &gv); gv.function = GXcopy; gv.background = ss->selected_data_color; gv.foreground = ss->selected_graph_color; ss->selected_erase_gc = XCreateGC(dpy, wn, GCForeground | GCBackground | GCFunction, &gv); gv.function = GXcopy; gv.background = ss->basic_color; gv.foreground = ss->black; ss->fltenv_basic_gc = XCreateGC(dpy, wn, GCBackground | GCForeground | GCFunction, &gv); gv.function = GXcopy; gv.background = ss->basic_color; gv.foreground = ss->filter_control_waveform_color; ss->fltenv_data_gc = XCreateGC(dpy, wn, GCBackground | GCForeground | GCFunction, &gv); initialize_colormap(); /* X11 not ours */ make_icons_transparent(BASIC_COLOR); if (with_toolbar(ss)) show_toolbar(); #ifndef _MSC_VER if (setjmp(top_level_jump)) { if (!(ss->jump_ok)) snd_error_without_format("Caught top level error (will try to continue):\n"); else ss->jump_ok = false; } else #endif startup_funcs(); /* snd /tmp -> segfault if this happens before the setjmp(top_level_jump) */ if (ss->startup_errors) { post_it("Error in initialization", ss->startup_errors); free(ss->startup_errors); ss->startup_errors = NULL; } XtAppMainLoop(app); } snd-16.1/popup.fs0000644000076400007640000011324612434353162012042 0ustar bilbil\ popup.fs -- popup.scm|rb --> popup.fs \ Translator/Author: Michael Scholz \ Created: 05/12/23 00:28:28 \ Changed: 14/11/11 00:07:54 \ \ @(#)popup.fs 1.42 11/11/14 \ selection-popup-menu \ graph-popup-menu \ fft-popup-menu \ edit-history-menu \ listener-popup-menu \ \ add-popups ( -- ) \ \ edhist-help-edits ( w c i -- ) \ change-menu-color ( menu new-color -- ) \ change-selection-popup-color ( new-color -- ) \ change-graph-popup-color ( new-color -- ) \ change-fft-popup-color ( new-color -- ) \ change-edhist-popup-color ( new-color -- ) \ change-listener-popup-color ( new-color -- ) 'snd-motif provided? [unless] skip-file [then] require snd-xm require extensions \ for prefs : edhist-help-edits <{ w c info -- }> "Edit History Functions" "This popup menu gives access to the edit-list \ function handlers in Snd. \ At any time you can backup in the edit list, \ 'save' the current trailing edits, make some \ new set of edits, then 'reapply' the saved edits. \ The 'apply' choice gives access to all \ currently saved edit lists -- any such list can be applied to any channel. \ 'Clear' deletes all saved edit lists." #( "{edit lists}" "{edit-list->function}" ) #( "extsnd.html#editlists" "extsnd.html#editlist_to_function" ) help-dialog drop ; 1 "PROC is the only argument." create-hook edhist-save-hook hide #() value cascade-popup-cb-list : widget->name ( w -- s ) FXtName ; : popup-post-it { menu info -- } info menu Fset_menuToPost drop ; \ --- make-simple-popdown-menu for fft-popup-menu --- : popup-cascade-cb { children cb -- prc; w c i self -- } 3 proc-create ( prc ) cb , children , does> { w c info self -- } self @ { cb } self cell+ @ { children } cb #( children ) run-proc drop ; : make-simple-popdown-menu { label popdown-labels parent cascade-cb -- } parent label #( FXmNbackground highlight-color ) undef FXmCreatePulldownMenu { top } label FxmCascadeButtonWidgetClass parent #( FXmNbackground highlight-color FXmNsubMenuId top ) undef FXtCreateManagedWidget { menu } #() { children } nil { c } popdown-labels proc? if \ edhist sends a proc to set TOP to edhist-widgets popdown-labels #( top ) run-proc drop else \ else arrays of #( name proc ) lists popdown-labels each { poplab } poplab 0 array-ref FxmPushButtonWidgetClass top #( FXmNbackground highlight-color ) undef FXtCreateManagedWidget to c c FXmNactivateCallback poplab 1 array-ref undef FXtAddCallback drop children c array-push drop end-each then cascade-cb if menu FXmNcascadingCallback children cascade-cb popup-cascade-cb undef FXtAddCallback drop then ; \ --- make-popdown-entry for listener-popup-menu --- #() value listener-values : collector-cb { func collector -- prc; w c i self -- val } 3 proc-create ( prc ) func , collector , does> { w c info self -- val } self @ { func } self cell+ @ { collector } collector #( sounds ) run-proc ( lst ) 0 array-ref 1 >array func swap run-proc ; : cas-cb ( func -- prc; w c i self -- val ) { func } 3 proc-create ( prc ) func , does> { w c info self -- val } self @ ( func ) #( w current-label 0 find-sound ) run-proc ; : popdown-cascade-cb { func coll menu children -- prc; w c i self -- } 3 proc-create ( prc ) func , coll , menu , children , does> { w c info self -- } self @ { func } self cell+ @ { collector } self 2 cells + @ { menu } self 3 cells + @ { children } children each ( child ) FXtUnmanageChild drop end-each collector #( sounds ) run-proc { snds } children length { clen } snds length { slen } clen slen < if slen clen ?do "" FxmPushButtonWidgetClass menu #( FXmNbackground highlight-color ) undef FXtCreateManagedWidget { c } c FXmNactivateCallback func cas-cb undef FXtAddCallback drop children c array-push drop loop then slen if children each { child } snds i array-ref { snd } child snd short-file-name change-label child FXtManageChild drop end-each then ; : make-popdown-entry { label parent func collector with-one -- values } #f { widget } #() { children } with-one if label FxmPushButtonWidgetClass parent #( FXmNbackground highlight-color ) undef FXtCreateManagedWidget to widget widget FXmNactivateCallback func collector collector-cb undef FXtAddCallback drop then parent label #( FXmNbackground highlight-color ) undef FXmCreatePulldownMenu { menu } label FxmCascadeButtonWidgetClass parent #( FXmNbackground highlight-color FXmNsubMenuId menu ) undef FXtCreateManagedWidget { cas-wid } cas-wid FXmNcascadingCallback func collector menu children popdown-cascade-cb undef FXtAddCallback drop listener-values #( widget menu cas-wid collector ) array-push drop ; \ --- make-popup-menu for graph-, fft-, and listener-menu --- \ \ general entries: \ entries: #( #( name type cb func ) ... ) \ \ simple popdown (fft-menu) \ entries: #( #( name type labels-array cb ) ... ) \ \ special popdown (listener) \ entries: #( #( name type func collector with-one ) ... ) : make-popup-menu ( name parent entries -- menu ) { name parent entries } parent name #( FXmNpopupEnabled FXmPOPUP_AUTOMATIC FXmNbackground highlight-color ) undef FXmCreatePopupMenu { menu } entries each { entry } #f { casc } \ string entry 0 array-ref { label } \ 'label|'separator|'cascade|#f entry 1 array-ref { typ } typ 'label = if FxmLabelWidgetClass else typ 'separator = if FxmSeparatorWidgetClass else FxmPushButtonWidgetClass then then { class } typ 'cascade = if entry length 4 = if \ fft menu label entry 2 array-ref ( labels ) menu entry 3 array-ref ( prc ) make-simple-popdown-menu else \ listener menu label menu entry 2 array-ref ( func ) entry 3 array-ref ( collector ) entry 4 array-ref ( with-one ) make-popdown-entry then else label class menu #( FXmNbackground highlight-color ) undef FXtCreateManagedWidget { wid } entry 2 array-ref if \ cb: 3 args or #f wid FXmNactivateCallback entry 2 array-ref undef FXtAddCallback drop then entry 3 array-ref if \ func: 1 arg or #f entry 3 array-ref #( wid ) run-proc drop then then end-each menu ; \ --- selection popup --- : sel-stop-play-cb { vars -- prc; self -- val } 0 proc-create ( prc ) vars , does> { self -- val } self @ { vars } vars :stopping array-assoc-ref if vars :stopping #f array-assoc-set! ( vars ) :stop-widget array-assoc-ref { w } w widget? if w "Play" change-label then then #f ; : sel-play-again-cb ( -- val ) selection play ; : sel-play-cb { vars -- prc; w c i self -- val } 3 proc-create ( prc ) vars , does> { w c info self -- val } self @ { vars } vars :stopping array-assoc-ref if w "Play" change-label vars :stopping #f array-assoc-set! ( vars ) :stopping1 array-assoc-ref if vars :stopping1 #f array-assoc-set! ( vars ) :stop-widget1 array-assoc-ref "Loop play" change-label stop-playing-selection-hook <'> sel-play-again-cb remove-hook! drop then undef stop-playing else w "Stop" change-label vars :stop-widget w array-assoc-set! ( vars ) :stopping #t array-assoc-set! drop selection play then ; : sel-loop-cb { vars -- prc; w c i self -- val } 3 proc-create ( prc ) vars , does> { w c info self -- val } self @ { vars } vars :stopping1 array-assoc-ref if w "Loop play" change-label vars :stopping1 #f array-assoc-set! ( vars ) :stopping array-assoc-ref if vars :stopping #f array-assoc-set! ( vars ) :stop-widget array-assoc-ref "Play" change-label then stop-playing-selection-hook <'> sel-play-again-cb remove-hook! drop undef stop-playing else w "Stop!" change-label vars :stop-widget1 w array-assoc-set! ( vars ) :stopping1 #t array-assoc-set! drop stop-playing-selection-hook <'> sel-play-again-cb add-hook! selection play then ; : as-one-edit-thunk { sel -- prc; self -- val } 0 proc-create ( prc ) sel , does> { self -- val } self @ { sel } sel 0 array-ref { snd } sel 1 array-ref { chn } snd chn selection-position { beg } snd chn selection-framples { len } beg 0> if 0 beg snd chn delete-samples drop then snd chn #f framples { frms } len frms < if len 1+ frms len - snd chn delete-samples drop then #f ; : sel-del <{ w c info -- val }> delete-selection ; : sel-zero <{ w c info -- val }> 0.0 scale-selection-by ; : sel-crop <{ w c info -- val }> selection-members each ( sel ) as-one-edit-thunk "" as-one-edit drop end-each #f ; : sel-save-as <{ w c info -- val }> #t save-selection-dialog ; : sel-copy <{ w c info -- val }> snd-tempnam { new-file-name } new-file-name save-selection drop new-file-name open-sound ; : sel-cut <{ w c info -- val }> snd-tempnam { new-file-name } new-file-name save-selection drop delete-selection drop new-file-name open-sound ; : sel-marks <{ w c info -- val }> selection-members each { select } select 0 array-ref { snd } select 1 array-ref { chn } snd chn selection-position { pos } snd chn selection-framples 1- { len } pos snd chn #f 0 add-mark drop pos len d+ snd chn #f 0 add-mark drop end-each #f ; : sel-info <{ w c info -- val }> #f #f selection-position { beg } #f #f selection-framples { len } " start: %d, %.3f\n" #( beg beg #f srate f/ ) string-format ( str ) " end: %d, %.3f\n" #( beg len + dup #f srate f/ ) string-format $+ " duration: %d, %.3f\n" #( len len #f srate f/ ) string-format $+ " chans: %d\n" #( selection-chans ) string-format $+ " maxamp: %.3f\n" #( #f #f selection-maxamp ) string-format $+ { str } "Selection Info" str info-dialog ; \ choice 2 == selection : sel-appcnt <{ w c info -- val }> #f 2 0 undef apply-controls ; : sel-rescnt <{ w c info -- val }> #f reset-controls ; : sel-unsel <{ w c info -- val }> #f #t set-selection-member? ; : sel-rev <{ w c info -- val }> reverse-selection ; : sel-mix <{ w c info -- val }> #f #f #f cursor mix-selection ; : sel-invert <{ w c info -- val }> -1.0 scale-selection-by ; let: ( -- menu ) #a( :stopping #f :stopping1 #f :stop-widget #f :stop-widget1 #f ) { vars } stop-playing-selection-hook vars sel-stop-play-cb add-hook! "selection-popup" main-widgets 2 array-ref #( #( "Selection" 'label #f #f ) #( "sep" 'separator #f #f ) #( "Play" #f vars sel-play-cb #f ) #( "Loop play" #f vars sel-loop-cb #f ) #( "Delete" #f <'> sel-del #f ) #( "Zero" #f <'> sel-zero #f ) #( "Crop" #f <'> sel-crop #f ) #( "Save as" #f <'> sel-save-as #f ) #( "Copy->New" #f <'> sel-copy #f ) #( "Cut->New" #f <'> sel-cut #f ) #( "Snap marks" #f <'> sel-marks #f ) #( "Selection Info" #f <'> sel-info #f ) #( "Apply controls" #f <'> sel-appcnt #f ) #( "Reset controls" #f <'> sel-rescnt #f ) #( "Unselect" #f <'> sel-unsel #f ) #( "Reverse" #f <'> sel-rev #f ) #( "Mix" #f <'> sel-mix #f ) #( "Invert" #f <'> sel-invert #f ) ) make-popup-menu ;let constant selection-popup-menu \ --- time domain popup --- #f value graph-popup-snd #f value graph-popup-chn : stop-playing-cb { vars -- prc; snd self -- val } 1 proc-create ( prc ) vars , does> { snd self -- val } self @ { vars } vars :stopping array-assoc-ref if vars :stopping #f array-assoc-set! ( vars ) :stop-widget array-assoc-ref ?dup-if "Play" change-label then then #f ; : play-cb { vars -- prc; w c i self -- val } 3 proc-create ( prc ) vars , does> { w c info self -- val } self @ { vars } vars :stopping array-assoc-ref if vars :stopping #f array-assoc-set! drop w "Play" change-label undef stop-playing else w "Stop" change-label vars :stopping #t array-assoc-set! drop graph-popup-snd play then ; : stop-cb { vars -- prc; widget self -- val } 1 proc-create ( prc ) vars , does> { w self -- val } self @ ( vars ) :stop-widget w array-assoc-set! ; : pchan-cb { vars -- prc; w c i self -- val } 3 proc-create ( prc ) vars , does> { w c info self -- val } self @ ( vars ) :stopping #t array-assoc-set! ( vars ) :stop-widget array-assoc-ref "Stop" change-label graph-popup-snd :channel graph-popup-chn play ; : pcur-cb { vars -- prc; w c i self -- val } 3 proc-create ( prc ) vars , does> { w c info self -- val } self @ ( vars ) :stopping #t array-assoc-set! ( vars ) :stop-widget array-assoc-ref "Stop" change-label graph-popup-snd :start graph-popup-snd graph-popup-chn #f cursor play ; : pprev-cb { vars -- prc; w c i self -- val } 3 proc-create ( prc ) vars , does> { w c info self -- val } self @ ( vars ) :stopping #t array-assoc-set! ( vars ) :stop-widget array-assoc-ref "Stop" change-label graph-popup-snd :channel graph-popup-chn :edit-position graph-popup-snd graph-popup-chn edit-position 1- play ; : porig-cb { vars -- prc; w c i self -- val } 3 proc-create ( prc ) vars , does> { w c info self -- val } self @ ( vars ) :stopping #t array-assoc-set! ( vars ) :stop-widget array-assoc-ref "Stop" change-label graph-popup-snd :channel graph-popup-chn :edit-position 0 play ; : pundo-cb <{ w c info -- val }> 1 graph-popup-snd graph-popup-chn undo ; : predo-cb <{ w c info -- val }> 1 graph-popup-snd graph-popup-chn redo ; : prev-cb <{ w c info -- val }> graph-popup-snd revert-sound ; : popen-cb <{ w c info -- val }> #t open-file-dialog ; : psave-cb <{ w c info -- val }> graph-popup-snd save-sound ; : psaveas-cb <{ w c info -- val }> graph-popup-snd select-sound drop #t save-sound-dialog ; : pupdate-cb <{ w c info -- val }> graph-popup-snd update-sound ; : pclose-cb <{ w c info -- val }> graph-popup-snd close-sound-extend #f ; : pmixsel-cb <{ w c info -- val }> graph-popup-snd graph-popup-chn #f cursor graph-popup-snd graph-popup-chn mix-selection ; : pinssel-cb <{ w c info -- val }> graph-popup-snd graph-popup-chn #f cursor graph-popup-snd graph-popup-chn insert-selection ; : prepsel-cb <{ w c info -- val }> graph-popup-snd { snd } graph-popup-chn { chn } snd chn #f cursor { beg } snd chn selection-framples { len } snd chn selection-position { sbeg } snd chn selection-member? not beg len + sbeg < || beg sbeg len + > || if beg len snd chn #f delete-samples drop beg snd chn insert-selection else beg sbeg < if beg sbeg beg - snd chn #f delete-samples else #f then then ; : pselall-cb <{ w c info -- val }> graph-popup-snd graph-popup-chn select-all ; : punsel-cb <{ w c info -- val }> #f #t set-selection-member? ; : papcnt-cb <{ w c info -- val }> #f 0 0 undef apply-controls ; : precnt-cb <{ w c info -- val }> #f reset-controls ; : print-props { props -- str } object-print-length { old-len } print-length { old-vct-len } 3 set-object-print-length 3 set-print-length drop "" ( str ) props each { prop } \ ( key . val ) ( str ) " %s: %s\n" #( prop 0 array-ref prop 1 array-ref ) string-format $+ end-each ( str ) old-len set-object-print-length old-vct-len set-print-length drop ( str ) ; : pinfo-cb <{ w c info -- val }> graph-popup-snd { snd } graph-popup-chn { chn } snd chn #f framples { frms } snd srate { sr } " chans: %d, srate: %d\n" #( snd channels sr ) string-format ( str ) " format: %s [%s]\n" #( snd sample-type mus-sample-type-name snd header-type mus-header-type-name ) string-format $+ " length: %.3f (%d frames)\n" #( frms sr f/ frms ) string-format $+ snd #t #f maxamp each { mx } "%6s %c: %.3f\n" #( "maxamp" [char] A i + mx ) string-format $+ end-each snd comment empty? unless " comment: %S\n" #( snd comment ) string-format $+ then snd file-name mus-sound-loop-info { loops } loops nil? unless " loop: %s\n" #( loops ) string-format $+ then snd header-type mus-soundfont = if " sounds: %s\n" #( snd soundfont-info ) string-format $+ then snd sound-properties { props } props nil? unless "properties:\n" $+ props print-props $+ then snd channels 0 ?do snd i channel-properties to props props nil? unless "chan %d properties:\n" #( i ) string-format $+ props print-props $+ then loop { str } snd file-name " info" $+ str info-dialog ; : paddmrk-cb <{ w c info -- val }> graph-popup-snd graph-popup-chn #f cursor ( samp ) graph-popup-snd graph-popup-chn #f ( name ) 0 ( sync ) add-mark ; : pdelmrk-cb <{ w c info -- val }> graph-popup-snd graph-popup-chn #f marks { ms } ms nil? unless ms length 1 = if ms 0 array-ref delete-mark drop else graph-popup-snd graph-popup-chn #f cursor { loc } ms 0 array-ref { id } loc id undef mark-sample - abs { cur-min } ms each { m } loc m undef mark-sample - abs { this-min } this-min cur-min < if this-min to cur-min m to id then end-each id delete-mark then then #f ; : pdelamrk-cb <{ w c info -- val }> graph-popup-snd graph-popup-chn delete-marks ; : pnextmrk-cb <{ w c info -- val }> [char] j 4 graph-popup-snd graph-popup-chn key \ C-j ; : plastmrk-cb <{ w c info -- val }> [char] - 4 graph-popup-snd graph-popup-chn key drop \ C-- [char] j 4 graph-popup-snd graph-popup-chn key \ C-j ; : exit-cb <{ w c info -- val }> 0 snd-exit ; let: ( -- menu ) #a( :stopping #f :stop-widget #f ) { vars } stop-playing-hook vars stop-playing-cb add-hook! "graph-popup" main-widgets 2 array-ref #( #( "Snd" 'label #f #f ) #( "sep" 'separator #f #f ) #( "Play" #f vars play-cb vars stop-cb ) #( "Play channel" #f vars pchan-cb #f ) #( "Play from cursor" #f vars pcur-cb #f ) #( "Play previous" #f vars pprev-cb #f ) #( "Play original" #f vars porig-cb #f ) #( "Undo" #f <'> pundo-cb #f ) #( "Redo" #f <'> predo-cb #f ) #( "Revert" #f <'> prev-cb #f ) #( "Open" #f <'> popen-cb #f ) #( "Save" #f <'> psave-cb #f ) #( "Save as" #f <'> psaveas-cb #f ) #( "Update" #f <'> pupdate-cb #f ) #( "Close" #f <'> pclose-cb #f ) #( "Mix selection" #f <'> pmixsel-cb #f ) #( "Insert selection" #f <'> pinssel-cb #f ) #( "Replace with selection" #f <'> prepsel-cb #f ) #( "Select all" #f <'> pselall-cb #f ) #( "Unselect" #f <'> punsel-cb #f ) #( "Apply controls" #f <'> papcnt-cb #f ) #( "Reset controls" #f <'> precnt-cb #f ) #( "Info" #f <'> pinfo-cb #f ) #( "Add mark" #f <'> paddmrk-cb #f ) #( "Delete mark" #f <'> pdelmrk-cb #f ) #( "Delete all marks" #f <'> pdelamrk-cb #f ) #( "To next mark" #f <'> pnextmrk-cb #f ) #( "To last mark" #f <'> plastmrk-cb #f ) #( "sep" 'separator #f #f ) #( "Exit" #f <'> exit-cb #f ) ) make-popup-menu ;let constant graph-popup-menu : graph-popup-cb { snd chn -- prc; w self -- } 1 proc-create ( prc ) chn , snd , does> { w self -- } self @ { chn } self cell+ @ { snd } snd chn edits { eds } w widget->name { name } name "Snd" string= if snd channels 1 > if "%s[%d]" #( snd short-file-name chn ) string-format w swap change-label else w snd short-file-name change-label then #f exit then name "Save" string= name "Undo" string= || name "Revert" string= || name "Play previous" string= || if w eds 0 array-ref 0> if show-widget else hide-widget then exit then name "Play channel" string= if w snd channels 1 > if show-widget else hide-widget then exit then name "Redo" string= if w eds 1 array-ref 0> if show-widget else hide-widget then exit then name "Mix selection" string= name "Insert selection" string= || name "Unselect" string= || name "Replace with selection" string= || if w undef selection? if show-widget else hide-widget then exit then name "Play from cursor" string= if w snd chn #f cursor 0> if show-widget else hide-widget then exit then name "Play original" string= if w eds 0 array-ref 1 > if show-widget else hide-widget then exit then name "Delete mark" string= name "Delete all marks" string= || name "To next mark" string= || name "To last mark" string= || if w snd chn #f marks nil? unless show-widget else hide-widget then else #f then ; \ --- fft popup --- : choose-chan ( -- chn ) graph-popup-snd channel-style channels-separate = if graph-popup-chn else #t then ; : fft-peaks-cb <{ w c info -- val }> graph-popup-snd graph-popup-chn show-transform-peaks not graph-popup-snd choose-chan set-show-transform-peaks ; : fft-db-cb <{ w c info -- val }> graph-popup-snd graph-popup-chn fft-log-magnitude not graph-popup-snd choose-chan set-fft-log-magnitude ; : fft-frq-cb <{ w c info -- val }> graph-popup-snd graph-popup-chn fft-log-frequency not graph-popup-snd choose-chan set-fft-log-frequency ; : fft-norm-cb <{ w c info -- val }> graph-popup-snd graph-popup-chn transform-normalization dont-normalize = if normalize-by-channel graph-popup-snd choose-chan else dont-normalize graph-popup-snd choose-chan then set-transform-normalization ; : grp-lst-cb { val -- prc; w c i self -- val } 3 proc-create ( prc ) val , does> { w c info self -- val } self @ ( val ) graph-popup-snd choose-chan set-transform-graph-type ; : grp-labs ( -- ary ) #( #( "once" graph-once grp-lst-cb ) #( "sonogram" graph-as-sonogram grp-lst-cb ) #( "spectrogram" graph-as-spectrogram grp-lst-cb ) ) ; : grp-set <{ lst -- }> graph-popup-snd graph-popup-chn transform-graph-type { tp } lst each ( child ) i tp <> set-sensitive end-each ; #( 16 64 256 512 1024 4096 16384 65536 262144 1048576 ) constant fft-siz-sizes : siz-lst-cb { val -- prc; w c i self -- val } 3 proc-create ( prc ) val , does> { w c info self -- val } self @ ( val ) graph-popup-snd choose-chan set-transform-size ; : siz-labs ( -- ary ) fft-siz-sizes map #( *key* object->string *key* siz-lst-cb ) end-map ( ary ) ; : siz-set <{ lst -- }> graph-popup-snd graph-popup-chn transform-size { siz } lst each ( child ) fft-siz-sizes i array-ref siz <> set-sensitive end-each ; #( rectangular-window hann-window welch-window parzen-window bartlett-window hamming-window blackman2-window blackman3-window blackman4-window blackman5-window blackman6-window blackman7-window blackman8-window blackman9-window blackman10-window exponential-window riemann-window kaiser-window cauchy-window poisson-window gaussian-window tukey-window dolph-chebyshev-window hann-poisson-window connes-window samaraki-window ultraspherical-window bartlett-hann-window bohman-window flat-top-window ) constant fft-win-windows : win-lst-cb { val -- prc; w c i self -- val } 3 proc-create ( prc ) val , does> { w c info self -- val } self @ ( val ) graph-popup-snd choose-chan set-fft-window ; : win-labs ( -- ary ) #( "Rectangular" "Hann" "Welch" "Parzen" "Bartlett" "Hamming" "Blackman2" "Blackman3" "Blackman4" "Blackman5" "Blackman6" "Blackman7" "Blackman8" "Blackman9" "Blackman10" "Exponential" "Riemann" "Kaiser" "Cauchy" "Poisson" "Gaussian" "Tukey" "Dolph-Chebyshev" "Hann-Poisson" "Connes" "Samaraki" "Ultraspherical" "Bartlett-Hann" "Bohman" "Flat-top" ) map #( *key* fft-win-windows i array-ref win-lst-cb ) end-map ; : win-set <{ lst -- }> graph-popup-snd graph-popup-chn fft-window { win } lst each ( child ) fft-win-windows i array-ref win <> set-sensitive end-each ; #( fourier-transform wavelet-transform autocorrelation cepstrum walsh-transform haar-transform ) value fft-trn-transform : trn-lst-cb { val -- prc; w c i self -- val } 3 proc-create ( prc ) val , does> { w c info self -- } self @ ( val ) graph-popup-snd choose-chan set-transform-type ; : trn-labs ( -- ary ) #( "Fourier" "Wavelet" "Autocorrelate" "Cepstrum" "Walsh" "Haar" ) map #( *key* fft-trn-transform i array-ref trn-lst-cb ) end-map ( ary ) ; : trn-set <{ lst -- }> graph-popup-snd graph-popup-chn transform-type { trn } lst each ( child ) fft-trn-transform i array-ref trn equal? not set-sensitive end-each ; : typ-lst-cb { val -- prc; w c i self -- val } 3 proc-create ( prc ) val , does> { w c info self -- val } self @ ( val ) graph-popup-snd choose-chan set-wavelet-type ; : typ-labs ( -- ary ) #( "doub4" "doub6" "doub8" "doub10" "doub12" "doub14" "doub16" "doub18" "doub20" "battle_lemarie" "burt_adelson" "beylkin" "coif2" "coif4" "coif6" "sym2" "sym3" "sym4" "sym5" "sym6" ) map #( *key* i typ-lst-cb ) end-map ; : typ-set <{ lst -- }> graph-popup-snd graph-popup-chn wavelet-type { tp } lst each ( child ) i tp <> set-sensitive end-each ; : fft-color <{ w c info -- val }> #t color-orientation-dialog ; let: ( -- menu ) "fft-popup" main-widgets 2 array-ref #( #( "Transform" 'label #f #f ) #( "sep" 'separator #f #f ) #( "Peaks" #f <'> fft-peaks-cb #f ) #( "dB" #f <'> fft-db-cb #f ) #( "Log freq" #f <'> fft-frq-cb #f ) #( "Normalize" #f <'> fft-norm-cb #f ) #( "Graph type" 'cascade grp-labs <'> grp-set ) #( "Size" 'cascade siz-labs <'> siz-set ) #( "Window" 'cascade win-labs <'> win-set ) #( "Transform type" 'cascade trn-labs <'> trn-set ) #( "Wavelet type" 'cascade typ-labs <'> typ-set ) #( "Color/Orientation" #f <'> fft-color #f ) ) make-popup-menu ;let constant fft-popup-menu : fft-popup-cb { snd chn -- prc; w self -- val } 1 proc-create ( prc ) chn , snd , does> { w self -- val } self @ { chn } self cell+ @ { snd } w widget->name { name } name "Peaks" string= if w snd chn show-transform-peaks if "No peaks" else "Peaks" then change-label else name "dB" string= if w snd chn fft-log-magnitude if "Linear" else "dB" then change-label else name "Log freq" string= if w snd chn fft-log-frequency if "Linear freq" else "Log freq" then change-label then then then cascade-popup-cb-list each { entry } entry 0 array-ref #( entry 1 array-ref ) run-proc drop end-each #f ; : popup-install { snd chn xe ye info -- } snd to graph-popup-snd chn to graph-popup-chn snd channel-style channels-combined = if #t \ flag snd channels 0 ?do ye snd i undef axis-info 14 array-ref < if i 1- to graph-popup-chn not \ toggle flag leave then loop ( flag ) if snd channels 1- to graph-popup-chn then then snd chn transform-graph? if snd chn transform-graph axis-info else #f then { fax } snd chn lisp-graph? if snd chn lisp-graph axis-info else #f then { lax } fax if xe fax 10 array-ref >= xe fax 12 array-ref <= && if \ in fft fft-popup-menu snd chn fft-popup-cb for-each-child fft-popup-menu info popup-post-it #f else #t then else #t then if lax if xe lax 10 array-ref >= xe lax 12 array-ref <= && if \ in lisp #f else #t then else #t then if undef selection? if snd graph-popup-chn selection-position { pos } snd srate { sr } \ BEG and END should be floats pos sr f/ { beg } pos snd graph-popup-chn selection-framples f+ sr f/ { end } xe beg snd chn undef x->position >= xe end snd chn undef x->position <= && if selection-popup-menu info popup-post-it #f else #t then else #t then if graph-popup-menu graph-popup-snd graph-popup-chn graph-popup-cb for-each-child graph-popup-menu info popup-post-it then then then ; \ --- edit history popup --- #() value edhist-funcs #() value edhist-widgets #f value edhist-snd #f value edhist-chn : edhist-clear-edits <{ w c info -- #f }> #() to edhist-funcs #f ; : edhist-save-edits <{ w c info -- val }> edhist-funcs #( edhist-snd edhist-chn ) array-assoc-ref { old-proc } edhist-snd edhist-chn edits { cur-edits } edhist-snd edhist-chn cur-edits 0 array-ref 1+ 0 cur-edits each + end-each edit-list->function { proc } edhist-save-hook #( proc ) run-hook drop old-proc proc? if edhist-funcs #( edhist-snd edhist-chn ) proc array-assoc-set! else edhist-funcs #( #( edhist-snd edhist-chn ) proc ) array-push then to edhist-funcs ; : edhist-reapply-edits <{ w c info -- val }> edhist-funcs #( edhist-snd edhist-chn ) array-assoc-ref #( edhist-snd edhist-chn ) run-proc ; : edhist-set-wid <{ widget -- }> edhist-widgets widget array-push to edhist-widgets ; : edhist-apply <{ w c info -- }> edhist-funcs c range? if edhist-funcs c array-ref 1 array-ref ( proc ) #( edhist-snd edhist-chn ) run-proc drop then ; : edhist-apply-edits <{ lst -- }> edhist-widgets 0 array-ref { parent } edhist-widgets 1 nil array-subarray { wids } edhist-funcs each 0 array-ref { label } nil { button } wids nil? if "wid" FxmPushButtonWidgetClass parent #( FXmNbackground highlight-color ) undef FXtCreateManagedWidget to button edhist-widgets #( button ) array-append to edhist-widgets button FXmNactivateCallback <'> edhist-apply i FXtAddCallback drop else wids 0 array-ref to button wids 1 nil array-subarray to wids button FXtManageChild drop then label array? if \ label: #(snd chn) button "%s[%s]" #( label 0 array-ref short-file-name label 1 array-ref ) string-format change-label else \ label: "file-name[chn]" button label change-label then button #( FXmNuserData i ) FXtVaSetValues drop end-each wids each ( w ) FXtUnmanageChild drop end-each ; : edhist-close-hook-cb <{ snd -- }> snd channels 0 ?do edhist-funcs #( snd i ) array-assoc { old-val } old-val array? if old-val 0 "%s[%d]" #( snd short-file-name i ) string-format array-set! then loop ; let: ( -- menu ) close-hook <'> edhist-close-hook-cb add-hook! "edhist-popup" main-widgets 2 array-ref #( #( "Edits" 'label #f #f ) #( "sep" 'separator #f #f ) #( "Save" #f <'> edhist-save-edits #f ) #( "Reapply" #f <'> edhist-reapply-edits #f ) #( "Apply" 'cascade <'> edhist-set-wid <'> edhist-apply-edits ) #( "Clear" #f <'> edhist-clear-edits #f ) #( "sep" 'separator #f #f ) #( "Help" #f <'> edhist-help-edits #f ) ) make-popup-menu ;let constant edit-history-menu : edhist-popup-cb { snd chn -- prc; w self -- val } 1 proc-create ( prc ) chn , snd , does> { w self -- val } self @ { chn } self cell+ @ { snd } w FXtName { name } name "Clear" string= name "Apply" string= || if w edhist-funcs empty? not set-sensitive #f exit then name "Save" string= if w 0 snd chn edits each ( eds ) + end-each 0> set-sensitive #f exit then name "Reapply" string= if w edhist-funcs #( snd chn ) array-assoc-ref set-sensitive then #f ; : edhist-popup-handler-cb { snd chn -- prc; w c i self -- val } 3 proc-create ( prc ) chn , snd , does> { w c info self -- val } self @ { chn } self cell+ @ { snd } info Fevent { ev } FButtonPress ev Ftype = if snd to edhist-snd chn to edhist-chn edit-history-menu snd chn edhist-popup-cb for-each-child edit-history-menu info popup-post-it then #f ; : popup-handler-cb { snd chn -- prc; w c i self -- val } 3 proc-create ( prc ) chn , snd , does> { w c info self -- val } self @ { chn } self cell+ @ { snd } info Fevent { ev } ev Fx_root w 0 0 FXtTranslateCoords 0 array-ref - { xe } ev Fy { ye } FButtonPress ev Ftype = if snd chn xe ye info popup-install then #f ; \ --- listener popup --- : identity-cb <{ snds -- lst }> snds ; : edited-cb <{ snds -- lst }> snds each { snd } snd channels 0 ?do snd i edits 0 array-ref 0= if snds snd array-delete-key drop then loop end-each snds ; : focused-cb <{ snds -- lst }> snds length 1 > if snds else #() then ; : list-play-cb <{ snd -- val }> snd play ; : list-focus-cb <{ us -- val }> \ 5 == notebook-outer-pane main-widgets 5 array-ref FWidget? if us set-selected-sound else us sound-widgets 0 array-ref { pane } main-widgets 1 array-ref #( FXmNallowShellResize #f ) FXtVaSetValues drop sounds each ( them ) sound-widgets 0 array-ref FXtUnmanageChild drop end-each pane FXtManageChild drop main-widgets 1 array-ref #( FXmNallowShellResize auto-resize ) FXtVaSetValues then ; : list-help-cb <{ w c info -- val }> listener-selection { selected } selected if selected undef snd-help { help } help if selected help undef undef help-dialog then then ; : list-clear-cb <{ w c info -- val }> clear-listener ; : listener-edit <{ w -- }> w FXtName "Help" string= if listener-selection ?dup-if 1 >list w "Help on %S" rot string-format change-label w FXtManageChild else w FXtUnmanageChild then drop then ; : listener-popup-cb <{ w c info -- }> c { menu } FButtonPress info Fevent Ftype = if listener-values each { vals } vals array? if vals 0 array-ref { top-one } vals 1 array-ref { top-two } vals 2 array-ref { top-two-cascade } vals 3 array-ref #( sounds ) run-proc length { len } top-two FXtUnmanageChild drop top-two-cascade FXtUnmanageChild drop top-one if top-one FXtUnmanageChild drop then len 1 > if top-two-cascade FXtManageChild drop top-two FXtManageChild drop then top-one FWidget? len 1 = && if top-one FXtManageChild drop then then end-each menu <'> listener-edit for-each-child info menu Fset_menuToPost drop then ; let: ( -- menu ) main-widgets 4 array-ref ?dup-if ( parent ) else #t set-show-listener drop #f set-show-listener drop main-widgets 4 array-ref then { parent } "listener-popup" parent #( #( "Listener" 'label #f #f ) #( "sep" 'separator #f #f ) #( "Play" 'cascade <'> list-play-cb <'> identity-cb #t ) #( "Help" #f <'> list-help-cb #f ) #( "Open" #f <'> popen-cb #f ) #( "Clear listener" #f <'> list-clear-cb #f ) #( "Close" 'cascade <'> close-sound-extend <'> identity-cb #t ) #( "Save" 'cascade <'> save-sound <'> edited-cb #t ) #( "Revert" 'cascade <'> revert-sound <'> edited-cb #t ) #( "Focus" 'cascade <'> list-focus-cb <'> focused-cb #f ) #( "sep" 'separator #f #f ) #( "Exit" #f <'> exit-cb #f ) ) make-popup-menu { menu } parent FXmNpopupHandlerCallback <'> listener-popup-cb menu FXtAddCallback drop menu ;let constant listener-popup-menu #() constant popups : add-popup <{ snd -- }> snd channels 0 ?do popups #( snd i ) array-member? unless popups #( snd i ) array-push drop snd i channel-widgets 7 array-ref ( chn-edhist ) FXmNpopupHandlerCallback snd i edhist-popup-handler-cb undef FXtAddCallback drop snd i channel-widgets 0 array-ref ( chn-grf ) FXmNpopupHandlerCallback snd i popup-handler-cb undef FXtAddCallback drop then loop ; : change-color-col-cb { col -- prc; w self -- val } 1 proc-create ( prc ) col , does> { w self -- val } w self @ ( col ) FXmChangeColor ; set-current : change-menu-color ( menu new-color -- ) doc" Change the color of MENU to NEW-COLOR. \ NEW-COLOR can be the color name, an xm Pixel, a snd color, \ or a list of rgb values (as in Snd's make-color)." { menu new-color } new-color string? if \ assuming X11 color names here main-widgets 1 array-ref { shell } shell FXtDisplay { dpy } dpy FDefaultScreen { scr } dpy scr FDefaultColormap { cmap } FXColor { col } dpy cmap new-color col col FXAllocNamedColor 0= if "can't allocate %S" #( new-color ) string-format snd-error else col Fpixel then else new-color color? if new-color else new-color each ( vals-to-stack ) end-each make-color then then ( color-pixel ) menu swap change-color-col-cb for-each-child ; : change-selection-popup-color ( new-color -- ) doc" Change the selection popup menu's color: \ \"red\" change-selection-popup-color." selection-popup-menu swap change-menu-color ; : change-graph-popup-color ( new-color -- ) doc" Change the time-domain popup menu's color: \ basic-color change-graph-popup-color." selection-popup-menu swap change-menu-color ; : change-fft-popup-color ( new-color -- ) doc" Change the fft popup menu's color: \ #(0.5 0.5 0.5) change-fft-popup-color." fft-popup-menu swap change-menu-color ; : change-edhist-popup-color ( new-color -- ) doc" Change the time-domain popup menu's color: \ basic-color change-graph-popup-color." edit-history-menu swap change-menu-color ; : change-listener-popup-color ( new-color -- ) doc" Change the listener popup menu's color." listener-popup-menu swap change-menu-color ; : add-popups ( -- ) after-open-hook <'> add-popup add-hook! sounds each ( snd ) add-popup end-each ; previous \ install all popups add-popups \ popup.fs ends here snd-16.1/snd-edits.c0000644000076400007640000103524712623170516012410 0ustar bilbil#include "snd.h" static Xen save_hook; static bool dont_save(snd_info *sp, const char *newname) { Xen res = Xen_false; if (Xen_hook_has_list(save_hook)) res = run_or_hook(save_hook, Xen_list_2(C_int_to_Xen_sound(sp->index), (newname) ? C_string_to_Xen_string(newname) : Xen_false), S_save_hook); return(Xen_is_true(res)); } void after_edit(chan_info *cp) { reflect_edit_history_change(cp); reflect_enved_fft_change(cp); if ((cp->hookable == WITH_HOOK) && (Xen_is_hook(cp->after_edit_hook)) && (Xen_hook_has_list(cp->after_edit_hook))) run_hook(cp->after_edit_hook, Xen_empty_list, S_after_edit_hook); } void free_sound_list(chan_info *cp) { if (cp) { if (cp->sounds) { int i; if ((cp->sound) && (cp->sound->playing)) stop_playing_sound_without_hook(cp->sound, PLAY_CLOSE); for (i = 0; i < cp->sound_size; i++) if (cp->sounds[i]) cp->sounds[i] = free_snd_data(cp->sounds[i]); free(cp->sounds); cp->sounds = NULL; } cp->sound_ctr = NOT_A_SOUND; cp->sound_size = 0; } } static void release_pending_sounds(chan_info *cp, int edit_ctr) { /* look for buffers or temp files that are no longer reachable after pruning the edit tree */ if ((cp) && (cp->sounds)) { int i; if ((cp->sound) && (cp->sound->playing)) stop_playing_sound_without_hook(cp->sound, PLAY_CLOSE); for (i = 0; i < cp->sound_size; i++) { snd_data *sd; sd = cp->sounds[i]; if (sd) { if (sd->edit_ctr >= edit_ctr) cp->sounds[i] = free_snd_data(sd); else cp->sound_ctr = i; } } } } #define EDIT_ALLOC_SIZE 32 /* EDIT_ALLOC_SIZE is the allocation amount (pointers) each time cp->sounds is (re)allocated */ void prepare_sound_list(chan_info *cp) { cp->sound_ctr++; /* this is the only place the sound set is incremented */ if (cp->sound_ctr >= cp->sound_size) { int i; cp->sound_size += EDIT_ALLOC_SIZE; cp->sounds = (snd_data **)realloc(cp->sounds, cp->sound_size * sizeof(snd_data *)); for (i = cp->sound_ctr; i < cp->sound_size; i++) cp->sounds[i] = NULL; } if (cp->sounds[cp->sound_ctr]) { if ((cp->sound) && (cp->sound->playing)) stop_playing_sound_without_hook(cp->sound, PLAY_CLOSE); cp->sounds[cp->sound_ctr] = free_snd_data(cp->sounds[cp->sound_ctr]); } } static int add_sound_file_to_edit_list(chan_info *cp, const char *name, snd_io *io, file_info *hdr, file_delete_t temp, int chan) { prepare_sound_list(cp); cp->sounds[cp->sound_ctr] = make_snd_data_file(name, io, hdr, temp, cp->edit_ctr, chan); return(cp->sound_ctr); } static ed_list *free_ed_list(ed_list *ed, chan_info *cp); static void prune_edits(chan_info *cp, int edpt) { if (cp->edits[edpt]) { int i; if (ss->deferred_regions > 0) sequester_deferred_regions(cp, edpt - 1); for (i = edpt; i < cp->edit_size; i++) cp->edits[i] = free_ed_list(cp->edits[i], cp); release_pending_sounds(cp, edpt); } } bool is_editable(chan_info *cp) { if (!(cp->editable)) return(false); if ((Xen_is_hook(cp->edit_hook)) && (Xen_hook_has_list(cp->edit_hook))) { Xen res; res = run_or_hook(cp->edit_hook, Xen_empty_list, S_edit_hook); if (Xen_is_true(res)) return(false); } return(true); } static void increment_edit_ctr(chan_info *cp) { cp->edit_ctr++; if (cp->edit_ctr >= cp->edit_size) { int i; cp->edit_size += EDIT_ALLOC_SIZE; if (!cp->edits) cp->edits = (ed_list **)calloc(cp->edit_size, sizeof(ed_list *)); else cp->edits = (ed_list **)realloc(cp->edits, cp->edit_size * sizeof(ed_list *)); for (i = cp->edit_ctr; i < cp->edit_size; i++) cp->edits[i] = NULL; } } static bool prepare_edit_list(chan_info *cp, int pos, const char *caller) { /* pos is the edit position the current edit is referring to -- * we normally can't set up an edit list entry that refers to a situation * that will be clobbered by prune_edits below */ snd_info *sp; if (!(is_editable(cp))) return(false); /* this may represent a second call on edit-hook for this edit */ if (pos > cp->edit_ctr) { Xen_error(NO_SUCH_EDIT, Xen_list_6(C_string_to_Xen_string("~A: edpos: ~A but ~A chan ~A has ~A edits"), C_string_to_Xen_string(caller), C_int_to_Xen_integer(pos), C_string_to_Xen_string(cp->sound->short_filename), C_int_to_Xen_integer(cp->chan), C_int_to_Xen_integer(cp->edit_ctr))); } sp = cp->sound; stop_peak_env(cp); if ((sp) && (sp->playing)) stop_playing_sound_without_hook(sp, PLAY_EDIT); increment_edit_ctr(cp); prune_edits(cp, cp->edit_ctr); return(true); } static void reflect_sample_change_in_axis(chan_info *cp) { axis_info *ap; ap = cp->axis; if (ap) { mus_long_t samps; samps = current_samples(cp); ap->xmax = (double)samps / (double)snd_srate(cp->sound); ap->x_ambit = ap->xmax - ap->xmin; if (ap->x1 > ap->xmax) ap->x1 = ap->xmax; if ((samps == 0) || (ap->no_data)) { ap->no_data = (samps == 0); if (ap->xlabel) free(ap->xlabel); if (samps == 0) ap->xlabel = mus_strdup("(no data)"); else { if (ap->default_xlabel) ap->xlabel = mus_strdup(ap->default_xlabel); else ap->xlabel = mus_strdup("time"); } } set_x_bounds(ap); } } void reflect_file_change_in_label(chan_info *cp) { #if (!USE_NO_GUI) snd_info *sp; if (cp->edit_ctr == 0) return; sp = cp->sound; if (!(cp->squelch_update)) { char *starred_name; int len; len = strlen(shortname(sp)) + 16; starred_name = (char *)calloc(len, sizeof(char)); strcopy(starred_name, shortname_indexed(sp), len); if ((sp->user_read_only == FILE_READ_ONLY) || (sp->file_read_only == FILE_READ_ONLY)) strcat(starred_name, "(*)"); else strcat(starred_name, "*"); set_sound_pane_file_label(sp, starred_name); free(starred_name); } #endif } static void check_for_first_edit(chan_info *cp) { if (cp->edit_ctr == 1) /* first edit on this file (?) */ reflect_file_change_in_label(cp); } static Xen save_state_hook; char *run_save_state_hook(const char *file) { char *filename; filename = mus_strdup(file); if (Xen_hook_has_list(save_state_hook)) { Xen result; #if HAVE_SCHEME result = s7_call(s7, save_state_hook, s7_cons(s7, C_string_to_Xen_string(filename), s7_nil(s7))); if (Xen_is_string(result)) { free(filename); filename = mus_strdup(Xen_string_to_C_string(result)); } #else Xen procs, fname; fname = C_string_to_Xen_string(filename); procs = Xen_hook_list(save_state_hook); while (!Xen_is_null(procs)) { result = Xen_call_with_1_arg(Xen_car(procs), fname, "save state hook"); if (Xen_is_string(result)) { free(filename); filename = mus_strdup(Xen_string_to_C_string(result)); } procs = Xen_cdr(procs); } #endif } return(filename); } /* -------- EDIT LISTS -------- * * each channel has a list of lists containing the current edit history and the associated sound temp files or buffers * undo: back up current list position * redo: push position foward * No actual changes are flushed out to the file system until the file is saved. * * the editing possibilities are insert, change, delete, scale, zero, env, mix * All input goes through these lists (with minor exceptions -- see chn_sample below). * * The accessors are highly optimized (split into numerous choices) since everything else in Snd * goes through the accessors to get at the data. * * I tried a flattened version (using ed_fragment* rather than ed_fragment**) which involves fewer calls on malloc, * but the edit list is a "real" list -- we do internal insertions and deletions and so on, so it's simpler * to use in the current form. */ /* fragment ramp info */ typedef struct { double start, incr; } ramp_state; typedef struct { double start, incr, scl, off; } xramp_state; typedef struct { int ramps, xramps; ramp_state *ramp_list; xramp_state *xramp_list; } ed_ramps; /* fragment mix info */ typedef struct { int size; /* size of mix_list, but some entries can be empty */ mix_state **mix_list; } ed_mixes; /* ed list fragment */ typedef struct ed_fragment { /* this name is necessary even in straight C */ int typ, /* code for accessor choice (ED_SIMPLE etc) */ snd; /* either an index into the cp->sounds array (snd_data structs) or EDIT_LIST_END|ZERO_MARK */ mus_long_t out, /* running segment location within current overall edited data */ beg, /* index into the associated data => start point of data used in current segment */ end; /* index into the associated data => end point of data used in current segment */ mus_float_t scl; /* segment scaler */ ed_ramps *ramps; ed_mixes *mixes; struct ed_fragment *next; } ed_fragment; /* reader ramp info */ typedef struct { int ramps, xramps; double *incrs, *vals; double *xincrs, *xvals; mus_float_t (*rampf)(struct snd_fd *sf); mus_float_t (*rev_rampf)(struct snd_fd *sf); } reader_ramps; /* reader mix info */ typedef struct { short size; snd_fd **sfs; } reader_mixes; /* two ed_fragment->snd markers */ #define EDIT_LIST_END_MARK -2 #define EDIT_LIST_ZERO_MARK -1 #define FRAGMENTS(Ed) (ed_fragment **)((Ed)->fragments) #define FRAGMENT(Ed, Pos) ((ed_fragment **)((Ed)->fragments))[Pos] /* #define FRAGMENT_RAMPS(Ed, Pos) ((ed_fragment **)((Ed)->fragments))[Pos]->ramps */ /* #define FRAGMENT_RAMP_LIST(Ed, Pos) ((ed_fragment **)((Ed)->fragments))[Pos]->ramps->ramp_list */ #define FRAGMENT_RAMP_LIST_SIZE(Ed, Pos) ((ed_fragment **)((Ed)->fragments))[Pos]->ramps->ramps /* #define FRAGMENT_XRAMP_LIST(Ed, Pos) ((ed_fragment **)((Ed)->fragments))[Pos]->ramps->xramp_list */ #define FRAGMENT_XRAMP_LIST_SIZE(Ed, Pos) ((ed_fragment **)((Ed)->fragments))[Pos]->ramps->xramps #define FRAGMENT_MIXES(Ed, Pos) ((ed_fragment **)((Ed)->fragments))[Pos]->mixes #define FRAGMENT_MIX_LIST_SIZE(Ed, Pos) ((ed_fragment **)((Ed)->fragments))[Pos]->mixes->size #define FRAGMENT_MIX_LIST(Ed, Pos) ((ed_fragment **)((Ed)->fragments))[Pos]->mixes->mix_list #define FRAGMENT_GLOBAL_POSITION(Ed, Pos) ((ed_fragment **)((Ed)->fragments))[Pos]->out #define FRAGMENT_LOCAL_POSITION(Ed, Pos) ((ed_fragment **)((Ed)->fragments))[Pos]->beg #define FRAGMENT_LOCAL_END(Ed, Pos) ((ed_fragment **)((Ed)->fragments))[Pos]->end #define FRAGMENT_SCALER(Ed, Pos) ((ed_fragment **)((Ed)->fragments))[Pos]->scl #define FRAGMENT_TYPE(Ed, Pos) ((ed_fragment **)((Ed)->fragments))[Pos]->typ #define FRAGMENT_SOUND(Ed, Pos) ((ed_fragment **)((Ed)->fragments))[Pos]->snd #define FRAGMENT_LENGTH(Ed, Pos) (FRAGMENT_LOCAL_END(Ed, Pos) - FRAGMENT_LOCAL_POSITION(Ed, Pos) + 1) #define FRAGMENT_RAMP_START(Ed, Pos, Rmp) ((ed_fragment **)((Ed)->fragments))[Pos]->ramps->ramp_list[Rmp].start #define FRAGMENT_RAMP_INCR(Ed, Pos, Rmp) ((ed_fragment **)((Ed)->fragments))[Pos]->ramps->ramp_list[Rmp].incr #define FRAGMENT_XRAMP_START(Ed, Pos, Rmp) ((ed_fragment **)((Ed)->fragments))[Pos]->ramps->xramp_list[Rmp].start #define FRAGMENT_XRAMP_INCR(Ed, Pos, Rmp) ((ed_fragment **)((Ed)->fragments))[Pos]->ramps->xramp_list[Rmp].incr #define FRAGMENT_XRAMP_SCALER(Ed, Pos, Rmp) ((ed_fragment **)((Ed)->fragments))[Pos]->ramps->xramp_list[Rmp].scl #define FRAGMENT_XRAMP_OFFSET(Ed, Pos, Rmp) ((ed_fragment **)((Ed)->fragments))[Pos]->ramps->xramp_list[Rmp].off #define FRAGMENT_MIX_STATE(Ed, Pos, Mix) ((ed_fragment **)((Ed)->fragments))[Pos]->mixes->mix_list[Mix] /* #define FRAGMENT_MIX_INDEX(Ed, Pos, Mix) ((ed_fragment **)((Ed)->fragments))[Pos]->mixes->mix_list[Mix]->index */ /* #define FRAGMENT_MIX_LENGTH(Ed, Pos, Mix) ((ed_fragment **)((Ed)->fragments))[Pos]->mixes->mix_list[Mix]->len */ /* #define FRAGMENT_MIX_SCALER(Ed, Pos, Mix) ((ed_fragment **)((Ed)->fragments))[Pos]->mixes->mix_list[Mix]->scaler */ /* #define FRAGMENT_MIX_BEG(Ed, Pos, Mix) ((ed_fragment **)((Ed)->fragments))[Pos]->mixes->mix_list[Mix]->beg */ #define ED_GLOBAL_POSITION(Ed) (Ed)->out #define ED_LOCAL_POSITION(Ed) (Ed)->beg #define ED_LOCAL_END(Ed) (Ed)->end #define ED_SCALER(Ed) (Ed)->scl #define ED_TYPE(Ed) (Ed)->typ #define ED_SOUND(Ed) (Ed)->snd #define ED_RAMPS(Ed) (Ed)->ramps #define ED_RAMP_LIST(Ed) (Ed)->ramps->ramp_list #define ED_RAMP_LIST_SIZE(Ed) (Ed)->ramps->ramps #define ED_XRAMP_LIST(Ed) (Ed)->ramps->xramp_list #define ED_XRAMP_LIST_SIZE(Ed) (Ed)->ramps->xramps #define ED_RAMP_START(Ed, Rmp) (Ed)->ramps->ramp_list[Rmp].start #define ED_RAMP_INCR(Ed, Rmp) (Ed)->ramps->ramp_list[Rmp].incr #define ED_XRAMP_START(Ed, Rmp) (Ed)->ramps->xramp_list[Rmp].start #define ED_XRAMP_INCR(Ed, Rmp) (Ed)->ramps->xramp_list[Rmp].incr #define ED_XRAMP_SCALER(Ed, Rmp) (Ed)->ramps->xramp_list[Rmp].scl #define ED_XRAMP_OFFSET(Ed, Rmp) (Ed)->ramps->xramp_list[Rmp].off #define ED_MIXES(Ed) (Ed)->mixes #define ED_MIX_LIST(Ed) (Ed)->mixes->mix_list /* #define ED_MIX_LIST_SIZE(Ed) (Ed)->mixes->size */ /* #define ED_MIX_STATE(Ed, Mix) (Ed)->mixes->mix_list[Mix] */ /* #define ED_MIX_INDEX(Ed, Mix) (Ed)->mixes->mix_list[Mix]->index */ /* #define ED_MIX_LENGTH(Ed, Mix) (Ed)->mixes->mix_list[Mix]->len */ /* #define ED_MIX_SCALER(Ed, Mix) (Ed)->mixes->mix_list[Mix]->scaler */ /* #define ED_MIX_BEG(Ed, Mix) (Ed)->mixes->mix_list[Mix]->beg */ #define MIX_LIST_SCALER(Ed, Mix) (Ed)->mix_list[Mix]->scaler #define MIX_LIST_STATE(Ed, Mix) (Ed)->mix_list[Mix] #define MIX_LIST_INDEX(Ed, Mix) (Ed)->mix_list[Mix]->index /* #define MIX_LIST_LENGTH(Ed, Mix) (Ed)->mix_list[Mix]->len */ #define MIX_LIST_BEG(Ed, Mix) (Ed)->mix_list[Mix]->beg #define READER_GLOBAL_POSITION(Sf) ((ed_fragment *)((Sf)->cb))->out #define READER_LOCAL_POSITION(Sf) ((ed_fragment *)((Sf)->cb))->beg #define READER_LOCAL_END(Sf) ((ed_fragment *)((Sf)->cb))->end #define READER_SCALER(Sf) ((ed_fragment *)((Sf)->cb))->scl #define READER_TYPE(Sf) ((ed_fragment *)((Sf)->cb))->typ #define READER_SOUND(Sf) ((ed_fragment *)((Sf)->cb))->snd #define READER_RAMP_START(Sf, Pos) ((ed_fragment *)((Sf)->cb))->ramps->ramp_list[Pos].start #define READER_RAMP_INCR(Sf, Pos) ((ed_fragment *)((Sf)->cb))->ramps->ramp_list[Pos].incr #define READER_XRAMP_START(Sf, Pos) ((ed_fragment *)((Sf)->cb))->ramps->xramp_list[Pos].start #define READER_XRAMP_INCR(Sf, Pos) ((ed_fragment *)((Sf)->cb))->ramps->xramp_list[Pos].incr #define READER_XRAMP_SCALER(Sf, Pos) ((ed_fragment *)((Sf)->cb))->ramps->xramp_list[Pos].scl #define READER_XRAMP_OFFSET(Sf, Pos) ((ed_fragment *)((Sf)->cb))->ramps->xramp_list[Pos].off #define READER_RAMPS(Sf) ((reader_ramps *)((Sf)->ramps))->ramps #define READER_XRAMPS(Sf) ((reader_ramps *)((Sf)->ramps))->xramps #define READER_INCRS(Sf) ((reader_ramps *)((Sf)->ramps))->incrs #define READER_VALS(Sf) ((reader_ramps *)((Sf)->ramps))->vals #define READER_XINCRS(Sf) ((reader_ramps *)((Sf)->ramps))->xincrs #define READER_XVALS(Sf) ((reader_ramps *)((Sf)->ramps))->xvals #define READER_INCR(Sf, Pos) ((reader_ramps *)((Sf)->ramps))->incrs[Pos] #define READER_VAL(Sf, Pos) ((reader_ramps *)((Sf)->ramps))->vals[Pos] #define READER_XINCR(Sf, Pos) ((reader_ramps *)((Sf)->ramps))->xincrs[Pos] #define READER_XVAL(Sf, Pos) ((reader_ramps *)((Sf)->ramps))->xvals[Pos] #define READER_RAMPF(Sf) ((reader_ramps *)((Sf)->ramps))->rampf #define READER_REV_RAMPF(Sf) ((reader_ramps *)((Sf)->ramps))->rev_rampf /* #define READER_MIXES(Sf) ((ed_fragment *)((Sf)->cb))->mixes */ #define READER_MIX_LIST_SIZE(Sf) ((ed_fragment *)((Sf)->cb))->mixes->size /* #define READER_MIX_LIST(Sf) ((ed_fragment *)((Sf)->cb))->mixes->mix_list */ #define READER_MIX_STATE(Sf, Mix) ((ed_fragment *)((Sf)->cb))->mixes->mix_list[Mix] #define READER_MIX_INDEX(Sf, Mix) ((ed_fragment *)((Sf)->cb))->mixes->mix_list[Mix]->index #define READER_MIX_LENGTH(Sf, Mix) ((ed_fragment *)((Sf)->cb))->mixes->mix_list[Mix]->len #define READER_MIX_SCALER(Sf, Mix) ((ed_fragment *)((Sf)->cb))->mixes->mix_list[Mix]->scaler #define READER_MIX_BEG(Sf, Mix) ((ed_fragment *)((Sf)->cb))->mixes->mix_list[Mix]->beg /* -------------------------------- fragment accessors -------------------------------- */ static mus_float_t next_ramp1_value(snd_fd *sf) { mus_float_t val; val = READER_VAL(sf, 0); READER_VAL(sf, 0) += READER_INCR(sf, 0); return(val); } static mus_float_t previous_ramp1_value(snd_fd *sf) { mus_float_t val; val = READER_VAL(sf, 0); READER_VAL(sf, 0) -= READER_INCR(sf, 0); return(val); } static mus_float_t next_ramp2_value(snd_fd *sf) { mus_float_t val; val = READER_VAL(sf, 0) * READER_VAL(sf, 1); READER_VAL(sf, 0) += READER_INCR(sf, 0); READER_VAL(sf, 1) += READER_INCR(sf, 1); return(val); } static mus_float_t previous_ramp2_value(snd_fd *sf) { mus_float_t val; val = READER_VAL(sf, 0) * READER_VAL(sf, 1); READER_VAL(sf, 0) -= READER_INCR(sf, 0); READER_VAL(sf, 1) -= READER_INCR(sf, 1); return(val); } static mus_float_t next_ramp_value(snd_fd *sf) { mus_float_t val; int i; val = READER_VAL(sf, 0); READER_VAL(sf, 0) += READER_INCR(sf, 0); for (i = 1; i < READER_RAMPS(sf); i++) { val *= READER_VAL(sf, i); READER_VAL(sf, i) += READER_INCR(sf, i); } return(val); } static mus_float_t previous_ramp_value(snd_fd *sf) { mus_float_t val; int i; val = READER_VAL(sf, 0); READER_VAL(sf, 0) -= READER_INCR(sf, 0); for (i = 1; i < READER_RAMPS(sf); i++) { val *= READER_VAL(sf, i); READER_VAL(sf, i) -= READER_INCR(sf, i); } return(val); } static mus_float_t next_xramp1_value(snd_fd *sf) { mus_float_t val; val = (READER_XRAMP_OFFSET(sf, 0) + (READER_XRAMP_SCALER(sf, 0) * READER_XVAL(sf, 0))); READER_XVAL(sf, 0) *= READER_XINCR(sf, 0); return(val); } /* ideally we'd invert the increment if reading an xramp in reverse, making this a multiply, not a divide, * but then we'd need a fixup when the reader changes direction -- probably not worth the complexity. */ static mus_float_t previous_xramp1_value(snd_fd *sf) { mus_float_t val; val = (READER_XRAMP_OFFSET(sf, 0) + (READER_XRAMP_SCALER(sf, 0) * READER_XVAL(sf, 0))); READER_XVAL(sf, 0) /= READER_XINCR(sf, 0); return(val); } static mus_float_t next_xramp_value(snd_fd *sf) { int i; mus_float_t val; val = (READER_XRAMP_OFFSET(sf, 0) + (READER_XRAMP_SCALER(sf, 0) * READER_XVAL(sf, 0))); READER_XVAL(sf, 0) *= READER_XINCR(sf, 0); for (i = 1; i < READER_XRAMPS(sf); i++) { val *= (READER_XRAMP_OFFSET(sf, i) + (READER_XRAMP_SCALER(sf, i) * READER_XVAL(sf, i))); READER_XVAL(sf, i) *= READER_XINCR(sf, i); } return(val); } static mus_float_t previous_xramp_value(snd_fd *sf) { int i; mus_float_t val = 1.0; for (i = 0; i < READER_XRAMPS(sf); i++) { val *= (READER_XRAMP_OFFSET(sf, i) + (READER_XRAMP_SCALER(sf, i) * READER_XVAL(sf, i))); READER_XVAL(sf, i) /= READER_XINCR(sf, i); } return(val); } static mus_float_t next_xramp_ramp_value(snd_fd *sf) { return(next_xramp_value(sf) * next_ramp_value(sf)); } static mus_float_t previous_xramp_ramp_value(snd_fd *sf) { return(previous_xramp_value(sf) * previous_ramp_value(sf)); } static mus_float_t previous_sound(snd_fd *sf); static mus_float_t next_sound(snd_fd *sf); static mus_float_t end_sample_value(snd_fd *ignore) {return(0.0);} static mus_float_t next_sample_value(snd_fd *sf) { if (sf->loc > sf->last) return(next_sound(sf)); else return(sf->data[sf->loc++] * sf->fscaler); } #define SF_UNSAFE 0 static mus_float_t next_sample_value_unchecked(snd_fd *sf) { #if SF_UNSAFE if (sf->loc > sf->last) { fprintf(stderr, "ran off end somehow\n"); abort(); } #endif return(sf->data[sf->loc++] * sf->fscaler); } static mus_float_t previous_sample_value(snd_fd *sf) { if (sf->loc < sf->first) return(previous_sound(sf)); else return(sf->data[sf->loc--] * sf->fscaler); } mus_float_t previous_sample_value_unchecked(snd_fd *sf) ; mus_float_t previous_sample_value_unchecked(snd_fd *sf) { return(sf->data[sf->loc--] * sf->fscaler); } static mus_float_t next_sample_value_unscaled(snd_fd *sf) { if (sf->loc > sf->last) return(next_sound(sf)); else return(sf->data[sf->loc++]); } mus_float_t next_sample_value_unscaled_and_unchecked(snd_fd *sf); mus_float_t next_sample_value_unscaled_and_unchecked(snd_fd *sf) { #if SF_UNSAFE if (sf->loc > sf->last) { fprintf(stderr, "ran off end somehow\n"); abort(); } #endif return(sf->data[sf->loc++]); } mus_float_t previous_sample_value_unscaled(snd_fd *sf) ; mus_float_t previous_sample_value_unscaled(snd_fd *sf) { if (sf->loc < sf->first) return(previous_sound(sf)); else return(sf->data[sf->loc--]); } mus_float_t previous_sample_value_unscaled_and_unchecked(snd_fd *sf); mus_float_t previous_sample_value_unscaled_and_unchecked(snd_fd *sf) { return(sf->data[sf->loc--]); } static mus_float_t next_zero(snd_fd *sf) { if (sf->loc > sf->last) return(next_sound(sf)); sf->loc++; return(0.0); } static mus_float_t previous_zero(snd_fd *sf) { if (sf->loc < sf->first) return(previous_sound(sf)); sf->loc--; return(0.0); } static mus_float_t next_ramp1(snd_fd *sf) { if (sf->loc > sf->last) return(next_sound(sf)); else { mus_float_t val; val = sf->data[sf->loc++] * READER_VAL(sf, 0); READER_VAL(sf, 0) += READER_INCR(sf, 0); return(val); } } static mus_float_t next_ramp1_unchecked(snd_fd *sf) { mus_float_t val; #if SF_UNSAFE if (sf->loc > sf->last) { fprintf(stderr, "ran off end somehow\n"); abort(); } #endif val = sf->data[sf->loc++] * READER_VAL(sf, 0); READER_VAL(sf, 0) += READER_INCR(sf, 0); return(val); } static mus_float_t previous_ramp1(snd_fd *sf) { if (sf->loc < sf->first) return(previous_sound(sf)); else { mus_float_t val; val = sf->data[sf->loc--] * READER_VAL(sf, 0); READER_VAL(sf, 0) -= READER_INCR(sf, 0); return(val); } } static mus_float_t next_ramp_f(snd_fd *sf) { if (sf->loc > sf->last) return(next_sound(sf)); else return(sf->data[sf->loc++] * (*(READER_RAMPF(sf)))(sf)); } static mus_float_t previous_ramp_f(snd_fd *sf) { if (sf->loc < sf->first) return(previous_sound(sf)); else return(sf->data[sf->loc--] * (*(READER_REV_RAMPF(sf)))(sf)); } static mus_float_t next_ramp(snd_fd *sf) { if (sf->loc > sf->last) return(next_sound(sf)); else return(sf->data[sf->loc++] * next_ramp_value(sf)); } static mus_float_t previous_ramp(snd_fd *sf) { if (sf->loc < sf->first) return(previous_sound(sf)); else return(sf->data[sf->loc--] * previous_ramp_value(sf)); } static mus_float_t next_xramp1(snd_fd *sf) { if (sf->loc > sf->last) return(next_sound(sf)); else return(sf->data[sf->loc++] * READER_SCALER(sf) * next_xramp1_value(sf)); } static mus_float_t previous_xramp1(snd_fd *sf) { if (sf->loc < sf->first) return(previous_sound(sf)); else return(sf->data[sf->loc--] * READER_SCALER(sf) * previous_xramp1_value(sf)); } static mus_float_t next_xramp(snd_fd *sf) { if (sf->loc > sf->last) return(next_sound(sf)); else return(sf->data[sf->loc++] * READER_SCALER(sf) * next_xramp_value(sf)); } static mus_float_t previous_xramp(snd_fd *sf) { if (sf->loc < sf->first) return(previous_sound(sf)); else return(sf->data[sf->loc--] * READER_SCALER(sf) * previous_xramp_value(sf)); } /* mix readers */ static mus_float_t read_mix_list_samples(snd_fd *sf) { reader_mixes *m; int i; mus_float_t sum; m = (reader_mixes *)(sf->mixes); if (m->size == 0) return(0.0); /* this is apparently possible?? */ sum = read_sample(m->sfs[0]); for (i = 1; i < m->size; i++) sum += read_sample(m->sfs[i]); return(sum); } static mus_float_t next_mix(snd_fd *sf) { /* read_sample here would call runf => next_mix => infinite recursion */ if (sf->loc > sf->last) return(next_sound(sf)); /* next_sound here refers to whatever follows the mixed portion */ return((sf->data[sf->loc++] * sf->fscaler) + read_mix_list_samples(sf)); } /* if underlying data was scaled,and we added a mix, we couldn't share the existing scale, * and mixes can be added after subsequent scaling, so we're constrained to use the mix-amps */ static mus_float_t previous_mix(snd_fd *sf) { if (sf->loc < sf->first) return(previous_sound(sf)); return((sf->data[sf->loc--] * sf->fscaler) + read_mix_list_samples(sf)); } static mus_float_t next_mix_zero(snd_fd *sf) { if (sf->loc > sf->last) return(next_sound(sf)); /* next_sound here refers to whatever follows the mixed portion */ sf->loc++; return(read_mix_list_samples(sf)); } static mus_float_t previous_mix_zero(snd_fd *sf) { if (sf->loc < sf->first) return(previous_sound(sf)); sf->loc--; return(read_mix_list_samples(sf)); } static mus_float_t next_one_mix(snd_fd *sf) { if (sf->loc > sf->last) return(next_sound(sf)); /* next_sound here refers to whatever follows the mixed portion */ return((sf->data[sf->loc++] * sf->fscaler) + read_sample(((reader_mixes *)(sf->mixes))->sfs[0])); } static mus_float_t previous_one_mix(snd_fd *sf) { if (sf->loc < sf->first) return(previous_sound(sf)); return((sf->data[sf->loc--] * sf->fscaler) + read_sample(((reader_mixes *)(sf->mixes))->sfs[0])); } static mus_float_t next_one_mix_zero(snd_fd *sf) { if (sf->loc > sf->last) return(next_sound(sf)); /* next_sound here refers to whatever follows the mixed portion */ sf->loc++; return(read_sample(((reader_mixes *)(sf->mixes))->sfs[0])); } static mus_float_t previous_one_mix_zero(snd_fd *sf) { if (sf->loc < sf->first) return(previous_sound(sf)); sf->loc--; return(read_sample(((reader_mixes *)(sf->mixes))->sfs[0])); } static mus_float_t next_mix_ramp1(snd_fd *sf) { if (sf->loc > sf->last) return(next_sound(sf)); return((sf->data[sf->loc++] * next_ramp1_value(sf)) + read_mix_list_samples(sf)); } static mus_float_t previous_mix_ramp1(snd_fd *sf) { if (sf->loc < sf->first) return(previous_sound(sf)); return((sf->data[sf->loc--] * previous_ramp1_value(sf)) + read_mix_list_samples(sf)); } static mus_float_t next_mix_ramp2(snd_fd *sf) { if (sf->loc > sf->last) return(next_sound(sf)); return((sf->data[sf->loc++] * next_ramp2_value(sf)) + read_mix_list_samples(sf)); } static mus_float_t previous_mix_ramp2(snd_fd *sf) { if (sf->loc < sf->first) return(previous_sound(sf)); return((sf->data[sf->loc--] * previous_ramp2_value(sf)) + read_mix_list_samples(sf)); } static mus_float_t next_mix_ramp(snd_fd *sf) { if (sf->loc > sf->last) return(next_sound(sf)); return((sf->data[sf->loc++] * next_ramp_value(sf)) + read_mix_list_samples(sf)); } static mus_float_t previous_mix_ramp(snd_fd *sf) { if (sf->loc < sf->first) return(previous_sound(sf)); return((sf->data[sf->loc--] * previous_ramp_value(sf)) + read_mix_list_samples(sf)); } static mus_float_t next_mix_xramp1(snd_fd *sf) { if (sf->loc > sf->last) return(next_sound(sf)); return((sf->data[sf->loc++] * READER_SCALER(sf) * next_xramp1_value(sf)) + read_mix_list_samples(sf)); } static mus_float_t previous_mix_xramp1(snd_fd *sf) { if (sf->loc < sf->first) return(previous_sound(sf)); return((sf->data[sf->loc--] * READER_SCALER(sf) * previous_xramp1_value(sf)) + read_mix_list_samples(sf)); } static mus_float_t next_mix_xramp(snd_fd *sf) { if (sf->loc > sf->last) return(next_sound(sf)); return((sf->data[sf->loc++] * READER_SCALER(sf) * next_xramp_value(sf)) + read_mix_list_samples(sf)); } static mus_float_t previous_mix_xramp(snd_fd *sf) { if (sf->loc < sf->first) return(previous_sound(sf)); return((sf->data[sf->loc--] * READER_SCALER(sf) * previous_xramp_value(sf)) + read_mix_list_samples(sf)); } static mus_float_t next_mix_xramp_f_ramp_f(snd_fd *sf) { if (sf->loc > sf->last) return(next_sound(sf)); return((sf->data[sf->loc++] * (*(READER_RAMPF(sf)))(sf)) + read_mix_list_samples(sf)); } static mus_float_t previous_mix_xramp_f_ramp_f(snd_fd *sf) { if (sf->loc < sf->first) return(previous_sound(sf)); return((sf->data[sf->loc--] * (*(READER_REV_RAMPF(sf)))(sf)) + read_mix_list_samples(sf)); } /* this is a kind of state machine for the virtual editor: if, for example, the current op is ed_ramp and we want to add an xramp, we look at the add_xramp field of ed_ramp's type_info struct, and if it's not -1, the add_xramp field is the new virtual editor op; otherwise the op is collapsed to a change edit. So, to add a new entry, make the accessor, and fill in the fields that can reach it. Since, for example, ramp->xramp is flipped to xramp->ramp since a(b()) == b(a()) in this case, there can be several ways to reach a given op. Then fix the ramp segments in choose_accessor. The first struct field is redundant, but makes editing this table much easier. */ enum {ED_SIMPLE, ED_MIX, ED_ZERO, ED_MIX_ZERO, /* simple envelope special cases */ ED_RAMP1, ED_MIX_RAMP1, ED_RAMP2, ED_MIX_RAMP2, ED_XRAMP1, ED_MIX_XRAMP1, /* envelopes */ ED_RAMP, ED_MIX_RAMP, ED_XRAMP, ED_MIX_XRAMP, ED_XRAMP_RAMP, ED_MIX_XRAMP_RAMP, NUM_OPS }; typedef struct { int type, add_ramp, add_xramp, add_mix, subtract_mix; bool ramps, zero, mixes; /* zero = no underlying data (mix, etc), mixes = involves virtual mixes in some way */ int scale_op; const char *name; mus_float_t (*next)(struct snd_fd *sf); mus_float_t (*previous)(struct snd_fd *sf); mus_float_t (*rampf)(struct snd_fd *sf); mus_float_t (*rev_rampf)(struct snd_fd *sf); } fragment_type_info; enum {NO_SCALE, SIMPLE_SCALE, SCALE_R, SCALE_X}; #define NO_RAMP false #define NO_MIX false #define ON_ZERO true #define ON_DATA false #define MIXED true #define RAMPED true static fragment_type_info type_info[NUM_OPS] = { {ED_SIMPLE, ED_RAMP1, ED_XRAMP1, ED_MIX, -1, NO_RAMP, ON_DATA, NO_MIX, SIMPLE_SCALE, "ed_simple", next_sample_value, previous_sample_value, NULL, NULL}, {ED_MIX, -1, -1, ED_MIX, ED_SIMPLE, NO_RAMP, ON_DATA, MIXED, NO_SCALE, "ed_mix_simple", next_mix, previous_mix, NULL, NULL}, {ED_ZERO, ED_ZERO, ED_ZERO, ED_MIX_ZERO, -1, NO_RAMP, ON_ZERO, NO_MIX, NO_SCALE, "ed_zero", next_zero, previous_zero, NULL, NULL}, {ED_MIX_ZERO, -1, -1, ED_MIX_ZERO, ED_ZERO, NO_RAMP, ON_ZERO, MIXED, NO_SCALE, "ed_mix_zero", next_mix_zero, previous_mix_zero, NULL, NULL}, {ED_RAMP1, ED_RAMP2, ED_XRAMP_RAMP, ED_MIX_RAMP1, -1, RAMPED, ON_DATA, NO_MIX, SCALE_R, "ed_ramp1", next_ramp1, previous_ramp1, NULL, NULL}, {ED_MIX_RAMP1, -1, -1, ED_MIX_RAMP1, ED_RAMP1, RAMPED, ON_DATA, MIXED, SCALE_R, "ed_mix_ramp1", next_mix_ramp1, previous_mix_ramp1, NULL, NULL}, {ED_RAMP2, ED_RAMP, ED_XRAMP_RAMP, ED_MIX_RAMP2, -1, RAMPED, ON_DATA, NO_MIX, SCALE_R, "ed_ramp2", next_ramp_f, previous_ramp_f, next_ramp2_value, previous_ramp2_value}, {ED_MIX_RAMP2, -1, -1, ED_MIX_RAMP2, ED_RAMP2, RAMPED, ON_DATA, MIXED, SCALE_R, "ed_mix_ramp2", next_mix_ramp2, previous_mix_ramp2, NULL, NULL}, {ED_XRAMP1, ED_XRAMP_RAMP, ED_XRAMP, ED_MIX_XRAMP1, -1, RAMPED, ON_DATA, NO_MIX, NO_SCALE, "ed_xramp1", next_xramp1, previous_xramp1, NULL, NULL}, {ED_MIX_XRAMP1, -1, -1, ED_MIX_XRAMP1, ED_XRAMP1, RAMPED, ON_DATA, MIXED, NO_SCALE, "ed_mix_xramp1", next_mix_xramp1, previous_mix_xramp1, NULL, NULL}, {ED_RAMP, ED_RAMP, ED_XRAMP_RAMP, ED_MIX_RAMP, -1, RAMPED, ON_DATA, NO_MIX, SCALE_R, "ed_ramp", next_ramp, previous_ramp, NULL, NULL}, {ED_MIX_RAMP, -1, -1, ED_MIX_RAMP, ED_RAMP, RAMPED, ON_DATA, MIXED, SCALE_R, "ed_mix_ramp", next_mix_ramp, previous_mix_ramp, NULL, NULL}, {ED_XRAMP, ED_XRAMP_RAMP, ED_XRAMP, ED_MIX_XRAMP, -1, RAMPED, ON_DATA, NO_MIX, NO_SCALE, "ed_xramp", next_xramp, previous_xramp, NULL, NULL}, {ED_MIX_XRAMP, -1, -1, ED_MIX_XRAMP, ED_XRAMP, RAMPED, ON_DATA, MIXED, NO_SCALE, "ed_mix_xramp", next_mix_xramp, previous_mix_xramp, NULL, NULL}, {ED_XRAMP_RAMP, ED_XRAMP_RAMP, ED_XRAMP_RAMP, ED_MIX_XRAMP_RAMP, -1, RAMPED, ON_DATA, NO_MIX, SCALE_R, "ed_xramp_ramp", next_ramp_f, previous_ramp_f, next_xramp_ramp_value, previous_xramp_ramp_value}, {ED_MIX_XRAMP_RAMP, -1, -1, ED_MIX_XRAMP_RAMP, ED_XRAMP_RAMP, RAMPED, ON_DATA, MIXED, SCALE_R, "ed_mix_xramp_ramp", next_mix_xramp_f_ramp_f, previous_mix_xramp_f_ramp_f, next_xramp_ramp_value, previous_xramp_ramp_value}, }; static bool zero_op(int type) { return(type_info[type].zero); } static bool ramp_op(int type) { return(type_info[type].ramps); } static bool is_mix_op(int type) { return(type_info[type].mixes); } static bool is_unmixable_op(int type) { return(type_info[type].subtract_mix != -1); } static bool is_mixable_op(int type) { return(type_info[type].add_mix != -1); } #define DEBUG_EDIT_TABLES 0 #if DEBUG_EDIT_TABLES static int hit_entry[NUM_OPS]; static void init_hit_entries(void) { int i; for (i = 0; i < NUM_OPS; i++) hit_entry[i] = 0; } static void report_unhit_entries(void) { int i; for (i = 0; i < NUM_OPS; i++) if (hit_entry[i] == 0) { if (type_info[i].next) fprintf(stderr, "accessible "); fprintf(stderr, "%s unhit\n", type_info[i].name); } } static void check_type_info_entry(int op, int expected_ramps, int expected_xramps, bool is_zero) { hit_entry[op]++; if (op != type_info[op].type) fprintf(stderr, "%s type: %d %d\n", type_info[op].name, op, type_info[op].type); if (op != ED_SIMPLE) { if (type_info[op].next == NULL) fprintf(stderr, "%s no next\n", type_info[op].name); if (type_info[op].previous == NULL) fprintf(stderr, "%s no previous\n", type_info[op].name); } if (is_zero != type_info[op].zero) fprintf(stderr, "%s zero: %d %d\n", type_info[op].name, is_zero, type_info[op].zero); if ((type_info[op].add_ramp != -1) && (type_info[op].add_ramp != op)) check_type_info_entry(type_info[op].add_ramp, expected_ramps + 1, expected_xramps, is_zero); if ((type_info[op].add_xramp != -1) && (type_info[op].add_xramp != op)) check_type_info_entry(type_info[op].add_xramp, expected_ramps, expected_xramps + 1, is_zero); if ((type_info[op].add_mix != -1) && (type_info[op].subtract_mix == -1)) /* not a loop! */ check_type_info_entry(type_info[op].add_mix, expected_ramps, expected_xramps, is_zero); if ((!(type_info[op].mixes)) && (type_info[op].subtract_mix != -1)) fprintf(stderr, "%s: mix confused (#f)?\n", type_info[op].name); if (type_info[op].subtract_mix != -1) { if ((type_info[op].add_mix != -1) && (type_info[op].add_mix != op)) fprintf(stderr, "%s add_mix: %s\n", type_info[op].name, type_info[type_info[op].add_mix].name); if ((type_info[op].add_ramp != -1) && (op != ED_MIX_ZERO)) fprintf(stderr, "%s add_ramp: %s\n", type_info[op].name, type_info[type_info[op].add_ramp].name); if (type_info[op].add_xramp != -1) fprintf(stderr, "%s add_xramp: %s\n", type_info[op].name, type_info[type_info[op].add_xramp].name); if (type_info[type_info[op].subtract_mix].add_mix != op) fprintf(stderr, "%s subtract: %s but its add: %s\n", type_info[op].name, type_info[type_info[op].subtract_mix].name, (type_info[type_info[op].subtract_mix].add_mix != -1) ? type_info[type_info[type_info[op].subtract_mix].add_mix].name : "not an op"); } } #endif static void swap_readers(snd_fd *sf) { mus_float_t (*rrunf)(struct snd_fd *sf); rrunf = sf->runf; sf->runf = sf->rev_runf; sf->rev_runf = rrunf; } void read_sample_change_direction(snd_fd *sf, read_direction_t dir1) /* can't use "dir" on Mac */ { /* direction reversal can happen in dac(speed arrow), src gen, or user can call next/previous independent of initial dir */ swap_readers(sf); sf->direction = dir1; /* can't optimize anything here -- some accessors have state, but how to handle the loc=-1 case? */ if ((dir1 == READ_FORWARD) && (sf->loc < 0)) sf->loc = 0; else read_sample(sf); } static mus_float_t protected_next_sample(snd_fd *sf) { if (sf->direction == READ_BACKWARD) read_sample_change_direction(sf, READ_FORWARD); return(read_sample(sf)); } static mus_float_t protected_previous_sample(snd_fd *sf) { if (sf->direction == READ_FORWARD) read_sample_change_direction(sf, READ_BACKWARD); return(read_sample(sf)); } /* setting the at_end flag here means that a 0.0 is returned from read-sample and then * the caller has to check at-end to see if that 0.0 is real. Not sure how (or whether) * this should be fixed. */ static void reader_out_of_data(snd_fd *sf) { sf->at_eof = true; sf->runf = end_sample_value; sf->rev_runf = end_sample_value; } static snd_fd *cancel_reader(snd_fd *sf) { sf->current_sound = NULL; sf->cbi = 0; reader_out_of_data(sf); return(sf); } static reader_mixes *free_reader_mixes(reader_mixes *md); static void setup_mix(snd_fd *sf) { reader_mixes *md; int i, list_size, active_mixes = 0; if (sf->mixes) sf->mixes = (void *)free_reader_mixes((reader_mixes *)(sf->mixes)); md = (reader_mixes *)calloc(1, sizeof(reader_mixes)); sf->mixes = (void *)md; list_size = READER_MIX_LIST_SIZE(sf); for (i = 0; i < list_size; i++) if ((READER_MIX_STATE(sf, i)) && (READER_MIX_SCALER(sf, i) != 0.0)) active_mixes++; md->size = active_mixes; if (md->size > 0) { int j = 0; md->sfs = (snd_fd **)calloc(md->size, sizeof(snd_fd *)); for (i = 0; i < list_size; i++) if ((READER_MIX_STATE(sf, i)) && (READER_MIX_SCALER(sf, i) != 0.0)) md->sfs[j++] = make_virtual_mix_reader(sf->cp, sf->frag_pos + READER_GLOBAL_POSITION(sf) - READER_MIX_BEG(sf, i), /* global position - mix position + fragment start loc */ READER_MIX_LENGTH(sf, i), READER_MIX_INDEX(sf, i), READER_MIX_SCALER(sf, i), sf->direction); if (active_mixes == 1) { if (READER_TYPE(sf) == ED_MIX) { sf->runf = next_one_mix; sf->rev_runf = previous_one_mix; } else { if (READER_TYPE(sf) == ED_MIX_ZERO) { sf->runf = next_one_mix_zero; sf->rev_runf = previous_one_mix_zero; } } } } } static void setup_ramps(snd_fd *sf, int typ) { int rmps, xrmps; ed_fragment *ed; ed = (ed_fragment *)(sf->cb); rmps = ED_RAMP_LIST_SIZE(ed); xrmps = ED_XRAMP_LIST_SIZE(ed); if (sf->ramps == NULL) sf->ramps = (void *)calloc(1, sizeof(reader_ramps)); /* make sure the ramp arrays are large enough (we'll free them at the end of the read) */ if (rmps != READER_RAMPS(sf)) { if (READER_RAMPS(sf) > 0) { free(READER_INCRS(sf)); READER_INCRS(sf) = NULL; free(READER_VALS(sf)); READER_VALS(sf) = NULL; } if (rmps > 0) { READER_INCRS(sf) = (double *)calloc(rmps, sizeof(double)); READER_VALS(sf) = (double *)calloc(rmps, sizeof(double)); } READER_RAMPS(sf) = rmps; /* this has to match the actual ramp number */ } if (xrmps != READER_XRAMPS(sf)) { if (READER_XRAMPS(sf) > 0) { free(READER_XINCRS(sf)); READER_XINCRS(sf) = NULL; free(READER_XVALS(sf)); READER_XVALS(sf) = NULL; } if (xrmps > 0) { READER_XINCRS(sf) = (double *)calloc(xrmps, sizeof(double)); READER_XVALS(sf) = (double *)calloc(xrmps, sizeof(double)); } READER_XRAMPS(sf) = xrmps; } if (rmps > 0) { int i; for (i = 0; i < rmps; i++) { READER_INCR(sf, i) = READER_RAMP_INCR(sf, i); READER_VAL(sf, i) = READER_RAMP_START(sf, i) + READER_INCR(sf, i) * sf->frag_pos; } } if (xrmps > 0) { int i; for (i = 0; i < xrmps; i++) { READER_XINCR(sf, i) = READER_XRAMP_INCR(sf, i); READER_XVAL(sf, i) = READER_XRAMP_START(sf, i) * exp(log(READER_XRAMP_INCR(sf, i)) * sf->frag_pos); } } READER_RAMPF(sf) = type_info[typ].rampf; READER_REV_RAMPF(sf) = type_info[typ].rev_rampf; } static void scale_ramp(snd_fd *sf, int rmp, mus_float_t scl) { READER_INCR(sf, rmp) *= scl; READER_VAL(sf, rmp) *= scl; } static void scale_inputs(snd_fd *sf, int scl_type) { switch (scl_type) { case NO_SCALE: break; case SIMPLE_SCALE: /* ED_SIMPLE special case */ if ((READER_SCALER(sf) == 1.0) && (sf->fscaler == 1.0)) { sf->runf = next_sample_value_unscaled; sf->rev_runf = previous_sample_value_unscaled; } break; case SCALE_R: scale_ramp(sf, 0, READER_SCALER(sf)); break; } } static void choose_accessor(snd_fd *sf) { int typ; /* fragment-specific reader choice */ typ = READER_TYPE(sf); if (ramp_op(typ)) setup_ramps(sf, typ); if (is_mix_op(typ)) setup_mix(sf); sf->runf = type_info[typ].next; sf->rev_runf = type_info[typ].previous; scale_inputs(sf, type_info[typ].scale_op); if (sf->direction == READ_BACKWARD) swap_readers(sf); } static const char *edit_names[NUM_EDIT_TYPES] = {"insert", "delete", "set", "init", "scale", "zero", "env", "extend", "mix", "change mix"}; static void display_ed_list(chan_info *cp, FILE *outp, int i, ed_list *ed) { int len, j; snd_data *sd; if (ed == NULL) { fprintf(outp, "\n (NULL FRAGMENT at %d)", i); return; } if (i >= cp->edit_size) { fprintf(outp, "\n (BOGUS FRAGMENT at %d of %d)", i, cp->edit_size); return; } len = ed->size; /* number of fragments in this list */ switch (ed->edit_type) { case INSERTION_EDIT: fprintf(outp, "\n (insert %lld %lld) ", ed->beg, ed->len); break; case DELETION_EDIT: fprintf(outp, "\n (delete %lld %lld) ", ed->beg, ed->len); break; case CHANGE_EDIT: fprintf(outp, "\n (set %lld %lld) ", ed->beg, ed->len); break; case SCALED_EDIT: fprintf(outp, "\n (scale %lld %lld) ", ed->beg, ed->len); break; case ZERO_EDIT: fprintf(outp, "\n (silence %lld %lld) ", ed->beg, ed->len); break; case RAMP_EDIT: fprintf(outp, "\n (ramp %lld %lld) ", ed->beg, ed->len); break; case EXTEND_EDIT: fprintf(outp, "\n (extend edit list with no-op)"); break; case MIX_EDIT: fprintf(outp, "\n (mix %lld %lld) ", ed->beg, ed->len); break; case CHANGE_MIX_EDIT: fprintf(outp, "\n (change mix %lld %lld) ", ed->beg, ed->len); break; case INITIALIZE_EDIT: fprintf(outp, "\n (begin) "); break; default: break; } if (ed->origin) fprintf(outp, "; %s ", ed->origin); fprintf(outp, "[%d:%d]:", i, len); for (j = 0; j < len; j++) { int index; index = FRAGMENT_SOUND(ed, j); if (index == EDIT_LIST_END_MARK) fprintf(outp, "\n (at %lld, end_mark)", FRAGMENT_GLOBAL_POSITION(ed, j)); else { int typ; typ = FRAGMENT_TYPE(ed, j); fprintf(outp, "\n (at %lld, cp->sounds[%d][%lld:%lld, %.3f", FRAGMENT_GLOBAL_POSITION(ed, j), index, FRAGMENT_LOCAL_POSITION(ed, j), FRAGMENT_LOCAL_END(ed, j), FRAGMENT_SCALER(ed, j)); if (ramp_op(typ)) { int k; for (k = 0; k < FRAGMENT_RAMP_LIST_SIZE(ed, j); k++) /* step envs become successive scalings */ fprintf(outp, ", [%d]%.3f -> %.3f", k + 1, FRAGMENT_RAMP_START(ed, j, k), FRAGMENT_RAMP_START(ed, j, k) + (FRAGMENT_LENGTH(ed, j) - 1) * FRAGMENT_RAMP_INCR(ed, j, k)); for (k = 0; k < FRAGMENT_XRAMP_LIST_SIZE(ed, j); k++) { double y; y = FRAGMENT_XRAMP_SCALER(ed, j, k) * FRAGMENT_XRAMP_START(ed, j, k); fprintf(outp, ", [%d]%.3f -> %.3f, off: %.3f, scl: %.3f", k + 1 + FRAGMENT_RAMP_LIST_SIZE(ed, j), FRAGMENT_XRAMP_OFFSET(ed, j, k) + y, FRAGMENT_XRAMP_OFFSET(ed, j, k) + y * exp(log(FRAGMENT_XRAMP_INCR(ed, j, k)) * (FRAGMENT_LENGTH(ed, j) - 1)), FRAGMENT_XRAMP_OFFSET(ed, j, k), FRAGMENT_XRAMP_SCALER(ed, j, k)); } } if (is_mix_op(typ)) { ed_mixes *mxs; mxs = FRAGMENT_MIXES(ed, j); if (!mxs) fprintf(outp, ", %s but no mixes found?", type_info[typ].name); else { int i; for (i = 0; i < mxs->size; i++) { if (MIX_LIST_STATE(mxs, i)) fprintf(outp, ", ([%d]: %d %.3f %lld)", i, MIX_LIST_INDEX(mxs, i), MIX_LIST_SCALER(mxs, i), FRAGMENT_GLOBAL_POSITION(ed, j) - MIX_LIST_BEG(mxs, i)); } } } fprintf(outp, "])"); if (index != EDIT_LIST_ZERO_MARK) { sd = cp->sounds[index]; if (sd == NULL) fprintf(outp, " [nil!]"); else if (sd->type == SND_DATA_FILE) fprintf(outp, " [file: %s[%d]]", sd->filename, sd->chan); else if (sd->type == SND_DATA_BUFFER) fprintf(outp, " [buf: %lld] ", sd->data_bytes / sizeof(mus_float_t)); else fprintf(outp, " [bogus!]"); } } } fprintf(outp, "\n"); } mus_long_t edit_changes_begin_at(chan_info *cp, int edpos) { return(cp->edits[edpos]->beg); } mus_long_t edit_changes_end_at(chan_info *cp, int edpos) { /* the env code assumes a deletion passes in the number deleted so that the copy knows where to start in the old env */ return(cp->edits[edpos]->beg + cp->edits[edpos]->len); } /* ---------------- edit list display, save, etc ---------------- */ char *edit_to_string(chan_info *cp, int edit) { ed_list *ed; ed = cp->edits[edit]; /* only for edit list in snd-g|xchn.c */ #if HAVE_FORTH return(mus_format("%s : %lld %lld %s", ed->origin, ed->beg, ed->len, edit_names[(int)(ed->edit_type)])); #endif #if HAVE_RUBY return(mus_format("%s : %s(%lld, %lld)", ed->origin, edit_names[(int)(ed->edit_type)], ed->beg, ed->len)); #endif #if HAVE_SCHEME return(mus_format("%s : (%s %lld %lld)", ed->origin, edit_names[(int)(ed->edit_type)], ed->beg, ed->len)); #endif return(NULL); } static void display_edits(chan_info *cp, FILE *outp) { int i; fprintf(outp, "\nEDITS: %d\n", cp->edit_ctr); for (i = 0; i <= cp->edit_ctr; i++) display_ed_list(cp, outp, i, cp->edits[i]); } static io_error_t snd_make_file(const char *ofile, int chans, file_info *hdr, snd_fd **sfs, mus_long_t length, bool report_ok) { /* create ofile, fill it by following sfs, use hdr for srate/type/format decisions */ int ofd; int i, j, datumb; bool reporting = false; mus_long_t len = 0, total = 0, alloc_len; chan_info *cp = NULL; mus_float_t **obufs; io_error_t io_err = IO_NO_ERROR; int sl_err = MUS_NO_ERROR; bool need_clipping; ofd = open_temp_file(ofile, chans, hdr, &io_err); if (ofd == -1) return(io_err); alloc_len = length; if (alloc_len > REPORTING_SIZE) alloc_len = REPORTING_SIZE; need_clipping = clipping(ss); if (need_clipping) { bool max_ok = false; mus_float_t mx = 0.0; for (i = 0; i < chans; i++) { mus_float_t cur_mx; chan_info *ncp; int edpos; ncp = sfs[i]->cp; edpos = sfs[i]->edit_ctr; if (peak_env_maxamp_ok(ncp, edpos)) cur_mx = peak_env_maxamp(ncp, edpos); else { cur_mx = ed_maxamp(ncp, edpos); if (cur_mx < 0.0) break; } if (cur_mx > mx) mx = cur_mx; if (i == (chans - 1)) max_ok = true; } if ((max_ok) && (mx <= 1.0)) need_clipping = false; } mus_file_set_clipping(ofd, need_clipping); /* clipping is very expensive, so try to avoid it */ datumb = mus_bytes_per_sample(hdr->sample_type); ss->stopped_explicitly = false; obufs = (mus_float_t **)malloc(chans * sizeof(mus_float_t *)); for (i = 0; i < chans; i++) obufs[i] = (mus_float_t *)calloc(alloc_len, sizeof(mus_float_t)); j = 0; reporting = ((report_ok) && (length > alloc_len)); if (reporting) { cp = sfs[0]->cp; start_progress_report(cp); } if (chans == 1) { mus_float_t *buf; snd_fd *sf; buf = obufs[0]; sf = sfs[0]; if (length > alloc_len) { sampler_set_safe(sf, length); for (len = 0; len < length; ) { int k, kdur; kdur = length - len; if (kdur > alloc_len) kdur = alloc_len; for (k = 0; k < kdur; k++) buf[k] = read_sample(sf); sl_err = mus_file_write(ofd, 0, kdur - 1, 1, obufs); j = 0; if (sl_err != MUS_NO_ERROR) break; if (reporting) { total += kdur; progress_report(cp, (mus_float_t)((double)total / (double)length)); } len += kdur; } } else { samples_to_vct_with_reader(length, buf, sf); len = length; j = (int)length; } } else { if (length > alloc_len) { mus_float_t *buf; snd_fd *sf; for (i = 0; i < chans; i++) sampler_set_safe(sfs[i], length); for (len = 0; len < length;) { int k, kdur; kdur = length - len; if (kdur > alloc_len) kdur = alloc_len; for (i = 0; i < chans; i++) { buf = obufs[i]; sf = sfs[i]; for (k = 0; k < kdur; k++) buf[k] = read_sample(sf); } sl_err = mus_file_write(ofd, 0, kdur - 1, chans, obufs); j = 0; if (sl_err != MUS_NO_ERROR) break; if (reporting) { total += kdur; progress_report(cp, (mus_float_t)((double)total / (double)length)); } len += kdur; } } else { for (i = 0; i < chans; i++) samples_to_vct_with_reader(length, obufs[i], sfs[i]); len = length; j = (int)length; } } if ((sl_err == MUS_NO_ERROR) && (j > 0)) sl_err = mus_file_write(ofd, 0, j - 1, chans, obufs); if (sl_err == MUS_NO_ERROR) { io_err = close_temp_file(ofile, ofd, hdr->type, len * chans * datumb); #if USE_MOTIF if (!(ss->file_monitor_ok)) alert_new_file(); #endif } else { mus_file_close(ofd); io_err = sndlib_error_to_snd(sl_err); } if (reporting) finish_progress_report(cp); for (i = 0; i < chans; i++) free(obufs[i]); free(obufs); return(io_err); } static io_error_t channel_to_file_with_bounds(chan_info *cp, const char *ofile, int edpos, mus_long_t beg, mus_long_t len, file_info *hdr, bool report_ok) { snd_info *sp; snd_fd **sf; io_error_t err = IO_NO_ERROR; sp = cp->sound; sf = (snd_fd **)malloc(sizeof(snd_fd *)); sf[0] = init_sample_read_any_with_bufsize(beg, cp, READ_FORWARD, edpos, len); if (sf[0] == NULL) { free(sf); snd_error("no such edit: %s[%d]: %d (this channel has %d edit%s", sp->short_filename, cp->chan, edpos, cp->edit_ctr, (cp->edit_ctr == 1) ? "" : "s"); } else { err = snd_make_file(ofile, 1, hdr, sf, len, report_ok); free_snd_fd(sf[0]); free(sf); if ((err != IO_NO_ERROR) && (err != IO_INTERRUPTED)) snd_error("can't save %s chan %d: %s %s", sp->short_filename, cp->chan, ofile, snd_io_strerror()); } return(err); } static io_error_t channel_to_file(chan_info *cp, const char *ofile, int edpos) /* preserves cp->sound's header settings */ { return(channel_to_file_with_bounds(cp, ofile, edpos, 0, cp->edits[edpos]->samples, cp->sound->hdr, true)); } io_error_t channel_to_file_with_settings(chan_info *cp, const char *new_name, int srate, mus_sample_t samp_type, mus_header_t hd_type, const char *comment, int pos) { file_info *hdr, *ohdr; snd_info *sp; io_error_t err = IO_NO_ERROR; sp = cp->sound; ohdr = sp->hdr; hdr = copy_header(new_name, ohdr); hdr->sample_type = samp_type; hdr->srate = srate; hdr->type = hd_type; if (comment) hdr->comment = mus_strdup(comment); else hdr->comment = NULL; hdr->data_location = 0; /* in case comment changes it */ if (pos == AT_CURRENT_EDIT_POSITION) pos = cp->edit_ctr; if ((mus_strcmp(new_name, sp->filename)) && /* overwriting current file with one of its channels */ ((sp->user_read_only == FILE_READ_ONLY) || (sp->file_read_only == FILE_READ_ONLY))) { snd_error("can't save channel %d as %s (%s is write-protected)", cp->chan, new_name, sp->short_filename); return(IO_WRITE_PROTECTED); } err = channel_to_file_with_bounds(cp, new_name, pos, 0, cp->edits[pos]->samples, hdr, true); free_file_info(hdr); return(err); } /* these are used internally by the save-state process */ #define S_change_samples_with_origin "change-samples-with-origin" #define S_insert_samples_with_origin "insert-samples-with-origin" #define S_override_samples_with_origin "override-samples-with-origin" static void fprintf_with_possible_embedded_string(FILE *fd, const char *str) { int i, len; len = mus_strlen(str); fputc('"', fd); for (i = 0; i < len; i++) { if (str[i] == '"') fputc('\\', fd); fputc(str[i], fd); } fputc('"', fd); } static char *edit_list_data_to_temp_file(chan_info *cp, ed_list *ed, file_delete_t delete_me, bool with_save_state_hook) { snd_data *sd; char *ofile; if (with_save_state_hook) { char *nfile; nfile = shorter_tempnam(save_dir(ss), "snd_"); ofile = run_save_state_hook(nfile); free(nfile); } else ofile = shorter_tempnam(save_dir(ss), "snd_"); sd = cp->sounds[ed->sound_location]; if (sd->type == SND_DATA_BUFFER) mus_array_to_file(ofile, sd->buffered_data, ed->len, DEFAULT_OUTPUT_SRATE, 1); else { io_error_t io_err; io_err = copy_file(sd->filename, ofile); if (io_err != IO_NO_ERROR) { if (io_err == IO_CANT_OPEN_FILE) snd_warning("%s edit list original temp file %s: %s", io_error_name(io_err), sd->filename, snd_io_strerror()); else snd_warning("%s edit list saved temp file %s: %s", io_error_name(io_err), ofile, snd_io_strerror()); } } if (delete_me == DELETE_ME) remember_temp(ofile, 1); /* deletion upon exit (forget_temps) if a temp (edit-list->function, but not save-state) */ return(ofile); } #if HAVE_FORTH /* * ret_name: last word in origin (function name) * func: rest-origin (must be freed) */ static char *split_origin(char *origin, char **ret_name) { if (origin && *origin) { char *func = (char *)calloc(strlen(origin), sizeof(char)); if ((*ret_name = strrchr(origin, ' '))) { (*ret_name)++; strncpy(func, origin, strlen(origin) - strlen(*ret_name) - 1); } else *ret_name = origin; return(func); } return NULL; } #endif void edit_history_to_file(FILE *fd, chan_info *cp, bool with_save_state_hook) { /* write edit list as a scheme|ruby|forth program to fd (open for writing) for subsequent load */ /* the entire current list is written, then the edit_ctr is fixed up to reflect its current state */ int i, edits; #if HAVE_FORTH char *forth_func = NULL; bool mix_ed = false; #endif edits = cp->edit_ctr; while ((edits < (cp->edit_size - 1)) && (cp->edits[edits + 1])) edits++; /* 0 case = open-sound */ for (i = 1; i <= edits; i++) { ed_list *ed; ed = cp->edits[i]; if (ed) { if (ed->backed_up) { /* as-one-edit (and internally backup_edit_list) remove edit history entries, * making it impossible to reconstruct exactly the edit sequence in save/restore. * The backed_up flag is set in the backed-up entry, and for save/restore, we * override the entire current sound with a saved file. */ char *nfile = NULL; mus_long_t len; io_error_t io_err; if (with_save_state_hook) { char *ofile; ofile = shorter_tempnam(save_dir(ss), "snd_"); nfile = run_save_state_hook(ofile); free(ofile); } else nfile = shorter_tempnam(save_dir(ss), "snd_"); len = cp->edits[i]->samples; io_err = channel_to_file(cp, nfile, i); if (io_err != IO_NO_ERROR) { /* error is trapped at lower level and pulled up via redirection */ free(nfile); return; } #if HAVE_RUBY fprintf(fd, " %s(\"%s\", %lld, sfile, %d, ", to_proc_name(S_override_samples_with_origin), nfile, len, cp->chan); if (ed->origin) fprintf_with_possible_embedded_string(fd, ed->origin); else fprintf(fd, "\"\""); fprintf(fd, ", [%d, %lld])\n", (int)mus_sound_write_date(nfile), mus_sound_length(nfile)); #endif #if HAVE_SCHEME fprintf(fd, " (%s \"%s\" %lld sfile %d ", S_override_samples_with_origin, nfile, len, cp->chan); if (ed->origin) fprintf_with_possible_embedded_string(fd, ed->origin); else fprintf(fd, "\"\""); fprintf(fd, " (list %d %lld))\n", (int)mus_sound_write_date(nfile), mus_sound_length(nfile)); #endif #if HAVE_FORTH fprintf(fd, " \"%s\" %lld sfile %d ", nfile, len, cp->chan); if (ed->origin) fprintf_with_possible_embedded_string(fd, ed->origin); else fprintf(fd, "\"\""); fprintf(fd, " '( %d %lld ) %s drop\n", (int)mus_sound_write_date(nfile), mus_sound_length(nfile), S_override_samples_with_origin); #endif free(nfile); } else { char *nfile = NULL; #if HAVE_RUBY || HAVE_FORTH fprintf(fd, " "); #endif #if HAVE_SCHEME fprintf(fd, " ("); #endif #if HAVE_FORTH switch (ed->edit_type) { case INSERTION_EDIT: /* samp data snd chn */ forth_func = S_insert_samples_with_origin; fprintf(fd, "%lld %lld ", ed->beg, ed->len); if (ed->origin) fprintf_with_possible_embedded_string(fd, ed->origin); else fprintf(fd, "\"%s\"", S_insert_samples); nfile = edit_list_data_to_temp_file(cp, ed, DONT_DELETE_ME, with_save_state_hook); fprintf(fd, " \"%s\" sfile %d", nfile, cp->chan); break; case DELETION_EDIT: /* samp samps snd chn */ forth_func = S_delete_samples; fprintf(fd, "%lld %lld sfile %d", ed->beg, ed->len, cp->chan); break; case CHANGE_EDIT: forth_func = S_change_samples_with_origin; fprintf(fd, "%lld %lld ", ed->beg, ed->len); if (ed->origin) fprintf_with_possible_embedded_string(fd, ed->origin); else fprintf(fd, "\"\""); nfile = edit_list_data_to_temp_file(cp, ed, DONT_DELETE_ME, with_save_state_hook); fprintf(fd, " \"%s\" sfile %d", nfile, cp->chan); break; case EXTEND_EDIT: /* not currently savable (this is a dummy edit fragment for zero-mix-drag position change) */ break; case ZERO_EDIT: forth_func = S_pad_channel; fprintf(fd, "%lld %lld sfile %d", ed->beg, ed->len, cp->chan); break; case SCALED_EDIT: case RAMP_EDIT: { char *func; if ((func = split_origin(ed->origin, &forth_func))) { fprintf(fd, "%s sfile %d", func, cp->chan); free(func); } else fprintf(fd, "sfile %d", cp->chan); } break; case MIX_EDIT: case CHANGE_MIX_EDIT: mix_ed = true; fprintf(fd, "sfile value snd\n"); fprintf(fd, " %d value chn\n", cp->chan); fprintf(fd, " "); forth_func = ed->origin; break; default: snd_error("unknown edit branch: %s: %d %d", ed->origin, ed->edit_type, ed->sound_location); break; } #else switch (ed->edit_type) { case INSERTION_EDIT: /* samp data snd chn */ fprintf(fd, "%s" PROC_OPEN "%lld" PROC_SEP "%lld" PROC_SEP, to_proc_name(S_insert_samples_with_origin), ed->beg, ed->len); if (ed->origin) fprintf_with_possible_embedded_string(fd, ed->origin); else fprintf(fd, "\"%s\"", S_insert_samples); fprintf(fd, PROC_SEP); nfile = edit_list_data_to_temp_file(cp, ed, DONT_DELETE_ME, with_save_state_hook); fprintf(fd, "\"%s\"" PROC_SEP "sfile" PROC_SEP "%d", nfile, cp->chan); break; case DELETION_EDIT: /* samp samps snd chn */ fprintf(fd, "%s" PROC_OPEN "%lld" PROC_SEP "%lld" PROC_SEP "sfile" PROC_SEP "%d", to_proc_name(S_delete_samples), ed->beg, ed->len, cp->chan); break; case CHANGE_EDIT: fprintf(fd, "%s" PROC_OPEN "%lld" PROC_SEP "%lld" PROC_SEP, to_proc_name(S_change_samples_with_origin), ed->beg, ed->len); if (ed->origin) fprintf_with_possible_embedded_string(fd, ed->origin); else fprintf(fd, "\"\""); fprintf(fd, PROC_SEP); nfile = edit_list_data_to_temp_file(cp, ed, DONT_DELETE_ME, with_save_state_hook); fprintf(fd, "\"%s\"" PROC_SEP "sfile" PROC_SEP "%d", nfile, cp->chan); break; case EXTEND_EDIT: /* not currently savable (this is a dummy edit fragment for zero-mix-drag position change) */ break; case SCALED_EDIT: fprintf(fd, "%s" PROC_SEP "sfile" PROC_SEP "%d", ed->origin, /* imports scaler */ cp->chan); break; case ZERO_EDIT: fprintf(fd, "%s" PROC_OPEN "%lld" PROC_SEP "%lld" PROC_SEP "sfile" PROC_SEP "%d", to_proc_name(S_pad_channel), ed->beg, ed->len, cp->chan); break; case RAMP_EDIT: fprintf(fd, "%s" PROC_SEP "sfile" PROC_SEP "%d", ed->origin, cp->chan); break; case MIX_EDIT: #if HAVE_SCHEME fprintf(fd, "(lambda (snd chn ignore) %s) sfile %d", ed->origin, cp->chan); #else fprintf(fd, "func = lambda do |snd, chn, ignore|\n %s\n end\n func(sfile, %d", ed->origin, cp->chan); #endif break; case CHANGE_MIX_EDIT: fprintf(fd, "%s", ed->origin); break; default: snd_error("unknown edit branch: %s: %d %d", ed->origin, ed->edit_type, ed->sound_location); break; } #endif if ((ed->edpos != AT_CURRENT_EDIT_POSITION) && (ed->edpos != (i - 1))) fprintf(fd, PROC_SEP " %d", ed->edpos); #if HAVE_RUBY else fprintf(fd, ", false"); #endif #if HAVE_SCHEME else fprintf(fd, " #f"); #endif #if HAVE_FORTH else { if (!mix_ed) fprintf(fd, " #f"); } #endif if (nfile) { #if HAVE_SCHEME fprintf(fd, " (list %d %lld)", (int)mus_sound_write_date(nfile), mus_sound_length(nfile)); #endif #if HAVE_RUBY fprintf(fd, ", [%d, %lld]", (int)mus_sound_write_date(nfile), mus_sound_length(nfile)); #endif #if HAVE_FORTH fprintf(fd, " '( %d %lld )", (int)mus_sound_write_date(nfile), mus_sound_length(nfile)); #endif free(nfile); } #if HAVE_FORTH if (mix_ed) fprintf(fd, " %s\n", forth_func); else fprintf(fd, " %s drop\n", forth_func); #else fprintf(fd, ")\n"); /* works for both Ruby and Scheme */ #endif } } } if (cp->edit_ctr < edits) #if HAVE_RUBY fprintf(fd, " undo(%d, sfile, %d);\n", edits - cp->edit_ctr, cp->chan); #endif #if HAVE_SCHEME fprintf(fd, " (undo %d sfile %d)\n", edits - cp->edit_ctr, cp->chan); #endif #if HAVE_FORTH fprintf(fd, " %d sfile %d undo drop\n", edits - cp->edit_ctr, cp->chan); #endif save_mark_list(fd, cp, false); /* false -> save just the current channel's marks */ } char *edit_list_to_function(chan_info *cp, int start_pos, int end_pos) { #if HAVE_SCHEME char *function = NULL, *old_function = NULL; bool close_mix_let = false; int i, edits; edits = cp->edit_ctr; while ((edits < (cp->edit_size - 1)) && (cp->edits[edits + 1])) edits++; if ((end_pos > 0) && /* end_pos can be -1 = end of edits (?) */ (end_pos < edits)) edits = end_pos; if (start_pos > edits) return(mus_strdup("(lambda (snd chn) #f)")); if (start_pos == 0) start_pos = 1; if (channel_has_mixes(cp)) { char *mix_list; mix_list = edit_list_mix_init(cp); if (mix_list) { close_mix_let = true; function = mus_format("(lambda (snd chn)\n (let (%s)", mix_list); free(mix_list); } else function = mus_strdup("(lambda (snd chn)"); } else function = mus_strdup("(lambda (snd chn)"); for (i = start_pos; i <= edits; i++) { ed_list *ed; ed = cp->edits[i]; if (ed) { old_function = function; function = NULL; /* most of these depend on the caller to supply a usable re-call string (origin). */ /* In insert/change cases, there's basically no choice */ if (ed->backed_up) { if ((ed->origin) && (strncmp(ed->origin, "set!", 4) == 0)) function = mus_format("%s\n (%s)", old_function, ed->origin); else function = mus_format("%s\n (%s snd chn)", old_function, ed->origin); } else { switch (ed->edit_type) { case INSERTION_EDIT: /* this and change_edit are not bullet-proof -- there are many ways an incomplete * origin can get here, but we want to trap the mix setters. In save-state above, * origin is just ignored, which is also less than ideal, but there are cases * (map-channel for example) where the lambda form can't be saved correctly, * so "the right thing" is not reachable. Here, perhaps the strcmp should * check for "set! -mix" or "set! (". */ if ((!(ed->origin)) || (strcmp(ed->origin, S_insert_samples) == 0)) { /* save data in temp file, use insert-samples with file name */ char *ofile; ofile = edit_list_data_to_temp_file(cp, ed, DELETE_ME, false); function = mus_format("%s\n (%s %lld %lld \"%s\" snd chn)", old_function, S_insert_samples, ed->beg, ed->len, ofile); free(ofile); } else function = mus_format("%s\n (%s snd chn)", old_function, ed->origin); break; case CHANGE_EDIT: if ((!(ed->origin)) || (strcmp(ed->origin, "set-samples") == 0)) { /* save data in temp file, use set-samples with file name */ char *ofile; ofile = edit_list_data_to_temp_file(cp, ed, DELETE_ME, false); function = mus_format("%s\n (set-samples %lld %lld \"%s\" snd chn)", old_function, ed->beg, ed->len, ofile); free(ofile); } else { if (strncmp(ed->origin, "set!", 4) == 0) function = mus_format("%s\n (%s)", old_function, ed->origin); else function = mus_format("%s\n (%s snd chn)", old_function, ed->origin); } break; case DELETION_EDIT: function = mus_format("%s\n (%s %lld %lld snd chn)", old_function, S_delete_samples, ed->beg, ed->len); break; case SCALED_EDIT: function = mus_format("%s\n (%s snd chn)", old_function, ed->origin); break; case EXTEND_EDIT: /* mix drag case */ break; case RAMP_EDIT: function = mus_format("%s\n (%s snd chn)", old_function, ed->origin); break; case ZERO_EDIT: /* origin here is useless (see extend_with_zeros cases) */ function = mus_format("%s\n (%s %lld %lld snd chn)", old_function, S_pad_channel, ed->beg, ed->len); break; case MIX_EDIT: function = mus_format("%s\n %s", old_function, ed->origin); break; case CHANGE_MIX_EDIT: function = mus_format("%s\n %s", old_function, ed->origin); break; default: break; } } if (old_function) {free(old_function); old_function = NULL;} } } old_function = function; if (close_mix_let) function = mus_format("%s))", old_function); else function = mus_format("%s)", old_function); free(old_function); return(function); #endif #if HAVE_RUBY char *function = NULL, *old_function = NULL; bool close_mix_let = false, first = true; int i, edits; edits = cp->edit_ctr; while ((edits < (cp->edit_size - 1)) && (cp->edits[edits + 1])) edits++; if ((end_pos > 0) && (end_pos < edits)) edits = end_pos; if (start_pos > edits) return(mus_strdup("Proc.new {|snd, chn| false }")); if (channel_has_mixes(cp)) { char *mix_list; mix_list = edit_list_mix_init(cp); if (mix_list) { close_mix_let = true; function = mus_format("Proc.new {|snd, chn| %s; ", mix_list); free(mix_list); } else function = mus_strdup("Proc.new {|snd, chn| "); } else function = mus_strdup("Proc.new {|snd, chn| "); for (i = start_pos; i <= edits; i++) { ed_list *ed; ed = cp->edits[i]; if (ed) { old_function = function; /* most of these depend on the caller to supply a usable re-call string (origin). */ /* In insert/change/ cases, there's basically no choice */ if (ed->backed_up) { if ((ed->origin) && (strncmp(ed->origin, "set_mix", 7) == 0)) function = mus_format("%s%s %s", function, (first) ? "" : ";", ed->origin); else function = mus_format("%s%s %s%ssnd, chn)", function, (first) ? "" : ";", ed->origin, (ed->origin[mus_strlen(ed->origin) - 1] == '(') ? "" : ", "); } else { switch (ed->edit_type) { case INSERTION_EDIT: if ((!(ed->origin)) || (strcmp(ed->origin, to_proc_name(S_insert_samples)) == 0)) { /* from HAVE_SCHEME above */ /* save data in temp file, use insert-samples with file name */ char *ofile; ofile = edit_list_data_to_temp_file(cp, ed, DELETE_ME, false); function = mus_format("%s %s(%lld, %lld, \"%s\", snd, chn)", function, to_proc_name(S_insert_samples), ed->beg, ed->len, ofile); free(ofile); } else function = mus_format("%s%s %s, snd, chn)", function, (first) ? "" : ";", ed->origin); break; case CHANGE_EDIT: if ((!(ed->origin)) || (strcmp(ed->origin, "set-samples") == 0)) { /* from HAVE_SCHEME above */ /* save data in temp file, use set-samples with file name */ char *ofile; ofile = edit_list_data_to_temp_file(cp, ed, DELETE_ME, false); function = mus_format("%s set_samples(%lld, %lld, \"%s\", snd, chn)", function, ed->beg, ed->len, ofile); free(ofile); } else if ((ed->origin) && (strncmp(ed->origin, "set_mix", 7) == 0)) function = mus_format("%s%s %s", function, (first) ? "" : ";", ed->origin); else function = mus_format("%s%s %s%ssnd, chn)", function, (first) ? "" : ";", ed->origin, (ed->origin[mus_strlen(ed->origin) - 1] == '(') ? "" : ", "); break; case DELETION_EDIT: function = mus_format("%s%s %s(%lld, %lld, snd, chn)", function, (first) ? "" : ";", to_proc_name(S_delete_samples), ed->beg, ed->len); break; case SCALED_EDIT: function = mus_format("%s%s %s, snd, chn)", function, (first) ? "" : ";", ed->origin); break; case EXTEND_EDIT: /* mix drag case */ break; case RAMP_EDIT: function = mus_format("%s%s %s, snd, chn)", function, (first) ? "" : ";", ed->origin); break; case ZERO_EDIT: /* origin here is useless (see extend_with_zeros cases) */ function = mus_format("%s%s %s(%lld, %lld, snd, chn)", function, (first) ? "" : ";", to_proc_name(S_pad_channel), ed->beg, ed->len); break; case MIX_EDIT: function = mus_format("%s%s %s", function, (first) ? "" : ";", ed->origin); break; case CHANGE_MIX_EDIT: function = mus_format("%s%s %s", function, (first) ? "" : ";", ed->origin); break; default: break; } } if (old_function) {free(old_function); old_function = NULL;} } first = false; } old_function = function; if (close_mix_let) function = mus_format("%s }", function); else function = mus_format("%s }", function); free(old_function); return(function); #endif #if HAVE_FORTH char *function = NULL, *old_function = NULL; int i, edits; edits = cp->edit_ctr; while ((edits < (cp->edit_size - 1)) && (cp->edits[edits + 1])) edits++; if ((end_pos > 0) && (end_pos < edits)) edits = end_pos; if (start_pos > edits) return(mus_strdup("lambda: <{ snd chn -- val }> #f ;")); if (channel_has_mixes(cp)) { char *mix_list; mix_list = edit_list_mix_init(cp); if (mix_list) { function = mus_format("lambda: <{ snd chn -- val }> %s", mix_list); free(mix_list); } else function = mus_strdup("lambda: <{ snd chn -- val }>"); } else function = mus_strdup("lambda: <{ snd chn -- val }>"); for (i = start_pos; i <= edits; i++) { ed_list *ed; ed = cp->edits[i]; if (ed) { old_function = function; /* most of these depend on the caller to supply a usable re-call string (origin). */ /* In insert/change cases, there's basically no choice */ if (ed->backed_up) { char *name, *func; func = split_origin(ed->origin, &name); if ((name) && (strncmp(name, "set-", 4) == 0)) function = mus_format("%s %s drop", function, ed->origin); else if ((ed->origin) && strstr(ed->origin, "mix-selection")) function = mus_format("%s %s", function, ed->origin); else { if (func) function = mus_format("%s %s snd chn %s drop", function, func, name); else function = mus_format("%s snd chn %s drop", function, name); } if (func) free(func); } else { switch (ed->edit_type) { case CHANGE_EDIT: { char *name, *func; func = split_origin(ed->origin, &name); if ((name) && (strncmp(name, "set-", 4) == 0)) function = mus_format("%s %s drop", function, ed->origin); else if ((ed->origin) && strstr(ed->origin, "mix-selection")) function = mus_format("%s %s", function, ed->origin); else { if (func) function = mus_format("%s %s snd chn %s drop", function, func, name); else function = mus_format("%s snd chn %s drop", function, name); } if (func) free(func); } break; case DELETION_EDIT: function = mus_format("%s %lld %lld snd chn %s drop", function, ed->beg, ed->len, S_delete_samples); break; case INSERTION_EDIT: case SCALED_EDIT: case RAMP_EDIT: { char *name, *func; if ((func = split_origin(ed->origin, &name))) { function = mus_format("%s %s snd chn %s drop", function, func, name); free(func); } else function = mus_format("%s snd chn %s drop", function, name); } break; case EXTEND_EDIT: /* mix drag case */ break; case ZERO_EDIT: /* origin here is unpredictable -- most of these extensions should be backed-over and invisible */ /* the one case that should survive (pad-channel) just passes its name as the origin */ function = mus_format("%s %lld %lld snd chn %s drop", function, ed->beg, ed->len, S_pad_channel); break; case MIX_EDIT: function = mus_format("%s %s", function, ed->origin); break; case CHANGE_MIX_EDIT: function = mus_format("%s %s", function, ed->origin); break; default: break; } } if (old_function) {free(old_function); old_function = NULL;} } } old_function = function; function = mus_format("%s ;", function); free(old_function); return(function); #endif #if (!HAVE_EXTENSION_LANGUAGE) return(NULL); #endif } static ed_fragment *fragment_free_list = NULL; static ed_fragment *make_ed_fragment(void) { if (fragment_free_list) { ed_fragment *e; e = fragment_free_list; fragment_free_list = (ed_fragment *)(fragment_free_list->next); memset((void *)e, 0, sizeof(ed_fragment)); return(e); } return((ed_fragment *)calloc(1, sizeof(ed_fragment))); } static ed_mixes *copy_fragment_mixes(ed_mixes *old_mixes) { ed_mixes *ed; ed = (ed_mixes *)calloc(1, sizeof(ed_mixes)); ed->size = old_mixes->size; ed->mix_list = (mix_state **)malloc(ed->size * sizeof(mix_state *)); /* pointer fixup is in ripple, but we need access to the old choice */ memcpy((void *)(ed->mix_list), (void *)(old_mixes->mix_list), ed->size * sizeof(mix_state *)); return(ed); } static ed_ramps *copy_fragment_ramps(ed_ramps *old_ramps) { ed_ramps *new_ramps; new_ramps = (ed_ramps *)malloc(sizeof(ed_ramps)); new_ramps->ramps = old_ramps->ramps; new_ramps->xramps = old_ramps->xramps; if (new_ramps->ramps > 0) { new_ramps->ramp_list = (ramp_state *)malloc(new_ramps->ramps * sizeof(ramp_state)); memcpy((void *)(new_ramps->ramp_list), (void *)(old_ramps->ramp_list), new_ramps->ramps * sizeof(ramp_state)); } else new_ramps->ramp_list = NULL; if (new_ramps->xramps > 0) { new_ramps->xramp_list = (xramp_state *)malloc(new_ramps->xramps * sizeof(xramp_state)); memcpy((void *)(new_ramps->xramp_list), (void *)(old_ramps->xramp_list), new_ramps->xramps * sizeof(xramp_state)); } else new_ramps->xramp_list = NULL; return(new_ramps); } static void copy_ed_fragment(ed_fragment *new_ed, ed_fragment *old_ed) { new_ed->typ = old_ed->typ; new_ed->snd = old_ed->snd; new_ed->out = old_ed->out; new_ed->beg = old_ed->beg; new_ed->end = old_ed->end; new_ed->scl = old_ed->scl; if (ED_RAMPS(old_ed)) ED_RAMPS(new_ed) = copy_fragment_ramps(ED_RAMPS(old_ed)); if (ED_MIXES(old_ed)) ED_MIXES(new_ed) = copy_fragment_mixes(ED_MIXES(old_ed)); } static void copy_checked_ed_fragment(ed_fragment *new_ed, ed_fragment *old_ed) { /* insert list special case */ if ((ED_RAMPS(old_ed)) && (ED_RAMPS(new_ed))) { if (ED_RAMP_LIST(new_ed)) free(ED_RAMP_LIST(new_ed)); if (ED_XRAMP_LIST(new_ed)) free(ED_XRAMP_LIST(new_ed)); free(ED_RAMPS(new_ed)); } if ((ED_MIXES(old_ed)) && (ED_MIXES(new_ed))) { if (ED_MIX_LIST(new_ed)) free(ED_MIX_LIST(new_ed)); free(ED_MIXES(new_ed)); } copy_ed_fragment(new_ed, old_ed); } static void clear_ed_fragment(ed_fragment *ed) { /* used by free_ed_fragment and when zeroing a copied fragment */ if (ED_RAMPS(ed)) { if (ED_RAMP_LIST(ed)) free(ED_RAMP_LIST(ed)); if (ED_XRAMP_LIST(ed)) free(ED_XRAMP_LIST(ed)); free(ED_RAMPS(ed)); ED_RAMPS(ed) = NULL; } if (ED_MIXES(ed)) { if (ED_MIX_LIST(ed)) free(ED_MIX_LIST(ed)); free(ED_MIXES(ed)); ED_MIXES(ed) = NULL; } } static ed_fragment *free_ed_fragment(ed_fragment *ed) { if (ed) { clear_ed_fragment(ed); ed->next = (struct ed_fragment *)fragment_free_list; fragment_free_list = ed; } return(NULL); } static ed_list *make_ed_list(int size) { ed_list *ed; int i; ed = (ed_list *)calloc(1, sizeof(ed_list)); ed->size = size; ed->allocated_size = size; ed->fragments = (ed_fragment **)malloc(size * sizeof(ed_fragment *)); /* can't use malloc/free -- compiler dislikes the assignment in free */ for (i = 0; i < size; i++) FRAGMENT(ed, i) = make_ed_fragment(); ed->origin = NULL; ed->maxamp = -1.0; ed->maxamp_position = -1; ed->selection_maxamp = -1.0; ed->selection_maxamp_position = -1; ed->properties_gc_loc = NOT_A_GC_LOC; ed->properties = Xen_false; return(ed); } void set_ed_maxamp(chan_info *cp, int edpos, mus_float_t val) { ed_list *ed; ed = cp->edits[edpos]; ed->maxamp = val; } mus_float_t ed_maxamp(chan_info *cp, int edpos) { ed_list *ed; ed = cp->edits[edpos]; return(ed->maxamp); } void set_ed_maxamp_position(chan_info *cp, int edpos, mus_long_t val) { ed_list *ed; ed = cp->edits[edpos]; ed->maxamp_position = val; } mus_long_t ed_maxamp_position(chan_info *cp, int edpos) { ed_list *ed; ed = cp->edits[edpos]; return(ed->maxamp_position); } void set_ed_selection_maxamp(chan_info *cp, mus_float_t val) { ed_list *ed; ed = cp->edits[cp->edit_ctr]; ed->selection_maxamp = val; } mus_float_t ed_selection_maxamp(chan_info *cp) { ed_list *ed; ed = cp->edits[cp->edit_ctr]; return(ed->selection_maxamp); } void set_ed_selection_maxamp_position(chan_info *cp, mus_long_t val) { ed_list *ed; ed = cp->edits[cp->edit_ctr]; ed->selection_maxamp_position = val; } mus_long_t ed_selection_maxamp_position(chan_info *cp) { ed_list *ed; ed = cp->edits[cp->edit_ctr]; return(ed->selection_maxamp_position); } typedef struct { snd_fd **rds; int size; } sf_info; static ed_list *free_ed_list(ed_list *ed, chan_info *cp) { if (ed) { if (FRAGMENTS(ed)) { int i; for (i = 0; i < ed->allocated_size; i++) free_ed_fragment(FRAGMENT(ed, i)); free(FRAGMENTS(ed)); } if (ed->origin) { free(ed->origin); ed->origin = NULL; } if (ed->marks) free_mark_list(ed); if (ed->peak_env) ed->peak_env = free_peak_env_info(ed->peak_env); if (ed->fft) ed->fft = free_enved_fft(ed->fft); if (ed->readers) { int i; sf_info *lst; lst = (sf_info *)(ed->readers); for (i = 0; i < lst->size; i++) if (lst->rds[i]) { reader_out_of_data(lst->rds[i]); lst->rds[i]->current_state = NULL; /* this pointer is now being freed, so it can't be safe to leave it around */ lst->rds[i]->cb = NULL; lst->rds[i] = NULL; } free(lst->rds); free(lst); ed->readers = NULL; } if (ed->properties_gc_loc != NOT_A_GC_LOC) { snd_unprotect_at(ed->properties_gc_loc); ed->properties_gc_loc = NOT_A_GC_LOC; ed->properties = Xen_false; } if (ED_MIXES(ed)) { free_ed_mixes(ED_MIXES(ed)); ED_MIXES(ed) = NULL; } free(ed); } return(NULL); } static void backup_edit_list_1(chan_info *cp, bool freeing) { int cur, i; ed_list *old_ed, *new_ed; mus_long_t old_end, new_end; ed_fragment *top = NULL; cur = cp->edit_ctr; if (cur <= 0) return; new_ed = cp->edits[cur]; old_ed = cp->edits[cur - 1]; new_ed->edpos = old_ed->edpos; new_ed->backed_up = true; old_end = old_ed->beg + old_ed->len; new_end = new_ed->beg + new_ed->len; if (old_end > new_end) new_end = old_end; if (old_ed->beg < new_ed->beg) new_ed->beg = old_ed->beg; new_ed->len = new_end - new_ed->beg + 1; if (freeing) top = fragment_free_list; old_ed = free_ed_list(old_ed, cp); if (freeing) { while ((fragment_free_list) && (fragment_free_list != top)) { ed_fragment *e; e = fragment_free_list; fragment_free_list = e->next; free(e); } } cp->edits[cur - 1] = new_ed; cp->edits[cur] = NULL; if (cp->sounds) /* protect from release_pending_sounds upon edit after undo after as-one-edit or whatever */ for (i = 0; i < cp->sound_size; i++) { snd_data *sd; sd = cp->sounds[i]; if ((sd) && (sd->edit_ctr == cur)) sd->edit_ctr--; } cp->edit_ctr--; reflect_edit_history_change(cp); } void backup_edit_list(chan_info *cp) { backup_edit_list_1(cp, false); } void free_edit_list(chan_info *cp) { if (cp) { if (cp->edits) { int i; for (i = 0; i < cp->edit_size; i++) if (cp->edits[i]) cp->edits[i] = free_ed_list(cp->edits[i], cp); free(cp->edits); cp->edits = NULL; } cp->edit_ctr = -1; cp->edit_size = 0; } } ed_list *initial_ed_list(mus_long_t beg, mus_long_t end) { ed_list *ed; ed = make_ed_list(2); ed->beg = beg; ed->len = end + 1; ed->selection_beg = NO_SELECTION; ed->selection_end = 0; ed->edit_type = INITIALIZE_EDIT; ed->sound_location = 0; ed->samples = end + 1; /* origin (channel %s %d) desc channel should be obvious from context */ FRAGMENT_LOCAL_POSITION(ed, 0) = beg; FRAGMENT_LOCAL_END(ed, 0) = end; FRAGMENT_SCALER(ed, 0) = 1.0; FRAGMENT_TYPE(ed, 0) = ED_SIMPLE; if (ed->len > 0) { /* second block is our end-of-tree marker */ FRAGMENT_SOUND(ed, 1) = EDIT_LIST_END_MARK; FRAGMENT_GLOBAL_POSITION(ed, 1) = end + 1; } else { FRAGMENT_SOUND(ed, 0) = EDIT_LIST_END_MARK; ed->size = 1; } return(ed); } snd_info *sound_is_silence(snd_info *sp) { if (sp) { int i; for (i = 0; i < sp->nchans; i++) { chan_info *cp; ed_list *ed; cp = sp->chans[i]; ed = cp->edits[0]; FRAGMENT_SCALER(ed, 0) = 0.0; FRAGMENT_TYPE(ed, 0) = ED_ZERO; } } return(sp); } static void ensure_ed_ramps(ed_fragment *ed, int rmps, int xrmps) { if (!(ED_RAMPS(ed))) { ED_RAMPS(ed) = (ed_ramps *)calloc(1, sizeof(ed_ramps)); if (rmps > 0) { ED_RAMP_LIST_SIZE(ed) = rmps; ED_RAMP_LIST(ed) = (ramp_state *)calloc(rmps, sizeof(ramp_state)); } if (xrmps > 0) { ED_XRAMP_LIST_SIZE(ed) = xrmps; ED_XRAMP_LIST(ed) = (xramp_state *)calloc(xrmps, sizeof(xramp_state)); } } else { if (rmps > ED_RAMP_LIST_SIZE(ed)) { if (ED_RAMP_LIST_SIZE(ed) == 0) ED_RAMP_LIST(ed) = (ramp_state *)calloc(rmps, sizeof(ramp_state)); else ED_RAMP_LIST(ed) = (ramp_state *)realloc(ED_RAMP_LIST(ed), rmps * sizeof(ramp_state)); ED_RAMP_LIST_SIZE(ed) = rmps; } if (xrmps > ED_XRAMP_LIST_SIZE(ed)) { if (ED_XRAMP_LIST_SIZE(ed) == 0) ED_XRAMP_LIST(ed) = (xramp_state *)calloc(xrmps, sizeof(xramp_state)); else ED_XRAMP_LIST(ed) = (xramp_state *)realloc(ED_XRAMP_LIST(ed), xrmps * sizeof(xramp_state)); ED_XRAMP_LIST_SIZE(ed) = xrmps; } } } static void new_before_ramp(ed_fragment *new_before, ed_fragment *old_before) { if (ramp_op(ED_TYPE(old_before))) { int i, rmps, xrmps; rmps = ED_RAMP_LIST_SIZE(old_before); xrmps = ED_XRAMP_LIST_SIZE(old_before); ensure_ed_ramps(new_before, rmps, xrmps); for (i = 0; i < rmps; i++) { ED_RAMP_INCR(new_before, i) = ED_RAMP_INCR(old_before, i); ED_RAMP_START(new_before, i) = ED_RAMP_START(old_before, i); } for (i = 0; i < xrmps; i++) { ED_XRAMP_OFFSET(new_before, i) = ED_XRAMP_OFFSET(old_before, i); ED_XRAMP_SCALER(new_before, i) = ED_XRAMP_SCALER(old_before, i); ED_XRAMP_INCR(new_before, i) = ED_XRAMP_INCR(old_before, i); ED_XRAMP_START(new_before, i) = ED_XRAMP_START(old_before, i); } } } static void new_after_ramp(ed_fragment *new_after, ed_fragment *old_after, mus_long_t samp) { mus_long_t dur; double d_dur; dur = samp - ED_GLOBAL_POSITION(old_after); d_dur = (double)dur; if (ramp_op(ED_TYPE(old_after))) { int i, rmps, xrmps; rmps = ED_RAMP_LIST_SIZE(old_after); xrmps = ED_XRAMP_LIST_SIZE(old_after); ensure_ed_ramps(new_after, rmps, xrmps); for (i = 0; i < rmps; i++) { ED_RAMP_INCR(new_after, i) = ED_RAMP_INCR(old_after, i); ED_RAMP_START(new_after, i) = ED_RAMP_START(old_after, i) + ED_RAMP_INCR(old_after, i) * d_dur; } for (i = 0; i < xrmps; i++) { ED_XRAMP_OFFSET(new_after, i) = ED_XRAMP_OFFSET(old_after, i); ED_XRAMP_SCALER(new_after, i) = ED_XRAMP_SCALER(old_after, i); ED_XRAMP_INCR(new_after, i) = ED_XRAMP_INCR(old_after, i); ED_XRAMP_START(new_after, i) = ED_XRAMP_START(old_after, i) * exp(log(ED_XRAMP_INCR(old_after, i)) * d_dur); } } } static void ripple_mixes(chan_info *cp, mus_long_t beg, mus_long_t change); static void ripple_mixes_with_scale(chan_info *cp, mus_long_t beg, mus_long_t len, mus_float_t scl); static ed_list *change_samples_in_list(mus_long_t beg, mus_long_t num, int pos, chan_info *cp, ed_fragment **rtn, const char *origin); static void ripple_all(chan_info *cp, mus_long_t beg, mus_long_t samps) { ripple_marks(cp, beg, samps); ripple_mixes(cp, beg, samps); check_for_first_edit(cp); } static bool lock_affected_mixes(chan_info *cp, int edpos, mus_long_t beg, mus_long_t end) { /* if a deletion, insertion, or change takes place on top of any part of * a virtual mix, we have to write the mix+underlying stuff out as a * change op. This returns true if it changed the edit list. * * we assume this is called either just after prepare_edit_list so cp->edit_ctr * points to the new (empty) edit list entry. */ ed_list *ed; int i; bool changed = false; mus_long_t change_beg = -1, change_end = -1, possible_beg = -1, fragment_end; ed = cp->edits[edpos]; /* first look for any directly affected mixes -- even if beg=0 and end=samples I think we want to * optimize the change as much as possible. */ for (i = 0; i < ed->size; i++) { mus_long_t fragment_beg; fragment_beg = FRAGMENT_GLOBAL_POSITION(ed, i); if (is_mix_op(FRAGMENT_TYPE(ed, i))) { fragment_end = fragment_beg + FRAGMENT_LENGTH(ed, i); if (possible_beg < 0) possible_beg = fragment_beg; if ((fragment_beg <= end) && (fragment_end >= beg) && /* hit a mix in the changing section */ (change_beg < 0)) { change_beg = possible_beg; /* this should track all the way back to where the current mixes started */ change_end = fragment_end; } } else { possible_beg = -1; /* break current chain, if any */ if (change_beg > 0) change_end = fragment_beg; if (fragment_beg > end) break; } } if (change_beg >= 0) { /* now make the change edit, and make sure the affected mixes are removed from the mixes arrays */ char *temp_file_name; io_error_t err; mus_long_t cur_len, cur_cursor; cur_len = ed->samples; cur_cursor = ed->cursor; temp_file_name = snd_tempnam(); err = channel_to_file_with_bounds(cp, temp_file_name, edpos, change_beg, change_end - change_beg + 1, cp->sound->hdr, false); if (err == IO_NO_ERROR) /* else snd_error earlier? */ { file_info *hdr; hdr = make_file_info(temp_file_name, FILE_READ_ONLY, FILE_NOT_SELECTED); if (hdr) { int fd; ed_list *new_ed; ed_fragment *cb = NULL; bool full_file; full_file = ((change_beg == 0) && (change_end >= ed->samples)); fd = snd_open_read(temp_file_name); snd_file_open_descriptors(fd, temp_file_name, hdr->sample_type, hdr->data_location, hdr->chans, hdr->type); if (full_file) { new_ed = initial_ed_list(0, change_end); new_ed->origin = mus_strdup("lock mixes"); new_ed->edpos = edpos; cb = FRAGMENT(new_ed, 0); } else new_ed = change_samples_in_list(change_beg, change_end - change_beg + 1, edpos, cp, &cb, NULL); new_ed->edit_type = CHANGE_EDIT; new_ed->samples = cur_len; new_ed->cursor = cur_cursor; cp->edits[cp->edit_ctr] = new_ed; ED_SOUND(cb) = add_sound_file_to_edit_list(cp, temp_file_name, make_file_state(fd, hdr, 0, 0, FILE_BUFFER_SIZE), hdr, DELETE_ME, 0); new_ed->sound_location = ED_SOUND(cb); ripple_all(cp, 0, 0); reflect_mix_change(ANY_MIX_ID); changed = true; } } if (temp_file_name) free(temp_file_name); } return(changed); } /* -------------------------------- insert samples -------------------------------- */ static ed_list *insert_section_into_list(mus_long_t samp, mus_long_t num, ed_list *current_state, ed_fragment **rtn, const char *origin, mus_float_t scaler) { int cur_len, cur_i, new_i; ed_fragment *new_f, *inserted_f = NULL; ed_list *new_state; if (num <= 0) return(NULL); cur_len = current_state->size; new_state = make_ed_list(cur_len + 3); /* leave room for possible split */ for (cur_i = 0, new_i = 0; cur_i < cur_len; cur_i++, new_i++) { ed_fragment *cur_f; cur_f = FRAGMENT(current_state, cur_i); new_f = FRAGMENT(new_state, new_i); if (ED_GLOBAL_POSITION(cur_f) > samp) { /* copy this fragment and ripple */ copy_ed_fragment(new_f, cur_f); ED_GLOBAL_POSITION(new_f) += num; } else { if (ED_GLOBAL_POSITION(cur_f) == samp) { /* insert new fragment, copy to end */ inserted_f = new_f; /* make newf and increment */ new_i++; new_f = FRAGMENT(new_state, new_i); copy_ed_fragment(new_f, cur_f); ED_GLOBAL_POSITION(new_f) += num; } else { copy_ed_fragment(new_f, cur_f); /* look for splits */ if (FRAGMENT_GLOBAL_POSITION(current_state, (cur_i + 1)) > samp) { ed_fragment *split_front_f, *split_back_f; /* split current at samp */ split_front_f = new_f; copy_checked_ed_fragment(split_front_f, cur_f); ED_LOCAL_END(split_front_f) = ED_LOCAL_POSITION(split_front_f) + samp - ED_GLOBAL_POSITION(split_front_f) - 1; /* samp - global position = where in current fragment, offset that by its local offset, turn into end sample */ new_i++; inserted_f = FRAGMENT(new_state, new_i); /* deal with that later */ new_i++; split_back_f = FRAGMENT(new_state, new_i); copy_ed_fragment(split_back_f, cur_f); ED_LOCAL_POSITION(split_back_f) = ED_LOCAL_END(split_front_f) + 1; ED_GLOBAL_POSITION(split_back_f) = samp + num; /* rippled */ /* now fixup ramps affected by the split */ if (ramp_op(ED_TYPE(cur_f))) { new_before_ramp(split_front_f, cur_f); new_after_ramp(split_back_f, cur_f, samp); } } } } } ED_GLOBAL_POSITION(inserted_f) = samp; ED_LOCAL_POSITION(inserted_f) = 0; ED_LOCAL_END(inserted_f) = num - 1; ED_TYPE(inserted_f) = ED_SIMPLE; ED_SCALER(inserted_f) = scaler; if (scaler == 0.0) ED_TYPE(inserted_f) = ED_ZERO; (*rtn) = inserted_f; new_state->size = new_i; new_state->beg = samp; new_state->len = num; if (origin) new_state->origin = mus_strdup(origin); return(new_state); } static ed_list *insert_samples_into_list(mus_long_t samp, mus_long_t num, int pos, chan_info *cp, ed_fragment **rtn, const char *origin, mus_float_t scaler) { ed_list *new_state; new_state = insert_section_into_list(samp, num, cp->edits[pos], rtn, origin, scaler); new_state->edpos = pos; if ((cp->edits) && (cp->edit_ctr > 0)) { ed_list *old_state; old_state = cp->edits[cp->edit_ctr - 1]; new_state->selection_beg = old_state->selection_beg; new_state->selection_end = old_state->selection_end; new_state->cursor = old_state->cursor; } if (new_state->cursor > samp) new_state->cursor += num; return(new_state); } static bool insert_zeros(chan_info *cp, mus_long_t beg, mus_long_t num, int edpos) { mus_long_t len, new_len; ed_fragment *cb; ed_list *ed, *old_ed; bool backup = false; old_ed = cp->edits[edpos]; len = cp->edits[edpos]->samples; new_len = len + num; /* we're inserting num zeros somewhere */ if (lock_affected_mixes(cp, edpos, beg, beg)) { edpos = cp->edit_ctr; old_ed = cp->edits[edpos]; increment_edit_ctr(cp); backup = true; } ed = insert_samples_into_list(beg, num, edpos, cp, &cb, S_pad_channel, 0.0); ed->samples = new_len; ED_SOUND(cb) = EDIT_LIST_ZERO_MARK; ED_SCALER(cb) = 0.0; ED_TYPE(cb) = ED_ZERO; ed->edit_type = ZERO_EDIT; ed->sound_location = 0; ed->maxamp = old_ed->maxamp; ed->maxamp_position = old_ed->maxamp_position; if (ed->maxamp_position >= beg) ed->maxamp_position += num; cp->edits[cp->edit_ctr] = ed; peak_env_insert_zeros(cp, beg, num, edpos); ripple_all(cp, beg, num); ripple_selection(ed, beg, num); reflect_sample_change_in_axis(cp); reflect_mix_change(ANY_MIX_ID); after_edit(cp); if (backup) backup_edit_list(cp); return(true); } bool extend_with_zeros(chan_info *cp, mus_long_t beg, mus_long_t num, int edpos, const char *origin) { /* this can also be called when beg is within the current sound -> insert a block of zeros */ int i; mus_long_t len, new_len; ed_fragment *cb; ed_list *new_ed, *old_ed; if (num <= 0) return(true); /* false if can't edit, but this is a no-op */ if (!(prepare_edit_list(cp, edpos, origin))) return(false); old_ed = cp->edits[edpos]; len = cp->edits[edpos]->samples; /* check for insert zeros case */ if (beg < len) return(insert_zeros(cp, beg, num, edpos)); /* extend with zeros at end */ new_len = beg + num; /* beg might even be > current end? */ beg = len; num = new_len - beg; new_ed = make_ed_list(old_ed->size + 1); new_ed->beg = beg; new_ed->len = num; new_ed->samples = new_len; new_ed->cursor = old_ed->cursor; new_ed->origin = mus_strdup(origin); new_ed->edpos = edpos; new_ed->selection_beg = old_ed->selection_beg; new_ed->selection_end = old_ed->selection_end; new_ed->maxamp = old_ed->maxamp; new_ed->maxamp_position = old_ed->maxamp_position; for (i = 0; i < old_ed->size; i++) copy_ed_fragment(FRAGMENT(new_ed, i), FRAGMENT(old_ed, i)); /* make the zero fragment, fixup the end fragment */ if (FRAGMENT(new_ed, old_ed->size)) free_ed_fragment(FRAGMENT(new_ed, old_ed->size)); /* make room for extension */ FRAGMENT(new_ed, old_ed->size) = FRAGMENT(new_ed, old_ed->size - 1); FRAGMENT_GLOBAL_POSITION(new_ed, old_ed->size) = new_len; cb = make_ed_fragment(); FRAGMENT(new_ed, old_ed->size - 1) = cb; ED_SOUND(cb) = EDIT_LIST_ZERO_MARK; ED_SCALER(cb) = 0.0; ED_TYPE(cb) = ED_ZERO; ED_GLOBAL_POSITION(cb) = beg; ED_LOCAL_POSITION(cb) = 0; ED_LOCAL_END(cb) = num - 1; new_ed->edit_type = ZERO_EDIT; cp->edits[cp->edit_ctr] = new_ed; peak_env_insert_zeros(cp, beg, num, edpos); ripple_all(cp, 0, 0); reflect_sample_change_in_axis(cp); after_edit(cp); return(true); } bool file_insert_samples(mus_long_t beg, mus_long_t num, const char *inserted_file, chan_info *cp, int chan, file_delete_t auto_delete, const char *origin, int edpos) { mus_long_t len; ed_fragment *cb; file_info *hdr; ed_list *ed, *old_ed; int backup = 0; old_ed = cp->edits[edpos]; len = old_ed->samples; if (beg > len) { if (!(extend_with_zeros(cp, len, beg - len, edpos, origin))) return(false); edpos = cp->edit_ctr; len = current_samples(cp); backup++; } if (!(prepare_edit_list(cp, edpos, origin))) return(false); if (lock_affected_mixes(cp, edpos, beg, beg)) { edpos = cp->edit_ctr; increment_edit_ctr(cp); backup++; } ed = insert_samples_into_list(beg, num, edpos, cp, &cb, origin, 1.0); ed->samples = len + num; ed->edit_type = INSERTION_EDIT; cp->edits[cp->edit_ctr] = ed; if ((old_ed->maxamp_position != -1) && (mus_sound_channel_maxamp_exists(inserted_file, chan))) { mus_float_t mx; mus_long_t pos; mx = mus_sound_channel_maxamp(inserted_file, chan, &pos); if (mx > old_ed->maxamp) { ed->maxamp = mx; ed->maxamp_position = beg + pos; } else { ed->maxamp = old_ed->maxamp; ed->maxamp_position = old_ed->maxamp_position; if (ed->maxamp_position >= beg) ed->maxamp_position += num; } } hdr = make_file_info(inserted_file, FILE_READ_ONLY, FILE_NOT_SELECTED); if (hdr) { int fd; fd = snd_open_read(inserted_file); snd_file_open_descriptors(fd, inserted_file, hdr->sample_type, hdr->data_location, hdr->chans, hdr->type); during_open(fd, inserted_file, SND_INSERT_FILE); ED_SOUND(cb) = add_sound_file_to_edit_list(cp, inserted_file, make_file_state(fd, hdr, chan, 0, FILE_BUFFER_SIZE), hdr, auto_delete, chan); ed->sound_location = ED_SOUND(cb); /* mixes are rippled first (ripple_all -> ripple_mixes) * so the lock should affect those that were split by the insertion, which in current * terms means we're interested only in 'beg' */ ripple_all(cp, beg, num); ripple_selection(ed, beg, num); reflect_sample_change_in_axis(cp); reflect_mix_change(ANY_MIX_ID); after_edit(cp); if (backup > 0) { backup_edit_list(cp); if (backup > 1) backup_edit_list(cp); } return(true); } return(false); } #define MAXAMP_CHECK_SIZE 10000 /* making this larger was slower, smaller no difference? */ bool insert_samples(mus_long_t beg, mus_long_t num, mus_float_t *vals, chan_info *cp, const char *origin, int edpos) { mus_long_t len; ed_fragment *cb; ed_list *ed, *old_ed; int backup = 0; if (num <= 0) return(true); old_ed = cp->edits[edpos]; len = old_ed->samples; if (beg > len) { if (!(extend_with_zeros(cp, len, beg - len, edpos, origin))) return(false); edpos = cp->edit_ctr; len = current_samples(cp); backup++; } if (!(prepare_edit_list(cp, edpos, origin))) return(false); if (lock_affected_mixes(cp, edpos, beg, beg)) { edpos = cp->edit_ctr; increment_edit_ctr(cp); backup++; } ed = insert_samples_into_list(beg, num, edpos, cp, &cb, origin, 1.0); ed->edit_type = INSERTION_EDIT; ed->samples = len + num; cp->edits[cp->edit_ctr] = ed; prepare_sound_list(cp); cp->sounds[cp->sound_ctr] = make_snd_data_buffer(vals, (int)num, cp->edit_ctr); ED_SOUND(cb) = cp->sound_ctr; ed->sound_location = ED_SOUND(cb); if ((old_ed->maxamp_position != -1) && (num < MAXAMP_CHECK_SIZE)) { mus_float_t mx; int i, pos = 0; mx = fabs(vals[0]); for (i = 1; i < num; i++) { mus_float_t temp; temp = fabs(vals[i]); if (temp > mx) { mx = temp; pos = i; } } if (mx > old_ed->maxamp) { ed->maxamp = mx; ed->maxamp_position = beg + pos; } else { ed->maxamp = old_ed->maxamp; ed->maxamp_position = old_ed->maxamp_position; if (ed->maxamp_position >= beg) ed->maxamp_position += num; } } ripple_all(cp, beg, num); ripple_selection(ed, beg, num); reflect_sample_change_in_axis(cp); reflect_mix_change(ANY_MIX_ID); after_edit(cp); if (backup > 0) { backup_edit_list(cp); if (backup > 1) backup_edit_list(cp); } return(true); } bool insert_complete_file(snd_info *sp, const char *str, mus_long_t chan_beg, file_delete_t auto_delete) { int nc; bool ok = false; char *filename; filename = mus_expand_filename(str); nc = mus_sound_chans(filename); if (nc > 0) { mus_long_t len; len = mus_sound_framples(filename); if (len == 0) snd_warning("%s has no data", str); else { int i, j, first_chan = 0; chan_info *ncp; if (sp->sync != 0) ncp = sp->chans[0]; else ncp = any_selected_channel(sp); first_chan = ncp->chan; for (i = first_chan, j = 0; (j < nc) && (i < sp->nchans); i++, j++) { char *origin; ncp = sp->chans[i]; #if HAVE_FORTH origin = mus_format("\"%s\" %lld %d %s drop", filename, chan_beg, j, S_insert_sound); #else origin = mus_format("%s" PROC_OPEN "\"%s\"" PROC_SEP "%lld" PROC_SEP "%d", to_proc_name(S_insert_sound), filename, chan_beg, j); #endif ok = file_insert_samples(chan_beg, len, filename, ncp, j, auto_delete, origin, ncp->edit_ctr); if (ok) update_graph(ncp); free(origin); } } } else snd_warning("can't read %s", str); free(filename); return(ok); } bool insert_complete_file_at_cursor(snd_info *sp, const char *filename) { chan_info *ncp; ncp = any_selected_channel(sp); return(insert_complete_file(sp, filename, cursor_sample(ncp), DONT_DELETE_ME)); } /* -------------------------------- delete samples -------------------------------- */ static ed_list *delete_section_from_list(mus_long_t beg, mus_long_t num, ed_list *current_state) { int cur_len, cur_i, new_i; ed_fragment *new_f; mus_long_t end, next_pos; ed_list *new_state; if (num <= 0) return(NULL); cur_len = current_state->size; end = beg + num; new_state = make_ed_list(cur_len + 3); /* leave room for possible splits */ for (cur_i = 0, new_i = 0; cur_i < cur_len; cur_i++) { ed_fragment *cur_f; cur_f = FRAGMENT(current_state, cur_i); new_f = FRAGMENT(new_state, new_i); if (ED_GLOBAL_POSITION(cur_f) >= end) { /* copy this fragment (we're past the deletion) */ copy_ed_fragment(new_f, cur_f); ED_GLOBAL_POSITION(new_f) -= num; new_i++; } else { next_pos = FRAGMENT_GLOBAL_POSITION(current_state, (cur_i + 1)); if (next_pos <= beg) { /* we're before deletion without any split, just copy */ copy_ed_fragment(new_f, cur_f); new_i++; } else { /* split off begin (if any), delete until num used up, split off end (if any) */ /* if global_pos > beg and global_pos next <= end, just drop it, else split */ if (ED_GLOBAL_POSITION(cur_f) < beg) { ed_fragment *split_front_f; /* split front */ split_front_f = new_f; copy_ed_fragment(split_front_f, cur_f); new_i++; ED_LOCAL_END(split_front_f) = ED_LOCAL_POSITION(split_front_f) + beg - ED_GLOBAL_POSITION(split_front_f) - 1; /* samp - global position = where in current fragment, offset that by its local offset, turn into end sample */ if (ramp_op(ED_TYPE(cur_f))) new_before_ramp(split_front_f, cur_f); } next_pos = FRAGMENT_GLOBAL_POSITION(current_state, (cur_i + 1)); if (next_pos > end) { ed_fragment *split_back_f; new_f = FRAGMENT(new_state, new_i); split_back_f = new_f; copy_ed_fragment(split_back_f, cur_f); new_i++; ED_GLOBAL_POSITION(split_back_f) = beg; ED_LOCAL_POSITION(split_back_f) += end - ED_GLOBAL_POSITION(cur_f); if (ramp_op(ED_TYPE(cur_f))) new_after_ramp(split_back_f, cur_f, end); } } } } new_state->size = new_i; new_state->beg = beg; new_state->len = num; #if HAVE_FORTH new_state->origin = mus_format("%lld %lld %s drop", beg, num, S_delete_samples); #else #if HAVE_RUBY { char *temp; temp = to_proc_name(S_delete_samples); new_state->origin = mus_format("%s" PROC_OPEN "%lld" PROC_SEP "%lld", temp, beg, num); if (temp) free(temp); } #else new_state->origin = mus_format("%s" PROC_OPEN "%lld" PROC_SEP "%lld", to_proc_name(S_delete_samples), beg, num); #endif #endif new_state->edit_type = DELETION_EDIT; new_state->sound_location = 0; return(new_state); } bool delete_samples(mus_long_t beg, mus_long_t num, chan_info *cp, int edpos) { mus_long_t len; if (num <= 0) return(true); len = cp->edits[edpos]->samples; if ((beg < len) && (beg >= 0)) { ed_list *ed; bool backup = false, read_max = false; if ((beg + num) > len) num = len - beg; if (!(prepare_edit_list(cp, edpos, S_delete_samples))) return(false); if (lock_affected_mixes(cp, edpos, beg, beg + num)) { edpos = cp->edit_ctr; increment_edit_ctr(cp); backup = true; } ed = delete_section_from_list(beg, num, cp->edits[edpos]); if ((cp->edits) && (cp->edit_ctr > 0)) { ed_list *old_state; old_state = cp->edits[cp->edit_ctr - 1]; ed->selection_beg = old_state->selection_beg; ed->selection_end = old_state->selection_end; ed->cursor = old_state->cursor; if (((old_state->maxamp_position >= 0) && (old_state->maxamp_position < beg)) || (old_state->maxamp_position > (beg + num))) { ed->maxamp = old_state->maxamp; ed->maxamp_position = old_state->maxamp_position; if (old_state->maxamp_position > (beg + num)) ed->maxamp_position -= num; } else { if ((beg == 0) && (num >= len)) { ed->maxamp = 0.0; ed->maxamp_position = 0; } else read_max = ((len - num) < MAXAMP_CHECK_SIZE); } } ed->edpos = edpos; ed->samples = len - num; cp->edits[cp->edit_ctr] = ed; ripple_all(cp, beg, -num); ripple_selection(ed, beg, -num); if (ed->cursor > beg) { /* this added 6-Dec-02 */ ed->cursor -= num; if (ed->cursor < beg) ed->cursor = beg; } if (read_max) { mus_long_t new_len; mus_float_t mx; int i, loc = 0; snd_fd *sf; new_len = ed->samples; sf = init_sample_read_any_with_bufsize(0, cp, READ_FORWARD, cp->edit_ctr, new_len + 1); /* read current samps */ sampler_set_safe(sf, new_len); mx = fabs(read_sample(sf)); for (i = 1; i < new_len; i++) { mus_float_t temp; temp = fabs(read_sample(sf)); if (temp > mx) { mx = temp; loc = i; } } free_snd_fd(sf); ed->maxamp = mx; ed->maxamp_position = loc; } reflect_sample_change_in_axis(cp); reflect_mix_change(ANY_MIX_ID); after_edit(cp); if (backup) backup_edit_list(cp); return(true); } return(false); } /* -------------------------------- change samples -------------------------------- */ static ed_list *change_samples_in_list(mus_long_t beg, mus_long_t num, int pos, chan_info *cp, ed_fragment **rtn, const char *origin) { /* delete + insert -- already checked that beg < cur end */ ed_list *new_state; mus_long_t del_num, cur_end; ed_fragment *changed_f; if (num <= 0) return(NULL); cur_end = cp->edits[pos]->samples; del_num = cur_end - beg; if (num < del_num) del_num = num; if (del_num > 0) { ed_list *del_state; del_state = delete_section_from_list(beg, del_num, cp->edits[pos]); new_state = insert_section_into_list(beg, num, del_state, &changed_f, origin, 1.0); del_state = free_ed_list(del_state, cp); } else new_state = insert_section_into_list(beg, num, cp->edits[pos], &changed_f, origin, 1.0); (*rtn) = changed_f; if ((cp->edits) && (cp->edit_ctr > 0)) { ed_list *old_state; old_state = cp->edits[cp->edit_ctr - 1]; new_state->selection_beg = old_state->selection_beg; new_state->selection_end = old_state->selection_end; } new_state->edpos = pos; return(new_state); } bool file_change_samples(mus_long_t beg, mus_long_t num, const char *tempfile, chan_info *cp, int chan, file_delete_t auto_delete, const char *origin, int edpos) { file_info *hdr; hdr = make_file_info(tempfile, FILE_READ_ONLY, FILE_NOT_SELECTED); if (hdr) { ed_list *ed, *old_ed; mus_long_t prev_len, new_len; ed_fragment *cb = NULL; int fd; int backup = 0; old_ed = cp->edits[edpos]; prev_len = old_ed->samples; if (beg > prev_len) { if (!(extend_with_zeros(cp, prev_len, beg - prev_len, edpos, origin))) { free_file_info(hdr); return(false); } backup++; edpos = cp->edit_ctr; prev_len = current_samples(cp); } new_len = beg + num; if (new_len < prev_len) new_len = prev_len; if (!(prepare_edit_list(cp, edpos, origin))) { free_file_info(hdr); return(false); } if (lock_affected_mixes(cp, edpos, beg, beg + num)) { edpos = cp->edit_ctr; increment_edit_ctr(cp); backup++; } ed = change_samples_in_list(beg, num, edpos, cp, &cb, origin); ed->edit_type = CHANGE_EDIT; ed->samples = new_len; if (cp->edit_ctr > 0) ed->cursor = cp->edits[cp->edit_ctr - 1]->cursor; cp->edits[cp->edit_ctr] = ed; if (((old_ed->maxamp_position >= 0) || ((beg == 0) && (num >= old_ed->samples))) && (mus_sound_channel_maxamp_exists(tempfile, chan))) { mus_float_t mx; mus_long_t pos; mx = mus_sound_channel_maxamp(tempfile, chan, &pos); if ((mx > old_ed->maxamp) || ((beg == 0) && (num >= old_ed->samples))) { ed->maxamp = mx; ed->maxamp_position = beg + pos; } else { /* make sure old max info is still relevant */ if ((old_ed->maxamp_position < beg) || (old_ed->maxamp_position > (beg + num))) { ed->maxamp = old_ed->maxamp; ed->maxamp_position = old_ed->maxamp_position; } } } fd = snd_open_read(tempfile); snd_file_open_descriptors(fd, tempfile, hdr->sample_type, hdr->data_location, hdr->chans, hdr->type); during_open(fd, tempfile, SND_CHANGE_FILE); ED_SOUND(cb) = add_sound_file_to_edit_list(cp, tempfile, make_file_state(fd, hdr, chan, 0, FILE_BUFFER_SIZE), hdr, auto_delete, chan); ed->sound_location = ED_SOUND(cb); ripple_all(cp, 0, 0); /* copies marks/mixes */ if (new_len > prev_len) reflect_sample_change_in_axis(cp); reflect_mix_change(ANY_MIX_ID); after_edit(cp); if (backup > 0) { backup_edit_list(cp); if (backup > 1) backup_edit_list(cp); } } else { Xen_error(NO_SUCH_FILE, Xen_list_3(C_string_to_Xen_string("~A: ~A"), C_string_to_Xen_string(origin), C_string_to_Xen_string(snd_io_strerror()))); } return(true); } bool file_override_samples(mus_long_t num, const char *tempfile, chan_info *cp, int chan, file_delete_t auto_delete, const char *origin) { file_info *hdr; hdr = make_file_info(tempfile, FILE_READ_ONLY, FILE_NOT_SELECTED); if (hdr) { int fd; ed_list *e; if (num == -1) num = (hdr->samples / hdr->chans); if (!(prepare_edit_list(cp, AT_CURRENT_EDIT_POSITION, origin))) { free_file_info(hdr); return(false); } /* don't need to lock mixes here -- we're simply ignoring all previous edit state */ fd = snd_open_read(tempfile); snd_file_open_descriptors(fd, tempfile, hdr->sample_type, hdr->data_location, hdr->chans, hdr->type); during_open(fd, tempfile, SND_OVERRIDE_FILE); e = initial_ed_list(0, num - 1); if (origin) e->origin = mus_strdup(origin); else e->origin = mus_strdup("file change samples"); e->edit_type = CHANGE_EDIT; e->edpos = cp->edit_ctr - 1; e->samples = num; if (cp->edit_ctr > 0) e->cursor = cp->edits[cp->edit_ctr - 1]->cursor; cp->edits[cp->edit_ctr] = e; if (mus_sound_channel_maxamp_exists(tempfile, chan)) { mus_long_t pos; e->maxamp = mus_sound_channel_maxamp(tempfile, chan, &pos); e->maxamp_position = pos; } FRAGMENT_SOUND(e, 0) = add_sound_file_to_edit_list(cp, tempfile, make_file_state(fd, hdr, chan, 0, FILE_BUFFER_SIZE), hdr, auto_delete, chan); e->sound_location = FRAGMENT_SOUND(e, 0); ripple_all(cp, 0, 0); reflect_sample_change_in_axis(cp); reflect_mix_change(ANY_MIX_ID); after_edit(cp); } else { Xen_error(NO_SUCH_FILE, Xen_list_3(C_string_to_Xen_string("~A: ~A"), C_string_to_Xen_string(origin), C_string_to_Xen_string(snd_io_strerror()))); } return(true); } bool change_samples(mus_long_t beg, mus_long_t num, mus_float_t *vals, chan_info *cp, const char *origin, int edpos, mus_float_t mx) { /* mx should be -1.0 except in the one case where vals is a block all of the same value */ mus_long_t prev_len, new_len; ed_fragment *cb; ed_list *ed, *old_ed; int backup = 0; if (num <= 0) return(true); old_ed = cp->edits[edpos]; prev_len = old_ed->samples; if (beg > prev_len) { if (!(extend_with_zeros(cp, prev_len, beg - prev_len, edpos, origin))) return(false); edpos = cp->edit_ctr; prev_len = current_samples(cp); backup++; } new_len = beg + num; if (new_len < prev_len) new_len = prev_len; if (!(prepare_edit_list(cp, edpos, origin))) return(false); if (lock_affected_mixes(cp, edpos, beg, beg + num)) { edpos = cp->edit_ctr; increment_edit_ctr(cp); backup++; } ed = change_samples_in_list(beg, num, edpos, cp, &cb, origin); ed->edit_type = CHANGE_EDIT; ed->samples = new_len; cp->edits[cp->edit_ctr] = ed; if (cp->edit_ctr > 0) ed->cursor = cp->edits[cp->edit_ctr - 1]->cursor; prepare_sound_list(cp); cp->sounds[cp->sound_ctr] = make_snd_data_buffer(vals, (int)num, cp->edit_ctr); ED_SOUND(cb) = cp->sound_ctr; ed->sound_location = ED_SOUND(cb); if ((old_ed->maxamp_position >= 0) || ((beg == 0) && (num >= old_ed->samples))) /* perhaps old max is irrelevant */ { int pos = 0; if ((mx < 0.0) && (num < MAXAMP_CHECK_SIZE)) { mus_float_t nmx; int i; nmx = fabs(vals[0]); for (i = 1; i < num; i++) { mus_float_t temp; temp = fabs(vals[i]); if (temp > nmx) { nmx = temp; pos = i; } } mx = nmx; } if (mx >= 0.0) { if ((mx > old_ed->maxamp) || ((beg == 0) && (num >= old_ed->samples))) { ed->maxamp = mx; ed->maxamp_position = beg + pos; } else { if ((old_ed->maxamp_position < beg) || (old_ed->maxamp_position > (beg + num))) { ed->maxamp = old_ed->maxamp; ed->maxamp_position = old_ed->maxamp_position; } } } } ripple_all(cp, 0, 0); if (new_len > prev_len) reflect_sample_change_in_axis(cp); reflect_mix_change(ANY_MIX_ID); after_edit(cp); if (backup > 0) { backup_edit_list(cp); if (backup > 1) backup_edit_list(cp); } return(true); } /* -------------------------------- ramp/scale -------------------------------- */ bool unrampable(chan_info *cp, mus_long_t beg, mus_long_t dur, int pos, bool is_xramp) { /* from enveloper (snd-sig.c) */ ed_list *ed; int i; mus_long_t end; ed = cp->edits[pos]; end = beg + dur - 1; for (i = 0; i < ed->size - 1; i++) { mus_long_t loc, next_loc; int typ; if (FRAGMENT_SOUND(ed, i) == EDIT_LIST_END_MARK) return(false); loc = FRAGMENT_GLOBAL_POSITION(ed, i); if (loc > end) return(false); typ = FRAGMENT_TYPE(ed, i); next_loc = FRAGMENT_GLOBAL_POSITION(ed, i + 1); /* i.e. next loc = current fragment end point */ /* fragment starts at loc, ends just before next_loc, is of type typ */ if ((next_loc > beg) && (((!is_xramp) && (type_info[typ].add_ramp == -1)) || ((is_xramp) && ((type_info[typ].add_xramp == -1))))) return(true); } return(false); } bool sound_fragments_in_use(chan_info *cp, int pos) { /* (swap-channels): are there any non-simple/non-ramp edits? */ int i; ed_list *ed; ed = cp->edits[pos]; for (i = 0; i < ed->size - 1; i++) { int index; index = FRAGMENT_SOUND(ed, i); if (index == EDIT_LIST_END_MARK) return(false); if ((index != 0) && (index != EDIT_LIST_ZERO_MARK)) return(true); } return(false); } bool virtual_mix_ok(chan_info *cp, int edpos) { /* since a mix can be dragged anywhere, and we want to continue treating it as a virtual mix anywhere, * we have to make sure that all edits in the current edit list are mix-able. */ ed_list *ed; int i; ed = cp->edits[edpos]; for (i = 0; i < ed->size - 1; i++) { if (FRAGMENT_SOUND(ed, i) == EDIT_LIST_END_MARK) return(true); if (!(is_mixable_op(FRAGMENT_TYPE(ed, i)))) return(false); } return(true); } static bool found_virtual_mix(chan_info *cp, int edpos) { ed_list *ed; int i; ed = cp->edits[edpos]; for (i = 0; i < ed->size - 1; i++) { if (FRAGMENT_SOUND(ed, i) == EDIT_LIST_END_MARK) return(false); if (is_mix_op(FRAGMENT_TYPE(ed, i))) return(true); } return(false); } static bool found_unmixable_ramped_op(chan_info *cp, int edpos, mus_long_t beg, mus_long_t end, bool is_xramp) { ed_list *ed; int i; ed = cp->edits[edpos]; for (i = 0; i < ed->size - 1; i++) { mus_long_t loc, next_loc; if (FRAGMENT_SOUND(ed, i) == EDIT_LIST_END_MARK) return(false); loc = FRAGMENT_GLOBAL_POSITION(ed, i); if (loc > end) return(false); next_loc = FRAGMENT_GLOBAL_POSITION(ed, i + 1); /* i.e. next loc = current fragment end point */ /* this fragment (i) starts at loc, ends just before next_loc, is of type typ */ if (next_loc > beg) { int after_ramp_op; if (is_xramp) after_ramp_op = type_info[FRAGMENT_TYPE(ed, i)].add_xramp; else after_ramp_op = type_info[FRAGMENT_TYPE(ed, i)].add_ramp; if ((after_ramp_op == -1) || /* this should not happen since we check for it ahead of time */ (!(is_mixable_op(after_ramp_op)))) return(true); } } return(false); } static bool section_is_zero(chan_info *cp, mus_long_t beg, mus_long_t dur, int pos) { ed_list *ed; int i; mus_long_t end; ed = cp->edits[pos]; end = beg + dur - 1; for (i = 0; i < ed->size - 1; i++) { mus_long_t loc, next_loc; int typ; if (FRAGMENT_SOUND(ed, i) == EDIT_LIST_END_MARK) return(true); loc = FRAGMENT_GLOBAL_POSITION(ed, i); if (loc > end) return(true); typ = FRAGMENT_TYPE(ed, i); next_loc = FRAGMENT_GLOBAL_POSITION(ed, i + 1); /* i.e. next loc = current fragment end point */ /* this fragment (i) starts at loc, ends just before next_loc, is of type typ */ if ((next_loc > beg) && (typ != ED_ZERO)) return(false); } return(true); } static ed_list *copy_and_split_list(mus_long_t beg, mus_long_t num, ed_list *current_state) { mus_long_t end, next_pos; int cur_len, cur_i, new_i; ed_list *new_state; ed_fragment *new_f, *mid_f = NULL; if (num <= 0) return(NULL); cur_len = current_state->size; end = beg + num; new_state = make_ed_list(cur_len + 2); /* leave room for possible split */ for (cur_i = 0, new_i = 0; cur_i < cur_len; cur_i++, new_i++) { ed_fragment *cur_f; cur_f = FRAGMENT(current_state, cur_i); new_f = FRAGMENT(new_state, new_i); if (ED_GLOBAL_POSITION(cur_f) >= end) { /* after any split, copy this fragment */ copy_ed_fragment(new_f, cur_f); } else { next_pos = FRAGMENT_GLOBAL_POSITION(current_state, (cur_i + 1)); if (next_pos <= beg) { /* we're before any split, just copy */ copy_ed_fragment(new_f, cur_f); } else { if ((ED_GLOBAL_POSITION(cur_f) >= beg) && (next_pos < end)) { /* entire segment is included */ copy_ed_fragment(new_f, cur_f); } else { /* check for front and back splits, copy cur */ copy_ed_fragment(new_f, cur_f); if (ED_GLOBAL_POSITION(cur_f) < beg) { ed_fragment *split_front_f, *split_back_f; /* split current at samp */ split_front_f = new_f; new_i++; split_back_f = FRAGMENT(new_state, new_i); copy_ed_fragment(split_back_f, cur_f); new_f = split_back_f; ED_LOCAL_END(split_front_f) = ED_LOCAL_POSITION(split_front_f) + beg - ED_GLOBAL_POSITION(split_front_f) - 1; /* beg - global position = where in current fragment, offset that by its local offset, turn into end sample */ ED_LOCAL_POSITION(split_back_f) = ED_LOCAL_END(split_front_f) + 1; ED_GLOBAL_POSITION(split_back_f) = beg; /* now fixup ramps affected by the split */ if (ramp_op(ED_TYPE(cur_f))) { new_before_ramp(split_front_f, cur_f); new_after_ramp(split_back_f, cur_f, beg); mid_f = split_back_f; } } if (next_pos > end) { ed_fragment *split_front_f, *split_back_f; /* split current at samp */ split_front_f = new_f; new_i++; split_back_f = FRAGMENT(new_state, new_i); copy_ed_fragment(split_back_f, cur_f); ED_LOCAL_END(split_front_f) = ED_LOCAL_POSITION(split_front_f) + end - ED_GLOBAL_POSITION(split_front_f) - 1; ED_LOCAL_POSITION(split_back_f) = ED_LOCAL_END(split_front_f) + 1; ED_GLOBAL_POSITION(split_back_f) = end; /* now fixup ramps affected by the split */ if (ramp_op(ED_TYPE(cur_f))) { if (ED_RAMPS(split_front_f)) { mus_float_t *ramp_begs = NULL, *xramp_begs = NULL; int i, rmps, xrmps; rmps = ED_RAMP_LIST_SIZE(split_front_f); xrmps = ED_XRAMP_LIST_SIZE(split_front_f); if (rmps > 0) ramp_begs = (mus_float_t *)calloc(rmps, sizeof(mus_float_t)); if (xrmps > 0) xramp_begs = (mus_float_t *)calloc(xrmps, sizeof(mus_float_t)); for (i = 0; i < rmps; i++) ramp_begs[i] = ED_RAMP_START(split_front_f, i); for (i = 0; i < xrmps; i++) xramp_begs[i] = ED_XRAMP_START(split_front_f, i); new_before_ramp(split_front_f, cur_f); if (mid_f == split_front_f) { for (i = 0; i < rmps; i++) ED_RAMP_START(split_front_f, i) = ramp_begs[i]; for (i = 0; i < xrmps; i++) ED_XRAMP_START(split_front_f, i) = xramp_begs[i]; } if (ramp_begs) free(ramp_begs); if (xramp_begs) free(xramp_begs); } new_after_ramp(split_back_f, cur_f, end); } } } } } } new_state->size = new_i; new_state->beg = beg; new_state->len = num; return(new_state); } bool scale_channel_with_origin(chan_info *cp, mus_float_t scl, mus_long_t beg, mus_long_t num, int pos, bool in_as_one_edit, const char *origin) { /* copy current ed-list and reset scalers */ mus_long_t len = 0; int i, old_pos; ed_list *new_ed, *old_ed; bool backup = false; old_ed = cp->edits[pos]; if ((beg < 0) || (num <= 0) || (beg >= old_ed->samples) || ((scl == 1.0) && (pos == cp->edit_ctr)) || (section_is_zero(cp, beg, num, pos))) return(false); old_pos = pos; len = old_ed->samples; if (!(prepare_edit_list(cp, pos, S_scale_channel))) return(false); if ((beg == 0) && (num >= old_ed->samples)) { if (scl == 0.0) { new_ed = initial_ed_list(0, num - 1); FRAGMENT_SCALER(new_ed, 0) = 0.0; FRAGMENT_TYPE(new_ed, 0) = ED_ZERO; new_ed->maxamp = 0.0; new_ed->maxamp_position = 0; } else { num = len; new_ed = make_ed_list(old_ed->size); new_ed->beg = beg; new_ed->len = num; for (i = 0; i < new_ed->size; i++) { copy_ed_fragment(FRAGMENT(new_ed, i), FRAGMENT(old_ed, i)); FRAGMENT_SCALER(new_ed, i) *= scl; } if (old_ed->maxamp_position != -1) { new_ed->maxamp = old_ed->maxamp * fabs(scl); new_ed->maxamp_position = old_ed->maxamp_position; } } new_ed->samples = len; cp->edits[cp->edit_ctr] = new_ed; peak_env_scale_by(cp, scl, pos); /* this seems wasteful if this is an intermediate (in_as_one_edit etc) */ } else { /* not sure how hard-nosed to be here -- we could probably get by if the scaled section completely encloses the mix(es) */ if (lock_affected_mixes(cp, pos, beg, beg + num)) { pos = cp->edit_ctr; old_ed = cp->edits[pos]; increment_edit_ctr(cp); backup = true; } if (beg + num > len) num = len - beg; new_ed = copy_and_split_list(beg, num, old_ed); new_ed->samples = len; cp->edits[cp->edit_ctr] = new_ed; for (i = 0; i < new_ed->size; i++) { if (FRAGMENT_GLOBAL_POSITION(new_ed, i) > (beg + num - 1)) break; /* not >= (1 sample selections) */ if (FRAGMENT_GLOBAL_POSITION(new_ed, i) >= beg) { FRAGMENT_SCALER(new_ed, i) *= scl; if (scl == 0.0) { FRAGMENT_TYPE(new_ed, i) = ED_ZERO; clear_ed_fragment(FRAGMENT(new_ed, i)); } } } peak_env_scale_selection_by(cp, scl, beg, num, pos); if (old_ed->maxamp_position >= 0) { if ((old_ed->maxamp_position < beg) || (old_ed->maxamp_position > (beg + num))) { if (fabs(scl) <= 1.0) { new_ed->maxamp = old_ed->maxamp; new_ed->maxamp_position = old_ed->maxamp_position; } else { /* perhaps this costs more than it saves */ if (num < MAXAMP_CHECK_SIZE) { mus_float_t mx; int i, loc = 0; snd_fd *sf; sf = init_sample_read_any_with_bufsize(beg, cp, READ_FORWARD, old_pos, num + 1); sampler_set_safe(sf, num); mx = fabs(read_sample(sf)); for (i = 1; i < num; i++) { mus_float_t temp; temp = fabs(read_sample(sf)); if (temp > mx) { mx = temp; loc = i; } } free_snd_fd(sf); mx *= fabs(scl); if (mx > old_ed->maxamp) { new_ed->maxamp = mx; new_ed->maxamp_position = beg + loc; } else { new_ed->maxamp = old_ed->maxamp; new_ed->maxamp_position = old_ed->maxamp_position; } } } } else { if (fabs(scl) >= 1.0) { new_ed->maxamp = old_ed->maxamp * fabs(scl); new_ed->maxamp_position = old_ed->maxamp_position; } } } } new_ed->cursor = old_ed->cursor; new_ed->edit_type = SCALED_EDIT; new_ed->sound_location = 0; if (origin) new_ed->origin = mus_strdup(origin); else { if (num == len) #if HAVE_FORTH new_ed->origin = mus_format("%.3f %lld" PROC_SEP PROC_FALSE " %s", scl, beg, S_scale_channel); #else new_ed->origin = mus_format("%s" PROC_OPEN "%.3f" PROC_SEP "%lld" PROC_SEP PROC_FALSE, to_proc_name(S_scale_channel), scl, beg); #endif else { #if HAVE_FORTH new_ed->origin = mus_format("%.3f %lld" PROC_SEP "%lld %s", scl, beg, num, S_scale_channel); #else new_ed->origin = mus_format("%s" PROC_OPEN "%.3f" PROC_SEP "%lld" PROC_SEP "%lld", to_proc_name(S_scale_channel), scl, beg, num); #endif } } new_ed->edpos = pos; new_ed->selection_beg = old_ed->selection_beg; new_ed->selection_end = old_ed->selection_end; ripple_marks(cp, 0, 0); ripple_mixes_with_scale(cp, beg, num, scl); check_for_first_edit(cp); if (!in_as_one_edit) { update_graph(cp); reflect_mix_change(ANY_MIX_ID); after_edit(cp); /* "as_one_edit" here is an envelope, so it's not a "real" edit -- after_edit called explicitly in snd-sig.c in this case */ } if (backup) backup_edit_list(cp); return(true); } bool scale_channel(chan_info *cp, mus_float_t scl, mus_long_t beg, mus_long_t num, int pos, bool in_as_one_edit) { return(scale_channel_with_origin(cp, scl, beg, num, pos, in_as_one_edit, NULL)); } static void add_ramp_to_fragment(ed_list *new_ed, int i, double start, double incr, mus_float_t scaler, mus_float_t offset, bool is_xramp) { ed_fragment *ed; int rmps = 0, xrmps = 0, loc, typ; ed = FRAGMENT(new_ed, i); if (ED_TYPE(ed) == ED_ZERO) return; if ((!is_xramp) && (start == 0.0) && (incr == 0.0)) { ED_TYPE(ed) = ED_ZERO; clear_ed_fragment(ed); return; } if (ED_RAMPS(ed)) { rmps = ED_RAMP_LIST_SIZE(ed); xrmps = ED_XRAMP_LIST_SIZE(ed); } if (is_xramp) xrmps++; else rmps++; ensure_ed_ramps(ed, rmps, xrmps); typ = ED_TYPE(ed); if (is_xramp) { loc = xrmps - 1; ED_XRAMP_START(ed, loc) = start; ED_XRAMP_INCR(ed, loc) = incr; ED_XRAMP_SCALER(ed, loc) = scaler; ED_XRAMP_OFFSET(ed, loc) = offset; ED_TYPE(ed) = type_info[typ].add_xramp; } else { loc = rmps - 1; ED_RAMP_START(ed, loc) = start; ED_RAMP_INCR(ed, loc) = incr; ED_TYPE(ed) = type_info[typ].add_ramp; } } static bool all_ramp_channel(chan_info *cp, double start, double incr, double scaler, double offset, mus_long_t beg, mus_long_t num, int pos, bool in_as_one_edit, const char *origin, bool is_xramp, mus_any *e, int xramp_seg_loc) { mus_long_t len = 0; int i, old_pos; ed_list *new_ed, *old_ed; bool backup = false; double rstart; /* fprintf(stderr,"ramp: %f %f %f %f %lld %lld\n", start, incr, scaler, offset, beg, num); */ old_ed = cp->edits[pos]; if ((beg < 0) || (num <= 0) || (beg >= old_ed->samples) || (section_is_zero(cp, beg, num, pos))) return(false); /* was true, but this is a no-op */ if ((!is_xramp) && ((incr == 0.0) || (num == 1))) /* in xramp case, we're ramping a power, not a scaler */ return(scale_channel(cp, start, beg, num, pos, in_as_one_edit)); len = old_ed->samples; old_pos = pos; if (!(prepare_edit_list(cp, pos, origin))) return(false); if (found_virtual_mix(cp, pos)) { mus_long_t lock_beg, lock_end; if (found_unmixable_ramped_op(cp, pos, beg, beg + num, is_xramp)) { lock_beg = 0; lock_end = len - 1; } else { lock_beg = beg; lock_end = beg + num; } if (lock_affected_mixes(cp, pos, lock_beg, lock_end)) { pos = cp->edit_ctr; old_ed = cp->edits[pos]; increment_edit_ctr(cp); backup = true; } } rstart = start; if ((beg == 0) && (num >= old_ed->samples)) { /* one ramp over entire fragment list -- no splits will occur here */ num = len; new_ed = make_ed_list(old_ed->size); new_ed->beg = beg; new_ed->len = num; cp->edits[cp->edit_ctr] = new_ed; for (i = 0; i < new_ed->size; i++) copy_ed_fragment(FRAGMENT(new_ed, i), FRAGMENT(old_ed, i)); for (i = 0; i < new_ed->size - 1; i++) /* -1 here to leave end mark alone */ { add_ramp_to_fragment(new_ed, i, start, incr, scaler, offset, is_xramp); if (!is_xramp) start += (incr * FRAGMENT_LENGTH(new_ed, i)); else start *= exp(log(incr) * FRAGMENT_LENGTH(new_ed, i)); } } else { if (beg + num > len) num = len - beg; new_ed = copy_and_split_list(beg, num, old_ed); cp->edits[cp->edit_ctr] = new_ed; for (i = 0; i < new_ed->size - 1; i++) { if (FRAGMENT_GLOBAL_POSITION(new_ed, i) > (beg + num - 1)) break; /* not >= (1 sample selections) */ if (FRAGMENT_GLOBAL_POSITION(new_ed, i) >= beg) { add_ramp_to_fragment(new_ed, i, start, incr, scaler, offset, is_xramp); if (!is_xramp) start += (incr * FRAGMENT_LENGTH(new_ed, i)); else start *= exp(log(incr) * FRAGMENT_LENGTH(new_ed, i)); } } if ((old_ed->maxamp_position >= 0) || ((beg == 0) && (num >= old_ed->samples))) { if ((old_ed->maxamp_position >= 0) && ((old_ed->maxamp_position < beg) || (old_ed->maxamp_position > (beg + num))) && (fabs(rstart) <= 1.0) && (((!is_xramp) && (fabs(rstart + incr * num) <= 1.0)) || ((is_xramp) && (fabs(rstart * exp(log(incr) * num)) <= 1.0)))) { /* we have maxamp data for the previous edit and * the ramp does not hit the current maxamp and it stays within -1.0 to 1.0, * so it can't affect the maxamp */ new_ed->maxamp = old_ed->maxamp; new_ed->maxamp_position = old_ed->maxamp_position; } else { /* if ramped portion has a max > old max, we can use it in any case, * but we need to do the ramp by hand here, I think. */ if ((num < MAXAMP_CHECK_SIZE) && (!is_xramp)) { mus_float_t mx, x; int i, loc = 0; snd_fd *sf; x = rstart; sf = init_sample_read_any_with_bufsize(beg, cp, READ_FORWARD, old_pos, num + 1); sampler_set_safe(sf, num); mx = fabs(x * read_sample(sf)); for (i = 1; i < num; i++) { mus_float_t temp; x += incr; temp = fabs(x * read_sample(sf)); if (temp > mx) { mx = temp; loc = i; } } free_snd_fd(sf); if ((mx > old_ed->maxamp) || ((beg == 0) && (num >= old_ed->samples))) { new_ed->maxamp = mx; new_ed->maxamp_position = beg + loc; } else { if ((old_ed->maxamp_position < beg) || (old_ed->maxamp_position > (beg + num))) { new_ed->maxamp = old_ed->maxamp; new_ed->maxamp_position = old_ed->maxamp_position; } } } } } } new_ed->samples = len; new_ed->cursor = old_ed->cursor; new_ed->edit_type = RAMP_EDIT; new_ed->sound_location = 0; if (!is_xramp) { mus_float_t rmp0, rmp1; rmp0 = rstart; rmp1 = rstart + incr * (num - 1); /* want end point */ #if HAVE_FORTH if (num == len) new_ed->origin = mus_format("%.3f %.3f %lld" PROC_SEP PROC_FALSE " %s", rmp0, rmp1, beg, origin); else new_ed->origin = mus_format("%.3f %.3f %lld" PROC_SEP "%lld %s", rmp0, rmp1, beg, num, origin); #else if (num == len) new_ed->origin = mus_format("%s" PROC_OPEN "%.3f" PROC_SEP "%.3f" PROC_SEP "%lld" PROC_SEP PROC_FALSE, to_proc_name(origin), rmp0, rmp1, beg); else new_ed->origin = mus_format("%s" PROC_OPEN "%.3f" PROC_SEP "%.3f" PROC_SEP "%lld" PROC_SEP "%lld", to_proc_name(origin), rmp0, rmp1, beg, num); #endif } else { mus_float_t *data; data = mus_data(e); #if HAVE_FORTH if (num == len) new_ed->origin = mus_format("%.3f %.3f %.3f %lld" PROC_SEP PROC_FALSE " %s", data[xramp_seg_loc * 2 + 1], data[xramp_seg_loc * 2 + 3], mus_increment(e), beg, origin); else new_ed->origin = mus_format("%.3f %.3f %.3f %lld" PROC_SEP "%lld %s", data[xramp_seg_loc * 2 + 1], data[xramp_seg_loc * 2 + 3], mus_increment(e), beg, num, origin); #else if (num == len) new_ed->origin = mus_format("%s" PROC_OPEN "%.3f" PROC_SEP "%.3f" PROC_SEP "%.3f" PROC_SEP "%lld" PROC_SEP PROC_FALSE, to_proc_name(origin), data[xramp_seg_loc * 2 + 1], data[xramp_seg_loc * 2 + 3], mus_increment(e), beg); else new_ed->origin = mus_format("%s" PROC_OPEN "%.3f" PROC_SEP "%.3f" PROC_SEP "%.3f" PROC_SEP "%lld" PROC_SEP "%lld", to_proc_name(origin), data[xramp_seg_loc * 2 + 1], data[xramp_seg_loc * 2 + 3], mus_increment(e), beg, num); #endif } new_ed->edpos = pos; new_ed->selection_beg = old_ed->selection_beg; new_ed->selection_end = old_ed->selection_end; ripple_all(cp, 0, 0); /* 0,0 -> copy marks */ reflect_mix_change(ANY_MIX_ID); after_edit(cp); if (backup) backup_edit_list(cp); return(true); } bool ramp_channel(chan_info *cp, double start, double incr, mus_long_t beg, mus_long_t num, int pos, bool in_as_one_edit) { return(all_ramp_channel(cp, start, incr, 0.0, 0.0, beg, num, pos, in_as_one_edit, S_ramp_channel, false, NULL, 0)); } bool xramp_channel(chan_info *cp, double start, double incr, double scaler, double offset, mus_long_t beg, mus_long_t num, int pos, bool in_as_one_edit, mus_any *e, int xramp_seg_loc) { return(all_ramp_channel(cp, start, incr, scaler, offset, beg, num, pos, in_as_one_edit, S_xramp_channel, true, e, xramp_seg_loc)); } /* -------------------------------- samplers -------------------------------- */ static reader_mixes *free_reader_mixes(reader_mixes *md) { if (md) { if ((md->size > 0) && (md->sfs)) { int i; for (i = 0; i < md->size; i++) if (md->sfs[i]) { if (md->sfs[i]->current_state) md->sfs[i]->current_state = free_ed_list(md->sfs[i]->current_state, md->sfs[i]->cp); /* md->cp is ignored in this case -- MIX_EDIT */ md->sfs[i] = free_snd_fd(md->sfs[i]); } free(md->sfs); } free(md); } return(NULL); } snd_fd *free_snd_fd_almost(snd_fd *sf) { if ((sf) && (!(sf->freed))) { snd_data *sd; if (sf->ramps) { if (READER_INCRS(sf)) free(READER_INCRS(sf)); if (READER_VALS(sf)) free(READER_VALS(sf)); if (READER_XINCRS(sf)) free(READER_XINCRS(sf)); if (READER_XVALS(sf)) free(READER_XVALS(sf)); free(sf->ramps); sf->ramps = NULL; } if (sf->mixes) sf->mixes = (void *)free_reader_mixes((reader_mixes *)(sf->mixes)); reader_out_of_data(sf); sd = sf->current_sound; if ((sd) && ((sd->type == SND_DATA_BUFFER) || (sd->type == SND_DATA_FILE))) { sd->inuse = false; if ((sd->copy) || (sd->free_me)) sd = free_snd_data(sd); } sf->current_sound = NULL; if (sf->current_state) { if (sf->type == MIX_READER) sf->current_state = free_ed_list(sf->current_state, sf->cp); sf->current_state = NULL; } sf->cp = NULL; sf->local_sp = NULL; sf->cb = NULL; sf->region = INVALID_REGION; sf->edit_ctr = -1; sf->freed = true; } return(NULL); } snd_fd *free_snd_fd(snd_fd *sf) { if ((sf) && (!(sf->freed))) { free_snd_fd_almost(sf); free(sf); } return(NULL); } mus_long_t current_location(snd_fd *sf) { /* only used by moving cursor code in snd-dac.c [and sampler-position] */ if (sf->current_sound) return(READER_GLOBAL_POSITION(sf) - READER_LOCAL_POSITION(sf) + io_beg(sf->current_sound->io) + sf->loc); return(READER_GLOBAL_POSITION(sf) - READER_LOCAL_POSITION(sf) + sf->loc); } void sampler_set_safe(snd_fd *sf, mus_long_t dur) { /* tricky because we currently assume the reader protects against reading off the end by returning 0.0, * perhaps pass in dur (= number of samples we will be reading), and if last-loc+1>=dur, we're safe? * dur here has to match the number of samples we will read! */ /* fprintf(stderr, "%lld %lld %lld: %lld\n", sf->first, sf->loc, sf->last, dur); */ if ((sf->last - sf->loc + 1) >= dur) /* two kinds of counter here: last is sample number, dur is how many samples */ { if (sf->runf == next_sample_value_unscaled) sf->runf = next_sample_value_unscaled_and_unchecked; else { if (sf->runf == next_sample_value) sf->runf = next_sample_value_unchecked; else { if (sf->runf == next_ramp1) sf->runf = next_ramp1_unchecked; } } } else { if (sf->loc - sf->first + 1 >= dur) { if (sf->runf == previous_sample_value_unscaled) sf->runf = previous_sample_value_unscaled_and_unchecked; else { if (sf->runf == previous_sample_value) sf->runf = previous_sample_value_unchecked; } } } } snd_fd *init_sample_read_any_with_bufsize(mus_long_t samp, chan_info *cp, read_direction_t direction, int edit_position, int bufsize) { snd_fd *sf; snd_info *sp; ed_list *ed; int len, i; mus_long_t curlen; snd_data *first_snd = NULL; /* bufsize might be ignored here except in the copied buffer case -- we use the pre-exisiting buffer? */ if (cp->active < CHANNEL_HAS_EDIT_LIST) return(NULL); if ((edit_position < 0) || (edit_position >= cp->edit_size)) return(NULL); /* was ">" not ">=": 6-Jan-05 */ ed = cp->edits[edit_position]; if (!ed) return(NULL); sp = cp->sound; if (sp->inuse == SOUND_IDLE) return(NULL); if ((sp->need_update) && (!(sp->writing))) { if (mus_file_probe(sp->filename) == 0) { snd_warning("%s no longer exists!", sp->short_filename); return(NULL); } else { time_t write_date; write_date = file_write_date(sp->filename); if (sp->update_warning_write_date != write_date) { snd_warning("%s has changed since we last read it!", sp->short_filename); sp->update_warning_write_date = write_date; /* without this write-date check, there are cases where this can get into a loop sending warnings */ } } } curlen = cp->edits[edit_position]->samples; /* snd_fd allocated only here */ sf = (snd_fd *)calloc(1, sizeof(snd_fd)); /* only creation point (... oops -- see below...)*/ sf->freed = false; sf->region = INVALID_REGION; sf->type = SAMPLER; sf->initial_samp = samp; sf->cp = cp; sf->fscaler = 1.0; sf->direction = direction; sf->current_state = ed; sf->edit_ctr = edit_position; if ((curlen <= 0) || /* no samples, not ed->len (delete->len = #deleted samps) */ (samp < 0) || /* this should never happen */ ((samp >= curlen) && (direction == READ_FORWARD))) return(cancel_reader(sf)); if (samp >= curlen) samp = curlen - 1; len = ed->size; for (i = 0; i < len; i++) { ed_fragment *cb; cb = FRAGMENT(ed, i); if ((ED_GLOBAL_POSITION(cb) > samp) || (ED_SOUND(cb) == EDIT_LIST_END_MARK)) /* i.e. we went one too far */ { mus_long_t ind0, ind1, indx; sf->cb = FRAGMENT(ed, i - 1); /* so back up one */ sf->cbi = i - 1; sf->frag_pos = samp - READER_GLOBAL_POSITION(sf); ind0 = READER_LOCAL_POSITION(sf); /* cb->beg */ indx = ind0 + sf->frag_pos; ind1 = READER_LOCAL_END(sf); /* cb->end */ sf->fscaler = READER_SCALER(sf); if (zero_op(READER_TYPE(sf))) { sf->current_sound = NULL; sf->loc = indx; sf->first = ind0; sf->last = ind1; sf->data = NULL; choose_accessor(sf); return(sf); } first_snd = sf->cp->sounds[READER_SOUND(sf)]; if (!first_snd) return(cancel_reader(sf)); if (first_snd->type == SND_DATA_FILE) { /* since arbitrarily many work procs can be running in parallel, reading the same * data (edit tree sound file entries), we can't share the clm-style IO buffers since these contain * a local notion of current position which is not accessed on every sample by the * samplers (they trust their snd_fd indices); we wouldn't want to be * constantly jumping around and re-reading data buffers (in the worst case * many times per sample) anyway, so we copy the IO buffer, allocate a relatively * small(?? -- is this obsolete) data buffer, and then free all the copied snd_data stuff as soon as * the current reader is done. * * but if all the data is in the current buffer, it won't be moving? */ if ((first_snd->inuse) || (bufsize > FILE_BUFFER_SIZE)) { first_snd = copy_snd_data(first_snd, samp, bufsize); if (!first_snd) return(cancel_reader(sf)); } first_snd->inuse = true; sf->current_sound = first_snd; sf->data = first_snd->buffered_data; if (direction == READ_FORWARD) file_buffers_forward(ind0, ind1, indx, sf, first_snd); else file_buffers_back(ind0, ind1, indx, sf, first_snd); } else { sf->current_sound = NULL; sf->data = first_snd->buffered_data; sf->first = ind0; sf->last = ind1; sf->loc = indx; } choose_accessor(sf); return(sf); } } if (sf) free(sf); return(NULL); } snd_fd *init_sample_read_any(mus_long_t samp, chan_info *cp, read_direction_t direction, int edit_position) { return(init_sample_read_any_with_bufsize(samp, cp, direction, edit_position, FILE_BUFFER_SIZE)); } snd_fd *init_sample_read(mus_long_t samp, chan_info *cp, read_direction_t direction) { return(init_sample_read_any_with_bufsize(samp, cp, direction, cp->edit_ctr, FILE_BUFFER_SIZE)); } mus_float_t chn_sample(mus_long_t samp, chan_info *cp, int pos) { snd_fd *sf; mus_float_t val = 0.0; /* pos is assumed to be right here, not AT_CURRENT_EDIT_POSITION for example */ if ((cp->active < CHANNEL_HAS_EDIT_LIST) || (samp < 0) || (pos < 0) || (pos >= cp->edit_size) || (samp >= cp->edits[pos]->samples)) return(0.0); /* try the quick case */ if (pos == 0) { snd_data *sd; sd = cp->sounds[0]; if ((sd) && (sd->io) && (io_beg(sd->io) <= samp) && (io_end(sd->io) >= samp)) return(sd->buffered_data[samp - io_beg(sd->io)]); } /* do it the hard way */ sf = init_sample_read_any_with_bufsize(samp, cp, READ_FORWARD, pos, 2); if (sf) { val = read_sample(sf); free_snd_fd(sf); } return(val); } static void previous_sound_1(snd_fd *sf) { mus_long_t ind0, ind1; bool at_start; if ((sf->cp) && (sf->cp->active < CHANNEL_HAS_EDIT_LIST)) { reader_out_of_data(sf); return; } at_start = ((sf->cb == NULL) || (sf->current_sound == NULL) || (READER_LOCAL_POSITION(sf) >= io_beg(sf->current_sound->io))); if (at_start) { snd_data *prev_snd; if (sf->current_sound) { prev_snd = sf->current_sound; prev_snd->inuse = false; sf->current_sound = NULL; if (prev_snd->copy) prev_snd = free_snd_data(prev_snd); } if (sf->cbi == 0) { reader_out_of_data(sf); return; } sf->cbi--; /* now start in the final portion of this block (if a file) */ sf->cb = FRAGMENT((sf->current_state), sf->cbi); ind0 = READER_LOCAL_POSITION(sf); ind1 = READER_LOCAL_END(sf); sf->fscaler = READER_SCALER(sf); if (zero_op(READER_TYPE(sf))) { sf->current_sound = NULL; sf->loc = ind1; sf->first = ind0; sf->last = ind1; sf->data = NULL; } else { prev_snd = sf->cp->sounds[READER_SOUND(sf)]; if (prev_snd->type == SND_DATA_FILE) { if (prev_snd->inuse) { prev_snd = copy_snd_data(prev_snd, ind0, FILE_BUFFER_SIZE); if (prev_snd == NULL) { /* too many files open or something of that sort */ reader_out_of_data(sf); return; } } sf->data = prev_snd->buffered_data; prev_snd->inuse = true; sf->current_sound = prev_snd; file_buffers_back(ind0, ind1, ind1, sf, prev_snd); } else { sf->data = prev_snd->buffered_data; sf->loc = ind1; sf->first = ind0; sf->last = ind1; } } sf->frag_pos = ind1 - ind0; choose_accessor(sf); } else { mus_long_t indx; /* back up in current file */ ind0 = READER_LOCAL_POSITION(sf); ind1 = READER_LOCAL_END(sf); indx = io_beg(sf->current_sound->io) - 1; file_buffers_back(ind0, ind1, indx, sf, sf->current_sound); } } static mus_float_t previous_sound(snd_fd *sf) { previous_sound_1(sf); return(read_sample(sf)); } static void next_sound_1(snd_fd *sf) { mus_long_t ind0, ind1; bool at_end = false; if ((sf->cp) && (sf->cp->active < CHANNEL_HAS_EDIT_LIST)) { reader_out_of_data(sf); return; } at_end = ((sf->cb == NULL) || (sf->current_sound == NULL) || (READER_LOCAL_END(sf) <= io_end(sf->current_sound->io))); if (at_end) { snd_data *nxt_snd; if (sf->current_sound) { nxt_snd = sf->current_sound; nxt_snd->inuse = false; sf->current_sound = NULL; if (nxt_snd->copy) nxt_snd = free_snd_data(nxt_snd); } sf->cbi++; if (sf->cbi >= (sf->current_state)->size) { reader_out_of_data(sf); return; } sf->cb = FRAGMENT((sf->current_state), sf->cbi); if ((!(sf->cb)) || (READER_SOUND(sf) == EDIT_LIST_END_MARK)) { reader_out_of_data(sf); return; } ind0 = READER_LOCAL_POSITION(sf); ind1 = READER_LOCAL_END(sf); sf->fscaler = READER_SCALER(sf); if (zero_op(READER_TYPE(sf))) { sf->current_sound = NULL; sf->loc = ind0; sf->first = ind0; sf->last = ind1; sf->data = NULL; } else { nxt_snd = sf->cp->sounds[READER_SOUND(sf)]; if (nxt_snd->type == SND_DATA_FILE) { if (nxt_snd->inuse) { nxt_snd = copy_snd_data(nxt_snd, ind0, FILE_BUFFER_SIZE); if (nxt_snd == NULL) { reader_out_of_data(sf); return; } } sf->data = nxt_snd->buffered_data; nxt_snd->inuse = true; sf->current_sound = nxt_snd; file_buffers_forward(ind0, ind1, ind0, sf, nxt_snd); } else { sf->data = nxt_snd->buffered_data; sf->loc = ind0; sf->first = ind0; sf->last = ind1; } } sf->frag_pos = 0; choose_accessor(sf); } else { mus_long_t indx; ind0 = READER_LOCAL_POSITION(sf); ind1 = READER_LOCAL_END(sf); indx = io_end(sf->current_sound->io) + 1; file_buffers_forward(ind0, ind1, indx, sf, sf->current_sound); } } static mus_float_t next_sound(snd_fd *sf) { next_sound_1(sf); return(read_sample(sf)); } void copy_then_swap_channels(chan_info *cp0, chan_info *cp1, int pos0, int pos1) { int i, fd, new0, new1; char *name; ed_list *new_ed, *old_ed; file_info *hdr0, *hdr1; peak_env_info *e0 = NULL, *e1 = NULL; if ((!(prepare_edit_list(cp0, AT_CURRENT_EDIT_POSITION, S_swap_channels))) || (!(prepare_edit_list(cp1, AT_CURRENT_EDIT_POSITION, S_swap_channels)))) return; name = cp0->sound->filename; hdr0 = copy_header(name, cp0->sound->hdr); fd = snd_open_read(name); snd_file_open_descriptors(fd, name, hdr0->sample_type, hdr0->data_location, hdr0->chans, hdr0->type); new0 = add_sound_file_to_edit_list(cp1, name, make_file_state(fd, hdr0, cp0->chan, 0, FILE_BUFFER_SIZE), hdr0, DONT_DELETE_ME, cp0->chan); name = cp1->sound->filename; hdr1 = copy_header(name, cp1->sound->hdr); fd = snd_open_read(name); snd_file_open_descriptors(fd, name, hdr1->sample_type, hdr1->data_location, hdr1->chans, hdr1->type); new1 = add_sound_file_to_edit_list(cp0, name, make_file_state(fd, hdr1, cp1->chan, 0, FILE_BUFFER_SIZE), hdr1, DONT_DELETE_ME, cp1->chan); e0 = peak_env_copy(cp0, false, pos0); if (e0) e1 = peak_env_copy(cp1, false, pos1); old_ed = cp1->edits[pos1]; new_ed = make_ed_list(old_ed->size); new_ed->edit_type = CHANGE_EDIT; new_ed->sound_location = new1; new_ed->edpos = pos1; new_ed->maxamp = old_ed->maxamp; new_ed->maxamp_position = old_ed->maxamp_position; new_ed->samples = old_ed->samples; new_ed->cursor = old_ed->cursor; new_ed->beg = 0; new_ed->len = old_ed->len; new_ed->origin = mus_strdup(to_proc_name(S_swap_channels)); cp0->edits[cp0->edit_ctr] = new_ed; if (new_ed->len > 0) for (i = 0; i < new_ed->size; i++) { copy_ed_fragment(FRAGMENT(new_ed, i), FRAGMENT(old_ed, i)); if (FRAGMENT_SOUND(new_ed, i) == 0) FRAGMENT_SOUND(new_ed, i) = new1; } old_ed = cp0->edits[pos0]; new_ed = make_ed_list(old_ed->size); new_ed->edit_type = CHANGE_EDIT; new_ed->sound_location = new0; new_ed->edpos = pos0; new_ed->maxamp = old_ed->maxamp; new_ed->maxamp_position = old_ed->maxamp_position; new_ed->beg = 0; new_ed->len = old_ed->len; new_ed->samples = old_ed->samples; new_ed->cursor = old_ed->cursor; new_ed->origin = mus_strdup(to_proc_name(S_swap_channels)); /* swap = stored change-edit at restore time, so no redundancy here */ cp1->edits[cp1->edit_ctr] = new_ed; if (new_ed->len > 0) for (i = 0; i < new_ed->size; i++) { copy_ed_fragment(FRAGMENT(new_ed, i), FRAGMENT(old_ed, i)); if (FRAGMENT_SOUND(new_ed, i) == 0) FRAGMENT_SOUND(new_ed, i) = new0; } if ((e0) && (e1)) { cp0->edits[cp0->edit_ctr]->peak_env = e1; cp1->edits[cp1->edit_ctr]->peak_env = e0; } else { if (e0) e0 = free_peak_env_info(e0); if (e1) e1 = free_peak_env_info(e1); } ripple_all(cp0, 0, 0); ripple_all(cp1, 0, 0); swap_marks(cp0, cp1); if (cp0->edits[cp0->edit_ctr]->samples != cp0->edits[cp0->edit_ctr - 1]->samples) reflect_sample_change_in_axis(cp0); if (cp1->edits[cp1->edit_ctr]->samples != cp1->edits[cp1->edit_ctr - 1]->samples) reflect_sample_change_in_axis(cp1); after_edit(cp0); after_edit(cp1); update_graph(cp0); update_graph(cp1); } io_error_t save_edits_and_update_display(snd_info *sp) { /* open temp, write current state, rename to old, reopen and clear all state */ /* can't overwrite current because we may have cut/paste backpointers scattered around the current edit list */ /* have to decide here what header/data type to write as well -- original? */ /* if latter, must be able to write all headers! -- perhaps warn user and use snd/aiff/riff/ircam */ /* read_only already checked */ char *ofile = NULL; int i; mus_long_t samples = 0; mus_long_t *old_cursors = NULL; void *ms; axes_data *sa; file_info *sphdr = NULL; io_error_t io_err = IO_NO_ERROR; snd_fd **sf; mus_float_t *vals = NULL; mus_long_t *times = NULL; bool have_maxamps = true; if (dont_save(sp, NULL)) return(IO_SAVE_HOOK_CANCELLATION); ofile = snd_tempnam(); /* this will use user's TMPDIR if temp_dir(ss) is not set, else stdio.h's P_tmpdir else /tmp */ for (i = 0; i < sp->nchans; i++) { chan_info *ncp; ncp = sp->chans[i]; if ((ed_maxamp(ncp, ncp->edit_ctr) < 0.0) || (ed_maxamp_position(ncp, ncp->edit_ctr) < 0)) { have_maxamps = false; break; } } if (have_maxamps) { vals = (mus_float_t *)calloc(sp->nchans, sizeof(mus_float_t)); times = (mus_long_t *)calloc(sp->nchans, sizeof(mus_long_t)); for (i = 0; i < sp->nchans; i++) { chan_info *ncp; ncp = sp->chans[i]; vals[i] = ed_maxamp(ncp, ncp->edit_ctr); times[i] = ed_maxamp_position(ncp, ncp->edit_ctr); } } sf = (snd_fd **)calloc(sp->nchans, sizeof(snd_fd *)); for (i = 0; i < sp->nchans; i++) { sf[i] = init_sample_read(0, sp->chans[i], READ_FORWARD); if (sf[i] == NULL) { int j; for (j = 0; j < i; j++) free_snd_fd(sf[j]); free(sf); if (vals) free(vals); if (times) free(times); return(IO_BAD_CHANNEL); } if (samples < current_samples(sp->chans[i])) samples = current_samples(sp->chans[i]); } /* write the new file */ io_err = snd_make_file(ofile, sp->nchans, sp->hdr, sf, samples, true); for (i = 0; i < sp->nchans; i++) free_snd_fd(sf[i]); free(sf); sf = NULL; if (io_err != IO_NO_ERROR) { if (ofile) free(ofile); if (vals) { free(vals); free(times); } return(io_err); } sa = make_axes_data(sp); sphdr = sp->hdr; sphdr->samples = samples * sp->nchans; ms = (void *)sound_store_marks(sp); old_cursors = (mus_long_t *)calloc(sp->nchans, sizeof(mus_long_t)); for (i = 0; i < sp->nchans; i++) { chan_info *cp; cp = sp->chans[i]; old_cursors[i] = cursor_sample(cp); /* depends on edit_ctr -- set to -1 by free_edit_list below */ if (ss->deferred_regions > 0) sequester_deferred_regions(cp, -1); if (cp->edits) free_edit_list(cp); /* sets cp->edits to NULL */ if (cp->sounds) free_sound_list(cp); cp->axis = free_axis_info(cp->axis); } #ifndef _MSC_VER if (access(sp->filename, W_OK)) { sa = free_axes_data(sa); if (ofile) free(ofile); if (old_cursors) free(old_cursors); if (vals) { free(vals); free(times); } return(IO_WRITE_PROTECTED); } #endif mus_sound_forget(sp->filename); sp->writing = true; io_err = move_file(ofile, sp->filename); /* should we cancel and restart a monitor? */ sp->writing = false; if (io_err != IO_NO_ERROR) { if (ofile) free(ofile); if (old_cursors) free(old_cursors); if (vals) { free(vals); free(times); } return(io_err); } if (vals) { mus_sound_set_maxamps(sp->filename, sp->nchans, vals, times); free(vals); free(times); } sp->write_date = file_write_date(sp->filename); add_sound_data(sp->filename, sp, WITHOUT_INITIAL_GRAPH_HOOK); restore_axes_data(sp, sa, mus_sound_duration(sp->filename), true); sound_restore_marks(sp, ms); sa = free_axes_data(sa); for (i = 0; i < sp->nchans; i++) cursor_sample(sp->chans[i]) = old_cursors[i]; free(old_cursors); reflect_file_revert_in_label(sp); if (ofile) { free(ofile); ofile = NULL; } if (!(ss->file_monitor_ok)) if (auto_update(ss)) for_each_sound(sound_not_current); return(IO_NO_ERROR); } io_error_t save_edits_without_display(snd_info *sp, const char *new_name, mus_header_t type, mus_sample_t sample_type, int srate, const char *comment, int pos) { /* assume we've already checked for (over)write permissions, and header-type+sample-type writable, */ file_info *hdr; snd_fd **sf; mus_long_t framples = 0; int i; file_info *ohdr; io_error_t err = IO_NO_ERROR; mus_float_t *vals = NULL; mus_long_t *times = NULL; bool have_maxamps = true; if (dont_save(sp, new_name)) return(IO_SAVE_HOOK_CANCELLATION); ohdr = sp->hdr; hdr = copy_header(new_name, ohdr); hdr->sample_type = sample_type; hdr->srate = srate; hdr->type = type; if (comment) hdr->comment = mus_strdup(comment); else hdr->comment = NULL; hdr->data_location = 0; /* in case comment changes it */ for (i = 0; i < sp->nchans; i++) { chan_info *ncp; ncp = sp->chans[i]; if ((ed_maxamp(ncp, ncp->edit_ctr) < 0.0) || (ed_maxamp_position(ncp, ncp->edit_ctr) < 0)) { have_maxamps = false; break; } } if (have_maxamps) { vals = (mus_float_t *)calloc(sp->nchans, sizeof(mus_float_t)); times = (mus_long_t *)calloc(sp->nchans, sizeof(mus_long_t)); for (i = 0; i < sp->nchans; i++) { chan_info *ncp; ncp = sp->chans[i]; vals[i] = ed_maxamp(ncp, ncp->edit_ctr); times[i] = ed_maxamp_position(ncp, ncp->edit_ctr); } } sf = (snd_fd **)malloc(sp->nchans * sizeof(snd_fd *)); for (i = 0; i < sp->nchans; i++) { chan_info *cp; int local_pos; cp = sp->chans[i]; if (pos == AT_CURRENT_EDIT_POSITION) local_pos = cp->edit_ctr; else local_pos = pos; if (framples < cp->edits[local_pos]->samples) framples = cp->edits[local_pos]->samples; sf[i] = init_sample_read_any(0, cp, READ_FORWARD, local_pos); if (sf[i] == NULL) { int k; /* this should not (cannot?) happen since we've supposedly checked before getting here... */ for (k = 0; k < sp->nchans; k++) sf[k] = free_snd_fd(sf[k]); free(sf); sf = NULL; hdr = free_file_info(hdr); if (vals) { free(vals); free(times); } return(err); } } err = snd_make_file(new_name, sp->nchans, hdr, sf, framples, true); if (vals) { if (err == IO_NO_ERROR) mus_sound_set_maxamps(new_name, sp->nchans, vals, times); free(vals); free(times); } for (i = 0; i < sp->nchans; i++) free_snd_fd(sf[i]); free(sf); free_file_info(hdr); return(err); } io_error_t save_channel_edits(chan_info *cp, const char *ofile, int pos) { /* channel extraction -- does not (normally) cause reversion of edits, or change of in-window file, etc */ snd_info *sp; io_error_t err = IO_NO_ERROR; sp = cp->sound; if (pos == AT_CURRENT_EDIT_POSITION) pos = cp->edit_ctr; if (mus_strcmp(ofile, sp->filename)) /* overwriting current file with one of its channels */ { char *nfile = NULL; if ((sp->user_read_only == FILE_READ_ONLY) || (sp->file_read_only == FILE_READ_ONLY)) { snd_error("can't save channel as %s (%s is write-protected)", ofile, sp->short_filename); return(IO_WRITE_PROTECTED); } nfile = snd_tempnam(); err = channel_to_file(cp, nfile, pos); /* snd_error unless MUS_INTERRUPTED (???) */ if (err == IO_NO_ERROR) { err = move_file(nfile, ofile); if (err == IO_NO_ERROR) snd_update(sp); else { if (is_serious_io_error(err)) { free(nfile); nfile = NULL; snd_error("save channel %s -> %s: %s (%s)", nfile, ofile, io_error_name(err), snd_io_strerror()); } } } if (nfile) free(nfile); } else err = channel_to_file(cp, ofile, pos); /* snd_error unless MUS_INTERRUPTED */ return(err); } bool has_unsaved_edits(snd_info *sp) { int i; for (i = 0; i < sp->nchans; i++) if (sp->chans[i]->edit_ctr > 0) return(true); return(false); } static io_error_t save_edits_1(snd_info *sp, bool ask) { io_error_t err; time_t current_write_date; if (sp == NULL) snd_error_without_format("save edits of null sound!"); if ((sp->user_read_only == FILE_READ_ONLY) || (sp->file_read_only == FILE_READ_ONLY)) return(IO_WRITE_PROTECTED); if (!(has_unsaved_edits(sp))) return(IO_NO_CHANGES); /* check for change to file while we were editing it */ current_write_date = file_write_date(sp->filename); /* returns -1 if file does not exist (stat -> -1) */ if (current_write_date < 0) { snd_error("can't save edits; %s has disappeared!", sp->filename); /* unless by chance it fits in one in-core buffer, there's nothing we can do now */ return(IO_CANT_OPEN_FILE); } if ((ask) && ((current_write_date - sp->write_date) > 1)) /* In Redhat 7.1 these can differ by 1?? Surely this is a bug! */ return(IO_NEED_WRITE_CONFIRMATION); /* see snd-kbd.c save_edits_from_kbd for the rest of this */ /* this used to include ask_before_overwrite, but I don't think that is relevant. If the file * has changed from what we think it is, we have a problem -- the save is unlikely to do anything useful. */ err = save_edits_and_update_display(sp); if (err == IO_NO_ERROR) { if (sp->edited_region) save_region_backpointer(sp); /* region edit save is not reflected in other sounds because the region is a separate thing from the selection */ } return(err); } io_error_t save_edits(snd_info *sp) { return(save_edits_1(sp, true)); } io_error_t save_edits_without_asking(snd_info *sp) { return(save_edits_1(sp, false)); } void revert_edits(chan_info *cp) { if (cp->edit_ctr == 0) return; cp->edit_ctr = 0; clear_transform_edit_ctrs(cp); reflect_edit_counter_change(cp); reflect_sample_change_in_axis(cp); enved_reflect_selection(selection_is_active()); reflect_selection_in_save_as_dialog(selection_is_active()); if (Xen_hook_has_list(ss->effects_hook)) run_hook(ss->effects_hook, Xen_empty_list, S_effects_hook); update_graph(cp); reflect_mix_change(ANY_MIX_ID); reflect_enved_fft_change(cp); if ((cp->hookable == WITH_HOOK) && (Xen_is_hook(cp->undo_hook)) && (Xen_hook_has_list(cp->undo_hook))) run_hook(cp->undo_hook, Xen_empty_list, S_undo_hook); } /* how to handle something like safe-map-channel that wants to disallow undo? */ bool undo_edit(chan_info *cp, int count) { if ((cp) && (cp->edit_ctr > 0) && (count != 0)) { snd_info *sp; sp = cp->sound; cp->edit_ctr -= count; if (cp->edit_ctr < 0) cp->edit_ctr = 0; clear_transform_edit_ctrs(cp); reflect_edit_counter_change(cp); reflect_sample_change_in_axis(cp); enved_reflect_selection(selection_is_active()); reflect_selection_in_save_as_dialog(selection_is_active()); if (cp->edit_ctr == 0) { reflect_file_revert_in_label(sp); } if (Xen_hook_has_list(ss->effects_hook)) run_hook(ss->effects_hook, Xen_empty_list, S_effects_hook); update_graph(cp); reflect_mix_change(ANY_MIX_ID); reflect_enved_fft_change(cp); if ((cp->hookable == WITH_HOOK) && (Xen_is_hook(cp->undo_hook)) && (Xen_hook_has_list(cp->undo_hook))) run_hook(cp->undo_hook, Xen_empty_list, S_undo_hook); return(true); } return(false); } bool undo_edit_with_sync(chan_info *cp, int count) { /* there is a problem with syncd undo: if the syncd edit decided one portion * was a no-op (scale by 1.0 etc), but not another, a subsequent undo with * sync can end up in a state different from where it started. */ if (count == 0) return(false); if (count < 0) return(redo_edit_with_sync(cp, -count)); else { if (cp) { snd_info *sp; sync_info *si = NULL; sp = cp->sound; if (sp->sync != 0) si = snd_sync(sp->sync); if (si) { bool something_changed = false; int i; for (i = 0; i < si->chans; i++) if (undo_edit(si->cps[i], count)) something_changed = true; si = free_sync_info(si); return(something_changed); } else return(undo_edit(cp, count)); } } return(false); } bool redo_edit(chan_info *cp, int count) { /* returns true if an edit history change occurred */ if ((cp) && (count != 0)) { int old_edit_ctr; old_edit_ctr = cp->edit_ctr; cp->edit_ctr += count; if (cp->edit_ctr >= cp->edit_size) cp->edit_ctr = cp->edit_size - 1; while (!(cp->edits[cp->edit_ctr])) cp->edit_ctr--; if ((cp->edit_ctr != 0) && /* possibly a sync'd redo to chan that has no edits */ (cp->edit_ctr != old_edit_ctr)) /* or attempt to redo when nothing to redo */ { clear_transform_edit_ctrs(cp); reflect_file_change_in_label(cp); reflect_edit_counter_change(cp); reflect_sample_change_in_axis(cp); enved_reflect_selection(selection_is_active()); reflect_selection_in_save_as_dialog(selection_is_active()); if (Xen_hook_has_list(ss->effects_hook)) run_hook(ss->effects_hook, Xen_empty_list, S_effects_hook); update_graph(cp); reflect_mix_change(ANY_MIX_ID); reflect_enved_fft_change(cp); if ((cp->hookable == WITH_HOOK) && (Xen_is_hook(cp->undo_hook)) && (Xen_hook_has_list(cp->undo_hook))) run_hook(cp->undo_hook, Xen_empty_list, S_undo_hook); return(true); } } return(false); } bool redo_edit_with_sync(chan_info *cp, int count) { if (count == 0) return(false); if (count < 0) return(undo_edit_with_sync(cp, -count)); else { if (cp) { snd_info *sp; sync_info *si = NULL; sp = cp->sound; if (sp->sync != 0) si = snd_sync(sp->sync); if (si) { bool something_changed = false; int i; for (i = 0; i < si->chans; i++) if (redo_edit(si->cps[i], count)) something_changed = true; si = free_sync_info(si); return(something_changed); } else return(redo_edit(cp, count)); } } return(false); } /* -------------------- virtual mixes -------------------- */ /* ramp on mix is technically possible, but ambiguous -- currently if we mix, then ramp elsewhere, then drag the mix * to the ramped portion, the mix treats the ramp as prior data (adding); if we had ramp_mix, it would want to * treat that ramp as an envelope on the mix if the ramp happened after the mix was established but as data if before. * Too tricky. (We'd also need ED_RAMP_ZERO to make clean fixups upon drag and so on). * Three times and out so far... * ... * but, if the envelope is global, it is not ambiguous, (except that we have scaled portions?) -- * still the ramp-but-no-mix sections need special handling (ramp_mix with 0 mixes?), * as do the ramp-as-scale-but-no-mix portions (scale_mix? -- confusing name) * ... * this (ramp_mix as edit with locked mixes) turned out to be too tricky -- scaling especially is a mess. * (scaling can't be globalized without saving the pre-mix scaler on every mix, for a start) */ static void make_mix_fragment(ed_list *new_ed, int i, mix_state *ms) { ed_mixes *mxs; int mloc = -1; /* mix_loc = index into cp->sound arrays for reading the mixed-in data (buffer or file) */ /* i = index into ed_fragment list for this edit */ /* we're changing one fragment to add the mix */ FRAGMENT_TYPE(new_ed, i) = type_info[FRAGMENT_TYPE(new_ed, i)].add_mix; if (!(FRAGMENT_MIXES(new_ed, i))) FRAGMENT_MIXES(new_ed, i) = (ed_mixes *)calloc(1, sizeof(ed_mixes)); mxs = FRAGMENT_MIXES(new_ed, i); if (mxs->size == 0) { mxs->size = 1; mxs->mix_list = (mix_state **)malloc(sizeof(mix_state *)); mloc = 0; } else { int j; for (j = 0; j < mxs->size; j++) if (MIX_LIST_STATE(mxs, j) == NULL) { mloc = j; break; } if (mloc == -1) { mloc = mxs->size; mxs->size++; mxs->mix_list = (mix_state **)realloc(mxs->mix_list, mxs->size * sizeof(mix_state *)); } } MIX_LIST_STATE(mxs, mloc) = ms; } static ed_list *make_mix_edit(ed_list *old_ed, mus_long_t beg, mus_long_t len, mix_state *ms, bool full_fragment) { ed_list *new_ed; int i; if (full_fragment) { new_ed = make_ed_list(old_ed->size); new_ed->beg = 0; new_ed->len = len; for (i = 0; i < new_ed->size; i++) /* whole file changed in this case */ { copy_ed_fragment(FRAGMENT(new_ed, i), FRAGMENT(old_ed, i)); if (i < new_ed->size - 1) make_mix_fragment(new_ed, i, ms); } } else { new_ed = copy_and_split_list(beg, len, old_ed); for (i = 0; i < new_ed->size; i++) { if (FRAGMENT_GLOBAL_POSITION(new_ed, i) > (beg + len - 1)) break; /* not >= (1 sample selections) */ if ((FRAGMENT_GLOBAL_POSITION(new_ed, i) >= beg) && (i < new_ed->size - 1)) make_mix_fragment(new_ed, i, ms); } } new_ed->cursor = old_ed->cursor; new_ed->edit_type = MIX_EDIT; new_ed->sound_location = old_ed->sound_location; new_ed->selection_beg = old_ed->selection_beg; new_ed->selection_end = old_ed->selection_end; return(new_ed); } int mix_file_with_tag(chan_info *cp, const char *filename, int chan, mus_long_t beg, file_delete_t auto_delete, const char *origin) { mus_long_t file_len, old_len, new_len; int edpos; int fd, mix_loc; ed_list *new_ed, *old_ed; file_info *hdr; mix_state *ms; bool backup = false; hdr = make_file_info(filename, FILE_READ_ONLY, FILE_NOT_SELECTED); if (chan >= hdr->chans) return(NO_MIX_TAG); edpos = cp->edit_ctr; file_len = mus_sound_framples(filename); old_ed = cp->edits[edpos]; if ((beg < 0) || (file_len <= 0)) return(NO_MIX_TAG); old_len = old_ed->samples; if (beg + file_len > old_len) { if (!(extend_with_zeros(cp, old_len, beg + file_len - old_len, edpos, origin))) return(NO_MIX_TAG); edpos = cp->edit_ctr; new_len = beg + file_len; old_ed = cp->edits[edpos]; backup = true; } else new_len = old_len; if (!(prepare_edit_list(cp, edpos, origin))) return(NO_MIX_TAG); fd = snd_open_read(filename); snd_file_open_descriptors(fd, filename, hdr->sample_type, hdr->data_location, hdr->chans, hdr->type); mix_loc = add_sound_file_to_edit_list(cp, filename, make_file_state(fd, hdr, chan, 0, FILE_BUFFER_SIZE), hdr, auto_delete, chan); ms = prepare_mix_state_for_channel(cp, mix_loc, beg, file_len); new_ed = make_mix_edit(old_ed, beg, file_len, ms, ((beg == 0) && (file_len >= old_len))); new_ed->samples = new_len; new_ed->origin = mus_strdup(origin); new_ed->edpos = edpos; cp->edits[cp->edit_ctr] = new_ed; add_ed_mix(cp->edits[cp->edit_ctr], ms); ripple_all(cp, 0, 0); /* 0,0 -> copy marks */ reflect_mix_change(ANY_MIX_ID); after_edit(cp); if (backup) backup_edit_list(cp); return(ms->mix_id); } int mix_buffer_with_tag(chan_info *cp, mus_float_t *data, mus_long_t beg, mus_long_t buf_len, const char *origin) { int edpos, mix_loc; mus_long_t old_len, new_len; ed_list *old_ed, *new_ed; bool backup = false; mix_state *ms; edpos = cp->edit_ctr; old_ed = cp->edits[edpos]; if ((beg < 0) || (buf_len == 0)) return(NO_MIX_TAG); old_len = old_ed->samples; if (beg + buf_len > old_len) { if (!(extend_with_zeros(cp, old_len, beg + buf_len - old_len, edpos, origin))) return(NO_MIX_TAG); edpos = cp->edit_ctr; new_len = beg + buf_len; old_ed = cp->edits[edpos]; backup = true; } else new_len = old_len; if (!(prepare_edit_list(cp, edpos, origin))) return(NO_MIX_TAG); prepare_sound_list(cp); cp->sounds[cp->sound_ctr] = make_snd_data_buffer(data, (int)buf_len, cp->edit_ctr); mix_loc = cp->sound_ctr; ms = prepare_mix_state_for_channel(cp, mix_loc, beg, buf_len); new_ed = make_mix_edit(old_ed, beg, buf_len, ms, ((beg == 0) && (buf_len >= old_len))); new_ed->samples = new_len; new_ed->origin = mus_strdup(origin); new_ed->edpos = edpos; cp->edits[cp->edit_ctr] = new_ed; add_ed_mix(cp->edits[cp->edit_ctr], ms); ripple_all(cp, 0, 0); /* 0,0 -> copy marks */ reflect_mix_change(ANY_MIX_ID); after_edit(cp); if (backup) backup_edit_list(cp); return(ms->mix_id); } void unmix(chan_info *cp, mix_state *ms) { /* assume both mix_list (via ripple) and ed fragments list are ready for the unmix */ /* used in set position and set speed (snd-mix) to remove ms prior to the edit/remix */ int i; ed_list *ed; ed = cp->edits[cp->edit_ctr]; for (i = 0; i < ed->size; i++) { if ((FRAGMENT_GLOBAL_POSITION(ed, i) >= ms->beg) && (FRAGMENT_GLOBAL_POSITION(ed, i) < (ms->beg + ms->len)) && (is_unmixable_op(FRAGMENT_TYPE(ed, i)))) { /* look for ms in the current fragment's mix list */ int j, remaining_mixes = 0, mss_size; ed_mixes *mxl; mix_state **mss; mxl = FRAGMENT_MIXES(ed, i); mss = FRAGMENT_MIX_LIST(ed, i); mss_size = FRAGMENT_MIX_LIST_SIZE(ed, i); for (j = 0; j < mss_size; j++) if (mss[j]) { if (mss[j]->index == ms->index) mss[j] = NULL; else remaining_mixes++; } if (remaining_mixes == 0) { FRAGMENT_TYPE(ed, i) = type_info[FRAGMENT_TYPE(ed, i)].subtract_mix; free(mss); free(mxl); FRAGMENT_MIXES(ed, i) = NULL; } } } } void remix(chan_info *cp, mix_state *ms) { int i; ed_list *new_ed; new_ed = cp->edits[cp->edit_ctr]; for (i = 0; i < new_ed->size; i++) { if (FRAGMENT_GLOBAL_POSITION(new_ed, i) > (ms->beg + ms->len - 1)) break; /* not >= (1 sample selections) */ if (FRAGMENT_GLOBAL_POSITION(new_ed, i) >= ms->beg) make_mix_fragment(new_ed, i, ms); } } static void ripple_mixes_1(chan_info *cp, mus_long_t beg, mus_long_t len, mus_long_t change, mus_float_t scl) { /* this is where most of the time goes in mixing! */ if ((cp) && (cp->edit_ctr > 0)) { ed_list *ed; int i, low_id = 0, high_id = 0, size = 0; /* low_id confuses the compiler, but it will always get set below (current_states starts NULL etc) */ mix_state **current_states = NULL; ed = cp->edits[cp->edit_ctr]; /* this may have mixes already (current op was mix op) or might be null */ for (i = 0; i < ed->size; i++) { if ((FRAGMENT_MIXES(ed, i)) && (FRAGMENT_MIX_LIST(ed, i)) && (FRAGMENT_MIX_LIST_SIZE(ed, i) > 0)) { int j; if (current_states == NULL) { low_id = lowest_mix_id(); high_id = highest_mix_id(); size = high_id - low_id + 1; current_states = (mix_state **)calloc(size, sizeof(mix_state *)); preload_mixes(current_states, low_id, ed); } for (j = 0; j < FRAGMENT_MIX_LIST_SIZE(ed, i); j++) { mix_state *old_ms; old_ms = FRAGMENT_MIX_STATE(ed, i, j); /* the old copy -- we (may) need to make a new one */ if (old_ms) { mix_state *new_ms; new_ms = current_states[old_ms->mix_id - low_id]; if (!new_ms) { new_ms = copy_mix_state(old_ms); /* cannot return null unless we're out of memory */ add_ed_mix(ed, new_ms); if (new_ms->beg >= beg) { if ((len != 0) && (new_ms->beg < beg + len)) new_ms->scaler *= scl; if (change != 0) new_ms->beg += change; } } FRAGMENT_MIX_STATE(ed, i, j) = new_ms; if (((new_ms->mix_id - low_id) < size) && ((new_ms->mix_id - low_id) >= 0)) current_states[new_ms->mix_id - low_id] = new_ms; } } } } if (current_states) free(current_states); } } static void ripple_mixes(chan_info *cp, mus_long_t beg, mus_long_t change) { ripple_mixes_1(cp, beg, 0, change, 1.0); } static void ripple_mixes_with_scale(chan_info *cp, mus_long_t beg, mus_long_t len, mus_float_t scl) { ripple_mixes_1(cp, beg, len, 0, scl); } snd_fd *make_virtual_mix_reader(chan_info *cp, mus_long_t beg, mus_long_t len, int index, mus_float_t scl, read_direction_t direction) { snd_fd *sf; snd_data *first_snd = NULL; mus_long_t ind0, ind1, indx; sf = (snd_fd *)calloc(1, sizeof(snd_fd)); sf->freed = false; sf->region = INVALID_MIX_ID; sf->type = MIX_READER; sf->initial_samp = beg; sf->cp = cp; sf->direction = direction; sf->current_state = initial_ed_list(0, len - 1); /* need size field here to signal eof -- GC'd in free_reader_mixes */ sf->cb = FRAGMENT(sf->current_state, 0); sf->edit_ctr = 0; first_snd = cp->sounds[index]; sf->frag_pos = 0; ind0 = 0; indx = beg; ind1 = len - 1; /* ind1 (LOCAL_END...) is a sample number, not a length */ sf->fscaler = scl; if ((scl == 1.0) && (sf->fscaler == 1.0)) { sf->runf = next_sample_value_unscaled; sf->rev_runf = previous_sample_value_unscaled; } else { if (scl == 0.0) { sf->runf = next_zero; sf->rev_runf = previous_zero; } else { sf->runf = next_sample_value; sf->rev_runf = previous_sample_value; } } if (direction == READ_BACKWARD) swap_readers(sf); if (first_snd->type == SND_DATA_FILE) { if (first_snd->inuse) { first_snd = copy_snd_data(first_snd, beg, FILE_BUFFER_SIZE); if (!first_snd) return(cancel_reader(sf)); } first_snd->inuse = true; sf->current_sound = first_snd; sf->data = first_snd->buffered_data; if (direction == READ_FORWARD) file_buffers_forward(ind0, ind1, indx, sf, first_snd); else file_buffers_back(ind0, ind1, indx, sf, first_snd); } else { sf->current_sound = NULL; sf->data = first_snd->buffered_data; sf->first = ind0; sf->last = ind1; sf->loc = indx; } return(sf); } bool begin_mix_op(chan_info *cp, mus_long_t old_beg, mus_long_t old_len, mus_long_t new_beg, mus_long_t new_len, int edpos, const char *caller) { int i; ed_list *new_ed, *old_ed, *temp_ed; mus_long_t new_samples; old_ed = cp->edits[edpos]; if (!(prepare_edit_list(cp, edpos, caller))) return(false); new_samples = new_beg + new_len; if (new_samples > old_ed->samples) { ed_fragment *cb; mus_long_t old_pos; cb = make_ed_fragment(); old_pos = FRAGMENT_GLOBAL_POSITION(old_ed, old_ed->size - 1); temp_ed = make_ed_list(old_ed->size + 1); for (i = 0; i < old_ed->size; i++) copy_ed_fragment(FRAGMENT(temp_ed, i), FRAGMENT(old_ed, i)); FRAGMENT_GLOBAL_POSITION(temp_ed, old_ed->size - 1) = new_samples + 1; if (FRAGMENT(temp_ed, old_ed->size)) free_ed_fragment(FRAGMENT(temp_ed, old_ed->size)); FRAGMENT(temp_ed, old_ed->size) = FRAGMENT(temp_ed, old_ed->size - 1); FRAGMENT(temp_ed, old_ed->size - 1) = cb; ED_SOUND(cb) = EDIT_LIST_ZERO_MARK; ED_SCALER(cb) = 0.0; ED_TYPE(cb) = ED_ZERO; ED_GLOBAL_POSITION(cb) = old_pos; ED_LOCAL_POSITION(cb) = 0; ED_LOCAL_END(cb) = new_samples - old_ed->samples; } else temp_ed = old_ed; if ((new_beg == old_beg) && (new_len == old_len)) { if (temp_ed != old_ed) new_ed = temp_ed; else { new_ed = make_ed_list(temp_ed->size); for (i = 0; i < temp_ed->size; i++) copy_ed_fragment(FRAGMENT(new_ed, i), FRAGMENT(temp_ed, i)); } new_ed->beg = new_beg; new_ed->len = new_len; } else { mus_long_t old_end, new_end; new_ed = copy_and_split_list(new_beg, new_len, temp_ed); if (temp_ed != old_ed) { for (i = 0; i < temp_ed->allocated_size; i++) free_ed_fragment(FRAGMENT(temp_ed, i)); free(FRAGMENTS(temp_ed)); free(temp_ed); } old_end = old_beg + old_len; new_end = new_beg + new_len; if (old_beg < new_beg) new_ed->beg = old_beg; else new_ed->beg = new_beg; if (old_end > new_end) new_ed->len = old_end - new_ed->beg + 1; else new_ed->len = new_end - new_ed->beg + 1; } if (new_samples > old_ed->samples) new_ed->samples = new_samples; else new_ed->samples = old_ed->samples; new_ed->cursor = old_ed->cursor; new_ed->edit_type = CHANGE_MIX_EDIT; new_ed->sound_location = old_ed->sound_location; new_ed->origin = mus_strdup(caller); new_ed->edpos = edpos; new_ed->selection_beg = old_ed->selection_beg; new_ed->selection_end = old_ed->selection_end; cp->edits[cp->edit_ctr] = new_ed; ripple_all(cp, 0, 0); /* 0,0 -> copy current mix (and mark) lists */ return(true); } static int check_splice_at(ed_list *new_ed, mus_long_t beg, int start) { int i; for (i = start; i < new_ed->size; i++) { if ((FRAGMENT_GLOBAL_POSITION(new_ed, i) == beg) && ((FRAGMENT_TYPE(new_ed, i) == ED_SIMPLE) || (FRAGMENT_TYPE(new_ed, i) == ED_ZERO)) && (FRAGMENT_TYPE(new_ed, i - 1) == FRAGMENT_TYPE(new_ed, i)) && (FRAGMENT_SOUND(new_ed, i) == FRAGMENT_SOUND(new_ed, i - 1)) && (FRAGMENT_SCALER(new_ed, i) == FRAGMENT_SCALER(new_ed, i -1)) && (FRAGMENT_LOCAL_END(new_ed, i - 1) == FRAGMENT_LOCAL_POSITION(new_ed, i) - 1)) { int k; FRAGMENT_LOCAL_END(new_ed, i - 1) = FRAGMENT_LOCAL_END(new_ed, i); free_ed_fragment(FRAGMENT(new_ed, i)); for (k = i + 1; k < new_ed->size; k++) FRAGMENT(new_ed, k - 1) = FRAGMENT(new_ed, k); FRAGMENT(new_ed, new_ed->size - 1) = NULL; new_ed->size--; return(i); } } return(0); } void end_mix_op(chan_info *cp, mus_long_t old_beg, mus_long_t old_len) { /* if beg != 0, try to remove old splice points */ if (old_beg > 0) { int start_loc; ed_list *new_ed; new_ed = cp->edits[cp->edit_ctr]; start_loc = check_splice_at(new_ed, old_beg, 1); if (old_len > 0) check_splice_at(new_ed, old_beg + old_len, start_loc); } if (cp->edits[cp->edit_ctr - 1]->samples != cp->edits[cp->edit_ctr]->samples) reflect_sample_change_in_axis(cp); reflect_mix_change(ANY_MIX_ID); } /* ----------------------- Xen connection -------------------------------- */ static Xen g_display_edits(Xen snd, Xen chn, Xen edpos) { #define H_display_edits "(" S_display_edits " :optional snd chn edpos): current edit tree" FILE *tmp = NULL; char *buf, *name; chan_info *cp; int fd, pos = AT_CURRENT_EDIT_POSITION; mus_long_t len; Xen res; ssize_t bytes; Snd_assert_channel(S_display_edits, snd, chn, 1); cp = get_cp(snd, chn, S_display_edits); if (!cp) return(Xen_false); if (Xen_is_integer(edpos)) { pos = Xen_integer_to_C_int(edpos); if (pos == AT_CURRENT_EDIT_POSITION) pos = cp->edit_ctr; if ((pos < 0) || (pos >= cp->edit_size) || (!(cp->edits[pos]))) Xen_error(NO_SUCH_EDIT, Xen_list_2(C_string_to_Xen_string(S_display_edits ": no such edit: ~A"), edpos)); } name = snd_tempnam(); tmp = FOPEN(name, "w"); if (tmp) { if (pos != AT_CURRENT_EDIT_POSITION) display_ed_list(cp, tmp, pos, cp->edits[pos]); else display_edits(cp, tmp); snd_fclose(tmp, name); } else Xen_error(CANNOT_SAVE, Xen_list_3(C_string_to_Xen_string(S_display_edits ": can't save ~S, ~A"), C_string_to_Xen_string(name), C_string_to_Xen_string(snd_io_strerror()))); fd = mus_file_open_read(name); len = lseek(fd, 0L, SEEK_END); buf = (char *)calloc(len + 1, sizeof(char)); lseek(fd, 0L, SEEK_SET); bytes = read(fd, buf, len); snd_close(fd, name); snd_remove(name, IGNORE_CACHE); if (name) free(name); if (bytes != 0) res = C_string_to_Xen_string(buf); else res = C_string_to_Xen_symbol("read-error"); free(buf); return(res); } static Xen g_edit_fragment(Xen uctr, Xen snd, Xen chn) { #define H_edit_fragment "(" S_edit_fragment " :optional (ctr " S_current_edit_position ") snd chn): edit history entry at ctr \ associated with snd's channel chn; the returned value is a list (origin type start-sample samps)" chan_info *cp; int ctr; Snd_assert_channel(S_edit_fragment, snd, chn, 2); Xen_check_type(Xen_is_integer_or_unbound(uctr), uctr, 1, S_edit_fragment, "an integer"); cp = get_cp(snd, chn, S_edit_fragment); if (!cp) return(Xen_false); ctr = (Xen_is_integer(uctr)) ? Xen_integer_to_C_int(uctr) : cp->edit_ctr; if ((ctr < cp->edit_size) && (ctr >= 0)) { ed_list *ed; ed = cp->edits[ctr]; if (ed) return(Xen_list_4(C_string_to_Xen_string(ed->origin), C_string_to_Xen_string(edit_names[(int)(ed->edit_type)]), C_llong_to_Xen_llong(ed->beg), C_llong_to_Xen_llong(ed->len))); } Xen_error(NO_SUCH_EDIT, Xen_list_2(C_string_to_Xen_string(S_edit_fragment ": no such edit ~A"), uctr)); return(uctr); } static Xen g_edit_tree(Xen snd, Xen chn, Xen upos) { #define H_edit_tree "(" S_edit_tree " :optional snd chn edpos): \ the edit lists '((global-pos data-num local-pos local-end scaler rmp0 rmp1 type-name)...)" /* internal debugging (auto-test) aid -- return complete ed list at pos */ int i, len, pos; chan_info *cp; ed_list *eds; Xen res = Xen_empty_list; Snd_assert_channel(S_edit_tree, snd, chn, 1); cp = get_cp(snd, chn, S_edit_tree); if (!cp) return(Xen_false); pos = to_c_edit_position(cp, upos, S_edit_tree, 3); eds = cp->edits[pos]; len = eds->size; /* fragments in this list */ for (i = len - 1; i >= 0; i--) { ed_fragment *ed; mus_float_t rbeg, rend; ed = FRAGMENT(eds, i); if ((ED_RAMPS(ed)) && (ED_RAMP_LIST_SIZE(ed) > 0)) { /* this is how it used to work -- kinda dumb -- also we need the op name, not the number */ rbeg = ED_RAMP_START(ed, 0); rend = ED_RAMP_INCR(ed, 0); } else { rbeg = 0.0; rend = 0.0; } res = Xen_cons(Xen_list_8(C_llong_to_Xen_llong(ED_GLOBAL_POSITION(ed)), C_int_to_Xen_integer(ED_SOUND(ed)), C_llong_to_Xen_llong(ED_LOCAL_POSITION(ed)), C_llong_to_Xen_llong(ED_LOCAL_END(ed)), C_double_to_Xen_real(ED_SCALER(ed)), C_double_to_Xen_real(rbeg), C_double_to_Xen_real(rend), C_int_to_Xen_integer(ED_TYPE(ed))), res); } return(res); } #define S_edit_fragment_type_name "edit-fragment-type-name" static Xen g_edit_fragment_type_name(Xen type) { int typ; Xen_check_type(Xen_is_integer(type), type, 1, S_edit_fragment_type_name, "an int"); typ = Xen_integer_to_C_int(type); if ((typ >= 0) && (typ < NUM_OPS)) return(C_string_to_Xen_string(type_info[typ].name)); return(Xen_false); } /* ---------------- samplers ---------------- */ static Xen_object_type_t sf_tag; bool is_sampler(Xen obj) {return(Xen_c_object_is_type(obj, sf_tag));} #define is_any_sampler(Obj) ((is_sampler(Obj)) || (is_mix_sampler(Obj))) snd_fd *xen_to_sampler(Xen obj) {if (is_sampler(obj)) return((snd_fd *)Xen_object_ref(obj)); else return(NULL);} #define Xen_to_C_sampler(obj) ((snd_fd *)Xen_object_ref(obj)) #if HAVE_SCHEME static bool s7_equalp_sf(void *s1, void *s2) { return(s1 == s2); } static s7_pointer length_sf(s7_scheme *sc, s7_pointer obj) { snd_fd *fd; fd = (snd_fd *)s7_object_value(obj); return(s7_make_integer(sc, current_samples(fd->cp))); } #endif char *sampler_to_string(snd_fd *fd) { char *desc; chan_info *cp; #if HAVE_SCHEME desc = (char *)calloc(PRINT_BUFFER_SIZE, sizeof(char)); #else desc = (char *)calloc(PRINT_BUFFER_SIZE, sizeof(char)); #endif if (fd == NULL) snprintf(desc, PRINT_BUFFER_SIZE, "#"); else { const char *name = NULL; cp = fd->cp; if ((fd->local_sp) && (fd->local_sp->hdr)) name = (const char *)(((fd->local_sp)->hdr)->name); else { if ((cp) && (cp->sound) && (cp->active >= CHANNEL_HAS_EDIT_LIST) && (!(fd->at_eof))) { if (fd->type == SAMPLER) { name = cp->sound->short_filename; if (name == NULL) switch (cp->sound->inuse) { case SOUND_IDLE: name = "idle source"; break; case SOUND_NORMAL: name = "unknown source"; break; case SOUND_WRAPPER: name = "wrapped source"; break; case SOUND_REGION: name = "region as source"; break; case SOUND_READER: name = "readable source"; break; } } else name = "region as source"; } } if (name == NULL) name = "unknown source"; if (fd->at_eof) snprintf(desc, PRINT_BUFFER_SIZE, "#", name); else { if (cp) snprintf(desc, PRINT_BUFFER_SIZE, "#", name, cp->chan, fd->edit_ctr, fd->initial_samp, current_location(fd), (fd->direction == READ_BACKWARD) ? "backward" : "forward"); else snprintf(desc, PRINT_BUFFER_SIZE, "#", name, fd->initial_samp, current_location(fd), (fd->direction == READ_BACKWARD) ? "backward" : "forward"); } } return(desc); } Xen_wrap_print(snd_fd, print_sf, sampler_to_string) /* make-sampler can refer to any edit of any sound, user can subsequently * either clobber that edit (undo, new edit), or close the sound, but forget * that the reader is now invalid. So, we keep a list of these and unconnect * them by hand when an edit is pruned or a sound is closed. * * channel|sound-properties are ok in this regard because the variable stays in * xen and is merely cleared, not freed at the C level. */ static void list_reader(snd_fd *fd) { ed_list *ed; ed = fd->current_state; if (ed) { int loc = -1; sf_info *lst = NULL; if (ed->readers == NULL) { ed->readers = (void *)calloc(1, sizeof(sf_info)); lst = (sf_info *)(ed->readers); lst->size = 2; lst->rds = (snd_fd **)calloc(2, sizeof(snd_fd *)); loc = 0; } else { int i; lst = (sf_info *)(ed->readers); for (i = 0; i < lst->size; i++) if (!(lst->rds[i])) { loc = i; break; } if (loc == -1) { loc = lst->size; lst->size *= 2; lst->rds = (snd_fd **)realloc(lst->rds, lst->size * sizeof(snd_fd *)); for (i = loc; i < lst->size; i++) lst->rds[i] = NULL; } } lst->rds[loc] = fd; } else fprintf(stderr, "can't list reader?"); } static void unlist_reader(snd_fd *fd) { if ((fd) && (!(fd->freed)) && (fd->cp) && (fd->cp->active >= CHANNEL_HAS_EDIT_LIST) && (fd->current_state) && (fd->current_state->readers)) { int i; ed_list *ed; sf_info *lst; ed = fd->current_state; lst = (sf_info *)(ed->readers); for (i = 0; i < lst->size; i++) if (fd == lst->rds[i]) lst->rds[i] = NULL; } /* unlist and read can be called on fully freed xen-allocated readers accessed through mixing, * but this happens only if the underlying sound has been closed -- nutty cases at the end * of snd-test.scm -- Snd goes on, but valgrind complains about it. I don't think this is * a bug, since we're deliberately breaking the rules, so to speak. */ } static void sf_free(snd_fd *fd) { if (fd) { snd_info *sp = NULL; /* changed to reflect g_free_sampler 29-Oct-00 */ unlist_reader(fd); sp = fd->local_sp; fd->local_sp = NULL; free_snd_fd(fd); if (sp) completely_free_snd_info(sp); } } Xen_wrap_free(snd_fd, free_sf, sf_free) /* sf_free is original, free_sf is wrapped form */ static Xen g_sampler_at_end(Xen obj) { #define H_sampler_at_end "(" S_is_sampler_at_end " obj): " PROC_TRUE " if sampler has reached the end of its data" Xen_check_type(is_any_sampler(obj), obj, 1, S_is_sampler_at_end, "a sampler (of any kind)"); if (is_sampler(obj)) { snd_fd *sf; sf = Xen_to_C_sampler(obj); return(C_bool_to_Xen_boolean(sf->at_eof)); } if (is_mix_sampler(obj)) return(g_mix_sampler_is_at_end(obj)); return(Xen_false); } /* can sampler-position be settable? * this requires that we find the fragment that holds the new position (as at the start of init_sample_read_any_with_bufsize 6892) * set the fragment bounds (ind0, ind1), call file_buffers_forward|backward * also check for reader_out_of_data complications, etc * so, it's simpler and just as fast to require that the user make a new reader or use random access (channel->vct) * (the only thing we avoid is choose_accessor) */ static Xen g_sampler_position(Xen obj) { #define H_sampler_position "(" S_sampler_position " obj): current (sample-wise) location of sampler" Xen_check_type(is_any_sampler(obj), obj, 1, S_sampler_position, "a sampler (of any kind)"); if (is_sampler(obj)) { snd_fd *fd = NULL; fd = Xen_to_C_sampler(obj); if (fd->at_eof) return(Xen_integer_zero); /* -1? framples? */ if ((fd->cp) && (fd->cp->active >= CHANNEL_HAS_EDIT_LIST) && (fd->cp->sound)) { if (fd->type == SAMPLER) return(C_llong_to_Xen_llong(current_location(fd))); return(C_llong_to_Xen_llong(region_current_location(fd))); } } if (is_mix_sampler(obj)) return(g_mix_sampler_position(obj)); return(Xen_integer_zero); } static Xen g_sampler_home(Xen obj) { #define H_sampler_home "(" S_sampler_home " obj): (list sound-index chan-num) associated with a sound reader, or \ if 'obj' is a mix-sampler, the id of underlying mix" Xen_check_type(is_any_sampler(obj), obj, 1, S_sampler_home, "a sampler (of any kind)"); if (is_sampler(obj)) { snd_fd *fd = NULL; fd = Xen_to_C_sampler(obj); if ((fd->cp) && (fd->cp->active >= CHANNEL_HAS_EDIT_LIST) && (fd->cp->sound)) { if (fd->type == SAMPLER) return(Xen_list_2(C_int_to_Xen_sound(fd->cp->sound->index), C_int_to_Xen_integer(fd->cp->chan))); return(Xen_list_2(C_int_to_Xen_region(fd->region), C_int_to_Xen_integer(fd->cp->chan))); } } if (is_mix_sampler(obj)) return(g_mix_sampler_home(obj)); return(Xen_false); } Xen g_sampler_file_name(Xen obj) { if (is_sampler(obj)) { snd_fd *fd = NULL; fd = Xen_to_C_sampler(obj); if ((fd->cp) && (fd->cp->active >= CHANNEL_HAS_EDIT_LIST) && (fd->cp->sound)) return(C_string_to_Xen_string(fd->cp->sound->filename)); return(Xen_false); } return(C_string_to_Xen_string(mix_file_name(Xen_mix_to_C_int(obj)))); } Xen g_c_make_sampler(snd_fd *fd) { return(Xen_make_object(sf_tag, fd, 0, free_sf)); } static Xen g_make_region_sampler(Xen reg, Xen samp_n, Xen chn, Xen dir1) { #define H_make_region_sampler "(" S_make_region_sampler " reg :optional (start-samp 0) (chn 0) (dir 1)): \ return a reader ready to access region's channel chn data starting at start-samp going in direction dir" snd_fd *fd = NULL; int reg_n, chn_n = 0; mus_long_t beg; int direction = 1; Xen_check_type(xen_is_region(reg), reg, 1, S_make_region_sampler, "a region"); Xen_check_type(Xen_is_integer_or_unbound(samp_n), samp_n, 2, S_make_region_sampler, "an integer"); Xen_check_type(Xen_is_integer_or_unbound(chn), chn, 3, S_make_region_sampler, "an integer"); Xen_check_type(Xen_is_integer_boolean_or_unbound(dir1), dir1, 4, S_make_region_sampler, "an integer"); reg_n = Xen_region_to_C_int(reg); if (!(region_ok(reg_n))) Xen_error(Xen_make_error_type("no-such-region"), Xen_list_2(C_string_to_Xen_string(S_make_region_sampler ": no such region: ~A"), reg)); if (Xen_is_integer(chn)) chn_n = Xen_integer_to_C_int(chn); if ((chn_n < 0) || (chn_n >= region_chans(reg_n))) return(snd_no_such_channel_error(S_make_region_sampler, Xen_list_1(reg), chn)); beg = beg_to_sample(samp_n, S_make_region_sampler); if (Xen_is_integer(dir1)) direction = Xen_integer_to_C_int(dir1); if (direction == 1) fd = init_region_read(beg, reg_n, chn_n, READ_FORWARD); else { if (direction == -1) fd = init_region_read(beg, reg_n, chn_n, READ_BACKWARD); else Xen_error(Xen_make_error_type("no-such-direction"), Xen_list_2(C_string_to_Xen_string(S_make_region_sampler ": bad direction: ~A"), dir1)); } if (fd) { fd->edit_ctr = -2 - reg_n; /* can't use fd->cp because deferred case is pointer to original (not copied) data */ /* has to be less than -1 because that is the "delete all readers" sign on chan close */ fd->region = reg_n; fd->type = REGION_READER; list_reader(fd); return(Xen_make_object(sf_tag, fd, 0, free_sf)); } return(Xen_false); } static Xen g_make_sampler(Xen samp_n, Xen snd, Xen chn, Xen dir1, Xen pos) /* "dir" confuses Mac OS-X Objective-C! */ { #define H_make_sampler "(" S_make_sampler " :optional (start-samp 0) snd chn (dir 1) edpos): \ return a reader ready to access snd's channel chn's data starting at start-samp, going in direction dir (1 = \ forward, -1 = backward), reading the version of the data indicated by edpos which defaults to the current version. \ snd can be a filename, a mix, a region, or a sound index number." snd_fd *fd = NULL; int edpos, direction = 1; /* in Scheme 1=forward, -1=backward */ chan_info *cp; snd_info *loc_sp = NULL; mus_long_t beg; Xen_check_type(Xen_is_integer_or_unbound(samp_n), samp_n, 1, S_make_sampler, "an integer"); Xen_check_type(Xen_is_integer_boolean_or_unbound(dir1), dir1, 4, S_make_sampler, "an integer"); if (xen_is_mix(snd)) return(g_make_mix_sampler(snd, samp_n)); if (xen_is_region(snd)) return(g_make_region_sampler(snd, samp_n, chn, dir1)); if (Xen_is_string(snd)) { const char *filename; int chan = 0; Xen_check_type(Xen_is_integer_boolean_or_unbound(chn), chn, 3, S_make_sampler, "an integer or boolean"); filename = Xen_string_to_C_string(snd); if (mus_file_probe(filename)) loc_sp = make_sound_readable(filename, false); else return(snd_no_such_file_error(S_make_sampler, snd)); if (Xen_is_integer(chn)) chan = Xen_integer_to_C_int(chn); if ((chan < 0) || (chan >= loc_sp->nchans)) { completely_free_snd_info(loc_sp); return(snd_no_such_channel_error(S_make_sampler, snd, chn)); } cp = loc_sp->chans[chan]; } else { Snd_assert_channel(S_make_sampler, snd, chn, 2); cp = get_cp(snd, chn, S_make_sampler); if (!cp) return(Xen_false); } edpos = to_c_edit_position(cp, pos, S_make_sampler, 5); if (Xen_is_integer(dir1)) direction = Xen_integer_to_C_int(dir1); beg = beg_to_sample(samp_n, S_make_sampler); if (direction == 1) fd = init_sample_read_any(beg, cp, READ_FORWARD, edpos); else { if (direction == -1) fd = init_sample_read_any(beg, cp, READ_BACKWARD, edpos); else Xen_error(Xen_make_error_type("no-such-direction"), Xen_list_2(C_string_to_Xen_string(S_make_sampler ": bad direction: ~A"), dir1)); } if (fd) { fd->local_sp = loc_sp; list_reader(fd); return(Xen_make_object(sf_tag, fd, 0, free_sf)); } return(Xen_false); } static Xen g_is_sampler(Xen obj) { #define H_is_sampler "(" S_is_sampler " obj): " PROC_TRUE " if obj is a sound sampler." if (is_sampler(obj)) { snd_fd *fd; fd = Xen_to_C_sampler(obj); return(C_bool_to_Xen_boolean(fd->type == SAMPLER)); } if (is_mix_sampler(obj)) return(C_string_to_Xen_symbol("mix")); return(Xen_false); } static Xen g_region_is_sampler(Xen obj) { #define H_region_is_sampler "(" S_is_region_sampler " obj): " PROC_TRUE " if obj is a region sampler." if (is_sampler(obj)) { snd_fd *fd; fd = Xen_to_C_sampler(obj); return(C_bool_to_Xen_boolean(fd->type == REGION_READER)); } return(Xen_false); } static Xen g_copy_sampler(Xen obj) { #define H_copy_sampler "(" S_copy_sampler " reader): return a copy of reader" Xen_check_type(is_any_sampler(obj), obj, 1, S_copy_sampler, "a sampler (of any kind)"); if (is_sampler(obj)) { snd_fd *fd = NULL; fd = Xen_to_C_sampler(obj); if ((fd->cp) && (fd->cp->active >= CHANNEL_HAS_EDIT_LIST) && (fd->cp->sound)) { if (fd->type == SAMPLER) return(g_make_sampler(C_llong_to_Xen_llong(current_location(fd)), C_int_to_Xen_sound(fd->cp->sound->index), C_int_to_Xen_integer(fd->cp->chan), C_int_to_Xen_integer((fd->direction == READ_FORWARD) ? 1 : -1), /* Scheme side is different from C side */ C_int_to_Xen_integer(fd->edit_ctr))); return(g_make_region_sampler(C_int_to_Xen_region(fd->region), C_llong_to_Xen_llong(region_current_location(fd)), C_int_to_Xen_integer(fd->cp->chan), C_int_to_Xen_integer((fd->direction == READ_FORWARD) ? 1 : -1))); } return(Xen_false); } if (is_mix_sampler(obj)) return(g_copy_mix_sampler(obj)); return(Xen_false); } static Xen g_next_sample(Xen obj) { #define H_next_sample "(" S_next_sample " reader): next sample from reader" if (is_sampler(obj)) return(C_double_to_Xen_real(protected_next_sample((snd_fd *)Xen_object_ref(obj)))); if (is_mix_sampler(obj)) return(C_double_to_Xen_real(protected_next_sample(xen_mix_to_snd_fd(obj)))); Xen_check_type(false, obj, 1, S_next_sample, "a sampler"); return(C_double_to_Xen_real(0.0)); } mus_float_t read_sample_with_direction(void *p, int dir); mus_float_t read_sample_with_direction(void *p, int dir) { if (dir > 0) return(protected_next_sample((snd_fd *)p)); return(protected_previous_sample((snd_fd *)p)); } static Xen g_read_sample(Xen obj) { #define H_read_sample "(" S_read_sample " reader): read sample from reader" if (is_sampler(obj)) return(C_double_to_Xen_real(read_sample((snd_fd *)Xen_object_ref(obj)))); if (is_mix_sampler(obj)) return(C_double_to_Xen_real(read_sample(xen_mix_to_snd_fd(obj)))); Xen_check_type(false, obj, 1, S_read_sample, "a sampler"); return(C_double_to_Xen_real(0.0)); } #define S_read_sample_with_direction "read-sample-with-direction" static Xen g_read_sample_with_direction(Xen obj, Xen dir) { #define H_read_sample_with_direction "(" S_read_sample_with_direction " reader dir): read sample from reader following dir (next/previous choice)" Xen_check_type(Xen_is_integer(dir), dir, 1, S_read_sample_with_direction, "an integer"); if (is_sampler(obj)) return(C_double_to_Xen_real(read_sample_with_direction((void *)Xen_object_ref(obj), Xen_integer_to_C_int(dir)))); if (is_mix_sampler(obj)) return(C_double_to_Xen_real(read_sample_with_direction((void *)xen_mix_to_snd_fd(obj), Xen_integer_to_C_int(dir)))); Xen_check_type(false, obj, 1, S_read_sample_with_direction, "a sampler"); return(C_double_to_Xen_real(0.0)); } #if HAVE_SCHEME static Xen s7_read_sample(s7_scheme *sc, Xen obj, Xen args) { /* we can only get here if obj is already known to be a sampler */ return(C_double_to_Xen_real(read_sample((snd_fd *)Xen_object_ref(obj)))); } #endif static Xen g_previous_sample(Xen obj) { #define H_previous_sample "(" S_previous_sample " reader): previous sample from reader" if (is_sampler(obj)) return(C_double_to_Xen_real(protected_previous_sample((snd_fd *)Xen_object_ref(obj)))); if (is_mix_sampler(obj)) return(C_double_to_Xen_real(protected_previous_sample(xen_mix_to_snd_fd(obj)))); Xen_check_type(false, obj, 1, S_previous_sample, "a sampler"); return(C_double_to_Xen_real(0.0)); } static Xen g_free_sampler(Xen obj) { #define H_free_sampler "(" S_free_sampler " reader): free a sampler (of any kind)" Xen_check_type(is_any_sampler(obj), obj, 1, S_free_sampler, "a sampler"); if (is_sampler(obj)) { snd_info *sp = NULL; snd_fd *fd; fd = Xen_to_C_sampler(obj); unlist_reader(fd); sp = fd->local_sp; fd->local_sp = NULL; free_snd_fd_almost(fd); /* this is different from sf_free! */ if (sp) completely_free_snd_info(sp); } if (is_mix_sampler(obj)) return(g_free_mix_sampler(obj)); return(Xen_false); } static Xen g_save_edit_history(Xen filename, Xen snd, Xen chn) { #define H_save_edit_history "(" S_save_edit_history " filename :optional snd chn): save snd channel's chn edit history in filename" FILE *fd; const char *name; char *mcf = NULL; Xen_check_type(Xen_is_string(filename), filename, 1, S_save_edit_history, "a string"); Snd_assert_channel(S_save_edit_history, snd, chn, 2); name = Xen_string_to_C_string(filename); mcf = mus_expand_filename(name); if (!mcf) return(Xen_false); fd = FOPEN(mcf, "w"); if (mcf) free(mcf); if (fd) { if ((Xen_is_integer(chn)) && (Xen_is_integer(snd) || xen_is_sound(snd))) { chan_info *cp; cp = get_cp(snd, chn, S_save_edit_history); if (!cp) return(Xen_false); edit_history_to_file(fd, cp, false); } else { int i; snd_info *sp; if (Xen_is_integer(snd) || xen_is_sound(snd)) { sp = get_sp(snd); if (sp) for (i = 0; i < sp->nchans; i++) edit_history_to_file(fd, sp->chans[i], false); } else { for (i = 0; i < ss->max_sounds; i++) { int j; sp = ss->sounds[i]; if ((sp) && (sp->inuse == SOUND_NORMAL)) for (j = 0; j < sp->nchans; j++) edit_history_to_file(fd, sp->chans[j], false); } } } snd_fclose(fd, name); } else { Xen_error(CANNOT_SAVE, Xen_list_3(C_string_to_Xen_string(S_save_edit_history ": can't save ~S: ~A"), filename, C_string_to_Xen_string(snd_open_strerror()))); } return(filename); } static Xen g_undo(Xen ed_n, Xen snd, Xen chn_n) /* opt ed_n */ { #define H_undo "(" S_undo " :optional (count 1) snd chn): undo 'count' edits in snd's channel chn" chan_info *cp; Xen_check_type(Xen_is_integer_or_unbound(ed_n), ed_n, 1, S_undo, "an integer"); Snd_assert_channel(S_undo, snd, chn_n, 2); cp = get_cp(snd, chn_n, S_undo); if (!cp) return(Xen_false); if (Xen_is_integer(ed_n)) { int num; num = Xen_integer_to_C_int(ed_n); if ((num != 0) && (num < 1000000000) && (num > -1000000000)) { if (undo_edit_with_sync(cp, num)) return(C_int_to_Xen_integer(num)); } return(Xen_integer_zero); } if (undo_edit_with_sync(cp, 1)) return(C_int_to_Xen_integer(1)); return(Xen_integer_zero); } static Xen g_redo(Xen ed_n, Xen snd, Xen chn_n) /* opt ed_n */ { #define H_redo "(" S_redo " :optional (count 1) snd chn): redo 'count' edits in snd's channel chn" chan_info *cp; Xen_check_type(Xen_is_integer_or_unbound(ed_n), ed_n, 1, S_redo, "an integer"); Snd_assert_channel(S_redo, snd, chn_n, 2); cp = get_cp(snd, chn_n, S_redo); if (!cp) return(Xen_false); if (Xen_is_integer(ed_n)) { int num; num = Xen_integer_to_C_int(ed_n); if ((num != 0) && (num < 1000000000) && (num > -1000000000)) { if (redo_edit_with_sync(cp, num)) return(C_int_to_Xen_integer(num)); } return(Xen_integer_zero); } if (redo_edit_with_sync(cp, 1)) return(C_int_to_Xen_integer(1)); return(Xen_integer_zero); } /* ---------------------------------------- AS-ONE-EDIT ---------------------------------------- */ #define INITIAL_AS_ONE_EDIT_POSITIONS_SIZE 2 void as_one_edit(chan_info *cp, int one_edit) { /* it's not safe to back up during the as-one-edit function call because that function might refer back via the edpos args etc */ bool need_backup; need_backup = (cp->edit_ctr > one_edit); /* cp->edit_ctr will be changing, so save this */ if (cp->edit_ctr >= one_edit) /* ">=" here because the origin needs to be set even if there were no extra edits */ { if (ss->deferred_regions > 0) sequester_deferred_regions(cp, one_edit - 1); while (cp->edit_ctr > one_edit) backup_edit_list_1(cp, true); /* i.e. free all the fragments */ if (need_backup) prune_edits(cp, cp->edit_ctr + 1); } } static void init_as_one_edit(chan_info *cp) { if (cp->in_as_one_edit == 0) cp->previous_squelch_update = cp->squelch_update; /* preserve possible user setting across as-one-edit call */ cp->squelch_update = true; if (cp->as_one_edit_positions_size == 0) { cp->as_one_edit_positions_size = INITIAL_AS_ONE_EDIT_POSITIONS_SIZE; cp->as_one_edit_positions = (int *)calloc(cp->as_one_edit_positions_size, sizeof(int)); } else { if (cp->in_as_one_edit >= cp->as_one_edit_positions_size) { cp->as_one_edit_positions_size += INITIAL_AS_ONE_EDIT_POSITIONS_SIZE; cp->as_one_edit_positions = (int *)realloc(cp->as_one_edit_positions, cp->as_one_edit_positions_size * sizeof(int)); } } cp->as_one_edit_positions[cp->in_as_one_edit] = cp->edit_ctr; cp->in_as_one_edit++; } static void as_one_edit_set_origin(chan_info *cp, void *origin) { if (cp->as_one_edit_positions) { if ((cp->as_one_edit_positions[cp->in_as_one_edit] + 1) == cp->edit_ctr) { ed_list *ed; ed = cp->edits[cp->edit_ctr]; if (ed) { if (ed->origin) free(ed->origin); ed->origin = mus_strdup((char *)origin); } } } } static void finish_as_one_edit(chan_info *cp) { /* if a sound was opened within as-one-edit, it will have 0 here and no array */ if ((cp->in_as_one_edit > 0) && (cp->as_one_edit_positions)) { cp->in_as_one_edit--; if (cp->in_as_one_edit < 0) cp->in_as_one_edit = 0; as_one_edit(cp, cp->as_one_edit_positions[cp->in_as_one_edit] + 1); if (cp->in_as_one_edit == 0) { cp->squelch_update = cp->previous_squelch_update; if (!(cp->squelch_update)) clear_status_area(cp->sound); reflect_edit_history_change(cp); update_graph(cp); } } } #if HAVE_SCHEME static s7_pointer edit_finish; static s7_pointer g_edit_finish(s7_scheme *sc, s7_pointer args) { for_each_normal_chan(finish_as_one_edit); return(args); } #endif static Xen g_as_one_edit(Xen proc, Xen origin) { #define H_as_one_edit "(" S_as_one_edit " thunk :optional origin): evaluate thunk, collecting all edits into one from the edit history's point of view" Xen result = Xen_false; char *errmsg, *as_one_edit_origin = NULL; Xen_check_type((Xen_is_procedure(proc)), proc, 1, S_as_one_edit, "a procedure"); Xen_check_type(Xen_is_string_or_unbound(origin), origin, 2, S_as_one_edit, "a string"); errmsg = procedure_ok(proc, 0, S_as_one_edit, "edit", 1); if (errmsg) { Xen errstr; errstr = C_string_to_Xen_string(errmsg); free(errmsg); return(snd_bad_arity_error(S_as_one_edit, errstr, proc)); } if (Xen_is_string(origin)) as_one_edit_origin = mus_strdup(Xen_string_to_C_string(origin)); else as_one_edit_origin = NULL; for_each_normal_chan(init_as_one_edit); #if HAVE_SCHEME result = s7_dynamic_wind(s7, xen_false, proc, edit_finish); #else result = Xen_unprotected_call_with_no_args(proc); for_each_normal_chan(finish_as_one_edit); #endif if (as_one_edit_origin) { for_each_normal_chan_with_void(as_one_edit_set_origin, (void *)as_one_edit_origin); free(as_one_edit_origin); } return(result); } static Xen g_scale_channel(Xen scl, Xen beg, Xen num, Xen snd, Xen chn, Xen edpos) { #define H_scale_channel "(" S_scale_channel " scaler :optional (beg 0) (dur len) snd chn edpos): \ scale samples in the given sound/channel between beg and beg + num by scaler." mus_float_t scaler; chan_info *cp; mus_long_t samp; int pos; Xen_check_type(Xen_is_number(scl), scl, 1, S_scale_channel, "a number"); Snd_assert_sample_type(S_scale_channel, beg, 2); Snd_assert_sample_type(S_scale_channel, num, 3); Snd_assert_sound(S_scale_channel, snd, 4); scaler = Xen_real_to_C_double(scl); samp = beg_to_sample(beg, S_scale_channel); cp = get_cp(snd, chn, S_scale_channel); if (!cp) return(Xen_false); pos = to_c_edit_position(cp, edpos, S_scale_channel, 6); scale_channel(cp, scaler, samp, dur_to_samples(num, samp, cp, pos, 3, S_scale_channel), pos, NOT_IN_AS_ONE_EDIT); return(scl); } static Xen g_normalize_channel(Xen scl, Xen beg, Xen num, Xen snd, Xen chn, Xen edpos) { #define H_normalize_channel "(" S_normalize_channel " norm :optional (beg 0) (dur len) snd chn edpos): \ scale samples in the given sound/channel between beg and beg + num to norm." mus_float_t norm, cur_max; chan_info *cp; mus_long_t samp, samps; int pos; char *origin = NULL; Xen_check_type(Xen_is_number(scl), scl, 1, S_normalize_channel, "a number"); Snd_assert_sample_type(S_normalize_channel, beg, 2); Snd_assert_sample_type(S_normalize_channel, num, 3); Snd_assert_sound(S_normalize_channel, snd, 4); norm = Xen_real_to_C_double(scl); samp = beg_to_sample(beg, S_normalize_channel); cp = get_cp(snd, chn, S_normalize_channel); if (!cp) return(Xen_false); pos = to_c_edit_position(cp, edpos, S_normalize_channel, 6); samps = dur_to_samples(num, samp, cp, pos, 3, S_normalize_channel); /* in order to normalize the data, we need its current maxamp */ #if HAVE_FORTH if ((samp == 0) && (samps == cp->edits[pos]->samples)) { cur_max = channel_maxamp(cp, pos); origin = mus_format("%.3f 0 " PROC_FALSE " %s", norm, S_normalize_channel); } else { cur_max = channel_local_maxamp(cp, samp, samps, pos, NULL); origin = mus_format("%.3f %lld" PROC_SEP "%lld %s", norm, samp, samps, S_normalize_channel); } #else if ((samp == 0) && (samps == cp->edits[pos]->samples)) { cur_max = channel_maxamp(cp, pos); origin = mus_format("%s" PROC_OPEN "%.3f" PROC_SEP "0" PROC_SEP PROC_FALSE, to_proc_name(S_normalize_channel), norm); } else { cur_max = channel_local_maxamp(cp, samp, samps, pos, NULL); origin = mus_format("%s" PROC_OPEN "%.3f" PROC_SEP "%lld" PROC_SEP "%lld", to_proc_name(S_normalize_channel), norm, samp, samps); } #endif if (cur_max != 0.0) scale_channel_with_origin(cp, norm / cur_max, samp, samps, pos, NOT_IN_AS_ONE_EDIT, origin); if (origin) free(origin); return(scl); } mus_float_t channel_maxamp_and_position(chan_info *cp, int edpos, mus_long_t *maxpos) { /* maxamp position is not tracked in peak env because it gloms up the code, and cannot easily be saved/restored in the peak env files */ mus_float_t val; int pos; mus_long_t locpos; if (edpos == AT_CURRENT_EDIT_POSITION) pos = cp->edit_ctr; else pos = edpos; if ((peak_env_maxamp_ok(cp, pos)) && (!maxpos)) return(peak_env_maxamp(cp, pos)); val = ed_maxamp(cp, pos); locpos = ed_maxamp_position(cp, pos); if (maxpos) (*maxpos) = locpos; if ((val >= 0.0) && /* defaults to -1.0! */ ((!maxpos) || (locpos >= 0))) return(val); val = channel_local_maxamp(cp, 0, cp->edits[pos]->samples, pos, &locpos); set_ed_maxamp(cp, pos, val); set_ed_maxamp_position(cp, pos, locpos); if (maxpos) (*maxpos) = locpos; return(val); } mus_float_t channel_maxamp(chan_info *cp, int edpos) { return(channel_maxamp_and_position(cp, edpos, NULL)); } mus_long_t channel_maxamp_position(chan_info *cp, int edpos) { mus_long_t maxpos = 0; channel_maxamp_and_position(cp, edpos, &maxpos); return(maxpos); } mus_float_t channel_local_maxamp(chan_info *cp, mus_long_t beg, mus_long_t num, int edpos, mus_long_t *maxpos) { snd_fd *sf; mus_float_t ymax, x; mus_float_t *d; mus_long_t i, k, lim8, kend, mpos; sf = init_sample_read_any_with_bufsize(beg, cp, READ_FORWARD, edpos, (num > MAX_BUFFER_SIZE) ? MAX_BUFFER_SIZE : num); if (sf == NULL) return(0.0); ymax = 0.0; mpos = -1; i = 0; while (true) { mus_long_t dur, left, offset; dur = sf->last - sf->loc + 1; /* current fragment, we're always reading forward here */ left = num - i; if (dur > left) dur = left; offset = i - sf->loc; if (sf->runf == next_sample_value_unscaled) { kend = sf->loc + dur; lim8 = kend - 8; k = sf->loc; d = sf->data; while (k <= lim8) { x = fabs(d[k]); if (x > ymax) {ymax = x; mpos = k + offset;} k++; x = fabs(d[k]); if (x > ymax) {ymax = x; mpos = k + offset;} k++; x = fabs(d[k]); if (x > ymax) {ymax = x; mpos = k + offset;} k++; x = fabs(d[k]); if (x > ymax) {ymax = x; mpos = k + offset;} k++; x = fabs(d[k]); if (x > ymax) {ymax = x; mpos = k + offset;} k++; x = fabs(d[k]); if (x > ymax) {ymax = x; mpos = k + offset;} k++; x = fabs(d[k]); if (x > ymax) {ymax = x; mpos = k + offset;} k++; x = fabs(d[k]); if (x > ymax) {ymax = x; mpos = k + offset;} k++; } while (k < kend) { x = fabs(d[k]); if (x > ymax) {ymax = x; mpos = k + offset;} k++; } i += dur; } else { if (sf->runf == next_sample_value) { mus_float_t scl, lmax; /* provisional max -- we omit the scaling until the end */ mus_long_t lpos; /* provisional max position */ scl = fabs(sf->fscaler); lpos = -1; lmax = 0.0; kend = sf->loc + dur; lim8 = kend - 8; d = sf->data; k = sf->loc; while (k <= lim8) { x = fabs(d[k]); if (x > lmax) {lmax = x; lpos = k;} k++; x = fabs(d[k]); if (x > lmax) {lmax = x; lpos = k;} k++; x = fabs(d[k]); if (x > lmax) {lmax = x; lpos = k;} k++; x = fabs(d[k]); if (x > lmax) {lmax = x; lpos = k;} k++; x = fabs(d[k]); if (x > lmax) {lmax = x; lpos = k;} k++; x = fabs(d[k]); if (x > lmax) {lmax = x; lpos = k;} k++; x = fabs(d[k]); if (x > lmax) {lmax = x; lpos = k;} k++; x = fabs(d[k]); if (x > lmax) {lmax = x; lpos = k;} k++; } while (k < kend) { x = fabs(d[k]); if (x > lmax) {lmax = x; lpos = k;} k++; } if (lmax * scl > ymax) { ymax = lmax * scl; mpos = lpos + offset; } i += dur; } else { if (sf->runf == next_ramp1) { mus_float_t amp, incr; mus_long_t j; amp = READER_VAL(sf, 0); incr = READER_INCR(sf, 0); kend = sf->loc + dur; lim8 = kend - 4; d = sf->data; j = sf->loc; while (j <= lim8) { x = fabs(amp * d[j]); if (x > ymax) {ymax = x; mpos = j + offset;} amp += incr; j++; x = fabs(amp * d[j]); if (x > ymax) {ymax = x; mpos = j + offset;} amp += incr; j++; x = fabs(amp * d[j]); if (x > ymax) {ymax = x; mpos = j + offset;} amp += incr; j++; x = fabs(amp * d[j]); if (x > ymax) {ymax = x; mpos = j + offset;} amp += incr; j++; } while (j < kend) { x = fabs(amp * d[j]); if (x > ymax) {ymax = x; mpos = j + offset;} amp += incr; j++; } READER_VAL(sf, 0) = amp; i += dur; } else { if (sf->runf == end_sample_value) break; if (sf->runf == next_zero) i += dur; else { if (sf->runf == next_xramp1) { mus_float_t off, scaler, xval, scl, incr; mus_long_t j; off = READER_XRAMP_OFFSET(sf, 0); scl = READER_SCALER(sf); scaler = READER_XRAMP_SCALER(sf, 0); xval = READER_XVAL(sf, 0); incr = READER_XINCR(sf, 0); d = sf->data; kend = sf->loc + dur; off *= scl; scaler *= scl; for (j = sf->loc; j < kend; j++) { x = fabs(d[j] * (off + scaler * xval)); if (x > ymax) {ymax = x; mpos = j + offset;} xval *= incr; } READER_XVAL(sf, 0) = xval; i += dur; } else { left = i + dur; for (; i < left; i++) { x = fabs(read_sample(sf)); if (x > ymax) {ymax = x; mpos = i;} } } } } } } if (i >= num) break; next_sound_1(sf); } /* fprintf(stderr, "use %f %lld\n", ymax, mpos); */ if ((edpos == 0) && (beg == 0) && (num = cp->edits[0]->samples)) mus_sound_channel_set_maxamp(cp->sound->filename, cp->chan, ymax, mpos); if (maxpos) (*maxpos) = mpos; free_snd_fd(sf); return(ymax); } static mus_float_t *g_floats_to_samples(Xen obj, int *size, const char *caller, int position) { mus_float_t *vals = NULL; int i, num = 0; if (Xen_is_list(obj)) { Xen lst; num = Xen_list_length(obj); if (num == 0) return(NULL); if (((*size) > 0) && (num > (*size))) num = (*size); vals = (mus_float_t *)malloc(num * sizeof(mus_float_t)); for (i = 0, lst = Xen_copy_arg(obj); i < num; i++, lst = Xen_cdr(lst)) vals[i] = (Xen_real_to_C_double(Xen_car(lst))); } else { if (Xen_is_vector(obj)) { num = Xen_vector_length(obj); if (num == 0) return(NULL); if (((*size) > 0) && (num > (*size))) num = (*size); vals = (mus_float_t *)malloc(num * sizeof(mus_float_t)); for (i = 0; i < num; i++) vals[i] = (Xen_real_to_C_double(Xen_vector_ref(obj, i))); } else { /* this block probably can't happen anymore */ if (mus_is_vct(obj)) { vct *v; mus_float_t *vdata; v = Xen_to_vct(obj); vdata = mus_vct_data(v); num = mus_vct_length(v); if (((*size) > 0) && (num > (*size))) num = (*size); vals = (mus_float_t *)malloc(num * sizeof(mus_float_t)); for (i = 0; i < num; i++) vals[i] = (vdata[i]); } else Xen_check_type(0, obj, position, caller, "a " S_vct ", vector, or list"); } } (*size) = num; return(vals); } static Xen g_sample(Xen samp_n, Xen snd, Xen chn_n, Xen pos_n) { #define H_sample "(" S_sample " samp :optional snd chn edpos): \ return sample samp in snd's channel chn (this is a slow access -- use samplers for speed)" mus_long_t beg; int pos; chan_info *cp; Xen_check_type(Xen_is_integer_or_unbound(samp_n), samp_n, 1, S_sample, "an integer"); if (Xen_is_true(chn_n)) /* a convenience! */ { Xen lst = Xen_empty_list; int i, loc; snd_info *sp; Snd_assert_sound(S_sample, snd, 1); sp = get_sp(snd); if (!sp) return(Xen_false); cp = any_selected_channel(sp); if (!cp) return(Xen_false); pos = to_c_edit_position(cp, pos_n, S_sample, 4); beg = beg_to_sample(samp_n, S_sample); loc = snd_protect(lst); for (i = 0; i < sp->nchans; i++) { if (pos > sp->chans[i]->edit_ctr) lst = Xen_cons(C_double_to_Xen_real(chn_sample(beg, sp->chans[i], sp->chans[i]->edit_ctr)), lst); else lst = Xen_cons(C_double_to_Xen_real(chn_sample(beg, sp->chans[i], pos)), lst); } snd_unprotect_at(loc); return(lst); } Snd_assert_channel(S_sample, snd, chn_n, 2); cp = get_cp(snd, chn_n, S_sample); if (!cp) return(Xen_false); pos = to_c_edit_position(cp, pos_n, S_sample, 4); if (Xen_is_bound(samp_n)) beg = beg_to_sample(samp_n, S_sample); else beg = cursor_sample(cp); return(C_double_to_Xen_real(chn_sample(beg, cp, pos))); } static Xen g_set_sample(Xen samp_n, Xen val, Xen snd, Xen chn_n, Xen edpos) { /* each call consitutes a separate edit from the undo/redo point-of-view */ chan_info *cp; int pos; char *origin; mus_long_t beg; mus_float_t fval; mus_float_t ival[1]; Xen_check_type(Xen_is_integer_or_unbound(samp_n), samp_n, 1, S_set S_sample, "an integer"); Xen_check_type(Xen_is_number(val), val, 2, S_set S_sample, "a number"); Snd_assert_channel(S_set S_sample, snd, chn_n, 3); cp = get_cp(snd, chn_n, S_set S_sample); if (!cp) return(Xen_false); pos = to_c_edit_position(cp, edpos, S_set S_sample, 5); if (pos > cp->edit_ctr) Xen_error(NO_SUCH_EDIT, Xen_list_2(C_string_to_Xen_string(S_set S_sample ": no such edit: ~A"), edpos)); if (Xen_is_bound(samp_n)) beg = beg_to_sample(samp_n, S_set S_sample); else beg = cursor_sample(cp); fval = Xen_real_to_C_double(val); if ((fval == 1.0) && (mus_bytes_per_sample(((cp->sound)->hdr)->sample_type) == 2)) fval = 32767.0 / 32768.0; ival[0] = fval; #if HAVE_FORTH origin = mus_format("%lld %.4f %s drop", beg, fval, "set-sample"); #else origin = mus_format("%s" PROC_OPEN "%lld" PROC_SEP "%.4f", to_proc_name("set-sample"), beg, fval); #endif if (change_samples(beg, 1, ival, cp, origin, pos, fabs(fval))) update_graph(cp); free(origin); return(val); } #if HAVE_SCHEME static Xen g_set_sample_reversed(s7_scheme *sc, s7_pointer args) { int len; len = Xen_list_length(args); if (len == 1) return(g_set_sample(Xen_undefined, Xen_list_ref(args, 0), Xen_undefined, Xen_undefined, Xen_undefined)); if (len == 2) return(g_set_sample(Xen_list_ref(args, 0), Xen_list_ref(args, 1), Xen_undefined, Xen_undefined, Xen_undefined)); if (len == 3) return(g_set_sample(Xen_list_ref(args, 0), Xen_list_ref(args, 2), Xen_list_ref(args, 1), Xen_undefined, Xen_undefined)); if (len == 4) return(g_set_sample(Xen_list_ref(args, 0), Xen_list_ref(args, 3), Xen_list_ref(args, 1), Xen_list_ref(args, 2), Xen_undefined)); return(g_set_sample(Xen_list_ref(args, 0), Xen_list_ref(args, 4), Xen_list_ref(args, 1), Xen_list_ref(args, 2), Xen_list_ref(args, 3))); } #endif file_delete_t xen_to_file_delete_t(Xen auto_delete, const char *caller) { if (Xen_is_boolean(auto_delete)) { if (Xen_boolean_to_C_bool(auto_delete)) return(DELETE_ME); else return(DONT_DELETE_ME); } else { if (Xen_is_integer(auto_delete)) /* might be unbound */ { int val; val = Xen_integer_to_C_int(auto_delete); if ((val >= DONT_DELETE_ME) && (val <= MULTICHANNEL_DELETION_IF_FILE)) return((file_delete_t)val); Xen_error(Xen_make_error_type("no-such-auto-delete-choice"), Xen_list_3(C_string_to_Xen_string("~A: no such auto-delete option: ~A"), C_string_to_Xen_string(caller), auto_delete)); } } return(DONT_DELETE_ME); } static Xen g_set_samples_with_origin(Xen samp_0, Xen samps, Xen vect, Xen snd, Xen chn_n, Xen truncate, const char *edname, Xen infile_chan, Xen edpos, Xen auto_delete) { #define H_set_samples "(set-" S_samples " start-samp samps data :optional snd chn truncate edname (infile-chan 0) edpos auto-delete): \ set snd's channel chn's samples starting at start-samp for samps from data (a " S_vct ", vector, or string (filename)); \ start-samp can be beyond current data end; if truncate is " PROC_TRUE " and start-samp is 0, the end of the file is set to match \ the new data's end." chan_info *cp; mus_long_t len = 0, beg; bool override = false; int pos; const char *caller; if (edname) caller = edname; else caller = "set-samples"; Snd_assert_sample_type(caller, samp_0, 1); Snd_assert_sample_type(caller, samps, 2); Snd_assert_channel(caller, snd, chn_n, 4); Xen_check_type(Xen_is_boolean_or_unbound(truncate), truncate, 6, caller, "a boolean"); cp = get_cp(snd, chn_n, caller); if (!cp) return(Xen_false); Xen_check_type(Xen_is_integer_boolean_or_unbound(infile_chan), infile_chan, 8, caller, "an integer"); pos = to_c_edit_position(cp, edpos, caller, 9); beg = beg_to_sample(samp_0, caller); len = dur_to_samples(samps, beg, cp, pos, 2, caller); if (len == 0) return(Xen_false); Xen_check_type(Xen_is_integer_boolean_or_unbound(auto_delete), auto_delete, 10, caller, "a boolean or an integer"); override = Xen_is_true(truncate); if (Xen_is_string(vect)) { int inchan = 0; file_delete_t delete_file = DONT_DELETE_ME; mus_long_t curlen; const char *fname; curlen = cp->edits[pos]->samples; fname = Xen_string_to_C_string(vect); if (!mus_file_probe(fname)) return(snd_no_such_file_error(caller, vect)); if (Xen_is_integer(infile_chan)) inchan = Xen_integer_to_C_int(infile_chan); if ((inchan < 0) || (inchan >= mus_sound_chans(fname))) Xen_error(NO_SUCH_CHANNEL, Xen_list_5(C_string_to_Xen_string("~A: no such channel: ~A (~S has ~A chans)"), C_string_to_Xen_string(caller), infile_chan, vect, C_int_to_Xen_integer(mus_sound_chans(fname)))); delete_file = xen_to_file_delete_t(auto_delete, caller); if ((beg == 0) && ((len > curlen) || override)) file_override_samples(len, fname, cp, inchan, delete_file, caller); else file_change_samples(beg, len, fname, cp, inchan, delete_file, caller, pos); } else { if (mus_is_vct(vect)) { vct *v; v = Xen_to_vct(vect); if (len > mus_vct_length(v)) len = mus_vct_length(v); change_samples(beg, len, mus_vct_data(v), cp, caller, pos, -1.0); } else { mus_float_t *ivals; int ilen; ilen = (int)len; ivals = g_floats_to_samples(vect, &ilen, caller, 3); if (ivals) { change_samples(beg, (mus_long_t)ilen, ivals, cp, caller, pos, -1.0); free(ivals); } } } update_graph(cp); return(vect); } static Xen g_set_samples(Xen samp_0, Xen samps, Xen vect, Xen snd, Xen chn_n, Xen truncate, Xen edname, Xen infile_chan, Xen edpos, Xen auto_delete) { Xen_check_type(!Xen_is_bound(edname) || Xen_is_string(edname) || Xen_is_false(edname), edname, 7, "set-samples", "a string"); return(g_set_samples_with_origin(samp_0, samps, vect, snd, chn_n, truncate, (char *)((Xen_is_string(edname)) ? Xen_string_to_C_string(edname) : "set-samples"), infile_chan, edpos, auto_delete)); } static Xen g_set_samples_any(Xen args) { Xen arg; Xen samp_0 = Xen_undefined, samps = Xen_undefined, vect = Xen_undefined; Xen snd = Xen_undefined, chn_n = Xen_undefined, truncate = Xen_undefined; Xen edname = Xen_undefined, infile_chan = Xen_undefined, edpos = Xen_undefined, auto_delete = Xen_undefined; arg = args; if (!Xen_is_null(arg)) { samp_0 = Xen_car(arg); arg = Xen_cdr(arg); if (!Xen_is_null(arg)) { samps = Xen_car(arg); arg = Xen_cdr(arg); if (!Xen_is_null(arg)) { vect = Xen_car(arg); arg = Xen_cdr(arg); if (!Xen_is_null(arg)) { snd = Xen_car(arg); arg = Xen_cdr(arg); if (!Xen_is_null(arg)) { chn_n = Xen_car(arg); arg = Xen_cdr(arg); if (!Xen_is_null(arg)) { truncate = Xen_car(arg); arg = Xen_cdr(arg); if (!Xen_is_null(arg)) { edname = Xen_car(arg); arg = Xen_cdr(arg); if (!Xen_is_null(arg)) { infile_chan = Xen_car(arg); arg = Xen_cdr(arg); if (!Xen_is_null(arg)) { edpos = Xen_car(arg); arg = Xen_cdr(arg); if (!Xen_is_null(arg)) auto_delete = Xen_car(arg); }}}}}}}}} return(g_set_samples(samp_0, samps, vect, snd, chn_n, truncate, edname, infile_chan, edpos, auto_delete)); } void check_saved_temp_file(const char *type, Xen filename, Xen date_and_length) { const char *file; if (!Xen_is_list(date_and_length)) return; /* can this happen? */ file = Xen_string_to_C_string(filename); if (mus_file_probe(file)) { time_t old_time, new_time; mus_long_t old_bytes, new_bytes; old_time = (time_t)Xen_ulong_to_C_ulong(Xen_car(date_and_length)); old_bytes = Xen_llong_to_C_llong(Xen_cadr(date_and_length)); new_time = mus_sound_write_date(file); new_bytes = mus_sound_length(file); if ((new_time != old_time) || (new_bytes != old_bytes)) { char *buf = NULL; if (old_time != new_time) { if (old_bytes != new_bytes) buf = mus_format("Saved %s temp file %s: original write date: %s, current: %s, original length: %lldbytes, current: %lld", type, file, snd_strftime(STRFTIME_FORMAT, old_time), snd_strftime(STRFTIME_FORMAT, new_time), old_bytes, new_bytes); else buf = mus_format("Saved %s temp file %s: original write date: %s, current: %s", type, file, snd_strftime(STRFTIME_FORMAT, old_time), snd_strftime(STRFTIME_FORMAT, new_time)); } else buf = mus_format("Saved %s temp file %s: original length: %lldbytes, current: %lld", type, file, old_bytes, new_bytes); snd_warning_without_format(buf); free(buf); } } } static Xen g_override_samples_with_origin(Xen filename, Xen samps, Xen snd, Xen chn_n, Xen origin, Xen date) { check_saved_temp_file("sound", filename, date); return(g_set_samples(Xen_integer_zero, samps, filename, snd, chn_n, Xen_true, origin, Xen_integer_zero, Xen_false, Xen_false)); } static Xen g_vct_to_channel(Xen v, Xen beg, Xen dur, Xen snd, Xen chn_n, Xen edpos, Xen origin) { #define H_vct_to_channel "(" S_vct_to_channel " v :optional (beg 0) (dur len) snd chn edpos origin): \ set snd's channel chn's samples starting at beg for dur samps from " S_vct " v" const char *caller; Xen_check_type(mus_is_vct(v), v, 1, S_vct_to_channel, "a " S_vct); Xen_check_type(Xen_is_string_or_unbound(origin), origin, 7, S_vct_to_channel, "a string"); if (!Xen_is_bound(beg)) beg = Xen_integer_zero; if (!Xen_is_bound(dur)) { vct *v1; v1 = Xen_to_vct(v); dur = C_int_to_Xen_integer(mus_vct_length(v1)); } if (!Xen_is_bound(origin)) caller = S_vct_to_channel; else caller = (const char *)Xen_string_to_C_string(origin); return(g_set_samples_with_origin(beg, dur, v, snd, chn_n, Xen_false, caller, Xen_false, edpos, Xen_undefined)); } vct *samples_to_vct(mus_long_t beg, mus_long_t len, chan_info *cp, int pos, mus_float_t *buf, snd_fd *reader) { /* if reader, beg, cp, and pos are ignored */ snd_fd *sf; vct *v = NULL; mus_float_t **d; mus_float_t *fvals; if (!buf) { v = mus_vct_make(len); fvals = mus_vct_data(v); } else { v = mus_vct_wrap(len, buf); fvals = buf; } if ((pos == 0) && (beg + len <= cp->edits[0]->samples) && (d = mus_sound_saved_data(cp->sound->filename))) { mus_float_t *dc; dc = d[cp->chan]; memcpy((void *)fvals, (void *)(dc + beg), len * sizeof(mus_float_t)); return(v); } if (!reader) sf = init_sample_read_any_with_bufsize(beg, cp, READ_FORWARD, pos, len); else sf = reader; if (sf) { mus_long_t i; i = 0; while (true) { mus_long_t dur, left; dur = sf->last - sf->loc + 1; /* current fragment, we're always reading forward here */ left = len - i; if (dur > left) dur = left; if (sf->runf == next_sample_value_unscaled) { memcpy((void *)(fvals + i), (void *)(sf->data + sf->loc), dur * sizeof(mus_float_t)); i += dur; } else { if (sf->runf == next_sample_value) { mus_float_t scl; scl = sf->fscaler; memcpy((void *)(fvals + i), (void *)(sf->data + sf->loc), dur * sizeof(mus_float_t)); left = i + dur; for (; i < left; i++) fvals[i] *= scl; } else { if (sf->runf == next_ramp1) { mus_float_t amp, incr; mus_long_t j; amp = READER_VAL(sf, 0); incr = READER_INCR(sf, 0); left = i + dur; for (j = sf->loc; i < left; i++, j++) { fvals[i] = amp * sf->data[j]; amp += incr; } READER_VAL(sf, 0) = amp; } else { if (sf->runf == end_sample_value) break; if (sf->runf == next_zero) i += dur; else { if (sf->runf == next_xramp1) { mus_float_t offset, scaler, xval, scl, incr; mus_long_t j; offset = READER_XRAMP_OFFSET(sf, 0); scl = READER_SCALER(sf); scaler = READER_XRAMP_SCALER(sf, 0); xval = READER_XVAL(sf, 0); incr = READER_XINCR(sf, 0); left = i + dur; offset *= scl; scaler *= scl; for (j = sf->loc; i < left; i++, j++) { fvals[i] = sf->data[j] * (offset + scaler * xval); xval *= incr; } READER_XVAL(sf, 0) = xval; } else { left = i + dur; for (; i < left; i++) fvals[i] = read_sample(sf); } } } } } if (i >= len) break; next_sound_1(sf); } if (!reader) free_snd_fd(sf); } return(v); } vct *samples_to_vct_with_reader(mus_long_t len, mus_float_t *buf, snd_fd *reader) { return(samples_to_vct(0, len, NULL, -1, buf, reader)); } static Xen samples_to_vct_1(Xen samp_0, Xen samps, Xen snd, Xen chn_n, Xen edpos, const char *caller) { chan_info *cp; mus_long_t len, beg; int pos; Xen_check_type(Xen_is_integer_or_unbound(samp_0) || Xen_is_false(samp_0), samp_0, 1, caller, "an integer"); Xen_check_type(Xen_is_integer_or_unbound(samps) || Xen_is_false(samps), samps, 2, caller, "an integer"); Snd_assert_channel(caller, snd, chn_n, 3); cp = get_cp(snd, chn_n, caller); if (!cp) return(Xen_false); pos = to_c_edit_position(cp, edpos, caller, 6); beg = beg_to_sample(samp_0, caller); len = dur_to_samples(samps, beg, cp, pos, 2, caller); if (len == 0) return(Xen_false); /* empty file (channel) possibility */ return(vct_to_xen(samples_to_vct(beg, len, cp, pos, NULL, NULL))); } static Xen g_channel_to_vct(Xen samp_0, Xen samps, Xen snd, Xen chn_n, Xen edpos) { #define H_channel_to_vct "(" S_channel_to_vct " :optional (beg 0) (dur len) snd chn edpos): \ return a " S_vct " containing snd channel chn's data starting at beg for dur samps" return(samples_to_vct_1(samp_0, samps, snd, chn_n, edpos, S_channel_to_vct)); } static Xen g_samples(Xen samp_0, Xen samps, Xen snd, Xen chn_n, Xen edpos) { #define H_samples "(" S_samples " :optional (start-samp 0) (samps len) snd chn edpos): \ return a " S_vct " containing snd channel chn's samples starting at start-samp for samps samples; edpos is the edit \ history position to read (defaults to current position). snd can be a filename, a mix, a region, or a sound index number." chan_info *cp; mus_long_t beg, len; int pos; Xen_check_type(Xen_is_integer_or_unbound(samp_0) || Xen_is_false(samp_0), samp_0, 1, S_samples, "an integer"); Xen_check_type(Xen_is_integer_or_unbound(samps) || Xen_is_false(samps), samps, 2, S_samples, "an integer"); beg = beg_to_sample(samp_0, S_samples); /* -------- a file -------- */ if (Xen_is_string(snd)) { snd_info *loc_sp = NULL; int chan = 0, chans; const char *filename; mus_float_t *fvals; vct *v; Xen_check_type(Xen_is_integer_boolean_or_unbound(chn_n), chn_n, 4, S_samples, "an integer"); if (Xen_is_integer(chn_n)) chan = Xen_integer_to_C_int(chn_n); if (chan < 0) return(snd_no_such_channel_error(S_samples, snd, chn_n)); filename = Xen_string_to_C_string(snd); if (!mus_file_probe(filename)) return(snd_no_such_file_error(S_make_sampler, snd)); if (Xen_is_integer(samps)) len = Xen_integer_to_C_int(samps); else len = mus_sound_framples(filename); if (len <= 0) return(Xen_false); chans = mus_sound_chans(filename); if (chan >= chans) return(snd_no_such_channel_error(S_samples, snd, chn_n)); loc_sp = make_sound_readable(filename, false); cp = loc_sp->chans[chan]; v = mus_vct_make(len); fvals = mus_vct_data(v); mus_file_to_array(filename, chan, beg, len, fvals); completely_free_snd_info(loc_sp); return(vct_to_xen(v)); } /* -------- a mix -------- */ if (xen_is_mix(snd)) return(g_mix_to_vct(snd, samp_0, samps)); /* -------- a region -------- */ if (xen_is_region(snd)) return(g_region_to_vct(snd, samp_0, samps, chn_n, Xen_false)); /* -------- a sound -------- */ Snd_assert_channel(S_samples, snd, chn_n, 3); cp = get_cp(snd, chn_n, S_samples); if (!cp) return(Xen_false); pos = to_c_edit_position(cp, edpos, S_samples, 5); len = dur_to_samples(samps, beg, cp, pos, 2, S_samples); if (len == 0) return(Xen_false); return(vct_to_xen(samples_to_vct(beg, len, cp, pos, NULL, NULL))); } #if HAVE_SCHEME static Xen g_set_samples_reversed(s7_scheme *sc, s7_pointer args) { int len; len = Xen_list_length(args); switch (len) { case 3: return(g_set_samples(Xen_list_ref(args, 0), Xen_list_ref(args, 1), Xen_list_ref(args, 2), Xen_undefined, Xen_undefined, Xen_undefined, Xen_undefined, Xen_undefined, Xen_undefined, Xen_undefined)); case 4: return(g_set_samples(Xen_list_ref(args, 0), Xen_list_ref(args, 1), Xen_list_ref(args, 3), Xen_list_ref(args, 2), Xen_undefined, Xen_undefined, Xen_undefined, Xen_undefined, Xen_undefined, Xen_undefined)); case 5: return(g_set_samples(Xen_list_ref(args, 0), Xen_list_ref(args, 1), Xen_list_ref(args, 4), Xen_list_ref(args, 2), Xen_list_ref(args, 3), Xen_undefined, Xen_undefined, Xen_undefined, Xen_undefined, Xen_undefined)); case 6: return(g_set_samples(Xen_list_ref(args, 0), Xen_list_ref(args, 1), Xen_list_ref(args, 5), Xen_list_ref(args, 2), Xen_list_ref(args, 3), Xen_list_ref(args, 4), Xen_undefined, Xen_undefined, Xen_undefined, Xen_undefined)); case 7: return(g_set_samples(Xen_list_ref(args, 0), Xen_list_ref(args, 1), Xen_list_ref(args, 6), Xen_list_ref(args, 2), Xen_list_ref(args, 3), Xen_list_ref(args, 4), Xen_list_ref(args, 5), Xen_undefined, Xen_undefined, Xen_undefined)); case 8: return(g_set_samples(Xen_list_ref(args, 0), Xen_list_ref(args, 1), Xen_list_ref(args, 7), Xen_list_ref(args, 2), Xen_list_ref(args, 3), Xen_list_ref(args, 4), Xen_list_ref(args, 5), Xen_list_ref(args, 6), Xen_undefined, Xen_undefined)); case 9: return(g_set_samples(Xen_list_ref(args, 0), Xen_list_ref(args, 1), Xen_list_ref(args, 8), Xen_list_ref(args, 2), Xen_list_ref(args, 3), Xen_list_ref(args, 4), Xen_list_ref(args, 5), Xen_list_ref(args, 6), Xen_list_ref(args, 7), Xen_undefined)); default: return(g_set_samples(Xen_list_ref(args, 0), Xen_list_ref(args, 1), Xen_list_ref(args, 9), Xen_list_ref(args, 2), Xen_list_ref(args, 3), Xen_list_ref(args, 4), Xen_list_ref(args, 5), Xen_list_ref(args, 6), Xen_list_ref(args, 7), Xen_list_ref(args, 8))); } } #endif static Xen g_change_samples_with_origin(Xen samp_0, Xen samps, Xen origin, Xen vect, Xen snd, Xen chn_n, Xen edpos, Xen date) { chan_info *cp; int pos; mus_long_t beg, len = 0; Xen_check_type(Xen_is_llong(samp_0), samp_0, 1, S_change_samples_with_origin, "an integer"); Xen_check_type(Xen_is_llong(samps), samps, 2, S_change_samples_with_origin, "an integer"); Xen_check_type(Xen_is_string(origin), origin, 3, S_change_samples_with_origin, "a string"); Xen_check_type(Xen_is_string(vect), vect, 4, S_change_samples_with_origin, "a filename"); Snd_assert_channel(S_change_samples_with_origin, snd, chn_n, 5); cp = get_cp(snd, chn_n, S_change_samples_with_origin); if (!cp) return(Xen_false); beg = beg_to_sample(samp_0, S_change_samples_with_origin); if (Xen_is_llong(samps)) len = Xen_llong_to_C_llong(samps); if (len <= 0) return(Xen_false); pos = to_c_edit_position(cp, edpos, S_change_samples_with_origin, 7); check_saved_temp_file("sound", vect, date); file_change_samples(beg, len, Xen_string_to_C_string(vect), cp, 0, DONT_DELETE_ME, Xen_string_to_C_string(origin), pos); update_graph(cp); return(vect); } static Xen g_insert_sound(Xen file, Xen ubeg, Xen file_chn, Xen snd, Xen chn_n, Xen edpos, Xen auto_delete) { #if HAVE_SCHEME #define insert_sound_example "(" S_insert_sound " \"oboe.snd\" 1000)" #endif #if HAVE_RUBY #define insert_sound_example "insert_sound(\"oboe.snd\", 1000)" #endif #if HAVE_FORTH #define insert_sound_example "\"oboe.snd\" 1000 insert-sound" #endif #define H_insert_sound "(" S_insert_sound " file :optional (beg 0) (file-chan 0) snd chn edpos auto-delete): \ insert channel file-chan of file (or all chans if file-chan is not given) into snd's channel chn at beg or at the cursor \ position.\n " insert_sound_example "\ninserts all of oboe.snd starting at sample 1000." chan_info *cp; static char *filename = NULL; int nc; char *origin; file_delete_t delete_file = DONT_DELETE_ME; mus_long_t beg = 0, len; Xen_check_type(Xen_is_string(file), file, 1, S_insert_sound, "a string"); Xen_check_type(Xen_is_integer_or_unbound(ubeg), ubeg, 2, S_insert_sound, "an integer"); Xen_check_type(Xen_is_integer_or_unbound(file_chn), file_chn, 3, S_insert_sound, "an integer"); Snd_assert_channel(S_insert_sound, snd, chn_n, 4); cp = get_cp(snd, chn_n, S_insert_sound); if (!cp) return(Xen_false); Xen_check_type(Xen_is_integer_boolean_or_unbound(auto_delete), auto_delete, 7, S_insert_sound, "a boolean or an integer"); delete_file = xen_to_file_delete_t(auto_delete, S_insert_sound); if (filename) free(filename); filename = mus_expand_filename(Xen_string_to_C_string(file)); if (!mus_file_probe(filename)) return(snd_no_such_file_error(S_insert_sound, file)); nc = mus_sound_chans(filename); if (nc <= 0) { Xen_error(BAD_HEADER, Xen_list_3(C_string_to_Xen_string(S_insert_sound ": chans <= 0? (~S has ~D chans)"), file, C_int_to_Xen_integer(nc))); } len = mus_sound_framples(filename); if (len <= 0) return(C_llong_to_Xen_llong(len)); if (Xen_is_integer(ubeg)) beg = beg_to_sample(ubeg, S_insert_sound); else beg = cursor_sample(cp); if (Xen_is_integer(file_chn)) { int fchn; fchn = Xen_integer_to_C_int(file_chn); if (fchn < 0) Xen_error(NO_SUCH_CHANNEL, Xen_list_2(C_string_to_Xen_string(S_insert_sound ": file channel: ~D"), file_chn)); if (fchn < nc) { #if HAVE_FORTH origin = mus_format("\"%s\" %lld %d %s drop", filename, beg, fchn, S_insert_sound); #else origin = mus_format("%s" PROC_OPEN "\"%s\"" PROC_SEP "%lld" PROC_SEP "%d", to_proc_name(S_insert_sound), filename, beg, fchn); #endif if (file_insert_samples(beg, len, filename, cp, fchn, delete_file, origin, to_c_edit_position(cp, edpos, S_insert_sound, 6))) update_graph(cp); free(origin); return(C_llong_to_Xen_llong(len)); } else return(snd_no_such_channel_error(S_insert_sound, file, file_chn)); } else { int i; snd_info *sp; sp = cp->sound; if (sp->nchans < nc) nc = sp->nchans; for (i = 0; i < nc; i++) { #if HAVE_FORTH origin = mus_format("\"%s\" %lld %d %s drop", filename, beg, i, S_insert_sound); #else origin = mus_format("%s" PROC_OPEN "\"%s\"" PROC_SEP "%lld" PROC_SEP "%d", to_proc_name(S_insert_sound), filename, beg, i); #endif if (file_insert_samples(beg, len, filename, sp->chans[i], i, delete_file, origin, /* this edit_position cannot be optimized out -- each channel may have * a different edit history, but edpos might be -1 throughout etc. */ to_c_edit_position(sp->chans[i], edpos, S_insert_sound, 6))) update_graph(sp->chans[i]); free(origin); } return(C_llong_to_Xen_llong(len)); } return(Xen_false); /* not reached */ } static Xen g_insert_sample(Xen samp_n, Xen val, Xen snd, Xen chn_n, Xen edpos) { #define H_insert_sample "(" S_insert_sample " sample value :optional snd chn edpos): insert 'value' at 'sample' in snd's channel chn" chan_info *cp; char *origin; int pos; mus_long_t beg; mus_float_t fval; mus_float_t ival[1]; Xen_check_type(Xen_is_integer(samp_n), samp_n, 1, S_insert_sample, "an integer"); Xen_check_type(Xen_is_number(val), val, 2, S_insert_sample, "a number"); Snd_assert_channel(S_insert_sample, snd, chn_n, 3); cp = get_cp(snd, chn_n, S_insert_sample); if (!cp) return(Xen_false); beg = beg_to_sample(samp_n, S_insert_sample); pos = to_c_edit_position(cp, edpos, S_insert_sample, 5); fval = Xen_real_to_C_double(val); ival[0] = fval; #if HAVE_FORTH origin = mus_format("%lld %.4f %s drop", beg, fval, S_insert_sample); #else origin = mus_format("%s" PROC_OPEN "%lld" PROC_SEP "%.4f", to_proc_name(S_insert_sample), beg, fval); #endif if (insert_samples(beg, 1, ival, cp, origin, pos)) update_graph(cp); free(origin); return(val); } static Xen g_insert_samples(Xen samp, Xen samps, Xen vect, Xen snd, Xen chn_n, Xen edpos, Xen auto_delete, Xen caller) { #define H_insert_samples "(" S_insert_samples " start-samp samps data :optional snd chn edpos auto-delete origin): \ insert data (either a " S_vct ", a list of samples, or a filename) into snd's channel chn starting at 'start-samp' for 'samps' samples" chan_info *cp; int pos; char *origin = NULL; file_delete_t delete_file = DONT_DELETE_ME; mus_long_t beg, len = 0; Xen_check_type(Xen_is_integer(samp), samp, 1, S_insert_samples, "an integer"); Xen_check_type(Xen_is_integer(samps), samps, 2, S_insert_samples, "an integer"); Snd_assert_channel(S_insert_samples, snd, chn_n, 4); Xen_check_type(Xen_is_string_or_unbound(caller), caller, 8, S_insert_samples, "a string"); cp = get_cp(snd, chn_n, S_insert_samples); if (!cp) return(Xen_false); beg = beg_to_sample(samp, S_insert_samples); len = Xen_llong_to_C_llong(samps); if (len <= 0) return(samps); pos = to_c_edit_position(cp, edpos, S_insert_samples, 6); Xen_check_type(Xen_is_integer_boolean_or_unbound(auto_delete), auto_delete, 7, S_insert_samples, "a boolean or an integer"); delete_file = xen_to_file_delete_t(auto_delete, S_insert_samples); if (Xen_is_string(caller)) origin = mus_strdup(Xen_string_to_C_string(caller)); if (Xen_is_string(vect)) { char *filename; filename = mus_expand_filename(Xen_string_to_C_string(vect)); if (!mus_file_probe(filename)) { free(filename); return(snd_no_such_file_error(S_insert_samples, vect)); } if (mus_sound_framples(filename) <= 0) return(Xen_integer_zero); #if HAVE_FORTH if (!origin) origin = mus_format("%lld" PROC_SEP "%lld \"%s\" %s drop", beg, len, filename, S_insert_samples); #else if (!origin) origin = mus_format("%s" PROC_OPEN "%lld" PROC_SEP "%lld" PROC_SEP "\"%s\"", to_proc_name(S_insert_samples), beg, len, filename); #endif file_insert_samples(beg, len, filename, cp, 0, delete_file, origin, pos); if (filename) free(filename); } else { if (mus_is_vct(vect)) { vct *v; v = Xen_to_vct(vect); if (len > mus_vct_length(v)) len = mus_vct_length(v); if (!origin) origin = mus_strdup(to_proc_name(S_insert_samples)); insert_samples(beg, len, mus_vct_data(v), cp, origin, pos); } else { int ilen; mus_float_t *ivals; ilen = (int)len; ivals = g_floats_to_samples(vect, &ilen, S_insert_samples, 3); if (ivals) { if (!origin) origin = mus_strdup(to_proc_name(S_insert_samples)); insert_samples(beg, (mus_long_t)ilen, ivals, cp, origin, pos); free(ivals); } } } if (origin) free(origin); update_graph(cp); return(C_llong_to_Xen_llong(len)); } static Xen g_insert_samples_with_origin(Xen samp, Xen samps, Xen origin, Xen vect, Xen snd, Xen chn_n, Xen edpos, Xen date) { chan_info *cp; int pos; mus_long_t beg, len; Xen_check_type(Xen_is_integer(samp), samp, 1, S_insert_samples_with_origin, "an integer"); Xen_check_type(Xen_is_integer(samps), samps, 2, S_insert_samples_with_origin, "an integer"); Xen_check_type(Xen_is_string(origin), origin, 3, S_insert_samples_with_origin, "a string"); Xen_check_type(Xen_is_string(vect), vect, 4, S_insert_samples_with_origin, "a filename"); Snd_assert_channel(S_insert_samples_with_origin, snd, chn_n, 5); cp = get_cp(snd, chn_n, S_insert_samples_with_origin); if (!cp) return(Xen_false); beg = beg_to_sample(samp, S_insert_samples_with_origin); len = Xen_llong_to_C_llong(samps); if (len <= 0) return(samps); pos = to_c_edit_position(cp, edpos, S_insert_samples_with_origin, 7); check_saved_temp_file("sound", vect, date); file_insert_samples(beg, len, Xen_string_to_C_string(vect), cp, 0, DONT_DELETE_ME, Xen_string_to_C_string(origin), pos); update_graph(cp); return(C_llong_to_Xen_llong(len)); } static Xen g_delete_sample(Xen samp_n, Xen snd, Xen chn_n, Xen edpos) { #define H_delete_sample "(" S_delete_sample " samp :optional snd chn edpos): delete sample 'samp' from snd's channel chn" chan_info *cp; mus_long_t samp; int pos; Xen_check_type(Xen_is_integer(samp_n), samp_n, 1, S_delete_sample, "an integer"); Snd_assert_channel(S_delete_sample, snd, chn_n, 2); cp = get_cp(snd, chn_n, S_delete_sample); if (!cp) return(Xen_false); samp = beg_to_sample(samp_n, S_delete_sample); pos = to_c_edit_position(cp, edpos, S_delete_sample, 4); if ((samp < 0) || (samp > cp->edits[pos]->samples)) Xen_error(NO_SUCH_SAMPLE, Xen_list_2(C_string_to_Xen_string(S_delete_sample ": no such sample: ~A"), samp_n)); if (delete_samples(samp, 1, cp, pos)) update_graph(cp); return(samp_n); } static Xen g_delete_samples(Xen samp_n, Xen samps, Xen snd, Xen chn_n, Xen edpos) { #define H_delete_samples "(" S_delete_samples " start-samp samps :optional snd chn edpos): \ delete 'samps' samples from snd's channel chn starting at 'start-samp'" chan_info *cp; int pos; mus_long_t samp, len; Xen_check_type(Xen_is_integer(samp_n), samp_n, 1, S_delete_samples, "an integer"); Xen_check_type(Xen_is_integer(samps), samps, 2, S_delete_samples, "an integer"); Snd_assert_channel(S_delete_samples, snd, chn_n, 3); cp = get_cp(snd, chn_n, S_delete_samples); if (!cp) return(Xen_false); pos = to_c_edit_position(cp, edpos, S_delete_samples, 6); samp = beg_to_sample(samp_n, S_delete_samples); len = Xen_llong_to_C_llong(samps); if (len <= 0) return(Xen_false); if (delete_samples(samp, len, cp, pos)) update_graph(cp); return(samp_n); } /* -------- re-direct CLM input (ina etc) to use samplers -------- */ #include "clm2xen.h" static int snd_to_sample_tag = 0; typedef struct { mus_any_class *core; snd_info *sp; snd_fd **sfs; int chans; mus_long_t *samps; } snd_to_sample; static bool is_snd_to_sample(mus_any *ptr) {return(mus_type(ptr) == snd_to_sample_tag);} static bool snd_to_sample_equalp(mus_any *p1, mus_any *p2) {return(p1 == p2);} static int snd_to_sample_channels(mus_any *ptr) {return(((snd_to_sample *)ptr)->chans);} static mus_long_t snd_to_sample_location(mus_any *ptr) {return(((snd_to_sample *)ptr)->samps[0]);} static char *snd_to_sample_file_name(mus_any *ptr) {return(((snd_to_sample *)ptr)->sp->filename);} static mus_long_t snd_to_sample_length(mus_any *ptr) {return(current_samples(((snd_to_sample *)ptr)->sp->chans[0]));} static void snd_to_sample_free(mus_any *ptr) { snd_to_sample *spl = (snd_to_sample *)ptr; if (spl->sfs) { int i; for (i = 0; i < spl->chans; i++) spl->sfs[i] = free_snd_fd(spl->sfs[i]); free(spl->sfs); spl->sfs = NULL; } if (spl->samps) { free(spl->samps); spl->samps = NULL; } free(spl); } static char *snd_to_sample_describe(mus_any *ptr) { char *snd_to_sample_buf = NULL; int i, len = PRINT_BUFFER_SIZE; snd_to_sample *spl = (snd_to_sample *)ptr; char *temp; if (spl->sfs) { len += spl->chans * 8; for (i = 0; i < spl->chans; i++) if (spl->sfs[i]) { temp = sampler_to_string(spl->sfs[i]); if (temp) { len += mus_strlen(temp); free(temp); } } } snd_to_sample_buf = (char *)calloc(len, sizeof(char)); snprintf(snd_to_sample_buf, len, "%s reading %s (%d chan%s) at %lld:[", mus_name(ptr), spl->sp->short_filename, spl->chans, (spl->chans > 1) ? "s" : "", spl->samps[0]); if (spl->sfs) { for (i = 0; i < spl->chans; i++) if (spl->sfs[i]) { temp = sampler_to_string(spl->sfs[i]); if (temp) { strcat(snd_to_sample_buf, temp); free(temp); } if (i < spl->chans - 1) strcat(snd_to_sample_buf, ", "); else strcat(snd_to_sample_buf, "]"); } else strcat(snd_to_sample_buf, "nil, "); } else strcat(snd_to_sample_buf, "no readers]"); return(snd_to_sample_buf); } static mus_float_t snd_to_sample_read(mus_any *ptr, mus_long_t frample, int chan) { snd_to_sample *spl = (snd_to_sample *)ptr; mus_long_t diff, i; if (!(spl->sfs)) spl->sfs = (snd_fd **)calloc(spl->chans, sizeof(snd_fd *)); if (!(spl->sfs[chan])) { spl->sfs[chan] = init_sample_read(frample, spl->sp->chans[chan], READ_FORWARD); spl->samps[chan] = frample; return(next_sample_value(spl->sfs[chan])); } diff = frample - spl->samps[chan]; if (diff == 1) { spl->samps[chan]++; return(next_sample_value(spl->sfs[chan])); } if (diff > 1) { for (i = 1; i < diff; i++) next_sample_value(spl->sfs[chan]); /* just push pointer forward */ spl->samps[chan] = frample; return(next_sample_value(spl->sfs[chan])); } diff = -diff; for (i = 0; i <= diff; i++) previous_sample_value(spl->sfs[chan]); /* just push pointer backward (one too far) */ spl->samps[chan] = frample; return(next_sample_value(spl->sfs[chan])); /* always end up going forward (for simpler code) */ } static mus_any_class *snd_to_sample_class; static mus_any *make_snd_to_sample(snd_info *sp) { snd_to_sample *gen; gen = (snd_to_sample *)calloc(1, sizeof(snd_to_sample)); gen->core = snd_to_sample_class; gen->chans = sp->nchans; gen->sp = sp; gen->samps = (mus_long_t *)calloc(sp->nchans, sizeof(mus_long_t)); gen->sfs = NULL; /* created as needed */ return((mus_any *)gen); } static Xen g_is_snd_to_sample(Xen os) { #define H_is_snd_to_sample "(" S_is_snd_to_sample " gen): " PROC_TRUE " if gen is an " S_snd_to_sample " generator" return(C_bool_to_Xen_boolean((mus_is_xen(os)) && (is_snd_to_sample(Xen_to_mus_any(os))))); } static Xen g_snd_to_sample(Xen os, Xen frample, Xen chan) { #define H_snd_to_sample "(" S_snd_to_sample " gen frample chan): input sample (via snd->sample gen) at frample in channel chan" Xen_check_type((mus_is_xen(os)) && (is_snd_to_sample(Xen_to_mus_any(os))), os, 1, S_snd_to_sample, "a " S_snd_to_sample " gen"); Xen_check_type(Xen_is_llong(frample), frample, 2, S_snd_to_sample, "an integer"); Xen_check_type(Xen_is_integer_or_unbound(chan), chan, 3, S_snd_to_sample, "an integer"); return(C_double_to_Xen_real(snd_to_sample_read((mus_any *)Xen_to_mus_any(os), Xen_llong_to_C_llong(frample), (Xen_is_integer(chan)) ? Xen_integer_to_C_int(chan) : 0))); } static Xen g_make_snd_to_sample(Xen snd) { #define H_make_snd_to_sample "(" S_make_snd_to_sample " snd): return a new " S_snd_to_sample " (Snd to CLM input) generator" mus_any *ge; snd_info *sp; Snd_assert_sound(S_make_snd_to_sample, snd, 1); sp = get_sp(snd); if (sp == NULL) return(snd_no_such_sound_error(S_make_snd_to_sample, snd)); ge = make_snd_to_sample(sp); if (ge) return(mus_xen_to_object(mus_any_to_mus_xen(ge))); return(Xen_false); } static Xen g_edit_list_to_function(Xen snd, Xen chn, Xen start, Xen end) { #define H_edit_list_to_function "(" S_edit_list_to_function " :optional snd chn start end): function encapsulating edits" chan_info *cp; char *funcstr = NULL; Xen func; int start_pos = 1, end_pos = -1; Snd_assert_channel(S_edit_list_to_function, snd, chn, 1); cp = get_cp(snd, chn, S_edit_list_to_function); if (!cp) return(Xen_false); Xen_check_type(Xen_is_integer_or_unbound(start), start, 3, S_edit_list_to_function, "an integer"); Xen_check_type(Xen_is_integer_or_unbound(end), end, 4, S_edit_list_to_function, "an integer"); if (Xen_is_integer(start)) start_pos = Xen_integer_to_C_int(start); if (start_pos < 0) /* is 0 legal here? */ Xen_out_of_range_error(S_edit_list_to_function, 3, start, "a non-negative integer"); if (Xen_is_integer(end)) end_pos = Xen_integer_to_C_int(end); funcstr = edit_list_to_function(cp, start_pos, end_pos); func = Xen_eval_C_string(funcstr); #if HAVE_RUBY rb_set_property(rb_obj_id(func), C_string_to_Xen_symbol("proc_source"), C_string_to_Xen_string(funcstr)); #endif #if HAVE_FORTH fth_proc_source_set(func, C_string_to_Xen_string(funcstr)); #endif free(funcstr); return(func); } #if HAVE_SCHEME static s7_double next_sample_rf_s(s7_scheme *sc, s7_pointer **p) { snd_fd *fd; fd = (snd_fd *)(*(*p)); (*p)++; return(protected_next_sample(fd)); } static s7_double read_sample_rf_s(s7_scheme *sc, s7_pointer **p) { snd_fd *fd; fd = (snd_fd *)(*(*p)); (*p)++; return(read_sample(fd)); } static s7_double next_mix_sample_rf_s(s7_scheme *sc, s7_pointer **p) { snd_fd *fd; fd = (snd_fd *)(*(*p)); (*p)++; return(protected_next_sample(fd)); } static s7_double read_mix_sample_rf_s(s7_scheme *sc, s7_pointer **p) { snd_fd *fd; fd = (snd_fd *)(*(*p)); (*p)++; return(read_sample(fd)); } static s7_rf_t read_sample_rf(s7_scheme *sc, s7_pointer expr) { s7_pointer sym, o; snd_fd *g; if (!s7_is_null(sc, s7_cddr(expr))) return(NULL); /* just (gen s) for now */ sym = s7_cadr(expr); if (!s7_is_symbol(sym)) return(NULL); if (s7_xf_is_stepper(sc, sym)) return(NULL); o = s7_symbol_value(sc, sym); g = (snd_fd *)s7_object_value_checked(o, sf_tag); if (g) { s7_xf_store(sc, (s7_pointer)g); return(read_sample_rf_s); } if (is_mix_sampler(o)) { s7_xf_store(sc, (s7_pointer)mf_to_snd_fd(s7_object_value(o))); return(read_mix_sample_rf_s); } return(NULL); } static s7_rf_t next_sample_rf(s7_scheme *sc, s7_pointer expr) { s7_pointer sym, o; snd_fd *g; if (!s7_is_null(sc, s7_cddr(expr))) return(NULL); sym = s7_cadr(expr); if (!s7_is_symbol(sym)) return(NULL); if (s7_xf_is_stepper(sc, sym)) return(NULL); o = s7_symbol_value(sc, sym); g = (snd_fd *)s7_object_value_checked(o, sf_tag); if (g) { s7_xf_store(sc, (s7_pointer)g); return(next_sample_rf_s); } if (is_mix_sampler(o)) { s7_xf_store(sc, (s7_pointer)mf_to_snd_fd(s7_object_value(o))); return(next_mix_sample_rf_s); } return(NULL); } static s7_pointer is_sampler_at_end_pf_s(s7_scheme *sc, s7_pointer **p) { snd_fd *fd; fd = (snd_fd *)(*(*p)); (*p)++; return(s7_make_boolean(sc, fd->at_eof)); } static s7_pf_t is_sampler_at_end_pf(s7_scheme *sc, s7_pointer expr) { s7_pointer sym, o; snd_fd *g; if (!s7_is_null(sc, s7_cddr(expr))) return(NULL); sym = s7_cadr(expr); if (!s7_is_symbol(sym)) return(NULL); if (s7_xf_is_stepper(sc, sym)) return(NULL); o = s7_symbol_value(sc, sym); g = (snd_fd *)s7_object_value_checked(o, sf_tag); if (g) { s7_xf_store(sc, (s7_pointer)g); return(is_sampler_at_end_pf_s); } if (is_mix_sampler(o)) { s7_xf_store(sc, (s7_pointer)mf_to_snd_fd(s7_object_value(o))); return(is_sampler_at_end_pf_s); } return(NULL); } #endif Xen_wrap_5_optional_args(g_make_sampler_w, g_make_sampler) Xen_wrap_4_optional_args(g_make_region_sampler_w, g_make_region_sampler) Xen_wrap_1_arg(g_next_sample_w, g_next_sample) Xen_wrap_1_arg(g_read_sample_w, g_read_sample) Xen_wrap_2_args(g_read_sample_with_direction_w, g_read_sample_with_direction) Xen_wrap_1_arg(g_previous_sample_w, g_previous_sample) Xen_wrap_1_arg(g_free_sampler_w, g_free_sampler) Xen_wrap_1_arg(g_sampler_home_w, g_sampler_home) Xen_wrap_1_arg(g_sampler_position_w, g_sampler_position) Xen_wrap_1_arg(g_is_sampler_w, g_is_sampler) Xen_wrap_1_arg(g_region_is_sampler_w, g_region_is_sampler) Xen_wrap_1_arg(g_sampler_at_end_w, g_sampler_at_end) Xen_wrap_1_arg(g_copy_sampler_w, g_copy_sampler) Xen_wrap_3_optional_args(g_save_edit_history_w, g_save_edit_history) Xen_wrap_3_optional_args(g_edit_fragment_w, g_edit_fragment) Xen_wrap_3_optional_args(g_undo_w, g_undo) Xen_wrap_3_optional_args(g_redo_w, g_redo) Xen_wrap_2_optional_args(g_as_one_edit_w, g_as_one_edit) Xen_wrap_3_optional_args(g_display_edits_w, g_display_edits) Xen_wrap_3_optional_args(g_edit_tree_w, g_edit_tree) Xen_wrap_4_optional_args(g_delete_sample_w, g_delete_sample) Xen_wrap_5_optional_args(g_delete_samples_w, g_delete_samples) Xen_wrap_5_optional_args(g_insert_sample_w, g_insert_sample) Xen_wrap_8_optional_args(g_insert_samples_w, g_insert_samples) Xen_wrap_7_optional_args(g_vct_to_channel_w, g_vct_to_channel) Xen_wrap_5_optional_args(g_channel_to_vct_w, g_channel_to_vct) Xen_wrap_7_optional_args(g_insert_sound_w, g_insert_sound) Xen_wrap_6_optional_args(g_scale_channel_w, g_scale_channel) Xen_wrap_6_optional_args(g_normalize_channel_w, g_normalize_channel) Xen_wrap_8_optional_args(g_change_samples_with_origin_w, g_change_samples_with_origin) Xen_wrap_8_optional_args(g_insert_samples_with_origin_w, g_insert_samples_with_origin) Xen_wrap_6_optional_args(g_override_samples_with_origin_w, g_override_samples_with_origin) Xen_wrap_4_optional_args(g_sample_w, g_sample) #if HAVE_SCHEME #define g_set_sample_w g_set_sample_reversed #define g_set_samples_w g_set_samples_reversed Xen_wrap_5_optional_args(orig_g_set_sample_w, g_set_sample) #else Xen_wrap_5_optional_args(g_set_sample_w, g_set_sample) Xen_wrap_any_args(g_set_samples_w, g_set_samples_any) #endif Xen_wrap_any_args(orig_g_set_samples_w, g_set_samples_any) Xen_wrap_5_optional_args(g_samples_w, g_samples) Xen_wrap_1_arg(g_is_snd_to_sample_w, g_is_snd_to_sample) Xen_wrap_3_optional_args(g_snd_to_sample_w, g_snd_to_sample) Xen_wrap_1_optional_arg(g_make_snd_to_sample_w, g_make_snd_to_sample) Xen_wrap_4_optional_args(g_edit_list_to_function_w, g_edit_list_to_function) Xen_wrap_1_arg(g_edit_fragment_type_name_w, g_edit_fragment_type_name) void g_init_edits(void) { #if HAVE_SCHEME sf_tag = s7_new_type_x(s7, "", print_sf, free_sf, s7_equalp_sf, NULL, s7_read_sample, NULL, length_sf, NULL, NULL, NULL); #else sf_tag = Xen_make_object_type("Sampler", sizeof(snd_fd)); #endif #if HAVE_RUBY rb_define_method(sf_tag, "to_s", Xen_procedure_cast print_sf, 0); rb_define_method(sf_tag, "call", Xen_procedure_cast g_read_sample, 0); #endif #if HAVE_FORTH fth_set_object_inspect(sf_tag, print_sf); fth_set_object_free(sf_tag, free_sf); fth_set_object_apply(sf_tag, Xen_procedure_cast g_read_sample, 0, 0, 0); #endif Xen_define_constant(S_current_edit_position, AT_CURRENT_EDIT_POSITION, "represents the current edit history list position (-1)"); Xen_define_safe_procedure(S_make_sampler, g_make_sampler_w, 0, 5, 0, H_make_sampler); Xen_define_safe_procedure(S_make_region_sampler, g_make_region_sampler_w, 1, 3, 0, H_make_region_sampler); Xen_define_safe_procedure(S_read_sample, g_read_sample_w, 1, 0, 0, H_read_sample); Xen_define_safe_procedure(S_read_sample_with_direction, g_read_sample_with_direction_w, 2, 0, 0, H_read_sample_with_direction); Xen_define_safe_procedure(S_read_region_sample, g_read_sample_w, 1, 0, 0, H_read_sample); Xen_define_safe_procedure(S_next_sample, g_next_sample_w, 1, 0, 0, H_next_sample); Xen_define_safe_procedure(S_previous_sample, g_previous_sample_w, 1, 0, 0, H_previous_sample); Xen_define_safe_procedure(S_free_sampler, g_free_sampler_w, 1, 0, 0, H_free_sampler); Xen_define_safe_procedure(S_sampler_home, g_sampler_home_w, 1, 0, 0, H_sampler_home); Xen_define_safe_procedure(S_is_sampler, g_is_sampler_w, 1, 0, 0, H_is_sampler); Xen_define_safe_procedure(S_is_region_sampler, g_region_is_sampler_w, 1, 0, 0, H_region_is_sampler); Xen_define_safe_procedure(S_is_sampler_at_end, g_sampler_at_end_w, 1, 0, 0, H_sampler_at_end); Xen_define_safe_procedure(S_sampler_position, g_sampler_position_w, 1, 0, 0, H_sampler_position); Xen_define_safe_procedure(S_copy_sampler, g_copy_sampler_w, 1, 0, 0, H_copy_sampler); Xen_define_safe_procedure(S_save_edit_history, g_save_edit_history_w, 1, 2, 0, H_save_edit_history); Xen_define_safe_procedure(S_edit_fragment, g_edit_fragment_w, 0, 3, 0, H_edit_fragment); Xen_define_safe_procedure(S_edit_fragment_type_name,g_edit_fragment_type_name_w, 1, 0, 0, "internal testing function"); Xen_define_safe_procedure(S_undo, g_undo_w, 0, 3, 0, H_undo); #if HAVE_RUBY Xen_define_procedure("undo_edit", g_undo_w, 0, 3, 0, H_undo); #endif Xen_define_safe_procedure(S_redo, g_redo_w, 0, 3, 0, H_redo); Xen_define_procedure(S_as_one_edit, g_as_one_edit_w, 1, 1, 0, H_as_one_edit); Xen_define_safe_procedure(S_display_edits, g_display_edits_w, 0, 3, 0, H_display_edits); Xen_define_safe_procedure(S_edit_tree, g_edit_tree_w, 0, 3, 0, H_edit_tree); Xen_define_safe_procedure(S_delete_sample, g_delete_sample_w, 1, 3, 0, H_delete_sample); Xen_define_safe_procedure(S_delete_samples, g_delete_samples_w, 2, 3, 0, H_delete_samples); Xen_define_safe_procedure(S_insert_sample, g_insert_sample_w, 2, 3, 0, H_insert_sample); Xen_define_safe_procedure(S_insert_samples, g_insert_samples_w, 3, 5, 0, H_insert_samples); Xen_define_safe_procedure(S_vct_to_channel, g_vct_to_channel_w, 1, 6, 0, H_vct_to_channel); Xen_define_safe_procedure(S_channel_to_vct, g_channel_to_vct_w, 0, 5, 0, H_channel_to_vct); Xen_define_safe_procedure(S_insert_sound, g_insert_sound_w, 1, 6, 0, H_insert_sound); Xen_define_safe_procedure(S_scale_channel, g_scale_channel_w, 1, 5, 0, H_scale_channel); Xen_define_safe_procedure(S_normalize_channel, g_normalize_channel_w, 1, 5, 0, H_normalize_channel); Xen_define_procedure(S_change_samples_with_origin, g_change_samples_with_origin_w, 7, 1, 0, "internal function used in save-state"); Xen_define_procedure(S_insert_samples_with_origin, g_insert_samples_with_origin_w, 7, 1, 0, "internal function used in save-state"); Xen_define_procedure(S_override_samples_with_origin, g_override_samples_with_origin_w, 5, 1, 0, "internal function used in save-state"); Xen_define_dilambda(S_sample, g_sample_w, H_sample, S_set S_sample, g_set_sample_w, 0, 4, 1, 4); Xen_define_dilambda(S_samples, g_samples_w, H_samples, S_set S_samples, g_set_samples_w, 0, 5, 3, 7); #if HAVE_SCHEME Xen_define_procedure("set-sample", orig_g_set_sample_w, 2, 3, 0, H_sample); /* for edit-list->function */ #endif Xen_define_procedure("set-samples", orig_g_set_samples_w, 0, 0, 1, H_set_samples); Xen_define_safe_procedure(S_is_snd_to_sample, g_is_snd_to_sample_w, 1, 0, 0, H_is_snd_to_sample); Xen_define_procedure(S_make_snd_to_sample, g_make_snd_to_sample_w, 0, 1, 0, H_make_snd_to_sample); Xen_define_procedure(S_snd_to_sample, g_snd_to_sample_w, 2, 1, 0, H_snd_to_sample); Xen_define_procedure(S_edit_list_to_function, g_edit_list_to_function_w, 0, 4, 0, H_edit_list_to_function); #define H_save_hook S_save_hook " (snd name): called each time a file is about to be saved. \ If it returns " PROC_TRUE ", the file is not saved. 'name' is " PROC_FALSE " unless the file is being saved under a new name (as in sound-save-as)." save_hook = Xen_define_hook(S_save_hook, "(make-hook 'snd 'name)", 2, H_save_hook); #define H_save_state_hook S_save_state_hook " (temp-filename): called each time the " S_save_state " \ mechanism is about to create a new temporary file to save some edit history sample values. \ temp-filename is the current file. \ If the hook returns a string, it is treated as the new temp filename. This hook provides a way to \ keep track of which files are in a given saved state batch, and a way to rename or redirect those files." save_state_hook = Xen_define_hook(S_save_state_hook, "(make-hook 'name)", 1, H_save_state_hook); snd_to_sample_tag = mus_make_generator_type(); snd_to_sample_class = mus_make_generator(snd_to_sample_tag, (char *)S_snd_to_sample, snd_to_sample_free, snd_to_sample_describe, snd_to_sample_equalp); mus_generator_set_length(snd_to_sample_class, snd_to_sample_length); mus_generator_set_channels(snd_to_sample_class, snd_to_sample_channels); mus_generator_set_read_sample(snd_to_sample_class, snd_to_sample_read); mus_generator_set_file_name(snd_to_sample_class, snd_to_sample_file_name); mus_generator_set_location(snd_to_sample_class, snd_to_sample_location); mus_generator_set_extended_type(snd_to_sample_class, MUS_INPUT); #if HAVE_SCHEME { s7_pointer f; edit_finish = s7_make_function(s7, "(finish-as-one-edit)", g_edit_finish, 0, 0, false, ""); f = s7_name_to_value(s7, "next-sample"); s7_rf_set_function(f, next_sample_rf); f = s7_name_to_value(s7, "read-sample"); s7_rf_set_function(f, read_sample_rf); f = s7_name_to_value(s7, "sampler-at-end?"); s7_pf_set_function(f, is_sampler_at_end_pf); } #endif #if DEBUG_EDIT_TABLES /* consistency checks for the accessor state table */ init_hit_entries(); check_type_info_entry(ED_SIMPLE, 0, 0, 0, false); check_type_info_entry(ED_ZERO, 0, 0, 0, true); report_unhit_entries(); #endif } /* from Anders: How to have the trees displayed in a meaningful manner, especially related to common-music type work? Maybe the edits could be given optional names? ie. "inversed", "prolongue-1", "scale-1" etc. - and a more specialised graphing system put together. If all this is based on closures, doing "Select-All", should it write out a temp-file of the state as now? And how to import it into some arbitrary place in the tree again? Would pasting it in be analogous to take a certain stage of the edit-history and append the rest? */ snd-16.1/marks.fs0000644000076400007640000001250612306421672012011 0ustar bilbil\ marks.fs -- marks.scm|rb -> marks.fs \ Author: Michael Scholz \ Created: Tue Dec 27 19:22:06 CET 2005 \ Changed: Wed Nov 21 19:52:34 CET 2012 \ Commentary: \ \ add-named-mark ( samp name snd chn -- mark ) \ mark-name->id ( name -- m ) \ move-syncd-marks ( sync diff -- ) \ describe-mark ( id -- ary ) \ \ save-mark-properties ( -- ) \ mark-click-info ( id -- #t ) \ marks->string ( snd -- str ) \ Code: require clm require examp <'> integer? alias channel? \ snd #f: all sounds \ chn #f: all channels : marks-length <{ :optional snd #f chn #f edpos #f -- len }> snd sound? if chn channel? if snd chn edpos marks else snd chn edpos marks car then else snd chn edpos marks car car then length ; : marks? ( :optional snd chn edpos -- f ) marks-length 0> ; \ from rubber.fs : add-named-mark { samp name snd chn -- mark } samp snd chn add-mark { m } m name set-mark-name drop m ; \ mark-name->id is a global version of find-mark : mark-name->id ( name -- m ) doc" Like find-mark but searche all currently accessible channels." { name } #f \ flag sounds each { snd } snd channels 0 ?do name snd i undef find-mark { m } m mark? if drop \ replace #f with mark m exit then loop end-each ; : move-syncd-marks ( sync diff -- ) doc" Move all marks sharing SYNC by DIFF samples." { syn diff } syn syncd-marks each { m } m undef mark-sample diff + { val } m val set-mark-sample drop end-each ; : describe-mark ( id -- ary ) doc" Return a description of the movements of mark ID over \ the channel's edit history." { id } id <'> mark-home 'no-such-mark nil fth-catch if sounds each { snd } snd channels 0 ?do 0 snd i ( chn ) edits each + end-each 1+ ( max-edits ) 0 ?do snd j ( chn ) #f marks { m } m id m array-member? && if #( snd j ( chn ) ) leave then loop loop end-each then { mark-setting } mark-setting array? if mark-setting 0 array-ref { snd } mark-setting 1 array-ref { chn } #( #( 'mark id 'sound snd snd short-file-name 'channel chn ) ) { descr } 0 snd chn edits each + end-each 1+ 1 ?do descr snd chn i marks id array-member? if id i mark-sample else #f then array-push drop loop descr else 'no-such-mark #( "%s: %s" get-func-name id ) fth-throw then ; \ --- Mark Properties --- hide : mark-writeit { mp mhome msamp io -- } io "\t%S 0 find-sound to snd\n" #( mhome 0 array-ref file-name ) io-write-format io "\tsnd sound? if\n" io-write io " %d snd %d find-mark to mk\n" #( msamp mhome 1 array-ref ) io-write-format io "\t\tmk mark? if\n" io-write io "\t\t\tmk %S set-mark-properties\n" #( mp ) io-write-format io "\t\tthen\n" io-write io "\tthen\n" io-write ; : save-mark-properties-cb <{ filename -- }> undef undef undef marks car car cons? if filename :fam a/o io-open { io } io "\n\\ from save-mark-properties in %s\n" #( *filename* ) io-write-format io "require marks\n\n" io-write io "let: ( -- )\n" io-write io "\tnil nil { snd mk }\n" io-write undef undef undef marks each ( snd-m ) each ( chn-m ) each { m } m mark-properties { mp } mp if m mark-home { mhome } m undef mark-sample { msamp } mp mhome msamp io mark-writeit then end-each end-each end-each io ";let\n" io-write io io-close then ; set-current : save-mark-properties ( -- ) doc" Set up an after-save-state-hook \ function to save any mark-properties." after-save-state-hook <'> save-mark-properties-cb add-hook! ; previous : mark-click-info <{ id -- #t }> doc" A mark-click-hook function that describes a \ mark and its properties.\n\ mark-click-hook <'> mark-click-info add-hook!." " mark id: %s\n" #( id ) string-format make-string-output-port { prt } id mark-name empty? unless prt " name: %s\n" #( id mark-name ) port-puts-format then prt " sample: %s (%.3f secs)\n" #( id undef mark-sample dup id mark-home 0 array-ref srate f/ ) port-puts-format id mark-sync if prt " sync: %s\n" #( id mark-sync ) port-puts-format then id mark-properties { props } props empty? unless prt " properties: %s" #( props ) port-puts-format then "Mark Info" prt port->string info-dialog drop #t ; \ mark-click-hook <'> mark-click-info add-hook! \ This code saves mark info in the sound file header, and reads it \ back in when the sound is later reopened. : marks->string { snd -- str } "\nrequire marks\n" make-string-output-port { prt } prt "let: ( -- )\n" port-puts prt "\t#f { mr }\n" port-puts snd marks each { chan-marks } prt "\n\t\\ channel %d\n" #( i ) port-puts-format chan-marks each { m } m nil? ?leave "\t%s #f %d %S %d add-mark to mk\n" #( m undef mark-sample j ( chn ) m mark-name length 0= if #f else m mark-name then m mark-sync ) port-puts-format m mark-properties { props } props if "\tmk %S set-mark-properties\n" #( props ) port-puts-format then end-each end-each prt ";let\n" port-puts prt port->string ; 0 [if] output-comment-hook lambda: <{ str }> selected-sound marks->string ; add-hook! after-open-hook lambda: <{ snd -- }> snd comment ( str ) <'> string-eval #t nil fth-catch if ( str ) drop then ; add-hook! [then] \ marks.fs ends here snd-16.1/v.scm0000644000076400007640000001615512616231602011313 0ustar bilbil(provide 'snd-v.scm) (if (provided? 'snd) (require snd-ws.scm) (require sndlib-ws.scm)) (define default-index-env (float-vector 0 1 25 .4 75 .6 100 0)) (define default-amp-env (float-vector 0 0 25 1 75 1 100 0)) (define default-gliss-env (float-vector 0 0 100 0)) (definstrument (fm-violin startime dur frequency amplitude (fm-index 1.0) amp-env (periodic-vibrato-rate 5.0) (random-vibrato-rate 16.0) (periodic-vibrato-amplitude 0.0025) (random-vibrato-amplitude 0.005) (noise-amount 0.0) (noise-freq 1000.0) (ind-noise-freq 10.0) (ind-noise-amount 0.0) (amp-noise-freq 20.0) (amp-noise-amount 0.0) (gliss-env default-gliss-env) (glissando-amount 0.0) fm1-env fm2-env fm3-env (fm1-rat 1.0) (fm2-rat 3.0) (fm3-rat 4.0) fm1-index fm2-index fm3-index degree (distance 1.0) (reverb-amount 0.01) (base 1.0)) "(fm-violin startime dur frequency amplitude (fm-index 1.0) (amp-env '(0 0 25 1 75 1 100 0)) (periodic-vibrato-rate 5.0) (random-vibrato-rate 16.0) (periodic-vibrato-amplitude 0.0025) (random-vibrato-amplitude 0.005) (noise-amount 0.0) (noise-freq 1000.0) (ind-noise-freq 10.0) (ind-noise-amount 0.0) (amp-noise-freq 20.0) (amp-noise-amount 0.0) (gliss-env '(0 0 100 0)) (glissando-amount 0.0) (fm1-env '(0 1 25 .4 75 .6 100 0)) (fm2-env '(0 1 25 .4 75 .6 100 0)) (fm3-rat 4.0) (fm3-env '(0 1 25 .4 75 .6 100 0)) (fm1-rat 1.0) (fm2-rat 3.0) (fm1-index #f) (fm2-index #f) (fm3-index #f) (degree #f) (distance 1.0) (reverb-amount 0.01) (base 1.0)) (with-sound () (fm-violin 0 1 440 .1))" (let ((beg (seconds->samples startime)) (end (seconds->samples (+ startime dur))) (frq-scl (hz->radians frequency)) (logfreq (log frequency)) (sqrtfreq (sqrt frequency)) (maxdev (* (hz->radians frequency) fm-index))) (if (>= (* 2 fm1-rat frequency) *clm-srate*) (set! fm1-rat 1.0)) (if (>= (* 2 fm2-rat frequency) *clm-srate*) (set! fm2-rat 1.0)) (if (>= (* 2 fm3-rat frequency) *clm-srate*) (set! fm3-rat 1.0)) (let ((index1 (or fm1-index (min pi (* maxdev (/ 5.0 logfreq))))) (index2 (or fm2-index (min pi (* maxdev 3.0 (/ (- 8.5 logfreq) (+ 3.0 (* frequency .001))))))) (index3 (or fm3-index (min pi (* maxdev (/ 4.0 sqrtfreq))))) (easy-case (and (zero? noise-amount) (equal? fm1-env fm2-env) (equal? fm1-env fm3-env) (= fm1-rat (floor fm1-rat)) (= fm2-rat (floor fm2-rat)) (= fm3-rat (floor fm3-rat)) (integer? (rationalize (/ fm2-rat fm1-rat))) ; might be 2=2 but 1=3 or whatever (integer? (rationalize (/ fm3-rat fm1-rat)))))) (let ((norm (if easy-case 1.0 index1))) (let ((fmosc1 (if easy-case (make-polywave (* fm1-rat frequency) (list (floor fm1-rat) index1 (floor (/ fm2-rat fm1-rat)) index2 (floor (/ fm3-rat fm1-rat)) index3) mus-chebyshev-second-kind) (make-oscil (* fm1-rat frequency)))) (indf1 (make-env (or fm1-env default-index-env) norm :duration dur)) (indf2 (or easy-case (make-env (or fm2-env default-index-env) index2 :duration dur))) (indf3 (or easy-case (make-env (or fm3-env default-index-env) index3 :duration dur))) (frqf (make-env gliss-env (* glissando-amount frq-scl) :duration dur)) (pervib (make-triangle-wave periodic-vibrato-rate (* periodic-vibrato-amplitude frq-scl))) (ranvib (make-rand-interp random-vibrato-rate (* random-vibrato-amplitude frq-scl))) (fm-noi (and (not (zero? noise-amount)) (make-rand noise-freq (* pi noise-amount)))) (ind-noi (and (not (zero? ind-noise-amount)) (not (zero? ind-noise-freq)) (make-rand-interp ind-noise-freq ind-noise-amount))) (amp-noi (and (not (zero? amp-noise-amount)) (not (zero? amp-noise-freq)) (make-rand-interp amp-noise-freq amp-noise-amount))) (carrier (make-oscil frequency)) (fmosc2 (if (not easy-case) (make-oscil (* fm2-rat frequency)))) (fmosc3 (if (not easy-case) (make-oscil (* fm3-rat frequency)))) (ampf (make-env (or amp-env default-amp-env) :scaler amplitude :base base :duration dur)) (locs (make-locsig (or degree (random 90.0)) distance reverb-amount))) (if (or (not easy-case) ind-noi amp-noi fm-noi) (let ((fuzz 0.0) (vib 0.0) (anoi 1.0) (inoi 1.0)) (if easy-case ; no fm-noi here (do ((i beg (+ i 1))) ((= i end)) (if amp-noi (set! anoi (* (env ampf) (+ 1.0 (rand-interp amp-noi)))) (set! anoi (env ampf))) (if ind-noi (set! inoi (+ 1.0 (rand-interp ind-noi)))) (set! vib (+ (env frqf) (triangle-wave pervib) (rand-interp ranvib))) (locsig locs i (* anoi (oscil carrier (+ vib (* inoi (env indf1) (polywave fmosc1 vib))))))) (if (or ind-noi amp-noi fm-noi) (if (not (or ind-noi amp-noi)) (do ((i beg (+ i 1))) ((= i end)) (let ((fuzz (rand fm-noi)) (vib (+ (env frqf) (triangle-wave pervib) (rand-interp ranvib)))) (locsig locs i (* (env ampf) (oscil carrier (+ vib (+ (* (env indf1) (oscil fmosc1 (+ (* fm1-rat vib) fuzz))) (* (env indf2) (oscil fmosc2 (+ (* fm2-rat vib) fuzz))) (* (env indf3) (oscil fmosc3 (+ (* fm3-rat vib) fuzz)))))))))) (do ((i beg (+ i 1))) ((= i end)) (if fm-noi (set! fuzz (rand fm-noi))) (if amp-noi (set! anoi (* (env ampf) (+ 1.0 (rand-interp amp-noi)))) (set! anoi (env ampf))) (if ind-noi (set! inoi (+ 1.0 (rand-interp ind-noi)))) (set! vib (+ (env frqf) (triangle-wave pervib) (rand-interp ranvib))) (locsig locs i (* anoi (oscil carrier (+ vib (* inoi (+ (* (env indf1) (oscil fmosc1 (+ (* fm1-rat vib) fuzz))) (* (env indf2) (oscil fmosc2 (+ (* fm2-rat vib) fuzz))) (* (env indf3) (oscil fmosc3 (+ (* fm3-rat vib) fuzz))))))))))) (do ((i beg (+ i 1))) ((= i end)) (let ((vib (+ (env frqf) (triangle-wave pervib) (rand-interp ranvib)))) (locsig locs i (* (env ampf) (oscil carrier (+ vib (+ (* (env indf1) (oscil fmosc1 (* fm1-rat vib))) (* (env indf2) (oscil fmosc2 (* fm2-rat vib))) (* (env indf3) (oscil fmosc3 (* fm3-rat vib))))))))))))) (if (= (mus-scaler frqf) 0.0) (do ((i beg (+ i 1))) ((= i end)) (let ((vib (+ (triangle-wave pervib) (rand-interp ranvib)))) (locsig locs i (* (env ampf) (oscil carrier (+ vib (* (env indf1) (polywave fmosc1 vib)))))))) (do ((i beg (+ i 1))) ((= i end)) (let ((vib (+ (env frqf) (triangle-wave pervib) (rand-interp ranvib)))) (locsig locs i (* (env ampf) (oscil carrier (+ vib (* (env indf1) (polywave fmosc1 vib))))))))))))))) ;; (with-sound (:statistics #t) (fm-violin 0 10 440 .1 :fm-index 2.0)) ;; (with-sound (:statistics #t) (fm-violin 0 10 440 .1 :noise-amount .01)) ;; (with-sound (:statistics #t) (fm-violin 0 10 440 .1 :ind-noise-amount .01)) ;; (with-sound (:statistics #t) (fm-violin 0 10 440 .1 :fm1-rat 1.002)) snd-16.1/snd-gxcolormaps.c0000644000076400007640000010675512603035272013635 0ustar bilbil#include "snd.h" typedef struct { int size; char *name; rgb_t *r, *g, *b; Xen lambda; int gc_loc; mus_float_t **(*make_rgb)(int size, Xen func); void (*get_rgb)(float x, rgb_t *r, rgb_t *g, rgb_t *b); } cmap; static cmap **cmaps = NULL; static int cmaps_size = 0; #define NO_SUCH_COLORMAP Xen_make_error_type("no-such-colormap") bool is_colormap(int n) { return((n >= 0) && (n < cmaps_size) && (cmaps[n])); } char *colormap_name(int n) { if (is_colormap(n)) return(cmaps[n]->name); return(NULL); } int num_colormaps(void) { int i; for (i = cmaps_size - 1; i >= 0; i--) if (cmaps[i]) return(i + 1); return(0); } static cmap *delete_cmap(int index) { if (is_colormap(index)) { cmap *c; c = cmaps[index]; if (c->r) free(c->r); if (c->g) free(c->g); if (c->b) free(c->b); if (c->name) free(c->name); if (Xen_is_procedure(c->lambda)) snd_unprotect_at(c->gc_loc); free(c); cmaps[index] = NULL; } return(NULL); } static rgb_t *mus_float_ts_to_rgb_t(int size, mus_float_t *data) { int i; rgb_t *new_data; new_data = (rgb_t *)calloc(size, sizeof(rgb_t)); for (i = 0; i < size; i++) new_data[i] = float_to_rgb(data[i]); return(new_data); } static void rebuild_colormap(cmap *c) { mus_float_t **rgb; int i; /* release old colormap data */ if (c->r) free(c->r); if (c->g) free(c->g); if (c->b) free(c->b); c->size = color_map_size(ss); /* make new data */ rgb = (*(c->make_rgb))(c->size, c->lambda); c->r = mus_float_ts_to_rgb_t(c->size, rgb[0]); c->g = mus_float_ts_to_rgb_t(c->size, rgb[1]); c->b = mus_float_ts_to_rgb_t(c->size, rgb[2]); for (i = 0; i < 3; i++) free(rgb[i]); free(rgb); } void get_current_color(int index, int n, rgb_t *r, rgb_t *g, rgb_t *b) { if (is_colormap(index)) { cmap *c; c = cmaps[index]; if (c->get_rgb) (c->get_rgb)((float)n / (float)color_map_size(ss), r, g, b); else { if (color_map_size(ss) != c->size) rebuild_colormap(c); if (n < c->size) { (*r) = c->r[n]; (*g) = c->g[n]; (*b) = c->b[n]; } } } } #if HAVE_GL rgb_t *color_map_reds(int index) { if (is_colormap(index)) { cmap *c; c = cmaps[index]; if (c->get_rgb) return(NULL); if (color_map_size(ss) != c->size) rebuild_colormap(c); return(c->r); } return(NULL); } rgb_t *color_map_greens(int index) { if (is_colormap(index)) { cmap *c; c = cmaps[index]; if (c->get_rgb) return(NULL); if (color_map_size(ss) != c->size) rebuild_colormap(c); return(c->g); } return(NULL); } rgb_t *color_map_blues(int index) { if (is_colormap(index)) { cmap *c; c = cmaps[index]; if (c->get_rgb) return(NULL); if (color_map_size(ss) != c->size) rebuild_colormap(c); return(c->b); } return(NULL); } #endif static cmap *new_cmap(const char *name, int size, mus_float_t **rgb) { cmap *c = NULL; c = (cmap *)calloc(1, sizeof(cmap)); c->name = mus_strdup(name); c->size = size; if (rgb) { c->r = mus_float_ts_to_rgb_t(size, rgb[0]); c->g = mus_float_ts_to_rgb_t(size, rgb[1]); c->b = mus_float_ts_to_rgb_t(size, rgb[2]); } c->lambda = Xen_false; c->gc_loc = NOT_A_GC_LOC; return(c); } static cmap *make_builtin_cmap(int size, const char *name, mus_float_t **(*make_rgb)(int size, Xen ignored), void (*get_rgb)(float x, rgb_t *r, rgb_t *g, rgb_t *b)) { mus_float_t **rgb = NULL; cmap *c = NULL; if ((make_rgb) && (!get_rgb)) rgb = make_rgb(size, Xen_false); c = new_cmap(name, size, rgb); c->get_rgb = get_rgb; c->make_rgb = make_rgb; if (rgb) { int i; for (i = 0; i < 3; i++) free(rgb[i]); free(rgb); } return(c); } static mus_float_t **make_base_rgb(int size) { mus_float_t **rgb; int i; rgb = (mus_float_t **)calloc(3, sizeof(mus_float_t *)); for (i = 0; i < 3; i++) rgb[i] = (mus_float_t *)calloc(size, sizeof(mus_float_t)); return(rgb); } static char *add_colormap_func_error_msg = NULL; static bool add_colormap_func_hit_error = false; static void add_colormap_func_error(const char *msg, void *data) { add_colormap_func_hit_error = true; add_colormap_func_error_msg = mus_strdup(msg); /* msg itself is freed by the error handler in snd-xen.c */ } static mus_float_t **make_xen_colormap(int size, Xen lambda) { Xen xrgb; mus_float_t **rgb = NULL; add_colormap_func_hit_error = false; redirect_xen_error_to(add_colormap_func_error, NULL); xrgb = Xen_call_with_1_arg(lambda, C_int_to_Xen_integer(size), S_add_colormap); redirect_xen_error_to(NULL, NULL); if (add_colormap_func_hit_error) { Xen str; if (add_colormap_func_error_msg) { str = C_string_to_Xen_string(add_colormap_func_error_msg); free(add_colormap_func_error_msg); add_colormap_func_error_msg = NULL; } else str = Xen_false; Xen_error(Xen_make_error_type("colormap-error"), Xen_list_2(C_string_to_Xen_string(S_add_colormap ": function error ~A"), str)); } if (!(Xen_is_list(xrgb))) Xen_error(Xen_make_error_type("colormap-error"), Xen_list_3(C_string_to_Xen_string(S_add_colormap ": colormap function, ~A, returned ~A, but should return a list of 3 " S_vct "s"), lambda, xrgb)); else { vct *xr, *xg, *xb; mus_float_t *xrdata, *xgdata, *xbdata; int i, gc_loc; /* user-defined colormap func returns a list of 3 vcts (r g b) */ gc_loc = snd_protect(xrgb); if (!(mus_is_vct(Xen_list_ref(xrgb, 0)))) Xen_error(Xen_make_error_type("colormap-error"), Xen_list_2(C_string_to_Xen_string(S_add_colormap ": function did not return a list of " S_vct "s! ~A"), xrgb)); xr = Xen_to_vct(Xen_list_ref(xrgb, 0)); xrdata = mus_vct_data(xr); if (mus_vct_length(xr) < size) Xen_error(Xen_make_error_type("colormap-error"), Xen_list_2(C_string_to_Xen_string(S_add_colormap ": function did not return a list of " S_vct "s of the correct size: ~A"), xrgb)); xg = Xen_to_vct(Xen_list_ref(xrgb, 1)); xgdata = mus_vct_data(xg); xb = Xen_to_vct(Xen_list_ref(xrgb, 2)); xbdata = mus_vct_data(xb); rgb = make_base_rgb(size); for (i = 0; i < size; i++) { rgb[0][i] = xrdata[i]; rgb[1][i] = xgdata[i]; rgb[2][i] = xbdata[i]; } snd_unprotect_at(gc_loc); } return(rgb); } static int add_colormap(const char *name, Xen func) { cmap *c; mus_float_t **rgb; int index = -1, i, loc; for (i = 0; i < cmaps_size; i++) if (!(cmaps[i])) { index = i; break; } if (index == -1) /* no free slot */ { index = cmaps_size; cmaps_size += 8; cmaps = (cmap **)realloc(cmaps, cmaps_size * sizeof(cmap *)); for (i = index; i < cmaps_size; i++) cmaps[i] = NULL; } loc = snd_protect(func); rgb = make_xen_colormap(color_map_size(ss), func); c = new_cmap(name, color_map_size(ss), rgb); c->make_rgb = make_xen_colormap; c->lambda = func; c->gc_loc = loc; for (i = 0; i < 3; i++) free(rgb[i]); free(rgb); cmaps[index] = c; return(index); } static mus_float_t **make_black_and_white_colormap(int size, Xen ignored) { /* (r 0) (g 0) (b 0) */ return(make_base_rgb(size)); } #if USE_GTK static void black_and_white_rgb(float n, rgb_t *r, rgb_t *g, rgb_t *b) { (*r) = 0.0; (*g) = 0.0; (*b) = 0.0; } #else #define black_and_white_rgb NULL #endif /* colormap functions taken mostly from (GPL) octave-forge code written by Kai Habel */ static mus_float_t **make_gray_colormap(int size, Xen ignored) { /* (r x) (g x) (b x) */ mus_float_t **rgb; int i; mus_float_t x, incr; rgb = make_base_rgb(size); incr = 1.0 / (mus_float_t)size; for (i = 0, x = 0.0; i < size; i++, x += incr) { rgb[0][i] = x; rgb[1][i] = x; rgb[2][i] = x; } return(rgb); } #if USE_GTK static void gray_rgb(float n, rgb_t *r, rgb_t *g, rgb_t *b) { (*r) = n; (*g) = n; (*b) = n; } #else #define gray_rgb NULL #endif static mus_float_t **make_autumn_colormap(int size, Xen ignored) { /* (r 1.0) (g x) (b 0.0) */ mus_float_t **rgb; int i; mus_float_t x, incr; rgb = make_base_rgb(size); incr = 1.0 / (mus_float_t)size; for (i = 0, x = 0.0; i < size; i++, x += incr) { rgb[0][i] = 1.0; rgb[1][i] = x; rgb[2][i] = 0.0; } return(rgb); } #if USE_GTK static void autumn_rgb(float n, rgb_t *r, rgb_t *g, rgb_t *b) { (*r) = 1.0; (*g) = n; (*b) = 0.0; } #else #define autumn_rgb NULL #endif static mus_float_t **make_spring_colormap(int size, Xen ignored) { /* (r 1.0) (g x) (b (- 1.0 x)) */ mus_float_t **rgb; int i; mus_float_t x, incr; rgb = make_base_rgb(size); incr = 1.0 / (mus_float_t)size; for (i = 0, x = 0.0; i < size; i++, x += incr) { rgb[0][i] = 1.0; rgb[1][i] = x; rgb[2][i] = 1.0 - x; } return(rgb); } #if USE_GTK static void spring_rgb(float n, rgb_t *r, rgb_t *g, rgb_t *b) { (*r) = 1.0; (*g) = n; (*b) = 1.0 - n; } #else #define spring_rgb NULL #endif static mus_float_t **make_winter_colormap(int size, Xen ignored) { /* (r 0.0) (g x) (b (- 1.0 (/ x 2))) */ mus_float_t **rgb; int i; mus_float_t x, incr; rgb = make_base_rgb(size); incr = 1.0 / (mus_float_t)size; for (i = 0, x = 0.0; i < size; i++, x += incr) { rgb[0][i] = 0.0; rgb[1][i] = x; rgb[2][i] = 1.0 - (x * 0.5); } return(rgb); } #if USE_GTK static void winter_rgb(float n, rgb_t *r, rgb_t *g, rgb_t *b) { (*r) = 0.0; (*g) = n; (*b) = 1.0 - (n * 0.5); } #else #define winter_rgb NULL #endif static mus_float_t **make_summer_colormap(int size, Xen ignored) { /* (r x) (g (+ 0.5 (/ x 2))) (b 0.4) */ mus_float_t **rgb; int i; mus_float_t x, incr; rgb = make_base_rgb(size); incr = 1.0 / (mus_float_t)size; for (i = 0, x = 0.0; i < size; i++, x += incr) { rgb[0][i] = x; rgb[1][i] = 0.5 + (0.5 * x); rgb[2][i] = 0.4; } return(rgb); } #if USE_GTK static void summer_rgb(float n, rgb_t *r, rgb_t *g, rgb_t *b) { (*r) = n; (*g) = 0.5 + (0.5 * n); (*b) = 0.4; } #else #define summer_rgb NULL #endif static mus_float_t **make_cool_colormap(int size, Xen ignored) { /* (r x) (g (- 1.0 x)) (b 1.0) */ mus_float_t **rgb; int i; mus_float_t x, incr; rgb = make_base_rgb(size); incr = 1.0 / (mus_float_t)size; for (i = 0, x = 0.0; i < size; i++, x += incr) { rgb[0][i] = x; rgb[1][i] = 1.0 - x; rgb[2][i] = 1.0; } return(rgb); } #if USE_GTK static void cool_rgb(float n, rgb_t *r, rgb_t *g, rgb_t *b) { (*r) = n; (*g) = 1.0 - n; (*b) = 1.0; } #else #define cool_rgb NULL #endif static mus_float_t **make_copper_colormap(int size, Xen ignored) { /* (r (if (< x 4/5) (* 5/4 x) 1.0)) (g (* 4/5 x)) (b (* 1/2 x)) */ mus_float_t **rgb; int i; mus_float_t x, incr; rgb = make_base_rgb(size); incr = 1.0 / (mus_float_t)size; for (i = 0, x = 0.0; i < size; i++, x += incr) { rgb[0][i] = (x < 0.8) ? (1.25 * x) : 1.0; rgb[1][i] = 0.8 * x; rgb[2][i] = 0.5 * x; } return(rgb); } #if USE_GTK static void copper_rgb(float x, rgb_t *r, rgb_t *g, rgb_t *b) { (*r) = (x < 0.8) ? (1.25 * x) : 1.0; (*g) = 0.8 * x; (*b) = 0.5 * x; } #else #define copper_rgb NULL #endif static mus_float_t **make_flag_colormap(int size, Xen ignored) { /* (r (if (or (= k 0) (= k 1)) 1.0 0.0)) (g (if (= k 1) 1.0 0.0)) (b (if (or (= k 1) (= k 2)) 1.0 0.0)) */ mus_float_t **rgb; int i, k = 0; rgb = make_base_rgb(size); for (i = 0; i < size; i++) { rgb[0][i] = (k < 2) ? 1.0 : 0.0; rgb[1][i] = (k == 1) ? 1.0 : 0.0; rgb[2][i] = ((k == 1) || (k == 2)) ? 1.0 : 0.0; k++; if (k == 4) k = 0; } return(rgb); } #if USE_GTK static void flag_rgb(float x, rgb_t *r, rgb_t *g, rgb_t *b) { int k; k = ((int)(x * color_map_size(ss))) % 4; (*r) = (k < 2) ? 1.0 : 0.0; (*g) = (k == 1) ? 1.0 : 0.0; (*b) = ((k == 1) || (k == 2)) ? 1.0 : 0.0; } #else #define flag_rgb NULL #endif static mus_float_t **make_prism_colormap(int size, Xen ignored) { /* (r (list-ref (list 1 1 1 0 0 2/3) k)) (g (list-ref (list 0 1/2 1 1 0 0) k)) (b (list-ref (list 0 0 0 0 1 1) k)) */ mus_float_t **rgb; int i, k = 0; mus_float_t rs[6] = {1.0, 1.0, 1.0, 0.0, 0.0, 0.6667}; mus_float_t gs[6] = {0.0, 0.5, 1.0, 1.0, 0.0, 0.0}; mus_float_t bs[6] = {0.0, 0.0, 0.0, 0.0, 1.0, 1.0}; rgb = make_base_rgb(size); for (i = 0; i < size; i++) { rgb[0][i] = rs[k]; rgb[1][i] = gs[k]; rgb[2][i] = bs[k]; k++; if (k == 6) k = 0; } return(rgb); } #if USE_GTK static void prism_rgb(float x, rgb_t *r, rgb_t *g, rgb_t *b) { int k; mus_float_t rs[6] = {1.0, 1.0, 1.0, 0.0, 0.0, 0.6667}; mus_float_t gs[6] = {0.0, 0.5, 1.0, 1.0, 0.0, 0.0}; mus_float_t bs[6] = {0.0, 0.0, 0.0, 0.0, 1.0, 1.0}; k = ((int)(x * color_map_size(ss))) % 6; (*r) = rs[k]; (*g) = gs[k]; (*b) = bs[k]; } #else #define prism_rgb NULL #endif static mus_float_t **make_bone_colormap(int size, Xen ignored) { /* (r (if (< x 3/4) (* 7/8 x) (- (* 11/8 x) 3/8))) (g (if (< x 3/8) (* 7/8 x) (if (< x 3/4) (- (* 29/24 x) 1/8) (+ (* 7/8 x) 1/8)))) (b (if (< x 3/8) (* 29/24 x) (+ (* 7/8 x) 1/8))) */ mus_float_t **rgb; int i; mus_float_t x, incr; rgb = make_base_rgb(size); incr = 1.0 / (mus_float_t)size; for (i = 0, x = 0.0; i < size; i++, x += incr) { rgb[0][i] = (x < .75) ? (x * .875) : ((x * 11.0 / 8.0) - .375); rgb[1][i] = (x < .375) ? (x * .875) : ((x < .75) ? ((x * 29.0 / 24.0) - .125) : ((x * .875) + .125)); rgb[2][i] = (x < .375) ? (x * 29.0 / 24.0) : ((x * .875) + .125); } return(rgb); } #if USE_GTK static void bone_rgb(float x, rgb_t *r, rgb_t *g, rgb_t *b) { (*r) = (x < .75) ? (x * .875) : ((x * 11.0 / 8.0) - .375); (*g) = (x < .375) ? (x * .875) : ((x < .75) ? ((x * 29.0 / 24.0) - .125) : ((x * .875) + .125)); (*b) = (x < .375) ? (x * 29.0 / 24.0) : ((x * .875) + .125); } #else #define bone_rgb NULL #endif static mus_float_t **make_hot_colormap(int size, Xen ignored) { /* (mimicking matlab here, not octave) (r (if (< x 3/8) (* 8/3 x) 1.0)) (g (if (< x 3/8) 0.0 (if (< x 3/4) (- (* 8/3 x) 1.0) 1.0))) (b (if (< x 3/4) 0.0 (- (* 4 x) 3))) */ mus_float_t **rgb; int i; mus_float_t x, incr; rgb = make_base_rgb(size); incr = 1.0 / (mus_float_t)size; for (i = 0, x = 0.0; i < size; i++, x += incr) { rgb[0][i] = (x < .375) ? (x * 8.0 / 3.0) : 1.0; rgb[1][i] = (x < .375) ? 0.0 : ((x < .75) ? ((x * 8.0 / 3.0) - 1.0) : 1.0); rgb[2][i] = (x < .75) ? 0.0 : ((x * 4.0) - 3.0); } return(rgb); } #if USE_GTK static void hot_rgb(float x, rgb_t *r, rgb_t *g, rgb_t *b) { (*r) = (x < .375) ? (x * 8.0 / 3.0) : 1.0; (*g) = (x < .375) ? 0.0 : ((x < .75) ? ((x * 8.0 / 3.0) - 1.0) : 1.0); (*b) = (x < .75) ? 0.0 : ((x * 4.0) - 3.0); } #else #define hot_rgb NULL #endif static mus_float_t **make_jet_colormap(int size, Xen ignored) { /* (r (if (< x 3/8) 0.0 (if (< x 5/8) (- (* 4 x) 3/2) (if (< x 7/8) 1.0 (+ (* -4 x) 9/2))))) (g (if (< x 1/8) 0.0 (if (< x 3/8) (- (* 4 x) 1/2) (if (< x 5/8) 1.0 (if (< x 7/8) (+ (* -4 x) 7/2) 0.0))))) (b (if (< x 1/8) (+ (* 4 x) 1/2) (if (< x 3/8) 1.0 (if (< x 5/8) (+ (* -4 x) 5/2) 0.0)))) */ mus_float_t **rgb; int i; mus_float_t x, incr; rgb = make_base_rgb(size); incr = 1.0 / (mus_float_t)size; for (i = 0, x = 0.0; i < size; i++, x += incr) { rgb[0][i] = (x < .375) ? 0.0 : ((x < .625) ? ((x * 4.0) - 1.5) : ((x < .875) ? 1.0 : ((x * -4.0) + 4.5))); rgb[1][i] = (x < .125) ? 0.0 : ((x < .375) ? ((x * 4.0) - 0.5) : ((x < .625) ? 1.0 : ((x < .875) ? ((x * -4.0) + 3.5) : 0.0))); rgb[2][i] = (x < .125) ? ((x * 4.0) + 0.5) : ((x < .375) ? 1.0 : ((x < .625) ? ((x * -4.0) + 2.5) : 0.0)); } return(rgb); } #if USE_GTK static void jet_rgb(float x, rgb_t *r, rgb_t *g, rgb_t *b) { (*r) = (x < .375) ? 0.0 : ((x < .625) ? ((x * 4.0) - 1.5) : ((x < .875) ? 1.0 : ((x * -4.0) + 4.5))); (*g) = (x < .125) ? 0.0 : ((x < .375) ? ((x * 4.0) - 0.5) : ((x < .625) ? 1.0 : ((x < .875) ? ((x * -4.0) + 3.5) : 0.0))); (*b) = (x < .125) ? ((x * 4.0) + 0.5) : ((x < .375) ? 1.0 : ((x < .625) ? ((x * -4.0) + 2.5) : 0.0)); } #else #define jet_rgb NULL #endif static mus_float_t **make_pink_colormap(int size, Xen ignored) { /* matlab uses log here, or something like that -- this version is quite different (r (if (< x 3/8) (* 14/9 x) (+ (* 2/3 x) 1/3))) (g (if (< x 3/8) (* 2/3 x) (if (< x 3/4) (- (* 14/9 x) 1/3) (+ (* 2/3 x) 1/3)))) (b (if (< x 3/4) (* 2/3 x) (- (* 2 x) 1))) */ mus_float_t **rgb; int i; mus_float_t x, incr; rgb = make_base_rgb(size); incr = 1.0 / (mus_float_t)size; for (i = 0, x = 0.0; i < size; i++, x += incr) { rgb[0][i] = (x < .375) ? (x * 14.0 / 9.0) : ((x * 2.0 / 3.0) + 1.0 / 3.0); rgb[1][i] = (x < .375) ? (x * 2.0 / 3.0) : ((x < .75) ? ((x * 14.0 / 9.0) - 1.0 / 3.0) : ((x * 2.0 / 3.0) + 1.0 / 3.0)); rgb[2][i] = (x < .75) ? (x * 2.0 / 3.0) : ((x * 2.0) - 1.0); } return(rgb); } #if USE_GTK static void pink_rgb(float x, rgb_t *r, rgb_t *g, rgb_t *b) { (*r) = (x < .375) ? (x * 14.0 / 9.0) : ((x * 2.0 / 3.0) + 1.0 / 3.0); (*g) = (x < .375) ? (x * 2.0 / 3.0) : ((x < .75) ? ((x * 14.0 / 9.0) - 1.0 / 3.0) : ((x * 2.0 / 3.0) + 1.0 / 3.0)); (*b) = (x < .75) ? (x * 2.0 / 3.0) : ((x * 2.0) - 1.0); } #else #define pink_rgb NULL #endif static mus_float_t **make_rainbow_colormap(int size, Xen ignored) { /* (r (if (< x 2/5) 1.0 (if (< x 3/5) (+ (* -5 x) 3) (if (< x 4/5) 0.0 (- (* 10/3 x) 8/3))))) (g (if (< x 2/5) (* 5/2 x) (if (< x 3/5) 1.0 (if (< x 4/5) (+ (* -5 x) 4) 0.0)))) (b (if (< x 3/5) 0.0 (if (< x 4/5) (- (* 5 x) 3) 1.0))) */ mus_float_t **rgb; int i; mus_float_t x, incr; rgb = make_base_rgb(size); incr = 1.0 / (mus_float_t)size; for (i = 0, x = 0.0; i < size; i++, x += incr) { rgb[0][i] = (x < .4) ? 1.0 : ((x < .6) ? ((x * -5.0) + 3.0) : ((x < .8) ? 0.0 : ((x * 10.0 / 3.0) - 8.0 / 3.0))); rgb[1][i] = (x < .4) ? (x * 2.5) : ((x < .6) ? 1.0 : ((x < .8) ? ((x * -5.0) + 4.0) : 0.0)); rgb[2][i] = (x < .6) ? 0.0 : ((x < .8) ? ((x * 5.0) - 3.0) : 1.0); } return(rgb); } #if USE_GTK static void rainbow_rgb(float x, rgb_t *r, rgb_t *g, rgb_t *b) { (*r) = (x < .4) ? 1.0 : ((x < .6) ? ((x * -5.0) + 3.0) : ((x < .8) ? 0.0 : ((x * 10.0 / 3.0) - 8.0 / 3.0))); (*g) = (x < .4) ? (x * 2.5) : ((x < .6) ? 1.0 : ((x < .8) ? ((x * -5.0) + 4.0) : 0.0)); (*b) = (x < .6) ? 0.0 : ((x < .8) ? ((x * 5.0) - 3.0) : 1.0); } #else #define rainbow_rgb NULL #endif static mus_float_t **make_phases_colormap(int size, Xen ignored) { /* 0 and pi: blue->green, pi/2 and 3pi/2: red->black */ mus_float_t **rgb; int i; mus_float_t x, incr; rgb = make_base_rgb(size); incr = (2.0 * M_PI) / (mus_float_t)size; for (i = 0, x = 0.0; i < size; i++, x += incr) { if (x <= 0.5 * M_PI) { rgb[0][i] = x / (0.5 * M_PI); rgb[1][i] = 0.0; rgb[2][i] = 1.0 - rgb[0][i]; } else { if (x <= M_PI) { rgb[0][i] = 1.0 - ((x - 0.5 * M_PI) / (0.5 * M_PI)); rgb[1][i] = 1.0 - rgb[0][i]; rgb[2][i] = 0.0; } else { if (x <= 1.5 * M_PI) { rgb[0][i] = 0.0; rgb[1][i] = 1.0 - ((x - M_PI) / (0.5 * M_PI)); rgb[2][i] = 0.0; } else { rgb[0][i] = 0.0; rgb[1][i] = 1.0 - ((x - (1.5 * M_PI)) / (0.5 * M_PI)); rgb[2][i] = 0.0; } } } } return(rgb); } #if USE_GTK void phases_rgb(float x, rgb_t *r, rgb_t *g, rgb_t *b) { x *= (2.0 * M_PI); /* match code above */ if (x <= 0.5 * M_PI) { (*r) = x / (0.5 * M_PI); (*g) = 0.0; (*b) = 1.0 - (*r); } else { if (x <= M_PI) { (*r) = 1.0 - ((x - 0.5 * M_PI) / (0.5 * M_PI)); (*g) = 1.0 - (*r); (*b) = 0.0; } else { if (x <= 1.5 * M_PI) { (*r) = 0.0; (*g) = 1.0 - ((x - M_PI) / (0.5 * M_PI)); (*b) = 0.0; } else { (*r) = 0.0; (*g) = 1.0 - ((x - (1.5 * M_PI)) / (0.5 * M_PI)); (*b) = 0.0; } } } } #else #define phases_rgb NULL #endif /* ---------------------------------------- colormap objects ---------------------------------------- */ typedef struct { int n; } xen_colormap; #define Xen_to_xen_colormap(arg) ((xen_colormap *)Xen_object_ref(arg)) static int xen_colormap_to_int(Xen n) { xen_colormap *col; col = Xen_to_xen_colormap(n); return(col->n); } #define Xen_colormap_to_C_int(n) xen_colormap_to_int(n) static Xen_object_type_t xen_colormap_tag; static bool xen_is_colormap(Xen obj) { return(Xen_c_object_is_type(obj, xen_colormap_tag)); } static void xen_colormap_free(xen_colormap *v) {if (v) free(v);} Xen_wrap_free(xen_colormap, free_xen_colormap, xen_colormap_free) static char *xen_colormap_to_string(xen_colormap *v) { #define COLORMAP_PRINT_BUFFER_SIZE 64 char *buf; if (v == NULL) return(NULL); buf = (char *)calloc(COLORMAP_PRINT_BUFFER_SIZE, sizeof(char)); snprintf(buf, COLORMAP_PRINT_BUFFER_SIZE, "#", colormap_name(v->n)); return(buf); } Xen_wrap_print(xen_colormap, print_xen_colormap, xen_colormap_to_string) #if HAVE_FORTH || HAVE_RUBY static Xen g_xen_colormap_to_string(Xen obj) { char *vstr; Xen result; #define S_xen_colormap_to_string "colormap->string" Xen_check_type(xen_is_colormap(obj), obj, 1, S_xen_colormap_to_string, "a colormap"); vstr = xen_colormap_to_string(Xen_to_xen_colormap(obj)); result = C_string_to_Xen_string(vstr); free(vstr); return(result); } #endif #if (!HAVE_SCHEME) static bool xen_colormap_equalp(xen_colormap *v1, xen_colormap *v2) { return((v1 == v2) || (v1->n == v2->n)); } static Xen equalp_xen_colormap(Xen obj1, Xen obj2) { if ((!(xen_is_colormap(obj1))) || (!(xen_is_colormap(obj2)))) return(Xen_false); return(C_bool_to_Xen_boolean(xen_colormap_equalp(Xen_to_xen_colormap(obj1), Xen_to_xen_colormap(obj2)))); } #endif static xen_colormap *xen_colormap_make(int n) { xen_colormap *new_v; new_v = (xen_colormap *)malloc(sizeof(xen_colormap)); new_v->n = n; return(new_v); } static Xen new_xen_colormap(int n) { xen_colormap *mx; if (n < 0) return(Xen_false); mx = xen_colormap_make(n); return(Xen_make_object(xen_colormap_tag, mx, 0, free_xen_colormap)); } #define C_int_to_Xen_colormap(Val) new_xen_colormap(Val) #if HAVE_SCHEME static bool s7_xen_colormap_equalp(void *obj1, void *obj2) { return((obj1 == obj2) || (((xen_colormap *)obj1)->n == ((xen_colormap *)obj2)->n)); } static Xen s7_xen_colormap_length(s7_scheme *sc, Xen obj) { return(C_int_to_Xen_integer(color_map_size(ss))); } static Xen g_colormap_ref(Xen map, Xen pos); static Xen s7_colormap_apply(s7_scheme *sc, Xen obj, Xen args) { return(g_colormap_ref(obj, Xen_car(args))); } #endif static void init_xen_colormap(void) { #if HAVE_SCHEME xen_colormap_tag = s7_new_type_x(s7, "", print_xen_colormap, free_xen_colormap, s7_xen_colormap_equalp, NULL, s7_colormap_apply, NULL, s7_xen_colormap_length, NULL, NULL, NULL); #else #if HAVE_RUBY xen_colormap_tag = Xen_make_object_type("XenColormap", sizeof(xen_colormap)); #else xen_colormap_tag = Xen_make_object_type("Colormap", sizeof(xen_colormap)); #endif #endif #if HAVE_FORTH fth_set_object_inspect(xen_colormap_tag, print_xen_colormap); fth_set_object_dump(xen_colormap_tag, g_xen_colormap_to_string); fth_set_object_equal(xen_colormap_tag, equalp_xen_colormap); fth_set_object_free(xen_colormap_tag, free_xen_colormap); #endif #if HAVE_RUBY rb_define_method(xen_colormap_tag, "to_s", Xen_procedure_cast print_xen_colormap, 0); rb_define_method(xen_colormap_tag, "eql?", Xen_procedure_cast equalp_xen_colormap, 1); rb_define_method(xen_colormap_tag, "==", Xen_procedure_cast equalp_xen_colormap, 1); rb_define_method(xen_colormap_tag, "to_str", Xen_procedure_cast g_xen_colormap_to_string, 0); #endif } /* -------------------------------------------------------------------------------- */ static Xen g_integer_to_colormap(Xen n) { #define H_integer_to_colormap "(" S_integer_to_colormap " n) returns a colormap object corresponding to the given integer" Xen_check_type(Xen_is_integer(n), n, 1, S_integer_to_colormap, "an integer"); return(new_xen_colormap(Xen_integer_to_C_int(n))); } static Xen g_colormap_to_integer(Xen n) { #define H_colormap_to_integer "(" S_colormap_to_integer " id) returns the integer corresponding to the given colormap" Xen_check_type(xen_is_colormap(n), n, 1, S_colormap_to_integer, "a colormap"); return(C_int_to_Xen_integer(xen_colormap_to_int(n))); } static Xen g_colormap_ref(Xen map, Xen pos) { int index; mus_float_t x; rgb_t r = 0, g = 0, b = 0; #define H_colormap_ref "(" S_colormap_ref " colormap pos): (list r g b). Pos is between 0.0 and 1.0." Xen_check_type(xen_is_colormap(map), map, 1, S_colormap_ref, "a colormap object"); Xen_check_type(Xen_is_number(pos), pos, 2, S_colormap_ref, "a number between 0.0 and 1.0"); index = Xen_colormap_to_C_int(map); if (!(is_colormap(index))) Xen_error(NO_SUCH_COLORMAP, Xen_list_2(C_string_to_Xen_string(S_colormap_ref ": no such colormap: ~A"), map)); x = Xen_real_to_C_double(pos); if ((x < 0.0) || (x > 1.0)) Xen_out_of_range_error(S_colormap_ref, 2, pos, "x must be between 0.0 and 1.0"); get_current_color(index, (int)(color_map_size(ss) * x + 0.5), &r, &g, &b); return(Xen_list_3(C_double_to_Xen_real(rgb_to_float(r)), C_double_to_Xen_real(rgb_to_float(g)), C_double_to_Xen_real(rgb_to_float(b)))); } /* can't use Colormap -- it's the X type name */ static Xen g_colormap(void) { #define H_colormap "(" S_colormap "): current colormap choice." return(C_int_to_Xen_colormap(color_map(ss))); } static Xen g_set_colormap(Xen val) { int index; Xen_check_type(xen_is_colormap(val), val, 1, S_set S_colormap, "a colormap"); index = Xen_colormap_to_C_int(val); if (!(is_colormap(index))) Xen_error(NO_SUCH_COLORMAP, Xen_list_2(C_string_to_Xen_string(S_colormap ": no such colormap: ~A"), val)); set_color_map(index); /* this normally redisplays */ return(val); } static Xen g_colormap_size(void) {return(C_int_to_Xen_integer(color_map_size(ss)));} static Xen g_set_colormap_size(Xen val) { int size; #define H_colormap_size "(" S_colormap_size "): current colormap size; default is 512." Xen_check_type(Xen_is_integer(val), val, 1, S_set S_colormap_size, "an integer"); size = Xen_integer_to_C_int(val); if (size < 0) Xen_out_of_range_error(S_set S_colormap_size, 1, val, "size < 0?"); if (size > (1 << 26)) Xen_out_of_range_error(S_set S_colormap_size, 1, val, "size too large"); set_color_map_size(size); check_colormap_sizes(color_map_size(ss)); return(C_int_to_Xen_integer(color_map_size(ss))); } static Xen g_colormap_name(Xen col) { int map; #define H_colormap_name "(" S_colormap_name " colormap) returns the colormap's name (used in the Color/Orientation dialog)." Xen_check_type(xen_is_colormap(col), col, 1, S_colormap_name, "a colormap"); map = Xen_colormap_to_C_int(col); if (!(is_colormap(map))) Xen_error(NO_SUCH_COLORMAP, Xen_list_2(C_string_to_Xen_string(S_colormap_name ": no such colormap: ~A"), col)); return(C_string_to_Xen_string(cmaps[map]->name)); } static Xen g_is_colormap(Xen obj) { #define H_is_colormap "(" S_is_colormap " obj) -> " PROC_TRUE " if 'obj' is a colormap." return(C_bool_to_Xen_boolean(xen_is_colormap(obj) && is_colormap(Xen_colormap_to_C_int(obj)))); } static Xen g_delete_colormap(Xen col) { int map; #define H_delete_colormap "(" S_delete_colormap " colormap) frees the specified colormap." Xen_check_type(xen_is_colormap(col), col, 1, S_delete_colormap, "a colormap"); map = Xen_colormap_to_C_int(col); if (!(is_colormap(map))) Xen_error(NO_SUCH_COLORMAP, Xen_list_2(C_string_to_Xen_string(S_delete_colormap ": no such colormap: ~A"), col)); delete_cmap(map); reflect_color_list(false); if (color_map(ss) == map) set_color_map(DEFAULT_COLOR_MAP); return(col); } #include "clm2xen.h" static Xen g_add_colormap(Xen name, Xen func) { int index; #define H_add_colormap "(" S_add_colormap " name func) adds the colormap created by func to the colormap table, \ returning the new colormap. 'name' is the colormap's name in the View:Color/Orientation dialog." Xen_check_type(Xen_is_string(name), name, 1, S_add_colormap, "a string"); Xen_check_type(Xen_is_procedure(func) && (!mus_is_xen(func)), func, 2, S_add_colormap, "a function of 2 args"); if (!(procedure_arity_ok(func, 1))) return(snd_bad_arity_error(S_add_colormap, C_string_to_Xen_string("func should take 1 arg"), func)); index = add_colormap(Xen_string_to_C_string(name), func); reflect_color_list(false); return(C_int_to_Xen_colormap(index)); } Xen_wrap_2_args(g_colormap_ref_w, g_colormap_ref) Xen_wrap_no_args(g_colormap_w, g_colormap) Xen_wrap_1_arg(g_is_colormap_w, g_is_colormap) Xen_wrap_1_arg(g_set_colormap_w, g_set_colormap) Xen_wrap_no_args(g_colormap_size_w, g_colormap_size) Xen_wrap_1_arg(g_set_colormap_size_w, g_set_colormap_size) Xen_wrap_1_arg(g_colormap_name_w, g_colormap_name) Xen_wrap_1_arg(g_delete_colormap_w, g_delete_colormap) Xen_wrap_2_args(g_add_colormap_w, g_add_colormap) Xen_wrap_1_arg(g_integer_to_colormap_w, g_integer_to_colormap) Xen_wrap_1_arg(g_colormap_to_integer_w, g_colormap_to_integer) #if HAVE_SCHEME static s7_pointer acc_colormap(s7_scheme *sc, s7_pointer args) {return(g_set_colormap(s7_cadr(args)));} static s7_pointer acc_colormap_size(s7_scheme *sc, s7_pointer args) {return(g_set_colormap_size(s7_cadr(args)));} #endif #if (!HAVE_SCHEME) static Xen colormap_temp[16]; /* static for Ruby's sake */ #endif void g_init_gxcolormaps(void) { cmaps_size = NUM_BUILTIN_COLORMAPS; cmaps = (cmap **)calloc(cmaps_size, sizeof(cmap *)); init_xen_colormap(); cmaps[BLACK_AND_WHITE_COLORMAP] = make_builtin_cmap(1, "black-and-white", make_black_and_white_colormap, black_and_white_rgb); cmaps[GRAY_COLORMAP] = make_builtin_cmap(1, "gray", make_gray_colormap, gray_rgb); cmaps[AUTUMN_COLORMAP] = make_builtin_cmap(1, "autumn", make_autumn_colormap, autumn_rgb); cmaps[SPRING_COLORMAP] = make_builtin_cmap(1, "spring", make_spring_colormap, spring_rgb); cmaps[WINTER_COLORMAP] = make_builtin_cmap(1, "winter", make_winter_colormap, winter_rgb); cmaps[SUMMER_COLORMAP] = make_builtin_cmap(1, "summer", make_summer_colormap, summer_rgb); cmaps[COOL_COLORMAP] = make_builtin_cmap(1, "cool", make_cool_colormap, cool_rgb); cmaps[COPPER_COLORMAP] = make_builtin_cmap(1, "copper", make_copper_colormap, copper_rgb); cmaps[FLAG_COLORMAP] = make_builtin_cmap(1, "flag", make_flag_colormap, flag_rgb); cmaps[PRISM_COLORMAP] = make_builtin_cmap(1, "prism", make_prism_colormap, prism_rgb); cmaps[BONE_COLORMAP] = make_builtin_cmap(1, "bone", make_bone_colormap, bone_rgb); cmaps[HOT_COLORMAP] = make_builtin_cmap(1, "hot", make_hot_colormap, hot_rgb); cmaps[JET_COLORMAP] = make_builtin_cmap(1, "jet", make_jet_colormap, jet_rgb); cmaps[PINK_COLORMAP] = make_builtin_cmap(1, "pink", make_pink_colormap, pink_rgb); cmaps[RAINBOW_COLORMAP] = make_builtin_cmap(1, "rainbow", make_rainbow_colormap, rainbow_rgb); cmaps[PHASES_COLORMAP] = make_builtin_cmap(1, "phases", make_phases_colormap, phases_rgb); #if HAVE_SCHEME s7_define_constant(s7, "black-and-white-colormap", C_int_to_Xen_colormap(0)); s7_define_constant(s7, "gray-colormap", C_int_to_Xen_colormap(1)); s7_define_constant(s7, "hot-colormap", C_int_to_Xen_colormap(2)); s7_define_constant(s7, "cool-colormap", C_int_to_Xen_colormap(3)); s7_define_constant(s7, "bone-colormap", C_int_to_Xen_colormap(4)); s7_define_constant(s7, "copper-colormap", C_int_to_Xen_colormap(5)); s7_define_constant(s7, "pink-colormap", C_int_to_Xen_colormap(6)); s7_define_constant(s7, "jet-colormap", C_int_to_Xen_colormap(7)); s7_define_constant(s7, "prism-colormap", C_int_to_Xen_colormap(8)); s7_define_constant(s7, "autumn-colormap", C_int_to_Xen_colormap(9)); s7_define_constant(s7, "winter-colormap", C_int_to_Xen_colormap(10)); s7_define_constant(s7, "spring-colormap", C_int_to_Xen_colormap(11)); s7_define_constant(s7, "summer-colormap", C_int_to_Xen_colormap(12)); s7_define_constant(s7, "rainbow-colormap", C_int_to_Xen_colormap(13)); s7_define_constant(s7, "flag-colormap", C_int_to_Xen_colormap(14)); s7_define_constant(s7, "phases-colormap", C_int_to_Xen_colormap(15)); #else Xen_define_variable("black-and-white-colormap", colormap_temp[0], C_int_to_Xen_colormap(0)); Xen_define_variable("gray-colormap", colormap_temp[1], C_int_to_Xen_colormap(1)); Xen_define_variable("hot-colormap", colormap_temp[2], C_int_to_Xen_colormap(2)); Xen_define_variable("cool-colormap", colormap_temp[3], C_int_to_Xen_colormap(3)); Xen_define_variable("bone-colormap", colormap_temp[4], C_int_to_Xen_colormap(4)); Xen_define_variable("copper-colormap", colormap_temp[5], C_int_to_Xen_colormap(5)); Xen_define_variable("pink-colormap", colormap_temp[6], C_int_to_Xen_colormap(6)); Xen_define_variable("jet-colormap", colormap_temp[7], C_int_to_Xen_colormap(7)); Xen_define_variable("prism-colormap", colormap_temp[8], C_int_to_Xen_colormap(8)); Xen_define_variable("autumn-colormap", colormap_temp[9], C_int_to_Xen_colormap(9)); Xen_define_variable("winter-colormap", colormap_temp[10], C_int_to_Xen_colormap(10)); Xen_define_variable("spring-colormap", colormap_temp[11], C_int_to_Xen_colormap(11)); Xen_define_variable("summer-colormap", colormap_temp[12], C_int_to_Xen_colormap(12)); Xen_define_variable("rainbow-colormap", colormap_temp[13], C_int_to_Xen_colormap(13)); Xen_define_variable("flag-colormap", colormap_temp[14], C_int_to_Xen_colormap(14)); Xen_define_variable("phases-colormap", colormap_temp[15], C_int_to_Xen_colormap(15)); #endif Xen_define_safe_procedure(S_is_colormap, g_is_colormap_w, 1, 0, 0, H_is_colormap); Xen_define_safe_procedure(S_colormap_ref, g_colormap_ref_w, 2, 0, 0, H_colormap_ref); Xen_define_safe_procedure(S_add_colormap, g_add_colormap_w, 2, 0, 0, H_add_colormap); Xen_define_safe_procedure(S_colormap_name, g_colormap_name_w, 1, 0, 0, H_colormap_name); Xen_define_safe_procedure(S_delete_colormap, g_delete_colormap_w, 1, 0, 0, H_delete_colormap); Xen_define_dilambda(S_colormap, g_colormap_w, H_colormap, S_set S_colormap, g_set_colormap_w, 0, 0, 1, 0); Xen_define_dilambda(S_colormap_size, g_colormap_size_w, H_colormap_size, S_set S_colormap_size, g_set_colormap_size_w, 0, 0, 1, 0); Xen_define_safe_procedure(S_integer_to_colormap, g_integer_to_colormap_w, 1, 0, 0, H_integer_to_colormap); Xen_define_safe_procedure(S_colormap_to_integer, g_colormap_to_integer_w, 1, 0, 0, H_colormap_to_integer); #if HAVE_SCHEME s7_symbol_set_access(s7, ss->color_map_size_symbol, s7_make_function(s7, "[acc-" S_colormap_size "]", acc_colormap_size, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->color_map_symbol, s7_make_function(s7, "[acc-" S_colormap "]", acc_colormap, 2, 0, false, "accessor")); s7_symbol_set_documentation(s7, ss->color_map_size_symbol, "*colormap-size*: current colormap size; default is 512."); s7_symbol_set_documentation(s7, ss->color_map_symbol, "*colormap*: current colormap choice."); #endif } snd-16.1/examp.fs0000644000076400007640000021735012462674025012017 0ustar bilbil\ examp.fs -- examples from examp.scm|rb \ Translator/Author: Michael Scholz \ Created: 05/07/05 13:09:37 \ Changed: 15/01/29 23:39:32 \ \ @(#)examp.fs 1.68 1/29/15 \ With original comments and doc strings from examp.scm. \ \ all-chans ( -- array-of-lists ) \ close-sound-extend ( snd -- ) \ snd-snd ( :optional snd -- snd ) \ snd-chn ( :optional chn -- chn ) \ make-read-eval-loop ( -- ) \ remove-read-eval-loop ( -- ) \ toggle-read-eval-loop ( -- ) \ \ from frame.scm \ insert-vct ( v :optional beg dur snd chn edpos -- samps ) \ \ examp.(scm|rb) \ selection-rms ( -- val ) \ region-rms ( :optional n -- val ) \ window-samples ( :optional snd chn -- vct ) \ display-energy ( snd chn -- val ) \ display-db ( snd chn -- val ) \ window-rms ( -- val ) \ fft-peak ( snd chn scaler -- pk ) \ finfo ( file -- str ) \ display-correlate ( snd chn y0 y1 -- val ) \ zoom-spectrum ( snd chn y0 y1 -- val ) \ superimpose-ffts ( snd chn y0 y1 -- val ) \ locate-zero ( limit -- samp ) \ mpg ( mpgfile rawfile -- ) \ auto-dot ( snd chn y0 y1 -- val ) \ first-mark-in-window-at-left ( -- ) \ flash-selected-data ( millisecs -- ) \ mark-loops ( -- ) \ \ do-all-chans ( func :optional origin -- ) \ update-graphs ( -- ) \ do-chans ( func :optional origin -- ) \ do-sound-chans ( func :optional origin -- ) \ every-sample? ( func -- f ) \ sort-samples ( nbins -- ary ) \ place-sound ( mono stereo pan -- res ) \ fft-edit ( bottom top :optional snd chn -- vct ) \ fft-squelch ( squelch :optional snd chn -- scl ) \ fft-cancel ( lo-freq hi-freq :optional snd chn -- vct ) \ make-ramp ( :optional size -- gen ) \ ramp ( gen up -- val ) \ squelch-vowels ( :optional snd chn -- val ) \ fft-env-data ( fft-env :optional snd chn -- vct ) \ fft-env-edit ( fft-env :optional snd chn -- vct ) \ fft-env-interp ( env1 env2 interp :optional snd chn -- vct ) \ filter-fft ( flt :optional normalize snd chn -- val ) \ fft-smoother ( cutoff start samps :optional snd chn -- val ) \ comb-filter ( scaler size -- prc; x self -- res ) \ comb-chord ( scaler size amp -- prc; x self -- res ) \ zcomb ( scaler size pm -- prc; x self -- val ) \ notch-filter ( scaler size -- prc; x self -- val ) \ formant-filter ( radius frequency -- prc; x self -- val ) \ formants ( r1 f1 r2 f2 r3 f3 -- prc; x self -- val ) \ moving-formant ( radius move -- prc; x self -- val ) \ osc-formants ( radius bases amounts freqs -- prc; x self -- val ) \ \ echo ( scaler secs -- prc; y self -- val ) \ zecho ( scaler secs freq amp -- prc; y self -- val ) \ flecho ( scaler secs -- prc; y self -- val ) \ ring-mod ( freq gliss-env -- prc; y self -- val ) \ am ( freq -- prc; y self -- val ) \ vibro ( speed depth -- prc; y self -- val ) \ \ hello-dentist ( frq amp :optional snd chn -- vct ) \ fp ( sr osamp osfrq :optional snd chn -- vct ) \ compand ( -- prc; y self -- val ) \ expsrc ( rate :optional snd chn -- val ) \ expsnd ( gr-env :optional snd chn -- vct ) \ cross-synthesis ( cross-snd amp fftsize r -- prc; y self -- val ) \ voiced->unvoiced ( amp fftsize r tempo :optional snd chn -- vct ) \ pulse-voice ( cos :optional freq amp fftsize r snd chn -- vct ) \ cnvtest ( snd0 snd1 amp -- mx ) \ swap-selection-channels ( -- ) \ make-sound-interp ( start :optional snd chn -- prc; loc self -- val ) \ sound-interp ( func loc -- val ) \ env-sound-interp ( env :optional time-scale snd chn -- vct ) \ granulated-sound-interp ( e :optional tscl glen genv ohop snd chn -- vct ) \ filtered-env ( e :optional snd chn -- val ) \ \ find-click ( loc -- pos ) \ remove-clicks ( -- ) \ search-for-click ( -- pos ) \ zero+ ( -- prc; n self -- val ) \ next-peak ( -- prc; n self -- val ) \ find-pitch ( pitch -- prc; y self -- val ) \ file->vct ( file -- vct ) \ add-notes ( notes :optional snd chn -- #f ) \ region-play-list ( data -- ) \ region-play-sequence ( data -- ) \ replace-with-selection ( -- ) \ explode-sf2 ( -- ) \ open-next-file-in-directory ( -- f ) \ click-middle-button-to-open-next-file-in-directory ( -- ) \ chain-dsps ( start dur :optional dsps -- ) \ \ scramble-channels ( new-order -- ) \ scramble-channel ( silence -- ) \ reverse-by-blocks ( block-len :optional snd chn -- val ) \ reverse-within-blocks ( block-len :optional snd chn -- val ) \ channel-clipped? ( :optional snd chn -- val ) \ sync-everything ( -- ) \ \ make-moog-filter ( freq Q -- gen ) \ moog-frequecy@ ( gen -- frq ) \ moog-frequecy! ( frq gen -- ) \ moog-filter ( gen sig -- A ) 'snd-nogui provided? [if] <'> noop alias show-widget ( a -- a ) <'> noop alias hide-widget ( a -- a ) <'> noop alias widget-size ( a -- a ) : set-widget-size ( a b -- a ) drop ; : window-property ( a b -- a ) drop ; : set-window-property ( a b c -- a ) 2drop ; [then] \ #( #( snd0 chn0 ) #( snd0 chn1 ) ... ) : all-chans ( -- array-of-lists ) nil { snd } #() ( ary ) sounds each to snd snd channels 0 ?do ( ary ) #( snd i ) array-push loop end-each ( ary ) ; \ 5 == notebook widget : close-sound-extend <{ snd -- }> main-widgets 5 object-ref if sounds snd object-index 0 max { idx } snd close-sound drop sounds empty? unless sounds idx sounds length < if idx else -1 then object-ref set-selected-sound drop then else snd close-sound drop then ; : snd-snd <{ :optional snd #f -- snd }> snd sound? if snd else selected-sound to snd snd sound? if snd else sounds car then then ; : snd-chn <{ :optional chn #f -- chn }> chn integer? if chn else #f selected-channel to chn chn integer? if chn else 0 then then ; \ === Traditional Forth Read-Eval-Loop for Snd's listener. === "ok " constant read-eval-loop-prompt hide #f value rel-ficl-stack #f value rel-old-listener-prompt #f value rel-old-hooks : rel-cb <{ text -- flag }> rel-ficl-stack restore-stack $space snd-print drop text string-eval save-stack to rel-ficl-stack $cr snd-print drop read-eval-loop-prompt snd-print drop \ reset-listener-cursor returns #f reset-listener-cursor not ; : rel-add ( -- ) listener-prompt to rel-old-listener-prompt read-eval-loop-prompt set-listener-prompt drop read-hook hook->array to rel-old-hooks read-hook reset-hook! read-hook <'> rel-cb add-hook! ; : rel-remove ( -- ) read-hook <'> rel-cb remove-hook! nil { prc } rel-old-hooks empty? unless rel-old-hooks each to prc read-hook prc add-hook! end-each then rel-old-listener-prompt set-listener-prompt drop ; : rel-toggle ( key -- ) ( key ) case 'on of read-hook <'> rel-cb hook-member? unless rel-add then endof 'off of rel-remove endof 'toggle of read-hook <'> rel-cb hook-member? if rel-remove else rel-add then endof endcase #f to rel-ficl-stack stack-reset reset-listener-cursor drop ; set-current <'> noop alias ok : make-read-eval-loop ( -- ) 'on rel-toggle ; : remove-read-eval-loop ( -- ) 'off rel-toggle ; : toggle-read-eval-loop ( -- ) 'toggle rel-toggle ; previous require clm require env require rgb \ === from frame.scm \ : insert-vct <{ v :optional beg 0 dur #f snd #f chn #f edpos #f -- samps }> doc" Insert vct V's data into sound SND at BEG." v vct? v 1 "a vct" assert-type dur v vct-length || { len } beg len v snd chn edpos #f "%S %s %s %s" #( v beg dur get-func-name ) string-format insert-samples ; \ === examp.scm|rb \ \ this mainly involves keeping track of the current sound/channel : selection-rms ( -- val ) doc" Return rms of selection data using sample readers." undef selection? unless 'no-active-selection #( get-func-name ) fth-throw then selection-position #f #f 1 #f make-sampler { rd } selection-framples { len } 0.0 ( sum ) len 0 ?do rd next-sample dup f* f+ ( sum += ... ) loop len f/ fsqrt ; : region-rms <{ :optional reg 0 -- val }> doc" Return rms of region N's data (chan 0)." reg region? unless 'no-such-region #( "%s: %s" get-func-name reg ) fth-throw then reg 0 0 region->vct { data } data dup dot-product data length f/ fsqrt ; : window-samples <{ :optional snd #f chn #f -- vct }> doc" Sample in SND channel CHN in current graph window." snd chn left-sample { wl } snd chn right-sample { wr } wl wr wl - 1+ snd chn #f channel->vct ; : display-energy <{ snd chn -- v }> doc" A lisp-graph-hook function to display the time \ domain data as energy (squared).\n\ list-graph-hook <'> display-energy add-hook!." snd chn undef undef undef make-graph-data dup array? if 1 array-ref then { data } data if snd chn left-sample { ls } snd chn right-sample { rs } snd srate { sr } snd chn y-zoom-slider { y-max } data data vct-multiply! "energy" ls sr f/ rs sr f/ 0.0 y-max dup f* snd chn #t undef graph else #f then ; \ lisp-graph-hook <'> display-energy add-hook! hide : db-calc { val -- r } val 0.001 f< if -60.0 else 20.0 val flog10 f* then ; set-current : display-db <{ snd chn -- v }> doc" A lisp-graph-hook function to display \ the time domain data in dB.\n\ list-graph-hook <'> display-db add-hook!." snd chn undef undef undef make-graph-data dup array? if 1 array-ref then { data } data if snd chn left-sample { ls } snd chn right-sample { rs } snd srate { sr } data map *key* fabs db-calc 60.0 f+ end-map "dB" ls sr f/ rs sr f/ 0.0 60.0 snd chn #t undef graph else #f then ; previous \ lisp-graph-hook <'> display-db add-hook! : window-rms ( -- val ) doc" Return rms of data in currently selected graph window." #f #f left-sample { ls } #f #f right-sample { rs } ls rs ls - 1+ #f #f #f channel->vct { data } data vct-length { len } data dup len dot-product len f/ fsqrt ; : fft-peak <{ snd chn scaler -- pk }> doc" print peak spectral magnitude\n\ Returns the peak spectral magnitude. \ It is intended for use with after-transform-hook." snd chn transform-graph? snd chn transform-graph-type graph-once = && if snd chn #f transform->vct vct-peak f2* snd chn transform-size f/ { pk } pk number->string snd status-report drop pk else #f then ; \ after-transform-hook <'> fft-peak add-hook! \ ;;; -------- 'info' from extsnd.html using format -------- : finfo ( file -- str ) doc" Return description (as a string) of file." find-file { file } file unless 'no-such-file #( "%s: %S" get-func-name file ) fth-throw then "%s: chans: %d, srate: %d, %s, %s, len: %1.3f" #( file file mus-sound-chans file mus-sound-srate file mus-sound-header-type mus-header-type-name file mus-sound-sample-type mus-sample-type-name file mus-sound-samples file mus-sound-chans file mus-sound-srate f* f/ ) string-format ; \ ;;; -------- Correlation -------- \ ;;; \ ;;; correlation of channels in a stereo sound : display-correlate <{ snd chn y0 y1 -- val }> doc" Return the correlation of SND's 2 channels (intended \ for use with graph-hook). \ y0 and y1 are ignored." snd channels 2 = if snd 0 #f framples 1 > snd 1 #f framples 1 > && if snd chn left-sample { ls } snd chn right-sample { rs } rs ls - 1+ { ilen } ilen flog 2.0 flog f/ fround->s { pow2 } 2.0 pow2 f** fround->s { fftlen } fftlen 2/ { fftlen2 } fftlen 1/f { fftscale } ls fftlen snd 0 #f channel->vct { rl1 } ls fftlen snd 1 #f channel->vct { rl2 } fftlen 0.0 make-vct { im1 } fftlen 0.0 make-vct { im2 } rl1 im1 1 fft drop rl2 im2 1 fft drop rl1 vct-copy { tmprl } im1 vct-copy { tmpim } fftlen2 0.0 make-vct { data3 } tmprl rl2 vct-multiply! drop tmpim im2 vct-multiply! drop im2 rl1 vct-multiply! drop rl2 im1 vct-multiply! drop tmprl tmpim 0 vct-add! drop im2 rl2 vct-subtract! drop tmprl im2 -1 fft drop data3 tmprl 0 vct-add! drop data3 fftscale vct-scale! drop data3 "lag time" 0 fftlen2 undef undef snd chn #t undef graph then else get-func-name " wants stereo input" $+ snd status-report then ; \ graph-hook <'> display-correlate add-hook! \ ;;; -------- set transform-size based on current time domain window size \ ;;; \ ;;; also zoom spectrum based on y-axis zoom slider : zoom-spectrum <{ snd chn y0 y1 -- val }> doc" Set the transform size to correspond to the \ time-domain window size (use with graph-hook)." snd chn transform-graph? snd chn transform-graph-type graph-once = && if 2.0 snd chn right-sample snd chn left-sample f- flog 2.0 flog f/ fceil f** fround->s { val } val 0> if val snd chn set-transform-size drop then snd chn y-zoom-slider snd chn set-spectrum-end drop then #f ; \ graph-hook <'> zoom-spectrum add-hook! \ ;;; -------- superimpose spectra of sycn'd sounds : superimpose-ffts <{ snd chn y0 y1 -- val }> doc" Superimpose ffts of multiple (syncd) sounds (use with graph-hook)." 0 ( maxsync ) sounds each ( snd ) sync max end-each { maxsync } 0 sounds each { n } n sync snd sync = if n else maxsync 1+ then min end-each { sndsync } snd chn left-sample { ls } snd chn right-sample { rs } snd sync 0> rs ls > && snd sndsync = && if rs ls f- 1.0 fmax 2.0 flog fceil->s { pow2 } 2.0 pow2 f** floor->s { fftlen } pow2 2 > if #() { ffts } sounds each { n } n sync snd sync = n channels chn > && if ls fftlen n chn #f channel->vct { fdr } fftlen 0.0 make-vct { fdi } fftlen 2/ 0.0 make-vct ( spectr ) fdr fdi #f 2 spectrum 0 vct-add! { val } ffts #( val ) array-push drop then end-each ffts "spectra" 0.0 0.5 y0 y1 snd chn #t undef graph drop then then #f ; \ graph-hook <'> superimpose-ffts add-hook! \ ;;; -------- c-g? example (Anders Vinjar) : locate-zero ( limit -- samp ) doc" Look for successive samples that sum to less than LIMIT, \ moving the cursor if successful." { limit } #f #f #f cursor { start } start #f #f 1 #f make-sampler { sf } sf next-sample fabs { val0 } sf next-sample fabs { val1 } begin sf sampler-at-end? val0 val1 f+ limit f< || not while start 1+ to start val1 to val0 sf next-sample fabs to val1 repeat sf free-sampler drop start #f #f #f set-cursor ; \ ;;; -------- translate mpeg input to 16-bit linear and read into Snd \ ;;; \ ;;; mpg123 with the -s switch sends the 16-bit (mono or stereo) \ ;;; representation of an mpeg file to stdout. There's also \ ;;; apparently a switch to write 'wave' output. : mpg ( mpgfile rawfile -- ) doc" Convert file from MPEG to raw 16-bit samples using mpg123." { mpgfile rawfile } mpgfile io-open-read { io } io io-getc { b0 } io io-getc { b1 } io io-getc { b2 } io io-getc { b3 } io io-close b0 255 <> b1 0b11100000 and 0b11100000 <> || if "%s is not an MPEG file (first 11 bytes: %b %b)" #( mpgfile b0 b1 0b11100000 and ) clm-print exit then b1 0b11000 and 3 rshift { id } b1 0b110 and 1 rshift { layer } b2 0b1100 and 2 rshift { srate-index } b3 0b11000000 and 6 rshift { channel-mode } id 1 = if "odd: %s is using a reserved Version ID" #( mpgfile ) clm-print then layer 0= if "odd: %s is using a reserved layer description" #( mpgfile ) clm-print then channel-mode 3 = if 1 else 2 then { chans } id 0= if 4 else id 2 = if 2 else 1 then then { mpegnum } layer 3 = if 1 else layer 2 = if 2 else 3 then then { mpeg-layer } #( 44100 48000 32000 0 ) srate-index array-ref mpegnum / { srate } "%s: %s Hz, %s, MPEG-%s" #( mpgfile srate chans 1 = if "mono" else "stereo" then mpeg-layer ) clm-print "mpg123 -s %s > %s" #( mpgfile rawfile ) string-format file-system if rawfile chans srate little-endian? if mus-lshort else mus-bshort then open-raw-sound drop else "system in %s: %s" #( get-func-name exit-status ) fth-throw then ; \ "mpeg.mpg" "mpeg.raw" mpg \ ;;; -------- read ASCII files \ ;;; \ ;;; these are used by Octave (WaveLab) -- each line has one integer, \ ;;; apparently a signed short. hide : read-ascii-cb { fname snd -- prc; self -- } 0 proc-create ( prc ) fname , snd , does> { self -- } self @ ( fname ) readlines { in-buffer } self cell+ @ { snd } 512 { bufsize } bufsize 0.0 make-vct { data } 0 { loc } 0 { frame } 32768.0 1/f { short->float } nil { val } in-buffer each ( line ) nil string-split each ( str-val ) string->number ( val ) short->float f* data loc rot vct-set! drop loc 1+ to loc loc bufsize = if data frame bufsize snd 0 vct->channel drop frame bufsize d+ to frame 0 to loc then end-each end-each loc d0> if data frame loc snd 0 vct->channel drop then ; set-current : read-ascii <{ fl :optional sf "test.snd" st mus-next ht mus-bshort sr 44100 -- snd }> doc" Try to read an ASCII sound file." "created by %s: %s" #( get-func-name fl ) string-format { com } sf 1 sr ht st com new-sound { snd } fl snd read-ascii-cb as-one-edit drop snd ; previous \ ;;; -------- make dot size dependent on number of samples being displayed \ ;;; \ ;;; this could be extended to set time-graph-style to graph-lines \ ;;; if many samples are displayed, etc : auto-dot <{ snd chn y0 y1 -- val }> doc" Set the dot size depending on the number of \ samples being displayed (use with graph-hook)." snd chn right-sample snd chn left-sample - { dots } dots 100 > if 1 else dots 50 > if 2 else dots 25 > if 3 else 5 then then then snd chn set-dot-size ; \ graph-hook <'> auto-dot add-hook! \ ;;; -------- move window left edge to mark upon 'm' \ ;;; \ ;;; in large sounds, it can be pain to get the left edge of the window \ ;;; aligned with a specific spot in the sound. In this code, we assume \ ;;; the desired left edge has a mark, and the 'm' key (without control) \ ;;; will move the window left edge to that mark. : first-mark-in-window-at-left <{ -- val }> doc" Move the graph so that the leftmost \ visible mark is at the left edge." #f snd-snd { keysnd } #f snd-chn { keychn } keysnd keychn left-sample { current-left-sample } keysnd keychn #f marks { chan-marks } chan-marks length 0= if "no marks" status-report else #f ( flag ) chan-marks map *key* undef mark-sample end-map each { samp } samp current-left-sample > if drop \ drop #f samp leave then end-each { leftmost } leftmost if leftmost keysnd keychn set-left-sample else "no mark in window" status-report then then drop keyboard-no-action ; \ "m" 0 <'> first-mark-in-window-at-left \ #f "align window left edge with mark" dup bind-key drop \ ;;; -------- flash selected data red and green hide : fsd-cb { ms xt -- prc; self -- val } 0 proc-create ( prc ) ms , xt , does> { self -- val } self @ ( ms ) self cell+ @ ( xt ) execute #f ; user data-red? #t data-red? ! set-current : flash-selected-data ( millisecs -- ) doc" Cause the selected data to flash red and green." { ms } selected-sound sound? if data-red? @ if green else red then set-selected-data-color drop data-red? @ not data-red? ! ms ms running-word fsd-cb in drop then ; previous \ ;;; -------- use loop info (if any) to set marks at loop points : mark-loops ( -- ) doc" Place marks at loop points found in the selected sound's header." #f snd-snd { snd } #f snd-chn { chn } snd sound-loop-info snd file-name mus-sound-loop-info || { loops } loops empty? if "%s has no loop info" #( snd short-file-name ) string-format snd status-report drop exit then loops 0 array-ref 0<> loops 1 array-ref 0<> || if loops 0 array-ref snd chn undef undef add-mark drop loops 1 array-ref snd chn undef undef add-mark drop loops 2 array-ref 0<> loops 3 array-ref 0<> || if loops 2 array-ref snd chn undef undef add-mark drop loops 3 array-ref snd chn undef undef add-mark drop then then ; \ ;;; -------- mapping extensions \ ;;; (map arbitrary single-channel function over various channel collections) : do-all-chans <{ func :optional origin #f -- }> doc" Apply FUNC to all active channels, \ using ORIGIN as the edit history indication:\n\ lambda: <{ val -- val*2 }> val f2* ; \"double all samples\" do-all-chans." all-chans each { lst } lst 0 array-ref { snd } lst 1 array-ref { chn } func 0 #f snd chn #f origin map-channel drop end-each ; : update-graphs ( -- ) doc" Update (redraw) all graphs." all-chans each { lst } lst 0 array-ref { snd } lst 1 array-ref { chn } snd chn update-time-graph drop end-each ; : do-chans <{ func :optional origin #f -- }> doc" Apply FUNC to all sync'd channels \ using ORIGIN as the edit history indication." #f snd-snd sync { snc } snc 0> if all-chans each { lst } lst 0 array-ref { snd } lst 1 array-ref { chn } snd sync snc = if func 0 #f snd chn #f origin map-channel drop then end-each else "sync not set" snd status-report drop then ; : do-sound-chans <{ func :optional origin #f -- }> doc" Apply FUNC to all selected channels \ using ORIGIN as the edit history indication." selected-sound { snd } snd sound? if snd channels 0 ?do func 0 #f snd i ( chn ) #f origin map-channel drop loop else "no selected sound" snd status-report drop then ; hide : everys-cb { func -- prc; y self -- f } 1 proc-create ( prc ) func , does> { y self -- f } self @ ( func ) #( y ) run-proc not ; set-current : every-sample? ( func -- f ) doc" Return #t if FUNC is not #f for all samples in the \ current channel, otherwise it moves the cursor to the first offending sample." { func } func everys-cb 0 #f #f #f #f scan-channel { baddy } baddy if baddy 1 array-ref #f #f #f set-cursor drop then baddy not ; previous hide : sorts-cb { bins -- prc; y self -- f } 1 proc-create ( prc ) bins , does> { y self -- f } self @ { bins } y fabs bins length f* fround->s { bin } bins bin 1 object-set+! #f ; set-current : sort-samples ( nbins -- ary ) doc" Provide histogram in BINS bins." { nbins } nbins :initial-element 0 make-array { bins } bins sorts-cb 0 #f #f #f #f scan-channel drop bins ; previous \ ;;; -------- mix mono sound into stereo sound panning according to env hide : places1-cb { rd pos -- prc; y self -- val } 1 proc-create ( prc ) rd , pos , does> { y self -- val } self @ { rd } self cell+ @ { pos } rd read-sample pos f* y f+ ; : places0-cb { rd pos -- prc; y self -- val } 1 proc-create ( prc ) rd , pos , does> { y self -- val } self @ { rd } self cell+ @ { pos } rd read-sample 1.0 pos f- f* y f+ ; : places3-cb { rd en -- prc; y self -- val } 1 proc-create ( prc ) rd , en , does> { y self -- val } self @ { rd } self cell+ @ { en } rd read-sample en env f* y f+ ; : places2-cb { rd en -- prc; y self -- val } 1 proc-create ( prc ) rd , en , does> { y self -- val } self @ { rd } self cell+ @ { en } rd read-sample 1.0 en env f- f* y f+ ; set-current : place-sound ( mono stereo pan -- res ) doc" Mix a mono sound into a stereo sound, \ splitting it into two copies whose amplitudes depend on the envelope PAN-ENV. \ If PAN-ENV is a number, the sound is split such that 0 is all in channel 0 \ and 90 is all in channel 1." { mono stereo pan } mono #f #f #f framples { len } pan number? if pan 90.0 f/ { pos } 0 mono #f 1 #f make-sampler { reader0 } 0 mono #f 1 #f make-sampler { reader1 } reader1 pos places1-cb 0 len stereo 1 #f #f map-channel drop reader0 pos places0-cb 0 len stereo 0 #f #f map-channel drop else :envelope pan :length len make-env { e0 } :envelope pan :length len make-env { e1 } 0 mono #f 1 #f make-sampler { reader0 } 0 mono #f 1 #f make-sampler { reader1 } reader1 e1 places3-cb 0 len stereo 1 #f #f map-channel drop reader0 e0 places2-cb 0 len stereo 0 #f #f map-channel drop then ; previous \ ;;; -------- FFT-based editing : fft-edit <{ bottom top :optional snd #f chn #f -- vct }> doc" Fft an entire sound, remove all energy \ below BOTTOM and all above TOP, then inverse fft." snd srate { sr } snd chn #f framples { len } 2.0 len flog 2.0 flog f/ fceil f** fround->s { fsize } 0 fsize snd chn #f channel->vct { rdata } fsize 0.0 make-vct { idata } bottom sr fsize f/ f/ fround->s { lo } top sr fsize f/ f/ fround->s { hi } rdata idata 1 fft drop lo 0> if rdata 0 0.0 vct-set! drop idata 0 0.0 vct-set! drop fsize 1- { jj } lo 1 ?do rdata i 0.0 vct-set! drop rdata jj 0.0 vct-set! drop idata i 0.0 vct-set! drop idata jj 0.0 vct-set! drop jj 1- to jj loop then hi fsize 2/ < if fsize hi - { jj } fsize 2/ hi ?do rdata i 0.0 vct-set! drop rdata jj 0.0 vct-set! drop idata i 0.0 vct-set! drop idata jj 0.0 vct-set! drop jj 1- to jj loop then rdata idata -1 fft drop "%s %s %s" #( bottom top get-func-name ) string-format { origin } rdata fsize 1/f vct-scale! 0 len 1- snd chn #f origin vct->channel ; : fft-squelch <{ squelch :optional snd #f chn #f -- scl }> doc" Fft an entire sound, set all bins \ to 0.0 whose energy is below squelch, then inverse fft." snd chn #f framples { len } 2.0 len flog 2.0 flog f/ fceil f** fround->s { fsize } 0 fsize snd chn #f channel->vct { rdata } fsize 0.0 make-vct { idata } fsize 2/ { fsize2 } rdata idata 1 fft drop rdata vct-copy { vr } idata vct-copy { vi } vr vi rectangular->polar drop vr vct-peak { scaler } squelch scaler f* { scl-squelch } rdata 0 vct-ref dup f* idata 0 vct-ref dup f* f+ fsqrt scl-squelch f< if rdata 0 0.0 vct-set! drop idata 0 0.0 vct-set! drop then fsize 1- { jj } fsize 1 ?do rdata i vct-ref dup f* idata i vct-ref dup f* f+ fsqrt scl-squelch f< if rdata i 0.0 vct-set! drop rdata jj 0.0 vct-set! drop idata i 0.0 vct-set! drop idata jj 0.0 vct-set! drop then jj 1- to jj loop rdata idata -1 fft drop "%s %s" #( squelch get-func-name ) string-format { origin } rdata fsize 1/f vct-scale! 0 len 1- snd chn #f origin vct->channel drop scaler ; : fft-cancel <{ lo-freq hi-freq :optional snd #f chn #f -- vct }> doc" Fft an entire sound, set the bin(s) \ representing LO-FREQ to HI-FREQ to 0, then inverse fft." snd srate { sr } snd chn #f framples { len } 2.0 len flog 2.0 flog f/ fceil f** fround->s { fsize } 0 fsize snd chn #f channel->vct { rdata } fsize 0.0 make-vct { idata } rdata idata 1 fft drop sr fsize f/ { hz-bin } lo-freq hz-bin f/ fround->s { lo-bin } hi-freq hz-bin f/ fround->s { hi-bin } fsize lo-bin - { jj } hi-bin 1+ lo-bin ?do rdata i 0.0 vct-set! drop rdata jj 0.0 vct-set! drop idata i 0.0 vct-set! drop idata jj 0.0 vct-set! drop jj 1- to jj loop rdata idata -1 fft drop "%s %s %s" #( lo-freq hi-freq get-func-name ) string-format { origin } rdata fsize 1/f vct-scale! 0 len 1- snd chn #f origin vct->channel ; : make-ramp <{ :optional size 128 -- gen }> doc" Return ramp generator." vct( 0.0 size ) ; : ramp <{ gen up -- val }> doc" Is a kind of CLM generator that produces a ramp of a \ given length, then sticks at 0.0 or 1.0 until the UP argument changes." gen 0 vct-ref { ctr } gen 1 vct-ref { size } ctr size f/ { val } gen 0 ctr up if 1 else -1 then f+ 0 fmax size fmin vct-set! drop val ; hide : squelch-vowels-cb { snd chn -- prc; y self -- val } 32 { fft-size } 0 snd chn 1 #f make-sampler { read-ahead } 1 proc-create { prc } fft-size 0.0 make-vct map! read-ahead #() apply end-map ( rl ) , fft-size 0.0 make-vct ( im ) , 256 make-ramp ( ramper ) , snd chn #f maxamp fft-size f2/ f/ ( peak ) , read-ahead , #f ( in-vowel ) , prc does> { y self -- val } self @ { rl } self cell+ @ { im } self 2 cells + @ { ramper } self 3 cells + @ { peak } self 4 cells + @ { read-ahead } self 5 cells + @ { in-vowel } rl read-ahead #() apply cycle-set! rl cycle-start@ 0= if rl im 1 fft ( rl ) dup vct-multiply! drop im im vct-multiply! drop rl im 0 vct-add! drop rl 0 vct-ref rl 1 vct-ref f+ rl 2 vct-ref f+ rl 3 vct-ref f+ peak f> to in-vowel in-vowel self 5 cells + ! ( in-vowel ) im 0.0 vct-fill! drop then 1.0 ramper in-vowel ramp f- ( rval ) y f* ; set-current : squelch-vowels <{ :optional snd #f chn #f -- val }> doc" Suppress portions of a sound that look like steady-state." snd chn squelch-vowels-cb 0 #f snd chn #f get-func-name map-channel ; previous : fft-env-data <{ fft-env :optional snd #f chn #f -- vct }> doc" Apply FFT-ENV as spectral env to current sound, \ returning vct of new data." snd chn #f framples { len } 2.0 len flog 2.0 flog f/ fceil f** fround->s { fsize } 0 fsize snd chn #f channel->vct { rdata } fsize 0.0 make-vct { idata } fsize 2/ { fsize2 } :envelope fft-env :length fsize2 make-env { e } rdata idata 1 fft drop e env { val } rdata 0 val object-set*! idata 0 val object-set*! fsize 1- { jj } fsize2 1 ?do e env to val rdata i val object-set*! rdata jj val object-set*! idata i val object-set*! idata jj val object-set*! jj 1- to jj loop rdata idata -1 fft ( rdata ) fsize 1/f vct-scale! ; : fft-env-edit <{ fft-env :optional snd #f chn #f -- vct }> doc" Edit (filter) current chan using FFT-ENV." "%s %s" #( fft-env get-func-name ) string-format { origin } fft-env snd chn fft-env-data 0 snd chn #f framples 1- snd chn #f origin vct->channel ; : fft-env-interp <{ env1 env2 interp :optional snd #f chn #f -- vct }> doc" Interpolate between two fft-filtered \ versions (ENV1 and ENV2 are the spectral envelopes) \ following interp (an env between 0 and 1)." env1 snd chn fft-env-data { data1 } env2 snd chn fft-env-data { data2 } snd chn #f framples { len } :envelope interp :length len make-env { e } "%s %s %s %s" #( env1 env2 interp get-func-name ) string-format { origin } len 0.0 make-vct map! e env { pan } 1.0 pan f- data1 i vct-ref f* data2 i vct-ref pan f* f+ end-map ( new-data ) 0 len 1- snd chn #f origin vct->channel ; : filter-fft <{ flt :optional normalize #t snd #f chn #f -- val }> doc" Get the spectrum of all the data in the given channel, \ apply the function FLT to it, then inverse fft. \ FLT should take one argument, the current spectrum value.\n\ lambda: <{ y -- val }> y 0.01 f< if 0.0 else y then ; filter-fft\n\ is like fft-squelch." snd chn #f framples { len } snd chn #f maxamp { mx } 2.0 len flog 2.0 flog f/ fceil f** fround->s { fsize } fsize 2/ { fsize2 } 0 fsize snd chn #f channel->vct { rdata } fsize 0.0 make-vct { idata } rdata rectangular-window fsize #t 1.0 #f ( in-place == #f ) normalize snd-spectrum { spect } rdata idata 1 fft drop flt #( spect 0 vct-ref ) run-proc drop fsize 1- { jj } fsize2 1 ?do spect i vct-ref { orig } flt #( orig ) run-proc { cur } orig fabs 0.000001 f> if cur orig f/ { scl } rdata i scl object-set*! idata i scl object-set*! rdata jj scl object-set*! idata jj scl object-set*! else cur fabs 0.000001 f> if cur 2.0 fsqrt f/ { scl } rdata i scl vct-set! drop idata i scl vct-set! drop rdata jj scl vct-set! drop idata jj scl fnegate vct-set! drop then then jj 1- to jj loop rdata idata -1 fft drop "<'> %s %s" #( flt get-func-name ) string-format { origin } mx f0<> if rdata vct-peak { pk } rdata mx pk f/ vct-scale! else rdata then 0 len 1- snd chn #f origin vct->channel ; \ 0.5 0.5 make-one-zero filter-fft \ 0.05 0.05 make-one-pole filter-fft \ lambda: <{ y -- val }> y 0.1 f< if 0.0 else y then ; filter-fft \ 0 0 0 1 0 make-sampler filter-fft \ <'> contrast-enhancement filter-fft \ lambda: <{ y -- val }> y y f* y f* ; filter-fft : fft-smoother <{ cutoff start samps :optional snd #f chn #f -- val }> doc" Use fft-filtering to smooth a section:\n\ #f #f #f cursor value curs 0.1 curs 400 #f #f fft-smoother curs 400 #f #f #f undef vct->channel." 2.0 samps 1+ flog 2.0 flog f/ fceil f** fround->s { fftpts } start fftpts snd chn #f channel->vct { rl } fftpts 0.0 make-vct { im } fftpts cutoff f* fround->s { top } rl 0 vct-ref { old0 } rl samps 1- vct-ref { old1 } rl vct-peak { oldmax } rl im 1 fft drop fftpts top ?do rl i 0.0 vct-set! drop im i 0.0 vct-set! drop loop rl im -1 fft ( rl ) fftpts 1/f vct-scale! drop rl vct-peak { newmax } newmax f0<> if oldmax newmax f/ 1.5 f> if rl oldmax newmax f/ vct-scale! drop then rl 0 vct-ref { new0 } rl samps 1- vct-ref { new1 } old0 new0 f- { offset0 } old1 new1 f- { offset1 } offset1 offset0 f= if 0.0 else offset1 offset0 f- samps f/ then { incr } offset0 { trend } samps 0 ?do rl i trend object-set+! trend incr f+ to trend loop then rl ; \ ;;; -------- comb-filter : comb-filter ( scaler size -- prc; x self -- val ) doc" Return comb-filter ready for map-channel etc: \ 0.8 32 comb-filter map-channel. \ If you're in a hurry use: 0.8 32 make-comb clm-channel instead." { scaler size } scaler size make-comb { gen } 1 proc-create ( prc ) gen , does> { x self -- val } self @ ( cmb ) x 0.0 comb ; \ ;;; by using filters at harmonically related sizes, we can get chords: : comb-chord ( scaler size amp -- prc; x self -- val ) doc" Return set of harmonically-related comb \ filters: 0.95 100 0.3 comb-chord map-channel." { scaler size amp } scaler size make-comb { c1 } scaler size 0.75 f* f>s make-comb { c2 } scaler size 1.2 f* f>s make-comb { c3 } 1 proc-create ( prc ) amp , c1 , c2 , c3 , does> ( x self -- val ) { x self } self @ { amp } self 1 cells + @ { c1 } self 2 cells + @ { c2 } self 3 cells + @ { c3 } c1 x 0.0 comb c2 x 0.0 comb c3 x 0.0 comb f+ f+ amp f* ; \ ;;; or change the comb length via an envelope: : zcomb ( scaler size pm -- prc; x self -- val ) doc" Return comb filter whose length varies according to an envelope:\n\ 0.8 32 #( 0 0 1 10 ) zcomb map-channel." { scaler size pm } :size size :max-size pm 0.0 max-envelope 1.0 f+ size f+ fround->s make-comb { gen } :envelope pm :length #f #f #f framples make-env { penv } 1 proc-create ( prc ) gen , penv , does> { x self -- val } self @ ( gen ) x self cell+ @ ( penv ) env comb ; : notch-filter ( scaler size -- prc; x self -- val ) doc" Return notch-filter: 0.8 32 notch-filter map-channel." make-notch { gen } 1 proc-create ( prc ) gen , does> { x self -- val } self @ ( gen ) x 0.0 notch ; : formant-filter ( radius frequency -- prc; x self -- val ) doc" Return formant generator: 2400 0.99 formant-filter map-channel. \ Faster is: 2400 0.99 make-formant filter-sound." make-formant { gen } 1 proc-create ( prc ) gen , does> { x self -- val } self @ ( gen ) x formant ; : formants ( r1 f1 r2 f2 r3 f3 -- prc; x self -- val ) doc" Return 3 formant filters in \ parallel: 0.99 900 0.98 1800 0.99 2700 formants map-channel." { r1 f1 r2 f2 r3 f3 } f1 r1 make-formant { fr1 } f2 r2 make-formant { fr2 } f3 r3 make-formant { fr3 } 1 proc-create ( prc ) fr1 , fr2 , fr3 , does> { x self -- val } self @ ( fr1 ) x formant self 1 cells + @ ( fr2 ) x formant f+ self 2 cells + @ ( fr3 ) x formant f+ ; : moving-formant ( radius move -- prc; x self -- val ) doc" Return time-varying (in frequency) formant filter:\n\ 0.99 #( 0 1200 1 2400 ) moving-formant map-channel." { radius move } move 1 array-ref radius make-formant { frm } :envelope move :length #f #f #f framples make-env { menv } 1 proc-create ( prc ) frm , menv , does> { x self -- val } self @ ( frm ) x formant ( val ) self @ ( frm ) self cell+ @ ( menv ) env set-mus-frequency drop ( val ) ; : osc-formants ( radius bases amounts freqs -- prc; x self -- val ) doc" Return time-varying (in frequency) formant filter:\n\ 0.99 #( 0 1200 1 2400 ) moving-formant map-channel." { radius bases amounts freqs } bases vct-length { len } len make-array map! bases i vct-ref radius make-formant end-map { frms } len make-array map! freqs i vct-ref make-oscil end-map { oscs } 1 proc-create ( prc ) frms , amounts , oscs , bases , does> { x self -- val } self @ { frms } self 1 cells + @ { amounts } self 2 cells + @ { oscs } self 3 cells + @ { bases } 0.0 ( val ) frms each { frm } frm x formant f+ ( val += ... ) frm bases i vct-ref amounts i vct-ref oscs i array-ref 0.0 0.0 oscil f* f+ set-mus-frequency drop end-each ( val ) ; \ ;;; -------- echo : echo ( scaler secs -- prc; y self -- val ) doc" Return echo maker: 0.5 0.5 echo 0 44100 map-channel." { scaler secs } secs #f srate f* fround->s make-delay { del } 1 proc-create ( prc ) del , scaler , does> { y self -- val } self @ { del } self cell+ @ { scaler } del del 0.0 tap y f+ scaler f* 0.0 delay y f+ ; : zecho ( scaler secs freq amp -- prc; y self -- val ) doc" Return modulated echo maker: \ 0.5 0.75 6 10.0 zecho 0 65000 map-channel." { scaler secs freq amp } freq make-oscil { os } secs #f srate f* fround->s { len } :size len :max-size len amp f+ fround->s 1+ make-delay { del } 1 proc-create ( prc ) del , scaler , os , amp , does> { y self -- val } self @ { del } self cell+ @ { scaler } self 2 cells + @ { os } self 3 cells + @ { amp } del del 0.0 tap y f+ scaler f* os 0.0 0.0 oscil amp f* delay y f+ ; : flecho ( scaler secs -- prc; y self -- val ) doc" Return low-pass filtered echo maker: \ 0.5 0.9 flecho 0 75000 map-channel." { scaler secs } :order 4 :xcoeffs vct( 0.125 0.25 0.25 0.125 ) make-fir-filter { flt } secs #f srate f* fround->s make-delay { del } 1 proc-create ( prc ) del , scaler , flt , does> { y self -- val } self @ { del } self cell+ @ { scaler } self 2 cells + @ { flt } del flt del 0.0 tap y f+ scaler f* fir-filter 0.0 delay y f+ ; \ ;;; -------- ring-mod and am \ ;;; \ ;;; CLM instrument is ring-modulate.ins : ring-mod ( freq gliss-env -- prc; y self -- val ) doc" Return time-varying ring-modulation filter:\n\ 10 #( 0 0 1 100 hz->radians ) ring-mod map-channel." { freq gliss-env } :frequency freq make-oscil { os } :envelope gliss-env :length #f #f #f framples make-env { genv } 1 proc-create ( prc ) os , genv , does> { y self -- val } self @ { os } self cell+ @ { genv } os genv env 0.0 oscil y f* ; : am ( freq -- prc; y self -- val ) doc" Return amplitude-modulator: 440 am map-channel." make-oscil { os } 1 proc-create ( prc ) os , does> { y self -- val } 1.0 y self @ ( os ) 0.0 0.0 oscil amplitude-modulate ; \ ;;; this taken from sox (vibro.c) : vibro ( speed depth -- prc; y self -- val ) { speed depth } speed make-oscil { sine } depth f2/ { scl } 1.0 scl f- { offset } 1 proc-create ( prc ) sine , scl , offset , does> { y self -- val } self @ { sine } self cell+ @ { scl } self 2 cells + @ { offset } sine 0.0 0.0 oscil scl f* offset f+ y f* ; \ ;;; -------- hello-dentist \ ;;; \ ;;; CLM instrument version is in sndclm.html hide : hd-input-cb { in-data -- prc; dir self -- val } 1 proc-create ( prc ) in-data , 0 ( idx ) , does> { dir self -- val } self @ { in-data } self cell+ @ { idx } in-data idx object-range? if in-data idx vct-ref else 0.0 then ( val ) idx dir + self cell+ ! ( idx ) ( val ) ; set-current : hello-dentist <{ frq amp :optional snd #f chn #f -- vct }> doc" Vary the sampling rate randomly, making a voice sound quavery:\n\ 40.0 0.1 #f #f hello-dentist drop." :frequency frq :amplitude amp make-rand-interp { rn } snd chn #f framples { len } 0 len snd chn #f channel->vct { in-data } :srate 1.0 :input in-data hd-input-cb make-src { rd } "%s %s %s" #( frq amp get-func-name ) string-format { origin } amp f2* 1.0 f+ len f* fround->s 0.0 make-vct map! rd rn 0.0 rand-interp #f src end-map ( out-data ) 0 len snd chn #f origin vct->channel ; previous \ ;;; a very similar function uses oscil instead of rand-interp, giving \ ;;; various "Forbidden Planet" sound effects: hide : fp-input-cb { sf -- prc; dir self -- val } 1 proc-create ( prc ) sf , does> { dir self -- val } self @ ( sf ) dir 0> if next-sample else previous-sample then ; set-current : fp <{ sr osamp osfrq :optional snd #f chn #f -- vct }> doc" Vary the sampling rate via an oscil: 1.0 0.3 20 #f #f fp." osfrq make-oscil { os } 0 snd chn 1 #f make-sampler { sf } :srate sr :input sf fp-input-cb make-src { s } snd chn #f framples { len } "%s %s %s %s" #( sr osamp osfrq get-func-name ) string-format { origin } len 0.0 make-vct map! s os 0.0 0.0 oscil osamp f* #f src end-map ( out-data ) 0 len snd chn #f origin vct->channel ( vct ) sf free-sampler drop ; previous vct( -1.000 -0.960 -0.900 -0.820 -0.720 -0.600 -0.450 -0.250 0.000 0.250 0.450 0.600 0.720 0.820 0.900 0.960 1.000 ) constant compand-table : compand ( -- prc; y self -- val ) doc" Return compander: compand map-channel." 1 proc-create ( prc ) does> { y self -- val } compand-table y 8.0 f* 8.0 f+ compand-table vct-length array-interp ; \ ;;; -------- shift pitch keeping duration constant \ ;;; \ ;;; both src and granulate take a function argument to get input \ ;;; whenever it is needed. \ ;;; In this case, src calls granulate which reads the currently \ ;;; selected file. CLM version is in expsrc.ins hide : expgr-cb { v snd chn -- prc; dir self -- val } 1 proc-create ( prc ) v , snd , chn , 0 , does> { dir self -- val } self @ { v } v cycle-ref ( val ) v cycle-start@ 0= if self cell+ @ { snd } self 2 cells + @ { chn } self 3 cells + @ { vbeg } vbeg v vct-length + dup self 3 cells + ! ( vbeg += v-len ) vbeg v vct-length snd chn #f channel->vct drop then ( val ) ; : expsr-cb { gr -- prc; dir self -- val } 1 proc-create ( prc ) gr , does> { dir self -- val } self @ ( gr ) #f #f granulate ; set-current : expsrc <{ rate :optional snd #f chn #f -- val }> doc" Use sampling-rate conversion and granular synthesis to \ produce a sound at a new pitch but at the original tempo. \ It returns a function for map-channel." 0 1024 snd chn #f channel->vct { v } :input v snd chn expgr-cb :expansion rate make-granulate { gr } :input gr expsr-cb :srate rate make-src { sr } 1 proc-create ( prc ) sr , does> { y self -- val } self @ ( sr ) 0.0 #f src ; previous \ ;;; the next (expsnd) changes the tempo according to an envelope; the new \ ;;; duration will depend on the expansion envelope -- we integrate it to get \ ;;; the overall expansion, then use that to decide the new length. hide : es-input-cb { sf -- prc; dir self -- val } 1 proc-create ( prc ) sf , does> { dir self -- val } self @ ( sf ) next-sample ; set-current : expsnd <{ gr-env :optional snd #f chn #f -- vct }> doc" Use the granulate generator to change tempo \ according to an envelope:\n\ #( 0 0.5 2 2.0 ) #f #f expsnd." snd chn #f framples { len } len snd srate f/ gr-env integrate-envelope f* gr-env envelope-last-x f/ { dur } 0 snd chn 1 #f make-sampler { sf } :expansion gr-env 1 array-ref :jitter 0 :input sf es-input-cb make-granulate { gr } :envelope gr-env :duration dur make-env { ge } snd srate dur f* fround->s { sound-len } sound-len len max to len "%s %s" #( gr-env get-func-name ) string-format { origin } len 0.0 make-vct map! gr #f granulate ( val ) gr ge env set-mus-increment drop end-map ( out-data ) 0 len snd chn #f origin vct->channel ( vct ) sf free-sampler drop ; previous \ ;;; -------- cross-synthesis \ ;;; \ ;;; CLM version is in sndclm.html : cross-synthesis ( cross-snd amp fftsize r -- prc; y self -- val ) doc" Do cross-synthesis between CROSS-SND (a sound index) \ and the currently selected sound:\n\ 1 0.5 128 6.0 cross-synthesis map-channel." { cross-snd amp fftsize r } fftsize 2/ { freq-inc } fftsize 0.0 make-vct { fdr } fftsize 0.0 make-vct { fdi } freq-inc 0.0 make-vct { spectr } 1.0 r fftsize f/ f- { radius } #f srate fftsize / { bin } freq-inc make-array map! i bin * radius make-formant end-map spectr make-formant-bank { formants } 1 proc-create ( prc ) fdr , fdi , spectr , formants , amp , freq-inc , cross-snd , fftsize , 0 , does> { y self -- val } self @ { fdr } self cell+ @ { fdi } self 2 cells + @ { spectr } self 3 cells + @ { formants } self 4 cells + @ { amp } self 5 cells + @ { ctr } ctr formants length = if self 6 cells + @ { cross-snd } self 7 cells + @ { fftsize } self 8 cells + @ { inctr } inctr fftsize cross-snd 0 #f channel->vct dup self ! to fdr inctr fftsize 2/ + self 8 cells + ! ( inctr += freq-inc ) fdr fdi #f 2 spectrum ( fdr ) spectr vct-subtract! ( fdr ) fftsize 2/ 1/f vct-scale! drop 0 self 5 cells + ! ( ctr = 0 ) then 1 self 5 cells + +! ( ctr++ ) spectr fdr 0 vct-add! drop formants y formant-bank amp f* ; : voiced->unvoiced <{ amp fftsize r tempo :optional snd #f chn #f -- vct }> doc" Turn vocal sound into \ whispering: 1.0 256 2.0 2.0 #f #f voiced->unvoiced." fftsize 2/ { freq-inc } nil { fdr } fftsize 0.0 make-vct { fdi } freq-inc 0.0 make-vct { spectr } snd srate 3.0 f/ make-rand { noi } 0 { inctr } 1.0 r fftsize f/ f- { radius } snd srate fftsize / { bin } snd chn #f framples { len } len tempo f/ fround->s len max { out-len } freq-inc tempo f* fround->s { hop } 0.0 0.0 { old-peak-amp new-peak-amp } "%s %s %s %s %s" #( amp fftsize r tempo get-func-name ) string-format { origin } freq-inc make-array map! i bin * radius make-formant end-map ( formants ) spectr make-formant-bank { formants } freq-inc 1/f { 1/freq-inc } out-len 0.0 make-vct map! i freq-inc mod 0= if inctr fftsize snd chn #f channel->vct to fdr fdr vct-peak old-peak-amp fmax to old-peak-amp fdr fdi #f 2 spectrum ( fdr ) spectr vct-subtract! ( fdr ) 1/freq-inc vct-scale! drop hop inctr + to inctr then spectr fdr 0 vct-add! drop formants noi 0.0 rand formant-bank ( outval ) end-map { out-data } out-data old-peak-amp out-data vct-peak f/ amp f* vct-scale! ( odata ) 0 out-len snd chn #f origin vct->channel ( odata ) ; : pulse-voice <{ co :optional freq 440.0 amp 1.0 fftsize 256 r 2.0 snd #f chn #f -- vct }> doc" Use sum-of-cosines to manipulate speech sounds." fftsize 2/ { freq-inc } fftsize 0.0 make-vct { fdr } fftsize 0.0 make-vct { fdi } freq-inc 0.0 make-vct { spectr } :cosines co :frequency freq make-sum-of-cosines { pulse } 0 { inctr } 1.0 r fftsize f/ f- { radius } snd srate fftsize / { bin } snd chn #f framples { len } 0.0 0.0 { old-peak-amp new-peak-amp } "%s %s %s %s %s %s" #( co freq amp fftsize r get-func-name ) string-format { origin } freq-inc make-array map! i bin * radius make-formant end-map spectr make-formant-bank { formants } len 0.0 make-vct map! i freq-inc mod 0= if inctr fftsize snd chn #f channel->vct to fdr fdr vct-peak old-peak-amp fmax to old-peak-amp fdr fdi #f 2 spectrum ( fdr ) spectr vct-subtract! ( fdr ) freq-inc 1/f vct-scale! drop freq-inc inctr + to inctr then spectr fdr 0 vct-add! drop formants pulse 0.0 sum-of-cosines formant-bank ( outval ) dup fabs new-peak-amp fmax to new-peak-amp ( outval ) end-map old-peak-amp new-peak-amp f/ amp f* vct-scale! 0 len snd chn #f origin vct->channel ( vct ) ; \ 20.0 1.0 1024 0.01 pulse-voice \ 120.0 1.0 1024 0.2 pulse-voice \ 240.0 1.0 1024 0.1 pulse-voice \ 240.0 1.0 2048 pulse-voice \ 1000.0 1.0 512 pulse-voice 'snd-nogui provided? [unless] \ ;;; -------- convolution example hide : cnv-cb { sf -- prc; dir self -- val } 1 proc-create ( prc ) sf , does> { dir self -- val } self @ ( sf ) next-sample ; set-current : cnvtest ( snd0 snd1 amp -- mx ) doc" Convolve SND0 and SND1, scaling by AMP, \ returns new max amp: 0 1 0.1 cnvtest." { snd0 snd1 amp } snd0 #f #f framples { flt-len } snd1 #f #f framples flt-len + { total-len } 0 snd1 0 1 #f make-sampler { sf } :input sf cnv-cb :filter 0 flt-len snd0 #f #f channel->vct make-convolve { cnv } total-len 0.0 make-vct map! cnv #f convolve end-map amp vct-scale! ( out-data ) 0 total-len snd1 #f #f get-func-name vct->channel vct-peak { max-samp } sf free-sampler drop max-samp 1.0 f> if #( max-samp fnegate max-samp ) snd1 #f set-y-bounds drop then max-samp ; previous [then] \ ;;; -------- swap selection chans : swap-selection-channels ( -- ) doc" Swap the currently selected data's channels." undef selection? unless 'no-active-selection #( get-func-name ) fth-throw then selection-chans 2 = if selection-position { beg } selection-framples { len } #f { snd-chn0 } #f { snd-chn1 } all-chans each { lst } lst car lst cadr selection-member? if snd-chn0 false? if lst to snd-chn0 else snd-chn1 false? if lst to snd-chn1 leave then then then end-each snd-chn1 if snd-chn0 car snd-chn0 cadr snd-chn1 car snd-chn1 cadr beg len #f #f swap-channels drop else 'wrong-number-of-channels #( "%s: needs two channels to swap" get-func-name ) fth-throw then else 'wrong-number-of-channels #( "%s: needs a stereo selection (not %s chans)" get-func-name selection-chans ) fth-throw then ; \ ;;; -------- sound interp \ ;;; \ ;;; make-sound-interp sets up a sound reader that reads a channel at an \ ;;; arbitary location, interpolating between samples if necessary, \ ;;; the corresponding "generator" is sound-interp : make-sound-interp <{ start :optional snd #f chn #f -- prc; loc self -- val }> doc" Return an interpolating reader for SND's channel CHN." 0 #f snd chn #f channel->vct { data } 1 proc-create ( prc ) data , data vct-length , does> { loc self -- val } self @ ( data ) loc self cell+ @ ( size ) array-interp ; : sound-interp { func loc -- val } doc" Return sample at LOC (interpolated if necessary) \ from FUNC created by make-sound-interp." loc func execute ; \ ;; env-sound-interp takes an envelope that goes between 0 and 1 \ ;; (y-axis), and a time-scaler (1.0 = original length) and returns a \ ;; new version of the data in the specified channel that follows that \ ;; envelope (that is, when the envelope is 0 we get sample 0, when the \ ;; envelope is 1 we get the last sample, envelope = .5 we get the middle \ ;; sample of the sound and so on. (env-sound-interp #(0 0 1 1)) will \ ;; return a copy of the current sound; (env-sound-interp #(0 0 1 1 2 0) \ ;; 2.0) will return a new sound with the sound copied first in normal \ ;; order, then reversed. src-sound with an envelope could be used \ ;; for this effect, but it is much more direct to apply the envelope \ ;; to sound sample positions. : env-sound-interp <{ en :optional time-scale 1.0 snd #f chn #f -- vct }> doc" Read SND's channel CHN according to EN and TIME-SCALE." snd chn #f framples { len } time-scale len f* fround->s { newlen } :envelope en :length newlen 1+ :scaler len make-env { read-env } 0 #f snd chn #f channel->vct { data } newlen 0.0 make-vct map! data read-env env len array-interp end-map { new-snd } "%s %s %s" #( en time-scale get-func-name ) string-format { origin } 0 newlen new-snd snd chn #t origin 0 current-edit-position #t set-samples ( vct ) ; \ #( 0 0 1 1 2 0 ) 2.0 env-sound-interp : granulated-sound-interp <{ en :optional tscl 1.0 grlen 0.1 gren #f ohop 0.05 snd #f chn #f -- vct }> doc" Read the given channel following EN (as env-sound-interp), \ using grains to create the re-tempo'd read." gren empty? if #( 0 0 1 1 2 1 3 0 ) to gren then snd chn #f framples { len } tscl len f* fround->s { newlen } :envelope en :length newlen :scaler len make-env { read-env } snd srate { sr } grlen sr f* fround->s { grain-framples } ohop sr f* fround->s { hop-framples } grlen ohop f/ fceil->s { num-readers } 0 0 { cur-readers next-reader } sr 0.005 f* { jitter } num-readers make-array { readers } num-readers make-array map! :envelope gren :length grain-framples make-env end-map { grain-envs } newlen 0.0 make-vct { new-snd } newlen 0 ?do read-env i set-mus-location drop read-env env { position-in-original } position-in-original jitter mus-random f+ fround->s 0 max { mx } mx snd chn 1 #f make-sampler { srd } readers srd cycle-set! grain-envs next-reader array-ref mus-reset drop readers cycle-start@ to next-reader cur-readers next-reader < if next-reader to cur-readers then cur-readers 0 ?do grain-envs i array-ref { e } readers i array-ref { rd } \ j is index from outer loop newlen hop-framples j + min j ?do new-snd i e env rd next-sample f* vct-set! drop loop loop hop-framples +loop "%s %s %s %s %s %s" #( en tscl grlen gren ohop get-func-name ) string-format { origin } 0 newlen new-snd snd chn #t origin 0 current-edit-position #t set-samples ( vct ) ; \ #( 0 0 1 .1 2 1 ) 1.0 0.2 #( 0 0 1 1 2 0 ) granulated-sound-interp \ #( 0 0 1 1 ) 2.0 granulated-sound-interp \ #( 0 0 1 .1 2 1 ) 1.0 0.2 #( 0 0 1 1 2 0 ) 0.02 granulated-sound-interp \ ;;; -------- filtered-env hide : fe-cb { flt amp-env -- prc; y self -- val } 1 proc-create ( prc ) flt , amp-env , does> { y self -- val } self @ { flt } self cell+ @ ( amp-env ) env { env-val } flt 0 env-val set-mus-xcoeff drop flt 1 env-val 1.0 f- set-mus-xcoeff drop flt env-val y f* one-pole ; set-current : filtered-env <{ e :optional snd #f chn #f -- val }> doc" It's a time-varying one-pole filter: \ when env is at 1.0, no filtering, as env moves to 0.0, \ low-pass gets more intense; \ amplitude and low-pass amount move together." 1.0 0.0 make-one-pole { flt } :envelope e :length snd chn #f framples make-env { amp-env } flt amp-env fe-cb 0 #f snd chn #f "%s %s" #( e get-func-name ) string-format map-channel ; previous \ ;;; -------- C-x b support: hide all but one of the current sounds \ ;;; (more like Emacs) hide #f value xb-last-buffer #f value xb-current-buffer 0 value xb-last-width 0 value xb-last-height set-current : open-current-buffer { width heigth -- } width to xb-last-width heigth to xb-last-height xb-current-buffer 0 array-ref sound-widgets 0 array-ref { sound-pane } sound-pane if sound-pane show-widget drop sound-pane #( width heigth ) set-widget-size drop xb-current-buffer 0 array-ref select-sound drop xb-current-buffer 1 array-ref select-channel drop then ; : close-all-buffers ( -- ) sounds each ( s ) sound-widgets 0 array-ref hide-widget drop end-each ; previous \ ;;; -------- remove-clicks : find-click ( loc -- pos ) doc" Find the next click starting at LOC." { loc } loc #f #f 1 #f make-sampler { rd } 0.0 0.0 0.0 { samp0 samp1 samp2 } 10 0.0 make-vct { samps } #f \ flag #f #f #f framples loc ?do samp1 to samp0 samp2 to samp1 rd next-sample to samp2 samps samp0 cycle-set! samps vct-peak 0.1 fmax { local-max } samp0 samp1 f- fabs local-max f> samp1 samp2 f- fabs local-max f> && samp0 samp2 f- fabs local-max f2/ f< && if drop ( flag ) i leave then loop ; : remove-clicks ( -- ) doc" Try to find and smooth-over clicks." -2 { click } begin click 2+ find-click to click click while click 2- 4 #f #f smooth-sound drop repeat ; : search-for-click ( -- prc; val self -- pos ) doc" Look for the next click (for use with C-s)." 1 proc-create ( prc ) 10 0.0 make-vct , 0.0 , 0.0 , 0.0 , does> { val self -- pos } self @ { samps } self cell+ @ { samp0 } self 2 cells + @ { samp1 } self 3 cells + @ { samp2 } samp1 to samp0 samp2 to samp1 val to samp2 samp0 self cell+ ! samp1 self 2 cells + ! samp2 self 3 cells + ! samps samp0 cycle-set! samps vct-peak 0.1 fmax { local-max } samp0 samp1 f- fabs local-max f>= samp1 samp2 f- fabs local-max f>= && samp0 samp2 f- fabs local-max f2/ f<= && if -1 else #f then ; : zero+ ( -- prc; n self -- val ) doc" Find the next positive-going zero crossing (if \ searching forward) (for use with C-s)." 1 proc-create ( prc ) 0.0 ( lastn ) , does> { n self -- val } self @ ( lastn ) f0< n f0>= && -1 && ( val ) n self ! ( lastn = n ) ( val ) ; : next-peak ( -- prc; n self -- val ) doc" Find the next max or min point in the \ time-domain waveform (for use with C-s)." 1 proc-create ( prc ) ( last0 ) #f , ( last1 ) #f , does> { n self -- val } self @ { last0 } self cell+ @ { last1 } last0 number? last0 last1 f< last1 n f> && last0 last1 f> last1 n f< && || && -1 && ( val ) last1 self ! ( last0 = last1 ) n self cell+ ! ( last1 = n ) ( val ) ; : find-pitch ( pitch -- prc; y self -- val ) doc" Find the point in the current sound \ where PITCH (in Hz) predominates:\n\ C-s 300 find-pitch\n\ In most cases, this will be slightly offset from the true \ beginning of the note." { pitch } 1 proc-create ( prc ) #f #f transform-size 0.0 make-vct , pitch , does> { y self -- val } self @ { data } self cell+ @ { pitch } data y cycle-set! data cycle-start@ 0= if data vct-peak 0.001 f> if data rectangular-window data length #t 0.0 undef #t snd-spectrum { spectr } 10.0 flog { log10 } 0.0 0 { pk pkloc } data length 2/ 0 ?do spectr i vct-ref dup pk f> if ( val ) to pk i to pkloc else ( val ) drop then loop pkloc 0> if spectr pkloc 1- vct-ref { la } spectr pkloc vct-ref { ca } spectr pkloc 1+ vct-ref { ra } la ca fmax ra fmax 0.001 f* { pk1 } la 0.0000001 fmax pk1 f/ flog log10 f/ { logla } ca 0.0000001 fmax pk1 f/ flog log10 f/ { logca } ra 0.0000001 fmax pk1 f/ flog log10 f/ { logra } logla logra f- f2/ logla logra f+ logca f2* f- f/ else 0.0 then pkloc f+ #f srate f* data length f/ { pit } pitch pit f- fabs #f srate data length f2* f/ f< if data length 2/ negate else #f then ( val ) then data 0.0 vct-fill! drop else #f then ; \ ;;; -------- file->vct and a sort of cue-list, I think [ifundef] file->vct : file->vct ( file -- vct ) doc" Return a vct with FILE's data." { file } file find-file to file file unless 'no-such-file #( "%s: %S" get-func-name file ) fth-throw then 0 file undef 1 #f make-sampler { reader } file mus-sound-framples 0.0 make-vct map! reader next-sample end-map ( data ) reader free-sampler drop ; [then] hide : an-cb ( notes snd chn -- prc; self -- #f ) { notes snd chn } 0 proc-create ( prc ) notes , snd , chn , does> { self -- #f } self @ { notes } self cell+ @ { snd } self 2 cells + @ { chn } snd chn #f cursor { start } notes each { note } note 0 array-ref find-file { file } file unless 'no-such-file #( "add-notes: %S" file ) fth-throw then note length 1 > if note 1 array-ref else 0.0 then { offset } note length 2 > if note 2 array-ref else 1.0 then { amp } snd srate offset f* fround->s start + { beg } amp 1.0 f<> if file file->vct amp vct-scale! beg snd chn #f "add-notes" mix-vct else file beg 0 snd chn #f undef mix then drop end-each #f ; set-current : add-notes <{ notes :optional snd #f chn #f -- #f }> doc" Add (mix) NOTES which is a list of lists of the form:\n\ file :optional offset 0.0 amp 1.0\n\ starting at the cursor in the currently selected channel:\n\ #( #( \"oboe.snd\" ) #( \"pistol.snd\" 1.0 2.0 ) ) add-notes." notes snd chn an-cb "%s %s" #( notes get-func-name ) string-format as-one-edit ; previous hide : rpl-cb { reg -- prc; self -- val } 0 proc-create ( prc ) reg , does> { self -- val } self @ ( reg ) play ; set-current : region-play-list ( data -- ) doc" DATA is list of lists #( #( time reg ) ... ), TIME in secs, \ setting up a sort of play list:\n\ #( #( 0.0 0 ) #( 0.5 1 ) #( 1.0 2 ) #( 1.0 0 ) ) region-play-list." ( data ) each { tone } tone 0 array-ref 1000.0 f* fround->s { time } tone 1 array-ref { region } region region? if time region rpl-cb in drop then end-each ; previous : region-play-sequence ( data -- ) doc" DATA is list of region ids which will be played \ one after the other:\n\ #( 0 2 1 ) region-play-sequence." 0.0 { time } ( data ) map *key* { id } time { cur } id 0 region-framples id region-srate f/ time f+ to time #( cur id ) end-map region-play-list ; \ ;;; -------- replace-with-selection : replace-with-selection ( -- ) doc" Replace the samples from the cursor with the current selection." #f #f #f cursor { beg } #f #f selection-framples { len } beg #f #f insert-selection drop beg len + len #f #f #f delete-samples drop ; \ ;;; -------- explode-sf2 : explode-sf2 ( -- ) doc" Turn the currently selected soundfont file into \ a bunch of files of the form sample-name.aif." #f soundfont-info { lst } lst length 1- { last } lst each { vals } \ #( name start loop-start loop-end ) vals 0 array-ref { name } vals 1 array-ref { start } i last < if lst i 1+ array-ref 1 array-ref else #f #f #f framples then { end } vals 2 array-ref start d- { loop-start } vals 3 array-ref start d- { loop-end } name ".aif" $+ { filename } undef selection? if #f #t #f set-selection-member? drop then #t #f #f set-selection-member? drop start #f #f set-selection-position drop end start d- #f #f set-selection-framples drop :file filename :header-type mus-aifc save-selection drop filename open-sound { temp } temp #( loop-start loop-end ) set-sound-loop-info drop temp close-sound drop end-each ; \ ;;; -------- open-next-file-in-directory hide #f value nd-last-file-opened \ string #f value nd-current-directory \ string #f value nd-current-sorted-files \ array : gcf-sort-cb <{ a b -- n }> a b string< if -1 else a b string> if 1 else 0 then then ; : get-current-files { dir -- } dir to nd-current-directory dir sound-files-in-directory <'> gcf-sort-cb sort to nd-current-sorted-files ; : get-current-directory <{ filename -- filename }> filename to nd-last-file-opened filename mus-expand-filename file-dirname { new-path } nd-current-directory new-path string<> if new-path get-current-files then filename ; set-current : open-next-file-in-directory ( -- f ) \ open-hook <'> get-current-directory hook-member? unless \ open-hook <'> get-current-directory add-hook! \ then nd-last-file-opened string? not sounds nil? not && if #f snd-snd file-name to nd-last-file-opened then nd-current-directory string? unless sounds nil? if file-pwd else nd-last-file-opened file-dirname then get-current-files then nd-current-sorted-files empty? if 'no-such-file #( "%s: %s" get-func-name nd-current-directory ) fth-throw else nd-current-sorted-files cycle-ref { next-file } next-file 0 find-sound if 'file-already-open #( "%s: %s" get-func-name next-file ) fth-throw else sounds nil? unless #f snd-snd close-sound drop then next-file find-file dup if open-sound then drop then then #t ; previous hide : mouse-click-to-open-cb <{ snd chn button state x y axis -- f }> button 2 = if open-next-file-in-directory else #f then ; set-current : click-middle-button-to-open-next-file-in-directory ( -- ) mouse-click-hook <'> mouse-click-to-open-cb add-hook! open-hook <'> get-current-directory add-hook! ; previous \ ;;; -------- chain-dsps instrument: chain-dsps <{ start dur :optional dsps #() -- }> dsps map *key* array? if :envelope *key* :duration dur make-env else *key* then end-map { dsp-chain } start dur nil run-instrument 0.0 { val } dsp-chain each { gen } gen env? if gen env val f* else gen readin? if gen readin val f+ else gen mus-generator? if gen val 0.0 mus-apply else gen #( val ) run-proc then then then to val end-each val end-run ;instrument hide : cdsps-cb { os1 os2 -- prc; val self -- r } 1 proc-create ( prc ) os1 , os2 , does> { val self -- r } self @ ( osc1 ) val 0.0 oscil self cell+ @ ( osc2 ) val f2* 0.0 oscil f+ ; set-current 0 [if] lambda: ( -- ) 440.0 make-oscil { os1 } 0 1.0 #( #( 0 0 1 1 2 0 ) os1 ) chain-dsps 0.5 make-one-zero { oz } "oboe.snd" find-file make-readin { rd } 0 1.0 #( #( 0 0 1 1 2 0 ) oz rd ) chain-dsps 220 make-oscil { osc1 } 440 make-oscil { osc2 } osc1 osc2 cdsps-cb { cb } 0 1.0 #( #( 0 0 1 1 2 0 ) cb ) chain-dsps ; with-sound [then] previous \ ;;; -------- re-order channels : scramble-channels ( new-order -- ) \ ;; (scramble-channels 3 2 0 1) means chan 3 goes to 0, etc { end-chans } end-chans length { len } len 1 > if end-chans map i end-map { cur-chans } end-chans each { end-chan } cur-chans i array-ref { cur-chan } end-chan cur-chan <> if #f cur-chans each { chn } chn end-chan = if drop ( #f ) i leave then end-each { end-loc } #f end-loc #f i 0 len #f swap-channels drop cur-chans end-loc cur-chan array-set! cur-chans i end-chan array-set! then end-each then ; hide : sc-scan-cb { buffer silence in-silence edges samp -- prc; y self -- #f } 1 proc-create ( prc ) buffer , silence , in-silence , edges , samp , does> { y self -- #f } self @ ( buffer ) y y f* moving-average { sum-of-squares } sum-of-squares self cell+ @ ( silence ) f< { now-silent } self 2 cells + @ ( in-silence ) now-silent equal? unless self 3 cells + @ ( edges ) self 4 cells + @ ( samp ) array-push drop then now-silent self 2 cells + ! ( in-silence = now-silent ) 1 self 4 cells + +! ( samp++ ) #f ; : sc-edit-cb { pieces -- prc; self -- val } 0 proc-create ( prc ) pieces , 0 ( start ) , does> { self -- val } self @ { pieces } self cell+ @ { start } 0.0 { scale-by } pieces length { len } len 0 ?do len random fround->s { this } pieces this array-ref { reg } pieces this #f array-set! reg unless len this 1+ ?do pieces i array-ref dup if to reg pieces i #f array-set! leave then loop reg unless 0 this 1- ?do pieces i array-ref dup if to reg pieces i #f array-set! leave then -1 +loop then then reg start #f #f 0 mix-region drop reg 0 region-framples start + to start reg forget-region drop loop pieces ; set-current : scramble-channel ( silence -- ) \ ;; (scramble-channel .01) { silence } 128 make-moving-average { buffer } silence 128 f/ to silence #() { edges } 0 { samp } #t { in-silence } max-regions { old-max } with-mix-tags { old-tags } 1024 set-max-regions drop #f set-with-mix-tags drop buffer silence in-silence edges samp sc-scan-cb 0 #f #f #f #f scan-channel drop edges #f #f #f framples array-push drop 0 0 { start end } edges map start *key* #f #f make-region *key* to start end-map ( pieces ) sc-edit-cb get-func-name as-one-edit drop old-max set-max-regions drop old-tags set-with-mix-tags drop ; previous \ ;; -------- reorder blocks within channel hide : rbb-cb { rd beg ctr actual-block-len len snd chn -- prc; y self -- val } 1 proc-create ( prc ) rd , beg , ctr , actual-block-len , len , snd , chn , does> { y self -- val } self @ { rd } self cell+ @ { beg } self 2 cells + @ { ctr } self 3 cells + @ { actual-block-len } self 4 cells + @ { len } self 5 cells + @ { snd } self 6 cells + @ { chn } rd read-sample { val } beg 10 < if val beg f* 0.1 f* to val else beg actual-block-len 10 - > if val actual-block-len beg - f* 0.1 f* to val then then beg 1+ to beg beg actual-block-len = if 1 self 2 cells + +! ( ctr++ ) 0 self 1 cells + ! ( beg = 0 ) len self 2 cells + @ ( ctr ) actual-block-len * - 0 max snd chn 1 #f make-sampler self ! then val ; set-current : reverse-by-blocks <{ block-len :optional snd #f chn #f -- val }> doc" Divide sound into block-len blocks, \ recombine blocks in reverse order." snd chn #f framples { len } len snd srate block-len f* f/ fround->s { num-blocks } num-blocks 1 > if len num-blocks f/ fceil f>s { actual-block-len } len actual-block-len - snd chn 1 #f make-sampler { rd } 0 { beg } 1 { ctr } "%s %s" #( block-len get-func-name ) string-format { origin } rd beg ctr actual-block-len len snd chn rbb-cb 0 #f snd chn #f origin map-channel else #f then ; previous hide : rwb-cb { len actual-block-len no-clicks-env snd chn -- prc; self -- val } 0 proc-create ( prc ) len , actual-block-len , no-clicks-env , snd , chn , does> { self -- val } self @ { len } self cell+ @ { actual-block-len } self 2 cells + @ { no-clicks-env } self 3 cells + @ { snd } self 4 cells + @ { chn } len 0 ?do i actual-block-len snd chn #f reverse-channel drop no-clicks-env i actual-block-len snd chn #f env-channel drop actual-block-len +loop #t ; set-current : reverse-within-blocks <{ block-len :optional snd #f chn #f -- val }> doc" Divide sound into blocks, recombine in order, \ but each block internally reversed." snd chn #f framples { len } len snd srate block-len f* f/ fround->s { num-blocks } num-blocks 1 > if len num-blocks f/ fceil f>s { actual-block-len } #( 0.0 0.0 0.01 1.0 0.99 1.0 1.0 0.0 ) { no-clicks-env } "%s %s" #( block-len get-func-name ) string-format { origin } len actual-block-len no-clicks-env snd chn rwb-cb origin as-one-edit else 0 #f snd chn #f reverse-channel then ; previous \ ;;; -------- channel-clipped? hide : cc-cb ( -- prc; y self -- f ) 1 proc-create ( prc ) 0.0 ( last-y ) , does> { y self -- f } self @ { last-y } y fabs 0.9999 f>= last-y fabs 0.9999 f>= && ( flag ) y self ! ( last-y = y ) ( flag ) ; set-current : channel-clipped? <{ :optional snd #f chn #f -- val }> doc" Return #t and a sample number if it finds clipping." cc-cb 0 #f snd chn #f scan-channel ; previous \ ;;; -------- sync-everything : sync-everything ( -- ) doc" Set the sync fields of all currently open sounds \ to the same, unique value." sync-max 1+ { new-sync } sounds each ( snd ) new-sync swap set-sync drop end-each ; \ === Moog Filter === hide vct( 0.999969 0.990082 0.980347 0.970764 0.961304 0.951996 0.94281 0.933777 0.924866 0.916077 0.90741 0.898865 0.890442 0.882141 0.873962 0.865906 0.857941 0.850067 0.842346 0.834686 0.827148 0.819733 0.812378 0.805145 0.798004 0.790955 0.783997 0.77713 0.770355 0.763672 0.75708 0.75058 0.744141 0.737793 0.731537 0.725342 0.719238 0.713196 0.707245 0.701355 0.695557 0.689819 0.684174 0.678558 0.673035 0.667572 0.66217 0.65686 0.651581 0.646393 0.641235 0.636169 0.631134 0.62619 0.621277 0.616425 0.611633 0.606903 0.602234 0.597626 0.593048 0.588531 0.584045 0.579651 0.575287 0.570953 0.566681 0.562469 0.558289 0.554169 0.550079 0.546051 0.542053 0.538116 0.53421 0.530334 0.52652 0.522736 0.518982 0.515289 0.511627 0.507996 0.504425 0.500885 0.497375 0.493896 0.490448 0.487061 0.483704 0.480377 0.477081 0.473816 0.470581 0.467377 0.464203 0.46109 0.457977 0.454926 0.451874 0.448883 0.445892 0.442932 0.440033 0.437134 0.434265 0.431427 0.428619 0.425842 0.423096 0.42038 0.417664 0.415009 0.412354 0.409729 0.407135 0.404572 0.402008 0.399506 0.397003 0.394501 0.392059 0.389618 0.387207 0.384827 0.382477 0.380127 0.377808 0.375488 0.37323 0.370972 0.368713 0.366516 0.364319 0.362122 0.359985 0.357849 0.355713 0.353607 0.351532 0.349457 0.347412 0.345398 0.343384 0.34137 0.339417 0.337463 0.33551 0.333588 0.331665 0.329773 0.327911 0.32605 0.324188 0.322357 0.320557 0.318756 0.316986 0.315216 0.313446 0.311707 0.309998 0.308289 0.30658 0.304901 0.303223 0.301575 0.299927 0.298309 0.296692 0.295074 0.293488 0.291931 0.290375 0.288818 0.287262 0.285736 0.284241 0.282715 0.28125 0.279755 0.27829 0.276825 0.275391 0.273956 0.272552 0.271118 0.269745 0.268341 0.266968 0.265594 0.264252 0.262909 0.261566 0.260223 0.258911 0.257599 0.256317 0.255035 0.25375 ) constant moog-gaintable #( 0.0 -1.0 0.03311111 -0.9 0.06457143 -0.8 0.0960272 -0.7 0.127483 -0.6 0.1605941 -0.5 0.1920544 -0.4 0.22682086 -0.3 0.2615873 -0.2 0.29801363 -0.1 0.33278003 -0.0 0.37086168 0.1 0.40893877 0.2 0.4536417 0.3 0.5 0.4 0.5463583 0.5 0.5943719 0.6 0.6556281 0.7 0.72185487 0.8 0.8096009 0.9 0.87913835 0.95 0.9933787 1.0 1.0 1.0 ) constant moog-freqtable #( "moog-freq" "moog-Q" "moog-s" "moog-y" "moog-fc" ) create-struct make-moog-filter-struct set-current <'> moog-freq@ alias moog-frequecy@ ( gen -- frq ) : moog-frequency! { gen frq -- } gen frq moog-freq! gen frq mus-srate f2/ f/ moog-freqtable 1.0 envelope-interp moog-fc! ; : make-moog-filter ( freq Q -- gen ) doc" Make a new moog-filter generator. \ FREQ is the cutoff in Hz, Q sets the resonance: \ 0 = no resonance, 1: oscillates at FREQUENCY." { freq Q } make-moog-filter-struct { gen } gen freq moog-frequency! gen Q moog-Q! gen vct( 0.0 0.0 0.0 0.0 ) moog-s! gen 0.0 moog-y! gen ; : moog-filter ( gen sig -- A ) { gen sig } 0.25 sig gen moog-y@ f- f* { A } gen moog-s@ each { st } gen moog-fc@ A st f- f* A f+ -0.95 fmax 0.95 fmin to A gen moog-s@ i A vct-set! drop A st f+ -0.95 fmax 0.95 fmin to A end-each gen moog-fc@ 99.0 f* { ix } ix fround->s { ixint } ix ixint f- { ixfrac } A gen moog-Q@ f* 1.0 ixfrac f- moog-gaintable ixint 99 + vct-ref f* ixfrac moog-gaintable ixint 100 + vct-ref f* f+ f* gen swap moog-y! A ; previous \ 500.0 0.1 make-moog-filter value gen \ lambda: <{ y -- val }> gen y moog-filter ; map-channel \ gen 1.0 moog-filter \ examp.fs ends here snd-16.1/snd-print.c0000644000076400007640000005635712603035272012435 0ustar bilbil#include "snd.h" /* create Postscript version of graph */ static char *pbuf = NULL; static int bbx = 0, bby = 0, bx0 = 0, by0 = 0; static int ps_fd; static char *nbuf = NULL; static int nbuf_ctr = 0; #define NBUF_SIZE 8192 static void ps_flush(int fd) { if (nbuf_ctr > 0) { ssize_t bytes; bytes = write(fd, nbuf, nbuf_ctr); if (bytes == 0) fprintf(stderr, "ps_flush write error"); nbuf_ctr = 0; memset((void *)nbuf, 0, NBUF_SIZE); } } static void ps_write(const char *buf) { /* sending tiny buffers over the net is a total loss -- grab a bunch at a time */ int i, len; if (!nbuf) { nbuf = (char *)calloc(NBUF_SIZE, sizeof(char)); nbuf_ctr = 0; } len = mus_strlen(buf); for (i = 0; i < len; i++) { nbuf[nbuf_ctr++] = buf[i]; if (nbuf_ctr == NBUF_SIZE) ps_flush(ps_fd); } memset((void *)buf, 0, PRINT_BUFFER_SIZE); } static int start_ps_graph(const char *output, const char *title) { ps_fd = CREAT(output, 0666); if (ps_fd == -1) return(-1); if (!pbuf) pbuf = (char *)calloc(PRINT_BUFFER_SIZE, sizeof(char)); bbx = 0; bby = 0; snprintf(pbuf, PRINT_BUFFER_SIZE, "%%!PS-Adobe-2.0 EPSF-2.0\n%%%%Title: %s\n%%%%Creator: Snd: %s\n%%%%CreationDate: %s", title, SND_DATE, snd_local_time()); ps_write(pbuf); snprintf(pbuf, PRINT_BUFFER_SIZE, "\n%%%%BoundingBox:(atend)\n%%%%EndComments\n%%%%EndProlog\n%%%%Page: 1 1\n"); ps_write(pbuf); snprintf(pbuf, PRINT_BUFFER_SIZE, "/LT {lineto} bind def\n/RF {rectfill} bind def\n/RG {setrgbcolor} bind def\n/NAF {newpath arc fill} bind def\n\n"); ps_write(pbuf); snprintf(pbuf, PRINT_BUFFER_SIZE, "gsave [%.3f 0.0 0.0 %.3f %.3f %.3f] concat\n\n", eps_size(ss), eps_size(ss), eps_left_margin(ss), eps_bottom_margin(ss)); ps_write(pbuf); return(0); } static void ps_graph(chan_info *cp, int x0, int y0) { cp->printing = PRINTING; bx0 = x0; by0 = y0; display_channel_data(cp); cp->printing = NOT_PRINTING; } static void end_ps_graph(void) { snprintf(pbuf, PRINT_BUFFER_SIZE, "%s\nshowpage\n%%%%Trailer\n%%%%BoundingBox: %d %d %d %d\n", ((eps_left_margin(ss) != 0) || (eps_bottom_margin(ss) != 0)) ? "\ngrestore" : "", 0, 0, (int)(bbx + 10 + eps_left_margin(ss)), (int)(bby + 10 + eps_bottom_margin(ss))); ps_write(pbuf); ps_flush(ps_fd); snd_close(ps_fd, "eps file"); if (nbuf) { free(nbuf); nbuf = NULL; nbuf_ctr = 0; } } /* the x and y values in the "points" are relative to grf_x/y: * * x: ap->x_axis_x0 + (val - ap->x0) * ap->x_scale * y: ap->y_axis_y0 + (val * MUS_FIX_TO_FLOAT - ap->y0) * ap->y_scale * * kept here in full precision since normally printers have much higher resolution than screens */ static int reflect_y(axis_info *ap, int y) { return(ap->height - y); } static mus_float_t *xpts = NULL; static mus_float_t *ypts = NULL; static mus_float_t *ypts1 = NULL; void ps_allocate_grf_points(void) { if (!xpts) xpts = (mus_float_t *)calloc(POINT_BUFFER_SIZE, sizeof(mus_float_t)); if (!ypts) ypts = (mus_float_t *)calloc(POINT_BUFFER_SIZE, sizeof(mus_float_t)); if (!ypts1) ypts1 = (mus_float_t *)calloc(POINT_BUFFER_SIZE, sizeof(mus_float_t)); } void ps_set_grf_points(double x, int j, mus_float_t ymin, mus_float_t ymax) { xpts[j] = x; ypts[j] = ymin; ypts1[j] = ymax; } void ps_set_grf_point(double x, int j, mus_float_t y) { xpts[j] = x; ypts[j] = y; } static mus_float_t ps_grf_x(axis_info *ap, mus_float_t val) { return(ap->x_axis_x0 + bx0 + (val - ap->x0) * ap->x_scale); } static mus_float_t ps_grf_y(axis_info *ap, mus_float_t val) { return(by0 + ap->height - (ap->y_axis_y0 + (val - ap->y0) * ap->y_scale)); } static void ps_draw_lines(axis_info *ap, int j, mus_float_t *xpts, mus_float_t *ypts) { int i; snprintf(pbuf, PRINT_BUFFER_SIZE, " %.2f %.2f moveto\n", ps_grf_x(ap, xpts[0]), ps_grf_y(ap, ypts[0])); ps_write(pbuf); for (i = 1; i < j; i++) { snprintf(pbuf, PRINT_BUFFER_SIZE, " %.2f %.2f lineto\n", ps_grf_x(ap, xpts[i]), ps_grf_y(ap, ypts[i])); ps_write(pbuf); } snprintf(pbuf, PRINT_BUFFER_SIZE, " stroke\n"); ps_write(pbuf); } static void ps_draw_dots(axis_info *ap, int j, mus_float_t *xpts, mus_float_t *ypts, int dot_size) { int i; mus_float_t arc_size; arc_size = .5 * dot_size; /* radius here, diameter in X */ for (i = 0; i < j; i++) { snprintf(pbuf, PRINT_BUFFER_SIZE, " %.2f %.2f %.2f 0 360 NAF\n", ps_grf_x(ap, xpts[i]), ps_grf_y(ap, ypts[i]), arc_size); ps_write(pbuf); } } static void ps_fill_polygons(axis_info *ap, int j, mus_float_t *xpts, mus_float_t *ypts, mus_float_t y0) { int i; for (i = 1; i < j; i++) { snprintf(pbuf, PRINT_BUFFER_SIZE, " %.2f %.2f moveto\n", ps_grf_x(ap, xpts[i - 1]), ps_grf_y(ap, ypts[i - 1])); ps_write(pbuf); snprintf(pbuf, PRINT_BUFFER_SIZE, " %.2f %.2f lineto\n", ps_grf_x(ap, xpts[i]), ps_grf_y(ap, ypts[i])); ps_write(pbuf); snprintf(pbuf, PRINT_BUFFER_SIZE, " %.2f %.2f lineto\n", ps_grf_x(ap, xpts[i]), ps_grf_y(ap, y0)); ps_write(pbuf); snprintf(pbuf, PRINT_BUFFER_SIZE, " %.2f %.2f lineto\n", ps_grf_x(ap, xpts[i - 1]), ps_grf_y(ap, y0)); ps_write(pbuf); snprintf(pbuf, PRINT_BUFFER_SIZE, " closepath fill\n"); ps_write(pbuf); } } void ps_draw_grf_points(axis_info *ap, int j, mus_float_t y0, graph_style_t graph_style, int dot_size) { switch (graph_style) { case GRAPH_LINES: default: ps_draw_lines(ap, j, xpts, ypts); break; case GRAPH_DOTS: ps_draw_dots(ap, j, xpts, ypts, dot_size); break; case GRAPH_FILLED: ps_fill_polygons(ap, j, xpts, ypts, y0); break; case GRAPH_DOTS_AND_LINES: ps_draw_lines(ap, j, xpts, ypts); if (dot_size > 1) ps_draw_dots(ap, j, xpts, ypts, dot_size); break; case GRAPH_LOLLIPOPS: { int i, gy0, size8, size4; if (dot_size > 1) ps_draw_dots(ap, j, xpts, ypts, dot_size); gy0 = (int)ps_grf_y(ap, y0); size8 = dot_size / 8; size4 = dot_size / 4; if (size4 < 1) size4 = 1; for (i = 0; i < j; i++) { snprintf(pbuf, PRINT_BUFFER_SIZE, " %.2f %.2f %.2f %.2f RF\n", ps_grf_x(ap, xpts[i]) - size8, (float)gy0, (float)size4, ps_grf_y(ap, ypts[i]) - gy0); ps_write(pbuf); } } break; } } void ps_draw_both_grf_points(axis_info *ap, int j, graph_style_t graph_style, int dot_size) { int i, size8, size4; switch (graph_style) { case GRAPH_LINES: default: ps_draw_lines(ap, j, xpts, ypts); ps_draw_lines(ap, j, xpts, ypts1); break; case GRAPH_DOTS: ps_draw_dots(ap, j, xpts, ypts, dot_size); ps_draw_dots(ap, j, xpts, ypts1, dot_size); break; case GRAPH_FILLED: for (i = 1; i < j; i++) { snprintf(pbuf, PRINT_BUFFER_SIZE, " %.2f %.2f moveto\n", ps_grf_x(ap, xpts[i - 1]), ps_grf_y(ap, ypts[i - 1])); ps_write(pbuf); snprintf(pbuf, PRINT_BUFFER_SIZE, " %.2f %.2f lineto\n", ps_grf_x(ap, xpts[i]), ps_grf_y(ap, ypts[i])); ps_write(pbuf); snprintf(pbuf, PRINT_BUFFER_SIZE, " %.2f %.2f lineto\n", ps_grf_x(ap, xpts[i]), ps_grf_y(ap, ypts1[i])); ps_write(pbuf); snprintf(pbuf, PRINT_BUFFER_SIZE, " %.2f %.2f lineto\n", ps_grf_x(ap, xpts[i - 1]), ps_grf_y(ap, ypts1[i - 1])); ps_write(pbuf); snprintf(pbuf, PRINT_BUFFER_SIZE, " closepath fill\n"); ps_write(pbuf); } break; case GRAPH_DOTS_AND_LINES: if (dot_size > 1) { ps_draw_dots(ap, j, xpts, ypts, dot_size); ps_draw_dots(ap, j, xpts, ypts1, dot_size); } ps_draw_lines(ap, j, xpts, ypts); ps_draw_lines(ap, j, xpts, ypts1); break; case GRAPH_LOLLIPOPS: if (dot_size > 1) { ps_draw_dots(ap, j, xpts, ypts, dot_size); ps_draw_dots(ap, j, xpts, ypts1, dot_size); } size8 = dot_size / 8; size4 = dot_size / 4; if (size4 < 1) size4 = 1; for (i = 0; i < j; i++) { snprintf(pbuf, PRINT_BUFFER_SIZE, " %.2f %.2f %.2f %.2f RF\n", ps_grf_x(ap, xpts[i]) - size8, ps_grf_y(ap, ypts[i]), (float)size4, ps_grf_y(ap, ypts1[i]) - ps_grf_y(ap, ypts[i])); ps_write(pbuf); } break; } } static int last_color = -1; void ps_draw_sono_rectangle(axis_info *ap, int color, mus_float_t x, mus_float_t y, mus_float_t width, mus_float_t height) { rgb_t r, g, b; if (last_color != color) { get_current_color(color_map(ss), color, &r, &g, &b); last_color = color; snprintf(pbuf, PRINT_BUFFER_SIZE, " %.2f %.2f %.2f RG\n", rgb_to_float(r), rgb_to_float(g), rgb_to_float(b)); ps_write(pbuf); } snprintf(pbuf, PRINT_BUFFER_SIZE, " %.1f %.1f %.2f %.2f RF\n", ps_grf_x(ap, x) + 2, ps_grf_y(ap, y), width, height); ps_write(pbuf); } void ps_reset_color(void) { snprintf(pbuf, PRINT_BUFFER_SIZE, " 0 setgray\n"); ps_write(pbuf); last_color = -1; } #if USE_MOTIF || USE_GTK static void ps_set_color(color_t color) { #if USE_MOTIF Colormap cmap; XColor tmp_color; Display *dpy; dpy = XtDisplay(MAIN_SHELL(ss)); cmap = DefaultColormap(dpy, DefaultScreen(dpy)); tmp_color.flags = DoRed | DoGreen | DoBlue; tmp_color.pixel = color; XQueryColor(dpy, cmap, &tmp_color); snprintf(pbuf, PRINT_BUFFER_SIZE, " %.2f %.2f %.2f RG\n", rgb_to_float(tmp_color.red), rgb_to_float(tmp_color.green), rgb_to_float(tmp_color.blue)); ps_write(pbuf); #else #if USE_GTK snprintf(pbuf, PRINT_BUFFER_SIZE, " %.2f %.2f %.2f RG\n", rgb_to_float(color->red), rgb_to_float(color->green), rgb_to_float(color->blue)); ps_write(pbuf); #endif #endif last_color = -1; } #endif void ps_bg(axis_info *ap, graphics_context *ax) { /* get background color, fill graph, then set foreground for axis */ chan_info *cp; cp = ap->cp; #if USE_MOTIF { XGCValues gv; XGetGCValues(MAIN_DISPLAY(ss), ax->gc, GCBackground, &gv); ps_set_color(gv.background); } #else #if USE_GTK { if (cp->selected) ps_set_color(ss->selected_graph_color); else ps_set_color(ss->graph_color); } #endif #endif snprintf(pbuf, PRINT_BUFFER_SIZE, " %d %d %d %d RF\n", ap->graph_x0 + bx0, ap->y_offset + by0, ap->width, ap->height); ps_write(pbuf); ps_fg(cp, ax); } void ps_fg(chan_info *cp, graphics_context *ax) { /* set foreground color for subsequent line drawing */ #if USE_MOTIF ps_set_color(get_foreground_color(ax)); #else #if USE_GTK { if (cp->selected) ps_set_color(ss->selected_data_color); else ps_set_color(ss->data_color); } #endif #endif } /* the rest are in real coordinates except upsidedown from PS point of view */ void ps_draw_line(axis_info *ap, int x0, int y0, int x1, int y1) { int py0, py1, px0, px1; px0 = x0 + bx0; px1 = x1 + bx0; py0 = reflect_y(ap, y0) + by0; py1 = reflect_y(ap, y1) + by0; if (px0 > bbx) bbx = px0; if (px1 > bbx) bbx = px1; if (py0 > bby) bby = py0; if (py1 > bby) bby = py1; snprintf(pbuf, PRINT_BUFFER_SIZE, " 0 setlinewidth %d %d moveto %d %d lineto stroke\n", px0, py0, px1, py1); ps_write(pbuf); } void ps_draw_spectro_line(axis_info *ap, int color, mus_float_t x0, mus_float_t y0, mus_float_t x1, mus_float_t y1) { /* these are in local coords */ rgb_t r, g, b; if (last_color != color) { get_current_color(color_map(ss), color, &r, &g, &b); last_color = color; snprintf(pbuf, PRINT_BUFFER_SIZE, " %.2f %.2f %.2f RG\n", rgb_to_float(r), rgb_to_float(g), rgb_to_float(b)); ps_write(pbuf); } ps_draw_line(ap, (int)x0, (int)y0, (int)x1, (int)y1); } void ps_fill_rectangle(axis_info *ap, int x0, int y0, int width, int height) { int py0, py1, px0, px1; px0 = x0 + bx0; px1 = x0 + bx0 + width; py0 = reflect_y(ap, y0) + by0; py1 = reflect_y(ap, y0 + height) + by0; if (px0 > bbx) bbx = px0; if (px1 > bbx) bbx = px1; if (py0 > bby) bby = py0; if (py1 > bby) bby = py1; snprintf(pbuf, PRINT_BUFFER_SIZE, " %d %d %d %d RF\n", px0, py0, width, -height); ps_write(pbuf); } void ps_draw_string(axis_info *ap, int x0, int y0, const char *str) { int px0, py0; px0 = x0 + bx0; py0 = reflect_y(ap, y0) + by0; #if USE_GTK py0 -= 12; #endif if (px0 > bbx) bbx = px0; if (py0 > bby) bby = py0; snprintf(pbuf, PRINT_BUFFER_SIZE, " %d %d moveto (%s) show\n", px0, py0, str); ps_write(pbuf); } void ps_set_number_font(void) { snprintf(pbuf, PRINT_BUFFER_SIZE, " /Courier findfont 15 scalefont setfont\n"); ps_write(pbuf); } void ps_set_label_font(void) { snprintf(pbuf, PRINT_BUFFER_SIZE, " /Times-Roman findfont 20 scalefont setfont\n"); ps_write(pbuf); } void ps_set_bold_peak_numbers_font(void) { snprintf(pbuf, PRINT_BUFFER_SIZE, " /Times-Bold findfont 14 scalefont setfont\n"); ps_write(pbuf); } void ps_set_peak_numbers_font(void) { snprintf(pbuf, PRINT_BUFFER_SIZE, " /Times-Roman findfont 14 scalefont setfont\n"); ps_write(pbuf); } void ps_set_tiny_numbers_font(void) { snprintf(pbuf, PRINT_BUFFER_SIZE, " /Times-Roman findfont 12 scalefont setfont\n"); ps_write(pbuf); } #define PRINTED_VERTICAL_SPACING 25 static char *snd_print_or_error(const char *output) { if ((output) && (*output)) { int j, i, err; int *offsets = NULL; sync_info *si; chan_info *ccp; char *errstr = NULL; ccp = current_channel(); if (ccp == NULL) return(mus_strdup("nothing to print?")); si = sync_to_chan(ccp); offsets = (int *)calloc(si->chans, sizeof(int)); for (j = 0, i = (si->chans - 1); i >= 0; i--) { offsets[i] = j; j += ((((axis_info *)((si->cps[i])->axis))->height) + PRINTED_VERTICAL_SPACING); } if (si->chans > 1) for (i = 0; i < si->chans; ) { snd_info *sp; sp = (si->cps[i])->sound; if (sp == NULL) break; if (sp->channel_style == CHANNELS_COMBINED) for (j = i + 1; (j < i + sp->nchans) && (j < si->chans); j++) offsets[j] = offsets[i]; else if (sp->channel_style == CHANNELS_SUPERIMPOSED) for (j = i; (j < i + sp->nchans - 1) && (j < si->chans); j++) offsets[j] = offsets[i + sp->nchans - 1]; i += sp->nchans; } err = start_ps_graph(output, ((si->cps[0])->sound)->filename); if (err == 0) { for (i = 0; i < si->chans; i++) ps_graph(si->cps[i], 0, offsets[i]); end_ps_graph(); } else errstr = mus_format("print %s failed: %s", output, snd_io_strerror()); si = free_sync_info(si); if (offsets) free(offsets); return(errstr); } else return(mus_strdup("print sound: eps file name needed")); } bool snd_print(const char *output) { char *error; error = snd_print_or_error(output); if (error) { snd_error_without_format(error); free(error); return(false); } return(true); } void print_enved(const char *output, int y0) { if ((output) && (*output)) { int err; err = start_ps_graph(output, "Envelope Editor"); if (err == 0) { bx0 = 0; by0 = y0; env_redisplay_with_print(); end_ps_graph(); } else snd_error("print env %s failed: %s", output, snd_io_strerror()); } else snd_error_without_format("print envelope: eps file name needed"); } static Xen g_graph_to_ps(Xen filename) { #define H_graph_to_ps "(" S_graph_to_ps " :optional (filename eps-file)): write the current Snd displays to an EPS file" char *error; const char *file; Xen_check_type(Xen_is_string_or_unbound(filename), filename, 1, S_graph_to_ps, "a string (filename)"); if (Xen_is_string(filename)) file = Xen_string_to_C_string(filename); else file = eps_file(ss); error = snd_print_or_error(file); if (error) { Xen result; result = C_string_to_Xen_string(error); free(error); Xen_error(Xen_make_error_type("cannot-print"), Xen_list_3(C_string_to_Xen_string(S_graph_to_ps ": can't print ~S (~A)"), C_string_to_Xen_string(file), result)); } return(C_string_to_Xen_string(file)); } /* ---------------- gl -> ps ---------------- */ #if HAVE_GL && WITH_GL2PS #include "gl2ps.h" #define NUM_GL2PS_TYPES 6 static int gl2ps_types[NUM_GL2PS_TYPES] = {GL2PS_EPS, GL2PS_PS, GL2PS_PDF, GL2PS_TEX, GL2PS_SVG, GL2PS_PGF}; static Xen g_gl_graph_to_ps(Xen filename, Xen output_type, Xen snd, Xen chn) { #define H_gl_graph_to_ps "(" S_gl_graph_to_ps " :optional filename (type 0) snd chn) produces a postscript output file from \ OpenGL graphics. type can be 0: eps, 1: ps, 2: pdf, 3: tex, 4: svg, 5: pgf." const char *file; FILE *fp; chan_info *cp; int state = GL2PS_OVERFLOW, buffsize = 1024 * 1024, type = 0; Xen_check_type(Xen_is_string_or_unbound(filename), filename, 1, S_gl_graph_to_ps, "a string (filename)"); Xen_check_type(Xen_is_integer_or_unbound(output_type), output_type, 2, S_gl_graph_to_ps, "an integer, 0=eps"); Snd_assert_channel(S_gl_graph_to_ps, snd, chn, 3); cp = get_cp(snd, chn, S_gl_graph_to_ps); if (!cp) return(Xen_false); if (Xen_is_string(filename)) file = Xen_string_to_C_string(filename); else file = eps_file(ss); if (Xen_is_integer(output_type)) type = Xen_integer_to_C_int(output_type); if ((type < 0) || (type >= NUM_GL2PS_TYPES)) Xen_out_of_range_error(S_gl_graph_to_ps, 2, output_type, "must be between 0 and 5"); fp = fopen(file, "wb"); while (state == GL2PS_OVERFLOW) { GLint err; buffsize += 1024 * 1024; err = gl2psBeginPage(cp->sound->short_filename, "Snd", NULL, gl2ps_types[type], GL2PS_BSP_SORT, GL2PS_DRAW_BACKGROUND | GL2PS_USE_CURRENT_VIEWPORT | GL2PS_OCCLUSION_CULL, /* perhaps also GL2PS_NO_BLENDING */ GL_RGBA, 0, NULL, 0, 0, 0, buffsize, fp, file); if (err != GL2PS_SUCCESS) { /* if an error occurs, gl2ps itself insists on printing something -- this needs to be fixed! */ state = (int)err; } else { ss->gl_printing = true; display_channel_fft_data(cp); ss->gl_printing = false; state = gl2psEndPage(); } } fclose(fp); return(C_string_to_Xen_string(file)); } char *gl2ps_version(void); char *gl2ps_version(void) { char *buf; buf = (char *)calloc(128, sizeof(char)); snprintf(buf, 128, "gl2ps %d.%d.%d", GL2PS_MAJOR_VERSION, GL2PS_MINOR_VERSION, GL2PS_PATCH_VERSION); return(buf); } void gl2ps_text(const char *msg); void gl2ps_text(const char *msg) { gl2psText(msg, "Times-Roman", 20); } #else static Xen g_gl_graph_to_ps(Xen filename, Xen output_type, Xen snd_ignore, Xen chn_ignore) { #define H_gl_graph_to_ps "gl-graph->ps is a no-op in this version of Snd" Xen_check_type(Xen_is_string_or_unbound(filename), filename, 1, S_gl_graph_to_ps, "a string (filename)"); Xen_check_type(Xen_is_integer_or_unbound(output_type), output_type, 2, S_gl_graph_to_ps, "an integer, 0=eps"); return(Xen_false); } #endif /* -------------------------------- */ static Xen g_eps_file(void) {return(C_string_to_Xen_string(eps_file(ss)));} static Xen g_set_eps_file(Xen val) { #define H_eps_file "(" S_eps_file "): File:Print and " S_graph_to_ps " file name (snd.eps)" Xen_check_type(Xen_is_string(val), val, 1, S_set S_eps_file, "a string"); if (eps_file(ss)) free(eps_file(ss)); set_eps_file(mus_strdup(Xen_string_to_C_string(val))); return(C_string_to_Xen_string(eps_file(ss))); } #define MAX_EPS_MARGIN 1000.0 static Xen g_eps_left_margin(void) {return(C_double_to_Xen_real(eps_left_margin(ss)));} static Xen g_set_eps_left_margin(Xen val) { #define H_eps_left_margin "(" S_eps_left_margin "): File:Print and " S_graph_to_ps " left margin" Xen_check_type(Xen_is_number(val), val, 1, S_set S_eps_left_margin, "a number"); set_eps_left_margin(mus_fclamp(0.0, Xen_real_to_C_double(val), MAX_EPS_MARGIN)); return(C_double_to_Xen_real(eps_left_margin(ss))); } static Xen g_eps_bottom_margin(void) {return(C_double_to_Xen_real(eps_bottom_margin(ss)));} static Xen g_set_eps_bottom_margin(Xen val) { #define H_eps_bottom_margin "(" S_eps_bottom_margin "): File:Print and " S_graph_to_ps " bottom margin" Xen_check_type(Xen_is_number(val), val, 1, S_set S_eps_bottom_margin, "a number"); set_eps_bottom_margin(mus_fclamp(0.0, Xen_real_to_C_double(val), MAX_EPS_MARGIN)); return(C_double_to_Xen_real(eps_bottom_margin(ss))); } static Xen g_eps_size(void) {return(C_double_to_Xen_real(eps_size(ss)));} static Xen g_set_eps_size(Xen val) { #define MAX_EPS_SIZE 1000.0 #define H_eps_size "(" S_eps_size "): File:Print and " S_graph_to_ps " output size scaler (1.0)" Xen_check_type(Xen_is_number(val), val, 1, S_set S_eps_size, "a number"); set_eps_size(mus_fclamp(0.0, Xen_real_to_C_double(val), MAX_EPS_SIZE)); return(C_double_to_Xen_real(eps_size(ss))); } Xen_wrap_1_optional_arg(g_graph_to_ps_w, g_graph_to_ps) Xen_wrap_4_optional_args(g_gl_graph_to_ps_w, g_gl_graph_to_ps) Xen_wrap_no_args(g_eps_file_w, g_eps_file) Xen_wrap_1_arg(g_set_eps_file_w, g_set_eps_file) Xen_wrap_no_args(g_eps_left_margin_w, g_eps_left_margin) Xen_wrap_1_arg(g_set_eps_left_margin_w, g_set_eps_left_margin) Xen_wrap_no_args(g_eps_size_w, g_eps_size) Xen_wrap_1_arg(g_set_eps_size_w, g_set_eps_size) Xen_wrap_no_args(g_eps_bottom_margin_w, g_eps_bottom_margin) Xen_wrap_1_arg(g_set_eps_bottom_margin_w, g_set_eps_bottom_margin) #if HAVE_SCHEME static s7_pointer acc_eps_bottom_margin(s7_scheme *sc, s7_pointer args) {return(g_set_eps_bottom_margin(s7_cadr(args)));} static s7_pointer acc_eps_file(s7_scheme *sc, s7_pointer args) {return(g_set_eps_file(s7_cadr(args)));} static s7_pointer acc_eps_left_margin(s7_scheme *sc, s7_pointer args) {return(g_set_eps_left_margin(s7_cadr(args)));} static s7_pointer acc_eps_size(s7_scheme *sc, s7_pointer args) {return(g_set_eps_size(s7_cadr(args)));} #endif void g_init_print(void) { Xen_define_procedure(S_graph_to_ps, g_graph_to_ps_w, 0, 1, 0, H_graph_to_ps); Xen_define_procedure(S_gl_graph_to_ps, g_gl_graph_to_ps_w, 0, 4, 0, H_gl_graph_to_ps); Xen_define_dilambda(S_eps_file, g_eps_file_w, H_eps_file, S_set S_eps_file, g_set_eps_file_w, 0, 0, 1, 0); Xen_define_dilambda(S_eps_left_margin, g_eps_left_margin_w, H_eps_left_margin, S_set S_eps_left_margin, g_set_eps_left_margin_w, 0, 0, 1, 0); Xen_define_dilambda(S_eps_bottom_margin, g_eps_bottom_margin_w, H_eps_bottom_margin, S_set S_eps_bottom_margin, g_set_eps_bottom_margin_w, 0, 0, 1, 0); Xen_define_dilambda(S_eps_size, g_eps_size_w, H_eps_size, S_set S_eps_size, g_set_eps_size_w, 0, 0, 1, 0); #if HAVE_GL && WITH_GL2PS Xen_provide_feature("gl2ps"); #endif #if HAVE_SCHEME s7_symbol_set_access(s7, ss->eps_bottom_margin_symbol, s7_make_function(s7, "[acc-" S_eps_bottom_margin "]", acc_eps_bottom_margin, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->eps_file_symbol, s7_make_function(s7, "[acc-" S_eps_file "]", acc_eps_file, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->eps_left_margin_symbol, s7_make_function(s7, "[acc-" S_eps_left_margin "]", acc_eps_left_margin, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->eps_size_symbol, s7_make_function(s7, "[acc-" S_eps_size "]", acc_eps_size, 2, 0, false, "accessor")); s7_symbol_set_documentation(s7, ss->eps_bottom_margin_symbol, "*eps-bottom-margin*: File:Print and graph->ps bottom margin"); s7_symbol_set_documentation(s7, ss->eps_file_symbol, "*eps-file*: File:Print and graph->ps file name (snd.eps)"); s7_symbol_set_documentation(s7, ss->eps_left_margin_symbol, "*eps-left-margin*: File:Print and graph->ps left margin"); s7_symbol_set_documentation(s7, ss->eps_size_symbol, "*eps-size*: File:Print and graph->ps output size scaler (1.0)"); #endif } snd-16.1/extsnd.html0000644000076400007640000173257112622731715012554 0ustar bilbil Snd Customization and Extension
Snd Customization and Extension
this file:grfsnd.html:
setting switches
Introduction

Snd is a highly customizable, extensible program. I've tried to bring out to the extension language nearly every portion of Snd, both the signal-processing functions and much of the user interface. You can, for example, add your own menu choices, editing operations, or graphing alternatives. Nearly everything in Snd can be set in an initialization file, loaded at any time from a text file of program code, or specified in a saved state file. It can also be set via inter-process communication or from stdin from any other program (CLM and Emacs in particular), embedded in a keyboard macro, or typed in the listener.

The syntax used throughout this documentation is Scheme (a form of lisp) as implemented by s7. You can also use Ruby or Forth, but need to make various minor changes. I'm slowly adding parallel Forth and Ruby examples.

The easiest way to get acquainted with this aspect of Snd is to open the listener (via the View:Open listener menu option), and type experiments in its window. Its prompt is ">". So, say we've opened the listener.

SchemeRubyForth
> (+ 1 2)
3
>1+2
3
>1 2 +
3
> (open-sound "oboe.snd")
#<sound 0>
>open_sound("oboe.snd")
0
>"oboe.snd" open-sound
0
> (auto-resize)
#t
>auto_resize
true
>auto-resize
#t
> (set! (auto-resize) #f)
#f
>set_auto_resize false
false
>#f set-auto-resize
#f
> (set! (x-bounds) '(0.0 1.0))
(0.0 1.0)
>set_x_bounds([0.0, 1.0])
0.01.0
>'( 0.0 1.0 ) set-x-bounds
'( 0.0 1.0 )
> (load "bird.scm")
make-birds
>load "bird.rb"
true
>"bird.fs" file-eval
0
> (map-channel (lambda (y) (* y 2)))
0
>map_channel(lambda do |y| y * 2 end)
-0.0015869140625
>lambda: <{ y }> y 2.0 f* ; map-channel
-0.00158691
> (define (plus a b) (+ a b))
plus
>def plus(a, b) a+b end

>: plus ( a b -- sum ) { a b } a b + ;
nil
> (set! (basic-color) (make-color 1 0 0))
(Pixel 16711680)
>set_basic_color make_color(1, 0, 0)
[:Pixel, 16711680]
>1 0 0 make-color set-basic-color
#<XmRaw: Pixel 0x9d3b430>

Another quick way to check out the extension language is to go to the Preferences dialog (in the Options menu), choose some items, then save them. The saved file (~/.snd_prefs_s7 for example) is a text file, a program in the current extension language, that initializes Snd to use whatever items you chose.

Snd Programming

Snd is organized as a list of sounds, each with a list of channels, each channel containing lists of edits, marks, mixes, etc. There are other objects such as colors, and regions; the currently active region is called the selection. I originally presented all the functions and variables in an enormous alphabetical list, but that finally became unmanageable. In the following sections, each of the basic entities is treated in a separate section with cross-references where needed. The index provides alphabetical entry.

There are many examples in examp.scm, examp.rb, examp.fs, and snd-test.scm. Extensions to Snd can be found in:

analog-filter standard IIR filters
animals a bunch of animals
autosave auto-save (edit backup) support
bess FM demo
binary-io binary files
bird North-American birds
clean noise reduction
clm-ins, clm23 various CLM instruments
dlocsig moving sounds (Michael Scholz)
draw graphics additions
dsp various DSP-related procedures
env envelope functions
enved envelope editor
examp many examples
extensions various generally useful Snd extensions
fade frequency-domain cross-fades
freeverb a reverb
generators a bunch of generators
grani CLM's grani (Fernando Lopez-Lezcano and Mike Scholz)
heart use Snd with non-sound (arbitrary range) data
hooks functions related to hooks
index snd-help extension
inf-snd.el, DotEmacs Emacs subjob support (Michael Scholz, Fernando Lopez-Lezcano)
jcrev John Chowning's ancient reverb
lint a lint program for scheme
maraca Perry Cook's maraca physical model
marks functions related to marks
maxf Max Mathews resonator
menus additional menus
mix functions related to mixes
moog Moog filter
musglyphs Music notation symbols (from CMN)
nb Popup File info etc
noise noise maker
numerics various numerical functions
peak-phases phases for the unpulse-train
piano piano physical model
play play-related functions
poly polynomial-related stuff
prc95 Perry Cook's physical model examples
pvoc phase-vocoder
rgb color names
rubber rubber-sound
selection functions acting on the current selection
singer Perry Cook's vocal-tract physical model
snd13|14|15.scm Backwards compatibility
snddiff sound difference detection
snd-gl OpenGL examples (gl.c)
snd-motif, snd-gtk, snd-xm Motif/Gtk module (xm.c, xg.c)
snd-test Snd regression tests
sndwarp Bret Battey's sndwarp instrument
spectr instrument steady state spectra
stochastic Bill Sack's dynamic stochastic synthesis
strad string physical model (from CLM)
v fm-violin
ws with-sound
zip the zipper (the anti-cross-fader)
Customizing Snd's behavior

Most of Snd's behavior can be customized. For example, when a sound is saved, some people want to be warned if a pre-existing sound is about to be destroyed; others (Snd's author included) grumble "just do it". There are two ways this kind of situation is handled in Snd; through global variables and hooks. A hook is a list of callbacks invoked whenever its associated event happens. When Snd exits, for example, any functions found on the before-exit-hook list are evaluated; if any of them returns #t, Snd does not exit.

(define (unsaved-edits? lst)
  (and (pair? lst)
       (if (> (car (edits (car lst))) 0)
	   (begin
	     (status-report "there are unsaved edits")
	     #t)
	   (unsaved-edits? (cdr lst)))))

(hook-push before-exit-hook 
  (lambda (hook) 
    (set! (hook 'result) (unsaved-edits? (sounds)))))

Now when Snd is told to exit, it checks before-exit-hook, runs unsaved-edits?, and if the latter returns #t, if prints a worried message in the status area, and refuses to exit. Similar hooks customize actions such as closing a sound (close-hook), clicking a mark (mark-click-hook), pressing a key (key-press-hook), and so on.

Global variables

The global variables handle various customizations that aren't callback-oriented. For example, as sounds come and go, Snd's overall size may change (this is partly determined by the window manager, but is also up to Snd). Many people find this distracting — they would rather that the overall window stick to one size. The Snd variable associated with this is "auto-resize"; it can be accessed as:

  Scheme: *auto-resize* or (auto-resize)
  Ruby:   auto_resize()
  Forth:  auto-resize

and set via:

  Scheme: (set! *auto-resize* #f) or (set! (auto-resize) #f)
  Ruby:   set_auto_resize(false)
  Forth:  #f set-auto-resize

I originally wanted a variable like auto-resize to look like a variable in source files, but in those bygone days (1996), that was not possible: I had to use a dumb "procedure-with-setter" instead. So you'd sigh and access auto-resize by calling it as a function: (set! (auto-resize) #t). Now in s7, the same thing is also named *auto-resize*, but it's finally a variable, so you can use (set! *auto-resize* #t). The documentation of course is out of date, and mostly uses the old form. In any case, the statement (set! *auto-resize* #f) can be placed in your ~/.snd initialization file to make it the default setting for your version of Snd, or placed in a separate file of Scheme code and loaded at any time via the load function.

The functions affecting Snd's overall behavior are given below; in s7 there is also the variable of the same name, but with "*" around it: *auto-resize*.

ask-about-unsaved-edits (default: #f)

If ask-about-unsaved-edits is #t, Snd worries about unsaved edits when a sound is about to be closed. Otherwise Snd just closes the sound, flushing any unsaved edits. (set! (ask-about-unsaved-edits) #t)

ask-before-overwrite (default: #f)

ask-before-overwrite determines whether Snd asks before overwriting an existing file: (set! (ask-before-overwrite) #t)

auto-resize (default: #t in Motif, #f in Gtk)

auto-resize determines whether the Snd window should be resized when a sound is opened or closed.

auto-update (default: #f)

auto-update determines whether Snd should update a file automatically if it (the file) changes on disk due to some other process. If Snd's view of a sound doesn't match the on-disk version of the sound, a warning is posted that there are two conflicting versions of the sound.

auto-update-interval (default: 60)

This is the time (in seconds) between background checks for a changed file on disk (see auto-update). If auto-update-interval is 0.0, the auto-update background process is turned off.

clipping (default: #f)

If clipping is #t, output values are clipped to fit the current sndlib sample representation's notion of -1.0 to just less than 1.0. The default (#f) can cause wrap-around (if writing integer sound data) which makes the out-of-range values very obvious. To control this action more closely, use clip-hook. To get completely confused, see mus-clipping and mus-file-clipping: this has become as messed up as the sampling rate settings!

cursor-location-offset (default: 0.05)

cursor-location-offset is the offset in samples between Snd's notion of the location of the tracking cursor (with-tracking-cursor in Snd jargon) and the actual (DAC-relative) location. Since, in general, Snd can't tell how many samples of buffering there are between itself and the speakers (audio cards have varying amounts), its notion of where to place the tracking cursor can be wrong by an almost arbitrary amount. If you have some idea of the buffering amount, you can correct this error via cursor-location-offset.

cursor-update-interval (default: 0.05)

This is the time in seconds between cursor redisplays if playing a sound with with-tracking-cursor #t. If this number is too small, you may clicks during playback.

dac-combines-channels (default: #t)

If dac-combines-channels is #t, and the current sound has more channels than are supported by the available audio hardware, Snd mixes the extra channels into the available channels during audio output. This provides a way to hear 4-channel sounds when you only have a stereo audio card. If dac-combines-channels is #f, extra channels are not played.

dac-size (default: 256)

dac-size is the audio output buffer size; it is not always meaningful. See play-with-envs in enved.scm. When you change the control panel settings during playback, the snappiness of the response is set, to some extent, by the dac-size. The default of 256 gives a stair-case effect in many cases, whereas 2048 is smoother. This also affects the resampling smoothness of playback while dragging the mark play triangle. Some audio choices, ALSA in particular, may ignore dac-size.

default-output-chans (default: 1)

default-output-chans is the default number of channels when a new or temporary file is created, or a save dialog is opened.

default-output-header-type (default: mus-next)

This is the default header type when a new file is created, or a save dialog is opened. (The default, mus-next, stands for the NeXT/Sun sound file header). The available output header-types are:

    mus-next mus-aifc mus-riff mus-rf64 mus-nist mus-raw mus-ircam mus-aiff 
    mus-soundfont mus-bicsf mus-voc mus-svx mus-caff
default-output-sample-type (default: mus-bfloat)

default-output-sample-type is the default sample type when a new or temporary file is created, or a save dialog is opened. (The default, mus-bfloat, is from sndlib, standing for 32-bit big-endian floating point data). Use mus-out-format for fastest IO. The available output sample types are (b=big-endian, l=little, u=unsigned, short=16 bits, byte=8 bits, int = 32 bits):

    mus-bshort  mus-lshort mus-mulaw  mus-alaw   mus-byte   mus-ubyte   mus-bfloat
    mus-lfloat  mus-bint   mus-lint   mus-b24int mus-l24int mus-bdouble mus-ldouble
    mus-ubshort mus-ulshort

There are also "unscaled" versions of the floating point types, and "normalized" versions of the integers.

default-output-srate (default: 44100)

This is the default sampling rate when a new or temporary file is created, or a save dialog is opened. It also sets the default CLM srate (*clm-srate* in ws.scm), so all CLM generators use it outside with-sound.

eps-bottom-margin (default: 0.0)

eps-bottom-margin is the bottom margin used in snd.eps, created by the File:Print dialog, or the graph->ps function. PostScript units are 1/72 of an inch (a "point" in printer jargon); an inch is 2.54 cm:

Scheme:

(define (inches-to-ps inches) 
  (* inches 72))

(define (cm-to-ps cm) 
  (* cm (/ 72.0 2.54)))
Ruby:
def inches_to_ps(inches) 
  inches * 72 
end
def cm_to_ps(cm) 
  cm * 72.0 / 2.54 
end
Forth:
: inches-to-ps { inches } 
  inches 72 f* 
;
: cm-to-ps { cm } 
  cm 2.54 f/ 72 f* 
;

In the resulting .eps file, you'll find a concat statement near the top of the file; the first and fourth numbers are scale factors on the entire graph, the fifth is the left margin, and the sixth is the bottom margin.

eps-file (default: "snd.eps")

This is the default name of the Postscript file produced by the File:Print dialog, or the graph->ps function.

eps-left-margin (default: 0.0)

eps-left-margin is the left margin used in snd.eps, created by the File:Print dialog, or the graph->ps function.

eps-size (default: 1.0)

eps-size is the scaler used to set the overall picture size in snd.eps, created by the File:Print dialog, or the graph->ps function,

graph-cursor (default: XC_crosshair (34))

graph-cursor is the kind of cursor displayed following the mouse in the data graph. It can be any of the cursors provided by X or Gtk+: (set! (graph-cursor) 22). The X/Motif cursors are declared in /usr/include/X11/cursorfont.h or some such file; gtk versions are in gdkcursor.h. Some useful choices are:

    Motif              Gtk+             value

XC_center_ptr      GDK_CENTER_PTR        22
XC_cross           GDK_CROSS             30
XC_crosshair       GDK_CROSSHAIR         34
XC_left_ptr        GDK_LEFT_PTR          68
XC_plus            GDK_PLUS              90
XC_right_ptr       GDK_RIGHT_PTR         94
XC_tcross          GDK_TCROSS           130
XC_xterm           GDK_XTERM            152
html-dir (default: ".")

html-dir is the directory to search for documentation if an HTML reader is in use. See the function html in index.scm.

html-program (default: "firefox")

This is the program to use to read HTML files. On the Mac, you need to give the full path to the executable image: "/Applications/Safari.app/Contents/MacOS/Safari". See the function html in index.scm.

initial-beg (default: 0.0)

initial-beg is the start point (in seconds) of the initial graph of a sound.

initial-dur (default: 0.1)

initial-dur is the duration (in seconds) of the initial graph of a sound.

just-sounds (default: #t)

If just-sounds is #t, the file lists displayed by the file selection dialogs are filtered to show just sound files (see add-sound-file-extension).

ladspa-dir (default: #f)

LADSPA is a way of managing plug-ins in Linux. I consider it very old-fashioned, but there are a bunch of ladspa libraries, and they're easy to load. so... ladspa-dir is the name of the directory to search for LADSPA plugin libraries (it can override or replace LADSPA_PATH). See Snd and LADSPA.

log-freq-start (default: 32.0)

log-freq-start is the start (lowest) frequency used in the log freq display (ffts). Since the log display emphasizes the lower frequencies, but the lowest are all inaudible, it seemed more informative to squash the lowest 30Hz or so into a single point (0 Hz) on the log freq graphs; otherwise the audible data starts about 1/4 of the way down the x axis, wasting valuable screen space! But it also seemed a bother to have to set/reset the spectrum-start variable every time you wanted to flip between log and linear displays. log-freq-start to the rescue? For other ideas along these lines, see display-bark-fft.

max-regions (default: 16)

This sets the maximum size of the region list, the number of regions that are accessible.

mus-max-malloc (default: 67108864)

This sets the maximum memory allocation (in bytes). In s7, you can use the variable *mus-max-malloc* instead.

mus-max-table-size (default: 20971520)

This sets the maximum table size (delay line length in samples, etc). In s7, you can use the variable *mus-max-table-size* instead.

mus-sound-path (default: ())

This is the list of directories searched for an incompletely specified sound file. The current directory is always searched first.

open-file-dialog-directory (default: ".")

open-file-dialog-directory is the name of the initial open file dialog directory (normally ".").

peak-env-dir (default: #f)

peak-env-dir is the directory to use for peak env files; if it is #f (the default), the peak-env machinery is turned off. If the peak-env-dir is writable, Snd saves an overview of the sound data in that directory to speed up the initial graph display the next time you open that sound.

play-arrow-size (default: 10)

This is the size of the triangular arrow that handles click-to-play duties for the cursor, marks, mixes, and the selection.

print-length (default: 12)

For objects such as float-vectors, print-length sets the number of elements printed. In s7, this also sets (*s7* 'print-length).

> (set! (print-length) 3)
3
> (make-float-vector 10 .1)
#(0.1 0.1 0.1 ...)
remember-sound-state (default: #f)

If remember-sound-state is #t, Snd saves most of a sound's display state when it is closed, and if that same sound is later re-opened, restores the previous state.

save-dir (default: #f)

save-dir is the name of the directory for saved-state files. These files are written when you call save-state or choose the Options:Save session menu item. If any of the current sounds has an edit that requires saved data, it is written as a separate sound file, and that file is reloaded automatically when you restart the saved session. To keep such files safe, or at least separate from others, you can set up separate directory for them.

save-state-file (default: "saved-snd.scm")

This is the saved state file name.

search-procedure

This is the search procedure used by the find dialog or C-s if none is otherwise specified.

(set! (search-procedure) (lambda (y) (> y .1)))
selection-creates-region (default: #t)

If selection-creates-region is #t, a region is created whenever a selection is made. If you're editing very large sounds and using selections, the region temp files can use up a lot of disk space (and the time to write them); if you're not using regions anyway, this switch can turn them off.

show-full-duration (default: #f)

If show-full-duration is #t, Snd displays the entire sound when it is first opened.

show-full-range (default: #f)

If show-full-range is #t, Snd makes sure the sound's graph y bounds can accommodate the entire range of sample values. This is especially useful when you're working with sounds that go beyond the normal -1.0 to 1.0 range.

show-indices (default: #f)

If show-indices is #t, each sound's name is preceded by its index in the sound pane.

show-selection-transform (default: #f)

If show-selection-transform is #t, Snd displays the transform of the current active selection, if any. The sonogram and spectrogram displays ignore this flag because they assume their time axis matches that of the time domain graph.

sinc-width (default: 10)

sinc-width is the width in samples of the sampling rate conversion sinc interpolation. The higher this number, the better the src low-pass filter, but the slower src runs. If you use too low a setting, you can sometimes hear high frequency whistles leaking through. To hear these on purpose, make a sine wave at (say) 55 Hz, then (src-sound '(0 3 1 1)) with sinc-width at 4.

sync-style (default: sync-by-sound)

sync-style determines how sounds and their channels are sync'd together when they are opened. sync-none means that no sounds, and no channels are tied together; sync-all causes everything to be tied together; sync-by-sound, the default, causes individual sounds to be separate, but if they have more than one channel, all the channels are tied together.

temp-dir (default: #f)

temp-dir is the directory to use for temporary files; if it is #f, Snd uses whatever the system default is, usually "/tmp" or "/var/tmp". See also snd-tempnam.

window-height (default: 0)

window-height is the current Snd window height in pixels. This is the same as

Scheme: (cadr (widget-size (cadr (main-widgets))))
Ruby:   widget_size(main_widgets.cadr).cadr
Forth:  main-widgets cadr widget-size cadr

except at startup when the window-height function and friends defer the assignment until after the main widgets have been created. If Snd becomes confused about screen size, it can make its main window so large that you can't get at any of the decorations for resizing the window; in this emergency you can (set! (window-height) 300) or some such number.

window-width (default: 0)

This is the current Snd window width in pixels.

window-x (default: -1)

This is the current Snd window left side position in pixels (-1 means unset). This is (usually) the same as (car (widget-position (cadr (main-widgets)))).

window-y (default: -1)

This is the current Snd window upper side position in pixels (X numbering starts at 0 at the top, -1 means unset).

with-background-processes (default: #t)

with-background-processes determines whether Snd should use background (idle time) processes for ffts and so forth. It is intended primarily for auto-testing.

with-file-monitor (default: #t)

If with-file-monitor is #t, the file alteration monitor is active. There are still bugs in this library that can cause Snd to hang — I haven't tracked down what the problem is yet; in the meantime, set this switch to #f to disable the monitor.

with-inset-graph (default: #f)

If with-inset-graph is #t, a small graph is added to the upper right corner showing the overall current sound and where the current window fits in it. This information is implicit in the x axis zoom and position sliders, but a redundant graph doesn't hurt. If you click in that graph, the cursor is moved to the clicked point.

with-inset-graph
with-interrupts (default: #t)

If with-interrupts is true, the Snd listener (in Gtk/Motif) adds a check for GUI activity to each computation called from the listener. This makes it possible to stop an infinite loop, or use the user interface while some long computation is running, but it also slows down that computation. To get the maximum performance, set this flag to false (#f).

with-menu-icons (default: #t)

with-menu-icons determines whether some menus display icons beside the item labels (in Gtk only). This sets both gtk-menu-images and gtk-button-images. There are a lot of these default settings in gtk (see GtkSettings.html). To set one from Scheme:

(with-let *gtk* (g_object_set (GPOINTER (gtk_settings_get_default)) "gtk-menu-images" #t))

To get the current value of one of these settings, you need to tell xg the expected return type. In the next example, we assume we're getting an integer:

> (with-let *gtk* (g_object_get (GPOINTER (gtk_settings_get_default)) "gtk-cursor-blink-time" #f))
1200
with-pointer-focus (default: #f)

If with-pointer-focus is #t, whatever text or graph widget is underneath the mouse cursor is activated (this is sometimes known as "point-to-focus" mode).

with-relative-panes (default: #t)

If with-relative-panes is #t in the Motif version of Snd, a multichannel sound tries to retain the relative channel graph sizes when the outer sash (the overall sound size sash) changes. Mono sounds and the listener are not affected (perhaps they should be?).

with-smpte-label (default: #f)

with-smpte-label shows the current SMPTE frame number in a box in the upper left corner of the graph (see the picture above under add-mark-pane).

with-toolbar (default: #t (gtk), #f (motif))

with-toolbar places a toolbar at the top of the Snd window, just under the main menu.

with-toolbar picture
with-tooltips (default: #t)

Set with-tooltips to #f to turn off tooltips.

with-tracking-cursor (default: #f)

This is #t if the cursor always follows along in the sound during playback. If it is #f, you get the tracking cursor displayed only when you ask for it (via control-click of the play button, for example). At the end of the play, the default is to return to the original (starting) cursor position. If you want the cursor to stay where it is, set with-tracking-cursor to :track-and-stay (#t = :track-and-return).

The interval (in seconds) between cursor updates is set by cursor-update-interval which defaults to 0.05. The accuracy of the cursor in reflecting the sound coming out the speakers depends on the amount of buffering in your audio system. If Snd's displayed location is off, set cursor-location-offset to reflect the number of samples of buffering you think you probably have. A positive cursor-location-offset delays the cursor's apparent progress (if playing forwards).

tracking cursor
play from the current cursor position with a tracking cursor: pfc
display tracking cursor as a full height vertical line: tracking-cursor-style
track play once: control-click 'play'. (You can add a mark at the current tracking cursor location during the play with C-m)
leave the cursor at the final position after tracking play: (set! *with-tracking-cursor* :track-and-stay)
tracking cursor accuracy: cursor-location-offset
tracking cursor updating: cursor-update-interval
zoom-focus-style (default: zoom-focus-active)

This determines what a zoom action focuses (centers) on. The choices are zoom-focus-left, zoom-focus-right, zoom-focus-active, zoom-focus-middle, or a function of 6 arguments. The function should return the new window left edge as a float. Its arguments are the current sound, channel number, zoom slider value (0.0 to 1.0), time domain window left and right edges in seconds, and the current total x axis size (seconds) corresponding to a slider value of 1.0.

(set! (zoom-focus-style) (lambda (snd chn zx x0 x1 range) (- x1 (* zx range))))

mimics zoom-focus-right. zoom-focus-active tries to focus on some object in the view: the cursor, a mix or mark, etc. See also Zoom options.

Generic functions

Several functions in Snd are "generic" in the sense that they can handle a wide variety of objects. The length function, for example, applies to strings and vectors, as well as lists. Objects specific to Snd include sounds, the selection, mixes, marks, samplers, regions, and players, all of which should be compared with equal?, not eq?.

channels obj

channels handles strings (mus-sound-chans), region-chans, the current selection (selection-chans), mus-channels, mixes, vcts, and vectors (always 1 channel), and sounds (as objects or as integers).

copy obj

copy returns a copy of its argument. It works with strings, lists, vectors, hash tables, float-vectors, sounds, the current selection, mixes, marks, bignums, and the non-gmp random state objects.

file-name obj

filename can replace mus-expand-filename, mus-file-name, and (s7 scheme's) port-filename, as well as handling mixes, regions, samplers, and the regular sound-oriented file-name.

fill! obj val

fill! fills obj with val (s7 only). fill! works with strings, vectors, hash-tables, float-vectors, lists, sounds, and the selection.

framples obj chn edpos

framples returns the number of "framples" in an object, that is, the number of samples per channel (a frample is a set of samples, representing each channel's value at a given sampling instant, a "sample frame" or a "frame of samples" in old time terminology).

The framples function overlaps the length function, but length of a string is string-length, whereas framples of a string treats the string as a sound file name and returns mus-sound-framples. framples can replace mus-sound-framples, mus-length, mix-length, region-framples, selection-framples, and the regular framples function that handles sound objects and integers as sound indices.

length obj

length handles list length, string-length, vector-length, framples (sound length), colormap-size, mus-length (generators), mix-length, transform-size, selection-framples, and region-framples.

maxamp obj chn

maxamp can handle a sound (via the regular maxamp function), string (treated as a sound file name, mus-sound-maxamp), generator (maxamp of the mus-data vct, if any), float-vector, region (region-maxamp), the current selection (selection-maxamp), vector, list, or mix object.

play object :start :end :channel :edit-position :out-channel :with-sync :wait :stop :srate :channels

play plays an object. The object can be a string (sound filename), a sound object or index, a mix, a region, the selection object, #f, a procedure, or a player. Not all the keyword arguments apply in all cases, though I hope to fill in the table of possibilities eventually. The full documentation is currently under play.

srate obj

srate handles strings (treated as file names: mus-sound-srate), regions (region-srate), the selection (selection-srate), and sounds (as objects or as integers).

sync obj

sync accesses the 'sync' field of a sound, mark, or mix.

Hooks

When some user-interface action takes place, code is called that responds to that action; these functions are sometimes called callbacks; the variable that holds a list of such callbacks is known as a hook. For example, the hook that is checked when you click the sound's name in the status area is name-click-hook. We can cause that action to print "hi":

Scheme: (hook-push name-click-hook (lambda (hook) (snd-print "hi") (set! (hook 'result) #t)))
Ruby:   $name_click_hook.add_hook!("print") do |snd| snd_print("hi"); true end
Forth:  name-click-hook lambda: <{ snd }> "hi" snd-print drop #t ; add-hook!

The Scheme hook function is slightly different from the Forth and Ruby cases. For about 15 years, Snd used Guile-style hooks which are essentially a list of functions, each called with the hook arguments ('snd' above). But now Scheme hooks are functions that have three internal lists of functions. The internal functions (the things we add to hook-functions, for example) take the hook's internal environment as their only argument ('hook' above), and then access the actual hook arguments via (hook name). So, the examples are confusing because the situation is confused! To move between the versions, match the Forth/Ruby argument name to the Scheme hook variable, so the function argument 'snd in Forth/Ruby is (hook 'snd) in Scheme.

In Ruby and Forth, but not in Scheme, if there is more than one function attached to a hook, some of the hooks "or" the functions together; that is they run through the list of functions, and if any function returns something other than #f, the hook invocation eventually returns the last such non-#f value. A few hooks are "cascade" hooks; that is, each function gets the result of the previous function, and the final function's value is returned. In other cases the result returned by the hook is the result of the last function in the list. Whatever the hook combination choice, all the functions on the hook list are run on each invocation.

In Scheme, all functions are run, each takes one argument, the hook environment, and any return values are ignored. It is up to the individual functions to track (hook 'result) if intermediate results matter.

There are several basic actions that involve a bunch of hooks. Here is a schematic view of some of these sequences.

    Open filename
        bad header?: bad-header-hook — can cancel request
        no header?:  open-raw-sound-hook — can cancel request
        file ok: 
             open-hook — can change filename
             file opened (no data read yet)
                 during-open-hook (can set prescaling etc)
             data read, no graphics yet
             after-open-hook
             initial-graph-hook
    
    
    Save current sound
        before-save-as-hook — can cancel the request or set its output parameters
        save-hook
            sound saved
              if any sample is clipped during save, clip-hook
        after-save-as-hook


    Play sound
        when a play request occurs: start-playing-hook — can cancel the request, also start-playing-selection-hook
            (any number of sounds can be playing at once)
        as each sound ends: stop-playing-hook, stop-playing-selection-hook
    

    Close sound
        before-close-hook — can cancel close
        close-hook (sound is still open)
        sound closed
    
    
    Save current Snd ("session") state
        save-state-hook — can change output filename (crummy name is an historical artifact)
        output save-state file opened
            before-save-state-hook
            Snd saves its state
            after-save-state-hook
        output closed
    
    
    Exit Snd
        before-exit-hook — can cancel exit request
        exit-hook
        Snd cleans up and exits

Here's the Ruby version of some of the hook-related functions:

$var_hook.remove_hook!("proc_name")
$var_hook.reset_hook!
$var_hook.run_hook do |prc| prc.call(1, 2, 3) end
$var_hook.call(1, 2, 3)   # calls all procedures
    
require 'hooks'
$var_hook.show            # prints the code of the procedure(s)
$va_hook.to_a

And some Forth examples, taken from Mike Scholz's documentation:

open-hook ' open-buffer 1 make-proc add-hook!
open-hook "open-buffer" remove-hook!
open-hook reset-hook!
open-hook hook->list
    
2 "A simple hook." create-hook my-new-hook
my-new-hook ' + 2 make-proc add-hook!
my-new-hook '( 2 3 ) run-hook
help my-new-hook             

These hooks are extremely easy to add; if there's some user-interface action you'd like to specialize in some way, send me a note. hooks.scm has snd-hooks and reset-all-hooks, as well as other useful hook-related functions.

In the following list of hooks, the arguments after the hook name refer to the arguments to the functions invoked by the hook (in Ruby and Forth). That is, after-apply-controls-hook (snd) means that the functions on the after-apply-controls-hook list each take one argument, a sound. In Scheme, they refer to the hook variables accessible in the hook environment via (hook 'snd), for example.

after-apply-controls-hook (snd)

This hook is called when apply-controls finishes. add-amp-controls in snd-motif.scm uses this hook to reset any added amplitude sliders to 1.0.

after-graph-hook (snd chn)

This hook is called after a graph is updated or redisplayed. Use it to add your own finishing touches to the display; if added earlier they risk being erased by Snd as it redraws graphs.

after-lisp-graph-hook (snd chn)

This hook is called after a "lisp" graph is updated or redisplayed. The lisp-graph-hook functions are called before the actual graph is displayed, so if you want to add to a graph in some way, you need to use after-lisp-graph-hook. display-bark-fft in dsp.scm uses it to draw the x axis labels and ticks for various frequency scales.

after-open-hook (snd)

This hook is called just before a newly opened sound's window is displayed. It provides a way to set various sound-specific defaults. For example, the following causes Snd to default to locally sync'd channels (that is, each sound's channels are sync'd together but are independent of any other sound), united channels (all chans in one graph), and filled graphs (not line segments or dots, etc):

(hook-push after-open-hook
  (lambda (hook)
    (let ((snd (hook 'snd)))
      (if (> (channels snd) 1)
          (begin
            (set! (sync snd) (+ 1 (sync-max)))
            (set! (channel-style snd) channels-combined)
            (set! (graph-style snd) graph-filled))))))

See also enved.scm, and various examples in snd-motif.scm.

after-save-as-hook (snd name dialog)

This hook is called after File:Save as. ('snd = sound index, 'name = full filename, 'dialog = #t if called from a dialog).

after-save-state-hook (name)

This hook is called after Snd has saved its state (save-state). 'name is the (otherwise complete) saved state program (a filename). See ws-save-state in ws.scm. It uses this sequence:

(let ((fd (open-output-file filename "a"))) ; "a" = append
  (format fd "~%~%;;; from ws.scm~%")
  ...
  (close-output-port fd))
after-transform-hook (snd chn scaler)

This hook is called just after an FFT (or spectrum) is calculated.

(define (report-fft-peak snd chn)
  (if (and (transform-graph?) 
           (= (transform-graph-type) graph-once))
      (status-report 
        (number->string (/ (* 2 (maxamp (transform->float-vector snd chn)))
                           (transform-size snd chn))))))

(hook-push after-transform-hook 
  (lambda (hook) 
    (report-fft-peak (hook 'snd) (hook 'chn))))
bad-header-hook (name)

This hook is called if a file has a bogus-looking header (that is, a header with what appear to be bad values such as a negative number of channels). If the hook returns #t, Snd does not try to open the file.

(hook-push bad-header-hook 
  (lambda (hook) 
    (set! (hook 'result) #t))) ; don't open bogus-looking files

If no header is found, open-raw-sound-hook is invoked instead ("raw" = "headerless").

before-close-hook (snd) 

This hook is called when a file is about to be closed. If the hook returns #t, the file is not closed.

before-exit-hook ()

This hook is called upon a request to exit Snd. If the hook returns #t, Snd does not exit.

before-save-as-hook (snd name selection sampling-rate sample-type header-type comment)

This hook is called before save-sound-as or File:Save as. If the hook returns #t, the save is not performed. This hook provides a way to do last minute fixups (srate conversion for example) just before a sound is saved. The arguments to the hook function describe the requested attributes of the saved sound; 'snd' is the to-be-saved sound's index; 'name' is the output file's name; 'selection' is #t if we're saving the selection.

(hook-push before-save-as-hook
  (lambda (hook)	   
    ((lambda (index filename sr dformat htype comment)
      (if (not (= sr (srate index)))
          (let ((chns (channels index)))
	    (do ((i 0 (+ i 1)))
	        ((= i chns))
	      (src-channel (exact->inexact (/ (srate index) sr)) 0 #f index i))
	    (save-sound-as filename index :header-type htype :sample-type dformat :srate sr :comment comment) 
	    (do ((i 0 (+ i 1)))
	        ((= i chns))
	      (undo 1 index i))
	    (set! (hook 'result) #t)))) ; tell Snd that the sound is already saved
     (hook 'snd) (hook 'name) (hook 'sampling-rate) (hook 'header-type) (hook 'sample-type) (hook 'comment))))

before-save-state-hook (name)

This hook is called before Snd saves its state (save-state). 'name' is the saved state file. If the hook returns #t, the save state file is opened in append mode (rather than create/truncate), so you can write preliminary stuff via this hook, then instruct Snd not to clobber it during the save process.

(hook-push before-save-state-hook
  (lambda (hook) 
    (call-with-output-file (hook 'name)
      (lambda (p)
        (format p ";this comment will be at the top of the saved state file.~%~%")))
    (set! (hook 'result) #t)))
before-transform-hook (snd chn)

This hook is called just before an FFT (or spectrum) is calculated. If the hook returns an integer, that value is used as the starting point (sample number) of the fft. Normally, the fft starts from the left window edge. To have it start at mid-window:

(hook-push before-transform-hook
  (lambda (hook)        ; 0.5 * (left + right) = midpoint
    (set! (hook 'result) 
          (round (* 0.5 (+ (right-sample (hook 'snd) (hook 'chn)) 
                           (left-sample (hook 'snd) (hook 'chn))))))))

The following somewhat brute-force code shows a way to have the fft reflect the position of a moving mark:

(let ((fft-position #f))
  (hook-push before-transform-hook 
    (lambda (hook) 
      (set! (hook 'result) fft-position)))
  (hook-push mark-drag-hook 
    (lambda (hook)
      (set! fft-position (mark-sample (hook 'id)))
      (update-transform-graph))))
clip-hook (val) 

This hook is called whenever a sample is about to be clipped while writing out a sound file. The hook can return the new value.

close-hook (snd)

This hook is called when a file is closed (before the actual close, so the index 'snd' is still valid).

(hook-push close-hook
  (lambda (hook) 
    (play "wood16.wav")))
color-hook () 

This hook is called whenever one of the variables associated with the color dialog changes.

draw-mark-hook (id)

This hook is called before a mark is drawn. If the hook returns #t, the mark is not drawn. mark-sync-color in snd-motif.scm uses this hook to draw sync'd marks in some other color than the current mark-color.

draw-mix-hook (id old-x old-y x y)

This hook is called before a mix tag is drawn. If the hook returns either #t or a list, the mix tag is not drawn by Snd (the assumption is that the hook function drew something). old-x and old-y are the previous mix tag positions (in case you're using draw-mix-hook to draw your own mix tag as in musglyphs.scm). x and y give the current position. If the hook returns a list, its two elements (integers) are treated as the mix's tag x and y locations for subsequent mouse click hit detection.

drop-hook (name) 

This hook is called each time Snd receives a drag-and-drop event, passing the hook functions the dropped filename. If the hook returns #t, the file is not opened by Snd. Normally if you drag a file icon to the menubar, Snd opens it as if you had called open-sound. If you drag the icon to a particular channel, Snd mixes it at the mouse location in that channel. To get Snd to mix the dragged file even from the menubar:

(hook-push drop-hook
  (lambda (hook) 
    (mix (hook 'name))
    (set! (hook 'result) #t))) ; return #t = we already dealt with the drop
during-open-hook (fd name reason)

This hook is called after a file is opened, but before its data has been read. 'reason' is an integer indicating why this file is being opened:

0: reopen a temporarily closed file (internal to Snd — normally invisible)
1: sound-open, File:open etc — the normal path to open a sound
2: copy reader — another internal case; this happens if a sound is played and edited at the same time
3: insert sound (File:Insert etc)
4: re-read after an edit (file changed, etc — an invisible editing case)
5: open temp file after an edit (another invisible editing case)
6: mix sound (File:Mix etc)

So, to restrict the hook action to the normal case where Snd is opening a file for the first time, check that 'reason' is 1, or perhaps 1, 3, or 6 (these read the external form of the data).

effects-hook ()

effects-hook is a convenience hook for the effects dialogs.

enved-hook (envelope point x y reason)

Each time a breakpoint is changed in the envelope editor, this hook is called; if it returns a list, that list defines the new envelope, otherwise the breakpoint is moved (but not beyond the neighboring breakpoint), leaving other points untouched. The kind of change that triggered the hook callback is indicated by the argument 'reason'. It can be enved-move-point, enved-delete-point, or enved-add-point. This hook makes it possible to define attack and decay portions in the envelope editor, or use functions such as stretch-envelope from env.scm:

(hook-push enved-hook
  (lambda (hook)
    ((lambda (env pt x y reason)
       (if (and (= reason enved-move-point)
                (> x 0.0)
                (< x (envelope-last-x env))) ; from env.scm
         (let* ((old-x (env (* pt 2)))
                (new-env (stretch-envelope env old-x x)))
           (set! (new-env (+ (* pt 2) 1)) y)
           (set! (hook 'result) new-env))))
     (hook 'envelope) (hook 'point) (hook 'x) (hook 'y) (hook 'reason))))

In Forth/Ruby, if there are several functions on the hook, each gets the envelope result of the preceding function.

exit-hook ()

This hook is called upon exit.

graph-hook (snd chn y0 y1) 

This hook is called each time a graph is updated or redisplayed. If it returns #t, the display is not updated. See examp.scm for many examples. If you want to add your own graphics to the display, use after-graph-hook.

(hook-push graph-hook
  (let ((documentation "set the dot size depending on the number of samples being displayed"))
    (lambda (hook)
      (let* ((snd (hook 'snd))
             (chn (hook 'chn))
             (dots (- (right-sample snd chn) (left-sample snd chn))))
        (if (> dots 100) 
	    (set! (dot-size snd chn) 1)
	  (if (> dots 50)
	      (set! (dot-size snd chn) 3)
	    (if (> dots 25)
	        (set! (dot-size snd chn) 5)
	      (set! (dot-size snd chn) 8))))))))
help-hook (subject help-string)

This hook is called from snd-help with the current help subject and default help-string. Say we want the index.scm procedure html called any time snd-help is called (from C-? for example):

(hook-push help-hook (lambda (hook) (html (hook 'subject))))
initial-graph-hook (snd chn duration) 

This hook is called the first time a given channel is displayed (when the sound is first opened). If the hook returns a list, the list's contents are interpreted as:

(list x0 x1 y0 y1 label ymin ymax)

(all trailing values are optional), where these numbers set the initial x and y axis limits and the x axis label. The default (an empty hook) is equivalent to:

(hook-push initial-graph-hook 
  (lambda (hook) 
    (set! (hook 'result) (list 0.0 0.1 -1.0 1.0 "time" -1.0 1.0))))

The 'duration' argument is the total length in seconds of the displayed portion of the channel, so to cause the entire sound to be displayed initially:

(hook-push initial-graph-hook 
  (lambda (hook) 
    (set! (hook 'result) (list 0.0 (hook 'duration)))))

To get other the data limits (rather than the default y axis limits of -1.0 to 1.0), you can use mus-sound-maxamp, but if that sound's maxamp isn't already known, it can require a long process of reading the file. The following hook procedure uses the maxamp data if it is already available or if the file is short:

(hook-push initial-graph-hook
  (lambda (hook)
    (let ((snd (hook 'snd))
          (chn (hook 'chn))
          (dur (hook 'duration)))
      (if (or (mus-sound-maxamp-exists? (file-name snd))
              (< (framples snd chn) 10000000))
	  (let* ((amp-vals (mus-sound-maxamp (file-name snd)))
	         (max-val (max 1.0 (amp-vals (+ (* chn 2) 1)))))
                 ;; max amp data is list: (sample value sample value ...)
	    (set! (hook 'result) (list 0.0 dur (- max-val) max-val))) ; these are the new y-axis limits
	(set! (hook 'result) (list 0.0 dur -1.0 1.0))))))             ; max amp unknown, so use defaults
key-press-hook (snd chn key state)

This hook is called upon key press while the mouse is in the lisp graph (the third graph, to the right of the time and fft graphs). If it returns #t, the key press is not passed to the main handler. 'state' refers to the control, meta, and shift keys. start-enveloping in enved.scm uses this hook to add C-g and C-. support to the channel-specific envelope editors.

lisp-graph-hook (snd chn)

This hook is called just before the lisp graph is updated or redisplayed (see display-db). If it returns a list of pixels (xm style), they are used in order by the list of graphs, rather than Snd's default colors. If it returns a thunk, that function is called rather than the standard graph routine:

(hook-push lisp-graph-hook
  (lambda (hook)
    (let ((snd (hook 'snd))
          (chn (hook 'chn)))
      (set! (hook 'result)
        (lambda ()
          (draw-string "hi" 
                       (x->position 0.5 snd chn lisp-graph) 
	               (y->position 0.0 snd chn lisp-graph)
	               snd chn))))))

For a fancy example, see display-bark-fft in dsp.scm.

listener-click-hook (position)

This hook is called when a click occurs in the listener; the 'position' argument is the position in the text (a character number) where the click occurred.

mark-click-hook (id)

This hook is called when a mark is clicked; return #t to squelch the default status area mark identification.

(hook-push mark-click-hook
  (lambda (hook)
    (let ((n (hook 'id)))
      (if (not (defined? 'mark-properties)) (load "marks.scm"))
      (info-dialog "Mark Help"
        (format #f "Mark ~A~A:~%  sample: ~D = ~,3F secs~A~A"
	        n 
	        (let ((name (mark-name n)))
   	          (if (> (string-length name) 0)
		      (format #f " (~S)" name)
		      ""))
	        (mark-sample n)
	        (* 1.0 (/ (mark-sample n) (srate (car (mark-home n)))))
	        (if (not (= (mark-sync n) 0))
	          (format #f "~%  sync: ~A" (mark-sync n))
	          "")
	        (let ((props (mark-properties n)))
	          (if (pair? props)
	            (format #f "~%  properties: '~A" props)
	            ""))))
      (set! (hook 'result) #t))))
mark-drag-hook (id)

This hook is called when a mark is dragged. If it returns #t, the mark position is not reflected in the status area.

(define (report-mark-location id)
  ;; print current mark location in status area
  (let ((samp (mark-sample id))
        (sndchn (mark-home id)))
    (status-report 
      (format #f "mark ~A: sample: ~D (~,3F) ~A[~D]: ~,3F"
              id samp 
              (exact->inexact (/ samp (srate (car sndchn))))
              (short-file-name (car sndchn))
              (cadr sndchn)
	      (sample samp (car sndchn) (cadr sndchn))))))

(hook-push mark-drag-hook 
  (lambda (hook) 
    (report-mark-location (hook 'id))
    (set! (hook 'result) #t)))
mark-hook (mark snd chn reason)

This hook is called when a mark is added, deleted, or moved (but not while moving). 'reason' can be 0: add, 1: delete, 2: move (via set! mark-sample), 3: delete all marks, 4: release (after drag). In the "release" case, the hook is called upon button release before any edits (control-drag of mark) or sorting (simple drag), and if the mark-sync is not 0, the hook is called on each syncd mark.

(define (snap-mark-to-beat)
  ;; when a mark is dragged, its end position is always on a beat
  (hook-push mark-hook
    (lambda (hook)
      ((lambda (mrk snd chn reason)
         (let ((mark-release 4))
           (if (= reason mark-release)
               (let* ((samp (mark-sample mrk))
	              (bps (/ (beats-per-minute snd chn) 60.0))
		      (sr (srate snd))
		      (beat (floor (/ (* samp bps) sr)))
		      (lower (floor (/ (* beat sr) bps)))
		      (higher (floor (/ (* (+ 1 beat) sr) bps))))
	          (set! (mark-sample mrk) (if (< (- samp lower) (- higher samp)) lower higher))))))
       (hook 'id) (hook 'snd) (hook 'chn) (hook 'reason)))))
mix-click-hook (id)

This hook is called when a mix tag is clicked (when the double-arrow is displayed over the tag); return #t to omit the default action which is to start the Mix dialog with the clicked mix. One example is mix-click-info in mix.scm. Here's an example that sets a mix's amps to 0 if you click it (see mix-click-sets-amp in mix.scm for a fancier version):

(hook-push mix-click-hook
  (lambda (hook)
    (set! (mix-amp (hook 'id)) 0.0)
    (set! (hook 'result) #t)))
mix-drag-hook (id x y)

This hook is called when a mix is dragged.

(hook-push mix-drag-hook
  (lambda (hook)
    (status-report 
      (format #f "mix ~A at ~D: ~,3F" 
        (hook 'id) 
        (mix-position (hook 'id)) 
        (exact->inexact (/ (mix-position (hook 'id)) (srate)))))))

A neat example is to set up an empty sound with a 1.0 in sample 0, mix in a float-vector containing one element of 0.5, then set up this mix-drag-hook:

(hook-push mix-drag-hook 
  (lambda (hook) 
    (update-transform-graph)))

and turn on the FFT graph. As you drag the mix, you can see the spectral effect of that moving value as a comb filter.

mix-release-hook (id samples)

This hook is called after a mix has been dragged by the mouse to a new position. 'samples' is the number of samples moved during the drag. If the hook returns #t, the final position of the mix is hook's responsibility. See snap-mix-to-beat in mix.scm.

mouse-click-hook (snd chn button state x y axis) 

This hook is called upon a mouse button release or click (with various exceptions). If its function returns #t, the click is ignored by Snd.

(define (click-to-center snd chn x axis)
  ;; if mouse click in time domain graph, set cursor as normally, but also center the window
  (and (= axis time-graph)
       (let ((samp (floor (* (srate snd) (position->x x snd chn)))))
	 (set! (cursor snd chn) samp)
	 (set! (right-sample snd chn) 
           (- samp (floor (* .5 (- (left-sample snd chn) (right-sample snd chn))))))
	 (update-time-graph)
	 #t)))

(hook-push mouse-click-hook 
  (lambda (hook) 
    (set! (hook 'result) (click-to-center (hook 'snd) (hook 'chn) (hook 'x) (hook 'axis)))))

;;; this example disables button 2 -> insert selection
(hook-push mouse-click-hook
  (lambda (hook)
    (set! (hook 'result) 
       (and (= (hook 'axis) time-graph) 
            (= (hook 'button) 2)))))

The mouse scroll wheel is sometimes reported as buttons 4 and 5; in the next example, turning the wheel zooms the graph in or out:

(hook-push mouse-click-hook
  (lambda (hook)
    (let ((button (hook 'button))
          (axis (hook 'axis)))
      (if (and (= axis time-graph)
	       (memv button '(4 5))) ; mouse scroll wheel
  	  (let ((midpoint (* 0.5 (apply + (x-bounds))))
	        (dur (/ (framples) (srate)))
	        (range (if (= button 4)
			   (* -0.25 (apply - (x-bounds))) ; zoom in
			   (abs (apply - (x-bounds))))))  ; zoom out
	    (set! (x-bounds) (list (max 0.0 (- midpoint range))
				   (min dur (+ midpoint range)))))))))

Here is a Forth example:

mouse-click-hook lambda: <{ snd chn button state x y axis -- }> 
 axis time-graph = if 
   $" freq: %.3f" '( snd chn #f cursor  snd chn spot-freq ) string-format 
   snd #f status-report 
 else 
   #f 
 then 
; add-hook! 
mouse-drag-hook (snd chn button state x y)

This hook is called when the mouse is dragged within the lisp graph (see enved.scm).

mouse-enter-graph-hook (snd chn)

This hook is called when the mouse enters a channel's drawing area (graph pane).

(hook-push mouse-enter-graph-hook
  (lambda (hook)
    (snd-print (format #f "~A[~A]" (short-file-name (hook 'snd)) (hook 'chn)))))
mouse-enter-label-hook (type position label)

This hook is called when the mouse enters a file viewer or region label. The 'type' is 1 for view files list, and 2 for regions. The 'position' is the scrolled list position of the label. The label itself is 'label'. We can use the finfo procedure in examp.scm to popup file info as follows:

(hook-push mouse-enter-label-hook
  (lambda (hook)
    (if (not (= (hook 'type) 2))
        (info-dialog (hook 'label) (finfo (hook 'label))))))

See also files-popup-info in nb.scm.

mouse-enter-listener-hook (widget)

This hook is called when the mouse enters the listener pane. This hook, along with the parallel graph hook makes it possible to set up Snd to behave internally like a window manager with pointer focus. That is, to ensure that the pane under the mouse is the one that receives keyboard input, we can define the following hook procedures:

(hook-push mouse-enter-graph-hook
  (lambda (hook)
    (if (sound? (hook 'snd))
         (focus-widget (car (channel-widgets (hook 'snd) (hook 'chn)))))))

(hook-push mouse-enter-listener-hook
  (lambda (hook)
    (focus-widget (hook 'widget))))
mouse-enter-text-hook (widget)

This hook is called when the mouse enters a text widget (this is the third of the pointer focus hooks).

(hook-push mouse-enter-text-hook
  (lambda (hook)
    (focus-widget (hook 'widget))))
mouse-leave-graph-hook (snd chn)

This hook is called when the mouse leaves a channel's drawing area (graph pane).

mouse-leave-label-hook (type position name)

This hook is called when the mouse exits one of the labels covered by mouse-enter-label-hook. See nb.scm.

mouse-leave-listener-hook (widget)

This hook is called when the mouse leaves the listener pane.

mouse-leave-text-hook (widget)

This hook is called when the mouse leaves a text widget.

mouse-press-hook (snd chn button state x y)

This hook is called upon a mouse button press within the lisp graph (see enved.scm). The 'x' and 'y' values are relative to the lisp graph axis (as if the raw mouse pixel position was passed through position->x and position->y).

mus-error-hook (type message)

This hook is called upon mus-error. If it returns #t, Snd ignores the error (it assumes you've handled it via the hook). Both mus_error and mus_print run this hook; in the mus_print case, the 'type' is mus-no-error (0). You can redirect mus_print output from stderr (the default) to stdout via:

(hook-push mus-error-hook
  (lambda (hook)
    (if (= (hook 'type) 0)
        (begin
	  (display (hook 'message))
	  (set! (hook 'result) #t)))))

To decode the 'type' argument, see mus-error-type->string.

name-click-hook (snd)

This hook is called when the sound name is clicked (in the label in the status area region of the sound's pane). If the function returns #t, the usual highly informative status area babbling is squelched.

(hook-push name-click-hook
  (lambda (hook) ; toggle read-only
    (set! (read-only (hook 'snd)) (not (read-only (hook 'snd))))
    (set! (hook 'result) #t)))
new-sound-hook (name)

This hook is called whenever a new sound file is being created. sound-let in ws.scm uses this hook to keep track of newly created temporary sounds so that it can delete them once they are no longer needed.

new-widget-hook (widget)

This hook is called each time a dialog or a new set of channel or sound widgets is created. This is used in misc.scm (paint-all) to make sure all newly created widgets have the same background pixmaps.

open-hook (name)

This hook is called before a sound file is opened. If the function returns #t, or the sound is not readable (bad header, etc) the file is not opened and any corresponding after-open-hook functions are not called. If it returns a string (a filename), that file is opened instead of the original one.

(hook-push open-hook
  (lambda (hook)
    (let ((filename (hook 'name)))
      (if (and (= (mus-sound-header-type filename) mus-raw)
               ;; check for "OggS" first word, if found, translate to something Snd can read
	       (call-with-input-file filename 
	        (lambda (fd)
		  (and (char=? (read-char fd) #\O)
		       (char=? (read-char fd) #\g)
		       (char=? (read-char fd) #\g)
		       (char=? (read-char fd) #\S)))))
	(let ((aufile (string-append filename ".au")))
	  (if (file-exists? aufile) (delete-file aufile))
	  (system (format #f "ogg123 -d au -f ~A ~A" aufile filename))
	  (set! (hook 'result) aufile)))))) ; now open-sound will read the new .au file
open-raw-sound-hook (name state)

This hook is called each time open-sound encounters a headerless file. Its result can be a list describing the raw file's attributes (thereby bypassing the Raw File Dialog and so on): (list chans srate sample-type data-location data-length) where trailing elements can be omitted ('data-location' defaults to 0, and 'data-length' defaults to the file length in bytes). In Ruby and Forth, if there is more than one function on the hook list, functions after the first get the on-going list result as the 'state (the empty list is the default).

(hook-push open-raw-sound-hook 
  (lambda (hook) 
    (set! (hook 'result) (list 1 44100 mus-lshort))))

Return () to accept all the current raw header defaults; return #f to fallback on the Raw File Dialog. The raw header defaults are stereo, 44100 Hz, big endian short data; these values can be changed in the Raw File Dialog, by calling open-raw-sound with explicit arguments, or via mus-header-raw-defaults. If the hook returns #t, open-sound returns without opening the file.

orientation-hook () 

This hook is called whenever one of the variables associated with the orientation dialog changes.

output-comment-hook (comment)

This hook is called in the Save-As dialog to set the default output comment value. 'str' is the current sound's comment. If there is more than one hook function, each function's result is passed as input to the next function in the list.

(hook-push output-comment-hook
  (lambda (hook)   ; append a time-stamp
    (set! (hook 'result) 
      (string-append (hook 'comment)
                     ": written " 
                     (strftime "%a %d-%b-%Y %H:%M %Z" (localtime (current-time)))))))

;; in Ruby: format("%s: written %s", comment, Time.new.localtime.strftime("%d-%b %H:%M %Z"))
play-hook (size)

This hook is called each time a buffer is about to be filled for the DAC. The buffer size is 'size'. See enved.scm and marks.scm.

read-hook (text)

This hook is called each time a line is typed into the listener (it is triggered by the carriage return).

save-hook (snd name)

This hook is called each time a sound ('snd') is about to be saved. If it returns #t, the file is not saved. 'name' is #f unless the file is being saved under a new name (as in save-sound-as). See autosave.scm.

save-state-hook (name)

This hook is called each time the save-state mechanism is about to create a new temporary file to save some edit history sample data; that is, each channel's edit history data is saved in a separate temporary file, and this hook provides a way to specify the name of that file. 'name' is the temporary file name that will be used unless the hook function returns a different one (as a string). This hook provides a way to keep track of which files are used in a given saved state batch, so that later cleanup is easier to manage.

select-channel-hook (snd chn)

This hook is called when a channel is selected (after the sound has been selected). The function arguments are the sound's index and the channel number.

select-sound-hook (snd)

This hook is called when a sound is selected. The argument is the about-to-be-selected sound.

snd-error-hook (message)

This hook is called upon snd-error. If the listener is closed, it is also called upon any Scheme, Ruby, or Forth error. If it returns #t, Snd flushes the error (it assumes you've dealt with it via the hook).

(hook-push snd-error-hook
  (lambda (hook)
    (play "bong.snd")))
snd-warning-hook (message)

This hook is called upon snd-warning. If it returns #t, Snd flushes the warning (it assumes you've reported it via the hook).

(define without-warnings
  (lambda (thunk)
    (define no-warning (lambda (hook) (set! (hook 'result) #t)))
    (hook-push snd-warning-hook no-warning)
    (thunk)
    (hook-remove snd-warning-hook no-warning)))
start-playing-hook (snd)

This hook is called when a sound is about to be played. If its function returns #t, Snd does not play. We can use this hook to replace "play" with "play selection" if the selection is active:

(hook-push start-playing-hook
  (lambda (hook)
    (if (and (selection?)
	     (selection-member? (hook 'snd)))
	(begin
	  (play (selection))
	  (set! (hook 'result) #t))))) ; there's a selection so don't play the entire sound
start-playing-selection-hook ()

This hook is called when the selection is about to be played. If its function returns #t, Snd does not play the selection.

stop-playing-hook (snd)

This hook is called when a sound finishes playing. stop-playing-hook may be called more often than start-playing-hook.

stop-playing-selection-hook ()

This hook is called when the selection finishes playing.

update-hook (snd)

update-hook is called just before a sound is updated ("update" means the sound is re-read from the disk, flushing the current version; this is useful if you overwrite a sound file with some other program, while viewing it in Snd). The update process can be triggered by a variety of situations, not just by update-sound. The hook is passed the sound's index. If it returns #t, the update is cancelled (this is not recommended!); if it returns a procedure of one argument, that procedure is called upon completion of the update operation; its argument is the (possibly different) sound. Snd tries to maintain the index across the update, but if you change the number of channels the newly updated sound may have a different index. add-mark-pane in snd-motif.scm uses the returned procedure to make sure the mark pane is reactivated right away when a sound is updated. The basic idea is:

(hook-push update-hook
  (lambda (hook)             
    (set! (hook 'result) 
      (lambda (updated-snd)  ; this code executed when update is complete
        (snd-print "ok!")))))

I use update-hook to make sure the y axis bounds reflect the new maxamp, if it is greater than 1.0:

(hook-push update-hook
  (lambda (hook)
    (let ((old-snd (hook 'snd)))  ; (hook 'snd) is the sound about to be updated
      (set! (hook 'result) 
           (lambda (snd)
              (do ((i 0 (+ i 1)))
	          ((= i (channels snd)))
	        (let ((mx (maxamp snd i)))
	        (if (> mx 1.0)
  	            (set! (y-bounds snd i) (list (- mx) mx))
	            (if (and (> (cadr (y-bounds old-snd)) 1.0) ; previous (pre-update) version was > 1.0
		             (<= mx 1.0))                      ; but current is not, so reset axes
		        (set! (y-bounds snd i) (list -1.0 1.0)))))))))))
view-files-select-hook (dialog name) [Motif only]

This hook is called each time a file is selected in a View Files dialog's files list.

Channel-specific hooks:
edit-hook (snd chn)
undo-hook (snd chn)
after-edit-hook (snd chn)

These are functions that return the hooks in question associated with the specified channel. In Ruby and Forth the functions on these hooks are thunks — they should take no arguments. edit-hook is called just before any attempt to edit the channel's data; if it returns #t, the edit is cancelled. So,

Scheme: (hook-push (edit-hook hook) (lambda (hook) (set! (hook 'result) #t)))
Ruby:   edit_hook(snd, chn).add_hook!(\"stop-edit\") do | | true end
Forth:  snd chn edit-hook lambda: <{ }> #t ; add-hook!

halts any attempt to edit the data; this is even more restrictive than setting the read-only flag because the latter only refuses to overwrite the current data. undo-hook is called just after any undo, redo, or revert that affects the channel. after-edit-hook is called after an edit, but before after-graph-hook (add-mark-pane in snd-motif.scm uses this hook to update a mark list after each edit so that the displayed mark positions are correct). You can use edit-hook to set up protected portions of the edit history:

(define* (protect snd chn)
  (let ((edit-pos (edit-position snd chn))
        (hook (edit-hook snd chn)))
    (set! (hook-functions hook)
      (list 
        (lambda ()
          (let ((val (< (edit-position snd chn) edit-pos)))
            (if val (status-report "protected"))
            (set! (hook 'result) val)))))))

(define* (unprotect snd chn)
  (set! (hook-functions (edit-hook snd chn)) ()))

enved.scm uses several of these hooks to implement an envelope editor in lisp. add-mark-pane in snd-motif.scm uses them to make sure the mark list reflects the current edit history location. See also autosave.scm. It is possible for after-edit-hook to be called more often that edit-hook, or vice-versa; edit-hook may be called more than once on a given attempt to edit; if a long computation is required Snd may check edit-hook ahead of time to avoid unnecessary work.

Snd's objects

Snd presents its various data structures as a list of sounds, each with a list of channels, each with lists of edits, marks, and mixes. The sound data itself is accessed through a variety of structures and functions, each aimed at a particular kind of use. The accessors from lowest level up are: samplers (one sample at a time iterators) and frample-readers (a "frample" is a multichannel sample), channel-at-a-time blocks (float-vectors, map-channel, etc), multichannel blocks (map-sound, etc), a few historical leftovers that follow the "sync" field (scale-to, etc), and finally the top-level operations such as save-sound-as (these are used in the File menu, etc). In the following sections, I'll start with the lowest level and work upwards, more or less. But before launching into samplers, I need to explain a few things about the following documentation.

Each sound is an object in Snd, and has an associated index. To refer to that sound, you can use either the object or the index. In the argument lists below, 'snd' as an argument refers to either the sound object or its index. It normally defaults to the currently selected sound. Similarly, 'chn' is the channel number, starting from 0, and defaults to the currently selected channel. So if there's only one sound active, and it has only one channel, (cursor), (cursor 0), (cursor 0 0), and (cursor (integer->sound 0)) all refer to the same thing. If you want to refer to the currently selected sound explicitly, use selected-sound.

In many cases, the 'snd', 'chn', and 'reg' arguments can be #t which means "all"; if 'snd' is #t, all sounds are included. (expand-control #t) returns a list of the current control panel expansion settings of all sounds, and (set! (transform-graph? #t #t) #t) turns on the fft display in all channels of all sounds.

When an error occurs, the function throws a tag such as 'no-such-sound, 'no-active-selection, etc. All the functions that take sound and channel args ('snd chn' below) can return the errors 'no-such-sound and 'no-such-channel; all the mix-related functions can return 'no-such-mix; all the region-related functions can return 'no-such-region; all selection-oriented functions can return 'no-active-selection. To reduce clutter, I'll omit mention of these below.

Samplers

The simplest data access function is sample which returns the sample at a given position in a sound's channel. This simplicity, however, comes at a price in computation: if the desired sample is not in Snd's in-core (already loaded) view of the data, it has to go get the sample, which can sometimes require that it open, read, and close a sound file. The result is that sample can bring your code to a grinding halt. There are two alternatives, leaving aside the scanning and mapping functions mentioned below. One involves keeping the buffer of data around explicitly (channel->float-vector), and the other involves the use of a special object known as a sampler. The sampler returns the next sample in its sound each time it is called; this kind of access is sometimes called an "enumerator" (Ruby) or perhaps "iterator" (Gtk+). The buffer approach (channel->float-vector in expsrc) is better if you're jumping around in the data, the sample-by-sample approach if you're treating the data as a sequence of samples. To get a sampler, you create a reader (via make-sampler) giving it the start position, the sound and channel to read, and the initial read direction, then get data via read-sample (which remembers the read direction passed to make-sampler), or next-sample (read forward) and previous-sample (read backward); when done, you can close the reader with free-sampler, but it's usually not necessary; the garbage collector will take care of it if you forget (but, sigh, the GC can be dilatory at times).

There is a similar set of functions giving access to the mix data. make-mix-sampler returns a mix reader for the desired mix, mix-sampler? returns #t if its argument in a mix sampler, and read-mix-sample returns the next sample (before it is mixed into the output).

copy-sampler obj

copy-sampler returns a copy of 'obj' which can be any kind of sampler.

free-sampler obj

free-sampler releases the sampler 'obj'. In most cases, you don't need to call this function because the garbage collector handles the sampler object, but it doesn't hurt anything (but don't try to use a sampler after you've freed it!). If you're using zillions of samplers, sometimes freeing the samplers explicitly can reduce demands on memory.

make-mix-sampler mix (beg 0)

make-mix-sampler creates a mix-sampler reading 'mix' starting (in the mix input) at 'beg'. See mix->float-vector in mix.scm.

make-region-sampler start reg chn (dir 1)

make-region-sampler creates a sampler reading channel 'chn' of the region 'reg' starting at sample 'start', and reading forward if 'dir' is 1, backwards if 'dir' is -1. It is not safe to assume that this reader will return zeros beyond the region boundaries.

make-sampler start snd chn dir edpos

make-sampler creates a sampler reading the given channel starting at sample 'start' with initial read direction 'dir' (1=forward, -1=backward). 'edpos' is the edit history position to read; it defaults to the current edit.

> (open-sound "oboe.snd")
#<sound 0>
> (define reader (make-sampler 1000))
reader
> reader
#<sampler: oboe.snd[0: 0] from 1000, at 1000, forward>
> (read-sample reader)
0.0328369140625
> (sample 1000)
0.0328369140625
> (next-sample reader)
0.0347900390625
> (sample 1001)
0.0347900390625
> (sampler-home reader)
(#<sound 0> 0)
> (sampler-position reader)
1002

One use of 'edpos' is to get the difference between two edits:

(define snd-diff
  (lambda () ;assume mono, get diff between current state and previous
    (let* ((index (selected-sound))
           (edit-pos (edit-position index))
           (previous-edit (make-sampler 0 0 index 1 (- edit-pos 1))))
      (lambda (x)
        (- x (read-sample previous-edit)) #f))))

(map-channel (snd-diff))

Once the reader has been set up to read at a given edit position, subsequent edits won't affect it. One sequence that takes advantage of this is: make-sampler, scale-by 0, then run an overlap-add process on the data from before the scaling.

'snd' can be a filename (a string); in this way a sampler can read external sounds without going to the trouble of loading them into Snd.

(define reader (make-sampler 100 "oboe.snd"))

'snd' also can be a mix or region. make-sampler is probably the most useful function in Snd; there are lots of examples in the Scheme, Ruby, and Forth files.

mix-sampler? obj

mix-sampler? returns #t if 'obj' is a mix-sampler.

next-sample obj

next-sample returns the next sample (reading forward) read by the sampler 'obj'.

previous-sample obj

previous-sample returns the previous sample in the stream read by the sampler 'obj'.

read-mix-sample obj

read-mix-sample returns the next sample read by the mix-sampler 'obj'.

read-region-sample obj

read-region-sample returns the next sample read by the region-sampler 'obj'.

(define* (region->float-vector reg (chn 0))
  (if (region? reg)
      (if (< chn (channels reg))
	  (let* ((reader (make-region-sampler 0 reg chn))
		 (len (region-framples reg))
		 (data (make-float-vector len 0.0)))
	    (do ((i 0 (+ i 1)))
		((= i len) data)
	      (set! (data i) (reader))))
	  (error 'no-such-channel (list "region->float-vector" reg chn)))
      (error 'no-such-region (list "region->float-vector" reg))))
read-sample obj

read-sample returns the next sample read by the sampler 'obj', reading in the direction set by make-sampler.

read-sample-with-direction obj dir

read-sample-with-direction returns the next sample read by the sampler 'obj', reading in the direction set by 'dir' (1 = forward, -1 = backward). This combination of next-sample and previous-sample is intended mainly for src.

region-sampler? obj

region-sampler? returns #t if 'obj' is a region sampler.

sampler-at-end? obj

sampler-at-end? returns #t if the sampler 'obj' (any kind of reader) is at the end of the sound (or whatever it is reading), and hence is returning 0.0 each time it is called. When the last "real" sample is returned, the at-end? flag is still false; when it becomes true, the sampler returns a 0.0 sample. See locate-zero in examp.scm, or linear-src-channel in dsp.scm.

sampler-home obj

sampler-home returns information describing the source of the data the sampler 'obj' is reading. if 'obj' is a sound sampler, it returns a list with the sound and channel number associated with 'obj'. If 'obj' is a mix reader, it returns the mix. Finally, if 'obj' is a region reader, it returns a list with the region.

sampler-position obj

sampler-position returns the current (sample-wise) location of the sampler 'obj' (any kind of reader).

sampler? obj

sampler? returns #t if 'obj' is a sampler.

If your extension language supports it, the read-sample functions can be omitted: (reader) is the same as (read-sample reader).

Snd->sample

There is a Snd-specific CLM-style generator that redirects CLM instrument input (via in-any, ina, etc) to Snd data, snd->sample.

make-snd->sample snd

make-snd->sample creates a Snd data reader for use with CLM's in-any, file->sample, etc.

snd->sample gen frample chan

snd->sample gets the next sample from the data accessed by 'gen', similar to file->sample. If *reverb* is a snd->sample generator, for example, ina and file->sample actually call snd->sample.

snd->sample? obj

snd->sample? returns #t if 'obj' is a snd->sample generator.

Vcts or float-vectors

These are arrays of floats. In s7, use "float-vector", and in Forth and Ruby use "vct".

list->vct lst
list->float-vector lst

return a new float-vector with elements of list 'lst' (equivalent to the float-vector function).

make-vct len (initial-element 0.0)
make-float-vector len (initial-element 0.0)

make-float-vector creates a float-vector of size 'len'.

vct :rest args
float-vector :rest args

float-vector is equivalent to list->float-vector with 'args' as the list: (float-vector 0.0 0.1 0.2).

vct? v
float-vector? v

float-vector? returns #t if 'v' is a float-vector.

vct-abs! v
float-vector-abs! v

float-vector-abs! replaces each element of 'v' with its absolute value.

vct-add! v1 v2 (off 0)
float-vector-add! v1 v2 (off 0)

float-vector-add! performs element-wise add: v1[i + off] += v2[i], returning 'v1'.

vct-copy v
float-vector-copy v

float-vector-copy returns a copy of the float-vector 'v'.

Copying
copy file: in Scheme: copy-file, in Ruby: File.copy or File.syscopy
copy string: in Forth: string-copy
copy list: in Forth: list-copy or copy-tree
copy mix: mix->float-vector
copy sampler: copy-sampler
copy (clone) current sound edit state: clone-sound-as
copy channel data: channel->float-vector, or save-sound-as
copy selection data: selection->float-vector or save-selection
copy region data: region->float-vector, save-region
copy transform data: transform->float-vector
vct-equal? v1 v2 diff
float-vector-equal? v1 v2 diff

float-vector-equal? is an element-wise relative difference check. If (abs(v1[i] - v2[i]) / (max (abs v1[i]) (abs v2[i]))) > diff, it returns false. Otherwise it returns the maximum relative difference encountered. If v1 and v2 are of different lengths, the overlapping portion is checked.

vct-fill! v val
float-vector-fill! v val

float-vector-fill! sets each element of 'v' to 'val': v[i] = val. It returns 'v'.

vct-length v
float-vector-length v

float-vector-length returns the length of 'v'.

vct-max v
float-vector-max v

float-vector-max returns the maximum value of the elements of 'v'.

vct-min v
float-vector-min v

float-vector-min returns the minimum value of the elements of 'v'.

vct-move! v new old backwards
float-vector-move! v new old backwards

float-vector-move moves a block of values within a float-vector: v[new++] = v[old++], or if 'backwards' is #t: v[new--] = v[old--]. It returns 'v'.

vct-multiply! v1 v2
float-vector-multiply! v1 v2

float-vector-multiply! performs element-wise multiply of two float-vectors: v1[i] *= v2[i]. It returns 'v1'.

vct-offset! v val
float-vector-offset! v val

float-vector-offset! adds 'val' to each element of 'v': v[i] += val. It returns 'v'.

vct-peak v
float-vector-peak v

float-vector-peak returns the maximum absolute value of the elements of 'v'.

vct-ref v pos
float-vector-ref v pos

float-vector-ref returns the element 'pos' in 'v': v[pos].

vct-reverse! v size
float-vector-reverse! v size

float-vector-reverse! reverses the elements of 'v' (in-place), returning 'v'. If 'size' is given, the reversal centers around it.

vct-scale! v scl
float-vector-scale! v scl

float-vector-scale! multiplies each element of 'v' by 'scl': v[i] *= scl. It returns 'v'.

vct-set! v pos val
float-vector-set! v pos val

float-vector-set! sets the float-vector 'v' element at 'pos' to 'val': v[pos] = val. In Scheme, this is the same as (set! (v pos) val).

vct-subtract! v1 v2
float-vector-subtract! v1 v2

float-vector-subtract! performs an element-wise subtract: v1[i] -= v2[i]. It returns 'v1'.

vct-subseq v start (end len) nv
float-vector-subseq v start (end len) nv

float-vector-subseq returns a new float-vector (or 'nv' if given) with the elements of 'v' between 'start' and 'end' inclusive. 'end' defaults to the end of 'v'.

vct+ obj1 obj2
float-vector+ obj1 obj2

float-vector+ combines float-vector-add! and float-vector-offset!, depending on the type of its arguments.

vct* obj1 obj2
float-vector* obj1 obj2

float-vector* combines float-vector-multiply! and float-vector-scale!, depending on the type of its arguments.

vct->channel v (beg 0) dur snd chn edpos origin
float-vector->channel v (beg 0) dur snd chn edpos origin

float-vector->channel sets the samples from 'beg' to 'beg' + 'dur' from the values in 'v'. This changes (edits) the channel, so 'origin' provides a way to name the edit (for the edit history list and whatnot).

vct->list v
float-vector->list v

float-vector->list returns a list with elements of 'v'.

vct->string v
float-vector->string v

float-vector->string returns a string describing 'v'.

vct->vector v

vct->vector returns a vector with the elements of 'v'.

vector->vct vect

vector->vct returns a vct with elements of vector 'vect'.

In Ruby, vcts partake in the Enumerable and Comparable classes, and have a variety of additional methods: map, each, <=>, etc. See vct.c and the Ruby documentation for a complete list.

:v1
#<vct[len=10]: 0.100 0.100 0.100 3.000 0.100 0.100 0.100 0.100 0.100 0.100>
:v1.find_all {|x| x > 1.0 }
[3.0, 4.0]
:v1.max
4.0
:v2 = make_vct(10, 0.1)
#<vct[len=10]: 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100>
:v2 < v1
true
Sndlib

All of the underlying sound library (Sndlib) functions are available, as well as most of CLM (sndclm.html). See play.scm. Much of the mus-audio interface is changing. In particular, I'm removing the input side of the audio code. The most important Sndlib functions for Snd are:

mus-alsa-buffers

mus-alsa-buffers is the number of buffers ("periods") used in ALSA; you can also use the environment variable MUS_ALSA_BUFFERS. The default setting is 3. These ALSA variables only matter if you built Snd with the configure switch --with-alsa.

mus-alsa-buffer-size

mus-alsa-buffer-size is the buffer size used in ALSA. You can also use the environment variable MUS_ALSA_BUFFER_SIZE. The defaut setting is 1024.

mus-alsa-device

This is the ALSA audio device; it defaults to "default". The matching environment variable is MUS_ALSA_DEVICE. If the ALSA "default" device can't be found, we also look for "plughw:0" and "hw:0". The "0" is apparently a card number or something. On my machine where the internal sound card is worse than useless, I have an EMI 2|6 connected to a USB port. Its ALSA name seems to be "hw:1" on a good day.

mus-alsa-capture-device

This is the ALSA capture device. The matching environment variable is MUS_ALSA_CAPTURE_DEVICE.

mus-alsa-playback-device

This is the ALSA audio playback device. The matching environment variable is MUS_ALSA_PLAYBACK_DEVICE.

mus-alsa-squelch-warning

Set mus-alsa-squelch-warning to #t to squelch warnings from ALSA about srate mismatches.

mus-bytes-per-sample sample-type

mus-bytes-per-sample returns the number of bytes that 'sample-type' uses to encode one sample of sound.

> (mus-bytes-per-sample mus-bdouble)
8
mus-clipping

mus-clipping is the default low-level clipping choice while accessing sound data. Its default is #f which makes clipping very obvious (it will cause wrap-around). If you're using the standard Snd file accessors, you probably want to use clipping, not this function. This function refers to mus-sound-open-output and friends; the file-local version is mus-file-clipping — surely we could make this more confusing! See also clip-hook.

mus-error-type->string error

mus-error-type->string returns a brief string description of 'error' (a mus-error return type). This is only useful in mus-error-hook, and it's not very useful even there.

mus-expand-filename name

mus-expand-filename fills out the filename 'name' to include its 'absolute' pathname; that is, it replaces '~' with the current home directory, and whatever else seems appropriate.

> (mus-expand-filename "oboe.snd")
"/home/bil/cl/oboe.snd"
mus-file-clipping fd

This is the clipping choice for the file referred to by 'fd' (a file identifier as returned by mus-sound-open-input). The default is #f which makes clipping very obvious (it will cause wrap-around). See also clip-hook.

mus-header-raw-defaults

mus-header-raw-defaults returns a list: '(srate chans sample-type), the current raw header defaults. These can be set:

(set! (mus-header-raw-defaults) (list 22050 4 mus-lint))
mus-header-type-name type

mus-header-type-name converts 'type', an integer, to a string, e.g. "AIFF". Some of the sndlib header types are:

mus-next  mus-aifc  mus-riff  mus-rf64 mus-nist  mus-raw  mus-ircam  mus-aiff mus-caff
mus-bicsf mus-soundfont mus-voc mus-svx mus-unsupported

This function just decodes a sndlib header type identifier.

> (mus-header-type-name (mus-sound-header-type "oboe.snd"))
"Sun/Next"

The default sound output header choice is default-output-header-type, a sound file's header type is mus-sound-header-type, the CLM (with-sound) header default is *clm-header-type*, and an opened sound's header type is header-type.

mus-header-type->string type

mus-header-type->string converts 'type', an integer, to a string, e.g. "mus-aifc".

mus-oss-set-buffers num size

In Linux (OSS), this sets the number and size of the OSS fragments. The default (as of 21-May-01) is to accept whatever OSS chooses: I believe this is normally equivalent to (mus-oss-set-buffers 16 12). This default makes the control panel controls very sluggish. Snd used to call (mus-oss-set-buffers 4 12) as its default, but this seems to cause trouble for a variety of new sound cards. My initialization file includes (mus-oss-set-buffers 2 12).

mus-sample-type-name format

mus-sample-type-name converts 'format' from an integer to an explanatory string, e.g. "16-bit big endian linear".

mus-bshort   mus-lshort   mus-mulaw   mus-alaw   mus-byte  
mus-lfloat   mus-bint     mus-lint    mus-b24int mus-l24int
mus-ubshort  mus-ulshort  mus-ubyte   mus-bfloat mus-bdouble 
mus-ldouble  mus-unknown

There are also "unscaled" versions of the floating point types, and "normalized" versions of the integers.

mus-sample-type->string format

mus-sample-type->string converts 'format' from an integer to a string, e.g. "mus-mulaw".

> (mus-sample-type->string mus-bdouble)
"mus-bdouble"
mus-sound-chans filename

This is the number of channels in 'filename'. This value can be set (as can the others like it mentioned below); the assignment refers to the table of sound file data maintained by sndlib. The file itself is not touched, but any subsequent reference to it in Snd will assume the new value. In the mus-sound-chans case, say we have a sound file whose header claims it has 43 channels, but we know it only has 2:

(set! (mus-sound-chans "43chans.snd") 2)

tells Snd that it has 2 channels no matter what the header says.

mus-sound-close-input fd

This closes the sound file referred to by 'fd'; 'fd' is an integer returned by mus-sound-open-input. These mus-sound-* file functions refer to a direct path to read and write sound files. Any such operation is beneath the notice, so to speak, of Snd.

mus-sound-close-output fd bytes

This function closes the sound file 'fd', and updates its length indication, if any to be 'bytes' bytes. If you didn't specify a sample-type to mus-sound-open-output, it defaulted to mus-out-format. mus-out-format can currently be either ints, floats, or doubles, depending on how you've configured Snd, so it's safest to use (mus-bytes-per-sample mus-out-format) for the number of bytes per sample.

mus-sound-comment filename

mus-sound-comment returns the comment in the header of the file 'filename'.

> (with-sound (:comment "this is a comment") (fm-violin 0 1 440 .1))
"test.snd"
> (mus-sound-comment "test.snd")
"this is a comment"
mus-sound-data-location filename

This is the location in bytes of the first sample in the file 'filename'.

mus-sound-datum-size filename

This returns the size in bytes of each sample in 'filename'. It is equivalent to (mus-bytes-per-sample (mus-sound-sample-type filename)).

mus-sound-duration filename

This returns the duration in seconds of the sound data in the file 'filename'.

> (mus-sound-duration "oboe.snd")
2.30512475967407
mus-sound-forget filename

mus-sound-forget removes the file 'filename' from the sndlib sound cache.

mus-sound-framples filename

mus-sound-framples returns the number of framples of sound data in the file 'filename' according to its header (this number is occasionally incorrect in mus-next headers).

mus-sound-header-type filename

This returns the header type (e.g. mus-aifc) of the file 'filename'.

> (mus-header-type->string (mus-sound-header-type "oboe.snd"))
"mus-next"
mus-sound-length filename

mus-sound-length returns the number of bytes of sound data in the file 'filename'.

mus-sound-loop-info filename

This function refers to the "loop" info that is sometimes found in some headers (aifc, wav etc). mark-loops in examp.scm uses mus-sound-loop-info to place a mark at each loop point.

> (mus-sound-loop-info "~/sf1/forest.aiff")
(24981 144332 0 0 60 0 1 0)

The loop info is a list of up to 4 points, the first two (start, end = 24981 144332 above) refer to the sustain loop, and the second two (0 0 above) refer to the release. The 5th and 6th list entries are the base note and detune values (60 0 above). For historical reasons, the 7th and 8th entries are the sustain and release modes (1 0 above). The looper instrument uses this function to implement a sort of "freeze" function. See also sound-loop-info.

mus-sound-mark-info filename

This function refers to the "mark" info that is sometimes found in aifc and aiff headers. It returns a list of lists (or an empty list if there are no marks), each inner list being (mark-id mark-position). The mark-id is a number that identifies it for use with mus-sound-loop-info, and the mark-position is its sample number in the file. Normally, this information is already included in the mus-sound-loop-info list:

> (mus-sound-mark-info "/home/bil/sf1/forest.aiff")
((4 1) (3 0) (2 144332) (1 24981))
> (mus-sound-loop-info "/home/bil/sf1/forest.aiff")
(24981 144332 0 0 60 0 1 0)
mus-sound-maxamp filename

mus-sound-maxamp returns a list of max amps and locations thereof. The corresponding set! affects only the sndlib table of sound file info, not the sound file itself, as in all such cases.

> (mus-sound-maxamp "oboe.snd")
(24971 0.147247314453125)                  
;; oboe's maxamp is .147 first encountered at sample 24971
> (mus-sound-maxamp "2a.snd")
(933 0.0999755859375 2827 0.0999755859375) 
;; 2a's maxamps are 0.1 in each channel at sample 933 in chan 0, 2827 in chan 1
mus-sound-maxamp-exists? filename

This function returns #t if the sound's maxamp data is available in the sound cache; if it isn't, a call on mus-sound-maxamp has to open and read the data to get the maxamp.

> (mus-sound-maxamp-exists? "/home/bil/test/sound/away.snd")
#f
> (mus-sound-maxamp "/home/bil/test/sound/away.snd")
(14562264 0.463623046875 14557044 0.404571533203125)
> (mus-sound-maxamp-exists? "/home/bil/test/sound/away.snd")
#t
mus-sound-open-input filename

mus-sound-open-input opens the sound file 'filename' and returns an integer for use with mus-sound-read and mus-sound-close-input.

mus-sound-open-output filename (srate 44100) (chans 1) sample-type header-type comment

mus-sound-open-output creates a new sound file with the indicated attributes, and returns an integer for use with mus-sound-write and mus-sound-close-output.

mus-sound-preload filename

mus-sound-preload loads a sound file into memory, and uses that copy of it thereafter. If the sound data is stored in some odd format, and you use that file a lot, this can save some time.

mus-sound-prune

mus-sound-prune removes all defunct (non-existent) files from the sound cache. This is primarily intended for internal testing (snd-test.scm).

mus-sound-read fd beg-in-file num-to-read chans sd

mus-sound-read reads data from the sound file 'fd', starting at frample 'beg-in-file' (frample 0 is the first), loading num-to-read samples into the float-vector 'sd' starting from 0 in that vector.

mus-sound-reopen-output filename (chans 1) sample-type header-type data-location

mus-sound-reopen-output reopens the sound file 'filename', ready to continue writing output.

mus-sound-report-cache file

This function prints the current sound header data table to the file given or stdout if none is specified.

mus-sound-samples filename

mus-sound-samples returns the number of samples in the sound file 'filename' according to its header.

> (mus-sound-samples "oboe.snd")
50828
mus-sound-sample-type filename

mus-sound-sample-type returns the sample type (e.g. mus-bshort) of the file 'filename'.

> (mus-sample-type->string (mus-sound-sample-type "oboe.snd"))
"mus-bshort"
mus-sound-seek-frample fd frample

mus-sound-seek-frample moves the input or output reading point to 'frample' in the sound file 'fd'.

mus-sound-srate filename

mus-sound-srate returns the sampling rate of 'filename'.

mus-sound-type-specifier filename

This is the original type indication of 'filename'. This is only useful in internal testing.

mus-sound-write fd beg end chans sd

mus-sound-write writes data from the float-vector 'sd' to the sound file 'fd'.

mus-sound-write-date filename

This returns the sound's write date:

> (strftime "%d-%b %H:%M %Z" (localtime (mus-sound-write-date "oboe.snd")))
"18-Oct 06:56 PDT"

See Sndlib for more information on these functions. When called from Snd, these throw 'mus-error upon encountering an error, rather than returning -1 like the underlying sndlib functions.

The following function uses the sndlib functions to mimic the 'info' popup menu option (see examp.scm for a version that uses format):

(define info 
  (lambda (file)
    (string-append 
     file
     ": chans: " (number->string (channels file))
     ", srate: " (number->string (srate file))
     ", " (mus-header-type-name (mus-sound-header-type file))
     ", " (mus-sample-type-name (mus-sound-sample-type file))
     ", len: " (number->string 
                (/ (mus-sound-samples file) 
                   (* (channels file) (srate file)))))))
Marks

A mark is an object that refers to a particular sample. Each mark has an associated sample number (mark-sample), name (mark-name), and sync value (mark-sync). See Marks in snd.html for an overview and key bindings associated with marks. See also the hooks section above for various mark-related hooks.

add-mark sample snd chn name sync

add-mark adds a mark at the position 'sample', returning the new mark.

> (define m1 (add-mark 1234))
m1
> m1
#<mark 0>
> (mark-sample m1)
1234

The mark-name can be set via 'name', and the mark-sync field via 'sync'. If 'sample' is beyond the end of the data, add-mark throws 'no-such-sample. There is also the form add-mark! which returns #f if the sample number is beyond the current last sample, rather than throwing the 'no-such-sample error.

delete-mark mark

delete-mark deletes the mark. Mark additions and deletions follow the edit list, so if the deleted mark was present in an earlier edit, and you undo to that point, the mark comes back to life.

delete-marks snd chn

This function deletes all marks in the given channel. It could be defined in Scheme as:

(for-each delete-mark (marks (or snd (selected-sound)) (or chn (selected-channel))))
find-mark samp snd chn edpos

find-mark returns the mark at sample 'samp' or #f if none is found. If 'samp' is a string, rather than an integer, find-mark looks for a mark of that name. mark-name->id in marks.scm finds a named mark in any channel (a global version of find-mark).

integer->mark i

In olden times, a mark was handled in Snd code as an integer; nowadays, it's an object. Originally I said, "this function, and its companion mark->integer, exist mainly to convert old code to the current style", but that was premature. The mark-as-integer approach was handy because it's easy to type the mark's identifying integer. I changed from integers to mark objects to make it possible to treat marks in the various generic functions, but that meant that if you forget to save the mark object in some handy variable, you end up typing "integer->mark" over and over. One way out is to define a #-reader that sees something like "#m12" and expands that into (integer->mark 12):

> (set! *#readers*
    (cons (cons #\m (lambda (str)
                      (integer->mark (string->number (substring str 1)))))
          *#readers*))
((#\m . #<lambda (str)>))
> #m1
#<mark 1>
> (mark-sample #m1)
38694
mark->integer mark

This is the counterpart to integer->mark.

mark-color

This sets the color of mark indicator; the default is red. mark-sync-color uses mark-color to display all sync'd marks with some distinctive color.

mark-context

This is the graphics context to use to draw a mark (XOR mode).

mark-home mark

mark-home is a list with the sound and channel that hold the mark.

> (marks 0 0)   ; what marks are in snd 0, chn 0?
(#<mark 0>)            ; just one
> (mark-home (car (marks 0 0))) ; what is that mark's snd/chn?
(#<sound 0> 0)
mark-name mark

This is the name of the mark.

> (define m1 (add-mark 1234 0 0 "a name"))
m1
> (mark-name m1)
"a name"
> (set! (mark-name m1) "a new name")
"a new name"
> (mark-name m1)
"a new name"
mark-properties mark

mark-properties is a property list associated with a mark. mark-property reads and writes this list.

mark-property key mark

mark-property accesses the property 'key' in the property list associated with the mark.

> (set! (mark-property :weight m0) 2.5)   ; m0 is the mark
2.5
> (mark-property :weight m0)
2.5
mark-sample mark edpos

mark-sample is the sample number (a location) marked by the mark at edit history position 'edpos'.

> (mark-sample m1)
1234
> (set! (mark-sample m1) 4321)
4321
> (mark-sample m1)
4321

It might be more consistent with other Snd names to call this mark-position, but I wanted to emphasize that a mark follows its sample around as a sound is edited; that is, it marks a sample, not a position in the sound. Say we have three named marks in a speech excerpt (see below), then delete the initial spoken word ("now"); each mark backs up with the deletion so that it continues to point to its original sample:

marks
mark-sync mark

This is the mark's sync field (the default is 0). The sync value provides a way to group marks for simultaneous changes. Marks that share the same sync value (if not 0), move together when any one of them is dragged, play together if clicked, etc. To find which marks share a given sync value, use syncd-marks; to find an unused sync value use mark-sync-max.

Marks that are syncd together can be used for insertions, and deletions, and can set arbitrary groups of play points. But it's a bit tedious to type (set! (mark-sync ...)...) for each of the marks you want in the group. The following code example uses the mark-click-hook instead; you type (start-sync), then click each of the marks that you want grouped together, then (stop-sync).

(define mark-sync-number 0)
(define (start-sync) (set! mark-sync-number (+ (mark-sync-max) 1)))
(define (stop-sync) (set! mark-sync-number 0))
(define (click-to-sync id) (set! (mark-sync id) mark-sync-number) #f)
(hook-push mark-click-hook click-to-sync)

Now control-click and drag one of them, and all of them move together deleting data, or inserting zeros; or click the "play" triangle, and all of them play together starting from their respective samples.

mark-sync-max

This is the maximum mark sync value seen so far.

mark-tag-height

When a mark is drawn, it has a horizontal rectangle at the top, then a vertical line, then a triangle. The line marks the marked sample, the triangle can be clicked to play from the mark, and the rectangle can be clicked or dragged. The mark-tag-height refers to the vertical thickness of that tag in pixels; its default is 4.

mark-tag-width

This is the mark tag width in pixels; it defaults to 10.

marks snd chn edpos

This function returns a list of mark ids in the given channel at the edit history position 'edpos'. If 'chn' and 'edpos' are omitted, a list of lists is returned, each inner list representing a channel of 'snd'. If 'snd' is also omitted, a list of lists of lists is returned, representing each sound and its channels.

(define (how-many-marks-in-channel snd chn)
  (length (marks snd chn)))

(define (how-many-marks-in-sound snd)
  (apply + (map length (marks snd))))

(define (how-many-marks)
  (apply + (map how-many-marks-in-sound (sounds))))

If the marks function is called without any argument, or with just a sound, it returns a list of lists; each inner list is the list of current marks active in that channel, ordered by sample number. If the channel argument is specified, marks returns just the list of marks. If the edit history position is given, the list of marks reflects the marks active at that point in the edit history. See describe-mark in marks.scm.

Say we have two sounds open, 2 marks in the first (a mono sound), and one in the second channel of the second (a stereo sound):

> (marks 0 0)
(#<mark 1> #<mark 0>)     ; these are mark id's, as returned by the add-mark function for example
> (marks 1)
(() (#<mark 2>))  ; no mark in channel 0, one in channel 1
> (marks)
(((#<mark 1> #<mark 0>)) (() (#<mark 2>)))
mark? obj

mark? returns #t if 'obj' is a mark and is active (that is, if it is present in a currently open channel).

save-marks snd filename

save-marks saves the given sound's marks, writing a Scheme, Ruby, or Forth source file named either 'filename' or <sound's file-name>.marks. It returns the file name or #f if there are no marks to save.

show-marks

show-marks is #t if marks are being displayed.

syncd-marks sync

syncd-marks returns a list of marks that share the mark-sync value 'sync'.

(define (move-syncd-marks sync diff)
  (for-each 
    (lambda (m) 
      (set! (mark-sample m) (+ (mark-sample m) diff))) 
    (syncd-marks sync)))

See marks.scm for more examples including:

Marks
find mark in any sound: mark-name->id
mark history: describe-mark
synchronize marks by inserting silences: syncup
squeeze selection between marks: fit-selection-between-marks
insert silence before marks: pad-marks
move syncd marks: move-syncd-marks
play starting from syncd marks: play-syncd-marks
place marks at selection start and end: snap-marks
define selection via marks: define-selection-via-marks
force dragged mark to land on a beat: snap-mark-to-beat
split sound into separate files based on mark placement: mark-explode
mark property lists: mark-property
save mark properties in saved state file: save-mark-properties
show mark properties upon click: mark-click-info

Other examples can be found in Dave Phillips' marks-menu.scm, snd-motif.scm (add-mark-pane), edit-menu.scm (trim from mark, etc), examp.scm (move window to correspond to mark, looping).

Mixes

Mixing operations have a lot of extra support built into Snd. In nearly every mixing function, you can request a "mix tag" (or set that request globally via with-mix-tags). If the mix operation is tagged, you can then operate on that data through a number of functions, the Mix Dialog, various hooks, and various mouse-related actions.

A mix is an object that represents a channel (one channel in and one channel out) of a sound mix. Various mixing functions create these objects (mix-vct for example). In the old days, mixes were identified by integers, so for conversion you can use mix->integer and integer->mix. Say we have a mix object stored in the variable "id":

> (set! (mix-amp id) .5)
.5

This sets the mix's amplitude scaler to .5.

integer->mix i

In olden times, a mix was handled in Snd code as an integer; nowadays, it's an object. This function, and its companion mix->integer, exist mainly to convert old code to the current style.

mix->integer mix

This is the counterpart to integer->mix.

mix file samp in-chan snd chn with-mix-tags auto-delete

mix is one of the basic mixing functions. It mixes the 'in-chan' channel of the file 'file' into the given channel starting at 'samp' in the output channel, and returns a list with the mix. If 'in-chan' is #t, all input channels are mixed into successive output channels, and mix returns a list of the mixes.

If 'with-mix-tags' is #f (the default is #t), the data is mixed without creating any mix objects.

(mix "test.snd")             ; add channel 0 of test.snd to the current sound at sample 0
(mix "test.snd" 0 #t)        ; same but add all channels of test.snd into successive output channels
(mix "test.snd" 0 1)         ; add channel 1 of test.snd to channel 0 of the current sound
(mix "test.snd" 0 0 #f 1)    ; add channel 0 of test.snd to channel 1 of the current sound
(mix "test.snd" 0 3 #f 1 #f) ; add channel 3 of test.snd to channel 1 of the current sound, without a mix tag

The input file ('file') is not deleted by Snd unless 'auto-delete' is #t (or 1 or 3). auto-delete can be a boolean (#f = don't delete), or and integer: 0=don't delete, 1=delete, 3=delete but keep track of multichannel inputs.

In the next example, we mix in two sounds:

mixes

Now we can drag either of the red tags to move the mixed sounds, call up the View:Mixes dialog to edit them, or use the functions in this section. For example, we'll set the amplitude of the first and the position of the second:

mixes

We can use dlocsig in conjunction with mix to move the mixed-in sound:

(if (not (provided? 'snd-dlocsig.scm)) (load-from-path "dlocsig.scm"))
(if (not (provided? 'snd-ws.scm)) (load-from-path "ws.scm"))

(define (mix-move-sound start-time file path)
  "mix file at start-time in the currently selected sound following the given dlocsig path"
  (let* ((duration (mus-sound-duration file))
	 (rd (make-sampler 0 file))
	 (start (seconds->samples start-time))
         (tmp-sound (with-temp-sound (:channels (channels) :srate (srate file))

         ;; We use with-temp-sound here rather than sound-let because mix normally expects its input file to
         ;; be around until it decides it doesn't need it anymore, but sound-let deletes all its temp files.
         ;; We use with-temp-sound rather than with-sound because the latter would want to open the output
         ;; file in Snd; this could be turned off by including the :to-snd #f argument.

                       (let* ((vals (make-dlocsig :start-time 0
				                  :duration duration
				                  :path path))
		              (dloc (car vals))
		              (beg (cadr vals))
		              (end (caddr vals)))
		         (do ((i beg (+ i 1)))
		             ((= i end))
		           (dlocsig dloc i (read-sample rd)))))))

         ;; now tmp-sound is the name of a temp sound file that moves 'file' in a spiral

    (mix tmp-sound start #t #f #f (with-mix-tags) #t)))

;;; (mix-move-sound 0 "oboe.snd" (make-spiral-path :turns 3))
mixes snd chn

mixes returns a list of the mix objects associated with the given channel. If the channel argument is omitted, you get a list of lists, each inner list referring to a single channel of that sound. If the sound is also omitted, you get a list of lists of lists, the outer list referring to each sound, each inner list to that sound's channels. Say we have two sounds open, 2 mixes in the first (a mono sound), and 1 mix in the second channel of the second (a stereo sound):

> (mixes 0 0)
(#<mix 0> #<mix 2>)     ; these are mix objects, as returned by the mix function for example
> (mixes 1)
(() (#<mix 1>))  ; no mix in channel 0, one in channel 1
> (mixes)
(((#<mix 0> #<mix 2>)) (() (#<mix 1>)))
mix-amp mix

mix-amp is the amplitude scaler applied to the mix. To make mix mx half as loud:

(set! (mix-amp mx) .5)
mix-amp-env mix

mix-amp-env is the amplitude envelope applied to the mix (a list of breakpoints). To reset this to its default (null) state, use #f.

(set! (mix-amp-env mx) '(0 0 1 1))

sets mix mx's envelope to a ramp.

mix-color mix

This is the color of mix waveforms; it defaults to dark-gray. If you want to set just a particular mix's color, pass the mix object as the 'mix' argument: (set! (mix-color) red) sets all mix waveforms to red; but (set! (mix-color mx) red) sets only mix mx's waveform to red.

mix-length mix

mix-length returns the mix's length in samples.

mix-home mix

mix-home returns a list containing the mix's output sound and channel number, and the input original filename (if any), and input channel.

> (define mx (mix "pistol.snd" 1000))
#<mix 0>
> (mix-home mx)
(#<sound 0> 0 "/home/bil/cl/pistol.snd" 0)
;; (list output-sound-index output-channel input-filename input-channel)
> (set! mx (mix-vct (make-vct 100 .1) 2000))
#<mix 1>
> (mix-home mx)
(#<sound 0> 0 #f 0)
;;   #f: no input file
mix-name mix

mix-name is the mix's name, if any. The mix name is displayed near the mix tag. See also mix-name->id. Here's an example that uses the mix name and the tag location (mix-tag-y) to provide some pitch feedback:

(if (not (provided? 'snd-v.scm)) (load-from-path "v.scm"))
(if (not (provided? 'snd-ws.scm)) (load-from-path "ws.scm"))

(define (frequency->tag-y freq lo octs) ; tag height dependent on freq
  (round (* 100 (- 1.0 (/ (log (/ freq lo)) (* (log 2.0) octs))))))

(let ((violin-sync 1)
      (violin-color (make-color 0 0 1)) ; blue
      (cello-sync 2)
      (cello-color (make-color 0 1 0)) ; green
      (index (new-sound "test.snd" :channels 1 :size (* 44100 22))))
  
  (define (violin beg dur freq amp)
    (let ((id (mix (with-temp-sound ()                            ; write instrument output to temp sound
   	             (fm-violin 0 dur (->frequency freq #t) amp)) ; our favorite FM instrument
		(->sample beg) 0 index 0  ; mix start, file in-chan, sound, channel
                #t #t)))                  ; mix with tag and auto-delete
      (if (symbol? freq)
	  (set! (mix-name id) (symbol->string freq)))
      (set! (mix-sync id) violin-sync)
      (set! (mix-color id) violin-color)
      (set! (mix-tag-y id) (frequency->tag-y (->frequency freq #t) (->frequency 'c2) 3))))
  
  (define (cello beg dur freq amp)
    (let ((id (mix (with-temp-sound ()
   	             (fm-violin 0 dur (->frequency freq #t) amp :fm-index 1.5))
                (->sample beg) 0 index 0
  	        #t #t)))
      (if (symbol? freq)
	  (set! (mix-name id) (symbol->string freq)))
      (set! (mix-sync id) cello-sync)
      (set! (mix-color id) cello-color)
      (set! (mix-tag-y id) (frequency->tag-y (->frequency freq #t) (->frequency 'c2) 3))))
  
  (as-one-edit
   (lambda ()
     (violin 0 1 'e4 .2)  (violin 1 1.5 'g4 .2)  (violin 2.5 .5 'g3 .2)
     (cello  0 1 'c3 .2)  (cello  1 1.5 'e3 .2)  (cello  2.5 .5 'g2 .2)
     
     (violin 3 3 'f4 .2)
     (cello  3 3 'd3 .2)
     
     (violin 6 1 'e4 .2)   (violin 7 1 'g3 .2)   (violin 8 1 'e4 .2)
     (cello  6 1 'c3 .2)   (cello  7 1 'g2 .2)   (cello  8 1 'c3 .2)
     
     (violin 9 3 'd4 .2)
     (cello  9 3 'b2 .2))))
mix name example

But note names are a bother to read; musglyphs.scm has code to display notes using CMN glyphs. Here we use the draw-mix-hook to display our notes as a score:

mix CMN example

In more complex cases, using a mix per note fills the screen with mix tags; it's probably cleaner to use multiple output files, collecting related notes in one file, then mixing these at the end:

;; open two output files, one for the violin notes, the other for the cellos
;;   then mix them into "test.snd"

(let ((violins (make-sample->file "violins.snd" 1 mus-lfloat mus-next))
      (cellos (make-sample->file "cellos.snd" 1 mus-lfloat mus-next)))

  (define (violin beg dur freq amp)
    (with-temp-sound (:continue-old-file #t :output "violins.snd") 
      (fm-violin beg dur (->frequency freq #t) amp)))

  (define (cello beg dur freq amp)
    (with-temp-sound (:continue-old-file #t :output "cellos.snd") 
      (fm-violin beg dur (->frequency freq #t) amp :fm-index 1.5)))

  (violin 0 1 'e4 .2)  (violin 1 1.5 'g4 .2)   (violin 2.5 .5 'g3 .2)
  (cello  0 1 'c3 .2)  (cello  1 1.5 'e3 .2)  (cello  2.5 .5 'g2 .2)
  ;; etc

  (new-sound "test.snd" :channels 1) ; our overall output file
  (mix "violins.snd")
  (mix "cellos.snd")
  (mus-close violins)
  (mus-close cellos))

See also with-mixed-sound in ws.scm.

mix-position mix

mix-position is the current starting position (a sample number) of 'mix'. To move mix mx so that it starts at sample 200 in the output:

(set! (mix-position mx) 200)
mix-properties mix

mix-properties is a property list associated with a mix. mix-property reads and writes this list.

mix-property key mix

mix-property associates a property with a mix.

> (set! (mix-property :info mx) "this is a mix")
"this is a mix"
> (mix-property :info mx)
"this is a mix"
mix-region samp reg snd chn reg-chan

mix-region mixes region 'reg's' channel 'reg-chan' into the given channel starting at sample 'samp' ('samp' defaults to the cursor sample). It returns a list of the new mixes.

mix-selection beg snd chn selection-chan

mix-selection mixes the current selection's channel 'selection-cha' into the given channel starting at 'beg', returning a list of the new mixes. The Edit:Mix selection menu choice is essentially (mix-selection (cursor)).

mix-speed mix

mix-speed is the speed (resampling ratio) of 'mix'; 1.0 (the default) means no resampling takes place; 2.0 causes the mix data to be read twice as fast.

mix-sync mix

mix-sync is an integer, like sync that you can use to group mixes. See mix.scm for many examples. Mix objects that share a non-zero sync value drag together, and are edited together in the mix dialog.

mix-sync-max

This is the maximum mix sync value seen so far.

mix-tag-height

This is the mix tag height (the vertical extent of the tag rectangle) in pixels (the default is 14).

mix-tag-width

This is the mix tag width in pixels (the default is 6).

mix-tag-y mix

This is the mix tag y (vertical) offset; 0 (the default) is the top of the graph, so higher tag-y values position the tag lower in the graph. For example, if you know the frequency of the mix sound, you can reflect that in the tag height with:

(set! (mix-tag-y mix-id) (round (* 100 (- 1.0 (/ (log (/ freq 40.0)) (* (log 2.0) 7))))))

See, for example, check-mix-tags in sndscm.html.

mix-vct vct beg snd chn with-mix-tags origin

mix-vct is one of the basic mixing functions. It mixes the contents of 'vct' into the given channel starting at sample 'beg'. If 'with-mix-tags' is #f (the default is #t), the data is mixed without creating any mix tags. mix-vct returns the id of the new mix, or -1 (a simple mix, no tag).

mix-waveform-height

This is the maximum height in pixels of mix waveforms. The default is 20 (see show-mix-waveforms).

mix? obj

mix? returns #t if 'obj' is a mix object and it is accessible in a channel's edit list.

save-mix mix filename

save-mix saves a given mix's data in the file 'filename'.

with-mix-tags

If with-mix-tags is #f (the default is #t), newly mixed data does not have a mix id or tag associated with it.

Mixing
mix sound file: mix or drag-and-drop it where you want it mixed
mix channel: see mix-channel in extensions.scm
mix region: mix-region
mix selection: mix-selection
mix vct: mix-vct
enveloped mix: see enveloped-mix in extensions.scm
read mix samples: make-mix-sampler
mix data maxamp: mix-maxamp
mix data to vct: mix->vct
save mix data in file: save-mix
mix property list: mix-property in mix.scm
pan mono sound into stereo: see place-sound in examp.scm
move a mixed sound via dlocsig: mix-move-sound
the mix dialog: Mix Dialog
cross-fade in frequency: cross-fade and dissolve-fade in fade.scm
zipper cross-fade: zipper.scm
snap mix to beat after drag: snap-mix-to-beat
delete all mixes: silence-all-mixes
with-sound (a notelist) expanded into mixes: with-mixed-sound
Regions and Selections

A region is a saved portion of sound data. Use the View:Region browser to inspect, edit, and save regions. As regions are defined, the new ones are pushed on a stack, and if enough regions already exist, old ones are pushed off (and deleted) to make room.

forget-region reg

forget-region deletes region 'reg', removing it from the region stack. This does not affect any of the active sounds; it just tells Snd that you no longer need any access to one of the current regions. To delete all regions,

(for-each forget-region (regions))

I called this forget-region because delete-region seemed ambiguous, especially given delete-selection.

insert-region reg beg snd chn

insert-region inserts region 'reg' at sample 'beg' in the given channel. The following function uses insert-region (and other region functions) to rotate the samples in a channel:

(define* (rotate-channel (samps 1) snd chn)
  (let ((ind (or snd (selected-sound) (car (sounds))))
	(chan (or chn (selected-channel) 0)))
    (let ((reg (make-region 0 (- samps 1) ind chan)))
      (as-one-edit
       (lambda ()
	 (delete-samples 0 samps ind chan)
	 (insert-region reg (framples ind chan))))
      (forget-region reg))))
integer->region i

In olden times, a region was handled in Snd code as an integer; nowadays, it's an object. This function, and its companion region->integer, exist mainly to convert old code to the current style.

make-region beg end snd chn

make-region creates a new region spanning the samples 'beg' to 'end' in the given channel. It returns the new region. If no arguments are given, the current selection is used. If 'chn' is #t, all chans are included, taking the sync fields into account.

make-region-sampler reg start chn (dir 1)

This creates a sampler reading the region's channel 'chn' starting at sample 'start' within that region. 'dir' can be 1 (read forwards) or -1 (read backwards).

mix-region reg samp snd chn

mix-region mixes region 'reg' into the given channel starting at sample 'samp' (defaulting to the cursor location). It returns a list of mixes, one for each channel mixed.

region-chans reg

This returns the number of channels in the region 'reg'.

region-framples reg (chan 0)

region-framples returns the number of framples in the region 'reg'.

> (make-region 100 200)
#<region 1>
> (region-framples (integer->region 1))
101
region-graph-style

region-graph-style is the graph drawing choice for the region dialog's graph. The choices are:

graph-lines  graph-dots  graph-filled  graph-lollipops  graph-dots-and-lines 

graph-lines is the default.

region-home reg

This returns a list with the name of the source file for the given region, its start time in the original data, and its length in framples.

region->integer region

This is the counterpart to integer->region.

region-maxamp reg

region-maxamp is the peak amplitude of the samples in the region 'reg'.

> (region-maxamp (integer->region 1))
4.8828125e-4
region-maxamp-position reg

region-maxamp-position returns the location (a sample number) of the peak amplitude of the region 'reg'.

region-position reg chan

region-position returns the begin time of the region's channel 'chan' in the original sound.

> (make-region 1000 2000)
2
> (region-position (integer->region 2))
1000
region-sample reg samp chan

region-sample returns the value of the sample 'samp' in channel 'chan' of the region 'reg'.

region->vct reg samp samps chan v

region->vct returns a vct containing 'samps' samples starting at 'samp' in channel 'chan' of the region 'reg'. If 'v' (a vct) is provided, it is filled, rather than creating a new vct.

(define (region-rms n)
  (let* ((data (region->vct (integer->region 0) 0 #f n))
	 (len (length data)))
    (sqrt (/ (dot-product data data len) len))))
region-srate reg

region-srate returns the sampling rate of the data that makes up the region 'reg'.

regions

regions returns a list of active regions. The most recently created region is (car (regions)). (map region-framples (regions)) returns a list of region lengths. The maximum length of this list is set by max-regions.

region? reg

region? returns #t if the region 'reg' exists. There is a limit to how many regions Snd tries to keep track of (max-regions); when necessary, the least-recently created region is deleted.

save-region reg :file :sample-type :header-type :comment

save-region saves the region 'reg' in 'file' in the given sample type and header type. It returns the output filename. The following calls are equivalent:

(save-region reg "reg0.snd")
(save-region reg :file "reg0.snd" :header-type mus-next)
(save-region reg "reg0.snd" mus-bfloat mus-next "a comment")
(save-region reg :file "reg0.snd" :comment "a comment" :sample-type mus-bfloat)
Regions
Max length of region list: max-regions
Whether selection creates a region: selection-creates-region
To play region repeatedly: play-region-forever
Start region browser from Scheme: view-regions-dialog
All about regions: regions
The region dialog: region browser
Region rms amp: region-rms
region-play-list and region-play-sequence in examp.scm
convolve-selection-with file amp

convolve-selection-with convolves the current selection with 'file', replacing the selection with the result. 'amp' sets the maxamp of the result.

delete-selection

delete-selection deletes the selection, equivalent to the Edit:Delete selection menu choice.

delete-selection-and-smooth

delete-selection-and-smooth deletes the selection, then tries to make the splice smooth.

env-selection envelope env-base

env-selection applies 'envelope' to the selection. (as an amplitude envelope). 'envelope' can also be a CLM env generator; in this case, 'env-base' is ignored. These are equivalent:

(env-selection '(0 0 1 1 2 0))
(env-selection (make-env '(0 0 1 1 2 0) :length (selection-framples)))
filter-selection env order truncate

filter-selection applies an FIR filter of order 'order' and frequency response 'env' to the selection. 'env' can be the filter coefficients themselves in a vct with at least 'order' elements, or a CLM filtering generator (see filter-sound). If 'truncate' is #t (the default), the filter output is truncated at the selection end. If 'truncate' is #f, the extra output ('order' samples worth) is mixed into the stuff following the selection.

insert-selection beg snd chn

insert-selection inserts a copy of the selection starting at 'beg' in the given channel (that is, it pastes in the selection as a block). The Edit:Insert selection menu choice is essentially (insert-selection (cursor)).

mix-selection beg snd chn selection-channel

mix-selection mixes (adds) a copy of the selection starting at 'beg' in the given channel, and returns a list of the new mixes. The Edit:Mix selection menu choice is (mix-selection (cursor)).

reverse-selection

reverse-selection reverses the selection.

save-selection :file :srate :sample-type (:header-type mus-next) :comment :channel

save-selection saves the selection in 'file'. If 'channel' is given, it saves only that channel.

(define brksnd
  (let ((documentation "(brksnd dur base) divides the current sound into dur-sized pieces, 
saving them in files named 'base'.n: (brksnd 1.0 \"sec\")"))
    (lambda (dur base)
      (let ((hop (floor (* (srate) dur)))
	    (len (framples))
            (old-sync (sync)))
        (set! (sync) 1) ; save all chans
        (do ((i 0 (+ i hop))
	     (j 0 (+ j 1)))
	    ((>= i len))
          (make-selection i (+ i hop)) ; in extensions.scm
          (save-selection (string-append base "." (number->string j))))
        (set! (sync) old-sync)))))
(define* (extract-channels :rest chans)
  ;; extract a list of channels from the current sound and save as test.snd: (extract-channels 0 2)
  (let ((snd (or (selected-sound) (car (sounds)))))
    (if (sound? snd)
	(begin
	  (for-each
	   (lambda (chan)
	     (set! (selection-member? snd chan) #t)
	     (set! (selection-position snd chan) 0)
	     (set! (selection-framples snd chan) (framples snd chan)))
	   chans)
	  (save-selection "test.snd")))))
scale-selection-by scalers

scale-selection-by scales (multiplies) the selection by 'scalers' which can be either a float, a list of floats, or a vct. In a multichannel selection, each member of the vct or list is applied to the next channel in the selection. (scale-selection-by '(0.0 2.0)) scales the first channel by 0.0, the second (if any) by 2.0. (scale-selection-by 2.0) scales all channels by 2.0. Normally the order of channels follows the order of the sounds.

scale-selection-to norms

scale-selection-to normalizes the selection to peak amplitude 'norms' which can be either a float, a list of floats, or a vct.

select-all snd chn

This function selects all samples in the given channel. If a region is created, it returns the new region.

selection

selection returns an object representing the current selection, or #f if there is no active selection. The object can be passed to the generic functions to refer to the current selection:

> (define selobj (selection))
selobj
> selobj
#<selection 1>
> (selection-chans)
1
> (channels selobj)
1
selection-chans

selection-chans returns the number of channels in the current selection.

selection-framples snd chn

selection-framples returns the number of framples in the current selection (its length in samples). You can set this to move the selection end point:

> (select-all)                    ; grab all of current channel
#<region 1>
> (selection-framples)
55240
> (set! (selection-framples) 10000) ; unselect all but the starting 10000
10000
> (selection-framples)
10000
> (set! (selection-framples) (* 2 (selection-framples))) ; double the selection length
20000

See also make-selection.

selection-maxamp snd chn

selection-maxamp returns the peak amplitude of the selection in the given channel. If no arguments are passed, selection-maxamp returns the overall selection maxamp. I use this to provide a view of the selection amplitude envelope in the envelope editor. If you select 'selection' and 'wave' in that dialog, it displays a copy of whatever is in the main channel graph, so to get a display that makes it easy to "connect the dots", I use C-x m:

(bind-key #\m 0
  (lambda ()
    (set! (y-bounds (selected-sound) (selected-channel)) (list 0 (selection-maxamp))))
    #t)

(bind-key #\m 4
  (lambda ()
    (set! (y-bounds (selected-sound) (selected-channel)) (list -1.0 1.0)))
    #t)

The second key binding (C-x C-m), undoes the previous C-x m. Another useful key binding in this regard is C-x v, the built-in command to fill the current window with the selection.

selection-maxamp-position snd chn

selection-maxamp-position returns the location (a sample number) of the peak amplitude of the selection in the given channel.

selection-member? snd chn

selection-member? returns #t if the given channel has data that is currently selected. This is mostly useful when adding a channel to the current selection; see make-selection in extensions.scm. If 'snd' is #t and the new value is #f, the entire selection is deactivated.

(set! (selection-member? #t) #f)

i.e. equivalent to unselect-all.

selection->mix

selection->mix turns the current selection into a mix, or into several sync'd mixes if the selection has more than one channel.

selection-position snd chn

selection-position is the sample where selection begins. You can set this to move the selection's starting point to some arbitrary sample. If changed, the selection end point stays the same, while the length (selection-framples) changes to reflect the moved origin. See make-selection in extensions.scm.

selection-srate

This function returns the selection srate. There's some arbitrariness in this if the sounds that make up the selection have different sampling rates.

selection? obj

selection? returns #t if there is a selection. If some 'obj' is passed, selection? returns #t is obj is a selection object, and there is a selection.

> (select-all)
#<region 2>
> (selection?)
#t
> (set! (selection-member? #t) #f)
#f
> (selection?)
#f
show-selection

show-selection finds the bounds of the current selection (in all channels), and sets the time domain view to show it.

smooth-selection

smooth-selection applies a smoothing function to the selection, producing a sinusoid between the selection end points. In normal use, you'd bind this function to some key, select a portion (say a few samples) of a sound around a click, then smooth it by typing that key.

src-selection num-or-env base

src-selection applies sampling rate conversion to the selection; this is the same as src-sound but as applied to the selection.

unselect-all

If there is currently a selection, this deactivates (unselects) it.

Selections
show the current selection: show-selection
color of selected portion: selection-color
set whether creating a selection creates a region: selection-creates-region
fft graph refers to the selection: show-selection-transform
hook called when selection stops playing: stop-playing-selection-hook
swap chans in selected portion: swap-selection-channels
replace portion with selection: replace-with-selection
select portion via function: make-selection
selection members as list of lists of sound indices and channels: selection-members
rms of selection data: selection-rms
delete selection and smooth the splice: delete-selection-and-smooth
select portion between two marks: define-selection-via-marks
place marks at selection start and end: snap-marks
squeeze selection between marks: fit-selection-between-marks
delete selection and write it to a file: cut-selection->new
append selection: append-selection
write selection to a file: selection->new
notch filter selection: notch-selection
undo select-all.: deselect-all
filter the selection: filter-selection, filter-selection-and-smooth
turn the selection into a mix: selection->mix
unselect everything: unselect-all

The selected portion can be chosen, independent of any region, by setting selection-position and selection-framples. It's easy to extend the notion of a selection to an arbitrary list of sound portions:

(define (make-section . members)
  ;; each member is '(beg dur snd chn)
  (append (list 'Section) members))

(define (section-for-each func section)
  ;; call func on each member of the section
  (as-one-edit (lambda () (for-each func (cdr section)))))

;; an example that scales each member of the section by .5
(section-for-each 
 (lambda (sect)
   (apply scale-channel (append (list .5) sect)))
 (make-section (list 0 10000 0 0) (list 30000 10000 0 0)))
Sounds and channels

This is the heart of Snd; we've waded through all the ancillary junk, and we've finally reached the functions that actually edit sounds! Most of these functions take both a sound and a channel number. When the function refers to a variable that can be set locally on a sound (zero-pad, for example), the 'snd' and 'chn' arguments can be #t, referring to all current sounds or all channels of a sound. In cases where it makes sense, if the 'snd' argument is omitted, the reference is to the global default value. So, (set! (amp-control-bounds) '(0.0 2.0)) sets the global amp control (slider) bounds to be between 0.0 and 2.0, whereas (set! (amp-control-bounds snd) '(0.0 2.0)) sets it only for the sound referred to by 'snd'.

Many of the procedures also have an 'edpos' argument (standing for "edit position"). It always defaults to the current edit history position. If specified, it can be either an edit history position (to which the operation is applied), or the constant current-edit-position.

For not-very-good historical reasons (it took me awhile to decide how to organize things), some of the procedures here are unnecessarily inconsistent in what arguments they accept, whether a channel of #t signals application to all channels or just the selected one, whether the sync field is followed, and so on. Rather than make a bunch of backwards incompatible changes, I decided to add a bunch of more-or-less synonymous functions that regularize these calls. The replacements always take arguments in the order begin time, duration (not end sample), sound, channel number, and edit position, possibly preceded by one argument, and sometimes followed by an edit history name or 'ring time' (overlap). The sync field is ignored, an unspecified sound argument applies only to the current sound, and an unspecified channel argument applies only to the current channel. The following substitutions can be made:

convolve-with file amp s c e                    clm-channel convolve-gen beg dur s c e
env-sound env beg dur base s c e                env-channel env beg dur s c e
filter-sound env order s c e                    filter-channel env order beg dur s c e trunc
insert-silence beg dur s c                      pad-channel beg dur s c e
insert-sound file beg filechn s c e             insert-channel filedat beg dur s c e
mix file beg filechn s c with-tags              mix-channel filedat beg dur s c e
redo edits s c                                  redo-channel edits s c
reverse-sound s c e                             reverse-channel beg dur s c e
scale-by scls s c                               scale-channel scl beg dur s c e
scale-to scls s c                               normalize-channel norm beg dur s c e
set-samples beg dur data s c trunc origin fchan vct->channel vct beg dur s c e
smooth-sound beg dur s c                        smooth-channel beg dur s c e
src-sound num base s c e                        src-channel ratio-or-env beg dur s c e
undo edits s c                                  undo-channel edits s c
apply-ladspa reader dat dur origin snd chn      ladspa-channel dat beg dur s c e

Another case that might deserve "regularization" is make-sampler which confusingly interpolates the direction argument between the channel and edit-position:

(define* (read-channel (beg 0) snd chn edpos (direction 1))
  (make-sampler beg snd chn direction edpos))

The edit position argument can cause ambiguity in a few cases. What should Snd do with: (pad-channel 100 0 snd chn 2)? It currently treats any 0-length operation as a no-op, so the edit history is not changed by this function call. However, in a similar situation (where the current edit counter is greater than 2, so this code is reaching back into the edit history list): (scale-channel 1.0 0 #f snd chn 2) Snd essentially copies the state of the channel at that edit position, and puts it in the current edit position. There's never any good reason to do this, so if it looks like a no-op, do it a different way.

add-player player start end edpos stop-proc out-chan

add-player adds 'player' to the play-list (see make-player). If 'edpos' is given, play at that edit position. 'stop-proc' can be a procedure of one argument; it is called when the play process stops and passed the reason the play is stopping; it will be 0 if the play completed normally (the other possibilities are listed here, but they really aren't interesting). The 'out-chan' argument is the audio output channel to send the data to; it defaults to the channel number of the player's channel in the containing sound (that is, the default is to send channel 1 data to channel 1 of the DAC, and so on). See play-with-envs in enved.scm, play-syncd-marks in marks.scm, or start-dac in play.scm.

axis-info snd chn grf

axis-info returns a list describing the specified axis:

(list left-sample right-sample 
      x0 y0 x1 y1 x-min y-min x-max y-max 
      x0-position y0-position x1-position y1-position y-offset 
      xlabel ylabel new-peaks)

This can be useful if you're drawing arbitrary figures in a graph. 'grf' defaults to time-graph; the other choices are transform-graph and lisp-graph. 'x0' is the time in seconds corresponding to the left-sample (the left edge of the graph). Similarly 'y0' is the lower y axis limit as a sample value (i.e. -1.0). 'x-max' is the sound's duration in seconds ('x-min' is always 0.0). The "positions" are pixel values, in drawing area coordinates; these give the position of the graph in the drawing area. 'y-offset' refers to "united" graphs where several channels share one drawing area. You can use it to translate mouse coordinates to channel number in that situation. For example, x->position could be:

(define (x->position-1 x snd chn)
  (let* ((axinfo (axis-info snd chn time-graph))
	 (x0 (axinfo 2))
	 (x1 (axinfo 4))
	 (axis-left (axinfo 10))
	 (axis-right (axinfo 12)))
    (floor
     (+ axis-left
	(* (- x x0) 
	   (/ (- axis-right axis-left)
	      (- x1 x0)))))))

Here's a key binding that uses axis-info to save every channel's graph position upon "Page Down", then restore that state upon "Page Up":

(bind-key "Page_Down" 0 
	  (lambda ()
	    (let ((last-page-state 
	            (map (lambda (snd) 
			   (let ((data (list snd (file-name snd))))
			     (do ((i 0 (+ i 1)))
 				 ((= i (channels snd)) data)
			       (set! data (append data (list (cons i (axis-info snd i))))))))
		         (sounds))))
	      (bind-key "Page_Up" 0
			(lambda ()
			  (if last-page-state
			      (for-each
			       (lambda (lst)
				 (let ((snd (lst 0))
				       (name (lst 1)))
				   (if (and (sound? snd) 
					    (string=? (file-name snd) name))
				       (for-each
					(lambda (chan-data)
					  (let ((chn (chan-data 0))
						(x0 (chan-data 3))
						(x1 (chan-data 5))
						(y0 (chan-data 4))
						(y1 (chan-data 6)))
					    (set! (x-bounds snd chn) (list x0 x1))
					    (set! (y-bounds snd chn) (list y0 y1))))
					(cddr lst)))))
			       last-page-state)))))))
beats-per-measure snd chn

The x axis labelling of the time domain waveform can be in measures (x-axis-style = x-axis-in-measures); this variable sets the number of beats per measure. The default is 4.

beats-per-minute snd chn

The x axis labelling of the time domain waveform can be in beats (x-axis-style = x-axis-in-beats) or in measures (x-axis-in-measures); this variable sets the number of beats per minute. The default is 60.0, making it the same as x-axis-in-seconds. See snap-mark-to-beat, or snap-mix-to-beat.

channel-amp-envs file chan size peak-file-func work-proc-func

channel-amp-envs returns two vcts of length 'size' containing the peak-amp envelopes of the channel 'chan' of file 'file'. 'peak-file-func' (if any) is used to get the name of the associated peak-env file if the file is very large. 'work-proc-func' is called when the amp envs are ready if the amp envs are gathered in the background. If 'file' is a sound, 'size' is an edit-position, and the current amp envs (if any) are returned. The arguments to 'peak-file-func' are the file and the channel. If it returns a string, that is treated as the filename to read to get the peak info. The arguments to 'work-proc-func' are the filename, the channel and the current peak. make-sound-icon in make-sound-box in snd-motif.scm uses this function to draw the little thumbnail graph for each sound icon.

channel-data snd chn

channel-data provides very low-level access to the data currently in the given channel's sample buffers. It is used by the variable-display mechanism to show graphs of variable values (normally in an instrument). channel-data only works with sounds returned by make-variable-display, and only in a float-sample version of Snd (i.e. not one that was built with the configure argument --without-float-samples). See make-variable-display in snd-motif.scm.

channel-properties snd chn

channel-properties is a property list associated with a channel. It is set to () at the time a sound is opened, so it provides a relatively simple way to save data about a channel which will automatically be erased when the channel is closed. channel-property reads and writes this list.

Traditionally in Lisp, a property list has been treated as an association list. This is a list of pairs (made by cons), each inner pair having a key as its first element, and the associated value as the second element. The function assoc can be used to search the list for a given key's value; a new key-value pair can be added with:

(cons (cons key value) a-list)

In Common Lisp, property lists have other properties, so to speak, but channel-properties (and sound-properties) can be handled in any way you like. See channel-sync in extensions.scm for a brief example; more elaborate examples are in enved.scm (enved-envelope), or draw.scm (colored-samples and insert-envelope).

channel-property key snd chn

channel-property returns the value associated with 'key' in the given channel's property list. To add or change a property, use set! with this procedure.

Scheme:
> (set! (channel-property 'info 0 0) "this is sound 0, first channel")
"this is sound 0, first channel"
> (channel-property 'info 0 0)
"this is sound 0, first channel"

Ruby:
>set_channel_property(:info, "this is info", 0, 0)
this is info
>channel_property(:info, 0, 0)
this is info

Forth:
>'info "this is info" 0 0 set-channel-property
'( '( 'info . this is info ) )
>'info 0 0 channel-property
this is info

The property list is convenient because the associated information goes away automatically when the channel is closed, and the property lists are saved by save-state.

channel-style snd

channel-style reflects the value of the 'unite' button in multichannel files. Possible values are channels-separate, channels-combined (the default), and channels-superimposed. The following code sets the 'unite' button if the current sound has more than 4 channels:

(hook-push after-open-hook 
  (lambda (hook)
    (if (> (channels (hook 'snd)) 4)
        (set! (channel-style (hook 'snd)) channels-combined))))
channel->vct beg dur snd chn edpos

channel->vct returns a vct with the specified data. In Ruby, the "->" in a function name is translated to "2", so the function call is:

    v = channel2vct(0, 100)
(define* (selection->vct snd chn)
  (if (selection-member? snd chn)
      (channel->vct (selection-position snd chn)
		    (selection-framples snd chn)
		    snd chn)
      (if (selection?)
          (error 'no-such-channel 
                 (list "selection->vct"
     	               (format #f "snd ~A channel ~D is not a member of the selection" snd chn)))
	  (error 'no-active-selection (list "selection->vct")))))

See also mark-explode in marks.scm.

channels snd 
chans snd

This function returns the number of channels in 'snd'. It can be set, but the result is a new version of the underlying sound with the header changed to reflect the new number of channels. That is, no new data is created, but the existing data is reapportioned to the new channels: (set! (channels) 2); this is not undo-able (except by calling it again with the original number of channels — the data is not touched).

clm-channel clm-gen beg dur snd chn edpos overlap origin

clm-channel applies 'clm-gen' to the given channel starting at sample 'beg' for 'dur' samples, and 'overlap' samples of 'ring time'. This is used by some of the regularized functions, but it can also be used directly:

(define* (convolve-channel kernel nbeg ndur nsnd nchn nedpos)
  (let* ((beg (or nbeg 0)) 
	 (snd (or nsnd (selected-sound) (car (sounds))))
	 (chn (or nchn (selected-channel)))
	 (dur (or ndur (- (framples snd chn) beg)))
	 (edpos (or nedpos current-edit-position))
	 (reader (make-sampler beg snd chn 1 edpos))
	 (cgen (make-convolve :filter kernel 
                              :input (lambda (dir)
				       (read-sample reader)))))
    (clm-channel cgen beg dur snd chn edpos)
    (free-sampler reader)))

(define (difference) (clm-channel (make-two-zero 1 -1)))
(define (wobble) (clm-channel (make-ncos 50 3)))
(define (hold-nose) (clm-channel (make-ncos 1 3)))
(define (bad-reception) (clm-channel (make-ncos 10 5)))
close-sound snd

This closes 'snd' (the same as the File:Close menu item). To close all sounds:

(close-sound #t) 
;; equivalent to:
(for-each close-sound (sounds))

Before the sound is actually closed, before-close-hook is called, then close-hook, then the sound is closed.

comment snd

This returns the sound's comment, if any; when a sound is opened, the comment is taken from the file's header (the same as mus-sound-comment). If you set it, the header is not updated until the sound is saved. If the new comment is the only change you want to make, you can save the new header via the Edit:Edit Header menu option.

convolve-with file amp snd chn edpos

This convolves the given channel (or the currently sync'd data) with the data in the sound file 'file'. 'amp' is the resultant peak amplitude (leave 'amp' unset, or set it to #f to get the unnormalized result). Convolve-with in conjunction with mix can provide high-quality reverb:

(define conrev
  (lambda (impulse amp)
    (convolve-with impulse amp)
    (save-sound-as "reverb.snd") ;let mix scalers set reverb amount
    (revert-sound)
    (mix "reverb.snd")))
count-matches proc sample snd chn edpos

count-matches returns how many samples satisfy the function 'proc'; 'proc' should take one argument (the current sample value), and return #t for a hit. 'sample' determines where to start the search.

Scheme: (count-matches (lambda (y) (> y .1)))
Ruby:   count_matches(lambda do |y| y > 0.1 end)
Forth:  lambda: <{ y }> y 0.1 f- f0< ; count-matches

count-matches is obsolete; use a do loop and a sampler:

(define* (count-matches func (beg 0) snd chn edpos)
  (let ((end (framples snd chn edpos))
	(matches 0)
	(reader (make-sampler beg snd chn 1 edpos)))
    (do ((i beg (+ i 1)))
	((= i end) matches)
      (if (func (next-sample reader))
	  (set! matches (+ matches 1))))))
cursor snd chn edpos

This returns the cursor location (as a sample number; the first sample is numbered 0) in channel 'chn' of 'snd'. (set! (cursor) 100) moves the cursor to sample 100. The cursor is somewhat similar to a mark in that it moves if you delete or insert samples in front of it. To turn the cursor off, set it to some negative number.

Cursor
Tracking cursor: with-tracking-cursor
Change cursor shape or size: cursor-style, cursor-size
Cursor moving keys: Moving the Cursor
Display data about sample under cursor: with-verbose-cursor
play from the current cursor position with a tracking cursor: pfc
display tracking cursor as a full height vertical line: tracking-cursor-style
track play once: control-click 'play'. (You can add a mark at the current tracking cursor location during the play with C-m)
leave the cursor at the final position after tracking play: (set! *with-tracking-cursor* :track-and-stay)
tracking cursor accuracy: cursor-location-offset
tracking cursor updating: cursor-update-interval
cursor-position snd chn

This gives the current cursor position as a list (x y). These graph-relative values can be turned into axis-relative values with position->x and position->y:

(position->x (car (cursor-position)))
;; equals:
(/ (cursor) (srate))
cursor-size snd chn

This gives the cursor size in pixels; it defaults to 15. (set! (cursor-size) 30) makes the cursor twice as big as usual.

cursor-style snd chn

The cursor style is cursor-cross, cursor-line, or a cursor-drawing function. The default cursor shape is a "+" sign; the cursor-line is a vertical line. As a function, cursor-style is a procedure of three arguments, the sound, channel number, and a boolean that is true if the cursor is currently tracking playback (a "tracking-cursor"). The procedure should draw the cursor at the current cursor position using the cursor-context. Here is a simpler one that replaces the normal "+" cursor with an "x":

(define (x-cursor snd chn ax)
  (let* ((point (cursor-position))
         (x (car point))
         (y (cadr point))
         (size (cursor-size))
         (cr (make-cairo (car (channel-widgets snd chn))))) ; needed in Gtk, ignored in Motif
    (draw-line (- x size) (- y size) (+ x size) (+ y size) snd chn cursor-context cr)    
    (draw-line (- x size) (+ y size) (+ x size) (- y size) snd chn cursor-context cr)
    (free-cairo cr)))

(set! (cursor-style) x-cursor)
data-location snd

This gives the location (in bytes) of the sound samples in the file represented by 'snd'. In a raw (headerless) file, this is 0, but normally the data comes after some portion of the header. To get the data-location of some sound file, use mus-sound-data-location. If you set this field (you don't want to do this — it is a law of nature that you will forget the original setting!), the underlying file is immediately rewritten.

data-size snd

This gives the size (in bytes) of the sound data in the file represented by 'snd'. If you set this field, the underlying file is immediately rewritten (the header is changed; I don't think the file is truncated, but no matter what happens, it is not my fault). Next/Sun files treat the size field as purely "advisory", so an incorrect data size is often ignored in that case.

delete-sample samp snd chn edpos

This deletes sample 'samp' in the given channel.

Deletions
delete a file: in scheme delete-file or Ruby's File.delete
delete a region: forget-region
delete the currently selected samples: delete-selection
delete the selection and smooth the splice: delete-selection-and-smooth
delete a mark or all marks: delete-mark
delete a colormap: delete-colormap
delete samples: delete-samples
delete samples and smooth over the splice: delete-samples-and-smooth
remove a file from the sound cache: mus-sound-forget
remove a menu item: remove-from-menu or remove-main-menu in snd-motif.scm
delete a mix or all mixes: silence-mixes
add a 'delete' option to the file selection dialog: add-delete-option
Scheme delete funcs: remove-if assoc-remove! hash-remove! delete-if! delete! string-delete
delete-samples samp samps snd chn edpos

This deletes a block of samples. The deleted portion starts at sample 'samp' and runs for 'samps' samples.

delete-samples-and-smooth samp samps snd chn edpos

This deletes a block of samples, then tries to smooth over the splice. The deleted portion starts at sample 'samp' and runs for 'samps' samples.

dot-size snd chn

This gives the size in pixels of dots when graphing with dots (default: 1); this affects graph-styles such as graph-lollipops. See graph-hook or auto-dot in examp.scm.

env-channel clm-env-gen beg dur snd chn edpos

env-channel is the regularized version of env-sound. 'clm-env-gen' can be either a CLM envelope generator or an envelope (a list of breakpoints). (env-channel '(0 0 1 1 2 0)). To get .1 seconds of attack and decay:

(let ((dur (/ (framples) (srate)))) 
  (env-channel (list 0 0  .1 1  (- dur .1) 1  dur 0)))

An envelope in Snd is a list of breakpoints. It can be packaged as a CLM generator (an 'env') via make-env. It can be declared via define just like any other variable, or with define-envelope.

Envelopes
envelope sound: env-channel, env-sound
Other enveloping functions: ramp-channel, xramp-channel, smooth-channel
The CLM env generator: env, many examples in examp.scm, new-effects.scm, etc
Various operations on envelopes: env.scm
The envelope editor: Edit or View and Envelope
Panning: place-sound in examp.scm
Envelope over mix: enveloped-mix
Local envelope editor: enved.scm, xm-enved.scm
Read sound indexed through envelope: env-sound-interp
Cosine as envelope: cosine-channel, bell-curve
envelope with sinusoidal connections between points: sine-env-channel
envelope with separate base for each segment: powenv-channel
envelope with x^2 connections: env-squared-channel
envelope with x^n connections: env-expt-channel
envelope with ncos connections: blackman4-env-channel
Customizing the envelope editor: enved-hook
peak amp follower: moving-max
env-channel-with-base envelope-or-env-gen base beg dur snd chn edpos

env-channel-with-base is a slight variation on env-channel. There are times when it's a bother to call make-env just to get an exponential envelope.

env-sound envelope samp samps env-base snd chn edpos

env-sound applies the amplitude 'envelope' to the given channel starting at sample 'samp' for 'samps' samples with connecting segments based on 'env-base'. 'env-base' defaults to 1.0. 'samp' defaults to 0. 'samps' defaults to the full duration. 'envelope' is a list containing the breakpoint values (as in CLM) or an env generator.

ampenvs ampenvs
Scheme: (env-sound '(0 0 1 1 2 0))
Ruby:   env_sound([0.0, 0.0, 1.0, 1.0, 2.0, 0.0])
Forth:  '( 0.0 0.0 1.0 1.0 2.0 0.0 ) env-sound

As mentioned in sndclm.html, 'env-base' determines how the break-points are connected. If it is 1.0 (the default), you get straight line segments. 'env-base' = 0.0 gives a step function (the envelope changes its value suddenly to the new one without any interpolation). Any other positive value becomes the exponent of the exponential curve connecting the points. 'env-base' < 1.0 gives convex curves (i.e. bowed out), and 'env-base' > 1.0 gives concave curves (i.e. sagging). If you'd rather think in terms of e^-kt, set 'env-base' to (exp k). See env.lisp for a CLM instrument that shows the relation between the connecting curve's exponent and 'env-base'. Here's a brief restatement:

(define (compare-exp k)
   (let ((e (make-env (list 0 1 1 (exp (- k))) :base (exp k) :length 11)))
      (do ((i 0 (+ 1 i )))
         ((= i 10))
         (snd-print (format #f "~A ~A~%" (env e) (exp (* (- k) (/ i 10.0))))))))

If 'envelope' is a CLM env generator, 'env-base' is ignored.

fft-log-frequency snd chn

This returns whether the spectrum frequency axis is logarithmic (#t) or linear (#f, the default). If logarithmic, the lower end is set by log-freq-start which defaults to 32Hz.

fft-log-magnitude snd chn

This returns whether the spectrum magnitude axis is in decibels (#t) or linear (#f, the default). If in decibels, the minimum displayed is set by min-dB which defaults to -60.

fft-window snd chn

This sets the choice of fft data window (default: blackman2-window)

bartlett-hann-window     bartlett-window        blackman2-window       blackman3-window
blackman4-window         bohman-window          cauchy-window          connes-window       
dolph-chebyshev-window   exponential-window     flat-top-window        gaussian-window     
hamming-window           hann-poisson-window    hann-window            kaiser-window
parzen-window            poisson-window         rectangular-window     riemann-window      
samaraki-window          tukey-window           ultraspherical-window  welch-window        
blackman5-window         blackman6-window       blackman7-window       blackman8-window       
blackman9-window         blackman10-window      rv2-window             rv3-window
rv4-window               mlt-sine-window        papoulis-window        dpss-window
sinc-window

The Hann window is sometimes called Hanning in the DSP literature, apparently as an in-joke. For an extensive discussion of these windows, see Fredric J. Harris, "On the Use of Windows for Harmonic Analysis with the Discrete Fourier Transform", Proceedings of the IEEE, Vol. 66, No. 1, January 1978, with updates from: Albert H. Nuttall, "Some Windows with Very Good Sidelobe Behaviour", IEEE Transactions of Acoustics, Speech, and Signal Processing, Vol. ASSP-29, 1, February 1981, and of course, Julius Smith's DSP web site.

fft-window-alpha snd chn

The ultraspherical window has two "family" parameters; the one named "mu" is called "beta" here, to parallel its use in related windows; the other one, named "xmu" is named "alpha" here, for no good reason. fft-window-alpha sets the shape of the side lobes; see "Design of Ultraspherical Window Functions with Prescribed Spectral Characteristics", Bergen and Antoniou, EURASIP JASP 2004 (also available on-line) for details.

fft-window-beta snd chn

Some fft windows have a parameter, often named alpha or beta, that chooses one from a family of possible windows. The actual (underlying) beta values are dependent on the window choice, but in Snd, fft-window-beta is scaled to fit the current window's range of values, so its value here should fall between 0.0 and 1.0.

fft-with-phases snd chn

This returns whether the single FFT display includes phase information (the default is #f).

file-name snd

This returns the sound's complete (or "absolute") file name; the directory is included; see short-file-name if you don't want all the directory junk. See examp.scm for many examples.

filter-channel env order beg dur snd chn edpos trunc origin

The regularized version of filter-sound. If the end of the filtered portion is not the end of the sound, the 'trunc' argument determines whether the filtered sound is truncated at that point (the default: #t), or mixed with the overlapping section, similar to the truncate argument to filter-selection. 'env' can be either the frequency response envelope, or a vct containing the desired coefficients.

filter-sound env order snd chn edpos origin

filter-sound applies an FIR filter of order 'order' (actually one more than the nominal order) and frequency response 'env' to the given channel. 'env' can also be a vct containing the filter coefficients, or any CLM filtering generator (e.g. comb, formant, one-pole, iir-filter, etc). The generator is called in C, not Scheme, so this is the fastest way to apply CLM filtering to a sound. See also clm-channel.

(filter-sound '(0 1 1 0) 1024)                             ; FIR filter given frequency response
(filter-sound (float-vector .1 .2 .3 .3 .2 .1) 6)                   ; FIR filter given actual coefficients
(filter-sound (make-fir-filter 6 (float-vector .1 .2 .3 .3 .2 .1))) ; CLM FIR filter
(filter-sound (make-delay 120))                            ; CLM delay (same as insert-silence)
(filter-sound (make-formant 1200 .99))                     ; CLM formant
(filter-sound (make-filter 2 (float-vector 1 -1) (float-vector 0 -0.99)))    ; remove DC

If you want to use the cascade filter structure, rather than the canonical form of CLM's filter generator:

(define (make-biquad a0 a1 a2 b1 b2)
  (make-filter 3 (float-vector a0 a1 a2) (float-vector 0.0 b1 b2)))

If you have coefficients for the cascade form, but have no scruples about using some other form, see cascade->canonical in dsp.scm, and the examples that follow.

Filters
filter a sound: filter-sound, filter-channel, and clm-channel
filter the selection: filter-selection, filter-selection-and-smooth
CLM filter generators: filter, one-pole, formant, comb, notch, all-pass, etc
lowpass filter: make-lowpass in dsp.scm
highpass filter: make-highpass in dsp.scm
bandpass filter: make-bandpass in dsp.scm
bandstop filter: make-bandstop in dsp.scm
the usual analog filters (Butterworth, Chebyshev, Bessel, Elliptic): analog-filter.scm
Butterworth filters: make-butter-high-pass, make-butter-low etc in dsp.scm, used in new-effects.scm
IIR filters of various orders/kinds: dsp.scm
Hilbert transform: make-hilbert-transform in dsp.scm
differentiator: make-differentiator in dsp.scm
block DC: see example above, dc-block in prc95.scm, or stereo-flute in clm-ins.scm
hum elimination: see eliminate-hum and notch-channel in dsp.scm
hiss elimination: notch-out-rumble-and-hiss
smoothing filters: moving-average, weighted-moving-average, exponentially-weighted-moving-average
notch-filters: notch-channel and notch-selection
arbitrary spectrum via FIR filter: spectrum->coeffs in dsp.scm
invert an FIR filter: invert-filter in dsp.scm
filtered echo sound effect: flecho in examp.scm
time varying filter: fltit in examp.scm
draw frequency response: use envelope editor or filter control in control panel
Moog filter: moog.scm
Savitzky-Golay filter: savitzky-golay-filter
Click reduction: remove-clicks, clean-channel
Max Mathews resonator: firmant, maxf.scm, maxf.rb
Spectral edit dialog: Envelope Editor
graphical equalizer filter bank: graphEq
nonlinear (Volterra) filter: volterra-filter
Kalman filter: kalman-filter-channel
see also convolution, physical modeling, reverb, and fft-based filtering
Searches
find a mark: find-mark
find a mix: find-mix
find a sound: find-sound
Example find procedures: search-for-click, zero+, next-peak, find-pitch
Default search procedure: search-procedure
The Find dialog: Find or find-dialog
find silence: map-silence, scramble-channel in examp.scm
find any difference between two chans: channels-equal
find a widget: find-child in snd-motif.scm
add C-s and C-r to the listener key bindings: add-find-to-listener in snd-motif.scm
Scheme find: find-if
find-sound filename nth

find-sound returns the sound object of 'filename' or #f if no sound is found that matches 'filename'. If there is (or might be) more than one file open with the given filename, the 'nth' parameter (which defaults to 0) chooses which to return. Leaving aside the 'nth' parameter, find-sound could be defined as:

(define (find-sound name)
  (call-with-current-continuation
   (lambda (return)
     (for-each 
      (lambda (snd)
	(if (or (string=? (short-file-name snd) name)
		(string=? (file-name snd) name))
	    (return snd)))
      (sounds))
     #f)))

See files-popup-buffer, open-next-file-in-directory, and the "Buffer Menu" code in examp.scm.

finish-progress-report snd chn

This ends an on-going progress report (a visual indication of how far along some time-consuming process is). See progress-report.

framples snd chn edpos

This returns current length in samples of the channel 'chn'. Used with set!, this either truncates the sound or pads it with zeros at the end.

free-player player

free-player frees all resources associated with 'player' and remove it from the play-list.

graph data xlabel x0 x1 y0 y1 snd chn force-display show-axes-choice

This function displays a graph of 'data' in a separate display per channel. The x axis is labelled 'xlabel', the x axis units go from 'x0' to 'x1' (the default is 0.0 to 1.0), the y axis goes from 'y0' to 'y1' (the default fits the data), and the display is associated with channel 'chn' in 'snd'.

(graph (float-vector 0 .1 .2 .3 .4 .3 .2 .1 0) "roof")

The current slider values can be read from x-position-slider, x-zoom-slider, etc. The 'data' argument can be a list of vcts; each is graphed at the same time, following the sequence of colors used when channels are superimposed. If 'data' is a list of numbers, it is assumed to be an envelope (a list of breakpoints). If 'force-display' is #f (the default is #t), the graph is not explicitly drawn; this is useful when you're calling graph from the lisp-graph-hook, where the redisplay is automatic. 'show-axes-choice' sets the show-axes choice for the lisp graph.

(define display-energy
  ;; y-zoom-slider controls the graph amp
  (lambda (snd chn)
    (let* ((ls (left-sample))
           (rs (right-sample))
	   (datal (make-graph-data snd chn))
	   (data (if (float-vector? datal) datal (cadr datal)))
           (sr (srate snd))
	   (y-max (y-zoom-slider snd chn)))
      (float-vector-multiply! data data)
      (graph data "energy" (/ ls sr) (/ rs sr) 0.0 (* y-max y-max) snd chn #f))))

(hook-push lisp-graph-hook (lambda (hook) (display-energy (hook 'snd) (hook 'chn))))
picture of examp.scm in action
graph-style snd chn

graph-style determines how sound data is displayed (default: graph-lines). The choices are:

graph-lines  graph-dots  graph-filled  graph-lollipops  graph-dots-and-lines 

In the set! case, if no 'snd' is specified, all graph-styles are set to the new value. If 'snd' is given, the three graph styles for that sound's channels (or channel 'chn') are set. See time-graph-style, lisp-graph-style, and transform-graph-style to override the default for a specific graph.

graphs-horizontal snd chn

This determines whether channel graphs (the time domain, spectrum, and lisp graphs) are arranged vertically or horizontally (the latter is the default).

grid-density snd chn

This controls the spacing of axis ticks; the default is 1.0. If grid-density is less than 1.0, more ticks are squeezed in; if greater than 1.0, fewer ticks are displayed. This mainly affects the grid display (show-grid).

header-type snd

This returns the header type (e.g. mus-aiff) of the file that underlies 'snd'. Snd can read about 60 header types, and write 7 or so. "aiff" and "aifc" come from Apple, "riff" is the Microsoft "wave" header, "rf64" is the European Broadcast Union's 64-bit RIFF replacement, "nist" comes from the NIST-Sphere package, "next" or "sun" is the Next/Sun (".au") header, "ircam" is IRCAM's extension of the Next header, "caf" is Apple's 64-bit AIFC replacement, and "raw" means the sound file has no header. If you change the header type to "raw", any existing header is removed. Each header type has its own peculiarities; if in doubt, use mus-next because it is simple, and can handle any sample type that Snd can write (whereas each of the others is restricted in this regard). The writable header types are mus-next, mus-nist, mus-aiff (obsolete, rarely needed), mus-aifc, mus-riff, mus-rf64, mus-caff, mus-ircam, and mus-raw (no header). For technical descriptions of the headers, see headers.c; for actual sound files, see sf.tar.gz at ccrma-ftp.

To turn a header type number into a string, use mus-header-type-name. To get the header type of some sound file, use mus-sound-header-type. If you set the header-type, the sound file is rewritten with the new header. The default output (new-sound, and save-sound-as) header type is default-output-header-type.

To read or write your own headers (or some header that isn't built-in), I recommend using either open-hook or open-raw-sound-hook: in the latter case, when you open the file with the unsupported header, Snd will throw up its hands and say "maybe it's a raw (headerless) sound"; it will then look at open-raw-sound-hook before trying other fallbacks (such as the Raw File Dialog). See examp.scm or misc.scm (MPEG, OGG, etc).

insert-sample samp value snd chn edpos

This inserts sample 'value' at sample 'samp' in the given channel

Insertions
insert some portion of a channel: insert-channel
insert a silence: pad-channel, insert-silence, pad-sound
insert a region: insert-region
insert the selection: insert-selection
insert a vct of samples: insert-samples
insert a sound: insert-sound
append a sound and silence: append-sound
insert-samples samp samps data snd chn edpos auto-delete origin

This inserts 'samps' samples of 'data' (normally a vct) starting at sample 'samp' in the given channel. 'data' can be a filename. The regularized version of this is:

(define* (insert-channel data beg dur snd chn edpos)
  (insert-samples beg dur data snd chn edpos))

To insert a block of samples of a given value: (insert-samples beg dur (make-float-vector dur val)) If 'data' is a file, it is not deleted by Snd unless 'auto-delete' is #t.

insert-silence beg num snd chn

This inserts 'num' zeros at 'beg' in the given channel. pad-channel is the regularized version, with one small change: insert-silence forces 'beg' to be within the current sound, but pad-channel pads out to 'beg' if 'beg' is past the end of the sound. (And, as usual in these cases, insert-silence follows the sync field, whereas pad-channel ignores it).

insert-sound file beg in-chan snd chn edpos auto-delete

This inserts channel 'in-chan' of 'file' at sample 'beg' in the given channel. 'beg' defaults to the cursor position; if 'in-chan' is not given, all channels are inserted. To append one sound to another, padding at the end with some silence:

(define* (append-sound file (silence 1.0))
  (insert-sound file (framples))
  (insert-silence (framples) (round (* (srate) silence))))

'file' is not deleted by Snd unless 'auto-delete' is #t.

integer->sound i

In olden times, a sound was handled in Snd code as an integer; nowadays, it's an object (although the integer approach still works). This function, and its companion sound->integer, exist mainly to convert old code to the current style.

left-sample snd chn

This returns the position in samples of the left edge of the time domain waveform for the given channel. To get the data currently displayed in the time domain window:

(define (window-samples)
  (let ((wl (left-sample))
	(wr (right-sample)))
   (samples wl (+ 1 (- wr wl)))))

See also move-one-pixel.

Time Domain Display
Built-in keyboard commands: Moving the Window
Specialized keyboard commands: bind-key
Window size: x-zoom-slider, zoom-one-pixel,
Window position: x-position-slider, move-one-pixel
Window left edge: left-sample
Window right edge: right-sample

fft window:
window size: drag x axis, spectrum-end
window start: spectrum-start
relation to time domain: before-transform-hook
selection fft: show-selection-transform

general info:
Axis description: axis-info
lisp-graph? snd chn

lisp-graph? returns #t if the lisp-generated graph is currently displayed ("lisp" here means any extension language). The lisp graph section is also active if there's a drawing function on the lisp-graph-hook.

lisp-graph-style snd chn

This determines how lisp-generated data is displayed. The choices are:

graph-lines  graph-dots  graph-filled  graph-lollipops  graph-dots-and-lines 
make-player snd chn

This function makes a new player associated with the given channel. A player is a sort of wrapper for a channel of a sound that supports all the control-panel functions. Once created, you can set these fields, then call add-player to add this channel to the list of channels either being played (if a play is in progress) or about to be played. Once some player is in the play-list, you can start the play with start-playing, and stop it prematurely with either stop-player or stop-playing. These functions make it possible to build custom control panels. Here's an example that plays a sound with individual amplitudes for the channels:

(define play-with-amps
  (lambda (sound . amps)
    (let ((chans (channels sound)))
      (do ((chan 0 (+ 1 chan)))
          ((= chan chans))
        (let ((player (make-player sound chan)))
          (set! (amp-control player) (amps chan))
          (add-player player)))
      (start-playing chans (srate sound)))))

(play-with-amps 0 1.0 0.5) ;plays channel 2 of stereo sound at half amplitude

See play-with-envs in enved.scm, play-syncd-marks in marks.scm, start-dac in play.scm, and add-amp-controls in snd-motif.scm.

make-variable-graph container name length srate

make-variable-graph is a part of the variable-display mechanism in snd-motif.scm. It creates the sound/channel pair that displays a graph or spectrum of the arbitrary data accessed via channel-data.

map-channel func beg dur snd chn edpos origin

map-channel is one of the standard ways to change a sound. It applies 'func' to each sample replacing the current value with whatever 'func' returns. As usual, 'beg' defaults to 0, 'dur' defaults to the full length of the sound, 'snd' and 'chn' default to the currently selected sound, and 'edpos' to the current edit history list position. 'origin' is the edit history name of the current operation.

'func', a procedure of one argument (the current sample), can return #f, which means that the data passed in is deleted (replaced by nothing), or a number which replaces the current sample, or #t which halts the mapping operation, leaving trailing samples unaffected, or a vct the contents of which are spliced into the edited version, effectively replacing the current sample with any number of samples. This sounds more complicated than it is! Basically, a map-channel function receives each sample and returns either #f (no corresponding output), a number (the new output), or a bunch of numbers. If every value returned for a given channel is #f, the data is not edited. Here we add 0.2 to every sample in a channel:

Scheme:
> (map-channel (lambda (y) (+ y 0.2)))
0

Ruby:
>map_channel(lambda do |y| y + 0.2 end)
-0.0015869140625

Forth:
>lambda: <{ y }> y 0.2 f+ ; map-channel
-0.00158691

In the next sequence, we replace a sound by the difference between successive samples (a high-pass effect), then undo that by adding them back together, then check to see how close our reconstruction is to the original:

> (let ((y0 0.0)) (map-channel (lambda (y) (let ((diff (- y y0))) (set! y0 y) diff))))
0
> (let ((y0 0.0)) (map-channel (lambda (y) (let ((add (+ y y0))) (set! y0 add) add))))
0
> (let ((rd (make-sampler 0 0 0 1 0))) (map-channel (lambda (y) (- y (rd)))))
0          ; the sampler is reading the unedited form of the sound
> (maxamp) ; i.e. how big is the biggest difference
0.0
(define* (cosine-channel (beg 0) dur snd chn edpos)
  (map-channel
   (let* ((samps (or dur (framples snd chn)))
	  (incr (/ pi samps))
	  (angle (* -0.5 pi)))
     (lambda (y)
       (let ((val (* y (cos angle))))
	 (set! angle (+ angle incr))
	 val)))
   beg dur snd chn edpos))

Here's a slightly more involved example; we define a function that finds silent portions and replaces them with something:

(define (map-silence in-silence replacement)
  (let ((buffer (make-moving-average 128))
        (silence (/ in-silence 128)))
    (lambda (y)
      (let ((sum-of-squares (moving-average buffer (* y y))))
        (if (> sum-of-squares silence) y replacement)))))

(map-channel (map-silence .01 0.0))  ; squelch background noise
(map-channel (map-silence .001 #f))  ; remove silences altogether

Here we're using 'buffer', a CLM moving-average generator, to track the RMS value of the last 128 input samples. When that falls below the argument 'silence', we replace the current sample with 'replacement'. It may be easier in complex cases to use with-sound rather than map-channel. See step-src for example.

It is possible to break out of a map, flushing any edits, via call-with-current-continuation:

(define ctr 0)
(call-with-current-continuation 
  (lambda (return)
    (map-channel (lambda (val)
                   (set! ctr (+ 1 ctr)) 
                   (if (> ctr 100) 
                     (return "quitting!") 
                     val)))))

It is also possible to stop, then continue map-channel:

(define go-on #f)
(map-channel (lambda (y) 
               (call-with-current-continuation 
                 (lambda (stop) 
                   (if (> y 1.0)
                       (begin 
                         (set! go-on stop) 
                         (error 'oops))))) 
               .2))

If this hits a sample > 1.0, it will print 'oops and put the continuation in the variable 'go-on'. (go-on) will continue where you left off. (I'm not sure how far this can be pushed, or whether it's a good idea — you may end up with unclosed files and so on).

If the editing action is not mapping something over the current sound, it is safest to write a temp file with the new data, then pass that to set-samples with the 'trunc' argument set to #t. This way you don't assume the new sound will fit in memory (as in using float-vector->channel for example). Use snd-tempnam to get a temporary filename that reflects the current temp-dir setting. The env-sound-interp function in examp.scm is an example of this.

(define* (map-sound-chans proc (beg 0) dur snd edpos origin)
  (do ((i 0 (+ i 1)))
      ((= i (channels snd)))
    (map-channel proc beg dur snd i edpos origin)))

An esoteric aside: map-channel sets up the sampler before calling the procedure, so if that procedure edits the sound itself (independent of map-channel), the result will be all such edits after the current edit, then the map-channel result applied to the original (not the newly edited) data. That is,


(let ((first #t)) 
  (map-channel (lambda (y) 
                 (if first (set! (sample 0) 1.0)) 
                 (set! first #f) 
                 (* y 2))))

will return with two edits registered in the edit history list; the map-channel result will be the original data doubled; the preceding edit in the list will be the (set! (sample 0) 1.0) which the map-channel ignores.

maxamp snd chn edpos

This returns the max amp of the given channel, or the overall maxamp of snd if no channel argument is given. Used with set!, it is equivalent to scale-to.

(define maxamp-all
  (let ((documentation "(maxamp-all) returns the current maxamp of all currently open sounds"))
    (lambda ()
      (apply max (map (lambda (snd) (apply max (maxamp snd #t))) (sounds))))))
Maxamps
Sound file maxamp: mus-sound-maxamp
Region maxamp: region-maxamp
Selection maxamp: selection-maxamp
To set the y axis bounds to reflect the channel's maxamp: y-bounds
Mix maxamp: mix-maxamp
maxamp locations: maxamp-position, region-maxamp-position, selection-maxamp-position
maxamp-position snd chn edpos

This gives the location (sample number) of the maximum sample in the given channel.

max-transform-peaks snd chn

This returns the maximum number of transform peaks reported. The default is 100. max-transform-peaks affects both the fft display (if show-transform-peaks) and the peaks function.

min-dB snd chn

This sets the minimum dB value displayed in various graphs (the default is -60.0). Due to problems with arithmetic underflows in sqrt, the spectrum functions set the lowest actual dB value calculated to -140.0 or -180.0 (depending on which function is called and so on).

new-sound :file :channels :srate :sample-type :header-type :comment :size

new-sound creates a new sound named 'file'. The following function opens a new sound named "test.snd", extends it to 'dur' samples, and initializes all samples to 'val':

(define (init-sound val dur)
  (let ((ind (new-sound "test.snd" :size dur)))
    (map-channel (lambda (y) val))
    ind))

If the 'header-type' and other arguments are not specified, they default to the current default-output-header-type and related settings. sample types are (b=big-endian, l=little, u=unsigned):

mus-bshort  mus-lshort mus-mulaw  mus-alaw   mus-byte   mus-ubyte   mus-bfloat
mus-lfloat  mus-bint   mus-lint   mus-b24int mus-l24int mus-bdouble mus-ldouble
mus-ubshort mus-ulshort

Header-types are:

mus-next mus-aifc mus-riff mus-rf64 mus-nist mus-raw mus-ircam mus-aiff 
mus-soundfont mus-bicsf mus-voc mus-svx mus-caff

To be informed whenever a new sound is created, use new-sound-hook (see ws.scm).

normalize-channel norm beg dur snd chn edpos

normalize-channel scales (changes the amplitude) of a sound so that its new peak amplitude is 'norm'. This is the "regularized" form of scale-to. The multichannel version is normalize-sound in extensions.scm.

open-raw-sound :file :channels :srate :sample-type

This opens 'file' as a raw (no header) sound in the layout specified. If the file has a header, it is not ignored (use (set! (sample-type ...)) and friends to get around this). If the header is messed up, you can override its settings by giving the correct values in the call to open-raw-sound.

(define mpg
  (let ((documentation "(mpg file tmpname chans) converts file from MPEG-3 to raw 16-bit samples using mpg123"))
    (lambda (mpgfile rawfile chans)
      (system (format #f "mpg123 -s ~A > ~A" mpgfile rawfile))
      (open-raw-sound rawfile 1 44100 (if (little-endian?) mus-lshort mus-bshort)))))

There's a more elaborate version of this function in examp.scm. See also open-raw-sound-hook.

open-sound filename

open-sound opens 'filename' and returns the sound object; this is equivalent to the File:Open option. view-sound opens a sound read-only, or you can set read-only by hand. close-sound closes a file opened by open-sound. There are a variety of hooks that are invoked during the sound opening process: during-open-hook, open-hook, after-open-hook, initial-graph-hook, open-raw-sound-hook. The sequence of actions is:

bad header?: bad-header-hook — can cancel request
no header?:  open-raw-sound-hook — can cancel request
file ok: 
     open-hook — can change filename
     file opened (no data read yet)
         during-open-hook (can set prescaling etc)
     data read, no graphics yet
     after-open-hook
     initial-graph-hook

There are other ways to get at sound file data: make-sampler can be given a filename, rather than a sound; file->vct in examp.scm; mus-sound-open-input and there are a variety of CLM-based functions such as file->sample and file->array.

pad-channel beg dur snd chn edpos

pad-channel inserts 'dur' zeros at 'beg' in the given channel. This is the regularized version of insert-silence. To set a block of samples to zero, use scale-channel with a scaler of 0.0. To insert a block of arbitrary-valued samples:

(define* (block-channel value (beg 0) dur snd chn edpos)
  (pad-channel beg dur snd chn edpos) ; insert 'dur' samples
  (map-channel (lambda (y) value) beg dur snd chn))
pausing

pausing is #t if sound output is currently paused. You can unpause the sound by setting pausing to #f, and pause it by setting pausing to #t. If you pause a sound (via C-click of the play button, for example), then call play (via a key binding perhaps), the sound remains paused by default. To cancel the current pause and restart with the new play command:

(bind-key (char->integer #\p) 0
  (lambda ()
    (if (pausing) (stop-playing))
    (play)))
peaks file snd chn

peaks displays fft peak information. If 'file' is not null, it writes the information to that file, otherwise it posts the data in a help window. The maximum number of peaks reported is set by max-transform-peaks.

(hook-push after-transform-hook 
  (lambda (hook)
    (peaks))) ; post a detailed list of peaks after each FFT
play object :start :end :channel :edit-position :out-channel :with-sync :wait :stop :srate :channels

play plays 'object'. If no arguments are passed, it plays the currently selected sound. 'object' can be a string (sound filename), a sound object or index, a mix, a region, the selection object, #f, a procedure, or a player. Not all the keyword arguments apply in all cases, though I hope to fill in the table of possibilities eventually. 'start' is where to start playing (a sample number, defaults to 0). 'end' is where to stop playing. 'channel' is which channel to play (the default is to play all channels). 'edit-position' is which edit history list entry to play, where that is relevant. The default is the current entry. 'out-channel' is which DAC channel to send the samples to. 'with-sync' sets whether to include all objects sync'd to the current one (default is no, #f). 'wait' sets whether the function call should wait until the play is complete before returning (default is no, #f). 'stop' is a procedure called when the play completes. 'srate' and 'channels' are for one special case, described below.

(play)                                                       ; play current sound, all chans from start to end
(play 0 :channel 1)                                          ; play just the second channel of sound 0
(play ((selected-sound) cursor))                             ; play starting from the cursor
(play (integer->sound 1) (round (* 3.0 (srate))) :channel 3) ; play snd 1, chan 3 (4th chan), start at 3.0 secs
(play (selected-sound) 0 :with-sync #t)                      ; play sync'd sounds
(play (selected-sound) 0 :end (round (* 3.0 (srate))))       ; play from start for 3.0 secs
(play (selected-sound) 0 :edit-position 2)                   ; play the version at edit history position 2
(play (integer->sound 0) 0 :channel 2 :out-channel 0)        ; play chan 2, but send it to DAC chan 0
(play (selected-sound) (mark-sample (integer->mark 0)) :end (mark-sample (integer->mark 1))); play between marks 0 and 1
(play (selection))                                           ; play the selection
(play #f :srate 44100 :channels 2)                           ; open DAC and run, stop with stop-playing
(play "1a.snd")                                              ; play 1a.snd
(play "1a.snd" 1000 4000)                                    ; play 1a.snd from sample 1000 to 4000

If 'stop' is a procedure of one argument, it is called when the play process stops. The argument passed to the stop procedure provides the reason the play is stopping; it will be 0 if the play completed normally. This is intended mainly for looping plays, as in play-often.

(play (selected-sound) 0 :stop (lambda (reason)              ; if interrupted, say so in the listener
                                 (if (not (= reason 0))
                                     (snd-print ";play interrupted"))))

The 'edit-position' argument makes it easier to try "A:B" comparisons; this plays the version before the latest edit:

(play (selected-sound) :edit-position (- (edit-position) 1))

The following code binds the "p" key to play all channels of the current sound from the cursor, and the "P" key to play the previous version of the current sound:

(define (play-from-cursor current)
  (play (selected-sound) (cursor) :edit-position (and (not current) (- (edit-position) 1))))

(bind-key (char->integer #\p) 0 
  (lambda () "play from cursor" (play-from-cursor #t) keyboard-no-action))

(bind-key (char->integer #\P) 0 
  (lambda () "play previous version from cursor" (play-from-cursor #f) keyboard-no-action))

And here we play from the cursor with a moving ("tracking") cursor:

(define (pfc)
  (let ((old-tracking (with-tracking-cursor)))
    (set! (with-tracking-cursor) #t)
    (hook-push stop-playing-hook 
      (lambda (hook)
        (set! (with-tracking-cursor) old-tracking)))
    (play (selected-sound) (cursor))))

If 'object' is #f, the :srate and :channels arguments set up the DAC. The DAC then stays open until you call stop-playing. This is useful when you're using bind-key and play to trigger sounds, but want the output to have more channels than the various inputs.

(bind-key #\o 0 
  (lambda () ; send oboe.snd to chan 0
    (play "oboe.snd" :out-channel 0)))   

(bind-key #\p 0 
  (lambda () ; send pistol.snd to chan 1
    (play "pistol.snd" :out-channel 1))) 

;;; Now open a sound (so you have a non-listener pane to type to)

(play #f :srate 22050 :channels 2) ; srate 22050, 2 output chans

;;; this holds the DAC open indefinitely
;;; Now type o and p in the sound pane until you want to quit, then

(stop-playing) 

Finally, if 'object' is a function, it is called on every sample; if it returns a number, that number is sent to the DAC; if it returns #f, it stops. play-mixes uses this function option to time the playing of each mix in a sequence of mixes. Another example is play-sine:

(define play-sine 
  (let ((documentation "(play-sine freq amp) plays a 1 second sinewave at freq and amp"))
    (lambda (freq amp)
      (let ((len 22050)
            (osc (make-oscil freq)))
        (play (lambda ()
	        (set! len (- len 1))
	        (and (positive? len)        ; we've sent 22050 samples, so it's time to stop
		     (* amp (oscil osc)))))))))

Here's another example that plays a sound file, skipping any portion that looks like silence:

(define (play-skipping-silence file)
  (let ((buffer (make-moving-average 128))
        (silence (/ .001 128))
	(rd (make-sampler 0 file))
	(sum-of-squares 0.0)
	(y 0.0))
    (play (lambda ()
	    (let loop ()
	      (set! y (rd))
	      (set! sum-of-squares (moving-average buffer (* y y)))
	      (and (not (sampler-at-end? rd))
		   (if (> sum-of-squares silence)
		       y
		       (loop))))))))
Play
play from cursor: C-q and example above
play from cursor with tracking cursor: pfc above
play the selection: (play (selection)), C-x p
play a region: (play region-object), C-x p, play button in Region dialog
play a mix: (play mix-object), play button in Mix dialog
play a sequence of mixes: play-mixes
play from mark: click or drag triangle (control-click for all chans)
stop playing: C-g, C-t, stop-playing, set playing to #f
pause or resume playback: space, set pausing
play repeatedly: play-often
play repeatedly until C-g: play-until-c-g
play region repeatedly: play-region-forever
play a file upon a keystroke: bind-key
play using an external program: (system "sndplay wood16.wav")
play a sine-wave or spectrum: play-sine and play-sines
play arbitrary mixtures of things: make-player and related functions, play-syncd-marks
play with applied amplitude envelope: play-with-envs
play an external file: (play "file")

The "reasons" that might be passed to the stop-procedure are:

0    play completed normally	
1    file is being closed	
2    play button unset
3    stop-playing function called	
4    C-g	
5    DAC error (no available channel)
6    play error (audio setup problem)	
7    apply requested (control panel)	
8    file edited
9    C-t

The hooks called during a play operation are:

when a play request occurs: start-playing-hook — can cancel the request, 
                            also start-playing-selection-hook
    (any number of sounds can be playing at once)
as each sound ends: stop-playing-hook, stop-playing-selection-hook
player-home player

This returns a list of the sound and channel number associated with player.

playing

This returns #t if sound output is currently in progress. You can also start playing by setting playing to #t (equivalent to calling start-playing with default arguments), and stop by setting it to #f (equivalent to stop-playing).

players

This returns a list of currently active players.

player? obj

This returns #t if 'obj' is an active player.

position->x xpos snd chn axis

This returns the x axis value that corresponds to the graph (screen pixel) position 'xpos'. To find the sample that the mouse is pointing at, given the current mouse position,

(round (* (srate snd) (position->x x snd chn)))
position->y ypos snd chn axis

This returns the y axis value that corresponds to the graph (screen pixel) position 'ypos'.

progress-report pct snd chn

The functions start-progress-report, progress-report, and finish-progress-report handle the animated hour-glass icon that hopes to amuse the idle user while some long computation is in progress. The 'pct' argument is a float between 0.0 and 1.0 which indicates how far along we are in the computation; there are only 20 separate icons, so there's no point in calling this more often than that. start-progress-report posts the initial icon, and finish-progress-report removes it. If the icons are not available, a message is posted in the sound's status area using 'name' to identify itself.

ramp-channel rmp0 rmp1 beg dur snd chn edpos

ramp-channel is a slight extension of scale-channel. It scales samples in the given sound/channel between 'beg' and 'beg' + 'dur' by a (linear) ramp going from 'rmp0' to 'rmp1'.

read-only snd

This returns #t if 'snd' is read-only, #f otherwise. If you open a file with view-sound, read-only is set to #t. read-only does not reflect (or affect) the write permission state of the underlying file; it is a way to keep from accidentally clobbering an otherwise writable file. If it is #t (or if the file is not writable), a lock icon is displayed beside the file name.

redo edits snd chn

This re-activates 'edits' edits (the default is 1) in the given channel. Redo follows the sync field if it is not 0. The following might be a more reasonable redo function:

(define* (redo-channel (edits 1) snd chn)
  (if (and snd (not (= (sync snd) 0)) chn)
      (set! (edit-position snd chn) (+ (edit-position snd chn) edits))
      (redo edits snd)))

redo moves forward in the edit history list, whereas undo backs up, and revert-sound resets the current edit position to the start of the list. For more about the edit history list, see Edit Lists.

In Ruby, redo is a part of the loop handling, so Snd's redo is renamed redo_edit. redo-edit also exists in Scheme, for consistency.

reverse-channel beg dur snd chn edpos

reverse-channel is the regularized version of reverse-sound.

Reversing
reverse channel: reverse-channel, reverse-sound
reverse selected portion: reverse-selection
read samples in reverse: use make-sampler with direction -1
reverse at new sampling rate: use src-channel with a negative ratio
Reverse in control panel: control panel and speed-control variable
reverse an envelope: reverse-envelope
reverse block-wise: reverse-by-blocks and reverse-within-blocks
reverse via FFT: silly-reverse
reverse order of channels: reverse-channels
reverse a list: reverse and reverse!
reverse a string: in Ruby: reverse
reverse vct: vct-reverse!
reverse-sound snd chn edpos

reverse-sound reverses the sound data in the given channel. There are some interesting non-causal effects you can get with this: take a voice sound, reverse it, reverberate it, reverse it again, and you get the original with reversed reverb. As a hack, you can reverse a sound (modulo a one sample rotation) by doing two ffts (DSP-ers call this a "flip"):

(define* (silly-reverse snd)
  (let* ((len (framples snd 0))
	 (fsize (expt 2 (ceiling (log len 2))))
	 (rl (channel->float-vector 0 fsize snd 0))
	 (im (make-float-vector fsize 0.0)))
    (mus-fft rl im fsize)
    (mus-fft rl im fsize)
    (float-vector-scale! rl (/ 1.0 fsize))
    (float-vector->channel (float-vector-subseq rl (- fsize len) fsize) 0 len snd 0)))
revert-sound snd

This reverts 'snd' to its saved (unedited) state. A channel-specific version:

(define* (revert-channel snd chn)
  (set! (edit-position snd chn) 0))
right-sample snd chn

This returns the position (in samples) of right edge of the time domain waveform. See left-sample, move-one-pixel, and many examples in examp.scm.

sample samp snd chn edpos

This function gives the value of sample 'samp' in the given channel.

Scheme: (set! (sample 100) .5)
Ruby:   set_sample(100, 0.5)
Forth:  100 0.5 set-sample

'samp' defaults to the current cursor location. If 'chn' is #t, sample returns a list of all the samples at 'samp', so:

(define* (frample samp snd edpos)
  (apply float-vector (sample samp snd #t edpos)))
samples samp samps snd chn edpos

This returns a vct of 'samps' samples starting at 'samp' in the given channel. 'samp' defaults to 0. 'samps' defaults to framples - 'samp' (i.e. read to the end of the data). 'pos' is the edit history position to read (it defaults to the current position). This is settable (as is sample):

> (samples 1000 10)
#<vct[len=10]: 0.033 0.035 0.034 0.031 0.026 0.020 0.013 0.009 0.005 0.004>
> (set! (samples 1000 10) (make-vct 10 .1))
#<vct[len=10]: 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100 0.100>
sample-type snd

This returns the sound's sample type — the encoding used for the sound samples (e.g. mus-bshort).

The standard formats nowadays are mus-bshort (big-endian 16-bit integers), mus-bfloat (32-bit big-endian floats), and mus-bint (32-bit big-endian integers), and the corresponding little-endian versions: mus-lshort, mus-lfloat, and mus-lint. If you're using an Intel-style PC, you're using a little-endian machine; Old macs (PowerPC Macs) and Suns use big-endian (NeXT, SGI, and Atari also used it in the good old days). If you write a Next file and use little-endian data, some programs other than Snd may complain; similarly, RIFF wants little-endian and AIFC wants big-endian data (both can handle the other kind, but most sound-related programs don't know that). In the old days, when disk space was at a premium, 8-bit formats were used a lot: mus-mulaw and mus-alaw (kludges for a kind of 8-bit float), mus-byte and mus-ubyte (8-bit ints, unsigned in the latter case). A few DACs want a particular kind of data, but Snd handles that conversion internally. Anything less than 12 bits will sound bad — Perry Cook's book "Real Sound Synthesis" has examples.

If you encounter a file with an unknown format, or a header that has the wrong format, you can set this field to force Snd to interpret the data in any way you like. Similar remarks apply to the srate, data-location, header-type, and channels fields. There are ambiguities in some header specifications, usually involving big/little endian or signed/unsigned data confusion. If you encounter a sound that is clipping crazily or is just a burst of noise, try changing these settings. Some NeXT/Sun (au) header files using byte-wide data assume the byte is unsigned, whereas most others assume it is signed. Sndlib treats it as signed by default, so to make one of the unsigned-byte files playable,

(set! (sample-type) mus-ubyte)

mus_float_t data is another source of confusion; there is apparently no agreement on whether the data is between -1.0 and 1.0, or -32768.0 and 32767.0 or anything else. In this case, Snd assumes -1.0 to 1.0 (except in one special case involving IRCAM headers), and you may have to set y-bounds to see the actual data. Yet another gotcha: files with 32-bit integers. Some programs (Glame, apparently, and perhaps Ardour) assume the fraction is 31 bits wide, others (Snd) use whatever its sample width is configured to be; there is no correct or standard placement of the fixed point, but not to worry! Your data is ok: (set! (y-bounds) (list -256.0 256.0)). There are several ways you can handle these files automatically in Snd. Perhaps the simplest is to use one of the open hooks:

(hook-push after-open-hook 
  (lambda (hook) 
    ;; this could also (alternatively) set the y-bounds as above
    (if (= (sample-type (hook 'snd)) mus-lint)
        (set! (sample-type (hook 'snd)) mus-lintn))))

or (an alternative that sets the underlying database entry, rather than the current in-Snd choice):

(hook-push open-hook 
  (lambda (hook)
    (if (= (mus-sound-sample-type (hook 'name)) mus-lint)
        (set! (mus-sound-sample-type (hook 'name)) mus-lintn))))

If you set any of these fields, the sound's index may change (there can be an embedded update-sound). To deal with MPEG, OGG, Flac, or Speex files, see examp.scm (mpg) or misc.scm (mpg123 and ogg123). Octave/WaveLab ASCII files can be translated by read-ascii (examp.scm).

To turn a sample-type number into a string, use mus-sample-type-name. To get the sample type of some sound file, use mus-sound-sample-type. The default output (new-sound, and save-sound-as) sample-type is default-output-sample-type. To change a sound file's sample-type, use save-sound-as.

save-sound snd

save-sound saves 'snd', writing the current state of the sound to its underlying sound file, (like the File menu's Save option). save-hook is invoked upon save-sound. After save-sound, the sound has no undoable edits in its edit history (this is different from Emacs, but I find Emac's way of handling this very confusing, and it's never what I want).

Saving
save sound: save-sound
save all sounds: (for-each save-sound (sounds))
save a sound under a different name: save-sound-as
extract one channel from a sound: extract-channel
extract a set of channels from a sound: extract-channels
save a sound in a different sample type or header: save-sound-as
backup edits automatically: autosave
check first for unsaved edits: ask-about-unsaved-edits
save Snd's complete state (unsaved edits and all): save-state, save-dir, save-state-hook, save-state-file
save the selection: save-selection
save a region: save-region
save a mix: save-mix
save the control panel state: save-controls
save currently defined envelopes (envelope editor): save-envelopes
start the file save dialog: save-sound-dialog
start the selection save dialog: save-selection-dialog
start the region save dialog: save-region-dialog
save the current listener text: save-listener
save marks: save-marks
save just the edit history: save-edit-history
take some action upon a window manager save-yourself signal: upon-save-yourself
save the current sound setup for a later reopen: remember-sound-state
save the current fft peak info: peaks
save-sound-as :file :sound :srate :sample-type :header-type :channel :edit-position :comment

This saves 'sound' as 'file' (like the 'File:Save as' menu option). If 'channel' is specified, only that channel is saved (it is extracted if necessary from the multichannel original). 'edit-position', if given, specifies which edit history position to save. The :srate argument refers only to the new sound file's header's srate field; the data is not resampled. If you want to resample the data as it is saved, see the example under before-save-as-hook. If :sample-type is given, the sound file is written using that sample type. Any omitted argument's value is taken from the sound being saved. save-sound-as returns the new file name.

(save-sound-as "test.snd" :sample-type mus-bdouble :header-type mus-aifc)

saves the currently selected sound as an AIFC file using big-endian doubles for the samples.

To start a parallel editing branch on a given file, you could:

(save-sound-as "test.snd") (open-sound "test.snd")

To define an explicit channel extraction function:


Scheme:
(define (extract-channel filename snd chn) (save-sound-as filename snd :channel chn))

Ruby:
def extract_channel(filename, snd, chn) save_sound_as(filename, snd, :channel, chn) end

Forth:
: extract-channel { filename snd chn } filename snd :channel chn save-sound-as ;

The hooks called during a save operation are:

before-save-as-hook — can cancel the request or set its output parameters
save-hook
    sound saved
      if any sample is clipped during save, clip-hook
after-save-as-hook
scale-by scalers snd chn

scale-by scales the amplitude of 'snd' by 'scalers'. Unlike most of these functions, scale-by follows the 'sync' buttons and affects all currently sync'd channels. 'scalers' can be either a float, a list, or a vct. In the latter case, the values are used one by one, applying each as scale-by moves through the channels. If 'sync' is off, channel 'chn' is scaled (it defaults to the currently selected channel). (scale-by 2.0) doubles all samples.

scale-channel scl beg dur snd chn edpos

scale-channel scales (changes the amplitude) of a sound by 'scl'. channel-polynomial is a generalization of the idea. There are approximately a bazillion ways to scale samples in Snd; here's a potpourri of increasingly silly choices:

(scale-channel 2.0)
(scale-by 2.0)
(map-channel (lambda (val) (* val 2.0)))
(set! (maxamp) (* 2 (maxamp)))
(env-sound '(0 2 1 2))
(env-channel (make-env '(0 1 1 1) :scaler 2.0 :length (framples)))
(clm-channel (make-one-zero :a0 2.0 :a1 0.0))
(filter-channel (float-vector 2.0) 1)
(float-vector->channel (float-vector-scale! (channel->float-vector) 2.0) 0)
(begin (select-all) (mix-selection 0))
(begin (select-all) (scale-selection-by 2.0))
(begin (save-sound-as "temp.snd") (mix "temp.snd" 0) (delete-file "temp.snd"))

(let ((flt (make-float-vector 8 0.0)))
  (set! (flt 0) 2.0)
  (let ((cnv (make-convolve :filter flt))
	(sf (make-sampler 0)))
    (map-channel
     (lambda (val)
       (convolve cnv (lambda (dir) 
                       (read-sample sf)))))))

(float-vector->channel (poly* (channel->float-vector 0 (framples)) (float-vector 2.0))) ; poly.scm (sound = polynomial coeffs)

(let* ((len (framples))
       (fsize (expt 2 (ceiling (/ (log len) (log 2)))))
       (rl (channel->float-vector 0 fsize))
       (im (make-float-vector fsize 0.0)))
  (mus-fft rl im fsize)
  (mus-fft rl im fsize)
  (mus-fft rl im fsize)
  (mus-fft rl im fsize)
  (float-vector->channel (float-vector-scale! rl (/ 2.0 (* fsize fsize))) 0 len))

(do ((i 0 (+ i 1)))
    ((= i (framples)))
  ;; don't actually do this! — it involves a separate edit on each sample
  (set! (sample i) (* 2 (sample i))))

(let ((make-scaler 
       (lambda (start end)
	 (letrec ((ctr start)
		  (us (lambda (them)
			(set! (sample ctr) (* 2.0 (sample ctr)))
			(set! ctr (+ ctr 2))
			(if (<= ctr end)
			    (them us)))))
	   us))))
  ((make-scaler 0 (framples)) 
     (make-scaler 1 (framples))))
scale-to norms snd chn

scale-to normalizes 'snd' to 'norms' (following sync as in scale-by). (scale-to 0.5) scales the current channel so that its maxamp is 0.5. If all the sound's samples are 0.0, scale-to returns #f and does not perform any edit. 'norms' can be a number, a list of numbers, or a vct.

scan-channel func beg dur snd chn edpos

scan-channel is obsolete; use a do loop with a sampler:

(define* (scan-channel func (beg 0) dur snd chn edpos)
  (let ((end (if dur (min (+ beg dur) (framples snd chn)) (framples snd chn)))
	(rd (make-sampler beg snd chn 1 edpos)))
    (do ((pos beg (+ pos 1)))
        ((or (>= pos end)
	     (func (next-sample rd)))
         (and (< pos end)
	      pos)))))

scan-channel "scans" the data in the specified channel between the given sample numbers (the default is the entire sound) by applying 'func' to each sample. If 'func' returns something other than #f, the scan is halted, and the current sample number is returned. The following call scans the current channel looking for any sample greater than .1:

> (scan-channel (lambda (y) (> y .1)))
4423
selected-channel snd

This gives the selected channel in 'snd'; you can set it to select a channel. It returns #f is no channel is selected in 'snd'.

selected-sound

This returns the currently selected sound; you can set it to select a sound. It returns #f is there is no selected sound.

(or (selected-sound)
    (and (pair? (sounds))
         (car (sounds))))

returns the currently selected sound, if any, and failing that, any other sound that is currently open.

select-channel chn

This selects channel 'chn' in the currently selected sound; equivalent to (set! (selected-channel) chn). See also select-channel-hook.

select-sound snd

This selects sound 'snd' (a sound object or an index); equivalent to (set! (selected-sound) snd). See also select-sound-hook.

set-samples samp samps data snd chn trunc edname infile-chan edpos auto-delete

set-samples (and its equivalent form (set! (samples...)...)) set the given channel's samples starting from sample 'samp' for 'samps' samples to the values in 'data'.

(set! (samples 0 100) (make-vct 100 .1))
(set-samples 0 100 (make-vct 100 .1))

both change all samples between 0 and 100 to be 0.1. If 'samp' is beyond the end of the file, the file is first zero-padded to reach it. 'data' can be a filename.

(set-samples 10000 20000 "oboe.snd")

replaces 10000 samples with data from oboe.snd. If 'data' is a vct, set-samples is identical to vct->channel. If 'trunc' is #t and 'samp' is 0, the sound is truncated (if necessary) to reflect the end of 'data'. If the in-coming data file has more than one channel, 'infile-chan' sets which input file to read. The in-coming data file is not deleted by Snd unless 'auto-delete' is #t. (If you write a temporary sound as an edit, it can be non-obvious when it is safe to delete that file; 'auto-delete' set to #t asks Snd to handle cleanup).

The form (set! (samples samp samps 'snd chn trunc edname infile-chan edpos auto-delete') data) can also be used.

(define (step-src)
  (let* ((rd (make-sampler 0))
	 (o (make-oscil 2205.0))
	 (s (make-src :srate 0.0))
	 (incr (+ 2.0 (oscil o)))	  
	 (tempfile (with-sound (:output (snd-tempnam) :srate (srate) :to-snd #f)
		     (do ((samp 0 (+ 1 samp)))
			 ((sampler-at-end? rd))
		       (out-any samp (src s incr (lambda (dir) (read-sample rd))) 0)
		       (if (= (modulo samp 2205) 0)
			   (set! incr (+ 2.0 (oscil o)))))))
	 (len (mus-sound-framples tempfile)))
    (set-samples 0 (- len 1) tempfile #f #f #t "step-src" 0 #f #t)))
short-file-name snd

This returns the brief (no directory) form of the sound's filename.

> (open-sound "oboe.snd")
#<sound 0>
> (file-name (integer->sound 0))
"/home/bil/cl/oboe.snd"
> (short-file-name (integer->sound 0))
"oboe.snd"
show-axes snd chn

This determines what axes are displayed. If show-axes is show-all-axes (the default), both the x and y axes are displayed; if it is show-x-axis, just one (bottom) x axis is displayed, reducing screen clutter. show-no-axes omits both x and y axes. To remove the x axis label, use either show-x-axis-unlabelled or show-all-axes-unlabelled. To omit all the x axis labels and ticks (but include the y axis as usual) use show-bare-x-axis. This is the View:Axes choice.

show-grid snd chn

If show-grid is #t (the default is #f), a background grid is displayed (default is #f). See also grid-density.

grid
show-marks snd chn

If show-marks is #t (the default), marks are displayed. This is the 'Show marks' View menu option.

show-mix-waveforms snd chn

If show-mix-waveforms is #t (the default), a mixed sound is displayed as a separate waveform above the main data. The rectangular tag at the start of the waveform can be dragged to move the mix, or clicked to select it for the mix dialog.

show-sonogram-cursor snd chn

If show-sonogram-cursor is #t (the default is #f), the cursor is also displayed in the sonogram.

show-transform-peaks snd chn

If show-transform-peaks is #t (the default is #f), transform peak information is included in the transform display. This is the 'peaks' button in the Transform options dialog.

show-y-zero snd chn

If show-y-zero is #t (the default is #f), the y=0 axis is displayed. This is the 'Show Y=0' View menu option.

smooth-channel beg dur snd chn edpos

smooth-channel is the regularized version of smooth-sound.

Smoothing
smooth channel: smooth-channel
smooth all channels: smooth-sound
smooth selection: smooth-selection
delete the selection and smooth the splice: delete-selection-and-smooth
smoothing via fft: fft-smoother
smooth via low-pass filter
smooth over click: remove-clicks in examp.scm
smooth-sound beg num snd chn

smooth-sound applies a smoothing function to the indicated data. This produces a sinusoid between the end points:

(define (smoother y0 y1 num)
   (let ((v (make-float-vector (+ 1 num) 0.0)) 
	 (angle (if (> y1 y0) pi 0.0)) 
	 (off (* .5 (+ y0 y1))) 
	 (scale (* 0.5 (abs (- y1 y0)))))
     (do ((i 0 (+ i 1)))
         ((= i num) v)
       (set! (v i) (+ off (* scale (cos (+ angle (* i (/ pi num))))))))))
smoother

For a fancier version, see fft-smoother in examp.scm. See also remove-clicks in examp.scm.

sound? snd

sound? returns #t if 'snd' refers to an open sound.

soundfont-info snd

This returns a list of lists describing 'snd' as a soundfont. Each inner list consists of the sound name, start point, loop start, and loop end.

> (soundfont-info)
(("BrSteel_E4" 0 65390 65458) ("BrSteel_B2" 65490 131458 131637) ...)

To set a named mark at the start of each sound with un-named marks at the loop points:

(define (mark-sf2)
  (letrec 
    ((sf2it 
       (lambda (lst)
         (if (pair? lst)
             (let* ((vals (car lst))
                    (m1 (add-mark (cadr vals))))
               (set! (mark-name m1) (car vals))
               (add-mark (caddr vals))
               (add-mark (cadddr vals))
               (sf2it (cdr lst)))))))
   (sf2it (soundfont-info))))
soundfont marks

See also explode-sf2 in examp.scm.

sound->integer sound

This is the counterpart to integer->sound.

sound-loop-info snd

This gives info about loop points from the sound's header. The loop info is a list of up to 4 points, the first two (start, end) refer to the sustain loop, the second two to the release. The 5th and 6th list entries are the base note and detune values. For historical reasons, the 7th and 8th entries are the sustain and release modes. This is similar to mus-sound-loop-info (but it's settable). See explode-sf2 in examp.scm.

> (sound-loop-info)
(24981 144332 0 0 60 0 1 0)
sound-properties snd

This is a property list associated with the given sound. It is set to () at the time a sound is opened. The accessor is sound-property. There are several examples of using it in snd-motif.scm and autosave.scm.

sound-property key snd

sound-property provides access to a sound's property list. These properties are saved when Snd's state is saved (via save-state or the Options:Save session menu). To omit a given property at that time, add its name (a symbol) to the property 'save-state-ignore (a list of symbols); see 'inset-envelope in extensions.scm.

sounds

sounds returns a list of currently active sounds. A common Snd trope is (map func (sounds)):

(map maxamp (sounds))

Or, if the return value is not needed:

(for-each (lambda (snd) (display (short-file-name snd))) (sounds))

This can be extended to provide a complete list of sounds and channels (since many Snd functions take the "snd chn" arguments):

(define (all-chans)
  (let ((sndlist ())
        (chnlist ()))
    (for-each (lambda (snd)
                (do ((i (- (channels snd) 1) (- i 1)))
                    ((< i 0))
                  (set! sndlist (cons snd sndlist))
                  (set! chnlist (cons i chnlist))))
              (sounds))
    (list sndlist chnlist)))

(apply map maxamp (all-chans))
spectrum-end snd chn

This is the amount of the frequency domain to include in the spectrum display (the default is 1.0 = all of it). spectrum-end the slider labelled '% of spectrum' in the View Orientation dialog. See zoom-fft in examp.scm.

spectro-hop snd chn

This is the distance (in pixels) moved between successive spectrogram traces (default is 4). spectro-hop is the 'hop' slider in the Color/Orientation dialog.

spectrum-start snd chn

This is the start point of the frequency domain in the spectrum display (default is 0.0). See zoom-fft in examp.scm.

spectro-x-angle snd chn

This is the spectrogram x-axis viewing angle (the default is 90.0 except in GL where it is 300.0). See snd-gl.scm.

spectro-x-scale snd chn

This is the scaler (stretch amount) along the spectrogram x axis (the is default 1.0, in GL: 1.5).

spectro-y-angle snd chn

This is the spectrogram y axis viewing angle (the default is 0.0, in GL: 320.0).

spectro-y-scale snd chn

This is the scaler (stretch amount) for the spectrogram y axis (the default is 1.0).

spectro-z-angle snd chn

This is the spectrogram viewing angle for the z axis (the default is 358.0, in GL: 0.0).

spectro-z-scale snd chn

This is the scaler (stretch amount) for the z axis (the default is 0.1, in GL: 1.0).

squelch-update snd chn

This is #t if graphic updates are currently squelched (turned off). If you're doing a sequence of edits where intermediate states aren't of great interest, you can save time by turning off redisplays.

(define (without-graphics thunk)
  (set! (squelch-update) #t)
  (let ((val (catch #t thunk (lambda args (car args)))))
    (set! (squelch-update) #f)
    val))
srate snd

This is the sound's sampling rate. If you set this to a new value, update-sound is called to reflect the new srate, but any current edits are flushed. This is consistent with the other header fields (sample-type, etc), but it can be annoying.

There are several srates floating around in Snd. (srate snd) returns the sampling rate of a particular (currently open) sound. (mus-sound-srate filename) returns a sound file's sampling rate. *clm-srate* (also known as mus-srate) is associated with the CLM package (setting the implicit srate for oscil etc). default-output-srate is the default sampling rate used when opening new files. enved-srate is a constant that can be assigned to the envelope editor's enved-target (to apply an envelope to the sampling rate). region-srate is the sampling rate associated with a region.

src-channel num-or-env beg dur snd chn edpos

src-channel preforms sampling rate conversion using 'warped sinc interpolation'. The argument 'num-or-env' can be a number, an envelope, or a CLM env generator. (src-channel 2.0) makes the sound go twice as fast. This is the regularized version of src-sound.

> (framples)                  ; current duration
50828
> (src-channel 2.0)         ; make it half as long
2.0
> (framples)
25415
> (src-channel '(0 .5 1 1)) ; start slow and speed up
(0 0.5 1 1)
> (framples)
35235
> (src-channel (make-env '(0 .5 1 1) :length 20000)) ; stick at 1 after sample 20000
#<env linear, pass: 35236 (dur: 20000), index: 1, scaler: 1.0000, offset: 0.0000, ...>
> (framples)
42964
Resampling
resample channel: src-channel
resample all chans: src-sound
resample selection: src-selection
resample mix: speed control in Mix dialog (also apply-controls)
resample via drawn envelope: srate in Envelope editor
resample via CLM gen: src
resample with independent time control (ssb-am): ssb-bank in dsp.scm
resample with independent time control (granulate): expand in control panel, expsrc and expsnd
resample with independent time control (vocoder): phase-vocoder (this never works)
another time stretcher (autocorrelation):rubber-sound (this takes forever and rarely works)
resampling-based sound effects: hello-dentist, fp, flange and chorus in dsp.scm and new-effects.scm
the digital zipper: zipper
resample via FFT: down-oct
resample through env: sound-interp and env-sound-interp
resample through list: scratch
resample step-size through a function: step-src
predict duration of resampled sound: src-duration
linear src: linear-src-channel in dsp.scm
src-sound num-or-env base snd chn edpos

src-sound performs sampling rate conversion using 'warped sinc interpolation'. The argument 'num-or-env', which sets the ratio between the old and the new srate, can be either a number or an envelope. In the latter case, 'base' sets the segment base (the default is 1.0 = linear). A value greater than 1.0 causes the sound to be transposed up. A value less than 0.0 causes the sound to be reversed. (src-sound 2.0) speeds the sound up by a factor of 2 (transposes it up an octave), whereas (src-sound 0.5) slows it down by the same factor (transposes it down an octave). (src-sound '(0 1 1 2)) starts at the original speed, then gradually increases until, at the end of the sound, it is going twice as fast.

'num-or-env' can also be a CLM env generator (its duration should be the same as the original sound, and its segments should not pass through 0.0). The following function can be used to predict how long the resultant note will be given an src envelope:

;;; find new duration of sound after using env as srate.
;;; the envelope gives the per-sample increment, so the "tempo"
;;;   is the inverse of that. To get the total new duration,
;;;   we need to integrate the inverse envelope, but a straight
;;;   line in the increment envelope becomes a 1/x curve in the
;;;   tempo curve, so we use log(x) as integral of 1/x and
;;;   take into account the local notion of "x".

(define (src-duration e)
  (let* ((len (length e))
	 (ex0 (e 0))
	 (ex1 (e (- len 2)))
	 (all-x (- ex1 ex0))
	 (dur 0.0))
    (do ((i 0 (+ i 2)))
	((>= i (- len 2)) dur)
      (let* ((x0 (e i))
	     (x1 (e (+ i 2)))
	     (y0 (e (+ i 1))) ; 1/x x points
	     (y1 (e (+ i 3)))
	     (area (if (< (abs (- y0 y1)) .0001)
		       (/ (- x1 x0) (* y0 all-x))
		       (* (/ (- (log y1) (log y0)) 
			     (- y1 y0)) 
			  (/ (- x1 x0) all-x)))))
	(set! dur (+ dur (abs area)))))))

;;; (src-duration '(0 1 1 2)) -> 0.693147180559945
:;; (src-duration '(0 1 1 .5)) -> 1.38629436111989
;;; (src-duration '(0 .5 .5 3 .6 1 .7 .1 .8 1.5 1 1)) -> 1.02474349685432

;;; here we're using this in the Snd listener:
> (framples)
220501
> (src-duration '(0 1 1 2))
0.693147180559945
> (src-sound '(0 1 1 2)) ; should be about .693 * 220500 framples 
(0 1 1 2)
> (framples)
152842
> (/ 152842.0 220501)
0.693157854159392       ; tada!

The inverse, so to speak, of this is src-fit-envelope:

(define (src-fit-envelope e target-dur)
  (scale-envelope e (/ (src-duration e) target-dur)))
start-playing chans srate background

If a play-list is waiting, this starts it. 'chans' defaults to 1, 'srate' defaults to 44100, 'background' defaults to #t. See play.scm or marks.scm.

start-progress-report snd chn

This starts a progress-report.

status-report msg snd

This posts 'msg' in the sound's status area. The status area is the text widget between the sound's filename and the buttons on the right, beneath the graph. If 'snd' is not a currently open sound, the message is sent to the listener, if it is open. If there is no sound or listener, 'msg' is sent to stderr.

stop-player player

This removes 'player' from the current play-list (see make-player).

stop-playing snd

If 'snd' is playing, this stops it. If no argument is given, it stops all playback. See play.scm, stop-playing-hook, or stop-playing-selection-hook.

swap-channels snd1 chn1 snd2 chn2 beg dur edpos0 edpos1

This swaps the indicated channels, between 'beg' and 'beg' + 'dur'. In simple cases, this is a virtual operation. swap-channels can be used to change channel order arbitrarily. For example, the following function reverses the channel order:

(define* (reverse-channels snd)
  (let* ((ind (or snd (selected-sound) (car (sounds))))
	 (chns (channels ind)))
    (let ((swaps (floor (/ chns 2))))
      (as-one-edit
       (lambda ()
	 (do ((i 0 (+ i 1))
	      (j (- chns 1) (- j 1)))
	     ((= i swaps))
	   (swap-channels ind i ind j)))))))

Channel rotation is similar, though slightly more work; see scramble-channels in examp.scm. Since swap-channels is a virtual operation in many cases, it's worth using it even where just a channel copy is desired; mono->stereo in extensions.scm for an example. Another example is swap-selection-channels in examp.scm.

sync snd

sync returns the sound's 'sync' value (an integer, 0 = not sync'd). Several functions (scale-by, for example), apply to the currently selected sound and also to any other sounds that share its sync value. (I later decided that this was a bad idea, hence the regularized replacements). Sounds that share a given sync value move together when you drag an x-axis slider and so on.

sync-max

This is the maximum sync setting seen so far — it provides a painless way to get a sync value that is guaranteed to be unique. To sync all currently open sounds:

(let ((new-sync (+ 1 (sync-max))))
  (for-each (lambda (snd) (set! (sync snd) new-sync)) (sounds)))
time-graph? snd chn

This is #t if the time domain graph is being displayed (the 'w' button).

time-graph-style snd chn

This determines how time-domain data is displayed. The choices are:

graph-lines  graph-dots  graph-filled  graph-lollipops  graph-dots-and-lines

(set! (time-graph-style 0 4) graph-lollipops)
graph styles
time-graph-type snd chn

If time-graph-type is graph-as-wavogram, the time domain waveform is displayed as a 'wavogram'. The default is graph-once. See also wavo-hop and wavo-trace.

tracking-cursor-style snd chn

This is the cursor-style in effect when the cursor is tracking playback (with-tracking-cursor). tracking-cursor-style can be cursor-cross or cursor-line (the default). If you want some other shape, use the function choice for cursor-style (that function's third argument can tell you when you're tracking).

transform-framples snd chn

This returns either 0 if there is no transform, transform-size if transform-graph-type is graph-once, or (list spectrum-end time-slices fft-bins) if either a sonogram or a spectrogram is being displayed.

> (set! (transform-graph?) #t) ; turn on fft display
#t
> (transform-framples)
512
> (set! (transform-graph-type) graph-as-sonogram)
1                             ; 1 = graph-as-sonogram
> (transform-framples)
(1.0 375 256)                 ; 1.0 -> full spectrum displayed
> (set! (transform-graph?) #f) ; turn off fft display
#f
> (transform-framples)
0
transform-graph? snd chn

This is #t if the given channel is displaying a spectrum (the 'f' button).

transform-graph-style snd chn

This determines how frequency-domain data is displayed. The choices are:

graph-lines  graph-dots  graph-filled  graph-lollipops  graph-dots-and-lines 
transform-graph-type snd chn

This determines the choice of spectral display. The choices are (default) graph-once (a single FFT), graph-as-sonogram, and graph-as-spectrogram. The sonogram is a set of FFTS taken at regular time intervals displayed as time vs frequency, using the width or color of the spectral portion to indicate its amplitude. The spectrogram is similar, but uses a 3D effect where the height of the line corresponds to its amplitude. Currently, the fft-log-frequency and transform-normalization choices are ignored by the spectrogram display. If you've included openGL in Snd, the spectrogram will use openGL if with-gl is #t (the default).

transform-normalization snd chn

This is the transform normalization choice (default: normalize-by-channel). If it is normalize-by-channel or normalize-by-sound, spectral data is normalized to 1.0 before display. If dont-normalize, you get the raw data values, which can reflect amplitude changes — Snd tries to choose a y axis limit that makes successive displays move smoothly. The other choice is normalize-globally (i.e. across all sounds).

transform-sample bin slice snd chn

This is the current value of the transform (if any) in 'bin' and (if a sonogram or spectrogram) 'slice' in the given channel.

transform-size snd chn

This is the fft size (the default size is 512). It should be a power of 2. If your version of Snd was built with FFTW, and you set transform-size too large (on my machine, with 2 GBytes of memory, (expt 2 26) is apparently too large), FFTW exits Snd! There is currently no way to trap the error. Also, FFTW assumes the fft size is a (signed) int — 2^30 is probably the transform-size limit.

transform-type snd chn

This is the spectrum transform type (the default is fourier-transform).

fourier-transform  wavelet-transform   haar-transform
autocorrelation    walsh-transform     cepstrum     
transform->vct snd chn v

This returns a vct with the transform data from the given channel. If 'v' (a vct) is provided, it is filled, rather than creating a new vct. See fft-peak for an example.

undo edits snd chn

This undoes 'edits' edits (the default is 1) in the given channel. Undo follows the sync field if it is not 0. The following might be a more reasonable undo function:

(define* (undo-channel (edits 1) snd chn)
  (if (and snd (not (= (sync snd) 0)) chn)
      (set! (edit-position snd chn) 
         (max 0 (- (edit-position snd chn) edits)))
      (undo edits snd)))

See also undo-hook. Since redo collides with Ruby, forcing me to change its name to redo_edit, undo can also be accessed under the name undo_edit (in Scheme, undo-edit).

Undo
undo edit: undo and undo-channel
undo all edits: revert-sound
specialize undo: undo-hook
protect against undo: edit-hook
redo edit: redo and redo-channel
move around in edit list: edit-position and current-edit-position
About edit lists: Edit lists
update-lisp-graph snd chn

This forces Snd to redisplay 'chn's' lisp graph. See enved.scm which uses the lisp graph as a local envelope editor.

update-sound snd

This causes Snd to update 'snd' (it re-reads the data from disk, flushing any pending edits). In some cases (primarily involving a change in the number of channels), update-sound can change the index of the sound referred to by 'snd'. See update-hook for a way to deal with the index confusion.

update-time-graph snd chn

This forces Snd to redisplay 'chn's' time domain graph. See color-samples in draw.scm.

update-transform-graph snd chn

This forces Snd to redisplay 'chn's' fft graph. For historical reasons, it also forces the current transform to completion.

variable-graph? index

This returns #t if 'index' refers to a variable graph (see make-variable-graph).

view-sound filename

This opens 'filename' read-only (you can edit the sound within Snd, but you can't overwrite the original sound).

wavelet-type snd chn

If transform-type is wavelet-transform, wavelet-type selects which wavelet is used. The list of available wavelets is in the Transform Dialog. There are around 48 choices, so this variable goes from 0 to 47 (the default is 0).

wavo-hop snd chn

This sets the distance upward (in pixels) between wavogram traces; that is, the smaller this number, the more traces can be displayed (the default is 3). See time-graph-type.

wavo-trace snd chn

This sets the length (in samples) of each wavogram trace (the default is 64). See time-graph-type.

with-verbose-cursor snd chn

If with-verbose-cursor is #t, the cursor's position and other information is constantly displayed in the status area. This is the View:Verbose cursor option (default: #f).

x-axis-label snd chn context

This is the current x axis label. 'context' is one of time-graph (the default), lisp-graph, or transform-graph.

> (x-axis-label)
"time"
> (set! (x-axis-label) "tempus")
"tempus"
x-axis-style snd chn

x-axis-style is the View menu 'X-axis units' option (the default value is x-axis-in-seconds). The x axis labelling of the time domain waveform can be in seconds (x-axis-in-seconds), in samples (x-axis-in-samples), expressed as a percentage of the overall duration (x-axis-as-percentage, useful in envelope definitions), as a beat number (x-axis-in-beats), as a measure number (x-axis-in-measures), or in digital clock format (DD:HH:MM:SS.ddd) (x-axis-as-clock, useful in very large files). When the x axis labelling is in measures, the label has the form M(B)F or M(B) where M is the one-based measure number (that is, the first measure, at time 0.0, is measure 1), B is the one-based beat number within that measure, and F (if present) is the location within that beat on a scale of 0.0 to 1.0. If a major tick marks a measure beginning, and there are non-measure minor ticks, then the measure is distinguished from the beat by having a longer tick mark.

x-bounds snd chn axis

This returns (list x0 x1), the current x axis bounds in seconds. To display the entire sound:

(set! (x-bounds) (/ (framples) (srate)))
x->position x snd chn axis

This returns the graph (screen pixel) position that corresponds to the x axis value 'x'. 'axis' is one of time-graph (the default), lisp-graph, or transform-graph. See draw.scm for an example.

x-position-slider snd chn

This is the value of x axis position slider. See zoom-fft in examp.scm.

x-zoom-slider snd chn

This is the value of x axis zoom slider. See zoom-one-pixel.

xramp-channel rmp0 rmp1 base beg dur snd chn edpos

xramp-channel is a slight extension of ramp-channel. It scales samples in the given sound/channel between 'beg' and 'beg' + 'dur' by an exponential ramp going from 'rmp0' to 'rmp1' with the connecting segment curvature set by 'base'.

(xramp-channel 0.0 1.0 32.0)
y-axis-label snd chn context

This is the current y axis label. 'context' is one of time-graph (the default), lisp-graph, or transform-graph.

y-bounds snd chn axis

This returns (list y0 y1), the current y axis bounds. To set the bounds to reflect the channel's maxamp, use (set! (y-bounds) ()). To set all channels at once using the selected sound's maxamp:

(let ((maxval (apply max (maxamp #f #t)))) 
  (do ((i 0 (+ i 1))) 
      ((= i (channels))) 
    (set! (y-bounds #f i) (list (- maxval) maxval))))

Or to set each channel to its own maxamp:

(do ((i 0 (+ i 1))) 
    ((= i (channels)))
  (let ((maxval (maxamp #f i))) 
    (set! (y-bounds #f i) (list (- maxval) maxval))))
y->position y snd chn axis

This returns the graph (screen pixel) position that corresponds to the y axis value 'y'. 'axis' is one of time-graph (the default), lisp-graph, or transform-graph. This is used in samples-via-colormap in draw.scm to draw the time domain samples in many colors.

y-position-slider snd chn

This is the value of y axis position slider. See zync in snd-motif.scm.

y-zoom-slider snd chn

This is the value of y axis zoom slider. See display-energy, or zync in snd-motif.scm.

zero-pad snd chn

zero-pad is the fft zero pad size as a multiple of the fft size; (set! (zero-pad) 1) gives you half data, half zeros (the default value is 0). The data length is determined by the nominal transform-size. Zero padding causes interpolation of the fft points, making the display look smoother.

(bind-key (char->integer #\p) 0 
  (lambda () 
    (set! (zero-pad) (+ (zero-pad) 1)) 
    (update-transform-graph)))

(bind-key (char->integer #\m) 0 
  (lambda () 
    (set! (zero-pad) (- (zero-pad) 1)) 
    (update-transform-graph)))
more pads
the control panel

The control panel makes it easy to try out various sound effects without editing anything. You can change volume ('amp'), pitch ('speed'), tempo ('expand'), reverb amount ('reverb'), simulated room size ('reverb len'), brightness ('contrast'), and dullness ('filter'). To treat a current setting as an edit operation, call apply-controls. For more on the effects themselves (and a pretty picture!), see the discussion in snd.html.

The control panel normally processes samples as follows: if the sampling rate conversion is on (the 'Speed' control is not 1.0), it applies srate conversion to the incoming sample; the next stage is the expansion function, if the 'Expand' toggle button is set; this value is passed next to the Contrast function, if it is running, and then the result is scaled by the Amp slider's value. The filter is run next, if it's on, and finally the sample is scaled by the reverb slider and passed to the reverb, if any, which adds its result to the sample; the final result is sent to the speakers. The control panel procedures are:

amp-control snd chn

The current amp value. It is possible to use these controls (in "real-time") in your own functions. See amprt in examp.scm for an example, or add-amp-control in snd-motif.scm. As an experiment, I added the optional 'chn' argument; if it is specified, the channel's local amp-control value is set instead of the sound's. This affects apply-controls and playback.

amp-control-bounds snd

The amp-control min and max amounts as a list. The default is (list 0.0 8.0). The value 1.0 should be in the given range, since it is placed in the middle of the slider's range. If no 'snd' argument is given, this also affects the Mix and View:Files dialogs.

apply-controls snd target beg dur

Apply the current control panel state as an edit. 'target' can be 0=sound, 1=channel, 2=selection. 'beg' sets where in samples the apply starts: (apply-controls 0 0 (mark-sample m)) starts from the given mark. 'dur', if given, sets how many samples to run through the apply process (the input duration). apply-controls can be used in conjunction with the various control panel variables:

(define (expnd amt)
  (set! (expand-control?) #t) 
  (set! (expand-control) amt) 
  (apply-controls))
def expnd(amt)
  set_expand_control? true
  set_expand_control amt
  apply_controls
end
: expnd ( amt -- ) { amt }
  #t set-expand-control? drop
  amt set-expand-control drop
  apply-controls
;

For many examples see new-effects.scm.

controls->channel settings beg dur snd chn origin

This sets up the sound's controls to reflect 'settings' (unspecified settings are not changed), then applies the controls as an edit of channel 'chn'. The 'settings' argument is a list where each entry can also be #f or an empty list:

(list amp speed
  (list contrast contrast_amp)
  (list expand expand_length expand_ramp expand_hop expand_jitter)
  (list reverb_scale reverb_length reverb_feedback reverb_low_pass reverb_decay)
  (list filter_order filter_env))
contrast-control snd

The contrast amount. The contrast-enhancement algorithm treats this variable as a kind of modulation index (the higher, the brighter), whereas contrast-control-amp below prescales the in-coming signal to be closer to -1.0 to 1.0 (the brightening effect works best if it has a full amplitude signal to work with).

contrast-control-amp snd

The contrast-control-amp (a prescaler on the contrast-enhancement to get the full effect of the compander).

contrast-control-bounds snd

The contrast-control min and max amounts as a list. The default is (list 0.0 10.0).

contrast-control? snd

#t if the contrast button is set (i.e. the contrast compander is active).

expand-control snd

The expansion amount. This sets the ratio between the output and input grain spacing. If it is greater than 1.0, the result is longer.

expand-control-bounds snd

The expand-control min and max amounts as a list. The default is (list 0.001 20.0).

expand-control-hop snd

The expansion hop amount in seconds (the distance between successive grains).

expand-control-jitter snd

The expansion grain timing jitter. This defaults to .1; if you set it to too small a number (0.0 for example), you'll probably notice (presumably unwanted) notch-filter effects.

expand-control-length snd

The expansion segment (grain) length in seconds. The longer the grain, the more reverberated or slurred the effect.

expand-control-ramp snd

The expansion ramp amount (between 0 and .5). This affects the smoothness of the grain overlaps — .001 gives a rattling effect.

expand-control? snd

#t if the expand button is set (i.e. the expansion effect is active).

filter-control-coeffs snd

The filter coefficients (read-only currently). It is a vct suitable for use with the filter generator or with filter-sound.

filter-control-envelope snd

The filter (frequency reponse) envelope (a list of breakpoints).

filter-control-in-dB snd

The filter dB button. If #t, the filter (frequency) envelope graph is displayed in dB.

filter-control-in-hz snd

If #t, the filter frequency response envelope x axis is in Hz, otherwise 0 to 1.0 (where 1.0 corresponds to srate/2).

filter-control-order snd

The filter order. This affects how much computing is needed to run the filter, and how close the filter can get to the desired frequency response envelope.

filter-control-waveform-color

The filter frequency response waveform color.

filter-control? snd

#t if the filter button is set (i.e. the filter is active).

reset-controls snd

Set all the controls to their default state.

restore-controls snd

Set all the controls to the last saved state.

reverb-control-decay snd

The length (in seconds) of the reverberation after the sound has finished (default: 1.0).

reverb-control-feedback snd

The reverb feedback coefficient. The more feedback, the happier Elvis.

reverb-control-length snd

The reverb delay line length scaler. Longer reverb simulates, to some extent, a bigger hall.

reverb-control-length-bounds snd

The reverb-control-length min and max amounts as a list. The default is (list 0.0 5.0).

reverb-control-lowpass snd

The reverb low pass filter coefficient. (This filter is in the feedback loop).

reverb-control-scale snd

The reverb amount (the amount of the direct signal sent to the reverb). You can never have enough reverb.

reverb-control-scale-bounds snd

The reverb-control-scale min and max amounts as a list. The default is (list 0.0 4.0).

reverb-control? snd

#t if the reverb button is set (i.e. the reverberator is active).

save-controls snd

This remembers the current control settings for a later restore-controls. In new-effects.scm, the effects that use the control panel internally (post-expsrc-dialog, for example) save and restore the current state via:

(save-controls)
(reset-controls)
;;; now set the ones that are of interest for the current effect
(apply-controls)
(restore-controls)
show-controls snd

#t if the sound's control panel is currently open. If set to #t, the sound's control panel is opened, else it is closed.

speed-control snd

current speed (sampling rate conversion factor). A speed of 2 plays the sound twice as fast.

speed-control-bounds snd

The speed-control min and max amounts as a list. The default is (list 0.05 20.0). If no 'snd' argument is given, this also affects the Mix, and View:Files dialogs.

speed-control-style snd

The speed control can be interpreted as a float, (speed-control-as-float, the default), as a ratio of relatively small integers (speed-control-as-ratio), or as a step in a microtonal scale (speed-control-as-semitone). In the various speed controls, you can click the number to cycle through the speed style choices.

speed-control-tones snd

The number of tones per octave in the speed-control-as-semitone speed style (default: 12).

The Options:Controls menu option starts a dialog to handle the controls that aren't handled by the control panel (expand-control-hop, expand-control-length, expand-control-ramp, contrast-control-amp, reverb-control-lowpass, and reverb-control-feedback). The control panel itself is accessible as ((sound-widgets) 2). You can add or remove controls; add-amp-controls in snd-motif.scm sets up a separate amp slider for each channel in the current sound. disable-control-panel disables (hides) the entire panel.

Edit Lists

An edit list (in other editors this is called an "edit decision list", I guess because it sounds decisive) describes the edit history of a channel. When, for example, you type C-d, nothing actually happens to any data, despite the fact that the graph no longer shows that sample, it's omitted when you play the channel, and so on. Instead, a descriptor is appended to the edit history of that channel saying "sample n was deleted". Undo and redo move around in this list (they just move the pointer to the current edit history position); all the positions are accessible just like the current one, and are exposed in many functions described above via the 'pos' or 'edpos' arguments. The edit list functions are:

as-one-edit func origin

call 'func', a function of no arguments, treating it as one edit (in all channels) in the edit history mechanism. Graphics redisplays are squelched during as-one-edit. as-one-edit returns the result of 'func'.

(as-one-edit 
  (lambda () 
    (set! (sample 100) .1) 
    (set! (sample 200) .2)))
as_one_edit(lambda do || 
  set_sample(100, 0.1)
  set_sample(200, 0.2)
  end)
lambda: 
  100 .1 set-sample drop 
  200 .2 set-sample drop
; 0 make-proc as-one-edit

See mix.scm for many examples. If you want to save and restore Snd's state after using as-one-edit, you need to set 'origin' to some string that can restore the effect of the as-one-edit; the default is to copy the last edit history string and use its associated bounds — unlikely to be what you want.

display-edits snd chn edpos

This returns the current edit list contents as a string. If 'edpos' is specified, only that position is described.

> (open-sound "oboe.snd")
#<sound 0>
> (scale-channel 2.0)
2.0
> (pad-channel 100 200)
100
> (display-edits 0 0 1)  ; show just edit 1 (the scale-channel call)
"
 (scale 0 50828) ; scale-channel 2.000 0 #f [1:2]:
   (at 0, cp->sounds[0][0:50827, 2.000]) [file: /home/bil/cl/oboe.snd[0]]
   (at 50828, end_mark)
"
edit-fragment edpos snd chn

This returns a list similar to that displayed in the edit history window giving the origin of the specified edit, its type (delete, insert, etc), its begin sample, and the number of samples affected. If 'edpos' is omitted, edit-fragment returns the currently active edit.

> (edit-fragment 2 0 0) ; continuing example above
("pad-channel" "zero" 100 200)
edit-list->function snd chn start end

This returns a function encapsulating the current edit history list, providing a way to save an edit sequence and re-apply it in some other context. For example, you can back up to some earlier point, save the edit list, make a change, then re-run the saved edit sequence. The function returned takes 2 arguments, a sound and a channel number.

> (define our-edits (edit-list->function)) ; same example as above
#<unspecified>
> our-edits
#<procedure our-edits ((snd chn) (scale-channel 2.0 0 #f snd chn) (pad-channel 100 200 snd chn))>
> (undo 2)
2
> (our-edits 0 0)
100

In Ruby:

:open_sound "oboe.snd"
0
:scale_channel 2.0
2.0
:pad_channel 100, 200
100
:our_edits = edit_list2function
#<Proc:0x40c713ec@(eval):2>
:our_edits.source
Proc.new {|snd, chn|  scale_channel(2.000, 0, false, snd, chn); pad_channel(100, 200, snd, chn) }
:undo 2
2
:our_edits.call(0, 0)
100

In Forth:

snd> "oboe.snd" open-sound
0
snd> 2.0 scale-channel
2.0
snd> 100 200 pad-channel
100
snd> 0 0 edit-list->function value our-edits
nil
snd> our-edits proc-source-ref
lambda: { snd chn } 2.000 0 #f snd chn scale-channel drop 100 200 snd chn pad-channel drop ; 2 make-proc
snd> 2 undo
2
snd> our-edits '( 0 0 ) run-proc
#f
edit-position snd chn

The current position in the edit history list; it can be set: (set! (edit-position) 0) is equivalent to (revert-sound) in a mono sound. See make-sampler.

edit-properties snd chn edpos

Each entry in a channel's edit history list has a property list (similar to the channel-properties list). If you have information that changes with the edit lists, these property lists might simplify the access code.

edit-property key snd chn edpos

edit-property returns the value associated with 'key' in the given channel's edit history list property list at edit location 'edpos'. To add or change a property, use set! with this procedure as in channel-property. The edit list property list is convenient because the associated information goes away automatically when the given edit is no longer accessible.

edits snd chn

This returns a list with the number of undo-able edits and redo-able edits. That is, if we have 2 undo-able edits and no redo-able edits, (edits) returns (list 2 0).

edit-tree snd chn edpos

This returns a list of lists completely describing current edit list. Each inner list has the form

(list global-position data-number local-position local-end scaler ramp0 ramp1 type)

If 'data-number' is -2, it marks the end of the list. In our example above (the scale-channel/pad-channel sequence):

> (edit-tree)
    ((0 0 0 99 2.0 0.0 0.0 0) (100 -1 0 199 0.0 0.0 0.0 1) 
        (300 0 100 50827 2.0 0.0 0.0 0) (51028 -2 0 0 0.0 0.0 0.0 0))
save-edit-history filename snd chn

This function saves the current edit lists in 'filename'. If 'chn' is omitted, all of the sound's channels are saved; if 'snd' is omitted, all edit lists are saved. If the underlying files are not subsequently changed, you can load this file to restore the current edit list state. save-edit-history returns #t if all went well. The following function makes an exact copy of the state (edit lists and all) of the given sound, providing a way to fork an edit path (geez, what jargon!). The idea here is to copy the complete edit state into a new sound so that two or more edit sequences can be compared.

(define sfile 0)

(define* (clone-sound-as new-name snd)
  (let* ((tmpf (snd-tempnam))
	 (scm (string-append (substring tmpf 0 (- (string-length tmpf) 3)) "scm"))
	 (oldsnd (or snd (selected-sound))))
    (if (not (string? (save-dir))) (set! (save-dir) "/tmp"))
    (save-edit-history scm oldsnd)
    (copy-file (file-name oldsnd) new-name)
    (set! sfile (open-sound new-name))
    (load scm)
    (delete-file scm)
    sfile))

We can also use save-edit-history (with some trouble) to split a sound off into an independent Snd process:

(define* (separate-sound snd)
  (let* ((tmpf (snd-tempnam))
	 (scm (string-append (substring tmpf 0 (- (string-length tmpf) 3)) "scm"))
	 (scm1 (string-append (substring tmpf 0 (- (string-length tmpf) 4)) "-1.scm"))
	 (oldsnd (or snd (selected-sound)))
	 (name (file-name oldsnd)))
    (if (string=? (save-dir) "") (set! (save-dir) "/tmp"))
    (save-edit-history scm oldsnd)
    (close-sound oldsnd)
    (with-output-to-file
	scm1
      (lambda ()
	(format #t "(define sfile (open-sound ~S))~%" name)
	(format #t "(load ~S)~%" scm)))
    (system (format #f "snd ~A &" scm1))))

It is sometimes more convenient to edit the edit history lists directly, than to run Snd and invoke the "Save session" menu option. These lists are Scheme, Ruby, or Forth programs, just like anything else discussed in this document. You could even write them from scratch. Say we want to make a stereo file that consists of four mono files mixed at various points; we know where they should go, and we have religious objections to using a graphical user interface. So we create myfile.scm, and put in it something like:

(let ((myfile (new-sound "mysound.snd" 2 44100 mus-bshort mus-aifc "this is my sound")))
	;; this is equivalent to the New file menu option
  (mix "oboe.snd" 0 0 myfile 0)
  ;; this mixes in the mono file oboe.snd at sample 0 in channel 0
  ;; use (mix "oboe.snd" 0 0 myfile 0 #f) to forego the editable mix
  (mix "pistol.snd" 0 0 myfile 1)
  ;; now pistol.snd is at sample 0 in channel 1
  (mix "fyow.snd" 10000 0 myfile 0)
  ;; add in fyow.snd at sample 10000 in the first channel
  (mix "cardinal.snd" 20000 0 myfile 1)
  ;; etc
  )

Now start Snd: snd -l myfile.scm and voila! Files like this can contain any arbitrary code, calling anything in Snd or anywhere else for that matter; you have a CLM-like notelist reader to describe sound file edits. Similarly, when you save Snd's state (via the Save session menu option or by calling the function save-state), the result is a program that can be edited just like any other such text.

Transforms

Most of the transform functions and variables have been treated above, so they are only mentioned here.

add-transform name xlabel lo hi transform

add-transform adds a transform to the transform choices (alongside fourier-transform, etc). 'name' is the name to use in the transform dialog. 'xlabel' is the x axis label of the resultant graph. 'lo' and 'hi' set which portion of the returned data to graph (normally 0.0 to 1.0). 'proc' is a function of two arguments, the length of the desired transform, and a sampler that can be used to get the current data. Do not free the sampler! The function should return a vct containing the transform data. add-transform returns the new transform's transform-type (an object). Here's an example that displays a histogram of the current values in 16 bins:

(add-transform "histogram" "bins" 0.0 1.0 
  (lambda (len fd)
    (let ((v (make-float-vector len 0.0))
          (steps (/ len 16))
          (step (/ 1.0 len)))
      (do ((i 0 (+ i 1))) 
          ((= i len) v)
        (let* ((val (read-sample fd))
               (bin (floor (* (abs val) 16.0))))
          (do ((j 0 (+ j 1))) 
              ((= j steps))
            (set! (v (+ j bin)) (+ step (v (+ j bin))))))))))

If GSL is included in Snd, the following code ties in the (slow) Hankel transform:

(add-transform "Hankel" "Hankel" 0.0 1.0
   (lambda (n rd)
      (let ((v (make-float-vector n 0.0)))
         (do ((i 0 (+ i 1))) ((= i n)) (set! (v i) (rd)))
         (gsl-dht n v 1.0 1.0)
         v)))
delete-transform type

This removes a transform that was added via add-transform.

fft rl im sgn

This performs an FFT on vcts 'rl' and 'im' (the real and imaginary parts of the input data). 'sgn' is 1 for an FFT, -1 for an inverse FFT; (the default is 1). The CLM fft function is called mus-fft in Snd. The only difference between the two is that Snd's fft determines the fft size from the size of the vcts passed to it, whereas CLM's takes the size as an argument. Here's an example that uses the fft to produce a sum of sinusoids each with arbitrary amplitude and initial-phase:

(define (fft->sines amps phases)
  (let* ((len (length phases))
	 (fft-size (expt 2 (+ 10 (ceiling (log len 2)))))
	 (rl (make-vct fft-size))
	 (im (make-vct fft-size)))
    (do ((i 0 (+ i 1)))
	((= i len))
      (let ((amp (amps i))
	    (phase (phases i)))
	(set! (rl (+ i 1)) (* amp (sin phase)))
	(set! (im (+ i 1)) (* amp (cos phase)))))
    (fft rl im -1)
    rl))
integer->transform i

This function returns the transform (type object) corresponding to a given integer.

snd-spectrum data window length (linear #t) (beta 0.0) in-place (normalized #t)

This returns the spectrum (as a vct) of 'data' (also a vct) using the fft window 'win'. 'length' is the number of samples of data.

(let ((spectr (snd-spectrum data rectangular-window (transform-size)))) 
  ...)

If 'linear' is #f (its default is #t), the spectrum is in dB. 'beta' is the fft data window family parameter; it is scaled internally so here it should be between 0.0 and 1.0. If 'in-place' is #t, the spectrum is in 'data', otherwise snd-spectrum returns a new vct.

transform->integer transform-object

This function returns the integer corresponding to a given transform type object (e.g. fourier-transform).

transform? object

This returns #t if 'object' is a transform object.

Other related variables and functions:

transform-graph?         show-transform-peaks        transform-sample
fft-window-beta          show-selection-transform    transform->vct
after-transform-hook     spectrum-end                transform-framples
fft-log-frequency        spectro-hop                 transform-type
fft-log-magnitude        spectrum-start              update-transform-graph
transform-size           spectro-x-angle             transform-normalization
transform-graph-type     spectro-x-scale             zero-pad
fft-window               spectro-y-angle             wavelet-type
max-transform-peaks      spectro-y-scale             spectro-z-scale
min-dB                   spectro-z-angle

Some FFT-based effects and editing functions:

FFTs
CLM fft function: mus-fft
CLM spectrum: spectrum
Snd spectrum: snd-spectrum
autocorrelation: autocorrelate
cross correlation: correlate, display-correlation
FFT window: make-fft-window
Dolph-Chebyshev window in Scheme: dolph
Hartley transform in Scheme: dht
Spectral edit dialog: Envelope Editor

fft-based filter: fft-edit, fft-env-edit, fft-env-interp, fft-squelch, fft-cancel
phase-vocoder: phase-vocoder. pvoc
transposition via fft: down-oct
phase rotation via fft: zero-phase, rotate-phase
duration change via autocorrelation: rubber-sound
smoothing via fft: fft-smoother
cross-synthesis: cross-synthesis
voiced->unvoiced effect: voiced->unvoiced
noise reduction: clean-channel, anoi
power spectral density: green.scm
spectral modeling: pins
polynomial approach to spectral multiplies (convolution): spectral-polynomial

Superimpose ffts: superimpose-ffts
More transforms: fractional-fourier-transform, z-transform in dsp.scm
3D (single) fft display: complexify
bark, mel, erb scale display: display-bark-fft
apply function to spectrum, inverse fft: filter-fft
Dialogs and other widgets

The built-in dialogs, accessible from the main menu, provide the standard, but sometimes clumsy ways to open and save sounds, edit envelopes and headers, and set various global variables. In addition, many other dialogs are implemented in various Scheme/Ruby/Forth files. The following functions refer to the built-in dialogs. They were aimed originally at semi-internal needs like saving the current Snd state, but might be useful elsewhere. Functions such as color-orientation-dialog normally create and start the dialog in question; that is, (color-orientation-dialog) puts the color/orientation dialog on the screen. If you're trying instead to customize the dialog in some way (in your initialization file, for example), you want the dialog to be created (so that the various widget children exist), but don't want it to pop up on the screen ('managed' in X jargon). So, most of the dialog functions have a 'managed' argument that defaults to #t. If #f, the dialog is created, if need be, but not started. install-searcher-with-colors in snd-motif.scm, which adds customized file filtering code to the File:Open dialog, first makes sure the dialog exists with (open-file-dialog #f).

add-directory-to-view-files-list dir dialog [Motif only]

This adds the sound files in directory 'dir' to the list of files in the View:Files dialog.

add-file-to-view-files-list file dialog [Motif only]

This adds 'file' to the list of files in the View:Files dialog.

add-file-filter name func

This adds 'func' to the file filter list under the name 'name'. The file filter list is a list of functions, accessed from drop-down menus in the various file-related dialogs. Each such function filters the list of files displayed by the dialog, so that only some interesting subset is posted. The built-in filter is just-sounds which uses the sound file extension tables to decide which files are sounds, omitting all others from the file lists. You can add your own filters to this menu with add-file-filter. The 'name' appears as the menu item label corresponding to the function. The function should take one argument, a file name, and return #t to retain that file in the file list. add-file-filter returns an integer to identify 'func' in other contexts.

(add-file-filter
 "mono files"
 (lambda (a)
   (and (sound-file? a)
	(= (channels a) 1))))
add-file-sorter name func [Motif only]

This adds 'func' to the file-sorter list under the name 'name'. Some dialog file lists include a "sort" menu to reorder the files in the file list. You can add your own sort functions to this menu with add-file-sorter. The 'name' appears as the menu item label corresponding to the function. The new sorter's index is returned; it is an integer for use with functions such as view-files-sort. The function should take two arguments, each a filename, and return a strcmp-like number describing how to sort the pair. The following adds a sorter named "duration" that sorts files from shorter to longer:

  (add-file-sorter
   "duration"
   (lambda (a b)
     (let ((dur1 (mus-sound-duration a))
	   (dur2 (mus-sound-duration b)))
       (if (> dur1 dur2) 1
	   (if (< dur1 dur2) -1 0)))))
add-sound-file-extension ext

This adds 'ext' to the list of (case sensitive) sound file extensions used by sound-files-in-directory. The initial list is ("snd" "aiff" "aif" "wav" "au" "aifc" "voc" "wve" "WAV" "sf2" "rf64" "caf"). To add "ogg" as a recognized extension:

 (add-sound-file-extension "ogg")

The list itself is sound-file-extensions. See also add-sound-file-extension-1.

add-to-main-menu menu-label update-callback

This adds a new top-level menu named 'menu-label' and returns its menu index. The index identifies the menu for add-to-menu and others. 'update-callback' is a procedure of no arguments that is called each time the menu is displayed.

Scheme:
(define new-menu (add-to-main-menu "New Menu"))
(add-to-menu new-menu "First Item" (lambda () (snd-print ";item 1")))
(add-to-menu new-menu "Second Item" (lambda () (snd-print ";item 2")))

Ruby:
new_menu = add_to_main_menu("New Menu")
add_to_menu(new_menu, "First Item", lambda do | | snd_print("item 1") end)
add_to_menu(new_menu, "Second Item", lambda do | | snd_print("item 2") end)

Forth:
"New Menu" add-to-main-menu constant new-menu drop
new-menu "First Item" lambda: <{ }> "item1" snd-print ; undef add-to-menu drop
new-menu "Second Item" lambda: <{ }> "item2" snd-print ; undef add-to-menu drop
add-to-menu top-menu menu-label callback position

This adds the menu 'menu-label' to the top-level menu whose index is 'top-menu' with the callback function 'callback', then returns the new menu label widget. The built-in Snd menus are numbered from 0 ('File') to 4 ('Help'). If the label and callback are #f, a separator is added to the menu. 'position' sets the position of the new menu option; it defaults to the end of the menu. See new-effects.scm for many examples.

  (add-to-menu 1 "Stop Playing" stop-playing)

  (add-to-menu 5 "Reduce height" 
    (lambda () (set! (window-height) (/ (window-height) 2))))
channel-widgets

channel-widgets returns a list of various widgets associated with a given channel:

0: graph                      ;drawing area for all 3 graphs (time, fft, lisp)
1: w-button 
2: f-button 
3: x-position slider
4: y-position slider
5: x-zoom slider
6: y-zoom slider
7: edit history list 
8: right(united-chans) y-position slider
9: right y-zoom slider
10: main pane for channel
------ the rest only in Gtk+
11..16: adjustment widgets associated with the zoom and position sliders
clear-listener

This deletes all listener text from the beginning to the cursor position (C-M-g is bound to this function).

color-orientation-dialog managed

This creates and (if 'managed' which defaults to #t) activates the Color/Orientation dialog; it returns the dialog widget.

define-envelope name data (base 1.0)

This adds an envelope to the envelope editor's list, under the name 'name', using the list of breakpoints 'data', and the optional 'base'.

Scheme: (define-envelope ramp '(0 0 1 1))
Ruby:   define_envelope("ramp", [0, 0, 1, 1])
Forth:  $" ramp" '( 0.0 0.0 1.0 1.0 ) 1.0 define-envelope
delete-file-filter index

This removes the file filter function associated with 'index' from the file filter list.

delete-file-sorter index [Motif only]

This removes the file sorter function associated with 'index' from the file sorter list.

dialog-widgets

dialog-widgets returns a list of dialog widgets (or lists thereof, or #f if none yet):

0: View: Color/Orientation dialog 
2: Edit: EnvelopeEditor dialog 
   3 and 4: unused
5: Options: Transform dialog 
6: File: Open dialog 
7: File: Save as dialog 
8: View: Files dialog 
9: raw data dialog (activated when raw sound opened, sometimes)
10: File: New sound dialog 
11: File: Mix dialog 
12: Edit: Edit header dialog 
13: Edit: Find dialog 
14: Help dialog 
16: View: Mixes dialog
17: File: Print dialog 
19: View: Regions dialog
20: info dialog (activated by info-dialog function)
21: more controls dialog
22: Edit: Selection Save as dialog
23: File: Insert file dialog
24: region save as dialog (from regions dialog save button)
25: Options: Preferences dialog
edit-header-dialog snd

This starts the Edit Header dialog on 'snd', returning the dialog widget.

enved-base 

This is the envelope editor exponential base value.

enved-clip?

This reflects the state of the envelope editor 'clip' button.

enved-dialog

This starts the envelope editor dialog, returning the dialog widget.

enved-envelope

This is the envelope (a list of breakpoints) in the envelope editor's graph window.

enved-filter

This reflects the type of the envelope editor's filter (the default #t means FIR; #f is FFT). To get the FFT display in the envelope editor as the default:

  (set! (enved-filter) #f)
  (set! (enved-wave?) #t)
  (set! (enved-target) enved-spectrum)
enved-filter-order

This is the order of the envelope editor's FIR filter (the default is 40).

enved-in-dB

This reflects the state of the envelope editor 'dB' button (it defaults to #f).

enved-power

This is the envelope editor's base scale range (it defaults to 3.0).

enved-style

This is the envelope editor choice for connecting breakpoints. It can be envelope-linear (the default), or envelope-exponential.

enved-target

This determines how the envelope editor's current envelope is applied to the selected data. The choices are enved-amplitude, enved-srate and enved-spectrum. The first treats the envelope as an amplitude envelope, the second as an srate curve (changing speed), and the last as a frequency response envelope for a filter.

enved-waveform-color

This is the color of the waveform displayed in envelope editor (the default is blue).

enved-wave?

This reflects the state of the envelope editor 'wave' button. The wave shown is the time domain display, even when filtering.

find-dialog managed text

This creates and (if 'managed' which defaults to #t) starts the Edit:Find dialog, returning the dialog widget.

focus-widget widget

This gives 'widget' "focus" — it becomes the active widget, receiving keystrokes and so on.

gl-graph->ps file (type 0) snd chn

This creates a Postscript picture of the current openGL display in snd's channel chn (a spectrogram). 'file' defaults to eps-file. 'type' can be 0: eps, 1: ps, 2: pdf, 3: tex, 4: svg, or 5: pgf. This function is available only if OpenGL and gl2ps have been loaded (via the --with-gl and --with-gl2ps configuration switches).

goto-listener-end

This moves the cursor to the end of the listener text, and scrolls the window so that it is visible.

graph->ps file

This creates a Postscript picture of the current display. 'file' defaults to eps-file. See also eps-bottom-margin, eps-left-margin, and eps-size.

help-dialog subject help-string xrefs urls

This starts the help dialog with the title 'subject' and help area text 'help', returning the dialog widget. 'xrefs' is an optional list of strings to post in the "related items" list. 'urls' is a corresponding list of urls. There are many examples in new-effects.scm.

(define-macro (with-snd-help form)
  ;; if an error occurs while evaluating form, try to start the help dialog with some relevant help
  `(catch #t 
	  (lambda ()
	    ,form)
	  (lambda args
	    (if (and args (cadr args) (string? (cadr args)))
		(let* ((func (if (string=? "set!" (substring (cadr args) 0 4))
				(substring (cadr args) 5)
				(cadr args)))
		       (help (snd-help func)))
		  (if help (help-dialog func help))))
	    args)))
hide-widget widget

This hides (unmanages) 'widget'. To remove the y-position slider (which is only there for looks):

(hide-widget ((channel-widgets) 4))
info-dialog subject info

This starts the info dialog with the title 'subject' and body 'info' returning the dialog widget.

insert-file-dialog managed

This creates and (if 'managed' which defaults to #t) activates the File:Insert dialog, returning the dialog widget.

listener-color

This is the background color of listener.

(set! (listener-color) (make-color 0 0 0))
listener-colorized

This determines whether the listener displays the code with syntax highlights in the Gtk version of Snd. The colors can be changed with colorizer-colors.

listener-font

This is the listener font.

listener-prompt

This is the listener prompt which defaults to ">". I like ":" better (as you can see in many of the examples in this file), so in ~/.snd_s7 I have this line:

(set! (listener-prompt) ":")
listener-selection

listener-selection returns the currently selected text in the listener, or #f if there isn't any. The following code starts the help dialog with help related to the selection if "h" is typed in the graph:

(bind-key #\h 0 
  (let ((documentation "start help dialog based on listener selected text"))
    (lambda ()
      (let ((subject (listener-selection)))
        (if subject
            (help-dialog subject (snd-help subject)))))))
listener-text-color

This is the text color in the listener. For red text on a black background:

(set! (listener-color) (make-color 0 0 0)) ; in Gtk, maybe a bad idea — the cursor remains black...
(set! (listener-text-color) (make-color 1 0 0))
main-menu menu

main-menu returns the top-level menu associated with its integer argument:

0: File menu
1: Edit menu
2: View menu
3: Options menu
4: Help menu
and others as added by add-main-menu
main-widgets

main-widgets returns a list of the top-level widgets in Snd (#f if not created):

0: top-level-application      ; XtAppContext in Motif, top level window in Gtk+
1: top-level-shell 
2: main-pane                  ; outer paned window top window (holds sounds)
3: main-sound-pane 
4: listener-pane              ; outer paned window bottom window
5: notebook-outer-pane

For example, to get at Snd's main shell widget:

Scheme:    (cadr (main-widgets)) 
Ruby:      main_widgets.cadr
Forth:     main-widgets cadr

In Gtk 3.1 or later, we can use this to fire up a modal font chooser dialog:

> (define (get-font)
  (with-let *gtk*
    (let ((fonts (gtk_font_chooser_dialog_new "fonts" (GTK_WINDOW (cadr (main-widgets))))))
      (let ((response (gtk_dialog_run (GTK_DIALOG fonts)))) ; don't return until a choice is made 
        (let ((name (if (= response GTK_RESPONSE_OK)        ;   (cancel = GTK_RESPONSE_CANCEL)
	                (gtk_font_chooser_get_font (GTK_FONT_CHOOSER fonts))
		        'no-font-selected)))                ; perhaps pass in the current value instead?
	  (gtk_widget_destroy (GTK_WIDGET fonts))           ; clean up after the dialog
	  name)))))                                         ; return new font
get-font

> (set! (listener-font) (get-font))
"Monospace Bold Italic 10"
menu-widgets

menu-widgets returns the top-level menu widgets (cascade menus in Motif or menu bars in Gtk+) as a list:

0: top-level-menu-bar 
1: file-menu
2: edit-menu 
3: view-menu 
4: options-menu 
5: help-menu

See snd-motif.scm, snd-gtk.scm, and new-effects.scm for various examples. Manipulating menus can be tricky in both Motif and Gtk; if I were to try to explain submenus and whatnot here, I'd only get tangled up in half-forgotten complications. When I have to deal with this stuff, I always go to a working example.

mix-dialog-mix

This is the id (mix object) of the mix displayed by the mix dialog.

mix-file-dialog managed

This creates and (if 'managed' which defaults to #t) activates the File:Mix dialog, returning the dialog widget.

new-sound-dialog managed

This creates and (if 'managed' which defaults to #t) starts the File:New sound dialog, returning the dialog widget.

open-file-dialog managed

This creates and (if 'managed' which defaults to #t) activates the File:Open dialog, returning the dialog widget.

preferences-dialog

This activates the Options:Preferences dialog.

print-dialog managed direct-to-printer

This creates and (if 'managed' which defaults to #t) activates the File:Print dialog, returning the dialog widget.

remove-from-menu top-menu menu-label

This removes the menu 'menu-label' from the top top-level menu whose index is 'top-menu'. See examp.scm or snd-motif.scm.

reset-listener-cursor

This resets the listener cursor to the default pointer shape.

save-as-dialog-auto-comment

This is the 'auto' button in the Save-as dialogs. If set, a comment is automatically generated for the new file.

save-as-dialog-src

This is the 'src' button in the Save-as dialogs. If set, sampling rate conversion is performed if the output srate does not match the original srate.

save-envelopes filename

This saves the envelope editor envelopes in 'filename'.

save-listener filename

This saves the listener contents in 'filename'.

save-region-dialog managed

This creates and (if 'managed' which defaults to #t) starts the Region Save-as dialog (to save the current Region browser region), returning the dialog widget.

save-selection-dialog managed

This creates and (if 'managed' which defaults to #t) starts the Edit:Save selection as dialog (to save the current selection), returning the dialog widget.

save-sound-dialog managed

This creates and (if 'managed' which defaults to #t) starts the File:Save as dialog (to save the currently selected sound), returning the dialog widget.

show-listener

If show-listener is set to #t, Snd opens the listener pane; otherwise it closes the listener.

show-widget widget

This shows (manages) 'widget'.

sound-file-extensions

This is the list of sound file extensions used by the "just-sounds" buttons and sound-files-in-directory to try to recognize sound files. It is settable: a list of extensions as strings:

(set! (sound-file-extensions) 
  (list "snd" "aiff" "aif" "wav" "au" "aifc" "voc" "wve" "WAV" "sf2" "rf64" "caf"))
sound-file? filename

This returns #t if 'filename' has an extension that matches one in the sound-file-extensions list.

> (sound-file? "oboe.snd")
#t
> (sound-file? "extsnd.html")
#f
sound-files-in-directory dir

This returns a list of the sound files found in 'dir'. A file is considered a sound if it has data and its extension is on the sound file extension list (see add-sound-file-extension). The directory name defaults to the current directory. This is useful for batch processing of sounds. The following prints the names of all the stereo AIFC files it finds:

(for-each
  (lambda (filename)
    (if (and (= (mus-sound-header-type filename) mus-aifc)
             (= (channels filename) 2))
        (snd-print (format #f "~%~A" filename))))
  (sound-files-in-directory))

See also map-sound-files in extensions.scm.

sound-widgets

sound-widgets returns a list of various widgets specific to a given sound:

0: main-pane 
1: name-label                 ; sound's file name
2: control-panel 
3: status area 
4: play button
5: filter-graph               ; control panel drawing area for filter envelope
6: unite button               ; invisible in mono sounds
8: name-icon                  ; hour-glass or whatever
9: sync button

For example, we can read and write the status area:

Scheme:
> (status-report "this is a test")
"this is a test"
> (widget-text ((sound-widgets) 3))
"this is a test"
    
Ruby:
:status_report("this is a test")
this is a test
:widget_text(sound_widgets()[3])
this is a test
    
Forth:
snd> "this is a test" status-report
this is a test
snd> 0 sound-widgets 3 list-ref widget-text
this is a test
transform-dialog managed

This creates and (if 'managed' which defaults to #t) activates the Options:Transform dialog, returning the dialog widget.

view-files-amp dialog [Motif only]

This is the value of the amplitude slider in the View:Files dialog.

view-files-amp-env dialog [Motif only]

This is the amplitude envelope displayed in the View:Files dialog.

view-files-dialog managed [Motif only]

This creates and (if 'managed' which defaults to #t) activates a View:Files dialog and returns the dialog widget.

view-files-files dialog [Motif only]

This is the file list (a list of strings) of a View:Files dialog.

view-files-selected-files dialog [Motif only]

This is the list of selected files (a list of strings) in a View:Files dialog.

view-files-sort dialog [Motif only]

This is the sort function choice in a View:Files dialog. Initially there are 6 sort choices: a..z, z..a (sort by file name), new..old, old..new (sort by file write date), and small..big, big..small (sort by file size). The default is 0 (a..z). If you set view-files-sort without giving the dialog argument, it just affects the startup state of subsequent new View:Files dialogs. To set the sort choice in the current dialog:

  (set! (view-files-sort ((dialog-widgets) 8)) 2) ; 2=new..old
view-files-speed dialog [Motif only]

This is the value of the speed slider in a View:Files dialog.

view-files-speed-style dialog [Motif only]

This is the speed style choice in a View:Files dialog. It is one of speed-control-as-float (the default), speed-control-as-ratio, or speed-control-as-semitone.

view-mixes-dialog

This creates and activates the View:Mixes Dialog, returning the dialog widget.

view-regions-dialog

This starts the region browser (a no-op if there are no regions), and returns the dialog widget.

widget-position widget

This returns a list giving the widget's x and y coordinates (in pixels). It can be set to reposition the widget. See nb.scm where it uses the current window position to try to find a convenient place for the help dialog.

widget-size widget

This returns a list giving the widget's width and height (in pixels). It can be set to resize the widget. See nb.scm and examp.scm.

(set! (widget-position (cadr (main-widgets))) (list 300 100))
widget-text widget

This returns the text widget's text. It can be set.

Miscellaneous functions
abort

This exits Snd via "abort", presumably to fall into the C debugger. To stop some on-going Snd operation, use C-g.

add-source-file-extension ext

add-source-file-extension adds 'ext' to the list of source file extensions.

(add-source-file-extension "rbs")
bes-j0 x
bes-j1 x
bes-jn n x
bes-y0 x
bes-y1 x
bes-yn n x
bes-i0 n x
bes-i1 n x ; from GSL
bes-in n x
bes-k0 x
bes-k1 x
bes-kn n x

If the Bessel functions are available from the math library (or GSL), these are J0 and friends.

bind-key key state func extended origin

bind-key causes 'key' (an integer or a key name) with modifiers 'state' (and preceding C-x if 'extended') to evaluate 'func' when the graph is receiving keysrokes. If bind-key seems to be a no-op, try clicking in the graph to force it to take the focus. If 'origin' is included, it is the name reported if an error occurs. The default is a description of the key.

The function ('func' above) should take zero or one arguments and return one of the cursor choices telling Snd what action (if any) to take after evaluating 'code'. Possible return values are:

cursor-in-view  cursor-on-left  cursor-on-right  cursor-in-middle  keyboard-no-action

If the function takes one argument, that argument is the count (the C-u number prefixed to the keyboard command) defaulting to 1 if no prefix is typed.

The modifier 'state' is a combination of control = 4 and meta = 8. If the key argument is a string (a key name) it has to match exactly one of the known key names. In X, these can be found in <X11/xkeysymdef.h>, and in Gtk in gdk/gdkkeysyms.h; in both cases, remove the XK_ or GDK_ prefix. So, for example, the key marked "Page Down" is named "Page_Down" in both tables. Similarly "+" is "plus".

  Scheme: (bind-key "End" 0 (lambda () "view full sound" (set! (x-bounds) (list 0.0 (/ (framples) (srate))))))

  Ruby: bind_key("End", 0, lambda do || set_x_bounds([0.0, framples.to_f / srate.to_f]) end)

  Forth: "End" 0 lambda: 0.0 #f #f #f framples #f srate f/ 2 >list set-x-bounds ; 0 make-proc bind-key
(bind-key "Home" 0 
           (lambda () 
	     (let ((ed (edit-fragment))) 
	       (status-report (format #f "~A" ed)) 
	       (set! (cursor) (caddr ed)) 
	       cursor-in-view)))

(bind-key #\p 0 
          (lambda () 
            cursor-on-left)
          #f "#\\p->cursor-on-left")

(bind-key #\v 4
	  (lambda ()
	    (if (< (right-sample) (framples))
		(set! (left-sample) (right-sample)))
	    keyboard-no-action))

(bind-key #\v 0 
          (lambda () 
            (set! (sample (cursor)) (* 0.5 (+ (sample (- (cursor) 1)) (sample (+ 1 (cursor)))))) 
            cursor-in-view))

We can use bind-key to turn the keyboard into a sort of extended piano:

(bind-key #\o 0 
  (lambda ()
    (play "oboe.snd") 
    keyboard-no-action))

(bind-key #\p 0 
  (lambda ()
    (play "pistol.snd") 
    keyboard-no-action))

Now each time we hit "o", "oboe.snd" plays, etc. Or say we want to move forward two samples in the graph each time we type "l":

(bind-key #\l 0 
  (lambda ()
    (set! (left-sample 0 0) (+ 2 (left-sample 0 0))) 
    keyboard-no-action))

Or, more useful perhaps, have C-c set the cursor at a particular sample:

(bind-key #\c 4
  (lambda (arg)
    (set! (cursor) arg) 
    cursor-in-middle))

A similar set rebinds the arrow keys to give much more precise window position and size control:

(define (move-one-pixel s c right)
  (let* ((ax (axis-info s c time-graph))
	 (lo (ax 0))
	 (hi (ax 1))
	 (lo-pix (ax 10))
	 (hi-pix (ax 12))
	 (samps-per-pixel (max 1 (round (/ (- hi lo) (- hi-pix lo-pix)))))
	 (change (if right 
                     (- (min (+ hi samps-per-pixel) (framples s c)) hi)
                     (- (max 0 (- lo samps-per-pixel)) lo))))
    (set! (left-sample) (+ lo change))
    keyboard-no-action))

(bind-key "Left" 0     ;left arrow
  (lambda () 
    (move-one-pixel (selected-sound) (selected-channel) #f)))

(bind-key "Right" 0    ;right arrow
  (lambda () 
    (move-one-pixel (selected-sound) (selected-channel) #t)))

(define (zoom-one-pixel s c in)
  (let* ((ax (axis-info s c time-graph))
	 (lo (ax 0))
	 (hi (ax 1))
	 (lo-pix (ax 10))
	 (hi-pix (ax 12))
	 (samps-per-pixel (max 1 (round (/ (- hi lo) (- hi-pix lo-pix)))))
	 (len (framples s c)))
    (if in
	(if (> (- hi-pix lo-pix) samps-per-pixel)
	    (begin
	      (set! (left-sample) (+ lo samps-per-pixel))
	      (set! (x-zoom-slider) 
                (* 1.0 (round (/ (max samps-per-pixel (- hi lo (* 2 samps-per-pixel))) len))))))
	(begin
	  (set! (left-sample) (max 0 (- lo samps-per-pixel)))
	  (set! (x-zoom-slider) 
            (* 1.0 (round (/ (min len (+ (- hi lo) (* 2 samps-per-pixel))) len))))))
    keyboard-no-action))

(bind-key "Up" 0     ;up arrow
  (lambda () 
    (zoom-one-pixel (selected-sound) (selected-channel) #f)))

(bind-key "Down" 0   ;down arrow
  (lambda () 
    (zoom-one-pixel (selected-sound) (selected-channel) #t)))

The key bindings set by bind-key are active only when the active widget is a graph; when the listener is receiving key strokes, the underlying text widget interprets them itself (using Emacs as a vague guide). You can change the listener's interpretation in the following manner (this assumes you're using Motif and have the xm module loaded):

(XtAppAddActions (car (main-widgets)) (list (list "hiho" (lambda args (snd-print "hiho")))))
(XtOverrideTranslations ((main-widgets) 4) (XtParseTranslationTable "Ctrl <Key>i: hiho()\n"))

Since neither Motif nor Gtk explicitly support an Emacs-like extended mode, we have to go to a bit of trouble to add an extended command to the listener. The following implements C-x C-f in either Motif or Gtk:

;;; Motif version:

(define extended #f)     ; our extended mode flag

(XtAddEventHandler ((main-widgets) 4) KeyPressMask #f
  (lambda (w context event go)
    (let* ((bits (.state event))
	   (keysym (XKeycodeToKeysym (XtDisplay w)
				    (.keycode event)
				    (if (not (= (logand bits ShiftMask) 0)) 1 0))))
      (if (= (logand bits ControlMask) 0)
	  (set! extended #f)
	  ;; got C-<something>
	  (if (= (cadr keysym) 120) ; C-x
	      (set! extended #t)
	      (begin
		(if (and extended
			 (= (cadr keysym) 102)) ; C-x C-f
		    (open-file-dialog))
		(set! extended #f)))))))


;;; Gtk version:

(define extended #f)     ; our extended mode flag

(let ((listener ((main-widgets) 4)))
  (g_signal_connect_closure_by_id 
   (GPOINTER listener)
   (g_signal_lookup "key_press_event" (G_OBJECT_TYPE (G_OBJECT listener)))
   0
   (g_cclosure_new (lambda (w event data)
		     (let ((bits (.state (GDK_EVENT_KEY event)))
			   (key (.keyval (GDK_EVENT_KEY event))))
		       (if (= (logand bits GDK_CONTROL_MASK) 0)
			   (set! extended #f)
			   ;; got C-<something>
			   (if (= key 120) ; C-x
			       (set! extended #t)
			       (begin
				 (if (and extended
					  (= key 102))
				     (open-file-dialog))
				 (set! extended #f))))
		       #f))
		   #f #f)
   #f))
break

In s7, this places a breakpoint at the current code location. If you hit the breakpoint, the listener prompt reflects the current function name (if any), and any typing at that point is evaluated in the local environment (so you have access to function arguments and local variables). To continue from the breakpoint, (break-ok). To exit back to the top level, (break-exit):

c-g?

This checks for C-g to interrupt an on-going computation, and lets other UI events through. It is obsolete in s7.

erf x
erfc n x

These are the erf and erfc functions from the math library.

exit exit-value

This exits Snd. Scheme's exit function is renamed %exit. In Forth, this function is snd-exit. The hooks associated with this function are:

before-exit-hook — can cancel exit request
exit-hook
Snd cleans up and exits
fmod x y

fmod is mod with float arguments:

> (fmod 2.5 1.4)
1.1

In Scheme, fmod is a synonym for modulo.

gc-off

gc-off turns garbage collection off, if possible.

gc-on

gc-on turns garbage collection on.

in ms thunk

'ms' milliseconds from now, evaluate 'thunk', a function of no arguments. In Ruby, this is named "call_in".

(in 5000 (lambda () (snd-print "boo!")))
(define (at hour minute func)
  (let* ((cur-time (localtime (current-time)))
	 (cur-minute (cur-time 1))
	 (cur-hour (cur-time 2))
	 (now (+ (* cur-hour 60) cur-minute))
	 (then (+ (* hour 60) minute)))
    (in (* 1000 60 (- then now)) func)))

(at 15 11 (lambda () (snd-print "it's 3:11 pm!")))
key key state snd chn

This executes the keyboard command 'key' with modifier keys 'state'. 'state' is a combination of control = 4 and meta = 8.

key-binding key (state 0) extended

This returns the user-defined (not built-in) procedure, if any, currently bound to 'key' with 'state' and 'extended' flags. 'state' is a combination of control = 4 and meta = 8. 'extended' is #t if the command is preceded by C-x.

> (key-binding "Right" 0)
#<procedure #f (() "move one pixel forward" (move-one-pixel (selected-sound) (selected-channel) #t))>
lgamma x

This is the lgamma function from the math library.

little-endian?

This returns #t if underlying machine is little endian.

save-state filename

This saves the current state of Snd in 'filename'. The saved-state file is a Scheme/Ruby/Forth program that when loaded into Snd, recreates the state of Snd (as far as possible) at the point of the save. save-state-hook is called during the saving process (once on each temp file), and after-save-state-hook is called afterwards. 'filename' defaults to save-state-file which itself defaults to "saved-snd.scm" or some variant thereof.

There are a variety of limitations to this process; the worst is that save-state does not try to save hook values or global variable values. If you call save-state with active regions, and have the region browser running all the time, and subsequently want to back up to the saved state, it's safer to delete all the regions first (via forget-region), then load the saved-state file.

script-arg

This is the current startup argument number (normally 1). See Snd as a script engine and snd-test.scm.

script-args

This returns the startup arguments as a list of strings. See Snd as a script engine and snd-test.scm.

snd-error str

This throws 'snd-error with the error message 'str'. It provides a way to dive directly into Snd's error handling mechanism. See also mus-error-hook and snd-error-hook.

snd-help obj (formatted #t)

This returns the help text associated with 'obj':

Scheme:
> (snd-help 'open-sound)   ; or "open-sound"
"(open-sound filename) opens filename (as if opened from File:Open menu option), 
and returns the new sound's index"

Ruby:
:snd_help("close_sound")  ; or :open_sound
close_sound((snd false)): close snd

Forth:
snd> "revert-sound" snd-help
(revert-sound (snd #f)): revert snd to its unedited state (undo all)

If no help string can be found, or if the name doesn't come close to any currently defined name, snd-help runs through the current load path searching *.scm (or *.rb) files for a definition of that name. So, if you haven't loaded dsp.scm:

> (snd-help "volterra-filter")
"volterra-filter is not defined; it appears to be defined in:
/home/bil/cl/dsp.scm:1936> (define (volterra-filter flt x) 
and documented at sndscm.html#volterrafilter"

snd-help tries to be smart about minor mispellings:

> (snd-help "close-soud")
"(close-sound (snd #f)): close snd
Other possibilities:
close-sound is defined; it is documented at extsnd.html#closesound"

To go to the HTML documentation for a given object, load index.scm and use the html function.

Normally snd-help adds carriage-returns to fit the current size of the listener; to get the raw string instead, set the argument 'formatted' to #f (or use s7's help function).

snd-version

This is a string giving the current Snd version.

*snd-opened-sound*

When a sound file is opened, Snd looks for a file with the same name but with an appended ".scm" extension. If such a file is found, it is loaded automatically. The variable *snd-opened-sound* is set to the newly opened sound (the object). This supports the snd-memo feature in the CL version of CLM, but can be used independently of CLM to store marks, selections, or whatever that you want associated with a particular sound. Confusingly enough, this is a variable, unlike all the others — that is, you refer to it directly, not as a procedure call. Say we have a sound file "now.snd", and we want it to use the grid-graph whenever it is viewed. We make "now.snd.scm" and put in it: (set! (show-grid *snd-opened-sound*) #t). When "now.snd" is opened, "now.snd.scm" is loaded automatically with *snd-opened-sound* holding the sound object of "now.snd".

snd-print str

This displays 'str' in the listener, then returns 'str'.

snd-tempnam

This returns a new temp file name using Snd's temp-dir.

> (temp-dir)
"/home/bil/zap/tmp"
> (snd-tempnam)
"/home/bil/zap/tmp/snd_7000_2.snd"
snd-url name

This is the url (in the Snd documentation) corresponding to 'name'; 'name' can be a string or a symbol.

> (snd-url 'open-sound)
"extsnd.html#opensound"
snd-urls

This returns a list of lists, each inner list containing a Snd function name (as a string) and its associated url in the Snd documentation.

> (assoc "open-sound" (snd-urls))
("open-sound" . "extsnd.html#opensound")
snd-warning str

This posts a 'str' in the status area and returns 'str'. See also snd-warning-hook.

unbind-key key state extended

This causes 'key' with modifiers 'state' and 'extended' to revert to its built-in default.

Constants

Sndlib (see sndlib.html for a complete list):

mus-next mus-aifc mus-riff mus-rf64 mus-nist mus-raw mus-ircam mus-aiff
mus-bicsf mus-soundfont mus-voc mus-svx mus-caff

mus-bshort  mus-lshort mus-mulaw  mus-alaw   mus-byte   mus-ubyte   mus-bfloat
mus-lfloat  mus-bint   mus-lint   mus-b24int mus-l24int mus-bdouble mus-ldouble
mus-ubshort mus-ulshort

mus-out-format

Time domain graph type (time-graph-type):

  graph-once  graph-as-wavogram

Transform graph type (the Transform Options Display choice, transform-graph-type):

  graph-once  graph-as-sonogram  graph-as-spectrogram

Transform type (transform-type):

  fourier-transform  wavelet-transform   cepstrum   haar-transform
  autocorrelation    walsh-transform

Transform normalization (transform-normalization):

  dont-normalize     normalize-by-channel    normalize-by-sound    normalize-globally

FFT Window type (fft-window):

  rectangular-window     hann(ing)-window      welch-window         parzen-window
  bartlett-window        hamming-window        blackman2-window     blackman3-window
  blackman4-window       exponential-window    riemann-window       kaiser-window
  cauchy-window          poisson-window        gaussian-window      tukey-window
  dolph-chebyshev-window hann-poisson-window   connes-window        samaraki-window
  ultraspherical-window  bartlett-hann-window  bohman-window        flat-top-window
  blackman5-window       blackman6-window      blackman7-window     blackman8-window       
  blackman9-window       blackman10-window     rv2-window           rv3-window
  rv4-window             mlt-sine-window       papoulis-window      dpss-window
  sinc-window

Zoom Focus style (zoom-focus-style):

  zoom-focus-left    zoom-focus-right   zoom-focus-active zoom-focus-middle

X-axis Label (x-axis-style):

  x-axis-in-seconds  x-axis-in-samples  x-axis-as-percentage  x-axis-in-beats  x-axis-in-measures x-axis-as-clock

Speed Control style (speed-control-style, view-files-speed-style):

  speed-control-as-float     speed-control-as-ratio     speed-control-as-semitone

Channel Combination style (channel-style):

  channels-separate  channels-combined  channels-superimposed

Envelope Editor target (enved-target):

  enved-amplitude      enved-spectrum       enved-srate

Envelope Editor ramp choice (enved-style):

  envelope-linear   envelope-exponential

Graph Line style (graph-style):

  graph-lines        graph-dots         graph-filled      graph-lollipops
  graph-dots-and-lines 

Key binding cursor action (bind-key):

  cursor-in-view     cursor-on-left     cursor-on-right   cursor-in-middle  keyboard-no-action

Cursor style (cursor-style):

  cursor-cross   cursor-line

Axis placement choice (show-axes):

  show-all-axes  show-no-axes  show-x-axis  show-all-axes-unlabelled  show-x-axis-unlabelled  show-bare-x-axis

Graph id (for y->position etc):

  time-graph     transform-graph     lisp-graph

Colormap choice (colormap):

  black-and-white-colormap gray-colormap     hot-colormap     cool-colormap
  bone-colormap            copper-colormap   pink-colormap    jet-colormap
  prism-colormap           autumn-colormap   winter-colormap  spring-colormap
  summer-colormap          rainbow-colormap  flag-colormap    phases-colormap

Graphics context choice (graph-data)

  copy-context   cursor-context   selection-context  mark-context
Errors and debugging

When something goes awry, the various functions can throw an error (a symbol) which is normally caught by the default error handler (this is a kind of goto but without the embarrassment). It prints out some message, and sometimes appends a stack trace. So, as an example, selection-position throws 'no-active-selection if there isn't a selection:

> (selection-position)
selection-position: no-active-selection
> asdf
Unbound variable: asdf

But there are cases where you'd rather handle an error (or all errors) specially. In the case of 'no-active-selection, we set up our own handler for that as follows:

> (catch 'no-active-selection 
    (lambda () 
      (+ 1 (selection-position))) 
    (lambda (tag val) 0))
0

Here we've caught 'no-active-selection (if it occurs within the first thunk's body), and return 0 if it occurs; otherwise we return (+ 1 (selection-position)). Scheme has a number of errors such as 'out-of-range, 'wrong-type-arg, 'numerical-overflow, etc. The Snd-specific errors are:

'no-such-channel  'no-such-sound  'no-such-mark       'no-such-mix
'no-such-menu     'no-such-file   'no-such-region     'no-such-sample
'no-such-edit     'cannot-save    'no-such-envelope   'no-active-selection
'no-such-widget   'mus-error                          'bad-arity
'cannot-print     'no-such-axis   'no-such-player     'no-such-graphics-context
'no-such-color    'no-such-widget 'no-such-plugin     'no-data
'gsl-error        'no-such-key    'no-such-direction  'cannot-parse
'no-such-colormap

bad-arity is jargon indicating that a procedure has been passed the wrong number of arguments. gsl-error indicates that the GSL library is the source of the error. The symbol #t stands for all errors in this case, so we can run rough-shod over any error with:

(define-macro (without-errors func)
  `(catch #t 
	  (lambda ()
	    ,func)
	  (lambda args 
            (car args))))

You can use these errors in your code, if you like, or add your own. The following throws the error 'no-such-file:

(define look-for-file
  (lambda (file)
    (or (file-exists? file)
	(error 'no-such-file (list "look-for-file" file)))))

There is one special catch: 'snd-top-level. This is used by the debuggers to exit the current context, returning up a level in the stack of listeners. Normally that means you jump out of a breakpoint or whatever and find yourself back at the top level. (throw 'snd-top-level).

s7 debugging

When s7 hits an error, it prints out a stacktrace as well as the error message. The owlet has additional info. You can also trace functions, and place breakpoints. See s7.html for further details.

Forth debugging

See the debugging section in the fth documentation.

Ruby debugging

$DEBUG = true turns on the Ruby debugger.

C debugging

If you hit a bug in Snd's C code, you'll need to use gdb to track it down, or mail me the gory details; if the error is a segfault, there is probably a file named "core" or "core.nnnn" on the current directory:

gdb snd core
where

The "where" command displays the stack at the point of the error. "up", and "down" move around in the stack, and "info locals" prints out the current frame's variables. If it's not a segfault, you can

gdb snd
run

Then get the error to happen, at which point you should fall into gdb where you can type "where" and so on. If the problem involves X, you may need to run -sync. If Gtk, run --g-fatal-errors. If Snd gets hung and you need to type C-C to get out (that is, C-g doesn't interrupt the loop),

gdb snd
break exit
run
Customizing Snd's appearance

Snd's overall appearance is controlled first by the startup switches that choose the outermost widget; normally this is a paned window with a sound in each pane; -separate puts each sound in a separate window, and -notebook puts each sound on a separate page of a notebook widget. Similarly -horizontal and -vertical determine which way the outer panes are laid out. There are a variety of functions and variables related to widget colors and so forth.

Colors

A color in Snd is an object with three fields representing the rgb (red green blue) settings as numbers between 0.0 and 1.0. A color object is created via make-color:

> (define blue (make-color 0 0 1))

This declares the Scheme variable "blue" and gives it the value of the color whose rgb components include only blue in full force. The X11 color names are defined in rgb.scm. The overall widget background color is basic-color.

> (set! (basic-color) blue)

The color variables are:

axis-color                    black           color of axes
basic-color                   ivory2          main Snd color.
combined-data-color           black           color of channel data if channels-combined
cursor-color                  red             graph cursor color.
data-color                    black           color of data in unselected graph.
enved-waveform-color          blue            color of waveform displayed in envelope editor.
filter-control-waveform-color blue            color of control panel filter waveform.
graph-color                   white           background color of unselected graph.
highlight-color               ivory1          highlighting color.
listener-color                aliceblue       background color of listener.
listener-colorized            #f              is syntax highlighting in effect.
listener-text-color           black           text color in listener.
mark-color                    red             color of mark indicator.
mix-color                     darkgray        color of mix waveforms.
position-color                ivory3          position slider color
sash-color                    lightgreen      color of paned window sashes.
selected-data-color           black           color of data in currently selected graph.
selected-graph-color          white           background color of currently selected graph.
selection-color               lightsteelblue1 color of selected portion of graph.
text-focus-color              white           color of text field when it has focus.
zoom-color                    ivory4          zoom slider color.

I have these lines in my ~/.snd_s7 file:

(define beige (make-color 0.96 0.96 0.86))
(define blue (make-color 0 0 1))
(set! *selected-graph-color* beige)
(set! *selected-data-color* blue)

In Forth (~/.snd_forth) this is:

0.96 0.96 0.86 make-color ( beige ) set-selected-graph-color drop
0.00 0.00 1.00 make-color ( blue )  set-selected-data-color drop

And in Ruby (~/.snd_ruby):

beige = make_color 0.96, 0.96, 0.86
blue = make_color 0, 0, 1
set_selected_graph_color beige
set_selected_data_color blue

combined-data-color is slightly special. It takes two arguments, the sound and channel number, and applies to the channel's data only if the graphs are superimposed, when channel-style is channels-combined.

Colors
Other color-related stuff:
Color names: rgb.scm, rgb.rb
colors in the file dialogs: install-searcher-with-colors in snd-motif.scm
color-orientation-dialog: color-orientation-dialog
colored samples: display-colored-samples and others in draw.scm
colored edits: display-previous-edits in draw.scm
colored marks: mark-sync-color in snd-motif.scm
colors in rxvt: red-text et al in examp.scm
flashing colors: flash-selected-data in examp.scm
openGL: snd-gl.scm, Snd and OpenGL
color hook: color-hook
Snd graphics contexts: snd-gcs
Fonts

Fonts in Snd are strings containing a description of the desired font. These can be the abbreviated forms such as "8x14" or a full X font name such as "-misc-fixed-bold-r-normal--*-140-*-*-*-*-*-*". In Gtk, the font names resemble "Monospace 10", etc. The font variables are:

axis-label-font     used in axis labels
axis-numbers-font   used in axis tick numbers
bold-peaks-font     used by fft peaks display
peaks-font          used by fft peaks display
listener-font       listener font
tiny-font           smallest font used
(set! (listener-font) "9x15")
(set! (axis-label-font) "-*-times-medium-r-normal-*-18-*-*-*-*-*-*-*")
(set! (axis-numbers-font) "9x15")

See also current-font below. If the requested font can't be loaded, the set! statement returns the old (unchanged) font name.

> (set! (axis-label-font) "8x14")
"-*-times-medium-r-normal-*-18-*-*-*-*-*-*-*"
Graphics
add-colormap name func

add-colormap adds a new colormap to the colormap table, returning the colormap object (for use with colormap or colormap-ref). 'name' is the name displayed in the Color/Orientation Dialog's list of colormaps. 'func' is a function of one argument, the desired colormap size; it will be called whenever the new colormap's values are needed or the colormap size changes, so that the colormap needs to be recomputed. It should return a list of three vcts, each vct containing 'size' values representing respectively the red, green, and blue values (each a number between 0.0 and 1.0). In the following code, the fields are set from envelopes (this is a loose translation of FractInt's royal colormap):

(add-colormap "purple" 
  (lambda (size) 
    (let ((r (make-float-vector size 0.0))
	  (g (make-float-vector size 0.0))
	  (b (make-float-vector size 0.0))
	  (incr (/ 256.0 size))
	  (er (list 0 60 60 116 128 252 192 252 256 60))
	  (eg (list 0 0  64 0   128 252 192 252 256 0))
	  (eb (list 0 80        128 252 192 0   256 80)))
      (do ((i 0 (+ i 1))
	   (x 0.0 (+ x incr)))
	  ((= i size))
        (set! (r i) (/ (envelope-interp x er) 256.0)) ; from env.scm
        (set! (g i) (/ (envelope-interp x eg) 256.0))
        (set! (b i) (/ (envelope-interp x eb) 256.0)))
      (list r g b))))

;;; another amusing colormap from FractInt:
(add-colormap "cos" 
  (lambda (size) 
    (let ((r (make-float-vector size 0.0))
	  (g (make-float-vector size 0.0))
	  (b (make-float-vector size 0.0))
	  (incr (/ 3.14159 size)))
      (do ((i 0 (+ i 1))
	   (x 0.0 (+ x incr)))
	  ((= i size))
	(set! (r i) (abs (sin (* 1.5 x))))
	(set! (g i) (abs (sin (* 3.5 x))))
	(set! (b i) (abs (sin (* 2.5 x)))))
      (list r g b))))
colormaps colormaps colormaps
background-gradient

In Gtk versions of Snd, this is the amount of background color gradient in the channel graphs (0.0, the default, means no gradient).

graph with background gradient
color? obj

This returns #t if 'obj' is a color (a Pixel in xm jargon); see make-color.

color->list obj

This returns the rgb color components of 'obj' in a list.

  > (color->list (make-color 1 0 0))
  (1.0 0.0 0.0)
color-cutoff

In spectra, this sets the lowest data value that will be colored (the default is 0.003). Anything less than that is rendered in the background color. This is the "data cutoff" slider in the View:Color/Orientation dialog.

color-inverted

This reflects the 'invert' button in the View:Color/Orientation dialog. If the colormap is inverted, the order of colors is reversed.

color-scale

color-scale reflects the darkness setting in the View:Color/Orientation dialog. The mapping between the slider in the dialog and the color-scale value is not linear, and is currently different in Gtk and Motif.

colormap

This is the colormap choice for various displays, most prominently the transform sonogram and spectrogram, and the wavogram. The built-in maps are: black-and-white-colormap, gray-colormap, hot-colormap, cool-colormap, bone-colormap, copper-colormap, pink-colormap, jet-colormap, prism-colormap, autumn-colormap, winter-colormap, spring-colormap, summer-colormap, rainbow-colormap, flag-colormap, and phases-colormap.

colormap-name index

colormap-name returns the specified colormap's name.

> (colormap-name (colormap))
"hot"
colormap-ref map pos

colormap-ref returns the rgb values of the colormap 'map' at position 'pos', suitable for use with make-color. 'pos' should be a float between 0.0 and 1.0. See the example above, or samples-via-colormap in draw.scm.

colormap-size

colormap-size returns (or sets) the current number of colors in each colormap. The default is 512.

colormap->integer colormap-object

This function returns the integer corresponding to a given colormap.

colormap? object

colormap? returns #t if 'object' is a usable colormap.

copy-context

This is the graphics mode (an integer in Snd, not a function) to use to draw over whatever is currently in a graph. The "contexts" refer to graphics contexts used throughout Snd; the copy-context copies into the current graph, whereas the cursor-context uses XOR. The error thrown for an unimplemented context is 'no-such-graphics-context.

current-font snd chn context

This is the current font (a Font in Motif, a PangoFontDescription* in Gtk+).

cursor-context

This is the graphics mode (an integer in Snd, not a function) for XOR drawing in the cursor color (for cursors, normally). See x-cursor or foreground-color.

delete-colormap object

delete-colormap deletes the memory associated with the given colormap.

draw-axes wid gc label x0 x1 y0 y1 style axes cr

This draws axes in the widget 'wid', using the graphics context 'gc', with the x-axis label 'label' going from 'x0' to 'x1' (floats) along the x axis, 'y0' to 'y1' along the y axis, with x-axis-style 'style' (x-axis-in-seconds etc). Whether axes are actually displayed or just implied depends on 'axes', which defaults to show-all-axes. In Gtk, the cairo_t 'cr' argument is not optional; it is ignored in Motif. draw-axes returns a list of the actual (pixel) axis bounds. See the scanned-synthesis display code in snd-motif.scm, or the local envelope editor code in xm-enved.scm.

draw-dot x0 y0 dot-size snd chn context cr

This draws a dot at ('x0 y0') of diameter 'dot-size' pixels in the specified context. See musglyphs.scm.

draw-dots positions dot-size snd chn context cr

This draws dots of size 'dot-size' from the (x y) pairs in the vector 'positions' in the specified context. draw-dots, draw-lines, and fill-polygon take vectors, rather than vcts (which would be more consistent with the rest of Snd) because the values passed are supposed to be short ints.

draw-line x0 y0 x1 y1 snd chn context cr

This draws a line from ('x0 y0') to ('x1 y1') in the specified context.

draw-lines lines snd chn context cr

This draws lines following the (x y) pairs in the vector 'lines' in the specified context. make-bezier-1 in musglyphs.scm can be used to draw Bezier curves.

draw-string text x0 y0 snd chn context cr

This draws a string ('text') in the current font and foreground color starting at ('x0 y0') in the specified context. The next procedures use the channel-property list to maintain a list of sample-oriented comments, displaying a given comment if its associated sample is currently in the time-domain graph:

(define* (add-comment sample comment snd1 chn1)
  (let* ((snd (or snd1 (selected-sound)))
	 (chn (or chn1 (selected-channel)))
	 (old-comments (or (channel-property 'comments snd chn) ())))
    (set! (channel-property 'comments snd chn)
	  (cons (list sample comment)
		old-comments))))
	  
(define (show-comments snd chn)
  (let ((comments (or (channel-property 'comments snd chn) ())))
    (for-each
     (lambda (comment)
       (let* ((samp (car comment))
	      (text (cadr comment))
	      (text-width (* 6 (string-length text)))
	      (ls (left-sample snd chn))
	      (rs (right-sample snd chn)))
	 (if (and (< ls samp)
		  (> rs samp))
	     (let ((xpos (x->position (/ samp (srate))))
		   (ypos (y->position (sample samp)))
                   (cr (make-cairo (car (channel-widgets snd chn)))))
	       (draw-line xpos 20 xpos (- ypos 4) snd chn time-graph cr)
	       (draw-string text (- xpos (/ text-width 2)) 18 snd chn time-graph cr)
               (free-cairo cr)))))
     comments)))

(hook-push after-graph-hook
  (lambda (hook) 
    (show-comments (hook 'snd) (hook 'chn))))
fill-rectangle x0 y0 width height snd chn context erase cr

This draws a filled rectangle in the current foreground color from ('x0 y0') of size ('width height'). If 'erase' is #t, this function erases the rectangular area. See draw.scm and snd-motif.scm.

fill-polygon points snd chn context cr

This draws a filled polygon whose vertices are in the vector 'points'.

(define (-> x0 y0 size snd chn cr)
  ;; draw an arrow pointing (from the left) at the point (x0 y0)
  (let ((points (make-vector 8)))
    (define (point i x y)
      (set! (points (* i 2)) x)
      (set! (points (+ (* i 2) 1)) y))
    (define (arrow-head x y)
      (point 0 x y)
      (point 1 (- x (* 2 size)) (- y size))
      (point 2 (- x (* 2 size)) (+ y size))
      (point 3 x y)
      (fill-polygon points snd chn time-graph cr))
    (arrow-head x0 y0)
    (fill-rectangle (- x0 (* 4 size)) 
		    (floor (- y0 (* .4 size)))
		    (* 2 size)
		    (floor (* .8 size))
                    snd chn time-graph #f cr)))	

musglyphs.scm has some elaborate examples that use fill-polygon to draw music notation symbols.

foreground-color snd chn context

This is the current foreground color. The following gives us a green cursor:

  (set! (foreground-color 0 0 cursor-context) (make-color 1 0 1))
glSpectrogram data gl-list cutoff use-dB min-dB scale br bg bb

glSpectrogram takes spectrogram data and passes it to openGL.

graph-data data snd chn context low high graphics-style cr

graph-data displays 'data' in the time domain graph of the sound's channel 'chn' using the graphics context 'context' (normally copy-context), placing the data in the recipient's graph between points 'low' and 'high' in the drawing mode 'graphics-style'. With this function and make-graph-data, we can overlay sounds, overlay different versions of the same sound, place a portion of a sound over another at an arbitrary point, and so on (see draw.scm).

red samples
integer->colormap i

This function returns the colormap corresponding to a given integer.

make-color red green blue (alpha 1.0)

make-color returns a color object using the rgb values 'red', 'green', and 'blue'. Each argument is a float between 0.0 (none of that color) and 1.0 (full value for that color). So,

(make-color 1 0 0)

returns a red color object. Two colors are equal (i.e. equal? returns #t) if their rgb values are the same. The 'alpha' argument only matters in Gtk.

make-graph-data snd chn edit-position low-sample high-sample

Use make-graph-data to get the currently displayed data (i.e. the waveform displayed in the graph, which can be based on an overall peak envelope rather than the individual samples). It returns either a vct (if the graph has one trace), or a list of two vcts (the two sides of the peak envelope graph). 'edit-position' defaults to the current edit history position, 'low-sample' defaults to the current window left sample, and 'high-sample' defaults to the current rightmost sample. The result can be used in the lisp graph:

(define display-db
  (lambda (snd chn)
    (let ((datal (make-graph-data snd chn)))
      (if datal
          (let* ((data (if (float-vector? datal) datal (cadr datal)))
                 (len (length data))
                 (sr (srate snd)))
            (define (dB val)
	      (if (< val .001)
	          -60.0
	          (* 20.0 (log10 val))))
            (do ((i 0 (+ i 1)))
	        ((= i len))
	      (set! (data i) (+ 60.0 (dB (abs (data i))))))
              (graph data "dB" 
	            (/ (left-sample snd chn) sr) (/ (right-sample snd chn) sr)  
	            0.0 60.0
	            snd chn))))))

(hook-push lisp-graph-hook 
  (lambda (hook)
    (display-db (hook 'snd) (hook 'chn))))

Here we are taking whatever is displayed in the time domain, and presenting the same thing in dB in the lisp graph. display-energy in draw.scm is another example. But the real power of this function comes from its use with graph-data. The latter takes its argument (either a vct or a list of two vcts), and displays it in any channel's time domain graph using its current graph-style.

mark-context

This is the graphics context used to draw a mark (XOR mode). (It is an integer, not a function).

selection-context

This is the graphics context for XOR drawing in the selection color. (An integer, not a function).

snd-color choice

snd-color returns a Snd built-in color (as a Pixel/GdkPixel); it simplifies code that wants to follow whatever the current Snd color choices are. The choices are:

0: white                   12: listener-color                 
1: black                   13: listener-text-color            25: sash-color
2: red                     14: basic-color                    
3: yellow                  15: selection-color                
4: green                   16: zoom-color                     
5: light-blue              17: position-color                 
6: lighter-blue            18: highlight-color                
7: data-color              19: enved-waveform-color           31: grid-color
8: selected-data-color     20: cursor-color                   32: selected-grid-color
9: mark-color              21: text-focus-color               33: axis-color
10: graph-color            22: filter-control-waveform-color
11: selected-graph-color   23: mix-color
snd-font choice

snd-font returns a Snd built-in font (as a raw pointer, suitable for current-font but not much else); it simplifies code that wants to follow whatever the current Snd font choices are, but is really aimed at code that wants to use just built-in functions like current-font, and not rely on the xm or xg modules. The choices are:

0: peaks-font
1: bold-peaks-font
2: tiny-font
3: axis-label-font
4: axis-numbers-font
5: listener-font

See display-bark-fft in dsp.scm for an example.

snd-gcs

snd-gcs returns a list of Snd's graphics contexts:

0: bg=graph-color, fg=data-color
1: bg=selected-graph-color, fg=selected-data-color
2: bg=graph-color, fg=data-color, fg changes for superimposed graphs

3: bg=graph-color, fg=cursor-color, XOR (for cursor)
4: bg=selected-graph-color, fg=cursor-color, XOR (for cursor in selection)

5: bg=graph-color, fg=selection-color, XOR (for selection highlighting)
6: bg=selected-graph-color, fg=selection-color, XOR (selection highlighting)

7: bg=data-color, fg=graph-color (to erase data)
8: bg=selected-data-color, fg=selected-graph-color (erase data in selected channel)

9: bg=graph-color, fg=mark-color, XOR (for marks)
0: bg=selected-graph-color, fg=mark-color, XOR (marks in selected channel)

1: bg=graph-color, fg=mix-color
2: bg=selected-graph-color, fg=mix-color

3: bg=basic-color, fg=black
4: bg=basic-color, fg=filter-waveform-color

These graphics-contexts make it easier to fit in with whatever color scheme is currently in use. For example, in to make sure the font color reflects whether we're in the selected channel:

  (XSetFont dpy
    (if (= chn (selected-channel snd))
        (cadr (snd-gcs))
        (car (snd-gcs)))
    (.fid fs))
with-gl

If with-gl is #t and GL is loaded, use GL where possible (the default is #t if HAVE_GL). You can find out at run-time whether GL is loaded via (provided? 'gl).

snd-16.1/sndlib.html0000644000076400007640000010612112574565143012511 0ustar bilbil The Sound Library
SndLib
Bill Schottstaedt (bil@ccrma.stanford.edu)
Contents
Introduction

sndlib is a collection of sound file and sound synthesis function written in C and running currently in various Unices via OSS or ALSA, Mac OSX, and on old Windows systems. To build sndlib (sndlib.so if possible, and sndlib.a):

  ./configure
  make

To install it, 'make install' — I've tested this process in Linux.

The following files make up sndlib:

  • io.c (read and write sound file data)
  • headers.c (read and write sound file headers)
  • audio.c (read and write sound hardware ports)
  • sound.c (provide slightly higher level access to the preceding files)
  • sndlib.h (header for the preceding files)
  • sndlib2xen.c and sndlib-strings.h (tie preceding into s7, Ruby, or Forth)
  • clm.c and clm.h (Music V implementation)
  • clm2xen.c, vct.c and vct.h (tie clm.c into s7, Ruby, or Forth)
  • xen.h, xen.c (the embedded language support)

The naming scheme is more as less as follows: the sndlib prefix is "mus" so function names start with "mus_" and constants start with "MUS_". Functions involving sound files referenced through the file name start with "mus_sound_", functions involving files at a lower level with "mus_file_", functions involving header access with "mus_header_", functions involving audio hardware access with "mus_audio_", and various others just with "mus_" (number translations, etc). Conversions use the word "to" as in "mus_samples_to_bytes".

Headers

Sound files have built-in descriptors known as headers. The following functions return the information in the header. In each case the argument to the function is the full file name of the sound file.

  mus_long_t mus_sound_samples (const char *arg)        /* samples of sound according to header */
  mus_long_t mus_sound_framples (const char *arg)         /* samples per channel */
  float mus_sound_duration (const char *arg)       /* sound duration in seconds */
  mus_long_t mus_sound_length (const char *arg)         /* true file length in bytes */

  int mus_sound_datum_size (const char *arg)       /* bytes per sample */
  mus_long_t mus_sound_data_location (const char *arg)  /* location of first sample (bytes) */
  int mus_sound_bits_per_sample(const char *arg)   /* bits per sample */
  int mus_bytes_per_sample(int format)             /* bytes per sample */

  int mus_sound_chans (const char *arg)            /* number of channels (samples are interleaved) */
  int mus_sound_srate (const char *arg)            /* sampling rate */

  mus_header_t mus_sound_header_type (const char *arg)      /* header type (aiff etc) */
  mus_sample_t mus_sound_sample_type (const char *arg)      /* sample type (alaw etc) */
  int mus_sound_original_format (const char *arg)  /* unmodified sample type specifier */
  int mus_sound_type_specifier (const char *arg)   /* original header type identifier */

  char *mus_sound_comment (const char *arg)        /* comment if any */
  mus_long_t mus_sound_comment_start (const char *arg)  /* comment start (bytes) if any */
  mus_long_t mus_sound_comment_end (const char *arg)    /* comment end (bytes) */
  int *mus_sound_loop_info(const char *arg)        /* 8 loop vals (mode,start,end) then base-detune and base-note  (empty list if no loop info found) */

  int mus_sound_write_date (const char *arg)       /* bare (uninterpreted) file write date */
  int mus_sound_initialize(void)                   /* initialize everything */

The following can be used to provide user-understandable descriptions of the header type and the sample type:

  char *mus_header_type_name(mus_header_t type)             /* "AIFF" etc */
  char *mus_sample_type_name(mus_sample_t samp_type)        /* "16-bit big endian linear" etc */
  char *mus_header_type_to_string(mus_header_t type)
  char *mus_sample_type_to_string(mus_sample_t samp_type)
  const char *mus_sample_type_short_name(mus_sample_t samp_type)

In all cases if an error occurs, -1 (MUS_ERROR) is returned, and some sort of error message is printed; to customize error handling, use mus_set_error_handler and mus_set_print_handler.

  mus_error_handler_t *mus_error_set_handler(mus_error_handler_t *new_error_handler);
  mus_print_handler_t *mus_print_set_handler(mus_print_handler_t *new_print_handler);

To decode the error indication, use:

  char *mus_error_to_string(int err);

Header data is cached internally, so the actual header is read only if it hasn't already been read, or the write date has changed. Loop points are also available, if there's interest. To go below the "sound" level, see headers.c — once a header has been read, all the components that have been found can be read via functions such as mus_header_srate.

Data

The following functions provide access to sound file data:

  int mus_sound_open_input (const char *arg) 
  int mus_sound_open_output (const char *arg, int srate, int chans, mus_sample_t sample_type, mus_header_t header_type, const char *comment)
  int mus_sound_reopen_output (const char *arg, mus_header_t type, mus_sample_t format, mus_long_t data_loc)
  int mus_sound_close_input (int fd) 
  int mus_sound_close_output (int fd, mus_long_t bytes_of_data) 
  int mus_sound_read (int fd, int beg, int end, int chans, mus_float_t **bufs) 
  int mus_sound_write (int fd, int beg, int end, int chans, mus_float_t **bufs) 
  mus_long_t mus_sound_seek_frample (int fd, mus_long_t frample)

mus_float_t defaults to double. It is set when sndlib is built, and refers to Sndlib's internal representation of sample values.

mus_sound_open_input opens arg for reading. Most standard uncompressed formats are readable. This function returns the associated file number, or -1 upon failure.

mus_sound_close_input closes an open sound file. Its argument is the integer returned by mus_sound_open_input.

mus_sound_open_output opens (creates) the file arg, setting its sampling rate to be srate, number of channels to chans, sample type to sample_type (see sndlib.h for these types: MUS_BSHORT, means 16-bit 2's complement big endian fractions), header type to header_type (AIFF for example; the available writable header types are MUS_AIFC (or AIFF), MUS_RIFF ('wave'), MUS_RF64, MUS_NEXT, MUS_NIST, MUS_CAFF, and MUS_IRCAM), and comment (if any) to comment. The header is not considered complete without an indication of the data size, but since this is rarely known in advance, it is supplied when the sound file is closed. mus_sound_open_output function returns the associated file number.

mus_sound_close_output first updates the file's header to reflect the final data size bytes_of_data, then closes the file. The argument fd is the integer returned by mus_sound_open_output.

mus_sound_read reads data from the file indicated by fd, placing data in the array obufs as mus_float_t values (floats normally). chans determines how many arrays of samples are in obufs, which is filled by mus_sound_read from its index beg to end with zero padding if necessary.

mus_sound_write writes samples to the file indicated by fd, starting for each of chans channels in obufs at beg and ending at end.

mus_sound_seek_frample moves the read or write position for the file indicated by fd to the desired frample.

Hardware

The following functions provide access to audio harware. If an error occurs, they return -1 (MUS_ERROR).

  int mus_audio_initialize(void)
  int mus_audio_open_output(int dev, int srate, int chans, mus_sample_t format, int size)
  int mus_audio_open_input(int dev, int srate, int chans, mus_sample_t format, int size)
  int mus_audio_write(int line, char *buf, int bytes)
  int mus_audio_close(int line)
  int mus_audio_read(int line, char *buf, int bytes)

mus_audio_initialize takes care of any necessary initialization.

mus_audio_open_input opens an audio port to read sound data (i.e. a microphone, line in, etc). The input device is dev (see sndlib.h for details; when in doubt, use MUS_AUDIO_DEFAULT). The input sampling rate is srate or as close as we can get to it. The number of input channels (if available) is chans. The input sample type is format (when in doubt, use the macro MUS_AUDIO_COMPATIBLE_FORMAT). And the input buffer size (if settable at all) is size (bytes). This function returns an integer to distinguish its port from others that might be in use.

mus_audio_open_output opens an audio port to write data (i.e. speakers, line out, etc). The output device is dev (see sndlib.h). Its sampling rate is srate, number of channels chans, sample type format, and buffer size size. This function returns the associated line number of the output port.

mus_audio_close closes the port (input or output) associated with line.

mus_audio_read reads sound data from line. The incoming 'bytes' bytes of data are placed in buf. If no error was returned from mus_audio_open_input, the data is in the format requested by that function with channels interleaved.

mus_audio_write writes 'bytes' bytes of data in buf to the output port associated with line. This data is assumed to be in the format requested by mus_audio_open_output with channels interleaved.

Music V

clm.c and friends implement all the generators found in CLM, a music V implementation, and clm2xen.c ties these into the languages supported by the xen package (currently s7, Ruby, and Forth). The primary clm documentation (which describes both the Scheme and Common Lisp implementations) is clm.html found in clm-5.tar.gz or sndclm.html in snd-16.tar.gz alongside sndlib at ccrma-ftp. The simplest way to try these out is to load them into Snd; see extsnd.html, examp.scm, and snd-test.scm in snd-16.tar.gz for more details. The following briefly describes the C calls (see clm.h).

clm.c implements a bunch of generators and sound IO handlers. Each generator has three associated functions, make-gen, gen, and gen_p; the first creates the generator (if needed), the second gets the next sample from the generator, and the last examines some pointer to determine if it is that kind of generator. In addition, there are a variety of generic functions that generators respond to: mus_free, for example, frees a generator, and mus_frequency returns its current frequency, if relevant. All generators are pointers to mus_any structs.

  • oscil — generate a sine wave.
    • mus_any *mus_make_oscil (float freq, float phase)
    • float mus_oscil (mus_any *o, float fm, float pm)
    • int mus_oscil_p (mus_any *ptr)
      mus_any *osc;
      osc = mus_make_oscil(440.0, 0.0);
      if (mus_oscil_p(osc)) 
        fprintf(stderr, "%.3f, %.3f ", .1 * mus_oscil(osc, 0.0, 0.0), mus_frequency(osc));
      mus_free(osc);
    

The other generators are:

  • sum_of_cosines: generate a pulse train made up of cosines
  • sum_of_sines: generate a sum of sines
  • delay: a delay line with optional interpolation
  • tap: read delay line
  • comb: comb filter
  • notch: notch filter
  • all_pass: all pass filter
  • table_lookup: interpolating table lookup
  • sawtooth_wave, triangle_wave, pulse_train, square_wave
  • rand: white noise (a step function)
  • rand-interp: interpolating noise
  • asymmetric_fm: a variety of FM
  • one_zero, two_zero, one_pole, two_pole: basic filters
  • formant: create a formant region (two poles, two zeros)
  • sine_summation: another way to create sine waves
  • filter, fir_filter, iir_filter: direct form filters of any order
  • wave_train: sequence of possibly overlapping waves
  • env: envelopes
  • polyshape, polywave: waveshaping
  • readin, file_to_sample, file_to_frample, in_any: file sample input
  • locsig, sample_to_file, frample_to_file, out_any: file sample output
  • src: sampling rate conversion
  • granulate: granular synthesis
  • convolve: convolution
  • phase-vocoder: phase vocoder
  • moving-average: moving window average
  • ssb-am: single side-bank amplitude modulation

Some useful functions provided by clm.c are:

  • float mus_radians_to_hz(float rads): convert radians/sample to cycles/sec.
  • float mus_hz_to_radians(float hz): and the reverse.
  • float mus_degrees_to_radians(float deg): convert degrees to radians.
  • float mus_radians_to_degrees(float rads): and the reverse.
  • float mus_srate(void): current sampling rate
  • float mus_set_srate(float rate): set current sampling rate
  • float mus_ring_modulate(float sig1, float sig2): multiply sig1 by sig2
  • float mus_amplitude_modulate(float s1, float s2, float s3): AM
  • float mus_contrast_enhancement(float sig, float index)
  • float mus_dot_product(float *data1, float *data2, int size)
  • void mus_clear_array(float *arr, int size)
  • float mus_array_interp(float *wave, float phase, int size)
  • float mus_polynomial(float *coeffs, float x, int ncoeffs);
  • void mus_multiply_arrays(float *data, float *window, int len);
  • void mus_rectangular_to_polar(float *rl, float *im, int size);
  • void mus_spectrum(float *rdat, float *idat, float *window, int n, int type)
  • void mus_fft(float *rl, float *im, int n, int isign)
  • float *mus_make_fft_window(int size, int type, float beta)
  • void mus_convolution(float* rl1, float* rl2, int n, int ipow)
  • float *mus_partials_to_wave(float *partial_data, int partials, float *table, int table_size, int normalize)
  • float *mus_phase_partials_to_wave(float *partial_data, int partials, float *table, int table_size, int normalize)
  • float mus_samples_to_seconds(mus_long_t samps)
  • mus_long_t mus_seconds_to_samples(float secs)

and various others: see clm.h.

The more useful generic functions are:

  • int mus_free(mus_any *ptr)
  • char *mus_describe(mus_any *gen)
  • float mus_phase(mus_any *gen)
  • float mus_set_phase(mus_any *gen, float val)
  • float mus_set_frequency(mus_any *gen, float val)
  • float mus_frequency(mus_any *gen)
  • float mus_run(mus_any *gen, float arg1, float arg2)
  • int mus_length(mus_any *gen)
  • int mus_set_length(mus_any *gen, int len)
  • float *mus_data(mus_any *gen)
  • float *mus_set_data(mus_any *gen, float *data)
  • char *mus_name(mus_any *ptr)
  • float mus_scaler(mus_any *gen)
  • float mus_set_scaler(mus_any *gen, float val)
  • float mus_apply(mus_any *gen, ...)

Errors are reported through mus_error which can be redirected or muffled. See clm2xen.c for an example.

Examples
sndinfo

This program prints out a description of a sound file (sndinfo.c).

int main(int argc, char *argv[])
{
  int fd, chans, srate;
  mus_long_t samples;
  float length;
  time_t date;
  char *comment;
  char timestr[64];
  mus_sound_initialize();	    /* initialize sndlib */
  fd = mus_file_open_read(argv[1]); /* see if it exists */
  if (fd != -1)
    {
      close(fd);
      date = mus_sound_write_date(argv[1]);
      srate = mus_sound_srate(argv[1]);
      chans = mus_sound_chans(argv[1]);
      samples = mus_sound_samples(argv[1]);
      comment = mus_sound_comment(argv[1]); 
      length = (double)samples / (float)(chans * srate);
      strftime(timestr, 64, "%a %d-%b-%y %H:%M %Z", localtime(&date));
      fprintf(stdout, "%s:\n  srate: %d\n  chans: %d\n  length: %f\n", 
	      argv[1], srate, chans, length);
      fprintf(stdout, "  header: %s\n  sample type: %s\n  written: %s\n  comment: %s\n", 
	      mus_header_type_name(mus_sound_header_type(argv[1])), 
	      mus_sample_type_name(mus_sound_sample_type(argv[1])), 
	      timestr, comment);
    }
  else
    fprintf(stderr, "%s: %s\n", argv[1], strerror(errno));
  return(0);
}
sndplay

This code plays a sound file (sndplay.c):


int main(int argc, char *argv[])
{
  int fd, afd, i, j, n, k, chans, srate, outbytes;
  mus_long_t framples;
  mus_float_t **bufs;
  short *obuf;
  mus_sound_initialize();	
  fd = mus_sound_open_input(argv[1]);
  if (fd != -1)
    {
      chans = mus_sound_chans(argv[1]);
      srate = mus_sound_srate(argv[1]);
      framples = mus_sound_framples(argv[1]);
      outbytes = BUFFER_SIZE * chans * 2;
      bufs = (mus_float_t **)calloc(chans, sizeof(mus_float_t *));
      for (i=0;i<chans;i++) 
        bufs[i] = (mus_float_t *)calloc(BUFFER_SIZE, sizeof(mus_float_t));
      obuf = (short *)calloc(BUFFER_SIZE * chans, sizeof(short));
      afd = mus_audio_open_output(MUS_AUDIO_DEFAULT, srate, chans, MUS_AUDIO_COMPATIBLE_FORMAT, outbytes);
      if (afd != -1)
	{
	  for (i = 0; i < framples; i += BUFFER_SIZE)
	    {
	      mus_sound_read(fd, 0, BUFFER_SIZE - 1, chans, bufs);
	      for (k = 0, j = 0; k < BUFFER_SIZE; k++, j += chans)
		for (n = 0; n < chans; n++) 
                  obuf[j + n] = MUS_SAMPLE_TO_SHORT(bufs[n][k]);
	      mus_audio_write(afd, (char *)obuf, outbytes);
	    }
	  mus_audio_close(afd);
	}
      mus_sound_close_input(fd);
      for (i = 0; i < chans; i++) free(bufs[i]);
      free(bufs);
      free(obuf);
    }
  return(0);
}

sndsine

This program writes a one channel NeXT/Sun sound file containing a sine wave at 440 Hz.

int main(int argc, char *argv[])
{
  int fd, i, k, framples;
  float phase, incr;
  mus_float_t *obuf[1];
  mus_sound_initialize();	
  fd = mus_sound_open_output(argv[1], 22050, 1, MUS_BSHORT, MUS_NEXT, "created by sndsine");
  if (fd != -1)
    {
      framples = 22050;
      phase = 0.0;
      incr = 2 * M_PI * 440.0 / 22050.0;
      obuf[0] = (mus_float_t *)calloc(BUFFER_SIZE, sizeof(mus_float_t));
      k = 0;
      for (i = 0; i < framples; i++)
	{
	  obuf[0][k] = MUS_FLOAT_TO_SAMPLE(0.1 * sin(phase)); /* amp = .1 */
	  phase += incr;
	  k++;
	  if (k == BUFFER_SIZE)
	    {
	      mus_sound_write(fd, 0, BUFFER_SIZE-1, 1, obuf);
	      k=0;
	    }
	}
      if (k > 0) mus_sound_write(fd, 0, k - 1, 1, obuf);
      mus_sound_close_output(fd, 22050 * mus_bytes_per_sample(MUS_BSHORT));
      free(obuf[0]);
    }
  return(0);
}
clmosc

This is program uses the clm.c oscillator and output functions to write the same sine wave as we wrote in SndSine.

int main(int argc, char *argv[])
{
  int i;
  mus_any *osc, *op;
  mus_sound_initialize();	
  osc = mus_make_oscil(440.0, 0.0);
  op = mus_make_sample_to_file("test.snd", 1, MUS_BSHORT, MUS_NEXT);
  if (op) 
    for (i = 0; i < 22050; i++) 
      mus_sample_to_file(op, i, 0, .1 * mus_oscil(osc, 0.0, 0.0));
  mus_free(osc);
  if (op) mus_free(op);
  return(0);
}

Here is the fm-violin and a sample with-sound call:

static int feq(float x, int i) {return(fabs(x-i)<.00001);}

void fm_violin(float start, float dur, float frequency, float amplitude, float fm_index, mus_any *op)
{
 float pervibfrq = 5.0,
   ranvibfrq = 16.0,
   pervibamp = .0025,
   ranvibamp = .005,
   noise_amount = 0.0,
   noise_frq = 1000.0,
   gliss_amp = 0.0,
   fm1_rat = 1.0,
   fm2_rat = 3.0,
   fm3_rat = 4.0,
   reverb_amount = 0.0,
   degree = 0.0, 
   distance = 1.0;
  float fm_env[] = {0.0, 1.0, 25.0, 0.4, 75.0, 0.6, 100.0, 0.0};
  float amp_env[] = {0.0, 0.0,  25.0, 1.0, 75.0, 1.0, 100.0, 0.0};
  float frq_env[] = {0.0, -1.0, 15.0, 1.0, 25.0, 0.0, 100.0, 0.0};
  int beg = 0, end, easy_case = 0, npartials, i;
  float *coeffs, *partials;
  float frq_scl, maxdev, logfrq, sqrtfrq, index1, index2, index3, norm;
  float vib = 0.0, modulation = 0.0, fuzz = 0.0, indfuzz = 1.0;
  mus_any *carrier, *fmosc1, *fmosc2, *fmosc3, *ampf;
  mus_any *indf1, *indf2, *indf3, *fmnoi = NULL, *pervib, *ranvib, *frqf = NULL, *loc;
  beg = start * mus_srate();
  end = beg + dur * mus_srate();
  frq_scl = mus_hz_to_radians(frequency);
  maxdev = frq_scl * fm_index;
  if ((noise_amount == 0.0) && 
      (feq(fm1_rat, floor(fm1_rat))) && 
      (feq(fm2_rat, floor(fm2_rat))) && 
      (feq(fm3_rat, floor(fm3_rat)))) 
    easy_case = 1;
  logfrq = log(frequency);
  sqrtfrq = sqrt(frequency);
  index1 = maxdev * 5.0 / logfrq; 
  if (index1 > M_PI) index1 = M_PI;
  index2 = maxdev * 3.0 * (8.5 - logfrq) / (3.0 + frequency * .001); 
  if (index2 > M_PI) index2 = M_PI;
  index3 = maxdev * 4.0 / sqrtfrq; 
  if (index3 > M_PI) index3 = M_PI;
  if (easy_case)
    {
      npartials = floor(fm1_rat);
      if ((floor(fm2_rat)) > npartials) npartials = floor(fm2_rat);
      if ((floor(fm3_rat)) > npartials) npartials = floor(fm3_rat);
      npartials++;
      partials = (float *)calloc(npartials, sizeof(float));
      partials[(int)(fm1_rat)] = index1;
      partials[(int)(fm2_rat)] = index2;
      partials[(int)(fm3_rat)] = index3;
      coeffs = mus_partials_to_polynomial(npartials, partials, 1);
      norm = 1.0;
    }
  else norm = index1;
  carrier = mus_make_oscil(frequency, 0.0);
  if (easy_case == 0)
    {
      fmosc1 = mus_make_oscil(frequency * fm1_rat, 0.0);
      fmosc2 = mus_make_oscil(frequency * fm2_rat, 0.0);
      fmosc3 = mus_make_oscil(frequency * fm3_rat, 0.0);
    }
  else fmosc1 = mus_make_oscil(frequency, 0.0);
  ampf = mus_make_env(amp_env, 4, amplitude, 0.0, 1.0, dur, 0, NULL);
  indf1 = mus_make_env(fm_env, 4, norm, 0.0, 1.0, dur, 0, NULL);
  if (gliss_amp != 0.0) 
    frqf = mus_make_env(frq_env, 4, gliss_amp * frq_scl, 0.0, 1.0, dur, 0, NULL);
  if (easy_case == 0)
    {
      indf2 = mus_make_env(fm_env, 4, index2, 0.0, 1.0, dur, 0, NULL);
      indf3 = mus_make_env(fm_env, 4, index3, 0.0, 1.0, dur, 0, NULL);
    }
  pervib = mus_make_triangle_wave(pervibfrq, frq_scl * pervibamp, 0.0);
  ranvib = mus_make_rand_interp(ranvibfrq, frq_scl * ranvibamp);
  if (noise_amount != 0.0) fmnoi = mus_make_rand(noise_frq, noise_amount * M_PI);
  loc = mus_make_locsig(degree, distance, reverb_amount, 1, (mus_any *)op, 0, NULL, MUS_INTERP_LINEAR);
  for (i = beg; i < end; i++)
    {
      if (noise_amount != 0.0) fuzz = mus_rand(fmnoi, 0.0);
      if (frqf) vib = mus_env(frqf); else vib = 0.0;
      vib += mus_triangle_wave(pervib, 0.0) + mus_rand_interp(ranvib, 0.0);
      if (easy_case)
	modulation = mus_env(indf1) * 
                     mus_polynomial(coeffs, mus_oscil(fmosc1, vib, 0.0), npartials);
      else
	modulation = mus_env(indf1) * mus_oscil(fmosc1, (fuzz + fm1_rat * vib), 0.0) + 
	             mus_env(indf2) * mus_oscil(fmosc2, (fuzz + fm2_rat * vib), 0.0) + 
	             mus_env(indf3) * mus_oscil(fmosc3, (fuzz + fm3_rat * vib), 0.0);
      mus_locsig(loc, i, mus_env(ampf) * mus_oscil(carrier, vib + indfuzz * modulation, 0.0));
    }
  mus_free(pervib);
  mus_free(ranvib);
  mus_free(carrier);
  mus_free(fmosc1);
  mus_free(ampf);
  mus_free(indf1);
  if (fmnoi) mus_free(fmnoi);
  if (frqf) mus_free(frqf);
  if (!(easy_case))
    {
      mus_free(indf2);
      mus_free(indf3);
      mus_free(fmosc2);
      mus_free(fmosc3);
    }
  else
    free(partials);
  mus_free(loc);
}

int main(int argc, char *argv[])
{
  mus_any *op = NULL;
  mus_sound_initialize();	
  op = mus_make_sample_to_file("test.snd", 1, MUS_BSHORT, MUS_NEXT);
  if (op)
    {
      fm_violin(0.0, 20.0, 440.0, .3, 1.0, op);
      mus_free(op);
    }
  return(0);
}

The CLM version is v.ins, the Scheme version can be found in v.scm, and the Ruby version is in v.rb. This code can be run:

cc v.c -o vc -O3 -lm io.o headers.o audio.o sound.o clm.o -DLINUX

For generators such as src that take a function for "as-needed" input, you can use something like:

static mus_float_t input_as_needed(void *arg, int dir) {/* get input here — arg is "sf" passed below */}

static SCM call_phase-vocoder(void)
{
  mus_any *pv;
  int sf; /* file channel or whatever */
  pv = mus_make_phase_vocoder(NULL, 512, 4, 128, 0.5, NULL, NULL, NULL, (void *)sf);
  mus_phase_vocoder(pv, &input_as_needed);
  /* etc */
}

Michael Scholz has written a package using these functions, and several CLM instruments: see the sndins directory, and in particular the README file, for details.

Other examples

The primary impetus for the sound library was the development of Snd and CLM, both of which are freely available.

Extension Languages

Much of sndlib is accessible at run time in any program that has one of the languages supported by the xen package (s7, Ruby, Forth); the modules sndlib2xen and clm2xen tie most of the library into that language making it possible to call the library functions from its interpreter. The documentation is scattered around, unfortunately: the clm side is in sndclm.html and extsnd.html with many examples in Snd's examp.scm. Most of these are obvious translations of the constants and functions described above into Scheme. To initialize sndlib, call Init_sndlib, or, at run time, use s7's loader and s7_init_sndlib:

(let ((sndlib (load "libsndlib.so" 
                (inlet (curlet)
                  (cons 'init_func 's7_init_sndlib)))))
  ....)

Init_sndlib ties most of the functions mentioned above into the extension language (s7, Forth, or Ruby).

  mus-next mus-aifc mus-rf64 mus-riff mus-nist mus-raw mus-ircam mus-aiff mus-bicsf mus-soundfont mus-voc mus-svx mus-caff

  mus-bshort mus-lshort mus-mulaw mus-alaw mus-byte mus-ubyte mus-bfloat
  mus-lfloat mus-bint mus-lint mus-b24int mus-l24int mus-bdouble mus-ldouble
  mus-ubshort mus-ulshort

  mus-sound-samples (filename)             samples of sound according to header (can be incorrect)
  mus-sound-framples (filename)              framples of sound according to header (can be incorrect)
  mus-sound-duration (filename)            duration of sound in seconds
  mus-sound-datum-size (filename)          bytes per sample
  mus-sound-data-location (filename)       location of first sample (bytes)
  mus-sound-chans (filename)               number of channels (samples are interleaved)
  mus-sound-srate (filename)               sampling rate
  mus-sound-header-type (filename)         header type (e.g. mus-aiff)
  mus-sound-sample-type (filename)         sample type (e.g. mus-bshort)
  mus-sound-length (filename)              true file length (bytes)
  mus-sound-type-specifier (filename)      original header type identifier
  mus-sound-maxamp(filename)               returns a list of max amps and locations thereof
  mus-sound-loop-info(filename)            returns list of 4 loop values (the actual mark positions here, not
                                           the so-called id's), then base-note and base-detune
  
  mus-header-type-name (type)              e.g. "AIFF"
  mus-sample-type-name (format)            e.g. "16-bit big endian linear"
  mus-sound-comment (filename)             header comment, if any
  mus-sound-write-date (filename)          sound write date
  sample-type-bytes-per-sample (format)    bytes per sample

  mus-sound-open-input (filename)          open filename (a sound file) returning an integer ("fd" below)
  mus-sound-open-output (filename srate chans sample-type header-type comment)
                                           create a new sound file with the indicated attributes, return "fd"
  mus-sound-reopen-output (filename chans sample-type header-type data-location)
                                           reopen (without disturbing) filename, ready to be written
  mus-sound-close-input (fd)               close sound file
  mus-sound-close-output (fd bytes)        close sound file and update its length indication, if any
  mus-sound-read (fd beg end chans sdata)  read data from sound file fd loading the data array from beg to end
                                           sdata is a float-vector that should be able to accommodate the read
  mus-sound-write (fd beg end chans sdata) write data to sound file fd
  mus-sound-seek-frample (fd frample)          move to frample in sound file fd
  mus-file-clipping (fd)                   whether output is clipped in file 'fd'
  mus-clipping ()                          global clipping choice

  mus-oss-set-buffers (num size)           in Linux (OSS) sets the number and size of the OSS "fragments"

;;; this function prints header information
(define info
  (lambda (file)
    (string-append
     file
     ": chans: " (number->string (mus-sound-chans file))
     ", srate: " (number->string (mus-sound-srate file))
     ", " (mus-header-type-name (mus-sound-header-type file))
     ", " (mus-sample-type-name (mus-sound-sample-type file))
     ", len: " (number->string
                (/ (mus-sound-samples file)
                   (* (mus-sound-chans file) (mus-sound-srate file)))))))
s7 repl and sndlib
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

#include "mus-config.h"
#include "s7.h"
#include "xen.h"
#include "clm.h"
#include "clm2xen.h"

static void mus_error_to_s7(int type, char *msg)
{
  s7_error(s7,                               /* s7 is declared in xen.h, defined in xen.c */
	   s7_make_symbol(s7, "mus-error"),
	   s7_cons(s7, s7_make_string(s7, msg), s7_nil(s7)));
}

int main(int argc, char **argv)
{
  s7 = s7_init();

  s7_xen_initialize(s7);
  Init_sndlib();
  mus_error_set_handler(mus_error_to_s7); /* catch low-level errors and pass them to s7-error */

  if (argc == 2)
    {
      fprintf(stderr, "load %s\n", argv[1]);
      s7_load(s7, argv[1]);
    }
  else 
    {
      s7_load(s7, "repl.scm");
      s7_eval_c_string(s7, "((*repl* 'run))");
    }

  return(0);
}

/* gcc -o sl sl.c /home/bil/test/sndlib/libsndlib.a -Wl,-export-dynamic -lasound -lm -I. -ldl -lgsl -lgslcblas -lfftw3
 *
 * (load "sndlib-ws.scm")
 * (load "v.scm")
 * (set! *clm-player* (lambda (file) (system (format #f "sndplay ~A" file))))
 * (with-sound (:play #t) (fm-violin 0 1 330 .1))
 */
snd-16.1/maraca.scm0000644000076400007640000001103412350136561012264 0ustar bilbil;;; Perry Cook's maraca from CMJ vol 21 no 3 (Fall 97) p 44 ;;; translated from CLM's maraca.ins (provide 'snd-maraca.scm) (if (provided? 'snd) (require snd-ws.scm) (require sndlib-ws.scm)) (define two-pi (* 2 pi)) (definstrument (maraca beg dur (amp .1) (sound-decay 0.95) (system-decay 0.999) (probability .0625) (shell-freq 3200.0) (shell-reso 0.96)) (let ((num-beans 64)) (let ((st (seconds->samples beg)) (nd (seconds->samples (+ beg dur))) (temp 0.0) (shake-energy 0.0) (snd-level 0.0) (input 0.0) (stop 0) (h20 (hz->radians 20.0)) (sndamp (/ amp 16384.0)) (srate4 (floor (/ *clm-srate* 4))) (gain (/ (* (log num-beans 4.0) 40) num-beans)) (tz (make-two-pole 1.0 (* -2.0 shell-reso (cos (hz->radians shell-freq))) (* shell-reso shell-reso))) (oz (make-one-zero 1.0 -1.0)) ;; gourd resonance filter ) (do ((i st (+ i srate4))) ((>= i nd)) (set! temp 0.0) (set! stop (min nd (+ i srate4))) (do ((k i (+ k 1))) ((= k stop)) (if (< temp two-pi) (begin ;; shake over 50msec and add shake energy (set! temp (+ temp h20)) (set! shake-energy (+ shake-energy (- 1.0 (cos temp)))))) (set! shake-energy (* shake-energy system-decay)) ;; if collision, add energy (if (< (random 1.0) probability) (set! snd-level (+ snd-level (* gain shake-energy)))) ;; actual sound is random (set! input (mus-random snd-level)) ;; compute exponential sound decay (set! snd-level (* snd-level sound-decay)) ;; gourd resonance filter calc (outa k (* sndamp (one-zero oz (two-pole tz input))))))))) ;;; maraca: (with-sound (:statistics #t :play #t) (maraca 0 5 .5)) ;;; cabasa: (with-sound (:statistics #t :play #t) (maraca 0 5 .5 0.95 0.997 0.5 3000.0 0.7)) (definstrument (big-maraca beg dur (amp .1) (sound-decay 0.95) (system-decay 0.999) (probability .0625) (shell-freqs '(3200.0)) (shell-resos '(0.96)) (randiff .01) (with-filters #t)) ;; like maraca, but takes a list of resonances and includes low-pass filter (or no filter) (let ((num-beans 64) (resn (length shell-freqs))) (let ((st (seconds->samples beg)) (nd (seconds->samples (+ beg dur))) (temp 0.0) (shake-energy 0.0) (snd-level 0.0) (input 0.0) (sum 0.0) (last-sum 0.0) (tzs (make-vector resn)) (h20 (hz->radians 20.0)) (stop 0) (sndamp (/ amp (* 16384.0 resn))) (srate4 (floor (/ *clm-srate* 4))) (gain (/ (* (log num-beans 4) 40) num-beans)) (oz (make-one-zero (/ amp (* resn 16384.0)) (/ amp (* resn 16384.0))))) ;; we need to fixup Perry's frequency dithering amount since we're going through our mus-frequency method (set! randiff (radians->hz randiff)) ;; gourd resonance filters (do ((i 0 (+ i 1))) ((= i resn)) (vector-set! tzs i (make-two-pole 1.0 (* -2.0 (shell-resos i) (cos (hz->radians (shell-freqs i)))) (* (shell-resos i) (shell-resos i))))) (do ((i st (+ i srate4))) ((>= i nd)) (set! temp 0.0) (set! stop (min nd (+ i srate4))) (do ((k i (+ k 1))) ((= k stop)) (if (< temp two-pi) (begin ;; shake over 50msec and add shake energy (set! temp (+ temp h20)) (set! shake-energy (+ shake-energy (- 1.0 (cos temp)))))) (set! shake-energy (* shake-energy system-decay)) ;; if collision, add energy (if (< (random 1.0) probability) (begin (set! snd-level (+ snd-level (* gain shake-energy))) ;; randomize res freqs a bit (do ((j 0 (+ j 1))) ((= j resn)) (set! (mus-frequency (vector-ref tzs j)) (+ (shell-freqs j) (mus-random randiff)))))) ;; actual sound is random (set! input (mus-random snd-level)) ;; compute exponential sound decay (set! snd-level (* snd-level sound-decay)) ;; gourd resonance filter calcs (set! last-sum sum) (set! sum 0.0) (do ((j 0 (+ j 1))) ((= j resn)) (set! sum (+ sum (two-pole (vector-ref tzs j) input)))) (if with-filters (outa k (one-zero oz (- sum last-sum))) (outa k (* sndamp sum)))))))) ;;; tambourine: (with-sound (:play #t :statistics #t) (big-maraca 0 1 .25 0.95 0.9985 .03125 '(2300 5600 8100) '(0.96 0.995 0.995) .01)) ;;; sleighbells: (with-sound (:play #t :statistics #t) (big-maraca 0 2 .15 0.97 0.9994 0.03125 '(2500 5300 6500 8300 9800) '(0.999 0.999 0.999 0.999 0.999))) ;;; sekere: (with-sound (:play #t :statistics #t) (big-maraca 0 2 .5 0.96 0.999 .0625 '(5500) '(0.6))) ;;; windchimes: (with-sound (:play #t :statistics #t) (big-maraca 0 2 .5 0.99995 0.95 .001 '(2200 2800 3400) '(0.995 0.995 0.995) .01 #f)) snd-16.1/xg.c0000644000076400007640001335465412626046435011152 0ustar bilbil/* xg.c: s7, Ruby, and Forth bindings for gtk/pango/cairo, some of glib * this file generated automatically from makexg.scm and xgdata.scm * needs xen.h * * reference args initial values are usually ignored, resultant values are returned in a list. * null ptrs are passed and returned as #f, trailing "user_data" callback function arguments are optional (default: #f). * where supported, "..." args are passed as a list, trailing NULL or -1 should be omitted. * 'xg is added to *features* * * added funcs: * (xg-version): date string. * (c-array->list arr len) derefs each member of arr, returning lisp list, len=#f: null terminated array * (list->c-array lst ctype) packages each member of list as c-type "type" returning (wrapped) c array * (make-target-entry lst) returns a GtkTargetEntry table, each member of 'lst' should be (list target flags info) * (GtkTextIter): GtkTextIter struct * (GtkTreeIter): GtkTreeIter struct * (PangoRectangle): PangoRectangle struct * (cairo_matrix_t): cairo_matrix_t struct (if cairo) * * omitted functions and macros: * anything with a va_list or GtkArg* argument. * most of the unusual keysym names * all *_CLASS, *_IFACE macros, *_get_type functions * win32-specific functions * * HISTORY: * * 29-Oct: removed ->string. * 21-Aug-15: procedure-signature changes. * -------- * 27-Dec: integer procedure stuff. * 16-Apr: changed max-args to 8. * 6-Mar: changed most macros. * 21-Feb-14: changed _p to _is_. * -------- * 3-Sep: use symbol directly in type checks, not the symbol name. * 18-Aug: changed the gtk version macros to reflect the version number. * 7-Jun-13: added mixed arg types to the ... arg lists. * -------- * 19-Aug-10: removed lots of Gdk stuff -- we assume Gtk 2.9 and cairo now. * 28-Jan-10: removed the rest of the struct accessors. * -------- * 16-Dec-09: removed Guile support. * -------- * 16-Oct: removed Gauche support. * 1-Sep: s7 support. * 8-Jul-08: started removing all struct accessors (for Gtk 3). * -------- * 9-Mar: removed all *_get_type functions (nearly 300!). * 5-Mar-07: cairo and more gtkprint. * -------- * 26-Aug: removed --with-x11, WITH_GTK_AND_X11, xg-x11.h. * 4-Aug: added a form of g_object_get and gtk_settings_get_for_screen. * 20-Jul: gtkprint stuff. * 17-Jul: g_signal_connect and other related macros. * 21-Apr: Gauche support. * 29-Mar: Forth support. * 7-Mar-06: if g_set_error, return the error message, not the GError pointer * -------- * 9-Jul: Collapse 2.3.* into 2.3.6, 2.5.* into 2.5.6. * 13-Jun: folded xg-ruby.c into xg.c. * 21-Feb: changed libxm to libxg, xm-version to xg-version. * 10-Jan: plugged some memory leaks. * 4-Jan-05: removed deprecated Xen_VECTOR_ELEMENTS. * -------- * 8-Dec: added some g_log handler funcs. * 6-Dec: check for lost callback context. * tightened type (pointer) checking considerably (#f only acceptable if explicit @ used in xgdata.scm). * 3-Dec: changed GPOINTER cast func to accept non-lists. * 27-Aug: removed the PANGO_ENGINE and PANGO_BACKEND stuff. * 2-Jun: gdk_atom_name needs to free return value * 28-May: GtkFileSelection struct support put back in -- need ok_button et al. * 14-Apr: make-target-entry. * 4-Apr: various additions, deletions, and bugfixes for snd-test 26 * 29-Mar: support for some ... args. * 22-Mar: g_source_remove and related changes. * 12-Feb-04: g_list_nth_data (Kjetil S. Matheussen). * -------- * 15-Sep: removed client_window GtkIMMulticontext struct field. * 26-May: removed nugatory GdkInputFunction stuff and some unused type converters. * 1-Apr: gdk_property_get uses scm_mem2string in some cases now. * 31-Mar: gchar* -> xen string bugfix (thanks to Friedrich Delgado Friedrichs). * 10-Mar-03: Ruby Xm_Version. * -------- * 18-Nov: Ruby/Gtk bugfixes. * 25-Oct: removed (deprecated) gdk_set_pointer_hooks * 31-Jul: removed GTK 1.n support * 24-Jul: changed Guile prefix (R5RS reserves vertical-bar). * 19-Jul: XG_FIELD_PRE for change from using vertical-bar (reserved in R5RS) * 2-Jun: removed deprecated and broken stuff * 12-Mar: support for GtkDestroyNotify callbacks * Ruby support via xg-ruby.c * 21-Feb: #f=NULL throughout, gdk-pixbuf, GTypes. * 11-Feb-02: initial version. */ #include "mus-config.h" #define HAVE_CAIRO_1_8 ((CAIRO_VERSION_MAJOR >= 1) && (CAIRO_VERSION_MINOR >= 8)) #define HAVE_CAIRO_1_9_12 ((CAIRO_VERSION_MAJOR >= 1) && (CAIRO_VERSION_MINOR >= 9) && (CAIRO_VERSION_MICRO >= 12)) #if ((!__NetBSD__) && ((_MSC_VER) || (!defined(__STC__)) || (defined(__STDC_VERSION__) && (__STDC_VERSION__ < 199901L)))) #define __func__ __FUNCTION__ #endif #if HAVE_EXTENSION_LANGUAGE #include #include #include #include #include #if (!GTK_CHECK_VERSION(3, 0, 0)) #include #endif #include #include #include #if USE_SND /* USE_SND causes xm to use Snd's error handlers which are much smarter than xen's fallback versions */ #include "snd.h" #else #include "xen.h" #define NOT_A_GC_LOC -1 #endif #ifndef PROC_FALSE #if HAVE_RUBY #define PROC_FALSE "false" #define PROC_TRUE "true" #else #define PROC_FALSE "#f" #define PROC_TRUE "#t" #endif #endif /* -------------------------------- GC -------------------------------- */ static Xen_object_type_t xm_obj_tag; #if HAVE_RUBY static void *xm_obj_free(Xen obj) { void *xobj; xobj = (void *)obj; free(xobj); return(NULL); } #endif #if HAVE_FORTH static void xm_obj_free(Xen obj) { void *val; val = (void *)Xen_object_ref(obj); free(val); } #endif #if HAVE_SCHEME static void xm_obj_free(void *val) { free(val); } static bool s7_equalp_xm(void *x1, void *x2) { return(x1 == x2); } #endif static Xen make_xm_obj(void *ptr) { return(Xen_make_object(xm_obj_tag, ptr, 0, xm_obj_free)); } static void define_xm_obj(void) { #if HAVE_SCHEME xm_obj_tag = s7_new_type_x(s7, "", NULL, xm_obj_free, s7_equalp_xm, NULL, NULL, NULL, NULL, NULL, NULL, NULL); #else xm_obj_tag = Xen_make_object_type("XmObj", sizeof(void *)); #endif #if HAVE_FORTH fth_set_object_free(xm_obj_tag, xm_obj_free); #endif } /* prefix for all names */ #if HAVE_SCHEME #define Xg_pre "" #define Xg_field_pre "." #define Xg_post "" #endif #if HAVE_RUBY /* for Ruby, XG PRE needs to be uppercase */ #define Xg_pre "R" #define Xg_post "" #define Xg_field_pre "R" #endif #if HAVE_FORTH #define Xg_pre "F" #define Xg_post "" #define Xg_field_pre "F" #endif static Xen xg_GtkAllocation_symbol, xg_GtkShortcutsWindow__symbol, xg_GtkStackSidebar__symbol, xg_GtkSearchEntry__symbol, xg_GtkPopoverMenu__symbol, xg_GtkStyleContext__symbol, xg_GdkGLContext__symbol, xg_GtkGLArea__symbol, xg_GtkPropagationPhase_symbol, xg_GtkEventController__symbol, xg_GtkGestureZoom__symbol, xg_GtkGestureSwipe__symbol, xg_GtkGestureSingle__symbol, xg_GtkGestureRotate__symbol, xg_GtkGestureMultiPress__symbol, xg_GtkGesturePan__symbol, xg_GtkGestureDrag__symbol, xg_GdkEventSequence__symbol, xg_GtkEventSequenceState_symbol, xg_GtkGesture__symbol, xg_GtkPopover__symbol, xg_GtkActionBar__symbol, xg_GtkFlowBox__symbol, xg_GtkFlowBoxChild__symbol, xg_GdkEventType_symbol, xg_GtkSearchBar__symbol, xg_GtkListBox__symbol, xg_GtkListBoxRow__symbol, xg_GtkHeaderBar__symbol, xg_GtkRevealerTransitionType_symbol, xg_GtkRevealer__symbol, xg_GtkStackTransitionType_symbol, xg_GtkStack__symbol, xg_GtkStackSwitcher__symbol, xg_GtkPlacesSidebar__symbol, xg_GtkPlacesOpenFlags_symbol, xg_GtkBaselinePosition_symbol, xg_GdkFullscreenMode_symbol, xg_GtkInputHints_symbol, xg_GtkInputPurpose_symbol, xg_GtkLevelBarMode_symbol, xg_GtkLevelBar__symbol, xg_GtkMenuButton__symbol, xg_GtkColorChooser__symbol, xg_GtkApplicationWindow__symbol, xg_GtkApplication__symbol, xg_GMenuModel__symbol, xg_guint___symbol, xg_GdkModifierIntent_symbol, xg_GtkFontChooser__symbol, xg_GdkScrollDirection_symbol, xg_GtkOverlay__symbol, xg_GtkWidgetPath__symbol, xg_GtkStateFlags_symbol, xg_GdkScreen___symbol, xg_GtkToolShell__symbol, xg_GtkWindowGroup__symbol, xg_GtkInvisible__symbol, xg_GtkOrientable__symbol, xg_GtkCellArea__symbol, xg_GtkBorder__symbol, xg_GtkSwitch__symbol, xg_GtkScrollablePolicy_symbol, xg_GtkScrollable__symbol, xg_GtkGrid__symbol, xg_GdkRGBA__symbol, xg_GtkComboBoxText__symbol, xg_GtkAlign_symbol, xg_GtkContainerClass__symbol, xg_GtkSizeRequestMode_symbol, xg_cairo_region_overlap_t_symbol, xg_cairo_rectangle_int_t__symbol, xg_double__symbol, xg_cairo_rectangle_t__symbol, xg_cairo_device_t__symbol, xg_cairo_bool_t_symbol, xg_cairo_text_cluster_flags_t__symbol, xg_cairo_text_cluster_t___symbol, xg_cairo_glyph_t___symbol, xg_cairo_text_cluster_flags_t_symbol, xg_cairo_text_cluster_t__symbol, xg_cairo_region_t__symbol, xg_GtkMessageDialog__symbol, xg_GdkDevice__symbol, xg_GdkDeviceManager__symbol, xg_GtkAccessible__symbol, xg_GdkModifierType__symbol, xg_GtkToolPaletteDragTargets_symbol, xg_GtkToolItemGroup__symbol, xg_GtkToolPalette__symbol, xg_GtkSpinner__symbol, xg_GtkEntryBuffer__symbol, xg_GtkMessageType_symbol, xg_GtkInfoBar__symbol, xg_GIcon__symbol, xg_GtkEntryIconPosition_symbol, xg_GFile__symbol, xg_GtkScaleButton__symbol, xg_GtkCalendarDetailFunc_symbol, xg_GtkTooltip__symbol, xg_cairo_rectangle_list_t__symbol, xg_void__symbol, xg_cairo_filter_t_symbol, xg_cairo_extend_t_symbol, xg_cairo_format_t_symbol, xg_cairo_path_t__symbol, xg_cairo_destroy_func_t_symbol, xg_cairo_user_data_key_t__symbol, xg_cairo_text_extents_t__symbol, xg_cairo_font_extents_t__symbol, xg_cairo_font_face_t__symbol, xg_cairo_glyph_t__symbol, xg_cairo_scaled_font_t__symbol, xg_cairo_font_weight_t_symbol, xg_cairo_font_slant_t_symbol, xg_cairo_hint_metrics_t_symbol, xg_cairo_hint_style_t_symbol, xg_cairo_subpixel_order_t_symbol, xg_cairo_status_t_symbol, xg_bool_symbol, xg_cairo_matrix_t__symbol, xg_cairo_line_join_t_symbol, xg_cairo_line_cap_t_symbol, xg_cairo_fill_rule_t_symbol, xg_cairo_antialias_t_symbol, xg_cairo_operator_t_symbol, xg_cairo_pattern_t__symbol, xg_cairo_content_t_symbol, xg_GtkPageSet_symbol, xg_GtkPageRange__symbol, xg_GtkPrintPages_symbol, xg_GtkPrintQuality_symbol, xg_GtkPrintDuplex_symbol, xg_GtkPaperSize__symbol, xg_GtkPageOrientation_symbol, xg_GtkPrintSettingsFunc_symbol, xg_GtkPrintOperationPreview__symbol, xg_GtkPageSetupDoneFunc_symbol, xg_GtkPrintStatus_symbol, xg_GtkPrintOperationAction_symbol, xg_GtkPrintOperationResult_symbol, xg_GtkUnit_symbol, xg_GtkPrintSettings__symbol, xg_GtkPrintOperation__symbol, xg_GtkPageSetup__symbol, xg_GtkPrintContext__symbol, xg_cairo_surface_t__symbol, xg_GtkTreeViewGridLines_symbol, xg_GtkRecentData__symbol, xg_GtkTextBufferDeserializeFunc_symbol, xg_GtkTextBufferSerializeFunc_symbol, xg_time_t_symbol, xg_GtkRecentChooserMenu__symbol, xg_GtkRecentManager__symbol, xg_GtkRecentFilter__symbol, xg_GtkRecentSortFunc_symbol, xg_GtkRecentSortType_symbol, xg_GtkRecentChooser__symbol, xg_GtkLinkButton__symbol, xg_GtkAssistantPageType_symbol, xg_GtkAssistantPageFunc_symbol, xg_GtkAssistant__symbol, xg_GDestroyNotify_symbol, xg_GtkTreeViewSearchPositionFunc_symbol, xg_GtkSensitivityType_symbol, xg_GtkClipboardRichTextReceivedFunc_symbol, xg_GtkMenuBar__symbol, xg_GtkPackDirection_symbol, xg_GtkIconViewDropPosition_symbol, xg_GValue__symbol, xg_GLogFunc_symbol, xg_PangoMatrix__symbol, xg_PangoRenderPart_symbol, xg_PangoRenderer__symbol, xg_GtkClipboardImageReceivedFunc_symbol, xg_GtkMenuToolButton__symbol, xg_GtkFileChooserButton__symbol, xg_PangoScriptIter__symbol, xg_PangoScript_symbol, xg_PangoAttrFilterFunc_symbol, xg_PangoEllipsizeMode_symbol, xg_GtkIconViewForeachFunc_symbol, xg_GtkAboutDialog__symbol, xg_GtkTreeViewRowSeparatorFunc_symbol, xg_GtkCellView__symbol, xg_GtkAccelMap__symbol, xg_GtkClipboardTargetsReceivedFunc_symbol, xg_GtkOrientation_symbol, xg_GtkToolButton__symbol, xg_GtkIconLookupFlags_symbol, xg_GtkIconInfo__symbol, xg_GtkIconTheme__symbol, xg_GtkFileChooser__symbol, xg_GtkCellLayoutDataFunc_symbol, xg_GtkCellLayout__symbol, xg_GtkFileFilterFunc_symbol, xg_GtkFileFilterFlags_symbol, xg_GtkFileFilter__symbol, xg_GSourceFunc_symbol, xg_GtkToggleToolButton__symbol, xg_GtkSeparatorToolItem__symbol, xg_GtkRadioToolButton__symbol, xg_GtkEntryCompletionMatchFunc_symbol, xg_GtkFontButton__symbol, xg_GtkExpander__symbol, xg_GtkComboBox__symbol, xg_GtkTreeModelFilter__symbol, xg_GtkFileChooserAction_symbol, xg_GtkToolItem__symbol, xg_GtkEventBox__symbol, xg_GtkCalendarDisplayOptions_symbol, xg_GdkScreen__symbol, xg_PangoLayoutRun__symbol, xg_PangoLayoutIter__symbol, xg_PangoLayoutLine__symbol, xg_int__symbol, xg_PangoAlignment_symbol, xg_PangoWrapMode_symbol, xg_PangoItem__symbol, xg_PangoGlyphString__symbol, xg_PangoFontMap__symbol, xg_PangoGlyph_symbol, xg_PangoFontFace__symbol, xg_PangoFontFace___symbol, xg_PangoFontFamily__symbol, xg_PangoFontMask_symbol, xg_PangoFontDescription___symbol, xg_PangoCoverageLevel_symbol, xg_PangoCoverage__symbol, xg_PangoFontMetrics__symbol, xg_PangoFontset__symbol, xg_PangoFont__symbol, xg_PangoFontFamily___symbol, xg_PangoLogAttr__symbol, xg_PangoAnalysis__symbol, xg_PangoAttrList___symbol, xg_PangoAttrIterator__symbol, xg_PangoRectangle__symbol, xg_PangoUnderline_symbol, xg_PangoStretch_symbol, xg_PangoVariant_symbol, xg_PangoWeight_symbol, xg_PangoStyle_symbol, xg_guint16_symbol, xg_PangoAttribute__symbol, xg_PangoAttrType_symbol, xg_PangoColor__symbol, xg_GdkGravity_symbol, xg_GtkWindowPosition_symbol, xg_GtkWindowType_symbol, xg_GtkWindow__symbol, xg_GtkTextDirection_symbol, xg_AtkObject__symbol, xg_GtkDirectionType_symbol, xg_GtkAllocation__symbol, xg_GtkViewport__symbol, xg_GtkTreeViewSearchEqualFunc_symbol, xg_GtkTreeViewDropPosition_symbol, xg_GtkTreeViewMappingFunc_symbol, xg_GtkTreeViewColumnDropFunc_symbol, xg_GtkTreeViewColumnSizing_symbol, xg_GtkTreeCellDataFunc_symbol, xg_GtkTreeStore__symbol, xg_GtkTreeIterCompareFunc_symbol, xg_GtkSortType_symbol, xg_GtkTreeSortable__symbol, xg_GtkTreeSelectionForeachFunc_symbol, xg_GtkTreeModel___symbol, xg_GtkTreeSelectionFunc_symbol, xg_GtkSelectionMode_symbol, xg_GtkTreeModelSort__symbol, xg_GtkTreeModelForeachFunc_symbol, xg_GtkTreeModelFlags_symbol, xg_GtkTreeRowReference__symbol, xg_GtkTreeDragDest__symbol, xg_GtkTreeDragSource__symbol, xg_GtkToolbarStyle_symbol, xg_GtkToolbar__symbol, xg_GtkToggleButton__symbol, xg_PangoTabArray__symbol, xg_GtkWrapMode_symbol, xg_GtkTextWindowType_symbol, xg_GtkTextView__symbol, xg_GtkTextTagTableForeach_symbol, xg_GtkTextSearchFlags_symbol, xg_GtkTextCharPredicate_symbol, xg_GtkTextAttributes__symbol, xg_GtkTextMark__symbol, xg_GtkTextChildAnchor__symbol, xg_GtkTextIter__symbol, xg_GtkTextTagTable__symbol, xg_GtkTextBuffer__symbol, xg_GtkStatusbar__symbol, xg_GtkSpinType_symbol, xg_GtkSpinButtonUpdatePolicy_symbol, xg_GtkSpinButton__symbol, xg_GtkSizeGroupMode_symbol, xg_GtkSizeGroup__symbol, xg_GtkSettings__symbol, xg_GtkCornerType_symbol, xg_GtkPolicyType_symbol, xg_GtkScrolledWindow__symbol, xg_GtkScale__symbol, xg_GtkRange__symbol, xg_GtkRadioMenuItem__symbol, xg_GtkRadioButton__symbol, xg_GtkProgressBar__symbol, xg_GtkPaned__symbol, xg_GtkPositionType_symbol, xg_GtkNotebook__symbol, xg_GtkMenuShell__symbol, xg_GtkMenuItem__symbol, xg_GtkMenuPositionFunc_symbol, xg_PangoLanguage__symbol, xg_GtkListStore__symbol, xg_GtkLayout__symbol, xg_GtkJustification_symbol, xg_GtkLabel__symbol, xg_guint16__symbol, xg_GtkIMContextSimple__symbol, xg_GdkEventKey__symbol, xg_PangoAttrList__symbol, xg_GtkIMContext__symbol, xg_GtkImageType_symbol, xg_GtkImage__symbol, xg_GtkShadowType_symbol, xg_GtkFrame__symbol, xg_GtkFixed__symbol, xg_PangoLayout__symbol, xg_GtkEntry__symbol, xg_GtkEditable__symbol, xg_GtkTargetList__symbol, xg_GtkDestDefaults_symbol, xg_etc_symbol, xg_GtkDialog__symbol, xg_GtkCallback_symbol, xg_GtkContainer__symbol, xg_GtkClipboardTextReceivedFunc_symbol, xg_GtkClipboardReceivedFunc_symbol, xg_GtkClipboardClearFunc_symbol, xg_GtkClipboardGetFunc_symbol, xg_GtkTargetEntry__symbol, xg_GtkCheckMenuItem__symbol, xg_GtkCellRendererToggle__symbol, xg_GtkCellRendererText__symbol, xg_GtkCellRendererState_symbol, xg_GtkCellEditable__symbol, xg_GtkCalendar__symbol, xg_GtkReliefStyle_symbol, xg_GtkButton__symbol, xg_GtkPackType_symbol, xg_GtkBox__symbol, xg_GtkBin__symbol, xg_GtkBindingSet__symbol, xg_GtkButtonBox__symbol, xg_GtkButtonBoxStyle_symbol, xg_GtkAspectFrame__symbol, xg_GtkAdjustment__symbol, xg_GtkAccelMapForeach_symbol, xg_GtkAccelLabel__symbol, xg_GtkAccelGroupEntry__symbol, xg_lambda3_symbol, xg_GSList__symbol, xg_GObject__symbol, xg_GtkAccelFlags_symbol, xg_GtkAccelGroup__symbol, xg_GTimeVal__symbol, xg_GdkPixbufAnimationIter__symbol, xg_GdkPixbufAnimation__symbol, xg_GdkInterpType_symbol, xg_double_symbol, xg_gfloat_symbol, xg_guchar_symbol, xg_char___symbol, xg_GdkPixbufDestroyNotify_symbol, xg_GError__symbol, xg_int_symbol, xg_GdkColorspace_symbol, xg_GdkWindowTypeHint_symbol, xg_GdkWindowHints_symbol, xg_GdkGeometry__symbol, xg_GdkWindowEdge_symbol, xg_GdkWMFunction_symbol, xg_GdkWMDecoration_symbol, xg_GdkEventMask_symbol, xg_GdkWindowState_symbol, xg_GdkFilterFunc_symbol, xg_GdkWindowType_symbol, xg_GdkWindowAttr__symbol, xg_GdkVisualType__symbol, xg_gint__symbol, xg_GdkVisualType_symbol, xg_GdkPropMode_symbol, xg_guchar__symbol, xg_PangoContext__symbol, xg_PangoDirection_symbol, xg_GdkKeymapKey__symbol, xg_GdkKeymap__symbol, xg_GdkRectangle__symbol, xg_char__symbol, xg_gchar___symbol, xg_GdkEventFunc_symbol, xg_gdouble_symbol, xg_GList__symbol, xg_GdkWindow__symbol, xg_guint32_symbol, xg_GdkDragAction_symbol, xg_GdkDragContext__symbol, xg_GdkCursorType_symbol, xg_GdkDisplay__symbol, xg_GdkCursor__symbol, xg_GdkVisual__symbol, xg_GSignalMatchType_symbol, xg_GConnectFlags_symbol, xg_GtkDestroyNotify_symbol, xg_GSignalEmissionHook_symbol, xg_gulong_symbol, xg_GSignalInvocationHint__symbol, xg_GQuark_symbol, xg_guint__symbol, xg_GSignalQuery__symbol, xg_GType__symbol, xg_GSignalCMarshaller_symbol, xg_gpointer_symbol, xg_GSignalAccumulator_symbol, xg_GSignalFlags_symbol, xg_GType_symbol, xg_GClosureNotify_symbol, xg_GCallback_symbol, xg_GNormalizeMode_symbol, xg_glong_symbol, xg_gssize_symbol, xg_gunichar__symbol, xg_void_symbol, xg_GtkRecentInfo__symbol, xg_gsize_symbol, xg_guint8__symbol, xg_GdkAtom_symbol, xg_GLogLevelFlags_symbol, xg_GdkPixbuf__symbol, xg_GtkIconView__symbol, xg_GtkEntryCompletion__symbol, xg_GtkFileFilterInfo__symbol, xg_GtkTreeSelection__symbol, xg_GtkCellRenderer__symbol, xg_GtkTreeViewColumn__symbol, xg_GtkTreeView__symbol, xg_gunichar_symbol, xg_GdkAtom__symbol, xg_GtkSelectionData__symbol, xg_GtkClipboard__symbol, xg_GtkTreeIter__symbol, xg_GtkTreePath__symbol, xg_GtkTreeModel__symbol, xg_GdkModifierType_symbol, xg_guint_symbol, xg_gchar__symbol, xg_GtkTextTag__symbol, xg_gboolean_symbol, xg_gint_symbol, xg_GtkMenu__symbol, xg_GdkXEvent__symbol, xg_GtkWidget__symbol, xg_lambda_data_symbol, xg_GClosure__symbol, xg_GtkAccelKey__symbol, xg_GdkEventMotion__symbol, xg_gdouble__symbol, xg_GdkEventAny__symbol, xg_GdkEvent__symbol, xg_cairo_t__symbol, xg_cairo_font_options_t__symbol, xg_PangoFontDescription__symbol, xg_idler_symbol, xg_GtkCellRendererPixbuf__symbol, xg_GtkCheckButton__symbol, xg_GtkDrawingArea__symbol, xg_GtkScrollbar__symbol, xg_GtkSeparator__symbol, xg_GtkSeparatorMenuItem__symbol, xg_GdkEventExpose__symbol, xg_GdkEventNoExpose__symbol, xg_GdkEventVisibility__symbol, xg_GdkEventButton__symbol, xg_GdkEventScroll__symbol, xg_GdkEventCrossing__symbol, xg_GdkEventFocus__symbol, xg_GdkEventConfigure__symbol, xg_GdkEventProperty__symbol, xg_GdkEventSelection__symbol, xg_GdkEventProximity__symbol, xg_GdkEventSetting__symbol, xg_GdkEventWindowState__symbol, xg_GdkEventDND__symbol, xg_GtkFileChooserDialog__symbol, xg_GtkFileChooserWidget__symbol, xg_GtkColorButton__symbol, xg_GtkAccelMap_symbol, xg_GtkCellRendererCombo__symbol, xg_GtkCellRendererProgress__symbol, xg_GtkCellRendererAccel__symbol, xg_GtkCellRendererSpin__symbol, xg_GtkRecentChooserDialog__symbol, xg_GtkRecentChooserWidget__symbol, xg_GtkCellRendererSpinner__symbol, xg_gboolean__symbol, xg_GtkFontChooserDialog__symbol, xg_GtkFontChooserWidget__symbol, xg_GtkColorChooserDialog__symbol, xg_GtkColorChooserWidget__symbol, xg_GtkColorWidget__symbol, xg_GtkGestureLongPress__symbol; #define wrap_for_Xen(Name, Value) Xen_list_2(xg_ ## Name ## _symbol, Xen_wrap_C_pointer(Value)) #define is_wrapped(Name, Value) (Xen_is_pair(Value) && (Xen_car(Value) == xg_ ## Name ## _symbol)) #define Xm_type(Name, XType) \ static Xen C_to_Xen_ ## Name (XType val) {return(Xen_list_2(xg_ ## Name ## _symbol, C_ulong_to_Xen_ulong(val)));} \ static XType Xen_to_C_ ## Name (Xen val) {return((XType)Xen_ulong_to_C_ulong(Xen_cadr(val)));} \ static bool Xen_is_ ## Name (Xen val) {return(is_wrapped(Name, val));} #define Xm_type_1(Name, XType) \ static XType Xen_to_C_ ## Name (Xen val) {return((XType)Xen_ulong_to_C_ulong(Xen_cadr(val)));} \ static bool Xen_is_ ## Name (Xen val) {return(is_wrapped(Name, val));} #define Xm_type_no_p_2(Name, XType) \ static Xen C_to_Xen_ ## Name (XType val) {return(wrap_for_Xen(Name, val));} #define Xm_type_Ptr(Name, XType) \ static Xen C_to_Xen_ ## Name (XType val) {if (val) return(wrap_for_Xen(Name, val)); return(Xen_false);} \ static XType Xen_to_C_ ## Name (Xen val) {if (Xen_is_false(val)) return(NULL); return((XType)Xen_unwrap_C_pointer(Xen_cadr(val)));} \ static bool Xen_is_ ## Name (Xen val) {return(is_wrapped(Name, val));} #define Xm_type_Ptr_const(Name, XType) \ static Xen C_to_Xen_ ## Name (const XType val) {if (val) return(wrap_for_Xen(Name, val)); return(Xen_false);} \ static const XType Xen_to_C_ ## Name (Xen val) {if (Xen_is_false(val)) return(NULL); return((const XType)Xen_unwrap_C_pointer(Xen_cadr(val)));} \ static bool Xen_is_ ## Name (Xen val) {return(is_wrapped(Name, val));} #define Xm_type_Ptr_1(Name, XType) \ static XType Xen_to_C_ ## Name (Xen val) {if (Xen_is_false(val)) return(NULL); return((XType)Xen_unwrap_C_pointer(Xen_cadr(val)));} \ static bool Xen_is_ ## Name (Xen val) {return(is_wrapped(Name, val));} #define Xm_type_Ptr_2(Name, XType) \ static Xen C_to_Xen_ ## Name (XType val) {if (val) return(wrap_for_Xen(Name, val)); return(Xen_false);} \ /* type checks for callback wrappers */ #define Xen_is_lambda3(Arg) Xen_is_false(Arg) || (Xen_is_procedure(Arg) && (Xen_is_aritable(Arg, 3))) #define Xen_is_GtkCallback(Arg) Xen_is_false(Arg) || (Xen_is_procedure(Arg) && (Xen_is_aritable(Arg, 2))) #define Xen_is_GSourceFunc(Arg) Xen_is_false(Arg) || (Xen_is_procedure(Arg) && (Xen_is_aritable(Arg, 1))) #define Xen_is_GtkDestroyNotify(Arg) Xen_is_false(Arg) || (Xen_is_procedure(Arg) && (Xen_is_aritable(Arg, 1))) #define Xen_is_GdkFilterFunc(Arg) Xen_is_false(Arg) || (Xen_is_procedure(Arg) && (Xen_is_aritable(Arg, 3))) #define Xen_is_GdkEventFunc(Arg) Xen_is_false(Arg) || (Xen_is_procedure(Arg) && (Xen_is_aritable(Arg, 2))) #define Xen_is_GtkMenuPositionFunc(Arg) Xen_is_false(Arg) || (Xen_is_procedure(Arg) && (Xen_is_aritable(Arg, 5))) #define Xen_is_GtkTextTagTableForeach(Arg) Xen_is_false(Arg) || (Xen_is_procedure(Arg) && (Xen_is_aritable(Arg, 2))) #define Xen_is_GtkAccelMapForeach(Arg) Xen_is_false(Arg) || (Xen_is_procedure(Arg) && (Xen_is_aritable(Arg, 5))) #define Xen_is_GtkTreeModelForeachFunc(Arg) Xen_is_false(Arg) || (Xen_is_procedure(Arg) && (Xen_is_aritable(Arg, 4))) #define Xen_is_GtkTreeSelectionForeachFunc(Arg) Xen_is_false(Arg) || (Xen_is_procedure(Arg) && (Xen_is_aritable(Arg, 4))) #define Xen_is_GtkClipboardReceivedFunc(Arg) Xen_is_false(Arg) || (Xen_is_procedure(Arg) && (Xen_is_aritable(Arg, 3))) #define Xen_is_GtkClipboardTextReceivedFunc(Arg) Xen_is_false(Arg) || (Xen_is_procedure(Arg) && (Xen_is_aritable(Arg, 3))) #define Xen_is_GtkClipboardTargetsReceivedFunc(Arg) Xen_is_false(Arg) || (Xen_is_procedure(Arg) && (Xen_is_aritable(Arg, 4))) #define Xen_is_GtkTextCharPredicate(Arg) Xen_is_false(Arg) || (Xen_is_procedure(Arg) && (Xen_is_aritable(Arg, 2))) #define Xen_is_GtkTreeViewColumnDropFunc(Arg) Xen_is_false(Arg) || (Xen_is_procedure(Arg) && (Xen_is_aritable(Arg, 5))) #define Xen_is_GtkTreeViewMappingFunc(Arg) Xen_is_false(Arg) || (Xen_is_procedure(Arg) && (Xen_is_aritable(Arg, 3))) #define Xen_is_GtkTreeViewSearchEqualFunc(Arg) Xen_is_false(Arg) || (Xen_is_procedure(Arg) && (Xen_is_aritable(Arg, 5))) #define Xen_is_GtkTreeCellDataFunc(Arg) Xen_is_false(Arg) || (Xen_is_procedure(Arg) && (Xen_is_aritable(Arg, 5))) #define Xen_is_GtkTreeIterCompareFunc(Arg) Xen_is_false(Arg) || (Xen_is_procedure(Arg) && (Xen_is_aritable(Arg, 4))) #define Xen_is_GtkTreeSelectionFunc(Arg) Xen_is_false(Arg) || (Xen_is_procedure(Arg) && (Xen_is_aritable(Arg, 5))) #define Xen_is_GtkClipboardGetFunc(Arg) Xen_is_false(Arg) || (Xen_is_procedure(Arg) && (Xen_is_aritable(Arg, 4))) #define Xen_is_GtkClipboardClearFunc(Arg) Xen_is_false(Arg) || (Xen_is_procedure(Arg) && (Xen_is_aritable(Arg, 2))) #define Xen_is_GtkFileFilterFunc(Arg) Xen_is_false(Arg) || (Xen_is_procedure(Arg) && (Xen_is_aritable(Arg, 2))) #define Xen_is_GtkEntryCompletionMatchFunc(Arg) Xen_is_false(Arg) || (Xen_is_procedure(Arg) && (Xen_is_aritable(Arg, 4))) #define Xen_is_GtkTreeViewRowSeparatorFunc(Arg) Xen_is_false(Arg) || (Xen_is_procedure(Arg) && (Xen_is_aritable(Arg, 3))) #define Xen_is_GtkIconViewForeachFunc(Arg) Xen_is_false(Arg) || (Xen_is_procedure(Arg) && (Xen_is_aritable(Arg, 3))) #define Xen_is_GtkClipboardImageReceivedFunc(Arg) Xen_is_false(Arg) || (Xen_is_procedure(Arg) && (Xen_is_aritable(Arg, 3))) #define Xen_is_GLogFunc(Arg) Xen_is_false(Arg) || (Xen_is_procedure(Arg) && (Xen_is_aritable(Arg, 4))) #define Xen_is_GtkClipboardRichTextReceivedFunc(Arg) Xen_is_false(Arg) || (Xen_is_procedure(Arg) && (Xen_is_aritable(Arg, 5))) #define Xen_is_GtkTreeViewSearchPositionFunc(Arg) Xen_is_false(Arg) || (Xen_is_procedure(Arg) && (Xen_is_aritable(Arg, 3))) #define Xen_is_GtkAssistantPageFunc(Arg) Xen_is_false(Arg) || (Xen_is_procedure(Arg) && (Xen_is_aritable(Arg, 2))) #define Xen_is_GtkRecentSortFunc(Arg) Xen_is_false(Arg) || (Xen_is_procedure(Arg) && (Xen_is_aritable(Arg, 3))) #define Xen_is_GCallback(Arg) (Xen_is_procedure(Arg) && ((Xen_is_aritable(Arg, 2)) || (Xen_is_aritable(Arg, 3)) || (Xen_is_aritable(Arg, 4)))) #define Xen_to_C_lambda3(Arg) Xen_is_false(Arg) ? NULL : gxg_find_func #define Xen_to_C_GtkCallback(Arg) Xen_is_false(Arg) ? NULL : gxg_func2 #define Xen_to_C_GSourceFunc(Arg) Xen_is_false(Arg) ? NULL : gxg_timer_func #define Xen_to_C_GtkDestroyNotify(Arg) Xen_is_false(Arg) ? NULL : gxg_destroy_func #define Xen_to_C_GdkFilterFunc(Arg) Xen_is_false(Arg) ? NULL : gxg_filter_func #define Xen_to_C_GdkEventFunc(Arg) Xen_is_false(Arg) ? NULL : gxg_event_func #define Xen_to_C_GtkMenuPositionFunc(Arg) Xen_is_false(Arg) ? NULL : gxg_menu_position_func #define Xen_to_C_GtkTextTagTableForeach(Arg) Xen_is_false(Arg) ? NULL : gxg_text_tag_table_foreach #define Xen_to_C_GtkAccelMapForeach(Arg) Xen_is_false(Arg) ? NULL : gxg_accel_map_foreach #define Xen_to_C_GtkTreeModelForeachFunc(Arg) Xen_is_false(Arg) ? NULL : gxg_model_func #define Xen_to_C_GtkTreeSelectionForeachFunc(Arg) Xen_is_false(Arg) ? NULL : gxg_tree_selection_func #define Xen_to_C_GtkClipboardReceivedFunc(Arg) Xen_is_false(Arg) ? NULL : gxg_clip_received #define Xen_to_C_GtkClipboardTextReceivedFunc(Arg) Xen_is_false(Arg) ? NULL : gxg_clip_text_received #define Xen_to_C_GtkClipboardTargetsReceivedFunc(Arg) Xen_is_false(Arg) ? NULL : gxg_clip_targets_received #define Xen_to_C_GtkTextCharPredicate(Arg) Xen_is_false(Arg) ? NULL : gxg_text_char_predicate #define Xen_to_C_GtkTreeViewColumnDropFunc(Arg) Xen_is_false(Arg) ? NULL : gxg_tree_column #define Xen_to_C_GtkTreeViewMappingFunc(Arg) Xen_is_false(Arg) ? NULL : gxg_tree_mapping #define Xen_to_C_GtkTreeViewSearchEqualFunc(Arg) Xen_is_false(Arg) ? NULL : gxg_tree_search #define Xen_to_C_GtkTreeCellDataFunc(Arg) Xen_is_false(Arg) ? NULL : gxg_cell_data #define Xen_to_C_GtkTreeIterCompareFunc(Arg) Xen_is_false(Arg) ? NULL : gxg_iter_compare #define Xen_to_C_GtkTreeSelectionFunc(Arg) Xen_is_false(Arg) ? NULL : gxg_tree_selection #define Xen_to_C_GtkClipboardGetFunc(Arg) Xen_is_false(Arg) ? NULL : gxg_clip_get #define Xen_to_C_GtkClipboardClearFunc(Arg) Xen_is_false(Arg) ? NULL : gxg_clip_clear #define Xen_to_C_GtkFileFilterFunc(Arg) Xen_is_false(Arg) ? NULL : gxg_file_filter #define Xen_to_C_GtkEntryCompletionMatchFunc(Arg) Xen_is_false(Arg) ? NULL : gxg_entry_completion_match #define Xen_to_C_GtkTreeViewRowSeparatorFunc(Arg) Xen_is_false(Arg) ? NULL : gxg_row_separator #define Xen_to_C_GtkIconViewForeachFunc(Arg) Xen_is_false(Arg) ? NULL : gxg_icon_view_foreach #define Xen_to_C_GtkClipboardImageReceivedFunc(Arg) Xen_is_false(Arg) ? NULL : gxg_clip_image_received #define Xen_to_C_GLogFunc(Arg) Xen_is_false(Arg) ? NULL : gxg_g_message_log_func #define Xen_to_C_GtkClipboardRichTextReceivedFunc(Arg) Xen_is_false(Arg) ? NULL : gxg_clip_rich_text_received #define Xen_to_C_GtkTreeViewSearchPositionFunc(Arg) Xen_is_false(Arg) ? NULL : gxg_search_position #define Xen_to_C_GtkAssistantPageFunc(Arg) Xen_is_false(Arg) ? NULL : gxg_page_func #define Xen_to_C_GtkRecentSortFunc(Arg) Xen_is_false(Arg) ? NULL : gxg_recent_sort #define Xen_to_C_GCallback(Arg) ((Xen_is_aritable(Arg, 4)) ? (GCallback)gxg_func4 : ((Xen_is_aritable(Arg, 3)) ? (GCallback)gxg_func3 : (GCallback)gxg_func2)) #define Xen_to_C_lambda_data(Arg) (gpointer)gxg_ptr #define Xen_is_lambda_data(Arg) 1 #define C_to_Xen_GtkTreeViewSearchPositionFunc(Arg) wrap_for_Xen(GtkTreeViewSearchPositionFunc, Arg) #define C_to_Xen_GtkTreeViewSearchEqualFunc(Arg) wrap_for_Xen(GtkTreeViewSearchEqualFunc, Arg) #define Xen_to_C_GdkFilterReturn(Arg) (GdkFilterReturn)Xen_integer_to_C_int(Arg) #define C_to_Xen_String(Arg) C_string_to_Xen_string((char *)Arg) static Xen C_to_Xen_GError_(GError *err) { if (err) { Xen msg; msg = C_string_to_Xen_string(err->message); g_error_free(err); return(msg); } return(Xen_false); } /* ---------------------------------------- types ---------------------------------------- */ Xm_type_Ptr(PangoFontDescription_, PangoFontDescription*) Xm_type_Ptr(cairo_font_options_t_, cairo_font_options_t*) Xm_type_Ptr(cairo_t_, cairo_t*) Xm_type_Ptr_2(gboolean_, gboolean*) Xm_type_Ptr(GdkEvent_, GdkEvent*) Xm_type_Ptr_2(GdkEventAny_, GdkEventAny*) Xm_type_Ptr_1(gdouble_, gdouble*) Xm_type_Ptr_1(GdkEventMotion_, GdkEventMotion*) Xm_type_Ptr(GtkAccelKey_, GtkAccelKey*) Xm_type_Ptr(GClosure_, GClosure*) Xm_type_Ptr(GtkWidget_, GtkWidget*) Xm_type_Ptr_2(GdkXEvent_, GdkXEvent*) Xm_type_Ptr(GtkMenu_, GtkMenu*) #define C_to_Xen_gint(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_gint(Arg) (gint)(Xen_integer_to_C_int(Arg)) #define Xen_is_gint(Arg) Xen_is_integer(Arg) #define C_to_Xen_gboolean(Arg) C_bool_to_Xen_boolean(Arg) #define Xen_to_C_gboolean(Arg) (gboolean)(Xen_boolean_to_C_bool(Arg)) #define Xen_is_gboolean(Arg) Xen_is_boolean(Arg) Xm_type_Ptr(GtkTextTag_, GtkTextTag*) #define C_to_Xen_gchar_(Arg) C_string_to_Xen_string(Arg) #define Xen_to_C_gchar_(Arg) (gchar*)(Xen_string_to_C_string(Arg)) #define Xen_is_gchar_(Arg) Xen_is_string(Arg) #define C_to_Xen_guint(Arg) C_ulong_to_Xen_ulong(Arg) #define Xen_to_C_guint(Arg) (guint)(Xen_ulong_to_C_ulong(Arg)) #define Xen_is_guint(Arg) Xen_is_ulong(Arg) #define C_to_Xen_GdkModifierType(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GdkModifierType(Arg) (GdkModifierType)(Xen_integer_to_C_int(Arg)) #define Xen_is_GdkModifierType(Arg) Xen_is_integer(Arg) Xm_type_Ptr(GtkTreeModel_, GtkTreeModel*) Xm_type_Ptr(GtkTreePath_, GtkTreePath*) Xm_type_Ptr(GtkTreeIter_, GtkTreeIter*) Xm_type_Ptr(GtkClipboard_, GtkClipboard*) Xm_type_Ptr(GtkSelectionData_, GtkSelectionData*) Xm_type_Ptr(GdkAtom_, GdkAtom*) #define C_to_Xen_gunichar(Arg) C_ulong_to_Xen_ulong(Arg) #define Xen_to_C_gunichar(Arg) (gunichar)(Xen_ulong_to_C_ulong(Arg)) #define Xen_is_gunichar(Arg) Xen_is_ulong(Arg) Xm_type_Ptr(GtkTreeView_, GtkTreeView*) Xm_type_Ptr(GtkTreeViewColumn_, GtkTreeViewColumn*) Xm_type_Ptr(GtkCellRenderer_, GtkCellRenderer*) Xm_type_Ptr(GtkTreeSelection_, GtkTreeSelection*) Xm_type_Ptr(GtkFileFilterInfo_, GtkFileFilterInfo*) Xm_type_Ptr(GtkEntryCompletion_, GtkEntryCompletion*) Xm_type_Ptr(GtkIconView_, GtkIconView*) Xm_type_Ptr(GdkPixbuf_, GdkPixbuf*) #define C_to_Xen_GLogLevelFlags(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GLogLevelFlags(Arg) (GLogLevelFlags)(Xen_integer_to_C_int(Arg)) #define Xen_is_GLogLevelFlags(Arg) Xen_is_integer(Arg) Xm_type(GdkAtom, GdkAtom) Xm_type_Ptr_const(guint8_, guint8*) #define C_to_Xen_gsize(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_gsize(Arg) (gsize)(Xen_integer_to_C_int(Arg)) #define Xen_is_gsize(Arg) Xen_is_integer(Arg) Xm_type_Ptr(GtkRecentInfo_, GtkRecentInfo*) #define Xen_to_C_gunichar_(Arg) (gunichar*)(Xen_string_to_C_string(Arg)) #define Xen_is_gunichar_(Arg) Xen_is_string(Arg) #define Xen_to_C_gssize(Arg) (gssize)(Xen_integer_to_C_int(Arg)) #define Xen_is_gssize(Arg) Xen_is_integer(Arg) #define C_to_Xen_glong(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GNormalizeMode(Arg) (GNormalizeMode)(Xen_integer_to_C_int(Arg)) #define Xen_is_GNormalizeMode(Arg) Xen_is_integer(Arg) Xm_type_Ptr_1(GClosureNotify, GClosureNotify) #define C_to_Xen_GType(Arg) C_ulong_to_Xen_ulong(Arg) #define Xen_to_C_GType(Arg) (GType)(Xen_ulong_to_C_ulong(Arg)) #define Xen_is_GType(Arg) Xen_is_ulong(Arg) #define Xen_to_C_GSignalFlags(Arg) (GSignalFlags)(Xen_integer_to_C_int(Arg)) #define Xen_is_GSignalFlags(Arg) Xen_is_integer(Arg) Xm_type_1(GSignalAccumulator, GSignalAccumulator) Xm_type_Ptr(gpointer, gpointer) Xm_type_1(GSignalCMarshaller, GSignalCMarshaller) Xm_type_Ptr_1(GType_, GType*) Xm_type_Ptr_1(GSignalQuery_, GSignalQuery*) Xm_type_Ptr(guint_, guint*) #define C_to_Xen_GQuark(Arg) C_ulong_to_Xen_ulong(Arg) #define Xen_to_C_GQuark(Arg) (GQuark)(Xen_ulong_to_C_ulong(Arg)) #define Xen_is_GQuark(Arg) Xen_is_ulong(Arg) Xm_type_Ptr_2(GSignalInvocationHint_, GSignalInvocationHint*) #define C_to_Xen_gulong(Arg) C_ulong_to_Xen_ulong(Arg) #define Xen_to_C_gulong(Arg) (gulong)(Xen_ulong_to_C_ulong(Arg)) #define Xen_is_gulong(Arg) Xen_is_ulong(Arg) Xm_type_1(GSignalEmissionHook, GSignalEmissionHook) #define Xen_to_C_GConnectFlags(Arg) (GConnectFlags)(Xen_integer_to_C_int(Arg)) #define Xen_is_GConnectFlags(Arg) Xen_is_integer(Arg) #define Xen_to_C_GSignalMatchType(Arg) (GSignalMatchType)(Xen_integer_to_C_int(Arg)) #define Xen_is_GSignalMatchType(Arg) Xen_is_integer(Arg) Xm_type_Ptr(GdkVisual_, GdkVisual*) Xm_type_Ptr(GdkCursor_, GdkCursor*) Xm_type_Ptr(GdkDisplay_, GdkDisplay*) #define C_to_Xen_GdkCursorType(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GdkCursorType(Arg) (GdkCursorType)(Xen_integer_to_C_int(Arg)) #define Xen_is_GdkCursorType(Arg) Xen_is_integer(Arg) Xm_type_Ptr(GdkDragContext_, GdkDragContext*) #define Xen_to_C_GdkDragAction(Arg) (GdkDragAction)(Xen_integer_to_C_int(Arg)) #define Xen_is_GdkDragAction(Arg) Xen_is_integer(Arg) #define C_to_Xen_guint32(Arg) C_ulong_to_Xen_ulong(Arg) #define Xen_to_C_guint32(Arg) (guint32)(Xen_ulong_to_C_ulong(Arg)) #define Xen_is_guint32(Arg) Xen_is_ulong(Arg) Xm_type_Ptr(GdkWindow_, GdkWindow*) Xm_type_Ptr(GList_, GList*) #define C_to_Xen_gdouble(Arg) C_double_to_Xen_real(Arg) #define Xen_to_C_gdouble(Arg) (gdouble)(Xen_real_to_C_double(Arg)) #define Xen_is_gdouble(Arg) Xen_is_number(Arg) Xm_type_Ptr(gchar__, gchar**) #define C_to_Xen_char_(Arg) C_string_to_Xen_string(Arg) #define Xen_to_C_char_(Arg) (char*)(Xen_string_to_C_string(Arg)) #define Xen_is_char_(Arg) Xen_is_string(Arg) Xm_type_Ptr_1(GdkRectangle_, GdkRectangle*) Xm_type_Ptr(GdkKeymap_, GdkKeymap*) Xm_type_Ptr(GdkKeymapKey_, GdkKeymapKey*) #define C_to_Xen_PangoDirection(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_PangoDirection(Arg) (PangoDirection)(Xen_integer_to_C_int(Arg)) #define Xen_is_PangoDirection(Arg) Xen_is_integer(Arg) Xm_type_Ptr(PangoContext_, PangoContext*) #define C_to_Xen_guchar_(Arg) C_to_Xen_String(Arg) #define Xen_to_C_guchar_(Arg) (guchar*)(Xen_string_to_C_string(Arg)) #define Xen_is_guchar_(Arg) Xen_is_string(Arg) #define Xen_to_C_GdkPropMode(Arg) (GdkPropMode)(Xen_integer_to_C_int(Arg)) #define Xen_is_GdkPropMode(Arg) Xen_is_integer(Arg) #define C_to_Xen_GdkVisualType(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GdkVisualType(Arg) (GdkVisualType)(Xen_integer_to_C_int(Arg)) #define Xen_is_GdkVisualType(Arg) Xen_is_integer(Arg) Xm_type_Ptr(gint_, gint*) Xm_type_Ptr_2(GdkVisualType_, GdkVisualType*) Xm_type_Ptr_1(GdkWindowAttr_, GdkWindowAttr*) #define C_to_Xen_GdkWindowType(Arg) C_int_to_Xen_integer(Arg) #define C_to_Xen_GdkWindowState(Arg) C_int_to_Xen_integer(Arg) #define C_to_Xen_GdkEventMask(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GdkEventMask(Arg) (GdkEventMask)(Xen_integer_to_C_int(Arg)) #define Xen_is_GdkEventMask(Arg) Xen_is_integer(Arg) #define C_to_Xen_GdkWMDecoration(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GdkWMDecoration(Arg) (GdkWMDecoration)(Xen_integer_to_C_int(Arg)) #define Xen_is_GdkWMDecoration(Arg) Xen_is_integer(Arg) #define Xen_to_C_GdkWMFunction(Arg) (GdkWMFunction)(Xen_integer_to_C_int(Arg)) #define Xen_is_GdkWMFunction(Arg) Xen_is_integer(Arg) #define Xen_to_C_GdkWindowEdge(Arg) (GdkWindowEdge)(Xen_integer_to_C_int(Arg)) #define Xen_is_GdkWindowEdge(Arg) Xen_is_integer(Arg) Xm_type_Ptr_1(GdkGeometry_, GdkGeometry*) #define Xen_to_C_GdkWindowHints(Arg) (GdkWindowHints)(Xen_integer_to_C_int(Arg)) #define Xen_is_GdkWindowHints(Arg) Xen_is_integer(Arg) #define C_to_Xen_GdkWindowTypeHint(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GdkWindowTypeHint(Arg) (GdkWindowTypeHint)(Xen_integer_to_C_int(Arg)) #define Xen_is_GdkWindowTypeHint(Arg) Xen_is_integer(Arg) #define C_to_Xen_GdkColorspace(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GdkColorspace(Arg) (GdkColorspace)(Xen_integer_to_C_int(Arg)) #define Xen_is_GdkColorspace(Arg) Xen_is_integer(Arg) #define C_to_Xen_int(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_int(Arg) (int)(Xen_integer_to_C_int(Arg)) #define Xen_is_int(Arg) Xen_is_integer(Arg) Xm_type_1(GdkPixbufDestroyNotify, GdkPixbufDestroyNotify) Xm_type_Ptr(char__, char**) #define C_to_Xen_guchar(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_guchar(Arg) (guchar)(Xen_integer_to_C_int(Arg)) #define Xen_is_guchar(Arg) Xen_is_integer(Arg) #define C_to_Xen_gfloat(Arg) C_double_to_Xen_real(Arg) #define Xen_to_C_gfloat(Arg) (gfloat)(Xen_real_to_C_double(Arg)) #define Xen_is_gfloat(Arg) Xen_is_number(Arg) #define C_to_Xen_double(Arg) C_double_to_Xen_real(Arg) #define Xen_to_C_double(Arg) (double)(Xen_real_to_C_double(Arg)) #define Xen_to_C_GdkInterpType(Arg) (GdkInterpType)(Xen_integer_to_C_int(Arg)) #define Xen_is_GdkInterpType(Arg) Xen_is_integer(Arg) Xm_type_Ptr(GdkPixbufAnimation_, GdkPixbufAnimation*) Xm_type_Ptr(GdkPixbufAnimationIter_, GdkPixbufAnimationIter*) Xm_type_Ptr_1(GTimeVal_, GTimeVal*) Xm_type_Ptr(GtkAccelGroup_, GtkAccelGroup*) #define Xen_to_C_GtkAccelFlags(Arg) (GtkAccelFlags)(Xen_integer_to_C_int(Arg)) #define Xen_is_GtkAccelFlags(Arg) Xen_is_integer(Arg) Xm_type_Ptr(GObject_, GObject*) Xm_type_Ptr(GSList_, GSList*) Xm_type_Ptr_2(GtkAccelGroupEntry_, GtkAccelGroupEntry*) Xm_type_Ptr_1(GtkAccelLabel_, GtkAccelLabel*) Xm_type_Ptr(GtkAdjustment_, GtkAdjustment*) Xm_type_Ptr_1(GtkAspectFrame_, GtkAspectFrame*) #define C_to_Xen_GtkButtonBoxStyle(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GtkButtonBoxStyle(Arg) (GtkButtonBoxStyle)(Xen_integer_to_C_int(Arg)) #define Xen_is_GtkButtonBoxStyle(Arg) Xen_is_integer(Arg) Xm_type_Ptr_1(GtkButtonBox_, GtkButtonBox*) Xm_type_Ptr(GtkBindingSet_, GtkBindingSet*) Xm_type_Ptr_1(GtkBin_, GtkBin*) Xm_type_Ptr_1(GtkBox_, GtkBox*) #define C_to_Xen_GtkPackType(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GtkPackType(Arg) (GtkPackType)(Xen_integer_to_C_int(Arg)) #define Xen_is_GtkPackType(Arg) Xen_is_integer(Arg) Xm_type_Ptr_1(GtkButton_, GtkButton*) #define C_to_Xen_GtkReliefStyle(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GtkReliefStyle(Arg) (GtkReliefStyle)(Xen_integer_to_C_int(Arg)) #define Xen_is_GtkReliefStyle(Arg) Xen_is_integer(Arg) Xm_type_Ptr_1(GtkCalendar_, GtkCalendar*) Xm_type_Ptr(GtkCellEditable_, GtkCellEditable*) #define Xen_to_C_GtkCellRendererState(Arg) (GtkCellRendererState)(Xen_integer_to_C_int(Arg)) #define Xen_is_GtkCellRendererState(Arg) Xen_is_integer(Arg) Xm_type_Ptr_1(GtkCellRendererText_, GtkCellRendererText*) Xm_type_Ptr_1(GtkCellRendererToggle_, GtkCellRendererToggle*) Xm_type_Ptr_1(GtkCheckMenuItem_, GtkCheckMenuItem*) Xm_type_Ptr(GtkTargetEntry_, GtkTargetEntry*) Xm_type_Ptr_1(GtkContainer_, GtkContainer*) Xm_type_Ptr_1(GtkDialog_, GtkDialog*) #define Xen_is_etc(Arg) (Xen_is_list(Arg)) #define Xen_to_C_GtkDestDefaults(Arg) (GtkDestDefaults)(Xen_integer_to_C_int(Arg)) #define Xen_is_GtkDestDefaults(Arg) Xen_is_integer(Arg) Xm_type_Ptr(GtkTargetList_, GtkTargetList*) Xm_type_Ptr_1(GtkEditable_, GtkEditable*) Xm_type_Ptr(GtkEntry_, GtkEntry*) Xm_type_Ptr(PangoLayout_, PangoLayout*) Xm_type_Ptr_1(GtkFixed_, GtkFixed*) Xm_type_Ptr_1(GtkFrame_, GtkFrame*) #define C_to_Xen_GtkShadowType(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GtkShadowType(Arg) (GtkShadowType)(Xen_integer_to_C_int(Arg)) #define Xen_is_GtkShadowType(Arg) Xen_is_integer(Arg) Xm_type_Ptr_1(GtkImage_, GtkImage*) #define C_to_Xen_GtkImageType(Arg) C_int_to_Xen_integer(Arg) Xm_type_Ptr(GtkIMContext_, GtkIMContext*) Xm_type_Ptr(PangoAttrList_, PangoAttrList*) Xm_type_Ptr_1(GdkEventKey_, GdkEventKey*) Xm_type_Ptr_1(GtkIMContextSimple_, GtkIMContextSimple*) Xm_type_Ptr_1(guint16_, guint16*) Xm_type_Ptr_1(GtkLabel_, GtkLabel*) #define C_to_Xen_GtkJustification(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GtkJustification(Arg) (GtkJustification)(Xen_integer_to_C_int(Arg)) #define Xen_is_GtkJustification(Arg) Xen_is_integer(Arg) Xm_type_Ptr_1(GtkLayout_, GtkLayout*) Xm_type_Ptr(GtkListStore_, GtkListStore*) Xm_type_Ptr(PangoLanguage_, PangoLanguage*) Xm_type_Ptr_1(GtkMenuItem_, GtkMenuItem*) Xm_type_Ptr_1(GtkMenuShell_, GtkMenuShell*) Xm_type_Ptr_1(GtkNotebook_, GtkNotebook*) #define C_to_Xen_GtkPositionType(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GtkPositionType(Arg) (GtkPositionType)(Xen_integer_to_C_int(Arg)) #define Xen_is_GtkPositionType(Arg) Xen_is_integer(Arg) Xm_type_Ptr_1(GtkPaned_, GtkPaned*) Xm_type_Ptr_1(GtkProgressBar_, GtkProgressBar*) Xm_type_Ptr_1(GtkRadioButton_, GtkRadioButton*) Xm_type_Ptr_1(GtkRadioMenuItem_, GtkRadioMenuItem*) Xm_type_Ptr_1(GtkRange_, GtkRange*) Xm_type_Ptr_1(GtkScale_, GtkScale*) Xm_type_Ptr_1(GtkScrolledWindow_, GtkScrolledWindow*) #define C_to_Xen_GtkPolicyType(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GtkPolicyType(Arg) (GtkPolicyType)(Xen_integer_to_C_int(Arg)) #define Xen_is_GtkPolicyType(Arg) Xen_is_integer(Arg) #define C_to_Xen_GtkCornerType(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GtkCornerType(Arg) (GtkCornerType)(Xen_integer_to_C_int(Arg)) #define Xen_is_GtkCornerType(Arg) Xen_is_integer(Arg) Xm_type_Ptr_2(GtkSettings_, GtkSettings*) Xm_type_Ptr(GtkSizeGroup_, GtkSizeGroup*) #define C_to_Xen_GtkSizeGroupMode(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GtkSizeGroupMode(Arg) (GtkSizeGroupMode)(Xen_integer_to_C_int(Arg)) #define Xen_is_GtkSizeGroupMode(Arg) Xen_is_integer(Arg) Xm_type_Ptr_1(GtkSpinButton_, GtkSpinButton*) #define C_to_Xen_GtkSpinButtonUpdatePolicy(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GtkSpinButtonUpdatePolicy(Arg) (GtkSpinButtonUpdatePolicy)(Xen_integer_to_C_int(Arg)) #define Xen_is_GtkSpinButtonUpdatePolicy(Arg) Xen_is_integer(Arg) #define Xen_to_C_GtkSpinType(Arg) (GtkSpinType)(Xen_integer_to_C_int(Arg)) #define Xen_is_GtkSpinType(Arg) Xen_is_integer(Arg) Xm_type_Ptr_1(GtkStatusbar_, GtkStatusbar*) Xm_type_Ptr(GtkTextBuffer_, GtkTextBuffer*) Xm_type_Ptr(GtkTextTagTable_, GtkTextTagTable*) Xm_type_Ptr(GtkTextIter_, GtkTextIter*) Xm_type_Ptr(GtkTextChildAnchor_, GtkTextChildAnchor*) Xm_type_Ptr(GtkTextMark_, GtkTextMark*) Xm_type_Ptr(GtkTextAttributes_, GtkTextAttributes*) #define Xen_to_C_GtkTextSearchFlags(Arg) (GtkTextSearchFlags)(Xen_integer_to_C_int(Arg)) #define Xen_is_GtkTextSearchFlags(Arg) Xen_is_integer(Arg) Xm_type_Ptr_1(GtkTextView_, GtkTextView*) #define C_to_Xen_GtkTextWindowType(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GtkTextWindowType(Arg) (GtkTextWindowType)(Xen_integer_to_C_int(Arg)) #define Xen_is_GtkTextWindowType(Arg) Xen_is_integer(Arg) #define C_to_Xen_GtkWrapMode(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GtkWrapMode(Arg) (GtkWrapMode)(Xen_integer_to_C_int(Arg)) #define Xen_is_GtkWrapMode(Arg) Xen_is_integer(Arg) Xm_type_Ptr(PangoTabArray_, PangoTabArray*) Xm_type_Ptr_1(GtkToggleButton_, GtkToggleButton*) Xm_type_Ptr_1(GtkToolbar_, GtkToolbar*) #define C_to_Xen_GtkToolbarStyle(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GtkToolbarStyle(Arg) (GtkToolbarStyle)(Xen_integer_to_C_int(Arg)) #define Xen_is_GtkToolbarStyle(Arg) Xen_is_integer(Arg) Xm_type_Ptr_1(GtkTreeDragSource_, GtkTreeDragSource*) Xm_type_Ptr_1(GtkTreeDragDest_, GtkTreeDragDest*) Xm_type_Ptr(GtkTreeRowReference_, GtkTreeRowReference*) #define C_to_Xen_GtkTreeModelFlags(Arg) C_int_to_Xen_integer(Arg) Xm_type_Ptr_1(GtkTreeModelSort_, GtkTreeModelSort*) #define C_to_Xen_GtkSelectionMode(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GtkSelectionMode(Arg) (GtkSelectionMode)(Xen_integer_to_C_int(Arg)) #define Xen_is_GtkSelectionMode(Arg) Xen_is_integer(Arg) Xm_type_Ptr_1(GtkTreeModel__, GtkTreeModel**) Xm_type_Ptr_1(GtkTreeSortable_, GtkTreeSortable*) #define C_to_Xen_GtkSortType(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GtkSortType(Arg) (GtkSortType)(Xen_integer_to_C_int(Arg)) #define Xen_is_GtkSortType(Arg) Xen_is_integer(Arg) Xm_type_Ptr(GtkTreeStore_, GtkTreeStore*) #define C_to_Xen_GtkTreeViewColumnSizing(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GtkTreeViewColumnSizing(Arg) (GtkTreeViewColumnSizing)(Xen_integer_to_C_int(Arg)) #define Xen_is_GtkTreeViewColumnSizing(Arg) Xen_is_integer(Arg) #define C_to_Xen_GtkTreeViewDropPosition(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GtkTreeViewDropPosition(Arg) (GtkTreeViewDropPosition)(Xen_integer_to_C_int(Arg)) #define Xen_is_GtkTreeViewDropPosition(Arg) Xen_is_integer(Arg) Xm_type_Ptr_1(GtkViewport_, GtkViewport*) Xm_type_Ptr_1(GtkAllocation_, GtkAllocation*) #define Xen_to_C_GtkDirectionType(Arg) (GtkDirectionType)(Xen_integer_to_C_int(Arg)) #define Xen_is_GtkDirectionType(Arg) Xen_is_integer(Arg) Xm_type_Ptr_2(AtkObject_, AtkObject*) #define C_to_Xen_GtkTextDirection(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GtkTextDirection(Arg) (GtkTextDirection)(Xen_integer_to_C_int(Arg)) #define Xen_is_GtkTextDirection(Arg) Xen_is_integer(Arg) Xm_type_Ptr(GtkWindow_, GtkWindow*) #define C_to_Xen_GtkWindowType(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GtkWindowType(Arg) (GtkWindowType)(Xen_integer_to_C_int(Arg)) #define Xen_is_GtkWindowType(Arg) Xen_is_integer(Arg) #define Xen_to_C_GtkWindowPosition(Arg) (GtkWindowPosition)(Xen_integer_to_C_int(Arg)) #define Xen_is_GtkWindowPosition(Arg) Xen_is_integer(Arg) #define C_to_Xen_GdkGravity(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GdkGravity(Arg) (GdkGravity)(Xen_integer_to_C_int(Arg)) #define Xen_is_GdkGravity(Arg) Xen_is_integer(Arg) Xm_type_Ptr(PangoColor_, PangoColor*) #define C_to_Xen_PangoAttrType(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_PangoAttrType(Arg) (PangoAttrType)(Xen_integer_to_C_int(Arg)) #define Xen_is_PangoAttrType(Arg) Xen_is_integer(Arg) Xm_type_Ptr(PangoAttribute_, PangoAttribute*) #define C_to_Xen_guint16(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_guint16(Arg) (guint16)(Xen_integer_to_C_int(Arg)) #define Xen_is_guint16(Arg) Xen_is_integer(Arg) #define C_to_Xen_PangoStyle(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_PangoStyle(Arg) (PangoStyle)(Xen_integer_to_C_int(Arg)) #define Xen_is_PangoStyle(Arg) Xen_is_integer(Arg) #define C_to_Xen_PangoWeight(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_PangoWeight(Arg) (PangoWeight)(Xen_integer_to_C_int(Arg)) #define Xen_is_PangoWeight(Arg) Xen_is_integer(Arg) #define C_to_Xen_PangoVariant(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_PangoVariant(Arg) (PangoVariant)(Xen_integer_to_C_int(Arg)) #define Xen_is_PangoVariant(Arg) Xen_is_integer(Arg) #define C_to_Xen_PangoStretch(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_PangoStretch(Arg) (PangoStretch)(Xen_integer_to_C_int(Arg)) #define Xen_is_PangoStretch(Arg) Xen_is_integer(Arg) #define Xen_to_C_PangoUnderline(Arg) (PangoUnderline)(Xen_integer_to_C_int(Arg)) #define Xen_is_PangoUnderline(Arg) Xen_is_integer(Arg) Xm_type_Ptr_1(PangoRectangle_, PangoRectangle*) Xm_type_Ptr(PangoAttrIterator_, PangoAttrIterator*) Xm_type_Ptr_1(PangoAttrList__, PangoAttrList**) Xm_type_Ptr_1(PangoAnalysis_, PangoAnalysis*) Xm_type_Ptr(PangoLogAttr_, PangoLogAttr*) Xm_type_Ptr_2(PangoFontFamily__, PangoFontFamily**) Xm_type_Ptr(PangoFont_, PangoFont*) Xm_type_Ptr_2(PangoFontset_, PangoFontset*) Xm_type_Ptr(PangoFontMetrics_, PangoFontMetrics*) Xm_type_Ptr(PangoCoverage_, PangoCoverage*) #define C_to_Xen_PangoCoverageLevel(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_PangoCoverageLevel(Arg) (PangoCoverageLevel)(Xen_integer_to_C_int(Arg)) #define Xen_is_PangoCoverageLevel(Arg) Xen_is_integer(Arg) Xm_type_Ptr_1(PangoFontDescription__, PangoFontDescription**) #define C_to_Xen_PangoFontMask(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_PangoFontMask(Arg) (PangoFontMask)(Xen_integer_to_C_int(Arg)) #define Xen_is_PangoFontMask(Arg) Xen_is_integer(Arg) Xm_type_Ptr(PangoFontFamily_, PangoFontFamily*) Xm_type_Ptr_2(PangoFontFace__, PangoFontFace**) Xm_type_Ptr(PangoFontFace_, PangoFontFace*) #define Xen_to_C_PangoGlyph(Arg) (PangoGlyph)(Xen_ulong_to_C_ulong(Arg)) #define Xen_is_PangoGlyph(Arg) Xen_is_ulong(Arg) Xm_type_Ptr(PangoFontMap_, PangoFontMap*) Xm_type_Ptr(PangoGlyphString_, PangoGlyphString*) Xm_type_Ptr(PangoItem_, PangoItem*) #define C_to_Xen_PangoWrapMode(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_PangoWrapMode(Arg) (PangoWrapMode)(Xen_integer_to_C_int(Arg)) #define Xen_is_PangoWrapMode(Arg) Xen_is_integer(Arg) #define C_to_Xen_PangoAlignment(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_PangoAlignment(Arg) (PangoAlignment)(Xen_integer_to_C_int(Arg)) #define Xen_is_PangoAlignment(Arg) Xen_is_integer(Arg) Xm_type_Ptr(int_, int*) Xm_type_Ptr(PangoLayoutLine_, PangoLayoutLine*) Xm_type_Ptr(PangoLayoutIter_, PangoLayoutIter*) Xm_type_Ptr_2(PangoLayoutRun_, PangoLayoutRun*) Xm_type_Ptr(GdkScreen_, GdkScreen*) #define C_to_Xen_GtkCalendarDisplayOptions(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GtkCalendarDisplayOptions(Arg) (GtkCalendarDisplayOptions)(Xen_integer_to_C_int(Arg)) #define Xen_is_GtkCalendarDisplayOptions(Arg) Xen_is_integer(Arg) Xm_type_Ptr_1(GtkEventBox_, GtkEventBox*) Xm_type_Ptr(GtkToolItem_, GtkToolItem*) #define C_to_Xen_GtkFileChooserAction(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GtkFileChooserAction(Arg) (GtkFileChooserAction)(Xen_integer_to_C_int(Arg)) #define Xen_is_GtkFileChooserAction(Arg) Xen_is_integer(Arg) Xm_type_Ptr_1(GtkTreeModelFilter_, GtkTreeModelFilter*) Xm_type_Ptr_1(GtkComboBox_, GtkComboBox*) Xm_type_Ptr_1(GtkExpander_, GtkExpander*) Xm_type_Ptr_1(GtkFontButton_, GtkFontButton*) Xm_type_Ptr_1(GtkRadioToolButton_, GtkRadioToolButton*) Xm_type_Ptr_1(GtkSeparatorToolItem_, GtkSeparatorToolItem*) Xm_type_Ptr_1(GtkToggleToolButton_, GtkToggleToolButton*) Xm_type_Ptr(GtkFileFilter_, GtkFileFilter*) #define C_to_Xen_GtkFileFilterFlags(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GtkFileFilterFlags(Arg) (GtkFileFilterFlags)(Xen_integer_to_C_int(Arg)) #define Xen_is_GtkFileFilterFlags(Arg) Xen_is_integer(Arg) Xm_type_Ptr_1(GtkCellLayout_, GtkCellLayout*) Xm_type_1(GtkCellLayoutDataFunc, GtkCellLayoutDataFunc) Xm_type_Ptr_1(GtkFileChooser_, GtkFileChooser*) Xm_type_Ptr(GtkIconTheme_, GtkIconTheme*) Xm_type_Ptr(GtkIconInfo_, GtkIconInfo*) #define Xen_to_C_GtkIconLookupFlags(Arg) (GtkIconLookupFlags)(Xen_integer_to_C_int(Arg)) #define Xen_is_GtkIconLookupFlags(Arg) Xen_is_integer(Arg) Xm_type_Ptr_1(GtkToolButton_, GtkToolButton*) #define C_to_Xen_GtkOrientation(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GtkOrientation(Arg) (GtkOrientation)(Xen_integer_to_C_int(Arg)) #define Xen_is_GtkOrientation(Arg) Xen_is_integer(Arg) Xm_type_Ptr_2(GtkAccelMap_, GtkAccelMap*) Xm_type_Ptr_1(GtkCellView_, GtkCellView*) Xm_type_Ptr_1(GtkAboutDialog_, GtkAboutDialog*) #define C_to_Xen_PangoEllipsizeMode(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_PangoEllipsizeMode(Arg) (PangoEllipsizeMode)(Xen_integer_to_C_int(Arg)) #define Xen_is_PangoEllipsizeMode(Arg) Xen_is_integer(Arg) Xm_type_1(PangoAttrFilterFunc, PangoAttrFilterFunc) #define C_to_Xen_PangoScript(Arg) C_int_to_Xen_integer(Arg) Xm_type_Ptr(PangoScriptIter_, PangoScriptIter*) Xm_type_Ptr_1(GtkFileChooserButton_, GtkFileChooserButton*) Xm_type_Ptr_1(GtkMenuToolButton_, GtkMenuToolButton*) Xm_type_Ptr_1(PangoRenderer_, PangoRenderer*) #define Xen_to_C_PangoRenderPart(Arg) (PangoRenderPart)(Xen_integer_to_C_int(Arg)) #define Xen_is_PangoRenderPart(Arg) Xen_is_integer(Arg) Xm_type_Ptr_1(PangoMatrix_, PangoMatrix*) Xm_type_Ptr_1(GValue_, GValue*) #define C_to_Xen_GtkIconViewDropPosition(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GtkIconViewDropPosition(Arg) (GtkIconViewDropPosition)(Xen_integer_to_C_int(Arg)) #define Xen_is_GtkIconViewDropPosition(Arg) Xen_is_integer(Arg) #define C_to_Xen_GtkPackDirection(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GtkPackDirection(Arg) (GtkPackDirection)(Xen_integer_to_C_int(Arg)) #define Xen_is_GtkPackDirection(Arg) Xen_is_integer(Arg) Xm_type_Ptr_1(GtkMenuBar_, GtkMenuBar*) #define C_to_Xen_GtkSensitivityType(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GtkSensitivityType(Arg) (GtkSensitivityType)(Xen_integer_to_C_int(Arg)) #define Xen_is_GtkSensitivityType(Arg) Xen_is_integer(Arg) Xm_type_1(GDestroyNotify, GDestroyNotify) Xm_type_Ptr_1(GtkAssistant_, GtkAssistant*) #define C_to_Xen_GtkAssistantPageType(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GtkAssistantPageType(Arg) (GtkAssistantPageType)(Xen_integer_to_C_int(Arg)) #define Xen_is_GtkAssistantPageType(Arg) Xen_is_integer(Arg) Xm_type_Ptr_1(GtkLinkButton_, GtkLinkButton*) Xm_type_Ptr_1(GtkRecentChooser_, GtkRecentChooser*) #define C_to_Xen_GtkRecentSortType(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GtkRecentSortType(Arg) (GtkRecentSortType)(Xen_integer_to_C_int(Arg)) #define Xen_is_GtkRecentSortType(Arg) Xen_is_integer(Arg) Xm_type_Ptr(GtkRecentFilter_, GtkRecentFilter*) Xm_type_Ptr(GtkRecentManager_, GtkRecentManager*) Xm_type_Ptr_1(GtkRecentChooserMenu_, GtkRecentChooserMenu*) Xm_type_no_p_2(time_t, time_t) Xm_type_1(GtkTextBufferSerializeFunc, GtkTextBufferSerializeFunc) Xm_type_1(GtkTextBufferDeserializeFunc, GtkTextBufferDeserializeFunc) Xm_type_Ptr_1(GtkRecentData_, GtkRecentData*) #define C_to_Xen_GtkTreeViewGridLines(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GtkTreeViewGridLines(Arg) (GtkTreeViewGridLines)(Xen_integer_to_C_int(Arg)) #define Xen_is_GtkTreeViewGridLines(Arg) Xen_is_integer(Arg) Xm_type_Ptr(GtkPrintContext_, GtkPrintContext*) Xm_type_Ptr(GtkPageSetup_, GtkPageSetup*) Xm_type_Ptr(GtkPrintOperation_, GtkPrintOperation*) Xm_type_Ptr(GtkPrintSettings_, GtkPrintSettings*) Xm_type_1(GtkUnit, GtkUnit) #define C_to_Xen_GtkPrintOperationResult(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GtkPrintOperationAction(Arg) (GtkPrintOperationAction)(Xen_integer_to_C_int(Arg)) #define Xen_is_GtkPrintOperationAction(Arg) Xen_is_integer(Arg) #define C_to_Xen_GtkPrintStatus(Arg) C_int_to_Xen_integer(Arg) Xm_type_1(GtkPageSetupDoneFunc, GtkPageSetupDoneFunc) Xm_type_Ptr_1(GtkPrintOperationPreview_, GtkPrintOperationPreview*) Xm_type_1(GtkPrintSettingsFunc, GtkPrintSettingsFunc) Xm_type(GtkPageOrientation, GtkPageOrientation) Xm_type_Ptr(GtkPaperSize_, GtkPaperSize*) Xm_type(GtkPrintDuplex, GtkPrintDuplex) Xm_type(GtkPrintQuality, GtkPrintQuality) Xm_type(GtkPrintPages, GtkPrintPages) Xm_type_Ptr(GtkPageRange_, GtkPageRange*) Xm_type(GtkPageSet, GtkPageSet) Xm_type_Ptr_1(GtkTooltip_, GtkTooltip*) #if GTK_CHECK_VERSION(2, 14, 0) Xm_type_1(GtkCalendarDetailFunc, GtkCalendarDetailFunc) Xm_type_Ptr_1(GtkScaleButton_, GtkScaleButton*) Xm_type_Ptr(GFile_, GFile*) #endif #if GTK_CHECK_VERSION(2, 16, 0) #define Xen_to_C_GtkEntryIconPosition(Arg) (GtkEntryIconPosition)(Xen_integer_to_C_int(Arg)) #define Xen_is_GtkEntryIconPosition(Arg) Xen_is_integer(Arg) Xm_type_Ptr(GIcon_, GIcon*) #endif #if GTK_CHECK_VERSION(2, 18, 0) Xm_type_Ptr_1(GtkInfoBar_, GtkInfoBar*) #define C_to_Xen_GtkMessageType(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GtkMessageType(Arg) (GtkMessageType)(Xen_integer_to_C_int(Arg)) #define Xen_is_GtkMessageType(Arg) Xen_is_integer(Arg) Xm_type_Ptr(GtkEntryBuffer_, GtkEntryBuffer*) #endif #if GTK_CHECK_VERSION(2, 20, 0) Xm_type_Ptr_1(GtkSpinner_, GtkSpinner*) Xm_type_Ptr_1(GtkToolPalette_, GtkToolPalette*) Xm_type_Ptr(GtkToolItemGroup_, GtkToolItemGroup*) #define Xen_to_C_GtkToolPaletteDragTargets(Arg) (GtkToolPaletteDragTargets)(Xen_integer_to_C_int(Arg)) #define Xen_is_GtkToolPaletteDragTargets(Arg) Xen_is_integer(Arg) #endif #if GTK_CHECK_VERSION(3, 0, 0) Xm_type_Ptr_1(GdkModifierType_, GdkModifierType*) Xm_type_Ptr_1(GtkAccessible_, GtkAccessible*) Xm_type_Ptr_2(GdkDeviceManager_, GdkDeviceManager*) Xm_type_Ptr(GdkDevice_, GdkDevice*) Xm_type_Ptr_1(GtkMessageDialog_, GtkMessageDialog*) Xm_type_Ptr(cairo_region_t_, cairo_region_t*) #define C_to_Xen_GtkSizeRequestMode(Arg) C_int_to_Xen_integer(Arg) Xm_type_Ptr_1(GtkContainerClass_, GtkContainerClass*) #define C_to_Xen_GtkAlign(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GtkAlign(Arg) (GtkAlign)(Xen_integer_to_C_int(Arg)) #define Xen_is_GtkAlign(Arg) Xen_is_integer(Arg) Xm_type_Ptr_1(GtkComboBoxText_, GtkComboBoxText*) Xm_type_Ptr(GdkRGBA_, GdkRGBA*) Xm_type_Ptr_1(GtkGrid_, GtkGrid*) Xm_type_Ptr_1(GtkScrollable_, GtkScrollable*) #define C_to_Xen_GtkScrollablePolicy(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GtkScrollablePolicy(Arg) (GtkScrollablePolicy)(Xen_integer_to_C_int(Arg)) #define Xen_is_GtkScrollablePolicy(Arg) Xen_is_integer(Arg) Xm_type_Ptr_1(GtkSwitch_, GtkSwitch*) Xm_type_Ptr(GtkBorder_, GtkBorder*) Xm_type_Ptr_1(GtkCellArea_, GtkCellArea*) Xm_type_Ptr_1(GtkOrientable_, GtkOrientable*) Xm_type_Ptr_1(GtkInvisible_, GtkInvisible*) Xm_type_Ptr(GtkWindowGroup_, GtkWindowGroup*) Xm_type_Ptr_1(GtkToolShell_, GtkToolShell*) Xm_type_Ptr_1(GdkScreen__, GdkScreen**) #define C_to_Xen_GtkStateFlags(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GtkStateFlags(Arg) (GtkStateFlags)(Xen_integer_to_C_int(Arg)) #define Xen_is_GtkStateFlags(Arg) Xen_is_integer(Arg) #endif #if GTK_CHECK_VERSION(3, 2, 0) Xm_type_Ptr_1(GtkWidgetPath_, GtkWidgetPath*) Xm_type_Ptr_1(GtkOverlay_, GtkOverlay*) #define C_to_Xen_GdkScrollDirection(Arg) C_int_to_Xen_integer(Arg) Xm_type_Ptr_1(GtkFontChooser_, GtkFontChooser*) #endif #if GTK_CHECK_VERSION(3, 4, 0) #define Xen_to_C_GdkModifierIntent(Arg) (GdkModifierIntent)(Xen_integer_to_C_int(Arg)) #define Xen_is_GdkModifierIntent(Arg) Xen_is_integer(Arg) Xm_type_Ptr_1(guint__, guint**) Xm_type_Ptr(GMenuModel_, GMenuModel*) Xm_type_Ptr_1(GtkApplication_, GtkApplication*) Xm_type_Ptr_1(GtkApplicationWindow_, GtkApplicationWindow*) Xm_type_Ptr_1(GtkColorChooser_, GtkColorChooser*) #endif #if GTK_CHECK_VERSION(3, 6, 0) Xm_type_Ptr_1(GtkMenuButton_, GtkMenuButton*) Xm_type_Ptr_1(GtkLevelBar_, GtkLevelBar*) #define C_to_Xen_GtkLevelBarMode(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GtkLevelBarMode(Arg) (GtkLevelBarMode)(Xen_integer_to_C_int(Arg)) #define Xen_is_GtkLevelBarMode(Arg) Xen_is_integer(Arg) #define C_to_Xen_GtkInputPurpose(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GtkInputPurpose(Arg) (GtkInputPurpose)(Xen_integer_to_C_int(Arg)) #define Xen_is_GtkInputPurpose(Arg) Xen_is_integer(Arg) #define C_to_Xen_GtkInputHints(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GtkInputHints(Arg) (GtkInputHints)(Xen_integer_to_C_int(Arg)) #define Xen_is_GtkInputHints(Arg) Xen_is_integer(Arg) #endif #if GTK_CHECK_VERSION(3, 8, 0) #define C_to_Xen_GdkFullscreenMode(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GdkFullscreenMode(Arg) (GdkFullscreenMode)(Xen_integer_to_C_int(Arg)) #define Xen_is_GdkFullscreenMode(Arg) Xen_is_integer(Arg) #endif #if GTK_CHECK_VERSION(3, 10, 0) #define C_to_Xen_GtkBaselinePosition(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GtkBaselinePosition(Arg) (GtkBaselinePosition)(Xen_integer_to_C_int(Arg)) #define Xen_is_GtkBaselinePosition(Arg) Xen_is_integer(Arg) #define C_to_Xen_GtkPlacesOpenFlags(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GtkPlacesOpenFlags(Arg) (GtkPlacesOpenFlags)(Xen_integer_to_C_int(Arg)) #define Xen_is_GtkPlacesOpenFlags(Arg) Xen_is_integer(Arg) Xm_type_Ptr_1(GtkPlacesSidebar_, GtkPlacesSidebar*) Xm_type_Ptr_1(GtkStackSwitcher_, GtkStackSwitcher*) Xm_type_Ptr(GtkStack_, GtkStack*) #define C_to_Xen_GtkStackTransitionType(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GtkStackTransitionType(Arg) (GtkStackTransitionType)(Xen_integer_to_C_int(Arg)) #define Xen_is_GtkStackTransitionType(Arg) Xen_is_integer(Arg) Xm_type_Ptr_1(GtkRevealer_, GtkRevealer*) #define C_to_Xen_GtkRevealerTransitionType(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_GtkRevealerTransitionType(Arg) (GtkRevealerTransitionType)(Xen_integer_to_C_int(Arg)) #define Xen_is_GtkRevealerTransitionType(Arg) Xen_is_integer(Arg) Xm_type_Ptr_1(GtkHeaderBar_, GtkHeaderBar*) Xm_type_Ptr(GtkListBoxRow_, GtkListBoxRow*) Xm_type_Ptr_1(GtkListBox_, GtkListBox*) Xm_type_Ptr_1(GtkSearchBar_, GtkSearchBar*) #define C_to_Xen_GdkEventType(Arg) C_int_to_Xen_integer(Arg) #endif #if GTK_CHECK_VERSION(3, 12, 0) Xm_type_Ptr(GtkFlowBoxChild_, GtkFlowBoxChild*) Xm_type_Ptr_1(GtkFlowBox_, GtkFlowBox*) Xm_type_Ptr_1(GtkActionBar_, GtkActionBar*) Xm_type_Ptr_1(GtkPopover_, GtkPopover*) #endif #if GTK_CHECK_VERSION(3, 14, 0) Xm_type_Ptr(GtkGesture_, GtkGesture*) Xm_type(GtkEventSequenceState, GtkEventSequenceState) Xm_type_Ptr(GdkEventSequence_, GdkEventSequence*) Xm_type_Ptr_1(GtkGestureDrag_, GtkGestureDrag*) Xm_type_Ptr_1(GtkGesturePan_, GtkGesturePan*) Xm_type_Ptr_1(GtkGestureMultiPress_, GtkGestureMultiPress*) Xm_type_Ptr_1(GtkGestureRotate_, GtkGestureRotate*) Xm_type_Ptr_1(GtkGestureSingle_, GtkGestureSingle*) Xm_type_Ptr_1(GtkGestureSwipe_, GtkGestureSwipe*) Xm_type_Ptr_1(GtkGestureZoom_, GtkGestureZoom*) Xm_type_Ptr_1(GtkEventController_, GtkEventController*) Xm_type(GtkPropagationPhase, GtkPropagationPhase) #endif #if GTK_CHECK_VERSION(3, 16, 0) Xm_type_Ptr_1(GtkGLArea_, GtkGLArea*) Xm_type_Ptr(GdkGLContext_, GdkGLContext*) Xm_type_Ptr_1(GtkStyleContext_, GtkStyleContext*) Xm_type_Ptr_1(GtkPopoverMenu_, GtkPopoverMenu*) Xm_type_Ptr_1(GtkSearchEntry_, GtkSearchEntry*) Xm_type_Ptr_1(GtkStackSidebar_, GtkStackSidebar*) #endif #if GTK_CHECK_VERSION(3, 20, 0) Xm_type_Ptr(GtkShortcutsWindow_, GtkShortcutsWindow*) Xm_type(GtkAllocation, GtkAllocation) #endif Xm_type_Ptr(cairo_surface_t_, cairo_surface_t*) #define C_to_Xen_cairo_content_t(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_cairo_content_t(Arg) (cairo_content_t)(Xen_integer_to_C_int(Arg)) #define Xen_is_cairo_content_t(Arg) Xen_is_integer(Arg) Xm_type_Ptr(cairo_pattern_t_, cairo_pattern_t*) #define C_to_Xen_cairo_operator_t(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_cairo_operator_t(Arg) (cairo_operator_t)(Xen_integer_to_C_int(Arg)) #define Xen_is_cairo_operator_t(Arg) Xen_is_integer(Arg) #define C_to_Xen_cairo_antialias_t(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_cairo_antialias_t(Arg) (cairo_antialias_t)(Xen_integer_to_C_int(Arg)) #define Xen_is_cairo_antialias_t(Arg) Xen_is_integer(Arg) #define C_to_Xen_cairo_fill_rule_t(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_cairo_fill_rule_t(Arg) (cairo_fill_rule_t)(Xen_integer_to_C_int(Arg)) #define Xen_is_cairo_fill_rule_t(Arg) Xen_is_integer(Arg) #define C_to_Xen_cairo_line_cap_t(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_cairo_line_cap_t(Arg) (cairo_line_cap_t)(Xen_integer_to_C_int(Arg)) #define Xen_is_cairo_line_cap_t(Arg) Xen_is_integer(Arg) #define C_to_Xen_cairo_line_join_t(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_cairo_line_join_t(Arg) (cairo_line_join_t)(Xen_integer_to_C_int(Arg)) #define Xen_is_cairo_line_join_t(Arg) Xen_is_integer(Arg) Xm_type_Ptr_1(cairo_matrix_t_, cairo_matrix_t*) #define C_to_Xen_bool(Arg) C_bool_to_Xen_boolean(Arg) #define Xen_to_C_bool(Arg) (bool)(Xen_boolean_to_C_bool(Arg)) #define Xen_is_bool(Arg) Xen_is_boolean(Arg) #define C_to_Xen_cairo_status_t(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_cairo_status_t(Arg) (cairo_status_t)(Xen_integer_to_C_int(Arg)) #define Xen_is_cairo_status_t(Arg) Xen_is_integer(Arg) #define C_to_Xen_cairo_subpixel_order_t(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_cairo_subpixel_order_t(Arg) (cairo_subpixel_order_t)(Xen_integer_to_C_int(Arg)) #define Xen_is_cairo_subpixel_order_t(Arg) Xen_is_integer(Arg) #define C_to_Xen_cairo_hint_style_t(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_cairo_hint_style_t(Arg) (cairo_hint_style_t)(Xen_integer_to_C_int(Arg)) #define Xen_is_cairo_hint_style_t(Arg) Xen_is_integer(Arg) #define C_to_Xen_cairo_hint_metrics_t(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_cairo_hint_metrics_t(Arg) (cairo_hint_metrics_t)(Xen_integer_to_C_int(Arg)) #define Xen_is_cairo_hint_metrics_t(Arg) Xen_is_integer(Arg) #define C_to_Xen_cairo_font_slant_t(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_cairo_font_slant_t(Arg) (cairo_font_slant_t)(Xen_integer_to_C_int(Arg)) #define Xen_is_cairo_font_slant_t(Arg) Xen_is_integer(Arg) #define C_to_Xen_cairo_font_weight_t(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_cairo_font_weight_t(Arg) (cairo_font_weight_t)(Xen_integer_to_C_int(Arg)) #define Xen_is_cairo_font_weight_t(Arg) Xen_is_integer(Arg) Xm_type_Ptr(cairo_scaled_font_t_, cairo_scaled_font_t*) Xm_type_Ptr(cairo_glyph_t_, cairo_glyph_t*) Xm_type_Ptr(cairo_font_face_t_, cairo_font_face_t*) Xm_type_Ptr_1(cairo_font_extents_t_, cairo_font_extents_t*) Xm_type_Ptr_1(cairo_text_extents_t_, cairo_text_extents_t*) Xm_type_Ptr_1(cairo_user_data_key_t_, cairo_user_data_key_t*) Xm_type_1(cairo_destroy_func_t, cairo_destroy_func_t) Xm_type_Ptr(cairo_path_t_, cairo_path_t*) #define C_to_Xen_cairo_format_t(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_cairo_format_t(Arg) (cairo_format_t)(Xen_integer_to_C_int(Arg)) #define Xen_is_cairo_format_t(Arg) Xen_is_integer(Arg) #define C_to_Xen_cairo_extend_t(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_cairo_extend_t(Arg) (cairo_extend_t)(Xen_integer_to_C_int(Arg)) #define Xen_is_cairo_extend_t(Arg) Xen_is_integer(Arg) #define C_to_Xen_cairo_filter_t(Arg) C_int_to_Xen_integer(Arg) #define Xen_to_C_cairo_filter_t(Arg) (cairo_filter_t)(Xen_integer_to_C_int(Arg)) #define Xen_is_cairo_filter_t(Arg) Xen_is_integer(Arg) Xm_type_Ptr(void_, void*) Xm_type_Ptr(cairo_rectangle_list_t_, cairo_rectangle_list_t*) #if HAVE_CAIRO_1_8 Xm_type_Ptr(cairo_text_cluster_t_, cairo_text_cluster_t*) Xm_type_1(cairo_text_cluster_flags_t, cairo_text_cluster_flags_t) Xm_type_Ptr_1(cairo_glyph_t__, cairo_glyph_t**) Xm_type_Ptr_1(cairo_text_cluster_t__, cairo_text_cluster_t**) Xm_type_Ptr_1(cairo_text_cluster_flags_t_, cairo_text_cluster_flags_t*) #define C_to_Xen_cairo_bool_t(Arg) C_int_to_Xen_integer(Arg) #endif #if HAVE_CAIRO_1_9_12 && GTK_CHECK_VERSION(3, 0, 0) Xm_type_Ptr(cairo_device_t_, cairo_device_t*) Xm_type_Ptr_1(cairo_rectangle_t_, cairo_rectangle_t*) Xm_type_Ptr_1(double_, double*) Xm_type_Ptr_1(cairo_rectangle_int_t_, cairo_rectangle_int_t*) Xm_type_no_p_2(cairo_region_overlap_t, cairo_region_overlap_t) #endif #define XLS(a, b) Xen_to_C_gchar_(Xen_list_ref(a, b)) #define XLI(a, b) ((int)Xen_integer_to_C_int(Xen_list_ref(a, b))) #define XLL(a, b) (Xen_llong_to_C_llong(Xen_list_ref(a, b))) #define XLG(a, b) Xen_to_C_GType(Xen_list_ref(a, b)) #define XLT(a, b) Xen_to_C_GtkTextTag_(Xen_list_ref(a, b)) #define XLA(a, b) ((Xen_is_integer(Xen_list_ref(a, b))) ? ((gpointer)XLL(a, b)) : ((Xen_is_string(Xen_list_ref(a, b))) ? ((gpointer)XLS(a, b)) : ((gpointer)XLG(a, b)))) /* -------------------------------- gc protection -------------------------------- */ static Xen xm_protected; static int xm_protected_size = 0; static Xen xm_gc_table; static int last_xm_unprotect = NOT_A_GC_LOC; static int xm_protect(Xen obj) { int i, new_size; Xen new_table; if (last_xm_unprotect >= 0) { i = last_xm_unprotect; if (Xen_is_false(Xen_vector_ref(xm_protected, i))) { Xen_vector_set(xm_protected, i, obj); last_xm_unprotect = NOT_A_GC_LOC; return(i); } last_xm_unprotect = NOT_A_GC_LOC; } for (i = 0; i < xm_protected_size; i++) if (Xen_is_false(Xen_vector_ref(xm_protected, i))) { Xen_vector_set(xm_protected, i, obj); return(i); } new_size = xm_protected_size * 2; new_table = Xen_make_vector(new_size, Xen_false); for (i = 0; i < xm_protected_size; i++) { Xen_vector_set(new_table, i, Xen_vector_ref(xm_protected, i)); Xen_vector_set(xm_protected, i, Xen_false); } Xen_vector_set(new_table, xm_protected_size, obj); Xen_vector_set(xm_gc_table, 0, new_table); i = xm_protected_size; xm_protected_size = new_size; xm_protected = new_table; return(i); } static void xm_unprotect_at(int ind) { Xen_vector_set(xm_protected, ind, Xen_false); last_xm_unprotect = ind; } /* ---------------------------------------- callback handlers ---------------------------------------- */ static gboolean gxg_find_func(GtkAccelKey* key, GClosure* closure, gpointer func_info) { if (!Xen_is_list((Xen)func_info)) return((gboolean)0); return(Xen_to_C_gboolean(Xen_call_with_3_args(Xen_car((Xen)func_info), C_to_Xen_GtkAccelKey_(key), C_to_Xen_GClosure_(closure), Xen_cadr((Xen)func_info), __func__))); } static void gxg_func2(GtkWidget* w, gpointer func_info) { if (!Xen_is_list((Xen)func_info)) return; Xen_call_with_2_args(Xen_car((Xen)func_info), C_to_Xen_GtkWidget_(w), Xen_cadr((Xen)func_info), __func__); } static gboolean gxg_timer_func(gpointer func_info) { if (!Xen_is_list((Xen)func_info)) return((gboolean)0); return(Xen_to_C_gboolean(Xen_call_with_1_arg(Xen_car((Xen)func_info), Xen_cadr((Xen)func_info), __func__))); } static void gxg_destroy_func(gpointer func_info) { if (!Xen_is_list((Xen)func_info)) return; Xen_call_with_1_arg(Xen_cadddr((Xen)func_info), Xen_cadr((Xen)func_info), __func__); } static GdkFilterReturn gxg_filter_func(GdkXEvent* xevent, GdkEvent* event, gpointer func_info) { if (!Xen_is_list((Xen)func_info)) return((GdkFilterReturn)0); return(Xen_to_C_GdkFilterReturn(Xen_call_with_3_args(Xen_car((Xen)func_info), C_to_Xen_GdkXEvent_(xevent), C_to_Xen_GdkEvent_(event), Xen_cadr((Xen)func_info), __func__))); } static void gxg_event_func(GdkEvent* event, gpointer func_info) { if (!Xen_is_list((Xen)func_info)) return; Xen_call_with_2_args(Xen_car((Xen)func_info), C_to_Xen_GdkEvent_(event), Xen_cadr((Xen)func_info), __func__); } static void gxg_menu_position_func(GtkMenu* menu, gint* x, gint* y, gboolean* push, gpointer func_info) { if (!Xen_is_list((Xen)func_info)) return; Xen_call_with_5_args(Xen_car((Xen)func_info), C_to_Xen_GtkMenu_(menu), C_to_Xen_gint_(x), C_to_Xen_gint_(y), C_to_Xen_gboolean_(push), Xen_cadr((Xen)func_info), __func__); } static void gxg_text_tag_table_foreach(GtkTextTag* tag, gpointer func_info) { if (!Xen_is_list((Xen)func_info)) return; Xen_call_with_2_args(Xen_car((Xen)func_info), C_to_Xen_GtkTextTag_(tag), Xen_cadr((Xen)func_info), __func__); } static void gxg_accel_map_foreach(gpointer func_info, const gchar* accel_path, guint accel_key, GdkModifierType accel_mods, gboolean changed) { if (!Xen_is_list((Xen)func_info)) return; Xen_call_with_5_args(Xen_car((Xen)func_info), Xen_cadr((Xen)func_info), C_to_Xen_gchar_(accel_path), C_to_Xen_guint(accel_key), C_to_Xen_GdkModifierType(accel_mods), C_to_Xen_gboolean(changed), __func__); } static gboolean gxg_model_func(GtkTreeModel* model, GtkTreePath* path, GtkTreeIter* iter, gpointer func_info) { if (!Xen_is_list((Xen)func_info)) return((gboolean)0); return(Xen_to_C_gboolean(Xen_call_with_4_args(Xen_car((Xen)func_info), C_to_Xen_GtkTreeModel_(model), C_to_Xen_GtkTreePath_(path), C_to_Xen_GtkTreeIter_(iter), Xen_cadr((Xen)func_info), __func__))); } static void gxg_tree_selection_func(GtkTreeModel* model, GtkTreePath* path, GtkTreeIter* iter, gpointer func_info) { if (!Xen_is_list((Xen)func_info)) return; Xen_call_with_4_args(Xen_car((Xen)func_info), C_to_Xen_GtkTreeModel_(model), C_to_Xen_GtkTreePath_(path), C_to_Xen_GtkTreeIter_(iter), Xen_cadr((Xen)func_info), __func__); } static void gxg_clip_received(GtkClipboard* clipboard, GtkSelectionData* selection_data, gpointer func_info) { if (!Xen_is_list((Xen)func_info)) return; Xen_call_with_3_args(Xen_car((Xen)func_info), C_to_Xen_GtkClipboard_(clipboard), C_to_Xen_GtkSelectionData_(selection_data), Xen_cadr((Xen)func_info), __func__); } static void gxg_clip_text_received(GtkClipboard* clipboard, const gchar* text, gpointer func_info) { if (!Xen_is_list((Xen)func_info)) return; Xen_call_with_3_args(Xen_car((Xen)func_info), C_to_Xen_GtkClipboard_(clipboard), C_to_Xen_gchar_(text), Xen_cadr((Xen)func_info), __func__); } static void gxg_clip_targets_received(GtkClipboard* clipboard, GdkAtom* atoms, gint n_atoms, gpointer func_info) { if (!Xen_is_list((Xen)func_info)) return; Xen_call_with_4_args(Xen_car((Xen)func_info), C_to_Xen_GtkClipboard_(clipboard), C_to_Xen_GdkAtom_(atoms), C_to_Xen_gint(n_atoms), Xen_cadr((Xen)func_info), __func__); } static gboolean gxg_text_char_predicate(gunichar ch, gpointer func_info) { if (!Xen_is_list((Xen)func_info)) return((gboolean)0); return(Xen_to_C_gboolean(Xen_call_with_2_args(Xen_car((Xen)func_info), C_to_Xen_gunichar(ch), Xen_cadr((Xen)func_info), __func__))); } static gboolean gxg_tree_column(GtkTreeView* tree_view, GtkTreeViewColumn* column, GtkTreeViewColumn* prev_column, GtkTreeViewColumn* next_column, gpointer func_info) { if (!Xen_is_list((Xen)func_info)) return((gboolean)0); return(Xen_to_C_gboolean(Xen_call_with_5_args(Xen_car((Xen)func_info), C_to_Xen_GtkTreeView_(tree_view), C_to_Xen_GtkTreeViewColumn_(column), C_to_Xen_GtkTreeViewColumn_(prev_column), C_to_Xen_GtkTreeViewColumn_(next_column), Xen_cadr((Xen)func_info), __func__))); } static void gxg_tree_mapping(GtkTreeView* tree_view, GtkTreePath* path, gpointer func_info) { if (!Xen_is_list((Xen)func_info)) return; Xen_call_with_3_args(Xen_car((Xen)func_info), C_to_Xen_GtkTreeView_(tree_view), C_to_Xen_GtkTreePath_(path), Xen_cadr((Xen)func_info), __func__); } static gboolean gxg_tree_search(GtkTreeModel* model, gint column, const gchar* key, GtkTreeIter* iter, gpointer func_info) { if (!Xen_is_list((Xen)func_info)) return((gboolean)0); return(Xen_to_C_gboolean(Xen_call_with_5_args(Xen_car((Xen)func_info), C_to_Xen_GtkTreeModel_(model), C_to_Xen_gint(column), C_to_Xen_gchar_(key), C_to_Xen_GtkTreeIter_(iter), Xen_cadr((Xen)func_info), __func__))); } static void gxg_cell_data(GtkTreeViewColumn* tree_column, GtkCellRenderer* cell, GtkTreeModel* tree_model, GtkTreeIter* iter, gpointer func_info) { if (!Xen_is_list((Xen)func_info)) return; Xen_call_with_5_args(Xen_car((Xen)func_info), C_to_Xen_GtkTreeViewColumn_(tree_column), C_to_Xen_GtkCellRenderer_(cell), C_to_Xen_GtkTreeModel_(tree_model), C_to_Xen_GtkTreeIter_(iter), Xen_cadr((Xen)func_info), __func__); } static gint gxg_iter_compare(GtkTreeModel* model, GtkTreeIter* a, GtkTreeIter* b, gpointer func_info) { if (!Xen_is_list((Xen)func_info)) return((gint)0); return(Xen_to_C_gint(Xen_call_with_4_args(Xen_car((Xen)func_info), C_to_Xen_GtkTreeModel_(model), C_to_Xen_GtkTreeIter_(a), C_to_Xen_GtkTreeIter_(b), Xen_cadr((Xen)func_info), __func__))); } static gboolean gxg_tree_selection(GtkTreeSelection* selection, GtkTreeModel* model, GtkTreePath* path, gboolean path_currently_selected, gpointer func_info) { if (!Xen_is_list((Xen)func_info)) return((gboolean)0); return(Xen_to_C_gboolean(Xen_call_with_5_args(Xen_car((Xen)func_info), C_to_Xen_GtkTreeSelection_(selection), C_to_Xen_GtkTreeModel_(model), C_to_Xen_GtkTreePath_(path), C_to_Xen_gboolean(path_currently_selected), Xen_cadr((Xen)func_info), __func__))); } static void gxg_clip_get(GtkClipboard* clipboard, GtkSelectionData* selection_data, guint info, gpointer func_info) { if (!Xen_is_list((Xen)func_info)) return; Xen_call_with_4_args(Xen_car((Xen)func_info), C_to_Xen_GtkClipboard_(clipboard), C_to_Xen_GtkSelectionData_(selection_data), C_to_Xen_guint(info), Xen_cadr((Xen)func_info), __func__); } static void gxg_clip_clear(GtkClipboard* clipboard, gpointer func_info) { if (!Xen_is_list((Xen)func_info)) return; Xen_call_with_2_args(Xen_caddr((Xen)func_info), C_to_Xen_GtkClipboard_(clipboard), Xen_cadr((Xen)func_info), __func__); } static gboolean gxg_file_filter(const GtkFileFilterInfo* info, gpointer func_info) { if (!Xen_is_list((Xen)func_info)) return((gboolean)0); return(Xen_to_C_gboolean(Xen_call_with_2_args(Xen_car((Xen)func_info), C_to_Xen_GtkFileFilterInfo_((GtkFileFilterInfo *)info), Xen_cadr((Xen)func_info), __func__))); } static gboolean gxg_entry_completion_match(GtkEntryCompletion* completion, const gchar* key, GtkTreeIter* iter, gpointer func_info) { if (!Xen_is_list((Xen)func_info)) return((gboolean)0); return(Xen_to_C_gboolean(Xen_call_with_4_args(Xen_car((Xen)func_info), C_to_Xen_GtkEntryCompletion_(completion), C_to_Xen_gchar_(key), C_to_Xen_GtkTreeIter_(iter), Xen_cadr((Xen)func_info), __func__))); } static gboolean gxg_row_separator(GtkTreeModel* model, GtkTreeIter* iter, gpointer func_info) { if (!Xen_is_list((Xen)func_info)) return((gboolean)0); return(Xen_to_C_gboolean(Xen_call_with_3_args(Xen_car((Xen)func_info), C_to_Xen_GtkTreeModel_(model), C_to_Xen_GtkTreeIter_(iter), Xen_cadr((Xen)func_info), __func__))); } static void gxg_icon_view_foreach(GtkIconView* icon_view, GtkTreePath* path, gpointer func_info) { if (!Xen_is_list((Xen)func_info)) return; Xen_call_with_3_args(Xen_car((Xen)func_info), C_to_Xen_GtkIconView_(icon_view), C_to_Xen_GtkTreePath_(path), Xen_cadr((Xen)func_info), __func__); } static void gxg_clip_image_received(GtkClipboard* clipboard, GdkPixbuf* pixbuf, gpointer func_info) { if (!Xen_is_list((Xen)func_info)) return; Xen_call_with_3_args(Xen_car((Xen)func_info), C_to_Xen_GtkClipboard_(clipboard), C_to_Xen_GdkPixbuf_(pixbuf), Xen_cadr((Xen)func_info), __func__); } static void gxg_g_message_log_func(const gchar* domain, GLogLevelFlags log_level, const gchar* message, gpointer func_info) { if (!Xen_is_list((Xen)func_info)) return; Xen_call_with_4_args(Xen_car((Xen)func_info), C_to_Xen_gchar_(domain), C_to_Xen_GLogLevelFlags(log_level), C_to_Xen_gchar_(message), Xen_cadr((Xen)func_info), __func__); } static void gxg_clip_rich_text_received(GtkClipboard* clipboard, GdkAtom format, const guint8* text, gsize length, gpointer func_info) { if (!Xen_is_list((Xen)func_info)) return; #if (!(defined(__cplusplus))) Xen_call_with_5_args(Xen_car((Xen)func_info), C_to_Xen_GtkClipboard_(clipboard), C_to_Xen_GdkAtom(format), C_to_Xen_guint8_(text), C_to_Xen_gsize(length), Xen_cadr((Xen)func_info), __func__); #endif } static void gxg_search_position(GtkTreeView* tree_view, GtkWidget* search_dialog, gpointer func_info) { if (!Xen_is_list((Xen)func_info)) return; Xen_call_with_3_args(Xen_car((Xen)func_info), C_to_Xen_GtkTreeView_(tree_view), C_to_Xen_GtkWidget_(search_dialog), Xen_cadr((Xen)func_info), __func__); } static gint gxg_page_func(gint current_page, gpointer func_info) { if (!Xen_is_list((Xen)func_info)) return((gint)0); return(Xen_to_C_gint(Xen_call_with_2_args(Xen_car((Xen)func_info), C_to_Xen_gint(current_page), Xen_cadr((Xen)func_info), __func__))); } static gint gxg_recent_sort(GtkRecentInfo* a, GtkRecentInfo* b, gpointer func_info) { if (!Xen_is_list((Xen)func_info)) return((gint)0); return(Xen_to_C_gint(Xen_call_with_3_args(Xen_car((Xen)func_info), C_to_Xen_GtkRecentInfo_(a), C_to_Xen_GtkRecentInfo_(b), Xen_cadr((Xen)func_info), __func__))); } static gboolean gxg_func3(GtkWidget *w, GdkEventAny *ev, gpointer data) { return(Xen_boolean_to_C_bool(Xen_call_with_3_args(Xen_car((Xen)data), C_to_Xen_GtkWidget_(w), C_to_Xen_GdkEventAny_(ev), Xen_cadr((Xen)data), __func__))); } static gboolean gxg_func4(GtkPrintOperation *op, GtkPrintContext *context, gint page_nr, gpointer data) { return(Xen_boolean_to_C_bool(Xen_call_with_4_args(Xen_car((Xen)data), C_to_Xen_GtkPrintOperation_(op), C_to_Xen_GtkPrintContext_(context), C_int_to_Xen_integer(page_nr), Xen_cadr((Xen)data), __func__))); } /* ---------------------------------------- functions ---------------------------------------- */ static Xen gxg_g_unichar_validate(Xen ch) { #define H_g_unichar_validate "gboolean g_unichar_validate(gunichar ch)" Xen_check_type(Xen_is_gunichar(ch), ch, 1, "g_unichar_validate", "gunichar"); return(C_to_Xen_gboolean(g_unichar_validate(Xen_to_C_gunichar(ch)))); } static Xen gxg_g_unichar_isalnum(Xen c) { #define H_g_unichar_isalnum "gboolean g_unichar_isalnum(gunichar c)" Xen_check_type(Xen_is_gunichar(c), c, 1, "g_unichar_isalnum", "gunichar"); return(C_to_Xen_gboolean(g_unichar_isalnum(Xen_to_C_gunichar(c)))); } static Xen gxg_g_unichar_isalpha(Xen c) { #define H_g_unichar_isalpha "gboolean g_unichar_isalpha(gunichar c)" Xen_check_type(Xen_is_gunichar(c), c, 1, "g_unichar_isalpha", "gunichar"); return(C_to_Xen_gboolean(g_unichar_isalpha(Xen_to_C_gunichar(c)))); } static Xen gxg_g_unichar_iscntrl(Xen c) { #define H_g_unichar_iscntrl "gboolean g_unichar_iscntrl(gunichar c)" Xen_check_type(Xen_is_gunichar(c), c, 1, "g_unichar_iscntrl", "gunichar"); return(C_to_Xen_gboolean(g_unichar_iscntrl(Xen_to_C_gunichar(c)))); } static Xen gxg_g_unichar_isdefined(Xen c) { #define H_g_unichar_isdefined "gboolean g_unichar_isdefined(gunichar c)" Xen_check_type(Xen_is_gunichar(c), c, 1, "g_unichar_isdefined", "gunichar"); return(C_to_Xen_gboolean(g_unichar_isdefined(Xen_to_C_gunichar(c)))); } static Xen gxg_g_unichar_isdigit(Xen c) { #define H_g_unichar_isdigit "gboolean g_unichar_isdigit(gunichar c)" Xen_check_type(Xen_is_gunichar(c), c, 1, "g_unichar_isdigit", "gunichar"); return(C_to_Xen_gboolean(g_unichar_isdigit(Xen_to_C_gunichar(c)))); } static Xen gxg_g_unichar_isgraph(Xen c) { #define H_g_unichar_isgraph "gboolean g_unichar_isgraph(gunichar c)" Xen_check_type(Xen_is_gunichar(c), c, 1, "g_unichar_isgraph", "gunichar"); return(C_to_Xen_gboolean(g_unichar_isgraph(Xen_to_C_gunichar(c)))); } static Xen gxg_g_unichar_islower(Xen c) { #define H_g_unichar_islower "gboolean g_unichar_islower(gunichar c)" Xen_check_type(Xen_is_gunichar(c), c, 1, "g_unichar_islower", "gunichar"); return(C_to_Xen_gboolean(g_unichar_islower(Xen_to_C_gunichar(c)))); } static Xen gxg_g_unichar_ismark(Xen c) { #define H_g_unichar_ismark "gboolean g_unichar_ismark(gunichar c)" Xen_check_type(Xen_is_gunichar(c), c, 1, "g_unichar_ismark", "gunichar"); return(C_to_Xen_gboolean(g_unichar_ismark(Xen_to_C_gunichar(c)))); } static Xen gxg_g_unichar_isprint(Xen c) { #define H_g_unichar_isprint "gboolean g_unichar_isprint(gunichar c)" Xen_check_type(Xen_is_gunichar(c), c, 1, "g_unichar_isprint", "gunichar"); return(C_to_Xen_gboolean(g_unichar_isprint(Xen_to_C_gunichar(c)))); } static Xen gxg_g_unichar_ispunct(Xen c) { #define H_g_unichar_ispunct "gboolean g_unichar_ispunct(gunichar c)" Xen_check_type(Xen_is_gunichar(c), c, 1, "g_unichar_ispunct", "gunichar"); return(C_to_Xen_gboolean(g_unichar_ispunct(Xen_to_C_gunichar(c)))); } static Xen gxg_g_unichar_isspace(Xen c) { #define H_g_unichar_isspace "gboolean g_unichar_isspace(gunichar c)" Xen_check_type(Xen_is_gunichar(c), c, 1, "g_unichar_isspace", "gunichar"); return(C_to_Xen_gboolean(g_unichar_isspace(Xen_to_C_gunichar(c)))); } static Xen gxg_g_unichar_istitle(Xen c) { #define H_g_unichar_istitle "gboolean g_unichar_istitle(gunichar c)" Xen_check_type(Xen_is_gunichar(c), c, 1, "g_unichar_istitle", "gunichar"); return(C_to_Xen_gboolean(g_unichar_istitle(Xen_to_C_gunichar(c)))); } static Xen gxg_g_unichar_isupper(Xen c) { #define H_g_unichar_isupper "gboolean g_unichar_isupper(gunichar c)" Xen_check_type(Xen_is_gunichar(c), c, 1, "g_unichar_isupper", "gunichar"); return(C_to_Xen_gboolean(g_unichar_isupper(Xen_to_C_gunichar(c)))); } static Xen gxg_g_unichar_isxdigit(Xen c) { #define H_g_unichar_isxdigit "gboolean g_unichar_isxdigit(gunichar c)" Xen_check_type(Xen_is_gunichar(c), c, 1, "g_unichar_isxdigit", "gunichar"); return(C_to_Xen_gboolean(g_unichar_isxdigit(Xen_to_C_gunichar(c)))); } static Xen gxg_g_unichar_iswide(Xen c) { #define H_g_unichar_iswide "gboolean g_unichar_iswide(gunichar c)" Xen_check_type(Xen_is_gunichar(c), c, 1, "g_unichar_iswide", "gunichar"); return(C_to_Xen_gboolean(g_unichar_iswide(Xen_to_C_gunichar(c)))); } static Xen gxg_g_unichar_iswide_cjk(Xen c) { #define H_g_unichar_iswide_cjk "gboolean g_unichar_iswide_cjk(gunichar c)" Xen_check_type(Xen_is_gunichar(c), c, 1, "g_unichar_iswide_cjk", "gunichar"); return(C_to_Xen_gboolean(g_unichar_iswide_cjk(Xen_to_C_gunichar(c)))); } static Xen gxg_g_unichar_iszerowidth(Xen c) { #define H_g_unichar_iszerowidth "gboolean g_unichar_iszerowidth(gunichar c)" Xen_check_type(Xen_is_gunichar(c), c, 1, "g_unichar_iszerowidth", "gunichar"); return(C_to_Xen_gboolean(g_unichar_iszerowidth(Xen_to_C_gunichar(c)))); } static Xen gxg_g_unichar_toupper(Xen c) { #define H_g_unichar_toupper "gunichar g_unichar_toupper(gunichar c)" Xen_check_type(Xen_is_gunichar(c), c, 1, "g_unichar_toupper", "gunichar"); return(C_to_Xen_gunichar(g_unichar_toupper(Xen_to_C_gunichar(c)))); } static Xen gxg_g_unichar_tolower(Xen c) { #define H_g_unichar_tolower "gunichar g_unichar_tolower(gunichar c)" Xen_check_type(Xen_is_gunichar(c), c, 1, "g_unichar_tolower", "gunichar"); return(C_to_Xen_gunichar(g_unichar_tolower(Xen_to_C_gunichar(c)))); } static Xen gxg_g_unichar_totitle(Xen c) { #define H_g_unichar_totitle "gunichar g_unichar_totitle(gunichar c)" Xen_check_type(Xen_is_gunichar(c), c, 1, "g_unichar_totitle", "gunichar"); return(C_to_Xen_gunichar(g_unichar_totitle(Xen_to_C_gunichar(c)))); } static Xen gxg_g_unichar_digit_value(Xen c) { #define H_g_unichar_digit_value "gint g_unichar_digit_value(gunichar c)" Xen_check_type(Xen_is_gunichar(c), c, 1, "g_unichar_digit_value", "gunichar"); return(C_to_Xen_gint(g_unichar_digit_value(Xen_to_C_gunichar(c)))); } static Xen gxg_g_unichar_xdigit_value(Xen c) { #define H_g_unichar_xdigit_value "gint g_unichar_xdigit_value(gunichar c)" Xen_check_type(Xen_is_gunichar(c), c, 1, "g_unichar_xdigit_value", "gunichar"); return(C_to_Xen_gint(g_unichar_xdigit_value(Xen_to_C_gunichar(c)))); } static Xen gxg_g_unichar_combining_class(Xen uc) { #define H_g_unichar_combining_class "gint g_unichar_combining_class(gunichar uc)" Xen_check_type(Xen_is_gunichar(uc), uc, 1, "g_unichar_combining_class", "gunichar"); return(C_to_Xen_gint(g_unichar_combining_class(Xen_to_C_gunichar(uc)))); } static Xen gxg_g_unicode_canonical_ordering(Xen string, Xen len) { #define H_g_unicode_canonical_ordering "void g_unicode_canonical_ordering(gunichar* string, gsize len)" Xen_check_type(Xen_is_gunichar_(string), string, 1, "g_unicode_canonical_ordering", "gunichar*"); Xen_check_type(Xen_is_gsize(len), len, 2, "g_unicode_canonical_ordering", "gsize"); g_unicode_canonical_ordering(Xen_to_C_gunichar_(string), Xen_to_C_gsize(len)); return(Xen_false); } static Xen gxg_g_utf8_get_char(Xen p) { #define H_g_utf8_get_char "gunichar g_utf8_get_char(gchar* p)" Xen_check_type(Xen_is_gchar_(p), p, 1, "g_utf8_get_char", "gchar*"); return(C_to_Xen_gunichar(g_utf8_get_char((const gchar*)Xen_to_C_gchar_(p)))); } static Xen gxg_g_utf8_get_char_validated(Xen p, Xen max_len) { #define H_g_utf8_get_char_validated "gunichar g_utf8_get_char_validated(gchar* p, gssize max_len)" Xen_check_type(Xen_is_gchar_(p), p, 1, "g_utf8_get_char_validated", "gchar*"); Xen_check_type(Xen_is_gssize(max_len), max_len, 2, "g_utf8_get_char_validated", "gssize"); return(C_to_Xen_gunichar(g_utf8_get_char_validated((const gchar*)Xen_to_C_gchar_(p), Xen_to_C_gssize(max_len)))); } static Xen gxg_g_utf8_prev_char(Xen p) { #define H_g_utf8_prev_char "gchar* g_utf8_prev_char(gchar* p)" Xen_check_type(Xen_is_gchar_(p), p, 1, "g_utf8_prev_char", "gchar*"); return(C_to_Xen_gchar_(g_utf8_prev_char((const gchar*)Xen_to_C_gchar_(p)))); } static Xen gxg_g_utf8_find_next_char(Xen p, Xen end) { #define H_g_utf8_find_next_char "gchar* g_utf8_find_next_char(gchar* p, gchar* end)" Xen_check_type(Xen_is_gchar_(p), p, 1, "g_utf8_find_next_char", "gchar*"); Xen_check_type(Xen_is_gchar_(end), end, 2, "g_utf8_find_next_char", "gchar*"); return(C_to_Xen_gchar_(g_utf8_find_next_char((const gchar*)Xen_to_C_gchar_(p), (const gchar*)Xen_to_C_gchar_(end)))); } static Xen gxg_g_utf8_find_prev_char(Xen str, Xen p) { #define H_g_utf8_find_prev_char "gchar* g_utf8_find_prev_char(gchar* str, gchar* p)" Xen_check_type(Xen_is_gchar_(str), str, 1, "g_utf8_find_prev_char", "gchar*"); Xen_check_type(Xen_is_gchar_(p), p, 2, "g_utf8_find_prev_char", "gchar*"); return(C_to_Xen_gchar_(g_utf8_find_prev_char((const gchar*)Xen_to_C_gchar_(str), (const gchar*)Xen_to_C_gchar_(p)))); } static Xen gxg_g_utf8_strlen(Xen p, Xen max) { #define H_g_utf8_strlen "glong g_utf8_strlen(gchar* p, gssize max)" Xen_check_type(Xen_is_gchar_(p), p, 1, "g_utf8_strlen", "gchar*"); Xen_check_type(Xen_is_gssize(max), max, 2, "g_utf8_strlen", "gssize"); return(C_to_Xen_glong(g_utf8_strlen((const gchar*)Xen_to_C_gchar_(p), Xen_to_C_gssize(max)))); } static Xen gxg_g_utf8_strchr(Xen p, Xen len, Xen c) { #define H_g_utf8_strchr "gchar* g_utf8_strchr(gchar* p, gssize len, gunichar c)" Xen_check_type(Xen_is_gchar_(p), p, 1, "g_utf8_strchr", "gchar*"); Xen_check_type(Xen_is_gssize(len), len, 2, "g_utf8_strchr", "gssize"); Xen_check_type(Xen_is_gunichar(c), c, 3, "g_utf8_strchr", "gunichar"); return(C_to_Xen_gchar_(g_utf8_strchr((const gchar*)Xen_to_C_gchar_(p), Xen_to_C_gssize(len), Xen_to_C_gunichar(c)))); } static Xen gxg_g_utf8_strrchr(Xen p, Xen len, Xen c) { #define H_g_utf8_strrchr "gchar* g_utf8_strrchr(gchar* p, gssize len, gunichar c)" Xen_check_type(Xen_is_gchar_(p), p, 1, "g_utf8_strrchr", "gchar*"); Xen_check_type(Xen_is_gssize(len), len, 2, "g_utf8_strrchr", "gssize"); Xen_check_type(Xen_is_gunichar(c), c, 3, "g_utf8_strrchr", "gunichar"); return(C_to_Xen_gchar_(g_utf8_strrchr((const gchar*)Xen_to_C_gchar_(p), Xen_to_C_gssize(len), Xen_to_C_gunichar(c)))); } static Xen gxg_g_utf8_strreverse(Xen str, Xen len) { #define H_g_utf8_strreverse "gchar* g_utf8_strreverse(gchar* str, gssize len)" Xen_check_type(Xen_is_gchar_(str), str, 1, "g_utf8_strreverse", "gchar*"); Xen_check_type(Xen_is_gssize(len), len, 2, "g_utf8_strreverse", "gssize"); return(C_to_Xen_gchar_(g_utf8_strreverse((const gchar*)Xen_to_C_gchar_(str), Xen_to_C_gssize(len)))); } static Xen gxg_g_utf8_validate(Xen str, Xen max_len, Xen ignore_end) { #define H_g_utf8_validate "gboolean g_utf8_validate(gchar* str, gssize max_len, gchar** [end])" gchar* ref_end = NULL; Xen_check_type(Xen_is_gchar_(str), str, 1, "g_utf8_validate", "gchar*"); Xen_check_type(Xen_is_gssize(max_len), max_len, 2, "g_utf8_validate", "gssize"); { Xen result; result = C_to_Xen_gboolean(g_utf8_validate((const gchar*)Xen_to_C_gchar_(str), Xen_to_C_gssize(max_len), (const gchar**)&ref_end)); return(Xen_list_2(result, C_to_Xen_gchar_(ref_end))); } } static Xen gxg_g_utf8_strup(Xen str, Xen len) { #define H_g_utf8_strup "gchar* g_utf8_strup(gchar* str, gssize len)" Xen_check_type(Xen_is_gchar_(str), str, 1, "g_utf8_strup", "gchar*"); Xen_check_type(Xen_is_gssize(len), len, 2, "g_utf8_strup", "gssize"); return(C_to_Xen_gchar_(g_utf8_strup((const gchar*)Xen_to_C_gchar_(str), Xen_to_C_gssize(len)))); } static Xen gxg_g_utf8_strdown(Xen str, Xen len) { #define H_g_utf8_strdown "gchar* g_utf8_strdown(gchar* str, gssize len)" Xen_check_type(Xen_is_gchar_(str), str, 1, "g_utf8_strdown", "gchar*"); Xen_check_type(Xen_is_gssize(len), len, 2, "g_utf8_strdown", "gssize"); return(C_to_Xen_gchar_(g_utf8_strdown((const gchar*)Xen_to_C_gchar_(str), Xen_to_C_gssize(len)))); } static Xen gxg_g_utf8_casefold(Xen str, Xen len) { #define H_g_utf8_casefold "gchar* g_utf8_casefold(gchar* str, gssize len)" Xen_check_type(Xen_is_gchar_(str), str, 1, "g_utf8_casefold", "gchar*"); Xen_check_type(Xen_is_gssize(len), len, 2, "g_utf8_casefold", "gssize"); return(C_to_Xen_gchar_(g_utf8_casefold((const gchar*)Xen_to_C_gchar_(str), Xen_to_C_gssize(len)))); } static Xen gxg_g_utf8_normalize(Xen str, Xen len, Xen mode) { #define H_g_utf8_normalize "gchar* g_utf8_normalize(gchar* str, gssize len, GNormalizeMode mode)" Xen_check_type(Xen_is_gchar_(str), str, 1, "g_utf8_normalize", "gchar*"); Xen_check_type(Xen_is_gssize(len), len, 2, "g_utf8_normalize", "gssize"); Xen_check_type(Xen_is_GNormalizeMode(mode), mode, 3, "g_utf8_normalize", "GNormalizeMode"); return(C_to_Xen_gchar_(g_utf8_normalize((const gchar*)Xen_to_C_gchar_(str), Xen_to_C_gssize(len), Xen_to_C_GNormalizeMode(mode)))); } static Xen gxg_g_utf8_collate(Xen str1, Xen str2) { #define H_g_utf8_collate "gint g_utf8_collate(gchar* str1, gchar* str2)" Xen_check_type(Xen_is_gchar_(str1), str1, 1, "g_utf8_collate", "gchar*"); Xen_check_type(Xen_is_gchar_(str2), str2, 2, "g_utf8_collate", "gchar*"); return(C_to_Xen_gint(g_utf8_collate((const gchar*)Xen_to_C_gchar_(str1), (const gchar*)Xen_to_C_gchar_(str2)))); } static Xen gxg_g_utf8_collate_key(Xen str, Xen len) { #define H_g_utf8_collate_key "gchar* g_utf8_collate_key(gchar* str, gssize len)" Xen_check_type(Xen_is_gchar_(str), str, 1, "g_utf8_collate_key", "gchar*"); Xen_check_type(Xen_is_gssize(len), len, 2, "g_utf8_collate_key", "gssize"); return(C_to_Xen_gchar_(g_utf8_collate_key((const gchar*)Xen_to_C_gchar_(str), Xen_to_C_gssize(len)))); } static Xen gxg_g_utf8_collate_key_for_filename(Xen str, Xen len) { #define H_g_utf8_collate_key_for_filename "gchar* g_utf8_collate_key_for_filename(gchar* str, gssize len)" Xen_check_type(Xen_is_gchar_(str), str, 1, "g_utf8_collate_key_for_filename", "gchar*"); Xen_check_type(Xen_is_gssize(len), len, 2, "g_utf8_collate_key_for_filename", "gssize"); return(C_to_Xen_gchar_(g_utf8_collate_key_for_filename((const gchar*)Xen_to_C_gchar_(str), Xen_to_C_gssize(len)))); } static Xen gxg_g_cclosure_new(Xen func, Xen func_info, Xen destroy_data) { #define H_g_cclosure_new "GClosure* g_cclosure_new(GCallback func, lambda_data func_info, GClosureNotify destroy_data)" Xen_check_type(Xen_is_GCallback(func), func, 1, "g_cclosure_new", "GCallback"); Xen_check_type(Xen_is_lambda_data(func_info), func_info, 2, "g_cclosure_new", "lambda_data"); Xen_check_type(Xen_is_GClosureNotify(destroy_data) || Xen_is_false(destroy_data), destroy_data, 3, "g_cclosure_new", "GClosureNotify"); { Xen result; int loc; Xen gxg_ptr = Xen_list_5(func, func_info, Xen_false, Xen_false, Xen_false); loc = xm_protect(gxg_ptr); Xen_list_set(gxg_ptr, 2, C_int_to_Xen_integer(loc)); result = C_to_Xen_GClosure_(g_cclosure_new(Xen_to_C_GCallback(func), Xen_to_C_lambda_data(func_info), Xen_to_C_GClosureNotify(destroy_data))); return(result); } } static Xen gxg_g_signal_newv(Xen arglist) { #define H_g_signal_newv "guint g_signal_newv(gchar* signal_name, GType itype, GSignalFlags signal_flags, \ GClosure* class_closure, GSignalAccumulator accumulator, gpointer accu_data, GSignalCMarshaller c_marshaller, \ GType return_type, guint n_params, GType* param_types)" Xen signal_name, itype, signal_flags, class_closure, accumulator, accu_data, c_marshaller, return_type, n_params, param_types; signal_name = Xen_list_ref(arglist, 0); itype = Xen_list_ref(arglist, 1); signal_flags = Xen_list_ref(arglist, 2); class_closure = Xen_list_ref(arglist, 3); accumulator = Xen_list_ref(arglist, 4); accu_data = Xen_list_ref(arglist, 5); c_marshaller = Xen_list_ref(arglist, 6); return_type = Xen_list_ref(arglist, 7); n_params = Xen_list_ref(arglist, 8); param_types = Xen_list_ref(arglist, 9); Xen_check_type(Xen_is_gchar_(signal_name), signal_name, 1, "g_signal_newv", "gchar*"); Xen_check_type(Xen_is_GType(itype), itype, 2, "g_signal_newv", "GType"); Xen_check_type(Xen_is_GSignalFlags(signal_flags), signal_flags, 3, "g_signal_newv", "GSignalFlags"); Xen_check_type(Xen_is_GClosure_(class_closure) || Xen_is_false(class_closure), class_closure, 4, "g_signal_newv", "GClosure*"); Xen_check_type(Xen_is_GSignalAccumulator(accumulator), accumulator, 5, "g_signal_newv", "GSignalAccumulator"); Xen_check_type(Xen_is_gpointer(accu_data), accu_data, 6, "g_signal_newv", "gpointer"); Xen_check_type(Xen_is_GSignalCMarshaller(c_marshaller), c_marshaller, 7, "g_signal_newv", "GSignalCMarshaller"); Xen_check_type(Xen_is_GType(return_type), return_type, 8, "g_signal_newv", "GType"); Xen_check_type(Xen_is_guint(n_params), n_params, 9, "g_signal_newv", "guint"); Xen_check_type(Xen_is_GType_(param_types), param_types, 10, "g_signal_newv", "GType*"); return(C_to_Xen_guint(g_signal_newv(Xen_to_C_gchar_(signal_name), Xen_to_C_GType(itype), Xen_to_C_GSignalFlags(signal_flags), Xen_to_C_GClosure_(class_closure), Xen_to_C_GSignalAccumulator(accumulator), Xen_to_C_gpointer(accu_data), Xen_to_C_GSignalCMarshaller(c_marshaller), Xen_to_C_GType(return_type), Xen_to_C_guint(n_params), Xen_to_C_GType_(param_types)))); } static Xen gxg_g_signal_lookup(Xen name, Xen itype) { #define H_g_signal_lookup "guint g_signal_lookup(gchar* name, GType itype)" Xen_check_type(Xen_is_gchar_(name), name, 1, "g_signal_lookup", "gchar*"); Xen_check_type(Xen_is_GType(itype), itype, 2, "g_signal_lookup", "GType"); return(C_to_Xen_guint(g_signal_lookup(Xen_to_C_gchar_(name), Xen_to_C_GType(itype)))); } static Xen gxg_g_signal_name(Xen signal_id) { #define H_g_signal_name "gchar* g_signal_name(guint signal_id)" Xen_check_type(Xen_is_guint(signal_id), signal_id, 1, "g_signal_name", "guint"); return(C_to_Xen_gchar_(g_signal_name(Xen_to_C_guint(signal_id)))); } static Xen gxg_g_signal_query(Xen signal_id, Xen query) { #define H_g_signal_query "void g_signal_query(guint signal_id, GSignalQuery* query)" Xen_check_type(Xen_is_guint(signal_id), signal_id, 1, "g_signal_query", "guint"); Xen_check_type(Xen_is_GSignalQuery_(query), query, 2, "g_signal_query", "GSignalQuery*"); g_signal_query(Xen_to_C_guint(signal_id), Xen_to_C_GSignalQuery_(query)); return(Xen_false); } static Xen gxg_g_signal_list_ids(Xen itype, Xen n_ids) { #define H_g_signal_list_ids "guint* g_signal_list_ids(GType itype, guint* n_ids)" Xen_check_type(Xen_is_GType(itype), itype, 1, "g_signal_list_ids", "GType"); Xen_check_type(Xen_is_guint_(n_ids), n_ids, 2, "g_signal_list_ids", "guint*"); return(C_to_Xen_guint_(g_signal_list_ids(Xen_to_C_GType(itype), Xen_to_C_guint_(n_ids)))); } static Xen gxg_g_signal_parse_name(Xen detailed_signal, Xen itype, Xen ignore_signal_id_p, Xen ignore_detail_p, Xen force_detail_quark) { #define H_g_signal_parse_name "gboolean g_signal_parse_name(gchar* detailed_signal, GType itype, guint* [signal_id_p], \ GQuark* [detail_p], gboolean force_detail_quark)" guint ref_signal_id_p; GQuark ref_detail_p; Xen_check_type(Xen_is_gchar_(detailed_signal), detailed_signal, 1, "g_signal_parse_name", "gchar*"); Xen_check_type(Xen_is_GType(itype), itype, 2, "g_signal_parse_name", "GType"); Xen_check_type(Xen_is_gboolean(force_detail_quark), force_detail_quark, 5, "g_signal_parse_name", "gboolean"); { Xen result; result = C_to_Xen_gboolean(g_signal_parse_name(Xen_to_C_gchar_(detailed_signal), Xen_to_C_GType(itype), &ref_signal_id_p, &ref_detail_p, Xen_to_C_gboolean(force_detail_quark))); return(Xen_list_3(result, C_to_Xen_guint(ref_signal_id_p), C_to_Xen_GQuark(ref_detail_p))); } } static Xen gxg_g_signal_get_invocation_hint(Xen instance) { #define H_g_signal_get_invocation_hint "GSignalInvocationHint* g_signal_get_invocation_hint(gpointer instance)" Xen_check_type(Xen_is_gpointer(instance), instance, 1, "g_signal_get_invocation_hint", "gpointer"); return(C_to_Xen_GSignalInvocationHint_(g_signal_get_invocation_hint(Xen_to_C_gpointer(instance)))); } static Xen gxg_g_signal_stop_emission(Xen instance, Xen signal_id, Xen detail) { #define H_g_signal_stop_emission "void g_signal_stop_emission(gpointer instance, guint signal_id, GQuark detail)" Xen_check_type(Xen_is_gpointer(instance), instance, 1, "g_signal_stop_emission", "gpointer"); Xen_check_type(Xen_is_guint(signal_id), signal_id, 2, "g_signal_stop_emission", "guint"); Xen_check_type(Xen_is_GQuark(detail), detail, 3, "g_signal_stop_emission", "GQuark"); g_signal_stop_emission(Xen_to_C_gpointer(instance), Xen_to_C_guint(signal_id), Xen_to_C_GQuark(detail)); return(Xen_false); } static Xen gxg_g_signal_stop_emission_by_name(Xen instance, Xen detailed_signal) { #define H_g_signal_stop_emission_by_name "void g_signal_stop_emission_by_name(gpointer instance, gchar* detailed_signal)" Xen_check_type(Xen_is_gpointer(instance), instance, 1, "g_signal_stop_emission_by_name", "gpointer"); Xen_check_type(Xen_is_gchar_(detailed_signal), detailed_signal, 2, "g_signal_stop_emission_by_name", "gchar*"); g_signal_stop_emission_by_name(Xen_to_C_gpointer(instance), Xen_to_C_gchar_(detailed_signal)); return(Xen_false); } static Xen gxg_g_signal_add_emission_hook(Xen signal_id, Xen quark, Xen hook_func, Xen func_info, Xen data_destroy) { #define H_g_signal_add_emission_hook "gulong g_signal_add_emission_hook(guint signal_id, GQuark quark, \ GSignalEmissionHook hook_func, lambda_data func_info, GtkDestroyNotify data_destroy)" Xen_check_type(Xen_is_guint(signal_id), signal_id, 1, "g_signal_add_emission_hook", "guint"); Xen_check_type(Xen_is_GQuark(quark), quark, 2, "g_signal_add_emission_hook", "GQuark"); Xen_check_type(Xen_is_GSignalEmissionHook(hook_func), hook_func, 3, "g_signal_add_emission_hook", "GSignalEmissionHook"); Xen_check_type(Xen_is_lambda_data(func_info), func_info, 4, "g_signal_add_emission_hook", "lambda_data"); Xen_check_type(Xen_is_GtkDestroyNotify(data_destroy), data_destroy, 5, "g_signal_add_emission_hook", "GtkDestroyNotify"); { Xen result; Xen gxg_ptr = Xen_list_5(Xen_false, func_info, Xen_false, Xen_false, Xen_false); xm_protect(gxg_ptr); Xen_list_set(gxg_ptr, 3, data_destroy); result = C_to_Xen_gulong(g_signal_add_emission_hook(Xen_to_C_guint(signal_id), Xen_to_C_GQuark(quark), Xen_to_C_GSignalEmissionHook(hook_func), Xen_to_C_lambda_data(func_info), Xen_to_C_GtkDestroyNotify(data_destroy))); return(result); } } static Xen gxg_g_signal_remove_emission_hook(Xen signal_id, Xen hook_id) { #define H_g_signal_remove_emission_hook "void g_signal_remove_emission_hook(guint signal_id, gulong hook_id)" Xen_check_type(Xen_is_guint(signal_id), signal_id, 1, "g_signal_remove_emission_hook", "guint"); Xen_check_type(Xen_is_gulong(hook_id), hook_id, 2, "g_signal_remove_emission_hook", "gulong"); g_signal_remove_emission_hook(Xen_to_C_guint(signal_id), Xen_to_C_gulong(hook_id)); return(Xen_false); } static Xen gxg_g_signal_has_handler_pending(Xen instance, Xen signal_id, Xen detail, Xen may_be_blocked) { #define H_g_signal_has_handler_pending "gboolean g_signal_has_handler_pending(gpointer instance, guint signal_id, \ GQuark detail, gboolean may_be_blocked)" Xen_check_type(Xen_is_gpointer(instance), instance, 1, "g_signal_has_handler_pending", "gpointer"); Xen_check_type(Xen_is_guint(signal_id), signal_id, 2, "g_signal_has_handler_pending", "guint"); Xen_check_type(Xen_is_GQuark(detail), detail, 3, "g_signal_has_handler_pending", "GQuark"); Xen_check_type(Xen_is_gboolean(may_be_blocked), may_be_blocked, 4, "g_signal_has_handler_pending", "gboolean"); return(C_to_Xen_gboolean(g_signal_has_handler_pending(Xen_to_C_gpointer(instance), Xen_to_C_guint(signal_id), Xen_to_C_GQuark(detail), Xen_to_C_gboolean(may_be_blocked)))); } static Xen gxg_g_signal_connect_closure_by_id(Xen instance, Xen signal_id, Xen detail, Xen closure, Xen after) { #define H_g_signal_connect_closure_by_id "gulong g_signal_connect_closure_by_id(gpointer instance, \ guint signal_id, GQuark detail, GClosure* closure, gboolean after)" Xen_check_type(Xen_is_gpointer(instance), instance, 1, "g_signal_connect_closure_by_id", "gpointer"); Xen_check_type(Xen_is_guint(signal_id), signal_id, 2, "g_signal_connect_closure_by_id", "guint"); Xen_check_type(Xen_is_GQuark(detail), detail, 3, "g_signal_connect_closure_by_id", "GQuark"); Xen_check_type(Xen_is_GClosure_(closure), closure, 4, "g_signal_connect_closure_by_id", "GClosure*"); Xen_check_type(Xen_is_gboolean(after), after, 5, "g_signal_connect_closure_by_id", "gboolean"); return(C_to_Xen_gulong(g_signal_connect_closure_by_id(Xen_to_C_gpointer(instance), Xen_to_C_guint(signal_id), Xen_to_C_GQuark(detail), Xen_to_C_GClosure_(closure), Xen_to_C_gboolean(after)))); } static Xen gxg_g_signal_connect_closure(Xen instance, Xen detailed_signal, Xen closure, Xen after) { #define H_g_signal_connect_closure "gulong g_signal_connect_closure(gpointer instance, gchar* detailed_signal, \ GClosure* closure, gboolean after)" Xen_check_type(Xen_is_gpointer(instance), instance, 1, "g_signal_connect_closure", "gpointer"); Xen_check_type(Xen_is_gchar_(detailed_signal), detailed_signal, 2, "g_signal_connect_closure", "gchar*"); Xen_check_type(Xen_is_GClosure_(closure), closure, 3, "g_signal_connect_closure", "GClosure*"); Xen_check_type(Xen_is_gboolean(after), after, 4, "g_signal_connect_closure", "gboolean"); return(C_to_Xen_gulong(g_signal_connect_closure(Xen_to_C_gpointer(instance), Xen_to_C_gchar_(detailed_signal), Xen_to_C_GClosure_(closure), Xen_to_C_gboolean(after)))); } static Xen gxg_g_signal_connect_data(Xen instance, Xen detailed_signal, Xen func, Xen func_info, Xen destroy_data, Xen connect_flags) { #define H_g_signal_connect_data "gulong g_signal_connect_data(gpointer instance, gchar* detailed_signal, \ GCallback func, lambda_data func_info, GClosureNotify destroy_data, GConnectFlags connect_flags)" Xen_check_type(Xen_is_gpointer(instance), instance, 1, "g_signal_connect_data", "gpointer"); Xen_check_type(Xen_is_gchar_(detailed_signal), detailed_signal, 2, "g_signal_connect_data", "gchar*"); Xen_check_type(Xen_is_GCallback(func), func, 3, "g_signal_connect_data", "GCallback"); Xen_check_type(Xen_is_lambda_data(func_info), func_info, 4, "g_signal_connect_data", "lambda_data"); Xen_check_type(Xen_is_GClosureNotify(destroy_data) || Xen_is_false(destroy_data), destroy_data, 5, "g_signal_connect_data", "GClosureNotify"); Xen_check_type(Xen_is_GConnectFlags(connect_flags), connect_flags, 6, "g_signal_connect_data", "GConnectFlags"); { Xen result; int loc; Xen gxg_ptr = Xen_list_5(func, func_info, Xen_false, Xen_false, Xen_false); loc = xm_protect(gxg_ptr); Xen_list_set(gxg_ptr, 2, C_int_to_Xen_integer(loc)); result = C_to_Xen_gulong(g_signal_connect_data(Xen_to_C_gpointer(instance), Xen_to_C_gchar_(detailed_signal), Xen_to_C_GCallback(func), Xen_to_C_lambda_data(func_info), Xen_to_C_GClosureNotify(destroy_data), Xen_to_C_GConnectFlags(connect_flags))); return(result); } } static Xen gxg_g_signal_handler_block(Xen instance, Xen handler_id) { #define H_g_signal_handler_block "void g_signal_handler_block(gpointer instance, gulong handler_id)" Xen_check_type(Xen_is_gpointer(instance), instance, 1, "g_signal_handler_block", "gpointer"); Xen_check_type(Xen_is_gulong(handler_id), handler_id, 2, "g_signal_handler_block", "gulong"); g_signal_handler_block(Xen_to_C_gpointer(instance), Xen_to_C_gulong(handler_id)); return(Xen_false); } static Xen gxg_g_signal_handler_unblock(Xen instance, Xen handler_id) { #define H_g_signal_handler_unblock "void g_signal_handler_unblock(gpointer instance, gulong handler_id)" Xen_check_type(Xen_is_gpointer(instance), instance, 1, "g_signal_handler_unblock", "gpointer"); Xen_check_type(Xen_is_gulong(handler_id), handler_id, 2, "g_signal_handler_unblock", "gulong"); g_signal_handler_unblock(Xen_to_C_gpointer(instance), Xen_to_C_gulong(handler_id)); return(Xen_false); } static Xen gxg_g_signal_handler_disconnect(Xen instance, Xen handler_id) { #define H_g_signal_handler_disconnect "void g_signal_handler_disconnect(gpointer instance, gulong handler_id)" Xen_check_type(Xen_is_gpointer(instance), instance, 1, "g_signal_handler_disconnect", "gpointer"); Xen_check_type(Xen_is_gulong(handler_id), handler_id, 2, "g_signal_handler_disconnect", "gulong"); g_signal_handler_disconnect(Xen_to_C_gpointer(instance), Xen_to_C_gulong(handler_id)); return(Xen_false); } static Xen gxg_g_signal_handler_is_connected(Xen instance, Xen handler_id) { #define H_g_signal_handler_is_connected "gboolean g_signal_handler_is_connected(gpointer instance, \ gulong handler_id)" Xen_check_type(Xen_is_gpointer(instance), instance, 1, "g_signal_handler_is_connected", "gpointer"); Xen_check_type(Xen_is_gulong(handler_id), handler_id, 2, "g_signal_handler_is_connected", "gulong"); return(C_to_Xen_gboolean(g_signal_handler_is_connected(Xen_to_C_gpointer(instance), Xen_to_C_gulong(handler_id)))); } static Xen gxg_g_signal_handler_find(Xen instance, Xen mask, Xen signal_id, Xen detail, Xen closure, Xen func, Xen data) { #define H_g_signal_handler_find "gulong g_signal_handler_find(gpointer instance, GSignalMatchType mask, \ guint signal_id, GQuark detail, GClosure* closure, gpointer func, gpointer data)" Xen_check_type(Xen_is_gpointer(instance), instance, 1, "g_signal_handler_find", "gpointer"); Xen_check_type(Xen_is_GSignalMatchType(mask), mask, 2, "g_signal_handler_find", "GSignalMatchType"); Xen_check_type(Xen_is_guint(signal_id), signal_id, 3, "g_signal_handler_find", "guint"); Xen_check_type(Xen_is_GQuark(detail), detail, 4, "g_signal_handler_find", "GQuark"); Xen_check_type(Xen_is_GClosure_(closure) || Xen_is_false(closure), closure, 5, "g_signal_handler_find", "GClosure*"); Xen_check_type(Xen_is_gpointer(func), func, 6, "g_signal_handler_find", "gpointer"); Xen_check_type(Xen_is_gpointer(data), data, 7, "g_signal_handler_find", "gpointer"); return(C_to_Xen_gulong(g_signal_handler_find(Xen_to_C_gpointer(instance), Xen_to_C_GSignalMatchType(mask), Xen_to_C_guint(signal_id), Xen_to_C_GQuark(detail), Xen_to_C_GClosure_(closure), Xen_to_C_gpointer(func), Xen_to_C_gpointer(data)))); } static Xen gxg_g_signal_handlers_block_matched(Xen instance, Xen mask, Xen signal_id, Xen detail, Xen closure, Xen func, Xen data) { #define H_g_signal_handlers_block_matched "guint g_signal_handlers_block_matched(gpointer instance, \ GSignalMatchType mask, guint signal_id, GQuark detail, GClosure* closure, gpointer func, gpointer data)" Xen_check_type(Xen_is_gpointer(instance), instance, 1, "g_signal_handlers_block_matched", "gpointer"); Xen_check_type(Xen_is_GSignalMatchType(mask), mask, 2, "g_signal_handlers_block_matched", "GSignalMatchType"); Xen_check_type(Xen_is_guint(signal_id), signal_id, 3, "g_signal_handlers_block_matched", "guint"); Xen_check_type(Xen_is_GQuark(detail), detail, 4, "g_signal_handlers_block_matched", "GQuark"); Xen_check_type(Xen_is_GClosure_(closure) || Xen_is_false(closure), closure, 5, "g_signal_handlers_block_matched", "GClosure*"); Xen_check_type(Xen_is_gpointer(func), func, 6, "g_signal_handlers_block_matched", "gpointer"); Xen_check_type(Xen_is_gpointer(data), data, 7, "g_signal_handlers_block_matched", "gpointer"); return(C_to_Xen_guint(g_signal_handlers_block_matched(Xen_to_C_gpointer(instance), Xen_to_C_GSignalMatchType(mask), Xen_to_C_guint(signal_id), Xen_to_C_GQuark(detail), Xen_to_C_GClosure_(closure), Xen_to_C_gpointer(func), Xen_to_C_gpointer(data)))); } static Xen gxg_g_signal_handlers_unblock_matched(Xen instance, Xen mask, Xen signal_id, Xen detail, Xen closure, Xen func, Xen data) { #define H_g_signal_handlers_unblock_matched "guint g_signal_handlers_unblock_matched(gpointer instance, \ GSignalMatchType mask, guint signal_id, GQuark detail, GClosure* closure, gpointer func, gpointer data)" Xen_check_type(Xen_is_gpointer(instance), instance, 1, "g_signal_handlers_unblock_matched", "gpointer"); Xen_check_type(Xen_is_GSignalMatchType(mask), mask, 2, "g_signal_handlers_unblock_matched", "GSignalMatchType"); Xen_check_type(Xen_is_guint(signal_id), signal_id, 3, "g_signal_handlers_unblock_matched", "guint"); Xen_check_type(Xen_is_GQuark(detail), detail, 4, "g_signal_handlers_unblock_matched", "GQuark"); Xen_check_type(Xen_is_GClosure_(closure) || Xen_is_false(closure), closure, 5, "g_signal_handlers_unblock_matched", "GClosure*"); Xen_check_type(Xen_is_gpointer(func), func, 6, "g_signal_handlers_unblock_matched", "gpointer"); Xen_check_type(Xen_is_gpointer(data), data, 7, "g_signal_handlers_unblock_matched", "gpointer"); return(C_to_Xen_guint(g_signal_handlers_unblock_matched(Xen_to_C_gpointer(instance), Xen_to_C_GSignalMatchType(mask), Xen_to_C_guint(signal_id), Xen_to_C_GQuark(detail), Xen_to_C_GClosure_(closure), Xen_to_C_gpointer(func), Xen_to_C_gpointer(data)))); } static Xen gxg_g_signal_handlers_disconnect_matched(Xen instance, Xen mask, Xen signal_id, Xen detail, Xen closure, Xen func, Xen data) { #define H_g_signal_handlers_disconnect_matched "guint g_signal_handlers_disconnect_matched(gpointer instance, \ GSignalMatchType mask, guint signal_id, GQuark detail, GClosure* closure, gpointer func, gpointer data)" Xen_check_type(Xen_is_gpointer(instance), instance, 1, "g_signal_handlers_disconnect_matched", "gpointer"); Xen_check_type(Xen_is_GSignalMatchType(mask), mask, 2, "g_signal_handlers_disconnect_matched", "GSignalMatchType"); Xen_check_type(Xen_is_guint(signal_id), signal_id, 3, "g_signal_handlers_disconnect_matched", "guint"); Xen_check_type(Xen_is_GQuark(detail), detail, 4, "g_signal_handlers_disconnect_matched", "GQuark"); Xen_check_type(Xen_is_GClosure_(closure) || Xen_is_false(closure), closure, 5, "g_signal_handlers_disconnect_matched", "GClosure*"); Xen_check_type(Xen_is_gpointer(func), func, 6, "g_signal_handlers_disconnect_matched", "gpointer"); Xen_check_type(Xen_is_gpointer(data), data, 7, "g_signal_handlers_disconnect_matched", "gpointer"); return(C_to_Xen_guint(g_signal_handlers_disconnect_matched(Xen_to_C_gpointer(instance), Xen_to_C_GSignalMatchType(mask), Xen_to_C_guint(signal_id), Xen_to_C_GQuark(detail), Xen_to_C_GClosure_(closure), Xen_to_C_gpointer(func), Xen_to_C_gpointer(data)))); } static Xen gxg_g_signal_handlers_destroy(Xen instance) { #define H_g_signal_handlers_destroy "void g_signal_handlers_destroy(gpointer instance)" Xen_check_type(Xen_is_gpointer(instance), instance, 1, "g_signal_handlers_destroy", "gpointer"); g_signal_handlers_destroy(Xen_to_C_gpointer(instance)); return(Xen_false); } static Xen gxg_g_object_ref(Xen object) { #define H_g_object_ref "gpointer g_object_ref(gpointer object)" Xen_check_type(Xen_is_gpointer(object), object, 1, "g_object_ref", "gpointer"); return(C_to_Xen_gpointer(g_object_ref(Xen_to_C_gpointer(object)))); } static Xen gxg_g_object_unref(Xen object) { #define H_g_object_unref "void g_object_unref(gpointer object)" Xen_check_type(Xen_is_gpointer(object), object, 1, "g_object_unref", "gpointer"); g_object_unref(Xen_to_C_gpointer(object)); return(Xen_false); } static Xen gxg_gdk_visual_get_system(void) { #define H_gdk_visual_get_system "GdkVisual* gdk_visual_get_system( void)" return(C_to_Xen_GdkVisual_(gdk_visual_get_system())); } static Xen gxg_gdk_cursor_new_for_display(Xen display, Xen cursor_type) { #define H_gdk_cursor_new_for_display "GdkCursor* gdk_cursor_new_for_display(GdkDisplay* display, GdkCursorType cursor_type)" Xen_check_type(Xen_is_GdkDisplay_(display), display, 1, "gdk_cursor_new_for_display", "GdkDisplay*"); Xen_check_type(Xen_is_GdkCursorType(cursor_type), cursor_type, 2, "gdk_cursor_new_for_display", "GdkCursorType"); return(C_to_Xen_GdkCursor_(gdk_cursor_new_for_display(Xen_to_C_GdkDisplay_(display), Xen_to_C_GdkCursorType(cursor_type)))); } static Xen gxg_gdk_cursor_get_display(Xen cursor) { #define H_gdk_cursor_get_display "GdkDisplay* gdk_cursor_get_display(GdkCursor* cursor)" Xen_check_type(Xen_is_GdkCursor_(cursor), cursor, 1, "gdk_cursor_get_display", "GdkCursor*"); return(C_to_Xen_GdkDisplay_(gdk_cursor_get_display(Xen_to_C_GdkCursor_(cursor)))); } static Xen gxg_gdk_drag_status(Xen context, Xen action, Xen time) { #define H_gdk_drag_status "void gdk_drag_status(GdkDragContext* context, GdkDragAction action, guint32 time)" Xen_check_type(Xen_is_GdkDragContext_(context), context, 1, "gdk_drag_status", "GdkDragContext*"); Xen_check_type(Xen_is_GdkDragAction(action), action, 2, "gdk_drag_status", "GdkDragAction"); Xen_check_type(Xen_is_guint32(time), time, 3, "gdk_drag_status", "guint32"); gdk_drag_status(Xen_to_C_GdkDragContext_(context), Xen_to_C_GdkDragAction(action), Xen_to_C_guint32(time)); return(Xen_false); } static Xen gxg_gdk_drop_reply(Xen context, Xen ok, Xen time) { #define H_gdk_drop_reply "void gdk_drop_reply(GdkDragContext* context, gboolean ok, guint32 time)" Xen_check_type(Xen_is_GdkDragContext_(context), context, 1, "gdk_drop_reply", "GdkDragContext*"); Xen_check_type(Xen_is_gboolean(ok), ok, 2, "gdk_drop_reply", "gboolean"); Xen_check_type(Xen_is_guint32(time), time, 3, "gdk_drop_reply", "guint32"); gdk_drop_reply(Xen_to_C_GdkDragContext_(context), Xen_to_C_gboolean(ok), Xen_to_C_guint32(time)); return(Xen_false); } static Xen gxg_gdk_drop_finish(Xen context, Xen success, Xen time) { #define H_gdk_drop_finish "void gdk_drop_finish(GdkDragContext* context, gboolean success, guint32 time)" Xen_check_type(Xen_is_GdkDragContext_(context), context, 1, "gdk_drop_finish", "GdkDragContext*"); Xen_check_type(Xen_is_gboolean(success), success, 2, "gdk_drop_finish", "gboolean"); Xen_check_type(Xen_is_guint32(time), time, 3, "gdk_drop_finish", "guint32"); gdk_drop_finish(Xen_to_C_GdkDragContext_(context), Xen_to_C_gboolean(success), Xen_to_C_guint32(time)); return(Xen_false); } static Xen gxg_gdk_drag_get_selection(Xen context) { #define H_gdk_drag_get_selection "GdkAtom gdk_drag_get_selection(GdkDragContext* context)" Xen_check_type(Xen_is_GdkDragContext_(context), context, 1, "gdk_drag_get_selection", "GdkDragContext*"); return(C_to_Xen_GdkAtom(gdk_drag_get_selection(Xen_to_C_GdkDragContext_(context)))); } static Xen gxg_gdk_drag_begin(Xen window, Xen targets) { #define H_gdk_drag_begin "GdkDragContext* gdk_drag_begin(GdkWindow* window, GList* targets)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_drag_begin", "GdkWindow*"); Xen_check_type(Xen_is_GList_(targets), targets, 2, "gdk_drag_begin", "GList*"); return(C_to_Xen_GdkDragContext_(gdk_drag_begin(Xen_to_C_GdkWindow_(window), Xen_to_C_GList_(targets)))); } static Xen gxg_gdk_drag_drop(Xen context, Xen time) { #define H_gdk_drag_drop "void gdk_drag_drop(GdkDragContext* context, guint32 time)" Xen_check_type(Xen_is_GdkDragContext_(context), context, 1, "gdk_drag_drop", "GdkDragContext*"); Xen_check_type(Xen_is_guint32(time), time, 2, "gdk_drag_drop", "guint32"); gdk_drag_drop(Xen_to_C_GdkDragContext_(context), Xen_to_C_guint32(time)); return(Xen_false); } static Xen gxg_gdk_drag_abort(Xen context, Xen time) { #define H_gdk_drag_abort "void gdk_drag_abort(GdkDragContext* context, guint32 time)" Xen_check_type(Xen_is_GdkDragContext_(context), context, 1, "gdk_drag_abort", "GdkDragContext*"); Xen_check_type(Xen_is_guint32(time), time, 2, "gdk_drag_abort", "guint32"); gdk_drag_abort(Xen_to_C_GdkDragContext_(context), Xen_to_C_guint32(time)); return(Xen_false); } static Xen gxg_gdk_events_pending(void) { #define H_gdk_events_pending "gboolean gdk_events_pending( void)" return(C_to_Xen_gboolean(gdk_events_pending())); } static Xen gxg_gdk_event_get(void) { #define H_gdk_event_get "GdkEvent* gdk_event_get( void)" return(C_to_Xen_GdkEvent_(gdk_event_get())); } static Xen gxg_gdk_event_peek(void) { #define H_gdk_event_peek "GdkEvent* gdk_event_peek( void)" return(C_to_Xen_GdkEvent_(gdk_event_peek())); } static Xen gxg_gdk_event_put(Xen event) { #define H_gdk_event_put "void gdk_event_put(GdkEvent* event)" Xen_check_type(Xen_is_GdkEvent_(event), event, 1, "gdk_event_put", "GdkEvent*"); gdk_event_put(Xen_to_C_GdkEvent_(event)); return(Xen_false); } static Xen gxg_gdk_event_copy(Xen event) { #define H_gdk_event_copy "GdkEvent* gdk_event_copy(GdkEvent* event)" Xen_check_type(Xen_is_GdkEvent_(event), event, 1, "gdk_event_copy", "GdkEvent*"); return(C_to_Xen_GdkEvent_(gdk_event_copy(Xen_to_C_GdkEvent_(event)))); } static Xen gxg_gdk_event_free(Xen event) { #define H_gdk_event_free "void gdk_event_free(GdkEvent* event)" Xen_check_type(Xen_is_GdkEvent_(event), event, 1, "gdk_event_free", "GdkEvent*"); gdk_event_free(Xen_to_C_GdkEvent_(event)); return(Xen_false); } static Xen gxg_gdk_event_get_time(Xen event) { #define H_gdk_event_get_time "guint32 gdk_event_get_time(GdkEvent* event)" Xen_check_type(Xen_is_GdkEvent_(event) || Xen_is_false(event), event, 1, "gdk_event_get_time", "GdkEvent*"); return(C_to_Xen_guint32(gdk_event_get_time(Xen_to_C_GdkEvent_(event)))); } static Xen gxg_gdk_event_get_state(Xen event, Xen ignore_state) { #define H_gdk_event_get_state "gboolean gdk_event_get_state(GdkEvent* event, GdkModifierType* [state])" GdkModifierType ref_state; Xen_check_type(Xen_is_GdkEvent_(event), event, 1, "gdk_event_get_state", "GdkEvent*"); { Xen result; result = C_to_Xen_gboolean(gdk_event_get_state(Xen_to_C_GdkEvent_(event), &ref_state)); return(Xen_list_2(result, C_to_Xen_GdkModifierType(ref_state))); } } static Xen gxg_gdk_event_get_coords(Xen event, Xen ignore_x_win, Xen ignore_y_win) { #define H_gdk_event_get_coords "gboolean gdk_event_get_coords(GdkEvent* event, gdouble* [x_win], gdouble* [y_win])" gdouble ref_x_win; gdouble ref_y_win; Xen_check_type(Xen_is_GdkEvent_(event), event, 1, "gdk_event_get_coords", "GdkEvent*"); { Xen result; result = C_to_Xen_gboolean(gdk_event_get_coords(Xen_to_C_GdkEvent_(event), &ref_x_win, &ref_y_win)); return(Xen_list_3(result, C_to_Xen_gdouble(ref_x_win), C_to_Xen_gdouble(ref_y_win))); } } static Xen gxg_gdk_event_get_root_coords(Xen event, Xen ignore_x_root, Xen ignore_y_root) { #define H_gdk_event_get_root_coords "gboolean gdk_event_get_root_coords(GdkEvent* event, gdouble* [x_root], \ gdouble* [y_root])" gdouble ref_x_root; gdouble ref_y_root; Xen_check_type(Xen_is_GdkEvent_(event), event, 1, "gdk_event_get_root_coords", "GdkEvent*"); { Xen result; result = C_to_Xen_gboolean(gdk_event_get_root_coords(Xen_to_C_GdkEvent_(event), &ref_x_root, &ref_y_root)); return(Xen_list_3(result, C_to_Xen_gdouble(ref_x_root), C_to_Xen_gdouble(ref_y_root))); } } static Xen gxg_gdk_event_handler_set(Xen func, Xen func_info, Xen notify) { #define H_gdk_event_handler_set "void gdk_event_handler_set(GdkEventFunc func, lambda_data func_info, \ GtkDestroyNotify notify)" Xen_check_type(Xen_is_GdkEventFunc(func), func, 1, "gdk_event_handler_set", "GdkEventFunc"); Xen_check_type(Xen_is_lambda_data(func_info), func_info, 2, "gdk_event_handler_set", "lambda_data"); Xen_check_type(Xen_is_GtkDestroyNotify(notify), notify, 3, "gdk_event_handler_set", "GtkDestroyNotify"); { Xen gxg_ptr = Xen_list_5(func, func_info, Xen_false, Xen_false, Xen_false); xm_protect(gxg_ptr); Xen_list_set(gxg_ptr, 3, notify); gdk_event_handler_set(Xen_to_C_GdkEventFunc(func), Xen_to_C_lambda_data(func_info), Xen_to_C_GtkDestroyNotify(notify)); return(Xen_false); } } static Xen gxg_gdk_set_show_events(Xen show_events) { #define H_gdk_set_show_events "void gdk_set_show_events(gboolean show_events)" Xen_check_type(Xen_is_gboolean(show_events), show_events, 1, "gdk_set_show_events", "gboolean"); gdk_set_show_events(Xen_to_C_gboolean(show_events)); return(Xen_false); } static Xen gxg_gdk_get_show_events(void) { #define H_gdk_get_show_events "gboolean gdk_get_show_events( void)" return(C_to_Xen_gboolean(gdk_get_show_events())); } static Xen gxg_gdk_init(Xen argc, Xen argv) { #define H_gdk_init "void gdk_init(gint* {argc}, gchar*** |argv|)" gint ref_argc; gchar** ref_argv = NULL; ref_argc = Xen_to_C_gint(argc); ref_argv = (gchar**)calloc(ref_argc, sizeof(gchar*)); { int i; Xen lst; lst = Xen_copy_arg(argv); for (i = 0; i < ref_argc; i++, lst = Xen_cdr(lst)) ref_argv[i] = Xen_to_C_gchar_(Xen_car(lst)); } gdk_init(&ref_argc, &ref_argv); return(Xen_list_2(C_to_Xen_gint(ref_argc), C_to_Xen_gchar__(ref_argv))); } static Xen gxg_gdk_init_check(Xen argc, Xen argv) { #define H_gdk_init_check "gboolean gdk_init_check(gint* {argc}, gchar*** |argv|)" gint ref_argc; gchar** ref_argv = NULL; ref_argc = Xen_to_C_gint(argc); ref_argv = (gchar**)calloc(ref_argc, sizeof(gchar*)); { int i; Xen lst; lst = Xen_copy_arg(argv); for (i = 0; i < ref_argc; i++, lst = Xen_cdr(lst)) ref_argv[i] = Xen_to_C_gchar_(Xen_car(lst)); } { Xen result; result = C_to_Xen_gboolean(gdk_init_check(&ref_argc, &ref_argv)); return(Xen_list_3(result, C_to_Xen_gint(ref_argc), C_to_Xen_gchar__(ref_argv))); } } static Xen gxg_gdk_get_program_class(void) { #define H_gdk_get_program_class "char* gdk_get_program_class( void)" return(C_to_Xen_char_(gdk_get_program_class())); } static Xen gxg_gdk_set_program_class(Xen program_class) { #define H_gdk_set_program_class "void gdk_set_program_class(char* program_class)" Xen_check_type(Xen_is_char_(program_class), program_class, 1, "gdk_set_program_class", "char*"); gdk_set_program_class(Xen_to_C_char_(program_class)); return(Xen_false); } static Xen gxg_gdk_error_trap_push(void) { #define H_gdk_error_trap_push "void gdk_error_trap_push( void)" gdk_error_trap_push(); return(Xen_false); } static Xen gxg_gdk_error_trap_pop(void) { #define H_gdk_error_trap_pop "gint gdk_error_trap_pop( void)" return(C_to_Xen_gint(gdk_error_trap_pop())); } static Xen gxg_gdk_get_display_arg_name(void) { #define H_gdk_get_display_arg_name "gchar* gdk_get_display_arg_name( void)" return(C_to_Xen_gchar_(gdk_get_display_arg_name())); } static Xen gxg_gdk_notify_startup_complete(void) { #define H_gdk_notify_startup_complete "void gdk_notify_startup_complete( void)" gdk_notify_startup_complete(); return(Xen_false); } static Xen gxg_gdk_screen_width(void) { #define H_gdk_screen_width "gint gdk_screen_width( void)" return(C_to_Xen_gint(gdk_screen_width())); } static Xen gxg_gdk_screen_height(void) { #define H_gdk_screen_height "gint gdk_screen_height( void)" return(C_to_Xen_gint(gdk_screen_height())); } static Xen gxg_gdk_screen_width_mm(void) { #define H_gdk_screen_width_mm "gint gdk_screen_width_mm( void)" return(C_to_Xen_gint(gdk_screen_width_mm())); } static Xen gxg_gdk_screen_height_mm(void) { #define H_gdk_screen_height_mm "gint gdk_screen_height_mm( void)" return(C_to_Xen_gint(gdk_screen_height_mm())); } static Xen gxg_gdk_flush(void) { #define H_gdk_flush "void gdk_flush( void)" gdk_flush(); return(Xen_false); } static Xen gxg_gdk_beep(void) { #define H_gdk_beep "void gdk_beep( void)" gdk_beep(); return(Xen_false); } static Xen gxg_gdk_set_double_click_time(Xen msec) { #define H_gdk_set_double_click_time "void gdk_set_double_click_time(guint msec)" Xen_check_type(Xen_is_guint(msec), msec, 1, "gdk_set_double_click_time", "guint"); gdk_set_double_click_time(Xen_to_C_guint(msec)); return(Xen_false); } static Xen gxg_gdk_rectangle_intersect(Xen src1, Xen src2, Xen dest) { #define H_gdk_rectangle_intersect "gboolean gdk_rectangle_intersect(GdkRectangle* src1, GdkRectangle* src2, \ GdkRectangle* dest)" Xen_check_type(Xen_is_GdkRectangle_(src1), src1, 1, "gdk_rectangle_intersect", "GdkRectangle*"); Xen_check_type(Xen_is_GdkRectangle_(src2), src2, 2, "gdk_rectangle_intersect", "GdkRectangle*"); Xen_check_type(Xen_is_GdkRectangle_(dest), dest, 3, "gdk_rectangle_intersect", "GdkRectangle*"); return(C_to_Xen_gboolean(gdk_rectangle_intersect(Xen_to_C_GdkRectangle_(src1), Xen_to_C_GdkRectangle_(src2), Xen_to_C_GdkRectangle_(dest)))); } static Xen gxg_gdk_rectangle_union(Xen src1, Xen src2, Xen dest) { #define H_gdk_rectangle_union "void gdk_rectangle_union(GdkRectangle* src1, GdkRectangle* src2, GdkRectangle* dest)" Xen_check_type(Xen_is_GdkRectangle_(src1), src1, 1, "gdk_rectangle_union", "GdkRectangle*"); Xen_check_type(Xen_is_GdkRectangle_(src2), src2, 2, "gdk_rectangle_union", "GdkRectangle*"); Xen_check_type(Xen_is_GdkRectangle_(dest), dest, 3, "gdk_rectangle_union", "GdkRectangle*"); gdk_rectangle_union(Xen_to_C_GdkRectangle_(src1), Xen_to_C_GdkRectangle_(src2), Xen_to_C_GdkRectangle_(dest)); return(Xen_false); } static Xen gxg_gdk_keymap_get_default(void) { #define H_gdk_keymap_get_default "GdkKeymap* gdk_keymap_get_default( void)" return(C_to_Xen_GdkKeymap_(gdk_keymap_get_default())); } static Xen gxg_gdk_keymap_lookup_key(Xen keymap, Xen key) { #define H_gdk_keymap_lookup_key "guint gdk_keymap_lookup_key(GdkKeymap* keymap, GdkKeymapKey* key)" Xen_check_type(Xen_is_GdkKeymap_(keymap), keymap, 1, "gdk_keymap_lookup_key", "GdkKeymap*"); Xen_check_type(Xen_is_GdkKeymapKey_(key), key, 2, "gdk_keymap_lookup_key", "GdkKeymapKey*"); return(C_to_Xen_guint(gdk_keymap_lookup_key(Xen_to_C_GdkKeymap_(keymap), Xen_to_C_GdkKeymapKey_(key)))); } static Xen gxg_gdk_keymap_get_entries_for_keyval(Xen keymap, Xen keyval, Xen ignore_keys, Xen ignore_n_keys) { #define H_gdk_keymap_get_entries_for_keyval "gboolean gdk_keymap_get_entries_for_keyval(GdkKeymap* keymap, \ guint keyval, GdkKeymapKey** [keys], gint* [n_keys])" GdkKeymapKey* ref_keys = NULL; gint ref_n_keys; Xen_check_type(Xen_is_GdkKeymap_(keymap), keymap, 1, "gdk_keymap_get_entries_for_keyval", "GdkKeymap*"); Xen_check_type(Xen_is_guint(keyval), keyval, 2, "gdk_keymap_get_entries_for_keyval", "guint"); { Xen result; result = C_to_Xen_gboolean(gdk_keymap_get_entries_for_keyval(Xen_to_C_GdkKeymap_(keymap), Xen_to_C_guint(keyval), &ref_keys, &ref_n_keys)); return(Xen_list_3(result, C_to_Xen_GdkKeymapKey_(ref_keys), C_to_Xen_gint(ref_n_keys))); } } static Xen gxg_gdk_keymap_get_entries_for_keycode(Xen keymap, Xen hardware_keycode, Xen ignore_keys, Xen ignore_keyvals, Xen ignore_n_entries) { #define H_gdk_keymap_get_entries_for_keycode "gboolean gdk_keymap_get_entries_for_keycode(GdkKeymap* keymap, \ guint hardware_keycode, GdkKeymapKey** [keys], guint** [keyvals], gint* [n_entries])" GdkKeymapKey* ref_keys = NULL; guint* ref_keyvals = NULL; gint ref_n_entries; Xen_check_type(Xen_is_GdkKeymap_(keymap), keymap, 1, "gdk_keymap_get_entries_for_keycode", "GdkKeymap*"); Xen_check_type(Xen_is_guint(hardware_keycode), hardware_keycode, 2, "gdk_keymap_get_entries_for_keycode", "guint"); { Xen result; result = C_to_Xen_gboolean(gdk_keymap_get_entries_for_keycode(Xen_to_C_GdkKeymap_(keymap), Xen_to_C_guint(hardware_keycode), &ref_keys, &ref_keyvals, &ref_n_entries)); return(Xen_list_4(result, C_to_Xen_GdkKeymapKey_(ref_keys), C_to_Xen_guint_(ref_keyvals), C_to_Xen_gint(ref_n_entries))); } } static Xen gxg_gdk_keymap_get_direction(Xen keymap) { #define H_gdk_keymap_get_direction "PangoDirection gdk_keymap_get_direction(GdkKeymap* keymap)" Xen_check_type(Xen_is_GdkKeymap_(keymap), keymap, 1, "gdk_keymap_get_direction", "GdkKeymap*"); return(C_to_Xen_PangoDirection(gdk_keymap_get_direction(Xen_to_C_GdkKeymap_(keymap)))); } static Xen gxg_gdk_keyval_name(Xen keyval) { #define H_gdk_keyval_name "gchar* gdk_keyval_name(guint keyval)" Xen_check_type(Xen_is_guint(keyval), keyval, 1, "gdk_keyval_name", "guint"); return(C_to_Xen_gchar_(gdk_keyval_name(Xen_to_C_guint(keyval)))); } static Xen gxg_gdk_keyval_from_name(Xen keyval_name) { #define H_gdk_keyval_from_name "guint gdk_keyval_from_name(gchar* keyval_name)" Xen_check_type(Xen_is_gchar_(keyval_name), keyval_name, 1, "gdk_keyval_from_name", "gchar*"); return(C_to_Xen_guint(gdk_keyval_from_name(Xen_to_C_gchar_(keyval_name)))); } static Xen gxg_gdk_keyval_convert_case(Xen symbol, Xen ignore_lower, Xen ignore_upper) { #define H_gdk_keyval_convert_case "void gdk_keyval_convert_case(guint symbol, guint* [lower], guint* [upper])" guint ref_lower; guint ref_upper; Xen_check_type(Xen_is_guint(symbol), symbol, 1, "gdk_keyval_convert_case", "guint"); gdk_keyval_convert_case(Xen_to_C_guint(symbol), &ref_lower, &ref_upper); return(Xen_list_2(C_to_Xen_guint(ref_lower), C_to_Xen_guint(ref_upper))); } static Xen gxg_gdk_keyval_to_upper(Xen keyval) { #define H_gdk_keyval_to_upper "guint gdk_keyval_to_upper(guint keyval)" Xen_check_type(Xen_is_guint(keyval), keyval, 1, "gdk_keyval_to_upper", "guint"); return(C_to_Xen_guint(gdk_keyval_to_upper(Xen_to_C_guint(keyval)))); } static Xen gxg_gdk_keyval_to_lower(Xen keyval) { #define H_gdk_keyval_to_lower "guint gdk_keyval_to_lower(guint keyval)" Xen_check_type(Xen_is_guint(keyval), keyval, 1, "gdk_keyval_to_lower", "guint"); return(C_to_Xen_guint(gdk_keyval_to_lower(Xen_to_C_guint(keyval)))); } static Xen gxg_gdk_keyval_is_upper(Xen keyval) { #define H_gdk_keyval_is_upper "gboolean gdk_keyval_is_upper(guint keyval)" Xen_check_type(Xen_is_guint(keyval), keyval, 1, "gdk_keyval_is_upper", "guint"); return(C_to_Xen_gboolean(gdk_keyval_is_upper(Xen_to_C_guint(keyval)))); } static Xen gxg_gdk_keyval_is_lower(Xen keyval) { #define H_gdk_keyval_is_lower "gboolean gdk_keyval_is_lower(guint keyval)" Xen_check_type(Xen_is_guint(keyval), keyval, 1, "gdk_keyval_is_lower", "guint"); return(C_to_Xen_gboolean(gdk_keyval_is_lower(Xen_to_C_guint(keyval)))); } static Xen gxg_gdk_keyval_to_unicode(Xen keyval) { #define H_gdk_keyval_to_unicode "guint32 gdk_keyval_to_unicode(guint keyval)" Xen_check_type(Xen_is_guint(keyval), keyval, 1, "gdk_keyval_to_unicode", "guint"); return(C_to_Xen_guint32(gdk_keyval_to_unicode(Xen_to_C_guint(keyval)))); } static Xen gxg_gdk_unicode_to_keyval(Xen wc) { #define H_gdk_unicode_to_keyval "guint gdk_unicode_to_keyval(guint32 wc)" Xen_check_type(Xen_is_guint32(wc), wc, 1, "gdk_unicode_to_keyval", "guint32"); return(C_to_Xen_guint(gdk_unicode_to_keyval(Xen_to_C_guint32(wc)))); } static Xen gxg_gdk_pango_context_get(void) { #define H_gdk_pango_context_get "PangoContext* gdk_pango_context_get( void)" return(C_to_Xen_PangoContext_(gdk_pango_context_get())); } static Xen gxg_gdk_atom_intern(Xen atom_name, Xen only_if_exists) { #define H_gdk_atom_intern "GdkAtom gdk_atom_intern(gchar* atom_name, gboolean only_if_exists)" Xen_check_type(Xen_is_gchar_(atom_name), atom_name, 1, "gdk_atom_intern", "gchar*"); Xen_check_type(Xen_is_gboolean(only_if_exists), only_if_exists, 2, "gdk_atom_intern", "gboolean"); return(C_to_Xen_GdkAtom(gdk_atom_intern(Xen_to_C_gchar_(atom_name), Xen_to_C_gboolean(only_if_exists)))); } static Xen gxg_gdk_atom_name(Xen atom) { #define H_gdk_atom_name "gchar* gdk_atom_name(GdkAtom atom)" Xen_check_type(Xen_is_GdkAtom(atom), atom, 1, "gdk_atom_name", "GdkAtom"); { gchar* result; Xen rtn; result = gdk_atom_name(Xen_to_C_GdkAtom(atom)); rtn = C_to_Xen_gchar_(result); g_free(result); return(rtn); } } static Xen gxg_gdk_property_get(Xen arglist) { #define H_gdk_property_get "gboolean gdk_property_get(GdkWindow* window, GdkAtom property, GdkAtom type, \ gulong offset, gulong length, gint pdelete, GdkAtom* [actual_property_type], gint* [actual_format], gint* [actual_length], \ guchar** [data])" GdkAtom ref_actual_property_type; gint ref_actual_format; gint ref_actual_length; guchar* ref_data = NULL; Xen window, property, type, offset, length, pdelete; window = Xen_list_ref(arglist, 0); property = Xen_list_ref(arglist, 1); type = Xen_list_ref(arglist, 2); offset = Xen_list_ref(arglist, 3); length = Xen_list_ref(arglist, 4); pdelete = Xen_list_ref(arglist, 5); Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_property_get", "GdkWindow*"); Xen_check_type(Xen_is_GdkAtom(property), property, 2, "gdk_property_get", "GdkAtom"); Xen_check_type(Xen_is_GdkAtom(type), type, 3, "gdk_property_get", "GdkAtom"); Xen_check_type(Xen_is_gulong(offset), offset, 4, "gdk_property_get", "gulong"); Xen_check_type(Xen_is_gulong(length), length, 5, "gdk_property_get", "gulong"); Xen_check_type(Xen_is_gint(pdelete), pdelete, 6, "gdk_property_get", "gint"); { Xen result; result = C_to_Xen_gboolean(gdk_property_get(Xen_to_C_GdkWindow_(window), Xen_to_C_GdkAtom(property), Xen_to_C_GdkAtom(type), Xen_to_C_gulong(offset), Xen_to_C_gulong(length), Xen_to_C_gint(pdelete), &ref_actual_property_type, &ref_actual_format, &ref_actual_length, &ref_data)); { Xen data_val = Xen_false; if (ref_actual_property_type == GDK_TARGET_STRING) data_val = C_string_to_Xen_string((char *)ref_data); else if (ref_actual_length > 0) data_val = C_string_to_Xen_string_with_length((char *)ref_data, ref_actual_length * ref_actual_format / 8); return(Xen_list_5(result, C_to_Xen_GdkAtom(ref_actual_property_type), C_to_Xen_gint(ref_actual_format), C_to_Xen_gint(ref_actual_length), data_val)); } } } static Xen gxg_gdk_property_change(Xen window, Xen property, Xen type, Xen format, Xen mode, Xen data, Xen nelements) { #define H_gdk_property_change "void gdk_property_change(GdkWindow* window, GdkAtom property, GdkAtom type, \ gint format, GdkPropMode mode, guchar* data, gint nelements)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_property_change", "GdkWindow*"); Xen_check_type(Xen_is_GdkAtom(property), property, 2, "gdk_property_change", "GdkAtom"); Xen_check_type(Xen_is_GdkAtom(type), type, 3, "gdk_property_change", "GdkAtom"); Xen_check_type(Xen_is_gint(format), format, 4, "gdk_property_change", "gint"); Xen_check_type(Xen_is_GdkPropMode(mode), mode, 5, "gdk_property_change", "GdkPropMode"); Xen_check_type(Xen_is_guchar_(data), data, 6, "gdk_property_change", "guchar*"); Xen_check_type(Xen_is_gint(nelements), nelements, 7, "gdk_property_change", "gint"); gdk_property_change(Xen_to_C_GdkWindow_(window), Xen_to_C_GdkAtom(property), Xen_to_C_GdkAtom(type), Xen_to_C_gint(format), Xen_to_C_GdkPropMode(mode), Xen_to_C_guchar_(data), Xen_to_C_gint(nelements)); return(Xen_false); } static Xen gxg_gdk_property_delete(Xen window, Xen property) { #define H_gdk_property_delete "void gdk_property_delete(GdkWindow* window, GdkAtom property)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_property_delete", "GdkWindow*"); Xen_check_type(Xen_is_GdkAtom(property), property, 2, "gdk_property_delete", "GdkAtom"); gdk_property_delete(Xen_to_C_GdkWindow_(window), Xen_to_C_GdkAtom(property)); return(Xen_false); } static Xen gxg_gdk_utf8_to_string_target(Xen str) { #define H_gdk_utf8_to_string_target "gchar* gdk_utf8_to_string_target(gchar* str)" Xen_check_type(Xen_is_gchar_(str), str, 1, "gdk_utf8_to_string_target", "gchar*"); { gchar* result; Xen rtn; result = gdk_utf8_to_string_target(Xen_to_C_gchar_(str)); rtn = C_to_Xen_gchar_(result); g_free(result); return(rtn); } } static Xen gxg_gdk_selection_owner_set(Xen owner, Xen selection, Xen time, Xen send_event) { #define H_gdk_selection_owner_set "gboolean gdk_selection_owner_set(GdkWindow* owner, GdkAtom selection, \ guint32 time, gboolean send_event)" Xen_check_type(Xen_is_GdkWindow_(owner), owner, 1, "gdk_selection_owner_set", "GdkWindow*"); Xen_check_type(Xen_is_GdkAtom(selection), selection, 2, "gdk_selection_owner_set", "GdkAtom"); Xen_check_type(Xen_is_guint32(time), time, 3, "gdk_selection_owner_set", "guint32"); Xen_check_type(Xen_is_gboolean(send_event), send_event, 4, "gdk_selection_owner_set", "gboolean"); return(C_to_Xen_gboolean(gdk_selection_owner_set(Xen_to_C_GdkWindow_(owner), Xen_to_C_GdkAtom(selection), Xen_to_C_guint32(time), Xen_to_C_gboolean(send_event)))); } static Xen gxg_gdk_selection_owner_get(Xen selection) { #define H_gdk_selection_owner_get "GdkWindow* gdk_selection_owner_get(GdkAtom selection)" Xen_check_type(Xen_is_GdkAtom(selection), selection, 1, "gdk_selection_owner_get", "GdkAtom"); return(C_to_Xen_GdkWindow_(gdk_selection_owner_get(Xen_to_C_GdkAtom(selection)))); } static Xen gxg_gdk_selection_convert(Xen requestor, Xen selection, Xen target, Xen time) { #define H_gdk_selection_convert "void gdk_selection_convert(GdkWindow* requestor, GdkAtom selection, \ GdkAtom target, guint32 time)" Xen_check_type(Xen_is_GdkWindow_(requestor), requestor, 1, "gdk_selection_convert", "GdkWindow*"); Xen_check_type(Xen_is_GdkAtom(selection), selection, 2, "gdk_selection_convert", "GdkAtom"); Xen_check_type(Xen_is_GdkAtom(target), target, 3, "gdk_selection_convert", "GdkAtom"); Xen_check_type(Xen_is_guint32(time), time, 4, "gdk_selection_convert", "guint32"); gdk_selection_convert(Xen_to_C_GdkWindow_(requestor), Xen_to_C_GdkAtom(selection), Xen_to_C_GdkAtom(target), Xen_to_C_guint32(time)); return(Xen_false); } static Xen gxg_gdk_selection_property_get(Xen requestor, Xen ignore_data, Xen ignore_prop_type, Xen ignore_prop_format) { #define H_gdk_selection_property_get "gboolean gdk_selection_property_get(GdkWindow* requestor, guchar** [data], \ GdkAtom* [prop_type], gint* [prop_format])" guchar* ref_data = NULL; GdkAtom ref_prop_type; gint ref_prop_format; Xen_check_type(Xen_is_GdkWindow_(requestor), requestor, 1, "gdk_selection_property_get", "GdkWindow*"); { Xen result; result = C_to_Xen_gboolean(gdk_selection_property_get(Xen_to_C_GdkWindow_(requestor), &ref_data, &ref_prop_type, &ref_prop_format)); return(Xen_list_4(result, C_to_Xen_guchar_(ref_data), C_to_Xen_GdkAtom(ref_prop_type), C_to_Xen_gint(ref_prop_format))); } } static Xen gxg_gdk_visual_get_best_depth(void) { #define H_gdk_visual_get_best_depth "gint gdk_visual_get_best_depth( void)" return(C_to_Xen_gint(gdk_visual_get_best_depth())); } static Xen gxg_gdk_visual_get_best_type(void) { #define H_gdk_visual_get_best_type "GdkVisualType gdk_visual_get_best_type( void)" return(C_to_Xen_GdkVisualType(gdk_visual_get_best_type())); } static Xen gxg_gdk_visual_get_best(void) { #define H_gdk_visual_get_best "GdkVisual* gdk_visual_get_best( void)" return(C_to_Xen_GdkVisual_(gdk_visual_get_best())); } static Xen gxg_gdk_visual_get_best_with_depth(Xen depth) { #define H_gdk_visual_get_best_with_depth "GdkVisual* gdk_visual_get_best_with_depth(gint depth)" Xen_check_type(Xen_is_gint(depth), depth, 1, "gdk_visual_get_best_with_depth", "gint"); return(C_to_Xen_GdkVisual_(gdk_visual_get_best_with_depth(Xen_to_C_gint(depth)))); } static Xen gxg_gdk_visual_get_best_with_type(Xen visual_type) { #define H_gdk_visual_get_best_with_type "GdkVisual* gdk_visual_get_best_with_type(GdkVisualType visual_type)" Xen_check_type(Xen_is_GdkVisualType(visual_type), visual_type, 1, "gdk_visual_get_best_with_type", "GdkVisualType"); return(C_to_Xen_GdkVisual_(gdk_visual_get_best_with_type(Xen_to_C_GdkVisualType(visual_type)))); } static Xen gxg_gdk_visual_get_best_with_both(Xen depth, Xen visual_type) { #define H_gdk_visual_get_best_with_both "GdkVisual* gdk_visual_get_best_with_both(gint depth, GdkVisualType visual_type)" Xen_check_type(Xen_is_gint(depth), depth, 1, "gdk_visual_get_best_with_both", "gint"); Xen_check_type(Xen_is_GdkVisualType(visual_type), visual_type, 2, "gdk_visual_get_best_with_both", "GdkVisualType"); return(C_to_Xen_GdkVisual_(gdk_visual_get_best_with_both(Xen_to_C_gint(depth), Xen_to_C_GdkVisualType(visual_type)))); } static Xen gxg_gdk_query_depths(Xen ignore_depths, Xen ignore_count) { #define H_gdk_query_depths "void gdk_query_depths(gint** [depths], gint* [count])" gint* ref_depths = NULL; gint ref_count; gdk_query_depths(&ref_depths, &ref_count); return(Xen_list_2(C_to_Xen_gint_(ref_depths), C_to_Xen_gint(ref_count))); } static Xen gxg_gdk_query_visual_types(Xen ignore_visual_types, Xen ignore_count) { #define H_gdk_query_visual_types "void gdk_query_visual_types(GdkVisualType** [visual_types], gint* [count])" GdkVisualType* ref_visual_types = NULL; gint ref_count; gdk_query_visual_types(&ref_visual_types, &ref_count); return(Xen_list_2(C_to_Xen_GdkVisualType_(ref_visual_types), C_to_Xen_gint(ref_count))); } static Xen gxg_gdk_list_visuals(void) { #define H_gdk_list_visuals "GList* gdk_list_visuals( void)" return(C_to_Xen_GList_(gdk_list_visuals())); } static Xen gxg_gdk_window_new(Xen parent, Xen attributes, Xen attributes_mask) { #define H_gdk_window_new "GdkWindow* gdk_window_new(GdkWindow* parent, GdkWindowAttr* attributes, gint attributes_mask)" Xen_check_type(Xen_is_GdkWindow_(parent), parent, 1, "gdk_window_new", "GdkWindow*"); Xen_check_type(Xen_is_GdkWindowAttr_(attributes), attributes, 2, "gdk_window_new", "GdkWindowAttr*"); Xen_check_type(Xen_is_gint(attributes_mask), attributes_mask, 3, "gdk_window_new", "gint"); return(C_to_Xen_GdkWindow_(gdk_window_new(Xen_to_C_GdkWindow_(parent), Xen_to_C_GdkWindowAttr_(attributes), Xen_to_C_gint(attributes_mask)))); } static Xen gxg_gdk_window_destroy(Xen window) { #define H_gdk_window_destroy "void gdk_window_destroy(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_destroy", "GdkWindow*"); gdk_window_destroy(Xen_to_C_GdkWindow_(window)); return(Xen_false); } static Xen gxg_gdk_window_get_window_type(Xen window) { #define H_gdk_window_get_window_type "GdkWindowType gdk_window_get_window_type(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_get_window_type", "GdkWindow*"); return(C_to_Xen_GdkWindowType(gdk_window_get_window_type(Xen_to_C_GdkWindow_(window)))); } static Xen gxg_gdk_window_show(Xen window) { #define H_gdk_window_show "void gdk_window_show(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_show", "GdkWindow*"); gdk_window_show(Xen_to_C_GdkWindow_(window)); return(Xen_false); } static Xen gxg_gdk_window_hide(Xen window) { #define H_gdk_window_hide "void gdk_window_hide(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_hide", "GdkWindow*"); gdk_window_hide(Xen_to_C_GdkWindow_(window)); return(Xen_false); } static Xen gxg_gdk_window_withdraw(Xen window) { #define H_gdk_window_withdraw "void gdk_window_withdraw(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_withdraw", "GdkWindow*"); gdk_window_withdraw(Xen_to_C_GdkWindow_(window)); return(Xen_false); } static Xen gxg_gdk_window_show_unraised(Xen window) { #define H_gdk_window_show_unraised "void gdk_window_show_unraised(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_show_unraised", "GdkWindow*"); gdk_window_show_unraised(Xen_to_C_GdkWindow_(window)); return(Xen_false); } static Xen gxg_gdk_window_move(Xen window, Xen x, Xen y) { #define H_gdk_window_move "void gdk_window_move(GdkWindow* window, gint x, gint y)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_move", "GdkWindow*"); Xen_check_type(Xen_is_gint(x), x, 2, "gdk_window_move", "gint"); Xen_check_type(Xen_is_gint(y), y, 3, "gdk_window_move", "gint"); gdk_window_move(Xen_to_C_GdkWindow_(window), Xen_to_C_gint(x), Xen_to_C_gint(y)); return(Xen_false); } static Xen gxg_gdk_window_resize(Xen window, Xen width, Xen height) { #define H_gdk_window_resize "void gdk_window_resize(GdkWindow* window, gint width, gint height)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_resize", "GdkWindow*"); Xen_check_type(Xen_is_gint(width), width, 2, "gdk_window_resize", "gint"); Xen_check_type(Xen_is_gint(height), height, 3, "gdk_window_resize", "gint"); gdk_window_resize(Xen_to_C_GdkWindow_(window), Xen_to_C_gint(width), Xen_to_C_gint(height)); return(Xen_false); } static Xen gxg_gdk_window_move_resize(Xen window, Xen x, Xen y, Xen width, Xen height) { #define H_gdk_window_move_resize "void gdk_window_move_resize(GdkWindow* window, gint x, gint y, gint width, \ gint height)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_move_resize", "GdkWindow*"); Xen_check_type(Xen_is_gint(x), x, 2, "gdk_window_move_resize", "gint"); Xen_check_type(Xen_is_gint(y), y, 3, "gdk_window_move_resize", "gint"); Xen_check_type(Xen_is_gint(width), width, 4, "gdk_window_move_resize", "gint"); Xen_check_type(Xen_is_gint(height), height, 5, "gdk_window_move_resize", "gint"); gdk_window_move_resize(Xen_to_C_GdkWindow_(window), Xen_to_C_gint(x), Xen_to_C_gint(y), Xen_to_C_gint(width), Xen_to_C_gint(height)); return(Xen_false); } static Xen gxg_gdk_window_reparent(Xen window, Xen new_parent, Xen x, Xen y) { #define H_gdk_window_reparent "void gdk_window_reparent(GdkWindow* window, GdkWindow* new_parent, gint x, \ gint y)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_reparent", "GdkWindow*"); Xen_check_type(Xen_is_GdkWindow_(new_parent), new_parent, 2, "gdk_window_reparent", "GdkWindow*"); Xen_check_type(Xen_is_gint(x), x, 3, "gdk_window_reparent", "gint"); Xen_check_type(Xen_is_gint(y), y, 4, "gdk_window_reparent", "gint"); gdk_window_reparent(Xen_to_C_GdkWindow_(window), Xen_to_C_GdkWindow_(new_parent), Xen_to_C_gint(x), Xen_to_C_gint(y)); return(Xen_false); } static Xen gxg_gdk_window_raise(Xen window) { #define H_gdk_window_raise "void gdk_window_raise(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_raise", "GdkWindow*"); gdk_window_raise(Xen_to_C_GdkWindow_(window)); return(Xen_false); } static Xen gxg_gdk_window_lower(Xen window) { #define H_gdk_window_lower "void gdk_window_lower(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_lower", "GdkWindow*"); gdk_window_lower(Xen_to_C_GdkWindow_(window)); return(Xen_false); } static Xen gxg_gdk_window_focus(Xen window, Xen timestamp) { #define H_gdk_window_focus "void gdk_window_focus(GdkWindow* window, guint32 timestamp)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_focus", "GdkWindow*"); Xen_check_type(Xen_is_guint32(timestamp), timestamp, 2, "gdk_window_focus", "guint32"); gdk_window_focus(Xen_to_C_GdkWindow_(window), Xen_to_C_guint32(timestamp)); return(Xen_false); } static Xen gxg_gdk_window_set_user_data(Xen window, Xen user_data) { #define H_gdk_window_set_user_data "void gdk_window_set_user_data(GdkWindow* window, gpointer user_data)" Xen_check_type(Xen_is_GdkWindow_(window) || Xen_is_false(window), window, 1, "gdk_window_set_user_data", "GdkWindow*"); Xen_check_type(Xen_is_gpointer(user_data), user_data, 2, "gdk_window_set_user_data", "gpointer"); gdk_window_set_user_data(Xen_to_C_GdkWindow_(window), Xen_to_C_gpointer(user_data)); return(Xen_false); } static Xen gxg_gdk_window_set_override_redirect(Xen window, Xen override_redirect) { #define H_gdk_window_set_override_redirect "void gdk_window_set_override_redirect(GdkWindow* window, \ gboolean override_redirect)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_set_override_redirect", "GdkWindow*"); Xen_check_type(Xen_is_gboolean(override_redirect), override_redirect, 2, "gdk_window_set_override_redirect", "gboolean"); gdk_window_set_override_redirect(Xen_to_C_GdkWindow_(window), Xen_to_C_gboolean(override_redirect)); return(Xen_false); } static Xen gxg_gdk_window_add_filter(Xen window, Xen func, Xen func_info) { #define H_gdk_window_add_filter "void gdk_window_add_filter(GdkWindow* window, GdkFilterFunc func, \ lambda_data func_info)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_add_filter", "GdkWindow*"); Xen_check_type(Xen_is_GdkFilterFunc(func), func, 2, "gdk_window_add_filter", "GdkFilterFunc"); if (!Xen_is_bound(func_info)) func_info = Xen_false; else Xen_check_type(Xen_is_lambda_data(func_info), func_info, 3, "gdk_window_add_filter", "lambda_data"); { Xen gxg_ptr = Xen_list_5(func, func_info, Xen_false, Xen_false, Xen_false); xm_protect(gxg_ptr); gdk_window_add_filter(Xen_to_C_GdkWindow_(window), Xen_to_C_GdkFilterFunc(func), Xen_to_C_lambda_data(func_info)); return(Xen_false); } } static Xen gxg_gdk_window_remove_filter(Xen window, Xen func, Xen func_info) { #define H_gdk_window_remove_filter "void gdk_window_remove_filter(GdkWindow* window, GdkFilterFunc func, \ lambda_data func_info)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_remove_filter", "GdkWindow*"); Xen_check_type(Xen_is_GdkFilterFunc(func), func, 2, "gdk_window_remove_filter", "GdkFilterFunc"); if (!Xen_is_bound(func_info)) func_info = Xen_false; else Xen_check_type(Xen_is_lambda_data(func_info), func_info, 3, "gdk_window_remove_filter", "lambda_data"); { Xen gxg_ptr = Xen_list_5(func, func_info, Xen_false, Xen_false, Xen_false); xm_protect(gxg_ptr); gdk_window_remove_filter(Xen_to_C_GdkWindow_(window), Xen_to_C_GdkFilterFunc(func), Xen_to_C_lambda_data(func_info)); return(Xen_false); } } static Xen gxg_gdk_window_scroll(Xen window, Xen dx, Xen dy) { #define H_gdk_window_scroll "void gdk_window_scroll(GdkWindow* window, gint dx, gint dy)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_scroll", "GdkWindow*"); Xen_check_type(Xen_is_gint(dx), dx, 2, "gdk_window_scroll", "gint"); Xen_check_type(Xen_is_gint(dy), dy, 3, "gdk_window_scroll", "gint"); gdk_window_scroll(Xen_to_C_GdkWindow_(window), Xen_to_C_gint(dx), Xen_to_C_gint(dy)); return(Xen_false); } static Xen gxg_gdk_window_set_child_shapes(Xen window) { #define H_gdk_window_set_child_shapes "void gdk_window_set_child_shapes(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_set_child_shapes", "GdkWindow*"); gdk_window_set_child_shapes(Xen_to_C_GdkWindow_(window)); return(Xen_false); } static Xen gxg_gdk_window_merge_child_shapes(Xen window) { #define H_gdk_window_merge_child_shapes "void gdk_window_merge_child_shapes(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_merge_child_shapes", "GdkWindow*"); gdk_window_merge_child_shapes(Xen_to_C_GdkWindow_(window)); return(Xen_false); } static Xen gxg_gdk_window_is_visible(Xen window) { #define H_gdk_window_is_visible "gboolean gdk_window_is_visible(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_is_visible", "GdkWindow*"); return(C_to_Xen_gboolean(gdk_window_is_visible(Xen_to_C_GdkWindow_(window)))); } static Xen gxg_gdk_window_is_viewable(Xen window) { #define H_gdk_window_is_viewable "gboolean gdk_window_is_viewable(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_is_viewable", "GdkWindow*"); return(C_to_Xen_gboolean(gdk_window_is_viewable(Xen_to_C_GdkWindow_(window)))); } static Xen gxg_gdk_window_get_state(Xen window) { #define H_gdk_window_get_state "GdkWindowState gdk_window_get_state(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_get_state", "GdkWindow*"); return(C_to_Xen_GdkWindowState(gdk_window_get_state(Xen_to_C_GdkWindow_(window)))); } static Xen gxg_gdk_window_get_root_origin(Xen window, Xen ignore_x, Xen ignore_y) { #define H_gdk_window_get_root_origin "void gdk_window_get_root_origin(GdkWindow* window, gint* [x], \ gint* [y])" gint ref_x; gint ref_y; Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_get_root_origin", "GdkWindow*"); gdk_window_get_root_origin(Xen_to_C_GdkWindow_(window), &ref_x, &ref_y); return(Xen_list_2(C_to_Xen_gint(ref_x), C_to_Xen_gint(ref_y))); } static Xen gxg_gdk_window_get_frame_extents(Xen window, Xen rect) { #define H_gdk_window_get_frame_extents "void gdk_window_get_frame_extents(GdkWindow* window, GdkRectangle* rect)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_get_frame_extents", "GdkWindow*"); Xen_check_type(Xen_is_GdkRectangle_(rect), rect, 2, "gdk_window_get_frame_extents", "GdkRectangle*"); gdk_window_get_frame_extents(Xen_to_C_GdkWindow_(window), Xen_to_C_GdkRectangle_(rect)); return(Xen_false); } static Xen gxg_gdk_window_get_parent(Xen window) { #define H_gdk_window_get_parent "GdkWindow* gdk_window_get_parent(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_get_parent", "GdkWindow*"); return(C_to_Xen_GdkWindow_(gdk_window_get_parent(Xen_to_C_GdkWindow_(window)))); } static Xen gxg_gdk_window_get_toplevel(Xen window) { #define H_gdk_window_get_toplevel "GdkWindow* gdk_window_get_toplevel(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_get_toplevel", "GdkWindow*"); return(C_to_Xen_GdkWindow_(gdk_window_get_toplevel(Xen_to_C_GdkWindow_(window)))); } static Xen gxg_gdk_window_get_children(Xen window) { #define H_gdk_window_get_children "GList* gdk_window_get_children(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_get_children", "GdkWindow*"); return(C_to_Xen_GList_(gdk_window_get_children(Xen_to_C_GdkWindow_(window)))); } static Xen gxg_gdk_window_peek_children(Xen window) { #define H_gdk_window_peek_children "GList* gdk_window_peek_children(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_peek_children", "GdkWindow*"); return(C_to_Xen_GList_(gdk_window_peek_children(Xen_to_C_GdkWindow_(window)))); } static Xen gxg_gdk_window_get_events(Xen window) { #define H_gdk_window_get_events "GdkEventMask gdk_window_get_events(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_get_events", "GdkWindow*"); return(C_to_Xen_GdkEventMask(gdk_window_get_events(Xen_to_C_GdkWindow_(window)))); } static Xen gxg_gdk_window_set_events(Xen window, Xen event_mask) { #define H_gdk_window_set_events "void gdk_window_set_events(GdkWindow* window, GdkEventMask event_mask)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_set_events", "GdkWindow*"); Xen_check_type(Xen_is_GdkEventMask(event_mask), event_mask, 2, "gdk_window_set_events", "GdkEventMask"); gdk_window_set_events(Xen_to_C_GdkWindow_(window), Xen_to_C_GdkEventMask(event_mask)); return(Xen_false); } static Xen gxg_gdk_window_set_icon_list(Xen window, Xen pixbufs) { #define H_gdk_window_set_icon_list "void gdk_window_set_icon_list(GdkWindow* window, GList* pixbufs)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_set_icon_list", "GdkWindow*"); Xen_check_type(Xen_is_GList_(pixbufs), pixbufs, 2, "gdk_window_set_icon_list", "GList*"); gdk_window_set_icon_list(Xen_to_C_GdkWindow_(window), Xen_to_C_GList_(pixbufs)); return(Xen_false); } static Xen gxg_gdk_window_set_icon_name(Xen window, Xen name) { #define H_gdk_window_set_icon_name "void gdk_window_set_icon_name(GdkWindow* window, gchar* name)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_set_icon_name", "GdkWindow*"); Xen_check_type(Xen_is_gchar_(name), name, 2, "gdk_window_set_icon_name", "gchar*"); gdk_window_set_icon_name(Xen_to_C_GdkWindow_(window), Xen_to_C_gchar_(name)); return(Xen_false); } static Xen gxg_gdk_window_set_group(Xen window, Xen leader) { #define H_gdk_window_set_group "void gdk_window_set_group(GdkWindow* window, GdkWindow* leader)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_set_group", "GdkWindow*"); Xen_check_type(Xen_is_GdkWindow_(leader), leader, 2, "gdk_window_set_group", "GdkWindow*"); gdk_window_set_group(Xen_to_C_GdkWindow_(window), Xen_to_C_GdkWindow_(leader)); return(Xen_false); } static Xen gxg_gdk_window_set_decorations(Xen window, Xen decorations) { #define H_gdk_window_set_decorations "void gdk_window_set_decorations(GdkWindow* window, GdkWMDecoration decorations)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_set_decorations", "GdkWindow*"); Xen_check_type(Xen_is_GdkWMDecoration(decorations), decorations, 2, "gdk_window_set_decorations", "GdkWMDecoration"); gdk_window_set_decorations(Xen_to_C_GdkWindow_(window), Xen_to_C_GdkWMDecoration(decorations)); return(Xen_false); } static Xen gxg_gdk_window_get_decorations(Xen window, Xen ignore_decorations) { #define H_gdk_window_get_decorations "gboolean gdk_window_get_decorations(GdkWindow* window, GdkWMDecoration* [decorations])" GdkWMDecoration ref_decorations; Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_get_decorations", "GdkWindow*"); { Xen result; result = C_to_Xen_gboolean(gdk_window_get_decorations(Xen_to_C_GdkWindow_(window), &ref_decorations)); return(Xen_list_2(result, C_to_Xen_GdkWMDecoration(ref_decorations))); } } static Xen gxg_gdk_window_set_functions(Xen window, Xen functions) { #define H_gdk_window_set_functions "void gdk_window_set_functions(GdkWindow* window, GdkWMFunction functions)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_set_functions", "GdkWindow*"); Xen_check_type(Xen_is_GdkWMFunction(functions), functions, 2, "gdk_window_set_functions", "GdkWMFunction"); gdk_window_set_functions(Xen_to_C_GdkWindow_(window), Xen_to_C_GdkWMFunction(functions)); return(Xen_false); } static Xen gxg_gdk_window_iconify(Xen window) { #define H_gdk_window_iconify "void gdk_window_iconify(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_iconify", "GdkWindow*"); gdk_window_iconify(Xen_to_C_GdkWindow_(window)); return(Xen_false); } static Xen gxg_gdk_window_deiconify(Xen window) { #define H_gdk_window_deiconify "void gdk_window_deiconify(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_deiconify", "GdkWindow*"); gdk_window_deiconify(Xen_to_C_GdkWindow_(window)); return(Xen_false); } static Xen gxg_gdk_window_stick(Xen window) { #define H_gdk_window_stick "void gdk_window_stick(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_stick", "GdkWindow*"); gdk_window_stick(Xen_to_C_GdkWindow_(window)); return(Xen_false); } static Xen gxg_gdk_window_unstick(Xen window) { #define H_gdk_window_unstick "void gdk_window_unstick(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_unstick", "GdkWindow*"); gdk_window_unstick(Xen_to_C_GdkWindow_(window)); return(Xen_false); } static Xen gxg_gdk_window_maximize(Xen window) { #define H_gdk_window_maximize "void gdk_window_maximize(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_maximize", "GdkWindow*"); gdk_window_maximize(Xen_to_C_GdkWindow_(window)); return(Xen_false); } static Xen gxg_gdk_window_unmaximize(Xen window) { #define H_gdk_window_unmaximize "void gdk_window_unmaximize(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_unmaximize", "GdkWindow*"); gdk_window_unmaximize(Xen_to_C_GdkWindow_(window)); return(Xen_false); } static Xen gxg_gdk_window_register_dnd(Xen window) { #define H_gdk_window_register_dnd "void gdk_window_register_dnd(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_register_dnd", "GdkWindow*"); gdk_window_register_dnd(Xen_to_C_GdkWindow_(window)); return(Xen_false); } static Xen gxg_gdk_window_begin_resize_drag(Xen window, Xen edge, Xen button, Xen root_x, Xen root_y, Xen timestamp) { #define H_gdk_window_begin_resize_drag "void gdk_window_begin_resize_drag(GdkWindow* window, GdkWindowEdge edge, \ gint button, gint root_x, gint root_y, guint32 timestamp)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_begin_resize_drag", "GdkWindow*"); Xen_check_type(Xen_is_GdkWindowEdge(edge), edge, 2, "gdk_window_begin_resize_drag", "GdkWindowEdge"); Xen_check_type(Xen_is_gint(button), button, 3, "gdk_window_begin_resize_drag", "gint"); Xen_check_type(Xen_is_gint(root_x), root_x, 4, "gdk_window_begin_resize_drag", "gint"); Xen_check_type(Xen_is_gint(root_y), root_y, 5, "gdk_window_begin_resize_drag", "gint"); Xen_check_type(Xen_is_guint32(timestamp), timestamp, 6, "gdk_window_begin_resize_drag", "guint32"); gdk_window_begin_resize_drag(Xen_to_C_GdkWindow_(window), Xen_to_C_GdkWindowEdge(edge), Xen_to_C_gint(button), Xen_to_C_gint(root_x), Xen_to_C_gint(root_y), Xen_to_C_guint32(timestamp)); return(Xen_false); } static Xen gxg_gdk_window_begin_move_drag(Xen window, Xen button, Xen root_x, Xen root_y, Xen timestamp) { #define H_gdk_window_begin_move_drag "void gdk_window_begin_move_drag(GdkWindow* window, gint button, \ gint root_x, gint root_y, guint32 timestamp)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_begin_move_drag", "GdkWindow*"); Xen_check_type(Xen_is_gint(button), button, 2, "gdk_window_begin_move_drag", "gint"); Xen_check_type(Xen_is_gint(root_x), root_x, 3, "gdk_window_begin_move_drag", "gint"); Xen_check_type(Xen_is_gint(root_y), root_y, 4, "gdk_window_begin_move_drag", "gint"); Xen_check_type(Xen_is_guint32(timestamp), timestamp, 5, "gdk_window_begin_move_drag", "guint32"); gdk_window_begin_move_drag(Xen_to_C_GdkWindow_(window), Xen_to_C_gint(button), Xen_to_C_gint(root_x), Xen_to_C_gint(root_y), Xen_to_C_guint32(timestamp)); return(Xen_false); } static Xen gxg_gdk_window_invalidate_rect(Xen window, Xen rect, Xen invalidate_children) { #define H_gdk_window_invalidate_rect "void gdk_window_invalidate_rect(GdkWindow* window, GdkRectangle* rect, \ gboolean invalidate_children)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_invalidate_rect", "GdkWindow*"); Xen_check_type(Xen_is_GdkRectangle_(rect), rect, 2, "gdk_window_invalidate_rect", "GdkRectangle*"); Xen_check_type(Xen_is_gboolean(invalidate_children), invalidate_children, 3, "gdk_window_invalidate_rect", "gboolean"); gdk_window_invalidate_rect(Xen_to_C_GdkWindow_(window), Xen_to_C_GdkRectangle_(rect), Xen_to_C_gboolean(invalidate_children)); return(Xen_false); } static Xen gxg_gdk_window_freeze_updates(Xen window) { #define H_gdk_window_freeze_updates "void gdk_window_freeze_updates(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_freeze_updates", "GdkWindow*"); gdk_window_freeze_updates(Xen_to_C_GdkWindow_(window)); return(Xen_false); } static Xen gxg_gdk_window_thaw_updates(Xen window) { #define H_gdk_window_thaw_updates "void gdk_window_thaw_updates(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_thaw_updates", "GdkWindow*"); gdk_window_thaw_updates(Xen_to_C_GdkWindow_(window)); return(Xen_false); } static Xen gxg_gdk_window_process_all_updates(void) { #define H_gdk_window_process_all_updates "void gdk_window_process_all_updates( void)" gdk_window_process_all_updates(); return(Xen_false); } static Xen gxg_gdk_window_process_updates(Xen window, Xen update_children) { #define H_gdk_window_process_updates "void gdk_window_process_updates(GdkWindow* window, gboolean update_children)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_process_updates", "GdkWindow*"); Xen_check_type(Xen_is_gboolean(update_children), update_children, 2, "gdk_window_process_updates", "gboolean"); gdk_window_process_updates(Xen_to_C_GdkWindow_(window), Xen_to_C_gboolean(update_children)); return(Xen_false); } static Xen gxg_gdk_window_set_debug_updates(Xen setting) { #define H_gdk_window_set_debug_updates "void gdk_window_set_debug_updates(gboolean setting)" Xen_check_type(Xen_is_gboolean(setting), setting, 1, "gdk_window_set_debug_updates", "gboolean"); gdk_window_set_debug_updates(Xen_to_C_gboolean(setting)); return(Xen_false); } static Xen gxg_gdk_window_constrain_size(Xen geometry, Xen flags, Xen width, Xen height, Xen ignore_new_width, Xen ignore_new_height) { #define H_gdk_window_constrain_size "void gdk_window_constrain_size(GdkGeometry* geometry, GdkWindowHints flags, \ gint width, gint height, gint* [new_width], gint* [new_height])" gint ref_new_width; gint ref_new_height; Xen_check_type(Xen_is_GdkGeometry_(geometry), geometry, 1, "gdk_window_constrain_size", "GdkGeometry*"); Xen_check_type(Xen_is_GdkWindowHints(flags), flags, 2, "gdk_window_constrain_size", "GdkWindowHints"); Xen_check_type(Xen_is_gint(width), width, 3, "gdk_window_constrain_size", "gint"); Xen_check_type(Xen_is_gint(height), height, 4, "gdk_window_constrain_size", "gint"); gdk_window_constrain_size(Xen_to_C_GdkGeometry_(geometry), Xen_to_C_GdkWindowHints(flags), Xen_to_C_gint(width), Xen_to_C_gint(height), &ref_new_width, &ref_new_height); return(Xen_list_2(C_to_Xen_gint(ref_new_width), C_to_Xen_gint(ref_new_height))); } static Xen gxg_gdk_window_set_type_hint(Xen window, Xen hint) { #define H_gdk_window_set_type_hint "void gdk_window_set_type_hint(GdkWindow* window, GdkWindowTypeHint hint)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_set_type_hint", "GdkWindow*"); Xen_check_type(Xen_is_GdkWindowTypeHint(hint), hint, 2, "gdk_window_set_type_hint", "GdkWindowTypeHint"); gdk_window_set_type_hint(Xen_to_C_GdkWindow_(window), Xen_to_C_GdkWindowTypeHint(hint)); return(Xen_false); } static Xen gxg_gdk_window_set_modal_hint(Xen window, Xen modal) { #define H_gdk_window_set_modal_hint "void gdk_window_set_modal_hint(GdkWindow* window, gboolean modal)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_set_modal_hint", "GdkWindow*"); Xen_check_type(Xen_is_gboolean(modal), modal, 2, "gdk_window_set_modal_hint", "gboolean"); gdk_window_set_modal_hint(Xen_to_C_GdkWindow_(window), Xen_to_C_gboolean(modal)); return(Xen_false); } static Xen gxg_gdk_window_set_geometry_hints(Xen window, Xen geometry, Xen geom_mask) { #define H_gdk_window_set_geometry_hints "void gdk_window_set_geometry_hints(GdkWindow* window, GdkGeometry* geometry, \ GdkWindowHints geom_mask)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_set_geometry_hints", "GdkWindow*"); Xen_check_type(Xen_is_GdkGeometry_(geometry), geometry, 2, "gdk_window_set_geometry_hints", "GdkGeometry*"); Xen_check_type(Xen_is_GdkWindowHints(geom_mask), geom_mask, 3, "gdk_window_set_geometry_hints", "GdkWindowHints"); gdk_window_set_geometry_hints(Xen_to_C_GdkWindow_(window), Xen_to_C_GdkGeometry_(geometry), Xen_to_C_GdkWindowHints(geom_mask)); return(Xen_false); } static Xen gxg_gdk_window_begin_paint_rect(Xen window, Xen rectangle) { #define H_gdk_window_begin_paint_rect "void gdk_window_begin_paint_rect(GdkWindow* window, GdkRectangle* rectangle)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_begin_paint_rect", "GdkWindow*"); Xen_check_type(Xen_is_GdkRectangle_(rectangle), rectangle, 2, "gdk_window_begin_paint_rect", "GdkRectangle*"); gdk_window_begin_paint_rect(Xen_to_C_GdkWindow_(window), Xen_to_C_GdkRectangle_(rectangle)); return(Xen_false); } static Xen gxg_gdk_window_end_paint(Xen window) { #define H_gdk_window_end_paint "void gdk_window_end_paint(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_end_paint", "GdkWindow*"); gdk_window_end_paint(Xen_to_C_GdkWindow_(window)); return(Xen_false); } static Xen gxg_gdk_window_set_title(Xen window, Xen title) { #define H_gdk_window_set_title "void gdk_window_set_title(GdkWindow* window, gchar* title)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_set_title", "GdkWindow*"); Xen_check_type(Xen_is_gchar_(title), title, 2, "gdk_window_set_title", "gchar*"); gdk_window_set_title(Xen_to_C_GdkWindow_(window), Xen_to_C_gchar_(title)); return(Xen_false); } static Xen gxg_gdk_window_set_role(Xen window, Xen role) { #define H_gdk_window_set_role "void gdk_window_set_role(GdkWindow* window, gchar* role)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_set_role", "GdkWindow*"); Xen_check_type(Xen_is_gchar_(role), role, 2, "gdk_window_set_role", "gchar*"); gdk_window_set_role(Xen_to_C_GdkWindow_(window), Xen_to_C_gchar_(role)); return(Xen_false); } static Xen gxg_gdk_window_set_transient_for(Xen window, Xen parent) { #define H_gdk_window_set_transient_for "void gdk_window_set_transient_for(GdkWindow* window, GdkWindow* parent)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_set_transient_for", "GdkWindow*"); Xen_check_type(Xen_is_GdkWindow_(parent), parent, 2, "gdk_window_set_transient_for", "GdkWindow*"); gdk_window_set_transient_for(Xen_to_C_GdkWindow_(window), Xen_to_C_GdkWindow_(parent)); return(Xen_false); } static Xen gxg_gdk_window_set_cursor(Xen window, Xen cursor) { #define H_gdk_window_set_cursor "void gdk_window_set_cursor(GdkWindow* window, GdkCursor* cursor)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_set_cursor", "GdkWindow*"); Xen_check_type(Xen_is_GdkCursor_(cursor), cursor, 2, "gdk_window_set_cursor", "GdkCursor*"); gdk_window_set_cursor(Xen_to_C_GdkWindow_(window), Xen_to_C_GdkCursor_(cursor)); return(Xen_false); } static Xen gxg_gdk_window_get_user_data(Xen window, Xen ignore_data) { #define H_gdk_window_get_user_data "void gdk_window_get_user_data(GdkWindow* window, gpointer* [data])" gpointer ref_data; Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_get_user_data", "GdkWindow*"); gdk_window_get_user_data(Xen_to_C_GdkWindow_(window), &ref_data); return(Xen_list_1(C_to_Xen_gpointer(ref_data))); } static Xen gxg_gdk_window_get_position(Xen window, Xen ignore_x, Xen ignore_y) { #define H_gdk_window_get_position "void gdk_window_get_position(GdkWindow* window, gint* [x], gint* [y])" gint ref_x; gint ref_y; Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_get_position", "GdkWindow*"); gdk_window_get_position(Xen_to_C_GdkWindow_(window), &ref_x, &ref_y); return(Xen_list_2(C_to_Xen_gint(ref_x), C_to_Xen_gint(ref_y))); } static Xen gxg_gdk_window_get_origin(Xen window, Xen ignore_x, Xen ignore_y) { #define H_gdk_window_get_origin "gint gdk_window_get_origin(GdkWindow* window, gint* [x], gint* [y])" gint ref_x; gint ref_y; Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_get_origin", "GdkWindow*"); { Xen result; result = C_to_Xen_gint(gdk_window_get_origin(Xen_to_C_GdkWindow_(window), &ref_x, &ref_y)); return(Xen_list_3(result, C_to_Xen_gint(ref_x), C_to_Xen_gint(ref_y))); } } static Xen gxg_gdk_get_default_root_window(void) { #define H_gdk_get_default_root_window "GdkWindow* gdk_get_default_root_window( void)" return(C_to_Xen_GdkWindow_(gdk_get_default_root_window())); } static Xen gxg_gdk_pixbuf_error_quark(void) { #define H_gdk_pixbuf_error_quark "GQuark gdk_pixbuf_error_quark( void)" return(C_to_Xen_GQuark(gdk_pixbuf_error_quark())); } static Xen gxg_gdk_pixbuf_get_colorspace(Xen pixbuf) { #define H_gdk_pixbuf_get_colorspace "GdkColorspace gdk_pixbuf_get_colorspace(GdkPixbuf* pixbuf)" Xen_check_type(Xen_is_GdkPixbuf_(pixbuf), pixbuf, 1, "gdk_pixbuf_get_colorspace", "GdkPixbuf*"); return(C_to_Xen_GdkColorspace(gdk_pixbuf_get_colorspace(Xen_to_C_GdkPixbuf_(pixbuf)))); } static Xen gxg_gdk_pixbuf_get_n_channels(Xen pixbuf) { #define H_gdk_pixbuf_get_n_channels "int gdk_pixbuf_get_n_channels(GdkPixbuf* pixbuf)" Xen_check_type(Xen_is_GdkPixbuf_(pixbuf), pixbuf, 1, "gdk_pixbuf_get_n_channels", "GdkPixbuf*"); return(C_to_Xen_int(gdk_pixbuf_get_n_channels(Xen_to_C_GdkPixbuf_(pixbuf)))); } static Xen gxg_gdk_pixbuf_get_has_alpha(Xen pixbuf) { #define H_gdk_pixbuf_get_has_alpha "gboolean gdk_pixbuf_get_has_alpha(GdkPixbuf* pixbuf)" Xen_check_type(Xen_is_GdkPixbuf_(pixbuf), pixbuf, 1, "gdk_pixbuf_get_has_alpha", "GdkPixbuf*"); return(C_to_Xen_gboolean(gdk_pixbuf_get_has_alpha(Xen_to_C_GdkPixbuf_(pixbuf)))); } static Xen gxg_gdk_pixbuf_get_bits_per_sample(Xen pixbuf) { #define H_gdk_pixbuf_get_bits_per_sample "int gdk_pixbuf_get_bits_per_sample(GdkPixbuf* pixbuf)" Xen_check_type(Xen_is_GdkPixbuf_(pixbuf), pixbuf, 1, "gdk_pixbuf_get_bits_per_sample", "GdkPixbuf*"); return(C_to_Xen_int(gdk_pixbuf_get_bits_per_sample(Xen_to_C_GdkPixbuf_(pixbuf)))); } static Xen gxg_gdk_pixbuf_get_pixels(Xen pixbuf) { #define H_gdk_pixbuf_get_pixels "guchar* gdk_pixbuf_get_pixels(GdkPixbuf* pixbuf)" Xen_check_type(Xen_is_GdkPixbuf_(pixbuf), pixbuf, 1, "gdk_pixbuf_get_pixels", "GdkPixbuf*"); return(C_to_Xen_guchar_(gdk_pixbuf_get_pixels(Xen_to_C_GdkPixbuf_(pixbuf)))); } static Xen gxg_gdk_pixbuf_get_width(Xen pixbuf) { #define H_gdk_pixbuf_get_width "int gdk_pixbuf_get_width(GdkPixbuf* pixbuf)" Xen_check_type(Xen_is_GdkPixbuf_(pixbuf), pixbuf, 1, "gdk_pixbuf_get_width", "GdkPixbuf*"); return(C_to_Xen_int(gdk_pixbuf_get_width(Xen_to_C_GdkPixbuf_(pixbuf)))); } static Xen gxg_gdk_pixbuf_get_height(Xen pixbuf) { #define H_gdk_pixbuf_get_height "int gdk_pixbuf_get_height(GdkPixbuf* pixbuf)" Xen_check_type(Xen_is_GdkPixbuf_(pixbuf), pixbuf, 1, "gdk_pixbuf_get_height", "GdkPixbuf*"); return(C_to_Xen_int(gdk_pixbuf_get_height(Xen_to_C_GdkPixbuf_(pixbuf)))); } static Xen gxg_gdk_pixbuf_get_rowstride(Xen pixbuf) { #define H_gdk_pixbuf_get_rowstride "int gdk_pixbuf_get_rowstride(GdkPixbuf* pixbuf)" Xen_check_type(Xen_is_GdkPixbuf_(pixbuf), pixbuf, 1, "gdk_pixbuf_get_rowstride", "GdkPixbuf*"); return(C_to_Xen_int(gdk_pixbuf_get_rowstride(Xen_to_C_GdkPixbuf_(pixbuf)))); } static Xen gxg_gdk_pixbuf_new(Xen colorspace, Xen has_alpha, Xen bits_per_sample, Xen width, Xen height) { #define H_gdk_pixbuf_new "GdkPixbuf* gdk_pixbuf_new(GdkColorspace colorspace, gboolean has_alpha, int bits_per_sample, \ int width, int height)" Xen_check_type(Xen_is_GdkColorspace(colorspace), colorspace, 1, "gdk_pixbuf_new", "GdkColorspace"); Xen_check_type(Xen_is_gboolean(has_alpha), has_alpha, 2, "gdk_pixbuf_new", "gboolean"); Xen_check_type(Xen_is_int(bits_per_sample), bits_per_sample, 3, "gdk_pixbuf_new", "int"); Xen_check_type(Xen_is_int(width), width, 4, "gdk_pixbuf_new", "int"); Xen_check_type(Xen_is_int(height), height, 5, "gdk_pixbuf_new", "int"); return(C_to_Xen_GdkPixbuf_(gdk_pixbuf_new(Xen_to_C_GdkColorspace(colorspace), Xen_to_C_gboolean(has_alpha), Xen_to_C_int(bits_per_sample), Xen_to_C_int(width), Xen_to_C_int(height)))); } static Xen gxg_gdk_pixbuf_copy(Xen pixbuf) { #define H_gdk_pixbuf_copy "GdkPixbuf* gdk_pixbuf_copy(GdkPixbuf* pixbuf)" Xen_check_type(Xen_is_GdkPixbuf_(pixbuf), pixbuf, 1, "gdk_pixbuf_copy", "GdkPixbuf*"); return(C_to_Xen_GdkPixbuf_(gdk_pixbuf_copy(Xen_to_C_GdkPixbuf_(pixbuf)))); } static Xen gxg_gdk_pixbuf_new_subpixbuf(Xen src_pixbuf, Xen src_x, Xen src_y, Xen width, Xen height) { #define H_gdk_pixbuf_new_subpixbuf "GdkPixbuf* gdk_pixbuf_new_subpixbuf(GdkPixbuf* src_pixbuf, int src_x, \ int src_y, int width, int height)" Xen_check_type(Xen_is_GdkPixbuf_(src_pixbuf), src_pixbuf, 1, "gdk_pixbuf_new_subpixbuf", "GdkPixbuf*"); Xen_check_type(Xen_is_int(src_x), src_x, 2, "gdk_pixbuf_new_subpixbuf", "int"); Xen_check_type(Xen_is_int(src_y), src_y, 3, "gdk_pixbuf_new_subpixbuf", "int"); Xen_check_type(Xen_is_int(width), width, 4, "gdk_pixbuf_new_subpixbuf", "int"); Xen_check_type(Xen_is_int(height), height, 5, "gdk_pixbuf_new_subpixbuf", "int"); return(C_to_Xen_GdkPixbuf_(gdk_pixbuf_new_subpixbuf(Xen_to_C_GdkPixbuf_(src_pixbuf), Xen_to_C_int(src_x), Xen_to_C_int(src_y), Xen_to_C_int(width), Xen_to_C_int(height)))); } static Xen gxg_gdk_pixbuf_new_from_file(Xen filename, Xen ignore_error) { #define H_gdk_pixbuf_new_from_file "GdkPixbuf* gdk_pixbuf_new_from_file(char* filename, GError** [error])" GError* ref_error = NULL; Xen_check_type(Xen_is_char_(filename), filename, 1, "gdk_pixbuf_new_from_file", "char*"); { Xen result; result = C_to_Xen_GdkPixbuf_(gdk_pixbuf_new_from_file(Xen_to_C_char_(filename), &ref_error)); return(Xen_list_2(result, C_to_Xen_GError_(ref_error))); } } static Xen gxg_gdk_pixbuf_new_from_data(Xen arglist) { #define H_gdk_pixbuf_new_from_data "GdkPixbuf* gdk_pixbuf_new_from_data(guchar* data, GdkColorspace colorspace, \ gboolean has_alpha, int bits_per_sample, int width, int height, int rowstride, GdkPixbufDestroyNotify destroy_fn, \ gpointer destroy_fn_data)" Xen data, colorspace, has_alpha, bits_per_sample, width, height, rowstride, destroy_fn, destroy_fn_data; data = Xen_list_ref(arglist, 0); colorspace = Xen_list_ref(arglist, 1); has_alpha = Xen_list_ref(arglist, 2); bits_per_sample = Xen_list_ref(arglist, 3); width = Xen_list_ref(arglist, 4); height = Xen_list_ref(arglist, 5); rowstride = Xen_list_ref(arglist, 6); destroy_fn = Xen_list_ref(arglist, 7); destroy_fn_data = Xen_list_ref(arglist, 8); Xen_check_type(Xen_is_guchar_(data), data, 1, "gdk_pixbuf_new_from_data", "guchar*"); Xen_check_type(Xen_is_GdkColorspace(colorspace), colorspace, 2, "gdk_pixbuf_new_from_data", "GdkColorspace"); Xen_check_type(Xen_is_gboolean(has_alpha), has_alpha, 3, "gdk_pixbuf_new_from_data", "gboolean"); Xen_check_type(Xen_is_int(bits_per_sample), bits_per_sample, 4, "gdk_pixbuf_new_from_data", "int"); Xen_check_type(Xen_is_int(width), width, 5, "gdk_pixbuf_new_from_data", "int"); Xen_check_type(Xen_is_int(height), height, 6, "gdk_pixbuf_new_from_data", "int"); Xen_check_type(Xen_is_int(rowstride), rowstride, 7, "gdk_pixbuf_new_from_data", "int"); Xen_check_type(Xen_is_GdkPixbufDestroyNotify(destroy_fn), destroy_fn, 8, "gdk_pixbuf_new_from_data", "GdkPixbufDestroyNotify"); Xen_check_type(Xen_is_gpointer(destroy_fn_data), destroy_fn_data, 9, "gdk_pixbuf_new_from_data", "gpointer"); return(C_to_Xen_GdkPixbuf_(gdk_pixbuf_new_from_data(Xen_to_C_guchar_(data), Xen_to_C_GdkColorspace(colorspace), Xen_to_C_gboolean(has_alpha), Xen_to_C_int(bits_per_sample), Xen_to_C_int(width), Xen_to_C_int(height), Xen_to_C_int(rowstride), Xen_to_C_GdkPixbufDestroyNotify(destroy_fn), Xen_to_C_gpointer(destroy_fn_data)))); } static Xen gxg_gdk_pixbuf_new_from_xpm_data(Xen data) { #define H_gdk_pixbuf_new_from_xpm_data "GdkPixbuf* gdk_pixbuf_new_from_xpm_data(char** data)" Xen_check_type(Xen_is_char__(data), data, 1, "gdk_pixbuf_new_from_xpm_data", "char**"); return(C_to_Xen_GdkPixbuf_(gdk_pixbuf_new_from_xpm_data((const char**)Xen_to_C_char__(data)))); } static Xen gxg_gdk_pixbuf_fill(Xen pixbuf, Xen pixel) { #define H_gdk_pixbuf_fill "void gdk_pixbuf_fill(GdkPixbuf* pixbuf, guint32 pixel)" Xen_check_type(Xen_is_GdkPixbuf_(pixbuf), pixbuf, 1, "gdk_pixbuf_fill", "GdkPixbuf*"); Xen_check_type(Xen_is_guint32(pixel), pixel, 2, "gdk_pixbuf_fill", "guint32"); gdk_pixbuf_fill(Xen_to_C_GdkPixbuf_(pixbuf), Xen_to_C_guint32(pixel)); return(Xen_false); } static Xen gxg_gdk_pixbuf_savev(Xen pixbuf, Xen filename, Xen type, Xen option_keys, Xen option_values, Xen ignore_error) { #define H_gdk_pixbuf_savev "gboolean gdk_pixbuf_savev(GdkPixbuf* pixbuf, char* filename, char* type, \ char** option_keys, char** option_values, GError** [error])" GError* ref_error = NULL; Xen_check_type(Xen_is_GdkPixbuf_(pixbuf), pixbuf, 1, "gdk_pixbuf_savev", "GdkPixbuf*"); Xen_check_type(Xen_is_char_(filename), filename, 2, "gdk_pixbuf_savev", "char*"); Xen_check_type(Xen_is_char_(type), type, 3, "gdk_pixbuf_savev", "char*"); Xen_check_type(Xen_is_char__(option_keys), option_keys, 4, "gdk_pixbuf_savev", "char**"); Xen_check_type(Xen_is_char__(option_values), option_values, 5, "gdk_pixbuf_savev", "char**"); { Xen result; result = C_to_Xen_gboolean(gdk_pixbuf_savev(Xen_to_C_GdkPixbuf_(pixbuf), Xen_to_C_char_(filename), Xen_to_C_char_(type), Xen_to_C_char__(option_keys), Xen_to_C_char__(option_values), &ref_error)); return(Xen_list_2(result, C_to_Xen_GError_(ref_error))); } } static Xen gxg_gdk_pixbuf_add_alpha(Xen pixbuf, Xen substitute_color, Xen r, Xen g, Xen b) { #define H_gdk_pixbuf_add_alpha "GdkPixbuf* gdk_pixbuf_add_alpha(GdkPixbuf* pixbuf, gboolean substitute_color, \ guchar r, guchar g, guchar b)" Xen_check_type(Xen_is_GdkPixbuf_(pixbuf), pixbuf, 1, "gdk_pixbuf_add_alpha", "GdkPixbuf*"); Xen_check_type(Xen_is_gboolean(substitute_color), substitute_color, 2, "gdk_pixbuf_add_alpha", "gboolean"); Xen_check_type(Xen_is_guchar(r), r, 3, "gdk_pixbuf_add_alpha", "guchar"); Xen_check_type(Xen_is_guchar(g), g, 4, "gdk_pixbuf_add_alpha", "guchar"); Xen_check_type(Xen_is_guchar(b), b, 5, "gdk_pixbuf_add_alpha", "guchar"); return(C_to_Xen_GdkPixbuf_(gdk_pixbuf_add_alpha(Xen_to_C_GdkPixbuf_(pixbuf), Xen_to_C_gboolean(substitute_color), Xen_to_C_guchar(r), Xen_to_C_guchar(g), Xen_to_C_guchar(b)))); } static Xen gxg_gdk_pixbuf_copy_area(Xen arglist) { #define H_gdk_pixbuf_copy_area "void gdk_pixbuf_copy_area(GdkPixbuf* src_pixbuf, int src_x, int src_y, \ int width, int height, GdkPixbuf* dest_pixbuf, int dest_x, int dest_y)" Xen src_pixbuf, src_x, src_y, width, height, dest_pixbuf, dest_x, dest_y; src_pixbuf = Xen_list_ref(arglist, 0); src_x = Xen_list_ref(arglist, 1); src_y = Xen_list_ref(arglist, 2); width = Xen_list_ref(arglist, 3); height = Xen_list_ref(arglist, 4); dest_pixbuf = Xen_list_ref(arglist, 5); dest_x = Xen_list_ref(arglist, 6); dest_y = Xen_list_ref(arglist, 7); Xen_check_type(Xen_is_GdkPixbuf_(src_pixbuf), src_pixbuf, 1, "gdk_pixbuf_copy_area", "GdkPixbuf*"); Xen_check_type(Xen_is_int(src_x), src_x, 2, "gdk_pixbuf_copy_area", "int"); Xen_check_type(Xen_is_int(src_y), src_y, 3, "gdk_pixbuf_copy_area", "int"); Xen_check_type(Xen_is_int(width), width, 4, "gdk_pixbuf_copy_area", "int"); Xen_check_type(Xen_is_int(height), height, 5, "gdk_pixbuf_copy_area", "int"); Xen_check_type(Xen_is_GdkPixbuf_(dest_pixbuf), dest_pixbuf, 6, "gdk_pixbuf_copy_area", "GdkPixbuf*"); Xen_check_type(Xen_is_int(dest_x), dest_x, 7, "gdk_pixbuf_copy_area", "int"); Xen_check_type(Xen_is_int(dest_y), dest_y, 8, "gdk_pixbuf_copy_area", "int"); gdk_pixbuf_copy_area(Xen_to_C_GdkPixbuf_(src_pixbuf), Xen_to_C_int(src_x), Xen_to_C_int(src_y), Xen_to_C_int(width), Xen_to_C_int(height), Xen_to_C_GdkPixbuf_(dest_pixbuf), Xen_to_C_int(dest_x), Xen_to_C_int(dest_y)); return(Xen_false); } static Xen gxg_gdk_pixbuf_saturate_and_pixelate(Xen src, Xen dest, Xen saturation, Xen pixelate) { #define H_gdk_pixbuf_saturate_and_pixelate "void gdk_pixbuf_saturate_and_pixelate(GdkPixbuf* src, GdkPixbuf* dest, \ gfloat saturation, gboolean pixelate)" Xen_check_type(Xen_is_GdkPixbuf_(src), src, 1, "gdk_pixbuf_saturate_and_pixelate", "GdkPixbuf*"); Xen_check_type(Xen_is_GdkPixbuf_(dest), dest, 2, "gdk_pixbuf_saturate_and_pixelate", "GdkPixbuf*"); Xen_check_type(Xen_is_gfloat(saturation), saturation, 3, "gdk_pixbuf_saturate_and_pixelate", "gfloat"); Xen_check_type(Xen_is_gboolean(pixelate), pixelate, 4, "gdk_pixbuf_saturate_and_pixelate", "gboolean"); gdk_pixbuf_saturate_and_pixelate(Xen_to_C_GdkPixbuf_(src), Xen_to_C_GdkPixbuf_(dest), Xen_to_C_gfloat(saturation), Xen_to_C_gboolean(pixelate)); return(Xen_false); } static Xen gxg_gdk_pixbuf_scale(Xen arglist) { #define H_gdk_pixbuf_scale "void gdk_pixbuf_scale(GdkPixbuf* src, GdkPixbuf* dest, int dest_x, int dest_y, \ int dest_width, int dest_height, double offset_x, double offset_y, double scale_x, double scale_y, GdkInterpType interp_type)" Xen src, dest, dest_x, dest_y, dest_width, dest_height, offset_x, offset_y, scale_x, scale_y, interp_type; src = Xen_list_ref(arglist, 0); dest = Xen_list_ref(arglist, 1); dest_x = Xen_list_ref(arglist, 2); dest_y = Xen_list_ref(arglist, 3); dest_width = Xen_list_ref(arglist, 4); dest_height = Xen_list_ref(arglist, 5); offset_x = Xen_list_ref(arglist, 6); offset_y = Xen_list_ref(arglist, 7); scale_x = Xen_list_ref(arglist, 8); scale_y = Xen_list_ref(arglist, 9); interp_type = Xen_list_ref(arglist, 10); Xen_check_type(Xen_is_GdkPixbuf_(src), src, 1, "gdk_pixbuf_scale", "GdkPixbuf*"); Xen_check_type(Xen_is_GdkPixbuf_(dest), dest, 2, "gdk_pixbuf_scale", "GdkPixbuf*"); Xen_check_type(Xen_is_int(dest_x), dest_x, 3, "gdk_pixbuf_scale", "int"); Xen_check_type(Xen_is_int(dest_y), dest_y, 4, "gdk_pixbuf_scale", "int"); Xen_check_type(Xen_is_int(dest_width), dest_width, 5, "gdk_pixbuf_scale", "int"); Xen_check_type(Xen_is_int(dest_height), dest_height, 6, "gdk_pixbuf_scale", "int"); Xen_check_type(Xen_is_double(offset_x), offset_x, 7, "gdk_pixbuf_scale", "double"); Xen_check_type(Xen_is_double(offset_y), offset_y, 8, "gdk_pixbuf_scale", "double"); Xen_check_type(Xen_is_double(scale_x), scale_x, 9, "gdk_pixbuf_scale", "double"); Xen_check_type(Xen_is_double(scale_y), scale_y, 10, "gdk_pixbuf_scale", "double"); Xen_check_type(Xen_is_GdkInterpType(interp_type), interp_type, 11, "gdk_pixbuf_scale", "GdkInterpType"); gdk_pixbuf_scale(Xen_to_C_GdkPixbuf_(src), Xen_to_C_GdkPixbuf_(dest), Xen_to_C_int(dest_x), Xen_to_C_int(dest_y), Xen_to_C_int(dest_width), Xen_to_C_int(dest_height), Xen_to_C_double(offset_x), Xen_to_C_double(offset_y), Xen_to_C_double(scale_x), Xen_to_C_double(scale_y), Xen_to_C_GdkInterpType(interp_type)); return(Xen_false); } static Xen gxg_gdk_pixbuf_composite(Xen arglist) { #define H_gdk_pixbuf_composite "void gdk_pixbuf_composite(GdkPixbuf* src, GdkPixbuf* dest, int dest_x, \ int dest_y, int dest_width, int dest_height, double offset_x, double offset_y, double scale_x, double scale_y, \ GdkInterpType interp_type, int overall_alpha)" Xen src, dest, dest_x, dest_y, dest_width, dest_height, offset_x, offset_y, scale_x, scale_y, interp_type, overall_alpha; src = Xen_list_ref(arglist, 0); dest = Xen_list_ref(arglist, 1); dest_x = Xen_list_ref(arglist, 2); dest_y = Xen_list_ref(arglist, 3); dest_width = Xen_list_ref(arglist, 4); dest_height = Xen_list_ref(arglist, 5); offset_x = Xen_list_ref(arglist, 6); offset_y = Xen_list_ref(arglist, 7); scale_x = Xen_list_ref(arglist, 8); scale_y = Xen_list_ref(arglist, 9); interp_type = Xen_list_ref(arglist, 10); overall_alpha = Xen_list_ref(arglist, 11); Xen_check_type(Xen_is_GdkPixbuf_(src), src, 1, "gdk_pixbuf_composite", "GdkPixbuf*"); Xen_check_type(Xen_is_GdkPixbuf_(dest), dest, 2, "gdk_pixbuf_composite", "GdkPixbuf*"); Xen_check_type(Xen_is_int(dest_x), dest_x, 3, "gdk_pixbuf_composite", "int"); Xen_check_type(Xen_is_int(dest_y), dest_y, 4, "gdk_pixbuf_composite", "int"); Xen_check_type(Xen_is_int(dest_width), dest_width, 5, "gdk_pixbuf_composite", "int"); Xen_check_type(Xen_is_int(dest_height), dest_height, 6, "gdk_pixbuf_composite", "int"); Xen_check_type(Xen_is_double(offset_x), offset_x, 7, "gdk_pixbuf_composite", "double"); Xen_check_type(Xen_is_double(offset_y), offset_y, 8, "gdk_pixbuf_composite", "double"); Xen_check_type(Xen_is_double(scale_x), scale_x, 9, "gdk_pixbuf_composite", "double"); Xen_check_type(Xen_is_double(scale_y), scale_y, 10, "gdk_pixbuf_composite", "double"); Xen_check_type(Xen_is_GdkInterpType(interp_type), interp_type, 11, "gdk_pixbuf_composite", "GdkInterpType"); Xen_check_type(Xen_is_int(overall_alpha), overall_alpha, 12, "gdk_pixbuf_composite", "int"); gdk_pixbuf_composite(Xen_to_C_GdkPixbuf_(src), Xen_to_C_GdkPixbuf_(dest), Xen_to_C_int(dest_x), Xen_to_C_int(dest_y), Xen_to_C_int(dest_width), Xen_to_C_int(dest_height), Xen_to_C_double(offset_x), Xen_to_C_double(offset_y), Xen_to_C_double(scale_x), Xen_to_C_double(scale_y), Xen_to_C_GdkInterpType(interp_type), Xen_to_C_int(overall_alpha)); return(Xen_false); } static Xen gxg_gdk_pixbuf_composite_color(Xen arglist) { #define H_gdk_pixbuf_composite_color "void gdk_pixbuf_composite_color(GdkPixbuf* src, GdkPixbuf* dest, \ int dest_x, int dest_y, int dest_width, int dest_height, double offset_x, double offset_y, double scale_x, \ double scale_y, GdkInterpType interp_type, int overall_alpha, int check_x, int check_y, int check_size, \ guint32 color1, guint32 color2)" Xen src, dest, dest_x, dest_y, dest_width, dest_height, offset_x, offset_y, scale_x, scale_y, interp_type, overall_alpha, check_x, check_y, check_size, color1, color2; src = Xen_list_ref(arglist, 0); dest = Xen_list_ref(arglist, 1); dest_x = Xen_list_ref(arglist, 2); dest_y = Xen_list_ref(arglist, 3); dest_width = Xen_list_ref(arglist, 4); dest_height = Xen_list_ref(arglist, 5); offset_x = Xen_list_ref(arglist, 6); offset_y = Xen_list_ref(arglist, 7); scale_x = Xen_list_ref(arglist, 8); scale_y = Xen_list_ref(arglist, 9); interp_type = Xen_list_ref(arglist, 10); overall_alpha = Xen_list_ref(arglist, 11); check_x = Xen_list_ref(arglist, 12); check_y = Xen_list_ref(arglist, 13); check_size = Xen_list_ref(arglist, 14); color1 = Xen_list_ref(arglist, 15); color2 = Xen_list_ref(arglist, 16); Xen_check_type(Xen_is_GdkPixbuf_(src), src, 1, "gdk_pixbuf_composite_color", "GdkPixbuf*"); Xen_check_type(Xen_is_GdkPixbuf_(dest), dest, 2, "gdk_pixbuf_composite_color", "GdkPixbuf*"); Xen_check_type(Xen_is_int(dest_x), dest_x, 3, "gdk_pixbuf_composite_color", "int"); Xen_check_type(Xen_is_int(dest_y), dest_y, 4, "gdk_pixbuf_composite_color", "int"); Xen_check_type(Xen_is_int(dest_width), dest_width, 5, "gdk_pixbuf_composite_color", "int"); Xen_check_type(Xen_is_int(dest_height), dest_height, 6, "gdk_pixbuf_composite_color", "int"); Xen_check_type(Xen_is_double(offset_x), offset_x, 7, "gdk_pixbuf_composite_color", "double"); Xen_check_type(Xen_is_double(offset_y), offset_y, 8, "gdk_pixbuf_composite_color", "double"); Xen_check_type(Xen_is_double(scale_x), scale_x, 9, "gdk_pixbuf_composite_color", "double"); Xen_check_type(Xen_is_double(scale_y), scale_y, 10, "gdk_pixbuf_composite_color", "double"); Xen_check_type(Xen_is_GdkInterpType(interp_type), interp_type, 11, "gdk_pixbuf_composite_color", "GdkInterpType"); Xen_check_type(Xen_is_int(overall_alpha), overall_alpha, 12, "gdk_pixbuf_composite_color", "int"); Xen_check_type(Xen_is_int(check_x), check_x, 13, "gdk_pixbuf_composite_color", "int"); Xen_check_type(Xen_is_int(check_y), check_y, 14, "gdk_pixbuf_composite_color", "int"); Xen_check_type(Xen_is_int(check_size), check_size, 15, "gdk_pixbuf_composite_color", "int"); Xen_check_type(Xen_is_guint32(color1), color1, 16, "gdk_pixbuf_composite_color", "guint32"); Xen_check_type(Xen_is_guint32(color2), color2, 17, "gdk_pixbuf_composite_color", "guint32"); gdk_pixbuf_composite_color(Xen_to_C_GdkPixbuf_(src), Xen_to_C_GdkPixbuf_(dest), Xen_to_C_int(dest_x), Xen_to_C_int(dest_y), Xen_to_C_int(dest_width), Xen_to_C_int(dest_height), Xen_to_C_double(offset_x), Xen_to_C_double(offset_y), Xen_to_C_double(scale_x), Xen_to_C_double(scale_y), Xen_to_C_GdkInterpType(interp_type), Xen_to_C_int(overall_alpha), Xen_to_C_int(check_x), Xen_to_C_int(check_y), Xen_to_C_int(check_size), Xen_to_C_guint32(color1), Xen_to_C_guint32(color2)); return(Xen_false); } static Xen gxg_gdk_pixbuf_scale_simple(Xen src, Xen dest_width, Xen dest_height, Xen interp_type) { #define H_gdk_pixbuf_scale_simple "GdkPixbuf* gdk_pixbuf_scale_simple(GdkPixbuf* src, int dest_width, \ int dest_height, GdkInterpType interp_type)" Xen_check_type(Xen_is_GdkPixbuf_(src), src, 1, "gdk_pixbuf_scale_simple", "GdkPixbuf*"); Xen_check_type(Xen_is_int(dest_width), dest_width, 2, "gdk_pixbuf_scale_simple", "int"); Xen_check_type(Xen_is_int(dest_height), dest_height, 3, "gdk_pixbuf_scale_simple", "int"); Xen_check_type(Xen_is_GdkInterpType(interp_type), interp_type, 4, "gdk_pixbuf_scale_simple", "GdkInterpType"); return(C_to_Xen_GdkPixbuf_(gdk_pixbuf_scale_simple(Xen_to_C_GdkPixbuf_(src), Xen_to_C_int(dest_width), Xen_to_C_int(dest_height), Xen_to_C_GdkInterpType(interp_type)))); } static Xen gxg_gdk_pixbuf_composite_color_simple(Xen arglist) { #define H_gdk_pixbuf_composite_color_simple "GdkPixbuf* gdk_pixbuf_composite_color_simple(GdkPixbuf* src, \ int dest_width, int dest_height, GdkInterpType interp_type, int overall_alpha, int check_size, guint32 color1, \ guint32 color2)" Xen src, dest_width, dest_height, interp_type, overall_alpha, check_size, color1, color2; src = Xen_list_ref(arglist, 0); dest_width = Xen_list_ref(arglist, 1); dest_height = Xen_list_ref(arglist, 2); interp_type = Xen_list_ref(arglist, 3); overall_alpha = Xen_list_ref(arglist, 4); check_size = Xen_list_ref(arglist, 5); color1 = Xen_list_ref(arglist, 6); color2 = Xen_list_ref(arglist, 7); Xen_check_type(Xen_is_GdkPixbuf_(src), src, 1, "gdk_pixbuf_composite_color_simple", "GdkPixbuf*"); Xen_check_type(Xen_is_int(dest_width), dest_width, 2, "gdk_pixbuf_composite_color_simple", "int"); Xen_check_type(Xen_is_int(dest_height), dest_height, 3, "gdk_pixbuf_composite_color_simple", "int"); Xen_check_type(Xen_is_GdkInterpType(interp_type), interp_type, 4, "gdk_pixbuf_composite_color_simple", "GdkInterpType"); Xen_check_type(Xen_is_int(overall_alpha), overall_alpha, 5, "gdk_pixbuf_composite_color_simple", "int"); Xen_check_type(Xen_is_int(check_size), check_size, 6, "gdk_pixbuf_composite_color_simple", "int"); Xen_check_type(Xen_is_guint32(color1), color1, 7, "gdk_pixbuf_composite_color_simple", "guint32"); Xen_check_type(Xen_is_guint32(color2), color2, 8, "gdk_pixbuf_composite_color_simple", "guint32"); return(C_to_Xen_GdkPixbuf_(gdk_pixbuf_composite_color_simple(Xen_to_C_GdkPixbuf_(src), Xen_to_C_int(dest_width), Xen_to_C_int(dest_height), Xen_to_C_GdkInterpType(interp_type), Xen_to_C_int(overall_alpha), Xen_to_C_int(check_size), Xen_to_C_guint32(color1), Xen_to_C_guint32(color2)))); } static Xen gxg_gdk_pixbuf_animation_new_from_file(Xen filename, Xen ignore_error) { #define H_gdk_pixbuf_animation_new_from_file "GdkPixbufAnimation* gdk_pixbuf_animation_new_from_file(char* filename, \ GError** [error])" GError* ref_error = NULL; Xen_check_type(Xen_is_char_(filename), filename, 1, "gdk_pixbuf_animation_new_from_file", "char*"); { Xen result; result = C_to_Xen_GdkPixbufAnimation_(gdk_pixbuf_animation_new_from_file(Xen_to_C_char_(filename), &ref_error)); return(Xen_list_2(result, C_to_Xen_GError_(ref_error))); } } static Xen gxg_gdk_pixbuf_animation_get_width(Xen animation) { #define H_gdk_pixbuf_animation_get_width "int gdk_pixbuf_animation_get_width(GdkPixbufAnimation* animation)" Xen_check_type(Xen_is_GdkPixbufAnimation_(animation), animation, 1, "gdk_pixbuf_animation_get_width", "GdkPixbufAnimation*"); return(C_to_Xen_int(gdk_pixbuf_animation_get_width(Xen_to_C_GdkPixbufAnimation_(animation)))); } static Xen gxg_gdk_pixbuf_animation_get_height(Xen animation) { #define H_gdk_pixbuf_animation_get_height "int gdk_pixbuf_animation_get_height(GdkPixbufAnimation* animation)" Xen_check_type(Xen_is_GdkPixbufAnimation_(animation), animation, 1, "gdk_pixbuf_animation_get_height", "GdkPixbufAnimation*"); return(C_to_Xen_int(gdk_pixbuf_animation_get_height(Xen_to_C_GdkPixbufAnimation_(animation)))); } static Xen gxg_gdk_pixbuf_animation_is_static_image(Xen animation) { #define H_gdk_pixbuf_animation_is_static_image "gboolean gdk_pixbuf_animation_is_static_image(GdkPixbufAnimation* animation)" Xen_check_type(Xen_is_GdkPixbufAnimation_(animation), animation, 1, "gdk_pixbuf_animation_is_static_image", "GdkPixbufAnimation*"); return(C_to_Xen_gboolean(gdk_pixbuf_animation_is_static_image(Xen_to_C_GdkPixbufAnimation_(animation)))); } static Xen gxg_gdk_pixbuf_animation_get_static_image(Xen animation) { #define H_gdk_pixbuf_animation_get_static_image "GdkPixbuf* gdk_pixbuf_animation_get_static_image(GdkPixbufAnimation* animation)" Xen_check_type(Xen_is_GdkPixbufAnimation_(animation), animation, 1, "gdk_pixbuf_animation_get_static_image", "GdkPixbufAnimation*"); return(C_to_Xen_GdkPixbuf_(gdk_pixbuf_animation_get_static_image(Xen_to_C_GdkPixbufAnimation_(animation)))); } static Xen gxg_gdk_pixbuf_animation_get_iter(Xen animation, Xen start_time) { #define H_gdk_pixbuf_animation_get_iter "GdkPixbufAnimationIter* gdk_pixbuf_animation_get_iter(GdkPixbufAnimation* animation, \ GTimeVal* start_time)" Xen_check_type(Xen_is_GdkPixbufAnimation_(animation), animation, 1, "gdk_pixbuf_animation_get_iter", "GdkPixbufAnimation*"); Xen_check_type(Xen_is_GTimeVal_(start_time), start_time, 2, "gdk_pixbuf_animation_get_iter", "GTimeVal*"); return(C_to_Xen_GdkPixbufAnimationIter_(gdk_pixbuf_animation_get_iter(Xen_to_C_GdkPixbufAnimation_(animation), Xen_to_C_GTimeVal_(start_time)))); } static Xen gxg_gdk_pixbuf_animation_iter_get_delay_time(Xen iter) { #define H_gdk_pixbuf_animation_iter_get_delay_time "int gdk_pixbuf_animation_iter_get_delay_time(GdkPixbufAnimationIter* iter)" Xen_check_type(Xen_is_GdkPixbufAnimationIter_(iter), iter, 1, "gdk_pixbuf_animation_iter_get_delay_time", "GdkPixbufAnimationIter*"); return(C_to_Xen_int(gdk_pixbuf_animation_iter_get_delay_time(Xen_to_C_GdkPixbufAnimationIter_(iter)))); } static Xen gxg_gdk_pixbuf_animation_iter_get_pixbuf(Xen iter) { #define H_gdk_pixbuf_animation_iter_get_pixbuf "GdkPixbuf* gdk_pixbuf_animation_iter_get_pixbuf(GdkPixbufAnimationIter* iter)" Xen_check_type(Xen_is_GdkPixbufAnimationIter_(iter), iter, 1, "gdk_pixbuf_animation_iter_get_pixbuf", "GdkPixbufAnimationIter*"); return(C_to_Xen_GdkPixbuf_(gdk_pixbuf_animation_iter_get_pixbuf(Xen_to_C_GdkPixbufAnimationIter_(iter)))); } static Xen gxg_gdk_pixbuf_animation_iter_on_currently_loading_frame(Xen iter) { #define H_gdk_pixbuf_animation_iter_on_currently_loading_frame "gboolean gdk_pixbuf_animation_iter_on_currently_loading_frame(GdkPixbufAnimationIter* iter)" Xen_check_type(Xen_is_GdkPixbufAnimationIter_(iter), iter, 1, "gdk_pixbuf_animation_iter_on_currently_loading_frame", "GdkPixbufAnimationIter*"); return(C_to_Xen_gboolean(gdk_pixbuf_animation_iter_on_currently_loading_frame(Xen_to_C_GdkPixbufAnimationIter_(iter)))); } static Xen gxg_gdk_pixbuf_animation_iter_advance(Xen iter, Xen current_time) { #define H_gdk_pixbuf_animation_iter_advance "gboolean gdk_pixbuf_animation_iter_advance(GdkPixbufAnimationIter* iter, \ GTimeVal* current_time)" Xen_check_type(Xen_is_GdkPixbufAnimationIter_(iter), iter, 1, "gdk_pixbuf_animation_iter_advance", "GdkPixbufAnimationIter*"); Xen_check_type(Xen_is_GTimeVal_(current_time), current_time, 2, "gdk_pixbuf_animation_iter_advance", "GTimeVal*"); return(C_to_Xen_gboolean(gdk_pixbuf_animation_iter_advance(Xen_to_C_GdkPixbufAnimationIter_(iter), Xen_to_C_GTimeVal_(current_time)))); } static Xen gxg_gdk_pixbuf_get_option(Xen pixbuf, Xen key) { #define H_gdk_pixbuf_get_option "gchar* gdk_pixbuf_get_option(GdkPixbuf* pixbuf, gchar* key)" Xen_check_type(Xen_is_GdkPixbuf_(pixbuf), pixbuf, 1, "gdk_pixbuf_get_option", "GdkPixbuf*"); Xen_check_type(Xen_is_gchar_(key), key, 2, "gdk_pixbuf_get_option", "gchar*"); return(C_to_Xen_gchar_(gdk_pixbuf_get_option(Xen_to_C_GdkPixbuf_(pixbuf), Xen_to_C_gchar_(key)))); } static Xen gxg_gtk_accel_group_new(void) { #define H_gtk_accel_group_new "GtkAccelGroup* gtk_accel_group_new( void)" return(C_to_Xen_GtkAccelGroup_(gtk_accel_group_new())); } static Xen gxg_gtk_accel_group_lock(Xen accel_group) { #define H_gtk_accel_group_lock "void gtk_accel_group_lock(GtkAccelGroup* accel_group)" Xen_check_type(Xen_is_GtkAccelGroup_(accel_group), accel_group, 1, "gtk_accel_group_lock", "GtkAccelGroup*"); gtk_accel_group_lock(Xen_to_C_GtkAccelGroup_(accel_group)); return(Xen_false); } static Xen gxg_gtk_accel_group_unlock(Xen accel_group) { #define H_gtk_accel_group_unlock "void gtk_accel_group_unlock(GtkAccelGroup* accel_group)" Xen_check_type(Xen_is_GtkAccelGroup_(accel_group), accel_group, 1, "gtk_accel_group_unlock", "GtkAccelGroup*"); gtk_accel_group_unlock(Xen_to_C_GtkAccelGroup_(accel_group)); return(Xen_false); } static Xen gxg_gtk_accel_group_connect(Xen accel_group, Xen accel_key, Xen accel_mods, Xen accel_flags, Xen closure) { #define H_gtk_accel_group_connect "void gtk_accel_group_connect(GtkAccelGroup* accel_group, guint accel_key, \ GdkModifierType accel_mods, GtkAccelFlags accel_flags, GClosure* closure)" Xen_check_type(Xen_is_GtkAccelGroup_(accel_group), accel_group, 1, "gtk_accel_group_connect", "GtkAccelGroup*"); Xen_check_type(Xen_is_guint(accel_key), accel_key, 2, "gtk_accel_group_connect", "guint"); Xen_check_type(Xen_is_GdkModifierType(accel_mods), accel_mods, 3, "gtk_accel_group_connect", "GdkModifierType"); Xen_check_type(Xen_is_GtkAccelFlags(accel_flags), accel_flags, 4, "gtk_accel_group_connect", "GtkAccelFlags"); Xen_check_type(Xen_is_GClosure_(closure) || Xen_is_false(closure), closure, 5, "gtk_accel_group_connect", "GClosure*"); gtk_accel_group_connect(Xen_to_C_GtkAccelGroup_(accel_group), Xen_to_C_guint(accel_key), Xen_to_C_GdkModifierType(accel_mods), Xen_to_C_GtkAccelFlags(accel_flags), Xen_to_C_GClosure_(closure)); return(Xen_false); } static Xen gxg_gtk_accel_group_connect_by_path(Xen accel_group, Xen accel_path, Xen closure) { #define H_gtk_accel_group_connect_by_path "void gtk_accel_group_connect_by_path(GtkAccelGroup* accel_group, \ gchar* accel_path, GClosure* closure)" Xen_check_type(Xen_is_GtkAccelGroup_(accel_group), accel_group, 1, "gtk_accel_group_connect_by_path", "GtkAccelGroup*"); Xen_check_type(Xen_is_gchar_(accel_path), accel_path, 2, "gtk_accel_group_connect_by_path", "gchar*"); Xen_check_type(Xen_is_GClosure_(closure) || Xen_is_false(closure), closure, 3, "gtk_accel_group_connect_by_path", "GClosure*"); gtk_accel_group_connect_by_path(Xen_to_C_GtkAccelGroup_(accel_group), Xen_to_C_gchar_(accel_path), Xen_to_C_GClosure_(closure)); return(Xen_false); } static Xen gxg_gtk_accel_group_disconnect(Xen accel_group, Xen closure) { #define H_gtk_accel_group_disconnect "gboolean gtk_accel_group_disconnect(GtkAccelGroup* accel_group, \ GClosure* closure)" Xen_check_type(Xen_is_GtkAccelGroup_(accel_group), accel_group, 1, "gtk_accel_group_disconnect", "GtkAccelGroup*"); Xen_check_type(Xen_is_GClosure_(closure) || Xen_is_false(closure), closure, 2, "gtk_accel_group_disconnect", "GClosure*"); return(C_to_Xen_gboolean(gtk_accel_group_disconnect(Xen_to_C_GtkAccelGroup_(accel_group), Xen_to_C_GClosure_(closure)))); } static Xen gxg_gtk_accel_group_disconnect_key(Xen accel_group, Xen accel_key, Xen accel_mods) { #define H_gtk_accel_group_disconnect_key "gboolean gtk_accel_group_disconnect_key(GtkAccelGroup* accel_group, \ guint accel_key, GdkModifierType accel_mods)" Xen_check_type(Xen_is_GtkAccelGroup_(accel_group), accel_group, 1, "gtk_accel_group_disconnect_key", "GtkAccelGroup*"); Xen_check_type(Xen_is_guint(accel_key), accel_key, 2, "gtk_accel_group_disconnect_key", "guint"); Xen_check_type(Xen_is_GdkModifierType(accel_mods), accel_mods, 3, "gtk_accel_group_disconnect_key", "GdkModifierType"); return(C_to_Xen_gboolean(gtk_accel_group_disconnect_key(Xen_to_C_GtkAccelGroup_(accel_group), Xen_to_C_guint(accel_key), Xen_to_C_GdkModifierType(accel_mods)))); } static Xen gxg_gtk_accel_groups_activate(Xen object, Xen accel_key, Xen accel_mods) { #define H_gtk_accel_groups_activate "gboolean gtk_accel_groups_activate(GObject* object, guint accel_key, \ GdkModifierType accel_mods)" Xen_check_type(Xen_is_GObject_(object), object, 1, "gtk_accel_groups_activate", "GObject*"); Xen_check_type(Xen_is_guint(accel_key), accel_key, 2, "gtk_accel_groups_activate", "guint"); Xen_check_type(Xen_is_GdkModifierType(accel_mods), accel_mods, 3, "gtk_accel_groups_activate", "GdkModifierType"); return(C_to_Xen_gboolean(gtk_accel_groups_activate(Xen_to_C_GObject_(object), Xen_to_C_guint(accel_key), Xen_to_C_GdkModifierType(accel_mods)))); } static Xen gxg_gtk_accel_groups_from_object(Xen object) { #define H_gtk_accel_groups_from_object "GSList* gtk_accel_groups_from_object(GObject* object)" Xen_check_type(Xen_is_GObject_(object), object, 1, "gtk_accel_groups_from_object", "GObject*"); return(C_to_Xen_GSList_(gtk_accel_groups_from_object(Xen_to_C_GObject_(object)))); } static Xen gxg_gtk_accel_group_find(Xen accel_group, Xen func, Xen func_info) { #define H_gtk_accel_group_find "GtkAccelKey* gtk_accel_group_find(GtkAccelGroup* accel_group, lambda3 func, \ lambda_data func_info)" Xen_check_type(Xen_is_GtkAccelGroup_(accel_group), accel_group, 1, "gtk_accel_group_find", "GtkAccelGroup*"); Xen_check_type(Xen_is_lambda3(func), func, 2, "gtk_accel_group_find", "lambda3"); if (!Xen_is_bound(func_info)) func_info = Xen_false; else Xen_check_type(Xen_is_lambda_data(func_info), func_info, 3, "gtk_accel_group_find", "lambda_data"); { Xen result; int loc; Xen gxg_ptr = Xen_list_5(func, func_info, Xen_false, Xen_false, Xen_false); loc = xm_protect(gxg_ptr); Xen_list_set(gxg_ptr, 2, C_int_to_Xen_integer(loc)); result = C_to_Xen_GtkAccelKey_(gtk_accel_group_find(Xen_to_C_GtkAccelGroup_(accel_group), Xen_to_C_lambda3(func), Xen_to_C_lambda_data(func_info))); xm_unprotect_at(loc); return(result); } } static Xen gxg_gtk_accel_group_from_accel_closure(Xen closure) { #define H_gtk_accel_group_from_accel_closure "GtkAccelGroup* gtk_accel_group_from_accel_closure(GClosure* closure)" Xen_check_type(Xen_is_GClosure_(closure) || Xen_is_false(closure), closure, 1, "gtk_accel_group_from_accel_closure", "GClosure*"); return(C_to_Xen_GtkAccelGroup_(gtk_accel_group_from_accel_closure(Xen_to_C_GClosure_(closure)))); } static Xen gxg_gtk_accelerator_valid(Xen keyval, Xen modifiers) { #define H_gtk_accelerator_valid "gboolean gtk_accelerator_valid(guint keyval, GdkModifierType modifiers)" Xen_check_type(Xen_is_guint(keyval), keyval, 1, "gtk_accelerator_valid", "guint"); Xen_check_type(Xen_is_GdkModifierType(modifiers), modifiers, 2, "gtk_accelerator_valid", "GdkModifierType"); return(C_to_Xen_gboolean(gtk_accelerator_valid(Xen_to_C_guint(keyval), Xen_to_C_GdkModifierType(modifiers)))); } static Xen gxg_gtk_accelerator_parse(Xen accelerator, Xen ignore_accelerator_key, Xen ignore_accelerator_mods) { #define H_gtk_accelerator_parse "void gtk_accelerator_parse(gchar* accelerator, guint* [accelerator_key], \ GdkModifierType* [accelerator_mods])" guint ref_accelerator_key; GdkModifierType ref_accelerator_mods; Xen_check_type(Xen_is_gchar_(accelerator), accelerator, 1, "gtk_accelerator_parse", "gchar*"); gtk_accelerator_parse(Xen_to_C_gchar_(accelerator), &ref_accelerator_key, &ref_accelerator_mods); return(Xen_list_2(C_to_Xen_guint(ref_accelerator_key), C_to_Xen_GdkModifierType(ref_accelerator_mods))); } static Xen gxg_gtk_accelerator_name(Xen accelerator_key, Xen accelerator_mods) { #define H_gtk_accelerator_name "gchar* gtk_accelerator_name(guint accelerator_key, GdkModifierType accelerator_mods)" Xen_check_type(Xen_is_guint(accelerator_key), accelerator_key, 1, "gtk_accelerator_name", "guint"); Xen_check_type(Xen_is_GdkModifierType(accelerator_mods), accelerator_mods, 2, "gtk_accelerator_name", "GdkModifierType"); { gchar* result; Xen rtn; result = gtk_accelerator_name(Xen_to_C_guint(accelerator_key), Xen_to_C_GdkModifierType(accelerator_mods)); rtn = C_to_Xen_gchar_(result); g_free(result); return(rtn); } } static Xen gxg_gtk_accelerator_set_default_mod_mask(Xen default_mod_mask) { #define H_gtk_accelerator_set_default_mod_mask "void gtk_accelerator_set_default_mod_mask(GdkModifierType default_mod_mask)" Xen_check_type(Xen_is_GdkModifierType(default_mod_mask), default_mod_mask, 1, "gtk_accelerator_set_default_mod_mask", "GdkModifierType"); gtk_accelerator_set_default_mod_mask(Xen_to_C_GdkModifierType(default_mod_mask)); return(Xen_false); } static Xen gxg_gtk_accel_group_query(Xen accel_group, Xen accel_key, Xen accel_mods, Xen ignore_n_entries) { #define H_gtk_accel_group_query "GtkAccelGroupEntry* gtk_accel_group_query(GtkAccelGroup* accel_group, \ guint accel_key, GdkModifierType accel_mods, guint* [n_entries])" guint ref_n_entries; Xen_check_type(Xen_is_GtkAccelGroup_(accel_group), accel_group, 1, "gtk_accel_group_query", "GtkAccelGroup*"); Xen_check_type(Xen_is_guint(accel_key), accel_key, 2, "gtk_accel_group_query", "guint"); Xen_check_type(Xen_is_GdkModifierType(accel_mods), accel_mods, 3, "gtk_accel_group_query", "GdkModifierType"); { Xen result; result = C_to_Xen_GtkAccelGroupEntry_(gtk_accel_group_query(Xen_to_C_GtkAccelGroup_(accel_group), Xen_to_C_guint(accel_key), Xen_to_C_GdkModifierType(accel_mods), &ref_n_entries)); return(Xen_list_2(result, C_to_Xen_guint(ref_n_entries))); } } static Xen gxg_gtk_accel_group_activate(Xen accel_group, Xen accel_quark, Xen acceleratable, Xen accel_key, Xen accel_mods) { #define H_gtk_accel_group_activate "gboolean gtk_accel_group_activate(GtkAccelGroup* accel_group, GQuark accel_quark, \ GObject* acceleratable, guint accel_key, GdkModifierType accel_mods)" Xen_check_type(Xen_is_GtkAccelGroup_(accel_group), accel_group, 1, "gtk_accel_group_activate", "GtkAccelGroup*"); Xen_check_type(Xen_is_GQuark(accel_quark), accel_quark, 2, "gtk_accel_group_activate", "GQuark"); Xen_check_type(Xen_is_GObject_(acceleratable), acceleratable, 3, "gtk_accel_group_activate", "GObject*"); Xen_check_type(Xen_is_guint(accel_key), accel_key, 4, "gtk_accel_group_activate", "guint"); Xen_check_type(Xen_is_GdkModifierType(accel_mods), accel_mods, 5, "gtk_accel_group_activate", "GdkModifierType"); return(C_to_Xen_gboolean(gtk_accel_group_activate(Xen_to_C_GtkAccelGroup_(accel_group), Xen_to_C_GQuark(accel_quark), Xen_to_C_GObject_(acceleratable), Xen_to_C_guint(accel_key), Xen_to_C_GdkModifierType(accel_mods)))); } static Xen gxg_gtk_accel_label_new(Xen string) { #define H_gtk_accel_label_new "GtkWidget* gtk_accel_label_new(gchar* string)" Xen_check_type(Xen_is_gchar_(string), string, 1, "gtk_accel_label_new", "gchar*"); return(C_to_Xen_GtkWidget_(gtk_accel_label_new(Xen_to_C_gchar_(string)))); } static Xen gxg_gtk_accel_label_get_accel_widget(Xen accel_label) { #define H_gtk_accel_label_get_accel_widget "GtkWidget* gtk_accel_label_get_accel_widget(GtkAccelLabel* accel_label)" Xen_check_type(Xen_is_GtkAccelLabel_(accel_label), accel_label, 1, "gtk_accel_label_get_accel_widget", "GtkAccelLabel*"); return(C_to_Xen_GtkWidget_(gtk_accel_label_get_accel_widget(Xen_to_C_GtkAccelLabel_(accel_label)))); } static Xen gxg_gtk_accel_label_get_accel_width(Xen accel_label) { #define H_gtk_accel_label_get_accel_width "guint gtk_accel_label_get_accel_width(GtkAccelLabel* accel_label)" Xen_check_type(Xen_is_GtkAccelLabel_(accel_label), accel_label, 1, "gtk_accel_label_get_accel_width", "GtkAccelLabel*"); return(C_to_Xen_guint(gtk_accel_label_get_accel_width(Xen_to_C_GtkAccelLabel_(accel_label)))); } static Xen gxg_gtk_accel_label_set_accel_widget(Xen accel_label, Xen accel_widget) { #define H_gtk_accel_label_set_accel_widget "void gtk_accel_label_set_accel_widget(GtkAccelLabel* accel_label, \ GtkWidget* accel_widget)" Xen_check_type(Xen_is_GtkAccelLabel_(accel_label), accel_label, 1, "gtk_accel_label_set_accel_widget", "GtkAccelLabel*"); Xen_check_type(Xen_is_GtkWidget_(accel_widget), accel_widget, 2, "gtk_accel_label_set_accel_widget", "GtkWidget*"); gtk_accel_label_set_accel_widget(Xen_to_C_GtkAccelLabel_(accel_label), Xen_to_C_GtkWidget_(accel_widget)); return(Xen_false); } static Xen gxg_gtk_accel_label_set_accel_closure(Xen accel_label, Xen closure) { #define H_gtk_accel_label_set_accel_closure "void gtk_accel_label_set_accel_closure(GtkAccelLabel* accel_label, \ GClosure* closure)" Xen_check_type(Xen_is_GtkAccelLabel_(accel_label), accel_label, 1, "gtk_accel_label_set_accel_closure", "GtkAccelLabel*"); Xen_check_type(Xen_is_GClosure_(closure) || Xen_is_false(closure), closure, 2, "gtk_accel_label_set_accel_closure", "GClosure*"); gtk_accel_label_set_accel_closure(Xen_to_C_GtkAccelLabel_(accel_label), Xen_to_C_GClosure_(closure)); return(Xen_false); } static Xen gxg_gtk_accel_label_refetch(Xen accel_label) { #define H_gtk_accel_label_refetch "gboolean gtk_accel_label_refetch(GtkAccelLabel* accel_label)" Xen_check_type(Xen_is_GtkAccelLabel_(accel_label), accel_label, 1, "gtk_accel_label_refetch", "GtkAccelLabel*"); return(C_to_Xen_gboolean(gtk_accel_label_refetch(Xen_to_C_GtkAccelLabel_(accel_label)))); } static Xen gxg_gtk_accel_map_add_entry(Xen accel_path, Xen accel_key, Xen accel_mods) { #define H_gtk_accel_map_add_entry "void gtk_accel_map_add_entry(gchar* accel_path, guint accel_key, \ GdkModifierType accel_mods)" Xen_check_type(Xen_is_gchar_(accel_path), accel_path, 1, "gtk_accel_map_add_entry", "gchar*"); Xen_check_type(Xen_is_guint(accel_key), accel_key, 2, "gtk_accel_map_add_entry", "guint"); Xen_check_type(Xen_is_GdkModifierType(accel_mods), accel_mods, 3, "gtk_accel_map_add_entry", "GdkModifierType"); gtk_accel_map_add_entry(Xen_to_C_gchar_(accel_path), Xen_to_C_guint(accel_key), Xen_to_C_GdkModifierType(accel_mods)); return(Xen_false); } static Xen gxg_gtk_accel_map_lookup_entry(Xen accel_path, Xen key) { #define H_gtk_accel_map_lookup_entry "gboolean gtk_accel_map_lookup_entry(gchar* accel_path, GtkAccelKey* key)" Xen_check_type(Xen_is_gchar_(accel_path), accel_path, 1, "gtk_accel_map_lookup_entry", "gchar*"); Xen_check_type(Xen_is_GtkAccelKey_(key), key, 2, "gtk_accel_map_lookup_entry", "GtkAccelKey*"); return(C_to_Xen_gboolean(gtk_accel_map_lookup_entry(Xen_to_C_gchar_(accel_path), Xen_to_C_GtkAccelKey_(key)))); } static Xen gxg_gtk_accel_map_change_entry(Xen accel_path, Xen accel_key, Xen accel_mods, Xen replace) { #define H_gtk_accel_map_change_entry "gboolean gtk_accel_map_change_entry(gchar* accel_path, guint accel_key, \ GdkModifierType accel_mods, gboolean replace)" Xen_check_type(Xen_is_gchar_(accel_path), accel_path, 1, "gtk_accel_map_change_entry", "gchar*"); Xen_check_type(Xen_is_guint(accel_key), accel_key, 2, "gtk_accel_map_change_entry", "guint"); Xen_check_type(Xen_is_GdkModifierType(accel_mods), accel_mods, 3, "gtk_accel_map_change_entry", "GdkModifierType"); Xen_check_type(Xen_is_gboolean(replace), replace, 4, "gtk_accel_map_change_entry", "gboolean"); return(C_to_Xen_gboolean(gtk_accel_map_change_entry(Xen_to_C_gchar_(accel_path), Xen_to_C_guint(accel_key), Xen_to_C_GdkModifierType(accel_mods), Xen_to_C_gboolean(replace)))); } static Xen gxg_gtk_accel_map_load(Xen file_name) { #define H_gtk_accel_map_load "void gtk_accel_map_load(gchar* file_name)" Xen_check_type(Xen_is_gchar_(file_name), file_name, 1, "gtk_accel_map_load", "gchar*"); gtk_accel_map_load(Xen_to_C_gchar_(file_name)); return(Xen_false); } static Xen gxg_gtk_accel_map_save(Xen file_name) { #define H_gtk_accel_map_save "void gtk_accel_map_save(gchar* file_name)" Xen_check_type(Xen_is_gchar_(file_name), file_name, 1, "gtk_accel_map_save", "gchar*"); gtk_accel_map_save(Xen_to_C_gchar_(file_name)); return(Xen_false); } static Xen gxg_gtk_accel_map_foreach(Xen func_info, Xen func) { #define H_gtk_accel_map_foreach "void gtk_accel_map_foreach(lambda_data func_info, GtkAccelMapForeach func)" Xen_check_type(Xen_is_lambda_data(func_info), func_info, 1, "gtk_accel_map_foreach", "lambda_data"); Xen_check_type(Xen_is_GtkAccelMapForeach(func), func, 2, "gtk_accel_map_foreach", "GtkAccelMapForeach"); { int loc; Xen gxg_ptr = Xen_list_5(func, func_info, Xen_false, Xen_false, Xen_false); loc = xm_protect(gxg_ptr); Xen_list_set(gxg_ptr, 2, C_int_to_Xen_integer(loc)); gtk_accel_map_foreach(Xen_to_C_lambda_data(func_info), Xen_to_C_GtkAccelMapForeach(func)); xm_unprotect_at(loc); return(Xen_false); } } static Xen gxg_gtk_accel_map_load_fd(Xen fd) { #define H_gtk_accel_map_load_fd "void gtk_accel_map_load_fd(gint fd)" Xen_check_type(Xen_is_gint(fd), fd, 1, "gtk_accel_map_load_fd", "gint"); gtk_accel_map_load_fd(Xen_to_C_gint(fd)); return(Xen_false); } static Xen gxg_gtk_accel_map_save_fd(Xen fd) { #define H_gtk_accel_map_save_fd "void gtk_accel_map_save_fd(gint fd)" Xen_check_type(Xen_is_gint(fd), fd, 1, "gtk_accel_map_save_fd", "gint"); gtk_accel_map_save_fd(Xen_to_C_gint(fd)); return(Xen_false); } static Xen gxg_gtk_accel_map_add_filter(Xen filter_pattern) { #define H_gtk_accel_map_add_filter "void gtk_accel_map_add_filter(gchar* filter_pattern)" Xen_check_type(Xen_is_gchar_(filter_pattern), filter_pattern, 1, "gtk_accel_map_add_filter", "gchar*"); gtk_accel_map_add_filter(Xen_to_C_gchar_(filter_pattern)); return(Xen_false); } static Xen gxg_gtk_accel_map_foreach_unfiltered(Xen func_info, Xen func) { #define H_gtk_accel_map_foreach_unfiltered "void gtk_accel_map_foreach_unfiltered(lambda_data func_info, \ GtkAccelMapForeach func)" Xen_check_type(Xen_is_lambda_data(func_info), func_info, 1, "gtk_accel_map_foreach_unfiltered", "lambda_data"); Xen_check_type(Xen_is_GtkAccelMapForeach(func), func, 2, "gtk_accel_map_foreach_unfiltered", "GtkAccelMapForeach"); { int loc; Xen gxg_ptr = Xen_list_5(func, func_info, Xen_false, Xen_false, Xen_false); loc = xm_protect(gxg_ptr); Xen_list_set(gxg_ptr, 2, C_int_to_Xen_integer(loc)); gtk_accel_map_foreach_unfiltered(Xen_to_C_lambda_data(func_info), Xen_to_C_GtkAccelMapForeach(func)); xm_unprotect_at(loc); return(Xen_false); } } static Xen gxg_gtk_adjustment_clamp_page(Xen adjustment, Xen lower, Xen upper) { #define H_gtk_adjustment_clamp_page "void gtk_adjustment_clamp_page(GtkAdjustment* adjustment, gdouble lower, \ gdouble upper)" Xen_check_type(Xen_is_GtkAdjustment_(adjustment), adjustment, 1, "gtk_adjustment_clamp_page", "GtkAdjustment*"); Xen_check_type(Xen_is_gdouble(lower), lower, 2, "gtk_adjustment_clamp_page", "gdouble"); Xen_check_type(Xen_is_gdouble(upper), upper, 3, "gtk_adjustment_clamp_page", "gdouble"); gtk_adjustment_clamp_page(Xen_to_C_GtkAdjustment_(adjustment), Xen_to_C_gdouble(lower), Xen_to_C_gdouble(upper)); return(Xen_false); } static Xen gxg_gtk_adjustment_get_value(Xen adjustment) { #define H_gtk_adjustment_get_value "gdouble gtk_adjustment_get_value(GtkAdjustment* adjustment)" Xen_check_type(Xen_is_GtkAdjustment_(adjustment), adjustment, 1, "gtk_adjustment_get_value", "GtkAdjustment*"); return(C_to_Xen_gdouble(gtk_adjustment_get_value(Xen_to_C_GtkAdjustment_(adjustment)))); } static Xen gxg_gtk_adjustment_set_value(Xen adjustment, Xen value) { #define H_gtk_adjustment_set_value "void gtk_adjustment_set_value(GtkAdjustment* adjustment, gdouble value)" Xen_check_type(Xen_is_GtkAdjustment_(adjustment), adjustment, 1, "gtk_adjustment_set_value", "GtkAdjustment*"); Xen_check_type(Xen_is_gdouble(value), value, 2, "gtk_adjustment_set_value", "gdouble"); gtk_adjustment_set_value(Xen_to_C_GtkAdjustment_(adjustment), Xen_to_C_gdouble(value)); return(Xen_false); } static Xen gxg_gtk_aspect_frame_new(Xen label, Xen xalign, Xen yalign, Xen ratio, Xen obey_child) { #define H_gtk_aspect_frame_new "GtkWidget* gtk_aspect_frame_new(gchar* label, gfloat xalign, gfloat yalign, \ gfloat ratio, gboolean obey_child)" Xen_check_type(Xen_is_gchar_(label), label, 1, "gtk_aspect_frame_new", "gchar*"); Xen_check_type(Xen_is_gfloat(xalign), xalign, 2, "gtk_aspect_frame_new", "gfloat"); Xen_check_type(Xen_is_gfloat(yalign), yalign, 3, "gtk_aspect_frame_new", "gfloat"); Xen_check_type(Xen_is_gfloat(ratio), ratio, 4, "gtk_aspect_frame_new", "gfloat"); Xen_check_type(Xen_is_gboolean(obey_child), obey_child, 5, "gtk_aspect_frame_new", "gboolean"); return(C_to_Xen_GtkWidget_(gtk_aspect_frame_new(Xen_to_C_gchar_(label), Xen_to_C_gfloat(xalign), Xen_to_C_gfloat(yalign), Xen_to_C_gfloat(ratio), Xen_to_C_gboolean(obey_child)))); } static Xen gxg_gtk_aspect_frame_set(Xen aspect_frame, Xen xalign, Xen yalign, Xen ratio, Xen obey_child) { #define H_gtk_aspect_frame_set "void gtk_aspect_frame_set(GtkAspectFrame* aspect_frame, gfloat xalign, \ gfloat yalign, gfloat ratio, gboolean obey_child)" Xen_check_type(Xen_is_GtkAspectFrame_(aspect_frame), aspect_frame, 1, "gtk_aspect_frame_set", "GtkAspectFrame*"); Xen_check_type(Xen_is_gfloat(xalign), xalign, 2, "gtk_aspect_frame_set", "gfloat"); Xen_check_type(Xen_is_gfloat(yalign), yalign, 3, "gtk_aspect_frame_set", "gfloat"); Xen_check_type(Xen_is_gfloat(ratio), ratio, 4, "gtk_aspect_frame_set", "gfloat"); Xen_check_type(Xen_is_gboolean(obey_child), obey_child, 5, "gtk_aspect_frame_set", "gboolean"); gtk_aspect_frame_set(Xen_to_C_GtkAspectFrame_(aspect_frame), Xen_to_C_gfloat(xalign), Xen_to_C_gfloat(yalign), Xen_to_C_gfloat(ratio), Xen_to_C_gboolean(obey_child)); return(Xen_false); } static Xen gxg_gtk_button_box_get_layout(Xen widget) { #define H_gtk_button_box_get_layout "GtkButtonBoxStyle gtk_button_box_get_layout(GtkButtonBox* widget)" Xen_check_type(Xen_is_GtkButtonBox_(widget), widget, 1, "gtk_button_box_get_layout", "GtkButtonBox*"); return(C_to_Xen_GtkButtonBoxStyle(gtk_button_box_get_layout(Xen_to_C_GtkButtonBox_(widget)))); } static Xen gxg_gtk_button_box_set_layout(Xen widget, Xen layout_style) { #define H_gtk_button_box_set_layout "void gtk_button_box_set_layout(GtkButtonBox* widget, GtkButtonBoxStyle layout_style)" Xen_check_type(Xen_is_GtkButtonBox_(widget), widget, 1, "gtk_button_box_set_layout", "GtkButtonBox*"); Xen_check_type(Xen_is_GtkButtonBoxStyle(layout_style), layout_style, 2, "gtk_button_box_set_layout", "GtkButtonBoxStyle"); gtk_button_box_set_layout(Xen_to_C_GtkButtonBox_(widget), Xen_to_C_GtkButtonBoxStyle(layout_style)); return(Xen_false); } static Xen gxg_gtk_button_box_set_child_secondary(Xen widget, Xen child, Xen is_secondary) { #define H_gtk_button_box_set_child_secondary "void gtk_button_box_set_child_secondary(GtkButtonBox* widget, \ GtkWidget* child, gboolean is_secondary)" Xen_check_type(Xen_is_GtkButtonBox_(widget), widget, 1, "gtk_button_box_set_child_secondary", "GtkButtonBox*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_button_box_set_child_secondary", "GtkWidget*"); Xen_check_type(Xen_is_gboolean(is_secondary), is_secondary, 3, "gtk_button_box_set_child_secondary", "gboolean"); gtk_button_box_set_child_secondary(Xen_to_C_GtkButtonBox_(widget), Xen_to_C_GtkWidget_(child), Xen_to_C_gboolean(is_secondary)); return(Xen_false); } static Xen gxg_gtk_binding_set_new(Xen set_name) { #define H_gtk_binding_set_new "GtkBindingSet* gtk_binding_set_new(gchar* set_name)" Xen_check_type(Xen_is_gchar_(set_name), set_name, 1, "gtk_binding_set_new", "gchar*"); return(C_to_Xen_GtkBindingSet_(gtk_binding_set_new(Xen_to_C_gchar_(set_name)))); } static Xen gxg_gtk_binding_set_by_class(Xen object_class) { #define H_gtk_binding_set_by_class "GtkBindingSet* gtk_binding_set_by_class(gpointer object_class)" Xen_check_type(Xen_is_gpointer(object_class), object_class, 1, "gtk_binding_set_by_class", "gpointer"); return(C_to_Xen_GtkBindingSet_(gtk_binding_set_by_class(Xen_to_C_gpointer(object_class)))); } static Xen gxg_gtk_binding_set_find(Xen set_name) { #define H_gtk_binding_set_find "GtkBindingSet* gtk_binding_set_find(gchar* set_name)" Xen_check_type(Xen_is_gchar_(set_name), set_name, 1, "gtk_binding_set_find", "gchar*"); return(C_to_Xen_GtkBindingSet_(gtk_binding_set_find(Xen_to_C_gchar_(set_name)))); } static Xen gxg_gtk_binding_entry_remove(Xen binding_set, Xen keyval, Xen modifiers) { #define H_gtk_binding_entry_remove "void gtk_binding_entry_remove(GtkBindingSet* binding_set, guint keyval, \ GdkModifierType modifiers)" Xen_check_type(Xen_is_GtkBindingSet_(binding_set), binding_set, 1, "gtk_binding_entry_remove", "GtkBindingSet*"); Xen_check_type(Xen_is_guint(keyval), keyval, 2, "gtk_binding_entry_remove", "guint"); Xen_check_type(Xen_is_GdkModifierType(modifiers), modifiers, 3, "gtk_binding_entry_remove", "GdkModifierType"); gtk_binding_entry_remove(Xen_to_C_GtkBindingSet_(binding_set), Xen_to_C_guint(keyval), Xen_to_C_GdkModifierType(modifiers)); return(Xen_false); } static Xen gxg_gtk_bin_get_child(Xen bin) { #define H_gtk_bin_get_child "GtkWidget* gtk_bin_get_child(GtkBin* bin)" Xen_check_type(Xen_is_GtkBin_(bin), bin, 1, "gtk_bin_get_child", "GtkBin*"); return(C_to_Xen_GtkWidget_(gtk_bin_get_child(Xen_to_C_GtkBin_(bin)))); } static Xen gxg_gtk_box_pack_start(Xen box, Xen child, Xen expand, Xen fill, Xen padding) { #define H_gtk_box_pack_start "void gtk_box_pack_start(GtkBox* box, GtkWidget* child, gboolean expand, \ gboolean fill, guint padding)" Xen_check_type(Xen_is_GtkBox_(box), box, 1, "gtk_box_pack_start", "GtkBox*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_box_pack_start", "GtkWidget*"); Xen_check_type(Xen_is_gboolean(expand), expand, 3, "gtk_box_pack_start", "gboolean"); Xen_check_type(Xen_is_gboolean(fill), fill, 4, "gtk_box_pack_start", "gboolean"); Xen_check_type(Xen_is_guint(padding), padding, 5, "gtk_box_pack_start", "guint"); gtk_box_pack_start(Xen_to_C_GtkBox_(box), Xen_to_C_GtkWidget_(child), Xen_to_C_gboolean(expand), Xen_to_C_gboolean(fill), Xen_to_C_guint(padding)); return(Xen_false); } static Xen gxg_gtk_box_pack_end(Xen box, Xen child, Xen expand, Xen fill, Xen padding) { #define H_gtk_box_pack_end "void gtk_box_pack_end(GtkBox* box, GtkWidget* child, gboolean expand, gboolean fill, \ guint padding)" Xen_check_type(Xen_is_GtkBox_(box), box, 1, "gtk_box_pack_end", "GtkBox*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_box_pack_end", "GtkWidget*"); Xen_check_type(Xen_is_gboolean(expand), expand, 3, "gtk_box_pack_end", "gboolean"); Xen_check_type(Xen_is_gboolean(fill), fill, 4, "gtk_box_pack_end", "gboolean"); Xen_check_type(Xen_is_guint(padding), padding, 5, "gtk_box_pack_end", "guint"); gtk_box_pack_end(Xen_to_C_GtkBox_(box), Xen_to_C_GtkWidget_(child), Xen_to_C_gboolean(expand), Xen_to_C_gboolean(fill), Xen_to_C_guint(padding)); return(Xen_false); } static Xen gxg_gtk_box_set_homogeneous(Xen box, Xen homogeneous) { #define H_gtk_box_set_homogeneous "void gtk_box_set_homogeneous(GtkBox* box, gboolean homogeneous)" Xen_check_type(Xen_is_GtkBox_(box), box, 1, "gtk_box_set_homogeneous", "GtkBox*"); Xen_check_type(Xen_is_gboolean(homogeneous), homogeneous, 2, "gtk_box_set_homogeneous", "gboolean"); gtk_box_set_homogeneous(Xen_to_C_GtkBox_(box), Xen_to_C_gboolean(homogeneous)); return(Xen_false); } static Xen gxg_gtk_box_get_homogeneous(Xen box) { #define H_gtk_box_get_homogeneous "gboolean gtk_box_get_homogeneous(GtkBox* box)" Xen_check_type(Xen_is_GtkBox_(box), box, 1, "gtk_box_get_homogeneous", "GtkBox*"); return(C_to_Xen_gboolean(gtk_box_get_homogeneous(Xen_to_C_GtkBox_(box)))); } static Xen gxg_gtk_box_set_spacing(Xen box, Xen spacing) { #define H_gtk_box_set_spacing "void gtk_box_set_spacing(GtkBox* box, gint spacing)" Xen_check_type(Xen_is_GtkBox_(box), box, 1, "gtk_box_set_spacing", "GtkBox*"); Xen_check_type(Xen_is_gint(spacing), spacing, 2, "gtk_box_set_spacing", "gint"); gtk_box_set_spacing(Xen_to_C_GtkBox_(box), Xen_to_C_gint(spacing)); return(Xen_false); } static Xen gxg_gtk_box_get_spacing(Xen box) { #define H_gtk_box_get_spacing "gint gtk_box_get_spacing(GtkBox* box)" Xen_check_type(Xen_is_GtkBox_(box), box, 1, "gtk_box_get_spacing", "GtkBox*"); return(C_to_Xen_gint(gtk_box_get_spacing(Xen_to_C_GtkBox_(box)))); } static Xen gxg_gtk_box_reorder_child(Xen box, Xen child, Xen position) { #define H_gtk_box_reorder_child "void gtk_box_reorder_child(GtkBox* box, GtkWidget* child, gint position)" Xen_check_type(Xen_is_GtkBox_(box), box, 1, "gtk_box_reorder_child", "GtkBox*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_box_reorder_child", "GtkWidget*"); Xen_check_type(Xen_is_gint(position), position, 3, "gtk_box_reorder_child", "gint"); gtk_box_reorder_child(Xen_to_C_GtkBox_(box), Xen_to_C_GtkWidget_(child), Xen_to_C_gint(position)); return(Xen_false); } static Xen gxg_gtk_box_query_child_packing(Xen box, Xen child, Xen ignore_expand, Xen ignore_fill, Xen ignore_padding, Xen ignore_pack_type) { #define H_gtk_box_query_child_packing "void gtk_box_query_child_packing(GtkBox* box, GtkWidget* child, \ gboolean* [expand], gboolean* [fill], guint* [padding], GtkPackType* [pack_type])" gboolean ref_expand; gboolean ref_fill; guint ref_padding; GtkPackType ref_pack_type; Xen_check_type(Xen_is_GtkBox_(box), box, 1, "gtk_box_query_child_packing", "GtkBox*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_box_query_child_packing", "GtkWidget*"); gtk_box_query_child_packing(Xen_to_C_GtkBox_(box), Xen_to_C_GtkWidget_(child), &ref_expand, &ref_fill, &ref_padding, &ref_pack_type); return(Xen_list_4(C_to_Xen_gboolean(ref_expand), C_to_Xen_gboolean(ref_fill), C_to_Xen_guint(ref_padding), C_to_Xen_GtkPackType(ref_pack_type))); } static Xen gxg_gtk_box_set_child_packing(Xen box, Xen child, Xen expand, Xen fill, Xen padding, Xen pack_type) { #define H_gtk_box_set_child_packing "void gtk_box_set_child_packing(GtkBox* box, GtkWidget* child, \ gboolean expand, gboolean fill, guint padding, GtkPackType pack_type)" Xen_check_type(Xen_is_GtkBox_(box), box, 1, "gtk_box_set_child_packing", "GtkBox*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_box_set_child_packing", "GtkWidget*"); Xen_check_type(Xen_is_gboolean(expand), expand, 3, "gtk_box_set_child_packing", "gboolean"); Xen_check_type(Xen_is_gboolean(fill), fill, 4, "gtk_box_set_child_packing", "gboolean"); Xen_check_type(Xen_is_guint(padding), padding, 5, "gtk_box_set_child_packing", "guint"); Xen_check_type(Xen_is_GtkPackType(pack_type), pack_type, 6, "gtk_box_set_child_packing", "GtkPackType"); gtk_box_set_child_packing(Xen_to_C_GtkBox_(box), Xen_to_C_GtkWidget_(child), Xen_to_C_gboolean(expand), Xen_to_C_gboolean(fill), Xen_to_C_guint(padding), Xen_to_C_GtkPackType(pack_type)); return(Xen_false); } static Xen gxg_gtk_button_new(void) { #define H_gtk_button_new "GtkWidget* gtk_button_new( void)" return(C_to_Xen_GtkWidget_(gtk_button_new())); } static Xen gxg_gtk_button_new_with_label(Xen label) { #define H_gtk_button_new_with_label "GtkWidget* gtk_button_new_with_label(gchar* label)" Xen_check_type(Xen_is_gchar_(label), label, 1, "gtk_button_new_with_label", "gchar*"); return(C_to_Xen_GtkWidget_(gtk_button_new_with_label(Xen_to_C_gchar_(label)))); } static Xen gxg_gtk_button_new_with_mnemonic(Xen label) { #define H_gtk_button_new_with_mnemonic "GtkWidget* gtk_button_new_with_mnemonic(gchar* label)" Xen_check_type(Xen_is_gchar_(label), label, 1, "gtk_button_new_with_mnemonic", "gchar*"); return(C_to_Xen_GtkWidget_(gtk_button_new_with_mnemonic(Xen_to_C_gchar_(label)))); } static Xen gxg_gtk_button_clicked(Xen button) { #define H_gtk_button_clicked "void gtk_button_clicked(GtkButton* button)" Xen_check_type(Xen_is_GtkButton_(button), button, 1, "gtk_button_clicked", "GtkButton*"); gtk_button_clicked(Xen_to_C_GtkButton_(button)); return(Xen_false); } static Xen gxg_gtk_button_set_relief(Xen button, Xen newstyle) { #define H_gtk_button_set_relief "void gtk_button_set_relief(GtkButton* button, GtkReliefStyle newstyle)" Xen_check_type(Xen_is_GtkButton_(button), button, 1, "gtk_button_set_relief", "GtkButton*"); Xen_check_type(Xen_is_GtkReliefStyle(newstyle), newstyle, 2, "gtk_button_set_relief", "GtkReliefStyle"); gtk_button_set_relief(Xen_to_C_GtkButton_(button), Xen_to_C_GtkReliefStyle(newstyle)); return(Xen_false); } static Xen gxg_gtk_button_get_relief(Xen button) { #define H_gtk_button_get_relief "GtkReliefStyle gtk_button_get_relief(GtkButton* button)" Xen_check_type(Xen_is_GtkButton_(button), button, 1, "gtk_button_get_relief", "GtkButton*"); return(C_to_Xen_GtkReliefStyle(gtk_button_get_relief(Xen_to_C_GtkButton_(button)))); } static Xen gxg_gtk_button_set_label(Xen button, Xen label) { #define H_gtk_button_set_label "void gtk_button_set_label(GtkButton* button, gchar* label)" Xen_check_type(Xen_is_GtkButton_(button), button, 1, "gtk_button_set_label", "GtkButton*"); Xen_check_type(Xen_is_gchar_(label), label, 2, "gtk_button_set_label", "gchar*"); gtk_button_set_label(Xen_to_C_GtkButton_(button), Xen_to_C_gchar_(label)); return(Xen_false); } static Xen gxg_gtk_button_get_label(Xen button) { #define H_gtk_button_get_label "gchar* gtk_button_get_label(GtkButton* button)" Xen_check_type(Xen_is_GtkButton_(button), button, 1, "gtk_button_get_label", "GtkButton*"); return(C_to_Xen_gchar_(gtk_button_get_label(Xen_to_C_GtkButton_(button)))); } static Xen gxg_gtk_button_set_use_underline(Xen button, Xen use_underline) { #define H_gtk_button_set_use_underline "void gtk_button_set_use_underline(GtkButton* button, gboolean use_underline)" Xen_check_type(Xen_is_GtkButton_(button), button, 1, "gtk_button_set_use_underline", "GtkButton*"); Xen_check_type(Xen_is_gboolean(use_underline), use_underline, 2, "gtk_button_set_use_underline", "gboolean"); gtk_button_set_use_underline(Xen_to_C_GtkButton_(button), Xen_to_C_gboolean(use_underline)); return(Xen_false); } static Xen gxg_gtk_button_get_use_underline(Xen button) { #define H_gtk_button_get_use_underline "gboolean gtk_button_get_use_underline(GtkButton* button)" Xen_check_type(Xen_is_GtkButton_(button), button, 1, "gtk_button_get_use_underline", "GtkButton*"); return(C_to_Xen_gboolean(gtk_button_get_use_underline(Xen_to_C_GtkButton_(button)))); } static Xen gxg_gtk_calendar_new(void) { #define H_gtk_calendar_new "GtkWidget* gtk_calendar_new( void)" return(C_to_Xen_GtkWidget_(gtk_calendar_new())); } static Xen gxg_gtk_calendar_select_day(Xen calendar, Xen day) { #define H_gtk_calendar_select_day "void gtk_calendar_select_day(GtkCalendar* calendar, guint day)" Xen_check_type(Xen_is_GtkCalendar_(calendar), calendar, 1, "gtk_calendar_select_day", "GtkCalendar*"); Xen_check_type(Xen_is_guint(day), day, 2, "gtk_calendar_select_day", "guint"); gtk_calendar_select_day(Xen_to_C_GtkCalendar_(calendar), Xen_to_C_guint(day)); return(Xen_false); } static Xen gxg_gtk_calendar_clear_marks(Xen calendar) { #define H_gtk_calendar_clear_marks "void gtk_calendar_clear_marks(GtkCalendar* calendar)" Xen_check_type(Xen_is_GtkCalendar_(calendar), calendar, 1, "gtk_calendar_clear_marks", "GtkCalendar*"); gtk_calendar_clear_marks(Xen_to_C_GtkCalendar_(calendar)); return(Xen_false); } static Xen gxg_gtk_calendar_get_date(Xen calendar, Xen ignore_year, Xen ignore_month, Xen ignore_day) { #define H_gtk_calendar_get_date "void gtk_calendar_get_date(GtkCalendar* calendar, guint* [year], guint* [month], \ guint* [day])" guint ref_year; guint ref_month; guint ref_day; Xen_check_type(Xen_is_GtkCalendar_(calendar), calendar, 1, "gtk_calendar_get_date", "GtkCalendar*"); gtk_calendar_get_date(Xen_to_C_GtkCalendar_(calendar), &ref_year, &ref_month, &ref_day); return(Xen_list_3(C_to_Xen_guint(ref_year), C_to_Xen_guint(ref_month), C_to_Xen_guint(ref_day))); } static Xen gxg_gtk_cell_editable_start_editing(Xen cell_editable, Xen event) { #define H_gtk_cell_editable_start_editing "void gtk_cell_editable_start_editing(GtkCellEditable* cell_editable, \ GdkEvent* event)" Xen_check_type(Xen_is_GtkCellEditable_(cell_editable), cell_editable, 1, "gtk_cell_editable_start_editing", "GtkCellEditable*"); Xen_check_type(Xen_is_GdkEvent_(event) || Xen_is_false(event), event, 2, "gtk_cell_editable_start_editing", "GdkEvent*"); gtk_cell_editable_start_editing(Xen_to_C_GtkCellEditable_(cell_editable), Xen_to_C_GdkEvent_(event)); return(Xen_false); } static Xen gxg_gtk_cell_editable_editing_done(Xen cell_editable) { #define H_gtk_cell_editable_editing_done "void gtk_cell_editable_editing_done(GtkCellEditable* cell_editable)" Xen_check_type(Xen_is_GtkCellEditable_(cell_editable), cell_editable, 1, "gtk_cell_editable_editing_done", "GtkCellEditable*"); gtk_cell_editable_editing_done(Xen_to_C_GtkCellEditable_(cell_editable)); return(Xen_false); } static Xen gxg_gtk_cell_editable_remove_widget(Xen cell_editable) { #define H_gtk_cell_editable_remove_widget "void gtk_cell_editable_remove_widget(GtkCellEditable* cell_editable)" Xen_check_type(Xen_is_GtkCellEditable_(cell_editable), cell_editable, 1, "gtk_cell_editable_remove_widget", "GtkCellEditable*"); gtk_cell_editable_remove_widget(Xen_to_C_GtkCellEditable_(cell_editable)); return(Xen_false); } static Xen gxg_gtk_cell_renderer_activate(Xen cell, Xen event, Xen widget, Xen path, Xen background_area, Xen cell_area, Xen flags) { #define H_gtk_cell_renderer_activate "gboolean gtk_cell_renderer_activate(GtkCellRenderer* cell, GdkEvent* event, \ GtkWidget* widget, gchar* path, GdkRectangle* background_area, GdkRectangle* cell_area, GtkCellRendererState flags)" Xen_check_type(Xen_is_GtkCellRenderer_(cell), cell, 1, "gtk_cell_renderer_activate", "GtkCellRenderer*"); Xen_check_type(Xen_is_GdkEvent_(event), event, 2, "gtk_cell_renderer_activate", "GdkEvent*"); Xen_check_type(Xen_is_GtkWidget_(widget), widget, 3, "gtk_cell_renderer_activate", "GtkWidget*"); Xen_check_type(Xen_is_gchar_(path), path, 4, "gtk_cell_renderer_activate", "gchar*"); Xen_check_type(Xen_is_GdkRectangle_(background_area), background_area, 5, "gtk_cell_renderer_activate", "GdkRectangle*"); Xen_check_type(Xen_is_GdkRectangle_(cell_area), cell_area, 6, "gtk_cell_renderer_activate", "GdkRectangle*"); Xen_check_type(Xen_is_GtkCellRendererState(flags), flags, 7, "gtk_cell_renderer_activate", "GtkCellRendererState"); return(C_to_Xen_gboolean(gtk_cell_renderer_activate(Xen_to_C_GtkCellRenderer_(cell), Xen_to_C_GdkEvent_(event), Xen_to_C_GtkWidget_(widget), Xen_to_C_gchar_(path), Xen_to_C_GdkRectangle_(background_area), Xen_to_C_GdkRectangle_(cell_area), Xen_to_C_GtkCellRendererState(flags)))); } static Xen gxg_gtk_cell_renderer_start_editing(Xen cell, Xen event, Xen widget, Xen path, Xen background_area, Xen cell_area, Xen flags) { #define H_gtk_cell_renderer_start_editing "GtkCellEditable* gtk_cell_renderer_start_editing(GtkCellRenderer* cell, \ GdkEvent* event, GtkWidget* widget, gchar* path, GdkRectangle* background_area, GdkRectangle* cell_area, \ GtkCellRendererState flags)" Xen_check_type(Xen_is_GtkCellRenderer_(cell), cell, 1, "gtk_cell_renderer_start_editing", "GtkCellRenderer*"); Xen_check_type(Xen_is_GdkEvent_(event) || Xen_is_false(event), event, 2, "gtk_cell_renderer_start_editing", "GdkEvent*"); Xen_check_type(Xen_is_GtkWidget_(widget), widget, 3, "gtk_cell_renderer_start_editing", "GtkWidget*"); Xen_check_type(Xen_is_gchar_(path), path, 4, "gtk_cell_renderer_start_editing", "gchar*"); Xen_check_type(Xen_is_GdkRectangle_(background_area), background_area, 5, "gtk_cell_renderer_start_editing", "GdkRectangle*"); Xen_check_type(Xen_is_GdkRectangle_(cell_area), cell_area, 6, "gtk_cell_renderer_start_editing", "GdkRectangle*"); Xen_check_type(Xen_is_GtkCellRendererState(flags), flags, 7, "gtk_cell_renderer_start_editing", "GtkCellRendererState"); return(C_to_Xen_GtkCellEditable_(gtk_cell_renderer_start_editing(Xen_to_C_GtkCellRenderer_(cell), Xen_to_C_GdkEvent_(event), Xen_to_C_GtkWidget_(widget), Xen_to_C_gchar_(path), Xen_to_C_GdkRectangle_(background_area), Xen_to_C_GdkRectangle_(cell_area), Xen_to_C_GtkCellRendererState(flags)))); } static Xen gxg_gtk_cell_renderer_set_fixed_size(Xen cell, Xen width, Xen height) { #define H_gtk_cell_renderer_set_fixed_size "void gtk_cell_renderer_set_fixed_size(GtkCellRenderer* cell, \ gint width, gint height)" Xen_check_type(Xen_is_GtkCellRenderer_(cell), cell, 1, "gtk_cell_renderer_set_fixed_size", "GtkCellRenderer*"); Xen_check_type(Xen_is_gint(width), width, 2, "gtk_cell_renderer_set_fixed_size", "gint"); Xen_check_type(Xen_is_gint(height), height, 3, "gtk_cell_renderer_set_fixed_size", "gint"); gtk_cell_renderer_set_fixed_size(Xen_to_C_GtkCellRenderer_(cell), Xen_to_C_gint(width), Xen_to_C_gint(height)); return(Xen_false); } static Xen gxg_gtk_cell_renderer_get_fixed_size(Xen cell, Xen ignore_width, Xen ignore_height) { #define H_gtk_cell_renderer_get_fixed_size "void gtk_cell_renderer_get_fixed_size(GtkCellRenderer* cell, \ gint* [width], gint* [height])" gint ref_width; gint ref_height; Xen_check_type(Xen_is_GtkCellRenderer_(cell), cell, 1, "gtk_cell_renderer_get_fixed_size", "GtkCellRenderer*"); gtk_cell_renderer_get_fixed_size(Xen_to_C_GtkCellRenderer_(cell), &ref_width, &ref_height); return(Xen_list_2(C_to_Xen_gint(ref_width), C_to_Xen_gint(ref_height))); } static Xen gxg_gtk_cell_renderer_pixbuf_new(void) { #define H_gtk_cell_renderer_pixbuf_new "GtkCellRenderer* gtk_cell_renderer_pixbuf_new( void)" return(C_to_Xen_GtkCellRenderer_(gtk_cell_renderer_pixbuf_new())); } static Xen gxg_gtk_cell_renderer_text_new(void) { #define H_gtk_cell_renderer_text_new "GtkCellRenderer* gtk_cell_renderer_text_new( void)" return(C_to_Xen_GtkCellRenderer_(gtk_cell_renderer_text_new())); } static Xen gxg_gtk_cell_renderer_text_set_fixed_height_from_font(Xen renderer, Xen number_of_rows) { #define H_gtk_cell_renderer_text_set_fixed_height_from_font "void gtk_cell_renderer_text_set_fixed_height_from_font(GtkCellRendererText* renderer, \ gint number_of_rows)" Xen_check_type(Xen_is_GtkCellRendererText_(renderer), renderer, 1, "gtk_cell_renderer_text_set_fixed_height_from_font", "GtkCellRendererText*"); Xen_check_type(Xen_is_gint(number_of_rows), number_of_rows, 2, "gtk_cell_renderer_text_set_fixed_height_from_font", "gint"); gtk_cell_renderer_text_set_fixed_height_from_font(Xen_to_C_GtkCellRendererText_(renderer), Xen_to_C_gint(number_of_rows)); return(Xen_false); } static Xen gxg_gtk_cell_renderer_toggle_new(void) { #define H_gtk_cell_renderer_toggle_new "GtkCellRenderer* gtk_cell_renderer_toggle_new( void)" return(C_to_Xen_GtkCellRenderer_(gtk_cell_renderer_toggle_new())); } static Xen gxg_gtk_cell_renderer_toggle_get_radio(Xen toggle) { #define H_gtk_cell_renderer_toggle_get_radio "gboolean gtk_cell_renderer_toggle_get_radio(GtkCellRendererToggle* toggle)" Xen_check_type(Xen_is_GtkCellRendererToggle_(toggle), toggle, 1, "gtk_cell_renderer_toggle_get_radio", "GtkCellRendererToggle*"); return(C_to_Xen_gboolean(gtk_cell_renderer_toggle_get_radio(Xen_to_C_GtkCellRendererToggle_(toggle)))); } static Xen gxg_gtk_cell_renderer_toggle_set_radio(Xen toggle, Xen radio) { #define H_gtk_cell_renderer_toggle_set_radio "void gtk_cell_renderer_toggle_set_radio(GtkCellRendererToggle* toggle, \ gboolean radio)" Xen_check_type(Xen_is_GtkCellRendererToggle_(toggle), toggle, 1, "gtk_cell_renderer_toggle_set_radio", "GtkCellRendererToggle*"); Xen_check_type(Xen_is_gboolean(radio), radio, 2, "gtk_cell_renderer_toggle_set_radio", "gboolean"); gtk_cell_renderer_toggle_set_radio(Xen_to_C_GtkCellRendererToggle_(toggle), Xen_to_C_gboolean(radio)); return(Xen_false); } static Xen gxg_gtk_cell_renderer_toggle_get_active(Xen toggle) { #define H_gtk_cell_renderer_toggle_get_active "gboolean gtk_cell_renderer_toggle_get_active(GtkCellRendererToggle* toggle)" Xen_check_type(Xen_is_GtkCellRendererToggle_(toggle), toggle, 1, "gtk_cell_renderer_toggle_get_active", "GtkCellRendererToggle*"); return(C_to_Xen_gboolean(gtk_cell_renderer_toggle_get_active(Xen_to_C_GtkCellRendererToggle_(toggle)))); } static Xen gxg_gtk_cell_renderer_toggle_set_active(Xen toggle, Xen setting) { #define H_gtk_cell_renderer_toggle_set_active "void gtk_cell_renderer_toggle_set_active(GtkCellRendererToggle* toggle, \ gboolean setting)" Xen_check_type(Xen_is_GtkCellRendererToggle_(toggle), toggle, 1, "gtk_cell_renderer_toggle_set_active", "GtkCellRendererToggle*"); Xen_check_type(Xen_is_gboolean(setting), setting, 2, "gtk_cell_renderer_toggle_set_active", "gboolean"); gtk_cell_renderer_toggle_set_active(Xen_to_C_GtkCellRendererToggle_(toggle), Xen_to_C_gboolean(setting)); return(Xen_false); } static Xen gxg_gtk_check_button_new(void) { #define H_gtk_check_button_new "GtkWidget* gtk_check_button_new( void)" return(C_to_Xen_GtkWidget_(gtk_check_button_new())); } static Xen gxg_gtk_check_button_new_with_label(Xen label) { #define H_gtk_check_button_new_with_label "GtkWidget* gtk_check_button_new_with_label(gchar* label)" Xen_check_type(Xen_is_gchar_(label), label, 1, "gtk_check_button_new_with_label", "gchar*"); return(C_to_Xen_GtkWidget_(gtk_check_button_new_with_label(Xen_to_C_gchar_(label)))); } static Xen gxg_gtk_check_button_new_with_mnemonic(Xen label) { #define H_gtk_check_button_new_with_mnemonic "GtkWidget* gtk_check_button_new_with_mnemonic(gchar* label)" Xen_check_type(Xen_is_gchar_(label), label, 1, "gtk_check_button_new_with_mnemonic", "gchar*"); return(C_to_Xen_GtkWidget_(gtk_check_button_new_with_mnemonic(Xen_to_C_gchar_(label)))); } static Xen gxg_gtk_check_menu_item_new(void) { #define H_gtk_check_menu_item_new "GtkWidget* gtk_check_menu_item_new( void)" return(C_to_Xen_GtkWidget_(gtk_check_menu_item_new())); } static Xen gxg_gtk_check_menu_item_new_with_label(Xen label) { #define H_gtk_check_menu_item_new_with_label "GtkWidget* gtk_check_menu_item_new_with_label(gchar* label)" Xen_check_type(Xen_is_gchar_(label), label, 1, "gtk_check_menu_item_new_with_label", "gchar*"); return(C_to_Xen_GtkWidget_(gtk_check_menu_item_new_with_label(Xen_to_C_gchar_(label)))); } static Xen gxg_gtk_check_menu_item_new_with_mnemonic(Xen label) { #define H_gtk_check_menu_item_new_with_mnemonic "GtkWidget* gtk_check_menu_item_new_with_mnemonic(gchar* label)" Xen_check_type(Xen_is_gchar_(label), label, 1, "gtk_check_menu_item_new_with_mnemonic", "gchar*"); return(C_to_Xen_GtkWidget_(gtk_check_menu_item_new_with_mnemonic(Xen_to_C_gchar_(label)))); } static Xen gxg_gtk_check_menu_item_set_active(Xen check_menu_item, Xen is_active) { #define H_gtk_check_menu_item_set_active "void gtk_check_menu_item_set_active(GtkCheckMenuItem* check_menu_item, \ gboolean is_active)" Xen_check_type(Xen_is_GtkCheckMenuItem_(check_menu_item), check_menu_item, 1, "gtk_check_menu_item_set_active", "GtkCheckMenuItem*"); Xen_check_type(Xen_is_gboolean(is_active), is_active, 2, "gtk_check_menu_item_set_active", "gboolean"); gtk_check_menu_item_set_active(Xen_to_C_GtkCheckMenuItem_(check_menu_item), Xen_to_C_gboolean(is_active)); return(Xen_false); } static Xen gxg_gtk_check_menu_item_get_active(Xen check_menu_item) { #define H_gtk_check_menu_item_get_active "gboolean gtk_check_menu_item_get_active(GtkCheckMenuItem* check_menu_item)" Xen_check_type(Xen_is_GtkCheckMenuItem_(check_menu_item), check_menu_item, 1, "gtk_check_menu_item_get_active", "GtkCheckMenuItem*"); return(C_to_Xen_gboolean(gtk_check_menu_item_get_active(Xen_to_C_GtkCheckMenuItem_(check_menu_item)))); } static Xen gxg_gtk_check_menu_item_toggled(Xen check_menu_item) { #define H_gtk_check_menu_item_toggled "void gtk_check_menu_item_toggled(GtkCheckMenuItem* check_menu_item)" Xen_check_type(Xen_is_GtkCheckMenuItem_(check_menu_item), check_menu_item, 1, "gtk_check_menu_item_toggled", "GtkCheckMenuItem*"); gtk_check_menu_item_toggled(Xen_to_C_GtkCheckMenuItem_(check_menu_item)); return(Xen_false); } static Xen gxg_gtk_check_menu_item_set_inconsistent(Xen check_menu_item, Xen setting) { #define H_gtk_check_menu_item_set_inconsistent "void gtk_check_menu_item_set_inconsistent(GtkCheckMenuItem* check_menu_item, \ gboolean setting)" Xen_check_type(Xen_is_GtkCheckMenuItem_(check_menu_item), check_menu_item, 1, "gtk_check_menu_item_set_inconsistent", "GtkCheckMenuItem*"); Xen_check_type(Xen_is_gboolean(setting), setting, 2, "gtk_check_menu_item_set_inconsistent", "gboolean"); gtk_check_menu_item_set_inconsistent(Xen_to_C_GtkCheckMenuItem_(check_menu_item), Xen_to_C_gboolean(setting)); return(Xen_false); } static Xen gxg_gtk_check_menu_item_get_inconsistent(Xen check_menu_item) { #define H_gtk_check_menu_item_get_inconsistent "gboolean gtk_check_menu_item_get_inconsistent(GtkCheckMenuItem* check_menu_item)" Xen_check_type(Xen_is_GtkCheckMenuItem_(check_menu_item), check_menu_item, 1, "gtk_check_menu_item_get_inconsistent", "GtkCheckMenuItem*"); return(C_to_Xen_gboolean(gtk_check_menu_item_get_inconsistent(Xen_to_C_GtkCheckMenuItem_(check_menu_item)))); } static Xen gxg_gtk_clipboard_get(Xen selection) { #define H_gtk_clipboard_get "GtkClipboard* gtk_clipboard_get(GdkAtom selection)" Xen_check_type(Xen_is_GdkAtom(selection), selection, 1, "gtk_clipboard_get", "GdkAtom"); return(C_to_Xen_GtkClipboard_(gtk_clipboard_get(Xen_to_C_GdkAtom(selection)))); } static Xen gxg_gtk_clipboard_set_with_data(Xen clipboard, Xen targets, Xen n_targets, Xen func, Xen clear_func, Xen func_info) { #define H_gtk_clipboard_set_with_data "gboolean gtk_clipboard_set_with_data(GtkClipboard* clipboard, \ GtkTargetEntry* targets, guint n_targets, GtkClipboardGetFunc func, GtkClipboardClearFunc clear_func, \ lambda_data func_info)" Xen_check_type(Xen_is_GtkClipboard_(clipboard), clipboard, 1, "gtk_clipboard_set_with_data", "GtkClipboard*"); Xen_check_type(Xen_is_GtkTargetEntry_(targets), targets, 2, "gtk_clipboard_set_with_data", "GtkTargetEntry*"); Xen_check_type(Xen_is_guint(n_targets), n_targets, 3, "gtk_clipboard_set_with_data", "guint"); Xen_check_type(Xen_is_GtkClipboardGetFunc(func), func, 4, "gtk_clipboard_set_with_data", "GtkClipboardGetFunc"); Xen_check_type(Xen_is_GtkClipboardClearFunc(clear_func), clear_func, 5, "gtk_clipboard_set_with_data", "GtkClipboardClearFunc"); if (!Xen_is_bound(func_info)) func_info = Xen_false; else Xen_check_type(Xen_is_lambda_data(func_info), func_info, 6, "gtk_clipboard_set_with_data", "lambda_data"); { Xen result; Xen gxg_ptr = Xen_list_5(func, func_info, Xen_false, Xen_false, Xen_false); xm_protect(gxg_ptr); Xen_list_set(gxg_ptr, 2, clear_func); result = C_to_Xen_gboolean(gtk_clipboard_set_with_data(Xen_to_C_GtkClipboard_(clipboard), Xen_to_C_GtkTargetEntry_(targets), Xen_to_C_guint(n_targets), Xen_to_C_GtkClipboardGetFunc(func), Xen_to_C_GtkClipboardClearFunc(clear_func), Xen_to_C_lambda_data(func_info))); return(result); } } static Xen gxg_gtk_clipboard_get_owner(Xen clipboard) { #define H_gtk_clipboard_get_owner "GObject* gtk_clipboard_get_owner(GtkClipboard* clipboard)" Xen_check_type(Xen_is_GtkClipboard_(clipboard), clipboard, 1, "gtk_clipboard_get_owner", "GtkClipboard*"); return(C_to_Xen_GObject_(gtk_clipboard_get_owner(Xen_to_C_GtkClipboard_(clipboard)))); } static Xen gxg_gtk_clipboard_clear(Xen clipboard) { #define H_gtk_clipboard_clear "void gtk_clipboard_clear(GtkClipboard* clipboard)" Xen_check_type(Xen_is_GtkClipboard_(clipboard), clipboard, 1, "gtk_clipboard_clear", "GtkClipboard*"); gtk_clipboard_clear(Xen_to_C_GtkClipboard_(clipboard)); return(Xen_false); } static Xen gxg_gtk_clipboard_set_text(Xen clipboard, Xen text, Xen len) { #define H_gtk_clipboard_set_text "void gtk_clipboard_set_text(GtkClipboard* clipboard, gchar* text, \ gint len)" Xen_check_type(Xen_is_GtkClipboard_(clipboard), clipboard, 1, "gtk_clipboard_set_text", "GtkClipboard*"); Xen_check_type(Xen_is_gchar_(text), text, 2, "gtk_clipboard_set_text", "gchar*"); Xen_check_type(Xen_is_gint(len), len, 3, "gtk_clipboard_set_text", "gint"); gtk_clipboard_set_text(Xen_to_C_GtkClipboard_(clipboard), Xen_to_C_gchar_(text), Xen_to_C_gint(len)); return(Xen_false); } static Xen gxg_gtk_clipboard_request_contents(Xen clipboard, Xen target, Xen func, Xen func_info) { #define H_gtk_clipboard_request_contents "void gtk_clipboard_request_contents(GtkClipboard* clipboard, \ GdkAtom target, GtkClipboardReceivedFunc func, lambda_data func_info)" Xen_check_type(Xen_is_GtkClipboard_(clipboard), clipboard, 1, "gtk_clipboard_request_contents", "GtkClipboard*"); Xen_check_type(Xen_is_GdkAtom(target), target, 2, "gtk_clipboard_request_contents", "GdkAtom"); Xen_check_type(Xen_is_GtkClipboardReceivedFunc(func), func, 3, "gtk_clipboard_request_contents", "GtkClipboardReceivedFunc"); if (!Xen_is_bound(func_info)) func_info = Xen_false; else Xen_check_type(Xen_is_lambda_data(func_info), func_info, 4, "gtk_clipboard_request_contents", "lambda_data"); { int loc; Xen gxg_ptr = Xen_list_5(func, func_info, Xen_false, Xen_false, Xen_false); loc = xm_protect(gxg_ptr); Xen_list_set(gxg_ptr, 2, C_int_to_Xen_integer(loc)); gtk_clipboard_request_contents(Xen_to_C_GtkClipboard_(clipboard), Xen_to_C_GdkAtom(target), Xen_to_C_GtkClipboardReceivedFunc(func), Xen_to_C_lambda_data(func_info)); xm_unprotect_at(loc); return(Xen_false); } } static Xen gxg_gtk_clipboard_request_text(Xen clipboard, Xen func, Xen func_info) { #define H_gtk_clipboard_request_text "void gtk_clipboard_request_text(GtkClipboard* clipboard, GtkClipboardTextReceivedFunc func, \ lambda_data func_info)" Xen_check_type(Xen_is_GtkClipboard_(clipboard), clipboard, 1, "gtk_clipboard_request_text", "GtkClipboard*"); Xen_check_type(Xen_is_GtkClipboardTextReceivedFunc(func), func, 2, "gtk_clipboard_request_text", "GtkClipboardTextReceivedFunc"); if (!Xen_is_bound(func_info)) func_info = Xen_false; else Xen_check_type(Xen_is_lambda_data(func_info), func_info, 3, "gtk_clipboard_request_text", "lambda_data"); { int loc; Xen gxg_ptr = Xen_list_5(func, func_info, Xen_false, Xen_false, Xen_false); loc = xm_protect(gxg_ptr); Xen_list_set(gxg_ptr, 2, C_int_to_Xen_integer(loc)); gtk_clipboard_request_text(Xen_to_C_GtkClipboard_(clipboard), Xen_to_C_GtkClipboardTextReceivedFunc(func), Xen_to_C_lambda_data(func_info)); xm_unprotect_at(loc); return(Xen_false); } } static Xen gxg_gtk_clipboard_wait_for_contents(Xen clipboard, Xen target) { #define H_gtk_clipboard_wait_for_contents "GtkSelectionData* gtk_clipboard_wait_for_contents(GtkClipboard* clipboard, \ GdkAtom target)" Xen_check_type(Xen_is_GtkClipboard_(clipboard), clipboard, 1, "gtk_clipboard_wait_for_contents", "GtkClipboard*"); Xen_check_type(Xen_is_GdkAtom(target), target, 2, "gtk_clipboard_wait_for_contents", "GdkAtom"); return(C_to_Xen_GtkSelectionData_(gtk_clipboard_wait_for_contents(Xen_to_C_GtkClipboard_(clipboard), Xen_to_C_GdkAtom(target)))); } static Xen gxg_gtk_clipboard_wait_for_text(Xen clipboard) { #define H_gtk_clipboard_wait_for_text "gchar* gtk_clipboard_wait_for_text(GtkClipboard* clipboard)" Xen_check_type(Xen_is_GtkClipboard_(clipboard), clipboard, 1, "gtk_clipboard_wait_for_text", "GtkClipboard*"); { gchar* result; Xen rtn; result = gtk_clipboard_wait_for_text(Xen_to_C_GtkClipboard_(clipboard)); rtn = C_to_Xen_gchar_(result); g_free(result); return(rtn); } } static Xen gxg_gtk_clipboard_wait_is_text_available(Xen clipboard) { #define H_gtk_clipboard_wait_is_text_available "gboolean gtk_clipboard_wait_is_text_available(GtkClipboard* clipboard)" Xen_check_type(Xen_is_GtkClipboard_(clipboard), clipboard, 1, "gtk_clipboard_wait_is_text_available", "GtkClipboard*"); return(C_to_Xen_gboolean(gtk_clipboard_wait_is_text_available(Xen_to_C_GtkClipboard_(clipboard)))); } static Xen gxg_gtk_container_set_border_width(Xen container, Xen border_width) { #define H_gtk_container_set_border_width "void gtk_container_set_border_width(GtkContainer* container, \ guint border_width)" Xen_check_type(Xen_is_GtkContainer_(container), container, 1, "gtk_container_set_border_width", "GtkContainer*"); Xen_check_type(Xen_is_guint(border_width), border_width, 2, "gtk_container_set_border_width", "guint"); gtk_container_set_border_width(Xen_to_C_GtkContainer_(container), Xen_to_C_guint(border_width)); return(Xen_false); } static Xen gxg_gtk_container_get_border_width(Xen container) { #define H_gtk_container_get_border_width "guint gtk_container_get_border_width(GtkContainer* container)" Xen_check_type(Xen_is_GtkContainer_(container), container, 1, "gtk_container_get_border_width", "GtkContainer*"); return(C_to_Xen_guint(gtk_container_get_border_width(Xen_to_C_GtkContainer_(container)))); } static Xen gxg_gtk_container_add(Xen container, Xen widget) { #define H_gtk_container_add "void gtk_container_add(GtkContainer* container, GtkWidget* widget)" Xen_check_type(Xen_is_GtkContainer_(container), container, 1, "gtk_container_add", "GtkContainer*"); Xen_check_type(Xen_is_GtkWidget_(widget), widget, 2, "gtk_container_add", "GtkWidget*"); gtk_container_add(Xen_to_C_GtkContainer_(container), Xen_to_C_GtkWidget_(widget)); return(Xen_false); } static Xen gxg_gtk_container_remove(Xen container, Xen widget) { #define H_gtk_container_remove "void gtk_container_remove(GtkContainer* container, GtkWidget* widget)" Xen_check_type(Xen_is_GtkContainer_(container), container, 1, "gtk_container_remove", "GtkContainer*"); Xen_check_type(Xen_is_GtkWidget_(widget), widget, 2, "gtk_container_remove", "GtkWidget*"); gtk_container_remove(Xen_to_C_GtkContainer_(container), Xen_to_C_GtkWidget_(widget)); return(Xen_false); } static Xen gxg_gtk_container_check_resize(Xen container) { #define H_gtk_container_check_resize "void gtk_container_check_resize(GtkContainer* container)" Xen_check_type(Xen_is_GtkContainer_(container), container, 1, "gtk_container_check_resize", "GtkContainer*"); gtk_container_check_resize(Xen_to_C_GtkContainer_(container)); return(Xen_false); } static Xen gxg_gtk_container_foreach(Xen container, Xen func, Xen func_info) { #define H_gtk_container_foreach "void gtk_container_foreach(GtkContainer* container, GtkCallback func, \ lambda_data func_info)" Xen_check_type(Xen_is_GtkContainer_(container), container, 1, "gtk_container_foreach", "GtkContainer*"); Xen_check_type(Xen_is_GtkCallback(func), func, 2, "gtk_container_foreach", "GtkCallback"); if (!Xen_is_bound(func_info)) func_info = Xen_false; else Xen_check_type(Xen_is_lambda_data(func_info), func_info, 3, "gtk_container_foreach", "lambda_data"); { int loc; Xen gxg_ptr = Xen_list_5(func, func_info, Xen_false, Xen_false, Xen_false); loc = xm_protect(gxg_ptr); Xen_list_set(gxg_ptr, 2, C_int_to_Xen_integer(loc)); gtk_container_foreach(Xen_to_C_GtkContainer_(container), Xen_to_C_GtkCallback(func), Xen_to_C_lambda_data(func_info)); xm_unprotect_at(loc); return(Xen_false); } } static Xen gxg_gtk_container_get_children(Xen container) { #define H_gtk_container_get_children "GList* gtk_container_get_children(GtkContainer* container)" Xen_check_type(Xen_is_GtkContainer_(container), container, 1, "gtk_container_get_children", "GtkContainer*"); return(C_to_Xen_GList_(gtk_container_get_children(Xen_to_C_GtkContainer_(container)))); } static Xen gxg_gtk_dialog_new(void) { #define H_gtk_dialog_new "GtkWidget* gtk_dialog_new( void)" return(C_to_Xen_GtkWidget_(gtk_dialog_new())); } static Xen gxg_gtk_dialog_add_action_widget(Xen dialog, Xen child, Xen response_id) { #define H_gtk_dialog_add_action_widget "void gtk_dialog_add_action_widget(GtkDialog* dialog, GtkWidget* child, \ gint response_id)" Xen_check_type(Xen_is_GtkDialog_(dialog), dialog, 1, "gtk_dialog_add_action_widget", "GtkDialog*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_dialog_add_action_widget", "GtkWidget*"); Xen_check_type(Xen_is_gint(response_id), response_id, 3, "gtk_dialog_add_action_widget", "gint"); gtk_dialog_add_action_widget(Xen_to_C_GtkDialog_(dialog), Xen_to_C_GtkWidget_(child), Xen_to_C_gint(response_id)); return(Xen_false); } static Xen gxg_gtk_dialog_add_button(Xen dialog, Xen button_text, Xen response_id) { #define H_gtk_dialog_add_button "GtkWidget* gtk_dialog_add_button(GtkDialog* dialog, gchar* button_text, \ gint response_id)" Xen_check_type(Xen_is_GtkDialog_(dialog), dialog, 1, "gtk_dialog_add_button", "GtkDialog*"); Xen_check_type(Xen_is_gchar_(button_text), button_text, 2, "gtk_dialog_add_button", "gchar*"); Xen_check_type(Xen_is_gint(response_id), response_id, 3, "gtk_dialog_add_button", "gint"); return(C_to_Xen_GtkWidget_(gtk_dialog_add_button(Xen_to_C_GtkDialog_(dialog), Xen_to_C_gchar_(button_text), Xen_to_C_gint(response_id)))); } static Xen gxg_gtk_dialog_add_buttons(Xen dialog, Xen buttons) { #define H_gtk_dialog_add_buttons "void gtk_dialog_add_buttons(GtkDialog* dialog, etc buttons)" Xen_check_type(Xen_is_GtkDialog_(dialog), dialog, 1, "gtk_dialog_add_buttons", "GtkDialog*"); Xen_check_type(Xen_is_etc(buttons), buttons, 2, "gtk_dialog_add_buttons", "etc"); { int etc_len = 0; GtkDialog* p_arg0; if (Xen_is_list(buttons)) etc_len = Xen_list_length(buttons); if (etc_len < 2) Xen_out_of_range_error("gtk_dialog_add_buttons", 1, buttons, "... list must have at least 2 entries"); if (etc_len > 10) Xen_out_of_range_error("gtk_dialog_add_buttons", 1, buttons, "... list too long (max len: 10)"); if ((etc_len % 2) != 0) Xen_out_of_range_error("gtk_dialog_add_buttons", 1, buttons, "... list len must be multiple of 2"); p_arg0 = Xen_to_C_GtkDialog_(dialog); switch (etc_len) { case 2: gtk_dialog_add_buttons(p_arg0, XLS(buttons, 0), XLI(buttons, 1), NULL); break; case 4: gtk_dialog_add_buttons(p_arg0, XLS(buttons, 0), XLI(buttons, 1), XLS(buttons, 2), XLI(buttons, 3), NULL); break; case 6: gtk_dialog_add_buttons(p_arg0, XLS(buttons, 0), XLI(buttons, 1), XLS(buttons, 2), XLI(buttons, 3), XLS(buttons, 4), XLI(buttons, 5), NULL); break; case 8: gtk_dialog_add_buttons(p_arg0, XLS(buttons, 0), XLI(buttons, 1), XLS(buttons, 2), XLI(buttons, 3), XLS(buttons, 4), XLI(buttons, 5), XLS(buttons, 6), XLI(buttons, 7), NULL); break; case 10: gtk_dialog_add_buttons(p_arg0, XLS(buttons, 0), XLI(buttons, 1), XLS(buttons, 2), XLI(buttons, 3), XLS(buttons, 4), XLI(buttons, 5), XLS(buttons, 6), XLI(buttons, 7), XLS(buttons, 8), XLI(buttons, 9), NULL); break; } return(Xen_false); } } static Xen gxg_gtk_dialog_set_response_sensitive(Xen dialog, Xen response_id, Xen setting) { #define H_gtk_dialog_set_response_sensitive "void gtk_dialog_set_response_sensitive(GtkDialog* dialog, \ gint response_id, gboolean setting)" Xen_check_type(Xen_is_GtkDialog_(dialog), dialog, 1, "gtk_dialog_set_response_sensitive", "GtkDialog*"); Xen_check_type(Xen_is_gint(response_id), response_id, 2, "gtk_dialog_set_response_sensitive", "gint"); Xen_check_type(Xen_is_gboolean(setting), setting, 3, "gtk_dialog_set_response_sensitive", "gboolean"); gtk_dialog_set_response_sensitive(Xen_to_C_GtkDialog_(dialog), Xen_to_C_gint(response_id), Xen_to_C_gboolean(setting)); return(Xen_false); } static Xen gxg_gtk_dialog_set_default_response(Xen dialog, Xen response_id) { #define H_gtk_dialog_set_default_response "void gtk_dialog_set_default_response(GtkDialog* dialog, \ gint response_id)" Xen_check_type(Xen_is_GtkDialog_(dialog), dialog, 1, "gtk_dialog_set_default_response", "GtkDialog*"); Xen_check_type(Xen_is_gint(response_id), response_id, 2, "gtk_dialog_set_default_response", "gint"); gtk_dialog_set_default_response(Xen_to_C_GtkDialog_(dialog), Xen_to_C_gint(response_id)); return(Xen_false); } static Xen gxg_gtk_dialog_response(Xen dialog, Xen response_id) { #define H_gtk_dialog_response "void gtk_dialog_response(GtkDialog* dialog, gint response_id)" Xen_check_type(Xen_is_GtkDialog_(dialog), dialog, 1, "gtk_dialog_response", "GtkDialog*"); Xen_check_type(Xen_is_gint(response_id), response_id, 2, "gtk_dialog_response", "gint"); gtk_dialog_response(Xen_to_C_GtkDialog_(dialog), Xen_to_C_gint(response_id)); return(Xen_false); } static Xen gxg_gtk_dialog_run(Xen dialog) { #define H_gtk_dialog_run "gint gtk_dialog_run(GtkDialog* dialog)" Xen_check_type(Xen_is_GtkDialog_(dialog), dialog, 1, "gtk_dialog_run", "GtkDialog*"); return(C_to_Xen_gint(gtk_dialog_run(Xen_to_C_GtkDialog_(dialog)))); } static Xen gxg_gtk_drag_get_data(Xen widget, Xen context, Xen target, Xen time) { #define H_gtk_drag_get_data "void gtk_drag_get_data(GtkWidget* widget, GdkDragContext* context, GdkAtom target, \ guint32 time)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_drag_get_data", "GtkWidget*"); Xen_check_type(Xen_is_GdkDragContext_(context), context, 2, "gtk_drag_get_data", "GdkDragContext*"); Xen_check_type(Xen_is_GdkAtom(target), target, 3, "gtk_drag_get_data", "GdkAtom"); Xen_check_type(Xen_is_guint32(time), time, 4, "gtk_drag_get_data", "guint32"); gtk_drag_get_data(Xen_to_C_GtkWidget_(widget), Xen_to_C_GdkDragContext_(context), Xen_to_C_GdkAtom(target), Xen_to_C_guint32(time)); return(Xen_false); } static Xen gxg_gtk_drag_finish(Xen context, Xen success, Xen del, Xen time) { #define H_gtk_drag_finish "void gtk_drag_finish(GdkDragContext* context, gboolean success, gboolean del, \ guint32 time)" Xen_check_type(Xen_is_GdkDragContext_(context), context, 1, "gtk_drag_finish", "GdkDragContext*"); Xen_check_type(Xen_is_gboolean(success), success, 2, "gtk_drag_finish", "gboolean"); Xen_check_type(Xen_is_gboolean(del), del, 3, "gtk_drag_finish", "gboolean"); Xen_check_type(Xen_is_guint32(time), time, 4, "gtk_drag_finish", "guint32"); gtk_drag_finish(Xen_to_C_GdkDragContext_(context), Xen_to_C_gboolean(success), Xen_to_C_gboolean(del), Xen_to_C_guint32(time)); return(Xen_false); } static Xen gxg_gtk_drag_get_source_widget(Xen context) { #define H_gtk_drag_get_source_widget "GtkWidget* gtk_drag_get_source_widget(GdkDragContext* context)" Xen_check_type(Xen_is_GdkDragContext_(context), context, 1, "gtk_drag_get_source_widget", "GdkDragContext*"); return(C_to_Xen_GtkWidget_(gtk_drag_get_source_widget(Xen_to_C_GdkDragContext_(context)))); } static Xen gxg_gtk_drag_highlight(Xen widget) { #define H_gtk_drag_highlight "void gtk_drag_highlight(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_drag_highlight", "GtkWidget*"); gtk_drag_highlight(Xen_to_C_GtkWidget_(widget)); return(Xen_false); } static Xen gxg_gtk_drag_unhighlight(Xen widget) { #define H_gtk_drag_unhighlight "void gtk_drag_unhighlight(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_drag_unhighlight", "GtkWidget*"); gtk_drag_unhighlight(Xen_to_C_GtkWidget_(widget)); return(Xen_false); } static Xen gxg_gtk_drag_dest_set(Xen widget, Xen flags, Xen targets, Xen n_targets, Xen actions) { #define H_gtk_drag_dest_set "void gtk_drag_dest_set(GtkWidget* widget, GtkDestDefaults flags, GtkTargetEntry* targets, \ gint n_targets, GdkDragAction actions)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_drag_dest_set", "GtkWidget*"); Xen_check_type(Xen_is_GtkDestDefaults(flags), flags, 2, "gtk_drag_dest_set", "GtkDestDefaults"); Xen_check_type(Xen_is_GtkTargetEntry_(targets), targets, 3, "gtk_drag_dest_set", "GtkTargetEntry*"); Xen_check_type(Xen_is_gint(n_targets), n_targets, 4, "gtk_drag_dest_set", "gint"); Xen_check_type(Xen_is_GdkDragAction(actions), actions, 5, "gtk_drag_dest_set", "GdkDragAction"); gtk_drag_dest_set(Xen_to_C_GtkWidget_(widget), Xen_to_C_GtkDestDefaults(flags), Xen_to_C_GtkTargetEntry_(targets), Xen_to_C_gint(n_targets), Xen_to_C_GdkDragAction(actions)); return(Xen_false); } static Xen gxg_gtk_drag_dest_unset(Xen widget) { #define H_gtk_drag_dest_unset "void gtk_drag_dest_unset(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_drag_dest_unset", "GtkWidget*"); gtk_drag_dest_unset(Xen_to_C_GtkWidget_(widget)); return(Xen_false); } static Xen gxg_gtk_drag_dest_find_target(Xen widget, Xen context, Xen target_list) { #define H_gtk_drag_dest_find_target "GdkAtom gtk_drag_dest_find_target(GtkWidget* widget, GdkDragContext* context, \ GtkTargetList* target_list)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_drag_dest_find_target", "GtkWidget*"); Xen_check_type(Xen_is_GdkDragContext_(context), context, 2, "gtk_drag_dest_find_target", "GdkDragContext*"); Xen_check_type(Xen_is_GtkTargetList_(target_list) || Xen_is_false(target_list), target_list, 3, "gtk_drag_dest_find_target", "GtkTargetList*"); return(C_to_Xen_GdkAtom(gtk_drag_dest_find_target(Xen_to_C_GtkWidget_(widget), Xen_to_C_GdkDragContext_(context), Xen_to_C_GtkTargetList_(target_list)))); } static Xen gxg_gtk_drag_dest_get_target_list(Xen widget) { #define H_gtk_drag_dest_get_target_list "GtkTargetList* gtk_drag_dest_get_target_list(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_drag_dest_get_target_list", "GtkWidget*"); return(C_to_Xen_GtkTargetList_(gtk_drag_dest_get_target_list(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_drag_dest_set_target_list(Xen widget, Xen target_list) { #define H_gtk_drag_dest_set_target_list "void gtk_drag_dest_set_target_list(GtkWidget* widget, GtkTargetList* target_list)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_drag_dest_set_target_list", "GtkWidget*"); Xen_check_type(Xen_is_GtkTargetList_(target_list) || Xen_is_false(target_list), target_list, 2, "gtk_drag_dest_set_target_list", "GtkTargetList*"); gtk_drag_dest_set_target_list(Xen_to_C_GtkWidget_(widget), Xen_to_C_GtkTargetList_(target_list)); return(Xen_false); } static Xen gxg_gtk_drag_source_set(Xen widget, Xen start_button_mask, Xen targets, Xen n_targets, Xen actions) { #define H_gtk_drag_source_set "void gtk_drag_source_set(GtkWidget* widget, GdkModifierType start_button_mask, \ GtkTargetEntry* targets, gint n_targets, GdkDragAction actions)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_drag_source_set", "GtkWidget*"); Xen_check_type(Xen_is_GdkModifierType(start_button_mask), start_button_mask, 2, "gtk_drag_source_set", "GdkModifierType"); Xen_check_type(Xen_is_GtkTargetEntry_(targets), targets, 3, "gtk_drag_source_set", "GtkTargetEntry*"); Xen_check_type(Xen_is_gint(n_targets), n_targets, 4, "gtk_drag_source_set", "gint"); Xen_check_type(Xen_is_GdkDragAction(actions), actions, 5, "gtk_drag_source_set", "GdkDragAction"); gtk_drag_source_set(Xen_to_C_GtkWidget_(widget), Xen_to_C_GdkModifierType(start_button_mask), Xen_to_C_GtkTargetEntry_(targets), Xen_to_C_gint(n_targets), Xen_to_C_GdkDragAction(actions)); return(Xen_false); } static Xen gxg_gtk_drag_source_unset(Xen widget) { #define H_gtk_drag_source_unset "void gtk_drag_source_unset(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_drag_source_unset", "GtkWidget*"); gtk_drag_source_unset(Xen_to_C_GtkWidget_(widget)); return(Xen_false); } static Xen gxg_gtk_drag_source_set_icon_pixbuf(Xen widget, Xen pixbuf) { #define H_gtk_drag_source_set_icon_pixbuf "void gtk_drag_source_set_icon_pixbuf(GtkWidget* widget, \ GdkPixbuf* pixbuf)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_drag_source_set_icon_pixbuf", "GtkWidget*"); Xen_check_type(Xen_is_GdkPixbuf_(pixbuf), pixbuf, 2, "gtk_drag_source_set_icon_pixbuf", "GdkPixbuf*"); gtk_drag_source_set_icon_pixbuf(Xen_to_C_GtkWidget_(widget), Xen_to_C_GdkPixbuf_(pixbuf)); return(Xen_false); } static Xen gxg_gtk_drag_set_icon_widget(Xen context, Xen widget, Xen hot_x, Xen hot_y) { #define H_gtk_drag_set_icon_widget "void gtk_drag_set_icon_widget(GdkDragContext* context, GtkWidget* widget, \ gint hot_x, gint hot_y)" Xen_check_type(Xen_is_GdkDragContext_(context), context, 1, "gtk_drag_set_icon_widget", "GdkDragContext*"); Xen_check_type(Xen_is_GtkWidget_(widget), widget, 2, "gtk_drag_set_icon_widget", "GtkWidget*"); Xen_check_type(Xen_is_gint(hot_x), hot_x, 3, "gtk_drag_set_icon_widget", "gint"); Xen_check_type(Xen_is_gint(hot_y), hot_y, 4, "gtk_drag_set_icon_widget", "gint"); gtk_drag_set_icon_widget(Xen_to_C_GdkDragContext_(context), Xen_to_C_GtkWidget_(widget), Xen_to_C_gint(hot_x), Xen_to_C_gint(hot_y)); return(Xen_false); } static Xen gxg_gtk_drag_set_icon_pixbuf(Xen context, Xen pixbuf, Xen hot_x, Xen hot_y) { #define H_gtk_drag_set_icon_pixbuf "void gtk_drag_set_icon_pixbuf(GdkDragContext* context, GdkPixbuf* pixbuf, \ gint hot_x, gint hot_y)" Xen_check_type(Xen_is_GdkDragContext_(context), context, 1, "gtk_drag_set_icon_pixbuf", "GdkDragContext*"); Xen_check_type(Xen_is_GdkPixbuf_(pixbuf), pixbuf, 2, "gtk_drag_set_icon_pixbuf", "GdkPixbuf*"); Xen_check_type(Xen_is_gint(hot_x), hot_x, 3, "gtk_drag_set_icon_pixbuf", "gint"); Xen_check_type(Xen_is_gint(hot_y), hot_y, 4, "gtk_drag_set_icon_pixbuf", "gint"); gtk_drag_set_icon_pixbuf(Xen_to_C_GdkDragContext_(context), Xen_to_C_GdkPixbuf_(pixbuf), Xen_to_C_gint(hot_x), Xen_to_C_gint(hot_y)); return(Xen_false); } static Xen gxg_gtk_drag_set_icon_default(Xen context) { #define H_gtk_drag_set_icon_default "void gtk_drag_set_icon_default(GdkDragContext* context)" Xen_check_type(Xen_is_GdkDragContext_(context), context, 1, "gtk_drag_set_icon_default", "GdkDragContext*"); gtk_drag_set_icon_default(Xen_to_C_GdkDragContext_(context)); return(Xen_false); } static Xen gxg_gtk_drag_check_threshold(Xen widget, Xen start_x, Xen start_y, Xen current_x, Xen current_y) { #define H_gtk_drag_check_threshold "gboolean gtk_drag_check_threshold(GtkWidget* widget, gint start_x, \ gint start_y, gint current_x, gint current_y)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_drag_check_threshold", "GtkWidget*"); Xen_check_type(Xen_is_gint(start_x), start_x, 2, "gtk_drag_check_threshold", "gint"); Xen_check_type(Xen_is_gint(start_y), start_y, 3, "gtk_drag_check_threshold", "gint"); Xen_check_type(Xen_is_gint(current_x), current_x, 4, "gtk_drag_check_threshold", "gint"); Xen_check_type(Xen_is_gint(current_y), current_y, 5, "gtk_drag_check_threshold", "gint"); return(C_to_Xen_gboolean(gtk_drag_check_threshold(Xen_to_C_GtkWidget_(widget), Xen_to_C_gint(start_x), Xen_to_C_gint(start_y), Xen_to_C_gint(current_x), Xen_to_C_gint(current_y)))); } static Xen gxg_gtk_drawing_area_new(void) { #define H_gtk_drawing_area_new "GtkWidget* gtk_drawing_area_new( void)" return(C_to_Xen_GtkWidget_(gtk_drawing_area_new())); } static Xen gxg_gtk_editable_select_region(Xen editable, Xen start, Xen end) { #define H_gtk_editable_select_region "void gtk_editable_select_region(GtkEditable* editable, gint start, \ gint end)" Xen_check_type(Xen_is_GtkEditable_(editable), editable, 1, "gtk_editable_select_region", "GtkEditable*"); Xen_check_type(Xen_is_gint(start), start, 2, "gtk_editable_select_region", "gint"); Xen_check_type(Xen_is_gint(end), end, 3, "gtk_editable_select_region", "gint"); gtk_editable_select_region(Xen_to_C_GtkEditable_(editable), Xen_to_C_gint(start), Xen_to_C_gint(end)); return(Xen_false); } static Xen gxg_gtk_editable_get_selection_bounds(Xen editable, Xen ignore_start, Xen ignore_end) { #define H_gtk_editable_get_selection_bounds "gboolean gtk_editable_get_selection_bounds(GtkEditable* editable, \ gint* [start], gint* [end])" gint ref_start; gint ref_end; Xen_check_type(Xen_is_GtkEditable_(editable), editable, 1, "gtk_editable_get_selection_bounds", "GtkEditable*"); { Xen result; result = C_to_Xen_gboolean(gtk_editable_get_selection_bounds(Xen_to_C_GtkEditable_(editable), &ref_start, &ref_end)); return(Xen_list_3(result, C_to_Xen_gint(ref_start), C_to_Xen_gint(ref_end))); } } static Xen gxg_gtk_editable_insert_text(Xen editable, Xen new_text, Xen new_text_length, Xen ignore_position) { #define H_gtk_editable_insert_text "void gtk_editable_insert_text(GtkEditable* editable, gchar* new_text, \ gint new_text_length, gint* [position])" gint ref_position; Xen_check_type(Xen_is_GtkEditable_(editable), editable, 1, "gtk_editable_insert_text", "GtkEditable*"); Xen_check_type(Xen_is_gchar_(new_text), new_text, 2, "gtk_editable_insert_text", "gchar*"); Xen_check_type(Xen_is_gint(new_text_length), new_text_length, 3, "gtk_editable_insert_text", "gint"); gtk_editable_insert_text(Xen_to_C_GtkEditable_(editable), Xen_to_C_gchar_(new_text), Xen_to_C_gint(new_text_length), &ref_position); return(Xen_list_1(C_to_Xen_gint(ref_position))); } static Xen gxg_gtk_editable_delete_text(Xen editable, Xen start_pos, Xen end_pos) { #define H_gtk_editable_delete_text "void gtk_editable_delete_text(GtkEditable* editable, gint start_pos, \ gint end_pos)" Xen_check_type(Xen_is_GtkEditable_(editable), editable, 1, "gtk_editable_delete_text", "GtkEditable*"); Xen_check_type(Xen_is_gint(start_pos), start_pos, 2, "gtk_editable_delete_text", "gint"); Xen_check_type(Xen_is_gint(end_pos), end_pos, 3, "gtk_editable_delete_text", "gint"); gtk_editable_delete_text(Xen_to_C_GtkEditable_(editable), Xen_to_C_gint(start_pos), Xen_to_C_gint(end_pos)); return(Xen_false); } static Xen gxg_gtk_editable_get_chars(Xen editable, Xen start_pos, Xen end_pos) { #define H_gtk_editable_get_chars "gchar* gtk_editable_get_chars(GtkEditable* editable, gint start_pos, \ gint end_pos)" Xen_check_type(Xen_is_GtkEditable_(editable), editable, 1, "gtk_editable_get_chars", "GtkEditable*"); Xen_check_type(Xen_is_gint(start_pos), start_pos, 2, "gtk_editable_get_chars", "gint"); Xen_check_type(Xen_is_gint(end_pos), end_pos, 3, "gtk_editable_get_chars", "gint"); { gchar* result; Xen rtn; result = gtk_editable_get_chars(Xen_to_C_GtkEditable_(editable), Xen_to_C_gint(start_pos), Xen_to_C_gint(end_pos)); rtn = C_to_Xen_gchar_(result); g_free(result); return(rtn); } } static Xen gxg_gtk_editable_cut_clipboard(Xen editable) { #define H_gtk_editable_cut_clipboard "void gtk_editable_cut_clipboard(GtkEditable* editable)" Xen_check_type(Xen_is_GtkEditable_(editable), editable, 1, "gtk_editable_cut_clipboard", "GtkEditable*"); gtk_editable_cut_clipboard(Xen_to_C_GtkEditable_(editable)); return(Xen_false); } static Xen gxg_gtk_editable_copy_clipboard(Xen editable) { #define H_gtk_editable_copy_clipboard "void gtk_editable_copy_clipboard(GtkEditable* editable)" Xen_check_type(Xen_is_GtkEditable_(editable), editable, 1, "gtk_editable_copy_clipboard", "GtkEditable*"); gtk_editable_copy_clipboard(Xen_to_C_GtkEditable_(editable)); return(Xen_false); } static Xen gxg_gtk_editable_paste_clipboard(Xen editable) { #define H_gtk_editable_paste_clipboard "void gtk_editable_paste_clipboard(GtkEditable* editable)" Xen_check_type(Xen_is_GtkEditable_(editable), editable, 1, "gtk_editable_paste_clipboard", "GtkEditable*"); gtk_editable_paste_clipboard(Xen_to_C_GtkEditable_(editable)); return(Xen_false); } static Xen gxg_gtk_editable_delete_selection(Xen editable) { #define H_gtk_editable_delete_selection "void gtk_editable_delete_selection(GtkEditable* editable)" Xen_check_type(Xen_is_GtkEditable_(editable), editable, 1, "gtk_editable_delete_selection", "GtkEditable*"); gtk_editable_delete_selection(Xen_to_C_GtkEditable_(editable)); return(Xen_false); } static Xen gxg_gtk_editable_set_position(Xen editable, Xen position) { #define H_gtk_editable_set_position "void gtk_editable_set_position(GtkEditable* editable, gint position)" Xen_check_type(Xen_is_GtkEditable_(editable), editable, 1, "gtk_editable_set_position", "GtkEditable*"); Xen_check_type(Xen_is_gint(position), position, 2, "gtk_editable_set_position", "gint"); gtk_editable_set_position(Xen_to_C_GtkEditable_(editable), Xen_to_C_gint(position)); return(Xen_false); } static Xen gxg_gtk_editable_get_position(Xen editable) { #define H_gtk_editable_get_position "gint gtk_editable_get_position(GtkEditable* editable)" Xen_check_type(Xen_is_GtkEditable_(editable), editable, 1, "gtk_editable_get_position", "GtkEditable*"); return(C_to_Xen_gint(gtk_editable_get_position(Xen_to_C_GtkEditable_(editable)))); } static Xen gxg_gtk_editable_set_editable(Xen editable, Xen is_editable) { #define H_gtk_editable_set_editable "void gtk_editable_set_editable(GtkEditable* editable, gboolean is_editable)" Xen_check_type(Xen_is_GtkEditable_(editable), editable, 1, "gtk_editable_set_editable", "GtkEditable*"); Xen_check_type(Xen_is_gboolean(is_editable), is_editable, 2, "gtk_editable_set_editable", "gboolean"); gtk_editable_set_editable(Xen_to_C_GtkEditable_(editable), Xen_to_C_gboolean(is_editable)); return(Xen_false); } static Xen gxg_gtk_editable_get_editable(Xen editable) { #define H_gtk_editable_get_editable "gboolean gtk_editable_get_editable(GtkEditable* editable)" Xen_check_type(Xen_is_GtkEditable_(editable), editable, 1, "gtk_editable_get_editable", "GtkEditable*"); return(C_to_Xen_gboolean(gtk_editable_get_editable(Xen_to_C_GtkEditable_(editable)))); } static Xen gxg_gtk_entry_new(void) { #define H_gtk_entry_new "GtkWidget* gtk_entry_new( void)" return(C_to_Xen_GtkWidget_(gtk_entry_new())); } static Xen gxg_gtk_entry_set_visibility(Xen entry, Xen visible) { #define H_gtk_entry_set_visibility "void gtk_entry_set_visibility(GtkEntry* entry, gboolean visible)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_set_visibility", "GtkEntry*"); Xen_check_type(Xen_is_gboolean(visible), visible, 2, "gtk_entry_set_visibility", "gboolean"); gtk_entry_set_visibility(Xen_to_C_GtkEntry_(entry), Xen_to_C_gboolean(visible)); return(Xen_false); } static Xen gxg_gtk_entry_get_visibility(Xen entry) { #define H_gtk_entry_get_visibility "gboolean gtk_entry_get_visibility(GtkEntry* entry)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_get_visibility", "GtkEntry*"); return(C_to_Xen_gboolean(gtk_entry_get_visibility(Xen_to_C_GtkEntry_(entry)))); } static Xen gxg_gtk_entry_set_invisible_char(Xen entry, Xen ch) { #define H_gtk_entry_set_invisible_char "void gtk_entry_set_invisible_char(GtkEntry* entry, gunichar ch)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_set_invisible_char", "GtkEntry*"); Xen_check_type(Xen_is_gunichar(ch), ch, 2, "gtk_entry_set_invisible_char", "gunichar"); gtk_entry_set_invisible_char(Xen_to_C_GtkEntry_(entry), Xen_to_C_gunichar(ch)); return(Xen_false); } static Xen gxg_gtk_entry_get_invisible_char(Xen entry) { #define H_gtk_entry_get_invisible_char "gunichar gtk_entry_get_invisible_char(GtkEntry* entry)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_get_invisible_char", "GtkEntry*"); return(C_to_Xen_gunichar(gtk_entry_get_invisible_char(Xen_to_C_GtkEntry_(entry)))); } static Xen gxg_gtk_entry_set_has_frame(Xen entry, Xen setting) { #define H_gtk_entry_set_has_frame "void gtk_entry_set_has_frame(GtkEntry* entry, gboolean setting)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_set_has_frame", "GtkEntry*"); Xen_check_type(Xen_is_gboolean(setting), setting, 2, "gtk_entry_set_has_frame", "gboolean"); gtk_entry_set_has_frame(Xen_to_C_GtkEntry_(entry), Xen_to_C_gboolean(setting)); return(Xen_false); } static Xen gxg_gtk_entry_get_has_frame(Xen entry) { #define H_gtk_entry_get_has_frame "gboolean gtk_entry_get_has_frame(GtkEntry* entry)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_get_has_frame", "GtkEntry*"); return(C_to_Xen_gboolean(gtk_entry_get_has_frame(Xen_to_C_GtkEntry_(entry)))); } static Xen gxg_gtk_entry_set_max_length(Xen entry, Xen max) { #define H_gtk_entry_set_max_length "void gtk_entry_set_max_length(GtkEntry* entry, gint max)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_set_max_length", "GtkEntry*"); Xen_check_type(Xen_is_gint(max), max, 2, "gtk_entry_set_max_length", "gint"); gtk_entry_set_max_length(Xen_to_C_GtkEntry_(entry), Xen_to_C_gint(max)); return(Xen_false); } static Xen gxg_gtk_entry_get_max_length(Xen entry) { #define H_gtk_entry_get_max_length "gint gtk_entry_get_max_length(GtkEntry* entry)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_get_max_length", "GtkEntry*"); return(C_to_Xen_gint(gtk_entry_get_max_length(Xen_to_C_GtkEntry_(entry)))); } static Xen gxg_gtk_entry_set_activates_default(Xen entry, Xen setting) { #define H_gtk_entry_set_activates_default "void gtk_entry_set_activates_default(GtkEntry* entry, gboolean setting)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_set_activates_default", "GtkEntry*"); Xen_check_type(Xen_is_gboolean(setting), setting, 2, "gtk_entry_set_activates_default", "gboolean"); gtk_entry_set_activates_default(Xen_to_C_GtkEntry_(entry), Xen_to_C_gboolean(setting)); return(Xen_false); } static Xen gxg_gtk_entry_get_activates_default(Xen entry) { #define H_gtk_entry_get_activates_default "gboolean gtk_entry_get_activates_default(GtkEntry* entry)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_get_activates_default", "GtkEntry*"); return(C_to_Xen_gboolean(gtk_entry_get_activates_default(Xen_to_C_GtkEntry_(entry)))); } static Xen gxg_gtk_entry_set_width_chars(Xen entry, Xen n_chars) { #define H_gtk_entry_set_width_chars "void gtk_entry_set_width_chars(GtkEntry* entry, gint n_chars)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_set_width_chars", "GtkEntry*"); Xen_check_type(Xen_is_gint(n_chars), n_chars, 2, "gtk_entry_set_width_chars", "gint"); gtk_entry_set_width_chars(Xen_to_C_GtkEntry_(entry), Xen_to_C_gint(n_chars)); return(Xen_false); } static Xen gxg_gtk_entry_get_width_chars(Xen entry) { #define H_gtk_entry_get_width_chars "gint gtk_entry_get_width_chars(GtkEntry* entry)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_get_width_chars", "GtkEntry*"); return(C_to_Xen_gint(gtk_entry_get_width_chars(Xen_to_C_GtkEntry_(entry)))); } static Xen gxg_gtk_entry_set_text(Xen entry, Xen text) { #define H_gtk_entry_set_text "void gtk_entry_set_text(GtkEntry* entry, gchar* text)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_set_text", "GtkEntry*"); Xen_check_type(Xen_is_gchar_(text), text, 2, "gtk_entry_set_text", "gchar*"); gtk_entry_set_text(Xen_to_C_GtkEntry_(entry), Xen_to_C_gchar_(text)); return(Xen_false); } static Xen gxg_gtk_entry_get_text(Xen entry) { #define H_gtk_entry_get_text "gchar* gtk_entry_get_text(GtkEntry* entry)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_get_text", "GtkEntry*"); return(C_to_Xen_gchar_(gtk_entry_get_text(Xen_to_C_GtkEntry_(entry)))); } static Xen gxg_gtk_entry_get_layout(Xen entry) { #define H_gtk_entry_get_layout "PangoLayout* gtk_entry_get_layout(GtkEntry* entry)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_get_layout", "GtkEntry*"); return(C_to_Xen_PangoLayout_(gtk_entry_get_layout(Xen_to_C_GtkEntry_(entry)))); } static Xen gxg_gtk_entry_get_layout_offsets(Xen entry, Xen ignore_x, Xen ignore_y) { #define H_gtk_entry_get_layout_offsets "void gtk_entry_get_layout_offsets(GtkEntry* entry, gint* [x], \ gint* [y])" gint ref_x; gint ref_y; Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_get_layout_offsets", "GtkEntry*"); gtk_entry_get_layout_offsets(Xen_to_C_GtkEntry_(entry), &ref_x, &ref_y); return(Xen_list_2(C_to_Xen_gint(ref_x), C_to_Xen_gint(ref_y))); } static Xen gxg_gtk_event_box_new(void) { #define H_gtk_event_box_new "GtkWidget* gtk_event_box_new( void)" return(C_to_Xen_GtkWidget_(gtk_event_box_new())); } static Xen gxg_gtk_fixed_new(void) { #define H_gtk_fixed_new "GtkWidget* gtk_fixed_new( void)" return(C_to_Xen_GtkWidget_(gtk_fixed_new())); } static Xen gxg_gtk_fixed_put(Xen fixed, Xen widget, Xen x, Xen y) { #define H_gtk_fixed_put "void gtk_fixed_put(GtkFixed* fixed, GtkWidget* widget, gint x, gint y)" Xen_check_type(Xen_is_GtkFixed_(fixed), fixed, 1, "gtk_fixed_put", "GtkFixed*"); Xen_check_type(Xen_is_GtkWidget_(widget), widget, 2, "gtk_fixed_put", "GtkWidget*"); Xen_check_type(Xen_is_gint(x), x, 3, "gtk_fixed_put", "gint"); Xen_check_type(Xen_is_gint(y), y, 4, "gtk_fixed_put", "gint"); gtk_fixed_put(Xen_to_C_GtkFixed_(fixed), Xen_to_C_GtkWidget_(widget), Xen_to_C_gint(x), Xen_to_C_gint(y)); return(Xen_false); } static Xen gxg_gtk_fixed_move(Xen fixed, Xen widget, Xen x, Xen y) { #define H_gtk_fixed_move "void gtk_fixed_move(GtkFixed* fixed, GtkWidget* widget, gint x, gint y)" Xen_check_type(Xen_is_GtkFixed_(fixed), fixed, 1, "gtk_fixed_move", "GtkFixed*"); Xen_check_type(Xen_is_GtkWidget_(widget), widget, 2, "gtk_fixed_move", "GtkWidget*"); Xen_check_type(Xen_is_gint(x), x, 3, "gtk_fixed_move", "gint"); Xen_check_type(Xen_is_gint(y), y, 4, "gtk_fixed_move", "gint"); gtk_fixed_move(Xen_to_C_GtkFixed_(fixed), Xen_to_C_GtkWidget_(widget), Xen_to_C_gint(x), Xen_to_C_gint(y)); return(Xen_false); } static Xen gxg_gtk_frame_new(Xen label) { #define H_gtk_frame_new "GtkWidget* gtk_frame_new(gchar* label)" Xen_check_type(Xen_is_gchar_(label), label, 1, "gtk_frame_new", "gchar*"); return(C_to_Xen_GtkWidget_(gtk_frame_new(Xen_to_C_gchar_(label)))); } static Xen gxg_gtk_frame_set_label(Xen frame, Xen label) { #define H_gtk_frame_set_label "void gtk_frame_set_label(GtkFrame* frame, gchar* label)" Xen_check_type(Xen_is_GtkFrame_(frame), frame, 1, "gtk_frame_set_label", "GtkFrame*"); Xen_check_type(Xen_is_gchar_(label), label, 2, "gtk_frame_set_label", "gchar*"); gtk_frame_set_label(Xen_to_C_GtkFrame_(frame), Xen_to_C_gchar_(label)); return(Xen_false); } static Xen gxg_gtk_frame_get_label(Xen frame) { #define H_gtk_frame_get_label "gchar* gtk_frame_get_label(GtkFrame* frame)" Xen_check_type(Xen_is_GtkFrame_(frame), frame, 1, "gtk_frame_get_label", "GtkFrame*"); return(C_to_Xen_gchar_(gtk_frame_get_label(Xen_to_C_GtkFrame_(frame)))); } static Xen gxg_gtk_frame_set_label_widget(Xen frame, Xen label_widget) { #define H_gtk_frame_set_label_widget "void gtk_frame_set_label_widget(GtkFrame* frame, GtkWidget* label_widget)" Xen_check_type(Xen_is_GtkFrame_(frame), frame, 1, "gtk_frame_set_label_widget", "GtkFrame*"); Xen_check_type(Xen_is_GtkWidget_(label_widget), label_widget, 2, "gtk_frame_set_label_widget", "GtkWidget*"); gtk_frame_set_label_widget(Xen_to_C_GtkFrame_(frame), Xen_to_C_GtkWidget_(label_widget)); return(Xen_false); } static Xen gxg_gtk_frame_get_label_widget(Xen frame) { #define H_gtk_frame_get_label_widget "GtkWidget* gtk_frame_get_label_widget(GtkFrame* frame)" Xen_check_type(Xen_is_GtkFrame_(frame), frame, 1, "gtk_frame_get_label_widget", "GtkFrame*"); return(C_to_Xen_GtkWidget_(gtk_frame_get_label_widget(Xen_to_C_GtkFrame_(frame)))); } static Xen gxg_gtk_frame_set_label_align(Xen frame, Xen xalign, Xen yalign) { #define H_gtk_frame_set_label_align "void gtk_frame_set_label_align(GtkFrame* frame, gfloat xalign, \ gfloat yalign)" Xen_check_type(Xen_is_GtkFrame_(frame), frame, 1, "gtk_frame_set_label_align", "GtkFrame*"); Xen_check_type(Xen_is_gfloat(xalign), xalign, 2, "gtk_frame_set_label_align", "gfloat"); Xen_check_type(Xen_is_gfloat(yalign), yalign, 3, "gtk_frame_set_label_align", "gfloat"); gtk_frame_set_label_align(Xen_to_C_GtkFrame_(frame), Xen_to_C_gfloat(xalign), Xen_to_C_gfloat(yalign)); return(Xen_false); } static Xen gxg_gtk_frame_get_label_align(Xen frame, Xen ignore_xalign, Xen ignore_yalign) { #define H_gtk_frame_get_label_align "void gtk_frame_get_label_align(GtkFrame* frame, gfloat* [xalign], \ gfloat* [yalign])" gfloat ref_xalign; gfloat ref_yalign; Xen_check_type(Xen_is_GtkFrame_(frame), frame, 1, "gtk_frame_get_label_align", "GtkFrame*"); gtk_frame_get_label_align(Xen_to_C_GtkFrame_(frame), &ref_xalign, &ref_yalign); return(Xen_list_2(C_to_Xen_gfloat(ref_xalign), C_to_Xen_gfloat(ref_yalign))); } static Xen gxg_gtk_frame_set_shadow_type(Xen frame, Xen type) { #define H_gtk_frame_set_shadow_type "void gtk_frame_set_shadow_type(GtkFrame* frame, GtkShadowType type)" Xen_check_type(Xen_is_GtkFrame_(frame), frame, 1, "gtk_frame_set_shadow_type", "GtkFrame*"); Xen_check_type(Xen_is_GtkShadowType(type), type, 2, "gtk_frame_set_shadow_type", "GtkShadowType"); gtk_frame_set_shadow_type(Xen_to_C_GtkFrame_(frame), Xen_to_C_GtkShadowType(type)); return(Xen_false); } static Xen gxg_gtk_frame_get_shadow_type(Xen frame) { #define H_gtk_frame_get_shadow_type "GtkShadowType gtk_frame_get_shadow_type(GtkFrame* frame)" Xen_check_type(Xen_is_GtkFrame_(frame), frame, 1, "gtk_frame_get_shadow_type", "GtkFrame*"); return(C_to_Xen_GtkShadowType(gtk_frame_get_shadow_type(Xen_to_C_GtkFrame_(frame)))); } static Xen gxg_gtk_image_new(void) { #define H_gtk_image_new "GtkWidget* gtk_image_new( void)" return(C_to_Xen_GtkWidget_(gtk_image_new())); } static Xen gxg_gtk_image_new_from_file(Xen filename) { #define H_gtk_image_new_from_file "GtkWidget* gtk_image_new_from_file(gchar* filename)" Xen_check_type(Xen_is_gchar_(filename), filename, 1, "gtk_image_new_from_file", "gchar*"); return(C_to_Xen_GtkWidget_(gtk_image_new_from_file(Xen_to_C_gchar_(filename)))); } static Xen gxg_gtk_image_new_from_pixbuf(Xen pixbuf) { #define H_gtk_image_new_from_pixbuf "GtkWidget* gtk_image_new_from_pixbuf(GdkPixbuf* pixbuf)" Xen_check_type(Xen_is_GdkPixbuf_(pixbuf) || Xen_is_false(pixbuf), pixbuf, 1, "gtk_image_new_from_pixbuf", "GdkPixbuf*"); return(C_to_Xen_GtkWidget_(gtk_image_new_from_pixbuf(Xen_to_C_GdkPixbuf_(pixbuf)))); } static Xen gxg_gtk_image_new_from_animation(Xen animation) { #define H_gtk_image_new_from_animation "GtkWidget* gtk_image_new_from_animation(GdkPixbufAnimation* animation)" Xen_check_type(Xen_is_GdkPixbufAnimation_(animation), animation, 1, "gtk_image_new_from_animation", "GdkPixbufAnimation*"); return(C_to_Xen_GtkWidget_(gtk_image_new_from_animation(Xen_to_C_GdkPixbufAnimation_(animation)))); } static Xen gxg_gtk_image_set_from_file(Xen image, Xen filename) { #define H_gtk_image_set_from_file "void gtk_image_set_from_file(GtkImage* image, gchar* filename)" Xen_check_type(Xen_is_GtkImage_(image), image, 1, "gtk_image_set_from_file", "GtkImage*"); Xen_check_type(Xen_is_gchar_(filename), filename, 2, "gtk_image_set_from_file", "gchar*"); gtk_image_set_from_file(Xen_to_C_GtkImage_(image), Xen_to_C_gchar_(filename)); return(Xen_false); } static Xen gxg_gtk_image_set_from_pixbuf(Xen image, Xen pixbuf) { #define H_gtk_image_set_from_pixbuf "void gtk_image_set_from_pixbuf(GtkImage* image, GdkPixbuf* pixbuf)" Xen_check_type(Xen_is_GtkImage_(image), image, 1, "gtk_image_set_from_pixbuf", "GtkImage*"); Xen_check_type(Xen_is_GdkPixbuf_(pixbuf) || Xen_is_false(pixbuf), pixbuf, 2, "gtk_image_set_from_pixbuf", "GdkPixbuf*"); gtk_image_set_from_pixbuf(Xen_to_C_GtkImage_(image), Xen_to_C_GdkPixbuf_(pixbuf)); return(Xen_false); } static Xen gxg_gtk_image_set_from_animation(Xen image, Xen animation) { #define H_gtk_image_set_from_animation "void gtk_image_set_from_animation(GtkImage* image, GdkPixbufAnimation* animation)" Xen_check_type(Xen_is_GtkImage_(image), image, 1, "gtk_image_set_from_animation", "GtkImage*"); Xen_check_type(Xen_is_GdkPixbufAnimation_(animation) || Xen_is_false(animation), animation, 2, "gtk_image_set_from_animation", "GdkPixbufAnimation*"); gtk_image_set_from_animation(Xen_to_C_GtkImage_(image), Xen_to_C_GdkPixbufAnimation_(animation)); return(Xen_false); } static Xen gxg_gtk_image_get_storage_type(Xen image) { #define H_gtk_image_get_storage_type "GtkImageType gtk_image_get_storage_type(GtkImage* image)" Xen_check_type(Xen_is_GtkImage_(image), image, 1, "gtk_image_get_storage_type", "GtkImage*"); return(C_to_Xen_GtkImageType(gtk_image_get_storage_type(Xen_to_C_GtkImage_(image)))); } static Xen gxg_gtk_image_get_pixbuf(Xen image) { #define H_gtk_image_get_pixbuf "GdkPixbuf* gtk_image_get_pixbuf(GtkImage* image)" Xen_check_type(Xen_is_GtkImage_(image), image, 1, "gtk_image_get_pixbuf", "GtkImage*"); return(C_to_Xen_GdkPixbuf_(gtk_image_get_pixbuf(Xen_to_C_GtkImage_(image)))); } static Xen gxg_gtk_image_get_animation(Xen image) { #define H_gtk_image_get_animation "GdkPixbufAnimation* gtk_image_get_animation(GtkImage* image)" Xen_check_type(Xen_is_GtkImage_(image), image, 1, "gtk_image_get_animation", "GtkImage*"); return(C_to_Xen_GdkPixbufAnimation_(gtk_image_get_animation(Xen_to_C_GtkImage_(image)))); } static Xen gxg_gtk_im_context_set_client_window(Xen context, Xen window) { #define H_gtk_im_context_set_client_window "void gtk_im_context_set_client_window(GtkIMContext* context, \ GdkWindow* window)" Xen_check_type(Xen_is_GtkIMContext_(context), context, 1, "gtk_im_context_set_client_window", "GtkIMContext*"); Xen_check_type(Xen_is_GdkWindow_(window) || Xen_is_false(window), window, 2, "gtk_im_context_set_client_window", "GdkWindow*"); gtk_im_context_set_client_window(Xen_to_C_GtkIMContext_(context), Xen_to_C_GdkWindow_(window)); return(Xen_false); } static Xen gxg_gtk_im_context_get_preedit_string(Xen context, Xen ignore_str, Xen ignore_attrs, Xen ignore_cursor_pos) { #define H_gtk_im_context_get_preedit_string "void gtk_im_context_get_preedit_string(GtkIMContext* context, \ gchar** [str], PangoAttrList** [attrs], gint* [cursor_pos])" gchar* ref_str = NULL; PangoAttrList* ref_attrs = NULL; gint ref_cursor_pos; Xen_check_type(Xen_is_GtkIMContext_(context), context, 1, "gtk_im_context_get_preedit_string", "GtkIMContext*"); gtk_im_context_get_preedit_string(Xen_to_C_GtkIMContext_(context), &ref_str, &ref_attrs, &ref_cursor_pos); return(Xen_list_3(C_to_Xen_gchar_(ref_str), C_to_Xen_PangoAttrList_(ref_attrs), C_to_Xen_gint(ref_cursor_pos))); } static Xen gxg_gtk_im_context_filter_keypress(Xen context, Xen event) { #define H_gtk_im_context_filter_keypress "gboolean gtk_im_context_filter_keypress(GtkIMContext* context, \ GdkEventKey* event)" Xen_check_type(Xen_is_GtkIMContext_(context), context, 1, "gtk_im_context_filter_keypress", "GtkIMContext*"); Xen_check_type(Xen_is_GdkEventKey_(event), event, 2, "gtk_im_context_filter_keypress", "GdkEventKey*"); return(C_to_Xen_gboolean(gtk_im_context_filter_keypress(Xen_to_C_GtkIMContext_(context), Xen_to_C_GdkEventKey_(event)))); } static Xen gxg_gtk_im_context_focus_in(Xen context) { #define H_gtk_im_context_focus_in "void gtk_im_context_focus_in(GtkIMContext* context)" Xen_check_type(Xen_is_GtkIMContext_(context), context, 1, "gtk_im_context_focus_in", "GtkIMContext*"); gtk_im_context_focus_in(Xen_to_C_GtkIMContext_(context)); return(Xen_false); } static Xen gxg_gtk_im_context_focus_out(Xen context) { #define H_gtk_im_context_focus_out "void gtk_im_context_focus_out(GtkIMContext* context)" Xen_check_type(Xen_is_GtkIMContext_(context), context, 1, "gtk_im_context_focus_out", "GtkIMContext*"); gtk_im_context_focus_out(Xen_to_C_GtkIMContext_(context)); return(Xen_false); } static Xen gxg_gtk_im_context_reset(Xen context) { #define H_gtk_im_context_reset "void gtk_im_context_reset(GtkIMContext* context)" Xen_check_type(Xen_is_GtkIMContext_(context), context, 1, "gtk_im_context_reset", "GtkIMContext*"); gtk_im_context_reset(Xen_to_C_GtkIMContext_(context)); return(Xen_false); } static Xen gxg_gtk_im_context_set_cursor_location(Xen context, Xen area) { #define H_gtk_im_context_set_cursor_location "void gtk_im_context_set_cursor_location(GtkIMContext* context, \ GdkRectangle* area)" Xen_check_type(Xen_is_GtkIMContext_(context), context, 1, "gtk_im_context_set_cursor_location", "GtkIMContext*"); Xen_check_type(Xen_is_GdkRectangle_(area), area, 2, "gtk_im_context_set_cursor_location", "GdkRectangle*"); gtk_im_context_set_cursor_location(Xen_to_C_GtkIMContext_(context), Xen_to_C_GdkRectangle_(area)); return(Xen_false); } static Xen gxg_gtk_im_context_set_use_preedit(Xen context, Xen use_preedit) { #define H_gtk_im_context_set_use_preedit "void gtk_im_context_set_use_preedit(GtkIMContext* context, \ gboolean use_preedit)" Xen_check_type(Xen_is_GtkIMContext_(context), context, 1, "gtk_im_context_set_use_preedit", "GtkIMContext*"); Xen_check_type(Xen_is_gboolean(use_preedit), use_preedit, 2, "gtk_im_context_set_use_preedit", "gboolean"); gtk_im_context_set_use_preedit(Xen_to_C_GtkIMContext_(context), Xen_to_C_gboolean(use_preedit)); return(Xen_false); } static Xen gxg_gtk_im_context_set_surrounding(Xen context, Xen text, Xen len, Xen cursor_index) { #define H_gtk_im_context_set_surrounding "void gtk_im_context_set_surrounding(GtkIMContext* context, \ gchar* text, gint len, gint cursor_index)" Xen_check_type(Xen_is_GtkIMContext_(context), context, 1, "gtk_im_context_set_surrounding", "GtkIMContext*"); Xen_check_type(Xen_is_gchar_(text), text, 2, "gtk_im_context_set_surrounding", "gchar*"); Xen_check_type(Xen_is_gint(len), len, 3, "gtk_im_context_set_surrounding", "gint"); Xen_check_type(Xen_is_gint(cursor_index), cursor_index, 4, "gtk_im_context_set_surrounding", "gint"); gtk_im_context_set_surrounding(Xen_to_C_GtkIMContext_(context), Xen_to_C_gchar_(text), Xen_to_C_gint(len), Xen_to_C_gint(cursor_index)); return(Xen_false); } static Xen gxg_gtk_im_context_get_surrounding(Xen context, Xen ignore_text, Xen ignore_cursor_index) { #define H_gtk_im_context_get_surrounding "gboolean gtk_im_context_get_surrounding(GtkIMContext* context, \ gchar** [text], gint* [cursor_index])" gchar* ref_text = NULL; gint ref_cursor_index; Xen_check_type(Xen_is_GtkIMContext_(context), context, 1, "gtk_im_context_get_surrounding", "GtkIMContext*"); { Xen result; result = C_to_Xen_gboolean(gtk_im_context_get_surrounding(Xen_to_C_GtkIMContext_(context), &ref_text, &ref_cursor_index)); return(Xen_list_3(result, C_to_Xen_gchar_(ref_text), C_to_Xen_gint(ref_cursor_index))); } } static Xen gxg_gtk_im_context_delete_surrounding(Xen context, Xen offset, Xen n_chars) { #define H_gtk_im_context_delete_surrounding "gboolean gtk_im_context_delete_surrounding(GtkIMContext* context, \ gint offset, gint n_chars)" Xen_check_type(Xen_is_GtkIMContext_(context), context, 1, "gtk_im_context_delete_surrounding", "GtkIMContext*"); Xen_check_type(Xen_is_gint(offset), offset, 2, "gtk_im_context_delete_surrounding", "gint"); Xen_check_type(Xen_is_gint(n_chars), n_chars, 3, "gtk_im_context_delete_surrounding", "gint"); return(C_to_Xen_gboolean(gtk_im_context_delete_surrounding(Xen_to_C_GtkIMContext_(context), Xen_to_C_gint(offset), Xen_to_C_gint(n_chars)))); } static Xen gxg_gtk_im_context_simple_new(void) { #define H_gtk_im_context_simple_new "GtkIMContext* gtk_im_context_simple_new( void)" return(C_to_Xen_GtkIMContext_(gtk_im_context_simple_new())); } static Xen gxg_gtk_im_context_simple_add_table(Xen context_simple, Xen data, Xen max_seq_len, Xen n_seqs) { #define H_gtk_im_context_simple_add_table "void gtk_im_context_simple_add_table(GtkIMContextSimple* context_simple, \ guint16* data, gint max_seq_len, gint n_seqs)" Xen_check_type(Xen_is_GtkIMContextSimple_(context_simple), context_simple, 1, "gtk_im_context_simple_add_table", "GtkIMContextSimple*"); Xen_check_type(Xen_is_guint16_(data), data, 2, "gtk_im_context_simple_add_table", "guint16*"); Xen_check_type(Xen_is_gint(max_seq_len), max_seq_len, 3, "gtk_im_context_simple_add_table", "gint"); Xen_check_type(Xen_is_gint(n_seqs), n_seqs, 4, "gtk_im_context_simple_add_table", "gint"); gtk_im_context_simple_add_table(Xen_to_C_GtkIMContextSimple_(context_simple), Xen_to_C_guint16_(data), Xen_to_C_gint(max_seq_len), Xen_to_C_gint(n_seqs)); return(Xen_false); } static Xen gxg_gtk_invisible_new(void) { #define H_gtk_invisible_new "GtkWidget* gtk_invisible_new( void)" return(C_to_Xen_GtkWidget_(gtk_invisible_new())); } static Xen gxg_gtk_label_new(Xen str) { #define H_gtk_label_new "GtkWidget* gtk_label_new(char* str)" Xen_check_type(Xen_is_char_(str), str, 1, "gtk_label_new", "char*"); return(C_to_Xen_GtkWidget_(gtk_label_new(Xen_to_C_char_(str)))); } static Xen gxg_gtk_label_new_with_mnemonic(Xen str) { #define H_gtk_label_new_with_mnemonic "GtkWidget* gtk_label_new_with_mnemonic(char* str)" Xen_check_type(Xen_is_char_(str), str, 1, "gtk_label_new_with_mnemonic", "char*"); return(C_to_Xen_GtkWidget_(gtk_label_new_with_mnemonic(Xen_to_C_char_(str)))); } static Xen gxg_gtk_label_set_text(Xen label, Xen str) { #define H_gtk_label_set_text "void gtk_label_set_text(GtkLabel* label, char* str)" Xen_check_type(Xen_is_GtkLabel_(label), label, 1, "gtk_label_set_text", "GtkLabel*"); Xen_check_type(Xen_is_char_(str), str, 2, "gtk_label_set_text", "char*"); gtk_label_set_text(Xen_to_C_GtkLabel_(label), Xen_to_C_char_(str)); return(Xen_false); } static Xen gxg_gtk_label_get_text(Xen label) { #define H_gtk_label_get_text "gchar* gtk_label_get_text(GtkLabel* label)" Xen_check_type(Xen_is_GtkLabel_(label), label, 1, "gtk_label_get_text", "GtkLabel*"); return(C_to_Xen_gchar_(gtk_label_get_text(Xen_to_C_GtkLabel_(label)))); } static Xen gxg_gtk_label_set_attributes(Xen label, Xen attrs) { #define H_gtk_label_set_attributes "void gtk_label_set_attributes(GtkLabel* label, PangoAttrList* attrs)" Xen_check_type(Xen_is_GtkLabel_(label), label, 1, "gtk_label_set_attributes", "GtkLabel*"); Xen_check_type(Xen_is_PangoAttrList_(attrs), attrs, 2, "gtk_label_set_attributes", "PangoAttrList*"); gtk_label_set_attributes(Xen_to_C_GtkLabel_(label), Xen_to_C_PangoAttrList_(attrs)); return(Xen_false); } static Xen gxg_gtk_label_get_attributes(Xen label) { #define H_gtk_label_get_attributes "PangoAttrList* gtk_label_get_attributes(GtkLabel* label)" Xen_check_type(Xen_is_GtkLabel_(label), label, 1, "gtk_label_get_attributes", "GtkLabel*"); return(C_to_Xen_PangoAttrList_(gtk_label_get_attributes(Xen_to_C_GtkLabel_(label)))); } static Xen gxg_gtk_label_set_label(Xen label, Xen str) { #define H_gtk_label_set_label "void gtk_label_set_label(GtkLabel* label, gchar* str)" Xen_check_type(Xen_is_GtkLabel_(label), label, 1, "gtk_label_set_label", "GtkLabel*"); Xen_check_type(Xen_is_gchar_(str), str, 2, "gtk_label_set_label", "gchar*"); gtk_label_set_label(Xen_to_C_GtkLabel_(label), Xen_to_C_gchar_(str)); return(Xen_false); } static Xen gxg_gtk_label_get_label(Xen label) { #define H_gtk_label_get_label "gchar* gtk_label_get_label(GtkLabel* label)" Xen_check_type(Xen_is_GtkLabel_(label), label, 1, "gtk_label_get_label", "GtkLabel*"); return(C_to_Xen_gchar_(gtk_label_get_label(Xen_to_C_GtkLabel_(label)))); } static Xen gxg_gtk_label_set_markup(Xen label, Xen str) { #define H_gtk_label_set_markup "void gtk_label_set_markup(GtkLabel* label, gchar* str)" Xen_check_type(Xen_is_GtkLabel_(label), label, 1, "gtk_label_set_markup", "GtkLabel*"); Xen_check_type(Xen_is_gchar_(str), str, 2, "gtk_label_set_markup", "gchar*"); gtk_label_set_markup(Xen_to_C_GtkLabel_(label), Xen_to_C_gchar_(str)); return(Xen_false); } static Xen gxg_gtk_label_set_use_markup(Xen label, Xen setting) { #define H_gtk_label_set_use_markup "void gtk_label_set_use_markup(GtkLabel* label, gboolean setting)" Xen_check_type(Xen_is_GtkLabel_(label), label, 1, "gtk_label_set_use_markup", "GtkLabel*"); Xen_check_type(Xen_is_gboolean(setting), setting, 2, "gtk_label_set_use_markup", "gboolean"); gtk_label_set_use_markup(Xen_to_C_GtkLabel_(label), Xen_to_C_gboolean(setting)); return(Xen_false); } static Xen gxg_gtk_label_get_use_markup(Xen label) { #define H_gtk_label_get_use_markup "gboolean gtk_label_get_use_markup(GtkLabel* label)" Xen_check_type(Xen_is_GtkLabel_(label), label, 1, "gtk_label_get_use_markup", "GtkLabel*"); return(C_to_Xen_gboolean(gtk_label_get_use_markup(Xen_to_C_GtkLabel_(label)))); } static Xen gxg_gtk_label_set_use_underline(Xen label, Xen setting) { #define H_gtk_label_set_use_underline "void gtk_label_set_use_underline(GtkLabel* label, gboolean setting)" Xen_check_type(Xen_is_GtkLabel_(label), label, 1, "gtk_label_set_use_underline", "GtkLabel*"); Xen_check_type(Xen_is_gboolean(setting), setting, 2, "gtk_label_set_use_underline", "gboolean"); gtk_label_set_use_underline(Xen_to_C_GtkLabel_(label), Xen_to_C_gboolean(setting)); return(Xen_false); } static Xen gxg_gtk_label_get_use_underline(Xen label) { #define H_gtk_label_get_use_underline "gboolean gtk_label_get_use_underline(GtkLabel* label)" Xen_check_type(Xen_is_GtkLabel_(label), label, 1, "gtk_label_get_use_underline", "GtkLabel*"); return(C_to_Xen_gboolean(gtk_label_get_use_underline(Xen_to_C_GtkLabel_(label)))); } static Xen gxg_gtk_label_set_markup_with_mnemonic(Xen label, Xen str) { #define H_gtk_label_set_markup_with_mnemonic "void gtk_label_set_markup_with_mnemonic(GtkLabel* label, \ gchar* str)" Xen_check_type(Xen_is_GtkLabel_(label), label, 1, "gtk_label_set_markup_with_mnemonic", "GtkLabel*"); Xen_check_type(Xen_is_gchar_(str), str, 2, "gtk_label_set_markup_with_mnemonic", "gchar*"); gtk_label_set_markup_with_mnemonic(Xen_to_C_GtkLabel_(label), Xen_to_C_gchar_(str)); return(Xen_false); } static Xen gxg_gtk_label_get_mnemonic_keyval(Xen label) { #define H_gtk_label_get_mnemonic_keyval "guint gtk_label_get_mnemonic_keyval(GtkLabel* label)" Xen_check_type(Xen_is_GtkLabel_(label), label, 1, "gtk_label_get_mnemonic_keyval", "GtkLabel*"); return(C_to_Xen_guint(gtk_label_get_mnemonic_keyval(Xen_to_C_GtkLabel_(label)))); } static Xen gxg_gtk_label_set_mnemonic_widget(Xen label, Xen widget) { #define H_gtk_label_set_mnemonic_widget "void gtk_label_set_mnemonic_widget(GtkLabel* label, GtkWidget* widget)" Xen_check_type(Xen_is_GtkLabel_(label), label, 1, "gtk_label_set_mnemonic_widget", "GtkLabel*"); Xen_check_type(Xen_is_GtkWidget_(widget), widget, 2, "gtk_label_set_mnemonic_widget", "GtkWidget*"); gtk_label_set_mnemonic_widget(Xen_to_C_GtkLabel_(label), Xen_to_C_GtkWidget_(widget)); return(Xen_false); } static Xen gxg_gtk_label_get_mnemonic_widget(Xen label) { #define H_gtk_label_get_mnemonic_widget "GtkWidget* gtk_label_get_mnemonic_widget(GtkLabel* label)" Xen_check_type(Xen_is_GtkLabel_(label), label, 1, "gtk_label_get_mnemonic_widget", "GtkLabel*"); return(C_to_Xen_GtkWidget_(gtk_label_get_mnemonic_widget(Xen_to_C_GtkLabel_(label)))); } static Xen gxg_gtk_label_set_text_with_mnemonic(Xen label, Xen str) { #define H_gtk_label_set_text_with_mnemonic "void gtk_label_set_text_with_mnemonic(GtkLabel* label, \ gchar* str)" Xen_check_type(Xen_is_GtkLabel_(label), label, 1, "gtk_label_set_text_with_mnemonic", "GtkLabel*"); Xen_check_type(Xen_is_gchar_(str), str, 2, "gtk_label_set_text_with_mnemonic", "gchar*"); gtk_label_set_text_with_mnemonic(Xen_to_C_GtkLabel_(label), Xen_to_C_gchar_(str)); return(Xen_false); } static Xen gxg_gtk_label_set_justify(Xen label, Xen jtype) { #define H_gtk_label_set_justify "void gtk_label_set_justify(GtkLabel* label, GtkJustification jtype)" Xen_check_type(Xen_is_GtkLabel_(label), label, 1, "gtk_label_set_justify", "GtkLabel*"); Xen_check_type(Xen_is_GtkJustification(jtype), jtype, 2, "gtk_label_set_justify", "GtkJustification"); gtk_label_set_justify(Xen_to_C_GtkLabel_(label), Xen_to_C_GtkJustification(jtype)); return(Xen_false); } static Xen gxg_gtk_label_get_justify(Xen label) { #define H_gtk_label_get_justify "GtkJustification gtk_label_get_justify(GtkLabel* label)" Xen_check_type(Xen_is_GtkLabel_(label), label, 1, "gtk_label_get_justify", "GtkLabel*"); return(C_to_Xen_GtkJustification(gtk_label_get_justify(Xen_to_C_GtkLabel_(label)))); } static Xen gxg_gtk_label_set_pattern(Xen label, Xen pattern) { #define H_gtk_label_set_pattern "void gtk_label_set_pattern(GtkLabel* label, gchar* pattern)" Xen_check_type(Xen_is_GtkLabel_(label), label, 1, "gtk_label_set_pattern", "GtkLabel*"); Xen_check_type(Xen_is_gchar_(pattern), pattern, 2, "gtk_label_set_pattern", "gchar*"); gtk_label_set_pattern(Xen_to_C_GtkLabel_(label), Xen_to_C_gchar_(pattern)); return(Xen_false); } static Xen gxg_gtk_label_set_line_wrap(Xen label, Xen wrap) { #define H_gtk_label_set_line_wrap "void gtk_label_set_line_wrap(GtkLabel* label, gboolean wrap)" Xen_check_type(Xen_is_GtkLabel_(label), label, 1, "gtk_label_set_line_wrap", "GtkLabel*"); Xen_check_type(Xen_is_gboolean(wrap), wrap, 2, "gtk_label_set_line_wrap", "gboolean"); gtk_label_set_line_wrap(Xen_to_C_GtkLabel_(label), Xen_to_C_gboolean(wrap)); return(Xen_false); } static Xen gxg_gtk_label_get_line_wrap(Xen label) { #define H_gtk_label_get_line_wrap "gboolean gtk_label_get_line_wrap(GtkLabel* label)" Xen_check_type(Xen_is_GtkLabel_(label), label, 1, "gtk_label_get_line_wrap", "GtkLabel*"); return(C_to_Xen_gboolean(gtk_label_get_line_wrap(Xen_to_C_GtkLabel_(label)))); } static Xen gxg_gtk_label_set_selectable(Xen label, Xen setting) { #define H_gtk_label_set_selectable "void gtk_label_set_selectable(GtkLabel* label, gboolean setting)" Xen_check_type(Xen_is_GtkLabel_(label), label, 1, "gtk_label_set_selectable", "GtkLabel*"); Xen_check_type(Xen_is_gboolean(setting), setting, 2, "gtk_label_set_selectable", "gboolean"); gtk_label_set_selectable(Xen_to_C_GtkLabel_(label), Xen_to_C_gboolean(setting)); return(Xen_false); } static Xen gxg_gtk_label_get_selectable(Xen label) { #define H_gtk_label_get_selectable "gboolean gtk_label_get_selectable(GtkLabel* label)" Xen_check_type(Xen_is_GtkLabel_(label), label, 1, "gtk_label_get_selectable", "GtkLabel*"); return(C_to_Xen_gboolean(gtk_label_get_selectable(Xen_to_C_GtkLabel_(label)))); } static Xen gxg_gtk_label_select_region(Xen label, Xen start_offset, Xen end_offset) { #define H_gtk_label_select_region "void gtk_label_select_region(GtkLabel* label, gint start_offset, \ gint end_offset)" Xen_check_type(Xen_is_GtkLabel_(label), label, 1, "gtk_label_select_region", "GtkLabel*"); Xen_check_type(Xen_is_gint(start_offset), start_offset, 2, "gtk_label_select_region", "gint"); Xen_check_type(Xen_is_gint(end_offset), end_offset, 3, "gtk_label_select_region", "gint"); gtk_label_select_region(Xen_to_C_GtkLabel_(label), Xen_to_C_gint(start_offset), Xen_to_C_gint(end_offset)); return(Xen_false); } static Xen gxg_gtk_label_get_selection_bounds(Xen label, Xen ignore_start, Xen ignore_end) { #define H_gtk_label_get_selection_bounds "gboolean gtk_label_get_selection_bounds(GtkLabel* label, \ gint* [start], gint* [end])" gint ref_start; gint ref_end; Xen_check_type(Xen_is_GtkLabel_(label), label, 1, "gtk_label_get_selection_bounds", "GtkLabel*"); { Xen result; result = C_to_Xen_gboolean(gtk_label_get_selection_bounds(Xen_to_C_GtkLabel_(label), &ref_start, &ref_end)); return(Xen_list_3(result, C_to_Xen_gint(ref_start), C_to_Xen_gint(ref_end))); } } static Xen gxg_gtk_label_get_layout(Xen label) { #define H_gtk_label_get_layout "PangoLayout* gtk_label_get_layout(GtkLabel* label)" Xen_check_type(Xen_is_GtkLabel_(label), label, 1, "gtk_label_get_layout", "GtkLabel*"); return(C_to_Xen_PangoLayout_(gtk_label_get_layout(Xen_to_C_GtkLabel_(label)))); } static Xen gxg_gtk_label_get_layout_offsets(Xen label, Xen ignore_x, Xen ignore_y) { #define H_gtk_label_get_layout_offsets "void gtk_label_get_layout_offsets(GtkLabel* label, gint* [x], \ gint* [y])" gint ref_x; gint ref_y; Xen_check_type(Xen_is_GtkLabel_(label), label, 1, "gtk_label_get_layout_offsets", "GtkLabel*"); gtk_label_get_layout_offsets(Xen_to_C_GtkLabel_(label), &ref_x, &ref_y); return(Xen_list_2(C_to_Xen_gint(ref_x), C_to_Xen_gint(ref_y))); } static Xen gxg_gtk_layout_new(Xen hadjustment, Xen vadjustment) { #define H_gtk_layout_new "GtkWidget* gtk_layout_new(GtkAdjustment* hadjustment, GtkAdjustment* vadjustment)" Xen_check_type(Xen_is_GtkAdjustment_(hadjustment) || Xen_is_false(hadjustment), hadjustment, 1, "gtk_layout_new", "GtkAdjustment*"); Xen_check_type(Xen_is_GtkAdjustment_(vadjustment) || Xen_is_false(vadjustment), vadjustment, 2, "gtk_layout_new", "GtkAdjustment*"); return(C_to_Xen_GtkWidget_(gtk_layout_new(Xen_to_C_GtkAdjustment_(hadjustment), Xen_to_C_GtkAdjustment_(vadjustment)))); } static Xen gxg_gtk_layout_put(Xen layout, Xen child_widget, Xen x, Xen y) { #define H_gtk_layout_put "void gtk_layout_put(GtkLayout* layout, GtkWidget* child_widget, gint x, gint y)" Xen_check_type(Xen_is_GtkLayout_(layout), layout, 1, "gtk_layout_put", "GtkLayout*"); Xen_check_type(Xen_is_GtkWidget_(child_widget), child_widget, 2, "gtk_layout_put", "GtkWidget*"); Xen_check_type(Xen_is_gint(x), x, 3, "gtk_layout_put", "gint"); Xen_check_type(Xen_is_gint(y), y, 4, "gtk_layout_put", "gint"); gtk_layout_put(Xen_to_C_GtkLayout_(layout), Xen_to_C_GtkWidget_(child_widget), Xen_to_C_gint(x), Xen_to_C_gint(y)); return(Xen_false); } static Xen gxg_gtk_layout_move(Xen layout, Xen child_widget, Xen x, Xen y) { #define H_gtk_layout_move "void gtk_layout_move(GtkLayout* layout, GtkWidget* child_widget, gint x, \ gint y)" Xen_check_type(Xen_is_GtkLayout_(layout), layout, 1, "gtk_layout_move", "GtkLayout*"); Xen_check_type(Xen_is_GtkWidget_(child_widget), child_widget, 2, "gtk_layout_move", "GtkWidget*"); Xen_check_type(Xen_is_gint(x), x, 3, "gtk_layout_move", "gint"); Xen_check_type(Xen_is_gint(y), y, 4, "gtk_layout_move", "gint"); gtk_layout_move(Xen_to_C_GtkLayout_(layout), Xen_to_C_GtkWidget_(child_widget), Xen_to_C_gint(x), Xen_to_C_gint(y)); return(Xen_false); } static Xen gxg_gtk_layout_set_size(Xen layout, Xen width, Xen height) { #define H_gtk_layout_set_size "void gtk_layout_set_size(GtkLayout* layout, guint width, guint height)" Xen_check_type(Xen_is_GtkLayout_(layout), layout, 1, "gtk_layout_set_size", "GtkLayout*"); Xen_check_type(Xen_is_guint(width), width, 2, "gtk_layout_set_size", "guint"); Xen_check_type(Xen_is_guint(height), height, 3, "gtk_layout_set_size", "guint"); gtk_layout_set_size(Xen_to_C_GtkLayout_(layout), Xen_to_C_guint(width), Xen_to_C_guint(height)); return(Xen_false); } static Xen gxg_gtk_layout_get_size(Xen layout, Xen ignore_width, Xen ignore_height) { #define H_gtk_layout_get_size "void gtk_layout_get_size(GtkLayout* layout, guint* [width], guint* [height])" guint ref_width; guint ref_height; Xen_check_type(Xen_is_GtkLayout_(layout), layout, 1, "gtk_layout_get_size", "GtkLayout*"); gtk_layout_get_size(Xen_to_C_GtkLayout_(layout), &ref_width, &ref_height); return(Xen_list_2(C_to_Xen_guint(ref_width), C_to_Xen_guint(ref_height))); } static Xen gxg_gtk_list_store_new(Xen n_columns, Xen types) { #define H_gtk_list_store_new "GtkListStore* gtk_list_store_new(gint n_columns, etc types)" Xen_check_type(Xen_is_gint(n_columns), n_columns, 1, "gtk_list_store_new", "gint"); Xen_check_type(Xen_is_etc(types), types, 2, "gtk_list_store_new", "etc"); { int etc_len = 0; GtkListStore* result = NULL; gint p_arg0; if (Xen_is_list(types)) etc_len = Xen_list_length(types); if (etc_len < 1) Xen_out_of_range_error("gtk_list_store_new", 1, types, "... list must have at least 1 entry"); if (etc_len > 6) Xen_out_of_range_error("gtk_list_store_new", 1, types, "... list too long (max len: 6)"); p_arg0 = Xen_to_C_gint(n_columns); switch (etc_len) { case 1: result = gtk_list_store_new(p_arg0, XLG(types, 0)); break; case 2: result = gtk_list_store_new(p_arg0, XLG(types, 0), XLG(types, 1)); break; case 3: result = gtk_list_store_new(p_arg0, XLG(types, 0), XLG(types, 1), XLG(types, 2)); break; case 4: result = gtk_list_store_new(p_arg0, XLG(types, 0), XLG(types, 1), XLG(types, 2), XLG(types, 3)); break; case 5: result = gtk_list_store_new(p_arg0, XLG(types, 0), XLG(types, 1), XLG(types, 2), XLG(types, 3), XLG(types, 4)); break; case 6: result = gtk_list_store_new(p_arg0, XLG(types, 0), XLG(types, 1), XLG(types, 2), XLG(types, 3), XLG(types, 4), XLG(types, 5)); break; } return(C_to_Xen_GtkListStore_(result)); } } static Xen gxg_gtk_list_store_newv(Xen n_columns, Xen types) { #define H_gtk_list_store_newv "GtkListStore* gtk_list_store_newv(gint n_columns, GType* types)" Xen_check_type(Xen_is_gint(n_columns), n_columns, 1, "gtk_list_store_newv", "gint"); Xen_check_type(Xen_is_GType_(types), types, 2, "gtk_list_store_newv", "GType*"); return(C_to_Xen_GtkListStore_(gtk_list_store_newv(Xen_to_C_gint(n_columns), Xen_to_C_GType_(types)))); } static Xen gxg_gtk_list_store_set_column_types(Xen list_store, Xen n_columns, Xen types) { #define H_gtk_list_store_set_column_types "void gtk_list_store_set_column_types(GtkListStore* list_store, \ gint n_columns, GType* types)" Xen_check_type(Xen_is_GtkListStore_(list_store), list_store, 1, "gtk_list_store_set_column_types", "GtkListStore*"); Xen_check_type(Xen_is_gint(n_columns), n_columns, 2, "gtk_list_store_set_column_types", "gint"); Xen_check_type(Xen_is_GType_(types), types, 3, "gtk_list_store_set_column_types", "GType*"); gtk_list_store_set_column_types(Xen_to_C_GtkListStore_(list_store), Xen_to_C_gint(n_columns), Xen_to_C_GType_(types)); return(Xen_false); } static Xen gxg_gtk_list_store_set(Xen list_store, Xen iter, Xen values) { #define H_gtk_list_store_set "void gtk_list_store_set(GtkListStore* list_store, GtkTreeIter* iter, \ etc values)" Xen_check_type(Xen_is_GtkListStore_(list_store), list_store, 1, "gtk_list_store_set", "GtkListStore*"); Xen_check_type(Xen_is_GtkTreeIter_(iter), iter, 2, "gtk_list_store_set", "GtkTreeIter*"); Xen_check_type(Xen_is_etc(values), values, 3, "gtk_list_store_set", "etc"); { int etc_len = 0; GtkListStore* p_arg0; GtkTreeIter* p_arg1; if (Xen_is_list(values)) etc_len = Xen_list_length(values); if (etc_len < 2) Xen_out_of_range_error("gtk_list_store_set", 2, values, "... list must have at least 2 entries"); if (etc_len > 10) Xen_out_of_range_error("gtk_list_store_set", 2, values, "... list too long (max len: 10)"); if ((etc_len % 2) != 0) Xen_out_of_range_error("gtk_list_store_set", 2, values, "... list len must be multiple of 2"); p_arg0 = Xen_to_C_GtkListStore_(list_store); p_arg1 = Xen_to_C_GtkTreeIter_(iter); switch (etc_len) { case 2: gtk_list_store_set(p_arg0, p_arg1, XLI(values, 0), XLS(values, 1), -1); break; case 4: gtk_list_store_set(p_arg0, p_arg1, XLI(values, 0), XLS(values, 1), XLI(values, 2), XLS(values, 3), -1); break; case 6: gtk_list_store_set(p_arg0, p_arg1, XLI(values, 0), XLS(values, 1), XLI(values, 2), XLS(values, 3), XLI(values, 4), XLS(values, 5), -1); break; case 8: gtk_list_store_set(p_arg0, p_arg1, XLI(values, 0), XLS(values, 1), XLI(values, 2), XLS(values, 3), XLI(values, 4), XLS(values, 5), XLI(values, 6), XLS(values, 7), -1); break; case 10: gtk_list_store_set(p_arg0, p_arg1, XLI(values, 0), XLS(values, 1), XLI(values, 2), XLS(values, 3), XLI(values, 4), XLS(values, 5), XLI(values, 6), XLS(values, 7), XLI(values, 8), XLS(values, 9), -1); break; } return(Xen_false); } } static Xen gxg_gtk_list_store_insert(Xen list_store, Xen iter, Xen position) { #define H_gtk_list_store_insert "void gtk_list_store_insert(GtkListStore* list_store, GtkTreeIter* iter, \ gint position)" Xen_check_type(Xen_is_GtkListStore_(list_store), list_store, 1, "gtk_list_store_insert", "GtkListStore*"); Xen_check_type(Xen_is_GtkTreeIter_(iter), iter, 2, "gtk_list_store_insert", "GtkTreeIter*"); Xen_check_type(Xen_is_gint(position), position, 3, "gtk_list_store_insert", "gint"); gtk_list_store_insert(Xen_to_C_GtkListStore_(list_store), Xen_to_C_GtkTreeIter_(iter), Xen_to_C_gint(position)); return(Xen_false); } static Xen gxg_gtk_list_store_insert_before(Xen list_store, Xen iter, Xen sibling) { #define H_gtk_list_store_insert_before "void gtk_list_store_insert_before(GtkListStore* list_store, \ GtkTreeIter* iter, GtkTreeIter* sibling)" Xen_check_type(Xen_is_GtkListStore_(list_store), list_store, 1, "gtk_list_store_insert_before", "GtkListStore*"); Xen_check_type(Xen_is_GtkTreeIter_(iter), iter, 2, "gtk_list_store_insert_before", "GtkTreeIter*"); Xen_check_type(Xen_is_GtkTreeIter_(sibling) || Xen_is_false(sibling), sibling, 3, "gtk_list_store_insert_before", "GtkTreeIter*"); gtk_list_store_insert_before(Xen_to_C_GtkListStore_(list_store), Xen_to_C_GtkTreeIter_(iter), Xen_to_C_GtkTreeIter_(sibling)); return(Xen_false); } static Xen gxg_gtk_list_store_insert_after(Xen list_store, Xen iter, Xen sibling) { #define H_gtk_list_store_insert_after "void gtk_list_store_insert_after(GtkListStore* list_store, GtkTreeIter* iter, \ GtkTreeIter* sibling)" Xen_check_type(Xen_is_GtkListStore_(list_store), list_store, 1, "gtk_list_store_insert_after", "GtkListStore*"); Xen_check_type(Xen_is_GtkTreeIter_(iter), iter, 2, "gtk_list_store_insert_after", "GtkTreeIter*"); Xen_check_type(Xen_is_GtkTreeIter_(sibling) || Xen_is_false(sibling), sibling, 3, "gtk_list_store_insert_after", "GtkTreeIter*"); gtk_list_store_insert_after(Xen_to_C_GtkListStore_(list_store), Xen_to_C_GtkTreeIter_(iter), Xen_to_C_GtkTreeIter_(sibling)); return(Xen_false); } static Xen gxg_gtk_list_store_prepend(Xen list_store, Xen iter) { #define H_gtk_list_store_prepend "void gtk_list_store_prepend(GtkListStore* list_store, GtkTreeIter* iter)" Xen_check_type(Xen_is_GtkListStore_(list_store), list_store, 1, "gtk_list_store_prepend", "GtkListStore*"); Xen_check_type(Xen_is_GtkTreeIter_(iter), iter, 2, "gtk_list_store_prepend", "GtkTreeIter*"); gtk_list_store_prepend(Xen_to_C_GtkListStore_(list_store), Xen_to_C_GtkTreeIter_(iter)); return(Xen_false); } static Xen gxg_gtk_list_store_append(Xen list_store, Xen iter) { #define H_gtk_list_store_append "void gtk_list_store_append(GtkListStore* list_store, GtkTreeIter* iter)" Xen_check_type(Xen_is_GtkListStore_(list_store), list_store, 1, "gtk_list_store_append", "GtkListStore*"); Xen_check_type(Xen_is_GtkTreeIter_(iter), iter, 2, "gtk_list_store_append", "GtkTreeIter*"); gtk_list_store_append(Xen_to_C_GtkListStore_(list_store), Xen_to_C_GtkTreeIter_(iter)); return(Xen_false); } static Xen gxg_gtk_list_store_clear(Xen list_store) { #define H_gtk_list_store_clear "void gtk_list_store_clear(GtkListStore* list_store)" Xen_check_type(Xen_is_GtkListStore_(list_store), list_store, 1, "gtk_list_store_clear", "GtkListStore*"); gtk_list_store_clear(Xen_to_C_GtkListStore_(list_store)); return(Xen_false); } static Xen gxg_gtk_check_version(Xen required_major, Xen required_minor, Xen required_micro) { #define H_gtk_check_version "gchar* gtk_check_version(guint required_major, guint required_minor, guint required_micro)" Xen_check_type(Xen_is_guint(required_major), required_major, 1, "gtk_check_version", "guint"); Xen_check_type(Xen_is_guint(required_minor), required_minor, 2, "gtk_check_version", "guint"); Xen_check_type(Xen_is_guint(required_micro), required_micro, 3, "gtk_check_version", "guint"); return(C_to_Xen_gchar_((gchar*)gtk_check_version(Xen_to_C_guint(required_major), Xen_to_C_guint(required_minor), Xen_to_C_guint(required_micro)))); } static Xen gxg_gtk_disable_setlocale(void) { #define H_gtk_disable_setlocale "void gtk_disable_setlocale( void)" gtk_disable_setlocale(); return(Xen_false); } static Xen gxg_gtk_get_default_language(void) { #define H_gtk_get_default_language "PangoLanguage* gtk_get_default_language( void)" return(C_to_Xen_PangoLanguage_(gtk_get_default_language())); } static Xen gxg_gtk_events_pending(void) { #define H_gtk_events_pending "gint gtk_events_pending( void)" return(C_to_Xen_gint(gtk_events_pending())); } static Xen gxg_gtk_main_do_event(Xen event) { #define H_gtk_main_do_event "void gtk_main_do_event(GdkEvent* event)" Xen_check_type(Xen_is_GdkEvent_(event), event, 1, "gtk_main_do_event", "GdkEvent*"); gtk_main_do_event(Xen_to_C_GdkEvent_(event)); return(Xen_false); } static Xen gxg_gtk_main(void) { #define H_gtk_main "void gtk_main( void)" gtk_main(); return(Xen_false); } static Xen gxg_gtk_main_level(void) { #define H_gtk_main_level "guint gtk_main_level( void)" return(C_to_Xen_guint(gtk_main_level())); } static Xen gxg_gtk_main_quit(void) { #define H_gtk_main_quit "void gtk_main_quit( void)" gtk_main_quit(); return(Xen_false); } static Xen gxg_gtk_main_iteration(void) { #define H_gtk_main_iteration "gboolean gtk_main_iteration( void)" return(C_to_Xen_gboolean(gtk_main_iteration())); } static Xen gxg_gtk_main_iteration_do(Xen blocking) { #define H_gtk_main_iteration_do "gboolean gtk_main_iteration_do(gboolean blocking)" Xen_check_type(Xen_is_gboolean(blocking), blocking, 1, "gtk_main_iteration_do", "gboolean"); return(C_to_Xen_gboolean(gtk_main_iteration_do(Xen_to_C_gboolean(blocking)))); } static Xen gxg_gtk_true(void) { #define H_gtk_true "gboolean gtk_true( void)" return(C_to_Xen_gboolean(gtk_true())); } static Xen gxg_gtk_false(void) { #define H_gtk_false "gboolean gtk_false( void)" return(C_to_Xen_gboolean(gtk_false())); } static Xen gxg_gtk_grab_add(Xen widget) { #define H_gtk_grab_add "void gtk_grab_add(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_grab_add", "GtkWidget*"); gtk_grab_add(Xen_to_C_GtkWidget_(widget)); return(Xen_false); } static Xen gxg_gtk_grab_get_current(void) { #define H_gtk_grab_get_current "GtkWidget* gtk_grab_get_current( void)" return(C_to_Xen_GtkWidget_(gtk_grab_get_current())); } static Xen gxg_gtk_grab_remove(Xen widget) { #define H_gtk_grab_remove "void gtk_grab_remove(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_grab_remove", "GtkWidget*"); gtk_grab_remove(Xen_to_C_GtkWidget_(widget)); return(Xen_false); } static Xen gxg_gtk_get_current_event(void) { #define H_gtk_get_current_event "GdkEvent* gtk_get_current_event( void)" return(C_to_Xen_GdkEvent_(gtk_get_current_event())); } static Xen gxg_gtk_get_current_event_time(void) { #define H_gtk_get_current_event_time "guint32 gtk_get_current_event_time( void)" return(C_to_Xen_guint32(gtk_get_current_event_time())); } static Xen gxg_gtk_get_current_event_state(Xen ignore_state) { #define H_gtk_get_current_event_state "gboolean gtk_get_current_event_state(GdkModifierType* [state])" GdkModifierType ref_state; { Xen result; result = C_to_Xen_gboolean(gtk_get_current_event_state(&ref_state)); return(Xen_list_2(result, C_to_Xen_GdkModifierType(ref_state))); } } static Xen gxg_gtk_get_event_widget(Xen event) { #define H_gtk_get_event_widget "GtkWidget* gtk_get_event_widget(GdkEvent* event)" Xen_check_type(Xen_is_GdkEvent_(event) || Xen_is_false(event), event, 1, "gtk_get_event_widget", "GdkEvent*"); return(C_to_Xen_GtkWidget_(gtk_get_event_widget(Xen_to_C_GdkEvent_(event)))); } static Xen gxg_gtk_propagate_event(Xen widget, Xen event) { #define H_gtk_propagate_event "void gtk_propagate_event(GtkWidget* widget, GdkEvent* event)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_propagate_event", "GtkWidget*"); Xen_check_type(Xen_is_GdkEvent_(event), event, 2, "gtk_propagate_event", "GdkEvent*"); gtk_propagate_event(Xen_to_C_GtkWidget_(widget), Xen_to_C_GdkEvent_(event)); return(Xen_false); } static Xen gxg_gtk_menu_bar_new(void) { #define H_gtk_menu_bar_new "GtkWidget* gtk_menu_bar_new( void)" return(C_to_Xen_GtkWidget_(gtk_menu_bar_new())); } static Xen gxg_gtk_menu_new(void) { #define H_gtk_menu_new "GtkWidget* gtk_menu_new( void)" return(C_to_Xen_GtkWidget_(gtk_menu_new())); } static Xen gxg_gtk_menu_popup(Xen menu, Xen parent_menu_shell, Xen parent_menu_item, Xen func, Xen func_info, Xen button, Xen activate_time) { #define H_gtk_menu_popup "void gtk_menu_popup(GtkMenu* menu, GtkWidget* parent_menu_shell, GtkWidget* parent_menu_item, \ GtkMenuPositionFunc func, lambda_data func_info, guint button, guint32 activate_time)" Xen_check_type(Xen_is_GtkMenu_(menu), menu, 1, "gtk_menu_popup", "GtkMenu*"); Xen_check_type(Xen_is_GtkWidget_(parent_menu_shell) || Xen_is_false(parent_menu_shell), parent_menu_shell, 2, "gtk_menu_popup", "GtkWidget*"); Xen_check_type(Xen_is_GtkWidget_(parent_menu_item) || Xen_is_false(parent_menu_item), parent_menu_item, 3, "gtk_menu_popup", "GtkWidget*"); Xen_check_type(Xen_is_GtkMenuPositionFunc(func), func, 4, "gtk_menu_popup", "GtkMenuPositionFunc"); Xen_check_type(Xen_is_lambda_data(func_info), func_info, 5, "gtk_menu_popup", "lambda_data"); Xen_check_type(Xen_is_guint(button), button, 6, "gtk_menu_popup", "guint"); Xen_check_type(Xen_is_guint32(activate_time), activate_time, 7, "gtk_menu_popup", "guint32"); { Xen gxg_ptr = Xen_list_5(func, func_info, Xen_false, Xen_false, Xen_false); xm_protect(gxg_ptr); gtk_menu_popup(Xen_to_C_GtkMenu_(menu), Xen_to_C_GtkWidget_(parent_menu_shell), Xen_to_C_GtkWidget_(parent_menu_item), Xen_to_C_GtkMenuPositionFunc(func), Xen_to_C_lambda_data(func_info), Xen_to_C_guint(button), Xen_to_C_guint32(activate_time)); return(Xen_false); } } static Xen gxg_gtk_menu_reposition(Xen menu) { #define H_gtk_menu_reposition "void gtk_menu_reposition(GtkMenu* menu)" Xen_check_type(Xen_is_GtkMenu_(menu), menu, 1, "gtk_menu_reposition", "GtkMenu*"); gtk_menu_reposition(Xen_to_C_GtkMenu_(menu)); return(Xen_false); } static Xen gxg_gtk_menu_popdown(Xen menu) { #define H_gtk_menu_popdown "void gtk_menu_popdown(GtkMenu* menu)" Xen_check_type(Xen_is_GtkMenu_(menu), menu, 1, "gtk_menu_popdown", "GtkMenu*"); gtk_menu_popdown(Xen_to_C_GtkMenu_(menu)); return(Xen_false); } static Xen gxg_gtk_menu_get_active(Xen menu) { #define H_gtk_menu_get_active "GtkWidget* gtk_menu_get_active(GtkMenu* menu)" Xen_check_type(Xen_is_GtkMenu_(menu), menu, 1, "gtk_menu_get_active", "GtkMenu*"); return(C_to_Xen_GtkWidget_(gtk_menu_get_active(Xen_to_C_GtkMenu_(menu)))); } static Xen gxg_gtk_menu_set_active(Xen menu, Xen index) { #define H_gtk_menu_set_active "void gtk_menu_set_active(GtkMenu* menu, guint index)" Xen_check_type(Xen_is_GtkMenu_(menu), menu, 1, "gtk_menu_set_active", "GtkMenu*"); Xen_check_type(Xen_is_guint(index), index, 2, "gtk_menu_set_active", "guint"); gtk_menu_set_active(Xen_to_C_GtkMenu_(menu), Xen_to_C_guint(index)); return(Xen_false); } static Xen gxg_gtk_menu_set_accel_group(Xen menu, Xen accel_group) { #define H_gtk_menu_set_accel_group "void gtk_menu_set_accel_group(GtkMenu* menu, GtkAccelGroup* accel_group)" Xen_check_type(Xen_is_GtkMenu_(menu), menu, 1, "gtk_menu_set_accel_group", "GtkMenu*"); Xen_check_type(Xen_is_GtkAccelGroup_(accel_group) || Xen_is_false(accel_group), accel_group, 2, "gtk_menu_set_accel_group", "GtkAccelGroup*"); gtk_menu_set_accel_group(Xen_to_C_GtkMenu_(menu), Xen_to_C_GtkAccelGroup_(accel_group)); return(Xen_false); } static Xen gxg_gtk_menu_get_accel_group(Xen menu) { #define H_gtk_menu_get_accel_group "GtkAccelGroup* gtk_menu_get_accel_group(GtkMenu* menu)" Xen_check_type(Xen_is_GtkMenu_(menu), menu, 1, "gtk_menu_get_accel_group", "GtkMenu*"); return(C_to_Xen_GtkAccelGroup_(gtk_menu_get_accel_group(Xen_to_C_GtkMenu_(menu)))); } static Xen gxg_gtk_menu_set_accel_path(Xen menu, Xen accel_path) { #define H_gtk_menu_set_accel_path "void gtk_menu_set_accel_path(GtkMenu* menu, gchar* accel_path)" Xen_check_type(Xen_is_GtkMenu_(menu), menu, 1, "gtk_menu_set_accel_path", "GtkMenu*"); Xen_check_type(Xen_is_gchar_(accel_path), accel_path, 2, "gtk_menu_set_accel_path", "gchar*"); gtk_menu_set_accel_path(Xen_to_C_GtkMenu_(menu), Xen_to_C_gchar_(accel_path)); return(Xen_false); } static Xen gxg_gtk_menu_detach(Xen menu) { #define H_gtk_menu_detach "void gtk_menu_detach(GtkMenu* menu)" Xen_check_type(Xen_is_GtkMenu_(menu), menu, 1, "gtk_menu_detach", "GtkMenu*"); gtk_menu_detach(Xen_to_C_GtkMenu_(menu)); return(Xen_false); } static Xen gxg_gtk_menu_get_attach_widget(Xen menu) { #define H_gtk_menu_get_attach_widget "GtkWidget* gtk_menu_get_attach_widget(GtkMenu* menu)" Xen_check_type(Xen_is_GtkMenu_(menu), menu, 1, "gtk_menu_get_attach_widget", "GtkMenu*"); return(C_to_Xen_GtkWidget_(gtk_menu_get_attach_widget(Xen_to_C_GtkMenu_(menu)))); } static Xen gxg_gtk_menu_reorder_child(Xen menu, Xen child, Xen position) { #define H_gtk_menu_reorder_child "void gtk_menu_reorder_child(GtkMenu* menu, GtkWidget* child, gint position)" Xen_check_type(Xen_is_GtkMenu_(menu), menu, 1, "gtk_menu_reorder_child", "GtkMenu*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_menu_reorder_child", "GtkWidget*"); Xen_check_type(Xen_is_gint(position), position, 3, "gtk_menu_reorder_child", "gint"); gtk_menu_reorder_child(Xen_to_C_GtkMenu_(menu), Xen_to_C_GtkWidget_(child), Xen_to_C_gint(position)); return(Xen_false); } static Xen gxg_gtk_menu_set_monitor(Xen menu, Xen monitor_num) { #define H_gtk_menu_set_monitor "void gtk_menu_set_monitor(GtkMenu* menu, gint monitor_num)" Xen_check_type(Xen_is_GtkMenu_(menu), menu, 1, "gtk_menu_set_monitor", "GtkMenu*"); Xen_check_type(Xen_is_gint(monitor_num), monitor_num, 2, "gtk_menu_set_monitor", "gint"); gtk_menu_set_monitor(Xen_to_C_GtkMenu_(menu), Xen_to_C_gint(monitor_num)); return(Xen_false); } static Xen gxg_gtk_menu_item_new(void) { #define H_gtk_menu_item_new "GtkWidget* gtk_menu_item_new( void)" return(C_to_Xen_GtkWidget_(gtk_menu_item_new())); } static Xen gxg_gtk_menu_item_new_with_label(Xen label) { #define H_gtk_menu_item_new_with_label "GtkWidget* gtk_menu_item_new_with_label(gchar* label)" Xen_check_type(Xen_is_gchar_(label), label, 1, "gtk_menu_item_new_with_label", "gchar*"); return(C_to_Xen_GtkWidget_(gtk_menu_item_new_with_label(Xen_to_C_gchar_(label)))); } static Xen gxg_gtk_menu_item_new_with_mnemonic(Xen label) { #define H_gtk_menu_item_new_with_mnemonic "GtkWidget* gtk_menu_item_new_with_mnemonic(gchar* label)" Xen_check_type(Xen_is_gchar_(label), label, 1, "gtk_menu_item_new_with_mnemonic", "gchar*"); return(C_to_Xen_GtkWidget_(gtk_menu_item_new_with_mnemonic(Xen_to_C_gchar_(label)))); } static Xen gxg_gtk_menu_item_set_submenu(Xen menu_item, Xen submenu) { #define H_gtk_menu_item_set_submenu "void gtk_menu_item_set_submenu(GtkMenuItem* menu_item, GtkWidget* submenu)" Xen_check_type(Xen_is_GtkMenuItem_(menu_item), menu_item, 1, "gtk_menu_item_set_submenu", "GtkMenuItem*"); Xen_check_type(Xen_is_GtkWidget_(submenu), submenu, 2, "gtk_menu_item_set_submenu", "GtkWidget*"); gtk_menu_item_set_submenu(Xen_to_C_GtkMenuItem_(menu_item), Xen_to_C_GtkWidget_(submenu)); return(Xen_false); } static Xen gxg_gtk_menu_item_get_submenu(Xen menu_item) { #define H_gtk_menu_item_get_submenu "GtkWidget* gtk_menu_item_get_submenu(GtkMenuItem* menu_item)" Xen_check_type(Xen_is_GtkMenuItem_(menu_item), menu_item, 1, "gtk_menu_item_get_submenu", "GtkMenuItem*"); return(C_to_Xen_GtkWidget_(gtk_menu_item_get_submenu(Xen_to_C_GtkMenuItem_(menu_item)))); } static Xen gxg_gtk_menu_item_select(Xen menu_item) { #define H_gtk_menu_item_select "void gtk_menu_item_select(GtkMenuItem* menu_item)" Xen_check_type(Xen_is_GtkMenuItem_(menu_item), menu_item, 1, "gtk_menu_item_select", "GtkMenuItem*"); gtk_menu_item_select(Xen_to_C_GtkMenuItem_(menu_item)); return(Xen_false); } static Xen gxg_gtk_menu_item_deselect(Xen menu_item) { #define H_gtk_menu_item_deselect "void gtk_menu_item_deselect(GtkMenuItem* menu_item)" Xen_check_type(Xen_is_GtkMenuItem_(menu_item), menu_item, 1, "gtk_menu_item_deselect", "GtkMenuItem*"); gtk_menu_item_deselect(Xen_to_C_GtkMenuItem_(menu_item)); return(Xen_false); } static Xen gxg_gtk_menu_item_activate(Xen menu_item) { #define H_gtk_menu_item_activate "void gtk_menu_item_activate(GtkMenuItem* menu_item)" Xen_check_type(Xen_is_GtkMenuItem_(menu_item), menu_item, 1, "gtk_menu_item_activate", "GtkMenuItem*"); gtk_menu_item_activate(Xen_to_C_GtkMenuItem_(menu_item)); return(Xen_false); } static Xen gxg_gtk_menu_item_toggle_size_request(Xen menu_item, Xen requisition) { #define H_gtk_menu_item_toggle_size_request "void gtk_menu_item_toggle_size_request(GtkMenuItem* menu_item, \ gint* requisition)" Xen_check_type(Xen_is_GtkMenuItem_(menu_item), menu_item, 1, "gtk_menu_item_toggle_size_request", "GtkMenuItem*"); Xen_check_type(Xen_is_gint_(requisition), requisition, 2, "gtk_menu_item_toggle_size_request", "gint*"); gtk_menu_item_toggle_size_request(Xen_to_C_GtkMenuItem_(menu_item), Xen_to_C_gint_(requisition)); return(Xen_false); } static Xen gxg_gtk_menu_item_toggle_size_allocate(Xen menu_item, Xen allocation) { #define H_gtk_menu_item_toggle_size_allocate "void gtk_menu_item_toggle_size_allocate(GtkMenuItem* menu_item, \ gint allocation)" Xen_check_type(Xen_is_GtkMenuItem_(menu_item), menu_item, 1, "gtk_menu_item_toggle_size_allocate", "GtkMenuItem*"); Xen_check_type(Xen_is_gint(allocation), allocation, 2, "gtk_menu_item_toggle_size_allocate", "gint"); gtk_menu_item_toggle_size_allocate(Xen_to_C_GtkMenuItem_(menu_item), Xen_to_C_gint(allocation)); return(Xen_false); } static Xen gxg_gtk_menu_item_set_accel_path(Xen menu_item, Xen accel_path) { #define H_gtk_menu_item_set_accel_path "void gtk_menu_item_set_accel_path(GtkMenuItem* menu_item, gchar* accel_path)" Xen_check_type(Xen_is_GtkMenuItem_(menu_item), menu_item, 1, "gtk_menu_item_set_accel_path", "GtkMenuItem*"); Xen_check_type(Xen_is_gchar_(accel_path), accel_path, 2, "gtk_menu_item_set_accel_path", "gchar*"); gtk_menu_item_set_accel_path(Xen_to_C_GtkMenuItem_(menu_item), Xen_to_C_gchar_(accel_path)); return(Xen_false); } static Xen gxg_gtk_menu_shell_append(Xen menu_shell, Xen child) { #define H_gtk_menu_shell_append "void gtk_menu_shell_append(GtkMenuShell* menu_shell, GtkWidget* child)" Xen_check_type(Xen_is_GtkMenuShell_(menu_shell), menu_shell, 1, "gtk_menu_shell_append", "GtkMenuShell*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_menu_shell_append", "GtkWidget*"); gtk_menu_shell_append(Xen_to_C_GtkMenuShell_(menu_shell), Xen_to_C_GtkWidget_(child)); return(Xen_false); } static Xen gxg_gtk_menu_shell_prepend(Xen menu_shell, Xen child) { #define H_gtk_menu_shell_prepend "void gtk_menu_shell_prepend(GtkMenuShell* menu_shell, GtkWidget* child)" Xen_check_type(Xen_is_GtkMenuShell_(menu_shell), menu_shell, 1, "gtk_menu_shell_prepend", "GtkMenuShell*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_menu_shell_prepend", "GtkWidget*"); gtk_menu_shell_prepend(Xen_to_C_GtkMenuShell_(menu_shell), Xen_to_C_GtkWidget_(child)); return(Xen_false); } static Xen gxg_gtk_menu_shell_insert(Xen menu_shell, Xen child, Xen position) { #define H_gtk_menu_shell_insert "void gtk_menu_shell_insert(GtkMenuShell* menu_shell, GtkWidget* child, \ gint position)" Xen_check_type(Xen_is_GtkMenuShell_(menu_shell), menu_shell, 1, "gtk_menu_shell_insert", "GtkMenuShell*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_menu_shell_insert", "GtkWidget*"); Xen_check_type(Xen_is_gint(position), position, 3, "gtk_menu_shell_insert", "gint"); gtk_menu_shell_insert(Xen_to_C_GtkMenuShell_(menu_shell), Xen_to_C_GtkWidget_(child), Xen_to_C_gint(position)); return(Xen_false); } static Xen gxg_gtk_menu_shell_deactivate(Xen menu_shell) { #define H_gtk_menu_shell_deactivate "void gtk_menu_shell_deactivate(GtkMenuShell* menu_shell)" Xen_check_type(Xen_is_GtkMenuShell_(menu_shell), menu_shell, 1, "gtk_menu_shell_deactivate", "GtkMenuShell*"); gtk_menu_shell_deactivate(Xen_to_C_GtkMenuShell_(menu_shell)); return(Xen_false); } static Xen gxg_gtk_menu_shell_select_item(Xen menu_shell, Xen menu_item) { #define H_gtk_menu_shell_select_item "void gtk_menu_shell_select_item(GtkMenuShell* menu_shell, GtkWidget* menu_item)" Xen_check_type(Xen_is_GtkMenuShell_(menu_shell), menu_shell, 1, "gtk_menu_shell_select_item", "GtkMenuShell*"); Xen_check_type(Xen_is_GtkWidget_(menu_item), menu_item, 2, "gtk_menu_shell_select_item", "GtkWidget*"); gtk_menu_shell_select_item(Xen_to_C_GtkMenuShell_(menu_shell), Xen_to_C_GtkWidget_(menu_item)); return(Xen_false); } static Xen gxg_gtk_menu_shell_deselect(Xen menu_shell) { #define H_gtk_menu_shell_deselect "void gtk_menu_shell_deselect(GtkMenuShell* menu_shell)" Xen_check_type(Xen_is_GtkMenuShell_(menu_shell), menu_shell, 1, "gtk_menu_shell_deselect", "GtkMenuShell*"); gtk_menu_shell_deselect(Xen_to_C_GtkMenuShell_(menu_shell)); return(Xen_false); } static Xen gxg_gtk_menu_shell_activate_item(Xen menu_shell, Xen menu_item, Xen force_deactivate) { #define H_gtk_menu_shell_activate_item "void gtk_menu_shell_activate_item(GtkMenuShell* menu_shell, \ GtkWidget* menu_item, gboolean force_deactivate)" Xen_check_type(Xen_is_GtkMenuShell_(menu_shell), menu_shell, 1, "gtk_menu_shell_activate_item", "GtkMenuShell*"); Xen_check_type(Xen_is_GtkWidget_(menu_item), menu_item, 2, "gtk_menu_shell_activate_item", "GtkWidget*"); Xen_check_type(Xen_is_gboolean(force_deactivate), force_deactivate, 3, "gtk_menu_shell_activate_item", "gboolean"); gtk_menu_shell_activate_item(Xen_to_C_GtkMenuShell_(menu_shell), Xen_to_C_GtkWidget_(menu_item), Xen_to_C_gboolean(force_deactivate)); return(Xen_false); } static Xen gxg_gtk_notebook_new(void) { #define H_gtk_notebook_new "GtkWidget* gtk_notebook_new( void)" return(C_to_Xen_GtkWidget_(gtk_notebook_new())); } static Xen gxg_gtk_notebook_remove_page(Xen notebook, Xen page_num) { #define H_gtk_notebook_remove_page "void gtk_notebook_remove_page(GtkNotebook* notebook, gint page_num)" Xen_check_type(Xen_is_GtkNotebook_(notebook), notebook, 1, "gtk_notebook_remove_page", "GtkNotebook*"); Xen_check_type(Xen_is_gint(page_num), page_num, 2, "gtk_notebook_remove_page", "gint"); gtk_notebook_remove_page(Xen_to_C_GtkNotebook_(notebook), Xen_to_C_gint(page_num)); return(Xen_false); } static Xen gxg_gtk_notebook_get_current_page(Xen notebook) { #define H_gtk_notebook_get_current_page "gint gtk_notebook_get_current_page(GtkNotebook* notebook)" Xen_check_type(Xen_is_GtkNotebook_(notebook), notebook, 1, "gtk_notebook_get_current_page", "GtkNotebook*"); return(C_to_Xen_gint(gtk_notebook_get_current_page(Xen_to_C_GtkNotebook_(notebook)))); } static Xen gxg_gtk_notebook_get_nth_page(Xen notebook, Xen page_num) { #define H_gtk_notebook_get_nth_page "GtkWidget* gtk_notebook_get_nth_page(GtkNotebook* notebook, gint page_num)" Xen_check_type(Xen_is_GtkNotebook_(notebook), notebook, 1, "gtk_notebook_get_nth_page", "GtkNotebook*"); Xen_check_type(Xen_is_gint(page_num), page_num, 2, "gtk_notebook_get_nth_page", "gint"); return(C_to_Xen_GtkWidget_(gtk_notebook_get_nth_page(Xen_to_C_GtkNotebook_(notebook), Xen_to_C_gint(page_num)))); } static Xen gxg_gtk_notebook_page_num(Xen notebook, Xen child) { #define H_gtk_notebook_page_num "gint gtk_notebook_page_num(GtkNotebook* notebook, GtkWidget* child)" Xen_check_type(Xen_is_GtkNotebook_(notebook), notebook, 1, "gtk_notebook_page_num", "GtkNotebook*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_notebook_page_num", "GtkWidget*"); return(C_to_Xen_gint(gtk_notebook_page_num(Xen_to_C_GtkNotebook_(notebook), Xen_to_C_GtkWidget_(child)))); } static Xen gxg_gtk_notebook_set_current_page(Xen notebook, Xen page_num) { #define H_gtk_notebook_set_current_page "void gtk_notebook_set_current_page(GtkNotebook* notebook, \ gint page_num)" Xen_check_type(Xen_is_GtkNotebook_(notebook), notebook, 1, "gtk_notebook_set_current_page", "GtkNotebook*"); Xen_check_type(Xen_is_gint(page_num), page_num, 2, "gtk_notebook_set_current_page", "gint"); gtk_notebook_set_current_page(Xen_to_C_GtkNotebook_(notebook), Xen_to_C_gint(page_num)); return(Xen_false); } static Xen gxg_gtk_notebook_next_page(Xen notebook) { #define H_gtk_notebook_next_page "void gtk_notebook_next_page(GtkNotebook* notebook)" Xen_check_type(Xen_is_GtkNotebook_(notebook), notebook, 1, "gtk_notebook_next_page", "GtkNotebook*"); gtk_notebook_next_page(Xen_to_C_GtkNotebook_(notebook)); return(Xen_false); } static Xen gxg_gtk_notebook_prev_page(Xen notebook) { #define H_gtk_notebook_prev_page "void gtk_notebook_prev_page(GtkNotebook* notebook)" Xen_check_type(Xen_is_GtkNotebook_(notebook), notebook, 1, "gtk_notebook_prev_page", "GtkNotebook*"); gtk_notebook_prev_page(Xen_to_C_GtkNotebook_(notebook)); return(Xen_false); } static Xen gxg_gtk_notebook_set_show_border(Xen notebook, Xen show_border) { #define H_gtk_notebook_set_show_border "void gtk_notebook_set_show_border(GtkNotebook* notebook, gboolean show_border)" Xen_check_type(Xen_is_GtkNotebook_(notebook), notebook, 1, "gtk_notebook_set_show_border", "GtkNotebook*"); Xen_check_type(Xen_is_gboolean(show_border), show_border, 2, "gtk_notebook_set_show_border", "gboolean"); gtk_notebook_set_show_border(Xen_to_C_GtkNotebook_(notebook), Xen_to_C_gboolean(show_border)); return(Xen_false); } static Xen gxg_gtk_notebook_get_show_border(Xen notebook) { #define H_gtk_notebook_get_show_border "gboolean gtk_notebook_get_show_border(GtkNotebook* notebook)" Xen_check_type(Xen_is_GtkNotebook_(notebook), notebook, 1, "gtk_notebook_get_show_border", "GtkNotebook*"); return(C_to_Xen_gboolean(gtk_notebook_get_show_border(Xen_to_C_GtkNotebook_(notebook)))); } static Xen gxg_gtk_notebook_set_show_tabs(Xen notebook, Xen show_tabs) { #define H_gtk_notebook_set_show_tabs "void gtk_notebook_set_show_tabs(GtkNotebook* notebook, gboolean show_tabs)" Xen_check_type(Xen_is_GtkNotebook_(notebook), notebook, 1, "gtk_notebook_set_show_tabs", "GtkNotebook*"); Xen_check_type(Xen_is_gboolean(show_tabs), show_tabs, 2, "gtk_notebook_set_show_tabs", "gboolean"); gtk_notebook_set_show_tabs(Xen_to_C_GtkNotebook_(notebook), Xen_to_C_gboolean(show_tabs)); return(Xen_false); } static Xen gxg_gtk_notebook_get_show_tabs(Xen notebook) { #define H_gtk_notebook_get_show_tabs "gboolean gtk_notebook_get_show_tabs(GtkNotebook* notebook)" Xen_check_type(Xen_is_GtkNotebook_(notebook), notebook, 1, "gtk_notebook_get_show_tabs", "GtkNotebook*"); return(C_to_Xen_gboolean(gtk_notebook_get_show_tabs(Xen_to_C_GtkNotebook_(notebook)))); } static Xen gxg_gtk_notebook_set_tab_pos(Xen notebook, Xen pos) { #define H_gtk_notebook_set_tab_pos "void gtk_notebook_set_tab_pos(GtkNotebook* notebook, GtkPositionType pos)" Xen_check_type(Xen_is_GtkNotebook_(notebook), notebook, 1, "gtk_notebook_set_tab_pos", "GtkNotebook*"); Xen_check_type(Xen_is_GtkPositionType(pos), pos, 2, "gtk_notebook_set_tab_pos", "GtkPositionType"); gtk_notebook_set_tab_pos(Xen_to_C_GtkNotebook_(notebook), Xen_to_C_GtkPositionType(pos)); return(Xen_false); } static Xen gxg_gtk_notebook_get_tab_pos(Xen notebook) { #define H_gtk_notebook_get_tab_pos "GtkPositionType gtk_notebook_get_tab_pos(GtkNotebook* notebook)" Xen_check_type(Xen_is_GtkNotebook_(notebook), notebook, 1, "gtk_notebook_get_tab_pos", "GtkNotebook*"); return(C_to_Xen_GtkPositionType(gtk_notebook_get_tab_pos(Xen_to_C_GtkNotebook_(notebook)))); } static Xen gxg_gtk_notebook_set_scrollable(Xen notebook, Xen scrollable) { #define H_gtk_notebook_set_scrollable "void gtk_notebook_set_scrollable(GtkNotebook* notebook, gboolean scrollable)" Xen_check_type(Xen_is_GtkNotebook_(notebook), notebook, 1, "gtk_notebook_set_scrollable", "GtkNotebook*"); Xen_check_type(Xen_is_gboolean(scrollable), scrollable, 2, "gtk_notebook_set_scrollable", "gboolean"); gtk_notebook_set_scrollable(Xen_to_C_GtkNotebook_(notebook), Xen_to_C_gboolean(scrollable)); return(Xen_false); } static Xen gxg_gtk_notebook_get_scrollable(Xen notebook) { #define H_gtk_notebook_get_scrollable "gboolean gtk_notebook_get_scrollable(GtkNotebook* notebook)" Xen_check_type(Xen_is_GtkNotebook_(notebook), notebook, 1, "gtk_notebook_get_scrollable", "GtkNotebook*"); return(C_to_Xen_gboolean(gtk_notebook_get_scrollable(Xen_to_C_GtkNotebook_(notebook)))); } static Xen gxg_gtk_notebook_popup_enable(Xen notebook) { #define H_gtk_notebook_popup_enable "void gtk_notebook_popup_enable(GtkNotebook* notebook)" Xen_check_type(Xen_is_GtkNotebook_(notebook), notebook, 1, "gtk_notebook_popup_enable", "GtkNotebook*"); gtk_notebook_popup_enable(Xen_to_C_GtkNotebook_(notebook)); return(Xen_false); } static Xen gxg_gtk_notebook_popup_disable(Xen notebook) { #define H_gtk_notebook_popup_disable "void gtk_notebook_popup_disable(GtkNotebook* notebook)" Xen_check_type(Xen_is_GtkNotebook_(notebook), notebook, 1, "gtk_notebook_popup_disable", "GtkNotebook*"); gtk_notebook_popup_disable(Xen_to_C_GtkNotebook_(notebook)); return(Xen_false); } static Xen gxg_gtk_notebook_get_tab_label(Xen notebook, Xen child) { #define H_gtk_notebook_get_tab_label "GtkWidget* gtk_notebook_get_tab_label(GtkNotebook* notebook, \ GtkWidget* child)" Xen_check_type(Xen_is_GtkNotebook_(notebook), notebook, 1, "gtk_notebook_get_tab_label", "GtkNotebook*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_notebook_get_tab_label", "GtkWidget*"); return(C_to_Xen_GtkWidget_(gtk_notebook_get_tab_label(Xen_to_C_GtkNotebook_(notebook), Xen_to_C_GtkWidget_(child)))); } static Xen gxg_gtk_notebook_set_tab_label(Xen notebook, Xen child, Xen tab_label) { #define H_gtk_notebook_set_tab_label "void gtk_notebook_set_tab_label(GtkNotebook* notebook, GtkWidget* child, \ GtkWidget* tab_label)" Xen_check_type(Xen_is_GtkNotebook_(notebook), notebook, 1, "gtk_notebook_set_tab_label", "GtkNotebook*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_notebook_set_tab_label", "GtkWidget*"); Xen_check_type(Xen_is_GtkWidget_(tab_label) || Xen_is_false(tab_label), tab_label, 3, "gtk_notebook_set_tab_label", "GtkWidget*"); gtk_notebook_set_tab_label(Xen_to_C_GtkNotebook_(notebook), Xen_to_C_GtkWidget_(child), Xen_to_C_GtkWidget_(tab_label)); return(Xen_false); } static Xen gxg_gtk_notebook_set_tab_label_text(Xen notebook, Xen child, Xen tab_text) { #define H_gtk_notebook_set_tab_label_text "void gtk_notebook_set_tab_label_text(GtkNotebook* notebook, \ GtkWidget* child, gchar* tab_text)" Xen_check_type(Xen_is_GtkNotebook_(notebook), notebook, 1, "gtk_notebook_set_tab_label_text", "GtkNotebook*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_notebook_set_tab_label_text", "GtkWidget*"); Xen_check_type(Xen_is_gchar_(tab_text), tab_text, 3, "gtk_notebook_set_tab_label_text", "gchar*"); gtk_notebook_set_tab_label_text(Xen_to_C_GtkNotebook_(notebook), Xen_to_C_GtkWidget_(child), Xen_to_C_gchar_(tab_text)); return(Xen_false); } static Xen gxg_gtk_notebook_get_tab_label_text(Xen notebook, Xen child) { #define H_gtk_notebook_get_tab_label_text "gchar* gtk_notebook_get_tab_label_text(GtkNotebook* notebook, \ GtkWidget* child)" Xen_check_type(Xen_is_GtkNotebook_(notebook), notebook, 1, "gtk_notebook_get_tab_label_text", "GtkNotebook*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_notebook_get_tab_label_text", "GtkWidget*"); return(C_to_Xen_gchar_(gtk_notebook_get_tab_label_text(Xen_to_C_GtkNotebook_(notebook), Xen_to_C_GtkWidget_(child)))); } static Xen gxg_gtk_notebook_get_menu_label(Xen notebook, Xen child) { #define H_gtk_notebook_get_menu_label "GtkWidget* gtk_notebook_get_menu_label(GtkNotebook* notebook, \ GtkWidget* child)" Xen_check_type(Xen_is_GtkNotebook_(notebook), notebook, 1, "gtk_notebook_get_menu_label", "GtkNotebook*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_notebook_get_menu_label", "GtkWidget*"); return(C_to_Xen_GtkWidget_(gtk_notebook_get_menu_label(Xen_to_C_GtkNotebook_(notebook), Xen_to_C_GtkWidget_(child)))); } static Xen gxg_gtk_notebook_set_menu_label(Xen notebook, Xen child, Xen menu_label) { #define H_gtk_notebook_set_menu_label "void gtk_notebook_set_menu_label(GtkNotebook* notebook, GtkWidget* child, \ GtkWidget* menu_label)" Xen_check_type(Xen_is_GtkNotebook_(notebook), notebook, 1, "gtk_notebook_set_menu_label", "GtkNotebook*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_notebook_set_menu_label", "GtkWidget*"); Xen_check_type(Xen_is_GtkWidget_(menu_label), menu_label, 3, "gtk_notebook_set_menu_label", "GtkWidget*"); gtk_notebook_set_menu_label(Xen_to_C_GtkNotebook_(notebook), Xen_to_C_GtkWidget_(child), Xen_to_C_GtkWidget_(menu_label)); return(Xen_false); } static Xen gxg_gtk_notebook_set_menu_label_text(Xen notebook, Xen child, Xen menu_text) { #define H_gtk_notebook_set_menu_label_text "void gtk_notebook_set_menu_label_text(GtkNotebook* notebook, \ GtkWidget* child, gchar* menu_text)" Xen_check_type(Xen_is_GtkNotebook_(notebook), notebook, 1, "gtk_notebook_set_menu_label_text", "GtkNotebook*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_notebook_set_menu_label_text", "GtkWidget*"); Xen_check_type(Xen_is_gchar_(menu_text), menu_text, 3, "gtk_notebook_set_menu_label_text", "gchar*"); gtk_notebook_set_menu_label_text(Xen_to_C_GtkNotebook_(notebook), Xen_to_C_GtkWidget_(child), Xen_to_C_gchar_(menu_text)); return(Xen_false); } static Xen gxg_gtk_notebook_get_menu_label_text(Xen notebook, Xen child) { #define H_gtk_notebook_get_menu_label_text "gchar* gtk_notebook_get_menu_label_text(GtkNotebook* notebook, \ GtkWidget* child)" Xen_check_type(Xen_is_GtkNotebook_(notebook), notebook, 1, "gtk_notebook_get_menu_label_text", "GtkNotebook*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_notebook_get_menu_label_text", "GtkWidget*"); return(C_to_Xen_gchar_(gtk_notebook_get_menu_label_text(Xen_to_C_GtkNotebook_(notebook), Xen_to_C_GtkWidget_(child)))); } static Xen gxg_gtk_notebook_reorder_child(Xen notebook, Xen child, Xen position) { #define H_gtk_notebook_reorder_child "void gtk_notebook_reorder_child(GtkNotebook* notebook, GtkWidget* child, \ gint position)" Xen_check_type(Xen_is_GtkNotebook_(notebook), notebook, 1, "gtk_notebook_reorder_child", "GtkNotebook*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_notebook_reorder_child", "GtkWidget*"); Xen_check_type(Xen_is_gint(position), position, 3, "gtk_notebook_reorder_child", "gint"); gtk_notebook_reorder_child(Xen_to_C_GtkNotebook_(notebook), Xen_to_C_GtkWidget_(child), Xen_to_C_gint(position)); return(Xen_false); } static Xen gxg_gtk_notebook_append_page(Xen notebook, Xen child, Xen tab_label) { #define H_gtk_notebook_append_page "gint gtk_notebook_append_page(GtkNotebook* notebook, GtkWidget* child, \ GtkWidget* tab_label)" Xen_check_type(Xen_is_GtkNotebook_(notebook), notebook, 1, "gtk_notebook_append_page", "GtkNotebook*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_notebook_append_page", "GtkWidget*"); Xen_check_type(Xen_is_GtkWidget_(tab_label) || Xen_is_false(tab_label), tab_label, 3, "gtk_notebook_append_page", "GtkWidget*"); return(C_to_Xen_gint(gtk_notebook_append_page(Xen_to_C_GtkNotebook_(notebook), Xen_to_C_GtkWidget_(child), Xen_to_C_GtkWidget_(tab_label)))); } static Xen gxg_gtk_notebook_append_page_menu(Xen notebook, Xen child, Xen tab_label, Xen menu_label) { #define H_gtk_notebook_append_page_menu "gint gtk_notebook_append_page_menu(GtkNotebook* notebook, \ GtkWidget* child, GtkWidget* tab_label, GtkWidget* menu_label)" Xen_check_type(Xen_is_GtkNotebook_(notebook), notebook, 1, "gtk_notebook_append_page_menu", "GtkNotebook*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_notebook_append_page_menu", "GtkWidget*"); Xen_check_type(Xen_is_GtkWidget_(tab_label) || Xen_is_false(tab_label), tab_label, 3, "gtk_notebook_append_page_menu", "GtkWidget*"); Xen_check_type(Xen_is_GtkWidget_(menu_label) || Xen_is_false(menu_label), menu_label, 4, "gtk_notebook_append_page_menu", "GtkWidget*"); return(C_to_Xen_gint(gtk_notebook_append_page_menu(Xen_to_C_GtkNotebook_(notebook), Xen_to_C_GtkWidget_(child), Xen_to_C_GtkWidget_(tab_label), Xen_to_C_GtkWidget_(menu_label)))); } static Xen gxg_gtk_notebook_prepend_page(Xen notebook, Xen child, Xen tab_label) { #define H_gtk_notebook_prepend_page "gint gtk_notebook_prepend_page(GtkNotebook* notebook, GtkWidget* child, \ GtkWidget* tab_label)" Xen_check_type(Xen_is_GtkNotebook_(notebook), notebook, 1, "gtk_notebook_prepend_page", "GtkNotebook*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_notebook_prepend_page", "GtkWidget*"); Xen_check_type(Xen_is_GtkWidget_(tab_label) || Xen_is_false(tab_label), tab_label, 3, "gtk_notebook_prepend_page", "GtkWidget*"); return(C_to_Xen_gint(gtk_notebook_prepend_page(Xen_to_C_GtkNotebook_(notebook), Xen_to_C_GtkWidget_(child), Xen_to_C_GtkWidget_(tab_label)))); } static Xen gxg_gtk_notebook_prepend_page_menu(Xen notebook, Xen child, Xen tab_label, Xen menu_label) { #define H_gtk_notebook_prepend_page_menu "gint gtk_notebook_prepend_page_menu(GtkNotebook* notebook, \ GtkWidget* child, GtkWidget* tab_label, GtkWidget* menu_label)" Xen_check_type(Xen_is_GtkNotebook_(notebook), notebook, 1, "gtk_notebook_prepend_page_menu", "GtkNotebook*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_notebook_prepend_page_menu", "GtkWidget*"); Xen_check_type(Xen_is_GtkWidget_(tab_label) || Xen_is_false(tab_label), tab_label, 3, "gtk_notebook_prepend_page_menu", "GtkWidget*"); Xen_check_type(Xen_is_GtkWidget_(menu_label) || Xen_is_false(menu_label), menu_label, 4, "gtk_notebook_prepend_page_menu", "GtkWidget*"); return(C_to_Xen_gint(gtk_notebook_prepend_page_menu(Xen_to_C_GtkNotebook_(notebook), Xen_to_C_GtkWidget_(child), Xen_to_C_GtkWidget_(tab_label), Xen_to_C_GtkWidget_(menu_label)))); } static Xen gxg_gtk_notebook_insert_page(Xen notebook, Xen child, Xen tab_label, Xen position) { #define H_gtk_notebook_insert_page "gint gtk_notebook_insert_page(GtkNotebook* notebook, GtkWidget* child, \ GtkWidget* tab_label, gint position)" Xen_check_type(Xen_is_GtkNotebook_(notebook), notebook, 1, "gtk_notebook_insert_page", "GtkNotebook*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_notebook_insert_page", "GtkWidget*"); Xen_check_type(Xen_is_GtkWidget_(tab_label) || Xen_is_false(tab_label), tab_label, 3, "gtk_notebook_insert_page", "GtkWidget*"); Xen_check_type(Xen_is_gint(position), position, 4, "gtk_notebook_insert_page", "gint"); return(C_to_Xen_gint(gtk_notebook_insert_page(Xen_to_C_GtkNotebook_(notebook), Xen_to_C_GtkWidget_(child), Xen_to_C_GtkWidget_(tab_label), Xen_to_C_gint(position)))); } static Xen gxg_gtk_notebook_insert_page_menu(Xen notebook, Xen child, Xen tab_label, Xen menu_label, Xen position) { #define H_gtk_notebook_insert_page_menu "gint gtk_notebook_insert_page_menu(GtkNotebook* notebook, \ GtkWidget* child, GtkWidget* tab_label, GtkWidget* menu_label, gint position)" Xen_check_type(Xen_is_GtkNotebook_(notebook), notebook, 1, "gtk_notebook_insert_page_menu", "GtkNotebook*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_notebook_insert_page_menu", "GtkWidget*"); Xen_check_type(Xen_is_GtkWidget_(tab_label) || Xen_is_false(tab_label), tab_label, 3, "gtk_notebook_insert_page_menu", "GtkWidget*"); Xen_check_type(Xen_is_GtkWidget_(menu_label) || Xen_is_false(menu_label), menu_label, 4, "gtk_notebook_insert_page_menu", "GtkWidget*"); Xen_check_type(Xen_is_gint(position), position, 5, "gtk_notebook_insert_page_menu", "gint"); return(C_to_Xen_gint(gtk_notebook_insert_page_menu(Xen_to_C_GtkNotebook_(notebook), Xen_to_C_GtkWidget_(child), Xen_to_C_GtkWidget_(tab_label), Xen_to_C_GtkWidget_(menu_label), Xen_to_C_gint(position)))); } static Xen gxg_gtk_paned_add1(Xen paned, Xen child) { #define H_gtk_paned_add1 "void gtk_paned_add1(GtkPaned* paned, GtkWidget* child)" Xen_check_type(Xen_is_GtkPaned_(paned), paned, 1, "gtk_paned_add1", "GtkPaned*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_paned_add1", "GtkWidget*"); gtk_paned_add1(Xen_to_C_GtkPaned_(paned), Xen_to_C_GtkWidget_(child)); return(Xen_false); } static Xen gxg_gtk_paned_add2(Xen paned, Xen child) { #define H_gtk_paned_add2 "void gtk_paned_add2(GtkPaned* paned, GtkWidget* child)" Xen_check_type(Xen_is_GtkPaned_(paned), paned, 1, "gtk_paned_add2", "GtkPaned*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_paned_add2", "GtkWidget*"); gtk_paned_add2(Xen_to_C_GtkPaned_(paned), Xen_to_C_GtkWidget_(child)); return(Xen_false); } static Xen gxg_gtk_paned_pack1(Xen paned, Xen child, Xen resize, Xen shrink) { #define H_gtk_paned_pack1 "void gtk_paned_pack1(GtkPaned* paned, GtkWidget* child, gboolean resize, \ gboolean shrink)" Xen_check_type(Xen_is_GtkPaned_(paned), paned, 1, "gtk_paned_pack1", "GtkPaned*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_paned_pack1", "GtkWidget*"); Xen_check_type(Xen_is_gboolean(resize), resize, 3, "gtk_paned_pack1", "gboolean"); Xen_check_type(Xen_is_gboolean(shrink), shrink, 4, "gtk_paned_pack1", "gboolean"); gtk_paned_pack1(Xen_to_C_GtkPaned_(paned), Xen_to_C_GtkWidget_(child), Xen_to_C_gboolean(resize), Xen_to_C_gboolean(shrink)); return(Xen_false); } static Xen gxg_gtk_paned_pack2(Xen paned, Xen child, Xen resize, Xen shrink) { #define H_gtk_paned_pack2 "void gtk_paned_pack2(GtkPaned* paned, GtkWidget* child, gboolean resize, \ gboolean shrink)" Xen_check_type(Xen_is_GtkPaned_(paned), paned, 1, "gtk_paned_pack2", "GtkPaned*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_paned_pack2", "GtkWidget*"); Xen_check_type(Xen_is_gboolean(resize), resize, 3, "gtk_paned_pack2", "gboolean"); Xen_check_type(Xen_is_gboolean(shrink), shrink, 4, "gtk_paned_pack2", "gboolean"); gtk_paned_pack2(Xen_to_C_GtkPaned_(paned), Xen_to_C_GtkWidget_(child), Xen_to_C_gboolean(resize), Xen_to_C_gboolean(shrink)); return(Xen_false); } static Xen gxg_gtk_paned_get_position(Xen paned) { #define H_gtk_paned_get_position "gint gtk_paned_get_position(GtkPaned* paned)" Xen_check_type(Xen_is_GtkPaned_(paned), paned, 1, "gtk_paned_get_position", "GtkPaned*"); return(C_to_Xen_gint(gtk_paned_get_position(Xen_to_C_GtkPaned_(paned)))); } static Xen gxg_gtk_paned_set_position(Xen paned, Xen position) { #define H_gtk_paned_set_position "void gtk_paned_set_position(GtkPaned* paned, gint position)" Xen_check_type(Xen_is_GtkPaned_(paned), paned, 1, "gtk_paned_set_position", "GtkPaned*"); Xen_check_type(Xen_is_gint(position), position, 2, "gtk_paned_set_position", "gint"); gtk_paned_set_position(Xen_to_C_GtkPaned_(paned), Xen_to_C_gint(position)); return(Xen_false); } static Xen gxg_gtk_progress_bar_new(void) { #define H_gtk_progress_bar_new "GtkWidget* gtk_progress_bar_new( void)" return(C_to_Xen_GtkWidget_(gtk_progress_bar_new())); } static Xen gxg_gtk_progress_bar_pulse(Xen pbar) { #define H_gtk_progress_bar_pulse "void gtk_progress_bar_pulse(GtkProgressBar* pbar)" Xen_check_type(Xen_is_GtkProgressBar_(pbar), pbar, 1, "gtk_progress_bar_pulse", "GtkProgressBar*"); gtk_progress_bar_pulse(Xen_to_C_GtkProgressBar_(pbar)); return(Xen_false); } static Xen gxg_gtk_progress_bar_set_text(Xen pbar, Xen text) { #define H_gtk_progress_bar_set_text "void gtk_progress_bar_set_text(GtkProgressBar* pbar, gchar* text)" Xen_check_type(Xen_is_GtkProgressBar_(pbar), pbar, 1, "gtk_progress_bar_set_text", "GtkProgressBar*"); Xen_check_type(Xen_is_gchar_(text), text, 2, "gtk_progress_bar_set_text", "gchar*"); gtk_progress_bar_set_text(Xen_to_C_GtkProgressBar_(pbar), Xen_to_C_gchar_(text)); return(Xen_false); } static Xen gxg_gtk_progress_bar_set_fraction(Xen pbar, Xen fraction) { #define H_gtk_progress_bar_set_fraction "void gtk_progress_bar_set_fraction(GtkProgressBar* pbar, gdouble fraction)" Xen_check_type(Xen_is_GtkProgressBar_(pbar), pbar, 1, "gtk_progress_bar_set_fraction", "GtkProgressBar*"); Xen_check_type(Xen_is_gdouble(fraction), fraction, 2, "gtk_progress_bar_set_fraction", "gdouble"); gtk_progress_bar_set_fraction(Xen_to_C_GtkProgressBar_(pbar), Xen_to_C_gdouble(fraction)); return(Xen_false); } static Xen gxg_gtk_progress_bar_set_pulse_step(Xen pbar, Xen fraction) { #define H_gtk_progress_bar_set_pulse_step "void gtk_progress_bar_set_pulse_step(GtkProgressBar* pbar, \ gdouble fraction)" Xen_check_type(Xen_is_GtkProgressBar_(pbar), pbar, 1, "gtk_progress_bar_set_pulse_step", "GtkProgressBar*"); Xen_check_type(Xen_is_gdouble(fraction), fraction, 2, "gtk_progress_bar_set_pulse_step", "gdouble"); gtk_progress_bar_set_pulse_step(Xen_to_C_GtkProgressBar_(pbar), Xen_to_C_gdouble(fraction)); return(Xen_false); } static Xen gxg_gtk_progress_bar_get_text(Xen pbar) { #define H_gtk_progress_bar_get_text "gchar* gtk_progress_bar_get_text(GtkProgressBar* pbar)" Xen_check_type(Xen_is_GtkProgressBar_(pbar), pbar, 1, "gtk_progress_bar_get_text", "GtkProgressBar*"); return(C_to_Xen_gchar_(gtk_progress_bar_get_text(Xen_to_C_GtkProgressBar_(pbar)))); } static Xen gxg_gtk_progress_bar_get_fraction(Xen pbar) { #define H_gtk_progress_bar_get_fraction "gdouble gtk_progress_bar_get_fraction(GtkProgressBar* pbar)" Xen_check_type(Xen_is_GtkProgressBar_(pbar), pbar, 1, "gtk_progress_bar_get_fraction", "GtkProgressBar*"); return(C_to_Xen_gdouble(gtk_progress_bar_get_fraction(Xen_to_C_GtkProgressBar_(pbar)))); } static Xen gxg_gtk_progress_bar_get_pulse_step(Xen pbar) { #define H_gtk_progress_bar_get_pulse_step "gdouble gtk_progress_bar_get_pulse_step(GtkProgressBar* pbar)" Xen_check_type(Xen_is_GtkProgressBar_(pbar), pbar, 1, "gtk_progress_bar_get_pulse_step", "GtkProgressBar*"); return(C_to_Xen_gdouble(gtk_progress_bar_get_pulse_step(Xen_to_C_GtkProgressBar_(pbar)))); } static Xen gxg_gtk_radio_button_new(Xen group) { #define H_gtk_radio_button_new "GtkWidget* gtk_radio_button_new(GSList* group)" Xen_check_type(Xen_is_GSList_(group) || Xen_is_false(group), group, 1, "gtk_radio_button_new", "GSList*"); return(C_to_Xen_GtkWidget_(gtk_radio_button_new(Xen_to_C_GSList_(group)))); } static Xen gxg_gtk_radio_button_new_from_widget(Xen group) { #define H_gtk_radio_button_new_from_widget "GtkWidget* gtk_radio_button_new_from_widget(GtkRadioButton* group)" Xen_check_type(Xen_is_GtkRadioButton_(group), group, 1, "gtk_radio_button_new_from_widget", "GtkRadioButton*"); return(C_to_Xen_GtkWidget_(gtk_radio_button_new_from_widget(Xen_to_C_GtkRadioButton_(group)))); } static Xen gxg_gtk_radio_button_new_with_label(Xen group, Xen label) { #define H_gtk_radio_button_new_with_label "GtkWidget* gtk_radio_button_new_with_label(GSList* group, \ gchar* label)" Xen_check_type(Xen_is_GSList_(group) || Xen_is_false(group), group, 1, "gtk_radio_button_new_with_label", "GSList*"); Xen_check_type(Xen_is_gchar_(label), label, 2, "gtk_radio_button_new_with_label", "gchar*"); return(C_to_Xen_GtkWidget_(gtk_radio_button_new_with_label(Xen_to_C_GSList_(group), Xen_to_C_gchar_(label)))); } static Xen gxg_gtk_radio_button_new_with_label_from_widget(Xen group, Xen label) { #define H_gtk_radio_button_new_with_label_from_widget "GtkWidget* gtk_radio_button_new_with_label_from_widget(GtkRadioButton* group, \ gchar* label)" Xen_check_type(Xen_is_GtkRadioButton_(group), group, 1, "gtk_radio_button_new_with_label_from_widget", "GtkRadioButton*"); Xen_check_type(Xen_is_gchar_(label), label, 2, "gtk_radio_button_new_with_label_from_widget", "gchar*"); return(C_to_Xen_GtkWidget_(gtk_radio_button_new_with_label_from_widget(Xen_to_C_GtkRadioButton_(group), Xen_to_C_gchar_(label)))); } static Xen gxg_gtk_radio_button_new_with_mnemonic(Xen group, Xen label) { #define H_gtk_radio_button_new_with_mnemonic "GtkWidget* gtk_radio_button_new_with_mnemonic(GSList* group, \ gchar* label)" Xen_check_type(Xen_is_GSList_(group) || Xen_is_false(group), group, 1, "gtk_radio_button_new_with_mnemonic", "GSList*"); Xen_check_type(Xen_is_gchar_(label), label, 2, "gtk_radio_button_new_with_mnemonic", "gchar*"); return(C_to_Xen_GtkWidget_(gtk_radio_button_new_with_mnemonic(Xen_to_C_GSList_(group), Xen_to_C_gchar_(label)))); } static Xen gxg_gtk_radio_button_new_with_mnemonic_from_widget(Xen group, Xen label) { #define H_gtk_radio_button_new_with_mnemonic_from_widget "GtkWidget* gtk_radio_button_new_with_mnemonic_from_widget(GtkRadioButton* group, \ gchar* label)" Xen_check_type(Xen_is_GtkRadioButton_(group), group, 1, "gtk_radio_button_new_with_mnemonic_from_widget", "GtkRadioButton*"); Xen_check_type(Xen_is_gchar_(label), label, 2, "gtk_radio_button_new_with_mnemonic_from_widget", "gchar*"); return(C_to_Xen_GtkWidget_(gtk_radio_button_new_with_mnemonic_from_widget(Xen_to_C_GtkRadioButton_(group), Xen_to_C_gchar_(label)))); } static Xen gxg_gtk_radio_button_get_group(Xen radio_button) { #define H_gtk_radio_button_get_group "GSList* gtk_radio_button_get_group(GtkRadioButton* radio_button)" Xen_check_type(Xen_is_GtkRadioButton_(radio_button), radio_button, 1, "gtk_radio_button_get_group", "GtkRadioButton*"); return(C_to_Xen_GSList_(gtk_radio_button_get_group(Xen_to_C_GtkRadioButton_(radio_button)))); } static Xen gxg_gtk_radio_button_set_group(Xen radio_button, Xen group) { #define H_gtk_radio_button_set_group "void gtk_radio_button_set_group(GtkRadioButton* radio_button, \ GSList* group)" Xen_check_type(Xen_is_GtkRadioButton_(radio_button), radio_button, 1, "gtk_radio_button_set_group", "GtkRadioButton*"); Xen_check_type(Xen_is_GSList_(group) || Xen_is_false(group), group, 2, "gtk_radio_button_set_group", "GSList*"); gtk_radio_button_set_group(Xen_to_C_GtkRadioButton_(radio_button), Xen_to_C_GSList_(group)); return(Xen_false); } static Xen gxg_gtk_radio_menu_item_new(Xen group) { #define H_gtk_radio_menu_item_new "GtkWidget* gtk_radio_menu_item_new(GSList* group)" Xen_check_type(Xen_is_GSList_(group) || Xen_is_false(group), group, 1, "gtk_radio_menu_item_new", "GSList*"); return(C_to_Xen_GtkWidget_(gtk_radio_menu_item_new(Xen_to_C_GSList_(group)))); } static Xen gxg_gtk_radio_menu_item_new_with_label(Xen group, Xen label) { #define H_gtk_radio_menu_item_new_with_label "GtkWidget* gtk_radio_menu_item_new_with_label(GSList* group, \ gchar* label)" Xen_check_type(Xen_is_GSList_(group) || Xen_is_false(group), group, 1, "gtk_radio_menu_item_new_with_label", "GSList*"); Xen_check_type(Xen_is_gchar_(label), label, 2, "gtk_radio_menu_item_new_with_label", "gchar*"); return(C_to_Xen_GtkWidget_(gtk_radio_menu_item_new_with_label(Xen_to_C_GSList_(group), Xen_to_C_gchar_(label)))); } static Xen gxg_gtk_radio_menu_item_new_with_mnemonic(Xen group, Xen label) { #define H_gtk_radio_menu_item_new_with_mnemonic "GtkWidget* gtk_radio_menu_item_new_with_mnemonic(GSList* group, \ gchar* label)" Xen_check_type(Xen_is_GSList_(group) || Xen_is_false(group), group, 1, "gtk_radio_menu_item_new_with_mnemonic", "GSList*"); Xen_check_type(Xen_is_gchar_(label), label, 2, "gtk_radio_menu_item_new_with_mnemonic", "gchar*"); return(C_to_Xen_GtkWidget_(gtk_radio_menu_item_new_with_mnemonic(Xen_to_C_GSList_(group), Xen_to_C_gchar_(label)))); } static Xen gxg_gtk_radio_menu_item_get_group(Xen radio_menu_item) { #define H_gtk_radio_menu_item_get_group "GSList* gtk_radio_menu_item_get_group(GtkRadioMenuItem* radio_menu_item)" Xen_check_type(Xen_is_GtkRadioMenuItem_(radio_menu_item), radio_menu_item, 1, "gtk_radio_menu_item_get_group", "GtkRadioMenuItem*"); return(C_to_Xen_GSList_(gtk_radio_menu_item_get_group(Xen_to_C_GtkRadioMenuItem_(radio_menu_item)))); } static Xen gxg_gtk_radio_menu_item_set_group(Xen radio_menu_item, Xen group) { #define H_gtk_radio_menu_item_set_group "void gtk_radio_menu_item_set_group(GtkRadioMenuItem* radio_menu_item, \ GSList* group)" Xen_check_type(Xen_is_GtkRadioMenuItem_(radio_menu_item), radio_menu_item, 1, "gtk_radio_menu_item_set_group", "GtkRadioMenuItem*"); Xen_check_type(Xen_is_GSList_(group) || Xen_is_false(group), group, 2, "gtk_radio_menu_item_set_group", "GSList*"); gtk_radio_menu_item_set_group(Xen_to_C_GtkRadioMenuItem_(radio_menu_item), Xen_to_C_GSList_(group)); return(Xen_false); } static Xen gxg_gtk_range_set_adjustment(Xen range, Xen adjustment) { #define H_gtk_range_set_adjustment "void gtk_range_set_adjustment(GtkRange* range, GtkAdjustment* adjustment)" Xen_check_type(Xen_is_GtkRange_(range), range, 1, "gtk_range_set_adjustment", "GtkRange*"); Xen_check_type(Xen_is_GtkAdjustment_(adjustment) || Xen_is_false(adjustment), adjustment, 2, "gtk_range_set_adjustment", "GtkAdjustment*"); gtk_range_set_adjustment(Xen_to_C_GtkRange_(range), Xen_to_C_GtkAdjustment_(adjustment)); return(Xen_false); } static Xen gxg_gtk_range_get_adjustment(Xen range) { #define H_gtk_range_get_adjustment "GtkAdjustment* gtk_range_get_adjustment(GtkRange* range)" Xen_check_type(Xen_is_GtkRange_(range), range, 1, "gtk_range_get_adjustment", "GtkRange*"); return(C_to_Xen_GtkAdjustment_(gtk_range_get_adjustment(Xen_to_C_GtkRange_(range)))); } static Xen gxg_gtk_range_set_inverted(Xen range, Xen setting) { #define H_gtk_range_set_inverted "void gtk_range_set_inverted(GtkRange* range, gboolean setting)" Xen_check_type(Xen_is_GtkRange_(range), range, 1, "gtk_range_set_inverted", "GtkRange*"); Xen_check_type(Xen_is_gboolean(setting), setting, 2, "gtk_range_set_inverted", "gboolean"); gtk_range_set_inverted(Xen_to_C_GtkRange_(range), Xen_to_C_gboolean(setting)); return(Xen_false); } static Xen gxg_gtk_range_get_inverted(Xen range) { #define H_gtk_range_get_inverted "gboolean gtk_range_get_inverted(GtkRange* range)" Xen_check_type(Xen_is_GtkRange_(range), range, 1, "gtk_range_get_inverted", "GtkRange*"); return(C_to_Xen_gboolean(gtk_range_get_inverted(Xen_to_C_GtkRange_(range)))); } static Xen gxg_gtk_range_set_increments(Xen range, Xen step, Xen page) { #define H_gtk_range_set_increments "void gtk_range_set_increments(GtkRange* range, gdouble step, gdouble page)" Xen_check_type(Xen_is_GtkRange_(range), range, 1, "gtk_range_set_increments", "GtkRange*"); Xen_check_type(Xen_is_gdouble(step), step, 2, "gtk_range_set_increments", "gdouble"); Xen_check_type(Xen_is_gdouble(page), page, 3, "gtk_range_set_increments", "gdouble"); gtk_range_set_increments(Xen_to_C_GtkRange_(range), Xen_to_C_gdouble(step), Xen_to_C_gdouble(page)); return(Xen_false); } static Xen gxg_gtk_range_set_range(Xen range, Xen min, Xen max) { #define H_gtk_range_set_range "void gtk_range_set_range(GtkRange* range, gdouble min, gdouble max)" Xen_check_type(Xen_is_GtkRange_(range), range, 1, "gtk_range_set_range", "GtkRange*"); Xen_check_type(Xen_is_gdouble(min), min, 2, "gtk_range_set_range", "gdouble"); Xen_check_type(Xen_is_gdouble(max), max, 3, "gtk_range_set_range", "gdouble"); gtk_range_set_range(Xen_to_C_GtkRange_(range), Xen_to_C_gdouble(min), Xen_to_C_gdouble(max)); return(Xen_false); } static Xen gxg_gtk_range_set_value(Xen range, Xen value) { #define H_gtk_range_set_value "void gtk_range_set_value(GtkRange* range, gdouble value)" Xen_check_type(Xen_is_GtkRange_(range), range, 1, "gtk_range_set_value", "GtkRange*"); Xen_check_type(Xen_is_gdouble(value), value, 2, "gtk_range_set_value", "gdouble"); gtk_range_set_value(Xen_to_C_GtkRange_(range), Xen_to_C_gdouble(value)); return(Xen_false); } static Xen gxg_gtk_range_get_value(Xen range) { #define H_gtk_range_get_value "gdouble gtk_range_get_value(GtkRange* range)" Xen_check_type(Xen_is_GtkRange_(range), range, 1, "gtk_range_get_value", "GtkRange*"); return(C_to_Xen_gdouble(gtk_range_get_value(Xen_to_C_GtkRange_(range)))); } static Xen gxg_gtk_scale_set_digits(Xen scale, Xen digits) { #define H_gtk_scale_set_digits "void gtk_scale_set_digits(GtkScale* scale, gint digits)" Xen_check_type(Xen_is_GtkScale_(scale), scale, 1, "gtk_scale_set_digits", "GtkScale*"); Xen_check_type(Xen_is_gint(digits), digits, 2, "gtk_scale_set_digits", "gint"); gtk_scale_set_digits(Xen_to_C_GtkScale_(scale), Xen_to_C_gint(digits)); return(Xen_false); } static Xen gxg_gtk_scale_get_digits(Xen scale) { #define H_gtk_scale_get_digits "gint gtk_scale_get_digits(GtkScale* scale)" Xen_check_type(Xen_is_GtkScale_(scale), scale, 1, "gtk_scale_get_digits", "GtkScale*"); return(C_to_Xen_gint(gtk_scale_get_digits(Xen_to_C_GtkScale_(scale)))); } static Xen gxg_gtk_scale_set_draw_value(Xen scale, Xen draw_value) { #define H_gtk_scale_set_draw_value "void gtk_scale_set_draw_value(GtkScale* scale, gboolean draw_value)" Xen_check_type(Xen_is_GtkScale_(scale), scale, 1, "gtk_scale_set_draw_value", "GtkScale*"); Xen_check_type(Xen_is_gboolean(draw_value), draw_value, 2, "gtk_scale_set_draw_value", "gboolean"); gtk_scale_set_draw_value(Xen_to_C_GtkScale_(scale), Xen_to_C_gboolean(draw_value)); return(Xen_false); } static Xen gxg_gtk_scale_get_draw_value(Xen scale) { #define H_gtk_scale_get_draw_value "gboolean gtk_scale_get_draw_value(GtkScale* scale)" Xen_check_type(Xen_is_GtkScale_(scale), scale, 1, "gtk_scale_get_draw_value", "GtkScale*"); return(C_to_Xen_gboolean(gtk_scale_get_draw_value(Xen_to_C_GtkScale_(scale)))); } static Xen gxg_gtk_scale_set_value_pos(Xen scale, Xen pos) { #define H_gtk_scale_set_value_pos "void gtk_scale_set_value_pos(GtkScale* scale, GtkPositionType pos)" Xen_check_type(Xen_is_GtkScale_(scale), scale, 1, "gtk_scale_set_value_pos", "GtkScale*"); Xen_check_type(Xen_is_GtkPositionType(pos), pos, 2, "gtk_scale_set_value_pos", "GtkPositionType"); gtk_scale_set_value_pos(Xen_to_C_GtkScale_(scale), Xen_to_C_GtkPositionType(pos)); return(Xen_false); } static Xen gxg_gtk_scale_get_value_pos(Xen scale) { #define H_gtk_scale_get_value_pos "GtkPositionType gtk_scale_get_value_pos(GtkScale* scale)" Xen_check_type(Xen_is_GtkScale_(scale), scale, 1, "gtk_scale_get_value_pos", "GtkScale*"); return(C_to_Xen_GtkPositionType(gtk_scale_get_value_pos(Xen_to_C_GtkScale_(scale)))); } static Xen gxg_gtk_scrolled_window_new(Xen hadjustment, Xen vadjustment) { #define H_gtk_scrolled_window_new "GtkWidget* gtk_scrolled_window_new(GtkAdjustment* hadjustment, GtkAdjustment* vadjustment)" Xen_check_type(Xen_is_GtkAdjustment_(hadjustment) || Xen_is_false(hadjustment), hadjustment, 1, "gtk_scrolled_window_new", "GtkAdjustment*"); Xen_check_type(Xen_is_GtkAdjustment_(vadjustment) || Xen_is_false(vadjustment), vadjustment, 2, "gtk_scrolled_window_new", "GtkAdjustment*"); return(C_to_Xen_GtkWidget_(gtk_scrolled_window_new(Xen_to_C_GtkAdjustment_(hadjustment), Xen_to_C_GtkAdjustment_(vadjustment)))); } static Xen gxg_gtk_scrolled_window_set_hadjustment(Xen scrolled_window, Xen hadjustment) { #define H_gtk_scrolled_window_set_hadjustment "void gtk_scrolled_window_set_hadjustment(GtkScrolledWindow* scrolled_window, \ GtkAdjustment* hadjustment)" Xen_check_type(Xen_is_GtkScrolledWindow_(scrolled_window), scrolled_window, 1, "gtk_scrolled_window_set_hadjustment", "GtkScrolledWindow*"); Xen_check_type(Xen_is_GtkAdjustment_(hadjustment) || Xen_is_false(hadjustment), hadjustment, 2, "gtk_scrolled_window_set_hadjustment", "GtkAdjustment*"); gtk_scrolled_window_set_hadjustment(Xen_to_C_GtkScrolledWindow_(scrolled_window), Xen_to_C_GtkAdjustment_(hadjustment)); return(Xen_false); } static Xen gxg_gtk_scrolled_window_set_vadjustment(Xen scrolled_window, Xen hadjustment) { #define H_gtk_scrolled_window_set_vadjustment "void gtk_scrolled_window_set_vadjustment(GtkScrolledWindow* scrolled_window, \ GtkAdjustment* hadjustment)" Xen_check_type(Xen_is_GtkScrolledWindow_(scrolled_window), scrolled_window, 1, "gtk_scrolled_window_set_vadjustment", "GtkScrolledWindow*"); Xen_check_type(Xen_is_GtkAdjustment_(hadjustment) || Xen_is_false(hadjustment), hadjustment, 2, "gtk_scrolled_window_set_vadjustment", "GtkAdjustment*"); gtk_scrolled_window_set_vadjustment(Xen_to_C_GtkScrolledWindow_(scrolled_window), Xen_to_C_GtkAdjustment_(hadjustment)); return(Xen_false); } static Xen gxg_gtk_scrolled_window_get_hadjustment(Xen scrolled_window) { #define H_gtk_scrolled_window_get_hadjustment "GtkAdjustment* gtk_scrolled_window_get_hadjustment(GtkScrolledWindow* scrolled_window)" Xen_check_type(Xen_is_GtkScrolledWindow_(scrolled_window), scrolled_window, 1, "gtk_scrolled_window_get_hadjustment", "GtkScrolledWindow*"); return(C_to_Xen_GtkAdjustment_(gtk_scrolled_window_get_hadjustment(Xen_to_C_GtkScrolledWindow_(scrolled_window)))); } static Xen gxg_gtk_scrolled_window_get_vadjustment(Xen scrolled_window) { #define H_gtk_scrolled_window_get_vadjustment "GtkAdjustment* gtk_scrolled_window_get_vadjustment(GtkScrolledWindow* scrolled_window)" Xen_check_type(Xen_is_GtkScrolledWindow_(scrolled_window), scrolled_window, 1, "gtk_scrolled_window_get_vadjustment", "GtkScrolledWindow*"); return(C_to_Xen_GtkAdjustment_(gtk_scrolled_window_get_vadjustment(Xen_to_C_GtkScrolledWindow_(scrolled_window)))); } static Xen gxg_gtk_scrolled_window_set_policy(Xen scrolled_window, Xen hscrollbar_policy, Xen vscrollbar_policy) { #define H_gtk_scrolled_window_set_policy "void gtk_scrolled_window_set_policy(GtkScrolledWindow* scrolled_window, \ GtkPolicyType hscrollbar_policy, GtkPolicyType vscrollbar_policy)" Xen_check_type(Xen_is_GtkScrolledWindow_(scrolled_window), scrolled_window, 1, "gtk_scrolled_window_set_policy", "GtkScrolledWindow*"); Xen_check_type(Xen_is_GtkPolicyType(hscrollbar_policy), hscrollbar_policy, 2, "gtk_scrolled_window_set_policy", "GtkPolicyType"); Xen_check_type(Xen_is_GtkPolicyType(vscrollbar_policy), vscrollbar_policy, 3, "gtk_scrolled_window_set_policy", "GtkPolicyType"); gtk_scrolled_window_set_policy(Xen_to_C_GtkScrolledWindow_(scrolled_window), Xen_to_C_GtkPolicyType(hscrollbar_policy), Xen_to_C_GtkPolicyType(vscrollbar_policy)); return(Xen_false); } static Xen gxg_gtk_scrolled_window_get_policy(Xen scrolled_window, Xen ignore_hscrollbar_policy, Xen ignore_vscrollbar_policy) { #define H_gtk_scrolled_window_get_policy "void gtk_scrolled_window_get_policy(GtkScrolledWindow* scrolled_window, \ GtkPolicyType* [hscrollbar_policy], GtkPolicyType* [vscrollbar_policy])" GtkPolicyType ref_hscrollbar_policy; GtkPolicyType ref_vscrollbar_policy; Xen_check_type(Xen_is_GtkScrolledWindow_(scrolled_window), scrolled_window, 1, "gtk_scrolled_window_get_policy", "GtkScrolledWindow*"); gtk_scrolled_window_get_policy(Xen_to_C_GtkScrolledWindow_(scrolled_window), &ref_hscrollbar_policy, &ref_vscrollbar_policy); return(Xen_list_2(C_to_Xen_GtkPolicyType(ref_hscrollbar_policy), C_to_Xen_GtkPolicyType(ref_vscrollbar_policy))); } static Xen gxg_gtk_scrolled_window_set_placement(Xen scrolled_window, Xen window_placement) { #define H_gtk_scrolled_window_set_placement "void gtk_scrolled_window_set_placement(GtkScrolledWindow* scrolled_window, \ GtkCornerType window_placement)" Xen_check_type(Xen_is_GtkScrolledWindow_(scrolled_window), scrolled_window, 1, "gtk_scrolled_window_set_placement", "GtkScrolledWindow*"); Xen_check_type(Xen_is_GtkCornerType(window_placement), window_placement, 2, "gtk_scrolled_window_set_placement", "GtkCornerType"); gtk_scrolled_window_set_placement(Xen_to_C_GtkScrolledWindow_(scrolled_window), Xen_to_C_GtkCornerType(window_placement)); return(Xen_false); } static Xen gxg_gtk_scrolled_window_get_placement(Xen scrolled_window) { #define H_gtk_scrolled_window_get_placement "GtkCornerType gtk_scrolled_window_get_placement(GtkScrolledWindow* scrolled_window)" Xen_check_type(Xen_is_GtkScrolledWindow_(scrolled_window), scrolled_window, 1, "gtk_scrolled_window_get_placement", "GtkScrolledWindow*"); return(C_to_Xen_GtkCornerType(gtk_scrolled_window_get_placement(Xen_to_C_GtkScrolledWindow_(scrolled_window)))); } static Xen gxg_gtk_scrolled_window_set_shadow_type(Xen scrolled_window, Xen type) { #define H_gtk_scrolled_window_set_shadow_type "void gtk_scrolled_window_set_shadow_type(GtkScrolledWindow* scrolled_window, \ GtkShadowType type)" Xen_check_type(Xen_is_GtkScrolledWindow_(scrolled_window), scrolled_window, 1, "gtk_scrolled_window_set_shadow_type", "GtkScrolledWindow*"); Xen_check_type(Xen_is_GtkShadowType(type), type, 2, "gtk_scrolled_window_set_shadow_type", "GtkShadowType"); gtk_scrolled_window_set_shadow_type(Xen_to_C_GtkScrolledWindow_(scrolled_window), Xen_to_C_GtkShadowType(type)); return(Xen_false); } static Xen gxg_gtk_scrolled_window_get_shadow_type(Xen scrolled_window) { #define H_gtk_scrolled_window_get_shadow_type "GtkShadowType gtk_scrolled_window_get_shadow_type(GtkScrolledWindow* scrolled_window)" Xen_check_type(Xen_is_GtkScrolledWindow_(scrolled_window), scrolled_window, 1, "gtk_scrolled_window_get_shadow_type", "GtkScrolledWindow*"); return(C_to_Xen_GtkShadowType(gtk_scrolled_window_get_shadow_type(Xen_to_C_GtkScrolledWindow_(scrolled_window)))); } static Xen gxg_gtk_target_list_new(Xen targets, Xen ntargets) { #define H_gtk_target_list_new "GtkTargetList* gtk_target_list_new(GtkTargetEntry* targets, guint ntargets)" Xen_check_type(Xen_is_GtkTargetEntry_(targets) || Xen_is_false(targets), targets, 1, "gtk_target_list_new", "GtkTargetEntry*"); Xen_check_type(Xen_is_guint(ntargets), ntargets, 2, "gtk_target_list_new", "guint"); return(C_to_Xen_GtkTargetList_(gtk_target_list_new(Xen_to_C_GtkTargetEntry_(targets), Xen_to_C_guint(ntargets)))); } static Xen gxg_gtk_target_list_unref(Xen list) { #define H_gtk_target_list_unref "void gtk_target_list_unref(GtkTargetList* list)" Xen_check_type(Xen_is_GtkTargetList_(list), list, 1, "gtk_target_list_unref", "GtkTargetList*"); gtk_target_list_unref(Xen_to_C_GtkTargetList_(list)); return(Xen_false); } static Xen gxg_gtk_target_list_add(Xen list, Xen target, Xen flags, Xen info) { #define H_gtk_target_list_add "void gtk_target_list_add(GtkTargetList* list, GdkAtom target, guint flags, \ guint info)" Xen_check_type(Xen_is_GtkTargetList_(list), list, 1, "gtk_target_list_add", "GtkTargetList*"); Xen_check_type(Xen_is_GdkAtom(target), target, 2, "gtk_target_list_add", "GdkAtom"); Xen_check_type(Xen_is_guint(flags), flags, 3, "gtk_target_list_add", "guint"); Xen_check_type(Xen_is_guint(info), info, 4, "gtk_target_list_add", "guint"); gtk_target_list_add(Xen_to_C_GtkTargetList_(list), Xen_to_C_GdkAtom(target), Xen_to_C_guint(flags), Xen_to_C_guint(info)); return(Xen_false); } static Xen gxg_gtk_target_list_add_table(Xen list, Xen targets, Xen ntargets) { #define H_gtk_target_list_add_table "void gtk_target_list_add_table(GtkTargetList* list, GtkTargetEntry* targets, \ guint ntargets)" Xen_check_type(Xen_is_GtkTargetList_(list), list, 1, "gtk_target_list_add_table", "GtkTargetList*"); Xen_check_type(Xen_is_GtkTargetEntry_(targets), targets, 2, "gtk_target_list_add_table", "GtkTargetEntry*"); Xen_check_type(Xen_is_guint(ntargets), ntargets, 3, "gtk_target_list_add_table", "guint"); gtk_target_list_add_table(Xen_to_C_GtkTargetList_(list), Xen_to_C_GtkTargetEntry_(targets), Xen_to_C_guint(ntargets)); return(Xen_false); } static Xen gxg_gtk_target_list_remove(Xen list, Xen target) { #define H_gtk_target_list_remove "void gtk_target_list_remove(GtkTargetList* list, GdkAtom target)" Xen_check_type(Xen_is_GtkTargetList_(list), list, 1, "gtk_target_list_remove", "GtkTargetList*"); Xen_check_type(Xen_is_GdkAtom(target), target, 2, "gtk_target_list_remove", "GdkAtom"); gtk_target_list_remove(Xen_to_C_GtkTargetList_(list), Xen_to_C_GdkAtom(target)); return(Xen_false); } static Xen gxg_gtk_target_list_find(Xen list, Xen target, Xen ignore_info) { #define H_gtk_target_list_find "gboolean gtk_target_list_find(GtkTargetList* list, GdkAtom target, \ guint* [info])" guint ref_info; Xen_check_type(Xen_is_GtkTargetList_(list), list, 1, "gtk_target_list_find", "GtkTargetList*"); Xen_check_type(Xen_is_GdkAtom(target), target, 2, "gtk_target_list_find", "GdkAtom"); { Xen result; result = C_to_Xen_gboolean(gtk_target_list_find(Xen_to_C_GtkTargetList_(list), Xen_to_C_GdkAtom(target), &ref_info)); return(Xen_list_2(result, C_to_Xen_guint(ref_info))); } } static Xen gxg_gtk_selection_owner_set(Xen widget, Xen selection, Xen time) { #define H_gtk_selection_owner_set "gboolean gtk_selection_owner_set(GtkWidget* widget, GdkAtom selection, \ guint32 time)" Xen_check_type(Xen_is_GtkWidget_(widget) || Xen_is_false(widget), widget, 1, "gtk_selection_owner_set", "GtkWidget*"); Xen_check_type(Xen_is_GdkAtom(selection), selection, 2, "gtk_selection_owner_set", "GdkAtom"); Xen_check_type(Xen_is_guint32(time), time, 3, "gtk_selection_owner_set", "guint32"); return(C_to_Xen_gboolean(gtk_selection_owner_set(Xen_to_C_GtkWidget_(widget), Xen_to_C_GdkAtom(selection), Xen_to_C_guint32(time)))); } static Xen gxg_gtk_selection_add_target(Xen widget, Xen selection, Xen target, Xen info) { #define H_gtk_selection_add_target "void gtk_selection_add_target(GtkWidget* widget, GdkAtom selection, \ GdkAtom target, guint info)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_selection_add_target", "GtkWidget*"); Xen_check_type(Xen_is_GdkAtom(selection), selection, 2, "gtk_selection_add_target", "GdkAtom"); Xen_check_type(Xen_is_GdkAtom(target), target, 3, "gtk_selection_add_target", "GdkAtom"); Xen_check_type(Xen_is_guint(info), info, 4, "gtk_selection_add_target", "guint"); gtk_selection_add_target(Xen_to_C_GtkWidget_(widget), Xen_to_C_GdkAtom(selection), Xen_to_C_GdkAtom(target), Xen_to_C_guint(info)); return(Xen_false); } static Xen gxg_gtk_selection_add_targets(Xen widget, Xen selection, Xen targets, Xen ntargets) { #define H_gtk_selection_add_targets "void gtk_selection_add_targets(GtkWidget* widget, GdkAtom selection, \ GtkTargetEntry* targets, guint ntargets)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_selection_add_targets", "GtkWidget*"); Xen_check_type(Xen_is_GdkAtom(selection), selection, 2, "gtk_selection_add_targets", "GdkAtom"); Xen_check_type(Xen_is_GtkTargetEntry_(targets), targets, 3, "gtk_selection_add_targets", "GtkTargetEntry*"); Xen_check_type(Xen_is_guint(ntargets), ntargets, 4, "gtk_selection_add_targets", "guint"); gtk_selection_add_targets(Xen_to_C_GtkWidget_(widget), Xen_to_C_GdkAtom(selection), Xen_to_C_GtkTargetEntry_(targets), Xen_to_C_guint(ntargets)); return(Xen_false); } static Xen gxg_gtk_selection_clear_targets(Xen widget, Xen selection) { #define H_gtk_selection_clear_targets "void gtk_selection_clear_targets(GtkWidget* widget, GdkAtom selection)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_selection_clear_targets", "GtkWidget*"); Xen_check_type(Xen_is_GdkAtom(selection), selection, 2, "gtk_selection_clear_targets", "GdkAtom"); gtk_selection_clear_targets(Xen_to_C_GtkWidget_(widget), Xen_to_C_GdkAtom(selection)); return(Xen_false); } static Xen gxg_gtk_selection_convert(Xen widget, Xen selection, Xen target, Xen time) { #define H_gtk_selection_convert "gboolean gtk_selection_convert(GtkWidget* widget, GdkAtom selection, \ GdkAtom target, guint32 time)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_selection_convert", "GtkWidget*"); Xen_check_type(Xen_is_GdkAtom(selection), selection, 2, "gtk_selection_convert", "GdkAtom"); Xen_check_type(Xen_is_GdkAtom(target), target, 3, "gtk_selection_convert", "GdkAtom"); Xen_check_type(Xen_is_guint32(time), time, 4, "gtk_selection_convert", "guint32"); return(C_to_Xen_gboolean(gtk_selection_convert(Xen_to_C_GtkWidget_(widget), Xen_to_C_GdkAtom(selection), Xen_to_C_GdkAtom(target), Xen_to_C_guint32(time)))); } static Xen gxg_gtk_selection_data_set(Xen selection_data, Xen type, Xen format, Xen data, Xen length) { #define H_gtk_selection_data_set "void gtk_selection_data_set(GtkSelectionData* selection_data, GdkAtom type, \ gint format, guchar* data, gint length)" Xen_check_type(Xen_is_GtkSelectionData_(selection_data), selection_data, 1, "gtk_selection_data_set", "GtkSelectionData*"); Xen_check_type(Xen_is_GdkAtom(type), type, 2, "gtk_selection_data_set", "GdkAtom"); Xen_check_type(Xen_is_gint(format), format, 3, "gtk_selection_data_set", "gint"); Xen_check_type(Xen_is_guchar_(data), data, 4, "gtk_selection_data_set", "guchar*"); Xen_check_type(Xen_is_gint(length), length, 5, "gtk_selection_data_set", "gint"); gtk_selection_data_set(Xen_to_C_GtkSelectionData_(selection_data), Xen_to_C_GdkAtom(type), Xen_to_C_gint(format), Xen_to_C_guchar_(data), Xen_to_C_gint(length)); return(Xen_false); } static Xen gxg_gtk_selection_data_set_text(Xen selection_data, Xen str, Xen len) { #define H_gtk_selection_data_set_text "gboolean gtk_selection_data_set_text(GtkSelectionData* selection_data, \ gchar* str, gint len)" Xen_check_type(Xen_is_GtkSelectionData_(selection_data), selection_data, 1, "gtk_selection_data_set_text", "GtkSelectionData*"); Xen_check_type(Xen_is_gchar_(str), str, 2, "gtk_selection_data_set_text", "gchar*"); Xen_check_type(Xen_is_gint(len), len, 3, "gtk_selection_data_set_text", "gint"); return(C_to_Xen_gboolean(gtk_selection_data_set_text(Xen_to_C_GtkSelectionData_(selection_data), Xen_to_C_gchar_(str), Xen_to_C_gint(len)))); } static Xen gxg_gtk_selection_data_get_text(Xen selection_data) { #define H_gtk_selection_data_get_text "guchar* gtk_selection_data_get_text(GtkSelectionData* selection_data)" Xen_check_type(Xen_is_GtkSelectionData_(selection_data), selection_data, 1, "gtk_selection_data_get_text", "GtkSelectionData*"); { guchar* result; Xen rtn; result = gtk_selection_data_get_text(Xen_to_C_GtkSelectionData_(selection_data)); rtn = C_to_Xen_guchar_(result); g_free(result); return(rtn); } } static Xen gxg_gtk_selection_data_get_targets(Xen selection_data, Xen ignore_targets, Xen ignore_n_atoms) { #define H_gtk_selection_data_get_targets "gboolean gtk_selection_data_get_targets(GtkSelectionData* selection_data, \ GdkAtom** [targets], gint* [n_atoms])" GdkAtom* ref_targets = NULL; gint ref_n_atoms; Xen_check_type(Xen_is_GtkSelectionData_(selection_data), selection_data, 1, "gtk_selection_data_get_targets", "GtkSelectionData*"); { Xen result; result = C_to_Xen_gboolean(gtk_selection_data_get_targets(Xen_to_C_GtkSelectionData_(selection_data), &ref_targets, &ref_n_atoms)); return(Xen_list_3(result, C_to_Xen_GdkAtom_(ref_targets), C_to_Xen_gint(ref_n_atoms))); } } static Xen gxg_gtk_selection_data_targets_include_text(Xen selection_data) { #define H_gtk_selection_data_targets_include_text "gboolean gtk_selection_data_targets_include_text(GtkSelectionData* selection_data)" Xen_check_type(Xen_is_GtkSelectionData_(selection_data), selection_data, 1, "gtk_selection_data_targets_include_text", "GtkSelectionData*"); return(C_to_Xen_gboolean(gtk_selection_data_targets_include_text(Xen_to_C_GtkSelectionData_(selection_data)))); } static Xen gxg_gtk_selection_remove_all(Xen widget) { #define H_gtk_selection_remove_all "void gtk_selection_remove_all(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_selection_remove_all", "GtkWidget*"); gtk_selection_remove_all(Xen_to_C_GtkWidget_(widget)); return(Xen_false); } static Xen gxg_gtk_selection_data_copy(Xen data) { #define H_gtk_selection_data_copy "GtkSelectionData* gtk_selection_data_copy(GtkSelectionData* data)" Xen_check_type(Xen_is_GtkSelectionData_(data), data, 1, "gtk_selection_data_copy", "GtkSelectionData*"); return(C_to_Xen_GtkSelectionData_(gtk_selection_data_copy(Xen_to_C_GtkSelectionData_(data)))); } static Xen gxg_gtk_selection_data_free(Xen data) { #define H_gtk_selection_data_free "void gtk_selection_data_free(GtkSelectionData* data)" Xen_check_type(Xen_is_GtkSelectionData_(data), data, 1, "gtk_selection_data_free", "GtkSelectionData*"); gtk_selection_data_free(Xen_to_C_GtkSelectionData_(data)); return(Xen_false); } static Xen gxg_gtk_separator_menu_item_new(void) { #define H_gtk_separator_menu_item_new "GtkWidget* gtk_separator_menu_item_new( void)" return(C_to_Xen_GtkWidget_(gtk_separator_menu_item_new())); } static Xen gxg_gtk_settings_get_default(void) { #define H_gtk_settings_get_default "GtkSettings* gtk_settings_get_default( void)" return(C_to_Xen_GtkSettings_(gtk_settings_get_default())); } static Xen gxg_gtk_size_group_new(Xen mode) { #define H_gtk_size_group_new "GtkSizeGroup* gtk_size_group_new(GtkSizeGroupMode mode)" Xen_check_type(Xen_is_GtkSizeGroupMode(mode), mode, 1, "gtk_size_group_new", "GtkSizeGroupMode"); return(C_to_Xen_GtkSizeGroup_(gtk_size_group_new(Xen_to_C_GtkSizeGroupMode(mode)))); } static Xen gxg_gtk_size_group_set_mode(Xen size_group, Xen mode) { #define H_gtk_size_group_set_mode "void gtk_size_group_set_mode(GtkSizeGroup* size_group, GtkSizeGroupMode mode)" Xen_check_type(Xen_is_GtkSizeGroup_(size_group), size_group, 1, "gtk_size_group_set_mode", "GtkSizeGroup*"); Xen_check_type(Xen_is_GtkSizeGroupMode(mode), mode, 2, "gtk_size_group_set_mode", "GtkSizeGroupMode"); gtk_size_group_set_mode(Xen_to_C_GtkSizeGroup_(size_group), Xen_to_C_GtkSizeGroupMode(mode)); return(Xen_false); } static Xen gxg_gtk_size_group_get_mode(Xen size_group) { #define H_gtk_size_group_get_mode "GtkSizeGroupMode gtk_size_group_get_mode(GtkSizeGroup* size_group)" Xen_check_type(Xen_is_GtkSizeGroup_(size_group), size_group, 1, "gtk_size_group_get_mode", "GtkSizeGroup*"); return(C_to_Xen_GtkSizeGroupMode(gtk_size_group_get_mode(Xen_to_C_GtkSizeGroup_(size_group)))); } static Xen gxg_gtk_size_group_add_widget(Xen size_group, Xen widget) { #define H_gtk_size_group_add_widget "void gtk_size_group_add_widget(GtkSizeGroup* size_group, GtkWidget* widget)" Xen_check_type(Xen_is_GtkSizeGroup_(size_group), size_group, 1, "gtk_size_group_add_widget", "GtkSizeGroup*"); Xen_check_type(Xen_is_GtkWidget_(widget), widget, 2, "gtk_size_group_add_widget", "GtkWidget*"); gtk_size_group_add_widget(Xen_to_C_GtkSizeGroup_(size_group), Xen_to_C_GtkWidget_(widget)); return(Xen_false); } static Xen gxg_gtk_size_group_remove_widget(Xen size_group, Xen widget) { #define H_gtk_size_group_remove_widget "void gtk_size_group_remove_widget(GtkSizeGroup* size_group, \ GtkWidget* widget)" Xen_check_type(Xen_is_GtkSizeGroup_(size_group), size_group, 1, "gtk_size_group_remove_widget", "GtkSizeGroup*"); Xen_check_type(Xen_is_GtkWidget_(widget), widget, 2, "gtk_size_group_remove_widget", "GtkWidget*"); gtk_size_group_remove_widget(Xen_to_C_GtkSizeGroup_(size_group), Xen_to_C_GtkWidget_(widget)); return(Xen_false); } static Xen gxg_gtk_spin_button_configure(Xen spin_button, Xen adjustment, Xen climb_rate, Xen digits) { #define H_gtk_spin_button_configure "void gtk_spin_button_configure(GtkSpinButton* spin_button, GtkAdjustment* adjustment, \ gdouble climb_rate, guint digits)" Xen_check_type(Xen_is_GtkSpinButton_(spin_button), spin_button, 1, "gtk_spin_button_configure", "GtkSpinButton*"); Xen_check_type(Xen_is_GtkAdjustment_(adjustment) || Xen_is_false(adjustment), adjustment, 2, "gtk_spin_button_configure", "GtkAdjustment*"); Xen_check_type(Xen_is_gdouble(climb_rate), climb_rate, 3, "gtk_spin_button_configure", "gdouble"); Xen_check_type(Xen_is_guint(digits), digits, 4, "gtk_spin_button_configure", "guint"); gtk_spin_button_configure(Xen_to_C_GtkSpinButton_(spin_button), Xen_to_C_GtkAdjustment_(adjustment), Xen_to_C_gdouble(climb_rate), Xen_to_C_guint(digits)); return(Xen_false); } static Xen gxg_gtk_spin_button_new(Xen adjustment, Xen climb_rate, Xen digits) { #define H_gtk_spin_button_new "GtkWidget* gtk_spin_button_new(GtkAdjustment* adjustment, gdouble climb_rate, \ guint digits)" Xen_check_type(Xen_is_GtkAdjustment_(adjustment) || Xen_is_false(adjustment), adjustment, 1, "gtk_spin_button_new", "GtkAdjustment*"); Xen_check_type(Xen_is_gdouble(climb_rate), climb_rate, 2, "gtk_spin_button_new", "gdouble"); Xen_check_type(Xen_is_guint(digits), digits, 3, "gtk_spin_button_new", "guint"); return(C_to_Xen_GtkWidget_(gtk_spin_button_new(Xen_to_C_GtkAdjustment_(adjustment), Xen_to_C_gdouble(climb_rate), Xen_to_C_guint(digits)))); } static Xen gxg_gtk_spin_button_new_with_range(Xen min, Xen max, Xen step) { #define H_gtk_spin_button_new_with_range "GtkWidget* gtk_spin_button_new_with_range(gdouble min, gdouble max, \ gdouble step)" Xen_check_type(Xen_is_gdouble(min), min, 1, "gtk_spin_button_new_with_range", "gdouble"); Xen_check_type(Xen_is_gdouble(max), max, 2, "gtk_spin_button_new_with_range", "gdouble"); Xen_check_type(Xen_is_gdouble(step), step, 3, "gtk_spin_button_new_with_range", "gdouble"); return(C_to_Xen_GtkWidget_(gtk_spin_button_new_with_range(Xen_to_C_gdouble(min), Xen_to_C_gdouble(max), Xen_to_C_gdouble(step)))); } static Xen gxg_gtk_spin_button_set_adjustment(Xen spin_button, Xen adjustment) { #define H_gtk_spin_button_set_adjustment "void gtk_spin_button_set_adjustment(GtkSpinButton* spin_button, \ GtkAdjustment* adjustment)" Xen_check_type(Xen_is_GtkSpinButton_(spin_button), spin_button, 1, "gtk_spin_button_set_adjustment", "GtkSpinButton*"); Xen_check_type(Xen_is_GtkAdjustment_(adjustment) || Xen_is_false(adjustment), adjustment, 2, "gtk_spin_button_set_adjustment", "GtkAdjustment*"); gtk_spin_button_set_adjustment(Xen_to_C_GtkSpinButton_(spin_button), Xen_to_C_GtkAdjustment_(adjustment)); return(Xen_false); } static Xen gxg_gtk_spin_button_get_adjustment(Xen spin_button) { #define H_gtk_spin_button_get_adjustment "GtkAdjustment* gtk_spin_button_get_adjustment(GtkSpinButton* spin_button)" Xen_check_type(Xen_is_GtkSpinButton_(spin_button), spin_button, 1, "gtk_spin_button_get_adjustment", "GtkSpinButton*"); return(C_to_Xen_GtkAdjustment_(gtk_spin_button_get_adjustment(Xen_to_C_GtkSpinButton_(spin_button)))); } static Xen gxg_gtk_spin_button_set_digits(Xen spin_button, Xen digits) { #define H_gtk_spin_button_set_digits "void gtk_spin_button_set_digits(GtkSpinButton* spin_button, guint digits)" Xen_check_type(Xen_is_GtkSpinButton_(spin_button), spin_button, 1, "gtk_spin_button_set_digits", "GtkSpinButton*"); Xen_check_type(Xen_is_guint(digits), digits, 2, "gtk_spin_button_set_digits", "guint"); gtk_spin_button_set_digits(Xen_to_C_GtkSpinButton_(spin_button), Xen_to_C_guint(digits)); return(Xen_false); } static Xen gxg_gtk_spin_button_get_digits(Xen spin_button) { #define H_gtk_spin_button_get_digits "guint gtk_spin_button_get_digits(GtkSpinButton* spin_button)" Xen_check_type(Xen_is_GtkSpinButton_(spin_button), spin_button, 1, "gtk_spin_button_get_digits", "GtkSpinButton*"); return(C_to_Xen_guint(gtk_spin_button_get_digits(Xen_to_C_GtkSpinButton_(spin_button)))); } static Xen gxg_gtk_spin_button_set_increments(Xen spin_button, Xen step, Xen page) { #define H_gtk_spin_button_set_increments "void gtk_spin_button_set_increments(GtkSpinButton* spin_button, \ gdouble step, gdouble page)" Xen_check_type(Xen_is_GtkSpinButton_(spin_button), spin_button, 1, "gtk_spin_button_set_increments", "GtkSpinButton*"); Xen_check_type(Xen_is_gdouble(step), step, 2, "gtk_spin_button_set_increments", "gdouble"); Xen_check_type(Xen_is_gdouble(page), page, 3, "gtk_spin_button_set_increments", "gdouble"); gtk_spin_button_set_increments(Xen_to_C_GtkSpinButton_(spin_button), Xen_to_C_gdouble(step), Xen_to_C_gdouble(page)); return(Xen_false); } static Xen gxg_gtk_spin_button_get_increments(Xen spin_button, Xen ignore_step, Xen ignore_page) { #define H_gtk_spin_button_get_increments "void gtk_spin_button_get_increments(GtkSpinButton* spin_button, \ gdouble* [step], gdouble* [page])" gdouble ref_step; gdouble ref_page; Xen_check_type(Xen_is_GtkSpinButton_(spin_button), spin_button, 1, "gtk_spin_button_get_increments", "GtkSpinButton*"); gtk_spin_button_get_increments(Xen_to_C_GtkSpinButton_(spin_button), &ref_step, &ref_page); return(Xen_list_2(C_to_Xen_gdouble(ref_step), C_to_Xen_gdouble(ref_page))); } static Xen gxg_gtk_spin_button_set_range(Xen spin_button, Xen min, Xen max) { #define H_gtk_spin_button_set_range "void gtk_spin_button_set_range(GtkSpinButton* spin_button, gdouble min, \ gdouble max)" Xen_check_type(Xen_is_GtkSpinButton_(spin_button), spin_button, 1, "gtk_spin_button_set_range", "GtkSpinButton*"); Xen_check_type(Xen_is_gdouble(min), min, 2, "gtk_spin_button_set_range", "gdouble"); Xen_check_type(Xen_is_gdouble(max), max, 3, "gtk_spin_button_set_range", "gdouble"); gtk_spin_button_set_range(Xen_to_C_GtkSpinButton_(spin_button), Xen_to_C_gdouble(min), Xen_to_C_gdouble(max)); return(Xen_false); } static Xen gxg_gtk_spin_button_get_range(Xen spin_button, Xen ignore_min, Xen ignore_max) { #define H_gtk_spin_button_get_range "void gtk_spin_button_get_range(GtkSpinButton* spin_button, gdouble* [min], \ gdouble* [max])" gdouble ref_min; gdouble ref_max; Xen_check_type(Xen_is_GtkSpinButton_(spin_button), spin_button, 1, "gtk_spin_button_get_range", "GtkSpinButton*"); gtk_spin_button_get_range(Xen_to_C_GtkSpinButton_(spin_button), &ref_min, &ref_max); return(Xen_list_2(C_to_Xen_gdouble(ref_min), C_to_Xen_gdouble(ref_max))); } static Xen gxg_gtk_spin_button_get_value(Xen spin_button) { #define H_gtk_spin_button_get_value "gdouble gtk_spin_button_get_value(GtkSpinButton* spin_button)" Xen_check_type(Xen_is_GtkSpinButton_(spin_button), spin_button, 1, "gtk_spin_button_get_value", "GtkSpinButton*"); return(C_to_Xen_gdouble(gtk_spin_button_get_value(Xen_to_C_GtkSpinButton_(spin_button)))); } static Xen gxg_gtk_spin_button_get_value_as_int(Xen spin_button) { #define H_gtk_spin_button_get_value_as_int "gint gtk_spin_button_get_value_as_int(GtkSpinButton* spin_button)" Xen_check_type(Xen_is_GtkSpinButton_(spin_button), spin_button, 1, "gtk_spin_button_get_value_as_int", "GtkSpinButton*"); return(C_to_Xen_gint(gtk_spin_button_get_value_as_int(Xen_to_C_GtkSpinButton_(spin_button)))); } static Xen gxg_gtk_spin_button_set_value(Xen spin_button, Xen value) { #define H_gtk_spin_button_set_value "void gtk_spin_button_set_value(GtkSpinButton* spin_button, gdouble value)" Xen_check_type(Xen_is_GtkSpinButton_(spin_button), spin_button, 1, "gtk_spin_button_set_value", "GtkSpinButton*"); Xen_check_type(Xen_is_gdouble(value), value, 2, "gtk_spin_button_set_value", "gdouble"); gtk_spin_button_set_value(Xen_to_C_GtkSpinButton_(spin_button), Xen_to_C_gdouble(value)); return(Xen_false); } static Xen gxg_gtk_spin_button_set_update_policy(Xen spin_button, Xen policy) { #define H_gtk_spin_button_set_update_policy "void gtk_spin_button_set_update_policy(GtkSpinButton* spin_button, \ GtkSpinButtonUpdatePolicy policy)" Xen_check_type(Xen_is_GtkSpinButton_(spin_button), spin_button, 1, "gtk_spin_button_set_update_policy", "GtkSpinButton*"); Xen_check_type(Xen_is_GtkSpinButtonUpdatePolicy(policy), policy, 2, "gtk_spin_button_set_update_policy", "GtkSpinButtonUpdatePolicy"); gtk_spin_button_set_update_policy(Xen_to_C_GtkSpinButton_(spin_button), Xen_to_C_GtkSpinButtonUpdatePolicy(policy)); return(Xen_false); } static Xen gxg_gtk_spin_button_get_update_policy(Xen spin_button) { #define H_gtk_spin_button_get_update_policy "GtkSpinButtonUpdatePolicy gtk_spin_button_get_update_policy(GtkSpinButton* spin_button)" Xen_check_type(Xen_is_GtkSpinButton_(spin_button), spin_button, 1, "gtk_spin_button_get_update_policy", "GtkSpinButton*"); return(C_to_Xen_GtkSpinButtonUpdatePolicy(gtk_spin_button_get_update_policy(Xen_to_C_GtkSpinButton_(spin_button)))); } static Xen gxg_gtk_spin_button_set_numeric(Xen spin_button, Xen numeric) { #define H_gtk_spin_button_set_numeric "void gtk_spin_button_set_numeric(GtkSpinButton* spin_button, \ gboolean numeric)" Xen_check_type(Xen_is_GtkSpinButton_(spin_button), spin_button, 1, "gtk_spin_button_set_numeric", "GtkSpinButton*"); Xen_check_type(Xen_is_gboolean(numeric), numeric, 2, "gtk_spin_button_set_numeric", "gboolean"); gtk_spin_button_set_numeric(Xen_to_C_GtkSpinButton_(spin_button), Xen_to_C_gboolean(numeric)); return(Xen_false); } static Xen gxg_gtk_spin_button_get_numeric(Xen spin_button) { #define H_gtk_spin_button_get_numeric "gboolean gtk_spin_button_get_numeric(GtkSpinButton* spin_button)" Xen_check_type(Xen_is_GtkSpinButton_(spin_button), spin_button, 1, "gtk_spin_button_get_numeric", "GtkSpinButton*"); return(C_to_Xen_gboolean(gtk_spin_button_get_numeric(Xen_to_C_GtkSpinButton_(spin_button)))); } static Xen gxg_gtk_spin_button_spin(Xen spin_button, Xen direction, Xen increment) { #define H_gtk_spin_button_spin "void gtk_spin_button_spin(GtkSpinButton* spin_button, GtkSpinType direction, \ gdouble increment)" Xen_check_type(Xen_is_GtkSpinButton_(spin_button), spin_button, 1, "gtk_spin_button_spin", "GtkSpinButton*"); Xen_check_type(Xen_is_GtkSpinType(direction), direction, 2, "gtk_spin_button_spin", "GtkSpinType"); Xen_check_type(Xen_is_gdouble(increment), increment, 3, "gtk_spin_button_spin", "gdouble"); gtk_spin_button_spin(Xen_to_C_GtkSpinButton_(spin_button), Xen_to_C_GtkSpinType(direction), Xen_to_C_gdouble(increment)); return(Xen_false); } static Xen gxg_gtk_spin_button_set_wrap(Xen spin_button, Xen wrap) { #define H_gtk_spin_button_set_wrap "void gtk_spin_button_set_wrap(GtkSpinButton* spin_button, gboolean wrap)" Xen_check_type(Xen_is_GtkSpinButton_(spin_button), spin_button, 1, "gtk_spin_button_set_wrap", "GtkSpinButton*"); Xen_check_type(Xen_is_gboolean(wrap), wrap, 2, "gtk_spin_button_set_wrap", "gboolean"); gtk_spin_button_set_wrap(Xen_to_C_GtkSpinButton_(spin_button), Xen_to_C_gboolean(wrap)); return(Xen_false); } static Xen gxg_gtk_spin_button_get_wrap(Xen spin_button) { #define H_gtk_spin_button_get_wrap "gboolean gtk_spin_button_get_wrap(GtkSpinButton* spin_button)" Xen_check_type(Xen_is_GtkSpinButton_(spin_button), spin_button, 1, "gtk_spin_button_get_wrap", "GtkSpinButton*"); return(C_to_Xen_gboolean(gtk_spin_button_get_wrap(Xen_to_C_GtkSpinButton_(spin_button)))); } static Xen gxg_gtk_spin_button_set_snap_to_ticks(Xen spin_button, Xen snap_to_ticks) { #define H_gtk_spin_button_set_snap_to_ticks "void gtk_spin_button_set_snap_to_ticks(GtkSpinButton* spin_button, \ gboolean snap_to_ticks)" Xen_check_type(Xen_is_GtkSpinButton_(spin_button), spin_button, 1, "gtk_spin_button_set_snap_to_ticks", "GtkSpinButton*"); Xen_check_type(Xen_is_gboolean(snap_to_ticks), snap_to_ticks, 2, "gtk_spin_button_set_snap_to_ticks", "gboolean"); gtk_spin_button_set_snap_to_ticks(Xen_to_C_GtkSpinButton_(spin_button), Xen_to_C_gboolean(snap_to_ticks)); return(Xen_false); } static Xen gxg_gtk_spin_button_get_snap_to_ticks(Xen spin_button) { #define H_gtk_spin_button_get_snap_to_ticks "gboolean gtk_spin_button_get_snap_to_ticks(GtkSpinButton* spin_button)" Xen_check_type(Xen_is_GtkSpinButton_(spin_button), spin_button, 1, "gtk_spin_button_get_snap_to_ticks", "GtkSpinButton*"); return(C_to_Xen_gboolean(gtk_spin_button_get_snap_to_ticks(Xen_to_C_GtkSpinButton_(spin_button)))); } static Xen gxg_gtk_spin_button_update(Xen spin_button) { #define H_gtk_spin_button_update "void gtk_spin_button_update(GtkSpinButton* spin_button)" Xen_check_type(Xen_is_GtkSpinButton_(spin_button), spin_button, 1, "gtk_spin_button_update", "GtkSpinButton*"); gtk_spin_button_update(Xen_to_C_GtkSpinButton_(spin_button)); return(Xen_false); } static Xen gxg_gtk_statusbar_new(void) { #define H_gtk_statusbar_new "GtkWidget* gtk_statusbar_new( void)" return(C_to_Xen_GtkWidget_(gtk_statusbar_new())); } static Xen gxg_gtk_statusbar_get_context_id(Xen statusbar, Xen context_description) { #define H_gtk_statusbar_get_context_id "guint gtk_statusbar_get_context_id(GtkStatusbar* statusbar, \ gchar* context_description)" Xen_check_type(Xen_is_GtkStatusbar_(statusbar), statusbar, 1, "gtk_statusbar_get_context_id", "GtkStatusbar*"); Xen_check_type(Xen_is_gchar_(context_description), context_description, 2, "gtk_statusbar_get_context_id", "gchar*"); return(C_to_Xen_guint(gtk_statusbar_get_context_id(Xen_to_C_GtkStatusbar_(statusbar), Xen_to_C_gchar_(context_description)))); } static Xen gxg_gtk_statusbar_push(Xen statusbar, Xen context_id, Xen text) { #define H_gtk_statusbar_push "guint gtk_statusbar_push(GtkStatusbar* statusbar, guint context_id, gchar* text)" Xen_check_type(Xen_is_GtkStatusbar_(statusbar), statusbar, 1, "gtk_statusbar_push", "GtkStatusbar*"); Xen_check_type(Xen_is_guint(context_id), context_id, 2, "gtk_statusbar_push", "guint"); Xen_check_type(Xen_is_gchar_(text), text, 3, "gtk_statusbar_push", "gchar*"); return(C_to_Xen_guint(gtk_statusbar_push(Xen_to_C_GtkStatusbar_(statusbar), Xen_to_C_guint(context_id), Xen_to_C_gchar_(text)))); } static Xen gxg_gtk_statusbar_pop(Xen statusbar, Xen context_id) { #define H_gtk_statusbar_pop "void gtk_statusbar_pop(GtkStatusbar* statusbar, guint context_id)" Xen_check_type(Xen_is_GtkStatusbar_(statusbar), statusbar, 1, "gtk_statusbar_pop", "GtkStatusbar*"); Xen_check_type(Xen_is_guint(context_id), context_id, 2, "gtk_statusbar_pop", "guint"); gtk_statusbar_pop(Xen_to_C_GtkStatusbar_(statusbar), Xen_to_C_guint(context_id)); return(Xen_false); } static Xen gxg_gtk_statusbar_remove(Xen statusbar, Xen context_id, Xen message_id) { #define H_gtk_statusbar_remove "void gtk_statusbar_remove(GtkStatusbar* statusbar, guint context_id, \ guint message_id)" Xen_check_type(Xen_is_GtkStatusbar_(statusbar), statusbar, 1, "gtk_statusbar_remove", "GtkStatusbar*"); Xen_check_type(Xen_is_guint(context_id), context_id, 2, "gtk_statusbar_remove", "guint"); Xen_check_type(Xen_is_guint(message_id), message_id, 3, "gtk_statusbar_remove", "guint"); gtk_statusbar_remove(Xen_to_C_GtkStatusbar_(statusbar), Xen_to_C_guint(context_id), Xen_to_C_guint(message_id)); return(Xen_false); } static Xen gxg_gtk_text_buffer_new(Xen table) { #define H_gtk_text_buffer_new "GtkTextBuffer* gtk_text_buffer_new(GtkTextTagTable* table)" Xen_check_type(Xen_is_GtkTextTagTable_(table) || Xen_is_false(table), table, 1, "gtk_text_buffer_new", "GtkTextTagTable*"); return(C_to_Xen_GtkTextBuffer_(gtk_text_buffer_new(Xen_to_C_GtkTextTagTable_(table)))); } static Xen gxg_gtk_text_buffer_get_line_count(Xen buffer) { #define H_gtk_text_buffer_get_line_count "gint gtk_text_buffer_get_line_count(GtkTextBuffer* buffer)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_get_line_count", "GtkTextBuffer*"); return(C_to_Xen_gint(gtk_text_buffer_get_line_count(Xen_to_C_GtkTextBuffer_(buffer)))); } static Xen gxg_gtk_text_buffer_get_char_count(Xen buffer) { #define H_gtk_text_buffer_get_char_count "gint gtk_text_buffer_get_char_count(GtkTextBuffer* buffer)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_get_char_count", "GtkTextBuffer*"); return(C_to_Xen_gint(gtk_text_buffer_get_char_count(Xen_to_C_GtkTextBuffer_(buffer)))); } static Xen gxg_gtk_text_buffer_get_tag_table(Xen buffer) { #define H_gtk_text_buffer_get_tag_table "GtkTextTagTable* gtk_text_buffer_get_tag_table(GtkTextBuffer* buffer)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_get_tag_table", "GtkTextBuffer*"); return(C_to_Xen_GtkTextTagTable_(gtk_text_buffer_get_tag_table(Xen_to_C_GtkTextBuffer_(buffer)))); } static Xen gxg_gtk_text_buffer_set_text(Xen buffer, Xen text, Xen len) { #define H_gtk_text_buffer_set_text "void gtk_text_buffer_set_text(GtkTextBuffer* buffer, gchar* text, \ gint len)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_set_text", "GtkTextBuffer*"); Xen_check_type(Xen_is_gchar_(text), text, 2, "gtk_text_buffer_set_text", "gchar*"); Xen_check_type(Xen_is_gint(len), len, 3, "gtk_text_buffer_set_text", "gint"); gtk_text_buffer_set_text(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_gchar_(text), Xen_to_C_gint(len)); return(Xen_false); } static Xen gxg_gtk_text_buffer_insert(Xen buffer, Xen iter, Xen text, Xen len) { #define H_gtk_text_buffer_insert "void gtk_text_buffer_insert(GtkTextBuffer* buffer, GtkTextIter* iter, \ gchar* text, gint len)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_insert", "GtkTextBuffer*"); Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 2, "gtk_text_buffer_insert", "GtkTextIter*"); Xen_check_type(Xen_is_gchar_(text), text, 3, "gtk_text_buffer_insert", "gchar*"); Xen_check_type(Xen_is_gint(len), len, 4, "gtk_text_buffer_insert", "gint"); gtk_text_buffer_insert(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_GtkTextIter_(iter), Xen_to_C_gchar_(text), Xen_to_C_gint(len)); return(Xen_false); } static Xen gxg_gtk_text_buffer_insert_at_cursor(Xen buffer, Xen text, Xen len) { #define H_gtk_text_buffer_insert_at_cursor "void gtk_text_buffer_insert_at_cursor(GtkTextBuffer* buffer, \ gchar* text, gint len)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_insert_at_cursor", "GtkTextBuffer*"); Xen_check_type(Xen_is_gchar_(text), text, 2, "gtk_text_buffer_insert_at_cursor", "gchar*"); Xen_check_type(Xen_is_gint(len), len, 3, "gtk_text_buffer_insert_at_cursor", "gint"); gtk_text_buffer_insert_at_cursor(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_gchar_(text), Xen_to_C_gint(len)); return(Xen_false); } static Xen gxg_gtk_text_buffer_insert_interactive(Xen buffer, Xen iter, Xen text, Xen len, Xen default_editable) { #define H_gtk_text_buffer_insert_interactive "gboolean gtk_text_buffer_insert_interactive(GtkTextBuffer* buffer, \ GtkTextIter* iter, gchar* text, gint len, gboolean default_editable)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_insert_interactive", "GtkTextBuffer*"); Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 2, "gtk_text_buffer_insert_interactive", "GtkTextIter*"); Xen_check_type(Xen_is_gchar_(text), text, 3, "gtk_text_buffer_insert_interactive", "gchar*"); Xen_check_type(Xen_is_gint(len), len, 4, "gtk_text_buffer_insert_interactive", "gint"); Xen_check_type(Xen_is_gboolean(default_editable), default_editable, 5, "gtk_text_buffer_insert_interactive", "gboolean"); return(C_to_Xen_gboolean(gtk_text_buffer_insert_interactive(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_GtkTextIter_(iter), Xen_to_C_gchar_(text), Xen_to_C_gint(len), Xen_to_C_gboolean(default_editable)))); } static Xen gxg_gtk_text_buffer_insert_interactive_at_cursor(Xen buffer, Xen text, Xen len, Xen default_editable) { #define H_gtk_text_buffer_insert_interactive_at_cursor "gboolean gtk_text_buffer_insert_interactive_at_cursor(GtkTextBuffer* buffer, \ gchar* text, gint len, gboolean default_editable)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_insert_interactive_at_cursor", "GtkTextBuffer*"); Xen_check_type(Xen_is_gchar_(text), text, 2, "gtk_text_buffer_insert_interactive_at_cursor", "gchar*"); Xen_check_type(Xen_is_gint(len), len, 3, "gtk_text_buffer_insert_interactive_at_cursor", "gint"); Xen_check_type(Xen_is_gboolean(default_editable), default_editable, 4, "gtk_text_buffer_insert_interactive_at_cursor", "gboolean"); return(C_to_Xen_gboolean(gtk_text_buffer_insert_interactive_at_cursor(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_gchar_(text), Xen_to_C_gint(len), Xen_to_C_gboolean(default_editable)))); } static Xen gxg_gtk_text_buffer_insert_range(Xen buffer, Xen iter, Xen start, Xen end) { #define H_gtk_text_buffer_insert_range "void gtk_text_buffer_insert_range(GtkTextBuffer* buffer, GtkTextIter* iter, \ GtkTextIter* start, GtkTextIter* end)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_insert_range", "GtkTextBuffer*"); Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 2, "gtk_text_buffer_insert_range", "GtkTextIter*"); Xen_check_type(Xen_is_GtkTextIter_(start), start, 3, "gtk_text_buffer_insert_range", "GtkTextIter*"); Xen_check_type(Xen_is_GtkTextIter_(end), end, 4, "gtk_text_buffer_insert_range", "GtkTextIter*"); gtk_text_buffer_insert_range(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_GtkTextIter_(iter), Xen_to_C_GtkTextIter_(start), Xen_to_C_GtkTextIter_(end)); return(Xen_false); } static Xen gxg_gtk_text_buffer_insert_range_interactive(Xen buffer, Xen iter, Xen start, Xen end, Xen default_editable) { #define H_gtk_text_buffer_insert_range_interactive "gboolean gtk_text_buffer_insert_range_interactive(GtkTextBuffer* buffer, \ GtkTextIter* iter, GtkTextIter* start, GtkTextIter* end, gboolean default_editable)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_insert_range_interactive", "GtkTextBuffer*"); Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 2, "gtk_text_buffer_insert_range_interactive", "GtkTextIter*"); Xen_check_type(Xen_is_GtkTextIter_(start), start, 3, "gtk_text_buffer_insert_range_interactive", "GtkTextIter*"); Xen_check_type(Xen_is_GtkTextIter_(end), end, 4, "gtk_text_buffer_insert_range_interactive", "GtkTextIter*"); Xen_check_type(Xen_is_gboolean(default_editable), default_editable, 5, "gtk_text_buffer_insert_range_interactive", "gboolean"); return(C_to_Xen_gboolean(gtk_text_buffer_insert_range_interactive(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_GtkTextIter_(iter), Xen_to_C_GtkTextIter_(start), Xen_to_C_GtkTextIter_(end), Xen_to_C_gboolean(default_editable)))); } static Xen gxg_gtk_text_buffer_insert_with_tags(Xen buffer, Xen iter, Xen text, Xen len, Xen tags) { #define H_gtk_text_buffer_insert_with_tags "void gtk_text_buffer_insert_with_tags(GtkTextBuffer* buffer, \ GtkTextIter* iter, gchar* text, gint len, etc tags)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_insert_with_tags", "GtkTextBuffer*"); Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 2, "gtk_text_buffer_insert_with_tags", "GtkTextIter*"); Xen_check_type(Xen_is_gchar_(text), text, 3, "gtk_text_buffer_insert_with_tags", "gchar*"); Xen_check_type(Xen_is_gint(len), len, 4, "gtk_text_buffer_insert_with_tags", "gint"); Xen_check_type(Xen_is_etc(tags), tags, 5, "gtk_text_buffer_insert_with_tags", "etc"); { int etc_len = 0; GtkTextBuffer* p_arg0; GtkTextIter* p_arg1; gchar* p_arg2; gint p_arg3; if (Xen_is_list(tags)) etc_len = Xen_list_length(tags); if (etc_len < 1) Xen_out_of_range_error("gtk_text_buffer_insert_with_tags", 4, tags, "... list must have at least 1 entry"); if (etc_len > 6) Xen_out_of_range_error("gtk_text_buffer_insert_with_tags", 4, tags, "... list too long (max len: 6)"); p_arg0 = Xen_to_C_GtkTextBuffer_(buffer); p_arg1 = Xen_to_C_GtkTextIter_(iter); p_arg2 = Xen_to_C_gchar_(text); p_arg3 = Xen_to_C_gint(len); switch (etc_len) { case 1: gtk_text_buffer_insert_with_tags(p_arg0, p_arg1, p_arg2, p_arg3, XLT(tags, 0), NULL); break; case 2: gtk_text_buffer_insert_with_tags(p_arg0, p_arg1, p_arg2, p_arg3, XLT(tags, 0), XLT(tags, 1), NULL); break; case 3: gtk_text_buffer_insert_with_tags(p_arg0, p_arg1, p_arg2, p_arg3, XLT(tags, 0), XLT(tags, 1), XLT(tags, 2), NULL); break; case 4: gtk_text_buffer_insert_with_tags(p_arg0, p_arg1, p_arg2, p_arg3, XLT(tags, 0), XLT(tags, 1), XLT(tags, 2), XLT(tags, 3), NULL); break; case 5: gtk_text_buffer_insert_with_tags(p_arg0, p_arg1, p_arg2, p_arg3, XLT(tags, 0), XLT(tags, 1), XLT(tags, 2), XLT(tags, 3), XLT(tags, 4), NULL); break; case 6: gtk_text_buffer_insert_with_tags(p_arg0, p_arg1, p_arg2, p_arg3, XLT(tags, 0), XLT(tags, 1), XLT(tags, 2), XLT(tags, 3), XLT(tags, 4), XLT(tags, 5), NULL); break; } return(Xen_false); } } static Xen gxg_gtk_text_buffer_insert_with_tags_by_name(Xen buffer, Xen iter, Xen text, Xen len, Xen tags) { #define H_gtk_text_buffer_insert_with_tags_by_name "void gtk_text_buffer_insert_with_tags_by_name(GtkTextBuffer* buffer, \ GtkTextIter* iter, gchar* text, gint len, etc tags)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_insert_with_tags_by_name", "GtkTextBuffer*"); Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 2, "gtk_text_buffer_insert_with_tags_by_name", "GtkTextIter*"); Xen_check_type(Xen_is_gchar_(text), text, 3, "gtk_text_buffer_insert_with_tags_by_name", "gchar*"); Xen_check_type(Xen_is_gint(len), len, 4, "gtk_text_buffer_insert_with_tags_by_name", "gint"); Xen_check_type(Xen_is_etc(tags), tags, 5, "gtk_text_buffer_insert_with_tags_by_name", "etc"); { int etc_len = 0; GtkTextBuffer* p_arg0; GtkTextIter* p_arg1; gchar* p_arg2; gint p_arg3; if (Xen_is_list(tags)) etc_len = Xen_list_length(tags); if (etc_len < 1) Xen_out_of_range_error("gtk_text_buffer_insert_with_tags_by_name", 4, tags, "... list must have at least 1 entry"); if (etc_len > 6) Xen_out_of_range_error("gtk_text_buffer_insert_with_tags_by_name", 4, tags, "... list too long (max len: 6)"); if ((etc_len % 2) != 0) Xen_out_of_range_error("gtk_text_buffer_insert_with_tags_by_name", 4, tags, "... list len must be multiple of 2"); p_arg0 = Xen_to_C_GtkTextBuffer_(buffer); p_arg1 = Xen_to_C_GtkTextIter_(iter); p_arg2 = Xen_to_C_gchar_(text); p_arg3 = Xen_to_C_gint(len); switch (etc_len) { case 1: gtk_text_buffer_insert_with_tags_by_name(p_arg0, p_arg1, p_arg2, p_arg3, XLS(tags, 0), NULL); break; case 3: gtk_text_buffer_insert_with_tags_by_name(p_arg0, p_arg1, p_arg2, p_arg3, XLS(tags, 0), XLI(tags, 1), XLS(tags, 2), NULL); break; case 5: gtk_text_buffer_insert_with_tags_by_name(p_arg0, p_arg1, p_arg2, p_arg3, XLS(tags, 0), XLI(tags, 1), XLS(tags, 2), XLI(tags, 3), XLS(tags, 4), NULL); break; } return(Xen_false); } } static Xen gxg_gtk_text_buffer_delete(Xen buffer, Xen start, Xen end) { #define H_gtk_text_buffer_delete "void gtk_text_buffer_delete(GtkTextBuffer* buffer, GtkTextIter* start, \ GtkTextIter* end)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_delete", "GtkTextBuffer*"); Xen_check_type(Xen_is_GtkTextIter_(start), start, 2, "gtk_text_buffer_delete", "GtkTextIter*"); Xen_check_type(Xen_is_GtkTextIter_(end), end, 3, "gtk_text_buffer_delete", "GtkTextIter*"); gtk_text_buffer_delete(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_GtkTextIter_(start), Xen_to_C_GtkTextIter_(end)); return(Xen_false); } static Xen gxg_gtk_text_buffer_delete_interactive(Xen buffer, Xen start_iter, Xen end_iter, Xen default_editable) { #define H_gtk_text_buffer_delete_interactive "gboolean gtk_text_buffer_delete_interactive(GtkTextBuffer* buffer, \ GtkTextIter* start_iter, GtkTextIter* end_iter, gboolean default_editable)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_delete_interactive", "GtkTextBuffer*"); Xen_check_type(Xen_is_GtkTextIter_(start_iter), start_iter, 2, "gtk_text_buffer_delete_interactive", "GtkTextIter*"); Xen_check_type(Xen_is_GtkTextIter_(end_iter), end_iter, 3, "gtk_text_buffer_delete_interactive", "GtkTextIter*"); Xen_check_type(Xen_is_gboolean(default_editable), default_editable, 4, "gtk_text_buffer_delete_interactive", "gboolean"); return(C_to_Xen_gboolean(gtk_text_buffer_delete_interactive(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_GtkTextIter_(start_iter), Xen_to_C_GtkTextIter_(end_iter), Xen_to_C_gboolean(default_editable)))); } static Xen gxg_gtk_text_buffer_get_text(Xen buffer, Xen start, Xen end, Xen include_hidden_chars) { #define H_gtk_text_buffer_get_text "gchar* gtk_text_buffer_get_text(GtkTextBuffer* buffer, GtkTextIter* start, \ GtkTextIter* end, gboolean include_hidden_chars)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_get_text", "GtkTextBuffer*"); Xen_check_type(Xen_is_GtkTextIter_(start), start, 2, "gtk_text_buffer_get_text", "GtkTextIter*"); Xen_check_type(Xen_is_GtkTextIter_(end), end, 3, "gtk_text_buffer_get_text", "GtkTextIter*"); Xen_check_type(Xen_is_gboolean(include_hidden_chars), include_hidden_chars, 4, "gtk_text_buffer_get_text", "gboolean"); { gchar* result; Xen rtn; result = gtk_text_buffer_get_text(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_GtkTextIter_(start), Xen_to_C_GtkTextIter_(end), Xen_to_C_gboolean(include_hidden_chars)); rtn = C_to_Xen_gchar_(result); g_free(result); return(rtn); } } static Xen gxg_gtk_text_buffer_get_slice(Xen buffer, Xen start, Xen end, Xen include_hidden_chars) { #define H_gtk_text_buffer_get_slice "gchar* gtk_text_buffer_get_slice(GtkTextBuffer* buffer, GtkTextIter* start, \ GtkTextIter* end, gboolean include_hidden_chars)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_get_slice", "GtkTextBuffer*"); Xen_check_type(Xen_is_GtkTextIter_(start), start, 2, "gtk_text_buffer_get_slice", "GtkTextIter*"); Xen_check_type(Xen_is_GtkTextIter_(end), end, 3, "gtk_text_buffer_get_slice", "GtkTextIter*"); Xen_check_type(Xen_is_gboolean(include_hidden_chars), include_hidden_chars, 4, "gtk_text_buffer_get_slice", "gboolean"); { gchar* result; Xen rtn; result = gtk_text_buffer_get_slice(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_GtkTextIter_(start), Xen_to_C_GtkTextIter_(end), Xen_to_C_gboolean(include_hidden_chars)); rtn = C_to_Xen_gchar_(result); g_free(result); return(rtn); } } static Xen gxg_gtk_text_buffer_insert_pixbuf(Xen buffer, Xen iter, Xen pixbuf) { #define H_gtk_text_buffer_insert_pixbuf "void gtk_text_buffer_insert_pixbuf(GtkTextBuffer* buffer, \ GtkTextIter* iter, GdkPixbuf* pixbuf)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_insert_pixbuf", "GtkTextBuffer*"); Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 2, "gtk_text_buffer_insert_pixbuf", "GtkTextIter*"); Xen_check_type(Xen_is_GdkPixbuf_(pixbuf), pixbuf, 3, "gtk_text_buffer_insert_pixbuf", "GdkPixbuf*"); gtk_text_buffer_insert_pixbuf(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_GtkTextIter_(iter), Xen_to_C_GdkPixbuf_(pixbuf)); return(Xen_false); } static Xen gxg_gtk_text_buffer_insert_child_anchor(Xen buffer, Xen iter, Xen anchor) { #define H_gtk_text_buffer_insert_child_anchor "void gtk_text_buffer_insert_child_anchor(GtkTextBuffer* buffer, \ GtkTextIter* iter, GtkTextChildAnchor* anchor)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_insert_child_anchor", "GtkTextBuffer*"); Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 2, "gtk_text_buffer_insert_child_anchor", "GtkTextIter*"); Xen_check_type(Xen_is_GtkTextChildAnchor_(anchor), anchor, 3, "gtk_text_buffer_insert_child_anchor", "GtkTextChildAnchor*"); gtk_text_buffer_insert_child_anchor(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_GtkTextIter_(iter), Xen_to_C_GtkTextChildAnchor_(anchor)); return(Xen_false); } static Xen gxg_gtk_text_buffer_create_child_anchor(Xen buffer, Xen iter) { #define H_gtk_text_buffer_create_child_anchor "GtkTextChildAnchor* gtk_text_buffer_create_child_anchor(GtkTextBuffer* buffer, \ GtkTextIter* iter)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_create_child_anchor", "GtkTextBuffer*"); Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 2, "gtk_text_buffer_create_child_anchor", "GtkTextIter*"); return(C_to_Xen_GtkTextChildAnchor_(gtk_text_buffer_create_child_anchor(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_GtkTextIter_(iter)))); } static Xen gxg_gtk_text_buffer_create_mark(Xen buffer, Xen mark_name, Xen where, Xen left_gravity) { #define H_gtk_text_buffer_create_mark "GtkTextMark* gtk_text_buffer_create_mark(GtkTextBuffer* buffer, \ gchar* mark_name, GtkTextIter* where, gboolean left_gravity)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_create_mark", "GtkTextBuffer*"); Xen_check_type(Xen_is_gchar_(mark_name), mark_name, 2, "gtk_text_buffer_create_mark", "gchar*"); Xen_check_type(Xen_is_GtkTextIter_(where), where, 3, "gtk_text_buffer_create_mark", "GtkTextIter*"); Xen_check_type(Xen_is_gboolean(left_gravity), left_gravity, 4, "gtk_text_buffer_create_mark", "gboolean"); return(C_to_Xen_GtkTextMark_(gtk_text_buffer_create_mark(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_gchar_(mark_name), Xen_to_C_GtkTextIter_(where), Xen_to_C_gboolean(left_gravity)))); } static Xen gxg_gtk_text_buffer_move_mark(Xen buffer, Xen mark, Xen where) { #define H_gtk_text_buffer_move_mark "void gtk_text_buffer_move_mark(GtkTextBuffer* buffer, GtkTextMark* mark, \ GtkTextIter* where)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_move_mark", "GtkTextBuffer*"); Xen_check_type(Xen_is_GtkTextMark_(mark), mark, 2, "gtk_text_buffer_move_mark", "GtkTextMark*"); Xen_check_type(Xen_is_GtkTextIter_(where), where, 3, "gtk_text_buffer_move_mark", "GtkTextIter*"); gtk_text_buffer_move_mark(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_GtkTextMark_(mark), Xen_to_C_GtkTextIter_(where)); return(Xen_false); } static Xen gxg_gtk_text_buffer_delete_mark(Xen buffer, Xen mark) { #define H_gtk_text_buffer_delete_mark "void gtk_text_buffer_delete_mark(GtkTextBuffer* buffer, GtkTextMark* mark)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_delete_mark", "GtkTextBuffer*"); Xen_check_type(Xen_is_GtkTextMark_(mark), mark, 2, "gtk_text_buffer_delete_mark", "GtkTextMark*"); gtk_text_buffer_delete_mark(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_GtkTextMark_(mark)); return(Xen_false); } static Xen gxg_gtk_text_buffer_get_mark(Xen buffer, Xen name) { #define H_gtk_text_buffer_get_mark "GtkTextMark* gtk_text_buffer_get_mark(GtkTextBuffer* buffer, gchar* name)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_get_mark", "GtkTextBuffer*"); Xen_check_type(Xen_is_gchar_(name), name, 2, "gtk_text_buffer_get_mark", "gchar*"); return(C_to_Xen_GtkTextMark_(gtk_text_buffer_get_mark(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_gchar_(name)))); } static Xen gxg_gtk_text_buffer_move_mark_by_name(Xen buffer, Xen name, Xen where) { #define H_gtk_text_buffer_move_mark_by_name "void gtk_text_buffer_move_mark_by_name(GtkTextBuffer* buffer, \ gchar* name, GtkTextIter* where)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_move_mark_by_name", "GtkTextBuffer*"); Xen_check_type(Xen_is_gchar_(name), name, 2, "gtk_text_buffer_move_mark_by_name", "gchar*"); Xen_check_type(Xen_is_GtkTextIter_(where), where, 3, "gtk_text_buffer_move_mark_by_name", "GtkTextIter*"); gtk_text_buffer_move_mark_by_name(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_gchar_(name), Xen_to_C_GtkTextIter_(where)); return(Xen_false); } static Xen gxg_gtk_text_buffer_delete_mark_by_name(Xen buffer, Xen name) { #define H_gtk_text_buffer_delete_mark_by_name "void gtk_text_buffer_delete_mark_by_name(GtkTextBuffer* buffer, \ gchar* name)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_delete_mark_by_name", "GtkTextBuffer*"); Xen_check_type(Xen_is_gchar_(name), name, 2, "gtk_text_buffer_delete_mark_by_name", "gchar*"); gtk_text_buffer_delete_mark_by_name(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_gchar_(name)); return(Xen_false); } static Xen gxg_gtk_text_buffer_get_insert(Xen buffer) { #define H_gtk_text_buffer_get_insert "GtkTextMark* gtk_text_buffer_get_insert(GtkTextBuffer* buffer)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_get_insert", "GtkTextBuffer*"); return(C_to_Xen_GtkTextMark_(gtk_text_buffer_get_insert(Xen_to_C_GtkTextBuffer_(buffer)))); } static Xen gxg_gtk_text_buffer_get_selection_bound(Xen buffer) { #define H_gtk_text_buffer_get_selection_bound "GtkTextMark* gtk_text_buffer_get_selection_bound(GtkTextBuffer* buffer)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_get_selection_bound", "GtkTextBuffer*"); return(C_to_Xen_GtkTextMark_(gtk_text_buffer_get_selection_bound(Xen_to_C_GtkTextBuffer_(buffer)))); } static Xen gxg_gtk_text_buffer_place_cursor(Xen buffer, Xen where) { #define H_gtk_text_buffer_place_cursor "void gtk_text_buffer_place_cursor(GtkTextBuffer* buffer, GtkTextIter* where)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_place_cursor", "GtkTextBuffer*"); Xen_check_type(Xen_is_GtkTextIter_(where), where, 2, "gtk_text_buffer_place_cursor", "GtkTextIter*"); gtk_text_buffer_place_cursor(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_GtkTextIter_(where)); return(Xen_false); } static Xen gxg_gtk_text_buffer_apply_tag(Xen buffer, Xen tag, Xen start, Xen end) { #define H_gtk_text_buffer_apply_tag "void gtk_text_buffer_apply_tag(GtkTextBuffer* buffer, GtkTextTag* tag, \ GtkTextIter* start, GtkTextIter* end)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_apply_tag", "GtkTextBuffer*"); Xen_check_type(Xen_is_GtkTextTag_(tag), tag, 2, "gtk_text_buffer_apply_tag", "GtkTextTag*"); Xen_check_type(Xen_is_GtkTextIter_(start), start, 3, "gtk_text_buffer_apply_tag", "GtkTextIter*"); Xen_check_type(Xen_is_GtkTextIter_(end), end, 4, "gtk_text_buffer_apply_tag", "GtkTextIter*"); gtk_text_buffer_apply_tag(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_GtkTextTag_(tag), Xen_to_C_GtkTextIter_(start), Xen_to_C_GtkTextIter_(end)); return(Xen_false); } static Xen gxg_gtk_text_buffer_remove_tag(Xen buffer, Xen tag, Xen start, Xen end) { #define H_gtk_text_buffer_remove_tag "void gtk_text_buffer_remove_tag(GtkTextBuffer* buffer, GtkTextTag* tag, \ GtkTextIter* start, GtkTextIter* end)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_remove_tag", "GtkTextBuffer*"); Xen_check_type(Xen_is_GtkTextTag_(tag), tag, 2, "gtk_text_buffer_remove_tag", "GtkTextTag*"); Xen_check_type(Xen_is_GtkTextIter_(start), start, 3, "gtk_text_buffer_remove_tag", "GtkTextIter*"); Xen_check_type(Xen_is_GtkTextIter_(end), end, 4, "gtk_text_buffer_remove_tag", "GtkTextIter*"); gtk_text_buffer_remove_tag(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_GtkTextTag_(tag), Xen_to_C_GtkTextIter_(start), Xen_to_C_GtkTextIter_(end)); return(Xen_false); } static Xen gxg_gtk_text_buffer_apply_tag_by_name(Xen buffer, Xen name, Xen start, Xen end) { #define H_gtk_text_buffer_apply_tag_by_name "void gtk_text_buffer_apply_tag_by_name(GtkTextBuffer* buffer, \ gchar* name, GtkTextIter* start, GtkTextIter* end)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_apply_tag_by_name", "GtkTextBuffer*"); Xen_check_type(Xen_is_gchar_(name), name, 2, "gtk_text_buffer_apply_tag_by_name", "gchar*"); Xen_check_type(Xen_is_GtkTextIter_(start), start, 3, "gtk_text_buffer_apply_tag_by_name", "GtkTextIter*"); Xen_check_type(Xen_is_GtkTextIter_(end), end, 4, "gtk_text_buffer_apply_tag_by_name", "GtkTextIter*"); gtk_text_buffer_apply_tag_by_name(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_gchar_(name), Xen_to_C_GtkTextIter_(start), Xen_to_C_GtkTextIter_(end)); return(Xen_false); } static Xen gxg_gtk_text_buffer_remove_tag_by_name(Xen buffer, Xen name, Xen start, Xen end) { #define H_gtk_text_buffer_remove_tag_by_name "void gtk_text_buffer_remove_tag_by_name(GtkTextBuffer* buffer, \ gchar* name, GtkTextIter* start, GtkTextIter* end)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_remove_tag_by_name", "GtkTextBuffer*"); Xen_check_type(Xen_is_gchar_(name), name, 2, "gtk_text_buffer_remove_tag_by_name", "gchar*"); Xen_check_type(Xen_is_GtkTextIter_(start), start, 3, "gtk_text_buffer_remove_tag_by_name", "GtkTextIter*"); Xen_check_type(Xen_is_GtkTextIter_(end), end, 4, "gtk_text_buffer_remove_tag_by_name", "GtkTextIter*"); gtk_text_buffer_remove_tag_by_name(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_gchar_(name), Xen_to_C_GtkTextIter_(start), Xen_to_C_GtkTextIter_(end)); return(Xen_false); } static Xen gxg_gtk_text_buffer_remove_all_tags(Xen buffer, Xen start, Xen end) { #define H_gtk_text_buffer_remove_all_tags "void gtk_text_buffer_remove_all_tags(GtkTextBuffer* buffer, \ GtkTextIter* start, GtkTextIter* end)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_remove_all_tags", "GtkTextBuffer*"); Xen_check_type(Xen_is_GtkTextIter_(start), start, 2, "gtk_text_buffer_remove_all_tags", "GtkTextIter*"); Xen_check_type(Xen_is_GtkTextIter_(end), end, 3, "gtk_text_buffer_remove_all_tags", "GtkTextIter*"); gtk_text_buffer_remove_all_tags(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_GtkTextIter_(start), Xen_to_C_GtkTextIter_(end)); return(Xen_false); } static Xen gxg_gtk_text_buffer_create_tag(Xen buffer, Xen tag_name, Xen tags) { #define H_gtk_text_buffer_create_tag "GtkTextTag* gtk_text_buffer_create_tag(GtkTextBuffer* buffer, \ gchar* tag_name, etc tags)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_create_tag", "GtkTextBuffer*"); Xen_check_type(Xen_is_gchar_(tag_name), tag_name, 2, "gtk_text_buffer_create_tag", "gchar*"); if (!Xen_is_bound(tags)) tags = Xen_false; else Xen_check_type(Xen_is_etc(tags), tags, 3, "gtk_text_buffer_create_tag", "etc"); { int etc_len = 0; GtkTextTag* result = NULL; GtkTextBuffer* p_arg0; gchar* p_arg1; if (Xen_is_list(tags)) etc_len = Xen_list_length(tags); if (etc_len > 6) Xen_out_of_range_error("gtk_text_buffer_create_tag", 2, tags, "... list too long (max len: 6)"); if ((etc_len % 2) != 0) Xen_out_of_range_error("gtk_text_buffer_create_tag", 2, tags, "... list len must be multiple of 2"); p_arg0 = Xen_to_C_GtkTextBuffer_(buffer); p_arg1 = Xen_to_C_gchar_(tag_name); switch (etc_len) { case 0: result = gtk_text_buffer_create_tag(p_arg0, p_arg1, NULL); break; case 2: result = gtk_text_buffer_create_tag(p_arg0, p_arg1, XLS(tags, 0), XLA(tags, 1), NULL); break; case 4: result = gtk_text_buffer_create_tag(p_arg0, p_arg1, XLS(tags, 0), XLA(tags, 1), XLS(tags, 2), XLA(tags, 3), NULL); break; case 6: result = gtk_text_buffer_create_tag(p_arg0, p_arg1, XLS(tags, 0), XLA(tags, 1), XLS(tags, 2), XLA(tags, 3), XLS(tags, 4), XLA(tags, 5), NULL); break; } return(C_to_Xen_GtkTextTag_(result)); } } static Xen gxg_gtk_text_buffer_get_iter_at_line_offset(Xen buffer, Xen iter, Xen line_number, Xen char_offset) { #define H_gtk_text_buffer_get_iter_at_line_offset "void gtk_text_buffer_get_iter_at_line_offset(GtkTextBuffer* buffer, \ GtkTextIter* iter, gint line_number, gint char_offset)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_get_iter_at_line_offset", "GtkTextBuffer*"); Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 2, "gtk_text_buffer_get_iter_at_line_offset", "GtkTextIter*"); Xen_check_type(Xen_is_gint(line_number), line_number, 3, "gtk_text_buffer_get_iter_at_line_offset", "gint"); Xen_check_type(Xen_is_gint(char_offset), char_offset, 4, "gtk_text_buffer_get_iter_at_line_offset", "gint"); gtk_text_buffer_get_iter_at_line_offset(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_GtkTextIter_(iter), Xen_to_C_gint(line_number), Xen_to_C_gint(char_offset)); return(Xen_false); } static Xen gxg_gtk_text_buffer_get_iter_at_line_index(Xen buffer, Xen iter, Xen line_number, Xen byte_index) { #define H_gtk_text_buffer_get_iter_at_line_index "void gtk_text_buffer_get_iter_at_line_index(GtkTextBuffer* buffer, \ GtkTextIter* iter, gint line_number, gint byte_index)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_get_iter_at_line_index", "GtkTextBuffer*"); Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 2, "gtk_text_buffer_get_iter_at_line_index", "GtkTextIter*"); Xen_check_type(Xen_is_gint(line_number), line_number, 3, "gtk_text_buffer_get_iter_at_line_index", "gint"); Xen_check_type(Xen_is_gint(byte_index), byte_index, 4, "gtk_text_buffer_get_iter_at_line_index", "gint"); gtk_text_buffer_get_iter_at_line_index(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_GtkTextIter_(iter), Xen_to_C_gint(line_number), Xen_to_C_gint(byte_index)); return(Xen_false); } static Xen gxg_gtk_text_buffer_get_iter_at_offset(Xen buffer, Xen iter, Xen char_offset) { #define H_gtk_text_buffer_get_iter_at_offset "void gtk_text_buffer_get_iter_at_offset(GtkTextBuffer* buffer, \ GtkTextIter* iter, gint char_offset)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_get_iter_at_offset", "GtkTextBuffer*"); Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 2, "gtk_text_buffer_get_iter_at_offset", "GtkTextIter*"); Xen_check_type(Xen_is_gint(char_offset), char_offset, 3, "gtk_text_buffer_get_iter_at_offset", "gint"); gtk_text_buffer_get_iter_at_offset(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_GtkTextIter_(iter), Xen_to_C_gint(char_offset)); return(Xen_false); } static Xen gxg_gtk_text_buffer_get_iter_at_line(Xen buffer, Xen iter, Xen line_number) { #define H_gtk_text_buffer_get_iter_at_line "void gtk_text_buffer_get_iter_at_line(GtkTextBuffer* buffer, \ GtkTextIter* iter, gint line_number)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_get_iter_at_line", "GtkTextBuffer*"); Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 2, "gtk_text_buffer_get_iter_at_line", "GtkTextIter*"); Xen_check_type(Xen_is_gint(line_number), line_number, 3, "gtk_text_buffer_get_iter_at_line", "gint"); gtk_text_buffer_get_iter_at_line(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_GtkTextIter_(iter), Xen_to_C_gint(line_number)); return(Xen_false); } static Xen gxg_gtk_text_buffer_get_start_iter(Xen buffer, Xen iter) { #define H_gtk_text_buffer_get_start_iter "void gtk_text_buffer_get_start_iter(GtkTextBuffer* buffer, \ GtkTextIter* iter)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_get_start_iter", "GtkTextBuffer*"); Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 2, "gtk_text_buffer_get_start_iter", "GtkTextIter*"); gtk_text_buffer_get_start_iter(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_GtkTextIter_(iter)); return(Xen_false); } static Xen gxg_gtk_text_buffer_get_end_iter(Xen buffer, Xen iter) { #define H_gtk_text_buffer_get_end_iter "void gtk_text_buffer_get_end_iter(GtkTextBuffer* buffer, GtkTextIter* iter)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_get_end_iter", "GtkTextBuffer*"); Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 2, "gtk_text_buffer_get_end_iter", "GtkTextIter*"); gtk_text_buffer_get_end_iter(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_GtkTextIter_(iter)); return(Xen_false); } static Xen gxg_gtk_text_buffer_get_bounds(Xen buffer, Xen start, Xen end) { #define H_gtk_text_buffer_get_bounds "void gtk_text_buffer_get_bounds(GtkTextBuffer* buffer, GtkTextIter* start, \ GtkTextIter* end)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_get_bounds", "GtkTextBuffer*"); Xen_check_type(Xen_is_GtkTextIter_(start), start, 2, "gtk_text_buffer_get_bounds", "GtkTextIter*"); Xen_check_type(Xen_is_GtkTextIter_(end), end, 3, "gtk_text_buffer_get_bounds", "GtkTextIter*"); gtk_text_buffer_get_bounds(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_GtkTextIter_(start), Xen_to_C_GtkTextIter_(end)); return(Xen_false); } static Xen gxg_gtk_text_buffer_get_iter_at_mark(Xen buffer, Xen iter, Xen mark) { #define H_gtk_text_buffer_get_iter_at_mark "void gtk_text_buffer_get_iter_at_mark(GtkTextBuffer* buffer, \ GtkTextIter* iter, GtkTextMark* mark)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_get_iter_at_mark", "GtkTextBuffer*"); Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 2, "gtk_text_buffer_get_iter_at_mark", "GtkTextIter*"); Xen_check_type(Xen_is_GtkTextMark_(mark), mark, 3, "gtk_text_buffer_get_iter_at_mark", "GtkTextMark*"); gtk_text_buffer_get_iter_at_mark(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_GtkTextIter_(iter), Xen_to_C_GtkTextMark_(mark)); return(Xen_false); } static Xen gxg_gtk_text_buffer_get_iter_at_child_anchor(Xen buffer, Xen iter, Xen anchor) { #define H_gtk_text_buffer_get_iter_at_child_anchor "void gtk_text_buffer_get_iter_at_child_anchor(GtkTextBuffer* buffer, \ GtkTextIter* iter, GtkTextChildAnchor* anchor)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_get_iter_at_child_anchor", "GtkTextBuffer*"); Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 2, "gtk_text_buffer_get_iter_at_child_anchor", "GtkTextIter*"); Xen_check_type(Xen_is_GtkTextChildAnchor_(anchor), anchor, 3, "gtk_text_buffer_get_iter_at_child_anchor", "GtkTextChildAnchor*"); gtk_text_buffer_get_iter_at_child_anchor(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_GtkTextIter_(iter), Xen_to_C_GtkTextChildAnchor_(anchor)); return(Xen_false); } static Xen gxg_gtk_text_buffer_get_modified(Xen buffer) { #define H_gtk_text_buffer_get_modified "gboolean gtk_text_buffer_get_modified(GtkTextBuffer* buffer)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_get_modified", "GtkTextBuffer*"); return(C_to_Xen_gboolean(gtk_text_buffer_get_modified(Xen_to_C_GtkTextBuffer_(buffer)))); } static Xen gxg_gtk_text_buffer_set_modified(Xen buffer, Xen setting) { #define H_gtk_text_buffer_set_modified "void gtk_text_buffer_set_modified(GtkTextBuffer* buffer, gboolean setting)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_set_modified", "GtkTextBuffer*"); Xen_check_type(Xen_is_gboolean(setting), setting, 2, "gtk_text_buffer_set_modified", "gboolean"); gtk_text_buffer_set_modified(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_gboolean(setting)); return(Xen_false); } static Xen gxg_gtk_text_buffer_add_selection_clipboard(Xen buffer, Xen clipboard) { #define H_gtk_text_buffer_add_selection_clipboard "void gtk_text_buffer_add_selection_clipboard(GtkTextBuffer* buffer, \ GtkClipboard* clipboard)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_add_selection_clipboard", "GtkTextBuffer*"); Xen_check_type(Xen_is_GtkClipboard_(clipboard), clipboard, 2, "gtk_text_buffer_add_selection_clipboard", "GtkClipboard*"); gtk_text_buffer_add_selection_clipboard(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_GtkClipboard_(clipboard)); return(Xen_false); } static Xen gxg_gtk_text_buffer_remove_selection_clipboard(Xen buffer, Xen clipboard) { #define H_gtk_text_buffer_remove_selection_clipboard "void gtk_text_buffer_remove_selection_clipboard(GtkTextBuffer* buffer, \ GtkClipboard* clipboard)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_remove_selection_clipboard", "GtkTextBuffer*"); Xen_check_type(Xen_is_GtkClipboard_(clipboard), clipboard, 2, "gtk_text_buffer_remove_selection_clipboard", "GtkClipboard*"); gtk_text_buffer_remove_selection_clipboard(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_GtkClipboard_(clipboard)); return(Xen_false); } static Xen gxg_gtk_text_buffer_cut_clipboard(Xen buffer, Xen clipboard, Xen default_editable) { #define H_gtk_text_buffer_cut_clipboard "void gtk_text_buffer_cut_clipboard(GtkTextBuffer* buffer, \ GtkClipboard* clipboard, gboolean default_editable)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_cut_clipboard", "GtkTextBuffer*"); Xen_check_type(Xen_is_GtkClipboard_(clipboard), clipboard, 2, "gtk_text_buffer_cut_clipboard", "GtkClipboard*"); Xen_check_type(Xen_is_gboolean(default_editable), default_editable, 3, "gtk_text_buffer_cut_clipboard", "gboolean"); gtk_text_buffer_cut_clipboard(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_GtkClipboard_(clipboard), Xen_to_C_gboolean(default_editable)); return(Xen_false); } static Xen gxg_gtk_text_buffer_copy_clipboard(Xen buffer, Xen clipboard) { #define H_gtk_text_buffer_copy_clipboard "void gtk_text_buffer_copy_clipboard(GtkTextBuffer* buffer, \ GtkClipboard* clipboard)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_copy_clipboard", "GtkTextBuffer*"); Xen_check_type(Xen_is_GtkClipboard_(clipboard), clipboard, 2, "gtk_text_buffer_copy_clipboard", "GtkClipboard*"); gtk_text_buffer_copy_clipboard(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_GtkClipboard_(clipboard)); return(Xen_false); } static Xen gxg_gtk_text_buffer_paste_clipboard(Xen buffer, Xen clipboard, Xen override_location, Xen default_editable) { #define H_gtk_text_buffer_paste_clipboard "void gtk_text_buffer_paste_clipboard(GtkTextBuffer* buffer, \ GtkClipboard* clipboard, GtkTextIter* override_location, gboolean default_editable)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_paste_clipboard", "GtkTextBuffer*"); Xen_check_type(Xen_is_GtkClipboard_(clipboard), clipboard, 2, "gtk_text_buffer_paste_clipboard", "GtkClipboard*"); Xen_check_type(Xen_is_GtkTextIter_(override_location) || Xen_is_false(override_location), override_location, 3, "gtk_text_buffer_paste_clipboard", "GtkTextIter*"); Xen_check_type(Xen_is_gboolean(default_editable), default_editable, 4, "gtk_text_buffer_paste_clipboard", "gboolean"); gtk_text_buffer_paste_clipboard(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_GtkClipboard_(clipboard), Xen_to_C_GtkTextIter_(override_location), Xen_to_C_gboolean(default_editable)); return(Xen_false); } static Xen gxg_gtk_text_buffer_get_selection_bounds(Xen buffer, Xen start, Xen end) { #define H_gtk_text_buffer_get_selection_bounds "gboolean gtk_text_buffer_get_selection_bounds(GtkTextBuffer* buffer, \ GtkTextIter* start, GtkTextIter* end)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_get_selection_bounds", "GtkTextBuffer*"); Xen_check_type(Xen_is_GtkTextIter_(start), start, 2, "gtk_text_buffer_get_selection_bounds", "GtkTextIter*"); Xen_check_type(Xen_is_GtkTextIter_(end), end, 3, "gtk_text_buffer_get_selection_bounds", "GtkTextIter*"); return(C_to_Xen_gboolean(gtk_text_buffer_get_selection_bounds(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_GtkTextIter_(start), Xen_to_C_GtkTextIter_(end)))); } static Xen gxg_gtk_text_buffer_delete_selection(Xen buffer, Xen interactive, Xen default_editable) { #define H_gtk_text_buffer_delete_selection "gboolean gtk_text_buffer_delete_selection(GtkTextBuffer* buffer, \ gboolean interactive, gboolean default_editable)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_delete_selection", "GtkTextBuffer*"); Xen_check_type(Xen_is_gboolean(interactive), interactive, 2, "gtk_text_buffer_delete_selection", "gboolean"); Xen_check_type(Xen_is_gboolean(default_editable), default_editable, 3, "gtk_text_buffer_delete_selection", "gboolean"); return(C_to_Xen_gboolean(gtk_text_buffer_delete_selection(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_gboolean(interactive), Xen_to_C_gboolean(default_editable)))); } static Xen gxg_gtk_text_buffer_begin_user_action(Xen buffer) { #define H_gtk_text_buffer_begin_user_action "void gtk_text_buffer_begin_user_action(GtkTextBuffer* buffer)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_begin_user_action", "GtkTextBuffer*"); gtk_text_buffer_begin_user_action(Xen_to_C_GtkTextBuffer_(buffer)); return(Xen_false); } static Xen gxg_gtk_text_buffer_end_user_action(Xen buffer) { #define H_gtk_text_buffer_end_user_action "void gtk_text_buffer_end_user_action(GtkTextBuffer* buffer)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_end_user_action", "GtkTextBuffer*"); gtk_text_buffer_end_user_action(Xen_to_C_GtkTextBuffer_(buffer)); return(Xen_false); } static Xen gxg_gtk_text_child_anchor_new(void) { #define H_gtk_text_child_anchor_new "GtkTextChildAnchor* gtk_text_child_anchor_new( void)" return(C_to_Xen_GtkTextChildAnchor_(gtk_text_child_anchor_new())); } static Xen gxg_gtk_text_child_anchor_get_widgets(Xen anchor) { #define H_gtk_text_child_anchor_get_widgets "GList* gtk_text_child_anchor_get_widgets(GtkTextChildAnchor* anchor)" Xen_check_type(Xen_is_GtkTextChildAnchor_(anchor), anchor, 1, "gtk_text_child_anchor_get_widgets", "GtkTextChildAnchor*"); return(C_to_Xen_GList_(gtk_text_child_anchor_get_widgets(Xen_to_C_GtkTextChildAnchor_(anchor)))); } static Xen gxg_gtk_text_child_anchor_get_deleted(Xen anchor) { #define H_gtk_text_child_anchor_get_deleted "gboolean gtk_text_child_anchor_get_deleted(GtkTextChildAnchor* anchor)" Xen_check_type(Xen_is_GtkTextChildAnchor_(anchor), anchor, 1, "gtk_text_child_anchor_get_deleted", "GtkTextChildAnchor*"); return(C_to_Xen_gboolean(gtk_text_child_anchor_get_deleted(Xen_to_C_GtkTextChildAnchor_(anchor)))); } static Xen gxg_gtk_text_iter_get_buffer(Xen iter) { #define H_gtk_text_iter_get_buffer "GtkTextBuffer* gtk_text_iter_get_buffer(GtkTextIter* iter)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_get_buffer", "GtkTextIter*"); return(C_to_Xen_GtkTextBuffer_(gtk_text_iter_get_buffer(Xen_to_C_GtkTextIter_(iter)))); } static Xen gxg_gtk_text_iter_copy(Xen iter) { #define H_gtk_text_iter_copy "GtkTextIter* gtk_text_iter_copy(GtkTextIter* iter)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_copy", "GtkTextIter*"); return(C_to_Xen_GtkTextIter_(gtk_text_iter_copy(Xen_to_C_GtkTextIter_(iter)))); } static Xen gxg_gtk_text_iter_free(Xen iter) { #define H_gtk_text_iter_free "void gtk_text_iter_free(GtkTextIter* iter)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_free", "GtkTextIter*"); gtk_text_iter_free(Xen_to_C_GtkTextIter_(iter)); return(Xen_false); } static Xen gxg_gtk_text_iter_get_offset(Xen iter) { #define H_gtk_text_iter_get_offset "gint gtk_text_iter_get_offset(GtkTextIter* iter)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_get_offset", "GtkTextIter*"); return(C_to_Xen_gint(gtk_text_iter_get_offset(Xen_to_C_GtkTextIter_(iter)))); } static Xen gxg_gtk_text_iter_get_line(Xen iter) { #define H_gtk_text_iter_get_line "gint gtk_text_iter_get_line(GtkTextIter* iter)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_get_line", "GtkTextIter*"); return(C_to_Xen_gint(gtk_text_iter_get_line(Xen_to_C_GtkTextIter_(iter)))); } static Xen gxg_gtk_text_iter_get_line_offset(Xen iter) { #define H_gtk_text_iter_get_line_offset "gint gtk_text_iter_get_line_offset(GtkTextIter* iter)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_get_line_offset", "GtkTextIter*"); return(C_to_Xen_gint(gtk_text_iter_get_line_offset(Xen_to_C_GtkTextIter_(iter)))); } static Xen gxg_gtk_text_iter_get_line_index(Xen iter) { #define H_gtk_text_iter_get_line_index "gint gtk_text_iter_get_line_index(GtkTextIter* iter)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_get_line_index", "GtkTextIter*"); return(C_to_Xen_gint(gtk_text_iter_get_line_index(Xen_to_C_GtkTextIter_(iter)))); } static Xen gxg_gtk_text_iter_get_visible_line_offset(Xen iter) { #define H_gtk_text_iter_get_visible_line_offset "gint gtk_text_iter_get_visible_line_offset(GtkTextIter* iter)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_get_visible_line_offset", "GtkTextIter*"); return(C_to_Xen_gint(gtk_text_iter_get_visible_line_offset(Xen_to_C_GtkTextIter_(iter)))); } static Xen gxg_gtk_text_iter_get_visible_line_index(Xen iter) { #define H_gtk_text_iter_get_visible_line_index "gint gtk_text_iter_get_visible_line_index(GtkTextIter* iter)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_get_visible_line_index", "GtkTextIter*"); return(C_to_Xen_gint(gtk_text_iter_get_visible_line_index(Xen_to_C_GtkTextIter_(iter)))); } static Xen gxg_gtk_text_iter_get_char(Xen iter) { #define H_gtk_text_iter_get_char "gunichar gtk_text_iter_get_char(GtkTextIter* iter)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_get_char", "GtkTextIter*"); return(C_to_Xen_gunichar(gtk_text_iter_get_char(Xen_to_C_GtkTextIter_(iter)))); } static Xen gxg_gtk_text_iter_get_slice(Xen start, Xen end) { #define H_gtk_text_iter_get_slice "gchar* gtk_text_iter_get_slice(GtkTextIter* start, GtkTextIter* end)" Xen_check_type(Xen_is_GtkTextIter_(start), start, 1, "gtk_text_iter_get_slice", "GtkTextIter*"); Xen_check_type(Xen_is_GtkTextIter_(end), end, 2, "gtk_text_iter_get_slice", "GtkTextIter*"); { gchar* result; Xen rtn; result = gtk_text_iter_get_slice(Xen_to_C_GtkTextIter_(start), Xen_to_C_GtkTextIter_(end)); rtn = C_to_Xen_gchar_(result); g_free(result); return(rtn); } } static Xen gxg_gtk_text_iter_get_text(Xen start, Xen end) { #define H_gtk_text_iter_get_text "gchar* gtk_text_iter_get_text(GtkTextIter* start, GtkTextIter* end)" Xen_check_type(Xen_is_GtkTextIter_(start), start, 1, "gtk_text_iter_get_text", "GtkTextIter*"); Xen_check_type(Xen_is_GtkTextIter_(end), end, 2, "gtk_text_iter_get_text", "GtkTextIter*"); { gchar* result; Xen rtn; result = gtk_text_iter_get_text(Xen_to_C_GtkTextIter_(start), Xen_to_C_GtkTextIter_(end)); rtn = C_to_Xen_gchar_(result); g_free(result); return(rtn); } } static Xen gxg_gtk_text_iter_get_visible_slice(Xen start, Xen end) { #define H_gtk_text_iter_get_visible_slice "gchar* gtk_text_iter_get_visible_slice(GtkTextIter* start, \ GtkTextIter* end)" Xen_check_type(Xen_is_GtkTextIter_(start), start, 1, "gtk_text_iter_get_visible_slice", "GtkTextIter*"); Xen_check_type(Xen_is_GtkTextIter_(end), end, 2, "gtk_text_iter_get_visible_slice", "GtkTextIter*"); { gchar* result; Xen rtn; result = gtk_text_iter_get_visible_slice(Xen_to_C_GtkTextIter_(start), Xen_to_C_GtkTextIter_(end)); rtn = C_to_Xen_gchar_(result); g_free(result); return(rtn); } } static Xen gxg_gtk_text_iter_get_visible_text(Xen start, Xen end) { #define H_gtk_text_iter_get_visible_text "gchar* gtk_text_iter_get_visible_text(GtkTextIter* start, \ GtkTextIter* end)" Xen_check_type(Xen_is_GtkTextIter_(start), start, 1, "gtk_text_iter_get_visible_text", "GtkTextIter*"); Xen_check_type(Xen_is_GtkTextIter_(end), end, 2, "gtk_text_iter_get_visible_text", "GtkTextIter*"); { gchar* result; Xen rtn; result = gtk_text_iter_get_visible_text(Xen_to_C_GtkTextIter_(start), Xen_to_C_GtkTextIter_(end)); rtn = C_to_Xen_gchar_(result); g_free(result); return(rtn); } } static Xen gxg_gtk_text_iter_get_pixbuf(Xen iter) { #define H_gtk_text_iter_get_pixbuf "GdkPixbuf* gtk_text_iter_get_pixbuf(GtkTextIter* iter)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_get_pixbuf", "GtkTextIter*"); return(C_to_Xen_GdkPixbuf_(gtk_text_iter_get_pixbuf(Xen_to_C_GtkTextIter_(iter)))); } static Xen gxg_gtk_text_iter_get_marks(Xen iter) { #define H_gtk_text_iter_get_marks "GSList* gtk_text_iter_get_marks(GtkTextIter* iter)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_get_marks", "GtkTextIter*"); return(C_to_Xen_GSList_(gtk_text_iter_get_marks(Xen_to_C_GtkTextIter_(iter)))); } static Xen gxg_gtk_text_iter_get_child_anchor(Xen iter) { #define H_gtk_text_iter_get_child_anchor "GtkTextChildAnchor* gtk_text_iter_get_child_anchor(GtkTextIter* iter)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_get_child_anchor", "GtkTextIter*"); return(C_to_Xen_GtkTextChildAnchor_(gtk_text_iter_get_child_anchor(Xen_to_C_GtkTextIter_(iter)))); } static Xen gxg_gtk_text_iter_get_toggled_tags(Xen iter, Xen toggled_on) { #define H_gtk_text_iter_get_toggled_tags "GSList* gtk_text_iter_get_toggled_tags(GtkTextIter* iter, \ gboolean toggled_on)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_get_toggled_tags", "GtkTextIter*"); Xen_check_type(Xen_is_gboolean(toggled_on), toggled_on, 2, "gtk_text_iter_get_toggled_tags", "gboolean"); return(C_to_Xen_GSList_(gtk_text_iter_get_toggled_tags(Xen_to_C_GtkTextIter_(iter), Xen_to_C_gboolean(toggled_on)))); } static Xen gxg_gtk_text_iter_begins_tag(Xen iter, Xen tag) { #define H_gtk_text_iter_begins_tag "gboolean gtk_text_iter_begins_tag(GtkTextIter* iter, GtkTextTag* tag)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_begins_tag", "GtkTextIter*"); Xen_check_type(Xen_is_GtkTextTag_(tag) || Xen_is_false(tag), tag, 2, "gtk_text_iter_begins_tag", "GtkTextTag*"); return(C_to_Xen_gboolean(gtk_text_iter_begins_tag(Xen_to_C_GtkTextIter_(iter), Xen_to_C_GtkTextTag_(tag)))); } static Xen gxg_gtk_text_iter_ends_tag(Xen iter, Xen tag) { #define H_gtk_text_iter_ends_tag "gboolean gtk_text_iter_ends_tag(GtkTextIter* iter, GtkTextTag* tag)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_ends_tag", "GtkTextIter*"); Xen_check_type(Xen_is_GtkTextTag_(tag) || Xen_is_false(tag), tag, 2, "gtk_text_iter_ends_tag", "GtkTextTag*"); return(C_to_Xen_gboolean(gtk_text_iter_ends_tag(Xen_to_C_GtkTextIter_(iter), Xen_to_C_GtkTextTag_(tag)))); } static Xen gxg_gtk_text_iter_toggles_tag(Xen iter, Xen tag) { #define H_gtk_text_iter_toggles_tag "gboolean gtk_text_iter_toggles_tag(GtkTextIter* iter, GtkTextTag* tag)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_toggles_tag", "GtkTextIter*"); Xen_check_type(Xen_is_GtkTextTag_(tag) || Xen_is_false(tag), tag, 2, "gtk_text_iter_toggles_tag", "GtkTextTag*"); return(C_to_Xen_gboolean(gtk_text_iter_toggles_tag(Xen_to_C_GtkTextIter_(iter), Xen_to_C_GtkTextTag_(tag)))); } static Xen gxg_gtk_text_iter_has_tag(Xen iter, Xen tag) { #define H_gtk_text_iter_has_tag "gboolean gtk_text_iter_has_tag(GtkTextIter* iter, GtkTextTag* tag)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_has_tag", "GtkTextIter*"); Xen_check_type(Xen_is_GtkTextTag_(tag), tag, 2, "gtk_text_iter_has_tag", "GtkTextTag*"); return(C_to_Xen_gboolean(gtk_text_iter_has_tag(Xen_to_C_GtkTextIter_(iter), Xen_to_C_GtkTextTag_(tag)))); } static Xen gxg_gtk_text_iter_get_tags(Xen iter) { #define H_gtk_text_iter_get_tags "GSList* gtk_text_iter_get_tags(GtkTextIter* iter)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_get_tags", "GtkTextIter*"); return(C_to_Xen_GSList_(gtk_text_iter_get_tags(Xen_to_C_GtkTextIter_(iter)))); } static Xen gxg_gtk_text_iter_editable(Xen iter, Xen default_setting) { #define H_gtk_text_iter_editable "gboolean gtk_text_iter_editable(GtkTextIter* iter, gboolean default_setting)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_editable", "GtkTextIter*"); Xen_check_type(Xen_is_gboolean(default_setting), default_setting, 2, "gtk_text_iter_editable", "gboolean"); return(C_to_Xen_gboolean(gtk_text_iter_editable(Xen_to_C_GtkTextIter_(iter), Xen_to_C_gboolean(default_setting)))); } static Xen gxg_gtk_text_iter_can_insert(Xen iter, Xen default_editability) { #define H_gtk_text_iter_can_insert "gboolean gtk_text_iter_can_insert(GtkTextIter* iter, gboolean default_editability)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_can_insert", "GtkTextIter*"); Xen_check_type(Xen_is_gboolean(default_editability), default_editability, 2, "gtk_text_iter_can_insert", "gboolean"); return(C_to_Xen_gboolean(gtk_text_iter_can_insert(Xen_to_C_GtkTextIter_(iter), Xen_to_C_gboolean(default_editability)))); } static Xen gxg_gtk_text_iter_starts_word(Xen iter) { #define H_gtk_text_iter_starts_word "gboolean gtk_text_iter_starts_word(GtkTextIter* iter)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_starts_word", "GtkTextIter*"); return(C_to_Xen_gboolean(gtk_text_iter_starts_word(Xen_to_C_GtkTextIter_(iter)))); } static Xen gxg_gtk_text_iter_ends_word(Xen iter) { #define H_gtk_text_iter_ends_word "gboolean gtk_text_iter_ends_word(GtkTextIter* iter)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_ends_word", "GtkTextIter*"); return(C_to_Xen_gboolean(gtk_text_iter_ends_word(Xen_to_C_GtkTextIter_(iter)))); } static Xen gxg_gtk_text_iter_inside_word(Xen iter) { #define H_gtk_text_iter_inside_word "gboolean gtk_text_iter_inside_word(GtkTextIter* iter)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_inside_word", "GtkTextIter*"); return(C_to_Xen_gboolean(gtk_text_iter_inside_word(Xen_to_C_GtkTextIter_(iter)))); } static Xen gxg_gtk_text_iter_starts_sentence(Xen iter) { #define H_gtk_text_iter_starts_sentence "gboolean gtk_text_iter_starts_sentence(GtkTextIter* iter)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_starts_sentence", "GtkTextIter*"); return(C_to_Xen_gboolean(gtk_text_iter_starts_sentence(Xen_to_C_GtkTextIter_(iter)))); } static Xen gxg_gtk_text_iter_ends_sentence(Xen iter) { #define H_gtk_text_iter_ends_sentence "gboolean gtk_text_iter_ends_sentence(GtkTextIter* iter)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_ends_sentence", "GtkTextIter*"); return(C_to_Xen_gboolean(gtk_text_iter_ends_sentence(Xen_to_C_GtkTextIter_(iter)))); } static Xen gxg_gtk_text_iter_inside_sentence(Xen iter) { #define H_gtk_text_iter_inside_sentence "gboolean gtk_text_iter_inside_sentence(GtkTextIter* iter)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_inside_sentence", "GtkTextIter*"); return(C_to_Xen_gboolean(gtk_text_iter_inside_sentence(Xen_to_C_GtkTextIter_(iter)))); } static Xen gxg_gtk_text_iter_starts_line(Xen iter) { #define H_gtk_text_iter_starts_line "gboolean gtk_text_iter_starts_line(GtkTextIter* iter)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_starts_line", "GtkTextIter*"); return(C_to_Xen_gboolean(gtk_text_iter_starts_line(Xen_to_C_GtkTextIter_(iter)))); } static Xen gxg_gtk_text_iter_ends_line(Xen iter) { #define H_gtk_text_iter_ends_line "gboolean gtk_text_iter_ends_line(GtkTextIter* iter)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_ends_line", "GtkTextIter*"); return(C_to_Xen_gboolean(gtk_text_iter_ends_line(Xen_to_C_GtkTextIter_(iter)))); } static Xen gxg_gtk_text_iter_is_cursor_position(Xen iter) { #define H_gtk_text_iter_is_cursor_position "gboolean gtk_text_iter_is_cursor_position(GtkTextIter* iter)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_is_cursor_position", "GtkTextIter*"); return(C_to_Xen_gboolean(gtk_text_iter_is_cursor_position(Xen_to_C_GtkTextIter_(iter)))); } static Xen gxg_gtk_text_iter_get_chars_in_line(Xen iter) { #define H_gtk_text_iter_get_chars_in_line "gint gtk_text_iter_get_chars_in_line(GtkTextIter* iter)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_get_chars_in_line", "GtkTextIter*"); return(C_to_Xen_gint(gtk_text_iter_get_chars_in_line(Xen_to_C_GtkTextIter_(iter)))); } static Xen gxg_gtk_text_iter_get_bytes_in_line(Xen iter) { #define H_gtk_text_iter_get_bytes_in_line "gint gtk_text_iter_get_bytes_in_line(GtkTextIter* iter)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_get_bytes_in_line", "GtkTextIter*"); return(C_to_Xen_gint(gtk_text_iter_get_bytes_in_line(Xen_to_C_GtkTextIter_(iter)))); } static Xen gxg_gtk_text_iter_get_attributes(Xen iter, Xen values) { #define H_gtk_text_iter_get_attributes "gboolean gtk_text_iter_get_attributes(GtkTextIter* iter, GtkTextAttributes* values)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_get_attributes", "GtkTextIter*"); Xen_check_type(Xen_is_GtkTextAttributes_(values), values, 2, "gtk_text_iter_get_attributes", "GtkTextAttributes*"); return(C_to_Xen_gboolean(gtk_text_iter_get_attributes(Xen_to_C_GtkTextIter_(iter), Xen_to_C_GtkTextAttributes_(values)))); } static Xen gxg_gtk_text_iter_get_language(Xen iter) { #define H_gtk_text_iter_get_language "PangoLanguage* gtk_text_iter_get_language(GtkTextIter* iter)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_get_language", "GtkTextIter*"); return(C_to_Xen_PangoLanguage_(gtk_text_iter_get_language(Xen_to_C_GtkTextIter_(iter)))); } static Xen gxg_gtk_text_iter_is_end(Xen iter) { #define H_gtk_text_iter_is_end "gboolean gtk_text_iter_is_end(GtkTextIter* iter)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_is_end", "GtkTextIter*"); return(C_to_Xen_gboolean(gtk_text_iter_is_end(Xen_to_C_GtkTextIter_(iter)))); } static Xen gxg_gtk_text_iter_is_start(Xen iter) { #define H_gtk_text_iter_is_start "gboolean gtk_text_iter_is_start(GtkTextIter* iter)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_is_start", "GtkTextIter*"); return(C_to_Xen_gboolean(gtk_text_iter_is_start(Xen_to_C_GtkTextIter_(iter)))); } static Xen gxg_gtk_text_iter_forward_char(Xen iter) { #define H_gtk_text_iter_forward_char "gboolean gtk_text_iter_forward_char(GtkTextIter* iter)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_forward_char", "GtkTextIter*"); return(C_to_Xen_gboolean(gtk_text_iter_forward_char(Xen_to_C_GtkTextIter_(iter)))); } static Xen gxg_gtk_text_iter_backward_char(Xen iter) { #define H_gtk_text_iter_backward_char "gboolean gtk_text_iter_backward_char(GtkTextIter* iter)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_backward_char", "GtkTextIter*"); return(C_to_Xen_gboolean(gtk_text_iter_backward_char(Xen_to_C_GtkTextIter_(iter)))); } static Xen gxg_gtk_text_iter_forward_chars(Xen iter, Xen count) { #define H_gtk_text_iter_forward_chars "gboolean gtk_text_iter_forward_chars(GtkTextIter* iter, gint count)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_forward_chars", "GtkTextIter*"); Xen_check_type(Xen_is_gint(count), count, 2, "gtk_text_iter_forward_chars", "gint"); return(C_to_Xen_gboolean(gtk_text_iter_forward_chars(Xen_to_C_GtkTextIter_(iter), Xen_to_C_gint(count)))); } static Xen gxg_gtk_text_iter_backward_chars(Xen iter, Xen count) { #define H_gtk_text_iter_backward_chars "gboolean gtk_text_iter_backward_chars(GtkTextIter* iter, gint count)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_backward_chars", "GtkTextIter*"); Xen_check_type(Xen_is_gint(count), count, 2, "gtk_text_iter_backward_chars", "gint"); return(C_to_Xen_gboolean(gtk_text_iter_backward_chars(Xen_to_C_GtkTextIter_(iter), Xen_to_C_gint(count)))); } static Xen gxg_gtk_text_iter_forward_line(Xen iter) { #define H_gtk_text_iter_forward_line "gboolean gtk_text_iter_forward_line(GtkTextIter* iter)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_forward_line", "GtkTextIter*"); return(C_to_Xen_gboolean(gtk_text_iter_forward_line(Xen_to_C_GtkTextIter_(iter)))); } static Xen gxg_gtk_text_iter_backward_line(Xen iter) { #define H_gtk_text_iter_backward_line "gboolean gtk_text_iter_backward_line(GtkTextIter* iter)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_backward_line", "GtkTextIter*"); return(C_to_Xen_gboolean(gtk_text_iter_backward_line(Xen_to_C_GtkTextIter_(iter)))); } static Xen gxg_gtk_text_iter_forward_lines(Xen iter, Xen count) { #define H_gtk_text_iter_forward_lines "gboolean gtk_text_iter_forward_lines(GtkTextIter* iter, gint count)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_forward_lines", "GtkTextIter*"); Xen_check_type(Xen_is_gint(count), count, 2, "gtk_text_iter_forward_lines", "gint"); return(C_to_Xen_gboolean(gtk_text_iter_forward_lines(Xen_to_C_GtkTextIter_(iter), Xen_to_C_gint(count)))); } static Xen gxg_gtk_text_iter_backward_lines(Xen iter, Xen count) { #define H_gtk_text_iter_backward_lines "gboolean gtk_text_iter_backward_lines(GtkTextIter* iter, gint count)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_backward_lines", "GtkTextIter*"); Xen_check_type(Xen_is_gint(count), count, 2, "gtk_text_iter_backward_lines", "gint"); return(C_to_Xen_gboolean(gtk_text_iter_backward_lines(Xen_to_C_GtkTextIter_(iter), Xen_to_C_gint(count)))); } static Xen gxg_gtk_text_iter_forward_word_end(Xen iter) { #define H_gtk_text_iter_forward_word_end "gboolean gtk_text_iter_forward_word_end(GtkTextIter* iter)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_forward_word_end", "GtkTextIter*"); return(C_to_Xen_gboolean(gtk_text_iter_forward_word_end(Xen_to_C_GtkTextIter_(iter)))); } static Xen gxg_gtk_text_iter_backward_word_start(Xen iter) { #define H_gtk_text_iter_backward_word_start "gboolean gtk_text_iter_backward_word_start(GtkTextIter* iter)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_backward_word_start", "GtkTextIter*"); return(C_to_Xen_gboolean(gtk_text_iter_backward_word_start(Xen_to_C_GtkTextIter_(iter)))); } static Xen gxg_gtk_text_iter_forward_word_ends(Xen iter, Xen count) { #define H_gtk_text_iter_forward_word_ends "gboolean gtk_text_iter_forward_word_ends(GtkTextIter* iter, \ gint count)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_forward_word_ends", "GtkTextIter*"); Xen_check_type(Xen_is_gint(count), count, 2, "gtk_text_iter_forward_word_ends", "gint"); return(C_to_Xen_gboolean(gtk_text_iter_forward_word_ends(Xen_to_C_GtkTextIter_(iter), Xen_to_C_gint(count)))); } static Xen gxg_gtk_text_iter_backward_word_starts(Xen iter, Xen count) { #define H_gtk_text_iter_backward_word_starts "gboolean gtk_text_iter_backward_word_starts(GtkTextIter* iter, \ gint count)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_backward_word_starts", "GtkTextIter*"); Xen_check_type(Xen_is_gint(count), count, 2, "gtk_text_iter_backward_word_starts", "gint"); return(C_to_Xen_gboolean(gtk_text_iter_backward_word_starts(Xen_to_C_GtkTextIter_(iter), Xen_to_C_gint(count)))); } static Xen gxg_gtk_text_iter_forward_sentence_end(Xen iter) { #define H_gtk_text_iter_forward_sentence_end "gboolean gtk_text_iter_forward_sentence_end(GtkTextIter* iter)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_forward_sentence_end", "GtkTextIter*"); return(C_to_Xen_gboolean(gtk_text_iter_forward_sentence_end(Xen_to_C_GtkTextIter_(iter)))); } static Xen gxg_gtk_text_iter_backward_sentence_start(Xen iter) { #define H_gtk_text_iter_backward_sentence_start "gboolean gtk_text_iter_backward_sentence_start(GtkTextIter* iter)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_backward_sentence_start", "GtkTextIter*"); return(C_to_Xen_gboolean(gtk_text_iter_backward_sentence_start(Xen_to_C_GtkTextIter_(iter)))); } static Xen gxg_gtk_text_iter_forward_sentence_ends(Xen iter, Xen count) { #define H_gtk_text_iter_forward_sentence_ends "gboolean gtk_text_iter_forward_sentence_ends(GtkTextIter* iter, \ gint count)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_forward_sentence_ends", "GtkTextIter*"); Xen_check_type(Xen_is_gint(count), count, 2, "gtk_text_iter_forward_sentence_ends", "gint"); return(C_to_Xen_gboolean(gtk_text_iter_forward_sentence_ends(Xen_to_C_GtkTextIter_(iter), Xen_to_C_gint(count)))); } static Xen gxg_gtk_text_iter_backward_sentence_starts(Xen iter, Xen count) { #define H_gtk_text_iter_backward_sentence_starts "gboolean gtk_text_iter_backward_sentence_starts(GtkTextIter* iter, \ gint count)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_backward_sentence_starts", "GtkTextIter*"); Xen_check_type(Xen_is_gint(count), count, 2, "gtk_text_iter_backward_sentence_starts", "gint"); return(C_to_Xen_gboolean(gtk_text_iter_backward_sentence_starts(Xen_to_C_GtkTextIter_(iter), Xen_to_C_gint(count)))); } static Xen gxg_gtk_text_iter_forward_cursor_position(Xen iter) { #define H_gtk_text_iter_forward_cursor_position "gboolean gtk_text_iter_forward_cursor_position(GtkTextIter* iter)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_forward_cursor_position", "GtkTextIter*"); return(C_to_Xen_gboolean(gtk_text_iter_forward_cursor_position(Xen_to_C_GtkTextIter_(iter)))); } static Xen gxg_gtk_text_iter_backward_cursor_position(Xen iter) { #define H_gtk_text_iter_backward_cursor_position "gboolean gtk_text_iter_backward_cursor_position(GtkTextIter* iter)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_backward_cursor_position", "GtkTextIter*"); return(C_to_Xen_gboolean(gtk_text_iter_backward_cursor_position(Xen_to_C_GtkTextIter_(iter)))); } static Xen gxg_gtk_text_iter_forward_cursor_positions(Xen iter, Xen count) { #define H_gtk_text_iter_forward_cursor_positions "gboolean gtk_text_iter_forward_cursor_positions(GtkTextIter* iter, \ gint count)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_forward_cursor_positions", "GtkTextIter*"); Xen_check_type(Xen_is_gint(count), count, 2, "gtk_text_iter_forward_cursor_positions", "gint"); return(C_to_Xen_gboolean(gtk_text_iter_forward_cursor_positions(Xen_to_C_GtkTextIter_(iter), Xen_to_C_gint(count)))); } static Xen gxg_gtk_text_iter_backward_cursor_positions(Xen iter, Xen count) { #define H_gtk_text_iter_backward_cursor_positions "gboolean gtk_text_iter_backward_cursor_positions(GtkTextIter* iter, \ gint count)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_backward_cursor_positions", "GtkTextIter*"); Xen_check_type(Xen_is_gint(count), count, 2, "gtk_text_iter_backward_cursor_positions", "gint"); return(C_to_Xen_gboolean(gtk_text_iter_backward_cursor_positions(Xen_to_C_GtkTextIter_(iter), Xen_to_C_gint(count)))); } static Xen gxg_gtk_text_iter_set_offset(Xen iter, Xen char_offset) { #define H_gtk_text_iter_set_offset "void gtk_text_iter_set_offset(GtkTextIter* iter, gint char_offset)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_set_offset", "GtkTextIter*"); Xen_check_type(Xen_is_gint(char_offset), char_offset, 2, "gtk_text_iter_set_offset", "gint"); gtk_text_iter_set_offset(Xen_to_C_GtkTextIter_(iter), Xen_to_C_gint(char_offset)); return(Xen_false); } static Xen gxg_gtk_text_iter_set_line(Xen iter, Xen line_number) { #define H_gtk_text_iter_set_line "void gtk_text_iter_set_line(GtkTextIter* iter, gint line_number)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_set_line", "GtkTextIter*"); Xen_check_type(Xen_is_gint(line_number), line_number, 2, "gtk_text_iter_set_line", "gint"); gtk_text_iter_set_line(Xen_to_C_GtkTextIter_(iter), Xen_to_C_gint(line_number)); return(Xen_false); } static Xen gxg_gtk_text_iter_set_line_offset(Xen iter, Xen char_on_line) { #define H_gtk_text_iter_set_line_offset "void gtk_text_iter_set_line_offset(GtkTextIter* iter, gint char_on_line)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_set_line_offset", "GtkTextIter*"); Xen_check_type(Xen_is_gint(char_on_line), char_on_line, 2, "gtk_text_iter_set_line_offset", "gint"); gtk_text_iter_set_line_offset(Xen_to_C_GtkTextIter_(iter), Xen_to_C_gint(char_on_line)); return(Xen_false); } static Xen gxg_gtk_text_iter_set_line_index(Xen iter, Xen byte_on_line) { #define H_gtk_text_iter_set_line_index "void gtk_text_iter_set_line_index(GtkTextIter* iter, gint byte_on_line)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_set_line_index", "GtkTextIter*"); Xen_check_type(Xen_is_gint(byte_on_line), byte_on_line, 2, "gtk_text_iter_set_line_index", "gint"); gtk_text_iter_set_line_index(Xen_to_C_GtkTextIter_(iter), Xen_to_C_gint(byte_on_line)); return(Xen_false); } static Xen gxg_gtk_text_iter_forward_to_end(Xen iter) { #define H_gtk_text_iter_forward_to_end "void gtk_text_iter_forward_to_end(GtkTextIter* iter)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_forward_to_end", "GtkTextIter*"); gtk_text_iter_forward_to_end(Xen_to_C_GtkTextIter_(iter)); return(Xen_false); } static Xen gxg_gtk_text_iter_forward_to_line_end(Xen iter) { #define H_gtk_text_iter_forward_to_line_end "gboolean gtk_text_iter_forward_to_line_end(GtkTextIter* iter)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_forward_to_line_end", "GtkTextIter*"); return(C_to_Xen_gboolean(gtk_text_iter_forward_to_line_end(Xen_to_C_GtkTextIter_(iter)))); } static Xen gxg_gtk_text_iter_set_visible_line_offset(Xen iter, Xen char_on_line) { #define H_gtk_text_iter_set_visible_line_offset "void gtk_text_iter_set_visible_line_offset(GtkTextIter* iter, \ gint char_on_line)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_set_visible_line_offset", "GtkTextIter*"); Xen_check_type(Xen_is_gint(char_on_line), char_on_line, 2, "gtk_text_iter_set_visible_line_offset", "gint"); gtk_text_iter_set_visible_line_offset(Xen_to_C_GtkTextIter_(iter), Xen_to_C_gint(char_on_line)); return(Xen_false); } static Xen gxg_gtk_text_iter_set_visible_line_index(Xen iter, Xen byte_on_line) { #define H_gtk_text_iter_set_visible_line_index "void gtk_text_iter_set_visible_line_index(GtkTextIter* iter, \ gint byte_on_line)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_set_visible_line_index", "GtkTextIter*"); Xen_check_type(Xen_is_gint(byte_on_line), byte_on_line, 2, "gtk_text_iter_set_visible_line_index", "gint"); gtk_text_iter_set_visible_line_index(Xen_to_C_GtkTextIter_(iter), Xen_to_C_gint(byte_on_line)); return(Xen_false); } static Xen gxg_gtk_text_iter_forward_to_tag_toggle(Xen iter, Xen tag) { #define H_gtk_text_iter_forward_to_tag_toggle "gboolean gtk_text_iter_forward_to_tag_toggle(GtkTextIter* iter, \ GtkTextTag* tag)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_forward_to_tag_toggle", "GtkTextIter*"); Xen_check_type(Xen_is_GtkTextTag_(tag) || Xen_is_false(tag), tag, 2, "gtk_text_iter_forward_to_tag_toggle", "GtkTextTag*"); return(C_to_Xen_gboolean(gtk_text_iter_forward_to_tag_toggle(Xen_to_C_GtkTextIter_(iter), Xen_to_C_GtkTextTag_(tag)))); } static Xen gxg_gtk_text_iter_backward_to_tag_toggle(Xen iter, Xen tag) { #define H_gtk_text_iter_backward_to_tag_toggle "gboolean gtk_text_iter_backward_to_tag_toggle(GtkTextIter* iter, \ GtkTextTag* tag)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_backward_to_tag_toggle", "GtkTextIter*"); Xen_check_type(Xen_is_GtkTextTag_(tag) || Xen_is_false(tag), tag, 2, "gtk_text_iter_backward_to_tag_toggle", "GtkTextTag*"); return(C_to_Xen_gboolean(gtk_text_iter_backward_to_tag_toggle(Xen_to_C_GtkTextIter_(iter), Xen_to_C_GtkTextTag_(tag)))); } static Xen gxg_gtk_text_iter_forward_find_char(Xen iter, Xen pred, Xen func_info, Xen limit) { #define H_gtk_text_iter_forward_find_char "gboolean gtk_text_iter_forward_find_char(GtkTextIter* iter, \ GtkTextCharPredicate pred, lambda_data func_info, GtkTextIter* limit)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_forward_find_char", "GtkTextIter*"); Xen_check_type(Xen_is_GtkTextCharPredicate(pred), pred, 2, "gtk_text_iter_forward_find_char", "GtkTextCharPredicate"); Xen_check_type(Xen_is_lambda_data(func_info), func_info, 3, "gtk_text_iter_forward_find_char", "lambda_data"); Xen_check_type(Xen_is_GtkTextIter_(limit) || Xen_is_false(limit), limit, 4, "gtk_text_iter_forward_find_char", "GtkTextIter*"); { Xen result; int loc; Xen gxg_ptr = Xen_list_5(Xen_false, func_info, Xen_false, Xen_false, Xen_false); loc = xm_protect(gxg_ptr); Xen_list_set(gxg_ptr, 2, C_int_to_Xen_integer(loc)); result = C_to_Xen_gboolean(gtk_text_iter_forward_find_char(Xen_to_C_GtkTextIter_(iter), Xen_to_C_GtkTextCharPredicate(pred), Xen_to_C_lambda_data(func_info), Xen_to_C_GtkTextIter_(limit))); xm_unprotect_at(loc); return(result); } } static Xen gxg_gtk_text_iter_backward_find_char(Xen iter, Xen pred, Xen func_info, Xen limit) { #define H_gtk_text_iter_backward_find_char "gboolean gtk_text_iter_backward_find_char(GtkTextIter* iter, \ GtkTextCharPredicate pred, lambda_data func_info, GtkTextIter* limit)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_backward_find_char", "GtkTextIter*"); Xen_check_type(Xen_is_GtkTextCharPredicate(pred), pred, 2, "gtk_text_iter_backward_find_char", "GtkTextCharPredicate"); Xen_check_type(Xen_is_lambda_data(func_info), func_info, 3, "gtk_text_iter_backward_find_char", "lambda_data"); Xen_check_type(Xen_is_GtkTextIter_(limit) || Xen_is_false(limit), limit, 4, "gtk_text_iter_backward_find_char", "GtkTextIter*"); { Xen result; int loc; Xen gxg_ptr = Xen_list_5(Xen_false, func_info, Xen_false, Xen_false, Xen_false); loc = xm_protect(gxg_ptr); Xen_list_set(gxg_ptr, 2, C_int_to_Xen_integer(loc)); result = C_to_Xen_gboolean(gtk_text_iter_backward_find_char(Xen_to_C_GtkTextIter_(iter), Xen_to_C_GtkTextCharPredicate(pred), Xen_to_C_lambda_data(func_info), Xen_to_C_GtkTextIter_(limit))); xm_unprotect_at(loc); return(result); } } static Xen gxg_gtk_text_iter_forward_search(Xen iter, Xen str, Xen flags, Xen match_start, Xen match_end, Xen limit) { #define H_gtk_text_iter_forward_search "gboolean gtk_text_iter_forward_search(GtkTextIter* iter, gchar* str, \ GtkTextSearchFlags flags, GtkTextIter* match_start, GtkTextIter* match_end, GtkTextIter* limit)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_forward_search", "GtkTextIter*"); Xen_check_type(Xen_is_gchar_(str), str, 2, "gtk_text_iter_forward_search", "gchar*"); Xen_check_type(Xen_is_GtkTextSearchFlags(flags), flags, 3, "gtk_text_iter_forward_search", "GtkTextSearchFlags"); Xen_check_type(Xen_is_GtkTextIter_(match_start) || Xen_is_false(match_start), match_start, 4, "gtk_text_iter_forward_search", "GtkTextIter*"); Xen_check_type(Xen_is_GtkTextIter_(match_end) || Xen_is_false(match_end), match_end, 5, "gtk_text_iter_forward_search", "GtkTextIter*"); Xen_check_type(Xen_is_GtkTextIter_(limit) || Xen_is_false(limit), limit, 6, "gtk_text_iter_forward_search", "GtkTextIter*"); return(C_to_Xen_gboolean(gtk_text_iter_forward_search(Xen_to_C_GtkTextIter_(iter), Xen_to_C_gchar_(str), Xen_to_C_GtkTextSearchFlags(flags), Xen_to_C_GtkTextIter_(match_start), Xen_to_C_GtkTextIter_(match_end), Xen_to_C_GtkTextIter_(limit)))); } static Xen gxg_gtk_text_iter_backward_search(Xen iter, Xen str, Xen flags, Xen match_start, Xen match_end, Xen limit) { #define H_gtk_text_iter_backward_search "gboolean gtk_text_iter_backward_search(GtkTextIter* iter, \ gchar* str, GtkTextSearchFlags flags, GtkTextIter* match_start, GtkTextIter* match_end, GtkTextIter* limit)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_backward_search", "GtkTextIter*"); Xen_check_type(Xen_is_gchar_(str), str, 2, "gtk_text_iter_backward_search", "gchar*"); Xen_check_type(Xen_is_GtkTextSearchFlags(flags), flags, 3, "gtk_text_iter_backward_search", "GtkTextSearchFlags"); Xen_check_type(Xen_is_GtkTextIter_(match_start) || Xen_is_false(match_start), match_start, 4, "gtk_text_iter_backward_search", "GtkTextIter*"); Xen_check_type(Xen_is_GtkTextIter_(match_end) || Xen_is_false(match_end), match_end, 5, "gtk_text_iter_backward_search", "GtkTextIter*"); Xen_check_type(Xen_is_GtkTextIter_(limit) || Xen_is_false(limit), limit, 6, "gtk_text_iter_backward_search", "GtkTextIter*"); return(C_to_Xen_gboolean(gtk_text_iter_backward_search(Xen_to_C_GtkTextIter_(iter), Xen_to_C_gchar_(str), Xen_to_C_GtkTextSearchFlags(flags), Xen_to_C_GtkTextIter_(match_start), Xen_to_C_GtkTextIter_(match_end), Xen_to_C_GtkTextIter_(limit)))); } static Xen gxg_gtk_text_iter_equal(Xen lhs, Xen rhs) { #define H_gtk_text_iter_equal "gboolean gtk_text_iter_equal(GtkTextIter* lhs, GtkTextIter* rhs)" Xen_check_type(Xen_is_GtkTextIter_(lhs), lhs, 1, "gtk_text_iter_equal", "GtkTextIter*"); Xen_check_type(Xen_is_GtkTextIter_(rhs), rhs, 2, "gtk_text_iter_equal", "GtkTextIter*"); return(C_to_Xen_gboolean(gtk_text_iter_equal(Xen_to_C_GtkTextIter_(lhs), Xen_to_C_GtkTextIter_(rhs)))); } static Xen gxg_gtk_text_iter_compare(Xen lhs, Xen rhs) { #define H_gtk_text_iter_compare "gint gtk_text_iter_compare(GtkTextIter* lhs, GtkTextIter* rhs)" Xen_check_type(Xen_is_GtkTextIter_(lhs), lhs, 1, "gtk_text_iter_compare", "GtkTextIter*"); Xen_check_type(Xen_is_GtkTextIter_(rhs), rhs, 2, "gtk_text_iter_compare", "GtkTextIter*"); return(C_to_Xen_gint(gtk_text_iter_compare(Xen_to_C_GtkTextIter_(lhs), Xen_to_C_GtkTextIter_(rhs)))); } static Xen gxg_gtk_text_iter_in_range(Xen iter, Xen start, Xen end) { #define H_gtk_text_iter_in_range "gboolean gtk_text_iter_in_range(GtkTextIter* iter, GtkTextIter* start, \ GtkTextIter* end)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_in_range", "GtkTextIter*"); Xen_check_type(Xen_is_GtkTextIter_(start), start, 2, "gtk_text_iter_in_range", "GtkTextIter*"); Xen_check_type(Xen_is_GtkTextIter_(end), end, 3, "gtk_text_iter_in_range", "GtkTextIter*"); return(C_to_Xen_gboolean(gtk_text_iter_in_range(Xen_to_C_GtkTextIter_(iter), Xen_to_C_GtkTextIter_(start), Xen_to_C_GtkTextIter_(end)))); } static Xen gxg_gtk_text_iter_order(Xen first, Xen second) { #define H_gtk_text_iter_order "void gtk_text_iter_order(GtkTextIter* first, GtkTextIter* second)" Xen_check_type(Xen_is_GtkTextIter_(first), first, 1, "gtk_text_iter_order", "GtkTextIter*"); Xen_check_type(Xen_is_GtkTextIter_(second), second, 2, "gtk_text_iter_order", "GtkTextIter*"); gtk_text_iter_order(Xen_to_C_GtkTextIter_(first), Xen_to_C_GtkTextIter_(second)); return(Xen_false); } static Xen gxg_gtk_text_mark_set_visible(Xen mark, Xen setting) { #define H_gtk_text_mark_set_visible "void gtk_text_mark_set_visible(GtkTextMark* mark, gboolean setting)" Xen_check_type(Xen_is_GtkTextMark_(mark), mark, 1, "gtk_text_mark_set_visible", "GtkTextMark*"); Xen_check_type(Xen_is_gboolean(setting), setting, 2, "gtk_text_mark_set_visible", "gboolean"); gtk_text_mark_set_visible(Xen_to_C_GtkTextMark_(mark), Xen_to_C_gboolean(setting)); return(Xen_false); } static Xen gxg_gtk_text_mark_get_visible(Xen mark) { #define H_gtk_text_mark_get_visible "gboolean gtk_text_mark_get_visible(GtkTextMark* mark)" Xen_check_type(Xen_is_GtkTextMark_(mark), mark, 1, "gtk_text_mark_get_visible", "GtkTextMark*"); return(C_to_Xen_gboolean(gtk_text_mark_get_visible(Xen_to_C_GtkTextMark_(mark)))); } static Xen gxg_gtk_text_mark_get_name(Xen mark) { #define H_gtk_text_mark_get_name "char* gtk_text_mark_get_name(GtkTextMark* mark)" Xen_check_type(Xen_is_GtkTextMark_(mark), mark, 1, "gtk_text_mark_get_name", "GtkTextMark*"); return(C_to_Xen_char_(gtk_text_mark_get_name(Xen_to_C_GtkTextMark_(mark)))); } static Xen gxg_gtk_text_mark_get_deleted(Xen mark) { #define H_gtk_text_mark_get_deleted "gboolean gtk_text_mark_get_deleted(GtkTextMark* mark)" Xen_check_type(Xen_is_GtkTextMark_(mark), mark, 1, "gtk_text_mark_get_deleted", "GtkTextMark*"); return(C_to_Xen_gboolean(gtk_text_mark_get_deleted(Xen_to_C_GtkTextMark_(mark)))); } static Xen gxg_gtk_text_mark_get_buffer(Xen mark) { #define H_gtk_text_mark_get_buffer "GtkTextBuffer* gtk_text_mark_get_buffer(GtkTextMark* mark)" Xen_check_type(Xen_is_GtkTextMark_(mark), mark, 1, "gtk_text_mark_get_buffer", "GtkTextMark*"); return(C_to_Xen_GtkTextBuffer_(gtk_text_mark_get_buffer(Xen_to_C_GtkTextMark_(mark)))); } static Xen gxg_gtk_text_mark_get_left_gravity(Xen mark) { #define H_gtk_text_mark_get_left_gravity "gboolean gtk_text_mark_get_left_gravity(GtkTextMark* mark)" Xen_check_type(Xen_is_GtkTextMark_(mark), mark, 1, "gtk_text_mark_get_left_gravity", "GtkTextMark*"); return(C_to_Xen_gboolean(gtk_text_mark_get_left_gravity(Xen_to_C_GtkTextMark_(mark)))); } static Xen gxg_gtk_text_tag_new(Xen name) { #define H_gtk_text_tag_new "GtkTextTag* gtk_text_tag_new(gchar* name)" Xen_check_type(Xen_is_gchar_(name), name, 1, "gtk_text_tag_new", "gchar*"); return(C_to_Xen_GtkTextTag_(gtk_text_tag_new(Xen_to_C_gchar_(name)))); } static Xen gxg_gtk_text_tag_get_priority(Xen tag) { #define H_gtk_text_tag_get_priority "gint gtk_text_tag_get_priority(GtkTextTag* tag)" Xen_check_type(Xen_is_GtkTextTag_(tag), tag, 1, "gtk_text_tag_get_priority", "GtkTextTag*"); return(C_to_Xen_gint(gtk_text_tag_get_priority(Xen_to_C_GtkTextTag_(tag)))); } static Xen gxg_gtk_text_tag_set_priority(Xen tag, Xen priority) { #define H_gtk_text_tag_set_priority "void gtk_text_tag_set_priority(GtkTextTag* tag, gint priority)" Xen_check_type(Xen_is_GtkTextTag_(tag), tag, 1, "gtk_text_tag_set_priority", "GtkTextTag*"); Xen_check_type(Xen_is_gint(priority), priority, 2, "gtk_text_tag_set_priority", "gint"); gtk_text_tag_set_priority(Xen_to_C_GtkTextTag_(tag), Xen_to_C_gint(priority)); return(Xen_false); } static Xen gxg_gtk_text_tag_event(Xen tag, Xen event_object, Xen event, Xen iter) { #define H_gtk_text_tag_event "gboolean gtk_text_tag_event(GtkTextTag* tag, GObject* event_object, GdkEvent* event, \ GtkTextIter* iter)" Xen_check_type(Xen_is_GtkTextTag_(tag), tag, 1, "gtk_text_tag_event", "GtkTextTag*"); Xen_check_type(Xen_is_GObject_(event_object), event_object, 2, "gtk_text_tag_event", "GObject*"); Xen_check_type(Xen_is_GdkEvent_(event), event, 3, "gtk_text_tag_event", "GdkEvent*"); Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 4, "gtk_text_tag_event", "GtkTextIter*"); return(C_to_Xen_gboolean(gtk_text_tag_event(Xen_to_C_GtkTextTag_(tag), Xen_to_C_GObject_(event_object), Xen_to_C_GdkEvent_(event), Xen_to_C_GtkTextIter_(iter)))); } static Xen gxg_gtk_text_attributes_new(void) { #define H_gtk_text_attributes_new "GtkTextAttributes* gtk_text_attributes_new( void)" return(C_to_Xen_GtkTextAttributes_(gtk_text_attributes_new())); } static Xen gxg_gtk_text_attributes_copy(Xen src) { #define H_gtk_text_attributes_copy "GtkTextAttributes* gtk_text_attributes_copy(GtkTextAttributes* src)" Xen_check_type(Xen_is_GtkTextAttributes_(src), src, 1, "gtk_text_attributes_copy", "GtkTextAttributes*"); return(C_to_Xen_GtkTextAttributes_(gtk_text_attributes_copy(Xen_to_C_GtkTextAttributes_(src)))); } static Xen gxg_gtk_text_attributes_copy_values(Xen src, Xen dest) { #define H_gtk_text_attributes_copy_values "void gtk_text_attributes_copy_values(GtkTextAttributes* src, \ GtkTextAttributes* dest)" Xen_check_type(Xen_is_GtkTextAttributes_(src), src, 1, "gtk_text_attributes_copy_values", "GtkTextAttributes*"); Xen_check_type(Xen_is_GtkTextAttributes_(dest), dest, 2, "gtk_text_attributes_copy_values", "GtkTextAttributes*"); gtk_text_attributes_copy_values(Xen_to_C_GtkTextAttributes_(src), Xen_to_C_GtkTextAttributes_(dest)); return(Xen_false); } static Xen gxg_gtk_text_attributes_unref(Xen values) { #define H_gtk_text_attributes_unref "void gtk_text_attributes_unref(GtkTextAttributes* values)" Xen_check_type(Xen_is_GtkTextAttributes_(values), values, 1, "gtk_text_attributes_unref", "GtkTextAttributes*"); gtk_text_attributes_unref(Xen_to_C_GtkTextAttributes_(values)); return(Xen_false); } static Xen gxg_gtk_text_tag_table_new(void) { #define H_gtk_text_tag_table_new "GtkTextTagTable* gtk_text_tag_table_new( void)" return(C_to_Xen_GtkTextTagTable_(gtk_text_tag_table_new())); } static Xen gxg_gtk_text_tag_table_add(Xen table, Xen tag) { #define H_gtk_text_tag_table_add "void gtk_text_tag_table_add(GtkTextTagTable* table, GtkTextTag* tag)" Xen_check_type(Xen_is_GtkTextTagTable_(table), table, 1, "gtk_text_tag_table_add", "GtkTextTagTable*"); Xen_check_type(Xen_is_GtkTextTag_(tag), tag, 2, "gtk_text_tag_table_add", "GtkTextTag*"); gtk_text_tag_table_add(Xen_to_C_GtkTextTagTable_(table), Xen_to_C_GtkTextTag_(tag)); return(Xen_false); } static Xen gxg_gtk_text_tag_table_remove(Xen table, Xen tag) { #define H_gtk_text_tag_table_remove "void gtk_text_tag_table_remove(GtkTextTagTable* table, GtkTextTag* tag)" Xen_check_type(Xen_is_GtkTextTagTable_(table), table, 1, "gtk_text_tag_table_remove", "GtkTextTagTable*"); Xen_check_type(Xen_is_GtkTextTag_(tag), tag, 2, "gtk_text_tag_table_remove", "GtkTextTag*"); gtk_text_tag_table_remove(Xen_to_C_GtkTextTagTable_(table), Xen_to_C_GtkTextTag_(tag)); return(Xen_false); } static Xen gxg_gtk_text_tag_table_lookup(Xen table, Xen name) { #define H_gtk_text_tag_table_lookup "GtkTextTag* gtk_text_tag_table_lookup(GtkTextTagTable* table, \ gchar* name)" Xen_check_type(Xen_is_GtkTextTagTable_(table), table, 1, "gtk_text_tag_table_lookup", "GtkTextTagTable*"); Xen_check_type(Xen_is_gchar_(name), name, 2, "gtk_text_tag_table_lookup", "gchar*"); return(C_to_Xen_GtkTextTag_(gtk_text_tag_table_lookup(Xen_to_C_GtkTextTagTable_(table), Xen_to_C_gchar_(name)))); } static Xen gxg_gtk_text_tag_table_foreach(Xen table, Xen func, Xen func_info) { #define H_gtk_text_tag_table_foreach "void gtk_text_tag_table_foreach(GtkTextTagTable* table, GtkTextTagTableForeach func, \ lambda_data func_info)" Xen_check_type(Xen_is_GtkTextTagTable_(table), table, 1, "gtk_text_tag_table_foreach", "GtkTextTagTable*"); Xen_check_type(Xen_is_GtkTextTagTableForeach(func), func, 2, "gtk_text_tag_table_foreach", "GtkTextTagTableForeach"); if (!Xen_is_bound(func_info)) func_info = Xen_false; else Xen_check_type(Xen_is_lambda_data(func_info), func_info, 3, "gtk_text_tag_table_foreach", "lambda_data"); { int loc; Xen gxg_ptr = Xen_list_5(func, func_info, Xen_false, Xen_false, Xen_false); loc = xm_protect(gxg_ptr); Xen_list_set(gxg_ptr, 2, C_int_to_Xen_integer(loc)); gtk_text_tag_table_foreach(Xen_to_C_GtkTextTagTable_(table), Xen_to_C_GtkTextTagTableForeach(func), Xen_to_C_lambda_data(func_info)); xm_unprotect_at(loc); return(Xen_false); } } static Xen gxg_gtk_text_tag_table_get_size(Xen table) { #define H_gtk_text_tag_table_get_size "gint gtk_text_tag_table_get_size(GtkTextTagTable* table)" Xen_check_type(Xen_is_GtkTextTagTable_(table), table, 1, "gtk_text_tag_table_get_size", "GtkTextTagTable*"); return(C_to_Xen_gint(gtk_text_tag_table_get_size(Xen_to_C_GtkTextTagTable_(table)))); } static Xen gxg_gtk_text_view_new(void) { #define H_gtk_text_view_new "GtkWidget* gtk_text_view_new( void)" return(C_to_Xen_GtkWidget_(gtk_text_view_new())); } static Xen gxg_gtk_text_view_new_with_buffer(Xen buffer) { #define H_gtk_text_view_new_with_buffer "GtkWidget* gtk_text_view_new_with_buffer(GtkTextBuffer* buffer)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_view_new_with_buffer", "GtkTextBuffer*"); return(C_to_Xen_GtkWidget_(gtk_text_view_new_with_buffer(Xen_to_C_GtkTextBuffer_(buffer)))); } static Xen gxg_gtk_text_view_set_buffer(Xen text_view, Xen buffer) { #define H_gtk_text_view_set_buffer "void gtk_text_view_set_buffer(GtkTextView* text_view, GtkTextBuffer* buffer)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_set_buffer", "GtkTextView*"); Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 2, "gtk_text_view_set_buffer", "GtkTextBuffer*"); gtk_text_view_set_buffer(Xen_to_C_GtkTextView_(text_view), Xen_to_C_GtkTextBuffer_(buffer)); return(Xen_false); } static Xen gxg_gtk_text_view_get_buffer(Xen text_view) { #define H_gtk_text_view_get_buffer "GtkTextBuffer* gtk_text_view_get_buffer(GtkTextView* text_view)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_get_buffer", "GtkTextView*"); return(C_to_Xen_GtkTextBuffer_(gtk_text_view_get_buffer(Xen_to_C_GtkTextView_(text_view)))); } static Xen gxg_gtk_text_view_scroll_to_iter(Xen text_view, Xen iter, Xen within_margin, Xen use_align, Xen xalign, Xen yalign) { #define H_gtk_text_view_scroll_to_iter "gboolean gtk_text_view_scroll_to_iter(GtkTextView* text_view, \ GtkTextIter* iter, gdouble within_margin, gboolean use_align, gdouble xalign, gdouble yalign)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_scroll_to_iter", "GtkTextView*"); Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 2, "gtk_text_view_scroll_to_iter", "GtkTextIter*"); Xen_check_type(Xen_is_gdouble(within_margin), within_margin, 3, "gtk_text_view_scroll_to_iter", "gdouble"); Xen_check_type(Xen_is_gboolean(use_align), use_align, 4, "gtk_text_view_scroll_to_iter", "gboolean"); Xen_check_type(Xen_is_gdouble(xalign), xalign, 5, "gtk_text_view_scroll_to_iter", "gdouble"); Xen_check_type(Xen_is_gdouble(yalign), yalign, 6, "gtk_text_view_scroll_to_iter", "gdouble"); return(C_to_Xen_gboolean(gtk_text_view_scroll_to_iter(Xen_to_C_GtkTextView_(text_view), Xen_to_C_GtkTextIter_(iter), Xen_to_C_gdouble(within_margin), Xen_to_C_gboolean(use_align), Xen_to_C_gdouble(xalign), Xen_to_C_gdouble(yalign)))); } static Xen gxg_gtk_text_view_scroll_to_mark(Xen text_view, Xen mark, Xen within_margin, Xen use_align, Xen xalign, Xen yalign) { #define H_gtk_text_view_scroll_to_mark "void gtk_text_view_scroll_to_mark(GtkTextView* text_view, GtkTextMark* mark, \ gdouble within_margin, gboolean use_align, gdouble xalign, gdouble yalign)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_scroll_to_mark", "GtkTextView*"); Xen_check_type(Xen_is_GtkTextMark_(mark), mark, 2, "gtk_text_view_scroll_to_mark", "GtkTextMark*"); Xen_check_type(Xen_is_gdouble(within_margin), within_margin, 3, "gtk_text_view_scroll_to_mark", "gdouble"); Xen_check_type(Xen_is_gboolean(use_align), use_align, 4, "gtk_text_view_scroll_to_mark", "gboolean"); Xen_check_type(Xen_is_gdouble(xalign), xalign, 5, "gtk_text_view_scroll_to_mark", "gdouble"); Xen_check_type(Xen_is_gdouble(yalign), yalign, 6, "gtk_text_view_scroll_to_mark", "gdouble"); gtk_text_view_scroll_to_mark(Xen_to_C_GtkTextView_(text_view), Xen_to_C_GtkTextMark_(mark), Xen_to_C_gdouble(within_margin), Xen_to_C_gboolean(use_align), Xen_to_C_gdouble(xalign), Xen_to_C_gdouble(yalign)); return(Xen_false); } static Xen gxg_gtk_text_view_scroll_mark_onscreen(Xen text_view, Xen mark) { #define H_gtk_text_view_scroll_mark_onscreen "void gtk_text_view_scroll_mark_onscreen(GtkTextView* text_view, \ GtkTextMark* mark)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_scroll_mark_onscreen", "GtkTextView*"); Xen_check_type(Xen_is_GtkTextMark_(mark), mark, 2, "gtk_text_view_scroll_mark_onscreen", "GtkTextMark*"); gtk_text_view_scroll_mark_onscreen(Xen_to_C_GtkTextView_(text_view), Xen_to_C_GtkTextMark_(mark)); return(Xen_false); } static Xen gxg_gtk_text_view_move_mark_onscreen(Xen text_view, Xen mark) { #define H_gtk_text_view_move_mark_onscreen "gboolean gtk_text_view_move_mark_onscreen(GtkTextView* text_view, \ GtkTextMark* mark)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_move_mark_onscreen", "GtkTextView*"); Xen_check_type(Xen_is_GtkTextMark_(mark), mark, 2, "gtk_text_view_move_mark_onscreen", "GtkTextMark*"); return(C_to_Xen_gboolean(gtk_text_view_move_mark_onscreen(Xen_to_C_GtkTextView_(text_view), Xen_to_C_GtkTextMark_(mark)))); } static Xen gxg_gtk_text_view_place_cursor_onscreen(Xen text_view) { #define H_gtk_text_view_place_cursor_onscreen "gboolean gtk_text_view_place_cursor_onscreen(GtkTextView* text_view)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_place_cursor_onscreen", "GtkTextView*"); return(C_to_Xen_gboolean(gtk_text_view_place_cursor_onscreen(Xen_to_C_GtkTextView_(text_view)))); } static Xen gxg_gtk_text_view_get_visible_rect(Xen text_view, Xen visible_rect) { #define H_gtk_text_view_get_visible_rect "void gtk_text_view_get_visible_rect(GtkTextView* text_view, \ GdkRectangle* visible_rect)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_get_visible_rect", "GtkTextView*"); Xen_check_type(Xen_is_GdkRectangle_(visible_rect), visible_rect, 2, "gtk_text_view_get_visible_rect", "GdkRectangle*"); gtk_text_view_get_visible_rect(Xen_to_C_GtkTextView_(text_view), Xen_to_C_GdkRectangle_(visible_rect)); return(Xen_false); } static Xen gxg_gtk_text_view_set_cursor_visible(Xen text_view, Xen setting) { #define H_gtk_text_view_set_cursor_visible "void gtk_text_view_set_cursor_visible(GtkTextView* text_view, \ gboolean setting)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_set_cursor_visible", "GtkTextView*"); Xen_check_type(Xen_is_gboolean(setting), setting, 2, "gtk_text_view_set_cursor_visible", "gboolean"); gtk_text_view_set_cursor_visible(Xen_to_C_GtkTextView_(text_view), Xen_to_C_gboolean(setting)); return(Xen_false); } static Xen gxg_gtk_text_view_get_cursor_visible(Xen text_view) { #define H_gtk_text_view_get_cursor_visible "gboolean gtk_text_view_get_cursor_visible(GtkTextView* text_view)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_get_cursor_visible", "GtkTextView*"); return(C_to_Xen_gboolean(gtk_text_view_get_cursor_visible(Xen_to_C_GtkTextView_(text_view)))); } static Xen gxg_gtk_text_view_get_iter_location(Xen text_view, Xen iter, Xen location) { #define H_gtk_text_view_get_iter_location "void gtk_text_view_get_iter_location(GtkTextView* text_view, \ GtkTextIter* iter, GdkRectangle* location)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_get_iter_location", "GtkTextView*"); Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 2, "gtk_text_view_get_iter_location", "GtkTextIter*"); Xen_check_type(Xen_is_GdkRectangle_(location), location, 3, "gtk_text_view_get_iter_location", "GdkRectangle*"); gtk_text_view_get_iter_location(Xen_to_C_GtkTextView_(text_view), Xen_to_C_GtkTextIter_(iter), Xen_to_C_GdkRectangle_(location)); return(Xen_false); } static Xen gxg_gtk_text_view_get_iter_at_location(Xen text_view, Xen iter, Xen x, Xen y) { #define H_gtk_text_view_get_iter_at_location "void gtk_text_view_get_iter_at_location(GtkTextView* text_view, \ GtkTextIter* iter, gint x, gint y)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_get_iter_at_location", "GtkTextView*"); Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 2, "gtk_text_view_get_iter_at_location", "GtkTextIter*"); Xen_check_type(Xen_is_gint(x), x, 3, "gtk_text_view_get_iter_at_location", "gint"); Xen_check_type(Xen_is_gint(y), y, 4, "gtk_text_view_get_iter_at_location", "gint"); gtk_text_view_get_iter_at_location(Xen_to_C_GtkTextView_(text_view), Xen_to_C_GtkTextIter_(iter), Xen_to_C_gint(x), Xen_to_C_gint(y)); return(Xen_false); } static Xen gxg_gtk_text_view_get_line_yrange(Xen text_view, Xen iter, Xen ignore_y, Xen ignore_height) { #define H_gtk_text_view_get_line_yrange "void gtk_text_view_get_line_yrange(GtkTextView* text_view, \ GtkTextIter* iter, gint* [y], gint* [height])" gint ref_y; gint ref_height; Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_get_line_yrange", "GtkTextView*"); Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 2, "gtk_text_view_get_line_yrange", "GtkTextIter*"); gtk_text_view_get_line_yrange(Xen_to_C_GtkTextView_(text_view), Xen_to_C_GtkTextIter_(iter), &ref_y, &ref_height); return(Xen_list_2(C_to_Xen_gint(ref_y), C_to_Xen_gint(ref_height))); } static Xen gxg_gtk_text_view_get_line_at_y(Xen text_view, Xen target_iter, Xen y, Xen ignore_line_top) { #define H_gtk_text_view_get_line_at_y "void gtk_text_view_get_line_at_y(GtkTextView* text_view, GtkTextIter* target_iter, \ gint y, gint* [line_top])" gint ref_line_top; Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_get_line_at_y", "GtkTextView*"); Xen_check_type(Xen_is_GtkTextIter_(target_iter), target_iter, 2, "gtk_text_view_get_line_at_y", "GtkTextIter*"); Xen_check_type(Xen_is_gint(y), y, 3, "gtk_text_view_get_line_at_y", "gint"); gtk_text_view_get_line_at_y(Xen_to_C_GtkTextView_(text_view), Xen_to_C_GtkTextIter_(target_iter), Xen_to_C_gint(y), &ref_line_top); return(Xen_list_1(C_to_Xen_gint(ref_line_top))); } static Xen gxg_gtk_text_view_buffer_to_window_coords(Xen text_view, Xen win, Xen buffer_x, Xen buffer_y, Xen ignore_window_x, Xen ignore_window_y) { #define H_gtk_text_view_buffer_to_window_coords "void gtk_text_view_buffer_to_window_coords(GtkTextView* text_view, \ GtkTextWindowType win, gint buffer_x, gint buffer_y, gint* [window_x], gint* [window_y])" gint ref_window_x; gint ref_window_y; Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_buffer_to_window_coords", "GtkTextView*"); Xen_check_type(Xen_is_GtkTextWindowType(win), win, 2, "gtk_text_view_buffer_to_window_coords", "GtkTextWindowType"); Xen_check_type(Xen_is_gint(buffer_x), buffer_x, 3, "gtk_text_view_buffer_to_window_coords", "gint"); Xen_check_type(Xen_is_gint(buffer_y), buffer_y, 4, "gtk_text_view_buffer_to_window_coords", "gint"); gtk_text_view_buffer_to_window_coords(Xen_to_C_GtkTextView_(text_view), Xen_to_C_GtkTextWindowType(win), Xen_to_C_gint(buffer_x), Xen_to_C_gint(buffer_y), &ref_window_x, &ref_window_y); return(Xen_list_2(C_to_Xen_gint(ref_window_x), C_to_Xen_gint(ref_window_y))); } static Xen gxg_gtk_text_view_window_to_buffer_coords(Xen text_view, Xen win, Xen window_x, Xen window_y, Xen ignore_buffer_x, Xen ignore_buffer_y) { #define H_gtk_text_view_window_to_buffer_coords "void gtk_text_view_window_to_buffer_coords(GtkTextView* text_view, \ GtkTextWindowType win, gint window_x, gint window_y, gint* [buffer_x], gint* [buffer_y])" gint ref_buffer_x; gint ref_buffer_y; Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_window_to_buffer_coords", "GtkTextView*"); Xen_check_type(Xen_is_GtkTextWindowType(win), win, 2, "gtk_text_view_window_to_buffer_coords", "GtkTextWindowType"); Xen_check_type(Xen_is_gint(window_x), window_x, 3, "gtk_text_view_window_to_buffer_coords", "gint"); Xen_check_type(Xen_is_gint(window_y), window_y, 4, "gtk_text_view_window_to_buffer_coords", "gint"); gtk_text_view_window_to_buffer_coords(Xen_to_C_GtkTextView_(text_view), Xen_to_C_GtkTextWindowType(win), Xen_to_C_gint(window_x), Xen_to_C_gint(window_y), &ref_buffer_x, &ref_buffer_y); return(Xen_list_2(C_to_Xen_gint(ref_buffer_x), C_to_Xen_gint(ref_buffer_y))); } static Xen gxg_gtk_text_view_get_window(Xen text_view, Xen win) { #define H_gtk_text_view_get_window "GdkWindow* gtk_text_view_get_window(GtkTextView* text_view, GtkTextWindowType win)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_get_window", "GtkTextView*"); Xen_check_type(Xen_is_GtkTextWindowType(win), win, 2, "gtk_text_view_get_window", "GtkTextWindowType"); return(C_to_Xen_GdkWindow_(gtk_text_view_get_window(Xen_to_C_GtkTextView_(text_view), Xen_to_C_GtkTextWindowType(win)))); } static Xen gxg_gtk_text_view_get_window_type(Xen text_view, Xen window) { #define H_gtk_text_view_get_window_type "GtkTextWindowType gtk_text_view_get_window_type(GtkTextView* text_view, \ GdkWindow* window)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_get_window_type", "GtkTextView*"); Xen_check_type(Xen_is_GdkWindow_(window), window, 2, "gtk_text_view_get_window_type", "GdkWindow*"); return(C_to_Xen_GtkTextWindowType(gtk_text_view_get_window_type(Xen_to_C_GtkTextView_(text_view), Xen_to_C_GdkWindow_(window)))); } static Xen gxg_gtk_text_view_set_border_window_size(Xen text_view, Xen type, Xen size) { #define H_gtk_text_view_set_border_window_size "void gtk_text_view_set_border_window_size(GtkTextView* text_view, \ GtkTextWindowType type, gint size)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_set_border_window_size", "GtkTextView*"); Xen_check_type(Xen_is_GtkTextWindowType(type), type, 2, "gtk_text_view_set_border_window_size", "GtkTextWindowType"); Xen_check_type(Xen_is_gint(size), size, 3, "gtk_text_view_set_border_window_size", "gint"); gtk_text_view_set_border_window_size(Xen_to_C_GtkTextView_(text_view), Xen_to_C_GtkTextWindowType(type), Xen_to_C_gint(size)); return(Xen_false); } static Xen gxg_gtk_text_view_get_border_window_size(Xen text_view, Xen type) { #define H_gtk_text_view_get_border_window_size "gint gtk_text_view_get_border_window_size(GtkTextView* text_view, \ GtkTextWindowType type)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_get_border_window_size", "GtkTextView*"); Xen_check_type(Xen_is_GtkTextWindowType(type), type, 2, "gtk_text_view_get_border_window_size", "GtkTextWindowType"); return(C_to_Xen_gint(gtk_text_view_get_border_window_size(Xen_to_C_GtkTextView_(text_view), Xen_to_C_GtkTextWindowType(type)))); } static Xen gxg_gtk_text_view_forward_display_line(Xen text_view, Xen iter) { #define H_gtk_text_view_forward_display_line "gboolean gtk_text_view_forward_display_line(GtkTextView* text_view, \ GtkTextIter* iter)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_forward_display_line", "GtkTextView*"); Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 2, "gtk_text_view_forward_display_line", "GtkTextIter*"); return(C_to_Xen_gboolean(gtk_text_view_forward_display_line(Xen_to_C_GtkTextView_(text_view), Xen_to_C_GtkTextIter_(iter)))); } static Xen gxg_gtk_text_view_backward_display_line(Xen text_view, Xen iter) { #define H_gtk_text_view_backward_display_line "gboolean gtk_text_view_backward_display_line(GtkTextView* text_view, \ GtkTextIter* iter)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_backward_display_line", "GtkTextView*"); Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 2, "gtk_text_view_backward_display_line", "GtkTextIter*"); return(C_to_Xen_gboolean(gtk_text_view_backward_display_line(Xen_to_C_GtkTextView_(text_view), Xen_to_C_GtkTextIter_(iter)))); } static Xen gxg_gtk_text_view_forward_display_line_end(Xen text_view, Xen iter) { #define H_gtk_text_view_forward_display_line_end "gboolean gtk_text_view_forward_display_line_end(GtkTextView* text_view, \ GtkTextIter* iter)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_forward_display_line_end", "GtkTextView*"); Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 2, "gtk_text_view_forward_display_line_end", "GtkTextIter*"); return(C_to_Xen_gboolean(gtk_text_view_forward_display_line_end(Xen_to_C_GtkTextView_(text_view), Xen_to_C_GtkTextIter_(iter)))); } static Xen gxg_gtk_text_view_backward_display_line_start(Xen text_view, Xen iter) { #define H_gtk_text_view_backward_display_line_start "gboolean gtk_text_view_backward_display_line_start(GtkTextView* text_view, \ GtkTextIter* iter)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_backward_display_line_start", "GtkTextView*"); Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 2, "gtk_text_view_backward_display_line_start", "GtkTextIter*"); return(C_to_Xen_gboolean(gtk_text_view_backward_display_line_start(Xen_to_C_GtkTextView_(text_view), Xen_to_C_GtkTextIter_(iter)))); } static Xen gxg_gtk_text_view_starts_display_line(Xen text_view, Xen iter) { #define H_gtk_text_view_starts_display_line "gboolean gtk_text_view_starts_display_line(GtkTextView* text_view, \ GtkTextIter* iter)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_starts_display_line", "GtkTextView*"); Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 2, "gtk_text_view_starts_display_line", "GtkTextIter*"); return(C_to_Xen_gboolean(gtk_text_view_starts_display_line(Xen_to_C_GtkTextView_(text_view), Xen_to_C_GtkTextIter_(iter)))); } static Xen gxg_gtk_text_view_move_visually(Xen text_view, Xen iter, Xen count) { #define H_gtk_text_view_move_visually "gboolean gtk_text_view_move_visually(GtkTextView* text_view, \ GtkTextIter* iter, gint count)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_move_visually", "GtkTextView*"); Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 2, "gtk_text_view_move_visually", "GtkTextIter*"); Xen_check_type(Xen_is_gint(count), count, 3, "gtk_text_view_move_visually", "gint"); return(C_to_Xen_gboolean(gtk_text_view_move_visually(Xen_to_C_GtkTextView_(text_view), Xen_to_C_GtkTextIter_(iter), Xen_to_C_gint(count)))); } static Xen gxg_gtk_text_view_add_child_at_anchor(Xen text_view, Xen child, Xen anchor) { #define H_gtk_text_view_add_child_at_anchor "void gtk_text_view_add_child_at_anchor(GtkTextView* text_view, \ GtkWidget* child, GtkTextChildAnchor* anchor)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_add_child_at_anchor", "GtkTextView*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_text_view_add_child_at_anchor", "GtkWidget*"); Xen_check_type(Xen_is_GtkTextChildAnchor_(anchor), anchor, 3, "gtk_text_view_add_child_at_anchor", "GtkTextChildAnchor*"); gtk_text_view_add_child_at_anchor(Xen_to_C_GtkTextView_(text_view), Xen_to_C_GtkWidget_(child), Xen_to_C_GtkTextChildAnchor_(anchor)); return(Xen_false); } static Xen gxg_gtk_text_view_add_child_in_window(Xen text_view, Xen child, Xen which_window, Xen xpos, Xen ypos) { #define H_gtk_text_view_add_child_in_window "void gtk_text_view_add_child_in_window(GtkTextView* text_view, \ GtkWidget* child, GtkTextWindowType which_window, gint xpos, gint ypos)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_add_child_in_window", "GtkTextView*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_text_view_add_child_in_window", "GtkWidget*"); Xen_check_type(Xen_is_GtkTextWindowType(which_window), which_window, 3, "gtk_text_view_add_child_in_window", "GtkTextWindowType"); Xen_check_type(Xen_is_gint(xpos), xpos, 4, "gtk_text_view_add_child_in_window", "gint"); Xen_check_type(Xen_is_gint(ypos), ypos, 5, "gtk_text_view_add_child_in_window", "gint"); gtk_text_view_add_child_in_window(Xen_to_C_GtkTextView_(text_view), Xen_to_C_GtkWidget_(child), Xen_to_C_GtkTextWindowType(which_window), Xen_to_C_gint(xpos), Xen_to_C_gint(ypos)); return(Xen_false); } static Xen gxg_gtk_text_view_move_child(Xen text_view, Xen child, Xen xpos, Xen ypos) { #define H_gtk_text_view_move_child "void gtk_text_view_move_child(GtkTextView* text_view, GtkWidget* child, \ gint xpos, gint ypos)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_move_child", "GtkTextView*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_text_view_move_child", "GtkWidget*"); Xen_check_type(Xen_is_gint(xpos), xpos, 3, "gtk_text_view_move_child", "gint"); Xen_check_type(Xen_is_gint(ypos), ypos, 4, "gtk_text_view_move_child", "gint"); gtk_text_view_move_child(Xen_to_C_GtkTextView_(text_view), Xen_to_C_GtkWidget_(child), Xen_to_C_gint(xpos), Xen_to_C_gint(ypos)); return(Xen_false); } static Xen gxg_gtk_text_view_set_wrap_mode(Xen text_view, Xen wrap_mode) { #define H_gtk_text_view_set_wrap_mode "void gtk_text_view_set_wrap_mode(GtkTextView* text_view, GtkWrapMode wrap_mode)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_set_wrap_mode", "GtkTextView*"); Xen_check_type(Xen_is_GtkWrapMode(wrap_mode), wrap_mode, 2, "gtk_text_view_set_wrap_mode", "GtkWrapMode"); gtk_text_view_set_wrap_mode(Xen_to_C_GtkTextView_(text_view), Xen_to_C_GtkWrapMode(wrap_mode)); return(Xen_false); } static Xen gxg_gtk_text_view_get_wrap_mode(Xen text_view) { #define H_gtk_text_view_get_wrap_mode "GtkWrapMode gtk_text_view_get_wrap_mode(GtkTextView* text_view)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_get_wrap_mode", "GtkTextView*"); return(C_to_Xen_GtkWrapMode(gtk_text_view_get_wrap_mode(Xen_to_C_GtkTextView_(text_view)))); } static Xen gxg_gtk_text_view_set_editable(Xen text_view, Xen setting) { #define H_gtk_text_view_set_editable "void gtk_text_view_set_editable(GtkTextView* text_view, gboolean setting)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_set_editable", "GtkTextView*"); Xen_check_type(Xen_is_gboolean(setting), setting, 2, "gtk_text_view_set_editable", "gboolean"); gtk_text_view_set_editable(Xen_to_C_GtkTextView_(text_view), Xen_to_C_gboolean(setting)); return(Xen_false); } static Xen gxg_gtk_text_view_get_editable(Xen text_view) { #define H_gtk_text_view_get_editable "gboolean gtk_text_view_get_editable(GtkTextView* text_view)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_get_editable", "GtkTextView*"); return(C_to_Xen_gboolean(gtk_text_view_get_editable(Xen_to_C_GtkTextView_(text_view)))); } static Xen gxg_gtk_text_view_set_pixels_above_lines(Xen text_view, Xen pixels_above_lines) { #define H_gtk_text_view_set_pixels_above_lines "void gtk_text_view_set_pixels_above_lines(GtkTextView* text_view, \ gint pixels_above_lines)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_set_pixels_above_lines", "GtkTextView*"); Xen_check_type(Xen_is_gint(pixels_above_lines), pixels_above_lines, 2, "gtk_text_view_set_pixels_above_lines", "gint"); gtk_text_view_set_pixels_above_lines(Xen_to_C_GtkTextView_(text_view), Xen_to_C_gint(pixels_above_lines)); return(Xen_false); } static Xen gxg_gtk_text_view_get_pixels_above_lines(Xen text_view) { #define H_gtk_text_view_get_pixels_above_lines "gint gtk_text_view_get_pixels_above_lines(GtkTextView* text_view)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_get_pixels_above_lines", "GtkTextView*"); return(C_to_Xen_gint(gtk_text_view_get_pixels_above_lines(Xen_to_C_GtkTextView_(text_view)))); } static Xen gxg_gtk_text_view_set_pixels_below_lines(Xen text_view, Xen pixels_below_lines) { #define H_gtk_text_view_set_pixels_below_lines "void gtk_text_view_set_pixels_below_lines(GtkTextView* text_view, \ gint pixels_below_lines)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_set_pixels_below_lines", "GtkTextView*"); Xen_check_type(Xen_is_gint(pixels_below_lines), pixels_below_lines, 2, "gtk_text_view_set_pixels_below_lines", "gint"); gtk_text_view_set_pixels_below_lines(Xen_to_C_GtkTextView_(text_view), Xen_to_C_gint(pixels_below_lines)); return(Xen_false); } static Xen gxg_gtk_text_view_get_pixels_below_lines(Xen text_view) { #define H_gtk_text_view_get_pixels_below_lines "gint gtk_text_view_get_pixels_below_lines(GtkTextView* text_view)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_get_pixels_below_lines", "GtkTextView*"); return(C_to_Xen_gint(gtk_text_view_get_pixels_below_lines(Xen_to_C_GtkTextView_(text_view)))); } static Xen gxg_gtk_text_view_set_pixels_inside_wrap(Xen text_view, Xen pixels_inside_wrap) { #define H_gtk_text_view_set_pixels_inside_wrap "void gtk_text_view_set_pixels_inside_wrap(GtkTextView* text_view, \ gint pixels_inside_wrap)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_set_pixels_inside_wrap", "GtkTextView*"); Xen_check_type(Xen_is_gint(pixels_inside_wrap), pixels_inside_wrap, 2, "gtk_text_view_set_pixels_inside_wrap", "gint"); gtk_text_view_set_pixels_inside_wrap(Xen_to_C_GtkTextView_(text_view), Xen_to_C_gint(pixels_inside_wrap)); return(Xen_false); } static Xen gxg_gtk_text_view_get_pixels_inside_wrap(Xen text_view) { #define H_gtk_text_view_get_pixels_inside_wrap "gint gtk_text_view_get_pixels_inside_wrap(GtkTextView* text_view)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_get_pixels_inside_wrap", "GtkTextView*"); return(C_to_Xen_gint(gtk_text_view_get_pixels_inside_wrap(Xen_to_C_GtkTextView_(text_view)))); } static Xen gxg_gtk_text_view_set_justification(Xen text_view, Xen justification) { #define H_gtk_text_view_set_justification "void gtk_text_view_set_justification(GtkTextView* text_view, \ GtkJustification justification)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_set_justification", "GtkTextView*"); Xen_check_type(Xen_is_GtkJustification(justification), justification, 2, "gtk_text_view_set_justification", "GtkJustification"); gtk_text_view_set_justification(Xen_to_C_GtkTextView_(text_view), Xen_to_C_GtkJustification(justification)); return(Xen_false); } static Xen gxg_gtk_text_view_get_justification(Xen text_view) { #define H_gtk_text_view_get_justification "GtkJustification gtk_text_view_get_justification(GtkTextView* text_view)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_get_justification", "GtkTextView*"); return(C_to_Xen_GtkJustification(gtk_text_view_get_justification(Xen_to_C_GtkTextView_(text_view)))); } static Xen gxg_gtk_text_view_set_left_margin(Xen text_view, Xen left_margin) { #define H_gtk_text_view_set_left_margin "void gtk_text_view_set_left_margin(GtkTextView* text_view, \ gint left_margin)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_set_left_margin", "GtkTextView*"); Xen_check_type(Xen_is_gint(left_margin), left_margin, 2, "gtk_text_view_set_left_margin", "gint"); gtk_text_view_set_left_margin(Xen_to_C_GtkTextView_(text_view), Xen_to_C_gint(left_margin)); return(Xen_false); } static Xen gxg_gtk_text_view_get_left_margin(Xen text_view) { #define H_gtk_text_view_get_left_margin "gint gtk_text_view_get_left_margin(GtkTextView* text_view)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_get_left_margin", "GtkTextView*"); return(C_to_Xen_gint(gtk_text_view_get_left_margin(Xen_to_C_GtkTextView_(text_view)))); } static Xen gxg_gtk_text_view_set_right_margin(Xen text_view, Xen right_margin) { #define H_gtk_text_view_set_right_margin "void gtk_text_view_set_right_margin(GtkTextView* text_view, \ gint right_margin)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_set_right_margin", "GtkTextView*"); Xen_check_type(Xen_is_gint(right_margin), right_margin, 2, "gtk_text_view_set_right_margin", "gint"); gtk_text_view_set_right_margin(Xen_to_C_GtkTextView_(text_view), Xen_to_C_gint(right_margin)); return(Xen_false); } static Xen gxg_gtk_text_view_get_right_margin(Xen text_view) { #define H_gtk_text_view_get_right_margin "gint gtk_text_view_get_right_margin(GtkTextView* text_view)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_get_right_margin", "GtkTextView*"); return(C_to_Xen_gint(gtk_text_view_get_right_margin(Xen_to_C_GtkTextView_(text_view)))); } static Xen gxg_gtk_text_view_set_indent(Xen text_view, Xen indent) { #define H_gtk_text_view_set_indent "void gtk_text_view_set_indent(GtkTextView* text_view, gint indent)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_set_indent", "GtkTextView*"); Xen_check_type(Xen_is_gint(indent), indent, 2, "gtk_text_view_set_indent", "gint"); gtk_text_view_set_indent(Xen_to_C_GtkTextView_(text_view), Xen_to_C_gint(indent)); return(Xen_false); } static Xen gxg_gtk_text_view_get_indent(Xen text_view) { #define H_gtk_text_view_get_indent "gint gtk_text_view_get_indent(GtkTextView* text_view)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_get_indent", "GtkTextView*"); return(C_to_Xen_gint(gtk_text_view_get_indent(Xen_to_C_GtkTextView_(text_view)))); } static Xen gxg_gtk_text_view_set_tabs(Xen text_view, Xen tabs) { #define H_gtk_text_view_set_tabs "void gtk_text_view_set_tabs(GtkTextView* text_view, PangoTabArray* tabs)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_set_tabs", "GtkTextView*"); Xen_check_type(Xen_is_PangoTabArray_(tabs) || Xen_is_false(tabs), tabs, 2, "gtk_text_view_set_tabs", "PangoTabArray*"); gtk_text_view_set_tabs(Xen_to_C_GtkTextView_(text_view), Xen_to_C_PangoTabArray_(tabs)); return(Xen_false); } static Xen gxg_gtk_text_view_get_tabs(Xen text_view) { #define H_gtk_text_view_get_tabs "PangoTabArray* gtk_text_view_get_tabs(GtkTextView* text_view)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_get_tabs", "GtkTextView*"); return(C_to_Xen_PangoTabArray_(gtk_text_view_get_tabs(Xen_to_C_GtkTextView_(text_view)))); } static Xen gxg_gtk_text_view_get_default_attributes(Xen text_view) { #define H_gtk_text_view_get_default_attributes "GtkTextAttributes* gtk_text_view_get_default_attributes(GtkTextView* text_view)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_get_default_attributes", "GtkTextView*"); return(C_to_Xen_GtkTextAttributes_(gtk_text_view_get_default_attributes(Xen_to_C_GtkTextView_(text_view)))); } static Xen gxg_gtk_toggle_button_new(void) { #define H_gtk_toggle_button_new "GtkWidget* gtk_toggle_button_new( void)" return(C_to_Xen_GtkWidget_(gtk_toggle_button_new())); } static Xen gxg_gtk_toggle_button_new_with_label(Xen label) { #define H_gtk_toggle_button_new_with_label "GtkWidget* gtk_toggle_button_new_with_label(gchar* label)" Xen_check_type(Xen_is_gchar_(label), label, 1, "gtk_toggle_button_new_with_label", "gchar*"); return(C_to_Xen_GtkWidget_(gtk_toggle_button_new_with_label(Xen_to_C_gchar_(label)))); } static Xen gxg_gtk_toggle_button_new_with_mnemonic(Xen label) { #define H_gtk_toggle_button_new_with_mnemonic "GtkWidget* gtk_toggle_button_new_with_mnemonic(gchar* label)" Xen_check_type(Xen_is_gchar_(label), label, 1, "gtk_toggle_button_new_with_mnemonic", "gchar*"); return(C_to_Xen_GtkWidget_(gtk_toggle_button_new_with_mnemonic(Xen_to_C_gchar_(label)))); } static Xen gxg_gtk_toggle_button_set_mode(Xen toggle_button, Xen draw_indicator) { #define H_gtk_toggle_button_set_mode "void gtk_toggle_button_set_mode(GtkToggleButton* toggle_button, \ gboolean draw_indicator)" Xen_check_type(Xen_is_GtkToggleButton_(toggle_button), toggle_button, 1, "gtk_toggle_button_set_mode", "GtkToggleButton*"); Xen_check_type(Xen_is_gboolean(draw_indicator), draw_indicator, 2, "gtk_toggle_button_set_mode", "gboolean"); gtk_toggle_button_set_mode(Xen_to_C_GtkToggleButton_(toggle_button), Xen_to_C_gboolean(draw_indicator)); return(Xen_false); } static Xen gxg_gtk_toggle_button_get_mode(Xen toggle_button) { #define H_gtk_toggle_button_get_mode "gboolean gtk_toggle_button_get_mode(GtkToggleButton* toggle_button)" Xen_check_type(Xen_is_GtkToggleButton_(toggle_button), toggle_button, 1, "gtk_toggle_button_get_mode", "GtkToggleButton*"); return(C_to_Xen_gboolean(gtk_toggle_button_get_mode(Xen_to_C_GtkToggleButton_(toggle_button)))); } static Xen gxg_gtk_toggle_button_set_active(Xen toggle_button, Xen is_active) { #define H_gtk_toggle_button_set_active "void gtk_toggle_button_set_active(GtkToggleButton* toggle_button, \ gboolean is_active)" Xen_check_type(Xen_is_GtkToggleButton_(toggle_button), toggle_button, 1, "gtk_toggle_button_set_active", "GtkToggleButton*"); Xen_check_type(Xen_is_gboolean(is_active), is_active, 2, "gtk_toggle_button_set_active", "gboolean"); gtk_toggle_button_set_active(Xen_to_C_GtkToggleButton_(toggle_button), Xen_to_C_gboolean(is_active)); return(Xen_false); } static Xen gxg_gtk_toggle_button_get_active(Xen toggle_button) { #define H_gtk_toggle_button_get_active "gboolean gtk_toggle_button_get_active(GtkToggleButton* toggle_button)" Xen_check_type(Xen_is_GtkToggleButton_(toggle_button), toggle_button, 1, "gtk_toggle_button_get_active", "GtkToggleButton*"); return(C_to_Xen_gboolean(gtk_toggle_button_get_active(Xen_to_C_GtkToggleButton_(toggle_button)))); } static Xen gxg_gtk_toggle_button_toggled(Xen toggle_button) { #define H_gtk_toggle_button_toggled "void gtk_toggle_button_toggled(GtkToggleButton* toggle_button)" Xen_check_type(Xen_is_GtkToggleButton_(toggle_button), toggle_button, 1, "gtk_toggle_button_toggled", "GtkToggleButton*"); gtk_toggle_button_toggled(Xen_to_C_GtkToggleButton_(toggle_button)); return(Xen_false); } static Xen gxg_gtk_toggle_button_set_inconsistent(Xen toggle_button, Xen setting) { #define H_gtk_toggle_button_set_inconsistent "void gtk_toggle_button_set_inconsistent(GtkToggleButton* toggle_button, \ gboolean setting)" Xen_check_type(Xen_is_GtkToggleButton_(toggle_button), toggle_button, 1, "gtk_toggle_button_set_inconsistent", "GtkToggleButton*"); Xen_check_type(Xen_is_gboolean(setting), setting, 2, "gtk_toggle_button_set_inconsistent", "gboolean"); gtk_toggle_button_set_inconsistent(Xen_to_C_GtkToggleButton_(toggle_button), Xen_to_C_gboolean(setting)); return(Xen_false); } static Xen gxg_gtk_toggle_button_get_inconsistent(Xen toggle_button) { #define H_gtk_toggle_button_get_inconsistent "gboolean gtk_toggle_button_get_inconsistent(GtkToggleButton* toggle_button)" Xen_check_type(Xen_is_GtkToggleButton_(toggle_button), toggle_button, 1, "gtk_toggle_button_get_inconsistent", "GtkToggleButton*"); return(C_to_Xen_gboolean(gtk_toggle_button_get_inconsistent(Xen_to_C_GtkToggleButton_(toggle_button)))); } static Xen gxg_gtk_toolbar_new(void) { #define H_gtk_toolbar_new "GtkWidget* gtk_toolbar_new( void)" return(C_to_Xen_GtkWidget_(gtk_toolbar_new())); } static Xen gxg_gtk_toolbar_set_style(Xen toolbar, Xen style) { #define H_gtk_toolbar_set_style "void gtk_toolbar_set_style(GtkToolbar* toolbar, GtkToolbarStyle style)" Xen_check_type(Xen_is_GtkToolbar_(toolbar), toolbar, 1, "gtk_toolbar_set_style", "GtkToolbar*"); Xen_check_type(Xen_is_GtkToolbarStyle(style), style, 2, "gtk_toolbar_set_style", "GtkToolbarStyle"); gtk_toolbar_set_style(Xen_to_C_GtkToolbar_(toolbar), Xen_to_C_GtkToolbarStyle(style)); return(Xen_false); } static Xen gxg_gtk_toolbar_unset_style(Xen toolbar) { #define H_gtk_toolbar_unset_style "void gtk_toolbar_unset_style(GtkToolbar* toolbar)" Xen_check_type(Xen_is_GtkToolbar_(toolbar), toolbar, 1, "gtk_toolbar_unset_style", "GtkToolbar*"); gtk_toolbar_unset_style(Xen_to_C_GtkToolbar_(toolbar)); return(Xen_false); } static Xen gxg_gtk_toolbar_get_style(Xen toolbar) { #define H_gtk_toolbar_get_style "GtkToolbarStyle gtk_toolbar_get_style(GtkToolbar* toolbar)" Xen_check_type(Xen_is_GtkToolbar_(toolbar), toolbar, 1, "gtk_toolbar_get_style", "GtkToolbar*"); return(C_to_Xen_GtkToolbarStyle(gtk_toolbar_get_style(Xen_to_C_GtkToolbar_(toolbar)))); } static Xen gxg_gtk_tree_drag_source_row_draggable(Xen drag_source, Xen path) { #define H_gtk_tree_drag_source_row_draggable "gboolean gtk_tree_drag_source_row_draggable(GtkTreeDragSource* drag_source, \ GtkTreePath* path)" Xen_check_type(Xen_is_GtkTreeDragSource_(drag_source), drag_source, 1, "gtk_tree_drag_source_row_draggable", "GtkTreeDragSource*"); Xen_check_type(Xen_is_GtkTreePath_(path), path, 2, "gtk_tree_drag_source_row_draggable", "GtkTreePath*"); return(C_to_Xen_gboolean(gtk_tree_drag_source_row_draggable(Xen_to_C_GtkTreeDragSource_(drag_source), Xen_to_C_GtkTreePath_(path)))); } static Xen gxg_gtk_tree_drag_source_drag_data_delete(Xen drag_source, Xen path) { #define H_gtk_tree_drag_source_drag_data_delete "gboolean gtk_tree_drag_source_drag_data_delete(GtkTreeDragSource* drag_source, \ GtkTreePath* path)" Xen_check_type(Xen_is_GtkTreeDragSource_(drag_source), drag_source, 1, "gtk_tree_drag_source_drag_data_delete", "GtkTreeDragSource*"); Xen_check_type(Xen_is_GtkTreePath_(path), path, 2, "gtk_tree_drag_source_drag_data_delete", "GtkTreePath*"); return(C_to_Xen_gboolean(gtk_tree_drag_source_drag_data_delete(Xen_to_C_GtkTreeDragSource_(drag_source), Xen_to_C_GtkTreePath_(path)))); } static Xen gxg_gtk_tree_drag_source_drag_data_get(Xen drag_source, Xen path, Xen selection_data) { #define H_gtk_tree_drag_source_drag_data_get "gboolean gtk_tree_drag_source_drag_data_get(GtkTreeDragSource* drag_source, \ GtkTreePath* path, GtkSelectionData* selection_data)" Xen_check_type(Xen_is_GtkTreeDragSource_(drag_source), drag_source, 1, "gtk_tree_drag_source_drag_data_get", "GtkTreeDragSource*"); Xen_check_type(Xen_is_GtkTreePath_(path), path, 2, "gtk_tree_drag_source_drag_data_get", "GtkTreePath*"); Xen_check_type(Xen_is_GtkSelectionData_(selection_data), selection_data, 3, "gtk_tree_drag_source_drag_data_get", "GtkSelectionData*"); return(C_to_Xen_gboolean(gtk_tree_drag_source_drag_data_get(Xen_to_C_GtkTreeDragSource_(drag_source), Xen_to_C_GtkTreePath_(path), Xen_to_C_GtkSelectionData_(selection_data)))); } static Xen gxg_gtk_tree_drag_dest_drag_data_received(Xen drag_dest, Xen dest, Xen selection_data) { #define H_gtk_tree_drag_dest_drag_data_received "gboolean gtk_tree_drag_dest_drag_data_received(GtkTreeDragDest* drag_dest, \ GtkTreePath* dest, GtkSelectionData* selection_data)" Xen_check_type(Xen_is_GtkTreeDragDest_(drag_dest), drag_dest, 1, "gtk_tree_drag_dest_drag_data_received", "GtkTreeDragDest*"); Xen_check_type(Xen_is_GtkTreePath_(dest), dest, 2, "gtk_tree_drag_dest_drag_data_received", "GtkTreePath*"); Xen_check_type(Xen_is_GtkSelectionData_(selection_data), selection_data, 3, "gtk_tree_drag_dest_drag_data_received", "GtkSelectionData*"); return(C_to_Xen_gboolean(gtk_tree_drag_dest_drag_data_received(Xen_to_C_GtkTreeDragDest_(drag_dest), Xen_to_C_GtkTreePath_(dest), Xen_to_C_GtkSelectionData_(selection_data)))); } static Xen gxg_gtk_tree_drag_dest_row_drop_possible(Xen drag_dest, Xen dest_path, Xen selection_data) { #define H_gtk_tree_drag_dest_row_drop_possible "gboolean gtk_tree_drag_dest_row_drop_possible(GtkTreeDragDest* drag_dest, \ GtkTreePath* dest_path, GtkSelectionData* selection_data)" Xen_check_type(Xen_is_GtkTreeDragDest_(drag_dest), drag_dest, 1, "gtk_tree_drag_dest_row_drop_possible", "GtkTreeDragDest*"); Xen_check_type(Xen_is_GtkTreePath_(dest_path), dest_path, 2, "gtk_tree_drag_dest_row_drop_possible", "GtkTreePath*"); Xen_check_type(Xen_is_GtkSelectionData_(selection_data), selection_data, 3, "gtk_tree_drag_dest_row_drop_possible", "GtkSelectionData*"); return(C_to_Xen_gboolean(gtk_tree_drag_dest_row_drop_possible(Xen_to_C_GtkTreeDragDest_(drag_dest), Xen_to_C_GtkTreePath_(dest_path), Xen_to_C_GtkSelectionData_(selection_data)))); } static Xen gxg_gtk_tree_set_row_drag_data(Xen selection_data, Xen tree_model, Xen path) { #define H_gtk_tree_set_row_drag_data "gboolean gtk_tree_set_row_drag_data(GtkSelectionData* selection_data, \ GtkTreeModel* tree_model, GtkTreePath* path)" Xen_check_type(Xen_is_GtkSelectionData_(selection_data), selection_data, 1, "gtk_tree_set_row_drag_data", "GtkSelectionData*"); Xen_check_type(Xen_is_GtkTreeModel_(tree_model), tree_model, 2, "gtk_tree_set_row_drag_data", "GtkTreeModel*"); Xen_check_type(Xen_is_GtkTreePath_(path), path, 3, "gtk_tree_set_row_drag_data", "GtkTreePath*"); return(C_to_Xen_gboolean(gtk_tree_set_row_drag_data(Xen_to_C_GtkSelectionData_(selection_data), Xen_to_C_GtkTreeModel_(tree_model), Xen_to_C_GtkTreePath_(path)))); } static Xen gxg_gtk_tree_get_row_drag_data(Xen selection_data, Xen ignore_tree_model, Xen ignore_path) { #define H_gtk_tree_get_row_drag_data "gboolean gtk_tree_get_row_drag_data(GtkSelectionData* selection_data, \ GtkTreeModel** [tree_model], GtkTreePath** [path])" GtkTreeModel* ref_tree_model = NULL; GtkTreePath* ref_path = NULL; Xen_check_type(Xen_is_GtkSelectionData_(selection_data), selection_data, 1, "gtk_tree_get_row_drag_data", "GtkSelectionData*"); { Xen result; result = C_to_Xen_gboolean(gtk_tree_get_row_drag_data(Xen_to_C_GtkSelectionData_(selection_data), &ref_tree_model, &ref_path)); return(Xen_list_3(result, C_to_Xen_GtkTreeModel_(ref_tree_model), C_to_Xen_GtkTreePath_(ref_path))); } } static Xen gxg_gtk_tree_path_new(void) { #define H_gtk_tree_path_new "GtkTreePath* gtk_tree_path_new( void)" return(C_to_Xen_GtkTreePath_(gtk_tree_path_new())); } static Xen gxg_gtk_tree_path_new_from_string(Xen path) { #define H_gtk_tree_path_new_from_string "GtkTreePath* gtk_tree_path_new_from_string(gchar* path)" Xen_check_type(Xen_is_gchar_(path), path, 1, "gtk_tree_path_new_from_string", "gchar*"); return(C_to_Xen_GtkTreePath_(gtk_tree_path_new_from_string(Xen_to_C_gchar_(path)))); } static Xen gxg_gtk_tree_path_to_string(Xen path) { #define H_gtk_tree_path_to_string "gchar* gtk_tree_path_to_string(GtkTreePath* path)" Xen_check_type(Xen_is_GtkTreePath_(path), path, 1, "gtk_tree_path_to_string", "GtkTreePath*"); { gchar* result; Xen rtn; result = gtk_tree_path_to_string(Xen_to_C_GtkTreePath_(path)); rtn = C_to_Xen_gchar_(result); g_free(result); return(rtn); } } static Xen gxg_gtk_tree_path_new_first(void) { #define H_gtk_tree_path_new_first "GtkTreePath* gtk_tree_path_new_first( void)" return(C_to_Xen_GtkTreePath_(gtk_tree_path_new_first())); } static Xen gxg_gtk_tree_path_append_index(Xen path, Xen index) { #define H_gtk_tree_path_append_index "void gtk_tree_path_append_index(GtkTreePath* path, gint index)" Xen_check_type(Xen_is_GtkTreePath_(path), path, 1, "gtk_tree_path_append_index", "GtkTreePath*"); Xen_check_type(Xen_is_gint(index), index, 2, "gtk_tree_path_append_index", "gint"); gtk_tree_path_append_index(Xen_to_C_GtkTreePath_(path), Xen_to_C_gint(index)); return(Xen_false); } static Xen gxg_gtk_tree_path_prepend_index(Xen path, Xen index) { #define H_gtk_tree_path_prepend_index "void gtk_tree_path_prepend_index(GtkTreePath* path, gint index)" Xen_check_type(Xen_is_GtkTreePath_(path), path, 1, "gtk_tree_path_prepend_index", "GtkTreePath*"); Xen_check_type(Xen_is_gint(index), index, 2, "gtk_tree_path_prepend_index", "gint"); gtk_tree_path_prepend_index(Xen_to_C_GtkTreePath_(path), Xen_to_C_gint(index)); return(Xen_false); } static Xen gxg_gtk_tree_path_get_depth(Xen path) { #define H_gtk_tree_path_get_depth "gint gtk_tree_path_get_depth(GtkTreePath* path)" Xen_check_type(Xen_is_GtkTreePath_(path), path, 1, "gtk_tree_path_get_depth", "GtkTreePath*"); return(C_to_Xen_gint(gtk_tree_path_get_depth(Xen_to_C_GtkTreePath_(path)))); } static Xen gxg_gtk_tree_path_get_indices(Xen path) { #define H_gtk_tree_path_get_indices "gint* gtk_tree_path_get_indices(GtkTreePath* path)" Xen_check_type(Xen_is_GtkTreePath_(path), path, 1, "gtk_tree_path_get_indices", "GtkTreePath*"); return(C_to_Xen_gint_(gtk_tree_path_get_indices(Xen_to_C_GtkTreePath_(path)))); } static Xen gxg_gtk_tree_path_free(Xen path) { #define H_gtk_tree_path_free "void gtk_tree_path_free(GtkTreePath* path)" Xen_check_type(Xen_is_GtkTreePath_(path), path, 1, "gtk_tree_path_free", "GtkTreePath*"); gtk_tree_path_free(Xen_to_C_GtkTreePath_(path)); return(Xen_false); } static Xen gxg_gtk_tree_path_copy(Xen path) { #define H_gtk_tree_path_copy "GtkTreePath* gtk_tree_path_copy(GtkTreePath* path)" Xen_check_type(Xen_is_GtkTreePath_(path), path, 1, "gtk_tree_path_copy", "GtkTreePath*"); return(C_to_Xen_GtkTreePath_(gtk_tree_path_copy(Xen_to_C_GtkTreePath_(path)))); } static Xen gxg_gtk_tree_path_compare(Xen a, Xen b) { #define H_gtk_tree_path_compare "gint gtk_tree_path_compare(GtkTreePath* a, GtkTreePath* b)" Xen_check_type(Xen_is_GtkTreePath_(a), a, 1, "gtk_tree_path_compare", "GtkTreePath*"); Xen_check_type(Xen_is_GtkTreePath_(b), b, 2, "gtk_tree_path_compare", "GtkTreePath*"); return(C_to_Xen_gint(gtk_tree_path_compare(Xen_to_C_GtkTreePath_(a), Xen_to_C_GtkTreePath_(b)))); } static Xen gxg_gtk_tree_path_next(Xen path) { #define H_gtk_tree_path_next "void gtk_tree_path_next(GtkTreePath* path)" Xen_check_type(Xen_is_GtkTreePath_(path), path, 1, "gtk_tree_path_next", "GtkTreePath*"); gtk_tree_path_next(Xen_to_C_GtkTreePath_(path)); return(Xen_false); } static Xen gxg_gtk_tree_path_prev(Xen path) { #define H_gtk_tree_path_prev "gboolean gtk_tree_path_prev(GtkTreePath* path)" Xen_check_type(Xen_is_GtkTreePath_(path), path, 1, "gtk_tree_path_prev", "GtkTreePath*"); return(C_to_Xen_gboolean(gtk_tree_path_prev(Xen_to_C_GtkTreePath_(path)))); } static Xen gxg_gtk_tree_path_up(Xen path) { #define H_gtk_tree_path_up "gboolean gtk_tree_path_up(GtkTreePath* path)" Xen_check_type(Xen_is_GtkTreePath_(path), path, 1, "gtk_tree_path_up", "GtkTreePath*"); return(C_to_Xen_gboolean(gtk_tree_path_up(Xen_to_C_GtkTreePath_(path)))); } static Xen gxg_gtk_tree_path_down(Xen path) { #define H_gtk_tree_path_down "void gtk_tree_path_down(GtkTreePath* path)" Xen_check_type(Xen_is_GtkTreePath_(path), path, 1, "gtk_tree_path_down", "GtkTreePath*"); gtk_tree_path_down(Xen_to_C_GtkTreePath_(path)); return(Xen_false); } static Xen gxg_gtk_tree_path_is_ancestor(Xen path, Xen descendant) { #define H_gtk_tree_path_is_ancestor "gboolean gtk_tree_path_is_ancestor(GtkTreePath* path, GtkTreePath* descendant)" Xen_check_type(Xen_is_GtkTreePath_(path), path, 1, "gtk_tree_path_is_ancestor", "GtkTreePath*"); Xen_check_type(Xen_is_GtkTreePath_(descendant), descendant, 2, "gtk_tree_path_is_ancestor", "GtkTreePath*"); return(C_to_Xen_gboolean(gtk_tree_path_is_ancestor(Xen_to_C_GtkTreePath_(path), Xen_to_C_GtkTreePath_(descendant)))); } static Xen gxg_gtk_tree_path_is_descendant(Xen path, Xen ancestor) { #define H_gtk_tree_path_is_descendant "gboolean gtk_tree_path_is_descendant(GtkTreePath* path, GtkTreePath* ancestor)" Xen_check_type(Xen_is_GtkTreePath_(path), path, 1, "gtk_tree_path_is_descendant", "GtkTreePath*"); Xen_check_type(Xen_is_GtkTreePath_(ancestor), ancestor, 2, "gtk_tree_path_is_descendant", "GtkTreePath*"); return(C_to_Xen_gboolean(gtk_tree_path_is_descendant(Xen_to_C_GtkTreePath_(path), Xen_to_C_GtkTreePath_(ancestor)))); } static Xen gxg_gtk_tree_row_reference_new(Xen model, Xen path) { #define H_gtk_tree_row_reference_new "GtkTreeRowReference* gtk_tree_row_reference_new(GtkTreeModel* model, \ GtkTreePath* path)" Xen_check_type(Xen_is_GtkTreeModel_(model), model, 1, "gtk_tree_row_reference_new", "GtkTreeModel*"); Xen_check_type(Xen_is_GtkTreePath_(path), path, 2, "gtk_tree_row_reference_new", "GtkTreePath*"); return(C_to_Xen_GtkTreeRowReference_(gtk_tree_row_reference_new(Xen_to_C_GtkTreeModel_(model), Xen_to_C_GtkTreePath_(path)))); } static Xen gxg_gtk_tree_row_reference_new_proxy(Xen proxy, Xen model, Xen path) { #define H_gtk_tree_row_reference_new_proxy "GtkTreeRowReference* gtk_tree_row_reference_new_proxy(GObject* proxy, \ GtkTreeModel* model, GtkTreePath* path)" Xen_check_type(Xen_is_GObject_(proxy), proxy, 1, "gtk_tree_row_reference_new_proxy", "GObject*"); Xen_check_type(Xen_is_GtkTreeModel_(model), model, 2, "gtk_tree_row_reference_new_proxy", "GtkTreeModel*"); Xen_check_type(Xen_is_GtkTreePath_(path), path, 3, "gtk_tree_row_reference_new_proxy", "GtkTreePath*"); return(C_to_Xen_GtkTreeRowReference_(gtk_tree_row_reference_new_proxy(Xen_to_C_GObject_(proxy), Xen_to_C_GtkTreeModel_(model), Xen_to_C_GtkTreePath_(path)))); } static Xen gxg_gtk_tree_row_reference_get_path(Xen reference) { #define H_gtk_tree_row_reference_get_path "GtkTreePath* gtk_tree_row_reference_get_path(GtkTreeRowReference* reference)" Xen_check_type(Xen_is_GtkTreeRowReference_(reference), reference, 1, "gtk_tree_row_reference_get_path", "GtkTreeRowReference*"); return(C_to_Xen_GtkTreePath_(gtk_tree_row_reference_get_path(Xen_to_C_GtkTreeRowReference_(reference)))); } static Xen gxg_gtk_tree_row_reference_valid(Xen reference) { #define H_gtk_tree_row_reference_valid "gboolean gtk_tree_row_reference_valid(GtkTreeRowReference* reference)" Xen_check_type(Xen_is_GtkTreeRowReference_(reference), reference, 1, "gtk_tree_row_reference_valid", "GtkTreeRowReference*"); return(C_to_Xen_gboolean(gtk_tree_row_reference_valid(Xen_to_C_GtkTreeRowReference_(reference)))); } static Xen gxg_gtk_tree_row_reference_free(Xen reference) { #define H_gtk_tree_row_reference_free "void gtk_tree_row_reference_free(GtkTreeRowReference* reference)" Xen_check_type(Xen_is_GtkTreeRowReference_(reference), reference, 1, "gtk_tree_row_reference_free", "GtkTreeRowReference*"); gtk_tree_row_reference_free(Xen_to_C_GtkTreeRowReference_(reference)); return(Xen_false); } static Xen gxg_gtk_tree_row_reference_inserted(Xen proxy, Xen path) { #define H_gtk_tree_row_reference_inserted "void gtk_tree_row_reference_inserted(GObject* proxy, GtkTreePath* path)" Xen_check_type(Xen_is_GObject_(proxy), proxy, 1, "gtk_tree_row_reference_inserted", "GObject*"); Xen_check_type(Xen_is_GtkTreePath_(path), path, 2, "gtk_tree_row_reference_inserted", "GtkTreePath*"); gtk_tree_row_reference_inserted(Xen_to_C_GObject_(proxy), Xen_to_C_GtkTreePath_(path)); return(Xen_false); } static Xen gxg_gtk_tree_row_reference_deleted(Xen proxy, Xen path) { #define H_gtk_tree_row_reference_deleted "void gtk_tree_row_reference_deleted(GObject* proxy, GtkTreePath* path)" Xen_check_type(Xen_is_GObject_(proxy), proxy, 1, "gtk_tree_row_reference_deleted", "GObject*"); Xen_check_type(Xen_is_GtkTreePath_(path), path, 2, "gtk_tree_row_reference_deleted", "GtkTreePath*"); gtk_tree_row_reference_deleted(Xen_to_C_GObject_(proxy), Xen_to_C_GtkTreePath_(path)); return(Xen_false); } static Xen gxg_gtk_tree_row_reference_reordered(Xen proxy, Xen path, Xen iter, Xen new_order) { #define H_gtk_tree_row_reference_reordered "void gtk_tree_row_reference_reordered(GObject* proxy, GtkTreePath* path, \ GtkTreeIter* iter, gint* new_order)" Xen_check_type(Xen_is_GObject_(proxy), proxy, 1, "gtk_tree_row_reference_reordered", "GObject*"); Xen_check_type(Xen_is_GtkTreePath_(path), path, 2, "gtk_tree_row_reference_reordered", "GtkTreePath*"); Xen_check_type(Xen_is_GtkTreeIter_(iter), iter, 3, "gtk_tree_row_reference_reordered", "GtkTreeIter*"); Xen_check_type(Xen_is_gint_(new_order), new_order, 4, "gtk_tree_row_reference_reordered", "gint*"); gtk_tree_row_reference_reordered(Xen_to_C_GObject_(proxy), Xen_to_C_GtkTreePath_(path), Xen_to_C_GtkTreeIter_(iter), Xen_to_C_gint_(new_order)); return(Xen_false); } static Xen gxg_gtk_tree_iter_copy(Xen iter) { #define H_gtk_tree_iter_copy "GtkTreeIter* gtk_tree_iter_copy(GtkTreeIter* iter)" Xen_check_type(Xen_is_GtkTreeIter_(iter), iter, 1, "gtk_tree_iter_copy", "GtkTreeIter*"); return(C_to_Xen_GtkTreeIter_(gtk_tree_iter_copy(Xen_to_C_GtkTreeIter_(iter)))); } static Xen gxg_gtk_tree_iter_free(Xen iter) { #define H_gtk_tree_iter_free "void gtk_tree_iter_free(GtkTreeIter* iter)" Xen_check_type(Xen_is_GtkTreeIter_(iter), iter, 1, "gtk_tree_iter_free", "GtkTreeIter*"); gtk_tree_iter_free(Xen_to_C_GtkTreeIter_(iter)); return(Xen_false); } static Xen gxg_gtk_tree_model_get_flags(Xen tree_model) { #define H_gtk_tree_model_get_flags "GtkTreeModelFlags gtk_tree_model_get_flags(GtkTreeModel* tree_model)" Xen_check_type(Xen_is_GtkTreeModel_(tree_model), tree_model, 1, "gtk_tree_model_get_flags", "GtkTreeModel*"); return(C_to_Xen_GtkTreeModelFlags(gtk_tree_model_get_flags(Xen_to_C_GtkTreeModel_(tree_model)))); } static Xen gxg_gtk_tree_model_get_n_columns(Xen tree_model) { #define H_gtk_tree_model_get_n_columns "gint gtk_tree_model_get_n_columns(GtkTreeModel* tree_model)" Xen_check_type(Xen_is_GtkTreeModel_(tree_model), tree_model, 1, "gtk_tree_model_get_n_columns", "GtkTreeModel*"); return(C_to_Xen_gint(gtk_tree_model_get_n_columns(Xen_to_C_GtkTreeModel_(tree_model)))); } static Xen gxg_gtk_tree_model_get_column_type(Xen tree_model, Xen index) { #define H_gtk_tree_model_get_column_type "GType gtk_tree_model_get_column_type(GtkTreeModel* tree_model, \ gint index)" Xen_check_type(Xen_is_GtkTreeModel_(tree_model), tree_model, 1, "gtk_tree_model_get_column_type", "GtkTreeModel*"); Xen_check_type(Xen_is_gint(index), index, 2, "gtk_tree_model_get_column_type", "gint"); return(C_to_Xen_GType(gtk_tree_model_get_column_type(Xen_to_C_GtkTreeModel_(tree_model), Xen_to_C_gint(index)))); } static Xen gxg_gtk_tree_model_get_iter(Xen tree_model, Xen iter, Xen path) { #define H_gtk_tree_model_get_iter "gboolean gtk_tree_model_get_iter(GtkTreeModel* tree_model, GtkTreeIter* iter, \ GtkTreePath* path)" Xen_check_type(Xen_is_GtkTreeModel_(tree_model), tree_model, 1, "gtk_tree_model_get_iter", "GtkTreeModel*"); Xen_check_type(Xen_is_GtkTreeIter_(iter), iter, 2, "gtk_tree_model_get_iter", "GtkTreeIter*"); Xen_check_type(Xen_is_GtkTreePath_(path), path, 3, "gtk_tree_model_get_iter", "GtkTreePath*"); return(C_to_Xen_gboolean(gtk_tree_model_get_iter(Xen_to_C_GtkTreeModel_(tree_model), Xen_to_C_GtkTreeIter_(iter), Xen_to_C_GtkTreePath_(path)))); } static Xen gxg_gtk_tree_model_get_iter_from_string(Xen tree_model, Xen iter, Xen path_string) { #define H_gtk_tree_model_get_iter_from_string "gboolean gtk_tree_model_get_iter_from_string(GtkTreeModel* tree_model, \ GtkTreeIter* iter, gchar* path_string)" Xen_check_type(Xen_is_GtkTreeModel_(tree_model), tree_model, 1, "gtk_tree_model_get_iter_from_string", "GtkTreeModel*"); Xen_check_type(Xen_is_GtkTreeIter_(iter), iter, 2, "gtk_tree_model_get_iter_from_string", "GtkTreeIter*"); Xen_check_type(Xen_is_gchar_(path_string), path_string, 3, "gtk_tree_model_get_iter_from_string", "gchar*"); return(C_to_Xen_gboolean(gtk_tree_model_get_iter_from_string(Xen_to_C_GtkTreeModel_(tree_model), Xen_to_C_GtkTreeIter_(iter), Xen_to_C_gchar_(path_string)))); } static Xen gxg_gtk_tree_model_get_iter_first(Xen tree_model, Xen iter) { #define H_gtk_tree_model_get_iter_first "gboolean gtk_tree_model_get_iter_first(GtkTreeModel* tree_model, \ GtkTreeIter* iter)" Xen_check_type(Xen_is_GtkTreeModel_(tree_model), tree_model, 1, "gtk_tree_model_get_iter_first", "GtkTreeModel*"); Xen_check_type(Xen_is_GtkTreeIter_(iter), iter, 2, "gtk_tree_model_get_iter_first", "GtkTreeIter*"); return(C_to_Xen_gboolean(gtk_tree_model_get_iter_first(Xen_to_C_GtkTreeModel_(tree_model), Xen_to_C_GtkTreeIter_(iter)))); } static Xen gxg_gtk_tree_model_get_path(Xen tree_model, Xen iter) { #define H_gtk_tree_model_get_path "GtkTreePath* gtk_tree_model_get_path(GtkTreeModel* tree_model, GtkTreeIter* iter)" Xen_check_type(Xen_is_GtkTreeModel_(tree_model), tree_model, 1, "gtk_tree_model_get_path", "GtkTreeModel*"); Xen_check_type(Xen_is_GtkTreeIter_(iter), iter, 2, "gtk_tree_model_get_path", "GtkTreeIter*"); return(C_to_Xen_GtkTreePath_(gtk_tree_model_get_path(Xen_to_C_GtkTreeModel_(tree_model), Xen_to_C_GtkTreeIter_(iter)))); } static Xen gxg_gtk_tree_model_iter_next(Xen tree_model, Xen iter) { #define H_gtk_tree_model_iter_next "gboolean gtk_tree_model_iter_next(GtkTreeModel* tree_model, GtkTreeIter* iter)" Xen_check_type(Xen_is_GtkTreeModel_(tree_model), tree_model, 1, "gtk_tree_model_iter_next", "GtkTreeModel*"); Xen_check_type(Xen_is_GtkTreeIter_(iter), iter, 2, "gtk_tree_model_iter_next", "GtkTreeIter*"); return(C_to_Xen_gboolean(gtk_tree_model_iter_next(Xen_to_C_GtkTreeModel_(tree_model), Xen_to_C_GtkTreeIter_(iter)))); } static Xen gxg_gtk_tree_model_iter_children(Xen tree_model, Xen iter, Xen parent) { #define H_gtk_tree_model_iter_children "gboolean gtk_tree_model_iter_children(GtkTreeModel* tree_model, \ GtkTreeIter* iter, GtkTreeIter* parent)" Xen_check_type(Xen_is_GtkTreeModel_(tree_model), tree_model, 1, "gtk_tree_model_iter_children", "GtkTreeModel*"); Xen_check_type(Xen_is_GtkTreeIter_(iter), iter, 2, "gtk_tree_model_iter_children", "GtkTreeIter*"); Xen_check_type(Xen_is_GtkTreeIter_(parent) || Xen_is_false(parent), parent, 3, "gtk_tree_model_iter_children", "GtkTreeIter*"); return(C_to_Xen_gboolean(gtk_tree_model_iter_children(Xen_to_C_GtkTreeModel_(tree_model), Xen_to_C_GtkTreeIter_(iter), Xen_to_C_GtkTreeIter_(parent)))); } static Xen gxg_gtk_tree_model_iter_has_child(Xen tree_model, Xen iter) { #define H_gtk_tree_model_iter_has_child "gboolean gtk_tree_model_iter_has_child(GtkTreeModel* tree_model, \ GtkTreeIter* iter)" Xen_check_type(Xen_is_GtkTreeModel_(tree_model), tree_model, 1, "gtk_tree_model_iter_has_child", "GtkTreeModel*"); Xen_check_type(Xen_is_GtkTreeIter_(iter), iter, 2, "gtk_tree_model_iter_has_child", "GtkTreeIter*"); return(C_to_Xen_gboolean(gtk_tree_model_iter_has_child(Xen_to_C_GtkTreeModel_(tree_model), Xen_to_C_GtkTreeIter_(iter)))); } static Xen gxg_gtk_tree_model_iter_n_children(Xen tree_model, Xen iter) { #define H_gtk_tree_model_iter_n_children "gint gtk_tree_model_iter_n_children(GtkTreeModel* tree_model, \ GtkTreeIter* iter)" Xen_check_type(Xen_is_GtkTreeModel_(tree_model), tree_model, 1, "gtk_tree_model_iter_n_children", "GtkTreeModel*"); Xen_check_type(Xen_is_GtkTreeIter_(iter) || Xen_is_false(iter), iter, 2, "gtk_tree_model_iter_n_children", "GtkTreeIter*"); return(C_to_Xen_gint(gtk_tree_model_iter_n_children(Xen_to_C_GtkTreeModel_(tree_model), Xen_to_C_GtkTreeIter_(iter)))); } static Xen gxg_gtk_tree_model_iter_nth_child(Xen tree_model, Xen iter, Xen parent, Xen n) { #define H_gtk_tree_model_iter_nth_child "gboolean gtk_tree_model_iter_nth_child(GtkTreeModel* tree_model, \ GtkTreeIter* iter, GtkTreeIter* parent, gint n)" Xen_check_type(Xen_is_GtkTreeModel_(tree_model), tree_model, 1, "gtk_tree_model_iter_nth_child", "GtkTreeModel*"); Xen_check_type(Xen_is_GtkTreeIter_(iter), iter, 2, "gtk_tree_model_iter_nth_child", "GtkTreeIter*"); Xen_check_type(Xen_is_GtkTreeIter_(parent) || Xen_is_false(parent), parent, 3, "gtk_tree_model_iter_nth_child", "GtkTreeIter*"); Xen_check_type(Xen_is_gint(n), n, 4, "gtk_tree_model_iter_nth_child", "gint"); return(C_to_Xen_gboolean(gtk_tree_model_iter_nth_child(Xen_to_C_GtkTreeModel_(tree_model), Xen_to_C_GtkTreeIter_(iter), Xen_to_C_GtkTreeIter_(parent), Xen_to_C_gint(n)))); } static Xen gxg_gtk_tree_model_iter_parent(Xen tree_model, Xen iter, Xen child) { #define H_gtk_tree_model_iter_parent "gboolean gtk_tree_model_iter_parent(GtkTreeModel* tree_model, \ GtkTreeIter* iter, GtkTreeIter* child)" Xen_check_type(Xen_is_GtkTreeModel_(tree_model), tree_model, 1, "gtk_tree_model_iter_parent", "GtkTreeModel*"); Xen_check_type(Xen_is_GtkTreeIter_(iter), iter, 2, "gtk_tree_model_iter_parent", "GtkTreeIter*"); Xen_check_type(Xen_is_GtkTreeIter_(child), child, 3, "gtk_tree_model_iter_parent", "GtkTreeIter*"); return(C_to_Xen_gboolean(gtk_tree_model_iter_parent(Xen_to_C_GtkTreeModel_(tree_model), Xen_to_C_GtkTreeIter_(iter), Xen_to_C_GtkTreeIter_(child)))); } static Xen gxg_gtk_tree_model_ref_node(Xen tree_model, Xen iter) { #define H_gtk_tree_model_ref_node "void gtk_tree_model_ref_node(GtkTreeModel* tree_model, GtkTreeIter* iter)" Xen_check_type(Xen_is_GtkTreeModel_(tree_model), tree_model, 1, "gtk_tree_model_ref_node", "GtkTreeModel*"); Xen_check_type(Xen_is_GtkTreeIter_(iter), iter, 2, "gtk_tree_model_ref_node", "GtkTreeIter*"); gtk_tree_model_ref_node(Xen_to_C_GtkTreeModel_(tree_model), Xen_to_C_GtkTreeIter_(iter)); return(Xen_false); } static Xen gxg_gtk_tree_model_unref_node(Xen tree_model, Xen iter) { #define H_gtk_tree_model_unref_node "void gtk_tree_model_unref_node(GtkTreeModel* tree_model, GtkTreeIter* iter)" Xen_check_type(Xen_is_GtkTreeModel_(tree_model), tree_model, 1, "gtk_tree_model_unref_node", "GtkTreeModel*"); Xen_check_type(Xen_is_GtkTreeIter_(iter), iter, 2, "gtk_tree_model_unref_node", "GtkTreeIter*"); gtk_tree_model_unref_node(Xen_to_C_GtkTreeModel_(tree_model), Xen_to_C_GtkTreeIter_(iter)); return(Xen_false); } static Xen gxg_gtk_tree_model_foreach(Xen model, Xen func, Xen func_info) { #define H_gtk_tree_model_foreach "void gtk_tree_model_foreach(GtkTreeModel* model, GtkTreeModelForeachFunc func, \ lambda_data func_info)" Xen_check_type(Xen_is_GtkTreeModel_(model), model, 1, "gtk_tree_model_foreach", "GtkTreeModel*"); Xen_check_type(Xen_is_GtkTreeModelForeachFunc(func), func, 2, "gtk_tree_model_foreach", "GtkTreeModelForeachFunc"); if (!Xen_is_bound(func_info)) func_info = Xen_false; else Xen_check_type(Xen_is_lambda_data(func_info), func_info, 3, "gtk_tree_model_foreach", "lambda_data"); { int loc; Xen gxg_ptr = Xen_list_5(func, func_info, Xen_false, Xen_false, Xen_false); loc = xm_protect(gxg_ptr); Xen_list_set(gxg_ptr, 2, C_int_to_Xen_integer(loc)); gtk_tree_model_foreach(Xen_to_C_GtkTreeModel_(model), Xen_to_C_GtkTreeModelForeachFunc(func), Xen_to_C_lambda_data(func_info)); xm_unprotect_at(loc); return(Xen_false); } } static Xen gxg_gtk_tree_model_row_changed(Xen tree_model, Xen path, Xen iter) { #define H_gtk_tree_model_row_changed "void gtk_tree_model_row_changed(GtkTreeModel* tree_model, GtkTreePath* path, \ GtkTreeIter* iter)" Xen_check_type(Xen_is_GtkTreeModel_(tree_model), tree_model, 1, "gtk_tree_model_row_changed", "GtkTreeModel*"); Xen_check_type(Xen_is_GtkTreePath_(path), path, 2, "gtk_tree_model_row_changed", "GtkTreePath*"); Xen_check_type(Xen_is_GtkTreeIter_(iter), iter, 3, "gtk_tree_model_row_changed", "GtkTreeIter*"); gtk_tree_model_row_changed(Xen_to_C_GtkTreeModel_(tree_model), Xen_to_C_GtkTreePath_(path), Xen_to_C_GtkTreeIter_(iter)); return(Xen_false); } static Xen gxg_gtk_tree_model_row_inserted(Xen tree_model, Xen path, Xen iter) { #define H_gtk_tree_model_row_inserted "void gtk_tree_model_row_inserted(GtkTreeModel* tree_model, GtkTreePath* path, \ GtkTreeIter* iter)" Xen_check_type(Xen_is_GtkTreeModel_(tree_model), tree_model, 1, "gtk_tree_model_row_inserted", "GtkTreeModel*"); Xen_check_type(Xen_is_GtkTreePath_(path), path, 2, "gtk_tree_model_row_inserted", "GtkTreePath*"); Xen_check_type(Xen_is_GtkTreeIter_(iter), iter, 3, "gtk_tree_model_row_inserted", "GtkTreeIter*"); gtk_tree_model_row_inserted(Xen_to_C_GtkTreeModel_(tree_model), Xen_to_C_GtkTreePath_(path), Xen_to_C_GtkTreeIter_(iter)); return(Xen_false); } static Xen gxg_gtk_tree_model_row_has_child_toggled(Xen tree_model, Xen path, Xen iter) { #define H_gtk_tree_model_row_has_child_toggled "void gtk_tree_model_row_has_child_toggled(GtkTreeModel* tree_model, \ GtkTreePath* path, GtkTreeIter* iter)" Xen_check_type(Xen_is_GtkTreeModel_(tree_model), tree_model, 1, "gtk_tree_model_row_has_child_toggled", "GtkTreeModel*"); Xen_check_type(Xen_is_GtkTreePath_(path), path, 2, "gtk_tree_model_row_has_child_toggled", "GtkTreePath*"); Xen_check_type(Xen_is_GtkTreeIter_(iter), iter, 3, "gtk_tree_model_row_has_child_toggled", "GtkTreeIter*"); gtk_tree_model_row_has_child_toggled(Xen_to_C_GtkTreeModel_(tree_model), Xen_to_C_GtkTreePath_(path), Xen_to_C_GtkTreeIter_(iter)); return(Xen_false); } static Xen gxg_gtk_tree_model_row_deleted(Xen tree_model, Xen path) { #define H_gtk_tree_model_row_deleted "void gtk_tree_model_row_deleted(GtkTreeModel* tree_model, GtkTreePath* path)" Xen_check_type(Xen_is_GtkTreeModel_(tree_model), tree_model, 1, "gtk_tree_model_row_deleted", "GtkTreeModel*"); Xen_check_type(Xen_is_GtkTreePath_(path), path, 2, "gtk_tree_model_row_deleted", "GtkTreePath*"); gtk_tree_model_row_deleted(Xen_to_C_GtkTreeModel_(tree_model), Xen_to_C_GtkTreePath_(path)); return(Xen_false); } static Xen gxg_gtk_tree_model_rows_reordered(Xen tree_model, Xen path, Xen iter, Xen new_order) { #define H_gtk_tree_model_rows_reordered "void gtk_tree_model_rows_reordered(GtkTreeModel* tree_model, \ GtkTreePath* path, GtkTreeIter* iter, gint* new_order)" Xen_check_type(Xen_is_GtkTreeModel_(tree_model), tree_model, 1, "gtk_tree_model_rows_reordered", "GtkTreeModel*"); Xen_check_type(Xen_is_GtkTreePath_(path), path, 2, "gtk_tree_model_rows_reordered", "GtkTreePath*"); Xen_check_type(Xen_is_GtkTreeIter_(iter), iter, 3, "gtk_tree_model_rows_reordered", "GtkTreeIter*"); Xen_check_type(Xen_is_gint_(new_order), new_order, 4, "gtk_tree_model_rows_reordered", "gint*"); gtk_tree_model_rows_reordered(Xen_to_C_GtkTreeModel_(tree_model), Xen_to_C_GtkTreePath_(path), Xen_to_C_GtkTreeIter_(iter), Xen_to_C_gint_(new_order)); return(Xen_false); } static Xen gxg_gtk_tree_model_sort_new_with_model(Xen child_model) { #define H_gtk_tree_model_sort_new_with_model "GtkTreeModel* gtk_tree_model_sort_new_with_model(GtkTreeModel* child_model)" Xen_check_type(Xen_is_GtkTreeModel_(child_model), child_model, 1, "gtk_tree_model_sort_new_with_model", "GtkTreeModel*"); return(C_to_Xen_GtkTreeModel_(gtk_tree_model_sort_new_with_model(Xen_to_C_GtkTreeModel_(child_model)))); } static Xen gxg_gtk_tree_model_sort_get_model(Xen tree_model) { #define H_gtk_tree_model_sort_get_model "GtkTreeModel* gtk_tree_model_sort_get_model(GtkTreeModelSort* tree_model)" Xen_check_type(Xen_is_GtkTreeModelSort_(tree_model), tree_model, 1, "gtk_tree_model_sort_get_model", "GtkTreeModelSort*"); return(C_to_Xen_GtkTreeModel_(gtk_tree_model_sort_get_model(Xen_to_C_GtkTreeModelSort_(tree_model)))); } static Xen gxg_gtk_tree_model_sort_convert_child_path_to_path(Xen tree_model_sort, Xen child_path) { #define H_gtk_tree_model_sort_convert_child_path_to_path "GtkTreePath* gtk_tree_model_sort_convert_child_path_to_path(GtkTreeModelSort* tree_model_sort, \ GtkTreePath* child_path)" Xen_check_type(Xen_is_GtkTreeModelSort_(tree_model_sort), tree_model_sort, 1, "gtk_tree_model_sort_convert_child_path_to_path", "GtkTreeModelSort*"); Xen_check_type(Xen_is_GtkTreePath_(child_path), child_path, 2, "gtk_tree_model_sort_convert_child_path_to_path", "GtkTreePath*"); return(C_to_Xen_GtkTreePath_(gtk_tree_model_sort_convert_child_path_to_path(Xen_to_C_GtkTreeModelSort_(tree_model_sort), Xen_to_C_GtkTreePath_(child_path)))); } static Xen gxg_gtk_tree_model_sort_convert_child_iter_to_iter(Xen tree_model_sort, Xen sort_iter, Xen child_iter) { #define H_gtk_tree_model_sort_convert_child_iter_to_iter "void gtk_tree_model_sort_convert_child_iter_to_iter(GtkTreeModelSort* tree_model_sort, \ GtkTreeIter* sort_iter, GtkTreeIter* child_iter)" Xen_check_type(Xen_is_GtkTreeModelSort_(tree_model_sort), tree_model_sort, 1, "gtk_tree_model_sort_convert_child_iter_to_iter", "GtkTreeModelSort*"); Xen_check_type(Xen_is_GtkTreeIter_(sort_iter), sort_iter, 2, "gtk_tree_model_sort_convert_child_iter_to_iter", "GtkTreeIter*"); Xen_check_type(Xen_is_GtkTreeIter_(child_iter), child_iter, 3, "gtk_tree_model_sort_convert_child_iter_to_iter", "GtkTreeIter*"); gtk_tree_model_sort_convert_child_iter_to_iter(Xen_to_C_GtkTreeModelSort_(tree_model_sort), Xen_to_C_GtkTreeIter_(sort_iter), Xen_to_C_GtkTreeIter_(child_iter)); return(Xen_false); } static Xen gxg_gtk_tree_model_sort_convert_path_to_child_path(Xen tree_model_sort, Xen sorted_path) { #define H_gtk_tree_model_sort_convert_path_to_child_path "GtkTreePath* gtk_tree_model_sort_convert_path_to_child_path(GtkTreeModelSort* tree_model_sort, \ GtkTreePath* sorted_path)" Xen_check_type(Xen_is_GtkTreeModelSort_(tree_model_sort), tree_model_sort, 1, "gtk_tree_model_sort_convert_path_to_child_path", "GtkTreeModelSort*"); Xen_check_type(Xen_is_GtkTreePath_(sorted_path), sorted_path, 2, "gtk_tree_model_sort_convert_path_to_child_path", "GtkTreePath*"); return(C_to_Xen_GtkTreePath_(gtk_tree_model_sort_convert_path_to_child_path(Xen_to_C_GtkTreeModelSort_(tree_model_sort), Xen_to_C_GtkTreePath_(sorted_path)))); } static Xen gxg_gtk_tree_model_sort_convert_iter_to_child_iter(Xen tree_model_sort, Xen child_iter, Xen sorted_iter) { #define H_gtk_tree_model_sort_convert_iter_to_child_iter "void gtk_tree_model_sort_convert_iter_to_child_iter(GtkTreeModelSort* tree_model_sort, \ GtkTreeIter* child_iter, GtkTreeIter* sorted_iter)" Xen_check_type(Xen_is_GtkTreeModelSort_(tree_model_sort), tree_model_sort, 1, "gtk_tree_model_sort_convert_iter_to_child_iter", "GtkTreeModelSort*"); Xen_check_type(Xen_is_GtkTreeIter_(child_iter), child_iter, 2, "gtk_tree_model_sort_convert_iter_to_child_iter", "GtkTreeIter*"); Xen_check_type(Xen_is_GtkTreeIter_(sorted_iter), sorted_iter, 3, "gtk_tree_model_sort_convert_iter_to_child_iter", "GtkTreeIter*"); gtk_tree_model_sort_convert_iter_to_child_iter(Xen_to_C_GtkTreeModelSort_(tree_model_sort), Xen_to_C_GtkTreeIter_(child_iter), Xen_to_C_GtkTreeIter_(sorted_iter)); return(Xen_false); } static Xen gxg_gtk_tree_model_sort_reset_default_sort_func(Xen tree_model_sort) { #define H_gtk_tree_model_sort_reset_default_sort_func "void gtk_tree_model_sort_reset_default_sort_func(GtkTreeModelSort* tree_model_sort)" Xen_check_type(Xen_is_GtkTreeModelSort_(tree_model_sort), tree_model_sort, 1, "gtk_tree_model_sort_reset_default_sort_func", "GtkTreeModelSort*"); gtk_tree_model_sort_reset_default_sort_func(Xen_to_C_GtkTreeModelSort_(tree_model_sort)); return(Xen_false); } static Xen gxg_gtk_tree_model_sort_clear_cache(Xen tree_model_sort) { #define H_gtk_tree_model_sort_clear_cache "void gtk_tree_model_sort_clear_cache(GtkTreeModelSort* tree_model_sort)" Xen_check_type(Xen_is_GtkTreeModelSort_(tree_model_sort), tree_model_sort, 1, "gtk_tree_model_sort_clear_cache", "GtkTreeModelSort*"); gtk_tree_model_sort_clear_cache(Xen_to_C_GtkTreeModelSort_(tree_model_sort)); return(Xen_false); } static Xen gxg_gtk_tree_selection_set_mode(Xen selection, Xen type) { #define H_gtk_tree_selection_set_mode "void gtk_tree_selection_set_mode(GtkTreeSelection* selection, \ GtkSelectionMode type)" Xen_check_type(Xen_is_GtkTreeSelection_(selection), selection, 1, "gtk_tree_selection_set_mode", "GtkTreeSelection*"); Xen_check_type(Xen_is_GtkSelectionMode(type), type, 2, "gtk_tree_selection_set_mode", "GtkSelectionMode"); gtk_tree_selection_set_mode(Xen_to_C_GtkTreeSelection_(selection), Xen_to_C_GtkSelectionMode(type)); return(Xen_false); } static Xen gxg_gtk_tree_selection_get_mode(Xen selection) { #define H_gtk_tree_selection_get_mode "GtkSelectionMode gtk_tree_selection_get_mode(GtkTreeSelection* selection)" Xen_check_type(Xen_is_GtkTreeSelection_(selection), selection, 1, "gtk_tree_selection_get_mode", "GtkTreeSelection*"); return(C_to_Xen_GtkSelectionMode(gtk_tree_selection_get_mode(Xen_to_C_GtkTreeSelection_(selection)))); } static Xen gxg_gtk_tree_selection_set_select_function(Xen selection, Xen func, Xen func_info, Xen destroy) { #define H_gtk_tree_selection_set_select_function "void gtk_tree_selection_set_select_function(GtkTreeSelection* selection, \ GtkTreeSelectionFunc func, lambda_data func_info, GtkDestroyNotify destroy)" Xen_check_type(Xen_is_GtkTreeSelection_(selection), selection, 1, "gtk_tree_selection_set_select_function", "GtkTreeSelection*"); Xen_check_type(Xen_is_GtkTreeSelectionFunc(func), func, 2, "gtk_tree_selection_set_select_function", "GtkTreeSelectionFunc"); Xen_check_type(Xen_is_lambda_data(func_info), func_info, 3, "gtk_tree_selection_set_select_function", "lambda_data"); Xen_check_type(Xen_is_GtkDestroyNotify(destroy), destroy, 4, "gtk_tree_selection_set_select_function", "GtkDestroyNotify"); { Xen gxg_ptr = Xen_list_5(func, func_info, Xen_false, Xen_false, Xen_false); xm_protect(gxg_ptr); Xen_list_set(gxg_ptr, 3, destroy); gtk_tree_selection_set_select_function(Xen_to_C_GtkTreeSelection_(selection), Xen_to_C_GtkTreeSelectionFunc(func), Xen_to_C_lambda_data(func_info), Xen_to_C_GtkDestroyNotify(destroy)); return(Xen_false); } } static Xen gxg_gtk_tree_selection_get_user_data(Xen selection) { #define H_gtk_tree_selection_get_user_data "gpointer gtk_tree_selection_get_user_data(GtkTreeSelection* selection)" Xen_check_type(Xen_is_GtkTreeSelection_(selection), selection, 1, "gtk_tree_selection_get_user_data", "GtkTreeSelection*"); return(C_to_Xen_gpointer(gtk_tree_selection_get_user_data(Xen_to_C_GtkTreeSelection_(selection)))); } static Xen gxg_gtk_tree_selection_get_tree_view(Xen selection) { #define H_gtk_tree_selection_get_tree_view "GtkTreeView* gtk_tree_selection_get_tree_view(GtkTreeSelection* selection)" Xen_check_type(Xen_is_GtkTreeSelection_(selection), selection, 1, "gtk_tree_selection_get_tree_view", "GtkTreeSelection*"); return(C_to_Xen_GtkTreeView_(gtk_tree_selection_get_tree_view(Xen_to_C_GtkTreeSelection_(selection)))); } static Xen gxg_gtk_tree_selection_get_selected(Xen selection, Xen model, Xen iter) { #define H_gtk_tree_selection_get_selected "gboolean gtk_tree_selection_get_selected(GtkTreeSelection* selection, \ GtkTreeModel** model, GtkTreeIter* iter)" Xen_check_type(Xen_is_GtkTreeSelection_(selection), selection, 1, "gtk_tree_selection_get_selected", "GtkTreeSelection*"); Xen_check_type(Xen_is_GtkTreeModel__(model), model, 2, "gtk_tree_selection_get_selected", "GtkTreeModel**"); Xen_check_type(Xen_is_GtkTreeIter_(iter), iter, 3, "gtk_tree_selection_get_selected", "GtkTreeIter*"); return(C_to_Xen_gboolean(gtk_tree_selection_get_selected(Xen_to_C_GtkTreeSelection_(selection), Xen_to_C_GtkTreeModel__(model), Xen_to_C_GtkTreeIter_(iter)))); } static Xen gxg_gtk_tree_selection_selected_foreach(Xen selection, Xen func, Xen func_info) { #define H_gtk_tree_selection_selected_foreach "void gtk_tree_selection_selected_foreach(GtkTreeSelection* selection, \ GtkTreeSelectionForeachFunc func, lambda_data func_info)" Xen_check_type(Xen_is_GtkTreeSelection_(selection), selection, 1, "gtk_tree_selection_selected_foreach", "GtkTreeSelection*"); Xen_check_type(Xen_is_GtkTreeSelectionForeachFunc(func), func, 2, "gtk_tree_selection_selected_foreach", "GtkTreeSelectionForeachFunc"); if (!Xen_is_bound(func_info)) func_info = Xen_false; else Xen_check_type(Xen_is_lambda_data(func_info), func_info, 3, "gtk_tree_selection_selected_foreach", "lambda_data"); { int loc; Xen gxg_ptr = Xen_list_5(func, func_info, Xen_false, Xen_false, Xen_false); loc = xm_protect(gxg_ptr); Xen_list_set(gxg_ptr, 2, C_int_to_Xen_integer(loc)); gtk_tree_selection_selected_foreach(Xen_to_C_GtkTreeSelection_(selection), Xen_to_C_GtkTreeSelectionForeachFunc(func), Xen_to_C_lambda_data(func_info)); xm_unprotect_at(loc); return(Xen_false); } } static Xen gxg_gtk_tree_selection_select_path(Xen selection, Xen path) { #define H_gtk_tree_selection_select_path "void gtk_tree_selection_select_path(GtkTreeSelection* selection, \ GtkTreePath* path)" Xen_check_type(Xen_is_GtkTreeSelection_(selection), selection, 1, "gtk_tree_selection_select_path", "GtkTreeSelection*"); Xen_check_type(Xen_is_GtkTreePath_(path), path, 2, "gtk_tree_selection_select_path", "GtkTreePath*"); gtk_tree_selection_select_path(Xen_to_C_GtkTreeSelection_(selection), Xen_to_C_GtkTreePath_(path)); return(Xen_false); } static Xen gxg_gtk_tree_selection_unselect_path(Xen selection, Xen path) { #define H_gtk_tree_selection_unselect_path "void gtk_tree_selection_unselect_path(GtkTreeSelection* selection, \ GtkTreePath* path)" Xen_check_type(Xen_is_GtkTreeSelection_(selection), selection, 1, "gtk_tree_selection_unselect_path", "GtkTreeSelection*"); Xen_check_type(Xen_is_GtkTreePath_(path), path, 2, "gtk_tree_selection_unselect_path", "GtkTreePath*"); gtk_tree_selection_unselect_path(Xen_to_C_GtkTreeSelection_(selection), Xen_to_C_GtkTreePath_(path)); return(Xen_false); } static Xen gxg_gtk_tree_selection_select_iter(Xen selection, Xen iter) { #define H_gtk_tree_selection_select_iter "void gtk_tree_selection_select_iter(GtkTreeSelection* selection, \ GtkTreeIter* iter)" Xen_check_type(Xen_is_GtkTreeSelection_(selection), selection, 1, "gtk_tree_selection_select_iter", "GtkTreeSelection*"); Xen_check_type(Xen_is_GtkTreeIter_(iter), iter, 2, "gtk_tree_selection_select_iter", "GtkTreeIter*"); gtk_tree_selection_select_iter(Xen_to_C_GtkTreeSelection_(selection), Xen_to_C_GtkTreeIter_(iter)); return(Xen_false); } static Xen gxg_gtk_tree_selection_unselect_iter(Xen selection, Xen iter) { #define H_gtk_tree_selection_unselect_iter "void gtk_tree_selection_unselect_iter(GtkTreeSelection* selection, \ GtkTreeIter* iter)" Xen_check_type(Xen_is_GtkTreeSelection_(selection), selection, 1, "gtk_tree_selection_unselect_iter", "GtkTreeSelection*"); Xen_check_type(Xen_is_GtkTreeIter_(iter), iter, 2, "gtk_tree_selection_unselect_iter", "GtkTreeIter*"); gtk_tree_selection_unselect_iter(Xen_to_C_GtkTreeSelection_(selection), Xen_to_C_GtkTreeIter_(iter)); return(Xen_false); } static Xen gxg_gtk_tree_selection_path_is_selected(Xen selection, Xen path) { #define H_gtk_tree_selection_path_is_selected "gboolean gtk_tree_selection_path_is_selected(GtkTreeSelection* selection, \ GtkTreePath* path)" Xen_check_type(Xen_is_GtkTreeSelection_(selection), selection, 1, "gtk_tree_selection_path_is_selected", "GtkTreeSelection*"); Xen_check_type(Xen_is_GtkTreePath_(path), path, 2, "gtk_tree_selection_path_is_selected", "GtkTreePath*"); return(C_to_Xen_gboolean(gtk_tree_selection_path_is_selected(Xen_to_C_GtkTreeSelection_(selection), Xen_to_C_GtkTreePath_(path)))); } static Xen gxg_gtk_tree_selection_iter_is_selected(Xen selection, Xen iter) { #define H_gtk_tree_selection_iter_is_selected "gboolean gtk_tree_selection_iter_is_selected(GtkTreeSelection* selection, \ GtkTreeIter* iter)" Xen_check_type(Xen_is_GtkTreeSelection_(selection), selection, 1, "gtk_tree_selection_iter_is_selected", "GtkTreeSelection*"); Xen_check_type(Xen_is_GtkTreeIter_(iter), iter, 2, "gtk_tree_selection_iter_is_selected", "GtkTreeIter*"); return(C_to_Xen_gboolean(gtk_tree_selection_iter_is_selected(Xen_to_C_GtkTreeSelection_(selection), Xen_to_C_GtkTreeIter_(iter)))); } static Xen gxg_gtk_tree_selection_select_all(Xen selection) { #define H_gtk_tree_selection_select_all "void gtk_tree_selection_select_all(GtkTreeSelection* selection)" Xen_check_type(Xen_is_GtkTreeSelection_(selection), selection, 1, "gtk_tree_selection_select_all", "GtkTreeSelection*"); gtk_tree_selection_select_all(Xen_to_C_GtkTreeSelection_(selection)); return(Xen_false); } static Xen gxg_gtk_tree_selection_unselect_all(Xen selection) { #define H_gtk_tree_selection_unselect_all "void gtk_tree_selection_unselect_all(GtkTreeSelection* selection)" Xen_check_type(Xen_is_GtkTreeSelection_(selection), selection, 1, "gtk_tree_selection_unselect_all", "GtkTreeSelection*"); gtk_tree_selection_unselect_all(Xen_to_C_GtkTreeSelection_(selection)); return(Xen_false); } static Xen gxg_gtk_tree_selection_select_range(Xen selection, Xen start_path, Xen end_path) { #define H_gtk_tree_selection_select_range "void gtk_tree_selection_select_range(GtkTreeSelection* selection, \ GtkTreePath* start_path, GtkTreePath* end_path)" Xen_check_type(Xen_is_GtkTreeSelection_(selection), selection, 1, "gtk_tree_selection_select_range", "GtkTreeSelection*"); Xen_check_type(Xen_is_GtkTreePath_(start_path), start_path, 2, "gtk_tree_selection_select_range", "GtkTreePath*"); Xen_check_type(Xen_is_GtkTreePath_(end_path), end_path, 3, "gtk_tree_selection_select_range", "GtkTreePath*"); gtk_tree_selection_select_range(Xen_to_C_GtkTreeSelection_(selection), Xen_to_C_GtkTreePath_(start_path), Xen_to_C_GtkTreePath_(end_path)); return(Xen_false); } static Xen gxg_gtk_tree_sortable_sort_column_changed(Xen sortable) { #define H_gtk_tree_sortable_sort_column_changed "void gtk_tree_sortable_sort_column_changed(GtkTreeSortable* sortable)" Xen_check_type(Xen_is_GtkTreeSortable_(sortable), sortable, 1, "gtk_tree_sortable_sort_column_changed", "GtkTreeSortable*"); gtk_tree_sortable_sort_column_changed(Xen_to_C_GtkTreeSortable_(sortable)); return(Xen_false); } static Xen gxg_gtk_tree_sortable_get_sort_column_id(Xen sortable, Xen ignore_sort_column_id, Xen ignore_order) { #define H_gtk_tree_sortable_get_sort_column_id "gboolean gtk_tree_sortable_get_sort_column_id(GtkTreeSortable* sortable, \ gint* [sort_column_id], GtkSortType* [order])" gint ref_sort_column_id; GtkSortType ref_order; Xen_check_type(Xen_is_GtkTreeSortable_(sortable), sortable, 1, "gtk_tree_sortable_get_sort_column_id", "GtkTreeSortable*"); { Xen result; result = C_to_Xen_gboolean(gtk_tree_sortable_get_sort_column_id(Xen_to_C_GtkTreeSortable_(sortable), &ref_sort_column_id, &ref_order)); return(Xen_list_3(result, C_to_Xen_gint(ref_sort_column_id), C_to_Xen_GtkSortType(ref_order))); } } static Xen gxg_gtk_tree_sortable_set_sort_column_id(Xen sortable, Xen sort_column_id, Xen order) { #define H_gtk_tree_sortable_set_sort_column_id "void gtk_tree_sortable_set_sort_column_id(GtkTreeSortable* sortable, \ gint sort_column_id, GtkSortType order)" Xen_check_type(Xen_is_GtkTreeSortable_(sortable), sortable, 1, "gtk_tree_sortable_set_sort_column_id", "GtkTreeSortable*"); Xen_check_type(Xen_is_gint(sort_column_id), sort_column_id, 2, "gtk_tree_sortable_set_sort_column_id", "gint"); Xen_check_type(Xen_is_GtkSortType(order), order, 3, "gtk_tree_sortable_set_sort_column_id", "GtkSortType"); gtk_tree_sortable_set_sort_column_id(Xen_to_C_GtkTreeSortable_(sortable), Xen_to_C_gint(sort_column_id), Xen_to_C_GtkSortType(order)); return(Xen_false); } static Xen gxg_gtk_tree_sortable_set_sort_func(Xen sortable, Xen sort_column_id, Xen func, Xen func_info, Xen destroy) { #define H_gtk_tree_sortable_set_sort_func "void gtk_tree_sortable_set_sort_func(GtkTreeSortable* sortable, \ gint sort_column_id, GtkTreeIterCompareFunc func, lambda_data func_info, GtkDestroyNotify destroy)" Xen_check_type(Xen_is_GtkTreeSortable_(sortable), sortable, 1, "gtk_tree_sortable_set_sort_func", "GtkTreeSortable*"); Xen_check_type(Xen_is_gint(sort_column_id), sort_column_id, 2, "gtk_tree_sortable_set_sort_func", "gint"); Xen_check_type(Xen_is_GtkTreeIterCompareFunc(func), func, 3, "gtk_tree_sortable_set_sort_func", "GtkTreeIterCompareFunc"); Xen_check_type(Xen_is_lambda_data(func_info), func_info, 4, "gtk_tree_sortable_set_sort_func", "lambda_data"); Xen_check_type(Xen_is_GtkDestroyNotify(destroy), destroy, 5, "gtk_tree_sortable_set_sort_func", "GtkDestroyNotify"); { Xen gxg_ptr = Xen_list_5(func, func_info, Xen_false, Xen_false, Xen_false); xm_protect(gxg_ptr); Xen_list_set(gxg_ptr, 3, destroy); gtk_tree_sortable_set_sort_func(Xen_to_C_GtkTreeSortable_(sortable), Xen_to_C_gint(sort_column_id), Xen_to_C_GtkTreeIterCompareFunc(func), Xen_to_C_lambda_data(func_info), Xen_to_C_GtkDestroyNotify(destroy)); return(Xen_false); } } static Xen gxg_gtk_tree_sortable_set_default_sort_func(Xen sortable, Xen func, Xen func_info, Xen destroy) { #define H_gtk_tree_sortable_set_default_sort_func "void gtk_tree_sortable_set_default_sort_func(GtkTreeSortable* sortable, \ GtkTreeIterCompareFunc func, lambda_data func_info, GtkDestroyNotify destroy)" Xen_check_type(Xen_is_GtkTreeSortable_(sortable), sortable, 1, "gtk_tree_sortable_set_default_sort_func", "GtkTreeSortable*"); Xen_check_type(Xen_is_GtkTreeIterCompareFunc(func), func, 2, "gtk_tree_sortable_set_default_sort_func", "GtkTreeIterCompareFunc"); Xen_check_type(Xen_is_lambda_data(func_info), func_info, 3, "gtk_tree_sortable_set_default_sort_func", "lambda_data"); Xen_check_type(Xen_is_GtkDestroyNotify(destroy), destroy, 4, "gtk_tree_sortable_set_default_sort_func", "GtkDestroyNotify"); { Xen gxg_ptr = Xen_list_5(func, func_info, Xen_false, Xen_false, Xen_false); xm_protect(gxg_ptr); Xen_list_set(gxg_ptr, 3, destroy); gtk_tree_sortable_set_default_sort_func(Xen_to_C_GtkTreeSortable_(sortable), Xen_to_C_GtkTreeIterCompareFunc(func), Xen_to_C_lambda_data(func_info), Xen_to_C_GtkDestroyNotify(destroy)); return(Xen_false); } } static Xen gxg_gtk_tree_sortable_has_default_sort_func(Xen sortable) { #define H_gtk_tree_sortable_has_default_sort_func "gboolean gtk_tree_sortable_has_default_sort_func(GtkTreeSortable* sortable)" Xen_check_type(Xen_is_GtkTreeSortable_(sortable), sortable, 1, "gtk_tree_sortable_has_default_sort_func", "GtkTreeSortable*"); return(C_to_Xen_gboolean(gtk_tree_sortable_has_default_sort_func(Xen_to_C_GtkTreeSortable_(sortable)))); } static Xen gxg_gtk_tree_store_new(Xen n_columns, Xen types) { #define H_gtk_tree_store_new "GtkTreeStore* gtk_tree_store_new(gint n_columns, etc types)" Xen_check_type(Xen_is_gint(n_columns), n_columns, 1, "gtk_tree_store_new", "gint"); Xen_check_type(Xen_is_etc(types), types, 2, "gtk_tree_store_new", "etc"); { int etc_len = 0; GtkTreeStore* result = NULL; gint p_arg0; if (Xen_is_list(types)) etc_len = Xen_list_length(types); if (etc_len < 1) Xen_out_of_range_error("gtk_tree_store_new", 1, types, "... list must have at least 1 entry"); if (etc_len > 6) Xen_out_of_range_error("gtk_tree_store_new", 1, types, "... list too long (max len: 6)"); p_arg0 = Xen_to_C_gint(n_columns); switch (etc_len) { case 1: result = gtk_tree_store_new(p_arg0, XLG(types, 0)); break; case 2: result = gtk_tree_store_new(p_arg0, XLG(types, 0), XLG(types, 1)); break; case 3: result = gtk_tree_store_new(p_arg0, XLG(types, 0), XLG(types, 1), XLG(types, 2)); break; case 4: result = gtk_tree_store_new(p_arg0, XLG(types, 0), XLG(types, 1), XLG(types, 2), XLG(types, 3)); break; case 5: result = gtk_tree_store_new(p_arg0, XLG(types, 0), XLG(types, 1), XLG(types, 2), XLG(types, 3), XLG(types, 4)); break; case 6: result = gtk_tree_store_new(p_arg0, XLG(types, 0), XLG(types, 1), XLG(types, 2), XLG(types, 3), XLG(types, 4), XLG(types, 5)); break; } return(C_to_Xen_GtkTreeStore_(result)); } } static Xen gxg_gtk_tree_store_newv(Xen n_columns, Xen types) { #define H_gtk_tree_store_newv "GtkTreeStore* gtk_tree_store_newv(gint n_columns, GType* types)" Xen_check_type(Xen_is_gint(n_columns), n_columns, 1, "gtk_tree_store_newv", "gint"); Xen_check_type(Xen_is_GType_(types), types, 2, "gtk_tree_store_newv", "GType*"); return(C_to_Xen_GtkTreeStore_(gtk_tree_store_newv(Xen_to_C_gint(n_columns), Xen_to_C_GType_(types)))); } static Xen gxg_gtk_tree_store_set_column_types(Xen tree_store, Xen n_columns, Xen types) { #define H_gtk_tree_store_set_column_types "void gtk_tree_store_set_column_types(GtkTreeStore* tree_store, \ gint n_columns, GType* types)" Xen_check_type(Xen_is_GtkTreeStore_(tree_store), tree_store, 1, "gtk_tree_store_set_column_types", "GtkTreeStore*"); Xen_check_type(Xen_is_gint(n_columns), n_columns, 2, "gtk_tree_store_set_column_types", "gint"); Xen_check_type(Xen_is_GType_(types), types, 3, "gtk_tree_store_set_column_types", "GType*"); gtk_tree_store_set_column_types(Xen_to_C_GtkTreeStore_(tree_store), Xen_to_C_gint(n_columns), Xen_to_C_GType_(types)); return(Xen_false); } static Xen gxg_gtk_tree_store_set(Xen tree_store, Xen iter, Xen values) { #define H_gtk_tree_store_set "void gtk_tree_store_set(GtkTreeStore* tree_store, GtkTreeIter* iter, \ etc values)" Xen_check_type(Xen_is_GtkTreeStore_(tree_store), tree_store, 1, "gtk_tree_store_set", "GtkTreeStore*"); Xen_check_type(Xen_is_GtkTreeIter_(iter), iter, 2, "gtk_tree_store_set", "GtkTreeIter*"); Xen_check_type(Xen_is_etc(values), values, 3, "gtk_tree_store_set", "etc"); { int etc_len = 0; GtkTreeStore* p_arg0; GtkTreeIter* p_arg1; if (Xen_is_list(values)) etc_len = Xen_list_length(values); if (etc_len < 2) Xen_out_of_range_error("gtk_tree_store_set", 2, values, "... list must have at least 2 entries"); if (etc_len > 10) Xen_out_of_range_error("gtk_tree_store_set", 2, values, "... list too long (max len: 10)"); if ((etc_len % 2) != 0) Xen_out_of_range_error("gtk_tree_store_set", 2, values, "... list len must be multiple of 2"); p_arg0 = Xen_to_C_GtkTreeStore_(tree_store); p_arg1 = Xen_to_C_GtkTreeIter_(iter); switch (etc_len) { case 2: gtk_tree_store_set(p_arg0, p_arg1, XLI(values, 0), XLS(values, 1), -1); break; case 4: gtk_tree_store_set(p_arg0, p_arg1, XLI(values, 0), XLS(values, 1), XLI(values, 2), XLS(values, 3), -1); break; case 6: gtk_tree_store_set(p_arg0, p_arg1, XLI(values, 0), XLS(values, 1), XLI(values, 2), XLS(values, 3), XLI(values, 4), XLS(values, 5), -1); break; case 8: gtk_tree_store_set(p_arg0, p_arg1, XLI(values, 0), XLS(values, 1), XLI(values, 2), XLS(values, 3), XLI(values, 4), XLS(values, 5), XLI(values, 6), XLS(values, 7), -1); break; case 10: gtk_tree_store_set(p_arg0, p_arg1, XLI(values, 0), XLS(values, 1), XLI(values, 2), XLS(values, 3), XLI(values, 4), XLS(values, 5), XLI(values, 6), XLS(values, 7), XLI(values, 8), XLS(values, 9), -1); break; } return(Xen_false); } } static Xen gxg_gtk_tree_store_remove(Xen tree_store, Xen iter) { #define H_gtk_tree_store_remove "void gtk_tree_store_remove(GtkTreeStore* tree_store, GtkTreeIter* iter)" Xen_check_type(Xen_is_GtkTreeStore_(tree_store), tree_store, 1, "gtk_tree_store_remove", "GtkTreeStore*"); Xen_check_type(Xen_is_GtkTreeIter_(iter), iter, 2, "gtk_tree_store_remove", "GtkTreeIter*"); gtk_tree_store_remove(Xen_to_C_GtkTreeStore_(tree_store), Xen_to_C_GtkTreeIter_(iter)); return(Xen_false); } static Xen gxg_gtk_tree_store_insert(Xen tree_store, Xen iter, Xen parent, Xen position) { #define H_gtk_tree_store_insert "void gtk_tree_store_insert(GtkTreeStore* tree_store, GtkTreeIter* iter, \ GtkTreeIter* parent, gint position)" Xen_check_type(Xen_is_GtkTreeStore_(tree_store), tree_store, 1, "gtk_tree_store_insert", "GtkTreeStore*"); Xen_check_type(Xen_is_GtkTreeIter_(iter), iter, 2, "gtk_tree_store_insert", "GtkTreeIter*"); Xen_check_type(Xen_is_GtkTreeIter_(parent) || Xen_is_false(parent), parent, 3, "gtk_tree_store_insert", "GtkTreeIter*"); Xen_check_type(Xen_is_gint(position), position, 4, "gtk_tree_store_insert", "gint"); gtk_tree_store_insert(Xen_to_C_GtkTreeStore_(tree_store), Xen_to_C_GtkTreeIter_(iter), Xen_to_C_GtkTreeIter_(parent), Xen_to_C_gint(position)); return(Xen_false); } static Xen gxg_gtk_tree_store_insert_before(Xen tree_store, Xen iter, Xen parent, Xen sibling) { #define H_gtk_tree_store_insert_before "void gtk_tree_store_insert_before(GtkTreeStore* tree_store, \ GtkTreeIter* iter, GtkTreeIter* parent, GtkTreeIter* sibling)" Xen_check_type(Xen_is_GtkTreeStore_(tree_store), tree_store, 1, "gtk_tree_store_insert_before", "GtkTreeStore*"); Xen_check_type(Xen_is_GtkTreeIter_(iter), iter, 2, "gtk_tree_store_insert_before", "GtkTreeIter*"); Xen_check_type(Xen_is_GtkTreeIter_(parent) || Xen_is_false(parent), parent, 3, "gtk_tree_store_insert_before", "GtkTreeIter*"); Xen_check_type(Xen_is_GtkTreeIter_(sibling) || Xen_is_false(sibling), sibling, 4, "gtk_tree_store_insert_before", "GtkTreeIter*"); gtk_tree_store_insert_before(Xen_to_C_GtkTreeStore_(tree_store), Xen_to_C_GtkTreeIter_(iter), Xen_to_C_GtkTreeIter_(parent), Xen_to_C_GtkTreeIter_(sibling)); return(Xen_false); } static Xen gxg_gtk_tree_store_insert_after(Xen tree_store, Xen iter, Xen parent, Xen sibling) { #define H_gtk_tree_store_insert_after "void gtk_tree_store_insert_after(GtkTreeStore* tree_store, GtkTreeIter* iter, \ GtkTreeIter* parent, GtkTreeIter* sibling)" Xen_check_type(Xen_is_GtkTreeStore_(tree_store), tree_store, 1, "gtk_tree_store_insert_after", "GtkTreeStore*"); Xen_check_type(Xen_is_GtkTreeIter_(iter), iter, 2, "gtk_tree_store_insert_after", "GtkTreeIter*"); Xen_check_type(Xen_is_GtkTreeIter_(parent) || Xen_is_false(parent), parent, 3, "gtk_tree_store_insert_after", "GtkTreeIter*"); Xen_check_type(Xen_is_GtkTreeIter_(sibling) || Xen_is_false(sibling), sibling, 4, "gtk_tree_store_insert_after", "GtkTreeIter*"); gtk_tree_store_insert_after(Xen_to_C_GtkTreeStore_(tree_store), Xen_to_C_GtkTreeIter_(iter), Xen_to_C_GtkTreeIter_(parent), Xen_to_C_GtkTreeIter_(sibling)); return(Xen_false); } static Xen gxg_gtk_tree_store_prepend(Xen tree_store, Xen iter, Xen parent) { #define H_gtk_tree_store_prepend "void gtk_tree_store_prepend(GtkTreeStore* tree_store, GtkTreeIter* iter, \ GtkTreeIter* parent)" Xen_check_type(Xen_is_GtkTreeStore_(tree_store), tree_store, 1, "gtk_tree_store_prepend", "GtkTreeStore*"); Xen_check_type(Xen_is_GtkTreeIter_(iter), iter, 2, "gtk_tree_store_prepend", "GtkTreeIter*"); Xen_check_type(Xen_is_GtkTreeIter_(parent) || Xen_is_false(parent), parent, 3, "gtk_tree_store_prepend", "GtkTreeIter*"); gtk_tree_store_prepend(Xen_to_C_GtkTreeStore_(tree_store), Xen_to_C_GtkTreeIter_(iter), Xen_to_C_GtkTreeIter_(parent)); return(Xen_false); } static Xen gxg_gtk_tree_store_append(Xen tree_store, Xen iter, Xen parent) { #define H_gtk_tree_store_append "void gtk_tree_store_append(GtkTreeStore* tree_store, GtkTreeIter* iter, \ GtkTreeIter* parent)" Xen_check_type(Xen_is_GtkTreeStore_(tree_store), tree_store, 1, "gtk_tree_store_append", "GtkTreeStore*"); Xen_check_type(Xen_is_GtkTreeIter_(iter), iter, 2, "gtk_tree_store_append", "GtkTreeIter*"); Xen_check_type(Xen_is_GtkTreeIter_(parent) || Xen_is_false(parent), parent, 3, "gtk_tree_store_append", "GtkTreeIter*"); gtk_tree_store_append(Xen_to_C_GtkTreeStore_(tree_store), Xen_to_C_GtkTreeIter_(iter), Xen_to_C_GtkTreeIter_(parent)); return(Xen_false); } static Xen gxg_gtk_tree_store_is_ancestor(Xen tree_store, Xen iter, Xen descendant) { #define H_gtk_tree_store_is_ancestor "gboolean gtk_tree_store_is_ancestor(GtkTreeStore* tree_store, \ GtkTreeIter* iter, GtkTreeIter* descendant)" Xen_check_type(Xen_is_GtkTreeStore_(tree_store), tree_store, 1, "gtk_tree_store_is_ancestor", "GtkTreeStore*"); Xen_check_type(Xen_is_GtkTreeIter_(iter), iter, 2, "gtk_tree_store_is_ancestor", "GtkTreeIter*"); Xen_check_type(Xen_is_GtkTreeIter_(descendant), descendant, 3, "gtk_tree_store_is_ancestor", "GtkTreeIter*"); return(C_to_Xen_gboolean(gtk_tree_store_is_ancestor(Xen_to_C_GtkTreeStore_(tree_store), Xen_to_C_GtkTreeIter_(iter), Xen_to_C_GtkTreeIter_(descendant)))); } static Xen gxg_gtk_tree_store_iter_depth(Xen tree_store, Xen iter) { #define H_gtk_tree_store_iter_depth "gint gtk_tree_store_iter_depth(GtkTreeStore* tree_store, GtkTreeIter* iter)" Xen_check_type(Xen_is_GtkTreeStore_(tree_store), tree_store, 1, "gtk_tree_store_iter_depth", "GtkTreeStore*"); Xen_check_type(Xen_is_GtkTreeIter_(iter), iter, 2, "gtk_tree_store_iter_depth", "GtkTreeIter*"); return(C_to_Xen_gint(gtk_tree_store_iter_depth(Xen_to_C_GtkTreeStore_(tree_store), Xen_to_C_GtkTreeIter_(iter)))); } static Xen gxg_gtk_tree_store_clear(Xen tree_store) { #define H_gtk_tree_store_clear "void gtk_tree_store_clear(GtkTreeStore* tree_store)" Xen_check_type(Xen_is_GtkTreeStore_(tree_store), tree_store, 1, "gtk_tree_store_clear", "GtkTreeStore*"); gtk_tree_store_clear(Xen_to_C_GtkTreeStore_(tree_store)); return(Xen_false); } static Xen gxg_gtk_tree_view_column_new(void) { #define H_gtk_tree_view_column_new "GtkTreeViewColumn* gtk_tree_view_column_new( void)" return(C_to_Xen_GtkTreeViewColumn_(gtk_tree_view_column_new())); } static Xen gxg_gtk_tree_view_column_new_with_attributes(Xen title, Xen cell, Xen attributes) { #define H_gtk_tree_view_column_new_with_attributes "GtkTreeViewColumn* gtk_tree_view_column_new_with_attributes(gchar* title, \ GtkCellRenderer* cell, etc attributes)" Xen_check_type(Xen_is_gchar_(title), title, 1, "gtk_tree_view_column_new_with_attributes", "gchar*"); Xen_check_type(Xen_is_GtkCellRenderer_(cell), cell, 2, "gtk_tree_view_column_new_with_attributes", "GtkCellRenderer*"); Xen_check_type(Xen_is_etc(attributes), attributes, 3, "gtk_tree_view_column_new_with_attributes", "etc"); { int etc_len = 0; GtkTreeViewColumn* result = NULL; gchar* p_arg0; GtkCellRenderer* p_arg1; if (Xen_is_list(attributes)) etc_len = Xen_list_length(attributes); if (etc_len < 2) Xen_out_of_range_error("gtk_tree_view_column_new_with_attributes", 2, attributes, "... list must have at least 2 entries"); if (etc_len > 10) Xen_out_of_range_error("gtk_tree_view_column_new_with_attributes", 2, attributes, "... list too long (max len: 10)"); if ((etc_len % 2) != 0) Xen_out_of_range_error("gtk_tree_view_column_new_with_attributes", 2, attributes, "... list len must be multiple of 2"); p_arg0 = Xen_to_C_gchar_(title); p_arg1 = Xen_to_C_GtkCellRenderer_(cell); switch (etc_len) { case 2: result = gtk_tree_view_column_new_with_attributes(p_arg0, p_arg1, XLS(attributes, 0), XLI(attributes, 1), NULL); break; case 4: result = gtk_tree_view_column_new_with_attributes(p_arg0, p_arg1, XLS(attributes, 0), XLI(attributes, 1), XLS(attributes, 2), XLI(attributes, 3), NULL); break; case 6: result = gtk_tree_view_column_new_with_attributes(p_arg0, p_arg1, XLS(attributes, 0), XLI(attributes, 1), XLS(attributes, 2), XLI(attributes, 3), XLS(attributes, 4), XLI(attributes, 5), NULL); break; case 8: result = gtk_tree_view_column_new_with_attributes(p_arg0, p_arg1, XLS(attributes, 0), XLI(attributes, 1), XLS(attributes, 2), XLI(attributes, 3), XLS(attributes, 4), XLI(attributes, 5), XLS(attributes, 6), XLI(attributes, 7), NULL); break; case 10: result = gtk_tree_view_column_new_with_attributes(p_arg0, p_arg1, XLS(attributes, 0), XLI(attributes, 1), XLS(attributes, 2), XLI(attributes, 3), XLS(attributes, 4), XLI(attributes, 5), XLS(attributes, 6), XLI(attributes, 7), XLS(attributes, 8), XLI(attributes, 9), NULL); break; } return(C_to_Xen_GtkTreeViewColumn_(result)); } } static Xen gxg_gtk_tree_view_column_pack_start(Xen tree_column, Xen cell, Xen expand) { #define H_gtk_tree_view_column_pack_start "void gtk_tree_view_column_pack_start(GtkTreeViewColumn* tree_column, \ GtkCellRenderer* cell, gboolean expand)" Xen_check_type(Xen_is_GtkTreeViewColumn_(tree_column), tree_column, 1, "gtk_tree_view_column_pack_start", "GtkTreeViewColumn*"); Xen_check_type(Xen_is_GtkCellRenderer_(cell), cell, 2, "gtk_tree_view_column_pack_start", "GtkCellRenderer*"); Xen_check_type(Xen_is_gboolean(expand), expand, 3, "gtk_tree_view_column_pack_start", "gboolean"); gtk_tree_view_column_pack_start(Xen_to_C_GtkTreeViewColumn_(tree_column), Xen_to_C_GtkCellRenderer_(cell), Xen_to_C_gboolean(expand)); return(Xen_false); } static Xen gxg_gtk_tree_view_column_pack_end(Xen tree_column, Xen cell, Xen expand) { #define H_gtk_tree_view_column_pack_end "void gtk_tree_view_column_pack_end(GtkTreeViewColumn* tree_column, \ GtkCellRenderer* cell, gboolean expand)" Xen_check_type(Xen_is_GtkTreeViewColumn_(tree_column), tree_column, 1, "gtk_tree_view_column_pack_end", "GtkTreeViewColumn*"); Xen_check_type(Xen_is_GtkCellRenderer_(cell), cell, 2, "gtk_tree_view_column_pack_end", "GtkCellRenderer*"); Xen_check_type(Xen_is_gboolean(expand), expand, 3, "gtk_tree_view_column_pack_end", "gboolean"); gtk_tree_view_column_pack_end(Xen_to_C_GtkTreeViewColumn_(tree_column), Xen_to_C_GtkCellRenderer_(cell), Xen_to_C_gboolean(expand)); return(Xen_false); } static Xen gxg_gtk_tree_view_column_clear(Xen tree_column) { #define H_gtk_tree_view_column_clear "void gtk_tree_view_column_clear(GtkTreeViewColumn* tree_column)" Xen_check_type(Xen_is_GtkTreeViewColumn_(tree_column), tree_column, 1, "gtk_tree_view_column_clear", "GtkTreeViewColumn*"); gtk_tree_view_column_clear(Xen_to_C_GtkTreeViewColumn_(tree_column)); return(Xen_false); } static Xen gxg_gtk_tree_view_column_add_attribute(Xen tree_column, Xen cell_renderer, Xen attribute, Xen column) { #define H_gtk_tree_view_column_add_attribute "void gtk_tree_view_column_add_attribute(GtkTreeViewColumn* tree_column, \ GtkCellRenderer* cell_renderer, gchar* attribute, gint column)" Xen_check_type(Xen_is_GtkTreeViewColumn_(tree_column), tree_column, 1, "gtk_tree_view_column_add_attribute", "GtkTreeViewColumn*"); Xen_check_type(Xen_is_GtkCellRenderer_(cell_renderer), cell_renderer, 2, "gtk_tree_view_column_add_attribute", "GtkCellRenderer*"); Xen_check_type(Xen_is_gchar_(attribute), attribute, 3, "gtk_tree_view_column_add_attribute", "gchar*"); Xen_check_type(Xen_is_gint(column), column, 4, "gtk_tree_view_column_add_attribute", "gint"); gtk_tree_view_column_add_attribute(Xen_to_C_GtkTreeViewColumn_(tree_column), Xen_to_C_GtkCellRenderer_(cell_renderer), Xen_to_C_gchar_(attribute), Xen_to_C_gint(column)); return(Xen_false); } static Xen gxg_gtk_tree_view_column_set_attributes(Xen tree_column, Xen cell_renderer, Xen attributes) { #define H_gtk_tree_view_column_set_attributes "void gtk_tree_view_column_set_attributes(GtkTreeViewColumn* tree_column, \ GtkCellRenderer* cell_renderer, etc attributes)" Xen_check_type(Xen_is_GtkTreeViewColumn_(tree_column), tree_column, 1, "gtk_tree_view_column_set_attributes", "GtkTreeViewColumn*"); Xen_check_type(Xen_is_GtkCellRenderer_(cell_renderer), cell_renderer, 2, "gtk_tree_view_column_set_attributes", "GtkCellRenderer*"); Xen_check_type(Xen_is_etc(attributes), attributes, 3, "gtk_tree_view_column_set_attributes", "etc"); { int etc_len = 0; GtkTreeViewColumn* p_arg0; GtkCellRenderer* p_arg1; if (Xen_is_list(attributes)) etc_len = Xen_list_length(attributes); if (etc_len < 2) Xen_out_of_range_error("gtk_tree_view_column_set_attributes", 2, attributes, "... list must have at least 2 entries"); if (etc_len > 10) Xen_out_of_range_error("gtk_tree_view_column_set_attributes", 2, attributes, "... list too long (max len: 10)"); if ((etc_len % 2) != 0) Xen_out_of_range_error("gtk_tree_view_column_set_attributes", 2, attributes, "... list len must be multiple of 2"); p_arg0 = Xen_to_C_GtkTreeViewColumn_(tree_column); p_arg1 = Xen_to_C_GtkCellRenderer_(cell_renderer); switch (etc_len) { case 2: gtk_tree_view_column_set_attributes(p_arg0, p_arg1, XLS(attributes, 0), XLI(attributes, 1), NULL); break; case 4: gtk_tree_view_column_set_attributes(p_arg0, p_arg1, XLS(attributes, 0), XLI(attributes, 1), XLS(attributes, 2), XLI(attributes, 3), NULL); break; case 6: gtk_tree_view_column_set_attributes(p_arg0, p_arg1, XLS(attributes, 0), XLI(attributes, 1), XLS(attributes, 2), XLI(attributes, 3), XLS(attributes, 4), XLI(attributes, 5), NULL); break; case 8: gtk_tree_view_column_set_attributes(p_arg0, p_arg1, XLS(attributes, 0), XLI(attributes, 1), XLS(attributes, 2), XLI(attributes, 3), XLS(attributes, 4), XLI(attributes, 5), XLS(attributes, 6), XLI(attributes, 7), NULL); break; case 10: gtk_tree_view_column_set_attributes(p_arg0, p_arg1, XLS(attributes, 0), XLI(attributes, 1), XLS(attributes, 2), XLI(attributes, 3), XLS(attributes, 4), XLI(attributes, 5), XLS(attributes, 6), XLI(attributes, 7), XLS(attributes, 8), XLI(attributes, 9), NULL); break; } return(Xen_false); } } static Xen gxg_gtk_tree_view_column_set_cell_data_func(Xen tree_column, Xen cell_renderer, Xen func, Xen func_info, Xen destroy) { #define H_gtk_tree_view_column_set_cell_data_func "void gtk_tree_view_column_set_cell_data_func(GtkTreeViewColumn* tree_column, \ GtkCellRenderer* cell_renderer, GtkTreeCellDataFunc func, lambda_data func_info, GtkDestroyNotify destroy)" Xen_check_type(Xen_is_GtkTreeViewColumn_(tree_column), tree_column, 1, "gtk_tree_view_column_set_cell_data_func", "GtkTreeViewColumn*"); Xen_check_type(Xen_is_GtkCellRenderer_(cell_renderer), cell_renderer, 2, "gtk_tree_view_column_set_cell_data_func", "GtkCellRenderer*"); Xen_check_type(Xen_is_GtkTreeCellDataFunc(func), func, 3, "gtk_tree_view_column_set_cell_data_func", "GtkTreeCellDataFunc"); Xen_check_type(Xen_is_lambda_data(func_info), func_info, 4, "gtk_tree_view_column_set_cell_data_func", "lambda_data"); Xen_check_type(Xen_is_GtkDestroyNotify(destroy), destroy, 5, "gtk_tree_view_column_set_cell_data_func", "GtkDestroyNotify"); { Xen gxg_ptr = Xen_list_5(func, func_info, Xen_false, Xen_false, Xen_false); xm_protect(gxg_ptr); Xen_list_set(gxg_ptr, 3, destroy); gtk_tree_view_column_set_cell_data_func(Xen_to_C_GtkTreeViewColumn_(tree_column), Xen_to_C_GtkCellRenderer_(cell_renderer), Xen_to_C_GtkTreeCellDataFunc(func), Xen_to_C_lambda_data(func_info), Xen_to_C_GtkDestroyNotify(destroy)); return(Xen_false); } } static Xen gxg_gtk_tree_view_column_clear_attributes(Xen tree_column, Xen cell_renderer) { #define H_gtk_tree_view_column_clear_attributes "void gtk_tree_view_column_clear_attributes(GtkTreeViewColumn* tree_column, \ GtkCellRenderer* cell_renderer)" Xen_check_type(Xen_is_GtkTreeViewColumn_(tree_column), tree_column, 1, "gtk_tree_view_column_clear_attributes", "GtkTreeViewColumn*"); Xen_check_type(Xen_is_GtkCellRenderer_(cell_renderer), cell_renderer, 2, "gtk_tree_view_column_clear_attributes", "GtkCellRenderer*"); gtk_tree_view_column_clear_attributes(Xen_to_C_GtkTreeViewColumn_(tree_column), Xen_to_C_GtkCellRenderer_(cell_renderer)); return(Xen_false); } static Xen gxg_gtk_tree_view_column_set_spacing(Xen tree_column, Xen spacing) { #define H_gtk_tree_view_column_set_spacing "void gtk_tree_view_column_set_spacing(GtkTreeViewColumn* tree_column, \ gint spacing)" Xen_check_type(Xen_is_GtkTreeViewColumn_(tree_column), tree_column, 1, "gtk_tree_view_column_set_spacing", "GtkTreeViewColumn*"); Xen_check_type(Xen_is_gint(spacing), spacing, 2, "gtk_tree_view_column_set_spacing", "gint"); gtk_tree_view_column_set_spacing(Xen_to_C_GtkTreeViewColumn_(tree_column), Xen_to_C_gint(spacing)); return(Xen_false); } static Xen gxg_gtk_tree_view_column_get_spacing(Xen tree_column) { #define H_gtk_tree_view_column_get_spacing "gint gtk_tree_view_column_get_spacing(GtkTreeViewColumn* tree_column)" Xen_check_type(Xen_is_GtkTreeViewColumn_(tree_column), tree_column, 1, "gtk_tree_view_column_get_spacing", "GtkTreeViewColumn*"); return(C_to_Xen_gint(gtk_tree_view_column_get_spacing(Xen_to_C_GtkTreeViewColumn_(tree_column)))); } static Xen gxg_gtk_tree_view_column_set_visible(Xen tree_column, Xen visible) { #define H_gtk_tree_view_column_set_visible "void gtk_tree_view_column_set_visible(GtkTreeViewColumn* tree_column, \ gboolean visible)" Xen_check_type(Xen_is_GtkTreeViewColumn_(tree_column), tree_column, 1, "gtk_tree_view_column_set_visible", "GtkTreeViewColumn*"); Xen_check_type(Xen_is_gboolean(visible), visible, 2, "gtk_tree_view_column_set_visible", "gboolean"); gtk_tree_view_column_set_visible(Xen_to_C_GtkTreeViewColumn_(tree_column), Xen_to_C_gboolean(visible)); return(Xen_false); } static Xen gxg_gtk_tree_view_column_get_visible(Xen tree_column) { #define H_gtk_tree_view_column_get_visible "gboolean gtk_tree_view_column_get_visible(GtkTreeViewColumn* tree_column)" Xen_check_type(Xen_is_GtkTreeViewColumn_(tree_column), tree_column, 1, "gtk_tree_view_column_get_visible", "GtkTreeViewColumn*"); return(C_to_Xen_gboolean(gtk_tree_view_column_get_visible(Xen_to_C_GtkTreeViewColumn_(tree_column)))); } static Xen gxg_gtk_tree_view_column_set_resizable(Xen tree_column, Xen resizable) { #define H_gtk_tree_view_column_set_resizable "void gtk_tree_view_column_set_resizable(GtkTreeViewColumn* tree_column, \ gboolean resizable)" Xen_check_type(Xen_is_GtkTreeViewColumn_(tree_column), tree_column, 1, "gtk_tree_view_column_set_resizable", "GtkTreeViewColumn*"); Xen_check_type(Xen_is_gboolean(resizable), resizable, 2, "gtk_tree_view_column_set_resizable", "gboolean"); gtk_tree_view_column_set_resizable(Xen_to_C_GtkTreeViewColumn_(tree_column), Xen_to_C_gboolean(resizable)); return(Xen_false); } static Xen gxg_gtk_tree_view_column_get_resizable(Xen tree_column) { #define H_gtk_tree_view_column_get_resizable "gboolean gtk_tree_view_column_get_resizable(GtkTreeViewColumn* tree_column)" Xen_check_type(Xen_is_GtkTreeViewColumn_(tree_column), tree_column, 1, "gtk_tree_view_column_get_resizable", "GtkTreeViewColumn*"); return(C_to_Xen_gboolean(gtk_tree_view_column_get_resizable(Xen_to_C_GtkTreeViewColumn_(tree_column)))); } static Xen gxg_gtk_tree_view_column_set_sizing(Xen tree_column, Xen type) { #define H_gtk_tree_view_column_set_sizing "void gtk_tree_view_column_set_sizing(GtkTreeViewColumn* tree_column, \ GtkTreeViewColumnSizing type)" Xen_check_type(Xen_is_GtkTreeViewColumn_(tree_column), tree_column, 1, "gtk_tree_view_column_set_sizing", "GtkTreeViewColumn*"); Xen_check_type(Xen_is_GtkTreeViewColumnSizing(type), type, 2, "gtk_tree_view_column_set_sizing", "GtkTreeViewColumnSizing"); gtk_tree_view_column_set_sizing(Xen_to_C_GtkTreeViewColumn_(tree_column), Xen_to_C_GtkTreeViewColumnSizing(type)); return(Xen_false); } static Xen gxg_gtk_tree_view_column_get_sizing(Xen tree_column) { #define H_gtk_tree_view_column_get_sizing "GtkTreeViewColumnSizing gtk_tree_view_column_get_sizing(GtkTreeViewColumn* tree_column)" Xen_check_type(Xen_is_GtkTreeViewColumn_(tree_column), tree_column, 1, "gtk_tree_view_column_get_sizing", "GtkTreeViewColumn*"); return(C_to_Xen_GtkTreeViewColumnSizing(gtk_tree_view_column_get_sizing(Xen_to_C_GtkTreeViewColumn_(tree_column)))); } static Xen gxg_gtk_tree_view_column_get_width(Xen tree_column) { #define H_gtk_tree_view_column_get_width "gint gtk_tree_view_column_get_width(GtkTreeViewColumn* tree_column)" Xen_check_type(Xen_is_GtkTreeViewColumn_(tree_column), tree_column, 1, "gtk_tree_view_column_get_width", "GtkTreeViewColumn*"); return(C_to_Xen_gint(gtk_tree_view_column_get_width(Xen_to_C_GtkTreeViewColumn_(tree_column)))); } static Xen gxg_gtk_tree_view_column_get_fixed_width(Xen tree_column) { #define H_gtk_tree_view_column_get_fixed_width "gint gtk_tree_view_column_get_fixed_width(GtkTreeViewColumn* tree_column)" Xen_check_type(Xen_is_GtkTreeViewColumn_(tree_column), tree_column, 1, "gtk_tree_view_column_get_fixed_width", "GtkTreeViewColumn*"); return(C_to_Xen_gint(gtk_tree_view_column_get_fixed_width(Xen_to_C_GtkTreeViewColumn_(tree_column)))); } static Xen gxg_gtk_tree_view_column_set_fixed_width(Xen tree_column, Xen fixed_width) { #define H_gtk_tree_view_column_set_fixed_width "void gtk_tree_view_column_set_fixed_width(GtkTreeViewColumn* tree_column, \ gint fixed_width)" Xen_check_type(Xen_is_GtkTreeViewColumn_(tree_column), tree_column, 1, "gtk_tree_view_column_set_fixed_width", "GtkTreeViewColumn*"); Xen_check_type(Xen_is_gint(fixed_width), fixed_width, 2, "gtk_tree_view_column_set_fixed_width", "gint"); gtk_tree_view_column_set_fixed_width(Xen_to_C_GtkTreeViewColumn_(tree_column), Xen_to_C_gint(fixed_width)); return(Xen_false); } static Xen gxg_gtk_tree_view_column_set_min_width(Xen tree_column, Xen min_width) { #define H_gtk_tree_view_column_set_min_width "void gtk_tree_view_column_set_min_width(GtkTreeViewColumn* tree_column, \ gint min_width)" Xen_check_type(Xen_is_GtkTreeViewColumn_(tree_column), tree_column, 1, "gtk_tree_view_column_set_min_width", "GtkTreeViewColumn*"); Xen_check_type(Xen_is_gint(min_width), min_width, 2, "gtk_tree_view_column_set_min_width", "gint"); gtk_tree_view_column_set_min_width(Xen_to_C_GtkTreeViewColumn_(tree_column), Xen_to_C_gint(min_width)); return(Xen_false); } static Xen gxg_gtk_tree_view_column_get_min_width(Xen tree_column) { #define H_gtk_tree_view_column_get_min_width "gint gtk_tree_view_column_get_min_width(GtkTreeViewColumn* tree_column)" Xen_check_type(Xen_is_GtkTreeViewColumn_(tree_column), tree_column, 1, "gtk_tree_view_column_get_min_width", "GtkTreeViewColumn*"); return(C_to_Xen_gint(gtk_tree_view_column_get_min_width(Xen_to_C_GtkTreeViewColumn_(tree_column)))); } static Xen gxg_gtk_tree_view_column_set_max_width(Xen tree_column, Xen max_width) { #define H_gtk_tree_view_column_set_max_width "void gtk_tree_view_column_set_max_width(GtkTreeViewColumn* tree_column, \ gint max_width)" Xen_check_type(Xen_is_GtkTreeViewColumn_(tree_column), tree_column, 1, "gtk_tree_view_column_set_max_width", "GtkTreeViewColumn*"); Xen_check_type(Xen_is_gint(max_width), max_width, 2, "gtk_tree_view_column_set_max_width", "gint"); gtk_tree_view_column_set_max_width(Xen_to_C_GtkTreeViewColumn_(tree_column), Xen_to_C_gint(max_width)); return(Xen_false); } static Xen gxg_gtk_tree_view_column_get_max_width(Xen tree_column) { #define H_gtk_tree_view_column_get_max_width "gint gtk_tree_view_column_get_max_width(GtkTreeViewColumn* tree_column)" Xen_check_type(Xen_is_GtkTreeViewColumn_(tree_column), tree_column, 1, "gtk_tree_view_column_get_max_width", "GtkTreeViewColumn*"); return(C_to_Xen_gint(gtk_tree_view_column_get_max_width(Xen_to_C_GtkTreeViewColumn_(tree_column)))); } static Xen gxg_gtk_tree_view_column_clicked(Xen tree_column) { #define H_gtk_tree_view_column_clicked "void gtk_tree_view_column_clicked(GtkTreeViewColumn* tree_column)" Xen_check_type(Xen_is_GtkTreeViewColumn_(tree_column), tree_column, 1, "gtk_tree_view_column_clicked", "GtkTreeViewColumn*"); gtk_tree_view_column_clicked(Xen_to_C_GtkTreeViewColumn_(tree_column)); return(Xen_false); } static Xen gxg_gtk_tree_view_column_set_title(Xen tree_column, Xen title) { #define H_gtk_tree_view_column_set_title "void gtk_tree_view_column_set_title(GtkTreeViewColumn* tree_column, \ gchar* title)" Xen_check_type(Xen_is_GtkTreeViewColumn_(tree_column), tree_column, 1, "gtk_tree_view_column_set_title", "GtkTreeViewColumn*"); Xen_check_type(Xen_is_gchar_(title), title, 2, "gtk_tree_view_column_set_title", "gchar*"); gtk_tree_view_column_set_title(Xen_to_C_GtkTreeViewColumn_(tree_column), Xen_to_C_gchar_(title)); return(Xen_false); } static Xen gxg_gtk_tree_view_column_get_title(Xen tree_column) { #define H_gtk_tree_view_column_get_title "gchar* gtk_tree_view_column_get_title(GtkTreeViewColumn* tree_column)" Xen_check_type(Xen_is_GtkTreeViewColumn_(tree_column), tree_column, 1, "gtk_tree_view_column_get_title", "GtkTreeViewColumn*"); return(C_to_Xen_gchar_(gtk_tree_view_column_get_title(Xen_to_C_GtkTreeViewColumn_(tree_column)))); } static Xen gxg_gtk_tree_view_column_set_clickable(Xen tree_column, Xen clickable) { #define H_gtk_tree_view_column_set_clickable "void gtk_tree_view_column_set_clickable(GtkTreeViewColumn* tree_column, \ gboolean clickable)" Xen_check_type(Xen_is_GtkTreeViewColumn_(tree_column), tree_column, 1, "gtk_tree_view_column_set_clickable", "GtkTreeViewColumn*"); Xen_check_type(Xen_is_gboolean(clickable), clickable, 2, "gtk_tree_view_column_set_clickable", "gboolean"); gtk_tree_view_column_set_clickable(Xen_to_C_GtkTreeViewColumn_(tree_column), Xen_to_C_gboolean(clickable)); return(Xen_false); } static Xen gxg_gtk_tree_view_column_get_clickable(Xen tree_column) { #define H_gtk_tree_view_column_get_clickable "gboolean gtk_tree_view_column_get_clickable(GtkTreeViewColumn* tree_column)" Xen_check_type(Xen_is_GtkTreeViewColumn_(tree_column), tree_column, 1, "gtk_tree_view_column_get_clickable", "GtkTreeViewColumn*"); return(C_to_Xen_gboolean(gtk_tree_view_column_get_clickable(Xen_to_C_GtkTreeViewColumn_(tree_column)))); } static Xen gxg_gtk_tree_view_column_set_widget(Xen tree_column, Xen widget) { #define H_gtk_tree_view_column_set_widget "void gtk_tree_view_column_set_widget(GtkTreeViewColumn* tree_column, \ GtkWidget* widget)" Xen_check_type(Xen_is_GtkTreeViewColumn_(tree_column), tree_column, 1, "gtk_tree_view_column_set_widget", "GtkTreeViewColumn*"); Xen_check_type(Xen_is_GtkWidget_(widget) || Xen_is_false(widget), widget, 2, "gtk_tree_view_column_set_widget", "GtkWidget*"); gtk_tree_view_column_set_widget(Xen_to_C_GtkTreeViewColumn_(tree_column), Xen_to_C_GtkWidget_(widget)); return(Xen_false); } static Xen gxg_gtk_tree_view_column_get_widget(Xen tree_column) { #define H_gtk_tree_view_column_get_widget "GtkWidget* gtk_tree_view_column_get_widget(GtkTreeViewColumn* tree_column)" Xen_check_type(Xen_is_GtkTreeViewColumn_(tree_column), tree_column, 1, "gtk_tree_view_column_get_widget", "GtkTreeViewColumn*"); return(C_to_Xen_GtkWidget_(gtk_tree_view_column_get_widget(Xen_to_C_GtkTreeViewColumn_(tree_column)))); } static Xen gxg_gtk_tree_view_column_set_alignment(Xen tree_column, Xen xalign) { #define H_gtk_tree_view_column_set_alignment "void gtk_tree_view_column_set_alignment(GtkTreeViewColumn* tree_column, \ gfloat xalign)" Xen_check_type(Xen_is_GtkTreeViewColumn_(tree_column), tree_column, 1, "gtk_tree_view_column_set_alignment", "GtkTreeViewColumn*"); Xen_check_type(Xen_is_gfloat(xalign), xalign, 2, "gtk_tree_view_column_set_alignment", "gfloat"); gtk_tree_view_column_set_alignment(Xen_to_C_GtkTreeViewColumn_(tree_column), Xen_to_C_gfloat(xalign)); return(Xen_false); } static Xen gxg_gtk_tree_view_column_get_alignment(Xen tree_column) { #define H_gtk_tree_view_column_get_alignment "gfloat gtk_tree_view_column_get_alignment(GtkTreeViewColumn* tree_column)" Xen_check_type(Xen_is_GtkTreeViewColumn_(tree_column), tree_column, 1, "gtk_tree_view_column_get_alignment", "GtkTreeViewColumn*"); return(C_to_Xen_gfloat(gtk_tree_view_column_get_alignment(Xen_to_C_GtkTreeViewColumn_(tree_column)))); } static Xen gxg_gtk_tree_view_column_set_reorderable(Xen tree_column, Xen reorderable) { #define H_gtk_tree_view_column_set_reorderable "void gtk_tree_view_column_set_reorderable(GtkTreeViewColumn* tree_column, \ gboolean reorderable)" Xen_check_type(Xen_is_GtkTreeViewColumn_(tree_column), tree_column, 1, "gtk_tree_view_column_set_reorderable", "GtkTreeViewColumn*"); Xen_check_type(Xen_is_gboolean(reorderable), reorderable, 2, "gtk_tree_view_column_set_reorderable", "gboolean"); gtk_tree_view_column_set_reorderable(Xen_to_C_GtkTreeViewColumn_(tree_column), Xen_to_C_gboolean(reorderable)); return(Xen_false); } static Xen gxg_gtk_tree_view_column_get_reorderable(Xen tree_column) { #define H_gtk_tree_view_column_get_reorderable "gboolean gtk_tree_view_column_get_reorderable(GtkTreeViewColumn* tree_column)" Xen_check_type(Xen_is_GtkTreeViewColumn_(tree_column), tree_column, 1, "gtk_tree_view_column_get_reorderable", "GtkTreeViewColumn*"); return(C_to_Xen_gboolean(gtk_tree_view_column_get_reorderable(Xen_to_C_GtkTreeViewColumn_(tree_column)))); } static Xen gxg_gtk_tree_view_column_set_sort_column_id(Xen tree_column, Xen sort_column_id) { #define H_gtk_tree_view_column_set_sort_column_id "void gtk_tree_view_column_set_sort_column_id(GtkTreeViewColumn* tree_column, \ gint sort_column_id)" Xen_check_type(Xen_is_GtkTreeViewColumn_(tree_column), tree_column, 1, "gtk_tree_view_column_set_sort_column_id", "GtkTreeViewColumn*"); Xen_check_type(Xen_is_gint(sort_column_id), sort_column_id, 2, "gtk_tree_view_column_set_sort_column_id", "gint"); gtk_tree_view_column_set_sort_column_id(Xen_to_C_GtkTreeViewColumn_(tree_column), Xen_to_C_gint(sort_column_id)); return(Xen_false); } static Xen gxg_gtk_tree_view_column_get_sort_column_id(Xen tree_column) { #define H_gtk_tree_view_column_get_sort_column_id "gint gtk_tree_view_column_get_sort_column_id(GtkTreeViewColumn* tree_column)" Xen_check_type(Xen_is_GtkTreeViewColumn_(tree_column), tree_column, 1, "gtk_tree_view_column_get_sort_column_id", "GtkTreeViewColumn*"); return(C_to_Xen_gint(gtk_tree_view_column_get_sort_column_id(Xen_to_C_GtkTreeViewColumn_(tree_column)))); } static Xen gxg_gtk_tree_view_column_set_sort_indicator(Xen tree_column, Xen setting) { #define H_gtk_tree_view_column_set_sort_indicator "void gtk_tree_view_column_set_sort_indicator(GtkTreeViewColumn* tree_column, \ gboolean setting)" Xen_check_type(Xen_is_GtkTreeViewColumn_(tree_column), tree_column, 1, "gtk_tree_view_column_set_sort_indicator", "GtkTreeViewColumn*"); Xen_check_type(Xen_is_gboolean(setting), setting, 2, "gtk_tree_view_column_set_sort_indicator", "gboolean"); gtk_tree_view_column_set_sort_indicator(Xen_to_C_GtkTreeViewColumn_(tree_column), Xen_to_C_gboolean(setting)); return(Xen_false); } static Xen gxg_gtk_tree_view_column_get_sort_indicator(Xen tree_column) { #define H_gtk_tree_view_column_get_sort_indicator "gboolean gtk_tree_view_column_get_sort_indicator(GtkTreeViewColumn* tree_column)" Xen_check_type(Xen_is_GtkTreeViewColumn_(tree_column), tree_column, 1, "gtk_tree_view_column_get_sort_indicator", "GtkTreeViewColumn*"); return(C_to_Xen_gboolean(gtk_tree_view_column_get_sort_indicator(Xen_to_C_GtkTreeViewColumn_(tree_column)))); } static Xen gxg_gtk_tree_view_column_set_sort_order(Xen tree_column, Xen order) { #define H_gtk_tree_view_column_set_sort_order "void gtk_tree_view_column_set_sort_order(GtkTreeViewColumn* tree_column, \ GtkSortType order)" Xen_check_type(Xen_is_GtkTreeViewColumn_(tree_column), tree_column, 1, "gtk_tree_view_column_set_sort_order", "GtkTreeViewColumn*"); Xen_check_type(Xen_is_GtkSortType(order), order, 2, "gtk_tree_view_column_set_sort_order", "GtkSortType"); gtk_tree_view_column_set_sort_order(Xen_to_C_GtkTreeViewColumn_(tree_column), Xen_to_C_GtkSortType(order)); return(Xen_false); } static Xen gxg_gtk_tree_view_column_get_sort_order(Xen tree_column) { #define H_gtk_tree_view_column_get_sort_order "GtkSortType gtk_tree_view_column_get_sort_order(GtkTreeViewColumn* tree_column)" Xen_check_type(Xen_is_GtkTreeViewColumn_(tree_column), tree_column, 1, "gtk_tree_view_column_get_sort_order", "GtkTreeViewColumn*"); return(C_to_Xen_GtkSortType(gtk_tree_view_column_get_sort_order(Xen_to_C_GtkTreeViewColumn_(tree_column)))); } static Xen gxg_gtk_tree_view_column_cell_set_cell_data(Xen tree_column, Xen tree_model, Xen iter, Xen is_expander, Xen is_expanded) { #define H_gtk_tree_view_column_cell_set_cell_data "void gtk_tree_view_column_cell_set_cell_data(GtkTreeViewColumn* tree_column, \ GtkTreeModel* tree_model, GtkTreeIter* iter, gboolean is_expander, gboolean is_expanded)" Xen_check_type(Xen_is_GtkTreeViewColumn_(tree_column), tree_column, 1, "gtk_tree_view_column_cell_set_cell_data", "GtkTreeViewColumn*"); Xen_check_type(Xen_is_GtkTreeModel_(tree_model), tree_model, 2, "gtk_tree_view_column_cell_set_cell_data", "GtkTreeModel*"); Xen_check_type(Xen_is_GtkTreeIter_(iter), iter, 3, "gtk_tree_view_column_cell_set_cell_data", "GtkTreeIter*"); Xen_check_type(Xen_is_gboolean(is_expander), is_expander, 4, "gtk_tree_view_column_cell_set_cell_data", "gboolean"); Xen_check_type(Xen_is_gboolean(is_expanded), is_expanded, 5, "gtk_tree_view_column_cell_set_cell_data", "gboolean"); gtk_tree_view_column_cell_set_cell_data(Xen_to_C_GtkTreeViewColumn_(tree_column), Xen_to_C_GtkTreeModel_(tree_model), Xen_to_C_GtkTreeIter_(iter), Xen_to_C_gboolean(is_expander), Xen_to_C_gboolean(is_expanded)); return(Xen_false); } static Xen gxg_gtk_tree_view_column_cell_get_size(Xen tree_column, Xen cell_area, Xen ignore_x_offset, Xen ignore_y_offset, Xen ignore_width, Xen ignore_height) { #define H_gtk_tree_view_column_cell_get_size "void gtk_tree_view_column_cell_get_size(GtkTreeViewColumn* tree_column, \ GdkRectangle* cell_area, gint* [x_offset], gint* [y_offset], gint* [width], gint* [height])" gint ref_x_offset; gint ref_y_offset; gint ref_width; gint ref_height; Xen_check_type(Xen_is_GtkTreeViewColumn_(tree_column), tree_column, 1, "gtk_tree_view_column_cell_get_size", "GtkTreeViewColumn*"); Xen_check_type(Xen_is_GdkRectangle_(cell_area), cell_area, 2, "gtk_tree_view_column_cell_get_size", "GdkRectangle*"); gtk_tree_view_column_cell_get_size(Xen_to_C_GtkTreeViewColumn_(tree_column), Xen_to_C_GdkRectangle_(cell_area), &ref_x_offset, &ref_y_offset, &ref_width, &ref_height); return(Xen_list_4(C_to_Xen_gint(ref_x_offset), C_to_Xen_gint(ref_y_offset), C_to_Xen_gint(ref_width), C_to_Xen_gint(ref_height))); } static Xen gxg_gtk_tree_view_column_cell_is_visible(Xen tree_column) { #define H_gtk_tree_view_column_cell_is_visible "gboolean gtk_tree_view_column_cell_is_visible(GtkTreeViewColumn* tree_column)" Xen_check_type(Xen_is_GtkTreeViewColumn_(tree_column), tree_column, 1, "gtk_tree_view_column_cell_is_visible", "GtkTreeViewColumn*"); return(C_to_Xen_gboolean(gtk_tree_view_column_cell_is_visible(Xen_to_C_GtkTreeViewColumn_(tree_column)))); } static Xen gxg_gtk_tree_view_column_cell_get_position(Xen tree_column, Xen cell_renderer, Xen ignore_start_pos, Xen ignore_width) { #define H_gtk_tree_view_column_cell_get_position "gboolean gtk_tree_view_column_cell_get_position(GtkTreeViewColumn* tree_column, \ GtkCellRenderer* cell_renderer, gint* [start_pos], gint* [width])" gint ref_start_pos; gint ref_width; Xen_check_type(Xen_is_GtkTreeViewColumn_(tree_column), tree_column, 1, "gtk_tree_view_column_cell_get_position", "GtkTreeViewColumn*"); Xen_check_type(Xen_is_GtkCellRenderer_(cell_renderer), cell_renderer, 2, "gtk_tree_view_column_cell_get_position", "GtkCellRenderer*"); { Xen result; result = C_to_Xen_gboolean(gtk_tree_view_column_cell_get_position(Xen_to_C_GtkTreeViewColumn_(tree_column), Xen_to_C_GtkCellRenderer_(cell_renderer), &ref_start_pos, &ref_width)); return(Xen_list_3(result, C_to_Xen_gint(ref_start_pos), C_to_Xen_gint(ref_width))); } } static Xen gxg_gtk_tree_view_new(void) { #define H_gtk_tree_view_new "GtkWidget* gtk_tree_view_new( void)" return(C_to_Xen_GtkWidget_(gtk_tree_view_new())); } static Xen gxg_gtk_tree_view_new_with_model(Xen model) { #define H_gtk_tree_view_new_with_model "GtkWidget* gtk_tree_view_new_with_model(GtkTreeModel* model)" Xen_check_type(Xen_is_GtkTreeModel_(model), model, 1, "gtk_tree_view_new_with_model", "GtkTreeModel*"); return(C_to_Xen_GtkWidget_(gtk_tree_view_new_with_model(Xen_to_C_GtkTreeModel_(model)))); } static Xen gxg_gtk_tree_view_get_model(Xen tree_view) { #define H_gtk_tree_view_get_model "GtkTreeModel* gtk_tree_view_get_model(GtkTreeView* tree_view)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_get_model", "GtkTreeView*"); return(C_to_Xen_GtkTreeModel_(gtk_tree_view_get_model(Xen_to_C_GtkTreeView_(tree_view)))); } static Xen gxg_gtk_tree_view_set_model(Xen tree_view, Xen model) { #define H_gtk_tree_view_set_model "void gtk_tree_view_set_model(GtkTreeView* tree_view, GtkTreeModel* model)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_set_model", "GtkTreeView*"); Xen_check_type(Xen_is_GtkTreeModel_(model) || Xen_is_false(model), model, 2, "gtk_tree_view_set_model", "GtkTreeModel*"); gtk_tree_view_set_model(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_GtkTreeModel_(model)); return(Xen_false); } static Xen gxg_gtk_tree_view_get_selection(Xen tree_view) { #define H_gtk_tree_view_get_selection "GtkTreeSelection* gtk_tree_view_get_selection(GtkTreeView* tree_view)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_get_selection", "GtkTreeView*"); return(C_to_Xen_GtkTreeSelection_(gtk_tree_view_get_selection(Xen_to_C_GtkTreeView_(tree_view)))); } static Xen gxg_gtk_tree_view_get_headers_visible(Xen tree_view) { #define H_gtk_tree_view_get_headers_visible "gboolean gtk_tree_view_get_headers_visible(GtkTreeView* tree_view)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_get_headers_visible", "GtkTreeView*"); return(C_to_Xen_gboolean(gtk_tree_view_get_headers_visible(Xen_to_C_GtkTreeView_(tree_view)))); } static Xen gxg_gtk_tree_view_set_headers_visible(Xen tree_view, Xen headers_visible) { #define H_gtk_tree_view_set_headers_visible "void gtk_tree_view_set_headers_visible(GtkTreeView* tree_view, \ gboolean headers_visible)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_set_headers_visible", "GtkTreeView*"); Xen_check_type(Xen_is_gboolean(headers_visible), headers_visible, 2, "gtk_tree_view_set_headers_visible", "gboolean"); gtk_tree_view_set_headers_visible(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_gboolean(headers_visible)); return(Xen_false); } static Xen gxg_gtk_tree_view_columns_autosize(Xen tree_view) { #define H_gtk_tree_view_columns_autosize "void gtk_tree_view_columns_autosize(GtkTreeView* tree_view)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_columns_autosize", "GtkTreeView*"); gtk_tree_view_columns_autosize(Xen_to_C_GtkTreeView_(tree_view)); return(Xen_false); } static Xen gxg_gtk_tree_view_set_headers_clickable(Xen tree_view, Xen setting) { #define H_gtk_tree_view_set_headers_clickable "void gtk_tree_view_set_headers_clickable(GtkTreeView* tree_view, \ gboolean setting)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_set_headers_clickable", "GtkTreeView*"); Xen_check_type(Xen_is_gboolean(setting), setting, 2, "gtk_tree_view_set_headers_clickable", "gboolean"); gtk_tree_view_set_headers_clickable(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_gboolean(setting)); return(Xen_false); } static Xen gxg_gtk_tree_view_append_column(Xen tree_view, Xen column) { #define H_gtk_tree_view_append_column "gint gtk_tree_view_append_column(GtkTreeView* tree_view, GtkTreeViewColumn* column)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_append_column", "GtkTreeView*"); Xen_check_type(Xen_is_GtkTreeViewColumn_(column), column, 2, "gtk_tree_view_append_column", "GtkTreeViewColumn*"); return(C_to_Xen_gint(gtk_tree_view_append_column(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_GtkTreeViewColumn_(column)))); } static Xen gxg_gtk_tree_view_remove_column(Xen tree_view, Xen column) { #define H_gtk_tree_view_remove_column "gint gtk_tree_view_remove_column(GtkTreeView* tree_view, GtkTreeViewColumn* column)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_remove_column", "GtkTreeView*"); Xen_check_type(Xen_is_GtkTreeViewColumn_(column), column, 2, "gtk_tree_view_remove_column", "GtkTreeViewColumn*"); return(C_to_Xen_gint(gtk_tree_view_remove_column(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_GtkTreeViewColumn_(column)))); } static Xen gxg_gtk_tree_view_insert_column(Xen tree_view, Xen column, Xen position) { #define H_gtk_tree_view_insert_column "gint gtk_tree_view_insert_column(GtkTreeView* tree_view, GtkTreeViewColumn* column, \ gint position)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_insert_column", "GtkTreeView*"); Xen_check_type(Xen_is_GtkTreeViewColumn_(column), column, 2, "gtk_tree_view_insert_column", "GtkTreeViewColumn*"); Xen_check_type(Xen_is_gint(position), position, 3, "gtk_tree_view_insert_column", "gint"); return(C_to_Xen_gint(gtk_tree_view_insert_column(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_GtkTreeViewColumn_(column), Xen_to_C_gint(position)))); } static Xen gxg_gtk_tree_view_insert_column_with_attributes(Xen tree_view, Xen position, Xen title, Xen cell, Xen attributes) { #define H_gtk_tree_view_insert_column_with_attributes "gint gtk_tree_view_insert_column_with_attributes(GtkTreeView* tree_view, \ gint position, gchar* title, GtkCellRenderer* cell, etc attributes)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_insert_column_with_attributes", "GtkTreeView*"); Xen_check_type(Xen_is_gint(position), position, 2, "gtk_tree_view_insert_column_with_attributes", "gint"); Xen_check_type(Xen_is_gchar_(title), title, 3, "gtk_tree_view_insert_column_with_attributes", "gchar*"); Xen_check_type(Xen_is_GtkCellRenderer_(cell), cell, 4, "gtk_tree_view_insert_column_with_attributes", "GtkCellRenderer*"); Xen_check_type(Xen_is_etc(attributes), attributes, 5, "gtk_tree_view_insert_column_with_attributes", "etc"); { int etc_len = 0; gint result = 0; GtkTreeView* p_arg0; gint p_arg1; gchar* p_arg2; GtkCellRenderer* p_arg3; if (Xen_is_list(attributes)) etc_len = Xen_list_length(attributes); if (etc_len < 2) Xen_out_of_range_error("gtk_tree_view_insert_column_with_attributes", 4, attributes, "... list must have at least 2 entries"); if (etc_len > 10) Xen_out_of_range_error("gtk_tree_view_insert_column_with_attributes", 4, attributes, "... list too long (max len: 10)"); if ((etc_len % 2) != 0) Xen_out_of_range_error("gtk_tree_view_insert_column_with_attributes", 4, attributes, "... list len must be multiple of 2"); p_arg0 = Xen_to_C_GtkTreeView_(tree_view); p_arg1 = Xen_to_C_gint(position); p_arg2 = Xen_to_C_gchar_(title); p_arg3 = Xen_to_C_GtkCellRenderer_(cell); switch (etc_len) { case 2: result = gtk_tree_view_insert_column_with_attributes(p_arg0, p_arg1, p_arg2, p_arg3, XLS(attributes, 0), XLI(attributes, 1), NULL); break; case 4: result = gtk_tree_view_insert_column_with_attributes(p_arg0, p_arg1, p_arg2, p_arg3, XLS(attributes, 0), XLI(attributes, 1), XLS(attributes, 2), XLI(attributes, 3), NULL); break; case 6: result = gtk_tree_view_insert_column_with_attributes(p_arg0, p_arg1, p_arg2, p_arg3, XLS(attributes, 0), XLI(attributes, 1), XLS(attributes, 2), XLI(attributes, 3), XLS(attributes, 4), XLI(attributes, 5), NULL); break; case 8: result = gtk_tree_view_insert_column_with_attributes(p_arg0, p_arg1, p_arg2, p_arg3, XLS(attributes, 0), XLI(attributes, 1), XLS(attributes, 2), XLI(attributes, 3), XLS(attributes, 4), XLI(attributes, 5), XLS(attributes, 6), XLI(attributes, 7), NULL); break; case 10: result = gtk_tree_view_insert_column_with_attributes(p_arg0, p_arg1, p_arg2, p_arg3, XLS(attributes, 0), XLI(attributes, 1), XLS(attributes, 2), XLI(attributes, 3), XLS(attributes, 4), XLI(attributes, 5), XLS(attributes, 6), XLI(attributes, 7), XLS(attributes, 8), XLI(attributes, 9), NULL); break; } return(C_to_Xen_gint(result)); } } static Xen gxg_gtk_tree_view_insert_column_with_data_func(Xen tree_view, Xen position, Xen title, Xen cell, Xen func, Xen func_info, Xen dnotify) { #define H_gtk_tree_view_insert_column_with_data_func "gint gtk_tree_view_insert_column_with_data_func(GtkTreeView* tree_view, \ gint position, gchar* title, GtkCellRenderer* cell, GtkTreeCellDataFunc func, lambda_data func_info, \ GtkDestroyNotify dnotify)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_insert_column_with_data_func", "GtkTreeView*"); Xen_check_type(Xen_is_gint(position), position, 2, "gtk_tree_view_insert_column_with_data_func", "gint"); Xen_check_type(Xen_is_gchar_(title), title, 3, "gtk_tree_view_insert_column_with_data_func", "gchar*"); Xen_check_type(Xen_is_GtkCellRenderer_(cell), cell, 4, "gtk_tree_view_insert_column_with_data_func", "GtkCellRenderer*"); Xen_check_type(Xen_is_GtkTreeCellDataFunc(func), func, 5, "gtk_tree_view_insert_column_with_data_func", "GtkTreeCellDataFunc"); Xen_check_type(Xen_is_lambda_data(func_info), func_info, 6, "gtk_tree_view_insert_column_with_data_func", "lambda_data"); Xen_check_type(Xen_is_GtkDestroyNotify(dnotify), dnotify, 7, "gtk_tree_view_insert_column_with_data_func", "GtkDestroyNotify"); { Xen result; Xen gxg_ptr = Xen_list_5(func, func_info, Xen_false, Xen_false, Xen_false); xm_protect(gxg_ptr); Xen_list_set(gxg_ptr, 3, dnotify); result = C_to_Xen_gint(gtk_tree_view_insert_column_with_data_func(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_gint(position), Xen_to_C_gchar_(title), Xen_to_C_GtkCellRenderer_(cell), Xen_to_C_GtkTreeCellDataFunc(func), Xen_to_C_lambda_data(func_info), Xen_to_C_GtkDestroyNotify(dnotify))); return(result); } } static Xen gxg_gtk_tree_view_get_column(Xen tree_view, Xen n) { #define H_gtk_tree_view_get_column "GtkTreeViewColumn* gtk_tree_view_get_column(GtkTreeView* tree_view, \ gint n)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_get_column", "GtkTreeView*"); Xen_check_type(Xen_is_gint(n), n, 2, "gtk_tree_view_get_column", "gint"); return(C_to_Xen_GtkTreeViewColumn_(gtk_tree_view_get_column(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_gint(n)))); } static Xen gxg_gtk_tree_view_get_columns(Xen tree_view) { #define H_gtk_tree_view_get_columns "GList* gtk_tree_view_get_columns(GtkTreeView* tree_view)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_get_columns", "GtkTreeView*"); return(C_to_Xen_GList_(gtk_tree_view_get_columns(Xen_to_C_GtkTreeView_(tree_view)))); } static Xen gxg_gtk_tree_view_move_column_after(Xen tree_view, Xen column, Xen base_column) { #define H_gtk_tree_view_move_column_after "void gtk_tree_view_move_column_after(GtkTreeView* tree_view, \ GtkTreeViewColumn* column, GtkTreeViewColumn* base_column)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_move_column_after", "GtkTreeView*"); Xen_check_type(Xen_is_GtkTreeViewColumn_(column), column, 2, "gtk_tree_view_move_column_after", "GtkTreeViewColumn*"); Xen_check_type(Xen_is_GtkTreeViewColumn_(base_column) || Xen_is_false(base_column), base_column, 3, "gtk_tree_view_move_column_after", "GtkTreeViewColumn*"); gtk_tree_view_move_column_after(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_GtkTreeViewColumn_(column), Xen_to_C_GtkTreeViewColumn_(base_column)); return(Xen_false); } static Xen gxg_gtk_tree_view_set_expander_column(Xen tree_view, Xen column) { #define H_gtk_tree_view_set_expander_column "void gtk_tree_view_set_expander_column(GtkTreeView* tree_view, \ GtkTreeViewColumn* column)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_set_expander_column", "GtkTreeView*"); Xen_check_type(Xen_is_GtkTreeViewColumn_(column) || Xen_is_false(column), column, 2, "gtk_tree_view_set_expander_column", "GtkTreeViewColumn*"); gtk_tree_view_set_expander_column(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_GtkTreeViewColumn_(column)); return(Xen_false); } static Xen gxg_gtk_tree_view_get_expander_column(Xen tree_view) { #define H_gtk_tree_view_get_expander_column "GtkTreeViewColumn* gtk_tree_view_get_expander_column(GtkTreeView* tree_view)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_get_expander_column", "GtkTreeView*"); return(C_to_Xen_GtkTreeViewColumn_(gtk_tree_view_get_expander_column(Xen_to_C_GtkTreeView_(tree_view)))); } static Xen gxg_gtk_tree_view_set_column_drag_function(Xen tree_view, Xen func, Xen func_info, Xen destroy) { #define H_gtk_tree_view_set_column_drag_function "void gtk_tree_view_set_column_drag_function(GtkTreeView* tree_view, \ GtkTreeViewColumnDropFunc func, lambda_data func_info, GtkDestroyNotify destroy)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_set_column_drag_function", "GtkTreeView*"); Xen_check_type(Xen_is_GtkTreeViewColumnDropFunc(func), func, 2, "gtk_tree_view_set_column_drag_function", "GtkTreeViewColumnDropFunc"); Xen_check_type(Xen_is_lambda_data(func_info), func_info, 3, "gtk_tree_view_set_column_drag_function", "lambda_data"); Xen_check_type(Xen_is_GtkDestroyNotify(destroy), destroy, 4, "gtk_tree_view_set_column_drag_function", "GtkDestroyNotify"); { int loc; Xen gxg_ptr = Xen_list_5(func, func_info, Xen_false, Xen_false, Xen_false); loc = xm_protect(gxg_ptr); Xen_list_set(gxg_ptr, 2, C_int_to_Xen_integer(loc)); Xen_list_set(gxg_ptr, 3, destroy); gtk_tree_view_set_column_drag_function(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_GtkTreeViewColumnDropFunc(func), Xen_to_C_lambda_data(func_info), Xen_to_C_GtkDestroyNotify(destroy)); xm_unprotect_at(loc); return(Xen_false); } } static Xen gxg_gtk_tree_view_scroll_to_point(Xen tree_view, Xen tree_x, Xen tree_y) { #define H_gtk_tree_view_scroll_to_point "void gtk_tree_view_scroll_to_point(GtkTreeView* tree_view, \ gint tree_x, gint tree_y)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_scroll_to_point", "GtkTreeView*"); Xen_check_type(Xen_is_gint(tree_x), tree_x, 2, "gtk_tree_view_scroll_to_point", "gint"); Xen_check_type(Xen_is_gint(tree_y), tree_y, 3, "gtk_tree_view_scroll_to_point", "gint"); gtk_tree_view_scroll_to_point(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_gint(tree_x), Xen_to_C_gint(tree_y)); return(Xen_false); } static Xen gxg_gtk_tree_view_scroll_to_cell(Xen tree_view, Xen path, Xen column, Xen use_align, Xen row_align, Xen col_align) { #define H_gtk_tree_view_scroll_to_cell "void gtk_tree_view_scroll_to_cell(GtkTreeView* tree_view, GtkTreePath* path, \ GtkTreeViewColumn* column, gboolean use_align, gfloat row_align, gfloat col_align)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_scroll_to_cell", "GtkTreeView*"); Xen_check_type(Xen_is_GtkTreePath_(path) || Xen_is_false(path), path, 2, "gtk_tree_view_scroll_to_cell", "GtkTreePath*"); Xen_check_type(Xen_is_GtkTreeViewColumn_(column) || Xen_is_false(column), column, 3, "gtk_tree_view_scroll_to_cell", "GtkTreeViewColumn*"); Xen_check_type(Xen_is_gboolean(use_align), use_align, 4, "gtk_tree_view_scroll_to_cell", "gboolean"); Xen_check_type(Xen_is_gfloat(row_align), row_align, 5, "gtk_tree_view_scroll_to_cell", "gfloat"); Xen_check_type(Xen_is_gfloat(col_align), col_align, 6, "gtk_tree_view_scroll_to_cell", "gfloat"); gtk_tree_view_scroll_to_cell(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_GtkTreePath_(path), Xen_to_C_GtkTreeViewColumn_(column), Xen_to_C_gboolean(use_align), Xen_to_C_gfloat(row_align), Xen_to_C_gfloat(col_align)); return(Xen_false); } static Xen gxg_gtk_tree_view_row_activated(Xen tree_view, Xen path, Xen column) { #define H_gtk_tree_view_row_activated "void gtk_tree_view_row_activated(GtkTreeView* tree_view, GtkTreePath* path, \ GtkTreeViewColumn* column)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_row_activated", "GtkTreeView*"); Xen_check_type(Xen_is_GtkTreePath_(path), path, 2, "gtk_tree_view_row_activated", "GtkTreePath*"); Xen_check_type(Xen_is_GtkTreeViewColumn_(column), column, 3, "gtk_tree_view_row_activated", "GtkTreeViewColumn*"); gtk_tree_view_row_activated(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_GtkTreePath_(path), Xen_to_C_GtkTreeViewColumn_(column)); return(Xen_false); } static Xen gxg_gtk_tree_view_expand_all(Xen tree_view) { #define H_gtk_tree_view_expand_all "void gtk_tree_view_expand_all(GtkTreeView* tree_view)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_expand_all", "GtkTreeView*"); gtk_tree_view_expand_all(Xen_to_C_GtkTreeView_(tree_view)); return(Xen_false); } static Xen gxg_gtk_tree_view_collapse_all(Xen tree_view) { #define H_gtk_tree_view_collapse_all "void gtk_tree_view_collapse_all(GtkTreeView* tree_view)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_collapse_all", "GtkTreeView*"); gtk_tree_view_collapse_all(Xen_to_C_GtkTreeView_(tree_view)); return(Xen_false); } static Xen gxg_gtk_tree_view_expand_row(Xen tree_view, Xen path, Xen open_all) { #define H_gtk_tree_view_expand_row "gboolean gtk_tree_view_expand_row(GtkTreeView* tree_view, GtkTreePath* path, \ gboolean open_all)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_expand_row", "GtkTreeView*"); Xen_check_type(Xen_is_GtkTreePath_(path), path, 2, "gtk_tree_view_expand_row", "GtkTreePath*"); Xen_check_type(Xen_is_gboolean(open_all), open_all, 3, "gtk_tree_view_expand_row", "gboolean"); return(C_to_Xen_gboolean(gtk_tree_view_expand_row(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_GtkTreePath_(path), Xen_to_C_gboolean(open_all)))); } static Xen gxg_gtk_tree_view_collapse_row(Xen tree_view, Xen path) { #define H_gtk_tree_view_collapse_row "gboolean gtk_tree_view_collapse_row(GtkTreeView* tree_view, GtkTreePath* path)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_collapse_row", "GtkTreeView*"); Xen_check_type(Xen_is_GtkTreePath_(path), path, 2, "gtk_tree_view_collapse_row", "GtkTreePath*"); return(C_to_Xen_gboolean(gtk_tree_view_collapse_row(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_GtkTreePath_(path)))); } static Xen gxg_gtk_tree_view_map_expanded_rows(Xen tree_view, Xen func, Xen func_info) { #define H_gtk_tree_view_map_expanded_rows "void gtk_tree_view_map_expanded_rows(GtkTreeView* tree_view, \ GtkTreeViewMappingFunc func, lambda_data func_info)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_map_expanded_rows", "GtkTreeView*"); Xen_check_type(Xen_is_GtkTreeViewMappingFunc(func), func, 2, "gtk_tree_view_map_expanded_rows", "GtkTreeViewMappingFunc"); if (!Xen_is_bound(func_info)) func_info = Xen_false; else Xen_check_type(Xen_is_lambda_data(func_info), func_info, 3, "gtk_tree_view_map_expanded_rows", "lambda_data"); { int loc; Xen gxg_ptr = Xen_list_5(func, func_info, Xen_false, Xen_false, Xen_false); loc = xm_protect(gxg_ptr); Xen_list_set(gxg_ptr, 2, C_int_to_Xen_integer(loc)); gtk_tree_view_map_expanded_rows(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_GtkTreeViewMappingFunc(func), Xen_to_C_lambda_data(func_info)); xm_unprotect_at(loc); return(Xen_false); } } static Xen gxg_gtk_tree_view_row_expanded(Xen tree_view, Xen path) { #define H_gtk_tree_view_row_expanded "gboolean gtk_tree_view_row_expanded(GtkTreeView* tree_view, GtkTreePath* path)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_row_expanded", "GtkTreeView*"); Xen_check_type(Xen_is_GtkTreePath_(path), path, 2, "gtk_tree_view_row_expanded", "GtkTreePath*"); return(C_to_Xen_gboolean(gtk_tree_view_row_expanded(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_GtkTreePath_(path)))); } static Xen gxg_gtk_tree_view_set_reorderable(Xen tree_view, Xen reorderable) { #define H_gtk_tree_view_set_reorderable "void gtk_tree_view_set_reorderable(GtkTreeView* tree_view, \ gboolean reorderable)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_set_reorderable", "GtkTreeView*"); Xen_check_type(Xen_is_gboolean(reorderable), reorderable, 2, "gtk_tree_view_set_reorderable", "gboolean"); gtk_tree_view_set_reorderable(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_gboolean(reorderable)); return(Xen_false); } static Xen gxg_gtk_tree_view_get_reorderable(Xen tree_view) { #define H_gtk_tree_view_get_reorderable "gboolean gtk_tree_view_get_reorderable(GtkTreeView* tree_view)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_get_reorderable", "GtkTreeView*"); return(C_to_Xen_gboolean(gtk_tree_view_get_reorderable(Xen_to_C_GtkTreeView_(tree_view)))); } static Xen gxg_gtk_tree_view_set_cursor(Xen tree_view, Xen path, Xen focus_column, Xen start_editing) { #define H_gtk_tree_view_set_cursor "void gtk_tree_view_set_cursor(GtkTreeView* tree_view, GtkTreePath* path, \ GtkTreeViewColumn* focus_column, gboolean start_editing)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_set_cursor", "GtkTreeView*"); Xen_check_type(Xen_is_GtkTreePath_(path), path, 2, "gtk_tree_view_set_cursor", "GtkTreePath*"); Xen_check_type(Xen_is_GtkTreeViewColumn_(focus_column), focus_column, 3, "gtk_tree_view_set_cursor", "GtkTreeViewColumn*"); Xen_check_type(Xen_is_gboolean(start_editing), start_editing, 4, "gtk_tree_view_set_cursor", "gboolean"); gtk_tree_view_set_cursor(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_GtkTreePath_(path), Xen_to_C_GtkTreeViewColumn_(focus_column), Xen_to_C_gboolean(start_editing)); return(Xen_false); } static Xen gxg_gtk_tree_view_get_cursor(Xen tree_view, Xen ignore_path, Xen ignore_focus_column) { #define H_gtk_tree_view_get_cursor "void gtk_tree_view_get_cursor(GtkTreeView* tree_view, GtkTreePath** [path], \ GtkTreeViewColumn** [focus_column])" GtkTreePath* ref_path = NULL; GtkTreeViewColumn* ref_focus_column = NULL; Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_get_cursor", "GtkTreeView*"); gtk_tree_view_get_cursor(Xen_to_C_GtkTreeView_(tree_view), &ref_path, &ref_focus_column); return(Xen_list_2(C_to_Xen_GtkTreePath_(ref_path), C_to_Xen_GtkTreeViewColumn_(ref_focus_column))); } static Xen gxg_gtk_tree_view_get_bin_window(Xen tree_view) { #define H_gtk_tree_view_get_bin_window "GdkWindow* gtk_tree_view_get_bin_window(GtkTreeView* tree_view)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_get_bin_window", "GtkTreeView*"); return(C_to_Xen_GdkWindow_(gtk_tree_view_get_bin_window(Xen_to_C_GtkTreeView_(tree_view)))); } static Xen gxg_gtk_tree_view_get_path_at_pos(Xen tree_view, Xen x, Xen y, Xen ignore_path, Xen ignore_column, Xen ignore_cell_x, Xen ignore_cell_y) { #define H_gtk_tree_view_get_path_at_pos "gboolean gtk_tree_view_get_path_at_pos(GtkTreeView* tree_view, \ gint x, gint y, GtkTreePath** [path], GtkTreeViewColumn** [column], gint* [cell_x], gint* [cell_y])" GtkTreePath* ref_path = NULL; GtkTreeViewColumn* ref_column = NULL; gint ref_cell_x; gint ref_cell_y; Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_get_path_at_pos", "GtkTreeView*"); Xen_check_type(Xen_is_gint(x), x, 2, "gtk_tree_view_get_path_at_pos", "gint"); Xen_check_type(Xen_is_gint(y), y, 3, "gtk_tree_view_get_path_at_pos", "gint"); { Xen result; result = C_to_Xen_gboolean(gtk_tree_view_get_path_at_pos(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_gint(x), Xen_to_C_gint(y), &ref_path, &ref_column, &ref_cell_x, &ref_cell_y)); return(Xen_list_5(result, C_to_Xen_GtkTreePath_(ref_path), C_to_Xen_GtkTreeViewColumn_(ref_column), C_to_Xen_gint(ref_cell_x), C_to_Xen_gint(ref_cell_y))); } } static Xen gxg_gtk_tree_view_get_cell_area(Xen tree_view, Xen path, Xen column, Xen rect) { #define H_gtk_tree_view_get_cell_area "void gtk_tree_view_get_cell_area(GtkTreeView* tree_view, GtkTreePath* path, \ GtkTreeViewColumn* column, GdkRectangle* rect)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_get_cell_area", "GtkTreeView*"); Xen_check_type(Xen_is_GtkTreePath_(path) || Xen_is_false(path), path, 2, "gtk_tree_view_get_cell_area", "GtkTreePath*"); Xen_check_type(Xen_is_GtkTreeViewColumn_(column) || Xen_is_false(column), column, 3, "gtk_tree_view_get_cell_area", "GtkTreeViewColumn*"); Xen_check_type(Xen_is_GdkRectangle_(rect), rect, 4, "gtk_tree_view_get_cell_area", "GdkRectangle*"); gtk_tree_view_get_cell_area(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_GtkTreePath_(path), Xen_to_C_GtkTreeViewColumn_(column), Xen_to_C_GdkRectangle_(rect)); return(Xen_false); } static Xen gxg_gtk_tree_view_get_background_area(Xen tree_view, Xen path, Xen column, Xen rect) { #define H_gtk_tree_view_get_background_area "void gtk_tree_view_get_background_area(GtkTreeView* tree_view, \ GtkTreePath* path, GtkTreeViewColumn* column, GdkRectangle* rect)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_get_background_area", "GtkTreeView*"); Xen_check_type(Xen_is_GtkTreePath_(path) || Xen_is_false(path), path, 2, "gtk_tree_view_get_background_area", "GtkTreePath*"); Xen_check_type(Xen_is_GtkTreeViewColumn_(column) || Xen_is_false(column), column, 3, "gtk_tree_view_get_background_area", "GtkTreeViewColumn*"); Xen_check_type(Xen_is_GdkRectangle_(rect), rect, 4, "gtk_tree_view_get_background_area", "GdkRectangle*"); gtk_tree_view_get_background_area(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_GtkTreePath_(path), Xen_to_C_GtkTreeViewColumn_(column), Xen_to_C_GdkRectangle_(rect)); return(Xen_false); } static Xen gxg_gtk_tree_view_get_visible_rect(Xen tree_view, Xen visible_rect) { #define H_gtk_tree_view_get_visible_rect "void gtk_tree_view_get_visible_rect(GtkTreeView* tree_view, \ GdkRectangle* visible_rect)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_get_visible_rect", "GtkTreeView*"); Xen_check_type(Xen_is_GdkRectangle_(visible_rect), visible_rect, 2, "gtk_tree_view_get_visible_rect", "GdkRectangle*"); gtk_tree_view_get_visible_rect(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_GdkRectangle_(visible_rect)); return(Xen_false); } static Xen gxg_gtk_tree_view_enable_model_drag_source(Xen tree_view, Xen start_button_mask, Xen targets, Xen n_targets, Xen actions) { #define H_gtk_tree_view_enable_model_drag_source "void gtk_tree_view_enable_model_drag_source(GtkTreeView* tree_view, \ GdkModifierType start_button_mask, GtkTargetEntry* targets, gint n_targets, GdkDragAction actions)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_enable_model_drag_source", "GtkTreeView*"); Xen_check_type(Xen_is_GdkModifierType(start_button_mask), start_button_mask, 2, "gtk_tree_view_enable_model_drag_source", "GdkModifierType"); Xen_check_type(Xen_is_GtkTargetEntry_(targets), targets, 3, "gtk_tree_view_enable_model_drag_source", "GtkTargetEntry*"); Xen_check_type(Xen_is_gint(n_targets), n_targets, 4, "gtk_tree_view_enable_model_drag_source", "gint"); Xen_check_type(Xen_is_GdkDragAction(actions), actions, 5, "gtk_tree_view_enable_model_drag_source", "GdkDragAction"); gtk_tree_view_enable_model_drag_source(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_GdkModifierType(start_button_mask), Xen_to_C_GtkTargetEntry_(targets), Xen_to_C_gint(n_targets), Xen_to_C_GdkDragAction(actions)); return(Xen_false); } static Xen gxg_gtk_tree_view_enable_model_drag_dest(Xen tree_view, Xen targets, Xen n_targets, Xen actions) { #define H_gtk_tree_view_enable_model_drag_dest "void gtk_tree_view_enable_model_drag_dest(GtkTreeView* tree_view, \ GtkTargetEntry* targets, gint n_targets, GdkDragAction actions)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_enable_model_drag_dest", "GtkTreeView*"); Xen_check_type(Xen_is_GtkTargetEntry_(targets), targets, 2, "gtk_tree_view_enable_model_drag_dest", "GtkTargetEntry*"); Xen_check_type(Xen_is_gint(n_targets), n_targets, 3, "gtk_tree_view_enable_model_drag_dest", "gint"); Xen_check_type(Xen_is_GdkDragAction(actions), actions, 4, "gtk_tree_view_enable_model_drag_dest", "GdkDragAction"); gtk_tree_view_enable_model_drag_dest(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_GtkTargetEntry_(targets), Xen_to_C_gint(n_targets), Xen_to_C_GdkDragAction(actions)); return(Xen_false); } static Xen gxg_gtk_tree_view_unset_rows_drag_source(Xen tree_view) { #define H_gtk_tree_view_unset_rows_drag_source "void gtk_tree_view_unset_rows_drag_source(GtkTreeView* tree_view)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_unset_rows_drag_source", "GtkTreeView*"); gtk_tree_view_unset_rows_drag_source(Xen_to_C_GtkTreeView_(tree_view)); return(Xen_false); } static Xen gxg_gtk_tree_view_unset_rows_drag_dest(Xen tree_view) { #define H_gtk_tree_view_unset_rows_drag_dest "void gtk_tree_view_unset_rows_drag_dest(GtkTreeView* tree_view)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_unset_rows_drag_dest", "GtkTreeView*"); gtk_tree_view_unset_rows_drag_dest(Xen_to_C_GtkTreeView_(tree_view)); return(Xen_false); } static Xen gxg_gtk_tree_view_set_drag_dest_row(Xen tree_view, Xen path, Xen pos) { #define H_gtk_tree_view_set_drag_dest_row "void gtk_tree_view_set_drag_dest_row(GtkTreeView* tree_view, \ GtkTreePath* path, GtkTreeViewDropPosition pos)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_set_drag_dest_row", "GtkTreeView*"); Xen_check_type(Xen_is_GtkTreePath_(path), path, 2, "gtk_tree_view_set_drag_dest_row", "GtkTreePath*"); Xen_check_type(Xen_is_GtkTreeViewDropPosition(pos), pos, 3, "gtk_tree_view_set_drag_dest_row", "GtkTreeViewDropPosition"); gtk_tree_view_set_drag_dest_row(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_GtkTreePath_(path), Xen_to_C_GtkTreeViewDropPosition(pos)); return(Xen_false); } static Xen gxg_gtk_tree_view_get_drag_dest_row(Xen tree_view, Xen ignore_path, Xen ignore_pos) { #define H_gtk_tree_view_get_drag_dest_row "void gtk_tree_view_get_drag_dest_row(GtkTreeView* tree_view, \ GtkTreePath** [path], GtkTreeViewDropPosition* [pos])" GtkTreePath* ref_path = NULL; GtkTreeViewDropPosition ref_pos; Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_get_drag_dest_row", "GtkTreeView*"); gtk_tree_view_get_drag_dest_row(Xen_to_C_GtkTreeView_(tree_view), &ref_path, &ref_pos); return(Xen_list_2(C_to_Xen_GtkTreePath_(ref_path), C_to_Xen_GtkTreeViewDropPosition(ref_pos))); } static Xen gxg_gtk_tree_view_get_dest_row_at_pos(Xen tree_view, Xen drag_x, Xen drag_y, Xen ignore_path, Xen ignore_pos) { #define H_gtk_tree_view_get_dest_row_at_pos "gboolean gtk_tree_view_get_dest_row_at_pos(GtkTreeView* tree_view, \ gint drag_x, gint drag_y, GtkTreePath** [path], GtkTreeViewDropPosition* [pos])" GtkTreePath* ref_path = NULL; GtkTreeViewDropPosition ref_pos; Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_get_dest_row_at_pos", "GtkTreeView*"); Xen_check_type(Xen_is_gint(drag_x), drag_x, 2, "gtk_tree_view_get_dest_row_at_pos", "gint"); Xen_check_type(Xen_is_gint(drag_y), drag_y, 3, "gtk_tree_view_get_dest_row_at_pos", "gint"); { Xen result; result = C_to_Xen_gboolean(gtk_tree_view_get_dest_row_at_pos(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_gint(drag_x), Xen_to_C_gint(drag_y), &ref_path, &ref_pos)); return(Xen_list_3(result, C_to_Xen_GtkTreePath_(ref_path), C_to_Xen_GtkTreeViewDropPosition(ref_pos))); } } static Xen gxg_gtk_tree_view_set_enable_search(Xen tree_view, Xen enable_search) { #define H_gtk_tree_view_set_enable_search "void gtk_tree_view_set_enable_search(GtkTreeView* tree_view, \ gboolean enable_search)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_set_enable_search", "GtkTreeView*"); Xen_check_type(Xen_is_gboolean(enable_search), enable_search, 2, "gtk_tree_view_set_enable_search", "gboolean"); gtk_tree_view_set_enable_search(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_gboolean(enable_search)); return(Xen_false); } static Xen gxg_gtk_tree_view_get_enable_search(Xen tree_view) { #define H_gtk_tree_view_get_enable_search "gboolean gtk_tree_view_get_enable_search(GtkTreeView* tree_view)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_get_enable_search", "GtkTreeView*"); return(C_to_Xen_gboolean(gtk_tree_view_get_enable_search(Xen_to_C_GtkTreeView_(tree_view)))); } static Xen gxg_gtk_tree_view_get_search_column(Xen tree_view) { #define H_gtk_tree_view_get_search_column "gint gtk_tree_view_get_search_column(GtkTreeView* tree_view)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_get_search_column", "GtkTreeView*"); return(C_to_Xen_gint(gtk_tree_view_get_search_column(Xen_to_C_GtkTreeView_(tree_view)))); } static Xen gxg_gtk_tree_view_set_search_column(Xen tree_view, Xen column) { #define H_gtk_tree_view_set_search_column "void gtk_tree_view_set_search_column(GtkTreeView* tree_view, \ gint column)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_set_search_column", "GtkTreeView*"); Xen_check_type(Xen_is_gint(column), column, 2, "gtk_tree_view_set_search_column", "gint"); gtk_tree_view_set_search_column(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_gint(column)); return(Xen_false); } static Xen gxg_gtk_tree_view_get_search_equal_func(Xen tree_view) { #define H_gtk_tree_view_get_search_equal_func "GtkTreeViewSearchEqualFunc gtk_tree_view_get_search_equal_func(GtkTreeView* tree_view)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_get_search_equal_func", "GtkTreeView*"); return(C_to_Xen_GtkTreeViewSearchEqualFunc(gtk_tree_view_get_search_equal_func(Xen_to_C_GtkTreeView_(tree_view)))); } static Xen gxg_gtk_tree_view_set_search_equal_func(Xen tree_view, Xen func, Xen func_info, Xen search_destroy) { #define H_gtk_tree_view_set_search_equal_func "void gtk_tree_view_set_search_equal_func(GtkTreeView* tree_view, \ GtkTreeViewSearchEqualFunc func, lambda_data func_info, GtkDestroyNotify search_destroy)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_set_search_equal_func", "GtkTreeView*"); Xen_check_type(Xen_is_GtkTreeViewSearchEqualFunc(func), func, 2, "gtk_tree_view_set_search_equal_func", "GtkTreeViewSearchEqualFunc"); Xen_check_type(Xen_is_lambda_data(func_info), func_info, 3, "gtk_tree_view_set_search_equal_func", "lambda_data"); Xen_check_type(Xen_is_GtkDestroyNotify(search_destroy), search_destroy, 4, "gtk_tree_view_set_search_equal_func", "GtkDestroyNotify"); { int loc; Xen gxg_ptr = Xen_list_5(func, func_info, Xen_false, Xen_false, Xen_false); loc = xm_protect(gxg_ptr); Xen_list_set(gxg_ptr, 2, C_int_to_Xen_integer(loc)); Xen_list_set(gxg_ptr, 3, search_destroy); gtk_tree_view_set_search_equal_func(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_GtkTreeViewSearchEqualFunc(func), Xen_to_C_lambda_data(func_info), Xen_to_C_GtkDestroyNotify(search_destroy)); xm_unprotect_at(loc); return(Xen_false); } } static Xen gxg_gtk_viewport_new(Xen hadjustment, Xen vadjustment) { #define H_gtk_viewport_new "GtkWidget* gtk_viewport_new(GtkAdjustment* hadjustment, GtkAdjustment* vadjustment)" Xen_check_type(Xen_is_GtkAdjustment_(hadjustment) || Xen_is_false(hadjustment), hadjustment, 1, "gtk_viewport_new", "GtkAdjustment*"); Xen_check_type(Xen_is_GtkAdjustment_(vadjustment) || Xen_is_false(vadjustment), vadjustment, 2, "gtk_viewport_new", "GtkAdjustment*"); return(C_to_Xen_GtkWidget_(gtk_viewport_new(Xen_to_C_GtkAdjustment_(hadjustment), Xen_to_C_GtkAdjustment_(vadjustment)))); } static Xen gxg_gtk_viewport_set_shadow_type(Xen viewport, Xen type) { #define H_gtk_viewport_set_shadow_type "void gtk_viewport_set_shadow_type(GtkViewport* viewport, GtkShadowType type)" Xen_check_type(Xen_is_GtkViewport_(viewport), viewport, 1, "gtk_viewport_set_shadow_type", "GtkViewport*"); Xen_check_type(Xen_is_GtkShadowType(type), type, 2, "gtk_viewport_set_shadow_type", "GtkShadowType"); gtk_viewport_set_shadow_type(Xen_to_C_GtkViewport_(viewport), Xen_to_C_GtkShadowType(type)); return(Xen_false); } static Xen gxg_gtk_viewport_get_shadow_type(Xen viewport) { #define H_gtk_viewport_get_shadow_type "GtkShadowType gtk_viewport_get_shadow_type(GtkViewport* viewport)" Xen_check_type(Xen_is_GtkViewport_(viewport), viewport, 1, "gtk_viewport_get_shadow_type", "GtkViewport*"); return(C_to_Xen_GtkShadowType(gtk_viewport_get_shadow_type(Xen_to_C_GtkViewport_(viewport)))); } static Xen gxg_gtk_widget_destroy(Xen widget) { #define H_gtk_widget_destroy "void gtk_widget_destroy(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_destroy", "GtkWidget*"); gtk_widget_destroy(Xen_to_C_GtkWidget_(widget)); return(Xen_false); } static Xen gxg_gtk_widget_destroyed(Xen widget, Xen ignore_widget_pointer) { #define H_gtk_widget_destroyed "void gtk_widget_destroyed(GtkWidget* widget, GtkWidget** [widget_pointer])" GtkWidget* ref_widget_pointer = NULL; Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_destroyed", "GtkWidget*"); gtk_widget_destroyed(Xen_to_C_GtkWidget_(widget), &ref_widget_pointer); return(Xen_list_1(C_to_Xen_GtkWidget_(ref_widget_pointer))); } static Xen gxg_gtk_widget_unparent(Xen widget) { #define H_gtk_widget_unparent "void gtk_widget_unparent(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_unparent", "GtkWidget*"); gtk_widget_unparent(Xen_to_C_GtkWidget_(widget)); return(Xen_false); } static Xen gxg_gtk_widget_show(Xen widget) { #define H_gtk_widget_show "void gtk_widget_show(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_show", "GtkWidget*"); gtk_widget_show(Xen_to_C_GtkWidget_(widget)); return(Xen_false); } static Xen gxg_gtk_widget_show_now(Xen widget) { #define H_gtk_widget_show_now "void gtk_widget_show_now(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_show_now", "GtkWidget*"); gtk_widget_show_now(Xen_to_C_GtkWidget_(widget)); return(Xen_false); } static Xen gxg_gtk_widget_hide(Xen widget) { #define H_gtk_widget_hide "void gtk_widget_hide(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_hide", "GtkWidget*"); gtk_widget_hide(Xen_to_C_GtkWidget_(widget)); return(Xen_false); } static Xen gxg_gtk_widget_show_all(Xen widget) { #define H_gtk_widget_show_all "void gtk_widget_show_all(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_show_all", "GtkWidget*"); gtk_widget_show_all(Xen_to_C_GtkWidget_(widget)); return(Xen_false); } static Xen gxg_gtk_widget_map(Xen widget) { #define H_gtk_widget_map "void gtk_widget_map(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_map", "GtkWidget*"); gtk_widget_map(Xen_to_C_GtkWidget_(widget)); return(Xen_false); } static Xen gxg_gtk_widget_unmap(Xen widget) { #define H_gtk_widget_unmap "void gtk_widget_unmap(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_unmap", "GtkWidget*"); gtk_widget_unmap(Xen_to_C_GtkWidget_(widget)); return(Xen_false); } static Xen gxg_gtk_widget_realize(Xen widget) { #define H_gtk_widget_realize "void gtk_widget_realize(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_realize", "GtkWidget*"); gtk_widget_realize(Xen_to_C_GtkWidget_(widget)); return(Xen_false); } static Xen gxg_gtk_widget_unrealize(Xen widget) { #define H_gtk_widget_unrealize "void gtk_widget_unrealize(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_unrealize", "GtkWidget*"); gtk_widget_unrealize(Xen_to_C_GtkWidget_(widget)); return(Xen_false); } static Xen gxg_gtk_widget_queue_draw(Xen widget) { #define H_gtk_widget_queue_draw "void gtk_widget_queue_draw(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_queue_draw", "GtkWidget*"); gtk_widget_queue_draw(Xen_to_C_GtkWidget_(widget)); return(Xen_false); } static Xen gxg_gtk_widget_queue_draw_area(Xen widget, Xen x, Xen y, Xen width, Xen height) { #define H_gtk_widget_queue_draw_area "void gtk_widget_queue_draw_area(GtkWidget* widget, gint x, gint y, \ gint width, gint height)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_queue_draw_area", "GtkWidget*"); Xen_check_type(Xen_is_gint(x), x, 2, "gtk_widget_queue_draw_area", "gint"); Xen_check_type(Xen_is_gint(y), y, 3, "gtk_widget_queue_draw_area", "gint"); Xen_check_type(Xen_is_gint(width), width, 4, "gtk_widget_queue_draw_area", "gint"); Xen_check_type(Xen_is_gint(height), height, 5, "gtk_widget_queue_draw_area", "gint"); gtk_widget_queue_draw_area(Xen_to_C_GtkWidget_(widget), Xen_to_C_gint(x), Xen_to_C_gint(y), Xen_to_C_gint(width), Xen_to_C_gint(height)); return(Xen_false); } static Xen gxg_gtk_widget_queue_resize(Xen widget) { #define H_gtk_widget_queue_resize "void gtk_widget_queue_resize(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_queue_resize", "GtkWidget*"); gtk_widget_queue_resize(Xen_to_C_GtkWidget_(widget)); return(Xen_false); } static Xen gxg_gtk_widget_size_allocate(Xen widget, Xen allocation) { #define H_gtk_widget_size_allocate "void gtk_widget_size_allocate(GtkWidget* widget, GtkAllocation* allocation)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_size_allocate", "GtkWidget*"); Xen_check_type(Xen_is_GtkAllocation_(allocation), allocation, 2, "gtk_widget_size_allocate", "GtkAllocation*"); gtk_widget_size_allocate(Xen_to_C_GtkWidget_(widget), Xen_to_C_GtkAllocation_(allocation)); return(Xen_false); } static Xen gxg_gtk_widget_add_accelerator(Xen widget, Xen accel_signal, Xen accel_group, Xen accel_key, Xen accel_mods, Xen accel_flags) { #define H_gtk_widget_add_accelerator "void gtk_widget_add_accelerator(GtkWidget* widget, gchar* accel_signal, \ GtkAccelGroup* accel_group, guint accel_key, GdkModifierType accel_mods, GtkAccelFlags accel_flags)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_add_accelerator", "GtkWidget*"); Xen_check_type(Xen_is_gchar_(accel_signal), accel_signal, 2, "gtk_widget_add_accelerator", "gchar*"); Xen_check_type(Xen_is_GtkAccelGroup_(accel_group), accel_group, 3, "gtk_widget_add_accelerator", "GtkAccelGroup*"); Xen_check_type(Xen_is_guint(accel_key), accel_key, 4, "gtk_widget_add_accelerator", "guint"); Xen_check_type(Xen_is_GdkModifierType(accel_mods), accel_mods, 5, "gtk_widget_add_accelerator", "GdkModifierType"); Xen_check_type(Xen_is_GtkAccelFlags(accel_flags), accel_flags, 6, "gtk_widget_add_accelerator", "GtkAccelFlags"); gtk_widget_add_accelerator(Xen_to_C_GtkWidget_(widget), Xen_to_C_gchar_(accel_signal), Xen_to_C_GtkAccelGroup_(accel_group), Xen_to_C_guint(accel_key), Xen_to_C_GdkModifierType(accel_mods), Xen_to_C_GtkAccelFlags(accel_flags)); return(Xen_false); } static Xen gxg_gtk_widget_remove_accelerator(Xen widget, Xen accel_group, Xen accel_key, Xen accel_mods) { #define H_gtk_widget_remove_accelerator "gboolean gtk_widget_remove_accelerator(GtkWidget* widget, \ GtkAccelGroup* accel_group, guint accel_key, GdkModifierType accel_mods)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_remove_accelerator", "GtkWidget*"); Xen_check_type(Xen_is_GtkAccelGroup_(accel_group), accel_group, 2, "gtk_widget_remove_accelerator", "GtkAccelGroup*"); Xen_check_type(Xen_is_guint(accel_key), accel_key, 3, "gtk_widget_remove_accelerator", "guint"); Xen_check_type(Xen_is_GdkModifierType(accel_mods), accel_mods, 4, "gtk_widget_remove_accelerator", "GdkModifierType"); return(C_to_Xen_gboolean(gtk_widget_remove_accelerator(Xen_to_C_GtkWidget_(widget), Xen_to_C_GtkAccelGroup_(accel_group), Xen_to_C_guint(accel_key), Xen_to_C_GdkModifierType(accel_mods)))); } static Xen gxg_gtk_widget_list_accel_closures(Xen widget) { #define H_gtk_widget_list_accel_closures "GList* gtk_widget_list_accel_closures(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_list_accel_closures", "GtkWidget*"); return(C_to_Xen_GList_(gtk_widget_list_accel_closures(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_mnemonic_activate(Xen widget, Xen group_cycling) { #define H_gtk_widget_mnemonic_activate "gboolean gtk_widget_mnemonic_activate(GtkWidget* widget, gboolean group_cycling)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_mnemonic_activate", "GtkWidget*"); Xen_check_type(Xen_is_gboolean(group_cycling), group_cycling, 2, "gtk_widget_mnemonic_activate", "gboolean"); return(C_to_Xen_gboolean(gtk_widget_mnemonic_activate(Xen_to_C_GtkWidget_(widget), Xen_to_C_gboolean(group_cycling)))); } static Xen gxg_gtk_widget_event(Xen widget, Xen event) { #define H_gtk_widget_event "gboolean gtk_widget_event(GtkWidget* widget, GdkEvent* event)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_event", "GtkWidget*"); Xen_check_type(Xen_is_GdkEvent_(event), event, 2, "gtk_widget_event", "GdkEvent*"); return(C_to_Xen_gboolean(gtk_widget_event(Xen_to_C_GtkWidget_(widget), Xen_to_C_GdkEvent_(event)))); } static Xen gxg_gtk_widget_send_expose(Xen widget, Xen event) { #define H_gtk_widget_send_expose "gint gtk_widget_send_expose(GtkWidget* widget, GdkEvent* event)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_send_expose", "GtkWidget*"); Xen_check_type(Xen_is_GdkEvent_(event), event, 2, "gtk_widget_send_expose", "GdkEvent*"); return(C_to_Xen_gint(gtk_widget_send_expose(Xen_to_C_GtkWidget_(widget), Xen_to_C_GdkEvent_(event)))); } static Xen gxg_gtk_widget_activate(Xen widget) { #define H_gtk_widget_activate "gboolean gtk_widget_activate(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_activate", "GtkWidget*"); return(C_to_Xen_gboolean(gtk_widget_activate(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_intersect(Xen widget, Xen area, Xen intersection) { #define H_gtk_widget_intersect "gboolean gtk_widget_intersect(GtkWidget* widget, GdkRectangle* area, \ GdkRectangle* intersection)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_intersect", "GtkWidget*"); Xen_check_type(Xen_is_GdkRectangle_(area), area, 2, "gtk_widget_intersect", "GdkRectangle*"); Xen_check_type(Xen_is_GdkRectangle_(intersection) || Xen_is_false(intersection), intersection, 3, "gtk_widget_intersect", "GdkRectangle*"); return(C_to_Xen_gboolean(gtk_widget_intersect(Xen_to_C_GtkWidget_(widget), Xen_to_C_GdkRectangle_(area), Xen_to_C_GdkRectangle_(intersection)))); } static Xen gxg_gtk_widget_freeze_child_notify(Xen widget) { #define H_gtk_widget_freeze_child_notify "void gtk_widget_freeze_child_notify(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_freeze_child_notify", "GtkWidget*"); gtk_widget_freeze_child_notify(Xen_to_C_GtkWidget_(widget)); return(Xen_false); } static Xen gxg_gtk_widget_child_notify(Xen widget, Xen child_property) { #define H_gtk_widget_child_notify "void gtk_widget_child_notify(GtkWidget* widget, gchar* child_property)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_child_notify", "GtkWidget*"); Xen_check_type(Xen_is_gchar_(child_property), child_property, 2, "gtk_widget_child_notify", "gchar*"); gtk_widget_child_notify(Xen_to_C_GtkWidget_(widget), Xen_to_C_gchar_(child_property)); return(Xen_false); } static Xen gxg_gtk_widget_thaw_child_notify(Xen widget) { #define H_gtk_widget_thaw_child_notify "void gtk_widget_thaw_child_notify(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_thaw_child_notify", "GtkWidget*"); gtk_widget_thaw_child_notify(Xen_to_C_GtkWidget_(widget)); return(Xen_false); } static Xen gxg_gtk_widget_is_focus(Xen widget) { #define H_gtk_widget_is_focus "gboolean gtk_widget_is_focus(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_is_focus", "GtkWidget*"); return(C_to_Xen_gboolean(gtk_widget_is_focus(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_grab_focus(Xen widget) { #define H_gtk_widget_grab_focus "void gtk_widget_grab_focus(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_grab_focus", "GtkWidget*"); gtk_widget_grab_focus(Xen_to_C_GtkWidget_(widget)); return(Xen_false); } static Xen gxg_gtk_widget_grab_default(Xen widget) { #define H_gtk_widget_grab_default "void gtk_widget_grab_default(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_grab_default", "GtkWidget*"); gtk_widget_grab_default(Xen_to_C_GtkWidget_(widget)); return(Xen_false); } static Xen gxg_gtk_widget_set_name(Xen widget, Xen name) { #define H_gtk_widget_set_name "void gtk_widget_set_name(GtkWidget* widget, gchar* name)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_set_name", "GtkWidget*"); Xen_check_type(Xen_is_gchar_(name), name, 2, "gtk_widget_set_name", "gchar*"); gtk_widget_set_name(Xen_to_C_GtkWidget_(widget), Xen_to_C_gchar_(name)); return(Xen_false); } static Xen gxg_gtk_widget_get_name(Xen widget) { #define H_gtk_widget_get_name "gchar* gtk_widget_get_name(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_name", "GtkWidget*"); return(C_to_Xen_gchar_(gtk_widget_get_name(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_set_sensitive(Xen widget, Xen sensitive) { #define H_gtk_widget_set_sensitive "void gtk_widget_set_sensitive(GtkWidget* widget, gboolean sensitive)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_set_sensitive", "GtkWidget*"); Xen_check_type(Xen_is_gboolean(sensitive), sensitive, 2, "gtk_widget_set_sensitive", "gboolean"); gtk_widget_set_sensitive(Xen_to_C_GtkWidget_(widget), Xen_to_C_gboolean(sensitive)); return(Xen_false); } static Xen gxg_gtk_widget_set_app_paintable(Xen widget, Xen app_paintable) { #define H_gtk_widget_set_app_paintable "void gtk_widget_set_app_paintable(GtkWidget* widget, gboolean app_paintable)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_set_app_paintable", "GtkWidget*"); Xen_check_type(Xen_is_gboolean(app_paintable), app_paintable, 2, "gtk_widget_set_app_paintable", "gboolean"); gtk_widget_set_app_paintable(Xen_to_C_GtkWidget_(widget), Xen_to_C_gboolean(app_paintable)); return(Xen_false); } static Xen gxg_gtk_widget_set_redraw_on_allocate(Xen widget, Xen redraw_on_allocate) { #define H_gtk_widget_set_redraw_on_allocate "void gtk_widget_set_redraw_on_allocate(GtkWidget* widget, \ gboolean redraw_on_allocate)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_set_redraw_on_allocate", "GtkWidget*"); Xen_check_type(Xen_is_gboolean(redraw_on_allocate), redraw_on_allocate, 2, "gtk_widget_set_redraw_on_allocate", "gboolean"); gtk_widget_set_redraw_on_allocate(Xen_to_C_GtkWidget_(widget), Xen_to_C_gboolean(redraw_on_allocate)); return(Xen_false); } static Xen gxg_gtk_widget_set_parent(Xen widget, Xen parent) { #define H_gtk_widget_set_parent "void gtk_widget_set_parent(GtkWidget* widget, GtkWidget* parent)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_set_parent", "GtkWidget*"); Xen_check_type(Xen_is_GtkWidget_(parent), parent, 2, "gtk_widget_set_parent", "GtkWidget*"); gtk_widget_set_parent(Xen_to_C_GtkWidget_(widget), Xen_to_C_GtkWidget_(parent)); return(Xen_false); } static Xen gxg_gtk_widget_set_parent_window(Xen widget, Xen parent_window) { #define H_gtk_widget_set_parent_window "void gtk_widget_set_parent_window(GtkWidget* widget, GdkWindow* parent_window)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_set_parent_window", "GtkWidget*"); Xen_check_type(Xen_is_GdkWindow_(parent_window), parent_window, 2, "gtk_widget_set_parent_window", "GdkWindow*"); gtk_widget_set_parent_window(Xen_to_C_GtkWidget_(widget), Xen_to_C_GdkWindow_(parent_window)); return(Xen_false); } static Xen gxg_gtk_widget_set_child_visible(Xen widget, Xen is_visible) { #define H_gtk_widget_set_child_visible "void gtk_widget_set_child_visible(GtkWidget* widget, gboolean is_visible)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_set_child_visible", "GtkWidget*"); Xen_check_type(Xen_is_gboolean(is_visible), is_visible, 2, "gtk_widget_set_child_visible", "gboolean"); gtk_widget_set_child_visible(Xen_to_C_GtkWidget_(widget), Xen_to_C_gboolean(is_visible)); return(Xen_false); } static Xen gxg_gtk_widget_set_accel_path(Xen widget, Xen accel_path, Xen accel_group) { #define H_gtk_widget_set_accel_path "void gtk_widget_set_accel_path(GtkWidget* widget, gchar* accel_path, \ GtkAccelGroup* accel_group)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_set_accel_path", "GtkWidget*"); Xen_check_type(Xen_is_gchar_(accel_path), accel_path, 2, "gtk_widget_set_accel_path", "gchar*"); Xen_check_type(Xen_is_GtkAccelGroup_(accel_group), accel_group, 3, "gtk_widget_set_accel_path", "GtkAccelGroup*"); gtk_widget_set_accel_path(Xen_to_C_GtkWidget_(widget), Xen_to_C_gchar_(accel_path), Xen_to_C_GtkAccelGroup_(accel_group)); return(Xen_false); } static Xen gxg_gtk_widget_get_child_visible(Xen widget) { #define H_gtk_widget_get_child_visible "gboolean gtk_widget_get_child_visible(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_child_visible", "GtkWidget*"); return(C_to_Xen_gboolean(gtk_widget_get_child_visible(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_get_parent(Xen widget) { #define H_gtk_widget_get_parent "GtkWidget* gtk_widget_get_parent(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_parent", "GtkWidget*"); return(C_to_Xen_GtkWidget_(gtk_widget_get_parent(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_get_parent_window(Xen widget) { #define H_gtk_widget_get_parent_window "GdkWindow* gtk_widget_get_parent_window(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_parent_window", "GtkWidget*"); return(C_to_Xen_GdkWindow_(gtk_widget_get_parent_window(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_child_focus(Xen widget, Xen direction) { #define H_gtk_widget_child_focus "gboolean gtk_widget_child_focus(GtkWidget* widget, GtkDirectionType direction)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_child_focus", "GtkWidget*"); Xen_check_type(Xen_is_GtkDirectionType(direction), direction, 2, "gtk_widget_child_focus", "GtkDirectionType"); return(C_to_Xen_gboolean(gtk_widget_child_focus(Xen_to_C_GtkWidget_(widget), Xen_to_C_GtkDirectionType(direction)))); } static Xen gxg_gtk_widget_set_size_request(Xen widget, Xen width, Xen height) { #define H_gtk_widget_set_size_request "void gtk_widget_set_size_request(GtkWidget* widget, gint width, \ gint height)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_set_size_request", "GtkWidget*"); Xen_check_type(Xen_is_gint(width), width, 2, "gtk_widget_set_size_request", "gint"); Xen_check_type(Xen_is_gint(height), height, 3, "gtk_widget_set_size_request", "gint"); gtk_widget_set_size_request(Xen_to_C_GtkWidget_(widget), Xen_to_C_gint(width), Xen_to_C_gint(height)); return(Xen_false); } static Xen gxg_gtk_widget_get_size_request(Xen widget, Xen ignore_width, Xen ignore_height) { #define H_gtk_widget_get_size_request "void gtk_widget_get_size_request(GtkWidget* widget, gint* [width], \ gint* [height])" gint ref_width; gint ref_height; Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_size_request", "GtkWidget*"); gtk_widget_get_size_request(Xen_to_C_GtkWidget_(widget), &ref_width, &ref_height); return(Xen_list_2(C_to_Xen_gint(ref_width), C_to_Xen_gint(ref_height))); } static Xen gxg_gtk_widget_set_events(Xen widget, Xen events) { #define H_gtk_widget_set_events "void gtk_widget_set_events(GtkWidget* widget, gint events)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_set_events", "GtkWidget*"); Xen_check_type(Xen_is_gint(events), events, 2, "gtk_widget_set_events", "gint"); gtk_widget_set_events(Xen_to_C_GtkWidget_(widget), Xen_to_C_gint(events)); return(Xen_false); } static Xen gxg_gtk_widget_add_events(Xen widget, Xen events) { #define H_gtk_widget_add_events "void gtk_widget_add_events(GtkWidget* widget, gint events)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_add_events", "GtkWidget*"); Xen_check_type(Xen_is_gint(events), events, 2, "gtk_widget_add_events", "gint"); gtk_widget_add_events(Xen_to_C_GtkWidget_(widget), Xen_to_C_gint(events)); return(Xen_false); } static Xen gxg_gtk_widget_get_toplevel(Xen widget) { #define H_gtk_widget_get_toplevel "GtkWidget* gtk_widget_get_toplevel(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_toplevel", "GtkWidget*"); return(C_to_Xen_GtkWidget_(gtk_widget_get_toplevel(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_get_ancestor(Xen widget, Xen widget_type) { #define H_gtk_widget_get_ancestor "GtkWidget* gtk_widget_get_ancestor(GtkWidget* widget, GType widget_type)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_ancestor", "GtkWidget*"); Xen_check_type(Xen_is_GType(widget_type), widget_type, 2, "gtk_widget_get_ancestor", "GType"); return(C_to_Xen_GtkWidget_(gtk_widget_get_ancestor(Xen_to_C_GtkWidget_(widget), Xen_to_C_GType(widget_type)))); } static Xen gxg_gtk_widget_get_visual(Xen widget) { #define H_gtk_widget_get_visual "GdkVisual* gtk_widget_get_visual(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_visual", "GtkWidget*"); return(C_to_Xen_GdkVisual_(gtk_widget_get_visual(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_get_settings(Xen widget) { #define H_gtk_widget_get_settings "GtkSettings* gtk_widget_get_settings(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_settings", "GtkWidget*"); return(C_to_Xen_GtkSettings_(gtk_widget_get_settings(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_get_accessible(Xen widget) { #define H_gtk_widget_get_accessible "AtkObject* gtk_widget_get_accessible(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_accessible", "GtkWidget*"); return(C_to_Xen_AtkObject_(gtk_widget_get_accessible(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_get_events(Xen widget) { #define H_gtk_widget_get_events "gint gtk_widget_get_events(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_events", "GtkWidget*"); return(C_to_Xen_gint(gtk_widget_get_events(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_is_ancestor(Xen widget, Xen ancestor) { #define H_gtk_widget_is_ancestor "gboolean gtk_widget_is_ancestor(GtkWidget* widget, GtkWidget* ancestor)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_is_ancestor", "GtkWidget*"); Xen_check_type(Xen_is_GtkWidget_(ancestor), ancestor, 2, "gtk_widget_is_ancestor", "GtkWidget*"); return(C_to_Xen_gboolean(gtk_widget_is_ancestor(Xen_to_C_GtkWidget_(widget), Xen_to_C_GtkWidget_(ancestor)))); } static Xen gxg_gtk_widget_translate_coordinates(Xen src_widget, Xen dest_widget, Xen src_x, Xen src_y, Xen ignore_dest_x, Xen ignore_dest_y) { #define H_gtk_widget_translate_coordinates "gboolean gtk_widget_translate_coordinates(GtkWidget* src_widget, \ GtkWidget* dest_widget, gint src_x, gint src_y, gint* [dest_x], gint* [dest_y])" gint ref_dest_x; gint ref_dest_y; Xen_check_type(Xen_is_GtkWidget_(src_widget), src_widget, 1, "gtk_widget_translate_coordinates", "GtkWidget*"); Xen_check_type(Xen_is_GtkWidget_(dest_widget), dest_widget, 2, "gtk_widget_translate_coordinates", "GtkWidget*"); Xen_check_type(Xen_is_gint(src_x), src_x, 3, "gtk_widget_translate_coordinates", "gint"); Xen_check_type(Xen_is_gint(src_y), src_y, 4, "gtk_widget_translate_coordinates", "gint"); { Xen result; result = C_to_Xen_gboolean(gtk_widget_translate_coordinates(Xen_to_C_GtkWidget_(src_widget), Xen_to_C_GtkWidget_(dest_widget), Xen_to_C_gint(src_x), Xen_to_C_gint(src_y), &ref_dest_x, &ref_dest_y)); return(Xen_list_3(result, C_to_Xen_gint(ref_dest_x), C_to_Xen_gint(ref_dest_y))); } } static Xen gxg_gtk_widget_hide_on_delete(Xen widget) { #define H_gtk_widget_hide_on_delete "gboolean gtk_widget_hide_on_delete(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_hide_on_delete", "GtkWidget*"); return(C_to_Xen_gboolean(gtk_widget_hide_on_delete(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_create_pango_context(Xen widget) { #define H_gtk_widget_create_pango_context "PangoContext* gtk_widget_create_pango_context(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_create_pango_context", "GtkWidget*"); return(C_to_Xen_PangoContext_(gtk_widget_create_pango_context(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_get_pango_context(Xen widget) { #define H_gtk_widget_get_pango_context "PangoContext* gtk_widget_get_pango_context(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_pango_context", "GtkWidget*"); return(C_to_Xen_PangoContext_(gtk_widget_get_pango_context(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_create_pango_layout(Xen widget, Xen text) { #define H_gtk_widget_create_pango_layout "PangoLayout* gtk_widget_create_pango_layout(GtkWidget* widget, \ gchar* text)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_create_pango_layout", "GtkWidget*"); Xen_check_type(Xen_is_gchar_(text), text, 2, "gtk_widget_create_pango_layout", "gchar*"); return(C_to_Xen_PangoLayout_(gtk_widget_create_pango_layout(Xen_to_C_GtkWidget_(widget), Xen_to_C_gchar_(text)))); } static Xen gxg_gtk_widget_set_direction(Xen widget, Xen dir) { #define H_gtk_widget_set_direction "void gtk_widget_set_direction(GtkWidget* widget, GtkTextDirection dir)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_set_direction", "GtkWidget*"); Xen_check_type(Xen_is_GtkTextDirection(dir), dir, 2, "gtk_widget_set_direction", "GtkTextDirection"); gtk_widget_set_direction(Xen_to_C_GtkWidget_(widget), Xen_to_C_GtkTextDirection(dir)); return(Xen_false); } static Xen gxg_gtk_widget_get_direction(Xen widget) { #define H_gtk_widget_get_direction "GtkTextDirection gtk_widget_get_direction(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_direction", "GtkWidget*"); return(C_to_Xen_GtkTextDirection(gtk_widget_get_direction(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_set_default_direction(Xen dir) { #define H_gtk_widget_set_default_direction "void gtk_widget_set_default_direction(GtkTextDirection dir)" Xen_check_type(Xen_is_GtkTextDirection(dir), dir, 1, "gtk_widget_set_default_direction", "GtkTextDirection"); gtk_widget_set_default_direction(Xen_to_C_GtkTextDirection(dir)); return(Xen_false); } static Xen gxg_gtk_widget_get_default_direction(void) { #define H_gtk_widget_get_default_direction "GtkTextDirection gtk_widget_get_default_direction( void)" return(C_to_Xen_GtkTextDirection(gtk_widget_get_default_direction())); } static Xen gxg_gtk_widget_can_activate_accel(Xen widget, Xen signal_id) { #define H_gtk_widget_can_activate_accel "gboolean gtk_widget_can_activate_accel(GtkWidget* widget, \ guint signal_id)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_can_activate_accel", "GtkWidget*"); Xen_check_type(Xen_is_guint(signal_id), signal_id, 2, "gtk_widget_can_activate_accel", "guint"); return(C_to_Xen_gboolean(gtk_widget_can_activate_accel(Xen_to_C_GtkWidget_(widget), Xen_to_C_guint(signal_id)))); } static Xen gxg_gtk_window_is_active(Xen window) { #define H_gtk_window_is_active "gboolean gtk_window_is_active(GtkWindow* window)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_is_active", "GtkWindow*"); return(C_to_Xen_gboolean(gtk_window_is_active(Xen_to_C_GtkWindow_(window)))); } static Xen gxg_gtk_window_has_toplevel_focus(Xen window) { #define H_gtk_window_has_toplevel_focus "gboolean gtk_window_has_toplevel_focus(GtkWindow* window)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_has_toplevel_focus", "GtkWindow*"); return(C_to_Xen_gboolean(gtk_window_has_toplevel_focus(Xen_to_C_GtkWindow_(window)))); } static Xen gxg_gtk_window_new(Xen type) { #define H_gtk_window_new "GtkWidget* gtk_window_new(GtkWindowType type)" Xen_check_type(Xen_is_GtkWindowType(type), type, 1, "gtk_window_new", "GtkWindowType"); return(C_to_Xen_GtkWidget_(gtk_window_new(Xen_to_C_GtkWindowType(type)))); } static Xen gxg_gtk_window_set_title(Xen window, Xen title) { #define H_gtk_window_set_title "void gtk_window_set_title(GtkWindow* window, gchar* title)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_set_title", "GtkWindow*"); Xen_check_type(Xen_is_gchar_(title), title, 2, "gtk_window_set_title", "gchar*"); gtk_window_set_title(Xen_to_C_GtkWindow_(window), Xen_to_C_gchar_(title)); return(Xen_false); } static Xen gxg_gtk_window_set_auto_startup_notification(Xen setting) { #define H_gtk_window_set_auto_startup_notification "void gtk_window_set_auto_startup_notification(gboolean setting)" Xen_check_type(Xen_is_gboolean(setting), setting, 1, "gtk_window_set_auto_startup_notification", "gboolean"); gtk_window_set_auto_startup_notification(Xen_to_C_gboolean(setting)); return(Xen_false); } static Xen gxg_gtk_window_get_title(Xen window) { #define H_gtk_window_get_title "gchar* gtk_window_get_title(GtkWindow* window)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_get_title", "GtkWindow*"); return(C_to_Xen_gchar_(gtk_window_get_title(Xen_to_C_GtkWindow_(window)))); } static Xen gxg_gtk_window_set_wmclass(Xen window, Xen wmclass_name, Xen wmclass_class) { #define H_gtk_window_set_wmclass "void gtk_window_set_wmclass(GtkWindow* window, gchar* wmclass_name, \ gchar* wmclass_class)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_set_wmclass", "GtkWindow*"); Xen_check_type(Xen_is_gchar_(wmclass_name), wmclass_name, 2, "gtk_window_set_wmclass", "gchar*"); Xen_check_type(Xen_is_gchar_(wmclass_class), wmclass_class, 3, "gtk_window_set_wmclass", "gchar*"); gtk_window_set_wmclass(Xen_to_C_GtkWindow_(window), Xen_to_C_gchar_(wmclass_name), Xen_to_C_gchar_(wmclass_class)); return(Xen_false); } static Xen gxg_gtk_window_set_role(Xen window, Xen role) { #define H_gtk_window_set_role "void gtk_window_set_role(GtkWindow* window, gchar* role)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_set_role", "GtkWindow*"); Xen_check_type(Xen_is_gchar_(role), role, 2, "gtk_window_set_role", "gchar*"); gtk_window_set_role(Xen_to_C_GtkWindow_(window), Xen_to_C_gchar_(role)); return(Xen_false); } static Xen gxg_gtk_window_get_role(Xen window) { #define H_gtk_window_get_role "gchar* gtk_window_get_role(GtkWindow* window)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_get_role", "GtkWindow*"); return(C_to_Xen_gchar_(gtk_window_get_role(Xen_to_C_GtkWindow_(window)))); } static Xen gxg_gtk_window_add_accel_group(Xen window, Xen accel_group) { #define H_gtk_window_add_accel_group "void gtk_window_add_accel_group(GtkWindow* window, GtkAccelGroup* accel_group)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_add_accel_group", "GtkWindow*"); Xen_check_type(Xen_is_GtkAccelGroup_(accel_group), accel_group, 2, "gtk_window_add_accel_group", "GtkAccelGroup*"); gtk_window_add_accel_group(Xen_to_C_GtkWindow_(window), Xen_to_C_GtkAccelGroup_(accel_group)); return(Xen_false); } static Xen gxg_gtk_window_remove_accel_group(Xen window, Xen accel_group) { #define H_gtk_window_remove_accel_group "void gtk_window_remove_accel_group(GtkWindow* window, GtkAccelGroup* accel_group)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_remove_accel_group", "GtkWindow*"); Xen_check_type(Xen_is_GtkAccelGroup_(accel_group), accel_group, 2, "gtk_window_remove_accel_group", "GtkAccelGroup*"); gtk_window_remove_accel_group(Xen_to_C_GtkWindow_(window), Xen_to_C_GtkAccelGroup_(accel_group)); return(Xen_false); } static Xen gxg_gtk_window_set_position(Xen window, Xen position) { #define H_gtk_window_set_position "void gtk_window_set_position(GtkWindow* window, GtkWindowPosition position)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_set_position", "GtkWindow*"); Xen_check_type(Xen_is_GtkWindowPosition(position), position, 2, "gtk_window_set_position", "GtkWindowPosition"); gtk_window_set_position(Xen_to_C_GtkWindow_(window), Xen_to_C_GtkWindowPosition(position)); return(Xen_false); } static Xen gxg_gtk_window_activate_focus(Xen window) { #define H_gtk_window_activate_focus "gboolean gtk_window_activate_focus(GtkWindow* window)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_activate_focus", "GtkWindow*"); return(C_to_Xen_gboolean(gtk_window_activate_focus(Xen_to_C_GtkWindow_(window)))); } static Xen gxg_gtk_window_set_focus(Xen window, Xen focus) { #define H_gtk_window_set_focus "void gtk_window_set_focus(GtkWindow* window, GtkWidget* focus)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_set_focus", "GtkWindow*"); Xen_check_type(Xen_is_GtkWidget_(focus) || Xen_is_false(focus), focus, 2, "gtk_window_set_focus", "GtkWidget*"); gtk_window_set_focus(Xen_to_C_GtkWindow_(window), Xen_to_C_GtkWidget_(focus)); return(Xen_false); } static Xen gxg_gtk_window_get_focus(Xen window) { #define H_gtk_window_get_focus "GtkWidget* gtk_window_get_focus(GtkWindow* window)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_get_focus", "GtkWindow*"); return(C_to_Xen_GtkWidget_(gtk_window_get_focus(Xen_to_C_GtkWindow_(window)))); } static Xen gxg_gtk_window_set_default(Xen window, Xen default_widget) { #define H_gtk_window_set_default "void gtk_window_set_default(GtkWindow* window, GtkWidget* default_widget)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_set_default", "GtkWindow*"); Xen_check_type(Xen_is_GtkWidget_(default_widget) || Xen_is_false(default_widget), default_widget, 2, "gtk_window_set_default", "GtkWidget*"); gtk_window_set_default(Xen_to_C_GtkWindow_(window), Xen_to_C_GtkWidget_(default_widget)); return(Xen_false); } static Xen gxg_gtk_window_activate_default(Xen window) { #define H_gtk_window_activate_default "gboolean gtk_window_activate_default(GtkWindow* window)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_activate_default", "GtkWindow*"); return(C_to_Xen_gboolean(gtk_window_activate_default(Xen_to_C_GtkWindow_(window)))); } static Xen gxg_gtk_window_set_transient_for(Xen window, Xen parent) { #define H_gtk_window_set_transient_for "void gtk_window_set_transient_for(GtkWindow* window, GtkWindow* parent)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_set_transient_for", "GtkWindow*"); Xen_check_type(Xen_is_GtkWindow_(parent) || Xen_is_false(parent), parent, 2, "gtk_window_set_transient_for", "GtkWindow*"); gtk_window_set_transient_for(Xen_to_C_GtkWindow_(window), Xen_to_C_GtkWindow_(parent)); return(Xen_false); } static Xen gxg_gtk_window_get_transient_for(Xen window) { #define H_gtk_window_get_transient_for "GtkWindow* gtk_window_get_transient_for(GtkWindow* window)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_get_transient_for", "GtkWindow*"); return(C_to_Xen_GtkWindow_(gtk_window_get_transient_for(Xen_to_C_GtkWindow_(window)))); } static Xen gxg_gtk_window_set_type_hint(Xen window, Xen hint) { #define H_gtk_window_set_type_hint "void gtk_window_set_type_hint(GtkWindow* window, GdkWindowTypeHint hint)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_set_type_hint", "GtkWindow*"); Xen_check_type(Xen_is_GdkWindowTypeHint(hint), hint, 2, "gtk_window_set_type_hint", "GdkWindowTypeHint"); gtk_window_set_type_hint(Xen_to_C_GtkWindow_(window), Xen_to_C_GdkWindowTypeHint(hint)); return(Xen_false); } static Xen gxg_gtk_window_get_type_hint(Xen window) { #define H_gtk_window_get_type_hint "GdkWindowTypeHint gtk_window_get_type_hint(GtkWindow* window)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_get_type_hint", "GtkWindow*"); return(C_to_Xen_GdkWindowTypeHint(gtk_window_get_type_hint(Xen_to_C_GtkWindow_(window)))); } static Xen gxg_gtk_window_set_destroy_with_parent(Xen window, Xen setting) { #define H_gtk_window_set_destroy_with_parent "void gtk_window_set_destroy_with_parent(GtkWindow* window, \ gboolean setting)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_set_destroy_with_parent", "GtkWindow*"); Xen_check_type(Xen_is_gboolean(setting), setting, 2, "gtk_window_set_destroy_with_parent", "gboolean"); gtk_window_set_destroy_with_parent(Xen_to_C_GtkWindow_(window), Xen_to_C_gboolean(setting)); return(Xen_false); } static Xen gxg_gtk_window_get_destroy_with_parent(Xen window) { #define H_gtk_window_get_destroy_with_parent "gboolean gtk_window_get_destroy_with_parent(GtkWindow* window)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_get_destroy_with_parent", "GtkWindow*"); return(C_to_Xen_gboolean(gtk_window_get_destroy_with_parent(Xen_to_C_GtkWindow_(window)))); } static Xen gxg_gtk_window_set_resizable(Xen window, Xen resizable) { #define H_gtk_window_set_resizable "void gtk_window_set_resizable(GtkWindow* window, gboolean resizable)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_set_resizable", "GtkWindow*"); Xen_check_type(Xen_is_gboolean(resizable), resizable, 2, "gtk_window_set_resizable", "gboolean"); gtk_window_set_resizable(Xen_to_C_GtkWindow_(window), Xen_to_C_gboolean(resizable)); return(Xen_false); } static Xen gxg_gtk_window_get_resizable(Xen window) { #define H_gtk_window_get_resizable "gboolean gtk_window_get_resizable(GtkWindow* window)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_get_resizable", "GtkWindow*"); return(C_to_Xen_gboolean(gtk_window_get_resizable(Xen_to_C_GtkWindow_(window)))); } static Xen gxg_gtk_window_set_gravity(Xen window, Xen gravity) { #define H_gtk_window_set_gravity "void gtk_window_set_gravity(GtkWindow* window, GdkGravity gravity)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_set_gravity", "GtkWindow*"); Xen_check_type(Xen_is_GdkGravity(gravity), gravity, 2, "gtk_window_set_gravity", "GdkGravity"); gtk_window_set_gravity(Xen_to_C_GtkWindow_(window), Xen_to_C_GdkGravity(gravity)); return(Xen_false); } static Xen gxg_gtk_window_get_gravity(Xen window) { #define H_gtk_window_get_gravity "GdkGravity gtk_window_get_gravity(GtkWindow* window)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_get_gravity", "GtkWindow*"); return(C_to_Xen_GdkGravity(gtk_window_get_gravity(Xen_to_C_GtkWindow_(window)))); } static Xen gxg_gtk_window_set_geometry_hints(Xen window, Xen geometry_widget, Xen geometry, Xen geom_mask) { #define H_gtk_window_set_geometry_hints "void gtk_window_set_geometry_hints(GtkWindow* window, GtkWidget* geometry_widget, \ GdkGeometry* geometry, GdkWindowHints geom_mask)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_set_geometry_hints", "GtkWindow*"); Xen_check_type(Xen_is_GtkWidget_(geometry_widget), geometry_widget, 2, "gtk_window_set_geometry_hints", "GtkWidget*"); Xen_check_type(Xen_is_GdkGeometry_(geometry), geometry, 3, "gtk_window_set_geometry_hints", "GdkGeometry*"); Xen_check_type(Xen_is_GdkWindowHints(geom_mask), geom_mask, 4, "gtk_window_set_geometry_hints", "GdkWindowHints"); gtk_window_set_geometry_hints(Xen_to_C_GtkWindow_(window), Xen_to_C_GtkWidget_(geometry_widget), Xen_to_C_GdkGeometry_(geometry), Xen_to_C_GdkWindowHints(geom_mask)); return(Xen_false); } static Xen gxg_gtk_window_set_decorated(Xen window, Xen setting) { #define H_gtk_window_set_decorated "void gtk_window_set_decorated(GtkWindow* window, gboolean setting)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_set_decorated", "GtkWindow*"); Xen_check_type(Xen_is_gboolean(setting), setting, 2, "gtk_window_set_decorated", "gboolean"); gtk_window_set_decorated(Xen_to_C_GtkWindow_(window), Xen_to_C_gboolean(setting)); return(Xen_false); } static Xen gxg_gtk_window_get_decorated(Xen window) { #define H_gtk_window_get_decorated "gboolean gtk_window_get_decorated(GtkWindow* window)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_get_decorated", "GtkWindow*"); return(C_to_Xen_gboolean(gtk_window_get_decorated(Xen_to_C_GtkWindow_(window)))); } static Xen gxg_gtk_window_set_icon_list(Xen window, Xen list) { #define H_gtk_window_set_icon_list "void gtk_window_set_icon_list(GtkWindow* window, GList* list)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_set_icon_list", "GtkWindow*"); Xen_check_type(Xen_is_GList_(list) || Xen_is_false(list), list, 2, "gtk_window_set_icon_list", "GList*"); gtk_window_set_icon_list(Xen_to_C_GtkWindow_(window), Xen_to_C_GList_(list)); return(Xen_false); } static Xen gxg_gtk_window_get_icon_list(Xen window) { #define H_gtk_window_get_icon_list "GList* gtk_window_get_icon_list(GtkWindow* window)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_get_icon_list", "GtkWindow*"); return(C_to_Xen_GList_(gtk_window_get_icon_list(Xen_to_C_GtkWindow_(window)))); } static Xen gxg_gtk_window_set_icon(Xen window, Xen icon) { #define H_gtk_window_set_icon "void gtk_window_set_icon(GtkWindow* window, GdkPixbuf* icon)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_set_icon", "GtkWindow*"); Xen_check_type(Xen_is_GdkPixbuf_(icon) || Xen_is_false(icon), icon, 2, "gtk_window_set_icon", "GdkPixbuf*"); gtk_window_set_icon(Xen_to_C_GtkWindow_(window), Xen_to_C_GdkPixbuf_(icon)); return(Xen_false); } static Xen gxg_gtk_window_get_icon(Xen window) { #define H_gtk_window_get_icon "GdkPixbuf* gtk_window_get_icon(GtkWindow* window)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_get_icon", "GtkWindow*"); return(C_to_Xen_GdkPixbuf_(gtk_window_get_icon(Xen_to_C_GtkWindow_(window)))); } static Xen gxg_gtk_window_set_default_icon_list(Xen list) { #define H_gtk_window_set_default_icon_list "void gtk_window_set_default_icon_list(GList* list)" Xen_check_type(Xen_is_GList_(list) || Xen_is_false(list), list, 1, "gtk_window_set_default_icon_list", "GList*"); gtk_window_set_default_icon_list(Xen_to_C_GList_(list)); return(Xen_false); } static Xen gxg_gtk_window_get_default_icon_list(void) { #define H_gtk_window_get_default_icon_list "GList* gtk_window_get_default_icon_list( void)" return(C_to_Xen_GList_(gtk_window_get_default_icon_list())); } static Xen gxg_gtk_window_set_modal(Xen window, Xen modal) { #define H_gtk_window_set_modal "void gtk_window_set_modal(GtkWindow* window, gboolean modal)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_set_modal", "GtkWindow*"); Xen_check_type(Xen_is_gboolean(modal), modal, 2, "gtk_window_set_modal", "gboolean"); gtk_window_set_modal(Xen_to_C_GtkWindow_(window), Xen_to_C_gboolean(modal)); return(Xen_false); } static Xen gxg_gtk_window_get_modal(Xen window) { #define H_gtk_window_get_modal "gboolean gtk_window_get_modal(GtkWindow* window)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_get_modal", "GtkWindow*"); return(C_to_Xen_gboolean(gtk_window_get_modal(Xen_to_C_GtkWindow_(window)))); } static Xen gxg_gtk_window_list_toplevels(void) { #define H_gtk_window_list_toplevels "GList* gtk_window_list_toplevels( void)" return(C_to_Xen_GList_(gtk_window_list_toplevels())); } static Xen gxg_gtk_window_add_mnemonic(Xen window, Xen keyval, Xen target) { #define H_gtk_window_add_mnemonic "void gtk_window_add_mnemonic(GtkWindow* window, guint keyval, GtkWidget* target)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_add_mnemonic", "GtkWindow*"); Xen_check_type(Xen_is_guint(keyval), keyval, 2, "gtk_window_add_mnemonic", "guint"); Xen_check_type(Xen_is_GtkWidget_(target), target, 3, "gtk_window_add_mnemonic", "GtkWidget*"); gtk_window_add_mnemonic(Xen_to_C_GtkWindow_(window), Xen_to_C_guint(keyval), Xen_to_C_GtkWidget_(target)); return(Xen_false); } static Xen gxg_gtk_window_remove_mnemonic(Xen window, Xen keyval, Xen target) { #define H_gtk_window_remove_mnemonic "void gtk_window_remove_mnemonic(GtkWindow* window, guint keyval, \ GtkWidget* target)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_remove_mnemonic", "GtkWindow*"); Xen_check_type(Xen_is_guint(keyval), keyval, 2, "gtk_window_remove_mnemonic", "guint"); Xen_check_type(Xen_is_GtkWidget_(target), target, 3, "gtk_window_remove_mnemonic", "GtkWidget*"); gtk_window_remove_mnemonic(Xen_to_C_GtkWindow_(window), Xen_to_C_guint(keyval), Xen_to_C_GtkWidget_(target)); return(Xen_false); } static Xen gxg_gtk_window_mnemonic_activate(Xen window, Xen keyval, Xen modifier) { #define H_gtk_window_mnemonic_activate "gboolean gtk_window_mnemonic_activate(GtkWindow* window, guint keyval, \ GdkModifierType modifier)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_mnemonic_activate", "GtkWindow*"); Xen_check_type(Xen_is_guint(keyval), keyval, 2, "gtk_window_mnemonic_activate", "guint"); Xen_check_type(Xen_is_GdkModifierType(modifier), modifier, 3, "gtk_window_mnemonic_activate", "GdkModifierType"); return(C_to_Xen_gboolean(gtk_window_mnemonic_activate(Xen_to_C_GtkWindow_(window), Xen_to_C_guint(keyval), Xen_to_C_GdkModifierType(modifier)))); } static Xen gxg_gtk_window_set_mnemonic_modifier(Xen window, Xen modifier) { #define H_gtk_window_set_mnemonic_modifier "void gtk_window_set_mnemonic_modifier(GtkWindow* window, \ GdkModifierType modifier)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_set_mnemonic_modifier", "GtkWindow*"); Xen_check_type(Xen_is_GdkModifierType(modifier), modifier, 2, "gtk_window_set_mnemonic_modifier", "GdkModifierType"); gtk_window_set_mnemonic_modifier(Xen_to_C_GtkWindow_(window), Xen_to_C_GdkModifierType(modifier)); return(Xen_false); } static Xen gxg_gtk_window_get_mnemonic_modifier(Xen window) { #define H_gtk_window_get_mnemonic_modifier "GdkModifierType gtk_window_get_mnemonic_modifier(GtkWindow* window)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_get_mnemonic_modifier", "GtkWindow*"); return(C_to_Xen_GdkModifierType(gtk_window_get_mnemonic_modifier(Xen_to_C_GtkWindow_(window)))); } static Xen gxg_gtk_window_present(Xen window) { #define H_gtk_window_present "void gtk_window_present(GtkWindow* window)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_present", "GtkWindow*"); gtk_window_present(Xen_to_C_GtkWindow_(window)); return(Xen_false); } static Xen gxg_gtk_window_iconify(Xen window) { #define H_gtk_window_iconify "void gtk_window_iconify(GtkWindow* window)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_iconify", "GtkWindow*"); gtk_window_iconify(Xen_to_C_GtkWindow_(window)); return(Xen_false); } static Xen gxg_gtk_window_deiconify(Xen window) { #define H_gtk_window_deiconify "void gtk_window_deiconify(GtkWindow* window)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_deiconify", "GtkWindow*"); gtk_window_deiconify(Xen_to_C_GtkWindow_(window)); return(Xen_false); } static Xen gxg_gtk_window_stick(Xen window) { #define H_gtk_window_stick "void gtk_window_stick(GtkWindow* window)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_stick", "GtkWindow*"); gtk_window_stick(Xen_to_C_GtkWindow_(window)); return(Xen_false); } static Xen gxg_gtk_window_unstick(Xen window) { #define H_gtk_window_unstick "void gtk_window_unstick(GtkWindow* window)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_unstick", "GtkWindow*"); gtk_window_unstick(Xen_to_C_GtkWindow_(window)); return(Xen_false); } static Xen gxg_gtk_window_maximize(Xen window) { #define H_gtk_window_maximize "void gtk_window_maximize(GtkWindow* window)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_maximize", "GtkWindow*"); gtk_window_maximize(Xen_to_C_GtkWindow_(window)); return(Xen_false); } static Xen gxg_gtk_window_unmaximize(Xen window) { #define H_gtk_window_unmaximize "void gtk_window_unmaximize(GtkWindow* window)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_unmaximize", "GtkWindow*"); gtk_window_unmaximize(Xen_to_C_GtkWindow_(window)); return(Xen_false); } static Xen gxg_gtk_window_begin_resize_drag(Xen window, Xen edge, Xen button, Xen root_x, Xen root_y, Xen timestamp) { #define H_gtk_window_begin_resize_drag "void gtk_window_begin_resize_drag(GtkWindow* window, GdkWindowEdge edge, \ gint button, gint root_x, gint root_y, guint32 timestamp)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_begin_resize_drag", "GtkWindow*"); Xen_check_type(Xen_is_GdkWindowEdge(edge), edge, 2, "gtk_window_begin_resize_drag", "GdkWindowEdge"); Xen_check_type(Xen_is_gint(button), button, 3, "gtk_window_begin_resize_drag", "gint"); Xen_check_type(Xen_is_gint(root_x), root_x, 4, "gtk_window_begin_resize_drag", "gint"); Xen_check_type(Xen_is_gint(root_y), root_y, 5, "gtk_window_begin_resize_drag", "gint"); Xen_check_type(Xen_is_guint32(timestamp), timestamp, 6, "gtk_window_begin_resize_drag", "guint32"); gtk_window_begin_resize_drag(Xen_to_C_GtkWindow_(window), Xen_to_C_GdkWindowEdge(edge), Xen_to_C_gint(button), Xen_to_C_gint(root_x), Xen_to_C_gint(root_y), Xen_to_C_guint32(timestamp)); return(Xen_false); } static Xen gxg_gtk_window_begin_move_drag(Xen window, Xen button, Xen root_x, Xen root_y, Xen timestamp) { #define H_gtk_window_begin_move_drag "void gtk_window_begin_move_drag(GtkWindow* window, gint button, \ gint root_x, gint root_y, guint32 timestamp)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_begin_move_drag", "GtkWindow*"); Xen_check_type(Xen_is_gint(button), button, 2, "gtk_window_begin_move_drag", "gint"); Xen_check_type(Xen_is_gint(root_x), root_x, 3, "gtk_window_begin_move_drag", "gint"); Xen_check_type(Xen_is_gint(root_y), root_y, 4, "gtk_window_begin_move_drag", "gint"); Xen_check_type(Xen_is_guint32(timestamp), timestamp, 5, "gtk_window_begin_move_drag", "guint32"); gtk_window_begin_move_drag(Xen_to_C_GtkWindow_(window), Xen_to_C_gint(button), Xen_to_C_gint(root_x), Xen_to_C_gint(root_y), Xen_to_C_guint32(timestamp)); return(Xen_false); } static Xen gxg_gtk_window_set_default_size(Xen window, Xen width, Xen height) { #define H_gtk_window_set_default_size "void gtk_window_set_default_size(GtkWindow* window, gint width, \ gint height)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_set_default_size", "GtkWindow*"); Xen_check_type(Xen_is_gint(width), width, 2, "gtk_window_set_default_size", "gint"); Xen_check_type(Xen_is_gint(height), height, 3, "gtk_window_set_default_size", "gint"); gtk_window_set_default_size(Xen_to_C_GtkWindow_(window), Xen_to_C_gint(width), Xen_to_C_gint(height)); return(Xen_false); } static Xen gxg_gtk_window_get_default_size(Xen window, Xen ignore_width, Xen ignore_height) { #define H_gtk_window_get_default_size "void gtk_window_get_default_size(GtkWindow* window, gint* [width], \ gint* [height])" gint ref_width; gint ref_height; Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_get_default_size", "GtkWindow*"); gtk_window_get_default_size(Xen_to_C_GtkWindow_(window), &ref_width, &ref_height); return(Xen_list_2(C_to_Xen_gint(ref_width), C_to_Xen_gint(ref_height))); } static Xen gxg_gtk_window_resize(Xen window, Xen width, Xen height) { #define H_gtk_window_resize "void gtk_window_resize(GtkWindow* window, gint width, gint height)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_resize", "GtkWindow*"); Xen_check_type(Xen_is_gint(width), width, 2, "gtk_window_resize", "gint"); Xen_check_type(Xen_is_gint(height), height, 3, "gtk_window_resize", "gint"); gtk_window_resize(Xen_to_C_GtkWindow_(window), Xen_to_C_gint(width), Xen_to_C_gint(height)); return(Xen_false); } static Xen gxg_gtk_window_get_size(Xen window, Xen ignore_width, Xen ignore_height) { #define H_gtk_window_get_size "void gtk_window_get_size(GtkWindow* window, gint* [width], gint* [height])" gint ref_width; gint ref_height; Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_get_size", "GtkWindow*"); gtk_window_get_size(Xen_to_C_GtkWindow_(window), &ref_width, &ref_height); return(Xen_list_2(C_to_Xen_gint(ref_width), C_to_Xen_gint(ref_height))); } static Xen gxg_gtk_window_move(Xen window, Xen x, Xen y) { #define H_gtk_window_move "void gtk_window_move(GtkWindow* window, gint x, gint y)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_move", "GtkWindow*"); Xen_check_type(Xen_is_gint(x), x, 2, "gtk_window_move", "gint"); Xen_check_type(Xen_is_gint(y), y, 3, "gtk_window_move", "gint"); gtk_window_move(Xen_to_C_GtkWindow_(window), Xen_to_C_gint(x), Xen_to_C_gint(y)); return(Xen_false); } static Xen gxg_gtk_window_get_position(Xen window, Xen ignore_root_x, Xen ignore_root_y) { #define H_gtk_window_get_position "void gtk_window_get_position(GtkWindow* window, gint* [root_x], \ gint* [root_y])" gint ref_root_x; gint ref_root_y; Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_get_position", "GtkWindow*"); gtk_window_get_position(Xen_to_C_GtkWindow_(window), &ref_root_x, &ref_root_y); return(Xen_list_2(C_to_Xen_gint(ref_root_x), C_to_Xen_gint(ref_root_y))); } static Xen gxg_gtk_window_parse_geometry(Xen window, Xen geometry) { #define H_gtk_window_parse_geometry "gboolean gtk_window_parse_geometry(GtkWindow* window, gchar* geometry)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_parse_geometry", "GtkWindow*"); Xen_check_type(Xen_is_gchar_(geometry), geometry, 2, "gtk_window_parse_geometry", "gchar*"); return(C_to_Xen_gboolean(gtk_window_parse_geometry(Xen_to_C_GtkWindow_(window), Xen_to_C_gchar_(geometry)))); } static Xen gxg_pango_color_copy(Xen src) { #define H_pango_color_copy "PangoColor* pango_color_copy(PangoColor* src)" Xen_check_type(Xen_is_PangoColor_(src), src, 1, "pango_color_copy", "PangoColor*"); return(C_to_Xen_PangoColor_(pango_color_copy(Xen_to_C_PangoColor_(src)))); } static Xen gxg_pango_color_free(Xen color) { #define H_pango_color_free "void pango_color_free(PangoColor* color)" Xen_check_type(Xen_is_PangoColor_(color), color, 1, "pango_color_free", "PangoColor*"); pango_color_free(Xen_to_C_PangoColor_(color)); return(Xen_false); } static Xen gxg_pango_color_parse(Xen color, Xen spec) { #define H_pango_color_parse "gboolean pango_color_parse(PangoColor* color, char* spec)" Xen_check_type(Xen_is_PangoColor_(color), color, 1, "pango_color_parse", "PangoColor*"); Xen_check_type(Xen_is_char_(spec), spec, 2, "pango_color_parse", "char*"); return(C_to_Xen_gboolean(pango_color_parse(Xen_to_C_PangoColor_(color), Xen_to_C_char_(spec)))); } static Xen gxg_pango_attr_type_register(Xen name) { #define H_pango_attr_type_register "PangoAttrType pango_attr_type_register(gchar* name)" Xen_check_type(Xen_is_gchar_(name), name, 1, "pango_attr_type_register", "gchar*"); return(C_to_Xen_PangoAttrType(pango_attr_type_register(Xen_to_C_gchar_(name)))); } static Xen gxg_pango_attribute_copy(Xen attr) { #define H_pango_attribute_copy "PangoAttribute* pango_attribute_copy(PangoAttribute* attr)" Xen_check_type(Xen_is_PangoAttribute_(attr), attr, 1, "pango_attribute_copy", "PangoAttribute*"); return(C_to_Xen_PangoAttribute_(pango_attribute_copy(Xen_to_C_PangoAttribute_(attr)))); } static Xen gxg_pango_attribute_destroy(Xen attr) { #define H_pango_attribute_destroy "void pango_attribute_destroy(PangoAttribute* attr)" Xen_check_type(Xen_is_PangoAttribute_(attr), attr, 1, "pango_attribute_destroy", "PangoAttribute*"); pango_attribute_destroy(Xen_to_C_PangoAttribute_(attr)); return(Xen_false); } static Xen gxg_pango_attribute_equal(Xen attr1, Xen attr2) { #define H_pango_attribute_equal "gboolean pango_attribute_equal(PangoAttribute* attr1, PangoAttribute* attr2)" Xen_check_type(Xen_is_PangoAttribute_(attr1), attr1, 1, "pango_attribute_equal", "PangoAttribute*"); Xen_check_type(Xen_is_PangoAttribute_(attr2), attr2, 2, "pango_attribute_equal", "PangoAttribute*"); return(C_to_Xen_gboolean(pango_attribute_equal(Xen_to_C_PangoAttribute_(attr1), Xen_to_C_PangoAttribute_(attr2)))); } static Xen gxg_pango_attr_language_new(Xen language) { #define H_pango_attr_language_new "PangoAttribute* pango_attr_language_new(PangoLanguage* language)" Xen_check_type(Xen_is_PangoLanguage_(language), language, 1, "pango_attr_language_new", "PangoLanguage*"); return(C_to_Xen_PangoAttribute_(pango_attr_language_new(Xen_to_C_PangoLanguage_(language)))); } static Xen gxg_pango_attr_family_new(Xen family) { #define H_pango_attr_family_new "PangoAttribute* pango_attr_family_new(char* family)" Xen_check_type(Xen_is_char_(family), family, 1, "pango_attr_family_new", "char*"); return(C_to_Xen_PangoAttribute_(pango_attr_family_new(Xen_to_C_char_(family)))); } static Xen gxg_pango_attr_foreground_new(Xen red, Xen green, Xen blue) { #define H_pango_attr_foreground_new "PangoAttribute* pango_attr_foreground_new(guint16 red, guint16 green, \ guint16 blue)" Xen_check_type(Xen_is_guint16(red), red, 1, "pango_attr_foreground_new", "guint16"); Xen_check_type(Xen_is_guint16(green), green, 2, "pango_attr_foreground_new", "guint16"); Xen_check_type(Xen_is_guint16(blue), blue, 3, "pango_attr_foreground_new", "guint16"); return(C_to_Xen_PangoAttribute_(pango_attr_foreground_new(Xen_to_C_guint16(red), Xen_to_C_guint16(green), Xen_to_C_guint16(blue)))); } static Xen gxg_pango_attr_background_new(Xen red, Xen green, Xen blue) { #define H_pango_attr_background_new "PangoAttribute* pango_attr_background_new(guint16 red, guint16 green, \ guint16 blue)" Xen_check_type(Xen_is_guint16(red), red, 1, "pango_attr_background_new", "guint16"); Xen_check_type(Xen_is_guint16(green), green, 2, "pango_attr_background_new", "guint16"); Xen_check_type(Xen_is_guint16(blue), blue, 3, "pango_attr_background_new", "guint16"); return(C_to_Xen_PangoAttribute_(pango_attr_background_new(Xen_to_C_guint16(red), Xen_to_C_guint16(green), Xen_to_C_guint16(blue)))); } static Xen gxg_pango_attr_size_new(Xen size) { #define H_pango_attr_size_new "PangoAttribute* pango_attr_size_new(int size)" Xen_check_type(Xen_is_int(size), size, 1, "pango_attr_size_new", "int"); return(C_to_Xen_PangoAttribute_(pango_attr_size_new(Xen_to_C_int(size)))); } static Xen gxg_pango_attr_style_new(Xen style) { #define H_pango_attr_style_new "PangoAttribute* pango_attr_style_new(PangoStyle style)" Xen_check_type(Xen_is_PangoStyle(style), style, 1, "pango_attr_style_new", "PangoStyle"); return(C_to_Xen_PangoAttribute_(pango_attr_style_new(Xen_to_C_PangoStyle(style)))); } static Xen gxg_pango_attr_weight_new(Xen weight) { #define H_pango_attr_weight_new "PangoAttribute* pango_attr_weight_new(PangoWeight weight)" Xen_check_type(Xen_is_PangoWeight(weight), weight, 1, "pango_attr_weight_new", "PangoWeight"); return(C_to_Xen_PangoAttribute_(pango_attr_weight_new(Xen_to_C_PangoWeight(weight)))); } static Xen gxg_pango_attr_variant_new(Xen variant) { #define H_pango_attr_variant_new "PangoAttribute* pango_attr_variant_new(PangoVariant variant)" Xen_check_type(Xen_is_PangoVariant(variant), variant, 1, "pango_attr_variant_new", "PangoVariant"); return(C_to_Xen_PangoAttribute_(pango_attr_variant_new(Xen_to_C_PangoVariant(variant)))); } static Xen gxg_pango_attr_stretch_new(Xen stretch) { #define H_pango_attr_stretch_new "PangoAttribute* pango_attr_stretch_new(PangoStretch stretch)" Xen_check_type(Xen_is_PangoStretch(stretch), stretch, 1, "pango_attr_stretch_new", "PangoStretch"); return(C_to_Xen_PangoAttribute_(pango_attr_stretch_new(Xen_to_C_PangoStretch(stretch)))); } static Xen gxg_pango_attr_font_desc_new(Xen desc) { #define H_pango_attr_font_desc_new "PangoAttribute* pango_attr_font_desc_new(PangoFontDescription* desc)" Xen_check_type(Xen_is_PangoFontDescription_(desc), desc, 1, "pango_attr_font_desc_new", "PangoFontDescription*"); return(C_to_Xen_PangoAttribute_(pango_attr_font_desc_new(Xen_to_C_PangoFontDescription_(desc)))); } static Xen gxg_pango_attr_underline_new(Xen underline) { #define H_pango_attr_underline_new "PangoAttribute* pango_attr_underline_new(PangoUnderline underline)" Xen_check_type(Xen_is_PangoUnderline(underline), underline, 1, "pango_attr_underline_new", "PangoUnderline"); return(C_to_Xen_PangoAttribute_(pango_attr_underline_new(Xen_to_C_PangoUnderline(underline)))); } static Xen gxg_pango_attr_strikethrough_new(Xen strikethrough) { #define H_pango_attr_strikethrough_new "PangoAttribute* pango_attr_strikethrough_new(gboolean strikethrough)" Xen_check_type(Xen_is_gboolean(strikethrough), strikethrough, 1, "pango_attr_strikethrough_new", "gboolean"); return(C_to_Xen_PangoAttribute_(pango_attr_strikethrough_new(Xen_to_C_gboolean(strikethrough)))); } static Xen gxg_pango_attr_rise_new(Xen rise) { #define H_pango_attr_rise_new "PangoAttribute* pango_attr_rise_new(int rise)" Xen_check_type(Xen_is_int(rise), rise, 1, "pango_attr_rise_new", "int"); return(C_to_Xen_PangoAttribute_(pango_attr_rise_new(Xen_to_C_int(rise)))); } static Xen gxg_pango_attr_shape_new(Xen ink_rect, Xen logical_rect) { #define H_pango_attr_shape_new "PangoAttribute* pango_attr_shape_new(PangoRectangle* ink_rect, PangoRectangle* logical_rect)" Xen_check_type(Xen_is_PangoRectangle_(ink_rect), ink_rect, 1, "pango_attr_shape_new", "PangoRectangle*"); Xen_check_type(Xen_is_PangoRectangle_(logical_rect), logical_rect, 2, "pango_attr_shape_new", "PangoRectangle*"); return(C_to_Xen_PangoAttribute_(pango_attr_shape_new(Xen_to_C_PangoRectangle_(ink_rect), Xen_to_C_PangoRectangle_(logical_rect)))); } static Xen gxg_pango_attr_scale_new(Xen scale_factor) { #define H_pango_attr_scale_new "PangoAttribute* pango_attr_scale_new(double scale_factor)" Xen_check_type(Xen_is_double(scale_factor), scale_factor, 1, "pango_attr_scale_new", "double"); return(C_to_Xen_PangoAttribute_(pango_attr_scale_new(Xen_to_C_double(scale_factor)))); } static Xen gxg_pango_attr_list_new(void) { #define H_pango_attr_list_new "PangoAttrList* pango_attr_list_new( void)" return(C_to_Xen_PangoAttrList_(pango_attr_list_new())); } static Xen gxg_pango_attr_list_unref(Xen list) { #define H_pango_attr_list_unref "void pango_attr_list_unref(PangoAttrList* list)" Xen_check_type(Xen_is_PangoAttrList_(list), list, 1, "pango_attr_list_unref", "PangoAttrList*"); pango_attr_list_unref(Xen_to_C_PangoAttrList_(list)); return(Xen_false); } static Xen gxg_pango_attr_list_copy(Xen list) { #define H_pango_attr_list_copy "PangoAttrList* pango_attr_list_copy(PangoAttrList* list)" Xen_check_type(Xen_is_PangoAttrList_(list), list, 1, "pango_attr_list_copy", "PangoAttrList*"); return(C_to_Xen_PangoAttrList_(pango_attr_list_copy(Xen_to_C_PangoAttrList_(list)))); } static Xen gxg_pango_attr_list_insert(Xen list, Xen attr) { #define H_pango_attr_list_insert "void pango_attr_list_insert(PangoAttrList* list, PangoAttribute* attr)" Xen_check_type(Xen_is_PangoAttrList_(list), list, 1, "pango_attr_list_insert", "PangoAttrList*"); Xen_check_type(Xen_is_PangoAttribute_(attr), attr, 2, "pango_attr_list_insert", "PangoAttribute*"); pango_attr_list_insert(Xen_to_C_PangoAttrList_(list), Xen_to_C_PangoAttribute_(attr)); return(Xen_false); } static Xen gxg_pango_attr_list_insert_before(Xen list, Xen attr) { #define H_pango_attr_list_insert_before "void pango_attr_list_insert_before(PangoAttrList* list, PangoAttribute* attr)" Xen_check_type(Xen_is_PangoAttrList_(list), list, 1, "pango_attr_list_insert_before", "PangoAttrList*"); Xen_check_type(Xen_is_PangoAttribute_(attr), attr, 2, "pango_attr_list_insert_before", "PangoAttribute*"); pango_attr_list_insert_before(Xen_to_C_PangoAttrList_(list), Xen_to_C_PangoAttribute_(attr)); return(Xen_false); } static Xen gxg_pango_attr_list_change(Xen list, Xen attr) { #define H_pango_attr_list_change "void pango_attr_list_change(PangoAttrList* list, PangoAttribute* attr)" Xen_check_type(Xen_is_PangoAttrList_(list), list, 1, "pango_attr_list_change", "PangoAttrList*"); Xen_check_type(Xen_is_PangoAttribute_(attr), attr, 2, "pango_attr_list_change", "PangoAttribute*"); pango_attr_list_change(Xen_to_C_PangoAttrList_(list), Xen_to_C_PangoAttribute_(attr)); return(Xen_false); } static Xen gxg_pango_attr_list_splice(Xen list, Xen other, Xen pos, Xen len) { #define H_pango_attr_list_splice "void pango_attr_list_splice(PangoAttrList* list, PangoAttrList* other, \ gint pos, gint len)" Xen_check_type(Xen_is_PangoAttrList_(list), list, 1, "pango_attr_list_splice", "PangoAttrList*"); Xen_check_type(Xen_is_PangoAttrList_(other), other, 2, "pango_attr_list_splice", "PangoAttrList*"); Xen_check_type(Xen_is_gint(pos), pos, 3, "pango_attr_list_splice", "gint"); Xen_check_type(Xen_is_gint(len), len, 4, "pango_attr_list_splice", "gint"); pango_attr_list_splice(Xen_to_C_PangoAttrList_(list), Xen_to_C_PangoAttrList_(other), Xen_to_C_gint(pos), Xen_to_C_gint(len)); return(Xen_false); } static Xen gxg_pango_attr_list_get_iterator(Xen list) { #define H_pango_attr_list_get_iterator "PangoAttrIterator* pango_attr_list_get_iterator(PangoAttrList* list)" Xen_check_type(Xen_is_PangoAttrList_(list), list, 1, "pango_attr_list_get_iterator", "PangoAttrList*"); return(C_to_Xen_PangoAttrIterator_(pango_attr_list_get_iterator(Xen_to_C_PangoAttrList_(list)))); } static Xen gxg_pango_attr_iterator_range(Xen iterator, Xen ignore_start, Xen ignore_end) { #define H_pango_attr_iterator_range "void pango_attr_iterator_range(PangoAttrIterator* iterator, gint* [start], \ gint* [end])" gint ref_start; gint ref_end; Xen_check_type(Xen_is_PangoAttrIterator_(iterator), iterator, 1, "pango_attr_iterator_range", "PangoAttrIterator*"); pango_attr_iterator_range(Xen_to_C_PangoAttrIterator_(iterator), &ref_start, &ref_end); return(Xen_list_2(C_to_Xen_gint(ref_start), C_to_Xen_gint(ref_end))); } static Xen gxg_pango_attr_iterator_next(Xen iterator) { #define H_pango_attr_iterator_next "gboolean pango_attr_iterator_next(PangoAttrIterator* iterator)" Xen_check_type(Xen_is_PangoAttrIterator_(iterator), iterator, 1, "pango_attr_iterator_next", "PangoAttrIterator*"); return(C_to_Xen_gboolean(pango_attr_iterator_next(Xen_to_C_PangoAttrIterator_(iterator)))); } static Xen gxg_pango_attr_iterator_copy(Xen iterator) { #define H_pango_attr_iterator_copy "PangoAttrIterator* pango_attr_iterator_copy(PangoAttrIterator* iterator)" Xen_check_type(Xen_is_PangoAttrIterator_(iterator), iterator, 1, "pango_attr_iterator_copy", "PangoAttrIterator*"); return(C_to_Xen_PangoAttrIterator_(pango_attr_iterator_copy(Xen_to_C_PangoAttrIterator_(iterator)))); } static Xen gxg_pango_attr_iterator_destroy(Xen iterator) { #define H_pango_attr_iterator_destroy "void pango_attr_iterator_destroy(PangoAttrIterator* iterator)" Xen_check_type(Xen_is_PangoAttrIterator_(iterator), iterator, 1, "pango_attr_iterator_destroy", "PangoAttrIterator*"); pango_attr_iterator_destroy(Xen_to_C_PangoAttrIterator_(iterator)); return(Xen_false); } static Xen gxg_pango_attr_iterator_get(Xen iterator, Xen type) { #define H_pango_attr_iterator_get "PangoAttribute* pango_attr_iterator_get(PangoAttrIterator* iterator, \ PangoAttrType type)" Xen_check_type(Xen_is_PangoAttrIterator_(iterator), iterator, 1, "pango_attr_iterator_get", "PangoAttrIterator*"); Xen_check_type(Xen_is_PangoAttrType(type), type, 2, "pango_attr_iterator_get", "PangoAttrType"); return(C_to_Xen_PangoAttribute_(pango_attr_iterator_get(Xen_to_C_PangoAttrIterator_(iterator), Xen_to_C_PangoAttrType(type)))); } static Xen gxg_pango_attr_iterator_get_font(Xen iterator, Xen desc, Xen ignore_language, Xen ignore_extra_attrs) { #define H_pango_attr_iterator_get_font "void pango_attr_iterator_get_font(PangoAttrIterator* iterator, \ PangoFontDescription* desc, PangoLanguage** [language], GSList** [extra_attrs])" PangoLanguage* ref_language = NULL; GSList* ref_extra_attrs = NULL; Xen_check_type(Xen_is_PangoAttrIterator_(iterator), iterator, 1, "pango_attr_iterator_get_font", "PangoAttrIterator*"); Xen_check_type(Xen_is_PangoFontDescription_(desc), desc, 2, "pango_attr_iterator_get_font", "PangoFontDescription*"); pango_attr_iterator_get_font(Xen_to_C_PangoAttrIterator_(iterator), Xen_to_C_PangoFontDescription_(desc), &ref_language, &ref_extra_attrs); return(Xen_list_2(C_to_Xen_PangoLanguage_(ref_language), C_to_Xen_GSList_(ref_extra_attrs))); } static Xen gxg_pango_parse_markup(Xen markup_text, Xen length, Xen accel_marker, Xen attr_list, Xen text, Xen accel_char, Xen ignore_error) { #define H_pango_parse_markup "gboolean pango_parse_markup(char* markup_text, int length, gunichar accel_marker, \ PangoAttrList** attr_list, char** text, gunichar* accel_char, GError** [error])" GError* ref_error = NULL; Xen_check_type(Xen_is_char_(markup_text), markup_text, 1, "pango_parse_markup", "char*"); Xen_check_type(Xen_is_int(length), length, 2, "pango_parse_markup", "int"); Xen_check_type(Xen_is_gunichar(accel_marker), accel_marker, 3, "pango_parse_markup", "gunichar"); Xen_check_type(Xen_is_PangoAttrList__(attr_list), attr_list, 4, "pango_parse_markup", "PangoAttrList**"); Xen_check_type(Xen_is_char__(text), text, 5, "pango_parse_markup", "char**"); Xen_check_type(Xen_is_gunichar_(accel_char), accel_char, 6, "pango_parse_markup", "gunichar*"); { Xen result; result = C_to_Xen_gboolean(pango_parse_markup(Xen_to_C_char_(markup_text), Xen_to_C_int(length), Xen_to_C_gunichar(accel_marker), Xen_to_C_PangoAttrList__(attr_list), Xen_to_C_char__(text), Xen_to_C_gunichar_(accel_char), &ref_error)); return(Xen_list_2(result, C_to_Xen_GError_(ref_error))); } } static Xen gxg_pango_break(Xen text, Xen length, Xen analysis, Xen attrs, Xen attrs_len) { #define H_pango_break "void pango_break(gchar* text, int length, PangoAnalysis* analysis, PangoLogAttr* attrs, \ int attrs_len)" Xen_check_type(Xen_is_gchar_(text), text, 1, "pango_break", "gchar*"); Xen_check_type(Xen_is_int(length), length, 2, "pango_break", "int"); Xen_check_type(Xen_is_PangoAnalysis_(analysis), analysis, 3, "pango_break", "PangoAnalysis*"); Xen_check_type(Xen_is_PangoLogAttr_(attrs), attrs, 4, "pango_break", "PangoLogAttr*"); Xen_check_type(Xen_is_int(attrs_len), attrs_len, 5, "pango_break", "int"); pango_break(Xen_to_C_gchar_(text), Xen_to_C_int(length), Xen_to_C_PangoAnalysis_(analysis), Xen_to_C_PangoLogAttr_(attrs), Xen_to_C_int(attrs_len)); return(Xen_false); } static Xen gxg_pango_find_paragraph_boundary(Xen text, Xen length, Xen ignore_paragraph_delimiter_index, Xen ignore_next_paragraph_start) { #define H_pango_find_paragraph_boundary "void pango_find_paragraph_boundary(gchar* text, gint length, \ gint* [paragraph_delimiter_index], gint* [next_paragraph_start])" gint ref_paragraph_delimiter_index; gint ref_next_paragraph_start; Xen_check_type(Xen_is_gchar_(text), text, 1, "pango_find_paragraph_boundary", "gchar*"); Xen_check_type(Xen_is_gint(length), length, 2, "pango_find_paragraph_boundary", "gint"); pango_find_paragraph_boundary(Xen_to_C_gchar_(text), Xen_to_C_gint(length), &ref_paragraph_delimiter_index, &ref_next_paragraph_start); return(Xen_list_2(C_to_Xen_gint(ref_paragraph_delimiter_index), C_to_Xen_gint(ref_next_paragraph_start))); } static Xen gxg_pango_get_log_attrs(Xen text, Xen length, Xen level, Xen language, Xen log_attrs, Xen attrs_len) { #define H_pango_get_log_attrs "void pango_get_log_attrs(char* text, int length, int level, PangoLanguage* language, \ PangoLogAttr* log_attrs, int attrs_len)" Xen_check_type(Xen_is_char_(text), text, 1, "pango_get_log_attrs", "char*"); Xen_check_type(Xen_is_int(length), length, 2, "pango_get_log_attrs", "int"); Xen_check_type(Xen_is_int(level), level, 3, "pango_get_log_attrs", "int"); Xen_check_type(Xen_is_PangoLanguage_(language), language, 4, "pango_get_log_attrs", "PangoLanguage*"); Xen_check_type(Xen_is_PangoLogAttr_(log_attrs), log_attrs, 5, "pango_get_log_attrs", "PangoLogAttr*"); Xen_check_type(Xen_is_int(attrs_len), attrs_len, 6, "pango_get_log_attrs", "int"); pango_get_log_attrs(Xen_to_C_char_(text), Xen_to_C_int(length), Xen_to_C_int(level), Xen_to_C_PangoLanguage_(language), Xen_to_C_PangoLogAttr_(log_attrs), Xen_to_C_int(attrs_len)); return(Xen_false); } static Xen gxg_pango_context_list_families(Xen context, Xen ignore_families, Xen ignore_n_families) { #define H_pango_context_list_families "void pango_context_list_families(PangoContext* context, PangoFontFamily*** [families], \ int* [n_families])" PangoFontFamily** ref_families = NULL; int ref_n_families; Xen_check_type(Xen_is_PangoContext_(context), context, 1, "pango_context_list_families", "PangoContext*"); pango_context_list_families(Xen_to_C_PangoContext_(context), &ref_families, &ref_n_families); return(Xen_list_2(C_to_Xen_PangoFontFamily__(ref_families), C_to_Xen_int(ref_n_families))); } static Xen gxg_pango_context_load_font(Xen context, Xen desc) { #define H_pango_context_load_font "PangoFont* pango_context_load_font(PangoContext* context, PangoFontDescription* desc)" Xen_check_type(Xen_is_PangoContext_(context), context, 1, "pango_context_load_font", "PangoContext*"); Xen_check_type(Xen_is_PangoFontDescription_(desc), desc, 2, "pango_context_load_font", "PangoFontDescription*"); return(C_to_Xen_PangoFont_(pango_context_load_font(Xen_to_C_PangoContext_(context), Xen_to_C_PangoFontDescription_(desc)))); } static Xen gxg_pango_context_load_fontset(Xen context, Xen desc, Xen language) { #define H_pango_context_load_fontset "PangoFontset* pango_context_load_fontset(PangoContext* context, \ PangoFontDescription* desc, PangoLanguage* language)" Xen_check_type(Xen_is_PangoContext_(context), context, 1, "pango_context_load_fontset", "PangoContext*"); Xen_check_type(Xen_is_PangoFontDescription_(desc), desc, 2, "pango_context_load_fontset", "PangoFontDescription*"); Xen_check_type(Xen_is_PangoLanguage_(language), language, 3, "pango_context_load_fontset", "PangoLanguage*"); return(C_to_Xen_PangoFontset_(pango_context_load_fontset(Xen_to_C_PangoContext_(context), Xen_to_C_PangoFontDescription_(desc), Xen_to_C_PangoLanguage_(language)))); } static Xen gxg_pango_context_get_metrics(Xen context, Xen desc, Xen language) { #define H_pango_context_get_metrics "PangoFontMetrics* pango_context_get_metrics(PangoContext* context, \ PangoFontDescription* desc, PangoLanguage* language)" Xen_check_type(Xen_is_PangoContext_(context), context, 1, "pango_context_get_metrics", "PangoContext*"); Xen_check_type(Xen_is_PangoFontDescription_(desc), desc, 2, "pango_context_get_metrics", "PangoFontDescription*"); Xen_check_type(Xen_is_PangoLanguage_(language), language, 3, "pango_context_get_metrics", "PangoLanguage*"); return(C_to_Xen_PangoFontMetrics_(pango_context_get_metrics(Xen_to_C_PangoContext_(context), Xen_to_C_PangoFontDescription_(desc), Xen_to_C_PangoLanguage_(language)))); } static Xen gxg_pango_context_set_font_description(Xen context, Xen desc) { #define H_pango_context_set_font_description "void pango_context_set_font_description(PangoContext* context, \ PangoFontDescription* desc)" Xen_check_type(Xen_is_PangoContext_(context), context, 1, "pango_context_set_font_description", "PangoContext*"); Xen_check_type(Xen_is_PangoFontDescription_(desc), desc, 2, "pango_context_set_font_description", "PangoFontDescription*"); pango_context_set_font_description(Xen_to_C_PangoContext_(context), Xen_to_C_PangoFontDescription_(desc)); return(Xen_false); } static Xen gxg_pango_context_get_font_description(Xen context) { #define H_pango_context_get_font_description "PangoFontDescription* pango_context_get_font_description(PangoContext* context)" Xen_check_type(Xen_is_PangoContext_(context), context, 1, "pango_context_get_font_description", "PangoContext*"); return(C_to_Xen_PangoFontDescription_(pango_context_get_font_description(Xen_to_C_PangoContext_(context)))); } static Xen gxg_pango_context_get_language(Xen context) { #define H_pango_context_get_language "PangoLanguage* pango_context_get_language(PangoContext* context)" Xen_check_type(Xen_is_PangoContext_(context), context, 1, "pango_context_get_language", "PangoContext*"); return(C_to_Xen_PangoLanguage_(pango_context_get_language(Xen_to_C_PangoContext_(context)))); } static Xen gxg_pango_context_set_language(Xen context, Xen language) { #define H_pango_context_set_language "void pango_context_set_language(PangoContext* context, PangoLanguage* language)" Xen_check_type(Xen_is_PangoContext_(context), context, 1, "pango_context_set_language", "PangoContext*"); Xen_check_type(Xen_is_PangoLanguage_(language), language, 2, "pango_context_set_language", "PangoLanguage*"); pango_context_set_language(Xen_to_C_PangoContext_(context), Xen_to_C_PangoLanguage_(language)); return(Xen_false); } static Xen gxg_pango_context_set_base_dir(Xen context, Xen direction) { #define H_pango_context_set_base_dir "void pango_context_set_base_dir(PangoContext* context, PangoDirection direction)" Xen_check_type(Xen_is_PangoContext_(context), context, 1, "pango_context_set_base_dir", "PangoContext*"); Xen_check_type(Xen_is_PangoDirection(direction), direction, 2, "pango_context_set_base_dir", "PangoDirection"); pango_context_set_base_dir(Xen_to_C_PangoContext_(context), Xen_to_C_PangoDirection(direction)); return(Xen_false); } static Xen gxg_pango_context_get_base_dir(Xen context) { #define H_pango_context_get_base_dir "PangoDirection pango_context_get_base_dir(PangoContext* context)" Xen_check_type(Xen_is_PangoContext_(context), context, 1, "pango_context_get_base_dir", "PangoContext*"); return(C_to_Xen_PangoDirection(pango_context_get_base_dir(Xen_to_C_PangoContext_(context)))); } static Xen gxg_pango_itemize(Xen context, Xen text, Xen start_index, Xen length, Xen attrs, Xen cached_iter) { #define H_pango_itemize "GList* pango_itemize(PangoContext* context, char* text, int start_index, int length, \ PangoAttrList* attrs, PangoAttrIterator* cached_iter)" Xen_check_type(Xen_is_PangoContext_(context), context, 1, "pango_itemize", "PangoContext*"); Xen_check_type(Xen_is_char_(text), text, 2, "pango_itemize", "char*"); Xen_check_type(Xen_is_int(start_index), start_index, 3, "pango_itemize", "int"); Xen_check_type(Xen_is_int(length), length, 4, "pango_itemize", "int"); Xen_check_type(Xen_is_PangoAttrList_(attrs), attrs, 5, "pango_itemize", "PangoAttrList*"); Xen_check_type(Xen_is_PangoAttrIterator_(cached_iter), cached_iter, 6, "pango_itemize", "PangoAttrIterator*"); return(C_to_Xen_GList_(pango_itemize(Xen_to_C_PangoContext_(context), Xen_to_C_char_(text), Xen_to_C_int(start_index), Xen_to_C_int(length), Xen_to_C_PangoAttrList_(attrs), Xen_to_C_PangoAttrIterator_(cached_iter)))); } static Xen gxg_pango_coverage_new(void) { #define H_pango_coverage_new "PangoCoverage* pango_coverage_new( void)" return(C_to_Xen_PangoCoverage_(pango_coverage_new())); } static Xen gxg_pango_coverage_ref(Xen coverage) { #define H_pango_coverage_ref "PangoCoverage* pango_coverage_ref(PangoCoverage* coverage)" Xen_check_type(Xen_is_PangoCoverage_(coverage), coverage, 1, "pango_coverage_ref", "PangoCoverage*"); return(C_to_Xen_PangoCoverage_(pango_coverage_ref(Xen_to_C_PangoCoverage_(coverage)))); } static Xen gxg_pango_coverage_unref(Xen coverage) { #define H_pango_coverage_unref "void pango_coverage_unref(PangoCoverage* coverage)" Xen_check_type(Xen_is_PangoCoverage_(coverage), coverage, 1, "pango_coverage_unref", "PangoCoverage*"); pango_coverage_unref(Xen_to_C_PangoCoverage_(coverage)); return(Xen_false); } static Xen gxg_pango_coverage_copy(Xen coverage) { #define H_pango_coverage_copy "PangoCoverage* pango_coverage_copy(PangoCoverage* coverage)" Xen_check_type(Xen_is_PangoCoverage_(coverage), coverage, 1, "pango_coverage_copy", "PangoCoverage*"); return(C_to_Xen_PangoCoverage_(pango_coverage_copy(Xen_to_C_PangoCoverage_(coverage)))); } static Xen gxg_pango_coverage_get(Xen coverage, Xen index) { #define H_pango_coverage_get "PangoCoverageLevel pango_coverage_get(PangoCoverage* coverage, int index)" Xen_check_type(Xen_is_PangoCoverage_(coverage), coverage, 1, "pango_coverage_get", "PangoCoverage*"); Xen_check_type(Xen_is_int(index), index, 2, "pango_coverage_get", "int"); return(C_to_Xen_PangoCoverageLevel(pango_coverage_get(Xen_to_C_PangoCoverage_(coverage), Xen_to_C_int(index)))); } static Xen gxg_pango_coverage_set(Xen coverage, Xen index, Xen level) { #define H_pango_coverage_set "void pango_coverage_set(PangoCoverage* coverage, int index, PangoCoverageLevel level)" Xen_check_type(Xen_is_PangoCoverage_(coverage), coverage, 1, "pango_coverage_set", "PangoCoverage*"); Xen_check_type(Xen_is_int(index), index, 2, "pango_coverage_set", "int"); Xen_check_type(Xen_is_PangoCoverageLevel(level), level, 3, "pango_coverage_set", "PangoCoverageLevel"); pango_coverage_set(Xen_to_C_PangoCoverage_(coverage), Xen_to_C_int(index), Xen_to_C_PangoCoverageLevel(level)); return(Xen_false); } static Xen gxg_pango_coverage_max(Xen coverage, Xen other) { #define H_pango_coverage_max "void pango_coverage_max(PangoCoverage* coverage, PangoCoverage* other)" Xen_check_type(Xen_is_PangoCoverage_(coverage), coverage, 1, "pango_coverage_max", "PangoCoverage*"); Xen_check_type(Xen_is_PangoCoverage_(other), other, 2, "pango_coverage_max", "PangoCoverage*"); pango_coverage_max(Xen_to_C_PangoCoverage_(coverage), Xen_to_C_PangoCoverage_(other)); return(Xen_false); } static Xen gxg_pango_coverage_to_bytes(Xen coverage, Xen ignore_bytes, Xen ignore_n_bytes) { #define H_pango_coverage_to_bytes "void pango_coverage_to_bytes(PangoCoverage* coverage, guchar** [bytes], \ int* [n_bytes])" guchar* ref_bytes = NULL; int ref_n_bytes; Xen_check_type(Xen_is_PangoCoverage_(coverage), coverage, 1, "pango_coverage_to_bytes", "PangoCoverage*"); pango_coverage_to_bytes(Xen_to_C_PangoCoverage_(coverage), &ref_bytes, &ref_n_bytes); return(Xen_list_2(C_to_Xen_guchar_(ref_bytes), C_to_Xen_int(ref_n_bytes))); } static Xen gxg_pango_coverage_from_bytes(Xen bytes, Xen n_bytes) { #define H_pango_coverage_from_bytes "PangoCoverage* pango_coverage_from_bytes(guchar* bytes, int n_bytes)" Xen_check_type(Xen_is_guchar_(bytes), bytes, 1, "pango_coverage_from_bytes", "guchar*"); Xen_check_type(Xen_is_int(n_bytes), n_bytes, 2, "pango_coverage_from_bytes", "int"); return(C_to_Xen_PangoCoverage_(pango_coverage_from_bytes(Xen_to_C_guchar_(bytes), Xen_to_C_int(n_bytes)))); } static Xen gxg_pango_font_description_new(void) { #define H_pango_font_description_new "PangoFontDescription* pango_font_description_new( void)" return(C_to_Xen_PangoFontDescription_(pango_font_description_new())); } static Xen gxg_pango_font_description_copy(Xen desc) { #define H_pango_font_description_copy "PangoFontDescription* pango_font_description_copy(PangoFontDescription* desc)" Xen_check_type(Xen_is_PangoFontDescription_(desc), desc, 1, "pango_font_description_copy", "PangoFontDescription*"); return(C_to_Xen_PangoFontDescription_(pango_font_description_copy(Xen_to_C_PangoFontDescription_(desc)))); } static Xen gxg_pango_font_description_copy_static(Xen desc) { #define H_pango_font_description_copy_static "PangoFontDescription* pango_font_description_copy_static(PangoFontDescription* desc)" Xen_check_type(Xen_is_PangoFontDescription_(desc), desc, 1, "pango_font_description_copy_static", "PangoFontDescription*"); return(C_to_Xen_PangoFontDescription_(pango_font_description_copy_static(Xen_to_C_PangoFontDescription_(desc)))); } static Xen gxg_pango_font_description_hash(Xen desc) { #define H_pango_font_description_hash "guint pango_font_description_hash(PangoFontDescription* desc)" Xen_check_type(Xen_is_PangoFontDescription_(desc), desc, 1, "pango_font_description_hash", "PangoFontDescription*"); return(C_to_Xen_guint(pango_font_description_hash(Xen_to_C_PangoFontDescription_(desc)))); } static Xen gxg_pango_font_description_equal(Xen desc1, Xen desc2) { #define H_pango_font_description_equal "gboolean pango_font_description_equal(PangoFontDescription* desc1, \ PangoFontDescription* desc2)" Xen_check_type(Xen_is_PangoFontDescription_(desc1), desc1, 1, "pango_font_description_equal", "PangoFontDescription*"); Xen_check_type(Xen_is_PangoFontDescription_(desc2), desc2, 2, "pango_font_description_equal", "PangoFontDescription*"); return(C_to_Xen_gboolean(pango_font_description_equal(Xen_to_C_PangoFontDescription_(desc1), Xen_to_C_PangoFontDescription_(desc2)))); } static Xen gxg_pango_font_description_free(Xen desc) { #define H_pango_font_description_free "void pango_font_description_free(PangoFontDescription* desc)" Xen_check_type(Xen_is_PangoFontDescription_(desc), desc, 1, "pango_font_description_free", "PangoFontDescription*"); pango_font_description_free(Xen_to_C_PangoFontDescription_(desc)); return(Xen_false); } static Xen gxg_pango_font_descriptions_free(Xen descs, Xen n_descs) { #define H_pango_font_descriptions_free "void pango_font_descriptions_free(PangoFontDescription** descs, \ int n_descs)" Xen_check_type(Xen_is_PangoFontDescription__(descs), descs, 1, "pango_font_descriptions_free", "PangoFontDescription**"); Xen_check_type(Xen_is_int(n_descs), n_descs, 2, "pango_font_descriptions_free", "int"); pango_font_descriptions_free(Xen_to_C_PangoFontDescription__(descs), Xen_to_C_int(n_descs)); return(Xen_false); } static Xen gxg_pango_font_description_set_family(Xen desc, Xen family) { #define H_pango_font_description_set_family "void pango_font_description_set_family(PangoFontDescription* desc, \ char* family)" Xen_check_type(Xen_is_PangoFontDescription_(desc), desc, 1, "pango_font_description_set_family", "PangoFontDescription*"); Xen_check_type(Xen_is_char_(family), family, 2, "pango_font_description_set_family", "char*"); pango_font_description_set_family(Xen_to_C_PangoFontDescription_(desc), Xen_to_C_char_(family)); return(Xen_false); } static Xen gxg_pango_font_description_set_family_static(Xen desc, Xen family) { #define H_pango_font_description_set_family_static "void pango_font_description_set_family_static(PangoFontDescription* desc, \ char* family)" Xen_check_type(Xen_is_PangoFontDescription_(desc), desc, 1, "pango_font_description_set_family_static", "PangoFontDescription*"); Xen_check_type(Xen_is_char_(family), family, 2, "pango_font_description_set_family_static", "char*"); pango_font_description_set_family_static(Xen_to_C_PangoFontDescription_(desc), Xen_to_C_char_(family)); return(Xen_false); } static Xen gxg_pango_font_description_get_family(Xen desc) { #define H_pango_font_description_get_family "char* pango_font_description_get_family(PangoFontDescription* desc)" Xen_check_type(Xen_is_PangoFontDescription_(desc), desc, 1, "pango_font_description_get_family", "PangoFontDescription*"); return(C_to_Xen_char_(pango_font_description_get_family(Xen_to_C_PangoFontDescription_(desc)))); } static Xen gxg_pango_font_description_set_style(Xen desc, Xen style) { #define H_pango_font_description_set_style "void pango_font_description_set_style(PangoFontDescription* desc, \ PangoStyle style)" Xen_check_type(Xen_is_PangoFontDescription_(desc), desc, 1, "pango_font_description_set_style", "PangoFontDescription*"); Xen_check_type(Xen_is_PangoStyle(style), style, 2, "pango_font_description_set_style", "PangoStyle"); pango_font_description_set_style(Xen_to_C_PangoFontDescription_(desc), Xen_to_C_PangoStyle(style)); return(Xen_false); } static Xen gxg_pango_font_description_get_style(Xen desc) { #define H_pango_font_description_get_style "PangoStyle pango_font_description_get_style(PangoFontDescription* desc)" Xen_check_type(Xen_is_PangoFontDescription_(desc), desc, 1, "pango_font_description_get_style", "PangoFontDescription*"); return(C_to_Xen_PangoStyle(pango_font_description_get_style(Xen_to_C_PangoFontDescription_(desc)))); } static Xen gxg_pango_font_description_set_variant(Xen desc, Xen variant) { #define H_pango_font_description_set_variant "void pango_font_description_set_variant(PangoFontDescription* desc, \ PangoVariant variant)" Xen_check_type(Xen_is_PangoFontDescription_(desc), desc, 1, "pango_font_description_set_variant", "PangoFontDescription*"); Xen_check_type(Xen_is_PangoVariant(variant), variant, 2, "pango_font_description_set_variant", "PangoVariant"); pango_font_description_set_variant(Xen_to_C_PangoFontDescription_(desc), Xen_to_C_PangoVariant(variant)); return(Xen_false); } static Xen gxg_pango_font_description_get_variant(Xen desc) { #define H_pango_font_description_get_variant "PangoVariant pango_font_description_get_variant(PangoFontDescription* desc)" Xen_check_type(Xen_is_PangoFontDescription_(desc), desc, 1, "pango_font_description_get_variant", "PangoFontDescription*"); return(C_to_Xen_PangoVariant(pango_font_description_get_variant(Xen_to_C_PangoFontDescription_(desc)))); } static Xen gxg_pango_font_description_set_weight(Xen desc, Xen weight) { #define H_pango_font_description_set_weight "void pango_font_description_set_weight(PangoFontDescription* desc, \ PangoWeight weight)" Xen_check_type(Xen_is_PangoFontDescription_(desc), desc, 1, "pango_font_description_set_weight", "PangoFontDescription*"); Xen_check_type(Xen_is_PangoWeight(weight), weight, 2, "pango_font_description_set_weight", "PangoWeight"); pango_font_description_set_weight(Xen_to_C_PangoFontDescription_(desc), Xen_to_C_PangoWeight(weight)); return(Xen_false); } static Xen gxg_pango_font_description_get_weight(Xen desc) { #define H_pango_font_description_get_weight "PangoWeight pango_font_description_get_weight(PangoFontDescription* desc)" Xen_check_type(Xen_is_PangoFontDescription_(desc), desc, 1, "pango_font_description_get_weight", "PangoFontDescription*"); return(C_to_Xen_PangoWeight(pango_font_description_get_weight(Xen_to_C_PangoFontDescription_(desc)))); } static Xen gxg_pango_font_description_set_stretch(Xen desc, Xen stretch) { #define H_pango_font_description_set_stretch "void pango_font_description_set_stretch(PangoFontDescription* desc, \ PangoStretch stretch)" Xen_check_type(Xen_is_PangoFontDescription_(desc), desc, 1, "pango_font_description_set_stretch", "PangoFontDescription*"); Xen_check_type(Xen_is_PangoStretch(stretch), stretch, 2, "pango_font_description_set_stretch", "PangoStretch"); pango_font_description_set_stretch(Xen_to_C_PangoFontDescription_(desc), Xen_to_C_PangoStretch(stretch)); return(Xen_false); } static Xen gxg_pango_font_description_get_stretch(Xen desc) { #define H_pango_font_description_get_stretch "PangoStretch pango_font_description_get_stretch(PangoFontDescription* desc)" Xen_check_type(Xen_is_PangoFontDescription_(desc), desc, 1, "pango_font_description_get_stretch", "PangoFontDescription*"); return(C_to_Xen_PangoStretch(pango_font_description_get_stretch(Xen_to_C_PangoFontDescription_(desc)))); } static Xen gxg_pango_font_description_set_size(Xen desc, Xen size) { #define H_pango_font_description_set_size "void pango_font_description_set_size(PangoFontDescription* desc, \ gint size)" Xen_check_type(Xen_is_PangoFontDescription_(desc), desc, 1, "pango_font_description_set_size", "PangoFontDescription*"); Xen_check_type(Xen_is_gint(size), size, 2, "pango_font_description_set_size", "gint"); pango_font_description_set_size(Xen_to_C_PangoFontDescription_(desc), Xen_to_C_gint(size)); return(Xen_false); } static Xen gxg_pango_font_description_get_size(Xen desc) { #define H_pango_font_description_get_size "gint pango_font_description_get_size(PangoFontDescription* desc)" Xen_check_type(Xen_is_PangoFontDescription_(desc), desc, 1, "pango_font_description_get_size", "PangoFontDescription*"); return(C_to_Xen_gint(pango_font_description_get_size(Xen_to_C_PangoFontDescription_(desc)))); } static Xen gxg_pango_font_description_get_set_fields(Xen desc) { #define H_pango_font_description_get_set_fields "PangoFontMask pango_font_description_get_set_fields(PangoFontDescription* desc)" Xen_check_type(Xen_is_PangoFontDescription_(desc), desc, 1, "pango_font_description_get_set_fields", "PangoFontDescription*"); return(C_to_Xen_PangoFontMask(pango_font_description_get_set_fields(Xen_to_C_PangoFontDescription_(desc)))); } static Xen gxg_pango_font_description_unset_fields(Xen desc, Xen to_unset) { #define H_pango_font_description_unset_fields "void pango_font_description_unset_fields(PangoFontDescription* desc, \ PangoFontMask to_unset)" Xen_check_type(Xen_is_PangoFontDescription_(desc), desc, 1, "pango_font_description_unset_fields", "PangoFontDescription*"); Xen_check_type(Xen_is_PangoFontMask(to_unset), to_unset, 2, "pango_font_description_unset_fields", "PangoFontMask"); pango_font_description_unset_fields(Xen_to_C_PangoFontDescription_(desc), Xen_to_C_PangoFontMask(to_unset)); return(Xen_false); } static Xen gxg_pango_font_description_merge(Xen desc, Xen desc_to_merge, Xen replace_existing) { #define H_pango_font_description_merge "void pango_font_description_merge(PangoFontDescription* desc, \ PangoFontDescription* desc_to_merge, gboolean replace_existing)" Xen_check_type(Xen_is_PangoFontDescription_(desc), desc, 1, "pango_font_description_merge", "PangoFontDescription*"); Xen_check_type(Xen_is_PangoFontDescription_(desc_to_merge), desc_to_merge, 2, "pango_font_description_merge", "PangoFontDescription*"); Xen_check_type(Xen_is_gboolean(replace_existing), replace_existing, 3, "pango_font_description_merge", "gboolean"); pango_font_description_merge(Xen_to_C_PangoFontDescription_(desc), Xen_to_C_PangoFontDescription_(desc_to_merge), Xen_to_C_gboolean(replace_existing)); return(Xen_false); } static Xen gxg_pango_font_description_merge_static(Xen desc, Xen desc_to_merge, Xen replace_existing) { #define H_pango_font_description_merge_static "void pango_font_description_merge_static(PangoFontDescription* desc, \ PangoFontDescription* desc_to_merge, gboolean replace_existing)" Xen_check_type(Xen_is_PangoFontDescription_(desc), desc, 1, "pango_font_description_merge_static", "PangoFontDescription*"); Xen_check_type(Xen_is_PangoFontDescription_(desc_to_merge), desc_to_merge, 2, "pango_font_description_merge_static", "PangoFontDescription*"); Xen_check_type(Xen_is_gboolean(replace_existing), replace_existing, 3, "pango_font_description_merge_static", "gboolean"); pango_font_description_merge_static(Xen_to_C_PangoFontDescription_(desc), Xen_to_C_PangoFontDescription_(desc_to_merge), Xen_to_C_gboolean(replace_existing)); return(Xen_false); } static Xen gxg_pango_font_description_better_match(Xen desc, Xen old_match, Xen new_match) { #define H_pango_font_description_better_match "gboolean pango_font_description_better_match(PangoFontDescription* desc, \ PangoFontDescription* old_match, PangoFontDescription* new_match)" Xen_check_type(Xen_is_PangoFontDescription_(desc), desc, 1, "pango_font_description_better_match", "PangoFontDescription*"); Xen_check_type(Xen_is_PangoFontDescription_(old_match), old_match, 2, "pango_font_description_better_match", "PangoFontDescription*"); Xen_check_type(Xen_is_PangoFontDescription_(new_match), new_match, 3, "pango_font_description_better_match", "PangoFontDescription*"); return(C_to_Xen_gboolean(pango_font_description_better_match(Xen_to_C_PangoFontDescription_(desc), Xen_to_C_PangoFontDescription_(old_match), Xen_to_C_PangoFontDescription_(new_match)))); } static Xen gxg_pango_font_description_from_string(Xen str) { #define H_pango_font_description_from_string "PangoFontDescription* pango_font_description_from_string(char* str)" Xen_check_type(Xen_is_char_(str), str, 1, "pango_font_description_from_string", "char*"); return(C_to_Xen_PangoFontDescription_(pango_font_description_from_string(Xen_to_C_char_(str)))); } static Xen gxg_pango_font_description_to_string(Xen desc) { #define H_pango_font_description_to_string "char* pango_font_description_to_string(PangoFontDescription* desc)" Xen_check_type(Xen_is_PangoFontDescription_(desc), desc, 1, "pango_font_description_to_string", "PangoFontDescription*"); { char* result; Xen rtn; result = pango_font_description_to_string(Xen_to_C_PangoFontDescription_(desc)); rtn = C_to_Xen_char_(result); g_free(result); return(rtn); } } static Xen gxg_pango_font_description_to_filename(Xen desc) { #define H_pango_font_description_to_filename "char* pango_font_description_to_filename(PangoFontDescription* desc)" Xen_check_type(Xen_is_PangoFontDescription_(desc), desc, 1, "pango_font_description_to_filename", "PangoFontDescription*"); { char* result; Xen rtn; result = pango_font_description_to_filename(Xen_to_C_PangoFontDescription_(desc)); rtn = C_to_Xen_char_(result); g_free(result); return(rtn); } } static Xen gxg_pango_font_metrics_ref(Xen metrics) { #define H_pango_font_metrics_ref "PangoFontMetrics* pango_font_metrics_ref(PangoFontMetrics* metrics)" Xen_check_type(Xen_is_PangoFontMetrics_(metrics), metrics, 1, "pango_font_metrics_ref", "PangoFontMetrics*"); return(C_to_Xen_PangoFontMetrics_(pango_font_metrics_ref(Xen_to_C_PangoFontMetrics_(metrics)))); } static Xen gxg_pango_font_metrics_unref(Xen metrics) { #define H_pango_font_metrics_unref "void pango_font_metrics_unref(PangoFontMetrics* metrics)" Xen_check_type(Xen_is_PangoFontMetrics_(metrics), metrics, 1, "pango_font_metrics_unref", "PangoFontMetrics*"); pango_font_metrics_unref(Xen_to_C_PangoFontMetrics_(metrics)); return(Xen_false); } static Xen gxg_pango_font_metrics_get_ascent(Xen metrics) { #define H_pango_font_metrics_get_ascent "int pango_font_metrics_get_ascent(PangoFontMetrics* metrics)" Xen_check_type(Xen_is_PangoFontMetrics_(metrics), metrics, 1, "pango_font_metrics_get_ascent", "PangoFontMetrics*"); return(C_to_Xen_int(pango_font_metrics_get_ascent(Xen_to_C_PangoFontMetrics_(metrics)))); } static Xen gxg_pango_font_metrics_get_descent(Xen metrics) { #define H_pango_font_metrics_get_descent "int pango_font_metrics_get_descent(PangoFontMetrics* metrics)" Xen_check_type(Xen_is_PangoFontMetrics_(metrics), metrics, 1, "pango_font_metrics_get_descent", "PangoFontMetrics*"); return(C_to_Xen_int(pango_font_metrics_get_descent(Xen_to_C_PangoFontMetrics_(metrics)))); } static Xen gxg_pango_font_metrics_get_approximate_char_width(Xen metrics) { #define H_pango_font_metrics_get_approximate_char_width "int pango_font_metrics_get_approximate_char_width(PangoFontMetrics* metrics)" Xen_check_type(Xen_is_PangoFontMetrics_(metrics), metrics, 1, "pango_font_metrics_get_approximate_char_width", "PangoFontMetrics*"); return(C_to_Xen_int(pango_font_metrics_get_approximate_char_width(Xen_to_C_PangoFontMetrics_(metrics)))); } static Xen gxg_pango_font_metrics_get_approximate_digit_width(Xen metrics) { #define H_pango_font_metrics_get_approximate_digit_width "int pango_font_metrics_get_approximate_digit_width(PangoFontMetrics* metrics)" Xen_check_type(Xen_is_PangoFontMetrics_(metrics), metrics, 1, "pango_font_metrics_get_approximate_digit_width", "PangoFontMetrics*"); return(C_to_Xen_int(pango_font_metrics_get_approximate_digit_width(Xen_to_C_PangoFontMetrics_(metrics)))); } static Xen gxg_pango_font_family_list_faces(Xen family, Xen ignore_faces, Xen ignore_n_faces) { #define H_pango_font_family_list_faces "void pango_font_family_list_faces(PangoFontFamily* family, \ PangoFontFace*** [faces], int* [n_faces])" PangoFontFace** ref_faces = NULL; int ref_n_faces; Xen_check_type(Xen_is_PangoFontFamily_(family), family, 1, "pango_font_family_list_faces", "PangoFontFamily*"); pango_font_family_list_faces(Xen_to_C_PangoFontFamily_(family), &ref_faces, &ref_n_faces); return(Xen_list_2(C_to_Xen_PangoFontFace__(ref_faces), C_to_Xen_int(ref_n_faces))); } static Xen gxg_pango_font_family_get_name(Xen family) { #define H_pango_font_family_get_name "char* pango_font_family_get_name(PangoFontFamily* family)" Xen_check_type(Xen_is_PangoFontFamily_(family), family, 1, "pango_font_family_get_name", "PangoFontFamily*"); return(C_to_Xen_char_(pango_font_family_get_name(Xen_to_C_PangoFontFamily_(family)))); } static Xen gxg_pango_font_face_describe(Xen face) { #define H_pango_font_face_describe "PangoFontDescription* pango_font_face_describe(PangoFontFace* face)" Xen_check_type(Xen_is_PangoFontFace_(face), face, 1, "pango_font_face_describe", "PangoFontFace*"); return(C_to_Xen_PangoFontDescription_(pango_font_face_describe(Xen_to_C_PangoFontFace_(face)))); } static Xen gxg_pango_font_face_get_face_name(Xen face) { #define H_pango_font_face_get_face_name "char* pango_font_face_get_face_name(PangoFontFace* face)" Xen_check_type(Xen_is_PangoFontFace_(face), face, 1, "pango_font_face_get_face_name", "PangoFontFace*"); return(C_to_Xen_char_(pango_font_face_get_face_name(Xen_to_C_PangoFontFace_(face)))); } static Xen gxg_pango_font_describe(Xen font) { #define H_pango_font_describe "PangoFontDescription* pango_font_describe(PangoFont* font)" Xen_check_type(Xen_is_PangoFont_(font), font, 1, "pango_font_describe", "PangoFont*"); return(C_to_Xen_PangoFontDescription_(pango_font_describe(Xen_to_C_PangoFont_(font)))); } static Xen gxg_pango_font_get_coverage(Xen font, Xen language) { #define H_pango_font_get_coverage "PangoCoverage* pango_font_get_coverage(PangoFont* font, PangoLanguage* language)" Xen_check_type(Xen_is_PangoFont_(font), font, 1, "pango_font_get_coverage", "PangoFont*"); Xen_check_type(Xen_is_PangoLanguage_(language), language, 2, "pango_font_get_coverage", "PangoLanguage*"); return(C_to_Xen_PangoCoverage_(pango_font_get_coverage(Xen_to_C_PangoFont_(font), Xen_to_C_PangoLanguage_(language)))); } static Xen gxg_pango_font_get_metrics(Xen font, Xen language) { #define H_pango_font_get_metrics "PangoFontMetrics* pango_font_get_metrics(PangoFont* font, PangoLanguage* language)" Xen_check_type(Xen_is_PangoFont_(font), font, 1, "pango_font_get_metrics", "PangoFont*"); Xen_check_type(Xen_is_PangoLanguage_(language), language, 2, "pango_font_get_metrics", "PangoLanguage*"); return(C_to_Xen_PangoFontMetrics_(pango_font_get_metrics(Xen_to_C_PangoFont_(font), Xen_to_C_PangoLanguage_(language)))); } static Xen gxg_pango_font_get_glyph_extents(Xen font, Xen glyph, Xen ink_rect, Xen logical_rect) { #define H_pango_font_get_glyph_extents "void pango_font_get_glyph_extents(PangoFont* font, PangoGlyph glyph, \ PangoRectangle* ink_rect, PangoRectangle* logical_rect)" Xen_check_type(Xen_is_PangoFont_(font), font, 1, "pango_font_get_glyph_extents", "PangoFont*"); Xen_check_type(Xen_is_PangoGlyph(glyph), glyph, 2, "pango_font_get_glyph_extents", "PangoGlyph"); Xen_check_type(Xen_is_PangoRectangle_(ink_rect), ink_rect, 3, "pango_font_get_glyph_extents", "PangoRectangle*"); Xen_check_type(Xen_is_PangoRectangle_(logical_rect), logical_rect, 4, "pango_font_get_glyph_extents", "PangoRectangle*"); pango_font_get_glyph_extents(Xen_to_C_PangoFont_(font), Xen_to_C_PangoGlyph(glyph), Xen_to_C_PangoRectangle_(ink_rect), Xen_to_C_PangoRectangle_(logical_rect)); return(Xen_false); } static Xen gxg_pango_font_map_load_font(Xen fontmap, Xen context, Xen desc) { #define H_pango_font_map_load_font "PangoFont* pango_font_map_load_font(PangoFontMap* fontmap, PangoContext* context, \ PangoFontDescription* desc)" Xen_check_type(Xen_is_PangoFontMap_(fontmap), fontmap, 1, "pango_font_map_load_font", "PangoFontMap*"); Xen_check_type(Xen_is_PangoContext_(context), context, 2, "pango_font_map_load_font", "PangoContext*"); Xen_check_type(Xen_is_PangoFontDescription_(desc), desc, 3, "pango_font_map_load_font", "PangoFontDescription*"); return(C_to_Xen_PangoFont_(pango_font_map_load_font(Xen_to_C_PangoFontMap_(fontmap), Xen_to_C_PangoContext_(context), Xen_to_C_PangoFontDescription_(desc)))); } static Xen gxg_pango_font_map_load_fontset(Xen fontmap, Xen context, Xen desc, Xen language) { #define H_pango_font_map_load_fontset "PangoFontset* pango_font_map_load_fontset(PangoFontMap* fontmap, \ PangoContext* context, PangoFontDescription* desc, PangoLanguage* language)" Xen_check_type(Xen_is_PangoFontMap_(fontmap), fontmap, 1, "pango_font_map_load_fontset", "PangoFontMap*"); Xen_check_type(Xen_is_PangoContext_(context), context, 2, "pango_font_map_load_fontset", "PangoContext*"); Xen_check_type(Xen_is_PangoFontDescription_(desc), desc, 3, "pango_font_map_load_fontset", "PangoFontDescription*"); Xen_check_type(Xen_is_PangoLanguage_(language), language, 4, "pango_font_map_load_fontset", "PangoLanguage*"); return(C_to_Xen_PangoFontset_(pango_font_map_load_fontset(Xen_to_C_PangoFontMap_(fontmap), Xen_to_C_PangoContext_(context), Xen_to_C_PangoFontDescription_(desc), Xen_to_C_PangoLanguage_(language)))); } static Xen gxg_pango_font_map_list_families(Xen fontmap, Xen ignore_families, Xen ignore_n_families) { #define H_pango_font_map_list_families "void pango_font_map_list_families(PangoFontMap* fontmap, PangoFontFamily*** [families], \ int* [n_families])" PangoFontFamily** ref_families = NULL; int ref_n_families; Xen_check_type(Xen_is_PangoFontMap_(fontmap), fontmap, 1, "pango_font_map_list_families", "PangoFontMap*"); pango_font_map_list_families(Xen_to_C_PangoFontMap_(fontmap), &ref_families, &ref_n_families); return(Xen_list_2(C_to_Xen_PangoFontFamily__(ref_families), C_to_Xen_int(ref_n_families))); } static Xen gxg_pango_glyph_string_new(void) { #define H_pango_glyph_string_new "PangoGlyphString* pango_glyph_string_new( void)" return(C_to_Xen_PangoGlyphString_(pango_glyph_string_new())); } static Xen gxg_pango_glyph_string_set_size(Xen string, Xen new_len) { #define H_pango_glyph_string_set_size "void pango_glyph_string_set_size(PangoGlyphString* string, gint new_len)" Xen_check_type(Xen_is_PangoGlyphString_(string), string, 1, "pango_glyph_string_set_size", "PangoGlyphString*"); Xen_check_type(Xen_is_gint(new_len), new_len, 2, "pango_glyph_string_set_size", "gint"); pango_glyph_string_set_size(Xen_to_C_PangoGlyphString_(string), Xen_to_C_gint(new_len)); return(Xen_false); } static Xen gxg_pango_glyph_string_copy(Xen string) { #define H_pango_glyph_string_copy "PangoGlyphString* pango_glyph_string_copy(PangoGlyphString* string)" Xen_check_type(Xen_is_PangoGlyphString_(string), string, 1, "pango_glyph_string_copy", "PangoGlyphString*"); return(C_to_Xen_PangoGlyphString_(pango_glyph_string_copy(Xen_to_C_PangoGlyphString_(string)))); } static Xen gxg_pango_glyph_string_free(Xen string) { #define H_pango_glyph_string_free "void pango_glyph_string_free(PangoGlyphString* string)" Xen_check_type(Xen_is_PangoGlyphString_(string), string, 1, "pango_glyph_string_free", "PangoGlyphString*"); pango_glyph_string_free(Xen_to_C_PangoGlyphString_(string)); return(Xen_false); } static Xen gxg_pango_glyph_string_extents(Xen glyphs, Xen font, Xen ink_rect, Xen logical_rect) { #define H_pango_glyph_string_extents "void pango_glyph_string_extents(PangoGlyphString* glyphs, PangoFont* font, \ PangoRectangle* ink_rect, PangoRectangle* logical_rect)" Xen_check_type(Xen_is_PangoGlyphString_(glyphs), glyphs, 1, "pango_glyph_string_extents", "PangoGlyphString*"); Xen_check_type(Xen_is_PangoFont_(font), font, 2, "pango_glyph_string_extents", "PangoFont*"); Xen_check_type(Xen_is_PangoRectangle_(ink_rect), ink_rect, 3, "pango_glyph_string_extents", "PangoRectangle*"); Xen_check_type(Xen_is_PangoRectangle_(logical_rect), logical_rect, 4, "pango_glyph_string_extents", "PangoRectangle*"); pango_glyph_string_extents(Xen_to_C_PangoGlyphString_(glyphs), Xen_to_C_PangoFont_(font), Xen_to_C_PangoRectangle_(ink_rect), Xen_to_C_PangoRectangle_(logical_rect)); return(Xen_false); } static Xen gxg_pango_glyph_string_extents_range(Xen glyphs, Xen start, Xen end, Xen font, Xen ink_rect, Xen logical_rect) { #define H_pango_glyph_string_extents_range "void pango_glyph_string_extents_range(PangoGlyphString* glyphs, \ int start, int end, PangoFont* font, PangoRectangle* ink_rect, PangoRectangle* logical_rect)" Xen_check_type(Xen_is_PangoGlyphString_(glyphs), glyphs, 1, "pango_glyph_string_extents_range", "PangoGlyphString*"); Xen_check_type(Xen_is_int(start), start, 2, "pango_glyph_string_extents_range", "int"); Xen_check_type(Xen_is_int(end), end, 3, "pango_glyph_string_extents_range", "int"); Xen_check_type(Xen_is_PangoFont_(font), font, 4, "pango_glyph_string_extents_range", "PangoFont*"); Xen_check_type(Xen_is_PangoRectangle_(ink_rect), ink_rect, 5, "pango_glyph_string_extents_range", "PangoRectangle*"); Xen_check_type(Xen_is_PangoRectangle_(logical_rect), logical_rect, 6, "pango_glyph_string_extents_range", "PangoRectangle*"); pango_glyph_string_extents_range(Xen_to_C_PangoGlyphString_(glyphs), Xen_to_C_int(start), Xen_to_C_int(end), Xen_to_C_PangoFont_(font), Xen_to_C_PangoRectangle_(ink_rect), Xen_to_C_PangoRectangle_(logical_rect)); return(Xen_false); } static Xen gxg_pango_glyph_string_get_logical_widths(Xen glyphs, Xen text, Xen length, Xen embedding_level, Xen ignore_logical_widths) { #define H_pango_glyph_string_get_logical_widths "void pango_glyph_string_get_logical_widths(PangoGlyphString* glyphs, \ char* text, int length, int embedding_level, int* [logical_widths])" int ref_logical_widths; Xen_check_type(Xen_is_PangoGlyphString_(glyphs), glyphs, 1, "pango_glyph_string_get_logical_widths", "PangoGlyphString*"); Xen_check_type(Xen_is_char_(text), text, 2, "pango_glyph_string_get_logical_widths", "char*"); Xen_check_type(Xen_is_int(length), length, 3, "pango_glyph_string_get_logical_widths", "int"); Xen_check_type(Xen_is_int(embedding_level), embedding_level, 4, "pango_glyph_string_get_logical_widths", "int"); pango_glyph_string_get_logical_widths(Xen_to_C_PangoGlyphString_(glyphs), Xen_to_C_char_(text), Xen_to_C_int(length), Xen_to_C_int(embedding_level), &ref_logical_widths); return(Xen_list_1(C_to_Xen_int(ref_logical_widths))); } static Xen gxg_pango_glyph_string_index_to_x(Xen glyphs, Xen text, Xen length, Xen analysis, Xen index, Xen trailing, Xen ignore_x_pos) { #define H_pango_glyph_string_index_to_x "void pango_glyph_string_index_to_x(PangoGlyphString* glyphs, \ char* text, int length, PangoAnalysis* analysis, int index, gboolean trailing, int* [x_pos])" int ref_x_pos; Xen_check_type(Xen_is_PangoGlyphString_(glyphs), glyphs, 1, "pango_glyph_string_index_to_x", "PangoGlyphString*"); Xen_check_type(Xen_is_char_(text), text, 2, "pango_glyph_string_index_to_x", "char*"); Xen_check_type(Xen_is_int(length), length, 3, "pango_glyph_string_index_to_x", "int"); Xen_check_type(Xen_is_PangoAnalysis_(analysis), analysis, 4, "pango_glyph_string_index_to_x", "PangoAnalysis*"); Xen_check_type(Xen_is_int(index), index, 5, "pango_glyph_string_index_to_x", "int"); Xen_check_type(Xen_is_gboolean(trailing), trailing, 6, "pango_glyph_string_index_to_x", "gboolean"); pango_glyph_string_index_to_x(Xen_to_C_PangoGlyphString_(glyphs), Xen_to_C_char_(text), Xen_to_C_int(length), Xen_to_C_PangoAnalysis_(analysis), Xen_to_C_int(index), Xen_to_C_gboolean(trailing), &ref_x_pos); return(Xen_list_1(C_to_Xen_int(ref_x_pos))); } static Xen gxg_pango_glyph_string_x_to_index(Xen glyphs, Xen text, Xen length, Xen analysis, Xen x_pos, Xen ignore_index, Xen ignore_trailing) { #define H_pango_glyph_string_x_to_index "void pango_glyph_string_x_to_index(PangoGlyphString* glyphs, \ char* text, int length, PangoAnalysis* analysis, int x_pos, int* [index], int* [trailing])" int ref_index; int ref_trailing; Xen_check_type(Xen_is_PangoGlyphString_(glyphs), glyphs, 1, "pango_glyph_string_x_to_index", "PangoGlyphString*"); Xen_check_type(Xen_is_char_(text), text, 2, "pango_glyph_string_x_to_index", "char*"); Xen_check_type(Xen_is_int(length), length, 3, "pango_glyph_string_x_to_index", "int"); Xen_check_type(Xen_is_PangoAnalysis_(analysis), analysis, 4, "pango_glyph_string_x_to_index", "PangoAnalysis*"); Xen_check_type(Xen_is_int(x_pos), x_pos, 5, "pango_glyph_string_x_to_index", "int"); pango_glyph_string_x_to_index(Xen_to_C_PangoGlyphString_(glyphs), Xen_to_C_char_(text), Xen_to_C_int(length), Xen_to_C_PangoAnalysis_(analysis), Xen_to_C_int(x_pos), &ref_index, &ref_trailing); return(Xen_list_2(C_to_Xen_int(ref_index), C_to_Xen_int(ref_trailing))); } static Xen gxg_pango_shape(Xen text, Xen length, Xen analysis, Xen glyphs) { #define H_pango_shape "void pango_shape(gchar* text, gint length, PangoAnalysis* analysis, PangoGlyphString* glyphs)" Xen_check_type(Xen_is_gchar_(text), text, 1, "pango_shape", "gchar*"); Xen_check_type(Xen_is_gint(length), length, 2, "pango_shape", "gint"); Xen_check_type(Xen_is_PangoAnalysis_(analysis), analysis, 3, "pango_shape", "PangoAnalysis*"); Xen_check_type(Xen_is_PangoGlyphString_(glyphs), glyphs, 4, "pango_shape", "PangoGlyphString*"); pango_shape(Xen_to_C_gchar_(text), Xen_to_C_gint(length), Xen_to_C_PangoAnalysis_(analysis), Xen_to_C_PangoGlyphString_(glyphs)); return(Xen_false); } static Xen gxg_pango_reorder_items(Xen logical_items) { #define H_pango_reorder_items "GList* pango_reorder_items(GList* logical_items)" Xen_check_type(Xen_is_GList_(logical_items), logical_items, 1, "pango_reorder_items", "GList*"); return(C_to_Xen_GList_(pango_reorder_items(Xen_to_C_GList_(logical_items)))); } static Xen gxg_pango_item_new(void) { #define H_pango_item_new "PangoItem* pango_item_new( void)" return(C_to_Xen_PangoItem_(pango_item_new())); } static Xen gxg_pango_item_copy(Xen item) { #define H_pango_item_copy "PangoItem* pango_item_copy(PangoItem* item)" Xen_check_type(Xen_is_PangoItem_(item), item, 1, "pango_item_copy", "PangoItem*"); return(C_to_Xen_PangoItem_(pango_item_copy(Xen_to_C_PangoItem_(item)))); } static Xen gxg_pango_item_free(Xen item) { #define H_pango_item_free "void pango_item_free(PangoItem* item)" Xen_check_type(Xen_is_PangoItem_(item), item, 1, "pango_item_free", "PangoItem*"); pango_item_free(Xen_to_C_PangoItem_(item)); return(Xen_false); } static Xen gxg_pango_item_split(Xen orig, Xen split_index, Xen split_offset) { #define H_pango_item_split "PangoItem* pango_item_split(PangoItem* orig, int split_index, int split_offset)" Xen_check_type(Xen_is_PangoItem_(orig), orig, 1, "pango_item_split", "PangoItem*"); Xen_check_type(Xen_is_int(split_index), split_index, 2, "pango_item_split", "int"); Xen_check_type(Xen_is_int(split_offset), split_offset, 3, "pango_item_split", "int"); return(C_to_Xen_PangoItem_(pango_item_split(Xen_to_C_PangoItem_(orig), Xen_to_C_int(split_index), Xen_to_C_int(split_offset)))); } static Xen gxg_pango_layout_new(Xen context) { #define H_pango_layout_new "PangoLayout* pango_layout_new(PangoContext* context)" Xen_check_type(Xen_is_PangoContext_(context), context, 1, "pango_layout_new", "PangoContext*"); return(C_to_Xen_PangoLayout_(pango_layout_new(Xen_to_C_PangoContext_(context)))); } static Xen gxg_pango_layout_copy(Xen src) { #define H_pango_layout_copy "PangoLayout* pango_layout_copy(PangoLayout* src)" Xen_check_type(Xen_is_PangoLayout_(src), src, 1, "pango_layout_copy", "PangoLayout*"); return(C_to_Xen_PangoLayout_(pango_layout_copy(Xen_to_C_PangoLayout_(src)))); } static Xen gxg_pango_layout_get_context(Xen layout) { #define H_pango_layout_get_context "PangoContext* pango_layout_get_context(PangoLayout* layout)" Xen_check_type(Xen_is_PangoLayout_(layout), layout, 1, "pango_layout_get_context", "PangoLayout*"); return(C_to_Xen_PangoContext_(pango_layout_get_context(Xen_to_C_PangoLayout_(layout)))); } static Xen gxg_pango_layout_set_attributes(Xen layout, Xen attrs) { #define H_pango_layout_set_attributes "void pango_layout_set_attributes(PangoLayout* layout, PangoAttrList* attrs)" Xen_check_type(Xen_is_PangoLayout_(layout), layout, 1, "pango_layout_set_attributes", "PangoLayout*"); Xen_check_type(Xen_is_PangoAttrList_(attrs), attrs, 2, "pango_layout_set_attributes", "PangoAttrList*"); pango_layout_set_attributes(Xen_to_C_PangoLayout_(layout), Xen_to_C_PangoAttrList_(attrs)); return(Xen_false); } static Xen gxg_pango_layout_get_attributes(Xen layout) { #define H_pango_layout_get_attributes "PangoAttrList* pango_layout_get_attributes(PangoLayout* layout)" Xen_check_type(Xen_is_PangoLayout_(layout), layout, 1, "pango_layout_get_attributes", "PangoLayout*"); return(C_to_Xen_PangoAttrList_(pango_layout_get_attributes(Xen_to_C_PangoLayout_(layout)))); } static Xen gxg_pango_layout_set_text(Xen layout, Xen text, Xen length) { #define H_pango_layout_set_text "void pango_layout_set_text(PangoLayout* layout, char* text, int length)" Xen_check_type(Xen_is_PangoLayout_(layout), layout, 1, "pango_layout_set_text", "PangoLayout*"); Xen_check_type(Xen_is_char_(text), text, 2, "pango_layout_set_text", "char*"); Xen_check_type(Xen_is_int(length), length, 3, "pango_layout_set_text", "int"); pango_layout_set_text(Xen_to_C_PangoLayout_(layout), Xen_to_C_char_(text), Xen_to_C_int(length)); return(Xen_false); } static Xen gxg_pango_layout_get_text(Xen layout) { #define H_pango_layout_get_text "char* pango_layout_get_text(PangoLayout* layout)" Xen_check_type(Xen_is_PangoLayout_(layout), layout, 1, "pango_layout_get_text", "PangoLayout*"); return(C_to_Xen_char_(pango_layout_get_text(Xen_to_C_PangoLayout_(layout)))); } static Xen gxg_pango_layout_set_markup(Xen layout, Xen markup, Xen length) { #define H_pango_layout_set_markup "void pango_layout_set_markup(PangoLayout* layout, char* markup, \ int length)" Xen_check_type(Xen_is_PangoLayout_(layout), layout, 1, "pango_layout_set_markup", "PangoLayout*"); Xen_check_type(Xen_is_char_(markup), markup, 2, "pango_layout_set_markup", "char*"); Xen_check_type(Xen_is_int(length), length, 3, "pango_layout_set_markup", "int"); pango_layout_set_markup(Xen_to_C_PangoLayout_(layout), Xen_to_C_char_(markup), Xen_to_C_int(length)); return(Xen_false); } static Xen gxg_pango_layout_set_markup_with_accel(Xen layout, Xen markup, Xen length, Xen accel_marker, Xen accel_char) { #define H_pango_layout_set_markup_with_accel "void pango_layout_set_markup_with_accel(PangoLayout* layout, \ char* markup, int length, gunichar accel_marker, gunichar* accel_char)" Xen_check_type(Xen_is_PangoLayout_(layout), layout, 1, "pango_layout_set_markup_with_accel", "PangoLayout*"); Xen_check_type(Xen_is_char_(markup), markup, 2, "pango_layout_set_markup_with_accel", "char*"); Xen_check_type(Xen_is_int(length), length, 3, "pango_layout_set_markup_with_accel", "int"); Xen_check_type(Xen_is_gunichar(accel_marker), accel_marker, 4, "pango_layout_set_markup_with_accel", "gunichar"); Xen_check_type(Xen_is_gunichar_(accel_char), accel_char, 5, "pango_layout_set_markup_with_accel", "gunichar*"); pango_layout_set_markup_with_accel(Xen_to_C_PangoLayout_(layout), Xen_to_C_char_(markup), Xen_to_C_int(length), Xen_to_C_gunichar(accel_marker), Xen_to_C_gunichar_(accel_char)); return(Xen_false); } static Xen gxg_pango_layout_set_font_description(Xen layout, Xen desc) { #define H_pango_layout_set_font_description "void pango_layout_set_font_description(PangoLayout* layout, \ PangoFontDescription* desc)" Xen_check_type(Xen_is_PangoLayout_(layout), layout, 1, "pango_layout_set_font_description", "PangoLayout*"); Xen_check_type(Xen_is_PangoFontDescription_(desc), desc, 2, "pango_layout_set_font_description", "PangoFontDescription*"); pango_layout_set_font_description(Xen_to_C_PangoLayout_(layout), Xen_to_C_PangoFontDescription_(desc)); return(Xen_false); } static Xen gxg_pango_layout_set_width(Xen layout, Xen width) { #define H_pango_layout_set_width "void pango_layout_set_width(PangoLayout* layout, int width)" Xen_check_type(Xen_is_PangoLayout_(layout), layout, 1, "pango_layout_set_width", "PangoLayout*"); Xen_check_type(Xen_is_int(width), width, 2, "pango_layout_set_width", "int"); pango_layout_set_width(Xen_to_C_PangoLayout_(layout), Xen_to_C_int(width)); return(Xen_false); } static Xen gxg_pango_layout_get_width(Xen layout) { #define H_pango_layout_get_width "int pango_layout_get_width(PangoLayout* layout)" Xen_check_type(Xen_is_PangoLayout_(layout), layout, 1, "pango_layout_get_width", "PangoLayout*"); return(C_to_Xen_int(pango_layout_get_width(Xen_to_C_PangoLayout_(layout)))); } static Xen gxg_pango_layout_set_wrap(Xen layout, Xen wrap) { #define H_pango_layout_set_wrap "void pango_layout_set_wrap(PangoLayout* layout, PangoWrapMode wrap)" Xen_check_type(Xen_is_PangoLayout_(layout), layout, 1, "pango_layout_set_wrap", "PangoLayout*"); Xen_check_type(Xen_is_PangoWrapMode(wrap), wrap, 2, "pango_layout_set_wrap", "PangoWrapMode"); pango_layout_set_wrap(Xen_to_C_PangoLayout_(layout), Xen_to_C_PangoWrapMode(wrap)); return(Xen_false); } static Xen gxg_pango_layout_get_wrap(Xen layout) { #define H_pango_layout_get_wrap "PangoWrapMode pango_layout_get_wrap(PangoLayout* layout)" Xen_check_type(Xen_is_PangoLayout_(layout), layout, 1, "pango_layout_get_wrap", "PangoLayout*"); return(C_to_Xen_PangoWrapMode(pango_layout_get_wrap(Xen_to_C_PangoLayout_(layout)))); } static Xen gxg_pango_layout_set_indent(Xen layout, Xen indent) { #define H_pango_layout_set_indent "void pango_layout_set_indent(PangoLayout* layout, int indent)" Xen_check_type(Xen_is_PangoLayout_(layout), layout, 1, "pango_layout_set_indent", "PangoLayout*"); Xen_check_type(Xen_is_int(indent), indent, 2, "pango_layout_set_indent", "int"); pango_layout_set_indent(Xen_to_C_PangoLayout_(layout), Xen_to_C_int(indent)); return(Xen_false); } static Xen gxg_pango_layout_get_indent(Xen layout) { #define H_pango_layout_get_indent "int pango_layout_get_indent(PangoLayout* layout)" Xen_check_type(Xen_is_PangoLayout_(layout), layout, 1, "pango_layout_get_indent", "PangoLayout*"); return(C_to_Xen_int(pango_layout_get_indent(Xen_to_C_PangoLayout_(layout)))); } static Xen gxg_pango_layout_set_spacing(Xen layout, Xen spacing) { #define H_pango_layout_set_spacing "void pango_layout_set_spacing(PangoLayout* layout, int spacing)" Xen_check_type(Xen_is_PangoLayout_(layout), layout, 1, "pango_layout_set_spacing", "PangoLayout*"); Xen_check_type(Xen_is_int(spacing), spacing, 2, "pango_layout_set_spacing", "int"); pango_layout_set_spacing(Xen_to_C_PangoLayout_(layout), Xen_to_C_int(spacing)); return(Xen_false); } static Xen gxg_pango_layout_get_spacing(Xen layout) { #define H_pango_layout_get_spacing "int pango_layout_get_spacing(PangoLayout* layout)" Xen_check_type(Xen_is_PangoLayout_(layout), layout, 1, "pango_layout_get_spacing", "PangoLayout*"); return(C_to_Xen_int(pango_layout_get_spacing(Xen_to_C_PangoLayout_(layout)))); } static Xen gxg_pango_layout_set_justify(Xen layout, Xen justify) { #define H_pango_layout_set_justify "void pango_layout_set_justify(PangoLayout* layout, gboolean justify)" Xen_check_type(Xen_is_PangoLayout_(layout), layout, 1, "pango_layout_set_justify", "PangoLayout*"); Xen_check_type(Xen_is_gboolean(justify), justify, 2, "pango_layout_set_justify", "gboolean"); pango_layout_set_justify(Xen_to_C_PangoLayout_(layout), Xen_to_C_gboolean(justify)); return(Xen_false); } static Xen gxg_pango_layout_get_justify(Xen layout) { #define H_pango_layout_get_justify "gboolean pango_layout_get_justify(PangoLayout* layout)" Xen_check_type(Xen_is_PangoLayout_(layout), layout, 1, "pango_layout_get_justify", "PangoLayout*"); return(C_to_Xen_gboolean(pango_layout_get_justify(Xen_to_C_PangoLayout_(layout)))); } static Xen gxg_pango_layout_set_alignment(Xen layout, Xen alignment) { #define H_pango_layout_set_alignment "void pango_layout_set_alignment(PangoLayout* layout, PangoAlignment alignment)" Xen_check_type(Xen_is_PangoLayout_(layout), layout, 1, "pango_layout_set_alignment", "PangoLayout*"); Xen_check_type(Xen_is_PangoAlignment(alignment), alignment, 2, "pango_layout_set_alignment", "PangoAlignment"); pango_layout_set_alignment(Xen_to_C_PangoLayout_(layout), Xen_to_C_PangoAlignment(alignment)); return(Xen_false); } static Xen gxg_pango_layout_get_alignment(Xen layout) { #define H_pango_layout_get_alignment "PangoAlignment pango_layout_get_alignment(PangoLayout* layout)" Xen_check_type(Xen_is_PangoLayout_(layout), layout, 1, "pango_layout_get_alignment", "PangoLayout*"); return(C_to_Xen_PangoAlignment(pango_layout_get_alignment(Xen_to_C_PangoLayout_(layout)))); } static Xen gxg_pango_layout_set_tabs(Xen layout, Xen tabs) { #define H_pango_layout_set_tabs "void pango_layout_set_tabs(PangoLayout* layout, PangoTabArray* tabs)" Xen_check_type(Xen_is_PangoLayout_(layout), layout, 1, "pango_layout_set_tabs", "PangoLayout*"); Xen_check_type(Xen_is_PangoTabArray_(tabs) || Xen_is_false(tabs), tabs, 2, "pango_layout_set_tabs", "PangoTabArray*"); pango_layout_set_tabs(Xen_to_C_PangoLayout_(layout), Xen_to_C_PangoTabArray_(tabs)); return(Xen_false); } static Xen gxg_pango_layout_get_tabs(Xen layout) { #define H_pango_layout_get_tabs "PangoTabArray* pango_layout_get_tabs(PangoLayout* layout)" Xen_check_type(Xen_is_PangoLayout_(layout), layout, 1, "pango_layout_get_tabs", "PangoLayout*"); return(C_to_Xen_PangoTabArray_(pango_layout_get_tabs(Xen_to_C_PangoLayout_(layout)))); } static Xen gxg_pango_layout_set_single_paragraph_mode(Xen layout, Xen setting) { #define H_pango_layout_set_single_paragraph_mode "void pango_layout_set_single_paragraph_mode(PangoLayout* layout, \ gboolean setting)" Xen_check_type(Xen_is_PangoLayout_(layout), layout, 1, "pango_layout_set_single_paragraph_mode", "PangoLayout*"); Xen_check_type(Xen_is_gboolean(setting), setting, 2, "pango_layout_set_single_paragraph_mode", "gboolean"); pango_layout_set_single_paragraph_mode(Xen_to_C_PangoLayout_(layout), Xen_to_C_gboolean(setting)); return(Xen_false); } static Xen gxg_pango_layout_get_single_paragraph_mode(Xen layout) { #define H_pango_layout_get_single_paragraph_mode "gboolean pango_layout_get_single_paragraph_mode(PangoLayout* layout)" Xen_check_type(Xen_is_PangoLayout_(layout), layout, 1, "pango_layout_get_single_paragraph_mode", "PangoLayout*"); return(C_to_Xen_gboolean(pango_layout_get_single_paragraph_mode(Xen_to_C_PangoLayout_(layout)))); } static Xen gxg_pango_layout_context_changed(Xen layout) { #define H_pango_layout_context_changed "void pango_layout_context_changed(PangoLayout* layout)" Xen_check_type(Xen_is_PangoLayout_(layout), layout, 1, "pango_layout_context_changed", "PangoLayout*"); pango_layout_context_changed(Xen_to_C_PangoLayout_(layout)); return(Xen_false); } static Xen gxg_pango_layout_get_log_attrs(Xen layout, Xen ignore_attrs, Xen ignore_n_attrs) { #define H_pango_layout_get_log_attrs "void pango_layout_get_log_attrs(PangoLayout* layout, PangoLogAttr** [attrs], \ gint* [n_attrs])" PangoLogAttr* ref_attrs = NULL; gint ref_n_attrs; Xen_check_type(Xen_is_PangoLayout_(layout), layout, 1, "pango_layout_get_log_attrs", "PangoLayout*"); pango_layout_get_log_attrs(Xen_to_C_PangoLayout_(layout), &ref_attrs, &ref_n_attrs); return(Xen_list_2(C_to_Xen_PangoLogAttr_(ref_attrs), C_to_Xen_gint(ref_n_attrs))); } static Xen gxg_pango_layout_index_to_pos(Xen layout, Xen index, Xen pos) { #define H_pango_layout_index_to_pos "void pango_layout_index_to_pos(PangoLayout* layout, int index, \ PangoRectangle* pos)" Xen_check_type(Xen_is_PangoLayout_(layout), layout, 1, "pango_layout_index_to_pos", "PangoLayout*"); Xen_check_type(Xen_is_int(index), index, 2, "pango_layout_index_to_pos", "int"); Xen_check_type(Xen_is_PangoRectangle_(pos), pos, 3, "pango_layout_index_to_pos", "PangoRectangle*"); pango_layout_index_to_pos(Xen_to_C_PangoLayout_(layout), Xen_to_C_int(index), Xen_to_C_PangoRectangle_(pos)); return(Xen_false); } static Xen gxg_pango_layout_get_cursor_pos(Xen layout, Xen index, Xen strong_pos, Xen weak_pos) { #define H_pango_layout_get_cursor_pos "void pango_layout_get_cursor_pos(PangoLayout* layout, int index, \ PangoRectangle* strong_pos, PangoRectangle* weak_pos)" Xen_check_type(Xen_is_PangoLayout_(layout), layout, 1, "pango_layout_get_cursor_pos", "PangoLayout*"); Xen_check_type(Xen_is_int(index), index, 2, "pango_layout_get_cursor_pos", "int"); Xen_check_type(Xen_is_PangoRectangle_(strong_pos), strong_pos, 3, "pango_layout_get_cursor_pos", "PangoRectangle*"); Xen_check_type(Xen_is_PangoRectangle_(weak_pos), weak_pos, 4, "pango_layout_get_cursor_pos", "PangoRectangle*"); pango_layout_get_cursor_pos(Xen_to_C_PangoLayout_(layout), Xen_to_C_int(index), Xen_to_C_PangoRectangle_(strong_pos), Xen_to_C_PangoRectangle_(weak_pos)); return(Xen_false); } static Xen gxg_pango_layout_move_cursor_visually(Xen layout, Xen strong, Xen old_index, Xen old_trailing, Xen direction, Xen new_index, Xen new_trailing) { #define H_pango_layout_move_cursor_visually "void pango_layout_move_cursor_visually(PangoLayout* layout, \ gboolean strong, int old_index, int old_trailing, int direction, int* new_index, int* new_trailing)" Xen_check_type(Xen_is_PangoLayout_(layout), layout, 1, "pango_layout_move_cursor_visually", "PangoLayout*"); Xen_check_type(Xen_is_gboolean(strong), strong, 2, "pango_layout_move_cursor_visually", "gboolean"); Xen_check_type(Xen_is_int(old_index), old_index, 3, "pango_layout_move_cursor_visually", "int"); Xen_check_type(Xen_is_int(old_trailing), old_trailing, 4, "pango_layout_move_cursor_visually", "int"); Xen_check_type(Xen_is_int(direction), direction, 5, "pango_layout_move_cursor_visually", "int"); Xen_check_type(Xen_is_int_(new_index), new_index, 6, "pango_layout_move_cursor_visually", "int*"); Xen_check_type(Xen_is_int_(new_trailing), new_trailing, 7, "pango_layout_move_cursor_visually", "int*"); pango_layout_move_cursor_visually(Xen_to_C_PangoLayout_(layout), Xen_to_C_gboolean(strong), Xen_to_C_int(old_index), Xen_to_C_int(old_trailing), Xen_to_C_int(direction), Xen_to_C_int_(new_index), Xen_to_C_int_(new_trailing)); return(Xen_false); } static Xen gxg_pango_layout_xy_to_index(Xen layout, Xen x, Xen y, Xen ignore_index, Xen ignore_trailing) { #define H_pango_layout_xy_to_index "gboolean pango_layout_xy_to_index(PangoLayout* layout, int x, int y, \ int* [index], int* [trailing])" int ref_index; int ref_trailing; Xen_check_type(Xen_is_PangoLayout_(layout), layout, 1, "pango_layout_xy_to_index", "PangoLayout*"); Xen_check_type(Xen_is_int(x), x, 2, "pango_layout_xy_to_index", "int"); Xen_check_type(Xen_is_int(y), y, 3, "pango_layout_xy_to_index", "int"); { Xen result; result = C_to_Xen_gboolean(pango_layout_xy_to_index(Xen_to_C_PangoLayout_(layout), Xen_to_C_int(x), Xen_to_C_int(y), &ref_index, &ref_trailing)); return(Xen_list_3(result, C_to_Xen_int(ref_index), C_to_Xen_int(ref_trailing))); } } static Xen gxg_pango_layout_get_extents(Xen layout, Xen ink_rect, Xen logical_rect) { #define H_pango_layout_get_extents "void pango_layout_get_extents(PangoLayout* layout, PangoRectangle* ink_rect, \ PangoRectangle* logical_rect)" Xen_check_type(Xen_is_PangoLayout_(layout), layout, 1, "pango_layout_get_extents", "PangoLayout*"); Xen_check_type(Xen_is_PangoRectangle_(ink_rect), ink_rect, 2, "pango_layout_get_extents", "PangoRectangle*"); Xen_check_type(Xen_is_PangoRectangle_(logical_rect), logical_rect, 3, "pango_layout_get_extents", "PangoRectangle*"); pango_layout_get_extents(Xen_to_C_PangoLayout_(layout), Xen_to_C_PangoRectangle_(ink_rect), Xen_to_C_PangoRectangle_(logical_rect)); return(Xen_false); } static Xen gxg_pango_layout_get_pixel_extents(Xen layout, Xen ink_rect, Xen logical_rect) { #define H_pango_layout_get_pixel_extents "void pango_layout_get_pixel_extents(PangoLayout* layout, \ PangoRectangle* ink_rect, PangoRectangle* logical_rect)" Xen_check_type(Xen_is_PangoLayout_(layout), layout, 1, "pango_layout_get_pixel_extents", "PangoLayout*"); Xen_check_type(Xen_is_PangoRectangle_(ink_rect), ink_rect, 2, "pango_layout_get_pixel_extents", "PangoRectangle*"); Xen_check_type(Xen_is_PangoRectangle_(logical_rect), logical_rect, 3, "pango_layout_get_pixel_extents", "PangoRectangle*"); pango_layout_get_pixel_extents(Xen_to_C_PangoLayout_(layout), Xen_to_C_PangoRectangle_(ink_rect), Xen_to_C_PangoRectangle_(logical_rect)); return(Xen_false); } static Xen gxg_pango_layout_get_size(Xen layout, Xen ignore_width, Xen ignore_height) { #define H_pango_layout_get_size "void pango_layout_get_size(PangoLayout* layout, int* [width], int* [height])" int ref_width; int ref_height; Xen_check_type(Xen_is_PangoLayout_(layout), layout, 1, "pango_layout_get_size", "PangoLayout*"); pango_layout_get_size(Xen_to_C_PangoLayout_(layout), &ref_width, &ref_height); return(Xen_list_2(C_to_Xen_int(ref_width), C_to_Xen_int(ref_height))); } static Xen gxg_pango_layout_get_pixel_size(Xen layout, Xen ignore_width, Xen ignore_height) { #define H_pango_layout_get_pixel_size "void pango_layout_get_pixel_size(PangoLayout* layout, int* [width], \ int* [height])" int ref_width; int ref_height; Xen_check_type(Xen_is_PangoLayout_(layout), layout, 1, "pango_layout_get_pixel_size", "PangoLayout*"); pango_layout_get_pixel_size(Xen_to_C_PangoLayout_(layout), &ref_width, &ref_height); return(Xen_list_2(C_to_Xen_int(ref_width), C_to_Xen_int(ref_height))); } static Xen gxg_pango_layout_get_line_count(Xen layout) { #define H_pango_layout_get_line_count "int pango_layout_get_line_count(PangoLayout* layout)" Xen_check_type(Xen_is_PangoLayout_(layout), layout, 1, "pango_layout_get_line_count", "PangoLayout*"); return(C_to_Xen_int(pango_layout_get_line_count(Xen_to_C_PangoLayout_(layout)))); } static Xen gxg_pango_layout_get_line(Xen layout, Xen line) { #define H_pango_layout_get_line "PangoLayoutLine* pango_layout_get_line(PangoLayout* layout, int line)" Xen_check_type(Xen_is_PangoLayout_(layout), layout, 1, "pango_layout_get_line", "PangoLayout*"); Xen_check_type(Xen_is_int(line), line, 2, "pango_layout_get_line", "int"); return(C_to_Xen_PangoLayoutLine_(pango_layout_get_line(Xen_to_C_PangoLayout_(layout), Xen_to_C_int(line)))); } static Xen gxg_pango_layout_get_lines(Xen layout) { #define H_pango_layout_get_lines "GSList* pango_layout_get_lines(PangoLayout* layout)" Xen_check_type(Xen_is_PangoLayout_(layout), layout, 1, "pango_layout_get_lines", "PangoLayout*"); return(C_to_Xen_GSList_(pango_layout_get_lines(Xen_to_C_PangoLayout_(layout)))); } static Xen gxg_pango_layout_line_unref(Xen line) { #define H_pango_layout_line_unref "void pango_layout_line_unref(PangoLayoutLine* line)" Xen_check_type(Xen_is_PangoLayoutLine_(line), line, 1, "pango_layout_line_unref", "PangoLayoutLine*"); pango_layout_line_unref(Xen_to_C_PangoLayoutLine_(line)); return(Xen_false); } static Xen gxg_pango_layout_line_x_to_index(Xen line, Xen x_pos, Xen ignore_index, Xen ignore_trailing) { #define H_pango_layout_line_x_to_index "gboolean pango_layout_line_x_to_index(PangoLayoutLine* line, \ int x_pos, int* [index], int* [trailing])" int ref_index; int ref_trailing; Xen_check_type(Xen_is_PangoLayoutLine_(line), line, 1, "pango_layout_line_x_to_index", "PangoLayoutLine*"); Xen_check_type(Xen_is_int(x_pos), x_pos, 2, "pango_layout_line_x_to_index", "int"); { Xen result; result = C_to_Xen_gboolean(pango_layout_line_x_to_index(Xen_to_C_PangoLayoutLine_(line), Xen_to_C_int(x_pos), &ref_index, &ref_trailing)); return(Xen_list_3(result, C_to_Xen_int(ref_index), C_to_Xen_int(ref_trailing))); } } static Xen gxg_pango_layout_line_index_to_x(Xen line, Xen index, Xen trailing, Xen ignore_x_pos) { #define H_pango_layout_line_index_to_x "void pango_layout_line_index_to_x(PangoLayoutLine* line, int index, \ gboolean trailing, int* [x_pos])" int ref_x_pos; Xen_check_type(Xen_is_PangoLayoutLine_(line), line, 1, "pango_layout_line_index_to_x", "PangoLayoutLine*"); Xen_check_type(Xen_is_int(index), index, 2, "pango_layout_line_index_to_x", "int"); Xen_check_type(Xen_is_gboolean(trailing), trailing, 3, "pango_layout_line_index_to_x", "gboolean"); pango_layout_line_index_to_x(Xen_to_C_PangoLayoutLine_(line), Xen_to_C_int(index), Xen_to_C_gboolean(trailing), &ref_x_pos); return(Xen_list_1(C_to_Xen_int(ref_x_pos))); } static Xen gxg_pango_layout_line_get_x_ranges(Xen line, Xen start_index, Xen end_index, Xen ignore_ranges, Xen ignore_n_ranges) { #define H_pango_layout_line_get_x_ranges "void pango_layout_line_get_x_ranges(PangoLayoutLine* line, \ int start_index, int end_index, int** [ranges], int* [n_ranges])" int* ref_ranges = NULL; int ref_n_ranges; Xen_check_type(Xen_is_PangoLayoutLine_(line), line, 1, "pango_layout_line_get_x_ranges", "PangoLayoutLine*"); Xen_check_type(Xen_is_int(start_index), start_index, 2, "pango_layout_line_get_x_ranges", "int"); Xen_check_type(Xen_is_int(end_index), end_index, 3, "pango_layout_line_get_x_ranges", "int"); pango_layout_line_get_x_ranges(Xen_to_C_PangoLayoutLine_(line), Xen_to_C_int(start_index), Xen_to_C_int(end_index), &ref_ranges, &ref_n_ranges); return(Xen_list_2(C_to_Xen_int_(ref_ranges), C_to_Xen_int(ref_n_ranges))); } static Xen gxg_pango_layout_line_get_extents(Xen line, Xen ink_rect, Xen logical_rect) { #define H_pango_layout_line_get_extents "void pango_layout_line_get_extents(PangoLayoutLine* line, \ PangoRectangle* ink_rect, PangoRectangle* logical_rect)" Xen_check_type(Xen_is_PangoLayoutLine_(line), line, 1, "pango_layout_line_get_extents", "PangoLayoutLine*"); Xen_check_type(Xen_is_PangoRectangle_(ink_rect), ink_rect, 2, "pango_layout_line_get_extents", "PangoRectangle*"); Xen_check_type(Xen_is_PangoRectangle_(logical_rect), logical_rect, 3, "pango_layout_line_get_extents", "PangoRectangle*"); pango_layout_line_get_extents(Xen_to_C_PangoLayoutLine_(line), Xen_to_C_PangoRectangle_(ink_rect), Xen_to_C_PangoRectangle_(logical_rect)); return(Xen_false); } static Xen gxg_pango_layout_line_get_pixel_extents(Xen layout_line, Xen ink_rect, Xen logical_rect) { #define H_pango_layout_line_get_pixel_extents "void pango_layout_line_get_pixel_extents(PangoLayoutLine* layout_line, \ PangoRectangle* ink_rect, PangoRectangle* logical_rect)" Xen_check_type(Xen_is_PangoLayoutLine_(layout_line), layout_line, 1, "pango_layout_line_get_pixel_extents", "PangoLayoutLine*"); Xen_check_type(Xen_is_PangoRectangle_(ink_rect), ink_rect, 2, "pango_layout_line_get_pixel_extents", "PangoRectangle*"); Xen_check_type(Xen_is_PangoRectangle_(logical_rect), logical_rect, 3, "pango_layout_line_get_pixel_extents", "PangoRectangle*"); pango_layout_line_get_pixel_extents(Xen_to_C_PangoLayoutLine_(layout_line), Xen_to_C_PangoRectangle_(ink_rect), Xen_to_C_PangoRectangle_(logical_rect)); return(Xen_false); } static Xen gxg_pango_layout_get_iter(Xen layout) { #define H_pango_layout_get_iter "PangoLayoutIter* pango_layout_get_iter(PangoLayout* layout)" Xen_check_type(Xen_is_PangoLayout_(layout), layout, 1, "pango_layout_get_iter", "PangoLayout*"); return(C_to_Xen_PangoLayoutIter_(pango_layout_get_iter(Xen_to_C_PangoLayout_(layout)))); } static Xen gxg_pango_layout_iter_free(Xen iter) { #define H_pango_layout_iter_free "void pango_layout_iter_free(PangoLayoutIter* iter)" Xen_check_type(Xen_is_PangoLayoutIter_(iter), iter, 1, "pango_layout_iter_free", "PangoLayoutIter*"); pango_layout_iter_free(Xen_to_C_PangoLayoutIter_(iter)); return(Xen_false); } static Xen gxg_pango_layout_iter_get_index(Xen iter) { #define H_pango_layout_iter_get_index "int pango_layout_iter_get_index(PangoLayoutIter* iter)" Xen_check_type(Xen_is_PangoLayoutIter_(iter), iter, 1, "pango_layout_iter_get_index", "PangoLayoutIter*"); return(C_to_Xen_int(pango_layout_iter_get_index(Xen_to_C_PangoLayoutIter_(iter)))); } static Xen gxg_pango_layout_iter_get_run(Xen iter) { #define H_pango_layout_iter_get_run "PangoLayoutRun* pango_layout_iter_get_run(PangoLayoutIter* iter)" Xen_check_type(Xen_is_PangoLayoutIter_(iter), iter, 1, "pango_layout_iter_get_run", "PangoLayoutIter*"); return(C_to_Xen_PangoLayoutRun_(pango_layout_iter_get_run(Xen_to_C_PangoLayoutIter_(iter)))); } static Xen gxg_pango_layout_iter_get_line(Xen iter) { #define H_pango_layout_iter_get_line "PangoLayoutLine* pango_layout_iter_get_line(PangoLayoutIter* iter)" Xen_check_type(Xen_is_PangoLayoutIter_(iter), iter, 1, "pango_layout_iter_get_line", "PangoLayoutIter*"); return(C_to_Xen_PangoLayoutLine_(pango_layout_iter_get_line(Xen_to_C_PangoLayoutIter_(iter)))); } static Xen gxg_pango_layout_iter_at_last_line(Xen iter) { #define H_pango_layout_iter_at_last_line "gboolean pango_layout_iter_at_last_line(PangoLayoutIter* iter)" Xen_check_type(Xen_is_PangoLayoutIter_(iter), iter, 1, "pango_layout_iter_at_last_line", "PangoLayoutIter*"); return(C_to_Xen_gboolean(pango_layout_iter_at_last_line(Xen_to_C_PangoLayoutIter_(iter)))); } static Xen gxg_pango_layout_iter_next_char(Xen iter) { #define H_pango_layout_iter_next_char "gboolean pango_layout_iter_next_char(PangoLayoutIter* iter)" Xen_check_type(Xen_is_PangoLayoutIter_(iter), iter, 1, "pango_layout_iter_next_char", "PangoLayoutIter*"); return(C_to_Xen_gboolean(pango_layout_iter_next_char(Xen_to_C_PangoLayoutIter_(iter)))); } static Xen gxg_pango_layout_iter_next_cluster(Xen iter) { #define H_pango_layout_iter_next_cluster "gboolean pango_layout_iter_next_cluster(PangoLayoutIter* iter)" Xen_check_type(Xen_is_PangoLayoutIter_(iter), iter, 1, "pango_layout_iter_next_cluster", "PangoLayoutIter*"); return(C_to_Xen_gboolean(pango_layout_iter_next_cluster(Xen_to_C_PangoLayoutIter_(iter)))); } static Xen gxg_pango_layout_iter_next_run(Xen iter) { #define H_pango_layout_iter_next_run "gboolean pango_layout_iter_next_run(PangoLayoutIter* iter)" Xen_check_type(Xen_is_PangoLayoutIter_(iter), iter, 1, "pango_layout_iter_next_run", "PangoLayoutIter*"); return(C_to_Xen_gboolean(pango_layout_iter_next_run(Xen_to_C_PangoLayoutIter_(iter)))); } static Xen gxg_pango_layout_iter_next_line(Xen iter) { #define H_pango_layout_iter_next_line "gboolean pango_layout_iter_next_line(PangoLayoutIter* iter)" Xen_check_type(Xen_is_PangoLayoutIter_(iter), iter, 1, "pango_layout_iter_next_line", "PangoLayoutIter*"); return(C_to_Xen_gboolean(pango_layout_iter_next_line(Xen_to_C_PangoLayoutIter_(iter)))); } static Xen gxg_pango_layout_iter_get_char_extents(Xen iter, Xen logical_rect) { #define H_pango_layout_iter_get_char_extents "void pango_layout_iter_get_char_extents(PangoLayoutIter* iter, \ PangoRectangle* logical_rect)" Xen_check_type(Xen_is_PangoLayoutIter_(iter), iter, 1, "pango_layout_iter_get_char_extents", "PangoLayoutIter*"); Xen_check_type(Xen_is_PangoRectangle_(logical_rect), logical_rect, 2, "pango_layout_iter_get_char_extents", "PangoRectangle*"); pango_layout_iter_get_char_extents(Xen_to_C_PangoLayoutIter_(iter), Xen_to_C_PangoRectangle_(logical_rect)); return(Xen_false); } static Xen gxg_pango_layout_iter_get_cluster_extents(Xen iter, Xen ink_rect, Xen logical_rect) { #define H_pango_layout_iter_get_cluster_extents "void pango_layout_iter_get_cluster_extents(PangoLayoutIter* iter, \ PangoRectangle* ink_rect, PangoRectangle* logical_rect)" Xen_check_type(Xen_is_PangoLayoutIter_(iter), iter, 1, "pango_layout_iter_get_cluster_extents", "PangoLayoutIter*"); Xen_check_type(Xen_is_PangoRectangle_(ink_rect), ink_rect, 2, "pango_layout_iter_get_cluster_extents", "PangoRectangle*"); Xen_check_type(Xen_is_PangoRectangle_(logical_rect), logical_rect, 3, "pango_layout_iter_get_cluster_extents", "PangoRectangle*"); pango_layout_iter_get_cluster_extents(Xen_to_C_PangoLayoutIter_(iter), Xen_to_C_PangoRectangle_(ink_rect), Xen_to_C_PangoRectangle_(logical_rect)); return(Xen_false); } static Xen gxg_pango_layout_iter_get_run_extents(Xen iter, Xen ink_rect, Xen logical_rect) { #define H_pango_layout_iter_get_run_extents "void pango_layout_iter_get_run_extents(PangoLayoutIter* iter, \ PangoRectangle* ink_rect, PangoRectangle* logical_rect)" Xen_check_type(Xen_is_PangoLayoutIter_(iter), iter, 1, "pango_layout_iter_get_run_extents", "PangoLayoutIter*"); Xen_check_type(Xen_is_PangoRectangle_(ink_rect), ink_rect, 2, "pango_layout_iter_get_run_extents", "PangoRectangle*"); Xen_check_type(Xen_is_PangoRectangle_(logical_rect), logical_rect, 3, "pango_layout_iter_get_run_extents", "PangoRectangle*"); pango_layout_iter_get_run_extents(Xen_to_C_PangoLayoutIter_(iter), Xen_to_C_PangoRectangle_(ink_rect), Xen_to_C_PangoRectangle_(logical_rect)); return(Xen_false); } static Xen gxg_pango_layout_iter_get_line_extents(Xen iter, Xen ink_rect, Xen logical_rect) { #define H_pango_layout_iter_get_line_extents "void pango_layout_iter_get_line_extents(PangoLayoutIter* iter, \ PangoRectangle* ink_rect, PangoRectangle* logical_rect)" Xen_check_type(Xen_is_PangoLayoutIter_(iter), iter, 1, "pango_layout_iter_get_line_extents", "PangoLayoutIter*"); Xen_check_type(Xen_is_PangoRectangle_(ink_rect), ink_rect, 2, "pango_layout_iter_get_line_extents", "PangoRectangle*"); Xen_check_type(Xen_is_PangoRectangle_(logical_rect), logical_rect, 3, "pango_layout_iter_get_line_extents", "PangoRectangle*"); pango_layout_iter_get_line_extents(Xen_to_C_PangoLayoutIter_(iter), Xen_to_C_PangoRectangle_(ink_rect), Xen_to_C_PangoRectangle_(logical_rect)); return(Xen_false); } static Xen gxg_pango_layout_iter_get_line_yrange(Xen iter, Xen ignore_y0, Xen ignore_y1) { #define H_pango_layout_iter_get_line_yrange "void pango_layout_iter_get_line_yrange(PangoLayoutIter* iter, \ int* [y0], int* [y1])" int ref_y0; int ref_y1; Xen_check_type(Xen_is_PangoLayoutIter_(iter), iter, 1, "pango_layout_iter_get_line_yrange", "PangoLayoutIter*"); pango_layout_iter_get_line_yrange(Xen_to_C_PangoLayoutIter_(iter), &ref_y0, &ref_y1); return(Xen_list_2(C_to_Xen_int(ref_y0), C_to_Xen_int(ref_y1))); } static Xen gxg_pango_layout_iter_get_layout_extents(Xen iter, Xen ink_rect, Xen logical_rect) { #define H_pango_layout_iter_get_layout_extents "void pango_layout_iter_get_layout_extents(PangoLayoutIter* iter, \ PangoRectangle* ink_rect, PangoRectangle* logical_rect)" Xen_check_type(Xen_is_PangoLayoutIter_(iter), iter, 1, "pango_layout_iter_get_layout_extents", "PangoLayoutIter*"); Xen_check_type(Xen_is_PangoRectangle_(ink_rect), ink_rect, 2, "pango_layout_iter_get_layout_extents", "PangoRectangle*"); Xen_check_type(Xen_is_PangoRectangle_(logical_rect), logical_rect, 3, "pango_layout_iter_get_layout_extents", "PangoRectangle*"); pango_layout_iter_get_layout_extents(Xen_to_C_PangoLayoutIter_(iter), Xen_to_C_PangoRectangle_(ink_rect), Xen_to_C_PangoRectangle_(logical_rect)); return(Xen_false); } static Xen gxg_pango_layout_iter_get_baseline(Xen iter) { #define H_pango_layout_iter_get_baseline "int pango_layout_iter_get_baseline(PangoLayoutIter* iter)" Xen_check_type(Xen_is_PangoLayoutIter_(iter), iter, 1, "pango_layout_iter_get_baseline", "PangoLayoutIter*"); return(C_to_Xen_int(pango_layout_iter_get_baseline(Xen_to_C_PangoLayoutIter_(iter)))); } static Xen gxg_pango_language_from_string(Xen language) { #define H_pango_language_from_string "PangoLanguage* pango_language_from_string(char* language)" Xen_check_type(Xen_is_char_(language), language, 1, "pango_language_from_string", "char*"); return(C_to_Xen_PangoLanguage_(pango_language_from_string(Xen_to_C_char_(language)))); } static Xen gxg_pango_language_matches(Xen language, Xen range_list) { #define H_pango_language_matches "gboolean pango_language_matches(PangoLanguage* language, char* range_list)" Xen_check_type(Xen_is_PangoLanguage_(language), language, 1, "pango_language_matches", "PangoLanguage*"); Xen_check_type(Xen_is_char_(range_list), range_list, 2, "pango_language_matches", "char*"); return(C_to_Xen_gboolean(pango_language_matches(Xen_to_C_PangoLanguage_(language), Xen_to_C_char_(range_list)))); } static Xen gxg_G_OBJECT_TYPE(Xen object) { #define H_G_OBJECT_TYPE "GType G_OBJECT_TYPE(GObject* object)" Xen_check_type(Xen_is_GObject_(object), object, 1, "G_OBJECT_TYPE", "GObject*"); return(C_to_Xen_GType(G_OBJECT_TYPE(Xen_to_C_GObject_(object)))); } static Xen gxg_gtk_tree_model_get_string_from_iter(Xen tree_model, Xen iter) { #define H_gtk_tree_model_get_string_from_iter "gchar* gtk_tree_model_get_string_from_iter(GtkTreeModel* tree_model, \ GtkTreeIter* iter)" Xen_check_type(Xen_is_GtkTreeModel_(tree_model), tree_model, 1, "gtk_tree_model_get_string_from_iter", "GtkTreeModel*"); Xen_check_type(Xen_is_GtkTreeIter_(iter), iter, 2, "gtk_tree_model_get_string_from_iter", "GtkTreeIter*"); { gchar* result; Xen rtn; result = gtk_tree_model_get_string_from_iter(Xen_to_C_GtkTreeModel_(tree_model), Xen_to_C_GtkTreeIter_(iter)); rtn = C_to_Xen_gchar_(result); g_free(result); return(rtn); } } static Xen gxg_gtk_tree_model_sort_iter_is_valid(Xen tree_model_sort, Xen iter) { #define H_gtk_tree_model_sort_iter_is_valid "gboolean gtk_tree_model_sort_iter_is_valid(GtkTreeModelSort* tree_model_sort, \ GtkTreeIter* iter)" Xen_check_type(Xen_is_GtkTreeModelSort_(tree_model_sort), tree_model_sort, 1, "gtk_tree_model_sort_iter_is_valid", "GtkTreeModelSort*"); Xen_check_type(Xen_is_GtkTreeIter_(iter), iter, 2, "gtk_tree_model_sort_iter_is_valid", "GtkTreeIter*"); return(C_to_Xen_gboolean(gtk_tree_model_sort_iter_is_valid(Xen_to_C_GtkTreeModelSort_(tree_model_sort), Xen_to_C_GtkTreeIter_(iter)))); } static Xen gxg_gtk_tree_view_expand_to_path(Xen tree_view, Xen path) { #define H_gtk_tree_view_expand_to_path "void gtk_tree_view_expand_to_path(GtkTreeView* tree_view, GtkTreePath* path)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_expand_to_path", "GtkTreeView*"); Xen_check_type(Xen_is_GtkTreePath_(path), path, 2, "gtk_tree_view_expand_to_path", "GtkTreePath*"); gtk_tree_view_expand_to_path(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_GtkTreePath_(path)); return(Xen_false); } static Xen gxg_gtk_tree_selection_get_selected_rows(Xen selection, Xen model) { #define H_gtk_tree_selection_get_selected_rows "GList* gtk_tree_selection_get_selected_rows(GtkTreeSelection* selection, \ GtkTreeModel** model)" Xen_check_type(Xen_is_GtkTreeSelection_(selection), selection, 1, "gtk_tree_selection_get_selected_rows", "GtkTreeSelection*"); Xen_check_type(Xen_is_GtkTreeModel__(model), model, 2, "gtk_tree_selection_get_selected_rows", "GtkTreeModel**"); return(C_to_Xen_GList_(gtk_tree_selection_get_selected_rows(Xen_to_C_GtkTreeSelection_(selection), Xen_to_C_GtkTreeModel__(model)))); } static Xen gxg_gtk_tree_selection_count_selected_rows(Xen selection) { #define H_gtk_tree_selection_count_selected_rows "int gtk_tree_selection_count_selected_rows(GtkTreeSelection* selection)" Xen_check_type(Xen_is_GtkTreeSelection_(selection), selection, 1, "gtk_tree_selection_count_selected_rows", "GtkTreeSelection*"); return(C_to_Xen_int(gtk_tree_selection_count_selected_rows(Xen_to_C_GtkTreeSelection_(selection)))); } static Xen gxg_gtk_menu_shell_select_first(Xen menu_shell, Xen search_sensitive) { #define H_gtk_menu_shell_select_first "void gtk_menu_shell_select_first(GtkMenuShell* menu_shell, gboolean search_sensitive)" Xen_check_type(Xen_is_GtkMenuShell_(menu_shell), menu_shell, 1, "gtk_menu_shell_select_first", "GtkMenuShell*"); Xen_check_type(Xen_is_gboolean(search_sensitive), search_sensitive, 2, "gtk_menu_shell_select_first", "gboolean"); gtk_menu_shell_select_first(Xen_to_C_GtkMenuShell_(menu_shell), Xen_to_C_gboolean(search_sensitive)); return(Xen_false); } static Xen gxg_gtk_notebook_get_n_pages(Xen notebook) { #define H_gtk_notebook_get_n_pages "int gtk_notebook_get_n_pages(GtkNotebook* notebook)" Xen_check_type(Xen_is_GtkNotebook_(notebook), notebook, 1, "gtk_notebook_get_n_pages", "GtkNotebook*"); return(C_to_Xen_int(gtk_notebook_get_n_pages(Xen_to_C_GtkNotebook_(notebook)))); } static Xen gxg_gtk_list_store_reorder(Xen store, Xen new_order) { #define H_gtk_list_store_reorder "void gtk_list_store_reorder(GtkListStore* store, int* new_order)" Xen_check_type(Xen_is_GtkListStore_(store), store, 1, "gtk_list_store_reorder", "GtkListStore*"); Xen_check_type(Xen_is_int_(new_order), new_order, 2, "gtk_list_store_reorder", "int*"); gtk_list_store_reorder(Xen_to_C_GtkListStore_(store), Xen_to_C_int_(new_order)); return(Xen_false); } static Xen gxg_gtk_list_store_swap(Xen store, Xen a, Xen b) { #define H_gtk_list_store_swap "void gtk_list_store_swap(GtkListStore* store, GtkTreeIter* a, GtkTreeIter* b)" Xen_check_type(Xen_is_GtkListStore_(store), store, 1, "gtk_list_store_swap", "GtkListStore*"); Xen_check_type(Xen_is_GtkTreeIter_(a), a, 2, "gtk_list_store_swap", "GtkTreeIter*"); Xen_check_type(Xen_is_GtkTreeIter_(b), b, 3, "gtk_list_store_swap", "GtkTreeIter*"); gtk_list_store_swap(Xen_to_C_GtkListStore_(store), Xen_to_C_GtkTreeIter_(a), Xen_to_C_GtkTreeIter_(b)); return(Xen_false); } static Xen gxg_gtk_list_store_move_after(Xen store, Xen iter, Xen position) { #define H_gtk_list_store_move_after "void gtk_list_store_move_after(GtkListStore* store, GtkTreeIter* iter, \ GtkTreeIter* position)" Xen_check_type(Xen_is_GtkListStore_(store), store, 1, "gtk_list_store_move_after", "GtkListStore*"); Xen_check_type(Xen_is_GtkTreeIter_(iter), iter, 2, "gtk_list_store_move_after", "GtkTreeIter*"); Xen_check_type(Xen_is_GtkTreeIter_(position) || Xen_is_false(position), position, 3, "gtk_list_store_move_after", "GtkTreeIter*"); gtk_list_store_move_after(Xen_to_C_GtkListStore_(store), Xen_to_C_GtkTreeIter_(iter), Xen_to_C_GtkTreeIter_(position)); return(Xen_false); } static Xen gxg_gtk_list_store_move_before(Xen store, Xen iter, Xen position) { #define H_gtk_list_store_move_before "void gtk_list_store_move_before(GtkListStore* store, GtkTreeIter* iter, \ GtkTreeIter* position)" Xen_check_type(Xen_is_GtkListStore_(store), store, 1, "gtk_list_store_move_before", "GtkListStore*"); Xen_check_type(Xen_is_GtkTreeIter_(iter), iter, 2, "gtk_list_store_move_before", "GtkTreeIter*"); Xen_check_type(Xen_is_GtkTreeIter_(position) || Xen_is_false(position), position, 3, "gtk_list_store_move_before", "GtkTreeIter*"); gtk_list_store_move_before(Xen_to_C_GtkListStore_(store), Xen_to_C_GtkTreeIter_(iter), Xen_to_C_GtkTreeIter_(position)); return(Xen_false); } static Xen gxg_gtk_tree_store_reorder(Xen tree_store, Xen parent, Xen new_order) { #define H_gtk_tree_store_reorder "void gtk_tree_store_reorder(GtkTreeStore* tree_store, GtkTreeIter* parent, \ int* new_order)" Xen_check_type(Xen_is_GtkTreeStore_(tree_store), tree_store, 1, "gtk_tree_store_reorder", "GtkTreeStore*"); Xen_check_type(Xen_is_GtkTreeIter_(parent), parent, 2, "gtk_tree_store_reorder", "GtkTreeIter*"); Xen_check_type(Xen_is_int_(new_order), new_order, 3, "gtk_tree_store_reorder", "int*"); gtk_tree_store_reorder(Xen_to_C_GtkTreeStore_(tree_store), Xen_to_C_GtkTreeIter_(parent), Xen_to_C_int_(new_order)); return(Xen_false); } static Xen gxg_gtk_tree_store_swap(Xen tree_store, Xen a, Xen b) { #define H_gtk_tree_store_swap "void gtk_tree_store_swap(GtkTreeStore* tree_store, GtkTreeIter* a, GtkTreeIter* b)" Xen_check_type(Xen_is_GtkTreeStore_(tree_store), tree_store, 1, "gtk_tree_store_swap", "GtkTreeStore*"); Xen_check_type(Xen_is_GtkTreeIter_(a), a, 2, "gtk_tree_store_swap", "GtkTreeIter*"); Xen_check_type(Xen_is_GtkTreeIter_(b), b, 3, "gtk_tree_store_swap", "GtkTreeIter*"); gtk_tree_store_swap(Xen_to_C_GtkTreeStore_(tree_store), Xen_to_C_GtkTreeIter_(a), Xen_to_C_GtkTreeIter_(b)); return(Xen_false); } static Xen gxg_gdk_display_open(Xen display_name) { #define H_gdk_display_open "GdkDisplay* gdk_display_open(gchar* display_name)" Xen_check_type(Xen_is_gchar_(display_name), display_name, 1, "gdk_display_open", "gchar*"); return(C_to_Xen_GdkDisplay_(gdk_display_open(Xen_to_C_gchar_(display_name)))); } static Xen gxg_gdk_display_get_name(Xen display) { #define H_gdk_display_get_name "gchar* gdk_display_get_name(GdkDisplay* display)" Xen_check_type(Xen_is_GdkDisplay_(display), display, 1, "gdk_display_get_name", "GdkDisplay*"); return(C_to_Xen_gchar_(gdk_display_get_name(Xen_to_C_GdkDisplay_(display)))); } static Xen gxg_gdk_display_get_screen(Xen display, Xen screen_num) { #define H_gdk_display_get_screen "GdkScreen* gdk_display_get_screen(GdkDisplay* display, int screen_num)" Xen_check_type(Xen_is_GdkDisplay_(display), display, 1, "gdk_display_get_screen", "GdkDisplay*"); Xen_check_type(Xen_is_int(screen_num), screen_num, 2, "gdk_display_get_screen", "int"); return(C_to_Xen_GdkScreen_(gdk_display_get_screen(Xen_to_C_GdkDisplay_(display), Xen_to_C_int(screen_num)))); } static Xen gxg_gdk_display_get_default_screen(Xen display) { #define H_gdk_display_get_default_screen "GdkScreen* gdk_display_get_default_screen(GdkDisplay* display)" Xen_check_type(Xen_is_GdkDisplay_(display), display, 1, "gdk_display_get_default_screen", "GdkDisplay*"); return(C_to_Xen_GdkScreen_(gdk_display_get_default_screen(Xen_to_C_GdkDisplay_(display)))); } static Xen gxg_gdk_display_beep(Xen display) { #define H_gdk_display_beep "void gdk_display_beep(GdkDisplay* display)" Xen_check_type(Xen_is_GdkDisplay_(display), display, 1, "gdk_display_beep", "GdkDisplay*"); gdk_display_beep(Xen_to_C_GdkDisplay_(display)); return(Xen_false); } static Xen gxg_gdk_display_sync(Xen display) { #define H_gdk_display_sync "void gdk_display_sync(GdkDisplay* display)" Xen_check_type(Xen_is_GdkDisplay_(display), display, 1, "gdk_display_sync", "GdkDisplay*"); gdk_display_sync(Xen_to_C_GdkDisplay_(display)); return(Xen_false); } static Xen gxg_gdk_display_close(Xen display) { #define H_gdk_display_close "void gdk_display_close(GdkDisplay* display)" Xen_check_type(Xen_is_GdkDisplay_(display), display, 1, "gdk_display_close", "GdkDisplay*"); gdk_display_close(Xen_to_C_GdkDisplay_(display)); return(Xen_false); } static Xen gxg_gdk_display_get_event(Xen display) { #define H_gdk_display_get_event "GdkEvent* gdk_display_get_event(GdkDisplay* display)" Xen_check_type(Xen_is_GdkDisplay_(display), display, 1, "gdk_display_get_event", "GdkDisplay*"); return(C_to_Xen_GdkEvent_(gdk_display_get_event(Xen_to_C_GdkDisplay_(display)))); } static Xen gxg_gdk_display_peek_event(Xen display) { #define H_gdk_display_peek_event "GdkEvent* gdk_display_peek_event(GdkDisplay* display)" Xen_check_type(Xen_is_GdkDisplay_(display), display, 1, "gdk_display_peek_event", "GdkDisplay*"); return(C_to_Xen_GdkEvent_(gdk_display_peek_event(Xen_to_C_GdkDisplay_(display)))); } static Xen gxg_gdk_display_put_event(Xen display, Xen event) { #define H_gdk_display_put_event "void gdk_display_put_event(GdkDisplay* display, GdkEvent* event)" Xen_check_type(Xen_is_GdkDisplay_(display), display, 1, "gdk_display_put_event", "GdkDisplay*"); Xen_check_type(Xen_is_GdkEvent_(event), event, 2, "gdk_display_put_event", "GdkEvent*"); gdk_display_put_event(Xen_to_C_GdkDisplay_(display), Xen_to_C_GdkEvent_(event)); return(Xen_false); } static Xen gxg_gdk_display_set_double_click_time(Xen display, Xen msec) { #define H_gdk_display_set_double_click_time "void gdk_display_set_double_click_time(GdkDisplay* display, \ guint msec)" Xen_check_type(Xen_is_GdkDisplay_(display), display, 1, "gdk_display_set_double_click_time", "GdkDisplay*"); Xen_check_type(Xen_is_guint(msec), msec, 2, "gdk_display_set_double_click_time", "guint"); gdk_display_set_double_click_time(Xen_to_C_GdkDisplay_(display), Xen_to_C_guint(msec)); return(Xen_false); } static Xen gxg_gdk_display_get_default(void) { #define H_gdk_display_get_default "GdkDisplay* gdk_display_get_default( void)" return(C_to_Xen_GdkDisplay_(gdk_display_get_default())); } static Xen gxg_gdk_screen_get_system_visual(Xen screen) { #define H_gdk_screen_get_system_visual "GdkVisual* gdk_screen_get_system_visual(GdkScreen* screen)" Xen_check_type(Xen_is_GdkScreen_(screen), screen, 1, "gdk_screen_get_system_visual", "GdkScreen*"); return(C_to_Xen_GdkVisual_(gdk_screen_get_system_visual(Xen_to_C_GdkScreen_(screen)))); } static Xen gxg_gdk_screen_get_root_window(Xen screen) { #define H_gdk_screen_get_root_window "GdkWindow* gdk_screen_get_root_window(GdkScreen* screen)" Xen_check_type(Xen_is_GdkScreen_(screen), screen, 1, "gdk_screen_get_root_window", "GdkScreen*"); return(C_to_Xen_GdkWindow_(gdk_screen_get_root_window(Xen_to_C_GdkScreen_(screen)))); } static Xen gxg_gdk_screen_get_display(Xen screen) { #define H_gdk_screen_get_display "GdkDisplay* gdk_screen_get_display(GdkScreen* screen)" Xen_check_type(Xen_is_GdkScreen_(screen), screen, 1, "gdk_screen_get_display", "GdkScreen*"); return(C_to_Xen_GdkDisplay_(gdk_screen_get_display(Xen_to_C_GdkScreen_(screen)))); } static Xen gxg_gdk_screen_get_number(Xen screen) { #define H_gdk_screen_get_number "int gdk_screen_get_number(GdkScreen* screen)" Xen_check_type(Xen_is_GdkScreen_(screen), screen, 1, "gdk_screen_get_number", "GdkScreen*"); return(C_to_Xen_int(gdk_screen_get_number(Xen_to_C_GdkScreen_(screen)))); } static Xen gxg_gdk_screen_get_width(Xen screen) { #define H_gdk_screen_get_width "int gdk_screen_get_width(GdkScreen* screen)" Xen_check_type(Xen_is_GdkScreen_(screen), screen, 1, "gdk_screen_get_width", "GdkScreen*"); return(C_to_Xen_int(gdk_screen_get_width(Xen_to_C_GdkScreen_(screen)))); } static Xen gxg_gdk_screen_get_height(Xen screen) { #define H_gdk_screen_get_height "int gdk_screen_get_height(GdkScreen* screen)" Xen_check_type(Xen_is_GdkScreen_(screen), screen, 1, "gdk_screen_get_height", "GdkScreen*"); return(C_to_Xen_int(gdk_screen_get_height(Xen_to_C_GdkScreen_(screen)))); } static Xen gxg_gdk_screen_get_width_mm(Xen screen) { #define H_gdk_screen_get_width_mm "int gdk_screen_get_width_mm(GdkScreen* screen)" Xen_check_type(Xen_is_GdkScreen_(screen), screen, 1, "gdk_screen_get_width_mm", "GdkScreen*"); return(C_to_Xen_int(gdk_screen_get_width_mm(Xen_to_C_GdkScreen_(screen)))); } static Xen gxg_gdk_screen_get_height_mm(Xen screen) { #define H_gdk_screen_get_height_mm "int gdk_screen_get_height_mm(GdkScreen* screen)" Xen_check_type(Xen_is_GdkScreen_(screen), screen, 1, "gdk_screen_get_height_mm", "GdkScreen*"); return(C_to_Xen_int(gdk_screen_get_height_mm(Xen_to_C_GdkScreen_(screen)))); } static Xen gxg_gdk_screen_list_visuals(Xen screen) { #define H_gdk_screen_list_visuals "GList* gdk_screen_list_visuals(GdkScreen* screen)" Xen_check_type(Xen_is_GdkScreen_(screen), screen, 1, "gdk_screen_list_visuals", "GdkScreen*"); return(C_to_Xen_GList_(gdk_screen_list_visuals(Xen_to_C_GdkScreen_(screen)))); } static Xen gxg_gdk_screen_get_toplevel_windows(Xen screen) { #define H_gdk_screen_get_toplevel_windows "GList* gdk_screen_get_toplevel_windows(GdkScreen* screen)" Xen_check_type(Xen_is_GdkScreen_(screen), screen, 1, "gdk_screen_get_toplevel_windows", "GdkScreen*"); return(C_to_Xen_GList_(gdk_screen_get_toplevel_windows(Xen_to_C_GdkScreen_(screen)))); } static Xen gxg_gdk_screen_make_display_name(Xen screen) { #define H_gdk_screen_make_display_name "gchar* gdk_screen_make_display_name(GdkScreen* screen)" Xen_check_type(Xen_is_GdkScreen_(screen), screen, 1, "gdk_screen_make_display_name", "GdkScreen*"); { gchar* result; Xen rtn; result = gdk_screen_make_display_name(Xen_to_C_GdkScreen_(screen)); rtn = C_to_Xen_gchar_(result); g_free(result); return(rtn); } } static Xen gxg_gdk_screen_get_n_monitors(Xen screen) { #define H_gdk_screen_get_n_monitors "int gdk_screen_get_n_monitors(GdkScreen* screen)" Xen_check_type(Xen_is_GdkScreen_(screen), screen, 1, "gdk_screen_get_n_monitors", "GdkScreen*"); return(C_to_Xen_int(gdk_screen_get_n_monitors(Xen_to_C_GdkScreen_(screen)))); } static Xen gxg_gdk_screen_get_monitor_geometry(Xen screen, Xen monitor_num, Xen dest) { #define H_gdk_screen_get_monitor_geometry "void gdk_screen_get_monitor_geometry(GdkScreen* screen, \ int monitor_num, GdkRectangle* dest)" Xen_check_type(Xen_is_GdkScreen_(screen), screen, 1, "gdk_screen_get_monitor_geometry", "GdkScreen*"); Xen_check_type(Xen_is_int(monitor_num), monitor_num, 2, "gdk_screen_get_monitor_geometry", "int"); Xen_check_type(Xen_is_GdkRectangle_(dest), dest, 3, "gdk_screen_get_monitor_geometry", "GdkRectangle*"); gdk_screen_get_monitor_geometry(Xen_to_C_GdkScreen_(screen), Xen_to_C_int(monitor_num), Xen_to_C_GdkRectangle_(dest)); return(Xen_false); } static Xen gxg_gdk_screen_get_monitor_at_point(Xen screen, Xen x, Xen y) { #define H_gdk_screen_get_monitor_at_point "int gdk_screen_get_monitor_at_point(GdkScreen* screen, int x, \ int y)" Xen_check_type(Xen_is_GdkScreen_(screen), screen, 1, "gdk_screen_get_monitor_at_point", "GdkScreen*"); Xen_check_type(Xen_is_int(x), x, 2, "gdk_screen_get_monitor_at_point", "int"); Xen_check_type(Xen_is_int(y), y, 3, "gdk_screen_get_monitor_at_point", "int"); return(C_to_Xen_int(gdk_screen_get_monitor_at_point(Xen_to_C_GdkScreen_(screen), Xen_to_C_int(x), Xen_to_C_int(y)))); } static Xen gxg_gdk_screen_get_monitor_at_window(Xen screen, Xen window) { #define H_gdk_screen_get_monitor_at_window "int gdk_screen_get_monitor_at_window(GdkScreen* screen, \ GdkWindow* window)" Xen_check_type(Xen_is_GdkScreen_(screen), screen, 1, "gdk_screen_get_monitor_at_window", "GdkScreen*"); Xen_check_type(Xen_is_GdkWindow_(window), window, 2, "gdk_screen_get_monitor_at_window", "GdkWindow*"); return(C_to_Xen_int(gdk_screen_get_monitor_at_window(Xen_to_C_GdkScreen_(screen), Xen_to_C_GdkWindow_(window)))); } static Xen gxg_gdk_screen_get_default(void) { #define H_gdk_screen_get_default "GdkScreen* gdk_screen_get_default( void)" return(C_to_Xen_GdkScreen_(gdk_screen_get_default())); } static Xen gxg_gtk_clipboard_get_for_display(Xen display, Xen selection) { #define H_gtk_clipboard_get_for_display "GtkClipboard* gtk_clipboard_get_for_display(GdkDisplay* display, \ GdkAtom selection)" Xen_check_type(Xen_is_GdkDisplay_(display), display, 1, "gtk_clipboard_get_for_display", "GdkDisplay*"); Xen_check_type(Xen_is_GdkAtom(selection), selection, 2, "gtk_clipboard_get_for_display", "GdkAtom"); return(C_to_Xen_GtkClipboard_(gtk_clipboard_get_for_display(Xen_to_C_GdkDisplay_(display), Xen_to_C_GdkAtom(selection)))); } static Xen gxg_gtk_clipboard_get_display(Xen clipboard) { #define H_gtk_clipboard_get_display "GdkDisplay* gtk_clipboard_get_display(GtkClipboard* clipboard)" Xen_check_type(Xen_is_GtkClipboard_(clipboard), clipboard, 1, "gtk_clipboard_get_display", "GtkClipboard*"); return(C_to_Xen_GdkDisplay_(gtk_clipboard_get_display(Xen_to_C_GtkClipboard_(clipboard)))); } static Xen gxg_gtk_widget_get_screen(Xen widget) { #define H_gtk_widget_get_screen "GdkScreen* gtk_widget_get_screen(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_screen", "GtkWidget*"); return(C_to_Xen_GdkScreen_(gtk_widget_get_screen(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_has_screen(Xen widget) { #define H_gtk_widget_has_screen "gboolean gtk_widget_has_screen(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_has_screen", "GtkWidget*"); return(C_to_Xen_gboolean(gtk_widget_has_screen(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_get_display(Xen widget) { #define H_gtk_widget_get_display "GdkDisplay* gtk_widget_get_display(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_display", "GtkWidget*"); return(C_to_Xen_GdkDisplay_(gtk_widget_get_display(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_get_clipboard(Xen widget, Xen selection) { #define H_gtk_widget_get_clipboard "GtkClipboard* gtk_widget_get_clipboard(GtkWidget* widget, GdkAtom selection)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_clipboard", "GtkWidget*"); Xen_check_type(Xen_is_GdkAtom(selection), selection, 2, "gtk_widget_get_clipboard", "GdkAtom"); return(C_to_Xen_GtkClipboard_(gtk_widget_get_clipboard(Xen_to_C_GtkWidget_(widget), Xen_to_C_GdkAtom(selection)))); } static Xen gxg_g_list_free(Xen list) { #define H_g_list_free "void g_list_free(GList* list)" Xen_check_type(Xen_is_GList_(list), list, 1, "g_list_free", "GList*"); g_list_free(Xen_to_C_GList_(list)); return(Xen_false); } static Xen gxg_g_list_reverse(Xen list) { #define H_g_list_reverse "GList* g_list_reverse(GList* list)" Xen_check_type(Xen_is_GList_(list) || Xen_is_false(list), list, 1, "g_list_reverse", "GList*"); return(C_to_Xen_GList_(g_list_reverse(Xen_to_C_GList_(list)))); } static Xen gxg_g_list_copy(Xen list) { #define H_g_list_copy "GList* g_list_copy(GList* list)" Xen_check_type(Xen_is_GList_(list) || Xen_is_false(list), list, 1, "g_list_copy", "GList*"); return(C_to_Xen_GList_(g_list_copy(Xen_to_C_GList_(list)))); } static Xen gxg_g_list_last(Xen list) { #define H_g_list_last "GList* g_list_last(GList* list)" Xen_check_type(Xen_is_GList_(list), list, 1, "g_list_last", "GList*"); return(C_to_Xen_GList_(g_list_last(Xen_to_C_GList_(list)))); } static Xen gxg_g_list_first(Xen list) { #define H_g_list_first "GList* g_list_first(GList* list)" Xen_check_type(Xen_is_GList_(list), list, 1, "g_list_first", "GList*"); return(C_to_Xen_GList_(g_list_first(Xen_to_C_GList_(list)))); } static Xen gxg_g_list_length(Xen list) { #define H_g_list_length "guint g_list_length(GList* list)" Xen_check_type(Xen_is_GList_(list) || Xen_is_false(list), list, 1, "g_list_length", "GList*"); return(C_to_Xen_guint(g_list_length(Xen_to_C_GList_(list)))); } static Xen gxg_g_free(Xen mem) { #define H_g_free "void g_free(gpointer mem)" Xen_check_type(Xen_is_gpointer(mem), mem, 1, "g_free", "gpointer"); g_free(Xen_to_C_gpointer(mem)); return(Xen_false); } static Xen gxg_g_list_remove_link(Xen list, Xen llink) { #define H_g_list_remove_link "GList* g_list_remove_link(GList* list, GList* llink)" Xen_check_type(Xen_is_GList_(list), list, 1, "g_list_remove_link", "GList*"); Xen_check_type(Xen_is_GList_(llink), llink, 2, "g_list_remove_link", "GList*"); return(C_to_Xen_GList_(g_list_remove_link(Xen_to_C_GList_(list), Xen_to_C_GList_(llink)))); } static Xen gxg_g_object_get_data(Xen object, Xen key) { #define H_g_object_get_data "gpointer g_object_get_data(GObject* object, gchar* key)" Xen_check_type(Xen_is_GObject_(object), object, 1, "g_object_get_data", "GObject*"); Xen_check_type(Xen_is_gchar_(key), key, 2, "g_object_get_data", "gchar*"); return(C_to_Xen_gpointer(g_object_get_data(Xen_to_C_GObject_(object), (const gchar*)Xen_to_C_gchar_(key)))); } static Xen gxg_g_object_set_data(Xen object, Xen key, Xen data) { #define H_g_object_set_data "void g_object_set_data(GObject* object, gchar* key, gpointer data)" Xen_check_type(Xen_is_GObject_(object), object, 1, "g_object_set_data", "GObject*"); Xen_check_type(Xen_is_gchar_(key), key, 2, "g_object_set_data", "gchar*"); Xen_check_type(Xen_is_gpointer(data), data, 3, "g_object_set_data", "gpointer"); g_object_set_data(Xen_to_C_GObject_(object), (const gchar*)Xen_to_C_gchar_(key), Xen_to_C_gpointer(data)); return(Xen_false); } static Xen gxg_gdk_cursor_new_from_pixbuf(Xen display, Xen pixbuf, Xen x, Xen y) { #define H_gdk_cursor_new_from_pixbuf "GdkCursor* gdk_cursor_new_from_pixbuf(GdkDisplay* display, GdkPixbuf* pixbuf, \ gint x, gint y)" Xen_check_type(Xen_is_GdkDisplay_(display), display, 1, "gdk_cursor_new_from_pixbuf", "GdkDisplay*"); Xen_check_type(Xen_is_GdkPixbuf_(pixbuf), pixbuf, 2, "gdk_cursor_new_from_pixbuf", "GdkPixbuf*"); Xen_check_type(Xen_is_gint(x), x, 3, "gdk_cursor_new_from_pixbuf", "gint"); Xen_check_type(Xen_is_gint(y), y, 4, "gdk_cursor_new_from_pixbuf", "gint"); return(C_to_Xen_GdkCursor_(gdk_cursor_new_from_pixbuf(Xen_to_C_GdkDisplay_(display), Xen_to_C_GdkPixbuf_(pixbuf), Xen_to_C_gint(x), Xen_to_C_gint(y)))); } static Xen gxg_gdk_display_flush(Xen display) { #define H_gdk_display_flush "void gdk_display_flush(GdkDisplay* display)" Xen_check_type(Xen_is_GdkDisplay_(display), display, 1, "gdk_display_flush", "GdkDisplay*"); gdk_display_flush(Xen_to_C_GdkDisplay_(display)); return(Xen_false); } static Xen gxg_gdk_display_supports_cursor_alpha(Xen display) { #define H_gdk_display_supports_cursor_alpha "gboolean gdk_display_supports_cursor_alpha(GdkDisplay* display)" Xen_check_type(Xen_is_GdkDisplay_(display), display, 1, "gdk_display_supports_cursor_alpha", "GdkDisplay*"); return(C_to_Xen_gboolean(gdk_display_supports_cursor_alpha(Xen_to_C_GdkDisplay_(display)))); } static Xen gxg_gdk_display_supports_cursor_color(Xen display) { #define H_gdk_display_supports_cursor_color "gboolean gdk_display_supports_cursor_color(GdkDisplay* display)" Xen_check_type(Xen_is_GdkDisplay_(display), display, 1, "gdk_display_supports_cursor_color", "GdkDisplay*"); return(C_to_Xen_gboolean(gdk_display_supports_cursor_color(Xen_to_C_GdkDisplay_(display)))); } static Xen gxg_gdk_display_get_default_cursor_size(Xen display) { #define H_gdk_display_get_default_cursor_size "guint gdk_display_get_default_cursor_size(GdkDisplay* display)" Xen_check_type(Xen_is_GdkDisplay_(display), display, 1, "gdk_display_get_default_cursor_size", "GdkDisplay*"); return(C_to_Xen_guint(gdk_display_get_default_cursor_size(Xen_to_C_GdkDisplay_(display)))); } static Xen gxg_gdk_display_get_maximal_cursor_size(Xen display, Xen ignore_width, Xen ignore_height) { #define H_gdk_display_get_maximal_cursor_size "void gdk_display_get_maximal_cursor_size(GdkDisplay* display, \ guint* [width], guint* [height])" guint ref_width; guint ref_height; Xen_check_type(Xen_is_GdkDisplay_(display), display, 1, "gdk_display_get_maximal_cursor_size", "GdkDisplay*"); gdk_display_get_maximal_cursor_size(Xen_to_C_GdkDisplay_(display), &ref_width, &ref_height); return(Xen_list_2(C_to_Xen_guint(ref_width), C_to_Xen_guint(ref_height))); } static Xen gxg_gdk_window_set_keep_above(Xen window, Xen setting) { #define H_gdk_window_set_keep_above "void gdk_window_set_keep_above(GdkWindow* window, gboolean setting)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_set_keep_above", "GdkWindow*"); Xen_check_type(Xen_is_gboolean(setting), setting, 2, "gdk_window_set_keep_above", "gboolean"); gdk_window_set_keep_above(Xen_to_C_GdkWindow_(window), Xen_to_C_gboolean(setting)); return(Xen_false); } static Xen gxg_gdk_window_set_keep_below(Xen window, Xen setting) { #define H_gdk_window_set_keep_below "void gdk_window_set_keep_below(GdkWindow* window, gboolean setting)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_set_keep_below", "GdkWindow*"); Xen_check_type(Xen_is_gboolean(setting), setting, 2, "gdk_window_set_keep_below", "gboolean"); gdk_window_set_keep_below(Xen_to_C_GdkWindow_(window), Xen_to_C_gboolean(setting)); return(Xen_false); } static Xen gxg_gtk_button_box_get_child_secondary(Xen widget, Xen child) { #define H_gtk_button_box_get_child_secondary "gboolean gtk_button_box_get_child_secondary(GtkButtonBox* widget, \ GtkWidget* child)" Xen_check_type(Xen_is_GtkButtonBox_(widget), widget, 1, "gtk_button_box_get_child_secondary", "GtkButtonBox*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_button_box_get_child_secondary", "GtkWidget*"); return(C_to_Xen_gboolean(gtk_button_box_get_child_secondary(Xen_to_C_GtkButtonBox_(widget), Xen_to_C_GtkWidget_(child)))); } static Xen gxg_gtk_calendar_set_display_options(Xen calendar, Xen flags) { #define H_gtk_calendar_set_display_options "void gtk_calendar_set_display_options(GtkCalendar* calendar, \ GtkCalendarDisplayOptions flags)" Xen_check_type(Xen_is_GtkCalendar_(calendar), calendar, 1, "gtk_calendar_set_display_options", "GtkCalendar*"); Xen_check_type(Xen_is_GtkCalendarDisplayOptions(flags), flags, 2, "gtk_calendar_set_display_options", "GtkCalendarDisplayOptions"); gtk_calendar_set_display_options(Xen_to_C_GtkCalendar_(calendar), Xen_to_C_GtkCalendarDisplayOptions(flags)); return(Xen_false); } static Xen gxg_gtk_calendar_get_display_options(Xen calendar) { #define H_gtk_calendar_get_display_options "GtkCalendarDisplayOptions gtk_calendar_get_display_options(GtkCalendar* calendar)" Xen_check_type(Xen_is_GtkCalendar_(calendar), calendar, 1, "gtk_calendar_get_display_options", "GtkCalendar*"); return(C_to_Xen_GtkCalendarDisplayOptions(gtk_calendar_get_display_options(Xen_to_C_GtkCalendar_(calendar)))); } static Xen gxg_gtk_check_menu_item_set_draw_as_radio(Xen check_menu_item, Xen draw_as_radio) { #define H_gtk_check_menu_item_set_draw_as_radio "void gtk_check_menu_item_set_draw_as_radio(GtkCheckMenuItem* check_menu_item, \ gboolean draw_as_radio)" Xen_check_type(Xen_is_GtkCheckMenuItem_(check_menu_item), check_menu_item, 1, "gtk_check_menu_item_set_draw_as_radio", "GtkCheckMenuItem*"); Xen_check_type(Xen_is_gboolean(draw_as_radio), draw_as_radio, 2, "gtk_check_menu_item_set_draw_as_radio", "gboolean"); gtk_check_menu_item_set_draw_as_radio(Xen_to_C_GtkCheckMenuItem_(check_menu_item), Xen_to_C_gboolean(draw_as_radio)); return(Xen_false); } static Xen gxg_gtk_check_menu_item_get_draw_as_radio(Xen check_menu_item) { #define H_gtk_check_menu_item_get_draw_as_radio "gboolean gtk_check_menu_item_get_draw_as_radio(GtkCheckMenuItem* check_menu_item)" Xen_check_type(Xen_is_GtkCheckMenuItem_(check_menu_item), check_menu_item, 1, "gtk_check_menu_item_get_draw_as_radio", "GtkCheckMenuItem*"); return(C_to_Xen_gboolean(gtk_check_menu_item_get_draw_as_radio(Xen_to_C_GtkCheckMenuItem_(check_menu_item)))); } static Xen gxg_gtk_entry_set_completion(Xen entry, Xen completion) { #define H_gtk_entry_set_completion "void gtk_entry_set_completion(GtkEntry* entry, GtkEntryCompletion* completion)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_set_completion", "GtkEntry*"); Xen_check_type(Xen_is_GtkEntryCompletion_(completion), completion, 2, "gtk_entry_set_completion", "GtkEntryCompletion*"); gtk_entry_set_completion(Xen_to_C_GtkEntry_(entry), Xen_to_C_GtkEntryCompletion_(completion)); return(Xen_false); } static Xen gxg_gtk_entry_get_completion(Xen entry) { #define H_gtk_entry_get_completion "GtkEntryCompletion* gtk_entry_get_completion(GtkEntry* entry)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_get_completion", "GtkEntry*"); return(C_to_Xen_GtkEntryCompletion_(gtk_entry_get_completion(Xen_to_C_GtkEntry_(entry)))); } static Xen gxg_gtk_event_box_get_visible_window(Xen event_box) { #define H_gtk_event_box_get_visible_window "gboolean gtk_event_box_get_visible_window(GtkEventBox* event_box)" Xen_check_type(Xen_is_GtkEventBox_(event_box), event_box, 1, "gtk_event_box_get_visible_window", "GtkEventBox*"); return(C_to_Xen_gboolean(gtk_event_box_get_visible_window(Xen_to_C_GtkEventBox_(event_box)))); } static Xen gxg_gtk_event_box_set_visible_window(Xen event_box, Xen visible_window) { #define H_gtk_event_box_set_visible_window "void gtk_event_box_set_visible_window(GtkEventBox* event_box, \ gboolean visible_window)" Xen_check_type(Xen_is_GtkEventBox_(event_box), event_box, 1, "gtk_event_box_set_visible_window", "GtkEventBox*"); Xen_check_type(Xen_is_gboolean(visible_window), visible_window, 2, "gtk_event_box_set_visible_window", "gboolean"); gtk_event_box_set_visible_window(Xen_to_C_GtkEventBox_(event_box), Xen_to_C_gboolean(visible_window)); return(Xen_false); } static Xen gxg_gtk_event_box_get_above_child(Xen event_box) { #define H_gtk_event_box_get_above_child "gboolean gtk_event_box_get_above_child(GtkEventBox* event_box)" Xen_check_type(Xen_is_GtkEventBox_(event_box), event_box, 1, "gtk_event_box_get_above_child", "GtkEventBox*"); return(C_to_Xen_gboolean(gtk_event_box_get_above_child(Xen_to_C_GtkEventBox_(event_box)))); } static Xen gxg_gtk_event_box_set_above_child(Xen event_box, Xen above_child) { #define H_gtk_event_box_set_above_child "void gtk_event_box_set_above_child(GtkEventBox* event_box, \ gboolean above_child)" Xen_check_type(Xen_is_GtkEventBox_(event_box), event_box, 1, "gtk_event_box_set_above_child", "GtkEventBox*"); Xen_check_type(Xen_is_gboolean(above_child), above_child, 2, "gtk_event_box_set_above_child", "gboolean"); gtk_event_box_set_above_child(Xen_to_C_GtkEventBox_(event_box), Xen_to_C_gboolean(above_child)); return(Xen_false); } static Xen gxg_gtk_menu_attach(Xen menu, Xen child, Xen left_attach, Xen right_attach, Xen top_attach, Xen bottom_attach) { #define H_gtk_menu_attach "void gtk_menu_attach(GtkMenu* menu, GtkWidget* child, guint left_attach, \ guint right_attach, guint top_attach, guint bottom_attach)" Xen_check_type(Xen_is_GtkMenu_(menu), menu, 1, "gtk_menu_attach", "GtkMenu*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_menu_attach", "GtkWidget*"); Xen_check_type(Xen_is_guint(left_attach), left_attach, 3, "gtk_menu_attach", "guint"); Xen_check_type(Xen_is_guint(right_attach), right_attach, 4, "gtk_menu_attach", "guint"); Xen_check_type(Xen_is_guint(top_attach), top_attach, 5, "gtk_menu_attach", "guint"); Xen_check_type(Xen_is_guint(bottom_attach), bottom_attach, 6, "gtk_menu_attach", "guint"); gtk_menu_attach(Xen_to_C_GtkMenu_(menu), Xen_to_C_GtkWidget_(child), Xen_to_C_guint(left_attach), Xen_to_C_guint(right_attach), Xen_to_C_guint(top_attach), Xen_to_C_guint(bottom_attach)); return(Xen_false); } static Xen gxg_gtk_text_buffer_select_range(Xen buffer, Xen ins, Xen bound) { #define H_gtk_text_buffer_select_range "void gtk_text_buffer_select_range(GtkTextBuffer* buffer, GtkTextIter* ins, \ GtkTextIter* bound)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_select_range", "GtkTextBuffer*"); Xen_check_type(Xen_is_GtkTextIter_(ins), ins, 2, "gtk_text_buffer_select_range", "GtkTextIter*"); Xen_check_type(Xen_is_GtkTextIter_(bound), bound, 3, "gtk_text_buffer_select_range", "GtkTextIter*"); gtk_text_buffer_select_range(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_GtkTextIter_(ins), Xen_to_C_GtkTextIter_(bound)); return(Xen_false); } static Xen gxg_gtk_text_view_set_overwrite(Xen text_view, Xen overwrite) { #define H_gtk_text_view_set_overwrite "void gtk_text_view_set_overwrite(GtkTextView* text_view, gboolean overwrite)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_set_overwrite", "GtkTextView*"); Xen_check_type(Xen_is_gboolean(overwrite), overwrite, 2, "gtk_text_view_set_overwrite", "gboolean"); gtk_text_view_set_overwrite(Xen_to_C_GtkTextView_(text_view), Xen_to_C_gboolean(overwrite)); return(Xen_false); } static Xen gxg_gtk_text_view_get_overwrite(Xen text_view) { #define H_gtk_text_view_get_overwrite "gboolean gtk_text_view_get_overwrite(GtkTextView* text_view)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_get_overwrite", "GtkTextView*"); return(C_to_Xen_gboolean(gtk_text_view_get_overwrite(Xen_to_C_GtkTextView_(text_view)))); } static Xen gxg_gtk_text_view_set_accepts_tab(Xen text_view, Xen accepts_tab) { #define H_gtk_text_view_set_accepts_tab "void gtk_text_view_set_accepts_tab(GtkTextView* text_view, \ gboolean accepts_tab)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_set_accepts_tab", "GtkTextView*"); Xen_check_type(Xen_is_gboolean(accepts_tab), accepts_tab, 2, "gtk_text_view_set_accepts_tab", "gboolean"); gtk_text_view_set_accepts_tab(Xen_to_C_GtkTextView_(text_view), Xen_to_C_gboolean(accepts_tab)); return(Xen_false); } static Xen gxg_gtk_text_view_get_accepts_tab(Xen text_view) { #define H_gtk_text_view_get_accepts_tab "gboolean gtk_text_view_get_accepts_tab(GtkTextView* text_view)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_get_accepts_tab", "GtkTextView*"); return(C_to_Xen_gboolean(gtk_text_view_get_accepts_tab(Xen_to_C_GtkTextView_(text_view)))); } static Xen gxg_gtk_toolbar_insert(Xen toolbar, Xen item, Xen pos) { #define H_gtk_toolbar_insert "void gtk_toolbar_insert(GtkToolbar* toolbar, GtkToolItem* item, gint pos)" Xen_check_type(Xen_is_GtkToolbar_(toolbar), toolbar, 1, "gtk_toolbar_insert", "GtkToolbar*"); Xen_check_type(Xen_is_GtkToolItem_(item), item, 2, "gtk_toolbar_insert", "GtkToolItem*"); Xen_check_type(Xen_is_gint(pos), pos, 3, "gtk_toolbar_insert", "gint"); gtk_toolbar_insert(Xen_to_C_GtkToolbar_(toolbar), Xen_to_C_GtkToolItem_(item), Xen_to_C_gint(pos)); return(Xen_false); } static Xen gxg_gtk_toolbar_get_item_index(Xen toolbar, Xen item) { #define H_gtk_toolbar_get_item_index "gint gtk_toolbar_get_item_index(GtkToolbar* toolbar, GtkToolItem* item)" Xen_check_type(Xen_is_GtkToolbar_(toolbar), toolbar, 1, "gtk_toolbar_get_item_index", "GtkToolbar*"); Xen_check_type(Xen_is_GtkToolItem_(item), item, 2, "gtk_toolbar_get_item_index", "GtkToolItem*"); return(C_to_Xen_gint(gtk_toolbar_get_item_index(Xen_to_C_GtkToolbar_(toolbar), Xen_to_C_GtkToolItem_(item)))); } static Xen gxg_gtk_toolbar_get_n_items(Xen toolbar) { #define H_gtk_toolbar_get_n_items "gint gtk_toolbar_get_n_items(GtkToolbar* toolbar)" Xen_check_type(Xen_is_GtkToolbar_(toolbar), toolbar, 1, "gtk_toolbar_get_n_items", "GtkToolbar*"); return(C_to_Xen_gint(gtk_toolbar_get_n_items(Xen_to_C_GtkToolbar_(toolbar)))); } static Xen gxg_gtk_toolbar_get_nth_item(Xen toolbar, Xen n) { #define H_gtk_toolbar_get_nth_item "GtkToolItem* gtk_toolbar_get_nth_item(GtkToolbar* toolbar, gint n)" Xen_check_type(Xen_is_GtkToolbar_(toolbar), toolbar, 1, "gtk_toolbar_get_nth_item", "GtkToolbar*"); Xen_check_type(Xen_is_gint(n), n, 2, "gtk_toolbar_get_nth_item", "gint"); return(C_to_Xen_GtkToolItem_(gtk_toolbar_get_nth_item(Xen_to_C_GtkToolbar_(toolbar), Xen_to_C_gint(n)))); } static Xen gxg_gtk_toolbar_set_show_arrow(Xen toolbar, Xen show_arrow) { #define H_gtk_toolbar_set_show_arrow "void gtk_toolbar_set_show_arrow(GtkToolbar* toolbar, gboolean show_arrow)" Xen_check_type(Xen_is_GtkToolbar_(toolbar), toolbar, 1, "gtk_toolbar_set_show_arrow", "GtkToolbar*"); Xen_check_type(Xen_is_gboolean(show_arrow), show_arrow, 2, "gtk_toolbar_set_show_arrow", "gboolean"); gtk_toolbar_set_show_arrow(Xen_to_C_GtkToolbar_(toolbar), Xen_to_C_gboolean(show_arrow)); return(Xen_false); } static Xen gxg_gtk_toolbar_get_show_arrow(Xen toolbar) { #define H_gtk_toolbar_get_show_arrow "gboolean gtk_toolbar_get_show_arrow(GtkToolbar* toolbar)" Xen_check_type(Xen_is_GtkToolbar_(toolbar), toolbar, 1, "gtk_toolbar_get_show_arrow", "GtkToolbar*"); return(C_to_Xen_gboolean(gtk_toolbar_get_show_arrow(Xen_to_C_GtkToolbar_(toolbar)))); } static Xen gxg_gtk_toolbar_get_relief_style(Xen toolbar) { #define H_gtk_toolbar_get_relief_style "GtkReliefStyle gtk_toolbar_get_relief_style(GtkToolbar* toolbar)" Xen_check_type(Xen_is_GtkToolbar_(toolbar), toolbar, 1, "gtk_toolbar_get_relief_style", "GtkToolbar*"); return(C_to_Xen_GtkReliefStyle(gtk_toolbar_get_relief_style(Xen_to_C_GtkToolbar_(toolbar)))); } static Xen gxg_gtk_toolbar_get_drop_index(Xen toolbar, Xen x, Xen y) { #define H_gtk_toolbar_get_drop_index "gint gtk_toolbar_get_drop_index(GtkToolbar* toolbar, gint x, \ gint y)" Xen_check_type(Xen_is_GtkToolbar_(toolbar), toolbar, 1, "gtk_toolbar_get_drop_index", "GtkToolbar*"); Xen_check_type(Xen_is_gint(x), x, 2, "gtk_toolbar_get_drop_index", "gint"); Xen_check_type(Xen_is_gint(y), y, 3, "gtk_toolbar_get_drop_index", "gint"); return(C_to_Xen_gint(gtk_toolbar_get_drop_index(Xen_to_C_GtkToolbar_(toolbar), Xen_to_C_gint(x), Xen_to_C_gint(y)))); } static Xen gxg_gtk_tree_view_column_set_expand(Xen tree_column, Xen expand) { #define H_gtk_tree_view_column_set_expand "void gtk_tree_view_column_set_expand(GtkTreeViewColumn* tree_column, \ gboolean expand)" Xen_check_type(Xen_is_GtkTreeViewColumn_(tree_column), tree_column, 1, "gtk_tree_view_column_set_expand", "GtkTreeViewColumn*"); Xen_check_type(Xen_is_gboolean(expand), expand, 2, "gtk_tree_view_column_set_expand", "gboolean"); gtk_tree_view_column_set_expand(Xen_to_C_GtkTreeViewColumn_(tree_column), Xen_to_C_gboolean(expand)); return(Xen_false); } static Xen gxg_gtk_tree_view_column_get_expand(Xen tree_column) { #define H_gtk_tree_view_column_get_expand "gboolean gtk_tree_view_column_get_expand(GtkTreeViewColumn* tree_column)" Xen_check_type(Xen_is_GtkTreeViewColumn_(tree_column), tree_column, 1, "gtk_tree_view_column_get_expand", "GtkTreeViewColumn*"); return(C_to_Xen_gboolean(gtk_tree_view_column_get_expand(Xen_to_C_GtkTreeViewColumn_(tree_column)))); } static Xen gxg_gtk_widget_set_no_show_all(Xen widget, Xen no_show_all) { #define H_gtk_widget_set_no_show_all "void gtk_widget_set_no_show_all(GtkWidget* widget, gboolean no_show_all)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_set_no_show_all", "GtkWidget*"); Xen_check_type(Xen_is_gboolean(no_show_all), no_show_all, 2, "gtk_widget_set_no_show_all", "gboolean"); gtk_widget_set_no_show_all(Xen_to_C_GtkWidget_(widget), Xen_to_C_gboolean(no_show_all)); return(Xen_false); } static Xen gxg_gtk_widget_get_no_show_all(Xen widget) { #define H_gtk_widget_get_no_show_all "gboolean gtk_widget_get_no_show_all(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_no_show_all", "GtkWidget*"); return(C_to_Xen_gboolean(gtk_widget_get_no_show_all(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_queue_resize_no_redraw(Xen widget) { #define H_gtk_widget_queue_resize_no_redraw "void gtk_widget_queue_resize_no_redraw(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_queue_resize_no_redraw", "GtkWidget*"); gtk_widget_queue_resize_no_redraw(Xen_to_C_GtkWidget_(widget)); return(Xen_false); } static Xen gxg_gtk_window_set_default_icon(Xen icon) { #define H_gtk_window_set_default_icon "void gtk_window_set_default_icon(GdkPixbuf* icon)" Xen_check_type(Xen_is_GdkPixbuf_(icon), icon, 1, "gtk_window_set_default_icon", "GdkPixbuf*"); gtk_window_set_default_icon(Xen_to_C_GdkPixbuf_(icon)); return(Xen_false); } static Xen gxg_gtk_window_set_keep_above(Xen window, Xen setting) { #define H_gtk_window_set_keep_above "void gtk_window_set_keep_above(GtkWindow* window, gboolean setting)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_set_keep_above", "GtkWindow*"); Xen_check_type(Xen_is_gboolean(setting), setting, 2, "gtk_window_set_keep_above", "gboolean"); gtk_window_set_keep_above(Xen_to_C_GtkWindow_(window), Xen_to_C_gboolean(setting)); return(Xen_false); } static Xen gxg_gtk_window_set_keep_below(Xen window, Xen setting) { #define H_gtk_window_set_keep_below "void gtk_window_set_keep_below(GtkWindow* window, gboolean setting)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_set_keep_below", "GtkWindow*"); Xen_check_type(Xen_is_gboolean(setting), setting, 2, "gtk_window_set_keep_below", "gboolean"); gtk_window_set_keep_below(Xen_to_C_GtkWindow_(window), Xen_to_C_gboolean(setting)); return(Xen_false); } static Xen gxg_gtk_file_chooser_dialog_new(Xen title, Xen parent, Xen action, Xen buttons) { #define H_gtk_file_chooser_dialog_new "GtkWidget* gtk_file_chooser_dialog_new(gchar* title, GtkWindow* parent, \ GtkFileChooserAction action, etc buttons)" Xen_check_type(Xen_is_gchar_(title), title, 1, "gtk_file_chooser_dialog_new", "gchar*"); Xen_check_type(Xen_is_GtkWindow_(parent) || Xen_is_false(parent), parent, 2, "gtk_file_chooser_dialog_new", "GtkWindow*"); Xen_check_type(Xen_is_GtkFileChooserAction(action), action, 3, "gtk_file_chooser_dialog_new", "GtkFileChooserAction"); if (!Xen_is_bound(buttons)) buttons = Xen_false; else Xen_check_type(Xen_is_etc(buttons), buttons, 4, "gtk_file_chooser_dialog_new", "etc"); { int etc_len = 0; GtkWidget* result = NULL; gchar* p_arg0; GtkWindow* p_arg1; GtkFileChooserAction p_arg2; if (Xen_is_list(buttons)) etc_len = Xen_list_length(buttons); if (etc_len > 10) Xen_out_of_range_error("gtk_file_chooser_dialog_new", 3, buttons, "... list too long (max len: 10)"); if ((etc_len % 2) != 0) Xen_out_of_range_error("gtk_file_chooser_dialog_new", 3, buttons, "... list len must be multiple of 2"); p_arg0 = Xen_to_C_gchar_(title); p_arg1 = Xen_to_C_GtkWindow_(parent); p_arg2 = Xen_to_C_GtkFileChooserAction(action); switch (etc_len) { case 0: result = gtk_file_chooser_dialog_new(p_arg0, p_arg1, p_arg2, NULL, NULL); break; case 2: result = gtk_file_chooser_dialog_new(p_arg0, p_arg1, p_arg2, XLS(buttons, 0), XLI(buttons, 1), NULL); break; case 4: result = gtk_file_chooser_dialog_new(p_arg0, p_arg1, p_arg2, XLS(buttons, 0), XLI(buttons, 1), XLS(buttons, 2), XLI(buttons, 3), NULL); break; case 6: result = gtk_file_chooser_dialog_new(p_arg0, p_arg1, p_arg2, XLS(buttons, 0), XLI(buttons, 1), XLS(buttons, 2), XLI(buttons, 3), XLS(buttons, 4), XLI(buttons, 5), NULL); break; case 8: result = gtk_file_chooser_dialog_new(p_arg0, p_arg1, p_arg2, XLS(buttons, 0), XLI(buttons, 1), XLS(buttons, 2), XLI(buttons, 3), XLS(buttons, 4), XLI(buttons, 5), XLS(buttons, 6), XLI(buttons, 7), NULL); break; case 10: result = gtk_file_chooser_dialog_new(p_arg0, p_arg1, p_arg2, XLS(buttons, 0), XLI(buttons, 1), XLS(buttons, 2), XLI(buttons, 3), XLS(buttons, 4), XLI(buttons, 5), XLS(buttons, 6), XLI(buttons, 7), XLS(buttons, 8), XLI(buttons, 9), NULL); break; } return(C_to_Xen_GtkWidget_(result)); } } static Xen gxg_gtk_file_chooser_widget_new(Xen action) { #define H_gtk_file_chooser_widget_new "GtkWidget* gtk_file_chooser_widget_new(GtkFileChooserAction action)" Xen_check_type(Xen_is_GtkFileChooserAction(action), action, 1, "gtk_file_chooser_widget_new", "GtkFileChooserAction"); return(C_to_Xen_GtkWidget_(gtk_file_chooser_widget_new(Xen_to_C_GtkFileChooserAction(action)))); } static Xen gxg_gtk_tree_model_filter_new(Xen child_model, Xen root) { #define H_gtk_tree_model_filter_new "GtkTreeModel* gtk_tree_model_filter_new(GtkTreeModel* child_model, \ GtkTreePath* root)" Xen_check_type(Xen_is_GtkTreeModel_(child_model), child_model, 1, "gtk_tree_model_filter_new", "GtkTreeModel*"); Xen_check_type(Xen_is_GtkTreePath_(root) || Xen_is_false(root), root, 2, "gtk_tree_model_filter_new", "GtkTreePath*"); return(C_to_Xen_GtkTreeModel_(gtk_tree_model_filter_new(Xen_to_C_GtkTreeModel_(child_model), Xen_to_C_GtkTreePath_(root)))); } static Xen gxg_gtk_tree_model_filter_set_visible_column(Xen filter, Xen column) { #define H_gtk_tree_model_filter_set_visible_column "void gtk_tree_model_filter_set_visible_column(GtkTreeModelFilter* filter, \ gint column)" Xen_check_type(Xen_is_GtkTreeModelFilter_(filter), filter, 1, "gtk_tree_model_filter_set_visible_column", "GtkTreeModelFilter*"); Xen_check_type(Xen_is_gint(column), column, 2, "gtk_tree_model_filter_set_visible_column", "gint"); gtk_tree_model_filter_set_visible_column(Xen_to_C_GtkTreeModelFilter_(filter), Xen_to_C_gint(column)); return(Xen_false); } static Xen gxg_gtk_tree_model_filter_get_model(Xen filter) { #define H_gtk_tree_model_filter_get_model "GtkTreeModel* gtk_tree_model_filter_get_model(GtkTreeModelFilter* filter)" Xen_check_type(Xen_is_GtkTreeModelFilter_(filter), filter, 1, "gtk_tree_model_filter_get_model", "GtkTreeModelFilter*"); return(C_to_Xen_GtkTreeModel_(gtk_tree_model_filter_get_model(Xen_to_C_GtkTreeModelFilter_(filter)))); } static Xen gxg_gtk_tree_model_filter_convert_iter_to_child_iter(Xen filter, Xen child_iter, Xen filter_iter) { #define H_gtk_tree_model_filter_convert_iter_to_child_iter "void gtk_tree_model_filter_convert_iter_to_child_iter(GtkTreeModelFilter* filter, \ GtkTreeIter* child_iter, GtkTreeIter* filter_iter)" Xen_check_type(Xen_is_GtkTreeModelFilter_(filter), filter, 1, "gtk_tree_model_filter_convert_iter_to_child_iter", "GtkTreeModelFilter*"); Xen_check_type(Xen_is_GtkTreeIter_(child_iter), child_iter, 2, "gtk_tree_model_filter_convert_iter_to_child_iter", "GtkTreeIter*"); Xen_check_type(Xen_is_GtkTreeIter_(filter_iter), filter_iter, 3, "gtk_tree_model_filter_convert_iter_to_child_iter", "GtkTreeIter*"); gtk_tree_model_filter_convert_iter_to_child_iter(Xen_to_C_GtkTreeModelFilter_(filter), Xen_to_C_GtkTreeIter_(child_iter), Xen_to_C_GtkTreeIter_(filter_iter)); return(Xen_false); } static Xen gxg_gtk_tree_model_filter_convert_child_path_to_path(Xen filter, Xen child_path) { #define H_gtk_tree_model_filter_convert_child_path_to_path "GtkTreePath* gtk_tree_model_filter_convert_child_path_to_path(GtkTreeModelFilter* filter, \ GtkTreePath* child_path)" Xen_check_type(Xen_is_GtkTreeModelFilter_(filter), filter, 1, "gtk_tree_model_filter_convert_child_path_to_path", "GtkTreeModelFilter*"); Xen_check_type(Xen_is_GtkTreePath_(child_path), child_path, 2, "gtk_tree_model_filter_convert_child_path_to_path", "GtkTreePath*"); return(C_to_Xen_GtkTreePath_(gtk_tree_model_filter_convert_child_path_to_path(Xen_to_C_GtkTreeModelFilter_(filter), Xen_to_C_GtkTreePath_(child_path)))); } static Xen gxg_gtk_tree_model_filter_convert_path_to_child_path(Xen path, Xen filter_path) { #define H_gtk_tree_model_filter_convert_path_to_child_path "GtkTreePath* gtk_tree_model_filter_convert_path_to_child_path(GtkTreeModelFilter* path, \ GtkTreePath* filter_path)" Xen_check_type(Xen_is_GtkTreeModelFilter_(path), path, 1, "gtk_tree_model_filter_convert_path_to_child_path", "GtkTreeModelFilter*"); Xen_check_type(Xen_is_GtkTreePath_(filter_path), filter_path, 2, "gtk_tree_model_filter_convert_path_to_child_path", "GtkTreePath*"); return(C_to_Xen_GtkTreePath_(gtk_tree_model_filter_convert_path_to_child_path(Xen_to_C_GtkTreeModelFilter_(path), Xen_to_C_GtkTreePath_(filter_path)))); } static Xen gxg_gtk_tree_model_filter_refilter(Xen filter) { #define H_gtk_tree_model_filter_refilter "void gtk_tree_model_filter_refilter(GtkTreeModelFilter* filter)" Xen_check_type(Xen_is_GtkTreeModelFilter_(filter), filter, 1, "gtk_tree_model_filter_refilter", "GtkTreeModelFilter*"); gtk_tree_model_filter_refilter(Xen_to_C_GtkTreeModelFilter_(filter)); return(Xen_false); } static Xen gxg_gtk_tree_model_filter_clear_cache(Xen filter) { #define H_gtk_tree_model_filter_clear_cache "void gtk_tree_model_filter_clear_cache(GtkTreeModelFilter* filter)" Xen_check_type(Xen_is_GtkTreeModelFilter_(filter), filter, 1, "gtk_tree_model_filter_clear_cache", "GtkTreeModelFilter*"); gtk_tree_model_filter_clear_cache(Xen_to_C_GtkTreeModelFilter_(filter)); return(Xen_false); } static Xen gxg_gtk_combo_box_new(void) { #define H_gtk_combo_box_new "GtkWidget* gtk_combo_box_new( void)" return(C_to_Xen_GtkWidget_(gtk_combo_box_new())); } static Xen gxg_gtk_combo_box_new_with_model(Xen model) { #define H_gtk_combo_box_new_with_model "GtkWidget* gtk_combo_box_new_with_model(GtkTreeModel* model)" Xen_check_type(Xen_is_GtkTreeModel_(model), model, 1, "gtk_combo_box_new_with_model", "GtkTreeModel*"); return(C_to_Xen_GtkWidget_(gtk_combo_box_new_with_model(Xen_to_C_GtkTreeModel_(model)))); } static Xen gxg_gtk_combo_box_set_model(Xen combo_box, Xen model) { #define H_gtk_combo_box_set_model "void gtk_combo_box_set_model(GtkComboBox* combo_box, GtkTreeModel* model)" Xen_check_type(Xen_is_GtkComboBox_(combo_box), combo_box, 1, "gtk_combo_box_set_model", "GtkComboBox*"); Xen_check_type(Xen_is_GtkTreeModel_(model) || Xen_is_false(model), model, 2, "gtk_combo_box_set_model", "GtkTreeModel*"); gtk_combo_box_set_model(Xen_to_C_GtkComboBox_(combo_box), Xen_to_C_GtkTreeModel_(model)); return(Xen_false); } static Xen gxg_gtk_combo_box_set_wrap_width(Xen combo_box, Xen width) { #define H_gtk_combo_box_set_wrap_width "void gtk_combo_box_set_wrap_width(GtkComboBox* combo_box, gint width)" Xen_check_type(Xen_is_GtkComboBox_(combo_box), combo_box, 1, "gtk_combo_box_set_wrap_width", "GtkComboBox*"); Xen_check_type(Xen_is_gint(width), width, 2, "gtk_combo_box_set_wrap_width", "gint"); gtk_combo_box_set_wrap_width(Xen_to_C_GtkComboBox_(combo_box), Xen_to_C_gint(width)); return(Xen_false); } static Xen gxg_gtk_combo_box_set_row_span_column(Xen combo_box, Xen row_span) { #define H_gtk_combo_box_set_row_span_column "void gtk_combo_box_set_row_span_column(GtkComboBox* combo_box, \ gint row_span)" Xen_check_type(Xen_is_GtkComboBox_(combo_box), combo_box, 1, "gtk_combo_box_set_row_span_column", "GtkComboBox*"); Xen_check_type(Xen_is_gint(row_span), row_span, 2, "gtk_combo_box_set_row_span_column", "gint"); gtk_combo_box_set_row_span_column(Xen_to_C_GtkComboBox_(combo_box), Xen_to_C_gint(row_span)); return(Xen_false); } static Xen gxg_gtk_combo_box_set_column_span_column(Xen combo_box, Xen column_span) { #define H_gtk_combo_box_set_column_span_column "void gtk_combo_box_set_column_span_column(GtkComboBox* combo_box, \ gint column_span)" Xen_check_type(Xen_is_GtkComboBox_(combo_box), combo_box, 1, "gtk_combo_box_set_column_span_column", "GtkComboBox*"); Xen_check_type(Xen_is_gint(column_span), column_span, 2, "gtk_combo_box_set_column_span_column", "gint"); gtk_combo_box_set_column_span_column(Xen_to_C_GtkComboBox_(combo_box), Xen_to_C_gint(column_span)); return(Xen_false); } static Xen gxg_gtk_combo_box_get_active(Xen combo_box) { #define H_gtk_combo_box_get_active "gint gtk_combo_box_get_active(GtkComboBox* combo_box)" Xen_check_type(Xen_is_GtkComboBox_(combo_box), combo_box, 1, "gtk_combo_box_get_active", "GtkComboBox*"); return(C_to_Xen_gint(gtk_combo_box_get_active(Xen_to_C_GtkComboBox_(combo_box)))); } static Xen gxg_gtk_combo_box_set_active(Xen combo_box, Xen index) { #define H_gtk_combo_box_set_active "void gtk_combo_box_set_active(GtkComboBox* combo_box, gint index)" Xen_check_type(Xen_is_GtkComboBox_(combo_box), combo_box, 1, "gtk_combo_box_set_active", "GtkComboBox*"); Xen_check_type(Xen_is_gint(index), index, 2, "gtk_combo_box_set_active", "gint"); gtk_combo_box_set_active(Xen_to_C_GtkComboBox_(combo_box), Xen_to_C_gint(index)); return(Xen_false); } static Xen gxg_gtk_combo_box_get_active_iter(Xen combo_box, Xen iter) { #define H_gtk_combo_box_get_active_iter "gboolean gtk_combo_box_get_active_iter(GtkComboBox* combo_box, \ GtkTreeIter* iter)" Xen_check_type(Xen_is_GtkComboBox_(combo_box), combo_box, 1, "gtk_combo_box_get_active_iter", "GtkComboBox*"); Xen_check_type(Xen_is_GtkTreeIter_(iter), iter, 2, "gtk_combo_box_get_active_iter", "GtkTreeIter*"); return(C_to_Xen_gboolean(gtk_combo_box_get_active_iter(Xen_to_C_GtkComboBox_(combo_box), Xen_to_C_GtkTreeIter_(iter)))); } static Xen gxg_gtk_combo_box_set_active_iter(Xen combo_box, Xen iter) { #define H_gtk_combo_box_set_active_iter "void gtk_combo_box_set_active_iter(GtkComboBox* combo_box, \ GtkTreeIter* iter)" Xen_check_type(Xen_is_GtkComboBox_(combo_box), combo_box, 1, "gtk_combo_box_set_active_iter", "GtkComboBox*"); Xen_check_type(Xen_is_GtkTreeIter_(iter), iter, 2, "gtk_combo_box_set_active_iter", "GtkTreeIter*"); gtk_combo_box_set_active_iter(Xen_to_C_GtkComboBox_(combo_box), Xen_to_C_GtkTreeIter_(iter)); return(Xen_false); } static Xen gxg_gtk_combo_box_get_model(Xen combo_box) { #define H_gtk_combo_box_get_model "GtkTreeModel* gtk_combo_box_get_model(GtkComboBox* combo_box)" Xen_check_type(Xen_is_GtkComboBox_(combo_box), combo_box, 1, "gtk_combo_box_get_model", "GtkComboBox*"); return(C_to_Xen_GtkTreeModel_(gtk_combo_box_get_model(Xen_to_C_GtkComboBox_(combo_box)))); } static Xen gxg_gtk_expander_new(Xen label) { #define H_gtk_expander_new "GtkWidget* gtk_expander_new(gchar* label)" Xen_check_type(Xen_is_gchar_(label), label, 1, "gtk_expander_new", "gchar*"); return(C_to_Xen_GtkWidget_(gtk_expander_new(Xen_to_C_gchar_(label)))); } static Xen gxg_gtk_expander_new_with_mnemonic(Xen label) { #define H_gtk_expander_new_with_mnemonic "GtkWidget* gtk_expander_new_with_mnemonic(gchar* label)" Xen_check_type(Xen_is_gchar_(label), label, 1, "gtk_expander_new_with_mnemonic", "gchar*"); return(C_to_Xen_GtkWidget_(gtk_expander_new_with_mnemonic(Xen_to_C_gchar_(label)))); } static Xen gxg_gtk_expander_set_expanded(Xen expander, Xen expanded) { #define H_gtk_expander_set_expanded "void gtk_expander_set_expanded(GtkExpander* expander, gboolean expanded)" Xen_check_type(Xen_is_GtkExpander_(expander), expander, 1, "gtk_expander_set_expanded", "GtkExpander*"); Xen_check_type(Xen_is_gboolean(expanded), expanded, 2, "gtk_expander_set_expanded", "gboolean"); gtk_expander_set_expanded(Xen_to_C_GtkExpander_(expander), Xen_to_C_gboolean(expanded)); return(Xen_false); } static Xen gxg_gtk_expander_get_expanded(Xen expander) { #define H_gtk_expander_get_expanded "gboolean gtk_expander_get_expanded(GtkExpander* expander)" Xen_check_type(Xen_is_GtkExpander_(expander), expander, 1, "gtk_expander_get_expanded", "GtkExpander*"); return(C_to_Xen_gboolean(gtk_expander_get_expanded(Xen_to_C_GtkExpander_(expander)))); } static Xen gxg_gtk_expander_set_spacing(Xen expander, Xen spacing) { #define H_gtk_expander_set_spacing "void gtk_expander_set_spacing(GtkExpander* expander, gint spacing)" Xen_check_type(Xen_is_GtkExpander_(expander), expander, 1, "gtk_expander_set_spacing", "GtkExpander*"); Xen_check_type(Xen_is_gint(spacing), spacing, 2, "gtk_expander_set_spacing", "gint"); gtk_expander_set_spacing(Xen_to_C_GtkExpander_(expander), Xen_to_C_gint(spacing)); return(Xen_false); } static Xen gxg_gtk_expander_get_spacing(Xen expander) { #define H_gtk_expander_get_spacing "gint gtk_expander_get_spacing(GtkExpander* expander)" Xen_check_type(Xen_is_GtkExpander_(expander), expander, 1, "gtk_expander_get_spacing", "GtkExpander*"); return(C_to_Xen_gint(gtk_expander_get_spacing(Xen_to_C_GtkExpander_(expander)))); } static Xen gxg_gtk_expander_set_label(Xen expander, Xen label) { #define H_gtk_expander_set_label "void gtk_expander_set_label(GtkExpander* expander, gchar* label)" Xen_check_type(Xen_is_GtkExpander_(expander), expander, 1, "gtk_expander_set_label", "GtkExpander*"); Xen_check_type(Xen_is_gchar_(label), label, 2, "gtk_expander_set_label", "gchar*"); gtk_expander_set_label(Xen_to_C_GtkExpander_(expander), Xen_to_C_gchar_(label)); return(Xen_false); } static Xen gxg_gtk_expander_get_label(Xen expander) { #define H_gtk_expander_get_label "gchar* gtk_expander_get_label(GtkExpander* expander)" Xen_check_type(Xen_is_GtkExpander_(expander), expander, 1, "gtk_expander_get_label", "GtkExpander*"); return(C_to_Xen_gchar_(gtk_expander_get_label(Xen_to_C_GtkExpander_(expander)))); } static Xen gxg_gtk_expander_set_use_underline(Xen expander, Xen use_underline) { #define H_gtk_expander_set_use_underline "void gtk_expander_set_use_underline(GtkExpander* expander, \ gboolean use_underline)" Xen_check_type(Xen_is_GtkExpander_(expander), expander, 1, "gtk_expander_set_use_underline", "GtkExpander*"); Xen_check_type(Xen_is_gboolean(use_underline), use_underline, 2, "gtk_expander_set_use_underline", "gboolean"); gtk_expander_set_use_underline(Xen_to_C_GtkExpander_(expander), Xen_to_C_gboolean(use_underline)); return(Xen_false); } static Xen gxg_gtk_expander_get_use_underline(Xen expander) { #define H_gtk_expander_get_use_underline "gboolean gtk_expander_get_use_underline(GtkExpander* expander)" Xen_check_type(Xen_is_GtkExpander_(expander), expander, 1, "gtk_expander_get_use_underline", "GtkExpander*"); return(C_to_Xen_gboolean(gtk_expander_get_use_underline(Xen_to_C_GtkExpander_(expander)))); } static Xen gxg_gtk_expander_set_label_widget(Xen expander, Xen label_widget) { #define H_gtk_expander_set_label_widget "void gtk_expander_set_label_widget(GtkExpander* expander, \ GtkWidget* label_widget)" Xen_check_type(Xen_is_GtkExpander_(expander), expander, 1, "gtk_expander_set_label_widget", "GtkExpander*"); Xen_check_type(Xen_is_GtkWidget_(label_widget), label_widget, 2, "gtk_expander_set_label_widget", "GtkWidget*"); gtk_expander_set_label_widget(Xen_to_C_GtkExpander_(expander), Xen_to_C_GtkWidget_(label_widget)); return(Xen_false); } static Xen gxg_gtk_expander_get_label_widget(Xen expander) { #define H_gtk_expander_get_label_widget "GtkWidget* gtk_expander_get_label_widget(GtkExpander* expander)" Xen_check_type(Xen_is_GtkExpander_(expander), expander, 1, "gtk_expander_get_label_widget", "GtkExpander*"); return(C_to_Xen_GtkWidget_(gtk_expander_get_label_widget(Xen_to_C_GtkExpander_(expander)))); } static Xen gxg_gtk_expander_set_use_markup(Xen expander, Xen use_markup) { #define H_gtk_expander_set_use_markup "void gtk_expander_set_use_markup(GtkExpander* expander, gboolean use_markup)" Xen_check_type(Xen_is_GtkExpander_(expander), expander, 1, "gtk_expander_set_use_markup", "GtkExpander*"); Xen_check_type(Xen_is_gboolean(use_markup), use_markup, 2, "gtk_expander_set_use_markup", "gboolean"); gtk_expander_set_use_markup(Xen_to_C_GtkExpander_(expander), Xen_to_C_gboolean(use_markup)); return(Xen_false); } static Xen gxg_gtk_expander_get_use_markup(Xen expander) { #define H_gtk_expander_get_use_markup "gboolean gtk_expander_get_use_markup(GtkExpander* expander)" Xen_check_type(Xen_is_GtkExpander_(expander), expander, 1, "gtk_expander_get_use_markup", "GtkExpander*"); return(C_to_Xen_gboolean(gtk_expander_get_use_markup(Xen_to_C_GtkExpander_(expander)))); } static Xen gxg_gtk_font_button_new(void) { #define H_gtk_font_button_new "GtkWidget* gtk_font_button_new( void)" return(C_to_Xen_GtkWidget_(gtk_font_button_new())); } static Xen gxg_gtk_font_button_new_with_font(Xen fontname) { #define H_gtk_font_button_new_with_font "GtkWidget* gtk_font_button_new_with_font(gchar* fontname)" Xen_check_type(Xen_is_gchar_(fontname), fontname, 1, "gtk_font_button_new_with_font", "gchar*"); return(C_to_Xen_GtkWidget_(gtk_font_button_new_with_font(Xen_to_C_gchar_(fontname)))); } static Xen gxg_gtk_font_button_get_title(Xen font_button) { #define H_gtk_font_button_get_title "gchar* gtk_font_button_get_title(GtkFontButton* font_button)" Xen_check_type(Xen_is_GtkFontButton_(font_button), font_button, 1, "gtk_font_button_get_title", "GtkFontButton*"); return(C_to_Xen_gchar_(gtk_font_button_get_title(Xen_to_C_GtkFontButton_(font_button)))); } static Xen gxg_gtk_font_button_set_title(Xen font_button, Xen title) { #define H_gtk_font_button_set_title "void gtk_font_button_set_title(GtkFontButton* font_button, gchar* title)" Xen_check_type(Xen_is_GtkFontButton_(font_button), font_button, 1, "gtk_font_button_set_title", "GtkFontButton*"); Xen_check_type(Xen_is_gchar_(title), title, 2, "gtk_font_button_set_title", "gchar*"); gtk_font_button_set_title(Xen_to_C_GtkFontButton_(font_button), Xen_to_C_gchar_(title)); return(Xen_false); } static Xen gxg_gtk_font_button_get_use_font(Xen font_button) { #define H_gtk_font_button_get_use_font "gboolean gtk_font_button_get_use_font(GtkFontButton* font_button)" Xen_check_type(Xen_is_GtkFontButton_(font_button), font_button, 1, "gtk_font_button_get_use_font", "GtkFontButton*"); return(C_to_Xen_gboolean(gtk_font_button_get_use_font(Xen_to_C_GtkFontButton_(font_button)))); } static Xen gxg_gtk_font_button_set_use_font(Xen font_button, Xen use_font) { #define H_gtk_font_button_set_use_font "void gtk_font_button_set_use_font(GtkFontButton* font_button, \ gboolean use_font)" Xen_check_type(Xen_is_GtkFontButton_(font_button), font_button, 1, "gtk_font_button_set_use_font", "GtkFontButton*"); Xen_check_type(Xen_is_gboolean(use_font), use_font, 2, "gtk_font_button_set_use_font", "gboolean"); gtk_font_button_set_use_font(Xen_to_C_GtkFontButton_(font_button), Xen_to_C_gboolean(use_font)); return(Xen_false); } static Xen gxg_gtk_font_button_get_use_size(Xen font_button) { #define H_gtk_font_button_get_use_size "gboolean gtk_font_button_get_use_size(GtkFontButton* font_button)" Xen_check_type(Xen_is_GtkFontButton_(font_button), font_button, 1, "gtk_font_button_get_use_size", "GtkFontButton*"); return(C_to_Xen_gboolean(gtk_font_button_get_use_size(Xen_to_C_GtkFontButton_(font_button)))); } static Xen gxg_gtk_font_button_set_use_size(Xen font_button, Xen use_size) { #define H_gtk_font_button_set_use_size "void gtk_font_button_set_use_size(GtkFontButton* font_button, \ gboolean use_size)" Xen_check_type(Xen_is_GtkFontButton_(font_button), font_button, 1, "gtk_font_button_set_use_size", "GtkFontButton*"); Xen_check_type(Xen_is_gboolean(use_size), use_size, 2, "gtk_font_button_set_use_size", "gboolean"); gtk_font_button_set_use_size(Xen_to_C_GtkFontButton_(font_button), Xen_to_C_gboolean(use_size)); return(Xen_false); } static Xen gxg_gtk_font_button_get_font_name(Xen font_button) { #define H_gtk_font_button_get_font_name "gchar* gtk_font_button_get_font_name(GtkFontButton* font_button)" Xen_check_type(Xen_is_GtkFontButton_(font_button), font_button, 1, "gtk_font_button_get_font_name", "GtkFontButton*"); return(C_to_Xen_gchar_(gtk_font_button_get_font_name(Xen_to_C_GtkFontButton_(font_button)))); } static Xen gxg_gtk_font_button_set_font_name(Xen font_button, Xen fontname) { #define H_gtk_font_button_set_font_name "gboolean gtk_font_button_set_font_name(GtkFontButton* font_button, \ gchar* fontname)" Xen_check_type(Xen_is_GtkFontButton_(font_button), font_button, 1, "gtk_font_button_set_font_name", "GtkFontButton*"); Xen_check_type(Xen_is_gchar_(fontname), fontname, 2, "gtk_font_button_set_font_name", "gchar*"); return(C_to_Xen_gboolean(gtk_font_button_set_font_name(Xen_to_C_GtkFontButton_(font_button), Xen_to_C_gchar_(fontname)))); } static Xen gxg_gtk_font_button_get_show_style(Xen font_button) { #define H_gtk_font_button_get_show_style "gboolean gtk_font_button_get_show_style(GtkFontButton* font_button)" Xen_check_type(Xen_is_GtkFontButton_(font_button), font_button, 1, "gtk_font_button_get_show_style", "GtkFontButton*"); return(C_to_Xen_gboolean(gtk_font_button_get_show_style(Xen_to_C_GtkFontButton_(font_button)))); } static Xen gxg_gtk_font_button_set_show_style(Xen font_button, Xen show_style) { #define H_gtk_font_button_set_show_style "void gtk_font_button_set_show_style(GtkFontButton* font_button, \ gboolean show_style)" Xen_check_type(Xen_is_GtkFontButton_(font_button), font_button, 1, "gtk_font_button_set_show_style", "GtkFontButton*"); Xen_check_type(Xen_is_gboolean(show_style), show_style, 2, "gtk_font_button_set_show_style", "gboolean"); gtk_font_button_set_show_style(Xen_to_C_GtkFontButton_(font_button), Xen_to_C_gboolean(show_style)); return(Xen_false); } static Xen gxg_gtk_font_button_get_show_size(Xen font_button) { #define H_gtk_font_button_get_show_size "gboolean gtk_font_button_get_show_size(GtkFontButton* font_button)" Xen_check_type(Xen_is_GtkFontButton_(font_button), font_button, 1, "gtk_font_button_get_show_size", "GtkFontButton*"); return(C_to_Xen_gboolean(gtk_font_button_get_show_size(Xen_to_C_GtkFontButton_(font_button)))); } static Xen gxg_gtk_font_button_set_show_size(Xen font_button, Xen show_size) { #define H_gtk_font_button_set_show_size "void gtk_font_button_set_show_size(GtkFontButton* font_button, \ gboolean show_size)" Xen_check_type(Xen_is_GtkFontButton_(font_button), font_button, 1, "gtk_font_button_set_show_size", "GtkFontButton*"); Xen_check_type(Xen_is_gboolean(show_size), show_size, 2, "gtk_font_button_set_show_size", "gboolean"); gtk_font_button_set_show_size(Xen_to_C_GtkFontButton_(font_button), Xen_to_C_gboolean(show_size)); return(Xen_false); } static Xen gxg_gtk_entry_completion_new(void) { #define H_gtk_entry_completion_new "GtkEntryCompletion* gtk_entry_completion_new( void)" return(C_to_Xen_GtkEntryCompletion_(gtk_entry_completion_new())); } static Xen gxg_gtk_entry_completion_get_entry(Xen entry) { #define H_gtk_entry_completion_get_entry "GtkWidget* gtk_entry_completion_get_entry(GtkEntryCompletion* entry)" Xen_check_type(Xen_is_GtkEntryCompletion_(entry), entry, 1, "gtk_entry_completion_get_entry", "GtkEntryCompletion*"); return(C_to_Xen_GtkWidget_(gtk_entry_completion_get_entry(Xen_to_C_GtkEntryCompletion_(entry)))); } static Xen gxg_gtk_entry_completion_set_model(Xen completion, Xen model) { #define H_gtk_entry_completion_set_model "void gtk_entry_completion_set_model(GtkEntryCompletion* completion, \ GtkTreeModel* model)" Xen_check_type(Xen_is_GtkEntryCompletion_(completion), completion, 1, "gtk_entry_completion_set_model", "GtkEntryCompletion*"); Xen_check_type(Xen_is_GtkTreeModel_(model) || Xen_is_false(model), model, 2, "gtk_entry_completion_set_model", "GtkTreeModel*"); gtk_entry_completion_set_model(Xen_to_C_GtkEntryCompletion_(completion), Xen_to_C_GtkTreeModel_(model)); return(Xen_false); } static Xen gxg_gtk_entry_completion_get_model(Xen completion) { #define H_gtk_entry_completion_get_model "GtkTreeModel* gtk_entry_completion_get_model(GtkEntryCompletion* completion)" Xen_check_type(Xen_is_GtkEntryCompletion_(completion), completion, 1, "gtk_entry_completion_get_model", "GtkEntryCompletion*"); return(C_to_Xen_GtkTreeModel_(gtk_entry_completion_get_model(Xen_to_C_GtkEntryCompletion_(completion)))); } static Xen gxg_gtk_entry_completion_set_match_func(Xen completion, Xen func, Xen func_info, Xen func_notify) { #define H_gtk_entry_completion_set_match_func "void gtk_entry_completion_set_match_func(GtkEntryCompletion* completion, \ GtkEntryCompletionMatchFunc func, lambda_data func_info, GtkDestroyNotify func_notify)" Xen_check_type(Xen_is_GtkEntryCompletion_(completion), completion, 1, "gtk_entry_completion_set_match_func", "GtkEntryCompletion*"); Xen_check_type(Xen_is_GtkEntryCompletionMatchFunc(func), func, 2, "gtk_entry_completion_set_match_func", "GtkEntryCompletionMatchFunc"); Xen_check_type(Xen_is_lambda_data(func_info), func_info, 3, "gtk_entry_completion_set_match_func", "lambda_data"); Xen_check_type(Xen_is_GtkDestroyNotify(func_notify), func_notify, 4, "gtk_entry_completion_set_match_func", "GtkDestroyNotify"); { Xen gxg_ptr = Xen_list_5(func, func_info, Xen_false, Xen_false, Xen_false); xm_protect(gxg_ptr); Xen_list_set(gxg_ptr, 3, func_notify); gtk_entry_completion_set_match_func(Xen_to_C_GtkEntryCompletion_(completion), Xen_to_C_GtkEntryCompletionMatchFunc(func), Xen_to_C_lambda_data(func_info), Xen_to_C_GtkDestroyNotify(func_notify)); return(Xen_false); } } static Xen gxg_gtk_entry_completion_set_minimum_key_length(Xen completion, Xen length) { #define H_gtk_entry_completion_set_minimum_key_length "void gtk_entry_completion_set_minimum_key_length(GtkEntryCompletion* completion, \ gint length)" Xen_check_type(Xen_is_GtkEntryCompletion_(completion), completion, 1, "gtk_entry_completion_set_minimum_key_length", "GtkEntryCompletion*"); Xen_check_type(Xen_is_gint(length), length, 2, "gtk_entry_completion_set_minimum_key_length", "gint"); gtk_entry_completion_set_minimum_key_length(Xen_to_C_GtkEntryCompletion_(completion), Xen_to_C_gint(length)); return(Xen_false); } static Xen gxg_gtk_entry_completion_get_minimum_key_length(Xen completion) { #define H_gtk_entry_completion_get_minimum_key_length "gint gtk_entry_completion_get_minimum_key_length(GtkEntryCompletion* completion)" Xen_check_type(Xen_is_GtkEntryCompletion_(completion), completion, 1, "gtk_entry_completion_get_minimum_key_length", "GtkEntryCompletion*"); return(C_to_Xen_gint(gtk_entry_completion_get_minimum_key_length(Xen_to_C_GtkEntryCompletion_(completion)))); } static Xen gxg_gtk_entry_completion_complete(Xen completion) { #define H_gtk_entry_completion_complete "void gtk_entry_completion_complete(GtkEntryCompletion* completion)" Xen_check_type(Xen_is_GtkEntryCompletion_(completion), completion, 1, "gtk_entry_completion_complete", "GtkEntryCompletion*"); gtk_entry_completion_complete(Xen_to_C_GtkEntryCompletion_(completion)); return(Xen_false); } static Xen gxg_gtk_entry_completion_insert_action_text(Xen completion, Xen index, Xen text) { #define H_gtk_entry_completion_insert_action_text "void gtk_entry_completion_insert_action_text(GtkEntryCompletion* completion, \ gint index, gchar* text)" Xen_check_type(Xen_is_GtkEntryCompletion_(completion), completion, 1, "gtk_entry_completion_insert_action_text", "GtkEntryCompletion*"); Xen_check_type(Xen_is_gint(index), index, 2, "gtk_entry_completion_insert_action_text", "gint"); Xen_check_type(Xen_is_gchar_(text), text, 3, "gtk_entry_completion_insert_action_text", "gchar*"); gtk_entry_completion_insert_action_text(Xen_to_C_GtkEntryCompletion_(completion), Xen_to_C_gint(index), Xen_to_C_gchar_(text)); return(Xen_false); } static Xen gxg_gtk_entry_completion_insert_action_markup(Xen completion, Xen index, Xen markup) { #define H_gtk_entry_completion_insert_action_markup "void gtk_entry_completion_insert_action_markup(GtkEntryCompletion* completion, \ gint index, gchar* markup)" Xen_check_type(Xen_is_GtkEntryCompletion_(completion), completion, 1, "gtk_entry_completion_insert_action_markup", "GtkEntryCompletion*"); Xen_check_type(Xen_is_gint(index), index, 2, "gtk_entry_completion_insert_action_markup", "gint"); Xen_check_type(Xen_is_gchar_(markup), markup, 3, "gtk_entry_completion_insert_action_markup", "gchar*"); gtk_entry_completion_insert_action_markup(Xen_to_C_GtkEntryCompletion_(completion), Xen_to_C_gint(index), Xen_to_C_gchar_(markup)); return(Xen_false); } static Xen gxg_gtk_entry_completion_delete_action(Xen completion, Xen index) { #define H_gtk_entry_completion_delete_action "void gtk_entry_completion_delete_action(GtkEntryCompletion* completion, \ gint index)" Xen_check_type(Xen_is_GtkEntryCompletion_(completion), completion, 1, "gtk_entry_completion_delete_action", "GtkEntryCompletion*"); Xen_check_type(Xen_is_gint(index), index, 2, "gtk_entry_completion_delete_action", "gint"); gtk_entry_completion_delete_action(Xen_to_C_GtkEntryCompletion_(completion), Xen_to_C_gint(index)); return(Xen_false); } static Xen gxg_gtk_entry_completion_set_text_column(Xen completion, Xen column) { #define H_gtk_entry_completion_set_text_column "void gtk_entry_completion_set_text_column(GtkEntryCompletion* completion, \ gint column)" Xen_check_type(Xen_is_GtkEntryCompletion_(completion), completion, 1, "gtk_entry_completion_set_text_column", "GtkEntryCompletion*"); Xen_check_type(Xen_is_gint(column), column, 2, "gtk_entry_completion_set_text_column", "gint"); gtk_entry_completion_set_text_column(Xen_to_C_GtkEntryCompletion_(completion), Xen_to_C_gint(column)); return(Xen_false); } static Xen gxg_gtk_radio_tool_button_new(Xen group) { #define H_gtk_radio_tool_button_new "GtkToolItem* gtk_radio_tool_button_new(GSList* group)" Xen_check_type(Xen_is_GSList_(group) || Xen_is_false(group), group, 1, "gtk_radio_tool_button_new", "GSList*"); return(C_to_Xen_GtkToolItem_(gtk_radio_tool_button_new(Xen_to_C_GSList_(group)))); } static Xen gxg_gtk_radio_tool_button_new_from_widget(Xen group) { #define H_gtk_radio_tool_button_new_from_widget "GtkToolItem* gtk_radio_tool_button_new_from_widget(GtkRadioToolButton* group)" Xen_check_type(Xen_is_GtkRadioToolButton_(group), group, 1, "gtk_radio_tool_button_new_from_widget", "GtkRadioToolButton*"); return(C_to_Xen_GtkToolItem_(gtk_radio_tool_button_new_from_widget(Xen_to_C_GtkRadioToolButton_(group)))); } static Xen gxg_gtk_radio_tool_button_get_group(Xen button) { #define H_gtk_radio_tool_button_get_group "GSList* gtk_radio_tool_button_get_group(GtkRadioToolButton* button)" Xen_check_type(Xen_is_GtkRadioToolButton_(button), button, 1, "gtk_radio_tool_button_get_group", "GtkRadioToolButton*"); return(C_to_Xen_GSList_(gtk_radio_tool_button_get_group(Xen_to_C_GtkRadioToolButton_(button)))); } static Xen gxg_gtk_radio_tool_button_set_group(Xen button, Xen group) { #define H_gtk_radio_tool_button_set_group "void gtk_radio_tool_button_set_group(GtkRadioToolButton* button, \ GSList* group)" Xen_check_type(Xen_is_GtkRadioToolButton_(button), button, 1, "gtk_radio_tool_button_set_group", "GtkRadioToolButton*"); Xen_check_type(Xen_is_GSList_(group) || Xen_is_false(group), group, 2, "gtk_radio_tool_button_set_group", "GSList*"); gtk_radio_tool_button_set_group(Xen_to_C_GtkRadioToolButton_(button), Xen_to_C_GSList_(group)); return(Xen_false); } static Xen gxg_gtk_separator_tool_item_new(void) { #define H_gtk_separator_tool_item_new "GtkToolItem* gtk_separator_tool_item_new( void)" return(C_to_Xen_GtkToolItem_(gtk_separator_tool_item_new())); } static Xen gxg_gtk_separator_tool_item_get_draw(Xen item) { #define H_gtk_separator_tool_item_get_draw "gboolean gtk_separator_tool_item_get_draw(GtkSeparatorToolItem* item)" Xen_check_type(Xen_is_GtkSeparatorToolItem_(item), item, 1, "gtk_separator_tool_item_get_draw", "GtkSeparatorToolItem*"); return(C_to_Xen_gboolean(gtk_separator_tool_item_get_draw(Xen_to_C_GtkSeparatorToolItem_(item)))); } static Xen gxg_gtk_separator_tool_item_set_draw(Xen tool_item, Xen draw) { #define H_gtk_separator_tool_item_set_draw "void gtk_separator_tool_item_set_draw(GtkSeparatorToolItem* tool_item, \ gboolean draw)" Xen_check_type(Xen_is_GtkSeparatorToolItem_(tool_item), tool_item, 1, "gtk_separator_tool_item_set_draw", "GtkSeparatorToolItem*"); Xen_check_type(Xen_is_gboolean(draw), draw, 2, "gtk_separator_tool_item_set_draw", "gboolean"); gtk_separator_tool_item_set_draw(Xen_to_C_GtkSeparatorToolItem_(tool_item), Xen_to_C_gboolean(draw)); return(Xen_false); } static Xen gxg_gtk_toggle_tool_button_new(void) { #define H_gtk_toggle_tool_button_new "GtkToolItem* gtk_toggle_tool_button_new( void)" return(C_to_Xen_GtkToolItem_(gtk_toggle_tool_button_new())); } static Xen gxg_gtk_toggle_tool_button_set_active(Xen button, Xen is_active) { #define H_gtk_toggle_tool_button_set_active "void gtk_toggle_tool_button_set_active(GtkToggleToolButton* button, \ gboolean is_active)" Xen_check_type(Xen_is_GtkToggleToolButton_(button), button, 1, "gtk_toggle_tool_button_set_active", "GtkToggleToolButton*"); Xen_check_type(Xen_is_gboolean(is_active), is_active, 2, "gtk_toggle_tool_button_set_active", "gboolean"); gtk_toggle_tool_button_set_active(Xen_to_C_GtkToggleToolButton_(button), Xen_to_C_gboolean(is_active)); return(Xen_false); } static Xen gxg_gtk_toggle_tool_button_get_active(Xen button) { #define H_gtk_toggle_tool_button_get_active "gboolean gtk_toggle_tool_button_get_active(GtkToggleToolButton* button)" Xen_check_type(Xen_is_GtkToggleToolButton_(button), button, 1, "gtk_toggle_tool_button_get_active", "GtkToggleToolButton*"); return(C_to_Xen_gboolean(gtk_toggle_tool_button_get_active(Xen_to_C_GtkToggleToolButton_(button)))); } static Xen gxg_g_timeout_add_full(Xen priority, Xen interval, Xen func, Xen func_info, Xen notify) { #define H_g_timeout_add_full "guint g_timeout_add_full(gint priority, guint interval, GSourceFunc func, \ lambda_data func_info, GtkDestroyNotify notify)" Xen_check_type(Xen_is_gint(priority), priority, 1, "g_timeout_add_full", "gint"); Xen_check_type(Xen_is_guint(interval), interval, 2, "g_timeout_add_full", "guint"); Xen_check_type(Xen_is_GSourceFunc(func), func, 3, "g_timeout_add_full", "GSourceFunc"); Xen_check_type(Xen_is_lambda_data(func_info), func_info, 4, "g_timeout_add_full", "lambda_data"); Xen_check_type(Xen_is_GtkDestroyNotify(notify), notify, 5, "g_timeout_add_full", "GtkDestroyNotify"); { Xen result; int loc; Xen gxg_ptr = Xen_list_5(func, func_info, Xen_false, Xen_false, Xen_false); loc = xm_protect(gxg_ptr); Xen_list_set(gxg_ptr, 2, C_int_to_Xen_integer(loc)); Xen_list_set(gxg_ptr, 3, notify); result = C_to_Xen_guint(g_timeout_add_full(Xen_to_C_gint(priority), Xen_to_C_guint(interval), Xen_to_C_GSourceFunc(func), Xen_to_C_lambda_data(func_info), Xen_to_C_GtkDestroyNotify(notify))); Xen_list_set(gxg_ptr, 2, Xen_list_3(xg_idler_symbol, result, C_int_to_Xen_integer(loc))); return(result); } } static Xen gxg_g_timeout_add(Xen interval, Xen func, Xen func_info) { #define H_g_timeout_add "guint g_timeout_add(guint interval, GSourceFunc func, lambda_data func_info)" Xen_check_type(Xen_is_guint(interval), interval, 1, "g_timeout_add", "guint"); Xen_check_type(Xen_is_GSourceFunc(func), func, 2, "g_timeout_add", "GSourceFunc"); if (!Xen_is_bound(func_info)) func_info = Xen_false; else Xen_check_type(Xen_is_lambda_data(func_info), func_info, 3, "g_timeout_add", "lambda_data"); { Xen result; int loc; Xen gxg_ptr = Xen_list_5(func, func_info, Xen_false, Xen_false, Xen_false); loc = xm_protect(gxg_ptr); Xen_list_set(gxg_ptr, 2, C_int_to_Xen_integer(loc)); result = C_to_Xen_guint(g_timeout_add(Xen_to_C_guint(interval), Xen_to_C_GSourceFunc(func), Xen_to_C_lambda_data(func_info))); Xen_list_set(gxg_ptr, 2, Xen_list_3(xg_idler_symbol, result, C_int_to_Xen_integer(loc))); return(result); } } static Xen gxg_g_idle_add(Xen func, Xen func_info) { #define H_g_idle_add "guint g_idle_add(GSourceFunc func, lambda_data func_info)" Xen_check_type(Xen_is_GSourceFunc(func), func, 1, "g_idle_add", "GSourceFunc"); if (!Xen_is_bound(func_info)) func_info = Xen_false; else Xen_check_type(Xen_is_lambda_data(func_info), func_info, 2, "g_idle_add", "lambda_data"); { Xen result; int loc; Xen gxg_ptr = Xen_list_5(func, func_info, Xen_false, Xen_false, Xen_false); loc = xm_protect(gxg_ptr); Xen_list_set(gxg_ptr, 2, C_int_to_Xen_integer(loc)); result = C_to_Xen_guint(g_idle_add(Xen_to_C_GSourceFunc(func), Xen_to_C_lambda_data(func_info))); Xen_list_set(gxg_ptr, 2, Xen_list_3(xg_idler_symbol, result, C_int_to_Xen_integer(loc))); return(result); } } static Xen gxg_g_idle_add_full(Xen priority, Xen func, Xen func_info, Xen notify) { #define H_g_idle_add_full "guint g_idle_add_full(gint priority, GSourceFunc func, lambda_data func_info, \ GtkDestroyNotify notify)" Xen_check_type(Xen_is_gint(priority), priority, 1, "g_idle_add_full", "gint"); Xen_check_type(Xen_is_GSourceFunc(func), func, 2, "g_idle_add_full", "GSourceFunc"); Xen_check_type(Xen_is_lambda_data(func_info), func_info, 3, "g_idle_add_full", "lambda_data"); Xen_check_type(Xen_is_GtkDestroyNotify(notify), notify, 4, "g_idle_add_full", "GtkDestroyNotify"); { Xen result; int loc; Xen gxg_ptr = Xen_list_5(func, func_info, Xen_false, Xen_false, Xen_false); loc = xm_protect(gxg_ptr); Xen_list_set(gxg_ptr, 2, C_int_to_Xen_integer(loc)); Xen_list_set(gxg_ptr, 3, notify); result = C_to_Xen_guint(g_idle_add_full(Xen_to_C_gint(priority), Xen_to_C_GSourceFunc(func), Xen_to_C_lambda_data(func_info), Xen_to_C_GtkDestroyNotify(notify))); Xen_list_set(gxg_ptr, 2, Xen_list_3(xg_idler_symbol, result, C_int_to_Xen_integer(loc))); return(result); } } static Xen gxg_g_idle_remove_by_data(Xen data) { #define H_g_idle_remove_by_data "gboolean g_idle_remove_by_data(gpointer data)" Xen_check_type(Xen_is_gpointer(data), data, 1, "g_idle_remove_by_data", "gpointer"); xm_unprotect_at(Xen_integer_to_C_int(Xen_caddr(data))); return(C_to_Xen_gboolean(g_idle_remove_by_data(Xen_to_C_gpointer(data)))); } static Xen gxg_g_source_remove(Xen tag) { #define H_g_source_remove "gboolean g_source_remove(guint tag)" Xen_check_type(Xen_is_guint(tag), tag, 1, "g_source_remove", "guint"); xm_unprotect_at(Xen_integer_to_C_int(Xen_caddr(tag))); return(C_to_Xen_gboolean(g_source_remove(Xen_to_C_guint(tag)))); } static Xen gxg_gtk_file_filter_new(void) { #define H_gtk_file_filter_new "GtkFileFilter* gtk_file_filter_new( void)" return(C_to_Xen_GtkFileFilter_(gtk_file_filter_new())); } static Xen gxg_gtk_file_filter_set_name(Xen filter, Xen name) { #define H_gtk_file_filter_set_name "void gtk_file_filter_set_name(GtkFileFilter* filter, gchar* name)" Xen_check_type(Xen_is_GtkFileFilter_(filter), filter, 1, "gtk_file_filter_set_name", "GtkFileFilter*"); Xen_check_type(Xen_is_gchar_(name), name, 2, "gtk_file_filter_set_name", "gchar*"); gtk_file_filter_set_name(Xen_to_C_GtkFileFilter_(filter), Xen_to_C_gchar_(name)); return(Xen_false); } static Xen gxg_gtk_file_filter_get_name(Xen filter) { #define H_gtk_file_filter_get_name "gchar* gtk_file_filter_get_name(GtkFileFilter* filter)" Xen_check_type(Xen_is_GtkFileFilter_(filter), filter, 1, "gtk_file_filter_get_name", "GtkFileFilter*"); return(C_to_Xen_gchar_(gtk_file_filter_get_name(Xen_to_C_GtkFileFilter_(filter)))); } static Xen gxg_gtk_file_filter_add_mime_type(Xen filter, Xen mime_type) { #define H_gtk_file_filter_add_mime_type "void gtk_file_filter_add_mime_type(GtkFileFilter* filter, \ gchar* mime_type)" Xen_check_type(Xen_is_GtkFileFilter_(filter), filter, 1, "gtk_file_filter_add_mime_type", "GtkFileFilter*"); Xen_check_type(Xen_is_gchar_(mime_type), mime_type, 2, "gtk_file_filter_add_mime_type", "gchar*"); gtk_file_filter_add_mime_type(Xen_to_C_GtkFileFilter_(filter), Xen_to_C_gchar_(mime_type)); return(Xen_false); } static Xen gxg_gtk_file_filter_add_pattern(Xen filter, Xen pattern) { #define H_gtk_file_filter_add_pattern "void gtk_file_filter_add_pattern(GtkFileFilter* filter, gchar* pattern)" Xen_check_type(Xen_is_GtkFileFilter_(filter), filter, 1, "gtk_file_filter_add_pattern", "GtkFileFilter*"); Xen_check_type(Xen_is_gchar_(pattern), pattern, 2, "gtk_file_filter_add_pattern", "gchar*"); gtk_file_filter_add_pattern(Xen_to_C_GtkFileFilter_(filter), Xen_to_C_gchar_(pattern)); return(Xen_false); } static Xen gxg_gtk_file_filter_add_custom(Xen filter, Xen needed, Xen func, Xen func_info, Xen notify) { #define H_gtk_file_filter_add_custom "void gtk_file_filter_add_custom(GtkFileFilter* filter, GtkFileFilterFlags needed, \ GtkFileFilterFunc func, lambda_data func_info, GtkDestroyNotify notify)" Xen_check_type(Xen_is_GtkFileFilter_(filter), filter, 1, "gtk_file_filter_add_custom", "GtkFileFilter*"); Xen_check_type(Xen_is_GtkFileFilterFlags(needed), needed, 2, "gtk_file_filter_add_custom", "GtkFileFilterFlags"); Xen_check_type(Xen_is_GtkFileFilterFunc(func), func, 3, "gtk_file_filter_add_custom", "GtkFileFilterFunc"); Xen_check_type(Xen_is_lambda_data(func_info), func_info, 4, "gtk_file_filter_add_custom", "lambda_data"); Xen_check_type(Xen_is_GtkDestroyNotify(notify), notify, 5, "gtk_file_filter_add_custom", "GtkDestroyNotify"); { Xen gxg_ptr = Xen_list_5(func, func_info, Xen_false, Xen_false, Xen_false); xm_protect(gxg_ptr); Xen_list_set(gxg_ptr, 3, notify); gtk_file_filter_add_custom(Xen_to_C_GtkFileFilter_(filter), Xen_to_C_GtkFileFilterFlags(needed), Xen_to_C_GtkFileFilterFunc(func), Xen_to_C_lambda_data(func_info), Xen_to_C_GtkDestroyNotify(notify)); return(Xen_false); } } static Xen gxg_gtk_file_filter_get_needed(Xen filter) { #define H_gtk_file_filter_get_needed "GtkFileFilterFlags gtk_file_filter_get_needed(GtkFileFilter* filter)" Xen_check_type(Xen_is_GtkFileFilter_(filter), filter, 1, "gtk_file_filter_get_needed", "GtkFileFilter*"); return(C_to_Xen_GtkFileFilterFlags(gtk_file_filter_get_needed(Xen_to_C_GtkFileFilter_(filter)))); } static Xen gxg_gtk_file_filter_filter(Xen filter, Xen filter_info) { #define H_gtk_file_filter_filter "gboolean gtk_file_filter_filter(GtkFileFilter* filter, GtkFileFilterInfo* filter_info)" Xen_check_type(Xen_is_GtkFileFilter_(filter), filter, 1, "gtk_file_filter_filter", "GtkFileFilter*"); Xen_check_type(Xen_is_GtkFileFilterInfo_(filter_info), filter_info, 2, "gtk_file_filter_filter", "GtkFileFilterInfo*"); return(C_to_Xen_gboolean(gtk_file_filter_filter(Xen_to_C_GtkFileFilter_(filter), Xen_to_C_GtkFileFilterInfo_(filter_info)))); } static Xen gxg_gtk_cell_layout_pack_start(Xen cell_layout, Xen cell, Xen expand) { #define H_gtk_cell_layout_pack_start "void gtk_cell_layout_pack_start(GtkCellLayout* cell_layout, GtkCellRenderer* cell, \ gboolean expand)" Xen_check_type(Xen_is_GtkCellLayout_(cell_layout), cell_layout, 1, "gtk_cell_layout_pack_start", "GtkCellLayout*"); Xen_check_type(Xen_is_GtkCellRenderer_(cell), cell, 2, "gtk_cell_layout_pack_start", "GtkCellRenderer*"); Xen_check_type(Xen_is_gboolean(expand), expand, 3, "gtk_cell_layout_pack_start", "gboolean"); gtk_cell_layout_pack_start(Xen_to_C_GtkCellLayout_(cell_layout), Xen_to_C_GtkCellRenderer_(cell), Xen_to_C_gboolean(expand)); return(Xen_false); } static Xen gxg_gtk_cell_layout_pack_end(Xen cell_layout, Xen cell, Xen expand) { #define H_gtk_cell_layout_pack_end "void gtk_cell_layout_pack_end(GtkCellLayout* cell_layout, GtkCellRenderer* cell, \ gboolean expand)" Xen_check_type(Xen_is_GtkCellLayout_(cell_layout), cell_layout, 1, "gtk_cell_layout_pack_end", "GtkCellLayout*"); Xen_check_type(Xen_is_GtkCellRenderer_(cell), cell, 2, "gtk_cell_layout_pack_end", "GtkCellRenderer*"); Xen_check_type(Xen_is_gboolean(expand), expand, 3, "gtk_cell_layout_pack_end", "gboolean"); gtk_cell_layout_pack_end(Xen_to_C_GtkCellLayout_(cell_layout), Xen_to_C_GtkCellRenderer_(cell), Xen_to_C_gboolean(expand)); return(Xen_false); } static Xen gxg_gtk_cell_layout_clear(Xen cell_layout) { #define H_gtk_cell_layout_clear "void gtk_cell_layout_clear(GtkCellLayout* cell_layout)" Xen_check_type(Xen_is_GtkCellLayout_(cell_layout), cell_layout, 1, "gtk_cell_layout_clear", "GtkCellLayout*"); gtk_cell_layout_clear(Xen_to_C_GtkCellLayout_(cell_layout)); return(Xen_false); } static Xen gxg_gtk_cell_layout_set_attributes(Xen cell_layout, Xen cell, Xen attributes) { #define H_gtk_cell_layout_set_attributes "void gtk_cell_layout_set_attributes(GtkCellLayout* cell_layout, \ GtkCellRenderer* cell, etc attributes)" Xen_check_type(Xen_is_GtkCellLayout_(cell_layout), cell_layout, 1, "gtk_cell_layout_set_attributes", "GtkCellLayout*"); Xen_check_type(Xen_is_GtkCellRenderer_(cell), cell, 2, "gtk_cell_layout_set_attributes", "GtkCellRenderer*"); Xen_check_type(Xen_is_etc(attributes), attributes, 3, "gtk_cell_layout_set_attributes", "etc"); { int etc_len = 0; GtkCellLayout* p_arg0; GtkCellRenderer* p_arg1; if (Xen_is_list(attributes)) etc_len = Xen_list_length(attributes); if (etc_len < 2) Xen_out_of_range_error("gtk_cell_layout_set_attributes", 2, attributes, "... list must have at least 2 entries"); if (etc_len > 10) Xen_out_of_range_error("gtk_cell_layout_set_attributes", 2, attributes, "... list too long (max len: 10)"); if ((etc_len % 2) != 0) Xen_out_of_range_error("gtk_cell_layout_set_attributes", 2, attributes, "... list len must be multiple of 2"); p_arg0 = Xen_to_C_GtkCellLayout_(cell_layout); p_arg1 = Xen_to_C_GtkCellRenderer_(cell); switch (etc_len) { case 2: gtk_cell_layout_set_attributes(p_arg0, p_arg1, XLS(attributes, 0), XLI(attributes, 1), NULL); break; case 4: gtk_cell_layout_set_attributes(p_arg0, p_arg1, XLS(attributes, 0), XLI(attributes, 1), XLS(attributes, 2), XLI(attributes, 3), NULL); break; case 6: gtk_cell_layout_set_attributes(p_arg0, p_arg1, XLS(attributes, 0), XLI(attributes, 1), XLS(attributes, 2), XLI(attributes, 3), XLS(attributes, 4), XLI(attributes, 5), NULL); break; case 8: gtk_cell_layout_set_attributes(p_arg0, p_arg1, XLS(attributes, 0), XLI(attributes, 1), XLS(attributes, 2), XLI(attributes, 3), XLS(attributes, 4), XLI(attributes, 5), XLS(attributes, 6), XLI(attributes, 7), NULL); break; case 10: gtk_cell_layout_set_attributes(p_arg0, p_arg1, XLS(attributes, 0), XLI(attributes, 1), XLS(attributes, 2), XLI(attributes, 3), XLS(attributes, 4), XLI(attributes, 5), XLS(attributes, 6), XLI(attributes, 7), XLS(attributes, 8), XLI(attributes, 9), NULL); break; } return(Xen_false); } } static Xen gxg_gtk_cell_layout_add_attribute(Xen cell_layout, Xen cell, Xen attribute, Xen column) { #define H_gtk_cell_layout_add_attribute "void gtk_cell_layout_add_attribute(GtkCellLayout* cell_layout, \ GtkCellRenderer* cell, gchar* attribute, gint column)" Xen_check_type(Xen_is_GtkCellLayout_(cell_layout), cell_layout, 1, "gtk_cell_layout_add_attribute", "GtkCellLayout*"); Xen_check_type(Xen_is_GtkCellRenderer_(cell), cell, 2, "gtk_cell_layout_add_attribute", "GtkCellRenderer*"); Xen_check_type(Xen_is_gchar_(attribute), attribute, 3, "gtk_cell_layout_add_attribute", "gchar*"); Xen_check_type(Xen_is_gint(column), column, 4, "gtk_cell_layout_add_attribute", "gint"); gtk_cell_layout_add_attribute(Xen_to_C_GtkCellLayout_(cell_layout), Xen_to_C_GtkCellRenderer_(cell), Xen_to_C_gchar_(attribute), Xen_to_C_gint(column)); return(Xen_false); } static Xen gxg_gtk_cell_layout_set_cell_data_func(Xen cell_layout, Xen cell, Xen func, Xen func_info, Xen destroy) { #define H_gtk_cell_layout_set_cell_data_func "void gtk_cell_layout_set_cell_data_func(GtkCellLayout* cell_layout, \ GtkCellRenderer* cell, GtkCellLayoutDataFunc func, lambda_data func_info, GtkDestroyNotify destroy)" Xen_check_type(Xen_is_GtkCellLayout_(cell_layout), cell_layout, 1, "gtk_cell_layout_set_cell_data_func", "GtkCellLayout*"); Xen_check_type(Xen_is_GtkCellRenderer_(cell), cell, 2, "gtk_cell_layout_set_cell_data_func", "GtkCellRenderer*"); Xen_check_type(Xen_is_GtkCellLayoutDataFunc(func), func, 3, "gtk_cell_layout_set_cell_data_func", "GtkCellLayoutDataFunc"); Xen_check_type(Xen_is_lambda_data(func_info), func_info, 4, "gtk_cell_layout_set_cell_data_func", "lambda_data"); Xen_check_type(Xen_is_GtkDestroyNotify(destroy), destroy, 5, "gtk_cell_layout_set_cell_data_func", "GtkDestroyNotify"); { Xen gxg_ptr = Xen_list_5(func, func_info, Xen_false, Xen_false, Xen_false); xm_protect(gxg_ptr); Xen_list_set(gxg_ptr, 3, destroy); gtk_cell_layout_set_cell_data_func(Xen_to_C_GtkCellLayout_(cell_layout), Xen_to_C_GtkCellRenderer_(cell), Xen_to_C_GtkCellLayoutDataFunc(func), Xen_to_C_lambda_data(func_info), Xen_to_C_GtkDestroyNotify(destroy)); return(Xen_false); } } static Xen gxg_gtk_cell_layout_clear_attributes(Xen cell_layout, Xen cell) { #define H_gtk_cell_layout_clear_attributes "void gtk_cell_layout_clear_attributes(GtkCellLayout* cell_layout, \ GtkCellRenderer* cell)" Xen_check_type(Xen_is_GtkCellLayout_(cell_layout), cell_layout, 1, "gtk_cell_layout_clear_attributes", "GtkCellLayout*"); Xen_check_type(Xen_is_GtkCellRenderer_(cell), cell, 2, "gtk_cell_layout_clear_attributes", "GtkCellRenderer*"); gtk_cell_layout_clear_attributes(Xen_to_C_GtkCellLayout_(cell_layout), Xen_to_C_GtkCellRenderer_(cell)); return(Xen_false); } static Xen gxg_gtk_file_chooser_set_action(Xen chooser, Xen action) { #define H_gtk_file_chooser_set_action "void gtk_file_chooser_set_action(GtkFileChooser* chooser, GtkFileChooserAction action)" Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_set_action", "GtkFileChooser*"); Xen_check_type(Xen_is_GtkFileChooserAction(action), action, 2, "gtk_file_chooser_set_action", "GtkFileChooserAction"); gtk_file_chooser_set_action(Xen_to_C_GtkFileChooser_(chooser), Xen_to_C_GtkFileChooserAction(action)); return(Xen_false); } static Xen gxg_gtk_file_chooser_get_action(Xen chooser) { #define H_gtk_file_chooser_get_action "GtkFileChooserAction gtk_file_chooser_get_action(GtkFileChooser* chooser)" Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_get_action", "GtkFileChooser*"); return(C_to_Xen_GtkFileChooserAction(gtk_file_chooser_get_action(Xen_to_C_GtkFileChooser_(chooser)))); } static Xen gxg_gtk_file_chooser_set_local_only(Xen chooser, Xen files_only) { #define H_gtk_file_chooser_set_local_only "void gtk_file_chooser_set_local_only(GtkFileChooser* chooser, \ gboolean files_only)" Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_set_local_only", "GtkFileChooser*"); Xen_check_type(Xen_is_gboolean(files_only), files_only, 2, "gtk_file_chooser_set_local_only", "gboolean"); gtk_file_chooser_set_local_only(Xen_to_C_GtkFileChooser_(chooser), Xen_to_C_gboolean(files_only)); return(Xen_false); } static Xen gxg_gtk_file_chooser_get_local_only(Xen chooser) { #define H_gtk_file_chooser_get_local_only "gboolean gtk_file_chooser_get_local_only(GtkFileChooser* chooser)" Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_get_local_only", "GtkFileChooser*"); return(C_to_Xen_gboolean(gtk_file_chooser_get_local_only(Xen_to_C_GtkFileChooser_(chooser)))); } static Xen gxg_gtk_file_chooser_set_select_multiple(Xen chooser, Xen select_multiple) { #define H_gtk_file_chooser_set_select_multiple "void gtk_file_chooser_set_select_multiple(GtkFileChooser* chooser, \ gboolean select_multiple)" Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_set_select_multiple", "GtkFileChooser*"); Xen_check_type(Xen_is_gboolean(select_multiple), select_multiple, 2, "gtk_file_chooser_set_select_multiple", "gboolean"); gtk_file_chooser_set_select_multiple(Xen_to_C_GtkFileChooser_(chooser), Xen_to_C_gboolean(select_multiple)); return(Xen_false); } static Xen gxg_gtk_file_chooser_get_select_multiple(Xen chooser) { #define H_gtk_file_chooser_get_select_multiple "gboolean gtk_file_chooser_get_select_multiple(GtkFileChooser* chooser)" Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_get_select_multiple", "GtkFileChooser*"); return(C_to_Xen_gboolean(gtk_file_chooser_get_select_multiple(Xen_to_C_GtkFileChooser_(chooser)))); } static Xen gxg_gtk_file_chooser_set_current_name(Xen chooser, Xen name) { #define H_gtk_file_chooser_set_current_name "void gtk_file_chooser_set_current_name(GtkFileChooser* chooser, \ gchar* name)" Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_set_current_name", "GtkFileChooser*"); Xen_check_type(Xen_is_gchar_(name), name, 2, "gtk_file_chooser_set_current_name", "gchar*"); gtk_file_chooser_set_current_name(Xen_to_C_GtkFileChooser_(chooser), Xen_to_C_gchar_(name)); return(Xen_false); } static Xen gxg_gtk_file_chooser_get_filename(Xen chooser) { #define H_gtk_file_chooser_get_filename "gchar* gtk_file_chooser_get_filename(GtkFileChooser* chooser)" Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_get_filename", "GtkFileChooser*"); { gchar* result; Xen rtn; result = gtk_file_chooser_get_filename(Xen_to_C_GtkFileChooser_(chooser)); rtn = C_to_Xen_gchar_(result); g_free(result); return(rtn); } } static Xen gxg_gtk_file_chooser_set_filename(Xen chooser, Xen filename) { #define H_gtk_file_chooser_set_filename "gboolean gtk_file_chooser_set_filename(GtkFileChooser* chooser, \ char* filename)" Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_set_filename", "GtkFileChooser*"); Xen_check_type(Xen_is_char_(filename), filename, 2, "gtk_file_chooser_set_filename", "char*"); return(C_to_Xen_gboolean(gtk_file_chooser_set_filename(Xen_to_C_GtkFileChooser_(chooser), Xen_to_C_char_(filename)))); } static Xen gxg_gtk_file_chooser_select_filename(Xen chooser, Xen filename) { #define H_gtk_file_chooser_select_filename "gboolean gtk_file_chooser_select_filename(GtkFileChooser* chooser, \ char* filename)" Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_select_filename", "GtkFileChooser*"); Xen_check_type(Xen_is_char_(filename), filename, 2, "gtk_file_chooser_select_filename", "char*"); return(C_to_Xen_gboolean(gtk_file_chooser_select_filename(Xen_to_C_GtkFileChooser_(chooser), Xen_to_C_char_(filename)))); } static Xen gxg_gtk_file_chooser_unselect_filename(Xen chooser, Xen filename) { #define H_gtk_file_chooser_unselect_filename "void gtk_file_chooser_unselect_filename(GtkFileChooser* chooser, \ char* filename)" Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_unselect_filename", "GtkFileChooser*"); Xen_check_type(Xen_is_char_(filename), filename, 2, "gtk_file_chooser_unselect_filename", "char*"); gtk_file_chooser_unselect_filename(Xen_to_C_GtkFileChooser_(chooser), Xen_to_C_char_(filename)); return(Xen_false); } static Xen gxg_gtk_file_chooser_select_all(Xen chooser) { #define H_gtk_file_chooser_select_all "void gtk_file_chooser_select_all(GtkFileChooser* chooser)" Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_select_all", "GtkFileChooser*"); gtk_file_chooser_select_all(Xen_to_C_GtkFileChooser_(chooser)); return(Xen_false); } static Xen gxg_gtk_file_chooser_unselect_all(Xen chooser) { #define H_gtk_file_chooser_unselect_all "void gtk_file_chooser_unselect_all(GtkFileChooser* chooser)" Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_unselect_all", "GtkFileChooser*"); gtk_file_chooser_unselect_all(Xen_to_C_GtkFileChooser_(chooser)); return(Xen_false); } static Xen gxg_gtk_file_chooser_get_filenames(Xen chooser) { #define H_gtk_file_chooser_get_filenames "GSList* gtk_file_chooser_get_filenames(GtkFileChooser* chooser)" Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_get_filenames", "GtkFileChooser*"); return(C_to_Xen_GSList_(gtk_file_chooser_get_filenames(Xen_to_C_GtkFileChooser_(chooser)))); } static Xen gxg_gtk_file_chooser_set_current_folder(Xen chooser, Xen filename) { #define H_gtk_file_chooser_set_current_folder "gboolean gtk_file_chooser_set_current_folder(GtkFileChooser* chooser, \ gchar* filename)" Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_set_current_folder", "GtkFileChooser*"); Xen_check_type(Xen_is_gchar_(filename), filename, 2, "gtk_file_chooser_set_current_folder", "gchar*"); return(C_to_Xen_gboolean(gtk_file_chooser_set_current_folder(Xen_to_C_GtkFileChooser_(chooser), Xen_to_C_gchar_(filename)))); } static Xen gxg_gtk_file_chooser_get_current_folder(Xen chooser) { #define H_gtk_file_chooser_get_current_folder "gchar* gtk_file_chooser_get_current_folder(GtkFileChooser* chooser)" Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_get_current_folder", "GtkFileChooser*"); { gchar* result; Xen rtn; result = gtk_file_chooser_get_current_folder(Xen_to_C_GtkFileChooser_(chooser)); rtn = C_to_Xen_gchar_(result); g_free(result); return(rtn); } } static Xen gxg_gtk_file_chooser_get_uri(Xen chooser) { #define H_gtk_file_chooser_get_uri "gchar* gtk_file_chooser_get_uri(GtkFileChooser* chooser)" Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_get_uri", "GtkFileChooser*"); { gchar* result; Xen rtn; result = gtk_file_chooser_get_uri(Xen_to_C_GtkFileChooser_(chooser)); rtn = C_to_Xen_gchar_(result); g_free(result); return(rtn); } } static Xen gxg_gtk_file_chooser_set_uri(Xen chooser, Xen uri) { #define H_gtk_file_chooser_set_uri "gboolean gtk_file_chooser_set_uri(GtkFileChooser* chooser, char* uri)" Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_set_uri", "GtkFileChooser*"); Xen_check_type(Xen_is_char_(uri), uri, 2, "gtk_file_chooser_set_uri", "char*"); return(C_to_Xen_gboolean(gtk_file_chooser_set_uri(Xen_to_C_GtkFileChooser_(chooser), Xen_to_C_char_(uri)))); } static Xen gxg_gtk_file_chooser_select_uri(Xen chooser, Xen uri) { #define H_gtk_file_chooser_select_uri "gboolean gtk_file_chooser_select_uri(GtkFileChooser* chooser, \ char* uri)" Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_select_uri", "GtkFileChooser*"); Xen_check_type(Xen_is_char_(uri), uri, 2, "gtk_file_chooser_select_uri", "char*"); return(C_to_Xen_gboolean(gtk_file_chooser_select_uri(Xen_to_C_GtkFileChooser_(chooser), Xen_to_C_char_(uri)))); } static Xen gxg_gtk_file_chooser_unselect_uri(Xen chooser, Xen uri) { #define H_gtk_file_chooser_unselect_uri "void gtk_file_chooser_unselect_uri(GtkFileChooser* chooser, \ char* uri)" Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_unselect_uri", "GtkFileChooser*"); Xen_check_type(Xen_is_char_(uri), uri, 2, "gtk_file_chooser_unselect_uri", "char*"); gtk_file_chooser_unselect_uri(Xen_to_C_GtkFileChooser_(chooser), Xen_to_C_char_(uri)); return(Xen_false); } static Xen gxg_gtk_file_chooser_get_uris(Xen chooser) { #define H_gtk_file_chooser_get_uris "GSList* gtk_file_chooser_get_uris(GtkFileChooser* chooser)" Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_get_uris", "GtkFileChooser*"); return(C_to_Xen_GSList_(gtk_file_chooser_get_uris(Xen_to_C_GtkFileChooser_(chooser)))); } static Xen gxg_gtk_file_chooser_set_current_folder_uri(Xen chooser, Xen uri) { #define H_gtk_file_chooser_set_current_folder_uri "gboolean gtk_file_chooser_set_current_folder_uri(GtkFileChooser* chooser, \ gchar* uri)" Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_set_current_folder_uri", "GtkFileChooser*"); Xen_check_type(Xen_is_gchar_(uri), uri, 2, "gtk_file_chooser_set_current_folder_uri", "gchar*"); return(C_to_Xen_gboolean(gtk_file_chooser_set_current_folder_uri(Xen_to_C_GtkFileChooser_(chooser), Xen_to_C_gchar_(uri)))); } static Xen gxg_gtk_file_chooser_get_current_folder_uri(Xen chooser) { #define H_gtk_file_chooser_get_current_folder_uri "gchar* gtk_file_chooser_get_current_folder_uri(GtkFileChooser* chooser)" Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_get_current_folder_uri", "GtkFileChooser*"); { gchar* result; Xen rtn; result = gtk_file_chooser_get_current_folder_uri(Xen_to_C_GtkFileChooser_(chooser)); rtn = C_to_Xen_gchar_(result); g_free(result); return(rtn); } } static Xen gxg_gtk_file_chooser_set_preview_widget(Xen chooser, Xen preview_widget) { #define H_gtk_file_chooser_set_preview_widget "void gtk_file_chooser_set_preview_widget(GtkFileChooser* chooser, \ GtkWidget* preview_widget)" Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_set_preview_widget", "GtkFileChooser*"); Xen_check_type(Xen_is_GtkWidget_(preview_widget), preview_widget, 2, "gtk_file_chooser_set_preview_widget", "GtkWidget*"); gtk_file_chooser_set_preview_widget(Xen_to_C_GtkFileChooser_(chooser), Xen_to_C_GtkWidget_(preview_widget)); return(Xen_false); } static Xen gxg_gtk_file_chooser_get_preview_widget(Xen chooser) { #define H_gtk_file_chooser_get_preview_widget "GtkWidget* gtk_file_chooser_get_preview_widget(GtkFileChooser* chooser)" Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_get_preview_widget", "GtkFileChooser*"); return(C_to_Xen_GtkWidget_(gtk_file_chooser_get_preview_widget(Xen_to_C_GtkFileChooser_(chooser)))); } static Xen gxg_gtk_file_chooser_set_preview_widget_active(Xen chooser, Xen active) { #define H_gtk_file_chooser_set_preview_widget_active "void gtk_file_chooser_set_preview_widget_active(GtkFileChooser* chooser, \ gboolean active)" Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_set_preview_widget_active", "GtkFileChooser*"); Xen_check_type(Xen_is_gboolean(active), active, 2, "gtk_file_chooser_set_preview_widget_active", "gboolean"); gtk_file_chooser_set_preview_widget_active(Xen_to_C_GtkFileChooser_(chooser), Xen_to_C_gboolean(active)); return(Xen_false); } static Xen gxg_gtk_file_chooser_get_preview_widget_active(Xen chooser) { #define H_gtk_file_chooser_get_preview_widget_active "gboolean gtk_file_chooser_get_preview_widget_active(GtkFileChooser* chooser)" Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_get_preview_widget_active", "GtkFileChooser*"); return(C_to_Xen_gboolean(gtk_file_chooser_get_preview_widget_active(Xen_to_C_GtkFileChooser_(chooser)))); } static Xen gxg_gtk_file_chooser_get_preview_filename(Xen file_chooser) { #define H_gtk_file_chooser_get_preview_filename "char* gtk_file_chooser_get_preview_filename(GtkFileChooser* file_chooser)" Xen_check_type(Xen_is_GtkFileChooser_(file_chooser), file_chooser, 1, "gtk_file_chooser_get_preview_filename", "GtkFileChooser*"); { char* result; Xen rtn; result = gtk_file_chooser_get_preview_filename(Xen_to_C_GtkFileChooser_(file_chooser)); rtn = C_to_Xen_char_(result); g_free(result); return(rtn); } } static Xen gxg_gtk_file_chooser_get_preview_uri(Xen file_chooser) { #define H_gtk_file_chooser_get_preview_uri "char* gtk_file_chooser_get_preview_uri(GtkFileChooser* file_chooser)" Xen_check_type(Xen_is_GtkFileChooser_(file_chooser), file_chooser, 1, "gtk_file_chooser_get_preview_uri", "GtkFileChooser*"); { char* result; Xen rtn; result = gtk_file_chooser_get_preview_uri(Xen_to_C_GtkFileChooser_(file_chooser)); rtn = C_to_Xen_char_(result); g_free(result); return(rtn); } } static Xen gxg_gtk_file_chooser_set_extra_widget(Xen chooser, Xen extra_widget) { #define H_gtk_file_chooser_set_extra_widget "void gtk_file_chooser_set_extra_widget(GtkFileChooser* chooser, \ GtkWidget* extra_widget)" Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_set_extra_widget", "GtkFileChooser*"); Xen_check_type(Xen_is_GtkWidget_(extra_widget), extra_widget, 2, "gtk_file_chooser_set_extra_widget", "GtkWidget*"); gtk_file_chooser_set_extra_widget(Xen_to_C_GtkFileChooser_(chooser), Xen_to_C_GtkWidget_(extra_widget)); return(Xen_false); } static Xen gxg_gtk_file_chooser_get_extra_widget(Xen chooser) { #define H_gtk_file_chooser_get_extra_widget "GtkWidget* gtk_file_chooser_get_extra_widget(GtkFileChooser* chooser)" Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_get_extra_widget", "GtkFileChooser*"); return(C_to_Xen_GtkWidget_(gtk_file_chooser_get_extra_widget(Xen_to_C_GtkFileChooser_(chooser)))); } static Xen gxg_gtk_file_chooser_add_filter(Xen chooser, Xen filter) { #define H_gtk_file_chooser_add_filter "void gtk_file_chooser_add_filter(GtkFileChooser* chooser, GtkFileFilter* filter)" Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_add_filter", "GtkFileChooser*"); Xen_check_type(Xen_is_GtkFileFilter_(filter), filter, 2, "gtk_file_chooser_add_filter", "GtkFileFilter*"); gtk_file_chooser_add_filter(Xen_to_C_GtkFileChooser_(chooser), Xen_to_C_GtkFileFilter_(filter)); return(Xen_false); } static Xen gxg_gtk_file_chooser_remove_filter(Xen chooser, Xen filter) { #define H_gtk_file_chooser_remove_filter "void gtk_file_chooser_remove_filter(GtkFileChooser* chooser, \ GtkFileFilter* filter)" Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_remove_filter", "GtkFileChooser*"); Xen_check_type(Xen_is_GtkFileFilter_(filter), filter, 2, "gtk_file_chooser_remove_filter", "GtkFileFilter*"); gtk_file_chooser_remove_filter(Xen_to_C_GtkFileChooser_(chooser), Xen_to_C_GtkFileFilter_(filter)); return(Xen_false); } static Xen gxg_gtk_file_chooser_list_filters(Xen chooser) { #define H_gtk_file_chooser_list_filters "GSList* gtk_file_chooser_list_filters(GtkFileChooser* chooser)" Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_list_filters", "GtkFileChooser*"); return(C_to_Xen_GSList_(gtk_file_chooser_list_filters(Xen_to_C_GtkFileChooser_(chooser)))); } static Xen gxg_gtk_file_chooser_set_filter(Xen chooser, Xen filter) { #define H_gtk_file_chooser_set_filter "void gtk_file_chooser_set_filter(GtkFileChooser* chooser, GtkFileFilter* filter)" Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_set_filter", "GtkFileChooser*"); Xen_check_type(Xen_is_GtkFileFilter_(filter), filter, 2, "gtk_file_chooser_set_filter", "GtkFileFilter*"); gtk_file_chooser_set_filter(Xen_to_C_GtkFileChooser_(chooser), Xen_to_C_GtkFileFilter_(filter)); return(Xen_false); } static Xen gxg_gtk_file_chooser_get_filter(Xen chooser) { #define H_gtk_file_chooser_get_filter "GtkFileFilter* gtk_file_chooser_get_filter(GtkFileChooser* chooser)" Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_get_filter", "GtkFileChooser*"); return(C_to_Xen_GtkFileFilter_(gtk_file_chooser_get_filter(Xen_to_C_GtkFileChooser_(chooser)))); } static Xen gxg_gtk_file_chooser_add_shortcut_folder(Xen chooser, Xen folder, Xen ignore_error) { #define H_gtk_file_chooser_add_shortcut_folder "gboolean gtk_file_chooser_add_shortcut_folder(GtkFileChooser* chooser, \ char* folder, GError** [error])" GError* ref_error = NULL; Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_add_shortcut_folder", "GtkFileChooser*"); Xen_check_type(Xen_is_char_(folder), folder, 2, "gtk_file_chooser_add_shortcut_folder", "char*"); { Xen result; result = C_to_Xen_gboolean(gtk_file_chooser_add_shortcut_folder(Xen_to_C_GtkFileChooser_(chooser), Xen_to_C_char_(folder), &ref_error)); return(Xen_list_2(result, C_to_Xen_GError_(ref_error))); } } static Xen gxg_gtk_file_chooser_remove_shortcut_folder(Xen chooser, Xen folder, Xen ignore_error) { #define H_gtk_file_chooser_remove_shortcut_folder "gboolean gtk_file_chooser_remove_shortcut_folder(GtkFileChooser* chooser, \ char* folder, GError** [error])" GError* ref_error = NULL; Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_remove_shortcut_folder", "GtkFileChooser*"); Xen_check_type(Xen_is_char_(folder), folder, 2, "gtk_file_chooser_remove_shortcut_folder", "char*"); { Xen result; result = C_to_Xen_gboolean(gtk_file_chooser_remove_shortcut_folder(Xen_to_C_GtkFileChooser_(chooser), Xen_to_C_char_(folder), &ref_error)); return(Xen_list_2(result, C_to_Xen_GError_(ref_error))); } } static Xen gxg_gtk_file_chooser_list_shortcut_folders(Xen chooser) { #define H_gtk_file_chooser_list_shortcut_folders "GSList* gtk_file_chooser_list_shortcut_folders(GtkFileChooser* chooser)" Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_list_shortcut_folders", "GtkFileChooser*"); return(C_to_Xen_GSList_(gtk_file_chooser_list_shortcut_folders(Xen_to_C_GtkFileChooser_(chooser)))); } static Xen gxg_gtk_file_chooser_add_shortcut_folder_uri(Xen chooser, Xen folder, Xen ignore_error) { #define H_gtk_file_chooser_add_shortcut_folder_uri "gboolean gtk_file_chooser_add_shortcut_folder_uri(GtkFileChooser* chooser, \ char* folder, GError** [error])" GError* ref_error = NULL; Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_add_shortcut_folder_uri", "GtkFileChooser*"); Xen_check_type(Xen_is_char_(folder), folder, 2, "gtk_file_chooser_add_shortcut_folder_uri", "char*"); { Xen result; result = C_to_Xen_gboolean(gtk_file_chooser_add_shortcut_folder_uri(Xen_to_C_GtkFileChooser_(chooser), Xen_to_C_char_(folder), &ref_error)); return(Xen_list_2(result, C_to_Xen_GError_(ref_error))); } } static Xen gxg_gtk_file_chooser_remove_shortcut_folder_uri(Xen chooser, Xen folder, Xen ignore_error) { #define H_gtk_file_chooser_remove_shortcut_folder_uri "gboolean gtk_file_chooser_remove_shortcut_folder_uri(GtkFileChooser* chooser, \ char* folder, GError** [error])" GError* ref_error = NULL; Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_remove_shortcut_folder_uri", "GtkFileChooser*"); Xen_check_type(Xen_is_char_(folder), folder, 2, "gtk_file_chooser_remove_shortcut_folder_uri", "char*"); { Xen result; result = C_to_Xen_gboolean(gtk_file_chooser_remove_shortcut_folder_uri(Xen_to_C_GtkFileChooser_(chooser), Xen_to_C_char_(folder), &ref_error)); return(Xen_list_2(result, C_to_Xen_GError_(ref_error))); } } static Xen gxg_gtk_file_chooser_list_shortcut_folder_uris(Xen chooser) { #define H_gtk_file_chooser_list_shortcut_folder_uris "GSList* gtk_file_chooser_list_shortcut_folder_uris(GtkFileChooser* chooser)" Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_list_shortcut_folder_uris", "GtkFileChooser*"); return(C_to_Xen_GSList_(gtk_file_chooser_list_shortcut_folder_uris(Xen_to_C_GtkFileChooser_(chooser)))); } static Xen gxg_gtk_icon_theme_new(void) { #define H_gtk_icon_theme_new "GtkIconTheme* gtk_icon_theme_new( void)" return(C_to_Xen_GtkIconTheme_(gtk_icon_theme_new())); } static Xen gxg_gtk_icon_theme_get_default(void) { #define H_gtk_icon_theme_get_default "GtkIconTheme* gtk_icon_theme_get_default( void)" return(C_to_Xen_GtkIconTheme_(gtk_icon_theme_get_default())); } static Xen gxg_gtk_icon_theme_get_for_screen(Xen screen) { #define H_gtk_icon_theme_get_for_screen "GtkIconTheme* gtk_icon_theme_get_for_screen(GdkScreen* screen)" Xen_check_type(Xen_is_GdkScreen_(screen), screen, 1, "gtk_icon_theme_get_for_screen", "GdkScreen*"); return(C_to_Xen_GtkIconTheme_(gtk_icon_theme_get_for_screen(Xen_to_C_GdkScreen_(screen)))); } static Xen gxg_gtk_icon_theme_set_screen(Xen icon_theme, Xen screen) { #define H_gtk_icon_theme_set_screen "void gtk_icon_theme_set_screen(GtkIconTheme* icon_theme, GdkScreen* screen)" Xen_check_type(Xen_is_GtkIconTheme_(icon_theme), icon_theme, 1, "gtk_icon_theme_set_screen", "GtkIconTheme*"); Xen_check_type(Xen_is_GdkScreen_(screen) || Xen_is_false(screen), screen, 2, "gtk_icon_theme_set_screen", "GdkScreen*"); gtk_icon_theme_set_screen(Xen_to_C_GtkIconTheme_(icon_theme), Xen_to_C_GdkScreen_(screen)); return(Xen_false); } static Xen gxg_gtk_icon_theme_get_search_path(Xen icon_theme, Xen ignore_path, Xen ignore_n_elements) { #define H_gtk_icon_theme_get_search_path "void gtk_icon_theme_get_search_path(GtkIconTheme* icon_theme, \ gchar*** [path], gint* [n_elements])" gchar** ref_path = NULL; gint ref_n_elements; Xen_check_type(Xen_is_GtkIconTheme_(icon_theme), icon_theme, 1, "gtk_icon_theme_get_search_path", "GtkIconTheme*"); gtk_icon_theme_get_search_path(Xen_to_C_GtkIconTheme_(icon_theme), &ref_path, &ref_n_elements); return(Xen_list_2(C_to_Xen_gchar__(ref_path), C_to_Xen_gint(ref_n_elements))); } static Xen gxg_gtk_icon_theme_append_search_path(Xen icon_theme, Xen path) { #define H_gtk_icon_theme_append_search_path "void gtk_icon_theme_append_search_path(GtkIconTheme* icon_theme, \ gchar* path)" Xen_check_type(Xen_is_GtkIconTheme_(icon_theme), icon_theme, 1, "gtk_icon_theme_append_search_path", "GtkIconTheme*"); Xen_check_type(Xen_is_gchar_(path), path, 2, "gtk_icon_theme_append_search_path", "gchar*"); gtk_icon_theme_append_search_path(Xen_to_C_GtkIconTheme_(icon_theme), Xen_to_C_gchar_(path)); return(Xen_false); } static Xen gxg_gtk_icon_theme_prepend_search_path(Xen icon_theme, Xen path) { #define H_gtk_icon_theme_prepend_search_path "void gtk_icon_theme_prepend_search_path(GtkIconTheme* icon_theme, \ gchar* path)" Xen_check_type(Xen_is_GtkIconTheme_(icon_theme), icon_theme, 1, "gtk_icon_theme_prepend_search_path", "GtkIconTheme*"); Xen_check_type(Xen_is_gchar_(path), path, 2, "gtk_icon_theme_prepend_search_path", "gchar*"); gtk_icon_theme_prepend_search_path(Xen_to_C_GtkIconTheme_(icon_theme), Xen_to_C_gchar_(path)); return(Xen_false); } static Xen gxg_gtk_icon_theme_set_custom_theme(Xen icon_theme, Xen theme_name) { #define H_gtk_icon_theme_set_custom_theme "void gtk_icon_theme_set_custom_theme(GtkIconTheme* icon_theme, \ gchar* theme_name)" Xen_check_type(Xen_is_GtkIconTheme_(icon_theme), icon_theme, 1, "gtk_icon_theme_set_custom_theme", "GtkIconTheme*"); Xen_check_type(Xen_is_gchar_(theme_name), theme_name, 2, "gtk_icon_theme_set_custom_theme", "gchar*"); gtk_icon_theme_set_custom_theme(Xen_to_C_GtkIconTheme_(icon_theme), Xen_to_C_gchar_(theme_name)); return(Xen_false); } static Xen gxg_gtk_icon_theme_has_icon(Xen icon_theme, Xen icon_name) { #define H_gtk_icon_theme_has_icon "gboolean gtk_icon_theme_has_icon(GtkIconTheme* icon_theme, gchar* icon_name)" Xen_check_type(Xen_is_GtkIconTheme_(icon_theme), icon_theme, 1, "gtk_icon_theme_has_icon", "GtkIconTheme*"); Xen_check_type(Xen_is_gchar_(icon_name), icon_name, 2, "gtk_icon_theme_has_icon", "gchar*"); return(C_to_Xen_gboolean(gtk_icon_theme_has_icon(Xen_to_C_GtkIconTheme_(icon_theme), Xen_to_C_gchar_(icon_name)))); } static Xen gxg_gtk_icon_theme_lookup_icon(Xen icon_theme, Xen icon_name, Xen size, Xen flags) { #define H_gtk_icon_theme_lookup_icon "GtkIconInfo* gtk_icon_theme_lookup_icon(GtkIconTheme* icon_theme, \ gchar* icon_name, gint size, GtkIconLookupFlags flags)" Xen_check_type(Xen_is_GtkIconTheme_(icon_theme), icon_theme, 1, "gtk_icon_theme_lookup_icon", "GtkIconTheme*"); Xen_check_type(Xen_is_gchar_(icon_name), icon_name, 2, "gtk_icon_theme_lookup_icon", "gchar*"); Xen_check_type(Xen_is_gint(size), size, 3, "gtk_icon_theme_lookup_icon", "gint"); Xen_check_type(Xen_is_GtkIconLookupFlags(flags), flags, 4, "gtk_icon_theme_lookup_icon", "GtkIconLookupFlags"); return(C_to_Xen_GtkIconInfo_(gtk_icon_theme_lookup_icon(Xen_to_C_GtkIconTheme_(icon_theme), Xen_to_C_gchar_(icon_name), Xen_to_C_gint(size), Xen_to_C_GtkIconLookupFlags(flags)))); } static Xen gxg_gtk_icon_theme_load_icon(Xen icon_theme, Xen icon_name, Xen size, Xen flags, Xen ignore_error) { #define H_gtk_icon_theme_load_icon "GdkPixbuf* gtk_icon_theme_load_icon(GtkIconTheme* icon_theme, gchar* icon_name, \ gint size, GtkIconLookupFlags flags, GError** [error])" GError* ref_error = NULL; Xen_check_type(Xen_is_GtkIconTheme_(icon_theme), icon_theme, 1, "gtk_icon_theme_load_icon", "GtkIconTheme*"); Xen_check_type(Xen_is_gchar_(icon_name), icon_name, 2, "gtk_icon_theme_load_icon", "gchar*"); Xen_check_type(Xen_is_gint(size), size, 3, "gtk_icon_theme_load_icon", "gint"); Xen_check_type(Xen_is_GtkIconLookupFlags(flags), flags, 4, "gtk_icon_theme_load_icon", "GtkIconLookupFlags"); { Xen result; result = C_to_Xen_GdkPixbuf_(gtk_icon_theme_load_icon(Xen_to_C_GtkIconTheme_(icon_theme), Xen_to_C_gchar_(icon_name), Xen_to_C_gint(size), Xen_to_C_GtkIconLookupFlags(flags), &ref_error)); return(Xen_list_2(result, C_to_Xen_GError_(ref_error))); } } static Xen gxg_gtk_icon_theme_list_icons(Xen icon_theme, Xen context) { #define H_gtk_icon_theme_list_icons "GList* gtk_icon_theme_list_icons(GtkIconTheme* icon_theme, gchar* context)" Xen_check_type(Xen_is_GtkIconTheme_(icon_theme), icon_theme, 1, "gtk_icon_theme_list_icons", "GtkIconTheme*"); Xen_check_type(Xen_is_gchar_(context), context, 2, "gtk_icon_theme_list_icons", "gchar*"); return(C_to_Xen_GList_(gtk_icon_theme_list_icons(Xen_to_C_GtkIconTheme_(icon_theme), Xen_to_C_gchar_(context)))); } static Xen gxg_gtk_icon_theme_get_example_icon_name(Xen icon_theme) { #define H_gtk_icon_theme_get_example_icon_name "char* gtk_icon_theme_get_example_icon_name(GtkIconTheme* icon_theme)" Xen_check_type(Xen_is_GtkIconTheme_(icon_theme), icon_theme, 1, "gtk_icon_theme_get_example_icon_name", "GtkIconTheme*"); return(C_to_Xen_char_(gtk_icon_theme_get_example_icon_name(Xen_to_C_GtkIconTheme_(icon_theme)))); } static Xen gxg_gtk_icon_theme_rescan_if_needed(Xen icon_theme) { #define H_gtk_icon_theme_rescan_if_needed "gboolean gtk_icon_theme_rescan_if_needed(GtkIconTheme* icon_theme)" Xen_check_type(Xen_is_GtkIconTheme_(icon_theme), icon_theme, 1, "gtk_icon_theme_rescan_if_needed", "GtkIconTheme*"); return(C_to_Xen_gboolean(gtk_icon_theme_rescan_if_needed(Xen_to_C_GtkIconTheme_(icon_theme)))); } static Xen gxg_gtk_icon_info_get_base_size(Xen icon_info) { #define H_gtk_icon_info_get_base_size "gint gtk_icon_info_get_base_size(GtkIconInfo* icon_info)" Xen_check_type(Xen_is_GtkIconInfo_(icon_info), icon_info, 1, "gtk_icon_info_get_base_size", "GtkIconInfo*"); return(C_to_Xen_gint(gtk_icon_info_get_base_size(Xen_to_C_GtkIconInfo_(icon_info)))); } static Xen gxg_gtk_icon_info_get_filename(Xen icon_info) { #define H_gtk_icon_info_get_filename "gchar* gtk_icon_info_get_filename(GtkIconInfo* icon_info)" Xen_check_type(Xen_is_GtkIconInfo_(icon_info), icon_info, 1, "gtk_icon_info_get_filename", "GtkIconInfo*"); return(C_to_Xen_gchar_(gtk_icon_info_get_filename(Xen_to_C_GtkIconInfo_(icon_info)))); } static Xen gxg_gtk_icon_info_load_icon(Xen icon_info, Xen ignore_error) { #define H_gtk_icon_info_load_icon "GdkPixbuf* gtk_icon_info_load_icon(GtkIconInfo* icon_info, GError** [error])" GError* ref_error = NULL; Xen_check_type(Xen_is_GtkIconInfo_(icon_info), icon_info, 1, "gtk_icon_info_load_icon", "GtkIconInfo*"); { Xen result; result = C_to_Xen_GdkPixbuf_(gtk_icon_info_load_icon(Xen_to_C_GtkIconInfo_(icon_info), &ref_error)); return(Xen_list_2(result, C_to_Xen_GError_(ref_error))); } } static Xen gxg_gtk_tool_button_new(Xen icon_widget, Xen label) { #define H_gtk_tool_button_new "GtkToolItem* gtk_tool_button_new(GtkWidget* icon_widget, gchar* label)" Xen_check_type(Xen_is_GtkWidget_(icon_widget) || Xen_is_false(icon_widget), icon_widget, 1, "gtk_tool_button_new", "GtkWidget*"); Xen_check_type(Xen_is_gchar_(label), label, 2, "gtk_tool_button_new", "gchar*"); return(C_to_Xen_GtkToolItem_(gtk_tool_button_new(Xen_to_C_GtkWidget_(icon_widget), Xen_to_C_gchar_(label)))); } static Xen gxg_gtk_tool_button_set_label(Xen button, Xen label) { #define H_gtk_tool_button_set_label "void gtk_tool_button_set_label(GtkToolButton* button, gchar* label)" Xen_check_type(Xen_is_GtkToolButton_(button), button, 1, "gtk_tool_button_set_label", "GtkToolButton*"); Xen_check_type(Xen_is_gchar_(label), label, 2, "gtk_tool_button_set_label", "gchar*"); gtk_tool_button_set_label(Xen_to_C_GtkToolButton_(button), Xen_to_C_gchar_(label)); return(Xen_false); } static Xen gxg_gtk_tool_button_get_label(Xen button) { #define H_gtk_tool_button_get_label "gchar* gtk_tool_button_get_label(GtkToolButton* button)" Xen_check_type(Xen_is_GtkToolButton_(button), button, 1, "gtk_tool_button_get_label", "GtkToolButton*"); return(C_to_Xen_gchar_(gtk_tool_button_get_label(Xen_to_C_GtkToolButton_(button)))); } static Xen gxg_gtk_tool_button_set_use_underline(Xen button, Xen use_underline) { #define H_gtk_tool_button_set_use_underline "void gtk_tool_button_set_use_underline(GtkToolButton* button, \ gboolean use_underline)" Xen_check_type(Xen_is_GtkToolButton_(button), button, 1, "gtk_tool_button_set_use_underline", "GtkToolButton*"); Xen_check_type(Xen_is_gboolean(use_underline), use_underline, 2, "gtk_tool_button_set_use_underline", "gboolean"); gtk_tool_button_set_use_underline(Xen_to_C_GtkToolButton_(button), Xen_to_C_gboolean(use_underline)); return(Xen_false); } static Xen gxg_gtk_tool_button_get_use_underline(Xen button) { #define H_gtk_tool_button_get_use_underline "gboolean gtk_tool_button_get_use_underline(GtkToolButton* button)" Xen_check_type(Xen_is_GtkToolButton_(button), button, 1, "gtk_tool_button_get_use_underline", "GtkToolButton*"); return(C_to_Xen_gboolean(gtk_tool_button_get_use_underline(Xen_to_C_GtkToolButton_(button)))); } static Xen gxg_gtk_tool_button_set_icon_widget(Xen button, Xen icon_widget) { #define H_gtk_tool_button_set_icon_widget "void gtk_tool_button_set_icon_widget(GtkToolButton* button, \ GtkWidget* icon_widget)" Xen_check_type(Xen_is_GtkToolButton_(button), button, 1, "gtk_tool_button_set_icon_widget", "GtkToolButton*"); Xen_check_type(Xen_is_GtkWidget_(icon_widget) || Xen_is_false(icon_widget), icon_widget, 2, "gtk_tool_button_set_icon_widget", "GtkWidget*"); gtk_tool_button_set_icon_widget(Xen_to_C_GtkToolButton_(button), Xen_to_C_GtkWidget_(icon_widget)); return(Xen_false); } static Xen gxg_gtk_tool_button_get_icon_widget(Xen button) { #define H_gtk_tool_button_get_icon_widget "GtkWidget* gtk_tool_button_get_icon_widget(GtkToolButton* button)" Xen_check_type(Xen_is_GtkToolButton_(button), button, 1, "gtk_tool_button_get_icon_widget", "GtkToolButton*"); return(C_to_Xen_GtkWidget_(gtk_tool_button_get_icon_widget(Xen_to_C_GtkToolButton_(button)))); } static Xen gxg_gtk_tool_button_set_label_widget(Xen button, Xen label_widget) { #define H_gtk_tool_button_set_label_widget "void gtk_tool_button_set_label_widget(GtkToolButton* button, \ GtkWidget* label_widget)" Xen_check_type(Xen_is_GtkToolButton_(button), button, 1, "gtk_tool_button_set_label_widget", "GtkToolButton*"); Xen_check_type(Xen_is_GtkWidget_(label_widget) || Xen_is_false(label_widget), label_widget, 2, "gtk_tool_button_set_label_widget", "GtkWidget*"); gtk_tool_button_set_label_widget(Xen_to_C_GtkToolButton_(button), Xen_to_C_GtkWidget_(label_widget)); return(Xen_false); } static Xen gxg_gtk_tool_button_get_label_widget(Xen button) { #define H_gtk_tool_button_get_label_widget "GtkWidget* gtk_tool_button_get_label_widget(GtkToolButton* button)" Xen_check_type(Xen_is_GtkToolButton_(button), button, 1, "gtk_tool_button_get_label_widget", "GtkToolButton*"); return(C_to_Xen_GtkWidget_(gtk_tool_button_get_label_widget(Xen_to_C_GtkToolButton_(button)))); } static Xen gxg_gtk_tool_item_new(void) { #define H_gtk_tool_item_new "GtkToolItem* gtk_tool_item_new( void)" return(C_to_Xen_GtkToolItem_(gtk_tool_item_new())); } static Xen gxg_gtk_tool_item_set_homogeneous(Xen tool_item, Xen homogeneous) { #define H_gtk_tool_item_set_homogeneous "void gtk_tool_item_set_homogeneous(GtkToolItem* tool_item, \ gboolean homogeneous)" Xen_check_type(Xen_is_GtkToolItem_(tool_item), tool_item, 1, "gtk_tool_item_set_homogeneous", "GtkToolItem*"); Xen_check_type(Xen_is_gboolean(homogeneous), homogeneous, 2, "gtk_tool_item_set_homogeneous", "gboolean"); gtk_tool_item_set_homogeneous(Xen_to_C_GtkToolItem_(tool_item), Xen_to_C_gboolean(homogeneous)); return(Xen_false); } static Xen gxg_gtk_tool_item_get_homogeneous(Xen tool_item) { #define H_gtk_tool_item_get_homogeneous "gboolean gtk_tool_item_get_homogeneous(GtkToolItem* tool_item)" Xen_check_type(Xen_is_GtkToolItem_(tool_item), tool_item, 1, "gtk_tool_item_get_homogeneous", "GtkToolItem*"); return(C_to_Xen_gboolean(gtk_tool_item_get_homogeneous(Xen_to_C_GtkToolItem_(tool_item)))); } static Xen gxg_gtk_tool_item_set_expand(Xen tool_item, Xen expand) { #define H_gtk_tool_item_set_expand "void gtk_tool_item_set_expand(GtkToolItem* tool_item, gboolean expand)" Xen_check_type(Xen_is_GtkToolItem_(tool_item), tool_item, 1, "gtk_tool_item_set_expand", "GtkToolItem*"); Xen_check_type(Xen_is_gboolean(expand), expand, 2, "gtk_tool_item_set_expand", "gboolean"); gtk_tool_item_set_expand(Xen_to_C_GtkToolItem_(tool_item), Xen_to_C_gboolean(expand)); return(Xen_false); } static Xen gxg_gtk_tool_item_get_expand(Xen tool_item) { #define H_gtk_tool_item_get_expand "gboolean gtk_tool_item_get_expand(GtkToolItem* tool_item)" Xen_check_type(Xen_is_GtkToolItem_(tool_item), tool_item, 1, "gtk_tool_item_get_expand", "GtkToolItem*"); return(C_to_Xen_gboolean(gtk_tool_item_get_expand(Xen_to_C_GtkToolItem_(tool_item)))); } static Xen gxg_gtk_tool_item_set_use_drag_window(Xen toolitem, Xen use_drag_window) { #define H_gtk_tool_item_set_use_drag_window "void gtk_tool_item_set_use_drag_window(GtkToolItem* toolitem, \ gboolean use_drag_window)" Xen_check_type(Xen_is_GtkToolItem_(toolitem), toolitem, 1, "gtk_tool_item_set_use_drag_window", "GtkToolItem*"); Xen_check_type(Xen_is_gboolean(use_drag_window), use_drag_window, 2, "gtk_tool_item_set_use_drag_window", "gboolean"); gtk_tool_item_set_use_drag_window(Xen_to_C_GtkToolItem_(toolitem), Xen_to_C_gboolean(use_drag_window)); return(Xen_false); } static Xen gxg_gtk_tool_item_get_use_drag_window(Xen toolitem) { #define H_gtk_tool_item_get_use_drag_window "gboolean gtk_tool_item_get_use_drag_window(GtkToolItem* toolitem)" Xen_check_type(Xen_is_GtkToolItem_(toolitem), toolitem, 1, "gtk_tool_item_get_use_drag_window", "GtkToolItem*"); return(C_to_Xen_gboolean(gtk_tool_item_get_use_drag_window(Xen_to_C_GtkToolItem_(toolitem)))); } static Xen gxg_gtk_tool_item_set_visible_horizontal(Xen toolitem, Xen visible_horizontal) { #define H_gtk_tool_item_set_visible_horizontal "void gtk_tool_item_set_visible_horizontal(GtkToolItem* toolitem, \ gboolean visible_horizontal)" Xen_check_type(Xen_is_GtkToolItem_(toolitem), toolitem, 1, "gtk_tool_item_set_visible_horizontal", "GtkToolItem*"); Xen_check_type(Xen_is_gboolean(visible_horizontal), visible_horizontal, 2, "gtk_tool_item_set_visible_horizontal", "gboolean"); gtk_tool_item_set_visible_horizontal(Xen_to_C_GtkToolItem_(toolitem), Xen_to_C_gboolean(visible_horizontal)); return(Xen_false); } static Xen gxg_gtk_tool_item_get_visible_horizontal(Xen toolitem) { #define H_gtk_tool_item_get_visible_horizontal "gboolean gtk_tool_item_get_visible_horizontal(GtkToolItem* toolitem)" Xen_check_type(Xen_is_GtkToolItem_(toolitem), toolitem, 1, "gtk_tool_item_get_visible_horizontal", "GtkToolItem*"); return(C_to_Xen_gboolean(gtk_tool_item_get_visible_horizontal(Xen_to_C_GtkToolItem_(toolitem)))); } static Xen gxg_gtk_tool_item_set_visible_vertical(Xen toolitem, Xen visible_vertical) { #define H_gtk_tool_item_set_visible_vertical "void gtk_tool_item_set_visible_vertical(GtkToolItem* toolitem, \ gboolean visible_vertical)" Xen_check_type(Xen_is_GtkToolItem_(toolitem), toolitem, 1, "gtk_tool_item_set_visible_vertical", "GtkToolItem*"); Xen_check_type(Xen_is_gboolean(visible_vertical), visible_vertical, 2, "gtk_tool_item_set_visible_vertical", "gboolean"); gtk_tool_item_set_visible_vertical(Xen_to_C_GtkToolItem_(toolitem), Xen_to_C_gboolean(visible_vertical)); return(Xen_false); } static Xen gxg_gtk_tool_item_get_visible_vertical(Xen toolitem) { #define H_gtk_tool_item_get_visible_vertical "gboolean gtk_tool_item_get_visible_vertical(GtkToolItem* toolitem)" Xen_check_type(Xen_is_GtkToolItem_(toolitem), toolitem, 1, "gtk_tool_item_get_visible_vertical", "GtkToolItem*"); return(C_to_Xen_gboolean(gtk_tool_item_get_visible_vertical(Xen_to_C_GtkToolItem_(toolitem)))); } static Xen gxg_gtk_tool_item_get_is_important(Xen tool_item) { #define H_gtk_tool_item_get_is_important "gboolean gtk_tool_item_get_is_important(GtkToolItem* tool_item)" Xen_check_type(Xen_is_GtkToolItem_(tool_item), tool_item, 1, "gtk_tool_item_get_is_important", "GtkToolItem*"); return(C_to_Xen_gboolean(gtk_tool_item_get_is_important(Xen_to_C_GtkToolItem_(tool_item)))); } static Xen gxg_gtk_tool_item_set_is_important(Xen tool_item, Xen is_important) { #define H_gtk_tool_item_set_is_important "void gtk_tool_item_set_is_important(GtkToolItem* tool_item, \ gboolean is_important)" Xen_check_type(Xen_is_GtkToolItem_(tool_item), tool_item, 1, "gtk_tool_item_set_is_important", "GtkToolItem*"); Xen_check_type(Xen_is_gboolean(is_important), is_important, 2, "gtk_tool_item_set_is_important", "gboolean"); gtk_tool_item_set_is_important(Xen_to_C_GtkToolItem_(tool_item), Xen_to_C_gboolean(is_important)); return(Xen_false); } static Xen gxg_gtk_tool_item_get_orientation(Xen tool_item) { #define H_gtk_tool_item_get_orientation "GtkOrientation gtk_tool_item_get_orientation(GtkToolItem* tool_item)" Xen_check_type(Xen_is_GtkToolItem_(tool_item), tool_item, 1, "gtk_tool_item_get_orientation", "GtkToolItem*"); return(C_to_Xen_GtkOrientation(gtk_tool_item_get_orientation(Xen_to_C_GtkToolItem_(tool_item)))); } static Xen gxg_gtk_tool_item_get_toolbar_style(Xen tool_item) { #define H_gtk_tool_item_get_toolbar_style "GtkToolbarStyle gtk_tool_item_get_toolbar_style(GtkToolItem* tool_item)" Xen_check_type(Xen_is_GtkToolItem_(tool_item), tool_item, 1, "gtk_tool_item_get_toolbar_style", "GtkToolItem*"); return(C_to_Xen_GtkToolbarStyle(gtk_tool_item_get_toolbar_style(Xen_to_C_GtkToolItem_(tool_item)))); } static Xen gxg_gtk_tool_item_get_relief_style(Xen tool_item) { #define H_gtk_tool_item_get_relief_style "GtkReliefStyle gtk_tool_item_get_relief_style(GtkToolItem* tool_item)" Xen_check_type(Xen_is_GtkToolItem_(tool_item), tool_item, 1, "gtk_tool_item_get_relief_style", "GtkToolItem*"); return(C_to_Xen_GtkReliefStyle(gtk_tool_item_get_relief_style(Xen_to_C_GtkToolItem_(tool_item)))); } static Xen gxg_gtk_tool_item_retrieve_proxy_menu_item(Xen tool_item) { #define H_gtk_tool_item_retrieve_proxy_menu_item "GtkWidget* gtk_tool_item_retrieve_proxy_menu_item(GtkToolItem* tool_item)" Xen_check_type(Xen_is_GtkToolItem_(tool_item), tool_item, 1, "gtk_tool_item_retrieve_proxy_menu_item", "GtkToolItem*"); return(C_to_Xen_GtkWidget_(gtk_tool_item_retrieve_proxy_menu_item(Xen_to_C_GtkToolItem_(tool_item)))); } static Xen gxg_gtk_tool_item_get_proxy_menu_item(Xen tool_item, Xen menu_item_id) { #define H_gtk_tool_item_get_proxy_menu_item "GtkWidget* gtk_tool_item_get_proxy_menu_item(GtkToolItem* tool_item, \ gchar* menu_item_id)" Xen_check_type(Xen_is_GtkToolItem_(tool_item), tool_item, 1, "gtk_tool_item_get_proxy_menu_item", "GtkToolItem*"); Xen_check_type(Xen_is_gchar_(menu_item_id), menu_item_id, 2, "gtk_tool_item_get_proxy_menu_item", "gchar*"); return(C_to_Xen_GtkWidget_(gtk_tool_item_get_proxy_menu_item(Xen_to_C_GtkToolItem_(tool_item), Xen_to_C_gchar_(menu_item_id)))); } static Xen gxg_gtk_tool_item_set_proxy_menu_item(Xen tool_item, Xen menu_item_id, Xen menu_item) { #define H_gtk_tool_item_set_proxy_menu_item "void gtk_tool_item_set_proxy_menu_item(GtkToolItem* tool_item, \ gchar* menu_item_id, GtkWidget* menu_item)" Xen_check_type(Xen_is_GtkToolItem_(tool_item) || Xen_is_false(tool_item), tool_item, 1, "gtk_tool_item_set_proxy_menu_item", "GtkToolItem*"); Xen_check_type(Xen_is_gchar_(menu_item_id), menu_item_id, 2, "gtk_tool_item_set_proxy_menu_item", "gchar*"); Xen_check_type(Xen_is_GtkWidget_(menu_item) || Xen_is_false(menu_item), menu_item, 3, "gtk_tool_item_set_proxy_menu_item", "GtkWidget*"); gtk_tool_item_set_proxy_menu_item(Xen_to_C_GtkToolItem_(tool_item), Xen_to_C_gchar_(menu_item_id), Xen_to_C_GtkWidget_(menu_item)); return(Xen_false); } static Xen gxg_gtk_list_store_remove(Xen list_store, Xen iter) { #define H_gtk_list_store_remove "gboolean gtk_list_store_remove(GtkListStore* list_store, GtkTreeIter* iter)" Xen_check_type(Xen_is_GtkListStore_(list_store), list_store, 1, "gtk_list_store_remove", "GtkListStore*"); Xen_check_type(Xen_is_GtkTreeIter_(iter), iter, 2, "gtk_list_store_remove", "GtkTreeIter*"); return(C_to_Xen_gboolean(gtk_list_store_remove(Xen_to_C_GtkListStore_(list_store), Xen_to_C_GtkTreeIter_(iter)))); } static Xen gxg_gdk_display_set_double_click_distance(Xen display, Xen distance) { #define H_gdk_display_set_double_click_distance "void gdk_display_set_double_click_distance(GdkDisplay* display, \ guint distance)" Xen_check_type(Xen_is_GdkDisplay_(display), display, 1, "gdk_display_set_double_click_distance", "GdkDisplay*"); Xen_check_type(Xen_is_guint(distance), distance, 2, "gdk_display_set_double_click_distance", "guint"); gdk_display_set_double_click_distance(Xen_to_C_GdkDisplay_(display), Xen_to_C_guint(distance)); return(Xen_false); } static Xen gxg_gdk_display_get_default_group(Xen display) { #define H_gdk_display_get_default_group "GdkWindow* gdk_display_get_default_group(GdkDisplay* display)" Xen_check_type(Xen_is_GdkDisplay_(display), display, 1, "gdk_display_get_default_group", "GdkDisplay*"); return(C_to_Xen_GdkWindow_(gdk_display_get_default_group(Xen_to_C_GdkDisplay_(display)))); } static Xen gxg_gdk_window_get_group(Xen window) { #define H_gdk_window_get_group "GdkWindow* gdk_window_get_group(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_get_group", "GdkWindow*"); return(C_to_Xen_GdkWindow_(gdk_window_get_group(Xen_to_C_GdkWindow_(window)))); } static Xen gxg_gtk_cell_layout_reorder(Xen cell_layout, Xen cell, Xen position) { #define H_gtk_cell_layout_reorder "void gtk_cell_layout_reorder(GtkCellLayout* cell_layout, GtkCellRenderer* cell, \ gint position)" Xen_check_type(Xen_is_GtkCellLayout_(cell_layout), cell_layout, 1, "gtk_cell_layout_reorder", "GtkCellLayout*"); Xen_check_type(Xen_is_GtkCellRenderer_(cell), cell, 2, "gtk_cell_layout_reorder", "GtkCellRenderer*"); Xen_check_type(Xen_is_gint(position), position, 3, "gtk_cell_layout_reorder", "gint"); gtk_cell_layout_reorder(Xen_to_C_GtkCellLayout_(cell_layout), Xen_to_C_GtkCellRenderer_(cell), Xen_to_C_gint(position)); return(Xen_false); } static Xen gxg_gtk_clipboard_request_targets(Xen clipboard, Xen func, Xen func_info) { #define H_gtk_clipboard_request_targets "void gtk_clipboard_request_targets(GtkClipboard* clipboard, \ GtkClipboardTargetsReceivedFunc func, lambda_data func_info)" Xen_check_type(Xen_is_GtkClipboard_(clipboard), clipboard, 1, "gtk_clipboard_request_targets", "GtkClipboard*"); Xen_check_type(Xen_is_GtkClipboardTargetsReceivedFunc(func), func, 2, "gtk_clipboard_request_targets", "GtkClipboardTargetsReceivedFunc"); if (!Xen_is_bound(func_info)) func_info = Xen_false; else Xen_check_type(Xen_is_lambda_data(func_info), func_info, 3, "gtk_clipboard_request_targets", "lambda_data"); { int loc; Xen gxg_ptr = Xen_list_5(func, func_info, Xen_false, Xen_false, Xen_false); loc = xm_protect(gxg_ptr); Xen_list_set(gxg_ptr, 2, C_int_to_Xen_integer(loc)); gtk_clipboard_request_targets(Xen_to_C_GtkClipboard_(clipboard), Xen_to_C_GtkClipboardTargetsReceivedFunc(func), Xen_to_C_lambda_data(func_info)); xm_unprotect_at(loc); return(Xen_false); } } static Xen gxg_gtk_clipboard_wait_for_targets(Xen clipboard, Xen ignore_targets, Xen ignore_n_targets) { #define H_gtk_clipboard_wait_for_targets "gboolean gtk_clipboard_wait_for_targets(GtkClipboard* clipboard, \ GdkAtom** [targets], gint* [n_targets])" GdkAtom* ref_targets = NULL; gint ref_n_targets; Xen_check_type(Xen_is_GtkClipboard_(clipboard), clipboard, 1, "gtk_clipboard_wait_for_targets", "GtkClipboard*"); { Xen result; result = C_to_Xen_gboolean(gtk_clipboard_wait_for_targets(Xen_to_C_GtkClipboard_(clipboard), &ref_targets, &ref_n_targets)); return(Xen_list_3(result, C_to_Xen_GdkAtom_(ref_targets), C_to_Xen_gint(ref_n_targets))); } } static Xen gxg_gtk_menu_shell_cancel(Xen menu_shell) { #define H_gtk_menu_shell_cancel "void gtk_menu_shell_cancel(GtkMenuShell* menu_shell)" Xen_check_type(Xen_is_GtkMenuShell_(menu_shell), menu_shell, 1, "gtk_menu_shell_cancel", "GtkMenuShell*"); gtk_menu_shell_cancel(Xen_to_C_GtkMenuShell_(menu_shell)); return(Xen_false); } static Xen gxg_gtk_paned_get_child1(Xen paned) { #define H_gtk_paned_get_child1 "GtkWidget* gtk_paned_get_child1(GtkPaned* paned)" Xen_check_type(Xen_is_GtkPaned_(paned), paned, 1, "gtk_paned_get_child1", "GtkPaned*"); return(C_to_Xen_GtkWidget_(gtk_paned_get_child1(Xen_to_C_GtkPaned_(paned)))); } static Xen gxg_gtk_paned_get_child2(Xen paned) { #define H_gtk_paned_get_child2 "GtkWidget* gtk_paned_get_child2(GtkPaned* paned)" Xen_check_type(Xen_is_GtkPaned_(paned), paned, 1, "gtk_paned_get_child2", "GtkPaned*"); return(C_to_Xen_GtkWidget_(gtk_paned_get_child2(Xen_to_C_GtkPaned_(paned)))); } static Xen gxg_gtk_window_set_accept_focus(Xen window, Xen setting) { #define H_gtk_window_set_accept_focus "void gtk_window_set_accept_focus(GtkWindow* window, gboolean setting)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_set_accept_focus", "GtkWindow*"); Xen_check_type(Xen_is_gboolean(setting), setting, 2, "gtk_window_set_accept_focus", "gboolean"); gtk_window_set_accept_focus(Xen_to_C_GtkWindow_(window), Xen_to_C_gboolean(setting)); return(Xen_false); } static Xen gxg_gtk_window_get_accept_focus(Xen window) { #define H_gtk_window_get_accept_focus "gboolean gtk_window_get_accept_focus(GtkWindow* window)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_get_accept_focus", "GtkWindow*"); return(C_to_Xen_gboolean(gtk_window_get_accept_focus(Xen_to_C_GtkWindow_(window)))); } static Xen gxg_g_list_nth_data(Xen list, Xen n) { #define H_g_list_nth_data "gpointer g_list_nth_data(GList* list, guint n)" Xen_check_type(Xen_is_GList_(list), list, 1, "g_list_nth_data", "GList*"); Xen_check_type(Xen_is_guint(n), n, 2, "g_list_nth_data", "guint"); return(C_to_Xen_gpointer(g_list_nth_data(Xen_to_C_GList_(list), Xen_to_C_guint(n)))); } static Xen gxg_gtk_accel_map_get(void) { #define H_gtk_accel_map_get "GtkAccelMap* gtk_accel_map_get( void)" return(C_to_Xen_GtkAccelMap_(gtk_accel_map_get())); } static Xen gxg_gtk_combo_box_popup(Xen combo_box) { #define H_gtk_combo_box_popup "void gtk_combo_box_popup(GtkComboBox* combo_box)" Xen_check_type(Xen_is_GtkComboBox_(combo_box), combo_box, 1, "gtk_combo_box_popup", "GtkComboBox*"); gtk_combo_box_popup(Xen_to_C_GtkComboBox_(combo_box)); return(Xen_false); } static Xen gxg_gtk_combo_box_popdown(Xen combo_box) { #define H_gtk_combo_box_popdown "void gtk_combo_box_popdown(GtkComboBox* combo_box)" Xen_check_type(Xen_is_GtkComboBox_(combo_box), combo_box, 1, "gtk_combo_box_popdown", "GtkComboBox*"); gtk_combo_box_popdown(Xen_to_C_GtkComboBox_(combo_box)); return(Xen_false); } static Xen gxg_gtk_radio_menu_item_new_from_widget(Xen group) { #define H_gtk_radio_menu_item_new_from_widget "GtkWidget* gtk_radio_menu_item_new_from_widget(GtkRadioMenuItem* group)" Xen_check_type(Xen_is_GtkRadioMenuItem_(group), group, 1, "gtk_radio_menu_item_new_from_widget", "GtkRadioMenuItem*"); return(C_to_Xen_GtkWidget_(gtk_radio_menu_item_new_from_widget(Xen_to_C_GtkRadioMenuItem_(group)))); } static Xen gxg_gtk_radio_menu_item_new_with_mnemonic_from_widget(Xen group, Xen label) { #define H_gtk_radio_menu_item_new_with_mnemonic_from_widget "GtkWidget* gtk_radio_menu_item_new_with_mnemonic_from_widget(GtkRadioMenuItem* group, \ gchar* label)" Xen_check_type(Xen_is_GtkRadioMenuItem_(group), group, 1, "gtk_radio_menu_item_new_with_mnemonic_from_widget", "GtkRadioMenuItem*"); Xen_check_type(Xen_is_gchar_(label), label, 2, "gtk_radio_menu_item_new_with_mnemonic_from_widget", "gchar*"); return(C_to_Xen_GtkWidget_(gtk_radio_menu_item_new_with_mnemonic_from_widget(Xen_to_C_GtkRadioMenuItem_(group), Xen_to_C_gchar_(label)))); } static Xen gxg_gtk_radio_menu_item_new_with_label_from_widget(Xen group, Xen label) { #define H_gtk_radio_menu_item_new_with_label_from_widget "GtkWidget* gtk_radio_menu_item_new_with_label_from_widget(GtkRadioMenuItem* group, \ gchar* label)" Xen_check_type(Xen_is_GtkRadioMenuItem_(group), group, 1, "gtk_radio_menu_item_new_with_label_from_widget", "GtkRadioMenuItem*"); Xen_check_type(Xen_is_gchar_(label), label, 2, "gtk_radio_menu_item_new_with_label_from_widget", "gchar*"); return(C_to_Xen_GtkWidget_(gtk_radio_menu_item_new_with_label_from_widget(Xen_to_C_GtkRadioMenuItem_(group), Xen_to_C_gchar_(label)))); } static Xen gxg_gtk_scale_get_layout(Xen scale) { #define H_gtk_scale_get_layout "PangoLayout* gtk_scale_get_layout(GtkScale* scale)" Xen_check_type(Xen_is_GtkScale_(scale), scale, 1, "gtk_scale_get_layout", "GtkScale*"); return(C_to_Xen_PangoLayout_(gtk_scale_get_layout(Xen_to_C_GtkScale_(scale)))); } static Xen gxg_gtk_scale_get_layout_offsets(Xen scale, Xen ignore_x, Xen ignore_y) { #define H_gtk_scale_get_layout_offsets "void gtk_scale_get_layout_offsets(GtkScale* scale, gint* [x], \ gint* [y])" gint ref_x; gint ref_y; Xen_check_type(Xen_is_GtkScale_(scale), scale, 1, "gtk_scale_get_layout_offsets", "GtkScale*"); gtk_scale_get_layout_offsets(Xen_to_C_GtkScale_(scale), &ref_x, &ref_y); return(Xen_list_2(C_to_Xen_gint(ref_x), C_to_Xen_gint(ref_y))); } static Xen gxg_gtk_drag_source_get_target_list(Xen widget) { #define H_gtk_drag_source_get_target_list "GtkTargetList* gtk_drag_source_get_target_list(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_drag_source_get_target_list", "GtkWidget*"); return(C_to_Xen_GtkTargetList_(gtk_drag_source_get_target_list(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_drag_source_set_target_list(Xen widget, Xen target_list) { #define H_gtk_drag_source_set_target_list "void gtk_drag_source_set_target_list(GtkWidget* widget, \ GtkTargetList* target_list)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_drag_source_set_target_list", "GtkWidget*"); Xen_check_type(Xen_is_GtkTargetList_(target_list) || Xen_is_false(target_list), target_list, 2, "gtk_drag_source_set_target_list", "GtkTargetList*"); gtk_drag_source_set_target_list(Xen_to_C_GtkWidget_(widget), Xen_to_C_GtkTargetList_(target_list)); return(Xen_false); } static Xen gxg_gtk_entry_set_alignment(Xen entry, Xen xalign) { #define H_gtk_entry_set_alignment "void gtk_entry_set_alignment(GtkEntry* entry, gfloat xalign)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_set_alignment", "GtkEntry*"); Xen_check_type(Xen_is_gfloat(xalign), xalign, 2, "gtk_entry_set_alignment", "gfloat"); gtk_entry_set_alignment(Xen_to_C_GtkEntry_(entry), Xen_to_C_gfloat(xalign)); return(Xen_false); } static Xen gxg_gtk_entry_get_alignment(Xen entry) { #define H_gtk_entry_get_alignment "gfloat gtk_entry_get_alignment(GtkEntry* entry)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_get_alignment", "GtkEntry*"); return(C_to_Xen_gfloat(gtk_entry_get_alignment(Xen_to_C_GtkEntry_(entry)))); } static Xen gxg_gtk_file_chooser_set_use_preview_label(Xen chooser, Xen use_label) { #define H_gtk_file_chooser_set_use_preview_label "void gtk_file_chooser_set_use_preview_label(GtkFileChooser* chooser, \ gboolean use_label)" Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_set_use_preview_label", "GtkFileChooser*"); Xen_check_type(Xen_is_gboolean(use_label), use_label, 2, "gtk_file_chooser_set_use_preview_label", "gboolean"); gtk_file_chooser_set_use_preview_label(Xen_to_C_GtkFileChooser_(chooser), Xen_to_C_gboolean(use_label)); return(Xen_false); } static Xen gxg_gtk_file_chooser_get_use_preview_label(Xen chooser) { #define H_gtk_file_chooser_get_use_preview_label "gboolean gtk_file_chooser_get_use_preview_label(GtkFileChooser* chooser)" Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_get_use_preview_label", "GtkFileChooser*"); return(C_to_Xen_gboolean(gtk_file_chooser_get_use_preview_label(Xen_to_C_GtkFileChooser_(chooser)))); } static Xen gxg_gtk_widget_list_mnemonic_labels(Xen widget) { #define H_gtk_widget_list_mnemonic_labels "GList* gtk_widget_list_mnemonic_labels(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_list_mnemonic_labels", "GtkWidget*"); return(C_to_Xen_GList_(gtk_widget_list_mnemonic_labels(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_add_mnemonic_label(Xen widget, Xen label) { #define H_gtk_widget_add_mnemonic_label "void gtk_widget_add_mnemonic_label(GtkWidget* widget, GtkWidget* label)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_add_mnemonic_label", "GtkWidget*"); Xen_check_type(Xen_is_GtkWidget_(label), label, 2, "gtk_widget_add_mnemonic_label", "GtkWidget*"); gtk_widget_add_mnemonic_label(Xen_to_C_GtkWidget_(widget), Xen_to_C_GtkWidget_(label)); return(Xen_false); } static Xen gxg_gtk_widget_remove_mnemonic_label(Xen widget, Xen label) { #define H_gtk_widget_remove_mnemonic_label "void gtk_widget_remove_mnemonic_label(GtkWidget* widget, \ GtkWidget* label)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_remove_mnemonic_label", "GtkWidget*"); Xen_check_type(Xen_is_GtkWidget_(label), label, 2, "gtk_widget_remove_mnemonic_label", "GtkWidget*"); gtk_widget_remove_mnemonic_label(Xen_to_C_GtkWidget_(widget), Xen_to_C_GtkWidget_(label)); return(Xen_false); } static Xen gxg_gtk_window_activate_key(Xen window, Xen event) { #define H_gtk_window_activate_key "gboolean gtk_window_activate_key(GtkWindow* window, GdkEventKey* event)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_activate_key", "GtkWindow*"); Xen_check_type(Xen_is_GdkEventKey_(event), event, 2, "gtk_window_activate_key", "GdkEventKey*"); return(C_to_Xen_gboolean(gtk_window_activate_key(Xen_to_C_GtkWindow_(window), Xen_to_C_GdkEventKey_(event)))); } static Xen gxg_gtk_window_propagate_key_event(Xen window, Xen event) { #define H_gtk_window_propagate_key_event "gboolean gtk_window_propagate_key_event(GtkWindow* window, \ GdkEventKey* event)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_propagate_key_event", "GtkWindow*"); Xen_check_type(Xen_is_GdkEventKey_(event), event, 2, "gtk_window_propagate_key_event", "GdkEventKey*"); return(C_to_Xen_gboolean(gtk_window_propagate_key_event(Xen_to_C_GtkWindow_(window), Xen_to_C_GdkEventKey_(event)))); } static Xen gxg_g_quark_from_string(Xen string) { #define H_g_quark_from_string "GQuark g_quark_from_string(gchar* string)" Xen_check_type(Xen_is_gchar_(string), string, 1, "g_quark_from_string", "gchar*"); return(C_to_Xen_GQuark(g_quark_from_string(Xen_to_C_gchar_(string)))); } static Xen gxg_g_quark_to_string(Xen quark) { #define H_g_quark_to_string "gchar* g_quark_to_string(GQuark quark)" Xen_check_type(Xen_is_GQuark(quark), quark, 1, "g_quark_to_string", "GQuark"); return(C_to_Xen_gchar_(g_quark_to_string(Xen_to_C_GQuark(quark)))); } static Xen gxg_gtk_cell_view_new(void) { #define H_gtk_cell_view_new "GtkWidget* gtk_cell_view_new( void)" return(C_to_Xen_GtkWidget_(gtk_cell_view_new())); } static Xen gxg_gtk_cell_view_new_with_text(Xen text) { #define H_gtk_cell_view_new_with_text "GtkWidget* gtk_cell_view_new_with_text(gchar* text)" Xen_check_type(Xen_is_gchar_(text), text, 1, "gtk_cell_view_new_with_text", "gchar*"); return(C_to_Xen_GtkWidget_(gtk_cell_view_new_with_text(Xen_to_C_gchar_(text)))); } static Xen gxg_gtk_cell_view_new_with_markup(Xen markup) { #define H_gtk_cell_view_new_with_markup "GtkWidget* gtk_cell_view_new_with_markup(gchar* markup)" Xen_check_type(Xen_is_gchar_(markup), markup, 1, "gtk_cell_view_new_with_markup", "gchar*"); return(C_to_Xen_GtkWidget_(gtk_cell_view_new_with_markup(Xen_to_C_gchar_(markup)))); } static Xen gxg_gtk_cell_view_new_with_pixbuf(Xen pixbuf) { #define H_gtk_cell_view_new_with_pixbuf "GtkWidget* gtk_cell_view_new_with_pixbuf(GdkPixbuf* pixbuf)" Xen_check_type(Xen_is_GdkPixbuf_(pixbuf), pixbuf, 1, "gtk_cell_view_new_with_pixbuf", "GdkPixbuf*"); return(C_to_Xen_GtkWidget_(gtk_cell_view_new_with_pixbuf(Xen_to_C_GdkPixbuf_(pixbuf)))); } static Xen gxg_gtk_cell_view_set_model(Xen cell_view, Xen model) { #define H_gtk_cell_view_set_model "void gtk_cell_view_set_model(GtkCellView* cell_view, GtkTreeModel* model)" Xen_check_type(Xen_is_GtkCellView_(cell_view), cell_view, 1, "gtk_cell_view_set_model", "GtkCellView*"); Xen_check_type(Xen_is_GtkTreeModel_(model) || Xen_is_false(model), model, 2, "gtk_cell_view_set_model", "GtkTreeModel*"); gtk_cell_view_set_model(Xen_to_C_GtkCellView_(cell_view), Xen_to_C_GtkTreeModel_(model)); return(Xen_false); } static Xen gxg_gtk_cell_view_set_displayed_row(Xen cell_view, Xen path) { #define H_gtk_cell_view_set_displayed_row "void gtk_cell_view_set_displayed_row(GtkCellView* cell_view, \ GtkTreePath* path)" Xen_check_type(Xen_is_GtkCellView_(cell_view), cell_view, 1, "gtk_cell_view_set_displayed_row", "GtkCellView*"); Xen_check_type(Xen_is_GtkTreePath_(path), path, 2, "gtk_cell_view_set_displayed_row", "GtkTreePath*"); gtk_cell_view_set_displayed_row(Xen_to_C_GtkCellView_(cell_view), Xen_to_C_GtkTreePath_(path)); return(Xen_false); } static Xen gxg_gtk_cell_view_get_displayed_row(Xen cell_view) { #define H_gtk_cell_view_get_displayed_row "GtkTreePath* gtk_cell_view_get_displayed_row(GtkCellView* cell_view)" Xen_check_type(Xen_is_GtkCellView_(cell_view), cell_view, 1, "gtk_cell_view_get_displayed_row", "GtkCellView*"); return(C_to_Xen_GtkTreePath_(gtk_cell_view_get_displayed_row(Xen_to_C_GtkCellView_(cell_view)))); } static Xen gxg_gtk_combo_box_get_wrap_width(Xen combo_box) { #define H_gtk_combo_box_get_wrap_width "gint gtk_combo_box_get_wrap_width(GtkComboBox* combo_box)" Xen_check_type(Xen_is_GtkComboBox_(combo_box), combo_box, 1, "gtk_combo_box_get_wrap_width", "GtkComboBox*"); return(C_to_Xen_gint(gtk_combo_box_get_wrap_width(Xen_to_C_GtkComboBox_(combo_box)))); } static Xen gxg_gtk_combo_box_get_row_span_column(Xen combo_box) { #define H_gtk_combo_box_get_row_span_column "gint gtk_combo_box_get_row_span_column(GtkComboBox* combo_box)" Xen_check_type(Xen_is_GtkComboBox_(combo_box), combo_box, 1, "gtk_combo_box_get_row_span_column", "GtkComboBox*"); return(C_to_Xen_gint(gtk_combo_box_get_row_span_column(Xen_to_C_GtkComboBox_(combo_box)))); } static Xen gxg_gtk_combo_box_get_column_span_column(Xen combo_box) { #define H_gtk_combo_box_get_column_span_column "gint gtk_combo_box_get_column_span_column(GtkComboBox* combo_box)" Xen_check_type(Xen_is_GtkComboBox_(combo_box), combo_box, 1, "gtk_combo_box_get_column_span_column", "GtkComboBox*"); return(C_to_Xen_gint(gtk_combo_box_get_column_span_column(Xen_to_C_GtkComboBox_(combo_box)))); } static Xen gxg_gtk_drag_dest_add_text_targets(Xen widget) { #define H_gtk_drag_dest_add_text_targets "void gtk_drag_dest_add_text_targets(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_drag_dest_add_text_targets", "GtkWidget*"); gtk_drag_dest_add_text_targets(Xen_to_C_GtkWidget_(widget)); return(Xen_false); } static Xen gxg_gtk_drag_source_add_text_targets(Xen widget) { #define H_gtk_drag_source_add_text_targets "void gtk_drag_source_add_text_targets(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_drag_source_add_text_targets", "GtkWidget*"); gtk_drag_source_add_text_targets(Xen_to_C_GtkWidget_(widget)); return(Xen_false); } static Xen gxg_gtk_entry_completion_insert_prefix(Xen completion) { #define H_gtk_entry_completion_insert_prefix "void gtk_entry_completion_insert_prefix(GtkEntryCompletion* completion)" Xen_check_type(Xen_is_GtkEntryCompletion_(completion), completion, 1, "gtk_entry_completion_insert_prefix", "GtkEntryCompletion*"); gtk_entry_completion_insert_prefix(Xen_to_C_GtkEntryCompletion_(completion)); return(Xen_false); } static Xen gxg_gtk_entry_completion_set_inline_completion(Xen completion, Xen inline_completion) { #define H_gtk_entry_completion_set_inline_completion "void gtk_entry_completion_set_inline_completion(GtkEntryCompletion* completion, \ gboolean inline_completion)" Xen_check_type(Xen_is_GtkEntryCompletion_(completion), completion, 1, "gtk_entry_completion_set_inline_completion", "GtkEntryCompletion*"); Xen_check_type(Xen_is_gboolean(inline_completion), inline_completion, 2, "gtk_entry_completion_set_inline_completion", "gboolean"); gtk_entry_completion_set_inline_completion(Xen_to_C_GtkEntryCompletion_(completion), Xen_to_C_gboolean(inline_completion)); return(Xen_false); } static Xen gxg_gtk_entry_completion_get_inline_completion(Xen completion) { #define H_gtk_entry_completion_get_inline_completion "gboolean gtk_entry_completion_get_inline_completion(GtkEntryCompletion* completion)" Xen_check_type(Xen_is_GtkEntryCompletion_(completion), completion, 1, "gtk_entry_completion_get_inline_completion", "GtkEntryCompletion*"); return(C_to_Xen_gboolean(gtk_entry_completion_get_inline_completion(Xen_to_C_GtkEntryCompletion_(completion)))); } static Xen gxg_gtk_entry_completion_set_popup_completion(Xen completion, Xen popup_completion) { #define H_gtk_entry_completion_set_popup_completion "void gtk_entry_completion_set_popup_completion(GtkEntryCompletion* completion, \ gboolean popup_completion)" Xen_check_type(Xen_is_GtkEntryCompletion_(completion), completion, 1, "gtk_entry_completion_set_popup_completion", "GtkEntryCompletion*"); Xen_check_type(Xen_is_gboolean(popup_completion), popup_completion, 2, "gtk_entry_completion_set_popup_completion", "gboolean"); gtk_entry_completion_set_popup_completion(Xen_to_C_GtkEntryCompletion_(completion), Xen_to_C_gboolean(popup_completion)); return(Xen_false); } static Xen gxg_gtk_entry_completion_get_popup_completion(Xen completion) { #define H_gtk_entry_completion_get_popup_completion "gboolean gtk_entry_completion_get_popup_completion(GtkEntryCompletion* completion)" Xen_check_type(Xen_is_GtkEntryCompletion_(completion), completion, 1, "gtk_entry_completion_get_popup_completion", "GtkEntryCompletion*"); return(C_to_Xen_gboolean(gtk_entry_completion_get_popup_completion(Xen_to_C_GtkEntryCompletion_(completion)))); } static Xen gxg_gtk_entry_completion_get_text_column(Xen completion) { #define H_gtk_entry_completion_get_text_column "gint gtk_entry_completion_get_text_column(GtkEntryCompletion* completion)" Xen_check_type(Xen_is_GtkEntryCompletion_(completion), completion, 1, "gtk_entry_completion_get_text_column", "GtkEntryCompletion*"); return(C_to_Xen_gint(gtk_entry_completion_get_text_column(Xen_to_C_GtkEntryCompletion_(completion)))); } static Xen gxg_gtk_icon_theme_get_icon_sizes(Xen icon_theme, Xen icon_name) { #define H_gtk_icon_theme_get_icon_sizes "gint* gtk_icon_theme_get_icon_sizes(GtkIconTheme* icon_theme, \ gchar* icon_name)" Xen_check_type(Xen_is_GtkIconTheme_(icon_theme), icon_theme, 1, "gtk_icon_theme_get_icon_sizes", "GtkIconTheme*"); Xen_check_type(Xen_is_gchar_(icon_name), icon_name, 2, "gtk_icon_theme_get_icon_sizes", "gchar*"); return(C_to_Xen_gint_(gtk_icon_theme_get_icon_sizes(Xen_to_C_GtkIconTheme_(icon_theme), Xen_to_C_gchar_(icon_name)))); } static Xen gxg_gtk_menu_get_for_attach_widget(Xen widget ) { #define H_gtk_menu_get_for_attach_widget "GList* gtk_menu_get_for_attach_widget(GtkWidget* widget, \ )" Xen_check_type(Xen_is_GtkWidget_(widget ), widget , 1, "gtk_menu_get_for_attach_widget", "GtkWidget*"); return(C_to_Xen_GList_(gtk_menu_get_for_attach_widget(Xen_to_C_GtkWidget_(widget )))); } static Xen gxg_gtk_tree_view_set_fixed_height_mode(Xen tree_view, Xen enable) { #define H_gtk_tree_view_set_fixed_height_mode "void gtk_tree_view_set_fixed_height_mode(GtkTreeView* tree_view, \ gboolean enable)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_set_fixed_height_mode", "GtkTreeView*"); Xen_check_type(Xen_is_gboolean(enable), enable, 2, "gtk_tree_view_set_fixed_height_mode", "gboolean"); gtk_tree_view_set_fixed_height_mode(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_gboolean(enable)); return(Xen_false); } static Xen gxg_gtk_tree_view_get_fixed_height_mode(Xen tree_view) { #define H_gtk_tree_view_get_fixed_height_mode "gboolean gtk_tree_view_get_fixed_height_mode(GtkTreeView* tree_view)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_get_fixed_height_mode", "GtkTreeView*"); return(C_to_Xen_gboolean(gtk_tree_view_get_fixed_height_mode(Xen_to_C_GtkTreeView_(tree_view)))); } static Xen gxg_gtk_tree_view_set_hover_selection(Xen tree_view, Xen hover) { #define H_gtk_tree_view_set_hover_selection "void gtk_tree_view_set_hover_selection(GtkTreeView* tree_view, \ gboolean hover)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_set_hover_selection", "GtkTreeView*"); Xen_check_type(Xen_is_gboolean(hover), hover, 2, "gtk_tree_view_set_hover_selection", "gboolean"); gtk_tree_view_set_hover_selection(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_gboolean(hover)); return(Xen_false); } static Xen gxg_gtk_tree_view_get_hover_selection(Xen tree_view) { #define H_gtk_tree_view_get_hover_selection "gboolean gtk_tree_view_get_hover_selection(GtkTreeView* tree_view)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_get_hover_selection", "GtkTreeView*"); return(C_to_Xen_gboolean(gtk_tree_view_get_hover_selection(Xen_to_C_GtkTreeView_(tree_view)))); } static Xen gxg_gtk_tree_view_set_row_separator_func(Xen tree_view, Xen func, Xen func_info, Xen destroy) { #define H_gtk_tree_view_set_row_separator_func "void gtk_tree_view_set_row_separator_func(GtkTreeView* tree_view, \ GtkTreeViewRowSeparatorFunc func, lambda_data func_info, GtkDestroyNotify destroy)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_set_row_separator_func", "GtkTreeView*"); Xen_check_type(Xen_is_GtkTreeViewRowSeparatorFunc(func), func, 2, "gtk_tree_view_set_row_separator_func", "GtkTreeViewRowSeparatorFunc"); Xen_check_type(Xen_is_lambda_data(func_info), func_info, 3, "gtk_tree_view_set_row_separator_func", "lambda_data"); Xen_check_type(Xen_is_GtkDestroyNotify(destroy), destroy, 4, "gtk_tree_view_set_row_separator_func", "GtkDestroyNotify"); { Xen gxg_ptr = Xen_list_5(func, func_info, Xen_false, Xen_false, Xen_false); xm_protect(gxg_ptr); Xen_list_set(gxg_ptr, 3, destroy); gtk_tree_view_set_row_separator_func(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_GtkTreeViewRowSeparatorFunc(func), Xen_to_C_lambda_data(func_info), Xen_to_C_GtkDestroyNotify(destroy)); return(Xen_false); } } static Xen gxg_gtk_window_set_focus_on_map(Xen window, Xen setting) { #define H_gtk_window_set_focus_on_map "void gtk_window_set_focus_on_map(GtkWindow* window, gboolean setting)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_set_focus_on_map", "GtkWindow*"); Xen_check_type(Xen_is_gboolean(setting), setting, 2, "gtk_window_set_focus_on_map", "gboolean"); gtk_window_set_focus_on_map(Xen_to_C_GtkWindow_(window), Xen_to_C_gboolean(setting)); return(Xen_false); } static Xen gxg_gtk_window_get_focus_on_map(Xen window) { #define H_gtk_window_get_focus_on_map "gboolean gtk_window_get_focus_on_map(GtkWindow* window)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_get_focus_on_map", "GtkWindow*"); return(C_to_Xen_gboolean(gtk_window_get_focus_on_map(Xen_to_C_GtkWindow_(window)))); } static Xen gxg_gtk_window_set_icon_name(Xen window, Xen name) { #define H_gtk_window_set_icon_name "void gtk_window_set_icon_name(GtkWindow* window, gchar* name)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_set_icon_name", "GtkWindow*"); Xen_check_type(Xen_is_gchar_(name), name, 2, "gtk_window_set_icon_name", "gchar*"); gtk_window_set_icon_name(Xen_to_C_GtkWindow_(window), Xen_to_C_gchar_(name)); return(Xen_false); } static Xen gxg_gtk_window_get_icon_name(Xen window) { #define H_gtk_window_get_icon_name "gchar* gtk_window_get_icon_name(GtkWindow* window)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_get_icon_name", "GtkWindow*"); return(C_to_Xen_gchar_(gtk_window_get_icon_name(Xen_to_C_GtkWindow_(window)))); } static Xen gxg_gtk_window_set_default_icon_name(Xen name) { #define H_gtk_window_set_default_icon_name "void gtk_window_set_default_icon_name(gchar* name)" Xen_check_type(Xen_is_gchar_(name), name, 1, "gtk_window_set_default_icon_name", "gchar*"); gtk_window_set_default_icon_name(Xen_to_C_gchar_(name)); return(Xen_false); } static Xen gxg_gtk_about_dialog_new(void) { #define H_gtk_about_dialog_new "GtkWidget* gtk_about_dialog_new( void)" return(C_to_Xen_GtkWidget_(gtk_about_dialog_new())); } static Xen gxg_gtk_about_dialog_get_version(Xen about) { #define H_gtk_about_dialog_get_version "gchar* gtk_about_dialog_get_version(GtkAboutDialog* about)" Xen_check_type(Xen_is_GtkAboutDialog_(about), about, 1, "gtk_about_dialog_get_version", "GtkAboutDialog*"); return(C_to_Xen_gchar_(gtk_about_dialog_get_version(Xen_to_C_GtkAboutDialog_(about)))); } static Xen gxg_gtk_about_dialog_set_version(Xen about, Xen version) { #define H_gtk_about_dialog_set_version "void gtk_about_dialog_set_version(GtkAboutDialog* about, gchar* version)" Xen_check_type(Xen_is_GtkAboutDialog_(about), about, 1, "gtk_about_dialog_set_version", "GtkAboutDialog*"); Xen_check_type(Xen_is_gchar_(version), version, 2, "gtk_about_dialog_set_version", "gchar*"); gtk_about_dialog_set_version(Xen_to_C_GtkAboutDialog_(about), Xen_to_C_gchar_(version)); return(Xen_false); } static Xen gxg_gtk_about_dialog_get_copyright(Xen about) { #define H_gtk_about_dialog_get_copyright "gchar* gtk_about_dialog_get_copyright(GtkAboutDialog* about)" Xen_check_type(Xen_is_GtkAboutDialog_(about), about, 1, "gtk_about_dialog_get_copyright", "GtkAboutDialog*"); return(C_to_Xen_gchar_(gtk_about_dialog_get_copyright(Xen_to_C_GtkAboutDialog_(about)))); } static Xen gxg_gtk_about_dialog_set_copyright(Xen about, Xen copyright) { #define H_gtk_about_dialog_set_copyright "void gtk_about_dialog_set_copyright(GtkAboutDialog* about, \ gchar* copyright)" Xen_check_type(Xen_is_GtkAboutDialog_(about), about, 1, "gtk_about_dialog_set_copyright", "GtkAboutDialog*"); Xen_check_type(Xen_is_gchar_(copyright), copyright, 2, "gtk_about_dialog_set_copyright", "gchar*"); gtk_about_dialog_set_copyright(Xen_to_C_GtkAboutDialog_(about), Xen_to_C_gchar_(copyright)); return(Xen_false); } static Xen gxg_gtk_about_dialog_get_comments(Xen about) { #define H_gtk_about_dialog_get_comments "gchar* gtk_about_dialog_get_comments(GtkAboutDialog* about)" Xen_check_type(Xen_is_GtkAboutDialog_(about), about, 1, "gtk_about_dialog_get_comments", "GtkAboutDialog*"); return(C_to_Xen_gchar_(gtk_about_dialog_get_comments(Xen_to_C_GtkAboutDialog_(about)))); } static Xen gxg_gtk_about_dialog_set_comments(Xen about, Xen comments) { #define H_gtk_about_dialog_set_comments "void gtk_about_dialog_set_comments(GtkAboutDialog* about, \ gchar* comments)" Xen_check_type(Xen_is_GtkAboutDialog_(about), about, 1, "gtk_about_dialog_set_comments", "GtkAboutDialog*"); Xen_check_type(Xen_is_gchar_(comments), comments, 2, "gtk_about_dialog_set_comments", "gchar*"); gtk_about_dialog_set_comments(Xen_to_C_GtkAboutDialog_(about), Xen_to_C_gchar_(comments)); return(Xen_false); } static Xen gxg_gtk_about_dialog_get_website(Xen about) { #define H_gtk_about_dialog_get_website "gchar* gtk_about_dialog_get_website(GtkAboutDialog* about)" Xen_check_type(Xen_is_GtkAboutDialog_(about), about, 1, "gtk_about_dialog_get_website", "GtkAboutDialog*"); return(C_to_Xen_gchar_(gtk_about_dialog_get_website(Xen_to_C_GtkAboutDialog_(about)))); } static Xen gxg_gtk_about_dialog_set_website(Xen about, Xen website) { #define H_gtk_about_dialog_set_website "void gtk_about_dialog_set_website(GtkAboutDialog* about, gchar* website)" Xen_check_type(Xen_is_GtkAboutDialog_(about), about, 1, "gtk_about_dialog_set_website", "GtkAboutDialog*"); Xen_check_type(Xen_is_gchar_(website), website, 2, "gtk_about_dialog_set_website", "gchar*"); gtk_about_dialog_set_website(Xen_to_C_GtkAboutDialog_(about), Xen_to_C_gchar_(website)); return(Xen_false); } static Xen gxg_gtk_about_dialog_get_website_label(Xen about) { #define H_gtk_about_dialog_get_website_label "gchar* gtk_about_dialog_get_website_label(GtkAboutDialog* about)" Xen_check_type(Xen_is_GtkAboutDialog_(about), about, 1, "gtk_about_dialog_get_website_label", "GtkAboutDialog*"); return(C_to_Xen_gchar_(gtk_about_dialog_get_website_label(Xen_to_C_GtkAboutDialog_(about)))); } static Xen gxg_gtk_about_dialog_set_website_label(Xen about, Xen website_label) { #define H_gtk_about_dialog_set_website_label "void gtk_about_dialog_set_website_label(GtkAboutDialog* about, \ gchar* website_label)" Xen_check_type(Xen_is_GtkAboutDialog_(about), about, 1, "gtk_about_dialog_set_website_label", "GtkAboutDialog*"); Xen_check_type(Xen_is_gchar_(website_label), website_label, 2, "gtk_about_dialog_set_website_label", "gchar*"); gtk_about_dialog_set_website_label(Xen_to_C_GtkAboutDialog_(about), Xen_to_C_gchar_(website_label)); return(Xen_false); } static Xen gxg_gtk_about_dialog_get_authors(Xen about) { #define H_gtk_about_dialog_get_authors "gchar** gtk_about_dialog_get_authors(GtkAboutDialog* about)" Xen_check_type(Xen_is_GtkAboutDialog_(about), about, 1, "gtk_about_dialog_get_authors", "GtkAboutDialog*"); return(C_to_Xen_gchar__((gchar**)gtk_about_dialog_get_authors(Xen_to_C_GtkAboutDialog_(about)))); } static Xen gxg_gtk_about_dialog_set_authors(Xen about, Xen authors) { #define H_gtk_about_dialog_set_authors "void gtk_about_dialog_set_authors(GtkAboutDialog* about, gchar** authors)" Xen_check_type(Xen_is_GtkAboutDialog_(about), about, 1, "gtk_about_dialog_set_authors", "GtkAboutDialog*"); Xen_check_type(Xen_is_gchar__(authors), authors, 2, "gtk_about_dialog_set_authors", "gchar**"); gtk_about_dialog_set_authors(Xen_to_C_GtkAboutDialog_(about), (const gchar**)Xen_to_C_gchar__(authors)); return(Xen_false); } static Xen gxg_gtk_about_dialog_get_documenters(Xen about) { #define H_gtk_about_dialog_get_documenters "gchar** gtk_about_dialog_get_documenters(GtkAboutDialog* about)" Xen_check_type(Xen_is_GtkAboutDialog_(about), about, 1, "gtk_about_dialog_get_documenters", "GtkAboutDialog*"); return(C_to_Xen_gchar__((gchar**)gtk_about_dialog_get_documenters(Xen_to_C_GtkAboutDialog_(about)))); } static Xen gxg_gtk_about_dialog_set_documenters(Xen about, Xen documenters) { #define H_gtk_about_dialog_set_documenters "void gtk_about_dialog_set_documenters(GtkAboutDialog* about, \ gchar** documenters)" Xen_check_type(Xen_is_GtkAboutDialog_(about), about, 1, "gtk_about_dialog_set_documenters", "GtkAboutDialog*"); Xen_check_type(Xen_is_gchar__(documenters), documenters, 2, "gtk_about_dialog_set_documenters", "gchar**"); gtk_about_dialog_set_documenters(Xen_to_C_GtkAboutDialog_(about), (const gchar**)Xen_to_C_gchar__(documenters)); return(Xen_false); } static Xen gxg_gtk_about_dialog_get_artists(Xen about) { #define H_gtk_about_dialog_get_artists "gchar** gtk_about_dialog_get_artists(GtkAboutDialog* about)" Xen_check_type(Xen_is_GtkAboutDialog_(about), about, 1, "gtk_about_dialog_get_artists", "GtkAboutDialog*"); return(C_to_Xen_gchar__((gchar**)gtk_about_dialog_get_artists(Xen_to_C_GtkAboutDialog_(about)))); } static Xen gxg_gtk_about_dialog_set_artists(Xen about, Xen artists) { #define H_gtk_about_dialog_set_artists "void gtk_about_dialog_set_artists(GtkAboutDialog* about, gchar** artists)" Xen_check_type(Xen_is_GtkAboutDialog_(about), about, 1, "gtk_about_dialog_set_artists", "GtkAboutDialog*"); Xen_check_type(Xen_is_gchar__(artists), artists, 2, "gtk_about_dialog_set_artists", "gchar**"); gtk_about_dialog_set_artists(Xen_to_C_GtkAboutDialog_(about), (const gchar**)Xen_to_C_gchar__(artists)); return(Xen_false); } static Xen gxg_gtk_about_dialog_get_translator_credits(Xen about) { #define H_gtk_about_dialog_get_translator_credits "gchar* gtk_about_dialog_get_translator_credits(GtkAboutDialog* about)" Xen_check_type(Xen_is_GtkAboutDialog_(about), about, 1, "gtk_about_dialog_get_translator_credits", "GtkAboutDialog*"); return(C_to_Xen_gchar_(gtk_about_dialog_get_translator_credits(Xen_to_C_GtkAboutDialog_(about)))); } static Xen gxg_gtk_about_dialog_set_translator_credits(Xen about, Xen translator_credits) { #define H_gtk_about_dialog_set_translator_credits "void gtk_about_dialog_set_translator_credits(GtkAboutDialog* about, \ gchar* translator_credits)" Xen_check_type(Xen_is_GtkAboutDialog_(about), about, 1, "gtk_about_dialog_set_translator_credits", "GtkAboutDialog*"); Xen_check_type(Xen_is_gchar_(translator_credits), translator_credits, 2, "gtk_about_dialog_set_translator_credits", "gchar*"); gtk_about_dialog_set_translator_credits(Xen_to_C_GtkAboutDialog_(about), Xen_to_C_gchar_(translator_credits)); return(Xen_false); } static Xen gxg_gtk_about_dialog_get_logo(Xen about) { #define H_gtk_about_dialog_get_logo "GdkPixbuf* gtk_about_dialog_get_logo(GtkAboutDialog* about)" Xen_check_type(Xen_is_GtkAboutDialog_(about), about, 1, "gtk_about_dialog_get_logo", "GtkAboutDialog*"); return(C_to_Xen_GdkPixbuf_(gtk_about_dialog_get_logo(Xen_to_C_GtkAboutDialog_(about)))); } static Xen gxg_gtk_about_dialog_set_logo(Xen about, Xen logo) { #define H_gtk_about_dialog_set_logo "void gtk_about_dialog_set_logo(GtkAboutDialog* about, GdkPixbuf* logo)" Xen_check_type(Xen_is_GtkAboutDialog_(about), about, 1, "gtk_about_dialog_set_logo", "GtkAboutDialog*"); Xen_check_type(Xen_is_GdkPixbuf_(logo) || Xen_is_false(logo), logo, 2, "gtk_about_dialog_set_logo", "GdkPixbuf*"); gtk_about_dialog_set_logo(Xen_to_C_GtkAboutDialog_(about), Xen_to_C_GdkPixbuf_(logo)); return(Xen_false); } static Xen gxg_gtk_about_dialog_get_program_name(Xen about) { #define H_gtk_about_dialog_get_program_name "gchar* gtk_about_dialog_get_program_name(GtkAboutDialog* about)" Xen_check_type(Xen_is_GtkAboutDialog_(about), about, 1, "gtk_about_dialog_get_program_name", "GtkAboutDialog*"); return(C_to_Xen_gchar_(gtk_about_dialog_get_program_name(Xen_to_C_GtkAboutDialog_(about)))); } static Xen gxg_gtk_about_dialog_set_program_name(Xen about, Xen name) { #define H_gtk_about_dialog_set_program_name "void gtk_about_dialog_set_program_name(GtkAboutDialog* about, \ gchar* name)" Xen_check_type(Xen_is_GtkAboutDialog_(about), about, 1, "gtk_about_dialog_set_program_name", "GtkAboutDialog*"); Xen_check_type(Xen_is_gchar_(name), name, 2, "gtk_about_dialog_set_program_name", "gchar*"); gtk_about_dialog_set_program_name(Xen_to_C_GtkAboutDialog_(about), Xen_to_C_gchar_(name)); return(Xen_false); } static Xen gxg_gtk_icon_view_new(void) { #define H_gtk_icon_view_new "GtkWidget* gtk_icon_view_new( void)" return(C_to_Xen_GtkWidget_(gtk_icon_view_new())); } static Xen gxg_gtk_icon_view_new_with_model(Xen model) { #define H_gtk_icon_view_new_with_model "GtkWidget* gtk_icon_view_new_with_model(GtkTreeModel* model)" Xen_check_type(Xen_is_GtkTreeModel_(model), model, 1, "gtk_icon_view_new_with_model", "GtkTreeModel*"); return(C_to_Xen_GtkWidget_(gtk_icon_view_new_with_model(Xen_to_C_GtkTreeModel_(model)))); } static Xen gxg_gtk_icon_view_set_model(Xen icon_view, Xen model) { #define H_gtk_icon_view_set_model "void gtk_icon_view_set_model(GtkIconView* icon_view, GtkTreeModel* model)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_set_model", "GtkIconView*"); Xen_check_type(Xen_is_GtkTreeModel_(model) || Xen_is_false(model), model, 2, "gtk_icon_view_set_model", "GtkTreeModel*"); gtk_icon_view_set_model(Xen_to_C_GtkIconView_(icon_view), Xen_to_C_GtkTreeModel_(model)); return(Xen_false); } static Xen gxg_gtk_icon_view_get_model(Xen icon_view) { #define H_gtk_icon_view_get_model "GtkTreeModel* gtk_icon_view_get_model(GtkIconView* icon_view)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_get_model", "GtkIconView*"); return(C_to_Xen_GtkTreeModel_(gtk_icon_view_get_model(Xen_to_C_GtkIconView_(icon_view)))); } static Xen gxg_gtk_icon_view_set_text_column(Xen icon_view, Xen column) { #define H_gtk_icon_view_set_text_column "void gtk_icon_view_set_text_column(GtkIconView* icon_view, \ gint column)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_set_text_column", "GtkIconView*"); Xen_check_type(Xen_is_gint(column), column, 2, "gtk_icon_view_set_text_column", "gint"); gtk_icon_view_set_text_column(Xen_to_C_GtkIconView_(icon_view), Xen_to_C_gint(column)); return(Xen_false); } static Xen gxg_gtk_icon_view_get_text_column(Xen icon_view) { #define H_gtk_icon_view_get_text_column "gint gtk_icon_view_get_text_column(GtkIconView* icon_view)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_get_text_column", "GtkIconView*"); return(C_to_Xen_gint(gtk_icon_view_get_text_column(Xen_to_C_GtkIconView_(icon_view)))); } static Xen gxg_gtk_icon_view_set_markup_column(Xen icon_view, Xen column) { #define H_gtk_icon_view_set_markup_column "void gtk_icon_view_set_markup_column(GtkIconView* icon_view, \ gint column)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_set_markup_column", "GtkIconView*"); Xen_check_type(Xen_is_gint(column), column, 2, "gtk_icon_view_set_markup_column", "gint"); gtk_icon_view_set_markup_column(Xen_to_C_GtkIconView_(icon_view), Xen_to_C_gint(column)); return(Xen_false); } static Xen gxg_gtk_icon_view_get_markup_column(Xen icon_view) { #define H_gtk_icon_view_get_markup_column "gint gtk_icon_view_get_markup_column(GtkIconView* icon_view)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_get_markup_column", "GtkIconView*"); return(C_to_Xen_gint(gtk_icon_view_get_markup_column(Xen_to_C_GtkIconView_(icon_view)))); } static Xen gxg_gtk_icon_view_set_pixbuf_column(Xen icon_view, Xen column) { #define H_gtk_icon_view_set_pixbuf_column "void gtk_icon_view_set_pixbuf_column(GtkIconView* icon_view, \ gint column)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_set_pixbuf_column", "GtkIconView*"); Xen_check_type(Xen_is_gint(column), column, 2, "gtk_icon_view_set_pixbuf_column", "gint"); gtk_icon_view_set_pixbuf_column(Xen_to_C_GtkIconView_(icon_view), Xen_to_C_gint(column)); return(Xen_false); } static Xen gxg_gtk_icon_view_get_pixbuf_column(Xen icon_view) { #define H_gtk_icon_view_get_pixbuf_column "gint gtk_icon_view_get_pixbuf_column(GtkIconView* icon_view)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_get_pixbuf_column", "GtkIconView*"); return(C_to_Xen_gint(gtk_icon_view_get_pixbuf_column(Xen_to_C_GtkIconView_(icon_view)))); } static Xen gxg_gtk_icon_view_get_path_at_pos(Xen icon_view, Xen x, Xen y) { #define H_gtk_icon_view_get_path_at_pos "GtkTreePath* gtk_icon_view_get_path_at_pos(GtkIconView* icon_view, \ gint x, gint y)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_get_path_at_pos", "GtkIconView*"); Xen_check_type(Xen_is_gint(x), x, 2, "gtk_icon_view_get_path_at_pos", "gint"); Xen_check_type(Xen_is_gint(y), y, 3, "gtk_icon_view_get_path_at_pos", "gint"); return(C_to_Xen_GtkTreePath_(gtk_icon_view_get_path_at_pos(Xen_to_C_GtkIconView_(icon_view), Xen_to_C_gint(x), Xen_to_C_gint(y)))); } static Xen gxg_gtk_icon_view_selected_foreach(Xen icon_view, Xen func, Xen func_info) { #define H_gtk_icon_view_selected_foreach "void gtk_icon_view_selected_foreach(GtkIconView* icon_view, \ GtkIconViewForeachFunc func, lambda_data func_info)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_selected_foreach", "GtkIconView*"); Xen_check_type(Xen_is_GtkIconViewForeachFunc(func), func, 2, "gtk_icon_view_selected_foreach", "GtkIconViewForeachFunc"); if (!Xen_is_bound(func_info)) func_info = Xen_false; else Xen_check_type(Xen_is_lambda_data(func_info), func_info, 3, "gtk_icon_view_selected_foreach", "lambda_data"); { Xen gxg_ptr = Xen_list_5(func, func_info, Xen_false, Xen_false, Xen_false); xm_protect(gxg_ptr); gtk_icon_view_selected_foreach(Xen_to_C_GtkIconView_(icon_view), Xen_to_C_GtkIconViewForeachFunc(func), Xen_to_C_lambda_data(func_info)); return(Xen_false); } } static Xen gxg_gtk_icon_view_set_selection_mode(Xen icon_view, Xen mode) { #define H_gtk_icon_view_set_selection_mode "void gtk_icon_view_set_selection_mode(GtkIconView* icon_view, \ GtkSelectionMode mode)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_set_selection_mode", "GtkIconView*"); Xen_check_type(Xen_is_GtkSelectionMode(mode), mode, 2, "gtk_icon_view_set_selection_mode", "GtkSelectionMode"); gtk_icon_view_set_selection_mode(Xen_to_C_GtkIconView_(icon_view), Xen_to_C_GtkSelectionMode(mode)); return(Xen_false); } static Xen gxg_gtk_icon_view_get_selection_mode(Xen icon_view) { #define H_gtk_icon_view_get_selection_mode "GtkSelectionMode gtk_icon_view_get_selection_mode(GtkIconView* icon_view)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_get_selection_mode", "GtkIconView*"); return(C_to_Xen_GtkSelectionMode(gtk_icon_view_get_selection_mode(Xen_to_C_GtkIconView_(icon_view)))); } static Xen gxg_gtk_icon_view_select_path(Xen icon_view, Xen path) { #define H_gtk_icon_view_select_path "void gtk_icon_view_select_path(GtkIconView* icon_view, GtkTreePath* path)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_select_path", "GtkIconView*"); Xen_check_type(Xen_is_GtkTreePath_(path), path, 2, "gtk_icon_view_select_path", "GtkTreePath*"); gtk_icon_view_select_path(Xen_to_C_GtkIconView_(icon_view), Xen_to_C_GtkTreePath_(path)); return(Xen_false); } static Xen gxg_gtk_icon_view_unselect_path(Xen icon_view, Xen path) { #define H_gtk_icon_view_unselect_path "void gtk_icon_view_unselect_path(GtkIconView* icon_view, GtkTreePath* path)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_unselect_path", "GtkIconView*"); Xen_check_type(Xen_is_GtkTreePath_(path), path, 2, "gtk_icon_view_unselect_path", "GtkTreePath*"); gtk_icon_view_unselect_path(Xen_to_C_GtkIconView_(icon_view), Xen_to_C_GtkTreePath_(path)); return(Xen_false); } static Xen gxg_gtk_icon_view_path_is_selected(Xen icon_view, Xen path) { #define H_gtk_icon_view_path_is_selected "gboolean gtk_icon_view_path_is_selected(GtkIconView* icon_view, \ GtkTreePath* path)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_path_is_selected", "GtkIconView*"); Xen_check_type(Xen_is_GtkTreePath_(path), path, 2, "gtk_icon_view_path_is_selected", "GtkTreePath*"); return(C_to_Xen_gboolean(gtk_icon_view_path_is_selected(Xen_to_C_GtkIconView_(icon_view), Xen_to_C_GtkTreePath_(path)))); } static Xen gxg_gtk_icon_view_get_selected_items(Xen icon_view) { #define H_gtk_icon_view_get_selected_items "GList* gtk_icon_view_get_selected_items(GtkIconView* icon_view)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_get_selected_items", "GtkIconView*"); return(C_to_Xen_GList_(gtk_icon_view_get_selected_items(Xen_to_C_GtkIconView_(icon_view)))); } static Xen gxg_gtk_icon_view_select_all(Xen icon_view) { #define H_gtk_icon_view_select_all "void gtk_icon_view_select_all(GtkIconView* icon_view)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_select_all", "GtkIconView*"); gtk_icon_view_select_all(Xen_to_C_GtkIconView_(icon_view)); return(Xen_false); } static Xen gxg_gtk_icon_view_unselect_all(Xen icon_view) { #define H_gtk_icon_view_unselect_all "void gtk_icon_view_unselect_all(GtkIconView* icon_view)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_unselect_all", "GtkIconView*"); gtk_icon_view_unselect_all(Xen_to_C_GtkIconView_(icon_view)); return(Xen_false); } static Xen gxg_gtk_icon_view_item_activated(Xen icon_view, Xen path) { #define H_gtk_icon_view_item_activated "void gtk_icon_view_item_activated(GtkIconView* icon_view, GtkTreePath* path)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_item_activated", "GtkIconView*"); Xen_check_type(Xen_is_GtkTreePath_(path), path, 2, "gtk_icon_view_item_activated", "GtkTreePath*"); gtk_icon_view_item_activated(Xen_to_C_GtkIconView_(icon_view), Xen_to_C_GtkTreePath_(path)); return(Xen_false); } static Xen gxg_gtk_cell_renderer_combo_new(void) { #define H_gtk_cell_renderer_combo_new "GtkCellRenderer* gtk_cell_renderer_combo_new( void)" return(C_to_Xen_GtkCellRenderer_(gtk_cell_renderer_combo_new())); } static Xen gxg_gtk_cell_renderer_progress_new(void) { #define H_gtk_cell_renderer_progress_new "GtkCellRenderer* gtk_cell_renderer_progress_new( void)" return(C_to_Xen_GtkCellRenderer_(gtk_cell_renderer_progress_new())); } static Xen gxg_gtk_combo_box_set_row_separator_func(Xen combo_box, Xen func, Xen func_info, Xen destroy) { #define H_gtk_combo_box_set_row_separator_func "void gtk_combo_box_set_row_separator_func(GtkComboBox* combo_box, \ GtkTreeViewRowSeparatorFunc func, lambda_data func_info, GtkDestroyNotify destroy)" Xen_check_type(Xen_is_GtkComboBox_(combo_box), combo_box, 1, "gtk_combo_box_set_row_separator_func", "GtkComboBox*"); Xen_check_type(Xen_is_GtkTreeViewRowSeparatorFunc(func), func, 2, "gtk_combo_box_set_row_separator_func", "GtkTreeViewRowSeparatorFunc"); Xen_check_type(Xen_is_lambda_data(func_info), func_info, 3, "gtk_combo_box_set_row_separator_func", "lambda_data"); Xen_check_type(Xen_is_GtkDestroyNotify(destroy), destroy, 4, "gtk_combo_box_set_row_separator_func", "GtkDestroyNotify"); { Xen gxg_ptr = Xen_list_5(func, func_info, Xen_false, Xen_false, Xen_false); xm_protect(gxg_ptr); Xen_list_set(gxg_ptr, 3, destroy); gtk_combo_box_set_row_separator_func(Xen_to_C_GtkComboBox_(combo_box), Xen_to_C_GtkTreeViewRowSeparatorFunc(func), Xen_to_C_lambda_data(func_info), Xen_to_C_GtkDestroyNotify(destroy)); return(Xen_false); } } static Xen gxg_gtk_label_set_ellipsize(Xen label, Xen mode) { #define H_gtk_label_set_ellipsize "void gtk_label_set_ellipsize(GtkLabel* label, PangoEllipsizeMode mode)" Xen_check_type(Xen_is_GtkLabel_(label), label, 1, "gtk_label_set_ellipsize", "GtkLabel*"); Xen_check_type(Xen_is_PangoEllipsizeMode(mode), mode, 2, "gtk_label_set_ellipsize", "PangoEllipsizeMode"); gtk_label_set_ellipsize(Xen_to_C_GtkLabel_(label), Xen_to_C_PangoEllipsizeMode(mode)); return(Xen_false); } static Xen gxg_gtk_label_get_ellipsize(Xen label) { #define H_gtk_label_get_ellipsize "PangoEllipsizeMode gtk_label_get_ellipsize(GtkLabel* label)" Xen_check_type(Xen_is_GtkLabel_(label), label, 1, "gtk_label_get_ellipsize", "GtkLabel*"); return(C_to_Xen_PangoEllipsizeMode(gtk_label_get_ellipsize(Xen_to_C_GtkLabel_(label)))); } static Xen gxg_pango_attr_fallback_new(Xen enable_fallback) { #define H_pango_attr_fallback_new "PangoAttribute* pango_attr_fallback_new(gboolean enable_fallback)" Xen_check_type(Xen_is_gboolean(enable_fallback), enable_fallback, 1, "pango_attr_fallback_new", "gboolean"); return(C_to_Xen_PangoAttribute_(pango_attr_fallback_new(Xen_to_C_gboolean(enable_fallback)))); } static Xen gxg_pango_attr_letter_spacing_new(Xen letter_spacing) { #define H_pango_attr_letter_spacing_new "PangoAttribute* pango_attr_letter_spacing_new(int letter_spacing)" Xen_check_type(Xen_is_int(letter_spacing), letter_spacing, 1, "pango_attr_letter_spacing_new", "int"); return(C_to_Xen_PangoAttribute_(pango_attr_letter_spacing_new(Xen_to_C_int(letter_spacing)))); } static Xen gxg_pango_attr_list_filter(Xen list, Xen func, Xen data) { #define H_pango_attr_list_filter "PangoAttrList* pango_attr_list_filter(PangoAttrList* list, PangoAttrFilterFunc func, \ gpointer data)" Xen_check_type(Xen_is_PangoAttrList_(list), list, 1, "pango_attr_list_filter", "PangoAttrList*"); Xen_check_type(Xen_is_PangoAttrFilterFunc(func), func, 2, "pango_attr_list_filter", "PangoAttrFilterFunc"); Xen_check_type(Xen_is_gpointer(data), data, 3, "pango_attr_list_filter", "gpointer"); return(C_to_Xen_PangoAttrList_(pango_attr_list_filter(Xen_to_C_PangoAttrList_(list), Xen_to_C_PangoAttrFilterFunc(func), Xen_to_C_gpointer(data)))); } static Xen gxg_pango_attr_iterator_get_attrs(Xen iterator) { #define H_pango_attr_iterator_get_attrs "GSList* pango_attr_iterator_get_attrs(PangoAttrIterator* iterator)" Xen_check_type(Xen_is_PangoAttrIterator_(iterator), iterator, 1, "pango_attr_iterator_get_attrs", "PangoAttrIterator*"); return(C_to_Xen_GSList_(pango_attr_iterator_get_attrs(Xen_to_C_PangoAttrIterator_(iterator)))); } static Xen gxg_pango_font_metrics_get_underline_position(Xen metrics) { #define H_pango_font_metrics_get_underline_position "int pango_font_metrics_get_underline_position(PangoFontMetrics* metrics)" Xen_check_type(Xen_is_PangoFontMetrics_(metrics), metrics, 1, "pango_font_metrics_get_underline_position", "PangoFontMetrics*"); return(C_to_Xen_int(pango_font_metrics_get_underline_position(Xen_to_C_PangoFontMetrics_(metrics)))); } static Xen gxg_pango_font_metrics_get_underline_thickness(Xen metrics) { #define H_pango_font_metrics_get_underline_thickness "int pango_font_metrics_get_underline_thickness(PangoFontMetrics* metrics)" Xen_check_type(Xen_is_PangoFontMetrics_(metrics), metrics, 1, "pango_font_metrics_get_underline_thickness", "PangoFontMetrics*"); return(C_to_Xen_int(pango_font_metrics_get_underline_thickness(Xen_to_C_PangoFontMetrics_(metrics)))); } static Xen gxg_pango_font_metrics_get_strikethrough_position(Xen metrics) { #define H_pango_font_metrics_get_strikethrough_position "int pango_font_metrics_get_strikethrough_position(PangoFontMetrics* metrics)" Xen_check_type(Xen_is_PangoFontMetrics_(metrics), metrics, 1, "pango_font_metrics_get_strikethrough_position", "PangoFontMetrics*"); return(C_to_Xen_int(pango_font_metrics_get_strikethrough_position(Xen_to_C_PangoFontMetrics_(metrics)))); } static Xen gxg_pango_font_metrics_get_strikethrough_thickness(Xen metrics) { #define H_pango_font_metrics_get_strikethrough_thickness "int pango_font_metrics_get_strikethrough_thickness(PangoFontMetrics* metrics)" Xen_check_type(Xen_is_PangoFontMetrics_(metrics), metrics, 1, "pango_font_metrics_get_strikethrough_thickness", "PangoFontMetrics*"); return(C_to_Xen_int(pango_font_metrics_get_strikethrough_thickness(Xen_to_C_PangoFontMetrics_(metrics)))); } static Xen gxg_pango_font_family_is_monospace(Xen family) { #define H_pango_font_family_is_monospace "gboolean pango_font_family_is_monospace(PangoFontFamily* family)" Xen_check_type(Xen_is_PangoFontFamily_(family), family, 1, "pango_font_family_is_monospace", "PangoFontFamily*"); return(C_to_Xen_gboolean(pango_font_family_is_monospace(Xen_to_C_PangoFontFamily_(family)))); } static Xen gxg_pango_font_face_list_sizes(Xen face, Xen ignore_sizes, Xen ignore_n_sizes) { #define H_pango_font_face_list_sizes "void pango_font_face_list_sizes(PangoFontFace* face, int** [sizes], \ int* [n_sizes])" int* ref_sizes = NULL; int ref_n_sizes; Xen_check_type(Xen_is_PangoFontFace_(face), face, 1, "pango_font_face_list_sizes", "PangoFontFace*"); pango_font_face_list_sizes(Xen_to_C_PangoFontFace_(face), &ref_sizes, &ref_n_sizes); return(Xen_list_2(C_to_Xen_int_(ref_sizes), C_to_Xen_int(ref_n_sizes))); } static Xen gxg_pango_layout_set_auto_dir(Xen layout, Xen auto_dir) { #define H_pango_layout_set_auto_dir "void pango_layout_set_auto_dir(PangoLayout* layout, gboolean auto_dir)" Xen_check_type(Xen_is_PangoLayout_(layout), layout, 1, "pango_layout_set_auto_dir", "PangoLayout*"); Xen_check_type(Xen_is_gboolean(auto_dir), auto_dir, 2, "pango_layout_set_auto_dir", "gboolean"); pango_layout_set_auto_dir(Xen_to_C_PangoLayout_(layout), Xen_to_C_gboolean(auto_dir)); return(Xen_false); } static Xen gxg_pango_layout_get_auto_dir(Xen layout) { #define H_pango_layout_get_auto_dir "gboolean pango_layout_get_auto_dir(PangoLayout* layout)" Xen_check_type(Xen_is_PangoLayout_(layout), layout, 1, "pango_layout_get_auto_dir", "PangoLayout*"); return(C_to_Xen_gboolean(pango_layout_get_auto_dir(Xen_to_C_PangoLayout_(layout)))); } static Xen gxg_pango_script_for_unichar(Xen ch) { #define H_pango_script_for_unichar "PangoScript pango_script_for_unichar(gunichar ch)" Xen_check_type(Xen_is_gunichar(ch), ch, 1, "pango_script_for_unichar", "gunichar"); return(C_to_Xen_PangoScript(pango_script_for_unichar(Xen_to_C_gunichar(ch)))); } static Xen gxg_pango_script_iter_new(Xen text, Xen length) { #define H_pango_script_iter_new "PangoScriptIter* pango_script_iter_new(char* text, int length)" Xen_check_type(Xen_is_char_(text), text, 1, "pango_script_iter_new", "char*"); Xen_check_type(Xen_is_int(length), length, 2, "pango_script_iter_new", "int"); return(C_to_Xen_PangoScriptIter_(pango_script_iter_new(Xen_to_C_char_(text), Xen_to_C_int(length)))); } static Xen gxg_pango_script_iter_get_range(Xen iter, Xen ignore_start, Xen ignore_end, Xen ignore_script) { #define H_pango_script_iter_get_range "void pango_script_iter_get_range(PangoScriptIter* iter, char** [start], \ char** [end], PangoScript* [script])" char* ref_start = NULL; char* ref_end = NULL; PangoScript ref_script; Xen_check_type(Xen_is_PangoScriptIter_(iter), iter, 1, "pango_script_iter_get_range", "PangoScriptIter*"); pango_script_iter_get_range(Xen_to_C_PangoScriptIter_(iter), (const char**)&ref_start, (const char**)&ref_end, &ref_script); return(Xen_list_3(C_to_Xen_char_(ref_start), C_to_Xen_char_(ref_end), C_to_Xen_PangoScript(ref_script))); } static Xen gxg_pango_script_iter_next(Xen iter) { #define H_pango_script_iter_next "gboolean pango_script_iter_next(PangoScriptIter* iter)" Xen_check_type(Xen_is_PangoScriptIter_(iter), iter, 1, "pango_script_iter_next", "PangoScriptIter*"); return(C_to_Xen_gboolean(pango_script_iter_next(Xen_to_C_PangoScriptIter_(iter)))); } static Xen gxg_pango_script_iter_free(Xen iter) { #define H_pango_script_iter_free "void pango_script_iter_free(PangoScriptIter* iter)" Xen_check_type(Xen_is_PangoScriptIter_(iter), iter, 1, "pango_script_iter_free", "PangoScriptIter*"); pango_script_iter_free(Xen_to_C_PangoScriptIter_(iter)); return(Xen_false); } static Xen gxg_gtk_file_chooser_button_new_with_dialog(Xen dialog) { #define H_gtk_file_chooser_button_new_with_dialog "GtkWidget* gtk_file_chooser_button_new_with_dialog(GtkWidget* dialog)" Xen_check_type(Xen_is_GtkWidget_(dialog), dialog, 1, "gtk_file_chooser_button_new_with_dialog", "GtkWidget*"); return(C_to_Xen_GtkWidget_(gtk_file_chooser_button_new_with_dialog(Xen_to_C_GtkWidget_(dialog)))); } static Xen gxg_gtk_file_chooser_button_get_title(Xen button) { #define H_gtk_file_chooser_button_get_title "gchar* gtk_file_chooser_button_get_title(GtkFileChooserButton* button)" Xen_check_type(Xen_is_GtkFileChooserButton_(button), button, 1, "gtk_file_chooser_button_get_title", "GtkFileChooserButton*"); return(C_to_Xen_gchar_(gtk_file_chooser_button_get_title(Xen_to_C_GtkFileChooserButton_(button)))); } static Xen gxg_gtk_file_chooser_button_set_title(Xen button, Xen title) { #define H_gtk_file_chooser_button_set_title "void gtk_file_chooser_button_set_title(GtkFileChooserButton* button, \ gchar* title)" Xen_check_type(Xen_is_GtkFileChooserButton_(button), button, 1, "gtk_file_chooser_button_set_title", "GtkFileChooserButton*"); Xen_check_type(Xen_is_gchar_(title), title, 2, "gtk_file_chooser_button_set_title", "gchar*"); gtk_file_chooser_button_set_title(Xen_to_C_GtkFileChooserButton_(button), Xen_to_C_gchar_(title)); return(Xen_false); } static Xen gxg_gdk_drag_drop_succeeded(Xen context) { #define H_gdk_drag_drop_succeeded "gboolean gdk_drag_drop_succeeded(GdkDragContext* context)" Xen_check_type(Xen_is_GdkDragContext_(context), context, 1, "gdk_drag_drop_succeeded", "GdkDragContext*"); return(C_to_Xen_gboolean(gdk_drag_drop_succeeded(Xen_to_C_GdkDragContext_(context)))); } static Xen gxg_gtk_entry_layout_index_to_text_index(Xen entry, Xen layout_index) { #define H_gtk_entry_layout_index_to_text_index "gint gtk_entry_layout_index_to_text_index(GtkEntry* entry, \ gint layout_index)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_layout_index_to_text_index", "GtkEntry*"); Xen_check_type(Xen_is_gint(layout_index), layout_index, 2, "gtk_entry_layout_index_to_text_index", "gint"); return(C_to_Xen_gint(gtk_entry_layout_index_to_text_index(Xen_to_C_GtkEntry_(entry), Xen_to_C_gint(layout_index)))); } static Xen gxg_gtk_entry_text_index_to_layout_index(Xen entry, Xen text_index) { #define H_gtk_entry_text_index_to_layout_index "gint gtk_entry_text_index_to_layout_index(GtkEntry* entry, \ gint text_index)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_text_index_to_layout_index", "GtkEntry*"); Xen_check_type(Xen_is_gint(text_index), text_index, 2, "gtk_entry_text_index_to_layout_index", "gint"); return(C_to_Xen_gint(gtk_entry_text_index_to_layout_index(Xen_to_C_GtkEntry_(entry), Xen_to_C_gint(text_index)))); } static Xen gxg_gtk_file_chooser_set_show_hidden(Xen chooser, Xen show_hidden) { #define H_gtk_file_chooser_set_show_hidden "void gtk_file_chooser_set_show_hidden(GtkFileChooser* chooser, \ gboolean show_hidden)" Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_set_show_hidden", "GtkFileChooser*"); Xen_check_type(Xen_is_gboolean(show_hidden), show_hidden, 2, "gtk_file_chooser_set_show_hidden", "gboolean"); gtk_file_chooser_set_show_hidden(Xen_to_C_GtkFileChooser_(chooser), Xen_to_C_gboolean(show_hidden)); return(Xen_false); } static Xen gxg_gtk_file_chooser_get_show_hidden(Xen chooser) { #define H_gtk_file_chooser_get_show_hidden "gboolean gtk_file_chooser_get_show_hidden(GtkFileChooser* chooser)" Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_get_show_hidden", "GtkFileChooser*"); return(C_to_Xen_gboolean(gtk_file_chooser_get_show_hidden(Xen_to_C_GtkFileChooser_(chooser)))); } static Xen gxg_gtk_tree_view_set_hover_expand(Xen tree_view, Xen expand) { #define H_gtk_tree_view_set_hover_expand "void gtk_tree_view_set_hover_expand(GtkTreeView* tree_view, \ gboolean expand)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_set_hover_expand", "GtkTreeView*"); Xen_check_type(Xen_is_gboolean(expand), expand, 2, "gtk_tree_view_set_hover_expand", "gboolean"); gtk_tree_view_set_hover_expand(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_gboolean(expand)); return(Xen_false); } static Xen gxg_gtk_tree_view_get_hover_expand(Xen tree_view) { #define H_gtk_tree_view_get_hover_expand "gboolean gtk_tree_view_get_hover_expand(GtkTreeView* tree_view)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_get_hover_expand", "GtkTreeView*"); return(C_to_Xen_gboolean(gtk_tree_view_get_hover_expand(Xen_to_C_GtkTreeView_(tree_view)))); } static Xen gxg_gtk_tool_item_rebuild_menu(Xen tool_item) { #define H_gtk_tool_item_rebuild_menu "void gtk_tool_item_rebuild_menu(GtkToolItem* tool_item)" Xen_check_type(Xen_is_GtkToolItem_(tool_item), tool_item, 1, "gtk_tool_item_rebuild_menu", "GtkToolItem*"); gtk_tool_item_rebuild_menu(Xen_to_C_GtkToolItem_(tool_item)); return(Xen_false); } static Xen gxg_gtk_menu_tool_button_new(Xen icon_widget, Xen label) { #define H_gtk_menu_tool_button_new "GtkToolItem* gtk_menu_tool_button_new(GtkWidget* icon_widget, gchar* label)" Xen_check_type(Xen_is_GtkWidget_(icon_widget) || Xen_is_false(icon_widget), icon_widget, 1, "gtk_menu_tool_button_new", "GtkWidget*"); Xen_check_type(Xen_is_gchar_(label), label, 2, "gtk_menu_tool_button_new", "gchar*"); return(C_to_Xen_GtkToolItem_(gtk_menu_tool_button_new(Xen_to_C_GtkWidget_(icon_widget), Xen_to_C_gchar_(label)))); } static Xen gxg_gtk_menu_tool_button_set_menu(Xen button, Xen menu) { #define H_gtk_menu_tool_button_set_menu "void gtk_menu_tool_button_set_menu(GtkMenuToolButton* button, \ GtkWidget* menu)" Xen_check_type(Xen_is_GtkMenuToolButton_(button), button, 1, "gtk_menu_tool_button_set_menu", "GtkMenuToolButton*"); Xen_check_type(Xen_is_GtkWidget_(menu), menu, 2, "gtk_menu_tool_button_set_menu", "GtkWidget*"); gtk_menu_tool_button_set_menu(Xen_to_C_GtkMenuToolButton_(button), Xen_to_C_GtkWidget_(menu)); return(Xen_false); } static Xen gxg_gtk_menu_tool_button_get_menu(Xen button) { #define H_gtk_menu_tool_button_get_menu "GtkWidget* gtk_menu_tool_button_get_menu(GtkMenuToolButton* button)" Xen_check_type(Xen_is_GtkMenuToolButton_(button), button, 1, "gtk_menu_tool_button_get_menu", "GtkMenuToolButton*"); return(C_to_Xen_GtkWidget_(gtk_menu_tool_button_get_menu(Xen_to_C_GtkMenuToolButton_(button)))); } static Xen gxg_gdk_display_supports_clipboard_persistence(Xen display) { #define H_gdk_display_supports_clipboard_persistence "gboolean gdk_display_supports_clipboard_persistence(GdkDisplay* display)" Xen_check_type(Xen_is_GdkDisplay_(display), display, 1, "gdk_display_supports_clipboard_persistence", "GdkDisplay*"); return(C_to_Xen_gboolean(gdk_display_supports_clipboard_persistence(Xen_to_C_GdkDisplay_(display)))); } static Xen gxg_gtk_about_dialog_get_logo_icon_name(Xen about) { #define H_gtk_about_dialog_get_logo_icon_name "gchar* gtk_about_dialog_get_logo_icon_name(GtkAboutDialog* about)" Xen_check_type(Xen_is_GtkAboutDialog_(about), about, 1, "gtk_about_dialog_get_logo_icon_name", "GtkAboutDialog*"); return(C_to_Xen_gchar_(gtk_about_dialog_get_logo_icon_name(Xen_to_C_GtkAboutDialog_(about)))); } static Xen gxg_gtk_about_dialog_set_logo_icon_name(Xen about, Xen icon_name) { #define H_gtk_about_dialog_set_logo_icon_name "void gtk_about_dialog_set_logo_icon_name(GtkAboutDialog* about, \ gchar* icon_name)" Xen_check_type(Xen_is_GtkAboutDialog_(about), about, 1, "gtk_about_dialog_set_logo_icon_name", "GtkAboutDialog*"); Xen_check_type(Xen_is_gchar_(icon_name), icon_name, 2, "gtk_about_dialog_set_logo_icon_name", "gchar*"); gtk_about_dialog_set_logo_icon_name(Xen_to_C_GtkAboutDialog_(about), Xen_to_C_gchar_(icon_name)); return(Xen_false); } static Xen gxg_gtk_accelerator_get_label(Xen accelerator_key, Xen accelerator_mods) { #define H_gtk_accelerator_get_label "gchar* gtk_accelerator_get_label(guint accelerator_key, GdkModifierType accelerator_mods)" Xen_check_type(Xen_is_guint(accelerator_key), accelerator_key, 1, "gtk_accelerator_get_label", "guint"); Xen_check_type(Xen_is_GdkModifierType(accelerator_mods), accelerator_mods, 2, "gtk_accelerator_get_label", "GdkModifierType"); { gchar* result; Xen rtn; result = gtk_accelerator_get_label(Xen_to_C_guint(accelerator_key), Xen_to_C_GdkModifierType(accelerator_mods)); rtn = C_to_Xen_gchar_(result); g_free(result); return(rtn); } } static Xen gxg_gtk_clipboard_wait_is_target_available(Xen clipboard, Xen target) { #define H_gtk_clipboard_wait_is_target_available "gboolean gtk_clipboard_wait_is_target_available(GtkClipboard* clipboard, \ GdkAtom target)" Xen_check_type(Xen_is_GtkClipboard_(clipboard), clipboard, 1, "gtk_clipboard_wait_is_target_available", "GtkClipboard*"); Xen_check_type(Xen_is_GdkAtom(target), target, 2, "gtk_clipboard_wait_is_target_available", "GdkAtom"); return(C_to_Xen_gboolean(gtk_clipboard_wait_is_target_available(Xen_to_C_GtkClipboard_(clipboard), Xen_to_C_GdkAtom(target)))); } static Xen gxg_gtk_clipboard_set_can_store(Xen clipboard, Xen targets, Xen n_targets) { #define H_gtk_clipboard_set_can_store "void gtk_clipboard_set_can_store(GtkClipboard* clipboard, GtkTargetEntry* targets, \ gint n_targets)" Xen_check_type(Xen_is_GtkClipboard_(clipboard), clipboard, 1, "gtk_clipboard_set_can_store", "GtkClipboard*"); Xen_check_type(Xen_is_GtkTargetEntry_(targets) || Xen_is_false(targets), targets, 2, "gtk_clipboard_set_can_store", "GtkTargetEntry*"); Xen_check_type(Xen_is_gint(n_targets), n_targets, 3, "gtk_clipboard_set_can_store", "gint"); gtk_clipboard_set_can_store(Xen_to_C_GtkClipboard_(clipboard), Xen_to_C_GtkTargetEntry_(targets), Xen_to_C_gint(n_targets)); return(Xen_false); } static Xen gxg_gtk_clipboard_store(Xen clipboard) { #define H_gtk_clipboard_store "void gtk_clipboard_store(GtkClipboard* clipboard)" Xen_check_type(Xen_is_GtkClipboard_(clipboard), clipboard, 1, "gtk_clipboard_store", "GtkClipboard*"); gtk_clipboard_store(Xen_to_C_GtkClipboard_(clipboard)); return(Xen_false); } static Xen gxg_gtk_drag_dest_add_image_targets(Xen widget) { #define H_gtk_drag_dest_add_image_targets "void gtk_drag_dest_add_image_targets(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_drag_dest_add_image_targets", "GtkWidget*"); gtk_drag_dest_add_image_targets(Xen_to_C_GtkWidget_(widget)); return(Xen_false); } static Xen gxg_gtk_drag_dest_add_uri_targets(Xen widget) { #define H_gtk_drag_dest_add_uri_targets "void gtk_drag_dest_add_uri_targets(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_drag_dest_add_uri_targets", "GtkWidget*"); gtk_drag_dest_add_uri_targets(Xen_to_C_GtkWidget_(widget)); return(Xen_false); } static Xen gxg_gtk_drag_source_add_image_targets(Xen widget) { #define H_gtk_drag_source_add_image_targets "void gtk_drag_source_add_image_targets(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_drag_source_add_image_targets", "GtkWidget*"); gtk_drag_source_add_image_targets(Xen_to_C_GtkWidget_(widget)); return(Xen_false); } static Xen gxg_gtk_drag_source_add_uri_targets(Xen widget) { #define H_gtk_drag_source_add_uri_targets "void gtk_drag_source_add_uri_targets(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_drag_source_add_uri_targets", "GtkWidget*"); gtk_drag_source_add_uri_targets(Xen_to_C_GtkWidget_(widget)); return(Xen_false); } static Xen gxg_gtk_file_chooser_button_get_width_chars(Xen button) { #define H_gtk_file_chooser_button_get_width_chars "gint gtk_file_chooser_button_get_width_chars(GtkFileChooserButton* button)" Xen_check_type(Xen_is_GtkFileChooserButton_(button), button, 1, "gtk_file_chooser_button_get_width_chars", "GtkFileChooserButton*"); return(C_to_Xen_gint(gtk_file_chooser_button_get_width_chars(Xen_to_C_GtkFileChooserButton_(button)))); } static Xen gxg_gtk_file_chooser_button_set_width_chars(Xen button, Xen n_chars) { #define H_gtk_file_chooser_button_set_width_chars "void gtk_file_chooser_button_set_width_chars(GtkFileChooserButton* button, \ gint n_chars)" Xen_check_type(Xen_is_GtkFileChooserButton_(button), button, 1, "gtk_file_chooser_button_set_width_chars", "GtkFileChooserButton*"); Xen_check_type(Xen_is_gint(n_chars), n_chars, 2, "gtk_file_chooser_button_set_width_chars", "gint"); gtk_file_chooser_button_set_width_chars(Xen_to_C_GtkFileChooserButton_(button), Xen_to_C_gint(n_chars)); return(Xen_false); } static Xen gxg_gtk_image_set_pixel_size(Xen image, Xen pixel_size) { #define H_gtk_image_set_pixel_size "void gtk_image_set_pixel_size(GtkImage* image, gint pixel_size)" Xen_check_type(Xen_is_GtkImage_(image), image, 1, "gtk_image_set_pixel_size", "GtkImage*"); Xen_check_type(Xen_is_gint(pixel_size), pixel_size, 2, "gtk_image_set_pixel_size", "gint"); gtk_image_set_pixel_size(Xen_to_C_GtkImage_(image), Xen_to_C_gint(pixel_size)); return(Xen_false); } static Xen gxg_gtk_image_get_pixel_size(Xen image) { #define H_gtk_image_get_pixel_size "gint gtk_image_get_pixel_size(GtkImage* image)" Xen_check_type(Xen_is_GtkImage_(image), image, 1, "gtk_image_get_pixel_size", "GtkImage*"); return(C_to_Xen_gint(gtk_image_get_pixel_size(Xen_to_C_GtkImage_(image)))); } static Xen gxg_gtk_label_set_width_chars(Xen label, Xen n_chars) { #define H_gtk_label_set_width_chars "void gtk_label_set_width_chars(GtkLabel* label, gint n_chars)" Xen_check_type(Xen_is_GtkLabel_(label), label, 1, "gtk_label_set_width_chars", "GtkLabel*"); Xen_check_type(Xen_is_gint(n_chars), n_chars, 2, "gtk_label_set_width_chars", "gint"); gtk_label_set_width_chars(Xen_to_C_GtkLabel_(label), Xen_to_C_gint(n_chars)); return(Xen_false); } static Xen gxg_gtk_label_get_width_chars(Xen label) { #define H_gtk_label_get_width_chars "gint gtk_label_get_width_chars(GtkLabel* label)" Xen_check_type(Xen_is_GtkLabel_(label), label, 1, "gtk_label_get_width_chars", "GtkLabel*"); return(C_to_Xen_gint(gtk_label_get_width_chars(Xen_to_C_GtkLabel_(label)))); } static Xen gxg_gtk_target_list_add_text_targets(Xen list, Xen info) { #define H_gtk_target_list_add_text_targets "void gtk_target_list_add_text_targets(GtkTargetList* list, \ guint info)" Xen_check_type(Xen_is_GtkTargetList_(list), list, 1, "gtk_target_list_add_text_targets", "GtkTargetList*"); Xen_check_type(Xen_is_guint(info), info, 2, "gtk_target_list_add_text_targets", "guint"); gtk_target_list_add_text_targets(Xen_to_C_GtkTargetList_(list), Xen_to_C_guint(info)); return(Xen_false); } static Xen gxg_gtk_target_list_add_image_targets(Xen list, Xen info, Xen writable) { #define H_gtk_target_list_add_image_targets "void gtk_target_list_add_image_targets(GtkTargetList* list, \ guint info, gboolean writable)" Xen_check_type(Xen_is_GtkTargetList_(list), list, 1, "gtk_target_list_add_image_targets", "GtkTargetList*"); Xen_check_type(Xen_is_guint(info), info, 2, "gtk_target_list_add_image_targets", "guint"); Xen_check_type(Xen_is_gboolean(writable), writable, 3, "gtk_target_list_add_image_targets", "gboolean"); gtk_target_list_add_image_targets(Xen_to_C_GtkTargetList_(list), Xen_to_C_guint(info), Xen_to_C_gboolean(writable)); return(Xen_false); } static Xen gxg_gtk_target_list_add_uri_targets(Xen list, Xen info) { #define H_gtk_target_list_add_uri_targets "void gtk_target_list_add_uri_targets(GtkTargetList* list, \ guint info)" Xen_check_type(Xen_is_GtkTargetList_(list), list, 1, "gtk_target_list_add_uri_targets", "GtkTargetList*"); Xen_check_type(Xen_is_guint(info), info, 2, "gtk_target_list_add_uri_targets", "guint"); gtk_target_list_add_uri_targets(Xen_to_C_GtkTargetList_(list), Xen_to_C_guint(info)); return(Xen_false); } static Xen gxg_gtk_selection_data_set_pixbuf(Xen selection_data, Xen pixbuf) { #define H_gtk_selection_data_set_pixbuf "gboolean gtk_selection_data_set_pixbuf(GtkSelectionData* selection_data, \ GdkPixbuf* pixbuf)" Xen_check_type(Xen_is_GtkSelectionData_(selection_data), selection_data, 1, "gtk_selection_data_set_pixbuf", "GtkSelectionData*"); Xen_check_type(Xen_is_GdkPixbuf_(pixbuf), pixbuf, 2, "gtk_selection_data_set_pixbuf", "GdkPixbuf*"); return(C_to_Xen_gboolean(gtk_selection_data_set_pixbuf(Xen_to_C_GtkSelectionData_(selection_data), Xen_to_C_GdkPixbuf_(pixbuf)))); } static Xen gxg_gtk_selection_data_get_pixbuf(Xen selection_data) { #define H_gtk_selection_data_get_pixbuf "GdkPixbuf* gtk_selection_data_get_pixbuf(GtkSelectionData* selection_data)" Xen_check_type(Xen_is_GtkSelectionData_(selection_data), selection_data, 1, "gtk_selection_data_get_pixbuf", "GtkSelectionData*"); return(C_to_Xen_GdkPixbuf_(gtk_selection_data_get_pixbuf(Xen_to_C_GtkSelectionData_(selection_data)))); } static Xen gxg_gtk_selection_data_set_uris(Xen selection_data, Xen uris) { #define H_gtk_selection_data_set_uris "gboolean gtk_selection_data_set_uris(GtkSelectionData* selection_data, \ gchar** uris)" Xen_check_type(Xen_is_GtkSelectionData_(selection_data), selection_data, 1, "gtk_selection_data_set_uris", "GtkSelectionData*"); Xen_check_type(Xen_is_gchar__(uris), uris, 2, "gtk_selection_data_set_uris", "gchar**"); return(C_to_Xen_gboolean(gtk_selection_data_set_uris(Xen_to_C_GtkSelectionData_(selection_data), Xen_to_C_gchar__(uris)))); } static Xen gxg_gtk_selection_data_get_uris(Xen selection_data) { #define H_gtk_selection_data_get_uris "gchar** gtk_selection_data_get_uris(GtkSelectionData* selection_data)" Xen_check_type(Xen_is_GtkSelectionData_(selection_data), selection_data, 1, "gtk_selection_data_get_uris", "GtkSelectionData*"); return(C_to_Xen_gchar__(gtk_selection_data_get_uris(Xen_to_C_GtkSelectionData_(selection_data)))); } static Xen gxg_gtk_text_buffer_backspace(Xen buffer, Xen iter, Xen interactive, Xen default_editable) { #define H_gtk_text_buffer_backspace "gboolean gtk_text_buffer_backspace(GtkTextBuffer* buffer, GtkTextIter* iter, \ gboolean interactive, gboolean default_editable)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_backspace", "GtkTextBuffer*"); Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 2, "gtk_text_buffer_backspace", "GtkTextIter*"); Xen_check_type(Xen_is_gboolean(interactive), interactive, 3, "gtk_text_buffer_backspace", "gboolean"); Xen_check_type(Xen_is_gboolean(default_editable), default_editable, 4, "gtk_text_buffer_backspace", "gboolean"); return(C_to_Xen_gboolean(gtk_text_buffer_backspace(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_GtkTextIter_(iter), Xen_to_C_gboolean(interactive), Xen_to_C_gboolean(default_editable)))); } static Xen gxg_gtk_clipboard_set_image(Xen clipboard, Xen pixbuf) { #define H_gtk_clipboard_set_image "void gtk_clipboard_set_image(GtkClipboard* clipboard, GdkPixbuf* pixbuf)" Xen_check_type(Xen_is_GtkClipboard_(clipboard), clipboard, 1, "gtk_clipboard_set_image", "GtkClipboard*"); Xen_check_type(Xen_is_GdkPixbuf_(pixbuf), pixbuf, 2, "gtk_clipboard_set_image", "GdkPixbuf*"); gtk_clipboard_set_image(Xen_to_C_GtkClipboard_(clipboard), Xen_to_C_GdkPixbuf_(pixbuf)); return(Xen_false); } static Xen gxg_gtk_clipboard_request_image(Xen clipboard, Xen func, Xen func_info) { #define H_gtk_clipboard_request_image "void gtk_clipboard_request_image(GtkClipboard* clipboard, GtkClipboardImageReceivedFunc func, \ lambda_data func_info)" Xen_check_type(Xen_is_GtkClipboard_(clipboard), clipboard, 1, "gtk_clipboard_request_image", "GtkClipboard*"); Xen_check_type(Xen_is_GtkClipboardImageReceivedFunc(func), func, 2, "gtk_clipboard_request_image", "GtkClipboardImageReceivedFunc"); if (!Xen_is_bound(func_info)) func_info = Xen_false; else Xen_check_type(Xen_is_lambda_data(func_info), func_info, 3, "gtk_clipboard_request_image", "lambda_data"); { Xen gxg_ptr = Xen_list_5(func, func_info, Xen_false, Xen_false, Xen_false); xm_protect(gxg_ptr); gtk_clipboard_request_image(Xen_to_C_GtkClipboard_(clipboard), Xen_to_C_GtkClipboardImageReceivedFunc(func), Xen_to_C_lambda_data(func_info)); return(Xen_false); } } static Xen gxg_gtk_clipboard_wait_for_image(Xen clipboard) { #define H_gtk_clipboard_wait_for_image "GdkPixbuf* gtk_clipboard_wait_for_image(GtkClipboard* clipboard)" Xen_check_type(Xen_is_GtkClipboard_(clipboard), clipboard, 1, "gtk_clipboard_wait_for_image", "GtkClipboard*"); return(C_to_Xen_GdkPixbuf_(gtk_clipboard_wait_for_image(Xen_to_C_GtkClipboard_(clipboard)))); } static Xen gxg_gtk_clipboard_wait_is_image_available(Xen clipboard) { #define H_gtk_clipboard_wait_is_image_available "gboolean gtk_clipboard_wait_is_image_available(GtkClipboard* clipboard)" Xen_check_type(Xen_is_GtkClipboard_(clipboard), clipboard, 1, "gtk_clipboard_wait_is_image_available", "GtkClipboard*"); return(C_to_Xen_gboolean(gtk_clipboard_wait_is_image_available(Xen_to_C_GtkClipboard_(clipboard)))); } static Xen gxg_gtk_file_filter_add_pixbuf_formats(Xen filter) { #define H_gtk_file_filter_add_pixbuf_formats "void gtk_file_filter_add_pixbuf_formats(GtkFileFilter* filter)" Xen_check_type(Xen_is_GtkFileFilter_(filter), filter, 1, "gtk_file_filter_add_pixbuf_formats", "GtkFileFilter*"); gtk_file_filter_add_pixbuf_formats(Xen_to_C_GtkFileFilter_(filter)); return(Xen_false); } static Xen gxg_gtk_label_set_single_line_mode(Xen label, Xen single_line_mode) { #define H_gtk_label_set_single_line_mode "void gtk_label_set_single_line_mode(GtkLabel* label, gboolean single_line_mode)" Xen_check_type(Xen_is_GtkLabel_(label), label, 1, "gtk_label_set_single_line_mode", "GtkLabel*"); Xen_check_type(Xen_is_gboolean(single_line_mode), single_line_mode, 2, "gtk_label_set_single_line_mode", "gboolean"); gtk_label_set_single_line_mode(Xen_to_C_GtkLabel_(label), Xen_to_C_gboolean(single_line_mode)); return(Xen_false); } static Xen gxg_gtk_label_get_single_line_mode(Xen label) { #define H_gtk_label_get_single_line_mode "gboolean gtk_label_get_single_line_mode(GtkLabel* label)" Xen_check_type(Xen_is_GtkLabel_(label), label, 1, "gtk_label_get_single_line_mode", "GtkLabel*"); return(C_to_Xen_gboolean(gtk_label_get_single_line_mode(Xen_to_C_GtkLabel_(label)))); } static Xen gxg_gtk_progress_bar_set_ellipsize(Xen pbar, Xen mode) { #define H_gtk_progress_bar_set_ellipsize "void gtk_progress_bar_set_ellipsize(GtkProgressBar* pbar, \ PangoEllipsizeMode mode)" Xen_check_type(Xen_is_GtkProgressBar_(pbar), pbar, 1, "gtk_progress_bar_set_ellipsize", "GtkProgressBar*"); Xen_check_type(Xen_is_PangoEllipsizeMode(mode), mode, 2, "gtk_progress_bar_set_ellipsize", "PangoEllipsizeMode"); gtk_progress_bar_set_ellipsize(Xen_to_C_GtkProgressBar_(pbar), Xen_to_C_PangoEllipsizeMode(mode)); return(Xen_false); } static Xen gxg_gtk_progress_bar_get_ellipsize(Xen pbar) { #define H_gtk_progress_bar_get_ellipsize "PangoEllipsizeMode gtk_progress_bar_get_ellipsize(GtkProgressBar* pbar)" Xen_check_type(Xen_is_GtkProgressBar_(pbar), pbar, 1, "gtk_progress_bar_get_ellipsize", "GtkProgressBar*"); return(C_to_Xen_PangoEllipsizeMode(gtk_progress_bar_get_ellipsize(Xen_to_C_GtkProgressBar_(pbar)))); } static Xen gxg_gtk_selection_data_targets_include_image(Xen selection_data, Xen writable) { #define H_gtk_selection_data_targets_include_image "gboolean gtk_selection_data_targets_include_image(GtkSelectionData* selection_data, \ gboolean writable)" Xen_check_type(Xen_is_GtkSelectionData_(selection_data), selection_data, 1, "gtk_selection_data_targets_include_image", "GtkSelectionData*"); Xen_check_type(Xen_is_gboolean(writable), writable, 2, "gtk_selection_data_targets_include_image", "gboolean"); return(C_to_Xen_gboolean(gtk_selection_data_targets_include_image(Xen_to_C_GtkSelectionData_(selection_data), Xen_to_C_gboolean(writable)))); } static Xen gxg_gtk_button_set_image(Xen button, Xen image) { #define H_gtk_button_set_image "void gtk_button_set_image(GtkButton* button, GtkWidget* image)" Xen_check_type(Xen_is_GtkButton_(button), button, 1, "gtk_button_set_image", "GtkButton*"); Xen_check_type(Xen_is_GtkWidget_(image), image, 2, "gtk_button_set_image", "GtkWidget*"); gtk_button_set_image(Xen_to_C_GtkButton_(button), Xen_to_C_GtkWidget_(image)); return(Xen_false); } static Xen gxg_gtk_button_get_image(Xen button) { #define H_gtk_button_get_image "GtkWidget* gtk_button_get_image(GtkButton* button)" Xen_check_type(Xen_is_GtkButton_(button), button, 1, "gtk_button_get_image", "GtkButton*"); return(C_to_Xen_GtkWidget_(gtk_button_get_image(Xen_to_C_GtkButton_(button)))); } static Xen gxg_gtk_label_set_angle(Xen label, Xen angle) { #define H_gtk_label_set_angle "void gtk_label_set_angle(GtkLabel* label, gdouble angle)" Xen_check_type(Xen_is_GtkLabel_(label), label, 1, "gtk_label_set_angle", "GtkLabel*"); Xen_check_type(Xen_is_gdouble(angle), angle, 2, "gtk_label_set_angle", "gdouble"); gtk_label_set_angle(Xen_to_C_GtkLabel_(label), Xen_to_C_gdouble(angle)); return(Xen_false); } static Xen gxg_gtk_label_get_angle(Xen label) { #define H_gtk_label_get_angle "gdouble gtk_label_get_angle(GtkLabel* label)" Xen_check_type(Xen_is_GtkLabel_(label), label, 1, "gtk_label_get_angle", "GtkLabel*"); return(C_to_Xen_gdouble(gtk_label_get_angle(Xen_to_C_GtkLabel_(label)))); } static Xen gxg_gtk_menu_set_screen(Xen menu, Xen screen) { #define H_gtk_menu_set_screen "void gtk_menu_set_screen(GtkMenu* menu, GdkScreen* screen)" Xen_check_type(Xen_is_GtkMenu_(menu), menu, 1, "gtk_menu_set_screen", "GtkMenu*"); Xen_check_type(Xen_is_GdkScreen_(screen) || Xen_is_false(screen), screen, 2, "gtk_menu_set_screen", "GdkScreen*"); gtk_menu_set_screen(Xen_to_C_GtkMenu_(menu), Xen_to_C_GdkScreen_(screen)); return(Xen_false); } static Xen gxg_pango_attr_underline_color_new(Xen red, Xen green, Xen blue) { #define H_pango_attr_underline_color_new "PangoAttribute* pango_attr_underline_color_new(guint16 red, \ guint16 green, guint16 blue)" Xen_check_type(Xen_is_guint16(red), red, 1, "pango_attr_underline_color_new", "guint16"); Xen_check_type(Xen_is_guint16(green), green, 2, "pango_attr_underline_color_new", "guint16"); Xen_check_type(Xen_is_guint16(blue), blue, 3, "pango_attr_underline_color_new", "guint16"); return(C_to_Xen_PangoAttribute_(pango_attr_underline_color_new(Xen_to_C_guint16(red), Xen_to_C_guint16(green), Xen_to_C_guint16(blue)))); } static Xen gxg_pango_attr_strikethrough_color_new(Xen red, Xen green, Xen blue) { #define H_pango_attr_strikethrough_color_new "PangoAttribute* pango_attr_strikethrough_color_new(guint16 red, \ guint16 green, guint16 blue)" Xen_check_type(Xen_is_guint16(red), red, 1, "pango_attr_strikethrough_color_new", "guint16"); Xen_check_type(Xen_is_guint16(green), green, 2, "pango_attr_strikethrough_color_new", "guint16"); Xen_check_type(Xen_is_guint16(blue), blue, 3, "pango_attr_strikethrough_color_new", "guint16"); return(C_to_Xen_PangoAttribute_(pango_attr_strikethrough_color_new(Xen_to_C_guint16(red), Xen_to_C_guint16(green), Xen_to_C_guint16(blue)))); } static Xen gxg_pango_renderer_draw_layout(Xen renderer, Xen layout, Xen x, Xen y) { #define H_pango_renderer_draw_layout "void pango_renderer_draw_layout(PangoRenderer* renderer, PangoLayout* layout, \ int x, int y)" Xen_check_type(Xen_is_PangoRenderer_(renderer), renderer, 1, "pango_renderer_draw_layout", "PangoRenderer*"); Xen_check_type(Xen_is_PangoLayout_(layout), layout, 2, "pango_renderer_draw_layout", "PangoLayout*"); Xen_check_type(Xen_is_int(x), x, 3, "pango_renderer_draw_layout", "int"); Xen_check_type(Xen_is_int(y), y, 4, "pango_renderer_draw_layout", "int"); pango_renderer_draw_layout(Xen_to_C_PangoRenderer_(renderer), Xen_to_C_PangoLayout_(layout), Xen_to_C_int(x), Xen_to_C_int(y)); return(Xen_false); } static Xen gxg_pango_renderer_draw_layout_line(Xen renderer, Xen line, Xen x, Xen y) { #define H_pango_renderer_draw_layout_line "void pango_renderer_draw_layout_line(PangoRenderer* renderer, \ PangoLayoutLine* line, int x, int y)" Xen_check_type(Xen_is_PangoRenderer_(renderer), renderer, 1, "pango_renderer_draw_layout_line", "PangoRenderer*"); Xen_check_type(Xen_is_PangoLayoutLine_(line), line, 2, "pango_renderer_draw_layout_line", "PangoLayoutLine*"); Xen_check_type(Xen_is_int(x), x, 3, "pango_renderer_draw_layout_line", "int"); Xen_check_type(Xen_is_int(y), y, 4, "pango_renderer_draw_layout_line", "int"); pango_renderer_draw_layout_line(Xen_to_C_PangoRenderer_(renderer), Xen_to_C_PangoLayoutLine_(line), Xen_to_C_int(x), Xen_to_C_int(y)); return(Xen_false); } static Xen gxg_pango_renderer_draw_glyphs(Xen renderer, Xen font, Xen glyphs, Xen x, Xen y) { #define H_pango_renderer_draw_glyphs "void pango_renderer_draw_glyphs(PangoRenderer* renderer, PangoFont* font, \ PangoGlyphString* glyphs, int x, int y)" Xen_check_type(Xen_is_PangoRenderer_(renderer), renderer, 1, "pango_renderer_draw_glyphs", "PangoRenderer*"); Xen_check_type(Xen_is_PangoFont_(font), font, 2, "pango_renderer_draw_glyphs", "PangoFont*"); Xen_check_type(Xen_is_PangoGlyphString_(glyphs), glyphs, 3, "pango_renderer_draw_glyphs", "PangoGlyphString*"); Xen_check_type(Xen_is_int(x), x, 4, "pango_renderer_draw_glyphs", "int"); Xen_check_type(Xen_is_int(y), y, 5, "pango_renderer_draw_glyphs", "int"); pango_renderer_draw_glyphs(Xen_to_C_PangoRenderer_(renderer), Xen_to_C_PangoFont_(font), Xen_to_C_PangoGlyphString_(glyphs), Xen_to_C_int(x), Xen_to_C_int(y)); return(Xen_false); } static Xen gxg_pango_renderer_draw_rectangle(Xen renderer, Xen part, Xen x, Xen y, Xen width, Xen height) { #define H_pango_renderer_draw_rectangle "void pango_renderer_draw_rectangle(PangoRenderer* renderer, \ PangoRenderPart part, int x, int y, int width, int height)" Xen_check_type(Xen_is_PangoRenderer_(renderer), renderer, 1, "pango_renderer_draw_rectangle", "PangoRenderer*"); Xen_check_type(Xen_is_PangoRenderPart(part), part, 2, "pango_renderer_draw_rectangle", "PangoRenderPart"); Xen_check_type(Xen_is_int(x), x, 3, "pango_renderer_draw_rectangle", "int"); Xen_check_type(Xen_is_int(y), y, 4, "pango_renderer_draw_rectangle", "int"); Xen_check_type(Xen_is_int(width), width, 5, "pango_renderer_draw_rectangle", "int"); Xen_check_type(Xen_is_int(height), height, 6, "pango_renderer_draw_rectangle", "int"); pango_renderer_draw_rectangle(Xen_to_C_PangoRenderer_(renderer), Xen_to_C_PangoRenderPart(part), Xen_to_C_int(x), Xen_to_C_int(y), Xen_to_C_int(width), Xen_to_C_int(height)); return(Xen_false); } static Xen gxg_pango_renderer_draw_error_underline(Xen renderer, Xen x, Xen y, Xen width, Xen height) { #define H_pango_renderer_draw_error_underline "void pango_renderer_draw_error_underline(PangoRenderer* renderer, \ int x, int y, int width, int height)" Xen_check_type(Xen_is_PangoRenderer_(renderer), renderer, 1, "pango_renderer_draw_error_underline", "PangoRenderer*"); Xen_check_type(Xen_is_int(x), x, 2, "pango_renderer_draw_error_underline", "int"); Xen_check_type(Xen_is_int(y), y, 3, "pango_renderer_draw_error_underline", "int"); Xen_check_type(Xen_is_int(width), width, 4, "pango_renderer_draw_error_underline", "int"); Xen_check_type(Xen_is_int(height), height, 5, "pango_renderer_draw_error_underline", "int"); pango_renderer_draw_error_underline(Xen_to_C_PangoRenderer_(renderer), Xen_to_C_int(x), Xen_to_C_int(y), Xen_to_C_int(width), Xen_to_C_int(height)); return(Xen_false); } static Xen gxg_pango_renderer_draw_trapezoid(Xen arglist) { #define H_pango_renderer_draw_trapezoid "void pango_renderer_draw_trapezoid(PangoRenderer* renderer, \ PangoRenderPart part, double y1, double x11, double x21, double y2, double x12, double x22)" Xen renderer, part, y1, x11, x21, y2, x12, x22; renderer = Xen_list_ref(arglist, 0); part = Xen_list_ref(arglist, 1); y1 = Xen_list_ref(arglist, 2); x11 = Xen_list_ref(arglist, 3); x21 = Xen_list_ref(arglist, 4); y2 = Xen_list_ref(arglist, 5); x12 = Xen_list_ref(arglist, 6); x22 = Xen_list_ref(arglist, 7); Xen_check_type(Xen_is_PangoRenderer_(renderer), renderer, 1, "pango_renderer_draw_trapezoid", "PangoRenderer*"); Xen_check_type(Xen_is_PangoRenderPart(part), part, 2, "pango_renderer_draw_trapezoid", "PangoRenderPart"); Xen_check_type(Xen_is_double(y1), y1, 3, "pango_renderer_draw_trapezoid", "double"); Xen_check_type(Xen_is_double(x11), x11, 4, "pango_renderer_draw_trapezoid", "double"); Xen_check_type(Xen_is_double(x21), x21, 5, "pango_renderer_draw_trapezoid", "double"); Xen_check_type(Xen_is_double(y2), y2, 6, "pango_renderer_draw_trapezoid", "double"); Xen_check_type(Xen_is_double(x12), x12, 7, "pango_renderer_draw_trapezoid", "double"); Xen_check_type(Xen_is_double(x22), x22, 8, "pango_renderer_draw_trapezoid", "double"); pango_renderer_draw_trapezoid(Xen_to_C_PangoRenderer_(renderer), Xen_to_C_PangoRenderPart(part), Xen_to_C_double(y1), Xen_to_C_double(x11), Xen_to_C_double(x21), Xen_to_C_double(y2), Xen_to_C_double(x12), Xen_to_C_double(x22)); return(Xen_false); } static Xen gxg_pango_renderer_draw_glyph(Xen renderer, Xen font, Xen glyph, Xen x, Xen y) { #define H_pango_renderer_draw_glyph "void pango_renderer_draw_glyph(PangoRenderer* renderer, PangoFont* font, \ PangoGlyph glyph, double x, double y)" Xen_check_type(Xen_is_PangoRenderer_(renderer), renderer, 1, "pango_renderer_draw_glyph", "PangoRenderer*"); Xen_check_type(Xen_is_PangoFont_(font), font, 2, "pango_renderer_draw_glyph", "PangoFont*"); Xen_check_type(Xen_is_PangoGlyph(glyph), glyph, 3, "pango_renderer_draw_glyph", "PangoGlyph"); Xen_check_type(Xen_is_double(x), x, 4, "pango_renderer_draw_glyph", "double"); Xen_check_type(Xen_is_double(y), y, 5, "pango_renderer_draw_glyph", "double"); pango_renderer_draw_glyph(Xen_to_C_PangoRenderer_(renderer), Xen_to_C_PangoFont_(font), Xen_to_C_PangoGlyph(glyph), Xen_to_C_double(x), Xen_to_C_double(y)); return(Xen_false); } static Xen gxg_pango_renderer_activate(Xen renderer) { #define H_pango_renderer_activate "void pango_renderer_activate(PangoRenderer* renderer)" Xen_check_type(Xen_is_PangoRenderer_(renderer), renderer, 1, "pango_renderer_activate", "PangoRenderer*"); pango_renderer_activate(Xen_to_C_PangoRenderer_(renderer)); return(Xen_false); } static Xen gxg_pango_renderer_deactivate(Xen renderer) { #define H_pango_renderer_deactivate "void pango_renderer_deactivate(PangoRenderer* renderer)" Xen_check_type(Xen_is_PangoRenderer_(renderer), renderer, 1, "pango_renderer_deactivate", "PangoRenderer*"); pango_renderer_deactivate(Xen_to_C_PangoRenderer_(renderer)); return(Xen_false); } static Xen gxg_pango_renderer_part_changed(Xen renderer, Xen part) { #define H_pango_renderer_part_changed "void pango_renderer_part_changed(PangoRenderer* renderer, PangoRenderPart part)" Xen_check_type(Xen_is_PangoRenderer_(renderer), renderer, 1, "pango_renderer_part_changed", "PangoRenderer*"); Xen_check_type(Xen_is_PangoRenderPart(part), part, 2, "pango_renderer_part_changed", "PangoRenderPart"); pango_renderer_part_changed(Xen_to_C_PangoRenderer_(renderer), Xen_to_C_PangoRenderPart(part)); return(Xen_false); } static Xen gxg_pango_renderer_set_color(Xen renderer, Xen part, Xen color) { #define H_pango_renderer_set_color "void pango_renderer_set_color(PangoRenderer* renderer, PangoRenderPart part, \ PangoColor* color)" Xen_check_type(Xen_is_PangoRenderer_(renderer), renderer, 1, "pango_renderer_set_color", "PangoRenderer*"); Xen_check_type(Xen_is_PangoRenderPart(part), part, 2, "pango_renderer_set_color", "PangoRenderPart"); Xen_check_type(Xen_is_PangoColor_(color), color, 3, "pango_renderer_set_color", "PangoColor*"); pango_renderer_set_color(Xen_to_C_PangoRenderer_(renderer), Xen_to_C_PangoRenderPart(part), Xen_to_C_PangoColor_(color)); return(Xen_false); } static Xen gxg_pango_renderer_get_color(Xen renderer, Xen part) { #define H_pango_renderer_get_color "PangoColor* pango_renderer_get_color(PangoRenderer* renderer, PangoRenderPart part)" Xen_check_type(Xen_is_PangoRenderer_(renderer), renderer, 1, "pango_renderer_get_color", "PangoRenderer*"); Xen_check_type(Xen_is_PangoRenderPart(part), part, 2, "pango_renderer_get_color", "PangoRenderPart"); return(C_to_Xen_PangoColor_(pango_renderer_get_color(Xen_to_C_PangoRenderer_(renderer), Xen_to_C_PangoRenderPart(part)))); } static Xen gxg_pango_renderer_set_matrix(Xen renderer, Xen matrix) { #define H_pango_renderer_set_matrix "void pango_renderer_set_matrix(PangoRenderer* renderer, PangoMatrix* matrix)" Xen_check_type(Xen_is_PangoRenderer_(renderer), renderer, 1, "pango_renderer_set_matrix", "PangoRenderer*"); Xen_check_type(Xen_is_PangoMatrix_(matrix), matrix, 2, "pango_renderer_set_matrix", "PangoMatrix*"); pango_renderer_set_matrix(Xen_to_C_PangoRenderer_(renderer), Xen_to_C_PangoMatrix_(matrix)); return(Xen_false); } static Xen gxg_g_log_set_handler(Xen log_domain, Xen log_levels, Xen func, Xen func_info) { #define H_g_log_set_handler "guint g_log_set_handler(gchar* log_domain, GLogLevelFlags log_levels, \ GLogFunc func, lambda_data func_info)" Xen_check_type(Xen_is_gchar_(log_domain), log_domain, 1, "g_log_set_handler", "gchar*"); Xen_check_type(Xen_is_GLogLevelFlags(log_levels), log_levels, 2, "g_log_set_handler", "GLogLevelFlags"); Xen_check_type(Xen_is_GLogFunc(func), func, 3, "g_log_set_handler", "GLogFunc"); if (!Xen_is_bound(func_info)) func_info = Xen_false; else Xen_check_type(Xen_is_lambda_data(func_info), func_info, 4, "g_log_set_handler", "lambda_data"); { Xen result; Xen gxg_ptr = Xen_list_5(func, func_info, Xen_false, Xen_false, Xen_false); xm_protect(gxg_ptr); result = C_to_Xen_guint(g_log_set_handler(Xen_to_C_gchar_(log_domain), Xen_to_C_GLogLevelFlags(log_levels), Xen_to_C_GLogFunc(func), Xen_to_C_lambda_data(func_info))); return(result); } } static Xen gxg_g_log_remove_handler(Xen log_domain, Xen handler_id) { #define H_g_log_remove_handler "void g_log_remove_handler(gchar* log_domain, guint handler_id)" Xen_check_type(Xen_is_gchar_(log_domain), log_domain, 1, "g_log_remove_handler", "gchar*"); Xen_check_type(Xen_is_guint(handler_id), handler_id, 2, "g_log_remove_handler", "guint"); g_log_remove_handler(Xen_to_C_gchar_(log_domain), Xen_to_C_guint(handler_id)); return(Xen_false); } static Xen gxg_gtk_cell_renderer_stop_editing(Xen cell, Xen canceled) { #define H_gtk_cell_renderer_stop_editing "void gtk_cell_renderer_stop_editing(GtkCellRenderer* cell, \ gboolean canceled)" Xen_check_type(Xen_is_GtkCellRenderer_(cell), cell, 1, "gtk_cell_renderer_stop_editing", "GtkCellRenderer*"); Xen_check_type(Xen_is_gboolean(canceled), canceled, 2, "gtk_cell_renderer_stop_editing", "gboolean"); gtk_cell_renderer_stop_editing(Xen_to_C_GtkCellRenderer_(cell), Xen_to_C_gboolean(canceled)); return(Xen_false); } static Xen gxg_gtk_file_chooser_button_new(Xen title, Xen action) { #define H_gtk_file_chooser_button_new "GtkWidget* gtk_file_chooser_button_new(gchar* title, GtkFileChooserAction action)" Xen_check_type(Xen_is_gchar_(title), title, 1, "gtk_file_chooser_button_new", "gchar*"); Xen_check_type(Xen_is_GtkFileChooserAction(action), action, 2, "gtk_file_chooser_button_new", "GtkFileChooserAction"); return(C_to_Xen_GtkWidget_(gtk_file_chooser_button_new((const gchar*)Xen_to_C_gchar_(title), Xen_to_C_GtkFileChooserAction(action)))); } static Xen gxg_gtk_icon_view_set_columns(Xen icon_view, Xen columns) { #define H_gtk_icon_view_set_columns "void gtk_icon_view_set_columns(GtkIconView* icon_view, gint columns)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_set_columns", "GtkIconView*"); Xen_check_type(Xen_is_gint(columns), columns, 2, "gtk_icon_view_set_columns", "gint"); gtk_icon_view_set_columns(Xen_to_C_GtkIconView_(icon_view), Xen_to_C_gint(columns)); return(Xen_false); } static Xen gxg_gtk_icon_view_get_columns(Xen icon_view) { #define H_gtk_icon_view_get_columns "gint gtk_icon_view_get_columns(GtkIconView* icon_view)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_get_columns", "GtkIconView*"); return(C_to_Xen_gint(gtk_icon_view_get_columns(Xen_to_C_GtkIconView_(icon_view)))); } static Xen gxg_gtk_icon_view_set_item_width(Xen icon_view, Xen item_width) { #define H_gtk_icon_view_set_item_width "void gtk_icon_view_set_item_width(GtkIconView* icon_view, gint item_width)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_set_item_width", "GtkIconView*"); Xen_check_type(Xen_is_gint(item_width), item_width, 2, "gtk_icon_view_set_item_width", "gint"); gtk_icon_view_set_item_width(Xen_to_C_GtkIconView_(icon_view), Xen_to_C_gint(item_width)); return(Xen_false); } static Xen gxg_gtk_icon_view_get_item_width(Xen icon_view) { #define H_gtk_icon_view_get_item_width "gint gtk_icon_view_get_item_width(GtkIconView* icon_view)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_get_item_width", "GtkIconView*"); return(C_to_Xen_gint(gtk_icon_view_get_item_width(Xen_to_C_GtkIconView_(icon_view)))); } static Xen gxg_gtk_icon_view_set_spacing(Xen icon_view, Xen spacing) { #define H_gtk_icon_view_set_spacing "void gtk_icon_view_set_spacing(GtkIconView* icon_view, gint spacing)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_set_spacing", "GtkIconView*"); Xen_check_type(Xen_is_gint(spacing), spacing, 2, "gtk_icon_view_set_spacing", "gint"); gtk_icon_view_set_spacing(Xen_to_C_GtkIconView_(icon_view), Xen_to_C_gint(spacing)); return(Xen_false); } static Xen gxg_gtk_icon_view_get_spacing(Xen icon_view) { #define H_gtk_icon_view_get_spacing "gint gtk_icon_view_get_spacing(GtkIconView* icon_view)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_get_spacing", "GtkIconView*"); return(C_to_Xen_gint(gtk_icon_view_get_spacing(Xen_to_C_GtkIconView_(icon_view)))); } static Xen gxg_gtk_icon_view_set_row_spacing(Xen icon_view, Xen row_spacing) { #define H_gtk_icon_view_set_row_spacing "void gtk_icon_view_set_row_spacing(GtkIconView* icon_view, \ gint row_spacing)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_set_row_spacing", "GtkIconView*"); Xen_check_type(Xen_is_gint(row_spacing), row_spacing, 2, "gtk_icon_view_set_row_spacing", "gint"); gtk_icon_view_set_row_spacing(Xen_to_C_GtkIconView_(icon_view), Xen_to_C_gint(row_spacing)); return(Xen_false); } static Xen gxg_gtk_icon_view_get_row_spacing(Xen icon_view) { #define H_gtk_icon_view_get_row_spacing "gint gtk_icon_view_get_row_spacing(GtkIconView* icon_view)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_get_row_spacing", "GtkIconView*"); return(C_to_Xen_gint(gtk_icon_view_get_row_spacing(Xen_to_C_GtkIconView_(icon_view)))); } static Xen gxg_gtk_icon_view_set_column_spacing(Xen icon_view, Xen column_spacing) { #define H_gtk_icon_view_set_column_spacing "void gtk_icon_view_set_column_spacing(GtkIconView* icon_view, \ gint column_spacing)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_set_column_spacing", "GtkIconView*"); Xen_check_type(Xen_is_gint(column_spacing), column_spacing, 2, "gtk_icon_view_set_column_spacing", "gint"); gtk_icon_view_set_column_spacing(Xen_to_C_GtkIconView_(icon_view), Xen_to_C_gint(column_spacing)); return(Xen_false); } static Xen gxg_gtk_icon_view_get_column_spacing(Xen icon_view) { #define H_gtk_icon_view_get_column_spacing "gint gtk_icon_view_get_column_spacing(GtkIconView* icon_view)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_get_column_spacing", "GtkIconView*"); return(C_to_Xen_gint(gtk_icon_view_get_column_spacing(Xen_to_C_GtkIconView_(icon_view)))); } static Xen gxg_gtk_icon_view_set_margin(Xen icon_view, Xen margin) { #define H_gtk_icon_view_set_margin "void gtk_icon_view_set_margin(GtkIconView* icon_view, gint margin)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_set_margin", "GtkIconView*"); Xen_check_type(Xen_is_gint(margin), margin, 2, "gtk_icon_view_set_margin", "gint"); gtk_icon_view_set_margin(Xen_to_C_GtkIconView_(icon_view), Xen_to_C_gint(margin)); return(Xen_false); } static Xen gxg_gtk_icon_view_get_margin(Xen icon_view) { #define H_gtk_icon_view_get_margin "gint gtk_icon_view_get_margin(GtkIconView* icon_view)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_get_margin", "GtkIconView*"); return(C_to_Xen_gint(gtk_icon_view_get_margin(Xen_to_C_GtkIconView_(icon_view)))); } static Xen gxg_gtk_label_set_max_width_chars(Xen label, Xen n_chars) { #define H_gtk_label_set_max_width_chars "void gtk_label_set_max_width_chars(GtkLabel* label, gint n_chars)" Xen_check_type(Xen_is_GtkLabel_(label), label, 1, "gtk_label_set_max_width_chars", "GtkLabel*"); Xen_check_type(Xen_is_gint(n_chars), n_chars, 2, "gtk_label_set_max_width_chars", "gint"); gtk_label_set_max_width_chars(Xen_to_C_GtkLabel_(label), Xen_to_C_gint(n_chars)); return(Xen_false); } static Xen gxg_gtk_label_get_max_width_chars(Xen label) { #define H_gtk_label_get_max_width_chars "gint gtk_label_get_max_width_chars(GtkLabel* label)" Xen_check_type(Xen_is_GtkLabel_(label), label, 1, "gtk_label_get_max_width_chars", "GtkLabel*"); return(C_to_Xen_gint(gtk_label_get_max_width_chars(Xen_to_C_GtkLabel_(label)))); } static Xen gxg_gtk_list_store_insert_with_values(Xen list_store, Xen iter, Xen position) { #define H_gtk_list_store_insert_with_values "void gtk_list_store_insert_with_values(GtkListStore* list_store, \ GtkTreeIter* iter, gint position, ...)" Xen_check_type(Xen_is_GtkListStore_(list_store), list_store, 1, "gtk_list_store_insert_with_values", "GtkListStore*"); Xen_check_type(Xen_is_GtkTreeIter_(iter), iter, 2, "gtk_list_store_insert_with_values", "GtkTreeIter*"); Xen_check_type(Xen_is_gint(position), position, 3, "gtk_list_store_insert_with_values", "gint"); gtk_list_store_insert_with_values(Xen_to_C_GtkListStore_(list_store), Xen_to_C_GtkTreeIter_(iter), Xen_to_C_gint(position)); return(Xen_false); } static Xen gxg_gtk_list_store_insert_with_valuesv(Xen list_store, Xen iter, Xen position, Xen columns, Xen values, Xen n_values) { #define H_gtk_list_store_insert_with_valuesv "void gtk_list_store_insert_with_valuesv(GtkListStore* list_store, \ GtkTreeIter* iter, gint position, gint* columns, GValue* values, gint n_values)" Xen_check_type(Xen_is_GtkListStore_(list_store), list_store, 1, "gtk_list_store_insert_with_valuesv", "GtkListStore*"); Xen_check_type(Xen_is_GtkTreeIter_(iter), iter, 2, "gtk_list_store_insert_with_valuesv", "GtkTreeIter*"); Xen_check_type(Xen_is_gint(position), position, 3, "gtk_list_store_insert_with_valuesv", "gint"); Xen_check_type(Xen_is_gint_(columns), columns, 4, "gtk_list_store_insert_with_valuesv", "gint*"); Xen_check_type(Xen_is_GValue_(values), values, 5, "gtk_list_store_insert_with_valuesv", "GValue*"); Xen_check_type(Xen_is_gint(n_values), n_values, 6, "gtk_list_store_insert_with_valuesv", "gint"); gtk_list_store_insert_with_valuesv(Xen_to_C_GtkListStore_(list_store), Xen_to_C_GtkTreeIter_(iter), Xen_to_C_gint(position), Xen_to_C_gint_(columns), Xen_to_C_GValue_(values), Xen_to_C_gint(n_values)); return(Xen_false); } static Xen gxg_gtk_text_view_get_iter_at_position(Xen text_view, Xen iter, Xen ignore_trailing, Xen x, Xen y) { #define H_gtk_text_view_get_iter_at_position "void gtk_text_view_get_iter_at_position(GtkTextView* text_view, \ GtkTextIter* iter, gint* [trailing], gint x, gint y)" gint ref_trailing; Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_get_iter_at_position", "GtkTextView*"); Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 2, "gtk_text_view_get_iter_at_position", "GtkTextIter*"); Xen_check_type(Xen_is_gint(x), x, 4, "gtk_text_view_get_iter_at_position", "gint"); Xen_check_type(Xen_is_gint(y), y, 5, "gtk_text_view_get_iter_at_position", "gint"); gtk_text_view_get_iter_at_position(Xen_to_C_GtkTextView_(text_view), Xen_to_C_GtkTextIter_(iter), &ref_trailing, Xen_to_C_gint(x), Xen_to_C_gint(y)); return(Xen_list_1(C_to_Xen_gint(ref_trailing))); } static Xen gxg_pango_attr_size_new_absolute(Xen size) { #define H_pango_attr_size_new_absolute "PangoAttribute* pango_attr_size_new_absolute(int size)" Xen_check_type(Xen_is_int(size), size, 1, "pango_attr_size_new_absolute", "int"); return(C_to_Xen_PangoAttribute_(pango_attr_size_new_absolute(Xen_to_C_int(size)))); } static Xen gxg_pango_font_description_set_absolute_size(Xen desc, Xen size) { #define H_pango_font_description_set_absolute_size "void pango_font_description_set_absolute_size(PangoFontDescription* desc, \ double size)" Xen_check_type(Xen_is_PangoFontDescription_(desc), desc, 1, "pango_font_description_set_absolute_size", "PangoFontDescription*"); Xen_check_type(Xen_is_double(size), size, 2, "pango_font_description_set_absolute_size", "double"); pango_font_description_set_absolute_size(Xen_to_C_PangoFontDescription_(desc), Xen_to_C_double(size)); return(Xen_false); } static Xen gxg_pango_layout_get_font_description(Xen layout) { #define H_pango_layout_get_font_description "PangoFontDescription* pango_layout_get_font_description(PangoLayout* layout)" Xen_check_type(Xen_is_PangoLayout_(layout), layout, 1, "pango_layout_get_font_description", "PangoLayout*"); return(C_to_Xen_PangoFontDescription_((PangoFontDescription*)pango_layout_get_font_description(Xen_to_C_PangoLayout_(layout)))); } static Xen gxg_gdk_cursor_new_from_name(Xen display, Xen name) { #define H_gdk_cursor_new_from_name "GdkCursor* gdk_cursor_new_from_name(GdkDisplay* display, gchar* name)" Xen_check_type(Xen_is_GdkDisplay_(display), display, 1, "gdk_cursor_new_from_name", "GdkDisplay*"); Xen_check_type(Xen_is_gchar_(name), name, 2, "gdk_cursor_new_from_name", "gchar*"); return(C_to_Xen_GdkCursor_(gdk_cursor_new_from_name(Xen_to_C_GdkDisplay_(display), (const gchar*)Xen_to_C_gchar_(name)))); } static Xen gxg_gdk_cursor_get_image(Xen cursor) { #define H_gdk_cursor_get_image "GdkPixbuf* gdk_cursor_get_image(GdkCursor* cursor)" Xen_check_type(Xen_is_GdkCursor_(cursor), cursor, 1, "gdk_cursor_get_image", "GdkCursor*"); return(C_to_Xen_GdkPixbuf_(gdk_cursor_get_image(Xen_to_C_GdkCursor_(cursor)))); } static Xen gxg_gdk_screen_get_rgba_visual(Xen screen) { #define H_gdk_screen_get_rgba_visual "GdkVisual* gdk_screen_get_rgba_visual(GdkScreen* screen)" Xen_check_type(Xen_is_GdkScreen_(screen), screen, 1, "gdk_screen_get_rgba_visual", "GdkScreen*"); return(C_to_Xen_GdkVisual_(gdk_screen_get_rgba_visual(Xen_to_C_GdkScreen_(screen)))); } static Xen gxg_gdk_window_set_urgency_hint(Xen window, Xen urgent) { #define H_gdk_window_set_urgency_hint "void gdk_window_set_urgency_hint(GdkWindow* window, gboolean urgent)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_set_urgency_hint", "GdkWindow*"); Xen_check_type(Xen_is_gboolean(urgent), urgent, 2, "gdk_window_set_urgency_hint", "gboolean"); gdk_window_set_urgency_hint(Xen_to_C_GdkWindow_(window), Xen_to_C_gboolean(urgent)); return(Xen_false); } static Xen gxg_gtk_dialog_get_response_for_widget(Xen dialog, Xen widget) { #define H_gtk_dialog_get_response_for_widget "gint gtk_dialog_get_response_for_widget(GtkDialog* dialog, \ GtkWidget* widget)" Xen_check_type(Xen_is_GtkDialog_(dialog), dialog, 1, "gtk_dialog_get_response_for_widget", "GtkDialog*"); Xen_check_type(Xen_is_GtkWidget_(widget), widget, 2, "gtk_dialog_get_response_for_widget", "GtkWidget*"); return(C_to_Xen_gint(gtk_dialog_get_response_for_widget(Xen_to_C_GtkDialog_(dialog), Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_drag_source_set_icon_name(Xen widget, Xen icon_name) { #define H_gtk_drag_source_set_icon_name "void gtk_drag_source_set_icon_name(GtkWidget* widget, gchar* icon_name)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_drag_source_set_icon_name", "GtkWidget*"); Xen_check_type(Xen_is_gchar_(icon_name), icon_name, 2, "gtk_drag_source_set_icon_name", "gchar*"); gtk_drag_source_set_icon_name(Xen_to_C_GtkWidget_(widget), (const gchar*)Xen_to_C_gchar_(icon_name)); return(Xen_false); } static Xen gxg_gtk_drag_set_icon_name(Xen context, Xen icon_name, Xen hot_x, Xen hot_y) { #define H_gtk_drag_set_icon_name "void gtk_drag_set_icon_name(GdkDragContext* context, gchar* icon_name, \ gint hot_x, gint hot_y)" Xen_check_type(Xen_is_GdkDragContext_(context), context, 1, "gtk_drag_set_icon_name", "GdkDragContext*"); Xen_check_type(Xen_is_gchar_(icon_name), icon_name, 2, "gtk_drag_set_icon_name", "gchar*"); Xen_check_type(Xen_is_gint(hot_x), hot_x, 3, "gtk_drag_set_icon_name", "gint"); Xen_check_type(Xen_is_gint(hot_y), hot_y, 4, "gtk_drag_set_icon_name", "gint"); gtk_drag_set_icon_name(Xen_to_C_GdkDragContext_(context), (const gchar*)Xen_to_C_gchar_(icon_name), Xen_to_C_gint(hot_x), Xen_to_C_gint(hot_y)); return(Xen_false); } static Xen gxg_gtk_entry_completion_set_popup_set_width(Xen completion, Xen popup_set_width) { #define H_gtk_entry_completion_set_popup_set_width "void gtk_entry_completion_set_popup_set_width(GtkEntryCompletion* completion, \ gboolean popup_set_width)" Xen_check_type(Xen_is_GtkEntryCompletion_(completion), completion, 1, "gtk_entry_completion_set_popup_set_width", "GtkEntryCompletion*"); Xen_check_type(Xen_is_gboolean(popup_set_width), popup_set_width, 2, "gtk_entry_completion_set_popup_set_width", "gboolean"); gtk_entry_completion_set_popup_set_width(Xen_to_C_GtkEntryCompletion_(completion), Xen_to_C_gboolean(popup_set_width)); return(Xen_false); } static Xen gxg_gtk_entry_completion_get_popup_set_width(Xen completion) { #define H_gtk_entry_completion_get_popup_set_width "gboolean gtk_entry_completion_get_popup_set_width(GtkEntryCompletion* completion)" Xen_check_type(Xen_is_GtkEntryCompletion_(completion), completion, 1, "gtk_entry_completion_get_popup_set_width", "GtkEntryCompletion*"); return(C_to_Xen_gboolean(gtk_entry_completion_get_popup_set_width(Xen_to_C_GtkEntryCompletion_(completion)))); } static Xen gxg_gtk_entry_completion_set_popup_single_match(Xen completion, Xen popup_single_match) { #define H_gtk_entry_completion_set_popup_single_match "void gtk_entry_completion_set_popup_single_match(GtkEntryCompletion* completion, \ gboolean popup_single_match)" Xen_check_type(Xen_is_GtkEntryCompletion_(completion), completion, 1, "gtk_entry_completion_set_popup_single_match", "GtkEntryCompletion*"); Xen_check_type(Xen_is_gboolean(popup_single_match), popup_single_match, 2, "gtk_entry_completion_set_popup_single_match", "gboolean"); gtk_entry_completion_set_popup_single_match(Xen_to_C_GtkEntryCompletion_(completion), Xen_to_C_gboolean(popup_single_match)); return(Xen_false); } static Xen gxg_gtk_entry_completion_get_popup_single_match(Xen completion) { #define H_gtk_entry_completion_get_popup_single_match "gboolean gtk_entry_completion_get_popup_single_match(GtkEntryCompletion* completion)" Xen_check_type(Xen_is_GtkEntryCompletion_(completion), completion, 1, "gtk_entry_completion_get_popup_single_match", "GtkEntryCompletion*"); return(C_to_Xen_gboolean(gtk_entry_completion_get_popup_single_match(Xen_to_C_GtkEntryCompletion_(completion)))); } static Xen gxg_gtk_icon_view_get_item_at_pos(Xen icon_view, Xen x, Xen y, Xen ignore_path, Xen ignore_cell) { #define H_gtk_icon_view_get_item_at_pos "gboolean gtk_icon_view_get_item_at_pos(GtkIconView* icon_view, \ gint x, gint y, GtkTreePath** [path], GtkCellRenderer** [cell])" GtkTreePath* ref_path = NULL; GtkCellRenderer* ref_cell = NULL; Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_get_item_at_pos", "GtkIconView*"); Xen_check_type(Xen_is_gint(x), x, 2, "gtk_icon_view_get_item_at_pos", "gint"); Xen_check_type(Xen_is_gint(y), y, 3, "gtk_icon_view_get_item_at_pos", "gint"); { Xen result; result = C_to_Xen_gboolean(gtk_icon_view_get_item_at_pos(Xen_to_C_GtkIconView_(icon_view), Xen_to_C_gint(x), Xen_to_C_gint(y), &ref_path, &ref_cell)); return(Xen_list_3(result, C_to_Xen_GtkTreePath_(ref_path), C_to_Xen_GtkCellRenderer_(ref_cell))); } } static Xen gxg_gtk_icon_view_get_visible_range(Xen icon_view, Xen ignore_start_path, Xen ignore_end_path) { #define H_gtk_icon_view_get_visible_range "gboolean gtk_icon_view_get_visible_range(GtkIconView* icon_view, \ GtkTreePath** [start_path], GtkTreePath** [end_path])" GtkTreePath* ref_start_path = NULL; GtkTreePath* ref_end_path = NULL; Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_get_visible_range", "GtkIconView*"); { Xen result; result = C_to_Xen_gboolean(gtk_icon_view_get_visible_range(Xen_to_C_GtkIconView_(icon_view), &ref_start_path, &ref_end_path)); return(Xen_list_3(result, C_to_Xen_GtkTreePath_(ref_start_path), C_to_Xen_GtkTreePath_(ref_end_path))); } } static Xen gxg_gtk_icon_view_set_cursor(Xen icon_view, Xen path, Xen cell, Xen start_editing) { #define H_gtk_icon_view_set_cursor "void gtk_icon_view_set_cursor(GtkIconView* icon_view, GtkTreePath* path, \ GtkCellRenderer* cell, gboolean start_editing)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_set_cursor", "GtkIconView*"); Xen_check_type(Xen_is_GtkTreePath_(path), path, 2, "gtk_icon_view_set_cursor", "GtkTreePath*"); Xen_check_type(Xen_is_GtkCellRenderer_(cell), cell, 3, "gtk_icon_view_set_cursor", "GtkCellRenderer*"); Xen_check_type(Xen_is_gboolean(start_editing), start_editing, 4, "gtk_icon_view_set_cursor", "gboolean"); gtk_icon_view_set_cursor(Xen_to_C_GtkIconView_(icon_view), Xen_to_C_GtkTreePath_(path), Xen_to_C_GtkCellRenderer_(cell), Xen_to_C_gboolean(start_editing)); return(Xen_false); } static Xen gxg_gtk_icon_view_get_cursor(Xen icon_view, Xen ignore_path, Xen ignore_cell) { #define H_gtk_icon_view_get_cursor "gboolean gtk_icon_view_get_cursor(GtkIconView* icon_view, GtkTreePath** [path], \ GtkCellRenderer** [cell])" GtkTreePath* ref_path = NULL; GtkCellRenderer* ref_cell = NULL; Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_get_cursor", "GtkIconView*"); { Xen result; result = C_to_Xen_gboolean(gtk_icon_view_get_cursor(Xen_to_C_GtkIconView_(icon_view), &ref_path, &ref_cell)); return(Xen_list_3(result, C_to_Xen_GtkTreePath_(ref_path), C_to_Xen_GtkCellRenderer_(ref_cell))); } } static Xen gxg_gtk_icon_view_scroll_to_path(Xen icon_view, Xen path, Xen use_align, Xen row_align, Xen col_align) { #define H_gtk_icon_view_scroll_to_path "void gtk_icon_view_scroll_to_path(GtkIconView* icon_view, GtkTreePath* path, \ gboolean use_align, gfloat row_align, gfloat col_align)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_scroll_to_path", "GtkIconView*"); Xen_check_type(Xen_is_GtkTreePath_(path), path, 2, "gtk_icon_view_scroll_to_path", "GtkTreePath*"); Xen_check_type(Xen_is_gboolean(use_align), use_align, 3, "gtk_icon_view_scroll_to_path", "gboolean"); Xen_check_type(Xen_is_gfloat(row_align), row_align, 4, "gtk_icon_view_scroll_to_path", "gfloat"); Xen_check_type(Xen_is_gfloat(col_align), col_align, 5, "gtk_icon_view_scroll_to_path", "gfloat"); gtk_icon_view_scroll_to_path(Xen_to_C_GtkIconView_(icon_view), Xen_to_C_GtkTreePath_(path), Xen_to_C_gboolean(use_align), Xen_to_C_gfloat(row_align), Xen_to_C_gfloat(col_align)); return(Xen_false); } static Xen gxg_gtk_icon_view_enable_model_drag_source(Xen icon_view, Xen start_button_mask, Xen targets, Xen n_targets, Xen actions) { #define H_gtk_icon_view_enable_model_drag_source "void gtk_icon_view_enable_model_drag_source(GtkIconView* icon_view, \ GdkModifierType start_button_mask, GtkTargetEntry* targets, gint n_targets, GdkDragAction actions)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_enable_model_drag_source", "GtkIconView*"); Xen_check_type(Xen_is_GdkModifierType(start_button_mask), start_button_mask, 2, "gtk_icon_view_enable_model_drag_source", "GdkModifierType"); Xen_check_type(Xen_is_GtkTargetEntry_(targets), targets, 3, "gtk_icon_view_enable_model_drag_source", "GtkTargetEntry*"); Xen_check_type(Xen_is_gint(n_targets), n_targets, 4, "gtk_icon_view_enable_model_drag_source", "gint"); Xen_check_type(Xen_is_GdkDragAction(actions), actions, 5, "gtk_icon_view_enable_model_drag_source", "GdkDragAction"); gtk_icon_view_enable_model_drag_source(Xen_to_C_GtkIconView_(icon_view), Xen_to_C_GdkModifierType(start_button_mask), Xen_to_C_GtkTargetEntry_(targets), Xen_to_C_gint(n_targets), Xen_to_C_GdkDragAction(actions)); return(Xen_false); } static Xen gxg_gtk_icon_view_enable_model_drag_dest(Xen icon_view, Xen targets, Xen n_targets, Xen actions) { #define H_gtk_icon_view_enable_model_drag_dest "void gtk_icon_view_enable_model_drag_dest(GtkIconView* icon_view, \ GtkTargetEntry* targets, gint n_targets, GdkDragAction actions)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_enable_model_drag_dest", "GtkIconView*"); Xen_check_type(Xen_is_GtkTargetEntry_(targets), targets, 2, "gtk_icon_view_enable_model_drag_dest", "GtkTargetEntry*"); Xen_check_type(Xen_is_gint(n_targets), n_targets, 3, "gtk_icon_view_enable_model_drag_dest", "gint"); Xen_check_type(Xen_is_GdkDragAction(actions), actions, 4, "gtk_icon_view_enable_model_drag_dest", "GdkDragAction"); gtk_icon_view_enable_model_drag_dest(Xen_to_C_GtkIconView_(icon_view), Xen_to_C_GtkTargetEntry_(targets), Xen_to_C_gint(n_targets), Xen_to_C_GdkDragAction(actions)); return(Xen_false); } static Xen gxg_gtk_icon_view_unset_model_drag_source(Xen icon_view) { #define H_gtk_icon_view_unset_model_drag_source "void gtk_icon_view_unset_model_drag_source(GtkIconView* icon_view)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_unset_model_drag_source", "GtkIconView*"); gtk_icon_view_unset_model_drag_source(Xen_to_C_GtkIconView_(icon_view)); return(Xen_false); } static Xen gxg_gtk_icon_view_unset_model_drag_dest(Xen icon_view) { #define H_gtk_icon_view_unset_model_drag_dest "void gtk_icon_view_unset_model_drag_dest(GtkIconView* icon_view)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_unset_model_drag_dest", "GtkIconView*"); gtk_icon_view_unset_model_drag_dest(Xen_to_C_GtkIconView_(icon_view)); return(Xen_false); } static Xen gxg_gtk_icon_view_set_reorderable(Xen icon_view, Xen reorderable) { #define H_gtk_icon_view_set_reorderable "void gtk_icon_view_set_reorderable(GtkIconView* icon_view, \ gboolean reorderable)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_set_reorderable", "GtkIconView*"); Xen_check_type(Xen_is_gboolean(reorderable), reorderable, 2, "gtk_icon_view_set_reorderable", "gboolean"); gtk_icon_view_set_reorderable(Xen_to_C_GtkIconView_(icon_view), Xen_to_C_gboolean(reorderable)); return(Xen_false); } static Xen gxg_gtk_icon_view_get_reorderable(Xen icon_view) { #define H_gtk_icon_view_get_reorderable "gboolean gtk_icon_view_get_reorderable(GtkIconView* icon_view)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_get_reorderable", "GtkIconView*"); return(C_to_Xen_gboolean(gtk_icon_view_get_reorderable(Xen_to_C_GtkIconView_(icon_view)))); } static Xen gxg_gtk_icon_view_set_drag_dest_item(Xen icon_view, Xen path, Xen pos) { #define H_gtk_icon_view_set_drag_dest_item "void gtk_icon_view_set_drag_dest_item(GtkIconView* icon_view, \ GtkTreePath* path, GtkIconViewDropPosition pos)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_set_drag_dest_item", "GtkIconView*"); Xen_check_type(Xen_is_GtkTreePath_(path), path, 2, "gtk_icon_view_set_drag_dest_item", "GtkTreePath*"); Xen_check_type(Xen_is_GtkIconViewDropPosition(pos), pos, 3, "gtk_icon_view_set_drag_dest_item", "GtkIconViewDropPosition"); gtk_icon_view_set_drag_dest_item(Xen_to_C_GtkIconView_(icon_view), Xen_to_C_GtkTreePath_(path), Xen_to_C_GtkIconViewDropPosition(pos)); return(Xen_false); } static Xen gxg_gtk_icon_view_get_drag_dest_item(Xen icon_view, Xen ignore_path, Xen ignore_pos) { #define H_gtk_icon_view_get_drag_dest_item "void gtk_icon_view_get_drag_dest_item(GtkIconView* icon_view, \ GtkTreePath** [path], GtkIconViewDropPosition* [pos])" GtkTreePath* ref_path = NULL; GtkIconViewDropPosition ref_pos; Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_get_drag_dest_item", "GtkIconView*"); gtk_icon_view_get_drag_dest_item(Xen_to_C_GtkIconView_(icon_view), &ref_path, &ref_pos); return(Xen_list_2(C_to_Xen_GtkTreePath_(ref_path), C_to_Xen_GtkIconViewDropPosition(ref_pos))); } static Xen gxg_gtk_icon_view_get_dest_item_at_pos(Xen icon_view, Xen drag_x, Xen drag_y, Xen ignore_path, Xen ignore_pos) { #define H_gtk_icon_view_get_dest_item_at_pos "gboolean gtk_icon_view_get_dest_item_at_pos(GtkIconView* icon_view, \ gint drag_x, gint drag_y, GtkTreePath** [path], GtkIconViewDropPosition* [pos])" GtkTreePath* ref_path = NULL; GtkIconViewDropPosition ref_pos; Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_get_dest_item_at_pos", "GtkIconView*"); Xen_check_type(Xen_is_gint(drag_x), drag_x, 2, "gtk_icon_view_get_dest_item_at_pos", "gint"); Xen_check_type(Xen_is_gint(drag_y), drag_y, 3, "gtk_icon_view_get_dest_item_at_pos", "gint"); { Xen result; result = C_to_Xen_gboolean(gtk_icon_view_get_dest_item_at_pos(Xen_to_C_GtkIconView_(icon_view), Xen_to_C_gint(drag_x), Xen_to_C_gint(drag_y), &ref_path, &ref_pos)); return(Xen_list_3(result, C_to_Xen_GtkTreePath_(ref_path), C_to_Xen_GtkIconViewDropPosition(ref_pos))); } } static Xen gxg_gtk_image_clear(Xen image) { #define H_gtk_image_clear "void gtk_image_clear(GtkImage* image)" Xen_check_type(Xen_is_GtkImage_(image), image, 1, "gtk_image_clear", "GtkImage*"); gtk_image_clear(Xen_to_C_GtkImage_(image)); return(Xen_false); } static Xen gxg_gtk_menu_bar_get_pack_direction(Xen menubar) { #define H_gtk_menu_bar_get_pack_direction "GtkPackDirection gtk_menu_bar_get_pack_direction(GtkMenuBar* menubar)" Xen_check_type(Xen_is_GtkMenuBar_(menubar), menubar, 1, "gtk_menu_bar_get_pack_direction", "GtkMenuBar*"); return(C_to_Xen_GtkPackDirection(gtk_menu_bar_get_pack_direction(Xen_to_C_GtkMenuBar_(menubar)))); } static Xen gxg_gtk_menu_bar_set_pack_direction(Xen menubar, Xen pack_dir) { #define H_gtk_menu_bar_set_pack_direction "void gtk_menu_bar_set_pack_direction(GtkMenuBar* menubar, \ GtkPackDirection pack_dir)" Xen_check_type(Xen_is_GtkMenuBar_(menubar), menubar, 1, "gtk_menu_bar_set_pack_direction", "GtkMenuBar*"); Xen_check_type(Xen_is_GtkPackDirection(pack_dir), pack_dir, 2, "gtk_menu_bar_set_pack_direction", "GtkPackDirection"); gtk_menu_bar_set_pack_direction(Xen_to_C_GtkMenuBar_(menubar), Xen_to_C_GtkPackDirection(pack_dir)); return(Xen_false); } static Xen gxg_gtk_menu_bar_get_child_pack_direction(Xen menubar) { #define H_gtk_menu_bar_get_child_pack_direction "GtkPackDirection gtk_menu_bar_get_child_pack_direction(GtkMenuBar* menubar)" Xen_check_type(Xen_is_GtkMenuBar_(menubar), menubar, 1, "gtk_menu_bar_get_child_pack_direction", "GtkMenuBar*"); return(C_to_Xen_GtkPackDirection(gtk_menu_bar_get_child_pack_direction(Xen_to_C_GtkMenuBar_(menubar)))); } static Xen gxg_gtk_menu_bar_set_child_pack_direction(Xen menubar, Xen child_pack_dir) { #define H_gtk_menu_bar_set_child_pack_direction "void gtk_menu_bar_set_child_pack_direction(GtkMenuBar* menubar, \ GtkPackDirection child_pack_dir)" Xen_check_type(Xen_is_GtkMenuBar_(menubar), menubar, 1, "gtk_menu_bar_set_child_pack_direction", "GtkMenuBar*"); Xen_check_type(Xen_is_GtkPackDirection(child_pack_dir), child_pack_dir, 2, "gtk_menu_bar_set_child_pack_direction", "GtkPackDirection"); gtk_menu_bar_set_child_pack_direction(Xen_to_C_GtkMenuBar_(menubar), Xen_to_C_GtkPackDirection(child_pack_dir)); return(Xen_false); } static Xen gxg_gtk_menu_shell_get_take_focus(Xen menu_shell) { #define H_gtk_menu_shell_get_take_focus "gboolean gtk_menu_shell_get_take_focus(GtkMenuShell* menu_shell)" Xen_check_type(Xen_is_GtkMenuShell_(menu_shell), menu_shell, 1, "gtk_menu_shell_get_take_focus", "GtkMenuShell*"); return(C_to_Xen_gboolean(gtk_menu_shell_get_take_focus(Xen_to_C_GtkMenuShell_(menu_shell)))); } static Xen gxg_gtk_menu_shell_set_take_focus(Xen menu_shell, Xen take_focus) { #define H_gtk_menu_shell_set_take_focus "void gtk_menu_shell_set_take_focus(GtkMenuShell* menu_shell, \ gboolean take_focus)" Xen_check_type(Xen_is_GtkMenuShell_(menu_shell), menu_shell, 1, "gtk_menu_shell_set_take_focus", "GtkMenuShell*"); Xen_check_type(Xen_is_gboolean(take_focus), take_focus, 2, "gtk_menu_shell_set_take_focus", "gboolean"); gtk_menu_shell_set_take_focus(Xen_to_C_GtkMenuShell_(menu_shell), Xen_to_C_gboolean(take_focus)); return(Xen_false); } static Xen gxg_gtk_size_group_set_ignore_hidden(Xen size_group, Xen ignore_hidden) { #define H_gtk_size_group_set_ignore_hidden "void gtk_size_group_set_ignore_hidden(GtkSizeGroup* size_group, \ gboolean ignore_hidden)" Xen_check_type(Xen_is_GtkSizeGroup_(size_group), size_group, 1, "gtk_size_group_set_ignore_hidden", "GtkSizeGroup*"); Xen_check_type(Xen_is_gboolean(ignore_hidden), ignore_hidden, 2, "gtk_size_group_set_ignore_hidden", "gboolean"); gtk_size_group_set_ignore_hidden(Xen_to_C_GtkSizeGroup_(size_group), Xen_to_C_gboolean(ignore_hidden)); return(Xen_false); } static Xen gxg_gtk_size_group_get_ignore_hidden(Xen size_group) { #define H_gtk_size_group_get_ignore_hidden "gboolean gtk_size_group_get_ignore_hidden(GtkSizeGroup* size_group)" Xen_check_type(Xen_is_GtkSizeGroup_(size_group), size_group, 1, "gtk_size_group_get_ignore_hidden", "GtkSizeGroup*"); return(C_to_Xen_gboolean(gtk_size_group_get_ignore_hidden(Xen_to_C_GtkSizeGroup_(size_group)))); } static Xen gxg_gtk_text_iter_forward_visible_line(Xen iter) { #define H_gtk_text_iter_forward_visible_line "gboolean gtk_text_iter_forward_visible_line(GtkTextIter* iter)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_forward_visible_line", "GtkTextIter*"); return(C_to_Xen_gboolean(gtk_text_iter_forward_visible_line(Xen_to_C_GtkTextIter_(iter)))); } static Xen gxg_gtk_text_iter_backward_visible_line(Xen iter) { #define H_gtk_text_iter_backward_visible_line "gboolean gtk_text_iter_backward_visible_line(GtkTextIter* iter)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_backward_visible_line", "GtkTextIter*"); return(C_to_Xen_gboolean(gtk_text_iter_backward_visible_line(Xen_to_C_GtkTextIter_(iter)))); } static Xen gxg_gtk_text_iter_forward_visible_lines(Xen iter, Xen count) { #define H_gtk_text_iter_forward_visible_lines "gboolean gtk_text_iter_forward_visible_lines(GtkTextIter* iter, \ gint count)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_forward_visible_lines", "GtkTextIter*"); Xen_check_type(Xen_is_gint(count), count, 2, "gtk_text_iter_forward_visible_lines", "gint"); return(C_to_Xen_gboolean(gtk_text_iter_forward_visible_lines(Xen_to_C_GtkTextIter_(iter), Xen_to_C_gint(count)))); } static Xen gxg_gtk_text_iter_backward_visible_lines(Xen iter, Xen count) { #define H_gtk_text_iter_backward_visible_lines "gboolean gtk_text_iter_backward_visible_lines(GtkTextIter* iter, \ gint count)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_backward_visible_lines", "GtkTextIter*"); Xen_check_type(Xen_is_gint(count), count, 2, "gtk_text_iter_backward_visible_lines", "gint"); return(C_to_Xen_gboolean(gtk_text_iter_backward_visible_lines(Xen_to_C_GtkTextIter_(iter), Xen_to_C_gint(count)))); } static Xen gxg_gtk_tool_button_set_icon_name(Xen button, Xen icon_name) { #define H_gtk_tool_button_set_icon_name "void gtk_tool_button_set_icon_name(GtkToolButton* button, \ gchar* icon_name)" Xen_check_type(Xen_is_GtkToolButton_(button), button, 1, "gtk_tool_button_set_icon_name", "GtkToolButton*"); Xen_check_type(Xen_is_gchar_(icon_name), icon_name, 2, "gtk_tool_button_set_icon_name", "gchar*"); gtk_tool_button_set_icon_name(Xen_to_C_GtkToolButton_(button), (const gchar*)Xen_to_C_gchar_(icon_name)); return(Xen_false); } static Xen gxg_gtk_tool_button_get_icon_name(Xen button) { #define H_gtk_tool_button_get_icon_name "gchar* gtk_tool_button_get_icon_name(GtkToolButton* button)" Xen_check_type(Xen_is_GtkToolButton_(button), button, 1, "gtk_tool_button_get_icon_name", "GtkToolButton*"); return(C_to_Xen_gchar_((gchar*)gtk_tool_button_get_icon_name(Xen_to_C_GtkToolButton_(button)))); } static Xen gxg_gtk_window_set_urgency_hint(Xen window, Xen setting) { #define H_gtk_window_set_urgency_hint "void gtk_window_set_urgency_hint(GtkWindow* window, gboolean setting)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_set_urgency_hint", "GtkWindow*"); Xen_check_type(Xen_is_gboolean(setting), setting, 2, "gtk_window_set_urgency_hint", "gboolean"); gtk_window_set_urgency_hint(Xen_to_C_GtkWindow_(window), Xen_to_C_gboolean(setting)); return(Xen_false); } static Xen gxg_gtk_window_get_urgency_hint(Xen window) { #define H_gtk_window_get_urgency_hint "gboolean gtk_window_get_urgency_hint(GtkWindow* window)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_get_urgency_hint", "GtkWindow*"); return(C_to_Xen_gboolean(gtk_window_get_urgency_hint(Xen_to_C_GtkWindow_(window)))); } static Xen gxg_gtk_window_present_with_time(Xen window, Xen timestamp) { #define H_gtk_window_present_with_time "void gtk_window_present_with_time(GtkWindow* window, guint32 timestamp)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_present_with_time", "GtkWindow*"); Xen_check_type(Xen_is_guint32(timestamp), timestamp, 2, "gtk_window_present_with_time", "guint32"); gtk_window_present_with_time(Xen_to_C_GtkWindow_(window), Xen_to_C_guint32(timestamp)); return(Xen_false); } static Xen gxg_gtk_file_chooser_set_do_overwrite_confirmation(Xen chooser, Xen do_overwrite_confirmation) { #define H_gtk_file_chooser_set_do_overwrite_confirmation "void gtk_file_chooser_set_do_overwrite_confirmation(GtkFileChooser* chooser, \ gboolean do_overwrite_confirmation)" Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_set_do_overwrite_confirmation", "GtkFileChooser*"); Xen_check_type(Xen_is_gboolean(do_overwrite_confirmation), do_overwrite_confirmation, 2, "gtk_file_chooser_set_do_overwrite_confirmation", "gboolean"); gtk_file_chooser_set_do_overwrite_confirmation(Xen_to_C_GtkFileChooser_(chooser), Xen_to_C_gboolean(do_overwrite_confirmation)); return(Xen_false); } static Xen gxg_gtk_file_chooser_get_do_overwrite_confirmation(Xen chooser) { #define H_gtk_file_chooser_get_do_overwrite_confirmation "gboolean gtk_file_chooser_get_do_overwrite_confirmation(GtkFileChooser* chooser)" Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_get_do_overwrite_confirmation", "GtkFileChooser*"); return(C_to_Xen_gboolean(gtk_file_chooser_get_do_overwrite_confirmation(Xen_to_C_GtkFileChooser_(chooser)))); } static Xen gxg_gtk_tree_row_reference_get_model(Xen reference) { #define H_gtk_tree_row_reference_get_model "GtkTreeModel* gtk_tree_row_reference_get_model(GtkTreeRowReference* reference)" Xen_check_type(Xen_is_GtkTreeRowReference_(reference), reference, 1, "gtk_tree_row_reference_get_model", "GtkTreeRowReference*"); return(C_to_Xen_GtkTreeModel_(gtk_tree_row_reference_get_model(Xen_to_C_GtkTreeRowReference_(reference)))); } static Xen gxg_gtk_tree_view_column_queue_resize(Xen tree_column) { #define H_gtk_tree_view_column_queue_resize "void gtk_tree_view_column_queue_resize(GtkTreeViewColumn* tree_column)" Xen_check_type(Xen_is_GtkTreeViewColumn_(tree_column), tree_column, 1, "gtk_tree_view_column_queue_resize", "GtkTreeViewColumn*"); gtk_tree_view_column_queue_resize(Xen_to_C_GtkTreeViewColumn_(tree_column)); return(Xen_false); } static Xen gxg_gtk_tree_view_get_visible_range(Xen tree_view, Xen ignore_start_path, Xen ignore_end_path) { #define H_gtk_tree_view_get_visible_range "gboolean gtk_tree_view_get_visible_range(GtkTreeView* tree_view, \ GtkTreePath** [start_path], GtkTreePath** [end_path])" GtkTreePath* ref_start_path = NULL; GtkTreePath* ref_end_path = NULL; Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_get_visible_range", "GtkTreeView*"); { Xen result; result = C_to_Xen_gboolean(gtk_tree_view_get_visible_range(Xen_to_C_GtkTreeView_(tree_view), &ref_start_path, &ref_end_path)); return(Xen_list_3(result, C_to_Xen_GtkTreePath_(ref_start_path), C_to_Xen_GtkTreePath_(ref_end_path))); } } static Xen gxg_gtk_text_attributes_ref(Xen values) { #define H_gtk_text_attributes_ref "GtkTextAttributes* gtk_text_attributes_ref(GtkTextAttributes* values)" Xen_check_type(Xen_is_GtkTextAttributes_(values), values, 1, "gtk_text_attributes_ref", "GtkTextAttributes*"); return(C_to_Xen_GtkTextAttributes_(gtk_text_attributes_ref(Xen_to_C_GtkTextAttributes_(values)))); } static Xen gxg_pango_attr_list_ref(Xen list) { #define H_pango_attr_list_ref "PangoAttrList* pango_attr_list_ref(PangoAttrList* list)" Xen_check_type(Xen_is_PangoAttrList_(list), list, 1, "pango_attr_list_ref", "PangoAttrList*"); return(C_to_Xen_PangoAttrList_(pango_attr_list_ref(Xen_to_C_PangoAttrList_(list)))); } static Xen gxg_pango_layout_line_ref(Xen line) { #define H_pango_layout_line_ref "PangoLayoutLine* pango_layout_line_ref(PangoLayoutLine* line)" Xen_check_type(Xen_is_PangoLayoutLine_(line), line, 1, "pango_layout_line_ref", "PangoLayoutLine*"); return(C_to_Xen_PangoLayoutLine_(pango_layout_line_ref(Xen_to_C_PangoLayoutLine_(line)))); } static Xen gxg_pango_layout_index_to_line_x(Xen layout, Xen index_, Xen trailing, Xen ignore_line, Xen ignore_x_pos) { #define H_pango_layout_index_to_line_x "void pango_layout_index_to_line_x(PangoLayout* layout, int index_, \ gboolean trailing, int* [line], int* [x_pos])" int ref_line; int ref_x_pos; Xen_check_type(Xen_is_PangoLayout_(layout), layout, 1, "pango_layout_index_to_line_x", "PangoLayout*"); Xen_check_type(Xen_is_int(index_), index_, 2, "pango_layout_index_to_line_x", "int"); Xen_check_type(Xen_is_gboolean(trailing), trailing, 3, "pango_layout_index_to_line_x", "gboolean"); pango_layout_index_to_line_x(Xen_to_C_PangoLayout_(layout), Xen_to_C_int(index_), Xen_to_C_gboolean(trailing), &ref_line, &ref_x_pos); return(Xen_list_2(C_to_Xen_int(ref_line), C_to_Xen_int(ref_x_pos))); } static Xen gxg_gtk_target_list_ref(Xen list) { #define H_gtk_target_list_ref "GtkTargetList* gtk_target_list_ref(GtkTargetList* list)" Xen_check_type(Xen_is_GtkTargetList_(list), list, 1, "gtk_target_list_ref", "GtkTargetList*"); return(C_to_Xen_GtkTargetList_(gtk_target_list_ref(Xen_to_C_GtkTargetList_(list)))); } static Xen gxg_gdk_display_supports_shapes(Xen display) { #define H_gdk_display_supports_shapes "gboolean gdk_display_supports_shapes(GdkDisplay* display)" Xen_check_type(Xen_is_GdkDisplay_(display), display, 1, "gdk_display_supports_shapes", "GdkDisplay*"); return(C_to_Xen_gboolean(gdk_display_supports_shapes(Xen_to_C_GdkDisplay_(display)))); } static Xen gxg_gdk_display_supports_input_shapes(Xen display) { #define H_gdk_display_supports_input_shapes "gboolean gdk_display_supports_input_shapes(GdkDisplay* display)" Xen_check_type(Xen_is_GdkDisplay_(display), display, 1, "gdk_display_supports_input_shapes", "GdkDisplay*"); return(C_to_Xen_gboolean(gdk_display_supports_input_shapes(Xen_to_C_GdkDisplay_(display)))); } static Xen gxg_gdk_screen_is_composited(Xen screen) { #define H_gdk_screen_is_composited "gboolean gdk_screen_is_composited(GdkScreen* screen)" Xen_check_type(Xen_is_GdkScreen_(screen), screen, 1, "gdk_screen_is_composited", "GdkScreen*"); return(C_to_Xen_gboolean(gdk_screen_is_composited(Xen_to_C_GdkScreen_(screen)))); } static Xen gxg_gdk_screen_set_resolution(Xen screen, Xen dpi) { #define H_gdk_screen_set_resolution "void gdk_screen_set_resolution(GdkScreen* screen, gdouble dpi)" Xen_check_type(Xen_is_GdkScreen_(screen), screen, 1, "gdk_screen_set_resolution", "GdkScreen*"); Xen_check_type(Xen_is_gdouble(dpi), dpi, 2, "gdk_screen_set_resolution", "gdouble"); gdk_screen_set_resolution(Xen_to_C_GdkScreen_(screen), Xen_to_C_gdouble(dpi)); return(Xen_false); } static Xen gxg_gdk_screen_get_resolution(Xen screen) { #define H_gdk_screen_get_resolution "gdouble gdk_screen_get_resolution(GdkScreen* screen)" Xen_check_type(Xen_is_GdkScreen_(screen), screen, 1, "gdk_screen_get_resolution", "GdkScreen*"); return(C_to_Xen_gdouble(gdk_screen_get_resolution(Xen_to_C_GdkScreen_(screen)))); } static Xen gxg_gdk_screen_get_active_window(Xen screen) { #define H_gdk_screen_get_active_window "GdkWindow* gdk_screen_get_active_window(GdkScreen* screen)" Xen_check_type(Xen_is_GdkScreen_(screen), screen, 1, "gdk_screen_get_active_window", "GdkScreen*"); return(C_to_Xen_GdkWindow_(gdk_screen_get_active_window(Xen_to_C_GdkScreen_(screen)))); } static Xen gxg_gdk_screen_get_window_stack(Xen screen) { #define H_gdk_screen_get_window_stack "GList* gdk_screen_get_window_stack(GdkScreen* screen)" Xen_check_type(Xen_is_GdkScreen_(screen), screen, 1, "gdk_screen_get_window_stack", "GdkScreen*"); return(C_to_Xen_GList_(gdk_screen_get_window_stack(Xen_to_C_GdkScreen_(screen)))); } static Xen gxg_gdk_window_get_type_hint(Xen window) { #define H_gdk_window_get_type_hint "GdkWindowTypeHint gdk_window_get_type_hint(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_get_type_hint", "GdkWindow*"); return(C_to_Xen_GdkWindowTypeHint(gdk_window_get_type_hint(Xen_to_C_GdkWindow_(window)))); } static Xen gxg_gtk_clipboard_request_rich_text(Xen clipboard, Xen buffer, Xen func, Xen func_info) { #define H_gtk_clipboard_request_rich_text "void gtk_clipboard_request_rich_text(GtkClipboard* clipboard, \ GtkTextBuffer* buffer, GtkClipboardRichTextReceivedFunc func, lambda_data func_info)" Xen_check_type(Xen_is_GtkClipboard_(clipboard), clipboard, 1, "gtk_clipboard_request_rich_text", "GtkClipboard*"); Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 2, "gtk_clipboard_request_rich_text", "GtkTextBuffer*"); Xen_check_type(Xen_is_GtkClipboardRichTextReceivedFunc(func), func, 3, "gtk_clipboard_request_rich_text", "GtkClipboardRichTextReceivedFunc"); if (!Xen_is_bound(func_info)) func_info = Xen_false; else Xen_check_type(Xen_is_lambda_data(func_info), func_info, 4, "gtk_clipboard_request_rich_text", "lambda_data"); { Xen gxg_ptr = Xen_list_5(func, func_info, Xen_false, Xen_false, Xen_false); xm_protect(gxg_ptr); gtk_clipboard_request_rich_text(Xen_to_C_GtkClipboard_(clipboard), Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_GtkClipboardRichTextReceivedFunc(func), Xen_to_C_lambda_data(func_info)); return(Xen_false); } } static Xen gxg_gtk_clipboard_wait_for_rich_text(Xen clipboard, Xen buffer, Xen format, Xen ignore_length) { #define H_gtk_clipboard_wait_for_rich_text "guint8* gtk_clipboard_wait_for_rich_text(GtkClipboard* clipboard, \ GtkTextBuffer* buffer, GdkAtom* format, gsize* [length])" gsize ref_length; Xen_check_type(Xen_is_GtkClipboard_(clipboard), clipboard, 1, "gtk_clipboard_wait_for_rich_text", "GtkClipboard*"); Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 2, "gtk_clipboard_wait_for_rich_text", "GtkTextBuffer*"); Xen_check_type(Xen_is_GdkAtom_(format), format, 3, "gtk_clipboard_wait_for_rich_text", "GdkAtom*"); { Xen result; result = C_to_Xen_guint8_(gtk_clipboard_wait_for_rich_text(Xen_to_C_GtkClipboard_(clipboard), Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_GdkAtom_(format), &ref_length)); return(Xen_list_2(result, C_to_Xen_gsize(ref_length))); } } static Xen gxg_gtk_clipboard_wait_is_rich_text_available(Xen clipboard, Xen buffer) { #define H_gtk_clipboard_wait_is_rich_text_available "gboolean gtk_clipboard_wait_is_rich_text_available(GtkClipboard* clipboard, \ GtkTextBuffer* buffer)" Xen_check_type(Xen_is_GtkClipboard_(clipboard), clipboard, 1, "gtk_clipboard_wait_is_rich_text_available", "GtkClipboard*"); Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 2, "gtk_clipboard_wait_is_rich_text_available", "GtkTextBuffer*"); return(C_to_Xen_gboolean(gtk_clipboard_wait_is_rich_text_available(Xen_to_C_GtkClipboard_(clipboard), Xen_to_C_GtkTextBuffer_(buffer)))); } static Xen gxg_gtk_drag_dest_set_track_motion(Xen widget, Xen track_motion) { #define H_gtk_drag_dest_set_track_motion "void gtk_drag_dest_set_track_motion(GtkWidget* widget, gboolean track_motion)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_drag_dest_set_track_motion", "GtkWidget*"); Xen_check_type(Xen_is_gboolean(track_motion), track_motion, 2, "gtk_drag_dest_set_track_motion", "gboolean"); gtk_drag_dest_set_track_motion(Xen_to_C_GtkWidget_(widget), Xen_to_C_gboolean(track_motion)); return(Xen_false); } static Xen gxg_gtk_drag_dest_get_track_motion(Xen widget) { #define H_gtk_drag_dest_get_track_motion "gboolean gtk_drag_dest_get_track_motion(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_drag_dest_get_track_motion", "GtkWidget*"); return(C_to_Xen_gboolean(gtk_drag_dest_get_track_motion(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_notebook_get_tab_reorderable(Xen notebook, Xen child) { #define H_gtk_notebook_get_tab_reorderable "gboolean gtk_notebook_get_tab_reorderable(GtkNotebook* notebook, \ GtkWidget* child)" Xen_check_type(Xen_is_GtkNotebook_(notebook), notebook, 1, "gtk_notebook_get_tab_reorderable", "GtkNotebook*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_notebook_get_tab_reorderable", "GtkWidget*"); return(C_to_Xen_gboolean(gtk_notebook_get_tab_reorderable(Xen_to_C_GtkNotebook_(notebook), Xen_to_C_GtkWidget_(child)))); } static Xen gxg_gtk_notebook_set_tab_reorderable(Xen notebook, Xen child, Xen reorderable) { #define H_gtk_notebook_set_tab_reorderable "void gtk_notebook_set_tab_reorderable(GtkNotebook* notebook, \ GtkWidget* child, gboolean reorderable)" Xen_check_type(Xen_is_GtkNotebook_(notebook), notebook, 1, "gtk_notebook_set_tab_reorderable", "GtkNotebook*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_notebook_set_tab_reorderable", "GtkWidget*"); Xen_check_type(Xen_is_gboolean(reorderable), reorderable, 3, "gtk_notebook_set_tab_reorderable", "gboolean"); gtk_notebook_set_tab_reorderable(Xen_to_C_GtkNotebook_(notebook), Xen_to_C_GtkWidget_(child), Xen_to_C_gboolean(reorderable)); return(Xen_false); } static Xen gxg_gtk_notebook_get_tab_detachable(Xen notebook, Xen child) { #define H_gtk_notebook_get_tab_detachable "gboolean gtk_notebook_get_tab_detachable(GtkNotebook* notebook, \ GtkWidget* child)" Xen_check_type(Xen_is_GtkNotebook_(notebook), notebook, 1, "gtk_notebook_get_tab_detachable", "GtkNotebook*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_notebook_get_tab_detachable", "GtkWidget*"); return(C_to_Xen_gboolean(gtk_notebook_get_tab_detachable(Xen_to_C_GtkNotebook_(notebook), Xen_to_C_GtkWidget_(child)))); } static Xen gxg_gtk_notebook_set_tab_detachable(Xen notebook, Xen child, Xen detachable) { #define H_gtk_notebook_set_tab_detachable "void gtk_notebook_set_tab_detachable(GtkNotebook* notebook, \ GtkWidget* child, gboolean detachable)" Xen_check_type(Xen_is_GtkNotebook_(notebook), notebook, 1, "gtk_notebook_set_tab_detachable", "GtkNotebook*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_notebook_set_tab_detachable", "GtkWidget*"); Xen_check_type(Xen_is_gboolean(detachable), detachable, 3, "gtk_notebook_set_tab_detachable", "gboolean"); gtk_notebook_set_tab_detachable(Xen_to_C_GtkNotebook_(notebook), Xen_to_C_GtkWidget_(child), Xen_to_C_gboolean(detachable)); return(Xen_false); } static Xen gxg_gtk_range_set_lower_stepper_sensitivity(Xen range, Xen sensitivity) { #define H_gtk_range_set_lower_stepper_sensitivity "void gtk_range_set_lower_stepper_sensitivity(GtkRange* range, \ GtkSensitivityType sensitivity)" Xen_check_type(Xen_is_GtkRange_(range), range, 1, "gtk_range_set_lower_stepper_sensitivity", "GtkRange*"); Xen_check_type(Xen_is_GtkSensitivityType(sensitivity), sensitivity, 2, "gtk_range_set_lower_stepper_sensitivity", "GtkSensitivityType"); gtk_range_set_lower_stepper_sensitivity(Xen_to_C_GtkRange_(range), Xen_to_C_GtkSensitivityType(sensitivity)); return(Xen_false); } static Xen gxg_gtk_range_get_lower_stepper_sensitivity(Xen range) { #define H_gtk_range_get_lower_stepper_sensitivity "GtkSensitivityType gtk_range_get_lower_stepper_sensitivity(GtkRange* range)" Xen_check_type(Xen_is_GtkRange_(range), range, 1, "gtk_range_get_lower_stepper_sensitivity", "GtkRange*"); return(C_to_Xen_GtkSensitivityType(gtk_range_get_lower_stepper_sensitivity(Xen_to_C_GtkRange_(range)))); } static Xen gxg_gtk_range_set_upper_stepper_sensitivity(Xen range, Xen sensitivity) { #define H_gtk_range_set_upper_stepper_sensitivity "void gtk_range_set_upper_stepper_sensitivity(GtkRange* range, \ GtkSensitivityType sensitivity)" Xen_check_type(Xen_is_GtkRange_(range), range, 1, "gtk_range_set_upper_stepper_sensitivity", "GtkRange*"); Xen_check_type(Xen_is_GtkSensitivityType(sensitivity), sensitivity, 2, "gtk_range_set_upper_stepper_sensitivity", "GtkSensitivityType"); gtk_range_set_upper_stepper_sensitivity(Xen_to_C_GtkRange_(range), Xen_to_C_GtkSensitivityType(sensitivity)); return(Xen_false); } static Xen gxg_gtk_range_get_upper_stepper_sensitivity(Xen range) { #define H_gtk_range_get_upper_stepper_sensitivity "GtkSensitivityType gtk_range_get_upper_stepper_sensitivity(GtkRange* range)" Xen_check_type(Xen_is_GtkRange_(range), range, 1, "gtk_range_get_upper_stepper_sensitivity", "GtkRange*"); return(C_to_Xen_GtkSensitivityType(gtk_range_get_upper_stepper_sensitivity(Xen_to_C_GtkRange_(range)))); } static Xen gxg_gtk_scrolled_window_unset_placement(Xen scrolled_window) { #define H_gtk_scrolled_window_unset_placement "void gtk_scrolled_window_unset_placement(GtkScrolledWindow* scrolled_window)" Xen_check_type(Xen_is_GtkScrolledWindow_(scrolled_window), scrolled_window, 1, "gtk_scrolled_window_unset_placement", "GtkScrolledWindow*"); gtk_scrolled_window_unset_placement(Xen_to_C_GtkScrolledWindow_(scrolled_window)); return(Xen_false); } static Xen gxg_gtk_target_list_add_rich_text_targets(Xen list, Xen info, Xen deserializable, Xen buffer) { #define H_gtk_target_list_add_rich_text_targets "void gtk_target_list_add_rich_text_targets(GtkTargetList* list, \ guint info, gboolean deserializable, GtkTextBuffer* buffer)" Xen_check_type(Xen_is_GtkTargetList_(list), list, 1, "gtk_target_list_add_rich_text_targets", "GtkTargetList*"); Xen_check_type(Xen_is_guint(info), info, 2, "gtk_target_list_add_rich_text_targets", "guint"); Xen_check_type(Xen_is_gboolean(deserializable), deserializable, 3, "gtk_target_list_add_rich_text_targets", "gboolean"); Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 4, "gtk_target_list_add_rich_text_targets", "GtkTextBuffer*"); gtk_target_list_add_rich_text_targets(Xen_to_C_GtkTargetList_(list), Xen_to_C_guint(info), Xen_to_C_gboolean(deserializable), Xen_to_C_GtkTextBuffer_(buffer)); return(Xen_false); } static Xen gxg_gtk_target_table_new_from_list(Xen list, Xen ignore_n_targets) { #define H_gtk_target_table_new_from_list "GtkTargetEntry* gtk_target_table_new_from_list(GtkTargetList* list, \ gint* [n_targets])" gint ref_n_targets; Xen_check_type(Xen_is_GtkTargetList_(list), list, 1, "gtk_target_table_new_from_list", "GtkTargetList*"); { Xen result; result = C_to_Xen_GtkTargetEntry_(gtk_target_table_new_from_list(Xen_to_C_GtkTargetList_(list), &ref_n_targets)); return(Xen_list_2(result, C_to_Xen_gint(ref_n_targets))); } } static Xen gxg_gtk_target_table_free(Xen targets, Xen n_targets) { #define H_gtk_target_table_free "void gtk_target_table_free(GtkTargetEntry* targets, gint n_targets)" Xen_check_type(Xen_is_GtkTargetEntry_(targets), targets, 1, "gtk_target_table_free", "GtkTargetEntry*"); Xen_check_type(Xen_is_gint(n_targets), n_targets, 2, "gtk_target_table_free", "gint"); gtk_target_table_free(Xen_to_C_GtkTargetEntry_(targets), Xen_to_C_gint(n_targets)); return(Xen_false); } static Xen gxg_gtk_selection_data_targets_include_rich_text(Xen selection_data, Xen buffer) { #define H_gtk_selection_data_targets_include_rich_text "gboolean gtk_selection_data_targets_include_rich_text(GtkSelectionData* selection_data, \ GtkTextBuffer* buffer)" Xen_check_type(Xen_is_GtkSelectionData_(selection_data), selection_data, 1, "gtk_selection_data_targets_include_rich_text", "GtkSelectionData*"); Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 2, "gtk_selection_data_targets_include_rich_text", "GtkTextBuffer*"); return(C_to_Xen_gboolean(gtk_selection_data_targets_include_rich_text(Xen_to_C_GtkSelectionData_(selection_data), Xen_to_C_GtkTextBuffer_(buffer)))); } static Xen gxg_gtk_selection_data_targets_include_uri(Xen selection_data) { #define H_gtk_selection_data_targets_include_uri "gboolean gtk_selection_data_targets_include_uri(GtkSelectionData* selection_data)" Xen_check_type(Xen_is_GtkSelectionData_(selection_data), selection_data, 1, "gtk_selection_data_targets_include_uri", "GtkSelectionData*"); return(C_to_Xen_gboolean(gtk_selection_data_targets_include_uri(Xen_to_C_GtkSelectionData_(selection_data)))); } static Xen gxg_gtk_targets_include_text(Xen targets, Xen n_targets) { #define H_gtk_targets_include_text "gboolean gtk_targets_include_text(GdkAtom* targets, gint n_targets)" Xen_check_type(Xen_is_GdkAtom_(targets), targets, 1, "gtk_targets_include_text", "GdkAtom*"); Xen_check_type(Xen_is_gint(n_targets), n_targets, 2, "gtk_targets_include_text", "gint"); return(C_to_Xen_gboolean(gtk_targets_include_text(Xen_to_C_GdkAtom_(targets), Xen_to_C_gint(n_targets)))); } static Xen gxg_gtk_targets_include_rich_text(Xen targets, Xen n_targets, Xen buffer) { #define H_gtk_targets_include_rich_text "gboolean gtk_targets_include_rich_text(GdkAtom* targets, gint n_targets, \ GtkTextBuffer* buffer)" Xen_check_type(Xen_is_GdkAtom_(targets), targets, 1, "gtk_targets_include_rich_text", "GdkAtom*"); Xen_check_type(Xen_is_gint(n_targets), n_targets, 2, "gtk_targets_include_rich_text", "gint"); Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 3, "gtk_targets_include_rich_text", "GtkTextBuffer*"); return(C_to_Xen_gboolean(gtk_targets_include_rich_text(Xen_to_C_GdkAtom_(targets), Xen_to_C_gint(n_targets), Xen_to_C_GtkTextBuffer_(buffer)))); } static Xen gxg_gtk_targets_include_image(Xen targets, Xen n_targets, Xen writable) { #define H_gtk_targets_include_image "gboolean gtk_targets_include_image(GdkAtom* targets, gint n_targets, \ gboolean writable)" Xen_check_type(Xen_is_GdkAtom_(targets), targets, 1, "gtk_targets_include_image", "GdkAtom*"); Xen_check_type(Xen_is_gint(n_targets), n_targets, 2, "gtk_targets_include_image", "gint"); Xen_check_type(Xen_is_gboolean(writable), writable, 3, "gtk_targets_include_image", "gboolean"); return(C_to_Xen_gboolean(gtk_targets_include_image(Xen_to_C_GdkAtom_(targets), Xen_to_C_gint(n_targets), Xen_to_C_gboolean(writable)))); } static Xen gxg_gtk_targets_include_uri(Xen targets, Xen n_targets) { #define H_gtk_targets_include_uri "gboolean gtk_targets_include_uri(GdkAtom* targets, gint n_targets)" Xen_check_type(Xen_is_GdkAtom_(targets), targets, 1, "gtk_targets_include_uri", "GdkAtom*"); Xen_check_type(Xen_is_gint(n_targets), n_targets, 2, "gtk_targets_include_uri", "gint"); return(C_to_Xen_gboolean(gtk_targets_include_uri(Xen_to_C_GdkAtom_(targets), Xen_to_C_gint(n_targets)))); } static Xen gxg_gtk_size_group_get_widgets(Xen size_group) { #define H_gtk_size_group_get_widgets "GSList* gtk_size_group_get_widgets(GtkSizeGroup* size_group)" Xen_check_type(Xen_is_GtkSizeGroup_(size_group), size_group, 1, "gtk_size_group_get_widgets", "GtkSizeGroup*"); return(C_to_Xen_GSList_(gtk_size_group_get_widgets(Xen_to_C_GtkSizeGroup_(size_group)))); } static Xen gxg_gtk_text_buffer_get_has_selection(Xen buffer) { #define H_gtk_text_buffer_get_has_selection "gboolean gtk_text_buffer_get_has_selection(GtkTextBuffer* buffer)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_get_has_selection", "GtkTextBuffer*"); return(C_to_Xen_gboolean(gtk_text_buffer_get_has_selection(Xen_to_C_GtkTextBuffer_(buffer)))); } static Xen gxg_gtk_text_buffer_get_copy_target_list(Xen buffer) { #define H_gtk_text_buffer_get_copy_target_list "GtkTargetList* gtk_text_buffer_get_copy_target_list(GtkTextBuffer* buffer)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_get_copy_target_list", "GtkTextBuffer*"); return(C_to_Xen_GtkTargetList_(gtk_text_buffer_get_copy_target_list(Xen_to_C_GtkTextBuffer_(buffer)))); } static Xen gxg_gtk_text_buffer_get_paste_target_list(Xen buffer) { #define H_gtk_text_buffer_get_paste_target_list "GtkTargetList* gtk_text_buffer_get_paste_target_list(GtkTextBuffer* buffer)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_get_paste_target_list", "GtkTextBuffer*"); return(C_to_Xen_GtkTargetList_(gtk_text_buffer_get_paste_target_list(Xen_to_C_GtkTextBuffer_(buffer)))); } static Xen gxg_gtk_tree_view_get_headers_clickable(Xen tree_view) { #define H_gtk_tree_view_get_headers_clickable "gboolean gtk_tree_view_get_headers_clickable(GtkTreeView* tree_view)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_get_headers_clickable", "GtkTreeView*"); return(C_to_Xen_gboolean(gtk_tree_view_get_headers_clickable(Xen_to_C_GtkTreeView_(tree_view)))); } static Xen gxg_gtk_tree_view_get_search_entry(Xen tree_view) { #define H_gtk_tree_view_get_search_entry "GtkEntry* gtk_tree_view_get_search_entry(GtkTreeView* tree_view)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_get_search_entry", "GtkTreeView*"); return(C_to_Xen_GtkEntry_(gtk_tree_view_get_search_entry(Xen_to_C_GtkTreeView_(tree_view)))); } static Xen gxg_gtk_tree_view_set_search_entry(Xen tree_view, Xen entry) { #define H_gtk_tree_view_set_search_entry "void gtk_tree_view_set_search_entry(GtkTreeView* tree_view, \ GtkEntry* entry)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_set_search_entry", "GtkTreeView*"); Xen_check_type(Xen_is_GtkEntry_(entry), entry, 2, "gtk_tree_view_set_search_entry", "GtkEntry*"); gtk_tree_view_set_search_entry(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_GtkEntry_(entry)); return(Xen_false); } static Xen gxg_gtk_tree_view_get_search_position_func(Xen tree_view) { #define H_gtk_tree_view_get_search_position_func "GtkTreeViewSearchPositionFunc gtk_tree_view_get_search_position_func(GtkTreeView* tree_view)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_get_search_position_func", "GtkTreeView*"); return(C_to_Xen_GtkTreeViewSearchPositionFunc(gtk_tree_view_get_search_position_func(Xen_to_C_GtkTreeView_(tree_view)))); } static Xen gxg_gtk_tree_view_set_search_position_func(Xen tree_view, Xen func, Xen func_info, Xen destroy) { #define H_gtk_tree_view_set_search_position_func "void gtk_tree_view_set_search_position_func(GtkTreeView* tree_view, \ GtkTreeViewSearchPositionFunc func, lambda_data func_info, GDestroyNotify destroy)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_set_search_position_func", "GtkTreeView*"); Xen_check_type(Xen_is_GtkTreeViewSearchPositionFunc(func), func, 2, "gtk_tree_view_set_search_position_func", "GtkTreeViewSearchPositionFunc"); if (!Xen_is_bound(func_info)) func_info = Xen_false; else Xen_check_type(Xen_is_lambda_data(func_info), func_info, 3, "gtk_tree_view_set_search_position_func", "lambda_data"); Xen_check_type(Xen_is_GDestroyNotify(destroy), destroy, 4, "gtk_tree_view_set_search_position_func", "GDestroyNotify"); { Xen gxg_ptr = Xen_list_5(func, func_info, Xen_false, Xen_false, Xen_false); xm_protect(gxg_ptr); gtk_tree_view_set_search_position_func(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_GtkTreeViewSearchPositionFunc(func), Xen_to_C_lambda_data(func_info), Xen_to_C_GDestroyNotify(destroy)); return(Xen_false); } } static Xen gxg_gtk_widget_is_composited(Xen widget) { #define H_gtk_widget_is_composited "gboolean gtk_widget_is_composited(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_is_composited", "GtkWidget*"); return(C_to_Xen_gboolean(gtk_widget_is_composited(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_window_set_deletable(Xen window, Xen setting) { #define H_gtk_window_set_deletable "void gtk_window_set_deletable(GtkWindow* window, gboolean setting)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_set_deletable", "GtkWindow*"); Xen_check_type(Xen_is_gboolean(setting), setting, 2, "gtk_window_set_deletable", "gboolean"); gtk_window_set_deletable(Xen_to_C_GtkWindow_(window), Xen_to_C_gboolean(setting)); return(Xen_false); } static Xen gxg_gtk_window_get_deletable(Xen window) { #define H_gtk_window_get_deletable "gboolean gtk_window_get_deletable(GtkWindow* window)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_get_deletable", "GtkWindow*"); return(C_to_Xen_gboolean(gtk_window_get_deletable(Xen_to_C_GtkWindow_(window)))); } static Xen gxg_gtk_assistant_new(void) { #define H_gtk_assistant_new "GtkWidget* gtk_assistant_new( void)" return(C_to_Xen_GtkWidget_(gtk_assistant_new())); } static Xen gxg_gtk_assistant_get_current_page(Xen assistant) { #define H_gtk_assistant_get_current_page "gint gtk_assistant_get_current_page(GtkAssistant* assistant)" Xen_check_type(Xen_is_GtkAssistant_(assistant), assistant, 1, "gtk_assistant_get_current_page", "GtkAssistant*"); return(C_to_Xen_gint(gtk_assistant_get_current_page(Xen_to_C_GtkAssistant_(assistant)))); } static Xen gxg_gtk_assistant_set_current_page(Xen assistant, Xen page_num) { #define H_gtk_assistant_set_current_page "void gtk_assistant_set_current_page(GtkAssistant* assistant, \ gint page_num)" Xen_check_type(Xen_is_GtkAssistant_(assistant), assistant, 1, "gtk_assistant_set_current_page", "GtkAssistant*"); Xen_check_type(Xen_is_gint(page_num), page_num, 2, "gtk_assistant_set_current_page", "gint"); gtk_assistant_set_current_page(Xen_to_C_GtkAssistant_(assistant), Xen_to_C_gint(page_num)); return(Xen_false); } static Xen gxg_gtk_assistant_get_n_pages(Xen assistant) { #define H_gtk_assistant_get_n_pages "gint gtk_assistant_get_n_pages(GtkAssistant* assistant)" Xen_check_type(Xen_is_GtkAssistant_(assistant), assistant, 1, "gtk_assistant_get_n_pages", "GtkAssistant*"); return(C_to_Xen_gint(gtk_assistant_get_n_pages(Xen_to_C_GtkAssistant_(assistant)))); } static Xen gxg_gtk_assistant_get_nth_page(Xen assistant, Xen page_num) { #define H_gtk_assistant_get_nth_page "GtkWidget* gtk_assistant_get_nth_page(GtkAssistant* assistant, \ gint page_num)" Xen_check_type(Xen_is_GtkAssistant_(assistant), assistant, 1, "gtk_assistant_get_nth_page", "GtkAssistant*"); Xen_check_type(Xen_is_gint(page_num), page_num, 2, "gtk_assistant_get_nth_page", "gint"); return(C_to_Xen_GtkWidget_(gtk_assistant_get_nth_page(Xen_to_C_GtkAssistant_(assistant), Xen_to_C_gint(page_num)))); } static Xen gxg_gtk_assistant_prepend_page(Xen assistant, Xen page) { #define H_gtk_assistant_prepend_page "gint gtk_assistant_prepend_page(GtkAssistant* assistant, GtkWidget* page)" Xen_check_type(Xen_is_GtkAssistant_(assistant), assistant, 1, "gtk_assistant_prepend_page", "GtkAssistant*"); Xen_check_type(Xen_is_GtkWidget_(page), page, 2, "gtk_assistant_prepend_page", "GtkWidget*"); return(C_to_Xen_gint(gtk_assistant_prepend_page(Xen_to_C_GtkAssistant_(assistant), Xen_to_C_GtkWidget_(page)))); } static Xen gxg_gtk_assistant_append_page(Xen assistant, Xen page) { #define H_gtk_assistant_append_page "gint gtk_assistant_append_page(GtkAssistant* assistant, GtkWidget* page)" Xen_check_type(Xen_is_GtkAssistant_(assistant), assistant, 1, "gtk_assistant_append_page", "GtkAssistant*"); Xen_check_type(Xen_is_GtkWidget_(page), page, 2, "gtk_assistant_append_page", "GtkWidget*"); return(C_to_Xen_gint(gtk_assistant_append_page(Xen_to_C_GtkAssistant_(assistant), Xen_to_C_GtkWidget_(page)))); } static Xen gxg_gtk_assistant_insert_page(Xen assistant, Xen page, Xen position) { #define H_gtk_assistant_insert_page "gint gtk_assistant_insert_page(GtkAssistant* assistant, GtkWidget* page, \ gint position)" Xen_check_type(Xen_is_GtkAssistant_(assistant), assistant, 1, "gtk_assistant_insert_page", "GtkAssistant*"); Xen_check_type(Xen_is_GtkWidget_(page), page, 2, "gtk_assistant_insert_page", "GtkWidget*"); Xen_check_type(Xen_is_gint(position), position, 3, "gtk_assistant_insert_page", "gint"); return(C_to_Xen_gint(gtk_assistant_insert_page(Xen_to_C_GtkAssistant_(assistant), Xen_to_C_GtkWidget_(page), Xen_to_C_gint(position)))); } static Xen gxg_gtk_assistant_set_forward_page_func(Xen assistant, Xen page_func, Xen func_info, Xen destroy) { #define H_gtk_assistant_set_forward_page_func "void gtk_assistant_set_forward_page_func(GtkAssistant* assistant, \ GtkAssistantPageFunc page_func, lambda_data func_info, GDestroyNotify destroy)" Xen_check_type(Xen_is_GtkAssistant_(assistant), assistant, 1, "gtk_assistant_set_forward_page_func", "GtkAssistant*"); Xen_check_type(Xen_is_GtkAssistantPageFunc(page_func), page_func, 2, "gtk_assistant_set_forward_page_func", "GtkAssistantPageFunc"); if (!Xen_is_bound(func_info)) func_info = Xen_false; else Xen_check_type(Xen_is_lambda_data(func_info), func_info, 3, "gtk_assistant_set_forward_page_func", "lambda_data"); Xen_check_type(Xen_is_GDestroyNotify(destroy), destroy, 4, "gtk_assistant_set_forward_page_func", "GDestroyNotify"); { Xen gxg_ptr = Xen_list_5(Xen_false, func_info, Xen_false, Xen_false, Xen_false); xm_protect(gxg_ptr); gtk_assistant_set_forward_page_func(Xen_to_C_GtkAssistant_(assistant), Xen_to_C_GtkAssistantPageFunc(page_func), Xen_to_C_lambda_data(func_info), Xen_to_C_GDestroyNotify(destroy)); return(Xen_false); } } static Xen gxg_gtk_assistant_set_page_type(Xen assistant, Xen page, Xen type) { #define H_gtk_assistant_set_page_type "void gtk_assistant_set_page_type(GtkAssistant* assistant, GtkWidget* page, \ GtkAssistantPageType type)" Xen_check_type(Xen_is_GtkAssistant_(assistant), assistant, 1, "gtk_assistant_set_page_type", "GtkAssistant*"); Xen_check_type(Xen_is_GtkWidget_(page), page, 2, "gtk_assistant_set_page_type", "GtkWidget*"); Xen_check_type(Xen_is_GtkAssistantPageType(type), type, 3, "gtk_assistant_set_page_type", "GtkAssistantPageType"); gtk_assistant_set_page_type(Xen_to_C_GtkAssistant_(assistant), Xen_to_C_GtkWidget_(page), Xen_to_C_GtkAssistantPageType(type)); return(Xen_false); } static Xen gxg_gtk_assistant_get_page_type(Xen assistant, Xen page) { #define H_gtk_assistant_get_page_type "GtkAssistantPageType gtk_assistant_get_page_type(GtkAssistant* assistant, \ GtkWidget* page)" Xen_check_type(Xen_is_GtkAssistant_(assistant), assistant, 1, "gtk_assistant_get_page_type", "GtkAssistant*"); Xen_check_type(Xen_is_GtkWidget_(page), page, 2, "gtk_assistant_get_page_type", "GtkWidget*"); return(C_to_Xen_GtkAssistantPageType(gtk_assistant_get_page_type(Xen_to_C_GtkAssistant_(assistant), Xen_to_C_GtkWidget_(page)))); } static Xen gxg_gtk_assistant_set_page_title(Xen assistant, Xen page, Xen title) { #define H_gtk_assistant_set_page_title "void gtk_assistant_set_page_title(GtkAssistant* assistant, \ GtkWidget* page, gchar* title)" Xen_check_type(Xen_is_GtkAssistant_(assistant), assistant, 1, "gtk_assistant_set_page_title", "GtkAssistant*"); Xen_check_type(Xen_is_GtkWidget_(page), page, 2, "gtk_assistant_set_page_title", "GtkWidget*"); Xen_check_type(Xen_is_gchar_(title), title, 3, "gtk_assistant_set_page_title", "gchar*"); gtk_assistant_set_page_title(Xen_to_C_GtkAssistant_(assistant), Xen_to_C_GtkWidget_(page), Xen_to_C_gchar_(title)); return(Xen_false); } static Xen gxg_gtk_assistant_get_page_title(Xen assistant, Xen page) { #define H_gtk_assistant_get_page_title "gchar* gtk_assistant_get_page_title(GtkAssistant* assistant, \ GtkWidget* page)" Xen_check_type(Xen_is_GtkAssistant_(assistant), assistant, 1, "gtk_assistant_get_page_title", "GtkAssistant*"); Xen_check_type(Xen_is_GtkWidget_(page), page, 2, "gtk_assistant_get_page_title", "GtkWidget*"); return(C_to_Xen_gchar_(gtk_assistant_get_page_title(Xen_to_C_GtkAssistant_(assistant), Xen_to_C_GtkWidget_(page)))); } static Xen gxg_gtk_assistant_set_page_complete(Xen assistant, Xen page, Xen complete) { #define H_gtk_assistant_set_page_complete "void gtk_assistant_set_page_complete(GtkAssistant* assistant, \ GtkWidget* page, gboolean complete)" Xen_check_type(Xen_is_GtkAssistant_(assistant), assistant, 1, "gtk_assistant_set_page_complete", "GtkAssistant*"); Xen_check_type(Xen_is_GtkWidget_(page), page, 2, "gtk_assistant_set_page_complete", "GtkWidget*"); Xen_check_type(Xen_is_gboolean(complete), complete, 3, "gtk_assistant_set_page_complete", "gboolean"); gtk_assistant_set_page_complete(Xen_to_C_GtkAssistant_(assistant), Xen_to_C_GtkWidget_(page), Xen_to_C_gboolean(complete)); return(Xen_false); } static Xen gxg_gtk_assistant_get_page_complete(Xen assistant, Xen page) { #define H_gtk_assistant_get_page_complete "gboolean gtk_assistant_get_page_complete(GtkAssistant* assistant, \ GtkWidget* page)" Xen_check_type(Xen_is_GtkAssistant_(assistant), assistant, 1, "gtk_assistant_get_page_complete", "GtkAssistant*"); Xen_check_type(Xen_is_GtkWidget_(page), page, 2, "gtk_assistant_get_page_complete", "GtkWidget*"); return(C_to_Xen_gboolean(gtk_assistant_get_page_complete(Xen_to_C_GtkAssistant_(assistant), Xen_to_C_GtkWidget_(page)))); } static Xen gxg_gtk_assistant_add_action_widget(Xen assistant, Xen child) { #define H_gtk_assistant_add_action_widget "void gtk_assistant_add_action_widget(GtkAssistant* assistant, \ GtkWidget* child)" Xen_check_type(Xen_is_GtkAssistant_(assistant), assistant, 1, "gtk_assistant_add_action_widget", "GtkAssistant*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_assistant_add_action_widget", "GtkWidget*"); gtk_assistant_add_action_widget(Xen_to_C_GtkAssistant_(assistant), Xen_to_C_GtkWidget_(child)); return(Xen_false); } static Xen gxg_gtk_assistant_remove_action_widget(Xen assistant, Xen child) { #define H_gtk_assistant_remove_action_widget "void gtk_assistant_remove_action_widget(GtkAssistant* assistant, \ GtkWidget* child)" Xen_check_type(Xen_is_GtkAssistant_(assistant), assistant, 1, "gtk_assistant_remove_action_widget", "GtkAssistant*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_assistant_remove_action_widget", "GtkWidget*"); gtk_assistant_remove_action_widget(Xen_to_C_GtkAssistant_(assistant), Xen_to_C_GtkWidget_(child)); return(Xen_false); } static Xen gxg_gtk_assistant_update_buttons_state(Xen assistant) { #define H_gtk_assistant_update_buttons_state "void gtk_assistant_update_buttons_state(GtkAssistant* assistant)" Xen_check_type(Xen_is_GtkAssistant_(assistant), assistant, 1, "gtk_assistant_update_buttons_state", "GtkAssistant*"); gtk_assistant_update_buttons_state(Xen_to_C_GtkAssistant_(assistant)); return(Xen_false); } static Xen gxg_gtk_cell_renderer_accel_new(void) { #define H_gtk_cell_renderer_accel_new "GtkCellRenderer* gtk_cell_renderer_accel_new( void)" return(C_to_Xen_GtkCellRenderer_(gtk_cell_renderer_accel_new())); } static Xen gxg_gtk_cell_renderer_spin_new(void) { #define H_gtk_cell_renderer_spin_new "GtkCellRenderer* gtk_cell_renderer_spin_new( void)" return(C_to_Xen_GtkCellRenderer_(gtk_cell_renderer_spin_new())); } static Xen gxg_gtk_link_button_new(Xen uri) { #define H_gtk_link_button_new "GtkWidget* gtk_link_button_new(gchar* uri)" Xen_check_type(Xen_is_gchar_(uri), uri, 1, "gtk_link_button_new", "gchar*"); return(C_to_Xen_GtkWidget_(gtk_link_button_new(Xen_to_C_gchar_(uri)))); } static Xen gxg_gtk_link_button_new_with_label(Xen uri, Xen label) { #define H_gtk_link_button_new_with_label "GtkWidget* gtk_link_button_new_with_label(gchar* uri, gchar* label)" Xen_check_type(Xen_is_gchar_(uri), uri, 1, "gtk_link_button_new_with_label", "gchar*"); Xen_check_type(Xen_is_gchar_(label), label, 2, "gtk_link_button_new_with_label", "gchar*"); return(C_to_Xen_GtkWidget_(gtk_link_button_new_with_label(Xen_to_C_gchar_(uri), Xen_to_C_gchar_(label)))); } static Xen gxg_gtk_link_button_get_uri(Xen link_button) { #define H_gtk_link_button_get_uri "gchar* gtk_link_button_get_uri(GtkLinkButton* link_button)" Xen_check_type(Xen_is_GtkLinkButton_(link_button), link_button, 1, "gtk_link_button_get_uri", "GtkLinkButton*"); return(C_to_Xen_gchar_(gtk_link_button_get_uri(Xen_to_C_GtkLinkButton_(link_button)))); } static Xen gxg_gtk_link_button_set_uri(Xen link_button, Xen uri) { #define H_gtk_link_button_set_uri "void gtk_link_button_set_uri(GtkLinkButton* link_button, gchar* uri)" Xen_check_type(Xen_is_GtkLinkButton_(link_button), link_button, 1, "gtk_link_button_set_uri", "GtkLinkButton*"); Xen_check_type(Xen_is_gchar_(uri), uri, 2, "gtk_link_button_set_uri", "gchar*"); gtk_link_button_set_uri(Xen_to_C_GtkLinkButton_(link_button), Xen_to_C_gchar_(uri)); return(Xen_false); } static Xen gxg_gtk_recent_chooser_error_quark(void) { #define H_gtk_recent_chooser_error_quark "GQuark gtk_recent_chooser_error_quark( void)" return(C_to_Xen_GQuark(gtk_recent_chooser_error_quark())); } static Xen gxg_gtk_recent_chooser_set_show_private(Xen chooser, Xen show_private) { #define H_gtk_recent_chooser_set_show_private "void gtk_recent_chooser_set_show_private(GtkRecentChooser* chooser, \ gboolean show_private)" Xen_check_type(Xen_is_GtkRecentChooser_(chooser), chooser, 1, "gtk_recent_chooser_set_show_private", "GtkRecentChooser*"); Xen_check_type(Xen_is_gboolean(show_private), show_private, 2, "gtk_recent_chooser_set_show_private", "gboolean"); gtk_recent_chooser_set_show_private(Xen_to_C_GtkRecentChooser_(chooser), Xen_to_C_gboolean(show_private)); return(Xen_false); } static Xen gxg_gtk_recent_chooser_get_show_private(Xen chooser) { #define H_gtk_recent_chooser_get_show_private "gboolean gtk_recent_chooser_get_show_private(GtkRecentChooser* chooser)" Xen_check_type(Xen_is_GtkRecentChooser_(chooser), chooser, 1, "gtk_recent_chooser_get_show_private", "GtkRecentChooser*"); return(C_to_Xen_gboolean(gtk_recent_chooser_get_show_private(Xen_to_C_GtkRecentChooser_(chooser)))); } static Xen gxg_gtk_recent_chooser_set_show_not_found(Xen chooser, Xen show_not_found) { #define H_gtk_recent_chooser_set_show_not_found "void gtk_recent_chooser_set_show_not_found(GtkRecentChooser* chooser, \ gboolean show_not_found)" Xen_check_type(Xen_is_GtkRecentChooser_(chooser), chooser, 1, "gtk_recent_chooser_set_show_not_found", "GtkRecentChooser*"); Xen_check_type(Xen_is_gboolean(show_not_found), show_not_found, 2, "gtk_recent_chooser_set_show_not_found", "gboolean"); gtk_recent_chooser_set_show_not_found(Xen_to_C_GtkRecentChooser_(chooser), Xen_to_C_gboolean(show_not_found)); return(Xen_false); } static Xen gxg_gtk_recent_chooser_get_show_not_found(Xen chooser) { #define H_gtk_recent_chooser_get_show_not_found "gboolean gtk_recent_chooser_get_show_not_found(GtkRecentChooser* chooser)" Xen_check_type(Xen_is_GtkRecentChooser_(chooser), chooser, 1, "gtk_recent_chooser_get_show_not_found", "GtkRecentChooser*"); return(C_to_Xen_gboolean(gtk_recent_chooser_get_show_not_found(Xen_to_C_GtkRecentChooser_(chooser)))); } static Xen gxg_gtk_recent_chooser_set_select_multiple(Xen chooser, Xen select_multiple) { #define H_gtk_recent_chooser_set_select_multiple "void gtk_recent_chooser_set_select_multiple(GtkRecentChooser* chooser, \ gboolean select_multiple)" Xen_check_type(Xen_is_GtkRecentChooser_(chooser), chooser, 1, "gtk_recent_chooser_set_select_multiple", "GtkRecentChooser*"); Xen_check_type(Xen_is_gboolean(select_multiple), select_multiple, 2, "gtk_recent_chooser_set_select_multiple", "gboolean"); gtk_recent_chooser_set_select_multiple(Xen_to_C_GtkRecentChooser_(chooser), Xen_to_C_gboolean(select_multiple)); return(Xen_false); } static Xen gxg_gtk_recent_chooser_get_select_multiple(Xen chooser) { #define H_gtk_recent_chooser_get_select_multiple "gboolean gtk_recent_chooser_get_select_multiple(GtkRecentChooser* chooser)" Xen_check_type(Xen_is_GtkRecentChooser_(chooser), chooser, 1, "gtk_recent_chooser_get_select_multiple", "GtkRecentChooser*"); return(C_to_Xen_gboolean(gtk_recent_chooser_get_select_multiple(Xen_to_C_GtkRecentChooser_(chooser)))); } static Xen gxg_gtk_recent_chooser_set_limit(Xen chooser, Xen limit) { #define H_gtk_recent_chooser_set_limit "void gtk_recent_chooser_set_limit(GtkRecentChooser* chooser, \ gint limit)" Xen_check_type(Xen_is_GtkRecentChooser_(chooser), chooser, 1, "gtk_recent_chooser_set_limit", "GtkRecentChooser*"); Xen_check_type(Xen_is_gint(limit), limit, 2, "gtk_recent_chooser_set_limit", "gint"); gtk_recent_chooser_set_limit(Xen_to_C_GtkRecentChooser_(chooser), Xen_to_C_gint(limit)); return(Xen_false); } static Xen gxg_gtk_recent_chooser_get_limit(Xen chooser) { #define H_gtk_recent_chooser_get_limit "gint gtk_recent_chooser_get_limit(GtkRecentChooser* chooser)" Xen_check_type(Xen_is_GtkRecentChooser_(chooser), chooser, 1, "gtk_recent_chooser_get_limit", "GtkRecentChooser*"); return(C_to_Xen_gint(gtk_recent_chooser_get_limit(Xen_to_C_GtkRecentChooser_(chooser)))); } static Xen gxg_gtk_recent_chooser_set_local_only(Xen chooser, Xen local_only) { #define H_gtk_recent_chooser_set_local_only "void gtk_recent_chooser_set_local_only(GtkRecentChooser* chooser, \ gboolean local_only)" Xen_check_type(Xen_is_GtkRecentChooser_(chooser), chooser, 1, "gtk_recent_chooser_set_local_only", "GtkRecentChooser*"); Xen_check_type(Xen_is_gboolean(local_only), local_only, 2, "gtk_recent_chooser_set_local_only", "gboolean"); gtk_recent_chooser_set_local_only(Xen_to_C_GtkRecentChooser_(chooser), Xen_to_C_gboolean(local_only)); return(Xen_false); } static Xen gxg_gtk_recent_chooser_get_local_only(Xen chooser) { #define H_gtk_recent_chooser_get_local_only "gboolean gtk_recent_chooser_get_local_only(GtkRecentChooser* chooser)" Xen_check_type(Xen_is_GtkRecentChooser_(chooser), chooser, 1, "gtk_recent_chooser_get_local_only", "GtkRecentChooser*"); return(C_to_Xen_gboolean(gtk_recent_chooser_get_local_only(Xen_to_C_GtkRecentChooser_(chooser)))); } static Xen gxg_gtk_recent_chooser_set_show_tips(Xen chooser, Xen show_tips) { #define H_gtk_recent_chooser_set_show_tips "void gtk_recent_chooser_set_show_tips(GtkRecentChooser* chooser, \ gboolean show_tips)" Xen_check_type(Xen_is_GtkRecentChooser_(chooser), chooser, 1, "gtk_recent_chooser_set_show_tips", "GtkRecentChooser*"); Xen_check_type(Xen_is_gboolean(show_tips), show_tips, 2, "gtk_recent_chooser_set_show_tips", "gboolean"); gtk_recent_chooser_set_show_tips(Xen_to_C_GtkRecentChooser_(chooser), Xen_to_C_gboolean(show_tips)); return(Xen_false); } static Xen gxg_gtk_recent_chooser_get_show_tips(Xen chooser) { #define H_gtk_recent_chooser_get_show_tips "gboolean gtk_recent_chooser_get_show_tips(GtkRecentChooser* chooser)" Xen_check_type(Xen_is_GtkRecentChooser_(chooser), chooser, 1, "gtk_recent_chooser_get_show_tips", "GtkRecentChooser*"); return(C_to_Xen_gboolean(gtk_recent_chooser_get_show_tips(Xen_to_C_GtkRecentChooser_(chooser)))); } static Xen gxg_gtk_recent_chooser_set_show_icons(Xen chooser, Xen show_icons) { #define H_gtk_recent_chooser_set_show_icons "void gtk_recent_chooser_set_show_icons(GtkRecentChooser* chooser, \ gboolean show_icons)" Xen_check_type(Xen_is_GtkRecentChooser_(chooser), chooser, 1, "gtk_recent_chooser_set_show_icons", "GtkRecentChooser*"); Xen_check_type(Xen_is_gboolean(show_icons), show_icons, 2, "gtk_recent_chooser_set_show_icons", "gboolean"); gtk_recent_chooser_set_show_icons(Xen_to_C_GtkRecentChooser_(chooser), Xen_to_C_gboolean(show_icons)); return(Xen_false); } static Xen gxg_gtk_recent_chooser_get_show_icons(Xen chooser) { #define H_gtk_recent_chooser_get_show_icons "gboolean gtk_recent_chooser_get_show_icons(GtkRecentChooser* chooser)" Xen_check_type(Xen_is_GtkRecentChooser_(chooser), chooser, 1, "gtk_recent_chooser_get_show_icons", "GtkRecentChooser*"); return(C_to_Xen_gboolean(gtk_recent_chooser_get_show_icons(Xen_to_C_GtkRecentChooser_(chooser)))); } static Xen gxg_gtk_recent_chooser_set_sort_type(Xen chooser, Xen sort_type) { #define H_gtk_recent_chooser_set_sort_type "void gtk_recent_chooser_set_sort_type(GtkRecentChooser* chooser, \ GtkRecentSortType sort_type)" Xen_check_type(Xen_is_GtkRecentChooser_(chooser), chooser, 1, "gtk_recent_chooser_set_sort_type", "GtkRecentChooser*"); Xen_check_type(Xen_is_GtkRecentSortType(sort_type), sort_type, 2, "gtk_recent_chooser_set_sort_type", "GtkRecentSortType"); gtk_recent_chooser_set_sort_type(Xen_to_C_GtkRecentChooser_(chooser), Xen_to_C_GtkRecentSortType(sort_type)); return(Xen_false); } static Xen gxg_gtk_recent_chooser_get_sort_type(Xen chooser) { #define H_gtk_recent_chooser_get_sort_type "GtkRecentSortType gtk_recent_chooser_get_sort_type(GtkRecentChooser* chooser)" Xen_check_type(Xen_is_GtkRecentChooser_(chooser), chooser, 1, "gtk_recent_chooser_get_sort_type", "GtkRecentChooser*"); return(C_to_Xen_GtkRecentSortType(gtk_recent_chooser_get_sort_type(Xen_to_C_GtkRecentChooser_(chooser)))); } static Xen gxg_gtk_recent_chooser_set_sort_func(Xen chooser, Xen func, Xen func_info, Xen data_destroy) { #define H_gtk_recent_chooser_set_sort_func "void gtk_recent_chooser_set_sort_func(GtkRecentChooser* chooser, \ GtkRecentSortFunc func, lambda_data func_info, GDestroyNotify data_destroy)" Xen_check_type(Xen_is_GtkRecentChooser_(chooser), chooser, 1, "gtk_recent_chooser_set_sort_func", "GtkRecentChooser*"); Xen_check_type(Xen_is_GtkRecentSortFunc(func), func, 2, "gtk_recent_chooser_set_sort_func", "GtkRecentSortFunc"); if (!Xen_is_bound(func_info)) func_info = Xen_false; else Xen_check_type(Xen_is_lambda_data(func_info), func_info, 3, "gtk_recent_chooser_set_sort_func", "lambda_data"); Xen_check_type(Xen_is_GDestroyNotify(data_destroy), data_destroy, 4, "gtk_recent_chooser_set_sort_func", "GDestroyNotify"); { Xen gxg_ptr = Xen_list_5(func, func_info, Xen_false, Xen_false, Xen_false); xm_protect(gxg_ptr); gtk_recent_chooser_set_sort_func(Xen_to_C_GtkRecentChooser_(chooser), Xen_to_C_GtkRecentSortFunc(func), Xen_to_C_lambda_data(func_info), Xen_to_C_GDestroyNotify(data_destroy)); return(Xen_false); } } static Xen gxg_gtk_recent_chooser_set_current_uri(Xen chooser, Xen uri, Xen ignore_error) { #define H_gtk_recent_chooser_set_current_uri "gboolean gtk_recent_chooser_set_current_uri(GtkRecentChooser* chooser, \ gchar* uri, GError** [error])" GError* ref_error = NULL; Xen_check_type(Xen_is_GtkRecentChooser_(chooser), chooser, 1, "gtk_recent_chooser_set_current_uri", "GtkRecentChooser*"); Xen_check_type(Xen_is_gchar_(uri), uri, 2, "gtk_recent_chooser_set_current_uri", "gchar*"); { Xen result; result = C_to_Xen_gboolean(gtk_recent_chooser_set_current_uri(Xen_to_C_GtkRecentChooser_(chooser), Xen_to_C_gchar_(uri), &ref_error)); return(Xen_list_2(result, C_to_Xen_GError_(ref_error))); } } static Xen gxg_gtk_recent_chooser_get_current_uri(Xen chooser) { #define H_gtk_recent_chooser_get_current_uri "gchar* gtk_recent_chooser_get_current_uri(GtkRecentChooser* chooser)" Xen_check_type(Xen_is_GtkRecentChooser_(chooser), chooser, 1, "gtk_recent_chooser_get_current_uri", "GtkRecentChooser*"); return(C_to_Xen_gchar_(gtk_recent_chooser_get_current_uri(Xen_to_C_GtkRecentChooser_(chooser)))); } static Xen gxg_gtk_recent_chooser_get_current_item(Xen chooser) { #define H_gtk_recent_chooser_get_current_item "GtkRecentInfo* gtk_recent_chooser_get_current_item(GtkRecentChooser* chooser)" Xen_check_type(Xen_is_GtkRecentChooser_(chooser), chooser, 1, "gtk_recent_chooser_get_current_item", "GtkRecentChooser*"); return(C_to_Xen_GtkRecentInfo_(gtk_recent_chooser_get_current_item(Xen_to_C_GtkRecentChooser_(chooser)))); } static Xen gxg_gtk_recent_chooser_select_uri(Xen chooser, Xen uri, Xen ignore_error) { #define H_gtk_recent_chooser_select_uri "gboolean gtk_recent_chooser_select_uri(GtkRecentChooser* chooser, \ gchar* uri, GError** [error])" GError* ref_error = NULL; Xen_check_type(Xen_is_GtkRecentChooser_(chooser), chooser, 1, "gtk_recent_chooser_select_uri", "GtkRecentChooser*"); Xen_check_type(Xen_is_gchar_(uri), uri, 2, "gtk_recent_chooser_select_uri", "gchar*"); { Xen result; result = C_to_Xen_gboolean(gtk_recent_chooser_select_uri(Xen_to_C_GtkRecentChooser_(chooser), Xen_to_C_gchar_(uri), &ref_error)); return(Xen_list_2(result, C_to_Xen_GError_(ref_error))); } } static Xen gxg_gtk_recent_chooser_unselect_uri(Xen chooser, Xen uri) { #define H_gtk_recent_chooser_unselect_uri "void gtk_recent_chooser_unselect_uri(GtkRecentChooser* chooser, \ gchar* uri)" Xen_check_type(Xen_is_GtkRecentChooser_(chooser), chooser, 1, "gtk_recent_chooser_unselect_uri", "GtkRecentChooser*"); Xen_check_type(Xen_is_gchar_(uri), uri, 2, "gtk_recent_chooser_unselect_uri", "gchar*"); gtk_recent_chooser_unselect_uri(Xen_to_C_GtkRecentChooser_(chooser), Xen_to_C_gchar_(uri)); return(Xen_false); } static Xen gxg_gtk_recent_chooser_select_all(Xen chooser) { #define H_gtk_recent_chooser_select_all "void gtk_recent_chooser_select_all(GtkRecentChooser* chooser)" Xen_check_type(Xen_is_GtkRecentChooser_(chooser), chooser, 1, "gtk_recent_chooser_select_all", "GtkRecentChooser*"); gtk_recent_chooser_select_all(Xen_to_C_GtkRecentChooser_(chooser)); return(Xen_false); } static Xen gxg_gtk_recent_chooser_unselect_all(Xen chooser) { #define H_gtk_recent_chooser_unselect_all "void gtk_recent_chooser_unselect_all(GtkRecentChooser* chooser)" Xen_check_type(Xen_is_GtkRecentChooser_(chooser), chooser, 1, "gtk_recent_chooser_unselect_all", "GtkRecentChooser*"); gtk_recent_chooser_unselect_all(Xen_to_C_GtkRecentChooser_(chooser)); return(Xen_false); } static Xen gxg_gtk_recent_chooser_get_items(Xen chooser) { #define H_gtk_recent_chooser_get_items "GList* gtk_recent_chooser_get_items(GtkRecentChooser* chooser)" Xen_check_type(Xen_is_GtkRecentChooser_(chooser), chooser, 1, "gtk_recent_chooser_get_items", "GtkRecentChooser*"); return(C_to_Xen_GList_(gtk_recent_chooser_get_items(Xen_to_C_GtkRecentChooser_(chooser)))); } static Xen gxg_gtk_recent_chooser_get_uris(Xen chooser, Xen ignore_length) { #define H_gtk_recent_chooser_get_uris "gchar** gtk_recent_chooser_get_uris(GtkRecentChooser* chooser, \ gsize* [length])" gsize ref_length; Xen_check_type(Xen_is_GtkRecentChooser_(chooser), chooser, 1, "gtk_recent_chooser_get_uris", "GtkRecentChooser*"); { Xen result; result = C_to_Xen_gchar__(gtk_recent_chooser_get_uris(Xen_to_C_GtkRecentChooser_(chooser), &ref_length)); return(Xen_list_2(result, C_to_Xen_gsize(ref_length))); } } static Xen gxg_gtk_recent_chooser_add_filter(Xen chooser, Xen filter) { #define H_gtk_recent_chooser_add_filter "void gtk_recent_chooser_add_filter(GtkRecentChooser* chooser, \ GtkRecentFilter* filter)" Xen_check_type(Xen_is_GtkRecentChooser_(chooser), chooser, 1, "gtk_recent_chooser_add_filter", "GtkRecentChooser*"); Xen_check_type(Xen_is_GtkRecentFilter_(filter), filter, 2, "gtk_recent_chooser_add_filter", "GtkRecentFilter*"); gtk_recent_chooser_add_filter(Xen_to_C_GtkRecentChooser_(chooser), Xen_to_C_GtkRecentFilter_(filter)); return(Xen_false); } static Xen gxg_gtk_recent_chooser_remove_filter(Xen chooser, Xen filter) { #define H_gtk_recent_chooser_remove_filter "void gtk_recent_chooser_remove_filter(GtkRecentChooser* chooser, \ GtkRecentFilter* filter)" Xen_check_type(Xen_is_GtkRecentChooser_(chooser), chooser, 1, "gtk_recent_chooser_remove_filter", "GtkRecentChooser*"); Xen_check_type(Xen_is_GtkRecentFilter_(filter), filter, 2, "gtk_recent_chooser_remove_filter", "GtkRecentFilter*"); gtk_recent_chooser_remove_filter(Xen_to_C_GtkRecentChooser_(chooser), Xen_to_C_GtkRecentFilter_(filter)); return(Xen_false); } static Xen gxg_gtk_recent_chooser_list_filters(Xen chooser) { #define H_gtk_recent_chooser_list_filters "GSList* gtk_recent_chooser_list_filters(GtkRecentChooser* chooser)" Xen_check_type(Xen_is_GtkRecentChooser_(chooser), chooser, 1, "gtk_recent_chooser_list_filters", "GtkRecentChooser*"); return(C_to_Xen_GSList_(gtk_recent_chooser_list_filters(Xen_to_C_GtkRecentChooser_(chooser)))); } static Xen gxg_gtk_recent_chooser_set_filter(Xen chooser, Xen filter) { #define H_gtk_recent_chooser_set_filter "void gtk_recent_chooser_set_filter(GtkRecentChooser* chooser, \ GtkRecentFilter* filter)" Xen_check_type(Xen_is_GtkRecentChooser_(chooser), chooser, 1, "gtk_recent_chooser_set_filter", "GtkRecentChooser*"); Xen_check_type(Xen_is_GtkRecentFilter_(filter), filter, 2, "gtk_recent_chooser_set_filter", "GtkRecentFilter*"); gtk_recent_chooser_set_filter(Xen_to_C_GtkRecentChooser_(chooser), Xen_to_C_GtkRecentFilter_(filter)); return(Xen_false); } static Xen gxg_gtk_recent_chooser_get_filter(Xen chooser) { #define H_gtk_recent_chooser_get_filter "GtkRecentFilter* gtk_recent_chooser_get_filter(GtkRecentChooser* chooser)" Xen_check_type(Xen_is_GtkRecentChooser_(chooser), chooser, 1, "gtk_recent_chooser_get_filter", "GtkRecentChooser*"); return(C_to_Xen_GtkRecentFilter_(gtk_recent_chooser_get_filter(Xen_to_C_GtkRecentChooser_(chooser)))); } static Xen gxg_gtk_recent_chooser_menu_new(void) { #define H_gtk_recent_chooser_menu_new "GtkWidget* gtk_recent_chooser_menu_new( void)" return(C_to_Xen_GtkWidget_(gtk_recent_chooser_menu_new())); } static Xen gxg_gtk_recent_chooser_menu_new_for_manager(Xen manager) { #define H_gtk_recent_chooser_menu_new_for_manager "GtkWidget* gtk_recent_chooser_menu_new_for_manager(GtkRecentManager* manager)" Xen_check_type(Xen_is_GtkRecentManager_(manager), manager, 1, "gtk_recent_chooser_menu_new_for_manager", "GtkRecentManager*"); return(C_to_Xen_GtkWidget_(gtk_recent_chooser_menu_new_for_manager(Xen_to_C_GtkRecentManager_(manager)))); } static Xen gxg_gtk_recent_chooser_menu_get_show_numbers(Xen menu) { #define H_gtk_recent_chooser_menu_get_show_numbers "gboolean gtk_recent_chooser_menu_get_show_numbers(GtkRecentChooserMenu* menu)" Xen_check_type(Xen_is_GtkRecentChooserMenu_(menu), menu, 1, "gtk_recent_chooser_menu_get_show_numbers", "GtkRecentChooserMenu*"); return(C_to_Xen_gboolean(gtk_recent_chooser_menu_get_show_numbers(Xen_to_C_GtkRecentChooserMenu_(menu)))); } static Xen gxg_gtk_recent_chooser_menu_set_show_numbers(Xen menu, Xen show_numbers) { #define H_gtk_recent_chooser_menu_set_show_numbers "void gtk_recent_chooser_menu_set_show_numbers(GtkRecentChooserMenu* menu, \ gboolean show_numbers)" Xen_check_type(Xen_is_GtkRecentChooserMenu_(menu), menu, 1, "gtk_recent_chooser_menu_set_show_numbers", "GtkRecentChooserMenu*"); Xen_check_type(Xen_is_gboolean(show_numbers), show_numbers, 2, "gtk_recent_chooser_menu_set_show_numbers", "gboolean"); gtk_recent_chooser_menu_set_show_numbers(Xen_to_C_GtkRecentChooserMenu_(menu), Xen_to_C_gboolean(show_numbers)); return(Xen_false); } static Xen gxg_gtk_recent_chooser_widget_new(void) { #define H_gtk_recent_chooser_widget_new "GtkWidget* gtk_recent_chooser_widget_new( void)" return(C_to_Xen_GtkWidget_(gtk_recent_chooser_widget_new())); } static Xen gxg_gtk_recent_chooser_widget_new_for_manager(Xen manager) { #define H_gtk_recent_chooser_widget_new_for_manager "GtkWidget* gtk_recent_chooser_widget_new_for_manager(GtkRecentManager* manager)" Xen_check_type(Xen_is_GtkRecentManager_(manager), manager, 1, "gtk_recent_chooser_widget_new_for_manager", "GtkRecentManager*"); return(C_to_Xen_GtkWidget_(gtk_recent_chooser_widget_new_for_manager(Xen_to_C_GtkRecentManager_(manager)))); } static Xen gxg_gtk_recent_filter_new(void) { #define H_gtk_recent_filter_new "GtkRecentFilter* gtk_recent_filter_new( void)" return(C_to_Xen_GtkRecentFilter_(gtk_recent_filter_new())); } static Xen gxg_gtk_recent_filter_set_name(Xen filter, Xen name) { #define H_gtk_recent_filter_set_name "void gtk_recent_filter_set_name(GtkRecentFilter* filter, gchar* name)" Xen_check_type(Xen_is_GtkRecentFilter_(filter), filter, 1, "gtk_recent_filter_set_name", "GtkRecentFilter*"); Xen_check_type(Xen_is_gchar_(name), name, 2, "gtk_recent_filter_set_name", "gchar*"); gtk_recent_filter_set_name(Xen_to_C_GtkRecentFilter_(filter), Xen_to_C_gchar_(name)); return(Xen_false); } static Xen gxg_gtk_recent_filter_get_name(Xen filter) { #define H_gtk_recent_filter_get_name "gchar* gtk_recent_filter_get_name(GtkRecentFilter* filter)" Xen_check_type(Xen_is_GtkRecentFilter_(filter), filter, 1, "gtk_recent_filter_get_name", "GtkRecentFilter*"); return(C_to_Xen_gchar_((gchar*)gtk_recent_filter_get_name(Xen_to_C_GtkRecentFilter_(filter)))); } static Xen gxg_gtk_recent_filter_add_mime_type(Xen filter, Xen mime_type) { #define H_gtk_recent_filter_add_mime_type "void gtk_recent_filter_add_mime_type(GtkRecentFilter* filter, \ gchar* mime_type)" Xen_check_type(Xen_is_GtkRecentFilter_(filter), filter, 1, "gtk_recent_filter_add_mime_type", "GtkRecentFilter*"); Xen_check_type(Xen_is_gchar_(mime_type), mime_type, 2, "gtk_recent_filter_add_mime_type", "gchar*"); gtk_recent_filter_add_mime_type(Xen_to_C_GtkRecentFilter_(filter), Xen_to_C_gchar_(mime_type)); return(Xen_false); } static Xen gxg_gtk_recent_filter_add_pattern(Xen filter, Xen pattern) { #define H_gtk_recent_filter_add_pattern "void gtk_recent_filter_add_pattern(GtkRecentFilter* filter, \ gchar* pattern)" Xen_check_type(Xen_is_GtkRecentFilter_(filter), filter, 1, "gtk_recent_filter_add_pattern", "GtkRecentFilter*"); Xen_check_type(Xen_is_gchar_(pattern), pattern, 2, "gtk_recent_filter_add_pattern", "gchar*"); gtk_recent_filter_add_pattern(Xen_to_C_GtkRecentFilter_(filter), Xen_to_C_gchar_(pattern)); return(Xen_false); } static Xen gxg_gtk_recent_filter_add_pixbuf_formats(Xen filter) { #define H_gtk_recent_filter_add_pixbuf_formats "void gtk_recent_filter_add_pixbuf_formats(GtkRecentFilter* filter)" Xen_check_type(Xen_is_GtkRecentFilter_(filter), filter, 1, "gtk_recent_filter_add_pixbuf_formats", "GtkRecentFilter*"); gtk_recent_filter_add_pixbuf_formats(Xen_to_C_GtkRecentFilter_(filter)); return(Xen_false); } static Xen gxg_gtk_recent_filter_add_application(Xen filter, Xen application) { #define H_gtk_recent_filter_add_application "void gtk_recent_filter_add_application(GtkRecentFilter* filter, \ gchar* application)" Xen_check_type(Xen_is_GtkRecentFilter_(filter), filter, 1, "gtk_recent_filter_add_application", "GtkRecentFilter*"); Xen_check_type(Xen_is_gchar_(application), application, 2, "gtk_recent_filter_add_application", "gchar*"); gtk_recent_filter_add_application(Xen_to_C_GtkRecentFilter_(filter), Xen_to_C_gchar_(application)); return(Xen_false); } static Xen gxg_gtk_recent_filter_add_group(Xen filter, Xen group) { #define H_gtk_recent_filter_add_group "void gtk_recent_filter_add_group(GtkRecentFilter* filter, gchar* group)" Xen_check_type(Xen_is_GtkRecentFilter_(filter), filter, 1, "gtk_recent_filter_add_group", "GtkRecentFilter*"); Xen_check_type(Xen_is_gchar_(group), group, 2, "gtk_recent_filter_add_group", "gchar*"); gtk_recent_filter_add_group(Xen_to_C_GtkRecentFilter_(filter), Xen_to_C_gchar_(group)); return(Xen_false); } static Xen gxg_gtk_recent_filter_add_age(Xen filter, Xen days) { #define H_gtk_recent_filter_add_age "void gtk_recent_filter_add_age(GtkRecentFilter* filter, gint days)" Xen_check_type(Xen_is_GtkRecentFilter_(filter), filter, 1, "gtk_recent_filter_add_age", "GtkRecentFilter*"); Xen_check_type(Xen_is_gint(days), days, 2, "gtk_recent_filter_add_age", "gint"); gtk_recent_filter_add_age(Xen_to_C_GtkRecentFilter_(filter), Xen_to_C_gint(days)); return(Xen_false); } static Xen gxg_gtk_recent_manager_error_quark(void) { #define H_gtk_recent_manager_error_quark "GQuark gtk_recent_manager_error_quark( void)" return(C_to_Xen_GQuark(gtk_recent_manager_error_quark())); } static Xen gxg_gtk_recent_manager_new(void) { #define H_gtk_recent_manager_new "GtkRecentManager* gtk_recent_manager_new( void)" return(C_to_Xen_GtkRecentManager_(gtk_recent_manager_new())); } static Xen gxg_gtk_recent_manager_get_default(void) { #define H_gtk_recent_manager_get_default "GtkRecentManager* gtk_recent_manager_get_default( void)" return(C_to_Xen_GtkRecentManager_(gtk_recent_manager_get_default())); } static Xen gxg_gtk_recent_manager_remove_item(Xen manager, Xen uri, Xen ignore_error) { #define H_gtk_recent_manager_remove_item "gboolean gtk_recent_manager_remove_item(GtkRecentManager* manager, \ gchar* uri, GError** [error])" GError* ref_error = NULL; Xen_check_type(Xen_is_GtkRecentManager_(manager), manager, 1, "gtk_recent_manager_remove_item", "GtkRecentManager*"); Xen_check_type(Xen_is_gchar_(uri), uri, 2, "gtk_recent_manager_remove_item", "gchar*"); { Xen result; result = C_to_Xen_gboolean(gtk_recent_manager_remove_item(Xen_to_C_GtkRecentManager_(manager), Xen_to_C_gchar_(uri), &ref_error)); return(Xen_list_2(result, C_to_Xen_GError_(ref_error))); } } static Xen gxg_gtk_recent_manager_lookup_item(Xen manager, Xen uri, Xen ignore_error) { #define H_gtk_recent_manager_lookup_item "GtkRecentInfo* gtk_recent_manager_lookup_item(GtkRecentManager* manager, \ gchar* uri, GError** [error])" GError* ref_error = NULL; Xen_check_type(Xen_is_GtkRecentManager_(manager), manager, 1, "gtk_recent_manager_lookup_item", "GtkRecentManager*"); Xen_check_type(Xen_is_gchar_(uri), uri, 2, "gtk_recent_manager_lookup_item", "gchar*"); { Xen result; result = C_to_Xen_GtkRecentInfo_(gtk_recent_manager_lookup_item(Xen_to_C_GtkRecentManager_(manager), Xen_to_C_gchar_(uri), &ref_error)); return(Xen_list_2(result, C_to_Xen_GError_(ref_error))); } } static Xen gxg_gtk_recent_manager_has_item(Xen manager, Xen uri) { #define H_gtk_recent_manager_has_item "gboolean gtk_recent_manager_has_item(GtkRecentManager* manager, \ gchar* uri)" Xen_check_type(Xen_is_GtkRecentManager_(manager), manager, 1, "gtk_recent_manager_has_item", "GtkRecentManager*"); Xen_check_type(Xen_is_gchar_(uri), uri, 2, "gtk_recent_manager_has_item", "gchar*"); return(C_to_Xen_gboolean(gtk_recent_manager_has_item(Xen_to_C_GtkRecentManager_(manager), Xen_to_C_gchar_(uri)))); } static Xen gxg_gtk_recent_manager_move_item(Xen manager, Xen uri, Xen new_uri, Xen ignore_error) { #define H_gtk_recent_manager_move_item "gboolean gtk_recent_manager_move_item(GtkRecentManager* manager, \ gchar* uri, gchar* new_uri, GError** [error])" GError* ref_error = NULL; Xen_check_type(Xen_is_GtkRecentManager_(manager), manager, 1, "gtk_recent_manager_move_item", "GtkRecentManager*"); Xen_check_type(Xen_is_gchar_(uri), uri, 2, "gtk_recent_manager_move_item", "gchar*"); Xen_check_type(Xen_is_gchar_(new_uri), new_uri, 3, "gtk_recent_manager_move_item", "gchar*"); { Xen result; result = C_to_Xen_gboolean(gtk_recent_manager_move_item(Xen_to_C_GtkRecentManager_(manager), Xen_to_C_gchar_(uri), Xen_to_C_gchar_(new_uri), &ref_error)); return(Xen_list_2(result, C_to_Xen_GError_(ref_error))); } } static Xen gxg_gtk_recent_manager_get_items(Xen manager) { #define H_gtk_recent_manager_get_items "GList* gtk_recent_manager_get_items(GtkRecentManager* manager)" Xen_check_type(Xen_is_GtkRecentManager_(manager), manager, 1, "gtk_recent_manager_get_items", "GtkRecentManager*"); return(C_to_Xen_GList_(gtk_recent_manager_get_items(Xen_to_C_GtkRecentManager_(manager)))); } static Xen gxg_gtk_recent_manager_purge_items(Xen manager, Xen ignore_error) { #define H_gtk_recent_manager_purge_items "gint gtk_recent_manager_purge_items(GtkRecentManager* manager, \ GError** [error])" GError* ref_error = NULL; Xen_check_type(Xen_is_GtkRecentManager_(manager), manager, 1, "gtk_recent_manager_purge_items", "GtkRecentManager*"); { Xen result; result = C_to_Xen_gint(gtk_recent_manager_purge_items(Xen_to_C_GtkRecentManager_(manager), &ref_error)); return(Xen_list_2(result, C_to_Xen_GError_(ref_error))); } } static Xen gxg_gtk_recent_info_ref(Xen info) { #define H_gtk_recent_info_ref "GtkRecentInfo* gtk_recent_info_ref(GtkRecentInfo* info)" Xen_check_type(Xen_is_GtkRecentInfo_(info), info, 1, "gtk_recent_info_ref", "GtkRecentInfo*"); return(C_to_Xen_GtkRecentInfo_(gtk_recent_info_ref(Xen_to_C_GtkRecentInfo_(info)))); } static Xen gxg_gtk_recent_info_unref(Xen info) { #define H_gtk_recent_info_unref "void gtk_recent_info_unref(GtkRecentInfo* info)" Xen_check_type(Xen_is_GtkRecentInfo_(info), info, 1, "gtk_recent_info_unref", "GtkRecentInfo*"); gtk_recent_info_unref(Xen_to_C_GtkRecentInfo_(info)); return(Xen_false); } static Xen gxg_gtk_recent_info_get_uri(Xen info) { #define H_gtk_recent_info_get_uri "gchar* gtk_recent_info_get_uri(GtkRecentInfo* info)" Xen_check_type(Xen_is_GtkRecentInfo_(info), info, 1, "gtk_recent_info_get_uri", "GtkRecentInfo*"); return(C_to_Xen_gchar_(gtk_recent_info_get_uri(Xen_to_C_GtkRecentInfo_(info)))); } static Xen gxg_gtk_recent_info_get_display_name(Xen info) { #define H_gtk_recent_info_get_display_name "gchar* gtk_recent_info_get_display_name(GtkRecentInfo* info)" Xen_check_type(Xen_is_GtkRecentInfo_(info), info, 1, "gtk_recent_info_get_display_name", "GtkRecentInfo*"); return(C_to_Xen_gchar_((gchar*)gtk_recent_info_get_display_name(Xen_to_C_GtkRecentInfo_(info)))); } static Xen gxg_gtk_recent_info_get_description(Xen info) { #define H_gtk_recent_info_get_description "gchar* gtk_recent_info_get_description(GtkRecentInfo* info)" Xen_check_type(Xen_is_GtkRecentInfo_(info), info, 1, "gtk_recent_info_get_description", "GtkRecentInfo*"); return(C_to_Xen_gchar_((gchar*)gtk_recent_info_get_description(Xen_to_C_GtkRecentInfo_(info)))); } static Xen gxg_gtk_recent_info_get_mime_type(Xen info) { #define H_gtk_recent_info_get_mime_type "gchar* gtk_recent_info_get_mime_type(GtkRecentInfo* info)" Xen_check_type(Xen_is_GtkRecentInfo_(info), info, 1, "gtk_recent_info_get_mime_type", "GtkRecentInfo*"); return(C_to_Xen_gchar_((gchar*)gtk_recent_info_get_mime_type(Xen_to_C_GtkRecentInfo_(info)))); } static Xen gxg_gtk_recent_info_get_added(Xen info) { #define H_gtk_recent_info_get_added "time_t gtk_recent_info_get_added(GtkRecentInfo* info)" Xen_check_type(Xen_is_GtkRecentInfo_(info), info, 1, "gtk_recent_info_get_added", "GtkRecentInfo*"); return(C_to_Xen_time_t(gtk_recent_info_get_added(Xen_to_C_GtkRecentInfo_(info)))); } static Xen gxg_gtk_recent_info_get_modified(Xen info) { #define H_gtk_recent_info_get_modified "time_t gtk_recent_info_get_modified(GtkRecentInfo* info)" Xen_check_type(Xen_is_GtkRecentInfo_(info), info, 1, "gtk_recent_info_get_modified", "GtkRecentInfo*"); return(C_to_Xen_time_t(gtk_recent_info_get_modified(Xen_to_C_GtkRecentInfo_(info)))); } static Xen gxg_gtk_recent_info_get_visited(Xen info) { #define H_gtk_recent_info_get_visited "time_t gtk_recent_info_get_visited(GtkRecentInfo* info)" Xen_check_type(Xen_is_GtkRecentInfo_(info), info, 1, "gtk_recent_info_get_visited", "GtkRecentInfo*"); return(C_to_Xen_time_t(gtk_recent_info_get_visited(Xen_to_C_GtkRecentInfo_(info)))); } static Xen gxg_gtk_recent_info_get_private_hint(Xen info) { #define H_gtk_recent_info_get_private_hint "gboolean gtk_recent_info_get_private_hint(GtkRecentInfo* info)" Xen_check_type(Xen_is_GtkRecentInfo_(info), info, 1, "gtk_recent_info_get_private_hint", "GtkRecentInfo*"); return(C_to_Xen_gboolean(gtk_recent_info_get_private_hint(Xen_to_C_GtkRecentInfo_(info)))); } static Xen gxg_gtk_recent_info_get_applications(Xen info, Xen ignore_length) { #define H_gtk_recent_info_get_applications "gchar** gtk_recent_info_get_applications(GtkRecentInfo* info, \ gsize* [length])" gsize ref_length; Xen_check_type(Xen_is_GtkRecentInfo_(info), info, 1, "gtk_recent_info_get_applications", "GtkRecentInfo*"); { Xen result; result = C_to_Xen_gchar__(gtk_recent_info_get_applications(Xen_to_C_GtkRecentInfo_(info), &ref_length)); return(Xen_list_2(result, C_to_Xen_gsize(ref_length))); } } static Xen gxg_gtk_recent_info_last_application(Xen info) { #define H_gtk_recent_info_last_application "gchar* gtk_recent_info_last_application(GtkRecentInfo* info)" Xen_check_type(Xen_is_GtkRecentInfo_(info), info, 1, "gtk_recent_info_last_application", "GtkRecentInfo*"); return(C_to_Xen_gchar_(gtk_recent_info_last_application(Xen_to_C_GtkRecentInfo_(info)))); } static Xen gxg_gtk_recent_info_has_application(Xen info, Xen app_name) { #define H_gtk_recent_info_has_application "gboolean gtk_recent_info_has_application(GtkRecentInfo* info, \ gchar* app_name)" Xen_check_type(Xen_is_GtkRecentInfo_(info), info, 1, "gtk_recent_info_has_application", "GtkRecentInfo*"); Xen_check_type(Xen_is_gchar_(app_name), app_name, 2, "gtk_recent_info_has_application", "gchar*"); return(C_to_Xen_gboolean(gtk_recent_info_has_application(Xen_to_C_GtkRecentInfo_(info), Xen_to_C_gchar_(app_name)))); } static Xen gxg_gtk_recent_info_get_groups(Xen info, Xen ignore_length) { #define H_gtk_recent_info_get_groups "gchar** gtk_recent_info_get_groups(GtkRecentInfo* info, gsize* [length])" gsize ref_length; Xen_check_type(Xen_is_GtkRecentInfo_(info), info, 1, "gtk_recent_info_get_groups", "GtkRecentInfo*"); { Xen result; result = C_to_Xen_gchar__(gtk_recent_info_get_groups(Xen_to_C_GtkRecentInfo_(info), &ref_length)); return(Xen_list_2(result, C_to_Xen_gsize(ref_length))); } } static Xen gxg_gtk_recent_info_has_group(Xen info, Xen group_name) { #define H_gtk_recent_info_has_group "gboolean gtk_recent_info_has_group(GtkRecentInfo* info, gchar* group_name)" Xen_check_type(Xen_is_GtkRecentInfo_(info), info, 1, "gtk_recent_info_has_group", "GtkRecentInfo*"); Xen_check_type(Xen_is_gchar_(group_name), group_name, 2, "gtk_recent_info_has_group", "gchar*"); return(C_to_Xen_gboolean(gtk_recent_info_has_group(Xen_to_C_GtkRecentInfo_(info), Xen_to_C_gchar_(group_name)))); } static Xen gxg_gtk_recent_info_get_icon(Xen info, Xen size) { #define H_gtk_recent_info_get_icon "GdkPixbuf* gtk_recent_info_get_icon(GtkRecentInfo* info, gint size)" Xen_check_type(Xen_is_GtkRecentInfo_(info), info, 1, "gtk_recent_info_get_icon", "GtkRecentInfo*"); Xen_check_type(Xen_is_gint(size), size, 2, "gtk_recent_info_get_icon", "gint"); return(C_to_Xen_GdkPixbuf_(gtk_recent_info_get_icon(Xen_to_C_GtkRecentInfo_(info), Xen_to_C_gint(size)))); } static Xen gxg_gtk_recent_info_get_short_name(Xen info) { #define H_gtk_recent_info_get_short_name "gchar* gtk_recent_info_get_short_name(GtkRecentInfo* info)" Xen_check_type(Xen_is_GtkRecentInfo_(info), info, 1, "gtk_recent_info_get_short_name", "GtkRecentInfo*"); return(C_to_Xen_gchar_(gtk_recent_info_get_short_name(Xen_to_C_GtkRecentInfo_(info)))); } static Xen gxg_gtk_recent_info_get_uri_display(Xen info) { #define H_gtk_recent_info_get_uri_display "gchar* gtk_recent_info_get_uri_display(GtkRecentInfo* info)" Xen_check_type(Xen_is_GtkRecentInfo_(info), info, 1, "gtk_recent_info_get_uri_display", "GtkRecentInfo*"); return(C_to_Xen_gchar_(gtk_recent_info_get_uri_display(Xen_to_C_GtkRecentInfo_(info)))); } static Xen gxg_gtk_recent_info_get_age(Xen info) { #define H_gtk_recent_info_get_age "gint gtk_recent_info_get_age(GtkRecentInfo* info)" Xen_check_type(Xen_is_GtkRecentInfo_(info), info, 1, "gtk_recent_info_get_age", "GtkRecentInfo*"); return(C_to_Xen_gint(gtk_recent_info_get_age(Xen_to_C_GtkRecentInfo_(info)))); } static Xen gxg_gtk_recent_info_is_local(Xen info) { #define H_gtk_recent_info_is_local "gboolean gtk_recent_info_is_local(GtkRecentInfo* info)" Xen_check_type(Xen_is_GtkRecentInfo_(info), info, 1, "gtk_recent_info_is_local", "GtkRecentInfo*"); return(C_to_Xen_gboolean(gtk_recent_info_is_local(Xen_to_C_GtkRecentInfo_(info)))); } static Xen gxg_gtk_recent_info_exists(Xen info) { #define H_gtk_recent_info_exists "gboolean gtk_recent_info_exists(GtkRecentInfo* info)" Xen_check_type(Xen_is_GtkRecentInfo_(info), info, 1, "gtk_recent_info_exists", "GtkRecentInfo*"); return(C_to_Xen_gboolean(gtk_recent_info_exists(Xen_to_C_GtkRecentInfo_(info)))); } static Xen gxg_gtk_recent_info_match(Xen info_a, Xen info_b) { #define H_gtk_recent_info_match "gboolean gtk_recent_info_match(GtkRecentInfo* info_a, GtkRecentInfo* info_b)" Xen_check_type(Xen_is_GtkRecentInfo_(info_a), info_a, 1, "gtk_recent_info_match", "GtkRecentInfo*"); Xen_check_type(Xen_is_GtkRecentInfo_(info_b), info_b, 2, "gtk_recent_info_match", "GtkRecentInfo*"); return(C_to_Xen_gboolean(gtk_recent_info_match(Xen_to_C_GtkRecentInfo_(info_a), Xen_to_C_GtkRecentInfo_(info_b)))); } static Xen gxg_gtk_text_buffer_register_serialize_format(Xen buffer, Xen mime_type, Xen function, Xen user_data, Xen user_data_destroy) { #define H_gtk_text_buffer_register_serialize_format "GdkAtom gtk_text_buffer_register_serialize_format(GtkTextBuffer* buffer, \ gchar* mime_type, GtkTextBufferSerializeFunc function, gpointer user_data, GDestroyNotify user_data_destroy)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_register_serialize_format", "GtkTextBuffer*"); Xen_check_type(Xen_is_gchar_(mime_type), mime_type, 2, "gtk_text_buffer_register_serialize_format", "gchar*"); Xen_check_type(Xen_is_GtkTextBufferSerializeFunc(function), function, 3, "gtk_text_buffer_register_serialize_format", "GtkTextBufferSerializeFunc"); Xen_check_type(Xen_is_gpointer(user_data), user_data, 4, "gtk_text_buffer_register_serialize_format", "gpointer"); Xen_check_type(Xen_is_GDestroyNotify(user_data_destroy), user_data_destroy, 5, "gtk_text_buffer_register_serialize_format", "GDestroyNotify"); return(C_to_Xen_GdkAtom(gtk_text_buffer_register_serialize_format(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_gchar_(mime_type), Xen_to_C_GtkTextBufferSerializeFunc(function), Xen_to_C_gpointer(user_data), Xen_to_C_GDestroyNotify(user_data_destroy)))); } static Xen gxg_gtk_text_buffer_register_serialize_tagset(Xen buffer, Xen tagset_name) { #define H_gtk_text_buffer_register_serialize_tagset "GdkAtom gtk_text_buffer_register_serialize_tagset(GtkTextBuffer* buffer, \ gchar* tagset_name)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_register_serialize_tagset", "GtkTextBuffer*"); Xen_check_type(Xen_is_gchar_(tagset_name), tagset_name, 2, "gtk_text_buffer_register_serialize_tagset", "gchar*"); return(C_to_Xen_GdkAtom(gtk_text_buffer_register_serialize_tagset(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_gchar_(tagset_name)))); } static Xen gxg_gtk_text_buffer_register_deserialize_format(Xen buffer, Xen mime_type, Xen function, Xen user_data, Xen user_data_destroy) { #define H_gtk_text_buffer_register_deserialize_format "GdkAtom gtk_text_buffer_register_deserialize_format(GtkTextBuffer* buffer, \ gchar* mime_type, GtkTextBufferDeserializeFunc function, gpointer user_data, GDestroyNotify user_data_destroy)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_register_deserialize_format", "GtkTextBuffer*"); Xen_check_type(Xen_is_gchar_(mime_type), mime_type, 2, "gtk_text_buffer_register_deserialize_format", "gchar*"); Xen_check_type(Xen_is_GtkTextBufferDeserializeFunc(function), function, 3, "gtk_text_buffer_register_deserialize_format", "GtkTextBufferDeserializeFunc"); Xen_check_type(Xen_is_gpointer(user_data), user_data, 4, "gtk_text_buffer_register_deserialize_format", "gpointer"); Xen_check_type(Xen_is_GDestroyNotify(user_data_destroy), user_data_destroy, 5, "gtk_text_buffer_register_deserialize_format", "GDestroyNotify"); return(C_to_Xen_GdkAtom(gtk_text_buffer_register_deserialize_format(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_gchar_(mime_type), Xen_to_C_GtkTextBufferDeserializeFunc(function), Xen_to_C_gpointer(user_data), Xen_to_C_GDestroyNotify(user_data_destroy)))); } static Xen gxg_gtk_text_buffer_register_deserialize_tagset(Xen buffer, Xen tagset_name) { #define H_gtk_text_buffer_register_deserialize_tagset "GdkAtom gtk_text_buffer_register_deserialize_tagset(GtkTextBuffer* buffer, \ gchar* tagset_name)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_register_deserialize_tagset", "GtkTextBuffer*"); Xen_check_type(Xen_is_gchar_(tagset_name), tagset_name, 2, "gtk_text_buffer_register_deserialize_tagset", "gchar*"); return(C_to_Xen_GdkAtom(gtk_text_buffer_register_deserialize_tagset(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_gchar_(tagset_name)))); } static Xen gxg_gtk_text_buffer_unregister_serialize_format(Xen buffer, Xen format) { #define H_gtk_text_buffer_unregister_serialize_format "void gtk_text_buffer_unregister_serialize_format(GtkTextBuffer* buffer, \ GdkAtom format)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_unregister_serialize_format", "GtkTextBuffer*"); Xen_check_type(Xen_is_GdkAtom(format), format, 2, "gtk_text_buffer_unregister_serialize_format", "GdkAtom"); gtk_text_buffer_unregister_serialize_format(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_GdkAtom(format)); return(Xen_false); } static Xen gxg_gtk_text_buffer_unregister_deserialize_format(Xen buffer, Xen format) { #define H_gtk_text_buffer_unregister_deserialize_format "void gtk_text_buffer_unregister_deserialize_format(GtkTextBuffer* buffer, \ GdkAtom format)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_unregister_deserialize_format", "GtkTextBuffer*"); Xen_check_type(Xen_is_GdkAtom(format), format, 2, "gtk_text_buffer_unregister_deserialize_format", "GdkAtom"); gtk_text_buffer_unregister_deserialize_format(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_GdkAtom(format)); return(Xen_false); } static Xen gxg_gtk_text_buffer_deserialize_set_can_create_tags(Xen buffer, Xen format, Xen can_create_tags) { #define H_gtk_text_buffer_deserialize_set_can_create_tags "void gtk_text_buffer_deserialize_set_can_create_tags(GtkTextBuffer* buffer, \ GdkAtom format, gboolean can_create_tags)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_deserialize_set_can_create_tags", "GtkTextBuffer*"); Xen_check_type(Xen_is_GdkAtom(format), format, 2, "gtk_text_buffer_deserialize_set_can_create_tags", "GdkAtom"); Xen_check_type(Xen_is_gboolean(can_create_tags), can_create_tags, 3, "gtk_text_buffer_deserialize_set_can_create_tags", "gboolean"); gtk_text_buffer_deserialize_set_can_create_tags(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_GdkAtom(format), Xen_to_C_gboolean(can_create_tags)); return(Xen_false); } static Xen gxg_gtk_text_buffer_deserialize_get_can_create_tags(Xen buffer, Xen format) { #define H_gtk_text_buffer_deserialize_get_can_create_tags "gboolean gtk_text_buffer_deserialize_get_can_create_tags(GtkTextBuffer* buffer, \ GdkAtom format)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_deserialize_get_can_create_tags", "GtkTextBuffer*"); Xen_check_type(Xen_is_GdkAtom(format), format, 2, "gtk_text_buffer_deserialize_get_can_create_tags", "GdkAtom"); return(C_to_Xen_gboolean(gtk_text_buffer_deserialize_get_can_create_tags(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_GdkAtom(format)))); } static Xen gxg_gtk_text_buffer_get_serialize_formats(Xen buffer, Xen ignore_n_formats) { #define H_gtk_text_buffer_get_serialize_formats "GdkAtom* gtk_text_buffer_get_serialize_formats(GtkTextBuffer* buffer, \ gint* [n_formats])" gint ref_n_formats; Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_get_serialize_formats", "GtkTextBuffer*"); { Xen result; result = C_to_Xen_GdkAtom_(gtk_text_buffer_get_serialize_formats(Xen_to_C_GtkTextBuffer_(buffer), &ref_n_formats)); return(Xen_list_2(result, C_to_Xen_gint(ref_n_formats))); } } static Xen gxg_gtk_text_buffer_get_deserialize_formats(Xen buffer, Xen ignore_n_formats) { #define H_gtk_text_buffer_get_deserialize_formats "GdkAtom* gtk_text_buffer_get_deserialize_formats(GtkTextBuffer* buffer, \ gint* [n_formats])" gint ref_n_formats; Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_get_deserialize_formats", "GtkTextBuffer*"); { Xen result; result = C_to_Xen_GdkAtom_(gtk_text_buffer_get_deserialize_formats(Xen_to_C_GtkTextBuffer_(buffer), &ref_n_formats)); return(Xen_list_2(result, C_to_Xen_gint(ref_n_formats))); } } static Xen gxg_gtk_text_buffer_serialize(Xen register_buffer, Xen content_buffer, Xen format, Xen start, Xen end, Xen ignore_length) { #define H_gtk_text_buffer_serialize "guint8* gtk_text_buffer_serialize(GtkTextBuffer* register_buffer, \ GtkTextBuffer* content_buffer, GdkAtom format, GtkTextIter* start, GtkTextIter* end, gsize* [length])" gsize ref_length; Xen_check_type(Xen_is_GtkTextBuffer_(register_buffer), register_buffer, 1, "gtk_text_buffer_serialize", "GtkTextBuffer*"); Xen_check_type(Xen_is_GtkTextBuffer_(content_buffer), content_buffer, 2, "gtk_text_buffer_serialize", "GtkTextBuffer*"); Xen_check_type(Xen_is_GdkAtom(format), format, 3, "gtk_text_buffer_serialize", "GdkAtom"); Xen_check_type(Xen_is_GtkTextIter_(start), start, 4, "gtk_text_buffer_serialize", "GtkTextIter*"); Xen_check_type(Xen_is_GtkTextIter_(end), end, 5, "gtk_text_buffer_serialize", "GtkTextIter*"); { Xen result; result = C_to_Xen_guint8_(gtk_text_buffer_serialize(Xen_to_C_GtkTextBuffer_(register_buffer), Xen_to_C_GtkTextBuffer_(content_buffer), Xen_to_C_GdkAtom(format), Xen_to_C_GtkTextIter_(start), Xen_to_C_GtkTextIter_(end), &ref_length)); return(Xen_list_2(result, C_to_Xen_gsize(ref_length))); } } static Xen gxg_gtk_text_buffer_deserialize(Xen register_buffer, Xen content_buffer, Xen format, Xen iter, Xen data, Xen length, Xen ignore_error) { #define H_gtk_text_buffer_deserialize "gboolean gtk_text_buffer_deserialize(GtkTextBuffer* register_buffer, \ GtkTextBuffer* content_buffer, GdkAtom format, GtkTextIter* iter, guint8* data, gsize length, GError** [error])" GError* ref_error = NULL; Xen_check_type(Xen_is_GtkTextBuffer_(register_buffer), register_buffer, 1, "gtk_text_buffer_deserialize", "GtkTextBuffer*"); Xen_check_type(Xen_is_GtkTextBuffer_(content_buffer), content_buffer, 2, "gtk_text_buffer_deserialize", "GtkTextBuffer*"); Xen_check_type(Xen_is_GdkAtom(format), format, 3, "gtk_text_buffer_deserialize", "GdkAtom"); Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 4, "gtk_text_buffer_deserialize", "GtkTextIter*"); Xen_check_type(Xen_is_guint8_(data), data, 5, "gtk_text_buffer_deserialize", "guint8*"); Xen_check_type(Xen_is_gsize(length), length, 6, "gtk_text_buffer_deserialize", "gsize"); { Xen result; result = C_to_Xen_gboolean(gtk_text_buffer_deserialize(Xen_to_C_GtkTextBuffer_(register_buffer), Xen_to_C_GtkTextBuffer_(content_buffer), Xen_to_C_GdkAtom(format), Xen_to_C_GtkTextIter_(iter), Xen_to_C_guint8_(data), Xen_to_C_gsize(length), &ref_error)); return(Xen_list_2(result, C_to_Xen_GError_(ref_error))); } } static Xen gxg_gtk_recent_manager_add_item(Xen manager, Xen uri) { #define H_gtk_recent_manager_add_item "gboolean gtk_recent_manager_add_item(GtkRecentManager* manager, \ gchar* uri)" Xen_check_type(Xen_is_GtkRecentManager_(manager), manager, 1, "gtk_recent_manager_add_item", "GtkRecentManager*"); Xen_check_type(Xen_is_gchar_(uri), uri, 2, "gtk_recent_manager_add_item", "gchar*"); return(C_to_Xen_gboolean(gtk_recent_manager_add_item(Xen_to_C_GtkRecentManager_(manager), Xen_to_C_gchar_(uri)))); } static Xen gxg_gtk_recent_manager_add_full(Xen manager, Xen uri, Xen recent_data) { #define H_gtk_recent_manager_add_full "gboolean gtk_recent_manager_add_full(GtkRecentManager* manager, \ gchar* uri, GtkRecentData* recent_data)" Xen_check_type(Xen_is_GtkRecentManager_(manager), manager, 1, "gtk_recent_manager_add_full", "GtkRecentManager*"); Xen_check_type(Xen_is_gchar_(uri), uri, 2, "gtk_recent_manager_add_full", "gchar*"); Xen_check_type(Xen_is_GtkRecentData_(recent_data), recent_data, 3, "gtk_recent_manager_add_full", "GtkRecentData*"); return(C_to_Xen_gboolean(gtk_recent_manager_add_full(Xen_to_C_GtkRecentManager_(manager), Xen_to_C_gchar_(uri), Xen_to_C_GtkRecentData_(recent_data)))); } static Xen gxg_gtk_tree_model_filter_convert_child_iter_to_iter(Xen filter, Xen filter_iter, Xen child_iter) { #define H_gtk_tree_model_filter_convert_child_iter_to_iter "gboolean gtk_tree_model_filter_convert_child_iter_to_iter(GtkTreeModelFilter* filter, \ GtkTreeIter* filter_iter, GtkTreeIter* child_iter)" Xen_check_type(Xen_is_GtkTreeModelFilter_(filter), filter, 1, "gtk_tree_model_filter_convert_child_iter_to_iter", "GtkTreeModelFilter*"); Xen_check_type(Xen_is_GtkTreeIter_(filter_iter), filter_iter, 2, "gtk_tree_model_filter_convert_child_iter_to_iter", "GtkTreeIter*"); Xen_check_type(Xen_is_GtkTreeIter_(child_iter), child_iter, 3, "gtk_tree_model_filter_convert_child_iter_to_iter", "GtkTreeIter*"); return(C_to_Xen_gboolean(gtk_tree_model_filter_convert_child_iter_to_iter(Xen_to_C_GtkTreeModelFilter_(filter), Xen_to_C_GtkTreeIter_(filter_iter), Xen_to_C_GtkTreeIter_(child_iter)))); } static Xen gxg_gtk_tree_view_get_grid_lines(Xen tree_view) { #define H_gtk_tree_view_get_grid_lines "GtkTreeViewGridLines gtk_tree_view_get_grid_lines(GtkTreeView* tree_view)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_get_grid_lines", "GtkTreeView*"); return(C_to_Xen_GtkTreeViewGridLines(gtk_tree_view_get_grid_lines(Xen_to_C_GtkTreeView_(tree_view)))); } static Xen gxg_gtk_tree_view_set_grid_lines(Xen tree_view, Xen grid_lines) { #define H_gtk_tree_view_set_grid_lines "void gtk_tree_view_set_grid_lines(GtkTreeView* tree_view, GtkTreeViewGridLines grid_lines)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_set_grid_lines", "GtkTreeView*"); Xen_check_type(Xen_is_GtkTreeViewGridLines(grid_lines), grid_lines, 2, "gtk_tree_view_set_grid_lines", "GtkTreeViewGridLines"); gtk_tree_view_set_grid_lines(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_GtkTreeViewGridLines(grid_lines)); return(Xen_false); } static Xen gxg_gtk_tree_view_get_enable_tree_lines(Xen tree_view) { #define H_gtk_tree_view_get_enable_tree_lines "gboolean gtk_tree_view_get_enable_tree_lines(GtkTreeView* tree_view)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_get_enable_tree_lines", "GtkTreeView*"); return(C_to_Xen_gboolean(gtk_tree_view_get_enable_tree_lines(Xen_to_C_GtkTreeView_(tree_view)))); } static Xen gxg_gtk_tree_view_set_enable_tree_lines(Xen tree_view, Xen enabled) { #define H_gtk_tree_view_set_enable_tree_lines "void gtk_tree_view_set_enable_tree_lines(GtkTreeView* tree_view, \ gboolean enabled)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_set_enable_tree_lines", "GtkTreeView*"); Xen_check_type(Xen_is_gboolean(enabled), enabled, 2, "gtk_tree_view_set_enable_tree_lines", "gboolean"); gtk_tree_view_set_enable_tree_lines(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_gboolean(enabled)); return(Xen_false); } static Xen gxg_gtk_label_set_line_wrap_mode(Xen label, Xen wrap_mode) { #define H_gtk_label_set_line_wrap_mode "void gtk_label_set_line_wrap_mode(GtkLabel* label, PangoWrapMode wrap_mode)" Xen_check_type(Xen_is_GtkLabel_(label), label, 1, "gtk_label_set_line_wrap_mode", "GtkLabel*"); Xen_check_type(Xen_is_PangoWrapMode(wrap_mode), wrap_mode, 2, "gtk_label_set_line_wrap_mode", "PangoWrapMode"); gtk_label_set_line_wrap_mode(Xen_to_C_GtkLabel_(label), Xen_to_C_PangoWrapMode(wrap_mode)); return(Xen_false); } static Xen gxg_gtk_label_get_line_wrap_mode(Xen label) { #define H_gtk_label_get_line_wrap_mode "PangoWrapMode gtk_label_get_line_wrap_mode(GtkLabel* label)" Xen_check_type(Xen_is_GtkLabel_(label), label, 1, "gtk_label_get_line_wrap_mode", "GtkLabel*"); return(C_to_Xen_PangoWrapMode(gtk_label_get_line_wrap_mode(Xen_to_C_GtkLabel_(label)))); } static Xen gxg_gtk_print_context_get_cairo_context(Xen context) { #define H_gtk_print_context_get_cairo_context "cairo_t* gtk_print_context_get_cairo_context(GtkPrintContext* context)" Xen_check_type(Xen_is_GtkPrintContext_(context), context, 1, "gtk_print_context_get_cairo_context", "GtkPrintContext*"); return(C_to_Xen_cairo_t_(gtk_print_context_get_cairo_context(Xen_to_C_GtkPrintContext_(context)))); } static Xen gxg_gtk_print_context_get_page_setup(Xen context) { #define H_gtk_print_context_get_page_setup "GtkPageSetup* gtk_print_context_get_page_setup(GtkPrintContext* context)" Xen_check_type(Xen_is_GtkPrintContext_(context), context, 1, "gtk_print_context_get_page_setup", "GtkPrintContext*"); return(C_to_Xen_GtkPageSetup_(gtk_print_context_get_page_setup(Xen_to_C_GtkPrintContext_(context)))); } static Xen gxg_gtk_print_context_get_width(Xen context) { #define H_gtk_print_context_get_width "gdouble gtk_print_context_get_width(GtkPrintContext* context)" Xen_check_type(Xen_is_GtkPrintContext_(context), context, 1, "gtk_print_context_get_width", "GtkPrintContext*"); return(C_to_Xen_gdouble(gtk_print_context_get_width(Xen_to_C_GtkPrintContext_(context)))); } static Xen gxg_gtk_print_context_get_height(Xen context) { #define H_gtk_print_context_get_height "gdouble gtk_print_context_get_height(GtkPrintContext* context)" Xen_check_type(Xen_is_GtkPrintContext_(context), context, 1, "gtk_print_context_get_height", "GtkPrintContext*"); return(C_to_Xen_gdouble(gtk_print_context_get_height(Xen_to_C_GtkPrintContext_(context)))); } static Xen gxg_gtk_print_context_get_dpi_x(Xen context) { #define H_gtk_print_context_get_dpi_x "gdouble gtk_print_context_get_dpi_x(GtkPrintContext* context)" Xen_check_type(Xen_is_GtkPrintContext_(context), context, 1, "gtk_print_context_get_dpi_x", "GtkPrintContext*"); return(C_to_Xen_gdouble(gtk_print_context_get_dpi_x(Xen_to_C_GtkPrintContext_(context)))); } static Xen gxg_gtk_print_context_get_dpi_y(Xen context) { #define H_gtk_print_context_get_dpi_y "gdouble gtk_print_context_get_dpi_y(GtkPrintContext* context)" Xen_check_type(Xen_is_GtkPrintContext_(context), context, 1, "gtk_print_context_get_dpi_y", "GtkPrintContext*"); return(C_to_Xen_gdouble(gtk_print_context_get_dpi_y(Xen_to_C_GtkPrintContext_(context)))); } static Xen gxg_gtk_print_context_create_pango_context(Xen context) { #define H_gtk_print_context_create_pango_context "PangoContext* gtk_print_context_create_pango_context(GtkPrintContext* context)" Xen_check_type(Xen_is_GtkPrintContext_(context), context, 1, "gtk_print_context_create_pango_context", "GtkPrintContext*"); return(C_to_Xen_PangoContext_(gtk_print_context_create_pango_context(Xen_to_C_GtkPrintContext_(context)))); } static Xen gxg_gtk_print_context_create_pango_layout(Xen context) { #define H_gtk_print_context_create_pango_layout "PangoLayout* gtk_print_context_create_pango_layout(GtkPrintContext* context)" Xen_check_type(Xen_is_GtkPrintContext_(context), context, 1, "gtk_print_context_create_pango_layout", "GtkPrintContext*"); return(C_to_Xen_PangoLayout_(gtk_print_context_create_pango_layout(Xen_to_C_GtkPrintContext_(context)))); } static Xen gxg_gtk_print_context_set_cairo_context(Xen context, Xen cr, Xen dpi_x, Xen dpi_y) { #define H_gtk_print_context_set_cairo_context "void gtk_print_context_set_cairo_context(GtkPrintContext* context, \ cairo_t* cr, double dpi_x, double dpi_y)" Xen_check_type(Xen_is_GtkPrintContext_(context), context, 1, "gtk_print_context_set_cairo_context", "GtkPrintContext*"); Xen_check_type(Xen_is_cairo_t_(cr), cr, 2, "gtk_print_context_set_cairo_context", "cairo_t*"); Xen_check_type(Xen_is_double(dpi_x), dpi_x, 3, "gtk_print_context_set_cairo_context", "double"); Xen_check_type(Xen_is_double(dpi_y), dpi_y, 4, "gtk_print_context_set_cairo_context", "double"); gtk_print_context_set_cairo_context(Xen_to_C_GtkPrintContext_(context), Xen_to_C_cairo_t_(cr), Xen_to_C_double(dpi_x), Xen_to_C_double(dpi_y)); return(Xen_false); } static Xen gxg_gtk_print_operation_new(void) { #define H_gtk_print_operation_new "GtkPrintOperation* gtk_print_operation_new( void)" return(C_to_Xen_GtkPrintOperation_(gtk_print_operation_new())); } static Xen gxg_gtk_print_operation_set_default_page_setup(Xen op, Xen default_page_setup) { #define H_gtk_print_operation_set_default_page_setup "void gtk_print_operation_set_default_page_setup(GtkPrintOperation* op, \ GtkPageSetup* default_page_setup)" Xen_check_type(Xen_is_GtkPrintOperation_(op), op, 1, "gtk_print_operation_set_default_page_setup", "GtkPrintOperation*"); Xen_check_type(Xen_is_GtkPageSetup_(default_page_setup), default_page_setup, 2, "gtk_print_operation_set_default_page_setup", "GtkPageSetup*"); gtk_print_operation_set_default_page_setup(Xen_to_C_GtkPrintOperation_(op), Xen_to_C_GtkPageSetup_(default_page_setup)); return(Xen_false); } static Xen gxg_gtk_print_operation_get_default_page_setup(Xen op) { #define H_gtk_print_operation_get_default_page_setup "GtkPageSetup* gtk_print_operation_get_default_page_setup(GtkPrintOperation* op)" Xen_check_type(Xen_is_GtkPrintOperation_(op), op, 1, "gtk_print_operation_get_default_page_setup", "GtkPrintOperation*"); return(C_to_Xen_GtkPageSetup_(gtk_print_operation_get_default_page_setup(Xen_to_C_GtkPrintOperation_(op)))); } static Xen gxg_gtk_print_operation_set_print_settings(Xen op, Xen print_settings) { #define H_gtk_print_operation_set_print_settings "void gtk_print_operation_set_print_settings(GtkPrintOperation* op, \ GtkPrintSettings* print_settings)" Xen_check_type(Xen_is_GtkPrintOperation_(op), op, 1, "gtk_print_operation_set_print_settings", "GtkPrintOperation*"); Xen_check_type(Xen_is_GtkPrintSettings_(print_settings), print_settings, 2, "gtk_print_operation_set_print_settings", "GtkPrintSettings*"); gtk_print_operation_set_print_settings(Xen_to_C_GtkPrintOperation_(op), Xen_to_C_GtkPrintSettings_(print_settings)); return(Xen_false); } static Xen gxg_gtk_print_operation_get_print_settings(Xen op) { #define H_gtk_print_operation_get_print_settings "GtkPrintSettings* gtk_print_operation_get_print_settings(GtkPrintOperation* op)" Xen_check_type(Xen_is_GtkPrintOperation_(op), op, 1, "gtk_print_operation_get_print_settings", "GtkPrintOperation*"); return(C_to_Xen_GtkPrintSettings_(gtk_print_operation_get_print_settings(Xen_to_C_GtkPrintOperation_(op)))); } static Xen gxg_gtk_print_operation_set_job_name(Xen op, Xen job_name) { #define H_gtk_print_operation_set_job_name "void gtk_print_operation_set_job_name(GtkPrintOperation* op, \ gchar* job_name)" Xen_check_type(Xen_is_GtkPrintOperation_(op), op, 1, "gtk_print_operation_set_job_name", "GtkPrintOperation*"); Xen_check_type(Xen_is_gchar_(job_name), job_name, 2, "gtk_print_operation_set_job_name", "gchar*"); gtk_print_operation_set_job_name(Xen_to_C_GtkPrintOperation_(op), Xen_to_C_gchar_(job_name)); return(Xen_false); } static Xen gxg_gtk_print_operation_set_n_pages(Xen op, Xen n_pages) { #define H_gtk_print_operation_set_n_pages "void gtk_print_operation_set_n_pages(GtkPrintOperation* op, \ gint n_pages)" Xen_check_type(Xen_is_GtkPrintOperation_(op), op, 1, "gtk_print_operation_set_n_pages", "GtkPrintOperation*"); Xen_check_type(Xen_is_gint(n_pages), n_pages, 2, "gtk_print_operation_set_n_pages", "gint"); gtk_print_operation_set_n_pages(Xen_to_C_GtkPrintOperation_(op), Xen_to_C_gint(n_pages)); return(Xen_false); } static Xen gxg_gtk_print_operation_set_current_page(Xen op, Xen current_page) { #define H_gtk_print_operation_set_current_page "void gtk_print_operation_set_current_page(GtkPrintOperation* op, \ gint current_page)" Xen_check_type(Xen_is_GtkPrintOperation_(op), op, 1, "gtk_print_operation_set_current_page", "GtkPrintOperation*"); Xen_check_type(Xen_is_gint(current_page), current_page, 2, "gtk_print_operation_set_current_page", "gint"); gtk_print_operation_set_current_page(Xen_to_C_GtkPrintOperation_(op), Xen_to_C_gint(current_page)); return(Xen_false); } static Xen gxg_gtk_print_operation_set_use_full_page(Xen op, Xen full_page) { #define H_gtk_print_operation_set_use_full_page "void gtk_print_operation_set_use_full_page(GtkPrintOperation* op, \ gboolean full_page)" Xen_check_type(Xen_is_GtkPrintOperation_(op), op, 1, "gtk_print_operation_set_use_full_page", "GtkPrintOperation*"); Xen_check_type(Xen_is_gboolean(full_page), full_page, 2, "gtk_print_operation_set_use_full_page", "gboolean"); gtk_print_operation_set_use_full_page(Xen_to_C_GtkPrintOperation_(op), Xen_to_C_gboolean(full_page)); return(Xen_false); } static Xen gxg_gtk_print_operation_set_unit(Xen op, Xen unit) { #define H_gtk_print_operation_set_unit "void gtk_print_operation_set_unit(GtkPrintOperation* op, GtkUnit unit)" Xen_check_type(Xen_is_GtkPrintOperation_(op), op, 1, "gtk_print_operation_set_unit", "GtkPrintOperation*"); Xen_check_type(Xen_is_GtkUnit(unit), unit, 2, "gtk_print_operation_set_unit", "GtkUnit"); gtk_print_operation_set_unit(Xen_to_C_GtkPrintOperation_(op), Xen_to_C_GtkUnit(unit)); return(Xen_false); } static Xen gxg_gtk_print_operation_set_export_filename(Xen op, Xen filename) { #define H_gtk_print_operation_set_export_filename "void gtk_print_operation_set_export_filename(GtkPrintOperation* op, \ gchar* filename)" Xen_check_type(Xen_is_GtkPrintOperation_(op), op, 1, "gtk_print_operation_set_export_filename", "GtkPrintOperation*"); Xen_check_type(Xen_is_gchar_(filename), filename, 2, "gtk_print_operation_set_export_filename", "gchar*"); gtk_print_operation_set_export_filename(Xen_to_C_GtkPrintOperation_(op), Xen_to_C_gchar_(filename)); return(Xen_false); } static Xen gxg_gtk_print_operation_set_track_print_status(Xen op, Xen track_status) { #define H_gtk_print_operation_set_track_print_status "void gtk_print_operation_set_track_print_status(GtkPrintOperation* op, \ gboolean track_status)" Xen_check_type(Xen_is_GtkPrintOperation_(op), op, 1, "gtk_print_operation_set_track_print_status", "GtkPrintOperation*"); Xen_check_type(Xen_is_gboolean(track_status), track_status, 2, "gtk_print_operation_set_track_print_status", "gboolean"); gtk_print_operation_set_track_print_status(Xen_to_C_GtkPrintOperation_(op), Xen_to_C_gboolean(track_status)); return(Xen_false); } static Xen gxg_gtk_print_operation_set_show_progress(Xen op, Xen show_progress) { #define H_gtk_print_operation_set_show_progress "void gtk_print_operation_set_show_progress(GtkPrintOperation* op, \ gboolean show_progress)" Xen_check_type(Xen_is_GtkPrintOperation_(op), op, 1, "gtk_print_operation_set_show_progress", "GtkPrintOperation*"); Xen_check_type(Xen_is_gboolean(show_progress), show_progress, 2, "gtk_print_operation_set_show_progress", "gboolean"); gtk_print_operation_set_show_progress(Xen_to_C_GtkPrintOperation_(op), Xen_to_C_gboolean(show_progress)); return(Xen_false); } static Xen gxg_gtk_print_operation_set_allow_async(Xen op, Xen allow_async) { #define H_gtk_print_operation_set_allow_async "void gtk_print_operation_set_allow_async(GtkPrintOperation* op, \ gboolean allow_async)" Xen_check_type(Xen_is_GtkPrintOperation_(op), op, 1, "gtk_print_operation_set_allow_async", "GtkPrintOperation*"); Xen_check_type(Xen_is_gboolean(allow_async), allow_async, 2, "gtk_print_operation_set_allow_async", "gboolean"); gtk_print_operation_set_allow_async(Xen_to_C_GtkPrintOperation_(op), Xen_to_C_gboolean(allow_async)); return(Xen_false); } static Xen gxg_gtk_print_operation_set_custom_tab_label(Xen op, Xen label) { #define H_gtk_print_operation_set_custom_tab_label "void gtk_print_operation_set_custom_tab_label(GtkPrintOperation* op, \ gchar* label)" Xen_check_type(Xen_is_GtkPrintOperation_(op), op, 1, "gtk_print_operation_set_custom_tab_label", "GtkPrintOperation*"); Xen_check_type(Xen_is_gchar_(label), label, 2, "gtk_print_operation_set_custom_tab_label", "gchar*"); gtk_print_operation_set_custom_tab_label(Xen_to_C_GtkPrintOperation_(op), Xen_to_C_gchar_(label)); return(Xen_false); } static Xen gxg_gtk_print_operation_run(Xen op, Xen action, Xen parent, Xen ignore_error) { #define H_gtk_print_operation_run "GtkPrintOperationResult gtk_print_operation_run(GtkPrintOperation* op, \ GtkPrintOperationAction action, GtkWindow* parent, GError** [error])" GError* ref_error = NULL; Xen_check_type(Xen_is_GtkPrintOperation_(op), op, 1, "gtk_print_operation_run", "GtkPrintOperation*"); Xen_check_type(Xen_is_GtkPrintOperationAction(action), action, 2, "gtk_print_operation_run", "GtkPrintOperationAction"); Xen_check_type(Xen_is_GtkWindow_(parent), parent, 3, "gtk_print_operation_run", "GtkWindow*"); { Xen result; result = C_to_Xen_GtkPrintOperationResult(gtk_print_operation_run(Xen_to_C_GtkPrintOperation_(op), Xen_to_C_GtkPrintOperationAction(action), Xen_to_C_GtkWindow_(parent), &ref_error)); return(Xen_list_2(result, C_to_Xen_GError_(ref_error))); } } static Xen gxg_gtk_print_operation_get_error(Xen op, Xen ignore_error) { #define H_gtk_print_operation_get_error "void gtk_print_operation_get_error(GtkPrintOperation* op, \ GError** [error])" GError* ref_error = NULL; Xen_check_type(Xen_is_GtkPrintOperation_(op), op, 1, "gtk_print_operation_get_error", "GtkPrintOperation*"); gtk_print_operation_get_error(Xen_to_C_GtkPrintOperation_(op), &ref_error); return(Xen_list_1(C_to_Xen_GError_(ref_error))); } static Xen gxg_gtk_print_operation_get_status(Xen op) { #define H_gtk_print_operation_get_status "GtkPrintStatus gtk_print_operation_get_status(GtkPrintOperation* op)" Xen_check_type(Xen_is_GtkPrintOperation_(op), op, 1, "gtk_print_operation_get_status", "GtkPrintOperation*"); return(C_to_Xen_GtkPrintStatus(gtk_print_operation_get_status(Xen_to_C_GtkPrintOperation_(op)))); } static Xen gxg_gtk_print_operation_get_status_string(Xen op) { #define H_gtk_print_operation_get_status_string "gchar* gtk_print_operation_get_status_string(GtkPrintOperation* op)" Xen_check_type(Xen_is_GtkPrintOperation_(op), op, 1, "gtk_print_operation_get_status_string", "GtkPrintOperation*"); return(C_to_Xen_gchar_(gtk_print_operation_get_status_string(Xen_to_C_GtkPrintOperation_(op)))); } static Xen gxg_gtk_print_operation_is_finished(Xen op) { #define H_gtk_print_operation_is_finished "gboolean gtk_print_operation_is_finished(GtkPrintOperation* op)" Xen_check_type(Xen_is_GtkPrintOperation_(op), op, 1, "gtk_print_operation_is_finished", "GtkPrintOperation*"); return(C_to_Xen_gboolean(gtk_print_operation_is_finished(Xen_to_C_GtkPrintOperation_(op)))); } static Xen gxg_gtk_print_operation_cancel(Xen op) { #define H_gtk_print_operation_cancel "void gtk_print_operation_cancel(GtkPrintOperation* op)" Xen_check_type(Xen_is_GtkPrintOperation_(op), op, 1, "gtk_print_operation_cancel", "GtkPrintOperation*"); gtk_print_operation_cancel(Xen_to_C_GtkPrintOperation_(op)); return(Xen_false); } static Xen gxg_gtk_print_run_page_setup_dialog(Xen parent, Xen page_setup, Xen settings) { #define H_gtk_print_run_page_setup_dialog "GtkPageSetup* gtk_print_run_page_setup_dialog(GtkWindow* parent, \ GtkPageSetup* page_setup, GtkPrintSettings* settings)" Xen_check_type(Xen_is_GtkWindow_(parent), parent, 1, "gtk_print_run_page_setup_dialog", "GtkWindow*"); Xen_check_type(Xen_is_GtkPageSetup_(page_setup), page_setup, 2, "gtk_print_run_page_setup_dialog", "GtkPageSetup*"); Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 3, "gtk_print_run_page_setup_dialog", "GtkPrintSettings*"); return(C_to_Xen_GtkPageSetup_(gtk_print_run_page_setup_dialog(Xen_to_C_GtkWindow_(parent), Xen_to_C_GtkPageSetup_(page_setup), Xen_to_C_GtkPrintSettings_(settings)))); } static Xen gxg_gtk_print_run_page_setup_dialog_async(Xen parent, Xen page_setup, Xen settings, Xen done_cb, Xen data) { #define H_gtk_print_run_page_setup_dialog_async "void gtk_print_run_page_setup_dialog_async(GtkWindow* parent, \ GtkPageSetup* page_setup, GtkPrintSettings* settings, GtkPageSetupDoneFunc done_cb, gpointer data)" Xen_check_type(Xen_is_GtkWindow_(parent), parent, 1, "gtk_print_run_page_setup_dialog_async", "GtkWindow*"); Xen_check_type(Xen_is_GtkPageSetup_(page_setup), page_setup, 2, "gtk_print_run_page_setup_dialog_async", "GtkPageSetup*"); Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 3, "gtk_print_run_page_setup_dialog_async", "GtkPrintSettings*"); Xen_check_type(Xen_is_GtkPageSetupDoneFunc(done_cb), done_cb, 4, "gtk_print_run_page_setup_dialog_async", "GtkPageSetupDoneFunc"); Xen_check_type(Xen_is_gpointer(data), data, 5, "gtk_print_run_page_setup_dialog_async", "gpointer"); gtk_print_run_page_setup_dialog_async(Xen_to_C_GtkWindow_(parent), Xen_to_C_GtkPageSetup_(page_setup), Xen_to_C_GtkPrintSettings_(settings), Xen_to_C_GtkPageSetupDoneFunc(done_cb), Xen_to_C_gpointer(data)); return(Xen_false); } static Xen gxg_gtk_print_operation_preview_render_page(Xen preview, Xen page_nr) { #define H_gtk_print_operation_preview_render_page "void gtk_print_operation_preview_render_page(GtkPrintOperationPreview* preview, \ gint page_nr)" Xen_check_type(Xen_is_GtkPrintOperationPreview_(preview), preview, 1, "gtk_print_operation_preview_render_page", "GtkPrintOperationPreview*"); Xen_check_type(Xen_is_gint(page_nr), page_nr, 2, "gtk_print_operation_preview_render_page", "gint"); gtk_print_operation_preview_render_page(Xen_to_C_GtkPrintOperationPreview_(preview), Xen_to_C_gint(page_nr)); return(Xen_false); } static Xen gxg_gtk_print_operation_preview_end_preview(Xen preview) { #define H_gtk_print_operation_preview_end_preview "void gtk_print_operation_preview_end_preview(GtkPrintOperationPreview* preview)" Xen_check_type(Xen_is_GtkPrintOperationPreview_(preview), preview, 1, "gtk_print_operation_preview_end_preview", "GtkPrintOperationPreview*"); gtk_print_operation_preview_end_preview(Xen_to_C_GtkPrintOperationPreview_(preview)); return(Xen_false); } static Xen gxg_gtk_print_operation_preview_is_selected(Xen preview, Xen page_nr) { #define H_gtk_print_operation_preview_is_selected "gboolean gtk_print_operation_preview_is_selected(GtkPrintOperationPreview* preview, \ gint page_nr)" Xen_check_type(Xen_is_GtkPrintOperationPreview_(preview), preview, 1, "gtk_print_operation_preview_is_selected", "GtkPrintOperationPreview*"); Xen_check_type(Xen_is_gint(page_nr), page_nr, 2, "gtk_print_operation_preview_is_selected", "gint"); return(C_to_Xen_gboolean(gtk_print_operation_preview_is_selected(Xen_to_C_GtkPrintOperationPreview_(preview), Xen_to_C_gint(page_nr)))); } static Xen gxg_gtk_print_settings_new(void) { #define H_gtk_print_settings_new "GtkPrintSettings* gtk_print_settings_new( void)" return(C_to_Xen_GtkPrintSettings_(gtk_print_settings_new())); } static Xen gxg_gtk_print_settings_copy(Xen other) { #define H_gtk_print_settings_copy "GtkPrintSettings* gtk_print_settings_copy(GtkPrintSettings* other)" Xen_check_type(Xen_is_GtkPrintSettings_(other), other, 1, "gtk_print_settings_copy", "GtkPrintSettings*"); return(C_to_Xen_GtkPrintSettings_(gtk_print_settings_copy(Xen_to_C_GtkPrintSettings_(other)))); } static Xen gxg_gtk_print_settings_has_key(Xen settings, Xen key) { #define H_gtk_print_settings_has_key "gboolean gtk_print_settings_has_key(GtkPrintSettings* settings, \ gchar* key)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_has_key", "GtkPrintSettings*"); Xen_check_type(Xen_is_gchar_(key), key, 2, "gtk_print_settings_has_key", "gchar*"); return(C_to_Xen_gboolean(gtk_print_settings_has_key(Xen_to_C_GtkPrintSettings_(settings), Xen_to_C_gchar_(key)))); } static Xen gxg_gtk_print_settings_get(Xen settings, Xen key) { #define H_gtk_print_settings_get "gchar* gtk_print_settings_get(GtkPrintSettings* settings, gchar* key)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_get", "GtkPrintSettings*"); Xen_check_type(Xen_is_gchar_(key), key, 2, "gtk_print_settings_get", "gchar*"); return(C_to_Xen_gchar_(gtk_print_settings_get(Xen_to_C_GtkPrintSettings_(settings), Xen_to_C_gchar_(key)))); } static Xen gxg_gtk_print_settings_set(Xen settings, Xen key, Xen value) { #define H_gtk_print_settings_set "void gtk_print_settings_set(GtkPrintSettings* settings, gchar* key, \ gchar* value)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_set", "GtkPrintSettings*"); Xen_check_type(Xen_is_gchar_(key), key, 2, "gtk_print_settings_set", "gchar*"); Xen_check_type(Xen_is_gchar_(value), value, 3, "gtk_print_settings_set", "gchar*"); gtk_print_settings_set(Xen_to_C_GtkPrintSettings_(settings), Xen_to_C_gchar_(key), Xen_to_C_gchar_(value)); return(Xen_false); } static Xen gxg_gtk_print_settings_unset(Xen settings, Xen key) { #define H_gtk_print_settings_unset "void gtk_print_settings_unset(GtkPrintSettings* settings, gchar* key)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_unset", "GtkPrintSettings*"); Xen_check_type(Xen_is_gchar_(key), key, 2, "gtk_print_settings_unset", "gchar*"); gtk_print_settings_unset(Xen_to_C_GtkPrintSettings_(settings), Xen_to_C_gchar_(key)); return(Xen_false); } static Xen gxg_gtk_print_settings_foreach(Xen settings, Xen func, Xen user_data) { #define H_gtk_print_settings_foreach "void gtk_print_settings_foreach(GtkPrintSettings* settings, GtkPrintSettingsFunc func, \ gpointer user_data)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_foreach", "GtkPrintSettings*"); Xen_check_type(Xen_is_GtkPrintSettingsFunc(func), func, 2, "gtk_print_settings_foreach", "GtkPrintSettingsFunc"); Xen_check_type(Xen_is_gpointer(user_data), user_data, 3, "gtk_print_settings_foreach", "gpointer"); gtk_print_settings_foreach(Xen_to_C_GtkPrintSettings_(settings), Xen_to_C_GtkPrintSettingsFunc(func), Xen_to_C_gpointer(user_data)); return(Xen_false); } static Xen gxg_gtk_print_settings_get_bool(Xen settings, Xen key) { #define H_gtk_print_settings_get_bool "gboolean gtk_print_settings_get_bool(GtkPrintSettings* settings, \ gchar* key)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_get_bool", "GtkPrintSettings*"); Xen_check_type(Xen_is_gchar_(key), key, 2, "gtk_print_settings_get_bool", "gchar*"); return(C_to_Xen_gboolean(gtk_print_settings_get_bool(Xen_to_C_GtkPrintSettings_(settings), Xen_to_C_gchar_(key)))); } static Xen gxg_gtk_print_settings_set_bool(Xen settings, Xen key, Xen value) { #define H_gtk_print_settings_set_bool "void gtk_print_settings_set_bool(GtkPrintSettings* settings, \ gchar* key, gboolean value)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_set_bool", "GtkPrintSettings*"); Xen_check_type(Xen_is_gchar_(key), key, 2, "gtk_print_settings_set_bool", "gchar*"); Xen_check_type(Xen_is_gboolean(value), value, 3, "gtk_print_settings_set_bool", "gboolean"); gtk_print_settings_set_bool(Xen_to_C_GtkPrintSettings_(settings), Xen_to_C_gchar_(key), Xen_to_C_gboolean(value)); return(Xen_false); } static Xen gxg_gtk_print_settings_get_double(Xen settings, Xen key) { #define H_gtk_print_settings_get_double "gdouble gtk_print_settings_get_double(GtkPrintSettings* settings, \ gchar* key)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_get_double", "GtkPrintSettings*"); Xen_check_type(Xen_is_gchar_(key), key, 2, "gtk_print_settings_get_double", "gchar*"); return(C_to_Xen_gdouble(gtk_print_settings_get_double(Xen_to_C_GtkPrintSettings_(settings), Xen_to_C_gchar_(key)))); } static Xen gxg_gtk_print_settings_get_double_with_default(Xen settings, Xen key, Xen def) { #define H_gtk_print_settings_get_double_with_default "gdouble gtk_print_settings_get_double_with_default(GtkPrintSettings* settings, \ gchar* key, gdouble def)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_get_double_with_default", "GtkPrintSettings*"); Xen_check_type(Xen_is_gchar_(key), key, 2, "gtk_print_settings_get_double_with_default", "gchar*"); Xen_check_type(Xen_is_gdouble(def), def, 3, "gtk_print_settings_get_double_with_default", "gdouble"); return(C_to_Xen_gdouble(gtk_print_settings_get_double_with_default(Xen_to_C_GtkPrintSettings_(settings), Xen_to_C_gchar_(key), Xen_to_C_gdouble(def)))); } static Xen gxg_gtk_print_settings_set_double(Xen settings, Xen key, Xen value) { #define H_gtk_print_settings_set_double "void gtk_print_settings_set_double(GtkPrintSettings* settings, \ gchar* key, gdouble value)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_set_double", "GtkPrintSettings*"); Xen_check_type(Xen_is_gchar_(key), key, 2, "gtk_print_settings_set_double", "gchar*"); Xen_check_type(Xen_is_gdouble(value), value, 3, "gtk_print_settings_set_double", "gdouble"); gtk_print_settings_set_double(Xen_to_C_GtkPrintSettings_(settings), Xen_to_C_gchar_(key), Xen_to_C_gdouble(value)); return(Xen_false); } static Xen gxg_gtk_print_settings_get_length(Xen settings, Xen key, Xen unit) { #define H_gtk_print_settings_get_length "gdouble gtk_print_settings_get_length(GtkPrintSettings* settings, \ gchar* key, GtkUnit unit)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_get_length", "GtkPrintSettings*"); Xen_check_type(Xen_is_gchar_(key), key, 2, "gtk_print_settings_get_length", "gchar*"); Xen_check_type(Xen_is_GtkUnit(unit), unit, 3, "gtk_print_settings_get_length", "GtkUnit"); return(C_to_Xen_gdouble(gtk_print_settings_get_length(Xen_to_C_GtkPrintSettings_(settings), Xen_to_C_gchar_(key), Xen_to_C_GtkUnit(unit)))); } static Xen gxg_gtk_print_settings_set_length(Xen settings, Xen key, Xen value, Xen unit) { #define H_gtk_print_settings_set_length "void gtk_print_settings_set_length(GtkPrintSettings* settings, \ gchar* key, gdouble value, GtkUnit unit)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_set_length", "GtkPrintSettings*"); Xen_check_type(Xen_is_gchar_(key), key, 2, "gtk_print_settings_set_length", "gchar*"); Xen_check_type(Xen_is_gdouble(value), value, 3, "gtk_print_settings_set_length", "gdouble"); Xen_check_type(Xen_is_GtkUnit(unit), unit, 4, "gtk_print_settings_set_length", "GtkUnit"); gtk_print_settings_set_length(Xen_to_C_GtkPrintSettings_(settings), Xen_to_C_gchar_(key), Xen_to_C_gdouble(value), Xen_to_C_GtkUnit(unit)); return(Xen_false); } static Xen gxg_gtk_print_settings_get_int(Xen settings, Xen key) { #define H_gtk_print_settings_get_int "gint gtk_print_settings_get_int(GtkPrintSettings* settings, gchar* key)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_get_int", "GtkPrintSettings*"); Xen_check_type(Xen_is_gchar_(key), key, 2, "gtk_print_settings_get_int", "gchar*"); return(C_to_Xen_gint(gtk_print_settings_get_int(Xen_to_C_GtkPrintSettings_(settings), Xen_to_C_gchar_(key)))); } static Xen gxg_gtk_print_settings_get_int_with_default(Xen settings, Xen key, Xen def) { #define H_gtk_print_settings_get_int_with_default "gint gtk_print_settings_get_int_with_default(GtkPrintSettings* settings, \ gchar* key, gint def)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_get_int_with_default", "GtkPrintSettings*"); Xen_check_type(Xen_is_gchar_(key), key, 2, "gtk_print_settings_get_int_with_default", "gchar*"); Xen_check_type(Xen_is_gint(def), def, 3, "gtk_print_settings_get_int_with_default", "gint"); return(C_to_Xen_gint(gtk_print_settings_get_int_with_default(Xen_to_C_GtkPrintSettings_(settings), Xen_to_C_gchar_(key), Xen_to_C_gint(def)))); } static Xen gxg_gtk_print_settings_set_int(Xen settings, Xen key, Xen value) { #define H_gtk_print_settings_set_int "void gtk_print_settings_set_int(GtkPrintSettings* settings, gchar* key, \ gint value)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_set_int", "GtkPrintSettings*"); Xen_check_type(Xen_is_gchar_(key), key, 2, "gtk_print_settings_set_int", "gchar*"); Xen_check_type(Xen_is_gint(value), value, 3, "gtk_print_settings_set_int", "gint"); gtk_print_settings_set_int(Xen_to_C_GtkPrintSettings_(settings), Xen_to_C_gchar_(key), Xen_to_C_gint(value)); return(Xen_false); } static Xen gxg_gtk_print_settings_get_printer(Xen settings) { #define H_gtk_print_settings_get_printer "gchar* gtk_print_settings_get_printer(GtkPrintSettings* settings)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_get_printer", "GtkPrintSettings*"); return(C_to_Xen_gchar_(gtk_print_settings_get_printer(Xen_to_C_GtkPrintSettings_(settings)))); } static Xen gxg_gtk_print_settings_set_printer(Xen settings, Xen printer) { #define H_gtk_print_settings_set_printer "void gtk_print_settings_set_printer(GtkPrintSettings* settings, \ gchar* printer)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_set_printer", "GtkPrintSettings*"); Xen_check_type(Xen_is_gchar_(printer), printer, 2, "gtk_print_settings_set_printer", "gchar*"); gtk_print_settings_set_printer(Xen_to_C_GtkPrintSettings_(settings), Xen_to_C_gchar_(printer)); return(Xen_false); } static Xen gxg_gtk_print_settings_get_orientation(Xen settings) { #define H_gtk_print_settings_get_orientation "GtkPageOrientation gtk_print_settings_get_orientation(GtkPrintSettings* settings)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_get_orientation", "GtkPrintSettings*"); return(C_to_Xen_GtkPageOrientation(gtk_print_settings_get_orientation(Xen_to_C_GtkPrintSettings_(settings)))); } static Xen gxg_gtk_print_settings_set_orientation(Xen settings, Xen orientation) { #define H_gtk_print_settings_set_orientation "void gtk_print_settings_set_orientation(GtkPrintSettings* settings, \ GtkPageOrientation orientation)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_set_orientation", "GtkPrintSettings*"); Xen_check_type(Xen_is_GtkPageOrientation(orientation), orientation, 2, "gtk_print_settings_set_orientation", "GtkPageOrientation"); gtk_print_settings_set_orientation(Xen_to_C_GtkPrintSettings_(settings), Xen_to_C_GtkPageOrientation(orientation)); return(Xen_false); } static Xen gxg_gtk_print_settings_get_paper_size(Xen settings) { #define H_gtk_print_settings_get_paper_size "GtkPaperSize* gtk_print_settings_get_paper_size(GtkPrintSettings* settings)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_get_paper_size", "GtkPrintSettings*"); return(C_to_Xen_GtkPaperSize_(gtk_print_settings_get_paper_size(Xen_to_C_GtkPrintSettings_(settings)))); } static Xen gxg_gtk_print_settings_set_paper_size(Xen settings, Xen paper_size) { #define H_gtk_print_settings_set_paper_size "void gtk_print_settings_set_paper_size(GtkPrintSettings* settings, \ GtkPaperSize* paper_size)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_set_paper_size", "GtkPrintSettings*"); Xen_check_type(Xen_is_GtkPaperSize_(paper_size), paper_size, 2, "gtk_print_settings_set_paper_size", "GtkPaperSize*"); gtk_print_settings_set_paper_size(Xen_to_C_GtkPrintSettings_(settings), Xen_to_C_GtkPaperSize_(paper_size)); return(Xen_false); } static Xen gxg_gtk_print_settings_get_paper_width(Xen settings, Xen unit) { #define H_gtk_print_settings_get_paper_width "gdouble gtk_print_settings_get_paper_width(GtkPrintSettings* settings, \ GtkUnit unit)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_get_paper_width", "GtkPrintSettings*"); Xen_check_type(Xen_is_GtkUnit(unit), unit, 2, "gtk_print_settings_get_paper_width", "GtkUnit"); return(C_to_Xen_gdouble(gtk_print_settings_get_paper_width(Xen_to_C_GtkPrintSettings_(settings), Xen_to_C_GtkUnit(unit)))); } static Xen gxg_gtk_print_settings_set_paper_width(Xen settings, Xen width, Xen unit) { #define H_gtk_print_settings_set_paper_width "void gtk_print_settings_set_paper_width(GtkPrintSettings* settings, \ gdouble width, GtkUnit unit)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_set_paper_width", "GtkPrintSettings*"); Xen_check_type(Xen_is_gdouble(width), width, 2, "gtk_print_settings_set_paper_width", "gdouble"); Xen_check_type(Xen_is_GtkUnit(unit), unit, 3, "gtk_print_settings_set_paper_width", "GtkUnit"); gtk_print_settings_set_paper_width(Xen_to_C_GtkPrintSettings_(settings), Xen_to_C_gdouble(width), Xen_to_C_GtkUnit(unit)); return(Xen_false); } static Xen gxg_gtk_print_settings_get_paper_height(Xen settings, Xen unit) { #define H_gtk_print_settings_get_paper_height "gdouble gtk_print_settings_get_paper_height(GtkPrintSettings* settings, \ GtkUnit unit)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_get_paper_height", "GtkPrintSettings*"); Xen_check_type(Xen_is_GtkUnit(unit), unit, 2, "gtk_print_settings_get_paper_height", "GtkUnit"); return(C_to_Xen_gdouble(gtk_print_settings_get_paper_height(Xen_to_C_GtkPrintSettings_(settings), Xen_to_C_GtkUnit(unit)))); } static Xen gxg_gtk_print_settings_set_paper_height(Xen settings, Xen height, Xen unit) { #define H_gtk_print_settings_set_paper_height "void gtk_print_settings_set_paper_height(GtkPrintSettings* settings, \ gdouble height, GtkUnit unit)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_set_paper_height", "GtkPrintSettings*"); Xen_check_type(Xen_is_gdouble(height), height, 2, "gtk_print_settings_set_paper_height", "gdouble"); Xen_check_type(Xen_is_GtkUnit(unit), unit, 3, "gtk_print_settings_set_paper_height", "GtkUnit"); gtk_print_settings_set_paper_height(Xen_to_C_GtkPrintSettings_(settings), Xen_to_C_gdouble(height), Xen_to_C_GtkUnit(unit)); return(Xen_false); } static Xen gxg_gtk_print_settings_get_use_color(Xen settings) { #define H_gtk_print_settings_get_use_color "gboolean gtk_print_settings_get_use_color(GtkPrintSettings* settings)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_get_use_color", "GtkPrintSettings*"); return(C_to_Xen_gboolean(gtk_print_settings_get_use_color(Xen_to_C_GtkPrintSettings_(settings)))); } static Xen gxg_gtk_print_settings_set_use_color(Xen settings, Xen use_color) { #define H_gtk_print_settings_set_use_color "void gtk_print_settings_set_use_color(GtkPrintSettings* settings, \ gboolean use_color)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_set_use_color", "GtkPrintSettings*"); Xen_check_type(Xen_is_gboolean(use_color), use_color, 2, "gtk_print_settings_set_use_color", "gboolean"); gtk_print_settings_set_use_color(Xen_to_C_GtkPrintSettings_(settings), Xen_to_C_gboolean(use_color)); return(Xen_false); } static Xen gxg_gtk_print_settings_get_collate(Xen settings) { #define H_gtk_print_settings_get_collate "gboolean gtk_print_settings_get_collate(GtkPrintSettings* settings)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_get_collate", "GtkPrintSettings*"); return(C_to_Xen_gboolean(gtk_print_settings_get_collate(Xen_to_C_GtkPrintSettings_(settings)))); } static Xen gxg_gtk_print_settings_set_collate(Xen settings, Xen collate) { #define H_gtk_print_settings_set_collate "void gtk_print_settings_set_collate(GtkPrintSettings* settings, \ gboolean collate)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_set_collate", "GtkPrintSettings*"); Xen_check_type(Xen_is_gboolean(collate), collate, 2, "gtk_print_settings_set_collate", "gboolean"); gtk_print_settings_set_collate(Xen_to_C_GtkPrintSettings_(settings), Xen_to_C_gboolean(collate)); return(Xen_false); } static Xen gxg_gtk_print_settings_get_reverse(Xen settings) { #define H_gtk_print_settings_get_reverse "gboolean gtk_print_settings_get_reverse(GtkPrintSettings* settings)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_get_reverse", "GtkPrintSettings*"); return(C_to_Xen_gboolean(gtk_print_settings_get_reverse(Xen_to_C_GtkPrintSettings_(settings)))); } static Xen gxg_gtk_print_settings_set_reverse(Xen settings, Xen reverse) { #define H_gtk_print_settings_set_reverse "void gtk_print_settings_set_reverse(GtkPrintSettings* settings, \ gboolean reverse)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_set_reverse", "GtkPrintSettings*"); Xen_check_type(Xen_is_gboolean(reverse), reverse, 2, "gtk_print_settings_set_reverse", "gboolean"); gtk_print_settings_set_reverse(Xen_to_C_GtkPrintSettings_(settings), Xen_to_C_gboolean(reverse)); return(Xen_false); } static Xen gxg_gtk_print_settings_get_duplex(Xen settings) { #define H_gtk_print_settings_get_duplex "GtkPrintDuplex gtk_print_settings_get_duplex(GtkPrintSettings* settings)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_get_duplex", "GtkPrintSettings*"); return(C_to_Xen_GtkPrintDuplex(gtk_print_settings_get_duplex(Xen_to_C_GtkPrintSettings_(settings)))); } static Xen gxg_gtk_print_settings_set_duplex(Xen settings, Xen duplex) { #define H_gtk_print_settings_set_duplex "void gtk_print_settings_set_duplex(GtkPrintSettings* settings, \ GtkPrintDuplex duplex)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_set_duplex", "GtkPrintSettings*"); Xen_check_type(Xen_is_GtkPrintDuplex(duplex), duplex, 2, "gtk_print_settings_set_duplex", "GtkPrintDuplex"); gtk_print_settings_set_duplex(Xen_to_C_GtkPrintSettings_(settings), Xen_to_C_GtkPrintDuplex(duplex)); return(Xen_false); } static Xen gxg_gtk_print_settings_get_quality(Xen settings) { #define H_gtk_print_settings_get_quality "GtkPrintQuality gtk_print_settings_get_quality(GtkPrintSettings* settings)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_get_quality", "GtkPrintSettings*"); return(C_to_Xen_GtkPrintQuality(gtk_print_settings_get_quality(Xen_to_C_GtkPrintSettings_(settings)))); } static Xen gxg_gtk_print_settings_set_quality(Xen settings, Xen quality) { #define H_gtk_print_settings_set_quality "void gtk_print_settings_set_quality(GtkPrintSettings* settings, \ GtkPrintQuality quality)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_set_quality", "GtkPrintSettings*"); Xen_check_type(Xen_is_GtkPrintQuality(quality), quality, 2, "gtk_print_settings_set_quality", "GtkPrintQuality"); gtk_print_settings_set_quality(Xen_to_C_GtkPrintSettings_(settings), Xen_to_C_GtkPrintQuality(quality)); return(Xen_false); } static Xen gxg_gtk_print_settings_get_n_copies(Xen settings) { #define H_gtk_print_settings_get_n_copies "gint gtk_print_settings_get_n_copies(GtkPrintSettings* settings)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_get_n_copies", "GtkPrintSettings*"); return(C_to_Xen_gint(gtk_print_settings_get_n_copies(Xen_to_C_GtkPrintSettings_(settings)))); } static Xen gxg_gtk_print_settings_set_n_copies(Xen settings, Xen num_copies) { #define H_gtk_print_settings_set_n_copies "void gtk_print_settings_set_n_copies(GtkPrintSettings* settings, \ gint num_copies)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_set_n_copies", "GtkPrintSettings*"); Xen_check_type(Xen_is_gint(num_copies), num_copies, 2, "gtk_print_settings_set_n_copies", "gint"); gtk_print_settings_set_n_copies(Xen_to_C_GtkPrintSettings_(settings), Xen_to_C_gint(num_copies)); return(Xen_false); } static Xen gxg_gtk_print_settings_get_number_up(Xen settings) { #define H_gtk_print_settings_get_number_up "gint gtk_print_settings_get_number_up(GtkPrintSettings* settings)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_get_number_up", "GtkPrintSettings*"); return(C_to_Xen_gint(gtk_print_settings_get_number_up(Xen_to_C_GtkPrintSettings_(settings)))); } static Xen gxg_gtk_print_settings_set_number_up(Xen settings, Xen number_up) { #define H_gtk_print_settings_set_number_up "void gtk_print_settings_set_number_up(GtkPrintSettings* settings, \ gint number_up)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_set_number_up", "GtkPrintSettings*"); Xen_check_type(Xen_is_gint(number_up), number_up, 2, "gtk_print_settings_set_number_up", "gint"); gtk_print_settings_set_number_up(Xen_to_C_GtkPrintSettings_(settings), Xen_to_C_gint(number_up)); return(Xen_false); } static Xen gxg_gtk_print_settings_get_resolution(Xen settings) { #define H_gtk_print_settings_get_resolution "gint gtk_print_settings_get_resolution(GtkPrintSettings* settings)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_get_resolution", "GtkPrintSettings*"); return(C_to_Xen_gint(gtk_print_settings_get_resolution(Xen_to_C_GtkPrintSettings_(settings)))); } static Xen gxg_gtk_print_settings_set_resolution(Xen settings, Xen resolution) { #define H_gtk_print_settings_set_resolution "void gtk_print_settings_set_resolution(GtkPrintSettings* settings, \ gint resolution)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_set_resolution", "GtkPrintSettings*"); Xen_check_type(Xen_is_gint(resolution), resolution, 2, "gtk_print_settings_set_resolution", "gint"); gtk_print_settings_set_resolution(Xen_to_C_GtkPrintSettings_(settings), Xen_to_C_gint(resolution)); return(Xen_false); } static Xen gxg_gtk_print_settings_get_scale(Xen settings) { #define H_gtk_print_settings_get_scale "gdouble gtk_print_settings_get_scale(GtkPrintSettings* settings)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_get_scale", "GtkPrintSettings*"); return(C_to_Xen_gdouble(gtk_print_settings_get_scale(Xen_to_C_GtkPrintSettings_(settings)))); } static Xen gxg_gtk_print_settings_set_scale(Xen settings, Xen scale) { #define H_gtk_print_settings_set_scale "void gtk_print_settings_set_scale(GtkPrintSettings* settings, \ gdouble scale)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_set_scale", "GtkPrintSettings*"); Xen_check_type(Xen_is_gdouble(scale), scale, 2, "gtk_print_settings_set_scale", "gdouble"); gtk_print_settings_set_scale(Xen_to_C_GtkPrintSettings_(settings), Xen_to_C_gdouble(scale)); return(Xen_false); } static Xen gxg_gtk_print_settings_get_print_pages(Xen settings) { #define H_gtk_print_settings_get_print_pages "GtkPrintPages gtk_print_settings_get_print_pages(GtkPrintSettings* settings)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_get_print_pages", "GtkPrintSettings*"); return(C_to_Xen_GtkPrintPages(gtk_print_settings_get_print_pages(Xen_to_C_GtkPrintSettings_(settings)))); } static Xen gxg_gtk_print_settings_set_print_pages(Xen settings, Xen pages) { #define H_gtk_print_settings_set_print_pages "void gtk_print_settings_set_print_pages(GtkPrintSettings* settings, \ GtkPrintPages pages)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_set_print_pages", "GtkPrintSettings*"); Xen_check_type(Xen_is_GtkPrintPages(pages), pages, 2, "gtk_print_settings_set_print_pages", "GtkPrintPages"); gtk_print_settings_set_print_pages(Xen_to_C_GtkPrintSettings_(settings), Xen_to_C_GtkPrintPages(pages)); return(Xen_false); } static Xen gxg_gtk_print_settings_get_page_ranges(Xen settings, Xen num_ranges) { #define H_gtk_print_settings_get_page_ranges "GtkPageRange* gtk_print_settings_get_page_ranges(GtkPrintSettings* settings, \ gint* num_ranges)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_get_page_ranges", "GtkPrintSettings*"); Xen_check_type(Xen_is_gint_(num_ranges), num_ranges, 2, "gtk_print_settings_get_page_ranges", "gint*"); return(C_to_Xen_GtkPageRange_(gtk_print_settings_get_page_ranges(Xen_to_C_GtkPrintSettings_(settings), Xen_to_C_gint_(num_ranges)))); } static Xen gxg_gtk_print_settings_set_page_ranges(Xen settings, Xen page_ranges, Xen num_ranges) { #define H_gtk_print_settings_set_page_ranges "void gtk_print_settings_set_page_ranges(GtkPrintSettings* settings, \ GtkPageRange* page_ranges, gint num_ranges)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_set_page_ranges", "GtkPrintSettings*"); Xen_check_type(Xen_is_GtkPageRange_(page_ranges), page_ranges, 2, "gtk_print_settings_set_page_ranges", "GtkPageRange*"); Xen_check_type(Xen_is_gint(num_ranges), num_ranges, 3, "gtk_print_settings_set_page_ranges", "gint"); gtk_print_settings_set_page_ranges(Xen_to_C_GtkPrintSettings_(settings), Xen_to_C_GtkPageRange_(page_ranges), Xen_to_C_gint(num_ranges)); return(Xen_false); } static Xen gxg_gtk_print_settings_get_page_set(Xen settings) { #define H_gtk_print_settings_get_page_set "GtkPageSet gtk_print_settings_get_page_set(GtkPrintSettings* settings)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_get_page_set", "GtkPrintSettings*"); return(C_to_Xen_GtkPageSet(gtk_print_settings_get_page_set(Xen_to_C_GtkPrintSettings_(settings)))); } static Xen gxg_gtk_print_settings_set_page_set(Xen settings, Xen page_set) { #define H_gtk_print_settings_set_page_set "void gtk_print_settings_set_page_set(GtkPrintSettings* settings, \ GtkPageSet page_set)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_set_page_set", "GtkPrintSettings*"); Xen_check_type(Xen_is_GtkPageSet(page_set), page_set, 2, "gtk_print_settings_set_page_set", "GtkPageSet"); gtk_print_settings_set_page_set(Xen_to_C_GtkPrintSettings_(settings), Xen_to_C_GtkPageSet(page_set)); return(Xen_false); } static Xen gxg_gtk_print_settings_get_default_source(Xen settings) { #define H_gtk_print_settings_get_default_source "gchar* gtk_print_settings_get_default_source(GtkPrintSettings* settings)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_get_default_source", "GtkPrintSettings*"); return(C_to_Xen_gchar_(gtk_print_settings_get_default_source(Xen_to_C_GtkPrintSettings_(settings)))); } static Xen gxg_gtk_print_settings_set_default_source(Xen settings, Xen default_source) { #define H_gtk_print_settings_set_default_source "void gtk_print_settings_set_default_source(GtkPrintSettings* settings, \ gchar* default_source)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_set_default_source", "GtkPrintSettings*"); Xen_check_type(Xen_is_gchar_(default_source), default_source, 2, "gtk_print_settings_set_default_source", "gchar*"); gtk_print_settings_set_default_source(Xen_to_C_GtkPrintSettings_(settings), Xen_to_C_gchar_(default_source)); return(Xen_false); } static Xen gxg_gtk_print_settings_get_media_type(Xen settings) { #define H_gtk_print_settings_get_media_type "gchar* gtk_print_settings_get_media_type(GtkPrintSettings* settings)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_get_media_type", "GtkPrintSettings*"); return(C_to_Xen_gchar_(gtk_print_settings_get_media_type(Xen_to_C_GtkPrintSettings_(settings)))); } static Xen gxg_gtk_print_settings_set_media_type(Xen settings, Xen media_type) { #define H_gtk_print_settings_set_media_type "void gtk_print_settings_set_media_type(GtkPrintSettings* settings, \ gchar* media_type)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_set_media_type", "GtkPrintSettings*"); Xen_check_type(Xen_is_gchar_(media_type), media_type, 2, "gtk_print_settings_set_media_type", "gchar*"); gtk_print_settings_set_media_type(Xen_to_C_GtkPrintSettings_(settings), Xen_to_C_gchar_(media_type)); return(Xen_false); } static Xen gxg_gtk_print_settings_get_dither(Xen settings) { #define H_gtk_print_settings_get_dither "gchar* gtk_print_settings_get_dither(GtkPrintSettings* settings)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_get_dither", "GtkPrintSettings*"); return(C_to_Xen_gchar_(gtk_print_settings_get_dither(Xen_to_C_GtkPrintSettings_(settings)))); } static Xen gxg_gtk_print_settings_set_dither(Xen settings, Xen dither) { #define H_gtk_print_settings_set_dither "void gtk_print_settings_set_dither(GtkPrintSettings* settings, \ gchar* dither)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_set_dither", "GtkPrintSettings*"); Xen_check_type(Xen_is_gchar_(dither), dither, 2, "gtk_print_settings_set_dither", "gchar*"); gtk_print_settings_set_dither(Xen_to_C_GtkPrintSettings_(settings), Xen_to_C_gchar_(dither)); return(Xen_false); } static Xen gxg_gtk_print_settings_get_finishings(Xen settings) { #define H_gtk_print_settings_get_finishings "gchar* gtk_print_settings_get_finishings(GtkPrintSettings* settings)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_get_finishings", "GtkPrintSettings*"); return(C_to_Xen_gchar_(gtk_print_settings_get_finishings(Xen_to_C_GtkPrintSettings_(settings)))); } static Xen gxg_gtk_print_settings_set_finishings(Xen settings, Xen finishings) { #define H_gtk_print_settings_set_finishings "void gtk_print_settings_set_finishings(GtkPrintSettings* settings, \ gchar* finishings)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_set_finishings", "GtkPrintSettings*"); Xen_check_type(Xen_is_gchar_(finishings), finishings, 2, "gtk_print_settings_set_finishings", "gchar*"); gtk_print_settings_set_finishings(Xen_to_C_GtkPrintSettings_(settings), Xen_to_C_gchar_(finishings)); return(Xen_false); } static Xen gxg_gtk_print_settings_get_output_bin(Xen settings) { #define H_gtk_print_settings_get_output_bin "gchar* gtk_print_settings_get_output_bin(GtkPrintSettings* settings)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_get_output_bin", "GtkPrintSettings*"); return(C_to_Xen_gchar_(gtk_print_settings_get_output_bin(Xen_to_C_GtkPrintSettings_(settings)))); } static Xen gxg_gtk_print_settings_set_output_bin(Xen settings, Xen output_bin) { #define H_gtk_print_settings_set_output_bin "void gtk_print_settings_set_output_bin(GtkPrintSettings* settings, \ gchar* output_bin)" Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_set_output_bin", "GtkPrintSettings*"); Xen_check_type(Xen_is_gchar_(output_bin), output_bin, 2, "gtk_print_settings_set_output_bin", "gchar*"); gtk_print_settings_set_output_bin(Xen_to_C_GtkPrintSettings_(settings), Xen_to_C_gchar_(output_bin)); return(Xen_false); } static Xen gxg_gtk_settings_get_for_screen(Xen screen) { #define H_gtk_settings_get_for_screen "GtkSettings* gtk_settings_get_for_screen(GdkScreen* screen)" Xen_check_type(Xen_is_GdkScreen_(screen), screen, 1, "gtk_settings_get_for_screen", "GdkScreen*"); return(C_to_Xen_GtkSettings_(gtk_settings_get_for_screen(Xen_to_C_GdkScreen_(screen)))); } static Xen gxg_pango_cairo_create_layout(Xen cr) { #define H_pango_cairo_create_layout "PangoLayout* pango_cairo_create_layout(cairo_t* cr)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "pango_cairo_create_layout", "cairo_t*"); return(C_to_Xen_PangoLayout_(pango_cairo_create_layout(Xen_to_C_cairo_t_(cr)))); } static Xen gxg_pango_cairo_update_layout(Xen cr, Xen layout) { #define H_pango_cairo_update_layout "void pango_cairo_update_layout(cairo_t* cr, PangoLayout* layout)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "pango_cairo_update_layout", "cairo_t*"); Xen_check_type(Xen_is_PangoLayout_(layout), layout, 2, "pango_cairo_update_layout", "PangoLayout*"); pango_cairo_update_layout(Xen_to_C_cairo_t_(cr), Xen_to_C_PangoLayout_(layout)); return(Xen_false); } static Xen gxg_pango_cairo_update_context(Xen cr, Xen context) { #define H_pango_cairo_update_context "void pango_cairo_update_context(cairo_t* cr, PangoContext* context)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "pango_cairo_update_context", "cairo_t*"); Xen_check_type(Xen_is_PangoContext_(context), context, 2, "pango_cairo_update_context", "PangoContext*"); pango_cairo_update_context(Xen_to_C_cairo_t_(cr), Xen_to_C_PangoContext_(context)); return(Xen_false); } static Xen gxg_pango_cairo_context_set_font_options(Xen context, Xen options) { #define H_pango_cairo_context_set_font_options "void pango_cairo_context_set_font_options(PangoContext* context, \ cairo_font_options_t* options)" Xen_check_type(Xen_is_PangoContext_(context), context, 1, "pango_cairo_context_set_font_options", "PangoContext*"); Xen_check_type(Xen_is_cairo_font_options_t_(options), options, 2, "pango_cairo_context_set_font_options", "cairo_font_options_t*"); pango_cairo_context_set_font_options(Xen_to_C_PangoContext_(context), Xen_to_C_cairo_font_options_t_(options)); return(Xen_false); } static Xen gxg_pango_cairo_context_get_font_options(Xen context) { #define H_pango_cairo_context_get_font_options "cairo_font_options_t* pango_cairo_context_get_font_options(PangoContext* context)" Xen_check_type(Xen_is_PangoContext_(context), context, 1, "pango_cairo_context_get_font_options", "PangoContext*"); return(C_to_Xen_cairo_font_options_t_((cairo_font_options_t*)pango_cairo_context_get_font_options(Xen_to_C_PangoContext_(context)))); } static Xen gxg_pango_cairo_context_set_resolution(Xen context, Xen dpi) { #define H_pango_cairo_context_set_resolution "void pango_cairo_context_set_resolution(PangoContext* context, \ gdouble dpi)" Xen_check_type(Xen_is_PangoContext_(context), context, 1, "pango_cairo_context_set_resolution", "PangoContext*"); Xen_check_type(Xen_is_gdouble(dpi), dpi, 2, "pango_cairo_context_set_resolution", "gdouble"); pango_cairo_context_set_resolution(Xen_to_C_PangoContext_(context), Xen_to_C_gdouble(dpi)); return(Xen_false); } static Xen gxg_pango_cairo_context_get_resolution(Xen context) { #define H_pango_cairo_context_get_resolution "gdouble pango_cairo_context_get_resolution(PangoContext* context)" Xen_check_type(Xen_is_PangoContext_(context), context, 1, "pango_cairo_context_get_resolution", "PangoContext*"); return(C_to_Xen_gdouble(pango_cairo_context_get_resolution(Xen_to_C_PangoContext_(context)))); } static Xen gxg_pango_cairo_show_glyph_string(Xen cr, Xen font, Xen glyphs) { #define H_pango_cairo_show_glyph_string "void pango_cairo_show_glyph_string(cairo_t* cr, PangoFont* font, \ PangoGlyphString* glyphs)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "pango_cairo_show_glyph_string", "cairo_t*"); Xen_check_type(Xen_is_PangoFont_(font), font, 2, "pango_cairo_show_glyph_string", "PangoFont*"); Xen_check_type(Xen_is_PangoGlyphString_(glyphs), glyphs, 3, "pango_cairo_show_glyph_string", "PangoGlyphString*"); pango_cairo_show_glyph_string(Xen_to_C_cairo_t_(cr), Xen_to_C_PangoFont_(font), Xen_to_C_PangoGlyphString_(glyphs)); return(Xen_false); } static Xen gxg_pango_cairo_show_layout_line(Xen cr, Xen line) { #define H_pango_cairo_show_layout_line "void pango_cairo_show_layout_line(cairo_t* cr, PangoLayoutLine* line)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "pango_cairo_show_layout_line", "cairo_t*"); Xen_check_type(Xen_is_PangoLayoutLine_(line), line, 2, "pango_cairo_show_layout_line", "PangoLayoutLine*"); pango_cairo_show_layout_line(Xen_to_C_cairo_t_(cr), Xen_to_C_PangoLayoutLine_(line)); return(Xen_false); } static Xen gxg_pango_cairo_show_layout(Xen cr, Xen layout) { #define H_pango_cairo_show_layout "void pango_cairo_show_layout(cairo_t* cr, PangoLayout* layout)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "pango_cairo_show_layout", "cairo_t*"); Xen_check_type(Xen_is_PangoLayout_(layout), layout, 2, "pango_cairo_show_layout", "PangoLayout*"); pango_cairo_show_layout(Xen_to_C_cairo_t_(cr), Xen_to_C_PangoLayout_(layout)); return(Xen_false); } static Xen gxg_pango_cairo_show_error_underline(Xen cr, Xen x, Xen y, Xen width, Xen height) { #define H_pango_cairo_show_error_underline "void pango_cairo_show_error_underline(cairo_t* cr, gdouble x, \ gdouble y, gdouble width, gdouble height)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "pango_cairo_show_error_underline", "cairo_t*"); Xen_check_type(Xen_is_gdouble(x), x, 2, "pango_cairo_show_error_underline", "gdouble"); Xen_check_type(Xen_is_gdouble(y), y, 3, "pango_cairo_show_error_underline", "gdouble"); Xen_check_type(Xen_is_gdouble(width), width, 4, "pango_cairo_show_error_underline", "gdouble"); Xen_check_type(Xen_is_gdouble(height), height, 5, "pango_cairo_show_error_underline", "gdouble"); pango_cairo_show_error_underline(Xen_to_C_cairo_t_(cr), Xen_to_C_gdouble(x), Xen_to_C_gdouble(y), Xen_to_C_gdouble(width), Xen_to_C_gdouble(height)); return(Xen_false); } static Xen gxg_pango_cairo_glyph_string_path(Xen cr, Xen font, Xen glyphs) { #define H_pango_cairo_glyph_string_path "void pango_cairo_glyph_string_path(cairo_t* cr, PangoFont* font, \ PangoGlyphString* glyphs)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "pango_cairo_glyph_string_path", "cairo_t*"); Xen_check_type(Xen_is_PangoFont_(font), font, 2, "pango_cairo_glyph_string_path", "PangoFont*"); Xen_check_type(Xen_is_PangoGlyphString_(glyphs), glyphs, 3, "pango_cairo_glyph_string_path", "PangoGlyphString*"); pango_cairo_glyph_string_path(Xen_to_C_cairo_t_(cr), Xen_to_C_PangoFont_(font), Xen_to_C_PangoGlyphString_(glyphs)); return(Xen_false); } static Xen gxg_pango_cairo_layout_line_path(Xen cr, Xen line) { #define H_pango_cairo_layout_line_path "void pango_cairo_layout_line_path(cairo_t* cr, PangoLayoutLine* line)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "pango_cairo_layout_line_path", "cairo_t*"); Xen_check_type(Xen_is_PangoLayoutLine_(line), line, 2, "pango_cairo_layout_line_path", "PangoLayoutLine*"); pango_cairo_layout_line_path(Xen_to_C_cairo_t_(cr), Xen_to_C_PangoLayoutLine_(line)); return(Xen_false); } static Xen gxg_pango_cairo_layout_path(Xen cr, Xen layout) { #define H_pango_cairo_layout_path "void pango_cairo_layout_path(cairo_t* cr, PangoLayout* layout)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "pango_cairo_layout_path", "cairo_t*"); Xen_check_type(Xen_is_PangoLayout_(layout), layout, 2, "pango_cairo_layout_path", "PangoLayout*"); pango_cairo_layout_path(Xen_to_C_cairo_t_(cr), Xen_to_C_PangoLayout_(layout)); return(Xen_false); } static Xen gxg_pango_cairo_error_underline_path(Xen cr, Xen x, Xen y, Xen width, Xen height) { #define H_pango_cairo_error_underline_path "void pango_cairo_error_underline_path(cairo_t* cr, gdouble x, \ gdouble y, gdouble width, gdouble height)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "pango_cairo_error_underline_path", "cairo_t*"); Xen_check_type(Xen_is_gdouble(x), x, 2, "pango_cairo_error_underline_path", "gdouble"); Xen_check_type(Xen_is_gdouble(y), y, 3, "pango_cairo_error_underline_path", "gdouble"); Xen_check_type(Xen_is_gdouble(width), width, 4, "pango_cairo_error_underline_path", "gdouble"); Xen_check_type(Xen_is_gdouble(height), height, 5, "pango_cairo_error_underline_path", "gdouble"); pango_cairo_error_underline_path(Xen_to_C_cairo_t_(cr), Xen_to_C_gdouble(x), Xen_to_C_gdouble(y), Xen_to_C_gdouble(width), Xen_to_C_gdouble(height)); return(Xen_false); } static Xen gxg_gdk_cairo_set_source_pixbuf(Xen cr, Xen pixbuf, Xen pixbuf_x, Xen pixbuf_y) { #define H_gdk_cairo_set_source_pixbuf "void gdk_cairo_set_source_pixbuf(cairo_t* cr, GdkPixbuf* pixbuf, \ gdouble pixbuf_x, gdouble pixbuf_y)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "gdk_cairo_set_source_pixbuf", "cairo_t*"); Xen_check_type(Xen_is_GdkPixbuf_(pixbuf), pixbuf, 2, "gdk_cairo_set_source_pixbuf", "GdkPixbuf*"); Xen_check_type(Xen_is_gdouble(pixbuf_x), pixbuf_x, 3, "gdk_cairo_set_source_pixbuf", "gdouble"); Xen_check_type(Xen_is_gdouble(pixbuf_y), pixbuf_y, 4, "gdk_cairo_set_source_pixbuf", "gdouble"); gdk_cairo_set_source_pixbuf(Xen_to_C_cairo_t_(cr), Xen_to_C_GdkPixbuf_(pixbuf), Xen_to_C_gdouble(pixbuf_x), Xen_to_C_gdouble(pixbuf_y)); return(Xen_false); } static Xen gxg_gdk_cairo_rectangle(Xen cr, Xen rectangle) { #define H_gdk_cairo_rectangle "void gdk_cairo_rectangle(cairo_t* cr, GdkRectangle* rectangle)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "gdk_cairo_rectangle", "cairo_t*"); Xen_check_type(Xen_is_GdkRectangle_(rectangle), rectangle, 2, "gdk_cairo_rectangle", "GdkRectangle*"); gdk_cairo_rectangle(Xen_to_C_cairo_t_(cr), Xen_to_C_GdkRectangle_(rectangle)); return(Xen_false); } static Xen gxg_gdk_event_request_motions(Xen event) { #define H_gdk_event_request_motions "void gdk_event_request_motions(GdkEventMotion* event)" Xen_check_type(Xen_is_GdkEventMotion_(event), event, 1, "gdk_event_request_motions", "GdkEventMotion*"); gdk_event_request_motions(Xen_to_C_GdkEventMotion_(event)); return(Xen_false); } static Xen gxg_gdk_notify_startup_complete_with_id(Xen startup_id) { #define H_gdk_notify_startup_complete_with_id "void gdk_notify_startup_complete_with_id(gchar* startup_id)" Xen_check_type(Xen_is_gchar_(startup_id), startup_id, 1, "gdk_notify_startup_complete_with_id", "gchar*"); gdk_notify_startup_complete_with_id(Xen_to_C_gchar_(startup_id)); return(Xen_false); } static Xen gxg_gdk_threads_add_idle_full(Xen priority, Xen func, Xen func_info, Xen notify) { #define H_gdk_threads_add_idle_full "guint gdk_threads_add_idle_full(gint priority, GSourceFunc func, \ lambda_data func_info, GDestroyNotify notify)" Xen_check_type(Xen_is_gint(priority), priority, 1, "gdk_threads_add_idle_full", "gint"); Xen_check_type(Xen_is_GSourceFunc(func), func, 2, "gdk_threads_add_idle_full", "GSourceFunc"); Xen_check_type(Xen_is_lambda_data(func_info), func_info, 3, "gdk_threads_add_idle_full", "lambda_data"); Xen_check_type(Xen_is_GDestroyNotify(notify), notify, 4, "gdk_threads_add_idle_full", "GDestroyNotify"); { Xen result; int loc; Xen gxg_ptr = Xen_list_5(func, func_info, Xen_false, Xen_false, Xen_false); loc = xm_protect(gxg_ptr); Xen_list_set(gxg_ptr, 2, C_int_to_Xen_integer(loc)); result = C_to_Xen_guint(gdk_threads_add_idle_full(Xen_to_C_gint(priority), Xen_to_C_GSourceFunc(func), Xen_to_C_lambda_data(func_info), Xen_to_C_GDestroyNotify(notify))); Xen_list_set(gxg_ptr, 2, Xen_list_3(xg_idler_symbol, result, C_int_to_Xen_integer(loc))); return(result); } } static Xen gxg_gdk_threads_add_idle(Xen func, Xen func_info) { #define H_gdk_threads_add_idle "guint gdk_threads_add_idle(GSourceFunc func, lambda_data func_info)" Xen_check_type(Xen_is_GSourceFunc(func), func, 1, "gdk_threads_add_idle", "GSourceFunc"); if (!Xen_is_bound(func_info)) func_info = Xen_false; else Xen_check_type(Xen_is_lambda_data(func_info), func_info, 2, "gdk_threads_add_idle", "lambda_data"); { Xen result; int loc; Xen gxg_ptr = Xen_list_5(func, func_info, Xen_false, Xen_false, Xen_false); loc = xm_protect(gxg_ptr); Xen_list_set(gxg_ptr, 2, C_int_to_Xen_integer(loc)); result = C_to_Xen_guint(gdk_threads_add_idle(Xen_to_C_GSourceFunc(func), Xen_to_C_lambda_data(func_info))); Xen_list_set(gxg_ptr, 2, Xen_list_3(xg_idler_symbol, result, C_int_to_Xen_integer(loc))); return(result); } } static Xen gxg_gdk_threads_add_timeout_full(Xen priority, Xen interval, Xen func, Xen func_info, Xen notify) { #define H_gdk_threads_add_timeout_full "guint gdk_threads_add_timeout_full(gint priority, guint interval, \ GSourceFunc func, lambda_data func_info, GDestroyNotify notify)" Xen_check_type(Xen_is_gint(priority), priority, 1, "gdk_threads_add_timeout_full", "gint"); Xen_check_type(Xen_is_guint(interval), interval, 2, "gdk_threads_add_timeout_full", "guint"); Xen_check_type(Xen_is_GSourceFunc(func), func, 3, "gdk_threads_add_timeout_full", "GSourceFunc"); Xen_check_type(Xen_is_lambda_data(func_info), func_info, 4, "gdk_threads_add_timeout_full", "lambda_data"); Xen_check_type(Xen_is_GDestroyNotify(notify), notify, 5, "gdk_threads_add_timeout_full", "GDestroyNotify"); { Xen result; int loc; Xen gxg_ptr = Xen_list_5(func, func_info, Xen_false, Xen_false, Xen_false); loc = xm_protect(gxg_ptr); Xen_list_set(gxg_ptr, 2, C_int_to_Xen_integer(loc)); result = C_to_Xen_guint(gdk_threads_add_timeout_full(Xen_to_C_gint(priority), Xen_to_C_guint(interval), Xen_to_C_GSourceFunc(func), Xen_to_C_lambda_data(func_info), Xen_to_C_GDestroyNotify(notify))); Xen_list_set(gxg_ptr, 2, Xen_list_3(xg_idler_symbol, result, C_int_to_Xen_integer(loc))); return(result); } } static Xen gxg_gdk_threads_add_timeout(Xen interval, Xen func, Xen func_info) { #define H_gdk_threads_add_timeout "guint gdk_threads_add_timeout(guint interval, GSourceFunc func, \ lambda_data func_info)" Xen_check_type(Xen_is_guint(interval), interval, 1, "gdk_threads_add_timeout", "guint"); Xen_check_type(Xen_is_GSourceFunc(func), func, 2, "gdk_threads_add_timeout", "GSourceFunc"); if (!Xen_is_bound(func_info)) func_info = Xen_false; else Xen_check_type(Xen_is_lambda_data(func_info), func_info, 3, "gdk_threads_add_timeout", "lambda_data"); { Xen result; int loc; Xen gxg_ptr = Xen_list_5(func, func_info, Xen_false, Xen_false, Xen_false); loc = xm_protect(gxg_ptr); Xen_list_set(gxg_ptr, 2, C_int_to_Xen_integer(loc)); result = C_to_Xen_guint(gdk_threads_add_timeout(Xen_to_C_guint(interval), Xen_to_C_GSourceFunc(func), Xen_to_C_lambda_data(func_info))); Xen_list_set(gxg_ptr, 2, Xen_list_3(xg_idler_symbol, result, C_int_to_Xen_integer(loc))); return(result); } } static Xen gxg_gdk_window_set_startup_id(Xen window, Xen startup_id) { #define H_gdk_window_set_startup_id "void gdk_window_set_startup_id(GdkWindow* window, gchar* startup_id)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_set_startup_id", "GdkWindow*"); Xen_check_type(Xen_is_gchar_(startup_id), startup_id, 2, "gdk_window_set_startup_id", "gchar*"); gdk_window_set_startup_id(Xen_to_C_GdkWindow_(window), Xen_to_C_gchar_(startup_id)); return(Xen_false); } static Xen gxg_gdk_window_beep(Xen window) { #define H_gdk_window_beep "void gdk_window_beep(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_beep", "GdkWindow*"); gdk_window_beep(Xen_to_C_GdkWindow_(window)); return(Xen_false); } static Xen gxg_gdk_window_set_opacity(Xen window, Xen opacity) { #define H_gdk_window_set_opacity "void gdk_window_set_opacity(GdkWindow* window, gdouble opacity)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_set_opacity", "GdkWindow*"); Xen_check_type(Xen_is_gdouble(opacity), opacity, 2, "gdk_window_set_opacity", "gdouble"); gdk_window_set_opacity(Xen_to_C_GdkWindow_(window), Xen_to_C_gdouble(opacity)); return(Xen_false); } static Xen gxg_gtk_binding_entry_skip(Xen binding_set, Xen keyval, Xen modifiers) { #define H_gtk_binding_entry_skip "void gtk_binding_entry_skip(GtkBindingSet* binding_set, guint keyval, \ GdkModifierType modifiers)" Xen_check_type(Xen_is_GtkBindingSet_(binding_set), binding_set, 1, "gtk_binding_entry_skip", "GtkBindingSet*"); Xen_check_type(Xen_is_guint(keyval), keyval, 2, "gtk_binding_entry_skip", "guint"); Xen_check_type(Xen_is_GdkModifierType(modifiers), modifiers, 3, "gtk_binding_entry_skip", "GdkModifierType"); gtk_binding_entry_skip(Xen_to_C_GtkBindingSet_(binding_set), Xen_to_C_guint(keyval), Xen_to_C_GdkModifierType(modifiers)); return(Xen_false); } static Xen gxg_gtk_cell_layout_get_cells(Xen cell_layout) { #define H_gtk_cell_layout_get_cells "GList* gtk_cell_layout_get_cells(GtkCellLayout* cell_layout)" Xen_check_type(Xen_is_GtkCellLayout_(cell_layout), cell_layout, 1, "gtk_cell_layout_get_cells", "GtkCellLayout*"); return(C_to_Xen_GList_(gtk_cell_layout_get_cells(Xen_to_C_GtkCellLayout_(cell_layout)))); } static Xen gxg_gtk_entry_completion_set_inline_selection(Xen completion, Xen inline_selection) { #define H_gtk_entry_completion_set_inline_selection "void gtk_entry_completion_set_inline_selection(GtkEntryCompletion* completion, \ gboolean inline_selection)" Xen_check_type(Xen_is_GtkEntryCompletion_(completion), completion, 1, "gtk_entry_completion_set_inline_selection", "GtkEntryCompletion*"); Xen_check_type(Xen_is_gboolean(inline_selection), inline_selection, 2, "gtk_entry_completion_set_inline_selection", "gboolean"); gtk_entry_completion_set_inline_selection(Xen_to_C_GtkEntryCompletion_(completion), Xen_to_C_gboolean(inline_selection)); return(Xen_false); } static Xen gxg_gtk_entry_completion_get_inline_selection(Xen completion) { #define H_gtk_entry_completion_get_inline_selection "gboolean gtk_entry_completion_get_inline_selection(GtkEntryCompletion* completion)" Xen_check_type(Xen_is_GtkEntryCompletion_(completion), completion, 1, "gtk_entry_completion_get_inline_selection", "GtkEntryCompletion*"); return(C_to_Xen_gboolean(gtk_entry_completion_get_inline_selection(Xen_to_C_GtkEntryCompletion_(completion)))); } static Xen gxg_gtk_entry_completion_get_completion_prefix(Xen completion) { #define H_gtk_entry_completion_get_completion_prefix "gchar* gtk_entry_completion_get_completion_prefix(GtkEntryCompletion* completion)" Xen_check_type(Xen_is_GtkEntryCompletion_(completion), completion, 1, "gtk_entry_completion_get_completion_prefix", "GtkEntryCompletion*"); return(C_to_Xen_gchar_(gtk_entry_completion_get_completion_prefix(Xen_to_C_GtkEntryCompletion_(completion)))); } static Xen gxg_gtk_entry_set_cursor_hadjustment(Xen entry, Xen adjustment) { #define H_gtk_entry_set_cursor_hadjustment "void gtk_entry_set_cursor_hadjustment(GtkEntry* entry, \ GtkAdjustment* adjustment)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_set_cursor_hadjustment", "GtkEntry*"); Xen_check_type(Xen_is_GtkAdjustment_(adjustment), adjustment, 2, "gtk_entry_set_cursor_hadjustment", "GtkAdjustment*"); gtk_entry_set_cursor_hadjustment(Xen_to_C_GtkEntry_(entry), Xen_to_C_GtkAdjustment_(adjustment)); return(Xen_false); } static Xen gxg_gtk_entry_get_cursor_hadjustment(Xen entry) { #define H_gtk_entry_get_cursor_hadjustment "GtkAdjustment* gtk_entry_get_cursor_hadjustment(GtkEntry* entry)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_get_cursor_hadjustment", "GtkEntry*"); return(C_to_Xen_GtkAdjustment_(gtk_entry_get_cursor_hadjustment(Xen_to_C_GtkEntry_(entry)))); } static Xen gxg_gtk_icon_theme_list_contexts(Xen icon_theme) { #define H_gtk_icon_theme_list_contexts "GList* gtk_icon_theme_list_contexts(GtkIconTheme* icon_theme)" Xen_check_type(Xen_is_GtkIconTheme_(icon_theme), icon_theme, 1, "gtk_icon_theme_list_contexts", "GtkIconTheme*"); return(C_to_Xen_GList_(gtk_icon_theme_list_contexts(Xen_to_C_GtkIconTheme_(icon_theme)))); } static Xen gxg_gtk_print_settings_new_from_file(Xen file_name, Xen ignore_error) { #define H_gtk_print_settings_new_from_file "GtkPrintSettings* gtk_print_settings_new_from_file(gchar* file_name, \ GError** [error])" GError* ref_error = NULL; Xen_check_type(Xen_is_gchar_(file_name), file_name, 1, "gtk_print_settings_new_from_file", "gchar*"); { Xen result; result = C_to_Xen_GtkPrintSettings_(gtk_print_settings_new_from_file(Xen_to_C_gchar_(file_name), &ref_error)); return(Xen_list_2(result, C_to_Xen_GError_(ref_error))); } } static Xen gxg_gtk_print_settings_to_file(Xen settings, Xen file_name, Xen ignore_error) { #define H_gtk_print_settings_to_file "gboolean gtk_print_settings_to_file(GtkPrintSettings* settings, \ gchar* file_name, GError** [error])" GError* ref_error = NULL; Xen_check_type(Xen_is_GtkPrintSettings_(settings), settings, 1, "gtk_print_settings_to_file", "GtkPrintSettings*"); Xen_check_type(Xen_is_gchar_(file_name), file_name, 2, "gtk_print_settings_to_file", "gchar*"); { Xen result; result = C_to_Xen_gboolean(gtk_print_settings_to_file(Xen_to_C_GtkPrintSettings_(settings), Xen_to_C_gchar_(file_name), &ref_error)); return(Xen_list_2(result, C_to_Xen_GError_(ref_error))); } } static Xen gxg_gtk_range_set_show_fill_level(Xen range, Xen show_fill_level) { #define H_gtk_range_set_show_fill_level "void gtk_range_set_show_fill_level(GtkRange* range, gboolean, \ show_fill_level)" Xen_check_type(Xen_is_GtkRange_(range), range, 1, "gtk_range_set_show_fill_level", "GtkRange*"); Xen_check_type(Xen_is_gboolean(show_fill_level), show_fill_level, 2, "gtk_range_set_show_fill_level", "gboolean"); gtk_range_set_show_fill_level(Xen_to_C_GtkRange_(range), Xen_to_C_gboolean(show_fill_level)); return(Xen_false); } static Xen gxg_gtk_range_get_show_fill_level(Xen range) { #define H_gtk_range_get_show_fill_level "gboolean gtk_range_get_show_fill_level(GtkRange* range)" Xen_check_type(Xen_is_GtkRange_(range), range, 1, "gtk_range_get_show_fill_level", "GtkRange*"); return(C_to_Xen_gboolean(gtk_range_get_show_fill_level(Xen_to_C_GtkRange_(range)))); } static Xen gxg_gtk_range_set_restrict_to_fill_level(Xen range, Xen restrict_to_fill_level) { #define H_gtk_range_set_restrict_to_fill_level "void gtk_range_set_restrict_to_fill_level(GtkRange* range, \ gboolean, restrict_to_fill_level)" Xen_check_type(Xen_is_GtkRange_(range), range, 1, "gtk_range_set_restrict_to_fill_level", "GtkRange*"); Xen_check_type(Xen_is_gboolean(restrict_to_fill_level), restrict_to_fill_level, 2, "gtk_range_set_restrict_to_fill_level", "gboolean"); gtk_range_set_restrict_to_fill_level(Xen_to_C_GtkRange_(range), Xen_to_C_gboolean(restrict_to_fill_level)); return(Xen_false); } static Xen gxg_gtk_range_get_restrict_to_fill_level(Xen range) { #define H_gtk_range_get_restrict_to_fill_level "gboolean gtk_range_get_restrict_to_fill_level(GtkRange* range)" Xen_check_type(Xen_is_GtkRange_(range), range, 1, "gtk_range_get_restrict_to_fill_level", "GtkRange*"); return(C_to_Xen_gboolean(gtk_range_get_restrict_to_fill_level(Xen_to_C_GtkRange_(range)))); } static Xen gxg_gtk_range_set_fill_level(Xen range, Xen fill_level) { #define H_gtk_range_set_fill_level "void gtk_range_set_fill_level(GtkRange* range, gdouble, fill_level)" Xen_check_type(Xen_is_GtkRange_(range), range, 1, "gtk_range_set_fill_level", "GtkRange*"); Xen_check_type(Xen_is_gdouble(fill_level), fill_level, 2, "gtk_range_set_fill_level", "gdouble"); gtk_range_set_fill_level(Xen_to_C_GtkRange_(range), Xen_to_C_gdouble(fill_level)); return(Xen_false); } static Xen gxg_gtk_range_get_fill_level(Xen range) { #define H_gtk_range_get_fill_level "gdouble gtk_range_get_fill_level(GtkRange* range)" Xen_check_type(Xen_is_GtkRange_(range), range, 1, "gtk_range_get_fill_level", "GtkRange*"); return(C_to_Xen_gdouble(gtk_range_get_fill_level(Xen_to_C_GtkRange_(range)))); } static Xen gxg_gtk_tree_view_set_show_expanders(Xen tree_view, Xen enabled) { #define H_gtk_tree_view_set_show_expanders "void gtk_tree_view_set_show_expanders(GtkTreeView* tree_view, \ gboolean enabled)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_set_show_expanders", "GtkTreeView*"); Xen_check_type(Xen_is_gboolean(enabled), enabled, 2, "gtk_tree_view_set_show_expanders", "gboolean"); gtk_tree_view_set_show_expanders(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_gboolean(enabled)); return(Xen_false); } static Xen gxg_gtk_tree_view_get_show_expanders(Xen tree_view) { #define H_gtk_tree_view_get_show_expanders "gboolean gtk_tree_view_get_show_expanders(GtkTreeView* tree_view)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_get_show_expanders", "GtkTreeView*"); return(C_to_Xen_gboolean(gtk_tree_view_get_show_expanders(Xen_to_C_GtkTreeView_(tree_view)))); } static Xen gxg_gtk_tree_view_set_level_indentation(Xen tree_view, Xen indentation) { #define H_gtk_tree_view_set_level_indentation "void gtk_tree_view_set_level_indentation(GtkTreeView* tree_view, \ gint indentation)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_set_level_indentation", "GtkTreeView*"); Xen_check_type(Xen_is_gint(indentation), indentation, 2, "gtk_tree_view_set_level_indentation", "gint"); gtk_tree_view_set_level_indentation(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_gint(indentation)); return(Xen_false); } static Xen gxg_gtk_tree_view_get_level_indentation(Xen tree_view) { #define H_gtk_tree_view_get_level_indentation "gint gtk_tree_view_get_level_indentation(GtkTreeView* tree_view)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_get_level_indentation", "GtkTreeView*"); return(C_to_Xen_gint(gtk_tree_view_get_level_indentation(Xen_to_C_GtkTreeView_(tree_view)))); } static Xen gxg_gtk_widget_keynav_failed(Xen widget, Xen direction) { #define H_gtk_widget_keynav_failed "gboolean gtk_widget_keynav_failed(GtkWidget* widget, GtkDirectionType direction)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_keynav_failed", "GtkWidget*"); Xen_check_type(Xen_is_GtkDirectionType(direction), direction, 2, "gtk_widget_keynav_failed", "GtkDirectionType"); return(C_to_Xen_gboolean(gtk_widget_keynav_failed(Xen_to_C_GtkWidget_(widget), Xen_to_C_GtkDirectionType(direction)))); } static Xen gxg_gtk_widget_error_bell(Xen widget) { #define H_gtk_widget_error_bell "void gtk_widget_error_bell(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_error_bell", "GtkWidget*"); gtk_widget_error_bell(Xen_to_C_GtkWidget_(widget)); return(Xen_false); } static Xen gxg_gtk_widget_set_tooltip_window(Xen widget, Xen custom_window) { #define H_gtk_widget_set_tooltip_window "void gtk_widget_set_tooltip_window(GtkWidget* widget, GtkWindow* custom_window)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_set_tooltip_window", "GtkWidget*"); Xen_check_type(Xen_is_GtkWindow_(custom_window), custom_window, 2, "gtk_widget_set_tooltip_window", "GtkWindow*"); gtk_widget_set_tooltip_window(Xen_to_C_GtkWidget_(widget), Xen_to_C_GtkWindow_(custom_window)); return(Xen_false); } static Xen gxg_gtk_widget_get_tooltip_window(Xen widget) { #define H_gtk_widget_get_tooltip_window "GtkWindow* gtk_widget_get_tooltip_window(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_tooltip_window", "GtkWidget*"); return(C_to_Xen_GtkWindow_(gtk_widget_get_tooltip_window(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_trigger_tooltip_query(Xen widget) { #define H_gtk_widget_trigger_tooltip_query "void gtk_widget_trigger_tooltip_query(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_trigger_tooltip_query", "GtkWidget*"); gtk_widget_trigger_tooltip_query(Xen_to_C_GtkWidget_(widget)); return(Xen_false); } static Xen gxg_gtk_window_set_startup_id(Xen window, Xen startup_id) { #define H_gtk_window_set_startup_id "void gtk_window_set_startup_id(GtkWindow* window, gchar* startup_id)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_set_startup_id", "GtkWindow*"); Xen_check_type(Xen_is_gchar_(startup_id), startup_id, 2, "gtk_window_set_startup_id", "gchar*"); gtk_window_set_startup_id(Xen_to_C_GtkWindow_(window), Xen_to_C_gchar_(startup_id)); return(Xen_false); } static Xen gxg_gtk_text_buffer_add_mark(Xen buffer, Xen mark, Xen where) { #define H_gtk_text_buffer_add_mark "void gtk_text_buffer_add_mark(GtkTextBuffer* buffer, GtkTextMark* mark, \ GtkTextIter* where)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_add_mark", "GtkTextBuffer*"); Xen_check_type(Xen_is_GtkTextMark_(mark), mark, 2, "gtk_text_buffer_add_mark", "GtkTextMark*"); Xen_check_type(Xen_is_GtkTextIter_(where), where, 3, "gtk_text_buffer_add_mark", "GtkTextIter*"); gtk_text_buffer_add_mark(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_GtkTextMark_(mark), Xen_to_C_GtkTextIter_(where)); return(Xen_false); } static Xen gxg_gtk_text_mark_new(Xen name, Xen left_gravity) { #define H_gtk_text_mark_new "GtkTextMark* gtk_text_mark_new(gchar* name, gboolean left_gravity)" Xen_check_type(Xen_is_gchar_(name), name, 1, "gtk_text_mark_new", "gchar*"); Xen_check_type(Xen_is_gboolean(left_gravity), left_gravity, 2, "gtk_text_mark_new", "gboolean"); return(C_to_Xen_GtkTextMark_(gtk_text_mark_new(Xen_to_C_gchar_(name), Xen_to_C_gboolean(left_gravity)))); } static Xen gxg_gtk_tree_view_column_get_tree_view(Xen tree_column) { #define H_gtk_tree_view_column_get_tree_view "GtkWidget* gtk_tree_view_column_get_tree_view(GtkTreeViewColumn* tree_column)" Xen_check_type(Xen_is_GtkTreeViewColumn_(tree_column), tree_column, 1, "gtk_tree_view_column_get_tree_view", "GtkTreeViewColumn*"); return(C_to_Xen_GtkWidget_(gtk_tree_view_column_get_tree_view(Xen_to_C_GtkTreeViewColumn_(tree_column)))); } static Xen gxg_gtk_tooltip_set_text(Xen tooltip, Xen text) { #define H_gtk_tooltip_set_text "void gtk_tooltip_set_text(GtkTooltip* tooltip, gchar* text)" Xen_check_type(Xen_is_GtkTooltip_(tooltip), tooltip, 1, "gtk_tooltip_set_text", "GtkTooltip*"); Xen_check_type(Xen_is_gchar_(text), text, 2, "gtk_tooltip_set_text", "gchar*"); gtk_tooltip_set_text(Xen_to_C_GtkTooltip_(tooltip), (const gchar*)Xen_to_C_gchar_(text)); return(Xen_false); } static Xen gxg_gtk_tree_view_convert_widget_to_tree_coords(Xen tree_view, Xen wx, Xen wy, Xen ignore_tx, Xen ignore_ty) { #define H_gtk_tree_view_convert_widget_to_tree_coords "void gtk_tree_view_convert_widget_to_tree_coords(GtkTreeView* tree_view, \ gint wx, gint wy, gint* [tx], gint* [ty])" gint ref_tx; gint ref_ty; Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_convert_widget_to_tree_coords", "GtkTreeView*"); Xen_check_type(Xen_is_gint(wx), wx, 2, "gtk_tree_view_convert_widget_to_tree_coords", "gint"); Xen_check_type(Xen_is_gint(wy), wy, 3, "gtk_tree_view_convert_widget_to_tree_coords", "gint"); gtk_tree_view_convert_widget_to_tree_coords(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_gint(wx), Xen_to_C_gint(wy), &ref_tx, &ref_ty); return(Xen_list_2(C_to_Xen_gint(ref_tx), C_to_Xen_gint(ref_ty))); } static Xen gxg_gtk_tree_view_convert_tree_to_widget_coords(Xen tree_view, Xen tx, Xen ty, Xen ignore_wx, Xen ignore_wy) { #define H_gtk_tree_view_convert_tree_to_widget_coords "void gtk_tree_view_convert_tree_to_widget_coords(GtkTreeView* tree_view, \ gint tx, gint ty, gint* [wx], gint* [wy])" gint ref_wx; gint ref_wy; Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_convert_tree_to_widget_coords", "GtkTreeView*"); Xen_check_type(Xen_is_gint(tx), tx, 2, "gtk_tree_view_convert_tree_to_widget_coords", "gint"); Xen_check_type(Xen_is_gint(ty), ty, 3, "gtk_tree_view_convert_tree_to_widget_coords", "gint"); gtk_tree_view_convert_tree_to_widget_coords(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_gint(tx), Xen_to_C_gint(ty), &ref_wx, &ref_wy); return(Xen_list_2(C_to_Xen_gint(ref_wx), C_to_Xen_gint(ref_wy))); } static Xen gxg_gtk_tree_view_convert_widget_to_bin_window_coords(Xen tree_view, Xen wx, Xen wy, Xen ignore_bx, Xen ignore_by) { #define H_gtk_tree_view_convert_widget_to_bin_window_coords "void gtk_tree_view_convert_widget_to_bin_window_coords(GtkTreeView* tree_view, \ gint wx, gint wy, gint* [bx], gint* [by])" gint ref_bx; gint ref_by; Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_convert_widget_to_bin_window_coords", "GtkTreeView*"); Xen_check_type(Xen_is_gint(wx), wx, 2, "gtk_tree_view_convert_widget_to_bin_window_coords", "gint"); Xen_check_type(Xen_is_gint(wy), wy, 3, "gtk_tree_view_convert_widget_to_bin_window_coords", "gint"); gtk_tree_view_convert_widget_to_bin_window_coords(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_gint(wx), Xen_to_C_gint(wy), &ref_bx, &ref_by); return(Xen_list_2(C_to_Xen_gint(ref_bx), C_to_Xen_gint(ref_by))); } static Xen gxg_gtk_tree_view_convert_bin_window_to_widget_coords(Xen tree_view, Xen bx, Xen by, Xen ignore_wx, Xen ignore_wy) { #define H_gtk_tree_view_convert_bin_window_to_widget_coords "void gtk_tree_view_convert_bin_window_to_widget_coords(GtkTreeView* tree_view, \ gint bx, gint by, gint* [wx], gint* [wy])" gint ref_wx; gint ref_wy; Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_convert_bin_window_to_widget_coords", "GtkTreeView*"); Xen_check_type(Xen_is_gint(bx), bx, 2, "gtk_tree_view_convert_bin_window_to_widget_coords", "gint"); Xen_check_type(Xen_is_gint(by), by, 3, "gtk_tree_view_convert_bin_window_to_widget_coords", "gint"); gtk_tree_view_convert_bin_window_to_widget_coords(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_gint(bx), Xen_to_C_gint(by), &ref_wx, &ref_wy); return(Xen_list_2(C_to_Xen_gint(ref_wx), C_to_Xen_gint(ref_wy))); } static Xen gxg_gtk_tree_view_convert_tree_to_bin_window_coords(Xen tree_view, Xen tx, Xen ty, Xen ignore_bx, Xen ignore_by) { #define H_gtk_tree_view_convert_tree_to_bin_window_coords "void gtk_tree_view_convert_tree_to_bin_window_coords(GtkTreeView* tree_view, \ gint tx, gint ty, gint* [bx], gint* [by])" gint ref_bx; gint ref_by; Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_convert_tree_to_bin_window_coords", "GtkTreeView*"); Xen_check_type(Xen_is_gint(tx), tx, 2, "gtk_tree_view_convert_tree_to_bin_window_coords", "gint"); Xen_check_type(Xen_is_gint(ty), ty, 3, "gtk_tree_view_convert_tree_to_bin_window_coords", "gint"); gtk_tree_view_convert_tree_to_bin_window_coords(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_gint(tx), Xen_to_C_gint(ty), &ref_bx, &ref_by); return(Xen_list_2(C_to_Xen_gint(ref_bx), C_to_Xen_gint(ref_by))); } static Xen gxg_gtk_tree_view_convert_bin_window_to_tree_coords(Xen tree_view, Xen bx, Xen by, Xen ignore_tx, Xen ignore_ty) { #define H_gtk_tree_view_convert_bin_window_to_tree_coords "void gtk_tree_view_convert_bin_window_to_tree_coords(GtkTreeView* tree_view, \ gint bx, gint by, gint* [tx], gint* [ty])" gint ref_tx; gint ref_ty; Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_convert_bin_window_to_tree_coords", "GtkTreeView*"); Xen_check_type(Xen_is_gint(bx), bx, 2, "gtk_tree_view_convert_bin_window_to_tree_coords", "gint"); Xen_check_type(Xen_is_gint(by), by, 3, "gtk_tree_view_convert_bin_window_to_tree_coords", "gint"); gtk_tree_view_convert_bin_window_to_tree_coords(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_gint(bx), Xen_to_C_gint(by), &ref_tx, &ref_ty); return(Xen_list_2(C_to_Xen_gint(ref_tx), C_to_Xen_gint(ref_ty))); } static Xen gxg_gtk_widget_set_tooltip_text(Xen widget, Xen text) { #define H_gtk_widget_set_tooltip_text "void gtk_widget_set_tooltip_text(GtkWidget* widget, gchar* text)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_set_tooltip_text", "GtkWidget*"); Xen_check_type(Xen_is_gchar_(text), text, 2, "gtk_widget_set_tooltip_text", "gchar*"); gtk_widget_set_tooltip_text(Xen_to_C_GtkWidget_(widget), (const gchar*)Xen_to_C_gchar_(text)); return(Xen_false); } static Xen gxg_gtk_widget_get_tooltip_text(Xen widget) { #define H_gtk_widget_get_tooltip_text "gchar* gtk_widget_get_tooltip_text(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_tooltip_text", "GtkWidget*"); return(C_to_Xen_gchar_(gtk_widget_get_tooltip_text(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_set_tooltip_markup(Xen widget, Xen markup) { #define H_gtk_widget_set_tooltip_markup "void gtk_widget_set_tooltip_markup(GtkWidget* widget, gchar* markup)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_set_tooltip_markup", "GtkWidget*"); Xen_check_type(Xen_is_gchar_(markup), markup, 2, "gtk_widget_set_tooltip_markup", "gchar*"); gtk_widget_set_tooltip_markup(Xen_to_C_GtkWidget_(widget), (const gchar*)Xen_to_C_gchar_(markup)); return(Xen_false); } static Xen gxg_gtk_widget_get_tooltip_markup(Xen widget) { #define H_gtk_widget_get_tooltip_markup "gchar* gtk_widget_get_tooltip_markup(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_tooltip_markup", "GtkWidget*"); return(C_to_Xen_gchar_(gtk_widget_get_tooltip_markup(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_tree_view_is_rubber_banding_active(Xen tree_view) { #define H_gtk_tree_view_is_rubber_banding_active "gboolean gtk_tree_view_is_rubber_banding_active(GtkTreeView* tree_view)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_is_rubber_banding_active", "GtkTreeView*"); return(C_to_Xen_gboolean(gtk_tree_view_is_rubber_banding_active(Xen_to_C_GtkTreeView_(tree_view)))); } static Xen gxg_gtk_icon_view_convert_widget_to_bin_window_coords(Xen icon_view, Xen wx, Xen wy, Xen ignore_bx, Xen ignore_by) { #define H_gtk_icon_view_convert_widget_to_bin_window_coords "void gtk_icon_view_convert_widget_to_bin_window_coords(GtkIconView* icon_view, \ gint wx, gint wy, gint* [bx], gint* [by])" gint ref_bx; gint ref_by; Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_convert_widget_to_bin_window_coords", "GtkIconView*"); Xen_check_type(Xen_is_gint(wx), wx, 2, "gtk_icon_view_convert_widget_to_bin_window_coords", "gint"); Xen_check_type(Xen_is_gint(wy), wy, 3, "gtk_icon_view_convert_widget_to_bin_window_coords", "gint"); gtk_icon_view_convert_widget_to_bin_window_coords(Xen_to_C_GtkIconView_(icon_view), Xen_to_C_gint(wx), Xen_to_C_gint(wy), &ref_bx, &ref_by); return(Xen_list_2(C_to_Xen_gint(ref_bx), C_to_Xen_gint(ref_by))); } static Xen gxg_gtk_icon_view_set_tooltip_item(Xen icon_view, Xen tooltip, Xen path) { #define H_gtk_icon_view_set_tooltip_item "void gtk_icon_view_set_tooltip_item(GtkIconView* icon_view, \ GtkTooltip* tooltip, GtkTreePath* path)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_set_tooltip_item", "GtkIconView*"); Xen_check_type(Xen_is_GtkTooltip_(tooltip), tooltip, 2, "gtk_icon_view_set_tooltip_item", "GtkTooltip*"); Xen_check_type(Xen_is_GtkTreePath_(path), path, 3, "gtk_icon_view_set_tooltip_item", "GtkTreePath*"); gtk_icon_view_set_tooltip_item(Xen_to_C_GtkIconView_(icon_view), Xen_to_C_GtkTooltip_(tooltip), Xen_to_C_GtkTreePath_(path)); return(Xen_false); } static Xen gxg_gtk_icon_view_set_tooltip_cell(Xen icon_view, Xen tooltip, Xen path, Xen cell) { #define H_gtk_icon_view_set_tooltip_cell "void gtk_icon_view_set_tooltip_cell(GtkIconView* icon_view, \ GtkTooltip* tooltip, GtkTreePath* path, GtkCellRenderer* cell)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_set_tooltip_cell", "GtkIconView*"); Xen_check_type(Xen_is_GtkTooltip_(tooltip), tooltip, 2, "gtk_icon_view_set_tooltip_cell", "GtkTooltip*"); Xen_check_type(Xen_is_GtkTreePath_(path), path, 3, "gtk_icon_view_set_tooltip_cell", "GtkTreePath*"); Xen_check_type(Xen_is_GtkCellRenderer_(cell), cell, 4, "gtk_icon_view_set_tooltip_cell", "GtkCellRenderer*"); gtk_icon_view_set_tooltip_cell(Xen_to_C_GtkIconView_(icon_view), Xen_to_C_GtkTooltip_(tooltip), Xen_to_C_GtkTreePath_(path), Xen_to_C_GtkCellRenderer_(cell)); return(Xen_false); } static Xen gxg_gtk_icon_view_get_tooltip_context(Xen icon_view, Xen ignore_x, Xen ignore_y, Xen keyboard_tip, Xen ignore_model, Xen ignore_path, Xen iter) { #define H_gtk_icon_view_get_tooltip_context "gboolean gtk_icon_view_get_tooltip_context(GtkIconView* icon_view, \ gint* [x], gint* [y], gboolean keyboard_tip, GtkTreeModel** [model], GtkTreePath** [path], GtkTreeIter* iter)" gint ref_x; gint ref_y; GtkTreeModel* ref_model = NULL; GtkTreePath* ref_path = NULL; Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_get_tooltip_context", "GtkIconView*"); Xen_check_type(Xen_is_gboolean(keyboard_tip), keyboard_tip, 4, "gtk_icon_view_get_tooltip_context", "gboolean"); Xen_check_type(Xen_is_GtkTreeIter_(iter) || Xen_is_false(iter), iter, 7, "gtk_icon_view_get_tooltip_context", "GtkTreeIter*"); { Xen result; result = C_to_Xen_gboolean(gtk_icon_view_get_tooltip_context(Xen_to_C_GtkIconView_(icon_view), &ref_x, &ref_y, Xen_to_C_gboolean(keyboard_tip), &ref_model, &ref_path, Xen_to_C_GtkTreeIter_(iter))); return(Xen_list_5(result, C_to_Xen_gint(ref_x), C_to_Xen_gint(ref_y), C_to_Xen_GtkTreeModel_(ref_model), C_to_Xen_GtkTreePath_(ref_path))); } } static Xen gxg_gtk_icon_view_set_tooltip_column(Xen icon_view, Xen column) { #define H_gtk_icon_view_set_tooltip_column "void gtk_icon_view_set_tooltip_column(GtkIconView* icon_view, \ gint column)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_set_tooltip_column", "GtkIconView*"); Xen_check_type(Xen_is_gint(column), column, 2, "gtk_icon_view_set_tooltip_column", "gint"); gtk_icon_view_set_tooltip_column(Xen_to_C_GtkIconView_(icon_view), Xen_to_C_gint(column)); return(Xen_false); } static Xen gxg_gtk_icon_view_get_tooltip_column(Xen icon_view ) { #define H_gtk_icon_view_get_tooltip_column "gint gtk_icon_view_get_tooltip_column(GtkIconView* icon_view, \ )" Xen_check_type(Xen_is_GtkIconView_(icon_view ), icon_view , 1, "gtk_icon_view_get_tooltip_column", "GtkIconView*"); return(C_to_Xen_gint(gtk_icon_view_get_tooltip_column(Xen_to_C_GtkIconView_(icon_view )))); } static Xen gxg_gtk_menu_tool_button_set_arrow_tooltip_text(Xen button, Xen text) { #define H_gtk_menu_tool_button_set_arrow_tooltip_text "void gtk_menu_tool_button_set_arrow_tooltip_text(GtkMenuToolButton* button, \ gchar* text)" Xen_check_type(Xen_is_GtkMenuToolButton_(button), button, 1, "gtk_menu_tool_button_set_arrow_tooltip_text", "GtkMenuToolButton*"); Xen_check_type(Xen_is_gchar_(text), text, 2, "gtk_menu_tool_button_set_arrow_tooltip_text", "gchar*"); gtk_menu_tool_button_set_arrow_tooltip_text(Xen_to_C_GtkMenuToolButton_(button), (const gchar*)Xen_to_C_gchar_(text)); return(Xen_false); } static Xen gxg_gtk_menu_tool_button_set_arrow_tooltip_markup(Xen button, Xen markup) { #define H_gtk_menu_tool_button_set_arrow_tooltip_markup "void gtk_menu_tool_button_set_arrow_tooltip_markup(GtkMenuToolButton* button, \ gchar* markup)" Xen_check_type(Xen_is_GtkMenuToolButton_(button), button, 1, "gtk_menu_tool_button_set_arrow_tooltip_markup", "GtkMenuToolButton*"); Xen_check_type(Xen_is_gchar_(markup), markup, 2, "gtk_menu_tool_button_set_arrow_tooltip_markup", "gchar*"); gtk_menu_tool_button_set_arrow_tooltip_markup(Xen_to_C_GtkMenuToolButton_(button), (const gchar*)Xen_to_C_gchar_(markup)); return(Xen_false); } static Xen gxg_gtk_tool_item_set_tooltip_text(Xen tool_item, Xen text) { #define H_gtk_tool_item_set_tooltip_text "void gtk_tool_item_set_tooltip_text(GtkToolItem* tool_item, \ gchar* text)" Xen_check_type(Xen_is_GtkToolItem_(tool_item), tool_item, 1, "gtk_tool_item_set_tooltip_text", "GtkToolItem*"); Xen_check_type(Xen_is_gchar_(text), text, 2, "gtk_tool_item_set_tooltip_text", "gchar*"); gtk_tool_item_set_tooltip_text(Xen_to_C_GtkToolItem_(tool_item), (const gchar*)Xen_to_C_gchar_(text)); return(Xen_false); } static Xen gxg_gtk_tool_item_set_tooltip_markup(Xen tool_item, Xen markup) { #define H_gtk_tool_item_set_tooltip_markup "void gtk_tool_item_set_tooltip_markup(GtkToolItem* tool_item, \ gchar* markup)" Xen_check_type(Xen_is_GtkToolItem_(tool_item), tool_item, 1, "gtk_tool_item_set_tooltip_markup", "GtkToolItem*"); Xen_check_type(Xen_is_gchar_(markup), markup, 2, "gtk_tool_item_set_tooltip_markup", "gchar*"); gtk_tool_item_set_tooltip_markup(Xen_to_C_GtkToolItem_(tool_item), (const gchar*)Xen_to_C_gchar_(markup)); return(Xen_false); } static Xen gxg_gtk_tooltip_set_tip_area(Xen tooltip, Xen rect) { #define H_gtk_tooltip_set_tip_area "void gtk_tooltip_set_tip_area(GtkTooltip* tooltip, GdkRectangle* rect)" Xen_check_type(Xen_is_GtkTooltip_(tooltip), tooltip, 1, "gtk_tooltip_set_tip_area", "GtkTooltip*"); Xen_check_type(Xen_is_GdkRectangle_(rect), rect, 2, "gtk_tooltip_set_tip_area", "GdkRectangle*"); gtk_tooltip_set_tip_area(Xen_to_C_GtkTooltip_(tooltip), Xen_to_C_GdkRectangle_(rect)); return(Xen_false); } static Xen gxg_gtk_tree_view_set_tooltip_row(Xen tree_view, Xen tooltip, Xen path) { #define H_gtk_tree_view_set_tooltip_row "void gtk_tree_view_set_tooltip_row(GtkTreeView* tree_view, \ GtkTooltip* tooltip, GtkTreePath* path)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_set_tooltip_row", "GtkTreeView*"); Xen_check_type(Xen_is_GtkTooltip_(tooltip), tooltip, 2, "gtk_tree_view_set_tooltip_row", "GtkTooltip*"); Xen_check_type(Xen_is_GtkTreePath_(path), path, 3, "gtk_tree_view_set_tooltip_row", "GtkTreePath*"); gtk_tree_view_set_tooltip_row(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_GtkTooltip_(tooltip), Xen_to_C_GtkTreePath_(path)); return(Xen_false); } static Xen gxg_gtk_tree_view_set_tooltip_cell(Xen tree_view, Xen tooltip, Xen path, Xen column, Xen cell) { #define H_gtk_tree_view_set_tooltip_cell "void gtk_tree_view_set_tooltip_cell(GtkTreeView* tree_view, \ GtkTooltip* tooltip, GtkTreePath* path, GtkTreeViewColumn* column, GtkCellRenderer* cell)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_set_tooltip_cell", "GtkTreeView*"); Xen_check_type(Xen_is_GtkTooltip_(tooltip), tooltip, 2, "gtk_tree_view_set_tooltip_cell", "GtkTooltip*"); Xen_check_type(Xen_is_GtkTreePath_(path), path, 3, "gtk_tree_view_set_tooltip_cell", "GtkTreePath*"); Xen_check_type(Xen_is_GtkTreeViewColumn_(column), column, 4, "gtk_tree_view_set_tooltip_cell", "GtkTreeViewColumn*"); Xen_check_type(Xen_is_GtkCellRenderer_(cell), cell, 5, "gtk_tree_view_set_tooltip_cell", "GtkCellRenderer*"); gtk_tree_view_set_tooltip_cell(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_GtkTooltip_(tooltip), Xen_to_C_GtkTreePath_(path), Xen_to_C_GtkTreeViewColumn_(column), Xen_to_C_GtkCellRenderer_(cell)); return(Xen_false); } static Xen gxg_gtk_tree_view_get_tooltip_context(Xen tree_view, Xen ignore_x, Xen ignore_y, Xen keyboard_tip, Xen ignore_model, Xen ignore_path, Xen iter) { #define H_gtk_tree_view_get_tooltip_context "gboolean gtk_tree_view_get_tooltip_context(GtkTreeView* tree_view, \ gint* [x], gint* [y], gboolean keyboard_tip, GtkTreeModel** [model], GtkTreePath** [path], GtkTreeIter* iter)" gint ref_x; gint ref_y; GtkTreeModel* ref_model = NULL; GtkTreePath* ref_path = NULL; Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_get_tooltip_context", "GtkTreeView*"); Xen_check_type(Xen_is_gboolean(keyboard_tip), keyboard_tip, 4, "gtk_tree_view_get_tooltip_context", "gboolean"); Xen_check_type(Xen_is_GtkTreeIter_(iter) || Xen_is_false(iter), iter, 7, "gtk_tree_view_get_tooltip_context", "GtkTreeIter*"); { Xen result; result = C_to_Xen_gboolean(gtk_tree_view_get_tooltip_context(Xen_to_C_GtkTreeView_(tree_view), &ref_x, &ref_y, Xen_to_C_gboolean(keyboard_tip), &ref_model, &ref_path, Xen_to_C_GtkTreeIter_(iter))); return(Xen_list_5(result, C_to_Xen_gint(ref_x), C_to_Xen_gint(ref_y), C_to_Xen_GtkTreeModel_(ref_model), C_to_Xen_GtkTreePath_(ref_path))); } } static Xen gxg_gtk_tree_view_set_tooltip_column(Xen tree_view, Xen column) { #define H_gtk_tree_view_set_tooltip_column "void gtk_tree_view_set_tooltip_column(GtkTreeView* tree_view, \ gint column)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_set_tooltip_column", "GtkTreeView*"); Xen_check_type(Xen_is_gint(column), column, 2, "gtk_tree_view_set_tooltip_column", "gint"); gtk_tree_view_set_tooltip_column(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_gint(column)); return(Xen_false); } static Xen gxg_gtk_tree_view_get_tooltip_column(Xen tree_view ) { #define H_gtk_tree_view_get_tooltip_column "gint gtk_tree_view_get_tooltip_column(GtkTreeView* tree_view, \ )" Xen_check_type(Xen_is_GtkTreeView_(tree_view ), tree_view , 1, "gtk_tree_view_get_tooltip_column", "GtkTreeView*"); return(C_to_Xen_gint(gtk_tree_view_get_tooltip_column(Xen_to_C_GtkTreeView_(tree_view )))); } static Xen gxg_gtk_widget_set_has_tooltip(Xen widget, Xen has_tooltip) { #define H_gtk_widget_set_has_tooltip "void gtk_widget_set_has_tooltip(GtkWidget* widget, gboolean has_tooltip)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_set_has_tooltip", "GtkWidget*"); Xen_check_type(Xen_is_gboolean(has_tooltip), has_tooltip, 2, "gtk_widget_set_has_tooltip", "gboolean"); gtk_widget_set_has_tooltip(Xen_to_C_GtkWidget_(widget), Xen_to_C_gboolean(has_tooltip)); return(Xen_false); } static Xen gxg_gtk_widget_get_has_tooltip(Xen widget) { #define H_gtk_widget_get_has_tooltip "gboolean gtk_widget_get_has_tooltip(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_has_tooltip", "GtkWidget*"); return(C_to_Xen_gboolean(gtk_widget_get_has_tooltip(Xen_to_C_GtkWidget_(widget)))); } #if GTK_CHECK_VERSION(2, 14, 0) static Xen gxg_gtk_calendar_set_detail_func(Xen calendar, Xen func, Xen data, Xen destroy) { #define H_gtk_calendar_set_detail_func "void gtk_calendar_set_detail_func(GtkCalendar* calendar, GtkCalendarDetailFunc func, \ gpointer data, GDestroyNotify destroy)" Xen_check_type(Xen_is_GtkCalendar_(calendar), calendar, 1, "gtk_calendar_set_detail_func", "GtkCalendar*"); Xen_check_type(Xen_is_GtkCalendarDetailFunc(func), func, 2, "gtk_calendar_set_detail_func", "GtkCalendarDetailFunc"); Xen_check_type(Xen_is_gpointer(data), data, 3, "gtk_calendar_set_detail_func", "gpointer"); Xen_check_type(Xen_is_GDestroyNotify(destroy), destroy, 4, "gtk_calendar_set_detail_func", "GDestroyNotify"); gtk_calendar_set_detail_func(Xen_to_C_GtkCalendar_(calendar), Xen_to_C_GtkCalendarDetailFunc(func), Xen_to_C_gpointer(data), Xen_to_C_GDestroyNotify(destroy)); return(Xen_false); } static Xen gxg_gtk_calendar_set_detail_width_chars(Xen calendar, Xen chars) { #define H_gtk_calendar_set_detail_width_chars "void gtk_calendar_set_detail_width_chars(GtkCalendar* calendar, \ gint chars)" Xen_check_type(Xen_is_GtkCalendar_(calendar), calendar, 1, "gtk_calendar_set_detail_width_chars", "GtkCalendar*"); Xen_check_type(Xen_is_gint(chars), chars, 2, "gtk_calendar_set_detail_width_chars", "gint"); gtk_calendar_set_detail_width_chars(Xen_to_C_GtkCalendar_(calendar), Xen_to_C_gint(chars)); return(Xen_false); } static Xen gxg_gtk_calendar_set_detail_height_rows(Xen calendar, Xen rows) { #define H_gtk_calendar_set_detail_height_rows "void gtk_calendar_set_detail_height_rows(GtkCalendar* calendar, \ gint rows)" Xen_check_type(Xen_is_GtkCalendar_(calendar), calendar, 1, "gtk_calendar_set_detail_height_rows", "GtkCalendar*"); Xen_check_type(Xen_is_gint(rows), rows, 2, "gtk_calendar_set_detail_height_rows", "gint"); gtk_calendar_set_detail_height_rows(Xen_to_C_GtkCalendar_(calendar), Xen_to_C_gint(rows)); return(Xen_false); } static Xen gxg_gtk_calendar_get_detail_width_chars(Xen calendar) { #define H_gtk_calendar_get_detail_width_chars "gint gtk_calendar_get_detail_width_chars(GtkCalendar* calendar)" Xen_check_type(Xen_is_GtkCalendar_(calendar), calendar, 1, "gtk_calendar_get_detail_width_chars", "GtkCalendar*"); return(C_to_Xen_gint(gtk_calendar_get_detail_width_chars(Xen_to_C_GtkCalendar_(calendar)))); } static Xen gxg_gtk_calendar_get_detail_height_rows(Xen calendar) { #define H_gtk_calendar_get_detail_height_rows "gint gtk_calendar_get_detail_height_rows(GtkCalendar* calendar)" Xen_check_type(Xen_is_GtkCalendar_(calendar), calendar, 1, "gtk_calendar_get_detail_height_rows", "GtkCalendar*"); return(C_to_Xen_gint(gtk_calendar_get_detail_height_rows(Xen_to_C_GtkCalendar_(calendar)))); } static Xen gxg_gdk_screen_get_monitor_width_mm(Xen screen, Xen monitor_num) { #define H_gdk_screen_get_monitor_width_mm "gint gdk_screen_get_monitor_width_mm(GdkScreen* screen, \ gint monitor_num)" Xen_check_type(Xen_is_GdkScreen_(screen), screen, 1, "gdk_screen_get_monitor_width_mm", "GdkScreen*"); Xen_check_type(Xen_is_gint(monitor_num), monitor_num, 2, "gdk_screen_get_monitor_width_mm", "gint"); return(C_to_Xen_gint(gdk_screen_get_monitor_width_mm(Xen_to_C_GdkScreen_(screen), Xen_to_C_gint(monitor_num)))); } static Xen gxg_gdk_screen_get_monitor_height_mm(Xen screen, Xen monitor_num) { #define H_gdk_screen_get_monitor_height_mm "gint gdk_screen_get_monitor_height_mm(GdkScreen* screen, \ gint monitor_num)" Xen_check_type(Xen_is_GdkScreen_(screen), screen, 1, "gdk_screen_get_monitor_height_mm", "GdkScreen*"); Xen_check_type(Xen_is_gint(monitor_num), monitor_num, 2, "gdk_screen_get_monitor_height_mm", "gint"); return(C_to_Xen_gint(gdk_screen_get_monitor_height_mm(Xen_to_C_GdkScreen_(screen), Xen_to_C_gint(monitor_num)))); } static Xen gxg_gdk_screen_get_monitor_plug_name(Xen screen, Xen monitor_num) { #define H_gdk_screen_get_monitor_plug_name "gchar* gdk_screen_get_monitor_plug_name(GdkScreen* screen, \ gint monitor_num)" Xen_check_type(Xen_is_GdkScreen_(screen), screen, 1, "gdk_screen_get_monitor_plug_name", "GdkScreen*"); Xen_check_type(Xen_is_gint(monitor_num), monitor_num, 2, "gdk_screen_get_monitor_plug_name", "gint"); return(C_to_Xen_gchar_(gdk_screen_get_monitor_plug_name(Xen_to_C_GdkScreen_(screen), Xen_to_C_gint(monitor_num)))); } static Xen gxg_gtk_accel_group_get_is_locked(Xen accel_group) { #define H_gtk_accel_group_get_is_locked "gboolean gtk_accel_group_get_is_locked(GtkAccelGroup* accel_group)" Xen_check_type(Xen_is_GtkAccelGroup_(accel_group), accel_group, 1, "gtk_accel_group_get_is_locked", "GtkAccelGroup*"); return(C_to_Xen_gboolean(gtk_accel_group_get_is_locked(Xen_to_C_GtkAccelGroup_(accel_group)))); } static Xen gxg_gtk_container_get_focus_child(Xen container) { #define H_gtk_container_get_focus_child "GtkWidget* gtk_container_get_focus_child(GtkContainer* container)" Xen_check_type(Xen_is_GtkContainer_(container), container, 1, "gtk_container_get_focus_child", "GtkContainer*"); return(C_to_Xen_GtkWidget_(gtk_container_get_focus_child(Xen_to_C_GtkContainer_(container)))); } static Xen gxg_gtk_dialog_get_content_area(Xen dialog) { #define H_gtk_dialog_get_content_area "GtkWidget* gtk_dialog_get_content_area(GtkDialog* dialog)" Xen_check_type(Xen_is_GtkDialog_(dialog), dialog, 1, "gtk_dialog_get_content_area", "GtkDialog*"); return(C_to_Xen_GtkWidget_(gtk_dialog_get_content_area(Xen_to_C_GtkDialog_(dialog)))); } static Xen gxg_gtk_entry_set_overwrite_mode(Xen entry, Xen overwrite) { #define H_gtk_entry_set_overwrite_mode "void gtk_entry_set_overwrite_mode(GtkEntry* entry, gboolean overwrite)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_set_overwrite_mode", "GtkEntry*"); Xen_check_type(Xen_is_gboolean(overwrite), overwrite, 2, "gtk_entry_set_overwrite_mode", "gboolean"); gtk_entry_set_overwrite_mode(Xen_to_C_GtkEntry_(entry), Xen_to_C_gboolean(overwrite)); return(Xen_false); } static Xen gxg_gtk_entry_get_overwrite_mode(Xen entry) { #define H_gtk_entry_get_overwrite_mode "gboolean gtk_entry_get_overwrite_mode(GtkEntry* entry)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_get_overwrite_mode", "GtkEntry*"); return(C_to_Xen_gboolean(gtk_entry_get_overwrite_mode(Xen_to_C_GtkEntry_(entry)))); } static Xen gxg_gtk_entry_get_text_length(Xen entry) { #define H_gtk_entry_get_text_length "guint16 gtk_entry_get_text_length(GtkEntry* entry)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_get_text_length", "GtkEntry*"); return(C_to_Xen_guint16(gtk_entry_get_text_length(Xen_to_C_GtkEntry_(entry)))); } static Xen gxg_gtk_layout_get_bin_window(Xen layout) { #define H_gtk_layout_get_bin_window "GdkWindow* gtk_layout_get_bin_window(GtkLayout* layout)" Xen_check_type(Xen_is_GtkLayout_(layout), layout, 1, "gtk_layout_get_bin_window", "GtkLayout*"); return(C_to_Xen_GdkWindow_(gtk_layout_get_bin_window(Xen_to_C_GtkLayout_(layout)))); } static Xen gxg_gtk_menu_get_accel_path(Xen menu) { #define H_gtk_menu_get_accel_path "gchar* gtk_menu_get_accel_path(GtkMenu* menu)" Xen_check_type(Xen_is_GtkMenu_(menu), menu, 1, "gtk_menu_get_accel_path", "GtkMenu*"); return(C_to_Xen_gchar_(gtk_menu_get_accel_path(Xen_to_C_GtkMenu_(menu)))); } static Xen gxg_gtk_menu_get_monitor(Xen menu) { #define H_gtk_menu_get_monitor "gint gtk_menu_get_monitor(GtkMenu* menu)" Xen_check_type(Xen_is_GtkMenu_(menu), menu, 1, "gtk_menu_get_monitor", "GtkMenu*"); return(C_to_Xen_gint(gtk_menu_get_monitor(Xen_to_C_GtkMenu_(menu)))); } static Xen gxg_gtk_menu_item_get_accel_path(Xen menu_item) { #define H_gtk_menu_item_get_accel_path "gchar* gtk_menu_item_get_accel_path(GtkMenuItem* menu_item)" Xen_check_type(Xen_is_GtkMenuItem_(menu_item), menu_item, 1, "gtk_menu_item_get_accel_path", "GtkMenuItem*"); return(C_to_Xen_gchar_(gtk_menu_item_get_accel_path(Xen_to_C_GtkMenuItem_(menu_item)))); } static Xen gxg_gtk_scale_button_get_plus_button(Xen button) { #define H_gtk_scale_button_get_plus_button "GtkWidget* gtk_scale_button_get_plus_button(GtkScaleButton* button)" Xen_check_type(Xen_is_GtkScaleButton_(button), button, 1, "gtk_scale_button_get_plus_button", "GtkScaleButton*"); return(C_to_Xen_GtkWidget_(gtk_scale_button_get_plus_button(Xen_to_C_GtkScaleButton_(button)))); } static Xen gxg_gtk_scale_button_get_minus_button(Xen button) { #define H_gtk_scale_button_get_minus_button "GtkWidget* gtk_scale_button_get_minus_button(GtkScaleButton* button)" Xen_check_type(Xen_is_GtkScaleButton_(button), button, 1, "gtk_scale_button_get_minus_button", "GtkScaleButton*"); return(C_to_Xen_GtkWidget_(gtk_scale_button_get_minus_button(Xen_to_C_GtkScaleButton_(button)))); } static Xen gxg_gtk_scale_button_get_popup(Xen button) { #define H_gtk_scale_button_get_popup "GtkWidget* gtk_scale_button_get_popup(GtkScaleButton* button)" Xen_check_type(Xen_is_GtkScaleButton_(button), button, 1, "gtk_scale_button_get_popup", "GtkScaleButton*"); return(C_to_Xen_GtkWidget_(gtk_scale_button_get_popup(Xen_to_C_GtkScaleButton_(button)))); } static Xen gxg_gtk_selection_data_get_target(Xen selection_data) { #define H_gtk_selection_data_get_target "GdkAtom gtk_selection_data_get_target(GtkSelectionData* selection_data)" Xen_check_type(Xen_is_GtkSelectionData_(selection_data), selection_data, 1, "gtk_selection_data_get_target", "GtkSelectionData*"); return(C_to_Xen_GdkAtom(gtk_selection_data_get_target(Xen_to_C_GtkSelectionData_(selection_data)))); } static Xen gxg_gtk_selection_data_get_data_type(Xen selection_data) { #define H_gtk_selection_data_get_data_type "GdkAtom gtk_selection_data_get_data_type(GtkSelectionData* selection_data)" Xen_check_type(Xen_is_GtkSelectionData_(selection_data), selection_data, 1, "gtk_selection_data_get_data_type", "GtkSelectionData*"); return(C_to_Xen_GdkAtom(gtk_selection_data_get_data_type(Xen_to_C_GtkSelectionData_(selection_data)))); } static Xen gxg_gtk_selection_data_get_format(Xen selection_data) { #define H_gtk_selection_data_get_format "gint gtk_selection_data_get_format(GtkSelectionData* selection_data)" Xen_check_type(Xen_is_GtkSelectionData_(selection_data), selection_data, 1, "gtk_selection_data_get_format", "GtkSelectionData*"); return(C_to_Xen_gint(gtk_selection_data_get_format(Xen_to_C_GtkSelectionData_(selection_data)))); } static Xen gxg_gtk_selection_data_get_display(Xen selection_data) { #define H_gtk_selection_data_get_display "GdkDisplay* gtk_selection_data_get_display(GtkSelectionData* selection_data)" Xen_check_type(Xen_is_GtkSelectionData_(selection_data), selection_data, 1, "gtk_selection_data_get_display", "GtkSelectionData*"); return(C_to_Xen_GdkDisplay_(gtk_selection_data_get_display(Xen_to_C_GtkSelectionData_(selection_data)))); } static Xen gxg_gtk_widget_get_window(Xen widget) { #define H_gtk_widget_get_window "GdkWindow* gtk_widget_get_window(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_window", "GtkWidget*"); return(C_to_Xen_GdkWindow_(gtk_widget_get_window(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_accel_group_get_modifier_mask(Xen accel_group) { #define H_gtk_accel_group_get_modifier_mask "GdkModifierType gtk_accel_group_get_modifier_mask(GtkAccelGroup* accel_group)" Xen_check_type(Xen_is_GtkAccelGroup_(accel_group), accel_group, 1, "gtk_accel_group_get_modifier_mask", "GtkAccelGroup*"); return(C_to_Xen_GdkModifierType(gtk_accel_group_get_modifier_mask(Xen_to_C_GtkAccelGroup_(accel_group)))); } static Xen gxg_gdk_threads_add_timeout_seconds_full(Xen priority, Xen interval, Xen function, Xen func_info, Xen notify) { #define H_gdk_threads_add_timeout_seconds_full "guint gdk_threads_add_timeout_seconds_full(gint priority, \ guint interval, GSourceFunc function, lambda_data func_info, GDestroyNotify notify)" Xen_check_type(Xen_is_gint(priority), priority, 1, "gdk_threads_add_timeout_seconds_full", "gint"); Xen_check_type(Xen_is_guint(interval), interval, 2, "gdk_threads_add_timeout_seconds_full", "guint"); Xen_check_type(Xen_is_GSourceFunc(function), function, 3, "gdk_threads_add_timeout_seconds_full", "GSourceFunc"); Xen_check_type(Xen_is_lambda_data(func_info), func_info, 4, "gdk_threads_add_timeout_seconds_full", "lambda_data"); Xen_check_type(Xen_is_GDestroyNotify(notify), notify, 5, "gdk_threads_add_timeout_seconds_full", "GDestroyNotify"); { Xen result; int loc; Xen gxg_ptr = Xen_list_5(Xen_false, func_info, Xen_false, Xen_false, Xen_false); loc = xm_protect(gxg_ptr); Xen_list_set(gxg_ptr, 2, C_int_to_Xen_integer(loc)); result = C_to_Xen_guint(gdk_threads_add_timeout_seconds_full(Xen_to_C_gint(priority), Xen_to_C_guint(interval), Xen_to_C_GSourceFunc(function), Xen_to_C_lambda_data(func_info), Xen_to_C_GDestroyNotify(notify))); Xen_list_set(gxg_ptr, 2, Xen_list_3(xg_idler_symbol, result, C_int_to_Xen_integer(loc))); return(result); } } static Xen gxg_gdk_threads_add_timeout_seconds(Xen interval, Xen function, Xen func_info) { #define H_gdk_threads_add_timeout_seconds "guint gdk_threads_add_timeout_seconds(guint interval, GSourceFunc function, \ lambda_data func_info)" Xen_check_type(Xen_is_guint(interval), interval, 1, "gdk_threads_add_timeout_seconds", "guint"); Xen_check_type(Xen_is_GSourceFunc(function), function, 2, "gdk_threads_add_timeout_seconds", "GSourceFunc"); if (!Xen_is_bound(func_info)) func_info = Xen_false; else Xen_check_type(Xen_is_lambda_data(func_info), func_info, 3, "gdk_threads_add_timeout_seconds", "lambda_data"); { Xen result; int loc; Xen gxg_ptr = Xen_list_5(Xen_false, func_info, Xen_false, Xen_false, Xen_false); loc = xm_protect(gxg_ptr); Xen_list_set(gxg_ptr, 2, C_int_to_Xen_integer(loc)); result = C_to_Xen_guint(gdk_threads_add_timeout_seconds(Xen_to_C_guint(interval), Xen_to_C_GSourceFunc(function), Xen_to_C_lambda_data(func_info))); Xen_list_set(gxg_ptr, 2, Xen_list_3(xg_idler_symbol, result, C_int_to_Xen_integer(loc))); return(result); } } static Xen gxg_gtk_adjustment_get_lower(Xen adjustment) { #define H_gtk_adjustment_get_lower "gdouble gtk_adjustment_get_lower(GtkAdjustment* adjustment)" Xen_check_type(Xen_is_GtkAdjustment_(adjustment), adjustment, 1, "gtk_adjustment_get_lower", "GtkAdjustment*"); return(C_to_Xen_gdouble(gtk_adjustment_get_lower(Xen_to_C_GtkAdjustment_(adjustment)))); } static Xen gxg_gtk_adjustment_set_lower(Xen adjustment, Xen lower) { #define H_gtk_adjustment_set_lower "void gtk_adjustment_set_lower(GtkAdjustment* adjustment, gdouble lower)" Xen_check_type(Xen_is_GtkAdjustment_(adjustment), adjustment, 1, "gtk_adjustment_set_lower", "GtkAdjustment*"); Xen_check_type(Xen_is_gdouble(lower), lower, 2, "gtk_adjustment_set_lower", "gdouble"); gtk_adjustment_set_lower(Xen_to_C_GtkAdjustment_(adjustment), Xen_to_C_gdouble(lower)); return(Xen_false); } static Xen gxg_gtk_adjustment_get_upper(Xen adjustment) { #define H_gtk_adjustment_get_upper "gdouble gtk_adjustment_get_upper(GtkAdjustment* adjustment)" Xen_check_type(Xen_is_GtkAdjustment_(adjustment), adjustment, 1, "gtk_adjustment_get_upper", "GtkAdjustment*"); return(C_to_Xen_gdouble(gtk_adjustment_get_upper(Xen_to_C_GtkAdjustment_(adjustment)))); } static Xen gxg_gtk_adjustment_set_upper(Xen adjustment, Xen upper) { #define H_gtk_adjustment_set_upper "void gtk_adjustment_set_upper(GtkAdjustment* adjustment, gdouble upper)" Xen_check_type(Xen_is_GtkAdjustment_(adjustment), adjustment, 1, "gtk_adjustment_set_upper", "GtkAdjustment*"); Xen_check_type(Xen_is_gdouble(upper), upper, 2, "gtk_adjustment_set_upper", "gdouble"); gtk_adjustment_set_upper(Xen_to_C_GtkAdjustment_(adjustment), Xen_to_C_gdouble(upper)); return(Xen_false); } static Xen gxg_gtk_adjustment_get_step_increment(Xen adjustment) { #define H_gtk_adjustment_get_step_increment "gdouble gtk_adjustment_get_step_increment(GtkAdjustment* adjustment)" Xen_check_type(Xen_is_GtkAdjustment_(adjustment), adjustment, 1, "gtk_adjustment_get_step_increment", "GtkAdjustment*"); return(C_to_Xen_gdouble(gtk_adjustment_get_step_increment(Xen_to_C_GtkAdjustment_(adjustment)))); } static Xen gxg_gtk_adjustment_set_step_increment(Xen adjustment, Xen step_increment) { #define H_gtk_adjustment_set_step_increment "void gtk_adjustment_set_step_increment(GtkAdjustment* adjustment, \ gdouble step_increment)" Xen_check_type(Xen_is_GtkAdjustment_(adjustment), adjustment, 1, "gtk_adjustment_set_step_increment", "GtkAdjustment*"); Xen_check_type(Xen_is_gdouble(step_increment), step_increment, 2, "gtk_adjustment_set_step_increment", "gdouble"); gtk_adjustment_set_step_increment(Xen_to_C_GtkAdjustment_(adjustment), Xen_to_C_gdouble(step_increment)); return(Xen_false); } static Xen gxg_gtk_adjustment_get_page_increment(Xen adjustment) { #define H_gtk_adjustment_get_page_increment "gdouble gtk_adjustment_get_page_increment(GtkAdjustment* adjustment)" Xen_check_type(Xen_is_GtkAdjustment_(adjustment), adjustment, 1, "gtk_adjustment_get_page_increment", "GtkAdjustment*"); return(C_to_Xen_gdouble(gtk_adjustment_get_page_increment(Xen_to_C_GtkAdjustment_(adjustment)))); } static Xen gxg_gtk_adjustment_set_page_increment(Xen adjustment, Xen page_increment) { #define H_gtk_adjustment_set_page_increment "void gtk_adjustment_set_page_increment(GtkAdjustment* adjustment, \ gdouble page_increment)" Xen_check_type(Xen_is_GtkAdjustment_(adjustment), adjustment, 1, "gtk_adjustment_set_page_increment", "GtkAdjustment*"); Xen_check_type(Xen_is_gdouble(page_increment), page_increment, 2, "gtk_adjustment_set_page_increment", "gdouble"); gtk_adjustment_set_page_increment(Xen_to_C_GtkAdjustment_(adjustment), Xen_to_C_gdouble(page_increment)); return(Xen_false); } static Xen gxg_gtk_adjustment_get_page_size(Xen adjustment) { #define H_gtk_adjustment_get_page_size "gdouble gtk_adjustment_get_page_size(GtkAdjustment* adjustment)" Xen_check_type(Xen_is_GtkAdjustment_(adjustment), adjustment, 1, "gtk_adjustment_get_page_size", "GtkAdjustment*"); return(C_to_Xen_gdouble(gtk_adjustment_get_page_size(Xen_to_C_GtkAdjustment_(adjustment)))); } static Xen gxg_gtk_adjustment_set_page_size(Xen adjustment, Xen page_size) { #define H_gtk_adjustment_set_page_size "void gtk_adjustment_set_page_size(GtkAdjustment* adjustment, \ gdouble page_size)" Xen_check_type(Xen_is_GtkAdjustment_(adjustment), adjustment, 1, "gtk_adjustment_set_page_size", "GtkAdjustment*"); Xen_check_type(Xen_is_gdouble(page_size), page_size, 2, "gtk_adjustment_set_page_size", "gdouble"); gtk_adjustment_set_page_size(Xen_to_C_GtkAdjustment_(adjustment), Xen_to_C_gdouble(page_size)); return(Xen_false); } static Xen gxg_gtk_adjustment_configure(Xen adjustment, Xen value, Xen lower, Xen upper, Xen step_increment, Xen page_increment, Xen page_size) { #define H_gtk_adjustment_configure "void gtk_adjustment_configure(GtkAdjustment* adjustment, gdouble value, \ gdouble lower, gdouble upper, gdouble step_increment, gdouble page_increment, gdouble page_size)" Xen_check_type(Xen_is_GtkAdjustment_(adjustment), adjustment, 1, "gtk_adjustment_configure", "GtkAdjustment*"); Xen_check_type(Xen_is_gdouble(value), value, 2, "gtk_adjustment_configure", "gdouble"); Xen_check_type(Xen_is_gdouble(lower), lower, 3, "gtk_adjustment_configure", "gdouble"); Xen_check_type(Xen_is_gdouble(upper), upper, 4, "gtk_adjustment_configure", "gdouble"); Xen_check_type(Xen_is_gdouble(step_increment), step_increment, 5, "gtk_adjustment_configure", "gdouble"); Xen_check_type(Xen_is_gdouble(page_increment), page_increment, 6, "gtk_adjustment_configure", "gdouble"); Xen_check_type(Xen_is_gdouble(page_size), page_size, 7, "gtk_adjustment_configure", "gdouble"); gtk_adjustment_configure(Xen_to_C_GtkAdjustment_(adjustment), Xen_to_C_gdouble(value), Xen_to_C_gdouble(lower), Xen_to_C_gdouble(upper), Xen_to_C_gdouble(step_increment), Xen_to_C_gdouble(page_increment), Xen_to_C_gdouble(page_size)); return(Xen_false); } static Xen gxg_gtk_combo_box_set_button_sensitivity(Xen combo_box, Xen sensitivity) { #define H_gtk_combo_box_set_button_sensitivity "void gtk_combo_box_set_button_sensitivity(GtkComboBox* combo_box, \ GtkSensitivityType sensitivity)" Xen_check_type(Xen_is_GtkComboBox_(combo_box), combo_box, 1, "gtk_combo_box_set_button_sensitivity", "GtkComboBox*"); Xen_check_type(Xen_is_GtkSensitivityType(sensitivity), sensitivity, 2, "gtk_combo_box_set_button_sensitivity", "GtkSensitivityType"); gtk_combo_box_set_button_sensitivity(Xen_to_C_GtkComboBox_(combo_box), Xen_to_C_GtkSensitivityType(sensitivity)); return(Xen_false); } static Xen gxg_gtk_combo_box_get_button_sensitivity(Xen combo_box) { #define H_gtk_combo_box_get_button_sensitivity "GtkSensitivityType gtk_combo_box_get_button_sensitivity(GtkComboBox* combo_box)" Xen_check_type(Xen_is_GtkComboBox_(combo_box), combo_box, 1, "gtk_combo_box_get_button_sensitivity", "GtkComboBox*"); return(C_to_Xen_GtkSensitivityType(gtk_combo_box_get_button_sensitivity(Xen_to_C_GtkComboBox_(combo_box)))); } static Xen gxg_gtk_file_chooser_get_file(Xen chooser) { #define H_gtk_file_chooser_get_file "GFile* gtk_file_chooser_get_file(GtkFileChooser* chooser)" Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_get_file", "GtkFileChooser*"); return(C_to_Xen_GFile_(gtk_file_chooser_get_file(Xen_to_C_GtkFileChooser_(chooser)))); } static Xen gxg_gtk_file_chooser_set_file(Xen chooser, Xen file, Xen ignore_error) { #define H_gtk_file_chooser_set_file "gboolean gtk_file_chooser_set_file(GtkFileChooser* chooser, GFile* file, \ GError** [error])" GError* ref_error = NULL; Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_set_file", "GtkFileChooser*"); Xen_check_type(Xen_is_GFile_(file), file, 2, "gtk_file_chooser_set_file", "GFile*"); { Xen result; result = C_to_Xen_gboolean(gtk_file_chooser_set_file(Xen_to_C_GtkFileChooser_(chooser), Xen_to_C_GFile_(file), &ref_error)); return(Xen_list_2(result, C_to_Xen_GError_(ref_error))); } } static Xen gxg_gtk_file_chooser_select_file(Xen chooser, Xen file, Xen ignore_error) { #define H_gtk_file_chooser_select_file "gboolean gtk_file_chooser_select_file(GtkFileChooser* chooser, \ GFile* file, GError** [error])" GError* ref_error = NULL; Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_select_file", "GtkFileChooser*"); Xen_check_type(Xen_is_GFile_(file), file, 2, "gtk_file_chooser_select_file", "GFile*"); { Xen result; result = C_to_Xen_gboolean(gtk_file_chooser_select_file(Xen_to_C_GtkFileChooser_(chooser), Xen_to_C_GFile_(file), &ref_error)); return(Xen_list_2(result, C_to_Xen_GError_(ref_error))); } } static Xen gxg_gtk_file_chooser_unselect_file(Xen chooser, Xen file) { #define H_gtk_file_chooser_unselect_file "void gtk_file_chooser_unselect_file(GtkFileChooser* chooser, \ GFile* file)" Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_unselect_file", "GtkFileChooser*"); Xen_check_type(Xen_is_GFile_(file), file, 2, "gtk_file_chooser_unselect_file", "GFile*"); gtk_file_chooser_unselect_file(Xen_to_C_GtkFileChooser_(chooser), Xen_to_C_GFile_(file)); return(Xen_false); } static Xen gxg_gtk_file_chooser_get_files(Xen chooser) { #define H_gtk_file_chooser_get_files "GSList* gtk_file_chooser_get_files(GtkFileChooser* chooser)" Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_get_files", "GtkFileChooser*"); return(C_to_Xen_GSList_(gtk_file_chooser_get_files(Xen_to_C_GtkFileChooser_(chooser)))); } static Xen gxg_gtk_file_chooser_set_current_folder_file(Xen chooser, Xen file, Xen ignore_error) { #define H_gtk_file_chooser_set_current_folder_file "gboolean gtk_file_chooser_set_current_folder_file(GtkFileChooser* chooser, \ GFile* file, GError** [error])" GError* ref_error = NULL; Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_set_current_folder_file", "GtkFileChooser*"); Xen_check_type(Xen_is_GFile_(file), file, 2, "gtk_file_chooser_set_current_folder_file", "GFile*"); { Xen result; result = C_to_Xen_gboolean(gtk_file_chooser_set_current_folder_file(Xen_to_C_GtkFileChooser_(chooser), Xen_to_C_GFile_(file), &ref_error)); return(Xen_list_2(result, C_to_Xen_GError_(ref_error))); } } static Xen gxg_gtk_file_chooser_get_current_folder_file(Xen chooser) { #define H_gtk_file_chooser_get_current_folder_file "GFile* gtk_file_chooser_get_current_folder_file(GtkFileChooser* chooser)" Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_get_current_folder_file", "GtkFileChooser*"); return(C_to_Xen_GFile_(gtk_file_chooser_get_current_folder_file(Xen_to_C_GtkFileChooser_(chooser)))); } static Xen gxg_gtk_file_chooser_get_preview_file(Xen chooser) { #define H_gtk_file_chooser_get_preview_file "GFile* gtk_file_chooser_get_preview_file(GtkFileChooser* chooser)" Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_get_preview_file", "GtkFileChooser*"); return(C_to_Xen_GFile_(gtk_file_chooser_get_preview_file(Xen_to_C_GtkFileChooser_(chooser)))); } static Xen gxg_gtk_window_get_default_widget(Xen window) { #define H_gtk_window_get_default_widget "GtkWidget* gtk_window_get_default_widget(GtkWindow* window)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_get_default_widget", "GtkWindow*"); return(C_to_Xen_GtkWidget_(gtk_window_get_default_widget(Xen_to_C_GtkWindow_(window)))); } #endif #if GTK_CHECK_VERSION(2, 16, 0) static Xen gxg_gtk_link_button_get_visited(Xen link_button) { #define H_gtk_link_button_get_visited "gboolean gtk_link_button_get_visited(GtkLinkButton* link_button)" Xen_check_type(Xen_is_GtkLinkButton_(link_button), link_button, 1, "gtk_link_button_get_visited", "GtkLinkButton*"); return(C_to_Xen_gboolean(gtk_link_button_get_visited(Xen_to_C_GtkLinkButton_(link_button)))); } static Xen gxg_gtk_link_button_set_visited(Xen link_button, Xen visited) { #define H_gtk_link_button_set_visited "void gtk_link_button_set_visited(GtkLinkButton* link_button, \ bool visited)" Xen_check_type(Xen_is_GtkLinkButton_(link_button), link_button, 1, "gtk_link_button_set_visited", "GtkLinkButton*"); Xen_check_type(Xen_is_bool(visited), visited, 2, "gtk_link_button_set_visited", "bool"); gtk_link_button_set_visited(Xen_to_C_GtkLinkButton_(link_button), Xen_to_C_bool(visited)); return(Xen_false); } static Xen gxg_gdk_keymap_get_caps_lock_state(Xen keymap) { #define H_gdk_keymap_get_caps_lock_state "gboolean gdk_keymap_get_caps_lock_state(GdkKeymap* keymap)" Xen_check_type(Xen_is_GdkKeymap_(keymap), keymap, 1, "gdk_keymap_get_caps_lock_state", "GdkKeymap*"); return(C_to_Xen_gboolean(gdk_keymap_get_caps_lock_state(Xen_to_C_GdkKeymap_(keymap)))); } static Xen gxg_gtk_cell_view_get_model(Xen cell_view) { #define H_gtk_cell_view_get_model "GtkTreeModel* gtk_cell_view_get_model(GtkCellView* cell_view)" Xen_check_type(Xen_is_GtkCellView_(cell_view), cell_view, 1, "gtk_cell_view_get_model", "GtkCellView*"); return(C_to_Xen_GtkTreeModel_(gtk_cell_view_get_model(Xen_to_C_GtkCellView_(cell_view)))); } static Xen gxg_gtk_entry_unset_invisible_char(Xen entry) { #define H_gtk_entry_unset_invisible_char "void gtk_entry_unset_invisible_char(GtkEntry* entry)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_unset_invisible_char", "GtkEntry*"); gtk_entry_unset_invisible_char(Xen_to_C_GtkEntry_(entry)); return(Xen_false); } static Xen gxg_gtk_entry_set_progress_fraction(Xen entry, Xen fraction) { #define H_gtk_entry_set_progress_fraction "void gtk_entry_set_progress_fraction(GtkEntry* entry, gdouble fraction)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_set_progress_fraction", "GtkEntry*"); Xen_check_type(Xen_is_gdouble(fraction), fraction, 2, "gtk_entry_set_progress_fraction", "gdouble"); gtk_entry_set_progress_fraction(Xen_to_C_GtkEntry_(entry), Xen_to_C_gdouble(fraction)); return(Xen_false); } static Xen gxg_gtk_entry_get_progress_fraction(Xen entry) { #define H_gtk_entry_get_progress_fraction "gdouble gtk_entry_get_progress_fraction(GtkEntry* entry)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_get_progress_fraction", "GtkEntry*"); return(C_to_Xen_gdouble(gtk_entry_get_progress_fraction(Xen_to_C_GtkEntry_(entry)))); } static Xen gxg_gtk_entry_set_progress_pulse_step(Xen entry, Xen fraction) { #define H_gtk_entry_set_progress_pulse_step "void gtk_entry_set_progress_pulse_step(GtkEntry* entry, \ gdouble fraction)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_set_progress_pulse_step", "GtkEntry*"); Xen_check_type(Xen_is_gdouble(fraction), fraction, 2, "gtk_entry_set_progress_pulse_step", "gdouble"); gtk_entry_set_progress_pulse_step(Xen_to_C_GtkEntry_(entry), Xen_to_C_gdouble(fraction)); return(Xen_false); } static Xen gxg_gtk_entry_get_progress_pulse_step(Xen entry) { #define H_gtk_entry_get_progress_pulse_step "gdouble gtk_entry_get_progress_pulse_step(GtkEntry* entry)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_get_progress_pulse_step", "GtkEntry*"); return(C_to_Xen_gdouble(gtk_entry_get_progress_pulse_step(Xen_to_C_GtkEntry_(entry)))); } static Xen gxg_gtk_entry_progress_pulse(Xen entry) { #define H_gtk_entry_progress_pulse "void gtk_entry_progress_pulse(GtkEntry* entry)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_progress_pulse", "GtkEntry*"); gtk_entry_progress_pulse(Xen_to_C_GtkEntry_(entry)); return(Xen_false); } static Xen gxg_gtk_entry_set_icon_from_pixbuf(Xen entry, Xen icon_pos, Xen pixbuf) { #define H_gtk_entry_set_icon_from_pixbuf "void gtk_entry_set_icon_from_pixbuf(GtkEntry* entry, GtkEntryIconPosition icon_pos, \ GdkPixbuf* pixbuf)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_set_icon_from_pixbuf", "GtkEntry*"); Xen_check_type(Xen_is_GtkEntryIconPosition(icon_pos), icon_pos, 2, "gtk_entry_set_icon_from_pixbuf", "GtkEntryIconPosition"); Xen_check_type(Xen_is_GdkPixbuf_(pixbuf), pixbuf, 3, "gtk_entry_set_icon_from_pixbuf", "GdkPixbuf*"); gtk_entry_set_icon_from_pixbuf(Xen_to_C_GtkEntry_(entry), Xen_to_C_GtkEntryIconPosition(icon_pos), Xen_to_C_GdkPixbuf_(pixbuf)); return(Xen_false); } static Xen gxg_gtk_entry_set_icon_from_icon_name(Xen entry, Xen icon_pos, Xen icon_name) { #define H_gtk_entry_set_icon_from_icon_name "void gtk_entry_set_icon_from_icon_name(GtkEntry* entry, \ GtkEntryIconPosition icon_pos, gchar* icon_name)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_set_icon_from_icon_name", "GtkEntry*"); Xen_check_type(Xen_is_GtkEntryIconPosition(icon_pos), icon_pos, 2, "gtk_entry_set_icon_from_icon_name", "GtkEntryIconPosition"); Xen_check_type(Xen_is_gchar_(icon_name), icon_name, 3, "gtk_entry_set_icon_from_icon_name", "gchar*"); gtk_entry_set_icon_from_icon_name(Xen_to_C_GtkEntry_(entry), Xen_to_C_GtkEntryIconPosition(icon_pos), Xen_to_C_gchar_(icon_name)); return(Xen_false); } static Xen gxg_gtk_entry_set_icon_from_gicon(Xen entry, Xen icon_pos, Xen icon) { #define H_gtk_entry_set_icon_from_gicon "void gtk_entry_set_icon_from_gicon(GtkEntry* entry, GtkEntryIconPosition icon_pos, \ GIcon* icon)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_set_icon_from_gicon", "GtkEntry*"); Xen_check_type(Xen_is_GtkEntryIconPosition(icon_pos), icon_pos, 2, "gtk_entry_set_icon_from_gicon", "GtkEntryIconPosition"); Xen_check_type(Xen_is_GIcon_(icon), icon, 3, "gtk_entry_set_icon_from_gicon", "GIcon*"); gtk_entry_set_icon_from_gicon(Xen_to_C_GtkEntry_(entry), Xen_to_C_GtkEntryIconPosition(icon_pos), Xen_to_C_GIcon_(icon)); return(Xen_false); } static Xen gxg_gtk_entry_get_icon_name(Xen entry, Xen icon_pos) { #define H_gtk_entry_get_icon_name "gchar* gtk_entry_get_icon_name(GtkEntry* entry, GtkEntryIconPosition icon_pos)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_get_icon_name", "GtkEntry*"); Xen_check_type(Xen_is_GtkEntryIconPosition(icon_pos), icon_pos, 2, "gtk_entry_get_icon_name", "GtkEntryIconPosition"); return(C_to_Xen_gchar_(gtk_entry_get_icon_name(Xen_to_C_GtkEntry_(entry), Xen_to_C_GtkEntryIconPosition(icon_pos)))); } static Xen gxg_gtk_entry_set_icon_activatable(Xen entry, Xen icon_pos, Xen activatable) { #define H_gtk_entry_set_icon_activatable "void gtk_entry_set_icon_activatable(GtkEntry* entry, GtkEntryIconPosition icon_pos, \ gboolean activatable)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_set_icon_activatable", "GtkEntry*"); Xen_check_type(Xen_is_GtkEntryIconPosition(icon_pos), icon_pos, 2, "gtk_entry_set_icon_activatable", "GtkEntryIconPosition"); Xen_check_type(Xen_is_gboolean(activatable), activatable, 3, "gtk_entry_set_icon_activatable", "gboolean"); gtk_entry_set_icon_activatable(Xen_to_C_GtkEntry_(entry), Xen_to_C_GtkEntryIconPosition(icon_pos), Xen_to_C_gboolean(activatable)); return(Xen_false); } static Xen gxg_gtk_entry_get_icon_activatable(Xen entry, Xen icon_pos) { #define H_gtk_entry_get_icon_activatable "gboolean gtk_entry_get_icon_activatable(GtkEntry* entry, \ GtkEntryIconPosition icon_pos)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_get_icon_activatable", "GtkEntry*"); Xen_check_type(Xen_is_GtkEntryIconPosition(icon_pos), icon_pos, 2, "gtk_entry_get_icon_activatable", "GtkEntryIconPosition"); return(C_to_Xen_gboolean(gtk_entry_get_icon_activatable(Xen_to_C_GtkEntry_(entry), Xen_to_C_GtkEntryIconPosition(icon_pos)))); } static Xen gxg_gtk_entry_set_icon_sensitive(Xen entry, Xen icon_pos, Xen sensitive) { #define H_gtk_entry_set_icon_sensitive "void gtk_entry_set_icon_sensitive(GtkEntry* entry, GtkEntryIconPosition icon_pos, \ gboolean sensitive)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_set_icon_sensitive", "GtkEntry*"); Xen_check_type(Xen_is_GtkEntryIconPosition(icon_pos), icon_pos, 2, "gtk_entry_set_icon_sensitive", "GtkEntryIconPosition"); Xen_check_type(Xen_is_gboolean(sensitive), sensitive, 3, "gtk_entry_set_icon_sensitive", "gboolean"); gtk_entry_set_icon_sensitive(Xen_to_C_GtkEntry_(entry), Xen_to_C_GtkEntryIconPosition(icon_pos), Xen_to_C_gboolean(sensitive)); return(Xen_false); } static Xen gxg_gtk_entry_get_icon_sensitive(Xen entry, Xen icon_pos) { #define H_gtk_entry_get_icon_sensitive "gboolean gtk_entry_get_icon_sensitive(GtkEntry* entry, GtkEntryIconPosition icon_pos)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_get_icon_sensitive", "GtkEntry*"); Xen_check_type(Xen_is_GtkEntryIconPosition(icon_pos), icon_pos, 2, "gtk_entry_get_icon_sensitive", "GtkEntryIconPosition"); return(C_to_Xen_gboolean(gtk_entry_get_icon_sensitive(Xen_to_C_GtkEntry_(entry), Xen_to_C_GtkEntryIconPosition(icon_pos)))); } static Xen gxg_gtk_entry_get_icon_at_pos(Xen entry, Xen x, Xen y) { #define H_gtk_entry_get_icon_at_pos "gint gtk_entry_get_icon_at_pos(GtkEntry* entry, gint x, gint y)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_get_icon_at_pos", "GtkEntry*"); Xen_check_type(Xen_is_gint(x), x, 2, "gtk_entry_get_icon_at_pos", "gint"); Xen_check_type(Xen_is_gint(y), y, 3, "gtk_entry_get_icon_at_pos", "gint"); return(C_to_Xen_gint(gtk_entry_get_icon_at_pos(Xen_to_C_GtkEntry_(entry), Xen_to_C_gint(x), Xen_to_C_gint(y)))); } static Xen gxg_gtk_entry_set_icon_tooltip_text(Xen entry, Xen icon_pos, Xen tooltip) { #define H_gtk_entry_set_icon_tooltip_text "void gtk_entry_set_icon_tooltip_text(GtkEntry* entry, GtkEntryIconPosition icon_pos, \ gchar* tooltip)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_set_icon_tooltip_text", "GtkEntry*"); Xen_check_type(Xen_is_GtkEntryIconPosition(icon_pos), icon_pos, 2, "gtk_entry_set_icon_tooltip_text", "GtkEntryIconPosition"); Xen_check_type(Xen_is_gchar_(tooltip), tooltip, 3, "gtk_entry_set_icon_tooltip_text", "gchar*"); gtk_entry_set_icon_tooltip_text(Xen_to_C_GtkEntry_(entry), Xen_to_C_GtkEntryIconPosition(icon_pos), Xen_to_C_gchar_(tooltip)); return(Xen_false); } static Xen gxg_gtk_entry_set_icon_tooltip_markup(Xen entry, Xen icon_pos, Xen tooltip) { #define H_gtk_entry_set_icon_tooltip_markup "void gtk_entry_set_icon_tooltip_markup(GtkEntry* entry, \ GtkEntryIconPosition icon_pos, gchar* tooltip)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_set_icon_tooltip_markup", "GtkEntry*"); Xen_check_type(Xen_is_GtkEntryIconPosition(icon_pos), icon_pos, 2, "gtk_entry_set_icon_tooltip_markup", "GtkEntryIconPosition"); Xen_check_type(Xen_is_gchar_(tooltip), tooltip, 3, "gtk_entry_set_icon_tooltip_markup", "gchar*"); gtk_entry_set_icon_tooltip_markup(Xen_to_C_GtkEntry_(entry), Xen_to_C_GtkEntryIconPosition(icon_pos), Xen_to_C_gchar_(tooltip)); return(Xen_false); } static Xen gxg_gtk_entry_set_icon_drag_source(Xen entry, Xen icon_pos, Xen target_list, Xen actions) { #define H_gtk_entry_set_icon_drag_source "void gtk_entry_set_icon_drag_source(GtkEntry* entry, GtkEntryIconPosition icon_pos, \ GtkTargetList* target_list, GdkDragAction actions)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_set_icon_drag_source", "GtkEntry*"); Xen_check_type(Xen_is_GtkEntryIconPosition(icon_pos), icon_pos, 2, "gtk_entry_set_icon_drag_source", "GtkEntryIconPosition"); Xen_check_type(Xen_is_GtkTargetList_(target_list), target_list, 3, "gtk_entry_set_icon_drag_source", "GtkTargetList*"); Xen_check_type(Xen_is_GdkDragAction(actions), actions, 4, "gtk_entry_set_icon_drag_source", "GdkDragAction"); gtk_entry_set_icon_drag_source(Xen_to_C_GtkEntry_(entry), Xen_to_C_GtkEntryIconPosition(icon_pos), Xen_to_C_GtkTargetList_(target_list), Xen_to_C_GdkDragAction(actions)); return(Xen_false); } static Xen gxg_gtk_entry_get_current_icon_drag_source(Xen entry) { #define H_gtk_entry_get_current_icon_drag_source "gint gtk_entry_get_current_icon_drag_source(GtkEntry* entry)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_get_current_icon_drag_source", "GtkEntry*"); return(C_to_Xen_gint(gtk_entry_get_current_icon_drag_source(Xen_to_C_GtkEntry_(entry)))); } static Xen gxg_gtk_menu_item_set_label(Xen menu_item, Xen label) { #define H_gtk_menu_item_set_label "void gtk_menu_item_set_label(GtkMenuItem* menu_item, gchar* label)" Xen_check_type(Xen_is_GtkMenuItem_(menu_item), menu_item, 1, "gtk_menu_item_set_label", "GtkMenuItem*"); Xen_check_type(Xen_is_gchar_(label), label, 2, "gtk_menu_item_set_label", "gchar*"); gtk_menu_item_set_label(Xen_to_C_GtkMenuItem_(menu_item), Xen_to_C_gchar_(label)); return(Xen_false); } static Xen gxg_gtk_menu_item_get_label(Xen menu_item) { #define H_gtk_menu_item_get_label "gchar* gtk_menu_item_get_label(GtkMenuItem* menu_item)" Xen_check_type(Xen_is_GtkMenuItem_(menu_item), menu_item, 1, "gtk_menu_item_get_label", "GtkMenuItem*"); return(C_to_Xen_gchar_(gtk_menu_item_get_label(Xen_to_C_GtkMenuItem_(menu_item)))); } static Xen gxg_gtk_menu_item_set_use_underline(Xen menu_item, Xen setting) { #define H_gtk_menu_item_set_use_underline "void gtk_menu_item_set_use_underline(GtkMenuItem* menu_item, \ gboolean setting)" Xen_check_type(Xen_is_GtkMenuItem_(menu_item), menu_item, 1, "gtk_menu_item_set_use_underline", "GtkMenuItem*"); Xen_check_type(Xen_is_gboolean(setting), setting, 2, "gtk_menu_item_set_use_underline", "gboolean"); gtk_menu_item_set_use_underline(Xen_to_C_GtkMenuItem_(menu_item), Xen_to_C_gboolean(setting)); return(Xen_false); } static Xen gxg_gtk_menu_item_get_use_underline(Xen menu_item) { #define H_gtk_menu_item_get_use_underline "gboolean gtk_menu_item_get_use_underline(GtkMenuItem* menu_item)" Xen_check_type(Xen_is_GtkMenuItem_(menu_item), menu_item, 1, "gtk_menu_item_get_use_underline", "GtkMenuItem*"); return(C_to_Xen_gboolean(gtk_menu_item_get_use_underline(Xen_to_C_GtkMenuItem_(menu_item)))); } static Xen gxg_gtk_selection_data_get_selection(Xen selection_data) { #define H_gtk_selection_data_get_selection "GdkAtom gtk_selection_data_get_selection(GtkSelectionData* selection_data)" Xen_check_type(Xen_is_GtkSelectionData_(selection_data), selection_data, 1, "gtk_selection_data_get_selection", "GtkSelectionData*"); return(C_to_Xen_GdkAtom(gtk_selection_data_get_selection(Xen_to_C_GtkSelectionData_(selection_data)))); } static Xen gxg_gtk_entry_get_icon_tooltip_text(Xen entry, Xen icon_pos) { #define H_gtk_entry_get_icon_tooltip_text "gchar* gtk_entry_get_icon_tooltip_text(GtkEntry* entry, \ GtkEntryIconPosition icon_pos)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_get_icon_tooltip_text", "GtkEntry*"); Xen_check_type(Xen_is_GtkEntryIconPosition(icon_pos), icon_pos, 2, "gtk_entry_get_icon_tooltip_text", "GtkEntryIconPosition"); return(C_to_Xen_gchar_(gtk_entry_get_icon_tooltip_text(Xen_to_C_GtkEntry_(entry), Xen_to_C_GtkEntryIconPosition(icon_pos)))); } static Xen gxg_gtk_entry_get_icon_tooltip_markup(Xen entry, Xen icon_pos) { #define H_gtk_entry_get_icon_tooltip_markup "gchar* gtk_entry_get_icon_tooltip_markup(GtkEntry* entry, \ GtkEntryIconPosition icon_pos)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_get_icon_tooltip_markup", "GtkEntry*"); Xen_check_type(Xen_is_GtkEntryIconPosition(icon_pos), icon_pos, 2, "gtk_entry_get_icon_tooltip_markup", "GtkEntryIconPosition"); return(C_to_Xen_gchar_(gtk_entry_get_icon_tooltip_markup(Xen_to_C_GtkEntry_(entry), Xen_to_C_GtkEntryIconPosition(icon_pos)))); } static Xen gxg_gtk_scale_add_mark(Xen scale, Xen value, Xen position, Xen markup) { #define H_gtk_scale_add_mark "void gtk_scale_add_mark(GtkScale* scale, gdouble value, GtkPositionType position, \ gchar* markup)" Xen_check_type(Xen_is_GtkScale_(scale), scale, 1, "gtk_scale_add_mark", "GtkScale*"); Xen_check_type(Xen_is_gdouble(value), value, 2, "gtk_scale_add_mark", "gdouble"); Xen_check_type(Xen_is_GtkPositionType(position), position, 3, "gtk_scale_add_mark", "GtkPositionType"); Xen_check_type(Xen_is_gchar_(markup), markup, 4, "gtk_scale_add_mark", "gchar*"); gtk_scale_add_mark(Xen_to_C_GtkScale_(scale), Xen_to_C_gdouble(value), Xen_to_C_GtkPositionType(position), Xen_to_C_gchar_(markup)); return(Xen_false); } static Xen gxg_gtk_scale_clear_marks(Xen scale) { #define H_gtk_scale_clear_marks "void gtk_scale_clear_marks(GtkScale* scale)" Xen_check_type(Xen_is_GtkScale_(scale), scale, 1, "gtk_scale_clear_marks", "GtkScale*"); gtk_scale_clear_marks(Xen_to_C_GtkScale_(scale)); return(Xen_false); } #endif #if GTK_CHECK_VERSION(2, 18, 0) static Xen gxg_gtk_window_get_default_icon_name(void) { #define H_gtk_window_get_default_icon_name "gchar* gtk_window_get_default_icon_name( void)" return(C_to_Xen_gchar_(gtk_window_get_default_icon_name())); } static Xen gxg_gtk_label_get_current_uri(Xen label) { #define H_gtk_label_get_current_uri "gchar* gtk_label_get_current_uri(GtkLabel* label)" Xen_check_type(Xen_is_GtkLabel_(label), label, 1, "gtk_label_get_current_uri", "GtkLabel*"); return(C_to_Xen_gchar_(gtk_label_get_current_uri(Xen_to_C_GtkLabel_(label)))); } static Xen gxg_gtk_info_bar_new(void) { #define H_gtk_info_bar_new "GtkWidget* gtk_info_bar_new( void)" return(C_to_Xen_GtkWidget_(gtk_info_bar_new())); } static Xen gxg_gtk_info_bar_get_action_area(Xen info_bar) { #define H_gtk_info_bar_get_action_area "GtkWidget* gtk_info_bar_get_action_area(GtkInfoBar* info_bar)" Xen_check_type(Xen_is_GtkInfoBar_(info_bar), info_bar, 1, "gtk_info_bar_get_action_area", "GtkInfoBar*"); return(C_to_Xen_GtkWidget_(gtk_info_bar_get_action_area(Xen_to_C_GtkInfoBar_(info_bar)))); } static Xen gxg_gtk_info_bar_get_content_area(Xen info_bar) { #define H_gtk_info_bar_get_content_area "GtkWidget* gtk_info_bar_get_content_area(GtkInfoBar* info_bar)" Xen_check_type(Xen_is_GtkInfoBar_(info_bar), info_bar, 1, "gtk_info_bar_get_content_area", "GtkInfoBar*"); return(C_to_Xen_GtkWidget_(gtk_info_bar_get_content_area(Xen_to_C_GtkInfoBar_(info_bar)))); } static Xen gxg_gtk_info_bar_add_action_widget(Xen info_bar, Xen child, Xen response_id) { #define H_gtk_info_bar_add_action_widget "void gtk_info_bar_add_action_widget(GtkInfoBar* info_bar, \ GtkWidget* child, gint response_id)" Xen_check_type(Xen_is_GtkInfoBar_(info_bar), info_bar, 1, "gtk_info_bar_add_action_widget", "GtkInfoBar*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_info_bar_add_action_widget", "GtkWidget*"); Xen_check_type(Xen_is_gint(response_id), response_id, 3, "gtk_info_bar_add_action_widget", "gint"); gtk_info_bar_add_action_widget(Xen_to_C_GtkInfoBar_(info_bar), Xen_to_C_GtkWidget_(child), Xen_to_C_gint(response_id)); return(Xen_false); } static Xen gxg_gtk_info_bar_add_button(Xen info_bar, Xen button_text, Xen response_id) { #define H_gtk_info_bar_add_button "GtkWidget* gtk_info_bar_add_button(GtkInfoBar* info_bar, gchar* button_text, \ gint response_id)" Xen_check_type(Xen_is_GtkInfoBar_(info_bar), info_bar, 1, "gtk_info_bar_add_button", "GtkInfoBar*"); Xen_check_type(Xen_is_gchar_(button_text), button_text, 2, "gtk_info_bar_add_button", "gchar*"); Xen_check_type(Xen_is_gint(response_id), response_id, 3, "gtk_info_bar_add_button", "gint"); return(C_to_Xen_GtkWidget_(gtk_info_bar_add_button(Xen_to_C_GtkInfoBar_(info_bar), Xen_to_C_gchar_(button_text), Xen_to_C_gint(response_id)))); } static Xen gxg_gtk_info_bar_set_response_sensitive(Xen info_bar, Xen response_id, Xen setting) { #define H_gtk_info_bar_set_response_sensitive "void gtk_info_bar_set_response_sensitive(GtkInfoBar* info_bar, \ gint response_id, gboolean setting)" Xen_check_type(Xen_is_GtkInfoBar_(info_bar), info_bar, 1, "gtk_info_bar_set_response_sensitive", "GtkInfoBar*"); Xen_check_type(Xen_is_gint(response_id), response_id, 2, "gtk_info_bar_set_response_sensitive", "gint"); Xen_check_type(Xen_is_gboolean(setting), setting, 3, "gtk_info_bar_set_response_sensitive", "gboolean"); gtk_info_bar_set_response_sensitive(Xen_to_C_GtkInfoBar_(info_bar), Xen_to_C_gint(response_id), Xen_to_C_gboolean(setting)); return(Xen_false); } static Xen gxg_gtk_info_bar_set_default_response(Xen info_bar, Xen response_id) { #define H_gtk_info_bar_set_default_response "void gtk_info_bar_set_default_response(GtkInfoBar* info_bar, \ gint response_id)" Xen_check_type(Xen_is_GtkInfoBar_(info_bar), info_bar, 1, "gtk_info_bar_set_default_response", "GtkInfoBar*"); Xen_check_type(Xen_is_gint(response_id), response_id, 2, "gtk_info_bar_set_default_response", "gint"); gtk_info_bar_set_default_response(Xen_to_C_GtkInfoBar_(info_bar), Xen_to_C_gint(response_id)); return(Xen_false); } static Xen gxg_gtk_info_bar_response(Xen info_bar, Xen response_id) { #define H_gtk_info_bar_response "void gtk_info_bar_response(GtkInfoBar* info_bar, gint response_id)" Xen_check_type(Xen_is_GtkInfoBar_(info_bar), info_bar, 1, "gtk_info_bar_response", "GtkInfoBar*"); Xen_check_type(Xen_is_gint(response_id), response_id, 2, "gtk_info_bar_response", "gint"); gtk_info_bar_response(Xen_to_C_GtkInfoBar_(info_bar), Xen_to_C_gint(response_id)); return(Xen_false); } static Xen gxg_gtk_info_bar_set_message_type(Xen info_bar, Xen message_type) { #define H_gtk_info_bar_set_message_type "void gtk_info_bar_set_message_type(GtkInfoBar* info_bar, GtkMessageType message_type)" Xen_check_type(Xen_is_GtkInfoBar_(info_bar), info_bar, 1, "gtk_info_bar_set_message_type", "GtkInfoBar*"); Xen_check_type(Xen_is_GtkMessageType(message_type), message_type, 2, "gtk_info_bar_set_message_type", "GtkMessageType"); gtk_info_bar_set_message_type(Xen_to_C_GtkInfoBar_(info_bar), Xen_to_C_GtkMessageType(message_type)); return(Xen_false); } static Xen gxg_gtk_info_bar_get_message_type(Xen info_bar) { #define H_gtk_info_bar_get_message_type "GtkMessageType gtk_info_bar_get_message_type(GtkInfoBar* info_bar)" Xen_check_type(Xen_is_GtkInfoBar_(info_bar), info_bar, 1, "gtk_info_bar_get_message_type", "GtkInfoBar*"); return(C_to_Xen_GtkMessageType(gtk_info_bar_get_message_type(Xen_to_C_GtkInfoBar_(info_bar)))); } static Xen gxg_gdk_window_ensure_native(Xen window) { #define H_gdk_window_ensure_native "gboolean gdk_window_ensure_native(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_ensure_native", "GdkWindow*"); return(C_to_Xen_gboolean(gdk_window_ensure_native(Xen_to_C_GdkWindow_(window)))); } static Xen gxg_gdk_window_get_root_coords(Xen window, Xen x, Xen y, Xen ignore_root_x, Xen ignore_root_y) { #define H_gdk_window_get_root_coords "void gdk_window_get_root_coords(GdkWindow* window, gint x, gint y, \ gint* [root_x], gint* [root_y])" gint ref_root_x; gint ref_root_y; Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_get_root_coords", "GdkWindow*"); Xen_check_type(Xen_is_gint(x), x, 2, "gdk_window_get_root_coords", "gint"); Xen_check_type(Xen_is_gint(y), y, 3, "gdk_window_get_root_coords", "gint"); gdk_window_get_root_coords(Xen_to_C_GdkWindow_(window), Xen_to_C_gint(x), Xen_to_C_gint(y), &ref_root_x, &ref_root_y); return(Xen_list_2(C_to_Xen_gint(ref_root_x), C_to_Xen_gint(ref_root_y))); } static Xen gxg_gdk_offscreen_window_set_embedder(Xen window, Xen embedder) { #define H_gdk_offscreen_window_set_embedder "void gdk_offscreen_window_set_embedder(GdkWindow* window, \ GdkWindow* embedder)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_offscreen_window_set_embedder", "GdkWindow*"); Xen_check_type(Xen_is_GdkWindow_(embedder), embedder, 2, "gdk_offscreen_window_set_embedder", "GdkWindow*"); gdk_offscreen_window_set_embedder(Xen_to_C_GdkWindow_(window), Xen_to_C_GdkWindow_(embedder)); return(Xen_false); } static Xen gxg_gdk_offscreen_window_get_embedder(Xen window) { #define H_gdk_offscreen_window_get_embedder "GdkWindow* gdk_offscreen_window_get_embedder(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_offscreen_window_get_embedder", "GdkWindow*"); return(C_to_Xen_GdkWindow_(gdk_offscreen_window_get_embedder(Xen_to_C_GdkWindow_(window)))); } static Xen gxg_gdk_window_geometry_changed(Xen window) { #define H_gdk_window_geometry_changed "void gdk_window_geometry_changed(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_geometry_changed", "GdkWindow*"); gdk_window_geometry_changed(Xen_to_C_GdkWindow_(window)); return(Xen_false); } static Xen gxg_gtk_menu_set_reserve_toggle_size(Xen menu, Xen reserve_toggle_size) { #define H_gtk_menu_set_reserve_toggle_size "void gtk_menu_set_reserve_toggle_size(GtkMenu* menu, gboolean reserve_toggle_size)" Xen_check_type(Xen_is_GtkMenu_(menu), menu, 1, "gtk_menu_set_reserve_toggle_size", "GtkMenu*"); Xen_check_type(Xen_is_gboolean(reserve_toggle_size), reserve_toggle_size, 2, "gtk_menu_set_reserve_toggle_size", "gboolean"); gtk_menu_set_reserve_toggle_size(Xen_to_C_GtkMenu_(menu), Xen_to_C_gboolean(reserve_toggle_size)); return(Xen_false); } static Xen gxg_gtk_menu_get_reserve_toggle_size(Xen menu) { #define H_gtk_menu_get_reserve_toggle_size "gboolean gtk_menu_get_reserve_toggle_size(GtkMenu* menu)" Xen_check_type(Xen_is_GtkMenu_(menu), menu, 1, "gtk_menu_get_reserve_toggle_size", "GtkMenu*"); return(C_to_Xen_gboolean(gtk_menu_get_reserve_toggle_size(Xen_to_C_GtkMenu_(menu)))); } static Xen gxg_gtk_entry_new_with_buffer(Xen buffer) { #define H_gtk_entry_new_with_buffer "GtkWidget* gtk_entry_new_with_buffer(GtkEntryBuffer* buffer)" Xen_check_type(Xen_is_GtkEntryBuffer_(buffer), buffer, 1, "gtk_entry_new_with_buffer", "GtkEntryBuffer*"); return(C_to_Xen_GtkWidget_(gtk_entry_new_with_buffer(Xen_to_C_GtkEntryBuffer_(buffer)))); } static Xen gxg_gtk_entry_get_buffer(Xen entry) { #define H_gtk_entry_get_buffer "GtkEntryBuffer* gtk_entry_get_buffer(GtkEntry* entry)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_get_buffer", "GtkEntry*"); return(C_to_Xen_GtkEntryBuffer_(gtk_entry_get_buffer(Xen_to_C_GtkEntry_(entry)))); } static Xen gxg_gtk_entry_set_buffer(Xen entry, Xen buffer) { #define H_gtk_entry_set_buffer "void gtk_entry_set_buffer(GtkEntry* entry, GtkEntryBuffer* buffer)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_set_buffer", "GtkEntry*"); Xen_check_type(Xen_is_GtkEntryBuffer_(buffer), buffer, 2, "gtk_entry_set_buffer", "GtkEntryBuffer*"); gtk_entry_set_buffer(Xen_to_C_GtkEntry_(entry), Xen_to_C_GtkEntryBuffer_(buffer)); return(Xen_false); } static Xen gxg_gtk_label_set_track_visited_links(Xen label, Xen track_links) { #define H_gtk_label_set_track_visited_links "void gtk_label_set_track_visited_links(GtkLabel* label, \ gboolean track_links)" Xen_check_type(Xen_is_GtkLabel_(label), label, 1, "gtk_label_set_track_visited_links", "GtkLabel*"); Xen_check_type(Xen_is_gboolean(track_links), track_links, 2, "gtk_label_set_track_visited_links", "gboolean"); gtk_label_set_track_visited_links(Xen_to_C_GtkLabel_(label), Xen_to_C_gboolean(track_links)); return(Xen_false); } static Xen gxg_gtk_label_get_track_visited_links(Xen label) { #define H_gtk_label_get_track_visited_links "gboolean gtk_label_get_track_visited_links(GtkLabel* label)" Xen_check_type(Xen_is_GtkLabel_(label), label, 1, "gtk_label_get_track_visited_links", "GtkLabel*"); return(C_to_Xen_gboolean(gtk_label_get_track_visited_links(Xen_to_C_GtkLabel_(label)))); } static Xen gxg_gtk_print_operation_set_embed_page_setup(Xen op, Xen embed) { #define H_gtk_print_operation_set_embed_page_setup "void gtk_print_operation_set_embed_page_setup(GtkPrintOperation* op, \ gboolean embed)" Xen_check_type(Xen_is_GtkPrintOperation_(op), op, 1, "gtk_print_operation_set_embed_page_setup", "GtkPrintOperation*"); Xen_check_type(Xen_is_gboolean(embed), embed, 2, "gtk_print_operation_set_embed_page_setup", "gboolean"); gtk_print_operation_set_embed_page_setup(Xen_to_C_GtkPrintOperation_(op), Xen_to_C_gboolean(embed)); return(Xen_false); } static Xen gxg_gtk_print_operation_get_embed_page_setup(Xen op) { #define H_gtk_print_operation_get_embed_page_setup "gboolean gtk_print_operation_get_embed_page_setup(GtkPrintOperation* op)" Xen_check_type(Xen_is_GtkPrintOperation_(op), op, 1, "gtk_print_operation_get_embed_page_setup", "GtkPrintOperation*"); return(C_to_Xen_gboolean(gtk_print_operation_get_embed_page_setup(Xen_to_C_GtkPrintOperation_(op)))); } static Xen gxg_gtk_entry_buffer_new(Xen initial_chars, Xen n_initial_chars) { #define H_gtk_entry_buffer_new "GtkEntryBuffer* gtk_entry_buffer_new(gchar* initial_chars, gint n_initial_chars)" Xen_check_type(Xen_is_gchar_(initial_chars), initial_chars, 1, "gtk_entry_buffer_new", "gchar*"); Xen_check_type(Xen_is_gint(n_initial_chars), n_initial_chars, 2, "gtk_entry_buffer_new", "gint"); return(C_to_Xen_GtkEntryBuffer_(gtk_entry_buffer_new(Xen_to_C_gchar_(initial_chars), Xen_to_C_gint(n_initial_chars)))); } static Xen gxg_gtk_entry_buffer_get_bytes(Xen buffer) { #define H_gtk_entry_buffer_get_bytes "gsize gtk_entry_buffer_get_bytes(GtkEntryBuffer* buffer)" Xen_check_type(Xen_is_GtkEntryBuffer_(buffer), buffer, 1, "gtk_entry_buffer_get_bytes", "GtkEntryBuffer*"); return(C_to_Xen_gsize(gtk_entry_buffer_get_bytes(Xen_to_C_GtkEntryBuffer_(buffer)))); } static Xen gxg_gtk_entry_buffer_get_length(Xen buffer) { #define H_gtk_entry_buffer_get_length "guint gtk_entry_buffer_get_length(GtkEntryBuffer* buffer)" Xen_check_type(Xen_is_GtkEntryBuffer_(buffer), buffer, 1, "gtk_entry_buffer_get_length", "GtkEntryBuffer*"); return(C_to_Xen_guint(gtk_entry_buffer_get_length(Xen_to_C_GtkEntryBuffer_(buffer)))); } static Xen gxg_gtk_entry_buffer_get_text(Xen buffer) { #define H_gtk_entry_buffer_get_text "gchar* gtk_entry_buffer_get_text(GtkEntryBuffer* buffer)" Xen_check_type(Xen_is_GtkEntryBuffer_(buffer), buffer, 1, "gtk_entry_buffer_get_text", "GtkEntryBuffer*"); return(C_to_Xen_gchar_(gtk_entry_buffer_get_text(Xen_to_C_GtkEntryBuffer_(buffer)))); } static Xen gxg_gtk_entry_buffer_set_text(Xen buffer, Xen chars, Xen n_chars) { #define H_gtk_entry_buffer_set_text "void gtk_entry_buffer_set_text(GtkEntryBuffer* buffer, gchar* chars, \ gint n_chars)" Xen_check_type(Xen_is_GtkEntryBuffer_(buffer), buffer, 1, "gtk_entry_buffer_set_text", "GtkEntryBuffer*"); Xen_check_type(Xen_is_gchar_(chars), chars, 2, "gtk_entry_buffer_set_text", "gchar*"); Xen_check_type(Xen_is_gint(n_chars), n_chars, 3, "gtk_entry_buffer_set_text", "gint"); gtk_entry_buffer_set_text(Xen_to_C_GtkEntryBuffer_(buffer), Xen_to_C_gchar_(chars), Xen_to_C_gint(n_chars)); return(Xen_false); } static Xen gxg_gtk_entry_buffer_set_max_length(Xen buffer, Xen max_length) { #define H_gtk_entry_buffer_set_max_length "void gtk_entry_buffer_set_max_length(GtkEntryBuffer* buffer, \ guint max_length)" Xen_check_type(Xen_is_GtkEntryBuffer_(buffer), buffer, 1, "gtk_entry_buffer_set_max_length", "GtkEntryBuffer*"); Xen_check_type(Xen_is_guint(max_length), max_length, 2, "gtk_entry_buffer_set_max_length", "guint"); gtk_entry_buffer_set_max_length(Xen_to_C_GtkEntryBuffer_(buffer), Xen_to_C_guint(max_length)); return(Xen_false); } static Xen gxg_gtk_entry_buffer_get_max_length(Xen buffer) { #define H_gtk_entry_buffer_get_max_length "guint gtk_entry_buffer_get_max_length(GtkEntryBuffer* buffer)" Xen_check_type(Xen_is_GtkEntryBuffer_(buffer), buffer, 1, "gtk_entry_buffer_get_max_length", "GtkEntryBuffer*"); return(C_to_Xen_guint(gtk_entry_buffer_get_max_length(Xen_to_C_GtkEntryBuffer_(buffer)))); } static Xen gxg_gtk_entry_buffer_insert_text(Xen buffer, Xen position, Xen chars, Xen n_chars) { #define H_gtk_entry_buffer_insert_text "guint gtk_entry_buffer_insert_text(GtkEntryBuffer* buffer, \ guint position, gchar* chars, gint n_chars)" Xen_check_type(Xen_is_GtkEntryBuffer_(buffer), buffer, 1, "gtk_entry_buffer_insert_text", "GtkEntryBuffer*"); Xen_check_type(Xen_is_guint(position), position, 2, "gtk_entry_buffer_insert_text", "guint"); Xen_check_type(Xen_is_gchar_(chars), chars, 3, "gtk_entry_buffer_insert_text", "gchar*"); Xen_check_type(Xen_is_gint(n_chars), n_chars, 4, "gtk_entry_buffer_insert_text", "gint"); return(C_to_Xen_guint(gtk_entry_buffer_insert_text(Xen_to_C_GtkEntryBuffer_(buffer), Xen_to_C_guint(position), Xen_to_C_gchar_(chars), Xen_to_C_gint(n_chars)))); } static Xen gxg_gtk_entry_buffer_delete_text(Xen buffer, Xen position, Xen n_chars) { #define H_gtk_entry_buffer_delete_text "guint gtk_entry_buffer_delete_text(GtkEntryBuffer* buffer, \ guint position, gint n_chars)" Xen_check_type(Xen_is_GtkEntryBuffer_(buffer), buffer, 1, "gtk_entry_buffer_delete_text", "GtkEntryBuffer*"); Xen_check_type(Xen_is_guint(position), position, 2, "gtk_entry_buffer_delete_text", "guint"); Xen_check_type(Xen_is_gint(n_chars), n_chars, 3, "gtk_entry_buffer_delete_text", "gint"); return(C_to_Xen_guint(gtk_entry_buffer_delete_text(Xen_to_C_GtkEntryBuffer_(buffer), Xen_to_C_guint(position), Xen_to_C_gint(n_chars)))); } static Xen gxg_gtk_entry_buffer_emit_inserted_text(Xen buffer, Xen position, Xen chars, Xen n_chars) { #define H_gtk_entry_buffer_emit_inserted_text "void gtk_entry_buffer_emit_inserted_text(GtkEntryBuffer* buffer, \ guint position, gchar* chars, guint n_chars)" Xen_check_type(Xen_is_GtkEntryBuffer_(buffer), buffer, 1, "gtk_entry_buffer_emit_inserted_text", "GtkEntryBuffer*"); Xen_check_type(Xen_is_guint(position), position, 2, "gtk_entry_buffer_emit_inserted_text", "guint"); Xen_check_type(Xen_is_gchar_(chars), chars, 3, "gtk_entry_buffer_emit_inserted_text", "gchar*"); Xen_check_type(Xen_is_guint(n_chars), n_chars, 4, "gtk_entry_buffer_emit_inserted_text", "guint"); gtk_entry_buffer_emit_inserted_text(Xen_to_C_GtkEntryBuffer_(buffer), Xen_to_C_guint(position), Xen_to_C_gchar_(chars), Xen_to_C_guint(n_chars)); return(Xen_false); } static Xen gxg_gtk_entry_buffer_emit_deleted_text(Xen buffer, Xen position, Xen n_chars) { #define H_gtk_entry_buffer_emit_deleted_text "void gtk_entry_buffer_emit_deleted_text(GtkEntryBuffer* buffer, \ guint position, guint n_chars)" Xen_check_type(Xen_is_GtkEntryBuffer_(buffer), buffer, 1, "gtk_entry_buffer_emit_deleted_text", "GtkEntryBuffer*"); Xen_check_type(Xen_is_guint(position), position, 2, "gtk_entry_buffer_emit_deleted_text", "guint"); Xen_check_type(Xen_is_guint(n_chars), n_chars, 3, "gtk_entry_buffer_emit_deleted_text", "guint"); gtk_entry_buffer_emit_deleted_text(Xen_to_C_GtkEntryBuffer_(buffer), Xen_to_C_guint(position), Xen_to_C_guint(n_chars)); return(Xen_false); } static Xen gxg_gtk_cell_renderer_set_alignment(Xen cell, Xen xalign, Xen yalign) { #define H_gtk_cell_renderer_set_alignment "void gtk_cell_renderer_set_alignment(GtkCellRenderer* cell, \ gfloat xalign, gfloat yalign)" Xen_check_type(Xen_is_GtkCellRenderer_(cell), cell, 1, "gtk_cell_renderer_set_alignment", "GtkCellRenderer*"); Xen_check_type(Xen_is_gfloat(xalign), xalign, 2, "gtk_cell_renderer_set_alignment", "gfloat"); Xen_check_type(Xen_is_gfloat(yalign), yalign, 3, "gtk_cell_renderer_set_alignment", "gfloat"); gtk_cell_renderer_set_alignment(Xen_to_C_GtkCellRenderer_(cell), Xen_to_C_gfloat(xalign), Xen_to_C_gfloat(yalign)); return(Xen_false); } static Xen gxg_gtk_cell_renderer_get_alignment(Xen cell, Xen ignore_xalign, Xen ignore_yalign) { #define H_gtk_cell_renderer_get_alignment "void gtk_cell_renderer_get_alignment(GtkCellRenderer* cell, \ gfloat* [xalign], gfloat* [yalign])" gfloat ref_xalign; gfloat ref_yalign; Xen_check_type(Xen_is_GtkCellRenderer_(cell), cell, 1, "gtk_cell_renderer_get_alignment", "GtkCellRenderer*"); gtk_cell_renderer_get_alignment(Xen_to_C_GtkCellRenderer_(cell), &ref_xalign, &ref_yalign); return(Xen_list_2(C_to_Xen_gfloat(ref_xalign), C_to_Xen_gfloat(ref_yalign))); } static Xen gxg_gtk_cell_renderer_set_padding(Xen cell, Xen xpad, Xen ypad) { #define H_gtk_cell_renderer_set_padding "void gtk_cell_renderer_set_padding(GtkCellRenderer* cell, \ gint xpad, gint ypad)" Xen_check_type(Xen_is_GtkCellRenderer_(cell), cell, 1, "gtk_cell_renderer_set_padding", "GtkCellRenderer*"); Xen_check_type(Xen_is_gint(xpad), xpad, 2, "gtk_cell_renderer_set_padding", "gint"); Xen_check_type(Xen_is_gint(ypad), ypad, 3, "gtk_cell_renderer_set_padding", "gint"); gtk_cell_renderer_set_padding(Xen_to_C_GtkCellRenderer_(cell), Xen_to_C_gint(xpad), Xen_to_C_gint(ypad)); return(Xen_false); } static Xen gxg_gtk_cell_renderer_get_padding(Xen cell, Xen ignore_xpad, Xen ignore_ypad) { #define H_gtk_cell_renderer_get_padding "void gtk_cell_renderer_get_padding(GtkCellRenderer* cell, \ gint* [xpad], gint* [ypad])" gint ref_xpad; gint ref_ypad; Xen_check_type(Xen_is_GtkCellRenderer_(cell), cell, 1, "gtk_cell_renderer_get_padding", "GtkCellRenderer*"); gtk_cell_renderer_get_padding(Xen_to_C_GtkCellRenderer_(cell), &ref_xpad, &ref_ypad); return(Xen_list_2(C_to_Xen_gint(ref_xpad), C_to_Xen_gint(ref_ypad))); } static Xen gxg_gtk_cell_renderer_set_visible(Xen cell, Xen visible) { #define H_gtk_cell_renderer_set_visible "void gtk_cell_renderer_set_visible(GtkCellRenderer* cell, \ gboolean visible)" Xen_check_type(Xen_is_GtkCellRenderer_(cell), cell, 1, "gtk_cell_renderer_set_visible", "GtkCellRenderer*"); Xen_check_type(Xen_is_gboolean(visible), visible, 2, "gtk_cell_renderer_set_visible", "gboolean"); gtk_cell_renderer_set_visible(Xen_to_C_GtkCellRenderer_(cell), Xen_to_C_gboolean(visible)); return(Xen_false); } static Xen gxg_gtk_cell_renderer_get_visible(Xen cell) { #define H_gtk_cell_renderer_get_visible "gboolean gtk_cell_renderer_get_visible(GtkCellRenderer* cell)" Xen_check_type(Xen_is_GtkCellRenderer_(cell), cell, 1, "gtk_cell_renderer_get_visible", "GtkCellRenderer*"); return(C_to_Xen_gboolean(gtk_cell_renderer_get_visible(Xen_to_C_GtkCellRenderer_(cell)))); } static Xen gxg_gtk_cell_renderer_set_sensitive(Xen cell, Xen sensitive) { #define H_gtk_cell_renderer_set_sensitive "void gtk_cell_renderer_set_sensitive(GtkCellRenderer* cell, \ gboolean sensitive)" Xen_check_type(Xen_is_GtkCellRenderer_(cell), cell, 1, "gtk_cell_renderer_set_sensitive", "GtkCellRenderer*"); Xen_check_type(Xen_is_gboolean(sensitive), sensitive, 2, "gtk_cell_renderer_set_sensitive", "gboolean"); gtk_cell_renderer_set_sensitive(Xen_to_C_GtkCellRenderer_(cell), Xen_to_C_gboolean(sensitive)); return(Xen_false); } static Xen gxg_gtk_cell_renderer_get_sensitive(Xen cell) { #define H_gtk_cell_renderer_get_sensitive "gboolean gtk_cell_renderer_get_sensitive(GtkCellRenderer* cell)" Xen_check_type(Xen_is_GtkCellRenderer_(cell), cell, 1, "gtk_cell_renderer_get_sensitive", "GtkCellRenderer*"); return(C_to_Xen_gboolean(gtk_cell_renderer_get_sensitive(Xen_to_C_GtkCellRenderer_(cell)))); } static Xen gxg_gtk_cell_renderer_toggle_get_activatable(Xen toggle) { #define H_gtk_cell_renderer_toggle_get_activatable "gboolean gtk_cell_renderer_toggle_get_activatable(GtkCellRendererToggle* toggle)" Xen_check_type(Xen_is_GtkCellRendererToggle_(toggle), toggle, 1, "gtk_cell_renderer_toggle_get_activatable", "GtkCellRendererToggle*"); return(C_to_Xen_gboolean(gtk_cell_renderer_toggle_get_activatable(Xen_to_C_GtkCellRendererToggle_(toggle)))); } static Xen gxg_gtk_cell_renderer_toggle_set_activatable(Xen toggle, Xen setting) { #define H_gtk_cell_renderer_toggle_set_activatable "void gtk_cell_renderer_toggle_set_activatable(GtkCellRendererToggle* toggle, \ gboolean setting)" Xen_check_type(Xen_is_GtkCellRendererToggle_(toggle), toggle, 1, "gtk_cell_renderer_toggle_set_activatable", "GtkCellRendererToggle*"); Xen_check_type(Xen_is_gboolean(setting), setting, 2, "gtk_cell_renderer_toggle_set_activatable", "gboolean"); gtk_cell_renderer_toggle_set_activatable(Xen_to_C_GtkCellRendererToggle_(toggle), Xen_to_C_gboolean(setting)); return(Xen_false); } static Xen gxg_gtk_widget_set_can_focus(Xen widget, Xen can_focus) { #define H_gtk_widget_set_can_focus "void gtk_widget_set_can_focus(GtkWidget* widget, gboolean can_focus)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_set_can_focus", "GtkWidget*"); Xen_check_type(Xen_is_gboolean(can_focus), can_focus, 2, "gtk_widget_set_can_focus", "gboolean"); gtk_widget_set_can_focus(Xen_to_C_GtkWidget_(widget), Xen_to_C_gboolean(can_focus)); return(Xen_false); } static Xen gxg_gtk_widget_get_can_focus(Xen widget) { #define H_gtk_widget_get_can_focus "gboolean gtk_widget_get_can_focus(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_can_focus", "GtkWidget*"); return(C_to_Xen_gboolean(gtk_widget_get_can_focus(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_has_focus(Xen widget) { #define H_gtk_widget_has_focus "gboolean gtk_widget_has_focus(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_has_focus", "GtkWidget*"); return(C_to_Xen_gboolean(gtk_widget_has_focus(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_set_can_default(Xen widget, Xen can_default) { #define H_gtk_widget_set_can_default "void gtk_widget_set_can_default(GtkWidget* widget, gboolean can_default)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_set_can_default", "GtkWidget*"); Xen_check_type(Xen_is_gboolean(can_default), can_default, 2, "gtk_widget_set_can_default", "gboolean"); gtk_widget_set_can_default(Xen_to_C_GtkWidget_(widget), Xen_to_C_gboolean(can_default)); return(Xen_false); } static Xen gxg_gtk_widget_get_can_default(Xen widget) { #define H_gtk_widget_get_can_default "gboolean gtk_widget_get_can_default(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_can_default", "GtkWidget*"); return(C_to_Xen_gboolean(gtk_widget_get_can_default(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_has_default(Xen widget) { #define H_gtk_widget_has_default "gboolean gtk_widget_has_default(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_has_default", "GtkWidget*"); return(C_to_Xen_gboolean(gtk_widget_has_default(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_get_sensitive(Xen widget) { #define H_gtk_widget_get_sensitive "gboolean gtk_widget_get_sensitive(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_sensitive", "GtkWidget*"); return(C_to_Xen_gboolean(gtk_widget_get_sensitive(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_is_sensitive(Xen widget) { #define H_gtk_widget_is_sensitive "gboolean gtk_widget_is_sensitive(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_is_sensitive", "GtkWidget*"); return(C_to_Xen_gboolean(gtk_widget_is_sensitive(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_set_has_window(Xen widget, Xen has_window) { #define H_gtk_widget_set_has_window "void gtk_widget_set_has_window(GtkWidget* widget, gboolean has_window)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_set_has_window", "GtkWidget*"); Xen_check_type(Xen_is_gboolean(has_window), has_window, 2, "gtk_widget_set_has_window", "gboolean"); gtk_widget_set_has_window(Xen_to_C_GtkWidget_(widget), Xen_to_C_gboolean(has_window)); return(Xen_false); } static Xen gxg_gtk_widget_get_has_window(Xen widget) { #define H_gtk_widget_get_has_window "gboolean gtk_widget_get_has_window(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_has_window", "GtkWidget*"); return(C_to_Xen_gboolean(gtk_widget_get_has_window(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_get_app_paintable(Xen widget) { #define H_gtk_widget_get_app_paintable "gboolean gtk_widget_get_app_paintable(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_app_paintable", "GtkWidget*"); return(C_to_Xen_gboolean(gtk_widget_get_app_paintable(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gdk_window_get_cursor(Xen window) { #define H_gdk_window_get_cursor "GdkCursor* gdk_window_get_cursor(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_get_cursor", "GdkWindow*"); return(C_to_Xen_GdkCursor_(gdk_window_get_cursor(Xen_to_C_GdkWindow_(window)))); } static Xen gxg_gtk_file_chooser_set_create_folders(Xen chooser, Xen create_folders) { #define H_gtk_file_chooser_set_create_folders "void gtk_file_chooser_set_create_folders(GtkFileChooser* chooser, \ gboolean create_folders)" Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_set_create_folders", "GtkFileChooser*"); Xen_check_type(Xen_is_gboolean(create_folders), create_folders, 2, "gtk_file_chooser_set_create_folders", "gboolean"); gtk_file_chooser_set_create_folders(Xen_to_C_GtkFileChooser_(chooser), Xen_to_C_gboolean(create_folders)); return(Xen_false); } static Xen gxg_gtk_file_chooser_get_create_folders(Xen chooser) { #define H_gtk_file_chooser_get_create_folders "gboolean gtk_file_chooser_get_create_folders(GtkFileChooser* chooser)" Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_get_create_folders", "GtkFileChooser*"); return(C_to_Xen_gboolean(gtk_file_chooser_get_create_folders(Xen_to_C_GtkFileChooser_(chooser)))); } static Xen gxg_gtk_icon_view_set_item_padding(Xen icon_view, Xen item_padding) { #define H_gtk_icon_view_set_item_padding "void gtk_icon_view_set_item_padding(GtkIconView* icon_view, \ gint item_padding)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_set_item_padding", "GtkIconView*"); Xen_check_type(Xen_is_gint(item_padding), item_padding, 2, "gtk_icon_view_set_item_padding", "gint"); gtk_icon_view_set_item_padding(Xen_to_C_GtkIconView_(icon_view), Xen_to_C_gint(item_padding)); return(Xen_false); } static Xen gxg_gtk_icon_view_get_item_padding(Xen icon_view) { #define H_gtk_icon_view_get_item_padding "gint gtk_icon_view_get_item_padding(GtkIconView* icon_view)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_get_item_padding", "GtkIconView*"); return(C_to_Xen_gint(gtk_icon_view_get_item_padding(Xen_to_C_GtkIconView_(icon_view)))); } static Xen gxg_gtk_widget_has_grab(Xen widget) { #define H_gtk_widget_has_grab "gboolean gtk_widget_has_grab(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_has_grab", "GtkWidget*"); return(C_to_Xen_gboolean(gtk_widget_has_grab(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_set_visible(Xen widget, Xen visible) { #define H_gtk_widget_set_visible "void gtk_widget_set_visible(GtkWidget* widget, gboolean visible)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_set_visible", "GtkWidget*"); Xen_check_type(Xen_is_gboolean(visible), visible, 2, "gtk_widget_set_visible", "gboolean"); gtk_widget_set_visible(Xen_to_C_GtkWidget_(widget), Xen_to_C_gboolean(visible)); return(Xen_false); } static Xen gxg_gtk_widget_get_visible(Xen widget) { #define H_gtk_widget_get_visible "gboolean gtk_widget_get_visible(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_visible", "GtkWidget*"); return(C_to_Xen_gboolean(gtk_widget_get_visible(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_range_set_flippable(Xen range, Xen flippable) { #define H_gtk_range_set_flippable "void gtk_range_set_flippable(GtkRange* range, gboolean flippable)" Xen_check_type(Xen_is_GtkRange_(range), range, 1, "gtk_range_set_flippable", "GtkRange*"); Xen_check_type(Xen_is_gboolean(flippable), flippable, 2, "gtk_range_set_flippable", "gboolean"); gtk_range_set_flippable(Xen_to_C_GtkRange_(range), Xen_to_C_gboolean(flippable)); return(Xen_false); } static Xen gxg_gtk_range_get_flippable(Xen range) { #define H_gtk_range_get_flippable "gboolean gtk_range_get_flippable(GtkRange* range)" Xen_check_type(Xen_is_GtkRange_(range), range, 1, "gtk_range_get_flippable", "GtkRange*"); return(C_to_Xen_gboolean(gtk_range_get_flippable(Xen_to_C_GtkRange_(range)))); } static Xen gxg_gtk_widget_is_toplevel(Xen widget) { #define H_gtk_widget_is_toplevel "gboolean gtk_widget_is_toplevel(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_is_toplevel", "GtkWidget*"); return(C_to_Xen_gboolean(gtk_widget_is_toplevel(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_is_drawable(Xen widget) { #define H_gtk_widget_is_drawable "gboolean gtk_widget_is_drawable(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_is_drawable", "GtkWidget*"); return(C_to_Xen_gboolean(gtk_widget_is_drawable(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_set_window(Xen widget, Xen window) { #define H_gtk_widget_set_window "void gtk_widget_set_window(GtkWidget* widget, GdkWindow* window)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_set_window", "GtkWidget*"); Xen_check_type(Xen_is_GdkWindow_(window), window, 2, "gtk_widget_set_window", "GdkWindow*"); gtk_widget_set_window(Xen_to_C_GtkWidget_(widget), Xen_to_C_GdkWindow_(window)); return(Xen_false); } static Xen gxg_gdk_window_is_destroyed(Xen window) { #define H_gdk_window_is_destroyed "gboolean gdk_window_is_destroyed(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_is_destroyed", "GdkWindow*"); return(C_to_Xen_gboolean(gdk_window_is_destroyed(Xen_to_C_GdkWindow_(window)))); } static Xen gxg_gdk_window_restack(Xen window, Xen sibling, Xen above) { #define H_gdk_window_restack "void gdk_window_restack(GdkWindow* window, GdkWindow* sibling, gboolean above)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_restack", "GdkWindow*"); Xen_check_type(Xen_is_GdkWindow_(sibling), sibling, 2, "gdk_window_restack", "GdkWindow*"); Xen_check_type(Xen_is_gboolean(above), above, 3, "gdk_window_restack", "gboolean"); gdk_window_restack(Xen_to_C_GdkWindow_(window), Xen_to_C_GdkWindow_(sibling), Xen_to_C_gboolean(above)); return(Xen_false); } static Xen gxg_gtk_widget_set_receives_default(Xen widget, Xen receives_default) { #define H_gtk_widget_set_receives_default "void gtk_widget_set_receives_default(GtkWidget* widget, \ gboolean receives_default)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_set_receives_default", "GtkWidget*"); Xen_check_type(Xen_is_gboolean(receives_default), receives_default, 2, "gtk_widget_set_receives_default", "gboolean"); gtk_widget_set_receives_default(Xen_to_C_GtkWidget_(widget), Xen_to_C_gboolean(receives_default)); return(Xen_false); } static Xen gxg_gtk_widget_get_receives_default(Xen widget) { #define H_gtk_widget_get_receives_default "gboolean gtk_widget_get_receives_default(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_receives_default", "GtkWidget*"); return(C_to_Xen_gboolean(gtk_widget_get_receives_default(Xen_to_C_GtkWidget_(widget)))); } #endif #if GTK_CHECK_VERSION(2, 20, 0) static Xen gxg_gtk_dialog_get_widget_for_response(Xen dialog, Xen response_id) { #define H_gtk_dialog_get_widget_for_response "GtkWidget* gtk_dialog_get_widget_for_response(GtkDialog* dialog, \ gint response_id)" Xen_check_type(Xen_is_GtkDialog_(dialog), dialog, 1, "gtk_dialog_get_widget_for_response", "GtkDialog*"); Xen_check_type(Xen_is_gint(response_id), response_id, 2, "gtk_dialog_get_widget_for_response", "gint"); return(C_to_Xen_GtkWidget_(gtk_dialog_get_widget_for_response(Xen_to_C_GtkDialog_(dialog), Xen_to_C_gint(response_id)))); } static Xen gxg_gtk_viewport_get_bin_window(Xen viewport) { #define H_gtk_viewport_get_bin_window "GdkWindow* gtk_viewport_get_bin_window(GtkViewport* viewport)" Xen_check_type(Xen_is_GtkViewport_(viewport), viewport, 1, "gtk_viewport_get_bin_window", "GtkViewport*"); return(C_to_Xen_GdkWindow_(gtk_viewport_get_bin_window(Xen_to_C_GtkViewport_(viewport)))); } static Xen gxg_gtk_spinner_new(void) { #define H_gtk_spinner_new "GtkWidget* gtk_spinner_new( void)" return(C_to_Xen_GtkWidget_(gtk_spinner_new())); } static Xen gxg_gtk_spinner_start(Xen spinner) { #define H_gtk_spinner_start "void gtk_spinner_start(GtkSpinner* spinner)" Xen_check_type(Xen_is_GtkSpinner_(spinner), spinner, 1, "gtk_spinner_start", "GtkSpinner*"); gtk_spinner_start(Xen_to_C_GtkSpinner_(spinner)); return(Xen_false); } static Xen gxg_gtk_spinner_stop(Xen spinner) { #define H_gtk_spinner_stop "void gtk_spinner_stop(GtkSpinner* spinner)" Xen_check_type(Xen_is_GtkSpinner_(spinner), spinner, 1, "gtk_spinner_stop", "GtkSpinner*"); gtk_spinner_stop(Xen_to_C_GtkSpinner_(spinner)); return(Xen_false); } static Xen gxg_gtk_cell_renderer_spinner_new(void) { #define H_gtk_cell_renderer_spinner_new "GtkCellRenderer* gtk_cell_renderer_spinner_new( void)" return(C_to_Xen_GtkCellRenderer_(gtk_cell_renderer_spinner_new())); } static Xen gxg_gtk_notebook_get_action_widget(Xen notebook, Xen pack_type) { #define H_gtk_notebook_get_action_widget "GtkWidget* gtk_notebook_get_action_widget(GtkNotebook* notebook, \ GtkPackType pack_type)" Xen_check_type(Xen_is_GtkNotebook_(notebook), notebook, 1, "gtk_notebook_get_action_widget", "GtkNotebook*"); Xen_check_type(Xen_is_GtkPackType(pack_type), pack_type, 2, "gtk_notebook_get_action_widget", "GtkPackType"); return(C_to_Xen_GtkWidget_(gtk_notebook_get_action_widget(Xen_to_C_GtkNotebook_(notebook), Xen_to_C_GtkPackType(pack_type)))); } static Xen gxg_gtk_notebook_set_action_widget(Xen notebook, Xen widget, Xen pack_type) { #define H_gtk_notebook_set_action_widget "void gtk_notebook_set_action_widget(GtkNotebook* notebook, \ GtkWidget* widget, GtkPackType pack_type)" Xen_check_type(Xen_is_GtkNotebook_(notebook), notebook, 1, "gtk_notebook_set_action_widget", "GtkNotebook*"); Xen_check_type(Xen_is_GtkWidget_(widget), widget, 2, "gtk_notebook_set_action_widget", "GtkWidget*"); Xen_check_type(Xen_is_GtkPackType(pack_type), pack_type, 3, "gtk_notebook_set_action_widget", "GtkPackType"); gtk_notebook_set_action_widget(Xen_to_C_GtkNotebook_(notebook), Xen_to_C_GtkWidget_(widget), Xen_to_C_GtkPackType(pack_type)); return(Xen_false); } static Xen gxg_gtk_statusbar_get_message_area(Xen statusbar) { #define H_gtk_statusbar_get_message_area "GtkWidget* gtk_statusbar_get_message_area(GtkStatusbar* statusbar)" Xen_check_type(Xen_is_GtkStatusbar_(statusbar), statusbar, 1, "gtk_statusbar_get_message_area", "GtkStatusbar*"); return(C_to_Xen_GtkWidget_(gtk_statusbar_get_message_area(Xen_to_C_GtkStatusbar_(statusbar)))); } static Xen gxg_gtk_tool_item_get_ellipsize_mode(Xen tool_item) { #define H_gtk_tool_item_get_ellipsize_mode "PangoEllipsizeMode gtk_tool_item_get_ellipsize_mode(GtkToolItem* tool_item)" Xen_check_type(Xen_is_GtkToolItem_(tool_item), tool_item, 1, "gtk_tool_item_get_ellipsize_mode", "GtkToolItem*"); return(C_to_Xen_PangoEllipsizeMode(gtk_tool_item_get_ellipsize_mode(Xen_to_C_GtkToolItem_(tool_item)))); } static Xen gxg_gtk_tool_item_get_text_alignment(Xen tool_item) { #define H_gtk_tool_item_get_text_alignment "gfloat gtk_tool_item_get_text_alignment(GtkToolItem* tool_item)" Xen_check_type(Xen_is_GtkToolItem_(tool_item), tool_item, 1, "gtk_tool_item_get_text_alignment", "GtkToolItem*"); return(C_to_Xen_gfloat(gtk_tool_item_get_text_alignment(Xen_to_C_GtkToolItem_(tool_item)))); } static Xen gxg_gtk_tool_item_get_text_orientation(Xen tool_item) { #define H_gtk_tool_item_get_text_orientation "GtkOrientation gtk_tool_item_get_text_orientation(GtkToolItem* tool_item)" Xen_check_type(Xen_is_GtkToolItem_(tool_item), tool_item, 1, "gtk_tool_item_get_text_orientation", "GtkToolItem*"); return(C_to_Xen_GtkOrientation(gtk_tool_item_get_text_orientation(Xen_to_C_GtkToolItem_(tool_item)))); } static Xen gxg_gtk_tool_item_get_text_size_group(Xen tool_item) { #define H_gtk_tool_item_get_text_size_group "GtkSizeGroup* gtk_tool_item_get_text_size_group(GtkToolItem* tool_item)" Xen_check_type(Xen_is_GtkToolItem_(tool_item), tool_item, 1, "gtk_tool_item_get_text_size_group", "GtkToolItem*"); return(C_to_Xen_GtkSizeGroup_(gtk_tool_item_get_text_size_group(Xen_to_C_GtkToolItem_(tool_item)))); } static Xen gxg_gtk_tool_palette_new(void) { #define H_gtk_tool_palette_new "GtkWidget* gtk_tool_palette_new( void)" return(C_to_Xen_GtkWidget_(gtk_tool_palette_new())); } static Xen gxg_gtk_tool_palette_set_group_position(Xen palette, Xen group, Xen position) { #define H_gtk_tool_palette_set_group_position "void gtk_tool_palette_set_group_position(GtkToolPalette* palette, \ GtkToolItemGroup* group, gint position)" Xen_check_type(Xen_is_GtkToolPalette_(palette), palette, 1, "gtk_tool_palette_set_group_position", "GtkToolPalette*"); Xen_check_type(Xen_is_GtkToolItemGroup_(group), group, 2, "gtk_tool_palette_set_group_position", "GtkToolItemGroup*"); Xen_check_type(Xen_is_gint(position), position, 3, "gtk_tool_palette_set_group_position", "gint"); gtk_tool_palette_set_group_position(Xen_to_C_GtkToolPalette_(palette), Xen_to_C_GtkToolItemGroup_(group), Xen_to_C_gint(position)); return(Xen_false); } static Xen gxg_gtk_tool_palette_set_exclusive(Xen palette, Xen group, Xen exclusive) { #define H_gtk_tool_palette_set_exclusive "void gtk_tool_palette_set_exclusive(GtkToolPalette* palette, \ GtkToolItemGroup* group, gboolean exclusive)" Xen_check_type(Xen_is_GtkToolPalette_(palette), palette, 1, "gtk_tool_palette_set_exclusive", "GtkToolPalette*"); Xen_check_type(Xen_is_GtkToolItemGroup_(group), group, 2, "gtk_tool_palette_set_exclusive", "GtkToolItemGroup*"); Xen_check_type(Xen_is_gboolean(exclusive), exclusive, 3, "gtk_tool_palette_set_exclusive", "gboolean"); gtk_tool_palette_set_exclusive(Xen_to_C_GtkToolPalette_(palette), Xen_to_C_GtkToolItemGroup_(group), Xen_to_C_gboolean(exclusive)); return(Xen_false); } static Xen gxg_gtk_tool_palette_set_expand(Xen palette, Xen group, Xen expand) { #define H_gtk_tool_palette_set_expand "void gtk_tool_palette_set_expand(GtkToolPalette* palette, GtkToolItemGroup* group, \ gboolean expand)" Xen_check_type(Xen_is_GtkToolPalette_(palette), palette, 1, "gtk_tool_palette_set_expand", "GtkToolPalette*"); Xen_check_type(Xen_is_GtkToolItemGroup_(group), group, 2, "gtk_tool_palette_set_expand", "GtkToolItemGroup*"); Xen_check_type(Xen_is_gboolean(expand), expand, 3, "gtk_tool_palette_set_expand", "gboolean"); gtk_tool_palette_set_expand(Xen_to_C_GtkToolPalette_(palette), Xen_to_C_GtkToolItemGroup_(group), Xen_to_C_gboolean(expand)); return(Xen_false); } static Xen gxg_gtk_tool_palette_get_group_position(Xen palette, Xen group) { #define H_gtk_tool_palette_get_group_position "gint gtk_tool_palette_get_group_position(GtkToolPalette* palette, \ GtkToolItemGroup* group)" Xen_check_type(Xen_is_GtkToolPalette_(palette), palette, 1, "gtk_tool_palette_get_group_position", "GtkToolPalette*"); Xen_check_type(Xen_is_GtkToolItemGroup_(group), group, 2, "gtk_tool_palette_get_group_position", "GtkToolItemGroup*"); return(C_to_Xen_gint(gtk_tool_palette_get_group_position(Xen_to_C_GtkToolPalette_(palette), Xen_to_C_GtkToolItemGroup_(group)))); } static Xen gxg_gtk_tool_palette_get_exclusive(Xen palette, Xen group) { #define H_gtk_tool_palette_get_exclusive "gboolean gtk_tool_palette_get_exclusive(GtkToolPalette* palette, \ GtkToolItemGroup* group)" Xen_check_type(Xen_is_GtkToolPalette_(palette), palette, 1, "gtk_tool_palette_get_exclusive", "GtkToolPalette*"); Xen_check_type(Xen_is_GtkToolItemGroup_(group), group, 2, "gtk_tool_palette_get_exclusive", "GtkToolItemGroup*"); return(C_to_Xen_gboolean(gtk_tool_palette_get_exclusive(Xen_to_C_GtkToolPalette_(palette), Xen_to_C_GtkToolItemGroup_(group)))); } static Xen gxg_gtk_tool_palette_get_expand(Xen palette, Xen group) { #define H_gtk_tool_palette_get_expand "gboolean gtk_tool_palette_get_expand(GtkToolPalette* palette, \ GtkToolItemGroup* group)" Xen_check_type(Xen_is_GtkToolPalette_(palette), palette, 1, "gtk_tool_palette_get_expand", "GtkToolPalette*"); Xen_check_type(Xen_is_GtkToolItemGroup_(group), group, 2, "gtk_tool_palette_get_expand", "GtkToolItemGroup*"); return(C_to_Xen_gboolean(gtk_tool_palette_get_expand(Xen_to_C_GtkToolPalette_(palette), Xen_to_C_GtkToolItemGroup_(group)))); } static Xen gxg_gtk_tool_palette_unset_icon_size(Xen palette) { #define H_gtk_tool_palette_unset_icon_size "void gtk_tool_palette_unset_icon_size(GtkToolPalette* palette)" Xen_check_type(Xen_is_GtkToolPalette_(palette), palette, 1, "gtk_tool_palette_unset_icon_size", "GtkToolPalette*"); gtk_tool_palette_unset_icon_size(Xen_to_C_GtkToolPalette_(palette)); return(Xen_false); } static Xen gxg_gtk_tool_palette_set_style(Xen palette, Xen style) { #define H_gtk_tool_palette_set_style "void gtk_tool_palette_set_style(GtkToolPalette* palette, GtkToolbarStyle style)" Xen_check_type(Xen_is_GtkToolPalette_(palette), palette, 1, "gtk_tool_palette_set_style", "GtkToolPalette*"); Xen_check_type(Xen_is_GtkToolbarStyle(style), style, 2, "gtk_tool_palette_set_style", "GtkToolbarStyle"); gtk_tool_palette_set_style(Xen_to_C_GtkToolPalette_(palette), Xen_to_C_GtkToolbarStyle(style)); return(Xen_false); } static Xen gxg_gtk_tool_palette_unset_style(Xen palette) { #define H_gtk_tool_palette_unset_style "void gtk_tool_palette_unset_style(GtkToolPalette* palette)" Xen_check_type(Xen_is_GtkToolPalette_(palette), palette, 1, "gtk_tool_palette_unset_style", "GtkToolPalette*"); gtk_tool_palette_unset_style(Xen_to_C_GtkToolPalette_(palette)); return(Xen_false); } static Xen gxg_gtk_tool_palette_get_style(Xen palette) { #define H_gtk_tool_palette_get_style "GtkToolbarStyle gtk_tool_palette_get_style(GtkToolPalette* palette)" Xen_check_type(Xen_is_GtkToolPalette_(palette), palette, 1, "gtk_tool_palette_get_style", "GtkToolPalette*"); return(C_to_Xen_GtkToolbarStyle(gtk_tool_palette_get_style(Xen_to_C_GtkToolPalette_(palette)))); } static Xen gxg_gtk_tool_palette_get_drop_item(Xen palette, Xen x, Xen y) { #define H_gtk_tool_palette_get_drop_item "GtkToolItem* gtk_tool_palette_get_drop_item(GtkToolPalette* palette, \ gint x, gint y)" Xen_check_type(Xen_is_GtkToolPalette_(palette), palette, 1, "gtk_tool_palette_get_drop_item", "GtkToolPalette*"); Xen_check_type(Xen_is_gint(x), x, 2, "gtk_tool_palette_get_drop_item", "gint"); Xen_check_type(Xen_is_gint(y), y, 3, "gtk_tool_palette_get_drop_item", "gint"); return(C_to_Xen_GtkToolItem_(gtk_tool_palette_get_drop_item(Xen_to_C_GtkToolPalette_(palette), Xen_to_C_gint(x), Xen_to_C_gint(y)))); } static Xen gxg_gtk_tool_palette_get_drop_group(Xen palette, Xen x, Xen y) { #define H_gtk_tool_palette_get_drop_group "GtkToolItemGroup* gtk_tool_palette_get_drop_group(GtkToolPalette* palette, \ gint x, gint y)" Xen_check_type(Xen_is_GtkToolPalette_(palette), palette, 1, "gtk_tool_palette_get_drop_group", "GtkToolPalette*"); Xen_check_type(Xen_is_gint(x), x, 2, "gtk_tool_palette_get_drop_group", "gint"); Xen_check_type(Xen_is_gint(y), y, 3, "gtk_tool_palette_get_drop_group", "gint"); return(C_to_Xen_GtkToolItemGroup_(gtk_tool_palette_get_drop_group(Xen_to_C_GtkToolPalette_(palette), Xen_to_C_gint(x), Xen_to_C_gint(y)))); } static Xen gxg_gtk_tool_palette_get_drag_item(Xen palette, Xen selection) { #define H_gtk_tool_palette_get_drag_item "GtkWidget* gtk_tool_palette_get_drag_item(GtkToolPalette* palette, \ GtkSelectionData* selection)" Xen_check_type(Xen_is_GtkToolPalette_(palette), palette, 1, "gtk_tool_palette_get_drag_item", "GtkToolPalette*"); Xen_check_type(Xen_is_GtkSelectionData_(selection), selection, 2, "gtk_tool_palette_get_drag_item", "GtkSelectionData*"); return(C_to_Xen_GtkWidget_(gtk_tool_palette_get_drag_item(Xen_to_C_GtkToolPalette_(palette), Xen_to_C_GtkSelectionData_(selection)))); } static Xen gxg_gtk_tool_palette_set_drag_source(Xen palette, Xen targets) { #define H_gtk_tool_palette_set_drag_source "void gtk_tool_palette_set_drag_source(GtkToolPalette* palette, \ GtkToolPaletteDragTargets targets)" Xen_check_type(Xen_is_GtkToolPalette_(palette), palette, 1, "gtk_tool_palette_set_drag_source", "GtkToolPalette*"); Xen_check_type(Xen_is_GtkToolPaletteDragTargets(targets), targets, 2, "gtk_tool_palette_set_drag_source", "GtkToolPaletteDragTargets"); gtk_tool_palette_set_drag_source(Xen_to_C_GtkToolPalette_(palette), Xen_to_C_GtkToolPaletteDragTargets(targets)); return(Xen_false); } static Xen gxg_gtk_tool_palette_add_drag_dest(Xen palette, Xen widget, Xen flags, Xen targets, Xen actions) { #define H_gtk_tool_palette_add_drag_dest "void gtk_tool_palette_add_drag_dest(GtkToolPalette* palette, \ GtkWidget* widget, GtkDestDefaults flags, GtkToolPaletteDragTargets targets, GdkDragAction actions)" Xen_check_type(Xen_is_GtkToolPalette_(palette), palette, 1, "gtk_tool_palette_add_drag_dest", "GtkToolPalette*"); Xen_check_type(Xen_is_GtkWidget_(widget), widget, 2, "gtk_tool_palette_add_drag_dest", "GtkWidget*"); Xen_check_type(Xen_is_GtkDestDefaults(flags), flags, 3, "gtk_tool_palette_add_drag_dest", "GtkDestDefaults"); Xen_check_type(Xen_is_GtkToolPaletteDragTargets(targets), targets, 4, "gtk_tool_palette_add_drag_dest", "GtkToolPaletteDragTargets"); Xen_check_type(Xen_is_GdkDragAction(actions), actions, 5, "gtk_tool_palette_add_drag_dest", "GdkDragAction"); gtk_tool_palette_add_drag_dest(Xen_to_C_GtkToolPalette_(palette), Xen_to_C_GtkWidget_(widget), Xen_to_C_GtkDestDefaults(flags), Xen_to_C_GtkToolPaletteDragTargets(targets), Xen_to_C_GdkDragAction(actions)); return(Xen_false); } static Xen gxg_gtk_tool_palette_get_drag_target_item(void) { #define H_gtk_tool_palette_get_drag_target_item "GtkTargetEntry* gtk_tool_palette_get_drag_target_item( void)" return(C_to_Xen_GtkTargetEntry_((GtkTargetEntry*)gtk_tool_palette_get_drag_target_item())); } static Xen gxg_gtk_tool_palette_get_drag_target_group(void) { #define H_gtk_tool_palette_get_drag_target_group "GtkTargetEntry* gtk_tool_palette_get_drag_target_group( void)" return(C_to_Xen_GtkTargetEntry_((GtkTargetEntry*)gtk_tool_palette_get_drag_target_group())); } static Xen gxg_gtk_tool_item_group_new(Xen label) { #define H_gtk_tool_item_group_new "GtkWidget* gtk_tool_item_group_new(gchar* label)" Xen_check_type(Xen_is_gchar_(label), label, 1, "gtk_tool_item_group_new", "gchar*"); return(C_to_Xen_GtkWidget_(gtk_tool_item_group_new((const gchar*)Xen_to_C_gchar_(label)))); } static Xen gxg_gtk_tool_item_group_set_label(Xen group, Xen label) { #define H_gtk_tool_item_group_set_label "void gtk_tool_item_group_set_label(GtkToolItemGroup* group, \ gchar* label)" Xen_check_type(Xen_is_GtkToolItemGroup_(group), group, 1, "gtk_tool_item_group_set_label", "GtkToolItemGroup*"); Xen_check_type(Xen_is_gchar_(label), label, 2, "gtk_tool_item_group_set_label", "gchar*"); gtk_tool_item_group_set_label(Xen_to_C_GtkToolItemGroup_(group), (const gchar*)Xen_to_C_gchar_(label)); return(Xen_false); } static Xen gxg_gtk_tool_item_group_set_label_widget(Xen group, Xen label_widget) { #define H_gtk_tool_item_group_set_label_widget "void gtk_tool_item_group_set_label_widget(GtkToolItemGroup* group, \ GtkWidget* label_widget)" Xen_check_type(Xen_is_GtkToolItemGroup_(group), group, 1, "gtk_tool_item_group_set_label_widget", "GtkToolItemGroup*"); Xen_check_type(Xen_is_GtkWidget_(label_widget), label_widget, 2, "gtk_tool_item_group_set_label_widget", "GtkWidget*"); gtk_tool_item_group_set_label_widget(Xen_to_C_GtkToolItemGroup_(group), Xen_to_C_GtkWidget_(label_widget)); return(Xen_false); } static Xen gxg_gtk_tool_item_group_set_collapsed(Xen group, Xen collapsed) { #define H_gtk_tool_item_group_set_collapsed "void gtk_tool_item_group_set_collapsed(GtkToolItemGroup* group, \ gboolean collapsed)" Xen_check_type(Xen_is_GtkToolItemGroup_(group), group, 1, "gtk_tool_item_group_set_collapsed", "GtkToolItemGroup*"); Xen_check_type(Xen_is_gboolean(collapsed), collapsed, 2, "gtk_tool_item_group_set_collapsed", "gboolean"); gtk_tool_item_group_set_collapsed(Xen_to_C_GtkToolItemGroup_(group), Xen_to_C_gboolean(collapsed)); return(Xen_false); } static Xen gxg_gtk_tool_item_group_set_ellipsize(Xen group, Xen ellipsize) { #define H_gtk_tool_item_group_set_ellipsize "void gtk_tool_item_group_set_ellipsize(GtkToolItemGroup* group, \ PangoEllipsizeMode ellipsize)" Xen_check_type(Xen_is_GtkToolItemGroup_(group), group, 1, "gtk_tool_item_group_set_ellipsize", "GtkToolItemGroup*"); Xen_check_type(Xen_is_PangoEllipsizeMode(ellipsize), ellipsize, 2, "gtk_tool_item_group_set_ellipsize", "PangoEllipsizeMode"); gtk_tool_item_group_set_ellipsize(Xen_to_C_GtkToolItemGroup_(group), Xen_to_C_PangoEllipsizeMode(ellipsize)); return(Xen_false); } static Xen gxg_gtk_tool_item_group_set_header_relief(Xen group, Xen style) { #define H_gtk_tool_item_group_set_header_relief "void gtk_tool_item_group_set_header_relief(GtkToolItemGroup* group, \ GtkReliefStyle style)" Xen_check_type(Xen_is_GtkToolItemGroup_(group), group, 1, "gtk_tool_item_group_set_header_relief", "GtkToolItemGroup*"); Xen_check_type(Xen_is_GtkReliefStyle(style), style, 2, "gtk_tool_item_group_set_header_relief", "GtkReliefStyle"); gtk_tool_item_group_set_header_relief(Xen_to_C_GtkToolItemGroup_(group), Xen_to_C_GtkReliefStyle(style)); return(Xen_false); } static Xen gxg_gtk_tool_item_group_get_label(Xen group) { #define H_gtk_tool_item_group_get_label "gchar* gtk_tool_item_group_get_label(GtkToolItemGroup* group)" Xen_check_type(Xen_is_GtkToolItemGroup_(group), group, 1, "gtk_tool_item_group_get_label", "GtkToolItemGroup*"); return(C_to_Xen_gchar_(gtk_tool_item_group_get_label(Xen_to_C_GtkToolItemGroup_(group)))); } static Xen gxg_gtk_tool_item_group_get_label_widget(Xen group) { #define H_gtk_tool_item_group_get_label_widget "GtkWidget* gtk_tool_item_group_get_label_widget(GtkToolItemGroup* group)" Xen_check_type(Xen_is_GtkToolItemGroup_(group), group, 1, "gtk_tool_item_group_get_label_widget", "GtkToolItemGroup*"); return(C_to_Xen_GtkWidget_(gtk_tool_item_group_get_label_widget(Xen_to_C_GtkToolItemGroup_(group)))); } static Xen gxg_gtk_tool_item_group_get_collapsed(Xen group) { #define H_gtk_tool_item_group_get_collapsed "gboolean gtk_tool_item_group_get_collapsed(GtkToolItemGroup* group)" Xen_check_type(Xen_is_GtkToolItemGroup_(group), group, 1, "gtk_tool_item_group_get_collapsed", "GtkToolItemGroup*"); return(C_to_Xen_gboolean(gtk_tool_item_group_get_collapsed(Xen_to_C_GtkToolItemGroup_(group)))); } static Xen gxg_gtk_tool_item_group_get_ellipsize(Xen group) { #define H_gtk_tool_item_group_get_ellipsize "PangoEllipsizeMode gtk_tool_item_group_get_ellipsize(GtkToolItemGroup* group)" Xen_check_type(Xen_is_GtkToolItemGroup_(group), group, 1, "gtk_tool_item_group_get_ellipsize", "GtkToolItemGroup*"); return(C_to_Xen_PangoEllipsizeMode(gtk_tool_item_group_get_ellipsize(Xen_to_C_GtkToolItemGroup_(group)))); } static Xen gxg_gtk_tool_item_group_get_header_relief(Xen group) { #define H_gtk_tool_item_group_get_header_relief "GtkReliefStyle gtk_tool_item_group_get_header_relief(GtkToolItemGroup* group)" Xen_check_type(Xen_is_GtkToolItemGroup_(group), group, 1, "gtk_tool_item_group_get_header_relief", "GtkToolItemGroup*"); return(C_to_Xen_GtkReliefStyle(gtk_tool_item_group_get_header_relief(Xen_to_C_GtkToolItemGroup_(group)))); } static Xen gxg_gtk_tool_item_group_insert(Xen group, Xen item, Xen position) { #define H_gtk_tool_item_group_insert "void gtk_tool_item_group_insert(GtkToolItemGroup* group, GtkToolItem* item, \ gint position)" Xen_check_type(Xen_is_GtkToolItemGroup_(group), group, 1, "gtk_tool_item_group_insert", "GtkToolItemGroup*"); Xen_check_type(Xen_is_GtkToolItem_(item), item, 2, "gtk_tool_item_group_insert", "GtkToolItem*"); Xen_check_type(Xen_is_gint(position), position, 3, "gtk_tool_item_group_insert", "gint"); gtk_tool_item_group_insert(Xen_to_C_GtkToolItemGroup_(group), Xen_to_C_GtkToolItem_(item), Xen_to_C_gint(position)); return(Xen_false); } static Xen gxg_gtk_tool_item_group_set_item_position(Xen group, Xen item, Xen position) { #define H_gtk_tool_item_group_set_item_position "void gtk_tool_item_group_set_item_position(GtkToolItemGroup* group, \ GtkToolItem* item, gint position)" Xen_check_type(Xen_is_GtkToolItemGroup_(group), group, 1, "gtk_tool_item_group_set_item_position", "GtkToolItemGroup*"); Xen_check_type(Xen_is_GtkToolItem_(item), item, 2, "gtk_tool_item_group_set_item_position", "GtkToolItem*"); Xen_check_type(Xen_is_gint(position), position, 3, "gtk_tool_item_group_set_item_position", "gint"); gtk_tool_item_group_set_item_position(Xen_to_C_GtkToolItemGroup_(group), Xen_to_C_GtkToolItem_(item), Xen_to_C_gint(position)); return(Xen_false); } static Xen gxg_gtk_tool_item_group_get_item_position(Xen group, Xen item) { #define H_gtk_tool_item_group_get_item_position "gint gtk_tool_item_group_get_item_position(GtkToolItemGroup* group, \ GtkToolItem* item)" Xen_check_type(Xen_is_GtkToolItemGroup_(group), group, 1, "gtk_tool_item_group_get_item_position", "GtkToolItemGroup*"); Xen_check_type(Xen_is_GtkToolItem_(item), item, 2, "gtk_tool_item_group_get_item_position", "GtkToolItem*"); return(C_to_Xen_gint(gtk_tool_item_group_get_item_position(Xen_to_C_GtkToolItemGroup_(group), Xen_to_C_GtkToolItem_(item)))); } static Xen gxg_gtk_tool_item_group_get_n_items(Xen group) { #define H_gtk_tool_item_group_get_n_items "guint gtk_tool_item_group_get_n_items(GtkToolItemGroup* group)" Xen_check_type(Xen_is_GtkToolItemGroup_(group), group, 1, "gtk_tool_item_group_get_n_items", "GtkToolItemGroup*"); return(C_to_Xen_guint(gtk_tool_item_group_get_n_items(Xen_to_C_GtkToolItemGroup_(group)))); } static Xen gxg_gtk_tool_item_group_get_nth_item(Xen group, Xen index) { #define H_gtk_tool_item_group_get_nth_item "GtkToolItem* gtk_tool_item_group_get_nth_item(GtkToolItemGroup* group, \ guint index)" Xen_check_type(Xen_is_GtkToolItemGroup_(group), group, 1, "gtk_tool_item_group_get_nth_item", "GtkToolItemGroup*"); Xen_check_type(Xen_is_guint(index), index, 2, "gtk_tool_item_group_get_nth_item", "guint"); return(C_to_Xen_GtkToolItem_(gtk_tool_item_group_get_nth_item(Xen_to_C_GtkToolItemGroup_(group), Xen_to_C_guint(index)))); } static Xen gxg_gtk_tool_item_group_get_drop_item(Xen group, Xen x, Xen y) { #define H_gtk_tool_item_group_get_drop_item "GtkToolItem* gtk_tool_item_group_get_drop_item(GtkToolItemGroup* group, \ gint x, gint y)" Xen_check_type(Xen_is_GtkToolItemGroup_(group), group, 1, "gtk_tool_item_group_get_drop_item", "GtkToolItemGroup*"); Xen_check_type(Xen_is_gint(x), x, 2, "gtk_tool_item_group_get_drop_item", "gint"); Xen_check_type(Xen_is_gint(y), y, 3, "gtk_tool_item_group_get_drop_item", "gint"); return(C_to_Xen_GtkToolItem_(gtk_tool_item_group_get_drop_item(Xen_to_C_GtkToolItemGroup_(group), Xen_to_C_gint(x), Xen_to_C_gint(y)))); } static Xen gxg_gdk_screen_get_primary_monitor(Xen screen) { #define H_gdk_screen_get_primary_monitor "gint gdk_screen_get_primary_monitor(GdkScreen* screen)" Xen_check_type(Xen_is_GdkScreen_(screen), screen, 1, "gdk_screen_get_primary_monitor", "GdkScreen*"); return(C_to_Xen_gint(gdk_screen_get_primary_monitor(Xen_to_C_GdkScreen_(screen)))); } static Xen gxg_gtk_window_set_mnemonics_visible(Xen window, Xen setting) { #define H_gtk_window_set_mnemonics_visible "void gtk_window_set_mnemonics_visible(GtkWindow* window, \ gboolean setting)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_set_mnemonics_visible", "GtkWindow*"); Xen_check_type(Xen_is_gboolean(setting), setting, 2, "gtk_window_set_mnemonics_visible", "gboolean"); gtk_window_set_mnemonics_visible(Xen_to_C_GtkWindow_(window), Xen_to_C_gboolean(setting)); return(Xen_false); } static Xen gxg_gtk_window_get_mnemonics_visible(Xen window) { #define H_gtk_window_get_mnemonics_visible "gboolean gtk_window_get_mnemonics_visible(GtkWindow* window)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_get_mnemonics_visible", "GtkWindow*"); return(C_to_Xen_gboolean(gtk_window_get_mnemonics_visible(Xen_to_C_GtkWindow_(window)))); } static Xen gxg_gtk_range_set_slider_size_fixed(Xen range, Xen size_fixed) { #define H_gtk_range_set_slider_size_fixed "void gtk_range_set_slider_size_fixed(GtkRange* range, gboolean size_fixed)" Xen_check_type(Xen_is_GtkRange_(range), range, 1, "gtk_range_set_slider_size_fixed", "GtkRange*"); Xen_check_type(Xen_is_gboolean(size_fixed), size_fixed, 2, "gtk_range_set_slider_size_fixed", "gboolean"); gtk_range_set_slider_size_fixed(Xen_to_C_GtkRange_(range), Xen_to_C_gboolean(size_fixed)); return(Xen_false); } static Xen gxg_gtk_range_get_slider_size_fixed(Xen range) { #define H_gtk_range_get_slider_size_fixed "gboolean gtk_range_get_slider_size_fixed(GtkRange* range)" Xen_check_type(Xen_is_GtkRange_(range), range, 1, "gtk_range_get_slider_size_fixed", "GtkRange*"); return(C_to_Xen_gboolean(gtk_range_get_slider_size_fixed(Xen_to_C_GtkRange_(range)))); } static Xen gxg_gtk_range_set_min_slider_size(Xen range, Xen min_size) { #define H_gtk_range_set_min_slider_size "void gtk_range_set_min_slider_size(GtkRange* range, gboolean min_size)" Xen_check_type(Xen_is_GtkRange_(range), range, 1, "gtk_range_set_min_slider_size", "GtkRange*"); Xen_check_type(Xen_is_gboolean(min_size), min_size, 2, "gtk_range_set_min_slider_size", "gboolean"); gtk_range_set_min_slider_size(Xen_to_C_GtkRange_(range), Xen_to_C_gboolean(min_size)); return(Xen_false); } static Xen gxg_gtk_range_get_min_slider_size(Xen range) { #define H_gtk_range_get_min_slider_size "gint gtk_range_get_min_slider_size(GtkRange* range)" Xen_check_type(Xen_is_GtkRange_(range), range, 1, "gtk_range_get_min_slider_size", "GtkRange*"); return(C_to_Xen_gint(gtk_range_get_min_slider_size(Xen_to_C_GtkRange_(range)))); } static Xen gxg_gtk_range_get_range_rect(Xen range, Xen range_rect) { #define H_gtk_range_get_range_rect "void gtk_range_get_range_rect(GtkRange* range, GdkRectangle* range_rect)" Xen_check_type(Xen_is_GtkRange_(range), range, 1, "gtk_range_get_range_rect", "GtkRange*"); Xen_check_type(Xen_is_GdkRectangle_(range_rect), range_rect, 2, "gtk_range_get_range_rect", "GdkRectangle*"); gtk_range_get_range_rect(Xen_to_C_GtkRange_(range), Xen_to_C_GdkRectangle_(range_rect)); return(Xen_false); } static Xen gxg_gtk_range_get_slider_range(Xen range, Xen ignore_slider_start, Xen ignore_slider_end) { #define H_gtk_range_get_slider_range "void gtk_range_get_slider_range(GtkRange* range, gint* [slider_start], \ gint* [slider_end])" gint ref_slider_start; gint ref_slider_end; Xen_check_type(Xen_is_GtkRange_(range), range, 1, "gtk_range_get_slider_range", "GtkRange*"); gtk_range_get_slider_range(Xen_to_C_GtkRange_(range), &ref_slider_start, &ref_slider_end); return(Xen_list_2(C_to_Xen_gint(ref_slider_start), C_to_Xen_gint(ref_slider_end))); } static Xen gxg_gtk_paned_get_handle_window(Xen paned) { #define H_gtk_paned_get_handle_window "GdkWindow* gtk_paned_get_handle_window(GtkPaned* paned)" Xen_check_type(Xen_is_GtkPaned_(paned), paned, 1, "gtk_paned_get_handle_window", "GtkPaned*"); return(C_to_Xen_GdkWindow_(gtk_paned_get_handle_window(Xen_to_C_GtkPaned_(paned)))); } static Xen gxg_gtk_widget_set_realized(Xen widget, Xen realized) { #define H_gtk_widget_set_realized "void gtk_widget_set_realized(GtkWidget* widget, gboolean realized)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_set_realized", "GtkWidget*"); Xen_check_type(Xen_is_gboolean(realized), realized, 2, "gtk_widget_set_realized", "gboolean"); gtk_widget_set_realized(Xen_to_C_GtkWidget_(widget), Xen_to_C_gboolean(realized)); return(Xen_false); } static Xen gxg_gtk_widget_get_realized(Xen widget) { #define H_gtk_widget_get_realized "gboolean gtk_widget_get_realized(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_realized", "GtkWidget*"); return(C_to_Xen_gboolean(gtk_widget_get_realized(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_set_mapped(Xen widget, Xen mapped) { #define H_gtk_widget_set_mapped "void gtk_widget_set_mapped(GtkWidget* widget, gboolean mapped)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_set_mapped", "GtkWidget*"); Xen_check_type(Xen_is_gboolean(mapped), mapped, 2, "gtk_widget_set_mapped", "gboolean"); gtk_widget_set_mapped(Xen_to_C_GtkWidget_(widget), Xen_to_C_gboolean(mapped)); return(Xen_false); } static Xen gxg_gtk_widget_get_mapped(Xen widget) { #define H_gtk_widget_get_mapped "gboolean gtk_widget_get_mapped(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_mapped", "GtkWidget*"); return(C_to_Xen_gboolean(gtk_widget_get_mapped(Xen_to_C_GtkWidget_(widget)))); } #endif #if GTK_CHECK_VERSION(3, 0, 0) static Xen gxg_gdk_cairo_create(Xen window) { #define H_gdk_cairo_create "cairo_t* gdk_cairo_create(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_cairo_create", "GdkWindow*"); return(C_to_Xen_cairo_t_(gdk_cairo_create(Xen_to_C_GdkWindow_(window)))); } static Xen gxg_gdk_window_get_geometry(Xen window, Xen ignore_x, Xen ignore_y, Xen ignore_width, Xen ignore_height) { #define H_gdk_window_get_geometry "void gdk_window_get_geometry(GdkWindow* window, gint* [x], gint* [y], \ gint* [width], gint* [height])" gint ref_x; gint ref_y; gint ref_width; gint ref_height; Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_get_geometry", "GdkWindow*"); gdk_window_get_geometry(Xen_to_C_GdkWindow_(window), &ref_x, &ref_y, &ref_width, &ref_height); return(Xen_list_4(C_to_Xen_gint(ref_x), C_to_Xen_gint(ref_y), C_to_Xen_gint(ref_width), C_to_Xen_gint(ref_height))); } static Xen gxg_gdk_keymap_add_virtual_modifiers(Xen keymap, Xen state) { #define H_gdk_keymap_add_virtual_modifiers "void gdk_keymap_add_virtual_modifiers(GdkKeymap* keymap, \ GdkModifierType* state)" Xen_check_type(Xen_is_GdkKeymap_(keymap), keymap, 1, "gdk_keymap_add_virtual_modifiers", "GdkKeymap*"); Xen_check_type(Xen_is_GdkModifierType_(state), state, 2, "gdk_keymap_add_virtual_modifiers", "GdkModifierType*"); gdk_keymap_add_virtual_modifiers(Xen_to_C_GdkKeymap_(keymap), Xen_to_C_GdkModifierType_(state)); return(Xen_false); } static Xen gxg_gdk_window_coords_to_parent(Xen window, Xen x, Xen y, Xen ignore_parent_x, Xen ignore_parent_y) { #define H_gdk_window_coords_to_parent "void gdk_window_coords_to_parent(GdkWindow* window, gdouble x, \ gdouble y, gdouble* [parent_x], gdouble* [parent_y])" gdouble ref_parent_x; gdouble ref_parent_y; Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_coords_to_parent", "GdkWindow*"); Xen_check_type(Xen_is_gdouble(x), x, 2, "gdk_window_coords_to_parent", "gdouble"); Xen_check_type(Xen_is_gdouble(y), y, 3, "gdk_window_coords_to_parent", "gdouble"); gdk_window_coords_to_parent(Xen_to_C_GdkWindow_(window), Xen_to_C_gdouble(x), Xen_to_C_gdouble(y), &ref_parent_x, &ref_parent_y); return(Xen_list_2(C_to_Xen_gdouble(ref_parent_x), C_to_Xen_gdouble(ref_parent_y))); } static Xen gxg_gdk_window_coords_from_parent(Xen window, Xen parent_x, Xen parent_y, Xen ignore_x, Xen ignore_y) { #define H_gdk_window_coords_from_parent "void gdk_window_coords_from_parent(GdkWindow* window, gdouble parent_x, \ gdouble parent_y, gdouble* [x], gdouble* [y])" gdouble ref_x; gdouble ref_y; Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_coords_from_parent", "GdkWindow*"); Xen_check_type(Xen_is_gdouble(parent_x), parent_x, 2, "gdk_window_coords_from_parent", "gdouble"); Xen_check_type(Xen_is_gdouble(parent_y), parent_y, 3, "gdk_window_coords_from_parent", "gdouble"); gdk_window_coords_from_parent(Xen_to_C_GdkWindow_(window), Xen_to_C_gdouble(parent_x), Xen_to_C_gdouble(parent_y), &ref_x, &ref_y); return(Xen_list_2(C_to_Xen_gdouble(ref_x), C_to_Xen_gdouble(ref_y))); } static Xen gxg_gdk_window_get_effective_parent(Xen window) { #define H_gdk_window_get_effective_parent "GdkWindow* gdk_window_get_effective_parent(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_get_effective_parent", "GdkWindow*"); return(C_to_Xen_GdkWindow_(gdk_window_get_effective_parent(Xen_to_C_GdkWindow_(window)))); } static Xen gxg_gdk_window_get_effective_toplevel(Xen window) { #define H_gdk_window_get_effective_toplevel "GdkWindow* gdk_window_get_effective_toplevel(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_get_effective_toplevel", "GdkWindow*"); return(C_to_Xen_GdkWindow_(gdk_window_get_effective_toplevel(Xen_to_C_GdkWindow_(window)))); } static Xen gxg_gtk_accessible_get_widget(Xen accessible) { #define H_gtk_accessible_get_widget "GtkWidget* gtk_accessible_get_widget(GtkAccessible* accessible)" Xen_check_type(Xen_is_GtkAccessible_(accessible), accessible, 1, "gtk_accessible_get_widget", "GtkAccessible*"); return(C_to_Xen_GtkWidget_(gtk_accessible_get_widget(Xen_to_C_GtkAccessible_(accessible)))); } static Xen gxg_gtk_widget_send_focus_change(Xen widget, Xen event) { #define H_gtk_widget_send_focus_change "gboolean gtk_widget_send_focus_change(GtkWidget* widget, GdkEvent* event)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_send_focus_change", "GtkWidget*"); Xen_check_type(Xen_is_GdkEvent_(event), event, 2, "gtk_widget_send_focus_change", "GdkEvent*"); return(C_to_Xen_gboolean(gtk_widget_send_focus_change(Xen_to_C_GtkWidget_(widget), Xen_to_C_GdkEvent_(event)))); } static Xen gxg_gdk_display_get_device_manager(Xen display) { #define H_gdk_display_get_device_manager "GdkDeviceManager* gdk_display_get_device_manager(GdkDisplay* display)" Xen_check_type(Xen_is_GdkDisplay_(display), display, 1, "gdk_display_get_device_manager", "GdkDisplay*"); return(C_to_Xen_GdkDeviceManager_(gdk_display_get_device_manager(Xen_to_C_GdkDisplay_(display)))); } static Xen gxg_gdk_drag_context_set_device(Xen context, Xen device) { #define H_gdk_drag_context_set_device "void gdk_drag_context_set_device(GdkDragContext* context, GdkDevice* device)" Xen_check_type(Xen_is_GdkDragContext_(context), context, 1, "gdk_drag_context_set_device", "GdkDragContext*"); Xen_check_type(Xen_is_GdkDevice_(device), device, 2, "gdk_drag_context_set_device", "GdkDevice*"); gdk_drag_context_set_device(Xen_to_C_GdkDragContext_(context), Xen_to_C_GdkDevice_(device)); return(Xen_false); } static Xen gxg_gdk_drag_context_get_device(Xen context) { #define H_gdk_drag_context_get_device "GdkDevice* gdk_drag_context_get_device(GdkDragContext* context)" Xen_check_type(Xen_is_GdkDragContext_(context), context, 1, "gdk_drag_context_get_device", "GdkDragContext*"); return(C_to_Xen_GdkDevice_(gdk_drag_context_get_device(Xen_to_C_GdkDragContext_(context)))); } static Xen gxg_gdk_drag_context_list_targets(Xen context) { #define H_gdk_drag_context_list_targets "GList* gdk_drag_context_list_targets(GdkDragContext* context)" Xen_check_type(Xen_is_GdkDragContext_(context), context, 1, "gdk_drag_context_list_targets", "GdkDragContext*"); return(C_to_Xen_GList_(gdk_drag_context_list_targets(Xen_to_C_GdkDragContext_(context)))); } static Xen gxg_gdk_event_set_device(Xen event, Xen device) { #define H_gdk_event_set_device "void gdk_event_set_device(GdkEvent* event, GdkDevice* device)" Xen_check_type(Xen_is_GdkEvent_(event), event, 1, "gdk_event_set_device", "GdkEvent*"); Xen_check_type(Xen_is_GdkDevice_(device), device, 2, "gdk_event_set_device", "GdkDevice*"); gdk_event_set_device(Xen_to_C_GdkEvent_(event), Xen_to_C_GdkDevice_(device)); return(Xen_false); } static Xen gxg_gdk_event_get_device(Xen event) { #define H_gdk_event_get_device "GdkDevice* gdk_event_get_device(GdkEvent* event)" Xen_check_type(Xen_is_GdkEvent_(event), event, 1, "gdk_event_get_device", "GdkEvent*"); return(C_to_Xen_GdkDevice_(gdk_event_get_device(Xen_to_C_GdkEvent_(event)))); } static Xen gxg_gdk_events_get_distance(Xen event1, Xen event2, Xen ignore_distance) { #define H_gdk_events_get_distance "gboolean gdk_events_get_distance(GdkEvent* event1, GdkEvent* event2, \ gdouble* [distance])" gdouble ref_distance; Xen_check_type(Xen_is_GdkEvent_(event1), event1, 1, "gdk_events_get_distance", "GdkEvent*"); Xen_check_type(Xen_is_GdkEvent_(event2), event2, 2, "gdk_events_get_distance", "GdkEvent*"); { Xen result; result = C_to_Xen_gboolean(gdk_events_get_distance(Xen_to_C_GdkEvent_(event1), Xen_to_C_GdkEvent_(event2), &ref_distance)); return(Xen_list_2(result, C_to_Xen_gdouble(ref_distance))); } } static Xen gxg_gdk_events_get_angle(Xen event1, Xen event2, Xen ignore_angle) { #define H_gdk_events_get_angle "gboolean gdk_events_get_angle(GdkEvent* event1, GdkEvent* event2, gdouble* [angle])" gdouble ref_angle; Xen_check_type(Xen_is_GdkEvent_(event1), event1, 1, "gdk_events_get_angle", "GdkEvent*"); Xen_check_type(Xen_is_GdkEvent_(event2), event2, 2, "gdk_events_get_angle", "GdkEvent*"); { Xen result; result = C_to_Xen_gboolean(gdk_events_get_angle(Xen_to_C_GdkEvent_(event1), Xen_to_C_GdkEvent_(event2), &ref_angle)); return(Xen_list_2(result, C_to_Xen_gdouble(ref_angle))); } } static Xen gxg_gdk_events_get_center(Xen event1, Xen event2, Xen ignore_x, Xen ignore_y) { #define H_gdk_events_get_center "gboolean gdk_events_get_center(GdkEvent* event1, GdkEvent* event2, \ gdouble* [x], gdouble* [y])" gdouble ref_x; gdouble ref_y; Xen_check_type(Xen_is_GdkEvent_(event1), event1, 1, "gdk_events_get_center", "GdkEvent*"); Xen_check_type(Xen_is_GdkEvent_(event2), event2, 2, "gdk_events_get_center", "GdkEvent*"); { Xen result; result = C_to_Xen_gboolean(gdk_events_get_center(Xen_to_C_GdkEvent_(event1), Xen_to_C_GdkEvent_(event2), &ref_x, &ref_y)); return(Xen_list_3(result, C_to_Xen_gdouble(ref_x), C_to_Xen_gdouble(ref_y))); } } static Xen gxg_gdk_window_get_accept_focus(Xen window) { #define H_gdk_window_get_accept_focus "gboolean gdk_window_get_accept_focus(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_get_accept_focus", "GdkWindow*"); return(C_to_Xen_gboolean(gdk_window_get_accept_focus(Xen_to_C_GdkWindow_(window)))); } static Xen gxg_gdk_window_get_focus_on_map(Xen window) { #define H_gdk_window_get_focus_on_map "gboolean gdk_window_get_focus_on_map(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_get_focus_on_map", "GdkWindow*"); return(C_to_Xen_gboolean(gdk_window_get_focus_on_map(Xen_to_C_GdkWindow_(window)))); } static Xen gxg_gdk_window_is_input_only(Xen window) { #define H_gdk_window_is_input_only "gboolean gdk_window_is_input_only(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_is_input_only", "GdkWindow*"); return(C_to_Xen_gboolean(gdk_window_is_input_only(Xen_to_C_GdkWindow_(window)))); } static Xen gxg_gdk_window_is_shaped(Xen window) { #define H_gdk_window_is_shaped "gboolean gdk_window_is_shaped(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_is_shaped", "GdkWindow*"); return(C_to_Xen_gboolean(gdk_window_is_shaped(Xen_to_C_GdkWindow_(window)))); } static Xen gxg_gdk_window_get_modal_hint(Xen window) { #define H_gdk_window_get_modal_hint "gboolean gdk_window_get_modal_hint(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_get_modal_hint", "GdkWindow*"); return(C_to_Xen_gboolean(gdk_window_get_modal_hint(Xen_to_C_GdkWindow_(window)))); } static Xen gxg_gdk_window_set_device_cursor(Xen window, Xen device, Xen cursor) { #define H_gdk_window_set_device_cursor "void gdk_window_set_device_cursor(GdkWindow* window, GdkDevice* device, \ GdkCursor* cursor)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_set_device_cursor", "GdkWindow*"); Xen_check_type(Xen_is_GdkDevice_(device), device, 2, "gdk_window_set_device_cursor", "GdkDevice*"); Xen_check_type(Xen_is_GdkCursor_(cursor), cursor, 3, "gdk_window_set_device_cursor", "GdkCursor*"); gdk_window_set_device_cursor(Xen_to_C_GdkWindow_(window), Xen_to_C_GdkDevice_(device), Xen_to_C_GdkCursor_(cursor)); return(Xen_false); } static Xen gxg_gdk_window_get_device_cursor(Xen window, Xen device) { #define H_gdk_window_get_device_cursor "GdkCursor* gdk_window_get_device_cursor(GdkWindow* window, \ GdkDevice* device)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_get_device_cursor", "GdkWindow*"); Xen_check_type(Xen_is_GdkDevice_(device), device, 2, "gdk_window_get_device_cursor", "GdkDevice*"); return(C_to_Xen_GdkCursor_(gdk_window_get_device_cursor(Xen_to_C_GdkWindow_(window), Xen_to_C_GdkDevice_(device)))); } static Xen gxg_gdk_window_get_device_position(Xen window, Xen device, Xen ignore_x, Xen ignore_y, Xen ignore_mask) { #define H_gdk_window_get_device_position "GdkWindow* gdk_window_get_device_position(GdkWindow* window, \ GdkDevice* device, gint* [x], gint* [y], GdkModifierType* [mask])" gint ref_x; gint ref_y; GdkModifierType ref_mask; Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_get_device_position", "GdkWindow*"); Xen_check_type(Xen_is_GdkDevice_(device), device, 2, "gdk_window_get_device_position", "GdkDevice*"); { Xen result; result = C_to_Xen_GdkWindow_(gdk_window_get_device_position(Xen_to_C_GdkWindow_(window), Xen_to_C_GdkDevice_(device), &ref_x, &ref_y, &ref_mask)); return(Xen_list_4(result, C_to_Xen_gint(ref_x), C_to_Xen_gint(ref_y), C_to_Xen_GdkModifierType(ref_mask))); } } static Xen gxg_gdk_window_set_device_events(Xen window, Xen device, Xen event_mask) { #define H_gdk_window_set_device_events "void gdk_window_set_device_events(GdkWindow* window, GdkDevice* device, \ GdkEventMask event_mask)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_set_device_events", "GdkWindow*"); Xen_check_type(Xen_is_GdkDevice_(device), device, 2, "gdk_window_set_device_events", "GdkDevice*"); Xen_check_type(Xen_is_GdkEventMask(event_mask), event_mask, 3, "gdk_window_set_device_events", "GdkEventMask"); gdk_window_set_device_events(Xen_to_C_GdkWindow_(window), Xen_to_C_GdkDevice_(device), Xen_to_C_GdkEventMask(event_mask)); return(Xen_false); } static Xen gxg_gdk_window_get_device_events(Xen window, Xen device) { #define H_gdk_window_get_device_events "GdkEventMask gdk_window_get_device_events(GdkWindow* window, \ GdkDevice* device)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_get_device_events", "GdkWindow*"); Xen_check_type(Xen_is_GdkDevice_(device), device, 2, "gdk_window_get_device_events", "GdkDevice*"); return(C_to_Xen_GdkEventMask(gdk_window_get_device_events(Xen_to_C_GdkWindow_(window), Xen_to_C_GdkDevice_(device)))); } static Xen gxg_gtk_combo_box_popup_for_device(Xen combo_box, Xen device) { #define H_gtk_combo_box_popup_for_device "void gtk_combo_box_popup_for_device(GtkComboBox* combo_box, \ GdkDevice* device)" Xen_check_type(Xen_is_GtkComboBox_(combo_box), combo_box, 1, "gtk_combo_box_popup_for_device", "GtkComboBox*"); Xen_check_type(Xen_is_GdkDevice_(device), device, 2, "gtk_combo_box_popup_for_device", "GdkDevice*"); gtk_combo_box_popup_for_device(Xen_to_C_GtkComboBox_(combo_box), Xen_to_C_GdkDevice_(device)); return(Xen_false); } static Xen gxg_gtk_device_grab_add(Xen widget, Xen device, Xen block_others) { #define H_gtk_device_grab_add "void gtk_device_grab_add(GtkWidget* widget, GdkDevice* device, gboolean block_others)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_device_grab_add", "GtkWidget*"); Xen_check_type(Xen_is_GdkDevice_(device), device, 2, "gtk_device_grab_add", "GdkDevice*"); Xen_check_type(Xen_is_gboolean(block_others), block_others, 3, "gtk_device_grab_add", "gboolean"); gtk_device_grab_add(Xen_to_C_GtkWidget_(widget), Xen_to_C_GdkDevice_(device), Xen_to_C_gboolean(block_others)); return(Xen_false); } static Xen gxg_gtk_device_grab_remove(Xen widget, Xen device) { #define H_gtk_device_grab_remove "void gtk_device_grab_remove(GtkWidget* widget, GdkDevice* device)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_device_grab_remove", "GtkWidget*"); Xen_check_type(Xen_is_GdkDevice_(device), device, 2, "gtk_device_grab_remove", "GdkDevice*"); gtk_device_grab_remove(Xen_to_C_GtkWidget_(widget), Xen_to_C_GdkDevice_(device)); return(Xen_false); } static Xen gxg_gtk_get_current_event_device(void) { #define H_gtk_get_current_event_device "GdkDevice* gtk_get_current_event_device( void)" return(C_to_Xen_GdkDevice_(gtk_get_current_event_device())); } static Xen gxg_gtk_paned_new(Xen orientation) { #define H_gtk_paned_new "GtkWidget* gtk_paned_new(GtkOrientation orientation)" Xen_check_type(Xen_is_GtkOrientation(orientation), orientation, 1, "gtk_paned_new", "GtkOrientation"); return(C_to_Xen_GtkWidget_(gtk_paned_new(Xen_to_C_GtkOrientation(orientation)))); } static Xen gxg_gtk_scale_new(Xen orientation, Xen adjustment) { #define H_gtk_scale_new "GtkWidget* gtk_scale_new(GtkOrientation orientation, GtkAdjustment* adjustment)" Xen_check_type(Xen_is_GtkOrientation(orientation), orientation, 1, "gtk_scale_new", "GtkOrientation"); Xen_check_type(Xen_is_GtkAdjustment_(adjustment), adjustment, 2, "gtk_scale_new", "GtkAdjustment*"); return(C_to_Xen_GtkWidget_(gtk_scale_new(Xen_to_C_GtkOrientation(orientation), Xen_to_C_GtkAdjustment_(adjustment)))); } static Xen gxg_gtk_scale_new_with_range(Xen orientation, Xen min, Xen max, Xen step) { #define H_gtk_scale_new_with_range "GtkWidget* gtk_scale_new_with_range(GtkOrientation orientation, \ gdouble min, gdouble max, gdouble step)" Xen_check_type(Xen_is_GtkOrientation(orientation), orientation, 1, "gtk_scale_new_with_range", "GtkOrientation"); Xen_check_type(Xen_is_gdouble(min), min, 2, "gtk_scale_new_with_range", "gdouble"); Xen_check_type(Xen_is_gdouble(max), max, 3, "gtk_scale_new_with_range", "gdouble"); Xen_check_type(Xen_is_gdouble(step), step, 4, "gtk_scale_new_with_range", "gdouble"); return(C_to_Xen_GtkWidget_(gtk_scale_new_with_range(Xen_to_C_GtkOrientation(orientation), Xen_to_C_gdouble(min), Xen_to_C_gdouble(max), Xen_to_C_gdouble(step)))); } static Xen gxg_gtk_scrollbar_new(Xen orientation, Xen adjustment) { #define H_gtk_scrollbar_new "GtkWidget* gtk_scrollbar_new(GtkOrientation orientation, GtkAdjustment* adjustment)" Xen_check_type(Xen_is_GtkOrientation(orientation), orientation, 1, "gtk_scrollbar_new", "GtkOrientation"); Xen_check_type(Xen_is_GtkAdjustment_(adjustment), adjustment, 2, "gtk_scrollbar_new", "GtkAdjustment*"); return(C_to_Xen_GtkWidget_(gtk_scrollbar_new(Xen_to_C_GtkOrientation(orientation), Xen_to_C_GtkAdjustment_(adjustment)))); } static Xen gxg_gtk_separator_new(Xen orientation) { #define H_gtk_separator_new "GtkWidget* gtk_separator_new(GtkOrientation orientation)" Xen_check_type(Xen_is_GtkOrientation(orientation), orientation, 1, "gtk_separator_new", "GtkOrientation"); return(C_to_Xen_GtkWidget_(gtk_separator_new(Xen_to_C_GtkOrientation(orientation)))); } static Xen gxg_gtk_widget_device_is_shadowed(Xen widget, Xen device) { #define H_gtk_widget_device_is_shadowed "gboolean gtk_widget_device_is_shadowed(GtkWidget* widget, \ GdkDevice* device)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_device_is_shadowed", "GtkWidget*"); Xen_check_type(Xen_is_GdkDevice_(device), device, 2, "gtk_widget_device_is_shadowed", "GdkDevice*"); return(C_to_Xen_gboolean(gtk_widget_device_is_shadowed(Xen_to_C_GtkWidget_(widget), Xen_to_C_GdkDevice_(device)))); } static Xen gxg_gtk_widget_set_device_events(Xen widget, Xen device, Xen events) { #define H_gtk_widget_set_device_events "void gtk_widget_set_device_events(GtkWidget* widget, GdkDevice* device, \ GdkEventMask events)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_set_device_events", "GtkWidget*"); Xen_check_type(Xen_is_GdkDevice_(device), device, 2, "gtk_widget_set_device_events", "GdkDevice*"); Xen_check_type(Xen_is_GdkEventMask(events), events, 3, "gtk_widget_set_device_events", "GdkEventMask"); gtk_widget_set_device_events(Xen_to_C_GtkWidget_(widget), Xen_to_C_GdkDevice_(device), Xen_to_C_GdkEventMask(events)); return(Xen_false); } static Xen gxg_gtk_widget_add_device_events(Xen widget, Xen device, Xen events) { #define H_gtk_widget_add_device_events "void gtk_widget_add_device_events(GtkWidget* widget, GdkDevice* device, \ GdkEventMask events)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_add_device_events", "GtkWidget*"); Xen_check_type(Xen_is_GdkDevice_(device), device, 2, "gtk_widget_add_device_events", "GdkDevice*"); Xen_check_type(Xen_is_GdkEventMask(events), events, 3, "gtk_widget_add_device_events", "GdkEventMask"); gtk_widget_add_device_events(Xen_to_C_GtkWidget_(widget), Xen_to_C_GdkDevice_(device), Xen_to_C_GdkEventMask(events)); return(Xen_false); } static Xen gxg_gtk_widget_get_support_multidevice(Xen widget) { #define H_gtk_widget_get_support_multidevice "gboolean gtk_widget_get_support_multidevice(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_support_multidevice", "GtkWidget*"); return(C_to_Xen_gboolean(gtk_widget_get_support_multidevice(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_set_support_multidevice(Xen widget, Xen support_multidevice) { #define H_gtk_widget_set_support_multidevice "void gtk_widget_set_support_multidevice(GtkWidget* widget, \ gboolean support_multidevice)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_set_support_multidevice", "GtkWidget*"); Xen_check_type(Xen_is_gboolean(support_multidevice), support_multidevice, 2, "gtk_widget_set_support_multidevice", "gboolean"); gtk_widget_set_support_multidevice(Xen_to_C_GtkWidget_(widget), Xen_to_C_gboolean(support_multidevice)); return(Xen_false); } static Xen gxg_gtk_widget_get_device_events(Xen widget, Xen device) { #define H_gtk_widget_get_device_events "GdkEventMask gtk_widget_get_device_events(GtkWidget* widget, \ GdkDevice* device)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_device_events", "GtkWidget*"); Xen_check_type(Xen_is_GdkDevice_(device), device, 2, "gtk_widget_get_device_events", "GdkDevice*"); return(C_to_Xen_GdkEventMask(gtk_widget_get_device_events(Xen_to_C_GtkWidget_(widget), Xen_to_C_GdkDevice_(device)))); } static Xen gxg_gtk_icon_view_get_item_row(Xen icon_view, Xen path) { #define H_gtk_icon_view_get_item_row "gint gtk_icon_view_get_item_row(GtkIconView* icon_view, GtkTreePath* path)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_get_item_row", "GtkIconView*"); Xen_check_type(Xen_is_GtkTreePath_(path), path, 2, "gtk_icon_view_get_item_row", "GtkTreePath*"); return(C_to_Xen_gint(gtk_icon_view_get_item_row(Xen_to_C_GtkIconView_(icon_view), Xen_to_C_GtkTreePath_(path)))); } static Xen gxg_gtk_icon_view_get_item_column(Xen icon_view, Xen path) { #define H_gtk_icon_view_get_item_column "gint gtk_icon_view_get_item_column(GtkIconView* icon_view, \ GtkTreePath* path)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_get_item_column", "GtkIconView*"); Xen_check_type(Xen_is_GtkTreePath_(path), path, 2, "gtk_icon_view_get_item_column", "GtkTreePath*"); return(C_to_Xen_gint(gtk_icon_view_get_item_column(Xen_to_C_GtkIconView_(icon_view), Xen_to_C_GtkTreePath_(path)))); } static Xen gxg_gtk_statusbar_remove_all(Xen statusbar, Xen context_id) { #define H_gtk_statusbar_remove_all "void gtk_statusbar_remove_all(GtkStatusbar* statusbar, guint context_id)" Xen_check_type(Xen_is_GtkStatusbar_(statusbar), statusbar, 1, "gtk_statusbar_remove_all", "GtkStatusbar*"); Xen_check_type(Xen_is_guint(context_id), context_id, 2, "gtk_statusbar_remove_all", "guint"); gtk_statusbar_remove_all(Xen_to_C_GtkStatusbar_(statusbar), Xen_to_C_guint(context_id)); return(Xen_false); } static Xen gxg_gtk_window_has_group(Xen window) { #define H_gtk_window_has_group "gboolean gtk_window_has_group(GtkWindow* window)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_has_group", "GtkWindow*"); return(C_to_Xen_gboolean(gtk_window_has_group(Xen_to_C_GtkWindow_(window)))); } static Xen gxg_gtk_calendar_select_month(Xen calendar, Xen month, Xen year) { #define H_gtk_calendar_select_month "void gtk_calendar_select_month(GtkCalendar* calendar, guint month, \ guint year)" Xen_check_type(Xen_is_GtkCalendar_(calendar), calendar, 1, "gtk_calendar_select_month", "GtkCalendar*"); Xen_check_type(Xen_is_guint(month), month, 2, "gtk_calendar_select_month", "guint"); Xen_check_type(Xen_is_guint(year), year, 3, "gtk_calendar_select_month", "guint"); gtk_calendar_select_month(Xen_to_C_GtkCalendar_(calendar), Xen_to_C_guint(month), Xen_to_C_guint(year)); return(Xen_false); } static Xen gxg_gtk_calendar_mark_day(Xen calendar, Xen day) { #define H_gtk_calendar_mark_day "void gtk_calendar_mark_day(GtkCalendar* calendar, guint day)" Xen_check_type(Xen_is_GtkCalendar_(calendar), calendar, 1, "gtk_calendar_mark_day", "GtkCalendar*"); Xen_check_type(Xen_is_guint(day), day, 2, "gtk_calendar_mark_day", "guint"); gtk_calendar_mark_day(Xen_to_C_GtkCalendar_(calendar), Xen_to_C_guint(day)); return(Xen_false); } static Xen gxg_gtk_calendar_unmark_day(Xen calendar, Xen day) { #define H_gtk_calendar_unmark_day "void gtk_calendar_unmark_day(GtkCalendar* calendar, guint day)" Xen_check_type(Xen_is_GtkCalendar_(calendar), calendar, 1, "gtk_calendar_unmark_day", "GtkCalendar*"); Xen_check_type(Xen_is_guint(day), day, 2, "gtk_calendar_unmark_day", "guint"); gtk_calendar_unmark_day(Xen_to_C_GtkCalendar_(calendar), Xen_to_C_guint(day)); return(Xen_false); } static Xen gxg_gdk_drag_context_get_source_window(Xen context) { #define H_gdk_drag_context_get_source_window "GdkWindow* gdk_drag_context_get_source_window(GdkDragContext* context)" Xen_check_type(Xen_is_GdkDragContext_(context), context, 1, "gdk_drag_context_get_source_window", "GdkDragContext*"); return(C_to_Xen_GdkWindow_(gdk_drag_context_get_source_window(Xen_to_C_GdkDragContext_(context)))); } static Xen gxg_gtk_viewport_get_view_window(Xen viewport) { #define H_gtk_viewport_get_view_window "GdkWindow* gtk_viewport_get_view_window(GtkViewport* viewport)" Xen_check_type(Xen_is_GtkViewport_(viewport), viewport, 1, "gtk_viewport_get_view_window", "GtkViewport*"); return(C_to_Xen_GdkWindow_(gtk_viewport_get_view_window(Xen_to_C_GtkViewport_(viewport)))); } static Xen gxg_gtk_accessible_set_widget(Xen accessible, Xen widget) { #define H_gtk_accessible_set_widget "void gtk_accessible_set_widget(GtkAccessible* accessible, GtkWidget* widget)" Xen_check_type(Xen_is_GtkAccessible_(accessible), accessible, 1, "gtk_accessible_set_widget", "GtkAccessible*"); Xen_check_type(Xen_is_GtkWidget_(widget), widget, 2, "gtk_accessible_set_widget", "GtkWidget*"); gtk_accessible_set_widget(Xen_to_C_GtkAccessible_(accessible), Xen_to_C_GtkWidget_(widget)); return(Xen_false); } static Xen gxg_gtk_button_get_event_window(Xen button) { #define H_gtk_button_get_event_window "GdkWindow* gtk_button_get_event_window(GtkButton* button)" Xen_check_type(Xen_is_GtkButton_(button), button, 1, "gtk_button_get_event_window", "GtkButton*"); return(C_to_Xen_GdkWindow_(gtk_button_get_event_window(Xen_to_C_GtkButton_(button)))); } static Xen gxg_gtk_message_dialog_get_message_area(Xen message_dialog) { #define H_gtk_message_dialog_get_message_area "GtkWidget* gtk_message_dialog_get_message_area(GtkMessageDialog* message_dialog)" Xen_check_type(Xen_is_GtkMessageDialog_(message_dialog), message_dialog, 1, "gtk_message_dialog_get_message_area", "GtkMessageDialog*"); return(C_to_Xen_GtkWidget_(gtk_message_dialog_get_message_area(Xen_to_C_GtkMessageDialog_(message_dialog)))); } static Xen gxg_gtk_selection_data_get_length(Xen selection_data) { #define H_gtk_selection_data_get_length "gint gtk_selection_data_get_length(GtkSelectionData* selection_data)" Xen_check_type(Xen_is_GtkSelectionData_(selection_data), selection_data, 1, "gtk_selection_data_get_length", "GtkSelectionData*"); return(C_to_Xen_gint(gtk_selection_data_get_length(Xen_to_C_GtkSelectionData_(selection_data)))); } static Xen gxg_gdk_pango_layout_line_get_clip_region(Xen line, Xen x_origin, Xen y_origin, Xen index_ranges, Xen n_ranges) { #define H_gdk_pango_layout_line_get_clip_region "cairo_region_t* gdk_pango_layout_line_get_clip_region(PangoLayoutLine* line, \ gint x_origin, gint y_origin, gint* index_ranges, gint n_ranges)" Xen_check_type(Xen_is_PangoLayoutLine_(line), line, 1, "gdk_pango_layout_line_get_clip_region", "PangoLayoutLine*"); Xen_check_type(Xen_is_gint(x_origin), x_origin, 2, "gdk_pango_layout_line_get_clip_region", "gint"); Xen_check_type(Xen_is_gint(y_origin), y_origin, 3, "gdk_pango_layout_line_get_clip_region", "gint"); Xen_check_type(Xen_is_gint_(index_ranges), index_ranges, 4, "gdk_pango_layout_line_get_clip_region", "gint*"); Xen_check_type(Xen_is_gint(n_ranges), n_ranges, 5, "gdk_pango_layout_line_get_clip_region", "gint"); return(C_to_Xen_cairo_region_t_(gdk_pango_layout_line_get_clip_region(Xen_to_C_PangoLayoutLine_(line), Xen_to_C_gint(x_origin), Xen_to_C_gint(y_origin), Xen_to_C_gint_(index_ranges), Xen_to_C_gint(n_ranges)))); } static Xen gxg_gdk_pango_layout_get_clip_region(Xen layout, Xen x_origin, Xen y_origin, Xen index_ranges, Xen n_ranges) { #define H_gdk_pango_layout_get_clip_region "cairo_region_t* gdk_pango_layout_get_clip_region(PangoLayout* layout, \ gint x_origin, gint y_origin, gint* index_ranges, gint n_ranges)" Xen_check_type(Xen_is_PangoLayout_(layout), layout, 1, "gdk_pango_layout_get_clip_region", "PangoLayout*"); Xen_check_type(Xen_is_gint(x_origin), x_origin, 2, "gdk_pango_layout_get_clip_region", "gint"); Xen_check_type(Xen_is_gint(y_origin), y_origin, 3, "gdk_pango_layout_get_clip_region", "gint"); Xen_check_type(Xen_is_gint_(index_ranges), index_ranges, 4, "gdk_pango_layout_get_clip_region", "gint*"); Xen_check_type(Xen_is_gint(n_ranges), n_ranges, 5, "gdk_pango_layout_get_clip_region", "gint"); return(C_to_Xen_cairo_region_t_(gdk_pango_layout_get_clip_region(Xen_to_C_PangoLayout_(layout), Xen_to_C_gint(x_origin), Xen_to_C_gint(y_origin), Xen_to_C_gint_(index_ranges), Xen_to_C_gint(n_ranges)))); } static Xen gxg_gdk_window_shape_combine_region(Xen window, Xen shape_region, Xen offset_x, Xen offset_y) { #define H_gdk_window_shape_combine_region "void gdk_window_shape_combine_region(GdkWindow* window, \ cairo_region_t* shape_region, gint offset_x, gint offset_y)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_shape_combine_region", "GdkWindow*"); Xen_check_type(Xen_is_cairo_region_t_(shape_region), shape_region, 2, "gdk_window_shape_combine_region", "cairo_region_t*"); Xen_check_type(Xen_is_gint(offset_x), offset_x, 3, "gdk_window_shape_combine_region", "gint"); Xen_check_type(Xen_is_gint(offset_y), offset_y, 4, "gdk_window_shape_combine_region", "gint"); gdk_window_shape_combine_region(Xen_to_C_GdkWindow_(window), Xen_to_C_cairo_region_t_(shape_region), Xen_to_C_gint(offset_x), Xen_to_C_gint(offset_y)); return(Xen_false); } static Xen gxg_gdk_window_invalidate_region(Xen window, Xen region, Xen invalidate_children) { #define H_gdk_window_invalidate_region "void gdk_window_invalidate_region(GdkWindow* window, cairo_region_t* region, \ gboolean invalidate_children)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_invalidate_region", "GdkWindow*"); Xen_check_type(Xen_is_cairo_region_t_(region), region, 2, "gdk_window_invalidate_region", "cairo_region_t*"); Xen_check_type(Xen_is_gboolean(invalidate_children), invalidate_children, 3, "gdk_window_invalidate_region", "gboolean"); gdk_window_invalidate_region(Xen_to_C_GdkWindow_(window), Xen_to_C_cairo_region_t_(region), Xen_to_C_gboolean(invalidate_children)); return(Xen_false); } static Xen gxg_gdk_window_get_update_area(Xen window) { #define H_gdk_window_get_update_area "cairo_region_t* gdk_window_get_update_area(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_get_update_area", "GdkWindow*"); return(C_to_Xen_cairo_region_t_(gdk_window_get_update_area(Xen_to_C_GdkWindow_(window)))); } static Xen gxg_gdk_window_begin_paint_region(Xen window, Xen region) { #define H_gdk_window_begin_paint_region "void gdk_window_begin_paint_region(GdkWindow* window, cairo_region_t* region)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_begin_paint_region", "GdkWindow*"); Xen_check_type(Xen_is_cairo_region_t_(region), region, 2, "gdk_window_begin_paint_region", "cairo_region_t*"); gdk_window_begin_paint_region(Xen_to_C_GdkWindow_(window), Xen_to_C_cairo_region_t_(region)); return(Xen_false); } static Xen gxg_gdk_window_move_region(Xen window, Xen region, Xen dx, Xen dy) { #define H_gdk_window_move_region "void gdk_window_move_region(GdkWindow* window, cairo_region_t* region, \ gint dx, gint dy)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_move_region", "GdkWindow*"); Xen_check_type(Xen_is_cairo_region_t_(region), region, 2, "gdk_window_move_region", "cairo_region_t*"); Xen_check_type(Xen_is_gint(dx), dx, 3, "gdk_window_move_region", "gint"); Xen_check_type(Xen_is_gint(dy), dy, 4, "gdk_window_move_region", "gint"); gdk_window_move_region(Xen_to_C_GdkWindow_(window), Xen_to_C_cairo_region_t_(region), Xen_to_C_gint(dx), Xen_to_C_gint(dy)); return(Xen_false); } static Xen gxg_gdk_keymap_get_num_lock_state(Xen keymap) { #define H_gdk_keymap_get_num_lock_state "gboolean gdk_keymap_get_num_lock_state(GdkKeymap* keymap)" Xen_check_type(Xen_is_GdkKeymap_(keymap), keymap, 1, "gdk_keymap_get_num_lock_state", "GdkKeymap*"); return(C_to_Xen_gboolean(gdk_keymap_get_num_lock_state(Xen_to_C_GdkKeymap_(keymap)))); } static Xen gxg_gdk_window_has_native(Xen window) { #define H_gdk_window_has_native "gboolean gdk_window_has_native(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_has_native", "GdkWindow*"); return(C_to_Xen_gboolean(gdk_window_has_native(Xen_to_C_GdkWindow_(window)))); } static Xen gxg_gdk_cursor_get_cursor_type(Xen cursor) { #define H_gdk_cursor_get_cursor_type "GdkCursorType gdk_cursor_get_cursor_type(GdkCursor* cursor)" Xen_check_type(Xen_is_GdkCursor_(cursor), cursor, 1, "gdk_cursor_get_cursor_type", "GdkCursor*"); return(C_to_Xen_GdkCursorType(gdk_cursor_get_cursor_type(Xen_to_C_GdkCursor_(cursor)))); } static Xen gxg_gdk_display_is_closed(Xen display) { #define H_gdk_display_is_closed "gboolean gdk_display_is_closed(GdkDisplay* display)" Xen_check_type(Xen_is_GdkDisplay_(display), display, 1, "gdk_display_is_closed", "GdkDisplay*"); return(C_to_Xen_gboolean(gdk_display_is_closed(Xen_to_C_GdkDisplay_(display)))); } static Xen gxg_gdk_window_get_background_pattern(Xen window) { #define H_gdk_window_get_background_pattern "cairo_pattern_t* gdk_window_get_background_pattern(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_get_background_pattern", "GdkWindow*"); return(C_to_Xen_cairo_pattern_t_(gdk_window_get_background_pattern(Xen_to_C_GdkWindow_(window)))); } static Xen gxg_gdk_window_create_similar_surface(Xen window, Xen content, Xen width, Xen height) { #define H_gdk_window_create_similar_surface "cairo_surface_t* gdk_window_create_similar_surface(GdkWindow* window, \ cairo_content_t content, int width, int height)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_create_similar_surface", "GdkWindow*"); Xen_check_type(Xen_is_cairo_content_t(content), content, 2, "gdk_window_create_similar_surface", "cairo_content_t"); Xen_check_type(Xen_is_int(width), width, 3, "gdk_window_create_similar_surface", "int"); Xen_check_type(Xen_is_int(height), height, 4, "gdk_window_create_similar_surface", "int"); return(C_to_Xen_cairo_surface_t_(gdk_window_create_similar_surface(Xen_to_C_GdkWindow_(window), Xen_to_C_cairo_content_t(content), Xen_to_C_int(width), Xen_to_C_int(height)))); } static Xen gxg_gtk_expander_set_label_fill(Xen expander, Xen label_fill) { #define H_gtk_expander_set_label_fill "void gtk_expander_set_label_fill(GtkExpander* expander, gboolean label_fill)" Xen_check_type(Xen_is_GtkExpander_(expander), expander, 1, "gtk_expander_set_label_fill", "GtkExpander*"); Xen_check_type(Xen_is_gboolean(label_fill), label_fill, 2, "gtk_expander_set_label_fill", "gboolean"); gtk_expander_set_label_fill(Xen_to_C_GtkExpander_(expander), Xen_to_C_gboolean(label_fill)); return(Xen_false); } static Xen gxg_gtk_expander_get_label_fill(Xen expander) { #define H_gtk_expander_get_label_fill "gboolean gtk_expander_get_label_fill(GtkExpander* expander)" Xen_check_type(Xen_is_GtkExpander_(expander), expander, 1, "gtk_expander_get_label_fill", "GtkExpander*"); return(C_to_Xen_gboolean(gtk_expander_get_label_fill(Xen_to_C_GtkExpander_(expander)))); } static Xen gxg_gtk_calendar_get_day_is_marked(Xen calendar, Xen day) { #define H_gtk_calendar_get_day_is_marked "gboolean gtk_calendar_get_day_is_marked(GtkCalendar* calendar, \ guint day)" Xen_check_type(Xen_is_GtkCalendar_(calendar), calendar, 1, "gtk_calendar_get_day_is_marked", "GtkCalendar*"); Xen_check_type(Xen_is_guint(day), day, 2, "gtk_calendar_get_day_is_marked", "guint"); return(C_to_Xen_gboolean(gtk_calendar_get_day_is_marked(Xen_to_C_GtkCalendar_(calendar), Xen_to_C_guint(day)))); } static Xen gxg_gtk_progress_bar_set_inverted(Xen pbar, Xen inverted) { #define H_gtk_progress_bar_set_inverted "void gtk_progress_bar_set_inverted(GtkProgressBar* pbar, gboolean inverted)" Xen_check_type(Xen_is_GtkProgressBar_(pbar), pbar, 1, "gtk_progress_bar_set_inverted", "GtkProgressBar*"); Xen_check_type(Xen_is_gboolean(inverted), inverted, 2, "gtk_progress_bar_set_inverted", "gboolean"); gtk_progress_bar_set_inverted(Xen_to_C_GtkProgressBar_(pbar), Xen_to_C_gboolean(inverted)); return(Xen_false); } static Xen gxg_gtk_progress_bar_get_inverted(Xen pbar) { #define H_gtk_progress_bar_get_inverted "gboolean gtk_progress_bar_get_inverted(GtkProgressBar* pbar)" Xen_check_type(Xen_is_GtkProgressBar_(pbar), pbar, 1, "gtk_progress_bar_get_inverted", "GtkProgressBar*"); return(C_to_Xen_gboolean(gtk_progress_bar_get_inverted(Xen_to_C_GtkProgressBar_(pbar)))); } static Xen gxg_gtk_radio_button_join_group(Xen radio_button, Xen group_source) { #define H_gtk_radio_button_join_group "void gtk_radio_button_join_group(GtkRadioButton* radio_button, \ GtkRadioButton* group_source)" Xen_check_type(Xen_is_GtkRadioButton_(radio_button), radio_button, 1, "gtk_radio_button_join_group", "GtkRadioButton*"); Xen_check_type(Xen_is_GtkRadioButton_(group_source), group_source, 2, "gtk_radio_button_join_group", "GtkRadioButton*"); gtk_radio_button_join_group(Xen_to_C_GtkRadioButton_(radio_button), Xen_to_C_GtkRadioButton_(group_source)); return(Xen_false); } static Xen gxg_gtk_adjustment_new(Xen value, Xen lower, Xen upper, Xen step_increment, Xen page_increment, Xen page_size) { #define H_gtk_adjustment_new "GtkAdjustment* gtk_adjustment_new(gdouble value, gdouble lower, gdouble upper, \ gdouble step_increment, gdouble page_increment, gdouble page_size)" Xen_check_type(Xen_is_gdouble(value), value, 1, "gtk_adjustment_new", "gdouble"); Xen_check_type(Xen_is_gdouble(lower), lower, 2, "gtk_adjustment_new", "gdouble"); Xen_check_type(Xen_is_gdouble(upper), upper, 3, "gtk_adjustment_new", "gdouble"); Xen_check_type(Xen_is_gdouble(step_increment), step_increment, 4, "gtk_adjustment_new", "gdouble"); Xen_check_type(Xen_is_gdouble(page_increment), page_increment, 5, "gtk_adjustment_new", "gdouble"); Xen_check_type(Xen_is_gdouble(page_size), page_size, 6, "gtk_adjustment_new", "gdouble"); return(C_to_Xen_GtkAdjustment_(gtk_adjustment_new(Xen_to_C_gdouble(value), Xen_to_C_gdouble(lower), Xen_to_C_gdouble(upper), Xen_to_C_gdouble(step_increment), Xen_to_C_gdouble(page_increment), Xen_to_C_gdouble(page_size)))); } static Xen gxg_gtk_binding_set_activate(Xen binding_set, Xen keyval, Xen modifiers, Xen object) { #define H_gtk_binding_set_activate "gboolean gtk_binding_set_activate(GtkBindingSet* binding_set, guint keyval, \ GdkModifierType modifiers, GObject* object)" Xen_check_type(Xen_is_GtkBindingSet_(binding_set), binding_set, 1, "gtk_binding_set_activate", "GtkBindingSet*"); Xen_check_type(Xen_is_guint(keyval), keyval, 2, "gtk_binding_set_activate", "guint"); Xen_check_type(Xen_is_GdkModifierType(modifiers), modifiers, 3, "gtk_binding_set_activate", "GdkModifierType"); Xen_check_type(Xen_is_GObject_(object), object, 4, "gtk_binding_set_activate", "GObject*"); return(C_to_Xen_gboolean(gtk_binding_set_activate(Xen_to_C_GtkBindingSet_(binding_set), Xen_to_C_guint(keyval), Xen_to_C_GdkModifierType(modifiers), Xen_to_C_GObject_(object)))); } static Xen gxg_gtk_bindings_activate(Xen object, Xen keyval, Xen modifiers) { #define H_gtk_bindings_activate "gboolean gtk_bindings_activate(GObject* object, guint keyval, GdkModifierType modifiers)" Xen_check_type(Xen_is_GObject_(object), object, 1, "gtk_bindings_activate", "GObject*"); Xen_check_type(Xen_is_guint(keyval), keyval, 2, "gtk_bindings_activate", "guint"); Xen_check_type(Xen_is_GdkModifierType(modifiers), modifiers, 3, "gtk_bindings_activate", "GdkModifierType"); return(C_to_Xen_gboolean(gtk_bindings_activate(Xen_to_C_GObject_(object), Xen_to_C_guint(keyval), Xen_to_C_GdkModifierType(modifiers)))); } static Xen gxg_gtk_icon_view_create_drag_icon(Xen icon_view, Xen path) { #define H_gtk_icon_view_create_drag_icon "cairo_surface_t* gtk_icon_view_create_drag_icon(GtkIconView* icon_view, \ GtkTreePath* path)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_create_drag_icon", "GtkIconView*"); Xen_check_type(Xen_is_GtkTreePath_(path), path, 2, "gtk_icon_view_create_drag_icon", "GtkTreePath*"); return(C_to_Xen_cairo_surface_t_(gtk_icon_view_create_drag_icon(Xen_to_C_GtkIconView_(icon_view), Xen_to_C_GtkTreePath_(path)))); } static Xen gxg_gtk_tree_view_create_row_drag_icon(Xen tree_view, Xen path) { #define H_gtk_tree_view_create_row_drag_icon "cairo_surface_t* gtk_tree_view_create_row_drag_icon(GtkTreeView* tree_view, \ GtkTreePath* path)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_create_row_drag_icon", "GtkTreeView*"); Xen_check_type(Xen_is_GtkTreePath_(path), path, 2, "gtk_tree_view_create_row_drag_icon", "GtkTreePath*"); return(C_to_Xen_cairo_surface_t_(gtk_tree_view_create_row_drag_icon(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_GtkTreePath_(path)))); } static Xen gxg_gdk_cairo_get_clip_rectangle(Xen cr, Xen rect) { #define H_gdk_cairo_get_clip_rectangle "gboolean gdk_cairo_get_clip_rectangle(cairo_t* cr, GdkRectangle* rect)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "gdk_cairo_get_clip_rectangle", "cairo_t*"); Xen_check_type(Xen_is_GdkRectangle_(rect), rect, 2, "gdk_cairo_get_clip_rectangle", "GdkRectangle*"); return(C_to_Xen_gboolean(gdk_cairo_get_clip_rectangle(Xen_to_C_cairo_t_(cr), Xen_to_C_GdkRectangle_(rect)))); } static Xen gxg_gdk_cairo_region_create_from_surface(Xen surface) { #define H_gdk_cairo_region_create_from_surface "cairo_region_t* gdk_cairo_region_create_from_surface(cairo_surface_t* surface)" Xen_check_type(Xen_is_cairo_surface_t_(surface), surface, 1, "gdk_cairo_region_create_from_surface", "cairo_surface_t*"); return(C_to_Xen_cairo_region_t_(gdk_cairo_region_create_from_surface(Xen_to_C_cairo_surface_t_(surface)))); } static Xen gxg_gdk_window_get_visual(Xen window) { #define H_gdk_window_get_visual "GdkVisual* gdk_window_get_visual(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_get_visual", "GdkWindow*"); return(C_to_Xen_GdkVisual_(gdk_window_get_visual(Xen_to_C_GdkWindow_(window)))); } static Xen gxg_gdk_window_get_screen(Xen window) { #define H_gdk_window_get_screen "GdkScreen* gdk_window_get_screen(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_get_screen", "GdkWindow*"); return(C_to_Xen_GdkScreen_(gdk_window_get_screen(Xen_to_C_GdkWindow_(window)))); } static Xen gxg_gdk_window_get_display(Xen window) { #define H_gdk_window_get_display "GdkDisplay* gdk_window_get_display(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_get_display", "GdkWindow*"); return(C_to_Xen_GdkDisplay_(gdk_window_get_display(Xen_to_C_GdkWindow_(window)))); } static Xen gxg_gdk_window_get_width(Xen window) { #define H_gdk_window_get_width "int gdk_window_get_width(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_get_width", "GdkWindow*"); return(C_to_Xen_int(gdk_window_get_width(Xen_to_C_GdkWindow_(window)))); } static Xen gxg_gdk_window_get_height(Xen window) { #define H_gdk_window_get_height "int gdk_window_get_height(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_get_height", "GdkWindow*"); return(C_to_Xen_int(gdk_window_get_height(Xen_to_C_GdkWindow_(window)))); } static Xen gxg_gtk_cell_renderer_get_request_mode(Xen cell) { #define H_gtk_cell_renderer_get_request_mode "GtkSizeRequestMode gtk_cell_renderer_get_request_mode(GtkCellRenderer* cell)" Xen_check_type(Xen_is_GtkCellRenderer_(cell), cell, 1, "gtk_cell_renderer_get_request_mode", "GtkCellRenderer*"); return(C_to_Xen_GtkSizeRequestMode(gtk_cell_renderer_get_request_mode(Xen_to_C_GtkCellRenderer_(cell)))); } static Xen gxg_gtk_cell_renderer_get_preferred_width(Xen cell, Xen widget, Xen ignore_minimum_size, Xen ignore_natural_size) { #define H_gtk_cell_renderer_get_preferred_width "void gtk_cell_renderer_get_preferred_width(GtkCellRenderer* cell, \ GtkWidget* widget, gint* [minimum_size], gint* [natural_size])" gint ref_minimum_size; gint ref_natural_size; Xen_check_type(Xen_is_GtkCellRenderer_(cell), cell, 1, "gtk_cell_renderer_get_preferred_width", "GtkCellRenderer*"); Xen_check_type(Xen_is_GtkWidget_(widget), widget, 2, "gtk_cell_renderer_get_preferred_width", "GtkWidget*"); gtk_cell_renderer_get_preferred_width(Xen_to_C_GtkCellRenderer_(cell), Xen_to_C_GtkWidget_(widget), &ref_minimum_size, &ref_natural_size); return(Xen_list_2(C_to_Xen_gint(ref_minimum_size), C_to_Xen_gint(ref_natural_size))); } static Xen gxg_gtk_cell_renderer_get_preferred_height_for_width(Xen cell, Xen widget, Xen width, Xen ignore_minimum_height, Xen ignore_natural_height) { #define H_gtk_cell_renderer_get_preferred_height_for_width "void gtk_cell_renderer_get_preferred_height_for_width(GtkCellRenderer* cell, \ GtkWidget* widget, gint width, gint* [minimum_height], gint* [natural_height])" gint ref_minimum_height; gint ref_natural_height; Xen_check_type(Xen_is_GtkCellRenderer_(cell), cell, 1, "gtk_cell_renderer_get_preferred_height_for_width", "GtkCellRenderer*"); Xen_check_type(Xen_is_GtkWidget_(widget), widget, 2, "gtk_cell_renderer_get_preferred_height_for_width", "GtkWidget*"); Xen_check_type(Xen_is_gint(width), width, 3, "gtk_cell_renderer_get_preferred_height_for_width", "gint"); gtk_cell_renderer_get_preferred_height_for_width(Xen_to_C_GtkCellRenderer_(cell), Xen_to_C_GtkWidget_(widget), Xen_to_C_gint(width), &ref_minimum_height, &ref_natural_height); return(Xen_list_2(C_to_Xen_gint(ref_minimum_height), C_to_Xen_gint(ref_natural_height))); } static Xen gxg_gtk_cell_renderer_get_preferred_height(Xen cell, Xen widget, Xen ignore_minimum_size, Xen ignore_natural_size) { #define H_gtk_cell_renderer_get_preferred_height "void gtk_cell_renderer_get_preferred_height(GtkCellRenderer* cell, \ GtkWidget* widget, gint* [minimum_size], gint* [natural_size])" gint ref_minimum_size; gint ref_natural_size; Xen_check_type(Xen_is_GtkCellRenderer_(cell), cell, 1, "gtk_cell_renderer_get_preferred_height", "GtkCellRenderer*"); Xen_check_type(Xen_is_GtkWidget_(widget), widget, 2, "gtk_cell_renderer_get_preferred_height", "GtkWidget*"); gtk_cell_renderer_get_preferred_height(Xen_to_C_GtkCellRenderer_(cell), Xen_to_C_GtkWidget_(widget), &ref_minimum_size, &ref_natural_size); return(Xen_list_2(C_to_Xen_gint(ref_minimum_size), C_to_Xen_gint(ref_natural_size))); } static Xen gxg_gtk_cell_renderer_get_preferred_width_for_height(Xen cell, Xen widget, Xen height, Xen ignore_minimum_width, Xen ignore_natural_width) { #define H_gtk_cell_renderer_get_preferred_width_for_height "void gtk_cell_renderer_get_preferred_width_for_height(GtkCellRenderer* cell, \ GtkWidget* widget, gint height, gint* [minimum_width], gint* [natural_width])" gint ref_minimum_width; gint ref_natural_width; Xen_check_type(Xen_is_GtkCellRenderer_(cell), cell, 1, "gtk_cell_renderer_get_preferred_width_for_height", "GtkCellRenderer*"); Xen_check_type(Xen_is_GtkWidget_(widget), widget, 2, "gtk_cell_renderer_get_preferred_width_for_height", "GtkWidget*"); Xen_check_type(Xen_is_gint(height), height, 3, "gtk_cell_renderer_get_preferred_width_for_height", "gint"); gtk_cell_renderer_get_preferred_width_for_height(Xen_to_C_GtkCellRenderer_(cell), Xen_to_C_GtkWidget_(widget), Xen_to_C_gint(height), &ref_minimum_width, &ref_natural_width); return(Xen_list_2(C_to_Xen_gint(ref_minimum_width), C_to_Xen_gint(ref_natural_width))); } static Xen gxg_gtk_container_class_handle_border_width(Xen klass) { #define H_gtk_container_class_handle_border_width "void gtk_container_class_handle_border_width(GtkContainerClass* klass)" Xen_check_type(Xen_is_GtkContainerClass_(klass), klass, 1, "gtk_container_class_handle_border_width", "GtkContainerClass*"); gtk_container_class_handle_border_width(Xen_to_C_GtkContainerClass_(klass)); return(Xen_false); } static Xen gxg_gtk_drag_set_icon_surface(Xen context, Xen surface) { #define H_gtk_drag_set_icon_surface "void gtk_drag_set_icon_surface(GdkDragContext* context, cairo_surface_t* surface)" Xen_check_type(Xen_is_GdkDragContext_(context), context, 1, "gtk_drag_set_icon_surface", "GdkDragContext*"); Xen_check_type(Xen_is_cairo_surface_t_(surface), surface, 2, "gtk_drag_set_icon_surface", "cairo_surface_t*"); gtk_drag_set_icon_surface(Xen_to_C_GdkDragContext_(context), Xen_to_C_cairo_surface_t_(surface)); return(Xen_false); } static Xen gxg_gtk_notebook_set_group_name(Xen notebook, Xen group_name) { #define H_gtk_notebook_set_group_name "void gtk_notebook_set_group_name(GtkNotebook* notebook, gchar* group_name)" Xen_check_type(Xen_is_GtkNotebook_(notebook), notebook, 1, "gtk_notebook_set_group_name", "GtkNotebook*"); Xen_check_type(Xen_is_gchar_(group_name), group_name, 2, "gtk_notebook_set_group_name", "gchar*"); gtk_notebook_set_group_name(Xen_to_C_GtkNotebook_(notebook), (const gchar*)Xen_to_C_gchar_(group_name)); return(Xen_false); } static Xen gxg_gtk_notebook_get_group_name(Xen notebook) { #define H_gtk_notebook_get_group_name "gchar* gtk_notebook_get_group_name(GtkNotebook* notebook)" Xen_check_type(Xen_is_GtkNotebook_(notebook), notebook, 1, "gtk_notebook_get_group_name", "GtkNotebook*"); return(C_to_Xen_gchar_((gchar*)gtk_notebook_get_group_name(Xen_to_C_GtkNotebook_(notebook)))); } static Xen gxg_gtk_widget_draw(Xen widget, Xen cr) { #define H_gtk_widget_draw "void gtk_widget_draw(GtkWidget* widget, cairo_t* cr)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_draw", "GtkWidget*"); Xen_check_type(Xen_is_cairo_t_(cr), cr, 2, "gtk_widget_draw", "cairo_t*"); gtk_widget_draw(Xen_to_C_GtkWidget_(widget), Xen_to_C_cairo_t_(cr)); return(Xen_false); } static Xen gxg_gtk_widget_get_request_mode(Xen widget) { #define H_gtk_widget_get_request_mode "GtkSizeRequestMode gtk_widget_get_request_mode(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_request_mode", "GtkWidget*"); return(C_to_Xen_GtkSizeRequestMode(gtk_widget_get_request_mode(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_get_preferred_width(Xen widget, Xen ignore_minimum_width, Xen ignore_natural_width) { #define H_gtk_widget_get_preferred_width "void gtk_widget_get_preferred_width(GtkWidget* widget, gint* [minimum_width], \ gint* [natural_width])" gint ref_minimum_width; gint ref_natural_width; Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_preferred_width", "GtkWidget*"); gtk_widget_get_preferred_width(Xen_to_C_GtkWidget_(widget), &ref_minimum_width, &ref_natural_width); return(Xen_list_2(C_to_Xen_gint(ref_minimum_width), C_to_Xen_gint(ref_natural_width))); } static Xen gxg_gtk_widget_get_preferred_height_for_width(Xen widget, Xen width, Xen ignore_minimum_height, Xen ignore_natural_height) { #define H_gtk_widget_get_preferred_height_for_width "void gtk_widget_get_preferred_height_for_width(GtkWidget* widget, \ gint width, gint* [minimum_height], gint* [natural_height])" gint ref_minimum_height; gint ref_natural_height; Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_preferred_height_for_width", "GtkWidget*"); Xen_check_type(Xen_is_gint(width), width, 2, "gtk_widget_get_preferred_height_for_width", "gint"); gtk_widget_get_preferred_height_for_width(Xen_to_C_GtkWidget_(widget), Xen_to_C_gint(width), &ref_minimum_height, &ref_natural_height); return(Xen_list_2(C_to_Xen_gint(ref_minimum_height), C_to_Xen_gint(ref_natural_height))); } static Xen gxg_gtk_widget_get_preferred_height(Xen widget, Xen ignore_minimum_height, Xen ignore_natural_height) { #define H_gtk_widget_get_preferred_height "void gtk_widget_get_preferred_height(GtkWidget* widget, \ gint* [minimum_height], gint* [natural_height])" gint ref_minimum_height; gint ref_natural_height; Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_preferred_height", "GtkWidget*"); gtk_widget_get_preferred_height(Xen_to_C_GtkWidget_(widget), &ref_minimum_height, &ref_natural_height); return(Xen_list_2(C_to_Xen_gint(ref_minimum_height), C_to_Xen_gint(ref_natural_height))); } static Xen gxg_gtk_widget_get_preferred_width_for_height(Xen widget, Xen height, Xen ignore_minimum_width, Xen ignore_natural_width) { #define H_gtk_widget_get_preferred_width_for_height "void gtk_widget_get_preferred_width_for_height(GtkWidget* widget, \ gint height, gint* [minimum_width], gint* [natural_width])" gint ref_minimum_width; gint ref_natural_width; Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_preferred_width_for_height", "GtkWidget*"); Xen_check_type(Xen_is_gint(height), height, 2, "gtk_widget_get_preferred_width_for_height", "gint"); gtk_widget_get_preferred_width_for_height(Xen_to_C_GtkWidget_(widget), Xen_to_C_gint(height), &ref_minimum_width, &ref_natural_width); return(Xen_list_2(C_to_Xen_gint(ref_minimum_width), C_to_Xen_gint(ref_natural_width))); } static Xen gxg_gtk_widget_get_allocated_width(Xen widget) { #define H_gtk_widget_get_allocated_width "int gtk_widget_get_allocated_width(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_allocated_width", "GtkWidget*"); return(C_to_Xen_int(gtk_widget_get_allocated_width(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_get_allocated_height(Xen widget) { #define H_gtk_widget_get_allocated_height "int gtk_widget_get_allocated_height(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_allocated_height", "GtkWidget*"); return(C_to_Xen_int(gtk_widget_get_allocated_height(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_set_visual(Xen widget, Xen visual) { #define H_gtk_widget_set_visual "void gtk_widget_set_visual(GtkWidget* widget, GdkVisual* visual)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_set_visual", "GtkWidget*"); Xen_check_type(Xen_is_GdkVisual_(visual), visual, 2, "gtk_widget_set_visual", "GdkVisual*"); gtk_widget_set_visual(Xen_to_C_GtkWidget_(widget), Xen_to_C_GdkVisual_(visual)); return(Xen_false); } static Xen gxg_gtk_widget_get_halign(Xen widget) { #define H_gtk_widget_get_halign "GtkAlign gtk_widget_get_halign(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_halign", "GtkWidget*"); return(C_to_Xen_GtkAlign(gtk_widget_get_halign(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_set_halign(Xen widget, Xen align) { #define H_gtk_widget_set_halign "void gtk_widget_set_halign(GtkWidget* widget, GtkAlign align)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_set_halign", "GtkWidget*"); Xen_check_type(Xen_is_GtkAlign(align), align, 2, "gtk_widget_set_halign", "GtkAlign"); gtk_widget_set_halign(Xen_to_C_GtkWidget_(widget), Xen_to_C_GtkAlign(align)); return(Xen_false); } static Xen gxg_gtk_widget_get_valign(Xen widget) { #define H_gtk_widget_get_valign "GtkAlign gtk_widget_get_valign(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_valign", "GtkWidget*"); return(C_to_Xen_GtkAlign(gtk_widget_get_valign(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_set_valign(Xen widget, Xen align) { #define H_gtk_widget_set_valign "void gtk_widget_set_valign(GtkWidget* widget, GtkAlign align)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_set_valign", "GtkWidget*"); Xen_check_type(Xen_is_GtkAlign(align), align, 2, "gtk_widget_set_valign", "GtkAlign"); gtk_widget_set_valign(Xen_to_C_GtkWidget_(widget), Xen_to_C_GtkAlign(align)); return(Xen_false); } static Xen gxg_gtk_widget_get_margin_top(Xen widget) { #define H_gtk_widget_get_margin_top "gint gtk_widget_get_margin_top(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_margin_top", "GtkWidget*"); return(C_to_Xen_gint(gtk_widget_get_margin_top(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_set_margin_top(Xen widget, Xen margin) { #define H_gtk_widget_set_margin_top "void gtk_widget_set_margin_top(GtkWidget* widget, gint margin)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_set_margin_top", "GtkWidget*"); Xen_check_type(Xen_is_gint(margin), margin, 2, "gtk_widget_set_margin_top", "gint"); gtk_widget_set_margin_top(Xen_to_C_GtkWidget_(widget), Xen_to_C_gint(margin)); return(Xen_false); } static Xen gxg_gtk_widget_get_margin_bottom(Xen widget) { #define H_gtk_widget_get_margin_bottom "gint gtk_widget_get_margin_bottom(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_margin_bottom", "GtkWidget*"); return(C_to_Xen_gint(gtk_widget_get_margin_bottom(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_set_margin_bottom(Xen widget, Xen margin) { #define H_gtk_widget_set_margin_bottom "void gtk_widget_set_margin_bottom(GtkWidget* widget, gint margin)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_set_margin_bottom", "GtkWidget*"); Xen_check_type(Xen_is_gint(margin), margin, 2, "gtk_widget_set_margin_bottom", "gint"); gtk_widget_set_margin_bottom(Xen_to_C_GtkWidget_(widget), Xen_to_C_gint(margin)); return(Xen_false); } static Xen gxg_gtk_widget_shape_combine_region(Xen widget, Xen region) { #define H_gtk_widget_shape_combine_region "void gtk_widget_shape_combine_region(GtkWidget* widget, \ cairo_region_t* region)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_shape_combine_region", "GtkWidget*"); Xen_check_type(Xen_is_cairo_region_t_(region), region, 2, "gtk_widget_shape_combine_region", "cairo_region_t*"); gtk_widget_shape_combine_region(Xen_to_C_GtkWidget_(widget), Xen_to_C_cairo_region_t_(region)); return(Xen_false); } static Xen gxg_gtk_widget_input_shape_combine_region(Xen widget, Xen region) { #define H_gtk_widget_input_shape_combine_region "void gtk_widget_input_shape_combine_region(GtkWidget* widget, \ cairo_region_t* region)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_input_shape_combine_region", "GtkWidget*"); Xen_check_type(Xen_is_cairo_region_t_(region), region, 2, "gtk_widget_input_shape_combine_region", "cairo_region_t*"); gtk_widget_input_shape_combine_region(Xen_to_C_GtkWidget_(widget), Xen_to_C_cairo_region_t_(region)); return(Xen_false); } static Xen gxg_gtk_cairo_should_draw_window(Xen cr, Xen window) { #define H_gtk_cairo_should_draw_window "gboolean gtk_cairo_should_draw_window(cairo_t* cr, GdkWindow* window)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "gtk_cairo_should_draw_window", "cairo_t*"); Xen_check_type(Xen_is_GdkWindow_(window), window, 2, "gtk_cairo_should_draw_window", "GdkWindow*"); return(C_to_Xen_gboolean(gtk_cairo_should_draw_window(Xen_to_C_cairo_t_(cr), Xen_to_C_GdkWindow_(window)))); } static Xen gxg_gtk_cairo_transform_to_window(Xen cr, Xen widget, Xen window) { #define H_gtk_cairo_transform_to_window "void gtk_cairo_transform_to_window(cairo_t* cr, GtkWidget* widget, \ GdkWindow* window)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "gtk_cairo_transform_to_window", "cairo_t*"); Xen_check_type(Xen_is_GtkWidget_(widget), widget, 2, "gtk_cairo_transform_to_window", "GtkWidget*"); Xen_check_type(Xen_is_GdkWindow_(window), window, 3, "gtk_cairo_transform_to_window", "GdkWindow*"); gtk_cairo_transform_to_window(Xen_to_C_cairo_t_(cr), Xen_to_C_GtkWidget_(widget), Xen_to_C_GdkWindow_(window)); return(Xen_false); } static Xen gxg_gtk_combo_box_new_with_entry(void) { #define H_gtk_combo_box_new_with_entry "GtkWidget* gtk_combo_box_new_with_entry( void)" return(C_to_Xen_GtkWidget_(gtk_combo_box_new_with_entry())); } static Xen gxg_gtk_combo_box_get_has_entry(Xen combo_box) { #define H_gtk_combo_box_get_has_entry "gboolean gtk_combo_box_get_has_entry(GtkComboBox* combo_box)" Xen_check_type(Xen_is_GtkComboBox_(combo_box), combo_box, 1, "gtk_combo_box_get_has_entry", "GtkComboBox*"); return(C_to_Xen_gboolean(gtk_combo_box_get_has_entry(Xen_to_C_GtkComboBox_(combo_box)))); } static Xen gxg_gtk_combo_box_set_entry_text_column(Xen combo_box, Xen text_column) { #define H_gtk_combo_box_set_entry_text_column "void gtk_combo_box_set_entry_text_column(GtkComboBox* combo_box, \ gint text_column)" Xen_check_type(Xen_is_GtkComboBox_(combo_box), combo_box, 1, "gtk_combo_box_set_entry_text_column", "GtkComboBox*"); Xen_check_type(Xen_is_gint(text_column), text_column, 2, "gtk_combo_box_set_entry_text_column", "gint"); gtk_combo_box_set_entry_text_column(Xen_to_C_GtkComboBox_(combo_box), Xen_to_C_gint(text_column)); return(Xen_false); } static Xen gxg_gtk_combo_box_get_entry_text_column(Xen combo_box) { #define H_gtk_combo_box_get_entry_text_column "gint gtk_combo_box_get_entry_text_column(GtkComboBox* combo_box)" Xen_check_type(Xen_is_GtkComboBox_(combo_box), combo_box, 1, "gtk_combo_box_get_entry_text_column", "GtkComboBox*"); return(C_to_Xen_gint(gtk_combo_box_get_entry_text_column(Xen_to_C_GtkComboBox_(combo_box)))); } static Xen gxg_gtk_target_entry_new(Xen target, Xen flags, Xen info) { #define H_gtk_target_entry_new "GtkTargetEntry* gtk_target_entry_new(char* target, guint flags, guint info)" Xen_check_type(Xen_is_char_(target), target, 1, "gtk_target_entry_new", "char*"); Xen_check_type(Xen_is_guint(flags), flags, 2, "gtk_target_entry_new", "guint"); Xen_check_type(Xen_is_guint(info), info, 3, "gtk_target_entry_new", "guint"); return(C_to_Xen_GtkTargetEntry_(gtk_target_entry_new((const char*)Xen_to_C_char_(target), Xen_to_C_guint(flags), Xen_to_C_guint(info)))); } static Xen gxg_gtk_target_entry_copy(Xen data) { #define H_gtk_target_entry_copy "GtkTargetEntry* gtk_target_entry_copy(GtkTargetEntry* data)" Xen_check_type(Xen_is_GtkTargetEntry_(data), data, 1, "gtk_target_entry_copy", "GtkTargetEntry*"); return(C_to_Xen_GtkTargetEntry_(gtk_target_entry_copy(Xen_to_C_GtkTargetEntry_(data)))); } static Xen gxg_gtk_target_entry_free(Xen data) { #define H_gtk_target_entry_free "void gtk_target_entry_free(GtkTargetEntry* data)" Xen_check_type(Xen_is_GtkTargetEntry_(data), data, 1, "gtk_target_entry_free", "GtkTargetEntry*"); gtk_target_entry_free(Xen_to_C_GtkTargetEntry_(data)); return(Xen_false); } static Xen gxg_gtk_widget_get_hexpand(Xen widget) { #define H_gtk_widget_get_hexpand "gboolean gtk_widget_get_hexpand(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_hexpand", "GtkWidget*"); return(C_to_Xen_gboolean(gtk_widget_get_hexpand(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_set_hexpand(Xen widget, Xen expand) { #define H_gtk_widget_set_hexpand "void gtk_widget_set_hexpand(GtkWidget* widget, gboolean expand)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_set_hexpand", "GtkWidget*"); Xen_check_type(Xen_is_gboolean(expand), expand, 2, "gtk_widget_set_hexpand", "gboolean"); gtk_widget_set_hexpand(Xen_to_C_GtkWidget_(widget), Xen_to_C_gboolean(expand)); return(Xen_false); } static Xen gxg_gtk_widget_get_hexpand_set(Xen widget) { #define H_gtk_widget_get_hexpand_set "gboolean gtk_widget_get_hexpand_set(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_hexpand_set", "GtkWidget*"); return(C_to_Xen_gboolean(gtk_widget_get_hexpand_set(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_set_hexpand_set(Xen widget, Xen set) { #define H_gtk_widget_set_hexpand_set "void gtk_widget_set_hexpand_set(GtkWidget* widget, gboolean set)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_set_hexpand_set", "GtkWidget*"); Xen_check_type(Xen_is_gboolean(set), set, 2, "gtk_widget_set_hexpand_set", "gboolean"); gtk_widget_set_hexpand_set(Xen_to_C_GtkWidget_(widget), Xen_to_C_gboolean(set)); return(Xen_false); } static Xen gxg_gtk_widget_get_vexpand(Xen widget) { #define H_gtk_widget_get_vexpand "gboolean gtk_widget_get_vexpand(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_vexpand", "GtkWidget*"); return(C_to_Xen_gboolean(gtk_widget_get_vexpand(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_set_vexpand(Xen widget, Xen expand) { #define H_gtk_widget_set_vexpand "void gtk_widget_set_vexpand(GtkWidget* widget, gboolean expand)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_set_vexpand", "GtkWidget*"); Xen_check_type(Xen_is_gboolean(expand), expand, 2, "gtk_widget_set_vexpand", "gboolean"); gtk_widget_set_vexpand(Xen_to_C_GtkWidget_(widget), Xen_to_C_gboolean(expand)); return(Xen_false); } static Xen gxg_gtk_widget_get_vexpand_set(Xen widget) { #define H_gtk_widget_get_vexpand_set "gboolean gtk_widget_get_vexpand_set(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_vexpand_set", "GtkWidget*"); return(C_to_Xen_gboolean(gtk_widget_get_vexpand_set(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_set_vexpand_set(Xen widget, Xen set) { #define H_gtk_widget_set_vexpand_set "void gtk_widget_set_vexpand_set(GtkWidget* widget, gboolean set)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_set_vexpand_set", "GtkWidget*"); Xen_check_type(Xen_is_gboolean(set), set, 2, "gtk_widget_set_vexpand_set", "gboolean"); gtk_widget_set_vexpand_set(Xen_to_C_GtkWidget_(widget), Xen_to_C_gboolean(set)); return(Xen_false); } static Xen gxg_gtk_widget_queue_compute_expand(Xen widget) { #define H_gtk_widget_queue_compute_expand "void gtk_widget_queue_compute_expand(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_queue_compute_expand", "GtkWidget*"); gtk_widget_queue_compute_expand(Xen_to_C_GtkWidget_(widget)); return(Xen_false); } static Xen gxg_gtk_widget_compute_expand(Xen widget, Xen orientation) { #define H_gtk_widget_compute_expand "gboolean gtk_widget_compute_expand(GtkWidget* widget, GtkOrientation orientation)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_compute_expand", "GtkWidget*"); Xen_check_type(Xen_is_GtkOrientation(orientation), orientation, 2, "gtk_widget_compute_expand", "GtkOrientation"); return(C_to_Xen_gboolean(gtk_widget_compute_expand(Xen_to_C_GtkWidget_(widget), Xen_to_C_GtkOrientation(orientation)))); } static Xen gxg_gtk_window_set_default_geometry(Xen window, Xen width, Xen height) { #define H_gtk_window_set_default_geometry "void gtk_window_set_default_geometry(GtkWindow* window, \ gint width, gint height)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_set_default_geometry", "GtkWindow*"); Xen_check_type(Xen_is_gint(width), width, 2, "gtk_window_set_default_geometry", "gint"); Xen_check_type(Xen_is_gint(height), height, 3, "gtk_window_set_default_geometry", "gint"); gtk_window_set_default_geometry(Xen_to_C_GtkWindow_(window), Xen_to_C_gint(width), Xen_to_C_gint(height)); return(Xen_false); } static Xen gxg_gtk_window_resize_to_geometry(Xen window, Xen width, Xen height) { #define H_gtk_window_resize_to_geometry "void gtk_window_resize_to_geometry(GtkWindow* window, gint width, \ gint height)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_resize_to_geometry", "GtkWindow*"); Xen_check_type(Xen_is_gint(width), width, 2, "gtk_window_resize_to_geometry", "gint"); Xen_check_type(Xen_is_gint(height), height, 3, "gtk_window_resize_to_geometry", "gint"); gtk_window_resize_to_geometry(Xen_to_C_GtkWindow_(window), Xen_to_C_gint(width), Xen_to_C_gint(height)); return(Xen_false); } static Xen gxg_gtk_combo_box_text_new(void) { #define H_gtk_combo_box_text_new "GtkWidget* gtk_combo_box_text_new( void)" return(C_to_Xen_GtkWidget_(gtk_combo_box_text_new())); } static Xen gxg_gtk_combo_box_text_new_with_entry(void) { #define H_gtk_combo_box_text_new_with_entry "GtkWidget* gtk_combo_box_text_new_with_entry( void)" return(C_to_Xen_GtkWidget_(gtk_combo_box_text_new_with_entry())); } static Xen gxg_gtk_combo_box_text_append_text(Xen combo_box, Xen text) { #define H_gtk_combo_box_text_append_text "void gtk_combo_box_text_append_text(GtkComboBoxText* combo_box, \ gchar* text)" Xen_check_type(Xen_is_GtkComboBoxText_(combo_box), combo_box, 1, "gtk_combo_box_text_append_text", "GtkComboBoxText*"); Xen_check_type(Xen_is_gchar_(text), text, 2, "gtk_combo_box_text_append_text", "gchar*"); gtk_combo_box_text_append_text(Xen_to_C_GtkComboBoxText_(combo_box), (const gchar*)Xen_to_C_gchar_(text)); return(Xen_false); } static Xen gxg_gtk_combo_box_text_insert_text(Xen combo_box, Xen position, Xen text) { #define H_gtk_combo_box_text_insert_text "void gtk_combo_box_text_insert_text(GtkComboBoxText* combo_box, \ gint position, gchar* text)" Xen_check_type(Xen_is_GtkComboBoxText_(combo_box), combo_box, 1, "gtk_combo_box_text_insert_text", "GtkComboBoxText*"); Xen_check_type(Xen_is_gint(position), position, 2, "gtk_combo_box_text_insert_text", "gint"); Xen_check_type(Xen_is_gchar_(text), text, 3, "gtk_combo_box_text_insert_text", "gchar*"); gtk_combo_box_text_insert_text(Xen_to_C_GtkComboBoxText_(combo_box), Xen_to_C_gint(position), (const gchar*)Xen_to_C_gchar_(text)); return(Xen_false); } static Xen gxg_gtk_combo_box_text_prepend_text(Xen combo_box, Xen text) { #define H_gtk_combo_box_text_prepend_text "void gtk_combo_box_text_prepend_text(GtkComboBoxText* combo_box, \ gchar* text)" Xen_check_type(Xen_is_GtkComboBoxText_(combo_box), combo_box, 1, "gtk_combo_box_text_prepend_text", "GtkComboBoxText*"); Xen_check_type(Xen_is_gchar_(text), text, 2, "gtk_combo_box_text_prepend_text", "gchar*"); gtk_combo_box_text_prepend_text(Xen_to_C_GtkComboBoxText_(combo_box), (const gchar*)Xen_to_C_gchar_(text)); return(Xen_false); } static Xen gxg_gtk_combo_box_text_remove(Xen combo_box, Xen position) { #define H_gtk_combo_box_text_remove "void gtk_combo_box_text_remove(GtkComboBoxText* combo_box, gint position)" Xen_check_type(Xen_is_GtkComboBoxText_(combo_box), combo_box, 1, "gtk_combo_box_text_remove", "GtkComboBoxText*"); Xen_check_type(Xen_is_gint(position), position, 2, "gtk_combo_box_text_remove", "gint"); gtk_combo_box_text_remove(Xen_to_C_GtkComboBoxText_(combo_box), Xen_to_C_gint(position)); return(Xen_false); } static Xen gxg_gtk_combo_box_text_get_active_text(Xen combo_box) { #define H_gtk_combo_box_text_get_active_text "gchar* gtk_combo_box_text_get_active_text(GtkComboBoxText* combo_box)" Xen_check_type(Xen_is_GtkComboBoxText_(combo_box), combo_box, 1, "gtk_combo_box_text_get_active_text", "GtkComboBoxText*"); return(C_to_Xen_gchar_(gtk_combo_box_text_get_active_text(Xen_to_C_GtkComboBoxText_(combo_box)))); } static Xen gxg_gdk_cairo_set_source_rgba(Xen cr, Xen rgba) { #define H_gdk_cairo_set_source_rgba "void gdk_cairo_set_source_rgba(cairo_t* cr, GdkRGBA* rgba)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "gdk_cairo_set_source_rgba", "cairo_t*"); Xen_check_type(Xen_is_GdkRGBA_(rgba), rgba, 2, "gdk_cairo_set_source_rgba", "GdkRGBA*"); gdk_cairo_set_source_rgba(Xen_to_C_cairo_t_(cr), Xen_to_C_GdkRGBA_(rgba)); return(Xen_false); } static Xen gxg_gdk_window_set_background_rgba(Xen window, Xen rgba) { #define H_gdk_window_set_background_rgba "void gdk_window_set_background_rgba(GdkWindow* window, GdkRGBA* rgba)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_set_background_rgba", "GdkWindow*"); Xen_check_type(Xen_is_GdkRGBA_(rgba), rgba, 2, "gdk_window_set_background_rgba", "GdkRGBA*"); gdk_window_set_background_rgba(Xen_to_C_GdkWindow_(window), Xen_to_C_GdkRGBA_(rgba)); return(Xen_false); } static Xen gxg_gtk_cell_view_set_background_rgba(Xen cell_view, Xen rgba) { #define H_gtk_cell_view_set_background_rgba "void gtk_cell_view_set_background_rgba(GtkCellView* cell_view, \ GdkRGBA* rgba)" Xen_check_type(Xen_is_GtkCellView_(cell_view), cell_view, 1, "gtk_cell_view_set_background_rgba", "GtkCellView*"); Xen_check_type(Xen_is_GdkRGBA_(rgba), rgba, 2, "gtk_cell_view_set_background_rgba", "GdkRGBA*"); gtk_cell_view_set_background_rgba(Xen_to_C_GtkCellView_(cell_view), Xen_to_C_GdkRGBA_(rgba)); return(Xen_false); } static Xen gxg_gtk_combo_box_text_remove_all(Xen combo_box) { #define H_gtk_combo_box_text_remove_all "void gtk_combo_box_text_remove_all(GtkComboBoxText* combo_box)" Xen_check_type(Xen_is_GtkComboBoxText_(combo_box), combo_box, 1, "gtk_combo_box_text_remove_all", "GtkComboBoxText*"); gtk_combo_box_text_remove_all(Xen_to_C_GtkComboBoxText_(combo_box)); return(Xen_false); } static Xen gxg_gtk_combo_box_set_popup_fixed_width(Xen combo_box, Xen fixed) { #define H_gtk_combo_box_set_popup_fixed_width "void gtk_combo_box_set_popup_fixed_width(GtkComboBox* combo_box, \ gboolean fixed)" Xen_check_type(Xen_is_GtkComboBox_(combo_box), combo_box, 1, "gtk_combo_box_set_popup_fixed_width", "GtkComboBox*"); Xen_check_type(Xen_is_gboolean(fixed), fixed, 2, "gtk_combo_box_set_popup_fixed_width", "gboolean"); gtk_combo_box_set_popup_fixed_width(Xen_to_C_GtkComboBox_(combo_box), Xen_to_C_gboolean(fixed)); return(Xen_false); } static Xen gxg_gtk_combo_box_get_popup_fixed_width(Xen combo_box) { #define H_gtk_combo_box_get_popup_fixed_width "gboolean gtk_combo_box_get_popup_fixed_width(GtkComboBox* combo_box)" Xen_check_type(Xen_is_GtkComboBox_(combo_box), combo_box, 1, "gtk_combo_box_get_popup_fixed_width", "GtkComboBox*"); return(C_to_Xen_gboolean(gtk_combo_box_get_popup_fixed_width(Xen_to_C_GtkComboBox_(combo_box)))); } static Xen gxg_gtk_scrolled_window_get_min_content_width(Xen scrolled_window) { #define H_gtk_scrolled_window_get_min_content_width "gint gtk_scrolled_window_get_min_content_width(GtkScrolledWindow* scrolled_window)" Xen_check_type(Xen_is_GtkScrolledWindow_(scrolled_window), scrolled_window, 1, "gtk_scrolled_window_get_min_content_width", "GtkScrolledWindow*"); return(C_to_Xen_gint(gtk_scrolled_window_get_min_content_width(Xen_to_C_GtkScrolledWindow_(scrolled_window)))); } static Xen gxg_gtk_scrolled_window_set_min_content_width(Xen scrolled_window, Xen width) { #define H_gtk_scrolled_window_set_min_content_width "void gtk_scrolled_window_set_min_content_width(GtkScrolledWindow* scrolled_window, \ gint width)" Xen_check_type(Xen_is_GtkScrolledWindow_(scrolled_window), scrolled_window, 1, "gtk_scrolled_window_set_min_content_width", "GtkScrolledWindow*"); Xen_check_type(Xen_is_gint(width), width, 2, "gtk_scrolled_window_set_min_content_width", "gint"); gtk_scrolled_window_set_min_content_width(Xen_to_C_GtkScrolledWindow_(scrolled_window), Xen_to_C_gint(width)); return(Xen_false); } static Xen gxg_gtk_scrolled_window_get_min_content_height(Xen scrolled_window) { #define H_gtk_scrolled_window_get_min_content_height "gint gtk_scrolled_window_get_min_content_height(GtkScrolledWindow* scrolled_window)" Xen_check_type(Xen_is_GtkScrolledWindow_(scrolled_window), scrolled_window, 1, "gtk_scrolled_window_get_min_content_height", "GtkScrolledWindow*"); return(C_to_Xen_gint(gtk_scrolled_window_get_min_content_height(Xen_to_C_GtkScrolledWindow_(scrolled_window)))); } static Xen gxg_gtk_scrolled_window_set_min_content_height(Xen scrolled_window, Xen height) { #define H_gtk_scrolled_window_set_min_content_height "void gtk_scrolled_window_set_min_content_height(GtkScrolledWindow* scrolled_window, \ gint height)" Xen_check_type(Xen_is_GtkScrolledWindow_(scrolled_window), scrolled_window, 1, "gtk_scrolled_window_set_min_content_height", "GtkScrolledWindow*"); Xen_check_type(Xen_is_gint(height), height, 2, "gtk_scrolled_window_set_min_content_height", "gint"); gtk_scrolled_window_set_min_content_height(Xen_to_C_GtkScrolledWindow_(scrolled_window), Xen_to_C_gint(height)); return(Xen_false); } static Xen gxg_gtk_grid_new(void) { #define H_gtk_grid_new "GtkWidget* gtk_grid_new( void)" return(C_to_Xen_GtkWidget_(gtk_grid_new())); } static Xen gxg_gtk_grid_attach(Xen grid, Xen child, Xen left, Xen top, Xen width, Xen height) { #define H_gtk_grid_attach "void gtk_grid_attach(GtkGrid* grid, GtkWidget* child, gint left, gint top, \ gint width, gint height)" Xen_check_type(Xen_is_GtkGrid_(grid), grid, 1, "gtk_grid_attach", "GtkGrid*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_grid_attach", "GtkWidget*"); Xen_check_type(Xen_is_gint(left), left, 3, "gtk_grid_attach", "gint"); Xen_check_type(Xen_is_gint(top), top, 4, "gtk_grid_attach", "gint"); Xen_check_type(Xen_is_gint(width), width, 5, "gtk_grid_attach", "gint"); Xen_check_type(Xen_is_gint(height), height, 6, "gtk_grid_attach", "gint"); gtk_grid_attach(Xen_to_C_GtkGrid_(grid), Xen_to_C_GtkWidget_(child), Xen_to_C_gint(left), Xen_to_C_gint(top), Xen_to_C_gint(width), Xen_to_C_gint(height)); return(Xen_false); } static Xen gxg_gtk_grid_attach_next_to(Xen grid, Xen child, Xen sibling, Xen side, Xen width, Xen height) { #define H_gtk_grid_attach_next_to "void gtk_grid_attach_next_to(GtkGrid* grid, GtkWidget* child, GtkWidget* sibling, \ GtkPositionType side, gint width, gint height)" Xen_check_type(Xen_is_GtkGrid_(grid), grid, 1, "gtk_grid_attach_next_to", "GtkGrid*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_grid_attach_next_to", "GtkWidget*"); Xen_check_type(Xen_is_GtkWidget_(sibling), sibling, 3, "gtk_grid_attach_next_to", "GtkWidget*"); Xen_check_type(Xen_is_GtkPositionType(side), side, 4, "gtk_grid_attach_next_to", "GtkPositionType"); Xen_check_type(Xen_is_gint(width), width, 5, "gtk_grid_attach_next_to", "gint"); Xen_check_type(Xen_is_gint(height), height, 6, "gtk_grid_attach_next_to", "gint"); gtk_grid_attach_next_to(Xen_to_C_GtkGrid_(grid), Xen_to_C_GtkWidget_(child), Xen_to_C_GtkWidget_(sibling), Xen_to_C_GtkPositionType(side), Xen_to_C_gint(width), Xen_to_C_gint(height)); return(Xen_false); } static Xen gxg_gtk_grid_set_row_homogeneous(Xen grid, Xen homogeneous) { #define H_gtk_grid_set_row_homogeneous "void gtk_grid_set_row_homogeneous(GtkGrid* grid, gboolean homogeneous)" Xen_check_type(Xen_is_GtkGrid_(grid), grid, 1, "gtk_grid_set_row_homogeneous", "GtkGrid*"); Xen_check_type(Xen_is_gboolean(homogeneous), homogeneous, 2, "gtk_grid_set_row_homogeneous", "gboolean"); gtk_grid_set_row_homogeneous(Xen_to_C_GtkGrid_(grid), Xen_to_C_gboolean(homogeneous)); return(Xen_false); } static Xen gxg_gtk_grid_get_row_homogeneous(Xen grid) { #define H_gtk_grid_get_row_homogeneous "gboolean gtk_grid_get_row_homogeneous(GtkGrid* grid)" Xen_check_type(Xen_is_GtkGrid_(grid), grid, 1, "gtk_grid_get_row_homogeneous", "GtkGrid*"); return(C_to_Xen_gboolean(gtk_grid_get_row_homogeneous(Xen_to_C_GtkGrid_(grid)))); } static Xen gxg_gtk_grid_set_row_spacing(Xen grid, Xen spacing) { #define H_gtk_grid_set_row_spacing "void gtk_grid_set_row_spacing(GtkGrid* grid, guint spacing)" Xen_check_type(Xen_is_GtkGrid_(grid), grid, 1, "gtk_grid_set_row_spacing", "GtkGrid*"); Xen_check_type(Xen_is_guint(spacing), spacing, 2, "gtk_grid_set_row_spacing", "guint"); gtk_grid_set_row_spacing(Xen_to_C_GtkGrid_(grid), Xen_to_C_guint(spacing)); return(Xen_false); } static Xen gxg_gtk_grid_get_row_spacing(Xen grid) { #define H_gtk_grid_get_row_spacing "guint gtk_grid_get_row_spacing(GtkGrid* grid)" Xen_check_type(Xen_is_GtkGrid_(grid), grid, 1, "gtk_grid_get_row_spacing", "GtkGrid*"); return(C_to_Xen_guint(gtk_grid_get_row_spacing(Xen_to_C_GtkGrid_(grid)))); } static Xen gxg_gtk_grid_set_column_homogeneous(Xen grid, Xen homogeneous) { #define H_gtk_grid_set_column_homogeneous "void gtk_grid_set_column_homogeneous(GtkGrid* grid, gboolean homogeneous)" Xen_check_type(Xen_is_GtkGrid_(grid), grid, 1, "gtk_grid_set_column_homogeneous", "GtkGrid*"); Xen_check_type(Xen_is_gboolean(homogeneous), homogeneous, 2, "gtk_grid_set_column_homogeneous", "gboolean"); gtk_grid_set_column_homogeneous(Xen_to_C_GtkGrid_(grid), Xen_to_C_gboolean(homogeneous)); return(Xen_false); } static Xen gxg_gtk_grid_get_column_homogeneous(Xen grid) { #define H_gtk_grid_get_column_homogeneous "gboolean gtk_grid_get_column_homogeneous(GtkGrid* grid)" Xen_check_type(Xen_is_GtkGrid_(grid), grid, 1, "gtk_grid_get_column_homogeneous", "GtkGrid*"); return(C_to_Xen_gboolean(gtk_grid_get_column_homogeneous(Xen_to_C_GtkGrid_(grid)))); } static Xen gxg_gtk_grid_set_column_spacing(Xen grid, Xen spacing) { #define H_gtk_grid_set_column_spacing "void gtk_grid_set_column_spacing(GtkGrid* grid, guint spacing)" Xen_check_type(Xen_is_GtkGrid_(grid), grid, 1, "gtk_grid_set_column_spacing", "GtkGrid*"); Xen_check_type(Xen_is_guint(spacing), spacing, 2, "gtk_grid_set_column_spacing", "guint"); gtk_grid_set_column_spacing(Xen_to_C_GtkGrid_(grid), Xen_to_C_guint(spacing)); return(Xen_false); } static Xen gxg_gtk_grid_get_column_spacing(Xen grid) { #define H_gtk_grid_get_column_spacing "guint gtk_grid_get_column_spacing(GtkGrid* grid)" Xen_check_type(Xen_is_GtkGrid_(grid), grid, 1, "gtk_grid_get_column_spacing", "GtkGrid*"); return(C_to_Xen_guint(gtk_grid_get_column_spacing(Xen_to_C_GtkGrid_(grid)))); } static Xen gxg_gtk_scrollable_get_hadjustment(Xen scrollable) { #define H_gtk_scrollable_get_hadjustment "GtkAdjustment* gtk_scrollable_get_hadjustment(GtkScrollable* scrollable)" Xen_check_type(Xen_is_GtkScrollable_(scrollable), scrollable, 1, "gtk_scrollable_get_hadjustment", "GtkScrollable*"); return(C_to_Xen_GtkAdjustment_(gtk_scrollable_get_hadjustment(Xen_to_C_GtkScrollable_(scrollable)))); } static Xen gxg_gtk_scrollable_set_hadjustment(Xen scrollable, Xen hadjustment) { #define H_gtk_scrollable_set_hadjustment "void gtk_scrollable_set_hadjustment(GtkScrollable* scrollable, \ GtkAdjustment* hadjustment)" Xen_check_type(Xen_is_GtkScrollable_(scrollable), scrollable, 1, "gtk_scrollable_set_hadjustment", "GtkScrollable*"); Xen_check_type(Xen_is_GtkAdjustment_(hadjustment), hadjustment, 2, "gtk_scrollable_set_hadjustment", "GtkAdjustment*"); gtk_scrollable_set_hadjustment(Xen_to_C_GtkScrollable_(scrollable), Xen_to_C_GtkAdjustment_(hadjustment)); return(Xen_false); } static Xen gxg_gtk_scrollable_get_vadjustment(Xen scrollable) { #define H_gtk_scrollable_get_vadjustment "GtkAdjustment* gtk_scrollable_get_vadjustment(GtkScrollable* scrollable)" Xen_check_type(Xen_is_GtkScrollable_(scrollable), scrollable, 1, "gtk_scrollable_get_vadjustment", "GtkScrollable*"); return(C_to_Xen_GtkAdjustment_(gtk_scrollable_get_vadjustment(Xen_to_C_GtkScrollable_(scrollable)))); } static Xen gxg_gtk_scrollable_set_vadjustment(Xen scrollable, Xen vadjustment) { #define H_gtk_scrollable_set_vadjustment "void gtk_scrollable_set_vadjustment(GtkScrollable* scrollable, \ GtkAdjustment* vadjustment)" Xen_check_type(Xen_is_GtkScrollable_(scrollable), scrollable, 1, "gtk_scrollable_set_vadjustment", "GtkScrollable*"); Xen_check_type(Xen_is_GtkAdjustment_(vadjustment), vadjustment, 2, "gtk_scrollable_set_vadjustment", "GtkAdjustment*"); gtk_scrollable_set_vadjustment(Xen_to_C_GtkScrollable_(scrollable), Xen_to_C_GtkAdjustment_(vadjustment)); return(Xen_false); } static Xen gxg_gtk_assistant_next_page(Xen assistant) { #define H_gtk_assistant_next_page "void gtk_assistant_next_page(GtkAssistant* assistant)" Xen_check_type(Xen_is_GtkAssistant_(assistant), assistant, 1, "gtk_assistant_next_page", "GtkAssistant*"); gtk_assistant_next_page(Xen_to_C_GtkAssistant_(assistant)); return(Xen_false); } static Xen gxg_gtk_assistant_previous_page(Xen assistant) { #define H_gtk_assistant_previous_page "void gtk_assistant_previous_page(GtkAssistant* assistant)" Xen_check_type(Xen_is_GtkAssistant_(assistant), assistant, 1, "gtk_assistant_previous_page", "GtkAssistant*"); gtk_assistant_previous_page(Xen_to_C_GtkAssistant_(assistant)); return(Xen_false); } static Xen gxg_gtk_combo_box_new_with_model_and_entry(Xen model) { #define H_gtk_combo_box_new_with_model_and_entry "GtkWidget* gtk_combo_box_new_with_model_and_entry(GtkTreeModel* model)" Xen_check_type(Xen_is_GtkTreeModel_(model), model, 1, "gtk_combo_box_new_with_model_and_entry", "GtkTreeModel*"); return(C_to_Xen_GtkWidget_(gtk_combo_box_new_with_model_and_entry(Xen_to_C_GtkTreeModel_(model)))); } static Xen gxg_gtk_scrollable_get_hscroll_policy(Xen scrollable) { #define H_gtk_scrollable_get_hscroll_policy "GtkScrollablePolicy gtk_scrollable_get_hscroll_policy(GtkScrollable* scrollable)" Xen_check_type(Xen_is_GtkScrollable_(scrollable), scrollable, 1, "gtk_scrollable_get_hscroll_policy", "GtkScrollable*"); return(C_to_Xen_GtkScrollablePolicy(gtk_scrollable_get_hscroll_policy(Xen_to_C_GtkScrollable_(scrollable)))); } static Xen gxg_gtk_scrollable_set_hscroll_policy(Xen scrollable, Xen policy) { #define H_gtk_scrollable_set_hscroll_policy "void gtk_scrollable_set_hscroll_policy(GtkScrollable* scrollable, \ GtkScrollablePolicy policy)" Xen_check_type(Xen_is_GtkScrollable_(scrollable), scrollable, 1, "gtk_scrollable_set_hscroll_policy", "GtkScrollable*"); Xen_check_type(Xen_is_GtkScrollablePolicy(policy), policy, 2, "gtk_scrollable_set_hscroll_policy", "GtkScrollablePolicy"); gtk_scrollable_set_hscroll_policy(Xen_to_C_GtkScrollable_(scrollable), Xen_to_C_GtkScrollablePolicy(policy)); return(Xen_false); } static Xen gxg_gtk_scrollable_get_vscroll_policy(Xen scrollable) { #define H_gtk_scrollable_get_vscroll_policy "GtkScrollablePolicy gtk_scrollable_get_vscroll_policy(GtkScrollable* scrollable)" Xen_check_type(Xen_is_GtkScrollable_(scrollable), scrollable, 1, "gtk_scrollable_get_vscroll_policy", "GtkScrollable*"); return(C_to_Xen_GtkScrollablePolicy(gtk_scrollable_get_vscroll_policy(Xen_to_C_GtkScrollable_(scrollable)))); } static Xen gxg_gtk_scrollable_set_vscroll_policy(Xen scrollable, Xen policy) { #define H_gtk_scrollable_set_vscroll_policy "void gtk_scrollable_set_vscroll_policy(GtkScrollable* scrollable, \ GtkScrollablePolicy policy)" Xen_check_type(Xen_is_GtkScrollable_(scrollable), scrollable, 1, "gtk_scrollable_set_vscroll_policy", "GtkScrollable*"); Xen_check_type(Xen_is_GtkScrollablePolicy(policy), policy, 2, "gtk_scrollable_set_vscroll_policy", "GtkScrollablePolicy"); gtk_scrollable_set_vscroll_policy(Xen_to_C_GtkScrollable_(scrollable), Xen_to_C_GtkScrollablePolicy(policy)); return(Xen_false); } static Xen gxg_gtk_switch_new(void) { #define H_gtk_switch_new "GtkWidget* gtk_switch_new( void)" return(C_to_Xen_GtkWidget_(gtk_switch_new())); } static Xen gxg_gtk_switch_set_active(Xen sw, Xen is_active) { #define H_gtk_switch_set_active "void gtk_switch_set_active(GtkSwitch* sw, gboolean is_active)" Xen_check_type(Xen_is_GtkSwitch_(sw), sw, 1, "gtk_switch_set_active", "GtkSwitch*"); Xen_check_type(Xen_is_gboolean(is_active), is_active, 2, "gtk_switch_set_active", "gboolean"); gtk_switch_set_active(Xen_to_C_GtkSwitch_(sw), Xen_to_C_gboolean(is_active)); return(Xen_false); } static Xen gxg_gtk_switch_get_active(Xen sw) { #define H_gtk_switch_get_active "gboolean gtk_switch_get_active(GtkSwitch* sw)" Xen_check_type(Xen_is_GtkSwitch_(sw), sw, 1, "gtk_switch_get_active", "GtkSwitch*"); return(C_to_Xen_gboolean(gtk_switch_get_active(Xen_to_C_GtkSwitch_(sw)))); } static Xen gxg_gdk_window_get_clip_region(Xen window) { #define H_gdk_window_get_clip_region "cairo_region_t* gdk_window_get_clip_region(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_get_clip_region", "GdkWindow*"); return(C_to_Xen_cairo_region_t_(gdk_window_get_clip_region(Xen_to_C_GdkWindow_(window)))); } static Xen gxg_gdk_window_get_visible_region(Xen window) { #define H_gdk_window_get_visible_region "cairo_region_t* gdk_window_get_visible_region(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_get_visible_region", "GdkWindow*"); return(C_to_Xen_cairo_region_t_(gdk_window_get_visible_region(Xen_to_C_GdkWindow_(window)))); } static Xen gxg_gtk_border_new(void) { #define H_gtk_border_new "GtkBorder* gtk_border_new( void)" return(C_to_Xen_GtkBorder_(gtk_border_new())); } static Xen gxg_gtk_border_copy(Xen border_) { #define H_gtk_border_copy "GtkBorder* gtk_border_copy(GtkBorder* border_)" Xen_check_type(Xen_is_GtkBorder_(border_), border_, 1, "gtk_border_copy", "GtkBorder*"); return(C_to_Xen_GtkBorder_(gtk_border_copy(Xen_to_C_GtkBorder_(border_)))); } static Xen gxg_gtk_border_free(Xen border_) { #define H_gtk_border_free "void gtk_border_free(GtkBorder* border_)" Xen_check_type(Xen_is_GtkBorder_(border_), border_, 1, "gtk_border_free", "GtkBorder*"); gtk_border_free(Xen_to_C_GtkBorder_(border_)); return(Xen_false); } static Xen gxg_gtk_combo_box_get_id_column(Xen combo_box) { #define H_gtk_combo_box_get_id_column "gint gtk_combo_box_get_id_column(GtkComboBox* combo_box)" Xen_check_type(Xen_is_GtkComboBox_(combo_box), combo_box, 1, "gtk_combo_box_get_id_column", "GtkComboBox*"); return(C_to_Xen_gint(gtk_combo_box_get_id_column(Xen_to_C_GtkComboBox_(combo_box)))); } static Xen gxg_gtk_combo_box_set_id_column(Xen combo_box, Xen id_column) { #define H_gtk_combo_box_set_id_column "void gtk_combo_box_set_id_column(GtkComboBox* combo_box, gint id_column)" Xen_check_type(Xen_is_GtkComboBox_(combo_box), combo_box, 1, "gtk_combo_box_set_id_column", "GtkComboBox*"); Xen_check_type(Xen_is_gint(id_column), id_column, 2, "gtk_combo_box_set_id_column", "gint"); gtk_combo_box_set_id_column(Xen_to_C_GtkComboBox_(combo_box), Xen_to_C_gint(id_column)); return(Xen_false); } static Xen gxg_gtk_combo_box_get_active_id(Xen combo_box) { #define H_gtk_combo_box_get_active_id "gchar* gtk_combo_box_get_active_id(GtkComboBox* combo_box)" Xen_check_type(Xen_is_GtkComboBox_(combo_box), combo_box, 1, "gtk_combo_box_get_active_id", "GtkComboBox*"); return(C_to_Xen_gchar_(gtk_combo_box_get_active_id(Xen_to_C_GtkComboBox_(combo_box)))); } static Xen gxg_gtk_combo_box_text_insert(Xen combo_box, Xen position, Xen id, Xen text) { #define H_gtk_combo_box_text_insert "void gtk_combo_box_text_insert(GtkComboBoxText* combo_box, gint position, \ gchar* id, gchar* text)" Xen_check_type(Xen_is_GtkComboBoxText_(combo_box), combo_box, 1, "gtk_combo_box_text_insert", "GtkComboBoxText*"); Xen_check_type(Xen_is_gint(position), position, 2, "gtk_combo_box_text_insert", "gint"); Xen_check_type(Xen_is_gchar_(id), id, 3, "gtk_combo_box_text_insert", "gchar*"); Xen_check_type(Xen_is_gchar_(text), text, 4, "gtk_combo_box_text_insert", "gchar*"); gtk_combo_box_text_insert(Xen_to_C_GtkComboBoxText_(combo_box), Xen_to_C_gint(position), (const gchar*)Xen_to_C_gchar_(id), (const gchar*)Xen_to_C_gchar_(text)); return(Xen_false); } static Xen gxg_gtk_combo_box_text_append(Xen combo_box, Xen id, Xen text) { #define H_gtk_combo_box_text_append "void gtk_combo_box_text_append(GtkComboBoxText* combo_box, gchar* id, \ gchar* text)" Xen_check_type(Xen_is_GtkComboBoxText_(combo_box), combo_box, 1, "gtk_combo_box_text_append", "GtkComboBoxText*"); Xen_check_type(Xen_is_gchar_(id), id, 2, "gtk_combo_box_text_append", "gchar*"); Xen_check_type(Xen_is_gchar_(text), text, 3, "gtk_combo_box_text_append", "gchar*"); gtk_combo_box_text_append(Xen_to_C_GtkComboBoxText_(combo_box), (const gchar*)Xen_to_C_gchar_(id), (const gchar*)Xen_to_C_gchar_(text)); return(Xen_false); } static Xen gxg_gtk_combo_box_text_prepend(Xen combo_box, Xen id, Xen text) { #define H_gtk_combo_box_text_prepend "void gtk_combo_box_text_prepend(GtkComboBoxText* combo_box, gchar* id, \ gchar* text)" Xen_check_type(Xen_is_GtkComboBoxText_(combo_box), combo_box, 1, "gtk_combo_box_text_prepend", "GtkComboBoxText*"); Xen_check_type(Xen_is_gchar_(id), id, 2, "gtk_combo_box_text_prepend", "gchar*"); Xen_check_type(Xen_is_gchar_(text), text, 3, "gtk_combo_box_text_prepend", "gchar*"); gtk_combo_box_text_prepend(Xen_to_C_GtkComboBoxText_(combo_box), (const gchar*)Xen_to_C_gchar_(id), (const gchar*)Xen_to_C_gchar_(text)); return(Xen_false); } static Xen gxg_gtk_button_box_new(Xen orientation) { #define H_gtk_button_box_new "GtkWidget* gtk_button_box_new(GtkOrientation orientation)" Xen_check_type(Xen_is_GtkOrientation(orientation), orientation, 1, "gtk_button_box_new", "GtkOrientation"); return(C_to_Xen_GtkWidget_(gtk_button_box_new(Xen_to_C_GtkOrientation(orientation)))); } static Xen gxg_gtk_box_new(Xen orientation, Xen spacing) { #define H_gtk_box_new "GtkWidget* gtk_box_new(GtkOrientation orientation, gint spacing)" Xen_check_type(Xen_is_GtkOrientation(orientation), orientation, 1, "gtk_box_new", "GtkOrientation"); Xen_check_type(Xen_is_gint(spacing), spacing, 2, "gtk_box_new", "gint"); return(C_to_Xen_GtkWidget_(gtk_box_new(Xen_to_C_GtkOrientation(orientation), Xen_to_C_gint(spacing)))); } static Xen gxg_gtk_tree_view_set_cursor_on_cell(Xen tree_view, Xen path, Xen focus_column, Xen focus_cell, Xen start_editing) { #define H_gtk_tree_view_set_cursor_on_cell "void gtk_tree_view_set_cursor_on_cell(GtkTreeView* tree_view, \ GtkTreePath* path, GtkTreeViewColumn* focus_column, GtkCellRenderer* focus_cell, gboolean start_editing)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_set_cursor_on_cell", "GtkTreeView*"); Xen_check_type(Xen_is_GtkTreePath_(path), path, 2, "gtk_tree_view_set_cursor_on_cell", "GtkTreePath*"); Xen_check_type(Xen_is_GtkTreeViewColumn_(focus_column), focus_column, 3, "gtk_tree_view_set_cursor_on_cell", "GtkTreeViewColumn*"); Xen_check_type(Xen_is_GtkCellRenderer_(focus_cell), focus_cell, 4, "gtk_tree_view_set_cursor_on_cell", "GtkCellRenderer*"); Xen_check_type(Xen_is_gboolean(start_editing), start_editing, 5, "gtk_tree_view_set_cursor_on_cell", "gboolean"); gtk_tree_view_set_cursor_on_cell(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_GtkTreePath_(path), Xen_to_C_GtkTreeViewColumn_(focus_column), Xen_to_C_GtkCellRenderer_(focus_cell), Xen_to_C_gboolean(start_editing)); return(Xen_false); } static Xen gxg_gtk_tree_view_set_rubber_banding(Xen tree_view, Xen enable) { #define H_gtk_tree_view_set_rubber_banding "void gtk_tree_view_set_rubber_banding(GtkTreeView* tree_view, \ gboolean enable)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_set_rubber_banding", "GtkTreeView*"); Xen_check_type(Xen_is_gboolean(enable), enable, 2, "gtk_tree_view_set_rubber_banding", "gboolean"); gtk_tree_view_set_rubber_banding(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_gboolean(enable)); return(Xen_false); } static Xen gxg_gtk_tree_view_get_rubber_banding(Xen tree_view) { #define H_gtk_tree_view_get_rubber_banding "gboolean gtk_tree_view_get_rubber_banding(GtkTreeView* tree_view)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_get_rubber_banding", "GtkTreeView*"); return(C_to_Xen_gboolean(gtk_tree_view_get_rubber_banding(Xen_to_C_GtkTreeView_(tree_view)))); } static Xen gxg_gtk_tooltip_set_markup(Xen tooltip, Xen markup) { #define H_gtk_tooltip_set_markup "void gtk_tooltip_set_markup(GtkTooltip* tooltip, gchar* markup)" Xen_check_type(Xen_is_GtkTooltip_(tooltip), tooltip, 1, "gtk_tooltip_set_markup", "GtkTooltip*"); Xen_check_type(Xen_is_gchar_(markup), markup, 2, "gtk_tooltip_set_markup", "gchar*"); gtk_tooltip_set_markup(Xen_to_C_GtkTooltip_(tooltip), (const gchar*)Xen_to_C_gchar_(markup)); return(Xen_false); } static Xen gxg_gtk_tooltip_set_icon(Xen tooltip, Xen pixbuf) { #define H_gtk_tooltip_set_icon "void gtk_tooltip_set_icon(GtkTooltip* tooltip, GdkPixbuf* pixbuf)" Xen_check_type(Xen_is_GtkTooltip_(tooltip), tooltip, 1, "gtk_tooltip_set_icon", "GtkTooltip*"); Xen_check_type(Xen_is_GdkPixbuf_(pixbuf), pixbuf, 2, "gtk_tooltip_set_icon", "GdkPixbuf*"); gtk_tooltip_set_icon(Xen_to_C_GtkTooltip_(tooltip), Xen_to_C_GdkPixbuf_(pixbuf)); return(Xen_false); } static Xen gxg_gtk_tooltip_set_custom(Xen tooltip, Xen custom_widget) { #define H_gtk_tooltip_set_custom "void gtk_tooltip_set_custom(GtkTooltip* tooltip, GtkWidget* custom_widget)" Xen_check_type(Xen_is_GtkTooltip_(tooltip), tooltip, 1, "gtk_tooltip_set_custom", "GtkTooltip*"); Xen_check_type(Xen_is_GtkWidget_(custom_widget), custom_widget, 2, "gtk_tooltip_set_custom", "GtkWidget*"); gtk_tooltip_set_custom(Xen_to_C_GtkTooltip_(tooltip), Xen_to_C_GtkWidget_(custom_widget)); return(Xen_false); } static Xen gxg_gtk_tooltip_trigger_tooltip_query(Xen display) { #define H_gtk_tooltip_trigger_tooltip_query "void gtk_tooltip_trigger_tooltip_query(GdkDisplay* display)" Xen_check_type(Xen_is_GdkDisplay_(display), display, 1, "gtk_tooltip_trigger_tooltip_query", "GdkDisplay*"); gtk_tooltip_trigger_tooltip_query(Xen_to_C_GdkDisplay_(display)); return(Xen_false); } static Xen gxg_gtk_button_set_image_position(Xen button, Xen position) { #define H_gtk_button_set_image_position "void gtk_button_set_image_position(GtkButton* button, GtkPositionType position)" Xen_check_type(Xen_is_GtkButton_(button), button, 1, "gtk_button_set_image_position", "GtkButton*"); Xen_check_type(Xen_is_GtkPositionType(position), position, 2, "gtk_button_set_image_position", "GtkPositionType"); gtk_button_set_image_position(Xen_to_C_GtkButton_(button), Xen_to_C_GtkPositionType(position)); return(Xen_false); } static Xen gxg_gtk_button_get_image_position(Xen button) { #define H_gtk_button_get_image_position "GtkPositionType gtk_button_get_image_position(GtkButton* button)" Xen_check_type(Xen_is_GtkButton_(button), button, 1, "gtk_button_get_image_position", "GtkButton*"); return(C_to_Xen_GtkPositionType(gtk_button_get_image_position(Xen_to_C_GtkButton_(button)))); } static Xen gxg_gtk_show_uri(Xen screen, Xen uri, Xen timestamp, Xen ignore_error) { #define H_gtk_show_uri "gboolean gtk_show_uri(GdkScreen* screen, gchar* uri, guint32 timestamp, GError** [error])" GError* ref_error = NULL; Xen_check_type(Xen_is_GdkScreen_(screen), screen, 1, "gtk_show_uri", "GdkScreen*"); Xen_check_type(Xen_is_gchar_(uri), uri, 2, "gtk_show_uri", "gchar*"); Xen_check_type(Xen_is_guint32(timestamp), timestamp, 3, "gtk_show_uri", "guint32"); { Xen result; result = C_to_Xen_gboolean(gtk_show_uri(Xen_to_C_GdkScreen_(screen), (const gchar*)Xen_to_C_gchar_(uri), Xen_to_C_guint32(timestamp), &ref_error)); return(Xen_list_2(result, C_to_Xen_GError_(ref_error))); } } static Xen gxg_gtk_tree_view_column_new_with_area(Xen area) { #define H_gtk_tree_view_column_new_with_area "GtkTreeViewColumn* gtk_tree_view_column_new_with_area(GtkCellArea* area)" Xen_check_type(Xen_is_GtkCellArea_(area), area, 1, "gtk_tree_view_column_new_with_area", "GtkCellArea*"); return(C_to_Xen_GtkTreeViewColumn_(gtk_tree_view_column_new_with_area(Xen_to_C_GtkCellArea_(area)))); } static Xen gxg_gtk_tree_view_column_get_button(Xen tree_column) { #define H_gtk_tree_view_column_get_button "GtkWidget* gtk_tree_view_column_get_button(GtkTreeViewColumn* tree_column)" Xen_check_type(Xen_is_GtkTreeViewColumn_(tree_column), tree_column, 1, "gtk_tree_view_column_get_button", "GtkTreeViewColumn*"); return(C_to_Xen_GtkWidget_(gtk_tree_view_column_get_button(Xen_to_C_GtkTreeViewColumn_(tree_column)))); } static Xen gxg_gtk_tree_view_column_focus_cell(Xen tree_column, Xen cell) { #define H_gtk_tree_view_column_focus_cell "void gtk_tree_view_column_focus_cell(GtkTreeViewColumn* tree_column, \ GtkCellRenderer* cell)" Xen_check_type(Xen_is_GtkTreeViewColumn_(tree_column), tree_column, 1, "gtk_tree_view_column_focus_cell", "GtkTreeViewColumn*"); Xen_check_type(Xen_is_GtkCellRenderer_(cell), cell, 2, "gtk_tree_view_column_focus_cell", "GtkCellRenderer*"); gtk_tree_view_column_focus_cell(Xen_to_C_GtkTreeViewColumn_(tree_column), Xen_to_C_GtkCellRenderer_(cell)); return(Xen_false); } static Xen gxg_gtk_clipboard_wait_is_uris_available(Xen clipboard) { #define H_gtk_clipboard_wait_is_uris_available "gboolean gtk_clipboard_wait_is_uris_available(GtkClipboard* clipboard)" Xen_check_type(Xen_is_GtkClipboard_(clipboard), clipboard, 1, "gtk_clipboard_wait_is_uris_available", "GtkClipboard*"); return(C_to_Xen_gboolean(gtk_clipboard_wait_is_uris_available(Xen_to_C_GtkClipboard_(clipboard)))); } static Xen gxg_gtk_toolbar_set_drop_highlight_item(Xen toolbar, Xen tool_item, Xen index) { #define H_gtk_toolbar_set_drop_highlight_item "void gtk_toolbar_set_drop_highlight_item(GtkToolbar* toolbar, \ GtkToolItem* tool_item, gint index)" Xen_check_type(Xen_is_GtkToolbar_(toolbar), toolbar, 1, "gtk_toolbar_set_drop_highlight_item", "GtkToolbar*"); Xen_check_type(Xen_is_GtkToolItem_(tool_item), tool_item, 2, "gtk_toolbar_set_drop_highlight_item", "GtkToolItem*"); Xen_check_type(Xen_is_gint(index), index, 3, "gtk_toolbar_set_drop_highlight_item", "gint"); gtk_toolbar_set_drop_highlight_item(Xen_to_C_GtkToolbar_(toolbar), Xen_to_C_GtkToolItem_(tool_item), Xen_to_C_gint(index)); return(Xen_false); } static Xen gxg_gtk_tool_item_toolbar_reconfigured(Xen tool_item) { #define H_gtk_tool_item_toolbar_reconfigured "void gtk_tool_item_toolbar_reconfigured(GtkToolItem* tool_item)" Xen_check_type(Xen_is_GtkToolItem_(tool_item), tool_item, 1, "gtk_tool_item_toolbar_reconfigured", "GtkToolItem*"); gtk_tool_item_toolbar_reconfigured(Xen_to_C_GtkToolItem_(tool_item)); return(Xen_false); } static Xen gxg_gtk_orientable_set_orientation(Xen orientable, Xen orientation) { #define H_gtk_orientable_set_orientation "void gtk_orientable_set_orientation(GtkOrientable* orientable, \ GtkOrientation orientation)" Xen_check_type(Xen_is_GtkOrientable_(orientable), orientable, 1, "gtk_orientable_set_orientation", "GtkOrientable*"); Xen_check_type(Xen_is_GtkOrientation(orientation), orientation, 2, "gtk_orientable_set_orientation", "GtkOrientation"); gtk_orientable_set_orientation(Xen_to_C_GtkOrientable_(orientable), Xen_to_C_GtkOrientation(orientation)); return(Xen_false); } static Xen gxg_gtk_orientable_get_orientation(Xen orientable) { #define H_gtk_orientable_get_orientation "GtkOrientation gtk_orientable_get_orientation(GtkOrientable* orientable)" Xen_check_type(Xen_is_GtkOrientable_(orientable), orientable, 1, "gtk_orientable_get_orientation", "GtkOrientable*"); return(C_to_Xen_GtkOrientation(gtk_orientable_get_orientation(Xen_to_C_GtkOrientable_(orientable)))); } static Xen gxg_gtk_parse_args(Xen argc, Xen argv) { #define H_gtk_parse_args "void gtk_parse_args(int* {argc}, char*** |argv|)" int ref_argc; char** ref_argv = NULL; ref_argc = Xen_to_C_int(argc); ref_argv = (char**)calloc(ref_argc, sizeof(char*)); { int i; Xen lst; lst = Xen_copy_arg(argv); for (i = 0; i < ref_argc; i++, lst = Xen_cdr(lst)) ref_argv[i] = Xen_to_C_char_(Xen_car(lst)); } gtk_parse_args(&ref_argc, &ref_argv); return(Xen_list_2(C_to_Xen_int(ref_argc), C_to_Xen_char__(ref_argv))); } static Xen gxg_gtk_get_major_version(void) { #define H_gtk_get_major_version "guint gtk_get_major_version( void)" return(C_to_Xen_guint((guint)gtk_get_major_version())); } static Xen gxg_gtk_get_minor_version(void) { #define H_gtk_get_minor_version "guint gtk_get_minor_version( void)" return(C_to_Xen_guint((guint)gtk_get_minor_version())); } static Xen gxg_gtk_get_micro_version(void) { #define H_gtk_get_micro_version "guint gtk_get_micro_version( void)" return(C_to_Xen_guint((guint)gtk_get_micro_version())); } static Xen gxg_gtk_get_binary_age(void) { #define H_gtk_get_binary_age "guint gtk_get_binary_age( void)" return(C_to_Xen_guint((guint)gtk_get_binary_age())); } static Xen gxg_gtk_get_interface_age(void) { #define H_gtk_get_interface_age "guint gtk_get_interface_age( void)" return(C_to_Xen_guint((guint)gtk_get_interface_age())); } static Xen gxg_gtk_progress_bar_set_show_text(Xen pbar, Xen show_text) { #define H_gtk_progress_bar_set_show_text "void gtk_progress_bar_set_show_text(GtkProgressBar* pbar, \ gboolean show_text)" Xen_check_type(Xen_is_GtkProgressBar_(pbar), pbar, 1, "gtk_progress_bar_set_show_text", "GtkProgressBar*"); Xen_check_type(Xen_is_gboolean(show_text), show_text, 2, "gtk_progress_bar_set_show_text", "gboolean"); gtk_progress_bar_set_show_text(Xen_to_C_GtkProgressBar_(pbar), Xen_to_C_gboolean(show_text)); return(Xen_false); } static Xen gxg_gtk_progress_bar_get_show_text(Xen pbar) { #define H_gtk_progress_bar_get_show_text "gboolean gtk_progress_bar_get_show_text(GtkProgressBar* pbar)" Xen_check_type(Xen_is_GtkProgressBar_(pbar), pbar, 1, "gtk_progress_bar_get_show_text", "GtkProgressBar*"); return(C_to_Xen_gboolean(gtk_progress_bar_get_show_text(Xen_to_C_GtkProgressBar_(pbar)))); } static Xen gxg_gtk_invisible_new_for_screen(Xen screen) { #define H_gtk_invisible_new_for_screen "GtkWidget* gtk_invisible_new_for_screen(GdkScreen* screen)" Xen_check_type(Xen_is_GdkScreen_(screen), screen, 1, "gtk_invisible_new_for_screen", "GdkScreen*"); return(C_to_Xen_GtkWidget_(gtk_invisible_new_for_screen(Xen_to_C_GdkScreen_(screen)))); } static Xen gxg_gtk_invisible_set_screen(Xen invisible, Xen screen) { #define H_gtk_invisible_set_screen "void gtk_invisible_set_screen(GtkInvisible* invisible, GdkScreen* screen)" Xen_check_type(Xen_is_GtkInvisible_(invisible), invisible, 1, "gtk_invisible_set_screen", "GtkInvisible*"); Xen_check_type(Xen_is_GdkScreen_(screen), screen, 2, "gtk_invisible_set_screen", "GdkScreen*"); gtk_invisible_set_screen(Xen_to_C_GtkInvisible_(invisible), Xen_to_C_GdkScreen_(screen)); return(Xen_false); } static Xen gxg_gtk_invisible_get_screen(Xen invisible) { #define H_gtk_invisible_get_screen "GdkScreen* gtk_invisible_get_screen(GtkInvisible* invisible)" Xen_check_type(Xen_is_GtkInvisible_(invisible), invisible, 1, "gtk_invisible_get_screen", "GtkInvisible*"); return(C_to_Xen_GdkScreen_(gtk_invisible_get_screen(Xen_to_C_GtkInvisible_(invisible)))); } static Xen gxg_gtk_entry_get_icon_storage_type(Xen entry, Xen icon_pos) { #define H_gtk_entry_get_icon_storage_type "GtkImageType gtk_entry_get_icon_storage_type(GtkEntry* entry, \ GtkEntryIconPosition icon_pos)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_get_icon_storage_type", "GtkEntry*"); Xen_check_type(Xen_is_GtkEntryIconPosition(icon_pos), icon_pos, 2, "gtk_entry_get_icon_storage_type", "GtkEntryIconPosition"); return(C_to_Xen_GtkImageType(gtk_entry_get_icon_storage_type(Xen_to_C_GtkEntry_(entry), Xen_to_C_GtkEntryIconPosition(icon_pos)))); } static Xen gxg_gtk_entry_get_icon_pixbuf(Xen entry, Xen icon_pos) { #define H_gtk_entry_get_icon_pixbuf "GdkPixbuf* gtk_entry_get_icon_pixbuf(GtkEntry* entry, GtkEntryIconPosition icon_pos)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_get_icon_pixbuf", "GtkEntry*"); Xen_check_type(Xen_is_GtkEntryIconPosition(icon_pos), icon_pos, 2, "gtk_entry_get_icon_pixbuf", "GtkEntryIconPosition"); return(C_to_Xen_GdkPixbuf_(gtk_entry_get_icon_pixbuf(Xen_to_C_GtkEntry_(entry), Xen_to_C_GtkEntryIconPosition(icon_pos)))); } static Xen gxg_gtk_entry_get_icon_gicon(Xen entry, Xen icon_pos) { #define H_gtk_entry_get_icon_gicon "GIcon* gtk_entry_get_icon_gicon(GtkEntry* entry, GtkEntryIconPosition icon_pos)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_get_icon_gicon", "GtkEntry*"); Xen_check_type(Xen_is_GtkEntryIconPosition(icon_pos), icon_pos, 2, "gtk_entry_get_icon_gicon", "GtkEntryIconPosition"); return(C_to_Xen_GIcon_(gtk_entry_get_icon_gicon(Xen_to_C_GtkEntry_(entry), Xen_to_C_GtkEntryIconPosition(icon_pos)))); } static Xen gxg_gtk_container_propagate_draw(Xen container, Xen child, Xen cr) { #define H_gtk_container_propagate_draw "void gtk_container_propagate_draw(GtkContainer* container, \ GtkWidget* child, cairo_t* cr)" Xen_check_type(Xen_is_GtkContainer_(container), container, 1, "gtk_container_propagate_draw", "GtkContainer*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_container_propagate_draw", "GtkWidget*"); Xen_check_type(Xen_is_cairo_t_(cr), cr, 3, "gtk_container_propagate_draw", "cairo_t*"); gtk_container_propagate_draw(Xen_to_C_GtkContainer_(container), Xen_to_C_GtkWidget_(child), Xen_to_C_cairo_t_(cr)); return(Xen_false); } static Xen gxg_gtk_container_set_focus_chain(Xen container, Xen focusable_widgets) { #define H_gtk_container_set_focus_chain "void gtk_container_set_focus_chain(GtkContainer* container, \ GList* focusable_widgets)" Xen_check_type(Xen_is_GtkContainer_(container), container, 1, "gtk_container_set_focus_chain", "GtkContainer*"); Xen_check_type(Xen_is_GList_(focusable_widgets), focusable_widgets, 2, "gtk_container_set_focus_chain", "GList*"); gtk_container_set_focus_chain(Xen_to_C_GtkContainer_(container), Xen_to_C_GList_(focusable_widgets)); return(Xen_false); } static Xen gxg_gtk_container_get_focus_chain(Xen container, Xen ignore_focusable_widgets) { #define H_gtk_container_get_focus_chain "gboolean gtk_container_get_focus_chain(GtkContainer* container, \ GList** [focusable_widgets])" GList* ref_focusable_widgets = NULL; Xen_check_type(Xen_is_GtkContainer_(container), container, 1, "gtk_container_get_focus_chain", "GtkContainer*"); { Xen result; result = C_to_Xen_gboolean(gtk_container_get_focus_chain(Xen_to_C_GtkContainer_(container), &ref_focusable_widgets)); return(Xen_list_2(result, C_to_Xen_GList_(ref_focusable_widgets))); } } static Xen gxg_gtk_container_unset_focus_chain(Xen container) { #define H_gtk_container_unset_focus_chain "void gtk_container_unset_focus_chain(GtkContainer* container)" Xen_check_type(Xen_is_GtkContainer_(container), container, 1, "gtk_container_unset_focus_chain", "GtkContainer*"); gtk_container_unset_focus_chain(Xen_to_C_GtkContainer_(container)); return(Xen_false); } static Xen gxg_gtk_container_set_focus_child(Xen container, Xen child) { #define H_gtk_container_set_focus_child "void gtk_container_set_focus_child(GtkContainer* container, \ GtkWidget* child)" Xen_check_type(Xen_is_GtkContainer_(container), container, 1, "gtk_container_set_focus_child", "GtkContainer*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_container_set_focus_child", "GtkWidget*"); gtk_container_set_focus_child(Xen_to_C_GtkContainer_(container), Xen_to_C_GtkWidget_(child)); return(Xen_false); } static Xen gxg_gtk_container_set_focus_vadjustment(Xen container, Xen adjustment) { #define H_gtk_container_set_focus_vadjustment "void gtk_container_set_focus_vadjustment(GtkContainer* container, \ GtkAdjustment* adjustment)" Xen_check_type(Xen_is_GtkContainer_(container), container, 1, "gtk_container_set_focus_vadjustment", "GtkContainer*"); Xen_check_type(Xen_is_GtkAdjustment_(adjustment), adjustment, 2, "gtk_container_set_focus_vadjustment", "GtkAdjustment*"); gtk_container_set_focus_vadjustment(Xen_to_C_GtkContainer_(container), Xen_to_C_GtkAdjustment_(adjustment)); return(Xen_false); } static Xen gxg_gtk_container_get_focus_vadjustment(Xen container) { #define H_gtk_container_get_focus_vadjustment "GtkAdjustment* gtk_container_get_focus_vadjustment(GtkContainer* container)" Xen_check_type(Xen_is_GtkContainer_(container), container, 1, "gtk_container_get_focus_vadjustment", "GtkContainer*"); return(C_to_Xen_GtkAdjustment_(gtk_container_get_focus_vadjustment(Xen_to_C_GtkContainer_(container)))); } static Xen gxg_gtk_container_set_focus_hadjustment(Xen container, Xen adjustment) { #define H_gtk_container_set_focus_hadjustment "void gtk_container_set_focus_hadjustment(GtkContainer* container, \ GtkAdjustment* adjustment)" Xen_check_type(Xen_is_GtkContainer_(container), container, 1, "gtk_container_set_focus_hadjustment", "GtkContainer*"); Xen_check_type(Xen_is_GtkAdjustment_(adjustment), adjustment, 2, "gtk_container_set_focus_hadjustment", "GtkAdjustment*"); gtk_container_set_focus_hadjustment(Xen_to_C_GtkContainer_(container), Xen_to_C_GtkAdjustment_(adjustment)); return(Xen_false); } static Xen gxg_gtk_container_get_focus_hadjustment(Xen container) { #define H_gtk_container_get_focus_hadjustment "GtkAdjustment* gtk_container_get_focus_hadjustment(GtkContainer* container)" Xen_check_type(Xen_is_GtkContainer_(container), container, 1, "gtk_container_get_focus_hadjustment", "GtkContainer*"); return(C_to_Xen_GtkAdjustment_(gtk_container_get_focus_hadjustment(Xen_to_C_GtkContainer_(container)))); } static Xen gxg_gtk_assistant_commit(Xen assistant) { #define H_gtk_assistant_commit "void gtk_assistant_commit(GtkAssistant* assistant)" Xen_check_type(Xen_is_GtkAssistant_(assistant), assistant, 1, "gtk_assistant_commit", "GtkAssistant*"); gtk_assistant_commit(Xen_to_C_GtkAssistant_(assistant)); return(Xen_false); } static Xen gxg_gtk_window_set_skip_taskbar_hint(Xen window, Xen setting) { #define H_gtk_window_set_skip_taskbar_hint "void gtk_window_set_skip_taskbar_hint(GtkWindow* window, \ gboolean setting)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_set_skip_taskbar_hint", "GtkWindow*"); Xen_check_type(Xen_is_gboolean(setting), setting, 2, "gtk_window_set_skip_taskbar_hint", "gboolean"); gtk_window_set_skip_taskbar_hint(Xen_to_C_GtkWindow_(window), Xen_to_C_gboolean(setting)); return(Xen_false); } static Xen gxg_gtk_window_get_skip_taskbar_hint(Xen window) { #define H_gtk_window_get_skip_taskbar_hint "gboolean gtk_window_get_skip_taskbar_hint(GtkWindow* window)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_get_skip_taskbar_hint", "GtkWindow*"); return(C_to_Xen_gboolean(gtk_window_get_skip_taskbar_hint(Xen_to_C_GtkWindow_(window)))); } static Xen gxg_gtk_window_set_skip_pager_hint(Xen window, Xen setting) { #define H_gtk_window_set_skip_pager_hint "void gtk_window_set_skip_pager_hint(GtkWindow* window, gboolean setting)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_set_skip_pager_hint", "GtkWindow*"); Xen_check_type(Xen_is_gboolean(setting), setting, 2, "gtk_window_set_skip_pager_hint", "gboolean"); gtk_window_set_skip_pager_hint(Xen_to_C_GtkWindow_(window), Xen_to_C_gboolean(setting)); return(Xen_false); } static Xen gxg_gtk_window_get_skip_pager_hint(Xen window) { #define H_gtk_window_get_skip_pager_hint "gboolean gtk_window_get_skip_pager_hint(GtkWindow* window)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_get_skip_pager_hint", "GtkWindow*"); return(C_to_Xen_gboolean(gtk_window_get_skip_pager_hint(Xen_to_C_GtkWindow_(window)))); } static Xen gxg_gtk_window_set_screen(Xen window, Xen screen) { #define H_gtk_window_set_screen "void gtk_window_set_screen(GtkWindow* window, GdkScreen* screen)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_set_screen", "GtkWindow*"); Xen_check_type(Xen_is_GdkScreen_(screen), screen, 2, "gtk_window_set_screen", "GdkScreen*"); gtk_window_set_screen(Xen_to_C_GtkWindow_(window), Xen_to_C_GdkScreen_(screen)); return(Xen_false); } static Xen gxg_gtk_window_get_screen(Xen window) { #define H_gtk_window_get_screen "GdkScreen* gtk_window_get_screen(GtkWindow* window)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_get_screen", "GtkWindow*"); return(C_to_Xen_GdkScreen_(gtk_window_get_screen(Xen_to_C_GtkWindow_(window)))); } static Xen gxg_gtk_window_set_icon_from_file(Xen window, Xen filename, Xen ignore_err) { #define H_gtk_window_set_icon_from_file "gboolean gtk_window_set_icon_from_file(GtkWindow* window, \ gchar* filename, GError** [err])" GError* ref_err = NULL; Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_set_icon_from_file", "GtkWindow*"); Xen_check_type(Xen_is_gchar_(filename), filename, 2, "gtk_window_set_icon_from_file", "gchar*"); { Xen result; result = C_to_Xen_gboolean(gtk_window_set_icon_from_file(Xen_to_C_GtkWindow_(window), (const gchar*)Xen_to_C_gchar_(filename), &ref_err)); return(Xen_list_2(result, C_to_Xen_GError_(ref_err))); } } static Xen gxg_gtk_window_set_default_icon_from_file(Xen filename, Xen ignore_err) { #define H_gtk_window_set_default_icon_from_file "gboolean gtk_window_set_default_icon_from_file(gchar* filename, \ GError** [err])" GError* ref_err = NULL; Xen_check_type(Xen_is_gchar_(filename), filename, 1, "gtk_window_set_default_icon_from_file", "gchar*"); { Xen result; result = C_to_Xen_gboolean(gtk_window_set_default_icon_from_file((const gchar*)Xen_to_C_gchar_(filename), &ref_err)); return(Xen_list_2(result, C_to_Xen_GError_(ref_err))); } } static Xen gxg_gtk_window_fullscreen(Xen window) { #define H_gtk_window_fullscreen "void gtk_window_fullscreen(GtkWindow* window)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_fullscreen", "GtkWindow*"); gtk_window_fullscreen(Xen_to_C_GtkWindow_(window)); return(Xen_false); } static Xen gxg_gtk_window_unfullscreen(Xen window) { #define H_gtk_window_unfullscreen "void gtk_window_unfullscreen(GtkWindow* window)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_unfullscreen", "GtkWindow*"); gtk_window_unfullscreen(Xen_to_C_GtkWindow_(window)); return(Xen_false); } static Xen gxg_gtk_window_get_window_type(Xen window) { #define H_gtk_window_get_window_type "GtkWindowType gtk_window_get_window_type(GtkWindow* window)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_get_window_type", "GtkWindow*"); return(C_to_Xen_GtkWindowType(gtk_window_get_window_type(Xen_to_C_GtkWindow_(window)))); } static Xen gxg_gtk_window_group_add_window(Xen window_group, Xen window) { #define H_gtk_window_group_add_window "void gtk_window_group_add_window(GtkWindowGroup* window_group, \ GtkWindow* window)" Xen_check_type(Xen_is_GtkWindowGroup_(window_group), window_group, 1, "gtk_window_group_add_window", "GtkWindowGroup*"); Xen_check_type(Xen_is_GtkWindow_(window), window, 2, "gtk_window_group_add_window", "GtkWindow*"); gtk_window_group_add_window(Xen_to_C_GtkWindowGroup_(window_group), Xen_to_C_GtkWindow_(window)); return(Xen_false); } static Xen gxg_gtk_window_group_remove_window(Xen window_group, Xen window) { #define H_gtk_window_group_remove_window "void gtk_window_group_remove_window(GtkWindowGroup* window_group, \ GtkWindow* window)" Xen_check_type(Xen_is_GtkWindowGroup_(window_group), window_group, 1, "gtk_window_group_remove_window", "GtkWindowGroup*"); Xen_check_type(Xen_is_GtkWindow_(window), window, 2, "gtk_window_group_remove_window", "GtkWindow*"); gtk_window_group_remove_window(Xen_to_C_GtkWindowGroup_(window_group), Xen_to_C_GtkWindow_(window)); return(Xen_false); } static Xen gxg_gtk_window_group_new(void) { #define H_gtk_window_group_new "GtkWindowGroup* gtk_window_group_new( void)" return(C_to_Xen_GtkWindowGroup_(gtk_window_group_new())); } static Xen gxg_gtk_window_get_group(Xen window) { #define H_gtk_window_get_group "GtkWindowGroup* gtk_window_get_group(GtkWindow* window)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_get_group", "GtkWindow*"); return(C_to_Xen_GtkWindowGroup_(gtk_window_get_group(Xen_to_C_GtkWindow_(window)))); } static Xen gxg_gtk_window_group_list_windows(Xen window_group) { #define H_gtk_window_group_list_windows "GList* gtk_window_group_list_windows(GtkWindowGroup* window_group)" Xen_check_type(Xen_is_GtkWindowGroup_(window_group), window_group, 1, "gtk_window_group_list_windows", "GtkWindowGroup*"); return(C_to_Xen_GList_(gtk_window_group_list_windows(Xen_to_C_GtkWindowGroup_(window_group)))); } static Xen gxg_gtk_window_group_get_current_device_grab(Xen window_group, Xen device) { #define H_gtk_window_group_get_current_device_grab "GtkWidget* gtk_window_group_get_current_device_grab(GtkWindowGroup* window_group, \ GdkDevice* device)" Xen_check_type(Xen_is_GtkWindowGroup_(window_group), window_group, 1, "gtk_window_group_get_current_device_grab", "GtkWindowGroup*"); Xen_check_type(Xen_is_GdkDevice_(device), device, 2, "gtk_window_group_get_current_device_grab", "GdkDevice*"); return(C_to_Xen_GtkWidget_(gtk_window_group_get_current_device_grab(Xen_to_C_GtkWindowGroup_(window_group), Xen_to_C_GdkDevice_(device)))); } static Xen gxg_gtk_window_group_get_current_grab(Xen window_group) { #define H_gtk_window_group_get_current_grab "GtkWidget* gtk_window_group_get_current_grab(GtkWindowGroup* window_group)" Xen_check_type(Xen_is_GtkWindowGroup_(window_group), window_group, 1, "gtk_window_group_get_current_grab", "GtkWindowGroup*"); return(C_to_Xen_GtkWidget_(gtk_window_group_get_current_grab(Xen_to_C_GtkWindowGroup_(window_group)))); } static Xen gxg_gtk_selection_data_get_data(Xen selection_data) { #define H_gtk_selection_data_get_data "guchar* gtk_selection_data_get_data(GtkSelectionData* selection_data)" Xen_check_type(Xen_is_GtkSelectionData_(selection_data), selection_data, 1, "gtk_selection_data_get_data", "GtkSelectionData*"); return(C_to_Xen_guchar_(gtk_selection_data_get_data(Xen_to_C_GtkSelectionData_(selection_data)))); } static Xen gxg_gtk_selection_owner_set_for_display(Xen display, Xen widget, Xen selection, Xen time) { #define H_gtk_selection_owner_set_for_display "gboolean gtk_selection_owner_set_for_display(GdkDisplay* display, \ GtkWidget* widget, GdkAtom selection, guint32 time)" Xen_check_type(Xen_is_GdkDisplay_(display), display, 1, "gtk_selection_owner_set_for_display", "GdkDisplay*"); Xen_check_type(Xen_is_GtkWidget_(widget), widget, 2, "gtk_selection_owner_set_for_display", "GtkWidget*"); Xen_check_type(Xen_is_GdkAtom(selection), selection, 3, "gtk_selection_owner_set_for_display", "GdkAtom"); Xen_check_type(Xen_is_guint32(time), time, 4, "gtk_selection_owner_set_for_display", "guint32"); return(C_to_Xen_gboolean(gtk_selection_owner_set_for_display(Xen_to_C_GdkDisplay_(display), Xen_to_C_GtkWidget_(widget), Xen_to_C_GdkAtom(selection), Xen_to_C_guint32(time)))); } static Xen gxg_gtk_tool_shell_get_text_orientation(Xen shell) { #define H_gtk_tool_shell_get_text_orientation "GtkOrientation gtk_tool_shell_get_text_orientation(GtkToolShell* shell)" Xen_check_type(Xen_is_GtkToolShell_(shell), shell, 1, "gtk_tool_shell_get_text_orientation", "GtkToolShell*"); return(C_to_Xen_GtkOrientation(gtk_tool_shell_get_text_orientation(Xen_to_C_GtkToolShell_(shell)))); } static Xen gxg_gtk_tool_shell_get_text_alignment(Xen shell) { #define H_gtk_tool_shell_get_text_alignment "gfloat gtk_tool_shell_get_text_alignment(GtkToolShell* shell)" Xen_check_type(Xen_is_GtkToolShell_(shell), shell, 1, "gtk_tool_shell_get_text_alignment", "GtkToolShell*"); return(C_to_Xen_gfloat(gtk_tool_shell_get_text_alignment(Xen_to_C_GtkToolShell_(shell)))); } static Xen gxg_gtk_tool_shell_get_ellipsize_mode(Xen shell) { #define H_gtk_tool_shell_get_ellipsize_mode "PangoEllipsizeMode gtk_tool_shell_get_ellipsize_mode(GtkToolShell* shell)" Xen_check_type(Xen_is_GtkToolShell_(shell), shell, 1, "gtk_tool_shell_get_ellipsize_mode", "GtkToolShell*"); return(C_to_Xen_PangoEllipsizeMode(gtk_tool_shell_get_ellipsize_mode(Xen_to_C_GtkToolShell_(shell)))); } static Xen gxg_gtk_tool_shell_get_text_size_group(Xen shell) { #define H_gtk_tool_shell_get_text_size_group "GtkSizeGroup* gtk_tool_shell_get_text_size_group(GtkToolShell* shell)" Xen_check_type(Xen_is_GtkToolShell_(shell), shell, 1, "gtk_tool_shell_get_text_size_group", "GtkToolShell*"); return(C_to_Xen_GtkSizeGroup_(gtk_tool_shell_get_text_size_group(Xen_to_C_GtkToolShell_(shell)))); } static Xen gxg_gtk_tool_shell_get_orientation(Xen shell) { #define H_gtk_tool_shell_get_orientation "GtkOrientation gtk_tool_shell_get_orientation(GtkToolShell* shell)" Xen_check_type(Xen_is_GtkToolShell_(shell), shell, 1, "gtk_tool_shell_get_orientation", "GtkToolShell*"); return(C_to_Xen_GtkOrientation(gtk_tool_shell_get_orientation(Xen_to_C_GtkToolShell_(shell)))); } static Xen gxg_gtk_tool_shell_get_style(Xen shell) { #define H_gtk_tool_shell_get_style "GtkToolbarStyle gtk_tool_shell_get_style(GtkToolShell* shell)" Xen_check_type(Xen_is_GtkToolShell_(shell), shell, 1, "gtk_tool_shell_get_style", "GtkToolShell*"); return(C_to_Xen_GtkToolbarStyle(gtk_tool_shell_get_style(Xen_to_C_GtkToolShell_(shell)))); } static Xen gxg_gtk_tool_shell_get_relief_style(Xen shell) { #define H_gtk_tool_shell_get_relief_style "GtkReliefStyle gtk_tool_shell_get_relief_style(GtkToolShell* shell)" Xen_check_type(Xen_is_GtkToolShell_(shell), shell, 1, "gtk_tool_shell_get_relief_style", "GtkToolShell*"); return(C_to_Xen_GtkReliefStyle(gtk_tool_shell_get_relief_style(Xen_to_C_GtkToolShell_(shell)))); } static Xen gxg_gtk_tool_shell_rebuild_menu(Xen shell) { #define H_gtk_tool_shell_rebuild_menu "void gtk_tool_shell_rebuild_menu(GtkToolShell* shell)" Xen_check_type(Xen_is_GtkToolShell_(shell), shell, 1, "gtk_tool_shell_rebuild_menu", "GtkToolShell*"); gtk_tool_shell_rebuild_menu(Xen_to_C_GtkToolShell_(shell)); return(Xen_false); } static Xen gxg_gtk_accel_map_lock_path(Xen accel_path) { #define H_gtk_accel_map_lock_path "void gtk_accel_map_lock_path(gchar* accel_path)" Xen_check_type(Xen_is_gchar_(accel_path), accel_path, 1, "gtk_accel_map_lock_path", "gchar*"); gtk_accel_map_lock_path((const gchar*)Xen_to_C_gchar_(accel_path)); return(Xen_false); } static Xen gxg_gtk_accel_map_unlock_path(Xen accel_path) { #define H_gtk_accel_map_unlock_path "void gtk_accel_map_unlock_path(gchar* accel_path)" Xen_check_type(Xen_is_gchar_(accel_path), accel_path, 1, "gtk_accel_map_unlock_path", "gchar*"); gtk_accel_map_unlock_path((const gchar*)Xen_to_C_gchar_(accel_path)); return(Xen_false); } static Xen gxg_gtk_icon_theme_lookup_by_gicon(Xen icon_theme, Xen icon, Xen size, Xen flags) { #define H_gtk_icon_theme_lookup_by_gicon "GtkIconInfo* gtk_icon_theme_lookup_by_gicon(GtkIconTheme* icon_theme, \ GIcon* icon, gint size, GtkIconLookupFlags flags)" Xen_check_type(Xen_is_GtkIconTheme_(icon_theme), icon_theme, 1, "gtk_icon_theme_lookup_by_gicon", "GtkIconTheme*"); Xen_check_type(Xen_is_GIcon_(icon), icon, 2, "gtk_icon_theme_lookup_by_gicon", "GIcon*"); Xen_check_type(Xen_is_gint(size), size, 3, "gtk_icon_theme_lookup_by_gicon", "gint"); Xen_check_type(Xen_is_GtkIconLookupFlags(flags), flags, 4, "gtk_icon_theme_lookup_by_gicon", "GtkIconLookupFlags"); return(C_to_Xen_GtkIconInfo_(gtk_icon_theme_lookup_by_gicon(Xen_to_C_GtkIconTheme_(icon_theme), Xen_to_C_GIcon_(icon), Xen_to_C_gint(size), Xen_to_C_GtkIconLookupFlags(flags)))); } static Xen gxg_gtk_icon_info_new_for_pixbuf(Xen icon_theme, Xen pixbuf) { #define H_gtk_icon_info_new_for_pixbuf "GtkIconInfo* gtk_icon_info_new_for_pixbuf(GtkIconTheme* icon_theme, \ GdkPixbuf* pixbuf)" Xen_check_type(Xen_is_GtkIconTheme_(icon_theme), icon_theme, 1, "gtk_icon_info_new_for_pixbuf", "GtkIconTheme*"); Xen_check_type(Xen_is_GdkPixbuf_(pixbuf), pixbuf, 2, "gtk_icon_info_new_for_pixbuf", "GdkPixbuf*"); return(C_to_Xen_GtkIconInfo_(gtk_icon_info_new_for_pixbuf(Xen_to_C_GtkIconTheme_(icon_theme), Xen_to_C_GdkPixbuf_(pixbuf)))); } static Xen gxg_gtk_icon_view_set_item_orientation(Xen icon_view, Xen orientation) { #define H_gtk_icon_view_set_item_orientation "void gtk_icon_view_set_item_orientation(GtkIconView* icon_view, \ GtkOrientation orientation)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_set_item_orientation", "GtkIconView*"); Xen_check_type(Xen_is_GtkOrientation(orientation), orientation, 2, "gtk_icon_view_set_item_orientation", "GtkOrientation"); gtk_icon_view_set_item_orientation(Xen_to_C_GtkIconView_(icon_view), Xen_to_C_GtkOrientation(orientation)); return(Xen_false); } static Xen gxg_gtk_icon_view_get_item_orientation(Xen icon_view) { #define H_gtk_icon_view_get_item_orientation "GtkOrientation gtk_icon_view_get_item_orientation(GtkIconView* icon_view)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_get_item_orientation", "GtkIconView*"); return(C_to_Xen_GtkOrientation(gtk_icon_view_get_item_orientation(Xen_to_C_GtkIconView_(icon_view)))); } static Xen gxg_gtk_text_view_im_context_filter_keypress(Xen text_view, Xen event) { #define H_gtk_text_view_im_context_filter_keypress "gboolean gtk_text_view_im_context_filter_keypress(GtkTextView* text_view, \ GdkEventKey* event)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_im_context_filter_keypress", "GtkTextView*"); Xen_check_type(Xen_is_GdkEventKey_(event), event, 2, "gtk_text_view_im_context_filter_keypress", "GdkEventKey*"); return(C_to_Xen_gboolean(gtk_text_view_im_context_filter_keypress(Xen_to_C_GtkTextView_(text_view), Xen_to_C_GdkEventKey_(event)))); } static Xen gxg_gtk_text_view_reset_im_context(Xen text_view) { #define H_gtk_text_view_reset_im_context "void gtk_text_view_reset_im_context(GtkTextView* text_view)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_reset_im_context", "GtkTextView*"); gtk_text_view_reset_im_context(Xen_to_C_GtkTextView_(text_view)); return(Xen_false); } static Xen gxg_gdk_device_get_position(Xen device, Xen screen, Xen ignore_x, Xen ignore_y) { #define H_gdk_device_get_position "void gdk_device_get_position(GdkDevice* device, GdkScreen** screen, \ gint* [x], gint* [y])" gint ref_x; gint ref_y; Xen_check_type(Xen_is_GdkDevice_(device), device, 1, "gdk_device_get_position", "GdkDevice*"); Xen_check_type(Xen_is_GdkScreen__(screen), screen, 2, "gdk_device_get_position", "GdkScreen**"); gdk_device_get_position(Xen_to_C_GdkDevice_(device), Xen_to_C_GdkScreen__(screen), &ref_x, &ref_y); return(Xen_list_2(C_to_Xen_gint(ref_x), C_to_Xen_gint(ref_y))); } static Xen gxg_gdk_device_get_window_at_position(Xen device, Xen ignore_win_x, Xen ignore_win_y) { #define H_gdk_device_get_window_at_position "GdkWindow* gdk_device_get_window_at_position(GdkDevice* device, \ gint* [win_x], gint* [win_y])" gint ref_win_x; gint ref_win_y; Xen_check_type(Xen_is_GdkDevice_(device), device, 1, "gdk_device_get_window_at_position", "GdkDevice*"); { Xen result; result = C_to_Xen_GdkWindow_(gdk_device_get_window_at_position(Xen_to_C_GdkDevice_(device), &ref_win_x, &ref_win_y)); return(Xen_list_3(result, C_to_Xen_gint(ref_win_x), C_to_Xen_gint(ref_win_y))); } } static Xen gxg_gtk_cell_view_get_draw_sensitive(Xen cell_view) { #define H_gtk_cell_view_get_draw_sensitive "gboolean gtk_cell_view_get_draw_sensitive(GtkCellView* cell_view)" Xen_check_type(Xen_is_GtkCellView_(cell_view), cell_view, 1, "gtk_cell_view_get_draw_sensitive", "GtkCellView*"); return(C_to_Xen_gboolean(gtk_cell_view_get_draw_sensitive(Xen_to_C_GtkCellView_(cell_view)))); } static Xen gxg_gtk_cell_view_set_draw_sensitive(Xen cell_view, Xen draw_sensitive) { #define H_gtk_cell_view_set_draw_sensitive "void gtk_cell_view_set_draw_sensitive(GtkCellView* cell_view, \ gboolean draw_sensitive)" Xen_check_type(Xen_is_GtkCellView_(cell_view), cell_view, 1, "gtk_cell_view_set_draw_sensitive", "GtkCellView*"); Xen_check_type(Xen_is_gboolean(draw_sensitive), draw_sensitive, 2, "gtk_cell_view_set_draw_sensitive", "gboolean"); gtk_cell_view_set_draw_sensitive(Xen_to_C_GtkCellView_(cell_view), Xen_to_C_gboolean(draw_sensitive)); return(Xen_false); } static Xen gxg_gtk_cell_view_get_fit_model(Xen cell_view) { #define H_gtk_cell_view_get_fit_model "gboolean gtk_cell_view_get_fit_model(GtkCellView* cell_view)" Xen_check_type(Xen_is_GtkCellView_(cell_view), cell_view, 1, "gtk_cell_view_get_fit_model", "GtkCellView*"); return(C_to_Xen_gboolean(gtk_cell_view_get_fit_model(Xen_to_C_GtkCellView_(cell_view)))); } static Xen gxg_gtk_cell_view_set_fit_model(Xen cell_view, Xen fit_model) { #define H_gtk_cell_view_set_fit_model "void gtk_cell_view_set_fit_model(GtkCellView* cell_view, gboolean fit_model)" Xen_check_type(Xen_is_GtkCellView_(cell_view), cell_view, 1, "gtk_cell_view_set_fit_model", "GtkCellView*"); Xen_check_type(Xen_is_gboolean(fit_model), fit_model, 2, "gtk_cell_view_set_fit_model", "gboolean"); gtk_cell_view_set_fit_model(Xen_to_C_GtkCellView_(cell_view), Xen_to_C_gboolean(fit_model)); return(Xen_false); } static Xen gxg_gtk_combo_box_new_with_area(Xen area) { #define H_gtk_combo_box_new_with_area "GtkWidget* gtk_combo_box_new_with_area(GtkCellArea* area)" Xen_check_type(Xen_is_GtkCellArea_(area), area, 1, "gtk_combo_box_new_with_area", "GtkCellArea*"); return(C_to_Xen_GtkWidget_(gtk_combo_box_new_with_area(Xen_to_C_GtkCellArea_(area)))); } static Xen gxg_gtk_combo_box_new_with_area_and_entry(Xen area) { #define H_gtk_combo_box_new_with_area_and_entry "GtkWidget* gtk_combo_box_new_with_area_and_entry(GtkCellArea* area)" Xen_check_type(Xen_is_GtkCellArea_(area), area, 1, "gtk_combo_box_new_with_area_and_entry", "GtkCellArea*"); return(C_to_Xen_GtkWidget_(gtk_combo_box_new_with_area_and_entry(Xen_to_C_GtkCellArea_(area)))); } static Xen gxg_gtk_icon_view_new_with_area(Xen area) { #define H_gtk_icon_view_new_with_area "GtkWidget* gtk_icon_view_new_with_area(GtkCellArea* area)" Xen_check_type(Xen_is_GtkCellArea_(area), area, 1, "gtk_icon_view_new_with_area", "GtkCellArea*"); return(C_to_Xen_GtkWidget_(gtk_icon_view_new_with_area(Xen_to_C_GtkCellArea_(area)))); } static Xen gxg_gtk_menu_item_set_reserve_indicator(Xen menu_item, Xen reserve) { #define H_gtk_menu_item_set_reserve_indicator "void gtk_menu_item_set_reserve_indicator(GtkMenuItem* menu_item, \ gboolean reserve)" Xen_check_type(Xen_is_GtkMenuItem_(menu_item), menu_item, 1, "gtk_menu_item_set_reserve_indicator", "GtkMenuItem*"); Xen_check_type(Xen_is_gboolean(reserve), reserve, 2, "gtk_menu_item_set_reserve_indicator", "gboolean"); gtk_menu_item_set_reserve_indicator(Xen_to_C_GtkMenuItem_(menu_item), Xen_to_C_gboolean(reserve)); return(Xen_false); } static Xen gxg_gtk_menu_item_get_reserve_indicator(Xen menu_item) { #define H_gtk_menu_item_get_reserve_indicator "gboolean gtk_menu_item_get_reserve_indicator(GtkMenuItem* menu_item)" Xen_check_type(Xen_is_GtkMenuItem_(menu_item), menu_item, 1, "gtk_menu_item_get_reserve_indicator", "GtkMenuItem*"); return(C_to_Xen_gboolean(gtk_menu_item_get_reserve_indicator(Xen_to_C_GtkMenuItem_(menu_item)))); } static Xen gxg_gtk_menu_shell_get_selected_item(Xen menu_shell) { #define H_gtk_menu_shell_get_selected_item "GtkWidget* gtk_menu_shell_get_selected_item(GtkMenuShell* menu_shell)" Xen_check_type(Xen_is_GtkMenuShell_(menu_shell), menu_shell, 1, "gtk_menu_shell_get_selected_item", "GtkMenuShell*"); return(C_to_Xen_GtkWidget_(gtk_menu_shell_get_selected_item(Xen_to_C_GtkMenuShell_(menu_shell)))); } static Xen gxg_gtk_menu_shell_get_parent_shell(Xen menu_shell) { #define H_gtk_menu_shell_get_parent_shell "GtkWidget* gtk_menu_shell_get_parent_shell(GtkMenuShell* menu_shell)" Xen_check_type(Xen_is_GtkMenuShell_(menu_shell), menu_shell, 1, "gtk_menu_shell_get_parent_shell", "GtkMenuShell*"); return(C_to_Xen_GtkWidget_(gtk_menu_shell_get_parent_shell(Xen_to_C_GtkMenuShell_(menu_shell)))); } static Xen gxg_gtk_selection_data_get_data_with_length(Xen selection_data, Xen ignore_length) { #define H_gtk_selection_data_get_data_with_length "guchar* gtk_selection_data_get_data_with_length(GtkSelectionData* selection_data, \ gint* [length])" gint ref_length; Xen_check_type(Xen_is_GtkSelectionData_(selection_data), selection_data, 1, "gtk_selection_data_get_data_with_length", "GtkSelectionData*"); { Xen result; result = C_to_Xen_guchar_(gtk_selection_data_get_data_with_length(Xen_to_C_GtkSelectionData_(selection_data), &ref_length)); return(Xen_list_2(result, C_to_Xen_gint(ref_length))); } } static Xen gxg_gtk_tree_model_iter_previous(Xen tree_model, Xen iter) { #define H_gtk_tree_model_iter_previous "gboolean gtk_tree_model_iter_previous(GtkTreeModel* tree_model, \ GtkTreeIter* iter)" Xen_check_type(Xen_is_GtkTreeModel_(tree_model), tree_model, 1, "gtk_tree_model_iter_previous", "GtkTreeModel*"); Xen_check_type(Xen_is_GtkTreeIter_(iter), iter, 2, "gtk_tree_model_iter_previous", "GtkTreeIter*"); return(C_to_Xen_gboolean(gtk_tree_model_iter_previous(Xen_to_C_GtkTreeModel_(tree_model), Xen_to_C_GtkTreeIter_(iter)))); } static Xen gxg_gtk_tree_view_is_blank_at_pos(Xen tree_view, Xen x, Xen y, Xen ignore_path, Xen ignore_column, Xen ignore_cell_x, Xen ignore_cell_y) { #define H_gtk_tree_view_is_blank_at_pos "gboolean gtk_tree_view_is_blank_at_pos(GtkTreeView* tree_view, \ gint x, gint y, GtkTreePath** [path], GtkTreeViewColumn** [column], gint* [cell_x], gint* [cell_y])" GtkTreePath* ref_path = NULL; GtkTreeViewColumn* ref_column = NULL; gint ref_cell_x; gint ref_cell_y; Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_is_blank_at_pos", "GtkTreeView*"); Xen_check_type(Xen_is_gint(x), x, 2, "gtk_tree_view_is_blank_at_pos", "gint"); Xen_check_type(Xen_is_gint(y), y, 3, "gtk_tree_view_is_blank_at_pos", "gint"); { Xen result; result = C_to_Xen_gboolean(gtk_tree_view_is_blank_at_pos(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_gint(x), Xen_to_C_gint(y), &ref_path, &ref_column, &ref_cell_x, &ref_cell_y)); return(Xen_list_5(result, C_to_Xen_GtkTreePath_(ref_path), C_to_Xen_GtkTreeViewColumn_(ref_column), C_to_Xen_gint(ref_cell_x), C_to_Xen_gint(ref_cell_y))); } } static Xen gxg_gtk_widget_set_device_enabled(Xen widget, Xen device, Xen enabled) { #define H_gtk_widget_set_device_enabled "void gtk_widget_set_device_enabled(GtkWidget* widget, GdkDevice* device, \ gboolean enabled)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_set_device_enabled", "GtkWidget*"); Xen_check_type(Xen_is_GdkDevice_(device), device, 2, "gtk_widget_set_device_enabled", "GdkDevice*"); Xen_check_type(Xen_is_gboolean(enabled), enabled, 3, "gtk_widget_set_device_enabled", "gboolean"); gtk_widget_set_device_enabled(Xen_to_C_GtkWidget_(widget), Xen_to_C_GdkDevice_(device), Xen_to_C_gboolean(enabled)); return(Xen_false); } static Xen gxg_gtk_widget_get_device_enabled(Xen widget, Xen device) { #define H_gtk_widget_get_device_enabled "gboolean gtk_widget_get_device_enabled(GtkWidget* widget, \ GdkDevice* device)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_device_enabled", "GtkWidget*"); Xen_check_type(Xen_is_GdkDevice_(device), device, 2, "gtk_widget_get_device_enabled", "GdkDevice*"); return(C_to_Xen_gboolean(gtk_widget_get_device_enabled(Xen_to_C_GtkWidget_(widget), Xen_to_C_GdkDevice_(device)))); } static Xen gxg_gtk_window_set_has_user_ref_count(Xen window, Xen setting) { #define H_gtk_window_set_has_user_ref_count "void gtk_window_set_has_user_ref_count(GtkWindow* window, \ gboolean setting)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_set_has_user_ref_count", "GtkWindow*"); Xen_check_type(Xen_is_gboolean(setting), setting, 2, "gtk_window_set_has_user_ref_count", "gboolean"); gtk_window_set_has_user_ref_count(Xen_to_C_GtkWindow_(window), Xen_to_C_gboolean(setting)); return(Xen_false); } static Xen gxg_gdk_selection_send_notify(Xen requestor, Xen selection, Xen target, Xen property, Xen time_) { #define H_gdk_selection_send_notify "void gdk_selection_send_notify(GdkWindow* requestor, GdkAtom selection, \ GdkAtom target, GdkAtom property, guint32 time_)" Xen_check_type(Xen_is_GdkWindow_(requestor), requestor, 1, "gdk_selection_send_notify", "GdkWindow*"); Xen_check_type(Xen_is_GdkAtom(selection), selection, 2, "gdk_selection_send_notify", "GdkAtom"); Xen_check_type(Xen_is_GdkAtom(target), target, 3, "gdk_selection_send_notify", "GdkAtom"); Xen_check_type(Xen_is_GdkAtom(property), property, 4, "gdk_selection_send_notify", "GdkAtom"); Xen_check_type(Xen_is_guint32(time_), time_, 5, "gdk_selection_send_notify", "guint32"); gdk_selection_send_notify(Xen_to_C_GdkWindow_(requestor), Xen_to_C_GdkAtom(selection), Xen_to_C_GdkAtom(target), Xen_to_C_GdkAtom(property), Xen_to_C_guint32(time_)); return(Xen_false); } static Xen gxg_gdk_selection_send_notify_for_display(Xen display, Xen requestor, Xen selection, Xen target, Xen property, Xen time_) { #define H_gdk_selection_send_notify_for_display "void gdk_selection_send_notify_for_display(GdkDisplay* display, \ GdkWindow* requestor, GdkAtom selection, GdkAtom target, GdkAtom property, guint32 time_)" Xen_check_type(Xen_is_GdkDisplay_(display), display, 1, "gdk_selection_send_notify_for_display", "GdkDisplay*"); Xen_check_type(Xen_is_GdkWindow_(requestor), requestor, 2, "gdk_selection_send_notify_for_display", "GdkWindow*"); Xen_check_type(Xen_is_GdkAtom(selection), selection, 3, "gdk_selection_send_notify_for_display", "GdkAtom"); Xen_check_type(Xen_is_GdkAtom(target), target, 4, "gdk_selection_send_notify_for_display", "GdkAtom"); Xen_check_type(Xen_is_GdkAtom(property), property, 5, "gdk_selection_send_notify_for_display", "GdkAtom"); Xen_check_type(Xen_is_guint32(time_), time_, 6, "gdk_selection_send_notify_for_display", "guint32"); gdk_selection_send_notify_for_display(Xen_to_C_GdkDisplay_(display), Xen_to_C_GdkWindow_(requestor), Xen_to_C_GdkAtom(selection), Xen_to_C_GdkAtom(target), Xen_to_C_GdkAtom(property), Xen_to_C_guint32(time_)); return(Xen_false); } static Xen gxg_gdk_rgba_copy(Xen rgba) { #define H_gdk_rgba_copy "GdkRGBA* gdk_rgba_copy(GdkRGBA* rgba)" Xen_check_type(Xen_is_GdkRGBA_(rgba), rgba, 1, "gdk_rgba_copy", "GdkRGBA*"); return(C_to_Xen_GdkRGBA_(gdk_rgba_copy(Xen_to_C_GdkRGBA_(rgba)))); } static Xen gxg_gdk_rgba_free(Xen rgba) { #define H_gdk_rgba_free "void gdk_rgba_free(GdkRGBA* rgba)" Xen_check_type(Xen_is_GdkRGBA_(rgba), rgba, 1, "gdk_rgba_free", "GdkRGBA*"); gdk_rgba_free(Xen_to_C_GdkRGBA_(rgba)); return(Xen_false); } static Xen gxg_gdk_rgba_parse(Xen rgba, Xen spec) { #define H_gdk_rgba_parse "gboolean gdk_rgba_parse(GdkRGBA* rgba, gchar* spec)" Xen_check_type(Xen_is_GdkRGBA_(rgba), rgba, 1, "gdk_rgba_parse", "GdkRGBA*"); Xen_check_type(Xen_is_gchar_(spec), spec, 2, "gdk_rgba_parse", "gchar*"); return(C_to_Xen_gboolean(gdk_rgba_parse(Xen_to_C_GdkRGBA_(rgba), (const gchar*)Xen_to_C_gchar_(spec)))); } static Xen gxg_gdk_rgba_to_string(Xen rgba) { #define H_gdk_rgba_to_string "gchar* gdk_rgba_to_string(GdkRGBA* rgba)" Xen_check_type(Xen_is_GdkRGBA_(rgba), rgba, 1, "gdk_rgba_to_string", "GdkRGBA*"); return(C_to_Xen_gchar_(gdk_rgba_to_string(Xen_to_C_GdkRGBA_(rgba)))); } static Xen gxg_gtk_widget_set_state_flags(Xen widget, Xen flags, Xen clear) { #define H_gtk_widget_set_state_flags "void gtk_widget_set_state_flags(GtkWidget* widget, GtkStateFlags flags, \ gboolean clear)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_set_state_flags", "GtkWidget*"); Xen_check_type(Xen_is_GtkStateFlags(flags), flags, 2, "gtk_widget_set_state_flags", "GtkStateFlags"); Xen_check_type(Xen_is_gboolean(clear), clear, 3, "gtk_widget_set_state_flags", "gboolean"); gtk_widget_set_state_flags(Xen_to_C_GtkWidget_(widget), Xen_to_C_GtkStateFlags(flags), Xen_to_C_gboolean(clear)); return(Xen_false); } static Xen gxg_gtk_widget_unset_state_flags(Xen widget, Xen flags) { #define H_gtk_widget_unset_state_flags "void gtk_widget_unset_state_flags(GtkWidget* widget, GtkStateFlags flags)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_unset_state_flags", "GtkWidget*"); Xen_check_type(Xen_is_GtkStateFlags(flags), flags, 2, "gtk_widget_unset_state_flags", "GtkStateFlags"); gtk_widget_unset_state_flags(Xen_to_C_GtkWidget_(widget), Xen_to_C_GtkStateFlags(flags)); return(Xen_false); } static Xen gxg_gtk_widget_get_state_flags(Xen widget) { #define H_gtk_widget_get_state_flags "GtkStateFlags gtk_widget_get_state_flags(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_state_flags", "GtkWidget*"); return(C_to_Xen_GtkStateFlags(gtk_widget_get_state_flags(Xen_to_C_GtkWidget_(widget)))); } #endif #if GTK_CHECK_VERSION(3, 2, 0) static Xen gxg_gtk_entry_get_placeholder_text(Xen entry) { #define H_gtk_entry_get_placeholder_text "gchar* gtk_entry_get_placeholder_text(GtkEntry* entry)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_get_placeholder_text", "GtkEntry*"); return(C_to_Xen_gchar_(gtk_entry_get_placeholder_text(Xen_to_C_GtkEntry_(entry)))); } static Xen gxg_gtk_entry_set_placeholder_text(Xen entry, Xen text) { #define H_gtk_entry_set_placeholder_text "void gtk_entry_set_placeholder_text(GtkEntry* entry, gchar* text)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_set_placeholder_text", "GtkEntry*"); Xen_check_type(Xen_is_gchar_(text), text, 2, "gtk_entry_set_placeholder_text", "gchar*"); gtk_entry_set_placeholder_text(Xen_to_C_GtkEntry_(entry), (const gchar*)Xen_to_C_gchar_(text)); return(Xen_false); } static Xen gxg_gtk_expander_set_resize_toplevel(Xen expander, Xen resize_toplevel) { #define H_gtk_expander_set_resize_toplevel "void gtk_expander_set_resize_toplevel(GtkExpander* expander, \ gboolean resize_toplevel)" Xen_check_type(Xen_is_GtkExpander_(expander), expander, 1, "gtk_expander_set_resize_toplevel", "GtkExpander*"); Xen_check_type(Xen_is_gboolean(resize_toplevel), resize_toplevel, 2, "gtk_expander_set_resize_toplevel", "gboolean"); gtk_expander_set_resize_toplevel(Xen_to_C_GtkExpander_(expander), Xen_to_C_gboolean(resize_toplevel)); return(Xen_false); } static Xen gxg_gtk_expander_get_resize_toplevel(Xen expander) { #define H_gtk_expander_get_resize_toplevel "gboolean gtk_expander_get_resize_toplevel(GtkExpander* expander)" Xen_check_type(Xen_is_GtkExpander_(expander), expander, 1, "gtk_expander_get_resize_toplevel", "GtkExpander*"); return(C_to_Xen_gboolean(gtk_expander_get_resize_toplevel(Xen_to_C_GtkExpander_(expander)))); } static Xen gxg_gtk_widget_path_to_string(Xen path) { #define H_gtk_widget_path_to_string "char* gtk_widget_path_to_string(GtkWidgetPath* path)" Xen_check_type(Xen_is_GtkWidgetPath_(path), path, 1, "gtk_widget_path_to_string", "GtkWidgetPath*"); return(C_to_Xen_char_(gtk_widget_path_to_string(Xen_to_C_GtkWidgetPath_(path)))); } static Xen gxg_gtk_button_box_get_child_non_homogeneous(Xen widget, Xen child) { #define H_gtk_button_box_get_child_non_homogeneous "gboolean gtk_button_box_get_child_non_homogeneous(GtkButtonBox* widget, \ GtkWidget* child)" Xen_check_type(Xen_is_GtkButtonBox_(widget), widget, 1, "gtk_button_box_get_child_non_homogeneous", "GtkButtonBox*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_button_box_get_child_non_homogeneous", "GtkWidget*"); return(C_to_Xen_gboolean(gtk_button_box_get_child_non_homogeneous(Xen_to_C_GtkButtonBox_(widget), Xen_to_C_GtkWidget_(child)))); } static Xen gxg_gtk_button_box_set_child_non_homogeneous(Xen widget, Xen child, Xen non_homogeneous) { #define H_gtk_button_box_set_child_non_homogeneous "void gtk_button_box_set_child_non_homogeneous(GtkButtonBox* widget, \ GtkWidget* child, gboolean non_homogeneous)" Xen_check_type(Xen_is_GtkButtonBox_(widget), widget, 1, "gtk_button_box_set_child_non_homogeneous", "GtkButtonBox*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_button_box_set_child_non_homogeneous", "GtkWidget*"); Xen_check_type(Xen_is_gboolean(non_homogeneous), non_homogeneous, 3, "gtk_button_box_set_child_non_homogeneous", "gboolean"); gtk_button_box_set_child_non_homogeneous(Xen_to_C_GtkButtonBox_(widget), Xen_to_C_GtkWidget_(child), Xen_to_C_gboolean(non_homogeneous)); return(Xen_false); } static Xen gxg_gtk_container_child_notify(Xen container, Xen child, Xen property_name) { #define H_gtk_container_child_notify "void gtk_container_child_notify(GtkContainer* container, GtkWidget* child, \ gchar* property_name)" Xen_check_type(Xen_is_GtkContainer_(container), container, 1, "gtk_container_child_notify", "GtkContainer*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_container_child_notify", "GtkWidget*"); Xen_check_type(Xen_is_gchar_(property_name), property_name, 3, "gtk_container_child_notify", "gchar*"); gtk_container_child_notify(Xen_to_C_GtkContainer_(container), Xen_to_C_GtkWidget_(child), (const gchar*)Xen_to_C_gchar_(property_name)); return(Xen_false); } static Xen gxg_gtk_drag_source_set_icon_gicon(Xen widget, Xen icon) { #define H_gtk_drag_source_set_icon_gicon "void gtk_drag_source_set_icon_gicon(GtkWidget* widget, GIcon* icon)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_drag_source_set_icon_gicon", "GtkWidget*"); Xen_check_type(Xen_is_GIcon_(icon), icon, 2, "gtk_drag_source_set_icon_gicon", "GIcon*"); gtk_drag_source_set_icon_gicon(Xen_to_C_GtkWidget_(widget), Xen_to_C_GIcon_(icon)); return(Xen_false); } static Xen gxg_gtk_drag_set_icon_gicon(Xen context, Xen icon, Xen hot_x, Xen hot_y) { #define H_gtk_drag_set_icon_gicon "void gtk_drag_set_icon_gicon(GdkDragContext* context, GIcon* icon, \ gint hot_x, gint hot_y)" Xen_check_type(Xen_is_GdkDragContext_(context), context, 1, "gtk_drag_set_icon_gicon", "GdkDragContext*"); Xen_check_type(Xen_is_GIcon_(icon), icon, 2, "gtk_drag_set_icon_gicon", "GIcon*"); Xen_check_type(Xen_is_gint(hot_x), hot_x, 3, "gtk_drag_set_icon_gicon", "gint"); Xen_check_type(Xen_is_gint(hot_y), hot_y, 4, "gtk_drag_set_icon_gicon", "gint"); gtk_drag_set_icon_gicon(Xen_to_C_GdkDragContext_(context), Xen_to_C_GIcon_(icon), Xen_to_C_gint(hot_x), Xen_to_C_gint(hot_y)); return(Xen_false); } static Xen gxg_gtk_combo_box_set_active_id(Xen combo_box, Xen active_id) { #define H_gtk_combo_box_set_active_id "gboolean gtk_combo_box_set_active_id(GtkComboBox* combo_box, \ gchar* active_id)" Xen_check_type(Xen_is_GtkComboBox_(combo_box), combo_box, 1, "gtk_combo_box_set_active_id", "GtkComboBox*"); Xen_check_type(Xen_is_gchar_(active_id), active_id, 2, "gtk_combo_box_set_active_id", "gchar*"); return(C_to_Xen_gboolean(gtk_combo_box_set_active_id(Xen_to_C_GtkComboBox_(combo_box), (const gchar*)Xen_to_C_gchar_(active_id)))); } static Xen gxg_gtk_tree_view_column_get_x_offset(Xen tree_column) { #define H_gtk_tree_view_column_get_x_offset "gint gtk_tree_view_column_get_x_offset(GtkTreeViewColumn* tree_column)" Xen_check_type(Xen_is_GtkTreeViewColumn_(tree_column), tree_column, 1, "gtk_tree_view_column_get_x_offset", "GtkTreeViewColumn*"); return(C_to_Xen_gint(gtk_tree_view_column_get_x_offset(Xen_to_C_GtkTreeViewColumn_(tree_column)))); } static Xen gxg_gtk_overlay_new(void) { #define H_gtk_overlay_new "GtkWidget* gtk_overlay_new( void)" return(C_to_Xen_GtkWidget_(gtk_overlay_new())); } static Xen gxg_gtk_overlay_add_overlay(Xen overlay, Xen widget) { #define H_gtk_overlay_add_overlay "void gtk_overlay_add_overlay(GtkOverlay* overlay, GtkWidget* widget)" Xen_check_type(Xen_is_GtkOverlay_(overlay), overlay, 1, "gtk_overlay_add_overlay", "GtkOverlay*"); Xen_check_type(Xen_is_GtkWidget_(widget), widget, 2, "gtk_overlay_add_overlay", "GtkWidget*"); gtk_overlay_add_overlay(Xen_to_C_GtkOverlay_(overlay), Xen_to_C_GtkWidget_(widget)); return(Xen_false); } static Xen gxg_gtk_adjustment_get_minimum_increment(Xen adjustment) { #define H_gtk_adjustment_get_minimum_increment "gdouble gtk_adjustment_get_minimum_increment(GtkAdjustment* adjustment)" Xen_check_type(Xen_is_GtkAdjustment_(adjustment), adjustment, 1, "gtk_adjustment_get_minimum_increment", "GtkAdjustment*"); return(C_to_Xen_gdouble(gtk_adjustment_get_minimum_increment(Xen_to_C_GtkAdjustment_(adjustment)))); } static Xen gxg_gtk_grid_insert_row(Xen grid, Xen position) { #define H_gtk_grid_insert_row "void gtk_grid_insert_row(GtkGrid* grid, gint position)" Xen_check_type(Xen_is_GtkGrid_(grid), grid, 1, "gtk_grid_insert_row", "GtkGrid*"); Xen_check_type(Xen_is_gint(position), position, 2, "gtk_grid_insert_row", "gint"); gtk_grid_insert_row(Xen_to_C_GtkGrid_(grid), Xen_to_C_gint(position)); return(Xen_false); } static Xen gxg_gtk_grid_insert_column(Xen grid, Xen position) { #define H_gtk_grid_insert_column "void gtk_grid_insert_column(GtkGrid* grid, gint position)" Xen_check_type(Xen_is_GtkGrid_(grid), grid, 1, "gtk_grid_insert_column", "GtkGrid*"); Xen_check_type(Xen_is_gint(position), position, 2, "gtk_grid_insert_column", "gint"); gtk_grid_insert_column(Xen_to_C_GtkGrid_(grid), Xen_to_C_gint(position)); return(Xen_false); } static Xen gxg_gtk_grid_insert_next_to(Xen grid, Xen sibling, Xen side) { #define H_gtk_grid_insert_next_to "void gtk_grid_insert_next_to(GtkGrid* grid, GtkWidget* sibling, \ GtkPositionType side)" Xen_check_type(Xen_is_GtkGrid_(grid), grid, 1, "gtk_grid_insert_next_to", "GtkGrid*"); Xen_check_type(Xen_is_GtkWidget_(sibling), sibling, 2, "gtk_grid_insert_next_to", "GtkWidget*"); Xen_check_type(Xen_is_GtkPositionType(side), side, 3, "gtk_grid_insert_next_to", "GtkPositionType"); gtk_grid_insert_next_to(Xen_to_C_GtkGrid_(grid), Xen_to_C_GtkWidget_(sibling), Xen_to_C_GtkPositionType(side)); return(Xen_false); } static Xen gxg_gtk_text_iter_assign(Xen iter, Xen other) { #define H_gtk_text_iter_assign "void gtk_text_iter_assign(GtkTextIter* iter, GtkTextIter* other)" Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 1, "gtk_text_iter_assign", "GtkTextIter*"); Xen_check_type(Xen_is_GtkTextIter_(other), other, 2, "gtk_text_iter_assign", "GtkTextIter*"); gtk_text_iter_assign(Xen_to_C_GtkTextIter_(iter), Xen_to_C_GtkTextIter_(other)); return(Xen_false); } static Xen gxg_gtk_widget_has_visible_focus(Xen widget) { #define H_gtk_widget_has_visible_focus "gboolean gtk_widget_has_visible_focus(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_has_visible_focus", "GtkWidget*"); return(C_to_Xen_gboolean(gtk_widget_has_visible_focus(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_window_set_focus_visible(Xen window, Xen setting) { #define H_gtk_window_set_focus_visible "void gtk_window_set_focus_visible(GtkWindow* window, gboolean setting)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_set_focus_visible", "GtkWindow*"); Xen_check_type(Xen_is_gboolean(setting), setting, 2, "gtk_window_set_focus_visible", "gboolean"); gtk_window_set_focus_visible(Xen_to_C_GtkWindow_(window), Xen_to_C_gboolean(setting)); return(Xen_false); } static Xen gxg_gtk_window_get_focus_visible(Xen window) { #define H_gtk_window_get_focus_visible "gboolean gtk_window_get_focus_visible(GtkWindow* window)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_get_focus_visible", "GtkWindow*"); return(C_to_Xen_gboolean(gtk_window_get_focus_visible(Xen_to_C_GtkWindow_(window)))); } static Xen gxg_gtk_font_chooser_dialog_new(Xen title, Xen window) { #define H_gtk_font_chooser_dialog_new "GtkWidget* gtk_font_chooser_dialog_new(gchar* title, GtkWindow* window)" Xen_check_type(Xen_is_gchar_(title), title, 1, "gtk_font_chooser_dialog_new", "gchar*"); Xen_check_type(Xen_is_GtkWindow_(window), window, 2, "gtk_font_chooser_dialog_new", "GtkWindow*"); return(C_to_Xen_GtkWidget_(gtk_font_chooser_dialog_new((const gchar*)Xen_to_C_gchar_(title), Xen_to_C_GtkWindow_(window)))); } static Xen gxg_gdk_event_get_button(Xen event, Xen button) { #define H_gdk_event_get_button "gboolean gdk_event_get_button(GdkEvent* event, guint* button)" Xen_check_type(Xen_is_GdkEvent_(event), event, 1, "gdk_event_get_button", "GdkEvent*"); Xen_check_type(Xen_is_guint_(button), button, 2, "gdk_event_get_button", "guint*"); return(C_to_Xen_gboolean(gdk_event_get_button(Xen_to_C_GdkEvent_(event), Xen_to_C_guint_(button)))); } static Xen gxg_gdk_event_get_click_count(Xen event, Xen click_count) { #define H_gdk_event_get_click_count "gboolean gdk_event_get_click_count(GdkEvent* event, guint* click_count)" Xen_check_type(Xen_is_GdkEvent_(event), event, 1, "gdk_event_get_click_count", "GdkEvent*"); Xen_check_type(Xen_is_guint_(click_count), click_count, 2, "gdk_event_get_click_count", "guint*"); return(C_to_Xen_gboolean(gdk_event_get_click_count(Xen_to_C_GdkEvent_(event), Xen_to_C_guint_(click_count)))); } static Xen gxg_gdk_event_get_keyval(Xen event, Xen keyval) { #define H_gdk_event_get_keyval "gboolean gdk_event_get_keyval(GdkEvent* event, guint* keyval)" Xen_check_type(Xen_is_GdkEvent_(event), event, 1, "gdk_event_get_keyval", "GdkEvent*"); Xen_check_type(Xen_is_guint_(keyval), keyval, 2, "gdk_event_get_keyval", "guint*"); return(C_to_Xen_gboolean(gdk_event_get_keyval(Xen_to_C_GdkEvent_(event), Xen_to_C_guint_(keyval)))); } static Xen gxg_gdk_event_get_keycode(Xen event, Xen keycode) { #define H_gdk_event_get_keycode "gboolean gdk_event_get_keycode(GdkEvent* event, guint16* keycode)" Xen_check_type(Xen_is_GdkEvent_(event), event, 1, "gdk_event_get_keycode", "GdkEvent*"); Xen_check_type(Xen_is_guint16_(keycode), keycode, 2, "gdk_event_get_keycode", "guint16*"); return(C_to_Xen_gboolean(gdk_event_get_keycode(Xen_to_C_GdkEvent_(event), Xen_to_C_guint16_(keycode)))); } static Xen gxg_gdk_event_get_scroll_direction(Xen event, Xen ignore_direction) { #define H_gdk_event_get_scroll_direction "gboolean gdk_event_get_scroll_direction(GdkEvent* event, \ GdkScrollDirection* [direction])" GdkScrollDirection ref_direction; Xen_check_type(Xen_is_GdkEvent_(event), event, 1, "gdk_event_get_scroll_direction", "GdkEvent*"); { Xen result; result = C_to_Xen_gboolean(gdk_event_get_scroll_direction(Xen_to_C_GdkEvent_(event), &ref_direction)); return(Xen_list_2(result, C_to_Xen_GdkScrollDirection(ref_direction))); } } static Xen gxg_gtk_grid_get_child_at(Xen grid, Xen left, Xen top) { #define H_gtk_grid_get_child_at "GtkWidget* gtk_grid_get_child_at(GtkGrid* grid, gint left, gint top)" Xen_check_type(Xen_is_GtkGrid_(grid), grid, 1, "gtk_grid_get_child_at", "GtkGrid*"); Xen_check_type(Xen_is_gint(left), left, 2, "gtk_grid_get_child_at", "gint"); Xen_check_type(Xen_is_gint(top), top, 3, "gtk_grid_get_child_at", "gint"); return(C_to_Xen_GtkWidget_(gtk_grid_get_child_at(Xen_to_C_GtkGrid_(grid), Xen_to_C_gint(left), Xen_to_C_gint(top)))); } static Xen gxg_gtk_font_chooser_get_font_family(Xen fontchooser) { #define H_gtk_font_chooser_get_font_family "PangoFontFamily* gtk_font_chooser_get_font_family(GtkFontChooser* fontchooser)" Xen_check_type(Xen_is_GtkFontChooser_(fontchooser), fontchooser, 1, "gtk_font_chooser_get_font_family", "GtkFontChooser*"); return(C_to_Xen_PangoFontFamily_(gtk_font_chooser_get_font_family(Xen_to_C_GtkFontChooser_(fontchooser)))); } static Xen gxg_gtk_font_chooser_get_font_face(Xen fontchooser) { #define H_gtk_font_chooser_get_font_face "PangoFontFace* gtk_font_chooser_get_font_face(GtkFontChooser* fontchooser)" Xen_check_type(Xen_is_GtkFontChooser_(fontchooser), fontchooser, 1, "gtk_font_chooser_get_font_face", "GtkFontChooser*"); return(C_to_Xen_PangoFontFace_(gtk_font_chooser_get_font_face(Xen_to_C_GtkFontChooser_(fontchooser)))); } static Xen gxg_gtk_font_chooser_get_font_size(Xen fontchooser) { #define H_gtk_font_chooser_get_font_size "gint gtk_font_chooser_get_font_size(GtkFontChooser* fontchooser)" Xen_check_type(Xen_is_GtkFontChooser_(fontchooser), fontchooser, 1, "gtk_font_chooser_get_font_size", "GtkFontChooser*"); return(C_to_Xen_gint(gtk_font_chooser_get_font_size(Xen_to_C_GtkFontChooser_(fontchooser)))); } static Xen gxg_gtk_font_chooser_get_font_desc(Xen fontchooser) { #define H_gtk_font_chooser_get_font_desc "PangoFontDescription* gtk_font_chooser_get_font_desc(GtkFontChooser* fontchooser)" Xen_check_type(Xen_is_GtkFontChooser_(fontchooser), fontchooser, 1, "gtk_font_chooser_get_font_desc", "GtkFontChooser*"); return(C_to_Xen_PangoFontDescription_(gtk_font_chooser_get_font_desc(Xen_to_C_GtkFontChooser_(fontchooser)))); } static Xen gxg_gtk_font_chooser_set_font_desc(Xen fontchooser, Xen font_desc) { #define H_gtk_font_chooser_set_font_desc "void gtk_font_chooser_set_font_desc(GtkFontChooser* fontchooser, \ PangoFontDescription* font_desc)" Xen_check_type(Xen_is_GtkFontChooser_(fontchooser), fontchooser, 1, "gtk_font_chooser_set_font_desc", "GtkFontChooser*"); Xen_check_type(Xen_is_PangoFontDescription_(font_desc), font_desc, 2, "gtk_font_chooser_set_font_desc", "PangoFontDescription*"); gtk_font_chooser_set_font_desc(Xen_to_C_GtkFontChooser_(fontchooser), Xen_to_C_PangoFontDescription_(font_desc)); return(Xen_false); } static Xen gxg_gtk_font_chooser_get_font(Xen fontchooser) { #define H_gtk_font_chooser_get_font "gchar* gtk_font_chooser_get_font(GtkFontChooser* fontchooser)" Xen_check_type(Xen_is_GtkFontChooser_(fontchooser), fontchooser, 1, "gtk_font_chooser_get_font", "GtkFontChooser*"); return(C_to_Xen_gchar_(gtk_font_chooser_get_font(Xen_to_C_GtkFontChooser_(fontchooser)))); } static Xen gxg_gtk_font_chooser_set_font(Xen fontchooser, Xen fontname) { #define H_gtk_font_chooser_set_font "void gtk_font_chooser_set_font(GtkFontChooser* fontchooser, gchar* fontname)" Xen_check_type(Xen_is_GtkFontChooser_(fontchooser), fontchooser, 1, "gtk_font_chooser_set_font", "GtkFontChooser*"); Xen_check_type(Xen_is_gchar_(fontname), fontname, 2, "gtk_font_chooser_set_font", "gchar*"); gtk_font_chooser_set_font(Xen_to_C_GtkFontChooser_(fontchooser), (const gchar*)Xen_to_C_gchar_(fontname)); return(Xen_false); } static Xen gxg_gtk_font_chooser_get_preview_text(Xen fontchooser) { #define H_gtk_font_chooser_get_preview_text "gchar* gtk_font_chooser_get_preview_text(GtkFontChooser* fontchooser)" Xen_check_type(Xen_is_GtkFontChooser_(fontchooser), fontchooser, 1, "gtk_font_chooser_get_preview_text", "GtkFontChooser*"); return(C_to_Xen_gchar_(gtk_font_chooser_get_preview_text(Xen_to_C_GtkFontChooser_(fontchooser)))); } static Xen gxg_gtk_font_chooser_set_preview_text(Xen fontchooser, Xen text) { #define H_gtk_font_chooser_set_preview_text "void gtk_font_chooser_set_preview_text(GtkFontChooser* fontchooser, \ gchar* text)" Xen_check_type(Xen_is_GtkFontChooser_(fontchooser), fontchooser, 1, "gtk_font_chooser_set_preview_text", "GtkFontChooser*"); Xen_check_type(Xen_is_gchar_(text), text, 2, "gtk_font_chooser_set_preview_text", "gchar*"); gtk_font_chooser_set_preview_text(Xen_to_C_GtkFontChooser_(fontchooser), (const gchar*)Xen_to_C_gchar_(text)); return(Xen_false); } static Xen gxg_gtk_font_chooser_get_show_preview_entry(Xen fontchooser) { #define H_gtk_font_chooser_get_show_preview_entry "gboolean gtk_font_chooser_get_show_preview_entry(GtkFontChooser* fontchooser)" Xen_check_type(Xen_is_GtkFontChooser_(fontchooser), fontchooser, 1, "gtk_font_chooser_get_show_preview_entry", "GtkFontChooser*"); return(C_to_Xen_gboolean(gtk_font_chooser_get_show_preview_entry(Xen_to_C_GtkFontChooser_(fontchooser)))); } static Xen gxg_gtk_font_chooser_set_show_preview_entry(Xen fontchooser, Xen show_preview_entry) { #define H_gtk_font_chooser_set_show_preview_entry "void gtk_font_chooser_set_show_preview_entry(GtkFontChooser* fontchooser, \ gboolean show_preview_entry)" Xen_check_type(Xen_is_GtkFontChooser_(fontchooser), fontchooser, 1, "gtk_font_chooser_set_show_preview_entry", "GtkFontChooser*"); Xen_check_type(Xen_is_gboolean(show_preview_entry), show_preview_entry, 2, "gtk_font_chooser_set_show_preview_entry", "gboolean"); gtk_font_chooser_set_show_preview_entry(Xen_to_C_GtkFontChooser_(fontchooser), Xen_to_C_gboolean(show_preview_entry)); return(Xen_false); } static Xen gxg_gtk_font_chooser_widget_new(void) { #define H_gtk_font_chooser_widget_new "GtkWidget* gtk_font_chooser_widget_new( void)" return(C_to_Xen_GtkWidget_(gtk_font_chooser_widget_new())); } #endif #if GTK_CHECK_VERSION(3, 4, 0) static Xen gxg_gdk_keymap_get_modifier_mask(Xen keymap, Xen intent) { #define H_gdk_keymap_get_modifier_mask "GdkModifierType gdk_keymap_get_modifier_mask(GdkKeymap* keymap, \ GdkModifierIntent intent)" Xen_check_type(Xen_is_GdkKeymap_(keymap), keymap, 1, "gdk_keymap_get_modifier_mask", "GdkKeymap*"); Xen_check_type(Xen_is_GdkModifierIntent(intent), intent, 2, "gdk_keymap_get_modifier_mask", "GdkModifierIntent"); return(C_to_Xen_GdkModifierType(gdk_keymap_get_modifier_mask(Xen_to_C_GdkKeymap_(keymap), Xen_to_C_GdkModifierIntent(intent)))); } static Xen gxg_gdk_window_begin_resize_drag_for_device(Xen window, Xen edge, Xen device, Xen button, Xen root_x, Xen root_y, Xen timestamp) { #define H_gdk_window_begin_resize_drag_for_device "void gdk_window_begin_resize_drag_for_device(GdkWindow* window, \ GdkWindowEdge edge, GdkDevice* device, gint button, gint root_x, gint root_y, guint32 timestamp)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_begin_resize_drag_for_device", "GdkWindow*"); Xen_check_type(Xen_is_GdkWindowEdge(edge), edge, 2, "gdk_window_begin_resize_drag_for_device", "GdkWindowEdge"); Xen_check_type(Xen_is_GdkDevice_(device), device, 3, "gdk_window_begin_resize_drag_for_device", "GdkDevice*"); Xen_check_type(Xen_is_gint(button), button, 4, "gdk_window_begin_resize_drag_for_device", "gint"); Xen_check_type(Xen_is_gint(root_x), root_x, 5, "gdk_window_begin_resize_drag_for_device", "gint"); Xen_check_type(Xen_is_gint(root_y), root_y, 6, "gdk_window_begin_resize_drag_for_device", "gint"); Xen_check_type(Xen_is_guint32(timestamp), timestamp, 7, "gdk_window_begin_resize_drag_for_device", "guint32"); gdk_window_begin_resize_drag_for_device(Xen_to_C_GdkWindow_(window), Xen_to_C_GdkWindowEdge(edge), Xen_to_C_GdkDevice_(device), Xen_to_C_gint(button), Xen_to_C_gint(root_x), Xen_to_C_gint(root_y), Xen_to_C_guint32(timestamp)); return(Xen_false); } static Xen gxg_gdk_window_begin_move_drag_for_device(Xen window, Xen device, Xen button, Xen root_x, Xen root_y, Xen timestamp) { #define H_gdk_window_begin_move_drag_for_device "void gdk_window_begin_move_drag_for_device(GdkWindow* window, \ GdkDevice* device, gint button, gint root_x, gint root_y, guint32 timestamp)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_begin_move_drag_for_device", "GdkWindow*"); Xen_check_type(Xen_is_GdkDevice_(device), device, 2, "gdk_window_begin_move_drag_for_device", "GdkDevice*"); Xen_check_type(Xen_is_gint(button), button, 3, "gdk_window_begin_move_drag_for_device", "gint"); Xen_check_type(Xen_is_gint(root_x), root_x, 4, "gdk_window_begin_move_drag_for_device", "gint"); Xen_check_type(Xen_is_gint(root_y), root_y, 5, "gdk_window_begin_move_drag_for_device", "gint"); Xen_check_type(Xen_is_guint32(timestamp), timestamp, 6, "gdk_window_begin_move_drag_for_device", "guint32"); gdk_window_begin_move_drag_for_device(Xen_to_C_GdkWindow_(window), Xen_to_C_GdkDevice_(device), Xen_to_C_gint(button), Xen_to_C_gint(root_x), Xen_to_C_gint(root_y), Xen_to_C_guint32(timestamp)); return(Xen_false); } static Xen gxg_gtk_accelerator_parse_with_keycode(Xen accelerator, Xen accelerator_key, Xen accelerator_codes, Xen accelerator_mods) { #define H_gtk_accelerator_parse_with_keycode "void gtk_accelerator_parse_with_keycode(gchar* accelerator, \ guint* accelerator_key, guint** accelerator_codes, GdkModifierType* accelerator_mods)" Xen_check_type(Xen_is_gchar_(accelerator), accelerator, 1, "gtk_accelerator_parse_with_keycode", "gchar*"); Xen_check_type(Xen_is_guint_(accelerator_key), accelerator_key, 2, "gtk_accelerator_parse_with_keycode", "guint*"); Xen_check_type(Xen_is_guint__(accelerator_codes), accelerator_codes, 3, "gtk_accelerator_parse_with_keycode", "guint**"); Xen_check_type(Xen_is_GdkModifierType_(accelerator_mods), accelerator_mods, 4, "gtk_accelerator_parse_with_keycode", "GdkModifierType*"); gtk_accelerator_parse_with_keycode((const gchar*)Xen_to_C_gchar_(accelerator), Xen_to_C_guint_(accelerator_key), Xen_to_C_guint__(accelerator_codes), Xen_to_C_GdkModifierType_(accelerator_mods)); return(Xen_false); } static Xen gxg_gtk_accelerator_name_with_keycode(Xen display, Xen accelerator_key, Xen keycode, Xen accelerator_mods) { #define H_gtk_accelerator_name_with_keycode "gchar* gtk_accelerator_name_with_keycode(GdkDisplay* display, \ guint accelerator_key, guint keycode, GdkModifierType accelerator_mods)" Xen_check_type(Xen_is_GdkDisplay_(display), display, 1, "gtk_accelerator_name_with_keycode", "GdkDisplay*"); Xen_check_type(Xen_is_guint(accelerator_key), accelerator_key, 2, "gtk_accelerator_name_with_keycode", "guint"); Xen_check_type(Xen_is_guint(keycode), keycode, 3, "gtk_accelerator_name_with_keycode", "guint"); Xen_check_type(Xen_is_GdkModifierType(accelerator_mods), accelerator_mods, 4, "gtk_accelerator_name_with_keycode", "GdkModifierType"); return(C_to_Xen_gchar_(gtk_accelerator_name_with_keycode(Xen_to_C_GdkDisplay_(display), Xen_to_C_guint(accelerator_key), Xen_to_C_guint(keycode), Xen_to_C_GdkModifierType(accelerator_mods)))); } static Xen gxg_gtk_accelerator_get_label_with_keycode(Xen display, Xen accelerator_key, Xen keycode, Xen accelerator_mods) { #define H_gtk_accelerator_get_label_with_keycode "gchar* gtk_accelerator_get_label_with_keycode(GdkDisplay* display, \ guint accelerator_key, guint keycode, GdkModifierType accelerator_mods)" Xen_check_type(Xen_is_GdkDisplay_(display), display, 1, "gtk_accelerator_get_label_with_keycode", "GdkDisplay*"); Xen_check_type(Xen_is_guint(accelerator_key), accelerator_key, 2, "gtk_accelerator_get_label_with_keycode", "guint"); Xen_check_type(Xen_is_guint(keycode), keycode, 3, "gtk_accelerator_get_label_with_keycode", "guint"); Xen_check_type(Xen_is_GdkModifierType(accelerator_mods), accelerator_mods, 4, "gtk_accelerator_get_label_with_keycode", "GdkModifierType"); return(C_to_Xen_gchar_(gtk_accelerator_get_label_with_keycode(Xen_to_C_GdkDisplay_(display), Xen_to_C_guint(accelerator_key), Xen_to_C_guint(keycode), Xen_to_C_GdkModifierType(accelerator_mods)))); } static Xen gxg_gdk_screen_get_monitor_workarea(Xen screen, Xen monitor_num, Xen dest) { #define H_gdk_screen_get_monitor_workarea "void gdk_screen_get_monitor_workarea(GdkScreen* screen, \ gint monitor_num, GdkRectangle* dest)" Xen_check_type(Xen_is_GdkScreen_(screen), screen, 1, "gdk_screen_get_monitor_workarea", "GdkScreen*"); Xen_check_type(Xen_is_gint(monitor_num), monitor_num, 2, "gdk_screen_get_monitor_workarea", "gint"); Xen_check_type(Xen_is_GdkRectangle_(dest), dest, 3, "gdk_screen_get_monitor_workarea", "GdkRectangle*"); gdk_screen_get_monitor_workarea(Xen_to_C_GdkScreen_(screen), Xen_to_C_gint(monitor_num), Xen_to_C_GdkRectangle_(dest)); return(Xen_false); } static Xen gxg_gtk_application_get_app_menu(Xen application) { #define H_gtk_application_get_app_menu "GMenuModel* gtk_application_get_app_menu(GtkApplication* application)" Xen_check_type(Xen_is_GtkApplication_(application), application, 1, "gtk_application_get_app_menu", "GtkApplication*"); return(C_to_Xen_GMenuModel_(gtk_application_get_app_menu(Xen_to_C_GtkApplication_(application)))); } static Xen gxg_gtk_application_set_app_menu(Xen application, Xen model) { #define H_gtk_application_set_app_menu "void gtk_application_set_app_menu(GtkApplication* application, \ GMenuModel* model)" Xen_check_type(Xen_is_GtkApplication_(application), application, 1, "gtk_application_set_app_menu", "GtkApplication*"); Xen_check_type(Xen_is_GMenuModel_(model), model, 2, "gtk_application_set_app_menu", "GMenuModel*"); gtk_application_set_app_menu(Xen_to_C_GtkApplication_(application), Xen_to_C_GMenuModel_(model)); return(Xen_false); } static Xen gxg_gtk_application_get_menubar(Xen application) { #define H_gtk_application_get_menubar "GMenuModel* gtk_application_get_menubar(GtkApplication* application)" Xen_check_type(Xen_is_GtkApplication_(application), application, 1, "gtk_application_get_menubar", "GtkApplication*"); return(C_to_Xen_GMenuModel_(gtk_application_get_menubar(Xen_to_C_GtkApplication_(application)))); } static Xen gxg_gtk_application_set_menubar(Xen application, Xen model) { #define H_gtk_application_set_menubar "void gtk_application_set_menubar(GtkApplication* application, \ GMenuModel* model)" Xen_check_type(Xen_is_GtkApplication_(application), application, 1, "gtk_application_set_menubar", "GtkApplication*"); Xen_check_type(Xen_is_GMenuModel_(model), model, 2, "gtk_application_set_menubar", "GMenuModel*"); gtk_application_set_menubar(Xen_to_C_GtkApplication_(application), Xen_to_C_GMenuModel_(model)); return(Xen_false); } static Xen gxg_gtk_entry_completion_compute_prefix(Xen completion, Xen key) { #define H_gtk_entry_completion_compute_prefix "gchar* gtk_entry_completion_compute_prefix(GtkEntryCompletion* completion, \ char* key)" Xen_check_type(Xen_is_GtkEntryCompletion_(completion), completion, 1, "gtk_entry_completion_compute_prefix", "GtkEntryCompletion*"); Xen_check_type(Xen_is_char_(key), key, 2, "gtk_entry_completion_compute_prefix", "char*"); return(C_to_Xen_gchar_(gtk_entry_completion_compute_prefix(Xen_to_C_GtkEntryCompletion_(completion), (const char*)Xen_to_C_char_(key)))); } static Xen gxg_gtk_scale_set_has_origin(Xen scale, Xen has_origin) { #define H_gtk_scale_set_has_origin "void gtk_scale_set_has_origin(GtkScale* scale, gboolean has_origin)" Xen_check_type(Xen_is_GtkScale_(scale), scale, 1, "gtk_scale_set_has_origin", "GtkScale*"); Xen_check_type(Xen_is_gboolean(has_origin), has_origin, 2, "gtk_scale_set_has_origin", "gboolean"); gtk_scale_set_has_origin(Xen_to_C_GtkScale_(scale), Xen_to_C_gboolean(has_origin)); return(Xen_false); } static Xen gxg_gtk_scale_get_has_origin(Xen scale) { #define H_gtk_scale_get_has_origin "gboolean gtk_scale_get_has_origin(GtkScale* scale)" Xen_check_type(Xen_is_GtkScale_(scale), scale, 1, "gtk_scale_get_has_origin", "GtkScale*"); return(C_to_Xen_gboolean(gtk_scale_get_has_origin(Xen_to_C_GtkScale_(scale)))); } static Xen gxg_gtk_window_set_hide_titlebar_when_maximized(Xen window, Xen setting) { #define H_gtk_window_set_hide_titlebar_when_maximized "void gtk_window_set_hide_titlebar_when_maximized(GtkWindow* window, \ gboolean setting)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_set_hide_titlebar_when_maximized", "GtkWindow*"); Xen_check_type(Xen_is_gboolean(setting), setting, 2, "gtk_window_set_hide_titlebar_when_maximized", "gboolean"); gtk_window_set_hide_titlebar_when_maximized(Xen_to_C_GtkWindow_(window), Xen_to_C_gboolean(setting)); return(Xen_false); } static Xen gxg_gtk_window_get_hide_titlebar_when_maximized(Xen window) { #define H_gtk_window_get_hide_titlebar_when_maximized "gboolean gtk_window_get_hide_titlebar_when_maximized(GtkWindow* window)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_get_hide_titlebar_when_maximized", "GtkWindow*"); return(C_to_Xen_gboolean(gtk_window_get_hide_titlebar_when_maximized(Xen_to_C_GtkWindow_(window)))); } static Xen gxg_gtk_application_window_new(Xen application) { #define H_gtk_application_window_new "GtkWidget* gtk_application_window_new(GtkApplication* application)" Xen_check_type(Xen_is_GtkApplication_(application), application, 1, "gtk_application_window_new", "GtkApplication*"); return(C_to_Xen_GtkWidget_(gtk_application_window_new(Xen_to_C_GtkApplication_(application)))); } static Xen gxg_gtk_application_window_set_show_menubar(Xen window, Xen show_menubar) { #define H_gtk_application_window_set_show_menubar "void gtk_application_window_set_show_menubar(GtkApplicationWindow* window, \ gboolean show_menubar)" Xen_check_type(Xen_is_GtkApplicationWindow_(window), window, 1, "gtk_application_window_set_show_menubar", "GtkApplicationWindow*"); Xen_check_type(Xen_is_gboolean(show_menubar), show_menubar, 2, "gtk_application_window_set_show_menubar", "gboolean"); gtk_application_window_set_show_menubar(Xen_to_C_GtkApplicationWindow_(window), Xen_to_C_gboolean(show_menubar)); return(Xen_false); } static Xen gxg_gtk_application_window_get_show_menubar(Xen window) { #define H_gtk_application_window_get_show_menubar "gboolean gtk_application_window_get_show_menubar(GtkApplicationWindow* window)" Xen_check_type(Xen_is_GtkApplicationWindow_(window), window, 1, "gtk_application_window_get_show_menubar", "GtkApplicationWindow*"); return(C_to_Xen_gboolean(gtk_application_window_get_show_menubar(Xen_to_C_GtkApplicationWindow_(window)))); } static Xen gxg_gtk_image_new_from_resource(Xen resource_path) { #define H_gtk_image_new_from_resource "GtkWidget* gtk_image_new_from_resource(gchar* resource_path)" Xen_check_type(Xen_is_gchar_(resource_path), resource_path, 1, "gtk_image_new_from_resource", "gchar*"); return(C_to_Xen_GtkWidget_(gtk_image_new_from_resource((const gchar*)Xen_to_C_gchar_(resource_path)))); } static Xen gxg_gtk_image_set_from_resource(Xen image, Xen resource_path) { #define H_gtk_image_set_from_resource "void gtk_image_set_from_resource(GtkImage* image, gchar* resource_path)" Xen_check_type(Xen_is_GtkImage_(image), image, 1, "gtk_image_set_from_resource", "GtkImage*"); Xen_check_type(Xen_is_gchar_(resource_path), resource_path, 2, "gtk_image_set_from_resource", "gchar*"); gtk_image_set_from_resource(Xen_to_C_GtkImage_(image), (const gchar*)Xen_to_C_gchar_(resource_path)); return(Xen_false); } static Xen gxg_gtk_window_set_attached_to(Xen window, Xen attach_widget) { #define H_gtk_window_set_attached_to "void gtk_window_set_attached_to(GtkWindow* window, GtkWidget* attach_widget)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_set_attached_to", "GtkWindow*"); Xen_check_type(Xen_is_GtkWidget_(attach_widget), attach_widget, 2, "gtk_window_set_attached_to", "GtkWidget*"); gtk_window_set_attached_to(Xen_to_C_GtkWindow_(window), Xen_to_C_GtkWidget_(attach_widget)); return(Xen_false); } static Xen gxg_gtk_window_get_attached_to(Xen window) { #define H_gtk_window_get_attached_to "GtkWidget* gtk_window_get_attached_to(GtkWindow* window)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_get_attached_to", "GtkWindow*"); return(C_to_Xen_GtkWidget_(gtk_window_get_attached_to(Xen_to_C_GtkWindow_(window)))); } static Xen gxg_gtk_about_dialog_add_credit_section(Xen about, Xen section_name, Xen people) { #define H_gtk_about_dialog_add_credit_section "void gtk_about_dialog_add_credit_section(GtkAboutDialog* about, \ gchar* section_name, gchar** people)" Xen_check_type(Xen_is_GtkAboutDialog_(about), about, 1, "gtk_about_dialog_add_credit_section", "GtkAboutDialog*"); Xen_check_type(Xen_is_gchar_(section_name), section_name, 2, "gtk_about_dialog_add_credit_section", "gchar*"); Xen_check_type(Xen_is_gchar__(people), people, 3, "gtk_about_dialog_add_credit_section", "gchar**"); gtk_about_dialog_add_credit_section(Xen_to_C_GtkAboutDialog_(about), (const gchar*)Xen_to_C_gchar_(section_name), (const gchar**)Xen_to_C_gchar__(people)); return(Xen_false); } static Xen gxg_gdk_keymap_get_modifier_state(Xen keymap) { #define H_gdk_keymap_get_modifier_state "guint gdk_keymap_get_modifier_state(GdkKeymap* keymap)" Xen_check_type(Xen_is_GdkKeymap_(keymap), keymap, 1, "gdk_keymap_get_modifier_state", "GdkKeymap*"); return(C_to_Xen_guint(gdk_keymap_get_modifier_state(Xen_to_C_GdkKeymap_(keymap)))); } static Xen gxg_gtk_hsv_to_rgb(Xen h, Xen s, Xen v, Xen ignore_r, Xen ignore_g, Xen ignore_b) { #define H_gtk_hsv_to_rgb "void gtk_hsv_to_rgb(gdouble h, gdouble s, gdouble v, gdouble* [r], gdouble* [g], \ gdouble* [b])" gdouble ref_r; gdouble ref_g; gdouble ref_b; Xen_check_type(Xen_is_gdouble(h), h, 1, "gtk_hsv_to_rgb", "gdouble"); Xen_check_type(Xen_is_gdouble(s), s, 2, "gtk_hsv_to_rgb", "gdouble"); Xen_check_type(Xen_is_gdouble(v), v, 3, "gtk_hsv_to_rgb", "gdouble"); gtk_hsv_to_rgb(Xen_to_C_gdouble(h), Xen_to_C_gdouble(s), Xen_to_C_gdouble(v), &ref_r, &ref_g, &ref_b); return(Xen_list_3(C_to_Xen_gdouble(ref_r), C_to_Xen_gdouble(ref_g), C_to_Xen_gdouble(ref_b))); } static Xen gxg_gtk_rgb_to_hsv(Xen r, Xen g, Xen b, Xen ignore_h, Xen ignore_s, Xen ignore_v) { #define H_gtk_rgb_to_hsv "void gtk_rgb_to_hsv(gdouble r, gdouble g, gdouble b, gdouble* [h], gdouble* [s], \ gdouble* [v])" gdouble ref_h; gdouble ref_s; gdouble ref_v; Xen_check_type(Xen_is_gdouble(r), r, 1, "gtk_rgb_to_hsv", "gdouble"); Xen_check_type(Xen_is_gdouble(g), g, 2, "gtk_rgb_to_hsv", "gdouble"); Xen_check_type(Xen_is_gdouble(b), b, 3, "gtk_rgb_to_hsv", "gdouble"); gtk_rgb_to_hsv(Xen_to_C_gdouble(r), Xen_to_C_gdouble(g), Xen_to_C_gdouble(b), &ref_h, &ref_s, &ref_v); return(Xen_list_3(C_to_Xen_gdouble(ref_h), C_to_Xen_gdouble(ref_s), C_to_Xen_gdouble(ref_v))); } static Xen gxg_gtk_color_chooser_get_rgba(Xen chooser, Xen color) { #define H_gtk_color_chooser_get_rgba "void gtk_color_chooser_get_rgba(GtkColorChooser* chooser, GdkRGBA* color)" Xen_check_type(Xen_is_GtkColorChooser_(chooser), chooser, 1, "gtk_color_chooser_get_rgba", "GtkColorChooser*"); Xen_check_type(Xen_is_GdkRGBA_(color), color, 2, "gtk_color_chooser_get_rgba", "GdkRGBA*"); gtk_color_chooser_get_rgba(Xen_to_C_GtkColorChooser_(chooser), Xen_to_C_GdkRGBA_(color)); return(Xen_false); } static Xen gxg_gtk_color_chooser_set_rgba(Xen chooser, Xen color) { #define H_gtk_color_chooser_set_rgba "void gtk_color_chooser_set_rgba(GtkColorChooser* chooser, GdkRGBA* color)" Xen_check_type(Xen_is_GtkColorChooser_(chooser), chooser, 1, "gtk_color_chooser_set_rgba", "GtkColorChooser*"); Xen_check_type(Xen_is_GdkRGBA_(color), color, 2, "gtk_color_chooser_set_rgba", "GdkRGBA*"); gtk_color_chooser_set_rgba(Xen_to_C_GtkColorChooser_(chooser), Xen_to_C_GdkRGBA_(color)); return(Xen_false); } static Xen gxg_gtk_color_chooser_get_use_alpha(Xen chooser) { #define H_gtk_color_chooser_get_use_alpha "gboolean gtk_color_chooser_get_use_alpha(GtkColorChooser* chooser)" Xen_check_type(Xen_is_GtkColorChooser_(chooser), chooser, 1, "gtk_color_chooser_get_use_alpha", "GtkColorChooser*"); return(C_to_Xen_gboolean(gtk_color_chooser_get_use_alpha(Xen_to_C_GtkColorChooser_(chooser)))); } static Xen gxg_gtk_color_chooser_set_use_alpha(Xen chooser, Xen use_alpha) { #define H_gtk_color_chooser_set_use_alpha "void gtk_color_chooser_set_use_alpha(GtkColorChooser* chooser, \ gboolean use_alpha)" Xen_check_type(Xen_is_GtkColorChooser_(chooser), chooser, 1, "gtk_color_chooser_set_use_alpha", "GtkColorChooser*"); Xen_check_type(Xen_is_gboolean(use_alpha), use_alpha, 2, "gtk_color_chooser_set_use_alpha", "gboolean"); gtk_color_chooser_set_use_alpha(Xen_to_C_GtkColorChooser_(chooser), Xen_to_C_gboolean(use_alpha)); return(Xen_false); } static Xen gxg_gtk_color_chooser_dialog_new(Xen title, Xen parent) { #define H_gtk_color_chooser_dialog_new "GtkWidget* gtk_color_chooser_dialog_new(gchar* title, GtkWindow* parent)" Xen_check_type(Xen_is_gchar_(title), title, 1, "gtk_color_chooser_dialog_new", "gchar*"); Xen_check_type(Xen_is_GtkWindow_(parent), parent, 2, "gtk_color_chooser_dialog_new", "GtkWindow*"); return(C_to_Xen_GtkWidget_(gtk_color_chooser_dialog_new((const gchar*)Xen_to_C_gchar_(title), Xen_to_C_GtkWindow_(parent)))); } static Xen gxg_gtk_color_chooser_widget_new(void) { #define H_gtk_color_chooser_widget_new "GtkWidget* gtk_color_chooser_widget_new( void)" return(C_to_Xen_GtkWidget_(gtk_color_chooser_widget_new())); } #endif #if GTK_CHECK_VERSION(3, 6, 0) static Xen gxg_gdk_event_get_scroll_deltas(Xen event, Xen ignore_delta_x, Xen ignore_delta_y) { #define H_gdk_event_get_scroll_deltas "gboolean gdk_event_get_scroll_deltas(GdkEvent* event, gdouble* [delta_x], \ gdouble* [delta_y])" gdouble ref_delta_x; gdouble ref_delta_y; Xen_check_type(Xen_is_GdkEvent_(event), event, 1, "gdk_event_get_scroll_deltas", "GdkEvent*"); { Xen result; result = C_to_Xen_gboolean(gdk_event_get_scroll_deltas(Xen_to_C_GdkEvent_(event), &ref_delta_x, &ref_delta_y)); return(Xen_list_3(result, C_to_Xen_gdouble(ref_delta_x), C_to_Xen_gdouble(ref_delta_y))); } } static Xen gxg_gtk_color_chooser_add_palette(Xen chooser, Xen horizontal, Xen colors_per_line, Xen n_colors, Xen colors) { #define H_gtk_color_chooser_add_palette "void gtk_color_chooser_add_palette(GtkColorChooser* chooser, \ GtkOrientation horizontal, gint colors_per_line, gint n_colors, GdkRGBA* colors)" Xen_check_type(Xen_is_GtkColorChooser_(chooser), chooser, 1, "gtk_color_chooser_add_palette", "GtkColorChooser*"); Xen_check_type(Xen_is_GtkOrientation(horizontal), horizontal, 2, "gtk_color_chooser_add_palette", "GtkOrientation"); Xen_check_type(Xen_is_gint(colors_per_line), colors_per_line, 3, "gtk_color_chooser_add_palette", "gint"); Xen_check_type(Xen_is_gint(n_colors), n_colors, 4, "gtk_color_chooser_add_palette", "gint"); Xen_check_type(Xen_is_GdkRGBA_(colors), colors, 5, "gtk_color_chooser_add_palette", "GdkRGBA*"); gtk_color_chooser_add_palette(Xen_to_C_GtkColorChooser_(chooser), Xen_to_C_GtkOrientation(horizontal), Xen_to_C_gint(colors_per_line), Xen_to_C_gint(n_colors), Xen_to_C_GdkRGBA_(colors)); return(Xen_false); } static Xen gxg_gtk_button_set_always_show_image(Xen button, Xen always_show) { #define H_gtk_button_set_always_show_image "void gtk_button_set_always_show_image(GtkButton* button, \ gboolean always_show)" Xen_check_type(Xen_is_GtkButton_(button), button, 1, "gtk_button_set_always_show_image", "GtkButton*"); Xen_check_type(Xen_is_gboolean(always_show), always_show, 2, "gtk_button_set_always_show_image", "gboolean"); gtk_button_set_always_show_image(Xen_to_C_GtkButton_(button), Xen_to_C_gboolean(always_show)); return(Xen_false); } static Xen gxg_gtk_button_get_always_show_image(Xen button) { #define H_gtk_button_get_always_show_image "gboolean gtk_button_get_always_show_image(GtkButton* button)" Xen_check_type(Xen_is_GtkButton_(button), button, 1, "gtk_button_get_always_show_image", "GtkButton*"); return(C_to_Xen_gboolean(gtk_button_get_always_show_image(Xen_to_C_GtkButton_(button)))); } static Xen gxg_gtk_tree_view_get_n_columns(Xen tree_view) { #define H_gtk_tree_view_get_n_columns "guint gtk_tree_view_get_n_columns(GtkTreeView* tree_view)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_get_n_columns", "GtkTreeView*"); return(C_to_Xen_guint(gtk_tree_view_get_n_columns(Xen_to_C_GtkTreeView_(tree_view)))); } static Xen gxg_gtk_menu_button_new(void) { #define H_gtk_menu_button_new "GtkWidget* gtk_menu_button_new( void)" return(C_to_Xen_GtkWidget_(gtk_menu_button_new())); } static Xen gxg_gtk_menu_button_set_menu_model(Xen menu_button, Xen menu_model) { #define H_gtk_menu_button_set_menu_model "void gtk_menu_button_set_menu_model(GtkMenuButton* menu_button, \ GMenuModel* menu_model)" Xen_check_type(Xen_is_GtkMenuButton_(menu_button), menu_button, 1, "gtk_menu_button_set_menu_model", "GtkMenuButton*"); Xen_check_type(Xen_is_GMenuModel_(menu_model), menu_model, 2, "gtk_menu_button_set_menu_model", "GMenuModel*"); gtk_menu_button_set_menu_model(Xen_to_C_GtkMenuButton_(menu_button), Xen_to_C_GMenuModel_(menu_model)); return(Xen_false); } static Xen gxg_gtk_menu_button_get_menu_model(Xen menu_button) { #define H_gtk_menu_button_get_menu_model "GMenuModel* gtk_menu_button_get_menu_model(GtkMenuButton* menu_button)" Xen_check_type(Xen_is_GtkMenuButton_(menu_button), menu_button, 1, "gtk_menu_button_get_menu_model", "GtkMenuButton*"); return(C_to_Xen_GMenuModel_(gtk_menu_button_get_menu_model(Xen_to_C_GtkMenuButton_(menu_button)))); } static Xen gxg_gtk_menu_button_set_align_widget(Xen menu_button, Xen align_widget) { #define H_gtk_menu_button_set_align_widget "void gtk_menu_button_set_align_widget(GtkMenuButton* menu_button, \ GtkWidget* align_widget)" Xen_check_type(Xen_is_GtkMenuButton_(menu_button), menu_button, 1, "gtk_menu_button_set_align_widget", "GtkMenuButton*"); Xen_check_type(Xen_is_GtkWidget_(align_widget), align_widget, 2, "gtk_menu_button_set_align_widget", "GtkWidget*"); gtk_menu_button_set_align_widget(Xen_to_C_GtkMenuButton_(menu_button), Xen_to_C_GtkWidget_(align_widget)); return(Xen_false); } static Xen gxg_gtk_menu_button_get_align_widget(Xen menu_button) { #define H_gtk_menu_button_get_align_widget "GtkWidget* gtk_menu_button_get_align_widget(GtkMenuButton* menu_button)" Xen_check_type(Xen_is_GtkMenuButton_(menu_button), menu_button, 1, "gtk_menu_button_get_align_widget", "GtkMenuButton*"); return(C_to_Xen_GtkWidget_(gtk_menu_button_get_align_widget(Xen_to_C_GtkMenuButton_(menu_button)))); } static Xen gxg_gtk_search_entry_new(void) { #define H_gtk_search_entry_new "GtkWidget* gtk_search_entry_new( void)" return(C_to_Xen_GtkWidget_(gtk_search_entry_new())); } static Xen gxg_gtk_level_bar_new(void) { #define H_gtk_level_bar_new "GtkWidget* gtk_level_bar_new( void)" return(C_to_Xen_GtkWidget_(gtk_level_bar_new())); } static Xen gxg_gtk_level_bar_new_for_interval(Xen min_value, Xen max_value) { #define H_gtk_level_bar_new_for_interval "GtkWidget* gtk_level_bar_new_for_interval(gdouble min_value, \ gdouble max_value)" Xen_check_type(Xen_is_gdouble(min_value), min_value, 1, "gtk_level_bar_new_for_interval", "gdouble"); Xen_check_type(Xen_is_gdouble(max_value), max_value, 2, "gtk_level_bar_new_for_interval", "gdouble"); return(C_to_Xen_GtkWidget_(gtk_level_bar_new_for_interval(Xen_to_C_gdouble(min_value), Xen_to_C_gdouble(max_value)))); } static Xen gxg_gtk_level_bar_set_mode(Xen self, Xen mode) { #define H_gtk_level_bar_set_mode "void gtk_level_bar_set_mode(GtkLevelBar* self, GtkLevelBarMode mode)" Xen_check_type(Xen_is_GtkLevelBar_(self), self, 1, "gtk_level_bar_set_mode", "GtkLevelBar*"); Xen_check_type(Xen_is_GtkLevelBarMode(mode), mode, 2, "gtk_level_bar_set_mode", "GtkLevelBarMode"); gtk_level_bar_set_mode(Xen_to_C_GtkLevelBar_(self), Xen_to_C_GtkLevelBarMode(mode)); return(Xen_false); } static Xen gxg_gtk_level_bar_get_mode(Xen self) { #define H_gtk_level_bar_get_mode "GtkLevelBarMode gtk_level_bar_get_mode(GtkLevelBar* self)" Xen_check_type(Xen_is_GtkLevelBar_(self), self, 1, "gtk_level_bar_get_mode", "GtkLevelBar*"); return(C_to_Xen_GtkLevelBarMode(gtk_level_bar_get_mode(Xen_to_C_GtkLevelBar_(self)))); } static Xen gxg_gtk_level_bar_set_value(Xen self, Xen value) { #define H_gtk_level_bar_set_value "void gtk_level_bar_set_value(GtkLevelBar* self, gdouble value)" Xen_check_type(Xen_is_GtkLevelBar_(self), self, 1, "gtk_level_bar_set_value", "GtkLevelBar*"); Xen_check_type(Xen_is_gdouble(value), value, 2, "gtk_level_bar_set_value", "gdouble"); gtk_level_bar_set_value(Xen_to_C_GtkLevelBar_(self), Xen_to_C_gdouble(value)); return(Xen_false); } static Xen gxg_gtk_level_bar_get_value(Xen self) { #define H_gtk_level_bar_get_value "gdouble gtk_level_bar_get_value(GtkLevelBar* self)" Xen_check_type(Xen_is_GtkLevelBar_(self), self, 1, "gtk_level_bar_get_value", "GtkLevelBar*"); return(C_to_Xen_gdouble(gtk_level_bar_get_value(Xen_to_C_GtkLevelBar_(self)))); } static Xen gxg_gtk_level_bar_set_min_value(Xen self, Xen value) { #define H_gtk_level_bar_set_min_value "void gtk_level_bar_set_min_value(GtkLevelBar* self, gdouble value)" Xen_check_type(Xen_is_GtkLevelBar_(self), self, 1, "gtk_level_bar_set_min_value", "GtkLevelBar*"); Xen_check_type(Xen_is_gdouble(value), value, 2, "gtk_level_bar_set_min_value", "gdouble"); gtk_level_bar_set_min_value(Xen_to_C_GtkLevelBar_(self), Xen_to_C_gdouble(value)); return(Xen_false); } static Xen gxg_gtk_level_bar_get_min_value(Xen self) { #define H_gtk_level_bar_get_min_value "gdouble gtk_level_bar_get_min_value(GtkLevelBar* self)" Xen_check_type(Xen_is_GtkLevelBar_(self), self, 1, "gtk_level_bar_get_min_value", "GtkLevelBar*"); return(C_to_Xen_gdouble(gtk_level_bar_get_min_value(Xen_to_C_GtkLevelBar_(self)))); } static Xen gxg_gtk_level_bar_set_max_value(Xen self, Xen value) { #define H_gtk_level_bar_set_max_value "void gtk_level_bar_set_max_value(GtkLevelBar* self, gdouble value)" Xen_check_type(Xen_is_GtkLevelBar_(self), self, 1, "gtk_level_bar_set_max_value", "GtkLevelBar*"); Xen_check_type(Xen_is_gdouble(value), value, 2, "gtk_level_bar_set_max_value", "gdouble"); gtk_level_bar_set_max_value(Xen_to_C_GtkLevelBar_(self), Xen_to_C_gdouble(value)); return(Xen_false); } static Xen gxg_gtk_level_bar_get_max_value(Xen self) { #define H_gtk_level_bar_get_max_value "gdouble gtk_level_bar_get_max_value(GtkLevelBar* self)" Xen_check_type(Xen_is_GtkLevelBar_(self), self, 1, "gtk_level_bar_get_max_value", "GtkLevelBar*"); return(C_to_Xen_gdouble(gtk_level_bar_get_max_value(Xen_to_C_GtkLevelBar_(self)))); } static Xen gxg_gtk_level_bar_add_offset_value(Xen self, Xen name, Xen value) { #define H_gtk_level_bar_add_offset_value "void gtk_level_bar_add_offset_value(GtkLevelBar* self, gchar* name, \ gdouble value)" Xen_check_type(Xen_is_GtkLevelBar_(self), self, 1, "gtk_level_bar_add_offset_value", "GtkLevelBar*"); Xen_check_type(Xen_is_gchar_(name), name, 2, "gtk_level_bar_add_offset_value", "gchar*"); Xen_check_type(Xen_is_gdouble(value), value, 3, "gtk_level_bar_add_offset_value", "gdouble"); gtk_level_bar_add_offset_value(Xen_to_C_GtkLevelBar_(self), (const gchar*)Xen_to_C_gchar_(name), Xen_to_C_gdouble(value)); return(Xen_false); } static Xen gxg_gtk_level_bar_remove_offset_value(Xen self, Xen name) { #define H_gtk_level_bar_remove_offset_value "void gtk_level_bar_remove_offset_value(GtkLevelBar* self, \ gchar* name)" Xen_check_type(Xen_is_GtkLevelBar_(self), self, 1, "gtk_level_bar_remove_offset_value", "GtkLevelBar*"); Xen_check_type(Xen_is_gchar_(name), name, 2, "gtk_level_bar_remove_offset_value", "gchar*"); gtk_level_bar_remove_offset_value(Xen_to_C_GtkLevelBar_(self), (const gchar*)Xen_to_C_gchar_(name)); return(Xen_false); } static Xen gxg_gtk_level_bar_get_offset_value(Xen self, Xen name, Xen ignore_value) { #define H_gtk_level_bar_get_offset_value "gboolean gtk_level_bar_get_offset_value(GtkLevelBar* self, \ gchar* name, gdouble* [value])" gdouble ref_value; Xen_check_type(Xen_is_GtkLevelBar_(self), self, 1, "gtk_level_bar_get_offset_value", "GtkLevelBar*"); Xen_check_type(Xen_is_gchar_(name), name, 2, "gtk_level_bar_get_offset_value", "gchar*"); { Xen result; result = C_to_Xen_gboolean(gtk_level_bar_get_offset_value(Xen_to_C_GtkLevelBar_(self), (const gchar*)Xen_to_C_gchar_(name), &ref_value)); return(Xen_list_2(result, C_to_Xen_gdouble(ref_value))); } } static Xen gxg_gtk_application_get_active_window(Xen application) { #define H_gtk_application_get_active_window "GtkWindow* gtk_application_get_active_window(GtkApplication* application)" Xen_check_type(Xen_is_GtkApplication_(application), application, 1, "gtk_application_get_active_window", "GtkApplication*"); return(C_to_Xen_GtkWindow_(gtk_application_get_active_window(Xen_to_C_GtkApplication_(application)))); } static Xen gxg_gtk_entry_set_input_purpose(Xen entry, Xen purpose) { #define H_gtk_entry_set_input_purpose "void gtk_entry_set_input_purpose(GtkEntry* entry, GtkInputPurpose purpose)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_set_input_purpose", "GtkEntry*"); Xen_check_type(Xen_is_GtkInputPurpose(purpose), purpose, 2, "gtk_entry_set_input_purpose", "GtkInputPurpose"); gtk_entry_set_input_purpose(Xen_to_C_GtkEntry_(entry), Xen_to_C_GtkInputPurpose(purpose)); return(Xen_false); } static Xen gxg_gtk_entry_get_input_purpose(Xen entry) { #define H_gtk_entry_get_input_purpose "GtkInputPurpose gtk_entry_get_input_purpose(GtkEntry* entry)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_get_input_purpose", "GtkEntry*"); return(C_to_Xen_GtkInputPurpose(gtk_entry_get_input_purpose(Xen_to_C_GtkEntry_(entry)))); } static Xen gxg_gtk_entry_set_input_hints(Xen entry, Xen hints) { #define H_gtk_entry_set_input_hints "void gtk_entry_set_input_hints(GtkEntry* entry, GtkInputHints hints)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_set_input_hints", "GtkEntry*"); Xen_check_type(Xen_is_GtkInputHints(hints), hints, 2, "gtk_entry_set_input_hints", "GtkInputHints"); gtk_entry_set_input_hints(Xen_to_C_GtkEntry_(entry), Xen_to_C_GtkInputHints(hints)); return(Xen_false); } static Xen gxg_gtk_entry_get_input_hints(Xen entry) { #define H_gtk_entry_get_input_hints "GtkInputHints gtk_entry_get_input_hints(GtkEntry* entry)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_get_input_hints", "GtkEntry*"); return(C_to_Xen_GtkInputHints(gtk_entry_get_input_hints(Xen_to_C_GtkEntry_(entry)))); } static Xen gxg_gtk_menu_button_get_popup(Xen menu_button) { #define H_gtk_menu_button_get_popup "GtkMenu* gtk_menu_button_get_popup(GtkMenuButton* menu_button)" Xen_check_type(Xen_is_GtkMenuButton_(menu_button), menu_button, 1, "gtk_menu_button_get_popup", "GtkMenuButton*"); return(C_to_Xen_GtkMenu_(gtk_menu_button_get_popup(Xen_to_C_GtkMenuButton_(menu_button)))); } static Xen gxg_gtk_text_view_set_input_purpose(Xen text_view, Xen purpose) { #define H_gtk_text_view_set_input_purpose "void gtk_text_view_set_input_purpose(GtkTextView* text_view, \ GtkInputPurpose purpose)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_set_input_purpose", "GtkTextView*"); Xen_check_type(Xen_is_GtkInputPurpose(purpose), purpose, 2, "gtk_text_view_set_input_purpose", "GtkInputPurpose"); gtk_text_view_set_input_purpose(Xen_to_C_GtkTextView_(text_view), Xen_to_C_GtkInputPurpose(purpose)); return(Xen_false); } static Xen gxg_gtk_text_view_get_input_purpose(Xen text_view) { #define H_gtk_text_view_get_input_purpose "GtkInputPurpose gtk_text_view_get_input_purpose(GtkTextView* text_view)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_get_input_purpose", "GtkTextView*"); return(C_to_Xen_GtkInputPurpose(gtk_text_view_get_input_purpose(Xen_to_C_GtkTextView_(text_view)))); } static Xen gxg_gtk_text_view_set_input_hints(Xen text_view, Xen hints) { #define H_gtk_text_view_set_input_hints "void gtk_text_view_set_input_hints(GtkTextView* text_view, \ GtkInputHints hints)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_set_input_hints", "GtkTextView*"); Xen_check_type(Xen_is_GtkInputHints(hints), hints, 2, "gtk_text_view_set_input_hints", "GtkInputHints"); gtk_text_view_set_input_hints(Xen_to_C_GtkTextView_(text_view), Xen_to_C_GtkInputHints(hints)); return(Xen_false); } static Xen gxg_gtk_text_view_get_input_hints(Xen text_view) { #define H_gtk_text_view_get_input_hints "GtkInputHints gtk_text_view_get_input_hints(GtkTextView* text_view)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_get_input_hints", "GtkTextView*"); return(C_to_Xen_GtkInputHints(gtk_text_view_get_input_hints(Xen_to_C_GtkTextView_(text_view)))); } static Xen gxg_gtk_entry_set_attributes(Xen entry, Xen attrs) { #define H_gtk_entry_set_attributes "void gtk_entry_set_attributes(GtkEntry* entry, PangoAttrList* attrs)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_set_attributes", "GtkEntry*"); Xen_check_type(Xen_is_PangoAttrList_(attrs), attrs, 2, "gtk_entry_set_attributes", "PangoAttrList*"); gtk_entry_set_attributes(Xen_to_C_GtkEntry_(entry), Xen_to_C_PangoAttrList_(attrs)); return(Xen_false); } static Xen gxg_gtk_entry_get_attributes(Xen entry) { #define H_gtk_entry_get_attributes "PangoAttrList* gtk_entry_get_attributes(GtkEntry* entry)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_get_attributes", "GtkEntry*"); return(C_to_Xen_PangoAttrList_(gtk_entry_get_attributes(Xen_to_C_GtkEntry_(entry)))); } static Xen gxg_gtk_accel_label_set_accel(Xen accel_label, Xen accelerator_key, Xen accelerator_mods) { #define H_gtk_accel_label_set_accel "void gtk_accel_label_set_accel(GtkAccelLabel* accel_label, guint accelerator_key, \ GdkModifierType accelerator_mods)" Xen_check_type(Xen_is_GtkAccelLabel_(accel_label), accel_label, 1, "gtk_accel_label_set_accel", "GtkAccelLabel*"); Xen_check_type(Xen_is_guint(accelerator_key), accelerator_key, 2, "gtk_accel_label_set_accel", "guint"); Xen_check_type(Xen_is_GdkModifierType(accelerator_mods), accelerator_mods, 3, "gtk_accel_label_set_accel", "GdkModifierType"); gtk_accel_label_set_accel(Xen_to_C_GtkAccelLabel_(accel_label), Xen_to_C_guint(accelerator_key), Xen_to_C_GdkModifierType(accelerator_mods)); return(Xen_false); } static Xen gxg_gtk_menu_shell_bind_model(Xen menu_shell, Xen model, Xen action_namespace, Xen with_separators) { #define H_gtk_menu_shell_bind_model "void gtk_menu_shell_bind_model(GtkMenuShell* menu_shell, GMenuModel* model, \ gchar* action_namespace, gboolean with_separators)" Xen_check_type(Xen_is_GtkMenuShell_(menu_shell), menu_shell, 1, "gtk_menu_shell_bind_model", "GtkMenuShell*"); Xen_check_type(Xen_is_GMenuModel_(model), model, 2, "gtk_menu_shell_bind_model", "GMenuModel*"); Xen_check_type(Xen_is_gchar_(action_namespace), action_namespace, 3, "gtk_menu_shell_bind_model", "gchar*"); Xen_check_type(Xen_is_gboolean(with_separators), with_separators, 4, "gtk_menu_shell_bind_model", "gboolean"); gtk_menu_shell_bind_model(Xen_to_C_GtkMenuShell_(menu_shell), Xen_to_C_GMenuModel_(model), (const gchar*)Xen_to_C_gchar_(action_namespace), Xen_to_C_gboolean(with_separators)); return(Xen_false); } #endif #if GTK_CHECK_VERSION(3, 8, 0) static Xen gxg_gtk_level_bar_set_inverted(Xen self, Xen inverted) { #define H_gtk_level_bar_set_inverted "void gtk_level_bar_set_inverted(GtkLevelBar* self, gboolean inverted)" Xen_check_type(Xen_is_GtkLevelBar_(self), self, 1, "gtk_level_bar_set_inverted", "GtkLevelBar*"); Xen_check_type(Xen_is_gboolean(inverted), inverted, 2, "gtk_level_bar_set_inverted", "gboolean"); gtk_level_bar_set_inverted(Xen_to_C_GtkLevelBar_(self), Xen_to_C_gboolean(inverted)); return(Xen_false); } static Xen gxg_gtk_level_bar_get_inverted(Xen self) { #define H_gtk_level_bar_get_inverted "gboolean gtk_level_bar_get_inverted(GtkLevelBar* self)" Xen_check_type(Xen_is_GtkLevelBar_(self), self, 1, "gtk_level_bar_get_inverted", "GtkLevelBar*"); return(C_to_Xen_gboolean(gtk_level_bar_get_inverted(Xen_to_C_GtkLevelBar_(self)))); } static Xen gxg_gtk_widget_is_visible(Xen widget) { #define H_gtk_widget_is_visible "gboolean gtk_widget_is_visible(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_is_visible", "GtkWidget*"); return(C_to_Xen_gboolean(gtk_widget_is_visible(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gdk_window_set_fullscreen_mode(Xen window, Xen mode) { #define H_gdk_window_set_fullscreen_mode "void gdk_window_set_fullscreen_mode(GdkWindow* window, GdkFullscreenMode mode)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_set_fullscreen_mode", "GdkWindow*"); Xen_check_type(Xen_is_GdkFullscreenMode(mode), mode, 2, "gdk_window_set_fullscreen_mode", "GdkFullscreenMode"); gdk_window_set_fullscreen_mode(Xen_to_C_GdkWindow_(window), Xen_to_C_GdkFullscreenMode(mode)); return(Xen_false); } static Xen gxg_gdk_window_get_fullscreen_mode(Xen window) { #define H_gdk_window_get_fullscreen_mode "GdkFullscreenMode gdk_window_get_fullscreen_mode(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_get_fullscreen_mode", "GdkWindow*"); return(C_to_Xen_GdkFullscreenMode(gdk_window_get_fullscreen_mode(Xen_to_C_GdkWindow_(window)))); } static Xen gxg_gtk_icon_view_set_activate_on_single_click(Xen icon_view, Xen single) { #define H_gtk_icon_view_set_activate_on_single_click "void gtk_icon_view_set_activate_on_single_click(GtkIconView* icon_view, \ gboolean single)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_set_activate_on_single_click", "GtkIconView*"); Xen_check_type(Xen_is_gboolean(single), single, 2, "gtk_icon_view_set_activate_on_single_click", "gboolean"); gtk_icon_view_set_activate_on_single_click(Xen_to_C_GtkIconView_(icon_view), Xen_to_C_gboolean(single)); return(Xen_false); } static Xen gxg_gtk_icon_view_get_activate_on_single_click(Xen icon_view) { #define H_gtk_icon_view_get_activate_on_single_click "gboolean gtk_icon_view_get_activate_on_single_click(GtkIconView* icon_view)" Xen_check_type(Xen_is_GtkIconView_(icon_view), icon_view, 1, "gtk_icon_view_get_activate_on_single_click", "GtkIconView*"); return(C_to_Xen_gboolean(gtk_icon_view_get_activate_on_single_click(Xen_to_C_GtkIconView_(icon_view)))); } static Xen gxg_gtk_tree_view_get_activate_on_single_click(Xen tree_view) { #define H_gtk_tree_view_get_activate_on_single_click "gboolean gtk_tree_view_get_activate_on_single_click(GtkTreeView* tree_view)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_get_activate_on_single_click", "GtkTreeView*"); return(C_to_Xen_gboolean(gtk_tree_view_get_activate_on_single_click(Xen_to_C_GtkTreeView_(tree_view)))); } static Xen gxg_gtk_tree_view_set_activate_on_single_click(Xen tree_view, Xen single) { #define H_gtk_tree_view_set_activate_on_single_click "void gtk_tree_view_set_activate_on_single_click(GtkTreeView* tree_view, \ gboolean single)" Xen_check_type(Xen_is_GtkTreeView_(tree_view), tree_view, 1, "gtk_tree_view_set_activate_on_single_click", "GtkTreeView*"); Xen_check_type(Xen_is_gboolean(single), single, 2, "gtk_tree_view_set_activate_on_single_click", "gboolean"); gtk_tree_view_set_activate_on_single_click(Xen_to_C_GtkTreeView_(tree_view), Xen_to_C_gboolean(single)); return(Xen_false); } static Xen gxg_gtk_widget_register_window(Xen widget, Xen window) { #define H_gtk_widget_register_window "void gtk_widget_register_window(GtkWidget* widget, GdkWindow* window)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_register_window", "GtkWidget*"); Xen_check_type(Xen_is_GdkWindow_(window), window, 2, "gtk_widget_register_window", "GdkWindow*"); gtk_widget_register_window(Xen_to_C_GtkWidget_(widget), Xen_to_C_GdkWindow_(window)); return(Xen_false); } static Xen gxg_gtk_widget_unregister_window(Xen widget, Xen window) { #define H_gtk_widget_unregister_window "void gtk_widget_unregister_window(GtkWidget* widget, GdkWindow* window)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_unregister_window", "GtkWidget*"); Xen_check_type(Xen_is_GdkWindow_(window), window, 2, "gtk_widget_unregister_window", "GdkWindow*"); gtk_widget_unregister_window(Xen_to_C_GtkWidget_(widget), Xen_to_C_GdkWindow_(window)); return(Xen_false); } static Xen gxg_gtk_widget_set_opacity(Xen widget, Xen opacity) { #define H_gtk_widget_set_opacity "void gtk_widget_set_opacity(GtkWidget* widget, double opacity)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_set_opacity", "GtkWidget*"); Xen_check_type(Xen_is_double(opacity), opacity, 2, "gtk_widget_set_opacity", "double"); gtk_widget_set_opacity(Xen_to_C_GtkWidget_(widget), Xen_to_C_double(opacity)); return(Xen_false); } static Xen gxg_gtk_widget_get_opacity(Xen widget) { #define H_gtk_widget_get_opacity "double gtk_widget_get_opacity(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_opacity", "GtkWidget*"); return(C_to_Xen_double(gtk_widget_get_opacity(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_pango_font_map_changed(Xen fontmap) { #define H_pango_font_map_changed "void pango_font_map_changed(PangoFontMap* fontmap)" Xen_check_type(Xen_is_PangoFontMap_(fontmap), fontmap, 1, "pango_font_map_changed", "PangoFontMap*"); pango_font_map_changed(Xen_to_C_PangoFontMap_(fontmap)); return(Xen_false); } #endif #if GTK_CHECK_VERSION(3, 10, 0) static Xen gxg_gdk_set_allowed_backends(Xen backends) { #define H_gdk_set_allowed_backends "void gdk_set_allowed_backends(gchar* backends)" Xen_check_type(Xen_is_gchar_(backends), backends, 1, "gdk_set_allowed_backends", "gchar*"); gdk_set_allowed_backends((const gchar*)Xen_to_C_gchar_(backends)); return(Xen_false); } static Xen gxg_gtk_box_set_baseline_position(Xen box, Xen position) { #define H_gtk_box_set_baseline_position "void gtk_box_set_baseline_position(GtkBox* box, GtkBaselinePosition position)" Xen_check_type(Xen_is_GtkBox_(box), box, 1, "gtk_box_set_baseline_position", "GtkBox*"); Xen_check_type(Xen_is_GtkBaselinePosition(position), position, 2, "gtk_box_set_baseline_position", "GtkBaselinePosition"); gtk_box_set_baseline_position(Xen_to_C_GtkBox_(box), Xen_to_C_GtkBaselinePosition(position)); return(Xen_false); } static Xen gxg_gtk_box_get_baseline_position(Xen box) { #define H_gtk_box_get_baseline_position "GtkBaselinePosition gtk_box_get_baseline_position(GtkBox* box)" Xen_check_type(Xen_is_GtkBox_(box), box, 1, "gtk_box_get_baseline_position", "GtkBox*"); return(C_to_Xen_GtkBaselinePosition(gtk_box_get_baseline_position(Xen_to_C_GtkBox_(box)))); } static Xen gxg_gtk_grid_remove_row(Xen grid, Xen position) { #define H_gtk_grid_remove_row "void gtk_grid_remove_row(GtkGrid* grid, gint position)" Xen_check_type(Xen_is_GtkGrid_(grid), grid, 1, "gtk_grid_remove_row", "GtkGrid*"); Xen_check_type(Xen_is_gint(position), position, 2, "gtk_grid_remove_row", "gint"); gtk_grid_remove_row(Xen_to_C_GtkGrid_(grid), Xen_to_C_gint(position)); return(Xen_false); } static Xen gxg_gtk_grid_remove_column(Xen grid, Xen position) { #define H_gtk_grid_remove_column "void gtk_grid_remove_column(GtkGrid* grid, gint position)" Xen_check_type(Xen_is_GtkGrid_(grid), grid, 1, "gtk_grid_remove_column", "GtkGrid*"); Xen_check_type(Xen_is_gint(position), position, 2, "gtk_grid_remove_column", "gint"); gtk_grid_remove_column(Xen_to_C_GtkGrid_(grid), Xen_to_C_gint(position)); return(Xen_false); } static Xen gxg_gtk_grid_set_row_baseline_position(Xen grid, Xen row, Xen pos) { #define H_gtk_grid_set_row_baseline_position "void gtk_grid_set_row_baseline_position(GtkGrid* grid, \ gint row, GtkBaselinePosition pos)" Xen_check_type(Xen_is_GtkGrid_(grid), grid, 1, "gtk_grid_set_row_baseline_position", "GtkGrid*"); Xen_check_type(Xen_is_gint(row), row, 2, "gtk_grid_set_row_baseline_position", "gint"); Xen_check_type(Xen_is_GtkBaselinePosition(pos), pos, 3, "gtk_grid_set_row_baseline_position", "GtkBaselinePosition"); gtk_grid_set_row_baseline_position(Xen_to_C_GtkGrid_(grid), Xen_to_C_gint(row), Xen_to_C_GtkBaselinePosition(pos)); return(Xen_false); } static Xen gxg_gtk_grid_get_row_baseline_position(Xen grid, Xen row) { #define H_gtk_grid_get_row_baseline_position "GtkBaselinePosition gtk_grid_get_row_baseline_position(GtkGrid* grid, \ gint row)" Xen_check_type(Xen_is_GtkGrid_(grid), grid, 1, "gtk_grid_get_row_baseline_position", "GtkGrid*"); Xen_check_type(Xen_is_gint(row), row, 2, "gtk_grid_get_row_baseline_position", "gint"); return(C_to_Xen_GtkBaselinePosition(gtk_grid_get_row_baseline_position(Xen_to_C_GtkGrid_(grid), Xen_to_C_gint(row)))); } static Xen gxg_gtk_grid_set_baseline_row(Xen grid, Xen row) { #define H_gtk_grid_set_baseline_row "void gtk_grid_set_baseline_row(GtkGrid* grid, gint row)" Xen_check_type(Xen_is_GtkGrid_(grid), grid, 1, "gtk_grid_set_baseline_row", "GtkGrid*"); Xen_check_type(Xen_is_gint(row), row, 2, "gtk_grid_set_baseline_row", "gint"); gtk_grid_set_baseline_row(Xen_to_C_GtkGrid_(grid), Xen_to_C_gint(row)); return(Xen_false); } static Xen gxg_gtk_grid_get_baseline_row(Xen grid) { #define H_gtk_grid_get_baseline_row "gint gtk_grid_get_baseline_row(GtkGrid* grid)" Xen_check_type(Xen_is_GtkGrid_(grid), grid, 1, "gtk_grid_get_baseline_row", "GtkGrid*"); return(C_to_Xen_gint(gtk_grid_get_baseline_row(Xen_to_C_GtkGrid_(grid)))); } static Xen gxg_gtk_widget_size_allocate_with_baseline(Xen widget, Xen allocation, Xen baseline) { #define H_gtk_widget_size_allocate_with_baseline "void gtk_widget_size_allocate_with_baseline(GtkWidget* widget, \ GtkAllocation* allocation, gint baseline)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_size_allocate_with_baseline", "GtkWidget*"); Xen_check_type(Xen_is_GtkAllocation_(allocation), allocation, 2, "gtk_widget_size_allocate_with_baseline", "GtkAllocation*"); Xen_check_type(Xen_is_gint(baseline), baseline, 3, "gtk_widget_size_allocate_with_baseline", "gint"); gtk_widget_size_allocate_with_baseline(Xen_to_C_GtkWidget_(widget), Xen_to_C_GtkAllocation_(allocation), Xen_to_C_gint(baseline)); return(Xen_false); } static Xen gxg_gtk_widget_get_preferred_height_and_baseline_for_width(Xen widget, Xen width, Xen ignore_minimum_height, Xen ignore_natural_height, Xen ignore_minimum_baseline, Xen ignore_natural_baseline) { #define H_gtk_widget_get_preferred_height_and_baseline_for_width "void gtk_widget_get_preferred_height_and_baseline_for_width(GtkWidget* widget, \ gint width, gint* [minimum_height], gint* [natural_height], gint* [minimum_baseline], gint* [natural_baseline])" gint ref_minimum_height; gint ref_natural_height; gint ref_minimum_baseline; gint ref_natural_baseline; Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_preferred_height_and_baseline_for_width", "GtkWidget*"); Xen_check_type(Xen_is_gint(width), width, 2, "gtk_widget_get_preferred_height_and_baseline_for_width", "gint"); gtk_widget_get_preferred_height_and_baseline_for_width(Xen_to_C_GtkWidget_(widget), Xen_to_C_gint(width), &ref_minimum_height, &ref_natural_height, &ref_minimum_baseline, &ref_natural_baseline); return(Xen_list_4(C_to_Xen_gint(ref_minimum_height), C_to_Xen_gint(ref_natural_height), C_to_Xen_gint(ref_minimum_baseline), C_to_Xen_gint(ref_natural_baseline))); } static Xen gxg_gtk_widget_get_allocated_baseline(Xen widget) { #define H_gtk_widget_get_allocated_baseline "int gtk_widget_get_allocated_baseline(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_allocated_baseline", "GtkWidget*"); return(C_to_Xen_int(gtk_widget_get_allocated_baseline(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_get_valign_with_baseline(Xen widget) { #define H_gtk_widget_get_valign_with_baseline "GtkAlign gtk_widget_get_valign_with_baseline(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_valign_with_baseline", "GtkWidget*"); return(C_to_Xen_GtkAlign(gtk_widget_get_valign_with_baseline(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_init_template(Xen widget) { #define H_gtk_widget_init_template "void gtk_widget_init_template(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_init_template", "GtkWidget*"); gtk_widget_init_template(Xen_to_C_GtkWidget_(widget)); return(Xen_false); } static Xen gxg_gtk_window_set_titlebar(Xen window, Xen titlebar) { #define H_gtk_window_set_titlebar "void gtk_window_set_titlebar(GtkWindow* window, GtkWidget* titlebar)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_set_titlebar", "GtkWindow*"); Xen_check_type(Xen_is_GtkWidget_(titlebar), titlebar, 2, "gtk_window_set_titlebar", "GtkWidget*"); gtk_window_set_titlebar(Xen_to_C_GtkWindow_(window), Xen_to_C_GtkWidget_(titlebar)); return(Xen_false); } static Xen gxg_gtk_places_sidebar_new(void) { #define H_gtk_places_sidebar_new "GtkWidget* gtk_places_sidebar_new( void)" return(C_to_Xen_GtkWidget_(gtk_places_sidebar_new())); } static Xen gxg_gtk_places_sidebar_get_open_flags(Xen sidebar) { #define H_gtk_places_sidebar_get_open_flags "GtkPlacesOpenFlags gtk_places_sidebar_get_open_flags(GtkPlacesSidebar* sidebar)" Xen_check_type(Xen_is_GtkPlacesSidebar_(sidebar), sidebar, 1, "gtk_places_sidebar_get_open_flags", "GtkPlacesSidebar*"); return(C_to_Xen_GtkPlacesOpenFlags(gtk_places_sidebar_get_open_flags(Xen_to_C_GtkPlacesSidebar_(sidebar)))); } static Xen gxg_gtk_places_sidebar_set_open_flags(Xen sidebar, Xen flags) { #define H_gtk_places_sidebar_set_open_flags "void gtk_places_sidebar_set_open_flags(GtkPlacesSidebar* sidebar, \ GtkPlacesOpenFlags flags)" Xen_check_type(Xen_is_GtkPlacesSidebar_(sidebar), sidebar, 1, "gtk_places_sidebar_set_open_flags", "GtkPlacesSidebar*"); Xen_check_type(Xen_is_GtkPlacesOpenFlags(flags), flags, 2, "gtk_places_sidebar_set_open_flags", "GtkPlacesOpenFlags"); gtk_places_sidebar_set_open_flags(Xen_to_C_GtkPlacesSidebar_(sidebar), Xen_to_C_GtkPlacesOpenFlags(flags)); return(Xen_false); } static Xen gxg_gtk_places_sidebar_get_location(Xen sidebar) { #define H_gtk_places_sidebar_get_location "GFile* gtk_places_sidebar_get_location(GtkPlacesSidebar* sidebar)" Xen_check_type(Xen_is_GtkPlacesSidebar_(sidebar), sidebar, 1, "gtk_places_sidebar_get_location", "GtkPlacesSidebar*"); return(C_to_Xen_GFile_(gtk_places_sidebar_get_location(Xen_to_C_GtkPlacesSidebar_(sidebar)))); } static Xen gxg_gtk_places_sidebar_set_location(Xen sidebar, Xen location) { #define H_gtk_places_sidebar_set_location "void gtk_places_sidebar_set_location(GtkPlacesSidebar* sidebar, \ GFile* location)" Xen_check_type(Xen_is_GtkPlacesSidebar_(sidebar), sidebar, 1, "gtk_places_sidebar_set_location", "GtkPlacesSidebar*"); Xen_check_type(Xen_is_GFile_(location), location, 2, "gtk_places_sidebar_set_location", "GFile*"); gtk_places_sidebar_set_location(Xen_to_C_GtkPlacesSidebar_(sidebar), Xen_to_C_GFile_(location)); return(Xen_false); } static Xen gxg_gtk_places_sidebar_get_show_desktop(Xen sidebar) { #define H_gtk_places_sidebar_get_show_desktop "gboolean gtk_places_sidebar_get_show_desktop(GtkPlacesSidebar* sidebar)" Xen_check_type(Xen_is_GtkPlacesSidebar_(sidebar), sidebar, 1, "gtk_places_sidebar_get_show_desktop", "GtkPlacesSidebar*"); return(C_to_Xen_gboolean(gtk_places_sidebar_get_show_desktop(Xen_to_C_GtkPlacesSidebar_(sidebar)))); } static Xen gxg_gtk_places_sidebar_set_show_desktop(Xen sidebar, Xen show_desktop) { #define H_gtk_places_sidebar_set_show_desktop "void gtk_places_sidebar_set_show_desktop(GtkPlacesSidebar* sidebar, \ gboolean show_desktop)" Xen_check_type(Xen_is_GtkPlacesSidebar_(sidebar), sidebar, 1, "gtk_places_sidebar_set_show_desktop", "GtkPlacesSidebar*"); Xen_check_type(Xen_is_gboolean(show_desktop), show_desktop, 2, "gtk_places_sidebar_set_show_desktop", "gboolean"); gtk_places_sidebar_set_show_desktop(Xen_to_C_GtkPlacesSidebar_(sidebar), Xen_to_C_gboolean(show_desktop)); return(Xen_false); } static Xen gxg_gtk_places_sidebar_add_shortcut(Xen sidebar, Xen location) { #define H_gtk_places_sidebar_add_shortcut "void gtk_places_sidebar_add_shortcut(GtkPlacesSidebar* sidebar, \ GFile* location)" Xen_check_type(Xen_is_GtkPlacesSidebar_(sidebar), sidebar, 1, "gtk_places_sidebar_add_shortcut", "GtkPlacesSidebar*"); Xen_check_type(Xen_is_GFile_(location), location, 2, "gtk_places_sidebar_add_shortcut", "GFile*"); gtk_places_sidebar_add_shortcut(Xen_to_C_GtkPlacesSidebar_(sidebar), Xen_to_C_GFile_(location)); return(Xen_false); } static Xen gxg_gtk_places_sidebar_remove_shortcut(Xen sidebar, Xen location) { #define H_gtk_places_sidebar_remove_shortcut "void gtk_places_sidebar_remove_shortcut(GtkPlacesSidebar* sidebar, \ GFile* location)" Xen_check_type(Xen_is_GtkPlacesSidebar_(sidebar), sidebar, 1, "gtk_places_sidebar_remove_shortcut", "GtkPlacesSidebar*"); Xen_check_type(Xen_is_GFile_(location), location, 2, "gtk_places_sidebar_remove_shortcut", "GFile*"); gtk_places_sidebar_remove_shortcut(Xen_to_C_GtkPlacesSidebar_(sidebar), Xen_to_C_GFile_(location)); return(Xen_false); } static Xen gxg_gtk_places_sidebar_list_shortcuts(Xen sidebar) { #define H_gtk_places_sidebar_list_shortcuts "GSList* gtk_places_sidebar_list_shortcuts(GtkPlacesSidebar* sidebar)" Xen_check_type(Xen_is_GtkPlacesSidebar_(sidebar), sidebar, 1, "gtk_places_sidebar_list_shortcuts", "GtkPlacesSidebar*"); return(C_to_Xen_GSList_(gtk_places_sidebar_list_shortcuts(Xen_to_C_GtkPlacesSidebar_(sidebar)))); } static Xen gxg_gtk_places_sidebar_get_nth_bookmark(Xen sidebar, Xen n) { #define H_gtk_places_sidebar_get_nth_bookmark "GFile* gtk_places_sidebar_get_nth_bookmark(GtkPlacesSidebar* sidebar, \ gint n)" Xen_check_type(Xen_is_GtkPlacesSidebar_(sidebar), sidebar, 1, "gtk_places_sidebar_get_nth_bookmark", "GtkPlacesSidebar*"); Xen_check_type(Xen_is_gint(n), n, 2, "gtk_places_sidebar_get_nth_bookmark", "gint"); return(C_to_Xen_GFile_(gtk_places_sidebar_get_nth_bookmark(Xen_to_C_GtkPlacesSidebar_(sidebar), Xen_to_C_gint(n)))); } static Xen gxg_gtk_stack_switcher_new(void) { #define H_gtk_stack_switcher_new "GtkWidget* gtk_stack_switcher_new( void)" return(C_to_Xen_GtkWidget_(gtk_stack_switcher_new())); } static Xen gxg_gtk_stack_switcher_set_stack(Xen switcher, Xen stack) { #define H_gtk_stack_switcher_set_stack "void gtk_stack_switcher_set_stack(GtkStackSwitcher* switcher, \ GtkStack* stack)" Xen_check_type(Xen_is_GtkStackSwitcher_(switcher), switcher, 1, "gtk_stack_switcher_set_stack", "GtkStackSwitcher*"); Xen_check_type(Xen_is_GtkStack_(stack), stack, 2, "gtk_stack_switcher_set_stack", "GtkStack*"); gtk_stack_switcher_set_stack(Xen_to_C_GtkStackSwitcher_(switcher), Xen_to_C_GtkStack_(stack)); return(Xen_false); } static Xen gxg_gtk_stack_switcher_get_stack(Xen switcher) { #define H_gtk_stack_switcher_get_stack "GtkStack* gtk_stack_switcher_get_stack(GtkStackSwitcher* switcher)" Xen_check_type(Xen_is_GtkStackSwitcher_(switcher), switcher, 1, "gtk_stack_switcher_get_stack", "GtkStackSwitcher*"); return(C_to_Xen_GtkStack_(gtk_stack_switcher_get_stack(Xen_to_C_GtkStackSwitcher_(switcher)))); } static Xen gxg_gtk_stack_new(void) { #define H_gtk_stack_new "GtkWidget* gtk_stack_new( void)" return(C_to_Xen_GtkWidget_(gtk_stack_new())); } static Xen gxg_gtk_stack_add_named(Xen stack, Xen child, Xen name) { #define H_gtk_stack_add_named "void gtk_stack_add_named(GtkStack* stack, GtkWidget* child, gchar* name)" Xen_check_type(Xen_is_GtkStack_(stack), stack, 1, "gtk_stack_add_named", "GtkStack*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_stack_add_named", "GtkWidget*"); Xen_check_type(Xen_is_gchar_(name), name, 3, "gtk_stack_add_named", "gchar*"); gtk_stack_add_named(Xen_to_C_GtkStack_(stack), Xen_to_C_GtkWidget_(child), (const gchar*)Xen_to_C_gchar_(name)); return(Xen_false); } static Xen gxg_gtk_stack_add_titled(Xen stack, Xen child, Xen name, Xen title) { #define H_gtk_stack_add_titled "void gtk_stack_add_titled(GtkStack* stack, GtkWidget* child, gchar* name, \ gchar* title)" Xen_check_type(Xen_is_GtkStack_(stack), stack, 1, "gtk_stack_add_titled", "GtkStack*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_stack_add_titled", "GtkWidget*"); Xen_check_type(Xen_is_gchar_(name), name, 3, "gtk_stack_add_titled", "gchar*"); Xen_check_type(Xen_is_gchar_(title), title, 4, "gtk_stack_add_titled", "gchar*"); gtk_stack_add_titled(Xen_to_C_GtkStack_(stack), Xen_to_C_GtkWidget_(child), (const gchar*)Xen_to_C_gchar_(name), (const gchar*)Xen_to_C_gchar_(title)); return(Xen_false); } static Xen gxg_gtk_stack_set_visible_child(Xen stack, Xen child) { #define H_gtk_stack_set_visible_child "void gtk_stack_set_visible_child(GtkStack* stack, GtkWidget* child)" Xen_check_type(Xen_is_GtkStack_(stack), stack, 1, "gtk_stack_set_visible_child", "GtkStack*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_stack_set_visible_child", "GtkWidget*"); gtk_stack_set_visible_child(Xen_to_C_GtkStack_(stack), Xen_to_C_GtkWidget_(child)); return(Xen_false); } static Xen gxg_gtk_stack_get_visible_child(Xen stack) { #define H_gtk_stack_get_visible_child "GtkWidget* gtk_stack_get_visible_child(GtkStack* stack)" Xen_check_type(Xen_is_GtkStack_(stack), stack, 1, "gtk_stack_get_visible_child", "GtkStack*"); return(C_to_Xen_GtkWidget_(gtk_stack_get_visible_child(Xen_to_C_GtkStack_(stack)))); } static Xen gxg_gtk_stack_set_visible_child_name(Xen stack, Xen name) { #define H_gtk_stack_set_visible_child_name "void gtk_stack_set_visible_child_name(GtkStack* stack, \ gchar* name)" Xen_check_type(Xen_is_GtkStack_(stack), stack, 1, "gtk_stack_set_visible_child_name", "GtkStack*"); Xen_check_type(Xen_is_gchar_(name), name, 2, "gtk_stack_set_visible_child_name", "gchar*"); gtk_stack_set_visible_child_name(Xen_to_C_GtkStack_(stack), (const gchar*)Xen_to_C_gchar_(name)); return(Xen_false); } static Xen gxg_gtk_stack_get_visible_child_name(Xen stack) { #define H_gtk_stack_get_visible_child_name "gchar* gtk_stack_get_visible_child_name(GtkStack* stack)" Xen_check_type(Xen_is_GtkStack_(stack), stack, 1, "gtk_stack_get_visible_child_name", "GtkStack*"); return(C_to_Xen_gchar_(gtk_stack_get_visible_child_name(Xen_to_C_GtkStack_(stack)))); } static Xen gxg_gtk_stack_set_visible_child_full(Xen stack, Xen name, Xen transition) { #define H_gtk_stack_set_visible_child_full "void gtk_stack_set_visible_child_full(GtkStack* stack, \ gchar* name, GtkStackTransitionType transition)" Xen_check_type(Xen_is_GtkStack_(stack), stack, 1, "gtk_stack_set_visible_child_full", "GtkStack*"); Xen_check_type(Xen_is_gchar_(name), name, 2, "gtk_stack_set_visible_child_full", "gchar*"); Xen_check_type(Xen_is_GtkStackTransitionType(transition), transition, 3, "gtk_stack_set_visible_child_full", "GtkStackTransitionType"); gtk_stack_set_visible_child_full(Xen_to_C_GtkStack_(stack), (const gchar*)Xen_to_C_gchar_(name), Xen_to_C_GtkStackTransitionType(transition)); return(Xen_false); } static Xen gxg_gtk_stack_set_homogeneous(Xen stack, Xen homogeneous) { #define H_gtk_stack_set_homogeneous "void gtk_stack_set_homogeneous(GtkStack* stack, gboolean homogeneous)" Xen_check_type(Xen_is_GtkStack_(stack), stack, 1, "gtk_stack_set_homogeneous", "GtkStack*"); Xen_check_type(Xen_is_gboolean(homogeneous), homogeneous, 2, "gtk_stack_set_homogeneous", "gboolean"); gtk_stack_set_homogeneous(Xen_to_C_GtkStack_(stack), Xen_to_C_gboolean(homogeneous)); return(Xen_false); } static Xen gxg_gtk_stack_get_homogeneous(Xen stack) { #define H_gtk_stack_get_homogeneous "gboolean gtk_stack_get_homogeneous(GtkStack* stack)" Xen_check_type(Xen_is_GtkStack_(stack), stack, 1, "gtk_stack_get_homogeneous", "GtkStack*"); return(C_to_Xen_gboolean(gtk_stack_get_homogeneous(Xen_to_C_GtkStack_(stack)))); } static Xen gxg_gtk_stack_set_transition_duration(Xen stack, Xen duration) { #define H_gtk_stack_set_transition_duration "void gtk_stack_set_transition_duration(GtkStack* stack, \ guint duration)" Xen_check_type(Xen_is_GtkStack_(stack), stack, 1, "gtk_stack_set_transition_duration", "GtkStack*"); Xen_check_type(Xen_is_guint(duration), duration, 2, "gtk_stack_set_transition_duration", "guint"); gtk_stack_set_transition_duration(Xen_to_C_GtkStack_(stack), Xen_to_C_guint(duration)); return(Xen_false); } static Xen gxg_gtk_stack_get_transition_duration(Xen stack) { #define H_gtk_stack_get_transition_duration "guint gtk_stack_get_transition_duration(GtkStack* stack)" Xen_check_type(Xen_is_GtkStack_(stack), stack, 1, "gtk_stack_get_transition_duration", "GtkStack*"); return(C_to_Xen_guint(gtk_stack_get_transition_duration(Xen_to_C_GtkStack_(stack)))); } static Xen gxg_gtk_stack_set_transition_type(Xen stack, Xen transition) { #define H_gtk_stack_set_transition_type "void gtk_stack_set_transition_type(GtkStack* stack, GtkStackTransitionType transition)" Xen_check_type(Xen_is_GtkStack_(stack), stack, 1, "gtk_stack_set_transition_type", "GtkStack*"); Xen_check_type(Xen_is_GtkStackTransitionType(transition), transition, 2, "gtk_stack_set_transition_type", "GtkStackTransitionType"); gtk_stack_set_transition_type(Xen_to_C_GtkStack_(stack), Xen_to_C_GtkStackTransitionType(transition)); return(Xen_false); } static Xen gxg_gtk_stack_get_transition_type(Xen stack) { #define H_gtk_stack_get_transition_type "GtkStackTransitionType gtk_stack_get_transition_type(GtkStack* stack)" Xen_check_type(Xen_is_GtkStack_(stack), stack, 1, "gtk_stack_get_transition_type", "GtkStack*"); return(C_to_Xen_GtkStackTransitionType(gtk_stack_get_transition_type(Xen_to_C_GtkStack_(stack)))); } static Xen gxg_gtk_revealer_new(void) { #define H_gtk_revealer_new "GtkWidget* gtk_revealer_new( void)" return(C_to_Xen_GtkWidget_(gtk_revealer_new())); } static Xen gxg_gtk_revealer_get_reveal_child(Xen revealer) { #define H_gtk_revealer_get_reveal_child "gboolean gtk_revealer_get_reveal_child(GtkRevealer* revealer)" Xen_check_type(Xen_is_GtkRevealer_(revealer), revealer, 1, "gtk_revealer_get_reveal_child", "GtkRevealer*"); return(C_to_Xen_gboolean(gtk_revealer_get_reveal_child(Xen_to_C_GtkRevealer_(revealer)))); } static Xen gxg_gtk_revealer_set_reveal_child(Xen revealer, Xen reveal_child) { #define H_gtk_revealer_set_reveal_child "void gtk_revealer_set_reveal_child(GtkRevealer* revealer, \ gboolean reveal_child)" Xen_check_type(Xen_is_GtkRevealer_(revealer), revealer, 1, "gtk_revealer_set_reveal_child", "GtkRevealer*"); Xen_check_type(Xen_is_gboolean(reveal_child), reveal_child, 2, "gtk_revealer_set_reveal_child", "gboolean"); gtk_revealer_set_reveal_child(Xen_to_C_GtkRevealer_(revealer), Xen_to_C_gboolean(reveal_child)); return(Xen_false); } static Xen gxg_gtk_revealer_get_child_revealed(Xen revealer) { #define H_gtk_revealer_get_child_revealed "gboolean gtk_revealer_get_child_revealed(GtkRevealer* revealer)" Xen_check_type(Xen_is_GtkRevealer_(revealer), revealer, 1, "gtk_revealer_get_child_revealed", "GtkRevealer*"); return(C_to_Xen_gboolean(gtk_revealer_get_child_revealed(Xen_to_C_GtkRevealer_(revealer)))); } static Xen gxg_gtk_revealer_get_transition_duration(Xen revealer) { #define H_gtk_revealer_get_transition_duration "guint gtk_revealer_get_transition_duration(GtkRevealer* revealer)" Xen_check_type(Xen_is_GtkRevealer_(revealer), revealer, 1, "gtk_revealer_get_transition_duration", "GtkRevealer*"); return(C_to_Xen_guint(gtk_revealer_get_transition_duration(Xen_to_C_GtkRevealer_(revealer)))); } static Xen gxg_gtk_revealer_set_transition_duration(Xen revealer, Xen duration) { #define H_gtk_revealer_set_transition_duration "void gtk_revealer_set_transition_duration(GtkRevealer* revealer, \ guint duration)" Xen_check_type(Xen_is_GtkRevealer_(revealer), revealer, 1, "gtk_revealer_set_transition_duration", "GtkRevealer*"); Xen_check_type(Xen_is_guint(duration), duration, 2, "gtk_revealer_set_transition_duration", "guint"); gtk_revealer_set_transition_duration(Xen_to_C_GtkRevealer_(revealer), Xen_to_C_guint(duration)); return(Xen_false); } static Xen gxg_gtk_revealer_set_transition_type(Xen revealer, Xen transition) { #define H_gtk_revealer_set_transition_type "void gtk_revealer_set_transition_type(GtkRevealer* revealer, \ GtkRevealerTransitionType transition)" Xen_check_type(Xen_is_GtkRevealer_(revealer), revealer, 1, "gtk_revealer_set_transition_type", "GtkRevealer*"); Xen_check_type(Xen_is_GtkRevealerTransitionType(transition), transition, 2, "gtk_revealer_set_transition_type", "GtkRevealerTransitionType"); gtk_revealer_set_transition_type(Xen_to_C_GtkRevealer_(revealer), Xen_to_C_GtkRevealerTransitionType(transition)); return(Xen_false); } static Xen gxg_gtk_revealer_get_transition_type(Xen revealer) { #define H_gtk_revealer_get_transition_type "GtkRevealerTransitionType gtk_revealer_get_transition_type(GtkRevealer* revealer)" Xen_check_type(Xen_is_GtkRevealer_(revealer), revealer, 1, "gtk_revealer_get_transition_type", "GtkRevealer*"); return(C_to_Xen_GtkRevealerTransitionType(gtk_revealer_get_transition_type(Xen_to_C_GtkRevealer_(revealer)))); } static Xen gxg_gtk_header_bar_new(void) { #define H_gtk_header_bar_new "GtkWidget* gtk_header_bar_new( void)" return(C_to_Xen_GtkWidget_(gtk_header_bar_new())); } static Xen gxg_gtk_header_bar_set_title(Xen bar, Xen title) { #define H_gtk_header_bar_set_title "void gtk_header_bar_set_title(GtkHeaderBar* bar, gchar* title)" Xen_check_type(Xen_is_GtkHeaderBar_(bar), bar, 1, "gtk_header_bar_set_title", "GtkHeaderBar*"); Xen_check_type(Xen_is_gchar_(title), title, 2, "gtk_header_bar_set_title", "gchar*"); gtk_header_bar_set_title(Xen_to_C_GtkHeaderBar_(bar), (const gchar*)Xen_to_C_gchar_(title)); return(Xen_false); } static Xen gxg_gtk_header_bar_get_title(Xen bar) { #define H_gtk_header_bar_get_title "gchar* gtk_header_bar_get_title(GtkHeaderBar* bar)" Xen_check_type(Xen_is_GtkHeaderBar_(bar), bar, 1, "gtk_header_bar_get_title", "GtkHeaderBar*"); return(C_to_Xen_gchar_(gtk_header_bar_get_title(Xen_to_C_GtkHeaderBar_(bar)))); } static Xen gxg_gtk_header_bar_set_subtitle(Xen bar, Xen subtitle) { #define H_gtk_header_bar_set_subtitle "void gtk_header_bar_set_subtitle(GtkHeaderBar* bar, gchar* subtitle)" Xen_check_type(Xen_is_GtkHeaderBar_(bar), bar, 1, "gtk_header_bar_set_subtitle", "GtkHeaderBar*"); Xen_check_type(Xen_is_gchar_(subtitle), subtitle, 2, "gtk_header_bar_set_subtitle", "gchar*"); gtk_header_bar_set_subtitle(Xen_to_C_GtkHeaderBar_(bar), (const gchar*)Xen_to_C_gchar_(subtitle)); return(Xen_false); } static Xen gxg_gtk_header_bar_get_subtitle(Xen bar) { #define H_gtk_header_bar_get_subtitle "gchar* gtk_header_bar_get_subtitle(GtkHeaderBar* bar)" Xen_check_type(Xen_is_GtkHeaderBar_(bar), bar, 1, "gtk_header_bar_get_subtitle", "GtkHeaderBar*"); return(C_to_Xen_gchar_(gtk_header_bar_get_subtitle(Xen_to_C_GtkHeaderBar_(bar)))); } static Xen gxg_gtk_header_bar_set_custom_title(Xen bar, Xen title_widget) { #define H_gtk_header_bar_set_custom_title "void gtk_header_bar_set_custom_title(GtkHeaderBar* bar, \ GtkWidget* title_widget)" Xen_check_type(Xen_is_GtkHeaderBar_(bar), bar, 1, "gtk_header_bar_set_custom_title", "GtkHeaderBar*"); Xen_check_type(Xen_is_GtkWidget_(title_widget), title_widget, 2, "gtk_header_bar_set_custom_title", "GtkWidget*"); gtk_header_bar_set_custom_title(Xen_to_C_GtkHeaderBar_(bar), Xen_to_C_GtkWidget_(title_widget)); return(Xen_false); } static Xen gxg_gtk_header_bar_get_custom_title(Xen bar) { #define H_gtk_header_bar_get_custom_title "GtkWidget* gtk_header_bar_get_custom_title(GtkHeaderBar* bar)" Xen_check_type(Xen_is_GtkHeaderBar_(bar), bar, 1, "gtk_header_bar_get_custom_title", "GtkHeaderBar*"); return(C_to_Xen_GtkWidget_(gtk_header_bar_get_custom_title(Xen_to_C_GtkHeaderBar_(bar)))); } static Xen gxg_gtk_header_bar_pack_start(Xen bar, Xen child) { #define H_gtk_header_bar_pack_start "void gtk_header_bar_pack_start(GtkHeaderBar* bar, GtkWidget* child)" Xen_check_type(Xen_is_GtkHeaderBar_(bar), bar, 1, "gtk_header_bar_pack_start", "GtkHeaderBar*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_header_bar_pack_start", "GtkWidget*"); gtk_header_bar_pack_start(Xen_to_C_GtkHeaderBar_(bar), Xen_to_C_GtkWidget_(child)); return(Xen_false); } static Xen gxg_gtk_header_bar_pack_end(Xen bar, Xen child) { #define H_gtk_header_bar_pack_end "void gtk_header_bar_pack_end(GtkHeaderBar* bar, GtkWidget* child)" Xen_check_type(Xen_is_GtkHeaderBar_(bar), bar, 1, "gtk_header_bar_pack_end", "GtkHeaderBar*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_header_bar_pack_end", "GtkWidget*"); gtk_header_bar_pack_end(Xen_to_C_GtkHeaderBar_(bar), Xen_to_C_GtkWidget_(child)); return(Xen_false); } static Xen gxg_gtk_list_box_row_new(void) { #define H_gtk_list_box_row_new "GtkWidget* gtk_list_box_row_new( void)" return(C_to_Xen_GtkWidget_(gtk_list_box_row_new())); } static Xen gxg_gtk_list_box_row_get_header(Xen row) { #define H_gtk_list_box_row_get_header "GtkWidget* gtk_list_box_row_get_header(GtkListBoxRow* row)" Xen_check_type(Xen_is_GtkListBoxRow_(row), row, 1, "gtk_list_box_row_get_header", "GtkListBoxRow*"); return(C_to_Xen_GtkWidget_(gtk_list_box_row_get_header(Xen_to_C_GtkListBoxRow_(row)))); } static Xen gxg_gtk_list_box_row_set_header(Xen row, Xen header) { #define H_gtk_list_box_row_set_header "void gtk_list_box_row_set_header(GtkListBoxRow* row, GtkWidget* header)" Xen_check_type(Xen_is_GtkListBoxRow_(row), row, 1, "gtk_list_box_row_set_header", "GtkListBoxRow*"); Xen_check_type(Xen_is_GtkWidget_(header), header, 2, "gtk_list_box_row_set_header", "GtkWidget*"); gtk_list_box_row_set_header(Xen_to_C_GtkListBoxRow_(row), Xen_to_C_GtkWidget_(header)); return(Xen_false); } static Xen gxg_gtk_list_box_row_changed(Xen row) { #define H_gtk_list_box_row_changed "void gtk_list_box_row_changed(GtkListBoxRow* row)" Xen_check_type(Xen_is_GtkListBoxRow_(row), row, 1, "gtk_list_box_row_changed", "GtkListBoxRow*"); gtk_list_box_row_changed(Xen_to_C_GtkListBoxRow_(row)); return(Xen_false); } static Xen gxg_gtk_list_box_get_selected_row(Xen list_box) { #define H_gtk_list_box_get_selected_row "GtkListBoxRow* gtk_list_box_get_selected_row(GtkListBox* list_box)" Xen_check_type(Xen_is_GtkListBox_(list_box), list_box, 1, "gtk_list_box_get_selected_row", "GtkListBox*"); return(C_to_Xen_GtkListBoxRow_(gtk_list_box_get_selected_row(Xen_to_C_GtkListBox_(list_box)))); } static Xen gxg_gtk_list_box_get_row_at_index(Xen list_box, Xen index_) { #define H_gtk_list_box_get_row_at_index "GtkListBoxRow* gtk_list_box_get_row_at_index(GtkListBox* list_box, \ gint index_)" Xen_check_type(Xen_is_GtkListBox_(list_box), list_box, 1, "gtk_list_box_get_row_at_index", "GtkListBox*"); Xen_check_type(Xen_is_gint(index_), index_, 2, "gtk_list_box_get_row_at_index", "gint"); return(C_to_Xen_GtkListBoxRow_(gtk_list_box_get_row_at_index(Xen_to_C_GtkListBox_(list_box), Xen_to_C_gint(index_)))); } static Xen gxg_gtk_list_box_get_row_at_y(Xen list_box, Xen y) { #define H_gtk_list_box_get_row_at_y "GtkListBoxRow* gtk_list_box_get_row_at_y(GtkListBox* list_box, \ gint y)" Xen_check_type(Xen_is_GtkListBox_(list_box), list_box, 1, "gtk_list_box_get_row_at_y", "GtkListBox*"); Xen_check_type(Xen_is_gint(y), y, 2, "gtk_list_box_get_row_at_y", "gint"); return(C_to_Xen_GtkListBoxRow_(gtk_list_box_get_row_at_y(Xen_to_C_GtkListBox_(list_box), Xen_to_C_gint(y)))); } static Xen gxg_gtk_list_box_select_row(Xen list_box, Xen row) { #define H_gtk_list_box_select_row "void gtk_list_box_select_row(GtkListBox* list_box, GtkListBoxRow* row)" Xen_check_type(Xen_is_GtkListBox_(list_box), list_box, 1, "gtk_list_box_select_row", "GtkListBox*"); Xen_check_type(Xen_is_GtkListBoxRow_(row), row, 2, "gtk_list_box_select_row", "GtkListBoxRow*"); gtk_list_box_select_row(Xen_to_C_GtkListBox_(list_box), Xen_to_C_GtkListBoxRow_(row)); return(Xen_false); } static Xen gxg_gtk_list_box_set_placeholder(Xen list_box, Xen placeholder) { #define H_gtk_list_box_set_placeholder "void gtk_list_box_set_placeholder(GtkListBox* list_box, GtkWidget* placeholder)" Xen_check_type(Xen_is_GtkListBox_(list_box), list_box, 1, "gtk_list_box_set_placeholder", "GtkListBox*"); Xen_check_type(Xen_is_GtkWidget_(placeholder), placeholder, 2, "gtk_list_box_set_placeholder", "GtkWidget*"); gtk_list_box_set_placeholder(Xen_to_C_GtkListBox_(list_box), Xen_to_C_GtkWidget_(placeholder)); return(Xen_false); } static Xen gxg_gtk_list_box_set_adjustment(Xen list_box, Xen adjustment) { #define H_gtk_list_box_set_adjustment "void gtk_list_box_set_adjustment(GtkListBox* list_box, GtkAdjustment* adjustment)" Xen_check_type(Xen_is_GtkListBox_(list_box), list_box, 1, "gtk_list_box_set_adjustment", "GtkListBox*"); Xen_check_type(Xen_is_GtkAdjustment_(adjustment), adjustment, 2, "gtk_list_box_set_adjustment", "GtkAdjustment*"); gtk_list_box_set_adjustment(Xen_to_C_GtkListBox_(list_box), Xen_to_C_GtkAdjustment_(adjustment)); return(Xen_false); } static Xen gxg_gtk_list_box_get_adjustment(Xen list_box) { #define H_gtk_list_box_get_adjustment "GtkAdjustment* gtk_list_box_get_adjustment(GtkListBox* list_box)" Xen_check_type(Xen_is_GtkListBox_(list_box), list_box, 1, "gtk_list_box_get_adjustment", "GtkListBox*"); return(C_to_Xen_GtkAdjustment_(gtk_list_box_get_adjustment(Xen_to_C_GtkListBox_(list_box)))); } static Xen gxg_gtk_list_box_set_selection_mode(Xen list_box, Xen mode) { #define H_gtk_list_box_set_selection_mode "void gtk_list_box_set_selection_mode(GtkListBox* list_box, \ GtkSelectionMode mode)" Xen_check_type(Xen_is_GtkListBox_(list_box), list_box, 1, "gtk_list_box_set_selection_mode", "GtkListBox*"); Xen_check_type(Xen_is_GtkSelectionMode(mode), mode, 2, "gtk_list_box_set_selection_mode", "GtkSelectionMode"); gtk_list_box_set_selection_mode(Xen_to_C_GtkListBox_(list_box), Xen_to_C_GtkSelectionMode(mode)); return(Xen_false); } static Xen gxg_gtk_list_box_get_selection_mode(Xen list_box) { #define H_gtk_list_box_get_selection_mode "GtkSelectionMode gtk_list_box_get_selection_mode(GtkListBox* list_box)" Xen_check_type(Xen_is_GtkListBox_(list_box), list_box, 1, "gtk_list_box_get_selection_mode", "GtkListBox*"); return(C_to_Xen_GtkSelectionMode(gtk_list_box_get_selection_mode(Xen_to_C_GtkListBox_(list_box)))); } static Xen gxg_gtk_list_box_invalidate_filter(Xen list_box) { #define H_gtk_list_box_invalidate_filter "void gtk_list_box_invalidate_filter(GtkListBox* list_box)" Xen_check_type(Xen_is_GtkListBox_(list_box), list_box, 1, "gtk_list_box_invalidate_filter", "GtkListBox*"); gtk_list_box_invalidate_filter(Xen_to_C_GtkListBox_(list_box)); return(Xen_false); } static Xen gxg_gtk_list_box_invalidate_sort(Xen list_box) { #define H_gtk_list_box_invalidate_sort "void gtk_list_box_invalidate_sort(GtkListBox* list_box)" Xen_check_type(Xen_is_GtkListBox_(list_box), list_box, 1, "gtk_list_box_invalidate_sort", "GtkListBox*"); gtk_list_box_invalidate_sort(Xen_to_C_GtkListBox_(list_box)); return(Xen_false); } static Xen gxg_gtk_list_box_invalidate_headers(Xen list_box) { #define H_gtk_list_box_invalidate_headers "void gtk_list_box_invalidate_headers(GtkListBox* list_box)" Xen_check_type(Xen_is_GtkListBox_(list_box), list_box, 1, "gtk_list_box_invalidate_headers", "GtkListBox*"); gtk_list_box_invalidate_headers(Xen_to_C_GtkListBox_(list_box)); return(Xen_false); } static Xen gxg_gtk_list_box_set_activate_on_single_click(Xen list_box, Xen single) { #define H_gtk_list_box_set_activate_on_single_click "void gtk_list_box_set_activate_on_single_click(GtkListBox* list_box, \ gboolean single)" Xen_check_type(Xen_is_GtkListBox_(list_box), list_box, 1, "gtk_list_box_set_activate_on_single_click", "GtkListBox*"); Xen_check_type(Xen_is_gboolean(single), single, 2, "gtk_list_box_set_activate_on_single_click", "gboolean"); gtk_list_box_set_activate_on_single_click(Xen_to_C_GtkListBox_(list_box), Xen_to_C_gboolean(single)); return(Xen_false); } static Xen gxg_gtk_list_box_get_activate_on_single_click(Xen list_box) { #define H_gtk_list_box_get_activate_on_single_click "gboolean gtk_list_box_get_activate_on_single_click(GtkListBox* list_box)" Xen_check_type(Xen_is_GtkListBox_(list_box), list_box, 1, "gtk_list_box_get_activate_on_single_click", "GtkListBox*"); return(C_to_Xen_gboolean(gtk_list_box_get_activate_on_single_click(Xen_to_C_GtkListBox_(list_box)))); } static Xen gxg_gtk_list_box_drag_unhighlight_row(Xen list_box) { #define H_gtk_list_box_drag_unhighlight_row "void gtk_list_box_drag_unhighlight_row(GtkListBox* list_box)" Xen_check_type(Xen_is_GtkListBox_(list_box), list_box, 1, "gtk_list_box_drag_unhighlight_row", "GtkListBox*"); gtk_list_box_drag_unhighlight_row(Xen_to_C_GtkListBox_(list_box)); return(Xen_false); } static Xen gxg_gtk_list_box_drag_highlight_row(Xen list_box, Xen row) { #define H_gtk_list_box_drag_highlight_row "void gtk_list_box_drag_highlight_row(GtkListBox* list_box, \ GtkListBoxRow* row)" Xen_check_type(Xen_is_GtkListBox_(list_box), list_box, 1, "gtk_list_box_drag_highlight_row", "GtkListBox*"); Xen_check_type(Xen_is_GtkListBoxRow_(row), row, 2, "gtk_list_box_drag_highlight_row", "GtkListBoxRow*"); gtk_list_box_drag_highlight_row(Xen_to_C_GtkListBox_(list_box), Xen_to_C_GtkListBoxRow_(row)); return(Xen_false); } static Xen gxg_gtk_list_box_new(void) { #define H_gtk_list_box_new "GtkWidget* gtk_list_box_new( void)" return(C_to_Xen_GtkWidget_(gtk_list_box_new())); } static Xen gxg_gtk_search_bar_new(void) { #define H_gtk_search_bar_new "GtkWidget* gtk_search_bar_new( void)" return(C_to_Xen_GtkWidget_(gtk_search_bar_new())); } static Xen gxg_gtk_search_bar_connect_entry(Xen bar, Xen entry) { #define H_gtk_search_bar_connect_entry "void gtk_search_bar_connect_entry(GtkSearchBar* bar, GtkEntry* entry)" Xen_check_type(Xen_is_GtkSearchBar_(bar), bar, 1, "gtk_search_bar_connect_entry", "GtkSearchBar*"); Xen_check_type(Xen_is_GtkEntry_(entry), entry, 2, "gtk_search_bar_connect_entry", "GtkEntry*"); gtk_search_bar_connect_entry(Xen_to_C_GtkSearchBar_(bar), Xen_to_C_GtkEntry_(entry)); return(Xen_false); } static Xen gxg_gtk_search_bar_get_search_mode(Xen bar) { #define H_gtk_search_bar_get_search_mode "gboolean gtk_search_bar_get_search_mode(GtkSearchBar* bar)" Xen_check_type(Xen_is_GtkSearchBar_(bar), bar, 1, "gtk_search_bar_get_search_mode", "GtkSearchBar*"); return(C_to_Xen_gboolean(gtk_search_bar_get_search_mode(Xen_to_C_GtkSearchBar_(bar)))); } static Xen gxg_gtk_search_bar_set_search_mode(Xen bar, Xen search_mode) { #define H_gtk_search_bar_set_search_mode "void gtk_search_bar_set_search_mode(GtkSearchBar* bar, gboolean search_mode)" Xen_check_type(Xen_is_GtkSearchBar_(bar), bar, 1, "gtk_search_bar_set_search_mode", "GtkSearchBar*"); Xen_check_type(Xen_is_gboolean(search_mode), search_mode, 2, "gtk_search_bar_set_search_mode", "gboolean"); gtk_search_bar_set_search_mode(Xen_to_C_GtkSearchBar_(bar), Xen_to_C_gboolean(search_mode)); return(Xen_false); } static Xen gxg_gtk_search_bar_get_show_close_button(Xen bar) { #define H_gtk_search_bar_get_show_close_button "gboolean gtk_search_bar_get_show_close_button(GtkSearchBar* bar)" Xen_check_type(Xen_is_GtkSearchBar_(bar), bar, 1, "gtk_search_bar_get_show_close_button", "GtkSearchBar*"); return(C_to_Xen_gboolean(gtk_search_bar_get_show_close_button(Xen_to_C_GtkSearchBar_(bar)))); } static Xen gxg_gtk_search_bar_set_show_close_button(Xen bar, Xen visible) { #define H_gtk_search_bar_set_show_close_button "void gtk_search_bar_set_show_close_button(GtkSearchBar* bar, \ gboolean visible)" Xen_check_type(Xen_is_GtkSearchBar_(bar), bar, 1, "gtk_search_bar_set_show_close_button", "GtkSearchBar*"); Xen_check_type(Xen_is_gboolean(visible), visible, 2, "gtk_search_bar_set_show_close_button", "gboolean"); gtk_search_bar_set_show_close_button(Xen_to_C_GtkSearchBar_(bar), Xen_to_C_gboolean(visible)); return(Xen_false); } static Xen gxg_gtk_search_bar_handle_event(Xen bar, Xen event) { #define H_gtk_search_bar_handle_event "gboolean gtk_search_bar_handle_event(GtkSearchBar* bar, GdkEvent* event)" Xen_check_type(Xen_is_GtkSearchBar_(bar), bar, 1, "gtk_search_bar_handle_event", "GtkSearchBar*"); Xen_check_type(Xen_is_GdkEvent_(event), event, 2, "gtk_search_bar_handle_event", "GdkEvent*"); return(C_to_Xen_gboolean(gtk_search_bar_handle_event(Xen_to_C_GtkSearchBar_(bar), Xen_to_C_GdkEvent_(event)))); } static Xen gxg_gtk_file_chooser_get_current_name(Xen chooser) { #define H_gtk_file_chooser_get_current_name "gchar* gtk_file_chooser_get_current_name(GtkFileChooser* chooser)" Xen_check_type(Xen_is_GtkFileChooser_(chooser), chooser, 1, "gtk_file_chooser_get_current_name", "GtkFileChooser*"); return(C_to_Xen_gchar_(gtk_file_chooser_get_current_name(Xen_to_C_GtkFileChooser_(chooser)))); } static Xen gxg_gdk_cairo_surface_create_from_pixbuf(Xen pixbuf, Xen scale, Xen for_window) { #define H_gdk_cairo_surface_create_from_pixbuf "cairo_surface_t* gdk_cairo_surface_create_from_pixbuf(GdkPixbuf* pixbuf, \ int scale, GdkWindow* for_window)" Xen_check_type(Xen_is_GdkPixbuf_(pixbuf), pixbuf, 1, "gdk_cairo_surface_create_from_pixbuf", "GdkPixbuf*"); Xen_check_type(Xen_is_int(scale), scale, 2, "gdk_cairo_surface_create_from_pixbuf", "int"); Xen_check_type(Xen_is_GdkWindow_(for_window), for_window, 3, "gdk_cairo_surface_create_from_pixbuf", "GdkWindow*"); return(C_to_Xen_cairo_surface_t_(gdk_cairo_surface_create_from_pixbuf(Xen_to_C_GdkPixbuf_(pixbuf), Xen_to_C_int(scale), Xen_to_C_GdkWindow_(for_window)))); } static Xen gxg_gdk_device_get_position_double(Xen device, Xen ignore_screen, Xen ignore_x, Xen ignore_y) { #define H_gdk_device_get_position_double "void gdk_device_get_position_double(GdkDevice* device, GdkScreen** [screen], \ gdouble* [x], gdouble* [y])" GdkScreen* ref_screen = NULL; gdouble ref_x; gdouble ref_y; Xen_check_type(Xen_is_GdkDevice_(device), device, 1, "gdk_device_get_position_double", "GdkDevice*"); gdk_device_get_position_double(Xen_to_C_GdkDevice_(device), &ref_screen, &ref_x, &ref_y); return(Xen_list_3(C_to_Xen_GdkScreen_(ref_screen), C_to_Xen_gdouble(ref_x), C_to_Xen_gdouble(ref_y))); } static Xen gxg_gdk_device_get_window_at_position_double(Xen device, Xen ignore_win_x, Xen ignore_win_y) { #define H_gdk_device_get_window_at_position_double "GdkWindow* gdk_device_get_window_at_position_double(GdkDevice* device, \ gdouble* [win_x], gdouble* [win_y])" gdouble ref_win_x; gdouble ref_win_y; Xen_check_type(Xen_is_GdkDevice_(device), device, 1, "gdk_device_get_window_at_position_double", "GdkDevice*"); { Xen result; result = C_to_Xen_GdkWindow_(gdk_device_get_window_at_position_double(Xen_to_C_GdkDevice_(device), &ref_win_x, &ref_win_y)); return(Xen_list_3(result, C_to_Xen_gdouble(ref_win_x), C_to_Xen_gdouble(ref_win_y))); } } static Xen gxg_gdk_screen_get_monitor_scale_factor(Xen screen, Xen monitor_num) { #define H_gdk_screen_get_monitor_scale_factor "gint gdk_screen_get_monitor_scale_factor(GdkScreen* screen, \ gint monitor_num)" Xen_check_type(Xen_is_GdkScreen_(screen), screen, 1, "gdk_screen_get_monitor_scale_factor", "GdkScreen*"); Xen_check_type(Xen_is_gint(monitor_num), monitor_num, 2, "gdk_screen_get_monitor_scale_factor", "gint"); return(C_to_Xen_gint(gdk_screen_get_monitor_scale_factor(Xen_to_C_GdkScreen_(screen), Xen_to_C_gint(monitor_num)))); } static Xen gxg_gdk_window_get_scale_factor(Xen window) { #define H_gdk_window_get_scale_factor "gint gdk_window_get_scale_factor(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_get_scale_factor", "GdkWindow*"); return(C_to_Xen_gint(gdk_window_get_scale_factor(Xen_to_C_GdkWindow_(window)))); } static Xen gxg_gdk_window_get_device_position_double(Xen window, Xen device, Xen ignore_x, Xen ignore_y, Xen ignore_mask) { #define H_gdk_window_get_device_position_double "GdkWindow* gdk_window_get_device_position_double(GdkWindow* window, \ GdkDevice* device, gdouble* [x], gdouble* [y], GdkModifierType* [mask])" gdouble ref_x; gdouble ref_y; GdkModifierType ref_mask; Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_get_device_position_double", "GdkWindow*"); Xen_check_type(Xen_is_GdkDevice_(device), device, 2, "gdk_window_get_device_position_double", "GdkDevice*"); { Xen result; result = C_to_Xen_GdkWindow_(gdk_window_get_device_position_double(Xen_to_C_GdkWindow_(window), Xen_to_C_GdkDevice_(device), &ref_x, &ref_y, &ref_mask)); return(Xen_list_4(result, C_to_Xen_gdouble(ref_x), C_to_Xen_gdouble(ref_y), C_to_Xen_GdkModifierType(ref_mask))); } } static Xen gxg_gdk_window_create_similar_image_surface(Xen window, Xen format, Xen width, Xen height, Xen scale) { #define H_gdk_window_create_similar_image_surface "cairo_surface_t* gdk_window_create_similar_image_surface(GdkWindow* window, \ cairo_format_t format, int width, int height, int scale)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_create_similar_image_surface", "GdkWindow*"); Xen_check_type(Xen_is_cairo_format_t(format), format, 2, "gdk_window_create_similar_image_surface", "cairo_format_t"); Xen_check_type(Xen_is_int(width), width, 3, "gdk_window_create_similar_image_surface", "int"); Xen_check_type(Xen_is_int(height), height, 4, "gdk_window_create_similar_image_surface", "int"); Xen_check_type(Xen_is_int(scale), scale, 5, "gdk_window_create_similar_image_surface", "int"); return(C_to_Xen_cairo_surface_t_(gdk_window_create_similar_image_surface(Xen_to_C_GdkWindow_(window), Xen_to_C_cairo_format_t(format), Xen_to_C_int(width), Xen_to_C_int(height), Xen_to_C_int(scale)))); } static Xen gxg_gtk_icon_theme_lookup_icon_for_scale(Xen icon_theme, Xen icon_name, Xen size, Xen scale, Xen flags) { #define H_gtk_icon_theme_lookup_icon_for_scale "GtkIconInfo* gtk_icon_theme_lookup_icon_for_scale(GtkIconTheme* icon_theme, \ gchar* icon_name, gint size, gint scale, GtkIconLookupFlags flags)" Xen_check_type(Xen_is_GtkIconTheme_(icon_theme), icon_theme, 1, "gtk_icon_theme_lookup_icon_for_scale", "GtkIconTheme*"); Xen_check_type(Xen_is_gchar_(icon_name), icon_name, 2, "gtk_icon_theme_lookup_icon_for_scale", "gchar*"); Xen_check_type(Xen_is_gint(size), size, 3, "gtk_icon_theme_lookup_icon_for_scale", "gint"); Xen_check_type(Xen_is_gint(scale), scale, 4, "gtk_icon_theme_lookup_icon_for_scale", "gint"); Xen_check_type(Xen_is_GtkIconLookupFlags(flags), flags, 5, "gtk_icon_theme_lookup_icon_for_scale", "GtkIconLookupFlags"); return(C_to_Xen_GtkIconInfo_(gtk_icon_theme_lookup_icon_for_scale(Xen_to_C_GtkIconTheme_(icon_theme), (const gchar*)Xen_to_C_gchar_(icon_name), Xen_to_C_gint(size), Xen_to_C_gint(scale), Xen_to_C_GtkIconLookupFlags(flags)))); } static Xen gxg_gtk_icon_theme_load_icon_for_scale(Xen icon_theme, Xen icon_name, Xen size, Xen scale, Xen flags, Xen ignore_error) { #define H_gtk_icon_theme_load_icon_for_scale "GdkPixbuf* gtk_icon_theme_load_icon_for_scale(GtkIconTheme* icon_theme, \ gchar* icon_name, gint size, gint scale, GtkIconLookupFlags flags, GError** [error])" GError* ref_error = NULL; Xen_check_type(Xen_is_GtkIconTheme_(icon_theme), icon_theme, 1, "gtk_icon_theme_load_icon_for_scale", "GtkIconTheme*"); Xen_check_type(Xen_is_gchar_(icon_name), icon_name, 2, "gtk_icon_theme_load_icon_for_scale", "gchar*"); Xen_check_type(Xen_is_gint(size), size, 3, "gtk_icon_theme_load_icon_for_scale", "gint"); Xen_check_type(Xen_is_gint(scale), scale, 4, "gtk_icon_theme_load_icon_for_scale", "gint"); Xen_check_type(Xen_is_GtkIconLookupFlags(flags), flags, 5, "gtk_icon_theme_load_icon_for_scale", "GtkIconLookupFlags"); { Xen result; result = C_to_Xen_GdkPixbuf_(gtk_icon_theme_load_icon_for_scale(Xen_to_C_GtkIconTheme_(icon_theme), (const gchar*)Xen_to_C_gchar_(icon_name), Xen_to_C_gint(size), Xen_to_C_gint(scale), Xen_to_C_GtkIconLookupFlags(flags), &ref_error)); return(Xen_list_2(result, C_to_Xen_GError_(ref_error))); } } static Xen gxg_gtk_icon_theme_load_surface(Xen icon_theme, Xen icon_name, Xen size, Xen scale, Xen for_window, Xen flags, Xen ignore_error) { #define H_gtk_icon_theme_load_surface "cairo_surface_t* gtk_icon_theme_load_surface(GtkIconTheme* icon_theme, \ gchar* icon_name, gint size, gint scale, GdkWindow* for_window, GtkIconLookupFlags flags, GError** [error])" GError* ref_error = NULL; Xen_check_type(Xen_is_GtkIconTheme_(icon_theme), icon_theme, 1, "gtk_icon_theme_load_surface", "GtkIconTheme*"); Xen_check_type(Xen_is_gchar_(icon_name), icon_name, 2, "gtk_icon_theme_load_surface", "gchar*"); Xen_check_type(Xen_is_gint(size), size, 3, "gtk_icon_theme_load_surface", "gint"); Xen_check_type(Xen_is_gint(scale), scale, 4, "gtk_icon_theme_load_surface", "gint"); Xen_check_type(Xen_is_GdkWindow_(for_window), for_window, 5, "gtk_icon_theme_load_surface", "GdkWindow*"); Xen_check_type(Xen_is_GtkIconLookupFlags(flags), flags, 6, "gtk_icon_theme_load_surface", "GtkIconLookupFlags"); { Xen result; result = C_to_Xen_cairo_surface_t_(gtk_icon_theme_load_surface(Xen_to_C_GtkIconTheme_(icon_theme), (const gchar*)Xen_to_C_gchar_(icon_name), Xen_to_C_gint(size), Xen_to_C_gint(scale), Xen_to_C_GdkWindow_(for_window), Xen_to_C_GtkIconLookupFlags(flags), &ref_error)); return(Xen_list_2(result, C_to_Xen_GError_(ref_error))); } } static Xen gxg_gtk_icon_theme_lookup_by_gicon_for_scale(Xen icon_theme, Xen icon, Xen size, Xen scale, Xen flags) { #define H_gtk_icon_theme_lookup_by_gicon_for_scale "GtkIconInfo* gtk_icon_theme_lookup_by_gicon_for_scale(GtkIconTheme* icon_theme, \ GIcon* icon, gint size, gint scale, GtkIconLookupFlags flags)" Xen_check_type(Xen_is_GtkIconTheme_(icon_theme), icon_theme, 1, "gtk_icon_theme_lookup_by_gicon_for_scale", "GtkIconTheme*"); Xen_check_type(Xen_is_GIcon_(icon), icon, 2, "gtk_icon_theme_lookup_by_gicon_for_scale", "GIcon*"); Xen_check_type(Xen_is_gint(size), size, 3, "gtk_icon_theme_lookup_by_gicon_for_scale", "gint"); Xen_check_type(Xen_is_gint(scale), scale, 4, "gtk_icon_theme_lookup_by_gicon_for_scale", "gint"); Xen_check_type(Xen_is_GtkIconLookupFlags(flags), flags, 5, "gtk_icon_theme_lookup_by_gicon_for_scale", "GtkIconLookupFlags"); return(C_to_Xen_GtkIconInfo_(gtk_icon_theme_lookup_by_gicon_for_scale(Xen_to_C_GtkIconTheme_(icon_theme), Xen_to_C_GIcon_(icon), Xen_to_C_gint(size), Xen_to_C_gint(scale), Xen_to_C_GtkIconLookupFlags(flags)))); } static Xen gxg_gtk_icon_info_get_base_scale(Xen icon_info) { #define H_gtk_icon_info_get_base_scale "gint gtk_icon_info_get_base_scale(GtkIconInfo* icon_info)" Xen_check_type(Xen_is_GtkIconInfo_(icon_info), icon_info, 1, "gtk_icon_info_get_base_scale", "GtkIconInfo*"); return(C_to_Xen_gint(gtk_icon_info_get_base_scale(Xen_to_C_GtkIconInfo_(icon_info)))); } static Xen gxg_gtk_icon_info_load_surface(Xen icon_info, Xen for_window, Xen ignore_error) { #define H_gtk_icon_info_load_surface "cairo_surface_t* gtk_icon_info_load_surface(GtkIconInfo* icon_info, \ GdkWindow* for_window, GError** [error])" GError* ref_error = NULL; Xen_check_type(Xen_is_GtkIconInfo_(icon_info), icon_info, 1, "gtk_icon_info_load_surface", "GtkIconInfo*"); Xen_check_type(Xen_is_GdkWindow_(for_window), for_window, 2, "gtk_icon_info_load_surface", "GdkWindow*"); { Xen result; result = C_to_Xen_cairo_surface_t_(gtk_icon_info_load_surface(Xen_to_C_GtkIconInfo_(icon_info), Xen_to_C_GdkWindow_(for_window), &ref_error)); return(Xen_list_2(result, C_to_Xen_GError_(ref_error))); } } static Xen gxg_gtk_image_new_from_surface(Xen surface) { #define H_gtk_image_new_from_surface "GtkWidget* gtk_image_new_from_surface(cairo_surface_t* surface)" Xen_check_type(Xen_is_cairo_surface_t_(surface), surface, 1, "gtk_image_new_from_surface", "cairo_surface_t*"); return(C_to_Xen_GtkWidget_(gtk_image_new_from_surface(Xen_to_C_cairo_surface_t_(surface)))); } static Xen gxg_gtk_image_set_from_surface(Xen image, Xen surface) { #define H_gtk_image_set_from_surface "void gtk_image_set_from_surface(GtkImage* image, cairo_surface_t* surface)" Xen_check_type(Xen_is_GtkImage_(image), image, 1, "gtk_image_set_from_surface", "GtkImage*"); Xen_check_type(Xen_is_cairo_surface_t_(surface), surface, 2, "gtk_image_set_from_surface", "cairo_surface_t*"); gtk_image_set_from_surface(Xen_to_C_GtkImage_(image), Xen_to_C_cairo_surface_t_(surface)); return(Xen_false); } static Xen gxg_gtk_list_box_row_get_index(Xen row) { #define H_gtk_list_box_row_get_index "gint gtk_list_box_row_get_index(GtkListBoxRow* row)" Xen_check_type(Xen_is_GtkListBoxRow_(row), row, 1, "gtk_list_box_row_get_index", "GtkListBoxRow*"); return(C_to_Xen_gint(gtk_list_box_row_get_index(Xen_to_C_GtkListBoxRow_(row)))); } static Xen gxg_gtk_widget_get_scale_factor(Xen widget) { #define H_gtk_widget_get_scale_factor "gint gtk_widget_get_scale_factor(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_scale_factor", "GtkWidget*"); return(C_to_Xen_gint(gtk_widget_get_scale_factor(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_window_close(Xen window) { #define H_gtk_window_close "void gtk_window_close(GtkWindow* window)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_close", "GtkWindow*"); gtk_window_close(Xen_to_C_GtkWindow_(window)); return(Xen_false); } static Xen gxg_gtk_info_bar_set_show_close_button(Xen info_bar, Xen setting) { #define H_gtk_info_bar_set_show_close_button "void gtk_info_bar_set_show_close_button(GtkInfoBar* info_bar, \ gboolean setting)" Xen_check_type(Xen_is_GtkInfoBar_(info_bar), info_bar, 1, "gtk_info_bar_set_show_close_button", "GtkInfoBar*"); Xen_check_type(Xen_is_gboolean(setting), setting, 2, "gtk_info_bar_set_show_close_button", "gboolean"); gtk_info_bar_set_show_close_button(Xen_to_C_GtkInfoBar_(info_bar), Xen_to_C_gboolean(setting)); return(Xen_false); } static Xen gxg_gtk_info_bar_get_show_close_button(Xen info_bar) { #define H_gtk_info_bar_get_show_close_button "gboolean gtk_info_bar_get_show_close_button(GtkInfoBar* info_bar)" Xen_check_type(Xen_is_GtkInfoBar_(info_bar), info_bar, 1, "gtk_info_bar_get_show_close_button", "GtkInfoBar*"); return(C_to_Xen_gboolean(gtk_info_bar_get_show_close_button(Xen_to_C_GtkInfoBar_(info_bar)))); } static Xen gxg_gtk_tree_model_rows_reordered_with_length(Xen tree_model, Xen path, Xen iter, Xen new_order, Xen length) { #define H_gtk_tree_model_rows_reordered_with_length "void gtk_tree_model_rows_reordered_with_length(GtkTreeModel* tree_model, \ GtkTreePath* path, GtkTreeIter* iter, gint* new_order, gint length)" Xen_check_type(Xen_is_GtkTreeModel_(tree_model), tree_model, 1, "gtk_tree_model_rows_reordered_with_length", "GtkTreeModel*"); Xen_check_type(Xen_is_GtkTreePath_(path), path, 2, "gtk_tree_model_rows_reordered_with_length", "GtkTreePath*"); Xen_check_type(Xen_is_GtkTreeIter_(iter), iter, 3, "gtk_tree_model_rows_reordered_with_length", "GtkTreeIter*"); Xen_check_type(Xen_is_gint_(new_order), new_order, 4, "gtk_tree_model_rows_reordered_with_length", "gint*"); Xen_check_type(Xen_is_gint(length), length, 5, "gtk_tree_model_rows_reordered_with_length", "gint"); gtk_tree_model_rows_reordered_with_length(Xen_to_C_GtkTreeModel_(tree_model), Xen_to_C_GtkTreePath_(path), Xen_to_C_GtkTreeIter_(iter), Xen_to_C_gint_(new_order), Xen_to_C_gint(length)); return(Xen_false); } static Xen gxg_gdk_cursor_new_from_surface(Xen display, Xen surface, Xen x, Xen y) { #define H_gdk_cursor_new_from_surface "GdkCursor* gdk_cursor_new_from_surface(GdkDisplay* display, \ cairo_surface_t* surface, gdouble x, gdouble y)" Xen_check_type(Xen_is_GdkDisplay_(display), display, 1, "gdk_cursor_new_from_surface", "GdkDisplay*"); Xen_check_type(Xen_is_cairo_surface_t_(surface), surface, 2, "gdk_cursor_new_from_surface", "cairo_surface_t*"); Xen_check_type(Xen_is_gdouble(x), x, 3, "gdk_cursor_new_from_surface", "gdouble"); Xen_check_type(Xen_is_gdouble(y), y, 4, "gdk_cursor_new_from_surface", "gdouble"); return(C_to_Xen_GdkCursor_(gdk_cursor_new_from_surface(Xen_to_C_GdkDisplay_(display), Xen_to_C_cairo_surface_t_(surface), Xen_to_C_gdouble(x), Xen_to_C_gdouble(y)))); } static Xen gxg_gdk_cursor_get_surface(Xen cursor, Xen ignore_x_hot, Xen ignore_y_hot) { #define H_gdk_cursor_get_surface "cairo_surface_t* gdk_cursor_get_surface(GdkCursor* cursor, gdouble* [x_hot], \ gdouble* [y_hot])" gdouble ref_x_hot; gdouble ref_y_hot; Xen_check_type(Xen_is_GdkCursor_(cursor), cursor, 1, "gdk_cursor_get_surface", "GdkCursor*"); { Xen result; result = C_to_Xen_cairo_surface_t_(gdk_cursor_get_surface(Xen_to_C_GdkCursor_(cursor), &ref_x_hot, &ref_y_hot)); return(Xen_list_3(result, C_to_Xen_gdouble(ref_x_hot), C_to_Xen_gdouble(ref_y_hot))); } } static Xen gxg_gdk_event_get_event_type(Xen event) { #define H_gdk_event_get_event_type "GdkEventType gdk_event_get_event_type(GdkEvent* event)" Xen_check_type(Xen_is_GdkEvent_(event), event, 1, "gdk_event_get_event_type", "GdkEvent*"); return(C_to_Xen_GdkEventType(gdk_event_get_event_type(Xen_to_C_GdkEvent_(event)))); } static Xen gxg_gtk_entry_set_tabs(Xen entry, Xen tabs) { #define H_gtk_entry_set_tabs "void gtk_entry_set_tabs(GtkEntry* entry, PangoTabArray* tabs)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_set_tabs", "GtkEntry*"); Xen_check_type(Xen_is_PangoTabArray_(tabs), tabs, 2, "gtk_entry_set_tabs", "PangoTabArray*"); gtk_entry_set_tabs(Xen_to_C_GtkEntry_(entry), Xen_to_C_PangoTabArray_(tabs)); return(Xen_false); } static Xen gxg_gtk_entry_get_tabs(Xen entry) { #define H_gtk_entry_get_tabs "PangoTabArray* gtk_entry_get_tabs(GtkEntry* entry)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_get_tabs", "GtkEntry*"); return(C_to_Xen_PangoTabArray_(gtk_entry_get_tabs(Xen_to_C_GtkEntry_(entry)))); } static Xen gxg_gtk_header_bar_get_show_close_button(Xen bar) { #define H_gtk_header_bar_get_show_close_button "gboolean gtk_header_bar_get_show_close_button(GtkHeaderBar* bar)" Xen_check_type(Xen_is_GtkHeaderBar_(bar), bar, 1, "gtk_header_bar_get_show_close_button", "GtkHeaderBar*"); return(C_to_Xen_gboolean(gtk_header_bar_get_show_close_button(Xen_to_C_GtkHeaderBar_(bar)))); } static Xen gxg_gtk_header_bar_set_show_close_button(Xen bar, Xen setting) { #define H_gtk_header_bar_set_show_close_button "void gtk_header_bar_set_show_close_button(GtkHeaderBar* bar, \ gboolean setting)" Xen_check_type(Xen_is_GtkHeaderBar_(bar), bar, 1, "gtk_header_bar_set_show_close_button", "GtkHeaderBar*"); Xen_check_type(Xen_is_gboolean(setting), setting, 2, "gtk_header_bar_set_show_close_button", "gboolean"); gtk_header_bar_set_show_close_button(Xen_to_C_GtkHeaderBar_(bar), Xen_to_C_gboolean(setting)); return(Xen_false); } static Xen gxg_gtk_list_box_prepend(Xen list_box, Xen child) { #define H_gtk_list_box_prepend "void gtk_list_box_prepend(GtkListBox* list_box, GtkWidget* child)" Xen_check_type(Xen_is_GtkListBox_(list_box), list_box, 1, "gtk_list_box_prepend", "GtkListBox*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_list_box_prepend", "GtkWidget*"); gtk_list_box_prepend(Xen_to_C_GtkListBox_(list_box), Xen_to_C_GtkWidget_(child)); return(Xen_false); } static Xen gxg_gtk_list_box_insert(Xen list_box, Xen child, Xen position) { #define H_gtk_list_box_insert "void gtk_list_box_insert(GtkListBox* list_box, GtkWidget* child, gint position)" Xen_check_type(Xen_is_GtkListBox_(list_box), list_box, 1, "gtk_list_box_insert", "GtkListBox*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_list_box_insert", "GtkWidget*"); Xen_check_type(Xen_is_gint(position), position, 3, "gtk_list_box_insert", "gint"); gtk_list_box_insert(Xen_to_C_GtkListBox_(list_box), Xen_to_C_GtkWidget_(child), Xen_to_C_gint(position)); return(Xen_false); } static Xen gxg_gdk_window_set_opaque_region(Xen window, Xen region) { #define H_gdk_window_set_opaque_region "void gdk_window_set_opaque_region(GdkWindow* window, cairo_region_t* region)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_set_opaque_region", "GdkWindow*"); Xen_check_type(Xen_is_cairo_region_t_(region), region, 2, "gdk_window_set_opaque_region", "cairo_region_t*"); gdk_window_set_opaque_region(Xen_to_C_GdkWindow_(window), Xen_to_C_cairo_region_t_(region)); return(Xen_false); } static Xen gxg_gtk_label_set_lines(Xen label, Xen lines) { #define H_gtk_label_set_lines "void gtk_label_set_lines(GtkLabel* label, gint lines)" Xen_check_type(Xen_is_GtkLabel_(label), label, 1, "gtk_label_set_lines", "GtkLabel*"); Xen_check_type(Xen_is_gint(lines), lines, 2, "gtk_label_set_lines", "gint"); gtk_label_set_lines(Xen_to_C_GtkLabel_(label), Xen_to_C_gint(lines)); return(Xen_false); } static Xen gxg_gtk_label_get_lines(Xen label) { #define H_gtk_label_get_lines "gint gtk_label_get_lines(GtkLabel* label)" Xen_check_type(Xen_is_GtkLabel_(label), label, 1, "gtk_label_get_lines", "GtkLabel*"); return(C_to_Xen_gint(gtk_label_get_lines(Xen_to_C_GtkLabel_(label)))); } static Xen gxg_gdk_event_get_window(Xen event) { #define H_gdk_event_get_window "GdkWindow* gdk_event_get_window(GdkEvent* event)" Xen_check_type(Xen_is_GdkEvent_(event), event, 1, "gdk_event_get_window", "GdkEvent*"); return(C_to_Xen_GdkWindow_(gdk_event_get_window(Xen_to_C_GdkEvent_(event)))); } #endif #if GTK_CHECK_VERSION(3, 12, 0) static Xen gxg_gtk_flow_box_child_new(void) { #define H_gtk_flow_box_child_new "GtkWidget* gtk_flow_box_child_new( void)" return(C_to_Xen_GtkWidget_(gtk_flow_box_child_new())); } static Xen gxg_gtk_flow_box_child_get_index(Xen child) { #define H_gtk_flow_box_child_get_index "gint gtk_flow_box_child_get_index(GtkFlowBoxChild* child)" Xen_check_type(Xen_is_GtkFlowBoxChild_(child), child, 1, "gtk_flow_box_child_get_index", "GtkFlowBoxChild*"); return(C_to_Xen_gint(gtk_flow_box_child_get_index(Xen_to_C_GtkFlowBoxChild_(child)))); } static Xen gxg_gtk_flow_box_child_is_selected(Xen child) { #define H_gtk_flow_box_child_is_selected "gboolean gtk_flow_box_child_is_selected(GtkFlowBoxChild* child)" Xen_check_type(Xen_is_GtkFlowBoxChild_(child), child, 1, "gtk_flow_box_child_is_selected", "GtkFlowBoxChild*"); return(C_to_Xen_gboolean(gtk_flow_box_child_is_selected(Xen_to_C_GtkFlowBoxChild_(child)))); } static Xen gxg_gtk_flow_box_child_changed(Xen child) { #define H_gtk_flow_box_child_changed "void gtk_flow_box_child_changed(GtkFlowBoxChild* child)" Xen_check_type(Xen_is_GtkFlowBoxChild_(child), child, 1, "gtk_flow_box_child_changed", "GtkFlowBoxChild*"); gtk_flow_box_child_changed(Xen_to_C_GtkFlowBoxChild_(child)); return(Xen_false); } static Xen gxg_gtk_flow_box_new(void) { #define H_gtk_flow_box_new "GtkWidget* gtk_flow_box_new( void)" return(C_to_Xen_GtkWidget_(gtk_flow_box_new())); } static Xen gxg_gtk_flow_box_set_homogeneous(Xen box, Xen homogeneous) { #define H_gtk_flow_box_set_homogeneous "void gtk_flow_box_set_homogeneous(GtkFlowBox* box, gboolean homogeneous)" Xen_check_type(Xen_is_GtkFlowBox_(box), box, 1, "gtk_flow_box_set_homogeneous", "GtkFlowBox*"); Xen_check_type(Xen_is_gboolean(homogeneous), homogeneous, 2, "gtk_flow_box_set_homogeneous", "gboolean"); gtk_flow_box_set_homogeneous(Xen_to_C_GtkFlowBox_(box), Xen_to_C_gboolean(homogeneous)); return(Xen_false); } static Xen gxg_gtk_flow_box_get_homogeneous(Xen box) { #define H_gtk_flow_box_get_homogeneous "gboolean gtk_flow_box_get_homogeneous(GtkFlowBox* box)" Xen_check_type(Xen_is_GtkFlowBox_(box), box, 1, "gtk_flow_box_get_homogeneous", "GtkFlowBox*"); return(C_to_Xen_gboolean(gtk_flow_box_get_homogeneous(Xen_to_C_GtkFlowBox_(box)))); } static Xen gxg_gtk_flow_box_set_row_spacing(Xen box, Xen spacing) { #define H_gtk_flow_box_set_row_spacing "void gtk_flow_box_set_row_spacing(GtkFlowBox* box, guint spacing)" Xen_check_type(Xen_is_GtkFlowBox_(box), box, 1, "gtk_flow_box_set_row_spacing", "GtkFlowBox*"); Xen_check_type(Xen_is_guint(spacing), spacing, 2, "gtk_flow_box_set_row_spacing", "guint"); gtk_flow_box_set_row_spacing(Xen_to_C_GtkFlowBox_(box), Xen_to_C_guint(spacing)); return(Xen_false); } static Xen gxg_gtk_flow_box_get_row_spacing(Xen box) { #define H_gtk_flow_box_get_row_spacing "guint gtk_flow_box_get_row_spacing(GtkFlowBox* box)" Xen_check_type(Xen_is_GtkFlowBox_(box), box, 1, "gtk_flow_box_get_row_spacing", "GtkFlowBox*"); return(C_to_Xen_guint(gtk_flow_box_get_row_spacing(Xen_to_C_GtkFlowBox_(box)))); } static Xen gxg_gtk_flow_box_set_column_spacing(Xen box, Xen spacing) { #define H_gtk_flow_box_set_column_spacing "void gtk_flow_box_set_column_spacing(GtkFlowBox* box, guint spacing)" Xen_check_type(Xen_is_GtkFlowBox_(box), box, 1, "gtk_flow_box_set_column_spacing", "GtkFlowBox*"); Xen_check_type(Xen_is_guint(spacing), spacing, 2, "gtk_flow_box_set_column_spacing", "guint"); gtk_flow_box_set_column_spacing(Xen_to_C_GtkFlowBox_(box), Xen_to_C_guint(spacing)); return(Xen_false); } static Xen gxg_gtk_flow_box_get_column_spacing(Xen box) { #define H_gtk_flow_box_get_column_spacing "guint gtk_flow_box_get_column_spacing(GtkFlowBox* box)" Xen_check_type(Xen_is_GtkFlowBox_(box), box, 1, "gtk_flow_box_get_column_spacing", "GtkFlowBox*"); return(C_to_Xen_guint(gtk_flow_box_get_column_spacing(Xen_to_C_GtkFlowBox_(box)))); } static Xen gxg_gtk_flow_box_set_min_children_per_line(Xen box, Xen n_children) { #define H_gtk_flow_box_set_min_children_per_line "void gtk_flow_box_set_min_children_per_line(GtkFlowBox* box, \ guint n_children)" Xen_check_type(Xen_is_GtkFlowBox_(box), box, 1, "gtk_flow_box_set_min_children_per_line", "GtkFlowBox*"); Xen_check_type(Xen_is_guint(n_children), n_children, 2, "gtk_flow_box_set_min_children_per_line", "guint"); gtk_flow_box_set_min_children_per_line(Xen_to_C_GtkFlowBox_(box), Xen_to_C_guint(n_children)); return(Xen_false); } static Xen gxg_gtk_flow_box_get_min_children_per_line(Xen box) { #define H_gtk_flow_box_get_min_children_per_line "guint gtk_flow_box_get_min_children_per_line(GtkFlowBox* box)" Xen_check_type(Xen_is_GtkFlowBox_(box), box, 1, "gtk_flow_box_get_min_children_per_line", "GtkFlowBox*"); return(C_to_Xen_guint(gtk_flow_box_get_min_children_per_line(Xen_to_C_GtkFlowBox_(box)))); } static Xen gxg_gtk_flow_box_set_max_children_per_line(Xen box, Xen n_children) { #define H_gtk_flow_box_set_max_children_per_line "void gtk_flow_box_set_max_children_per_line(GtkFlowBox* box, \ guint n_children)" Xen_check_type(Xen_is_GtkFlowBox_(box), box, 1, "gtk_flow_box_set_max_children_per_line", "GtkFlowBox*"); Xen_check_type(Xen_is_guint(n_children), n_children, 2, "gtk_flow_box_set_max_children_per_line", "guint"); gtk_flow_box_set_max_children_per_line(Xen_to_C_GtkFlowBox_(box), Xen_to_C_guint(n_children)); return(Xen_false); } static Xen gxg_gtk_flow_box_get_max_children_per_line(Xen box) { #define H_gtk_flow_box_get_max_children_per_line "guint gtk_flow_box_get_max_children_per_line(GtkFlowBox* box)" Xen_check_type(Xen_is_GtkFlowBox_(box), box, 1, "gtk_flow_box_get_max_children_per_line", "GtkFlowBox*"); return(C_to_Xen_guint(gtk_flow_box_get_max_children_per_line(Xen_to_C_GtkFlowBox_(box)))); } static Xen gxg_gtk_flow_box_set_activate_on_single_click(Xen box, Xen single) { #define H_gtk_flow_box_set_activate_on_single_click "void gtk_flow_box_set_activate_on_single_click(GtkFlowBox* box, \ gboolean single)" Xen_check_type(Xen_is_GtkFlowBox_(box), box, 1, "gtk_flow_box_set_activate_on_single_click", "GtkFlowBox*"); Xen_check_type(Xen_is_gboolean(single), single, 2, "gtk_flow_box_set_activate_on_single_click", "gboolean"); gtk_flow_box_set_activate_on_single_click(Xen_to_C_GtkFlowBox_(box), Xen_to_C_gboolean(single)); return(Xen_false); } static Xen gxg_gtk_flow_box_get_activate_on_single_click(Xen box) { #define H_gtk_flow_box_get_activate_on_single_click "gboolean gtk_flow_box_get_activate_on_single_click(GtkFlowBox* box)" Xen_check_type(Xen_is_GtkFlowBox_(box), box, 1, "gtk_flow_box_get_activate_on_single_click", "GtkFlowBox*"); return(C_to_Xen_gboolean(gtk_flow_box_get_activate_on_single_click(Xen_to_C_GtkFlowBox_(box)))); } static Xen gxg_gtk_flow_box_insert(Xen box, Xen widget, Xen position) { #define H_gtk_flow_box_insert "void gtk_flow_box_insert(GtkFlowBox* box, GtkWidget* widget, gint position)" Xen_check_type(Xen_is_GtkFlowBox_(box), box, 1, "gtk_flow_box_insert", "GtkFlowBox*"); Xen_check_type(Xen_is_GtkWidget_(widget), widget, 2, "gtk_flow_box_insert", "GtkWidget*"); Xen_check_type(Xen_is_gint(position), position, 3, "gtk_flow_box_insert", "gint"); gtk_flow_box_insert(Xen_to_C_GtkFlowBox_(box), Xen_to_C_GtkWidget_(widget), Xen_to_C_gint(position)); return(Xen_false); } static Xen gxg_gtk_flow_box_get_child_at_index(Xen box, Xen idx) { #define H_gtk_flow_box_get_child_at_index "GtkFlowBoxChild* gtk_flow_box_get_child_at_index(GtkFlowBox* box, \ gint idx)" Xen_check_type(Xen_is_GtkFlowBox_(box), box, 1, "gtk_flow_box_get_child_at_index", "GtkFlowBox*"); Xen_check_type(Xen_is_gint(idx), idx, 2, "gtk_flow_box_get_child_at_index", "gint"); return(C_to_Xen_GtkFlowBoxChild_(gtk_flow_box_get_child_at_index(Xen_to_C_GtkFlowBox_(box), Xen_to_C_gint(idx)))); } static Xen gxg_gtk_flow_box_get_selected_children(Xen box) { #define H_gtk_flow_box_get_selected_children "GList* gtk_flow_box_get_selected_children(GtkFlowBox* box)" Xen_check_type(Xen_is_GtkFlowBox_(box), box, 1, "gtk_flow_box_get_selected_children", "GtkFlowBox*"); return(C_to_Xen_GList_(gtk_flow_box_get_selected_children(Xen_to_C_GtkFlowBox_(box)))); } static Xen gxg_gtk_flow_box_select_child(Xen box, Xen child) { #define H_gtk_flow_box_select_child "void gtk_flow_box_select_child(GtkFlowBox* box, GtkFlowBoxChild* child)" Xen_check_type(Xen_is_GtkFlowBox_(box), box, 1, "gtk_flow_box_select_child", "GtkFlowBox*"); Xen_check_type(Xen_is_GtkFlowBoxChild_(child), child, 2, "gtk_flow_box_select_child", "GtkFlowBoxChild*"); gtk_flow_box_select_child(Xen_to_C_GtkFlowBox_(box), Xen_to_C_GtkFlowBoxChild_(child)); return(Xen_false); } static Xen gxg_gtk_flow_box_unselect_child(Xen box, Xen child) { #define H_gtk_flow_box_unselect_child "void gtk_flow_box_unselect_child(GtkFlowBox* box, GtkFlowBoxChild* child)" Xen_check_type(Xen_is_GtkFlowBox_(box), box, 1, "gtk_flow_box_unselect_child", "GtkFlowBox*"); Xen_check_type(Xen_is_GtkFlowBoxChild_(child), child, 2, "gtk_flow_box_unselect_child", "GtkFlowBoxChild*"); gtk_flow_box_unselect_child(Xen_to_C_GtkFlowBox_(box), Xen_to_C_GtkFlowBoxChild_(child)); return(Xen_false); } static Xen gxg_gtk_flow_box_select_all(Xen box) { #define H_gtk_flow_box_select_all "void gtk_flow_box_select_all(GtkFlowBox* box)" Xen_check_type(Xen_is_GtkFlowBox_(box), box, 1, "gtk_flow_box_select_all", "GtkFlowBox*"); gtk_flow_box_select_all(Xen_to_C_GtkFlowBox_(box)); return(Xen_false); } static Xen gxg_gtk_flow_box_unselect_all(Xen box) { #define H_gtk_flow_box_unselect_all "void gtk_flow_box_unselect_all(GtkFlowBox* box)" Xen_check_type(Xen_is_GtkFlowBox_(box), box, 1, "gtk_flow_box_unselect_all", "GtkFlowBox*"); gtk_flow_box_unselect_all(Xen_to_C_GtkFlowBox_(box)); return(Xen_false); } static Xen gxg_gtk_flow_box_set_selection_mode(Xen box, Xen mode) { #define H_gtk_flow_box_set_selection_mode "void gtk_flow_box_set_selection_mode(GtkFlowBox* box, GtkSelectionMode mode)" Xen_check_type(Xen_is_GtkFlowBox_(box), box, 1, "gtk_flow_box_set_selection_mode", "GtkFlowBox*"); Xen_check_type(Xen_is_GtkSelectionMode(mode), mode, 2, "gtk_flow_box_set_selection_mode", "GtkSelectionMode"); gtk_flow_box_set_selection_mode(Xen_to_C_GtkFlowBox_(box), Xen_to_C_GtkSelectionMode(mode)); return(Xen_false); } static Xen gxg_gtk_flow_box_get_selection_mode(Xen box) { #define H_gtk_flow_box_get_selection_mode "GtkSelectionMode gtk_flow_box_get_selection_mode(GtkFlowBox* box)" Xen_check_type(Xen_is_GtkFlowBox_(box), box, 1, "gtk_flow_box_get_selection_mode", "GtkFlowBox*"); return(C_to_Xen_GtkSelectionMode(gtk_flow_box_get_selection_mode(Xen_to_C_GtkFlowBox_(box)))); } static Xen gxg_gtk_flow_box_set_hadjustment(Xen box, Xen adjustment) { #define H_gtk_flow_box_set_hadjustment "void gtk_flow_box_set_hadjustment(GtkFlowBox* box, GtkAdjustment* adjustment)" Xen_check_type(Xen_is_GtkFlowBox_(box), box, 1, "gtk_flow_box_set_hadjustment", "GtkFlowBox*"); Xen_check_type(Xen_is_GtkAdjustment_(adjustment), adjustment, 2, "gtk_flow_box_set_hadjustment", "GtkAdjustment*"); gtk_flow_box_set_hadjustment(Xen_to_C_GtkFlowBox_(box), Xen_to_C_GtkAdjustment_(adjustment)); return(Xen_false); } static Xen gxg_gtk_flow_box_set_vadjustment(Xen box, Xen adjustment) { #define H_gtk_flow_box_set_vadjustment "void gtk_flow_box_set_vadjustment(GtkFlowBox* box, GtkAdjustment* adjustment)" Xen_check_type(Xen_is_GtkFlowBox_(box), box, 1, "gtk_flow_box_set_vadjustment", "GtkFlowBox*"); Xen_check_type(Xen_is_GtkAdjustment_(adjustment), adjustment, 2, "gtk_flow_box_set_vadjustment", "GtkAdjustment*"); gtk_flow_box_set_vadjustment(Xen_to_C_GtkFlowBox_(box), Xen_to_C_GtkAdjustment_(adjustment)); return(Xen_false); } static Xen gxg_gtk_flow_box_invalidate_filter(Xen box) { #define H_gtk_flow_box_invalidate_filter "void gtk_flow_box_invalidate_filter(GtkFlowBox* box)" Xen_check_type(Xen_is_GtkFlowBox_(box), box, 1, "gtk_flow_box_invalidate_filter", "GtkFlowBox*"); gtk_flow_box_invalidate_filter(Xen_to_C_GtkFlowBox_(box)); return(Xen_false); } static Xen gxg_gtk_flow_box_invalidate_sort(Xen box) { #define H_gtk_flow_box_invalidate_sort "void gtk_flow_box_invalidate_sort(GtkFlowBox* box)" Xen_check_type(Xen_is_GtkFlowBox_(box), box, 1, "gtk_flow_box_invalidate_sort", "GtkFlowBox*"); gtk_flow_box_invalidate_sort(Xen_to_C_GtkFlowBox_(box)); return(Xen_false); } static Xen gxg_gdk_window_set_event_compression(Xen window, Xen event_compression) { #define H_gdk_window_set_event_compression "void gdk_window_set_event_compression(GdkWindow* window, \ gboolean event_compression)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_set_event_compression", "GdkWindow*"); Xen_check_type(Xen_is_gboolean(event_compression), event_compression, 2, "gdk_window_set_event_compression", "gboolean"); gdk_window_set_event_compression(Xen_to_C_GdkWindow_(window), Xen_to_C_gboolean(event_compression)); return(Xen_false); } static Xen gxg_gdk_window_get_event_compression(Xen window) { #define H_gdk_window_get_event_compression "gboolean gdk_window_get_event_compression(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_get_event_compression", "GdkWindow*"); return(C_to_Xen_gboolean(gdk_window_get_event_compression(Xen_to_C_GdkWindow_(window)))); } static Xen gxg_gtk_places_sidebar_set_local_only(Xen sidebar, Xen local_only) { #define H_gtk_places_sidebar_set_local_only "void gtk_places_sidebar_set_local_only(GtkPlacesSidebar* sidebar, \ gboolean local_only)" Xen_check_type(Xen_is_GtkPlacesSidebar_(sidebar), sidebar, 1, "gtk_places_sidebar_set_local_only", "GtkPlacesSidebar*"); Xen_check_type(Xen_is_gboolean(local_only), local_only, 2, "gtk_places_sidebar_set_local_only", "gboolean"); gtk_places_sidebar_set_local_only(Xen_to_C_GtkPlacesSidebar_(sidebar), Xen_to_C_gboolean(local_only)); return(Xen_false); } static Xen gxg_gtk_places_sidebar_get_local_only(Xen sidebar) { #define H_gtk_places_sidebar_get_local_only "gboolean gtk_places_sidebar_get_local_only(GtkPlacesSidebar* sidebar)" Xen_check_type(Xen_is_GtkPlacesSidebar_(sidebar), sidebar, 1, "gtk_places_sidebar_get_local_only", "GtkPlacesSidebar*"); return(C_to_Xen_gboolean(gtk_places_sidebar_get_local_only(Xen_to_C_GtkPlacesSidebar_(sidebar)))); } static Xen gxg_gtk_stack_get_transition_running(Xen stack) { #define H_gtk_stack_get_transition_running "gboolean gtk_stack_get_transition_running(GtkStack* stack)" Xen_check_type(Xen_is_GtkStack_(stack), stack, 1, "gtk_stack_get_transition_running", "GtkStack*"); return(C_to_Xen_gboolean(gtk_stack_get_transition_running(Xen_to_C_GtkStack_(stack)))); } static Xen gxg_gtk_widget_get_margin_start(Xen widget) { #define H_gtk_widget_get_margin_start "gint gtk_widget_get_margin_start(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_margin_start", "GtkWidget*"); return(C_to_Xen_gint(gtk_widget_get_margin_start(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_set_margin_start(Xen widget, Xen margin) { #define H_gtk_widget_set_margin_start "void gtk_widget_set_margin_start(GtkWidget* widget, gint margin)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_set_margin_start", "GtkWidget*"); Xen_check_type(Xen_is_gint(margin), margin, 2, "gtk_widget_set_margin_start", "gint"); gtk_widget_set_margin_start(Xen_to_C_GtkWidget_(widget), Xen_to_C_gint(margin)); return(Xen_false); } static Xen gxg_gtk_widget_get_margin_end(Xen widget) { #define H_gtk_widget_get_margin_end "gint gtk_widget_get_margin_end(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_margin_end", "GtkWidget*"); return(C_to_Xen_gint(gtk_widget_get_margin_end(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_set_margin_end(Xen widget, Xen margin) { #define H_gtk_widget_set_margin_end "void gtk_widget_set_margin_end(GtkWidget* widget, gint margin)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_set_margin_end", "GtkWidget*"); Xen_check_type(Xen_is_gint(margin), margin, 2, "gtk_widget_set_margin_end", "gint"); gtk_widget_set_margin_end(Xen_to_C_GtkWidget_(widget), Xen_to_C_gint(margin)); return(Xen_false); } static Xen gxg_gtk_accel_label_get_accel(Xen accel_label, Xen ignore_accelerator_key, Xen ignore_accelerator_mods) { #define H_gtk_accel_label_get_accel "void gtk_accel_label_get_accel(GtkAccelLabel* accel_label, guint* [accelerator_key], \ GdkModifierType* [accelerator_mods])" guint ref_accelerator_key; GdkModifierType ref_accelerator_mods; Xen_check_type(Xen_is_GtkAccelLabel_(accel_label), accel_label, 1, "gtk_accel_label_get_accel", "GtkAccelLabel*"); gtk_accel_label_get_accel(Xen_to_C_GtkAccelLabel_(accel_label), &ref_accelerator_key, &ref_accelerator_mods); return(Xen_list_2(C_to_Xen_guint(ref_accelerator_key), C_to_Xen_GdkModifierType(ref_accelerator_mods))); } static Xen gxg_gdk_window_set_shadow_width(Xen window, Xen left, Xen right, Xen top, Xen bottom) { #define H_gdk_window_set_shadow_width "void gdk_window_set_shadow_width(GdkWindow* window, gint left, \ gint right, gint top, gint bottom)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_set_shadow_width", "GdkWindow*"); Xen_check_type(Xen_is_gint(left), left, 2, "gdk_window_set_shadow_width", "gint"); Xen_check_type(Xen_is_gint(right), right, 3, "gdk_window_set_shadow_width", "gint"); Xen_check_type(Xen_is_gint(top), top, 4, "gdk_window_set_shadow_width", "gint"); Xen_check_type(Xen_is_gint(bottom), bottom, 5, "gdk_window_set_shadow_width", "gint"); gdk_window_set_shadow_width(Xen_to_C_GdkWindow_(window), Xen_to_C_gint(left), Xen_to_C_gint(right), Xen_to_C_gint(top), Xen_to_C_gint(bottom)); return(Xen_false); } static Xen gxg_gtk_action_bar_new(void) { #define H_gtk_action_bar_new "GtkWidget* gtk_action_bar_new( void)" return(C_to_Xen_GtkWidget_(gtk_action_bar_new())); } static Xen gxg_gtk_action_bar_get_center_widget(Xen bar) { #define H_gtk_action_bar_get_center_widget "GtkWidget* gtk_action_bar_get_center_widget(GtkActionBar* bar)" Xen_check_type(Xen_is_GtkActionBar_(bar), bar, 1, "gtk_action_bar_get_center_widget", "GtkActionBar*"); return(C_to_Xen_GtkWidget_(gtk_action_bar_get_center_widget(Xen_to_C_GtkActionBar_(bar)))); } static Xen gxg_gtk_action_bar_set_center_widget(Xen bar, Xen center_widget) { #define H_gtk_action_bar_set_center_widget "void gtk_action_bar_set_center_widget(GtkActionBar* bar, \ GtkWidget* center_widget)" Xen_check_type(Xen_is_GtkActionBar_(bar), bar, 1, "gtk_action_bar_set_center_widget", "GtkActionBar*"); Xen_check_type(Xen_is_GtkWidget_(center_widget), center_widget, 2, "gtk_action_bar_set_center_widget", "GtkWidget*"); gtk_action_bar_set_center_widget(Xen_to_C_GtkActionBar_(bar), Xen_to_C_GtkWidget_(center_widget)); return(Xen_false); } static Xen gxg_gtk_action_bar_pack_start(Xen bar, Xen child) { #define H_gtk_action_bar_pack_start "void gtk_action_bar_pack_start(GtkActionBar* bar, GtkWidget* child)" Xen_check_type(Xen_is_GtkActionBar_(bar), bar, 1, "gtk_action_bar_pack_start", "GtkActionBar*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_action_bar_pack_start", "GtkWidget*"); gtk_action_bar_pack_start(Xen_to_C_GtkActionBar_(bar), Xen_to_C_GtkWidget_(child)); return(Xen_false); } static Xen gxg_gtk_action_bar_pack_end(Xen bar, Xen child) { #define H_gtk_action_bar_pack_end "void gtk_action_bar_pack_end(GtkActionBar* bar, GtkWidget* child)" Xen_check_type(Xen_is_GtkActionBar_(bar), bar, 1, "gtk_action_bar_pack_end", "GtkActionBar*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_action_bar_pack_end", "GtkWidget*"); gtk_action_bar_pack_end(Xen_to_C_GtkActionBar_(bar), Xen_to_C_GtkWidget_(child)); return(Xen_false); } static Xen gxg_gtk_header_bar_set_has_subtitle(Xen bar, Xen setting) { #define H_gtk_header_bar_set_has_subtitle "void gtk_header_bar_set_has_subtitle(GtkHeaderBar* bar, \ gboolean setting)" Xen_check_type(Xen_is_GtkHeaderBar_(bar), bar, 1, "gtk_header_bar_set_has_subtitle", "GtkHeaderBar*"); Xen_check_type(Xen_is_gboolean(setting), setting, 2, "gtk_header_bar_set_has_subtitle", "gboolean"); gtk_header_bar_set_has_subtitle(Xen_to_C_GtkHeaderBar_(bar), Xen_to_C_gboolean(setting)); return(Xen_false); } static Xen gxg_gtk_header_bar_get_has_subtitle(Xen bar) { #define H_gtk_header_bar_get_has_subtitle "gboolean gtk_header_bar_get_has_subtitle(GtkHeaderBar* bar)" Xen_check_type(Xen_is_GtkHeaderBar_(bar), bar, 1, "gtk_header_bar_get_has_subtitle", "GtkHeaderBar*"); return(C_to_Xen_gboolean(gtk_header_bar_get_has_subtitle(Xen_to_C_GtkHeaderBar_(bar)))); } static Xen gxg_gtk_header_bar_set_decoration_layout(Xen bar, Xen layout) { #define H_gtk_header_bar_set_decoration_layout "void gtk_header_bar_set_decoration_layout(GtkHeaderBar* bar, \ gchar* layout)" Xen_check_type(Xen_is_GtkHeaderBar_(bar), bar, 1, "gtk_header_bar_set_decoration_layout", "GtkHeaderBar*"); Xen_check_type(Xen_is_gchar_(layout), layout, 2, "gtk_header_bar_set_decoration_layout", "gchar*"); gtk_header_bar_set_decoration_layout(Xen_to_C_GtkHeaderBar_(bar), (const gchar*)Xen_to_C_gchar_(layout)); return(Xen_false); } static Xen gxg_gtk_header_bar_get_decoration_layout(Xen bar) { #define H_gtk_header_bar_get_decoration_layout "gchar* gtk_header_bar_get_decoration_layout(GtkHeaderBar* bar)" Xen_check_type(Xen_is_GtkHeaderBar_(bar), bar, 1, "gtk_header_bar_get_decoration_layout", "GtkHeaderBar*"); return(C_to_Xen_gchar_(gtk_header_bar_get_decoration_layout(Xen_to_C_GtkHeaderBar_(bar)))); } static Xen gxg_gtk_icon_info_is_symbolic(Xen icon_info) { #define H_gtk_icon_info_is_symbolic "gboolean gtk_icon_info_is_symbolic(GtkIconInfo* icon_info)" Xen_check_type(Xen_is_GtkIconInfo_(icon_info), icon_info, 1, "gtk_icon_info_is_symbolic", "GtkIconInfo*"); return(C_to_Xen_gboolean(gtk_icon_info_is_symbolic(Xen_to_C_GtkIconInfo_(icon_info)))); } static Xen gxg_gtk_get_locale_direction(void) { #define H_gtk_get_locale_direction "GtkTextDirection gtk_get_locale_direction( void)" return(C_to_Xen_GtkTextDirection(gtk_get_locale_direction())); } static Xen gxg_gtk_window_is_maximized(Xen window) { #define H_gtk_window_is_maximized "gboolean gtk_window_is_maximized(GtkWindow* window)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_is_maximized", "GtkWindow*"); return(C_to_Xen_gboolean(gtk_window_is_maximized(Xen_to_C_GtkWindow_(window)))); } static Xen gxg_gtk_dialog_get_header_bar(Xen dialog) { #define H_gtk_dialog_get_header_bar "GtkWidget* gtk_dialog_get_header_bar(GtkDialog* dialog)" Xen_check_type(Xen_is_GtkDialog_(dialog), dialog, 1, "gtk_dialog_get_header_bar", "GtkDialog*"); return(C_to_Xen_GtkWidget_(gtk_dialog_get_header_bar(Xen_to_C_GtkDialog_(dialog)))); } static Xen gxg_gtk_popover_new(Xen relative_to) { #define H_gtk_popover_new "GtkWidget* gtk_popover_new(GtkWidget* relative_to)" Xen_check_type(Xen_is_GtkWidget_(relative_to), relative_to, 1, "gtk_popover_new", "GtkWidget*"); return(C_to_Xen_GtkWidget_(gtk_popover_new(Xen_to_C_GtkWidget_(relative_to)))); } static Xen gxg_gtk_popover_set_relative_to(Xen popover, Xen relative_to) { #define H_gtk_popover_set_relative_to "void gtk_popover_set_relative_to(GtkPopover* popover, GtkWidget* relative_to)" Xen_check_type(Xen_is_GtkPopover_(popover), popover, 1, "gtk_popover_set_relative_to", "GtkPopover*"); Xen_check_type(Xen_is_GtkWidget_(relative_to), relative_to, 2, "gtk_popover_set_relative_to", "GtkWidget*"); gtk_popover_set_relative_to(Xen_to_C_GtkPopover_(popover), Xen_to_C_GtkWidget_(relative_to)); return(Xen_false); } static Xen gxg_gtk_popover_get_relative_to(Xen popover) { #define H_gtk_popover_get_relative_to "GtkWidget* gtk_popover_get_relative_to(GtkPopover* popover)" Xen_check_type(Xen_is_GtkPopover_(popover), popover, 1, "gtk_popover_get_relative_to", "GtkPopover*"); return(C_to_Xen_GtkWidget_(gtk_popover_get_relative_to(Xen_to_C_GtkPopover_(popover)))); } static Xen gxg_gtk_popover_set_position(Xen popover, Xen position) { #define H_gtk_popover_set_position "void gtk_popover_set_position(GtkPopover* popover, GtkPositionType position)" Xen_check_type(Xen_is_GtkPopover_(popover), popover, 1, "gtk_popover_set_position", "GtkPopover*"); Xen_check_type(Xen_is_GtkPositionType(position), position, 2, "gtk_popover_set_position", "GtkPositionType"); gtk_popover_set_position(Xen_to_C_GtkPopover_(popover), Xen_to_C_GtkPositionType(position)); return(Xen_false); } static Xen gxg_gtk_popover_get_position(Xen popover) { #define H_gtk_popover_get_position "GtkPositionType gtk_popover_get_position(GtkPopover* popover)" Xen_check_type(Xen_is_GtkPopover_(popover), popover, 1, "gtk_popover_get_position", "GtkPopover*"); return(C_to_Xen_GtkPositionType(gtk_popover_get_position(Xen_to_C_GtkPopover_(popover)))); } static Xen gxg_gtk_popover_set_modal(Xen popover, Xen modal) { #define H_gtk_popover_set_modal "void gtk_popover_set_modal(GtkPopover* popover, gboolean modal)" Xen_check_type(Xen_is_GtkPopover_(popover), popover, 1, "gtk_popover_set_modal", "GtkPopover*"); Xen_check_type(Xen_is_gboolean(modal), modal, 2, "gtk_popover_set_modal", "gboolean"); gtk_popover_set_modal(Xen_to_C_GtkPopover_(popover), Xen_to_C_gboolean(modal)); return(Xen_false); } static Xen gxg_gtk_popover_get_modal(Xen popover) { #define H_gtk_popover_get_modal "gboolean gtk_popover_get_modal(GtkPopover* popover)" Xen_check_type(Xen_is_GtkPopover_(popover), popover, 1, "gtk_popover_get_modal", "GtkPopover*"); return(C_to_Xen_gboolean(gtk_popover_get_modal(Xen_to_C_GtkPopover_(popover)))); } static Xen gxg_gtk_box_set_center_widget(Xen box, Xen widget) { #define H_gtk_box_set_center_widget "void gtk_box_set_center_widget(GtkBox* box, GtkWidget* widget)" Xen_check_type(Xen_is_GtkBox_(box), box, 1, "gtk_box_set_center_widget", "GtkBox*"); Xen_check_type(Xen_is_GtkWidget_(widget), widget, 2, "gtk_box_set_center_widget", "GtkWidget*"); gtk_box_set_center_widget(Xen_to_C_GtkBox_(box), Xen_to_C_GtkWidget_(widget)); return(Xen_false); } static Xen gxg_gtk_box_get_center_widget(Xen box) { #define H_gtk_box_get_center_widget "GtkWidget* gtk_box_get_center_widget(GtkBox* box)" Xen_check_type(Xen_is_GtkBox_(box), box, 1, "gtk_box_get_center_widget", "GtkBox*"); return(C_to_Xen_GtkWidget_(gtk_box_get_center_widget(Xen_to_C_GtkBox_(box)))); } static Xen gxg_gtk_entry_set_max_width_chars(Xen entry, Xen n_chars) { #define H_gtk_entry_set_max_width_chars "void gtk_entry_set_max_width_chars(GtkEntry* entry, gint n_chars)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_set_max_width_chars", "GtkEntry*"); Xen_check_type(Xen_is_gint(n_chars), n_chars, 2, "gtk_entry_set_max_width_chars", "gint"); gtk_entry_set_max_width_chars(Xen_to_C_GtkEntry_(entry), Xen_to_C_gint(n_chars)); return(Xen_false); } static Xen gxg_gtk_entry_get_max_width_chars(Xen entry) { #define H_gtk_entry_get_max_width_chars "gint gtk_entry_get_max_width_chars(GtkEntry* entry)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_get_max_width_chars", "GtkEntry*"); return(C_to_Xen_gint(gtk_entry_get_max_width_chars(Xen_to_C_GtkEntry_(entry)))); } static Xen gxg_gdk_device_get_last_event_window(Xen device) { #define H_gdk_device_get_last_event_window "GdkWindow* gdk_device_get_last_event_window(GdkDevice* device)" Xen_check_type(Xen_is_GdkDevice_(device), device, 1, "gdk_device_get_last_event_window", "GdkDevice*"); return(C_to_Xen_GdkWindow_(gdk_device_get_last_event_window(Xen_to_C_GdkDevice_(device)))); } #endif #if GTK_CHECK_VERSION(3, 14, 0) static Xen gxg_gtk_list_box_row_is_selected(Xen row) { #define H_gtk_list_box_row_is_selected "gboolean gtk_list_box_row_is_selected(GtkListBoxRow* row)" Xen_check_type(Xen_is_GtkListBoxRow_(row), row, 1, "gtk_list_box_row_is_selected", "GtkListBoxRow*"); return(C_to_Xen_gboolean(gtk_list_box_row_is_selected(Xen_to_C_GtkListBoxRow_(row)))); } static Xen gxg_gtk_list_box_unselect_row(Xen box, Xen row) { #define H_gtk_list_box_unselect_row "void gtk_list_box_unselect_row(GtkListBox* box, GtkListBoxRow* row)" Xen_check_type(Xen_is_GtkListBox_(box), box, 1, "gtk_list_box_unselect_row", "GtkListBox*"); Xen_check_type(Xen_is_GtkListBoxRow_(row), row, 2, "gtk_list_box_unselect_row", "GtkListBoxRow*"); gtk_list_box_unselect_row(Xen_to_C_GtkListBox_(box), Xen_to_C_GtkListBoxRow_(row)); return(Xen_false); } static Xen gxg_gtk_list_box_select_all(Xen box) { #define H_gtk_list_box_select_all "void gtk_list_box_select_all(GtkListBox* box)" Xen_check_type(Xen_is_GtkListBox_(box), box, 1, "gtk_list_box_select_all", "GtkListBox*"); gtk_list_box_select_all(Xen_to_C_GtkListBox_(box)); return(Xen_false); } static Xen gxg_gtk_list_box_unselect_all(Xen box) { #define H_gtk_list_box_unselect_all "void gtk_list_box_unselect_all(GtkListBox* box)" Xen_check_type(Xen_is_GtkListBox_(box), box, 1, "gtk_list_box_unselect_all", "GtkListBox*"); gtk_list_box_unselect_all(Xen_to_C_GtkListBox_(box)); return(Xen_false); } static Xen gxg_gtk_places_sidebar_get_show_enter_location(Xen sidebar) { #define H_gtk_places_sidebar_get_show_enter_location "gboolean gtk_places_sidebar_get_show_enter_location(GtkPlacesSidebar* sidebar)" Xen_check_type(Xen_is_GtkPlacesSidebar_(sidebar), sidebar, 1, "gtk_places_sidebar_get_show_enter_location", "GtkPlacesSidebar*"); return(C_to_Xen_gboolean(gtk_places_sidebar_get_show_enter_location(Xen_to_C_GtkPlacesSidebar_(sidebar)))); } static Xen gxg_gtk_places_sidebar_set_show_enter_location(Xen sidebar, Xen show_enter_location) { #define H_gtk_places_sidebar_set_show_enter_location "void gtk_places_sidebar_set_show_enter_location(GtkPlacesSidebar* sidebar, \ gboolean show_enter_location)" Xen_check_type(Xen_is_GtkPlacesSidebar_(sidebar), sidebar, 1, "gtk_places_sidebar_set_show_enter_location", "GtkPlacesSidebar*"); Xen_check_type(Xen_is_gboolean(show_enter_location), show_enter_location, 2, "gtk_places_sidebar_set_show_enter_location", "gboolean"); gtk_places_sidebar_set_show_enter_location(Xen_to_C_GtkPlacesSidebar_(sidebar), Xen_to_C_gboolean(show_enter_location)); return(Xen_false); } static Xen gxg_gtk_switch_set_state(Xen sw, Xen state) { #define H_gtk_switch_set_state "void gtk_switch_set_state(GtkSwitch* sw, gboolean state)" Xen_check_type(Xen_is_GtkSwitch_(sw), sw, 1, "gtk_switch_set_state", "GtkSwitch*"); Xen_check_type(Xen_is_gboolean(state), state, 2, "gtk_switch_set_state", "gboolean"); gtk_switch_set_state(Xen_to_C_GtkSwitch_(sw), Xen_to_C_gboolean(state)); return(Xen_false); } static Xen gxg_gtk_switch_get_state(Xen sw) { #define H_gtk_switch_get_state "gboolean gtk_switch_get_state(GtkSwitch* sw)" Xen_check_type(Xen_is_GtkSwitch_(sw), sw, 1, "gtk_switch_get_state", "GtkSwitch*"); return(C_to_Xen_gboolean(gtk_switch_get_state(Xen_to_C_GtkSwitch_(sw)))); } static Xen gxg_gdk_window_show_window_menu(Xen window, Xen event) { #define H_gdk_window_show_window_menu "gboolean gdk_window_show_window_menu(GdkWindow* window, GdkEvent* event)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_show_window_menu", "GdkWindow*"); Xen_check_type(Xen_is_GdkEvent_(event), event, 2, "gdk_window_show_window_menu", "GdkEvent*"); return(C_to_Xen_gboolean(gdk_window_show_window_menu(Xen_to_C_GdkWindow_(window), Xen_to_C_GdkEvent_(event)))); } static Xen gxg_gtk_widget_set_clip(Xen widget, Xen clip) { #define H_gtk_widget_set_clip "void gtk_widget_set_clip(GtkWidget* widget, GtkAllocation* clip)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_set_clip", "GtkWidget*"); Xen_check_type(Xen_is_GtkAllocation_(clip), clip, 2, "gtk_widget_set_clip", "GtkAllocation*"); gtk_widget_set_clip(Xen_to_C_GtkWidget_(widget), Xen_to_C_GtkAllocation_(clip)); return(Xen_false); } static Xen gxg_gtk_widget_get_clip(Xen widget, Xen clip) { #define H_gtk_widget_get_clip "void gtk_widget_get_clip(GtkWidget* widget, GtkAllocation* clip)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_clip", "GtkWidget*"); Xen_check_type(Xen_is_GtkAllocation_(clip), clip, 2, "gtk_widget_get_clip", "GtkAllocation*"); gtk_widget_get_clip(Xen_to_C_GtkWidget_(widget), Xen_to_C_GtkAllocation_(clip)); return(Xen_false); } static Xen gxg_gtk_gesture_get_device(Xen gesture) { #define H_gtk_gesture_get_device "GdkDevice* gtk_gesture_get_device(GtkGesture* gesture)" Xen_check_type(Xen_is_GtkGesture_(gesture), gesture, 1, "gtk_gesture_get_device", "GtkGesture*"); return(C_to_Xen_GdkDevice_(gtk_gesture_get_device(Xen_to_C_GtkGesture_(gesture)))); } static Xen gxg_gtk_gesture_set_state(Xen gesture, Xen state) { #define H_gtk_gesture_set_state "gboolean gtk_gesture_set_state(GtkGesture* gesture, GtkEventSequenceState state)" Xen_check_type(Xen_is_GtkGesture_(gesture), gesture, 1, "gtk_gesture_set_state", "GtkGesture*"); Xen_check_type(Xen_is_GtkEventSequenceState(state), state, 2, "gtk_gesture_set_state", "GtkEventSequenceState"); return(C_to_Xen_gboolean(gtk_gesture_set_state(Xen_to_C_GtkGesture_(gesture), Xen_to_C_GtkEventSequenceState(state)))); } static Xen gxg_gtk_gesture_get_sequence_state(Xen gesture, Xen sequence) { #define H_gtk_gesture_get_sequence_state "GtkEventSequenceState gtk_gesture_get_sequence_state(GtkGesture* gesture, \ GdkEventSequence* sequence)" Xen_check_type(Xen_is_GtkGesture_(gesture), gesture, 1, "gtk_gesture_get_sequence_state", "GtkGesture*"); Xen_check_type(Xen_is_GdkEventSequence_(sequence), sequence, 2, "gtk_gesture_get_sequence_state", "GdkEventSequence*"); return(C_to_Xen_GtkEventSequenceState(gtk_gesture_get_sequence_state(Xen_to_C_GtkGesture_(gesture), Xen_to_C_GdkEventSequence_(sequence)))); } static Xen gxg_gtk_gesture_set_sequence_state(Xen gesture, Xen sequence, Xen state) { #define H_gtk_gesture_set_sequence_state "gboolean gtk_gesture_set_sequence_state(GtkGesture* gesture, \ GdkEventSequence* sequence, GtkEventSequenceState state)" Xen_check_type(Xen_is_GtkGesture_(gesture), gesture, 1, "gtk_gesture_set_sequence_state", "GtkGesture*"); Xen_check_type(Xen_is_GdkEventSequence_(sequence), sequence, 2, "gtk_gesture_set_sequence_state", "GdkEventSequence*"); Xen_check_type(Xen_is_GtkEventSequenceState(state), state, 3, "gtk_gesture_set_sequence_state", "GtkEventSequenceState"); return(C_to_Xen_gboolean(gtk_gesture_set_sequence_state(Xen_to_C_GtkGesture_(gesture), Xen_to_C_GdkEventSequence_(sequence), Xen_to_C_GtkEventSequenceState(state)))); } static Xen gxg_gtk_gesture_get_sequences(Xen gesture) { #define H_gtk_gesture_get_sequences "GList* gtk_gesture_get_sequences(GtkGesture* gesture)" Xen_check_type(Xen_is_GtkGesture_(gesture), gesture, 1, "gtk_gesture_get_sequences", "GtkGesture*"); return(C_to_Xen_GList_(gtk_gesture_get_sequences(Xen_to_C_GtkGesture_(gesture)))); } static Xen gxg_gtk_gesture_get_last_updated_sequence(Xen gesture) { #define H_gtk_gesture_get_last_updated_sequence "GdkEventSequence* gtk_gesture_get_last_updated_sequence(GtkGesture* gesture)" Xen_check_type(Xen_is_GtkGesture_(gesture), gesture, 1, "gtk_gesture_get_last_updated_sequence", "GtkGesture*"); return(C_to_Xen_GdkEventSequence_(gtk_gesture_get_last_updated_sequence(Xen_to_C_GtkGesture_(gesture)))); } static Xen gxg_gtk_gesture_handles_sequence(Xen gesture, Xen sequence) { #define H_gtk_gesture_handles_sequence "gboolean gtk_gesture_handles_sequence(GtkGesture* gesture, \ GdkEventSequence* sequence)" Xen_check_type(Xen_is_GtkGesture_(gesture), gesture, 1, "gtk_gesture_handles_sequence", "GtkGesture*"); Xen_check_type(Xen_is_GdkEventSequence_(sequence), sequence, 2, "gtk_gesture_handles_sequence", "GdkEventSequence*"); return(C_to_Xen_gboolean(gtk_gesture_handles_sequence(Xen_to_C_GtkGesture_(gesture), Xen_to_C_GdkEventSequence_(sequence)))); } static Xen gxg_gtk_gesture_get_last_event(Xen gesture, Xen sequence) { #define H_gtk_gesture_get_last_event "GdkEvent* gtk_gesture_get_last_event(GtkGesture* gesture, GdkEventSequence* sequence)" Xen_check_type(Xen_is_GtkGesture_(gesture), gesture, 1, "gtk_gesture_get_last_event", "GtkGesture*"); Xen_check_type(Xen_is_GdkEventSequence_(sequence), sequence, 2, "gtk_gesture_get_last_event", "GdkEventSequence*"); return(C_to_Xen_GdkEvent_((GdkEvent*)gtk_gesture_get_last_event(Xen_to_C_GtkGesture_(gesture), Xen_to_C_GdkEventSequence_(sequence)))); } static Xen gxg_gtk_gesture_get_point(Xen gesture, Xen sequence, Xen ignore_x, Xen ignore_y) { #define H_gtk_gesture_get_point "gboolean gtk_gesture_get_point(GtkGesture* gesture, GdkEventSequence* sequence, \ gdouble* [x], gdouble* [y])" gdouble ref_x; gdouble ref_y; Xen_check_type(Xen_is_GtkGesture_(gesture), gesture, 1, "gtk_gesture_get_point", "GtkGesture*"); Xen_check_type(Xen_is_GdkEventSequence_(sequence), sequence, 2, "gtk_gesture_get_point", "GdkEventSequence*"); { Xen result; result = C_to_Xen_gboolean(gtk_gesture_get_point(Xen_to_C_GtkGesture_(gesture), Xen_to_C_GdkEventSequence_(sequence), &ref_x, &ref_y)); return(Xen_list_3(result, C_to_Xen_gdouble(ref_x), C_to_Xen_gdouble(ref_y))); } } static Xen gxg_gtk_gesture_get_bounding_box(Xen gesture, Xen rect) { #define H_gtk_gesture_get_bounding_box "gboolean gtk_gesture_get_bounding_box(GtkGesture* gesture, \ GdkRectangle* rect)" Xen_check_type(Xen_is_GtkGesture_(gesture), gesture, 1, "gtk_gesture_get_bounding_box", "GtkGesture*"); Xen_check_type(Xen_is_GdkRectangle_(rect), rect, 2, "gtk_gesture_get_bounding_box", "GdkRectangle*"); return(C_to_Xen_gboolean(gtk_gesture_get_bounding_box(Xen_to_C_GtkGesture_(gesture), Xen_to_C_GdkRectangle_(rect)))); } static Xen gxg_gtk_gesture_get_bounding_box_center(Xen gesture, Xen ignore_x, Xen ignore_y) { #define H_gtk_gesture_get_bounding_box_center "gboolean gtk_gesture_get_bounding_box_center(GtkGesture* gesture, \ gdouble* [x], gdouble* [y])" gdouble ref_x; gdouble ref_y; Xen_check_type(Xen_is_GtkGesture_(gesture), gesture, 1, "gtk_gesture_get_bounding_box_center", "GtkGesture*"); { Xen result; result = C_to_Xen_gboolean(gtk_gesture_get_bounding_box_center(Xen_to_C_GtkGesture_(gesture), &ref_x, &ref_y)); return(Xen_list_3(result, C_to_Xen_gdouble(ref_x), C_to_Xen_gdouble(ref_y))); } } static Xen gxg_gtk_gesture_is_active(Xen gesture) { #define H_gtk_gesture_is_active "gboolean gtk_gesture_is_active(GtkGesture* gesture)" Xen_check_type(Xen_is_GtkGesture_(gesture), gesture, 1, "gtk_gesture_is_active", "GtkGesture*"); return(C_to_Xen_gboolean(gtk_gesture_is_active(Xen_to_C_GtkGesture_(gesture)))); } static Xen gxg_gtk_gesture_is_recognized(Xen gesture) { #define H_gtk_gesture_is_recognized "gboolean gtk_gesture_is_recognized(GtkGesture* gesture)" Xen_check_type(Xen_is_GtkGesture_(gesture), gesture, 1, "gtk_gesture_is_recognized", "GtkGesture*"); return(C_to_Xen_gboolean(gtk_gesture_is_recognized(Xen_to_C_GtkGesture_(gesture)))); } static Xen gxg_gtk_gesture_get_window(Xen gesture) { #define H_gtk_gesture_get_window "GdkWindow* gtk_gesture_get_window(GtkGesture* gesture)" Xen_check_type(Xen_is_GtkGesture_(gesture), gesture, 1, "gtk_gesture_get_window", "GtkGesture*"); return(C_to_Xen_GdkWindow_(gtk_gesture_get_window(Xen_to_C_GtkGesture_(gesture)))); } static Xen gxg_gtk_gesture_set_window(Xen gesture, Xen window) { #define H_gtk_gesture_set_window "void gtk_gesture_set_window(GtkGesture* gesture, GdkWindow* window)" Xen_check_type(Xen_is_GtkGesture_(gesture), gesture, 1, "gtk_gesture_set_window", "GtkGesture*"); Xen_check_type(Xen_is_GdkWindow_(window), window, 2, "gtk_gesture_set_window", "GdkWindow*"); gtk_gesture_set_window(Xen_to_C_GtkGesture_(gesture), Xen_to_C_GdkWindow_(window)); return(Xen_false); } static Xen gxg_gtk_gesture_group(Xen group_gesture, Xen gesture) { #define H_gtk_gesture_group "void gtk_gesture_group(GtkGesture* group_gesture, GtkGesture* gesture)" Xen_check_type(Xen_is_GtkGesture_(group_gesture), group_gesture, 1, "gtk_gesture_group", "GtkGesture*"); Xen_check_type(Xen_is_GtkGesture_(gesture), gesture, 2, "gtk_gesture_group", "GtkGesture*"); gtk_gesture_group(Xen_to_C_GtkGesture_(group_gesture), Xen_to_C_GtkGesture_(gesture)); return(Xen_false); } static Xen gxg_gtk_gesture_ungroup(Xen gesture) { #define H_gtk_gesture_ungroup "void gtk_gesture_ungroup(GtkGesture* gesture)" Xen_check_type(Xen_is_GtkGesture_(gesture), gesture, 1, "gtk_gesture_ungroup", "GtkGesture*"); gtk_gesture_ungroup(Xen_to_C_GtkGesture_(gesture)); return(Xen_false); } static Xen gxg_gtk_gesture_get_group(Xen gesture) { #define H_gtk_gesture_get_group "GList* gtk_gesture_get_group(GtkGesture* gesture)" Xen_check_type(Xen_is_GtkGesture_(gesture), gesture, 1, "gtk_gesture_get_group", "GtkGesture*"); return(C_to_Xen_GList_(gtk_gesture_get_group(Xen_to_C_GtkGesture_(gesture)))); } static Xen gxg_gtk_gesture_is_grouped_with(Xen gesture, Xen other) { #define H_gtk_gesture_is_grouped_with "gboolean gtk_gesture_is_grouped_with(GtkGesture* gesture, GtkGesture* other)" Xen_check_type(Xen_is_GtkGesture_(gesture), gesture, 1, "gtk_gesture_is_grouped_with", "GtkGesture*"); Xen_check_type(Xen_is_GtkGesture_(other), other, 2, "gtk_gesture_is_grouped_with", "GtkGesture*"); return(C_to_Xen_gboolean(gtk_gesture_is_grouped_with(Xen_to_C_GtkGesture_(gesture), Xen_to_C_GtkGesture_(other)))); } static Xen gxg_gtk_gesture_drag_new(Xen widget) { #define H_gtk_gesture_drag_new "GtkGesture* gtk_gesture_drag_new(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_gesture_drag_new", "GtkWidget*"); return(C_to_Xen_GtkGesture_(gtk_gesture_drag_new(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_gesture_drag_get_start_point(Xen gesture, Xen ignore_x, Xen ignore_y) { #define H_gtk_gesture_drag_get_start_point "gboolean gtk_gesture_drag_get_start_point(GtkGestureDrag* gesture, \ gdouble* [x], gdouble* [y])" gdouble ref_x; gdouble ref_y; Xen_check_type(Xen_is_GtkGestureDrag_(gesture), gesture, 1, "gtk_gesture_drag_get_start_point", "GtkGestureDrag*"); { Xen result; result = C_to_Xen_gboolean(gtk_gesture_drag_get_start_point(Xen_to_C_GtkGestureDrag_(gesture), &ref_x, &ref_y)); return(Xen_list_3(result, C_to_Xen_gdouble(ref_x), C_to_Xen_gdouble(ref_y))); } } static Xen gxg_gtk_gesture_drag_get_offset(Xen gesture, Xen ignore_x, Xen ignore_y) { #define H_gtk_gesture_drag_get_offset "gboolean gtk_gesture_drag_get_offset(GtkGestureDrag* gesture, \ gdouble* [x], gdouble* [y])" gdouble ref_x; gdouble ref_y; Xen_check_type(Xen_is_GtkGestureDrag_(gesture), gesture, 1, "gtk_gesture_drag_get_offset", "GtkGestureDrag*"); { Xen result; result = C_to_Xen_gboolean(gtk_gesture_drag_get_offset(Xen_to_C_GtkGestureDrag_(gesture), &ref_x, &ref_y)); return(Xen_list_3(result, C_to_Xen_gdouble(ref_x), C_to_Xen_gdouble(ref_y))); } } static Xen gxg_gtk_gesture_long_press_new(Xen widget) { #define H_gtk_gesture_long_press_new "GtkGesture* gtk_gesture_long_press_new(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_gesture_long_press_new", "GtkWidget*"); return(C_to_Xen_GtkGesture_(gtk_gesture_long_press_new(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_gesture_pan_new(Xen widget, Xen orientation) { #define H_gtk_gesture_pan_new "GtkGesture* gtk_gesture_pan_new(GtkWidget* widget, GtkOrientation orientation)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_gesture_pan_new", "GtkWidget*"); Xen_check_type(Xen_is_GtkOrientation(orientation), orientation, 2, "gtk_gesture_pan_new", "GtkOrientation"); return(C_to_Xen_GtkGesture_(gtk_gesture_pan_new(Xen_to_C_GtkWidget_(widget), Xen_to_C_GtkOrientation(orientation)))); } static Xen gxg_gtk_gesture_pan_get_orientation(Xen gesture) { #define H_gtk_gesture_pan_get_orientation "GtkOrientation gtk_gesture_pan_get_orientation(GtkGesturePan* gesture)" Xen_check_type(Xen_is_GtkGesturePan_(gesture), gesture, 1, "gtk_gesture_pan_get_orientation", "GtkGesturePan*"); return(C_to_Xen_GtkOrientation(gtk_gesture_pan_get_orientation(Xen_to_C_GtkGesturePan_(gesture)))); } static Xen gxg_gtk_gesture_pan_set_orientation(Xen gesture, Xen orientation) { #define H_gtk_gesture_pan_set_orientation "void gtk_gesture_pan_set_orientation(GtkGesturePan* gesture, \ GtkOrientation orientation)" Xen_check_type(Xen_is_GtkGesturePan_(gesture), gesture, 1, "gtk_gesture_pan_set_orientation", "GtkGesturePan*"); Xen_check_type(Xen_is_GtkOrientation(orientation), orientation, 2, "gtk_gesture_pan_set_orientation", "GtkOrientation"); gtk_gesture_pan_set_orientation(Xen_to_C_GtkGesturePan_(gesture), Xen_to_C_GtkOrientation(orientation)); return(Xen_false); } static Xen gxg_gtk_gesture_multi_press_new(Xen widget) { #define H_gtk_gesture_multi_press_new "GtkGesture* gtk_gesture_multi_press_new(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_gesture_multi_press_new", "GtkWidget*"); return(C_to_Xen_GtkGesture_(gtk_gesture_multi_press_new(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_gesture_multi_press_set_area(Xen gesture, Xen rect) { #define H_gtk_gesture_multi_press_set_area "void gtk_gesture_multi_press_set_area(GtkGestureMultiPress* gesture, \ GdkRectangle* rect)" Xen_check_type(Xen_is_GtkGestureMultiPress_(gesture), gesture, 1, "gtk_gesture_multi_press_set_area", "GtkGestureMultiPress*"); Xen_check_type(Xen_is_GdkRectangle_(rect), rect, 2, "gtk_gesture_multi_press_set_area", "GdkRectangle*"); gtk_gesture_multi_press_set_area(Xen_to_C_GtkGestureMultiPress_(gesture), Xen_to_C_GdkRectangle_(rect)); return(Xen_false); } static Xen gxg_gtk_gesture_multi_press_get_area(Xen gesture, Xen rect) { #define H_gtk_gesture_multi_press_get_area "gboolean gtk_gesture_multi_press_get_area(GtkGestureMultiPress* gesture, \ GdkRectangle* rect)" Xen_check_type(Xen_is_GtkGestureMultiPress_(gesture), gesture, 1, "gtk_gesture_multi_press_get_area", "GtkGestureMultiPress*"); Xen_check_type(Xen_is_GdkRectangle_(rect), rect, 2, "gtk_gesture_multi_press_get_area", "GdkRectangle*"); return(C_to_Xen_gboolean(gtk_gesture_multi_press_get_area(Xen_to_C_GtkGestureMultiPress_(gesture), Xen_to_C_GdkRectangle_(rect)))); } static Xen gxg_gtk_gesture_rotate_new(Xen widget) { #define H_gtk_gesture_rotate_new "GtkGesture* gtk_gesture_rotate_new(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_gesture_rotate_new", "GtkWidget*"); return(C_to_Xen_GtkGesture_(gtk_gesture_rotate_new(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_gesture_rotate_get_angle_delta(Xen gesture) { #define H_gtk_gesture_rotate_get_angle_delta "gdouble gtk_gesture_rotate_get_angle_delta(GtkGestureRotate* gesture)" Xen_check_type(Xen_is_GtkGestureRotate_(gesture), gesture, 1, "gtk_gesture_rotate_get_angle_delta", "GtkGestureRotate*"); return(C_to_Xen_gdouble(gtk_gesture_rotate_get_angle_delta(Xen_to_C_GtkGestureRotate_(gesture)))); } static Xen gxg_gtk_gesture_single_get_touch_only(Xen gesture) { #define H_gtk_gesture_single_get_touch_only "gboolean gtk_gesture_single_get_touch_only(GtkGestureSingle* gesture)" Xen_check_type(Xen_is_GtkGestureSingle_(gesture), gesture, 1, "gtk_gesture_single_get_touch_only", "GtkGestureSingle*"); return(C_to_Xen_gboolean(gtk_gesture_single_get_touch_only(Xen_to_C_GtkGestureSingle_(gesture)))); } static Xen gxg_gtk_gesture_single_set_touch_only(Xen gesture, Xen touch_only) { #define H_gtk_gesture_single_set_touch_only "void gtk_gesture_single_set_touch_only(GtkGestureSingle* gesture, \ gboolean touch_only)" Xen_check_type(Xen_is_GtkGestureSingle_(gesture), gesture, 1, "gtk_gesture_single_set_touch_only", "GtkGestureSingle*"); Xen_check_type(Xen_is_gboolean(touch_only), touch_only, 2, "gtk_gesture_single_set_touch_only", "gboolean"); gtk_gesture_single_set_touch_only(Xen_to_C_GtkGestureSingle_(gesture), Xen_to_C_gboolean(touch_only)); return(Xen_false); } static Xen gxg_gtk_gesture_single_get_exclusive(Xen gesture) { #define H_gtk_gesture_single_get_exclusive "gboolean gtk_gesture_single_get_exclusive(GtkGestureSingle* gesture)" Xen_check_type(Xen_is_GtkGestureSingle_(gesture), gesture, 1, "gtk_gesture_single_get_exclusive", "GtkGestureSingle*"); return(C_to_Xen_gboolean(gtk_gesture_single_get_exclusive(Xen_to_C_GtkGestureSingle_(gesture)))); } static Xen gxg_gtk_gesture_single_set_exclusive(Xen gesture, Xen exclusive) { #define H_gtk_gesture_single_set_exclusive "void gtk_gesture_single_set_exclusive(GtkGestureSingle* gesture, \ gboolean exclusive)" Xen_check_type(Xen_is_GtkGestureSingle_(gesture), gesture, 1, "gtk_gesture_single_set_exclusive", "GtkGestureSingle*"); Xen_check_type(Xen_is_gboolean(exclusive), exclusive, 2, "gtk_gesture_single_set_exclusive", "gboolean"); gtk_gesture_single_set_exclusive(Xen_to_C_GtkGestureSingle_(gesture), Xen_to_C_gboolean(exclusive)); return(Xen_false); } static Xen gxg_gtk_gesture_single_get_button(Xen gesture) { #define H_gtk_gesture_single_get_button "guint gtk_gesture_single_get_button(GtkGestureSingle* gesture)" Xen_check_type(Xen_is_GtkGestureSingle_(gesture), gesture, 1, "gtk_gesture_single_get_button", "GtkGestureSingle*"); return(C_to_Xen_guint(gtk_gesture_single_get_button(Xen_to_C_GtkGestureSingle_(gesture)))); } static Xen gxg_gtk_gesture_single_set_button(Xen gesture, Xen button) { #define H_gtk_gesture_single_set_button "void gtk_gesture_single_set_button(GtkGestureSingle* gesture, \ guint button)" Xen_check_type(Xen_is_GtkGestureSingle_(gesture), gesture, 1, "gtk_gesture_single_set_button", "GtkGestureSingle*"); Xen_check_type(Xen_is_guint(button), button, 2, "gtk_gesture_single_set_button", "guint"); gtk_gesture_single_set_button(Xen_to_C_GtkGestureSingle_(gesture), Xen_to_C_guint(button)); return(Xen_false); } static Xen gxg_gtk_gesture_single_get_current_button(Xen gesture) { #define H_gtk_gesture_single_get_current_button "guint gtk_gesture_single_get_current_button(GtkGestureSingle* gesture)" Xen_check_type(Xen_is_GtkGestureSingle_(gesture), gesture, 1, "gtk_gesture_single_get_current_button", "GtkGestureSingle*"); return(C_to_Xen_guint(gtk_gesture_single_get_current_button(Xen_to_C_GtkGestureSingle_(gesture)))); } static Xen gxg_gtk_gesture_single_get_current_sequence(Xen gesture) { #define H_gtk_gesture_single_get_current_sequence "GdkEventSequence* gtk_gesture_single_get_current_sequence(GtkGestureSingle* gesture)" Xen_check_type(Xen_is_GtkGestureSingle_(gesture), gesture, 1, "gtk_gesture_single_get_current_sequence", "GtkGestureSingle*"); return(C_to_Xen_GdkEventSequence_(gtk_gesture_single_get_current_sequence(Xen_to_C_GtkGestureSingle_(gesture)))); } static Xen gxg_gtk_gesture_swipe_new(Xen widget) { #define H_gtk_gesture_swipe_new "GtkGesture* gtk_gesture_swipe_new(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_gesture_swipe_new", "GtkWidget*"); return(C_to_Xen_GtkGesture_(gtk_gesture_swipe_new(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_gesture_swipe_get_velocity(Xen gesture, Xen ignore_velocity_x, Xen ignore_velocity_y) { #define H_gtk_gesture_swipe_get_velocity "gboolean gtk_gesture_swipe_get_velocity(GtkGestureSwipe* gesture, \ gdouble* [velocity_x], gdouble* [velocity_y])" gdouble ref_velocity_x; gdouble ref_velocity_y; Xen_check_type(Xen_is_GtkGestureSwipe_(gesture), gesture, 1, "gtk_gesture_swipe_get_velocity", "GtkGestureSwipe*"); { Xen result; result = C_to_Xen_gboolean(gtk_gesture_swipe_get_velocity(Xen_to_C_GtkGestureSwipe_(gesture), &ref_velocity_x, &ref_velocity_y)); return(Xen_list_3(result, C_to_Xen_gdouble(ref_velocity_x), C_to_Xen_gdouble(ref_velocity_y))); } } static Xen gxg_gtk_gesture_zoom_new(Xen widget) { #define H_gtk_gesture_zoom_new "GtkGesture* gtk_gesture_zoom_new(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_gesture_zoom_new", "GtkWidget*"); return(C_to_Xen_GtkGesture_(gtk_gesture_zoom_new(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_gesture_zoom_get_scale_delta(Xen gesture) { #define H_gtk_gesture_zoom_get_scale_delta "gdouble gtk_gesture_zoom_get_scale_delta(GtkGestureZoom* gesture)" Xen_check_type(Xen_is_GtkGestureZoom_(gesture), gesture, 1, "gtk_gesture_zoom_get_scale_delta", "GtkGestureZoom*"); return(C_to_Xen_gdouble(gtk_gesture_zoom_get_scale_delta(Xen_to_C_GtkGestureZoom_(gesture)))); } static Xen gxg_gtk_event_controller_get_widget(Xen controller) { #define H_gtk_event_controller_get_widget "GtkWidget* gtk_event_controller_get_widget(GtkEventController* controller)" Xen_check_type(Xen_is_GtkEventController_(controller), controller, 1, "gtk_event_controller_get_widget", "GtkEventController*"); return(C_to_Xen_GtkWidget_(gtk_event_controller_get_widget(Xen_to_C_GtkEventController_(controller)))); } static Xen gxg_gtk_event_controller_handle_event(Xen controller, Xen event) { #define H_gtk_event_controller_handle_event "gboolean gtk_event_controller_handle_event(GtkEventController* controller, \ GdkEvent* event)" Xen_check_type(Xen_is_GtkEventController_(controller), controller, 1, "gtk_event_controller_handle_event", "GtkEventController*"); Xen_check_type(Xen_is_GdkEvent_(event), event, 2, "gtk_event_controller_handle_event", "GdkEvent*"); return(C_to_Xen_gboolean(gtk_event_controller_handle_event(Xen_to_C_GtkEventController_(controller), Xen_to_C_GdkEvent_(event)))); } static Xen gxg_gtk_event_controller_reset(Xen controller) { #define H_gtk_event_controller_reset "void gtk_event_controller_reset(GtkEventController* controller)" Xen_check_type(Xen_is_GtkEventController_(controller), controller, 1, "gtk_event_controller_reset", "GtkEventController*"); gtk_event_controller_reset(Xen_to_C_GtkEventController_(controller)); return(Xen_false); } static Xen gxg_gtk_event_controller_get_propagation_phase(Xen controller) { #define H_gtk_event_controller_get_propagation_phase "GtkPropagationPhase gtk_event_controller_get_propagation_phase(GtkEventController* controller)" Xen_check_type(Xen_is_GtkEventController_(controller), controller, 1, "gtk_event_controller_get_propagation_phase", "GtkEventController*"); return(C_to_Xen_GtkPropagationPhase(gtk_event_controller_get_propagation_phase(Xen_to_C_GtkEventController_(controller)))); } static Xen gxg_gtk_event_controller_set_propagation_phase(Xen controller, Xen phase) { #define H_gtk_event_controller_set_propagation_phase "void gtk_event_controller_set_propagation_phase(GtkEventController* controller, \ GtkPropagationPhase phase)" Xen_check_type(Xen_is_GtkEventController_(controller), controller, 1, "gtk_event_controller_set_propagation_phase", "GtkEventController*"); Xen_check_type(Xen_is_GtkPropagationPhase(phase), phase, 2, "gtk_event_controller_set_propagation_phase", "GtkPropagationPhase"); gtk_event_controller_set_propagation_phase(Xen_to_C_GtkEventController_(controller), Xen_to_C_GtkPropagationPhase(phase)); return(Xen_false); } static Xen gxg_gtk_icon_theme_add_resource_path(Xen icon_theme, Xen path) { #define H_gtk_icon_theme_add_resource_path "void gtk_icon_theme_add_resource_path(GtkIconTheme* icon_theme, \ gchar* path)" Xen_check_type(Xen_is_GtkIconTheme_(icon_theme), icon_theme, 1, "gtk_icon_theme_add_resource_path", "GtkIconTheme*"); Xen_check_type(Xen_is_gchar_(path), path, 2, "gtk_icon_theme_add_resource_path", "gchar*"); gtk_icon_theme_add_resource_path(Xen_to_C_GtkIconTheme_(icon_theme), (const gchar*)Xen_to_C_gchar_(path)); return(Xen_false); } static Xen gxg_gtk_list_box_row_set_activatable(Xen row, Xen activatable) { #define H_gtk_list_box_row_set_activatable "void gtk_list_box_row_set_activatable(GtkListBoxRow* row, \ gboolean activatable)" Xen_check_type(Xen_is_GtkListBoxRow_(row), row, 1, "gtk_list_box_row_set_activatable", "GtkListBoxRow*"); Xen_check_type(Xen_is_gboolean(activatable), activatable, 2, "gtk_list_box_row_set_activatable", "gboolean"); gtk_list_box_row_set_activatable(Xen_to_C_GtkListBoxRow_(row), Xen_to_C_gboolean(activatable)); return(Xen_false); } static Xen gxg_gtk_list_box_row_get_activatable(Xen row) { #define H_gtk_list_box_row_get_activatable "gboolean gtk_list_box_row_get_activatable(GtkListBoxRow* row)" Xen_check_type(Xen_is_GtkListBoxRow_(row), row, 1, "gtk_list_box_row_get_activatable", "GtkListBoxRow*"); return(C_to_Xen_gboolean(gtk_list_box_row_get_activatable(Xen_to_C_GtkListBoxRow_(row)))); } static Xen gxg_gtk_list_box_row_set_selectable(Xen row, Xen selectable) { #define H_gtk_list_box_row_set_selectable "void gtk_list_box_row_set_selectable(GtkListBoxRow* row, \ gboolean selectable)" Xen_check_type(Xen_is_GtkListBoxRow_(row), row, 1, "gtk_list_box_row_set_selectable", "GtkListBoxRow*"); Xen_check_type(Xen_is_gboolean(selectable), selectable, 2, "gtk_list_box_row_set_selectable", "gboolean"); gtk_list_box_row_set_selectable(Xen_to_C_GtkListBoxRow_(row), Xen_to_C_gboolean(selectable)); return(Xen_false); } static Xen gxg_gtk_list_box_row_get_selectable(Xen row) { #define H_gtk_list_box_row_get_selectable "gboolean gtk_list_box_row_get_selectable(GtkListBoxRow* row)" Xen_check_type(Xen_is_GtkListBoxRow_(row), row, 1, "gtk_list_box_row_get_selectable", "GtkListBoxRow*"); return(C_to_Xen_gboolean(gtk_list_box_row_get_selectable(Xen_to_C_GtkListBoxRow_(row)))); } static Xen gxg_gtk_widget_path_iter_get_state(Xen path, Xen pos) { #define H_gtk_widget_path_iter_get_state "GtkStateFlags gtk_widget_path_iter_get_state(GtkWidgetPath* path, \ gint pos)" Xen_check_type(Xen_is_GtkWidgetPath_(path), path, 1, "gtk_widget_path_iter_get_state", "GtkWidgetPath*"); Xen_check_type(Xen_is_gint(pos), pos, 2, "gtk_widget_path_iter_get_state", "gint"); return(C_to_Xen_GtkStateFlags(gtk_widget_path_iter_get_state(Xen_to_C_GtkWidgetPath_(path), Xen_to_C_gint(pos)))); } static Xen gxg_gtk_widget_path_iter_set_state(Xen path, Xen pos, Xen state) { #define H_gtk_widget_path_iter_set_state "void gtk_widget_path_iter_set_state(GtkWidgetPath* path, \ gint pos, GtkStateFlags state)" Xen_check_type(Xen_is_GtkWidgetPath_(path), path, 1, "gtk_widget_path_iter_set_state", "GtkWidgetPath*"); Xen_check_type(Xen_is_gint(pos), pos, 2, "gtk_widget_path_iter_set_state", "gint"); Xen_check_type(Xen_is_GtkStateFlags(state), state, 3, "gtk_widget_path_iter_set_state", "GtkStateFlags"); gtk_widget_path_iter_set_state(Xen_to_C_GtkWidgetPath_(path), Xen_to_C_gint(pos), Xen_to_C_GtkStateFlags(state)); return(Xen_false); } #endif #if GTK_CHECK_VERSION(3, 16, 0) static Xen gxg_gdk_cairo_draw_from_gl(Xen arglist) { #define H_gdk_cairo_draw_from_gl "void gdk_cairo_draw_from_gl(cairo_t* cr, GdkWindow* window, int source, \ int source_type, int buffer_scale, int x, int y, int width, int height)" Xen cr, window, source, source_type, buffer_scale, x, y, width, height; cr = Xen_list_ref(arglist, 0); window = Xen_list_ref(arglist, 1); source = Xen_list_ref(arglist, 2); source_type = Xen_list_ref(arglist, 3); buffer_scale = Xen_list_ref(arglist, 4); x = Xen_list_ref(arglist, 5); y = Xen_list_ref(arglist, 6); width = Xen_list_ref(arglist, 7); height = Xen_list_ref(arglist, 8); Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "gdk_cairo_draw_from_gl", "cairo_t*"); Xen_check_type(Xen_is_GdkWindow_(window), window, 2, "gdk_cairo_draw_from_gl", "GdkWindow*"); Xen_check_type(Xen_is_int(source), source, 3, "gdk_cairo_draw_from_gl", "int"); Xen_check_type(Xen_is_int(source_type), source_type, 4, "gdk_cairo_draw_from_gl", "int"); Xen_check_type(Xen_is_int(buffer_scale), buffer_scale, 5, "gdk_cairo_draw_from_gl", "int"); Xen_check_type(Xen_is_int(x), x, 6, "gdk_cairo_draw_from_gl", "int"); Xen_check_type(Xen_is_int(y), y, 7, "gdk_cairo_draw_from_gl", "int"); Xen_check_type(Xen_is_int(width), width, 8, "gdk_cairo_draw_from_gl", "int"); Xen_check_type(Xen_is_int(height), height, 9, "gdk_cairo_draw_from_gl", "int"); gdk_cairo_draw_from_gl(Xen_to_C_cairo_t_(cr), Xen_to_C_GdkWindow_(window), Xen_to_C_int(source), Xen_to_C_int(source_type), Xen_to_C_int(buffer_scale), Xen_to_C_int(x), Xen_to_C_int(y), Xen_to_C_int(width), Xen_to_C_int(height)); return(Xen_false); } static Xen gxg_gdk_window_mark_paint_from_clip(Xen window, Xen cr) { #define H_gdk_window_mark_paint_from_clip "void gdk_window_mark_paint_from_clip(GdkWindow* window, \ cairo_t* cr)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_mark_paint_from_clip", "GdkWindow*"); Xen_check_type(Xen_is_cairo_t_(cr), cr, 2, "gdk_window_mark_paint_from_clip", "cairo_t*"); gdk_window_mark_paint_from_clip(Xen_to_C_GdkWindow_(window), Xen_to_C_cairo_t_(cr)); return(Xen_false); } static Xen gxg_gtk_label_set_xalign(Xen label, Xen xalign) { #define H_gtk_label_set_xalign "void gtk_label_set_xalign(GtkLabel* label, gfloat xalign)" Xen_check_type(Xen_is_GtkLabel_(label), label, 1, "gtk_label_set_xalign", "GtkLabel*"); Xen_check_type(Xen_is_gfloat(xalign), xalign, 2, "gtk_label_set_xalign", "gfloat"); gtk_label_set_xalign(Xen_to_C_GtkLabel_(label), Xen_to_C_gfloat(xalign)); return(Xen_false); } static Xen gxg_gtk_label_get_xalign(Xen label) { #define H_gtk_label_get_xalign "gfloat gtk_label_get_xalign(GtkLabel* label)" Xen_check_type(Xen_is_GtkLabel_(label), label, 1, "gtk_label_get_xalign", "GtkLabel*"); return(C_to_Xen_gfloat(gtk_label_get_xalign(Xen_to_C_GtkLabel_(label)))); } static Xen gxg_gtk_label_set_yalign(Xen label, Xen xalign) { #define H_gtk_label_set_yalign "void gtk_label_set_yalign(GtkLabel* label, gfloat xalign)" Xen_check_type(Xen_is_GtkLabel_(label), label, 1, "gtk_label_set_yalign", "GtkLabel*"); Xen_check_type(Xen_is_gfloat(xalign), xalign, 2, "gtk_label_set_yalign", "gfloat"); gtk_label_set_yalign(Xen_to_C_GtkLabel_(label), Xen_to_C_gfloat(xalign)); return(Xen_false); } static Xen gxg_gtk_label_get_yalign(Xen label) { #define H_gtk_label_get_yalign "gfloat gtk_label_get_yalign(GtkLabel* label)" Xen_check_type(Xen_is_GtkLabel_(label), label, 1, "gtk_label_get_yalign", "GtkLabel*"); return(C_to_Xen_gfloat(gtk_label_get_yalign(Xen_to_C_GtkLabel_(label)))); } static Xen gxg_gtk_paned_set_wide_handle(Xen paned, Xen wide) { #define H_gtk_paned_set_wide_handle "void gtk_paned_set_wide_handle(GtkPaned* paned, gboolean wide)" Xen_check_type(Xen_is_GtkPaned_(paned), paned, 1, "gtk_paned_set_wide_handle", "GtkPaned*"); Xen_check_type(Xen_is_gboolean(wide), wide, 2, "gtk_paned_set_wide_handle", "gboolean"); gtk_paned_set_wide_handle(Xen_to_C_GtkPaned_(paned), Xen_to_C_gboolean(wide)); return(Xen_false); } static Xen gxg_gtk_paned_get_wide_handle(Xen paned) { #define H_gtk_paned_get_wide_handle "gboolean gtk_paned_get_wide_handle(GtkPaned* paned)" Xen_check_type(Xen_is_GtkPaned_(paned), paned, 1, "gtk_paned_get_wide_handle", "GtkPaned*"); return(C_to_Xen_gboolean(gtk_paned_get_wide_handle(Xen_to_C_GtkPaned_(paned)))); } static Xen gxg_gtk_scrolled_window_set_overlay_scrolling(Xen scrolled_window, Xen overlay_scrolling) { #define H_gtk_scrolled_window_set_overlay_scrolling "void gtk_scrolled_window_set_overlay_scrolling(GtkScrolledWindow* scrolled_window, \ gboolean overlay_scrolling)" Xen_check_type(Xen_is_GtkScrolledWindow_(scrolled_window), scrolled_window, 1, "gtk_scrolled_window_set_overlay_scrolling", "GtkScrolledWindow*"); Xen_check_type(Xen_is_gboolean(overlay_scrolling), overlay_scrolling, 2, "gtk_scrolled_window_set_overlay_scrolling", "gboolean"); gtk_scrolled_window_set_overlay_scrolling(Xen_to_C_GtkScrolledWindow_(scrolled_window), Xen_to_C_gboolean(overlay_scrolling)); return(Xen_false); } static Xen gxg_gtk_scrolled_window_get_overlay_scrolling(Xen scrolled_window) { #define H_gtk_scrolled_window_get_overlay_scrolling "gboolean gtk_scrolled_window_get_overlay_scrolling(GtkScrolledWindow* scrolled_window)" Xen_check_type(Xen_is_GtkScrolledWindow_(scrolled_window), scrolled_window, 1, "gtk_scrolled_window_get_overlay_scrolling", "GtkScrolledWindow*"); return(C_to_Xen_gboolean(gtk_scrolled_window_get_overlay_scrolling(Xen_to_C_GtkScrolledWindow_(scrolled_window)))); } static Xen gxg_gtk_text_view_set_monospace(Xen text_view, Xen monospace) { #define H_gtk_text_view_set_monospace "void gtk_text_view_set_monospace(GtkTextView* text_view, gboolean monospace)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_set_monospace", "GtkTextView*"); Xen_check_type(Xen_is_gboolean(monospace), monospace, 2, "gtk_text_view_set_monospace", "gboolean"); gtk_text_view_set_monospace(Xen_to_C_GtkTextView_(text_view), Xen_to_C_gboolean(monospace)); return(Xen_false); } static Xen gxg_gtk_text_view_get_monospace(Xen text_view) { #define H_gtk_text_view_get_monospace "gboolean gtk_text_view_get_monospace(GtkTextView* text_view)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_get_monospace", "GtkTextView*"); return(C_to_Xen_gboolean(gtk_text_view_get_monospace(Xen_to_C_GtkTextView_(text_view)))); } static Xen gxg_gtk_window_get_titlebar(Xen window) { #define H_gtk_window_get_titlebar "GtkWidget* gtk_window_get_titlebar(GtkWindow* window)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_get_titlebar", "GtkWindow*"); return(C_to_Xen_GtkWidget_(gtk_window_get_titlebar(Xen_to_C_GtkWindow_(window)))); } static Xen gxg_gtk_gl_area_new(void) { #define H_gtk_gl_area_new "GtkWidget* gtk_gl_area_new( void)" return(C_to_Xen_GtkWidget_(gtk_gl_area_new())); } static Xen gxg_gtk_gl_area_get_has_alpha(Xen area) { #define H_gtk_gl_area_get_has_alpha "gboolean gtk_gl_area_get_has_alpha(GtkGLArea* area)" Xen_check_type(Xen_is_GtkGLArea_(area), area, 1, "gtk_gl_area_get_has_alpha", "GtkGLArea*"); return(C_to_Xen_gboolean(gtk_gl_area_get_has_alpha(Xen_to_C_GtkGLArea_(area)))); } static Xen gxg_gtk_gl_area_set_has_alpha(Xen area, Xen has_alpha) { #define H_gtk_gl_area_set_has_alpha "void gtk_gl_area_set_has_alpha(GtkGLArea* area, gboolean has_alpha)" Xen_check_type(Xen_is_GtkGLArea_(area), area, 1, "gtk_gl_area_set_has_alpha", "GtkGLArea*"); Xen_check_type(Xen_is_gboolean(has_alpha), has_alpha, 2, "gtk_gl_area_set_has_alpha", "gboolean"); gtk_gl_area_set_has_alpha(Xen_to_C_GtkGLArea_(area), Xen_to_C_gboolean(has_alpha)); return(Xen_false); } static Xen gxg_gtk_gl_area_get_has_depth_buffer(Xen area) { #define H_gtk_gl_area_get_has_depth_buffer "gboolean gtk_gl_area_get_has_depth_buffer(GtkGLArea* area)" Xen_check_type(Xen_is_GtkGLArea_(area), area, 1, "gtk_gl_area_get_has_depth_buffer", "GtkGLArea*"); return(C_to_Xen_gboolean(gtk_gl_area_get_has_depth_buffer(Xen_to_C_GtkGLArea_(area)))); } static Xen gxg_gtk_gl_area_set_has_depth_buffer(Xen area, Xen has_depth_buffer) { #define H_gtk_gl_area_set_has_depth_buffer "void gtk_gl_area_set_has_depth_buffer(GtkGLArea* area, \ gboolean has_depth_buffer)" Xen_check_type(Xen_is_GtkGLArea_(area), area, 1, "gtk_gl_area_set_has_depth_buffer", "GtkGLArea*"); Xen_check_type(Xen_is_gboolean(has_depth_buffer), has_depth_buffer, 2, "gtk_gl_area_set_has_depth_buffer", "gboolean"); gtk_gl_area_set_has_depth_buffer(Xen_to_C_GtkGLArea_(area), Xen_to_C_gboolean(has_depth_buffer)); return(Xen_false); } static Xen gxg_gtk_gl_area_get_context(Xen area) { #define H_gtk_gl_area_get_context "GdkGLContext* gtk_gl_area_get_context(GtkGLArea* area)" Xen_check_type(Xen_is_GtkGLArea_(area), area, 1, "gtk_gl_area_get_context", "GtkGLArea*"); return(C_to_Xen_GdkGLContext_(gtk_gl_area_get_context(Xen_to_C_GtkGLArea_(area)))); } static Xen gxg_gtk_gl_area_make_current(Xen area) { #define H_gtk_gl_area_make_current "void gtk_gl_area_make_current(GtkGLArea* area)" Xen_check_type(Xen_is_GtkGLArea_(area), area, 1, "gtk_gl_area_make_current", "GtkGLArea*"); gtk_gl_area_make_current(Xen_to_C_GtkGLArea_(area)); return(Xen_false); } static Xen gxg_gtk_render_check(Xen context, Xen cr, Xen x, Xen y, Xen width, Xen height) { #define H_gtk_render_check "void gtk_render_check(GtkStyleContext* context, cairo_t* cr, gdouble x, \ gdouble y, gdouble width, gdouble height)" Xen_check_type(Xen_is_GtkStyleContext_(context), context, 1, "gtk_render_check", "GtkStyleContext*"); Xen_check_type(Xen_is_cairo_t_(cr), cr, 2, "gtk_render_check", "cairo_t*"); Xen_check_type(Xen_is_gdouble(x), x, 3, "gtk_render_check", "gdouble"); Xen_check_type(Xen_is_gdouble(y), y, 4, "gtk_render_check", "gdouble"); Xen_check_type(Xen_is_gdouble(width), width, 5, "gtk_render_check", "gdouble"); Xen_check_type(Xen_is_gdouble(height), height, 6, "gtk_render_check", "gdouble"); gtk_render_check(Xen_to_C_GtkStyleContext_(context), Xen_to_C_cairo_t_(cr), Xen_to_C_gdouble(x), Xen_to_C_gdouble(y), Xen_to_C_gdouble(width), Xen_to_C_gdouble(height)); return(Xen_false); } static Xen gxg_gtk_render_option(Xen context, Xen cr, Xen x, Xen y, Xen width, Xen height) { #define H_gtk_render_option "void gtk_render_option(GtkStyleContext* context, cairo_t* cr, gdouble x, \ gdouble y, gdouble width, gdouble height)" Xen_check_type(Xen_is_GtkStyleContext_(context), context, 1, "gtk_render_option", "GtkStyleContext*"); Xen_check_type(Xen_is_cairo_t_(cr), cr, 2, "gtk_render_option", "cairo_t*"); Xen_check_type(Xen_is_gdouble(x), x, 3, "gtk_render_option", "gdouble"); Xen_check_type(Xen_is_gdouble(y), y, 4, "gtk_render_option", "gdouble"); Xen_check_type(Xen_is_gdouble(width), width, 5, "gtk_render_option", "gdouble"); Xen_check_type(Xen_is_gdouble(height), height, 6, "gtk_render_option", "gdouble"); gtk_render_option(Xen_to_C_GtkStyleContext_(context), Xen_to_C_cairo_t_(cr), Xen_to_C_gdouble(x), Xen_to_C_gdouble(y), Xen_to_C_gdouble(width), Xen_to_C_gdouble(height)); return(Xen_false); } static Xen gxg_gtk_render_arrow(Xen context, Xen cr, Xen angle, Xen x, Xen y, Xen size) { #define H_gtk_render_arrow "void gtk_render_arrow(GtkStyleContext* context, cairo_t* cr, gdouble angle, \ gdouble x, gdouble y, gdouble size)" Xen_check_type(Xen_is_GtkStyleContext_(context), context, 1, "gtk_render_arrow", "GtkStyleContext*"); Xen_check_type(Xen_is_cairo_t_(cr), cr, 2, "gtk_render_arrow", "cairo_t*"); Xen_check_type(Xen_is_gdouble(angle), angle, 3, "gtk_render_arrow", "gdouble"); Xen_check_type(Xen_is_gdouble(x), x, 4, "gtk_render_arrow", "gdouble"); Xen_check_type(Xen_is_gdouble(y), y, 5, "gtk_render_arrow", "gdouble"); Xen_check_type(Xen_is_gdouble(size), size, 6, "gtk_render_arrow", "gdouble"); gtk_render_arrow(Xen_to_C_GtkStyleContext_(context), Xen_to_C_cairo_t_(cr), Xen_to_C_gdouble(angle), Xen_to_C_gdouble(x), Xen_to_C_gdouble(y), Xen_to_C_gdouble(size)); return(Xen_false); } static Xen gxg_gtk_render_background(Xen context, Xen cr, Xen x, Xen y, Xen width, Xen height) { #define H_gtk_render_background "void gtk_render_background(GtkStyleContext* context, cairo_t* cr, \ gdouble x, gdouble y, gdouble width, gdouble height)" Xen_check_type(Xen_is_GtkStyleContext_(context), context, 1, "gtk_render_background", "GtkStyleContext*"); Xen_check_type(Xen_is_cairo_t_(cr), cr, 2, "gtk_render_background", "cairo_t*"); Xen_check_type(Xen_is_gdouble(x), x, 3, "gtk_render_background", "gdouble"); Xen_check_type(Xen_is_gdouble(y), y, 4, "gtk_render_background", "gdouble"); Xen_check_type(Xen_is_gdouble(width), width, 5, "gtk_render_background", "gdouble"); Xen_check_type(Xen_is_gdouble(height), height, 6, "gtk_render_background", "gdouble"); gtk_render_background(Xen_to_C_GtkStyleContext_(context), Xen_to_C_cairo_t_(cr), Xen_to_C_gdouble(x), Xen_to_C_gdouble(y), Xen_to_C_gdouble(width), Xen_to_C_gdouble(height)); return(Xen_false); } static Xen gxg_gtk_render_frame(Xen context, Xen cr, Xen x, Xen y, Xen width, Xen height) { #define H_gtk_render_frame "void gtk_render_frame(GtkStyleContext* context, cairo_t* cr, gdouble x, \ gdouble y, gdouble width, gdouble height)" Xen_check_type(Xen_is_GtkStyleContext_(context), context, 1, "gtk_render_frame", "GtkStyleContext*"); Xen_check_type(Xen_is_cairo_t_(cr), cr, 2, "gtk_render_frame", "cairo_t*"); Xen_check_type(Xen_is_gdouble(x), x, 3, "gtk_render_frame", "gdouble"); Xen_check_type(Xen_is_gdouble(y), y, 4, "gtk_render_frame", "gdouble"); Xen_check_type(Xen_is_gdouble(width), width, 5, "gtk_render_frame", "gdouble"); Xen_check_type(Xen_is_gdouble(height), height, 6, "gtk_render_frame", "gdouble"); gtk_render_frame(Xen_to_C_GtkStyleContext_(context), Xen_to_C_cairo_t_(cr), Xen_to_C_gdouble(x), Xen_to_C_gdouble(y), Xen_to_C_gdouble(width), Xen_to_C_gdouble(height)); return(Xen_false); } static Xen gxg_gtk_render_expander(Xen context, Xen cr, Xen x, Xen y, Xen width, Xen height) { #define H_gtk_render_expander "void gtk_render_expander(GtkStyleContext* context, cairo_t* cr, gdouble x, \ gdouble y, gdouble width, gdouble height)" Xen_check_type(Xen_is_GtkStyleContext_(context), context, 1, "gtk_render_expander", "GtkStyleContext*"); Xen_check_type(Xen_is_cairo_t_(cr), cr, 2, "gtk_render_expander", "cairo_t*"); Xen_check_type(Xen_is_gdouble(x), x, 3, "gtk_render_expander", "gdouble"); Xen_check_type(Xen_is_gdouble(y), y, 4, "gtk_render_expander", "gdouble"); Xen_check_type(Xen_is_gdouble(width), width, 5, "gtk_render_expander", "gdouble"); Xen_check_type(Xen_is_gdouble(height), height, 6, "gtk_render_expander", "gdouble"); gtk_render_expander(Xen_to_C_GtkStyleContext_(context), Xen_to_C_cairo_t_(cr), Xen_to_C_gdouble(x), Xen_to_C_gdouble(y), Xen_to_C_gdouble(width), Xen_to_C_gdouble(height)); return(Xen_false); } static Xen gxg_gtk_render_focus(Xen context, Xen cr, Xen x, Xen y, Xen width, Xen height) { #define H_gtk_render_focus "void gtk_render_focus(GtkStyleContext* context, cairo_t* cr, gdouble x, \ gdouble y, gdouble width, gdouble height)" Xen_check_type(Xen_is_GtkStyleContext_(context), context, 1, "gtk_render_focus", "GtkStyleContext*"); Xen_check_type(Xen_is_cairo_t_(cr), cr, 2, "gtk_render_focus", "cairo_t*"); Xen_check_type(Xen_is_gdouble(x), x, 3, "gtk_render_focus", "gdouble"); Xen_check_type(Xen_is_gdouble(y), y, 4, "gtk_render_focus", "gdouble"); Xen_check_type(Xen_is_gdouble(width), width, 5, "gtk_render_focus", "gdouble"); Xen_check_type(Xen_is_gdouble(height), height, 6, "gtk_render_focus", "gdouble"); gtk_render_focus(Xen_to_C_GtkStyleContext_(context), Xen_to_C_cairo_t_(cr), Xen_to_C_gdouble(x), Xen_to_C_gdouble(y), Xen_to_C_gdouble(width), Xen_to_C_gdouble(height)); return(Xen_false); } static Xen gxg_gtk_render_layout(Xen context, Xen cr, Xen x, Xen y, Xen layout) { #define H_gtk_render_layout "void gtk_render_layout(GtkStyleContext* context, cairo_t* cr, gdouble x, \ gdouble y, PangoLayout* layout)" Xen_check_type(Xen_is_GtkStyleContext_(context), context, 1, "gtk_render_layout", "GtkStyleContext*"); Xen_check_type(Xen_is_cairo_t_(cr), cr, 2, "gtk_render_layout", "cairo_t*"); Xen_check_type(Xen_is_gdouble(x), x, 3, "gtk_render_layout", "gdouble"); Xen_check_type(Xen_is_gdouble(y), y, 4, "gtk_render_layout", "gdouble"); Xen_check_type(Xen_is_PangoLayout_(layout), layout, 5, "gtk_render_layout", "PangoLayout*"); gtk_render_layout(Xen_to_C_GtkStyleContext_(context), Xen_to_C_cairo_t_(cr), Xen_to_C_gdouble(x), Xen_to_C_gdouble(y), Xen_to_C_PangoLayout_(layout)); return(Xen_false); } static Xen gxg_gtk_render_line(Xen context, Xen cr, Xen x0, Xen y0, Xen x1, Xen y1) { #define H_gtk_render_line "void gtk_render_line(GtkStyleContext* context, cairo_t* cr, gdouble x0, \ gdouble y0, gdouble x1, gdouble y1)" Xen_check_type(Xen_is_GtkStyleContext_(context), context, 1, "gtk_render_line", "GtkStyleContext*"); Xen_check_type(Xen_is_cairo_t_(cr), cr, 2, "gtk_render_line", "cairo_t*"); Xen_check_type(Xen_is_gdouble(x0), x0, 3, "gtk_render_line", "gdouble"); Xen_check_type(Xen_is_gdouble(y0), y0, 4, "gtk_render_line", "gdouble"); Xen_check_type(Xen_is_gdouble(x1), x1, 5, "gtk_render_line", "gdouble"); Xen_check_type(Xen_is_gdouble(y1), y1, 6, "gtk_render_line", "gdouble"); gtk_render_line(Xen_to_C_GtkStyleContext_(context), Xen_to_C_cairo_t_(cr), Xen_to_C_gdouble(x0), Xen_to_C_gdouble(y0), Xen_to_C_gdouble(x1), Xen_to_C_gdouble(y1)); return(Xen_false); } static Xen gxg_gtk_render_slider(Xen context, Xen cr, Xen x, Xen y, Xen width, Xen height, Xen orientation) { #define H_gtk_render_slider "void gtk_render_slider(GtkStyleContext* context, cairo_t* cr, gdouble x, \ gdouble y, gdouble width, gdouble height, GtkOrientation orientation)" Xen_check_type(Xen_is_GtkStyleContext_(context), context, 1, "gtk_render_slider", "GtkStyleContext*"); Xen_check_type(Xen_is_cairo_t_(cr), cr, 2, "gtk_render_slider", "cairo_t*"); Xen_check_type(Xen_is_gdouble(x), x, 3, "gtk_render_slider", "gdouble"); Xen_check_type(Xen_is_gdouble(y), y, 4, "gtk_render_slider", "gdouble"); Xen_check_type(Xen_is_gdouble(width), width, 5, "gtk_render_slider", "gdouble"); Xen_check_type(Xen_is_gdouble(height), height, 6, "gtk_render_slider", "gdouble"); Xen_check_type(Xen_is_GtkOrientation(orientation), orientation, 7, "gtk_render_slider", "GtkOrientation"); gtk_render_slider(Xen_to_C_GtkStyleContext_(context), Xen_to_C_cairo_t_(cr), Xen_to_C_gdouble(x), Xen_to_C_gdouble(y), Xen_to_C_gdouble(width), Xen_to_C_gdouble(height), Xen_to_C_GtkOrientation(orientation)); return(Xen_false); } static Xen gxg_gtk_render_frame_gap(Xen arglist) { #define H_gtk_render_frame_gap "void gtk_render_frame_gap(GtkStyleContext* context, cairo_t* cr, gdouble x, \ gdouble y, gdouble width, gdouble height, GtkPositionType gap_side, gdouble xy0_gap, gdouble xy1_gap)" Xen context, cr, x, y, width, height, gap_side, xy0_gap, xy1_gap; context = Xen_list_ref(arglist, 0); cr = Xen_list_ref(arglist, 1); x = Xen_list_ref(arglist, 2); y = Xen_list_ref(arglist, 3); width = Xen_list_ref(arglist, 4); height = Xen_list_ref(arglist, 5); gap_side = Xen_list_ref(arglist, 6); xy0_gap = Xen_list_ref(arglist, 7); xy1_gap = Xen_list_ref(arglist, 8); Xen_check_type(Xen_is_GtkStyleContext_(context), context, 1, "gtk_render_frame_gap", "GtkStyleContext*"); Xen_check_type(Xen_is_cairo_t_(cr), cr, 2, "gtk_render_frame_gap", "cairo_t*"); Xen_check_type(Xen_is_gdouble(x), x, 3, "gtk_render_frame_gap", "gdouble"); Xen_check_type(Xen_is_gdouble(y), y, 4, "gtk_render_frame_gap", "gdouble"); Xen_check_type(Xen_is_gdouble(width), width, 5, "gtk_render_frame_gap", "gdouble"); Xen_check_type(Xen_is_gdouble(height), height, 6, "gtk_render_frame_gap", "gdouble"); Xen_check_type(Xen_is_GtkPositionType(gap_side), gap_side, 7, "gtk_render_frame_gap", "GtkPositionType"); Xen_check_type(Xen_is_gdouble(xy0_gap), xy0_gap, 8, "gtk_render_frame_gap", "gdouble"); Xen_check_type(Xen_is_gdouble(xy1_gap), xy1_gap, 9, "gtk_render_frame_gap", "gdouble"); gtk_render_frame_gap(Xen_to_C_GtkStyleContext_(context), Xen_to_C_cairo_t_(cr), Xen_to_C_gdouble(x), Xen_to_C_gdouble(y), Xen_to_C_gdouble(width), Xen_to_C_gdouble(height), Xen_to_C_GtkPositionType(gap_side), Xen_to_C_gdouble(xy0_gap), Xen_to_C_gdouble(xy1_gap)); return(Xen_false); } static Xen gxg_gtk_render_extension(Xen context, Xen cr, Xen x, Xen y, Xen width, Xen height, Xen gap_side) { #define H_gtk_render_extension "void gtk_render_extension(GtkStyleContext* context, cairo_t* cr, gdouble x, \ gdouble y, gdouble width, gdouble height, GtkPositionType gap_side)" Xen_check_type(Xen_is_GtkStyleContext_(context), context, 1, "gtk_render_extension", "GtkStyleContext*"); Xen_check_type(Xen_is_cairo_t_(cr), cr, 2, "gtk_render_extension", "cairo_t*"); Xen_check_type(Xen_is_gdouble(x), x, 3, "gtk_render_extension", "gdouble"); Xen_check_type(Xen_is_gdouble(y), y, 4, "gtk_render_extension", "gdouble"); Xen_check_type(Xen_is_gdouble(width), width, 5, "gtk_render_extension", "gdouble"); Xen_check_type(Xen_is_gdouble(height), height, 6, "gtk_render_extension", "gdouble"); Xen_check_type(Xen_is_GtkPositionType(gap_side), gap_side, 7, "gtk_render_extension", "GtkPositionType"); gtk_render_extension(Xen_to_C_GtkStyleContext_(context), Xen_to_C_cairo_t_(cr), Xen_to_C_gdouble(x), Xen_to_C_gdouble(y), Xen_to_C_gdouble(width), Xen_to_C_gdouble(height), Xen_to_C_GtkPositionType(gap_side)); return(Xen_false); } static Xen gxg_gtk_render_handle(Xen context, Xen cr, Xen x, Xen y, Xen width, Xen height) { #define H_gtk_render_handle "void gtk_render_handle(GtkStyleContext* context, cairo_t* cr, gdouble x, \ gdouble y, gdouble width, gdouble height)" Xen_check_type(Xen_is_GtkStyleContext_(context), context, 1, "gtk_render_handle", "GtkStyleContext*"); Xen_check_type(Xen_is_cairo_t_(cr), cr, 2, "gtk_render_handle", "cairo_t*"); Xen_check_type(Xen_is_gdouble(x), x, 3, "gtk_render_handle", "gdouble"); Xen_check_type(Xen_is_gdouble(y), y, 4, "gtk_render_handle", "gdouble"); Xen_check_type(Xen_is_gdouble(width), width, 5, "gtk_render_handle", "gdouble"); Xen_check_type(Xen_is_gdouble(height), height, 6, "gtk_render_handle", "gdouble"); gtk_render_handle(Xen_to_C_GtkStyleContext_(context), Xen_to_C_cairo_t_(cr), Xen_to_C_gdouble(x), Xen_to_C_gdouble(y), Xen_to_C_gdouble(width), Xen_to_C_gdouble(height)); return(Xen_false); } static Xen gxg_gtk_render_activity(Xen context, Xen cr, Xen x, Xen y, Xen width, Xen height) { #define H_gtk_render_activity "void gtk_render_activity(GtkStyleContext* context, cairo_t* cr, gdouble x, \ gdouble y, gdouble width, gdouble height)" Xen_check_type(Xen_is_GtkStyleContext_(context), context, 1, "gtk_render_activity", "GtkStyleContext*"); Xen_check_type(Xen_is_cairo_t_(cr), cr, 2, "gtk_render_activity", "cairo_t*"); Xen_check_type(Xen_is_gdouble(x), x, 3, "gtk_render_activity", "gdouble"); Xen_check_type(Xen_is_gdouble(y), y, 4, "gtk_render_activity", "gdouble"); Xen_check_type(Xen_is_gdouble(width), width, 5, "gtk_render_activity", "gdouble"); Xen_check_type(Xen_is_gdouble(height), height, 6, "gtk_render_activity", "gdouble"); gtk_render_activity(Xen_to_C_GtkStyleContext_(context), Xen_to_C_cairo_t_(cr), Xen_to_C_gdouble(x), Xen_to_C_gdouble(y), Xen_to_C_gdouble(width), Xen_to_C_gdouble(height)); return(Xen_false); } static Xen gxg_gtk_render_icon(Xen context, Xen cr, Xen pixbuf, Xen x, Xen y) { #define H_gtk_render_icon "void gtk_render_icon(GtkStyleContext* context, cairo_t* cr, GdkPixbuf* pixbuf, \ gdouble x, gdouble y)" Xen_check_type(Xen_is_GtkStyleContext_(context), context, 1, "gtk_render_icon", "GtkStyleContext*"); Xen_check_type(Xen_is_cairo_t_(cr), cr, 2, "gtk_render_icon", "cairo_t*"); Xen_check_type(Xen_is_GdkPixbuf_(pixbuf), pixbuf, 3, "gtk_render_icon", "GdkPixbuf*"); Xen_check_type(Xen_is_gdouble(x), x, 4, "gtk_render_icon", "gdouble"); Xen_check_type(Xen_is_gdouble(y), y, 5, "gtk_render_icon", "gdouble"); gtk_render_icon(Xen_to_C_GtkStyleContext_(context), Xen_to_C_cairo_t_(cr), Xen_to_C_GdkPixbuf_(pixbuf), Xen_to_C_gdouble(x), Xen_to_C_gdouble(y)); return(Xen_false); } static Xen gxg_gtk_render_icon_surface(Xen context, Xen cr, Xen surface, Xen x, Xen y) { #define H_gtk_render_icon_surface "void gtk_render_icon_surface(GtkStyleContext* context, cairo_t* cr, \ cairo_surface_t* surface, gdouble x, gdouble y)" Xen_check_type(Xen_is_GtkStyleContext_(context), context, 1, "gtk_render_icon_surface", "GtkStyleContext*"); Xen_check_type(Xen_is_cairo_t_(cr), cr, 2, "gtk_render_icon_surface", "cairo_t*"); Xen_check_type(Xen_is_cairo_surface_t_(surface), surface, 3, "gtk_render_icon_surface", "cairo_surface_t*"); Xen_check_type(Xen_is_gdouble(x), x, 4, "gtk_render_icon_surface", "gdouble"); Xen_check_type(Xen_is_gdouble(y), y, 5, "gtk_render_icon_surface", "gdouble"); gtk_render_icon_surface(Xen_to_C_GtkStyleContext_(context), Xen_to_C_cairo_t_(cr), Xen_to_C_cairo_surface_t_(surface), Xen_to_C_gdouble(x), Xen_to_C_gdouble(y)); return(Xen_false); } static Xen gxg_gdk_gl_context_get_window(Xen context) { #define H_gdk_gl_context_get_window "GdkWindow* gdk_gl_context_get_window(GdkGLContext* context)" Xen_check_type(Xen_is_GdkGLContext_(context), context, 1, "gdk_gl_context_get_window", "GdkGLContext*"); return(C_to_Xen_GdkWindow_(gdk_gl_context_get_window(Xen_to_C_GdkGLContext_(context)))); } static Xen gxg_gdk_gl_context_make_current(Xen context) { #define H_gdk_gl_context_make_current "void gdk_gl_context_make_current(GdkGLContext* context)" Xen_check_type(Xen_is_GdkGLContext_(context), context, 1, "gdk_gl_context_make_current", "GdkGLContext*"); gdk_gl_context_make_current(Xen_to_C_GdkGLContext_(context)); return(Xen_false); } static Xen gxg_gdk_gl_context_get_current(void) { #define H_gdk_gl_context_get_current "GdkGLContext* gdk_gl_context_get_current( void)" return(C_to_Xen_GdkGLContext_(gdk_gl_context_get_current())); } static Xen gxg_gdk_gl_context_clear_current(void) { #define H_gdk_gl_context_clear_current "void gdk_gl_context_clear_current( void)" gdk_gl_context_clear_current(); return(Xen_false); } static Xen gxg_gtk_stack_set_hhomogeneous(Xen stack, Xen hhomogeneous) { #define H_gtk_stack_set_hhomogeneous "void gtk_stack_set_hhomogeneous(GtkStack* stack, gboolean hhomogeneous)" Xen_check_type(Xen_is_GtkStack_(stack), stack, 1, "gtk_stack_set_hhomogeneous", "GtkStack*"); Xen_check_type(Xen_is_gboolean(hhomogeneous), hhomogeneous, 2, "gtk_stack_set_hhomogeneous", "gboolean"); gtk_stack_set_hhomogeneous(Xen_to_C_GtkStack_(stack), Xen_to_C_gboolean(hhomogeneous)); return(Xen_false); } static Xen gxg_gtk_stack_get_hhomogeneous(Xen stack) { #define H_gtk_stack_get_hhomogeneous "gboolean gtk_stack_get_hhomogeneous(GtkStack* stack)" Xen_check_type(Xen_is_GtkStack_(stack), stack, 1, "gtk_stack_get_hhomogeneous", "GtkStack*"); return(C_to_Xen_gboolean(gtk_stack_get_hhomogeneous(Xen_to_C_GtkStack_(stack)))); } static Xen gxg_gtk_stack_set_vhomogeneous(Xen stack, Xen vhomogeneous) { #define H_gtk_stack_set_vhomogeneous "void gtk_stack_set_vhomogeneous(GtkStack* stack, gboolean vhomogeneous)" Xen_check_type(Xen_is_GtkStack_(stack), stack, 1, "gtk_stack_set_vhomogeneous", "GtkStack*"); Xen_check_type(Xen_is_gboolean(vhomogeneous), vhomogeneous, 2, "gtk_stack_set_vhomogeneous", "gboolean"); gtk_stack_set_vhomogeneous(Xen_to_C_GtkStack_(stack), Xen_to_C_gboolean(vhomogeneous)); return(Xen_false); } static Xen gxg_gtk_stack_get_vhomogeneous(Xen stack) { #define H_gtk_stack_get_vhomogeneous "gboolean gtk_stack_get_vhomogeneous(GtkStack* stack)" Xen_check_type(Xen_is_GtkStack_(stack), stack, 1, "gtk_stack_get_vhomogeneous", "GtkStack*"); return(C_to_Xen_gboolean(gtk_stack_get_vhomogeneous(Xen_to_C_GtkStack_(stack)))); } static Xen gxg_gdk_gl_context_get_display(Xen context) { #define H_gdk_gl_context_get_display "GdkDisplay* gdk_gl_context_get_display(GdkGLContext* context)" Xen_check_type(Xen_is_GdkGLContext_(context), context, 1, "gdk_gl_context_get_display", "GdkGLContext*"); return(C_to_Xen_GdkDisplay_(gdk_gl_context_get_display(Xen_to_C_GdkGLContext_(context)))); } static Xen gxg_gtk_gl_area_get_has_stencil_buffer(Xen area) { #define H_gtk_gl_area_get_has_stencil_buffer "gboolean gtk_gl_area_get_has_stencil_buffer(GtkGLArea* area)" Xen_check_type(Xen_is_GtkGLArea_(area), area, 1, "gtk_gl_area_get_has_stencil_buffer", "GtkGLArea*"); return(C_to_Xen_gboolean(gtk_gl_area_get_has_stencil_buffer(Xen_to_C_GtkGLArea_(area)))); } static Xen gxg_gtk_gl_area_set_has_stencil_buffer(Xen area, Xen has_stencil_buffer) { #define H_gtk_gl_area_set_has_stencil_buffer "void gtk_gl_area_set_has_stencil_buffer(GtkGLArea* area, \ gboolean has_stencil_buffer)" Xen_check_type(Xen_is_GtkGLArea_(area), area, 1, "gtk_gl_area_set_has_stencil_buffer", "GtkGLArea*"); Xen_check_type(Xen_is_gboolean(has_stencil_buffer), has_stencil_buffer, 2, "gtk_gl_area_set_has_stencil_buffer", "gboolean"); gtk_gl_area_set_has_stencil_buffer(Xen_to_C_GtkGLArea_(area), Xen_to_C_gboolean(has_stencil_buffer)); return(Xen_false); } static Xen gxg_gtk_gl_area_get_auto_render(Xen area) { #define H_gtk_gl_area_get_auto_render "gboolean gtk_gl_area_get_auto_render(GtkGLArea* area)" Xen_check_type(Xen_is_GtkGLArea_(area), area, 1, "gtk_gl_area_get_auto_render", "GtkGLArea*"); return(C_to_Xen_gboolean(gtk_gl_area_get_auto_render(Xen_to_C_GtkGLArea_(area)))); } static Xen gxg_gtk_gl_area_set_auto_render(Xen area, Xen auto_render) { #define H_gtk_gl_area_set_auto_render "void gtk_gl_area_set_auto_render(GtkGLArea* area, gboolean auto_render)" Xen_check_type(Xen_is_GtkGLArea_(area), area, 1, "gtk_gl_area_set_auto_render", "GtkGLArea*"); Xen_check_type(Xen_is_gboolean(auto_render), auto_render, 2, "gtk_gl_area_set_auto_render", "gboolean"); gtk_gl_area_set_auto_render(Xen_to_C_GtkGLArea_(area), Xen_to_C_gboolean(auto_render)); return(Xen_false); } static Xen gxg_gtk_gl_area_queue_render(Xen area) { #define H_gtk_gl_area_queue_render "void gtk_gl_area_queue_render(GtkGLArea* area)" Xen_check_type(Xen_is_GtkGLArea_(area), area, 1, "gtk_gl_area_queue_render", "GtkGLArea*"); gtk_gl_area_queue_render(Xen_to_C_GtkGLArea_(area)); return(Xen_false); } static Xen gxg_gtk_gl_area_attach_buffers(Xen area) { #define H_gtk_gl_area_attach_buffers "void gtk_gl_area_attach_buffers(GtkGLArea* area)" Xen_check_type(Xen_is_GtkGLArea_(area), area, 1, "gtk_gl_area_attach_buffers", "GtkGLArea*"); gtk_gl_area_attach_buffers(Xen_to_C_GtkGLArea_(area)); return(Xen_false); } static Xen gxg_gtk_gl_area_get_error(Xen area) { #define H_gtk_gl_area_get_error "GError* gtk_gl_area_get_error(GtkGLArea* area)" Xen_check_type(Xen_is_GtkGLArea_(area), area, 1, "gtk_gl_area_get_error", "GtkGLArea*"); return(C_to_Xen_GError_(gtk_gl_area_get_error(Xen_to_C_GtkGLArea_(area)))); } static Xen gxg_gtk_popover_menu_new(void) { #define H_gtk_popover_menu_new "GtkWidget* gtk_popover_menu_new( void)" return(C_to_Xen_GtkWidget_(gtk_popover_menu_new())); } static Xen gxg_gtk_popover_menu_open_submenu(Xen popover, Xen name) { #define H_gtk_popover_menu_open_submenu "void gtk_popover_menu_open_submenu(GtkPopoverMenu* popover, \ gchar* name)" Xen_check_type(Xen_is_GtkPopoverMenu_(popover), popover, 1, "gtk_popover_menu_open_submenu", "GtkPopoverMenu*"); Xen_check_type(Xen_is_gchar_(name), name, 2, "gtk_popover_menu_open_submenu", "gchar*"); gtk_popover_menu_open_submenu(Xen_to_C_GtkPopoverMenu_(popover), (const gchar*)Xen_to_C_gchar_(name)); return(Xen_false); } static Xen gxg_gtk_entry_grab_focus_without_selecting(Xen entry) { #define H_gtk_entry_grab_focus_without_selecting "void gtk_entry_grab_focus_without_selecting(GtkEntry* entry)" Xen_check_type(Xen_is_GtkEntry_(entry), entry, 1, "gtk_entry_grab_focus_without_selecting", "GtkEntry*"); gtk_entry_grab_focus_without_selecting(Xen_to_C_GtkEntry_(entry)); return(Xen_false); } static Xen gxg_gtk_scrollable_get_border(Xen scrollable, Xen border) { #define H_gtk_scrollable_get_border "gboolean gtk_scrollable_get_border(GtkScrollable* scrollable, \ GtkBorder* border)" Xen_check_type(Xen_is_GtkScrollable_(scrollable), scrollable, 1, "gtk_scrollable_get_border", "GtkScrollable*"); Xen_check_type(Xen_is_GtkBorder_(border), border, 2, "gtk_scrollable_get_border", "GtkBorder*"); return(C_to_Xen_gboolean(gtk_scrollable_get_border(Xen_to_C_GtkScrollable_(scrollable), Xen_to_C_GtkBorder_(border)))); } static Xen gxg_gtk_text_buffer_insert_markup(Xen buffer, Xen iter, Xen markup, Xen len) { #define H_gtk_text_buffer_insert_markup "void gtk_text_buffer_insert_markup(GtkTextBuffer* buffer, \ GtkTextIter* iter, gchar* markup, gint len)" Xen_check_type(Xen_is_GtkTextBuffer_(buffer), buffer, 1, "gtk_text_buffer_insert_markup", "GtkTextBuffer*"); Xen_check_type(Xen_is_GtkTextIter_(iter), iter, 2, "gtk_text_buffer_insert_markup", "GtkTextIter*"); Xen_check_type(Xen_is_gchar_(markup), markup, 3, "gtk_text_buffer_insert_markup", "gchar*"); Xen_check_type(Xen_is_gint(len), len, 4, "gtk_text_buffer_insert_markup", "gint"); gtk_text_buffer_insert_markup(Xen_to_C_GtkTextBuffer_(buffer), Xen_to_C_GtkTextIter_(iter), (const gchar*)Xen_to_C_gchar_(markup), Xen_to_C_gint(len)); return(Xen_false); } static Xen gxg_gdk_device_get_vendor_id(Xen device) { #define H_gdk_device_get_vendor_id "gchar* gdk_device_get_vendor_id(GdkDevice* device)" Xen_check_type(Xen_is_GdkDevice_(device), device, 1, "gdk_device_get_vendor_id", "GdkDevice*"); return(C_to_Xen_gchar_((gchar*)gdk_device_get_vendor_id(Xen_to_C_GdkDevice_(device)))); } static Xen gxg_gdk_device_get_product_id(Xen device) { #define H_gdk_device_get_product_id "gchar* gdk_device_get_product_id(GdkDevice* device)" Xen_check_type(Xen_is_GdkDevice_(device), device, 1, "gdk_device_get_product_id", "GdkDevice*"); return(C_to_Xen_gchar_((gchar*)gdk_device_get_product_id(Xen_to_C_GdkDevice_(device)))); } static Xen gxg_gdk_gl_context_get_shared_context(Xen context) { #define H_gdk_gl_context_get_shared_context "GdkGLContext* gdk_gl_context_get_shared_context(GdkGLContext* context)" Xen_check_type(Xen_is_GdkGLContext_(context), context, 1, "gdk_gl_context_get_shared_context", "GdkGLContext*"); return(C_to_Xen_GdkGLContext_(gdk_gl_context_get_shared_context(Xen_to_C_GdkGLContext_(context)))); } static Xen gxg_gdk_gl_context_set_required_version(Xen context, Xen major, Xen minor) { #define H_gdk_gl_context_set_required_version "void gdk_gl_context_set_required_version(GdkGLContext* context, \ int major, int minor)" Xen_check_type(Xen_is_GdkGLContext_(context), context, 1, "gdk_gl_context_set_required_version", "GdkGLContext*"); Xen_check_type(Xen_is_int(major), major, 2, "gdk_gl_context_set_required_version", "int"); Xen_check_type(Xen_is_int(minor), minor, 3, "gdk_gl_context_set_required_version", "int"); gdk_gl_context_set_required_version(Xen_to_C_GdkGLContext_(context), Xen_to_C_int(major), Xen_to_C_int(minor)); return(Xen_false); } static Xen gxg_gdk_gl_context_get_required_version(Xen context, Xen ignore_major, Xen ignore_minor) { #define H_gdk_gl_context_get_required_version "void gdk_gl_context_get_required_version(GdkGLContext* context, \ int* [major], int* [minor])" int ref_major; int ref_minor; Xen_check_type(Xen_is_GdkGLContext_(context), context, 1, "gdk_gl_context_get_required_version", "GdkGLContext*"); gdk_gl_context_get_required_version(Xen_to_C_GdkGLContext_(context), &ref_major, &ref_minor); return(Xen_list_2(C_to_Xen_int(ref_major), C_to_Xen_int(ref_minor))); } static Xen gxg_gdk_gl_context_set_debug_enabled(Xen context, Xen enabled) { #define H_gdk_gl_context_set_debug_enabled "void gdk_gl_context_set_debug_enabled(GdkGLContext* context, \ gboolean enabled)" Xen_check_type(Xen_is_GdkGLContext_(context), context, 1, "gdk_gl_context_set_debug_enabled", "GdkGLContext*"); Xen_check_type(Xen_is_gboolean(enabled), enabled, 2, "gdk_gl_context_set_debug_enabled", "gboolean"); gdk_gl_context_set_debug_enabled(Xen_to_C_GdkGLContext_(context), Xen_to_C_gboolean(enabled)); return(Xen_false); } static Xen gxg_gdk_gl_context_get_debug_enabled(Xen context) { #define H_gdk_gl_context_get_debug_enabled "gboolean gdk_gl_context_get_debug_enabled(GdkGLContext* context)" Xen_check_type(Xen_is_GdkGLContext_(context), context, 1, "gdk_gl_context_get_debug_enabled", "GdkGLContext*"); return(C_to_Xen_gboolean(gdk_gl_context_get_debug_enabled(Xen_to_C_GdkGLContext_(context)))); } static Xen gxg_gdk_gl_context_set_forward_compatible(Xen context, Xen compatible) { #define H_gdk_gl_context_set_forward_compatible "void gdk_gl_context_set_forward_compatible(GdkGLContext* context, \ gboolean compatible)" Xen_check_type(Xen_is_GdkGLContext_(context), context, 1, "gdk_gl_context_set_forward_compatible", "GdkGLContext*"); Xen_check_type(Xen_is_gboolean(compatible), compatible, 2, "gdk_gl_context_set_forward_compatible", "gboolean"); gdk_gl_context_set_forward_compatible(Xen_to_C_GdkGLContext_(context), Xen_to_C_gboolean(compatible)); return(Xen_false); } static Xen gxg_gdk_gl_context_get_forward_compatible(Xen context) { #define H_gdk_gl_context_get_forward_compatible "gboolean gdk_gl_context_get_forward_compatible(GdkGLContext* context)" Xen_check_type(Xen_is_GdkGLContext_(context), context, 1, "gdk_gl_context_get_forward_compatible", "GdkGLContext*"); return(C_to_Xen_gboolean(gdk_gl_context_get_forward_compatible(Xen_to_C_GdkGLContext_(context)))); } static Xen gxg_gdk_gl_context_realize(Xen context, Xen ignore_error) { #define H_gdk_gl_context_realize "gboolean gdk_gl_context_realize(GdkGLContext* context, GError** [error])" GError* ref_error = NULL; Xen_check_type(Xen_is_GdkGLContext_(context), context, 1, "gdk_gl_context_realize", "GdkGLContext*"); { Xen result; result = C_to_Xen_gboolean(gdk_gl_context_realize(Xen_to_C_GdkGLContext_(context), &ref_error)); return(Xen_list_2(result, C_to_Xen_GError_(ref_error))); } } static Xen gxg_gtk_clipboard_get_default(Xen display) { #define H_gtk_clipboard_get_default "GtkClipboard* gtk_clipboard_get_default(GdkDisplay* display)" Xen_check_type(Xen_is_GdkDisplay_(display), display, 1, "gtk_clipboard_get_default", "GdkDisplay*"); return(C_to_Xen_GtkClipboard_(gtk_clipboard_get_default(Xen_to_C_GdkDisplay_(display)))); } static Xen gxg_gtk_drag_cancel(Xen context) { #define H_gtk_drag_cancel "void gtk_drag_cancel(GdkDragContext* context)" Xen_check_type(Xen_is_GdkDragContext_(context), context, 1, "gtk_drag_cancel", "GdkDragContext*"); gtk_drag_cancel(Xen_to_C_GdkDragContext_(context)); return(Xen_false); } static Xen gxg_gtk_search_entry_handle_event(Xen entry, Xen event) { #define H_gtk_search_entry_handle_event "gboolean gtk_search_entry_handle_event(GtkSearchEntry* entry, \ GdkEvent* event)" Xen_check_type(Xen_is_GtkSearchEntry_(entry), entry, 1, "gtk_search_entry_handle_event", "GtkSearchEntry*"); Xen_check_type(Xen_is_GdkEvent_(event), event, 2, "gtk_search_entry_handle_event", "GdkEvent*"); return(C_to_Xen_gboolean(gtk_search_entry_handle_event(Xen_to_C_GtkSearchEntry_(entry), Xen_to_C_GdkEvent_(event)))); } static Xen gxg_gdk_gl_context_get_version(Xen context, Xen ignore_major, Xen ignore_minor) { #define H_gdk_gl_context_get_version "void gdk_gl_context_get_version(GdkGLContext* context, int* [major], \ int* [minor])" int ref_major; int ref_minor; Xen_check_type(Xen_is_GdkGLContext_(context), context, 1, "gdk_gl_context_get_version", "GdkGLContext*"); gdk_gl_context_get_version(Xen_to_C_GdkGLContext_(context), &ref_major, &ref_minor); return(Xen_list_2(C_to_Xen_int(ref_major), C_to_Xen_int(ref_minor))); } static Xen gxg_gtk_gl_area_set_required_version(Xen area, Xen major, Xen minor) { #define H_gtk_gl_area_set_required_version "void gtk_gl_area_set_required_version(GtkGLArea* area, \ gint major, gint minor)" Xen_check_type(Xen_is_GtkGLArea_(area), area, 1, "gtk_gl_area_set_required_version", "GtkGLArea*"); Xen_check_type(Xen_is_gint(major), major, 2, "gtk_gl_area_set_required_version", "gint"); Xen_check_type(Xen_is_gint(minor), minor, 3, "gtk_gl_area_set_required_version", "gint"); gtk_gl_area_set_required_version(Xen_to_C_GtkGLArea_(area), Xen_to_C_gint(major), Xen_to_C_gint(minor)); return(Xen_false); } static Xen gxg_gtk_gl_area_get_required_version(Xen area, Xen ignore_major, Xen ignore_minor) { #define H_gtk_gl_area_get_required_version "void gtk_gl_area_get_required_version(GtkGLArea* area, \ gint* [major], gint* [minor])" gint ref_major; gint ref_minor; Xen_check_type(Xen_is_GtkGLArea_(area), area, 1, "gtk_gl_area_get_required_version", "GtkGLArea*"); gtk_gl_area_get_required_version(Xen_to_C_GtkGLArea_(area), &ref_major, &ref_minor); return(Xen_list_2(C_to_Xen_gint(ref_major), C_to_Xen_gint(ref_minor))); } static Xen gxg_gtk_notebook_detach_tab(Xen notebook, Xen child) { #define H_gtk_notebook_detach_tab "void gtk_notebook_detach_tab(GtkNotebook* notebook, GtkWidget* child)" Xen_check_type(Xen_is_GtkNotebook_(notebook), notebook, 1, "gtk_notebook_detach_tab", "GtkNotebook*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_notebook_detach_tab", "GtkWidget*"); gtk_notebook_detach_tab(Xen_to_C_GtkNotebook_(notebook), Xen_to_C_GtkWidget_(child)); return(Xen_false); } static Xen gxg_gtk_stack_sidebar_new(void) { #define H_gtk_stack_sidebar_new "GtkWidget* gtk_stack_sidebar_new( void)" return(C_to_Xen_GtkWidget_(gtk_stack_sidebar_new())); } static Xen gxg_gtk_stack_sidebar_set_stack(Xen sidebar, Xen stack) { #define H_gtk_stack_sidebar_set_stack "void gtk_stack_sidebar_set_stack(GtkStackSidebar* sidebar, GtkStack* stack)" Xen_check_type(Xen_is_GtkStackSidebar_(sidebar), sidebar, 1, "gtk_stack_sidebar_set_stack", "GtkStackSidebar*"); Xen_check_type(Xen_is_GtkStack_(stack), stack, 2, "gtk_stack_sidebar_set_stack", "GtkStack*"); gtk_stack_sidebar_set_stack(Xen_to_C_GtkStackSidebar_(sidebar), Xen_to_C_GtkStack_(stack)); return(Xen_false); } static Xen gxg_gtk_stack_sidebar_get_stack(Xen sidebar) { #define H_gtk_stack_sidebar_get_stack "GtkStack* gtk_stack_sidebar_get_stack(GtkStackSidebar* sidebar)" Xen_check_type(Xen_is_GtkStackSidebar_(sidebar), sidebar, 1, "gtk_stack_sidebar_get_stack", "GtkStackSidebar*"); return(C_to_Xen_GtkStack_(gtk_stack_sidebar_get_stack(Xen_to_C_GtkStackSidebar_(sidebar)))); } static Xen gxg_gtk_popover_set_transitions_enabled(Xen popover, Xen transitions_enabled) { #define H_gtk_popover_set_transitions_enabled "void gtk_popover_set_transitions_enabled(GtkPopover* popover, \ gboolean transitions_enabled)" Xen_check_type(Xen_is_GtkPopover_(popover), popover, 1, "gtk_popover_set_transitions_enabled", "GtkPopover*"); Xen_check_type(Xen_is_gboolean(transitions_enabled), transitions_enabled, 2, "gtk_popover_set_transitions_enabled", "gboolean"); gtk_popover_set_transitions_enabled(Xen_to_C_GtkPopover_(popover), Xen_to_C_gboolean(transitions_enabled)); return(Xen_false); } static Xen gxg_gtk_popover_get_transitions_enabled(Xen popover) { #define H_gtk_popover_get_transitions_enabled "gboolean gtk_popover_get_transitions_enabled(GtkPopover* popover)" Xen_check_type(Xen_is_GtkPopover_(popover), popover, 1, "gtk_popover_get_transitions_enabled", "GtkPopover*"); return(C_to_Xen_gboolean(gtk_popover_get_transitions_enabled(Xen_to_C_GtkPopover_(popover)))); } #endif #if GTK_CHECK_VERSION(3, 18, 0) static Xen gxg_gdk_keymap_get_scroll_lock_state(Xen keymap) { #define H_gdk_keymap_get_scroll_lock_state "gboolean gdk_keymap_get_scroll_lock_state(GdkKeymap* keymap)" Xen_check_type(Xen_is_GdkKeymap_(keymap), keymap, 1, "gdk_keymap_get_scroll_lock_state", "GdkKeymap*"); return(C_to_Xen_gboolean(gdk_keymap_get_scroll_lock_state(Xen_to_C_GdkKeymap_(keymap)))); } static Xen gxg_gtk_radio_menu_item_join_group(Xen radio_menu_item, Xen group_source) { #define H_gtk_radio_menu_item_join_group "void gtk_radio_menu_item_join_group(GtkRadioMenuItem* radio_menu_item, \ GtkRadioMenuItem* group_source)" Xen_check_type(Xen_is_GtkRadioMenuItem_(radio_menu_item), radio_menu_item, 1, "gtk_radio_menu_item_join_group", "GtkRadioMenuItem*"); Xen_check_type(Xen_is_GtkRadioMenuItem_(group_source), group_source, 2, "gtk_radio_menu_item_join_group", "GtkRadioMenuItem*"); gtk_radio_menu_item_join_group(Xen_to_C_GtkRadioMenuItem_(radio_menu_item), Xen_to_C_GtkRadioMenuItem_(group_source)); return(Xen_false); } static Xen gxg_gtk_font_chooser_set_font_map(Xen fontchooser, Xen fontmap) { #define H_gtk_font_chooser_set_font_map "void gtk_font_chooser_set_font_map(GtkFontChooser* fontchooser, \ PangoFontMap* fontmap)" Xen_check_type(Xen_is_GtkFontChooser_(fontchooser), fontchooser, 1, "gtk_font_chooser_set_font_map", "GtkFontChooser*"); Xen_check_type(Xen_is_PangoFontMap_(fontmap), fontmap, 2, "gtk_font_chooser_set_font_map", "PangoFontMap*"); gtk_font_chooser_set_font_map(Xen_to_C_GtkFontChooser_(fontchooser), Xen_to_C_PangoFontMap_(fontmap)); return(Xen_false); } static Xen gxg_gtk_font_chooser_get_font_map(Xen fontchooser) { #define H_gtk_font_chooser_get_font_map "PangoFontMap* gtk_font_chooser_get_font_map(GtkFontChooser* fontchooser)" Xen_check_type(Xen_is_GtkFontChooser_(fontchooser), fontchooser, 1, "gtk_font_chooser_get_font_map", "GtkFontChooser*"); return(C_to_Xen_PangoFontMap_(gtk_font_chooser_get_font_map(Xen_to_C_GtkFontChooser_(fontchooser)))); } static Xen gxg_gtk_popover_set_default_widget(Xen popover, Xen widget) { #define H_gtk_popover_set_default_widget "void gtk_popover_set_default_widget(GtkPopover* popover, \ GtkWidget* widget)" Xen_check_type(Xen_is_GtkPopover_(popover), popover, 1, "gtk_popover_set_default_widget", "GtkPopover*"); Xen_check_type(Xen_is_GtkWidget_(widget), widget, 2, "gtk_popover_set_default_widget", "GtkWidget*"); gtk_popover_set_default_widget(Xen_to_C_GtkPopover_(popover), Xen_to_C_GtkWidget_(widget)); return(Xen_false); } static Xen gxg_gtk_popover_get_default_widget(Xen popover) { #define H_gtk_popover_get_default_widget "GtkWidget* gtk_popover_get_default_widget(GtkPopover* popover)" Xen_check_type(Xen_is_GtkPopover_(popover), popover, 1, "gtk_popover_get_default_widget", "GtkPopover*"); return(C_to_Xen_GtkWidget_(gtk_popover_get_default_widget(Xen_to_C_GtkPopover_(popover)))); } static Xen gxg_gdk_window_set_pass_through(Xen window, Xen pass_through) { #define H_gdk_window_set_pass_through "void gdk_window_set_pass_through(GdkWindow* window, gboolean pass_through)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_set_pass_through", "GdkWindow*"); Xen_check_type(Xen_is_gboolean(pass_through), pass_through, 2, "gdk_window_set_pass_through", "gboolean"); gdk_window_set_pass_through(Xen_to_C_GdkWindow_(window), Xen_to_C_gboolean(pass_through)); return(Xen_false); } static Xen gxg_gdk_window_get_pass_through(Xen window) { #define H_gdk_window_get_pass_through "gboolean gdk_window_get_pass_through(GdkWindow* window)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_get_pass_through", "GdkWindow*"); return(C_to_Xen_gboolean(gdk_window_get_pass_through(Xen_to_C_GdkWindow_(window)))); } static Xen gxg_gtk_overlay_reorder_overlay(Xen overlay, Xen child, Xen position) { #define H_gtk_overlay_reorder_overlay "void gtk_overlay_reorder_overlay(GtkOverlay* overlay, GtkWidget* child, \ gint position)" Xen_check_type(Xen_is_GtkOverlay_(overlay), overlay, 1, "gtk_overlay_reorder_overlay", "GtkOverlay*"); Xen_check_type(Xen_is_GtkWidget_(child), child, 2, "gtk_overlay_reorder_overlay", "GtkWidget*"); Xen_check_type(Xen_is_gint(position), position, 3, "gtk_overlay_reorder_overlay", "gint"); gtk_overlay_reorder_overlay(Xen_to_C_GtkOverlay_(overlay), Xen_to_C_GtkWidget_(child), Xen_to_C_gint(position)); return(Xen_false); } static Xen gxg_gtk_overlay_get_overlay_pass_through(Xen overlay, Xen widget) { #define H_gtk_overlay_get_overlay_pass_through "gboolean gtk_overlay_get_overlay_pass_through(GtkOverlay* overlay, \ GtkWidget* widget)" Xen_check_type(Xen_is_GtkOverlay_(overlay), overlay, 1, "gtk_overlay_get_overlay_pass_through", "GtkOverlay*"); Xen_check_type(Xen_is_GtkWidget_(widget), widget, 2, "gtk_overlay_get_overlay_pass_through", "GtkWidget*"); return(C_to_Xen_gboolean(gtk_overlay_get_overlay_pass_through(Xen_to_C_GtkOverlay_(overlay), Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_overlay_set_overlay_pass_through(Xen overlay, Xen widget, Xen pass_through) { #define H_gtk_overlay_set_overlay_pass_through "void gtk_overlay_set_overlay_pass_through(GtkOverlay* overlay, \ GtkWidget* widget, gboolean pass_through)" Xen_check_type(Xen_is_GtkOverlay_(overlay), overlay, 1, "gtk_overlay_set_overlay_pass_through", "GtkOverlay*"); Xen_check_type(Xen_is_GtkWidget_(widget), widget, 2, "gtk_overlay_set_overlay_pass_through", "GtkWidget*"); Xen_check_type(Xen_is_gboolean(pass_through), pass_through, 3, "gtk_overlay_set_overlay_pass_through", "gboolean"); gtk_overlay_set_overlay_pass_through(Xen_to_C_GtkOverlay_(overlay), Xen_to_C_GtkWidget_(widget), Xen_to_C_gboolean(pass_through)); return(Xen_false); } static Xen gxg_gtk_places_sidebar_get_show_recent(Xen sidebar) { #define H_gtk_places_sidebar_get_show_recent "gboolean gtk_places_sidebar_get_show_recent(GtkPlacesSidebar* sidebar)" Xen_check_type(Xen_is_GtkPlacesSidebar_(sidebar), sidebar, 1, "gtk_places_sidebar_get_show_recent", "GtkPlacesSidebar*"); return(C_to_Xen_gboolean(gtk_places_sidebar_get_show_recent(Xen_to_C_GtkPlacesSidebar_(sidebar)))); } static Xen gxg_gtk_places_sidebar_set_show_recent(Xen sidebar, Xen show_recent) { #define H_gtk_places_sidebar_set_show_recent "void gtk_places_sidebar_set_show_recent(GtkPlacesSidebar* sidebar, \ gboolean show_recent)" Xen_check_type(Xen_is_GtkPlacesSidebar_(sidebar), sidebar, 1, "gtk_places_sidebar_set_show_recent", "GtkPlacesSidebar*"); Xen_check_type(Xen_is_gboolean(show_recent), show_recent, 2, "gtk_places_sidebar_set_show_recent", "gboolean"); gtk_places_sidebar_set_show_recent(Xen_to_C_GtkPlacesSidebar_(sidebar), Xen_to_C_gboolean(show_recent)); return(Xen_false); } static Xen gxg_gtk_places_sidebar_set_drop_targets_visible(Xen sidebar, Xen visible, Xen context) { #define H_gtk_places_sidebar_set_drop_targets_visible "void gtk_places_sidebar_set_drop_targets_visible(GtkPlacesSidebar* sidebar, \ gboolean visible, GdkDragContext* context)" Xen_check_type(Xen_is_GtkPlacesSidebar_(sidebar), sidebar, 1, "gtk_places_sidebar_set_drop_targets_visible", "GtkPlacesSidebar*"); Xen_check_type(Xen_is_gboolean(visible), visible, 2, "gtk_places_sidebar_set_drop_targets_visible", "gboolean"); Xen_check_type(Xen_is_GdkDragContext_(context), context, 3, "gtk_places_sidebar_set_drop_targets_visible", "GdkDragContext*"); gtk_places_sidebar_set_drop_targets_visible(Xen_to_C_GtkPlacesSidebar_(sidebar), Xen_to_C_gboolean(visible), Xen_to_C_GdkDragContext_(context)); return(Xen_false); } static Xen gxg_gtk_places_sidebar_get_show_trash(Xen sidebar) { #define H_gtk_places_sidebar_get_show_trash "gboolean gtk_places_sidebar_get_show_trash(GtkPlacesSidebar* sidebar)" Xen_check_type(Xen_is_GtkPlacesSidebar_(sidebar), sidebar, 1, "gtk_places_sidebar_get_show_trash", "GtkPlacesSidebar*"); return(C_to_Xen_gboolean(gtk_places_sidebar_get_show_trash(Xen_to_C_GtkPlacesSidebar_(sidebar)))); } static Xen gxg_gtk_places_sidebar_set_show_trash(Xen sidebar, Xen show_trash) { #define H_gtk_places_sidebar_set_show_trash "void gtk_places_sidebar_set_show_trash(GtkPlacesSidebar* sidebar, \ gboolean show_trash)" Xen_check_type(Xen_is_GtkPlacesSidebar_(sidebar), sidebar, 1, "gtk_places_sidebar_set_show_trash", "GtkPlacesSidebar*"); Xen_check_type(Xen_is_gboolean(show_trash), show_trash, 2, "gtk_places_sidebar_set_show_trash", "gboolean"); gtk_places_sidebar_set_show_trash(Xen_to_C_GtkPlacesSidebar_(sidebar), Xen_to_C_gboolean(show_trash)); return(Xen_false); } static Xen gxg_gtk_places_sidebar_set_show_other_locations(Xen sidebar, Xen show_other_locations) { #define H_gtk_places_sidebar_set_show_other_locations "void gtk_places_sidebar_set_show_other_locations(GtkPlacesSidebar* sidebar, \ gboolean show_other_locations)" Xen_check_type(Xen_is_GtkPlacesSidebar_(sidebar), sidebar, 1, "gtk_places_sidebar_set_show_other_locations", "GtkPlacesSidebar*"); Xen_check_type(Xen_is_gboolean(show_other_locations), show_other_locations, 2, "gtk_places_sidebar_set_show_other_locations", "gboolean"); gtk_places_sidebar_set_show_other_locations(Xen_to_C_GtkPlacesSidebar_(sidebar), Xen_to_C_gboolean(show_other_locations)); return(Xen_false); } static Xen gxg_gtk_places_sidebar_get_show_other_locations(Xen sidebar) { #define H_gtk_places_sidebar_get_show_other_locations "gboolean gtk_places_sidebar_get_show_other_locations(GtkPlacesSidebar* sidebar)" Xen_check_type(Xen_is_GtkPlacesSidebar_(sidebar), sidebar, 1, "gtk_places_sidebar_get_show_other_locations", "GtkPlacesSidebar*"); return(C_to_Xen_gboolean(gtk_places_sidebar_get_show_other_locations(Xen_to_C_GtkPlacesSidebar_(sidebar)))); } static Xen gxg_gtk_stack_set_interpolate_size(Xen stack, Xen interpolate_size) { #define H_gtk_stack_set_interpolate_size "void gtk_stack_set_interpolate_size(GtkStack* stack, gboolean interpolate_size)" Xen_check_type(Xen_is_GtkStack_(stack), stack, 1, "gtk_stack_set_interpolate_size", "GtkStack*"); Xen_check_type(Xen_is_gboolean(interpolate_size), interpolate_size, 2, "gtk_stack_set_interpolate_size", "gboolean"); gtk_stack_set_interpolate_size(Xen_to_C_GtkStack_(stack), Xen_to_C_gboolean(interpolate_size)); return(Xen_false); } static Xen gxg_gtk_stack_get_interpolate_size(Xen stack) { #define H_gtk_stack_get_interpolate_size "gboolean gtk_stack_get_interpolate_size(GtkStack* stack)" Xen_check_type(Xen_is_GtkStack_(stack), stack, 1, "gtk_stack_get_interpolate_size", "GtkStack*"); return(C_to_Xen_gboolean(gtk_stack_get_interpolate_size(Xen_to_C_GtkStack_(stack)))); } static Xen gxg_gtk_widget_set_font_options(Xen widget, Xen options) { #define H_gtk_widget_set_font_options "void gtk_widget_set_font_options(GtkWidget* widget, cairo_font_options_t* options)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_set_font_options", "GtkWidget*"); Xen_check_type(Xen_is_cairo_font_options_t_(options), options, 2, "gtk_widget_set_font_options", "cairo_font_options_t*"); gtk_widget_set_font_options(Xen_to_C_GtkWidget_(widget), Xen_to_C_cairo_font_options_t_(options)); return(Xen_false); } static Xen gxg_gtk_widget_get_font_options(Xen widget) { #define H_gtk_widget_get_font_options "cairo_font_options_t* gtk_widget_get_font_options(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_font_options", "GtkWidget*"); return(C_to_Xen_cairo_font_options_t_((cairo_font_options_t*)gtk_widget_get_font_options(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_set_font_map(Xen widget, Xen fontmap) { #define H_gtk_widget_set_font_map "void gtk_widget_set_font_map(GtkWidget* widget, PangoFontMap* fontmap)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_set_font_map", "GtkWidget*"); Xen_check_type(Xen_is_PangoFontMap_(fontmap), fontmap, 2, "gtk_widget_set_font_map", "PangoFontMap*"); gtk_widget_set_font_map(Xen_to_C_GtkWidget_(widget), Xen_to_C_PangoFontMap_(fontmap)); return(Xen_false); } static Xen gxg_gtk_widget_get_font_map(Xen widget) { #define H_gtk_widget_get_font_map "PangoFontMap* gtk_widget_get_font_map(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_font_map", "GtkWidget*"); return(C_to_Xen_PangoFontMap_(gtk_widget_get_font_map(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gdk_window_fullscreen_on_monitor(Xen window, Xen monitor) { #define H_gdk_window_fullscreen_on_monitor "void gdk_window_fullscreen_on_monitor(GdkWindow* window, \ gint monitor)" Xen_check_type(Xen_is_GdkWindow_(window), window, 1, "gdk_window_fullscreen_on_monitor", "GdkWindow*"); Xen_check_type(Xen_is_gint(monitor), monitor, 2, "gdk_window_fullscreen_on_monitor", "gint"); gdk_window_fullscreen_on_monitor(Xen_to_C_GdkWindow_(window), Xen_to_C_gint(monitor)); return(Xen_false); } static Xen gxg_gtk_window_fullscreen_on_monitor(Xen window, Xen screen, Xen monitor) { #define H_gtk_window_fullscreen_on_monitor "void gtk_window_fullscreen_on_monitor(GtkWindow* window, \ GdkScreen* screen, gint monitor)" Xen_check_type(Xen_is_GtkWindow_(window), window, 1, "gtk_window_fullscreen_on_monitor", "GtkWindow*"); Xen_check_type(Xen_is_GdkScreen_(screen), screen, 2, "gtk_window_fullscreen_on_monitor", "GdkScreen*"); Xen_check_type(Xen_is_gint(monitor), monitor, 3, "gtk_window_fullscreen_on_monitor", "gint"); gtk_window_fullscreen_on_monitor(Xen_to_C_GtkWindow_(window), Xen_to_C_GdkScreen_(screen), Xen_to_C_gint(monitor)); return(Xen_false); } static Xen gxg_gtk_text_view_set_top_margin(Xen text_view, Xen top_margin) { #define H_gtk_text_view_set_top_margin "void gtk_text_view_set_top_margin(GtkTextView* text_view, gint top_margin)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_set_top_margin", "GtkTextView*"); Xen_check_type(Xen_is_gint(top_margin), top_margin, 2, "gtk_text_view_set_top_margin", "gint"); gtk_text_view_set_top_margin(Xen_to_C_GtkTextView_(text_view), Xen_to_C_gint(top_margin)); return(Xen_false); } static Xen gxg_gtk_text_view_get_top_margin(Xen text_view) { #define H_gtk_text_view_get_top_margin "gint gtk_text_view_get_top_margin(GtkTextView* text_view)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_get_top_margin", "GtkTextView*"); return(C_to_Xen_gint(gtk_text_view_get_top_margin(Xen_to_C_GtkTextView_(text_view)))); } static Xen gxg_gtk_text_view_set_bottom_margin(Xen text_view, Xen bottom_margin) { #define H_gtk_text_view_set_bottom_margin "void gtk_text_view_set_bottom_margin(GtkTextView* text_view, \ gint bottom_margin)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_set_bottom_margin", "GtkTextView*"); Xen_check_type(Xen_is_gint(bottom_margin), bottom_margin, 2, "gtk_text_view_set_bottom_margin", "gint"); gtk_text_view_set_bottom_margin(Xen_to_C_GtkTextView_(text_view), Xen_to_C_gint(bottom_margin)); return(Xen_false); } static Xen gxg_gtk_text_view_get_bottom_margin(Xen text_view) { #define H_gtk_text_view_get_bottom_margin "gint gtk_text_view_get_bottom_margin(GtkTextView* text_view)" Xen_check_type(Xen_is_GtkTextView_(text_view), text_view, 1, "gtk_text_view_get_bottom_margin", "GtkTextView*"); return(C_to_Xen_gint(gtk_text_view_get_bottom_margin(Xen_to_C_GtkTextView_(text_view)))); } #endif #if GTK_CHECK_VERSION(3, 20, 0) static Xen gxg_gdk_gl_context_is_legacy(Xen context) { #define H_gdk_gl_context_is_legacy "gboolean gdk_gl_context_is_legacy(GdkGLContext* context)" Xen_check_type(Xen_is_GdkGLContext_(context), context, 1, "gdk_gl_context_is_legacy", "GdkGLContext*"); return(C_to_Xen_gboolean(gdk_gl_context_is_legacy(Xen_to_C_GdkGLContext_(context)))); } static Xen gxg_gdk_rectangle_equal(Xen rect1) { #define H_gdk_rectangle_equal "gboolean gdk_rectangle_equal(GdkRectangle* rect1, GdkRectangle*rect2)" Xen_check_type(Xen_is_GdkRectangle_(rect1), rect1, 1, "gdk_rectangle_equal", "GdkRectangle*"); return(C_to_Xen_gboolean(gdk_rectangle_equal(Xen_to_C_GdkRectangle_(rect1)))); } static Xen gxg_gtk_application_window_set_help_overlay(Xen window, Xen help_overlay) { #define H_gtk_application_window_set_help_overlay "void gtk_application_window_set_help_overlay(GtkApplicationWindow* window, \ GtkShortcutsWindow* help_overlay)" Xen_check_type(Xen_is_GtkApplicationWindow_(window), window, 1, "gtk_application_window_set_help_overlay", "GtkApplicationWindow*"); Xen_check_type(Xen_is_GtkShortcutsWindow_(help_overlay), help_overlay, 2, "gtk_application_window_set_help_overlay", "GtkShortcutsWindow*"); gtk_application_window_set_help_overlay(Xen_to_C_GtkApplicationWindow_(window), Xen_to_C_GtkShortcutsWindow_(help_overlay)); return(Xen_false); } static Xen gxg_gtk_settings_reset_property(Xen settings, Xen name) { #define H_gtk_settings_reset_property "void gtk_settings_reset_property(GtkSettings* settings, gchar* name)" Xen_check_type(Xen_is_GtkSettings_(settings), settings, 1, "gtk_settings_reset_property", "GtkSettings*"); Xen_check_type(Xen_is_gchar_(name), name, 2, "gtk_settings_reset_property", "gchar*"); gtk_settings_reset_property(Xen_to_C_GtkSettings_(settings), (const gchar*)Xen_to_C_gchar_(name)); return(Xen_false); } static Xen gxg_gtk_text_tag_changed(Xen tag, Xen size_changed) { #define H_gtk_text_tag_changed "void gtk_text_tag_changed(GtkTextTag* tag, gboolean size_changed)" Xen_check_type(Xen_is_GtkTextTag_(tag), tag, 1, "gtk_text_tag_changed", "GtkTextTag*"); Xen_check_type(Xen_is_gboolean(size_changed), size_changed, 2, "gtk_text_tag_changed", "gboolean"); gtk_text_tag_changed(Xen_to_C_GtkTextTag_(tag), Xen_to_C_gboolean(size_changed)); return(Xen_false); } static Xen gxg_gtk_widget_path_iter_get_object_name(Xen path, Xen pos) { #define H_gtk_widget_path_iter_get_object_name "char* gtk_widget_path_iter_get_object_name(GtkWidgetPath* path, \ gint pos)" Xen_check_type(Xen_is_GtkWidgetPath_(path), path, 1, "gtk_widget_path_iter_get_object_name", "GtkWidgetPath*"); Xen_check_type(Xen_is_gint(pos), pos, 2, "gtk_widget_path_iter_get_object_name", "gint"); return(C_to_Xen_char_((char*)gtk_widget_path_iter_get_object_name(Xen_to_C_GtkWidgetPath_(path), Xen_to_C_gint(pos)))); } static Xen gxg_gtk_widget_path_iter_set_object_name(Xen path, Xen pos, Xen name) { #define H_gtk_widget_path_iter_set_object_name "void gtk_widget_path_iter_set_object_name(GtkWidgetPath* path, \ gint pos, char* name)" Xen_check_type(Xen_is_GtkWidgetPath_(path), path, 1, "gtk_widget_path_iter_set_object_name", "GtkWidgetPath*"); Xen_check_type(Xen_is_gint(pos), pos, 2, "gtk_widget_path_iter_set_object_name", "gint"); Xen_check_type(Xen_is_char_(name), name, 3, "gtk_widget_path_iter_set_object_name", "char*"); gtk_widget_path_iter_set_object_name(Xen_to_C_GtkWidgetPath_(path), Xen_to_C_gint(pos), (const char*)Xen_to_C_char_(name)); return(Xen_false); } static Xen gxg_gtk_widget_queue_allocate(Xen widget) { #define H_gtk_widget_queue_allocate "void gtk_widget_queue_allocate(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_queue_allocate", "GtkWidget*"); gtk_widget_queue_allocate(Xen_to_C_GtkWidget_(widget)); return(Xen_false); } static Xen gxg_gtk_widget_set_focus_on_click(Xen widget, Xen focus_on_click) { #define H_gtk_widget_set_focus_on_click "void gtk_widget_set_focus_on_click(GtkWidget* widget, gboolean focus_on_click)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_set_focus_on_click", "GtkWidget*"); Xen_check_type(Xen_is_gboolean(focus_on_click), focus_on_click, 2, "gtk_widget_set_focus_on_click", "gboolean"); gtk_widget_set_focus_on_click(Xen_to_C_GtkWidget_(widget), Xen_to_C_gboolean(focus_on_click)); return(Xen_false); } static Xen gxg_gtk_widget_get_focus_on_click(Xen widget) { #define H_gtk_widget_get_focus_on_click "gboolean gtk_widget_get_focus_on_click(GtkWidget* widget)" Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_focus_on_click", "GtkWidget*"); return(C_to_Xen_gboolean(gtk_widget_get_focus_on_click(Xen_to_C_GtkWidget_(widget)))); } static Xen gxg_gtk_widget_get_allocated_size(Xen widget, Xen ignore_allocation, Xen ignore_baseline) { #define H_gtk_widget_get_allocated_size "void gtk_widget_get_allocated_size(GtkWidget* widget, GtkAllocation* [allocation], \ int* [baseline])" GtkAllocation ref_allocation; int ref_baseline; Xen_check_type(Xen_is_GtkWidget_(widget), widget, 1, "gtk_widget_get_allocated_size", "GtkWidget*"); gtk_widget_get_allocated_size(Xen_to_C_GtkWidget_(widget), &ref_allocation, &ref_baseline); return(Xen_list_2(C_to_Xen_GtkAllocation(ref_allocation), C_to_Xen_int(ref_baseline))); } #endif static Xen gxg_cairo_create(Xen target) { #define H_cairo_create "cairo_t* cairo_create(cairo_surface_t* target)" Xen_check_type(Xen_is_cairo_surface_t_(target), target, 1, "cairo_create", "cairo_surface_t*"); return(C_to_Xen_cairo_t_(cairo_create(Xen_to_C_cairo_surface_t_(target)))); } static Xen gxg_cairo_version(void) { #define H_cairo_version "int cairo_version( void)" return(C_to_Xen_int(cairo_version())); } static Xen gxg_cairo_version_string(void) { #define H_cairo_version_string "char* cairo_version_string( void)" return(C_to_Xen_char_(cairo_version_string())); } static Xen gxg_cairo_reference(Xen cr) { #define H_cairo_reference "cairo_t* cairo_reference(cairo_t* cr)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_reference", "cairo_t*"); return(C_to_Xen_cairo_t_(cairo_reference(Xen_to_C_cairo_t_(cr)))); } static Xen gxg_cairo_destroy(Xen cr) { #define H_cairo_destroy "void cairo_destroy(cairo_t* cr)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_destroy", "cairo_t*"); cairo_destroy(Xen_to_C_cairo_t_(cr)); return(Xen_false); } static Xen gxg_cairo_save(Xen cr) { #define H_cairo_save "void cairo_save(cairo_t* cr)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_save", "cairo_t*"); cairo_save(Xen_to_C_cairo_t_(cr)); return(Xen_false); } static Xen gxg_cairo_restore(Xen cr) { #define H_cairo_restore "void cairo_restore(cairo_t* cr)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_restore", "cairo_t*"); cairo_restore(Xen_to_C_cairo_t_(cr)); return(Xen_false); } static Xen gxg_cairo_push_group(Xen cr) { #define H_cairo_push_group "void cairo_push_group(cairo_t* cr)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_push_group", "cairo_t*"); cairo_push_group(Xen_to_C_cairo_t_(cr)); return(Xen_false); } static Xen gxg_cairo_push_group_with_content(Xen cr, Xen content) { #define H_cairo_push_group_with_content "void cairo_push_group_with_content(cairo_t* cr, cairo_content_t content)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_push_group_with_content", "cairo_t*"); Xen_check_type(Xen_is_cairo_content_t(content), content, 2, "cairo_push_group_with_content", "cairo_content_t"); cairo_push_group_with_content(Xen_to_C_cairo_t_(cr), Xen_to_C_cairo_content_t(content)); return(Xen_false); } static Xen gxg_cairo_pop_group(Xen cr) { #define H_cairo_pop_group "cairo_pattern_t* cairo_pop_group(cairo_t* cr)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_pop_group", "cairo_t*"); return(C_to_Xen_cairo_pattern_t_(cairo_pop_group(Xen_to_C_cairo_t_(cr)))); } static Xen gxg_cairo_pop_group_to_source(Xen cr) { #define H_cairo_pop_group_to_source "void cairo_pop_group_to_source(cairo_t* cr)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_pop_group_to_source", "cairo_t*"); cairo_pop_group_to_source(Xen_to_C_cairo_t_(cr)); return(Xen_false); } static Xen gxg_cairo_set_operator(Xen cr, Xen op) { #define H_cairo_set_operator "void cairo_set_operator(cairo_t* cr, cairo_operator_t op)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_set_operator", "cairo_t*"); Xen_check_type(Xen_is_cairo_operator_t(op), op, 2, "cairo_set_operator", "cairo_operator_t"); cairo_set_operator(Xen_to_C_cairo_t_(cr), Xen_to_C_cairo_operator_t(op)); return(Xen_false); } static Xen gxg_cairo_set_source(Xen cr, Xen source) { #define H_cairo_set_source "void cairo_set_source(cairo_t* cr, cairo_pattern_t* source)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_set_source", "cairo_t*"); Xen_check_type(Xen_is_cairo_pattern_t_(source), source, 2, "cairo_set_source", "cairo_pattern_t*"); cairo_set_source(Xen_to_C_cairo_t_(cr), Xen_to_C_cairo_pattern_t_(source)); return(Xen_false); } static Xen gxg_cairo_set_source_rgb(Xen cr, Xen red, Xen green, Xen blue) { #define H_cairo_set_source_rgb "void cairo_set_source_rgb(cairo_t* cr, double red, double green, double blue)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_set_source_rgb", "cairo_t*"); Xen_check_type(Xen_is_double(red), red, 2, "cairo_set_source_rgb", "double"); Xen_check_type(Xen_is_double(green), green, 3, "cairo_set_source_rgb", "double"); Xen_check_type(Xen_is_double(blue), blue, 4, "cairo_set_source_rgb", "double"); cairo_set_source_rgb(Xen_to_C_cairo_t_(cr), Xen_to_C_double(red), Xen_to_C_double(green), Xen_to_C_double(blue)); return(Xen_false); } static Xen gxg_cairo_set_source_rgba(Xen cr, Xen red, Xen green, Xen blue, Xen alpha) { #define H_cairo_set_source_rgba "void cairo_set_source_rgba(cairo_t* cr, double red, double green, \ double blue, double alpha)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_set_source_rgba", "cairo_t*"); Xen_check_type(Xen_is_double(red), red, 2, "cairo_set_source_rgba", "double"); Xen_check_type(Xen_is_double(green), green, 3, "cairo_set_source_rgba", "double"); Xen_check_type(Xen_is_double(blue), blue, 4, "cairo_set_source_rgba", "double"); Xen_check_type(Xen_is_double(alpha), alpha, 5, "cairo_set_source_rgba", "double"); cairo_set_source_rgba(Xen_to_C_cairo_t_(cr), Xen_to_C_double(red), Xen_to_C_double(green), Xen_to_C_double(blue), Xen_to_C_double(alpha)); return(Xen_false); } static Xen gxg_cairo_set_source_surface(Xen cr, Xen surface, Xen x, Xen y) { #define H_cairo_set_source_surface "void cairo_set_source_surface(cairo_t* cr, cairo_surface_t* surface, \ double x, double y)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_set_source_surface", "cairo_t*"); Xen_check_type(Xen_is_cairo_surface_t_(surface), surface, 2, "cairo_set_source_surface", "cairo_surface_t*"); Xen_check_type(Xen_is_double(x), x, 3, "cairo_set_source_surface", "double"); Xen_check_type(Xen_is_double(y), y, 4, "cairo_set_source_surface", "double"); cairo_set_source_surface(Xen_to_C_cairo_t_(cr), Xen_to_C_cairo_surface_t_(surface), Xen_to_C_double(x), Xen_to_C_double(y)); return(Xen_false); } static Xen gxg_cairo_set_tolerance(Xen cr, Xen tolerance) { #define H_cairo_set_tolerance "void cairo_set_tolerance(cairo_t* cr, double tolerance)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_set_tolerance", "cairo_t*"); Xen_check_type(Xen_is_double(tolerance), tolerance, 2, "cairo_set_tolerance", "double"); cairo_set_tolerance(Xen_to_C_cairo_t_(cr), Xen_to_C_double(tolerance)); return(Xen_false); } static Xen gxg_cairo_set_antialias(Xen cr, Xen antialias) { #define H_cairo_set_antialias "void cairo_set_antialias(cairo_t* cr, cairo_antialias_t antialias)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_set_antialias", "cairo_t*"); Xen_check_type(Xen_is_cairo_antialias_t(antialias), antialias, 2, "cairo_set_antialias", "cairo_antialias_t"); cairo_set_antialias(Xen_to_C_cairo_t_(cr), Xen_to_C_cairo_antialias_t(antialias)); return(Xen_false); } static Xen gxg_cairo_set_fill_rule(Xen cr, Xen fill_rule) { #define H_cairo_set_fill_rule "void cairo_set_fill_rule(cairo_t* cr, cairo_fill_rule_t fill_rule)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_set_fill_rule", "cairo_t*"); Xen_check_type(Xen_is_cairo_fill_rule_t(fill_rule), fill_rule, 2, "cairo_set_fill_rule", "cairo_fill_rule_t"); cairo_set_fill_rule(Xen_to_C_cairo_t_(cr), Xen_to_C_cairo_fill_rule_t(fill_rule)); return(Xen_false); } static Xen gxg_cairo_set_line_width(Xen cr, Xen width) { #define H_cairo_set_line_width "void cairo_set_line_width(cairo_t* cr, double width)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_set_line_width", "cairo_t*"); Xen_check_type(Xen_is_double(width), width, 2, "cairo_set_line_width", "double"); cairo_set_line_width(Xen_to_C_cairo_t_(cr), Xen_to_C_double(width)); return(Xen_false); } static Xen gxg_cairo_set_line_cap(Xen cr, Xen line_cap) { #define H_cairo_set_line_cap "void cairo_set_line_cap(cairo_t* cr, cairo_line_cap_t line_cap)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_set_line_cap", "cairo_t*"); Xen_check_type(Xen_is_cairo_line_cap_t(line_cap), line_cap, 2, "cairo_set_line_cap", "cairo_line_cap_t"); cairo_set_line_cap(Xen_to_C_cairo_t_(cr), Xen_to_C_cairo_line_cap_t(line_cap)); return(Xen_false); } static Xen gxg_cairo_set_line_join(Xen cr, Xen line_join) { #define H_cairo_set_line_join "void cairo_set_line_join(cairo_t* cr, cairo_line_join_t line_join)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_set_line_join", "cairo_t*"); Xen_check_type(Xen_is_cairo_line_join_t(line_join), line_join, 2, "cairo_set_line_join", "cairo_line_join_t"); cairo_set_line_join(Xen_to_C_cairo_t_(cr), Xen_to_C_cairo_line_join_t(line_join)); return(Xen_false); } static Xen gxg_cairo_set_dash(Xen cr, Xen dashes, Xen num_dashes, Xen offset) { #define H_cairo_set_dash "void cairo_set_dash(cairo_t* cr, gdouble* dashes, int num_dashes, double offset)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_set_dash", "cairo_t*"); Xen_check_type(Xen_is_gdouble_(dashes), dashes, 2, "cairo_set_dash", "gdouble*"); Xen_check_type(Xen_is_int(num_dashes), num_dashes, 3, "cairo_set_dash", "int"); Xen_check_type(Xen_is_double(offset), offset, 4, "cairo_set_dash", "double"); cairo_set_dash(Xen_to_C_cairo_t_(cr), Xen_to_C_gdouble_(dashes), Xen_to_C_int(num_dashes), Xen_to_C_double(offset)); return(Xen_false); } static Xen gxg_cairo_set_miter_limit(Xen cr, Xen limit) { #define H_cairo_set_miter_limit "void cairo_set_miter_limit(cairo_t* cr, double limit)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_set_miter_limit", "cairo_t*"); Xen_check_type(Xen_is_double(limit), limit, 2, "cairo_set_miter_limit", "double"); cairo_set_miter_limit(Xen_to_C_cairo_t_(cr), Xen_to_C_double(limit)); return(Xen_false); } static Xen gxg_cairo_translate(Xen cr, Xen tx, Xen ty) { #define H_cairo_translate "void cairo_translate(cairo_t* cr, double tx, double ty)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_translate", "cairo_t*"); Xen_check_type(Xen_is_double(tx), tx, 2, "cairo_translate", "double"); Xen_check_type(Xen_is_double(ty), ty, 3, "cairo_translate", "double"); cairo_translate(Xen_to_C_cairo_t_(cr), Xen_to_C_double(tx), Xen_to_C_double(ty)); return(Xen_false); } static Xen gxg_cairo_scale(Xen cr, Xen sx, Xen sy) { #define H_cairo_scale "void cairo_scale(cairo_t* cr, double sx, double sy)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_scale", "cairo_t*"); Xen_check_type(Xen_is_double(sx), sx, 2, "cairo_scale", "double"); Xen_check_type(Xen_is_double(sy), sy, 3, "cairo_scale", "double"); cairo_scale(Xen_to_C_cairo_t_(cr), Xen_to_C_double(sx), Xen_to_C_double(sy)); return(Xen_false); } static Xen gxg_cairo_rotate(Xen cr, Xen angle) { #define H_cairo_rotate "void cairo_rotate(cairo_t* cr, double angle)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_rotate", "cairo_t*"); Xen_check_type(Xen_is_double(angle), angle, 2, "cairo_rotate", "double"); cairo_rotate(Xen_to_C_cairo_t_(cr), Xen_to_C_double(angle)); return(Xen_false); } static Xen gxg_cairo_transform(Xen cr, Xen matrix) { #define H_cairo_transform "void cairo_transform(cairo_t* cr, cairo_matrix_t* matrix)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_transform", "cairo_t*"); Xen_check_type(Xen_is_cairo_matrix_t_(matrix), matrix, 2, "cairo_transform", "cairo_matrix_t*"); cairo_transform(Xen_to_C_cairo_t_(cr), Xen_to_C_cairo_matrix_t_(matrix)); return(Xen_false); } static Xen gxg_cairo_set_matrix(Xen cr, Xen matrix) { #define H_cairo_set_matrix "void cairo_set_matrix(cairo_t* cr, cairo_matrix_t* matrix)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_set_matrix", "cairo_t*"); Xen_check_type(Xen_is_cairo_matrix_t_(matrix), matrix, 2, "cairo_set_matrix", "cairo_matrix_t*"); cairo_set_matrix(Xen_to_C_cairo_t_(cr), Xen_to_C_cairo_matrix_t_(matrix)); return(Xen_false); } static Xen gxg_cairo_identity_matrix(Xen cr) { #define H_cairo_identity_matrix "void cairo_identity_matrix(cairo_t* cr)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_identity_matrix", "cairo_t*"); cairo_identity_matrix(Xen_to_C_cairo_t_(cr)); return(Xen_false); } static Xen gxg_cairo_user_to_device(Xen cr, Xen ignore_x, Xen ignore_y) { #define H_cairo_user_to_device "void cairo_user_to_device(cairo_t* cr, gdouble* [x], gdouble* [y])" gdouble ref_x; gdouble ref_y; Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_user_to_device", "cairo_t*"); cairo_user_to_device(Xen_to_C_cairo_t_(cr), &ref_x, &ref_y); return(Xen_list_2(C_to_Xen_gdouble(ref_x), C_to_Xen_gdouble(ref_y))); } static Xen gxg_cairo_user_to_device_distance(Xen cr, Xen ignore_dx, Xen ignore_dy) { #define H_cairo_user_to_device_distance "void cairo_user_to_device_distance(cairo_t* cr, gdouble* [dx], \ gdouble* [dy])" gdouble ref_dx; gdouble ref_dy; Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_user_to_device_distance", "cairo_t*"); cairo_user_to_device_distance(Xen_to_C_cairo_t_(cr), &ref_dx, &ref_dy); return(Xen_list_2(C_to_Xen_gdouble(ref_dx), C_to_Xen_gdouble(ref_dy))); } static Xen gxg_cairo_device_to_user(Xen cr, Xen ignore_x, Xen ignore_y) { #define H_cairo_device_to_user "void cairo_device_to_user(cairo_t* cr, gdouble* [x], gdouble* [y])" gdouble ref_x; gdouble ref_y; Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_device_to_user", "cairo_t*"); cairo_device_to_user(Xen_to_C_cairo_t_(cr), &ref_x, &ref_y); return(Xen_list_2(C_to_Xen_gdouble(ref_x), C_to_Xen_gdouble(ref_y))); } static Xen gxg_cairo_device_to_user_distance(Xen cr, Xen ignore_dx, Xen ignore_dy) { #define H_cairo_device_to_user_distance "void cairo_device_to_user_distance(cairo_t* cr, gdouble* [dx], \ gdouble* [dy])" gdouble ref_dx; gdouble ref_dy; Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_device_to_user_distance", "cairo_t*"); cairo_device_to_user_distance(Xen_to_C_cairo_t_(cr), &ref_dx, &ref_dy); return(Xen_list_2(C_to_Xen_gdouble(ref_dx), C_to_Xen_gdouble(ref_dy))); } static Xen gxg_cairo_new_path(Xen cr) { #define H_cairo_new_path "void cairo_new_path(cairo_t* cr)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_new_path", "cairo_t*"); cairo_new_path(Xen_to_C_cairo_t_(cr)); return(Xen_false); } static Xen gxg_cairo_move_to(Xen cr, Xen x, Xen y) { #define H_cairo_move_to "void cairo_move_to(cairo_t* cr, double x, double y)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_move_to", "cairo_t*"); Xen_check_type(Xen_is_double(x), x, 2, "cairo_move_to", "double"); Xen_check_type(Xen_is_double(y), y, 3, "cairo_move_to", "double"); cairo_move_to(Xen_to_C_cairo_t_(cr), Xen_to_C_double(x), Xen_to_C_double(y)); return(Xen_false); } static Xen gxg_cairo_new_sub_path(Xen cr) { #define H_cairo_new_sub_path "void cairo_new_sub_path(cairo_t* cr)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_new_sub_path", "cairo_t*"); cairo_new_sub_path(Xen_to_C_cairo_t_(cr)); return(Xen_false); } static Xen gxg_cairo_line_to(Xen cr, Xen x, Xen y) { #define H_cairo_line_to "void cairo_line_to(cairo_t* cr, double x, double y)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_line_to", "cairo_t*"); Xen_check_type(Xen_is_double(x), x, 2, "cairo_line_to", "double"); Xen_check_type(Xen_is_double(y), y, 3, "cairo_line_to", "double"); cairo_line_to(Xen_to_C_cairo_t_(cr), Xen_to_C_double(x), Xen_to_C_double(y)); return(Xen_false); } static Xen gxg_cairo_curve_to(Xen cr, Xen x1, Xen y1, Xen x2, Xen y2, Xen x3, Xen y3) { #define H_cairo_curve_to "void cairo_curve_to(cairo_t* cr, double x1, double y1, double x2, double y2, \ double x3, double y3)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_curve_to", "cairo_t*"); Xen_check_type(Xen_is_double(x1), x1, 2, "cairo_curve_to", "double"); Xen_check_type(Xen_is_double(y1), y1, 3, "cairo_curve_to", "double"); Xen_check_type(Xen_is_double(x2), x2, 4, "cairo_curve_to", "double"); Xen_check_type(Xen_is_double(y2), y2, 5, "cairo_curve_to", "double"); Xen_check_type(Xen_is_double(x3), x3, 6, "cairo_curve_to", "double"); Xen_check_type(Xen_is_double(y3), y3, 7, "cairo_curve_to", "double"); cairo_curve_to(Xen_to_C_cairo_t_(cr), Xen_to_C_double(x1), Xen_to_C_double(y1), Xen_to_C_double(x2), Xen_to_C_double(y2), Xen_to_C_double(x3), Xen_to_C_double(y3)); return(Xen_false); } static Xen gxg_cairo_arc(Xen cr, Xen xc, Xen yc, Xen radius, Xen angle1, Xen angle2) { #define H_cairo_arc "void cairo_arc(cairo_t* cr, double xc, double yc, double radius, double angle1, \ double angle2)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_arc", "cairo_t*"); Xen_check_type(Xen_is_double(xc), xc, 2, "cairo_arc", "double"); Xen_check_type(Xen_is_double(yc), yc, 3, "cairo_arc", "double"); Xen_check_type(Xen_is_double(radius), radius, 4, "cairo_arc", "double"); Xen_check_type(Xen_is_double(angle1), angle1, 5, "cairo_arc", "double"); Xen_check_type(Xen_is_double(angle2), angle2, 6, "cairo_arc", "double"); cairo_arc(Xen_to_C_cairo_t_(cr), Xen_to_C_double(xc), Xen_to_C_double(yc), Xen_to_C_double(radius), Xen_to_C_double(angle1), Xen_to_C_double(angle2)); return(Xen_false); } static Xen gxg_cairo_arc_negative(Xen cr, Xen xc, Xen yc, Xen radius, Xen angle1, Xen angle2) { #define H_cairo_arc_negative "void cairo_arc_negative(cairo_t* cr, double xc, double yc, double radius, \ double angle1, double angle2)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_arc_negative", "cairo_t*"); Xen_check_type(Xen_is_double(xc), xc, 2, "cairo_arc_negative", "double"); Xen_check_type(Xen_is_double(yc), yc, 3, "cairo_arc_negative", "double"); Xen_check_type(Xen_is_double(radius), radius, 4, "cairo_arc_negative", "double"); Xen_check_type(Xen_is_double(angle1), angle1, 5, "cairo_arc_negative", "double"); Xen_check_type(Xen_is_double(angle2), angle2, 6, "cairo_arc_negative", "double"); cairo_arc_negative(Xen_to_C_cairo_t_(cr), Xen_to_C_double(xc), Xen_to_C_double(yc), Xen_to_C_double(radius), Xen_to_C_double(angle1), Xen_to_C_double(angle2)); return(Xen_false); } static Xen gxg_cairo_rel_move_to(Xen cr, Xen dx, Xen dy) { #define H_cairo_rel_move_to "void cairo_rel_move_to(cairo_t* cr, double dx, double dy)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_rel_move_to", "cairo_t*"); Xen_check_type(Xen_is_double(dx), dx, 2, "cairo_rel_move_to", "double"); Xen_check_type(Xen_is_double(dy), dy, 3, "cairo_rel_move_to", "double"); cairo_rel_move_to(Xen_to_C_cairo_t_(cr), Xen_to_C_double(dx), Xen_to_C_double(dy)); return(Xen_false); } static Xen gxg_cairo_rel_line_to(Xen cr, Xen dx, Xen dy) { #define H_cairo_rel_line_to "void cairo_rel_line_to(cairo_t* cr, double dx, double dy)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_rel_line_to", "cairo_t*"); Xen_check_type(Xen_is_double(dx), dx, 2, "cairo_rel_line_to", "double"); Xen_check_type(Xen_is_double(dy), dy, 3, "cairo_rel_line_to", "double"); cairo_rel_line_to(Xen_to_C_cairo_t_(cr), Xen_to_C_double(dx), Xen_to_C_double(dy)); return(Xen_false); } static Xen gxg_cairo_rel_curve_to(Xen cr, Xen dx1, Xen dy1, Xen dx2, Xen dy2, Xen dx3, Xen dy3) { #define H_cairo_rel_curve_to "void cairo_rel_curve_to(cairo_t* cr, double dx1, double dy1, double dx2, \ double dy2, double dx3, double dy3)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_rel_curve_to", "cairo_t*"); Xen_check_type(Xen_is_double(dx1), dx1, 2, "cairo_rel_curve_to", "double"); Xen_check_type(Xen_is_double(dy1), dy1, 3, "cairo_rel_curve_to", "double"); Xen_check_type(Xen_is_double(dx2), dx2, 4, "cairo_rel_curve_to", "double"); Xen_check_type(Xen_is_double(dy2), dy2, 5, "cairo_rel_curve_to", "double"); Xen_check_type(Xen_is_double(dx3), dx3, 6, "cairo_rel_curve_to", "double"); Xen_check_type(Xen_is_double(dy3), dy3, 7, "cairo_rel_curve_to", "double"); cairo_rel_curve_to(Xen_to_C_cairo_t_(cr), Xen_to_C_double(dx1), Xen_to_C_double(dy1), Xen_to_C_double(dx2), Xen_to_C_double(dy2), Xen_to_C_double(dx3), Xen_to_C_double(dy3)); return(Xen_false); } static Xen gxg_cairo_rectangle(Xen cr, Xen x, Xen y, Xen width, Xen height) { #define H_cairo_rectangle "void cairo_rectangle(cairo_t* cr, double x, double y, double width, double height)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_rectangle", "cairo_t*"); Xen_check_type(Xen_is_double(x), x, 2, "cairo_rectangle", "double"); Xen_check_type(Xen_is_double(y), y, 3, "cairo_rectangle", "double"); Xen_check_type(Xen_is_double(width), width, 4, "cairo_rectangle", "double"); Xen_check_type(Xen_is_double(height), height, 5, "cairo_rectangle", "double"); cairo_rectangle(Xen_to_C_cairo_t_(cr), Xen_to_C_double(x), Xen_to_C_double(y), Xen_to_C_double(width), Xen_to_C_double(height)); return(Xen_false); } static Xen gxg_cairo_close_path(Xen cr) { #define H_cairo_close_path "void cairo_close_path(cairo_t* cr)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_close_path", "cairo_t*"); cairo_close_path(Xen_to_C_cairo_t_(cr)); return(Xen_false); } static Xen gxg_cairo_paint(Xen cr) { #define H_cairo_paint "void cairo_paint(cairo_t* cr)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_paint", "cairo_t*"); cairo_paint(Xen_to_C_cairo_t_(cr)); return(Xen_false); } static Xen gxg_cairo_paint_with_alpha(Xen cr, Xen alpha) { #define H_cairo_paint_with_alpha "void cairo_paint_with_alpha(cairo_t* cr, double alpha)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_paint_with_alpha", "cairo_t*"); Xen_check_type(Xen_is_double(alpha), alpha, 2, "cairo_paint_with_alpha", "double"); cairo_paint_with_alpha(Xen_to_C_cairo_t_(cr), Xen_to_C_double(alpha)); return(Xen_false); } static Xen gxg_cairo_mask(Xen cr, Xen pattern) { #define H_cairo_mask "void cairo_mask(cairo_t* cr, cairo_pattern_t* pattern)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_mask", "cairo_t*"); Xen_check_type(Xen_is_cairo_pattern_t_(pattern), pattern, 2, "cairo_mask", "cairo_pattern_t*"); cairo_mask(Xen_to_C_cairo_t_(cr), Xen_to_C_cairo_pattern_t_(pattern)); return(Xen_false); } static Xen gxg_cairo_mask_surface(Xen cr, Xen surface, Xen surface_x, Xen surface_y) { #define H_cairo_mask_surface "void cairo_mask_surface(cairo_t* cr, cairo_surface_t* surface, double surface_x, \ double surface_y)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_mask_surface", "cairo_t*"); Xen_check_type(Xen_is_cairo_surface_t_(surface), surface, 2, "cairo_mask_surface", "cairo_surface_t*"); Xen_check_type(Xen_is_double(surface_x), surface_x, 3, "cairo_mask_surface", "double"); Xen_check_type(Xen_is_double(surface_y), surface_y, 4, "cairo_mask_surface", "double"); cairo_mask_surface(Xen_to_C_cairo_t_(cr), Xen_to_C_cairo_surface_t_(surface), Xen_to_C_double(surface_x), Xen_to_C_double(surface_y)); return(Xen_false); } static Xen gxg_cairo_stroke(Xen cr) { #define H_cairo_stroke "void cairo_stroke(cairo_t* cr)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_stroke", "cairo_t*"); cairo_stroke(Xen_to_C_cairo_t_(cr)); return(Xen_false); } static Xen gxg_cairo_stroke_preserve(Xen cr) { #define H_cairo_stroke_preserve "void cairo_stroke_preserve(cairo_t* cr)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_stroke_preserve", "cairo_t*"); cairo_stroke_preserve(Xen_to_C_cairo_t_(cr)); return(Xen_false); } static Xen gxg_cairo_fill(Xen cr) { #define H_cairo_fill "void cairo_fill(cairo_t* cr)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_fill", "cairo_t*"); cairo_fill(Xen_to_C_cairo_t_(cr)); return(Xen_false); } static Xen gxg_cairo_fill_preserve(Xen cr) { #define H_cairo_fill_preserve "void cairo_fill_preserve(cairo_t* cr)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_fill_preserve", "cairo_t*"); cairo_fill_preserve(Xen_to_C_cairo_t_(cr)); return(Xen_false); } static Xen gxg_cairo_copy_page(Xen cr) { #define H_cairo_copy_page "void cairo_copy_page(cairo_t* cr)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_copy_page", "cairo_t*"); cairo_copy_page(Xen_to_C_cairo_t_(cr)); return(Xen_false); } static Xen gxg_cairo_show_page(Xen cr) { #define H_cairo_show_page "void cairo_show_page(cairo_t* cr)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_show_page", "cairo_t*"); cairo_show_page(Xen_to_C_cairo_t_(cr)); return(Xen_false); } static Xen gxg_cairo_in_stroke(Xen cr, Xen x, Xen y) { #define H_cairo_in_stroke "bool cairo_in_stroke(cairo_t* cr, double x, double y)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_in_stroke", "cairo_t*"); Xen_check_type(Xen_is_double(x), x, 2, "cairo_in_stroke", "double"); Xen_check_type(Xen_is_double(y), y, 3, "cairo_in_stroke", "double"); return(C_to_Xen_bool(cairo_in_stroke(Xen_to_C_cairo_t_(cr), Xen_to_C_double(x), Xen_to_C_double(y)))); } static Xen gxg_cairo_in_fill(Xen cr, Xen x, Xen y) { #define H_cairo_in_fill "bool cairo_in_fill(cairo_t* cr, double x, double y)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_in_fill", "cairo_t*"); Xen_check_type(Xen_is_double(x), x, 2, "cairo_in_fill", "double"); Xen_check_type(Xen_is_double(y), y, 3, "cairo_in_fill", "double"); return(C_to_Xen_bool(cairo_in_fill(Xen_to_C_cairo_t_(cr), Xen_to_C_double(x), Xen_to_C_double(y)))); } static Xen gxg_cairo_reset_clip(Xen cr) { #define H_cairo_reset_clip "void cairo_reset_clip(cairo_t* cr)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_reset_clip", "cairo_t*"); cairo_reset_clip(Xen_to_C_cairo_t_(cr)); return(Xen_false); } static Xen gxg_cairo_clip(Xen cr) { #define H_cairo_clip "void cairo_clip(cairo_t* cr)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_clip", "cairo_t*"); cairo_clip(Xen_to_C_cairo_t_(cr)); return(Xen_false); } static Xen gxg_cairo_clip_preserve(Xen cr) { #define H_cairo_clip_preserve "void cairo_clip_preserve(cairo_t* cr)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_clip_preserve", "cairo_t*"); cairo_clip_preserve(Xen_to_C_cairo_t_(cr)); return(Xen_false); } static Xen gxg_cairo_font_options_create(void) { #define H_cairo_font_options_create "cairo_font_options_t* cairo_font_options_create( void)" return(C_to_Xen_cairo_font_options_t_(cairo_font_options_create())); } static Xen gxg_cairo_font_options_copy(Xen original) { #define H_cairo_font_options_copy "cairo_font_options_t* cairo_font_options_copy(cairo_font_options_t* original)" Xen_check_type(Xen_is_cairo_font_options_t_(original), original, 1, "cairo_font_options_copy", "cairo_font_options_t*"); return(C_to_Xen_cairo_font_options_t_(cairo_font_options_copy(Xen_to_C_cairo_font_options_t_(original)))); } static Xen gxg_cairo_font_options_destroy(Xen options) { #define H_cairo_font_options_destroy "void cairo_font_options_destroy(cairo_font_options_t* options)" Xen_check_type(Xen_is_cairo_font_options_t_(options), options, 1, "cairo_font_options_destroy", "cairo_font_options_t*"); cairo_font_options_destroy(Xen_to_C_cairo_font_options_t_(options)); return(Xen_false); } static Xen gxg_cairo_font_options_status(Xen options) { #define H_cairo_font_options_status "cairo_status_t cairo_font_options_status(cairo_font_options_t* options)" Xen_check_type(Xen_is_cairo_font_options_t_(options), options, 1, "cairo_font_options_status", "cairo_font_options_t*"); return(C_to_Xen_cairo_status_t(cairo_font_options_status(Xen_to_C_cairo_font_options_t_(options)))); } static Xen gxg_cairo_font_options_merge(Xen options, Xen other) { #define H_cairo_font_options_merge "void cairo_font_options_merge(cairo_font_options_t* options, cairo_font_options_t* other)" Xen_check_type(Xen_is_cairo_font_options_t_(options), options, 1, "cairo_font_options_merge", "cairo_font_options_t*"); Xen_check_type(Xen_is_cairo_font_options_t_(other), other, 2, "cairo_font_options_merge", "cairo_font_options_t*"); cairo_font_options_merge(Xen_to_C_cairo_font_options_t_(options), Xen_to_C_cairo_font_options_t_(other)); return(Xen_false); } static Xen gxg_cairo_font_options_equal(Xen options, Xen other) { #define H_cairo_font_options_equal "bool cairo_font_options_equal(cairo_font_options_t* options, cairo_font_options_t* other)" Xen_check_type(Xen_is_cairo_font_options_t_(options), options, 1, "cairo_font_options_equal", "cairo_font_options_t*"); Xen_check_type(Xen_is_cairo_font_options_t_(other), other, 2, "cairo_font_options_equal", "cairo_font_options_t*"); return(C_to_Xen_bool(cairo_font_options_equal(Xen_to_C_cairo_font_options_t_(options), Xen_to_C_cairo_font_options_t_(other)))); } static Xen gxg_cairo_font_options_hash(Xen options) { #define H_cairo_font_options_hash "gulong cairo_font_options_hash(cairo_font_options_t* options)" Xen_check_type(Xen_is_cairo_font_options_t_(options), options, 1, "cairo_font_options_hash", "cairo_font_options_t*"); return(C_to_Xen_gulong(cairo_font_options_hash(Xen_to_C_cairo_font_options_t_(options)))); } static Xen gxg_cairo_font_options_set_antialias(Xen options, Xen antialias) { #define H_cairo_font_options_set_antialias "void cairo_font_options_set_antialias(cairo_font_options_t* options, \ cairo_antialias_t antialias)" Xen_check_type(Xen_is_cairo_font_options_t_(options), options, 1, "cairo_font_options_set_antialias", "cairo_font_options_t*"); Xen_check_type(Xen_is_cairo_antialias_t(antialias), antialias, 2, "cairo_font_options_set_antialias", "cairo_antialias_t"); cairo_font_options_set_antialias(Xen_to_C_cairo_font_options_t_(options), Xen_to_C_cairo_antialias_t(antialias)); return(Xen_false); } static Xen gxg_cairo_font_options_get_antialias(Xen options) { #define H_cairo_font_options_get_antialias "cairo_antialias_t cairo_font_options_get_antialias(cairo_font_options_t* options)" Xen_check_type(Xen_is_cairo_font_options_t_(options), options, 1, "cairo_font_options_get_antialias", "cairo_font_options_t*"); return(C_to_Xen_cairo_antialias_t(cairo_font_options_get_antialias(Xen_to_C_cairo_font_options_t_(options)))); } static Xen gxg_cairo_font_options_set_subpixel_order(Xen options, Xen subpixel_order) { #define H_cairo_font_options_set_subpixel_order "void cairo_font_options_set_subpixel_order(cairo_font_options_t* options, \ cairo_subpixel_order_t subpixel_order)" Xen_check_type(Xen_is_cairo_font_options_t_(options), options, 1, "cairo_font_options_set_subpixel_order", "cairo_font_options_t*"); Xen_check_type(Xen_is_cairo_subpixel_order_t(subpixel_order), subpixel_order, 2, "cairo_font_options_set_subpixel_order", "cairo_subpixel_order_t"); cairo_font_options_set_subpixel_order(Xen_to_C_cairo_font_options_t_(options), Xen_to_C_cairo_subpixel_order_t(subpixel_order)); return(Xen_false); } static Xen gxg_cairo_font_options_get_subpixel_order(Xen options) { #define H_cairo_font_options_get_subpixel_order "cairo_subpixel_order_t cairo_font_options_get_subpixel_order(cairo_font_options_t* options)" Xen_check_type(Xen_is_cairo_font_options_t_(options), options, 1, "cairo_font_options_get_subpixel_order", "cairo_font_options_t*"); return(C_to_Xen_cairo_subpixel_order_t(cairo_font_options_get_subpixel_order(Xen_to_C_cairo_font_options_t_(options)))); } static Xen gxg_cairo_font_options_set_hint_style(Xen options, Xen hint_style) { #define H_cairo_font_options_set_hint_style "void cairo_font_options_set_hint_style(cairo_font_options_t* options, \ cairo_hint_style_t hint_style)" Xen_check_type(Xen_is_cairo_font_options_t_(options), options, 1, "cairo_font_options_set_hint_style", "cairo_font_options_t*"); Xen_check_type(Xen_is_cairo_hint_style_t(hint_style), hint_style, 2, "cairo_font_options_set_hint_style", "cairo_hint_style_t"); cairo_font_options_set_hint_style(Xen_to_C_cairo_font_options_t_(options), Xen_to_C_cairo_hint_style_t(hint_style)); return(Xen_false); } static Xen gxg_cairo_font_options_get_hint_style(Xen options) { #define H_cairo_font_options_get_hint_style "cairo_hint_style_t cairo_font_options_get_hint_style(cairo_font_options_t* options)" Xen_check_type(Xen_is_cairo_font_options_t_(options), options, 1, "cairo_font_options_get_hint_style", "cairo_font_options_t*"); return(C_to_Xen_cairo_hint_style_t(cairo_font_options_get_hint_style(Xen_to_C_cairo_font_options_t_(options)))); } static Xen gxg_cairo_font_options_set_hint_metrics(Xen options, Xen hint_metrics) { #define H_cairo_font_options_set_hint_metrics "void cairo_font_options_set_hint_metrics(cairo_font_options_t* options, \ cairo_hint_metrics_t hint_metrics)" Xen_check_type(Xen_is_cairo_font_options_t_(options), options, 1, "cairo_font_options_set_hint_metrics", "cairo_font_options_t*"); Xen_check_type(Xen_is_cairo_hint_metrics_t(hint_metrics), hint_metrics, 2, "cairo_font_options_set_hint_metrics", "cairo_hint_metrics_t"); cairo_font_options_set_hint_metrics(Xen_to_C_cairo_font_options_t_(options), Xen_to_C_cairo_hint_metrics_t(hint_metrics)); return(Xen_false); } static Xen gxg_cairo_font_options_get_hint_metrics(Xen options) { #define H_cairo_font_options_get_hint_metrics "cairo_hint_metrics_t cairo_font_options_get_hint_metrics(cairo_font_options_t* options)" Xen_check_type(Xen_is_cairo_font_options_t_(options), options, 1, "cairo_font_options_get_hint_metrics", "cairo_font_options_t*"); return(C_to_Xen_cairo_hint_metrics_t(cairo_font_options_get_hint_metrics(Xen_to_C_cairo_font_options_t_(options)))); } static Xen gxg_cairo_select_font_face(Xen cr, Xen family, Xen slant, Xen weight) { #define H_cairo_select_font_face "void cairo_select_font_face(cairo_t* cr, char* family, cairo_font_slant_t slant, \ cairo_font_weight_t weight)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_select_font_face", "cairo_t*"); Xen_check_type(Xen_is_char_(family), family, 2, "cairo_select_font_face", "char*"); Xen_check_type(Xen_is_cairo_font_slant_t(slant), slant, 3, "cairo_select_font_face", "cairo_font_slant_t"); Xen_check_type(Xen_is_cairo_font_weight_t(weight), weight, 4, "cairo_select_font_face", "cairo_font_weight_t"); cairo_select_font_face(Xen_to_C_cairo_t_(cr), Xen_to_C_char_(family), Xen_to_C_cairo_font_slant_t(slant), Xen_to_C_cairo_font_weight_t(weight)); return(Xen_false); } static Xen gxg_cairo_set_font_size(Xen cr, Xen size) { #define H_cairo_set_font_size "void cairo_set_font_size(cairo_t* cr, double size)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_set_font_size", "cairo_t*"); Xen_check_type(Xen_is_double(size), size, 2, "cairo_set_font_size", "double"); cairo_set_font_size(Xen_to_C_cairo_t_(cr), Xen_to_C_double(size)); return(Xen_false); } static Xen gxg_cairo_set_font_matrix(Xen cr, Xen matrix) { #define H_cairo_set_font_matrix "void cairo_set_font_matrix(cairo_t* cr, cairo_matrix_t* matrix)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_set_font_matrix", "cairo_t*"); Xen_check_type(Xen_is_cairo_matrix_t_(matrix), matrix, 2, "cairo_set_font_matrix", "cairo_matrix_t*"); cairo_set_font_matrix(Xen_to_C_cairo_t_(cr), Xen_to_C_cairo_matrix_t_(matrix)); return(Xen_false); } static Xen gxg_cairo_get_font_matrix(Xen cr, Xen matrix) { #define H_cairo_get_font_matrix "void cairo_get_font_matrix(cairo_t* cr, cairo_matrix_t* matrix)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_get_font_matrix", "cairo_t*"); Xen_check_type(Xen_is_cairo_matrix_t_(matrix), matrix, 2, "cairo_get_font_matrix", "cairo_matrix_t*"); cairo_get_font_matrix(Xen_to_C_cairo_t_(cr), Xen_to_C_cairo_matrix_t_(matrix)); return(Xen_false); } static Xen gxg_cairo_set_font_options(Xen cr, Xen options) { #define H_cairo_set_font_options "void cairo_set_font_options(cairo_t* cr, cairo_font_options_t* options)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_set_font_options", "cairo_t*"); Xen_check_type(Xen_is_cairo_font_options_t_(options), options, 2, "cairo_set_font_options", "cairo_font_options_t*"); cairo_set_font_options(Xen_to_C_cairo_t_(cr), Xen_to_C_cairo_font_options_t_(options)); return(Xen_false); } static Xen gxg_cairo_get_font_options(Xen cr, Xen options) { #define H_cairo_get_font_options "void cairo_get_font_options(cairo_t* cr, cairo_font_options_t* options)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_get_font_options", "cairo_t*"); Xen_check_type(Xen_is_cairo_font_options_t_(options), options, 2, "cairo_get_font_options", "cairo_font_options_t*"); cairo_get_font_options(Xen_to_C_cairo_t_(cr), Xen_to_C_cairo_font_options_t_(options)); return(Xen_false); } static Xen gxg_cairo_set_scaled_font(Xen cr, Xen scaled_font) { #define H_cairo_set_scaled_font "void cairo_set_scaled_font(cairo_t* cr, cairo_scaled_font_t* scaled_font)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_set_scaled_font", "cairo_t*"); Xen_check_type(Xen_is_cairo_scaled_font_t_(scaled_font), scaled_font, 2, "cairo_set_scaled_font", "cairo_scaled_font_t*"); cairo_set_scaled_font(Xen_to_C_cairo_t_(cr), Xen_to_C_cairo_scaled_font_t_(scaled_font)); return(Xen_false); } static Xen gxg_cairo_show_text(Xen cr, Xen utf8) { #define H_cairo_show_text "void cairo_show_text(cairo_t* cr, char* utf8)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_show_text", "cairo_t*"); Xen_check_type(Xen_is_char_(utf8), utf8, 2, "cairo_show_text", "char*"); cairo_show_text(Xen_to_C_cairo_t_(cr), Xen_to_C_char_(utf8)); return(Xen_false); } static Xen gxg_cairo_show_glyphs(Xen cr, Xen glyphs, Xen num_glyphs) { #define H_cairo_show_glyphs "void cairo_show_glyphs(cairo_t* cr, cairo_glyph_t* glyphs, int num_glyphs)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_show_glyphs", "cairo_t*"); Xen_check_type(Xen_is_cairo_glyph_t_(glyphs), glyphs, 2, "cairo_show_glyphs", "cairo_glyph_t*"); Xen_check_type(Xen_is_int(num_glyphs), num_glyphs, 3, "cairo_show_glyphs", "int"); cairo_show_glyphs(Xen_to_C_cairo_t_(cr), Xen_to_C_cairo_glyph_t_(glyphs), Xen_to_C_int(num_glyphs)); return(Xen_false); } static Xen gxg_cairo_get_font_face(Xen cr) { #define H_cairo_get_font_face "cairo_font_face_t* cairo_get_font_face(cairo_t* cr)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_get_font_face", "cairo_t*"); return(C_to_Xen_cairo_font_face_t_(cairo_get_font_face(Xen_to_C_cairo_t_(cr)))); } static Xen gxg_cairo_font_extents(Xen cr, Xen extents) { #define H_cairo_font_extents "void cairo_font_extents(cairo_t* cr, cairo_font_extents_t* extents)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_font_extents", "cairo_t*"); Xen_check_type(Xen_is_cairo_font_extents_t_(extents), extents, 2, "cairo_font_extents", "cairo_font_extents_t*"); cairo_font_extents(Xen_to_C_cairo_t_(cr), Xen_to_C_cairo_font_extents_t_(extents)); return(Xen_false); } static Xen gxg_cairo_set_font_face(Xen cr, Xen font_face) { #define H_cairo_set_font_face "void cairo_set_font_face(cairo_t* cr, cairo_font_face_t* font_face)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_set_font_face", "cairo_t*"); Xen_check_type(Xen_is_cairo_font_face_t_(font_face), font_face, 2, "cairo_set_font_face", "cairo_font_face_t*"); cairo_set_font_face(Xen_to_C_cairo_t_(cr), Xen_to_C_cairo_font_face_t_(font_face)); return(Xen_false); } static Xen gxg_cairo_text_extents(Xen cr, Xen utf8, Xen extents) { #define H_cairo_text_extents "void cairo_text_extents(cairo_t* cr, char* utf8, cairo_text_extents_t* extents)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_text_extents", "cairo_t*"); Xen_check_type(Xen_is_char_(utf8), utf8, 2, "cairo_text_extents", "char*"); Xen_check_type(Xen_is_cairo_text_extents_t_(extents), extents, 3, "cairo_text_extents", "cairo_text_extents_t*"); cairo_text_extents(Xen_to_C_cairo_t_(cr), Xen_to_C_char_(utf8), Xen_to_C_cairo_text_extents_t_(extents)); return(Xen_false); } static Xen gxg_cairo_glyph_extents(Xen cr, Xen glyphs, Xen num_glyphs, Xen extents) { #define H_cairo_glyph_extents "void cairo_glyph_extents(cairo_t* cr, cairo_glyph_t* glyphs, int num_glyphs, \ cairo_text_extents_t* extents)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_glyph_extents", "cairo_t*"); Xen_check_type(Xen_is_cairo_glyph_t_(glyphs), glyphs, 2, "cairo_glyph_extents", "cairo_glyph_t*"); Xen_check_type(Xen_is_int(num_glyphs), num_glyphs, 3, "cairo_glyph_extents", "int"); Xen_check_type(Xen_is_cairo_text_extents_t_(extents), extents, 4, "cairo_glyph_extents", "cairo_text_extents_t*"); cairo_glyph_extents(Xen_to_C_cairo_t_(cr), Xen_to_C_cairo_glyph_t_(glyphs), Xen_to_C_int(num_glyphs), Xen_to_C_cairo_text_extents_t_(extents)); return(Xen_false); } static Xen gxg_cairo_text_path(Xen cr, Xen utf8) { #define H_cairo_text_path "void cairo_text_path(cairo_t* cr, char* utf8)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_text_path", "cairo_t*"); Xen_check_type(Xen_is_char_(utf8), utf8, 2, "cairo_text_path", "char*"); cairo_text_path(Xen_to_C_cairo_t_(cr), Xen_to_C_char_(utf8)); return(Xen_false); } static Xen gxg_cairo_glyph_path(Xen cr, Xen glyphs, Xen num_glyphs) { #define H_cairo_glyph_path "void cairo_glyph_path(cairo_t* cr, cairo_glyph_t* glyphs, int num_glyphs)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_glyph_path", "cairo_t*"); Xen_check_type(Xen_is_cairo_glyph_t_(glyphs), glyphs, 2, "cairo_glyph_path", "cairo_glyph_t*"); Xen_check_type(Xen_is_int(num_glyphs), num_glyphs, 3, "cairo_glyph_path", "int"); cairo_glyph_path(Xen_to_C_cairo_t_(cr), Xen_to_C_cairo_glyph_t_(glyphs), Xen_to_C_int(num_glyphs)); return(Xen_false); } static Xen gxg_cairo_font_face_reference(Xen font_face) { #define H_cairo_font_face_reference "cairo_font_face_t* cairo_font_face_reference(cairo_font_face_t* font_face)" Xen_check_type(Xen_is_cairo_font_face_t_(font_face), font_face, 1, "cairo_font_face_reference", "cairo_font_face_t*"); return(C_to_Xen_cairo_font_face_t_(cairo_font_face_reference(Xen_to_C_cairo_font_face_t_(font_face)))); } static Xen gxg_cairo_font_face_destroy(Xen font_face) { #define H_cairo_font_face_destroy "void cairo_font_face_destroy(cairo_font_face_t* font_face)" Xen_check_type(Xen_is_cairo_font_face_t_(font_face), font_face, 1, "cairo_font_face_destroy", "cairo_font_face_t*"); cairo_font_face_destroy(Xen_to_C_cairo_font_face_t_(font_face)); return(Xen_false); } static Xen gxg_cairo_font_face_status(Xen font_face) { #define H_cairo_font_face_status "cairo_status_t cairo_font_face_status(cairo_font_face_t* font_face)" Xen_check_type(Xen_is_cairo_font_face_t_(font_face), font_face, 1, "cairo_font_face_status", "cairo_font_face_t*"); return(C_to_Xen_cairo_status_t(cairo_font_face_status(Xen_to_C_cairo_font_face_t_(font_face)))); } static Xen gxg_cairo_font_face_get_user_data(Xen font_face, Xen key) { #define H_cairo_font_face_get_user_data "gpointer cairo_font_face_get_user_data(cairo_font_face_t* font_face, \ cairo_user_data_key_t* key)" Xen_check_type(Xen_is_cairo_font_face_t_(font_face), font_face, 1, "cairo_font_face_get_user_data", "cairo_font_face_t*"); Xen_check_type(Xen_is_cairo_user_data_key_t_(key), key, 2, "cairo_font_face_get_user_data", "cairo_user_data_key_t*"); return(C_to_Xen_gpointer(cairo_font_face_get_user_data(Xen_to_C_cairo_font_face_t_(font_face), Xen_to_C_cairo_user_data_key_t_(key)))); } static Xen gxg_cairo_font_face_set_user_data(Xen font_face, Xen key, Xen user_data, Xen destroy) { #define H_cairo_font_face_set_user_data "cairo_status_t cairo_font_face_set_user_data(cairo_font_face_t* font_face, \ cairo_user_data_key_t* key, gpointer user_data, cairo_destroy_func_t destroy)" Xen_check_type(Xen_is_cairo_font_face_t_(font_face), font_face, 1, "cairo_font_face_set_user_data", "cairo_font_face_t*"); Xen_check_type(Xen_is_cairo_user_data_key_t_(key), key, 2, "cairo_font_face_set_user_data", "cairo_user_data_key_t*"); Xen_check_type(Xen_is_gpointer(user_data), user_data, 3, "cairo_font_face_set_user_data", "gpointer"); Xen_check_type(Xen_is_cairo_destroy_func_t(destroy), destroy, 4, "cairo_font_face_set_user_data", "cairo_destroy_func_t"); return(C_to_Xen_cairo_status_t(cairo_font_face_set_user_data(Xen_to_C_cairo_font_face_t_(font_face), Xen_to_C_cairo_user_data_key_t_(key), Xen_to_C_gpointer(user_data), Xen_to_C_cairo_destroy_func_t(destroy)))); } static Xen gxg_cairo_scaled_font_create(Xen font_face, Xen font_matrix, Xen ctm, Xen options) { #define H_cairo_scaled_font_create "cairo_scaled_font_t* cairo_scaled_font_create(cairo_font_face_t* font_face, \ cairo_matrix_t* font_matrix, cairo_matrix_t* ctm, cairo_font_options_t* options)" Xen_check_type(Xen_is_cairo_font_face_t_(font_face), font_face, 1, "cairo_scaled_font_create", "cairo_font_face_t*"); Xen_check_type(Xen_is_cairo_matrix_t_(font_matrix), font_matrix, 2, "cairo_scaled_font_create", "cairo_matrix_t*"); Xen_check_type(Xen_is_cairo_matrix_t_(ctm), ctm, 3, "cairo_scaled_font_create", "cairo_matrix_t*"); Xen_check_type(Xen_is_cairo_font_options_t_(options), options, 4, "cairo_scaled_font_create", "cairo_font_options_t*"); return(C_to_Xen_cairo_scaled_font_t_(cairo_scaled_font_create(Xen_to_C_cairo_font_face_t_(font_face), Xen_to_C_cairo_matrix_t_(font_matrix), Xen_to_C_cairo_matrix_t_(ctm), Xen_to_C_cairo_font_options_t_(options)))); } static Xen gxg_cairo_scaled_font_reference(Xen scaled_font) { #define H_cairo_scaled_font_reference "cairo_scaled_font_t* cairo_scaled_font_reference(cairo_scaled_font_t* scaled_font)" Xen_check_type(Xen_is_cairo_scaled_font_t_(scaled_font), scaled_font, 1, "cairo_scaled_font_reference", "cairo_scaled_font_t*"); return(C_to_Xen_cairo_scaled_font_t_(cairo_scaled_font_reference(Xen_to_C_cairo_scaled_font_t_(scaled_font)))); } static Xen gxg_cairo_scaled_font_destroy(Xen scaled_font) { #define H_cairo_scaled_font_destroy "void cairo_scaled_font_destroy(cairo_scaled_font_t* scaled_font)" Xen_check_type(Xen_is_cairo_scaled_font_t_(scaled_font), scaled_font, 1, "cairo_scaled_font_destroy", "cairo_scaled_font_t*"); cairo_scaled_font_destroy(Xen_to_C_cairo_scaled_font_t_(scaled_font)); return(Xen_false); } static Xen gxg_cairo_scaled_font_status(Xen scaled_font) { #define H_cairo_scaled_font_status "cairo_status_t cairo_scaled_font_status(cairo_scaled_font_t* scaled_font)" Xen_check_type(Xen_is_cairo_scaled_font_t_(scaled_font), scaled_font, 1, "cairo_scaled_font_status", "cairo_scaled_font_t*"); return(C_to_Xen_cairo_status_t(cairo_scaled_font_status(Xen_to_C_cairo_scaled_font_t_(scaled_font)))); } static Xen gxg_cairo_scaled_font_extents(Xen scaled_font, Xen extents) { #define H_cairo_scaled_font_extents "void cairo_scaled_font_extents(cairo_scaled_font_t* scaled_font, \ cairo_font_extents_t* extents)" Xen_check_type(Xen_is_cairo_scaled_font_t_(scaled_font), scaled_font, 1, "cairo_scaled_font_extents", "cairo_scaled_font_t*"); Xen_check_type(Xen_is_cairo_font_extents_t_(extents), extents, 2, "cairo_scaled_font_extents", "cairo_font_extents_t*"); cairo_scaled_font_extents(Xen_to_C_cairo_scaled_font_t_(scaled_font), Xen_to_C_cairo_font_extents_t_(extents)); return(Xen_false); } static Xen gxg_cairo_scaled_font_text_extents(Xen scaled_font, Xen utf8, Xen extents) { #define H_cairo_scaled_font_text_extents "void cairo_scaled_font_text_extents(cairo_scaled_font_t* scaled_font, \ char* utf8, cairo_text_extents_t* extents)" Xen_check_type(Xen_is_cairo_scaled_font_t_(scaled_font), scaled_font, 1, "cairo_scaled_font_text_extents", "cairo_scaled_font_t*"); Xen_check_type(Xen_is_char_(utf8), utf8, 2, "cairo_scaled_font_text_extents", "char*"); Xen_check_type(Xen_is_cairo_text_extents_t_(extents), extents, 3, "cairo_scaled_font_text_extents", "cairo_text_extents_t*"); cairo_scaled_font_text_extents(Xen_to_C_cairo_scaled_font_t_(scaled_font), Xen_to_C_char_(utf8), Xen_to_C_cairo_text_extents_t_(extents)); return(Xen_false); } static Xen gxg_cairo_scaled_font_glyph_extents(Xen scaled_font, Xen glyphs, Xen num_glyphs, Xen extents) { #define H_cairo_scaled_font_glyph_extents "void cairo_scaled_font_glyph_extents(cairo_scaled_font_t* scaled_font, \ cairo_glyph_t* glyphs, int num_glyphs, cairo_text_extents_t* extents)" Xen_check_type(Xen_is_cairo_scaled_font_t_(scaled_font), scaled_font, 1, "cairo_scaled_font_glyph_extents", "cairo_scaled_font_t*"); Xen_check_type(Xen_is_cairo_glyph_t_(glyphs), glyphs, 2, "cairo_scaled_font_glyph_extents", "cairo_glyph_t*"); Xen_check_type(Xen_is_int(num_glyphs), num_glyphs, 3, "cairo_scaled_font_glyph_extents", "int"); Xen_check_type(Xen_is_cairo_text_extents_t_(extents), extents, 4, "cairo_scaled_font_glyph_extents", "cairo_text_extents_t*"); cairo_scaled_font_glyph_extents(Xen_to_C_cairo_scaled_font_t_(scaled_font), Xen_to_C_cairo_glyph_t_(glyphs), Xen_to_C_int(num_glyphs), Xen_to_C_cairo_text_extents_t_(extents)); return(Xen_false); } static Xen gxg_cairo_scaled_font_get_font_face(Xen scaled_font) { #define H_cairo_scaled_font_get_font_face "cairo_font_face_t* cairo_scaled_font_get_font_face(cairo_scaled_font_t* scaled_font)" Xen_check_type(Xen_is_cairo_scaled_font_t_(scaled_font), scaled_font, 1, "cairo_scaled_font_get_font_face", "cairo_scaled_font_t*"); return(C_to_Xen_cairo_font_face_t_(cairo_scaled_font_get_font_face(Xen_to_C_cairo_scaled_font_t_(scaled_font)))); } static Xen gxg_cairo_scaled_font_get_font_matrix(Xen scaled_font, Xen font_matrix) { #define H_cairo_scaled_font_get_font_matrix "void cairo_scaled_font_get_font_matrix(cairo_scaled_font_t* scaled_font, \ cairo_matrix_t* font_matrix)" Xen_check_type(Xen_is_cairo_scaled_font_t_(scaled_font), scaled_font, 1, "cairo_scaled_font_get_font_matrix", "cairo_scaled_font_t*"); Xen_check_type(Xen_is_cairo_matrix_t_(font_matrix), font_matrix, 2, "cairo_scaled_font_get_font_matrix", "cairo_matrix_t*"); cairo_scaled_font_get_font_matrix(Xen_to_C_cairo_scaled_font_t_(scaled_font), Xen_to_C_cairo_matrix_t_(font_matrix)); return(Xen_false); } static Xen gxg_cairo_scaled_font_get_ctm(Xen scaled_font, Xen ctm) { #define H_cairo_scaled_font_get_ctm "void cairo_scaled_font_get_ctm(cairo_scaled_font_t* scaled_font, \ cairo_matrix_t* ctm)" Xen_check_type(Xen_is_cairo_scaled_font_t_(scaled_font), scaled_font, 1, "cairo_scaled_font_get_ctm", "cairo_scaled_font_t*"); Xen_check_type(Xen_is_cairo_matrix_t_(ctm), ctm, 2, "cairo_scaled_font_get_ctm", "cairo_matrix_t*"); cairo_scaled_font_get_ctm(Xen_to_C_cairo_scaled_font_t_(scaled_font), Xen_to_C_cairo_matrix_t_(ctm)); return(Xen_false); } static Xen gxg_cairo_scaled_font_get_font_options(Xen scaled_font, Xen options) { #define H_cairo_scaled_font_get_font_options "void cairo_scaled_font_get_font_options(cairo_scaled_font_t* scaled_font, \ cairo_font_options_t* options)" Xen_check_type(Xen_is_cairo_scaled_font_t_(scaled_font), scaled_font, 1, "cairo_scaled_font_get_font_options", "cairo_scaled_font_t*"); Xen_check_type(Xen_is_cairo_font_options_t_(options), options, 2, "cairo_scaled_font_get_font_options", "cairo_font_options_t*"); cairo_scaled_font_get_font_options(Xen_to_C_cairo_scaled_font_t_(scaled_font), Xen_to_C_cairo_font_options_t_(options)); return(Xen_false); } static Xen gxg_cairo_get_operator(Xen cr) { #define H_cairo_get_operator "cairo_operator_t cairo_get_operator(cairo_t* cr)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_get_operator", "cairo_t*"); return(C_to_Xen_cairo_operator_t(cairo_get_operator(Xen_to_C_cairo_t_(cr)))); } static Xen gxg_cairo_get_source(Xen cr) { #define H_cairo_get_source "cairo_pattern_t* cairo_get_source(cairo_t* cr)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_get_source", "cairo_t*"); return(C_to_Xen_cairo_pattern_t_(cairo_get_source(Xen_to_C_cairo_t_(cr)))); } static Xen gxg_cairo_get_tolerance(Xen cr) { #define H_cairo_get_tolerance "gdouble cairo_get_tolerance(cairo_t* cr)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_get_tolerance", "cairo_t*"); return(C_to_Xen_gdouble(cairo_get_tolerance(Xen_to_C_cairo_t_(cr)))); } static Xen gxg_cairo_get_antialias(Xen cr) { #define H_cairo_get_antialias "cairo_antialias_t cairo_get_antialias(cairo_t* cr)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_get_antialias", "cairo_t*"); return(C_to_Xen_cairo_antialias_t(cairo_get_antialias(Xen_to_C_cairo_t_(cr)))); } static Xen gxg_cairo_get_current_point(Xen cr, Xen ignore_x, Xen ignore_y) { #define H_cairo_get_current_point "void cairo_get_current_point(cairo_t* cr, gdouble* [x], gdouble* [y])" gdouble ref_x; gdouble ref_y; Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_get_current_point", "cairo_t*"); cairo_get_current_point(Xen_to_C_cairo_t_(cr), &ref_x, &ref_y); return(Xen_list_2(C_to_Xen_gdouble(ref_x), C_to_Xen_gdouble(ref_y))); } static Xen gxg_cairo_get_fill_rule(Xen cr) { #define H_cairo_get_fill_rule "cairo_fill_rule_t cairo_get_fill_rule(cairo_t* cr)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_get_fill_rule", "cairo_t*"); return(C_to_Xen_cairo_fill_rule_t(cairo_get_fill_rule(Xen_to_C_cairo_t_(cr)))); } static Xen gxg_cairo_get_line_width(Xen cr) { #define H_cairo_get_line_width "gdouble cairo_get_line_width(cairo_t* cr)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_get_line_width", "cairo_t*"); return(C_to_Xen_gdouble(cairo_get_line_width(Xen_to_C_cairo_t_(cr)))); } static Xen gxg_cairo_get_line_cap(Xen cr) { #define H_cairo_get_line_cap "cairo_line_cap_t cairo_get_line_cap(cairo_t* cr)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_get_line_cap", "cairo_t*"); return(C_to_Xen_cairo_line_cap_t(cairo_get_line_cap(Xen_to_C_cairo_t_(cr)))); } static Xen gxg_cairo_get_line_join(Xen cr) { #define H_cairo_get_line_join "cairo_line_join_t cairo_get_line_join(cairo_t* cr)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_get_line_join", "cairo_t*"); return(C_to_Xen_cairo_line_join_t(cairo_get_line_join(Xen_to_C_cairo_t_(cr)))); } static Xen gxg_cairo_get_miter_limit(Xen cr) { #define H_cairo_get_miter_limit "gdouble cairo_get_miter_limit(cairo_t* cr)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_get_miter_limit", "cairo_t*"); return(C_to_Xen_gdouble(cairo_get_miter_limit(Xen_to_C_cairo_t_(cr)))); } static Xen gxg_cairo_get_matrix(Xen cr, Xen matrix) { #define H_cairo_get_matrix "void cairo_get_matrix(cairo_t* cr, cairo_matrix_t* matrix)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_get_matrix", "cairo_t*"); Xen_check_type(Xen_is_cairo_matrix_t_(matrix), matrix, 2, "cairo_get_matrix", "cairo_matrix_t*"); cairo_get_matrix(Xen_to_C_cairo_t_(cr), Xen_to_C_cairo_matrix_t_(matrix)); return(Xen_false); } static Xen gxg_cairo_get_target(Xen cr) { #define H_cairo_get_target "cairo_surface_t* cairo_get_target(cairo_t* cr)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_get_target", "cairo_t*"); return(C_to_Xen_cairo_surface_t_(cairo_get_target(Xen_to_C_cairo_t_(cr)))); } static Xen gxg_cairo_get_group_target(Xen cr) { #define H_cairo_get_group_target "cairo_surface_t* cairo_get_group_target(cairo_t* cr)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_get_group_target", "cairo_t*"); return(C_to_Xen_cairo_surface_t_(cairo_get_group_target(Xen_to_C_cairo_t_(cr)))); } static Xen gxg_cairo_copy_path(Xen cr) { #define H_cairo_copy_path "cairo_path_t* cairo_copy_path(cairo_t* cr)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_copy_path", "cairo_t*"); return(C_to_Xen_cairo_path_t_(cairo_copy_path(Xen_to_C_cairo_t_(cr)))); } static Xen gxg_cairo_copy_path_flat(Xen cr) { #define H_cairo_copy_path_flat "cairo_path_t* cairo_copy_path_flat(cairo_t* cr)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_copy_path_flat", "cairo_t*"); return(C_to_Xen_cairo_path_t_(cairo_copy_path_flat(Xen_to_C_cairo_t_(cr)))); } static Xen gxg_cairo_append_path(Xen cr, Xen path) { #define H_cairo_append_path "void cairo_append_path(cairo_t* cr, cairo_path_t* path)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_append_path", "cairo_t*"); Xen_check_type(Xen_is_cairo_path_t_(path), path, 2, "cairo_append_path", "cairo_path_t*"); cairo_append_path(Xen_to_C_cairo_t_(cr), Xen_to_C_cairo_path_t_(path)); return(Xen_false); } static Xen gxg_cairo_path_destroy(Xen path) { #define H_cairo_path_destroy "void cairo_path_destroy(cairo_path_t* path)" Xen_check_type(Xen_is_cairo_path_t_(path), path, 1, "cairo_path_destroy", "cairo_path_t*"); cairo_path_destroy(Xen_to_C_cairo_path_t_(path)); return(Xen_false); } static Xen gxg_cairo_status(Xen cr) { #define H_cairo_status "cairo_status_t cairo_status(cairo_t* cr)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_status", "cairo_t*"); return(C_to_Xen_cairo_status_t(cairo_status(Xen_to_C_cairo_t_(cr)))); } static Xen gxg_cairo_status_to_string(Xen status) { #define H_cairo_status_to_string "char* cairo_status_to_string(cairo_status_t status)" Xen_check_type(Xen_is_cairo_status_t(status), status, 1, "cairo_status_to_string", "cairo_status_t"); return(C_to_Xen_char_(cairo_status_to_string(Xen_to_C_cairo_status_t(status)))); } static Xen gxg_cairo_surface_create_similar(Xen other, Xen content, Xen width, Xen height) { #define H_cairo_surface_create_similar "cairo_surface_t* cairo_surface_create_similar(cairo_surface_t* other, \ cairo_content_t content, int width, int height)" Xen_check_type(Xen_is_cairo_surface_t_(other), other, 1, "cairo_surface_create_similar", "cairo_surface_t*"); Xen_check_type(Xen_is_cairo_content_t(content), content, 2, "cairo_surface_create_similar", "cairo_content_t"); Xen_check_type(Xen_is_int(width), width, 3, "cairo_surface_create_similar", "int"); Xen_check_type(Xen_is_int(height), height, 4, "cairo_surface_create_similar", "int"); return(C_to_Xen_cairo_surface_t_(cairo_surface_create_similar(Xen_to_C_cairo_surface_t_(other), Xen_to_C_cairo_content_t(content), Xen_to_C_int(width), Xen_to_C_int(height)))); } static Xen gxg_cairo_surface_reference(Xen surface) { #define H_cairo_surface_reference "cairo_surface_t* cairo_surface_reference(cairo_surface_t* surface)" Xen_check_type(Xen_is_cairo_surface_t_(surface), surface, 1, "cairo_surface_reference", "cairo_surface_t*"); return(C_to_Xen_cairo_surface_t_(cairo_surface_reference(Xen_to_C_cairo_surface_t_(surface)))); } static Xen gxg_cairo_surface_finish(Xen surface) { #define H_cairo_surface_finish "void cairo_surface_finish(cairo_surface_t* surface)" Xen_check_type(Xen_is_cairo_surface_t_(surface), surface, 1, "cairo_surface_finish", "cairo_surface_t*"); cairo_surface_finish(Xen_to_C_cairo_surface_t_(surface)); return(Xen_false); } static Xen gxg_cairo_surface_destroy(Xen surface) { #define H_cairo_surface_destroy "void cairo_surface_destroy(cairo_surface_t* surface)" Xen_check_type(Xen_is_cairo_surface_t_(surface), surface, 1, "cairo_surface_destroy", "cairo_surface_t*"); cairo_surface_destroy(Xen_to_C_cairo_surface_t_(surface)); return(Xen_false); } static Xen gxg_cairo_surface_status(Xen surface) { #define H_cairo_surface_status "cairo_status_t cairo_surface_status(cairo_surface_t* surface)" Xen_check_type(Xen_is_cairo_surface_t_(surface), surface, 1, "cairo_surface_status", "cairo_surface_t*"); return(C_to_Xen_cairo_status_t(cairo_surface_status(Xen_to_C_cairo_surface_t_(surface)))); } static Xen gxg_cairo_surface_get_content(Xen surface) { #define H_cairo_surface_get_content "cairo_content_t cairo_surface_get_content(cairo_surface_t* surface)" Xen_check_type(Xen_is_cairo_surface_t_(surface), surface, 1, "cairo_surface_get_content", "cairo_surface_t*"); return(C_to_Xen_cairo_content_t(cairo_surface_get_content(Xen_to_C_cairo_surface_t_(surface)))); } static Xen gxg_cairo_surface_get_user_data(Xen surface, Xen key) { #define H_cairo_surface_get_user_data "gpointer cairo_surface_get_user_data(cairo_surface_t* surface, \ cairo_user_data_key_t* key)" Xen_check_type(Xen_is_cairo_surface_t_(surface), surface, 1, "cairo_surface_get_user_data", "cairo_surface_t*"); Xen_check_type(Xen_is_cairo_user_data_key_t_(key), key, 2, "cairo_surface_get_user_data", "cairo_user_data_key_t*"); return(C_to_Xen_gpointer(cairo_surface_get_user_data(Xen_to_C_cairo_surface_t_(surface), Xen_to_C_cairo_user_data_key_t_(key)))); } static Xen gxg_cairo_surface_set_user_data(Xen surface, Xen key, Xen user_data, Xen destroy) { #define H_cairo_surface_set_user_data "cairo_status_t cairo_surface_set_user_data(cairo_surface_t* surface, \ cairo_user_data_key_t* key, gpointer user_data, cairo_destroy_func_t destroy)" Xen_check_type(Xen_is_cairo_surface_t_(surface), surface, 1, "cairo_surface_set_user_data", "cairo_surface_t*"); Xen_check_type(Xen_is_cairo_user_data_key_t_(key), key, 2, "cairo_surface_set_user_data", "cairo_user_data_key_t*"); Xen_check_type(Xen_is_gpointer(user_data), user_data, 3, "cairo_surface_set_user_data", "gpointer"); Xen_check_type(Xen_is_cairo_destroy_func_t(destroy), destroy, 4, "cairo_surface_set_user_data", "cairo_destroy_func_t"); return(C_to_Xen_cairo_status_t(cairo_surface_set_user_data(Xen_to_C_cairo_surface_t_(surface), Xen_to_C_cairo_user_data_key_t_(key), Xen_to_C_gpointer(user_data), Xen_to_C_cairo_destroy_func_t(destroy)))); } static Xen gxg_cairo_surface_get_font_options(Xen surface, Xen options) { #define H_cairo_surface_get_font_options "void cairo_surface_get_font_options(cairo_surface_t* surface, \ cairo_font_options_t* options)" Xen_check_type(Xen_is_cairo_surface_t_(surface), surface, 1, "cairo_surface_get_font_options", "cairo_surface_t*"); Xen_check_type(Xen_is_cairo_font_options_t_(options), options, 2, "cairo_surface_get_font_options", "cairo_font_options_t*"); cairo_surface_get_font_options(Xen_to_C_cairo_surface_t_(surface), Xen_to_C_cairo_font_options_t_(options)); return(Xen_false); } static Xen gxg_cairo_surface_flush(Xen surface) { #define H_cairo_surface_flush "void cairo_surface_flush(cairo_surface_t* surface)" Xen_check_type(Xen_is_cairo_surface_t_(surface), surface, 1, "cairo_surface_flush", "cairo_surface_t*"); cairo_surface_flush(Xen_to_C_cairo_surface_t_(surface)); return(Xen_false); } static Xen gxg_cairo_surface_mark_dirty(Xen surface) { #define H_cairo_surface_mark_dirty "void cairo_surface_mark_dirty(cairo_surface_t* surface)" Xen_check_type(Xen_is_cairo_surface_t_(surface), surface, 1, "cairo_surface_mark_dirty", "cairo_surface_t*"); cairo_surface_mark_dirty(Xen_to_C_cairo_surface_t_(surface)); return(Xen_false); } static Xen gxg_cairo_surface_mark_dirty_rectangle(Xen surface, Xen x, Xen y, Xen width, Xen height) { #define H_cairo_surface_mark_dirty_rectangle "void cairo_surface_mark_dirty_rectangle(cairo_surface_t* surface, \ int x, int y, int width, int height)" Xen_check_type(Xen_is_cairo_surface_t_(surface), surface, 1, "cairo_surface_mark_dirty_rectangle", "cairo_surface_t*"); Xen_check_type(Xen_is_int(x), x, 2, "cairo_surface_mark_dirty_rectangle", "int"); Xen_check_type(Xen_is_int(y), y, 3, "cairo_surface_mark_dirty_rectangle", "int"); Xen_check_type(Xen_is_int(width), width, 4, "cairo_surface_mark_dirty_rectangle", "int"); Xen_check_type(Xen_is_int(height), height, 5, "cairo_surface_mark_dirty_rectangle", "int"); cairo_surface_mark_dirty_rectangle(Xen_to_C_cairo_surface_t_(surface), Xen_to_C_int(x), Xen_to_C_int(y), Xen_to_C_int(width), Xen_to_C_int(height)); return(Xen_false); } static Xen gxg_cairo_surface_set_device_offset(Xen surface, Xen x_offset, Xen y_offset) { #define H_cairo_surface_set_device_offset "void cairo_surface_set_device_offset(cairo_surface_t* surface, \ double x_offset, double y_offset)" Xen_check_type(Xen_is_cairo_surface_t_(surface), surface, 1, "cairo_surface_set_device_offset", "cairo_surface_t*"); Xen_check_type(Xen_is_double(x_offset), x_offset, 2, "cairo_surface_set_device_offset", "double"); Xen_check_type(Xen_is_double(y_offset), y_offset, 3, "cairo_surface_set_device_offset", "double"); cairo_surface_set_device_offset(Xen_to_C_cairo_surface_t_(surface), Xen_to_C_double(x_offset), Xen_to_C_double(y_offset)); return(Xen_false); } static Xen gxg_cairo_surface_get_device_offset(Xen surface, Xen ignore_x_offset, Xen ignore_y_offset) { #define H_cairo_surface_get_device_offset "void cairo_surface_get_device_offset(cairo_surface_t* surface, \ gdouble* [x_offset], gdouble* [y_offset])" gdouble ref_x_offset; gdouble ref_y_offset; Xen_check_type(Xen_is_cairo_surface_t_(surface), surface, 1, "cairo_surface_get_device_offset", "cairo_surface_t*"); cairo_surface_get_device_offset(Xen_to_C_cairo_surface_t_(surface), &ref_x_offset, &ref_y_offset); return(Xen_list_2(C_to_Xen_gdouble(ref_x_offset), C_to_Xen_gdouble(ref_y_offset))); } static Xen gxg_cairo_surface_set_fallback_resolution(Xen surface, Xen x_pixels_per_inch, Xen y_pixels_per_inch) { #define H_cairo_surface_set_fallback_resolution "void cairo_surface_set_fallback_resolution(cairo_surface_t* surface, \ double x_pixels_per_inch, double y_pixels_per_inch)" Xen_check_type(Xen_is_cairo_surface_t_(surface), surface, 1, "cairo_surface_set_fallback_resolution", "cairo_surface_t*"); Xen_check_type(Xen_is_double(x_pixels_per_inch), x_pixels_per_inch, 2, "cairo_surface_set_fallback_resolution", "double"); Xen_check_type(Xen_is_double(y_pixels_per_inch), y_pixels_per_inch, 3, "cairo_surface_set_fallback_resolution", "double"); cairo_surface_set_fallback_resolution(Xen_to_C_cairo_surface_t_(surface), Xen_to_C_double(x_pixels_per_inch), Xen_to_C_double(y_pixels_per_inch)); return(Xen_false); } static Xen gxg_cairo_image_surface_create(Xen format, Xen width, Xen height) { #define H_cairo_image_surface_create "cairo_surface_t* cairo_image_surface_create(cairo_format_t format, \ int width, int height)" Xen_check_type(Xen_is_cairo_format_t(format), format, 1, "cairo_image_surface_create", "cairo_format_t"); Xen_check_type(Xen_is_int(width), width, 2, "cairo_image_surface_create", "int"); Xen_check_type(Xen_is_int(height), height, 3, "cairo_image_surface_create", "int"); return(C_to_Xen_cairo_surface_t_(cairo_image_surface_create(Xen_to_C_cairo_format_t(format), Xen_to_C_int(width), Xen_to_C_int(height)))); } static Xen gxg_cairo_image_surface_create_for_data(Xen data, Xen format, Xen width, Xen height, Xen stride) { #define H_cairo_image_surface_create_for_data "cairo_surface_t* cairo_image_surface_create_for_data(guchar* data, \ cairo_format_t format, int width, int height, int stride)" Xen_check_type(Xen_is_guchar_(data), data, 1, "cairo_image_surface_create_for_data", "guchar*"); Xen_check_type(Xen_is_cairo_format_t(format), format, 2, "cairo_image_surface_create_for_data", "cairo_format_t"); Xen_check_type(Xen_is_int(width), width, 3, "cairo_image_surface_create_for_data", "int"); Xen_check_type(Xen_is_int(height), height, 4, "cairo_image_surface_create_for_data", "int"); Xen_check_type(Xen_is_int(stride), stride, 5, "cairo_image_surface_create_for_data", "int"); return(C_to_Xen_cairo_surface_t_(cairo_image_surface_create_for_data(Xen_to_C_guchar_(data), Xen_to_C_cairo_format_t(format), Xen_to_C_int(width), Xen_to_C_int(height), Xen_to_C_int(stride)))); } static Xen gxg_cairo_image_surface_get_data(Xen surface) { #define H_cairo_image_surface_get_data "guchar* cairo_image_surface_get_data(cairo_surface_t* surface)" Xen_check_type(Xen_is_cairo_surface_t_(surface), surface, 1, "cairo_image_surface_get_data", "cairo_surface_t*"); return(C_to_Xen_guchar_(cairo_image_surface_get_data(Xen_to_C_cairo_surface_t_(surface)))); } static Xen gxg_cairo_image_surface_get_format(Xen surface) { #define H_cairo_image_surface_get_format "cairo_format_t cairo_image_surface_get_format(cairo_surface_t* surface)" Xen_check_type(Xen_is_cairo_surface_t_(surface), surface, 1, "cairo_image_surface_get_format", "cairo_surface_t*"); return(C_to_Xen_cairo_format_t(cairo_image_surface_get_format(Xen_to_C_cairo_surface_t_(surface)))); } static Xen gxg_cairo_image_surface_get_width(Xen surface) { #define H_cairo_image_surface_get_width "int cairo_image_surface_get_width(cairo_surface_t* surface)" Xen_check_type(Xen_is_cairo_surface_t_(surface), surface, 1, "cairo_image_surface_get_width", "cairo_surface_t*"); return(C_to_Xen_int(cairo_image_surface_get_width(Xen_to_C_cairo_surface_t_(surface)))); } static Xen gxg_cairo_image_surface_get_height(Xen surface) { #define H_cairo_image_surface_get_height "int cairo_image_surface_get_height(cairo_surface_t* surface)" Xen_check_type(Xen_is_cairo_surface_t_(surface), surface, 1, "cairo_image_surface_get_height", "cairo_surface_t*"); return(C_to_Xen_int(cairo_image_surface_get_height(Xen_to_C_cairo_surface_t_(surface)))); } static Xen gxg_cairo_image_surface_get_stride(Xen surface) { #define H_cairo_image_surface_get_stride "int cairo_image_surface_get_stride(cairo_surface_t* surface)" Xen_check_type(Xen_is_cairo_surface_t_(surface), surface, 1, "cairo_image_surface_get_stride", "cairo_surface_t*"); return(C_to_Xen_int(cairo_image_surface_get_stride(Xen_to_C_cairo_surface_t_(surface)))); } static Xen gxg_cairo_pattern_create_rgb(Xen red, Xen green, Xen blue) { #define H_cairo_pattern_create_rgb "cairo_pattern_t* cairo_pattern_create_rgb(double red, double green, \ double blue)" Xen_check_type(Xen_is_double(red), red, 1, "cairo_pattern_create_rgb", "double"); Xen_check_type(Xen_is_double(green), green, 2, "cairo_pattern_create_rgb", "double"); Xen_check_type(Xen_is_double(blue), blue, 3, "cairo_pattern_create_rgb", "double"); return(C_to_Xen_cairo_pattern_t_(cairo_pattern_create_rgb(Xen_to_C_double(red), Xen_to_C_double(green), Xen_to_C_double(blue)))); } static Xen gxg_cairo_pattern_create_rgba(Xen red, Xen green, Xen blue, Xen alpha) { #define H_cairo_pattern_create_rgba "cairo_pattern_t* cairo_pattern_create_rgba(double red, double green, \ double blue, double alpha)" Xen_check_type(Xen_is_double(red), red, 1, "cairo_pattern_create_rgba", "double"); Xen_check_type(Xen_is_double(green), green, 2, "cairo_pattern_create_rgba", "double"); Xen_check_type(Xen_is_double(blue), blue, 3, "cairo_pattern_create_rgba", "double"); Xen_check_type(Xen_is_double(alpha), alpha, 4, "cairo_pattern_create_rgba", "double"); return(C_to_Xen_cairo_pattern_t_(cairo_pattern_create_rgba(Xen_to_C_double(red), Xen_to_C_double(green), Xen_to_C_double(blue), Xen_to_C_double(alpha)))); } static Xen gxg_cairo_pattern_create_for_surface(Xen surface) { #define H_cairo_pattern_create_for_surface "cairo_pattern_t* cairo_pattern_create_for_surface(cairo_surface_t* surface)" Xen_check_type(Xen_is_cairo_surface_t_(surface), surface, 1, "cairo_pattern_create_for_surface", "cairo_surface_t*"); return(C_to_Xen_cairo_pattern_t_(cairo_pattern_create_for_surface(Xen_to_C_cairo_surface_t_(surface)))); } static Xen gxg_cairo_pattern_create_linear(Xen x0, Xen y0, Xen x1, Xen y1) { #define H_cairo_pattern_create_linear "cairo_pattern_t* cairo_pattern_create_linear(double x0, double y0, \ double x1, double y1)" Xen_check_type(Xen_is_double(x0), x0, 1, "cairo_pattern_create_linear", "double"); Xen_check_type(Xen_is_double(y0), y0, 2, "cairo_pattern_create_linear", "double"); Xen_check_type(Xen_is_double(x1), x1, 3, "cairo_pattern_create_linear", "double"); Xen_check_type(Xen_is_double(y1), y1, 4, "cairo_pattern_create_linear", "double"); return(C_to_Xen_cairo_pattern_t_(cairo_pattern_create_linear(Xen_to_C_double(x0), Xen_to_C_double(y0), Xen_to_C_double(x1), Xen_to_C_double(y1)))); } static Xen gxg_cairo_pattern_create_radial(Xen cx0, Xen cy0, Xen radius0, Xen cx1, Xen cy1, Xen radius1) { #define H_cairo_pattern_create_radial "cairo_pattern_t* cairo_pattern_create_radial(double cx0, double cy0, \ double radius0, double cx1, double cy1, double radius1)" Xen_check_type(Xen_is_double(cx0), cx0, 1, "cairo_pattern_create_radial", "double"); Xen_check_type(Xen_is_double(cy0), cy0, 2, "cairo_pattern_create_radial", "double"); Xen_check_type(Xen_is_double(radius0), radius0, 3, "cairo_pattern_create_radial", "double"); Xen_check_type(Xen_is_double(cx1), cx1, 4, "cairo_pattern_create_radial", "double"); Xen_check_type(Xen_is_double(cy1), cy1, 5, "cairo_pattern_create_radial", "double"); Xen_check_type(Xen_is_double(radius1), radius1, 6, "cairo_pattern_create_radial", "double"); return(C_to_Xen_cairo_pattern_t_(cairo_pattern_create_radial(Xen_to_C_double(cx0), Xen_to_C_double(cy0), Xen_to_C_double(radius0), Xen_to_C_double(cx1), Xen_to_C_double(cy1), Xen_to_C_double(radius1)))); } static Xen gxg_cairo_pattern_reference(Xen pattern) { #define H_cairo_pattern_reference "cairo_pattern_t* cairo_pattern_reference(cairo_pattern_t* pattern)" Xen_check_type(Xen_is_cairo_pattern_t_(pattern), pattern, 1, "cairo_pattern_reference", "cairo_pattern_t*"); return(C_to_Xen_cairo_pattern_t_(cairo_pattern_reference(Xen_to_C_cairo_pattern_t_(pattern)))); } static Xen gxg_cairo_pattern_destroy(Xen pattern) { #define H_cairo_pattern_destroy "void cairo_pattern_destroy(cairo_pattern_t* pattern)" Xen_check_type(Xen_is_cairo_pattern_t_(pattern), pattern, 1, "cairo_pattern_destroy", "cairo_pattern_t*"); cairo_pattern_destroy(Xen_to_C_cairo_pattern_t_(pattern)); return(Xen_false); } static Xen gxg_cairo_pattern_status(Xen pattern) { #define H_cairo_pattern_status "cairo_status_t cairo_pattern_status(cairo_pattern_t* pattern)" Xen_check_type(Xen_is_cairo_pattern_t_(pattern), pattern, 1, "cairo_pattern_status", "cairo_pattern_t*"); return(C_to_Xen_cairo_status_t(cairo_pattern_status(Xen_to_C_cairo_pattern_t_(pattern)))); } static Xen gxg_cairo_pattern_add_color_stop_rgb(Xen pattern, Xen offset, Xen red, Xen green, Xen blue) { #define H_cairo_pattern_add_color_stop_rgb "void cairo_pattern_add_color_stop_rgb(cairo_pattern_t* pattern, \ double offset, double red, double green, double blue)" Xen_check_type(Xen_is_cairo_pattern_t_(pattern), pattern, 1, "cairo_pattern_add_color_stop_rgb", "cairo_pattern_t*"); Xen_check_type(Xen_is_double(offset), offset, 2, "cairo_pattern_add_color_stop_rgb", "double"); Xen_check_type(Xen_is_double(red), red, 3, "cairo_pattern_add_color_stop_rgb", "double"); Xen_check_type(Xen_is_double(green), green, 4, "cairo_pattern_add_color_stop_rgb", "double"); Xen_check_type(Xen_is_double(blue), blue, 5, "cairo_pattern_add_color_stop_rgb", "double"); cairo_pattern_add_color_stop_rgb(Xen_to_C_cairo_pattern_t_(pattern), Xen_to_C_double(offset), Xen_to_C_double(red), Xen_to_C_double(green), Xen_to_C_double(blue)); return(Xen_false); } static Xen gxg_cairo_pattern_add_color_stop_rgba(Xen pattern, Xen offset, Xen red, Xen green, Xen blue, Xen alpha) { #define H_cairo_pattern_add_color_stop_rgba "void cairo_pattern_add_color_stop_rgba(cairo_pattern_t* pattern, \ double offset, double red, double green, double blue, double alpha)" Xen_check_type(Xen_is_cairo_pattern_t_(pattern), pattern, 1, "cairo_pattern_add_color_stop_rgba", "cairo_pattern_t*"); Xen_check_type(Xen_is_double(offset), offset, 2, "cairo_pattern_add_color_stop_rgba", "double"); Xen_check_type(Xen_is_double(red), red, 3, "cairo_pattern_add_color_stop_rgba", "double"); Xen_check_type(Xen_is_double(green), green, 4, "cairo_pattern_add_color_stop_rgba", "double"); Xen_check_type(Xen_is_double(blue), blue, 5, "cairo_pattern_add_color_stop_rgba", "double"); Xen_check_type(Xen_is_double(alpha), alpha, 6, "cairo_pattern_add_color_stop_rgba", "double"); cairo_pattern_add_color_stop_rgba(Xen_to_C_cairo_pattern_t_(pattern), Xen_to_C_double(offset), Xen_to_C_double(red), Xen_to_C_double(green), Xen_to_C_double(blue), Xen_to_C_double(alpha)); return(Xen_false); } static Xen gxg_cairo_pattern_set_matrix(Xen pattern, Xen matrix) { #define H_cairo_pattern_set_matrix "void cairo_pattern_set_matrix(cairo_pattern_t* pattern, cairo_matrix_t* matrix)" Xen_check_type(Xen_is_cairo_pattern_t_(pattern), pattern, 1, "cairo_pattern_set_matrix", "cairo_pattern_t*"); Xen_check_type(Xen_is_cairo_matrix_t_(matrix), matrix, 2, "cairo_pattern_set_matrix", "cairo_matrix_t*"); cairo_pattern_set_matrix(Xen_to_C_cairo_pattern_t_(pattern), Xen_to_C_cairo_matrix_t_(matrix)); return(Xen_false); } static Xen gxg_cairo_pattern_get_matrix(Xen pattern, Xen matrix) { #define H_cairo_pattern_get_matrix "void cairo_pattern_get_matrix(cairo_pattern_t* pattern, cairo_matrix_t* matrix)" Xen_check_type(Xen_is_cairo_pattern_t_(pattern), pattern, 1, "cairo_pattern_get_matrix", "cairo_pattern_t*"); Xen_check_type(Xen_is_cairo_matrix_t_(matrix), matrix, 2, "cairo_pattern_get_matrix", "cairo_matrix_t*"); cairo_pattern_get_matrix(Xen_to_C_cairo_pattern_t_(pattern), Xen_to_C_cairo_matrix_t_(matrix)); return(Xen_false); } static Xen gxg_cairo_pattern_set_extend(Xen pattern, Xen extend) { #define H_cairo_pattern_set_extend "void cairo_pattern_set_extend(cairo_pattern_t* pattern, cairo_extend_t extend)" Xen_check_type(Xen_is_cairo_pattern_t_(pattern), pattern, 1, "cairo_pattern_set_extend", "cairo_pattern_t*"); Xen_check_type(Xen_is_cairo_extend_t(extend), extend, 2, "cairo_pattern_set_extend", "cairo_extend_t"); cairo_pattern_set_extend(Xen_to_C_cairo_pattern_t_(pattern), Xen_to_C_cairo_extend_t(extend)); return(Xen_false); } static Xen gxg_cairo_pattern_get_extend(Xen pattern) { #define H_cairo_pattern_get_extend "cairo_extend_t cairo_pattern_get_extend(cairo_pattern_t* pattern)" Xen_check_type(Xen_is_cairo_pattern_t_(pattern), pattern, 1, "cairo_pattern_get_extend", "cairo_pattern_t*"); return(C_to_Xen_cairo_extend_t(cairo_pattern_get_extend(Xen_to_C_cairo_pattern_t_(pattern)))); } static Xen gxg_cairo_pattern_set_filter(Xen pattern, Xen filter) { #define H_cairo_pattern_set_filter "void cairo_pattern_set_filter(cairo_pattern_t* pattern, cairo_filter_t filter)" Xen_check_type(Xen_is_cairo_pattern_t_(pattern), pattern, 1, "cairo_pattern_set_filter", "cairo_pattern_t*"); Xen_check_type(Xen_is_cairo_filter_t(filter), filter, 2, "cairo_pattern_set_filter", "cairo_filter_t"); cairo_pattern_set_filter(Xen_to_C_cairo_pattern_t_(pattern), Xen_to_C_cairo_filter_t(filter)); return(Xen_false); } static Xen gxg_cairo_pattern_get_filter(Xen pattern) { #define H_cairo_pattern_get_filter "cairo_filter_t cairo_pattern_get_filter(cairo_pattern_t* pattern)" Xen_check_type(Xen_is_cairo_pattern_t_(pattern), pattern, 1, "cairo_pattern_get_filter", "cairo_pattern_t*"); return(C_to_Xen_cairo_filter_t(cairo_pattern_get_filter(Xen_to_C_cairo_pattern_t_(pattern)))); } static Xen gxg_cairo_matrix_init(Xen matrix, Xen xx, Xen yx, Xen xy, Xen yy, Xen x0, Xen y0) { #define H_cairo_matrix_init "void cairo_matrix_init(cairo_matrix_t* matrix, double xx, double yx, double xy, \ double yy, double x0, double y0)" Xen_check_type(Xen_is_cairo_matrix_t_(matrix), matrix, 1, "cairo_matrix_init", "cairo_matrix_t*"); Xen_check_type(Xen_is_double(xx), xx, 2, "cairo_matrix_init", "double"); Xen_check_type(Xen_is_double(yx), yx, 3, "cairo_matrix_init", "double"); Xen_check_type(Xen_is_double(xy), xy, 4, "cairo_matrix_init", "double"); Xen_check_type(Xen_is_double(yy), yy, 5, "cairo_matrix_init", "double"); Xen_check_type(Xen_is_double(x0), x0, 6, "cairo_matrix_init", "double"); Xen_check_type(Xen_is_double(y0), y0, 7, "cairo_matrix_init", "double"); cairo_matrix_init(Xen_to_C_cairo_matrix_t_(matrix), Xen_to_C_double(xx), Xen_to_C_double(yx), Xen_to_C_double(xy), Xen_to_C_double(yy), Xen_to_C_double(x0), Xen_to_C_double(y0)); return(Xen_false); } static Xen gxg_cairo_matrix_init_identity(Xen matrix) { #define H_cairo_matrix_init_identity "void cairo_matrix_init_identity(cairo_matrix_t* matrix)" Xen_check_type(Xen_is_cairo_matrix_t_(matrix), matrix, 1, "cairo_matrix_init_identity", "cairo_matrix_t*"); cairo_matrix_init_identity(Xen_to_C_cairo_matrix_t_(matrix)); return(Xen_false); } static Xen gxg_cairo_matrix_init_translate(Xen matrix, Xen tx, Xen ty) { #define H_cairo_matrix_init_translate "void cairo_matrix_init_translate(cairo_matrix_t* matrix, double tx, \ double ty)" Xen_check_type(Xen_is_cairo_matrix_t_(matrix), matrix, 1, "cairo_matrix_init_translate", "cairo_matrix_t*"); Xen_check_type(Xen_is_double(tx), tx, 2, "cairo_matrix_init_translate", "double"); Xen_check_type(Xen_is_double(ty), ty, 3, "cairo_matrix_init_translate", "double"); cairo_matrix_init_translate(Xen_to_C_cairo_matrix_t_(matrix), Xen_to_C_double(tx), Xen_to_C_double(ty)); return(Xen_false); } static Xen gxg_cairo_matrix_init_scale(Xen matrix, Xen sx, Xen sy) { #define H_cairo_matrix_init_scale "void cairo_matrix_init_scale(cairo_matrix_t* matrix, double sx, \ double sy)" Xen_check_type(Xen_is_cairo_matrix_t_(matrix), matrix, 1, "cairo_matrix_init_scale", "cairo_matrix_t*"); Xen_check_type(Xen_is_double(sx), sx, 2, "cairo_matrix_init_scale", "double"); Xen_check_type(Xen_is_double(sy), sy, 3, "cairo_matrix_init_scale", "double"); cairo_matrix_init_scale(Xen_to_C_cairo_matrix_t_(matrix), Xen_to_C_double(sx), Xen_to_C_double(sy)); return(Xen_false); } static Xen gxg_cairo_matrix_init_rotate(Xen matrix, Xen radians) { #define H_cairo_matrix_init_rotate "void cairo_matrix_init_rotate(cairo_matrix_t* matrix, double radians)" Xen_check_type(Xen_is_cairo_matrix_t_(matrix), matrix, 1, "cairo_matrix_init_rotate", "cairo_matrix_t*"); Xen_check_type(Xen_is_double(radians), radians, 2, "cairo_matrix_init_rotate", "double"); cairo_matrix_init_rotate(Xen_to_C_cairo_matrix_t_(matrix), Xen_to_C_double(radians)); return(Xen_false); } static Xen gxg_cairo_matrix_translate(Xen matrix, Xen tx, Xen ty) { #define H_cairo_matrix_translate "void cairo_matrix_translate(cairo_matrix_t* matrix, double tx, double ty)" Xen_check_type(Xen_is_cairo_matrix_t_(matrix), matrix, 1, "cairo_matrix_translate", "cairo_matrix_t*"); Xen_check_type(Xen_is_double(tx), tx, 2, "cairo_matrix_translate", "double"); Xen_check_type(Xen_is_double(ty), ty, 3, "cairo_matrix_translate", "double"); cairo_matrix_translate(Xen_to_C_cairo_matrix_t_(matrix), Xen_to_C_double(tx), Xen_to_C_double(ty)); return(Xen_false); } static Xen gxg_cairo_matrix_scale(Xen matrix, Xen sx, Xen sy) { #define H_cairo_matrix_scale "void cairo_matrix_scale(cairo_matrix_t* matrix, double sx, double sy)" Xen_check_type(Xen_is_cairo_matrix_t_(matrix), matrix, 1, "cairo_matrix_scale", "cairo_matrix_t*"); Xen_check_type(Xen_is_double(sx), sx, 2, "cairo_matrix_scale", "double"); Xen_check_type(Xen_is_double(sy), sy, 3, "cairo_matrix_scale", "double"); cairo_matrix_scale(Xen_to_C_cairo_matrix_t_(matrix), Xen_to_C_double(sx), Xen_to_C_double(sy)); return(Xen_false); } static Xen gxg_cairo_matrix_rotate(Xen matrix, Xen radians) { #define H_cairo_matrix_rotate "void cairo_matrix_rotate(cairo_matrix_t* matrix, double radians)" Xen_check_type(Xen_is_cairo_matrix_t_(matrix), matrix, 1, "cairo_matrix_rotate", "cairo_matrix_t*"); Xen_check_type(Xen_is_double(radians), radians, 2, "cairo_matrix_rotate", "double"); cairo_matrix_rotate(Xen_to_C_cairo_matrix_t_(matrix), Xen_to_C_double(radians)); return(Xen_false); } static Xen gxg_cairo_matrix_invert(Xen matrix) { #define H_cairo_matrix_invert "cairo_status_t cairo_matrix_invert(cairo_matrix_t* matrix)" Xen_check_type(Xen_is_cairo_matrix_t_(matrix), matrix, 1, "cairo_matrix_invert", "cairo_matrix_t*"); return(C_to_Xen_cairo_status_t(cairo_matrix_invert(Xen_to_C_cairo_matrix_t_(matrix)))); } static Xen gxg_cairo_matrix_multiply(Xen result, Xen a, Xen b) { #define H_cairo_matrix_multiply "void cairo_matrix_multiply(cairo_matrix_t* result, cairo_matrix_t* a, \ cairo_matrix_t* b)" Xen_check_type(Xen_is_cairo_matrix_t_(result), result, 1, "cairo_matrix_multiply", "cairo_matrix_t*"); Xen_check_type(Xen_is_cairo_matrix_t_(a), a, 2, "cairo_matrix_multiply", "cairo_matrix_t*"); Xen_check_type(Xen_is_cairo_matrix_t_(b), b, 3, "cairo_matrix_multiply", "cairo_matrix_t*"); cairo_matrix_multiply(Xen_to_C_cairo_matrix_t_(result), Xen_to_C_cairo_matrix_t_(a), Xen_to_C_cairo_matrix_t_(b)); return(Xen_false); } static Xen gxg_cairo_matrix_transform_distance(Xen matrix, Xen ignore_dx, Xen ignore_dy) { #define H_cairo_matrix_transform_distance "void cairo_matrix_transform_distance(cairo_matrix_t* matrix, \ gdouble* [dx], gdouble* [dy])" gdouble ref_dx; gdouble ref_dy; Xen_check_type(Xen_is_cairo_matrix_t_(matrix), matrix, 1, "cairo_matrix_transform_distance", "cairo_matrix_t*"); cairo_matrix_transform_distance(Xen_to_C_cairo_matrix_t_(matrix), &ref_dx, &ref_dy); return(Xen_list_2(C_to_Xen_gdouble(ref_dx), C_to_Xen_gdouble(ref_dy))); } static Xen gxg_cairo_matrix_transform_point(Xen matrix, Xen ignore_x, Xen ignore_y) { #define H_cairo_matrix_transform_point "void cairo_matrix_transform_point(cairo_matrix_t* matrix, gdouble* [x], \ gdouble* [y])" gdouble ref_x; gdouble ref_y; Xen_check_type(Xen_is_cairo_matrix_t_(matrix), matrix, 1, "cairo_matrix_transform_point", "cairo_matrix_t*"); cairo_matrix_transform_point(Xen_to_C_cairo_matrix_t_(matrix), &ref_x, &ref_y); return(Xen_list_2(C_to_Xen_gdouble(ref_x), C_to_Xen_gdouble(ref_y))); } static Xen gxg_cairo_get_reference_count(Xen cr) { #define H_cairo_get_reference_count "guint cairo_get_reference_count(cairo_t* cr)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_get_reference_count", "cairo_t*"); return(C_to_Xen_guint(cairo_get_reference_count(Xen_to_C_cairo_t_(cr)))); } static Xen gxg_cairo_get_user_data(Xen cr, Xen key) { #define H_cairo_get_user_data "void* cairo_get_user_data(cairo_t* cr, cairo_user_data_key_t* key)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_get_user_data", "cairo_t*"); Xen_check_type(Xen_is_cairo_user_data_key_t_(key), key, 2, "cairo_get_user_data", "cairo_user_data_key_t*"); return(C_to_Xen_void_(cairo_get_user_data(Xen_to_C_cairo_t_(cr), Xen_to_C_cairo_user_data_key_t_(key)))); } static Xen gxg_cairo_set_user_data(Xen cr, Xen key, Xen user_data, Xen destroy) { #define H_cairo_set_user_data "cairo_status_t cairo_set_user_data(cairo_t* cr, cairo_user_data_key_t* key, \ void* user_data, cairo_destroy_func_t destroy)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_set_user_data", "cairo_t*"); Xen_check_type(Xen_is_cairo_user_data_key_t_(key), key, 2, "cairo_set_user_data", "cairo_user_data_key_t*"); Xen_check_type(Xen_is_void_(user_data), user_data, 3, "cairo_set_user_data", "void*"); Xen_check_type(Xen_is_cairo_destroy_func_t(destroy), destroy, 4, "cairo_set_user_data", "cairo_destroy_func_t"); return(C_to_Xen_cairo_status_t(cairo_set_user_data(Xen_to_C_cairo_t_(cr), Xen_to_C_cairo_user_data_key_t_(key), Xen_to_C_void_(user_data), Xen_to_C_cairo_destroy_func_t(destroy)))); } static Xen gxg_cairo_clip_extents(Xen cr, Xen ignore_x1, Xen ignore_y1, Xen ignore_x2, Xen ignore_y2) { #define H_cairo_clip_extents "void cairo_clip_extents(cairo_t* cr, double* [x1], double* [y1], double* [x2], \ double* [y2])" double ref_x1; double ref_y1; double ref_x2; double ref_y2; Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_clip_extents", "cairo_t*"); cairo_clip_extents(Xen_to_C_cairo_t_(cr), &ref_x1, &ref_y1, &ref_x2, &ref_y2); return(Xen_list_4(C_to_Xen_double(ref_x1), C_to_Xen_double(ref_y1), C_to_Xen_double(ref_x2), C_to_Xen_double(ref_y2))); } static Xen gxg_cairo_copy_clip_rectangle_list(Xen cr) { #define H_cairo_copy_clip_rectangle_list "cairo_rectangle_list_t* cairo_copy_clip_rectangle_list(cairo_t* cr)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_copy_clip_rectangle_list", "cairo_t*"); return(C_to_Xen_cairo_rectangle_list_t_(cairo_copy_clip_rectangle_list(Xen_to_C_cairo_t_(cr)))); } static Xen gxg_cairo_rectangle_list_destroy(Xen rectangle_list) { #define H_cairo_rectangle_list_destroy "void cairo_rectangle_list_destroy(cairo_rectangle_list_t* rectangle_list)" Xen_check_type(Xen_is_cairo_rectangle_list_t_(rectangle_list), rectangle_list, 1, "cairo_rectangle_list_destroy", "cairo_rectangle_list_t*"); cairo_rectangle_list_destroy(Xen_to_C_cairo_rectangle_list_t_(rectangle_list)); return(Xen_false); } static Xen gxg_cairo_font_face_get_reference_count(Xen font_face) { #define H_cairo_font_face_get_reference_count "guint cairo_font_face_get_reference_count(cairo_font_face_t* font_face)" Xen_check_type(Xen_is_cairo_font_face_t_(font_face), font_face, 1, "cairo_font_face_get_reference_count", "cairo_font_face_t*"); return(C_to_Xen_guint(cairo_font_face_get_reference_count(Xen_to_C_cairo_font_face_t_(font_face)))); } static Xen gxg_cairo_scaled_font_get_reference_count(Xen scaled_font) { #define H_cairo_scaled_font_get_reference_count "guint cairo_scaled_font_get_reference_count(cairo_scaled_font_t* scaled_font)" Xen_check_type(Xen_is_cairo_scaled_font_t_(scaled_font), scaled_font, 1, "cairo_scaled_font_get_reference_count", "cairo_scaled_font_t*"); return(C_to_Xen_guint(cairo_scaled_font_get_reference_count(Xen_to_C_cairo_scaled_font_t_(scaled_font)))); } static Xen gxg_cairo_scaled_font_get_user_data(Xen scaled_font, Xen key) { #define H_cairo_scaled_font_get_user_data "void* cairo_scaled_font_get_user_data(cairo_scaled_font_t* scaled_font, \ cairo_user_data_key_t* key)" Xen_check_type(Xen_is_cairo_scaled_font_t_(scaled_font), scaled_font, 1, "cairo_scaled_font_get_user_data", "cairo_scaled_font_t*"); Xen_check_type(Xen_is_cairo_user_data_key_t_(key), key, 2, "cairo_scaled_font_get_user_data", "cairo_user_data_key_t*"); return(C_to_Xen_void_(cairo_scaled_font_get_user_data(Xen_to_C_cairo_scaled_font_t_(scaled_font), Xen_to_C_cairo_user_data_key_t_(key)))); } static Xen gxg_cairo_scaled_font_set_user_data(Xen scaled_font, Xen key, Xen user_data, Xen destroy) { #define H_cairo_scaled_font_set_user_data "cairo_status_t cairo_scaled_font_set_user_data(cairo_scaled_font_t* scaled_font, \ cairo_user_data_key_t* key, void* user_data, cairo_destroy_func_t destroy)" Xen_check_type(Xen_is_cairo_scaled_font_t_(scaled_font), scaled_font, 1, "cairo_scaled_font_set_user_data", "cairo_scaled_font_t*"); Xen_check_type(Xen_is_cairo_user_data_key_t_(key), key, 2, "cairo_scaled_font_set_user_data", "cairo_user_data_key_t*"); Xen_check_type(Xen_is_void_(user_data), user_data, 3, "cairo_scaled_font_set_user_data", "void*"); Xen_check_type(Xen_is_cairo_destroy_func_t(destroy), destroy, 4, "cairo_scaled_font_set_user_data", "cairo_destroy_func_t"); return(C_to_Xen_cairo_status_t(cairo_scaled_font_set_user_data(Xen_to_C_cairo_scaled_font_t_(scaled_font), Xen_to_C_cairo_user_data_key_t_(key), Xen_to_C_void_(user_data), Xen_to_C_cairo_destroy_func_t(destroy)))); } static Xen gxg_cairo_get_dash_count(Xen cr) { #define H_cairo_get_dash_count "int cairo_get_dash_count(cairo_t* cr)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_get_dash_count", "cairo_t*"); return(C_to_Xen_int(cairo_get_dash_count(Xen_to_C_cairo_t_(cr)))); } static Xen gxg_cairo_get_dash(Xen cr, Xen ignore_dashes, Xen ignore_offset) { #define H_cairo_get_dash "void cairo_get_dash(cairo_t* cr, double* [dashes], double* [offset])" double ref_dashes; double ref_offset; Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_get_dash", "cairo_t*"); cairo_get_dash(Xen_to_C_cairo_t_(cr), &ref_dashes, &ref_offset); return(Xen_list_2(C_to_Xen_double(ref_dashes), C_to_Xen_double(ref_offset))); } static Xen gxg_cairo_surface_get_reference_count(Xen surface) { #define H_cairo_surface_get_reference_count "guint cairo_surface_get_reference_count(cairo_surface_t* surface)" Xen_check_type(Xen_is_cairo_surface_t_(surface), surface, 1, "cairo_surface_get_reference_count", "cairo_surface_t*"); return(C_to_Xen_guint(cairo_surface_get_reference_count(Xen_to_C_cairo_surface_t_(surface)))); } static Xen gxg_cairo_pattern_get_reference_count(Xen pattern) { #define H_cairo_pattern_get_reference_count "guint cairo_pattern_get_reference_count(cairo_pattern_t* pattern)" Xen_check_type(Xen_is_cairo_pattern_t_(pattern), pattern, 1, "cairo_pattern_get_reference_count", "cairo_pattern_t*"); return(C_to_Xen_guint(cairo_pattern_get_reference_count(Xen_to_C_cairo_pattern_t_(pattern)))); } static Xen gxg_cairo_pattern_get_user_data(Xen pattern, Xen key) { #define H_cairo_pattern_get_user_data "void* cairo_pattern_get_user_data(cairo_pattern_t* pattern, \ cairo_user_data_key_t* key)" Xen_check_type(Xen_is_cairo_pattern_t_(pattern), pattern, 1, "cairo_pattern_get_user_data", "cairo_pattern_t*"); Xen_check_type(Xen_is_cairo_user_data_key_t_(key), key, 2, "cairo_pattern_get_user_data", "cairo_user_data_key_t*"); return(C_to_Xen_void_(cairo_pattern_get_user_data(Xen_to_C_cairo_pattern_t_(pattern), Xen_to_C_cairo_user_data_key_t_(key)))); } static Xen gxg_cairo_pattern_set_user_data(Xen pattern, Xen key, Xen user_data, Xen destroy) { #define H_cairo_pattern_set_user_data "cairo_status_t cairo_pattern_set_user_data(cairo_pattern_t* pattern, \ cairo_user_data_key_t* key, void* user_data, cairo_destroy_func_t destroy)" Xen_check_type(Xen_is_cairo_pattern_t_(pattern), pattern, 1, "cairo_pattern_set_user_data", "cairo_pattern_t*"); Xen_check_type(Xen_is_cairo_user_data_key_t_(key), key, 2, "cairo_pattern_set_user_data", "cairo_user_data_key_t*"); Xen_check_type(Xen_is_void_(user_data), user_data, 3, "cairo_pattern_set_user_data", "void*"); Xen_check_type(Xen_is_cairo_destroy_func_t(destroy), destroy, 4, "cairo_pattern_set_user_data", "cairo_destroy_func_t"); return(C_to_Xen_cairo_status_t(cairo_pattern_set_user_data(Xen_to_C_cairo_pattern_t_(pattern), Xen_to_C_cairo_user_data_key_t_(key), Xen_to_C_void_(user_data), Xen_to_C_cairo_destroy_func_t(destroy)))); } static Xen gxg_cairo_pattern_get_rgba(Xen pattern, Xen ignore_red, Xen ignore_green, Xen ignore_blue, Xen ignore_alpha) { #define H_cairo_pattern_get_rgba "cairo_status_t cairo_pattern_get_rgba(cairo_pattern_t* pattern, double* [red], \ double* [green], double* [blue], double* [alpha])" double ref_red; double ref_green; double ref_blue; double ref_alpha; Xen_check_type(Xen_is_cairo_pattern_t_(pattern), pattern, 1, "cairo_pattern_get_rgba", "cairo_pattern_t*"); { Xen result; result = C_to_Xen_cairo_status_t(cairo_pattern_get_rgba(Xen_to_C_cairo_pattern_t_(pattern), &ref_red, &ref_green, &ref_blue, &ref_alpha)); return(Xen_list_5(result, C_to_Xen_double(ref_red), C_to_Xen_double(ref_green), C_to_Xen_double(ref_blue), C_to_Xen_double(ref_alpha))); } } static Xen gxg_cairo_pattern_get_surface(Xen pattern, Xen ignore_surface) { #define H_cairo_pattern_get_surface "cairo_status_t cairo_pattern_get_surface(cairo_pattern_t* pattern, \ cairo_surface_t** [surface])" cairo_surface_t* ref_surface = NULL; Xen_check_type(Xen_is_cairo_pattern_t_(pattern), pattern, 1, "cairo_pattern_get_surface", "cairo_pattern_t*"); { Xen result; result = C_to_Xen_cairo_status_t(cairo_pattern_get_surface(Xen_to_C_cairo_pattern_t_(pattern), &ref_surface)); return(Xen_list_2(result, C_to_Xen_cairo_surface_t_(ref_surface))); } } static Xen gxg_cairo_pattern_get_color_stop_rgba(Xen pattern, Xen index, Xen ignore_offset, Xen ignore_red, Xen ignore_green, Xen ignore_blue, Xen ignore_alpha) { #define H_cairo_pattern_get_color_stop_rgba "cairo_status_t cairo_pattern_get_color_stop_rgba(cairo_pattern_t* pattern, \ int index, double* [offset], double* [red], double* [green], double* [blue], double* [alpha])" double ref_offset; double ref_red; double ref_green; double ref_blue; double ref_alpha; Xen_check_type(Xen_is_cairo_pattern_t_(pattern), pattern, 1, "cairo_pattern_get_color_stop_rgba", "cairo_pattern_t*"); Xen_check_type(Xen_is_int(index), index, 2, "cairo_pattern_get_color_stop_rgba", "int"); { Xen result; result = C_to_Xen_cairo_status_t(cairo_pattern_get_color_stop_rgba(Xen_to_C_cairo_pattern_t_(pattern), Xen_to_C_int(index), &ref_offset, &ref_red, &ref_green, &ref_blue, &ref_alpha)); return(Xen_list_6(result, C_to_Xen_double(ref_offset), C_to_Xen_double(ref_red), C_to_Xen_double(ref_green), C_to_Xen_double(ref_blue), C_to_Xen_double(ref_alpha))); } } static Xen gxg_cairo_pattern_get_color_stop_count(Xen pattern, Xen ignore_count) { #define H_cairo_pattern_get_color_stop_count "cairo_status_t cairo_pattern_get_color_stop_count(cairo_pattern_t* pattern, \ int* [count])" int ref_count; Xen_check_type(Xen_is_cairo_pattern_t_(pattern), pattern, 1, "cairo_pattern_get_color_stop_count", "cairo_pattern_t*"); { Xen result; result = C_to_Xen_cairo_status_t(cairo_pattern_get_color_stop_count(Xen_to_C_cairo_pattern_t_(pattern), &ref_count)); return(Xen_list_2(result, C_to_Xen_int(ref_count))); } } static Xen gxg_cairo_pattern_get_linear_points(Xen pattern, Xen ignore_x0, Xen ignore_y0, Xen ignore_x1, Xen ignore_y1) { #define H_cairo_pattern_get_linear_points "cairo_status_t cairo_pattern_get_linear_points(cairo_pattern_t* pattern, \ double* [x0], double* [y0], double* [x1], double* [y1])" double ref_x0; double ref_y0; double ref_x1; double ref_y1; Xen_check_type(Xen_is_cairo_pattern_t_(pattern), pattern, 1, "cairo_pattern_get_linear_points", "cairo_pattern_t*"); { Xen result; result = C_to_Xen_cairo_status_t(cairo_pattern_get_linear_points(Xen_to_C_cairo_pattern_t_(pattern), &ref_x0, &ref_y0, &ref_x1, &ref_y1)); return(Xen_list_5(result, C_to_Xen_double(ref_x0), C_to_Xen_double(ref_y0), C_to_Xen_double(ref_x1), C_to_Xen_double(ref_y1))); } } static Xen gxg_cairo_pattern_get_radial_circles(Xen pattern, Xen ignore_x0, Xen ignore_y0, Xen ignore_r0, Xen ignore_x1, Xen ignore_y1, Xen ignore_r1) { #define H_cairo_pattern_get_radial_circles "cairo_status_t cairo_pattern_get_radial_circles(cairo_pattern_t* pattern, \ double* [x0], double* [y0], double* [r0], double* [x1], double* [y1], double* [r1])" double ref_x0; double ref_y0; double ref_r0; double ref_x1; double ref_y1; double ref_r1; Xen_check_type(Xen_is_cairo_pattern_t_(pattern), pattern, 1, "cairo_pattern_get_radial_circles", "cairo_pattern_t*"); { Xen result; result = C_to_Xen_cairo_status_t(cairo_pattern_get_radial_circles(Xen_to_C_cairo_pattern_t_(pattern), &ref_x0, &ref_y0, &ref_r0, &ref_x1, &ref_y1, &ref_r1)); return(Xen_list_7(result, C_to_Xen_double(ref_x0), C_to_Xen_double(ref_y0), C_to_Xen_double(ref_r0), C_to_Xen_double(ref_x1), C_to_Xen_double(ref_y1), C_to_Xen_double(ref_r1))); } } static Xen gxg_cairo_get_scaled_font(Xen cr) { #define H_cairo_get_scaled_font "cairo_scaled_font_t* cairo_get_scaled_font(cairo_t* cr)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_get_scaled_font", "cairo_t*"); return(C_to_Xen_cairo_scaled_font_t_(cairo_get_scaled_font(Xen_to_C_cairo_t_(cr)))); } static Xen gxg_cairo_path_extents(Xen cr, Xen ignore_x1, Xen ignore_y1, Xen ignore_x2, Xen ignore_y2) { #define H_cairo_path_extents "void cairo_path_extents(cairo_t* cr, double* [x1], double* [y1], double* [x2], \ double* [y2])" double ref_x1; double ref_y1; double ref_x2; double ref_y2; Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_path_extents", "cairo_t*"); cairo_path_extents(Xen_to_C_cairo_t_(cr), &ref_x1, &ref_y1, &ref_x2, &ref_y2); return(Xen_list_4(C_to_Xen_double(ref_x1), C_to_Xen_double(ref_y1), C_to_Xen_double(ref_x2), C_to_Xen_double(ref_y2))); } static Xen gxg_cairo_has_current_point(Xen cr) { #define H_cairo_has_current_point "bool cairo_has_current_point(cairo_t* cr)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_has_current_point", "cairo_t*"); return(C_to_Xen_bool(cairo_has_current_point(Xen_to_C_cairo_t_(cr)))); } static Xen gxg_cairo_surface_copy_page(Xen surface) { #define H_cairo_surface_copy_page "void cairo_surface_copy_page(cairo_surface_t* surface)" Xen_check_type(Xen_is_cairo_surface_t_(surface), surface, 1, "cairo_surface_copy_page", "cairo_surface_t*"); cairo_surface_copy_page(Xen_to_C_cairo_surface_t_(surface)); return(Xen_false); } static Xen gxg_cairo_surface_show_page(Xen surface) { #define H_cairo_surface_show_page "void cairo_surface_show_page(cairo_surface_t* surface)" Xen_check_type(Xen_is_cairo_surface_t_(surface), surface, 1, "cairo_surface_show_page", "cairo_surface_t*"); cairo_surface_show_page(Xen_to_C_cairo_surface_t_(surface)); return(Xen_false); } static Xen gxg_cairo_format_stride_for_width(Xen format, Xen width) { #define H_cairo_format_stride_for_width "int cairo_format_stride_for_width(cairo_format_t format, int width)" Xen_check_type(Xen_is_cairo_format_t(format), format, 1, "cairo_format_stride_for_width", "cairo_format_t"); Xen_check_type(Xen_is_int(width), width, 2, "cairo_format_stride_for_width", "int"); return(C_to_Xen_int(cairo_format_stride_for_width(Xen_to_C_cairo_format_t(format), Xen_to_C_int(width)))); } static Xen gxg_cairo_image_surface_create_from_png(Xen filename) { #define H_cairo_image_surface_create_from_png "cairo_surface_t* cairo_image_surface_create_from_png(char* filename)" Xen_check_type(Xen_is_char_(filename), filename, 1, "cairo_image_surface_create_from_png", "char*"); return(C_to_Xen_cairo_surface_t_(cairo_image_surface_create_from_png((const char*)Xen_to_C_char_(filename)))); } static Xen gxg_cairo_surface_write_to_png(Xen surface, Xen filename) { #define H_cairo_surface_write_to_png "cairo_status_t cairo_surface_write_to_png(cairo_surface_t* surface, \ char* filename)" Xen_check_type(Xen_is_cairo_surface_t_(surface), surface, 1, "cairo_surface_write_to_png", "cairo_surface_t*"); Xen_check_type(Xen_is_char_(filename), filename, 2, "cairo_surface_write_to_png", "char*"); return(C_to_Xen_cairo_status_t(cairo_surface_write_to_png(Xen_to_C_cairo_surface_t_(surface), (const char*)Xen_to_C_char_(filename)))); } #if HAVE_CAIRO_1_8 static Xen gxg_cairo_glyph_allocate(Xen num_glyphs) { #define H_cairo_glyph_allocate "cairo_glyph_t* cairo_glyph_allocate(int num_glyphs)" Xen_check_type(Xen_is_int(num_glyphs), num_glyphs, 1, "cairo_glyph_allocate", "int"); return(C_to_Xen_cairo_glyph_t_(cairo_glyph_allocate(Xen_to_C_int(num_glyphs)))); } static Xen gxg_cairo_glyph_free(Xen glyphs) { #define H_cairo_glyph_free "void cairo_glyph_free(cairo_glyph_t* glyphs)" Xen_check_type(Xen_is_cairo_glyph_t_(glyphs), glyphs, 1, "cairo_glyph_free", "cairo_glyph_t*"); cairo_glyph_free(Xen_to_C_cairo_glyph_t_(glyphs)); return(Xen_false); } static Xen gxg_cairo_text_cluster_allocate(Xen num_clusters) { #define H_cairo_text_cluster_allocate "cairo_text_cluster_t* cairo_text_cluster_allocate(int num_clusters)" Xen_check_type(Xen_is_int(num_clusters), num_clusters, 1, "cairo_text_cluster_allocate", "int"); return(C_to_Xen_cairo_text_cluster_t_(cairo_text_cluster_allocate(Xen_to_C_int(num_clusters)))); } static Xen gxg_cairo_text_cluster_free(Xen clusters) { #define H_cairo_text_cluster_free "void cairo_text_cluster_free(cairo_text_cluster_t* clusters)" Xen_check_type(Xen_is_cairo_text_cluster_t_(clusters), clusters, 1, "cairo_text_cluster_free", "cairo_text_cluster_t*"); cairo_text_cluster_free(Xen_to_C_cairo_text_cluster_t_(clusters)); return(Xen_false); } static Xen gxg_cairo_show_text_glyphs(Xen arglist) { #define H_cairo_show_text_glyphs "void cairo_show_text_glyphs(cairo_t* cr, char* utf8, int utf8_len, \ cairo_glyph_t* glyphs, int num_glyphs, cairo_text_cluster_t* clusters, int num_clusters, cairo_text_cluster_flags_t cluster_flags)" Xen cr, utf8, utf8_len, glyphs, num_glyphs, clusters, num_clusters, cluster_flags; cr = Xen_list_ref(arglist, 0); utf8 = Xen_list_ref(arglist, 1); utf8_len = Xen_list_ref(arglist, 2); glyphs = Xen_list_ref(arglist, 3); num_glyphs = Xen_list_ref(arglist, 4); clusters = Xen_list_ref(arglist, 5); num_clusters = Xen_list_ref(arglist, 6); cluster_flags = Xen_list_ref(arglist, 7); Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_show_text_glyphs", "cairo_t*"); Xen_check_type(Xen_is_char_(utf8), utf8, 2, "cairo_show_text_glyphs", "char*"); Xen_check_type(Xen_is_int(utf8_len), utf8_len, 3, "cairo_show_text_glyphs", "int"); Xen_check_type(Xen_is_cairo_glyph_t_(glyphs), glyphs, 4, "cairo_show_text_glyphs", "cairo_glyph_t*"); Xen_check_type(Xen_is_int(num_glyphs), num_glyphs, 5, "cairo_show_text_glyphs", "int"); Xen_check_type(Xen_is_cairo_text_cluster_t_(clusters), clusters, 6, "cairo_show_text_glyphs", "cairo_text_cluster_t*"); Xen_check_type(Xen_is_int(num_clusters), num_clusters, 7, "cairo_show_text_glyphs", "int"); Xen_check_type(Xen_is_cairo_text_cluster_flags_t(cluster_flags), cluster_flags, 8, "cairo_show_text_glyphs", "cairo_text_cluster_flags_t"); cairo_show_text_glyphs(Xen_to_C_cairo_t_(cr), (const char*)Xen_to_C_char_(utf8), Xen_to_C_int(utf8_len), Xen_to_C_cairo_glyph_t_(glyphs), Xen_to_C_int(num_glyphs), Xen_to_C_cairo_text_cluster_t_(clusters), Xen_to_C_int(num_clusters), Xen_to_C_cairo_text_cluster_flags_t(cluster_flags)); return(Xen_false); } static Xen gxg_cairo_scaled_font_text_to_glyphs(Xen arglist) { #define H_cairo_scaled_font_text_to_glyphs "cairo_status_t cairo_scaled_font_text_to_glyphs(cairo_scaled_font_t* scaled_font, \ double x, double y, char* utf8, int utf8_len, cairo_glyph_t** glyphs, int* num_glyphs, cairo_text_cluster_t** clusters, \ int* num_clusters, cairo_text_cluster_flags_t* cluster_flags)" Xen scaled_font, x, y, utf8, utf8_len, glyphs, num_glyphs, clusters, num_clusters, cluster_flags; scaled_font = Xen_list_ref(arglist, 0); x = Xen_list_ref(arglist, 1); y = Xen_list_ref(arglist, 2); utf8 = Xen_list_ref(arglist, 3); utf8_len = Xen_list_ref(arglist, 4); glyphs = Xen_list_ref(arglist, 5); num_glyphs = Xen_list_ref(arglist, 6); clusters = Xen_list_ref(arglist, 7); num_clusters = Xen_list_ref(arglist, 8); cluster_flags = Xen_list_ref(arglist, 9); Xen_check_type(Xen_is_cairo_scaled_font_t_(scaled_font), scaled_font, 1, "cairo_scaled_font_text_to_glyphs", "cairo_scaled_font_t*"); Xen_check_type(Xen_is_double(x), x, 2, "cairo_scaled_font_text_to_glyphs", "double"); Xen_check_type(Xen_is_double(y), y, 3, "cairo_scaled_font_text_to_glyphs", "double"); Xen_check_type(Xen_is_char_(utf8), utf8, 4, "cairo_scaled_font_text_to_glyphs", "char*"); Xen_check_type(Xen_is_int(utf8_len), utf8_len, 5, "cairo_scaled_font_text_to_glyphs", "int"); Xen_check_type(Xen_is_cairo_glyph_t__(glyphs), glyphs, 6, "cairo_scaled_font_text_to_glyphs", "cairo_glyph_t**"); Xen_check_type(Xen_is_int_(num_glyphs), num_glyphs, 7, "cairo_scaled_font_text_to_glyphs", "int*"); Xen_check_type(Xen_is_cairo_text_cluster_t__(clusters), clusters, 8, "cairo_scaled_font_text_to_glyphs", "cairo_text_cluster_t**"); Xen_check_type(Xen_is_int_(num_clusters), num_clusters, 9, "cairo_scaled_font_text_to_glyphs", "int*"); Xen_check_type(Xen_is_cairo_text_cluster_flags_t_(cluster_flags), cluster_flags, 10, "cairo_scaled_font_text_to_glyphs", "cairo_text_cluster_flags_t*"); return(C_to_Xen_cairo_status_t(cairo_scaled_font_text_to_glyphs(Xen_to_C_cairo_scaled_font_t_(scaled_font), Xen_to_C_double(x), Xen_to_C_double(y), (const char*)Xen_to_C_char_(utf8), Xen_to_C_int(utf8_len), Xen_to_C_cairo_glyph_t__(glyphs), Xen_to_C_int_(num_glyphs), Xen_to_C_cairo_text_cluster_t__(clusters), Xen_to_C_int_(num_clusters), Xen_to_C_cairo_text_cluster_flags_t_(cluster_flags)))); } static Xen gxg_cairo_scaled_font_get_scale_matrix(Xen scaled_font, Xen scale_matrix) { #define H_cairo_scaled_font_get_scale_matrix "void cairo_scaled_font_get_scale_matrix(cairo_scaled_font_t* scaled_font, \ cairo_matrix_t* scale_matrix)" Xen_check_type(Xen_is_cairo_scaled_font_t_(scaled_font), scaled_font, 1, "cairo_scaled_font_get_scale_matrix", "cairo_scaled_font_t*"); Xen_check_type(Xen_is_cairo_matrix_t_(scale_matrix), scale_matrix, 2, "cairo_scaled_font_get_scale_matrix", "cairo_matrix_t*"); cairo_scaled_font_get_scale_matrix(Xen_to_C_cairo_scaled_font_t_(scaled_font), Xen_to_C_cairo_matrix_t_(scale_matrix)); return(Xen_false); } static Xen gxg_cairo_toy_font_face_create(Xen family, Xen slant, Xen weight) { #define H_cairo_toy_font_face_create "cairo_font_face_t* cairo_toy_font_face_create(char* family, cairo_font_slant_t slant, \ cairo_font_weight_t weight)" Xen_check_type(Xen_is_char_(family), family, 1, "cairo_toy_font_face_create", "char*"); Xen_check_type(Xen_is_cairo_font_slant_t(slant), slant, 2, "cairo_toy_font_face_create", "cairo_font_slant_t"); Xen_check_type(Xen_is_cairo_font_weight_t(weight), weight, 3, "cairo_toy_font_face_create", "cairo_font_weight_t"); return(C_to_Xen_cairo_font_face_t_(cairo_toy_font_face_create((const char*)Xen_to_C_char_(family), Xen_to_C_cairo_font_slant_t(slant), Xen_to_C_cairo_font_weight_t(weight)))); } static Xen gxg_cairo_toy_font_face_get_family(Xen font_face) { #define H_cairo_toy_font_face_get_family "char* cairo_toy_font_face_get_family(cairo_font_face_t* font_face)" Xen_check_type(Xen_is_cairo_font_face_t_(font_face), font_face, 1, "cairo_toy_font_face_get_family", "cairo_font_face_t*"); return(C_to_Xen_char_(cairo_toy_font_face_get_family(Xen_to_C_cairo_font_face_t_(font_face)))); } static Xen gxg_cairo_toy_font_face_get_slant(Xen font_face) { #define H_cairo_toy_font_face_get_slant "cairo_font_slant_t cairo_toy_font_face_get_slant(cairo_font_face_t* font_face)" Xen_check_type(Xen_is_cairo_font_face_t_(font_face), font_face, 1, "cairo_toy_font_face_get_slant", "cairo_font_face_t*"); return(C_to_Xen_cairo_font_slant_t(cairo_toy_font_face_get_slant(Xen_to_C_cairo_font_face_t_(font_face)))); } static Xen gxg_cairo_toy_font_face_get_weight(Xen font_face) { #define H_cairo_toy_font_face_get_weight "cairo_font_weight_t cairo_toy_font_face_get_weight(cairo_font_face_t* font_face)" Xen_check_type(Xen_is_cairo_font_face_t_(font_face), font_face, 1, "cairo_toy_font_face_get_weight", "cairo_font_face_t*"); return(C_to_Xen_cairo_font_weight_t(cairo_toy_font_face_get_weight(Xen_to_C_cairo_font_face_t_(font_face)))); } static Xen gxg_cairo_user_font_face_create(void) { #define H_cairo_user_font_face_create "cairo_font_face_t* cairo_user_font_face_create( void)" return(C_to_Xen_cairo_font_face_t_(cairo_user_font_face_create())); } static Xen gxg_cairo_surface_get_fallback_resolution(Xen surface, Xen ignore_x_pixels_per_inch, Xen ignore_y_pixels_per_inch) { #define H_cairo_surface_get_fallback_resolution "void cairo_surface_get_fallback_resolution(cairo_surface_t* surface, \ double* [x_pixels_per_inch], double* [y_pixels_per_inch])" double ref_x_pixels_per_inch; double ref_y_pixels_per_inch; Xen_check_type(Xen_is_cairo_surface_t_(surface), surface, 1, "cairo_surface_get_fallback_resolution", "cairo_surface_t*"); cairo_surface_get_fallback_resolution(Xen_to_C_cairo_surface_t_(surface), &ref_x_pixels_per_inch, &ref_y_pixels_per_inch); return(Xen_list_2(C_to_Xen_double(ref_x_pixels_per_inch), C_to_Xen_double(ref_y_pixels_per_inch))); } static Xen gxg_cairo_surface_has_show_text_glyphs(Xen surface) { #define H_cairo_surface_has_show_text_glyphs "cairo_bool_t cairo_surface_has_show_text_glyphs(cairo_surface_t* surface)" Xen_check_type(Xen_is_cairo_surface_t_(surface), surface, 1, "cairo_surface_has_show_text_glyphs", "cairo_surface_t*"); return(C_to_Xen_cairo_bool_t(cairo_surface_has_show_text_glyphs(Xen_to_C_cairo_surface_t_(surface)))); } #endif #if HAVE_CAIRO_1_9_12 && GTK_CHECK_VERSION(3, 0, 0) static Xen gxg_cairo_in_clip(Xen cr, Xen x, Xen y) { #define H_cairo_in_clip "cairo_bool_t cairo_in_clip(cairo_t* cr, double x, double y)" Xen_check_type(Xen_is_cairo_t_(cr), cr, 1, "cairo_in_clip", "cairo_t*"); Xen_check_type(Xen_is_double(x), x, 2, "cairo_in_clip", "double"); Xen_check_type(Xen_is_double(y), y, 3, "cairo_in_clip", "double"); return(C_to_Xen_cairo_bool_t(cairo_in_clip(Xen_to_C_cairo_t_(cr), Xen_to_C_double(x), Xen_to_C_double(y)))); } static Xen gxg_cairo_device_reference(Xen device) { #define H_cairo_device_reference "cairo_device_t* cairo_device_reference(cairo_device_t* device)" Xen_check_type(Xen_is_cairo_device_t_(device), device, 1, "cairo_device_reference", "cairo_device_t*"); return(C_to_Xen_cairo_device_t_(cairo_device_reference(Xen_to_C_cairo_device_t_(device)))); } static Xen gxg_cairo_device_status(Xen device) { #define H_cairo_device_status "cairo_status_t cairo_device_status(cairo_device_t* device)" Xen_check_type(Xen_is_cairo_device_t_(device), device, 1, "cairo_device_status", "cairo_device_t*"); return(C_to_Xen_cairo_status_t(cairo_device_status(Xen_to_C_cairo_device_t_(device)))); } static Xen gxg_cairo_device_acquire(Xen device) { #define H_cairo_device_acquire "cairo_status_t cairo_device_acquire(cairo_device_t* device)" Xen_check_type(Xen_is_cairo_device_t_(device), device, 1, "cairo_device_acquire", "cairo_device_t*"); return(C_to_Xen_cairo_status_t(cairo_device_acquire(Xen_to_C_cairo_device_t_(device)))); } static Xen gxg_cairo_device_release(Xen device) { #define H_cairo_device_release "void cairo_device_release(cairo_device_t* device)" Xen_check_type(Xen_is_cairo_device_t_(device), device, 1, "cairo_device_release", "cairo_device_t*"); cairo_device_release(Xen_to_C_cairo_device_t_(device)); return(Xen_false); } static Xen gxg_cairo_device_flush(Xen device) { #define H_cairo_device_flush "void cairo_device_flush(cairo_device_t* device)" Xen_check_type(Xen_is_cairo_device_t_(device), device, 1, "cairo_device_flush", "cairo_device_t*"); cairo_device_flush(Xen_to_C_cairo_device_t_(device)); return(Xen_false); } static Xen gxg_cairo_device_finish(Xen device) { #define H_cairo_device_finish "void cairo_device_finish(cairo_device_t* device)" Xen_check_type(Xen_is_cairo_device_t_(device), device, 1, "cairo_device_finish", "cairo_device_t*"); cairo_device_finish(Xen_to_C_cairo_device_t_(device)); return(Xen_false); } static Xen gxg_cairo_device_destroy(Xen device) { #define H_cairo_device_destroy "void cairo_device_destroy(cairo_device_t* device)" Xen_check_type(Xen_is_cairo_device_t_(device), device, 1, "cairo_device_destroy", "cairo_device_t*"); cairo_device_destroy(Xen_to_C_cairo_device_t_(device)); return(Xen_false); } static Xen gxg_cairo_device_get_reference_count(Xen device) { #define H_cairo_device_get_reference_count "guint cairo_device_get_reference_count(cairo_device_t* device)" Xen_check_type(Xen_is_cairo_device_t_(device), device, 1, "cairo_device_get_reference_count", "cairo_device_t*"); return(C_to_Xen_guint(cairo_device_get_reference_count(Xen_to_C_cairo_device_t_(device)))); } static Xen gxg_cairo_device_get_user_data(Xen device, Xen key) { #define H_cairo_device_get_user_data "void* cairo_device_get_user_data(cairo_device_t* device, cairo_user_data_key_t* key)" Xen_check_type(Xen_is_cairo_device_t_(device), device, 1, "cairo_device_get_user_data", "cairo_device_t*"); Xen_check_type(Xen_is_cairo_user_data_key_t_(key), key, 2, "cairo_device_get_user_data", "cairo_user_data_key_t*"); return(C_to_Xen_void_(cairo_device_get_user_data(Xen_to_C_cairo_device_t_(device), Xen_to_C_cairo_user_data_key_t_(key)))); } static Xen gxg_cairo_device_set_user_data(Xen device, Xen key, Xen user_data, Xen destroy) { #define H_cairo_device_set_user_data "cairo_status_t cairo_device_set_user_data(cairo_device_t* device, \ cairo_user_data_key_t* key, void* user_data, cairo_destroy_func_t destroy)" Xen_check_type(Xen_is_cairo_device_t_(device), device, 1, "cairo_device_set_user_data", "cairo_device_t*"); Xen_check_type(Xen_is_cairo_user_data_key_t_(key), key, 2, "cairo_device_set_user_data", "cairo_user_data_key_t*"); Xen_check_type(Xen_is_void_(user_data), user_data, 3, "cairo_device_set_user_data", "void*"); Xen_check_type(Xen_is_cairo_destroy_func_t(destroy), destroy, 4, "cairo_device_set_user_data", "cairo_destroy_func_t"); return(C_to_Xen_cairo_status_t(cairo_device_set_user_data(Xen_to_C_cairo_device_t_(device), Xen_to_C_cairo_user_data_key_t_(key), Xen_to_C_void_(user_data), Xen_to_C_cairo_destroy_func_t(destroy)))); } static Xen gxg_cairo_surface_create_for_rectangle(Xen target, Xen x, Xen y, Xen width, Xen height) { #define H_cairo_surface_create_for_rectangle "cairo_surface_t* cairo_surface_create_for_rectangle(cairo_surface_t* target, \ double x, double y, double width, double height)" Xen_check_type(Xen_is_cairo_surface_t_(target), target, 1, "cairo_surface_create_for_rectangle", "cairo_surface_t*"); Xen_check_type(Xen_is_double(x), x, 2, "cairo_surface_create_for_rectangle", "double"); Xen_check_type(Xen_is_double(y), y, 3, "cairo_surface_create_for_rectangle", "double"); Xen_check_type(Xen_is_double(width), width, 4, "cairo_surface_create_for_rectangle", "double"); Xen_check_type(Xen_is_double(height), height, 5, "cairo_surface_create_for_rectangle", "double"); return(C_to_Xen_cairo_surface_t_(cairo_surface_create_for_rectangle(Xen_to_C_cairo_surface_t_(target), Xen_to_C_double(x), Xen_to_C_double(y), Xen_to_C_double(width), Xen_to_C_double(height)))); } static Xen gxg_cairo_surface_get_device(Xen surface) { #define H_cairo_surface_get_device "cairo_device_t* cairo_surface_get_device(cairo_surface_t* surface)" Xen_check_type(Xen_is_cairo_surface_t_(surface), surface, 1, "cairo_surface_get_device", "cairo_surface_t*"); return(C_to_Xen_cairo_device_t_(cairo_surface_get_device(Xen_to_C_cairo_surface_t_(surface)))); } static Xen gxg_cairo_surface_set_mime_data(Xen surface, Xen mime_type, Xen data, Xen length, Xen destroy, Xen closure) { #define H_cairo_surface_set_mime_data "cairo_status_t cairo_surface_set_mime_data(cairo_surface_t* surface, \ char* mime_type, guchar* data, gulong length, cairo_destroy_func_t destroy, void* closure)" Xen_check_type(Xen_is_cairo_surface_t_(surface), surface, 1, "cairo_surface_set_mime_data", "cairo_surface_t*"); Xen_check_type(Xen_is_char_(mime_type), mime_type, 2, "cairo_surface_set_mime_data", "char*"); Xen_check_type(Xen_is_guchar_(data), data, 3, "cairo_surface_set_mime_data", "guchar*"); Xen_check_type(Xen_is_gulong(length), length, 4, "cairo_surface_set_mime_data", "gulong"); Xen_check_type(Xen_is_cairo_destroy_func_t(destroy), destroy, 5, "cairo_surface_set_mime_data", "cairo_destroy_func_t"); Xen_check_type(Xen_is_void_(closure), closure, 6, "cairo_surface_set_mime_data", "void*"); return(C_to_Xen_cairo_status_t(cairo_surface_set_mime_data(Xen_to_C_cairo_surface_t_(surface), (const char*)Xen_to_C_char_(mime_type), Xen_to_C_guchar_(data), Xen_to_C_gulong(length), Xen_to_C_cairo_destroy_func_t(destroy), Xen_to_C_void_(closure)))); } static Xen gxg_cairo_recording_surface_create(Xen content, Xen extents) { #define H_cairo_recording_surface_create "cairo_surface_t* cairo_recording_surface_create(cairo_content_t content, \ cairo_rectangle_t* extents)" Xen_check_type(Xen_is_cairo_content_t(content), content, 1, "cairo_recording_surface_create", "cairo_content_t"); Xen_check_type(Xen_is_cairo_rectangle_t_(extents), extents, 2, "cairo_recording_surface_create", "cairo_rectangle_t*"); return(C_to_Xen_cairo_surface_t_(cairo_recording_surface_create(Xen_to_C_cairo_content_t(content), Xen_to_C_cairo_rectangle_t_(extents)))); } static Xen gxg_cairo_recording_surface_ink_extents(Xen surface, Xen x0, Xen y0, Xen width, Xen height) { #define H_cairo_recording_surface_ink_extents "void cairo_recording_surface_ink_extents(cairo_surface_t* surface, \ double* x0, double* y0, double* width, double* height)" Xen_check_type(Xen_is_cairo_surface_t_(surface), surface, 1, "cairo_recording_surface_ink_extents", "cairo_surface_t*"); Xen_check_type(Xen_is_double_(x0), x0, 2, "cairo_recording_surface_ink_extents", "double*"); Xen_check_type(Xen_is_double_(y0), y0, 3, "cairo_recording_surface_ink_extents", "double*"); Xen_check_type(Xen_is_double_(width), width, 4, "cairo_recording_surface_ink_extents", "double*"); Xen_check_type(Xen_is_double_(height), height, 5, "cairo_recording_surface_ink_extents", "double*"); cairo_recording_surface_ink_extents(Xen_to_C_cairo_surface_t_(surface), Xen_to_C_double_(x0), Xen_to_C_double_(y0), Xen_to_C_double_(width), Xen_to_C_double_(height)); return(Xen_false); } static Xen gxg_cairo_region_create(void) { #define H_cairo_region_create "cairo_region_t* cairo_region_create( void)" return(C_to_Xen_cairo_region_t_(cairo_region_create())); } static Xen gxg_cairo_region_create_rectangle(Xen rectangle) { #define H_cairo_region_create_rectangle "cairo_region_t* cairo_region_create_rectangle(cairo_rectangle_int_t* rectangle)" Xen_check_type(Xen_is_cairo_rectangle_int_t_(rectangle), rectangle, 1, "cairo_region_create_rectangle", "cairo_rectangle_int_t*"); return(C_to_Xen_cairo_region_t_(cairo_region_create_rectangle(Xen_to_C_cairo_rectangle_int_t_(rectangle)))); } static Xen gxg_cairo_region_create_rectangles(Xen rects, Xen count) { #define H_cairo_region_create_rectangles "cairo_region_t* cairo_region_create_rectangles(cairo_rectangle_int_t* rects, \ int count)" Xen_check_type(Xen_is_cairo_rectangle_int_t_(rects), rects, 1, "cairo_region_create_rectangles", "cairo_rectangle_int_t*"); Xen_check_type(Xen_is_int(count), count, 2, "cairo_region_create_rectangles", "int"); return(C_to_Xen_cairo_region_t_(cairo_region_create_rectangles(Xen_to_C_cairo_rectangle_int_t_(rects), Xen_to_C_int(count)))); } static Xen gxg_cairo_region_copy(Xen original) { #define H_cairo_region_copy "cairo_region_t* cairo_region_copy(cairo_region_t* original)" Xen_check_type(Xen_is_cairo_region_t_(original), original, 1, "cairo_region_copy", "cairo_region_t*"); return(C_to_Xen_cairo_region_t_(cairo_region_copy(Xen_to_C_cairo_region_t_(original)))); } static Xen gxg_cairo_region_reference(Xen region) { #define H_cairo_region_reference "cairo_region_t* cairo_region_reference(cairo_region_t* region)" Xen_check_type(Xen_is_cairo_region_t_(region), region, 1, "cairo_region_reference", "cairo_region_t*"); return(C_to_Xen_cairo_region_t_(cairo_region_reference(Xen_to_C_cairo_region_t_(region)))); } static Xen gxg_cairo_region_destroy(Xen region) { #define H_cairo_region_destroy "void cairo_region_destroy(cairo_region_t* region)" Xen_check_type(Xen_is_cairo_region_t_(region), region, 1, "cairo_region_destroy", "cairo_region_t*"); cairo_region_destroy(Xen_to_C_cairo_region_t_(region)); return(Xen_false); } static Xen gxg_cairo_region_equal(Xen a, Xen b) { #define H_cairo_region_equal "cairo_bool_t cairo_region_equal(cairo_region_t* a, cairo_region_t* b)" Xen_check_type(Xen_is_cairo_region_t_(a), a, 1, "cairo_region_equal", "cairo_region_t*"); Xen_check_type(Xen_is_cairo_region_t_(b), b, 2, "cairo_region_equal", "cairo_region_t*"); return(C_to_Xen_cairo_bool_t(cairo_region_equal(Xen_to_C_cairo_region_t_(a), Xen_to_C_cairo_region_t_(b)))); } static Xen gxg_cairo_region_status(Xen region) { #define H_cairo_region_status "cairo_status_t cairo_region_status(cairo_region_t* region)" Xen_check_type(Xen_is_cairo_region_t_(region), region, 1, "cairo_region_status", "cairo_region_t*"); return(C_to_Xen_cairo_status_t(cairo_region_status(Xen_to_C_cairo_region_t_(region)))); } static Xen gxg_cairo_region_get_extents(Xen region, Xen extents) { #define H_cairo_region_get_extents "void cairo_region_get_extents(cairo_region_t* region, cairo_rectangle_int_t* extents)" Xen_check_type(Xen_is_cairo_region_t_(region), region, 1, "cairo_region_get_extents", "cairo_region_t*"); Xen_check_type(Xen_is_cairo_rectangle_int_t_(extents), extents, 2, "cairo_region_get_extents", "cairo_rectangle_int_t*"); cairo_region_get_extents(Xen_to_C_cairo_region_t_(region), Xen_to_C_cairo_rectangle_int_t_(extents)); return(Xen_false); } static Xen gxg_cairo_region_num_rectangles(Xen region) { #define H_cairo_region_num_rectangles "int cairo_region_num_rectangles(cairo_region_t* region)" Xen_check_type(Xen_is_cairo_region_t_(region), region, 1, "cairo_region_num_rectangles", "cairo_region_t*"); return(C_to_Xen_int(cairo_region_num_rectangles(Xen_to_C_cairo_region_t_(region)))); } static Xen gxg_cairo_region_get_rectangle(Xen region, Xen nth, Xen rectangle) { #define H_cairo_region_get_rectangle "void cairo_region_get_rectangle(cairo_region_t* region, int nth, \ cairo_rectangle_int_t* rectangle)" Xen_check_type(Xen_is_cairo_region_t_(region), region, 1, "cairo_region_get_rectangle", "cairo_region_t*"); Xen_check_type(Xen_is_int(nth), nth, 2, "cairo_region_get_rectangle", "int"); Xen_check_type(Xen_is_cairo_rectangle_int_t_(rectangle), rectangle, 3, "cairo_region_get_rectangle", "cairo_rectangle_int_t*"); cairo_region_get_rectangle(Xen_to_C_cairo_region_t_(region), Xen_to_C_int(nth), Xen_to_C_cairo_rectangle_int_t_(rectangle)); return(Xen_false); } static Xen gxg_cairo_region_is_empty(Xen region) { #define H_cairo_region_is_empty "cairo_bool_t cairo_region_is_empty(cairo_region_t* region)" Xen_check_type(Xen_is_cairo_region_t_(region), region, 1, "cairo_region_is_empty", "cairo_region_t*"); return(C_to_Xen_cairo_bool_t(cairo_region_is_empty(Xen_to_C_cairo_region_t_(region)))); } static Xen gxg_cairo_region_contains_rectangle(Xen region, Xen rectangle) { #define H_cairo_region_contains_rectangle "cairo_region_overlap_t cairo_region_contains_rectangle(cairo_region_t* region, \ cairo_rectangle_int_t* rectangle)" Xen_check_type(Xen_is_cairo_region_t_(region), region, 1, "cairo_region_contains_rectangle", "cairo_region_t*"); Xen_check_type(Xen_is_cairo_rectangle_int_t_(rectangle), rectangle, 2, "cairo_region_contains_rectangle", "cairo_rectangle_int_t*"); return(C_to_Xen_cairo_region_overlap_t(cairo_region_contains_rectangle(Xen_to_C_cairo_region_t_(region), Xen_to_C_cairo_rectangle_int_t_(rectangle)))); } static Xen gxg_cairo_region_contains_point(Xen region, Xen x, Xen y) { #define H_cairo_region_contains_point "cairo_bool_t cairo_region_contains_point(cairo_region_t* region, \ int x, int y)" Xen_check_type(Xen_is_cairo_region_t_(region), region, 1, "cairo_region_contains_point", "cairo_region_t*"); Xen_check_type(Xen_is_int(x), x, 2, "cairo_region_contains_point", "int"); Xen_check_type(Xen_is_int(y), y, 3, "cairo_region_contains_point", "int"); return(C_to_Xen_cairo_bool_t(cairo_region_contains_point(Xen_to_C_cairo_region_t_(region), Xen_to_C_int(x), Xen_to_C_int(y)))); } static Xen gxg_cairo_region_translate(Xen region, Xen dx, Xen dy) { #define H_cairo_region_translate "void cairo_region_translate(cairo_region_t* region, int dx, int dy)" Xen_check_type(Xen_is_cairo_region_t_(region), region, 1, "cairo_region_translate", "cairo_region_t*"); Xen_check_type(Xen_is_int(dx), dx, 2, "cairo_region_translate", "int"); Xen_check_type(Xen_is_int(dy), dy, 3, "cairo_region_translate", "int"); cairo_region_translate(Xen_to_C_cairo_region_t_(region), Xen_to_C_int(dx), Xen_to_C_int(dy)); return(Xen_false); } static Xen gxg_cairo_region_subtract(Xen dst, Xen other) { #define H_cairo_region_subtract "cairo_status_t cairo_region_subtract(cairo_region_t* dst, cairo_region_t* other)" Xen_check_type(Xen_is_cairo_region_t_(dst), dst, 1, "cairo_region_subtract", "cairo_region_t*"); Xen_check_type(Xen_is_cairo_region_t_(other), other, 2, "cairo_region_subtract", "cairo_region_t*"); return(C_to_Xen_cairo_status_t(cairo_region_subtract(Xen_to_C_cairo_region_t_(dst), Xen_to_C_cairo_region_t_(other)))); } static Xen gxg_cairo_region_subtract_rectangle(Xen dst, Xen rectangle) { #define H_cairo_region_subtract_rectangle "cairo_status_t cairo_region_subtract_rectangle(cairo_region_t* dst, \ cairo_rectangle_int_t* rectangle)" Xen_check_type(Xen_is_cairo_region_t_(dst), dst, 1, "cairo_region_subtract_rectangle", "cairo_region_t*"); Xen_check_type(Xen_is_cairo_rectangle_int_t_(rectangle), rectangle, 2, "cairo_region_subtract_rectangle", "cairo_rectangle_int_t*"); return(C_to_Xen_cairo_status_t(cairo_region_subtract_rectangle(Xen_to_C_cairo_region_t_(dst), Xen_to_C_cairo_rectangle_int_t_(rectangle)))); } static Xen gxg_cairo_region_intersect(Xen dst, Xen other) { #define H_cairo_region_intersect "cairo_status_t cairo_region_intersect(cairo_region_t* dst, cairo_region_t* other)" Xen_check_type(Xen_is_cairo_region_t_(dst), dst, 1, "cairo_region_intersect", "cairo_region_t*"); Xen_check_type(Xen_is_cairo_region_t_(other), other, 2, "cairo_region_intersect", "cairo_region_t*"); return(C_to_Xen_cairo_status_t(cairo_region_intersect(Xen_to_C_cairo_region_t_(dst), Xen_to_C_cairo_region_t_(other)))); } static Xen gxg_cairo_region_intersect_rectangle(Xen dst, Xen rectangle) { #define H_cairo_region_intersect_rectangle "cairo_status_t cairo_region_intersect_rectangle(cairo_region_t* dst, \ cairo_rectangle_int_t* rectangle)" Xen_check_type(Xen_is_cairo_region_t_(dst), dst, 1, "cairo_region_intersect_rectangle", "cairo_region_t*"); Xen_check_type(Xen_is_cairo_rectangle_int_t_(rectangle), rectangle, 2, "cairo_region_intersect_rectangle", "cairo_rectangle_int_t*"); return(C_to_Xen_cairo_status_t(cairo_region_intersect_rectangle(Xen_to_C_cairo_region_t_(dst), Xen_to_C_cairo_rectangle_int_t_(rectangle)))); } static Xen gxg_cairo_region_union(Xen dst, Xen other) { #define H_cairo_region_union "cairo_status_t cairo_region_union(cairo_region_t* dst, cairo_region_t* other)" Xen_check_type(Xen_is_cairo_region_t_(dst), dst, 1, "cairo_region_union", "cairo_region_t*"); Xen_check_type(Xen_is_cairo_region_t_(other), other, 2, "cairo_region_union", "cairo_region_t*"); return(C_to_Xen_cairo_status_t(cairo_region_union(Xen_to_C_cairo_region_t_(dst), Xen_to_C_cairo_region_t_(other)))); } static Xen gxg_cairo_region_union_rectangle(Xen dst, Xen rectangle) { #define H_cairo_region_union_rectangle "cairo_status_t cairo_region_union_rectangle(cairo_region_t* dst, \ cairo_rectangle_int_t* rectangle)" Xen_check_type(Xen_is_cairo_region_t_(dst), dst, 1, "cairo_region_union_rectangle", "cairo_region_t*"); Xen_check_type(Xen_is_cairo_rectangle_int_t_(rectangle), rectangle, 2, "cairo_region_union_rectangle", "cairo_rectangle_int_t*"); return(C_to_Xen_cairo_status_t(cairo_region_union_rectangle(Xen_to_C_cairo_region_t_(dst), Xen_to_C_cairo_rectangle_int_t_(rectangle)))); } static Xen gxg_cairo_region_xor(Xen dst, Xen other) { #define H_cairo_region_xor "cairo_status_t cairo_region_xor(cairo_region_t* dst, cairo_region_t* other)" Xen_check_type(Xen_is_cairo_region_t_(dst), dst, 1, "cairo_region_xor", "cairo_region_t*"); Xen_check_type(Xen_is_cairo_region_t_(other), other, 2, "cairo_region_xor", "cairo_region_t*"); return(C_to_Xen_cairo_status_t(cairo_region_xor(Xen_to_C_cairo_region_t_(dst), Xen_to_C_cairo_region_t_(other)))); } static Xen gxg_cairo_region_xor_rectangle(Xen dst, Xen rectangle) { #define H_cairo_region_xor_rectangle "cairo_status_t cairo_region_xor_rectangle(cairo_region_t* dst, \ cairo_rectangle_int_t* rectangle)" Xen_check_type(Xen_is_cairo_region_t_(dst), dst, 1, "cairo_region_xor_rectangle", "cairo_region_t*"); Xen_check_type(Xen_is_cairo_rectangle_int_t_(rectangle), rectangle, 2, "cairo_region_xor_rectangle", "cairo_rectangle_int_t*"); return(C_to_Xen_cairo_status_t(cairo_region_xor_rectangle(Xen_to_C_cairo_region_t_(dst), Xen_to_C_cairo_rectangle_int_t_(rectangle)))); } #endif #define Xen_is_wrapped_object(Obj) (Xen_is_list(Obj) && (Xen_list_length(Obj) >= 2) && (Xen_is_symbol(Xen_car(Obj)))) static Xen gxg_GPOINTER(Xen obj) {return(Xen_list_2(xg_gpointer_symbol, (Xen_is_wrapped_object(obj)) ? Xen_cadr(obj) : Xen_wrap_C_pointer(obj)));} static Xen gxg_GDK_DRAG_CONTEXT(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GdkDragContext__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GDK_DEVICE(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GdkDevice__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GDK_KEYMAP(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GdkKeymap__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GDK_VISUAL(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GdkVisual__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GDK_WINDOW(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GdkWindow__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GDK_PIXBUF(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GdkPixbuf__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GDK_PIXBUF_ANIMATION(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GdkPixbufAnimation__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GDK_PIXBUF_ANIMATION_ITER(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GdkPixbufAnimationIter__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_ACCEL_GROUP(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkAccelGroup__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_ACCEL_LABEL(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkAccelLabel__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_ACCESSIBLE(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkAccessible__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_ADJUSTMENT(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkAdjustment__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_ASPECT_FRAME(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkAspectFrame__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_BUTTON_BOX(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkButtonBox__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_BIN(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkBin__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_BOX(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkBox__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_BUTTON(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkButton__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_CALENDAR(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkCalendar__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_CELL_EDITABLE(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkCellEditable__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_CELL_RENDERER(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkCellRenderer__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_CELL_RENDERER_PIXBUF(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkCellRendererPixbuf__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_CELL_RENDERER_TEXT(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkCellRendererText__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_CELL_RENDERER_TOGGLE(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkCellRendererToggle__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_CHECK_BUTTON(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkCheckButton__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_CHECK_MENU_ITEM(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkCheckMenuItem__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_CONTAINER(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkContainer__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_DIALOG(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkDialog__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_DRAWING_AREA(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkDrawingArea__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_EDITABLE(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkEditable__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_ENTRY(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkEntry__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_EVENT_BOX(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkEventBox__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_FIXED(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkFixed__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_FRAME(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkFrame__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_IMAGE(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkImage__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_IM_CONTEXT(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkIMContext__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_IM_CONTEXT_SIMPLE(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkIMContextSimple__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_INVISIBLE(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkInvisible__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_LABEL(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkLabel__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_LAYOUT(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkLayout__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_LIST_STORE(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkListStore__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_MENU_BAR(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkMenuBar__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_MENU(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkMenu__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_MENU_ITEM(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkMenuItem__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_MENU_SHELL(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkMenuShell__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_NOTEBOOK(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkNotebook__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_PANED(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkPaned__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_PROGRESS_BAR(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkProgressBar__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_RADIO_BUTTON(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkRadioButton__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_RADIO_MENU_ITEM(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkRadioMenuItem__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_RANGE(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkRange__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_SCALE(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkScale__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_SCROLLBAR(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkScrollbar__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_SCROLLED_WINDOW(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkScrolledWindow__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_SEPARATOR(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkSeparator__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_SEPARATOR_MENU_ITEM(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkSeparatorMenuItem__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_SETTINGS(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkSettings__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_SIZE_GROUP(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkSizeGroup__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_SPIN_BUTTON(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkSpinButton__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_STATUSBAR(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkStatusbar__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_TEXT_BUFFER(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkTextBuffer__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_TEXT_CHILD_ANCHOR(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkTextChildAnchor__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_TEXT_MARK(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkTextMark__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_TEXT_TAG(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkTextTag__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_TEXT_TAG_TABLE(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkTextTagTable__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_TEXT_VIEW(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkTextView__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_TOGGLE_BUTTON(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkToggleButton__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_TOOLBAR(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkToolbar__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_TREE_DRAG_SOURCE(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkTreeDragSource__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_TREE_DRAG_DEST(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkTreeDragDest__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_TREE_MODEL(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkTreeModel__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_TREE_MODEL_SORT(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkTreeModelSort__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_TREE_SELECTION(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkTreeSelection__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_TREE_SORTABLE(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkTreeSortable__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_TREE_STORE(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkTreeStore__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_TREE_VIEW_COLUMN(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkTreeViewColumn__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_TREE_VIEW(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkTreeView__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_VIEWPORT(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkViewport__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_WIDGET(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkWidget__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_WINDOW(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkWindow__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_PANGO_CONTEXT(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_PangoContext__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_PANGO_FONT_FAMILY(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_PangoFontFamily__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_PANGO_FONT_FACE(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_PangoFontFace__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_PANGO_FONT(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_PangoFont__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_PANGO_FONT_MAP(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_PangoFontMap__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_PANGO_LAYOUT(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_PangoLayout__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_G_OBJECT(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GObject__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GDK_SCREEN(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GdkScreen__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GDK_DISPLAY_OBJECT(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GdkDisplay__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GDK_EVENT(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GdkEvent__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GDK_EVENT_ANY(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GdkEventAny__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GDK_EVENT_EXPOSE(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GdkEventExpose__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GDK_EVENT_NOEXPOSE(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GdkEventNoExpose__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GDK_EVENT_VISIBILITY(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GdkEventVisibility__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GDK_EVENT_MOTION(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GdkEventMotion__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GDK_EVENT_BUTTON(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GdkEventButton__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GDK_EVENT_SCROLL(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GdkEventScroll__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GDK_EVENT_KEY(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GdkEventKey__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GDK_EVENT_CROSSING(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GdkEventCrossing__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GDK_EVENT_FOCUS(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GdkEventFocus__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GDK_EVENT_CONFIGURE(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GdkEventConfigure__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GDK_EVENT_PROPERTY(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GdkEventProperty__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GDK_EVENT_SELECTION(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GdkEventSelection__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GDK_EVENT_PROXIMITY(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GdkEventProximity__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GDK_EVENT_SETTING(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GdkEventSetting__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GDK_EVENT_WINDOWSTATE(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GdkEventWindowState__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GDK_EVENT_DND(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GdkEventDND__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_FILE_CHOOSER_DIALOG(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkFileChooserDialog__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_FILE_CHOOSER_WIDGET(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkFileChooserWidget__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_TREE_MODEL_FILTER(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkTreeModelFilter__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_COMBO_BOX(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkComboBox__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_EXPANDER(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkExpander__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_FONT_BUTTON(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkFontButton__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_COLOR_BUTTON(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkColorButton__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_ENTRY_COMPLETION(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkEntryCompletion__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_RADIO_TOOL_BUTTON(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkRadioToolButton__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_SEPARATOR_TOOL_ITEM(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkSeparatorToolItem__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_TOGGLE_TOOL_BUTTON(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkToggleToolButton__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_FILE_FILTER(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkFileFilter__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_CELL_LAYOUT(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkCellLayout__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_CLIPBOARD(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkClipboard__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_FILE_CHOOSER(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkFileChooser__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_ICON_THEME(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkIconTheme__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_TOOL_BUTTON(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkToolButton__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_TOOL_ITEM(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkToolItem__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_ACCEL_MAP(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkAccelMap_symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_CELL_VIEW(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkCellView__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_ABOUT_DIALOG(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkAboutDialog__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_CELL_RENDERER_COMBO(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkCellRendererCombo__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_CELL_RENDERER_PROGRESS(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkCellRendererProgress__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_ICON_VIEW(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkIconView__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_FILE_CHOOSER_BUTTON(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkFileChooserButton__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_MENU_TOOL_BUTTON(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkMenuToolButton__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_ASSISTANT(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkAssistant__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_CELL_RENDERER_ACCEL(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkCellRendererAccel__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_CELL_RENDERER_SPIN(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkCellRendererSpin__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_LINK_BUTTON(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkLinkButton__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_RECENT_CHOOSER_DIALOG(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkRecentChooserDialog__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_RECENT_CHOOSER(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkRecentChooser__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_RECENT_CHOOSER_MENU(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkRecentChooserMenu__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_RECENT_CHOOSER_WIDGET(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkRecentChooserWidget__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_RECENT_FILTER(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkRecentFilter__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_RECENT_MANAGER(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkRecentManager__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_PRINT_CONTEXT(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkPrintContext__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_PRINT_OPERATION(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkPrintOperation__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_PRINT_OPERATION_PREVIEW(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkPrintOperationPreview__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_PRINT_SETTINGS(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkPrintSettings__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_TOOLTIP(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkTooltip__symbol, Xen_cadr(obj)) : Xen_false);} #if GTK_CHECK_VERSION(2, 18, 0) static Xen gxg_GTK_INFO_BAR(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkInfoBar__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_ENTRY_BUFFER(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkEntryBuffer__symbol, Xen_cadr(obj)) : Xen_false);} #endif #if GTK_CHECK_VERSION(2, 20, 0) static Xen gxg_GTK_SPINNER(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkSpinner__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_CELL_RENDERER_SPINNER(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkCellRendererSpinner__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_TOOL_PALETTE(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkToolPalette__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_TOOL_ITEM_GROUP(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkToolItemGroup__symbol, Xen_cadr(obj)) : Xen_false);} #endif #if GTK_CHECK_VERSION(3, 0, 0) static Xen gxg_GTK_COMBO_BOX_TEXT(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkComboBoxText__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_GRID(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkGrid__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_SCROLLABLE(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkScrollable__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GDK_RGBA(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GdkRGBA__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_SWITCH(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkSwitch__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_ORIENTABLE(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkOrientable__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_WINDOW_GROUP(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkWindowGroup__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_TOOL_SHELL(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkToolShell__symbol, Xen_cadr(obj)) : Xen_false);} #endif #if GTK_CHECK_VERSION(3, 2, 0) static Xen gxg_GTK_OVERLAY(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkOverlay__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_FONT_CHOOSER(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkFontChooser__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_FONT_CHOOSER_DIALOG(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkFontChooserDialog__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_FONT_CHOOSER_WIDGET(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkFontChooserWidget__symbol, Xen_cadr(obj)) : Xen_false);} #endif #if GTK_CHECK_VERSION(3, 4, 0) static Xen gxg_GTK_APPLICATION_WINDOW(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkApplicationWindow__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_COLOR_CHOOSER_DIALOG(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkColorChooserDialog__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_COLOR_CHOOSER_WIDGET(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkColorWidget__symbol, Xen_cadr(obj)) : Xen_false);} #endif #if GTK_CHECK_VERSION(3, 6, 0) static Xen gxg_GTK_MENU_BUTTON(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkMenuButton__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_SEARCH_ENTRY(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkWidget__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_LEVEL_BAR(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkLevelBar__symbol, Xen_cadr(obj)) : Xen_false);} #endif #if GTK_CHECK_VERSION(3, 10, 0) static Xen gxg_GTK_PLACES_SIDEBAR(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkPlacesSidebar__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_STACK_SWITCHER(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkStackSwitcher__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_STACK(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkStack__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_REVEALER(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkRevealer__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_HEADER_BAR(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkHeaderBar__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_LIST_BOX(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkListBox__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_LIST_BOX_ROW(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkListBoxRow__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_SEARCH_BAR(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkSearchBar__symbol, Xen_cadr(obj)) : Xen_false);} #endif #if GTK_CHECK_VERSION(3, 12, 0) static Xen gxg_GTK_FLOW_BOX(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkFlowBox__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_FLOW_BOX_CHILD(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkFlowBoxChild__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_ACTION_BAR(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkActionBar__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_POPOVER(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkPopover__symbol, Xen_cadr(obj)) : Xen_false);} #endif #if GTK_CHECK_VERSION(3, 14, 0) static Xen gxg_GTK_GESTURE(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkGesture__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_GESTURE_DRAG(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkGestureDrag__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_GESTURE_LONG_PRESS(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkGestureLongPress__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_GESTURE_ZOOM(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkGestureZoom__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_GESTURE_SWIPE(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkGestureSwipe__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_GESTURE_SINGLE(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkGestureSingle__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_GESTURE_PAN(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkGesturePan__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_GESTURE_MULTI_PRESS(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkGestureMultiPress__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_GESTURE_ROTATE(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkGestureRotate__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_EVENT_CONTROLLER(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkEventController__symbol, Xen_cadr(obj)) : Xen_false);} #endif #if GTK_CHECK_VERSION(3, 16, 0) static Xen gxg_GTK_GL_AREA(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkGLArea__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GDK_GL_CONTEXT(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GdkGLContext__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_POPOVER_MENU(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkPopoverMenu__symbol, Xen_cadr(obj)) : Xen_false);} static Xen gxg_GTK_STACK_SIDEBAR(Xen obj) {return((Xen_is_wrapped_object(obj)) ? Xen_list_2(xg_GtkStackSidebar__symbol, Xen_cadr(obj)) : Xen_false);} #endif static Xen gxg_GDK_IS_DRAG_CONTEXT(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GDK_IS_DRAG_CONTEXT((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GDK_IS_DEVICE(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GDK_IS_DEVICE((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GDK_IS_KEYMAP(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GDK_IS_KEYMAP((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GDK_IS_VISUAL(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GDK_IS_VISUAL((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GDK_IS_WINDOW(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GDK_IS_WINDOW((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GDK_IS_PIXBUF(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GDK_IS_PIXBUF((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GDK_IS_PIXBUF_ANIMATION(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GDK_IS_PIXBUF_ANIMATION((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GDK_IS_PIXBUF_ANIMATION_ITER(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GDK_IS_PIXBUF_ANIMATION_ITER((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_ACCEL_GROUP(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_ACCEL_GROUP((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_ACCEL_LABEL(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_ACCEL_LABEL((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_ACCESSIBLE(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_ACCESSIBLE((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_ADJUSTMENT(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_ADJUSTMENT((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_ASPECT_FRAME(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_ASPECT_FRAME((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_BUTTON_BOX(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_BUTTON_BOX((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_BIN(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_BIN((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_BOX(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_BOX((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_BUTTON(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_BUTTON((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_CALENDAR(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_CALENDAR((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_CELL_EDITABLE(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_CELL_EDITABLE((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_CELL_RENDERER(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_CELL_RENDERER((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_CELL_RENDERER_PIXBUF(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_CELL_RENDERER_PIXBUF((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_CELL_RENDERER_TEXT(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_CELL_RENDERER_TEXT((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_CELL_RENDERER_TOGGLE(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_CELL_RENDERER_TOGGLE((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_CHECK_BUTTON(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_CHECK_BUTTON((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_CHECK_MENU_ITEM(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_CHECK_MENU_ITEM((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_CONTAINER(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_CONTAINER((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_DIALOG(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_DIALOG((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_DRAWING_AREA(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_DRAWING_AREA((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_EDITABLE(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_EDITABLE((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_ENTRY(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_ENTRY((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_EVENT_BOX(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_EVENT_BOX((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_FIXED(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_FIXED((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_FRAME(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_FRAME((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_IMAGE(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_IMAGE((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_IM_CONTEXT(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_IM_CONTEXT((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_IM_CONTEXT_SIMPLE(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_IM_CONTEXT_SIMPLE((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_INVISIBLE(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_INVISIBLE((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_LABEL(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_LABEL((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_LAYOUT(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_LAYOUT((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_LIST_STORE(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_LIST_STORE((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_MENU_BAR(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_MENU_BAR((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_MENU(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_MENU((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_MENU_ITEM(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_MENU_ITEM((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_MENU_SHELL(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_MENU_SHELL((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_NOTEBOOK(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_NOTEBOOK((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_PANED(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_PANED((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_PROGRESS_BAR(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_PROGRESS_BAR((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_RADIO_BUTTON(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_RADIO_BUTTON((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_RADIO_MENU_ITEM(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_RADIO_MENU_ITEM((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_RANGE(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_RANGE((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_SCALE(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_SCALE((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_SCROLLBAR(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_SCROLLBAR((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_SCROLLED_WINDOW(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_SCROLLED_WINDOW((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_SEPARATOR(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_SEPARATOR((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_SEPARATOR_MENU_ITEM(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_SEPARATOR_MENU_ITEM((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_SETTINGS(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_SETTINGS((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_SIZE_GROUP(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_SIZE_GROUP((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_SPIN_BUTTON(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_SPIN_BUTTON((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_STATUSBAR(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_STATUSBAR((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_TEXT_BUFFER(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_TEXT_BUFFER((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_TEXT_CHILD_ANCHOR(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_TEXT_CHILD_ANCHOR((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_TEXT_MARK(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_TEXT_MARK((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_TEXT_TAG(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_TEXT_TAG((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_TEXT_TAG_TABLE(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_TEXT_TAG_TABLE((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_TEXT_VIEW(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_TEXT_VIEW((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_TOGGLE_BUTTON(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_TOGGLE_BUTTON((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_TOOLBAR(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_TOOLBAR((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_TREE_DRAG_SOURCE(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_TREE_DRAG_SOURCE((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_TREE_DRAG_DEST(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_TREE_DRAG_DEST((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_TREE_MODEL(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_TREE_MODEL((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_TREE_MODEL_SORT(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_TREE_MODEL_SORT((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_TREE_SELECTION(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_TREE_SELECTION((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_TREE_SORTABLE(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_TREE_SORTABLE((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_TREE_STORE(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_TREE_STORE((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_TREE_VIEW_COLUMN(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_TREE_VIEW_COLUMN((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_TREE_VIEW(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_TREE_VIEW((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_VIEWPORT(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_VIEWPORT((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_WIDGET(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_WIDGET((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_WINDOW(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_WINDOW((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_PANGO_IS_CONTEXT(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && PANGO_IS_CONTEXT((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_PANGO_IS_FONT_FAMILY(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && PANGO_IS_FONT_FAMILY((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_PANGO_IS_FONT_FACE(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && PANGO_IS_FONT_FACE((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_PANGO_IS_FONT(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && PANGO_IS_FONT((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_PANGO_IS_FONT_MAP(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && PANGO_IS_FONT_MAP((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_PANGO_IS_LAYOUT(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && PANGO_IS_LAYOUT((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_G_IS_OBJECT(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && G_IS_OBJECT((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GDK_IS_SCREEN(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GDK_IS_SCREEN((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GDK_IS_DISPLAY(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GDK_IS_DISPLAY((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_FILE_CHOOSER_DIALOG(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_FILE_CHOOSER_DIALOG((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_FILE_CHOOSER_WIDGET(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_FILE_CHOOSER_WIDGET((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_TREE_MODEL_FILTER(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_TREE_MODEL_FILTER((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_COMBO_BOX(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_COMBO_BOX((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_EXPANDER(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_EXPANDER((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_FONT_BUTTON(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_FONT_BUTTON((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_COLOR_BUTTON(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_COLOR_BUTTON((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_ENTRY_COMPLETION(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_ENTRY_COMPLETION((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_RADIO_TOOL_BUTTON(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_RADIO_TOOL_BUTTON((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_SEPARATOR_TOOL_ITEM(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_SEPARATOR_TOOL_ITEM((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_TOGGLE_TOOL_BUTTON(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_TOGGLE_TOOL_BUTTON((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_FILE_FILTER(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_FILE_FILTER((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_CELL_LAYOUT(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_CELL_LAYOUT((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_CLIPBOARD(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_CLIPBOARD((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_FILE_CHOOSER(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_FILE_CHOOSER((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_ICON_THEME(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_ICON_THEME((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_TOOL_BUTTON(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_TOOL_BUTTON((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_TOOL_ITEM(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_TOOL_ITEM((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_ACCEL_MAP(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_ACCEL_MAP((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_CELL_VIEW(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_CELL_VIEW((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_ABOUT_DIALOG(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_ABOUT_DIALOG((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_CELL_RENDERER_COMBO(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_CELL_RENDERER_COMBO((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_CELL_RENDERER_PROGRESS(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_CELL_RENDERER_PROGRESS((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_ICON_VIEW(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_ICON_VIEW((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_FILE_CHOOSER_BUTTON(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_FILE_CHOOSER_BUTTON((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_MENU_TOOL_BUTTON(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_MENU_TOOL_BUTTON((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_ASSISTANT(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_ASSISTANT((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_CELL_RENDERER_ACCEL(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_CELL_RENDERER_ACCEL((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_CELL_RENDERER_SPIN(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_CELL_RENDERER_SPIN((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_LINK_BUTTON(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_LINK_BUTTON((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_RECENT_CHOOSER_DIALOG(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_RECENT_CHOOSER_DIALOG((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_RECENT_CHOOSER(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_RECENT_CHOOSER((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_RECENT_CHOOSER_MENU(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_RECENT_CHOOSER_MENU((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_RECENT_CHOOSER_WIDGET(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_RECENT_CHOOSER_WIDGET((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_RECENT_FILTER(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_RECENT_FILTER((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_RECENT_MANAGER(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_RECENT_MANAGER((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_PRINT_CONTEXT(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_PRINT_CONTEXT((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_PRINT_OPERATION(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_PRINT_OPERATION((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_PRINT_OPERATION_PREVIEW(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_PRINT_OPERATION_PREVIEW((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_PRINT_SETTINGS(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_PRINT_SETTINGS((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_TOOLTIP(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_TOOLTIP((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} #if GTK_CHECK_VERSION(2, 18, 0) static Xen gxg_GTK_IS_INFO_BAR(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_INFO_BAR((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_ENTRY_BUFFER(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_ENTRY_BUFFER((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} #endif #if GTK_CHECK_VERSION(2, 20, 0) static Xen gxg_GTK_IS_SPINNER(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_SPINNER((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_CELL_RENDERER_SPINNER(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_CELL_RENDERER_SPINNER((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_TOOL_PALETTE(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_TOOL_PALETTE((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_TOOL_ITEM_GROUP(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_TOOL_ITEM_GROUP((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} #endif #if GTK_CHECK_VERSION(3, 0, 0) static Xen gxg_GTK_IS_COMBO_BOX_TEXT(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_COMBO_BOX_TEXT((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_GRID(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_GRID((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_SCROLLABLE(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_SCROLLABLE((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_SWITCH(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_SWITCH((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_ORIENTABLE(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_ORIENTABLE((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_WINDOW_GROUP(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_WINDOW_GROUP((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_TOOL_SHELL(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_TOOL_SHELL((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} #endif #if GTK_CHECK_VERSION(3, 2, 0) static Xen gxg_GTK_IS_OVERLAY(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_OVERLAY((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_FONT_CHOOSER(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_FONT_CHOOSER((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_FONT_CHOOSER_DIALOG(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_FONT_CHOOSER_DIALOG((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_FONT_CHOOSER_WIDGET(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_FONT_CHOOSER_WIDGET((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} #endif #if GTK_CHECK_VERSION(3, 4, 0) static Xen gxg_GTK_IS_APPLICATION_WINDOW(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_APPLICATION_WINDOW((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_COLOR_CHOOSER_DIALOG(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_COLOR_CHOOSER_DIALOG((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_COLOR_CHOOSER_WIDGET(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_COLOR_CHOOSER_WIDGET((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} #endif #if GTK_CHECK_VERSION(3, 6, 0) static Xen gxg_GTK_IS_MENU_BUTTON(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_MENU_BUTTON((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_SEARCH_ENTRY(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_SEARCH_ENTRY((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_LEVEL_BAR(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_LEVEL_BAR((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} #endif #if GTK_CHECK_VERSION(3, 10, 0) static Xen gxg_GTK_IS_PLACES_SIDEBAR(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_PLACES_SIDEBAR((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_STACK_SWITCHER(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_STACK_SWITCHER((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_STACK(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_STACK((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_REVEALER(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_REVEALER((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_HEADER_BAR(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_HEADER_BAR((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_LIST_BOX(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_LIST_BOX((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_LIST_BOX_ROW(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_LIST_BOX_ROW((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_SEARCH_BAR(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_SEARCH_BAR((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} #endif #if GTK_CHECK_VERSION(3, 12, 0) static Xen gxg_GTK_IS_FLOW_BOX(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_FLOW_BOX((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_FLOW_BOX_CHILD(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_FLOW_BOX_CHILD((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_ACTION_BAR(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_ACTION_BAR((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_POPOVER(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_POPOVER((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} #endif #if GTK_CHECK_VERSION(3, 14, 0) static Xen gxg_GTK_IS_GESTURE(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_GESTURE((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_GESTURE_DRAG(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_GESTURE_DRAG((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_GESTURE_LONG_PRESS(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_GESTURE_LONG_PRESS((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_GESTURE_ZOOM(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_GESTURE_ZOOM((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_GESTURE_SWIPE(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_GESTURE_SWIPE((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_GESTURE_SINGLE(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_GESTURE_SINGLE((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_GESTURE_PAN(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_GESTURE_PAN((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_GESTURE_MULTI_PRESS(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_GESTURE_MULTI_PRESS((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_GESTURE_ROTATE(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_GESTURE_ROTATE((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_EVENT_CONTROLLER(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_EVENT_CONTROLLER((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} #endif #if GTK_CHECK_VERSION(3, 16, 0) static Xen gxg_GTK_IS_GL_AREA(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_GL_AREA((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GDK_IS_GL_CONTEXT(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GDK_IS_GL_CONTEXT((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_POPOVER_MENU(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_POPOVER_MENU((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} static Xen gxg_GTK_IS_STACK_SIDEBAR(Xen obj) {return(C_bool_to_Xen_boolean(Xen_is_wrapped_object(obj) && GTK_IS_STACK_SIDEBAR((GTypeInstance *)Xen_unwrap_C_pointer(Xen_cadr(obj)))));} #endif /* ---------------------------------------- special functions ---------------------------------------- */ static Xen gxg_gtk_init(Xen argc, Xen argv) { #define H_gtk_init "void gtk_init(int* argc, char*** argv)" int ref_argc = 0; char** ref_argv = NULL; if (Xen_is_bound(argv)) { if (Xen_is_bound(argc) && Xen_is_integer(argc) && Xen_to_C_int(argc) <= Xen_list_length(argv)) ref_argc = Xen_to_C_int(argc); else ref_argc = Xen_list_length(argv); } ref_argv = (char**)calloc(ref_argc, sizeof(char*)); { int i; Xen lst; lst = Xen_copy_arg(argv); for (i = 0; i < ref_argc; i++, lst = Xen_cdr(lst)) ref_argv[i] = Xen_to_C_char_(Xen_car(lst)); } gtk_init(&ref_argc, &ref_argv); return(Xen_list_2(C_to_Xen_int(ref_argc), C_to_Xen_char__(ref_argv))); } static Xen gxg_gtk_init_check(Xen argc, Xen argv) { #define H_gtk_init_check "gboolean gtk_init_check(int* argc, char*** argv)" int ref_argc = 0; char** ref_argv = NULL; if (Xen_is_bound(argc) && Xen_is_list(argc)) { argv = argc; ref_argc = Xen_list_length(argv); } else { if (Xen_is_bound(argv)) { int len; Xen_check_type(Xen_is_integer(argc), argc, 1, "gtk_init_check", "int argc"); Xen_check_type(Xen_is_list(argv), argv, 2, "gtk_init_check", "char *argv[]"); len = Xen_list_length(argv); ref_argc = Xen_to_C_int(argc); if (ref_argc > len) ref_argc = len; } } ref_argv = (char**)calloc(ref_argc, sizeof(char*)); { int i; Xen lst; lst = Xen_copy_arg(argv); for (i = 0; i < ref_argc; i++, lst = Xen_cdr(lst)) ref_argv[i] = Xen_to_C_char_(Xen_car(lst)); } { Xen result; result = C_to_Xen_gboolean(gtk_init_check(&ref_argc, &ref_argv)); return(Xen_list_3(result, C_to_Xen_int(ref_argc), C_to_Xen_char__(ref_argv))); } } static Xen gxg_make_target_entry(Xen lst) { GtkTargetEntry* targets; int i, len; #define H_make_target_entry "(make-target-entry lst): GtkTargetEntry*, each member of 'lst' should be (list target flags info)" Xen_check_type(Xen_is_list(lst), lst, 1, "make-target-entry", "a list of lists describing each target"); len = Xen_list_length(lst); if (len == 0) return(Xen_false); targets = (GtkTargetEntry *)calloc(len, sizeof(GtkTargetEntry)); for (i = 0; i < len; i++) { Xen val; val = Xen_list_ref(lst, i); targets[i].target = xen_strdup(Xen_string_to_C_string(Xen_list_ref(val, 0))); targets[i].flags = (guint)Xen_ulong_to_C_ulong(Xen_list_ref(val, 1)); targets[i].info = (guint)Xen_ulong_to_C_ulong(Xen_list_ref(val, 2)); } return(C_to_Xen_GtkTargetEntry_(targets)); } /* conversions */ static Xen c_array_to_xen_list(Xen val_1, Xen clen) { Xen result = Xen_empty_list; Xen val, ctype; int i, len = -1; if (Xen_is_integer(clen)) len = Xen_integer_to_C_int(clen); if (!(Xen_is_list(val_1))) return(Xen_false); /* type:location cons */ val = Xen_copy_arg(val_1); /* protect Ruby arg */ ctype = Xen_car(val); if (ctype == xg_gboolean__symbol) { gboolean* arr; arr = (gboolean*)Xen_unwrap_C_pointer(Xen_cadr(val)); if (len == -1) {for (i = 0; arr[i]; i++) {}; len = i;} for (i = len - 1; i >= 0; i--) result = Xen_cons(C_to_Xen_gboolean(arr[i]), result); } if (ctype == xg_gdouble__symbol) { gdouble* arr; arr = (gdouble*)Xen_unwrap_C_pointer(Xen_cadr(val)); if (len == -1) {for (i = 0; arr[i]; i++) {}; len = i;} for (i = len - 1; i >= 0; i--) result = Xen_cons(C_to_Xen_gdouble(arr[i]), result); } if (ctype == xg_gunichar__symbol) { gunichar* arr; arr = (gunichar*)Xen_unwrap_C_pointer(Xen_cadr(val)); if (len == -1) {for (i = 0; arr[i]; i++) {}; len = i;} for (i = len - 1; i >= 0; i--) result = Xen_cons(C_to_Xen_gunichar(arr[i]), result); } if (ctype == xg_GType__symbol) { GType* arr; arr = (GType*)Xen_unwrap_C_pointer(Xen_cadr(val)); if (len == -1) {for (i = 0; arr[i]; i++) {}; len = i;} for (i = len - 1; i >= 0; i--) result = Xen_cons(C_to_Xen_GType(arr[i]), result); } if (ctype == xg_guint__symbol) { guint* arr; arr = (guint*)Xen_unwrap_C_pointer(Xen_cadr(val)); if (len == -1) {for (i = 0; arr[i]; i++) {}; len = i;} for (i = len - 1; i >= 0; i--) result = Xen_cons(C_to_Xen_guint(arr[i]), result); } if (ctype == xg_gchar___symbol) { gchar** arr; arr = (gchar**)Xen_unwrap_C_pointer(Xen_cadr(val)); if (len == -1) {for (i = 0; arr[i]; i++) {}; len = i;} for (i = len - 1; i >= 0; i--) result = Xen_cons(C_to_Xen_gchar_(arr[i]), result); } if (ctype == xg_guchar__symbol) { guchar* arr; arr = (guchar*)Xen_unwrap_C_pointer(Xen_cadr(val)); if (len == -1) {for (i = 0; arr[i]; i++) {}; len = i;} for (i = len - 1; i >= 0; i--) result = Xen_cons(C_to_Xen_guchar(arr[i]), result); } if (ctype == xg_gint__symbol) { gint* arr; arr = (gint*)Xen_unwrap_C_pointer(Xen_cadr(val)); if (len == -1) {for (i = 0; arr[i]; i++) {}; len = i;} for (i = len - 1; i >= 0; i--) result = Xen_cons(C_to_Xen_gint(arr[i]), result); } if (ctype == xg_GdkVisualType__symbol) { GdkVisualType* arr; arr = (GdkVisualType*)Xen_unwrap_C_pointer(Xen_cadr(val)); if (len == -1) {for (i = 0; arr[i]; i++) {}; len = i;} for (i = len - 1; i >= 0; i--) result = Xen_cons(C_to_Xen_GdkVisualType(arr[i]), result); } if (ctype == xg_char___symbol) { char** arr; arr = (char**)Xen_unwrap_C_pointer(Xen_cadr(val)); if (len == -1) {for (i = 0; arr[i]; i++) {}; len = i;} for (i = len - 1; i >= 0; i--) result = Xen_cons(C_to_Xen_char_(arr[i]), result); } if (ctype == xg_guint16__symbol) { guint16* arr; arr = (guint16*)Xen_unwrap_C_pointer(Xen_cadr(val)); if (len == -1) {for (i = 0; arr[i]; i++) {}; len = i;} for (i = len - 1; i >= 0; i--) result = Xen_cons(C_to_Xen_guint16(arr[i]), result); } if (ctype == xg_int__symbol) { int* arr; arr = (int*)Xen_unwrap_C_pointer(Xen_cadr(val)); if (len == -1) {for (i = 0; arr[i]; i++) {}; len = i;} for (i = len - 1; i >= 0; i--) result = Xen_cons(C_to_Xen_int(arr[i]), result); } if (ctype == xg_PangoFontFace___symbol) { PangoFontFace** arr; arr = (PangoFontFace**)Xen_unwrap_C_pointer(Xen_cadr(val)); if (len == -1) {for (i = 0; arr[i]; i++) {}; len = i;} for (i = len - 1; i >= 0; i--) result = Xen_cons(C_to_Xen_PangoFontFace_(arr[i]), result); } if (ctype == xg_PangoFontDescription___symbol) { PangoFontDescription** arr; arr = (PangoFontDescription**)Xen_unwrap_C_pointer(Xen_cadr(val)); if (len == -1) {for (i = 0; arr[i]; i++) {}; len = i;} for (i = len - 1; i >= 0; i--) result = Xen_cons(C_to_Xen_PangoFontDescription_(arr[i]), result); } if (ctype == xg_PangoFontFamily___symbol) { PangoFontFamily** arr; arr = (PangoFontFamily**)Xen_unwrap_C_pointer(Xen_cadr(val)); if (len == -1) {for (i = 0; arr[i]; i++) {}; len = i;} for (i = len - 1; i >= 0; i--) result = Xen_cons(C_to_Xen_PangoFontFamily_(arr[i]), result); } if (ctype == xg_PangoAttrList___symbol) { PangoAttrList** arr; arr = (PangoAttrList**)Xen_unwrap_C_pointer(Xen_cadr(val)); if (len == -1) {for (i = 0; arr[i]; i++) {}; len = i;} for (i = len - 1; i >= 0; i--) result = Xen_cons(C_to_Xen_PangoAttrList_(arr[i]), result); } if (ctype == xg_GtkTreeModel___symbol) { GtkTreeModel** arr; arr = (GtkTreeModel**)Xen_unwrap_C_pointer(Xen_cadr(val)); if (len == -1) {for (i = 0; arr[i]; i++) {}; len = i;} for (i = len - 1; i >= 0; i--) result = Xen_cons(C_to_Xen_GtkTreeModel_(arr[i]), result); } if (ctype == xg_GList__symbol) { /* tagging these pointers is currently up to the caller */ GList* lst; lst = (GList*)Xen_unwrap_C_pointer(Xen_cadr(val)); len = g_list_length(lst); for (i = len - 1; i >= 0; i--) result = Xen_cons(C_ulong_to_Xen_ulong(g_list_nth_data(lst, i)), result); } return(result); } static Xen xg_object_get(Xen val, Xen name, Xen string_type) { gint temp; gchar *str; Xen_check_type(Xen_is_gpointer(val), val, 1, "g_object_get", "gpointer"); Xen_check_type(Xen_is_string(name), name, 2, "g_object_get", "string"); if (Xen_is_false(string_type)) {g_object_get(Xen_to_C_gpointer(val), (const gchar *)(Xen_string_to_C_string(name)), &temp, NULL); return(C_int_to_Xen_integer(temp));} else {g_object_get(Xen_to_C_gpointer(val), (const gchar *)(Xen_string_to_C_string(name)), &str, NULL); return(C_string_to_Xen_string(str));} } static Xen xg_object_set(Xen val, Xen name, Xen new_val) { Xen_check_type(Xen_is_gpointer(val), val, 1, "g_object_set", "gpointer"); Xen_check_type(Xen_is_string(name), name, 2, "g_object_set", "string"); if (Xen_is_boolean(new_val)) g_object_set(Xen_to_C_gpointer(val), (const gchar *)(Xen_string_to_C_string(name)), Xen_boolean_to_C_bool(new_val), NULL); else { if (Xen_is_number(new_val)) g_object_set(Xen_to_C_gpointer(val), (const gchar *)(Xen_string_to_C_string(name)), Xen_integer_to_C_int(new_val), NULL); else g_object_set(Xen_to_C_gpointer(val), (const gchar *)(Xen_string_to_C_string(name)), Xen_string_to_C_string(new_val), NULL); } return(new_val); } static Xen xg_gtk_event_keyval(Xen event) { GdkEventKey *e; e = Xen_to_C_GdkEventKey_(event); if (e) return(C_int_to_Xen_integer((int)(e->keyval))); return(XEN_ZERO); } static Xen xen_list_to_c_array(Xen val, Xen type) { int i, len; len = Xen_list_length(val); if (type == xg_gboolean__symbol) { gboolean* arr; arr = (gboolean*)calloc(len + 1, sizeof(gboolean)); for (i = 0; i < len; i++, val = Xen_cdr(val)) arr[i] = Xen_to_C_gboolean(Xen_car(val)); return(Xen_list_3(xg_gboolean__symbol, Xen_wrap_C_pointer(arr), make_xm_obj(arr))); } if (type == xg_gdouble__symbol) { gdouble* arr; arr = (gdouble*)calloc(len + 1, sizeof(gdouble)); for (i = 0; i < len; i++, val = Xen_cdr(val)) arr[i] = Xen_to_C_gdouble(Xen_car(val)); return(Xen_list_3(xg_gdouble__symbol, Xen_wrap_C_pointer(arr), make_xm_obj(arr))); } if (type == xg_gunichar__symbol) { gunichar* arr; arr = (gunichar*)calloc(len + 1, sizeof(gunichar)); for (i = 0; i < len; i++, val = Xen_cdr(val)) arr[i] = Xen_to_C_gunichar(Xen_car(val)); return(Xen_list_3(xg_gunichar__symbol, Xen_wrap_C_pointer(arr), make_xm_obj(arr))); } if (type == xg_GType__symbol) { GType* arr; arr = (GType*)calloc(len + 1, sizeof(GType)); for (i = 0; i < len; i++, val = Xen_cdr(val)) arr[i] = Xen_to_C_GType(Xen_car(val)); return(Xen_list_3(xg_GType__symbol, Xen_wrap_C_pointer(arr), make_xm_obj(arr))); } if (type == xg_guint__symbol) { guint* arr; arr = (guint*)calloc(len + 1, sizeof(guint)); for (i = 0; i < len; i++, val = Xen_cdr(val)) arr[i] = Xen_to_C_guint(Xen_car(val)); return(Xen_list_3(xg_guint__symbol, Xen_wrap_C_pointer(arr), make_xm_obj(arr))); } if (type == xg_gchar___symbol) { gchar** arr; arr = (gchar**)calloc(len + 1, sizeof(gchar*)); for (i = 0; i < len; i++, val = Xen_cdr(val)) arr[i] = Xen_to_C_gchar_(Xen_car(val)); return(Xen_list_3(xg_gchar___symbol, Xen_wrap_C_pointer(arr), make_xm_obj(arr))); } if (type == xg_guchar__symbol) { guchar* arr; arr = (guchar*)calloc(len + 1, sizeof(guchar)); for (i = 0; i < len; i++, val = Xen_cdr(val)) arr[i] = Xen_to_C_guchar(Xen_car(val)); return(Xen_list_3(xg_guchar__symbol, Xen_wrap_C_pointer(arr), make_xm_obj(arr))); } if (type == xg_gint__symbol) { gint* arr; arr = (gint*)calloc(len + 1, sizeof(gint)); for (i = 0; i < len; i++, val = Xen_cdr(val)) arr[i] = Xen_to_C_gint(Xen_car(val)); return(Xen_list_3(xg_gint__symbol, Xen_wrap_C_pointer(arr), make_xm_obj(arr))); } if (type == xg_GdkVisualType__symbol) { GdkVisualType* arr; arr = (GdkVisualType*)calloc(len + 1, sizeof(GdkVisualType)); for (i = 0; i < len; i++, val = Xen_cdr(val)) arr[i] = Xen_to_C_GdkVisualType(Xen_car(val)); return(Xen_list_3(xg_GdkVisualType__symbol, Xen_wrap_C_pointer(arr), make_xm_obj(arr))); } if (type == xg_char___symbol) { char** arr; arr = (char**)calloc(len + 1, sizeof(char*)); for (i = 0; i < len; i++, val = Xen_cdr(val)) arr[i] = Xen_to_C_char_(Xen_car(val)); return(Xen_list_3(xg_char___symbol, Xen_wrap_C_pointer(arr), make_xm_obj(arr))); } if (type == xg_guint16__symbol) { guint16* arr; arr = (guint16*)calloc(len + 1, sizeof(guint16)); for (i = 0; i < len; i++, val = Xen_cdr(val)) arr[i] = Xen_to_C_guint16(Xen_car(val)); return(Xen_list_3(xg_guint16__symbol, Xen_wrap_C_pointer(arr), make_xm_obj(arr))); } if (type == xg_int__symbol) { int* arr; arr = (int*)calloc(len + 1, sizeof(int)); for (i = 0; i < len; i++, val = Xen_cdr(val)) arr[i] = Xen_to_C_int(Xen_car(val)); return(Xen_list_3(xg_int__symbol, Xen_wrap_C_pointer(arr), make_xm_obj(arr))); } if (type == xg_PangoFontFace___symbol) { PangoFontFace** arr; arr = (PangoFontFace**)calloc(len + 1, sizeof(PangoFontFace*)); for (i = 0; i < len; i++, val = Xen_cdr(val)) arr[i] = Xen_to_C_PangoFontFace_(Xen_car(val)); return(Xen_list_3(xg_PangoFontFace___symbol, Xen_wrap_C_pointer(arr), make_xm_obj(arr))); } if (type == xg_PangoFontDescription___symbol) { PangoFontDescription** arr; arr = (PangoFontDescription**)calloc(len + 1, sizeof(PangoFontDescription*)); for (i = 0; i < len; i++, val = Xen_cdr(val)) arr[i] = Xen_to_C_PangoFontDescription_(Xen_car(val)); return(Xen_list_3(xg_PangoFontDescription___symbol, Xen_wrap_C_pointer(arr), make_xm_obj(arr))); } if (type == xg_PangoFontFamily___symbol) { PangoFontFamily** arr; arr = (PangoFontFamily**)calloc(len + 1, sizeof(PangoFontFamily*)); for (i = 0; i < len; i++, val = Xen_cdr(val)) arr[i] = Xen_to_C_PangoFontFamily_(Xen_car(val)); return(Xen_list_3(xg_PangoFontFamily___symbol, Xen_wrap_C_pointer(arr), make_xm_obj(arr))); } if (type == xg_PangoAttrList___symbol) { PangoAttrList** arr; arr = (PangoAttrList**)calloc(len + 1, sizeof(PangoAttrList*)); for (i = 0; i < len; i++, val = Xen_cdr(val)) arr[i] = Xen_to_C_PangoAttrList_(Xen_car(val)); return(Xen_list_3(xg_PangoAttrList___symbol, Xen_wrap_C_pointer(arr), make_xm_obj(arr))); } if (type == xg_GtkTreeModel___symbol) { GtkTreeModel** arr; arr = (GtkTreeModel**)calloc(len + 1, sizeof(GtkTreeModel*)); for (i = 0; i < len; i++, val = Xen_cdr(val)) arr[i] = Xen_to_C_GtkTreeModel_(Xen_car(val)); return(Xen_list_3(xg_GtkTreeModel___symbol, Xen_wrap_C_pointer(arr), make_xm_obj(arr))); } return(Xen_false); } static Xen gxg_make_GtkTextIter(void) { GtkTextIter* result; result = (GtkTextIter*)calloc(1, sizeof(GtkTextIter)); return(Xen_list_3(C_string_to_Xen_symbol("GtkTextIter_"), Xen_wrap_C_pointer(result), make_xm_obj(result))); } static Xen gxg_make_GtkTreeIter(void) { GtkTreeIter* result; result = (GtkTreeIter*)calloc(1, sizeof(GtkTreeIter)); return(Xen_list_3(C_string_to_Xen_symbol("GtkTreeIter_"), Xen_wrap_C_pointer(result), make_xm_obj(result))); } static Xen gxg_make_PangoRectangle(void) { PangoRectangle* result; result = (PangoRectangle*)calloc(1, sizeof(PangoRectangle)); return(Xen_list_3(C_string_to_Xen_symbol("PangoRectangle_"), Xen_wrap_C_pointer(result), make_xm_obj(result))); } static Xen gxg_make_cairo_matrix_t(void) { cairo_matrix_t* result; result = (cairo_matrix_t*)calloc(1, sizeof(cairo_matrix_t)); return(Xen_list_3(C_string_to_Xen_symbol("cairo_matrix_t_"), Xen_wrap_C_pointer(result), make_xm_obj(result))); } #if GTK_CHECK_VERSION(3, 0, 0) static Xen gxg_make_GdkRGBA(void) { GdkRGBA* result; result = (GdkRGBA*)calloc(1, sizeof(GdkRGBA)); return(Xen_list_3(C_string_to_Xen_symbol("GdkRGBA_"), Xen_wrap_C_pointer(result), make_xm_obj(result))); } #endif #if HAVE_SCHEME #define Xg_define_procedure(Name, Value, A1, A2, A3, Help, Sig) s7_define_typed_function(s7, Xg_pre #Name Xg_post, Value, A1, A2, A3, Help, Sig) #else #define Xg_define_procedure(Name, Value, A1, A2, A3, Help, Sig) Xen_define_safe_procedure(Xg_pre #Name Xg_post, Value, A1, A2, A3, Help) #endif Xen_wrap_no_args(gxg_make_GtkTextIter_w, gxg_make_GtkTextIter) Xen_wrap_no_args(gxg_make_GtkTreeIter_w, gxg_make_GtkTreeIter) Xen_wrap_no_args(gxg_make_PangoRectangle_w, gxg_make_PangoRectangle) Xen_wrap_no_args(gxg_make_cairo_matrix_t_w, gxg_make_cairo_matrix_t) #if GTK_CHECK_VERSION(3, 0, 0) Xen_wrap_no_args(gxg_make_GdkRGBA_w, gxg_make_GdkRGBA) #endif static void define_structs(void) { Xg_define_procedure(GtkTextIter, gxg_make_GtkTextIter_w, 0, 0, 0, "(GtkTextIter): a new GtkTextIter struct", NULL); Xg_define_procedure(GtkTreeIter, gxg_make_GtkTreeIter_w, 0, 0, 0, "(GtkTreeIter): a new GtkTreeIter struct", NULL); Xg_define_procedure(PangoRectangle, gxg_make_PangoRectangle_w, 0, 0, 0, "(PangoRectangle): a new PangoRectangle struct", NULL); Xg_define_procedure(cairo_matrix_t, gxg_make_cairo_matrix_t_w, 0, 0, 0, "(cairo_matrix_t): a new cairo_matrix_t struct", NULL); #if GTK_CHECK_VERSION(3, 0, 0) Xg_define_procedure(GdkRGBA, gxg_make_GdkRGBA_w, 0, 0, 0, "(GdkRGBA): a new GdkRGBA struct", NULL); #endif } Xen_wrap_1_arg(gxg_g_unichar_validate_w, gxg_g_unichar_validate) Xen_wrap_1_arg(gxg_g_unichar_isalnum_w, gxg_g_unichar_isalnum) Xen_wrap_1_arg(gxg_g_unichar_isalpha_w, gxg_g_unichar_isalpha) Xen_wrap_1_arg(gxg_g_unichar_iscntrl_w, gxg_g_unichar_iscntrl) Xen_wrap_1_arg(gxg_g_unichar_isdefined_w, gxg_g_unichar_isdefined) Xen_wrap_1_arg(gxg_g_unichar_isdigit_w, gxg_g_unichar_isdigit) Xen_wrap_1_arg(gxg_g_unichar_isgraph_w, gxg_g_unichar_isgraph) Xen_wrap_1_arg(gxg_g_unichar_islower_w, gxg_g_unichar_islower) Xen_wrap_1_arg(gxg_g_unichar_ismark_w, gxg_g_unichar_ismark) Xen_wrap_1_arg(gxg_g_unichar_isprint_w, gxg_g_unichar_isprint) Xen_wrap_1_arg(gxg_g_unichar_ispunct_w, gxg_g_unichar_ispunct) Xen_wrap_1_arg(gxg_g_unichar_isspace_w, gxg_g_unichar_isspace) Xen_wrap_1_arg(gxg_g_unichar_istitle_w, gxg_g_unichar_istitle) Xen_wrap_1_arg(gxg_g_unichar_isupper_w, gxg_g_unichar_isupper) Xen_wrap_1_arg(gxg_g_unichar_isxdigit_w, gxg_g_unichar_isxdigit) Xen_wrap_1_arg(gxg_g_unichar_iswide_w, gxg_g_unichar_iswide) Xen_wrap_1_arg(gxg_g_unichar_iswide_cjk_w, gxg_g_unichar_iswide_cjk) Xen_wrap_1_arg(gxg_g_unichar_iszerowidth_w, gxg_g_unichar_iszerowidth) Xen_wrap_1_arg(gxg_g_unichar_toupper_w, gxg_g_unichar_toupper) Xen_wrap_1_arg(gxg_g_unichar_tolower_w, gxg_g_unichar_tolower) Xen_wrap_1_arg(gxg_g_unichar_totitle_w, gxg_g_unichar_totitle) Xen_wrap_1_arg(gxg_g_unichar_digit_value_w, gxg_g_unichar_digit_value) Xen_wrap_1_arg(gxg_g_unichar_xdigit_value_w, gxg_g_unichar_xdigit_value) Xen_wrap_1_arg(gxg_g_unichar_combining_class_w, gxg_g_unichar_combining_class) Xen_wrap_2_args(gxg_g_unicode_canonical_ordering_w, gxg_g_unicode_canonical_ordering) Xen_wrap_1_arg(gxg_g_utf8_get_char_w, gxg_g_utf8_get_char) Xen_wrap_2_args(gxg_g_utf8_get_char_validated_w, gxg_g_utf8_get_char_validated) Xen_wrap_1_arg(gxg_g_utf8_prev_char_w, gxg_g_utf8_prev_char) Xen_wrap_2_args(gxg_g_utf8_find_next_char_w, gxg_g_utf8_find_next_char) Xen_wrap_2_args(gxg_g_utf8_find_prev_char_w, gxg_g_utf8_find_prev_char) Xen_wrap_2_args(gxg_g_utf8_strlen_w, gxg_g_utf8_strlen) Xen_wrap_3_args(gxg_g_utf8_strchr_w, gxg_g_utf8_strchr) Xen_wrap_3_args(gxg_g_utf8_strrchr_w, gxg_g_utf8_strrchr) Xen_wrap_2_args(gxg_g_utf8_strreverse_w, gxg_g_utf8_strreverse) Xen_wrap_3_optional_args(gxg_g_utf8_validate_w, gxg_g_utf8_validate) Xen_wrap_2_args(gxg_g_utf8_strup_w, gxg_g_utf8_strup) Xen_wrap_2_args(gxg_g_utf8_strdown_w, gxg_g_utf8_strdown) Xen_wrap_2_args(gxg_g_utf8_casefold_w, gxg_g_utf8_casefold) Xen_wrap_3_args(gxg_g_utf8_normalize_w, gxg_g_utf8_normalize) Xen_wrap_2_args(gxg_g_utf8_collate_w, gxg_g_utf8_collate) Xen_wrap_2_args(gxg_g_utf8_collate_key_w, gxg_g_utf8_collate_key) Xen_wrap_2_args(gxg_g_utf8_collate_key_for_filename_w, gxg_g_utf8_collate_key_for_filename) Xen_wrap_3_args(gxg_g_cclosure_new_w, gxg_g_cclosure_new) Xen_wrap_any_args(gxg_g_signal_newv_w, gxg_g_signal_newv) Xen_wrap_2_args(gxg_g_signal_lookup_w, gxg_g_signal_lookup) Xen_wrap_1_arg(gxg_g_signal_name_w, gxg_g_signal_name) Xen_wrap_2_args(gxg_g_signal_query_w, gxg_g_signal_query) Xen_wrap_2_args(gxg_g_signal_list_ids_w, gxg_g_signal_list_ids) Xen_wrap_5_optional_args(gxg_g_signal_parse_name_w, gxg_g_signal_parse_name) Xen_wrap_1_arg(gxg_g_signal_get_invocation_hint_w, gxg_g_signal_get_invocation_hint) Xen_wrap_3_args(gxg_g_signal_stop_emission_w, gxg_g_signal_stop_emission) Xen_wrap_2_args(gxg_g_signal_stop_emission_by_name_w, gxg_g_signal_stop_emission_by_name) Xen_wrap_5_args(gxg_g_signal_add_emission_hook_w, gxg_g_signal_add_emission_hook) Xen_wrap_2_args(gxg_g_signal_remove_emission_hook_w, gxg_g_signal_remove_emission_hook) Xen_wrap_4_args(gxg_g_signal_has_handler_pending_w, gxg_g_signal_has_handler_pending) Xen_wrap_5_args(gxg_g_signal_connect_closure_by_id_w, gxg_g_signal_connect_closure_by_id) Xen_wrap_4_args(gxg_g_signal_connect_closure_w, gxg_g_signal_connect_closure) Xen_wrap_6_args(gxg_g_signal_connect_data_w, gxg_g_signal_connect_data) Xen_wrap_2_args(gxg_g_signal_handler_block_w, gxg_g_signal_handler_block) Xen_wrap_2_args(gxg_g_signal_handler_unblock_w, gxg_g_signal_handler_unblock) Xen_wrap_2_args(gxg_g_signal_handler_disconnect_w, gxg_g_signal_handler_disconnect) Xen_wrap_2_args(gxg_g_signal_handler_is_connected_w, gxg_g_signal_handler_is_connected) Xen_wrap_7_args(gxg_g_signal_handler_find_w, gxg_g_signal_handler_find) Xen_wrap_7_args(gxg_g_signal_handlers_block_matched_w, gxg_g_signal_handlers_block_matched) Xen_wrap_7_args(gxg_g_signal_handlers_unblock_matched_w, gxg_g_signal_handlers_unblock_matched) Xen_wrap_7_args(gxg_g_signal_handlers_disconnect_matched_w, gxg_g_signal_handlers_disconnect_matched) Xen_wrap_1_arg(gxg_g_signal_handlers_destroy_w, gxg_g_signal_handlers_destroy) Xen_wrap_1_arg(gxg_g_object_ref_w, gxg_g_object_ref) Xen_wrap_1_arg(gxg_g_object_unref_w, gxg_g_object_unref) Xen_wrap_no_args(gxg_gdk_visual_get_system_w, gxg_gdk_visual_get_system) Xen_wrap_2_args(gxg_gdk_cursor_new_for_display_w, gxg_gdk_cursor_new_for_display) Xen_wrap_1_arg(gxg_gdk_cursor_get_display_w, gxg_gdk_cursor_get_display) Xen_wrap_3_args(gxg_gdk_drag_status_w, gxg_gdk_drag_status) Xen_wrap_3_args(gxg_gdk_drop_reply_w, gxg_gdk_drop_reply) Xen_wrap_3_args(gxg_gdk_drop_finish_w, gxg_gdk_drop_finish) Xen_wrap_1_arg(gxg_gdk_drag_get_selection_w, gxg_gdk_drag_get_selection) Xen_wrap_2_args(gxg_gdk_drag_begin_w, gxg_gdk_drag_begin) Xen_wrap_2_args(gxg_gdk_drag_drop_w, gxg_gdk_drag_drop) Xen_wrap_2_args(gxg_gdk_drag_abort_w, gxg_gdk_drag_abort) Xen_wrap_no_args(gxg_gdk_events_pending_w, gxg_gdk_events_pending) Xen_wrap_no_args(gxg_gdk_event_get_w, gxg_gdk_event_get) Xen_wrap_no_args(gxg_gdk_event_peek_w, gxg_gdk_event_peek) Xen_wrap_1_arg(gxg_gdk_event_put_w, gxg_gdk_event_put) Xen_wrap_1_arg(gxg_gdk_event_copy_w, gxg_gdk_event_copy) Xen_wrap_1_arg(gxg_gdk_event_free_w, gxg_gdk_event_free) Xen_wrap_1_arg(gxg_gdk_event_get_time_w, gxg_gdk_event_get_time) Xen_wrap_2_optional_args(gxg_gdk_event_get_state_w, gxg_gdk_event_get_state) Xen_wrap_3_optional_args(gxg_gdk_event_get_coords_w, gxg_gdk_event_get_coords) Xen_wrap_3_optional_args(gxg_gdk_event_get_root_coords_w, gxg_gdk_event_get_root_coords) Xen_wrap_3_args(gxg_gdk_event_handler_set_w, gxg_gdk_event_handler_set) Xen_wrap_1_arg(gxg_gdk_set_show_events_w, gxg_gdk_set_show_events) Xen_wrap_no_args(gxg_gdk_get_show_events_w, gxg_gdk_get_show_events) Xen_wrap_2_optional_args(gxg_gdk_init_w, gxg_gdk_init) Xen_wrap_2_optional_args(gxg_gdk_init_check_w, gxg_gdk_init_check) Xen_wrap_no_args(gxg_gdk_get_program_class_w, gxg_gdk_get_program_class) Xen_wrap_1_arg(gxg_gdk_set_program_class_w, gxg_gdk_set_program_class) Xen_wrap_no_args(gxg_gdk_error_trap_push_w, gxg_gdk_error_trap_push) Xen_wrap_no_args(gxg_gdk_error_trap_pop_w, gxg_gdk_error_trap_pop) Xen_wrap_no_args(gxg_gdk_get_display_arg_name_w, gxg_gdk_get_display_arg_name) Xen_wrap_no_args(gxg_gdk_notify_startup_complete_w, gxg_gdk_notify_startup_complete) Xen_wrap_no_args(gxg_gdk_screen_width_w, gxg_gdk_screen_width) Xen_wrap_no_args(gxg_gdk_screen_height_w, gxg_gdk_screen_height) Xen_wrap_no_args(gxg_gdk_screen_width_mm_w, gxg_gdk_screen_width_mm) Xen_wrap_no_args(gxg_gdk_screen_height_mm_w, gxg_gdk_screen_height_mm) Xen_wrap_no_args(gxg_gdk_flush_w, gxg_gdk_flush) Xen_wrap_no_args(gxg_gdk_beep_w, gxg_gdk_beep) Xen_wrap_1_arg(gxg_gdk_set_double_click_time_w, gxg_gdk_set_double_click_time) Xen_wrap_3_args(gxg_gdk_rectangle_intersect_w, gxg_gdk_rectangle_intersect) Xen_wrap_3_args(gxg_gdk_rectangle_union_w, gxg_gdk_rectangle_union) Xen_wrap_no_args(gxg_gdk_keymap_get_default_w, gxg_gdk_keymap_get_default) Xen_wrap_2_args(gxg_gdk_keymap_lookup_key_w, gxg_gdk_keymap_lookup_key) Xen_wrap_4_optional_args(gxg_gdk_keymap_get_entries_for_keyval_w, gxg_gdk_keymap_get_entries_for_keyval) Xen_wrap_5_optional_args(gxg_gdk_keymap_get_entries_for_keycode_w, gxg_gdk_keymap_get_entries_for_keycode) Xen_wrap_1_arg(gxg_gdk_keymap_get_direction_w, gxg_gdk_keymap_get_direction) Xen_wrap_1_arg(gxg_gdk_keyval_name_w, gxg_gdk_keyval_name) Xen_wrap_1_arg(gxg_gdk_keyval_from_name_w, gxg_gdk_keyval_from_name) Xen_wrap_3_optional_args(gxg_gdk_keyval_convert_case_w, gxg_gdk_keyval_convert_case) Xen_wrap_1_arg(gxg_gdk_keyval_to_upper_w, gxg_gdk_keyval_to_upper) Xen_wrap_1_arg(gxg_gdk_keyval_to_lower_w, gxg_gdk_keyval_to_lower) Xen_wrap_1_arg(gxg_gdk_keyval_is_upper_w, gxg_gdk_keyval_is_upper) Xen_wrap_1_arg(gxg_gdk_keyval_is_lower_w, gxg_gdk_keyval_is_lower) Xen_wrap_1_arg(gxg_gdk_keyval_to_unicode_w, gxg_gdk_keyval_to_unicode) Xen_wrap_1_arg(gxg_gdk_unicode_to_keyval_w, gxg_gdk_unicode_to_keyval) Xen_wrap_no_args(gxg_gdk_pango_context_get_w, gxg_gdk_pango_context_get) Xen_wrap_2_args(gxg_gdk_atom_intern_w, gxg_gdk_atom_intern) Xen_wrap_1_arg(gxg_gdk_atom_name_w, gxg_gdk_atom_name) Xen_wrap_any_args(gxg_gdk_property_get_w, gxg_gdk_property_get) Xen_wrap_7_args(gxg_gdk_property_change_w, gxg_gdk_property_change) Xen_wrap_2_args(gxg_gdk_property_delete_w, gxg_gdk_property_delete) Xen_wrap_1_arg(gxg_gdk_utf8_to_string_target_w, gxg_gdk_utf8_to_string_target) Xen_wrap_4_args(gxg_gdk_selection_owner_set_w, gxg_gdk_selection_owner_set) Xen_wrap_1_arg(gxg_gdk_selection_owner_get_w, gxg_gdk_selection_owner_get) Xen_wrap_4_args(gxg_gdk_selection_convert_w, gxg_gdk_selection_convert) Xen_wrap_4_optional_args(gxg_gdk_selection_property_get_w, gxg_gdk_selection_property_get) Xen_wrap_no_args(gxg_gdk_visual_get_best_depth_w, gxg_gdk_visual_get_best_depth) Xen_wrap_no_args(gxg_gdk_visual_get_best_type_w, gxg_gdk_visual_get_best_type) Xen_wrap_no_args(gxg_gdk_visual_get_best_w, gxg_gdk_visual_get_best) Xen_wrap_1_arg(gxg_gdk_visual_get_best_with_depth_w, gxg_gdk_visual_get_best_with_depth) Xen_wrap_1_arg(gxg_gdk_visual_get_best_with_type_w, gxg_gdk_visual_get_best_with_type) Xen_wrap_2_args(gxg_gdk_visual_get_best_with_both_w, gxg_gdk_visual_get_best_with_both) Xen_wrap_2_optional_args(gxg_gdk_query_depths_w, gxg_gdk_query_depths) Xen_wrap_2_optional_args(gxg_gdk_query_visual_types_w, gxg_gdk_query_visual_types) Xen_wrap_no_args(gxg_gdk_list_visuals_w, gxg_gdk_list_visuals) Xen_wrap_3_args(gxg_gdk_window_new_w, gxg_gdk_window_new) Xen_wrap_1_arg(gxg_gdk_window_destroy_w, gxg_gdk_window_destroy) Xen_wrap_1_arg(gxg_gdk_window_get_window_type_w, gxg_gdk_window_get_window_type) Xen_wrap_1_arg(gxg_gdk_window_show_w, gxg_gdk_window_show) Xen_wrap_1_arg(gxg_gdk_window_hide_w, gxg_gdk_window_hide) Xen_wrap_1_arg(gxg_gdk_window_withdraw_w, gxg_gdk_window_withdraw) Xen_wrap_1_arg(gxg_gdk_window_show_unraised_w, gxg_gdk_window_show_unraised) Xen_wrap_3_args(gxg_gdk_window_move_w, gxg_gdk_window_move) Xen_wrap_3_args(gxg_gdk_window_resize_w, gxg_gdk_window_resize) Xen_wrap_5_args(gxg_gdk_window_move_resize_w, gxg_gdk_window_move_resize) Xen_wrap_4_args(gxg_gdk_window_reparent_w, gxg_gdk_window_reparent) Xen_wrap_1_arg(gxg_gdk_window_raise_w, gxg_gdk_window_raise) Xen_wrap_1_arg(gxg_gdk_window_lower_w, gxg_gdk_window_lower) Xen_wrap_2_args(gxg_gdk_window_focus_w, gxg_gdk_window_focus) Xen_wrap_2_args(gxg_gdk_window_set_user_data_w, gxg_gdk_window_set_user_data) Xen_wrap_2_args(gxg_gdk_window_set_override_redirect_w, gxg_gdk_window_set_override_redirect) Xen_wrap_3_optional_args(gxg_gdk_window_add_filter_w, gxg_gdk_window_add_filter) Xen_wrap_3_optional_args(gxg_gdk_window_remove_filter_w, gxg_gdk_window_remove_filter) Xen_wrap_3_args(gxg_gdk_window_scroll_w, gxg_gdk_window_scroll) Xen_wrap_1_arg(gxg_gdk_window_set_child_shapes_w, gxg_gdk_window_set_child_shapes) Xen_wrap_1_arg(gxg_gdk_window_merge_child_shapes_w, gxg_gdk_window_merge_child_shapes) Xen_wrap_1_arg(gxg_gdk_window_is_visible_w, gxg_gdk_window_is_visible) Xen_wrap_1_arg(gxg_gdk_window_is_viewable_w, gxg_gdk_window_is_viewable) Xen_wrap_1_arg(gxg_gdk_window_get_state_w, gxg_gdk_window_get_state) Xen_wrap_3_optional_args(gxg_gdk_window_get_root_origin_w, gxg_gdk_window_get_root_origin) Xen_wrap_2_args(gxg_gdk_window_get_frame_extents_w, gxg_gdk_window_get_frame_extents) Xen_wrap_1_arg(gxg_gdk_window_get_parent_w, gxg_gdk_window_get_parent) Xen_wrap_1_arg(gxg_gdk_window_get_toplevel_w, gxg_gdk_window_get_toplevel) Xen_wrap_1_arg(gxg_gdk_window_get_children_w, gxg_gdk_window_get_children) Xen_wrap_1_arg(gxg_gdk_window_peek_children_w, gxg_gdk_window_peek_children) Xen_wrap_1_arg(gxg_gdk_window_get_events_w, gxg_gdk_window_get_events) Xen_wrap_2_args(gxg_gdk_window_set_events_w, gxg_gdk_window_set_events) Xen_wrap_2_args(gxg_gdk_window_set_icon_list_w, gxg_gdk_window_set_icon_list) Xen_wrap_2_args(gxg_gdk_window_set_icon_name_w, gxg_gdk_window_set_icon_name) Xen_wrap_2_args(gxg_gdk_window_set_group_w, gxg_gdk_window_set_group) Xen_wrap_2_args(gxg_gdk_window_set_decorations_w, gxg_gdk_window_set_decorations) Xen_wrap_2_optional_args(gxg_gdk_window_get_decorations_w, gxg_gdk_window_get_decorations) Xen_wrap_2_args(gxg_gdk_window_set_functions_w, gxg_gdk_window_set_functions) Xen_wrap_1_arg(gxg_gdk_window_iconify_w, gxg_gdk_window_iconify) Xen_wrap_1_arg(gxg_gdk_window_deiconify_w, gxg_gdk_window_deiconify) Xen_wrap_1_arg(gxg_gdk_window_stick_w, gxg_gdk_window_stick) Xen_wrap_1_arg(gxg_gdk_window_unstick_w, gxg_gdk_window_unstick) Xen_wrap_1_arg(gxg_gdk_window_maximize_w, gxg_gdk_window_maximize) Xen_wrap_1_arg(gxg_gdk_window_unmaximize_w, gxg_gdk_window_unmaximize) Xen_wrap_1_arg(gxg_gdk_window_register_dnd_w, gxg_gdk_window_register_dnd) Xen_wrap_6_args(gxg_gdk_window_begin_resize_drag_w, gxg_gdk_window_begin_resize_drag) Xen_wrap_5_args(gxg_gdk_window_begin_move_drag_w, gxg_gdk_window_begin_move_drag) Xen_wrap_3_args(gxg_gdk_window_invalidate_rect_w, gxg_gdk_window_invalidate_rect) Xen_wrap_1_arg(gxg_gdk_window_freeze_updates_w, gxg_gdk_window_freeze_updates) Xen_wrap_1_arg(gxg_gdk_window_thaw_updates_w, gxg_gdk_window_thaw_updates) Xen_wrap_no_args(gxg_gdk_window_process_all_updates_w, gxg_gdk_window_process_all_updates) Xen_wrap_2_args(gxg_gdk_window_process_updates_w, gxg_gdk_window_process_updates) Xen_wrap_1_arg(gxg_gdk_window_set_debug_updates_w, gxg_gdk_window_set_debug_updates) Xen_wrap_6_optional_args(gxg_gdk_window_constrain_size_w, gxg_gdk_window_constrain_size) Xen_wrap_2_args(gxg_gdk_window_set_type_hint_w, gxg_gdk_window_set_type_hint) Xen_wrap_2_args(gxg_gdk_window_set_modal_hint_w, gxg_gdk_window_set_modal_hint) Xen_wrap_3_args(gxg_gdk_window_set_geometry_hints_w, gxg_gdk_window_set_geometry_hints) Xen_wrap_2_args(gxg_gdk_window_begin_paint_rect_w, gxg_gdk_window_begin_paint_rect) Xen_wrap_1_arg(gxg_gdk_window_end_paint_w, gxg_gdk_window_end_paint) Xen_wrap_2_args(gxg_gdk_window_set_title_w, gxg_gdk_window_set_title) Xen_wrap_2_args(gxg_gdk_window_set_role_w, gxg_gdk_window_set_role) Xen_wrap_2_args(gxg_gdk_window_set_transient_for_w, gxg_gdk_window_set_transient_for) Xen_wrap_2_args(gxg_gdk_window_set_cursor_w, gxg_gdk_window_set_cursor) Xen_wrap_2_optional_args(gxg_gdk_window_get_user_data_w, gxg_gdk_window_get_user_data) Xen_wrap_3_optional_args(gxg_gdk_window_get_position_w, gxg_gdk_window_get_position) Xen_wrap_3_optional_args(gxg_gdk_window_get_origin_w, gxg_gdk_window_get_origin) Xen_wrap_no_args(gxg_gdk_get_default_root_window_w, gxg_gdk_get_default_root_window) Xen_wrap_no_args(gxg_gdk_pixbuf_error_quark_w, gxg_gdk_pixbuf_error_quark) Xen_wrap_1_arg(gxg_gdk_pixbuf_get_colorspace_w, gxg_gdk_pixbuf_get_colorspace) Xen_wrap_1_arg(gxg_gdk_pixbuf_get_n_channels_w, gxg_gdk_pixbuf_get_n_channels) Xen_wrap_1_arg(gxg_gdk_pixbuf_get_has_alpha_w, gxg_gdk_pixbuf_get_has_alpha) Xen_wrap_1_arg(gxg_gdk_pixbuf_get_bits_per_sample_w, gxg_gdk_pixbuf_get_bits_per_sample) Xen_wrap_1_arg(gxg_gdk_pixbuf_get_pixels_w, gxg_gdk_pixbuf_get_pixels) Xen_wrap_1_arg(gxg_gdk_pixbuf_get_width_w, gxg_gdk_pixbuf_get_width) Xen_wrap_1_arg(gxg_gdk_pixbuf_get_height_w, gxg_gdk_pixbuf_get_height) Xen_wrap_1_arg(gxg_gdk_pixbuf_get_rowstride_w, gxg_gdk_pixbuf_get_rowstride) Xen_wrap_5_args(gxg_gdk_pixbuf_new_w, gxg_gdk_pixbuf_new) Xen_wrap_1_arg(gxg_gdk_pixbuf_copy_w, gxg_gdk_pixbuf_copy) Xen_wrap_5_args(gxg_gdk_pixbuf_new_subpixbuf_w, gxg_gdk_pixbuf_new_subpixbuf) Xen_wrap_2_optional_args(gxg_gdk_pixbuf_new_from_file_w, gxg_gdk_pixbuf_new_from_file) Xen_wrap_any_args(gxg_gdk_pixbuf_new_from_data_w, gxg_gdk_pixbuf_new_from_data) Xen_wrap_1_arg(gxg_gdk_pixbuf_new_from_xpm_data_w, gxg_gdk_pixbuf_new_from_xpm_data) Xen_wrap_2_args(gxg_gdk_pixbuf_fill_w, gxg_gdk_pixbuf_fill) Xen_wrap_6_optional_args(gxg_gdk_pixbuf_savev_w, gxg_gdk_pixbuf_savev) Xen_wrap_5_args(gxg_gdk_pixbuf_add_alpha_w, gxg_gdk_pixbuf_add_alpha) Xen_wrap_any_args(gxg_gdk_pixbuf_copy_area_w, gxg_gdk_pixbuf_copy_area) Xen_wrap_4_args(gxg_gdk_pixbuf_saturate_and_pixelate_w, gxg_gdk_pixbuf_saturate_and_pixelate) Xen_wrap_any_args(gxg_gdk_pixbuf_scale_w, gxg_gdk_pixbuf_scale) Xen_wrap_any_args(gxg_gdk_pixbuf_composite_w, gxg_gdk_pixbuf_composite) Xen_wrap_any_args(gxg_gdk_pixbuf_composite_color_w, gxg_gdk_pixbuf_composite_color) Xen_wrap_4_args(gxg_gdk_pixbuf_scale_simple_w, gxg_gdk_pixbuf_scale_simple) Xen_wrap_any_args(gxg_gdk_pixbuf_composite_color_simple_w, gxg_gdk_pixbuf_composite_color_simple) Xen_wrap_2_optional_args(gxg_gdk_pixbuf_animation_new_from_file_w, gxg_gdk_pixbuf_animation_new_from_file) Xen_wrap_1_arg(gxg_gdk_pixbuf_animation_get_width_w, gxg_gdk_pixbuf_animation_get_width) Xen_wrap_1_arg(gxg_gdk_pixbuf_animation_get_height_w, gxg_gdk_pixbuf_animation_get_height) Xen_wrap_1_arg(gxg_gdk_pixbuf_animation_is_static_image_w, gxg_gdk_pixbuf_animation_is_static_image) Xen_wrap_1_arg(gxg_gdk_pixbuf_animation_get_static_image_w, gxg_gdk_pixbuf_animation_get_static_image) Xen_wrap_2_args(gxg_gdk_pixbuf_animation_get_iter_w, gxg_gdk_pixbuf_animation_get_iter) Xen_wrap_1_arg(gxg_gdk_pixbuf_animation_iter_get_delay_time_w, gxg_gdk_pixbuf_animation_iter_get_delay_time) Xen_wrap_1_arg(gxg_gdk_pixbuf_animation_iter_get_pixbuf_w, gxg_gdk_pixbuf_animation_iter_get_pixbuf) Xen_wrap_1_arg(gxg_gdk_pixbuf_animation_iter_on_currently_loading_frame_w, gxg_gdk_pixbuf_animation_iter_on_currently_loading_frame) Xen_wrap_2_args(gxg_gdk_pixbuf_animation_iter_advance_w, gxg_gdk_pixbuf_animation_iter_advance) Xen_wrap_2_args(gxg_gdk_pixbuf_get_option_w, gxg_gdk_pixbuf_get_option) Xen_wrap_no_args(gxg_gtk_accel_group_new_w, gxg_gtk_accel_group_new) Xen_wrap_1_arg(gxg_gtk_accel_group_lock_w, gxg_gtk_accel_group_lock) Xen_wrap_1_arg(gxg_gtk_accel_group_unlock_w, gxg_gtk_accel_group_unlock) Xen_wrap_5_args(gxg_gtk_accel_group_connect_w, gxg_gtk_accel_group_connect) Xen_wrap_3_args(gxg_gtk_accel_group_connect_by_path_w, gxg_gtk_accel_group_connect_by_path) Xen_wrap_2_args(gxg_gtk_accel_group_disconnect_w, gxg_gtk_accel_group_disconnect) Xen_wrap_3_args(gxg_gtk_accel_group_disconnect_key_w, gxg_gtk_accel_group_disconnect_key) Xen_wrap_3_args(gxg_gtk_accel_groups_activate_w, gxg_gtk_accel_groups_activate) Xen_wrap_1_arg(gxg_gtk_accel_groups_from_object_w, gxg_gtk_accel_groups_from_object) Xen_wrap_3_optional_args(gxg_gtk_accel_group_find_w, gxg_gtk_accel_group_find) Xen_wrap_1_arg(gxg_gtk_accel_group_from_accel_closure_w, gxg_gtk_accel_group_from_accel_closure) Xen_wrap_2_args(gxg_gtk_accelerator_valid_w, gxg_gtk_accelerator_valid) Xen_wrap_3_optional_args(gxg_gtk_accelerator_parse_w, gxg_gtk_accelerator_parse) Xen_wrap_2_args(gxg_gtk_accelerator_name_w, gxg_gtk_accelerator_name) Xen_wrap_1_arg(gxg_gtk_accelerator_set_default_mod_mask_w, gxg_gtk_accelerator_set_default_mod_mask) Xen_wrap_4_optional_args(gxg_gtk_accel_group_query_w, gxg_gtk_accel_group_query) Xen_wrap_5_args(gxg_gtk_accel_group_activate_w, gxg_gtk_accel_group_activate) Xen_wrap_1_arg(gxg_gtk_accel_label_new_w, gxg_gtk_accel_label_new) Xen_wrap_1_arg(gxg_gtk_accel_label_get_accel_widget_w, gxg_gtk_accel_label_get_accel_widget) Xen_wrap_1_arg(gxg_gtk_accel_label_get_accel_width_w, gxg_gtk_accel_label_get_accel_width) Xen_wrap_2_args(gxg_gtk_accel_label_set_accel_widget_w, gxg_gtk_accel_label_set_accel_widget) Xen_wrap_2_args(gxg_gtk_accel_label_set_accel_closure_w, gxg_gtk_accel_label_set_accel_closure) Xen_wrap_1_arg(gxg_gtk_accel_label_refetch_w, gxg_gtk_accel_label_refetch) Xen_wrap_3_args(gxg_gtk_accel_map_add_entry_w, gxg_gtk_accel_map_add_entry) Xen_wrap_2_args(gxg_gtk_accel_map_lookup_entry_w, gxg_gtk_accel_map_lookup_entry) Xen_wrap_4_args(gxg_gtk_accel_map_change_entry_w, gxg_gtk_accel_map_change_entry) Xen_wrap_1_arg(gxg_gtk_accel_map_load_w, gxg_gtk_accel_map_load) Xen_wrap_1_arg(gxg_gtk_accel_map_save_w, gxg_gtk_accel_map_save) Xen_wrap_2_args(gxg_gtk_accel_map_foreach_w, gxg_gtk_accel_map_foreach) Xen_wrap_1_arg(gxg_gtk_accel_map_load_fd_w, gxg_gtk_accel_map_load_fd) Xen_wrap_1_arg(gxg_gtk_accel_map_save_fd_w, gxg_gtk_accel_map_save_fd) Xen_wrap_1_arg(gxg_gtk_accel_map_add_filter_w, gxg_gtk_accel_map_add_filter) Xen_wrap_2_args(gxg_gtk_accel_map_foreach_unfiltered_w, gxg_gtk_accel_map_foreach_unfiltered) Xen_wrap_3_args(gxg_gtk_adjustment_clamp_page_w, gxg_gtk_adjustment_clamp_page) Xen_wrap_1_arg(gxg_gtk_adjustment_get_value_w, gxg_gtk_adjustment_get_value) Xen_wrap_2_args(gxg_gtk_adjustment_set_value_w, gxg_gtk_adjustment_set_value) Xen_wrap_5_args(gxg_gtk_aspect_frame_new_w, gxg_gtk_aspect_frame_new) Xen_wrap_5_args(gxg_gtk_aspect_frame_set_w, gxg_gtk_aspect_frame_set) Xen_wrap_1_arg(gxg_gtk_button_box_get_layout_w, gxg_gtk_button_box_get_layout) Xen_wrap_2_args(gxg_gtk_button_box_set_layout_w, gxg_gtk_button_box_set_layout) Xen_wrap_3_args(gxg_gtk_button_box_set_child_secondary_w, gxg_gtk_button_box_set_child_secondary) Xen_wrap_1_arg(gxg_gtk_binding_set_new_w, gxg_gtk_binding_set_new) Xen_wrap_1_arg(gxg_gtk_binding_set_by_class_w, gxg_gtk_binding_set_by_class) Xen_wrap_1_arg(gxg_gtk_binding_set_find_w, gxg_gtk_binding_set_find) Xen_wrap_3_args(gxg_gtk_binding_entry_remove_w, gxg_gtk_binding_entry_remove) Xen_wrap_1_arg(gxg_gtk_bin_get_child_w, gxg_gtk_bin_get_child) Xen_wrap_5_args(gxg_gtk_box_pack_start_w, gxg_gtk_box_pack_start) Xen_wrap_5_args(gxg_gtk_box_pack_end_w, gxg_gtk_box_pack_end) Xen_wrap_2_args(gxg_gtk_box_set_homogeneous_w, gxg_gtk_box_set_homogeneous) Xen_wrap_1_arg(gxg_gtk_box_get_homogeneous_w, gxg_gtk_box_get_homogeneous) Xen_wrap_2_args(gxg_gtk_box_set_spacing_w, gxg_gtk_box_set_spacing) Xen_wrap_1_arg(gxg_gtk_box_get_spacing_w, gxg_gtk_box_get_spacing) Xen_wrap_3_args(gxg_gtk_box_reorder_child_w, gxg_gtk_box_reorder_child) Xen_wrap_6_optional_args(gxg_gtk_box_query_child_packing_w, gxg_gtk_box_query_child_packing) Xen_wrap_6_args(gxg_gtk_box_set_child_packing_w, gxg_gtk_box_set_child_packing) Xen_wrap_no_args(gxg_gtk_button_new_w, gxg_gtk_button_new) Xen_wrap_1_arg(gxg_gtk_button_new_with_label_w, gxg_gtk_button_new_with_label) Xen_wrap_1_arg(gxg_gtk_button_new_with_mnemonic_w, gxg_gtk_button_new_with_mnemonic) Xen_wrap_1_arg(gxg_gtk_button_clicked_w, gxg_gtk_button_clicked) Xen_wrap_2_args(gxg_gtk_button_set_relief_w, gxg_gtk_button_set_relief) Xen_wrap_1_arg(gxg_gtk_button_get_relief_w, gxg_gtk_button_get_relief) Xen_wrap_2_args(gxg_gtk_button_set_label_w, gxg_gtk_button_set_label) Xen_wrap_1_arg(gxg_gtk_button_get_label_w, gxg_gtk_button_get_label) Xen_wrap_2_args(gxg_gtk_button_set_use_underline_w, gxg_gtk_button_set_use_underline) Xen_wrap_1_arg(gxg_gtk_button_get_use_underline_w, gxg_gtk_button_get_use_underline) Xen_wrap_no_args(gxg_gtk_calendar_new_w, gxg_gtk_calendar_new) Xen_wrap_2_args(gxg_gtk_calendar_select_day_w, gxg_gtk_calendar_select_day) Xen_wrap_1_arg(gxg_gtk_calendar_clear_marks_w, gxg_gtk_calendar_clear_marks) Xen_wrap_4_optional_args(gxg_gtk_calendar_get_date_w, gxg_gtk_calendar_get_date) Xen_wrap_2_args(gxg_gtk_cell_editable_start_editing_w, gxg_gtk_cell_editable_start_editing) Xen_wrap_1_arg(gxg_gtk_cell_editable_editing_done_w, gxg_gtk_cell_editable_editing_done) Xen_wrap_1_arg(gxg_gtk_cell_editable_remove_widget_w, gxg_gtk_cell_editable_remove_widget) Xen_wrap_7_args(gxg_gtk_cell_renderer_activate_w, gxg_gtk_cell_renderer_activate) Xen_wrap_7_args(gxg_gtk_cell_renderer_start_editing_w, gxg_gtk_cell_renderer_start_editing) Xen_wrap_3_args(gxg_gtk_cell_renderer_set_fixed_size_w, gxg_gtk_cell_renderer_set_fixed_size) Xen_wrap_3_optional_args(gxg_gtk_cell_renderer_get_fixed_size_w, gxg_gtk_cell_renderer_get_fixed_size) Xen_wrap_no_args(gxg_gtk_cell_renderer_pixbuf_new_w, gxg_gtk_cell_renderer_pixbuf_new) Xen_wrap_no_args(gxg_gtk_cell_renderer_text_new_w, gxg_gtk_cell_renderer_text_new) Xen_wrap_2_args(gxg_gtk_cell_renderer_text_set_fixed_height_from_font_w, gxg_gtk_cell_renderer_text_set_fixed_height_from_font) Xen_wrap_no_args(gxg_gtk_cell_renderer_toggle_new_w, gxg_gtk_cell_renderer_toggle_new) Xen_wrap_1_arg(gxg_gtk_cell_renderer_toggle_get_radio_w, gxg_gtk_cell_renderer_toggle_get_radio) Xen_wrap_2_args(gxg_gtk_cell_renderer_toggle_set_radio_w, gxg_gtk_cell_renderer_toggle_set_radio) Xen_wrap_1_arg(gxg_gtk_cell_renderer_toggle_get_active_w, gxg_gtk_cell_renderer_toggle_get_active) Xen_wrap_2_args(gxg_gtk_cell_renderer_toggle_set_active_w, gxg_gtk_cell_renderer_toggle_set_active) Xen_wrap_no_args(gxg_gtk_check_button_new_w, gxg_gtk_check_button_new) Xen_wrap_1_arg(gxg_gtk_check_button_new_with_label_w, gxg_gtk_check_button_new_with_label) Xen_wrap_1_arg(gxg_gtk_check_button_new_with_mnemonic_w, gxg_gtk_check_button_new_with_mnemonic) Xen_wrap_no_args(gxg_gtk_check_menu_item_new_w, gxg_gtk_check_menu_item_new) Xen_wrap_1_arg(gxg_gtk_check_menu_item_new_with_label_w, gxg_gtk_check_menu_item_new_with_label) Xen_wrap_1_arg(gxg_gtk_check_menu_item_new_with_mnemonic_w, gxg_gtk_check_menu_item_new_with_mnemonic) Xen_wrap_2_args(gxg_gtk_check_menu_item_set_active_w, gxg_gtk_check_menu_item_set_active) Xen_wrap_1_arg(gxg_gtk_check_menu_item_get_active_w, gxg_gtk_check_menu_item_get_active) Xen_wrap_1_arg(gxg_gtk_check_menu_item_toggled_w, gxg_gtk_check_menu_item_toggled) Xen_wrap_2_args(gxg_gtk_check_menu_item_set_inconsistent_w, gxg_gtk_check_menu_item_set_inconsistent) Xen_wrap_1_arg(gxg_gtk_check_menu_item_get_inconsistent_w, gxg_gtk_check_menu_item_get_inconsistent) Xen_wrap_1_arg(gxg_gtk_clipboard_get_w, gxg_gtk_clipboard_get) Xen_wrap_6_optional_args(gxg_gtk_clipboard_set_with_data_w, gxg_gtk_clipboard_set_with_data) Xen_wrap_1_arg(gxg_gtk_clipboard_get_owner_w, gxg_gtk_clipboard_get_owner) Xen_wrap_1_arg(gxg_gtk_clipboard_clear_w, gxg_gtk_clipboard_clear) Xen_wrap_3_args(gxg_gtk_clipboard_set_text_w, gxg_gtk_clipboard_set_text) Xen_wrap_4_optional_args(gxg_gtk_clipboard_request_contents_w, gxg_gtk_clipboard_request_contents) Xen_wrap_3_optional_args(gxg_gtk_clipboard_request_text_w, gxg_gtk_clipboard_request_text) Xen_wrap_2_args(gxg_gtk_clipboard_wait_for_contents_w, gxg_gtk_clipboard_wait_for_contents) Xen_wrap_1_arg(gxg_gtk_clipboard_wait_for_text_w, gxg_gtk_clipboard_wait_for_text) Xen_wrap_1_arg(gxg_gtk_clipboard_wait_is_text_available_w, gxg_gtk_clipboard_wait_is_text_available) Xen_wrap_2_args(gxg_gtk_container_set_border_width_w, gxg_gtk_container_set_border_width) Xen_wrap_1_arg(gxg_gtk_container_get_border_width_w, gxg_gtk_container_get_border_width) Xen_wrap_2_args(gxg_gtk_container_add_w, gxg_gtk_container_add) Xen_wrap_2_args(gxg_gtk_container_remove_w, gxg_gtk_container_remove) Xen_wrap_1_arg(gxg_gtk_container_check_resize_w, gxg_gtk_container_check_resize) Xen_wrap_3_optional_args(gxg_gtk_container_foreach_w, gxg_gtk_container_foreach) Xen_wrap_1_arg(gxg_gtk_container_get_children_w, gxg_gtk_container_get_children) Xen_wrap_no_args(gxg_gtk_dialog_new_w, gxg_gtk_dialog_new) Xen_wrap_3_args(gxg_gtk_dialog_add_action_widget_w, gxg_gtk_dialog_add_action_widget) Xen_wrap_3_args(gxg_gtk_dialog_add_button_w, gxg_gtk_dialog_add_button) Xen_wrap_2_args(gxg_gtk_dialog_add_buttons_w, gxg_gtk_dialog_add_buttons) Xen_wrap_3_args(gxg_gtk_dialog_set_response_sensitive_w, gxg_gtk_dialog_set_response_sensitive) Xen_wrap_2_args(gxg_gtk_dialog_set_default_response_w, gxg_gtk_dialog_set_default_response) Xen_wrap_2_args(gxg_gtk_dialog_response_w, gxg_gtk_dialog_response) Xen_wrap_1_arg(gxg_gtk_dialog_run_w, gxg_gtk_dialog_run) Xen_wrap_4_args(gxg_gtk_drag_get_data_w, gxg_gtk_drag_get_data) Xen_wrap_4_args(gxg_gtk_drag_finish_w, gxg_gtk_drag_finish) Xen_wrap_1_arg(gxg_gtk_drag_get_source_widget_w, gxg_gtk_drag_get_source_widget) Xen_wrap_1_arg(gxg_gtk_drag_highlight_w, gxg_gtk_drag_highlight) Xen_wrap_1_arg(gxg_gtk_drag_unhighlight_w, gxg_gtk_drag_unhighlight) Xen_wrap_5_args(gxg_gtk_drag_dest_set_w, gxg_gtk_drag_dest_set) Xen_wrap_1_arg(gxg_gtk_drag_dest_unset_w, gxg_gtk_drag_dest_unset) Xen_wrap_3_args(gxg_gtk_drag_dest_find_target_w, gxg_gtk_drag_dest_find_target) Xen_wrap_1_arg(gxg_gtk_drag_dest_get_target_list_w, gxg_gtk_drag_dest_get_target_list) Xen_wrap_2_args(gxg_gtk_drag_dest_set_target_list_w, gxg_gtk_drag_dest_set_target_list) Xen_wrap_5_args(gxg_gtk_drag_source_set_w, gxg_gtk_drag_source_set) Xen_wrap_1_arg(gxg_gtk_drag_source_unset_w, gxg_gtk_drag_source_unset) Xen_wrap_2_args(gxg_gtk_drag_source_set_icon_pixbuf_w, gxg_gtk_drag_source_set_icon_pixbuf) Xen_wrap_4_args(gxg_gtk_drag_set_icon_widget_w, gxg_gtk_drag_set_icon_widget) Xen_wrap_4_args(gxg_gtk_drag_set_icon_pixbuf_w, gxg_gtk_drag_set_icon_pixbuf) Xen_wrap_1_arg(gxg_gtk_drag_set_icon_default_w, gxg_gtk_drag_set_icon_default) Xen_wrap_5_args(gxg_gtk_drag_check_threshold_w, gxg_gtk_drag_check_threshold) Xen_wrap_no_args(gxg_gtk_drawing_area_new_w, gxg_gtk_drawing_area_new) Xen_wrap_3_args(gxg_gtk_editable_select_region_w, gxg_gtk_editable_select_region) Xen_wrap_3_optional_args(gxg_gtk_editable_get_selection_bounds_w, gxg_gtk_editable_get_selection_bounds) Xen_wrap_4_optional_args(gxg_gtk_editable_insert_text_w, gxg_gtk_editable_insert_text) Xen_wrap_3_args(gxg_gtk_editable_delete_text_w, gxg_gtk_editable_delete_text) Xen_wrap_3_args(gxg_gtk_editable_get_chars_w, gxg_gtk_editable_get_chars) Xen_wrap_1_arg(gxg_gtk_editable_cut_clipboard_w, gxg_gtk_editable_cut_clipboard) Xen_wrap_1_arg(gxg_gtk_editable_copy_clipboard_w, gxg_gtk_editable_copy_clipboard) Xen_wrap_1_arg(gxg_gtk_editable_paste_clipboard_w, gxg_gtk_editable_paste_clipboard) Xen_wrap_1_arg(gxg_gtk_editable_delete_selection_w, gxg_gtk_editable_delete_selection) Xen_wrap_2_args(gxg_gtk_editable_set_position_w, gxg_gtk_editable_set_position) Xen_wrap_1_arg(gxg_gtk_editable_get_position_w, gxg_gtk_editable_get_position) Xen_wrap_2_args(gxg_gtk_editable_set_editable_w, gxg_gtk_editable_set_editable) Xen_wrap_1_arg(gxg_gtk_editable_get_editable_w, gxg_gtk_editable_get_editable) Xen_wrap_no_args(gxg_gtk_entry_new_w, gxg_gtk_entry_new) Xen_wrap_2_args(gxg_gtk_entry_set_visibility_w, gxg_gtk_entry_set_visibility) Xen_wrap_1_arg(gxg_gtk_entry_get_visibility_w, gxg_gtk_entry_get_visibility) Xen_wrap_2_args(gxg_gtk_entry_set_invisible_char_w, gxg_gtk_entry_set_invisible_char) Xen_wrap_1_arg(gxg_gtk_entry_get_invisible_char_w, gxg_gtk_entry_get_invisible_char) Xen_wrap_2_args(gxg_gtk_entry_set_has_frame_w, gxg_gtk_entry_set_has_frame) Xen_wrap_1_arg(gxg_gtk_entry_get_has_frame_w, gxg_gtk_entry_get_has_frame) Xen_wrap_2_args(gxg_gtk_entry_set_max_length_w, gxg_gtk_entry_set_max_length) Xen_wrap_1_arg(gxg_gtk_entry_get_max_length_w, gxg_gtk_entry_get_max_length) Xen_wrap_2_args(gxg_gtk_entry_set_activates_default_w, gxg_gtk_entry_set_activates_default) Xen_wrap_1_arg(gxg_gtk_entry_get_activates_default_w, gxg_gtk_entry_get_activates_default) Xen_wrap_2_args(gxg_gtk_entry_set_width_chars_w, gxg_gtk_entry_set_width_chars) Xen_wrap_1_arg(gxg_gtk_entry_get_width_chars_w, gxg_gtk_entry_get_width_chars) Xen_wrap_2_args(gxg_gtk_entry_set_text_w, gxg_gtk_entry_set_text) Xen_wrap_1_arg(gxg_gtk_entry_get_text_w, gxg_gtk_entry_get_text) Xen_wrap_1_arg(gxg_gtk_entry_get_layout_w, gxg_gtk_entry_get_layout) Xen_wrap_3_optional_args(gxg_gtk_entry_get_layout_offsets_w, gxg_gtk_entry_get_layout_offsets) Xen_wrap_no_args(gxg_gtk_event_box_new_w, gxg_gtk_event_box_new) Xen_wrap_no_args(gxg_gtk_fixed_new_w, gxg_gtk_fixed_new) Xen_wrap_4_args(gxg_gtk_fixed_put_w, gxg_gtk_fixed_put) Xen_wrap_4_args(gxg_gtk_fixed_move_w, gxg_gtk_fixed_move) Xen_wrap_1_arg(gxg_gtk_frame_new_w, gxg_gtk_frame_new) Xen_wrap_2_args(gxg_gtk_frame_set_label_w, gxg_gtk_frame_set_label) Xen_wrap_1_arg(gxg_gtk_frame_get_label_w, gxg_gtk_frame_get_label) Xen_wrap_2_args(gxg_gtk_frame_set_label_widget_w, gxg_gtk_frame_set_label_widget) Xen_wrap_1_arg(gxg_gtk_frame_get_label_widget_w, gxg_gtk_frame_get_label_widget) Xen_wrap_3_args(gxg_gtk_frame_set_label_align_w, gxg_gtk_frame_set_label_align) Xen_wrap_3_optional_args(gxg_gtk_frame_get_label_align_w, gxg_gtk_frame_get_label_align) Xen_wrap_2_args(gxg_gtk_frame_set_shadow_type_w, gxg_gtk_frame_set_shadow_type) Xen_wrap_1_arg(gxg_gtk_frame_get_shadow_type_w, gxg_gtk_frame_get_shadow_type) Xen_wrap_no_args(gxg_gtk_image_new_w, gxg_gtk_image_new) Xen_wrap_1_arg(gxg_gtk_image_new_from_file_w, gxg_gtk_image_new_from_file) Xen_wrap_1_arg(gxg_gtk_image_new_from_pixbuf_w, gxg_gtk_image_new_from_pixbuf) Xen_wrap_1_arg(gxg_gtk_image_new_from_animation_w, gxg_gtk_image_new_from_animation) Xen_wrap_2_args(gxg_gtk_image_set_from_file_w, gxg_gtk_image_set_from_file) Xen_wrap_2_args(gxg_gtk_image_set_from_pixbuf_w, gxg_gtk_image_set_from_pixbuf) Xen_wrap_2_args(gxg_gtk_image_set_from_animation_w, gxg_gtk_image_set_from_animation) Xen_wrap_1_arg(gxg_gtk_image_get_storage_type_w, gxg_gtk_image_get_storage_type) Xen_wrap_1_arg(gxg_gtk_image_get_pixbuf_w, gxg_gtk_image_get_pixbuf) Xen_wrap_1_arg(gxg_gtk_image_get_animation_w, gxg_gtk_image_get_animation) Xen_wrap_2_args(gxg_gtk_im_context_set_client_window_w, gxg_gtk_im_context_set_client_window) Xen_wrap_4_optional_args(gxg_gtk_im_context_get_preedit_string_w, gxg_gtk_im_context_get_preedit_string) Xen_wrap_2_args(gxg_gtk_im_context_filter_keypress_w, gxg_gtk_im_context_filter_keypress) Xen_wrap_1_arg(gxg_gtk_im_context_focus_in_w, gxg_gtk_im_context_focus_in) Xen_wrap_1_arg(gxg_gtk_im_context_focus_out_w, gxg_gtk_im_context_focus_out) Xen_wrap_1_arg(gxg_gtk_im_context_reset_w, gxg_gtk_im_context_reset) Xen_wrap_2_args(gxg_gtk_im_context_set_cursor_location_w, gxg_gtk_im_context_set_cursor_location) Xen_wrap_2_args(gxg_gtk_im_context_set_use_preedit_w, gxg_gtk_im_context_set_use_preedit) Xen_wrap_4_args(gxg_gtk_im_context_set_surrounding_w, gxg_gtk_im_context_set_surrounding) Xen_wrap_3_optional_args(gxg_gtk_im_context_get_surrounding_w, gxg_gtk_im_context_get_surrounding) Xen_wrap_3_args(gxg_gtk_im_context_delete_surrounding_w, gxg_gtk_im_context_delete_surrounding) Xen_wrap_no_args(gxg_gtk_im_context_simple_new_w, gxg_gtk_im_context_simple_new) Xen_wrap_4_args(gxg_gtk_im_context_simple_add_table_w, gxg_gtk_im_context_simple_add_table) Xen_wrap_no_args(gxg_gtk_invisible_new_w, gxg_gtk_invisible_new) Xen_wrap_1_arg(gxg_gtk_label_new_w, gxg_gtk_label_new) Xen_wrap_1_arg(gxg_gtk_label_new_with_mnemonic_w, gxg_gtk_label_new_with_mnemonic) Xen_wrap_2_args(gxg_gtk_label_set_text_w, gxg_gtk_label_set_text) Xen_wrap_1_arg(gxg_gtk_label_get_text_w, gxg_gtk_label_get_text) Xen_wrap_2_args(gxg_gtk_label_set_attributes_w, gxg_gtk_label_set_attributes) Xen_wrap_1_arg(gxg_gtk_label_get_attributes_w, gxg_gtk_label_get_attributes) Xen_wrap_2_args(gxg_gtk_label_set_label_w, gxg_gtk_label_set_label) Xen_wrap_1_arg(gxg_gtk_label_get_label_w, gxg_gtk_label_get_label) Xen_wrap_2_args(gxg_gtk_label_set_markup_w, gxg_gtk_label_set_markup) Xen_wrap_2_args(gxg_gtk_label_set_use_markup_w, gxg_gtk_label_set_use_markup) Xen_wrap_1_arg(gxg_gtk_label_get_use_markup_w, gxg_gtk_label_get_use_markup) Xen_wrap_2_args(gxg_gtk_label_set_use_underline_w, gxg_gtk_label_set_use_underline) Xen_wrap_1_arg(gxg_gtk_label_get_use_underline_w, gxg_gtk_label_get_use_underline) Xen_wrap_2_args(gxg_gtk_label_set_markup_with_mnemonic_w, gxg_gtk_label_set_markup_with_mnemonic) Xen_wrap_1_arg(gxg_gtk_label_get_mnemonic_keyval_w, gxg_gtk_label_get_mnemonic_keyval) Xen_wrap_2_args(gxg_gtk_label_set_mnemonic_widget_w, gxg_gtk_label_set_mnemonic_widget) Xen_wrap_1_arg(gxg_gtk_label_get_mnemonic_widget_w, gxg_gtk_label_get_mnemonic_widget) Xen_wrap_2_args(gxg_gtk_label_set_text_with_mnemonic_w, gxg_gtk_label_set_text_with_mnemonic) Xen_wrap_2_args(gxg_gtk_label_set_justify_w, gxg_gtk_label_set_justify) Xen_wrap_1_arg(gxg_gtk_label_get_justify_w, gxg_gtk_label_get_justify) Xen_wrap_2_args(gxg_gtk_label_set_pattern_w, gxg_gtk_label_set_pattern) Xen_wrap_2_args(gxg_gtk_label_set_line_wrap_w, gxg_gtk_label_set_line_wrap) Xen_wrap_1_arg(gxg_gtk_label_get_line_wrap_w, gxg_gtk_label_get_line_wrap) Xen_wrap_2_args(gxg_gtk_label_set_selectable_w, gxg_gtk_label_set_selectable) Xen_wrap_1_arg(gxg_gtk_label_get_selectable_w, gxg_gtk_label_get_selectable) Xen_wrap_3_args(gxg_gtk_label_select_region_w, gxg_gtk_label_select_region) Xen_wrap_3_optional_args(gxg_gtk_label_get_selection_bounds_w, gxg_gtk_label_get_selection_bounds) Xen_wrap_1_arg(gxg_gtk_label_get_layout_w, gxg_gtk_label_get_layout) Xen_wrap_3_optional_args(gxg_gtk_label_get_layout_offsets_w, gxg_gtk_label_get_layout_offsets) Xen_wrap_2_args(gxg_gtk_layout_new_w, gxg_gtk_layout_new) Xen_wrap_4_args(gxg_gtk_layout_put_w, gxg_gtk_layout_put) Xen_wrap_4_args(gxg_gtk_layout_move_w, gxg_gtk_layout_move) Xen_wrap_3_args(gxg_gtk_layout_set_size_w, gxg_gtk_layout_set_size) Xen_wrap_3_optional_args(gxg_gtk_layout_get_size_w, gxg_gtk_layout_get_size) Xen_wrap_2_args(gxg_gtk_list_store_new_w, gxg_gtk_list_store_new) Xen_wrap_2_args(gxg_gtk_list_store_newv_w, gxg_gtk_list_store_newv) Xen_wrap_3_args(gxg_gtk_list_store_set_column_types_w, gxg_gtk_list_store_set_column_types) Xen_wrap_3_args(gxg_gtk_list_store_set_w, gxg_gtk_list_store_set) Xen_wrap_3_args(gxg_gtk_list_store_insert_w, gxg_gtk_list_store_insert) Xen_wrap_3_args(gxg_gtk_list_store_insert_before_w, gxg_gtk_list_store_insert_before) Xen_wrap_3_args(gxg_gtk_list_store_insert_after_w, gxg_gtk_list_store_insert_after) Xen_wrap_2_args(gxg_gtk_list_store_prepend_w, gxg_gtk_list_store_prepend) Xen_wrap_2_args(gxg_gtk_list_store_append_w, gxg_gtk_list_store_append) Xen_wrap_1_arg(gxg_gtk_list_store_clear_w, gxg_gtk_list_store_clear) Xen_wrap_3_args(gxg_gtk_check_version_w, gxg_gtk_check_version) Xen_wrap_no_args(gxg_gtk_disable_setlocale_w, gxg_gtk_disable_setlocale) Xen_wrap_no_args(gxg_gtk_get_default_language_w, gxg_gtk_get_default_language) Xen_wrap_no_args(gxg_gtk_events_pending_w, gxg_gtk_events_pending) Xen_wrap_1_arg(gxg_gtk_main_do_event_w, gxg_gtk_main_do_event) Xen_wrap_no_args(gxg_gtk_main_w, gxg_gtk_main) Xen_wrap_no_args(gxg_gtk_main_level_w, gxg_gtk_main_level) Xen_wrap_no_args(gxg_gtk_main_quit_w, gxg_gtk_main_quit) Xen_wrap_no_args(gxg_gtk_main_iteration_w, gxg_gtk_main_iteration) Xen_wrap_1_arg(gxg_gtk_main_iteration_do_w, gxg_gtk_main_iteration_do) Xen_wrap_no_args(gxg_gtk_true_w, gxg_gtk_true) Xen_wrap_no_args(gxg_gtk_false_w, gxg_gtk_false) Xen_wrap_1_arg(gxg_gtk_grab_add_w, gxg_gtk_grab_add) Xen_wrap_no_args(gxg_gtk_grab_get_current_w, gxg_gtk_grab_get_current) Xen_wrap_1_arg(gxg_gtk_grab_remove_w, gxg_gtk_grab_remove) Xen_wrap_no_args(gxg_gtk_get_current_event_w, gxg_gtk_get_current_event) Xen_wrap_no_args(gxg_gtk_get_current_event_time_w, gxg_gtk_get_current_event_time) Xen_wrap_1_optional_arg(gxg_gtk_get_current_event_state_w, gxg_gtk_get_current_event_state) Xen_wrap_1_arg(gxg_gtk_get_event_widget_w, gxg_gtk_get_event_widget) Xen_wrap_2_args(gxg_gtk_propagate_event_w, gxg_gtk_propagate_event) Xen_wrap_no_args(gxg_gtk_menu_bar_new_w, gxg_gtk_menu_bar_new) Xen_wrap_no_args(gxg_gtk_menu_new_w, gxg_gtk_menu_new) Xen_wrap_7_args(gxg_gtk_menu_popup_w, gxg_gtk_menu_popup) Xen_wrap_1_arg(gxg_gtk_menu_reposition_w, gxg_gtk_menu_reposition) Xen_wrap_1_arg(gxg_gtk_menu_popdown_w, gxg_gtk_menu_popdown) Xen_wrap_1_arg(gxg_gtk_menu_get_active_w, gxg_gtk_menu_get_active) Xen_wrap_2_args(gxg_gtk_menu_set_active_w, gxg_gtk_menu_set_active) Xen_wrap_2_args(gxg_gtk_menu_set_accel_group_w, gxg_gtk_menu_set_accel_group) Xen_wrap_1_arg(gxg_gtk_menu_get_accel_group_w, gxg_gtk_menu_get_accel_group) Xen_wrap_2_args(gxg_gtk_menu_set_accel_path_w, gxg_gtk_menu_set_accel_path) Xen_wrap_1_arg(gxg_gtk_menu_detach_w, gxg_gtk_menu_detach) Xen_wrap_1_arg(gxg_gtk_menu_get_attach_widget_w, gxg_gtk_menu_get_attach_widget) Xen_wrap_3_args(gxg_gtk_menu_reorder_child_w, gxg_gtk_menu_reorder_child) Xen_wrap_2_args(gxg_gtk_menu_set_monitor_w, gxg_gtk_menu_set_monitor) Xen_wrap_no_args(gxg_gtk_menu_item_new_w, gxg_gtk_menu_item_new) Xen_wrap_1_arg(gxg_gtk_menu_item_new_with_label_w, gxg_gtk_menu_item_new_with_label) Xen_wrap_1_arg(gxg_gtk_menu_item_new_with_mnemonic_w, gxg_gtk_menu_item_new_with_mnemonic) Xen_wrap_2_args(gxg_gtk_menu_item_set_submenu_w, gxg_gtk_menu_item_set_submenu) Xen_wrap_1_arg(gxg_gtk_menu_item_get_submenu_w, gxg_gtk_menu_item_get_submenu) Xen_wrap_1_arg(gxg_gtk_menu_item_select_w, gxg_gtk_menu_item_select) Xen_wrap_1_arg(gxg_gtk_menu_item_deselect_w, gxg_gtk_menu_item_deselect) Xen_wrap_1_arg(gxg_gtk_menu_item_activate_w, gxg_gtk_menu_item_activate) Xen_wrap_2_args(gxg_gtk_menu_item_toggle_size_request_w, gxg_gtk_menu_item_toggle_size_request) Xen_wrap_2_args(gxg_gtk_menu_item_toggle_size_allocate_w, gxg_gtk_menu_item_toggle_size_allocate) Xen_wrap_2_args(gxg_gtk_menu_item_set_accel_path_w, gxg_gtk_menu_item_set_accel_path) Xen_wrap_2_args(gxg_gtk_menu_shell_append_w, gxg_gtk_menu_shell_append) Xen_wrap_2_args(gxg_gtk_menu_shell_prepend_w, gxg_gtk_menu_shell_prepend) Xen_wrap_3_args(gxg_gtk_menu_shell_insert_w, gxg_gtk_menu_shell_insert) Xen_wrap_1_arg(gxg_gtk_menu_shell_deactivate_w, gxg_gtk_menu_shell_deactivate) Xen_wrap_2_args(gxg_gtk_menu_shell_select_item_w, gxg_gtk_menu_shell_select_item) Xen_wrap_1_arg(gxg_gtk_menu_shell_deselect_w, gxg_gtk_menu_shell_deselect) Xen_wrap_3_args(gxg_gtk_menu_shell_activate_item_w, gxg_gtk_menu_shell_activate_item) Xen_wrap_no_args(gxg_gtk_notebook_new_w, gxg_gtk_notebook_new) Xen_wrap_2_args(gxg_gtk_notebook_remove_page_w, gxg_gtk_notebook_remove_page) Xen_wrap_1_arg(gxg_gtk_notebook_get_current_page_w, gxg_gtk_notebook_get_current_page) Xen_wrap_2_args(gxg_gtk_notebook_get_nth_page_w, gxg_gtk_notebook_get_nth_page) Xen_wrap_2_args(gxg_gtk_notebook_page_num_w, gxg_gtk_notebook_page_num) Xen_wrap_2_args(gxg_gtk_notebook_set_current_page_w, gxg_gtk_notebook_set_current_page) Xen_wrap_1_arg(gxg_gtk_notebook_next_page_w, gxg_gtk_notebook_next_page) Xen_wrap_1_arg(gxg_gtk_notebook_prev_page_w, gxg_gtk_notebook_prev_page) Xen_wrap_2_args(gxg_gtk_notebook_set_show_border_w, gxg_gtk_notebook_set_show_border) Xen_wrap_1_arg(gxg_gtk_notebook_get_show_border_w, gxg_gtk_notebook_get_show_border) Xen_wrap_2_args(gxg_gtk_notebook_set_show_tabs_w, gxg_gtk_notebook_set_show_tabs) Xen_wrap_1_arg(gxg_gtk_notebook_get_show_tabs_w, gxg_gtk_notebook_get_show_tabs) Xen_wrap_2_args(gxg_gtk_notebook_set_tab_pos_w, gxg_gtk_notebook_set_tab_pos) Xen_wrap_1_arg(gxg_gtk_notebook_get_tab_pos_w, gxg_gtk_notebook_get_tab_pos) Xen_wrap_2_args(gxg_gtk_notebook_set_scrollable_w, gxg_gtk_notebook_set_scrollable) Xen_wrap_1_arg(gxg_gtk_notebook_get_scrollable_w, gxg_gtk_notebook_get_scrollable) Xen_wrap_1_arg(gxg_gtk_notebook_popup_enable_w, gxg_gtk_notebook_popup_enable) Xen_wrap_1_arg(gxg_gtk_notebook_popup_disable_w, gxg_gtk_notebook_popup_disable) Xen_wrap_2_args(gxg_gtk_notebook_get_tab_label_w, gxg_gtk_notebook_get_tab_label) Xen_wrap_3_args(gxg_gtk_notebook_set_tab_label_w, gxg_gtk_notebook_set_tab_label) Xen_wrap_3_args(gxg_gtk_notebook_set_tab_label_text_w, gxg_gtk_notebook_set_tab_label_text) Xen_wrap_2_args(gxg_gtk_notebook_get_tab_label_text_w, gxg_gtk_notebook_get_tab_label_text) Xen_wrap_2_args(gxg_gtk_notebook_get_menu_label_w, gxg_gtk_notebook_get_menu_label) Xen_wrap_3_args(gxg_gtk_notebook_set_menu_label_w, gxg_gtk_notebook_set_menu_label) Xen_wrap_3_args(gxg_gtk_notebook_set_menu_label_text_w, gxg_gtk_notebook_set_menu_label_text) Xen_wrap_2_args(gxg_gtk_notebook_get_menu_label_text_w, gxg_gtk_notebook_get_menu_label_text) Xen_wrap_3_args(gxg_gtk_notebook_reorder_child_w, gxg_gtk_notebook_reorder_child) Xen_wrap_3_args(gxg_gtk_notebook_append_page_w, gxg_gtk_notebook_append_page) Xen_wrap_4_args(gxg_gtk_notebook_append_page_menu_w, gxg_gtk_notebook_append_page_menu) Xen_wrap_3_args(gxg_gtk_notebook_prepend_page_w, gxg_gtk_notebook_prepend_page) Xen_wrap_4_args(gxg_gtk_notebook_prepend_page_menu_w, gxg_gtk_notebook_prepend_page_menu) Xen_wrap_4_args(gxg_gtk_notebook_insert_page_w, gxg_gtk_notebook_insert_page) Xen_wrap_5_args(gxg_gtk_notebook_insert_page_menu_w, gxg_gtk_notebook_insert_page_menu) Xen_wrap_2_args(gxg_gtk_paned_add1_w, gxg_gtk_paned_add1) Xen_wrap_2_args(gxg_gtk_paned_add2_w, gxg_gtk_paned_add2) Xen_wrap_4_args(gxg_gtk_paned_pack1_w, gxg_gtk_paned_pack1) Xen_wrap_4_args(gxg_gtk_paned_pack2_w, gxg_gtk_paned_pack2) Xen_wrap_1_arg(gxg_gtk_paned_get_position_w, gxg_gtk_paned_get_position) Xen_wrap_2_args(gxg_gtk_paned_set_position_w, gxg_gtk_paned_set_position) Xen_wrap_no_args(gxg_gtk_progress_bar_new_w, gxg_gtk_progress_bar_new) Xen_wrap_1_arg(gxg_gtk_progress_bar_pulse_w, gxg_gtk_progress_bar_pulse) Xen_wrap_2_args(gxg_gtk_progress_bar_set_text_w, gxg_gtk_progress_bar_set_text) Xen_wrap_2_args(gxg_gtk_progress_bar_set_fraction_w, gxg_gtk_progress_bar_set_fraction) Xen_wrap_2_args(gxg_gtk_progress_bar_set_pulse_step_w, gxg_gtk_progress_bar_set_pulse_step) Xen_wrap_1_arg(gxg_gtk_progress_bar_get_text_w, gxg_gtk_progress_bar_get_text) Xen_wrap_1_arg(gxg_gtk_progress_bar_get_fraction_w, gxg_gtk_progress_bar_get_fraction) Xen_wrap_1_arg(gxg_gtk_progress_bar_get_pulse_step_w, gxg_gtk_progress_bar_get_pulse_step) Xen_wrap_1_arg(gxg_gtk_radio_button_new_w, gxg_gtk_radio_button_new) Xen_wrap_1_arg(gxg_gtk_radio_button_new_from_widget_w, gxg_gtk_radio_button_new_from_widget) Xen_wrap_2_args(gxg_gtk_radio_button_new_with_label_w, gxg_gtk_radio_button_new_with_label) Xen_wrap_2_args(gxg_gtk_radio_button_new_with_label_from_widget_w, gxg_gtk_radio_button_new_with_label_from_widget) Xen_wrap_2_args(gxg_gtk_radio_button_new_with_mnemonic_w, gxg_gtk_radio_button_new_with_mnemonic) Xen_wrap_2_args(gxg_gtk_radio_button_new_with_mnemonic_from_widget_w, gxg_gtk_radio_button_new_with_mnemonic_from_widget) Xen_wrap_1_arg(gxg_gtk_radio_button_get_group_w, gxg_gtk_radio_button_get_group) Xen_wrap_2_args(gxg_gtk_radio_button_set_group_w, gxg_gtk_radio_button_set_group) Xen_wrap_1_arg(gxg_gtk_radio_menu_item_new_w, gxg_gtk_radio_menu_item_new) Xen_wrap_2_args(gxg_gtk_radio_menu_item_new_with_label_w, gxg_gtk_radio_menu_item_new_with_label) Xen_wrap_2_args(gxg_gtk_radio_menu_item_new_with_mnemonic_w, gxg_gtk_radio_menu_item_new_with_mnemonic) Xen_wrap_1_arg(gxg_gtk_radio_menu_item_get_group_w, gxg_gtk_radio_menu_item_get_group) Xen_wrap_2_args(gxg_gtk_radio_menu_item_set_group_w, gxg_gtk_radio_menu_item_set_group) Xen_wrap_2_args(gxg_gtk_range_set_adjustment_w, gxg_gtk_range_set_adjustment) Xen_wrap_1_arg(gxg_gtk_range_get_adjustment_w, gxg_gtk_range_get_adjustment) Xen_wrap_2_args(gxg_gtk_range_set_inverted_w, gxg_gtk_range_set_inverted) Xen_wrap_1_arg(gxg_gtk_range_get_inverted_w, gxg_gtk_range_get_inverted) Xen_wrap_3_args(gxg_gtk_range_set_increments_w, gxg_gtk_range_set_increments) Xen_wrap_3_args(gxg_gtk_range_set_range_w, gxg_gtk_range_set_range) Xen_wrap_2_args(gxg_gtk_range_set_value_w, gxg_gtk_range_set_value) Xen_wrap_1_arg(gxg_gtk_range_get_value_w, gxg_gtk_range_get_value) Xen_wrap_2_args(gxg_gtk_scale_set_digits_w, gxg_gtk_scale_set_digits) Xen_wrap_1_arg(gxg_gtk_scale_get_digits_w, gxg_gtk_scale_get_digits) Xen_wrap_2_args(gxg_gtk_scale_set_draw_value_w, gxg_gtk_scale_set_draw_value) Xen_wrap_1_arg(gxg_gtk_scale_get_draw_value_w, gxg_gtk_scale_get_draw_value) Xen_wrap_2_args(gxg_gtk_scale_set_value_pos_w, gxg_gtk_scale_set_value_pos) Xen_wrap_1_arg(gxg_gtk_scale_get_value_pos_w, gxg_gtk_scale_get_value_pos) Xen_wrap_2_args(gxg_gtk_scrolled_window_new_w, gxg_gtk_scrolled_window_new) Xen_wrap_2_args(gxg_gtk_scrolled_window_set_hadjustment_w, gxg_gtk_scrolled_window_set_hadjustment) Xen_wrap_2_args(gxg_gtk_scrolled_window_set_vadjustment_w, gxg_gtk_scrolled_window_set_vadjustment) Xen_wrap_1_arg(gxg_gtk_scrolled_window_get_hadjustment_w, gxg_gtk_scrolled_window_get_hadjustment) Xen_wrap_1_arg(gxg_gtk_scrolled_window_get_vadjustment_w, gxg_gtk_scrolled_window_get_vadjustment) Xen_wrap_3_args(gxg_gtk_scrolled_window_set_policy_w, gxg_gtk_scrolled_window_set_policy) Xen_wrap_3_optional_args(gxg_gtk_scrolled_window_get_policy_w, gxg_gtk_scrolled_window_get_policy) Xen_wrap_2_args(gxg_gtk_scrolled_window_set_placement_w, gxg_gtk_scrolled_window_set_placement) Xen_wrap_1_arg(gxg_gtk_scrolled_window_get_placement_w, gxg_gtk_scrolled_window_get_placement) Xen_wrap_2_args(gxg_gtk_scrolled_window_set_shadow_type_w, gxg_gtk_scrolled_window_set_shadow_type) Xen_wrap_1_arg(gxg_gtk_scrolled_window_get_shadow_type_w, gxg_gtk_scrolled_window_get_shadow_type) Xen_wrap_2_args(gxg_gtk_target_list_new_w, gxg_gtk_target_list_new) Xen_wrap_1_arg(gxg_gtk_target_list_unref_w, gxg_gtk_target_list_unref) Xen_wrap_4_args(gxg_gtk_target_list_add_w, gxg_gtk_target_list_add) Xen_wrap_3_args(gxg_gtk_target_list_add_table_w, gxg_gtk_target_list_add_table) Xen_wrap_2_args(gxg_gtk_target_list_remove_w, gxg_gtk_target_list_remove) Xen_wrap_3_optional_args(gxg_gtk_target_list_find_w, gxg_gtk_target_list_find) Xen_wrap_3_args(gxg_gtk_selection_owner_set_w, gxg_gtk_selection_owner_set) Xen_wrap_4_args(gxg_gtk_selection_add_target_w, gxg_gtk_selection_add_target) Xen_wrap_4_args(gxg_gtk_selection_add_targets_w, gxg_gtk_selection_add_targets) Xen_wrap_2_args(gxg_gtk_selection_clear_targets_w, gxg_gtk_selection_clear_targets) Xen_wrap_4_args(gxg_gtk_selection_convert_w, gxg_gtk_selection_convert) Xen_wrap_5_args(gxg_gtk_selection_data_set_w, gxg_gtk_selection_data_set) Xen_wrap_3_args(gxg_gtk_selection_data_set_text_w, gxg_gtk_selection_data_set_text) Xen_wrap_1_arg(gxg_gtk_selection_data_get_text_w, gxg_gtk_selection_data_get_text) Xen_wrap_3_optional_args(gxg_gtk_selection_data_get_targets_w, gxg_gtk_selection_data_get_targets) Xen_wrap_1_arg(gxg_gtk_selection_data_targets_include_text_w, gxg_gtk_selection_data_targets_include_text) Xen_wrap_1_arg(gxg_gtk_selection_remove_all_w, gxg_gtk_selection_remove_all) Xen_wrap_1_arg(gxg_gtk_selection_data_copy_w, gxg_gtk_selection_data_copy) Xen_wrap_1_arg(gxg_gtk_selection_data_free_w, gxg_gtk_selection_data_free) Xen_wrap_no_args(gxg_gtk_separator_menu_item_new_w, gxg_gtk_separator_menu_item_new) Xen_wrap_no_args(gxg_gtk_settings_get_default_w, gxg_gtk_settings_get_default) Xen_wrap_1_arg(gxg_gtk_size_group_new_w, gxg_gtk_size_group_new) Xen_wrap_2_args(gxg_gtk_size_group_set_mode_w, gxg_gtk_size_group_set_mode) Xen_wrap_1_arg(gxg_gtk_size_group_get_mode_w, gxg_gtk_size_group_get_mode) Xen_wrap_2_args(gxg_gtk_size_group_add_widget_w, gxg_gtk_size_group_add_widget) Xen_wrap_2_args(gxg_gtk_size_group_remove_widget_w, gxg_gtk_size_group_remove_widget) Xen_wrap_4_args(gxg_gtk_spin_button_configure_w, gxg_gtk_spin_button_configure) Xen_wrap_3_args(gxg_gtk_spin_button_new_w, gxg_gtk_spin_button_new) Xen_wrap_3_args(gxg_gtk_spin_button_new_with_range_w, gxg_gtk_spin_button_new_with_range) Xen_wrap_2_args(gxg_gtk_spin_button_set_adjustment_w, gxg_gtk_spin_button_set_adjustment) Xen_wrap_1_arg(gxg_gtk_spin_button_get_adjustment_w, gxg_gtk_spin_button_get_adjustment) Xen_wrap_2_args(gxg_gtk_spin_button_set_digits_w, gxg_gtk_spin_button_set_digits) Xen_wrap_1_arg(gxg_gtk_spin_button_get_digits_w, gxg_gtk_spin_button_get_digits) Xen_wrap_3_args(gxg_gtk_spin_button_set_increments_w, gxg_gtk_spin_button_set_increments) Xen_wrap_3_optional_args(gxg_gtk_spin_button_get_increments_w, gxg_gtk_spin_button_get_increments) Xen_wrap_3_args(gxg_gtk_spin_button_set_range_w, gxg_gtk_spin_button_set_range) Xen_wrap_3_optional_args(gxg_gtk_spin_button_get_range_w, gxg_gtk_spin_button_get_range) Xen_wrap_1_arg(gxg_gtk_spin_button_get_value_w, gxg_gtk_spin_button_get_value) Xen_wrap_1_arg(gxg_gtk_spin_button_get_value_as_int_w, gxg_gtk_spin_button_get_value_as_int) Xen_wrap_2_args(gxg_gtk_spin_button_set_value_w, gxg_gtk_spin_button_set_value) Xen_wrap_2_args(gxg_gtk_spin_button_set_update_policy_w, gxg_gtk_spin_button_set_update_policy) Xen_wrap_1_arg(gxg_gtk_spin_button_get_update_policy_w, gxg_gtk_spin_button_get_update_policy) Xen_wrap_2_args(gxg_gtk_spin_button_set_numeric_w, gxg_gtk_spin_button_set_numeric) Xen_wrap_1_arg(gxg_gtk_spin_button_get_numeric_w, gxg_gtk_spin_button_get_numeric) Xen_wrap_3_args(gxg_gtk_spin_button_spin_w, gxg_gtk_spin_button_spin) Xen_wrap_2_args(gxg_gtk_spin_button_set_wrap_w, gxg_gtk_spin_button_set_wrap) Xen_wrap_1_arg(gxg_gtk_spin_button_get_wrap_w, gxg_gtk_spin_button_get_wrap) Xen_wrap_2_args(gxg_gtk_spin_button_set_snap_to_ticks_w, gxg_gtk_spin_button_set_snap_to_ticks) Xen_wrap_1_arg(gxg_gtk_spin_button_get_snap_to_ticks_w, gxg_gtk_spin_button_get_snap_to_ticks) Xen_wrap_1_arg(gxg_gtk_spin_button_update_w, gxg_gtk_spin_button_update) Xen_wrap_no_args(gxg_gtk_statusbar_new_w, gxg_gtk_statusbar_new) Xen_wrap_2_args(gxg_gtk_statusbar_get_context_id_w, gxg_gtk_statusbar_get_context_id) Xen_wrap_3_args(gxg_gtk_statusbar_push_w, gxg_gtk_statusbar_push) Xen_wrap_2_args(gxg_gtk_statusbar_pop_w, gxg_gtk_statusbar_pop) Xen_wrap_3_args(gxg_gtk_statusbar_remove_w, gxg_gtk_statusbar_remove) Xen_wrap_1_arg(gxg_gtk_text_buffer_new_w, gxg_gtk_text_buffer_new) Xen_wrap_1_arg(gxg_gtk_text_buffer_get_line_count_w, gxg_gtk_text_buffer_get_line_count) Xen_wrap_1_arg(gxg_gtk_text_buffer_get_char_count_w, gxg_gtk_text_buffer_get_char_count) Xen_wrap_1_arg(gxg_gtk_text_buffer_get_tag_table_w, gxg_gtk_text_buffer_get_tag_table) Xen_wrap_3_args(gxg_gtk_text_buffer_set_text_w, gxg_gtk_text_buffer_set_text) Xen_wrap_4_args(gxg_gtk_text_buffer_insert_w, gxg_gtk_text_buffer_insert) Xen_wrap_3_args(gxg_gtk_text_buffer_insert_at_cursor_w, gxg_gtk_text_buffer_insert_at_cursor) Xen_wrap_5_args(gxg_gtk_text_buffer_insert_interactive_w, gxg_gtk_text_buffer_insert_interactive) Xen_wrap_4_args(gxg_gtk_text_buffer_insert_interactive_at_cursor_w, gxg_gtk_text_buffer_insert_interactive_at_cursor) Xen_wrap_4_args(gxg_gtk_text_buffer_insert_range_w, gxg_gtk_text_buffer_insert_range) Xen_wrap_5_args(gxg_gtk_text_buffer_insert_range_interactive_w, gxg_gtk_text_buffer_insert_range_interactive) Xen_wrap_5_args(gxg_gtk_text_buffer_insert_with_tags_w, gxg_gtk_text_buffer_insert_with_tags) Xen_wrap_5_args(gxg_gtk_text_buffer_insert_with_tags_by_name_w, gxg_gtk_text_buffer_insert_with_tags_by_name) Xen_wrap_3_args(gxg_gtk_text_buffer_delete_w, gxg_gtk_text_buffer_delete) Xen_wrap_4_args(gxg_gtk_text_buffer_delete_interactive_w, gxg_gtk_text_buffer_delete_interactive) Xen_wrap_4_args(gxg_gtk_text_buffer_get_text_w, gxg_gtk_text_buffer_get_text) Xen_wrap_4_args(gxg_gtk_text_buffer_get_slice_w, gxg_gtk_text_buffer_get_slice) Xen_wrap_3_args(gxg_gtk_text_buffer_insert_pixbuf_w, gxg_gtk_text_buffer_insert_pixbuf) Xen_wrap_3_args(gxg_gtk_text_buffer_insert_child_anchor_w, gxg_gtk_text_buffer_insert_child_anchor) Xen_wrap_2_args(gxg_gtk_text_buffer_create_child_anchor_w, gxg_gtk_text_buffer_create_child_anchor) Xen_wrap_4_args(gxg_gtk_text_buffer_create_mark_w, gxg_gtk_text_buffer_create_mark) Xen_wrap_3_args(gxg_gtk_text_buffer_move_mark_w, gxg_gtk_text_buffer_move_mark) Xen_wrap_2_args(gxg_gtk_text_buffer_delete_mark_w, gxg_gtk_text_buffer_delete_mark) Xen_wrap_2_args(gxg_gtk_text_buffer_get_mark_w, gxg_gtk_text_buffer_get_mark) Xen_wrap_3_args(gxg_gtk_text_buffer_move_mark_by_name_w, gxg_gtk_text_buffer_move_mark_by_name) Xen_wrap_2_args(gxg_gtk_text_buffer_delete_mark_by_name_w, gxg_gtk_text_buffer_delete_mark_by_name) Xen_wrap_1_arg(gxg_gtk_text_buffer_get_insert_w, gxg_gtk_text_buffer_get_insert) Xen_wrap_1_arg(gxg_gtk_text_buffer_get_selection_bound_w, gxg_gtk_text_buffer_get_selection_bound) Xen_wrap_2_args(gxg_gtk_text_buffer_place_cursor_w, gxg_gtk_text_buffer_place_cursor) Xen_wrap_4_args(gxg_gtk_text_buffer_apply_tag_w, gxg_gtk_text_buffer_apply_tag) Xen_wrap_4_args(gxg_gtk_text_buffer_remove_tag_w, gxg_gtk_text_buffer_remove_tag) Xen_wrap_4_args(gxg_gtk_text_buffer_apply_tag_by_name_w, gxg_gtk_text_buffer_apply_tag_by_name) Xen_wrap_4_args(gxg_gtk_text_buffer_remove_tag_by_name_w, gxg_gtk_text_buffer_remove_tag_by_name) Xen_wrap_3_args(gxg_gtk_text_buffer_remove_all_tags_w, gxg_gtk_text_buffer_remove_all_tags) Xen_wrap_3_optional_args(gxg_gtk_text_buffer_create_tag_w, gxg_gtk_text_buffer_create_tag) Xen_wrap_4_args(gxg_gtk_text_buffer_get_iter_at_line_offset_w, gxg_gtk_text_buffer_get_iter_at_line_offset) Xen_wrap_4_args(gxg_gtk_text_buffer_get_iter_at_line_index_w, gxg_gtk_text_buffer_get_iter_at_line_index) Xen_wrap_3_args(gxg_gtk_text_buffer_get_iter_at_offset_w, gxg_gtk_text_buffer_get_iter_at_offset) Xen_wrap_3_args(gxg_gtk_text_buffer_get_iter_at_line_w, gxg_gtk_text_buffer_get_iter_at_line) Xen_wrap_2_args(gxg_gtk_text_buffer_get_start_iter_w, gxg_gtk_text_buffer_get_start_iter) Xen_wrap_2_args(gxg_gtk_text_buffer_get_end_iter_w, gxg_gtk_text_buffer_get_end_iter) Xen_wrap_3_args(gxg_gtk_text_buffer_get_bounds_w, gxg_gtk_text_buffer_get_bounds) Xen_wrap_3_args(gxg_gtk_text_buffer_get_iter_at_mark_w, gxg_gtk_text_buffer_get_iter_at_mark) Xen_wrap_3_args(gxg_gtk_text_buffer_get_iter_at_child_anchor_w, gxg_gtk_text_buffer_get_iter_at_child_anchor) Xen_wrap_1_arg(gxg_gtk_text_buffer_get_modified_w, gxg_gtk_text_buffer_get_modified) Xen_wrap_2_args(gxg_gtk_text_buffer_set_modified_w, gxg_gtk_text_buffer_set_modified) Xen_wrap_2_args(gxg_gtk_text_buffer_add_selection_clipboard_w, gxg_gtk_text_buffer_add_selection_clipboard) Xen_wrap_2_args(gxg_gtk_text_buffer_remove_selection_clipboard_w, gxg_gtk_text_buffer_remove_selection_clipboard) Xen_wrap_3_args(gxg_gtk_text_buffer_cut_clipboard_w, gxg_gtk_text_buffer_cut_clipboard) Xen_wrap_2_args(gxg_gtk_text_buffer_copy_clipboard_w, gxg_gtk_text_buffer_copy_clipboard) Xen_wrap_4_args(gxg_gtk_text_buffer_paste_clipboard_w, gxg_gtk_text_buffer_paste_clipboard) Xen_wrap_3_args(gxg_gtk_text_buffer_get_selection_bounds_w, gxg_gtk_text_buffer_get_selection_bounds) Xen_wrap_3_args(gxg_gtk_text_buffer_delete_selection_w, gxg_gtk_text_buffer_delete_selection) Xen_wrap_1_arg(gxg_gtk_text_buffer_begin_user_action_w, gxg_gtk_text_buffer_begin_user_action) Xen_wrap_1_arg(gxg_gtk_text_buffer_end_user_action_w, gxg_gtk_text_buffer_end_user_action) Xen_wrap_no_args(gxg_gtk_text_child_anchor_new_w, gxg_gtk_text_child_anchor_new) Xen_wrap_1_arg(gxg_gtk_text_child_anchor_get_widgets_w, gxg_gtk_text_child_anchor_get_widgets) Xen_wrap_1_arg(gxg_gtk_text_child_anchor_get_deleted_w, gxg_gtk_text_child_anchor_get_deleted) Xen_wrap_1_arg(gxg_gtk_text_iter_get_buffer_w, gxg_gtk_text_iter_get_buffer) Xen_wrap_1_arg(gxg_gtk_text_iter_copy_w, gxg_gtk_text_iter_copy) Xen_wrap_1_arg(gxg_gtk_text_iter_free_w, gxg_gtk_text_iter_free) Xen_wrap_1_arg(gxg_gtk_text_iter_get_offset_w, gxg_gtk_text_iter_get_offset) Xen_wrap_1_arg(gxg_gtk_text_iter_get_line_w, gxg_gtk_text_iter_get_line) Xen_wrap_1_arg(gxg_gtk_text_iter_get_line_offset_w, gxg_gtk_text_iter_get_line_offset) Xen_wrap_1_arg(gxg_gtk_text_iter_get_line_index_w, gxg_gtk_text_iter_get_line_index) Xen_wrap_1_arg(gxg_gtk_text_iter_get_visible_line_offset_w, gxg_gtk_text_iter_get_visible_line_offset) Xen_wrap_1_arg(gxg_gtk_text_iter_get_visible_line_index_w, gxg_gtk_text_iter_get_visible_line_index) Xen_wrap_1_arg(gxg_gtk_text_iter_get_char_w, gxg_gtk_text_iter_get_char) Xen_wrap_2_args(gxg_gtk_text_iter_get_slice_w, gxg_gtk_text_iter_get_slice) Xen_wrap_2_args(gxg_gtk_text_iter_get_text_w, gxg_gtk_text_iter_get_text) Xen_wrap_2_args(gxg_gtk_text_iter_get_visible_slice_w, gxg_gtk_text_iter_get_visible_slice) Xen_wrap_2_args(gxg_gtk_text_iter_get_visible_text_w, gxg_gtk_text_iter_get_visible_text) Xen_wrap_1_arg(gxg_gtk_text_iter_get_pixbuf_w, gxg_gtk_text_iter_get_pixbuf) Xen_wrap_1_arg(gxg_gtk_text_iter_get_marks_w, gxg_gtk_text_iter_get_marks) Xen_wrap_1_arg(gxg_gtk_text_iter_get_child_anchor_w, gxg_gtk_text_iter_get_child_anchor) Xen_wrap_2_args(gxg_gtk_text_iter_get_toggled_tags_w, gxg_gtk_text_iter_get_toggled_tags) Xen_wrap_2_args(gxg_gtk_text_iter_begins_tag_w, gxg_gtk_text_iter_begins_tag) Xen_wrap_2_args(gxg_gtk_text_iter_ends_tag_w, gxg_gtk_text_iter_ends_tag) Xen_wrap_2_args(gxg_gtk_text_iter_toggles_tag_w, gxg_gtk_text_iter_toggles_tag) Xen_wrap_2_args(gxg_gtk_text_iter_has_tag_w, gxg_gtk_text_iter_has_tag) Xen_wrap_1_arg(gxg_gtk_text_iter_get_tags_w, gxg_gtk_text_iter_get_tags) Xen_wrap_2_args(gxg_gtk_text_iter_editable_w, gxg_gtk_text_iter_editable) Xen_wrap_2_args(gxg_gtk_text_iter_can_insert_w, gxg_gtk_text_iter_can_insert) Xen_wrap_1_arg(gxg_gtk_text_iter_starts_word_w, gxg_gtk_text_iter_starts_word) Xen_wrap_1_arg(gxg_gtk_text_iter_ends_word_w, gxg_gtk_text_iter_ends_word) Xen_wrap_1_arg(gxg_gtk_text_iter_inside_word_w, gxg_gtk_text_iter_inside_word) Xen_wrap_1_arg(gxg_gtk_text_iter_starts_sentence_w, gxg_gtk_text_iter_starts_sentence) Xen_wrap_1_arg(gxg_gtk_text_iter_ends_sentence_w, gxg_gtk_text_iter_ends_sentence) Xen_wrap_1_arg(gxg_gtk_text_iter_inside_sentence_w, gxg_gtk_text_iter_inside_sentence) Xen_wrap_1_arg(gxg_gtk_text_iter_starts_line_w, gxg_gtk_text_iter_starts_line) Xen_wrap_1_arg(gxg_gtk_text_iter_ends_line_w, gxg_gtk_text_iter_ends_line) Xen_wrap_1_arg(gxg_gtk_text_iter_is_cursor_position_w, gxg_gtk_text_iter_is_cursor_position) Xen_wrap_1_arg(gxg_gtk_text_iter_get_chars_in_line_w, gxg_gtk_text_iter_get_chars_in_line) Xen_wrap_1_arg(gxg_gtk_text_iter_get_bytes_in_line_w, gxg_gtk_text_iter_get_bytes_in_line) Xen_wrap_2_args(gxg_gtk_text_iter_get_attributes_w, gxg_gtk_text_iter_get_attributes) Xen_wrap_1_arg(gxg_gtk_text_iter_get_language_w, gxg_gtk_text_iter_get_language) Xen_wrap_1_arg(gxg_gtk_text_iter_is_end_w, gxg_gtk_text_iter_is_end) Xen_wrap_1_arg(gxg_gtk_text_iter_is_start_w, gxg_gtk_text_iter_is_start) Xen_wrap_1_arg(gxg_gtk_text_iter_forward_char_w, gxg_gtk_text_iter_forward_char) Xen_wrap_1_arg(gxg_gtk_text_iter_backward_char_w, gxg_gtk_text_iter_backward_char) Xen_wrap_2_args(gxg_gtk_text_iter_forward_chars_w, gxg_gtk_text_iter_forward_chars) Xen_wrap_2_args(gxg_gtk_text_iter_backward_chars_w, gxg_gtk_text_iter_backward_chars) Xen_wrap_1_arg(gxg_gtk_text_iter_forward_line_w, gxg_gtk_text_iter_forward_line) Xen_wrap_1_arg(gxg_gtk_text_iter_backward_line_w, gxg_gtk_text_iter_backward_line) Xen_wrap_2_args(gxg_gtk_text_iter_forward_lines_w, gxg_gtk_text_iter_forward_lines) Xen_wrap_2_args(gxg_gtk_text_iter_backward_lines_w, gxg_gtk_text_iter_backward_lines) Xen_wrap_1_arg(gxg_gtk_text_iter_forward_word_end_w, gxg_gtk_text_iter_forward_word_end) Xen_wrap_1_arg(gxg_gtk_text_iter_backward_word_start_w, gxg_gtk_text_iter_backward_word_start) Xen_wrap_2_args(gxg_gtk_text_iter_forward_word_ends_w, gxg_gtk_text_iter_forward_word_ends) Xen_wrap_2_args(gxg_gtk_text_iter_backward_word_starts_w, gxg_gtk_text_iter_backward_word_starts) Xen_wrap_1_arg(gxg_gtk_text_iter_forward_sentence_end_w, gxg_gtk_text_iter_forward_sentence_end) Xen_wrap_1_arg(gxg_gtk_text_iter_backward_sentence_start_w, gxg_gtk_text_iter_backward_sentence_start) Xen_wrap_2_args(gxg_gtk_text_iter_forward_sentence_ends_w, gxg_gtk_text_iter_forward_sentence_ends) Xen_wrap_2_args(gxg_gtk_text_iter_backward_sentence_starts_w, gxg_gtk_text_iter_backward_sentence_starts) Xen_wrap_1_arg(gxg_gtk_text_iter_forward_cursor_position_w, gxg_gtk_text_iter_forward_cursor_position) Xen_wrap_1_arg(gxg_gtk_text_iter_backward_cursor_position_w, gxg_gtk_text_iter_backward_cursor_position) Xen_wrap_2_args(gxg_gtk_text_iter_forward_cursor_positions_w, gxg_gtk_text_iter_forward_cursor_positions) Xen_wrap_2_args(gxg_gtk_text_iter_backward_cursor_positions_w, gxg_gtk_text_iter_backward_cursor_positions) Xen_wrap_2_args(gxg_gtk_text_iter_set_offset_w, gxg_gtk_text_iter_set_offset) Xen_wrap_2_args(gxg_gtk_text_iter_set_line_w, gxg_gtk_text_iter_set_line) Xen_wrap_2_args(gxg_gtk_text_iter_set_line_offset_w, gxg_gtk_text_iter_set_line_offset) Xen_wrap_2_args(gxg_gtk_text_iter_set_line_index_w, gxg_gtk_text_iter_set_line_index) Xen_wrap_1_arg(gxg_gtk_text_iter_forward_to_end_w, gxg_gtk_text_iter_forward_to_end) Xen_wrap_1_arg(gxg_gtk_text_iter_forward_to_line_end_w, gxg_gtk_text_iter_forward_to_line_end) Xen_wrap_2_args(gxg_gtk_text_iter_set_visible_line_offset_w, gxg_gtk_text_iter_set_visible_line_offset) Xen_wrap_2_args(gxg_gtk_text_iter_set_visible_line_index_w, gxg_gtk_text_iter_set_visible_line_index) Xen_wrap_2_args(gxg_gtk_text_iter_forward_to_tag_toggle_w, gxg_gtk_text_iter_forward_to_tag_toggle) Xen_wrap_2_args(gxg_gtk_text_iter_backward_to_tag_toggle_w, gxg_gtk_text_iter_backward_to_tag_toggle) Xen_wrap_4_args(gxg_gtk_text_iter_forward_find_char_w, gxg_gtk_text_iter_forward_find_char) Xen_wrap_4_args(gxg_gtk_text_iter_backward_find_char_w, gxg_gtk_text_iter_backward_find_char) Xen_wrap_6_args(gxg_gtk_text_iter_forward_search_w, gxg_gtk_text_iter_forward_search) Xen_wrap_6_args(gxg_gtk_text_iter_backward_search_w, gxg_gtk_text_iter_backward_search) Xen_wrap_2_args(gxg_gtk_text_iter_equal_w, gxg_gtk_text_iter_equal) Xen_wrap_2_args(gxg_gtk_text_iter_compare_w, gxg_gtk_text_iter_compare) Xen_wrap_3_args(gxg_gtk_text_iter_in_range_w, gxg_gtk_text_iter_in_range) Xen_wrap_2_args(gxg_gtk_text_iter_order_w, gxg_gtk_text_iter_order) Xen_wrap_2_args(gxg_gtk_text_mark_set_visible_w, gxg_gtk_text_mark_set_visible) Xen_wrap_1_arg(gxg_gtk_text_mark_get_visible_w, gxg_gtk_text_mark_get_visible) Xen_wrap_1_arg(gxg_gtk_text_mark_get_name_w, gxg_gtk_text_mark_get_name) Xen_wrap_1_arg(gxg_gtk_text_mark_get_deleted_w, gxg_gtk_text_mark_get_deleted) Xen_wrap_1_arg(gxg_gtk_text_mark_get_buffer_w, gxg_gtk_text_mark_get_buffer) Xen_wrap_1_arg(gxg_gtk_text_mark_get_left_gravity_w, gxg_gtk_text_mark_get_left_gravity) Xen_wrap_1_arg(gxg_gtk_text_tag_new_w, gxg_gtk_text_tag_new) Xen_wrap_1_arg(gxg_gtk_text_tag_get_priority_w, gxg_gtk_text_tag_get_priority) Xen_wrap_2_args(gxg_gtk_text_tag_set_priority_w, gxg_gtk_text_tag_set_priority) Xen_wrap_4_args(gxg_gtk_text_tag_event_w, gxg_gtk_text_tag_event) Xen_wrap_no_args(gxg_gtk_text_attributes_new_w, gxg_gtk_text_attributes_new) Xen_wrap_1_arg(gxg_gtk_text_attributes_copy_w, gxg_gtk_text_attributes_copy) Xen_wrap_2_args(gxg_gtk_text_attributes_copy_values_w, gxg_gtk_text_attributes_copy_values) Xen_wrap_1_arg(gxg_gtk_text_attributes_unref_w, gxg_gtk_text_attributes_unref) Xen_wrap_no_args(gxg_gtk_text_tag_table_new_w, gxg_gtk_text_tag_table_new) Xen_wrap_2_args(gxg_gtk_text_tag_table_add_w, gxg_gtk_text_tag_table_add) Xen_wrap_2_args(gxg_gtk_text_tag_table_remove_w, gxg_gtk_text_tag_table_remove) Xen_wrap_2_args(gxg_gtk_text_tag_table_lookup_w, gxg_gtk_text_tag_table_lookup) Xen_wrap_3_optional_args(gxg_gtk_text_tag_table_foreach_w, gxg_gtk_text_tag_table_foreach) Xen_wrap_1_arg(gxg_gtk_text_tag_table_get_size_w, gxg_gtk_text_tag_table_get_size) Xen_wrap_no_args(gxg_gtk_text_view_new_w, gxg_gtk_text_view_new) Xen_wrap_1_arg(gxg_gtk_text_view_new_with_buffer_w, gxg_gtk_text_view_new_with_buffer) Xen_wrap_2_args(gxg_gtk_text_view_set_buffer_w, gxg_gtk_text_view_set_buffer) Xen_wrap_1_arg(gxg_gtk_text_view_get_buffer_w, gxg_gtk_text_view_get_buffer) Xen_wrap_6_args(gxg_gtk_text_view_scroll_to_iter_w, gxg_gtk_text_view_scroll_to_iter) Xen_wrap_6_args(gxg_gtk_text_view_scroll_to_mark_w, gxg_gtk_text_view_scroll_to_mark) Xen_wrap_2_args(gxg_gtk_text_view_scroll_mark_onscreen_w, gxg_gtk_text_view_scroll_mark_onscreen) Xen_wrap_2_args(gxg_gtk_text_view_move_mark_onscreen_w, gxg_gtk_text_view_move_mark_onscreen) Xen_wrap_1_arg(gxg_gtk_text_view_place_cursor_onscreen_w, gxg_gtk_text_view_place_cursor_onscreen) Xen_wrap_2_args(gxg_gtk_text_view_get_visible_rect_w, gxg_gtk_text_view_get_visible_rect) Xen_wrap_2_args(gxg_gtk_text_view_set_cursor_visible_w, gxg_gtk_text_view_set_cursor_visible) Xen_wrap_1_arg(gxg_gtk_text_view_get_cursor_visible_w, gxg_gtk_text_view_get_cursor_visible) Xen_wrap_3_args(gxg_gtk_text_view_get_iter_location_w, gxg_gtk_text_view_get_iter_location) Xen_wrap_4_args(gxg_gtk_text_view_get_iter_at_location_w, gxg_gtk_text_view_get_iter_at_location) Xen_wrap_4_optional_args(gxg_gtk_text_view_get_line_yrange_w, gxg_gtk_text_view_get_line_yrange) Xen_wrap_4_optional_args(gxg_gtk_text_view_get_line_at_y_w, gxg_gtk_text_view_get_line_at_y) Xen_wrap_6_optional_args(gxg_gtk_text_view_buffer_to_window_coords_w, gxg_gtk_text_view_buffer_to_window_coords) Xen_wrap_6_optional_args(gxg_gtk_text_view_window_to_buffer_coords_w, gxg_gtk_text_view_window_to_buffer_coords) Xen_wrap_2_args(gxg_gtk_text_view_get_window_w, gxg_gtk_text_view_get_window) Xen_wrap_2_args(gxg_gtk_text_view_get_window_type_w, gxg_gtk_text_view_get_window_type) Xen_wrap_3_args(gxg_gtk_text_view_set_border_window_size_w, gxg_gtk_text_view_set_border_window_size) Xen_wrap_2_args(gxg_gtk_text_view_get_border_window_size_w, gxg_gtk_text_view_get_border_window_size) Xen_wrap_2_args(gxg_gtk_text_view_forward_display_line_w, gxg_gtk_text_view_forward_display_line) Xen_wrap_2_args(gxg_gtk_text_view_backward_display_line_w, gxg_gtk_text_view_backward_display_line) Xen_wrap_2_args(gxg_gtk_text_view_forward_display_line_end_w, gxg_gtk_text_view_forward_display_line_end) Xen_wrap_2_args(gxg_gtk_text_view_backward_display_line_start_w, gxg_gtk_text_view_backward_display_line_start) Xen_wrap_2_args(gxg_gtk_text_view_starts_display_line_w, gxg_gtk_text_view_starts_display_line) Xen_wrap_3_args(gxg_gtk_text_view_move_visually_w, gxg_gtk_text_view_move_visually) Xen_wrap_3_args(gxg_gtk_text_view_add_child_at_anchor_w, gxg_gtk_text_view_add_child_at_anchor) Xen_wrap_5_args(gxg_gtk_text_view_add_child_in_window_w, gxg_gtk_text_view_add_child_in_window) Xen_wrap_4_args(gxg_gtk_text_view_move_child_w, gxg_gtk_text_view_move_child) Xen_wrap_2_args(gxg_gtk_text_view_set_wrap_mode_w, gxg_gtk_text_view_set_wrap_mode) Xen_wrap_1_arg(gxg_gtk_text_view_get_wrap_mode_w, gxg_gtk_text_view_get_wrap_mode) Xen_wrap_2_args(gxg_gtk_text_view_set_editable_w, gxg_gtk_text_view_set_editable) Xen_wrap_1_arg(gxg_gtk_text_view_get_editable_w, gxg_gtk_text_view_get_editable) Xen_wrap_2_args(gxg_gtk_text_view_set_pixels_above_lines_w, gxg_gtk_text_view_set_pixels_above_lines) Xen_wrap_1_arg(gxg_gtk_text_view_get_pixels_above_lines_w, gxg_gtk_text_view_get_pixels_above_lines) Xen_wrap_2_args(gxg_gtk_text_view_set_pixels_below_lines_w, gxg_gtk_text_view_set_pixels_below_lines) Xen_wrap_1_arg(gxg_gtk_text_view_get_pixels_below_lines_w, gxg_gtk_text_view_get_pixels_below_lines) Xen_wrap_2_args(gxg_gtk_text_view_set_pixels_inside_wrap_w, gxg_gtk_text_view_set_pixels_inside_wrap) Xen_wrap_1_arg(gxg_gtk_text_view_get_pixels_inside_wrap_w, gxg_gtk_text_view_get_pixels_inside_wrap) Xen_wrap_2_args(gxg_gtk_text_view_set_justification_w, gxg_gtk_text_view_set_justification) Xen_wrap_1_arg(gxg_gtk_text_view_get_justification_w, gxg_gtk_text_view_get_justification) Xen_wrap_2_args(gxg_gtk_text_view_set_left_margin_w, gxg_gtk_text_view_set_left_margin) Xen_wrap_1_arg(gxg_gtk_text_view_get_left_margin_w, gxg_gtk_text_view_get_left_margin) Xen_wrap_2_args(gxg_gtk_text_view_set_right_margin_w, gxg_gtk_text_view_set_right_margin) Xen_wrap_1_arg(gxg_gtk_text_view_get_right_margin_w, gxg_gtk_text_view_get_right_margin) Xen_wrap_2_args(gxg_gtk_text_view_set_indent_w, gxg_gtk_text_view_set_indent) Xen_wrap_1_arg(gxg_gtk_text_view_get_indent_w, gxg_gtk_text_view_get_indent) Xen_wrap_2_args(gxg_gtk_text_view_set_tabs_w, gxg_gtk_text_view_set_tabs) Xen_wrap_1_arg(gxg_gtk_text_view_get_tabs_w, gxg_gtk_text_view_get_tabs) Xen_wrap_1_arg(gxg_gtk_text_view_get_default_attributes_w, gxg_gtk_text_view_get_default_attributes) Xen_wrap_no_args(gxg_gtk_toggle_button_new_w, gxg_gtk_toggle_button_new) Xen_wrap_1_arg(gxg_gtk_toggle_button_new_with_label_w, gxg_gtk_toggle_button_new_with_label) Xen_wrap_1_arg(gxg_gtk_toggle_button_new_with_mnemonic_w, gxg_gtk_toggle_button_new_with_mnemonic) Xen_wrap_2_args(gxg_gtk_toggle_button_set_mode_w, gxg_gtk_toggle_button_set_mode) Xen_wrap_1_arg(gxg_gtk_toggle_button_get_mode_w, gxg_gtk_toggle_button_get_mode) Xen_wrap_2_args(gxg_gtk_toggle_button_set_active_w, gxg_gtk_toggle_button_set_active) Xen_wrap_1_arg(gxg_gtk_toggle_button_get_active_w, gxg_gtk_toggle_button_get_active) Xen_wrap_1_arg(gxg_gtk_toggle_button_toggled_w, gxg_gtk_toggle_button_toggled) Xen_wrap_2_args(gxg_gtk_toggle_button_set_inconsistent_w, gxg_gtk_toggle_button_set_inconsistent) Xen_wrap_1_arg(gxg_gtk_toggle_button_get_inconsistent_w, gxg_gtk_toggle_button_get_inconsistent) Xen_wrap_no_args(gxg_gtk_toolbar_new_w, gxg_gtk_toolbar_new) Xen_wrap_2_args(gxg_gtk_toolbar_set_style_w, gxg_gtk_toolbar_set_style) Xen_wrap_1_arg(gxg_gtk_toolbar_unset_style_w, gxg_gtk_toolbar_unset_style) Xen_wrap_1_arg(gxg_gtk_toolbar_get_style_w, gxg_gtk_toolbar_get_style) Xen_wrap_2_args(gxg_gtk_tree_drag_source_row_draggable_w, gxg_gtk_tree_drag_source_row_draggable) Xen_wrap_2_args(gxg_gtk_tree_drag_source_drag_data_delete_w, gxg_gtk_tree_drag_source_drag_data_delete) Xen_wrap_3_args(gxg_gtk_tree_drag_source_drag_data_get_w, gxg_gtk_tree_drag_source_drag_data_get) Xen_wrap_3_args(gxg_gtk_tree_drag_dest_drag_data_received_w, gxg_gtk_tree_drag_dest_drag_data_received) Xen_wrap_3_args(gxg_gtk_tree_drag_dest_row_drop_possible_w, gxg_gtk_tree_drag_dest_row_drop_possible) Xen_wrap_3_args(gxg_gtk_tree_set_row_drag_data_w, gxg_gtk_tree_set_row_drag_data) Xen_wrap_3_optional_args(gxg_gtk_tree_get_row_drag_data_w, gxg_gtk_tree_get_row_drag_data) Xen_wrap_no_args(gxg_gtk_tree_path_new_w, gxg_gtk_tree_path_new) Xen_wrap_1_arg(gxg_gtk_tree_path_new_from_string_w, gxg_gtk_tree_path_new_from_string) Xen_wrap_1_arg(gxg_gtk_tree_path_to_string_w, gxg_gtk_tree_path_to_string) Xen_wrap_no_args(gxg_gtk_tree_path_new_first_w, gxg_gtk_tree_path_new_first) Xen_wrap_2_args(gxg_gtk_tree_path_append_index_w, gxg_gtk_tree_path_append_index) Xen_wrap_2_args(gxg_gtk_tree_path_prepend_index_w, gxg_gtk_tree_path_prepend_index) Xen_wrap_1_arg(gxg_gtk_tree_path_get_depth_w, gxg_gtk_tree_path_get_depth) Xen_wrap_1_arg(gxg_gtk_tree_path_get_indices_w, gxg_gtk_tree_path_get_indices) Xen_wrap_1_arg(gxg_gtk_tree_path_free_w, gxg_gtk_tree_path_free) Xen_wrap_1_arg(gxg_gtk_tree_path_copy_w, gxg_gtk_tree_path_copy) Xen_wrap_2_args(gxg_gtk_tree_path_compare_w, gxg_gtk_tree_path_compare) Xen_wrap_1_arg(gxg_gtk_tree_path_next_w, gxg_gtk_tree_path_next) Xen_wrap_1_arg(gxg_gtk_tree_path_prev_w, gxg_gtk_tree_path_prev) Xen_wrap_1_arg(gxg_gtk_tree_path_up_w, gxg_gtk_tree_path_up) Xen_wrap_1_arg(gxg_gtk_tree_path_down_w, gxg_gtk_tree_path_down) Xen_wrap_2_args(gxg_gtk_tree_path_is_ancestor_w, gxg_gtk_tree_path_is_ancestor) Xen_wrap_2_args(gxg_gtk_tree_path_is_descendant_w, gxg_gtk_tree_path_is_descendant) Xen_wrap_2_args(gxg_gtk_tree_row_reference_new_w, gxg_gtk_tree_row_reference_new) Xen_wrap_3_args(gxg_gtk_tree_row_reference_new_proxy_w, gxg_gtk_tree_row_reference_new_proxy) Xen_wrap_1_arg(gxg_gtk_tree_row_reference_get_path_w, gxg_gtk_tree_row_reference_get_path) Xen_wrap_1_arg(gxg_gtk_tree_row_reference_valid_w, gxg_gtk_tree_row_reference_valid) Xen_wrap_1_arg(gxg_gtk_tree_row_reference_free_w, gxg_gtk_tree_row_reference_free) Xen_wrap_2_args(gxg_gtk_tree_row_reference_inserted_w, gxg_gtk_tree_row_reference_inserted) Xen_wrap_2_args(gxg_gtk_tree_row_reference_deleted_w, gxg_gtk_tree_row_reference_deleted) Xen_wrap_4_args(gxg_gtk_tree_row_reference_reordered_w, gxg_gtk_tree_row_reference_reordered) Xen_wrap_1_arg(gxg_gtk_tree_iter_copy_w, gxg_gtk_tree_iter_copy) Xen_wrap_1_arg(gxg_gtk_tree_iter_free_w, gxg_gtk_tree_iter_free) Xen_wrap_1_arg(gxg_gtk_tree_model_get_flags_w, gxg_gtk_tree_model_get_flags) Xen_wrap_1_arg(gxg_gtk_tree_model_get_n_columns_w, gxg_gtk_tree_model_get_n_columns) Xen_wrap_2_args(gxg_gtk_tree_model_get_column_type_w, gxg_gtk_tree_model_get_column_type) Xen_wrap_3_args(gxg_gtk_tree_model_get_iter_w, gxg_gtk_tree_model_get_iter) Xen_wrap_3_args(gxg_gtk_tree_model_get_iter_from_string_w, gxg_gtk_tree_model_get_iter_from_string) Xen_wrap_2_args(gxg_gtk_tree_model_get_iter_first_w, gxg_gtk_tree_model_get_iter_first) Xen_wrap_2_args(gxg_gtk_tree_model_get_path_w, gxg_gtk_tree_model_get_path) Xen_wrap_2_args(gxg_gtk_tree_model_iter_next_w, gxg_gtk_tree_model_iter_next) Xen_wrap_3_args(gxg_gtk_tree_model_iter_children_w, gxg_gtk_tree_model_iter_children) Xen_wrap_2_args(gxg_gtk_tree_model_iter_has_child_w, gxg_gtk_tree_model_iter_has_child) Xen_wrap_2_args(gxg_gtk_tree_model_iter_n_children_w, gxg_gtk_tree_model_iter_n_children) Xen_wrap_4_args(gxg_gtk_tree_model_iter_nth_child_w, gxg_gtk_tree_model_iter_nth_child) Xen_wrap_3_args(gxg_gtk_tree_model_iter_parent_w, gxg_gtk_tree_model_iter_parent) Xen_wrap_2_args(gxg_gtk_tree_model_ref_node_w, gxg_gtk_tree_model_ref_node) Xen_wrap_2_args(gxg_gtk_tree_model_unref_node_w, gxg_gtk_tree_model_unref_node) Xen_wrap_3_optional_args(gxg_gtk_tree_model_foreach_w, gxg_gtk_tree_model_foreach) Xen_wrap_3_args(gxg_gtk_tree_model_row_changed_w, gxg_gtk_tree_model_row_changed) Xen_wrap_3_args(gxg_gtk_tree_model_row_inserted_w, gxg_gtk_tree_model_row_inserted) Xen_wrap_3_args(gxg_gtk_tree_model_row_has_child_toggled_w, gxg_gtk_tree_model_row_has_child_toggled) Xen_wrap_2_args(gxg_gtk_tree_model_row_deleted_w, gxg_gtk_tree_model_row_deleted) Xen_wrap_4_args(gxg_gtk_tree_model_rows_reordered_w, gxg_gtk_tree_model_rows_reordered) Xen_wrap_1_arg(gxg_gtk_tree_model_sort_new_with_model_w, gxg_gtk_tree_model_sort_new_with_model) Xen_wrap_1_arg(gxg_gtk_tree_model_sort_get_model_w, gxg_gtk_tree_model_sort_get_model) Xen_wrap_2_args(gxg_gtk_tree_model_sort_convert_child_path_to_path_w, gxg_gtk_tree_model_sort_convert_child_path_to_path) Xen_wrap_3_args(gxg_gtk_tree_model_sort_convert_child_iter_to_iter_w, gxg_gtk_tree_model_sort_convert_child_iter_to_iter) Xen_wrap_2_args(gxg_gtk_tree_model_sort_convert_path_to_child_path_w, gxg_gtk_tree_model_sort_convert_path_to_child_path) Xen_wrap_3_args(gxg_gtk_tree_model_sort_convert_iter_to_child_iter_w, gxg_gtk_tree_model_sort_convert_iter_to_child_iter) Xen_wrap_1_arg(gxg_gtk_tree_model_sort_reset_default_sort_func_w, gxg_gtk_tree_model_sort_reset_default_sort_func) Xen_wrap_1_arg(gxg_gtk_tree_model_sort_clear_cache_w, gxg_gtk_tree_model_sort_clear_cache) Xen_wrap_2_args(gxg_gtk_tree_selection_set_mode_w, gxg_gtk_tree_selection_set_mode) Xen_wrap_1_arg(gxg_gtk_tree_selection_get_mode_w, gxg_gtk_tree_selection_get_mode) Xen_wrap_4_args(gxg_gtk_tree_selection_set_select_function_w, gxg_gtk_tree_selection_set_select_function) Xen_wrap_1_arg(gxg_gtk_tree_selection_get_user_data_w, gxg_gtk_tree_selection_get_user_data) Xen_wrap_1_arg(gxg_gtk_tree_selection_get_tree_view_w, gxg_gtk_tree_selection_get_tree_view) Xen_wrap_3_args(gxg_gtk_tree_selection_get_selected_w, gxg_gtk_tree_selection_get_selected) Xen_wrap_3_optional_args(gxg_gtk_tree_selection_selected_foreach_w, gxg_gtk_tree_selection_selected_foreach) Xen_wrap_2_args(gxg_gtk_tree_selection_select_path_w, gxg_gtk_tree_selection_select_path) Xen_wrap_2_args(gxg_gtk_tree_selection_unselect_path_w, gxg_gtk_tree_selection_unselect_path) Xen_wrap_2_args(gxg_gtk_tree_selection_select_iter_w, gxg_gtk_tree_selection_select_iter) Xen_wrap_2_args(gxg_gtk_tree_selection_unselect_iter_w, gxg_gtk_tree_selection_unselect_iter) Xen_wrap_2_args(gxg_gtk_tree_selection_path_is_selected_w, gxg_gtk_tree_selection_path_is_selected) Xen_wrap_2_args(gxg_gtk_tree_selection_iter_is_selected_w, gxg_gtk_tree_selection_iter_is_selected) Xen_wrap_1_arg(gxg_gtk_tree_selection_select_all_w, gxg_gtk_tree_selection_select_all) Xen_wrap_1_arg(gxg_gtk_tree_selection_unselect_all_w, gxg_gtk_tree_selection_unselect_all) Xen_wrap_3_args(gxg_gtk_tree_selection_select_range_w, gxg_gtk_tree_selection_select_range) Xen_wrap_1_arg(gxg_gtk_tree_sortable_sort_column_changed_w, gxg_gtk_tree_sortable_sort_column_changed) Xen_wrap_3_optional_args(gxg_gtk_tree_sortable_get_sort_column_id_w, gxg_gtk_tree_sortable_get_sort_column_id) Xen_wrap_3_args(gxg_gtk_tree_sortable_set_sort_column_id_w, gxg_gtk_tree_sortable_set_sort_column_id) Xen_wrap_5_args(gxg_gtk_tree_sortable_set_sort_func_w, gxg_gtk_tree_sortable_set_sort_func) Xen_wrap_4_args(gxg_gtk_tree_sortable_set_default_sort_func_w, gxg_gtk_tree_sortable_set_default_sort_func) Xen_wrap_1_arg(gxg_gtk_tree_sortable_has_default_sort_func_w, gxg_gtk_tree_sortable_has_default_sort_func) Xen_wrap_2_args(gxg_gtk_tree_store_new_w, gxg_gtk_tree_store_new) Xen_wrap_2_args(gxg_gtk_tree_store_newv_w, gxg_gtk_tree_store_newv) Xen_wrap_3_args(gxg_gtk_tree_store_set_column_types_w, gxg_gtk_tree_store_set_column_types) Xen_wrap_3_args(gxg_gtk_tree_store_set_w, gxg_gtk_tree_store_set) Xen_wrap_2_args(gxg_gtk_tree_store_remove_w, gxg_gtk_tree_store_remove) Xen_wrap_4_args(gxg_gtk_tree_store_insert_w, gxg_gtk_tree_store_insert) Xen_wrap_4_args(gxg_gtk_tree_store_insert_before_w, gxg_gtk_tree_store_insert_before) Xen_wrap_4_args(gxg_gtk_tree_store_insert_after_w, gxg_gtk_tree_store_insert_after) Xen_wrap_3_args(gxg_gtk_tree_store_prepend_w, gxg_gtk_tree_store_prepend) Xen_wrap_3_args(gxg_gtk_tree_store_append_w, gxg_gtk_tree_store_append) Xen_wrap_3_args(gxg_gtk_tree_store_is_ancestor_w, gxg_gtk_tree_store_is_ancestor) Xen_wrap_2_args(gxg_gtk_tree_store_iter_depth_w, gxg_gtk_tree_store_iter_depth) Xen_wrap_1_arg(gxg_gtk_tree_store_clear_w, gxg_gtk_tree_store_clear) Xen_wrap_no_args(gxg_gtk_tree_view_column_new_w, gxg_gtk_tree_view_column_new) Xen_wrap_3_args(gxg_gtk_tree_view_column_new_with_attributes_w, gxg_gtk_tree_view_column_new_with_attributes) Xen_wrap_3_args(gxg_gtk_tree_view_column_pack_start_w, gxg_gtk_tree_view_column_pack_start) Xen_wrap_3_args(gxg_gtk_tree_view_column_pack_end_w, gxg_gtk_tree_view_column_pack_end) Xen_wrap_1_arg(gxg_gtk_tree_view_column_clear_w, gxg_gtk_tree_view_column_clear) Xen_wrap_4_args(gxg_gtk_tree_view_column_add_attribute_w, gxg_gtk_tree_view_column_add_attribute) Xen_wrap_3_args(gxg_gtk_tree_view_column_set_attributes_w, gxg_gtk_tree_view_column_set_attributes) Xen_wrap_5_args(gxg_gtk_tree_view_column_set_cell_data_func_w, gxg_gtk_tree_view_column_set_cell_data_func) Xen_wrap_2_args(gxg_gtk_tree_view_column_clear_attributes_w, gxg_gtk_tree_view_column_clear_attributes) Xen_wrap_2_args(gxg_gtk_tree_view_column_set_spacing_w, gxg_gtk_tree_view_column_set_spacing) Xen_wrap_1_arg(gxg_gtk_tree_view_column_get_spacing_w, gxg_gtk_tree_view_column_get_spacing) Xen_wrap_2_args(gxg_gtk_tree_view_column_set_visible_w, gxg_gtk_tree_view_column_set_visible) Xen_wrap_1_arg(gxg_gtk_tree_view_column_get_visible_w, gxg_gtk_tree_view_column_get_visible) Xen_wrap_2_args(gxg_gtk_tree_view_column_set_resizable_w, gxg_gtk_tree_view_column_set_resizable) Xen_wrap_1_arg(gxg_gtk_tree_view_column_get_resizable_w, gxg_gtk_tree_view_column_get_resizable) Xen_wrap_2_args(gxg_gtk_tree_view_column_set_sizing_w, gxg_gtk_tree_view_column_set_sizing) Xen_wrap_1_arg(gxg_gtk_tree_view_column_get_sizing_w, gxg_gtk_tree_view_column_get_sizing) Xen_wrap_1_arg(gxg_gtk_tree_view_column_get_width_w, gxg_gtk_tree_view_column_get_width) Xen_wrap_1_arg(gxg_gtk_tree_view_column_get_fixed_width_w, gxg_gtk_tree_view_column_get_fixed_width) Xen_wrap_2_args(gxg_gtk_tree_view_column_set_fixed_width_w, gxg_gtk_tree_view_column_set_fixed_width) Xen_wrap_2_args(gxg_gtk_tree_view_column_set_min_width_w, gxg_gtk_tree_view_column_set_min_width) Xen_wrap_1_arg(gxg_gtk_tree_view_column_get_min_width_w, gxg_gtk_tree_view_column_get_min_width) Xen_wrap_2_args(gxg_gtk_tree_view_column_set_max_width_w, gxg_gtk_tree_view_column_set_max_width) Xen_wrap_1_arg(gxg_gtk_tree_view_column_get_max_width_w, gxg_gtk_tree_view_column_get_max_width) Xen_wrap_1_arg(gxg_gtk_tree_view_column_clicked_w, gxg_gtk_tree_view_column_clicked) Xen_wrap_2_args(gxg_gtk_tree_view_column_set_title_w, gxg_gtk_tree_view_column_set_title) Xen_wrap_1_arg(gxg_gtk_tree_view_column_get_title_w, gxg_gtk_tree_view_column_get_title) Xen_wrap_2_args(gxg_gtk_tree_view_column_set_clickable_w, gxg_gtk_tree_view_column_set_clickable) Xen_wrap_1_arg(gxg_gtk_tree_view_column_get_clickable_w, gxg_gtk_tree_view_column_get_clickable) Xen_wrap_2_args(gxg_gtk_tree_view_column_set_widget_w, gxg_gtk_tree_view_column_set_widget) Xen_wrap_1_arg(gxg_gtk_tree_view_column_get_widget_w, gxg_gtk_tree_view_column_get_widget) Xen_wrap_2_args(gxg_gtk_tree_view_column_set_alignment_w, gxg_gtk_tree_view_column_set_alignment) Xen_wrap_1_arg(gxg_gtk_tree_view_column_get_alignment_w, gxg_gtk_tree_view_column_get_alignment) Xen_wrap_2_args(gxg_gtk_tree_view_column_set_reorderable_w, gxg_gtk_tree_view_column_set_reorderable) Xen_wrap_1_arg(gxg_gtk_tree_view_column_get_reorderable_w, gxg_gtk_tree_view_column_get_reorderable) Xen_wrap_2_args(gxg_gtk_tree_view_column_set_sort_column_id_w, gxg_gtk_tree_view_column_set_sort_column_id) Xen_wrap_1_arg(gxg_gtk_tree_view_column_get_sort_column_id_w, gxg_gtk_tree_view_column_get_sort_column_id) Xen_wrap_2_args(gxg_gtk_tree_view_column_set_sort_indicator_w, gxg_gtk_tree_view_column_set_sort_indicator) Xen_wrap_1_arg(gxg_gtk_tree_view_column_get_sort_indicator_w, gxg_gtk_tree_view_column_get_sort_indicator) Xen_wrap_2_args(gxg_gtk_tree_view_column_set_sort_order_w, gxg_gtk_tree_view_column_set_sort_order) Xen_wrap_1_arg(gxg_gtk_tree_view_column_get_sort_order_w, gxg_gtk_tree_view_column_get_sort_order) Xen_wrap_5_args(gxg_gtk_tree_view_column_cell_set_cell_data_w, gxg_gtk_tree_view_column_cell_set_cell_data) Xen_wrap_6_optional_args(gxg_gtk_tree_view_column_cell_get_size_w, gxg_gtk_tree_view_column_cell_get_size) Xen_wrap_1_arg(gxg_gtk_tree_view_column_cell_is_visible_w, gxg_gtk_tree_view_column_cell_is_visible) Xen_wrap_4_optional_args(gxg_gtk_tree_view_column_cell_get_position_w, gxg_gtk_tree_view_column_cell_get_position) Xen_wrap_no_args(gxg_gtk_tree_view_new_w, gxg_gtk_tree_view_new) Xen_wrap_1_arg(gxg_gtk_tree_view_new_with_model_w, gxg_gtk_tree_view_new_with_model) Xen_wrap_1_arg(gxg_gtk_tree_view_get_model_w, gxg_gtk_tree_view_get_model) Xen_wrap_2_args(gxg_gtk_tree_view_set_model_w, gxg_gtk_tree_view_set_model) Xen_wrap_1_arg(gxg_gtk_tree_view_get_selection_w, gxg_gtk_tree_view_get_selection) Xen_wrap_1_arg(gxg_gtk_tree_view_get_headers_visible_w, gxg_gtk_tree_view_get_headers_visible) Xen_wrap_2_args(gxg_gtk_tree_view_set_headers_visible_w, gxg_gtk_tree_view_set_headers_visible) Xen_wrap_1_arg(gxg_gtk_tree_view_columns_autosize_w, gxg_gtk_tree_view_columns_autosize) Xen_wrap_2_args(gxg_gtk_tree_view_set_headers_clickable_w, gxg_gtk_tree_view_set_headers_clickable) Xen_wrap_2_args(gxg_gtk_tree_view_append_column_w, gxg_gtk_tree_view_append_column) Xen_wrap_2_args(gxg_gtk_tree_view_remove_column_w, gxg_gtk_tree_view_remove_column) Xen_wrap_3_args(gxg_gtk_tree_view_insert_column_w, gxg_gtk_tree_view_insert_column) Xen_wrap_5_args(gxg_gtk_tree_view_insert_column_with_attributes_w, gxg_gtk_tree_view_insert_column_with_attributes) Xen_wrap_7_args(gxg_gtk_tree_view_insert_column_with_data_func_w, gxg_gtk_tree_view_insert_column_with_data_func) Xen_wrap_2_args(gxg_gtk_tree_view_get_column_w, gxg_gtk_tree_view_get_column) Xen_wrap_1_arg(gxg_gtk_tree_view_get_columns_w, gxg_gtk_tree_view_get_columns) Xen_wrap_3_args(gxg_gtk_tree_view_move_column_after_w, gxg_gtk_tree_view_move_column_after) Xen_wrap_2_args(gxg_gtk_tree_view_set_expander_column_w, gxg_gtk_tree_view_set_expander_column) Xen_wrap_1_arg(gxg_gtk_tree_view_get_expander_column_w, gxg_gtk_tree_view_get_expander_column) Xen_wrap_4_args(gxg_gtk_tree_view_set_column_drag_function_w, gxg_gtk_tree_view_set_column_drag_function) Xen_wrap_3_args(gxg_gtk_tree_view_scroll_to_point_w, gxg_gtk_tree_view_scroll_to_point) Xen_wrap_6_args(gxg_gtk_tree_view_scroll_to_cell_w, gxg_gtk_tree_view_scroll_to_cell) Xen_wrap_3_args(gxg_gtk_tree_view_row_activated_w, gxg_gtk_tree_view_row_activated) Xen_wrap_1_arg(gxg_gtk_tree_view_expand_all_w, gxg_gtk_tree_view_expand_all) Xen_wrap_1_arg(gxg_gtk_tree_view_collapse_all_w, gxg_gtk_tree_view_collapse_all) Xen_wrap_3_args(gxg_gtk_tree_view_expand_row_w, gxg_gtk_tree_view_expand_row) Xen_wrap_2_args(gxg_gtk_tree_view_collapse_row_w, gxg_gtk_tree_view_collapse_row) Xen_wrap_3_optional_args(gxg_gtk_tree_view_map_expanded_rows_w, gxg_gtk_tree_view_map_expanded_rows) Xen_wrap_2_args(gxg_gtk_tree_view_row_expanded_w, gxg_gtk_tree_view_row_expanded) Xen_wrap_2_args(gxg_gtk_tree_view_set_reorderable_w, gxg_gtk_tree_view_set_reorderable) Xen_wrap_1_arg(gxg_gtk_tree_view_get_reorderable_w, gxg_gtk_tree_view_get_reorderable) Xen_wrap_4_args(gxg_gtk_tree_view_set_cursor_w, gxg_gtk_tree_view_set_cursor) Xen_wrap_3_optional_args(gxg_gtk_tree_view_get_cursor_w, gxg_gtk_tree_view_get_cursor) Xen_wrap_1_arg(gxg_gtk_tree_view_get_bin_window_w, gxg_gtk_tree_view_get_bin_window) Xen_wrap_7_optional_args(gxg_gtk_tree_view_get_path_at_pos_w, gxg_gtk_tree_view_get_path_at_pos) Xen_wrap_4_args(gxg_gtk_tree_view_get_cell_area_w, gxg_gtk_tree_view_get_cell_area) Xen_wrap_4_args(gxg_gtk_tree_view_get_background_area_w, gxg_gtk_tree_view_get_background_area) Xen_wrap_2_args(gxg_gtk_tree_view_get_visible_rect_w, gxg_gtk_tree_view_get_visible_rect) Xen_wrap_5_args(gxg_gtk_tree_view_enable_model_drag_source_w, gxg_gtk_tree_view_enable_model_drag_source) Xen_wrap_4_args(gxg_gtk_tree_view_enable_model_drag_dest_w, gxg_gtk_tree_view_enable_model_drag_dest) Xen_wrap_1_arg(gxg_gtk_tree_view_unset_rows_drag_source_w, gxg_gtk_tree_view_unset_rows_drag_source) Xen_wrap_1_arg(gxg_gtk_tree_view_unset_rows_drag_dest_w, gxg_gtk_tree_view_unset_rows_drag_dest) Xen_wrap_3_args(gxg_gtk_tree_view_set_drag_dest_row_w, gxg_gtk_tree_view_set_drag_dest_row) Xen_wrap_3_optional_args(gxg_gtk_tree_view_get_drag_dest_row_w, gxg_gtk_tree_view_get_drag_dest_row) Xen_wrap_5_optional_args(gxg_gtk_tree_view_get_dest_row_at_pos_w, gxg_gtk_tree_view_get_dest_row_at_pos) Xen_wrap_2_args(gxg_gtk_tree_view_set_enable_search_w, gxg_gtk_tree_view_set_enable_search) Xen_wrap_1_arg(gxg_gtk_tree_view_get_enable_search_w, gxg_gtk_tree_view_get_enable_search) Xen_wrap_1_arg(gxg_gtk_tree_view_get_search_column_w, gxg_gtk_tree_view_get_search_column) Xen_wrap_2_args(gxg_gtk_tree_view_set_search_column_w, gxg_gtk_tree_view_set_search_column) Xen_wrap_1_arg(gxg_gtk_tree_view_get_search_equal_func_w, gxg_gtk_tree_view_get_search_equal_func) Xen_wrap_4_args(gxg_gtk_tree_view_set_search_equal_func_w, gxg_gtk_tree_view_set_search_equal_func) Xen_wrap_2_args(gxg_gtk_viewport_new_w, gxg_gtk_viewport_new) Xen_wrap_2_args(gxg_gtk_viewport_set_shadow_type_w, gxg_gtk_viewport_set_shadow_type) Xen_wrap_1_arg(gxg_gtk_viewport_get_shadow_type_w, gxg_gtk_viewport_get_shadow_type) Xen_wrap_1_arg(gxg_gtk_widget_destroy_w, gxg_gtk_widget_destroy) Xen_wrap_2_optional_args(gxg_gtk_widget_destroyed_w, gxg_gtk_widget_destroyed) Xen_wrap_1_arg(gxg_gtk_widget_unparent_w, gxg_gtk_widget_unparent) Xen_wrap_1_arg(gxg_gtk_widget_show_w, gxg_gtk_widget_show) Xen_wrap_1_arg(gxg_gtk_widget_show_now_w, gxg_gtk_widget_show_now) Xen_wrap_1_arg(gxg_gtk_widget_hide_w, gxg_gtk_widget_hide) Xen_wrap_1_arg(gxg_gtk_widget_show_all_w, gxg_gtk_widget_show_all) Xen_wrap_1_arg(gxg_gtk_widget_map_w, gxg_gtk_widget_map) Xen_wrap_1_arg(gxg_gtk_widget_unmap_w, gxg_gtk_widget_unmap) Xen_wrap_1_arg(gxg_gtk_widget_realize_w, gxg_gtk_widget_realize) Xen_wrap_1_arg(gxg_gtk_widget_unrealize_w, gxg_gtk_widget_unrealize) Xen_wrap_1_arg(gxg_gtk_widget_queue_draw_w, gxg_gtk_widget_queue_draw) Xen_wrap_5_args(gxg_gtk_widget_queue_draw_area_w, gxg_gtk_widget_queue_draw_area) Xen_wrap_1_arg(gxg_gtk_widget_queue_resize_w, gxg_gtk_widget_queue_resize) Xen_wrap_2_args(gxg_gtk_widget_size_allocate_w, gxg_gtk_widget_size_allocate) Xen_wrap_6_args(gxg_gtk_widget_add_accelerator_w, gxg_gtk_widget_add_accelerator) Xen_wrap_4_args(gxg_gtk_widget_remove_accelerator_w, gxg_gtk_widget_remove_accelerator) Xen_wrap_1_arg(gxg_gtk_widget_list_accel_closures_w, gxg_gtk_widget_list_accel_closures) Xen_wrap_2_args(gxg_gtk_widget_mnemonic_activate_w, gxg_gtk_widget_mnemonic_activate) Xen_wrap_2_args(gxg_gtk_widget_event_w, gxg_gtk_widget_event) Xen_wrap_2_args(gxg_gtk_widget_send_expose_w, gxg_gtk_widget_send_expose) Xen_wrap_1_arg(gxg_gtk_widget_activate_w, gxg_gtk_widget_activate) Xen_wrap_3_args(gxg_gtk_widget_intersect_w, gxg_gtk_widget_intersect) Xen_wrap_1_arg(gxg_gtk_widget_freeze_child_notify_w, gxg_gtk_widget_freeze_child_notify) Xen_wrap_2_args(gxg_gtk_widget_child_notify_w, gxg_gtk_widget_child_notify) Xen_wrap_1_arg(gxg_gtk_widget_thaw_child_notify_w, gxg_gtk_widget_thaw_child_notify) Xen_wrap_1_arg(gxg_gtk_widget_is_focus_w, gxg_gtk_widget_is_focus) Xen_wrap_1_arg(gxg_gtk_widget_grab_focus_w, gxg_gtk_widget_grab_focus) Xen_wrap_1_arg(gxg_gtk_widget_grab_default_w, gxg_gtk_widget_grab_default) Xen_wrap_2_args(gxg_gtk_widget_set_name_w, gxg_gtk_widget_set_name) Xen_wrap_1_arg(gxg_gtk_widget_get_name_w, gxg_gtk_widget_get_name) Xen_wrap_2_args(gxg_gtk_widget_set_sensitive_w, gxg_gtk_widget_set_sensitive) Xen_wrap_2_args(gxg_gtk_widget_set_app_paintable_w, gxg_gtk_widget_set_app_paintable) Xen_wrap_2_args(gxg_gtk_widget_set_redraw_on_allocate_w, gxg_gtk_widget_set_redraw_on_allocate) Xen_wrap_2_args(gxg_gtk_widget_set_parent_w, gxg_gtk_widget_set_parent) Xen_wrap_2_args(gxg_gtk_widget_set_parent_window_w, gxg_gtk_widget_set_parent_window) Xen_wrap_2_args(gxg_gtk_widget_set_child_visible_w, gxg_gtk_widget_set_child_visible) Xen_wrap_3_args(gxg_gtk_widget_set_accel_path_w, gxg_gtk_widget_set_accel_path) Xen_wrap_1_arg(gxg_gtk_widget_get_child_visible_w, gxg_gtk_widget_get_child_visible) Xen_wrap_1_arg(gxg_gtk_widget_get_parent_w, gxg_gtk_widget_get_parent) Xen_wrap_1_arg(gxg_gtk_widget_get_parent_window_w, gxg_gtk_widget_get_parent_window) Xen_wrap_2_args(gxg_gtk_widget_child_focus_w, gxg_gtk_widget_child_focus) Xen_wrap_3_args(gxg_gtk_widget_set_size_request_w, gxg_gtk_widget_set_size_request) Xen_wrap_3_optional_args(gxg_gtk_widget_get_size_request_w, gxg_gtk_widget_get_size_request) Xen_wrap_2_args(gxg_gtk_widget_set_events_w, gxg_gtk_widget_set_events) Xen_wrap_2_args(gxg_gtk_widget_add_events_w, gxg_gtk_widget_add_events) Xen_wrap_1_arg(gxg_gtk_widget_get_toplevel_w, gxg_gtk_widget_get_toplevel) Xen_wrap_2_args(gxg_gtk_widget_get_ancestor_w, gxg_gtk_widget_get_ancestor) Xen_wrap_1_arg(gxg_gtk_widget_get_visual_w, gxg_gtk_widget_get_visual) Xen_wrap_1_arg(gxg_gtk_widget_get_settings_w, gxg_gtk_widget_get_settings) Xen_wrap_1_arg(gxg_gtk_widget_get_accessible_w, gxg_gtk_widget_get_accessible) Xen_wrap_1_arg(gxg_gtk_widget_get_events_w, gxg_gtk_widget_get_events) Xen_wrap_2_args(gxg_gtk_widget_is_ancestor_w, gxg_gtk_widget_is_ancestor) Xen_wrap_6_optional_args(gxg_gtk_widget_translate_coordinates_w, gxg_gtk_widget_translate_coordinates) Xen_wrap_1_arg(gxg_gtk_widget_hide_on_delete_w, gxg_gtk_widget_hide_on_delete) Xen_wrap_1_arg(gxg_gtk_widget_create_pango_context_w, gxg_gtk_widget_create_pango_context) Xen_wrap_1_arg(gxg_gtk_widget_get_pango_context_w, gxg_gtk_widget_get_pango_context) Xen_wrap_2_args(gxg_gtk_widget_create_pango_layout_w, gxg_gtk_widget_create_pango_layout) Xen_wrap_2_args(gxg_gtk_widget_set_direction_w, gxg_gtk_widget_set_direction) Xen_wrap_1_arg(gxg_gtk_widget_get_direction_w, gxg_gtk_widget_get_direction) Xen_wrap_1_arg(gxg_gtk_widget_set_default_direction_w, gxg_gtk_widget_set_default_direction) Xen_wrap_no_args(gxg_gtk_widget_get_default_direction_w, gxg_gtk_widget_get_default_direction) Xen_wrap_2_args(gxg_gtk_widget_can_activate_accel_w, gxg_gtk_widget_can_activate_accel) Xen_wrap_1_arg(gxg_gtk_window_is_active_w, gxg_gtk_window_is_active) Xen_wrap_1_arg(gxg_gtk_window_has_toplevel_focus_w, gxg_gtk_window_has_toplevel_focus) Xen_wrap_1_arg(gxg_gtk_window_new_w, gxg_gtk_window_new) Xen_wrap_2_args(gxg_gtk_window_set_title_w, gxg_gtk_window_set_title) Xen_wrap_1_arg(gxg_gtk_window_set_auto_startup_notification_w, gxg_gtk_window_set_auto_startup_notification) Xen_wrap_1_arg(gxg_gtk_window_get_title_w, gxg_gtk_window_get_title) Xen_wrap_3_args(gxg_gtk_window_set_wmclass_w, gxg_gtk_window_set_wmclass) Xen_wrap_2_args(gxg_gtk_window_set_role_w, gxg_gtk_window_set_role) Xen_wrap_1_arg(gxg_gtk_window_get_role_w, gxg_gtk_window_get_role) Xen_wrap_2_args(gxg_gtk_window_add_accel_group_w, gxg_gtk_window_add_accel_group) Xen_wrap_2_args(gxg_gtk_window_remove_accel_group_w, gxg_gtk_window_remove_accel_group) Xen_wrap_2_args(gxg_gtk_window_set_position_w, gxg_gtk_window_set_position) Xen_wrap_1_arg(gxg_gtk_window_activate_focus_w, gxg_gtk_window_activate_focus) Xen_wrap_2_args(gxg_gtk_window_set_focus_w, gxg_gtk_window_set_focus) Xen_wrap_1_arg(gxg_gtk_window_get_focus_w, gxg_gtk_window_get_focus) Xen_wrap_2_args(gxg_gtk_window_set_default_w, gxg_gtk_window_set_default) Xen_wrap_1_arg(gxg_gtk_window_activate_default_w, gxg_gtk_window_activate_default) Xen_wrap_2_args(gxg_gtk_window_set_transient_for_w, gxg_gtk_window_set_transient_for) Xen_wrap_1_arg(gxg_gtk_window_get_transient_for_w, gxg_gtk_window_get_transient_for) Xen_wrap_2_args(gxg_gtk_window_set_type_hint_w, gxg_gtk_window_set_type_hint) Xen_wrap_1_arg(gxg_gtk_window_get_type_hint_w, gxg_gtk_window_get_type_hint) Xen_wrap_2_args(gxg_gtk_window_set_destroy_with_parent_w, gxg_gtk_window_set_destroy_with_parent) Xen_wrap_1_arg(gxg_gtk_window_get_destroy_with_parent_w, gxg_gtk_window_get_destroy_with_parent) Xen_wrap_2_args(gxg_gtk_window_set_resizable_w, gxg_gtk_window_set_resizable) Xen_wrap_1_arg(gxg_gtk_window_get_resizable_w, gxg_gtk_window_get_resizable) Xen_wrap_2_args(gxg_gtk_window_set_gravity_w, gxg_gtk_window_set_gravity) Xen_wrap_1_arg(gxg_gtk_window_get_gravity_w, gxg_gtk_window_get_gravity) Xen_wrap_4_args(gxg_gtk_window_set_geometry_hints_w, gxg_gtk_window_set_geometry_hints) Xen_wrap_2_args(gxg_gtk_window_set_decorated_w, gxg_gtk_window_set_decorated) Xen_wrap_1_arg(gxg_gtk_window_get_decorated_w, gxg_gtk_window_get_decorated) Xen_wrap_2_args(gxg_gtk_window_set_icon_list_w, gxg_gtk_window_set_icon_list) Xen_wrap_1_arg(gxg_gtk_window_get_icon_list_w, gxg_gtk_window_get_icon_list) Xen_wrap_2_args(gxg_gtk_window_set_icon_w, gxg_gtk_window_set_icon) Xen_wrap_1_arg(gxg_gtk_window_get_icon_w, gxg_gtk_window_get_icon) Xen_wrap_1_arg(gxg_gtk_window_set_default_icon_list_w, gxg_gtk_window_set_default_icon_list) Xen_wrap_no_args(gxg_gtk_window_get_default_icon_list_w, gxg_gtk_window_get_default_icon_list) Xen_wrap_2_args(gxg_gtk_window_set_modal_w, gxg_gtk_window_set_modal) Xen_wrap_1_arg(gxg_gtk_window_get_modal_w, gxg_gtk_window_get_modal) Xen_wrap_no_args(gxg_gtk_window_list_toplevels_w, gxg_gtk_window_list_toplevels) Xen_wrap_3_args(gxg_gtk_window_add_mnemonic_w, gxg_gtk_window_add_mnemonic) Xen_wrap_3_args(gxg_gtk_window_remove_mnemonic_w, gxg_gtk_window_remove_mnemonic) Xen_wrap_3_args(gxg_gtk_window_mnemonic_activate_w, gxg_gtk_window_mnemonic_activate) Xen_wrap_2_args(gxg_gtk_window_set_mnemonic_modifier_w, gxg_gtk_window_set_mnemonic_modifier) Xen_wrap_1_arg(gxg_gtk_window_get_mnemonic_modifier_w, gxg_gtk_window_get_mnemonic_modifier) Xen_wrap_1_arg(gxg_gtk_window_present_w, gxg_gtk_window_present) Xen_wrap_1_arg(gxg_gtk_window_iconify_w, gxg_gtk_window_iconify) Xen_wrap_1_arg(gxg_gtk_window_deiconify_w, gxg_gtk_window_deiconify) Xen_wrap_1_arg(gxg_gtk_window_stick_w, gxg_gtk_window_stick) Xen_wrap_1_arg(gxg_gtk_window_unstick_w, gxg_gtk_window_unstick) Xen_wrap_1_arg(gxg_gtk_window_maximize_w, gxg_gtk_window_maximize) Xen_wrap_1_arg(gxg_gtk_window_unmaximize_w, gxg_gtk_window_unmaximize) Xen_wrap_6_args(gxg_gtk_window_begin_resize_drag_w, gxg_gtk_window_begin_resize_drag) Xen_wrap_5_args(gxg_gtk_window_begin_move_drag_w, gxg_gtk_window_begin_move_drag) Xen_wrap_3_args(gxg_gtk_window_set_default_size_w, gxg_gtk_window_set_default_size) Xen_wrap_3_optional_args(gxg_gtk_window_get_default_size_w, gxg_gtk_window_get_default_size) Xen_wrap_3_args(gxg_gtk_window_resize_w, gxg_gtk_window_resize) Xen_wrap_3_optional_args(gxg_gtk_window_get_size_w, gxg_gtk_window_get_size) Xen_wrap_3_args(gxg_gtk_window_move_w, gxg_gtk_window_move) Xen_wrap_3_optional_args(gxg_gtk_window_get_position_w, gxg_gtk_window_get_position) Xen_wrap_2_args(gxg_gtk_window_parse_geometry_w, gxg_gtk_window_parse_geometry) Xen_wrap_1_arg(gxg_pango_color_copy_w, gxg_pango_color_copy) Xen_wrap_1_arg(gxg_pango_color_free_w, gxg_pango_color_free) Xen_wrap_2_args(gxg_pango_color_parse_w, gxg_pango_color_parse) Xen_wrap_1_arg(gxg_pango_attr_type_register_w, gxg_pango_attr_type_register) Xen_wrap_1_arg(gxg_pango_attribute_copy_w, gxg_pango_attribute_copy) Xen_wrap_1_arg(gxg_pango_attribute_destroy_w, gxg_pango_attribute_destroy) Xen_wrap_2_args(gxg_pango_attribute_equal_w, gxg_pango_attribute_equal) Xen_wrap_1_arg(gxg_pango_attr_language_new_w, gxg_pango_attr_language_new) Xen_wrap_1_arg(gxg_pango_attr_family_new_w, gxg_pango_attr_family_new) Xen_wrap_3_args(gxg_pango_attr_foreground_new_w, gxg_pango_attr_foreground_new) Xen_wrap_3_args(gxg_pango_attr_background_new_w, gxg_pango_attr_background_new) Xen_wrap_1_arg(gxg_pango_attr_size_new_w, gxg_pango_attr_size_new) Xen_wrap_1_arg(gxg_pango_attr_style_new_w, gxg_pango_attr_style_new) Xen_wrap_1_arg(gxg_pango_attr_weight_new_w, gxg_pango_attr_weight_new) Xen_wrap_1_arg(gxg_pango_attr_variant_new_w, gxg_pango_attr_variant_new) Xen_wrap_1_arg(gxg_pango_attr_stretch_new_w, gxg_pango_attr_stretch_new) Xen_wrap_1_arg(gxg_pango_attr_font_desc_new_w, gxg_pango_attr_font_desc_new) Xen_wrap_1_arg(gxg_pango_attr_underline_new_w, gxg_pango_attr_underline_new) Xen_wrap_1_arg(gxg_pango_attr_strikethrough_new_w, gxg_pango_attr_strikethrough_new) Xen_wrap_1_arg(gxg_pango_attr_rise_new_w, gxg_pango_attr_rise_new) Xen_wrap_2_args(gxg_pango_attr_shape_new_w, gxg_pango_attr_shape_new) Xen_wrap_1_arg(gxg_pango_attr_scale_new_w, gxg_pango_attr_scale_new) Xen_wrap_no_args(gxg_pango_attr_list_new_w, gxg_pango_attr_list_new) Xen_wrap_1_arg(gxg_pango_attr_list_unref_w, gxg_pango_attr_list_unref) Xen_wrap_1_arg(gxg_pango_attr_list_copy_w, gxg_pango_attr_list_copy) Xen_wrap_2_args(gxg_pango_attr_list_insert_w, gxg_pango_attr_list_insert) Xen_wrap_2_args(gxg_pango_attr_list_insert_before_w, gxg_pango_attr_list_insert_before) Xen_wrap_2_args(gxg_pango_attr_list_change_w, gxg_pango_attr_list_change) Xen_wrap_4_args(gxg_pango_attr_list_splice_w, gxg_pango_attr_list_splice) Xen_wrap_1_arg(gxg_pango_attr_list_get_iterator_w, gxg_pango_attr_list_get_iterator) Xen_wrap_3_optional_args(gxg_pango_attr_iterator_range_w, gxg_pango_attr_iterator_range) Xen_wrap_1_arg(gxg_pango_attr_iterator_next_w, gxg_pango_attr_iterator_next) Xen_wrap_1_arg(gxg_pango_attr_iterator_copy_w, gxg_pango_attr_iterator_copy) Xen_wrap_1_arg(gxg_pango_attr_iterator_destroy_w, gxg_pango_attr_iterator_destroy) Xen_wrap_2_args(gxg_pango_attr_iterator_get_w, gxg_pango_attr_iterator_get) Xen_wrap_4_optional_args(gxg_pango_attr_iterator_get_font_w, gxg_pango_attr_iterator_get_font) Xen_wrap_7_optional_args(gxg_pango_parse_markup_w, gxg_pango_parse_markup) Xen_wrap_5_args(gxg_pango_break_w, gxg_pango_break) Xen_wrap_4_optional_args(gxg_pango_find_paragraph_boundary_w, gxg_pango_find_paragraph_boundary) Xen_wrap_6_args(gxg_pango_get_log_attrs_w, gxg_pango_get_log_attrs) Xen_wrap_3_optional_args(gxg_pango_context_list_families_w, gxg_pango_context_list_families) Xen_wrap_2_args(gxg_pango_context_load_font_w, gxg_pango_context_load_font) Xen_wrap_3_args(gxg_pango_context_load_fontset_w, gxg_pango_context_load_fontset) Xen_wrap_3_args(gxg_pango_context_get_metrics_w, gxg_pango_context_get_metrics) Xen_wrap_2_args(gxg_pango_context_set_font_description_w, gxg_pango_context_set_font_description) Xen_wrap_1_arg(gxg_pango_context_get_font_description_w, gxg_pango_context_get_font_description) Xen_wrap_1_arg(gxg_pango_context_get_language_w, gxg_pango_context_get_language) Xen_wrap_2_args(gxg_pango_context_set_language_w, gxg_pango_context_set_language) Xen_wrap_2_args(gxg_pango_context_set_base_dir_w, gxg_pango_context_set_base_dir) Xen_wrap_1_arg(gxg_pango_context_get_base_dir_w, gxg_pango_context_get_base_dir) Xen_wrap_6_args(gxg_pango_itemize_w, gxg_pango_itemize) Xen_wrap_no_args(gxg_pango_coverage_new_w, gxg_pango_coverage_new) Xen_wrap_1_arg(gxg_pango_coverage_ref_w, gxg_pango_coverage_ref) Xen_wrap_1_arg(gxg_pango_coverage_unref_w, gxg_pango_coverage_unref) Xen_wrap_1_arg(gxg_pango_coverage_copy_w, gxg_pango_coverage_copy) Xen_wrap_2_args(gxg_pango_coverage_get_w, gxg_pango_coverage_get) Xen_wrap_3_args(gxg_pango_coverage_set_w, gxg_pango_coverage_set) Xen_wrap_2_args(gxg_pango_coverage_max_w, gxg_pango_coverage_max) Xen_wrap_3_optional_args(gxg_pango_coverage_to_bytes_w, gxg_pango_coverage_to_bytes) Xen_wrap_2_args(gxg_pango_coverage_from_bytes_w, gxg_pango_coverage_from_bytes) Xen_wrap_no_args(gxg_pango_font_description_new_w, gxg_pango_font_description_new) Xen_wrap_1_arg(gxg_pango_font_description_copy_w, gxg_pango_font_description_copy) Xen_wrap_1_arg(gxg_pango_font_description_copy_static_w, gxg_pango_font_description_copy_static) Xen_wrap_1_arg(gxg_pango_font_description_hash_w, gxg_pango_font_description_hash) Xen_wrap_2_args(gxg_pango_font_description_equal_w, gxg_pango_font_description_equal) Xen_wrap_1_arg(gxg_pango_font_description_free_w, gxg_pango_font_description_free) Xen_wrap_2_args(gxg_pango_font_descriptions_free_w, gxg_pango_font_descriptions_free) Xen_wrap_2_args(gxg_pango_font_description_set_family_w, gxg_pango_font_description_set_family) Xen_wrap_2_args(gxg_pango_font_description_set_family_static_w, gxg_pango_font_description_set_family_static) Xen_wrap_1_arg(gxg_pango_font_description_get_family_w, gxg_pango_font_description_get_family) Xen_wrap_2_args(gxg_pango_font_description_set_style_w, gxg_pango_font_description_set_style) Xen_wrap_1_arg(gxg_pango_font_description_get_style_w, gxg_pango_font_description_get_style) Xen_wrap_2_args(gxg_pango_font_description_set_variant_w, gxg_pango_font_description_set_variant) Xen_wrap_1_arg(gxg_pango_font_description_get_variant_w, gxg_pango_font_description_get_variant) Xen_wrap_2_args(gxg_pango_font_description_set_weight_w, gxg_pango_font_description_set_weight) Xen_wrap_1_arg(gxg_pango_font_description_get_weight_w, gxg_pango_font_description_get_weight) Xen_wrap_2_args(gxg_pango_font_description_set_stretch_w, gxg_pango_font_description_set_stretch) Xen_wrap_1_arg(gxg_pango_font_description_get_stretch_w, gxg_pango_font_description_get_stretch) Xen_wrap_2_args(gxg_pango_font_description_set_size_w, gxg_pango_font_description_set_size) Xen_wrap_1_arg(gxg_pango_font_description_get_size_w, gxg_pango_font_description_get_size) Xen_wrap_1_arg(gxg_pango_font_description_get_set_fields_w, gxg_pango_font_description_get_set_fields) Xen_wrap_2_args(gxg_pango_font_description_unset_fields_w, gxg_pango_font_description_unset_fields) Xen_wrap_3_args(gxg_pango_font_description_merge_w, gxg_pango_font_description_merge) Xen_wrap_3_args(gxg_pango_font_description_merge_static_w, gxg_pango_font_description_merge_static) Xen_wrap_3_args(gxg_pango_font_description_better_match_w, gxg_pango_font_description_better_match) Xen_wrap_1_arg(gxg_pango_font_description_from_string_w, gxg_pango_font_description_from_string) Xen_wrap_1_arg(gxg_pango_font_description_to_string_w, gxg_pango_font_description_to_string) Xen_wrap_1_arg(gxg_pango_font_description_to_filename_w, gxg_pango_font_description_to_filename) Xen_wrap_1_arg(gxg_pango_font_metrics_ref_w, gxg_pango_font_metrics_ref) Xen_wrap_1_arg(gxg_pango_font_metrics_unref_w, gxg_pango_font_metrics_unref) Xen_wrap_1_arg(gxg_pango_font_metrics_get_ascent_w, gxg_pango_font_metrics_get_ascent) Xen_wrap_1_arg(gxg_pango_font_metrics_get_descent_w, gxg_pango_font_metrics_get_descent) Xen_wrap_1_arg(gxg_pango_font_metrics_get_approximate_char_width_w, gxg_pango_font_metrics_get_approximate_char_width) Xen_wrap_1_arg(gxg_pango_font_metrics_get_approximate_digit_width_w, gxg_pango_font_metrics_get_approximate_digit_width) Xen_wrap_3_optional_args(gxg_pango_font_family_list_faces_w, gxg_pango_font_family_list_faces) Xen_wrap_1_arg(gxg_pango_font_family_get_name_w, gxg_pango_font_family_get_name) Xen_wrap_1_arg(gxg_pango_font_face_describe_w, gxg_pango_font_face_describe) Xen_wrap_1_arg(gxg_pango_font_face_get_face_name_w, gxg_pango_font_face_get_face_name) Xen_wrap_1_arg(gxg_pango_font_describe_w, gxg_pango_font_describe) Xen_wrap_2_args(gxg_pango_font_get_coverage_w, gxg_pango_font_get_coverage) Xen_wrap_2_args(gxg_pango_font_get_metrics_w, gxg_pango_font_get_metrics) Xen_wrap_4_args(gxg_pango_font_get_glyph_extents_w, gxg_pango_font_get_glyph_extents) Xen_wrap_3_args(gxg_pango_font_map_load_font_w, gxg_pango_font_map_load_font) Xen_wrap_4_args(gxg_pango_font_map_load_fontset_w, gxg_pango_font_map_load_fontset) Xen_wrap_3_optional_args(gxg_pango_font_map_list_families_w, gxg_pango_font_map_list_families) Xen_wrap_no_args(gxg_pango_glyph_string_new_w, gxg_pango_glyph_string_new) Xen_wrap_2_args(gxg_pango_glyph_string_set_size_w, gxg_pango_glyph_string_set_size) Xen_wrap_1_arg(gxg_pango_glyph_string_copy_w, gxg_pango_glyph_string_copy) Xen_wrap_1_arg(gxg_pango_glyph_string_free_w, gxg_pango_glyph_string_free) Xen_wrap_4_args(gxg_pango_glyph_string_extents_w, gxg_pango_glyph_string_extents) Xen_wrap_6_args(gxg_pango_glyph_string_extents_range_w, gxg_pango_glyph_string_extents_range) Xen_wrap_5_optional_args(gxg_pango_glyph_string_get_logical_widths_w, gxg_pango_glyph_string_get_logical_widths) Xen_wrap_7_optional_args(gxg_pango_glyph_string_index_to_x_w, gxg_pango_glyph_string_index_to_x) Xen_wrap_7_optional_args(gxg_pango_glyph_string_x_to_index_w, gxg_pango_glyph_string_x_to_index) Xen_wrap_4_args(gxg_pango_shape_w, gxg_pango_shape) Xen_wrap_1_arg(gxg_pango_reorder_items_w, gxg_pango_reorder_items) Xen_wrap_no_args(gxg_pango_item_new_w, gxg_pango_item_new) Xen_wrap_1_arg(gxg_pango_item_copy_w, gxg_pango_item_copy) Xen_wrap_1_arg(gxg_pango_item_free_w, gxg_pango_item_free) Xen_wrap_3_args(gxg_pango_item_split_w, gxg_pango_item_split) Xen_wrap_1_arg(gxg_pango_layout_new_w, gxg_pango_layout_new) Xen_wrap_1_arg(gxg_pango_layout_copy_w, gxg_pango_layout_copy) Xen_wrap_1_arg(gxg_pango_layout_get_context_w, gxg_pango_layout_get_context) Xen_wrap_2_args(gxg_pango_layout_set_attributes_w, gxg_pango_layout_set_attributes) Xen_wrap_1_arg(gxg_pango_layout_get_attributes_w, gxg_pango_layout_get_attributes) Xen_wrap_3_args(gxg_pango_layout_set_text_w, gxg_pango_layout_set_text) Xen_wrap_1_arg(gxg_pango_layout_get_text_w, gxg_pango_layout_get_text) Xen_wrap_3_args(gxg_pango_layout_set_markup_w, gxg_pango_layout_set_markup) Xen_wrap_5_args(gxg_pango_layout_set_markup_with_accel_w, gxg_pango_layout_set_markup_with_accel) Xen_wrap_2_args(gxg_pango_layout_set_font_description_w, gxg_pango_layout_set_font_description) Xen_wrap_2_args(gxg_pango_layout_set_width_w, gxg_pango_layout_set_width) Xen_wrap_1_arg(gxg_pango_layout_get_width_w, gxg_pango_layout_get_width) Xen_wrap_2_args(gxg_pango_layout_set_wrap_w, gxg_pango_layout_set_wrap) Xen_wrap_1_arg(gxg_pango_layout_get_wrap_w, gxg_pango_layout_get_wrap) Xen_wrap_2_args(gxg_pango_layout_set_indent_w, gxg_pango_layout_set_indent) Xen_wrap_1_arg(gxg_pango_layout_get_indent_w, gxg_pango_layout_get_indent) Xen_wrap_2_args(gxg_pango_layout_set_spacing_w, gxg_pango_layout_set_spacing) Xen_wrap_1_arg(gxg_pango_layout_get_spacing_w, gxg_pango_layout_get_spacing) Xen_wrap_2_args(gxg_pango_layout_set_justify_w, gxg_pango_layout_set_justify) Xen_wrap_1_arg(gxg_pango_layout_get_justify_w, gxg_pango_layout_get_justify) Xen_wrap_2_args(gxg_pango_layout_set_alignment_w, gxg_pango_layout_set_alignment) Xen_wrap_1_arg(gxg_pango_layout_get_alignment_w, gxg_pango_layout_get_alignment) Xen_wrap_2_args(gxg_pango_layout_set_tabs_w, gxg_pango_layout_set_tabs) Xen_wrap_1_arg(gxg_pango_layout_get_tabs_w, gxg_pango_layout_get_tabs) Xen_wrap_2_args(gxg_pango_layout_set_single_paragraph_mode_w, gxg_pango_layout_set_single_paragraph_mode) Xen_wrap_1_arg(gxg_pango_layout_get_single_paragraph_mode_w, gxg_pango_layout_get_single_paragraph_mode) Xen_wrap_1_arg(gxg_pango_layout_context_changed_w, gxg_pango_layout_context_changed) Xen_wrap_3_optional_args(gxg_pango_layout_get_log_attrs_w, gxg_pango_layout_get_log_attrs) Xen_wrap_3_args(gxg_pango_layout_index_to_pos_w, gxg_pango_layout_index_to_pos) Xen_wrap_4_args(gxg_pango_layout_get_cursor_pos_w, gxg_pango_layout_get_cursor_pos) Xen_wrap_7_args(gxg_pango_layout_move_cursor_visually_w, gxg_pango_layout_move_cursor_visually) Xen_wrap_5_optional_args(gxg_pango_layout_xy_to_index_w, gxg_pango_layout_xy_to_index) Xen_wrap_3_args(gxg_pango_layout_get_extents_w, gxg_pango_layout_get_extents) Xen_wrap_3_args(gxg_pango_layout_get_pixel_extents_w, gxg_pango_layout_get_pixel_extents) Xen_wrap_3_optional_args(gxg_pango_layout_get_size_w, gxg_pango_layout_get_size) Xen_wrap_3_optional_args(gxg_pango_layout_get_pixel_size_w, gxg_pango_layout_get_pixel_size) Xen_wrap_1_arg(gxg_pango_layout_get_line_count_w, gxg_pango_layout_get_line_count) Xen_wrap_2_args(gxg_pango_layout_get_line_w, gxg_pango_layout_get_line) Xen_wrap_1_arg(gxg_pango_layout_get_lines_w, gxg_pango_layout_get_lines) Xen_wrap_1_arg(gxg_pango_layout_line_unref_w, gxg_pango_layout_line_unref) Xen_wrap_4_optional_args(gxg_pango_layout_line_x_to_index_w, gxg_pango_layout_line_x_to_index) Xen_wrap_4_optional_args(gxg_pango_layout_line_index_to_x_w, gxg_pango_layout_line_index_to_x) Xen_wrap_5_optional_args(gxg_pango_layout_line_get_x_ranges_w, gxg_pango_layout_line_get_x_ranges) Xen_wrap_3_args(gxg_pango_layout_line_get_extents_w, gxg_pango_layout_line_get_extents) Xen_wrap_3_args(gxg_pango_layout_line_get_pixel_extents_w, gxg_pango_layout_line_get_pixel_extents) Xen_wrap_1_arg(gxg_pango_layout_get_iter_w, gxg_pango_layout_get_iter) Xen_wrap_1_arg(gxg_pango_layout_iter_free_w, gxg_pango_layout_iter_free) Xen_wrap_1_arg(gxg_pango_layout_iter_get_index_w, gxg_pango_layout_iter_get_index) Xen_wrap_1_arg(gxg_pango_layout_iter_get_run_w, gxg_pango_layout_iter_get_run) Xen_wrap_1_arg(gxg_pango_layout_iter_get_line_w, gxg_pango_layout_iter_get_line) Xen_wrap_1_arg(gxg_pango_layout_iter_at_last_line_w, gxg_pango_layout_iter_at_last_line) Xen_wrap_1_arg(gxg_pango_layout_iter_next_char_w, gxg_pango_layout_iter_next_char) Xen_wrap_1_arg(gxg_pango_layout_iter_next_cluster_w, gxg_pango_layout_iter_next_cluster) Xen_wrap_1_arg(gxg_pango_layout_iter_next_run_w, gxg_pango_layout_iter_next_run) Xen_wrap_1_arg(gxg_pango_layout_iter_next_line_w, gxg_pango_layout_iter_next_line) Xen_wrap_2_args(gxg_pango_layout_iter_get_char_extents_w, gxg_pango_layout_iter_get_char_extents) Xen_wrap_3_args(gxg_pango_layout_iter_get_cluster_extents_w, gxg_pango_layout_iter_get_cluster_extents) Xen_wrap_3_args(gxg_pango_layout_iter_get_run_extents_w, gxg_pango_layout_iter_get_run_extents) Xen_wrap_3_args(gxg_pango_layout_iter_get_line_extents_w, gxg_pango_layout_iter_get_line_extents) Xen_wrap_3_optional_args(gxg_pango_layout_iter_get_line_yrange_w, gxg_pango_layout_iter_get_line_yrange) Xen_wrap_3_args(gxg_pango_layout_iter_get_layout_extents_w, gxg_pango_layout_iter_get_layout_extents) Xen_wrap_1_arg(gxg_pango_layout_iter_get_baseline_w, gxg_pango_layout_iter_get_baseline) Xen_wrap_1_arg(gxg_pango_language_from_string_w, gxg_pango_language_from_string) Xen_wrap_2_args(gxg_pango_language_matches_w, gxg_pango_language_matches) Xen_wrap_1_arg(gxg_G_OBJECT_TYPE_w, gxg_G_OBJECT_TYPE) Xen_wrap_2_args(gxg_gtk_tree_model_get_string_from_iter_w, gxg_gtk_tree_model_get_string_from_iter) Xen_wrap_2_args(gxg_gtk_tree_model_sort_iter_is_valid_w, gxg_gtk_tree_model_sort_iter_is_valid) Xen_wrap_2_args(gxg_gtk_tree_view_expand_to_path_w, gxg_gtk_tree_view_expand_to_path) Xen_wrap_2_args(gxg_gtk_tree_selection_get_selected_rows_w, gxg_gtk_tree_selection_get_selected_rows) Xen_wrap_1_arg(gxg_gtk_tree_selection_count_selected_rows_w, gxg_gtk_tree_selection_count_selected_rows) Xen_wrap_2_args(gxg_gtk_menu_shell_select_first_w, gxg_gtk_menu_shell_select_first) Xen_wrap_1_arg(gxg_gtk_notebook_get_n_pages_w, gxg_gtk_notebook_get_n_pages) Xen_wrap_2_args(gxg_gtk_list_store_reorder_w, gxg_gtk_list_store_reorder) Xen_wrap_3_args(gxg_gtk_list_store_swap_w, gxg_gtk_list_store_swap) Xen_wrap_3_args(gxg_gtk_list_store_move_after_w, gxg_gtk_list_store_move_after) Xen_wrap_3_args(gxg_gtk_list_store_move_before_w, gxg_gtk_list_store_move_before) Xen_wrap_3_args(gxg_gtk_tree_store_reorder_w, gxg_gtk_tree_store_reorder) Xen_wrap_3_args(gxg_gtk_tree_store_swap_w, gxg_gtk_tree_store_swap) Xen_wrap_1_arg(gxg_gdk_display_open_w, gxg_gdk_display_open) Xen_wrap_1_arg(gxg_gdk_display_get_name_w, gxg_gdk_display_get_name) Xen_wrap_2_args(gxg_gdk_display_get_screen_w, gxg_gdk_display_get_screen) Xen_wrap_1_arg(gxg_gdk_display_get_default_screen_w, gxg_gdk_display_get_default_screen) Xen_wrap_1_arg(gxg_gdk_display_beep_w, gxg_gdk_display_beep) Xen_wrap_1_arg(gxg_gdk_display_sync_w, gxg_gdk_display_sync) Xen_wrap_1_arg(gxg_gdk_display_close_w, gxg_gdk_display_close) Xen_wrap_1_arg(gxg_gdk_display_get_event_w, gxg_gdk_display_get_event) Xen_wrap_1_arg(gxg_gdk_display_peek_event_w, gxg_gdk_display_peek_event) Xen_wrap_2_args(gxg_gdk_display_put_event_w, gxg_gdk_display_put_event) Xen_wrap_2_args(gxg_gdk_display_set_double_click_time_w, gxg_gdk_display_set_double_click_time) Xen_wrap_no_args(gxg_gdk_display_get_default_w, gxg_gdk_display_get_default) Xen_wrap_1_arg(gxg_gdk_screen_get_system_visual_w, gxg_gdk_screen_get_system_visual) Xen_wrap_1_arg(gxg_gdk_screen_get_root_window_w, gxg_gdk_screen_get_root_window) Xen_wrap_1_arg(gxg_gdk_screen_get_display_w, gxg_gdk_screen_get_display) Xen_wrap_1_arg(gxg_gdk_screen_get_number_w, gxg_gdk_screen_get_number) Xen_wrap_1_arg(gxg_gdk_screen_get_width_w, gxg_gdk_screen_get_width) Xen_wrap_1_arg(gxg_gdk_screen_get_height_w, gxg_gdk_screen_get_height) Xen_wrap_1_arg(gxg_gdk_screen_get_width_mm_w, gxg_gdk_screen_get_width_mm) Xen_wrap_1_arg(gxg_gdk_screen_get_height_mm_w, gxg_gdk_screen_get_height_mm) Xen_wrap_1_arg(gxg_gdk_screen_list_visuals_w, gxg_gdk_screen_list_visuals) Xen_wrap_1_arg(gxg_gdk_screen_get_toplevel_windows_w, gxg_gdk_screen_get_toplevel_windows) Xen_wrap_1_arg(gxg_gdk_screen_make_display_name_w, gxg_gdk_screen_make_display_name) Xen_wrap_1_arg(gxg_gdk_screen_get_n_monitors_w, gxg_gdk_screen_get_n_monitors) Xen_wrap_3_args(gxg_gdk_screen_get_monitor_geometry_w, gxg_gdk_screen_get_monitor_geometry) Xen_wrap_3_args(gxg_gdk_screen_get_monitor_at_point_w, gxg_gdk_screen_get_monitor_at_point) Xen_wrap_2_args(gxg_gdk_screen_get_monitor_at_window_w, gxg_gdk_screen_get_monitor_at_window) Xen_wrap_no_args(gxg_gdk_screen_get_default_w, gxg_gdk_screen_get_default) Xen_wrap_2_args(gxg_gtk_clipboard_get_for_display_w, gxg_gtk_clipboard_get_for_display) Xen_wrap_1_arg(gxg_gtk_clipboard_get_display_w, gxg_gtk_clipboard_get_display) Xen_wrap_1_arg(gxg_gtk_widget_get_screen_w, gxg_gtk_widget_get_screen) Xen_wrap_1_arg(gxg_gtk_widget_has_screen_w, gxg_gtk_widget_has_screen) Xen_wrap_1_arg(gxg_gtk_widget_get_display_w, gxg_gtk_widget_get_display) Xen_wrap_2_args(gxg_gtk_widget_get_clipboard_w, gxg_gtk_widget_get_clipboard) Xen_wrap_1_arg(gxg_g_list_free_w, gxg_g_list_free) Xen_wrap_1_arg(gxg_g_list_reverse_w, gxg_g_list_reverse) Xen_wrap_1_arg(gxg_g_list_copy_w, gxg_g_list_copy) Xen_wrap_1_arg(gxg_g_list_last_w, gxg_g_list_last) Xen_wrap_1_arg(gxg_g_list_first_w, gxg_g_list_first) Xen_wrap_1_arg(gxg_g_list_length_w, gxg_g_list_length) Xen_wrap_1_arg(gxg_g_free_w, gxg_g_free) Xen_wrap_2_args(gxg_g_list_remove_link_w, gxg_g_list_remove_link) Xen_wrap_2_args(gxg_g_object_get_data_w, gxg_g_object_get_data) Xen_wrap_3_args(gxg_g_object_set_data_w, gxg_g_object_set_data) Xen_wrap_4_args(gxg_gdk_cursor_new_from_pixbuf_w, gxg_gdk_cursor_new_from_pixbuf) Xen_wrap_1_arg(gxg_gdk_display_flush_w, gxg_gdk_display_flush) Xen_wrap_1_arg(gxg_gdk_display_supports_cursor_alpha_w, gxg_gdk_display_supports_cursor_alpha) Xen_wrap_1_arg(gxg_gdk_display_supports_cursor_color_w, gxg_gdk_display_supports_cursor_color) Xen_wrap_1_arg(gxg_gdk_display_get_default_cursor_size_w, gxg_gdk_display_get_default_cursor_size) Xen_wrap_3_optional_args(gxg_gdk_display_get_maximal_cursor_size_w, gxg_gdk_display_get_maximal_cursor_size) Xen_wrap_2_args(gxg_gdk_window_set_keep_above_w, gxg_gdk_window_set_keep_above) Xen_wrap_2_args(gxg_gdk_window_set_keep_below_w, gxg_gdk_window_set_keep_below) Xen_wrap_2_args(gxg_gtk_button_box_get_child_secondary_w, gxg_gtk_button_box_get_child_secondary) Xen_wrap_2_args(gxg_gtk_calendar_set_display_options_w, gxg_gtk_calendar_set_display_options) Xen_wrap_1_arg(gxg_gtk_calendar_get_display_options_w, gxg_gtk_calendar_get_display_options) Xen_wrap_2_args(gxg_gtk_check_menu_item_set_draw_as_radio_w, gxg_gtk_check_menu_item_set_draw_as_radio) Xen_wrap_1_arg(gxg_gtk_check_menu_item_get_draw_as_radio_w, gxg_gtk_check_menu_item_get_draw_as_radio) Xen_wrap_2_args(gxg_gtk_entry_set_completion_w, gxg_gtk_entry_set_completion) Xen_wrap_1_arg(gxg_gtk_entry_get_completion_w, gxg_gtk_entry_get_completion) Xen_wrap_1_arg(gxg_gtk_event_box_get_visible_window_w, gxg_gtk_event_box_get_visible_window) Xen_wrap_2_args(gxg_gtk_event_box_set_visible_window_w, gxg_gtk_event_box_set_visible_window) Xen_wrap_1_arg(gxg_gtk_event_box_get_above_child_w, gxg_gtk_event_box_get_above_child) Xen_wrap_2_args(gxg_gtk_event_box_set_above_child_w, gxg_gtk_event_box_set_above_child) Xen_wrap_6_args(gxg_gtk_menu_attach_w, gxg_gtk_menu_attach) Xen_wrap_3_args(gxg_gtk_text_buffer_select_range_w, gxg_gtk_text_buffer_select_range) Xen_wrap_2_args(gxg_gtk_text_view_set_overwrite_w, gxg_gtk_text_view_set_overwrite) Xen_wrap_1_arg(gxg_gtk_text_view_get_overwrite_w, gxg_gtk_text_view_get_overwrite) Xen_wrap_2_args(gxg_gtk_text_view_set_accepts_tab_w, gxg_gtk_text_view_set_accepts_tab) Xen_wrap_1_arg(gxg_gtk_text_view_get_accepts_tab_w, gxg_gtk_text_view_get_accepts_tab) Xen_wrap_3_args(gxg_gtk_toolbar_insert_w, gxg_gtk_toolbar_insert) Xen_wrap_2_args(gxg_gtk_toolbar_get_item_index_w, gxg_gtk_toolbar_get_item_index) Xen_wrap_1_arg(gxg_gtk_toolbar_get_n_items_w, gxg_gtk_toolbar_get_n_items) Xen_wrap_2_args(gxg_gtk_toolbar_get_nth_item_w, gxg_gtk_toolbar_get_nth_item) Xen_wrap_2_args(gxg_gtk_toolbar_set_show_arrow_w, gxg_gtk_toolbar_set_show_arrow) Xen_wrap_1_arg(gxg_gtk_toolbar_get_show_arrow_w, gxg_gtk_toolbar_get_show_arrow) Xen_wrap_1_arg(gxg_gtk_toolbar_get_relief_style_w, gxg_gtk_toolbar_get_relief_style) Xen_wrap_3_args(gxg_gtk_toolbar_get_drop_index_w, gxg_gtk_toolbar_get_drop_index) Xen_wrap_2_args(gxg_gtk_tree_view_column_set_expand_w, gxg_gtk_tree_view_column_set_expand) Xen_wrap_1_arg(gxg_gtk_tree_view_column_get_expand_w, gxg_gtk_tree_view_column_get_expand) Xen_wrap_2_args(gxg_gtk_widget_set_no_show_all_w, gxg_gtk_widget_set_no_show_all) Xen_wrap_1_arg(gxg_gtk_widget_get_no_show_all_w, gxg_gtk_widget_get_no_show_all) Xen_wrap_1_arg(gxg_gtk_widget_queue_resize_no_redraw_w, gxg_gtk_widget_queue_resize_no_redraw) Xen_wrap_1_arg(gxg_gtk_window_set_default_icon_w, gxg_gtk_window_set_default_icon) Xen_wrap_2_args(gxg_gtk_window_set_keep_above_w, gxg_gtk_window_set_keep_above) Xen_wrap_2_args(gxg_gtk_window_set_keep_below_w, gxg_gtk_window_set_keep_below) Xen_wrap_4_optional_args(gxg_gtk_file_chooser_dialog_new_w, gxg_gtk_file_chooser_dialog_new) Xen_wrap_1_arg(gxg_gtk_file_chooser_widget_new_w, gxg_gtk_file_chooser_widget_new) Xen_wrap_2_args(gxg_gtk_tree_model_filter_new_w, gxg_gtk_tree_model_filter_new) Xen_wrap_2_args(gxg_gtk_tree_model_filter_set_visible_column_w, gxg_gtk_tree_model_filter_set_visible_column) Xen_wrap_1_arg(gxg_gtk_tree_model_filter_get_model_w, gxg_gtk_tree_model_filter_get_model) Xen_wrap_3_args(gxg_gtk_tree_model_filter_convert_iter_to_child_iter_w, gxg_gtk_tree_model_filter_convert_iter_to_child_iter) Xen_wrap_2_args(gxg_gtk_tree_model_filter_convert_child_path_to_path_w, gxg_gtk_tree_model_filter_convert_child_path_to_path) Xen_wrap_2_args(gxg_gtk_tree_model_filter_convert_path_to_child_path_w, gxg_gtk_tree_model_filter_convert_path_to_child_path) Xen_wrap_1_arg(gxg_gtk_tree_model_filter_refilter_w, gxg_gtk_tree_model_filter_refilter) Xen_wrap_1_arg(gxg_gtk_tree_model_filter_clear_cache_w, gxg_gtk_tree_model_filter_clear_cache) Xen_wrap_no_args(gxg_gtk_combo_box_new_w, gxg_gtk_combo_box_new) Xen_wrap_1_arg(gxg_gtk_combo_box_new_with_model_w, gxg_gtk_combo_box_new_with_model) Xen_wrap_2_args(gxg_gtk_combo_box_set_model_w, gxg_gtk_combo_box_set_model) Xen_wrap_2_args(gxg_gtk_combo_box_set_wrap_width_w, gxg_gtk_combo_box_set_wrap_width) Xen_wrap_2_args(gxg_gtk_combo_box_set_row_span_column_w, gxg_gtk_combo_box_set_row_span_column) Xen_wrap_2_args(gxg_gtk_combo_box_set_column_span_column_w, gxg_gtk_combo_box_set_column_span_column) Xen_wrap_1_arg(gxg_gtk_combo_box_get_active_w, gxg_gtk_combo_box_get_active) Xen_wrap_2_args(gxg_gtk_combo_box_set_active_w, gxg_gtk_combo_box_set_active) Xen_wrap_2_args(gxg_gtk_combo_box_get_active_iter_w, gxg_gtk_combo_box_get_active_iter) Xen_wrap_2_args(gxg_gtk_combo_box_set_active_iter_w, gxg_gtk_combo_box_set_active_iter) Xen_wrap_1_arg(gxg_gtk_combo_box_get_model_w, gxg_gtk_combo_box_get_model) Xen_wrap_1_arg(gxg_gtk_expander_new_w, gxg_gtk_expander_new) Xen_wrap_1_arg(gxg_gtk_expander_new_with_mnemonic_w, gxg_gtk_expander_new_with_mnemonic) Xen_wrap_2_args(gxg_gtk_expander_set_expanded_w, gxg_gtk_expander_set_expanded) Xen_wrap_1_arg(gxg_gtk_expander_get_expanded_w, gxg_gtk_expander_get_expanded) Xen_wrap_2_args(gxg_gtk_expander_set_spacing_w, gxg_gtk_expander_set_spacing) Xen_wrap_1_arg(gxg_gtk_expander_get_spacing_w, gxg_gtk_expander_get_spacing) Xen_wrap_2_args(gxg_gtk_expander_set_label_w, gxg_gtk_expander_set_label) Xen_wrap_1_arg(gxg_gtk_expander_get_label_w, gxg_gtk_expander_get_label) Xen_wrap_2_args(gxg_gtk_expander_set_use_underline_w, gxg_gtk_expander_set_use_underline) Xen_wrap_1_arg(gxg_gtk_expander_get_use_underline_w, gxg_gtk_expander_get_use_underline) Xen_wrap_2_args(gxg_gtk_expander_set_label_widget_w, gxg_gtk_expander_set_label_widget) Xen_wrap_1_arg(gxg_gtk_expander_get_label_widget_w, gxg_gtk_expander_get_label_widget) Xen_wrap_2_args(gxg_gtk_expander_set_use_markup_w, gxg_gtk_expander_set_use_markup) Xen_wrap_1_arg(gxg_gtk_expander_get_use_markup_w, gxg_gtk_expander_get_use_markup) Xen_wrap_no_args(gxg_gtk_font_button_new_w, gxg_gtk_font_button_new) Xen_wrap_1_arg(gxg_gtk_font_button_new_with_font_w, gxg_gtk_font_button_new_with_font) Xen_wrap_1_arg(gxg_gtk_font_button_get_title_w, gxg_gtk_font_button_get_title) Xen_wrap_2_args(gxg_gtk_font_button_set_title_w, gxg_gtk_font_button_set_title) Xen_wrap_1_arg(gxg_gtk_font_button_get_use_font_w, gxg_gtk_font_button_get_use_font) Xen_wrap_2_args(gxg_gtk_font_button_set_use_font_w, gxg_gtk_font_button_set_use_font) Xen_wrap_1_arg(gxg_gtk_font_button_get_use_size_w, gxg_gtk_font_button_get_use_size) Xen_wrap_2_args(gxg_gtk_font_button_set_use_size_w, gxg_gtk_font_button_set_use_size) Xen_wrap_1_arg(gxg_gtk_font_button_get_font_name_w, gxg_gtk_font_button_get_font_name) Xen_wrap_2_args(gxg_gtk_font_button_set_font_name_w, gxg_gtk_font_button_set_font_name) Xen_wrap_1_arg(gxg_gtk_font_button_get_show_style_w, gxg_gtk_font_button_get_show_style) Xen_wrap_2_args(gxg_gtk_font_button_set_show_style_w, gxg_gtk_font_button_set_show_style) Xen_wrap_1_arg(gxg_gtk_font_button_get_show_size_w, gxg_gtk_font_button_get_show_size) Xen_wrap_2_args(gxg_gtk_font_button_set_show_size_w, gxg_gtk_font_button_set_show_size) Xen_wrap_no_args(gxg_gtk_entry_completion_new_w, gxg_gtk_entry_completion_new) Xen_wrap_1_arg(gxg_gtk_entry_completion_get_entry_w, gxg_gtk_entry_completion_get_entry) Xen_wrap_2_args(gxg_gtk_entry_completion_set_model_w, gxg_gtk_entry_completion_set_model) Xen_wrap_1_arg(gxg_gtk_entry_completion_get_model_w, gxg_gtk_entry_completion_get_model) Xen_wrap_4_args(gxg_gtk_entry_completion_set_match_func_w, gxg_gtk_entry_completion_set_match_func) Xen_wrap_2_args(gxg_gtk_entry_completion_set_minimum_key_length_w, gxg_gtk_entry_completion_set_minimum_key_length) Xen_wrap_1_arg(gxg_gtk_entry_completion_get_minimum_key_length_w, gxg_gtk_entry_completion_get_minimum_key_length) Xen_wrap_1_arg(gxg_gtk_entry_completion_complete_w, gxg_gtk_entry_completion_complete) Xen_wrap_3_args(gxg_gtk_entry_completion_insert_action_text_w, gxg_gtk_entry_completion_insert_action_text) Xen_wrap_3_args(gxg_gtk_entry_completion_insert_action_markup_w, gxg_gtk_entry_completion_insert_action_markup) Xen_wrap_2_args(gxg_gtk_entry_completion_delete_action_w, gxg_gtk_entry_completion_delete_action) Xen_wrap_2_args(gxg_gtk_entry_completion_set_text_column_w, gxg_gtk_entry_completion_set_text_column) Xen_wrap_1_arg(gxg_gtk_radio_tool_button_new_w, gxg_gtk_radio_tool_button_new) Xen_wrap_1_arg(gxg_gtk_radio_tool_button_new_from_widget_w, gxg_gtk_radio_tool_button_new_from_widget) Xen_wrap_1_arg(gxg_gtk_radio_tool_button_get_group_w, gxg_gtk_radio_tool_button_get_group) Xen_wrap_2_args(gxg_gtk_radio_tool_button_set_group_w, gxg_gtk_radio_tool_button_set_group) Xen_wrap_no_args(gxg_gtk_separator_tool_item_new_w, gxg_gtk_separator_tool_item_new) Xen_wrap_1_arg(gxg_gtk_separator_tool_item_get_draw_w, gxg_gtk_separator_tool_item_get_draw) Xen_wrap_2_args(gxg_gtk_separator_tool_item_set_draw_w, gxg_gtk_separator_tool_item_set_draw) Xen_wrap_no_args(gxg_gtk_toggle_tool_button_new_w, gxg_gtk_toggle_tool_button_new) Xen_wrap_2_args(gxg_gtk_toggle_tool_button_set_active_w, gxg_gtk_toggle_tool_button_set_active) Xen_wrap_1_arg(gxg_gtk_toggle_tool_button_get_active_w, gxg_gtk_toggle_tool_button_get_active) Xen_wrap_5_args(gxg_g_timeout_add_full_w, gxg_g_timeout_add_full) Xen_wrap_3_optional_args(gxg_g_timeout_add_w, gxg_g_timeout_add) Xen_wrap_2_optional_args(gxg_g_idle_add_w, gxg_g_idle_add) Xen_wrap_4_args(gxg_g_idle_add_full_w, gxg_g_idle_add_full) Xen_wrap_1_arg(gxg_g_idle_remove_by_data_w, gxg_g_idle_remove_by_data) Xen_wrap_1_arg(gxg_g_source_remove_w, gxg_g_source_remove) Xen_wrap_no_args(gxg_gtk_file_filter_new_w, gxg_gtk_file_filter_new) Xen_wrap_2_args(gxg_gtk_file_filter_set_name_w, gxg_gtk_file_filter_set_name) Xen_wrap_1_arg(gxg_gtk_file_filter_get_name_w, gxg_gtk_file_filter_get_name) Xen_wrap_2_args(gxg_gtk_file_filter_add_mime_type_w, gxg_gtk_file_filter_add_mime_type) Xen_wrap_2_args(gxg_gtk_file_filter_add_pattern_w, gxg_gtk_file_filter_add_pattern) Xen_wrap_5_args(gxg_gtk_file_filter_add_custom_w, gxg_gtk_file_filter_add_custom) Xen_wrap_1_arg(gxg_gtk_file_filter_get_needed_w, gxg_gtk_file_filter_get_needed) Xen_wrap_2_args(gxg_gtk_file_filter_filter_w, gxg_gtk_file_filter_filter) Xen_wrap_3_args(gxg_gtk_cell_layout_pack_start_w, gxg_gtk_cell_layout_pack_start) Xen_wrap_3_args(gxg_gtk_cell_layout_pack_end_w, gxg_gtk_cell_layout_pack_end) Xen_wrap_1_arg(gxg_gtk_cell_layout_clear_w, gxg_gtk_cell_layout_clear) Xen_wrap_3_args(gxg_gtk_cell_layout_set_attributes_w, gxg_gtk_cell_layout_set_attributes) Xen_wrap_4_args(gxg_gtk_cell_layout_add_attribute_w, gxg_gtk_cell_layout_add_attribute) Xen_wrap_5_args(gxg_gtk_cell_layout_set_cell_data_func_w, gxg_gtk_cell_layout_set_cell_data_func) Xen_wrap_2_args(gxg_gtk_cell_layout_clear_attributes_w, gxg_gtk_cell_layout_clear_attributes) Xen_wrap_2_args(gxg_gtk_file_chooser_set_action_w, gxg_gtk_file_chooser_set_action) Xen_wrap_1_arg(gxg_gtk_file_chooser_get_action_w, gxg_gtk_file_chooser_get_action) Xen_wrap_2_args(gxg_gtk_file_chooser_set_local_only_w, gxg_gtk_file_chooser_set_local_only) Xen_wrap_1_arg(gxg_gtk_file_chooser_get_local_only_w, gxg_gtk_file_chooser_get_local_only) Xen_wrap_2_args(gxg_gtk_file_chooser_set_select_multiple_w, gxg_gtk_file_chooser_set_select_multiple) Xen_wrap_1_arg(gxg_gtk_file_chooser_get_select_multiple_w, gxg_gtk_file_chooser_get_select_multiple) Xen_wrap_2_args(gxg_gtk_file_chooser_set_current_name_w, gxg_gtk_file_chooser_set_current_name) Xen_wrap_1_arg(gxg_gtk_file_chooser_get_filename_w, gxg_gtk_file_chooser_get_filename) Xen_wrap_2_args(gxg_gtk_file_chooser_set_filename_w, gxg_gtk_file_chooser_set_filename) Xen_wrap_2_args(gxg_gtk_file_chooser_select_filename_w, gxg_gtk_file_chooser_select_filename) Xen_wrap_2_args(gxg_gtk_file_chooser_unselect_filename_w, gxg_gtk_file_chooser_unselect_filename) Xen_wrap_1_arg(gxg_gtk_file_chooser_select_all_w, gxg_gtk_file_chooser_select_all) Xen_wrap_1_arg(gxg_gtk_file_chooser_unselect_all_w, gxg_gtk_file_chooser_unselect_all) Xen_wrap_1_arg(gxg_gtk_file_chooser_get_filenames_w, gxg_gtk_file_chooser_get_filenames) Xen_wrap_2_args(gxg_gtk_file_chooser_set_current_folder_w, gxg_gtk_file_chooser_set_current_folder) Xen_wrap_1_arg(gxg_gtk_file_chooser_get_current_folder_w, gxg_gtk_file_chooser_get_current_folder) Xen_wrap_1_arg(gxg_gtk_file_chooser_get_uri_w, gxg_gtk_file_chooser_get_uri) Xen_wrap_2_args(gxg_gtk_file_chooser_set_uri_w, gxg_gtk_file_chooser_set_uri) Xen_wrap_2_args(gxg_gtk_file_chooser_select_uri_w, gxg_gtk_file_chooser_select_uri) Xen_wrap_2_args(gxg_gtk_file_chooser_unselect_uri_w, gxg_gtk_file_chooser_unselect_uri) Xen_wrap_1_arg(gxg_gtk_file_chooser_get_uris_w, gxg_gtk_file_chooser_get_uris) Xen_wrap_2_args(gxg_gtk_file_chooser_set_current_folder_uri_w, gxg_gtk_file_chooser_set_current_folder_uri) Xen_wrap_1_arg(gxg_gtk_file_chooser_get_current_folder_uri_w, gxg_gtk_file_chooser_get_current_folder_uri) Xen_wrap_2_args(gxg_gtk_file_chooser_set_preview_widget_w, gxg_gtk_file_chooser_set_preview_widget) Xen_wrap_1_arg(gxg_gtk_file_chooser_get_preview_widget_w, gxg_gtk_file_chooser_get_preview_widget) Xen_wrap_2_args(gxg_gtk_file_chooser_set_preview_widget_active_w, gxg_gtk_file_chooser_set_preview_widget_active) Xen_wrap_1_arg(gxg_gtk_file_chooser_get_preview_widget_active_w, gxg_gtk_file_chooser_get_preview_widget_active) Xen_wrap_1_arg(gxg_gtk_file_chooser_get_preview_filename_w, gxg_gtk_file_chooser_get_preview_filename) Xen_wrap_1_arg(gxg_gtk_file_chooser_get_preview_uri_w, gxg_gtk_file_chooser_get_preview_uri) Xen_wrap_2_args(gxg_gtk_file_chooser_set_extra_widget_w, gxg_gtk_file_chooser_set_extra_widget) Xen_wrap_1_arg(gxg_gtk_file_chooser_get_extra_widget_w, gxg_gtk_file_chooser_get_extra_widget) Xen_wrap_2_args(gxg_gtk_file_chooser_add_filter_w, gxg_gtk_file_chooser_add_filter) Xen_wrap_2_args(gxg_gtk_file_chooser_remove_filter_w, gxg_gtk_file_chooser_remove_filter) Xen_wrap_1_arg(gxg_gtk_file_chooser_list_filters_w, gxg_gtk_file_chooser_list_filters) Xen_wrap_2_args(gxg_gtk_file_chooser_set_filter_w, gxg_gtk_file_chooser_set_filter) Xen_wrap_1_arg(gxg_gtk_file_chooser_get_filter_w, gxg_gtk_file_chooser_get_filter) Xen_wrap_3_optional_args(gxg_gtk_file_chooser_add_shortcut_folder_w, gxg_gtk_file_chooser_add_shortcut_folder) Xen_wrap_3_optional_args(gxg_gtk_file_chooser_remove_shortcut_folder_w, gxg_gtk_file_chooser_remove_shortcut_folder) Xen_wrap_1_arg(gxg_gtk_file_chooser_list_shortcut_folders_w, gxg_gtk_file_chooser_list_shortcut_folders) Xen_wrap_3_optional_args(gxg_gtk_file_chooser_add_shortcut_folder_uri_w, gxg_gtk_file_chooser_add_shortcut_folder_uri) Xen_wrap_3_optional_args(gxg_gtk_file_chooser_remove_shortcut_folder_uri_w, gxg_gtk_file_chooser_remove_shortcut_folder_uri) Xen_wrap_1_arg(gxg_gtk_file_chooser_list_shortcut_folder_uris_w, gxg_gtk_file_chooser_list_shortcut_folder_uris) Xen_wrap_no_args(gxg_gtk_icon_theme_new_w, gxg_gtk_icon_theme_new) Xen_wrap_no_args(gxg_gtk_icon_theme_get_default_w, gxg_gtk_icon_theme_get_default) Xen_wrap_1_arg(gxg_gtk_icon_theme_get_for_screen_w, gxg_gtk_icon_theme_get_for_screen) Xen_wrap_2_args(gxg_gtk_icon_theme_set_screen_w, gxg_gtk_icon_theme_set_screen) Xen_wrap_3_optional_args(gxg_gtk_icon_theme_get_search_path_w, gxg_gtk_icon_theme_get_search_path) Xen_wrap_2_args(gxg_gtk_icon_theme_append_search_path_w, gxg_gtk_icon_theme_append_search_path) Xen_wrap_2_args(gxg_gtk_icon_theme_prepend_search_path_w, gxg_gtk_icon_theme_prepend_search_path) Xen_wrap_2_args(gxg_gtk_icon_theme_set_custom_theme_w, gxg_gtk_icon_theme_set_custom_theme) Xen_wrap_2_args(gxg_gtk_icon_theme_has_icon_w, gxg_gtk_icon_theme_has_icon) Xen_wrap_4_args(gxg_gtk_icon_theme_lookup_icon_w, gxg_gtk_icon_theme_lookup_icon) Xen_wrap_5_optional_args(gxg_gtk_icon_theme_load_icon_w, gxg_gtk_icon_theme_load_icon) Xen_wrap_2_args(gxg_gtk_icon_theme_list_icons_w, gxg_gtk_icon_theme_list_icons) Xen_wrap_1_arg(gxg_gtk_icon_theme_get_example_icon_name_w, gxg_gtk_icon_theme_get_example_icon_name) Xen_wrap_1_arg(gxg_gtk_icon_theme_rescan_if_needed_w, gxg_gtk_icon_theme_rescan_if_needed) Xen_wrap_1_arg(gxg_gtk_icon_info_get_base_size_w, gxg_gtk_icon_info_get_base_size) Xen_wrap_1_arg(gxg_gtk_icon_info_get_filename_w, gxg_gtk_icon_info_get_filename) Xen_wrap_2_optional_args(gxg_gtk_icon_info_load_icon_w, gxg_gtk_icon_info_load_icon) Xen_wrap_2_args(gxg_gtk_tool_button_new_w, gxg_gtk_tool_button_new) Xen_wrap_2_args(gxg_gtk_tool_button_set_label_w, gxg_gtk_tool_button_set_label) Xen_wrap_1_arg(gxg_gtk_tool_button_get_label_w, gxg_gtk_tool_button_get_label) Xen_wrap_2_args(gxg_gtk_tool_button_set_use_underline_w, gxg_gtk_tool_button_set_use_underline) Xen_wrap_1_arg(gxg_gtk_tool_button_get_use_underline_w, gxg_gtk_tool_button_get_use_underline) Xen_wrap_2_args(gxg_gtk_tool_button_set_icon_widget_w, gxg_gtk_tool_button_set_icon_widget) Xen_wrap_1_arg(gxg_gtk_tool_button_get_icon_widget_w, gxg_gtk_tool_button_get_icon_widget) Xen_wrap_2_args(gxg_gtk_tool_button_set_label_widget_w, gxg_gtk_tool_button_set_label_widget) Xen_wrap_1_arg(gxg_gtk_tool_button_get_label_widget_w, gxg_gtk_tool_button_get_label_widget) Xen_wrap_no_args(gxg_gtk_tool_item_new_w, gxg_gtk_tool_item_new) Xen_wrap_2_args(gxg_gtk_tool_item_set_homogeneous_w, gxg_gtk_tool_item_set_homogeneous) Xen_wrap_1_arg(gxg_gtk_tool_item_get_homogeneous_w, gxg_gtk_tool_item_get_homogeneous) Xen_wrap_2_args(gxg_gtk_tool_item_set_expand_w, gxg_gtk_tool_item_set_expand) Xen_wrap_1_arg(gxg_gtk_tool_item_get_expand_w, gxg_gtk_tool_item_get_expand) Xen_wrap_2_args(gxg_gtk_tool_item_set_use_drag_window_w, gxg_gtk_tool_item_set_use_drag_window) Xen_wrap_1_arg(gxg_gtk_tool_item_get_use_drag_window_w, gxg_gtk_tool_item_get_use_drag_window) Xen_wrap_2_args(gxg_gtk_tool_item_set_visible_horizontal_w, gxg_gtk_tool_item_set_visible_horizontal) Xen_wrap_1_arg(gxg_gtk_tool_item_get_visible_horizontal_w, gxg_gtk_tool_item_get_visible_horizontal) Xen_wrap_2_args(gxg_gtk_tool_item_set_visible_vertical_w, gxg_gtk_tool_item_set_visible_vertical) Xen_wrap_1_arg(gxg_gtk_tool_item_get_visible_vertical_w, gxg_gtk_tool_item_get_visible_vertical) Xen_wrap_1_arg(gxg_gtk_tool_item_get_is_important_w, gxg_gtk_tool_item_get_is_important) Xen_wrap_2_args(gxg_gtk_tool_item_set_is_important_w, gxg_gtk_tool_item_set_is_important) Xen_wrap_1_arg(gxg_gtk_tool_item_get_orientation_w, gxg_gtk_tool_item_get_orientation) Xen_wrap_1_arg(gxg_gtk_tool_item_get_toolbar_style_w, gxg_gtk_tool_item_get_toolbar_style) Xen_wrap_1_arg(gxg_gtk_tool_item_get_relief_style_w, gxg_gtk_tool_item_get_relief_style) Xen_wrap_1_arg(gxg_gtk_tool_item_retrieve_proxy_menu_item_w, gxg_gtk_tool_item_retrieve_proxy_menu_item) Xen_wrap_2_args(gxg_gtk_tool_item_get_proxy_menu_item_w, gxg_gtk_tool_item_get_proxy_menu_item) Xen_wrap_3_args(gxg_gtk_tool_item_set_proxy_menu_item_w, gxg_gtk_tool_item_set_proxy_menu_item) Xen_wrap_2_args(gxg_gtk_list_store_remove_w, gxg_gtk_list_store_remove) Xen_wrap_2_args(gxg_gdk_display_set_double_click_distance_w, gxg_gdk_display_set_double_click_distance) Xen_wrap_1_arg(gxg_gdk_display_get_default_group_w, gxg_gdk_display_get_default_group) Xen_wrap_1_arg(gxg_gdk_window_get_group_w, gxg_gdk_window_get_group) Xen_wrap_3_args(gxg_gtk_cell_layout_reorder_w, gxg_gtk_cell_layout_reorder) Xen_wrap_3_optional_args(gxg_gtk_clipboard_request_targets_w, gxg_gtk_clipboard_request_targets) Xen_wrap_3_optional_args(gxg_gtk_clipboard_wait_for_targets_w, gxg_gtk_clipboard_wait_for_targets) Xen_wrap_1_arg(gxg_gtk_menu_shell_cancel_w, gxg_gtk_menu_shell_cancel) Xen_wrap_1_arg(gxg_gtk_paned_get_child1_w, gxg_gtk_paned_get_child1) Xen_wrap_1_arg(gxg_gtk_paned_get_child2_w, gxg_gtk_paned_get_child2) Xen_wrap_2_args(gxg_gtk_window_set_accept_focus_w, gxg_gtk_window_set_accept_focus) Xen_wrap_1_arg(gxg_gtk_window_get_accept_focus_w, gxg_gtk_window_get_accept_focus) Xen_wrap_2_args(gxg_g_list_nth_data_w, gxg_g_list_nth_data) Xen_wrap_no_args(gxg_gtk_accel_map_get_w, gxg_gtk_accel_map_get) Xen_wrap_1_arg(gxg_gtk_combo_box_popup_w, gxg_gtk_combo_box_popup) Xen_wrap_1_arg(gxg_gtk_combo_box_popdown_w, gxg_gtk_combo_box_popdown) Xen_wrap_1_arg(gxg_gtk_radio_menu_item_new_from_widget_w, gxg_gtk_radio_menu_item_new_from_widget) Xen_wrap_2_args(gxg_gtk_radio_menu_item_new_with_mnemonic_from_widget_w, gxg_gtk_radio_menu_item_new_with_mnemonic_from_widget) Xen_wrap_2_args(gxg_gtk_radio_menu_item_new_with_label_from_widget_w, gxg_gtk_radio_menu_item_new_with_label_from_widget) Xen_wrap_1_arg(gxg_gtk_scale_get_layout_w, gxg_gtk_scale_get_layout) Xen_wrap_3_optional_args(gxg_gtk_scale_get_layout_offsets_w, gxg_gtk_scale_get_layout_offsets) Xen_wrap_1_arg(gxg_gtk_drag_source_get_target_list_w, gxg_gtk_drag_source_get_target_list) Xen_wrap_2_args(gxg_gtk_drag_source_set_target_list_w, gxg_gtk_drag_source_set_target_list) Xen_wrap_2_args(gxg_gtk_entry_set_alignment_w, gxg_gtk_entry_set_alignment) Xen_wrap_1_arg(gxg_gtk_entry_get_alignment_w, gxg_gtk_entry_get_alignment) Xen_wrap_2_args(gxg_gtk_file_chooser_set_use_preview_label_w, gxg_gtk_file_chooser_set_use_preview_label) Xen_wrap_1_arg(gxg_gtk_file_chooser_get_use_preview_label_w, gxg_gtk_file_chooser_get_use_preview_label) Xen_wrap_1_arg(gxg_gtk_widget_list_mnemonic_labels_w, gxg_gtk_widget_list_mnemonic_labels) Xen_wrap_2_args(gxg_gtk_widget_add_mnemonic_label_w, gxg_gtk_widget_add_mnemonic_label) Xen_wrap_2_args(gxg_gtk_widget_remove_mnemonic_label_w, gxg_gtk_widget_remove_mnemonic_label) Xen_wrap_2_args(gxg_gtk_window_activate_key_w, gxg_gtk_window_activate_key) Xen_wrap_2_args(gxg_gtk_window_propagate_key_event_w, gxg_gtk_window_propagate_key_event) Xen_wrap_1_arg(gxg_g_quark_from_string_w, gxg_g_quark_from_string) Xen_wrap_1_arg(gxg_g_quark_to_string_w, gxg_g_quark_to_string) Xen_wrap_no_args(gxg_gtk_cell_view_new_w, gxg_gtk_cell_view_new) Xen_wrap_1_arg(gxg_gtk_cell_view_new_with_text_w, gxg_gtk_cell_view_new_with_text) Xen_wrap_1_arg(gxg_gtk_cell_view_new_with_markup_w, gxg_gtk_cell_view_new_with_markup) Xen_wrap_1_arg(gxg_gtk_cell_view_new_with_pixbuf_w, gxg_gtk_cell_view_new_with_pixbuf) Xen_wrap_2_args(gxg_gtk_cell_view_set_model_w, gxg_gtk_cell_view_set_model) Xen_wrap_2_args(gxg_gtk_cell_view_set_displayed_row_w, gxg_gtk_cell_view_set_displayed_row) Xen_wrap_1_arg(gxg_gtk_cell_view_get_displayed_row_w, gxg_gtk_cell_view_get_displayed_row) Xen_wrap_1_arg(gxg_gtk_combo_box_get_wrap_width_w, gxg_gtk_combo_box_get_wrap_width) Xen_wrap_1_arg(gxg_gtk_combo_box_get_row_span_column_w, gxg_gtk_combo_box_get_row_span_column) Xen_wrap_1_arg(gxg_gtk_combo_box_get_column_span_column_w, gxg_gtk_combo_box_get_column_span_column) Xen_wrap_1_arg(gxg_gtk_drag_dest_add_text_targets_w, gxg_gtk_drag_dest_add_text_targets) Xen_wrap_1_arg(gxg_gtk_drag_source_add_text_targets_w, gxg_gtk_drag_source_add_text_targets) Xen_wrap_1_arg(gxg_gtk_entry_completion_insert_prefix_w, gxg_gtk_entry_completion_insert_prefix) Xen_wrap_2_args(gxg_gtk_entry_completion_set_inline_completion_w, gxg_gtk_entry_completion_set_inline_completion) Xen_wrap_1_arg(gxg_gtk_entry_completion_get_inline_completion_w, gxg_gtk_entry_completion_get_inline_completion) Xen_wrap_2_args(gxg_gtk_entry_completion_set_popup_completion_w, gxg_gtk_entry_completion_set_popup_completion) Xen_wrap_1_arg(gxg_gtk_entry_completion_get_popup_completion_w, gxg_gtk_entry_completion_get_popup_completion) Xen_wrap_1_arg(gxg_gtk_entry_completion_get_text_column_w, gxg_gtk_entry_completion_get_text_column) Xen_wrap_2_args(gxg_gtk_icon_theme_get_icon_sizes_w, gxg_gtk_icon_theme_get_icon_sizes) Xen_wrap_1_arg(gxg_gtk_menu_get_for_attach_widget_w, gxg_gtk_menu_get_for_attach_widget) Xen_wrap_2_args(gxg_gtk_tree_view_set_fixed_height_mode_w, gxg_gtk_tree_view_set_fixed_height_mode) Xen_wrap_1_arg(gxg_gtk_tree_view_get_fixed_height_mode_w, gxg_gtk_tree_view_get_fixed_height_mode) Xen_wrap_2_args(gxg_gtk_tree_view_set_hover_selection_w, gxg_gtk_tree_view_set_hover_selection) Xen_wrap_1_arg(gxg_gtk_tree_view_get_hover_selection_w, gxg_gtk_tree_view_get_hover_selection) Xen_wrap_4_args(gxg_gtk_tree_view_set_row_separator_func_w, gxg_gtk_tree_view_set_row_separator_func) Xen_wrap_2_args(gxg_gtk_window_set_focus_on_map_w, gxg_gtk_window_set_focus_on_map) Xen_wrap_1_arg(gxg_gtk_window_get_focus_on_map_w, gxg_gtk_window_get_focus_on_map) Xen_wrap_2_args(gxg_gtk_window_set_icon_name_w, gxg_gtk_window_set_icon_name) Xen_wrap_1_arg(gxg_gtk_window_get_icon_name_w, gxg_gtk_window_get_icon_name) Xen_wrap_1_arg(gxg_gtk_window_set_default_icon_name_w, gxg_gtk_window_set_default_icon_name) Xen_wrap_no_args(gxg_gtk_about_dialog_new_w, gxg_gtk_about_dialog_new) Xen_wrap_1_arg(gxg_gtk_about_dialog_get_version_w, gxg_gtk_about_dialog_get_version) Xen_wrap_2_args(gxg_gtk_about_dialog_set_version_w, gxg_gtk_about_dialog_set_version) Xen_wrap_1_arg(gxg_gtk_about_dialog_get_copyright_w, gxg_gtk_about_dialog_get_copyright) Xen_wrap_2_args(gxg_gtk_about_dialog_set_copyright_w, gxg_gtk_about_dialog_set_copyright) Xen_wrap_1_arg(gxg_gtk_about_dialog_get_comments_w, gxg_gtk_about_dialog_get_comments) Xen_wrap_2_args(gxg_gtk_about_dialog_set_comments_w, gxg_gtk_about_dialog_set_comments) Xen_wrap_1_arg(gxg_gtk_about_dialog_get_website_w, gxg_gtk_about_dialog_get_website) Xen_wrap_2_args(gxg_gtk_about_dialog_set_website_w, gxg_gtk_about_dialog_set_website) Xen_wrap_1_arg(gxg_gtk_about_dialog_get_website_label_w, gxg_gtk_about_dialog_get_website_label) Xen_wrap_2_args(gxg_gtk_about_dialog_set_website_label_w, gxg_gtk_about_dialog_set_website_label) Xen_wrap_1_arg(gxg_gtk_about_dialog_get_authors_w, gxg_gtk_about_dialog_get_authors) Xen_wrap_2_args(gxg_gtk_about_dialog_set_authors_w, gxg_gtk_about_dialog_set_authors) Xen_wrap_1_arg(gxg_gtk_about_dialog_get_documenters_w, gxg_gtk_about_dialog_get_documenters) Xen_wrap_2_args(gxg_gtk_about_dialog_set_documenters_w, gxg_gtk_about_dialog_set_documenters) Xen_wrap_1_arg(gxg_gtk_about_dialog_get_artists_w, gxg_gtk_about_dialog_get_artists) Xen_wrap_2_args(gxg_gtk_about_dialog_set_artists_w, gxg_gtk_about_dialog_set_artists) Xen_wrap_1_arg(gxg_gtk_about_dialog_get_translator_credits_w, gxg_gtk_about_dialog_get_translator_credits) Xen_wrap_2_args(gxg_gtk_about_dialog_set_translator_credits_w, gxg_gtk_about_dialog_set_translator_credits) Xen_wrap_1_arg(gxg_gtk_about_dialog_get_logo_w, gxg_gtk_about_dialog_get_logo) Xen_wrap_2_args(gxg_gtk_about_dialog_set_logo_w, gxg_gtk_about_dialog_set_logo) Xen_wrap_1_arg(gxg_gtk_about_dialog_get_program_name_w, gxg_gtk_about_dialog_get_program_name) Xen_wrap_2_args(gxg_gtk_about_dialog_set_program_name_w, gxg_gtk_about_dialog_set_program_name) Xen_wrap_no_args(gxg_gtk_icon_view_new_w, gxg_gtk_icon_view_new) Xen_wrap_1_arg(gxg_gtk_icon_view_new_with_model_w, gxg_gtk_icon_view_new_with_model) Xen_wrap_2_args(gxg_gtk_icon_view_set_model_w, gxg_gtk_icon_view_set_model) Xen_wrap_1_arg(gxg_gtk_icon_view_get_model_w, gxg_gtk_icon_view_get_model) Xen_wrap_2_args(gxg_gtk_icon_view_set_text_column_w, gxg_gtk_icon_view_set_text_column) Xen_wrap_1_arg(gxg_gtk_icon_view_get_text_column_w, gxg_gtk_icon_view_get_text_column) Xen_wrap_2_args(gxg_gtk_icon_view_set_markup_column_w, gxg_gtk_icon_view_set_markup_column) Xen_wrap_1_arg(gxg_gtk_icon_view_get_markup_column_w, gxg_gtk_icon_view_get_markup_column) Xen_wrap_2_args(gxg_gtk_icon_view_set_pixbuf_column_w, gxg_gtk_icon_view_set_pixbuf_column) Xen_wrap_1_arg(gxg_gtk_icon_view_get_pixbuf_column_w, gxg_gtk_icon_view_get_pixbuf_column) Xen_wrap_3_args(gxg_gtk_icon_view_get_path_at_pos_w, gxg_gtk_icon_view_get_path_at_pos) Xen_wrap_3_optional_args(gxg_gtk_icon_view_selected_foreach_w, gxg_gtk_icon_view_selected_foreach) Xen_wrap_2_args(gxg_gtk_icon_view_set_selection_mode_w, gxg_gtk_icon_view_set_selection_mode) Xen_wrap_1_arg(gxg_gtk_icon_view_get_selection_mode_w, gxg_gtk_icon_view_get_selection_mode) Xen_wrap_2_args(gxg_gtk_icon_view_select_path_w, gxg_gtk_icon_view_select_path) Xen_wrap_2_args(gxg_gtk_icon_view_unselect_path_w, gxg_gtk_icon_view_unselect_path) Xen_wrap_2_args(gxg_gtk_icon_view_path_is_selected_w, gxg_gtk_icon_view_path_is_selected) Xen_wrap_1_arg(gxg_gtk_icon_view_get_selected_items_w, gxg_gtk_icon_view_get_selected_items) Xen_wrap_1_arg(gxg_gtk_icon_view_select_all_w, gxg_gtk_icon_view_select_all) Xen_wrap_1_arg(gxg_gtk_icon_view_unselect_all_w, gxg_gtk_icon_view_unselect_all) Xen_wrap_2_args(gxg_gtk_icon_view_item_activated_w, gxg_gtk_icon_view_item_activated) Xen_wrap_no_args(gxg_gtk_cell_renderer_combo_new_w, gxg_gtk_cell_renderer_combo_new) Xen_wrap_no_args(gxg_gtk_cell_renderer_progress_new_w, gxg_gtk_cell_renderer_progress_new) Xen_wrap_4_args(gxg_gtk_combo_box_set_row_separator_func_w, gxg_gtk_combo_box_set_row_separator_func) Xen_wrap_2_args(gxg_gtk_label_set_ellipsize_w, gxg_gtk_label_set_ellipsize) Xen_wrap_1_arg(gxg_gtk_label_get_ellipsize_w, gxg_gtk_label_get_ellipsize) Xen_wrap_1_arg(gxg_pango_attr_fallback_new_w, gxg_pango_attr_fallback_new) Xen_wrap_1_arg(gxg_pango_attr_letter_spacing_new_w, gxg_pango_attr_letter_spacing_new) Xen_wrap_3_args(gxg_pango_attr_list_filter_w, gxg_pango_attr_list_filter) Xen_wrap_1_arg(gxg_pango_attr_iterator_get_attrs_w, gxg_pango_attr_iterator_get_attrs) Xen_wrap_1_arg(gxg_pango_font_metrics_get_underline_position_w, gxg_pango_font_metrics_get_underline_position) Xen_wrap_1_arg(gxg_pango_font_metrics_get_underline_thickness_w, gxg_pango_font_metrics_get_underline_thickness) Xen_wrap_1_arg(gxg_pango_font_metrics_get_strikethrough_position_w, gxg_pango_font_metrics_get_strikethrough_position) Xen_wrap_1_arg(gxg_pango_font_metrics_get_strikethrough_thickness_w, gxg_pango_font_metrics_get_strikethrough_thickness) Xen_wrap_1_arg(gxg_pango_font_family_is_monospace_w, gxg_pango_font_family_is_monospace) Xen_wrap_3_optional_args(gxg_pango_font_face_list_sizes_w, gxg_pango_font_face_list_sizes) Xen_wrap_2_args(gxg_pango_layout_set_auto_dir_w, gxg_pango_layout_set_auto_dir) Xen_wrap_1_arg(gxg_pango_layout_get_auto_dir_w, gxg_pango_layout_get_auto_dir) Xen_wrap_1_arg(gxg_pango_script_for_unichar_w, gxg_pango_script_for_unichar) Xen_wrap_2_args(gxg_pango_script_iter_new_w, gxg_pango_script_iter_new) Xen_wrap_4_optional_args(gxg_pango_script_iter_get_range_w, gxg_pango_script_iter_get_range) Xen_wrap_1_arg(gxg_pango_script_iter_next_w, gxg_pango_script_iter_next) Xen_wrap_1_arg(gxg_pango_script_iter_free_w, gxg_pango_script_iter_free) Xen_wrap_1_arg(gxg_gtk_file_chooser_button_new_with_dialog_w, gxg_gtk_file_chooser_button_new_with_dialog) Xen_wrap_1_arg(gxg_gtk_file_chooser_button_get_title_w, gxg_gtk_file_chooser_button_get_title) Xen_wrap_2_args(gxg_gtk_file_chooser_button_set_title_w, gxg_gtk_file_chooser_button_set_title) Xen_wrap_1_arg(gxg_gdk_drag_drop_succeeded_w, gxg_gdk_drag_drop_succeeded) Xen_wrap_2_args(gxg_gtk_entry_layout_index_to_text_index_w, gxg_gtk_entry_layout_index_to_text_index) Xen_wrap_2_args(gxg_gtk_entry_text_index_to_layout_index_w, gxg_gtk_entry_text_index_to_layout_index) Xen_wrap_2_args(gxg_gtk_file_chooser_set_show_hidden_w, gxg_gtk_file_chooser_set_show_hidden) Xen_wrap_1_arg(gxg_gtk_file_chooser_get_show_hidden_w, gxg_gtk_file_chooser_get_show_hidden) Xen_wrap_2_args(gxg_gtk_tree_view_set_hover_expand_w, gxg_gtk_tree_view_set_hover_expand) Xen_wrap_1_arg(gxg_gtk_tree_view_get_hover_expand_w, gxg_gtk_tree_view_get_hover_expand) Xen_wrap_1_arg(gxg_gtk_tool_item_rebuild_menu_w, gxg_gtk_tool_item_rebuild_menu) Xen_wrap_2_args(gxg_gtk_menu_tool_button_new_w, gxg_gtk_menu_tool_button_new) Xen_wrap_2_args(gxg_gtk_menu_tool_button_set_menu_w, gxg_gtk_menu_tool_button_set_menu) Xen_wrap_1_arg(gxg_gtk_menu_tool_button_get_menu_w, gxg_gtk_menu_tool_button_get_menu) Xen_wrap_1_arg(gxg_gdk_display_supports_clipboard_persistence_w, gxg_gdk_display_supports_clipboard_persistence) Xen_wrap_1_arg(gxg_gtk_about_dialog_get_logo_icon_name_w, gxg_gtk_about_dialog_get_logo_icon_name) Xen_wrap_2_args(gxg_gtk_about_dialog_set_logo_icon_name_w, gxg_gtk_about_dialog_set_logo_icon_name) Xen_wrap_2_args(gxg_gtk_accelerator_get_label_w, gxg_gtk_accelerator_get_label) Xen_wrap_2_args(gxg_gtk_clipboard_wait_is_target_available_w, gxg_gtk_clipboard_wait_is_target_available) Xen_wrap_3_args(gxg_gtk_clipboard_set_can_store_w, gxg_gtk_clipboard_set_can_store) Xen_wrap_1_arg(gxg_gtk_clipboard_store_w, gxg_gtk_clipboard_store) Xen_wrap_1_arg(gxg_gtk_drag_dest_add_image_targets_w, gxg_gtk_drag_dest_add_image_targets) Xen_wrap_1_arg(gxg_gtk_drag_dest_add_uri_targets_w, gxg_gtk_drag_dest_add_uri_targets) Xen_wrap_1_arg(gxg_gtk_drag_source_add_image_targets_w, gxg_gtk_drag_source_add_image_targets) Xen_wrap_1_arg(gxg_gtk_drag_source_add_uri_targets_w, gxg_gtk_drag_source_add_uri_targets) Xen_wrap_1_arg(gxg_gtk_file_chooser_button_get_width_chars_w, gxg_gtk_file_chooser_button_get_width_chars) Xen_wrap_2_args(gxg_gtk_file_chooser_button_set_width_chars_w, gxg_gtk_file_chooser_button_set_width_chars) Xen_wrap_2_args(gxg_gtk_image_set_pixel_size_w, gxg_gtk_image_set_pixel_size) Xen_wrap_1_arg(gxg_gtk_image_get_pixel_size_w, gxg_gtk_image_get_pixel_size) Xen_wrap_2_args(gxg_gtk_label_set_width_chars_w, gxg_gtk_label_set_width_chars) Xen_wrap_1_arg(gxg_gtk_label_get_width_chars_w, gxg_gtk_label_get_width_chars) Xen_wrap_2_args(gxg_gtk_target_list_add_text_targets_w, gxg_gtk_target_list_add_text_targets) Xen_wrap_3_args(gxg_gtk_target_list_add_image_targets_w, gxg_gtk_target_list_add_image_targets) Xen_wrap_2_args(gxg_gtk_target_list_add_uri_targets_w, gxg_gtk_target_list_add_uri_targets) Xen_wrap_2_args(gxg_gtk_selection_data_set_pixbuf_w, gxg_gtk_selection_data_set_pixbuf) Xen_wrap_1_arg(gxg_gtk_selection_data_get_pixbuf_w, gxg_gtk_selection_data_get_pixbuf) Xen_wrap_2_args(gxg_gtk_selection_data_set_uris_w, gxg_gtk_selection_data_set_uris) Xen_wrap_1_arg(gxg_gtk_selection_data_get_uris_w, gxg_gtk_selection_data_get_uris) Xen_wrap_4_args(gxg_gtk_text_buffer_backspace_w, gxg_gtk_text_buffer_backspace) Xen_wrap_2_args(gxg_gtk_clipboard_set_image_w, gxg_gtk_clipboard_set_image) Xen_wrap_3_optional_args(gxg_gtk_clipboard_request_image_w, gxg_gtk_clipboard_request_image) Xen_wrap_1_arg(gxg_gtk_clipboard_wait_for_image_w, gxg_gtk_clipboard_wait_for_image) Xen_wrap_1_arg(gxg_gtk_clipboard_wait_is_image_available_w, gxg_gtk_clipboard_wait_is_image_available) Xen_wrap_1_arg(gxg_gtk_file_filter_add_pixbuf_formats_w, gxg_gtk_file_filter_add_pixbuf_formats) Xen_wrap_2_args(gxg_gtk_label_set_single_line_mode_w, gxg_gtk_label_set_single_line_mode) Xen_wrap_1_arg(gxg_gtk_label_get_single_line_mode_w, gxg_gtk_label_get_single_line_mode) Xen_wrap_2_args(gxg_gtk_progress_bar_set_ellipsize_w, gxg_gtk_progress_bar_set_ellipsize) Xen_wrap_1_arg(gxg_gtk_progress_bar_get_ellipsize_w, gxg_gtk_progress_bar_get_ellipsize) Xen_wrap_2_args(gxg_gtk_selection_data_targets_include_image_w, gxg_gtk_selection_data_targets_include_image) Xen_wrap_2_args(gxg_gtk_button_set_image_w, gxg_gtk_button_set_image) Xen_wrap_1_arg(gxg_gtk_button_get_image_w, gxg_gtk_button_get_image) Xen_wrap_2_args(gxg_gtk_label_set_angle_w, gxg_gtk_label_set_angle) Xen_wrap_1_arg(gxg_gtk_label_get_angle_w, gxg_gtk_label_get_angle) Xen_wrap_2_args(gxg_gtk_menu_set_screen_w, gxg_gtk_menu_set_screen) Xen_wrap_3_args(gxg_pango_attr_underline_color_new_w, gxg_pango_attr_underline_color_new) Xen_wrap_3_args(gxg_pango_attr_strikethrough_color_new_w, gxg_pango_attr_strikethrough_color_new) Xen_wrap_4_args(gxg_pango_renderer_draw_layout_w, gxg_pango_renderer_draw_layout) Xen_wrap_4_args(gxg_pango_renderer_draw_layout_line_w, gxg_pango_renderer_draw_layout_line) Xen_wrap_5_args(gxg_pango_renderer_draw_glyphs_w, gxg_pango_renderer_draw_glyphs) Xen_wrap_6_args(gxg_pango_renderer_draw_rectangle_w, gxg_pango_renderer_draw_rectangle) Xen_wrap_5_args(gxg_pango_renderer_draw_error_underline_w, gxg_pango_renderer_draw_error_underline) Xen_wrap_any_args(gxg_pango_renderer_draw_trapezoid_w, gxg_pango_renderer_draw_trapezoid) Xen_wrap_5_args(gxg_pango_renderer_draw_glyph_w, gxg_pango_renderer_draw_glyph) Xen_wrap_1_arg(gxg_pango_renderer_activate_w, gxg_pango_renderer_activate) Xen_wrap_1_arg(gxg_pango_renderer_deactivate_w, gxg_pango_renderer_deactivate) Xen_wrap_2_args(gxg_pango_renderer_part_changed_w, gxg_pango_renderer_part_changed) Xen_wrap_3_args(gxg_pango_renderer_set_color_w, gxg_pango_renderer_set_color) Xen_wrap_2_args(gxg_pango_renderer_get_color_w, gxg_pango_renderer_get_color) Xen_wrap_2_args(gxg_pango_renderer_set_matrix_w, gxg_pango_renderer_set_matrix) Xen_wrap_4_optional_args(gxg_g_log_set_handler_w, gxg_g_log_set_handler) Xen_wrap_2_args(gxg_g_log_remove_handler_w, gxg_g_log_remove_handler) Xen_wrap_2_args(gxg_gtk_cell_renderer_stop_editing_w, gxg_gtk_cell_renderer_stop_editing) Xen_wrap_2_args(gxg_gtk_file_chooser_button_new_w, gxg_gtk_file_chooser_button_new) Xen_wrap_2_args(gxg_gtk_icon_view_set_columns_w, gxg_gtk_icon_view_set_columns) Xen_wrap_1_arg(gxg_gtk_icon_view_get_columns_w, gxg_gtk_icon_view_get_columns) Xen_wrap_2_args(gxg_gtk_icon_view_set_item_width_w, gxg_gtk_icon_view_set_item_width) Xen_wrap_1_arg(gxg_gtk_icon_view_get_item_width_w, gxg_gtk_icon_view_get_item_width) Xen_wrap_2_args(gxg_gtk_icon_view_set_spacing_w, gxg_gtk_icon_view_set_spacing) Xen_wrap_1_arg(gxg_gtk_icon_view_get_spacing_w, gxg_gtk_icon_view_get_spacing) Xen_wrap_2_args(gxg_gtk_icon_view_set_row_spacing_w, gxg_gtk_icon_view_set_row_spacing) Xen_wrap_1_arg(gxg_gtk_icon_view_get_row_spacing_w, gxg_gtk_icon_view_get_row_spacing) Xen_wrap_2_args(gxg_gtk_icon_view_set_column_spacing_w, gxg_gtk_icon_view_set_column_spacing) Xen_wrap_1_arg(gxg_gtk_icon_view_get_column_spacing_w, gxg_gtk_icon_view_get_column_spacing) Xen_wrap_2_args(gxg_gtk_icon_view_set_margin_w, gxg_gtk_icon_view_set_margin) Xen_wrap_1_arg(gxg_gtk_icon_view_get_margin_w, gxg_gtk_icon_view_get_margin) Xen_wrap_2_args(gxg_gtk_label_set_max_width_chars_w, gxg_gtk_label_set_max_width_chars) Xen_wrap_1_arg(gxg_gtk_label_get_max_width_chars_w, gxg_gtk_label_get_max_width_chars) Xen_wrap_3_args(gxg_gtk_list_store_insert_with_values_w, gxg_gtk_list_store_insert_with_values) Xen_wrap_6_args(gxg_gtk_list_store_insert_with_valuesv_w, gxg_gtk_list_store_insert_with_valuesv) Xen_wrap_5_optional_args(gxg_gtk_text_view_get_iter_at_position_w, gxg_gtk_text_view_get_iter_at_position) Xen_wrap_1_arg(gxg_pango_attr_size_new_absolute_w, gxg_pango_attr_size_new_absolute) Xen_wrap_2_args(gxg_pango_font_description_set_absolute_size_w, gxg_pango_font_description_set_absolute_size) Xen_wrap_1_arg(gxg_pango_layout_get_font_description_w, gxg_pango_layout_get_font_description) Xen_wrap_2_args(gxg_gdk_cursor_new_from_name_w, gxg_gdk_cursor_new_from_name) Xen_wrap_1_arg(gxg_gdk_cursor_get_image_w, gxg_gdk_cursor_get_image) Xen_wrap_1_arg(gxg_gdk_screen_get_rgba_visual_w, gxg_gdk_screen_get_rgba_visual) Xen_wrap_2_args(gxg_gdk_window_set_urgency_hint_w, gxg_gdk_window_set_urgency_hint) Xen_wrap_2_args(gxg_gtk_dialog_get_response_for_widget_w, gxg_gtk_dialog_get_response_for_widget) Xen_wrap_2_args(gxg_gtk_drag_source_set_icon_name_w, gxg_gtk_drag_source_set_icon_name) Xen_wrap_4_args(gxg_gtk_drag_set_icon_name_w, gxg_gtk_drag_set_icon_name) Xen_wrap_2_args(gxg_gtk_entry_completion_set_popup_set_width_w, gxg_gtk_entry_completion_set_popup_set_width) Xen_wrap_1_arg(gxg_gtk_entry_completion_get_popup_set_width_w, gxg_gtk_entry_completion_get_popup_set_width) Xen_wrap_2_args(gxg_gtk_entry_completion_set_popup_single_match_w, gxg_gtk_entry_completion_set_popup_single_match) Xen_wrap_1_arg(gxg_gtk_entry_completion_get_popup_single_match_w, gxg_gtk_entry_completion_get_popup_single_match) Xen_wrap_5_optional_args(gxg_gtk_icon_view_get_item_at_pos_w, gxg_gtk_icon_view_get_item_at_pos) Xen_wrap_3_optional_args(gxg_gtk_icon_view_get_visible_range_w, gxg_gtk_icon_view_get_visible_range) Xen_wrap_4_args(gxg_gtk_icon_view_set_cursor_w, gxg_gtk_icon_view_set_cursor) Xen_wrap_3_optional_args(gxg_gtk_icon_view_get_cursor_w, gxg_gtk_icon_view_get_cursor) Xen_wrap_5_args(gxg_gtk_icon_view_scroll_to_path_w, gxg_gtk_icon_view_scroll_to_path) Xen_wrap_5_args(gxg_gtk_icon_view_enable_model_drag_source_w, gxg_gtk_icon_view_enable_model_drag_source) Xen_wrap_4_args(gxg_gtk_icon_view_enable_model_drag_dest_w, gxg_gtk_icon_view_enable_model_drag_dest) Xen_wrap_1_arg(gxg_gtk_icon_view_unset_model_drag_source_w, gxg_gtk_icon_view_unset_model_drag_source) Xen_wrap_1_arg(gxg_gtk_icon_view_unset_model_drag_dest_w, gxg_gtk_icon_view_unset_model_drag_dest) Xen_wrap_2_args(gxg_gtk_icon_view_set_reorderable_w, gxg_gtk_icon_view_set_reorderable) Xen_wrap_1_arg(gxg_gtk_icon_view_get_reorderable_w, gxg_gtk_icon_view_get_reorderable) Xen_wrap_3_args(gxg_gtk_icon_view_set_drag_dest_item_w, gxg_gtk_icon_view_set_drag_dest_item) Xen_wrap_3_optional_args(gxg_gtk_icon_view_get_drag_dest_item_w, gxg_gtk_icon_view_get_drag_dest_item) Xen_wrap_5_optional_args(gxg_gtk_icon_view_get_dest_item_at_pos_w, gxg_gtk_icon_view_get_dest_item_at_pos) Xen_wrap_1_arg(gxg_gtk_image_clear_w, gxg_gtk_image_clear) Xen_wrap_1_arg(gxg_gtk_menu_bar_get_pack_direction_w, gxg_gtk_menu_bar_get_pack_direction) Xen_wrap_2_args(gxg_gtk_menu_bar_set_pack_direction_w, gxg_gtk_menu_bar_set_pack_direction) Xen_wrap_1_arg(gxg_gtk_menu_bar_get_child_pack_direction_w, gxg_gtk_menu_bar_get_child_pack_direction) Xen_wrap_2_args(gxg_gtk_menu_bar_set_child_pack_direction_w, gxg_gtk_menu_bar_set_child_pack_direction) Xen_wrap_1_arg(gxg_gtk_menu_shell_get_take_focus_w, gxg_gtk_menu_shell_get_take_focus) Xen_wrap_2_args(gxg_gtk_menu_shell_set_take_focus_w, gxg_gtk_menu_shell_set_take_focus) Xen_wrap_2_args(gxg_gtk_size_group_set_ignore_hidden_w, gxg_gtk_size_group_set_ignore_hidden) Xen_wrap_1_arg(gxg_gtk_size_group_get_ignore_hidden_w, gxg_gtk_size_group_get_ignore_hidden) Xen_wrap_1_arg(gxg_gtk_text_iter_forward_visible_line_w, gxg_gtk_text_iter_forward_visible_line) Xen_wrap_1_arg(gxg_gtk_text_iter_backward_visible_line_w, gxg_gtk_text_iter_backward_visible_line) Xen_wrap_2_args(gxg_gtk_text_iter_forward_visible_lines_w, gxg_gtk_text_iter_forward_visible_lines) Xen_wrap_2_args(gxg_gtk_text_iter_backward_visible_lines_w, gxg_gtk_text_iter_backward_visible_lines) Xen_wrap_2_args(gxg_gtk_tool_button_set_icon_name_w, gxg_gtk_tool_button_set_icon_name) Xen_wrap_1_arg(gxg_gtk_tool_button_get_icon_name_w, gxg_gtk_tool_button_get_icon_name) Xen_wrap_2_args(gxg_gtk_window_set_urgency_hint_w, gxg_gtk_window_set_urgency_hint) Xen_wrap_1_arg(gxg_gtk_window_get_urgency_hint_w, gxg_gtk_window_get_urgency_hint) Xen_wrap_2_args(gxg_gtk_window_present_with_time_w, gxg_gtk_window_present_with_time) Xen_wrap_2_args(gxg_gtk_file_chooser_set_do_overwrite_confirmation_w, gxg_gtk_file_chooser_set_do_overwrite_confirmation) Xen_wrap_1_arg(gxg_gtk_file_chooser_get_do_overwrite_confirmation_w, gxg_gtk_file_chooser_get_do_overwrite_confirmation) Xen_wrap_1_arg(gxg_gtk_tree_row_reference_get_model_w, gxg_gtk_tree_row_reference_get_model) Xen_wrap_1_arg(gxg_gtk_tree_view_column_queue_resize_w, gxg_gtk_tree_view_column_queue_resize) Xen_wrap_3_optional_args(gxg_gtk_tree_view_get_visible_range_w, gxg_gtk_tree_view_get_visible_range) Xen_wrap_1_arg(gxg_gtk_text_attributes_ref_w, gxg_gtk_text_attributes_ref) Xen_wrap_1_arg(gxg_pango_attr_list_ref_w, gxg_pango_attr_list_ref) Xen_wrap_1_arg(gxg_pango_layout_line_ref_w, gxg_pango_layout_line_ref) Xen_wrap_5_optional_args(gxg_pango_layout_index_to_line_x_w, gxg_pango_layout_index_to_line_x) Xen_wrap_1_arg(gxg_gtk_target_list_ref_w, gxg_gtk_target_list_ref) Xen_wrap_1_arg(gxg_gdk_display_supports_shapes_w, gxg_gdk_display_supports_shapes) Xen_wrap_1_arg(gxg_gdk_display_supports_input_shapes_w, gxg_gdk_display_supports_input_shapes) Xen_wrap_1_arg(gxg_gdk_screen_is_composited_w, gxg_gdk_screen_is_composited) Xen_wrap_2_args(gxg_gdk_screen_set_resolution_w, gxg_gdk_screen_set_resolution) Xen_wrap_1_arg(gxg_gdk_screen_get_resolution_w, gxg_gdk_screen_get_resolution) Xen_wrap_1_arg(gxg_gdk_screen_get_active_window_w, gxg_gdk_screen_get_active_window) Xen_wrap_1_arg(gxg_gdk_screen_get_window_stack_w, gxg_gdk_screen_get_window_stack) Xen_wrap_1_arg(gxg_gdk_window_get_type_hint_w, gxg_gdk_window_get_type_hint) Xen_wrap_4_optional_args(gxg_gtk_clipboard_request_rich_text_w, gxg_gtk_clipboard_request_rich_text) Xen_wrap_4_optional_args(gxg_gtk_clipboard_wait_for_rich_text_w, gxg_gtk_clipboard_wait_for_rich_text) Xen_wrap_2_args(gxg_gtk_clipboard_wait_is_rich_text_available_w, gxg_gtk_clipboard_wait_is_rich_text_available) Xen_wrap_2_args(gxg_gtk_drag_dest_set_track_motion_w, gxg_gtk_drag_dest_set_track_motion) Xen_wrap_1_arg(gxg_gtk_drag_dest_get_track_motion_w, gxg_gtk_drag_dest_get_track_motion) Xen_wrap_2_args(gxg_gtk_notebook_get_tab_reorderable_w, gxg_gtk_notebook_get_tab_reorderable) Xen_wrap_3_args(gxg_gtk_notebook_set_tab_reorderable_w, gxg_gtk_notebook_set_tab_reorderable) Xen_wrap_2_args(gxg_gtk_notebook_get_tab_detachable_w, gxg_gtk_notebook_get_tab_detachable) Xen_wrap_3_args(gxg_gtk_notebook_set_tab_detachable_w, gxg_gtk_notebook_set_tab_detachable) Xen_wrap_2_args(gxg_gtk_range_set_lower_stepper_sensitivity_w, gxg_gtk_range_set_lower_stepper_sensitivity) Xen_wrap_1_arg(gxg_gtk_range_get_lower_stepper_sensitivity_w, gxg_gtk_range_get_lower_stepper_sensitivity) Xen_wrap_2_args(gxg_gtk_range_set_upper_stepper_sensitivity_w, gxg_gtk_range_set_upper_stepper_sensitivity) Xen_wrap_1_arg(gxg_gtk_range_get_upper_stepper_sensitivity_w, gxg_gtk_range_get_upper_stepper_sensitivity) Xen_wrap_1_arg(gxg_gtk_scrolled_window_unset_placement_w, gxg_gtk_scrolled_window_unset_placement) Xen_wrap_4_args(gxg_gtk_target_list_add_rich_text_targets_w, gxg_gtk_target_list_add_rich_text_targets) Xen_wrap_2_optional_args(gxg_gtk_target_table_new_from_list_w, gxg_gtk_target_table_new_from_list) Xen_wrap_2_args(gxg_gtk_target_table_free_w, gxg_gtk_target_table_free) Xen_wrap_2_args(gxg_gtk_selection_data_targets_include_rich_text_w, gxg_gtk_selection_data_targets_include_rich_text) Xen_wrap_1_arg(gxg_gtk_selection_data_targets_include_uri_w, gxg_gtk_selection_data_targets_include_uri) Xen_wrap_2_args(gxg_gtk_targets_include_text_w, gxg_gtk_targets_include_text) Xen_wrap_3_args(gxg_gtk_targets_include_rich_text_w, gxg_gtk_targets_include_rich_text) Xen_wrap_3_args(gxg_gtk_targets_include_image_w, gxg_gtk_targets_include_image) Xen_wrap_2_args(gxg_gtk_targets_include_uri_w, gxg_gtk_targets_include_uri) Xen_wrap_1_arg(gxg_gtk_size_group_get_widgets_w, gxg_gtk_size_group_get_widgets) Xen_wrap_1_arg(gxg_gtk_text_buffer_get_has_selection_w, gxg_gtk_text_buffer_get_has_selection) Xen_wrap_1_arg(gxg_gtk_text_buffer_get_copy_target_list_w, gxg_gtk_text_buffer_get_copy_target_list) Xen_wrap_1_arg(gxg_gtk_text_buffer_get_paste_target_list_w, gxg_gtk_text_buffer_get_paste_target_list) Xen_wrap_1_arg(gxg_gtk_tree_view_get_headers_clickable_w, gxg_gtk_tree_view_get_headers_clickable) Xen_wrap_1_arg(gxg_gtk_tree_view_get_search_entry_w, gxg_gtk_tree_view_get_search_entry) Xen_wrap_2_args(gxg_gtk_tree_view_set_search_entry_w, gxg_gtk_tree_view_set_search_entry) Xen_wrap_1_arg(gxg_gtk_tree_view_get_search_position_func_w, gxg_gtk_tree_view_get_search_position_func) Xen_wrap_4_optional_args(gxg_gtk_tree_view_set_search_position_func_w, gxg_gtk_tree_view_set_search_position_func) Xen_wrap_1_arg(gxg_gtk_widget_is_composited_w, gxg_gtk_widget_is_composited) Xen_wrap_2_args(gxg_gtk_window_set_deletable_w, gxg_gtk_window_set_deletable) Xen_wrap_1_arg(gxg_gtk_window_get_deletable_w, gxg_gtk_window_get_deletable) Xen_wrap_no_args(gxg_gtk_assistant_new_w, gxg_gtk_assistant_new) Xen_wrap_1_arg(gxg_gtk_assistant_get_current_page_w, gxg_gtk_assistant_get_current_page) Xen_wrap_2_args(gxg_gtk_assistant_set_current_page_w, gxg_gtk_assistant_set_current_page) Xen_wrap_1_arg(gxg_gtk_assistant_get_n_pages_w, gxg_gtk_assistant_get_n_pages) Xen_wrap_2_args(gxg_gtk_assistant_get_nth_page_w, gxg_gtk_assistant_get_nth_page) Xen_wrap_2_args(gxg_gtk_assistant_prepend_page_w, gxg_gtk_assistant_prepend_page) Xen_wrap_2_args(gxg_gtk_assistant_append_page_w, gxg_gtk_assistant_append_page) Xen_wrap_3_args(gxg_gtk_assistant_insert_page_w, gxg_gtk_assistant_insert_page) Xen_wrap_4_optional_args(gxg_gtk_assistant_set_forward_page_func_w, gxg_gtk_assistant_set_forward_page_func) Xen_wrap_3_args(gxg_gtk_assistant_set_page_type_w, gxg_gtk_assistant_set_page_type) Xen_wrap_2_args(gxg_gtk_assistant_get_page_type_w, gxg_gtk_assistant_get_page_type) Xen_wrap_3_args(gxg_gtk_assistant_set_page_title_w, gxg_gtk_assistant_set_page_title) Xen_wrap_2_args(gxg_gtk_assistant_get_page_title_w, gxg_gtk_assistant_get_page_title) Xen_wrap_3_args(gxg_gtk_assistant_set_page_complete_w, gxg_gtk_assistant_set_page_complete) Xen_wrap_2_args(gxg_gtk_assistant_get_page_complete_w, gxg_gtk_assistant_get_page_complete) Xen_wrap_2_args(gxg_gtk_assistant_add_action_widget_w, gxg_gtk_assistant_add_action_widget) Xen_wrap_2_args(gxg_gtk_assistant_remove_action_widget_w, gxg_gtk_assistant_remove_action_widget) Xen_wrap_1_arg(gxg_gtk_assistant_update_buttons_state_w, gxg_gtk_assistant_update_buttons_state) Xen_wrap_no_args(gxg_gtk_cell_renderer_accel_new_w, gxg_gtk_cell_renderer_accel_new) Xen_wrap_no_args(gxg_gtk_cell_renderer_spin_new_w, gxg_gtk_cell_renderer_spin_new) Xen_wrap_1_arg(gxg_gtk_link_button_new_w, gxg_gtk_link_button_new) Xen_wrap_2_args(gxg_gtk_link_button_new_with_label_w, gxg_gtk_link_button_new_with_label) Xen_wrap_1_arg(gxg_gtk_link_button_get_uri_w, gxg_gtk_link_button_get_uri) Xen_wrap_2_args(gxg_gtk_link_button_set_uri_w, gxg_gtk_link_button_set_uri) Xen_wrap_no_args(gxg_gtk_recent_chooser_error_quark_w, gxg_gtk_recent_chooser_error_quark) Xen_wrap_2_args(gxg_gtk_recent_chooser_set_show_private_w, gxg_gtk_recent_chooser_set_show_private) Xen_wrap_1_arg(gxg_gtk_recent_chooser_get_show_private_w, gxg_gtk_recent_chooser_get_show_private) Xen_wrap_2_args(gxg_gtk_recent_chooser_set_show_not_found_w, gxg_gtk_recent_chooser_set_show_not_found) Xen_wrap_1_arg(gxg_gtk_recent_chooser_get_show_not_found_w, gxg_gtk_recent_chooser_get_show_not_found) Xen_wrap_2_args(gxg_gtk_recent_chooser_set_select_multiple_w, gxg_gtk_recent_chooser_set_select_multiple) Xen_wrap_1_arg(gxg_gtk_recent_chooser_get_select_multiple_w, gxg_gtk_recent_chooser_get_select_multiple) Xen_wrap_2_args(gxg_gtk_recent_chooser_set_limit_w, gxg_gtk_recent_chooser_set_limit) Xen_wrap_1_arg(gxg_gtk_recent_chooser_get_limit_w, gxg_gtk_recent_chooser_get_limit) Xen_wrap_2_args(gxg_gtk_recent_chooser_set_local_only_w, gxg_gtk_recent_chooser_set_local_only) Xen_wrap_1_arg(gxg_gtk_recent_chooser_get_local_only_w, gxg_gtk_recent_chooser_get_local_only) Xen_wrap_2_args(gxg_gtk_recent_chooser_set_show_tips_w, gxg_gtk_recent_chooser_set_show_tips) Xen_wrap_1_arg(gxg_gtk_recent_chooser_get_show_tips_w, gxg_gtk_recent_chooser_get_show_tips) Xen_wrap_2_args(gxg_gtk_recent_chooser_set_show_icons_w, gxg_gtk_recent_chooser_set_show_icons) Xen_wrap_1_arg(gxg_gtk_recent_chooser_get_show_icons_w, gxg_gtk_recent_chooser_get_show_icons) Xen_wrap_2_args(gxg_gtk_recent_chooser_set_sort_type_w, gxg_gtk_recent_chooser_set_sort_type) Xen_wrap_1_arg(gxg_gtk_recent_chooser_get_sort_type_w, gxg_gtk_recent_chooser_get_sort_type) Xen_wrap_4_optional_args(gxg_gtk_recent_chooser_set_sort_func_w, gxg_gtk_recent_chooser_set_sort_func) Xen_wrap_3_optional_args(gxg_gtk_recent_chooser_set_current_uri_w, gxg_gtk_recent_chooser_set_current_uri) Xen_wrap_1_arg(gxg_gtk_recent_chooser_get_current_uri_w, gxg_gtk_recent_chooser_get_current_uri) Xen_wrap_1_arg(gxg_gtk_recent_chooser_get_current_item_w, gxg_gtk_recent_chooser_get_current_item) Xen_wrap_3_optional_args(gxg_gtk_recent_chooser_select_uri_w, gxg_gtk_recent_chooser_select_uri) Xen_wrap_2_args(gxg_gtk_recent_chooser_unselect_uri_w, gxg_gtk_recent_chooser_unselect_uri) Xen_wrap_1_arg(gxg_gtk_recent_chooser_select_all_w, gxg_gtk_recent_chooser_select_all) Xen_wrap_1_arg(gxg_gtk_recent_chooser_unselect_all_w, gxg_gtk_recent_chooser_unselect_all) Xen_wrap_1_arg(gxg_gtk_recent_chooser_get_items_w, gxg_gtk_recent_chooser_get_items) Xen_wrap_2_optional_args(gxg_gtk_recent_chooser_get_uris_w, gxg_gtk_recent_chooser_get_uris) Xen_wrap_2_args(gxg_gtk_recent_chooser_add_filter_w, gxg_gtk_recent_chooser_add_filter) Xen_wrap_2_args(gxg_gtk_recent_chooser_remove_filter_w, gxg_gtk_recent_chooser_remove_filter) Xen_wrap_1_arg(gxg_gtk_recent_chooser_list_filters_w, gxg_gtk_recent_chooser_list_filters) Xen_wrap_2_args(gxg_gtk_recent_chooser_set_filter_w, gxg_gtk_recent_chooser_set_filter) Xen_wrap_1_arg(gxg_gtk_recent_chooser_get_filter_w, gxg_gtk_recent_chooser_get_filter) Xen_wrap_no_args(gxg_gtk_recent_chooser_menu_new_w, gxg_gtk_recent_chooser_menu_new) Xen_wrap_1_arg(gxg_gtk_recent_chooser_menu_new_for_manager_w, gxg_gtk_recent_chooser_menu_new_for_manager) Xen_wrap_1_arg(gxg_gtk_recent_chooser_menu_get_show_numbers_w, gxg_gtk_recent_chooser_menu_get_show_numbers) Xen_wrap_2_args(gxg_gtk_recent_chooser_menu_set_show_numbers_w, gxg_gtk_recent_chooser_menu_set_show_numbers) Xen_wrap_no_args(gxg_gtk_recent_chooser_widget_new_w, gxg_gtk_recent_chooser_widget_new) Xen_wrap_1_arg(gxg_gtk_recent_chooser_widget_new_for_manager_w, gxg_gtk_recent_chooser_widget_new_for_manager) Xen_wrap_no_args(gxg_gtk_recent_filter_new_w, gxg_gtk_recent_filter_new) Xen_wrap_2_args(gxg_gtk_recent_filter_set_name_w, gxg_gtk_recent_filter_set_name) Xen_wrap_1_arg(gxg_gtk_recent_filter_get_name_w, gxg_gtk_recent_filter_get_name) Xen_wrap_2_args(gxg_gtk_recent_filter_add_mime_type_w, gxg_gtk_recent_filter_add_mime_type) Xen_wrap_2_args(gxg_gtk_recent_filter_add_pattern_w, gxg_gtk_recent_filter_add_pattern) Xen_wrap_1_arg(gxg_gtk_recent_filter_add_pixbuf_formats_w, gxg_gtk_recent_filter_add_pixbuf_formats) Xen_wrap_2_args(gxg_gtk_recent_filter_add_application_w, gxg_gtk_recent_filter_add_application) Xen_wrap_2_args(gxg_gtk_recent_filter_add_group_w, gxg_gtk_recent_filter_add_group) Xen_wrap_2_args(gxg_gtk_recent_filter_add_age_w, gxg_gtk_recent_filter_add_age) Xen_wrap_no_args(gxg_gtk_recent_manager_error_quark_w, gxg_gtk_recent_manager_error_quark) Xen_wrap_no_args(gxg_gtk_recent_manager_new_w, gxg_gtk_recent_manager_new) Xen_wrap_no_args(gxg_gtk_recent_manager_get_default_w, gxg_gtk_recent_manager_get_default) Xen_wrap_3_optional_args(gxg_gtk_recent_manager_remove_item_w, gxg_gtk_recent_manager_remove_item) Xen_wrap_3_optional_args(gxg_gtk_recent_manager_lookup_item_w, gxg_gtk_recent_manager_lookup_item) Xen_wrap_2_args(gxg_gtk_recent_manager_has_item_w, gxg_gtk_recent_manager_has_item) Xen_wrap_4_optional_args(gxg_gtk_recent_manager_move_item_w, gxg_gtk_recent_manager_move_item) Xen_wrap_1_arg(gxg_gtk_recent_manager_get_items_w, gxg_gtk_recent_manager_get_items) Xen_wrap_2_optional_args(gxg_gtk_recent_manager_purge_items_w, gxg_gtk_recent_manager_purge_items) Xen_wrap_1_arg(gxg_gtk_recent_info_ref_w, gxg_gtk_recent_info_ref) Xen_wrap_1_arg(gxg_gtk_recent_info_unref_w, gxg_gtk_recent_info_unref) Xen_wrap_1_arg(gxg_gtk_recent_info_get_uri_w, gxg_gtk_recent_info_get_uri) Xen_wrap_1_arg(gxg_gtk_recent_info_get_display_name_w, gxg_gtk_recent_info_get_display_name) Xen_wrap_1_arg(gxg_gtk_recent_info_get_description_w, gxg_gtk_recent_info_get_description) Xen_wrap_1_arg(gxg_gtk_recent_info_get_mime_type_w, gxg_gtk_recent_info_get_mime_type) Xen_wrap_1_arg(gxg_gtk_recent_info_get_added_w, gxg_gtk_recent_info_get_added) Xen_wrap_1_arg(gxg_gtk_recent_info_get_modified_w, gxg_gtk_recent_info_get_modified) Xen_wrap_1_arg(gxg_gtk_recent_info_get_visited_w, gxg_gtk_recent_info_get_visited) Xen_wrap_1_arg(gxg_gtk_recent_info_get_private_hint_w, gxg_gtk_recent_info_get_private_hint) Xen_wrap_2_optional_args(gxg_gtk_recent_info_get_applications_w, gxg_gtk_recent_info_get_applications) Xen_wrap_1_arg(gxg_gtk_recent_info_last_application_w, gxg_gtk_recent_info_last_application) Xen_wrap_2_args(gxg_gtk_recent_info_has_application_w, gxg_gtk_recent_info_has_application) Xen_wrap_2_optional_args(gxg_gtk_recent_info_get_groups_w, gxg_gtk_recent_info_get_groups) Xen_wrap_2_args(gxg_gtk_recent_info_has_group_w, gxg_gtk_recent_info_has_group) Xen_wrap_2_args(gxg_gtk_recent_info_get_icon_w, gxg_gtk_recent_info_get_icon) Xen_wrap_1_arg(gxg_gtk_recent_info_get_short_name_w, gxg_gtk_recent_info_get_short_name) Xen_wrap_1_arg(gxg_gtk_recent_info_get_uri_display_w, gxg_gtk_recent_info_get_uri_display) Xen_wrap_1_arg(gxg_gtk_recent_info_get_age_w, gxg_gtk_recent_info_get_age) Xen_wrap_1_arg(gxg_gtk_recent_info_is_local_w, gxg_gtk_recent_info_is_local) Xen_wrap_1_arg(gxg_gtk_recent_info_exists_w, gxg_gtk_recent_info_exists) Xen_wrap_2_args(gxg_gtk_recent_info_match_w, gxg_gtk_recent_info_match) Xen_wrap_5_args(gxg_gtk_text_buffer_register_serialize_format_w, gxg_gtk_text_buffer_register_serialize_format) Xen_wrap_2_args(gxg_gtk_text_buffer_register_serialize_tagset_w, gxg_gtk_text_buffer_register_serialize_tagset) Xen_wrap_5_args(gxg_gtk_text_buffer_register_deserialize_format_w, gxg_gtk_text_buffer_register_deserialize_format) Xen_wrap_2_args(gxg_gtk_text_buffer_register_deserialize_tagset_w, gxg_gtk_text_buffer_register_deserialize_tagset) Xen_wrap_2_args(gxg_gtk_text_buffer_unregister_serialize_format_w, gxg_gtk_text_buffer_unregister_serialize_format) Xen_wrap_2_args(gxg_gtk_text_buffer_unregister_deserialize_format_w, gxg_gtk_text_buffer_unregister_deserialize_format) Xen_wrap_3_args(gxg_gtk_text_buffer_deserialize_set_can_create_tags_w, gxg_gtk_text_buffer_deserialize_set_can_create_tags) Xen_wrap_2_args(gxg_gtk_text_buffer_deserialize_get_can_create_tags_w, gxg_gtk_text_buffer_deserialize_get_can_create_tags) Xen_wrap_2_optional_args(gxg_gtk_text_buffer_get_serialize_formats_w, gxg_gtk_text_buffer_get_serialize_formats) Xen_wrap_2_optional_args(gxg_gtk_text_buffer_get_deserialize_formats_w, gxg_gtk_text_buffer_get_deserialize_formats) Xen_wrap_6_optional_args(gxg_gtk_text_buffer_serialize_w, gxg_gtk_text_buffer_serialize) Xen_wrap_7_optional_args(gxg_gtk_text_buffer_deserialize_w, gxg_gtk_text_buffer_deserialize) Xen_wrap_2_args(gxg_gtk_recent_manager_add_item_w, gxg_gtk_recent_manager_add_item) Xen_wrap_3_args(gxg_gtk_recent_manager_add_full_w, gxg_gtk_recent_manager_add_full) Xen_wrap_3_args(gxg_gtk_tree_model_filter_convert_child_iter_to_iter_w, gxg_gtk_tree_model_filter_convert_child_iter_to_iter) Xen_wrap_1_arg(gxg_gtk_tree_view_get_grid_lines_w, gxg_gtk_tree_view_get_grid_lines) Xen_wrap_2_args(gxg_gtk_tree_view_set_grid_lines_w, gxg_gtk_tree_view_set_grid_lines) Xen_wrap_1_arg(gxg_gtk_tree_view_get_enable_tree_lines_w, gxg_gtk_tree_view_get_enable_tree_lines) Xen_wrap_2_args(gxg_gtk_tree_view_set_enable_tree_lines_w, gxg_gtk_tree_view_set_enable_tree_lines) Xen_wrap_2_args(gxg_gtk_label_set_line_wrap_mode_w, gxg_gtk_label_set_line_wrap_mode) Xen_wrap_1_arg(gxg_gtk_label_get_line_wrap_mode_w, gxg_gtk_label_get_line_wrap_mode) Xen_wrap_1_arg(gxg_gtk_print_context_get_cairo_context_w, gxg_gtk_print_context_get_cairo_context) Xen_wrap_1_arg(gxg_gtk_print_context_get_page_setup_w, gxg_gtk_print_context_get_page_setup) Xen_wrap_1_arg(gxg_gtk_print_context_get_width_w, gxg_gtk_print_context_get_width) Xen_wrap_1_arg(gxg_gtk_print_context_get_height_w, gxg_gtk_print_context_get_height) Xen_wrap_1_arg(gxg_gtk_print_context_get_dpi_x_w, gxg_gtk_print_context_get_dpi_x) Xen_wrap_1_arg(gxg_gtk_print_context_get_dpi_y_w, gxg_gtk_print_context_get_dpi_y) Xen_wrap_1_arg(gxg_gtk_print_context_create_pango_context_w, gxg_gtk_print_context_create_pango_context) Xen_wrap_1_arg(gxg_gtk_print_context_create_pango_layout_w, gxg_gtk_print_context_create_pango_layout) Xen_wrap_4_args(gxg_gtk_print_context_set_cairo_context_w, gxg_gtk_print_context_set_cairo_context) Xen_wrap_no_args(gxg_gtk_print_operation_new_w, gxg_gtk_print_operation_new) Xen_wrap_2_args(gxg_gtk_print_operation_set_default_page_setup_w, gxg_gtk_print_operation_set_default_page_setup) Xen_wrap_1_arg(gxg_gtk_print_operation_get_default_page_setup_w, gxg_gtk_print_operation_get_default_page_setup) Xen_wrap_2_args(gxg_gtk_print_operation_set_print_settings_w, gxg_gtk_print_operation_set_print_settings) Xen_wrap_1_arg(gxg_gtk_print_operation_get_print_settings_w, gxg_gtk_print_operation_get_print_settings) Xen_wrap_2_args(gxg_gtk_print_operation_set_job_name_w, gxg_gtk_print_operation_set_job_name) Xen_wrap_2_args(gxg_gtk_print_operation_set_n_pages_w, gxg_gtk_print_operation_set_n_pages) Xen_wrap_2_args(gxg_gtk_print_operation_set_current_page_w, gxg_gtk_print_operation_set_current_page) Xen_wrap_2_args(gxg_gtk_print_operation_set_use_full_page_w, gxg_gtk_print_operation_set_use_full_page) Xen_wrap_2_args(gxg_gtk_print_operation_set_unit_w, gxg_gtk_print_operation_set_unit) Xen_wrap_2_args(gxg_gtk_print_operation_set_export_filename_w, gxg_gtk_print_operation_set_export_filename) Xen_wrap_2_args(gxg_gtk_print_operation_set_track_print_status_w, gxg_gtk_print_operation_set_track_print_status) Xen_wrap_2_args(gxg_gtk_print_operation_set_show_progress_w, gxg_gtk_print_operation_set_show_progress) Xen_wrap_2_args(gxg_gtk_print_operation_set_allow_async_w, gxg_gtk_print_operation_set_allow_async) Xen_wrap_2_args(gxg_gtk_print_operation_set_custom_tab_label_w, gxg_gtk_print_operation_set_custom_tab_label) Xen_wrap_4_optional_args(gxg_gtk_print_operation_run_w, gxg_gtk_print_operation_run) Xen_wrap_2_optional_args(gxg_gtk_print_operation_get_error_w, gxg_gtk_print_operation_get_error) Xen_wrap_1_arg(gxg_gtk_print_operation_get_status_w, gxg_gtk_print_operation_get_status) Xen_wrap_1_arg(gxg_gtk_print_operation_get_status_string_w, gxg_gtk_print_operation_get_status_string) Xen_wrap_1_arg(gxg_gtk_print_operation_is_finished_w, gxg_gtk_print_operation_is_finished) Xen_wrap_1_arg(gxg_gtk_print_operation_cancel_w, gxg_gtk_print_operation_cancel) Xen_wrap_3_args(gxg_gtk_print_run_page_setup_dialog_w, gxg_gtk_print_run_page_setup_dialog) Xen_wrap_5_args(gxg_gtk_print_run_page_setup_dialog_async_w, gxg_gtk_print_run_page_setup_dialog_async) Xen_wrap_2_args(gxg_gtk_print_operation_preview_render_page_w, gxg_gtk_print_operation_preview_render_page) Xen_wrap_1_arg(gxg_gtk_print_operation_preview_end_preview_w, gxg_gtk_print_operation_preview_end_preview) Xen_wrap_2_args(gxg_gtk_print_operation_preview_is_selected_w, gxg_gtk_print_operation_preview_is_selected) Xen_wrap_no_args(gxg_gtk_print_settings_new_w, gxg_gtk_print_settings_new) Xen_wrap_1_arg(gxg_gtk_print_settings_copy_w, gxg_gtk_print_settings_copy) Xen_wrap_2_args(gxg_gtk_print_settings_has_key_w, gxg_gtk_print_settings_has_key) Xen_wrap_2_args(gxg_gtk_print_settings_get_w, gxg_gtk_print_settings_get) Xen_wrap_3_args(gxg_gtk_print_settings_set_w, gxg_gtk_print_settings_set) Xen_wrap_2_args(gxg_gtk_print_settings_unset_w, gxg_gtk_print_settings_unset) Xen_wrap_3_args(gxg_gtk_print_settings_foreach_w, gxg_gtk_print_settings_foreach) Xen_wrap_2_args(gxg_gtk_print_settings_get_bool_w, gxg_gtk_print_settings_get_bool) Xen_wrap_3_args(gxg_gtk_print_settings_set_bool_w, gxg_gtk_print_settings_set_bool) Xen_wrap_2_args(gxg_gtk_print_settings_get_double_w, gxg_gtk_print_settings_get_double) Xen_wrap_3_args(gxg_gtk_print_settings_get_double_with_default_w, gxg_gtk_print_settings_get_double_with_default) Xen_wrap_3_args(gxg_gtk_print_settings_set_double_w, gxg_gtk_print_settings_set_double) Xen_wrap_3_args(gxg_gtk_print_settings_get_length_w, gxg_gtk_print_settings_get_length) Xen_wrap_4_args(gxg_gtk_print_settings_set_length_w, gxg_gtk_print_settings_set_length) Xen_wrap_2_args(gxg_gtk_print_settings_get_int_w, gxg_gtk_print_settings_get_int) Xen_wrap_3_args(gxg_gtk_print_settings_get_int_with_default_w, gxg_gtk_print_settings_get_int_with_default) Xen_wrap_3_args(gxg_gtk_print_settings_set_int_w, gxg_gtk_print_settings_set_int) Xen_wrap_1_arg(gxg_gtk_print_settings_get_printer_w, gxg_gtk_print_settings_get_printer) Xen_wrap_2_args(gxg_gtk_print_settings_set_printer_w, gxg_gtk_print_settings_set_printer) Xen_wrap_1_arg(gxg_gtk_print_settings_get_orientation_w, gxg_gtk_print_settings_get_orientation) Xen_wrap_2_args(gxg_gtk_print_settings_set_orientation_w, gxg_gtk_print_settings_set_orientation) Xen_wrap_1_arg(gxg_gtk_print_settings_get_paper_size_w, gxg_gtk_print_settings_get_paper_size) Xen_wrap_2_args(gxg_gtk_print_settings_set_paper_size_w, gxg_gtk_print_settings_set_paper_size) Xen_wrap_2_args(gxg_gtk_print_settings_get_paper_width_w, gxg_gtk_print_settings_get_paper_width) Xen_wrap_3_args(gxg_gtk_print_settings_set_paper_width_w, gxg_gtk_print_settings_set_paper_width) Xen_wrap_2_args(gxg_gtk_print_settings_get_paper_height_w, gxg_gtk_print_settings_get_paper_height) Xen_wrap_3_args(gxg_gtk_print_settings_set_paper_height_w, gxg_gtk_print_settings_set_paper_height) Xen_wrap_1_arg(gxg_gtk_print_settings_get_use_color_w, gxg_gtk_print_settings_get_use_color) Xen_wrap_2_args(gxg_gtk_print_settings_set_use_color_w, gxg_gtk_print_settings_set_use_color) Xen_wrap_1_arg(gxg_gtk_print_settings_get_collate_w, gxg_gtk_print_settings_get_collate) Xen_wrap_2_args(gxg_gtk_print_settings_set_collate_w, gxg_gtk_print_settings_set_collate) Xen_wrap_1_arg(gxg_gtk_print_settings_get_reverse_w, gxg_gtk_print_settings_get_reverse) Xen_wrap_2_args(gxg_gtk_print_settings_set_reverse_w, gxg_gtk_print_settings_set_reverse) Xen_wrap_1_arg(gxg_gtk_print_settings_get_duplex_w, gxg_gtk_print_settings_get_duplex) Xen_wrap_2_args(gxg_gtk_print_settings_set_duplex_w, gxg_gtk_print_settings_set_duplex) Xen_wrap_1_arg(gxg_gtk_print_settings_get_quality_w, gxg_gtk_print_settings_get_quality) Xen_wrap_2_args(gxg_gtk_print_settings_set_quality_w, gxg_gtk_print_settings_set_quality) Xen_wrap_1_arg(gxg_gtk_print_settings_get_n_copies_w, gxg_gtk_print_settings_get_n_copies) Xen_wrap_2_args(gxg_gtk_print_settings_set_n_copies_w, gxg_gtk_print_settings_set_n_copies) Xen_wrap_1_arg(gxg_gtk_print_settings_get_number_up_w, gxg_gtk_print_settings_get_number_up) Xen_wrap_2_args(gxg_gtk_print_settings_set_number_up_w, gxg_gtk_print_settings_set_number_up) Xen_wrap_1_arg(gxg_gtk_print_settings_get_resolution_w, gxg_gtk_print_settings_get_resolution) Xen_wrap_2_args(gxg_gtk_print_settings_set_resolution_w, gxg_gtk_print_settings_set_resolution) Xen_wrap_1_arg(gxg_gtk_print_settings_get_scale_w, gxg_gtk_print_settings_get_scale) Xen_wrap_2_args(gxg_gtk_print_settings_set_scale_w, gxg_gtk_print_settings_set_scale) Xen_wrap_1_arg(gxg_gtk_print_settings_get_print_pages_w, gxg_gtk_print_settings_get_print_pages) Xen_wrap_2_args(gxg_gtk_print_settings_set_print_pages_w, gxg_gtk_print_settings_set_print_pages) Xen_wrap_2_args(gxg_gtk_print_settings_get_page_ranges_w, gxg_gtk_print_settings_get_page_ranges) Xen_wrap_3_args(gxg_gtk_print_settings_set_page_ranges_w, gxg_gtk_print_settings_set_page_ranges) Xen_wrap_1_arg(gxg_gtk_print_settings_get_page_set_w, gxg_gtk_print_settings_get_page_set) Xen_wrap_2_args(gxg_gtk_print_settings_set_page_set_w, gxg_gtk_print_settings_set_page_set) Xen_wrap_1_arg(gxg_gtk_print_settings_get_default_source_w, gxg_gtk_print_settings_get_default_source) Xen_wrap_2_args(gxg_gtk_print_settings_set_default_source_w, gxg_gtk_print_settings_set_default_source) Xen_wrap_1_arg(gxg_gtk_print_settings_get_media_type_w, gxg_gtk_print_settings_get_media_type) Xen_wrap_2_args(gxg_gtk_print_settings_set_media_type_w, gxg_gtk_print_settings_set_media_type) Xen_wrap_1_arg(gxg_gtk_print_settings_get_dither_w, gxg_gtk_print_settings_get_dither) Xen_wrap_2_args(gxg_gtk_print_settings_set_dither_w, gxg_gtk_print_settings_set_dither) Xen_wrap_1_arg(gxg_gtk_print_settings_get_finishings_w, gxg_gtk_print_settings_get_finishings) Xen_wrap_2_args(gxg_gtk_print_settings_set_finishings_w, gxg_gtk_print_settings_set_finishings) Xen_wrap_1_arg(gxg_gtk_print_settings_get_output_bin_w, gxg_gtk_print_settings_get_output_bin) Xen_wrap_2_args(gxg_gtk_print_settings_set_output_bin_w, gxg_gtk_print_settings_set_output_bin) Xen_wrap_1_arg(gxg_gtk_settings_get_for_screen_w, gxg_gtk_settings_get_for_screen) Xen_wrap_1_arg(gxg_pango_cairo_create_layout_w, gxg_pango_cairo_create_layout) Xen_wrap_2_args(gxg_pango_cairo_update_layout_w, gxg_pango_cairo_update_layout) Xen_wrap_2_args(gxg_pango_cairo_update_context_w, gxg_pango_cairo_update_context) Xen_wrap_2_args(gxg_pango_cairo_context_set_font_options_w, gxg_pango_cairo_context_set_font_options) Xen_wrap_1_arg(gxg_pango_cairo_context_get_font_options_w, gxg_pango_cairo_context_get_font_options) Xen_wrap_2_args(gxg_pango_cairo_context_set_resolution_w, gxg_pango_cairo_context_set_resolution) Xen_wrap_1_arg(gxg_pango_cairo_context_get_resolution_w, gxg_pango_cairo_context_get_resolution) Xen_wrap_3_args(gxg_pango_cairo_show_glyph_string_w, gxg_pango_cairo_show_glyph_string) Xen_wrap_2_args(gxg_pango_cairo_show_layout_line_w, gxg_pango_cairo_show_layout_line) Xen_wrap_2_args(gxg_pango_cairo_show_layout_w, gxg_pango_cairo_show_layout) Xen_wrap_5_args(gxg_pango_cairo_show_error_underline_w, gxg_pango_cairo_show_error_underline) Xen_wrap_3_args(gxg_pango_cairo_glyph_string_path_w, gxg_pango_cairo_glyph_string_path) Xen_wrap_2_args(gxg_pango_cairo_layout_line_path_w, gxg_pango_cairo_layout_line_path) Xen_wrap_2_args(gxg_pango_cairo_layout_path_w, gxg_pango_cairo_layout_path) Xen_wrap_5_args(gxg_pango_cairo_error_underline_path_w, gxg_pango_cairo_error_underline_path) Xen_wrap_4_args(gxg_gdk_cairo_set_source_pixbuf_w, gxg_gdk_cairo_set_source_pixbuf) Xen_wrap_2_args(gxg_gdk_cairo_rectangle_w, gxg_gdk_cairo_rectangle) Xen_wrap_1_arg(gxg_gdk_event_request_motions_w, gxg_gdk_event_request_motions) Xen_wrap_1_arg(gxg_gdk_notify_startup_complete_with_id_w, gxg_gdk_notify_startup_complete_with_id) Xen_wrap_4_args(gxg_gdk_threads_add_idle_full_w, gxg_gdk_threads_add_idle_full) Xen_wrap_2_optional_args(gxg_gdk_threads_add_idle_w, gxg_gdk_threads_add_idle) Xen_wrap_5_args(gxg_gdk_threads_add_timeout_full_w, gxg_gdk_threads_add_timeout_full) Xen_wrap_3_optional_args(gxg_gdk_threads_add_timeout_w, gxg_gdk_threads_add_timeout) Xen_wrap_2_args(gxg_gdk_window_set_startup_id_w, gxg_gdk_window_set_startup_id) Xen_wrap_1_arg(gxg_gdk_window_beep_w, gxg_gdk_window_beep) Xen_wrap_2_args(gxg_gdk_window_set_opacity_w, gxg_gdk_window_set_opacity) Xen_wrap_3_args(gxg_gtk_binding_entry_skip_w, gxg_gtk_binding_entry_skip) Xen_wrap_1_arg(gxg_gtk_cell_layout_get_cells_w, gxg_gtk_cell_layout_get_cells) Xen_wrap_2_args(gxg_gtk_entry_completion_set_inline_selection_w, gxg_gtk_entry_completion_set_inline_selection) Xen_wrap_1_arg(gxg_gtk_entry_completion_get_inline_selection_w, gxg_gtk_entry_completion_get_inline_selection) Xen_wrap_1_arg(gxg_gtk_entry_completion_get_completion_prefix_w, gxg_gtk_entry_completion_get_completion_prefix) Xen_wrap_2_args(gxg_gtk_entry_set_cursor_hadjustment_w, gxg_gtk_entry_set_cursor_hadjustment) Xen_wrap_1_arg(gxg_gtk_entry_get_cursor_hadjustment_w, gxg_gtk_entry_get_cursor_hadjustment) Xen_wrap_1_arg(gxg_gtk_icon_theme_list_contexts_w, gxg_gtk_icon_theme_list_contexts) Xen_wrap_2_optional_args(gxg_gtk_print_settings_new_from_file_w, gxg_gtk_print_settings_new_from_file) Xen_wrap_3_optional_args(gxg_gtk_print_settings_to_file_w, gxg_gtk_print_settings_to_file) Xen_wrap_2_args(gxg_gtk_range_set_show_fill_level_w, gxg_gtk_range_set_show_fill_level) Xen_wrap_1_arg(gxg_gtk_range_get_show_fill_level_w, gxg_gtk_range_get_show_fill_level) Xen_wrap_2_args(gxg_gtk_range_set_restrict_to_fill_level_w, gxg_gtk_range_set_restrict_to_fill_level) Xen_wrap_1_arg(gxg_gtk_range_get_restrict_to_fill_level_w, gxg_gtk_range_get_restrict_to_fill_level) Xen_wrap_2_args(gxg_gtk_range_set_fill_level_w, gxg_gtk_range_set_fill_level) Xen_wrap_1_arg(gxg_gtk_range_get_fill_level_w, gxg_gtk_range_get_fill_level) Xen_wrap_2_args(gxg_gtk_tree_view_set_show_expanders_w, gxg_gtk_tree_view_set_show_expanders) Xen_wrap_1_arg(gxg_gtk_tree_view_get_show_expanders_w, gxg_gtk_tree_view_get_show_expanders) Xen_wrap_2_args(gxg_gtk_tree_view_set_level_indentation_w, gxg_gtk_tree_view_set_level_indentation) Xen_wrap_1_arg(gxg_gtk_tree_view_get_level_indentation_w, gxg_gtk_tree_view_get_level_indentation) Xen_wrap_2_args(gxg_gtk_widget_keynav_failed_w, gxg_gtk_widget_keynav_failed) Xen_wrap_1_arg(gxg_gtk_widget_error_bell_w, gxg_gtk_widget_error_bell) Xen_wrap_2_args(gxg_gtk_widget_set_tooltip_window_w, gxg_gtk_widget_set_tooltip_window) Xen_wrap_1_arg(gxg_gtk_widget_get_tooltip_window_w, gxg_gtk_widget_get_tooltip_window) Xen_wrap_1_arg(gxg_gtk_widget_trigger_tooltip_query_w, gxg_gtk_widget_trigger_tooltip_query) Xen_wrap_2_args(gxg_gtk_window_set_startup_id_w, gxg_gtk_window_set_startup_id) Xen_wrap_3_args(gxg_gtk_text_buffer_add_mark_w, gxg_gtk_text_buffer_add_mark) Xen_wrap_2_args(gxg_gtk_text_mark_new_w, gxg_gtk_text_mark_new) Xen_wrap_1_arg(gxg_gtk_tree_view_column_get_tree_view_w, gxg_gtk_tree_view_column_get_tree_view) Xen_wrap_2_args(gxg_gtk_tooltip_set_text_w, gxg_gtk_tooltip_set_text) Xen_wrap_5_optional_args(gxg_gtk_tree_view_convert_widget_to_tree_coords_w, gxg_gtk_tree_view_convert_widget_to_tree_coords) Xen_wrap_5_optional_args(gxg_gtk_tree_view_convert_tree_to_widget_coords_w, gxg_gtk_tree_view_convert_tree_to_widget_coords) Xen_wrap_5_optional_args(gxg_gtk_tree_view_convert_widget_to_bin_window_coords_w, gxg_gtk_tree_view_convert_widget_to_bin_window_coords) Xen_wrap_5_optional_args(gxg_gtk_tree_view_convert_bin_window_to_widget_coords_w, gxg_gtk_tree_view_convert_bin_window_to_widget_coords) Xen_wrap_5_optional_args(gxg_gtk_tree_view_convert_tree_to_bin_window_coords_w, gxg_gtk_tree_view_convert_tree_to_bin_window_coords) Xen_wrap_5_optional_args(gxg_gtk_tree_view_convert_bin_window_to_tree_coords_w, gxg_gtk_tree_view_convert_bin_window_to_tree_coords) Xen_wrap_2_args(gxg_gtk_widget_set_tooltip_text_w, gxg_gtk_widget_set_tooltip_text) Xen_wrap_1_arg(gxg_gtk_widget_get_tooltip_text_w, gxg_gtk_widget_get_tooltip_text) Xen_wrap_2_args(gxg_gtk_widget_set_tooltip_markup_w, gxg_gtk_widget_set_tooltip_markup) Xen_wrap_1_arg(gxg_gtk_widget_get_tooltip_markup_w, gxg_gtk_widget_get_tooltip_markup) Xen_wrap_1_arg(gxg_gtk_tree_view_is_rubber_banding_active_w, gxg_gtk_tree_view_is_rubber_banding_active) Xen_wrap_5_optional_args(gxg_gtk_icon_view_convert_widget_to_bin_window_coords_w, gxg_gtk_icon_view_convert_widget_to_bin_window_coords) Xen_wrap_3_args(gxg_gtk_icon_view_set_tooltip_item_w, gxg_gtk_icon_view_set_tooltip_item) Xen_wrap_4_args(gxg_gtk_icon_view_set_tooltip_cell_w, gxg_gtk_icon_view_set_tooltip_cell) Xen_wrap_7_optional_args(gxg_gtk_icon_view_get_tooltip_context_w, gxg_gtk_icon_view_get_tooltip_context) Xen_wrap_2_args(gxg_gtk_icon_view_set_tooltip_column_w, gxg_gtk_icon_view_set_tooltip_column) Xen_wrap_1_arg(gxg_gtk_icon_view_get_tooltip_column_w, gxg_gtk_icon_view_get_tooltip_column) Xen_wrap_2_args(gxg_gtk_menu_tool_button_set_arrow_tooltip_text_w, gxg_gtk_menu_tool_button_set_arrow_tooltip_text) Xen_wrap_2_args(gxg_gtk_menu_tool_button_set_arrow_tooltip_markup_w, gxg_gtk_menu_tool_button_set_arrow_tooltip_markup) Xen_wrap_2_args(gxg_gtk_tool_item_set_tooltip_text_w, gxg_gtk_tool_item_set_tooltip_text) Xen_wrap_2_args(gxg_gtk_tool_item_set_tooltip_markup_w, gxg_gtk_tool_item_set_tooltip_markup) Xen_wrap_2_args(gxg_gtk_tooltip_set_tip_area_w, gxg_gtk_tooltip_set_tip_area) Xen_wrap_3_args(gxg_gtk_tree_view_set_tooltip_row_w, gxg_gtk_tree_view_set_tooltip_row) Xen_wrap_5_args(gxg_gtk_tree_view_set_tooltip_cell_w, gxg_gtk_tree_view_set_tooltip_cell) Xen_wrap_7_optional_args(gxg_gtk_tree_view_get_tooltip_context_w, gxg_gtk_tree_view_get_tooltip_context) Xen_wrap_2_args(gxg_gtk_tree_view_set_tooltip_column_w, gxg_gtk_tree_view_set_tooltip_column) Xen_wrap_1_arg(gxg_gtk_tree_view_get_tooltip_column_w, gxg_gtk_tree_view_get_tooltip_column) Xen_wrap_2_args(gxg_gtk_widget_set_has_tooltip_w, gxg_gtk_widget_set_has_tooltip) Xen_wrap_1_arg(gxg_gtk_widget_get_has_tooltip_w, gxg_gtk_widget_get_has_tooltip) #if GTK_CHECK_VERSION(2, 14, 0) Xen_wrap_4_args(gxg_gtk_calendar_set_detail_func_w, gxg_gtk_calendar_set_detail_func) Xen_wrap_2_args(gxg_gtk_calendar_set_detail_width_chars_w, gxg_gtk_calendar_set_detail_width_chars) Xen_wrap_2_args(gxg_gtk_calendar_set_detail_height_rows_w, gxg_gtk_calendar_set_detail_height_rows) Xen_wrap_1_arg(gxg_gtk_calendar_get_detail_width_chars_w, gxg_gtk_calendar_get_detail_width_chars) Xen_wrap_1_arg(gxg_gtk_calendar_get_detail_height_rows_w, gxg_gtk_calendar_get_detail_height_rows) Xen_wrap_2_args(gxg_gdk_screen_get_monitor_width_mm_w, gxg_gdk_screen_get_monitor_width_mm) Xen_wrap_2_args(gxg_gdk_screen_get_monitor_height_mm_w, gxg_gdk_screen_get_monitor_height_mm) Xen_wrap_2_args(gxg_gdk_screen_get_monitor_plug_name_w, gxg_gdk_screen_get_monitor_plug_name) Xen_wrap_1_arg(gxg_gtk_accel_group_get_is_locked_w, gxg_gtk_accel_group_get_is_locked) Xen_wrap_1_arg(gxg_gtk_container_get_focus_child_w, gxg_gtk_container_get_focus_child) Xen_wrap_1_arg(gxg_gtk_dialog_get_content_area_w, gxg_gtk_dialog_get_content_area) Xen_wrap_2_args(gxg_gtk_entry_set_overwrite_mode_w, gxg_gtk_entry_set_overwrite_mode) Xen_wrap_1_arg(gxg_gtk_entry_get_overwrite_mode_w, gxg_gtk_entry_get_overwrite_mode) Xen_wrap_1_arg(gxg_gtk_entry_get_text_length_w, gxg_gtk_entry_get_text_length) Xen_wrap_1_arg(gxg_gtk_layout_get_bin_window_w, gxg_gtk_layout_get_bin_window) Xen_wrap_1_arg(gxg_gtk_menu_get_accel_path_w, gxg_gtk_menu_get_accel_path) Xen_wrap_1_arg(gxg_gtk_menu_get_monitor_w, gxg_gtk_menu_get_monitor) Xen_wrap_1_arg(gxg_gtk_menu_item_get_accel_path_w, gxg_gtk_menu_item_get_accel_path) Xen_wrap_1_arg(gxg_gtk_scale_button_get_plus_button_w, gxg_gtk_scale_button_get_plus_button) Xen_wrap_1_arg(gxg_gtk_scale_button_get_minus_button_w, gxg_gtk_scale_button_get_minus_button) Xen_wrap_1_arg(gxg_gtk_scale_button_get_popup_w, gxg_gtk_scale_button_get_popup) Xen_wrap_1_arg(gxg_gtk_selection_data_get_target_w, gxg_gtk_selection_data_get_target) Xen_wrap_1_arg(gxg_gtk_selection_data_get_data_type_w, gxg_gtk_selection_data_get_data_type) Xen_wrap_1_arg(gxg_gtk_selection_data_get_format_w, gxg_gtk_selection_data_get_format) Xen_wrap_1_arg(gxg_gtk_selection_data_get_display_w, gxg_gtk_selection_data_get_display) Xen_wrap_1_arg(gxg_gtk_widget_get_window_w, gxg_gtk_widget_get_window) Xen_wrap_1_arg(gxg_gtk_accel_group_get_modifier_mask_w, gxg_gtk_accel_group_get_modifier_mask) Xen_wrap_5_args(gxg_gdk_threads_add_timeout_seconds_full_w, gxg_gdk_threads_add_timeout_seconds_full) Xen_wrap_3_optional_args(gxg_gdk_threads_add_timeout_seconds_w, gxg_gdk_threads_add_timeout_seconds) Xen_wrap_1_arg(gxg_gtk_adjustment_get_lower_w, gxg_gtk_adjustment_get_lower) Xen_wrap_2_args(gxg_gtk_adjustment_set_lower_w, gxg_gtk_adjustment_set_lower) Xen_wrap_1_arg(gxg_gtk_adjustment_get_upper_w, gxg_gtk_adjustment_get_upper) Xen_wrap_2_args(gxg_gtk_adjustment_set_upper_w, gxg_gtk_adjustment_set_upper) Xen_wrap_1_arg(gxg_gtk_adjustment_get_step_increment_w, gxg_gtk_adjustment_get_step_increment) Xen_wrap_2_args(gxg_gtk_adjustment_set_step_increment_w, gxg_gtk_adjustment_set_step_increment) Xen_wrap_1_arg(gxg_gtk_adjustment_get_page_increment_w, gxg_gtk_adjustment_get_page_increment) Xen_wrap_2_args(gxg_gtk_adjustment_set_page_increment_w, gxg_gtk_adjustment_set_page_increment) Xen_wrap_1_arg(gxg_gtk_adjustment_get_page_size_w, gxg_gtk_adjustment_get_page_size) Xen_wrap_2_args(gxg_gtk_adjustment_set_page_size_w, gxg_gtk_adjustment_set_page_size) Xen_wrap_7_args(gxg_gtk_adjustment_configure_w, gxg_gtk_adjustment_configure) Xen_wrap_2_args(gxg_gtk_combo_box_set_button_sensitivity_w, gxg_gtk_combo_box_set_button_sensitivity) Xen_wrap_1_arg(gxg_gtk_combo_box_get_button_sensitivity_w, gxg_gtk_combo_box_get_button_sensitivity) Xen_wrap_1_arg(gxg_gtk_file_chooser_get_file_w, gxg_gtk_file_chooser_get_file) Xen_wrap_3_optional_args(gxg_gtk_file_chooser_set_file_w, gxg_gtk_file_chooser_set_file) Xen_wrap_3_optional_args(gxg_gtk_file_chooser_select_file_w, gxg_gtk_file_chooser_select_file) Xen_wrap_2_args(gxg_gtk_file_chooser_unselect_file_w, gxg_gtk_file_chooser_unselect_file) Xen_wrap_1_arg(gxg_gtk_file_chooser_get_files_w, gxg_gtk_file_chooser_get_files) Xen_wrap_3_optional_args(gxg_gtk_file_chooser_set_current_folder_file_w, gxg_gtk_file_chooser_set_current_folder_file) Xen_wrap_1_arg(gxg_gtk_file_chooser_get_current_folder_file_w, gxg_gtk_file_chooser_get_current_folder_file) Xen_wrap_1_arg(gxg_gtk_file_chooser_get_preview_file_w, gxg_gtk_file_chooser_get_preview_file) Xen_wrap_1_arg(gxg_gtk_window_get_default_widget_w, gxg_gtk_window_get_default_widget) #endif #if GTK_CHECK_VERSION(2, 16, 0) Xen_wrap_1_arg(gxg_gtk_link_button_get_visited_w, gxg_gtk_link_button_get_visited) Xen_wrap_2_args(gxg_gtk_link_button_set_visited_w, gxg_gtk_link_button_set_visited) Xen_wrap_1_arg(gxg_gdk_keymap_get_caps_lock_state_w, gxg_gdk_keymap_get_caps_lock_state) Xen_wrap_1_arg(gxg_gtk_cell_view_get_model_w, gxg_gtk_cell_view_get_model) Xen_wrap_1_arg(gxg_gtk_entry_unset_invisible_char_w, gxg_gtk_entry_unset_invisible_char) Xen_wrap_2_args(gxg_gtk_entry_set_progress_fraction_w, gxg_gtk_entry_set_progress_fraction) Xen_wrap_1_arg(gxg_gtk_entry_get_progress_fraction_w, gxg_gtk_entry_get_progress_fraction) Xen_wrap_2_args(gxg_gtk_entry_set_progress_pulse_step_w, gxg_gtk_entry_set_progress_pulse_step) Xen_wrap_1_arg(gxg_gtk_entry_get_progress_pulse_step_w, gxg_gtk_entry_get_progress_pulse_step) Xen_wrap_1_arg(gxg_gtk_entry_progress_pulse_w, gxg_gtk_entry_progress_pulse) Xen_wrap_3_args(gxg_gtk_entry_set_icon_from_pixbuf_w, gxg_gtk_entry_set_icon_from_pixbuf) Xen_wrap_3_args(gxg_gtk_entry_set_icon_from_icon_name_w, gxg_gtk_entry_set_icon_from_icon_name) Xen_wrap_3_args(gxg_gtk_entry_set_icon_from_gicon_w, gxg_gtk_entry_set_icon_from_gicon) Xen_wrap_2_args(gxg_gtk_entry_get_icon_name_w, gxg_gtk_entry_get_icon_name) Xen_wrap_3_args(gxg_gtk_entry_set_icon_activatable_w, gxg_gtk_entry_set_icon_activatable) Xen_wrap_2_args(gxg_gtk_entry_get_icon_activatable_w, gxg_gtk_entry_get_icon_activatable) Xen_wrap_3_args(gxg_gtk_entry_set_icon_sensitive_w, gxg_gtk_entry_set_icon_sensitive) Xen_wrap_2_args(gxg_gtk_entry_get_icon_sensitive_w, gxg_gtk_entry_get_icon_sensitive) Xen_wrap_3_args(gxg_gtk_entry_get_icon_at_pos_w, gxg_gtk_entry_get_icon_at_pos) Xen_wrap_3_args(gxg_gtk_entry_set_icon_tooltip_text_w, gxg_gtk_entry_set_icon_tooltip_text) Xen_wrap_3_args(gxg_gtk_entry_set_icon_tooltip_markup_w, gxg_gtk_entry_set_icon_tooltip_markup) Xen_wrap_4_args(gxg_gtk_entry_set_icon_drag_source_w, gxg_gtk_entry_set_icon_drag_source) Xen_wrap_1_arg(gxg_gtk_entry_get_current_icon_drag_source_w, gxg_gtk_entry_get_current_icon_drag_source) Xen_wrap_2_args(gxg_gtk_menu_item_set_label_w, gxg_gtk_menu_item_set_label) Xen_wrap_1_arg(gxg_gtk_menu_item_get_label_w, gxg_gtk_menu_item_get_label) Xen_wrap_2_args(gxg_gtk_menu_item_set_use_underline_w, gxg_gtk_menu_item_set_use_underline) Xen_wrap_1_arg(gxg_gtk_menu_item_get_use_underline_w, gxg_gtk_menu_item_get_use_underline) Xen_wrap_1_arg(gxg_gtk_selection_data_get_selection_w, gxg_gtk_selection_data_get_selection) Xen_wrap_2_args(gxg_gtk_entry_get_icon_tooltip_text_w, gxg_gtk_entry_get_icon_tooltip_text) Xen_wrap_2_args(gxg_gtk_entry_get_icon_tooltip_markup_w, gxg_gtk_entry_get_icon_tooltip_markup) Xen_wrap_4_args(gxg_gtk_scale_add_mark_w, gxg_gtk_scale_add_mark) Xen_wrap_1_arg(gxg_gtk_scale_clear_marks_w, gxg_gtk_scale_clear_marks) #endif #if GTK_CHECK_VERSION(2, 18, 0) Xen_wrap_no_args(gxg_gtk_window_get_default_icon_name_w, gxg_gtk_window_get_default_icon_name) Xen_wrap_1_arg(gxg_gtk_label_get_current_uri_w, gxg_gtk_label_get_current_uri) Xen_wrap_no_args(gxg_gtk_info_bar_new_w, gxg_gtk_info_bar_new) Xen_wrap_1_arg(gxg_gtk_info_bar_get_action_area_w, gxg_gtk_info_bar_get_action_area) Xen_wrap_1_arg(gxg_gtk_info_bar_get_content_area_w, gxg_gtk_info_bar_get_content_area) Xen_wrap_3_args(gxg_gtk_info_bar_add_action_widget_w, gxg_gtk_info_bar_add_action_widget) Xen_wrap_3_args(gxg_gtk_info_bar_add_button_w, gxg_gtk_info_bar_add_button) Xen_wrap_3_args(gxg_gtk_info_bar_set_response_sensitive_w, gxg_gtk_info_bar_set_response_sensitive) Xen_wrap_2_args(gxg_gtk_info_bar_set_default_response_w, gxg_gtk_info_bar_set_default_response) Xen_wrap_2_args(gxg_gtk_info_bar_response_w, gxg_gtk_info_bar_response) Xen_wrap_2_args(gxg_gtk_info_bar_set_message_type_w, gxg_gtk_info_bar_set_message_type) Xen_wrap_1_arg(gxg_gtk_info_bar_get_message_type_w, gxg_gtk_info_bar_get_message_type) Xen_wrap_1_arg(gxg_gdk_window_ensure_native_w, gxg_gdk_window_ensure_native) Xen_wrap_5_optional_args(gxg_gdk_window_get_root_coords_w, gxg_gdk_window_get_root_coords) Xen_wrap_2_args(gxg_gdk_offscreen_window_set_embedder_w, gxg_gdk_offscreen_window_set_embedder) Xen_wrap_1_arg(gxg_gdk_offscreen_window_get_embedder_w, gxg_gdk_offscreen_window_get_embedder) Xen_wrap_1_arg(gxg_gdk_window_geometry_changed_w, gxg_gdk_window_geometry_changed) Xen_wrap_2_args(gxg_gtk_menu_set_reserve_toggle_size_w, gxg_gtk_menu_set_reserve_toggle_size) Xen_wrap_1_arg(gxg_gtk_menu_get_reserve_toggle_size_w, gxg_gtk_menu_get_reserve_toggle_size) Xen_wrap_1_arg(gxg_gtk_entry_new_with_buffer_w, gxg_gtk_entry_new_with_buffer) Xen_wrap_1_arg(gxg_gtk_entry_get_buffer_w, gxg_gtk_entry_get_buffer) Xen_wrap_2_args(gxg_gtk_entry_set_buffer_w, gxg_gtk_entry_set_buffer) Xen_wrap_2_args(gxg_gtk_label_set_track_visited_links_w, gxg_gtk_label_set_track_visited_links) Xen_wrap_1_arg(gxg_gtk_label_get_track_visited_links_w, gxg_gtk_label_get_track_visited_links) Xen_wrap_2_args(gxg_gtk_print_operation_set_embed_page_setup_w, gxg_gtk_print_operation_set_embed_page_setup) Xen_wrap_1_arg(gxg_gtk_print_operation_get_embed_page_setup_w, gxg_gtk_print_operation_get_embed_page_setup) Xen_wrap_2_args(gxg_gtk_entry_buffer_new_w, gxg_gtk_entry_buffer_new) Xen_wrap_1_arg(gxg_gtk_entry_buffer_get_bytes_w, gxg_gtk_entry_buffer_get_bytes) Xen_wrap_1_arg(gxg_gtk_entry_buffer_get_length_w, gxg_gtk_entry_buffer_get_length) Xen_wrap_1_arg(gxg_gtk_entry_buffer_get_text_w, gxg_gtk_entry_buffer_get_text) Xen_wrap_3_args(gxg_gtk_entry_buffer_set_text_w, gxg_gtk_entry_buffer_set_text) Xen_wrap_2_args(gxg_gtk_entry_buffer_set_max_length_w, gxg_gtk_entry_buffer_set_max_length) Xen_wrap_1_arg(gxg_gtk_entry_buffer_get_max_length_w, gxg_gtk_entry_buffer_get_max_length) Xen_wrap_4_args(gxg_gtk_entry_buffer_insert_text_w, gxg_gtk_entry_buffer_insert_text) Xen_wrap_3_args(gxg_gtk_entry_buffer_delete_text_w, gxg_gtk_entry_buffer_delete_text) Xen_wrap_4_args(gxg_gtk_entry_buffer_emit_inserted_text_w, gxg_gtk_entry_buffer_emit_inserted_text) Xen_wrap_3_args(gxg_gtk_entry_buffer_emit_deleted_text_w, gxg_gtk_entry_buffer_emit_deleted_text) Xen_wrap_3_args(gxg_gtk_cell_renderer_set_alignment_w, gxg_gtk_cell_renderer_set_alignment) Xen_wrap_3_optional_args(gxg_gtk_cell_renderer_get_alignment_w, gxg_gtk_cell_renderer_get_alignment) Xen_wrap_3_args(gxg_gtk_cell_renderer_set_padding_w, gxg_gtk_cell_renderer_set_padding) Xen_wrap_3_optional_args(gxg_gtk_cell_renderer_get_padding_w, gxg_gtk_cell_renderer_get_padding) Xen_wrap_2_args(gxg_gtk_cell_renderer_set_visible_w, gxg_gtk_cell_renderer_set_visible) Xen_wrap_1_arg(gxg_gtk_cell_renderer_get_visible_w, gxg_gtk_cell_renderer_get_visible) Xen_wrap_2_args(gxg_gtk_cell_renderer_set_sensitive_w, gxg_gtk_cell_renderer_set_sensitive) Xen_wrap_1_arg(gxg_gtk_cell_renderer_get_sensitive_w, gxg_gtk_cell_renderer_get_sensitive) Xen_wrap_1_arg(gxg_gtk_cell_renderer_toggle_get_activatable_w, gxg_gtk_cell_renderer_toggle_get_activatable) Xen_wrap_2_args(gxg_gtk_cell_renderer_toggle_set_activatable_w, gxg_gtk_cell_renderer_toggle_set_activatable) Xen_wrap_2_args(gxg_gtk_widget_set_can_focus_w, gxg_gtk_widget_set_can_focus) Xen_wrap_1_arg(gxg_gtk_widget_get_can_focus_w, gxg_gtk_widget_get_can_focus) Xen_wrap_1_arg(gxg_gtk_widget_has_focus_w, gxg_gtk_widget_has_focus) Xen_wrap_2_args(gxg_gtk_widget_set_can_default_w, gxg_gtk_widget_set_can_default) Xen_wrap_1_arg(gxg_gtk_widget_get_can_default_w, gxg_gtk_widget_get_can_default) Xen_wrap_1_arg(gxg_gtk_widget_has_default_w, gxg_gtk_widget_has_default) Xen_wrap_1_arg(gxg_gtk_widget_get_sensitive_w, gxg_gtk_widget_get_sensitive) Xen_wrap_1_arg(gxg_gtk_widget_is_sensitive_w, gxg_gtk_widget_is_sensitive) Xen_wrap_2_args(gxg_gtk_widget_set_has_window_w, gxg_gtk_widget_set_has_window) Xen_wrap_1_arg(gxg_gtk_widget_get_has_window_w, gxg_gtk_widget_get_has_window) Xen_wrap_1_arg(gxg_gtk_widget_get_app_paintable_w, gxg_gtk_widget_get_app_paintable) Xen_wrap_1_arg(gxg_gdk_window_get_cursor_w, gxg_gdk_window_get_cursor) Xen_wrap_2_args(gxg_gtk_file_chooser_set_create_folders_w, gxg_gtk_file_chooser_set_create_folders) Xen_wrap_1_arg(gxg_gtk_file_chooser_get_create_folders_w, gxg_gtk_file_chooser_get_create_folders) Xen_wrap_2_args(gxg_gtk_icon_view_set_item_padding_w, gxg_gtk_icon_view_set_item_padding) Xen_wrap_1_arg(gxg_gtk_icon_view_get_item_padding_w, gxg_gtk_icon_view_get_item_padding) Xen_wrap_1_arg(gxg_gtk_widget_has_grab_w, gxg_gtk_widget_has_grab) Xen_wrap_2_args(gxg_gtk_widget_set_visible_w, gxg_gtk_widget_set_visible) Xen_wrap_1_arg(gxg_gtk_widget_get_visible_w, gxg_gtk_widget_get_visible) Xen_wrap_2_args(gxg_gtk_range_set_flippable_w, gxg_gtk_range_set_flippable) Xen_wrap_1_arg(gxg_gtk_range_get_flippable_w, gxg_gtk_range_get_flippable) Xen_wrap_1_arg(gxg_gtk_widget_is_toplevel_w, gxg_gtk_widget_is_toplevel) Xen_wrap_1_arg(gxg_gtk_widget_is_drawable_w, gxg_gtk_widget_is_drawable) Xen_wrap_2_args(gxg_gtk_widget_set_window_w, gxg_gtk_widget_set_window) Xen_wrap_1_arg(gxg_gdk_window_is_destroyed_w, gxg_gdk_window_is_destroyed) Xen_wrap_3_args(gxg_gdk_window_restack_w, gxg_gdk_window_restack) Xen_wrap_2_args(gxg_gtk_widget_set_receives_default_w, gxg_gtk_widget_set_receives_default) Xen_wrap_1_arg(gxg_gtk_widget_get_receives_default_w, gxg_gtk_widget_get_receives_default) #endif #if GTK_CHECK_VERSION(2, 20, 0) Xen_wrap_2_args(gxg_gtk_dialog_get_widget_for_response_w, gxg_gtk_dialog_get_widget_for_response) Xen_wrap_1_arg(gxg_gtk_viewport_get_bin_window_w, gxg_gtk_viewport_get_bin_window) Xen_wrap_no_args(gxg_gtk_spinner_new_w, gxg_gtk_spinner_new) Xen_wrap_1_arg(gxg_gtk_spinner_start_w, gxg_gtk_spinner_start) Xen_wrap_1_arg(gxg_gtk_spinner_stop_w, gxg_gtk_spinner_stop) Xen_wrap_no_args(gxg_gtk_cell_renderer_spinner_new_w, gxg_gtk_cell_renderer_spinner_new) Xen_wrap_2_args(gxg_gtk_notebook_get_action_widget_w, gxg_gtk_notebook_get_action_widget) Xen_wrap_3_args(gxg_gtk_notebook_set_action_widget_w, gxg_gtk_notebook_set_action_widget) Xen_wrap_1_arg(gxg_gtk_statusbar_get_message_area_w, gxg_gtk_statusbar_get_message_area) Xen_wrap_1_arg(gxg_gtk_tool_item_get_ellipsize_mode_w, gxg_gtk_tool_item_get_ellipsize_mode) Xen_wrap_1_arg(gxg_gtk_tool_item_get_text_alignment_w, gxg_gtk_tool_item_get_text_alignment) Xen_wrap_1_arg(gxg_gtk_tool_item_get_text_orientation_w, gxg_gtk_tool_item_get_text_orientation) Xen_wrap_1_arg(gxg_gtk_tool_item_get_text_size_group_w, gxg_gtk_tool_item_get_text_size_group) Xen_wrap_no_args(gxg_gtk_tool_palette_new_w, gxg_gtk_tool_palette_new) Xen_wrap_3_args(gxg_gtk_tool_palette_set_group_position_w, gxg_gtk_tool_palette_set_group_position) Xen_wrap_3_args(gxg_gtk_tool_palette_set_exclusive_w, gxg_gtk_tool_palette_set_exclusive) Xen_wrap_3_args(gxg_gtk_tool_palette_set_expand_w, gxg_gtk_tool_palette_set_expand) Xen_wrap_2_args(gxg_gtk_tool_palette_get_group_position_w, gxg_gtk_tool_palette_get_group_position) Xen_wrap_2_args(gxg_gtk_tool_palette_get_exclusive_w, gxg_gtk_tool_palette_get_exclusive) Xen_wrap_2_args(gxg_gtk_tool_palette_get_expand_w, gxg_gtk_tool_palette_get_expand) Xen_wrap_1_arg(gxg_gtk_tool_palette_unset_icon_size_w, gxg_gtk_tool_palette_unset_icon_size) Xen_wrap_2_args(gxg_gtk_tool_palette_set_style_w, gxg_gtk_tool_palette_set_style) Xen_wrap_1_arg(gxg_gtk_tool_palette_unset_style_w, gxg_gtk_tool_palette_unset_style) Xen_wrap_1_arg(gxg_gtk_tool_palette_get_style_w, gxg_gtk_tool_palette_get_style) Xen_wrap_3_args(gxg_gtk_tool_palette_get_drop_item_w, gxg_gtk_tool_palette_get_drop_item) Xen_wrap_3_args(gxg_gtk_tool_palette_get_drop_group_w, gxg_gtk_tool_palette_get_drop_group) Xen_wrap_2_args(gxg_gtk_tool_palette_get_drag_item_w, gxg_gtk_tool_palette_get_drag_item) Xen_wrap_2_args(gxg_gtk_tool_palette_set_drag_source_w, gxg_gtk_tool_palette_set_drag_source) Xen_wrap_5_args(gxg_gtk_tool_palette_add_drag_dest_w, gxg_gtk_tool_palette_add_drag_dest) Xen_wrap_no_args(gxg_gtk_tool_palette_get_drag_target_item_w, gxg_gtk_tool_palette_get_drag_target_item) Xen_wrap_no_args(gxg_gtk_tool_palette_get_drag_target_group_w, gxg_gtk_tool_palette_get_drag_target_group) Xen_wrap_1_arg(gxg_gtk_tool_item_group_new_w, gxg_gtk_tool_item_group_new) Xen_wrap_2_args(gxg_gtk_tool_item_group_set_label_w, gxg_gtk_tool_item_group_set_label) Xen_wrap_2_args(gxg_gtk_tool_item_group_set_label_widget_w, gxg_gtk_tool_item_group_set_label_widget) Xen_wrap_2_args(gxg_gtk_tool_item_group_set_collapsed_w, gxg_gtk_tool_item_group_set_collapsed) Xen_wrap_2_args(gxg_gtk_tool_item_group_set_ellipsize_w, gxg_gtk_tool_item_group_set_ellipsize) Xen_wrap_2_args(gxg_gtk_tool_item_group_set_header_relief_w, gxg_gtk_tool_item_group_set_header_relief) Xen_wrap_1_arg(gxg_gtk_tool_item_group_get_label_w, gxg_gtk_tool_item_group_get_label) Xen_wrap_1_arg(gxg_gtk_tool_item_group_get_label_widget_w, gxg_gtk_tool_item_group_get_label_widget) Xen_wrap_1_arg(gxg_gtk_tool_item_group_get_collapsed_w, gxg_gtk_tool_item_group_get_collapsed) Xen_wrap_1_arg(gxg_gtk_tool_item_group_get_ellipsize_w, gxg_gtk_tool_item_group_get_ellipsize) Xen_wrap_1_arg(gxg_gtk_tool_item_group_get_header_relief_w, gxg_gtk_tool_item_group_get_header_relief) Xen_wrap_3_args(gxg_gtk_tool_item_group_insert_w, gxg_gtk_tool_item_group_insert) Xen_wrap_3_args(gxg_gtk_tool_item_group_set_item_position_w, gxg_gtk_tool_item_group_set_item_position) Xen_wrap_2_args(gxg_gtk_tool_item_group_get_item_position_w, gxg_gtk_tool_item_group_get_item_position) Xen_wrap_1_arg(gxg_gtk_tool_item_group_get_n_items_w, gxg_gtk_tool_item_group_get_n_items) Xen_wrap_2_args(gxg_gtk_tool_item_group_get_nth_item_w, gxg_gtk_tool_item_group_get_nth_item) Xen_wrap_3_args(gxg_gtk_tool_item_group_get_drop_item_w, gxg_gtk_tool_item_group_get_drop_item) Xen_wrap_1_arg(gxg_gdk_screen_get_primary_monitor_w, gxg_gdk_screen_get_primary_monitor) Xen_wrap_2_args(gxg_gtk_window_set_mnemonics_visible_w, gxg_gtk_window_set_mnemonics_visible) Xen_wrap_1_arg(gxg_gtk_window_get_mnemonics_visible_w, gxg_gtk_window_get_mnemonics_visible) Xen_wrap_2_args(gxg_gtk_range_set_slider_size_fixed_w, gxg_gtk_range_set_slider_size_fixed) Xen_wrap_1_arg(gxg_gtk_range_get_slider_size_fixed_w, gxg_gtk_range_get_slider_size_fixed) Xen_wrap_2_args(gxg_gtk_range_set_min_slider_size_w, gxg_gtk_range_set_min_slider_size) Xen_wrap_1_arg(gxg_gtk_range_get_min_slider_size_w, gxg_gtk_range_get_min_slider_size) Xen_wrap_2_args(gxg_gtk_range_get_range_rect_w, gxg_gtk_range_get_range_rect) Xen_wrap_3_optional_args(gxg_gtk_range_get_slider_range_w, gxg_gtk_range_get_slider_range) Xen_wrap_1_arg(gxg_gtk_paned_get_handle_window_w, gxg_gtk_paned_get_handle_window) Xen_wrap_2_args(gxg_gtk_widget_set_realized_w, gxg_gtk_widget_set_realized) Xen_wrap_1_arg(gxg_gtk_widget_get_realized_w, gxg_gtk_widget_get_realized) Xen_wrap_2_args(gxg_gtk_widget_set_mapped_w, gxg_gtk_widget_set_mapped) Xen_wrap_1_arg(gxg_gtk_widget_get_mapped_w, gxg_gtk_widget_get_mapped) #endif #if GTK_CHECK_VERSION(3, 0, 0) Xen_wrap_1_arg(gxg_gdk_cairo_create_w, gxg_gdk_cairo_create) Xen_wrap_5_optional_args(gxg_gdk_window_get_geometry_w, gxg_gdk_window_get_geometry) Xen_wrap_2_args(gxg_gdk_keymap_add_virtual_modifiers_w, gxg_gdk_keymap_add_virtual_modifiers) Xen_wrap_5_optional_args(gxg_gdk_window_coords_to_parent_w, gxg_gdk_window_coords_to_parent) Xen_wrap_5_optional_args(gxg_gdk_window_coords_from_parent_w, gxg_gdk_window_coords_from_parent) Xen_wrap_1_arg(gxg_gdk_window_get_effective_parent_w, gxg_gdk_window_get_effective_parent) Xen_wrap_1_arg(gxg_gdk_window_get_effective_toplevel_w, gxg_gdk_window_get_effective_toplevel) Xen_wrap_1_arg(gxg_gtk_accessible_get_widget_w, gxg_gtk_accessible_get_widget) Xen_wrap_2_args(gxg_gtk_widget_send_focus_change_w, gxg_gtk_widget_send_focus_change) Xen_wrap_1_arg(gxg_gdk_display_get_device_manager_w, gxg_gdk_display_get_device_manager) Xen_wrap_2_args(gxg_gdk_drag_context_set_device_w, gxg_gdk_drag_context_set_device) Xen_wrap_1_arg(gxg_gdk_drag_context_get_device_w, gxg_gdk_drag_context_get_device) Xen_wrap_1_arg(gxg_gdk_drag_context_list_targets_w, gxg_gdk_drag_context_list_targets) Xen_wrap_2_args(gxg_gdk_event_set_device_w, gxg_gdk_event_set_device) Xen_wrap_1_arg(gxg_gdk_event_get_device_w, gxg_gdk_event_get_device) Xen_wrap_3_optional_args(gxg_gdk_events_get_distance_w, gxg_gdk_events_get_distance) Xen_wrap_3_optional_args(gxg_gdk_events_get_angle_w, gxg_gdk_events_get_angle) Xen_wrap_4_optional_args(gxg_gdk_events_get_center_w, gxg_gdk_events_get_center) Xen_wrap_1_arg(gxg_gdk_window_get_accept_focus_w, gxg_gdk_window_get_accept_focus) Xen_wrap_1_arg(gxg_gdk_window_get_focus_on_map_w, gxg_gdk_window_get_focus_on_map) Xen_wrap_1_arg(gxg_gdk_window_is_input_only_w, gxg_gdk_window_is_input_only) Xen_wrap_1_arg(gxg_gdk_window_is_shaped_w, gxg_gdk_window_is_shaped) Xen_wrap_1_arg(gxg_gdk_window_get_modal_hint_w, gxg_gdk_window_get_modal_hint) Xen_wrap_3_args(gxg_gdk_window_set_device_cursor_w, gxg_gdk_window_set_device_cursor) Xen_wrap_2_args(gxg_gdk_window_get_device_cursor_w, gxg_gdk_window_get_device_cursor) Xen_wrap_5_optional_args(gxg_gdk_window_get_device_position_w, gxg_gdk_window_get_device_position) Xen_wrap_3_args(gxg_gdk_window_set_device_events_w, gxg_gdk_window_set_device_events) Xen_wrap_2_args(gxg_gdk_window_get_device_events_w, gxg_gdk_window_get_device_events) Xen_wrap_2_args(gxg_gtk_combo_box_popup_for_device_w, gxg_gtk_combo_box_popup_for_device) Xen_wrap_3_args(gxg_gtk_device_grab_add_w, gxg_gtk_device_grab_add) Xen_wrap_2_args(gxg_gtk_device_grab_remove_w, gxg_gtk_device_grab_remove) Xen_wrap_no_args(gxg_gtk_get_current_event_device_w, gxg_gtk_get_current_event_device) Xen_wrap_1_arg(gxg_gtk_paned_new_w, gxg_gtk_paned_new) Xen_wrap_2_args(gxg_gtk_scale_new_w, gxg_gtk_scale_new) Xen_wrap_4_args(gxg_gtk_scale_new_with_range_w, gxg_gtk_scale_new_with_range) Xen_wrap_2_args(gxg_gtk_scrollbar_new_w, gxg_gtk_scrollbar_new) Xen_wrap_1_arg(gxg_gtk_separator_new_w, gxg_gtk_separator_new) Xen_wrap_2_args(gxg_gtk_widget_device_is_shadowed_w, gxg_gtk_widget_device_is_shadowed) Xen_wrap_3_args(gxg_gtk_widget_set_device_events_w, gxg_gtk_widget_set_device_events) Xen_wrap_3_args(gxg_gtk_widget_add_device_events_w, gxg_gtk_widget_add_device_events) Xen_wrap_1_arg(gxg_gtk_widget_get_support_multidevice_w, gxg_gtk_widget_get_support_multidevice) Xen_wrap_2_args(gxg_gtk_widget_set_support_multidevice_w, gxg_gtk_widget_set_support_multidevice) Xen_wrap_2_args(gxg_gtk_widget_get_device_events_w, gxg_gtk_widget_get_device_events) Xen_wrap_2_args(gxg_gtk_icon_view_get_item_row_w, gxg_gtk_icon_view_get_item_row) Xen_wrap_2_args(gxg_gtk_icon_view_get_item_column_w, gxg_gtk_icon_view_get_item_column) Xen_wrap_2_args(gxg_gtk_statusbar_remove_all_w, gxg_gtk_statusbar_remove_all) Xen_wrap_1_arg(gxg_gtk_window_has_group_w, gxg_gtk_window_has_group) Xen_wrap_3_args(gxg_gtk_calendar_select_month_w, gxg_gtk_calendar_select_month) Xen_wrap_2_args(gxg_gtk_calendar_mark_day_w, gxg_gtk_calendar_mark_day) Xen_wrap_2_args(gxg_gtk_calendar_unmark_day_w, gxg_gtk_calendar_unmark_day) Xen_wrap_1_arg(gxg_gdk_drag_context_get_source_window_w, gxg_gdk_drag_context_get_source_window) Xen_wrap_1_arg(gxg_gtk_viewport_get_view_window_w, gxg_gtk_viewport_get_view_window) Xen_wrap_2_args(gxg_gtk_accessible_set_widget_w, gxg_gtk_accessible_set_widget) Xen_wrap_1_arg(gxg_gtk_button_get_event_window_w, gxg_gtk_button_get_event_window) Xen_wrap_1_arg(gxg_gtk_message_dialog_get_message_area_w, gxg_gtk_message_dialog_get_message_area) Xen_wrap_1_arg(gxg_gtk_selection_data_get_length_w, gxg_gtk_selection_data_get_length) Xen_wrap_5_args(gxg_gdk_pango_layout_line_get_clip_region_w, gxg_gdk_pango_layout_line_get_clip_region) Xen_wrap_5_args(gxg_gdk_pango_layout_get_clip_region_w, gxg_gdk_pango_layout_get_clip_region) Xen_wrap_4_args(gxg_gdk_window_shape_combine_region_w, gxg_gdk_window_shape_combine_region) Xen_wrap_3_args(gxg_gdk_window_invalidate_region_w, gxg_gdk_window_invalidate_region) Xen_wrap_1_arg(gxg_gdk_window_get_update_area_w, gxg_gdk_window_get_update_area) Xen_wrap_2_args(gxg_gdk_window_begin_paint_region_w, gxg_gdk_window_begin_paint_region) Xen_wrap_4_args(gxg_gdk_window_move_region_w, gxg_gdk_window_move_region) Xen_wrap_1_arg(gxg_gdk_keymap_get_num_lock_state_w, gxg_gdk_keymap_get_num_lock_state) Xen_wrap_1_arg(gxg_gdk_window_has_native_w, gxg_gdk_window_has_native) Xen_wrap_1_arg(gxg_gdk_cursor_get_cursor_type_w, gxg_gdk_cursor_get_cursor_type) Xen_wrap_1_arg(gxg_gdk_display_is_closed_w, gxg_gdk_display_is_closed) Xen_wrap_1_arg(gxg_gdk_window_get_background_pattern_w, gxg_gdk_window_get_background_pattern) Xen_wrap_4_args(gxg_gdk_window_create_similar_surface_w, gxg_gdk_window_create_similar_surface) Xen_wrap_2_args(gxg_gtk_expander_set_label_fill_w, gxg_gtk_expander_set_label_fill) Xen_wrap_1_arg(gxg_gtk_expander_get_label_fill_w, gxg_gtk_expander_get_label_fill) Xen_wrap_2_args(gxg_gtk_calendar_get_day_is_marked_w, gxg_gtk_calendar_get_day_is_marked) Xen_wrap_2_args(gxg_gtk_progress_bar_set_inverted_w, gxg_gtk_progress_bar_set_inverted) Xen_wrap_1_arg(gxg_gtk_progress_bar_get_inverted_w, gxg_gtk_progress_bar_get_inverted) Xen_wrap_2_args(gxg_gtk_radio_button_join_group_w, gxg_gtk_radio_button_join_group) Xen_wrap_6_args(gxg_gtk_adjustment_new_w, gxg_gtk_adjustment_new) Xen_wrap_4_args(gxg_gtk_binding_set_activate_w, gxg_gtk_binding_set_activate) Xen_wrap_3_args(gxg_gtk_bindings_activate_w, gxg_gtk_bindings_activate) Xen_wrap_2_args(gxg_gtk_icon_view_create_drag_icon_w, gxg_gtk_icon_view_create_drag_icon) Xen_wrap_2_args(gxg_gtk_tree_view_create_row_drag_icon_w, gxg_gtk_tree_view_create_row_drag_icon) Xen_wrap_2_args(gxg_gdk_cairo_get_clip_rectangle_w, gxg_gdk_cairo_get_clip_rectangle) Xen_wrap_1_arg(gxg_gdk_cairo_region_create_from_surface_w, gxg_gdk_cairo_region_create_from_surface) Xen_wrap_1_arg(gxg_gdk_window_get_visual_w, gxg_gdk_window_get_visual) Xen_wrap_1_arg(gxg_gdk_window_get_screen_w, gxg_gdk_window_get_screen) Xen_wrap_1_arg(gxg_gdk_window_get_display_w, gxg_gdk_window_get_display) Xen_wrap_1_arg(gxg_gdk_window_get_width_w, gxg_gdk_window_get_width) Xen_wrap_1_arg(gxg_gdk_window_get_height_w, gxg_gdk_window_get_height) Xen_wrap_1_arg(gxg_gtk_cell_renderer_get_request_mode_w, gxg_gtk_cell_renderer_get_request_mode) Xen_wrap_4_optional_args(gxg_gtk_cell_renderer_get_preferred_width_w, gxg_gtk_cell_renderer_get_preferred_width) Xen_wrap_5_optional_args(gxg_gtk_cell_renderer_get_preferred_height_for_width_w, gxg_gtk_cell_renderer_get_preferred_height_for_width) Xen_wrap_4_optional_args(gxg_gtk_cell_renderer_get_preferred_height_w, gxg_gtk_cell_renderer_get_preferred_height) Xen_wrap_5_optional_args(gxg_gtk_cell_renderer_get_preferred_width_for_height_w, gxg_gtk_cell_renderer_get_preferred_width_for_height) Xen_wrap_1_arg(gxg_gtk_container_class_handle_border_width_w, gxg_gtk_container_class_handle_border_width) Xen_wrap_2_args(gxg_gtk_drag_set_icon_surface_w, gxg_gtk_drag_set_icon_surface) Xen_wrap_2_args(gxg_gtk_notebook_set_group_name_w, gxg_gtk_notebook_set_group_name) Xen_wrap_1_arg(gxg_gtk_notebook_get_group_name_w, gxg_gtk_notebook_get_group_name) Xen_wrap_2_args(gxg_gtk_widget_draw_w, gxg_gtk_widget_draw) Xen_wrap_1_arg(gxg_gtk_widget_get_request_mode_w, gxg_gtk_widget_get_request_mode) Xen_wrap_3_optional_args(gxg_gtk_widget_get_preferred_width_w, gxg_gtk_widget_get_preferred_width) Xen_wrap_4_optional_args(gxg_gtk_widget_get_preferred_height_for_width_w, gxg_gtk_widget_get_preferred_height_for_width) Xen_wrap_3_optional_args(gxg_gtk_widget_get_preferred_height_w, gxg_gtk_widget_get_preferred_height) Xen_wrap_4_optional_args(gxg_gtk_widget_get_preferred_width_for_height_w, gxg_gtk_widget_get_preferred_width_for_height) Xen_wrap_1_arg(gxg_gtk_widget_get_allocated_width_w, gxg_gtk_widget_get_allocated_width) Xen_wrap_1_arg(gxg_gtk_widget_get_allocated_height_w, gxg_gtk_widget_get_allocated_height) Xen_wrap_2_args(gxg_gtk_widget_set_visual_w, gxg_gtk_widget_set_visual) Xen_wrap_1_arg(gxg_gtk_widget_get_halign_w, gxg_gtk_widget_get_halign) Xen_wrap_2_args(gxg_gtk_widget_set_halign_w, gxg_gtk_widget_set_halign) Xen_wrap_1_arg(gxg_gtk_widget_get_valign_w, gxg_gtk_widget_get_valign) Xen_wrap_2_args(gxg_gtk_widget_set_valign_w, gxg_gtk_widget_set_valign) Xen_wrap_1_arg(gxg_gtk_widget_get_margin_top_w, gxg_gtk_widget_get_margin_top) Xen_wrap_2_args(gxg_gtk_widget_set_margin_top_w, gxg_gtk_widget_set_margin_top) Xen_wrap_1_arg(gxg_gtk_widget_get_margin_bottom_w, gxg_gtk_widget_get_margin_bottom) Xen_wrap_2_args(gxg_gtk_widget_set_margin_bottom_w, gxg_gtk_widget_set_margin_bottom) Xen_wrap_2_args(gxg_gtk_widget_shape_combine_region_w, gxg_gtk_widget_shape_combine_region) Xen_wrap_2_args(gxg_gtk_widget_input_shape_combine_region_w, gxg_gtk_widget_input_shape_combine_region) Xen_wrap_2_args(gxg_gtk_cairo_should_draw_window_w, gxg_gtk_cairo_should_draw_window) Xen_wrap_3_args(gxg_gtk_cairo_transform_to_window_w, gxg_gtk_cairo_transform_to_window) Xen_wrap_no_args(gxg_gtk_combo_box_new_with_entry_w, gxg_gtk_combo_box_new_with_entry) Xen_wrap_1_arg(gxg_gtk_combo_box_get_has_entry_w, gxg_gtk_combo_box_get_has_entry) Xen_wrap_2_args(gxg_gtk_combo_box_set_entry_text_column_w, gxg_gtk_combo_box_set_entry_text_column) Xen_wrap_1_arg(gxg_gtk_combo_box_get_entry_text_column_w, gxg_gtk_combo_box_get_entry_text_column) Xen_wrap_3_args(gxg_gtk_target_entry_new_w, gxg_gtk_target_entry_new) Xen_wrap_1_arg(gxg_gtk_target_entry_copy_w, gxg_gtk_target_entry_copy) Xen_wrap_1_arg(gxg_gtk_target_entry_free_w, gxg_gtk_target_entry_free) Xen_wrap_1_arg(gxg_gtk_widget_get_hexpand_w, gxg_gtk_widget_get_hexpand) Xen_wrap_2_args(gxg_gtk_widget_set_hexpand_w, gxg_gtk_widget_set_hexpand) Xen_wrap_1_arg(gxg_gtk_widget_get_hexpand_set_w, gxg_gtk_widget_get_hexpand_set) Xen_wrap_2_args(gxg_gtk_widget_set_hexpand_set_w, gxg_gtk_widget_set_hexpand_set) Xen_wrap_1_arg(gxg_gtk_widget_get_vexpand_w, gxg_gtk_widget_get_vexpand) Xen_wrap_2_args(gxg_gtk_widget_set_vexpand_w, gxg_gtk_widget_set_vexpand) Xen_wrap_1_arg(gxg_gtk_widget_get_vexpand_set_w, gxg_gtk_widget_get_vexpand_set) Xen_wrap_2_args(gxg_gtk_widget_set_vexpand_set_w, gxg_gtk_widget_set_vexpand_set) Xen_wrap_1_arg(gxg_gtk_widget_queue_compute_expand_w, gxg_gtk_widget_queue_compute_expand) Xen_wrap_2_args(gxg_gtk_widget_compute_expand_w, gxg_gtk_widget_compute_expand) Xen_wrap_3_args(gxg_gtk_window_set_default_geometry_w, gxg_gtk_window_set_default_geometry) Xen_wrap_3_args(gxg_gtk_window_resize_to_geometry_w, gxg_gtk_window_resize_to_geometry) Xen_wrap_no_args(gxg_gtk_combo_box_text_new_w, gxg_gtk_combo_box_text_new) Xen_wrap_no_args(gxg_gtk_combo_box_text_new_with_entry_w, gxg_gtk_combo_box_text_new_with_entry) Xen_wrap_2_args(gxg_gtk_combo_box_text_append_text_w, gxg_gtk_combo_box_text_append_text) Xen_wrap_3_args(gxg_gtk_combo_box_text_insert_text_w, gxg_gtk_combo_box_text_insert_text) Xen_wrap_2_args(gxg_gtk_combo_box_text_prepend_text_w, gxg_gtk_combo_box_text_prepend_text) Xen_wrap_2_args(gxg_gtk_combo_box_text_remove_w, gxg_gtk_combo_box_text_remove) Xen_wrap_1_arg(gxg_gtk_combo_box_text_get_active_text_w, gxg_gtk_combo_box_text_get_active_text) Xen_wrap_2_args(gxg_gdk_cairo_set_source_rgba_w, gxg_gdk_cairo_set_source_rgba) Xen_wrap_2_args(gxg_gdk_window_set_background_rgba_w, gxg_gdk_window_set_background_rgba) Xen_wrap_2_args(gxg_gtk_cell_view_set_background_rgba_w, gxg_gtk_cell_view_set_background_rgba) Xen_wrap_1_arg(gxg_gtk_combo_box_text_remove_all_w, gxg_gtk_combo_box_text_remove_all) Xen_wrap_2_args(gxg_gtk_combo_box_set_popup_fixed_width_w, gxg_gtk_combo_box_set_popup_fixed_width) Xen_wrap_1_arg(gxg_gtk_combo_box_get_popup_fixed_width_w, gxg_gtk_combo_box_get_popup_fixed_width) Xen_wrap_1_arg(gxg_gtk_scrolled_window_get_min_content_width_w, gxg_gtk_scrolled_window_get_min_content_width) Xen_wrap_2_args(gxg_gtk_scrolled_window_set_min_content_width_w, gxg_gtk_scrolled_window_set_min_content_width) Xen_wrap_1_arg(gxg_gtk_scrolled_window_get_min_content_height_w, gxg_gtk_scrolled_window_get_min_content_height) Xen_wrap_2_args(gxg_gtk_scrolled_window_set_min_content_height_w, gxg_gtk_scrolled_window_set_min_content_height) Xen_wrap_no_args(gxg_gtk_grid_new_w, gxg_gtk_grid_new) Xen_wrap_6_args(gxg_gtk_grid_attach_w, gxg_gtk_grid_attach) Xen_wrap_6_args(gxg_gtk_grid_attach_next_to_w, gxg_gtk_grid_attach_next_to) Xen_wrap_2_args(gxg_gtk_grid_set_row_homogeneous_w, gxg_gtk_grid_set_row_homogeneous) Xen_wrap_1_arg(gxg_gtk_grid_get_row_homogeneous_w, gxg_gtk_grid_get_row_homogeneous) Xen_wrap_2_args(gxg_gtk_grid_set_row_spacing_w, gxg_gtk_grid_set_row_spacing) Xen_wrap_1_arg(gxg_gtk_grid_get_row_spacing_w, gxg_gtk_grid_get_row_spacing) Xen_wrap_2_args(gxg_gtk_grid_set_column_homogeneous_w, gxg_gtk_grid_set_column_homogeneous) Xen_wrap_1_arg(gxg_gtk_grid_get_column_homogeneous_w, gxg_gtk_grid_get_column_homogeneous) Xen_wrap_2_args(gxg_gtk_grid_set_column_spacing_w, gxg_gtk_grid_set_column_spacing) Xen_wrap_1_arg(gxg_gtk_grid_get_column_spacing_w, gxg_gtk_grid_get_column_spacing) Xen_wrap_1_arg(gxg_gtk_scrollable_get_hadjustment_w, gxg_gtk_scrollable_get_hadjustment) Xen_wrap_2_args(gxg_gtk_scrollable_set_hadjustment_w, gxg_gtk_scrollable_set_hadjustment) Xen_wrap_1_arg(gxg_gtk_scrollable_get_vadjustment_w, gxg_gtk_scrollable_get_vadjustment) Xen_wrap_2_args(gxg_gtk_scrollable_set_vadjustment_w, gxg_gtk_scrollable_set_vadjustment) Xen_wrap_1_arg(gxg_gtk_assistant_next_page_w, gxg_gtk_assistant_next_page) Xen_wrap_1_arg(gxg_gtk_assistant_previous_page_w, gxg_gtk_assistant_previous_page) Xen_wrap_1_arg(gxg_gtk_combo_box_new_with_model_and_entry_w, gxg_gtk_combo_box_new_with_model_and_entry) Xen_wrap_1_arg(gxg_gtk_scrollable_get_hscroll_policy_w, gxg_gtk_scrollable_get_hscroll_policy) Xen_wrap_2_args(gxg_gtk_scrollable_set_hscroll_policy_w, gxg_gtk_scrollable_set_hscroll_policy) Xen_wrap_1_arg(gxg_gtk_scrollable_get_vscroll_policy_w, gxg_gtk_scrollable_get_vscroll_policy) Xen_wrap_2_args(gxg_gtk_scrollable_set_vscroll_policy_w, gxg_gtk_scrollable_set_vscroll_policy) Xen_wrap_no_args(gxg_gtk_switch_new_w, gxg_gtk_switch_new) Xen_wrap_2_args(gxg_gtk_switch_set_active_w, gxg_gtk_switch_set_active) Xen_wrap_1_arg(gxg_gtk_switch_get_active_w, gxg_gtk_switch_get_active) Xen_wrap_1_arg(gxg_gdk_window_get_clip_region_w, gxg_gdk_window_get_clip_region) Xen_wrap_1_arg(gxg_gdk_window_get_visible_region_w, gxg_gdk_window_get_visible_region) Xen_wrap_no_args(gxg_gtk_border_new_w, gxg_gtk_border_new) Xen_wrap_1_arg(gxg_gtk_border_copy_w, gxg_gtk_border_copy) Xen_wrap_1_arg(gxg_gtk_border_free_w, gxg_gtk_border_free) Xen_wrap_1_arg(gxg_gtk_combo_box_get_id_column_w, gxg_gtk_combo_box_get_id_column) Xen_wrap_2_args(gxg_gtk_combo_box_set_id_column_w, gxg_gtk_combo_box_set_id_column) Xen_wrap_1_arg(gxg_gtk_combo_box_get_active_id_w, gxg_gtk_combo_box_get_active_id) Xen_wrap_4_args(gxg_gtk_combo_box_text_insert_w, gxg_gtk_combo_box_text_insert) Xen_wrap_3_args(gxg_gtk_combo_box_text_append_w, gxg_gtk_combo_box_text_append) Xen_wrap_3_args(gxg_gtk_combo_box_text_prepend_w, gxg_gtk_combo_box_text_prepend) Xen_wrap_1_arg(gxg_gtk_button_box_new_w, gxg_gtk_button_box_new) Xen_wrap_2_args(gxg_gtk_box_new_w, gxg_gtk_box_new) Xen_wrap_5_args(gxg_gtk_tree_view_set_cursor_on_cell_w, gxg_gtk_tree_view_set_cursor_on_cell) Xen_wrap_2_args(gxg_gtk_tree_view_set_rubber_banding_w, gxg_gtk_tree_view_set_rubber_banding) Xen_wrap_1_arg(gxg_gtk_tree_view_get_rubber_banding_w, gxg_gtk_tree_view_get_rubber_banding) Xen_wrap_2_args(gxg_gtk_tooltip_set_markup_w, gxg_gtk_tooltip_set_markup) Xen_wrap_2_args(gxg_gtk_tooltip_set_icon_w, gxg_gtk_tooltip_set_icon) Xen_wrap_2_args(gxg_gtk_tooltip_set_custom_w, gxg_gtk_tooltip_set_custom) Xen_wrap_1_arg(gxg_gtk_tooltip_trigger_tooltip_query_w, gxg_gtk_tooltip_trigger_tooltip_query) Xen_wrap_2_args(gxg_gtk_button_set_image_position_w, gxg_gtk_button_set_image_position) Xen_wrap_1_arg(gxg_gtk_button_get_image_position_w, gxg_gtk_button_get_image_position) Xen_wrap_4_optional_args(gxg_gtk_show_uri_w, gxg_gtk_show_uri) Xen_wrap_1_arg(gxg_gtk_tree_view_column_new_with_area_w, gxg_gtk_tree_view_column_new_with_area) Xen_wrap_1_arg(gxg_gtk_tree_view_column_get_button_w, gxg_gtk_tree_view_column_get_button) Xen_wrap_2_args(gxg_gtk_tree_view_column_focus_cell_w, gxg_gtk_tree_view_column_focus_cell) Xen_wrap_1_arg(gxg_gtk_clipboard_wait_is_uris_available_w, gxg_gtk_clipboard_wait_is_uris_available) Xen_wrap_3_args(gxg_gtk_toolbar_set_drop_highlight_item_w, gxg_gtk_toolbar_set_drop_highlight_item) Xen_wrap_1_arg(gxg_gtk_tool_item_toolbar_reconfigured_w, gxg_gtk_tool_item_toolbar_reconfigured) Xen_wrap_2_args(gxg_gtk_orientable_set_orientation_w, gxg_gtk_orientable_set_orientation) Xen_wrap_1_arg(gxg_gtk_orientable_get_orientation_w, gxg_gtk_orientable_get_orientation) Xen_wrap_2_optional_args(gxg_gtk_parse_args_w, gxg_gtk_parse_args) Xen_wrap_no_args(gxg_gtk_get_major_version_w, gxg_gtk_get_major_version) Xen_wrap_no_args(gxg_gtk_get_minor_version_w, gxg_gtk_get_minor_version) Xen_wrap_no_args(gxg_gtk_get_micro_version_w, gxg_gtk_get_micro_version) Xen_wrap_no_args(gxg_gtk_get_binary_age_w, gxg_gtk_get_binary_age) Xen_wrap_no_args(gxg_gtk_get_interface_age_w, gxg_gtk_get_interface_age) Xen_wrap_2_args(gxg_gtk_progress_bar_set_show_text_w, gxg_gtk_progress_bar_set_show_text) Xen_wrap_1_arg(gxg_gtk_progress_bar_get_show_text_w, gxg_gtk_progress_bar_get_show_text) Xen_wrap_1_arg(gxg_gtk_invisible_new_for_screen_w, gxg_gtk_invisible_new_for_screen) Xen_wrap_2_args(gxg_gtk_invisible_set_screen_w, gxg_gtk_invisible_set_screen) Xen_wrap_1_arg(gxg_gtk_invisible_get_screen_w, gxg_gtk_invisible_get_screen) Xen_wrap_2_args(gxg_gtk_entry_get_icon_storage_type_w, gxg_gtk_entry_get_icon_storage_type) Xen_wrap_2_args(gxg_gtk_entry_get_icon_pixbuf_w, gxg_gtk_entry_get_icon_pixbuf) Xen_wrap_2_args(gxg_gtk_entry_get_icon_gicon_w, gxg_gtk_entry_get_icon_gicon) Xen_wrap_3_args(gxg_gtk_container_propagate_draw_w, gxg_gtk_container_propagate_draw) Xen_wrap_2_args(gxg_gtk_container_set_focus_chain_w, gxg_gtk_container_set_focus_chain) Xen_wrap_2_optional_args(gxg_gtk_container_get_focus_chain_w, gxg_gtk_container_get_focus_chain) Xen_wrap_1_arg(gxg_gtk_container_unset_focus_chain_w, gxg_gtk_container_unset_focus_chain) Xen_wrap_2_args(gxg_gtk_container_set_focus_child_w, gxg_gtk_container_set_focus_child) Xen_wrap_2_args(gxg_gtk_container_set_focus_vadjustment_w, gxg_gtk_container_set_focus_vadjustment) Xen_wrap_1_arg(gxg_gtk_container_get_focus_vadjustment_w, gxg_gtk_container_get_focus_vadjustment) Xen_wrap_2_args(gxg_gtk_container_set_focus_hadjustment_w, gxg_gtk_container_set_focus_hadjustment) Xen_wrap_1_arg(gxg_gtk_container_get_focus_hadjustment_w, gxg_gtk_container_get_focus_hadjustment) Xen_wrap_1_arg(gxg_gtk_assistant_commit_w, gxg_gtk_assistant_commit) Xen_wrap_2_args(gxg_gtk_window_set_skip_taskbar_hint_w, gxg_gtk_window_set_skip_taskbar_hint) Xen_wrap_1_arg(gxg_gtk_window_get_skip_taskbar_hint_w, gxg_gtk_window_get_skip_taskbar_hint) Xen_wrap_2_args(gxg_gtk_window_set_skip_pager_hint_w, gxg_gtk_window_set_skip_pager_hint) Xen_wrap_1_arg(gxg_gtk_window_get_skip_pager_hint_w, gxg_gtk_window_get_skip_pager_hint) Xen_wrap_2_args(gxg_gtk_window_set_screen_w, gxg_gtk_window_set_screen) Xen_wrap_1_arg(gxg_gtk_window_get_screen_w, gxg_gtk_window_get_screen) Xen_wrap_3_optional_args(gxg_gtk_window_set_icon_from_file_w, gxg_gtk_window_set_icon_from_file) Xen_wrap_2_optional_args(gxg_gtk_window_set_default_icon_from_file_w, gxg_gtk_window_set_default_icon_from_file) Xen_wrap_1_arg(gxg_gtk_window_fullscreen_w, gxg_gtk_window_fullscreen) Xen_wrap_1_arg(gxg_gtk_window_unfullscreen_w, gxg_gtk_window_unfullscreen) Xen_wrap_1_arg(gxg_gtk_window_get_window_type_w, gxg_gtk_window_get_window_type) Xen_wrap_2_args(gxg_gtk_window_group_add_window_w, gxg_gtk_window_group_add_window) Xen_wrap_2_args(gxg_gtk_window_group_remove_window_w, gxg_gtk_window_group_remove_window) Xen_wrap_no_args(gxg_gtk_window_group_new_w, gxg_gtk_window_group_new) Xen_wrap_1_arg(gxg_gtk_window_get_group_w, gxg_gtk_window_get_group) Xen_wrap_1_arg(gxg_gtk_window_group_list_windows_w, gxg_gtk_window_group_list_windows) Xen_wrap_2_args(gxg_gtk_window_group_get_current_device_grab_w, gxg_gtk_window_group_get_current_device_grab) Xen_wrap_1_arg(gxg_gtk_window_group_get_current_grab_w, gxg_gtk_window_group_get_current_grab) Xen_wrap_1_arg(gxg_gtk_selection_data_get_data_w, gxg_gtk_selection_data_get_data) Xen_wrap_4_args(gxg_gtk_selection_owner_set_for_display_w, gxg_gtk_selection_owner_set_for_display) Xen_wrap_1_arg(gxg_gtk_tool_shell_get_text_orientation_w, gxg_gtk_tool_shell_get_text_orientation) Xen_wrap_1_arg(gxg_gtk_tool_shell_get_text_alignment_w, gxg_gtk_tool_shell_get_text_alignment) Xen_wrap_1_arg(gxg_gtk_tool_shell_get_ellipsize_mode_w, gxg_gtk_tool_shell_get_ellipsize_mode) Xen_wrap_1_arg(gxg_gtk_tool_shell_get_text_size_group_w, gxg_gtk_tool_shell_get_text_size_group) Xen_wrap_1_arg(gxg_gtk_tool_shell_get_orientation_w, gxg_gtk_tool_shell_get_orientation) Xen_wrap_1_arg(gxg_gtk_tool_shell_get_style_w, gxg_gtk_tool_shell_get_style) Xen_wrap_1_arg(gxg_gtk_tool_shell_get_relief_style_w, gxg_gtk_tool_shell_get_relief_style) Xen_wrap_1_arg(gxg_gtk_tool_shell_rebuild_menu_w, gxg_gtk_tool_shell_rebuild_menu) Xen_wrap_1_arg(gxg_gtk_accel_map_lock_path_w, gxg_gtk_accel_map_lock_path) Xen_wrap_1_arg(gxg_gtk_accel_map_unlock_path_w, gxg_gtk_accel_map_unlock_path) Xen_wrap_4_args(gxg_gtk_icon_theme_lookup_by_gicon_w, gxg_gtk_icon_theme_lookup_by_gicon) Xen_wrap_2_args(gxg_gtk_icon_info_new_for_pixbuf_w, gxg_gtk_icon_info_new_for_pixbuf) Xen_wrap_2_args(gxg_gtk_icon_view_set_item_orientation_w, gxg_gtk_icon_view_set_item_orientation) Xen_wrap_1_arg(gxg_gtk_icon_view_get_item_orientation_w, gxg_gtk_icon_view_get_item_orientation) Xen_wrap_2_args(gxg_gtk_text_view_im_context_filter_keypress_w, gxg_gtk_text_view_im_context_filter_keypress) Xen_wrap_1_arg(gxg_gtk_text_view_reset_im_context_w, gxg_gtk_text_view_reset_im_context) Xen_wrap_4_optional_args(gxg_gdk_device_get_position_w, gxg_gdk_device_get_position) Xen_wrap_3_optional_args(gxg_gdk_device_get_window_at_position_w, gxg_gdk_device_get_window_at_position) Xen_wrap_1_arg(gxg_gtk_cell_view_get_draw_sensitive_w, gxg_gtk_cell_view_get_draw_sensitive) Xen_wrap_2_args(gxg_gtk_cell_view_set_draw_sensitive_w, gxg_gtk_cell_view_set_draw_sensitive) Xen_wrap_1_arg(gxg_gtk_cell_view_get_fit_model_w, gxg_gtk_cell_view_get_fit_model) Xen_wrap_2_args(gxg_gtk_cell_view_set_fit_model_w, gxg_gtk_cell_view_set_fit_model) Xen_wrap_1_arg(gxg_gtk_combo_box_new_with_area_w, gxg_gtk_combo_box_new_with_area) Xen_wrap_1_arg(gxg_gtk_combo_box_new_with_area_and_entry_w, gxg_gtk_combo_box_new_with_area_and_entry) Xen_wrap_1_arg(gxg_gtk_icon_view_new_with_area_w, gxg_gtk_icon_view_new_with_area) Xen_wrap_2_args(gxg_gtk_menu_item_set_reserve_indicator_w, gxg_gtk_menu_item_set_reserve_indicator) Xen_wrap_1_arg(gxg_gtk_menu_item_get_reserve_indicator_w, gxg_gtk_menu_item_get_reserve_indicator) Xen_wrap_1_arg(gxg_gtk_menu_shell_get_selected_item_w, gxg_gtk_menu_shell_get_selected_item) Xen_wrap_1_arg(gxg_gtk_menu_shell_get_parent_shell_w, gxg_gtk_menu_shell_get_parent_shell) Xen_wrap_2_optional_args(gxg_gtk_selection_data_get_data_with_length_w, gxg_gtk_selection_data_get_data_with_length) Xen_wrap_2_args(gxg_gtk_tree_model_iter_previous_w, gxg_gtk_tree_model_iter_previous) Xen_wrap_7_optional_args(gxg_gtk_tree_view_is_blank_at_pos_w, gxg_gtk_tree_view_is_blank_at_pos) Xen_wrap_3_args(gxg_gtk_widget_set_device_enabled_w, gxg_gtk_widget_set_device_enabled) Xen_wrap_2_args(gxg_gtk_widget_get_device_enabled_w, gxg_gtk_widget_get_device_enabled) Xen_wrap_2_args(gxg_gtk_window_set_has_user_ref_count_w, gxg_gtk_window_set_has_user_ref_count) Xen_wrap_5_args(gxg_gdk_selection_send_notify_w, gxg_gdk_selection_send_notify) Xen_wrap_6_args(gxg_gdk_selection_send_notify_for_display_w, gxg_gdk_selection_send_notify_for_display) Xen_wrap_1_arg(gxg_gdk_rgba_copy_w, gxg_gdk_rgba_copy) Xen_wrap_1_arg(gxg_gdk_rgba_free_w, gxg_gdk_rgba_free) Xen_wrap_2_args(gxg_gdk_rgba_parse_w, gxg_gdk_rgba_parse) Xen_wrap_1_arg(gxg_gdk_rgba_to_string_w, gxg_gdk_rgba_to_string) Xen_wrap_3_args(gxg_gtk_widget_set_state_flags_w, gxg_gtk_widget_set_state_flags) Xen_wrap_2_args(gxg_gtk_widget_unset_state_flags_w, gxg_gtk_widget_unset_state_flags) Xen_wrap_1_arg(gxg_gtk_widget_get_state_flags_w, gxg_gtk_widget_get_state_flags) #endif #if GTK_CHECK_VERSION(3, 2, 0) Xen_wrap_1_arg(gxg_gtk_entry_get_placeholder_text_w, gxg_gtk_entry_get_placeholder_text) Xen_wrap_2_args(gxg_gtk_entry_set_placeholder_text_w, gxg_gtk_entry_set_placeholder_text) Xen_wrap_2_args(gxg_gtk_expander_set_resize_toplevel_w, gxg_gtk_expander_set_resize_toplevel) Xen_wrap_1_arg(gxg_gtk_expander_get_resize_toplevel_w, gxg_gtk_expander_get_resize_toplevel) Xen_wrap_1_arg(gxg_gtk_widget_path_to_string_w, gxg_gtk_widget_path_to_string) Xen_wrap_2_args(gxg_gtk_button_box_get_child_non_homogeneous_w, gxg_gtk_button_box_get_child_non_homogeneous) Xen_wrap_3_args(gxg_gtk_button_box_set_child_non_homogeneous_w, gxg_gtk_button_box_set_child_non_homogeneous) Xen_wrap_3_args(gxg_gtk_container_child_notify_w, gxg_gtk_container_child_notify) Xen_wrap_2_args(gxg_gtk_drag_source_set_icon_gicon_w, gxg_gtk_drag_source_set_icon_gicon) Xen_wrap_4_args(gxg_gtk_drag_set_icon_gicon_w, gxg_gtk_drag_set_icon_gicon) Xen_wrap_2_args(gxg_gtk_combo_box_set_active_id_w, gxg_gtk_combo_box_set_active_id) Xen_wrap_1_arg(gxg_gtk_tree_view_column_get_x_offset_w, gxg_gtk_tree_view_column_get_x_offset) Xen_wrap_no_args(gxg_gtk_overlay_new_w, gxg_gtk_overlay_new) Xen_wrap_2_args(gxg_gtk_overlay_add_overlay_w, gxg_gtk_overlay_add_overlay) Xen_wrap_1_arg(gxg_gtk_adjustment_get_minimum_increment_w, gxg_gtk_adjustment_get_minimum_increment) Xen_wrap_2_args(gxg_gtk_grid_insert_row_w, gxg_gtk_grid_insert_row) Xen_wrap_2_args(gxg_gtk_grid_insert_column_w, gxg_gtk_grid_insert_column) Xen_wrap_3_args(gxg_gtk_grid_insert_next_to_w, gxg_gtk_grid_insert_next_to) Xen_wrap_2_args(gxg_gtk_text_iter_assign_w, gxg_gtk_text_iter_assign) Xen_wrap_1_arg(gxg_gtk_widget_has_visible_focus_w, gxg_gtk_widget_has_visible_focus) Xen_wrap_2_args(gxg_gtk_window_set_focus_visible_w, gxg_gtk_window_set_focus_visible) Xen_wrap_1_arg(gxg_gtk_window_get_focus_visible_w, gxg_gtk_window_get_focus_visible) Xen_wrap_2_args(gxg_gtk_font_chooser_dialog_new_w, gxg_gtk_font_chooser_dialog_new) Xen_wrap_2_args(gxg_gdk_event_get_button_w, gxg_gdk_event_get_button) Xen_wrap_2_args(gxg_gdk_event_get_click_count_w, gxg_gdk_event_get_click_count) Xen_wrap_2_args(gxg_gdk_event_get_keyval_w, gxg_gdk_event_get_keyval) Xen_wrap_2_args(gxg_gdk_event_get_keycode_w, gxg_gdk_event_get_keycode) Xen_wrap_2_optional_args(gxg_gdk_event_get_scroll_direction_w, gxg_gdk_event_get_scroll_direction) Xen_wrap_3_args(gxg_gtk_grid_get_child_at_w, gxg_gtk_grid_get_child_at) Xen_wrap_1_arg(gxg_gtk_font_chooser_get_font_family_w, gxg_gtk_font_chooser_get_font_family) Xen_wrap_1_arg(gxg_gtk_font_chooser_get_font_face_w, gxg_gtk_font_chooser_get_font_face) Xen_wrap_1_arg(gxg_gtk_font_chooser_get_font_size_w, gxg_gtk_font_chooser_get_font_size) Xen_wrap_1_arg(gxg_gtk_font_chooser_get_font_desc_w, gxg_gtk_font_chooser_get_font_desc) Xen_wrap_2_args(gxg_gtk_font_chooser_set_font_desc_w, gxg_gtk_font_chooser_set_font_desc) Xen_wrap_1_arg(gxg_gtk_font_chooser_get_font_w, gxg_gtk_font_chooser_get_font) Xen_wrap_2_args(gxg_gtk_font_chooser_set_font_w, gxg_gtk_font_chooser_set_font) Xen_wrap_1_arg(gxg_gtk_font_chooser_get_preview_text_w, gxg_gtk_font_chooser_get_preview_text) Xen_wrap_2_args(gxg_gtk_font_chooser_set_preview_text_w, gxg_gtk_font_chooser_set_preview_text) Xen_wrap_1_arg(gxg_gtk_font_chooser_get_show_preview_entry_w, gxg_gtk_font_chooser_get_show_preview_entry) Xen_wrap_2_args(gxg_gtk_font_chooser_set_show_preview_entry_w, gxg_gtk_font_chooser_set_show_preview_entry) Xen_wrap_no_args(gxg_gtk_font_chooser_widget_new_w, gxg_gtk_font_chooser_widget_new) #endif #if GTK_CHECK_VERSION(3, 4, 0) Xen_wrap_2_args(gxg_gdk_keymap_get_modifier_mask_w, gxg_gdk_keymap_get_modifier_mask) Xen_wrap_7_args(gxg_gdk_window_begin_resize_drag_for_device_w, gxg_gdk_window_begin_resize_drag_for_device) Xen_wrap_6_args(gxg_gdk_window_begin_move_drag_for_device_w, gxg_gdk_window_begin_move_drag_for_device) Xen_wrap_4_args(gxg_gtk_accelerator_parse_with_keycode_w, gxg_gtk_accelerator_parse_with_keycode) Xen_wrap_4_args(gxg_gtk_accelerator_name_with_keycode_w, gxg_gtk_accelerator_name_with_keycode) Xen_wrap_4_args(gxg_gtk_accelerator_get_label_with_keycode_w, gxg_gtk_accelerator_get_label_with_keycode) Xen_wrap_3_args(gxg_gdk_screen_get_monitor_workarea_w, gxg_gdk_screen_get_monitor_workarea) Xen_wrap_1_arg(gxg_gtk_application_get_app_menu_w, gxg_gtk_application_get_app_menu) Xen_wrap_2_args(gxg_gtk_application_set_app_menu_w, gxg_gtk_application_set_app_menu) Xen_wrap_1_arg(gxg_gtk_application_get_menubar_w, gxg_gtk_application_get_menubar) Xen_wrap_2_args(gxg_gtk_application_set_menubar_w, gxg_gtk_application_set_menubar) Xen_wrap_2_args(gxg_gtk_entry_completion_compute_prefix_w, gxg_gtk_entry_completion_compute_prefix) Xen_wrap_2_args(gxg_gtk_scale_set_has_origin_w, gxg_gtk_scale_set_has_origin) Xen_wrap_1_arg(gxg_gtk_scale_get_has_origin_w, gxg_gtk_scale_get_has_origin) Xen_wrap_2_args(gxg_gtk_window_set_hide_titlebar_when_maximized_w, gxg_gtk_window_set_hide_titlebar_when_maximized) Xen_wrap_1_arg(gxg_gtk_window_get_hide_titlebar_when_maximized_w, gxg_gtk_window_get_hide_titlebar_when_maximized) Xen_wrap_1_arg(gxg_gtk_application_window_new_w, gxg_gtk_application_window_new) Xen_wrap_2_args(gxg_gtk_application_window_set_show_menubar_w, gxg_gtk_application_window_set_show_menubar) Xen_wrap_1_arg(gxg_gtk_application_window_get_show_menubar_w, gxg_gtk_application_window_get_show_menubar) Xen_wrap_1_arg(gxg_gtk_image_new_from_resource_w, gxg_gtk_image_new_from_resource) Xen_wrap_2_args(gxg_gtk_image_set_from_resource_w, gxg_gtk_image_set_from_resource) Xen_wrap_2_args(gxg_gtk_window_set_attached_to_w, gxg_gtk_window_set_attached_to) Xen_wrap_1_arg(gxg_gtk_window_get_attached_to_w, gxg_gtk_window_get_attached_to) Xen_wrap_3_args(gxg_gtk_about_dialog_add_credit_section_w, gxg_gtk_about_dialog_add_credit_section) Xen_wrap_1_arg(gxg_gdk_keymap_get_modifier_state_w, gxg_gdk_keymap_get_modifier_state) Xen_wrap_6_optional_args(gxg_gtk_hsv_to_rgb_w, gxg_gtk_hsv_to_rgb) Xen_wrap_6_optional_args(gxg_gtk_rgb_to_hsv_w, gxg_gtk_rgb_to_hsv) Xen_wrap_2_args(gxg_gtk_color_chooser_get_rgba_w, gxg_gtk_color_chooser_get_rgba) Xen_wrap_2_args(gxg_gtk_color_chooser_set_rgba_w, gxg_gtk_color_chooser_set_rgba) Xen_wrap_1_arg(gxg_gtk_color_chooser_get_use_alpha_w, gxg_gtk_color_chooser_get_use_alpha) Xen_wrap_2_args(gxg_gtk_color_chooser_set_use_alpha_w, gxg_gtk_color_chooser_set_use_alpha) Xen_wrap_2_args(gxg_gtk_color_chooser_dialog_new_w, gxg_gtk_color_chooser_dialog_new) Xen_wrap_no_args(gxg_gtk_color_chooser_widget_new_w, gxg_gtk_color_chooser_widget_new) #endif #if GTK_CHECK_VERSION(3, 6, 0) Xen_wrap_3_optional_args(gxg_gdk_event_get_scroll_deltas_w, gxg_gdk_event_get_scroll_deltas) Xen_wrap_5_args(gxg_gtk_color_chooser_add_palette_w, gxg_gtk_color_chooser_add_palette) Xen_wrap_2_args(gxg_gtk_button_set_always_show_image_w, gxg_gtk_button_set_always_show_image) Xen_wrap_1_arg(gxg_gtk_button_get_always_show_image_w, gxg_gtk_button_get_always_show_image) Xen_wrap_1_arg(gxg_gtk_tree_view_get_n_columns_w, gxg_gtk_tree_view_get_n_columns) Xen_wrap_no_args(gxg_gtk_menu_button_new_w, gxg_gtk_menu_button_new) Xen_wrap_2_args(gxg_gtk_menu_button_set_menu_model_w, gxg_gtk_menu_button_set_menu_model) Xen_wrap_1_arg(gxg_gtk_menu_button_get_menu_model_w, gxg_gtk_menu_button_get_menu_model) Xen_wrap_2_args(gxg_gtk_menu_button_set_align_widget_w, gxg_gtk_menu_button_set_align_widget) Xen_wrap_1_arg(gxg_gtk_menu_button_get_align_widget_w, gxg_gtk_menu_button_get_align_widget) Xen_wrap_no_args(gxg_gtk_search_entry_new_w, gxg_gtk_search_entry_new) Xen_wrap_no_args(gxg_gtk_level_bar_new_w, gxg_gtk_level_bar_new) Xen_wrap_2_args(gxg_gtk_level_bar_new_for_interval_w, gxg_gtk_level_bar_new_for_interval) Xen_wrap_2_args(gxg_gtk_level_bar_set_mode_w, gxg_gtk_level_bar_set_mode) Xen_wrap_1_arg(gxg_gtk_level_bar_get_mode_w, gxg_gtk_level_bar_get_mode) Xen_wrap_2_args(gxg_gtk_level_bar_set_value_w, gxg_gtk_level_bar_set_value) Xen_wrap_1_arg(gxg_gtk_level_bar_get_value_w, gxg_gtk_level_bar_get_value) Xen_wrap_2_args(gxg_gtk_level_bar_set_min_value_w, gxg_gtk_level_bar_set_min_value) Xen_wrap_1_arg(gxg_gtk_level_bar_get_min_value_w, gxg_gtk_level_bar_get_min_value) Xen_wrap_2_args(gxg_gtk_level_bar_set_max_value_w, gxg_gtk_level_bar_set_max_value) Xen_wrap_1_arg(gxg_gtk_level_bar_get_max_value_w, gxg_gtk_level_bar_get_max_value) Xen_wrap_3_args(gxg_gtk_level_bar_add_offset_value_w, gxg_gtk_level_bar_add_offset_value) Xen_wrap_2_args(gxg_gtk_level_bar_remove_offset_value_w, gxg_gtk_level_bar_remove_offset_value) Xen_wrap_3_optional_args(gxg_gtk_level_bar_get_offset_value_w, gxg_gtk_level_bar_get_offset_value) Xen_wrap_1_arg(gxg_gtk_application_get_active_window_w, gxg_gtk_application_get_active_window) Xen_wrap_2_args(gxg_gtk_entry_set_input_purpose_w, gxg_gtk_entry_set_input_purpose) Xen_wrap_1_arg(gxg_gtk_entry_get_input_purpose_w, gxg_gtk_entry_get_input_purpose) Xen_wrap_2_args(gxg_gtk_entry_set_input_hints_w, gxg_gtk_entry_set_input_hints) Xen_wrap_1_arg(gxg_gtk_entry_get_input_hints_w, gxg_gtk_entry_get_input_hints) Xen_wrap_1_arg(gxg_gtk_menu_button_get_popup_w, gxg_gtk_menu_button_get_popup) Xen_wrap_2_args(gxg_gtk_text_view_set_input_purpose_w, gxg_gtk_text_view_set_input_purpose) Xen_wrap_1_arg(gxg_gtk_text_view_get_input_purpose_w, gxg_gtk_text_view_get_input_purpose) Xen_wrap_2_args(gxg_gtk_text_view_set_input_hints_w, gxg_gtk_text_view_set_input_hints) Xen_wrap_1_arg(gxg_gtk_text_view_get_input_hints_w, gxg_gtk_text_view_get_input_hints) Xen_wrap_2_args(gxg_gtk_entry_set_attributes_w, gxg_gtk_entry_set_attributes) Xen_wrap_1_arg(gxg_gtk_entry_get_attributes_w, gxg_gtk_entry_get_attributes) Xen_wrap_3_args(gxg_gtk_accel_label_set_accel_w, gxg_gtk_accel_label_set_accel) Xen_wrap_4_args(gxg_gtk_menu_shell_bind_model_w, gxg_gtk_menu_shell_bind_model) #endif #if GTK_CHECK_VERSION(3, 8, 0) Xen_wrap_2_args(gxg_gtk_level_bar_set_inverted_w, gxg_gtk_level_bar_set_inverted) Xen_wrap_1_arg(gxg_gtk_level_bar_get_inverted_w, gxg_gtk_level_bar_get_inverted) Xen_wrap_1_arg(gxg_gtk_widget_is_visible_w, gxg_gtk_widget_is_visible) Xen_wrap_2_args(gxg_gdk_window_set_fullscreen_mode_w, gxg_gdk_window_set_fullscreen_mode) Xen_wrap_1_arg(gxg_gdk_window_get_fullscreen_mode_w, gxg_gdk_window_get_fullscreen_mode) Xen_wrap_2_args(gxg_gtk_icon_view_set_activate_on_single_click_w, gxg_gtk_icon_view_set_activate_on_single_click) Xen_wrap_1_arg(gxg_gtk_icon_view_get_activate_on_single_click_w, gxg_gtk_icon_view_get_activate_on_single_click) Xen_wrap_1_arg(gxg_gtk_tree_view_get_activate_on_single_click_w, gxg_gtk_tree_view_get_activate_on_single_click) Xen_wrap_2_args(gxg_gtk_tree_view_set_activate_on_single_click_w, gxg_gtk_tree_view_set_activate_on_single_click) Xen_wrap_2_args(gxg_gtk_widget_register_window_w, gxg_gtk_widget_register_window) Xen_wrap_2_args(gxg_gtk_widget_unregister_window_w, gxg_gtk_widget_unregister_window) Xen_wrap_2_args(gxg_gtk_widget_set_opacity_w, gxg_gtk_widget_set_opacity) Xen_wrap_1_arg(gxg_gtk_widget_get_opacity_w, gxg_gtk_widget_get_opacity) Xen_wrap_1_arg(gxg_pango_font_map_changed_w, gxg_pango_font_map_changed) #endif #if GTK_CHECK_VERSION(3, 10, 0) Xen_wrap_1_arg(gxg_gdk_set_allowed_backends_w, gxg_gdk_set_allowed_backends) Xen_wrap_2_args(gxg_gtk_box_set_baseline_position_w, gxg_gtk_box_set_baseline_position) Xen_wrap_1_arg(gxg_gtk_box_get_baseline_position_w, gxg_gtk_box_get_baseline_position) Xen_wrap_2_args(gxg_gtk_grid_remove_row_w, gxg_gtk_grid_remove_row) Xen_wrap_2_args(gxg_gtk_grid_remove_column_w, gxg_gtk_grid_remove_column) Xen_wrap_3_args(gxg_gtk_grid_set_row_baseline_position_w, gxg_gtk_grid_set_row_baseline_position) Xen_wrap_2_args(gxg_gtk_grid_get_row_baseline_position_w, gxg_gtk_grid_get_row_baseline_position) Xen_wrap_2_args(gxg_gtk_grid_set_baseline_row_w, gxg_gtk_grid_set_baseline_row) Xen_wrap_1_arg(gxg_gtk_grid_get_baseline_row_w, gxg_gtk_grid_get_baseline_row) Xen_wrap_3_args(gxg_gtk_widget_size_allocate_with_baseline_w, gxg_gtk_widget_size_allocate_with_baseline) Xen_wrap_6_optional_args(gxg_gtk_widget_get_preferred_height_and_baseline_for_width_w, gxg_gtk_widget_get_preferred_height_and_baseline_for_width) Xen_wrap_1_arg(gxg_gtk_widget_get_allocated_baseline_w, gxg_gtk_widget_get_allocated_baseline) Xen_wrap_1_arg(gxg_gtk_widget_get_valign_with_baseline_w, gxg_gtk_widget_get_valign_with_baseline) Xen_wrap_1_arg(gxg_gtk_widget_init_template_w, gxg_gtk_widget_init_template) Xen_wrap_2_args(gxg_gtk_window_set_titlebar_w, gxg_gtk_window_set_titlebar) Xen_wrap_no_args(gxg_gtk_places_sidebar_new_w, gxg_gtk_places_sidebar_new) Xen_wrap_1_arg(gxg_gtk_places_sidebar_get_open_flags_w, gxg_gtk_places_sidebar_get_open_flags) Xen_wrap_2_args(gxg_gtk_places_sidebar_set_open_flags_w, gxg_gtk_places_sidebar_set_open_flags) Xen_wrap_1_arg(gxg_gtk_places_sidebar_get_location_w, gxg_gtk_places_sidebar_get_location) Xen_wrap_2_args(gxg_gtk_places_sidebar_set_location_w, gxg_gtk_places_sidebar_set_location) Xen_wrap_1_arg(gxg_gtk_places_sidebar_get_show_desktop_w, gxg_gtk_places_sidebar_get_show_desktop) Xen_wrap_2_args(gxg_gtk_places_sidebar_set_show_desktop_w, gxg_gtk_places_sidebar_set_show_desktop) Xen_wrap_2_args(gxg_gtk_places_sidebar_add_shortcut_w, gxg_gtk_places_sidebar_add_shortcut) Xen_wrap_2_args(gxg_gtk_places_sidebar_remove_shortcut_w, gxg_gtk_places_sidebar_remove_shortcut) Xen_wrap_1_arg(gxg_gtk_places_sidebar_list_shortcuts_w, gxg_gtk_places_sidebar_list_shortcuts) Xen_wrap_2_args(gxg_gtk_places_sidebar_get_nth_bookmark_w, gxg_gtk_places_sidebar_get_nth_bookmark) Xen_wrap_no_args(gxg_gtk_stack_switcher_new_w, gxg_gtk_stack_switcher_new) Xen_wrap_2_args(gxg_gtk_stack_switcher_set_stack_w, gxg_gtk_stack_switcher_set_stack) Xen_wrap_1_arg(gxg_gtk_stack_switcher_get_stack_w, gxg_gtk_stack_switcher_get_stack) Xen_wrap_no_args(gxg_gtk_stack_new_w, gxg_gtk_stack_new) Xen_wrap_3_args(gxg_gtk_stack_add_named_w, gxg_gtk_stack_add_named) Xen_wrap_4_args(gxg_gtk_stack_add_titled_w, gxg_gtk_stack_add_titled) Xen_wrap_2_args(gxg_gtk_stack_set_visible_child_w, gxg_gtk_stack_set_visible_child) Xen_wrap_1_arg(gxg_gtk_stack_get_visible_child_w, gxg_gtk_stack_get_visible_child) Xen_wrap_2_args(gxg_gtk_stack_set_visible_child_name_w, gxg_gtk_stack_set_visible_child_name) Xen_wrap_1_arg(gxg_gtk_stack_get_visible_child_name_w, gxg_gtk_stack_get_visible_child_name) Xen_wrap_3_args(gxg_gtk_stack_set_visible_child_full_w, gxg_gtk_stack_set_visible_child_full) Xen_wrap_2_args(gxg_gtk_stack_set_homogeneous_w, gxg_gtk_stack_set_homogeneous) Xen_wrap_1_arg(gxg_gtk_stack_get_homogeneous_w, gxg_gtk_stack_get_homogeneous) Xen_wrap_2_args(gxg_gtk_stack_set_transition_duration_w, gxg_gtk_stack_set_transition_duration) Xen_wrap_1_arg(gxg_gtk_stack_get_transition_duration_w, gxg_gtk_stack_get_transition_duration) Xen_wrap_2_args(gxg_gtk_stack_set_transition_type_w, gxg_gtk_stack_set_transition_type) Xen_wrap_1_arg(gxg_gtk_stack_get_transition_type_w, gxg_gtk_stack_get_transition_type) Xen_wrap_no_args(gxg_gtk_revealer_new_w, gxg_gtk_revealer_new) Xen_wrap_1_arg(gxg_gtk_revealer_get_reveal_child_w, gxg_gtk_revealer_get_reveal_child) Xen_wrap_2_args(gxg_gtk_revealer_set_reveal_child_w, gxg_gtk_revealer_set_reveal_child) Xen_wrap_1_arg(gxg_gtk_revealer_get_child_revealed_w, gxg_gtk_revealer_get_child_revealed) Xen_wrap_1_arg(gxg_gtk_revealer_get_transition_duration_w, gxg_gtk_revealer_get_transition_duration) Xen_wrap_2_args(gxg_gtk_revealer_set_transition_duration_w, gxg_gtk_revealer_set_transition_duration) Xen_wrap_2_args(gxg_gtk_revealer_set_transition_type_w, gxg_gtk_revealer_set_transition_type) Xen_wrap_1_arg(gxg_gtk_revealer_get_transition_type_w, gxg_gtk_revealer_get_transition_type) Xen_wrap_no_args(gxg_gtk_header_bar_new_w, gxg_gtk_header_bar_new) Xen_wrap_2_args(gxg_gtk_header_bar_set_title_w, gxg_gtk_header_bar_set_title) Xen_wrap_1_arg(gxg_gtk_header_bar_get_title_w, gxg_gtk_header_bar_get_title) Xen_wrap_2_args(gxg_gtk_header_bar_set_subtitle_w, gxg_gtk_header_bar_set_subtitle) Xen_wrap_1_arg(gxg_gtk_header_bar_get_subtitle_w, gxg_gtk_header_bar_get_subtitle) Xen_wrap_2_args(gxg_gtk_header_bar_set_custom_title_w, gxg_gtk_header_bar_set_custom_title) Xen_wrap_1_arg(gxg_gtk_header_bar_get_custom_title_w, gxg_gtk_header_bar_get_custom_title) Xen_wrap_2_args(gxg_gtk_header_bar_pack_start_w, gxg_gtk_header_bar_pack_start) Xen_wrap_2_args(gxg_gtk_header_bar_pack_end_w, gxg_gtk_header_bar_pack_end) Xen_wrap_no_args(gxg_gtk_list_box_row_new_w, gxg_gtk_list_box_row_new) Xen_wrap_1_arg(gxg_gtk_list_box_row_get_header_w, gxg_gtk_list_box_row_get_header) Xen_wrap_2_args(gxg_gtk_list_box_row_set_header_w, gxg_gtk_list_box_row_set_header) Xen_wrap_1_arg(gxg_gtk_list_box_row_changed_w, gxg_gtk_list_box_row_changed) Xen_wrap_1_arg(gxg_gtk_list_box_get_selected_row_w, gxg_gtk_list_box_get_selected_row) Xen_wrap_2_args(gxg_gtk_list_box_get_row_at_index_w, gxg_gtk_list_box_get_row_at_index) Xen_wrap_2_args(gxg_gtk_list_box_get_row_at_y_w, gxg_gtk_list_box_get_row_at_y) Xen_wrap_2_args(gxg_gtk_list_box_select_row_w, gxg_gtk_list_box_select_row) Xen_wrap_2_args(gxg_gtk_list_box_set_placeholder_w, gxg_gtk_list_box_set_placeholder) Xen_wrap_2_args(gxg_gtk_list_box_set_adjustment_w, gxg_gtk_list_box_set_adjustment) Xen_wrap_1_arg(gxg_gtk_list_box_get_adjustment_w, gxg_gtk_list_box_get_adjustment) Xen_wrap_2_args(gxg_gtk_list_box_set_selection_mode_w, gxg_gtk_list_box_set_selection_mode) Xen_wrap_1_arg(gxg_gtk_list_box_get_selection_mode_w, gxg_gtk_list_box_get_selection_mode) Xen_wrap_1_arg(gxg_gtk_list_box_invalidate_filter_w, gxg_gtk_list_box_invalidate_filter) Xen_wrap_1_arg(gxg_gtk_list_box_invalidate_sort_w, gxg_gtk_list_box_invalidate_sort) Xen_wrap_1_arg(gxg_gtk_list_box_invalidate_headers_w, gxg_gtk_list_box_invalidate_headers) Xen_wrap_2_args(gxg_gtk_list_box_set_activate_on_single_click_w, gxg_gtk_list_box_set_activate_on_single_click) Xen_wrap_1_arg(gxg_gtk_list_box_get_activate_on_single_click_w, gxg_gtk_list_box_get_activate_on_single_click) Xen_wrap_1_arg(gxg_gtk_list_box_drag_unhighlight_row_w, gxg_gtk_list_box_drag_unhighlight_row) Xen_wrap_2_args(gxg_gtk_list_box_drag_highlight_row_w, gxg_gtk_list_box_drag_highlight_row) Xen_wrap_no_args(gxg_gtk_list_box_new_w, gxg_gtk_list_box_new) Xen_wrap_no_args(gxg_gtk_search_bar_new_w, gxg_gtk_search_bar_new) Xen_wrap_2_args(gxg_gtk_search_bar_connect_entry_w, gxg_gtk_search_bar_connect_entry) Xen_wrap_1_arg(gxg_gtk_search_bar_get_search_mode_w, gxg_gtk_search_bar_get_search_mode) Xen_wrap_2_args(gxg_gtk_search_bar_set_search_mode_w, gxg_gtk_search_bar_set_search_mode) Xen_wrap_1_arg(gxg_gtk_search_bar_get_show_close_button_w, gxg_gtk_search_bar_get_show_close_button) Xen_wrap_2_args(gxg_gtk_search_bar_set_show_close_button_w, gxg_gtk_search_bar_set_show_close_button) Xen_wrap_2_args(gxg_gtk_search_bar_handle_event_w, gxg_gtk_search_bar_handle_event) Xen_wrap_1_arg(gxg_gtk_file_chooser_get_current_name_w, gxg_gtk_file_chooser_get_current_name) Xen_wrap_3_args(gxg_gdk_cairo_surface_create_from_pixbuf_w, gxg_gdk_cairo_surface_create_from_pixbuf) Xen_wrap_4_optional_args(gxg_gdk_device_get_position_double_w, gxg_gdk_device_get_position_double) Xen_wrap_3_optional_args(gxg_gdk_device_get_window_at_position_double_w, gxg_gdk_device_get_window_at_position_double) Xen_wrap_2_args(gxg_gdk_screen_get_monitor_scale_factor_w, gxg_gdk_screen_get_monitor_scale_factor) Xen_wrap_1_arg(gxg_gdk_window_get_scale_factor_w, gxg_gdk_window_get_scale_factor) Xen_wrap_5_optional_args(gxg_gdk_window_get_device_position_double_w, gxg_gdk_window_get_device_position_double) Xen_wrap_5_args(gxg_gdk_window_create_similar_image_surface_w, gxg_gdk_window_create_similar_image_surface) Xen_wrap_5_args(gxg_gtk_icon_theme_lookup_icon_for_scale_w, gxg_gtk_icon_theme_lookup_icon_for_scale) Xen_wrap_6_optional_args(gxg_gtk_icon_theme_load_icon_for_scale_w, gxg_gtk_icon_theme_load_icon_for_scale) Xen_wrap_7_optional_args(gxg_gtk_icon_theme_load_surface_w, gxg_gtk_icon_theme_load_surface) Xen_wrap_5_args(gxg_gtk_icon_theme_lookup_by_gicon_for_scale_w, gxg_gtk_icon_theme_lookup_by_gicon_for_scale) Xen_wrap_1_arg(gxg_gtk_icon_info_get_base_scale_w, gxg_gtk_icon_info_get_base_scale) Xen_wrap_3_optional_args(gxg_gtk_icon_info_load_surface_w, gxg_gtk_icon_info_load_surface) Xen_wrap_1_arg(gxg_gtk_image_new_from_surface_w, gxg_gtk_image_new_from_surface) Xen_wrap_2_args(gxg_gtk_image_set_from_surface_w, gxg_gtk_image_set_from_surface) Xen_wrap_1_arg(gxg_gtk_list_box_row_get_index_w, gxg_gtk_list_box_row_get_index) Xen_wrap_1_arg(gxg_gtk_widget_get_scale_factor_w, gxg_gtk_widget_get_scale_factor) Xen_wrap_1_arg(gxg_gtk_window_close_w, gxg_gtk_window_close) Xen_wrap_2_args(gxg_gtk_info_bar_set_show_close_button_w, gxg_gtk_info_bar_set_show_close_button) Xen_wrap_1_arg(gxg_gtk_info_bar_get_show_close_button_w, gxg_gtk_info_bar_get_show_close_button) Xen_wrap_5_args(gxg_gtk_tree_model_rows_reordered_with_length_w, gxg_gtk_tree_model_rows_reordered_with_length) Xen_wrap_4_args(gxg_gdk_cursor_new_from_surface_w, gxg_gdk_cursor_new_from_surface) Xen_wrap_3_optional_args(gxg_gdk_cursor_get_surface_w, gxg_gdk_cursor_get_surface) Xen_wrap_1_arg(gxg_gdk_event_get_event_type_w, gxg_gdk_event_get_event_type) Xen_wrap_2_args(gxg_gtk_entry_set_tabs_w, gxg_gtk_entry_set_tabs) Xen_wrap_1_arg(gxg_gtk_entry_get_tabs_w, gxg_gtk_entry_get_tabs) Xen_wrap_1_arg(gxg_gtk_header_bar_get_show_close_button_w, gxg_gtk_header_bar_get_show_close_button) Xen_wrap_2_args(gxg_gtk_header_bar_set_show_close_button_w, gxg_gtk_header_bar_set_show_close_button) Xen_wrap_2_args(gxg_gtk_list_box_prepend_w, gxg_gtk_list_box_prepend) Xen_wrap_3_args(gxg_gtk_list_box_insert_w, gxg_gtk_list_box_insert) Xen_wrap_2_args(gxg_gdk_window_set_opaque_region_w, gxg_gdk_window_set_opaque_region) Xen_wrap_2_args(gxg_gtk_label_set_lines_w, gxg_gtk_label_set_lines) Xen_wrap_1_arg(gxg_gtk_label_get_lines_w, gxg_gtk_label_get_lines) Xen_wrap_1_arg(gxg_gdk_event_get_window_w, gxg_gdk_event_get_window) #endif #if GTK_CHECK_VERSION(3, 12, 0) Xen_wrap_no_args(gxg_gtk_flow_box_child_new_w, gxg_gtk_flow_box_child_new) Xen_wrap_1_arg(gxg_gtk_flow_box_child_get_index_w, gxg_gtk_flow_box_child_get_index) Xen_wrap_1_arg(gxg_gtk_flow_box_child_is_selected_w, gxg_gtk_flow_box_child_is_selected) Xen_wrap_1_arg(gxg_gtk_flow_box_child_changed_w, gxg_gtk_flow_box_child_changed) Xen_wrap_no_args(gxg_gtk_flow_box_new_w, gxg_gtk_flow_box_new) Xen_wrap_2_args(gxg_gtk_flow_box_set_homogeneous_w, gxg_gtk_flow_box_set_homogeneous) Xen_wrap_1_arg(gxg_gtk_flow_box_get_homogeneous_w, gxg_gtk_flow_box_get_homogeneous) Xen_wrap_2_args(gxg_gtk_flow_box_set_row_spacing_w, gxg_gtk_flow_box_set_row_spacing) Xen_wrap_1_arg(gxg_gtk_flow_box_get_row_spacing_w, gxg_gtk_flow_box_get_row_spacing) Xen_wrap_2_args(gxg_gtk_flow_box_set_column_spacing_w, gxg_gtk_flow_box_set_column_spacing) Xen_wrap_1_arg(gxg_gtk_flow_box_get_column_spacing_w, gxg_gtk_flow_box_get_column_spacing) Xen_wrap_2_args(gxg_gtk_flow_box_set_min_children_per_line_w, gxg_gtk_flow_box_set_min_children_per_line) Xen_wrap_1_arg(gxg_gtk_flow_box_get_min_children_per_line_w, gxg_gtk_flow_box_get_min_children_per_line) Xen_wrap_2_args(gxg_gtk_flow_box_set_max_children_per_line_w, gxg_gtk_flow_box_set_max_children_per_line) Xen_wrap_1_arg(gxg_gtk_flow_box_get_max_children_per_line_w, gxg_gtk_flow_box_get_max_children_per_line) Xen_wrap_2_args(gxg_gtk_flow_box_set_activate_on_single_click_w, gxg_gtk_flow_box_set_activate_on_single_click) Xen_wrap_1_arg(gxg_gtk_flow_box_get_activate_on_single_click_w, gxg_gtk_flow_box_get_activate_on_single_click) Xen_wrap_3_args(gxg_gtk_flow_box_insert_w, gxg_gtk_flow_box_insert) Xen_wrap_2_args(gxg_gtk_flow_box_get_child_at_index_w, gxg_gtk_flow_box_get_child_at_index) Xen_wrap_1_arg(gxg_gtk_flow_box_get_selected_children_w, gxg_gtk_flow_box_get_selected_children) Xen_wrap_2_args(gxg_gtk_flow_box_select_child_w, gxg_gtk_flow_box_select_child) Xen_wrap_2_args(gxg_gtk_flow_box_unselect_child_w, gxg_gtk_flow_box_unselect_child) Xen_wrap_1_arg(gxg_gtk_flow_box_select_all_w, gxg_gtk_flow_box_select_all) Xen_wrap_1_arg(gxg_gtk_flow_box_unselect_all_w, gxg_gtk_flow_box_unselect_all) Xen_wrap_2_args(gxg_gtk_flow_box_set_selection_mode_w, gxg_gtk_flow_box_set_selection_mode) Xen_wrap_1_arg(gxg_gtk_flow_box_get_selection_mode_w, gxg_gtk_flow_box_get_selection_mode) Xen_wrap_2_args(gxg_gtk_flow_box_set_hadjustment_w, gxg_gtk_flow_box_set_hadjustment) Xen_wrap_2_args(gxg_gtk_flow_box_set_vadjustment_w, gxg_gtk_flow_box_set_vadjustment) Xen_wrap_1_arg(gxg_gtk_flow_box_invalidate_filter_w, gxg_gtk_flow_box_invalidate_filter) Xen_wrap_1_arg(gxg_gtk_flow_box_invalidate_sort_w, gxg_gtk_flow_box_invalidate_sort) Xen_wrap_2_args(gxg_gdk_window_set_event_compression_w, gxg_gdk_window_set_event_compression) Xen_wrap_1_arg(gxg_gdk_window_get_event_compression_w, gxg_gdk_window_get_event_compression) Xen_wrap_2_args(gxg_gtk_places_sidebar_set_local_only_w, gxg_gtk_places_sidebar_set_local_only) Xen_wrap_1_arg(gxg_gtk_places_sidebar_get_local_only_w, gxg_gtk_places_sidebar_get_local_only) Xen_wrap_1_arg(gxg_gtk_stack_get_transition_running_w, gxg_gtk_stack_get_transition_running) Xen_wrap_1_arg(gxg_gtk_widget_get_margin_start_w, gxg_gtk_widget_get_margin_start) Xen_wrap_2_args(gxg_gtk_widget_set_margin_start_w, gxg_gtk_widget_set_margin_start) Xen_wrap_1_arg(gxg_gtk_widget_get_margin_end_w, gxg_gtk_widget_get_margin_end) Xen_wrap_2_args(gxg_gtk_widget_set_margin_end_w, gxg_gtk_widget_set_margin_end) Xen_wrap_3_optional_args(gxg_gtk_accel_label_get_accel_w, gxg_gtk_accel_label_get_accel) Xen_wrap_5_args(gxg_gdk_window_set_shadow_width_w, gxg_gdk_window_set_shadow_width) Xen_wrap_no_args(gxg_gtk_action_bar_new_w, gxg_gtk_action_bar_new) Xen_wrap_1_arg(gxg_gtk_action_bar_get_center_widget_w, gxg_gtk_action_bar_get_center_widget) Xen_wrap_2_args(gxg_gtk_action_bar_set_center_widget_w, gxg_gtk_action_bar_set_center_widget) Xen_wrap_2_args(gxg_gtk_action_bar_pack_start_w, gxg_gtk_action_bar_pack_start) Xen_wrap_2_args(gxg_gtk_action_bar_pack_end_w, gxg_gtk_action_bar_pack_end) Xen_wrap_2_args(gxg_gtk_header_bar_set_has_subtitle_w, gxg_gtk_header_bar_set_has_subtitle) Xen_wrap_1_arg(gxg_gtk_header_bar_get_has_subtitle_w, gxg_gtk_header_bar_get_has_subtitle) Xen_wrap_2_args(gxg_gtk_header_bar_set_decoration_layout_w, gxg_gtk_header_bar_set_decoration_layout) Xen_wrap_1_arg(gxg_gtk_header_bar_get_decoration_layout_w, gxg_gtk_header_bar_get_decoration_layout) Xen_wrap_1_arg(gxg_gtk_icon_info_is_symbolic_w, gxg_gtk_icon_info_is_symbolic) Xen_wrap_no_args(gxg_gtk_get_locale_direction_w, gxg_gtk_get_locale_direction) Xen_wrap_1_arg(gxg_gtk_window_is_maximized_w, gxg_gtk_window_is_maximized) Xen_wrap_1_arg(gxg_gtk_dialog_get_header_bar_w, gxg_gtk_dialog_get_header_bar) Xen_wrap_1_arg(gxg_gtk_popover_new_w, gxg_gtk_popover_new) Xen_wrap_2_args(gxg_gtk_popover_set_relative_to_w, gxg_gtk_popover_set_relative_to) Xen_wrap_1_arg(gxg_gtk_popover_get_relative_to_w, gxg_gtk_popover_get_relative_to) Xen_wrap_2_args(gxg_gtk_popover_set_position_w, gxg_gtk_popover_set_position) Xen_wrap_1_arg(gxg_gtk_popover_get_position_w, gxg_gtk_popover_get_position) Xen_wrap_2_args(gxg_gtk_popover_set_modal_w, gxg_gtk_popover_set_modal) Xen_wrap_1_arg(gxg_gtk_popover_get_modal_w, gxg_gtk_popover_get_modal) Xen_wrap_2_args(gxg_gtk_box_set_center_widget_w, gxg_gtk_box_set_center_widget) Xen_wrap_1_arg(gxg_gtk_box_get_center_widget_w, gxg_gtk_box_get_center_widget) Xen_wrap_2_args(gxg_gtk_entry_set_max_width_chars_w, gxg_gtk_entry_set_max_width_chars) Xen_wrap_1_arg(gxg_gtk_entry_get_max_width_chars_w, gxg_gtk_entry_get_max_width_chars) Xen_wrap_1_arg(gxg_gdk_device_get_last_event_window_w, gxg_gdk_device_get_last_event_window) #endif #if GTK_CHECK_VERSION(3, 14, 0) Xen_wrap_1_arg(gxg_gtk_list_box_row_is_selected_w, gxg_gtk_list_box_row_is_selected) Xen_wrap_2_args(gxg_gtk_list_box_unselect_row_w, gxg_gtk_list_box_unselect_row) Xen_wrap_1_arg(gxg_gtk_list_box_select_all_w, gxg_gtk_list_box_select_all) Xen_wrap_1_arg(gxg_gtk_list_box_unselect_all_w, gxg_gtk_list_box_unselect_all) Xen_wrap_1_arg(gxg_gtk_places_sidebar_get_show_enter_location_w, gxg_gtk_places_sidebar_get_show_enter_location) Xen_wrap_2_args(gxg_gtk_places_sidebar_set_show_enter_location_w, gxg_gtk_places_sidebar_set_show_enter_location) Xen_wrap_2_args(gxg_gtk_switch_set_state_w, gxg_gtk_switch_set_state) Xen_wrap_1_arg(gxg_gtk_switch_get_state_w, gxg_gtk_switch_get_state) Xen_wrap_2_args(gxg_gdk_window_show_window_menu_w, gxg_gdk_window_show_window_menu) Xen_wrap_2_args(gxg_gtk_widget_set_clip_w, gxg_gtk_widget_set_clip) Xen_wrap_2_args(gxg_gtk_widget_get_clip_w, gxg_gtk_widget_get_clip) Xen_wrap_1_arg(gxg_gtk_gesture_get_device_w, gxg_gtk_gesture_get_device) Xen_wrap_2_args(gxg_gtk_gesture_set_state_w, gxg_gtk_gesture_set_state) Xen_wrap_2_args(gxg_gtk_gesture_get_sequence_state_w, gxg_gtk_gesture_get_sequence_state) Xen_wrap_3_args(gxg_gtk_gesture_set_sequence_state_w, gxg_gtk_gesture_set_sequence_state) Xen_wrap_1_arg(gxg_gtk_gesture_get_sequences_w, gxg_gtk_gesture_get_sequences) Xen_wrap_1_arg(gxg_gtk_gesture_get_last_updated_sequence_w, gxg_gtk_gesture_get_last_updated_sequence) Xen_wrap_2_args(gxg_gtk_gesture_handles_sequence_w, gxg_gtk_gesture_handles_sequence) Xen_wrap_2_args(gxg_gtk_gesture_get_last_event_w, gxg_gtk_gesture_get_last_event) Xen_wrap_4_optional_args(gxg_gtk_gesture_get_point_w, gxg_gtk_gesture_get_point) Xen_wrap_2_args(gxg_gtk_gesture_get_bounding_box_w, gxg_gtk_gesture_get_bounding_box) Xen_wrap_3_optional_args(gxg_gtk_gesture_get_bounding_box_center_w, gxg_gtk_gesture_get_bounding_box_center) Xen_wrap_1_arg(gxg_gtk_gesture_is_active_w, gxg_gtk_gesture_is_active) Xen_wrap_1_arg(gxg_gtk_gesture_is_recognized_w, gxg_gtk_gesture_is_recognized) Xen_wrap_1_arg(gxg_gtk_gesture_get_window_w, gxg_gtk_gesture_get_window) Xen_wrap_2_args(gxg_gtk_gesture_set_window_w, gxg_gtk_gesture_set_window) Xen_wrap_2_args(gxg_gtk_gesture_group_w, gxg_gtk_gesture_group) Xen_wrap_1_arg(gxg_gtk_gesture_ungroup_w, gxg_gtk_gesture_ungroup) Xen_wrap_1_arg(gxg_gtk_gesture_get_group_w, gxg_gtk_gesture_get_group) Xen_wrap_2_args(gxg_gtk_gesture_is_grouped_with_w, gxg_gtk_gesture_is_grouped_with) Xen_wrap_1_arg(gxg_gtk_gesture_drag_new_w, gxg_gtk_gesture_drag_new) Xen_wrap_3_optional_args(gxg_gtk_gesture_drag_get_start_point_w, gxg_gtk_gesture_drag_get_start_point) Xen_wrap_3_optional_args(gxg_gtk_gesture_drag_get_offset_w, gxg_gtk_gesture_drag_get_offset) Xen_wrap_1_arg(gxg_gtk_gesture_long_press_new_w, gxg_gtk_gesture_long_press_new) Xen_wrap_2_args(gxg_gtk_gesture_pan_new_w, gxg_gtk_gesture_pan_new) Xen_wrap_1_arg(gxg_gtk_gesture_pan_get_orientation_w, gxg_gtk_gesture_pan_get_orientation) Xen_wrap_2_args(gxg_gtk_gesture_pan_set_orientation_w, gxg_gtk_gesture_pan_set_orientation) Xen_wrap_1_arg(gxg_gtk_gesture_multi_press_new_w, gxg_gtk_gesture_multi_press_new) Xen_wrap_2_args(gxg_gtk_gesture_multi_press_set_area_w, gxg_gtk_gesture_multi_press_set_area) Xen_wrap_2_args(gxg_gtk_gesture_multi_press_get_area_w, gxg_gtk_gesture_multi_press_get_area) Xen_wrap_1_arg(gxg_gtk_gesture_rotate_new_w, gxg_gtk_gesture_rotate_new) Xen_wrap_1_arg(gxg_gtk_gesture_rotate_get_angle_delta_w, gxg_gtk_gesture_rotate_get_angle_delta) Xen_wrap_1_arg(gxg_gtk_gesture_single_get_touch_only_w, gxg_gtk_gesture_single_get_touch_only) Xen_wrap_2_args(gxg_gtk_gesture_single_set_touch_only_w, gxg_gtk_gesture_single_set_touch_only) Xen_wrap_1_arg(gxg_gtk_gesture_single_get_exclusive_w, gxg_gtk_gesture_single_get_exclusive) Xen_wrap_2_args(gxg_gtk_gesture_single_set_exclusive_w, gxg_gtk_gesture_single_set_exclusive) Xen_wrap_1_arg(gxg_gtk_gesture_single_get_button_w, gxg_gtk_gesture_single_get_button) Xen_wrap_2_args(gxg_gtk_gesture_single_set_button_w, gxg_gtk_gesture_single_set_button) Xen_wrap_1_arg(gxg_gtk_gesture_single_get_current_button_w, gxg_gtk_gesture_single_get_current_button) Xen_wrap_1_arg(gxg_gtk_gesture_single_get_current_sequence_w, gxg_gtk_gesture_single_get_current_sequence) Xen_wrap_1_arg(gxg_gtk_gesture_swipe_new_w, gxg_gtk_gesture_swipe_new) Xen_wrap_3_optional_args(gxg_gtk_gesture_swipe_get_velocity_w, gxg_gtk_gesture_swipe_get_velocity) Xen_wrap_1_arg(gxg_gtk_gesture_zoom_new_w, gxg_gtk_gesture_zoom_new) Xen_wrap_1_arg(gxg_gtk_gesture_zoom_get_scale_delta_w, gxg_gtk_gesture_zoom_get_scale_delta) Xen_wrap_1_arg(gxg_gtk_event_controller_get_widget_w, gxg_gtk_event_controller_get_widget) Xen_wrap_2_args(gxg_gtk_event_controller_handle_event_w, gxg_gtk_event_controller_handle_event) Xen_wrap_1_arg(gxg_gtk_event_controller_reset_w, gxg_gtk_event_controller_reset) Xen_wrap_1_arg(gxg_gtk_event_controller_get_propagation_phase_w, gxg_gtk_event_controller_get_propagation_phase) Xen_wrap_2_args(gxg_gtk_event_controller_set_propagation_phase_w, gxg_gtk_event_controller_set_propagation_phase) Xen_wrap_2_args(gxg_gtk_icon_theme_add_resource_path_w, gxg_gtk_icon_theme_add_resource_path) Xen_wrap_2_args(gxg_gtk_list_box_row_set_activatable_w, gxg_gtk_list_box_row_set_activatable) Xen_wrap_1_arg(gxg_gtk_list_box_row_get_activatable_w, gxg_gtk_list_box_row_get_activatable) Xen_wrap_2_args(gxg_gtk_list_box_row_set_selectable_w, gxg_gtk_list_box_row_set_selectable) Xen_wrap_1_arg(gxg_gtk_list_box_row_get_selectable_w, gxg_gtk_list_box_row_get_selectable) Xen_wrap_2_args(gxg_gtk_widget_path_iter_get_state_w, gxg_gtk_widget_path_iter_get_state) Xen_wrap_3_args(gxg_gtk_widget_path_iter_set_state_w, gxg_gtk_widget_path_iter_set_state) #endif #if GTK_CHECK_VERSION(3, 16, 0) Xen_wrap_any_args(gxg_gdk_cairo_draw_from_gl_w, gxg_gdk_cairo_draw_from_gl) Xen_wrap_2_args(gxg_gdk_window_mark_paint_from_clip_w, gxg_gdk_window_mark_paint_from_clip) Xen_wrap_2_args(gxg_gtk_label_set_xalign_w, gxg_gtk_label_set_xalign) Xen_wrap_1_arg(gxg_gtk_label_get_xalign_w, gxg_gtk_label_get_xalign) Xen_wrap_2_args(gxg_gtk_label_set_yalign_w, gxg_gtk_label_set_yalign) Xen_wrap_1_arg(gxg_gtk_label_get_yalign_w, gxg_gtk_label_get_yalign) Xen_wrap_2_args(gxg_gtk_paned_set_wide_handle_w, gxg_gtk_paned_set_wide_handle) Xen_wrap_1_arg(gxg_gtk_paned_get_wide_handle_w, gxg_gtk_paned_get_wide_handle) Xen_wrap_2_args(gxg_gtk_scrolled_window_set_overlay_scrolling_w, gxg_gtk_scrolled_window_set_overlay_scrolling) Xen_wrap_1_arg(gxg_gtk_scrolled_window_get_overlay_scrolling_w, gxg_gtk_scrolled_window_get_overlay_scrolling) Xen_wrap_2_args(gxg_gtk_text_view_set_monospace_w, gxg_gtk_text_view_set_monospace) Xen_wrap_1_arg(gxg_gtk_text_view_get_monospace_w, gxg_gtk_text_view_get_monospace) Xen_wrap_1_arg(gxg_gtk_window_get_titlebar_w, gxg_gtk_window_get_titlebar) Xen_wrap_no_args(gxg_gtk_gl_area_new_w, gxg_gtk_gl_area_new) Xen_wrap_1_arg(gxg_gtk_gl_area_get_has_alpha_w, gxg_gtk_gl_area_get_has_alpha) Xen_wrap_2_args(gxg_gtk_gl_area_set_has_alpha_w, gxg_gtk_gl_area_set_has_alpha) Xen_wrap_1_arg(gxg_gtk_gl_area_get_has_depth_buffer_w, gxg_gtk_gl_area_get_has_depth_buffer) Xen_wrap_2_args(gxg_gtk_gl_area_set_has_depth_buffer_w, gxg_gtk_gl_area_set_has_depth_buffer) Xen_wrap_1_arg(gxg_gtk_gl_area_get_context_w, gxg_gtk_gl_area_get_context) Xen_wrap_1_arg(gxg_gtk_gl_area_make_current_w, gxg_gtk_gl_area_make_current) Xen_wrap_6_args(gxg_gtk_render_check_w, gxg_gtk_render_check) Xen_wrap_6_args(gxg_gtk_render_option_w, gxg_gtk_render_option) Xen_wrap_6_args(gxg_gtk_render_arrow_w, gxg_gtk_render_arrow) Xen_wrap_6_args(gxg_gtk_render_background_w, gxg_gtk_render_background) Xen_wrap_6_args(gxg_gtk_render_frame_w, gxg_gtk_render_frame) Xen_wrap_6_args(gxg_gtk_render_expander_w, gxg_gtk_render_expander) Xen_wrap_6_args(gxg_gtk_render_focus_w, gxg_gtk_render_focus) Xen_wrap_5_args(gxg_gtk_render_layout_w, gxg_gtk_render_layout) Xen_wrap_6_args(gxg_gtk_render_line_w, gxg_gtk_render_line) Xen_wrap_7_args(gxg_gtk_render_slider_w, gxg_gtk_render_slider) Xen_wrap_any_args(gxg_gtk_render_frame_gap_w, gxg_gtk_render_frame_gap) Xen_wrap_7_args(gxg_gtk_render_extension_w, gxg_gtk_render_extension) Xen_wrap_6_args(gxg_gtk_render_handle_w, gxg_gtk_render_handle) Xen_wrap_6_args(gxg_gtk_render_activity_w, gxg_gtk_render_activity) Xen_wrap_5_args(gxg_gtk_render_icon_w, gxg_gtk_render_icon) Xen_wrap_5_args(gxg_gtk_render_icon_surface_w, gxg_gtk_render_icon_surface) Xen_wrap_1_arg(gxg_gdk_gl_context_get_window_w, gxg_gdk_gl_context_get_window) Xen_wrap_1_arg(gxg_gdk_gl_context_make_current_w, gxg_gdk_gl_context_make_current) Xen_wrap_no_args(gxg_gdk_gl_context_get_current_w, gxg_gdk_gl_context_get_current) Xen_wrap_no_args(gxg_gdk_gl_context_clear_current_w, gxg_gdk_gl_context_clear_current) Xen_wrap_2_args(gxg_gtk_stack_set_hhomogeneous_w, gxg_gtk_stack_set_hhomogeneous) Xen_wrap_1_arg(gxg_gtk_stack_get_hhomogeneous_w, gxg_gtk_stack_get_hhomogeneous) Xen_wrap_2_args(gxg_gtk_stack_set_vhomogeneous_w, gxg_gtk_stack_set_vhomogeneous) Xen_wrap_1_arg(gxg_gtk_stack_get_vhomogeneous_w, gxg_gtk_stack_get_vhomogeneous) Xen_wrap_1_arg(gxg_gdk_gl_context_get_display_w, gxg_gdk_gl_context_get_display) Xen_wrap_1_arg(gxg_gtk_gl_area_get_has_stencil_buffer_w, gxg_gtk_gl_area_get_has_stencil_buffer) Xen_wrap_2_args(gxg_gtk_gl_area_set_has_stencil_buffer_w, gxg_gtk_gl_area_set_has_stencil_buffer) Xen_wrap_1_arg(gxg_gtk_gl_area_get_auto_render_w, gxg_gtk_gl_area_get_auto_render) Xen_wrap_2_args(gxg_gtk_gl_area_set_auto_render_w, gxg_gtk_gl_area_set_auto_render) Xen_wrap_1_arg(gxg_gtk_gl_area_queue_render_w, gxg_gtk_gl_area_queue_render) Xen_wrap_1_arg(gxg_gtk_gl_area_attach_buffers_w, gxg_gtk_gl_area_attach_buffers) Xen_wrap_1_arg(gxg_gtk_gl_area_get_error_w, gxg_gtk_gl_area_get_error) Xen_wrap_no_args(gxg_gtk_popover_menu_new_w, gxg_gtk_popover_menu_new) Xen_wrap_2_args(gxg_gtk_popover_menu_open_submenu_w, gxg_gtk_popover_menu_open_submenu) Xen_wrap_1_arg(gxg_gtk_entry_grab_focus_without_selecting_w, gxg_gtk_entry_grab_focus_without_selecting) Xen_wrap_2_args(gxg_gtk_scrollable_get_border_w, gxg_gtk_scrollable_get_border) Xen_wrap_4_args(gxg_gtk_text_buffer_insert_markup_w, gxg_gtk_text_buffer_insert_markup) Xen_wrap_1_arg(gxg_gdk_device_get_vendor_id_w, gxg_gdk_device_get_vendor_id) Xen_wrap_1_arg(gxg_gdk_device_get_product_id_w, gxg_gdk_device_get_product_id) Xen_wrap_1_arg(gxg_gdk_gl_context_get_shared_context_w, gxg_gdk_gl_context_get_shared_context) Xen_wrap_3_args(gxg_gdk_gl_context_set_required_version_w, gxg_gdk_gl_context_set_required_version) Xen_wrap_3_optional_args(gxg_gdk_gl_context_get_required_version_w, gxg_gdk_gl_context_get_required_version) Xen_wrap_2_args(gxg_gdk_gl_context_set_debug_enabled_w, gxg_gdk_gl_context_set_debug_enabled) Xen_wrap_1_arg(gxg_gdk_gl_context_get_debug_enabled_w, gxg_gdk_gl_context_get_debug_enabled) Xen_wrap_2_args(gxg_gdk_gl_context_set_forward_compatible_w, gxg_gdk_gl_context_set_forward_compatible) Xen_wrap_1_arg(gxg_gdk_gl_context_get_forward_compatible_w, gxg_gdk_gl_context_get_forward_compatible) Xen_wrap_2_optional_args(gxg_gdk_gl_context_realize_w, gxg_gdk_gl_context_realize) Xen_wrap_1_arg(gxg_gtk_clipboard_get_default_w, gxg_gtk_clipboard_get_default) Xen_wrap_1_arg(gxg_gtk_drag_cancel_w, gxg_gtk_drag_cancel) Xen_wrap_2_args(gxg_gtk_search_entry_handle_event_w, gxg_gtk_search_entry_handle_event) Xen_wrap_3_optional_args(gxg_gdk_gl_context_get_version_w, gxg_gdk_gl_context_get_version) Xen_wrap_3_args(gxg_gtk_gl_area_set_required_version_w, gxg_gtk_gl_area_set_required_version) Xen_wrap_3_optional_args(gxg_gtk_gl_area_get_required_version_w, gxg_gtk_gl_area_get_required_version) Xen_wrap_2_args(gxg_gtk_notebook_detach_tab_w, gxg_gtk_notebook_detach_tab) Xen_wrap_no_args(gxg_gtk_stack_sidebar_new_w, gxg_gtk_stack_sidebar_new) Xen_wrap_2_args(gxg_gtk_stack_sidebar_set_stack_w, gxg_gtk_stack_sidebar_set_stack) Xen_wrap_1_arg(gxg_gtk_stack_sidebar_get_stack_w, gxg_gtk_stack_sidebar_get_stack) Xen_wrap_2_args(gxg_gtk_popover_set_transitions_enabled_w, gxg_gtk_popover_set_transitions_enabled) Xen_wrap_1_arg(gxg_gtk_popover_get_transitions_enabled_w, gxg_gtk_popover_get_transitions_enabled) #endif #if GTK_CHECK_VERSION(3, 18, 0) Xen_wrap_1_arg(gxg_gdk_keymap_get_scroll_lock_state_w, gxg_gdk_keymap_get_scroll_lock_state) Xen_wrap_2_args(gxg_gtk_radio_menu_item_join_group_w, gxg_gtk_radio_menu_item_join_group) Xen_wrap_2_args(gxg_gtk_font_chooser_set_font_map_w, gxg_gtk_font_chooser_set_font_map) Xen_wrap_1_arg(gxg_gtk_font_chooser_get_font_map_w, gxg_gtk_font_chooser_get_font_map) Xen_wrap_2_args(gxg_gtk_popover_set_default_widget_w, gxg_gtk_popover_set_default_widget) Xen_wrap_1_arg(gxg_gtk_popover_get_default_widget_w, gxg_gtk_popover_get_default_widget) Xen_wrap_2_args(gxg_gdk_window_set_pass_through_w, gxg_gdk_window_set_pass_through) Xen_wrap_1_arg(gxg_gdk_window_get_pass_through_w, gxg_gdk_window_get_pass_through) Xen_wrap_3_args(gxg_gtk_overlay_reorder_overlay_w, gxg_gtk_overlay_reorder_overlay) Xen_wrap_2_args(gxg_gtk_overlay_get_overlay_pass_through_w, gxg_gtk_overlay_get_overlay_pass_through) Xen_wrap_3_args(gxg_gtk_overlay_set_overlay_pass_through_w, gxg_gtk_overlay_set_overlay_pass_through) Xen_wrap_1_arg(gxg_gtk_places_sidebar_get_show_recent_w, gxg_gtk_places_sidebar_get_show_recent) Xen_wrap_2_args(gxg_gtk_places_sidebar_set_show_recent_w, gxg_gtk_places_sidebar_set_show_recent) Xen_wrap_3_args(gxg_gtk_places_sidebar_set_drop_targets_visible_w, gxg_gtk_places_sidebar_set_drop_targets_visible) Xen_wrap_1_arg(gxg_gtk_places_sidebar_get_show_trash_w, gxg_gtk_places_sidebar_get_show_trash) Xen_wrap_2_args(gxg_gtk_places_sidebar_set_show_trash_w, gxg_gtk_places_sidebar_set_show_trash) Xen_wrap_2_args(gxg_gtk_places_sidebar_set_show_other_locations_w, gxg_gtk_places_sidebar_set_show_other_locations) Xen_wrap_1_arg(gxg_gtk_places_sidebar_get_show_other_locations_w, gxg_gtk_places_sidebar_get_show_other_locations) Xen_wrap_2_args(gxg_gtk_stack_set_interpolate_size_w, gxg_gtk_stack_set_interpolate_size) Xen_wrap_1_arg(gxg_gtk_stack_get_interpolate_size_w, gxg_gtk_stack_get_interpolate_size) Xen_wrap_2_args(gxg_gtk_widget_set_font_options_w, gxg_gtk_widget_set_font_options) Xen_wrap_1_arg(gxg_gtk_widget_get_font_options_w, gxg_gtk_widget_get_font_options) Xen_wrap_2_args(gxg_gtk_widget_set_font_map_w, gxg_gtk_widget_set_font_map) Xen_wrap_1_arg(gxg_gtk_widget_get_font_map_w, gxg_gtk_widget_get_font_map) Xen_wrap_2_args(gxg_gdk_window_fullscreen_on_monitor_w, gxg_gdk_window_fullscreen_on_monitor) Xen_wrap_3_args(gxg_gtk_window_fullscreen_on_monitor_w, gxg_gtk_window_fullscreen_on_monitor) Xen_wrap_2_args(gxg_gtk_text_view_set_top_margin_w, gxg_gtk_text_view_set_top_margin) Xen_wrap_1_arg(gxg_gtk_text_view_get_top_margin_w, gxg_gtk_text_view_get_top_margin) Xen_wrap_2_args(gxg_gtk_text_view_set_bottom_margin_w, gxg_gtk_text_view_set_bottom_margin) Xen_wrap_1_arg(gxg_gtk_text_view_get_bottom_margin_w, gxg_gtk_text_view_get_bottom_margin) #endif #if GTK_CHECK_VERSION(3, 20, 0) Xen_wrap_1_arg(gxg_gdk_gl_context_is_legacy_w, gxg_gdk_gl_context_is_legacy) Xen_wrap_1_arg(gxg_gdk_rectangle_equal_w, gxg_gdk_rectangle_equal) Xen_wrap_2_args(gxg_gtk_application_window_set_help_overlay_w, gxg_gtk_application_window_set_help_overlay) Xen_wrap_2_args(gxg_gtk_settings_reset_property_w, gxg_gtk_settings_reset_property) Xen_wrap_2_args(gxg_gtk_text_tag_changed_w, gxg_gtk_text_tag_changed) Xen_wrap_2_args(gxg_gtk_widget_path_iter_get_object_name_w, gxg_gtk_widget_path_iter_get_object_name) Xen_wrap_3_args(gxg_gtk_widget_path_iter_set_object_name_w, gxg_gtk_widget_path_iter_set_object_name) Xen_wrap_1_arg(gxg_gtk_widget_queue_allocate_w, gxg_gtk_widget_queue_allocate) Xen_wrap_2_args(gxg_gtk_widget_set_focus_on_click_w, gxg_gtk_widget_set_focus_on_click) Xen_wrap_1_arg(gxg_gtk_widget_get_focus_on_click_w, gxg_gtk_widget_get_focus_on_click) Xen_wrap_3_optional_args(gxg_gtk_widget_get_allocated_size_w, gxg_gtk_widget_get_allocated_size) #endif Xen_wrap_1_arg(gxg_cairo_create_w, gxg_cairo_create) Xen_wrap_no_args(gxg_cairo_version_w, gxg_cairo_version) Xen_wrap_no_args(gxg_cairo_version_string_w, gxg_cairo_version_string) Xen_wrap_1_arg(gxg_cairo_reference_w, gxg_cairo_reference) Xen_wrap_1_arg(gxg_cairo_destroy_w, gxg_cairo_destroy) Xen_wrap_1_arg(gxg_cairo_save_w, gxg_cairo_save) Xen_wrap_1_arg(gxg_cairo_restore_w, gxg_cairo_restore) Xen_wrap_1_arg(gxg_cairo_push_group_w, gxg_cairo_push_group) Xen_wrap_2_args(gxg_cairo_push_group_with_content_w, gxg_cairo_push_group_with_content) Xen_wrap_1_arg(gxg_cairo_pop_group_w, gxg_cairo_pop_group) Xen_wrap_1_arg(gxg_cairo_pop_group_to_source_w, gxg_cairo_pop_group_to_source) Xen_wrap_2_args(gxg_cairo_set_operator_w, gxg_cairo_set_operator) Xen_wrap_2_args(gxg_cairo_set_source_w, gxg_cairo_set_source) Xen_wrap_4_args(gxg_cairo_set_source_rgb_w, gxg_cairo_set_source_rgb) Xen_wrap_5_args(gxg_cairo_set_source_rgba_w, gxg_cairo_set_source_rgba) Xen_wrap_4_args(gxg_cairo_set_source_surface_w, gxg_cairo_set_source_surface) Xen_wrap_2_args(gxg_cairo_set_tolerance_w, gxg_cairo_set_tolerance) Xen_wrap_2_args(gxg_cairo_set_antialias_w, gxg_cairo_set_antialias) Xen_wrap_2_args(gxg_cairo_set_fill_rule_w, gxg_cairo_set_fill_rule) Xen_wrap_2_args(gxg_cairo_set_line_width_w, gxg_cairo_set_line_width) Xen_wrap_2_args(gxg_cairo_set_line_cap_w, gxg_cairo_set_line_cap) Xen_wrap_2_args(gxg_cairo_set_line_join_w, gxg_cairo_set_line_join) Xen_wrap_4_args(gxg_cairo_set_dash_w, gxg_cairo_set_dash) Xen_wrap_2_args(gxg_cairo_set_miter_limit_w, gxg_cairo_set_miter_limit) Xen_wrap_3_args(gxg_cairo_translate_w, gxg_cairo_translate) Xen_wrap_3_args(gxg_cairo_scale_w, gxg_cairo_scale) Xen_wrap_2_args(gxg_cairo_rotate_w, gxg_cairo_rotate) Xen_wrap_2_args(gxg_cairo_transform_w, gxg_cairo_transform) Xen_wrap_2_args(gxg_cairo_set_matrix_w, gxg_cairo_set_matrix) Xen_wrap_1_arg(gxg_cairo_identity_matrix_w, gxg_cairo_identity_matrix) Xen_wrap_3_optional_args(gxg_cairo_user_to_device_w, gxg_cairo_user_to_device) Xen_wrap_3_optional_args(gxg_cairo_user_to_device_distance_w, gxg_cairo_user_to_device_distance) Xen_wrap_3_optional_args(gxg_cairo_device_to_user_w, gxg_cairo_device_to_user) Xen_wrap_3_optional_args(gxg_cairo_device_to_user_distance_w, gxg_cairo_device_to_user_distance) Xen_wrap_1_arg(gxg_cairo_new_path_w, gxg_cairo_new_path) Xen_wrap_3_args(gxg_cairo_move_to_w, gxg_cairo_move_to) Xen_wrap_1_arg(gxg_cairo_new_sub_path_w, gxg_cairo_new_sub_path) Xen_wrap_3_args(gxg_cairo_line_to_w, gxg_cairo_line_to) Xen_wrap_7_args(gxg_cairo_curve_to_w, gxg_cairo_curve_to) Xen_wrap_6_args(gxg_cairo_arc_w, gxg_cairo_arc) Xen_wrap_6_args(gxg_cairo_arc_negative_w, gxg_cairo_arc_negative) Xen_wrap_3_args(gxg_cairo_rel_move_to_w, gxg_cairo_rel_move_to) Xen_wrap_3_args(gxg_cairo_rel_line_to_w, gxg_cairo_rel_line_to) Xen_wrap_7_args(gxg_cairo_rel_curve_to_w, gxg_cairo_rel_curve_to) Xen_wrap_5_args(gxg_cairo_rectangle_w, gxg_cairo_rectangle) Xen_wrap_1_arg(gxg_cairo_close_path_w, gxg_cairo_close_path) Xen_wrap_1_arg(gxg_cairo_paint_w, gxg_cairo_paint) Xen_wrap_2_args(gxg_cairo_paint_with_alpha_w, gxg_cairo_paint_with_alpha) Xen_wrap_2_args(gxg_cairo_mask_w, gxg_cairo_mask) Xen_wrap_4_args(gxg_cairo_mask_surface_w, gxg_cairo_mask_surface) Xen_wrap_1_arg(gxg_cairo_stroke_w, gxg_cairo_stroke) Xen_wrap_1_arg(gxg_cairo_stroke_preserve_w, gxg_cairo_stroke_preserve) Xen_wrap_1_arg(gxg_cairo_fill_w, gxg_cairo_fill) Xen_wrap_1_arg(gxg_cairo_fill_preserve_w, gxg_cairo_fill_preserve) Xen_wrap_1_arg(gxg_cairo_copy_page_w, gxg_cairo_copy_page) Xen_wrap_1_arg(gxg_cairo_show_page_w, gxg_cairo_show_page) Xen_wrap_3_args(gxg_cairo_in_stroke_w, gxg_cairo_in_stroke) Xen_wrap_3_args(gxg_cairo_in_fill_w, gxg_cairo_in_fill) Xen_wrap_1_arg(gxg_cairo_reset_clip_w, gxg_cairo_reset_clip) Xen_wrap_1_arg(gxg_cairo_clip_w, gxg_cairo_clip) Xen_wrap_1_arg(gxg_cairo_clip_preserve_w, gxg_cairo_clip_preserve) Xen_wrap_no_args(gxg_cairo_font_options_create_w, gxg_cairo_font_options_create) Xen_wrap_1_arg(gxg_cairo_font_options_copy_w, gxg_cairo_font_options_copy) Xen_wrap_1_arg(gxg_cairo_font_options_destroy_w, gxg_cairo_font_options_destroy) Xen_wrap_1_arg(gxg_cairo_font_options_status_w, gxg_cairo_font_options_status) Xen_wrap_2_args(gxg_cairo_font_options_merge_w, gxg_cairo_font_options_merge) Xen_wrap_2_args(gxg_cairo_font_options_equal_w, gxg_cairo_font_options_equal) Xen_wrap_1_arg(gxg_cairo_font_options_hash_w, gxg_cairo_font_options_hash) Xen_wrap_2_args(gxg_cairo_font_options_set_antialias_w, gxg_cairo_font_options_set_antialias) Xen_wrap_1_arg(gxg_cairo_font_options_get_antialias_w, gxg_cairo_font_options_get_antialias) Xen_wrap_2_args(gxg_cairo_font_options_set_subpixel_order_w, gxg_cairo_font_options_set_subpixel_order) Xen_wrap_1_arg(gxg_cairo_font_options_get_subpixel_order_w, gxg_cairo_font_options_get_subpixel_order) Xen_wrap_2_args(gxg_cairo_font_options_set_hint_style_w, gxg_cairo_font_options_set_hint_style) Xen_wrap_1_arg(gxg_cairo_font_options_get_hint_style_w, gxg_cairo_font_options_get_hint_style) Xen_wrap_2_args(gxg_cairo_font_options_set_hint_metrics_w, gxg_cairo_font_options_set_hint_metrics) Xen_wrap_1_arg(gxg_cairo_font_options_get_hint_metrics_w, gxg_cairo_font_options_get_hint_metrics) Xen_wrap_4_args(gxg_cairo_select_font_face_w, gxg_cairo_select_font_face) Xen_wrap_2_args(gxg_cairo_set_font_size_w, gxg_cairo_set_font_size) Xen_wrap_2_args(gxg_cairo_set_font_matrix_w, gxg_cairo_set_font_matrix) Xen_wrap_2_args(gxg_cairo_get_font_matrix_w, gxg_cairo_get_font_matrix) Xen_wrap_2_args(gxg_cairo_set_font_options_w, gxg_cairo_set_font_options) Xen_wrap_2_args(gxg_cairo_get_font_options_w, gxg_cairo_get_font_options) Xen_wrap_2_args(gxg_cairo_set_scaled_font_w, gxg_cairo_set_scaled_font) Xen_wrap_2_args(gxg_cairo_show_text_w, gxg_cairo_show_text) Xen_wrap_3_args(gxg_cairo_show_glyphs_w, gxg_cairo_show_glyphs) Xen_wrap_1_arg(gxg_cairo_get_font_face_w, gxg_cairo_get_font_face) Xen_wrap_2_args(gxg_cairo_font_extents_w, gxg_cairo_font_extents) Xen_wrap_2_args(gxg_cairo_set_font_face_w, gxg_cairo_set_font_face) Xen_wrap_3_args(gxg_cairo_text_extents_w, gxg_cairo_text_extents) Xen_wrap_4_args(gxg_cairo_glyph_extents_w, gxg_cairo_glyph_extents) Xen_wrap_2_args(gxg_cairo_text_path_w, gxg_cairo_text_path) Xen_wrap_3_args(gxg_cairo_glyph_path_w, gxg_cairo_glyph_path) Xen_wrap_1_arg(gxg_cairo_font_face_reference_w, gxg_cairo_font_face_reference) Xen_wrap_1_arg(gxg_cairo_font_face_destroy_w, gxg_cairo_font_face_destroy) Xen_wrap_1_arg(gxg_cairo_font_face_status_w, gxg_cairo_font_face_status) Xen_wrap_2_args(gxg_cairo_font_face_get_user_data_w, gxg_cairo_font_face_get_user_data) Xen_wrap_4_args(gxg_cairo_font_face_set_user_data_w, gxg_cairo_font_face_set_user_data) Xen_wrap_4_args(gxg_cairo_scaled_font_create_w, gxg_cairo_scaled_font_create) Xen_wrap_1_arg(gxg_cairo_scaled_font_reference_w, gxg_cairo_scaled_font_reference) Xen_wrap_1_arg(gxg_cairo_scaled_font_destroy_w, gxg_cairo_scaled_font_destroy) Xen_wrap_1_arg(gxg_cairo_scaled_font_status_w, gxg_cairo_scaled_font_status) Xen_wrap_2_args(gxg_cairo_scaled_font_extents_w, gxg_cairo_scaled_font_extents) Xen_wrap_3_args(gxg_cairo_scaled_font_text_extents_w, gxg_cairo_scaled_font_text_extents) Xen_wrap_4_args(gxg_cairo_scaled_font_glyph_extents_w, gxg_cairo_scaled_font_glyph_extents) Xen_wrap_1_arg(gxg_cairo_scaled_font_get_font_face_w, gxg_cairo_scaled_font_get_font_face) Xen_wrap_2_args(gxg_cairo_scaled_font_get_font_matrix_w, gxg_cairo_scaled_font_get_font_matrix) Xen_wrap_2_args(gxg_cairo_scaled_font_get_ctm_w, gxg_cairo_scaled_font_get_ctm) Xen_wrap_2_args(gxg_cairo_scaled_font_get_font_options_w, gxg_cairo_scaled_font_get_font_options) Xen_wrap_1_arg(gxg_cairo_get_operator_w, gxg_cairo_get_operator) Xen_wrap_1_arg(gxg_cairo_get_source_w, gxg_cairo_get_source) Xen_wrap_1_arg(gxg_cairo_get_tolerance_w, gxg_cairo_get_tolerance) Xen_wrap_1_arg(gxg_cairo_get_antialias_w, gxg_cairo_get_antialias) Xen_wrap_3_optional_args(gxg_cairo_get_current_point_w, gxg_cairo_get_current_point) Xen_wrap_1_arg(gxg_cairo_get_fill_rule_w, gxg_cairo_get_fill_rule) Xen_wrap_1_arg(gxg_cairo_get_line_width_w, gxg_cairo_get_line_width) Xen_wrap_1_arg(gxg_cairo_get_line_cap_w, gxg_cairo_get_line_cap) Xen_wrap_1_arg(gxg_cairo_get_line_join_w, gxg_cairo_get_line_join) Xen_wrap_1_arg(gxg_cairo_get_miter_limit_w, gxg_cairo_get_miter_limit) Xen_wrap_2_args(gxg_cairo_get_matrix_w, gxg_cairo_get_matrix) Xen_wrap_1_arg(gxg_cairo_get_target_w, gxg_cairo_get_target) Xen_wrap_1_arg(gxg_cairo_get_group_target_w, gxg_cairo_get_group_target) Xen_wrap_1_arg(gxg_cairo_copy_path_w, gxg_cairo_copy_path) Xen_wrap_1_arg(gxg_cairo_copy_path_flat_w, gxg_cairo_copy_path_flat) Xen_wrap_2_args(gxg_cairo_append_path_w, gxg_cairo_append_path) Xen_wrap_1_arg(gxg_cairo_path_destroy_w, gxg_cairo_path_destroy) Xen_wrap_1_arg(gxg_cairo_status_w, gxg_cairo_status) Xen_wrap_1_arg(gxg_cairo_status_to_string_w, gxg_cairo_status_to_string) Xen_wrap_4_args(gxg_cairo_surface_create_similar_w, gxg_cairo_surface_create_similar) Xen_wrap_1_arg(gxg_cairo_surface_reference_w, gxg_cairo_surface_reference) Xen_wrap_1_arg(gxg_cairo_surface_finish_w, gxg_cairo_surface_finish) Xen_wrap_1_arg(gxg_cairo_surface_destroy_w, gxg_cairo_surface_destroy) Xen_wrap_1_arg(gxg_cairo_surface_status_w, gxg_cairo_surface_status) Xen_wrap_1_arg(gxg_cairo_surface_get_content_w, gxg_cairo_surface_get_content) Xen_wrap_2_args(gxg_cairo_surface_get_user_data_w, gxg_cairo_surface_get_user_data) Xen_wrap_4_args(gxg_cairo_surface_set_user_data_w, gxg_cairo_surface_set_user_data) Xen_wrap_2_args(gxg_cairo_surface_get_font_options_w, gxg_cairo_surface_get_font_options) Xen_wrap_1_arg(gxg_cairo_surface_flush_w, gxg_cairo_surface_flush) Xen_wrap_1_arg(gxg_cairo_surface_mark_dirty_w, gxg_cairo_surface_mark_dirty) Xen_wrap_5_args(gxg_cairo_surface_mark_dirty_rectangle_w, gxg_cairo_surface_mark_dirty_rectangle) Xen_wrap_3_args(gxg_cairo_surface_set_device_offset_w, gxg_cairo_surface_set_device_offset) Xen_wrap_3_optional_args(gxg_cairo_surface_get_device_offset_w, gxg_cairo_surface_get_device_offset) Xen_wrap_3_args(gxg_cairo_surface_set_fallback_resolution_w, gxg_cairo_surface_set_fallback_resolution) Xen_wrap_3_args(gxg_cairo_image_surface_create_w, gxg_cairo_image_surface_create) Xen_wrap_5_args(gxg_cairo_image_surface_create_for_data_w, gxg_cairo_image_surface_create_for_data) Xen_wrap_1_arg(gxg_cairo_image_surface_get_data_w, gxg_cairo_image_surface_get_data) Xen_wrap_1_arg(gxg_cairo_image_surface_get_format_w, gxg_cairo_image_surface_get_format) Xen_wrap_1_arg(gxg_cairo_image_surface_get_width_w, gxg_cairo_image_surface_get_width) Xen_wrap_1_arg(gxg_cairo_image_surface_get_height_w, gxg_cairo_image_surface_get_height) Xen_wrap_1_arg(gxg_cairo_image_surface_get_stride_w, gxg_cairo_image_surface_get_stride) Xen_wrap_3_args(gxg_cairo_pattern_create_rgb_w, gxg_cairo_pattern_create_rgb) Xen_wrap_4_args(gxg_cairo_pattern_create_rgba_w, gxg_cairo_pattern_create_rgba) Xen_wrap_1_arg(gxg_cairo_pattern_create_for_surface_w, gxg_cairo_pattern_create_for_surface) Xen_wrap_4_args(gxg_cairo_pattern_create_linear_w, gxg_cairo_pattern_create_linear) Xen_wrap_6_args(gxg_cairo_pattern_create_radial_w, gxg_cairo_pattern_create_radial) Xen_wrap_1_arg(gxg_cairo_pattern_reference_w, gxg_cairo_pattern_reference) Xen_wrap_1_arg(gxg_cairo_pattern_destroy_w, gxg_cairo_pattern_destroy) Xen_wrap_1_arg(gxg_cairo_pattern_status_w, gxg_cairo_pattern_status) Xen_wrap_5_args(gxg_cairo_pattern_add_color_stop_rgb_w, gxg_cairo_pattern_add_color_stop_rgb) Xen_wrap_6_args(gxg_cairo_pattern_add_color_stop_rgba_w, gxg_cairo_pattern_add_color_stop_rgba) Xen_wrap_2_args(gxg_cairo_pattern_set_matrix_w, gxg_cairo_pattern_set_matrix) Xen_wrap_2_args(gxg_cairo_pattern_get_matrix_w, gxg_cairo_pattern_get_matrix) Xen_wrap_2_args(gxg_cairo_pattern_set_extend_w, gxg_cairo_pattern_set_extend) Xen_wrap_1_arg(gxg_cairo_pattern_get_extend_w, gxg_cairo_pattern_get_extend) Xen_wrap_2_args(gxg_cairo_pattern_set_filter_w, gxg_cairo_pattern_set_filter) Xen_wrap_1_arg(gxg_cairo_pattern_get_filter_w, gxg_cairo_pattern_get_filter) Xen_wrap_7_args(gxg_cairo_matrix_init_w, gxg_cairo_matrix_init) Xen_wrap_1_arg(gxg_cairo_matrix_init_identity_w, gxg_cairo_matrix_init_identity) Xen_wrap_3_args(gxg_cairo_matrix_init_translate_w, gxg_cairo_matrix_init_translate) Xen_wrap_3_args(gxg_cairo_matrix_init_scale_w, gxg_cairo_matrix_init_scale) Xen_wrap_2_args(gxg_cairo_matrix_init_rotate_w, gxg_cairo_matrix_init_rotate) Xen_wrap_3_args(gxg_cairo_matrix_translate_w, gxg_cairo_matrix_translate) Xen_wrap_3_args(gxg_cairo_matrix_scale_w, gxg_cairo_matrix_scale) Xen_wrap_2_args(gxg_cairo_matrix_rotate_w, gxg_cairo_matrix_rotate) Xen_wrap_1_arg(gxg_cairo_matrix_invert_w, gxg_cairo_matrix_invert) Xen_wrap_3_args(gxg_cairo_matrix_multiply_w, gxg_cairo_matrix_multiply) Xen_wrap_3_optional_args(gxg_cairo_matrix_transform_distance_w, gxg_cairo_matrix_transform_distance) Xen_wrap_3_optional_args(gxg_cairo_matrix_transform_point_w, gxg_cairo_matrix_transform_point) Xen_wrap_1_arg(gxg_cairo_get_reference_count_w, gxg_cairo_get_reference_count) Xen_wrap_2_args(gxg_cairo_get_user_data_w, gxg_cairo_get_user_data) Xen_wrap_4_args(gxg_cairo_set_user_data_w, gxg_cairo_set_user_data) Xen_wrap_5_optional_args(gxg_cairo_clip_extents_w, gxg_cairo_clip_extents) Xen_wrap_1_arg(gxg_cairo_copy_clip_rectangle_list_w, gxg_cairo_copy_clip_rectangle_list) Xen_wrap_1_arg(gxg_cairo_rectangle_list_destroy_w, gxg_cairo_rectangle_list_destroy) Xen_wrap_1_arg(gxg_cairo_font_face_get_reference_count_w, gxg_cairo_font_face_get_reference_count) Xen_wrap_1_arg(gxg_cairo_scaled_font_get_reference_count_w, gxg_cairo_scaled_font_get_reference_count) Xen_wrap_2_args(gxg_cairo_scaled_font_get_user_data_w, gxg_cairo_scaled_font_get_user_data) Xen_wrap_4_args(gxg_cairo_scaled_font_set_user_data_w, gxg_cairo_scaled_font_set_user_data) Xen_wrap_1_arg(gxg_cairo_get_dash_count_w, gxg_cairo_get_dash_count) Xen_wrap_3_optional_args(gxg_cairo_get_dash_w, gxg_cairo_get_dash) Xen_wrap_1_arg(gxg_cairo_surface_get_reference_count_w, gxg_cairo_surface_get_reference_count) Xen_wrap_1_arg(gxg_cairo_pattern_get_reference_count_w, gxg_cairo_pattern_get_reference_count) Xen_wrap_2_args(gxg_cairo_pattern_get_user_data_w, gxg_cairo_pattern_get_user_data) Xen_wrap_4_args(gxg_cairo_pattern_set_user_data_w, gxg_cairo_pattern_set_user_data) Xen_wrap_5_optional_args(gxg_cairo_pattern_get_rgba_w, gxg_cairo_pattern_get_rgba) Xen_wrap_2_optional_args(gxg_cairo_pattern_get_surface_w, gxg_cairo_pattern_get_surface) Xen_wrap_7_optional_args(gxg_cairo_pattern_get_color_stop_rgba_w, gxg_cairo_pattern_get_color_stop_rgba) Xen_wrap_2_optional_args(gxg_cairo_pattern_get_color_stop_count_w, gxg_cairo_pattern_get_color_stop_count) Xen_wrap_5_optional_args(gxg_cairo_pattern_get_linear_points_w, gxg_cairo_pattern_get_linear_points) Xen_wrap_7_optional_args(gxg_cairo_pattern_get_radial_circles_w, gxg_cairo_pattern_get_radial_circles) Xen_wrap_1_arg(gxg_cairo_get_scaled_font_w, gxg_cairo_get_scaled_font) Xen_wrap_5_optional_args(gxg_cairo_path_extents_w, gxg_cairo_path_extents) Xen_wrap_1_arg(gxg_cairo_has_current_point_w, gxg_cairo_has_current_point) Xen_wrap_1_arg(gxg_cairo_surface_copy_page_w, gxg_cairo_surface_copy_page) Xen_wrap_1_arg(gxg_cairo_surface_show_page_w, gxg_cairo_surface_show_page) Xen_wrap_2_args(gxg_cairo_format_stride_for_width_w, gxg_cairo_format_stride_for_width) Xen_wrap_1_arg(gxg_cairo_image_surface_create_from_png_w, gxg_cairo_image_surface_create_from_png) Xen_wrap_2_args(gxg_cairo_surface_write_to_png_w, gxg_cairo_surface_write_to_png) #if HAVE_CAIRO_1_8 Xen_wrap_1_arg(gxg_cairo_glyph_allocate_w, gxg_cairo_glyph_allocate) Xen_wrap_1_arg(gxg_cairo_glyph_free_w, gxg_cairo_glyph_free) Xen_wrap_1_arg(gxg_cairo_text_cluster_allocate_w, gxg_cairo_text_cluster_allocate) Xen_wrap_1_arg(gxg_cairo_text_cluster_free_w, gxg_cairo_text_cluster_free) Xen_wrap_any_args(gxg_cairo_show_text_glyphs_w, gxg_cairo_show_text_glyphs) Xen_wrap_any_args(gxg_cairo_scaled_font_text_to_glyphs_w, gxg_cairo_scaled_font_text_to_glyphs) Xen_wrap_2_args(gxg_cairo_scaled_font_get_scale_matrix_w, gxg_cairo_scaled_font_get_scale_matrix) Xen_wrap_3_args(gxg_cairo_toy_font_face_create_w, gxg_cairo_toy_font_face_create) Xen_wrap_1_arg(gxg_cairo_toy_font_face_get_family_w, gxg_cairo_toy_font_face_get_family) Xen_wrap_1_arg(gxg_cairo_toy_font_face_get_slant_w, gxg_cairo_toy_font_face_get_slant) Xen_wrap_1_arg(gxg_cairo_toy_font_face_get_weight_w, gxg_cairo_toy_font_face_get_weight) Xen_wrap_no_args(gxg_cairo_user_font_face_create_w, gxg_cairo_user_font_face_create) Xen_wrap_3_optional_args(gxg_cairo_surface_get_fallback_resolution_w, gxg_cairo_surface_get_fallback_resolution) Xen_wrap_1_arg(gxg_cairo_surface_has_show_text_glyphs_w, gxg_cairo_surface_has_show_text_glyphs) #endif #if HAVE_CAIRO_1_9_12 && GTK_CHECK_VERSION(3, 0, 0) Xen_wrap_3_args(gxg_cairo_in_clip_w, gxg_cairo_in_clip) Xen_wrap_1_arg(gxg_cairo_device_reference_w, gxg_cairo_device_reference) Xen_wrap_1_arg(gxg_cairo_device_status_w, gxg_cairo_device_status) Xen_wrap_1_arg(gxg_cairo_device_acquire_w, gxg_cairo_device_acquire) Xen_wrap_1_arg(gxg_cairo_device_release_w, gxg_cairo_device_release) Xen_wrap_1_arg(gxg_cairo_device_flush_w, gxg_cairo_device_flush) Xen_wrap_1_arg(gxg_cairo_device_finish_w, gxg_cairo_device_finish) Xen_wrap_1_arg(gxg_cairo_device_destroy_w, gxg_cairo_device_destroy) Xen_wrap_1_arg(gxg_cairo_device_get_reference_count_w, gxg_cairo_device_get_reference_count) Xen_wrap_2_args(gxg_cairo_device_get_user_data_w, gxg_cairo_device_get_user_data) Xen_wrap_4_args(gxg_cairo_device_set_user_data_w, gxg_cairo_device_set_user_data) Xen_wrap_5_args(gxg_cairo_surface_create_for_rectangle_w, gxg_cairo_surface_create_for_rectangle) Xen_wrap_1_arg(gxg_cairo_surface_get_device_w, gxg_cairo_surface_get_device) Xen_wrap_6_args(gxg_cairo_surface_set_mime_data_w, gxg_cairo_surface_set_mime_data) Xen_wrap_2_args(gxg_cairo_recording_surface_create_w, gxg_cairo_recording_surface_create) Xen_wrap_5_args(gxg_cairo_recording_surface_ink_extents_w, gxg_cairo_recording_surface_ink_extents) Xen_wrap_no_args(gxg_cairo_region_create_w, gxg_cairo_region_create) Xen_wrap_1_arg(gxg_cairo_region_create_rectangle_w, gxg_cairo_region_create_rectangle) Xen_wrap_2_args(gxg_cairo_region_create_rectangles_w, gxg_cairo_region_create_rectangles) Xen_wrap_1_arg(gxg_cairo_region_copy_w, gxg_cairo_region_copy) Xen_wrap_1_arg(gxg_cairo_region_reference_w, gxg_cairo_region_reference) Xen_wrap_1_arg(gxg_cairo_region_destroy_w, gxg_cairo_region_destroy) Xen_wrap_2_args(gxg_cairo_region_equal_w, gxg_cairo_region_equal) Xen_wrap_1_arg(gxg_cairo_region_status_w, gxg_cairo_region_status) Xen_wrap_2_args(gxg_cairo_region_get_extents_w, gxg_cairo_region_get_extents) Xen_wrap_1_arg(gxg_cairo_region_num_rectangles_w, gxg_cairo_region_num_rectangles) Xen_wrap_3_args(gxg_cairo_region_get_rectangle_w, gxg_cairo_region_get_rectangle) Xen_wrap_1_arg(gxg_cairo_region_is_empty_w, gxg_cairo_region_is_empty) Xen_wrap_2_args(gxg_cairo_region_contains_rectangle_w, gxg_cairo_region_contains_rectangle) Xen_wrap_3_args(gxg_cairo_region_contains_point_w, gxg_cairo_region_contains_point) Xen_wrap_3_args(gxg_cairo_region_translate_w, gxg_cairo_region_translate) Xen_wrap_2_args(gxg_cairo_region_subtract_w, gxg_cairo_region_subtract) Xen_wrap_2_args(gxg_cairo_region_subtract_rectangle_w, gxg_cairo_region_subtract_rectangle) Xen_wrap_2_args(gxg_cairo_region_intersect_w, gxg_cairo_region_intersect) Xen_wrap_2_args(gxg_cairo_region_intersect_rectangle_w, gxg_cairo_region_intersect_rectangle) Xen_wrap_2_args(gxg_cairo_region_union_w, gxg_cairo_region_union) Xen_wrap_2_args(gxg_cairo_region_union_rectangle_w, gxg_cairo_region_union_rectangle) Xen_wrap_2_args(gxg_cairo_region_xor_w, gxg_cairo_region_xor) Xen_wrap_2_args(gxg_cairo_region_xor_rectangle_w, gxg_cairo_region_xor_rectangle) #endif Xen_wrap_1_arg(gxg_GPOINTER_w, gxg_GPOINTER) Xen_wrap_2_args(c_array_to_xen_list_w, c_array_to_xen_list) Xen_wrap_2_args(xen_list_to_c_array_w, xen_list_to_c_array) Xen_wrap_1_arg(gxg_make_target_entry_w, gxg_make_target_entry) Xen_wrap_3_args(xg_object_get_w, xg_object_get) Xen_wrap_3_args(xg_object_set_w, xg_object_set) Xen_wrap_1_arg(xg_gtk_event_keyval_w, xg_gtk_event_keyval) Xen_wrap_2_optional_args(gxg_gtk_init_w, gxg_gtk_init) Xen_wrap_2_optional_args(gxg_gtk_init_check_w, gxg_gtk_init_check) Xen_wrap_1_arg(gxg_GDK_DRAG_CONTEXT_w, gxg_GDK_DRAG_CONTEXT) Xen_wrap_1_arg(gxg_GDK_DEVICE_w, gxg_GDK_DEVICE) Xen_wrap_1_arg(gxg_GDK_KEYMAP_w, gxg_GDK_KEYMAP) Xen_wrap_1_arg(gxg_GDK_VISUAL_w, gxg_GDK_VISUAL) Xen_wrap_1_arg(gxg_GDK_WINDOW_w, gxg_GDK_WINDOW) Xen_wrap_1_arg(gxg_GDK_PIXBUF_w, gxg_GDK_PIXBUF) Xen_wrap_1_arg(gxg_GDK_PIXBUF_ANIMATION_w, gxg_GDK_PIXBUF_ANIMATION) Xen_wrap_1_arg(gxg_GDK_PIXBUF_ANIMATION_ITER_w, gxg_GDK_PIXBUF_ANIMATION_ITER) Xen_wrap_1_arg(gxg_GTK_ACCEL_GROUP_w, gxg_GTK_ACCEL_GROUP) Xen_wrap_1_arg(gxg_GTK_ACCEL_LABEL_w, gxg_GTK_ACCEL_LABEL) Xen_wrap_1_arg(gxg_GTK_ACCESSIBLE_w, gxg_GTK_ACCESSIBLE) Xen_wrap_1_arg(gxg_GTK_ADJUSTMENT_w, gxg_GTK_ADJUSTMENT) Xen_wrap_1_arg(gxg_GTK_ASPECT_FRAME_w, gxg_GTK_ASPECT_FRAME) Xen_wrap_1_arg(gxg_GTK_BUTTON_BOX_w, gxg_GTK_BUTTON_BOX) Xen_wrap_1_arg(gxg_GTK_BIN_w, gxg_GTK_BIN) Xen_wrap_1_arg(gxg_GTK_BOX_w, gxg_GTK_BOX) Xen_wrap_1_arg(gxg_GTK_BUTTON_w, gxg_GTK_BUTTON) Xen_wrap_1_arg(gxg_GTK_CALENDAR_w, gxg_GTK_CALENDAR) Xen_wrap_1_arg(gxg_GTK_CELL_EDITABLE_w, gxg_GTK_CELL_EDITABLE) Xen_wrap_1_arg(gxg_GTK_CELL_RENDERER_w, gxg_GTK_CELL_RENDERER) Xen_wrap_1_arg(gxg_GTK_CELL_RENDERER_PIXBUF_w, gxg_GTK_CELL_RENDERER_PIXBUF) Xen_wrap_1_arg(gxg_GTK_CELL_RENDERER_TEXT_w, gxg_GTK_CELL_RENDERER_TEXT) Xen_wrap_1_arg(gxg_GTK_CELL_RENDERER_TOGGLE_w, gxg_GTK_CELL_RENDERER_TOGGLE) Xen_wrap_1_arg(gxg_GTK_CHECK_BUTTON_w, gxg_GTK_CHECK_BUTTON) Xen_wrap_1_arg(gxg_GTK_CHECK_MENU_ITEM_w, gxg_GTK_CHECK_MENU_ITEM) Xen_wrap_1_arg(gxg_GTK_CONTAINER_w, gxg_GTK_CONTAINER) Xen_wrap_1_arg(gxg_GTK_DIALOG_w, gxg_GTK_DIALOG) Xen_wrap_1_arg(gxg_GTK_DRAWING_AREA_w, gxg_GTK_DRAWING_AREA) Xen_wrap_1_arg(gxg_GTK_EDITABLE_w, gxg_GTK_EDITABLE) Xen_wrap_1_arg(gxg_GTK_ENTRY_w, gxg_GTK_ENTRY) Xen_wrap_1_arg(gxg_GTK_EVENT_BOX_w, gxg_GTK_EVENT_BOX) Xen_wrap_1_arg(gxg_GTK_FIXED_w, gxg_GTK_FIXED) Xen_wrap_1_arg(gxg_GTK_FRAME_w, gxg_GTK_FRAME) Xen_wrap_1_arg(gxg_GTK_IMAGE_w, gxg_GTK_IMAGE) Xen_wrap_1_arg(gxg_GTK_IM_CONTEXT_w, gxg_GTK_IM_CONTEXT) Xen_wrap_1_arg(gxg_GTK_IM_CONTEXT_SIMPLE_w, gxg_GTK_IM_CONTEXT_SIMPLE) Xen_wrap_1_arg(gxg_GTK_INVISIBLE_w, gxg_GTK_INVISIBLE) Xen_wrap_1_arg(gxg_GTK_LABEL_w, gxg_GTK_LABEL) Xen_wrap_1_arg(gxg_GTK_LAYOUT_w, gxg_GTK_LAYOUT) Xen_wrap_1_arg(gxg_GTK_LIST_STORE_w, gxg_GTK_LIST_STORE) Xen_wrap_1_arg(gxg_GTK_MENU_BAR_w, gxg_GTK_MENU_BAR) Xen_wrap_1_arg(gxg_GTK_MENU_w, gxg_GTK_MENU) Xen_wrap_1_arg(gxg_GTK_MENU_ITEM_w, gxg_GTK_MENU_ITEM) Xen_wrap_1_arg(gxg_GTK_MENU_SHELL_w, gxg_GTK_MENU_SHELL) Xen_wrap_1_arg(gxg_GTK_NOTEBOOK_w, gxg_GTK_NOTEBOOK) Xen_wrap_1_arg(gxg_GTK_PANED_w, gxg_GTK_PANED) Xen_wrap_1_arg(gxg_GTK_PROGRESS_BAR_w, gxg_GTK_PROGRESS_BAR) Xen_wrap_1_arg(gxg_GTK_RADIO_BUTTON_w, gxg_GTK_RADIO_BUTTON) Xen_wrap_1_arg(gxg_GTK_RADIO_MENU_ITEM_w, gxg_GTK_RADIO_MENU_ITEM) Xen_wrap_1_arg(gxg_GTK_RANGE_w, gxg_GTK_RANGE) Xen_wrap_1_arg(gxg_GTK_SCALE_w, gxg_GTK_SCALE) Xen_wrap_1_arg(gxg_GTK_SCROLLBAR_w, gxg_GTK_SCROLLBAR) Xen_wrap_1_arg(gxg_GTK_SCROLLED_WINDOW_w, gxg_GTK_SCROLLED_WINDOW) Xen_wrap_1_arg(gxg_GTK_SEPARATOR_w, gxg_GTK_SEPARATOR) Xen_wrap_1_arg(gxg_GTK_SEPARATOR_MENU_ITEM_w, gxg_GTK_SEPARATOR_MENU_ITEM) Xen_wrap_1_arg(gxg_GTK_SETTINGS_w, gxg_GTK_SETTINGS) Xen_wrap_1_arg(gxg_GTK_SIZE_GROUP_w, gxg_GTK_SIZE_GROUP) Xen_wrap_1_arg(gxg_GTK_SPIN_BUTTON_w, gxg_GTK_SPIN_BUTTON) Xen_wrap_1_arg(gxg_GTK_STATUSBAR_w, gxg_GTK_STATUSBAR) Xen_wrap_1_arg(gxg_GTK_TEXT_BUFFER_w, gxg_GTK_TEXT_BUFFER) Xen_wrap_1_arg(gxg_GTK_TEXT_CHILD_ANCHOR_w, gxg_GTK_TEXT_CHILD_ANCHOR) Xen_wrap_1_arg(gxg_GTK_TEXT_MARK_w, gxg_GTK_TEXT_MARK) Xen_wrap_1_arg(gxg_GTK_TEXT_TAG_w, gxg_GTK_TEXT_TAG) Xen_wrap_1_arg(gxg_GTK_TEXT_TAG_TABLE_w, gxg_GTK_TEXT_TAG_TABLE) Xen_wrap_1_arg(gxg_GTK_TEXT_VIEW_w, gxg_GTK_TEXT_VIEW) Xen_wrap_1_arg(gxg_GTK_TOGGLE_BUTTON_w, gxg_GTK_TOGGLE_BUTTON) Xen_wrap_1_arg(gxg_GTK_TOOLBAR_w, gxg_GTK_TOOLBAR) Xen_wrap_1_arg(gxg_GTK_TREE_DRAG_SOURCE_w, gxg_GTK_TREE_DRAG_SOURCE) Xen_wrap_1_arg(gxg_GTK_TREE_DRAG_DEST_w, gxg_GTK_TREE_DRAG_DEST) Xen_wrap_1_arg(gxg_GTK_TREE_MODEL_w, gxg_GTK_TREE_MODEL) Xen_wrap_1_arg(gxg_GTK_TREE_MODEL_SORT_w, gxg_GTK_TREE_MODEL_SORT) Xen_wrap_1_arg(gxg_GTK_TREE_SELECTION_w, gxg_GTK_TREE_SELECTION) Xen_wrap_1_arg(gxg_GTK_TREE_SORTABLE_w, gxg_GTK_TREE_SORTABLE) Xen_wrap_1_arg(gxg_GTK_TREE_STORE_w, gxg_GTK_TREE_STORE) Xen_wrap_1_arg(gxg_GTK_TREE_VIEW_COLUMN_w, gxg_GTK_TREE_VIEW_COLUMN) Xen_wrap_1_arg(gxg_GTK_TREE_VIEW_w, gxg_GTK_TREE_VIEW) Xen_wrap_1_arg(gxg_GTK_VIEWPORT_w, gxg_GTK_VIEWPORT) Xen_wrap_1_arg(gxg_GTK_WIDGET_w, gxg_GTK_WIDGET) Xen_wrap_1_arg(gxg_GTK_WINDOW_w, gxg_GTK_WINDOW) Xen_wrap_1_arg(gxg_PANGO_CONTEXT_w, gxg_PANGO_CONTEXT) Xen_wrap_1_arg(gxg_PANGO_FONT_FAMILY_w, gxg_PANGO_FONT_FAMILY) Xen_wrap_1_arg(gxg_PANGO_FONT_FACE_w, gxg_PANGO_FONT_FACE) Xen_wrap_1_arg(gxg_PANGO_FONT_w, gxg_PANGO_FONT) Xen_wrap_1_arg(gxg_PANGO_FONT_MAP_w, gxg_PANGO_FONT_MAP) Xen_wrap_1_arg(gxg_PANGO_LAYOUT_w, gxg_PANGO_LAYOUT) Xen_wrap_1_arg(gxg_G_OBJECT_w, gxg_G_OBJECT) Xen_wrap_1_arg(gxg_GDK_SCREEN_w, gxg_GDK_SCREEN) Xen_wrap_1_arg(gxg_GDK_DISPLAY_OBJECT_w, gxg_GDK_DISPLAY_OBJECT) Xen_wrap_1_arg(gxg_GDK_EVENT_w, gxg_GDK_EVENT) Xen_wrap_1_arg(gxg_GDK_EVENT_ANY_w, gxg_GDK_EVENT_ANY) Xen_wrap_1_arg(gxg_GDK_EVENT_EXPOSE_w, gxg_GDK_EVENT_EXPOSE) Xen_wrap_1_arg(gxg_GDK_EVENT_NOEXPOSE_w, gxg_GDK_EVENT_NOEXPOSE) Xen_wrap_1_arg(gxg_GDK_EVENT_VISIBILITY_w, gxg_GDK_EVENT_VISIBILITY) Xen_wrap_1_arg(gxg_GDK_EVENT_MOTION_w, gxg_GDK_EVENT_MOTION) Xen_wrap_1_arg(gxg_GDK_EVENT_BUTTON_w, gxg_GDK_EVENT_BUTTON) Xen_wrap_1_arg(gxg_GDK_EVENT_SCROLL_w, gxg_GDK_EVENT_SCROLL) Xen_wrap_1_arg(gxg_GDK_EVENT_KEY_w, gxg_GDK_EVENT_KEY) Xen_wrap_1_arg(gxg_GDK_EVENT_CROSSING_w, gxg_GDK_EVENT_CROSSING) Xen_wrap_1_arg(gxg_GDK_EVENT_FOCUS_w, gxg_GDK_EVENT_FOCUS) Xen_wrap_1_arg(gxg_GDK_EVENT_CONFIGURE_w, gxg_GDK_EVENT_CONFIGURE) Xen_wrap_1_arg(gxg_GDK_EVENT_PROPERTY_w, gxg_GDK_EVENT_PROPERTY) Xen_wrap_1_arg(gxg_GDK_EVENT_SELECTION_w, gxg_GDK_EVENT_SELECTION) Xen_wrap_1_arg(gxg_GDK_EVENT_PROXIMITY_w, gxg_GDK_EVENT_PROXIMITY) Xen_wrap_1_arg(gxg_GDK_EVENT_SETTING_w, gxg_GDK_EVENT_SETTING) Xen_wrap_1_arg(gxg_GDK_EVENT_WINDOWSTATE_w, gxg_GDK_EVENT_WINDOWSTATE) Xen_wrap_1_arg(gxg_GDK_EVENT_DND_w, gxg_GDK_EVENT_DND) Xen_wrap_1_arg(gxg_GTK_FILE_CHOOSER_DIALOG_w, gxg_GTK_FILE_CHOOSER_DIALOG) Xen_wrap_1_arg(gxg_GTK_FILE_CHOOSER_WIDGET_w, gxg_GTK_FILE_CHOOSER_WIDGET) Xen_wrap_1_arg(gxg_GTK_TREE_MODEL_FILTER_w, gxg_GTK_TREE_MODEL_FILTER) Xen_wrap_1_arg(gxg_GTK_COMBO_BOX_w, gxg_GTK_COMBO_BOX) Xen_wrap_1_arg(gxg_GTK_EXPANDER_w, gxg_GTK_EXPANDER) Xen_wrap_1_arg(gxg_GTK_FONT_BUTTON_w, gxg_GTK_FONT_BUTTON) Xen_wrap_1_arg(gxg_GTK_COLOR_BUTTON_w, gxg_GTK_COLOR_BUTTON) Xen_wrap_1_arg(gxg_GTK_ENTRY_COMPLETION_w, gxg_GTK_ENTRY_COMPLETION) Xen_wrap_1_arg(gxg_GTK_RADIO_TOOL_BUTTON_w, gxg_GTK_RADIO_TOOL_BUTTON) Xen_wrap_1_arg(gxg_GTK_SEPARATOR_TOOL_ITEM_w, gxg_GTK_SEPARATOR_TOOL_ITEM) Xen_wrap_1_arg(gxg_GTK_TOGGLE_TOOL_BUTTON_w, gxg_GTK_TOGGLE_TOOL_BUTTON) Xen_wrap_1_arg(gxg_GTK_FILE_FILTER_w, gxg_GTK_FILE_FILTER) Xen_wrap_1_arg(gxg_GTK_CELL_LAYOUT_w, gxg_GTK_CELL_LAYOUT) Xen_wrap_1_arg(gxg_GTK_CLIPBOARD_w, gxg_GTK_CLIPBOARD) Xen_wrap_1_arg(gxg_GTK_FILE_CHOOSER_w, gxg_GTK_FILE_CHOOSER) Xen_wrap_1_arg(gxg_GTK_ICON_THEME_w, gxg_GTK_ICON_THEME) Xen_wrap_1_arg(gxg_GTK_TOOL_BUTTON_w, gxg_GTK_TOOL_BUTTON) Xen_wrap_1_arg(gxg_GTK_TOOL_ITEM_w, gxg_GTK_TOOL_ITEM) Xen_wrap_1_arg(gxg_GTK_ACCEL_MAP_w, gxg_GTK_ACCEL_MAP) Xen_wrap_1_arg(gxg_GTK_CELL_VIEW_w, gxg_GTK_CELL_VIEW) Xen_wrap_1_arg(gxg_GTK_ABOUT_DIALOG_w, gxg_GTK_ABOUT_DIALOG) Xen_wrap_1_arg(gxg_GTK_CELL_RENDERER_COMBO_w, gxg_GTK_CELL_RENDERER_COMBO) Xen_wrap_1_arg(gxg_GTK_CELL_RENDERER_PROGRESS_w, gxg_GTK_CELL_RENDERER_PROGRESS) Xen_wrap_1_arg(gxg_GTK_ICON_VIEW_w, gxg_GTK_ICON_VIEW) Xen_wrap_1_arg(gxg_GTK_FILE_CHOOSER_BUTTON_w, gxg_GTK_FILE_CHOOSER_BUTTON) Xen_wrap_1_arg(gxg_GTK_MENU_TOOL_BUTTON_w, gxg_GTK_MENU_TOOL_BUTTON) Xen_wrap_1_arg(gxg_GTK_ASSISTANT_w, gxg_GTK_ASSISTANT) Xen_wrap_1_arg(gxg_GTK_CELL_RENDERER_ACCEL_w, gxg_GTK_CELL_RENDERER_ACCEL) Xen_wrap_1_arg(gxg_GTK_CELL_RENDERER_SPIN_w, gxg_GTK_CELL_RENDERER_SPIN) Xen_wrap_1_arg(gxg_GTK_LINK_BUTTON_w, gxg_GTK_LINK_BUTTON) Xen_wrap_1_arg(gxg_GTK_RECENT_CHOOSER_DIALOG_w, gxg_GTK_RECENT_CHOOSER_DIALOG) Xen_wrap_1_arg(gxg_GTK_RECENT_CHOOSER_w, gxg_GTK_RECENT_CHOOSER) Xen_wrap_1_arg(gxg_GTK_RECENT_CHOOSER_MENU_w, gxg_GTK_RECENT_CHOOSER_MENU) Xen_wrap_1_arg(gxg_GTK_RECENT_CHOOSER_WIDGET_w, gxg_GTK_RECENT_CHOOSER_WIDGET) Xen_wrap_1_arg(gxg_GTK_RECENT_FILTER_w, gxg_GTK_RECENT_FILTER) Xen_wrap_1_arg(gxg_GTK_RECENT_MANAGER_w, gxg_GTK_RECENT_MANAGER) Xen_wrap_1_arg(gxg_GTK_PRINT_CONTEXT_w, gxg_GTK_PRINT_CONTEXT) Xen_wrap_1_arg(gxg_GTK_PRINT_OPERATION_w, gxg_GTK_PRINT_OPERATION) Xen_wrap_1_arg(gxg_GTK_PRINT_OPERATION_PREVIEW_w, gxg_GTK_PRINT_OPERATION_PREVIEW) Xen_wrap_1_arg(gxg_GTK_PRINT_SETTINGS_w, gxg_GTK_PRINT_SETTINGS) Xen_wrap_1_arg(gxg_GTK_TOOLTIP_w, gxg_GTK_TOOLTIP) #if GTK_CHECK_VERSION(2, 18, 0) Xen_wrap_1_arg(gxg_GTK_INFO_BAR_w, gxg_GTK_INFO_BAR) Xen_wrap_1_arg(gxg_GTK_ENTRY_BUFFER_w, gxg_GTK_ENTRY_BUFFER) #endif #if GTK_CHECK_VERSION(2, 20, 0) Xen_wrap_1_arg(gxg_GTK_SPINNER_w, gxg_GTK_SPINNER) Xen_wrap_1_arg(gxg_GTK_CELL_RENDERER_SPINNER_w, gxg_GTK_CELL_RENDERER_SPINNER) Xen_wrap_1_arg(gxg_GTK_TOOL_PALETTE_w, gxg_GTK_TOOL_PALETTE) Xen_wrap_1_arg(gxg_GTK_TOOL_ITEM_GROUP_w, gxg_GTK_TOOL_ITEM_GROUP) #endif #if GTK_CHECK_VERSION(3, 0, 0) Xen_wrap_1_arg(gxg_GTK_COMBO_BOX_TEXT_w, gxg_GTK_COMBO_BOX_TEXT) Xen_wrap_1_arg(gxg_GTK_GRID_w, gxg_GTK_GRID) Xen_wrap_1_arg(gxg_GTK_SCROLLABLE_w, gxg_GTK_SCROLLABLE) Xen_wrap_1_arg(gxg_GDK_RGBA_w, gxg_GDK_RGBA) Xen_wrap_1_arg(gxg_GTK_SWITCH_w, gxg_GTK_SWITCH) Xen_wrap_1_arg(gxg_GTK_ORIENTABLE_w, gxg_GTK_ORIENTABLE) Xen_wrap_1_arg(gxg_GTK_WINDOW_GROUP_w, gxg_GTK_WINDOW_GROUP) Xen_wrap_1_arg(gxg_GTK_TOOL_SHELL_w, gxg_GTK_TOOL_SHELL) #endif #if GTK_CHECK_VERSION(3, 2, 0) Xen_wrap_1_arg(gxg_GTK_OVERLAY_w, gxg_GTK_OVERLAY) Xen_wrap_1_arg(gxg_GTK_FONT_CHOOSER_w, gxg_GTK_FONT_CHOOSER) Xen_wrap_1_arg(gxg_GTK_FONT_CHOOSER_DIALOG_w, gxg_GTK_FONT_CHOOSER_DIALOG) Xen_wrap_1_arg(gxg_GTK_FONT_CHOOSER_WIDGET_w, gxg_GTK_FONT_CHOOSER_WIDGET) #endif #if GTK_CHECK_VERSION(3, 4, 0) Xen_wrap_1_arg(gxg_GTK_APPLICATION_WINDOW_w, gxg_GTK_APPLICATION_WINDOW) Xen_wrap_1_arg(gxg_GTK_COLOR_CHOOSER_DIALOG_w, gxg_GTK_COLOR_CHOOSER_DIALOG) Xen_wrap_1_arg(gxg_GTK_COLOR_CHOOSER_WIDGET_w, gxg_GTK_COLOR_CHOOSER_WIDGET) #endif #if GTK_CHECK_VERSION(3, 6, 0) Xen_wrap_1_arg(gxg_GTK_MENU_BUTTON_w, gxg_GTK_MENU_BUTTON) Xen_wrap_1_arg(gxg_GTK_SEARCH_ENTRY_w, gxg_GTK_SEARCH_ENTRY) Xen_wrap_1_arg(gxg_GTK_LEVEL_BAR_w, gxg_GTK_LEVEL_BAR) #endif #if GTK_CHECK_VERSION(3, 10, 0) Xen_wrap_1_arg(gxg_GTK_PLACES_SIDEBAR_w, gxg_GTK_PLACES_SIDEBAR) Xen_wrap_1_arg(gxg_GTK_STACK_SWITCHER_w, gxg_GTK_STACK_SWITCHER) Xen_wrap_1_arg(gxg_GTK_STACK_w, gxg_GTK_STACK) Xen_wrap_1_arg(gxg_GTK_REVEALER_w, gxg_GTK_REVEALER) Xen_wrap_1_arg(gxg_GTK_HEADER_BAR_w, gxg_GTK_HEADER_BAR) Xen_wrap_1_arg(gxg_GTK_LIST_BOX_w, gxg_GTK_LIST_BOX) Xen_wrap_1_arg(gxg_GTK_LIST_BOX_ROW_w, gxg_GTK_LIST_BOX_ROW) Xen_wrap_1_arg(gxg_GTK_SEARCH_BAR_w, gxg_GTK_SEARCH_BAR) #endif #if GTK_CHECK_VERSION(3, 12, 0) Xen_wrap_1_arg(gxg_GTK_FLOW_BOX_w, gxg_GTK_FLOW_BOX) Xen_wrap_1_arg(gxg_GTK_FLOW_BOX_CHILD_w, gxg_GTK_FLOW_BOX_CHILD) Xen_wrap_1_arg(gxg_GTK_ACTION_BAR_w, gxg_GTK_ACTION_BAR) Xen_wrap_1_arg(gxg_GTK_POPOVER_w, gxg_GTK_POPOVER) #endif #if GTK_CHECK_VERSION(3, 14, 0) Xen_wrap_1_arg(gxg_GTK_GESTURE_w, gxg_GTK_GESTURE) Xen_wrap_1_arg(gxg_GTK_GESTURE_DRAG_w, gxg_GTK_GESTURE_DRAG) Xen_wrap_1_arg(gxg_GTK_GESTURE_LONG_PRESS_w, gxg_GTK_GESTURE_LONG_PRESS) Xen_wrap_1_arg(gxg_GTK_GESTURE_ZOOM_w, gxg_GTK_GESTURE_ZOOM) Xen_wrap_1_arg(gxg_GTK_GESTURE_SWIPE_w, gxg_GTK_GESTURE_SWIPE) Xen_wrap_1_arg(gxg_GTK_GESTURE_SINGLE_w, gxg_GTK_GESTURE_SINGLE) Xen_wrap_1_arg(gxg_GTK_GESTURE_PAN_w, gxg_GTK_GESTURE_PAN) Xen_wrap_1_arg(gxg_GTK_GESTURE_MULTI_PRESS_w, gxg_GTK_GESTURE_MULTI_PRESS) Xen_wrap_1_arg(gxg_GTK_GESTURE_ROTATE_w, gxg_GTK_GESTURE_ROTATE) Xen_wrap_1_arg(gxg_GTK_EVENT_CONTROLLER_w, gxg_GTK_EVENT_CONTROLLER) #endif #if GTK_CHECK_VERSION(3, 16, 0) Xen_wrap_1_arg(gxg_GTK_GL_AREA_w, gxg_GTK_GL_AREA) Xen_wrap_1_arg(gxg_GDK_GL_CONTEXT_w, gxg_GDK_GL_CONTEXT) Xen_wrap_1_arg(gxg_GTK_POPOVER_MENU_w, gxg_GTK_POPOVER_MENU) Xen_wrap_1_arg(gxg_GTK_STACK_SIDEBAR_w, gxg_GTK_STACK_SIDEBAR) #endif Xen_wrap_1_arg(gxg_GDK_IS_DRAG_CONTEXT_w, gxg_GDK_IS_DRAG_CONTEXT) Xen_wrap_1_arg(gxg_GDK_IS_DEVICE_w, gxg_GDK_IS_DEVICE) Xen_wrap_1_arg(gxg_GDK_IS_KEYMAP_w, gxg_GDK_IS_KEYMAP) Xen_wrap_1_arg(gxg_GDK_IS_VISUAL_w, gxg_GDK_IS_VISUAL) Xen_wrap_1_arg(gxg_GDK_IS_WINDOW_w, gxg_GDK_IS_WINDOW) Xen_wrap_1_arg(gxg_GDK_IS_PIXBUF_w, gxg_GDK_IS_PIXBUF) Xen_wrap_1_arg(gxg_GDK_IS_PIXBUF_ANIMATION_w, gxg_GDK_IS_PIXBUF_ANIMATION) Xen_wrap_1_arg(gxg_GDK_IS_PIXBUF_ANIMATION_ITER_w, gxg_GDK_IS_PIXBUF_ANIMATION_ITER) Xen_wrap_1_arg(gxg_GTK_IS_ACCEL_GROUP_w, gxg_GTK_IS_ACCEL_GROUP) Xen_wrap_1_arg(gxg_GTK_IS_ACCEL_LABEL_w, gxg_GTK_IS_ACCEL_LABEL) Xen_wrap_1_arg(gxg_GTK_IS_ACCESSIBLE_w, gxg_GTK_IS_ACCESSIBLE) Xen_wrap_1_arg(gxg_GTK_IS_ADJUSTMENT_w, gxg_GTK_IS_ADJUSTMENT) Xen_wrap_1_arg(gxg_GTK_IS_ASPECT_FRAME_w, gxg_GTK_IS_ASPECT_FRAME) Xen_wrap_1_arg(gxg_GTK_IS_BUTTON_BOX_w, gxg_GTK_IS_BUTTON_BOX) Xen_wrap_1_arg(gxg_GTK_IS_BIN_w, gxg_GTK_IS_BIN) Xen_wrap_1_arg(gxg_GTK_IS_BOX_w, gxg_GTK_IS_BOX) Xen_wrap_1_arg(gxg_GTK_IS_BUTTON_w, gxg_GTK_IS_BUTTON) Xen_wrap_1_arg(gxg_GTK_IS_CALENDAR_w, gxg_GTK_IS_CALENDAR) Xen_wrap_1_arg(gxg_GTK_IS_CELL_EDITABLE_w, gxg_GTK_IS_CELL_EDITABLE) Xen_wrap_1_arg(gxg_GTK_IS_CELL_RENDERER_w, gxg_GTK_IS_CELL_RENDERER) Xen_wrap_1_arg(gxg_GTK_IS_CELL_RENDERER_PIXBUF_w, gxg_GTK_IS_CELL_RENDERER_PIXBUF) Xen_wrap_1_arg(gxg_GTK_IS_CELL_RENDERER_TEXT_w, gxg_GTK_IS_CELL_RENDERER_TEXT) Xen_wrap_1_arg(gxg_GTK_IS_CELL_RENDERER_TOGGLE_w, gxg_GTK_IS_CELL_RENDERER_TOGGLE) Xen_wrap_1_arg(gxg_GTK_IS_CHECK_BUTTON_w, gxg_GTK_IS_CHECK_BUTTON) Xen_wrap_1_arg(gxg_GTK_IS_CHECK_MENU_ITEM_w, gxg_GTK_IS_CHECK_MENU_ITEM) Xen_wrap_1_arg(gxg_GTK_IS_CONTAINER_w, gxg_GTK_IS_CONTAINER) Xen_wrap_1_arg(gxg_GTK_IS_DIALOG_w, gxg_GTK_IS_DIALOG) Xen_wrap_1_arg(gxg_GTK_IS_DRAWING_AREA_w, gxg_GTK_IS_DRAWING_AREA) Xen_wrap_1_arg(gxg_GTK_IS_EDITABLE_w, gxg_GTK_IS_EDITABLE) Xen_wrap_1_arg(gxg_GTK_IS_ENTRY_w, gxg_GTK_IS_ENTRY) Xen_wrap_1_arg(gxg_GTK_IS_EVENT_BOX_w, gxg_GTK_IS_EVENT_BOX) Xen_wrap_1_arg(gxg_GTK_IS_FIXED_w, gxg_GTK_IS_FIXED) Xen_wrap_1_arg(gxg_GTK_IS_FRAME_w, gxg_GTK_IS_FRAME) Xen_wrap_1_arg(gxg_GTK_IS_IMAGE_w, gxg_GTK_IS_IMAGE) Xen_wrap_1_arg(gxg_GTK_IS_IM_CONTEXT_w, gxg_GTK_IS_IM_CONTEXT) Xen_wrap_1_arg(gxg_GTK_IS_IM_CONTEXT_SIMPLE_w, gxg_GTK_IS_IM_CONTEXT_SIMPLE) Xen_wrap_1_arg(gxg_GTK_IS_INVISIBLE_w, gxg_GTK_IS_INVISIBLE) Xen_wrap_1_arg(gxg_GTK_IS_LABEL_w, gxg_GTK_IS_LABEL) Xen_wrap_1_arg(gxg_GTK_IS_LAYOUT_w, gxg_GTK_IS_LAYOUT) Xen_wrap_1_arg(gxg_GTK_IS_LIST_STORE_w, gxg_GTK_IS_LIST_STORE) Xen_wrap_1_arg(gxg_GTK_IS_MENU_BAR_w, gxg_GTK_IS_MENU_BAR) Xen_wrap_1_arg(gxg_GTK_IS_MENU_w, gxg_GTK_IS_MENU) Xen_wrap_1_arg(gxg_GTK_IS_MENU_ITEM_w, gxg_GTK_IS_MENU_ITEM) Xen_wrap_1_arg(gxg_GTK_IS_MENU_SHELL_w, gxg_GTK_IS_MENU_SHELL) Xen_wrap_1_arg(gxg_GTK_IS_NOTEBOOK_w, gxg_GTK_IS_NOTEBOOK) Xen_wrap_1_arg(gxg_GTK_IS_PANED_w, gxg_GTK_IS_PANED) Xen_wrap_1_arg(gxg_GTK_IS_PROGRESS_BAR_w, gxg_GTK_IS_PROGRESS_BAR) Xen_wrap_1_arg(gxg_GTK_IS_RADIO_BUTTON_w, gxg_GTK_IS_RADIO_BUTTON) Xen_wrap_1_arg(gxg_GTK_IS_RADIO_MENU_ITEM_w, gxg_GTK_IS_RADIO_MENU_ITEM) Xen_wrap_1_arg(gxg_GTK_IS_RANGE_w, gxg_GTK_IS_RANGE) Xen_wrap_1_arg(gxg_GTK_IS_SCALE_w, gxg_GTK_IS_SCALE) Xen_wrap_1_arg(gxg_GTK_IS_SCROLLBAR_w, gxg_GTK_IS_SCROLLBAR) Xen_wrap_1_arg(gxg_GTK_IS_SCROLLED_WINDOW_w, gxg_GTK_IS_SCROLLED_WINDOW) Xen_wrap_1_arg(gxg_GTK_IS_SEPARATOR_w, gxg_GTK_IS_SEPARATOR) Xen_wrap_1_arg(gxg_GTK_IS_SEPARATOR_MENU_ITEM_w, gxg_GTK_IS_SEPARATOR_MENU_ITEM) Xen_wrap_1_arg(gxg_GTK_IS_SETTINGS_w, gxg_GTK_IS_SETTINGS) Xen_wrap_1_arg(gxg_GTK_IS_SIZE_GROUP_w, gxg_GTK_IS_SIZE_GROUP) Xen_wrap_1_arg(gxg_GTK_IS_SPIN_BUTTON_w, gxg_GTK_IS_SPIN_BUTTON) Xen_wrap_1_arg(gxg_GTK_IS_STATUSBAR_w, gxg_GTK_IS_STATUSBAR) Xen_wrap_1_arg(gxg_GTK_IS_TEXT_BUFFER_w, gxg_GTK_IS_TEXT_BUFFER) Xen_wrap_1_arg(gxg_GTK_IS_TEXT_CHILD_ANCHOR_w, gxg_GTK_IS_TEXT_CHILD_ANCHOR) Xen_wrap_1_arg(gxg_GTK_IS_TEXT_MARK_w, gxg_GTK_IS_TEXT_MARK) Xen_wrap_1_arg(gxg_GTK_IS_TEXT_TAG_w, gxg_GTK_IS_TEXT_TAG) Xen_wrap_1_arg(gxg_GTK_IS_TEXT_TAG_TABLE_w, gxg_GTK_IS_TEXT_TAG_TABLE) Xen_wrap_1_arg(gxg_GTK_IS_TEXT_VIEW_w, gxg_GTK_IS_TEXT_VIEW) Xen_wrap_1_arg(gxg_GTK_IS_TOGGLE_BUTTON_w, gxg_GTK_IS_TOGGLE_BUTTON) Xen_wrap_1_arg(gxg_GTK_IS_TOOLBAR_w, gxg_GTK_IS_TOOLBAR) Xen_wrap_1_arg(gxg_GTK_IS_TREE_DRAG_SOURCE_w, gxg_GTK_IS_TREE_DRAG_SOURCE) Xen_wrap_1_arg(gxg_GTK_IS_TREE_DRAG_DEST_w, gxg_GTK_IS_TREE_DRAG_DEST) Xen_wrap_1_arg(gxg_GTK_IS_TREE_MODEL_w, gxg_GTK_IS_TREE_MODEL) Xen_wrap_1_arg(gxg_GTK_IS_TREE_MODEL_SORT_w, gxg_GTK_IS_TREE_MODEL_SORT) Xen_wrap_1_arg(gxg_GTK_IS_TREE_SELECTION_w, gxg_GTK_IS_TREE_SELECTION) Xen_wrap_1_arg(gxg_GTK_IS_TREE_SORTABLE_w, gxg_GTK_IS_TREE_SORTABLE) Xen_wrap_1_arg(gxg_GTK_IS_TREE_STORE_w, gxg_GTK_IS_TREE_STORE) Xen_wrap_1_arg(gxg_GTK_IS_TREE_VIEW_COLUMN_w, gxg_GTK_IS_TREE_VIEW_COLUMN) Xen_wrap_1_arg(gxg_GTK_IS_TREE_VIEW_w, gxg_GTK_IS_TREE_VIEW) Xen_wrap_1_arg(gxg_GTK_IS_VIEWPORT_w, gxg_GTK_IS_VIEWPORT) Xen_wrap_1_arg(gxg_GTK_IS_WIDGET_w, gxg_GTK_IS_WIDGET) Xen_wrap_1_arg(gxg_GTK_IS_WINDOW_w, gxg_GTK_IS_WINDOW) Xen_wrap_1_arg(gxg_PANGO_IS_CONTEXT_w, gxg_PANGO_IS_CONTEXT) Xen_wrap_1_arg(gxg_PANGO_IS_FONT_FAMILY_w, gxg_PANGO_IS_FONT_FAMILY) Xen_wrap_1_arg(gxg_PANGO_IS_FONT_FACE_w, gxg_PANGO_IS_FONT_FACE) Xen_wrap_1_arg(gxg_PANGO_IS_FONT_w, gxg_PANGO_IS_FONT) Xen_wrap_1_arg(gxg_PANGO_IS_FONT_MAP_w, gxg_PANGO_IS_FONT_MAP) Xen_wrap_1_arg(gxg_PANGO_IS_LAYOUT_w, gxg_PANGO_IS_LAYOUT) Xen_wrap_1_arg(gxg_G_IS_OBJECT_w, gxg_G_IS_OBJECT) Xen_wrap_1_arg(gxg_GDK_IS_SCREEN_w, gxg_GDK_IS_SCREEN) Xen_wrap_1_arg(gxg_GDK_IS_DISPLAY_w, gxg_GDK_IS_DISPLAY) Xen_wrap_1_arg(gxg_GTK_IS_FILE_CHOOSER_DIALOG_w, gxg_GTK_IS_FILE_CHOOSER_DIALOG) Xen_wrap_1_arg(gxg_GTK_IS_FILE_CHOOSER_WIDGET_w, gxg_GTK_IS_FILE_CHOOSER_WIDGET) Xen_wrap_1_arg(gxg_GTK_IS_TREE_MODEL_FILTER_w, gxg_GTK_IS_TREE_MODEL_FILTER) Xen_wrap_1_arg(gxg_GTK_IS_COMBO_BOX_w, gxg_GTK_IS_COMBO_BOX) Xen_wrap_1_arg(gxg_GTK_IS_EXPANDER_w, gxg_GTK_IS_EXPANDER) Xen_wrap_1_arg(gxg_GTK_IS_FONT_BUTTON_w, gxg_GTK_IS_FONT_BUTTON) Xen_wrap_1_arg(gxg_GTK_IS_COLOR_BUTTON_w, gxg_GTK_IS_COLOR_BUTTON) Xen_wrap_1_arg(gxg_GTK_IS_ENTRY_COMPLETION_w, gxg_GTK_IS_ENTRY_COMPLETION) Xen_wrap_1_arg(gxg_GTK_IS_RADIO_TOOL_BUTTON_w, gxg_GTK_IS_RADIO_TOOL_BUTTON) Xen_wrap_1_arg(gxg_GTK_IS_SEPARATOR_TOOL_ITEM_w, gxg_GTK_IS_SEPARATOR_TOOL_ITEM) Xen_wrap_1_arg(gxg_GTK_IS_TOGGLE_TOOL_BUTTON_w, gxg_GTK_IS_TOGGLE_TOOL_BUTTON) Xen_wrap_1_arg(gxg_GTK_IS_FILE_FILTER_w, gxg_GTK_IS_FILE_FILTER) Xen_wrap_1_arg(gxg_GTK_IS_CELL_LAYOUT_w, gxg_GTK_IS_CELL_LAYOUT) Xen_wrap_1_arg(gxg_GTK_IS_CLIPBOARD_w, gxg_GTK_IS_CLIPBOARD) Xen_wrap_1_arg(gxg_GTK_IS_FILE_CHOOSER_w, gxg_GTK_IS_FILE_CHOOSER) Xen_wrap_1_arg(gxg_GTK_IS_ICON_THEME_w, gxg_GTK_IS_ICON_THEME) Xen_wrap_1_arg(gxg_GTK_IS_TOOL_BUTTON_w, gxg_GTK_IS_TOOL_BUTTON) Xen_wrap_1_arg(gxg_GTK_IS_TOOL_ITEM_w, gxg_GTK_IS_TOOL_ITEM) Xen_wrap_1_arg(gxg_GTK_IS_ACCEL_MAP_w, gxg_GTK_IS_ACCEL_MAP) Xen_wrap_1_arg(gxg_GTK_IS_CELL_VIEW_w, gxg_GTK_IS_CELL_VIEW) Xen_wrap_1_arg(gxg_GTK_IS_ABOUT_DIALOG_w, gxg_GTK_IS_ABOUT_DIALOG) Xen_wrap_1_arg(gxg_GTK_IS_CELL_RENDERER_COMBO_w, gxg_GTK_IS_CELL_RENDERER_COMBO) Xen_wrap_1_arg(gxg_GTK_IS_CELL_RENDERER_PROGRESS_w, gxg_GTK_IS_CELL_RENDERER_PROGRESS) Xen_wrap_1_arg(gxg_GTK_IS_ICON_VIEW_w, gxg_GTK_IS_ICON_VIEW) Xen_wrap_1_arg(gxg_GTK_IS_FILE_CHOOSER_BUTTON_w, gxg_GTK_IS_FILE_CHOOSER_BUTTON) Xen_wrap_1_arg(gxg_GTK_IS_MENU_TOOL_BUTTON_w, gxg_GTK_IS_MENU_TOOL_BUTTON) Xen_wrap_1_arg(gxg_GTK_IS_ASSISTANT_w, gxg_GTK_IS_ASSISTANT) Xen_wrap_1_arg(gxg_GTK_IS_CELL_RENDERER_ACCEL_w, gxg_GTK_IS_CELL_RENDERER_ACCEL) Xen_wrap_1_arg(gxg_GTK_IS_CELL_RENDERER_SPIN_w, gxg_GTK_IS_CELL_RENDERER_SPIN) Xen_wrap_1_arg(gxg_GTK_IS_LINK_BUTTON_w, gxg_GTK_IS_LINK_BUTTON) Xen_wrap_1_arg(gxg_GTK_IS_RECENT_CHOOSER_DIALOG_w, gxg_GTK_IS_RECENT_CHOOSER_DIALOG) Xen_wrap_1_arg(gxg_GTK_IS_RECENT_CHOOSER_w, gxg_GTK_IS_RECENT_CHOOSER) Xen_wrap_1_arg(gxg_GTK_IS_RECENT_CHOOSER_MENU_w, gxg_GTK_IS_RECENT_CHOOSER_MENU) Xen_wrap_1_arg(gxg_GTK_IS_RECENT_CHOOSER_WIDGET_w, gxg_GTK_IS_RECENT_CHOOSER_WIDGET) Xen_wrap_1_arg(gxg_GTK_IS_RECENT_FILTER_w, gxg_GTK_IS_RECENT_FILTER) Xen_wrap_1_arg(gxg_GTK_IS_RECENT_MANAGER_w, gxg_GTK_IS_RECENT_MANAGER) Xen_wrap_1_arg(gxg_GTK_IS_PRINT_CONTEXT_w, gxg_GTK_IS_PRINT_CONTEXT) Xen_wrap_1_arg(gxg_GTK_IS_PRINT_OPERATION_w, gxg_GTK_IS_PRINT_OPERATION) Xen_wrap_1_arg(gxg_GTK_IS_PRINT_OPERATION_PREVIEW_w, gxg_GTK_IS_PRINT_OPERATION_PREVIEW) Xen_wrap_1_arg(gxg_GTK_IS_PRINT_SETTINGS_w, gxg_GTK_IS_PRINT_SETTINGS) Xen_wrap_1_arg(gxg_GTK_IS_TOOLTIP_w, gxg_GTK_IS_TOOLTIP) #if GTK_CHECK_VERSION(2, 18, 0) Xen_wrap_1_arg(gxg_GTK_IS_INFO_BAR_w, gxg_GTK_IS_INFO_BAR) Xen_wrap_1_arg(gxg_GTK_IS_ENTRY_BUFFER_w, gxg_GTK_IS_ENTRY_BUFFER) #endif #if GTK_CHECK_VERSION(2, 20, 0) Xen_wrap_1_arg(gxg_GTK_IS_SPINNER_w, gxg_GTK_IS_SPINNER) Xen_wrap_1_arg(gxg_GTK_IS_CELL_RENDERER_SPINNER_w, gxg_GTK_IS_CELL_RENDERER_SPINNER) Xen_wrap_1_arg(gxg_GTK_IS_TOOL_PALETTE_w, gxg_GTK_IS_TOOL_PALETTE) Xen_wrap_1_arg(gxg_GTK_IS_TOOL_ITEM_GROUP_w, gxg_GTK_IS_TOOL_ITEM_GROUP) #endif #if GTK_CHECK_VERSION(3, 0, 0) Xen_wrap_1_arg(gxg_GTK_IS_COMBO_BOX_TEXT_w, gxg_GTK_IS_COMBO_BOX_TEXT) Xen_wrap_1_arg(gxg_GTK_IS_GRID_w, gxg_GTK_IS_GRID) Xen_wrap_1_arg(gxg_GTK_IS_SCROLLABLE_w, gxg_GTK_IS_SCROLLABLE) Xen_wrap_1_arg(gxg_GTK_IS_SWITCH_w, gxg_GTK_IS_SWITCH) Xen_wrap_1_arg(gxg_GTK_IS_ORIENTABLE_w, gxg_GTK_IS_ORIENTABLE) Xen_wrap_1_arg(gxg_GTK_IS_WINDOW_GROUP_w, gxg_GTK_IS_WINDOW_GROUP) Xen_wrap_1_arg(gxg_GTK_IS_TOOL_SHELL_w, gxg_GTK_IS_TOOL_SHELL) #endif #if GTK_CHECK_VERSION(3, 2, 0) Xen_wrap_1_arg(gxg_GTK_IS_OVERLAY_w, gxg_GTK_IS_OVERLAY) Xen_wrap_1_arg(gxg_GTK_IS_FONT_CHOOSER_w, gxg_GTK_IS_FONT_CHOOSER) Xen_wrap_1_arg(gxg_GTK_IS_FONT_CHOOSER_DIALOG_w, gxg_GTK_IS_FONT_CHOOSER_DIALOG) Xen_wrap_1_arg(gxg_GTK_IS_FONT_CHOOSER_WIDGET_w, gxg_GTK_IS_FONT_CHOOSER_WIDGET) #endif #if GTK_CHECK_VERSION(3, 4, 0) Xen_wrap_1_arg(gxg_GTK_IS_APPLICATION_WINDOW_w, gxg_GTK_IS_APPLICATION_WINDOW) Xen_wrap_1_arg(gxg_GTK_IS_COLOR_CHOOSER_DIALOG_w, gxg_GTK_IS_COLOR_CHOOSER_DIALOG) Xen_wrap_1_arg(gxg_GTK_IS_COLOR_CHOOSER_WIDGET_w, gxg_GTK_IS_COLOR_CHOOSER_WIDGET) #endif #if GTK_CHECK_VERSION(3, 6, 0) Xen_wrap_1_arg(gxg_GTK_IS_MENU_BUTTON_w, gxg_GTK_IS_MENU_BUTTON) Xen_wrap_1_arg(gxg_GTK_IS_SEARCH_ENTRY_w, gxg_GTK_IS_SEARCH_ENTRY) Xen_wrap_1_arg(gxg_GTK_IS_LEVEL_BAR_w, gxg_GTK_IS_LEVEL_BAR) #endif #if GTK_CHECK_VERSION(3, 10, 0) Xen_wrap_1_arg(gxg_GTK_IS_PLACES_SIDEBAR_w, gxg_GTK_IS_PLACES_SIDEBAR) Xen_wrap_1_arg(gxg_GTK_IS_STACK_SWITCHER_w, gxg_GTK_IS_STACK_SWITCHER) Xen_wrap_1_arg(gxg_GTK_IS_STACK_w, gxg_GTK_IS_STACK) Xen_wrap_1_arg(gxg_GTK_IS_REVEALER_w, gxg_GTK_IS_REVEALER) Xen_wrap_1_arg(gxg_GTK_IS_HEADER_BAR_w, gxg_GTK_IS_HEADER_BAR) Xen_wrap_1_arg(gxg_GTK_IS_LIST_BOX_w, gxg_GTK_IS_LIST_BOX) Xen_wrap_1_arg(gxg_GTK_IS_LIST_BOX_ROW_w, gxg_GTK_IS_LIST_BOX_ROW) Xen_wrap_1_arg(gxg_GTK_IS_SEARCH_BAR_w, gxg_GTK_IS_SEARCH_BAR) #endif #if GTK_CHECK_VERSION(3, 12, 0) Xen_wrap_1_arg(gxg_GTK_IS_FLOW_BOX_w, gxg_GTK_IS_FLOW_BOX) Xen_wrap_1_arg(gxg_GTK_IS_FLOW_BOX_CHILD_w, gxg_GTK_IS_FLOW_BOX_CHILD) Xen_wrap_1_arg(gxg_GTK_IS_ACTION_BAR_w, gxg_GTK_IS_ACTION_BAR) Xen_wrap_1_arg(gxg_GTK_IS_POPOVER_w, gxg_GTK_IS_POPOVER) #endif #if GTK_CHECK_VERSION(3, 14, 0) Xen_wrap_1_arg(gxg_GTK_IS_GESTURE_w, gxg_GTK_IS_GESTURE) Xen_wrap_1_arg(gxg_GTK_IS_GESTURE_DRAG_w, gxg_GTK_IS_GESTURE_DRAG) Xen_wrap_1_arg(gxg_GTK_IS_GESTURE_LONG_PRESS_w, gxg_GTK_IS_GESTURE_LONG_PRESS) Xen_wrap_1_arg(gxg_GTK_IS_GESTURE_ZOOM_w, gxg_GTK_IS_GESTURE_ZOOM) Xen_wrap_1_arg(gxg_GTK_IS_GESTURE_SWIPE_w, gxg_GTK_IS_GESTURE_SWIPE) Xen_wrap_1_arg(gxg_GTK_IS_GESTURE_SINGLE_w, gxg_GTK_IS_GESTURE_SINGLE) Xen_wrap_1_arg(gxg_GTK_IS_GESTURE_PAN_w, gxg_GTK_IS_GESTURE_PAN) Xen_wrap_1_arg(gxg_GTK_IS_GESTURE_MULTI_PRESS_w, gxg_GTK_IS_GESTURE_MULTI_PRESS) Xen_wrap_1_arg(gxg_GTK_IS_GESTURE_ROTATE_w, gxg_GTK_IS_GESTURE_ROTATE) Xen_wrap_1_arg(gxg_GTK_IS_EVENT_CONTROLLER_w, gxg_GTK_IS_EVENT_CONTROLLER) #endif #if GTK_CHECK_VERSION(3, 16, 0) Xen_wrap_1_arg(gxg_GTK_IS_GL_AREA_w, gxg_GTK_IS_GL_AREA) Xen_wrap_1_arg(gxg_GDK_IS_GL_CONTEXT_w, gxg_GDK_IS_GL_CONTEXT) Xen_wrap_1_arg(gxg_GTK_IS_POPOVER_MENU_w, gxg_GTK_IS_POPOVER_MENU) Xen_wrap_1_arg(gxg_GTK_IS_STACK_SIDEBAR_w, gxg_GTK_IS_STACK_SIDEBAR) #endif #if HAVE_SCHEME static s7_pointer s_boolean, s_integer, s_real, s_string, s_any, s_pair, s_float, s_pair_false; static s7_pointer pl_tsb, pl_st, pl_tsu, pl_ts, pl_tsi, pl_tsiu, pl_tsiiuui, pl_tsiuui, pl_t, pl_psibiiiit, pl_psrrrb, pl_sui, pl_psu, pl_psb, pl_su, pl_sus, pl_ps, pl_psi, pl_psuit, pl_psut, pl_suuub, pl_p, pl_tts, pl_tti, pl_tusiuiuit, pl_tubu, pl_tuurru, pl_tuurrrrir, pl_tuurrrri, pl_tuuur, pl_tuuuui, pl_tuusb, pl_turru, pl_tuuuub, pl_tuttti, pl_tuuttti, pl_tuisi, pl_turis, pl_tubi, pl_tuttiisi, pl_tuiiiiui, pl_tuurb, pl_tuuiiiirrrri, pl_turrrb, pl_tuubbi, pl_pt, pl_tuuti, pl_tubbi, pl_tusiu, pl_tuuutti, pl_tuti, pl_tutti, pl_tutui, pl_tutisi, pl_tuuri, pl_tusr, pl_tusrt, pl_tusi, pl_turt, pl_tuui, pl_tut, pl_tuur, pl_tur, pl_tub, pl_tui, pl_tu, pl_tus, pl_tuiiu, pl_tusb, pl_tuuut, pl_tutb, pl_tust, pl_tuub, pl_tuus, pl_tuibu, pl_tuut, pl_tuiui, pl_tuubr, pl_tuuub, pl_tuuui, pl_tuuiuui, pl_tuiu, pl_tuuir, pl_tuir, pl_tuib, pl_tusu, pl_tuusi, pl_tuit, pl_tuis, pl_tubiiiu, pl_tusiis, pl_tusiuiu, pl_tusiuibu, pl_tusiiu, pl_tusui, pl_tuuubr, pl_tuiiiu, pl_tuuiu, pl_tuurbr, pl_tuusit, pl_pur, pl_puiu, pl_pusiiiu, pl_pusiiuiu, pl_puur, pl_puiiui, pl_pubi, pl_puiiu, pl_puuusuui, pl_pu, pl_puutu, pl_pui, pl_pusu, pl_pus, pl_put, pl_pusiiu, pl_pusi, pl_puui, pl_pub, pl_pust, pl_pusub, pl_puri, pl_bi, pl_bsiu, pl_bsiuub, pl_bsu, pl_bsiib, pl_bsiiuusu, pl_b, pl_btiib, pl_bti, pl_bt, pl_tb, pl_bur, pl_buut, pl_buuti, pl_buttiiiu, pl_butib, pl_buiui, pl_buuusuui, pl_buuit, pl_butu, pl_buti, pl_butti, pl_busi, pl_busu, pl_bui, pl_bu, pl_buuubu, pl_bus, pl_buutuuiu, pl_but, pl_bussu, pl_buib, pl_buiu, pl_buiiu, pl_bub, pl_buub, pl_pb, pl_buuiiu, pl_buui, pl_buuui, pl_buus, pl_buurbr, pl_busiu, pl_buttu, pl_buuub, pl_buuuub, pl_busib, pl_buusib, pl_iiit, pl_iit, pl_isiiutttiiu, pl_isi, pl_isit, pl_si, pl_is, pl_i, pl_itiiub, pl_itsub, pl_itsttti, pl_itiiiut, pl_tiu, pl_it, pl_ti, pl_iur, pl_iussitu, pl_iurrsiu, pl_iuut, pl_iuuut, pl_pir, pl_iuisi, pl_pibi, pl_iuuui, pl_iuuuui, pl_ius, pl_iusi, pl_iu, pl_iuiu, pl_iuui, pl_pi, pl_iui, pl_iuisut, pl_piu, pl_pit, pl_iuis, pl_trrru, pl_dusr, pl_dust, pl_dut, pl_du, pl_dus, pl_pr, pl_ssi, pl_s, pl_unused; #endif static void define_functions(void) { xm_gc_table = Xen_make_vector(1, Xen_false); Xen_GC_protect(xm_gc_table); xm_protected_size = 512; xm_protected = Xen_make_vector(xm_protected_size, Xen_false); Xen_vector_set(xm_gc_table, 0, xm_protected); #if HAVE_SCHEME s_boolean = s7_make_symbol(s7, "boolean?"); s_integer = s7_make_symbol(s7, "integer?"); s_real = s7_make_symbol(s7, "real?"); s_float = s7_make_symbol(s7, "float?"); s_string = s7_make_symbol(s7, "string?"); s_pair = s7_make_symbol(s7, "pair?"); s_pair_false = s7_make_signature(s7, 2, s_pair, s_boolean); s_any = s7_t(s7); pl_tsb = s7_make_circular_signature(s7, 2, 3, s_any, s_string, s_boolean); pl_st = s7_make_circular_signature(s7, 1, 2, s_string, s_any); pl_tsu = s7_make_circular_signature(s7, 2, 3, s_any, s_string, s_pair_false); pl_ts = s7_make_circular_signature(s7, 1, 2, s_any, s_string); pl_tsi = s7_make_circular_signature(s7, 2, 3, s_any, s_string, s_integer); pl_tsiu = s7_make_circular_signature(s7, 3, 4, s_any, s_string, s_integer, s_pair_false); pl_tsiiuui = s7_make_circular_signature(s7, 6, 7, s_any, s_string, s_integer, s_integer, s_pair_false, s_pair_false, s_integer); pl_tsiuui = s7_make_circular_signature(s7, 5, 6, s_any, s_string, s_integer, s_pair_false, s_pair_false, s_integer); pl_t = s7_make_circular_signature(s7, 0, 1, s_any); pl_psibiiiit = s7_make_circular_signature(s7, 8, 9, s_pair, s_string, s_integer, s_boolean, s_integer, s_integer, s_integer, s_integer, s_any); pl_psrrrb = s7_make_circular_signature(s7, 5, 6, s_pair, s_string, s_real, s_real, s_real, s_boolean); pl_sui = s7_make_circular_signature(s7, 2, 3, s_string, s_pair_false, s_integer); pl_psu = s7_make_circular_signature(s7, 2, 3, s_pair, s_string, s_pair_false); pl_psb = s7_make_circular_signature(s7, 2, 3, s_pair, s_string, s_boolean); pl_su = s7_make_circular_signature(s7, 1, 2, s_string, s_pair_false); pl_sus = s7_make_circular_signature(s7, 2, 3, s_string, s_pair_false, s_string); pl_ps = s7_make_circular_signature(s7, 1, 2, s_pair, s_string); pl_psi = s7_make_circular_signature(s7, 2, 3, s_pair, s_string, s_integer); pl_psuit = s7_make_circular_signature(s7, 4, 5, s_pair, s_string, s_pair_false, s_integer, s_any); pl_psut = s7_make_circular_signature(s7, 3, 4, s_pair, s_string, s_pair_false, s_any); pl_suuub = s7_make_circular_signature(s7, 4, 5, s_string, s_pair_false, s_pair_false, s_pair_false, s_boolean); pl_p = s7_make_circular_signature(s7, 0, 1, s_pair); pl_tts = s7_make_circular_signature(s7, 2, 3, s_any, s_any, s_string); pl_tti = s7_make_circular_signature(s7, 2, 3, s_any, s_any, s_integer); pl_tusiuiuit = s7_make_circular_signature(s7, 8, 9, s_any, s_pair_false, s_string, s_integer, s_pair_false, s_integer, s_pair_false, s_integer, s_any); pl_tubu = s7_make_circular_signature(s7, 3, 4, s_any, s_pair_false, s_boolean, s_pair_false); pl_tuurru = s7_make_circular_signature(s7, 5, 6, s_any, s_pair_false, s_pair_false, s_real, s_real, s_pair_false); pl_tuurrrrir = s7_make_circular_signature(s7, 8, 9, s_any, s_pair_false, s_pair_false, s_real, s_real, s_real, s_real, s_integer, s_real); pl_tuurrrri = s7_make_circular_signature(s7, 7, 8, s_any, s_pair_false, s_pair_false, s_real, s_real, s_real, s_real, s_integer); pl_tuuur = s7_make_circular_signature(s7, 4, 5, s_any, s_pair_false, s_pair_false, s_pair_false, s_real); pl_tuuuui = s7_make_circular_signature(s7, 5, 6, s_any, s_pair_false, s_pair_false, s_pair_false, s_pair_false, s_integer); pl_tuusb = s7_make_circular_signature(s7, 4, 5, s_any, s_pair_false, s_pair_false, s_string, s_boolean); pl_turru = s7_make_circular_signature(s7, 4, 5, s_any, s_pair_false, s_real, s_real, s_pair_false); pl_tuuuub = s7_make_circular_signature(s7, 5, 6, s_any, s_pair_false, s_pair_false, s_pair_false, s_pair_false, s_boolean); pl_tuttti = s7_make_circular_signature(s7, 5, 6, s_any, s_pair_false, s_any, s_any, s_any, s_integer); pl_tuuttti = s7_make_circular_signature(s7, 6, 7, s_any, s_pair_false, s_pair_false, s_any, s_any, s_any, s_integer); pl_tuisi = s7_make_circular_signature(s7, 4, 5, s_any, s_pair_false, s_integer, s_string, s_integer); pl_turis = s7_make_circular_signature(s7, 4, 5, s_any, s_pair_false, s_real, s_integer, s_string); pl_tubi = s7_make_circular_signature(s7, 3, 4, s_any, s_pair_false, s_boolean, s_integer); pl_tuttiisi = s7_make_circular_signature(s7, 7, 8, s_any, s_pair_false, s_any, s_any, s_integer, s_integer, s_string, s_integer); pl_tuiiiiui = s7_make_circular_signature(s7, 7, 8, s_any, s_pair_false, s_integer, s_integer, s_integer, s_integer, s_pair_false, s_integer); pl_tuurb = s7_make_circular_signature(s7, 4, 5, s_any, s_pair_false, s_pair_false, s_real, s_boolean); pl_tuuiiiirrrri = s7_make_circular_signature(s7, 11, 12, s_any, s_pair_false, s_pair_false, s_integer, s_integer, s_integer, s_integer, s_real, s_real, s_real, s_real, s_integer); pl_turrrb = s7_make_circular_signature(s7, 5, 6, s_any, s_pair_false, s_real, s_real, s_real, s_boolean); pl_tuubbi = s7_make_circular_signature(s7, 5, 6, s_any, s_pair_false, s_pair_false, s_boolean, s_boolean, s_integer); pl_pt = s7_make_circular_signature(s7, 1, 2, s_pair, s_any); pl_tuuti = s7_make_circular_signature(s7, 4, 5, s_any, s_pair_false, s_pair_false, s_any, s_integer); pl_tubbi = s7_make_circular_signature(s7, 4, 5, s_any, s_pair_false, s_boolean, s_boolean, s_integer); pl_tusiu = s7_make_circular_signature(s7, 4, 5, s_any, s_pair_false, s_string, s_integer, s_pair_false); pl_tuuutti = s7_make_circular_signature(s7, 6, 7, s_any, s_pair_false, s_pair_false, s_pair_false, s_any, s_any, s_integer); pl_tuti = s7_make_circular_signature(s7, 3, 4, s_any, s_pair_false, s_any, s_integer); pl_tutti = s7_make_circular_signature(s7, 4, 5, s_any, s_pair_false, s_any, s_any, s_integer); pl_tutui = s7_make_circular_signature(s7, 4, 5, s_any, s_pair_false, s_any, s_pair_false, s_integer); pl_tutisi = s7_make_circular_signature(s7, 5, 6, s_any, s_pair_false, s_any, s_integer, s_string, s_integer); pl_tuuri = s7_make_circular_signature(s7, 4, 5, s_any, s_pair_false, s_pair_false, s_real, s_integer); pl_tusr = s7_make_circular_signature(s7, 3, 4, s_any, s_pair_false, s_string, s_real); pl_tusrt = s7_make_circular_signature(s7, 4, 5, s_any, s_pair_false, s_string, s_real, s_any); pl_tusi = s7_make_circular_signature(s7, 3, 4, s_any, s_pair_false, s_string, s_integer); pl_turt = s7_make_circular_signature(s7, 3, 4, s_any, s_pair_false, s_real, s_any); pl_tuui = s7_make_circular_signature(s7, 3, 4, s_any, s_pair_false, s_pair_false, s_integer); pl_tut = s7_make_circular_signature(s7, 2, 3, s_any, s_pair_false, s_any); pl_tuur = s7_make_circular_signature(s7, 3, 4, s_any, s_pair_false, s_pair_false, s_real); pl_tur = s7_make_circular_signature(s7, 2, 3, s_any, s_pair_false, s_real); pl_tub = s7_make_circular_signature(s7, 2, 3, s_any, s_pair_false, s_boolean); pl_tui = s7_make_circular_signature(s7, 2, 3, s_any, s_pair_false, s_integer); pl_tu = s7_make_circular_signature(s7, 1, 2, s_any, s_pair_false); pl_tus = s7_make_circular_signature(s7, 2, 3, s_any, s_pair_false, s_string); pl_tuiiu = s7_make_circular_signature(s7, 4, 5, s_any, s_pair_false, s_integer, s_integer, s_pair_false); pl_tusb = s7_make_circular_signature(s7, 3, 4, s_any, s_pair_false, s_string, s_boolean); pl_tuuut = s7_make_circular_signature(s7, 4, 5, s_any, s_pair_false, s_pair_false, s_pair_false, s_any); pl_tutb = s7_make_circular_signature(s7, 3, 4, s_any, s_pair_false, s_any, s_boolean); pl_tust = s7_make_circular_signature(s7, 3, 4, s_any, s_pair_false, s_string, s_any); pl_tuub = s7_make_circular_signature(s7, 3, 4, s_any, s_pair_false, s_pair_false, s_boolean); pl_tuus = s7_make_circular_signature(s7, 3, 4, s_any, s_pair_false, s_pair_false, s_string); pl_tuibu = s7_make_circular_signature(s7, 4, 5, s_any, s_pair_false, s_integer, s_boolean, s_pair_false); pl_tuut = s7_make_circular_signature(s7, 3, 4, s_any, s_pair_false, s_pair_false, s_any); pl_tuiui = s7_make_circular_signature(s7, 4, 5, s_any, s_pair_false, s_integer, s_pair_false, s_integer); pl_tuubr = s7_make_circular_signature(s7, 4, 5, s_any, s_pair_false, s_pair_false, s_boolean, s_real); pl_tuuub = s7_make_circular_signature(s7, 4, 5, s_any, s_pair_false, s_pair_false, s_pair_false, s_boolean); pl_tuuui = s7_make_circular_signature(s7, 4, 5, s_any, s_pair_false, s_pair_false, s_pair_false, s_integer); pl_tuuiuui = s7_make_circular_signature(s7, 6, 7, s_any, s_pair_false, s_pair_false, s_integer, s_pair_false, s_pair_false, s_integer); pl_tuiu = s7_make_circular_signature(s7, 3, 4, s_any, s_pair_false, s_integer, s_pair_false); pl_tuuir = s7_make_circular_signature(s7, 4, 5, s_any, s_pair_false, s_pair_false, s_integer, s_real); pl_tuir = s7_make_circular_signature(s7, 3, 4, s_any, s_pair_false, s_integer, s_real); pl_tuib = s7_make_circular_signature(s7, 3, 4, s_any, s_pair_false, s_integer, s_boolean); pl_tusu = s7_make_circular_signature(s7, 3, 4, s_any, s_pair_false, s_string, s_pair_false); pl_tuusi = s7_make_circular_signature(s7, 4, 5, s_any, s_pair_false, s_pair_false, s_string, s_integer); pl_tuit = s7_make_circular_signature(s7, 3, 4, s_any, s_pair_false, s_integer, s_any); pl_tuis = s7_make_circular_signature(s7, 3, 4, s_any, s_pair_false, s_integer, s_string); pl_tubiiiu = s7_make_circular_signature(s7, 6, 7, s_any, s_pair_false, s_boolean, s_integer, s_integer, s_integer, s_pair_false); pl_tusiis = s7_make_circular_signature(s7, 5, 6, s_any, s_pair_false, s_string, s_integer, s_integer, s_string); pl_tusiuiu = s7_make_circular_signature(s7, 6, 7, s_any, s_pair_false, s_string, s_integer, s_pair_false, s_integer, s_pair_false); pl_tusiuibu = s7_make_circular_signature(s7, 7, 8, s_any, s_pair_false, s_string, s_integer, s_pair_false, s_integer, s_boolean, s_pair_false); pl_tusiiu = s7_make_circular_signature(s7, 5, 6, s_any, s_pair_false, s_string, s_integer, s_integer, s_pair_false); pl_tusui = s7_make_circular_signature(s7, 4, 5, s_any, s_pair_false, s_string, s_pair_false, s_integer); pl_tuuubr = s7_make_circular_signature(s7, 5, 6, s_any, s_pair_false, s_pair_false, s_pair_false, s_boolean, s_real); pl_tuiiiu = s7_make_circular_signature(s7, 5, 6, s_any, s_pair_false, s_integer, s_integer, s_integer, s_pair_false); pl_tuuiu = s7_make_circular_signature(s7, 4, 5, s_any, s_pair_false, s_pair_false, s_integer, s_pair_false); pl_tuurbr = s7_make_circular_signature(s7, 5, 6, s_any, s_pair_false, s_pair_false, s_real, s_boolean, s_real); pl_tuusit = s7_make_circular_signature(s7, 5, 6, s_any, s_pair_false, s_pair_false, s_string, s_integer, s_any); pl_pur = s7_make_circular_signature(s7, 2, 3, s_pair, s_pair_false, s_real); pl_puiu = s7_make_circular_signature(s7, 3, 4, s_pair, s_pair_false, s_integer, s_pair_false); pl_pusiiiu = s7_make_circular_signature(s7, 6, 7, s_pair, s_pair_false, s_string, s_integer, s_integer, s_integer, s_pair_false); pl_pusiiuiu = s7_make_circular_signature(s7, 7, 8, s_pair, s_pair_false, s_string, s_integer, s_integer, s_pair_false, s_integer, s_pair_false); pl_puur = s7_make_circular_signature(s7, 3, 4, s_pair, s_pair_false, s_pair_false, s_real); pl_puiiui = s7_make_circular_signature(s7, 5, 6, s_pair, s_pair_false, s_integer, s_integer, s_pair_false, s_integer); pl_pubi = s7_make_circular_signature(s7, 3, 4, s_pair, s_pair_false, s_boolean, s_integer); pl_puiiu = s7_make_circular_signature(s7, 4, 5, s_pair, s_pair_false, s_integer, s_integer, s_pair_false); pl_puuusuui = s7_make_circular_signature(s7, 7, 8, s_pair, s_pair_false, s_pair_false, s_pair_false, s_string, s_pair_false, s_pair_false, s_integer); pl_pu = s7_make_circular_signature(s7, 1, 2, s_pair, s_pair_false); pl_puutu = s7_make_circular_signature(s7, 4, 5, s_pair, s_pair_false, s_pair_false, s_any, s_pair_false); pl_pui = s7_make_circular_signature(s7, 2, 3, s_pair, s_pair_false, s_integer); pl_pusu = s7_make_circular_signature(s7, 3, 4, s_pair, s_pair_false, s_string, s_pair_false); pl_pus = s7_make_circular_signature(s7, 2, 3, s_pair, s_pair_false, s_string); pl_put = s7_make_circular_signature(s7, 2, 3, s_pair, s_pair_false, s_any); pl_pusiiu = s7_make_circular_signature(s7, 5, 6, s_pair, s_pair_false, s_string, s_integer, s_integer, s_pair_false); pl_pusi = s7_make_circular_signature(s7, 3, 4, s_pair, s_pair_false, s_string, s_integer); pl_puui = s7_make_circular_signature(s7, 3, 4, s_pair, s_pair_false, s_pair_false, s_integer); pl_pub = s7_make_circular_signature(s7, 2, 3, s_pair, s_pair_false, s_boolean); pl_pust = s7_make_circular_signature(s7, 3, 4, s_pair, s_pair_false, s_string, s_any); pl_pusub = s7_make_circular_signature(s7, 4, 5, s_pair, s_pair_false, s_string, s_pair_false, s_boolean); pl_puri = s7_make_circular_signature(s7, 3, 4, s_pair, s_pair_false, s_real, s_integer); pl_bi = s7_make_circular_signature(s7, 1, 2, s_boolean, s_integer); pl_bsiu = s7_make_circular_signature(s7, 3, 4, s_boolean, s_string, s_integer, s_pair_false); pl_bsiuub = s7_make_circular_signature(s7, 5, 6, s_boolean, s_string, s_integer, s_pair_false, s_pair_false, s_boolean); pl_bsu = s7_make_circular_signature(s7, 2, 3, s_boolean, s_string, s_pair_false); pl_bsiib = s7_make_circular_signature(s7, 4, 5, s_boolean, s_string, s_integer, s_integer, s_boolean); pl_bsiiuusu = s7_make_circular_signature(s7, 7, 8, s_boolean, s_string, s_integer, s_integer, s_pair_false, s_pair_false, s_string, s_pair_false); pl_b = s7_make_circular_signature(s7, 0, 1, s_boolean); pl_btiib = s7_make_circular_signature(s7, 4, 5, s_boolean, s_any, s_integer, s_integer, s_boolean); pl_bti = s7_make_circular_signature(s7, 2, 3, s_boolean, s_any, s_integer); pl_bt = s7_make_circular_signature(s7, 1, 2, s_boolean, s_any); pl_tb = s7_make_circular_signature(s7, 1, 2, s_any, s_boolean); pl_bur = s7_make_circular_signature(s7, 2, 3, s_boolean, s_pair_false, s_real); pl_buut = s7_make_circular_signature(s7, 3, 4, s_boolean, s_pair_false, s_pair_false, s_any); pl_buuti = s7_make_circular_signature(s7, 4, 5, s_boolean, s_pair_false, s_pair_false, s_any, s_integer); pl_buttiiiu = s7_make_circular_signature(s7, 7, 8, s_boolean, s_pair_false, s_any, s_any, s_integer, s_integer, s_integer, s_pair_false); pl_butib = s7_make_circular_signature(s7, 4, 5, s_boolean, s_pair_false, s_any, s_integer, s_boolean); pl_buiui = s7_make_circular_signature(s7, 4, 5, s_boolean, s_pair_false, s_integer, s_pair_false, s_integer); pl_buuusuui = s7_make_circular_signature(s7, 7, 8, s_boolean, s_pair_false, s_pair_false, s_pair_false, s_string, s_pair_false, s_pair_false, s_integer); pl_buuit = s7_make_circular_signature(s7, 4, 5, s_boolean, s_pair_false, s_pair_false, s_integer, s_any); pl_butu = s7_make_circular_signature(s7, 3, 4, s_boolean, s_pair_false, s_any, s_pair_false); pl_buti = s7_make_circular_signature(s7, 3, 4, s_boolean, s_pair_false, s_any, s_integer); pl_butti = s7_make_circular_signature(s7, 4, 5, s_boolean, s_pair_false, s_any, s_any, s_integer); pl_busi = s7_make_circular_signature(s7, 3, 4, s_boolean, s_pair_false, s_string, s_integer); pl_busu = s7_make_circular_signature(s7, 3, 4, s_boolean, s_pair_false, s_string, s_pair_false); pl_bui = s7_make_circular_signature(s7, 2, 3, s_boolean, s_pair_false, s_integer); pl_bu = s7_make_circular_signature(s7, 1, 2, s_boolean, s_pair_false); pl_buuubu = s7_make_circular_signature(s7, 5, 6, s_boolean, s_pair_false, s_pair_false, s_pair_false, s_boolean, s_pair_false); pl_bus = s7_make_circular_signature(s7, 2, 3, s_boolean, s_pair_false, s_string); pl_buutuuiu = s7_make_circular_signature(s7, 7, 8, s_boolean, s_pair_false, s_pair_false, s_any, s_pair_false, s_pair_false, s_integer, s_pair_false); pl_but = s7_make_circular_signature(s7, 2, 3, s_boolean, s_pair_false, s_any); pl_bussu = s7_make_circular_signature(s7, 4, 5, s_boolean, s_pair_false, s_string, s_string, s_pair_false); pl_buib = s7_make_circular_signature(s7, 3, 4, s_boolean, s_pair_false, s_integer, s_boolean); pl_buiu = s7_make_circular_signature(s7, 3, 4, s_boolean, s_pair_false, s_integer, s_pair_false); pl_buiiu = s7_make_circular_signature(s7, 4, 5, s_boolean, s_pair_false, s_integer, s_integer, s_pair_false); pl_bub = s7_make_circular_signature(s7, 2, 3, s_boolean, s_pair_false, s_boolean); pl_buub = s7_make_circular_signature(s7, 3, 4, s_boolean, s_pair_false, s_pair_false, s_boolean); pl_pb = s7_make_circular_signature(s7, 1, 2, s_pair, s_boolean); pl_buuiiu = s7_make_circular_signature(s7, 5, 6, s_boolean, s_pair_false, s_pair_false, s_integer, s_integer, s_pair_false); pl_buui = s7_make_circular_signature(s7, 3, 4, s_boolean, s_pair_false, s_pair_false, s_integer); pl_buuui = s7_make_circular_signature(s7, 4, 5, s_boolean, s_pair_false, s_pair_false, s_pair_false, s_integer); pl_buus = s7_make_circular_signature(s7, 3, 4, s_boolean, s_pair_false, s_pair_false, s_string); pl_buurbr = s7_make_circular_signature(s7, 5, 6, s_boolean, s_pair_false, s_pair_false, s_real, s_boolean, s_real); pl_busiu = s7_make_circular_signature(s7, 4, 5, s_boolean, s_pair_false, s_string, s_integer, s_pair_false); pl_buttu = s7_make_circular_signature(s7, 4, 5, s_boolean, s_pair_false, s_any, s_any, s_pair_false); pl_buuub = s7_make_circular_signature(s7, 4, 5, s_boolean, s_pair_false, s_pair_false, s_pair_false, s_boolean); pl_buuuub = s7_make_circular_signature(s7, 5, 6, s_boolean, s_pair_false, s_pair_false, s_pair_false, s_pair_false, s_boolean); pl_busib = s7_make_circular_signature(s7, 4, 5, s_boolean, s_pair_false, s_string, s_integer, s_boolean); pl_buusib = s7_make_circular_signature(s7, 5, 6, s_boolean, s_pair_false, s_pair_false, s_string, s_integer, s_boolean); pl_iiit = s7_make_circular_signature(s7, 3, 4, s_integer, s_integer, s_integer, s_any); pl_iit = s7_make_circular_signature(s7, 2, 3, s_integer, s_integer, s_any); pl_isiiutttiiu = s7_make_circular_signature(s7, 10, 11, s_integer, s_string, s_integer, s_integer, s_pair_false, s_any, s_any, s_any, s_integer, s_integer, s_pair_false); pl_isi = s7_make_circular_signature(s7, 2, 3, s_integer, s_string, s_integer); pl_isit = s7_make_circular_signature(s7, 3, 4, s_integer, s_string, s_integer, s_any); pl_si = s7_make_circular_signature(s7, 1, 2, s_string, s_integer); pl_is = s7_make_circular_signature(s7, 1, 2, s_integer, s_string); pl_i = s7_make_circular_signature(s7, 0, 1, s_integer); pl_itiiub = s7_make_circular_signature(s7, 5, 6, s_integer, s_any, s_integer, s_integer, s_pair_false, s_boolean); pl_itsub = s7_make_circular_signature(s7, 4, 5, s_integer, s_any, s_string, s_pair_false, s_boolean); pl_itsttti = s7_make_circular_signature(s7, 6, 7, s_integer, s_any, s_string, s_any, s_any, s_any, s_integer); pl_itiiiut = s7_make_circular_signature(s7, 6, 7, s_integer, s_any, s_integer, s_integer, s_integer, s_pair_false, s_any); pl_tiu = s7_make_circular_signature(s7, 2, 3, s_any, s_integer, s_pair_false); pl_it = s7_make_circular_signature(s7, 1, 2, s_integer, s_any); pl_ti = s7_make_circular_signature(s7, 1, 2, s_any, s_integer); pl_iur = s7_make_circular_signature(s7, 2, 3, s_integer, s_pair_false, s_real); pl_iussitu = s7_make_circular_signature(s7, 6, 7, s_integer, s_pair_false, s_string, s_string, s_integer, s_any, s_pair_false); pl_iurrsiu = s7_make_circular_signature(s7, 6, 7, s_integer, s_pair_false, s_real, s_real, s_string, s_integer, s_pair_false); pl_iuut = s7_make_circular_signature(s7, 3, 4, s_integer, s_pair_false, s_pair_false, s_any); pl_iuuut = s7_make_circular_signature(s7, 4, 5, s_integer, s_pair_false, s_pair_false, s_pair_false, s_any); pl_pir = s7_make_circular_signature(s7, 2, 3, s_pair, s_integer, s_real); pl_iuisi = s7_make_circular_signature(s7, 4, 5, s_integer, s_pair_false, s_integer, s_string, s_integer); pl_pibi = s7_make_circular_signature(s7, 3, 4, s_pair, s_integer, s_boolean, s_integer); pl_iuuui = s7_make_circular_signature(s7, 4, 5, s_integer, s_pair_false, s_pair_false, s_pair_false, s_integer); pl_iuuuui = s7_make_circular_signature(s7, 5, 6, s_integer, s_pair_false, s_pair_false, s_pair_false, s_pair_false, s_integer); pl_ius = s7_make_circular_signature(s7, 2, 3, s_integer, s_pair_false, s_string); pl_iusi = s7_make_circular_signature(s7, 3, 4, s_integer, s_pair_false, s_string, s_integer); pl_iu = s7_make_circular_signature(s7, 1, 2, s_integer, s_pair_false); pl_iuiu = s7_make_circular_signature(s7, 3, 4, s_integer, s_pair_false, s_integer, s_pair_false); pl_iuui = s7_make_circular_signature(s7, 3, 4, s_integer, s_pair_false, s_pair_false, s_integer); pl_pi = s7_make_circular_signature(s7, 1, 2, s_pair, s_integer); pl_iui = s7_make_circular_signature(s7, 2, 3, s_integer, s_pair_false, s_integer); pl_iuisut = s7_make_circular_signature(s7, 5, 6, s_integer, s_pair_false, s_integer, s_string, s_pair_false, s_any); pl_piu = s7_make_circular_signature(s7, 2, 3, s_pair, s_integer, s_pair_false); pl_pit = s7_make_circular_signature(s7, 2, 3, s_pair, s_integer, s_any); pl_iuis = s7_make_circular_signature(s7, 3, 4, s_integer, s_pair_false, s_integer, s_string); pl_trrru = s7_make_circular_signature(s7, 4, 5, s_any, s_real, s_real, s_real, s_pair_false); pl_dusr = s7_make_circular_signature(s7, 3, 4, s_float, s_pair_false, s_string, s_real); pl_dust = s7_make_circular_signature(s7, 3, 4, s_float, s_pair_false, s_string, s_any); pl_dut = s7_make_circular_signature(s7, 2, 3, s_float, s_pair_false, s_any); pl_du = s7_make_circular_signature(s7, 1, 2, s_float, s_pair_false); pl_dus = s7_make_circular_signature(s7, 2, 3, s_float, s_pair_false, s_string); pl_pr = s7_make_circular_signature(s7, 1, 2, s_pair, s_real); pl_ssi = s7_make_circular_signature(s7, 2, 3, s_string, s_string, s_integer); pl_s = s7_make_circular_signature(s7, 0, 1, s_string); pl_unused = NULL; #endif Xg_define_procedure(g_unichar_validate, gxg_g_unichar_validate_w, 1, 0, 0, H_g_unichar_validate, pl_bi); Xg_define_procedure(g_unichar_isalnum, gxg_g_unichar_isalnum_w, 1, 0, 0, H_g_unichar_isalnum, pl_bi); Xg_define_procedure(g_unichar_isalpha, gxg_g_unichar_isalpha_w, 1, 0, 0, H_g_unichar_isalpha, pl_bi); Xg_define_procedure(g_unichar_iscntrl, gxg_g_unichar_iscntrl_w, 1, 0, 0, H_g_unichar_iscntrl, pl_bi); Xg_define_procedure(g_unichar_isdefined, gxg_g_unichar_isdefined_w, 1, 0, 0, H_g_unichar_isdefined, pl_bi); Xg_define_procedure(g_unichar_isdigit, gxg_g_unichar_isdigit_w, 1, 0, 0, H_g_unichar_isdigit, pl_bi); Xg_define_procedure(g_unichar_isgraph, gxg_g_unichar_isgraph_w, 1, 0, 0, H_g_unichar_isgraph, pl_bi); Xg_define_procedure(g_unichar_islower, gxg_g_unichar_islower_w, 1, 0, 0, H_g_unichar_islower, pl_bi); Xg_define_procedure(g_unichar_ismark, gxg_g_unichar_ismark_w, 1, 0, 0, H_g_unichar_ismark, pl_bi); Xg_define_procedure(g_unichar_isprint, gxg_g_unichar_isprint_w, 1, 0, 0, H_g_unichar_isprint, pl_bi); Xg_define_procedure(g_unichar_ispunct, gxg_g_unichar_ispunct_w, 1, 0, 0, H_g_unichar_ispunct, pl_bi); Xg_define_procedure(g_unichar_isspace, gxg_g_unichar_isspace_w, 1, 0, 0, H_g_unichar_isspace, pl_bi); Xg_define_procedure(g_unichar_istitle, gxg_g_unichar_istitle_w, 1, 0, 0, H_g_unichar_istitle, pl_bi); Xg_define_procedure(g_unichar_isupper, gxg_g_unichar_isupper_w, 1, 0, 0, H_g_unichar_isupper, pl_bi); Xg_define_procedure(g_unichar_isxdigit, gxg_g_unichar_isxdigit_w, 1, 0, 0, H_g_unichar_isxdigit, pl_bi); Xg_define_procedure(g_unichar_iswide, gxg_g_unichar_iswide_w, 1, 0, 0, H_g_unichar_iswide, pl_bi); Xg_define_procedure(g_unichar_iswide_cjk, gxg_g_unichar_iswide_cjk_w, 1, 0, 0, H_g_unichar_iswide_cjk, pl_bi); Xg_define_procedure(g_unichar_iszerowidth, gxg_g_unichar_iszerowidth_w, 1, 0, 0, H_g_unichar_iszerowidth, pl_bi); Xg_define_procedure(g_unichar_toupper, gxg_g_unichar_toupper_w, 1, 0, 0, H_g_unichar_toupper, pl_i); Xg_define_procedure(g_unichar_tolower, gxg_g_unichar_tolower_w, 1, 0, 0, H_g_unichar_tolower, pl_i); Xg_define_procedure(g_unichar_totitle, gxg_g_unichar_totitle_w, 1, 0, 0, H_g_unichar_totitle, pl_i); Xg_define_procedure(g_unichar_digit_value, gxg_g_unichar_digit_value_w, 1, 0, 0, H_g_unichar_digit_value, pl_i); Xg_define_procedure(g_unichar_xdigit_value, gxg_g_unichar_xdigit_value_w, 1, 0, 0, H_g_unichar_xdigit_value, pl_i); Xg_define_procedure(g_unichar_combining_class, gxg_g_unichar_combining_class_w, 1, 0, 0, H_g_unichar_combining_class, pl_i); Xg_define_procedure(g_unicode_canonical_ordering, gxg_g_unicode_canonical_ordering_w, 2, 0, 0, H_g_unicode_canonical_ordering, pl_tsi); Xg_define_procedure(g_utf8_get_char, gxg_g_utf8_get_char_w, 1, 0, 0, H_g_utf8_get_char, pl_is); Xg_define_procedure(g_utf8_get_char_validated, gxg_g_utf8_get_char_validated_w, 2, 0, 0, H_g_utf8_get_char_validated, pl_isi); Xg_define_procedure(g_utf8_prev_char, gxg_g_utf8_prev_char_w, 1, 0, 0, H_g_utf8_prev_char, pl_s); Xg_define_procedure(g_utf8_find_next_char, gxg_g_utf8_find_next_char_w, 2, 0, 0, H_g_utf8_find_next_char, pl_s); Xg_define_procedure(g_utf8_find_prev_char, gxg_g_utf8_find_prev_char_w, 2, 0, 0, H_g_utf8_find_prev_char, pl_s); Xg_define_procedure(g_utf8_strlen, gxg_g_utf8_strlen_w, 2, 0, 0, H_g_utf8_strlen, pl_isi); Xg_define_procedure(g_utf8_strchr, gxg_g_utf8_strchr_w, 3, 0, 0, H_g_utf8_strchr, pl_ssi); Xg_define_procedure(g_utf8_strrchr, gxg_g_utf8_strrchr_w, 3, 0, 0, H_g_utf8_strrchr, pl_ssi); Xg_define_procedure(g_utf8_strreverse, gxg_g_utf8_strreverse_w, 2, 0, 0, H_g_utf8_strreverse, pl_ssi); Xg_define_procedure(g_utf8_validate, gxg_g_utf8_validate_w, 2, 1, 0, H_g_utf8_validate, pl_bsiu); Xg_define_procedure(g_utf8_strup, gxg_g_utf8_strup_w, 2, 0, 0, H_g_utf8_strup, pl_ssi); Xg_define_procedure(g_utf8_strdown, gxg_g_utf8_strdown_w, 2, 0, 0, H_g_utf8_strdown, pl_ssi); Xg_define_procedure(g_utf8_casefold, gxg_g_utf8_casefold_w, 2, 0, 0, H_g_utf8_casefold, pl_ssi); Xg_define_procedure(g_utf8_normalize, gxg_g_utf8_normalize_w, 3, 0, 0, H_g_utf8_normalize, pl_ssi); Xg_define_procedure(g_utf8_collate, gxg_g_utf8_collate_w, 2, 0, 0, H_g_utf8_collate, pl_is); Xg_define_procedure(g_utf8_collate_key, gxg_g_utf8_collate_key_w, 2, 0, 0, H_g_utf8_collate_key, pl_ssi); Xg_define_procedure(g_utf8_collate_key_for_filename, gxg_g_utf8_collate_key_for_filename_w, 2, 0, 0, H_g_utf8_collate_key_for_filename, pl_ssi); Xg_define_procedure(g_cclosure_new, gxg_g_cclosure_new_w, 3, 0, 0, H_g_cclosure_new, pl_pt); Xg_define_procedure(g_signal_newv, gxg_g_signal_newv_w, 0, 0, 1, H_g_signal_newv, pl_isiiutttiiu); Xg_define_procedure(g_signal_lookup, gxg_g_signal_lookup_w, 2, 0, 0, H_g_signal_lookup, pl_isi); Xg_define_procedure(g_signal_name, gxg_g_signal_name_w, 1, 0, 0, H_g_signal_name, pl_si); Xg_define_procedure(g_signal_query, gxg_g_signal_query_w, 2, 0, 0, H_g_signal_query, pl_tiu); Xg_define_procedure(g_signal_list_ids, gxg_g_signal_list_ids_w, 2, 0, 0, H_g_signal_list_ids, pl_piu); Xg_define_procedure(g_signal_parse_name, gxg_g_signal_parse_name_w, 3, 2, 0, H_g_signal_parse_name, pl_bsiuub); Xg_define_procedure(g_signal_get_invocation_hint, gxg_g_signal_get_invocation_hint_w, 1, 0, 0, H_g_signal_get_invocation_hint, pl_pt); Xg_define_procedure(g_signal_stop_emission, gxg_g_signal_stop_emission_w, 3, 0, 0, H_g_signal_stop_emission, pl_tti); Xg_define_procedure(g_signal_stop_emission_by_name, gxg_g_signal_stop_emission_by_name_w, 2, 0, 0, H_g_signal_stop_emission_by_name, pl_tts); Xg_define_procedure(g_signal_add_emission_hook, gxg_g_signal_add_emission_hook_w, 5, 0, 0, H_g_signal_add_emission_hook, pl_iiit); Xg_define_procedure(g_signal_remove_emission_hook, gxg_g_signal_remove_emission_hook_w, 2, 0, 0, H_g_signal_remove_emission_hook, pl_ti); Xg_define_procedure(g_signal_has_handler_pending, gxg_g_signal_has_handler_pending_w, 4, 0, 0, H_g_signal_has_handler_pending, pl_btiib); Xg_define_procedure(g_signal_connect_closure_by_id, gxg_g_signal_connect_closure_by_id_w, 5, 0, 0, H_g_signal_connect_closure_by_id, pl_itiiub); Xg_define_procedure(g_signal_connect_closure, gxg_g_signal_connect_closure_w, 4, 0, 0, H_g_signal_connect_closure, pl_itsub); Xg_define_procedure(g_signal_connect_data, gxg_g_signal_connect_data_w, 6, 0, 0, H_g_signal_connect_data, pl_itsttti); Xg_define_procedure(g_signal_handler_block, gxg_g_signal_handler_block_w, 2, 0, 0, H_g_signal_handler_block, pl_tti); Xg_define_procedure(g_signal_handler_unblock, gxg_g_signal_handler_unblock_w, 2, 0, 0, H_g_signal_handler_unblock, pl_tti); Xg_define_procedure(g_signal_handler_disconnect, gxg_g_signal_handler_disconnect_w, 2, 0, 0, H_g_signal_handler_disconnect, pl_tti); Xg_define_procedure(g_signal_handler_is_connected, gxg_g_signal_handler_is_connected_w, 2, 0, 0, H_g_signal_handler_is_connected, pl_bti); Xg_define_procedure(g_signal_handler_find, gxg_g_signal_handler_find_w, 7, 0, 0, H_g_signal_handler_find, pl_itiiiut); Xg_define_procedure(g_signal_handlers_block_matched, gxg_g_signal_handlers_block_matched_w, 7, 0, 0, H_g_signal_handlers_block_matched, pl_itiiiut); Xg_define_procedure(g_signal_handlers_unblock_matched, gxg_g_signal_handlers_unblock_matched_w, 7, 0, 0, H_g_signal_handlers_unblock_matched, pl_itiiiut); Xg_define_procedure(g_signal_handlers_disconnect_matched, gxg_g_signal_handlers_disconnect_matched_w, 7, 0, 0, H_g_signal_handlers_disconnect_matched, pl_itiiiut); Xg_define_procedure(g_signal_handlers_destroy, gxg_g_signal_handlers_destroy_w, 1, 0, 0, H_g_signal_handlers_destroy, pl_t); Xg_define_procedure(g_object_ref, gxg_g_object_ref_w, 1, 0, 0, H_g_object_ref, pl_t); Xg_define_procedure(g_object_unref, gxg_g_object_unref_w, 1, 0, 0, H_g_object_unref, pl_t); Xg_define_procedure(gdk_visual_get_system, gxg_gdk_visual_get_system_w, 0, 0, 0, H_gdk_visual_get_system, pl_p); Xg_define_procedure(gdk_cursor_new_for_display, gxg_gdk_cursor_new_for_display_w, 2, 0, 0, H_gdk_cursor_new_for_display, pl_pui); Xg_define_procedure(gdk_cursor_get_display, gxg_gdk_cursor_get_display_w, 1, 0, 0, H_gdk_cursor_get_display, pl_pu); Xg_define_procedure(gdk_drag_status, gxg_gdk_drag_status_w, 3, 0, 0, H_gdk_drag_status, pl_tui); Xg_define_procedure(gdk_drop_reply, gxg_gdk_drop_reply_w, 3, 0, 0, H_gdk_drop_reply, pl_tubi); Xg_define_procedure(gdk_drop_finish, gxg_gdk_drop_finish_w, 3, 0, 0, H_gdk_drop_finish, pl_tubi); Xg_define_procedure(gdk_drag_get_selection, gxg_gdk_drag_get_selection_w, 1, 0, 0, H_gdk_drag_get_selection, pl_tu); Xg_define_procedure(gdk_drag_begin, gxg_gdk_drag_begin_w, 2, 0, 0, H_gdk_drag_begin, pl_pu); Xg_define_procedure(gdk_drag_drop, gxg_gdk_drag_drop_w, 2, 0, 0, H_gdk_drag_drop, pl_tui); Xg_define_procedure(gdk_drag_abort, gxg_gdk_drag_abort_w, 2, 0, 0, H_gdk_drag_abort, pl_tui); Xg_define_procedure(gdk_events_pending, gxg_gdk_events_pending_w, 0, 0, 0, H_gdk_events_pending, pl_b); Xg_define_procedure(gdk_event_get, gxg_gdk_event_get_w, 0, 0, 0, H_gdk_event_get, pl_p); Xg_define_procedure(gdk_event_peek, gxg_gdk_event_peek_w, 0, 0, 0, H_gdk_event_peek, pl_p); Xg_define_procedure(gdk_event_put, gxg_gdk_event_put_w, 1, 0, 0, H_gdk_event_put, pl_tu); Xg_define_procedure(gdk_event_copy, gxg_gdk_event_copy_w, 1, 0, 0, H_gdk_event_copy, pl_pu); Xg_define_procedure(gdk_event_free, gxg_gdk_event_free_w, 1, 0, 0, H_gdk_event_free, pl_tu); Xg_define_procedure(gdk_event_get_time, gxg_gdk_event_get_time_w, 1, 0, 0, H_gdk_event_get_time, pl_iu); Xg_define_procedure(gdk_event_get_state, gxg_gdk_event_get_state_w, 1, 1, 0, H_gdk_event_get_state, pl_bu); Xg_define_procedure(gdk_event_get_coords, gxg_gdk_event_get_coords_w, 1, 2, 0, H_gdk_event_get_coords, pl_bu); Xg_define_procedure(gdk_event_get_root_coords, gxg_gdk_event_get_root_coords_w, 1, 2, 0, H_gdk_event_get_root_coords, pl_bu); Xg_define_procedure(gdk_event_handler_set, gxg_gdk_event_handler_set_w, 3, 0, 0, H_gdk_event_handler_set, pl_t); Xg_define_procedure(gdk_set_show_events, gxg_gdk_set_show_events_w, 1, 0, 0, H_gdk_set_show_events, pl_tb); Xg_define_procedure(gdk_get_show_events, gxg_gdk_get_show_events_w, 0, 0, 0, H_gdk_get_show_events, pl_b); Xg_define_procedure(gdk_init, gxg_gdk_init_w, 0, 2, 0, H_gdk_init, pl_tu); Xg_define_procedure(gdk_init_check, gxg_gdk_init_check_w, 0, 2, 0, H_gdk_init_check, pl_bu); Xg_define_procedure(gdk_get_program_class, gxg_gdk_get_program_class_w, 0, 0, 0, H_gdk_get_program_class, pl_s); Xg_define_procedure(gdk_set_program_class, gxg_gdk_set_program_class_w, 1, 0, 0, H_gdk_set_program_class, pl_ts); Xg_define_procedure(gdk_error_trap_push, gxg_gdk_error_trap_push_w, 0, 0, 0, H_gdk_error_trap_push, pl_t); Xg_define_procedure(gdk_error_trap_pop, gxg_gdk_error_trap_pop_w, 0, 0, 0, H_gdk_error_trap_pop, pl_i); Xg_define_procedure(gdk_get_display_arg_name, gxg_gdk_get_display_arg_name_w, 0, 0, 0, H_gdk_get_display_arg_name, pl_s); Xg_define_procedure(gdk_notify_startup_complete, gxg_gdk_notify_startup_complete_w, 0, 0, 0, H_gdk_notify_startup_complete, pl_t); Xg_define_procedure(gdk_screen_width, gxg_gdk_screen_width_w, 0, 0, 0, H_gdk_screen_width, pl_i); Xg_define_procedure(gdk_screen_height, gxg_gdk_screen_height_w, 0, 0, 0, H_gdk_screen_height, pl_i); Xg_define_procedure(gdk_screen_width_mm, gxg_gdk_screen_width_mm_w, 0, 0, 0, H_gdk_screen_width_mm, pl_i); Xg_define_procedure(gdk_screen_height_mm, gxg_gdk_screen_height_mm_w, 0, 0, 0, H_gdk_screen_height_mm, pl_i); Xg_define_procedure(gdk_flush, gxg_gdk_flush_w, 0, 0, 0, H_gdk_flush, pl_t); Xg_define_procedure(gdk_beep, gxg_gdk_beep_w, 0, 0, 0, H_gdk_beep, pl_t); Xg_define_procedure(gdk_set_double_click_time, gxg_gdk_set_double_click_time_w, 1, 0, 0, H_gdk_set_double_click_time, pl_ti); Xg_define_procedure(gdk_rectangle_intersect, gxg_gdk_rectangle_intersect_w, 3, 0, 0, H_gdk_rectangle_intersect, pl_bu); Xg_define_procedure(gdk_rectangle_union, gxg_gdk_rectangle_union_w, 3, 0, 0, H_gdk_rectangle_union, pl_tu); Xg_define_procedure(gdk_keymap_get_default, gxg_gdk_keymap_get_default_w, 0, 0, 0, H_gdk_keymap_get_default, pl_p); Xg_define_procedure(gdk_keymap_lookup_key, gxg_gdk_keymap_lookup_key_w, 2, 0, 0, H_gdk_keymap_lookup_key, pl_iu); Xg_define_procedure(gdk_keymap_get_entries_for_keyval, gxg_gdk_keymap_get_entries_for_keyval_w, 2, 2, 0, H_gdk_keymap_get_entries_for_keyval, pl_buiu); Xg_define_procedure(gdk_keymap_get_entries_for_keycode, gxg_gdk_keymap_get_entries_for_keycode_w, 2, 3, 0, H_gdk_keymap_get_entries_for_keycode, pl_buiu); Xg_define_procedure(gdk_keymap_get_direction, gxg_gdk_keymap_get_direction_w, 1, 0, 0, H_gdk_keymap_get_direction, pl_iu); Xg_define_procedure(gdk_keyval_name, gxg_gdk_keyval_name_w, 1, 0, 0, H_gdk_keyval_name, pl_si); Xg_define_procedure(gdk_keyval_from_name, gxg_gdk_keyval_from_name_w, 1, 0, 0, H_gdk_keyval_from_name, pl_is); Xg_define_procedure(gdk_keyval_convert_case, gxg_gdk_keyval_convert_case_w, 1, 2, 0, H_gdk_keyval_convert_case, pl_tiu); Xg_define_procedure(gdk_keyval_to_upper, gxg_gdk_keyval_to_upper_w, 1, 0, 0, H_gdk_keyval_to_upper, pl_i); Xg_define_procedure(gdk_keyval_to_lower, gxg_gdk_keyval_to_lower_w, 1, 0, 0, H_gdk_keyval_to_lower, pl_i); Xg_define_procedure(gdk_keyval_is_upper, gxg_gdk_keyval_is_upper_w, 1, 0, 0, H_gdk_keyval_is_upper, pl_bi); Xg_define_procedure(gdk_keyval_is_lower, gxg_gdk_keyval_is_lower_w, 1, 0, 0, H_gdk_keyval_is_lower, pl_bi); Xg_define_procedure(gdk_keyval_to_unicode, gxg_gdk_keyval_to_unicode_w, 1, 0, 0, H_gdk_keyval_to_unicode, pl_i); Xg_define_procedure(gdk_unicode_to_keyval, gxg_gdk_unicode_to_keyval_w, 1, 0, 0, H_gdk_unicode_to_keyval, pl_i); Xg_define_procedure(gdk_pango_context_get, gxg_gdk_pango_context_get_w, 0, 0, 0, H_gdk_pango_context_get, pl_p); Xg_define_procedure(gdk_atom_intern, gxg_gdk_atom_intern_w, 2, 0, 0, H_gdk_atom_intern, pl_tsb); Xg_define_procedure(gdk_atom_name, gxg_gdk_atom_name_w, 1, 0, 0, H_gdk_atom_name, pl_st); Xg_define_procedure(gdk_property_get, gxg_gdk_property_get_w, 0, 0, 1, H_gdk_property_get, pl_buttiiiu); Xg_define_procedure(gdk_property_change, gxg_gdk_property_change_w, 7, 0, 0, H_gdk_property_change, pl_tuttiisi); Xg_define_procedure(gdk_property_delete, gxg_gdk_property_delete_w, 2, 0, 0, H_gdk_property_delete, pl_tut); Xg_define_procedure(gdk_utf8_to_string_target, gxg_gdk_utf8_to_string_target_w, 1, 0, 0, H_gdk_utf8_to_string_target, pl_s); Xg_define_procedure(gdk_selection_owner_set, gxg_gdk_selection_owner_set_w, 4, 0, 0, H_gdk_selection_owner_set, pl_butib); Xg_define_procedure(gdk_selection_owner_get, gxg_gdk_selection_owner_get_w, 1, 0, 0, H_gdk_selection_owner_get, pl_pt); Xg_define_procedure(gdk_selection_convert, gxg_gdk_selection_convert_w, 4, 0, 0, H_gdk_selection_convert, pl_tutti); Xg_define_procedure(gdk_selection_property_get, gxg_gdk_selection_property_get_w, 1, 3, 0, H_gdk_selection_property_get, pl_bu); Xg_define_procedure(gdk_visual_get_best_depth, gxg_gdk_visual_get_best_depth_w, 0, 0, 0, H_gdk_visual_get_best_depth, pl_i); Xg_define_procedure(gdk_visual_get_best_type, gxg_gdk_visual_get_best_type_w, 0, 0, 0, H_gdk_visual_get_best_type, pl_i); Xg_define_procedure(gdk_visual_get_best, gxg_gdk_visual_get_best_w, 0, 0, 0, H_gdk_visual_get_best, pl_p); Xg_define_procedure(gdk_visual_get_best_with_depth, gxg_gdk_visual_get_best_with_depth_w, 1, 0, 0, H_gdk_visual_get_best_with_depth, pl_pi); Xg_define_procedure(gdk_visual_get_best_with_type, gxg_gdk_visual_get_best_with_type_w, 1, 0, 0, H_gdk_visual_get_best_with_type, pl_pi); Xg_define_procedure(gdk_visual_get_best_with_both, gxg_gdk_visual_get_best_with_both_w, 2, 0, 0, H_gdk_visual_get_best_with_both, pl_pi); Xg_define_procedure(gdk_query_depths, gxg_gdk_query_depths_w, 0, 2, 0, H_gdk_query_depths, pl_tu); Xg_define_procedure(gdk_query_visual_types, gxg_gdk_query_visual_types_w, 0, 2, 0, H_gdk_query_visual_types, pl_tu); Xg_define_procedure(gdk_list_visuals, gxg_gdk_list_visuals_w, 0, 0, 0, H_gdk_list_visuals, pl_p); Xg_define_procedure(gdk_window_new, gxg_gdk_window_new_w, 3, 0, 0, H_gdk_window_new, pl_puui); Xg_define_procedure(gdk_window_destroy, gxg_gdk_window_destroy_w, 1, 0, 0, H_gdk_window_destroy, pl_tu); Xg_define_procedure(gdk_window_get_window_type, gxg_gdk_window_get_window_type_w, 1, 0, 0, H_gdk_window_get_window_type, pl_iu); Xg_define_procedure(gdk_window_show, gxg_gdk_window_show_w, 1, 0, 0, H_gdk_window_show, pl_tu); Xg_define_procedure(gdk_window_hide, gxg_gdk_window_hide_w, 1, 0, 0, H_gdk_window_hide, pl_tu); Xg_define_procedure(gdk_window_withdraw, gxg_gdk_window_withdraw_w, 1, 0, 0, H_gdk_window_withdraw, pl_tu); Xg_define_procedure(gdk_window_show_unraised, gxg_gdk_window_show_unraised_w, 1, 0, 0, H_gdk_window_show_unraised, pl_tu); Xg_define_procedure(gdk_window_move, gxg_gdk_window_move_w, 3, 0, 0, H_gdk_window_move, pl_tui); Xg_define_procedure(gdk_window_resize, gxg_gdk_window_resize_w, 3, 0, 0, H_gdk_window_resize, pl_tui); Xg_define_procedure(gdk_window_move_resize, gxg_gdk_window_move_resize_w, 5, 0, 0, H_gdk_window_move_resize, pl_tui); Xg_define_procedure(gdk_window_reparent, gxg_gdk_window_reparent_w, 4, 0, 0, H_gdk_window_reparent, pl_tuui); Xg_define_procedure(gdk_window_raise, gxg_gdk_window_raise_w, 1, 0, 0, H_gdk_window_raise, pl_tu); Xg_define_procedure(gdk_window_lower, gxg_gdk_window_lower_w, 1, 0, 0, H_gdk_window_lower, pl_tu); Xg_define_procedure(gdk_window_focus, gxg_gdk_window_focus_w, 2, 0, 0, H_gdk_window_focus, pl_tui); Xg_define_procedure(gdk_window_set_user_data, gxg_gdk_window_set_user_data_w, 2, 0, 0, H_gdk_window_set_user_data, pl_tut); Xg_define_procedure(gdk_window_set_override_redirect, gxg_gdk_window_set_override_redirect_w, 2, 0, 0, H_gdk_window_set_override_redirect, pl_tub); Xg_define_procedure(gdk_window_add_filter, gxg_gdk_window_add_filter_w, 2, 1, 0, H_gdk_window_add_filter, pl_tut); Xg_define_procedure(gdk_window_remove_filter, gxg_gdk_window_remove_filter_w, 2, 1, 0, H_gdk_window_remove_filter, pl_tut); Xg_define_procedure(gdk_window_scroll, gxg_gdk_window_scroll_w, 3, 0, 0, H_gdk_window_scroll, pl_tui); Xg_define_procedure(gdk_window_set_child_shapes, gxg_gdk_window_set_child_shapes_w, 1, 0, 0, H_gdk_window_set_child_shapes, pl_tu); Xg_define_procedure(gdk_window_merge_child_shapes, gxg_gdk_window_merge_child_shapes_w, 1, 0, 0, H_gdk_window_merge_child_shapes, pl_tu); Xg_define_procedure(gdk_window_is_visible, gxg_gdk_window_is_visible_w, 1, 0, 0, H_gdk_window_is_visible, pl_bu); Xg_define_procedure(gdk_window_is_viewable, gxg_gdk_window_is_viewable_w, 1, 0, 0, H_gdk_window_is_viewable, pl_bu); Xg_define_procedure(gdk_window_get_state, gxg_gdk_window_get_state_w, 1, 0, 0, H_gdk_window_get_state, pl_iu); Xg_define_procedure(gdk_window_get_root_origin, gxg_gdk_window_get_root_origin_w, 1, 2, 0, H_gdk_window_get_root_origin, pl_tu); Xg_define_procedure(gdk_window_get_frame_extents, gxg_gdk_window_get_frame_extents_w, 2, 0, 0, H_gdk_window_get_frame_extents, pl_tu); Xg_define_procedure(gdk_window_get_parent, gxg_gdk_window_get_parent_w, 1, 0, 0, H_gdk_window_get_parent, pl_pu); Xg_define_procedure(gdk_window_get_toplevel, gxg_gdk_window_get_toplevel_w, 1, 0, 0, H_gdk_window_get_toplevel, pl_pu); Xg_define_procedure(gdk_window_get_children, gxg_gdk_window_get_children_w, 1, 0, 0, H_gdk_window_get_children, pl_pu); Xg_define_procedure(gdk_window_peek_children, gxg_gdk_window_peek_children_w, 1, 0, 0, H_gdk_window_peek_children, pl_pu); Xg_define_procedure(gdk_window_get_events, gxg_gdk_window_get_events_w, 1, 0, 0, H_gdk_window_get_events, pl_iu); Xg_define_procedure(gdk_window_set_events, gxg_gdk_window_set_events_w, 2, 0, 0, H_gdk_window_set_events, pl_tui); Xg_define_procedure(gdk_window_set_icon_list, gxg_gdk_window_set_icon_list_w, 2, 0, 0, H_gdk_window_set_icon_list, pl_tu); Xg_define_procedure(gdk_window_set_icon_name, gxg_gdk_window_set_icon_name_w, 2, 0, 0, H_gdk_window_set_icon_name, pl_tus); Xg_define_procedure(gdk_window_set_group, gxg_gdk_window_set_group_w, 2, 0, 0, H_gdk_window_set_group, pl_tu); Xg_define_procedure(gdk_window_set_decorations, gxg_gdk_window_set_decorations_w, 2, 0, 0, H_gdk_window_set_decorations, pl_tui); Xg_define_procedure(gdk_window_get_decorations, gxg_gdk_window_get_decorations_w, 1, 1, 0, H_gdk_window_get_decorations, pl_bu); Xg_define_procedure(gdk_window_set_functions, gxg_gdk_window_set_functions_w, 2, 0, 0, H_gdk_window_set_functions, pl_tui); Xg_define_procedure(gdk_window_iconify, gxg_gdk_window_iconify_w, 1, 0, 0, H_gdk_window_iconify, pl_tu); Xg_define_procedure(gdk_window_deiconify, gxg_gdk_window_deiconify_w, 1, 0, 0, H_gdk_window_deiconify, pl_tu); Xg_define_procedure(gdk_window_stick, gxg_gdk_window_stick_w, 1, 0, 0, H_gdk_window_stick, pl_tu); Xg_define_procedure(gdk_window_unstick, gxg_gdk_window_unstick_w, 1, 0, 0, H_gdk_window_unstick, pl_tu); Xg_define_procedure(gdk_window_maximize, gxg_gdk_window_maximize_w, 1, 0, 0, H_gdk_window_maximize, pl_tu); Xg_define_procedure(gdk_window_unmaximize, gxg_gdk_window_unmaximize_w, 1, 0, 0, H_gdk_window_unmaximize, pl_tu); Xg_define_procedure(gdk_window_register_dnd, gxg_gdk_window_register_dnd_w, 1, 0, 0, H_gdk_window_register_dnd, pl_tu); Xg_define_procedure(gdk_window_begin_resize_drag, gxg_gdk_window_begin_resize_drag_w, 6, 0, 0, H_gdk_window_begin_resize_drag, pl_tui); Xg_define_procedure(gdk_window_begin_move_drag, gxg_gdk_window_begin_move_drag_w, 5, 0, 0, H_gdk_window_begin_move_drag, pl_tui); Xg_define_procedure(gdk_window_invalidate_rect, gxg_gdk_window_invalidate_rect_w, 3, 0, 0, H_gdk_window_invalidate_rect, pl_tuub); Xg_define_procedure(gdk_window_freeze_updates, gxg_gdk_window_freeze_updates_w, 1, 0, 0, H_gdk_window_freeze_updates, pl_tu); Xg_define_procedure(gdk_window_thaw_updates, gxg_gdk_window_thaw_updates_w, 1, 0, 0, H_gdk_window_thaw_updates, pl_tu); Xg_define_procedure(gdk_window_process_all_updates, gxg_gdk_window_process_all_updates_w, 0, 0, 0, H_gdk_window_process_all_updates, pl_t); Xg_define_procedure(gdk_window_process_updates, gxg_gdk_window_process_updates_w, 2, 0, 0, H_gdk_window_process_updates, pl_tub); Xg_define_procedure(gdk_window_set_debug_updates, gxg_gdk_window_set_debug_updates_w, 1, 0, 0, H_gdk_window_set_debug_updates, pl_tb); Xg_define_procedure(gdk_window_constrain_size, gxg_gdk_window_constrain_size_w, 4, 2, 0, H_gdk_window_constrain_size, pl_tuiiiu); Xg_define_procedure(gdk_window_set_type_hint, gxg_gdk_window_set_type_hint_w, 2, 0, 0, H_gdk_window_set_type_hint, pl_tui); Xg_define_procedure(gdk_window_set_modal_hint, gxg_gdk_window_set_modal_hint_w, 2, 0, 0, H_gdk_window_set_modal_hint, pl_tub); Xg_define_procedure(gdk_window_set_geometry_hints, gxg_gdk_window_set_geometry_hints_w, 3, 0, 0, H_gdk_window_set_geometry_hints, pl_tuui); Xg_define_procedure(gdk_window_begin_paint_rect, gxg_gdk_window_begin_paint_rect_w, 2, 0, 0, H_gdk_window_begin_paint_rect, pl_tu); Xg_define_procedure(gdk_window_end_paint, gxg_gdk_window_end_paint_w, 1, 0, 0, H_gdk_window_end_paint, pl_tu); Xg_define_procedure(gdk_window_set_title, gxg_gdk_window_set_title_w, 2, 0, 0, H_gdk_window_set_title, pl_tus); Xg_define_procedure(gdk_window_set_role, gxg_gdk_window_set_role_w, 2, 0, 0, H_gdk_window_set_role, pl_tus); Xg_define_procedure(gdk_window_set_transient_for, gxg_gdk_window_set_transient_for_w, 2, 0, 0, H_gdk_window_set_transient_for, pl_tu); Xg_define_procedure(gdk_window_set_cursor, gxg_gdk_window_set_cursor_w, 2, 0, 0, H_gdk_window_set_cursor, pl_tu); Xg_define_procedure(gdk_window_get_user_data, gxg_gdk_window_get_user_data_w, 1, 1, 0, H_gdk_window_get_user_data, pl_tu); Xg_define_procedure(gdk_window_get_position, gxg_gdk_window_get_position_w, 1, 2, 0, H_gdk_window_get_position, pl_tu); Xg_define_procedure(gdk_window_get_origin, gxg_gdk_window_get_origin_w, 1, 2, 0, H_gdk_window_get_origin, pl_iu); Xg_define_procedure(gdk_get_default_root_window, gxg_gdk_get_default_root_window_w, 0, 0, 0, H_gdk_get_default_root_window, pl_p); Xg_define_procedure(gdk_pixbuf_error_quark, gxg_gdk_pixbuf_error_quark_w, 0, 0, 0, H_gdk_pixbuf_error_quark, pl_i); Xg_define_procedure(gdk_pixbuf_get_colorspace, gxg_gdk_pixbuf_get_colorspace_w, 1, 0, 0, H_gdk_pixbuf_get_colorspace, pl_iu); Xg_define_procedure(gdk_pixbuf_get_n_channels, gxg_gdk_pixbuf_get_n_channels_w, 1, 0, 0, H_gdk_pixbuf_get_n_channels, pl_iu); Xg_define_procedure(gdk_pixbuf_get_has_alpha, gxg_gdk_pixbuf_get_has_alpha_w, 1, 0, 0, H_gdk_pixbuf_get_has_alpha, pl_bu); Xg_define_procedure(gdk_pixbuf_get_bits_per_sample, gxg_gdk_pixbuf_get_bits_per_sample_w, 1, 0, 0, H_gdk_pixbuf_get_bits_per_sample, pl_iu); Xg_define_procedure(gdk_pixbuf_get_pixels, gxg_gdk_pixbuf_get_pixels_w, 1, 0, 0, H_gdk_pixbuf_get_pixels, pl_su); Xg_define_procedure(gdk_pixbuf_get_width, gxg_gdk_pixbuf_get_width_w, 1, 0, 0, H_gdk_pixbuf_get_width, pl_iu); Xg_define_procedure(gdk_pixbuf_get_height, gxg_gdk_pixbuf_get_height_w, 1, 0, 0, H_gdk_pixbuf_get_height, pl_iu); Xg_define_procedure(gdk_pixbuf_get_rowstride, gxg_gdk_pixbuf_get_rowstride_w, 1, 0, 0, H_gdk_pixbuf_get_rowstride, pl_iu); Xg_define_procedure(gdk_pixbuf_new, gxg_gdk_pixbuf_new_w, 5, 0, 0, H_gdk_pixbuf_new, pl_pibi); Xg_define_procedure(gdk_pixbuf_copy, gxg_gdk_pixbuf_copy_w, 1, 0, 0, H_gdk_pixbuf_copy, pl_pu); Xg_define_procedure(gdk_pixbuf_new_subpixbuf, gxg_gdk_pixbuf_new_subpixbuf_w, 5, 0, 0, H_gdk_pixbuf_new_subpixbuf, pl_pui); Xg_define_procedure(gdk_pixbuf_new_from_file, gxg_gdk_pixbuf_new_from_file_w, 1, 1, 0, H_gdk_pixbuf_new_from_file, pl_psu); Xg_define_procedure(gdk_pixbuf_new_from_data, gxg_gdk_pixbuf_new_from_data_w, 0, 0, 1, H_gdk_pixbuf_new_from_data, pl_psibiiiit); Xg_define_procedure(gdk_pixbuf_new_from_xpm_data, gxg_gdk_pixbuf_new_from_xpm_data_w, 1, 0, 0, H_gdk_pixbuf_new_from_xpm_data, pl_pu); Xg_define_procedure(gdk_pixbuf_fill, gxg_gdk_pixbuf_fill_w, 2, 0, 0, H_gdk_pixbuf_fill, pl_tui); Xg_define_procedure(gdk_pixbuf_savev, gxg_gdk_pixbuf_savev_w, 5, 1, 0, H_gdk_pixbuf_savev, pl_bussu); Xg_define_procedure(gdk_pixbuf_add_alpha, gxg_gdk_pixbuf_add_alpha_w, 5, 0, 0, H_gdk_pixbuf_add_alpha, pl_pubi); Xg_define_procedure(gdk_pixbuf_copy_area, gxg_gdk_pixbuf_copy_area_w, 0, 0, 1, H_gdk_pixbuf_copy_area, pl_tuiiiiui); Xg_define_procedure(gdk_pixbuf_saturate_and_pixelate, gxg_gdk_pixbuf_saturate_and_pixelate_w, 4, 0, 0, H_gdk_pixbuf_saturate_and_pixelate, pl_tuurb); Xg_define_procedure(gdk_pixbuf_scale, gxg_gdk_pixbuf_scale_w, 0, 0, 1, H_gdk_pixbuf_scale, pl_tuuiiiirrrri); Xg_define_procedure(gdk_pixbuf_composite, gxg_gdk_pixbuf_composite_w, 0, 0, 1, H_gdk_pixbuf_composite, pl_tuuiiiirrrri); Xg_define_procedure(gdk_pixbuf_composite_color, gxg_gdk_pixbuf_composite_color_w, 0, 0, 1, H_gdk_pixbuf_composite_color, pl_tuuiiiirrrri); Xg_define_procedure(gdk_pixbuf_scale_simple, gxg_gdk_pixbuf_scale_simple_w, 4, 0, 0, H_gdk_pixbuf_scale_simple, pl_pui); Xg_define_procedure(gdk_pixbuf_composite_color_simple, gxg_gdk_pixbuf_composite_color_simple_w, 0, 0, 1, H_gdk_pixbuf_composite_color_simple, pl_pui); Xg_define_procedure(gdk_pixbuf_animation_new_from_file, gxg_gdk_pixbuf_animation_new_from_file_w, 1, 1, 0, H_gdk_pixbuf_animation_new_from_file, pl_psu); Xg_define_procedure(gdk_pixbuf_animation_get_width, gxg_gdk_pixbuf_animation_get_width_w, 1, 0, 0, H_gdk_pixbuf_animation_get_width, pl_iu); Xg_define_procedure(gdk_pixbuf_animation_get_height, gxg_gdk_pixbuf_animation_get_height_w, 1, 0, 0, H_gdk_pixbuf_animation_get_height, pl_iu); Xg_define_procedure(gdk_pixbuf_animation_is_static_image, gxg_gdk_pixbuf_animation_is_static_image_w, 1, 0, 0, H_gdk_pixbuf_animation_is_static_image, pl_bu); Xg_define_procedure(gdk_pixbuf_animation_get_static_image, gxg_gdk_pixbuf_animation_get_static_image_w, 1, 0, 0, H_gdk_pixbuf_animation_get_static_image, pl_pu); Xg_define_procedure(gdk_pixbuf_animation_get_iter, gxg_gdk_pixbuf_animation_get_iter_w, 2, 0, 0, H_gdk_pixbuf_animation_get_iter, pl_pu); Xg_define_procedure(gdk_pixbuf_animation_iter_get_delay_time, gxg_gdk_pixbuf_animation_iter_get_delay_time_w, 1, 0, 0, H_gdk_pixbuf_animation_iter_get_delay_time, pl_iu); Xg_define_procedure(gdk_pixbuf_animation_iter_get_pixbuf, gxg_gdk_pixbuf_animation_iter_get_pixbuf_w, 1, 0, 0, H_gdk_pixbuf_animation_iter_get_pixbuf, pl_pu); Xg_define_procedure(gdk_pixbuf_animation_iter_on_currently_loading_frame, gxg_gdk_pixbuf_animation_iter_on_currently_loading_frame_w, 1, 0, 0, H_gdk_pixbuf_animation_iter_on_currently_loading_frame, pl_bu); Xg_define_procedure(gdk_pixbuf_animation_iter_advance, gxg_gdk_pixbuf_animation_iter_advance_w, 2, 0, 0, H_gdk_pixbuf_animation_iter_advance, pl_bu); Xg_define_procedure(gdk_pixbuf_get_option, gxg_gdk_pixbuf_get_option_w, 2, 0, 0, H_gdk_pixbuf_get_option, pl_sus); Xg_define_procedure(gtk_accel_group_new, gxg_gtk_accel_group_new_w, 0, 0, 0, H_gtk_accel_group_new, pl_p); Xg_define_procedure(gtk_accel_group_lock, gxg_gtk_accel_group_lock_w, 1, 0, 0, H_gtk_accel_group_lock, pl_tu); Xg_define_procedure(gtk_accel_group_unlock, gxg_gtk_accel_group_unlock_w, 1, 0, 0, H_gtk_accel_group_unlock, pl_tu); Xg_define_procedure(gtk_accel_group_connect, gxg_gtk_accel_group_connect_w, 5, 0, 0, H_gtk_accel_group_connect, pl_tuiiiu); Xg_define_procedure(gtk_accel_group_connect_by_path, gxg_gtk_accel_group_connect_by_path_w, 3, 0, 0, H_gtk_accel_group_connect_by_path, pl_tusu); Xg_define_procedure(gtk_accel_group_disconnect, gxg_gtk_accel_group_disconnect_w, 2, 0, 0, H_gtk_accel_group_disconnect, pl_bu); Xg_define_procedure(gtk_accel_group_disconnect_key, gxg_gtk_accel_group_disconnect_key_w, 3, 0, 0, H_gtk_accel_group_disconnect_key, pl_bui); Xg_define_procedure(gtk_accel_groups_activate, gxg_gtk_accel_groups_activate_w, 3, 0, 0, H_gtk_accel_groups_activate, pl_bui); Xg_define_procedure(gtk_accel_groups_from_object, gxg_gtk_accel_groups_from_object_w, 1, 0, 0, H_gtk_accel_groups_from_object, pl_pu); Xg_define_procedure(gtk_accel_group_find, gxg_gtk_accel_group_find_w, 2, 1, 0, H_gtk_accel_group_find, pl_put); Xg_define_procedure(gtk_accel_group_from_accel_closure, gxg_gtk_accel_group_from_accel_closure_w, 1, 0, 0, H_gtk_accel_group_from_accel_closure, pl_pu); Xg_define_procedure(gtk_accelerator_valid, gxg_gtk_accelerator_valid_w, 2, 0, 0, H_gtk_accelerator_valid, pl_bi); Xg_define_procedure(gtk_accelerator_parse, gxg_gtk_accelerator_parse_w, 1, 2, 0, H_gtk_accelerator_parse, pl_tsu); Xg_define_procedure(gtk_accelerator_name, gxg_gtk_accelerator_name_w, 2, 0, 0, H_gtk_accelerator_name, pl_si); Xg_define_procedure(gtk_accelerator_set_default_mod_mask, gxg_gtk_accelerator_set_default_mod_mask_w, 1, 0, 0, H_gtk_accelerator_set_default_mod_mask, pl_ti); Xg_define_procedure(gtk_accel_group_query, gxg_gtk_accel_group_query_w, 3, 1, 0, H_gtk_accel_group_query, pl_puiiu); Xg_define_procedure(gtk_accel_group_activate, gxg_gtk_accel_group_activate_w, 5, 0, 0, H_gtk_accel_group_activate, pl_buiui); Xg_define_procedure(gtk_accel_label_new, gxg_gtk_accel_label_new_w, 1, 0, 0, H_gtk_accel_label_new, pl_ps); Xg_define_procedure(gtk_accel_label_get_accel_widget, gxg_gtk_accel_label_get_accel_widget_w, 1, 0, 0, H_gtk_accel_label_get_accel_widget, pl_pu); Xg_define_procedure(gtk_accel_label_get_accel_width, gxg_gtk_accel_label_get_accel_width_w, 1, 0, 0, H_gtk_accel_label_get_accel_width, pl_iu); Xg_define_procedure(gtk_accel_label_set_accel_widget, gxg_gtk_accel_label_set_accel_widget_w, 2, 0, 0, H_gtk_accel_label_set_accel_widget, pl_tu); Xg_define_procedure(gtk_accel_label_set_accel_closure, gxg_gtk_accel_label_set_accel_closure_w, 2, 0, 0, H_gtk_accel_label_set_accel_closure, pl_tu); Xg_define_procedure(gtk_accel_label_refetch, gxg_gtk_accel_label_refetch_w, 1, 0, 0, H_gtk_accel_label_refetch, pl_bu); Xg_define_procedure(gtk_accel_map_add_entry, gxg_gtk_accel_map_add_entry_w, 3, 0, 0, H_gtk_accel_map_add_entry, pl_tsi); Xg_define_procedure(gtk_accel_map_lookup_entry, gxg_gtk_accel_map_lookup_entry_w, 2, 0, 0, H_gtk_accel_map_lookup_entry, pl_bsu); Xg_define_procedure(gtk_accel_map_change_entry, gxg_gtk_accel_map_change_entry_w, 4, 0, 0, H_gtk_accel_map_change_entry, pl_bsiib); Xg_define_procedure(gtk_accel_map_load, gxg_gtk_accel_map_load_w, 1, 0, 0, H_gtk_accel_map_load, pl_ts); Xg_define_procedure(gtk_accel_map_save, gxg_gtk_accel_map_save_w, 1, 0, 0, H_gtk_accel_map_save, pl_ts); Xg_define_procedure(gtk_accel_map_foreach, gxg_gtk_accel_map_foreach_w, 2, 0, 0, H_gtk_accel_map_foreach, pl_t); Xg_define_procedure(gtk_accel_map_load_fd, gxg_gtk_accel_map_load_fd_w, 1, 0, 0, H_gtk_accel_map_load_fd, pl_ti); Xg_define_procedure(gtk_accel_map_save_fd, gxg_gtk_accel_map_save_fd_w, 1, 0, 0, H_gtk_accel_map_save_fd, pl_ti); Xg_define_procedure(gtk_accel_map_add_filter, gxg_gtk_accel_map_add_filter_w, 1, 0, 0, H_gtk_accel_map_add_filter, pl_ts); Xg_define_procedure(gtk_accel_map_foreach_unfiltered, gxg_gtk_accel_map_foreach_unfiltered_w, 2, 0, 0, H_gtk_accel_map_foreach_unfiltered, pl_t); Xg_define_procedure(gtk_adjustment_clamp_page, gxg_gtk_adjustment_clamp_page_w, 3, 0, 0, H_gtk_adjustment_clamp_page, pl_tur); Xg_define_procedure(gtk_adjustment_get_value, gxg_gtk_adjustment_get_value_w, 1, 0, 0, H_gtk_adjustment_get_value, pl_du); Xg_define_procedure(gtk_adjustment_set_value, gxg_gtk_adjustment_set_value_w, 2, 0, 0, H_gtk_adjustment_set_value, pl_tur); Xg_define_procedure(gtk_aspect_frame_new, gxg_gtk_aspect_frame_new_w, 5, 0, 0, H_gtk_aspect_frame_new, pl_psrrrb); Xg_define_procedure(gtk_aspect_frame_set, gxg_gtk_aspect_frame_set_w, 5, 0, 0, H_gtk_aspect_frame_set, pl_turrrb); Xg_define_procedure(gtk_button_box_get_layout, gxg_gtk_button_box_get_layout_w, 1, 0, 0, H_gtk_button_box_get_layout, pl_iu); Xg_define_procedure(gtk_button_box_set_layout, gxg_gtk_button_box_set_layout_w, 2, 0, 0, H_gtk_button_box_set_layout, pl_tui); Xg_define_procedure(gtk_button_box_set_child_secondary, gxg_gtk_button_box_set_child_secondary_w, 3, 0, 0, H_gtk_button_box_set_child_secondary, pl_tuub); Xg_define_procedure(gtk_binding_set_new, gxg_gtk_binding_set_new_w, 1, 0, 0, H_gtk_binding_set_new, pl_ps); Xg_define_procedure(gtk_binding_set_by_class, gxg_gtk_binding_set_by_class_w, 1, 0, 0, H_gtk_binding_set_by_class, pl_pt); Xg_define_procedure(gtk_binding_set_find, gxg_gtk_binding_set_find_w, 1, 0, 0, H_gtk_binding_set_find, pl_ps); Xg_define_procedure(gtk_binding_entry_remove, gxg_gtk_binding_entry_remove_w, 3, 0, 0, H_gtk_binding_entry_remove, pl_tui); Xg_define_procedure(gtk_bin_get_child, gxg_gtk_bin_get_child_w, 1, 0, 0, H_gtk_bin_get_child, pl_pu); Xg_define_procedure(gtk_box_pack_start, gxg_gtk_box_pack_start_w, 5, 0, 0, H_gtk_box_pack_start, pl_tuubbi); Xg_define_procedure(gtk_box_pack_end, gxg_gtk_box_pack_end_w, 5, 0, 0, H_gtk_box_pack_end, pl_tuubbi); Xg_define_procedure(gtk_box_set_homogeneous, gxg_gtk_box_set_homogeneous_w, 2, 0, 0, H_gtk_box_set_homogeneous, pl_tub); Xg_define_procedure(gtk_box_get_homogeneous, gxg_gtk_box_get_homogeneous_w, 1, 0, 0, H_gtk_box_get_homogeneous, pl_bu); Xg_define_procedure(gtk_box_set_spacing, gxg_gtk_box_set_spacing_w, 2, 0, 0, H_gtk_box_set_spacing, pl_tui); Xg_define_procedure(gtk_box_get_spacing, gxg_gtk_box_get_spacing_w, 1, 0, 0, H_gtk_box_get_spacing, pl_iu); Xg_define_procedure(gtk_box_reorder_child, gxg_gtk_box_reorder_child_w, 3, 0, 0, H_gtk_box_reorder_child, pl_tuui); Xg_define_procedure(gtk_box_query_child_packing, gxg_gtk_box_query_child_packing_w, 2, 4, 0, H_gtk_box_query_child_packing, pl_tu); Xg_define_procedure(gtk_box_set_child_packing, gxg_gtk_box_set_child_packing_w, 6, 0, 0, H_gtk_box_set_child_packing, pl_tuubbi); Xg_define_procedure(gtk_button_new, gxg_gtk_button_new_w, 0, 0, 0, H_gtk_button_new, pl_p); Xg_define_procedure(gtk_button_new_with_label, gxg_gtk_button_new_with_label_w, 1, 0, 0, H_gtk_button_new_with_label, pl_ps); Xg_define_procedure(gtk_button_new_with_mnemonic, gxg_gtk_button_new_with_mnemonic_w, 1, 0, 0, H_gtk_button_new_with_mnemonic, pl_ps); Xg_define_procedure(gtk_button_clicked, gxg_gtk_button_clicked_w, 1, 0, 0, H_gtk_button_clicked, pl_tu); Xg_define_procedure(gtk_button_set_relief, gxg_gtk_button_set_relief_w, 2, 0, 0, H_gtk_button_set_relief, pl_tui); Xg_define_procedure(gtk_button_get_relief, gxg_gtk_button_get_relief_w, 1, 0, 0, H_gtk_button_get_relief, pl_iu); Xg_define_procedure(gtk_button_set_label, gxg_gtk_button_set_label_w, 2, 0, 0, H_gtk_button_set_label, pl_tus); Xg_define_procedure(gtk_button_get_label, gxg_gtk_button_get_label_w, 1, 0, 0, H_gtk_button_get_label, pl_su); Xg_define_procedure(gtk_button_set_use_underline, gxg_gtk_button_set_use_underline_w, 2, 0, 0, H_gtk_button_set_use_underline, pl_tub); Xg_define_procedure(gtk_button_get_use_underline, gxg_gtk_button_get_use_underline_w, 1, 0, 0, H_gtk_button_get_use_underline, pl_bu); Xg_define_procedure(gtk_calendar_new, gxg_gtk_calendar_new_w, 0, 0, 0, H_gtk_calendar_new, pl_p); Xg_define_procedure(gtk_calendar_select_day, gxg_gtk_calendar_select_day_w, 2, 0, 0, H_gtk_calendar_select_day, pl_tui); Xg_define_procedure(gtk_calendar_clear_marks, gxg_gtk_calendar_clear_marks_w, 1, 0, 0, H_gtk_calendar_clear_marks, pl_tu); Xg_define_procedure(gtk_calendar_get_date, gxg_gtk_calendar_get_date_w, 1, 3, 0, H_gtk_calendar_get_date, pl_tu); Xg_define_procedure(gtk_cell_editable_start_editing, gxg_gtk_cell_editable_start_editing_w, 2, 0, 0, H_gtk_cell_editable_start_editing, pl_tu); Xg_define_procedure(gtk_cell_editable_editing_done, gxg_gtk_cell_editable_editing_done_w, 1, 0, 0, H_gtk_cell_editable_editing_done, pl_tu); Xg_define_procedure(gtk_cell_editable_remove_widget, gxg_gtk_cell_editable_remove_widget_w, 1, 0, 0, H_gtk_cell_editable_remove_widget, pl_tu); Xg_define_procedure(gtk_cell_renderer_activate, gxg_gtk_cell_renderer_activate_w, 7, 0, 0, H_gtk_cell_renderer_activate, pl_buuusuui); Xg_define_procedure(gtk_cell_renderer_start_editing, gxg_gtk_cell_renderer_start_editing_w, 7, 0, 0, H_gtk_cell_renderer_start_editing, pl_puuusuui); Xg_define_procedure(gtk_cell_renderer_set_fixed_size, gxg_gtk_cell_renderer_set_fixed_size_w, 3, 0, 0, H_gtk_cell_renderer_set_fixed_size, pl_tui); Xg_define_procedure(gtk_cell_renderer_get_fixed_size, gxg_gtk_cell_renderer_get_fixed_size_w, 1, 2, 0, H_gtk_cell_renderer_get_fixed_size, pl_tu); Xg_define_procedure(gtk_cell_renderer_pixbuf_new, gxg_gtk_cell_renderer_pixbuf_new_w, 0, 0, 0, H_gtk_cell_renderer_pixbuf_new, pl_p); Xg_define_procedure(gtk_cell_renderer_text_new, gxg_gtk_cell_renderer_text_new_w, 0, 0, 0, H_gtk_cell_renderer_text_new, pl_p); Xg_define_procedure(gtk_cell_renderer_text_set_fixed_height_from_font, gxg_gtk_cell_renderer_text_set_fixed_height_from_font_w, 2, 0, 0, H_gtk_cell_renderer_text_set_fixed_height_from_font, pl_tui); Xg_define_procedure(gtk_cell_renderer_toggle_new, gxg_gtk_cell_renderer_toggle_new_w, 0, 0, 0, H_gtk_cell_renderer_toggle_new, pl_p); Xg_define_procedure(gtk_cell_renderer_toggle_get_radio, gxg_gtk_cell_renderer_toggle_get_radio_w, 1, 0, 0, H_gtk_cell_renderer_toggle_get_radio, pl_bu); Xg_define_procedure(gtk_cell_renderer_toggle_set_radio, gxg_gtk_cell_renderer_toggle_set_radio_w, 2, 0, 0, H_gtk_cell_renderer_toggle_set_radio, pl_tub); Xg_define_procedure(gtk_cell_renderer_toggle_get_active, gxg_gtk_cell_renderer_toggle_get_active_w, 1, 0, 0, H_gtk_cell_renderer_toggle_get_active, pl_bu); Xg_define_procedure(gtk_cell_renderer_toggle_set_active, gxg_gtk_cell_renderer_toggle_set_active_w, 2, 0, 0, H_gtk_cell_renderer_toggle_set_active, pl_tub); Xg_define_procedure(gtk_check_button_new, gxg_gtk_check_button_new_w, 0, 0, 0, H_gtk_check_button_new, pl_p); Xg_define_procedure(gtk_check_button_new_with_label, gxg_gtk_check_button_new_with_label_w, 1, 0, 0, H_gtk_check_button_new_with_label, pl_ps); Xg_define_procedure(gtk_check_button_new_with_mnemonic, gxg_gtk_check_button_new_with_mnemonic_w, 1, 0, 0, H_gtk_check_button_new_with_mnemonic, pl_ps); Xg_define_procedure(gtk_check_menu_item_new, gxg_gtk_check_menu_item_new_w, 0, 0, 0, H_gtk_check_menu_item_new, pl_p); Xg_define_procedure(gtk_check_menu_item_new_with_label, gxg_gtk_check_menu_item_new_with_label_w, 1, 0, 0, H_gtk_check_menu_item_new_with_label, pl_ps); Xg_define_procedure(gtk_check_menu_item_new_with_mnemonic, gxg_gtk_check_menu_item_new_with_mnemonic_w, 1, 0, 0, H_gtk_check_menu_item_new_with_mnemonic, pl_ps); Xg_define_procedure(gtk_check_menu_item_set_active, gxg_gtk_check_menu_item_set_active_w, 2, 0, 0, H_gtk_check_menu_item_set_active, pl_tub); Xg_define_procedure(gtk_check_menu_item_get_active, gxg_gtk_check_menu_item_get_active_w, 1, 0, 0, H_gtk_check_menu_item_get_active, pl_bu); Xg_define_procedure(gtk_check_menu_item_toggled, gxg_gtk_check_menu_item_toggled_w, 1, 0, 0, H_gtk_check_menu_item_toggled, pl_tu); Xg_define_procedure(gtk_check_menu_item_set_inconsistent, gxg_gtk_check_menu_item_set_inconsistent_w, 2, 0, 0, H_gtk_check_menu_item_set_inconsistent, pl_tub); Xg_define_procedure(gtk_check_menu_item_get_inconsistent, gxg_gtk_check_menu_item_get_inconsistent_w, 1, 0, 0, H_gtk_check_menu_item_get_inconsistent, pl_bu); Xg_define_procedure(gtk_clipboard_get, gxg_gtk_clipboard_get_w, 1, 0, 0, H_gtk_clipboard_get, pl_pt); Xg_define_procedure(gtk_clipboard_set_with_data, gxg_gtk_clipboard_set_with_data_w, 5, 1, 0, H_gtk_clipboard_set_with_data, pl_buuit); Xg_define_procedure(gtk_clipboard_get_owner, gxg_gtk_clipboard_get_owner_w, 1, 0, 0, H_gtk_clipboard_get_owner, pl_pu); Xg_define_procedure(gtk_clipboard_clear, gxg_gtk_clipboard_clear_w, 1, 0, 0, H_gtk_clipboard_clear, pl_tu); Xg_define_procedure(gtk_clipboard_set_text, gxg_gtk_clipboard_set_text_w, 3, 0, 0, H_gtk_clipboard_set_text, pl_tusi); Xg_define_procedure(gtk_clipboard_request_contents, gxg_gtk_clipboard_request_contents_w, 3, 1, 0, H_gtk_clipboard_request_contents, pl_tut); Xg_define_procedure(gtk_clipboard_request_text, gxg_gtk_clipboard_request_text_w, 2, 1, 0, H_gtk_clipboard_request_text, pl_tut); Xg_define_procedure(gtk_clipboard_wait_for_contents, gxg_gtk_clipboard_wait_for_contents_w, 2, 0, 0, H_gtk_clipboard_wait_for_contents, pl_put); Xg_define_procedure(gtk_clipboard_wait_for_text, gxg_gtk_clipboard_wait_for_text_w, 1, 0, 0, H_gtk_clipboard_wait_for_text, pl_su); Xg_define_procedure(gtk_clipboard_wait_is_text_available, gxg_gtk_clipboard_wait_is_text_available_w, 1, 0, 0, H_gtk_clipboard_wait_is_text_available, pl_bu); Xg_define_procedure(gtk_container_set_border_width, gxg_gtk_container_set_border_width_w, 2, 0, 0, H_gtk_container_set_border_width, pl_tui); Xg_define_procedure(gtk_container_get_border_width, gxg_gtk_container_get_border_width_w, 1, 0, 0, H_gtk_container_get_border_width, pl_iu); Xg_define_procedure(gtk_container_add, gxg_gtk_container_add_w, 2, 0, 0, H_gtk_container_add, pl_tu); Xg_define_procedure(gtk_container_remove, gxg_gtk_container_remove_w, 2, 0, 0, H_gtk_container_remove, pl_tu); Xg_define_procedure(gtk_container_check_resize, gxg_gtk_container_check_resize_w, 1, 0, 0, H_gtk_container_check_resize, pl_tu); Xg_define_procedure(gtk_container_foreach, gxg_gtk_container_foreach_w, 2, 1, 0, H_gtk_container_foreach, pl_tut); Xg_define_procedure(gtk_container_get_children, gxg_gtk_container_get_children_w, 1, 0, 0, H_gtk_container_get_children, pl_pu); Xg_define_procedure(gtk_dialog_new, gxg_gtk_dialog_new_w, 0, 0, 0, H_gtk_dialog_new, pl_p); Xg_define_procedure(gtk_dialog_add_action_widget, gxg_gtk_dialog_add_action_widget_w, 3, 0, 0, H_gtk_dialog_add_action_widget, pl_tuui); Xg_define_procedure(gtk_dialog_add_button, gxg_gtk_dialog_add_button_w, 3, 0, 0, H_gtk_dialog_add_button, pl_pusi); Xg_define_procedure(gtk_dialog_add_buttons, gxg_gtk_dialog_add_buttons_w, 2, 0, 0, H_gtk_dialog_add_buttons, pl_tut); Xg_define_procedure(gtk_dialog_set_response_sensitive, gxg_gtk_dialog_set_response_sensitive_w, 3, 0, 0, H_gtk_dialog_set_response_sensitive, pl_tuib); Xg_define_procedure(gtk_dialog_set_default_response, gxg_gtk_dialog_set_default_response_w, 2, 0, 0, H_gtk_dialog_set_default_response, pl_tui); Xg_define_procedure(gtk_dialog_response, gxg_gtk_dialog_response_w, 2, 0, 0, H_gtk_dialog_response, pl_tui); Xg_define_procedure(gtk_dialog_run, gxg_gtk_dialog_run_w, 1, 0, 0, H_gtk_dialog_run, pl_iu); Xg_define_procedure(gtk_drag_get_data, gxg_gtk_drag_get_data_w, 4, 0, 0, H_gtk_drag_get_data, pl_tuuti); Xg_define_procedure(gtk_drag_finish, gxg_gtk_drag_finish_w, 4, 0, 0, H_gtk_drag_finish, pl_tubbi); Xg_define_procedure(gtk_drag_get_source_widget, gxg_gtk_drag_get_source_widget_w, 1, 0, 0, H_gtk_drag_get_source_widget, pl_pu); Xg_define_procedure(gtk_drag_highlight, gxg_gtk_drag_highlight_w, 1, 0, 0, H_gtk_drag_highlight, pl_tu); Xg_define_procedure(gtk_drag_unhighlight, gxg_gtk_drag_unhighlight_w, 1, 0, 0, H_gtk_drag_unhighlight, pl_tu); Xg_define_procedure(gtk_drag_dest_set, gxg_gtk_drag_dest_set_w, 5, 0, 0, H_gtk_drag_dest_set, pl_tuiui); Xg_define_procedure(gtk_drag_dest_unset, gxg_gtk_drag_dest_unset_w, 1, 0, 0, H_gtk_drag_dest_unset, pl_tu); Xg_define_procedure(gtk_drag_dest_find_target, gxg_gtk_drag_dest_find_target_w, 3, 0, 0, H_gtk_drag_dest_find_target, pl_tu); Xg_define_procedure(gtk_drag_dest_get_target_list, gxg_gtk_drag_dest_get_target_list_w, 1, 0, 0, H_gtk_drag_dest_get_target_list, pl_pu); Xg_define_procedure(gtk_drag_dest_set_target_list, gxg_gtk_drag_dest_set_target_list_w, 2, 0, 0, H_gtk_drag_dest_set_target_list, pl_tu); Xg_define_procedure(gtk_drag_source_set, gxg_gtk_drag_source_set_w, 5, 0, 0, H_gtk_drag_source_set, pl_tuiui); Xg_define_procedure(gtk_drag_source_unset, gxg_gtk_drag_source_unset_w, 1, 0, 0, H_gtk_drag_source_unset, pl_tu); Xg_define_procedure(gtk_drag_source_set_icon_pixbuf, gxg_gtk_drag_source_set_icon_pixbuf_w, 2, 0, 0, H_gtk_drag_source_set_icon_pixbuf, pl_tu); Xg_define_procedure(gtk_drag_set_icon_widget, gxg_gtk_drag_set_icon_widget_w, 4, 0, 0, H_gtk_drag_set_icon_widget, pl_tuui); Xg_define_procedure(gtk_drag_set_icon_pixbuf, gxg_gtk_drag_set_icon_pixbuf_w, 4, 0, 0, H_gtk_drag_set_icon_pixbuf, pl_tuui); Xg_define_procedure(gtk_drag_set_icon_default, gxg_gtk_drag_set_icon_default_w, 1, 0, 0, H_gtk_drag_set_icon_default, pl_tu); Xg_define_procedure(gtk_drag_check_threshold, gxg_gtk_drag_check_threshold_w, 5, 0, 0, H_gtk_drag_check_threshold, pl_bui); Xg_define_procedure(gtk_drawing_area_new, gxg_gtk_drawing_area_new_w, 0, 0, 0, H_gtk_drawing_area_new, pl_p); Xg_define_procedure(gtk_editable_select_region, gxg_gtk_editable_select_region_w, 3, 0, 0, H_gtk_editable_select_region, pl_tui); Xg_define_procedure(gtk_editable_get_selection_bounds, gxg_gtk_editable_get_selection_bounds_w, 1, 2, 0, H_gtk_editable_get_selection_bounds, pl_bu); Xg_define_procedure(gtk_editable_insert_text, gxg_gtk_editable_insert_text_w, 3, 1, 0, H_gtk_editable_insert_text, pl_tusiu); Xg_define_procedure(gtk_editable_delete_text, gxg_gtk_editable_delete_text_w, 3, 0, 0, H_gtk_editable_delete_text, pl_tui); Xg_define_procedure(gtk_editable_get_chars, gxg_gtk_editable_get_chars_w, 3, 0, 0, H_gtk_editable_get_chars, pl_sui); Xg_define_procedure(gtk_editable_cut_clipboard, gxg_gtk_editable_cut_clipboard_w, 1, 0, 0, H_gtk_editable_cut_clipboard, pl_tu); Xg_define_procedure(gtk_editable_copy_clipboard, gxg_gtk_editable_copy_clipboard_w, 1, 0, 0, H_gtk_editable_copy_clipboard, pl_tu); Xg_define_procedure(gtk_editable_paste_clipboard, gxg_gtk_editable_paste_clipboard_w, 1, 0, 0, H_gtk_editable_paste_clipboard, pl_tu); Xg_define_procedure(gtk_editable_delete_selection, gxg_gtk_editable_delete_selection_w, 1, 0, 0, H_gtk_editable_delete_selection, pl_tu); Xg_define_procedure(gtk_editable_set_position, gxg_gtk_editable_set_position_w, 2, 0, 0, H_gtk_editable_set_position, pl_tui); Xg_define_procedure(gtk_editable_get_position, gxg_gtk_editable_get_position_w, 1, 0, 0, H_gtk_editable_get_position, pl_iu); Xg_define_procedure(gtk_editable_set_editable, gxg_gtk_editable_set_editable_w, 2, 0, 0, H_gtk_editable_set_editable, pl_tub); Xg_define_procedure(gtk_editable_get_editable, gxg_gtk_editable_get_editable_w, 1, 0, 0, H_gtk_editable_get_editable, pl_bu); Xg_define_procedure(gtk_entry_new, gxg_gtk_entry_new_w, 0, 0, 0, H_gtk_entry_new, pl_p); Xg_define_procedure(gtk_entry_set_visibility, gxg_gtk_entry_set_visibility_w, 2, 0, 0, H_gtk_entry_set_visibility, pl_tub); Xg_define_procedure(gtk_entry_get_visibility, gxg_gtk_entry_get_visibility_w, 1, 0, 0, H_gtk_entry_get_visibility, pl_bu); Xg_define_procedure(gtk_entry_set_invisible_char, gxg_gtk_entry_set_invisible_char_w, 2, 0, 0, H_gtk_entry_set_invisible_char, pl_tui); Xg_define_procedure(gtk_entry_get_invisible_char, gxg_gtk_entry_get_invisible_char_w, 1, 0, 0, H_gtk_entry_get_invisible_char, pl_iu); Xg_define_procedure(gtk_entry_set_has_frame, gxg_gtk_entry_set_has_frame_w, 2, 0, 0, H_gtk_entry_set_has_frame, pl_tub); Xg_define_procedure(gtk_entry_get_has_frame, gxg_gtk_entry_get_has_frame_w, 1, 0, 0, H_gtk_entry_get_has_frame, pl_bu); Xg_define_procedure(gtk_entry_set_max_length, gxg_gtk_entry_set_max_length_w, 2, 0, 0, H_gtk_entry_set_max_length, pl_tui); Xg_define_procedure(gtk_entry_get_max_length, gxg_gtk_entry_get_max_length_w, 1, 0, 0, H_gtk_entry_get_max_length, pl_iu); Xg_define_procedure(gtk_entry_set_activates_default, gxg_gtk_entry_set_activates_default_w, 2, 0, 0, H_gtk_entry_set_activates_default, pl_tub); Xg_define_procedure(gtk_entry_get_activates_default, gxg_gtk_entry_get_activates_default_w, 1, 0, 0, H_gtk_entry_get_activates_default, pl_bu); Xg_define_procedure(gtk_entry_set_width_chars, gxg_gtk_entry_set_width_chars_w, 2, 0, 0, H_gtk_entry_set_width_chars, pl_tui); Xg_define_procedure(gtk_entry_get_width_chars, gxg_gtk_entry_get_width_chars_w, 1, 0, 0, H_gtk_entry_get_width_chars, pl_iu); Xg_define_procedure(gtk_entry_set_text, gxg_gtk_entry_set_text_w, 2, 0, 0, H_gtk_entry_set_text, pl_tus); Xg_define_procedure(gtk_entry_get_text, gxg_gtk_entry_get_text_w, 1, 0, 0, H_gtk_entry_get_text, pl_su); Xg_define_procedure(gtk_entry_get_layout, gxg_gtk_entry_get_layout_w, 1, 0, 0, H_gtk_entry_get_layout, pl_pu); Xg_define_procedure(gtk_entry_get_layout_offsets, gxg_gtk_entry_get_layout_offsets_w, 1, 2, 0, H_gtk_entry_get_layout_offsets, pl_tu); Xg_define_procedure(gtk_event_box_new, gxg_gtk_event_box_new_w, 0, 0, 0, H_gtk_event_box_new, pl_p); Xg_define_procedure(gtk_fixed_new, gxg_gtk_fixed_new_w, 0, 0, 0, H_gtk_fixed_new, pl_p); Xg_define_procedure(gtk_fixed_put, gxg_gtk_fixed_put_w, 4, 0, 0, H_gtk_fixed_put, pl_tuui); Xg_define_procedure(gtk_fixed_move, gxg_gtk_fixed_move_w, 4, 0, 0, H_gtk_fixed_move, pl_tuui); Xg_define_procedure(gtk_frame_new, gxg_gtk_frame_new_w, 1, 0, 0, H_gtk_frame_new, pl_ps); Xg_define_procedure(gtk_frame_set_label, gxg_gtk_frame_set_label_w, 2, 0, 0, H_gtk_frame_set_label, pl_tus); Xg_define_procedure(gtk_frame_get_label, gxg_gtk_frame_get_label_w, 1, 0, 0, H_gtk_frame_get_label, pl_su); Xg_define_procedure(gtk_frame_set_label_widget, gxg_gtk_frame_set_label_widget_w, 2, 0, 0, H_gtk_frame_set_label_widget, pl_tu); Xg_define_procedure(gtk_frame_get_label_widget, gxg_gtk_frame_get_label_widget_w, 1, 0, 0, H_gtk_frame_get_label_widget, pl_pu); Xg_define_procedure(gtk_frame_set_label_align, gxg_gtk_frame_set_label_align_w, 3, 0, 0, H_gtk_frame_set_label_align, pl_tur); Xg_define_procedure(gtk_frame_get_label_align, gxg_gtk_frame_get_label_align_w, 1, 2, 0, H_gtk_frame_get_label_align, pl_tu); Xg_define_procedure(gtk_frame_set_shadow_type, gxg_gtk_frame_set_shadow_type_w, 2, 0, 0, H_gtk_frame_set_shadow_type, pl_tui); Xg_define_procedure(gtk_frame_get_shadow_type, gxg_gtk_frame_get_shadow_type_w, 1, 0, 0, H_gtk_frame_get_shadow_type, pl_iu); Xg_define_procedure(gtk_image_new, gxg_gtk_image_new_w, 0, 0, 0, H_gtk_image_new, pl_p); Xg_define_procedure(gtk_image_new_from_file, gxg_gtk_image_new_from_file_w, 1, 0, 0, H_gtk_image_new_from_file, pl_ps); Xg_define_procedure(gtk_image_new_from_pixbuf, gxg_gtk_image_new_from_pixbuf_w, 1, 0, 0, H_gtk_image_new_from_pixbuf, pl_pu); Xg_define_procedure(gtk_image_new_from_animation, gxg_gtk_image_new_from_animation_w, 1, 0, 0, H_gtk_image_new_from_animation, pl_pu); Xg_define_procedure(gtk_image_set_from_file, gxg_gtk_image_set_from_file_w, 2, 0, 0, H_gtk_image_set_from_file, pl_tus); Xg_define_procedure(gtk_image_set_from_pixbuf, gxg_gtk_image_set_from_pixbuf_w, 2, 0, 0, H_gtk_image_set_from_pixbuf, pl_tu); Xg_define_procedure(gtk_image_set_from_animation, gxg_gtk_image_set_from_animation_w, 2, 0, 0, H_gtk_image_set_from_animation, pl_tu); Xg_define_procedure(gtk_image_get_storage_type, gxg_gtk_image_get_storage_type_w, 1, 0, 0, H_gtk_image_get_storage_type, pl_iu); Xg_define_procedure(gtk_image_get_pixbuf, gxg_gtk_image_get_pixbuf_w, 1, 0, 0, H_gtk_image_get_pixbuf, pl_pu); Xg_define_procedure(gtk_image_get_animation, gxg_gtk_image_get_animation_w, 1, 0, 0, H_gtk_image_get_animation, pl_pu); Xg_define_procedure(gtk_im_context_set_client_window, gxg_gtk_im_context_set_client_window_w, 2, 0, 0, H_gtk_im_context_set_client_window, pl_tu); Xg_define_procedure(gtk_im_context_get_preedit_string, gxg_gtk_im_context_get_preedit_string_w, 1, 3, 0, H_gtk_im_context_get_preedit_string, pl_tu); Xg_define_procedure(gtk_im_context_filter_keypress, gxg_gtk_im_context_filter_keypress_w, 2, 0, 0, H_gtk_im_context_filter_keypress, pl_bu); Xg_define_procedure(gtk_im_context_focus_in, gxg_gtk_im_context_focus_in_w, 1, 0, 0, H_gtk_im_context_focus_in, pl_tu); Xg_define_procedure(gtk_im_context_focus_out, gxg_gtk_im_context_focus_out_w, 1, 0, 0, H_gtk_im_context_focus_out, pl_tu); Xg_define_procedure(gtk_im_context_reset, gxg_gtk_im_context_reset_w, 1, 0, 0, H_gtk_im_context_reset, pl_tu); Xg_define_procedure(gtk_im_context_set_cursor_location, gxg_gtk_im_context_set_cursor_location_w, 2, 0, 0, H_gtk_im_context_set_cursor_location, pl_tu); Xg_define_procedure(gtk_im_context_set_use_preedit, gxg_gtk_im_context_set_use_preedit_w, 2, 0, 0, H_gtk_im_context_set_use_preedit, pl_tub); Xg_define_procedure(gtk_im_context_set_surrounding, gxg_gtk_im_context_set_surrounding_w, 4, 0, 0, H_gtk_im_context_set_surrounding, pl_tusi); Xg_define_procedure(gtk_im_context_get_surrounding, gxg_gtk_im_context_get_surrounding_w, 1, 2, 0, H_gtk_im_context_get_surrounding, pl_bu); Xg_define_procedure(gtk_im_context_delete_surrounding, gxg_gtk_im_context_delete_surrounding_w, 3, 0, 0, H_gtk_im_context_delete_surrounding, pl_bui); Xg_define_procedure(gtk_im_context_simple_new, gxg_gtk_im_context_simple_new_w, 0, 0, 0, H_gtk_im_context_simple_new, pl_p); Xg_define_procedure(gtk_im_context_simple_add_table, gxg_gtk_im_context_simple_add_table_w, 4, 0, 0, H_gtk_im_context_simple_add_table, pl_tuui); Xg_define_procedure(gtk_invisible_new, gxg_gtk_invisible_new_w, 0, 0, 0, H_gtk_invisible_new, pl_p); Xg_define_procedure(gtk_label_new, gxg_gtk_label_new_w, 1, 0, 0, H_gtk_label_new, pl_ps); Xg_define_procedure(gtk_label_new_with_mnemonic, gxg_gtk_label_new_with_mnemonic_w, 1, 0, 0, H_gtk_label_new_with_mnemonic, pl_ps); Xg_define_procedure(gtk_label_set_text, gxg_gtk_label_set_text_w, 2, 0, 0, H_gtk_label_set_text, pl_tus); Xg_define_procedure(gtk_label_get_text, gxg_gtk_label_get_text_w, 1, 0, 0, H_gtk_label_get_text, pl_su); Xg_define_procedure(gtk_label_set_attributes, gxg_gtk_label_set_attributes_w, 2, 0, 0, H_gtk_label_set_attributes, pl_tu); Xg_define_procedure(gtk_label_get_attributes, gxg_gtk_label_get_attributes_w, 1, 0, 0, H_gtk_label_get_attributes, pl_pu); Xg_define_procedure(gtk_label_set_label, gxg_gtk_label_set_label_w, 2, 0, 0, H_gtk_label_set_label, pl_tus); Xg_define_procedure(gtk_label_get_label, gxg_gtk_label_get_label_w, 1, 0, 0, H_gtk_label_get_label, pl_su); Xg_define_procedure(gtk_label_set_markup, gxg_gtk_label_set_markup_w, 2, 0, 0, H_gtk_label_set_markup, pl_tus); Xg_define_procedure(gtk_label_set_use_markup, gxg_gtk_label_set_use_markup_w, 2, 0, 0, H_gtk_label_set_use_markup, pl_tub); Xg_define_procedure(gtk_label_get_use_markup, gxg_gtk_label_get_use_markup_w, 1, 0, 0, H_gtk_label_get_use_markup, pl_bu); Xg_define_procedure(gtk_label_set_use_underline, gxg_gtk_label_set_use_underline_w, 2, 0, 0, H_gtk_label_set_use_underline, pl_tub); Xg_define_procedure(gtk_label_get_use_underline, gxg_gtk_label_get_use_underline_w, 1, 0, 0, H_gtk_label_get_use_underline, pl_bu); Xg_define_procedure(gtk_label_set_markup_with_mnemonic, gxg_gtk_label_set_markup_with_mnemonic_w, 2, 0, 0, H_gtk_label_set_markup_with_mnemonic, pl_tus); Xg_define_procedure(gtk_label_get_mnemonic_keyval, gxg_gtk_label_get_mnemonic_keyval_w, 1, 0, 0, H_gtk_label_get_mnemonic_keyval, pl_iu); Xg_define_procedure(gtk_label_set_mnemonic_widget, gxg_gtk_label_set_mnemonic_widget_w, 2, 0, 0, H_gtk_label_set_mnemonic_widget, pl_tu); Xg_define_procedure(gtk_label_get_mnemonic_widget, gxg_gtk_label_get_mnemonic_widget_w, 1, 0, 0, H_gtk_label_get_mnemonic_widget, pl_pu); Xg_define_procedure(gtk_label_set_text_with_mnemonic, gxg_gtk_label_set_text_with_mnemonic_w, 2, 0, 0, H_gtk_label_set_text_with_mnemonic, pl_tus); Xg_define_procedure(gtk_label_set_justify, gxg_gtk_label_set_justify_w, 2, 0, 0, H_gtk_label_set_justify, pl_tui); Xg_define_procedure(gtk_label_get_justify, gxg_gtk_label_get_justify_w, 1, 0, 0, H_gtk_label_get_justify, pl_iu); Xg_define_procedure(gtk_label_set_pattern, gxg_gtk_label_set_pattern_w, 2, 0, 0, H_gtk_label_set_pattern, pl_tus); Xg_define_procedure(gtk_label_set_line_wrap, gxg_gtk_label_set_line_wrap_w, 2, 0, 0, H_gtk_label_set_line_wrap, pl_tub); Xg_define_procedure(gtk_label_get_line_wrap, gxg_gtk_label_get_line_wrap_w, 1, 0, 0, H_gtk_label_get_line_wrap, pl_bu); Xg_define_procedure(gtk_label_set_selectable, gxg_gtk_label_set_selectable_w, 2, 0, 0, H_gtk_label_set_selectable, pl_tub); Xg_define_procedure(gtk_label_get_selectable, gxg_gtk_label_get_selectable_w, 1, 0, 0, H_gtk_label_get_selectable, pl_bu); Xg_define_procedure(gtk_label_select_region, gxg_gtk_label_select_region_w, 3, 0, 0, H_gtk_label_select_region, pl_tui); Xg_define_procedure(gtk_label_get_selection_bounds, gxg_gtk_label_get_selection_bounds_w, 1, 2, 0, H_gtk_label_get_selection_bounds, pl_bu); Xg_define_procedure(gtk_label_get_layout, gxg_gtk_label_get_layout_w, 1, 0, 0, H_gtk_label_get_layout, pl_pu); Xg_define_procedure(gtk_label_get_layout_offsets, gxg_gtk_label_get_layout_offsets_w, 1, 2, 0, H_gtk_label_get_layout_offsets, pl_tu); Xg_define_procedure(gtk_layout_new, gxg_gtk_layout_new_w, 2, 0, 0, H_gtk_layout_new, pl_pu); Xg_define_procedure(gtk_layout_put, gxg_gtk_layout_put_w, 4, 0, 0, H_gtk_layout_put, pl_tuui); Xg_define_procedure(gtk_layout_move, gxg_gtk_layout_move_w, 4, 0, 0, H_gtk_layout_move, pl_tuui); Xg_define_procedure(gtk_layout_set_size, gxg_gtk_layout_set_size_w, 3, 0, 0, H_gtk_layout_set_size, pl_tui); Xg_define_procedure(gtk_layout_get_size, gxg_gtk_layout_get_size_w, 1, 2, 0, H_gtk_layout_get_size, pl_tu); Xg_define_procedure(gtk_list_store_new, gxg_gtk_list_store_new_w, 2, 0, 0, H_gtk_list_store_new, pl_pit); Xg_define_procedure(gtk_list_store_newv, gxg_gtk_list_store_newv_w, 2, 0, 0, H_gtk_list_store_newv, pl_piu); Xg_define_procedure(gtk_list_store_set_column_types, gxg_gtk_list_store_set_column_types_w, 3, 0, 0, H_gtk_list_store_set_column_types, pl_tuiu); Xg_define_procedure(gtk_list_store_set, gxg_gtk_list_store_set_w, 3, 0, 0, H_gtk_list_store_set, pl_tuut); Xg_define_procedure(gtk_list_store_insert, gxg_gtk_list_store_insert_w, 3, 0, 0, H_gtk_list_store_insert, pl_tuui); Xg_define_procedure(gtk_list_store_insert_before, gxg_gtk_list_store_insert_before_w, 3, 0, 0, H_gtk_list_store_insert_before, pl_tu); Xg_define_procedure(gtk_list_store_insert_after, gxg_gtk_list_store_insert_after_w, 3, 0, 0, H_gtk_list_store_insert_after, pl_tu); Xg_define_procedure(gtk_list_store_prepend, gxg_gtk_list_store_prepend_w, 2, 0, 0, H_gtk_list_store_prepend, pl_tu); Xg_define_procedure(gtk_list_store_append, gxg_gtk_list_store_append_w, 2, 0, 0, H_gtk_list_store_append, pl_tu); Xg_define_procedure(gtk_list_store_clear, gxg_gtk_list_store_clear_w, 1, 0, 0, H_gtk_list_store_clear, pl_tu); Xg_define_procedure(gtk_check_version, gxg_gtk_check_version_w, 3, 0, 0, H_gtk_check_version, pl_si); Xg_define_procedure(gtk_disable_setlocale, gxg_gtk_disable_setlocale_w, 0, 0, 0, H_gtk_disable_setlocale, pl_t); Xg_define_procedure(gtk_get_default_language, gxg_gtk_get_default_language_w, 0, 0, 0, H_gtk_get_default_language, pl_p); Xg_define_procedure(gtk_events_pending, gxg_gtk_events_pending_w, 0, 0, 0, H_gtk_events_pending, pl_i); Xg_define_procedure(gtk_main_do_event, gxg_gtk_main_do_event_w, 1, 0, 0, H_gtk_main_do_event, pl_tu); Xg_define_procedure(gtk_main, gxg_gtk_main_w, 0, 0, 0, H_gtk_main, pl_t); Xg_define_procedure(gtk_main_level, gxg_gtk_main_level_w, 0, 0, 0, H_gtk_main_level, pl_i); Xg_define_procedure(gtk_main_quit, gxg_gtk_main_quit_w, 0, 0, 0, H_gtk_main_quit, pl_t); Xg_define_procedure(gtk_main_iteration, gxg_gtk_main_iteration_w, 0, 0, 0, H_gtk_main_iteration, pl_b); Xg_define_procedure(gtk_main_iteration_do, gxg_gtk_main_iteration_do_w, 1, 0, 0, H_gtk_main_iteration_do, pl_b); Xg_define_procedure(gtk_true, gxg_gtk_true_w, 0, 0, 0, H_gtk_true, pl_b); Xg_define_procedure(gtk_false, gxg_gtk_false_w, 0, 0, 0, H_gtk_false, pl_b); Xg_define_procedure(gtk_grab_add, gxg_gtk_grab_add_w, 1, 0, 0, H_gtk_grab_add, pl_tu); Xg_define_procedure(gtk_grab_get_current, gxg_gtk_grab_get_current_w, 0, 0, 0, H_gtk_grab_get_current, pl_p); Xg_define_procedure(gtk_grab_remove, gxg_gtk_grab_remove_w, 1, 0, 0, H_gtk_grab_remove, pl_tu); Xg_define_procedure(gtk_get_current_event, gxg_gtk_get_current_event_w, 0, 0, 0, H_gtk_get_current_event, pl_p); Xg_define_procedure(gtk_get_current_event_time, gxg_gtk_get_current_event_time_w, 0, 0, 0, H_gtk_get_current_event_time, pl_i); Xg_define_procedure(gtk_get_current_event_state, gxg_gtk_get_current_event_state_w, 0, 1, 0, H_gtk_get_current_event_state, pl_bu); Xg_define_procedure(gtk_get_event_widget, gxg_gtk_get_event_widget_w, 1, 0, 0, H_gtk_get_event_widget, pl_pu); Xg_define_procedure(gtk_propagate_event, gxg_gtk_propagate_event_w, 2, 0, 0, H_gtk_propagate_event, pl_tu); Xg_define_procedure(gtk_menu_bar_new, gxg_gtk_menu_bar_new_w, 0, 0, 0, H_gtk_menu_bar_new, pl_p); Xg_define_procedure(gtk_menu_new, gxg_gtk_menu_new_w, 0, 0, 0, H_gtk_menu_new, pl_p); Xg_define_procedure(gtk_menu_popup, gxg_gtk_menu_popup_w, 7, 0, 0, H_gtk_menu_popup, pl_tuuutti); Xg_define_procedure(gtk_menu_reposition, gxg_gtk_menu_reposition_w, 1, 0, 0, H_gtk_menu_reposition, pl_tu); Xg_define_procedure(gtk_menu_popdown, gxg_gtk_menu_popdown_w, 1, 0, 0, H_gtk_menu_popdown, pl_tu); Xg_define_procedure(gtk_menu_get_active, gxg_gtk_menu_get_active_w, 1, 0, 0, H_gtk_menu_get_active, pl_pu); Xg_define_procedure(gtk_menu_set_active, gxg_gtk_menu_set_active_w, 2, 0, 0, H_gtk_menu_set_active, pl_tui); Xg_define_procedure(gtk_menu_set_accel_group, gxg_gtk_menu_set_accel_group_w, 2, 0, 0, H_gtk_menu_set_accel_group, pl_tu); Xg_define_procedure(gtk_menu_get_accel_group, gxg_gtk_menu_get_accel_group_w, 1, 0, 0, H_gtk_menu_get_accel_group, pl_pu); Xg_define_procedure(gtk_menu_set_accel_path, gxg_gtk_menu_set_accel_path_w, 2, 0, 0, H_gtk_menu_set_accel_path, pl_tus); Xg_define_procedure(gtk_menu_detach, gxg_gtk_menu_detach_w, 1, 0, 0, H_gtk_menu_detach, pl_tu); Xg_define_procedure(gtk_menu_get_attach_widget, gxg_gtk_menu_get_attach_widget_w, 1, 0, 0, H_gtk_menu_get_attach_widget, pl_pu); Xg_define_procedure(gtk_menu_reorder_child, gxg_gtk_menu_reorder_child_w, 3, 0, 0, H_gtk_menu_reorder_child, pl_tuui); Xg_define_procedure(gtk_menu_set_monitor, gxg_gtk_menu_set_monitor_w, 2, 0, 0, H_gtk_menu_set_monitor, pl_tui); Xg_define_procedure(gtk_menu_item_new, gxg_gtk_menu_item_new_w, 0, 0, 0, H_gtk_menu_item_new, pl_p); Xg_define_procedure(gtk_menu_item_new_with_label, gxg_gtk_menu_item_new_with_label_w, 1, 0, 0, H_gtk_menu_item_new_with_label, pl_ps); Xg_define_procedure(gtk_menu_item_new_with_mnemonic, gxg_gtk_menu_item_new_with_mnemonic_w, 1, 0, 0, H_gtk_menu_item_new_with_mnemonic, pl_ps); Xg_define_procedure(gtk_menu_item_set_submenu, gxg_gtk_menu_item_set_submenu_w, 2, 0, 0, H_gtk_menu_item_set_submenu, pl_tu); Xg_define_procedure(gtk_menu_item_get_submenu, gxg_gtk_menu_item_get_submenu_w, 1, 0, 0, H_gtk_menu_item_get_submenu, pl_pu); Xg_define_procedure(gtk_menu_item_select, gxg_gtk_menu_item_select_w, 1, 0, 0, H_gtk_menu_item_select, pl_tu); Xg_define_procedure(gtk_menu_item_deselect, gxg_gtk_menu_item_deselect_w, 1, 0, 0, H_gtk_menu_item_deselect, pl_tu); Xg_define_procedure(gtk_menu_item_activate, gxg_gtk_menu_item_activate_w, 1, 0, 0, H_gtk_menu_item_activate, pl_tu); Xg_define_procedure(gtk_menu_item_toggle_size_request, gxg_gtk_menu_item_toggle_size_request_w, 2, 0, 0, H_gtk_menu_item_toggle_size_request, pl_tu); Xg_define_procedure(gtk_menu_item_toggle_size_allocate, gxg_gtk_menu_item_toggle_size_allocate_w, 2, 0, 0, H_gtk_menu_item_toggle_size_allocate, pl_tui); Xg_define_procedure(gtk_menu_item_set_accel_path, gxg_gtk_menu_item_set_accel_path_w, 2, 0, 0, H_gtk_menu_item_set_accel_path, pl_tus); Xg_define_procedure(gtk_menu_shell_append, gxg_gtk_menu_shell_append_w, 2, 0, 0, H_gtk_menu_shell_append, pl_tu); Xg_define_procedure(gtk_menu_shell_prepend, gxg_gtk_menu_shell_prepend_w, 2, 0, 0, H_gtk_menu_shell_prepend, pl_tu); Xg_define_procedure(gtk_menu_shell_insert, gxg_gtk_menu_shell_insert_w, 3, 0, 0, H_gtk_menu_shell_insert, pl_tuui); Xg_define_procedure(gtk_menu_shell_deactivate, gxg_gtk_menu_shell_deactivate_w, 1, 0, 0, H_gtk_menu_shell_deactivate, pl_tu); Xg_define_procedure(gtk_menu_shell_select_item, gxg_gtk_menu_shell_select_item_w, 2, 0, 0, H_gtk_menu_shell_select_item, pl_tu); Xg_define_procedure(gtk_menu_shell_deselect, gxg_gtk_menu_shell_deselect_w, 1, 0, 0, H_gtk_menu_shell_deselect, pl_tu); Xg_define_procedure(gtk_menu_shell_activate_item, gxg_gtk_menu_shell_activate_item_w, 3, 0, 0, H_gtk_menu_shell_activate_item, pl_tuub); Xg_define_procedure(gtk_notebook_new, gxg_gtk_notebook_new_w, 0, 0, 0, H_gtk_notebook_new, pl_p); Xg_define_procedure(gtk_notebook_remove_page, gxg_gtk_notebook_remove_page_w, 2, 0, 0, H_gtk_notebook_remove_page, pl_tui); Xg_define_procedure(gtk_notebook_get_current_page, gxg_gtk_notebook_get_current_page_w, 1, 0, 0, H_gtk_notebook_get_current_page, pl_iu); Xg_define_procedure(gtk_notebook_get_nth_page, gxg_gtk_notebook_get_nth_page_w, 2, 0, 0, H_gtk_notebook_get_nth_page, pl_pui); Xg_define_procedure(gtk_notebook_page_num, gxg_gtk_notebook_page_num_w, 2, 0, 0, H_gtk_notebook_page_num, pl_iu); Xg_define_procedure(gtk_notebook_set_current_page, gxg_gtk_notebook_set_current_page_w, 2, 0, 0, H_gtk_notebook_set_current_page, pl_tui); Xg_define_procedure(gtk_notebook_next_page, gxg_gtk_notebook_next_page_w, 1, 0, 0, H_gtk_notebook_next_page, pl_tu); Xg_define_procedure(gtk_notebook_prev_page, gxg_gtk_notebook_prev_page_w, 1, 0, 0, H_gtk_notebook_prev_page, pl_tu); Xg_define_procedure(gtk_notebook_set_show_border, gxg_gtk_notebook_set_show_border_w, 2, 0, 0, H_gtk_notebook_set_show_border, pl_tub); Xg_define_procedure(gtk_notebook_get_show_border, gxg_gtk_notebook_get_show_border_w, 1, 0, 0, H_gtk_notebook_get_show_border, pl_bu); Xg_define_procedure(gtk_notebook_set_show_tabs, gxg_gtk_notebook_set_show_tabs_w, 2, 0, 0, H_gtk_notebook_set_show_tabs, pl_tub); Xg_define_procedure(gtk_notebook_get_show_tabs, gxg_gtk_notebook_get_show_tabs_w, 1, 0, 0, H_gtk_notebook_get_show_tabs, pl_bu); Xg_define_procedure(gtk_notebook_set_tab_pos, gxg_gtk_notebook_set_tab_pos_w, 2, 0, 0, H_gtk_notebook_set_tab_pos, pl_tui); Xg_define_procedure(gtk_notebook_get_tab_pos, gxg_gtk_notebook_get_tab_pos_w, 1, 0, 0, H_gtk_notebook_get_tab_pos, pl_iu); Xg_define_procedure(gtk_notebook_set_scrollable, gxg_gtk_notebook_set_scrollable_w, 2, 0, 0, H_gtk_notebook_set_scrollable, pl_tub); Xg_define_procedure(gtk_notebook_get_scrollable, gxg_gtk_notebook_get_scrollable_w, 1, 0, 0, H_gtk_notebook_get_scrollable, pl_bu); Xg_define_procedure(gtk_notebook_popup_enable, gxg_gtk_notebook_popup_enable_w, 1, 0, 0, H_gtk_notebook_popup_enable, pl_tu); Xg_define_procedure(gtk_notebook_popup_disable, gxg_gtk_notebook_popup_disable_w, 1, 0, 0, H_gtk_notebook_popup_disable, pl_tu); Xg_define_procedure(gtk_notebook_get_tab_label, gxg_gtk_notebook_get_tab_label_w, 2, 0, 0, H_gtk_notebook_get_tab_label, pl_pu); Xg_define_procedure(gtk_notebook_set_tab_label, gxg_gtk_notebook_set_tab_label_w, 3, 0, 0, H_gtk_notebook_set_tab_label, pl_tu); Xg_define_procedure(gtk_notebook_set_tab_label_text, gxg_gtk_notebook_set_tab_label_text_w, 3, 0, 0, H_gtk_notebook_set_tab_label_text, pl_tuus); Xg_define_procedure(gtk_notebook_get_tab_label_text, gxg_gtk_notebook_get_tab_label_text_w, 2, 0, 0, H_gtk_notebook_get_tab_label_text, pl_su); Xg_define_procedure(gtk_notebook_get_menu_label, gxg_gtk_notebook_get_menu_label_w, 2, 0, 0, H_gtk_notebook_get_menu_label, pl_pu); Xg_define_procedure(gtk_notebook_set_menu_label, gxg_gtk_notebook_set_menu_label_w, 3, 0, 0, H_gtk_notebook_set_menu_label, pl_tu); Xg_define_procedure(gtk_notebook_set_menu_label_text, gxg_gtk_notebook_set_menu_label_text_w, 3, 0, 0, H_gtk_notebook_set_menu_label_text, pl_tuus); Xg_define_procedure(gtk_notebook_get_menu_label_text, gxg_gtk_notebook_get_menu_label_text_w, 2, 0, 0, H_gtk_notebook_get_menu_label_text, pl_su); Xg_define_procedure(gtk_notebook_reorder_child, gxg_gtk_notebook_reorder_child_w, 3, 0, 0, H_gtk_notebook_reorder_child, pl_tuui); Xg_define_procedure(gtk_notebook_append_page, gxg_gtk_notebook_append_page_w, 3, 0, 0, H_gtk_notebook_append_page, pl_iu); Xg_define_procedure(gtk_notebook_append_page_menu, gxg_gtk_notebook_append_page_menu_w, 4, 0, 0, H_gtk_notebook_append_page_menu, pl_iu); Xg_define_procedure(gtk_notebook_prepend_page, gxg_gtk_notebook_prepend_page_w, 3, 0, 0, H_gtk_notebook_prepend_page, pl_iu); Xg_define_procedure(gtk_notebook_prepend_page_menu, gxg_gtk_notebook_prepend_page_menu_w, 4, 0, 0, H_gtk_notebook_prepend_page_menu, pl_iu); Xg_define_procedure(gtk_notebook_insert_page, gxg_gtk_notebook_insert_page_w, 4, 0, 0, H_gtk_notebook_insert_page, pl_iuuui); Xg_define_procedure(gtk_notebook_insert_page_menu, gxg_gtk_notebook_insert_page_menu_w, 5, 0, 0, H_gtk_notebook_insert_page_menu, pl_iuuuui); Xg_define_procedure(gtk_paned_add1, gxg_gtk_paned_add1_w, 2, 0, 0, H_gtk_paned_add1, pl_tu); Xg_define_procedure(gtk_paned_add2, gxg_gtk_paned_add2_w, 2, 0, 0, H_gtk_paned_add2, pl_tu); Xg_define_procedure(gtk_paned_pack1, gxg_gtk_paned_pack1_w, 4, 0, 0, H_gtk_paned_pack1, pl_tuub); Xg_define_procedure(gtk_paned_pack2, gxg_gtk_paned_pack2_w, 4, 0, 0, H_gtk_paned_pack2, pl_tuub); Xg_define_procedure(gtk_paned_get_position, gxg_gtk_paned_get_position_w, 1, 0, 0, H_gtk_paned_get_position, pl_iu); Xg_define_procedure(gtk_paned_set_position, gxg_gtk_paned_set_position_w, 2, 0, 0, H_gtk_paned_set_position, pl_tui); Xg_define_procedure(gtk_progress_bar_new, gxg_gtk_progress_bar_new_w, 0, 0, 0, H_gtk_progress_bar_new, pl_p); Xg_define_procedure(gtk_progress_bar_pulse, gxg_gtk_progress_bar_pulse_w, 1, 0, 0, H_gtk_progress_bar_pulse, pl_tu); Xg_define_procedure(gtk_progress_bar_set_text, gxg_gtk_progress_bar_set_text_w, 2, 0, 0, H_gtk_progress_bar_set_text, pl_tus); Xg_define_procedure(gtk_progress_bar_set_fraction, gxg_gtk_progress_bar_set_fraction_w, 2, 0, 0, H_gtk_progress_bar_set_fraction, pl_tur); Xg_define_procedure(gtk_progress_bar_set_pulse_step, gxg_gtk_progress_bar_set_pulse_step_w, 2, 0, 0, H_gtk_progress_bar_set_pulse_step, pl_tur); Xg_define_procedure(gtk_progress_bar_get_text, gxg_gtk_progress_bar_get_text_w, 1, 0, 0, H_gtk_progress_bar_get_text, pl_su); Xg_define_procedure(gtk_progress_bar_get_fraction, gxg_gtk_progress_bar_get_fraction_w, 1, 0, 0, H_gtk_progress_bar_get_fraction, pl_du); Xg_define_procedure(gtk_progress_bar_get_pulse_step, gxg_gtk_progress_bar_get_pulse_step_w, 1, 0, 0, H_gtk_progress_bar_get_pulse_step, pl_du); Xg_define_procedure(gtk_radio_button_new, gxg_gtk_radio_button_new_w, 1, 0, 0, H_gtk_radio_button_new, pl_pu); Xg_define_procedure(gtk_radio_button_new_from_widget, gxg_gtk_radio_button_new_from_widget_w, 1, 0, 0, H_gtk_radio_button_new_from_widget, pl_pu); Xg_define_procedure(gtk_radio_button_new_with_label, gxg_gtk_radio_button_new_with_label_w, 2, 0, 0, H_gtk_radio_button_new_with_label, pl_pus); Xg_define_procedure(gtk_radio_button_new_with_label_from_widget, gxg_gtk_radio_button_new_with_label_from_widget_w, 2, 0, 0, H_gtk_radio_button_new_with_label_from_widget, pl_pus); Xg_define_procedure(gtk_radio_button_new_with_mnemonic, gxg_gtk_radio_button_new_with_mnemonic_w, 2, 0, 0, H_gtk_radio_button_new_with_mnemonic, pl_pus); Xg_define_procedure(gtk_radio_button_new_with_mnemonic_from_widget, gxg_gtk_radio_button_new_with_mnemonic_from_widget_w, 2, 0, 0, H_gtk_radio_button_new_with_mnemonic_from_widget, pl_pus); Xg_define_procedure(gtk_radio_button_get_group, gxg_gtk_radio_button_get_group_w, 1, 0, 0, H_gtk_radio_button_get_group, pl_pu); Xg_define_procedure(gtk_radio_button_set_group, gxg_gtk_radio_button_set_group_w, 2, 0, 0, H_gtk_radio_button_set_group, pl_tu); Xg_define_procedure(gtk_radio_menu_item_new, gxg_gtk_radio_menu_item_new_w, 1, 0, 0, H_gtk_radio_menu_item_new, pl_pu); Xg_define_procedure(gtk_radio_menu_item_new_with_label, gxg_gtk_radio_menu_item_new_with_label_w, 2, 0, 0, H_gtk_radio_menu_item_new_with_label, pl_pus); Xg_define_procedure(gtk_radio_menu_item_new_with_mnemonic, gxg_gtk_radio_menu_item_new_with_mnemonic_w, 2, 0, 0, H_gtk_radio_menu_item_new_with_mnemonic, pl_pus); Xg_define_procedure(gtk_radio_menu_item_get_group, gxg_gtk_radio_menu_item_get_group_w, 1, 0, 0, H_gtk_radio_menu_item_get_group, pl_pu); Xg_define_procedure(gtk_radio_menu_item_set_group, gxg_gtk_radio_menu_item_set_group_w, 2, 0, 0, H_gtk_radio_menu_item_set_group, pl_tu); Xg_define_procedure(gtk_range_set_adjustment, gxg_gtk_range_set_adjustment_w, 2, 0, 0, H_gtk_range_set_adjustment, pl_tu); Xg_define_procedure(gtk_range_get_adjustment, gxg_gtk_range_get_adjustment_w, 1, 0, 0, H_gtk_range_get_adjustment, pl_pu); Xg_define_procedure(gtk_range_set_inverted, gxg_gtk_range_set_inverted_w, 2, 0, 0, H_gtk_range_set_inverted, pl_tub); Xg_define_procedure(gtk_range_get_inverted, gxg_gtk_range_get_inverted_w, 1, 0, 0, H_gtk_range_get_inverted, pl_bu); Xg_define_procedure(gtk_range_set_increments, gxg_gtk_range_set_increments_w, 3, 0, 0, H_gtk_range_set_increments, pl_tur); Xg_define_procedure(gtk_range_set_range, gxg_gtk_range_set_range_w, 3, 0, 0, H_gtk_range_set_range, pl_tur); Xg_define_procedure(gtk_range_set_value, gxg_gtk_range_set_value_w, 2, 0, 0, H_gtk_range_set_value, pl_tur); Xg_define_procedure(gtk_range_get_value, gxg_gtk_range_get_value_w, 1, 0, 0, H_gtk_range_get_value, pl_du); Xg_define_procedure(gtk_scale_set_digits, gxg_gtk_scale_set_digits_w, 2, 0, 0, H_gtk_scale_set_digits, pl_tui); Xg_define_procedure(gtk_scale_get_digits, gxg_gtk_scale_get_digits_w, 1, 0, 0, H_gtk_scale_get_digits, pl_iu); Xg_define_procedure(gtk_scale_set_draw_value, gxg_gtk_scale_set_draw_value_w, 2, 0, 0, H_gtk_scale_set_draw_value, pl_tub); Xg_define_procedure(gtk_scale_get_draw_value, gxg_gtk_scale_get_draw_value_w, 1, 0, 0, H_gtk_scale_get_draw_value, pl_bu); Xg_define_procedure(gtk_scale_set_value_pos, gxg_gtk_scale_set_value_pos_w, 2, 0, 0, H_gtk_scale_set_value_pos, pl_tui); Xg_define_procedure(gtk_scale_get_value_pos, gxg_gtk_scale_get_value_pos_w, 1, 0, 0, H_gtk_scale_get_value_pos, pl_iu); Xg_define_procedure(gtk_scrolled_window_new, gxg_gtk_scrolled_window_new_w, 2, 0, 0, H_gtk_scrolled_window_new, pl_pu); Xg_define_procedure(gtk_scrolled_window_set_hadjustment, gxg_gtk_scrolled_window_set_hadjustment_w, 2, 0, 0, H_gtk_scrolled_window_set_hadjustment, pl_tu); Xg_define_procedure(gtk_scrolled_window_set_vadjustment, gxg_gtk_scrolled_window_set_vadjustment_w, 2, 0, 0, H_gtk_scrolled_window_set_vadjustment, pl_tu); Xg_define_procedure(gtk_scrolled_window_get_hadjustment, gxg_gtk_scrolled_window_get_hadjustment_w, 1, 0, 0, H_gtk_scrolled_window_get_hadjustment, pl_pu); Xg_define_procedure(gtk_scrolled_window_get_vadjustment, gxg_gtk_scrolled_window_get_vadjustment_w, 1, 0, 0, H_gtk_scrolled_window_get_vadjustment, pl_pu); Xg_define_procedure(gtk_scrolled_window_set_policy, gxg_gtk_scrolled_window_set_policy_w, 3, 0, 0, H_gtk_scrolled_window_set_policy, pl_tui); Xg_define_procedure(gtk_scrolled_window_get_policy, gxg_gtk_scrolled_window_get_policy_w, 1, 2, 0, H_gtk_scrolled_window_get_policy, pl_tu); Xg_define_procedure(gtk_scrolled_window_set_placement, gxg_gtk_scrolled_window_set_placement_w, 2, 0, 0, H_gtk_scrolled_window_set_placement, pl_tui); Xg_define_procedure(gtk_scrolled_window_get_placement, gxg_gtk_scrolled_window_get_placement_w, 1, 0, 0, H_gtk_scrolled_window_get_placement, pl_iu); Xg_define_procedure(gtk_scrolled_window_set_shadow_type, gxg_gtk_scrolled_window_set_shadow_type_w, 2, 0, 0, H_gtk_scrolled_window_set_shadow_type, pl_tui); Xg_define_procedure(gtk_scrolled_window_get_shadow_type, gxg_gtk_scrolled_window_get_shadow_type_w, 1, 0, 0, H_gtk_scrolled_window_get_shadow_type, pl_iu); Xg_define_procedure(gtk_target_list_new, gxg_gtk_target_list_new_w, 2, 0, 0, H_gtk_target_list_new, pl_pui); Xg_define_procedure(gtk_target_list_unref, gxg_gtk_target_list_unref_w, 1, 0, 0, H_gtk_target_list_unref, pl_tu); Xg_define_procedure(gtk_target_list_add, gxg_gtk_target_list_add_w, 4, 0, 0, H_gtk_target_list_add, pl_tuti); Xg_define_procedure(gtk_target_list_add_table, gxg_gtk_target_list_add_table_w, 3, 0, 0, H_gtk_target_list_add_table, pl_tuui); Xg_define_procedure(gtk_target_list_remove, gxg_gtk_target_list_remove_w, 2, 0, 0, H_gtk_target_list_remove, pl_tut); Xg_define_procedure(gtk_target_list_find, gxg_gtk_target_list_find_w, 2, 1, 0, H_gtk_target_list_find, pl_butu); Xg_define_procedure(gtk_selection_owner_set, gxg_gtk_selection_owner_set_w, 3, 0, 0, H_gtk_selection_owner_set, pl_buti); Xg_define_procedure(gtk_selection_add_target, gxg_gtk_selection_add_target_w, 4, 0, 0, H_gtk_selection_add_target, pl_tutti); Xg_define_procedure(gtk_selection_add_targets, gxg_gtk_selection_add_targets_w, 4, 0, 0, H_gtk_selection_add_targets, pl_tutui); Xg_define_procedure(gtk_selection_clear_targets, gxg_gtk_selection_clear_targets_w, 2, 0, 0, H_gtk_selection_clear_targets, pl_tut); Xg_define_procedure(gtk_selection_convert, gxg_gtk_selection_convert_w, 4, 0, 0, H_gtk_selection_convert, pl_butti); Xg_define_procedure(gtk_selection_data_set, gxg_gtk_selection_data_set_w, 5, 0, 0, H_gtk_selection_data_set, pl_tutisi); Xg_define_procedure(gtk_selection_data_set_text, gxg_gtk_selection_data_set_text_w, 3, 0, 0, H_gtk_selection_data_set_text, pl_busi); Xg_define_procedure(gtk_selection_data_get_text, gxg_gtk_selection_data_get_text_w, 1, 0, 0, H_gtk_selection_data_get_text, pl_su); Xg_define_procedure(gtk_selection_data_get_targets, gxg_gtk_selection_data_get_targets_w, 1, 2, 0, H_gtk_selection_data_get_targets, pl_bu); Xg_define_procedure(gtk_selection_data_targets_include_text, gxg_gtk_selection_data_targets_include_text_w, 1, 0, 0, H_gtk_selection_data_targets_include_text, pl_bu); Xg_define_procedure(gtk_selection_remove_all, gxg_gtk_selection_remove_all_w, 1, 0, 0, H_gtk_selection_remove_all, pl_tu); Xg_define_procedure(gtk_selection_data_copy, gxg_gtk_selection_data_copy_w, 1, 0, 0, H_gtk_selection_data_copy, pl_pu); Xg_define_procedure(gtk_selection_data_free, gxg_gtk_selection_data_free_w, 1, 0, 0, H_gtk_selection_data_free, pl_tu); Xg_define_procedure(gtk_separator_menu_item_new, gxg_gtk_separator_menu_item_new_w, 0, 0, 0, H_gtk_separator_menu_item_new, pl_p); Xg_define_procedure(gtk_settings_get_default, gxg_gtk_settings_get_default_w, 0, 0, 0, H_gtk_settings_get_default, pl_p); Xg_define_procedure(gtk_size_group_new, gxg_gtk_size_group_new_w, 1, 0, 0, H_gtk_size_group_new, pl_pi); Xg_define_procedure(gtk_size_group_set_mode, gxg_gtk_size_group_set_mode_w, 2, 0, 0, H_gtk_size_group_set_mode, pl_tui); Xg_define_procedure(gtk_size_group_get_mode, gxg_gtk_size_group_get_mode_w, 1, 0, 0, H_gtk_size_group_get_mode, pl_iu); Xg_define_procedure(gtk_size_group_add_widget, gxg_gtk_size_group_add_widget_w, 2, 0, 0, H_gtk_size_group_add_widget, pl_tu); Xg_define_procedure(gtk_size_group_remove_widget, gxg_gtk_size_group_remove_widget_w, 2, 0, 0, H_gtk_size_group_remove_widget, pl_tu); Xg_define_procedure(gtk_spin_button_configure, gxg_gtk_spin_button_configure_w, 4, 0, 0, H_gtk_spin_button_configure, pl_tuuri); Xg_define_procedure(gtk_spin_button_new, gxg_gtk_spin_button_new_w, 3, 0, 0, H_gtk_spin_button_new, pl_puri); Xg_define_procedure(gtk_spin_button_new_with_range, gxg_gtk_spin_button_new_with_range_w, 3, 0, 0, H_gtk_spin_button_new_with_range, pl_pr); Xg_define_procedure(gtk_spin_button_set_adjustment, gxg_gtk_spin_button_set_adjustment_w, 2, 0, 0, H_gtk_spin_button_set_adjustment, pl_tu); Xg_define_procedure(gtk_spin_button_get_adjustment, gxg_gtk_spin_button_get_adjustment_w, 1, 0, 0, H_gtk_spin_button_get_adjustment, pl_pu); Xg_define_procedure(gtk_spin_button_set_digits, gxg_gtk_spin_button_set_digits_w, 2, 0, 0, H_gtk_spin_button_set_digits, pl_tui); Xg_define_procedure(gtk_spin_button_get_digits, gxg_gtk_spin_button_get_digits_w, 1, 0, 0, H_gtk_spin_button_get_digits, pl_iu); Xg_define_procedure(gtk_spin_button_set_increments, gxg_gtk_spin_button_set_increments_w, 3, 0, 0, H_gtk_spin_button_set_increments, pl_tur); Xg_define_procedure(gtk_spin_button_get_increments, gxg_gtk_spin_button_get_increments_w, 1, 2, 0, H_gtk_spin_button_get_increments, pl_tu); Xg_define_procedure(gtk_spin_button_set_range, gxg_gtk_spin_button_set_range_w, 3, 0, 0, H_gtk_spin_button_set_range, pl_tur); Xg_define_procedure(gtk_spin_button_get_range, gxg_gtk_spin_button_get_range_w, 1, 2, 0, H_gtk_spin_button_get_range, pl_tu); Xg_define_procedure(gtk_spin_button_get_value, gxg_gtk_spin_button_get_value_w, 1, 0, 0, H_gtk_spin_button_get_value, pl_du); Xg_define_procedure(gtk_spin_button_get_value_as_int, gxg_gtk_spin_button_get_value_as_int_w, 1, 0, 0, H_gtk_spin_button_get_value_as_int, pl_iu); Xg_define_procedure(gtk_spin_button_set_value, gxg_gtk_spin_button_set_value_w, 2, 0, 0, H_gtk_spin_button_set_value, pl_tur); Xg_define_procedure(gtk_spin_button_set_update_policy, gxg_gtk_spin_button_set_update_policy_w, 2, 0, 0, H_gtk_spin_button_set_update_policy, pl_tui); Xg_define_procedure(gtk_spin_button_get_update_policy, gxg_gtk_spin_button_get_update_policy_w, 1, 0, 0, H_gtk_spin_button_get_update_policy, pl_iu); Xg_define_procedure(gtk_spin_button_set_numeric, gxg_gtk_spin_button_set_numeric_w, 2, 0, 0, H_gtk_spin_button_set_numeric, pl_tub); Xg_define_procedure(gtk_spin_button_get_numeric, gxg_gtk_spin_button_get_numeric_w, 1, 0, 0, H_gtk_spin_button_get_numeric, pl_bu); Xg_define_procedure(gtk_spin_button_spin, gxg_gtk_spin_button_spin_w, 3, 0, 0, H_gtk_spin_button_spin, pl_tuir); Xg_define_procedure(gtk_spin_button_set_wrap, gxg_gtk_spin_button_set_wrap_w, 2, 0, 0, H_gtk_spin_button_set_wrap, pl_tub); Xg_define_procedure(gtk_spin_button_get_wrap, gxg_gtk_spin_button_get_wrap_w, 1, 0, 0, H_gtk_spin_button_get_wrap, pl_bu); Xg_define_procedure(gtk_spin_button_set_snap_to_ticks, gxg_gtk_spin_button_set_snap_to_ticks_w, 2, 0, 0, H_gtk_spin_button_set_snap_to_ticks, pl_tub); Xg_define_procedure(gtk_spin_button_get_snap_to_ticks, gxg_gtk_spin_button_get_snap_to_ticks_w, 1, 0, 0, H_gtk_spin_button_get_snap_to_ticks, pl_bu); Xg_define_procedure(gtk_spin_button_update, gxg_gtk_spin_button_update_w, 1, 0, 0, H_gtk_spin_button_update, pl_tu); Xg_define_procedure(gtk_statusbar_new, gxg_gtk_statusbar_new_w, 0, 0, 0, H_gtk_statusbar_new, pl_p); Xg_define_procedure(gtk_statusbar_get_context_id, gxg_gtk_statusbar_get_context_id_w, 2, 0, 0, H_gtk_statusbar_get_context_id, pl_ius); Xg_define_procedure(gtk_statusbar_push, gxg_gtk_statusbar_push_w, 3, 0, 0, H_gtk_statusbar_push, pl_iuis); Xg_define_procedure(gtk_statusbar_pop, gxg_gtk_statusbar_pop_w, 2, 0, 0, H_gtk_statusbar_pop, pl_tui); Xg_define_procedure(gtk_statusbar_remove, gxg_gtk_statusbar_remove_w, 3, 0, 0, H_gtk_statusbar_remove, pl_tui); Xg_define_procedure(gtk_text_buffer_new, gxg_gtk_text_buffer_new_w, 1, 0, 0, H_gtk_text_buffer_new, pl_pu); Xg_define_procedure(gtk_text_buffer_get_line_count, gxg_gtk_text_buffer_get_line_count_w, 1, 0, 0, H_gtk_text_buffer_get_line_count, pl_iu); Xg_define_procedure(gtk_text_buffer_get_char_count, gxg_gtk_text_buffer_get_char_count_w, 1, 0, 0, H_gtk_text_buffer_get_char_count, pl_iu); Xg_define_procedure(gtk_text_buffer_get_tag_table, gxg_gtk_text_buffer_get_tag_table_w, 1, 0, 0, H_gtk_text_buffer_get_tag_table, pl_pu); Xg_define_procedure(gtk_text_buffer_set_text, gxg_gtk_text_buffer_set_text_w, 3, 0, 0, H_gtk_text_buffer_set_text, pl_tusi); Xg_define_procedure(gtk_text_buffer_insert, gxg_gtk_text_buffer_insert_w, 4, 0, 0, H_gtk_text_buffer_insert, pl_tuusi); Xg_define_procedure(gtk_text_buffer_insert_at_cursor, gxg_gtk_text_buffer_insert_at_cursor_w, 3, 0, 0, H_gtk_text_buffer_insert_at_cursor, pl_tusi); Xg_define_procedure(gtk_text_buffer_insert_interactive, gxg_gtk_text_buffer_insert_interactive_w, 5, 0, 0, H_gtk_text_buffer_insert_interactive, pl_buusib); Xg_define_procedure(gtk_text_buffer_insert_interactive_at_cursor, gxg_gtk_text_buffer_insert_interactive_at_cursor_w, 4, 0, 0, H_gtk_text_buffer_insert_interactive_at_cursor, pl_busib); Xg_define_procedure(gtk_text_buffer_insert_range, gxg_gtk_text_buffer_insert_range_w, 4, 0, 0, H_gtk_text_buffer_insert_range, pl_tu); Xg_define_procedure(gtk_text_buffer_insert_range_interactive, gxg_gtk_text_buffer_insert_range_interactive_w, 5, 0, 0, H_gtk_text_buffer_insert_range_interactive, pl_buuuub); Xg_define_procedure(gtk_text_buffer_insert_with_tags, gxg_gtk_text_buffer_insert_with_tags_w, 5, 0, 0, H_gtk_text_buffer_insert_with_tags, pl_tuusit); Xg_define_procedure(gtk_text_buffer_insert_with_tags_by_name, gxg_gtk_text_buffer_insert_with_tags_by_name_w, 5, 0, 0, H_gtk_text_buffer_insert_with_tags_by_name, pl_tuusit); Xg_define_procedure(gtk_text_buffer_delete, gxg_gtk_text_buffer_delete_w, 3, 0, 0, H_gtk_text_buffer_delete, pl_tu); Xg_define_procedure(gtk_text_buffer_delete_interactive, gxg_gtk_text_buffer_delete_interactive_w, 4, 0, 0, H_gtk_text_buffer_delete_interactive, pl_buuub); Xg_define_procedure(gtk_text_buffer_get_text, gxg_gtk_text_buffer_get_text_w, 4, 0, 0, H_gtk_text_buffer_get_text, pl_suuub); Xg_define_procedure(gtk_text_buffer_get_slice, gxg_gtk_text_buffer_get_slice_w, 4, 0, 0, H_gtk_text_buffer_get_slice, pl_suuub); Xg_define_procedure(gtk_text_buffer_insert_pixbuf, gxg_gtk_text_buffer_insert_pixbuf_w, 3, 0, 0, H_gtk_text_buffer_insert_pixbuf, pl_tu); Xg_define_procedure(gtk_text_buffer_insert_child_anchor, gxg_gtk_text_buffer_insert_child_anchor_w, 3, 0, 0, H_gtk_text_buffer_insert_child_anchor, pl_tu); Xg_define_procedure(gtk_text_buffer_create_child_anchor, gxg_gtk_text_buffer_create_child_anchor_w, 2, 0, 0, H_gtk_text_buffer_create_child_anchor, pl_pu); Xg_define_procedure(gtk_text_buffer_create_mark, gxg_gtk_text_buffer_create_mark_w, 4, 0, 0, H_gtk_text_buffer_create_mark, pl_pusub); Xg_define_procedure(gtk_text_buffer_move_mark, gxg_gtk_text_buffer_move_mark_w, 3, 0, 0, H_gtk_text_buffer_move_mark, pl_tu); Xg_define_procedure(gtk_text_buffer_delete_mark, gxg_gtk_text_buffer_delete_mark_w, 2, 0, 0, H_gtk_text_buffer_delete_mark, pl_tu); Xg_define_procedure(gtk_text_buffer_get_mark, gxg_gtk_text_buffer_get_mark_w, 2, 0, 0, H_gtk_text_buffer_get_mark, pl_pus); Xg_define_procedure(gtk_text_buffer_move_mark_by_name, gxg_gtk_text_buffer_move_mark_by_name_w, 3, 0, 0, H_gtk_text_buffer_move_mark_by_name, pl_tusu); Xg_define_procedure(gtk_text_buffer_delete_mark_by_name, gxg_gtk_text_buffer_delete_mark_by_name_w, 2, 0, 0, H_gtk_text_buffer_delete_mark_by_name, pl_tus); Xg_define_procedure(gtk_text_buffer_get_insert, gxg_gtk_text_buffer_get_insert_w, 1, 0, 0, H_gtk_text_buffer_get_insert, pl_pu); Xg_define_procedure(gtk_text_buffer_get_selection_bound, gxg_gtk_text_buffer_get_selection_bound_w, 1, 0, 0, H_gtk_text_buffer_get_selection_bound, pl_pu); Xg_define_procedure(gtk_text_buffer_place_cursor, gxg_gtk_text_buffer_place_cursor_w, 2, 0, 0, H_gtk_text_buffer_place_cursor, pl_tu); Xg_define_procedure(gtk_text_buffer_apply_tag, gxg_gtk_text_buffer_apply_tag_w, 4, 0, 0, H_gtk_text_buffer_apply_tag, pl_tu); Xg_define_procedure(gtk_text_buffer_remove_tag, gxg_gtk_text_buffer_remove_tag_w, 4, 0, 0, H_gtk_text_buffer_remove_tag, pl_tu); Xg_define_procedure(gtk_text_buffer_apply_tag_by_name, gxg_gtk_text_buffer_apply_tag_by_name_w, 4, 0, 0, H_gtk_text_buffer_apply_tag_by_name, pl_tusu); Xg_define_procedure(gtk_text_buffer_remove_tag_by_name, gxg_gtk_text_buffer_remove_tag_by_name_w, 4, 0, 0, H_gtk_text_buffer_remove_tag_by_name, pl_tusu); Xg_define_procedure(gtk_text_buffer_remove_all_tags, gxg_gtk_text_buffer_remove_all_tags_w, 3, 0, 0, H_gtk_text_buffer_remove_all_tags, pl_tu); Xg_define_procedure(gtk_text_buffer_create_tag, gxg_gtk_text_buffer_create_tag_w, 2, 1, 0, H_gtk_text_buffer_create_tag, pl_pust); Xg_define_procedure(gtk_text_buffer_get_iter_at_line_offset, gxg_gtk_text_buffer_get_iter_at_line_offset_w, 4, 0, 0, H_gtk_text_buffer_get_iter_at_line_offset, pl_tuui); Xg_define_procedure(gtk_text_buffer_get_iter_at_line_index, gxg_gtk_text_buffer_get_iter_at_line_index_w, 4, 0, 0, H_gtk_text_buffer_get_iter_at_line_index, pl_tuui); Xg_define_procedure(gtk_text_buffer_get_iter_at_offset, gxg_gtk_text_buffer_get_iter_at_offset_w, 3, 0, 0, H_gtk_text_buffer_get_iter_at_offset, pl_tuui); Xg_define_procedure(gtk_text_buffer_get_iter_at_line, gxg_gtk_text_buffer_get_iter_at_line_w, 3, 0, 0, H_gtk_text_buffer_get_iter_at_line, pl_tuui); Xg_define_procedure(gtk_text_buffer_get_start_iter, gxg_gtk_text_buffer_get_start_iter_w, 2, 0, 0, H_gtk_text_buffer_get_start_iter, pl_tu); Xg_define_procedure(gtk_text_buffer_get_end_iter, gxg_gtk_text_buffer_get_end_iter_w, 2, 0, 0, H_gtk_text_buffer_get_end_iter, pl_tu); Xg_define_procedure(gtk_text_buffer_get_bounds, gxg_gtk_text_buffer_get_bounds_w, 3, 0, 0, H_gtk_text_buffer_get_bounds, pl_tu); Xg_define_procedure(gtk_text_buffer_get_iter_at_mark, gxg_gtk_text_buffer_get_iter_at_mark_w, 3, 0, 0, H_gtk_text_buffer_get_iter_at_mark, pl_tu); Xg_define_procedure(gtk_text_buffer_get_iter_at_child_anchor, gxg_gtk_text_buffer_get_iter_at_child_anchor_w, 3, 0, 0, H_gtk_text_buffer_get_iter_at_child_anchor, pl_tu); Xg_define_procedure(gtk_text_buffer_get_modified, gxg_gtk_text_buffer_get_modified_w, 1, 0, 0, H_gtk_text_buffer_get_modified, pl_bu); Xg_define_procedure(gtk_text_buffer_set_modified, gxg_gtk_text_buffer_set_modified_w, 2, 0, 0, H_gtk_text_buffer_set_modified, pl_tub); Xg_define_procedure(gtk_text_buffer_add_selection_clipboard, gxg_gtk_text_buffer_add_selection_clipboard_w, 2, 0, 0, H_gtk_text_buffer_add_selection_clipboard, pl_tu); Xg_define_procedure(gtk_text_buffer_remove_selection_clipboard, gxg_gtk_text_buffer_remove_selection_clipboard_w, 2, 0, 0, H_gtk_text_buffer_remove_selection_clipboard, pl_tu); Xg_define_procedure(gtk_text_buffer_cut_clipboard, gxg_gtk_text_buffer_cut_clipboard_w, 3, 0, 0, H_gtk_text_buffer_cut_clipboard, pl_tuub); Xg_define_procedure(gtk_text_buffer_copy_clipboard, gxg_gtk_text_buffer_copy_clipboard_w, 2, 0, 0, H_gtk_text_buffer_copy_clipboard, pl_tu); Xg_define_procedure(gtk_text_buffer_paste_clipboard, gxg_gtk_text_buffer_paste_clipboard_w, 4, 0, 0, H_gtk_text_buffer_paste_clipboard, pl_tuuub); Xg_define_procedure(gtk_text_buffer_get_selection_bounds, gxg_gtk_text_buffer_get_selection_bounds_w, 3, 0, 0, H_gtk_text_buffer_get_selection_bounds, pl_bu); Xg_define_procedure(gtk_text_buffer_delete_selection, gxg_gtk_text_buffer_delete_selection_w, 3, 0, 0, H_gtk_text_buffer_delete_selection, pl_bub); Xg_define_procedure(gtk_text_buffer_begin_user_action, gxg_gtk_text_buffer_begin_user_action_w, 1, 0, 0, H_gtk_text_buffer_begin_user_action, pl_tu); Xg_define_procedure(gtk_text_buffer_end_user_action, gxg_gtk_text_buffer_end_user_action_w, 1, 0, 0, H_gtk_text_buffer_end_user_action, pl_tu); Xg_define_procedure(gtk_text_child_anchor_new, gxg_gtk_text_child_anchor_new_w, 0, 0, 0, H_gtk_text_child_anchor_new, pl_p); Xg_define_procedure(gtk_text_child_anchor_get_widgets, gxg_gtk_text_child_anchor_get_widgets_w, 1, 0, 0, H_gtk_text_child_anchor_get_widgets, pl_pu); Xg_define_procedure(gtk_text_child_anchor_get_deleted, gxg_gtk_text_child_anchor_get_deleted_w, 1, 0, 0, H_gtk_text_child_anchor_get_deleted, pl_bu); Xg_define_procedure(gtk_text_iter_get_buffer, gxg_gtk_text_iter_get_buffer_w, 1, 0, 0, H_gtk_text_iter_get_buffer, pl_pu); Xg_define_procedure(gtk_text_iter_copy, gxg_gtk_text_iter_copy_w, 1, 0, 0, H_gtk_text_iter_copy, pl_pu); Xg_define_procedure(gtk_text_iter_free, gxg_gtk_text_iter_free_w, 1, 0, 0, H_gtk_text_iter_free, pl_tu); Xg_define_procedure(gtk_text_iter_get_offset, gxg_gtk_text_iter_get_offset_w, 1, 0, 0, H_gtk_text_iter_get_offset, pl_iu); Xg_define_procedure(gtk_text_iter_get_line, gxg_gtk_text_iter_get_line_w, 1, 0, 0, H_gtk_text_iter_get_line, pl_iu); Xg_define_procedure(gtk_text_iter_get_line_offset, gxg_gtk_text_iter_get_line_offset_w, 1, 0, 0, H_gtk_text_iter_get_line_offset, pl_iu); Xg_define_procedure(gtk_text_iter_get_line_index, gxg_gtk_text_iter_get_line_index_w, 1, 0, 0, H_gtk_text_iter_get_line_index, pl_iu); Xg_define_procedure(gtk_text_iter_get_visible_line_offset, gxg_gtk_text_iter_get_visible_line_offset_w, 1, 0, 0, H_gtk_text_iter_get_visible_line_offset, pl_iu); Xg_define_procedure(gtk_text_iter_get_visible_line_index, gxg_gtk_text_iter_get_visible_line_index_w, 1, 0, 0, H_gtk_text_iter_get_visible_line_index, pl_iu); Xg_define_procedure(gtk_text_iter_get_char, gxg_gtk_text_iter_get_char_w, 1, 0, 0, H_gtk_text_iter_get_char, pl_iu); Xg_define_procedure(gtk_text_iter_get_slice, gxg_gtk_text_iter_get_slice_w, 2, 0, 0, H_gtk_text_iter_get_slice, pl_su); Xg_define_procedure(gtk_text_iter_get_text, gxg_gtk_text_iter_get_text_w, 2, 0, 0, H_gtk_text_iter_get_text, pl_su); Xg_define_procedure(gtk_text_iter_get_visible_slice, gxg_gtk_text_iter_get_visible_slice_w, 2, 0, 0, H_gtk_text_iter_get_visible_slice, pl_su); Xg_define_procedure(gtk_text_iter_get_visible_text, gxg_gtk_text_iter_get_visible_text_w, 2, 0, 0, H_gtk_text_iter_get_visible_text, pl_su); Xg_define_procedure(gtk_text_iter_get_pixbuf, gxg_gtk_text_iter_get_pixbuf_w, 1, 0, 0, H_gtk_text_iter_get_pixbuf, pl_pu); Xg_define_procedure(gtk_text_iter_get_marks, gxg_gtk_text_iter_get_marks_w, 1, 0, 0, H_gtk_text_iter_get_marks, pl_pu); Xg_define_procedure(gtk_text_iter_get_child_anchor, gxg_gtk_text_iter_get_child_anchor_w, 1, 0, 0, H_gtk_text_iter_get_child_anchor, pl_pu); Xg_define_procedure(gtk_text_iter_get_toggled_tags, gxg_gtk_text_iter_get_toggled_tags_w, 2, 0, 0, H_gtk_text_iter_get_toggled_tags, pl_pub); Xg_define_procedure(gtk_text_iter_begins_tag, gxg_gtk_text_iter_begins_tag_w, 2, 0, 0, H_gtk_text_iter_begins_tag, pl_bu); Xg_define_procedure(gtk_text_iter_ends_tag, gxg_gtk_text_iter_ends_tag_w, 2, 0, 0, H_gtk_text_iter_ends_tag, pl_bu); Xg_define_procedure(gtk_text_iter_toggles_tag, gxg_gtk_text_iter_toggles_tag_w, 2, 0, 0, H_gtk_text_iter_toggles_tag, pl_bu); Xg_define_procedure(gtk_text_iter_has_tag, gxg_gtk_text_iter_has_tag_w, 2, 0, 0, H_gtk_text_iter_has_tag, pl_bu); Xg_define_procedure(gtk_text_iter_get_tags, gxg_gtk_text_iter_get_tags_w, 1, 0, 0, H_gtk_text_iter_get_tags, pl_pu); Xg_define_procedure(gtk_text_iter_editable, gxg_gtk_text_iter_editable_w, 2, 0, 0, H_gtk_text_iter_editable, pl_bub); Xg_define_procedure(gtk_text_iter_can_insert, gxg_gtk_text_iter_can_insert_w, 2, 0, 0, H_gtk_text_iter_can_insert, pl_bub); Xg_define_procedure(gtk_text_iter_starts_word, gxg_gtk_text_iter_starts_word_w, 1, 0, 0, H_gtk_text_iter_starts_word, pl_bu); Xg_define_procedure(gtk_text_iter_ends_word, gxg_gtk_text_iter_ends_word_w, 1, 0, 0, H_gtk_text_iter_ends_word, pl_bu); Xg_define_procedure(gtk_text_iter_inside_word, gxg_gtk_text_iter_inside_word_w, 1, 0, 0, H_gtk_text_iter_inside_word, pl_bu); Xg_define_procedure(gtk_text_iter_starts_sentence, gxg_gtk_text_iter_starts_sentence_w, 1, 0, 0, H_gtk_text_iter_starts_sentence, pl_bu); Xg_define_procedure(gtk_text_iter_ends_sentence, gxg_gtk_text_iter_ends_sentence_w, 1, 0, 0, H_gtk_text_iter_ends_sentence, pl_bu); Xg_define_procedure(gtk_text_iter_inside_sentence, gxg_gtk_text_iter_inside_sentence_w, 1, 0, 0, H_gtk_text_iter_inside_sentence, pl_bu); Xg_define_procedure(gtk_text_iter_starts_line, gxg_gtk_text_iter_starts_line_w, 1, 0, 0, H_gtk_text_iter_starts_line, pl_bu); Xg_define_procedure(gtk_text_iter_ends_line, gxg_gtk_text_iter_ends_line_w, 1, 0, 0, H_gtk_text_iter_ends_line, pl_bu); Xg_define_procedure(gtk_text_iter_is_cursor_position, gxg_gtk_text_iter_is_cursor_position_w, 1, 0, 0, H_gtk_text_iter_is_cursor_position, pl_bu); Xg_define_procedure(gtk_text_iter_get_chars_in_line, gxg_gtk_text_iter_get_chars_in_line_w, 1, 0, 0, H_gtk_text_iter_get_chars_in_line, pl_iu); Xg_define_procedure(gtk_text_iter_get_bytes_in_line, gxg_gtk_text_iter_get_bytes_in_line_w, 1, 0, 0, H_gtk_text_iter_get_bytes_in_line, pl_iu); Xg_define_procedure(gtk_text_iter_get_attributes, gxg_gtk_text_iter_get_attributes_w, 2, 0, 0, H_gtk_text_iter_get_attributes, pl_bu); Xg_define_procedure(gtk_text_iter_get_language, gxg_gtk_text_iter_get_language_w, 1, 0, 0, H_gtk_text_iter_get_language, pl_pu); Xg_define_procedure(gtk_text_iter_is_end, gxg_gtk_text_iter_is_end_w, 1, 0, 0, H_gtk_text_iter_is_end, pl_bu); Xg_define_procedure(gtk_text_iter_is_start, gxg_gtk_text_iter_is_start_w, 1, 0, 0, H_gtk_text_iter_is_start, pl_bu); Xg_define_procedure(gtk_text_iter_forward_char, gxg_gtk_text_iter_forward_char_w, 1, 0, 0, H_gtk_text_iter_forward_char, pl_bu); Xg_define_procedure(gtk_text_iter_backward_char, gxg_gtk_text_iter_backward_char_w, 1, 0, 0, H_gtk_text_iter_backward_char, pl_bu); Xg_define_procedure(gtk_text_iter_forward_chars, gxg_gtk_text_iter_forward_chars_w, 2, 0, 0, H_gtk_text_iter_forward_chars, pl_bui); Xg_define_procedure(gtk_text_iter_backward_chars, gxg_gtk_text_iter_backward_chars_w, 2, 0, 0, H_gtk_text_iter_backward_chars, pl_bui); Xg_define_procedure(gtk_text_iter_forward_line, gxg_gtk_text_iter_forward_line_w, 1, 0, 0, H_gtk_text_iter_forward_line, pl_bu); Xg_define_procedure(gtk_text_iter_backward_line, gxg_gtk_text_iter_backward_line_w, 1, 0, 0, H_gtk_text_iter_backward_line, pl_bu); Xg_define_procedure(gtk_text_iter_forward_lines, gxg_gtk_text_iter_forward_lines_w, 2, 0, 0, H_gtk_text_iter_forward_lines, pl_bui); Xg_define_procedure(gtk_text_iter_backward_lines, gxg_gtk_text_iter_backward_lines_w, 2, 0, 0, H_gtk_text_iter_backward_lines, pl_bui); Xg_define_procedure(gtk_text_iter_forward_word_end, gxg_gtk_text_iter_forward_word_end_w, 1, 0, 0, H_gtk_text_iter_forward_word_end, pl_bu); Xg_define_procedure(gtk_text_iter_backward_word_start, gxg_gtk_text_iter_backward_word_start_w, 1, 0, 0, H_gtk_text_iter_backward_word_start, pl_bu); Xg_define_procedure(gtk_text_iter_forward_word_ends, gxg_gtk_text_iter_forward_word_ends_w, 2, 0, 0, H_gtk_text_iter_forward_word_ends, pl_bui); Xg_define_procedure(gtk_text_iter_backward_word_starts, gxg_gtk_text_iter_backward_word_starts_w, 2, 0, 0, H_gtk_text_iter_backward_word_starts, pl_bui); Xg_define_procedure(gtk_text_iter_forward_sentence_end, gxg_gtk_text_iter_forward_sentence_end_w, 1, 0, 0, H_gtk_text_iter_forward_sentence_end, pl_bu); Xg_define_procedure(gtk_text_iter_backward_sentence_start, gxg_gtk_text_iter_backward_sentence_start_w, 1, 0, 0, H_gtk_text_iter_backward_sentence_start, pl_bu); Xg_define_procedure(gtk_text_iter_forward_sentence_ends, gxg_gtk_text_iter_forward_sentence_ends_w, 2, 0, 0, H_gtk_text_iter_forward_sentence_ends, pl_bui); Xg_define_procedure(gtk_text_iter_backward_sentence_starts, gxg_gtk_text_iter_backward_sentence_starts_w, 2, 0, 0, H_gtk_text_iter_backward_sentence_starts, pl_bui); Xg_define_procedure(gtk_text_iter_forward_cursor_position, gxg_gtk_text_iter_forward_cursor_position_w, 1, 0, 0, H_gtk_text_iter_forward_cursor_position, pl_bu); Xg_define_procedure(gtk_text_iter_backward_cursor_position, gxg_gtk_text_iter_backward_cursor_position_w, 1, 0, 0, H_gtk_text_iter_backward_cursor_position, pl_bu); Xg_define_procedure(gtk_text_iter_forward_cursor_positions, gxg_gtk_text_iter_forward_cursor_positions_w, 2, 0, 0, H_gtk_text_iter_forward_cursor_positions, pl_bui); Xg_define_procedure(gtk_text_iter_backward_cursor_positions, gxg_gtk_text_iter_backward_cursor_positions_w, 2, 0, 0, H_gtk_text_iter_backward_cursor_positions, pl_bui); Xg_define_procedure(gtk_text_iter_set_offset, gxg_gtk_text_iter_set_offset_w, 2, 0, 0, H_gtk_text_iter_set_offset, pl_tui); Xg_define_procedure(gtk_text_iter_set_line, gxg_gtk_text_iter_set_line_w, 2, 0, 0, H_gtk_text_iter_set_line, pl_tui); Xg_define_procedure(gtk_text_iter_set_line_offset, gxg_gtk_text_iter_set_line_offset_w, 2, 0, 0, H_gtk_text_iter_set_line_offset, pl_tui); Xg_define_procedure(gtk_text_iter_set_line_index, gxg_gtk_text_iter_set_line_index_w, 2, 0, 0, H_gtk_text_iter_set_line_index, pl_tui); Xg_define_procedure(gtk_text_iter_forward_to_end, gxg_gtk_text_iter_forward_to_end_w, 1, 0, 0, H_gtk_text_iter_forward_to_end, pl_tu); Xg_define_procedure(gtk_text_iter_forward_to_line_end, gxg_gtk_text_iter_forward_to_line_end_w, 1, 0, 0, H_gtk_text_iter_forward_to_line_end, pl_bu); Xg_define_procedure(gtk_text_iter_set_visible_line_offset, gxg_gtk_text_iter_set_visible_line_offset_w, 2, 0, 0, H_gtk_text_iter_set_visible_line_offset, pl_tui); Xg_define_procedure(gtk_text_iter_set_visible_line_index, gxg_gtk_text_iter_set_visible_line_index_w, 2, 0, 0, H_gtk_text_iter_set_visible_line_index, pl_tui); Xg_define_procedure(gtk_text_iter_forward_to_tag_toggle, gxg_gtk_text_iter_forward_to_tag_toggle_w, 2, 0, 0, H_gtk_text_iter_forward_to_tag_toggle, pl_bu); Xg_define_procedure(gtk_text_iter_backward_to_tag_toggle, gxg_gtk_text_iter_backward_to_tag_toggle_w, 2, 0, 0, H_gtk_text_iter_backward_to_tag_toggle, pl_bu); Xg_define_procedure(gtk_text_iter_forward_find_char, gxg_gtk_text_iter_forward_find_char_w, 4, 0, 0, H_gtk_text_iter_forward_find_char, pl_buttu); Xg_define_procedure(gtk_text_iter_backward_find_char, gxg_gtk_text_iter_backward_find_char_w, 4, 0, 0, H_gtk_text_iter_backward_find_char, pl_buttu); Xg_define_procedure(gtk_text_iter_forward_search, gxg_gtk_text_iter_forward_search_w, 6, 0, 0, H_gtk_text_iter_forward_search, pl_busiu); Xg_define_procedure(gtk_text_iter_backward_search, gxg_gtk_text_iter_backward_search_w, 6, 0, 0, H_gtk_text_iter_backward_search, pl_busiu); Xg_define_procedure(gtk_text_iter_equal, gxg_gtk_text_iter_equal_w, 2, 0, 0, H_gtk_text_iter_equal, pl_bu); Xg_define_procedure(gtk_text_iter_compare, gxg_gtk_text_iter_compare_w, 2, 0, 0, H_gtk_text_iter_compare, pl_iu); Xg_define_procedure(gtk_text_iter_in_range, gxg_gtk_text_iter_in_range_w, 3, 0, 0, H_gtk_text_iter_in_range, pl_bu); Xg_define_procedure(gtk_text_iter_order, gxg_gtk_text_iter_order_w, 2, 0, 0, H_gtk_text_iter_order, pl_tu); Xg_define_procedure(gtk_text_mark_set_visible, gxg_gtk_text_mark_set_visible_w, 2, 0, 0, H_gtk_text_mark_set_visible, pl_tub); Xg_define_procedure(gtk_text_mark_get_visible, gxg_gtk_text_mark_get_visible_w, 1, 0, 0, H_gtk_text_mark_get_visible, pl_bu); Xg_define_procedure(gtk_text_mark_get_name, gxg_gtk_text_mark_get_name_w, 1, 0, 0, H_gtk_text_mark_get_name, pl_su); Xg_define_procedure(gtk_text_mark_get_deleted, gxg_gtk_text_mark_get_deleted_w, 1, 0, 0, H_gtk_text_mark_get_deleted, pl_bu); Xg_define_procedure(gtk_text_mark_get_buffer, gxg_gtk_text_mark_get_buffer_w, 1, 0, 0, H_gtk_text_mark_get_buffer, pl_pu); Xg_define_procedure(gtk_text_mark_get_left_gravity, gxg_gtk_text_mark_get_left_gravity_w, 1, 0, 0, H_gtk_text_mark_get_left_gravity, pl_bu); Xg_define_procedure(gtk_text_tag_new, gxg_gtk_text_tag_new_w, 1, 0, 0, H_gtk_text_tag_new, pl_ps); Xg_define_procedure(gtk_text_tag_get_priority, gxg_gtk_text_tag_get_priority_w, 1, 0, 0, H_gtk_text_tag_get_priority, pl_iu); Xg_define_procedure(gtk_text_tag_set_priority, gxg_gtk_text_tag_set_priority_w, 2, 0, 0, H_gtk_text_tag_set_priority, pl_tui); Xg_define_procedure(gtk_text_tag_event, gxg_gtk_text_tag_event_w, 4, 0, 0, H_gtk_text_tag_event, pl_bu); Xg_define_procedure(gtk_text_attributes_new, gxg_gtk_text_attributes_new_w, 0, 0, 0, H_gtk_text_attributes_new, pl_p); Xg_define_procedure(gtk_text_attributes_copy, gxg_gtk_text_attributes_copy_w, 1, 0, 0, H_gtk_text_attributes_copy, pl_pu); Xg_define_procedure(gtk_text_attributes_copy_values, gxg_gtk_text_attributes_copy_values_w, 2, 0, 0, H_gtk_text_attributes_copy_values, pl_tu); Xg_define_procedure(gtk_text_attributes_unref, gxg_gtk_text_attributes_unref_w, 1, 0, 0, H_gtk_text_attributes_unref, pl_tu); Xg_define_procedure(gtk_text_tag_table_new, gxg_gtk_text_tag_table_new_w, 0, 0, 0, H_gtk_text_tag_table_new, pl_p); Xg_define_procedure(gtk_text_tag_table_add, gxg_gtk_text_tag_table_add_w, 2, 0, 0, H_gtk_text_tag_table_add, pl_tu); Xg_define_procedure(gtk_text_tag_table_remove, gxg_gtk_text_tag_table_remove_w, 2, 0, 0, H_gtk_text_tag_table_remove, pl_tu); Xg_define_procedure(gtk_text_tag_table_lookup, gxg_gtk_text_tag_table_lookup_w, 2, 0, 0, H_gtk_text_tag_table_lookup, pl_pus); Xg_define_procedure(gtk_text_tag_table_foreach, gxg_gtk_text_tag_table_foreach_w, 2, 1, 0, H_gtk_text_tag_table_foreach, pl_tut); Xg_define_procedure(gtk_text_tag_table_get_size, gxg_gtk_text_tag_table_get_size_w, 1, 0, 0, H_gtk_text_tag_table_get_size, pl_iu); Xg_define_procedure(gtk_text_view_new, gxg_gtk_text_view_new_w, 0, 0, 0, H_gtk_text_view_new, pl_p); Xg_define_procedure(gtk_text_view_new_with_buffer, gxg_gtk_text_view_new_with_buffer_w, 1, 0, 0, H_gtk_text_view_new_with_buffer, pl_pu); Xg_define_procedure(gtk_text_view_set_buffer, gxg_gtk_text_view_set_buffer_w, 2, 0, 0, H_gtk_text_view_set_buffer, pl_tu); Xg_define_procedure(gtk_text_view_get_buffer, gxg_gtk_text_view_get_buffer_w, 1, 0, 0, H_gtk_text_view_get_buffer, pl_pu); Xg_define_procedure(gtk_text_view_scroll_to_iter, gxg_gtk_text_view_scroll_to_iter_w, 6, 0, 0, H_gtk_text_view_scroll_to_iter, pl_buurbr); Xg_define_procedure(gtk_text_view_scroll_to_mark, gxg_gtk_text_view_scroll_to_mark_w, 6, 0, 0, H_gtk_text_view_scroll_to_mark, pl_tuurbr); Xg_define_procedure(gtk_text_view_scroll_mark_onscreen, gxg_gtk_text_view_scroll_mark_onscreen_w, 2, 0, 0, H_gtk_text_view_scroll_mark_onscreen, pl_tu); Xg_define_procedure(gtk_text_view_move_mark_onscreen, gxg_gtk_text_view_move_mark_onscreen_w, 2, 0, 0, H_gtk_text_view_move_mark_onscreen, pl_bu); Xg_define_procedure(gtk_text_view_place_cursor_onscreen, gxg_gtk_text_view_place_cursor_onscreen_w, 1, 0, 0, H_gtk_text_view_place_cursor_onscreen, pl_bu); Xg_define_procedure(gtk_text_view_get_visible_rect, gxg_gtk_text_view_get_visible_rect_w, 2, 0, 0, H_gtk_text_view_get_visible_rect, pl_tu); Xg_define_procedure(gtk_text_view_set_cursor_visible, gxg_gtk_text_view_set_cursor_visible_w, 2, 0, 0, H_gtk_text_view_set_cursor_visible, pl_tub); Xg_define_procedure(gtk_text_view_get_cursor_visible, gxg_gtk_text_view_get_cursor_visible_w, 1, 0, 0, H_gtk_text_view_get_cursor_visible, pl_bu); Xg_define_procedure(gtk_text_view_get_iter_location, gxg_gtk_text_view_get_iter_location_w, 3, 0, 0, H_gtk_text_view_get_iter_location, pl_tu); Xg_define_procedure(gtk_text_view_get_iter_at_location, gxg_gtk_text_view_get_iter_at_location_w, 4, 0, 0, H_gtk_text_view_get_iter_at_location, pl_tuui); Xg_define_procedure(gtk_text_view_get_line_yrange, gxg_gtk_text_view_get_line_yrange_w, 2, 2, 0, H_gtk_text_view_get_line_yrange, pl_tu); Xg_define_procedure(gtk_text_view_get_line_at_y, gxg_gtk_text_view_get_line_at_y_w, 3, 1, 0, H_gtk_text_view_get_line_at_y, pl_tuuiu); Xg_define_procedure(gtk_text_view_buffer_to_window_coords, gxg_gtk_text_view_buffer_to_window_coords_w, 4, 2, 0, H_gtk_text_view_buffer_to_window_coords, pl_tuiiiu); Xg_define_procedure(gtk_text_view_window_to_buffer_coords, gxg_gtk_text_view_window_to_buffer_coords_w, 4, 2, 0, H_gtk_text_view_window_to_buffer_coords, pl_tuiiiu); Xg_define_procedure(gtk_text_view_get_window, gxg_gtk_text_view_get_window_w, 2, 0, 0, H_gtk_text_view_get_window, pl_pui); Xg_define_procedure(gtk_text_view_get_window_type, gxg_gtk_text_view_get_window_type_w, 2, 0, 0, H_gtk_text_view_get_window_type, pl_iu); Xg_define_procedure(gtk_text_view_set_border_window_size, gxg_gtk_text_view_set_border_window_size_w, 3, 0, 0, H_gtk_text_view_set_border_window_size, pl_tui); Xg_define_procedure(gtk_text_view_get_border_window_size, gxg_gtk_text_view_get_border_window_size_w, 2, 0, 0, H_gtk_text_view_get_border_window_size, pl_iui); Xg_define_procedure(gtk_text_view_forward_display_line, gxg_gtk_text_view_forward_display_line_w, 2, 0, 0, H_gtk_text_view_forward_display_line, pl_bu); Xg_define_procedure(gtk_text_view_backward_display_line, gxg_gtk_text_view_backward_display_line_w, 2, 0, 0, H_gtk_text_view_backward_display_line, pl_bu); Xg_define_procedure(gtk_text_view_forward_display_line_end, gxg_gtk_text_view_forward_display_line_end_w, 2, 0, 0, H_gtk_text_view_forward_display_line_end, pl_bu); Xg_define_procedure(gtk_text_view_backward_display_line_start, gxg_gtk_text_view_backward_display_line_start_w, 2, 0, 0, H_gtk_text_view_backward_display_line_start, pl_bu); Xg_define_procedure(gtk_text_view_starts_display_line, gxg_gtk_text_view_starts_display_line_w, 2, 0, 0, H_gtk_text_view_starts_display_line, pl_bu); Xg_define_procedure(gtk_text_view_move_visually, gxg_gtk_text_view_move_visually_w, 3, 0, 0, H_gtk_text_view_move_visually, pl_buui); Xg_define_procedure(gtk_text_view_add_child_at_anchor, gxg_gtk_text_view_add_child_at_anchor_w, 3, 0, 0, H_gtk_text_view_add_child_at_anchor, pl_tu); Xg_define_procedure(gtk_text_view_add_child_in_window, gxg_gtk_text_view_add_child_in_window_w, 5, 0, 0, H_gtk_text_view_add_child_in_window, pl_tuui); Xg_define_procedure(gtk_text_view_move_child, gxg_gtk_text_view_move_child_w, 4, 0, 0, H_gtk_text_view_move_child, pl_tuui); Xg_define_procedure(gtk_text_view_set_wrap_mode, gxg_gtk_text_view_set_wrap_mode_w, 2, 0, 0, H_gtk_text_view_set_wrap_mode, pl_tui); Xg_define_procedure(gtk_text_view_get_wrap_mode, gxg_gtk_text_view_get_wrap_mode_w, 1, 0, 0, H_gtk_text_view_get_wrap_mode, pl_iu); Xg_define_procedure(gtk_text_view_set_editable, gxg_gtk_text_view_set_editable_w, 2, 0, 0, H_gtk_text_view_set_editable, pl_tub); Xg_define_procedure(gtk_text_view_get_editable, gxg_gtk_text_view_get_editable_w, 1, 0, 0, H_gtk_text_view_get_editable, pl_bu); Xg_define_procedure(gtk_text_view_set_pixels_above_lines, gxg_gtk_text_view_set_pixels_above_lines_w, 2, 0, 0, H_gtk_text_view_set_pixels_above_lines, pl_tui); Xg_define_procedure(gtk_text_view_get_pixels_above_lines, gxg_gtk_text_view_get_pixels_above_lines_w, 1, 0, 0, H_gtk_text_view_get_pixels_above_lines, pl_iu); Xg_define_procedure(gtk_text_view_set_pixels_below_lines, gxg_gtk_text_view_set_pixels_below_lines_w, 2, 0, 0, H_gtk_text_view_set_pixels_below_lines, pl_tui); Xg_define_procedure(gtk_text_view_get_pixels_below_lines, gxg_gtk_text_view_get_pixels_below_lines_w, 1, 0, 0, H_gtk_text_view_get_pixels_below_lines, pl_iu); Xg_define_procedure(gtk_text_view_set_pixels_inside_wrap, gxg_gtk_text_view_set_pixels_inside_wrap_w, 2, 0, 0, H_gtk_text_view_set_pixels_inside_wrap, pl_tui); Xg_define_procedure(gtk_text_view_get_pixels_inside_wrap, gxg_gtk_text_view_get_pixels_inside_wrap_w, 1, 0, 0, H_gtk_text_view_get_pixels_inside_wrap, pl_iu); Xg_define_procedure(gtk_text_view_set_justification, gxg_gtk_text_view_set_justification_w, 2, 0, 0, H_gtk_text_view_set_justification, pl_tui); Xg_define_procedure(gtk_text_view_get_justification, gxg_gtk_text_view_get_justification_w, 1, 0, 0, H_gtk_text_view_get_justification, pl_iu); Xg_define_procedure(gtk_text_view_set_left_margin, gxg_gtk_text_view_set_left_margin_w, 2, 0, 0, H_gtk_text_view_set_left_margin, pl_tui); Xg_define_procedure(gtk_text_view_get_left_margin, gxg_gtk_text_view_get_left_margin_w, 1, 0, 0, H_gtk_text_view_get_left_margin, pl_iu); Xg_define_procedure(gtk_text_view_set_right_margin, gxg_gtk_text_view_set_right_margin_w, 2, 0, 0, H_gtk_text_view_set_right_margin, pl_tui); Xg_define_procedure(gtk_text_view_get_right_margin, gxg_gtk_text_view_get_right_margin_w, 1, 0, 0, H_gtk_text_view_get_right_margin, pl_iu); Xg_define_procedure(gtk_text_view_set_indent, gxg_gtk_text_view_set_indent_w, 2, 0, 0, H_gtk_text_view_set_indent, pl_tui); Xg_define_procedure(gtk_text_view_get_indent, gxg_gtk_text_view_get_indent_w, 1, 0, 0, H_gtk_text_view_get_indent, pl_iu); Xg_define_procedure(gtk_text_view_set_tabs, gxg_gtk_text_view_set_tabs_w, 2, 0, 0, H_gtk_text_view_set_tabs, pl_tu); Xg_define_procedure(gtk_text_view_get_tabs, gxg_gtk_text_view_get_tabs_w, 1, 0, 0, H_gtk_text_view_get_tabs, pl_pu); Xg_define_procedure(gtk_text_view_get_default_attributes, gxg_gtk_text_view_get_default_attributes_w, 1, 0, 0, H_gtk_text_view_get_default_attributes, pl_pu); Xg_define_procedure(gtk_toggle_button_new, gxg_gtk_toggle_button_new_w, 0, 0, 0, H_gtk_toggle_button_new, pl_p); Xg_define_procedure(gtk_toggle_button_new_with_label, gxg_gtk_toggle_button_new_with_label_w, 1, 0, 0, H_gtk_toggle_button_new_with_label, pl_ps); Xg_define_procedure(gtk_toggle_button_new_with_mnemonic, gxg_gtk_toggle_button_new_with_mnemonic_w, 1, 0, 0, H_gtk_toggle_button_new_with_mnemonic, pl_ps); Xg_define_procedure(gtk_toggle_button_set_mode, gxg_gtk_toggle_button_set_mode_w, 2, 0, 0, H_gtk_toggle_button_set_mode, pl_tub); Xg_define_procedure(gtk_toggle_button_get_mode, gxg_gtk_toggle_button_get_mode_w, 1, 0, 0, H_gtk_toggle_button_get_mode, pl_bu); Xg_define_procedure(gtk_toggle_button_set_active, gxg_gtk_toggle_button_set_active_w, 2, 0, 0, H_gtk_toggle_button_set_active, pl_tub); Xg_define_procedure(gtk_toggle_button_get_active, gxg_gtk_toggle_button_get_active_w, 1, 0, 0, H_gtk_toggle_button_get_active, pl_bu); Xg_define_procedure(gtk_toggle_button_toggled, gxg_gtk_toggle_button_toggled_w, 1, 0, 0, H_gtk_toggle_button_toggled, pl_tu); Xg_define_procedure(gtk_toggle_button_set_inconsistent, gxg_gtk_toggle_button_set_inconsistent_w, 2, 0, 0, H_gtk_toggle_button_set_inconsistent, pl_tub); Xg_define_procedure(gtk_toggle_button_get_inconsistent, gxg_gtk_toggle_button_get_inconsistent_w, 1, 0, 0, H_gtk_toggle_button_get_inconsistent, pl_bu); Xg_define_procedure(gtk_toolbar_new, gxg_gtk_toolbar_new_w, 0, 0, 0, H_gtk_toolbar_new, pl_p); Xg_define_procedure(gtk_toolbar_set_style, gxg_gtk_toolbar_set_style_w, 2, 0, 0, H_gtk_toolbar_set_style, pl_tui); Xg_define_procedure(gtk_toolbar_unset_style, gxg_gtk_toolbar_unset_style_w, 1, 0, 0, H_gtk_toolbar_unset_style, pl_tu); Xg_define_procedure(gtk_toolbar_get_style, gxg_gtk_toolbar_get_style_w, 1, 0, 0, H_gtk_toolbar_get_style, pl_iu); Xg_define_procedure(gtk_tree_drag_source_row_draggable, gxg_gtk_tree_drag_source_row_draggable_w, 2, 0, 0, H_gtk_tree_drag_source_row_draggable, pl_bu); Xg_define_procedure(gtk_tree_drag_source_drag_data_delete, gxg_gtk_tree_drag_source_drag_data_delete_w, 2, 0, 0, H_gtk_tree_drag_source_drag_data_delete, pl_bu); Xg_define_procedure(gtk_tree_drag_source_drag_data_get, gxg_gtk_tree_drag_source_drag_data_get_w, 3, 0, 0, H_gtk_tree_drag_source_drag_data_get, pl_bu); Xg_define_procedure(gtk_tree_drag_dest_drag_data_received, gxg_gtk_tree_drag_dest_drag_data_received_w, 3, 0, 0, H_gtk_tree_drag_dest_drag_data_received, pl_bu); Xg_define_procedure(gtk_tree_drag_dest_row_drop_possible, gxg_gtk_tree_drag_dest_row_drop_possible_w, 3, 0, 0, H_gtk_tree_drag_dest_row_drop_possible, pl_bu); Xg_define_procedure(gtk_tree_set_row_drag_data, gxg_gtk_tree_set_row_drag_data_w, 3, 0, 0, H_gtk_tree_set_row_drag_data, pl_bu); Xg_define_procedure(gtk_tree_get_row_drag_data, gxg_gtk_tree_get_row_drag_data_w, 1, 2, 0, H_gtk_tree_get_row_drag_data, pl_bu); Xg_define_procedure(gtk_tree_path_new, gxg_gtk_tree_path_new_w, 0, 0, 0, H_gtk_tree_path_new, pl_p); Xg_define_procedure(gtk_tree_path_new_from_string, gxg_gtk_tree_path_new_from_string_w, 1, 0, 0, H_gtk_tree_path_new_from_string, pl_ps); Xg_define_procedure(gtk_tree_path_to_string, gxg_gtk_tree_path_to_string_w, 1, 0, 0, H_gtk_tree_path_to_string, pl_su); Xg_define_procedure(gtk_tree_path_new_first, gxg_gtk_tree_path_new_first_w, 0, 0, 0, H_gtk_tree_path_new_first, pl_p); Xg_define_procedure(gtk_tree_path_append_index, gxg_gtk_tree_path_append_index_w, 2, 0, 0, H_gtk_tree_path_append_index, pl_tui); Xg_define_procedure(gtk_tree_path_prepend_index, gxg_gtk_tree_path_prepend_index_w, 2, 0, 0, H_gtk_tree_path_prepend_index, pl_tui); Xg_define_procedure(gtk_tree_path_get_depth, gxg_gtk_tree_path_get_depth_w, 1, 0, 0, H_gtk_tree_path_get_depth, pl_iu); Xg_define_procedure(gtk_tree_path_get_indices, gxg_gtk_tree_path_get_indices_w, 1, 0, 0, H_gtk_tree_path_get_indices, pl_pu); Xg_define_procedure(gtk_tree_path_free, gxg_gtk_tree_path_free_w, 1, 0, 0, H_gtk_tree_path_free, pl_tu); Xg_define_procedure(gtk_tree_path_copy, gxg_gtk_tree_path_copy_w, 1, 0, 0, H_gtk_tree_path_copy, pl_pu); Xg_define_procedure(gtk_tree_path_compare, gxg_gtk_tree_path_compare_w, 2, 0, 0, H_gtk_tree_path_compare, pl_iu); Xg_define_procedure(gtk_tree_path_next, gxg_gtk_tree_path_next_w, 1, 0, 0, H_gtk_tree_path_next, pl_tu); Xg_define_procedure(gtk_tree_path_prev, gxg_gtk_tree_path_prev_w, 1, 0, 0, H_gtk_tree_path_prev, pl_bu); Xg_define_procedure(gtk_tree_path_up, gxg_gtk_tree_path_up_w, 1, 0, 0, H_gtk_tree_path_up, pl_bu); Xg_define_procedure(gtk_tree_path_down, gxg_gtk_tree_path_down_w, 1, 0, 0, H_gtk_tree_path_down, pl_tu); Xg_define_procedure(gtk_tree_path_is_ancestor, gxg_gtk_tree_path_is_ancestor_w, 2, 0, 0, H_gtk_tree_path_is_ancestor, pl_bu); Xg_define_procedure(gtk_tree_path_is_descendant, gxg_gtk_tree_path_is_descendant_w, 2, 0, 0, H_gtk_tree_path_is_descendant, pl_bu); Xg_define_procedure(gtk_tree_row_reference_new, gxg_gtk_tree_row_reference_new_w, 2, 0, 0, H_gtk_tree_row_reference_new, pl_pu); Xg_define_procedure(gtk_tree_row_reference_new_proxy, gxg_gtk_tree_row_reference_new_proxy_w, 3, 0, 0, H_gtk_tree_row_reference_new_proxy, pl_pu); Xg_define_procedure(gtk_tree_row_reference_get_path, gxg_gtk_tree_row_reference_get_path_w, 1, 0, 0, H_gtk_tree_row_reference_get_path, pl_pu); Xg_define_procedure(gtk_tree_row_reference_valid, gxg_gtk_tree_row_reference_valid_w, 1, 0, 0, H_gtk_tree_row_reference_valid, pl_bu); Xg_define_procedure(gtk_tree_row_reference_free, gxg_gtk_tree_row_reference_free_w, 1, 0, 0, H_gtk_tree_row_reference_free, pl_tu); Xg_define_procedure(gtk_tree_row_reference_inserted, gxg_gtk_tree_row_reference_inserted_w, 2, 0, 0, H_gtk_tree_row_reference_inserted, pl_tu); Xg_define_procedure(gtk_tree_row_reference_deleted, gxg_gtk_tree_row_reference_deleted_w, 2, 0, 0, H_gtk_tree_row_reference_deleted, pl_tu); Xg_define_procedure(gtk_tree_row_reference_reordered, gxg_gtk_tree_row_reference_reordered_w, 4, 0, 0, H_gtk_tree_row_reference_reordered, pl_tu); Xg_define_procedure(gtk_tree_iter_copy, gxg_gtk_tree_iter_copy_w, 1, 0, 0, H_gtk_tree_iter_copy, pl_pu); Xg_define_procedure(gtk_tree_iter_free, gxg_gtk_tree_iter_free_w, 1, 0, 0, H_gtk_tree_iter_free, pl_tu); Xg_define_procedure(gtk_tree_model_get_flags, gxg_gtk_tree_model_get_flags_w, 1, 0, 0, H_gtk_tree_model_get_flags, pl_iu); Xg_define_procedure(gtk_tree_model_get_n_columns, gxg_gtk_tree_model_get_n_columns_w, 1, 0, 0, H_gtk_tree_model_get_n_columns, pl_iu); Xg_define_procedure(gtk_tree_model_get_column_type, gxg_gtk_tree_model_get_column_type_w, 2, 0, 0, H_gtk_tree_model_get_column_type, pl_iui); Xg_define_procedure(gtk_tree_model_get_iter, gxg_gtk_tree_model_get_iter_w, 3, 0, 0, H_gtk_tree_model_get_iter, pl_bu); Xg_define_procedure(gtk_tree_model_get_iter_from_string, gxg_gtk_tree_model_get_iter_from_string_w, 3, 0, 0, H_gtk_tree_model_get_iter_from_string, pl_buus); Xg_define_procedure(gtk_tree_model_get_iter_first, gxg_gtk_tree_model_get_iter_first_w, 2, 0, 0, H_gtk_tree_model_get_iter_first, pl_bu); Xg_define_procedure(gtk_tree_model_get_path, gxg_gtk_tree_model_get_path_w, 2, 0, 0, H_gtk_tree_model_get_path, pl_pu); Xg_define_procedure(gtk_tree_model_iter_next, gxg_gtk_tree_model_iter_next_w, 2, 0, 0, H_gtk_tree_model_iter_next, pl_bu); Xg_define_procedure(gtk_tree_model_iter_children, gxg_gtk_tree_model_iter_children_w, 3, 0, 0, H_gtk_tree_model_iter_children, pl_bu); Xg_define_procedure(gtk_tree_model_iter_has_child, gxg_gtk_tree_model_iter_has_child_w, 2, 0, 0, H_gtk_tree_model_iter_has_child, pl_bu); Xg_define_procedure(gtk_tree_model_iter_n_children, gxg_gtk_tree_model_iter_n_children_w, 2, 0, 0, H_gtk_tree_model_iter_n_children, pl_iu); Xg_define_procedure(gtk_tree_model_iter_nth_child, gxg_gtk_tree_model_iter_nth_child_w, 4, 0, 0, H_gtk_tree_model_iter_nth_child, pl_buuui); Xg_define_procedure(gtk_tree_model_iter_parent, gxg_gtk_tree_model_iter_parent_w, 3, 0, 0, H_gtk_tree_model_iter_parent, pl_bu); Xg_define_procedure(gtk_tree_model_ref_node, gxg_gtk_tree_model_ref_node_w, 2, 0, 0, H_gtk_tree_model_ref_node, pl_tu); Xg_define_procedure(gtk_tree_model_unref_node, gxg_gtk_tree_model_unref_node_w, 2, 0, 0, H_gtk_tree_model_unref_node, pl_tu); Xg_define_procedure(gtk_tree_model_foreach, gxg_gtk_tree_model_foreach_w, 2, 1, 0, H_gtk_tree_model_foreach, pl_tut); Xg_define_procedure(gtk_tree_model_row_changed, gxg_gtk_tree_model_row_changed_w, 3, 0, 0, H_gtk_tree_model_row_changed, pl_tu); Xg_define_procedure(gtk_tree_model_row_inserted, gxg_gtk_tree_model_row_inserted_w, 3, 0, 0, H_gtk_tree_model_row_inserted, pl_tu); Xg_define_procedure(gtk_tree_model_row_has_child_toggled, gxg_gtk_tree_model_row_has_child_toggled_w, 3, 0, 0, H_gtk_tree_model_row_has_child_toggled, pl_tu); Xg_define_procedure(gtk_tree_model_row_deleted, gxg_gtk_tree_model_row_deleted_w, 2, 0, 0, H_gtk_tree_model_row_deleted, pl_tu); Xg_define_procedure(gtk_tree_model_rows_reordered, gxg_gtk_tree_model_rows_reordered_w, 4, 0, 0, H_gtk_tree_model_rows_reordered, pl_tu); Xg_define_procedure(gtk_tree_model_sort_new_with_model, gxg_gtk_tree_model_sort_new_with_model_w, 1, 0, 0, H_gtk_tree_model_sort_new_with_model, pl_pu); Xg_define_procedure(gtk_tree_model_sort_get_model, gxg_gtk_tree_model_sort_get_model_w, 1, 0, 0, H_gtk_tree_model_sort_get_model, pl_pu); Xg_define_procedure(gtk_tree_model_sort_convert_child_path_to_path, gxg_gtk_tree_model_sort_convert_child_path_to_path_w, 2, 0, 0, H_gtk_tree_model_sort_convert_child_path_to_path, pl_pu); Xg_define_procedure(gtk_tree_model_sort_convert_child_iter_to_iter, gxg_gtk_tree_model_sort_convert_child_iter_to_iter_w, 3, 0, 0, H_gtk_tree_model_sort_convert_child_iter_to_iter, pl_tu); Xg_define_procedure(gtk_tree_model_sort_convert_path_to_child_path, gxg_gtk_tree_model_sort_convert_path_to_child_path_w, 2, 0, 0, H_gtk_tree_model_sort_convert_path_to_child_path, pl_pu); Xg_define_procedure(gtk_tree_model_sort_convert_iter_to_child_iter, gxg_gtk_tree_model_sort_convert_iter_to_child_iter_w, 3, 0, 0, H_gtk_tree_model_sort_convert_iter_to_child_iter, pl_tu); Xg_define_procedure(gtk_tree_model_sort_reset_default_sort_func, gxg_gtk_tree_model_sort_reset_default_sort_func_w, 1, 0, 0, H_gtk_tree_model_sort_reset_default_sort_func, pl_tu); Xg_define_procedure(gtk_tree_model_sort_clear_cache, gxg_gtk_tree_model_sort_clear_cache_w, 1, 0, 0, H_gtk_tree_model_sort_clear_cache, pl_tu); Xg_define_procedure(gtk_tree_selection_set_mode, gxg_gtk_tree_selection_set_mode_w, 2, 0, 0, H_gtk_tree_selection_set_mode, pl_tui); Xg_define_procedure(gtk_tree_selection_get_mode, gxg_gtk_tree_selection_get_mode_w, 1, 0, 0, H_gtk_tree_selection_get_mode, pl_iu); Xg_define_procedure(gtk_tree_selection_set_select_function, gxg_gtk_tree_selection_set_select_function_w, 4, 0, 0, H_gtk_tree_selection_set_select_function, pl_tut); Xg_define_procedure(gtk_tree_selection_get_user_data, gxg_gtk_tree_selection_get_user_data_w, 1, 0, 0, H_gtk_tree_selection_get_user_data, pl_tu); Xg_define_procedure(gtk_tree_selection_get_tree_view, gxg_gtk_tree_selection_get_tree_view_w, 1, 0, 0, H_gtk_tree_selection_get_tree_view, pl_pu); Xg_define_procedure(gtk_tree_selection_get_selected, gxg_gtk_tree_selection_get_selected_w, 3, 0, 0, H_gtk_tree_selection_get_selected, pl_bu); Xg_define_procedure(gtk_tree_selection_selected_foreach, gxg_gtk_tree_selection_selected_foreach_w, 2, 1, 0, H_gtk_tree_selection_selected_foreach, pl_tut); Xg_define_procedure(gtk_tree_selection_select_path, gxg_gtk_tree_selection_select_path_w, 2, 0, 0, H_gtk_tree_selection_select_path, pl_tu); Xg_define_procedure(gtk_tree_selection_unselect_path, gxg_gtk_tree_selection_unselect_path_w, 2, 0, 0, H_gtk_tree_selection_unselect_path, pl_tu); Xg_define_procedure(gtk_tree_selection_select_iter, gxg_gtk_tree_selection_select_iter_w, 2, 0, 0, H_gtk_tree_selection_select_iter, pl_tu); Xg_define_procedure(gtk_tree_selection_unselect_iter, gxg_gtk_tree_selection_unselect_iter_w, 2, 0, 0, H_gtk_tree_selection_unselect_iter, pl_tu); Xg_define_procedure(gtk_tree_selection_path_is_selected, gxg_gtk_tree_selection_path_is_selected_w, 2, 0, 0, H_gtk_tree_selection_path_is_selected, pl_bu); Xg_define_procedure(gtk_tree_selection_iter_is_selected, gxg_gtk_tree_selection_iter_is_selected_w, 2, 0, 0, H_gtk_tree_selection_iter_is_selected, pl_bu); Xg_define_procedure(gtk_tree_selection_select_all, gxg_gtk_tree_selection_select_all_w, 1, 0, 0, H_gtk_tree_selection_select_all, pl_tu); Xg_define_procedure(gtk_tree_selection_unselect_all, gxg_gtk_tree_selection_unselect_all_w, 1, 0, 0, H_gtk_tree_selection_unselect_all, pl_tu); Xg_define_procedure(gtk_tree_selection_select_range, gxg_gtk_tree_selection_select_range_w, 3, 0, 0, H_gtk_tree_selection_select_range, pl_tu); Xg_define_procedure(gtk_tree_sortable_sort_column_changed, gxg_gtk_tree_sortable_sort_column_changed_w, 1, 0, 0, H_gtk_tree_sortable_sort_column_changed, pl_tu); Xg_define_procedure(gtk_tree_sortable_get_sort_column_id, gxg_gtk_tree_sortable_get_sort_column_id_w, 1, 2, 0, H_gtk_tree_sortable_get_sort_column_id, pl_bu); Xg_define_procedure(gtk_tree_sortable_set_sort_column_id, gxg_gtk_tree_sortable_set_sort_column_id_w, 3, 0, 0, H_gtk_tree_sortable_set_sort_column_id, pl_tui); Xg_define_procedure(gtk_tree_sortable_set_sort_func, gxg_gtk_tree_sortable_set_sort_func_w, 5, 0, 0, H_gtk_tree_sortable_set_sort_func, pl_tuit); Xg_define_procedure(gtk_tree_sortable_set_default_sort_func, gxg_gtk_tree_sortable_set_default_sort_func_w, 4, 0, 0, H_gtk_tree_sortable_set_default_sort_func, pl_tut); Xg_define_procedure(gtk_tree_sortable_has_default_sort_func, gxg_gtk_tree_sortable_has_default_sort_func_w, 1, 0, 0, H_gtk_tree_sortable_has_default_sort_func, pl_bu); Xg_define_procedure(gtk_tree_store_new, gxg_gtk_tree_store_new_w, 2, 0, 0, H_gtk_tree_store_new, pl_pit); Xg_define_procedure(gtk_tree_store_newv, gxg_gtk_tree_store_newv_w, 2, 0, 0, H_gtk_tree_store_newv, pl_piu); Xg_define_procedure(gtk_tree_store_set_column_types, gxg_gtk_tree_store_set_column_types_w, 3, 0, 0, H_gtk_tree_store_set_column_types, pl_tuiu); Xg_define_procedure(gtk_tree_store_set, gxg_gtk_tree_store_set_w, 3, 0, 0, H_gtk_tree_store_set, pl_tuut); Xg_define_procedure(gtk_tree_store_remove, gxg_gtk_tree_store_remove_w, 2, 0, 0, H_gtk_tree_store_remove, pl_tu); Xg_define_procedure(gtk_tree_store_insert, gxg_gtk_tree_store_insert_w, 4, 0, 0, H_gtk_tree_store_insert, pl_tuuui); Xg_define_procedure(gtk_tree_store_insert_before, gxg_gtk_tree_store_insert_before_w, 4, 0, 0, H_gtk_tree_store_insert_before, pl_tu); Xg_define_procedure(gtk_tree_store_insert_after, gxg_gtk_tree_store_insert_after_w, 4, 0, 0, H_gtk_tree_store_insert_after, pl_tu); Xg_define_procedure(gtk_tree_store_prepend, gxg_gtk_tree_store_prepend_w, 3, 0, 0, H_gtk_tree_store_prepend, pl_tu); Xg_define_procedure(gtk_tree_store_append, gxg_gtk_tree_store_append_w, 3, 0, 0, H_gtk_tree_store_append, pl_tu); Xg_define_procedure(gtk_tree_store_is_ancestor, gxg_gtk_tree_store_is_ancestor_w, 3, 0, 0, H_gtk_tree_store_is_ancestor, pl_bu); Xg_define_procedure(gtk_tree_store_iter_depth, gxg_gtk_tree_store_iter_depth_w, 2, 0, 0, H_gtk_tree_store_iter_depth, pl_iu); Xg_define_procedure(gtk_tree_store_clear, gxg_gtk_tree_store_clear_w, 1, 0, 0, H_gtk_tree_store_clear, pl_tu); Xg_define_procedure(gtk_tree_view_column_new, gxg_gtk_tree_view_column_new_w, 0, 0, 0, H_gtk_tree_view_column_new, pl_p); Xg_define_procedure(gtk_tree_view_column_new_with_attributes, gxg_gtk_tree_view_column_new_with_attributes_w, 3, 0, 0, H_gtk_tree_view_column_new_with_attributes, pl_psut); Xg_define_procedure(gtk_tree_view_column_pack_start, gxg_gtk_tree_view_column_pack_start_w, 3, 0, 0, H_gtk_tree_view_column_pack_start, pl_tuub); Xg_define_procedure(gtk_tree_view_column_pack_end, gxg_gtk_tree_view_column_pack_end_w, 3, 0, 0, H_gtk_tree_view_column_pack_end, pl_tuub); Xg_define_procedure(gtk_tree_view_column_clear, gxg_gtk_tree_view_column_clear_w, 1, 0, 0, H_gtk_tree_view_column_clear, pl_tu); Xg_define_procedure(gtk_tree_view_column_add_attribute, gxg_gtk_tree_view_column_add_attribute_w, 4, 0, 0, H_gtk_tree_view_column_add_attribute, pl_tuusi); Xg_define_procedure(gtk_tree_view_column_set_attributes, gxg_gtk_tree_view_column_set_attributes_w, 3, 0, 0, H_gtk_tree_view_column_set_attributes, pl_tuut); Xg_define_procedure(gtk_tree_view_column_set_cell_data_func, gxg_gtk_tree_view_column_set_cell_data_func_w, 5, 0, 0, H_gtk_tree_view_column_set_cell_data_func, pl_tuut); Xg_define_procedure(gtk_tree_view_column_clear_attributes, gxg_gtk_tree_view_column_clear_attributes_w, 2, 0, 0, H_gtk_tree_view_column_clear_attributes, pl_tu); Xg_define_procedure(gtk_tree_view_column_set_spacing, gxg_gtk_tree_view_column_set_spacing_w, 2, 0, 0, H_gtk_tree_view_column_set_spacing, pl_tui); Xg_define_procedure(gtk_tree_view_column_get_spacing, gxg_gtk_tree_view_column_get_spacing_w, 1, 0, 0, H_gtk_tree_view_column_get_spacing, pl_iu); Xg_define_procedure(gtk_tree_view_column_set_visible, gxg_gtk_tree_view_column_set_visible_w, 2, 0, 0, H_gtk_tree_view_column_set_visible, pl_tub); Xg_define_procedure(gtk_tree_view_column_get_visible, gxg_gtk_tree_view_column_get_visible_w, 1, 0, 0, H_gtk_tree_view_column_get_visible, pl_bu); Xg_define_procedure(gtk_tree_view_column_set_resizable, gxg_gtk_tree_view_column_set_resizable_w, 2, 0, 0, H_gtk_tree_view_column_set_resizable, pl_tub); Xg_define_procedure(gtk_tree_view_column_get_resizable, gxg_gtk_tree_view_column_get_resizable_w, 1, 0, 0, H_gtk_tree_view_column_get_resizable, pl_bu); Xg_define_procedure(gtk_tree_view_column_set_sizing, gxg_gtk_tree_view_column_set_sizing_w, 2, 0, 0, H_gtk_tree_view_column_set_sizing, pl_tui); Xg_define_procedure(gtk_tree_view_column_get_sizing, gxg_gtk_tree_view_column_get_sizing_w, 1, 0, 0, H_gtk_tree_view_column_get_sizing, pl_iu); Xg_define_procedure(gtk_tree_view_column_get_width, gxg_gtk_tree_view_column_get_width_w, 1, 0, 0, H_gtk_tree_view_column_get_width, pl_iu); Xg_define_procedure(gtk_tree_view_column_get_fixed_width, gxg_gtk_tree_view_column_get_fixed_width_w, 1, 0, 0, H_gtk_tree_view_column_get_fixed_width, pl_iu); Xg_define_procedure(gtk_tree_view_column_set_fixed_width, gxg_gtk_tree_view_column_set_fixed_width_w, 2, 0, 0, H_gtk_tree_view_column_set_fixed_width, pl_tui); Xg_define_procedure(gtk_tree_view_column_set_min_width, gxg_gtk_tree_view_column_set_min_width_w, 2, 0, 0, H_gtk_tree_view_column_set_min_width, pl_tui); Xg_define_procedure(gtk_tree_view_column_get_min_width, gxg_gtk_tree_view_column_get_min_width_w, 1, 0, 0, H_gtk_tree_view_column_get_min_width, pl_iu); Xg_define_procedure(gtk_tree_view_column_set_max_width, gxg_gtk_tree_view_column_set_max_width_w, 2, 0, 0, H_gtk_tree_view_column_set_max_width, pl_tui); Xg_define_procedure(gtk_tree_view_column_get_max_width, gxg_gtk_tree_view_column_get_max_width_w, 1, 0, 0, H_gtk_tree_view_column_get_max_width, pl_iu); Xg_define_procedure(gtk_tree_view_column_clicked, gxg_gtk_tree_view_column_clicked_w, 1, 0, 0, H_gtk_tree_view_column_clicked, pl_tu); Xg_define_procedure(gtk_tree_view_column_set_title, gxg_gtk_tree_view_column_set_title_w, 2, 0, 0, H_gtk_tree_view_column_set_title, pl_tus); Xg_define_procedure(gtk_tree_view_column_get_title, gxg_gtk_tree_view_column_get_title_w, 1, 0, 0, H_gtk_tree_view_column_get_title, pl_su); Xg_define_procedure(gtk_tree_view_column_set_clickable, gxg_gtk_tree_view_column_set_clickable_w, 2, 0, 0, H_gtk_tree_view_column_set_clickable, pl_tub); Xg_define_procedure(gtk_tree_view_column_get_clickable, gxg_gtk_tree_view_column_get_clickable_w, 1, 0, 0, H_gtk_tree_view_column_get_clickable, pl_bu); Xg_define_procedure(gtk_tree_view_column_set_widget, gxg_gtk_tree_view_column_set_widget_w, 2, 0, 0, H_gtk_tree_view_column_set_widget, pl_tu); Xg_define_procedure(gtk_tree_view_column_get_widget, gxg_gtk_tree_view_column_get_widget_w, 1, 0, 0, H_gtk_tree_view_column_get_widget, pl_pu); Xg_define_procedure(gtk_tree_view_column_set_alignment, gxg_gtk_tree_view_column_set_alignment_w, 2, 0, 0, H_gtk_tree_view_column_set_alignment, pl_tur); Xg_define_procedure(gtk_tree_view_column_get_alignment, gxg_gtk_tree_view_column_get_alignment_w, 1, 0, 0, H_gtk_tree_view_column_get_alignment, pl_du); Xg_define_procedure(gtk_tree_view_column_set_reorderable, gxg_gtk_tree_view_column_set_reorderable_w, 2, 0, 0, H_gtk_tree_view_column_set_reorderable, pl_tub); Xg_define_procedure(gtk_tree_view_column_get_reorderable, gxg_gtk_tree_view_column_get_reorderable_w, 1, 0, 0, H_gtk_tree_view_column_get_reorderable, pl_bu); Xg_define_procedure(gtk_tree_view_column_set_sort_column_id, gxg_gtk_tree_view_column_set_sort_column_id_w, 2, 0, 0, H_gtk_tree_view_column_set_sort_column_id, pl_tui); Xg_define_procedure(gtk_tree_view_column_get_sort_column_id, gxg_gtk_tree_view_column_get_sort_column_id_w, 1, 0, 0, H_gtk_tree_view_column_get_sort_column_id, pl_iu); Xg_define_procedure(gtk_tree_view_column_set_sort_indicator, gxg_gtk_tree_view_column_set_sort_indicator_w, 2, 0, 0, H_gtk_tree_view_column_set_sort_indicator, pl_tub); Xg_define_procedure(gtk_tree_view_column_get_sort_indicator, gxg_gtk_tree_view_column_get_sort_indicator_w, 1, 0, 0, H_gtk_tree_view_column_get_sort_indicator, pl_bu); Xg_define_procedure(gtk_tree_view_column_set_sort_order, gxg_gtk_tree_view_column_set_sort_order_w, 2, 0, 0, H_gtk_tree_view_column_set_sort_order, pl_tui); Xg_define_procedure(gtk_tree_view_column_get_sort_order, gxg_gtk_tree_view_column_get_sort_order_w, 1, 0, 0, H_gtk_tree_view_column_get_sort_order, pl_iu); Xg_define_procedure(gtk_tree_view_column_cell_set_cell_data, gxg_gtk_tree_view_column_cell_set_cell_data_w, 5, 0, 0, H_gtk_tree_view_column_cell_set_cell_data, pl_tuuub); Xg_define_procedure(gtk_tree_view_column_cell_get_size, gxg_gtk_tree_view_column_cell_get_size_w, 2, 4, 0, H_gtk_tree_view_column_cell_get_size, pl_tu); Xg_define_procedure(gtk_tree_view_column_cell_is_visible, gxg_gtk_tree_view_column_cell_is_visible_w, 1, 0, 0, H_gtk_tree_view_column_cell_is_visible, pl_bu); Xg_define_procedure(gtk_tree_view_column_cell_get_position, gxg_gtk_tree_view_column_cell_get_position_w, 2, 2, 0, H_gtk_tree_view_column_cell_get_position, pl_bu); Xg_define_procedure(gtk_tree_view_new, gxg_gtk_tree_view_new_w, 0, 0, 0, H_gtk_tree_view_new, pl_p); Xg_define_procedure(gtk_tree_view_new_with_model, gxg_gtk_tree_view_new_with_model_w, 1, 0, 0, H_gtk_tree_view_new_with_model, pl_pu); Xg_define_procedure(gtk_tree_view_get_model, gxg_gtk_tree_view_get_model_w, 1, 0, 0, H_gtk_tree_view_get_model, pl_pu); Xg_define_procedure(gtk_tree_view_set_model, gxg_gtk_tree_view_set_model_w, 2, 0, 0, H_gtk_tree_view_set_model, pl_tu); Xg_define_procedure(gtk_tree_view_get_selection, gxg_gtk_tree_view_get_selection_w, 1, 0, 0, H_gtk_tree_view_get_selection, pl_pu); Xg_define_procedure(gtk_tree_view_get_headers_visible, gxg_gtk_tree_view_get_headers_visible_w, 1, 0, 0, H_gtk_tree_view_get_headers_visible, pl_bu); Xg_define_procedure(gtk_tree_view_set_headers_visible, gxg_gtk_tree_view_set_headers_visible_w, 2, 0, 0, H_gtk_tree_view_set_headers_visible, pl_tub); Xg_define_procedure(gtk_tree_view_columns_autosize, gxg_gtk_tree_view_columns_autosize_w, 1, 0, 0, H_gtk_tree_view_columns_autosize, pl_tu); Xg_define_procedure(gtk_tree_view_set_headers_clickable, gxg_gtk_tree_view_set_headers_clickable_w, 2, 0, 0, H_gtk_tree_view_set_headers_clickable, pl_tub); Xg_define_procedure(gtk_tree_view_append_column, gxg_gtk_tree_view_append_column_w, 2, 0, 0, H_gtk_tree_view_append_column, pl_iu); Xg_define_procedure(gtk_tree_view_remove_column, gxg_gtk_tree_view_remove_column_w, 2, 0, 0, H_gtk_tree_view_remove_column, pl_iu); Xg_define_procedure(gtk_tree_view_insert_column, gxg_gtk_tree_view_insert_column_w, 3, 0, 0, H_gtk_tree_view_insert_column, pl_iuui); Xg_define_procedure(gtk_tree_view_insert_column_with_attributes, gxg_gtk_tree_view_insert_column_with_attributes_w, 5, 0, 0, H_gtk_tree_view_insert_column_with_attributes, pl_iuisut); Xg_define_procedure(gtk_tree_view_insert_column_with_data_func, gxg_gtk_tree_view_insert_column_with_data_func_w, 7, 0, 0, H_gtk_tree_view_insert_column_with_data_func, pl_iuisut); Xg_define_procedure(gtk_tree_view_get_column, gxg_gtk_tree_view_get_column_w, 2, 0, 0, H_gtk_tree_view_get_column, pl_pui); Xg_define_procedure(gtk_tree_view_get_columns, gxg_gtk_tree_view_get_columns_w, 1, 0, 0, H_gtk_tree_view_get_columns, pl_pu); Xg_define_procedure(gtk_tree_view_move_column_after, gxg_gtk_tree_view_move_column_after_w, 3, 0, 0, H_gtk_tree_view_move_column_after, pl_tu); Xg_define_procedure(gtk_tree_view_set_expander_column, gxg_gtk_tree_view_set_expander_column_w, 2, 0, 0, H_gtk_tree_view_set_expander_column, pl_tu); Xg_define_procedure(gtk_tree_view_get_expander_column, gxg_gtk_tree_view_get_expander_column_w, 1, 0, 0, H_gtk_tree_view_get_expander_column, pl_pu); Xg_define_procedure(gtk_tree_view_set_column_drag_function, gxg_gtk_tree_view_set_column_drag_function_w, 4, 0, 0, H_gtk_tree_view_set_column_drag_function, pl_tut); Xg_define_procedure(gtk_tree_view_scroll_to_point, gxg_gtk_tree_view_scroll_to_point_w, 3, 0, 0, H_gtk_tree_view_scroll_to_point, pl_tui); Xg_define_procedure(gtk_tree_view_scroll_to_cell, gxg_gtk_tree_view_scroll_to_cell_w, 6, 0, 0, H_gtk_tree_view_scroll_to_cell, pl_tuuubr); Xg_define_procedure(gtk_tree_view_row_activated, gxg_gtk_tree_view_row_activated_w, 3, 0, 0, H_gtk_tree_view_row_activated, pl_tu); Xg_define_procedure(gtk_tree_view_expand_all, gxg_gtk_tree_view_expand_all_w, 1, 0, 0, H_gtk_tree_view_expand_all, pl_tu); Xg_define_procedure(gtk_tree_view_collapse_all, gxg_gtk_tree_view_collapse_all_w, 1, 0, 0, H_gtk_tree_view_collapse_all, pl_tu); Xg_define_procedure(gtk_tree_view_expand_row, gxg_gtk_tree_view_expand_row_w, 3, 0, 0, H_gtk_tree_view_expand_row, pl_buub); Xg_define_procedure(gtk_tree_view_collapse_row, gxg_gtk_tree_view_collapse_row_w, 2, 0, 0, H_gtk_tree_view_collapse_row, pl_bu); Xg_define_procedure(gtk_tree_view_map_expanded_rows, gxg_gtk_tree_view_map_expanded_rows_w, 2, 1, 0, H_gtk_tree_view_map_expanded_rows, pl_tut); Xg_define_procedure(gtk_tree_view_row_expanded, gxg_gtk_tree_view_row_expanded_w, 2, 0, 0, H_gtk_tree_view_row_expanded, pl_bu); Xg_define_procedure(gtk_tree_view_set_reorderable, gxg_gtk_tree_view_set_reorderable_w, 2, 0, 0, H_gtk_tree_view_set_reorderable, pl_tub); Xg_define_procedure(gtk_tree_view_get_reorderable, gxg_gtk_tree_view_get_reorderable_w, 1, 0, 0, H_gtk_tree_view_get_reorderable, pl_bu); Xg_define_procedure(gtk_tree_view_set_cursor, gxg_gtk_tree_view_set_cursor_w, 4, 0, 0, H_gtk_tree_view_set_cursor, pl_tuuub); Xg_define_procedure(gtk_tree_view_get_cursor, gxg_gtk_tree_view_get_cursor_w, 1, 2, 0, H_gtk_tree_view_get_cursor, pl_tu); Xg_define_procedure(gtk_tree_view_get_bin_window, gxg_gtk_tree_view_get_bin_window_w, 1, 0, 0, H_gtk_tree_view_get_bin_window, pl_pu); Xg_define_procedure(gtk_tree_view_get_path_at_pos, gxg_gtk_tree_view_get_path_at_pos_w, 3, 4, 0, H_gtk_tree_view_get_path_at_pos, pl_buiiu); Xg_define_procedure(gtk_tree_view_get_cell_area, gxg_gtk_tree_view_get_cell_area_w, 4, 0, 0, H_gtk_tree_view_get_cell_area, pl_tu); Xg_define_procedure(gtk_tree_view_get_background_area, gxg_gtk_tree_view_get_background_area_w, 4, 0, 0, H_gtk_tree_view_get_background_area, pl_tu); Xg_define_procedure(gtk_tree_view_get_visible_rect, gxg_gtk_tree_view_get_visible_rect_w, 2, 0, 0, H_gtk_tree_view_get_visible_rect, pl_tu); Xg_define_procedure(gtk_tree_view_enable_model_drag_source, gxg_gtk_tree_view_enable_model_drag_source_w, 5, 0, 0, H_gtk_tree_view_enable_model_drag_source, pl_tuiui); Xg_define_procedure(gtk_tree_view_enable_model_drag_dest, gxg_gtk_tree_view_enable_model_drag_dest_w, 4, 0, 0, H_gtk_tree_view_enable_model_drag_dest, pl_tuui); Xg_define_procedure(gtk_tree_view_unset_rows_drag_source, gxg_gtk_tree_view_unset_rows_drag_source_w, 1, 0, 0, H_gtk_tree_view_unset_rows_drag_source, pl_tu); Xg_define_procedure(gtk_tree_view_unset_rows_drag_dest, gxg_gtk_tree_view_unset_rows_drag_dest_w, 1, 0, 0, H_gtk_tree_view_unset_rows_drag_dest, pl_tu); Xg_define_procedure(gtk_tree_view_set_drag_dest_row, gxg_gtk_tree_view_set_drag_dest_row_w, 3, 0, 0, H_gtk_tree_view_set_drag_dest_row, pl_tuui); Xg_define_procedure(gtk_tree_view_get_drag_dest_row, gxg_gtk_tree_view_get_drag_dest_row_w, 1, 2, 0, H_gtk_tree_view_get_drag_dest_row, pl_tu); Xg_define_procedure(gtk_tree_view_get_dest_row_at_pos, gxg_gtk_tree_view_get_dest_row_at_pos_w, 3, 2, 0, H_gtk_tree_view_get_dest_row_at_pos, pl_buiiu); Xg_define_procedure(gtk_tree_view_set_enable_search, gxg_gtk_tree_view_set_enable_search_w, 2, 0, 0, H_gtk_tree_view_set_enable_search, pl_tub); Xg_define_procedure(gtk_tree_view_get_enable_search, gxg_gtk_tree_view_get_enable_search_w, 1, 0, 0, H_gtk_tree_view_get_enable_search, pl_bu); Xg_define_procedure(gtk_tree_view_get_search_column, gxg_gtk_tree_view_get_search_column_w, 1, 0, 0, H_gtk_tree_view_get_search_column, pl_iu); Xg_define_procedure(gtk_tree_view_set_search_column, gxg_gtk_tree_view_set_search_column_w, 2, 0, 0, H_gtk_tree_view_set_search_column, pl_tui); Xg_define_procedure(gtk_tree_view_get_search_equal_func, gxg_gtk_tree_view_get_search_equal_func_w, 1, 0, 0, H_gtk_tree_view_get_search_equal_func, pl_tu); Xg_define_procedure(gtk_tree_view_set_search_equal_func, gxg_gtk_tree_view_set_search_equal_func_w, 4, 0, 0, H_gtk_tree_view_set_search_equal_func, pl_tut); Xg_define_procedure(gtk_viewport_new, gxg_gtk_viewport_new_w, 2, 0, 0, H_gtk_viewport_new, pl_pu); Xg_define_procedure(gtk_viewport_set_shadow_type, gxg_gtk_viewport_set_shadow_type_w, 2, 0, 0, H_gtk_viewport_set_shadow_type, pl_tui); Xg_define_procedure(gtk_viewport_get_shadow_type, gxg_gtk_viewport_get_shadow_type_w, 1, 0, 0, H_gtk_viewport_get_shadow_type, pl_iu); Xg_define_procedure(gtk_widget_destroy, gxg_gtk_widget_destroy_w, 1, 0, 0, H_gtk_widget_destroy, pl_tu); Xg_define_procedure(gtk_widget_destroyed, gxg_gtk_widget_destroyed_w, 1, 1, 0, H_gtk_widget_destroyed, pl_tu); Xg_define_procedure(gtk_widget_unparent, gxg_gtk_widget_unparent_w, 1, 0, 0, H_gtk_widget_unparent, pl_tu); Xg_define_procedure(gtk_widget_show, gxg_gtk_widget_show_w, 1, 0, 0, H_gtk_widget_show, pl_tu); Xg_define_procedure(gtk_widget_show_now, gxg_gtk_widget_show_now_w, 1, 0, 0, H_gtk_widget_show_now, pl_tu); Xg_define_procedure(gtk_widget_hide, gxg_gtk_widget_hide_w, 1, 0, 0, H_gtk_widget_hide, pl_tu); Xg_define_procedure(gtk_widget_show_all, gxg_gtk_widget_show_all_w, 1, 0, 0, H_gtk_widget_show_all, pl_tu); Xg_define_procedure(gtk_widget_map, gxg_gtk_widget_map_w, 1, 0, 0, H_gtk_widget_map, pl_tu); Xg_define_procedure(gtk_widget_unmap, gxg_gtk_widget_unmap_w, 1, 0, 0, H_gtk_widget_unmap, pl_tu); Xg_define_procedure(gtk_widget_realize, gxg_gtk_widget_realize_w, 1, 0, 0, H_gtk_widget_realize, pl_tu); Xg_define_procedure(gtk_widget_unrealize, gxg_gtk_widget_unrealize_w, 1, 0, 0, H_gtk_widget_unrealize, pl_tu); Xg_define_procedure(gtk_widget_queue_draw, gxg_gtk_widget_queue_draw_w, 1, 0, 0, H_gtk_widget_queue_draw, pl_tu); Xg_define_procedure(gtk_widget_queue_draw_area, gxg_gtk_widget_queue_draw_area_w, 5, 0, 0, H_gtk_widget_queue_draw_area, pl_tui); Xg_define_procedure(gtk_widget_queue_resize, gxg_gtk_widget_queue_resize_w, 1, 0, 0, H_gtk_widget_queue_resize, pl_tu); Xg_define_procedure(gtk_widget_size_allocate, gxg_gtk_widget_size_allocate_w, 2, 0, 0, H_gtk_widget_size_allocate, pl_tu); Xg_define_procedure(gtk_widget_add_accelerator, gxg_gtk_widget_add_accelerator_w, 6, 0, 0, H_gtk_widget_add_accelerator, pl_tusui); Xg_define_procedure(gtk_widget_remove_accelerator, gxg_gtk_widget_remove_accelerator_w, 4, 0, 0, H_gtk_widget_remove_accelerator, pl_buui); Xg_define_procedure(gtk_widget_list_accel_closures, gxg_gtk_widget_list_accel_closures_w, 1, 0, 0, H_gtk_widget_list_accel_closures, pl_pu); Xg_define_procedure(gtk_widget_mnemonic_activate, gxg_gtk_widget_mnemonic_activate_w, 2, 0, 0, H_gtk_widget_mnemonic_activate, pl_bub); Xg_define_procedure(gtk_widget_event, gxg_gtk_widget_event_w, 2, 0, 0, H_gtk_widget_event, pl_bu); Xg_define_procedure(gtk_widget_send_expose, gxg_gtk_widget_send_expose_w, 2, 0, 0, H_gtk_widget_send_expose, pl_iu); Xg_define_procedure(gtk_widget_activate, gxg_gtk_widget_activate_w, 1, 0, 0, H_gtk_widget_activate, pl_bu); Xg_define_procedure(gtk_widget_intersect, gxg_gtk_widget_intersect_w, 3, 0, 0, H_gtk_widget_intersect, pl_bu); Xg_define_procedure(gtk_widget_freeze_child_notify, gxg_gtk_widget_freeze_child_notify_w, 1, 0, 0, H_gtk_widget_freeze_child_notify, pl_tu); Xg_define_procedure(gtk_widget_child_notify, gxg_gtk_widget_child_notify_w, 2, 0, 0, H_gtk_widget_child_notify, pl_tus); Xg_define_procedure(gtk_widget_thaw_child_notify, gxg_gtk_widget_thaw_child_notify_w, 1, 0, 0, H_gtk_widget_thaw_child_notify, pl_tu); Xg_define_procedure(gtk_widget_is_focus, gxg_gtk_widget_is_focus_w, 1, 0, 0, H_gtk_widget_is_focus, pl_bu); Xg_define_procedure(gtk_widget_grab_focus, gxg_gtk_widget_grab_focus_w, 1, 0, 0, H_gtk_widget_grab_focus, pl_tu); Xg_define_procedure(gtk_widget_grab_default, gxg_gtk_widget_grab_default_w, 1, 0, 0, H_gtk_widget_grab_default, pl_tu); Xg_define_procedure(gtk_widget_set_name, gxg_gtk_widget_set_name_w, 2, 0, 0, H_gtk_widget_set_name, pl_tus); Xg_define_procedure(gtk_widget_get_name, gxg_gtk_widget_get_name_w, 1, 0, 0, H_gtk_widget_get_name, pl_su); Xg_define_procedure(gtk_widget_set_sensitive, gxg_gtk_widget_set_sensitive_w, 2, 0, 0, H_gtk_widget_set_sensitive, pl_tub); Xg_define_procedure(gtk_widget_set_app_paintable, gxg_gtk_widget_set_app_paintable_w, 2, 0, 0, H_gtk_widget_set_app_paintable, pl_tub); Xg_define_procedure(gtk_widget_set_redraw_on_allocate, gxg_gtk_widget_set_redraw_on_allocate_w, 2, 0, 0, H_gtk_widget_set_redraw_on_allocate, pl_tub); Xg_define_procedure(gtk_widget_set_parent, gxg_gtk_widget_set_parent_w, 2, 0, 0, H_gtk_widget_set_parent, pl_tu); Xg_define_procedure(gtk_widget_set_parent_window, gxg_gtk_widget_set_parent_window_w, 2, 0, 0, H_gtk_widget_set_parent_window, pl_tu); Xg_define_procedure(gtk_widget_set_child_visible, gxg_gtk_widget_set_child_visible_w, 2, 0, 0, H_gtk_widget_set_child_visible, pl_tub); Xg_define_procedure(gtk_widget_set_accel_path, gxg_gtk_widget_set_accel_path_w, 3, 0, 0, H_gtk_widget_set_accel_path, pl_tusu); Xg_define_procedure(gtk_widget_get_child_visible, gxg_gtk_widget_get_child_visible_w, 1, 0, 0, H_gtk_widget_get_child_visible, pl_bu); Xg_define_procedure(gtk_widget_get_parent, gxg_gtk_widget_get_parent_w, 1, 0, 0, H_gtk_widget_get_parent, pl_pu); Xg_define_procedure(gtk_widget_get_parent_window, gxg_gtk_widget_get_parent_window_w, 1, 0, 0, H_gtk_widget_get_parent_window, pl_pu); Xg_define_procedure(gtk_widget_child_focus, gxg_gtk_widget_child_focus_w, 2, 0, 0, H_gtk_widget_child_focus, pl_bui); Xg_define_procedure(gtk_widget_set_size_request, gxg_gtk_widget_set_size_request_w, 3, 0, 0, H_gtk_widget_set_size_request, pl_tui); Xg_define_procedure(gtk_widget_get_size_request, gxg_gtk_widget_get_size_request_w, 1, 2, 0, H_gtk_widget_get_size_request, pl_tu); Xg_define_procedure(gtk_widget_set_events, gxg_gtk_widget_set_events_w, 2, 0, 0, H_gtk_widget_set_events, pl_tui); Xg_define_procedure(gtk_widget_add_events, gxg_gtk_widget_add_events_w, 2, 0, 0, H_gtk_widget_add_events, pl_tui); Xg_define_procedure(gtk_widget_get_toplevel, gxg_gtk_widget_get_toplevel_w, 1, 0, 0, H_gtk_widget_get_toplevel, pl_pu); Xg_define_procedure(gtk_widget_get_ancestor, gxg_gtk_widget_get_ancestor_w, 2, 0, 0, H_gtk_widget_get_ancestor, pl_pui); Xg_define_procedure(gtk_widget_get_visual, gxg_gtk_widget_get_visual_w, 1, 0, 0, H_gtk_widget_get_visual, pl_pu); Xg_define_procedure(gtk_widget_get_settings, gxg_gtk_widget_get_settings_w, 1, 0, 0, H_gtk_widget_get_settings, pl_pu); Xg_define_procedure(gtk_widget_get_accessible, gxg_gtk_widget_get_accessible_w, 1, 0, 0, H_gtk_widget_get_accessible, pl_pu); Xg_define_procedure(gtk_widget_get_events, gxg_gtk_widget_get_events_w, 1, 0, 0, H_gtk_widget_get_events, pl_iu); Xg_define_procedure(gtk_widget_is_ancestor, gxg_gtk_widget_is_ancestor_w, 2, 0, 0, H_gtk_widget_is_ancestor, pl_bu); Xg_define_procedure(gtk_widget_translate_coordinates, gxg_gtk_widget_translate_coordinates_w, 4, 2, 0, H_gtk_widget_translate_coordinates, pl_buuiiu); Xg_define_procedure(gtk_widget_hide_on_delete, gxg_gtk_widget_hide_on_delete_w, 1, 0, 0, H_gtk_widget_hide_on_delete, pl_bu); Xg_define_procedure(gtk_widget_create_pango_context, gxg_gtk_widget_create_pango_context_w, 1, 0, 0, H_gtk_widget_create_pango_context, pl_pu); Xg_define_procedure(gtk_widget_get_pango_context, gxg_gtk_widget_get_pango_context_w, 1, 0, 0, H_gtk_widget_get_pango_context, pl_pu); Xg_define_procedure(gtk_widget_create_pango_layout, gxg_gtk_widget_create_pango_layout_w, 2, 0, 0, H_gtk_widget_create_pango_layout, pl_pus); Xg_define_procedure(gtk_widget_set_direction, gxg_gtk_widget_set_direction_w, 2, 0, 0, H_gtk_widget_set_direction, pl_tui); Xg_define_procedure(gtk_widget_get_direction, gxg_gtk_widget_get_direction_w, 1, 0, 0, H_gtk_widget_get_direction, pl_iu); Xg_define_procedure(gtk_widget_set_default_direction, gxg_gtk_widget_set_default_direction_w, 1, 0, 0, H_gtk_widget_set_default_direction, pl_ti); Xg_define_procedure(gtk_widget_get_default_direction, gxg_gtk_widget_get_default_direction_w, 0, 0, 0, H_gtk_widget_get_default_direction, pl_i); Xg_define_procedure(gtk_widget_can_activate_accel, gxg_gtk_widget_can_activate_accel_w, 2, 0, 0, H_gtk_widget_can_activate_accel, pl_bui); Xg_define_procedure(gtk_window_is_active, gxg_gtk_window_is_active_w, 1, 0, 0, H_gtk_window_is_active, pl_bu); Xg_define_procedure(gtk_window_has_toplevel_focus, gxg_gtk_window_has_toplevel_focus_w, 1, 0, 0, H_gtk_window_has_toplevel_focus, pl_bu); Xg_define_procedure(gtk_window_new, gxg_gtk_window_new_w, 1, 0, 0, H_gtk_window_new, pl_pi); Xg_define_procedure(gtk_window_set_title, gxg_gtk_window_set_title_w, 2, 0, 0, H_gtk_window_set_title, pl_tus); Xg_define_procedure(gtk_window_set_auto_startup_notification, gxg_gtk_window_set_auto_startup_notification_w, 1, 0, 0, H_gtk_window_set_auto_startup_notification, pl_tb); Xg_define_procedure(gtk_window_get_title, gxg_gtk_window_get_title_w, 1, 0, 0, H_gtk_window_get_title, pl_su); Xg_define_procedure(gtk_window_set_wmclass, gxg_gtk_window_set_wmclass_w, 3, 0, 0, H_gtk_window_set_wmclass, pl_tus); Xg_define_procedure(gtk_window_set_role, gxg_gtk_window_set_role_w, 2, 0, 0, H_gtk_window_set_role, pl_tus); Xg_define_procedure(gtk_window_get_role, gxg_gtk_window_get_role_w, 1, 0, 0, H_gtk_window_get_role, pl_su); Xg_define_procedure(gtk_window_add_accel_group, gxg_gtk_window_add_accel_group_w, 2, 0, 0, H_gtk_window_add_accel_group, pl_tu); Xg_define_procedure(gtk_window_remove_accel_group, gxg_gtk_window_remove_accel_group_w, 2, 0, 0, H_gtk_window_remove_accel_group, pl_tu); Xg_define_procedure(gtk_window_set_position, gxg_gtk_window_set_position_w, 2, 0, 0, H_gtk_window_set_position, pl_tui); Xg_define_procedure(gtk_window_activate_focus, gxg_gtk_window_activate_focus_w, 1, 0, 0, H_gtk_window_activate_focus, pl_bu); Xg_define_procedure(gtk_window_set_focus, gxg_gtk_window_set_focus_w, 2, 0, 0, H_gtk_window_set_focus, pl_tu); Xg_define_procedure(gtk_window_get_focus, gxg_gtk_window_get_focus_w, 1, 0, 0, H_gtk_window_get_focus, pl_pu); Xg_define_procedure(gtk_window_set_default, gxg_gtk_window_set_default_w, 2, 0, 0, H_gtk_window_set_default, pl_tu); Xg_define_procedure(gtk_window_activate_default, gxg_gtk_window_activate_default_w, 1, 0, 0, H_gtk_window_activate_default, pl_bu); Xg_define_procedure(gtk_window_set_transient_for, gxg_gtk_window_set_transient_for_w, 2, 0, 0, H_gtk_window_set_transient_for, pl_tu); Xg_define_procedure(gtk_window_get_transient_for, gxg_gtk_window_get_transient_for_w, 1, 0, 0, H_gtk_window_get_transient_for, pl_pu); Xg_define_procedure(gtk_window_set_type_hint, gxg_gtk_window_set_type_hint_w, 2, 0, 0, H_gtk_window_set_type_hint, pl_tui); Xg_define_procedure(gtk_window_get_type_hint, gxg_gtk_window_get_type_hint_w, 1, 0, 0, H_gtk_window_get_type_hint, pl_iu); Xg_define_procedure(gtk_window_set_destroy_with_parent, gxg_gtk_window_set_destroy_with_parent_w, 2, 0, 0, H_gtk_window_set_destroy_with_parent, pl_tub); Xg_define_procedure(gtk_window_get_destroy_with_parent, gxg_gtk_window_get_destroy_with_parent_w, 1, 0, 0, H_gtk_window_get_destroy_with_parent, pl_bu); Xg_define_procedure(gtk_window_set_resizable, gxg_gtk_window_set_resizable_w, 2, 0, 0, H_gtk_window_set_resizable, pl_tub); Xg_define_procedure(gtk_window_get_resizable, gxg_gtk_window_get_resizable_w, 1, 0, 0, H_gtk_window_get_resizable, pl_bu); Xg_define_procedure(gtk_window_set_gravity, gxg_gtk_window_set_gravity_w, 2, 0, 0, H_gtk_window_set_gravity, pl_tui); Xg_define_procedure(gtk_window_get_gravity, gxg_gtk_window_get_gravity_w, 1, 0, 0, H_gtk_window_get_gravity, pl_iu); Xg_define_procedure(gtk_window_set_geometry_hints, gxg_gtk_window_set_geometry_hints_w, 4, 0, 0, H_gtk_window_set_geometry_hints, pl_tuuui); Xg_define_procedure(gtk_window_set_decorated, gxg_gtk_window_set_decorated_w, 2, 0, 0, H_gtk_window_set_decorated, pl_tub); Xg_define_procedure(gtk_window_get_decorated, gxg_gtk_window_get_decorated_w, 1, 0, 0, H_gtk_window_get_decorated, pl_bu); Xg_define_procedure(gtk_window_set_icon_list, gxg_gtk_window_set_icon_list_w, 2, 0, 0, H_gtk_window_set_icon_list, pl_tu); Xg_define_procedure(gtk_window_get_icon_list, gxg_gtk_window_get_icon_list_w, 1, 0, 0, H_gtk_window_get_icon_list, pl_pu); Xg_define_procedure(gtk_window_set_icon, gxg_gtk_window_set_icon_w, 2, 0, 0, H_gtk_window_set_icon, pl_tu); Xg_define_procedure(gtk_window_get_icon, gxg_gtk_window_get_icon_w, 1, 0, 0, H_gtk_window_get_icon, pl_pu); Xg_define_procedure(gtk_window_set_default_icon_list, gxg_gtk_window_set_default_icon_list_w, 1, 0, 0, H_gtk_window_set_default_icon_list, pl_tu); Xg_define_procedure(gtk_window_get_default_icon_list, gxg_gtk_window_get_default_icon_list_w, 0, 0, 0, H_gtk_window_get_default_icon_list, pl_p); Xg_define_procedure(gtk_window_set_modal, gxg_gtk_window_set_modal_w, 2, 0, 0, H_gtk_window_set_modal, pl_tub); Xg_define_procedure(gtk_window_get_modal, gxg_gtk_window_get_modal_w, 1, 0, 0, H_gtk_window_get_modal, pl_bu); Xg_define_procedure(gtk_window_list_toplevels, gxg_gtk_window_list_toplevels_w, 0, 0, 0, H_gtk_window_list_toplevels, pl_p); Xg_define_procedure(gtk_window_add_mnemonic, gxg_gtk_window_add_mnemonic_w, 3, 0, 0, H_gtk_window_add_mnemonic, pl_tuiu); Xg_define_procedure(gtk_window_remove_mnemonic, gxg_gtk_window_remove_mnemonic_w, 3, 0, 0, H_gtk_window_remove_mnemonic, pl_tuiu); Xg_define_procedure(gtk_window_mnemonic_activate, gxg_gtk_window_mnemonic_activate_w, 3, 0, 0, H_gtk_window_mnemonic_activate, pl_bui); Xg_define_procedure(gtk_window_set_mnemonic_modifier, gxg_gtk_window_set_mnemonic_modifier_w, 2, 0, 0, H_gtk_window_set_mnemonic_modifier, pl_tui); Xg_define_procedure(gtk_window_get_mnemonic_modifier, gxg_gtk_window_get_mnemonic_modifier_w, 1, 0, 0, H_gtk_window_get_mnemonic_modifier, pl_iu); Xg_define_procedure(gtk_window_present, gxg_gtk_window_present_w, 1, 0, 0, H_gtk_window_present, pl_tu); Xg_define_procedure(gtk_window_iconify, gxg_gtk_window_iconify_w, 1, 0, 0, H_gtk_window_iconify, pl_tu); Xg_define_procedure(gtk_window_deiconify, gxg_gtk_window_deiconify_w, 1, 0, 0, H_gtk_window_deiconify, pl_tu); Xg_define_procedure(gtk_window_stick, gxg_gtk_window_stick_w, 1, 0, 0, H_gtk_window_stick, pl_tu); Xg_define_procedure(gtk_window_unstick, gxg_gtk_window_unstick_w, 1, 0, 0, H_gtk_window_unstick, pl_tu); Xg_define_procedure(gtk_window_maximize, gxg_gtk_window_maximize_w, 1, 0, 0, H_gtk_window_maximize, pl_tu); Xg_define_procedure(gtk_window_unmaximize, gxg_gtk_window_unmaximize_w, 1, 0, 0, H_gtk_window_unmaximize, pl_tu); Xg_define_procedure(gtk_window_begin_resize_drag, gxg_gtk_window_begin_resize_drag_w, 6, 0, 0, H_gtk_window_begin_resize_drag, pl_tui); Xg_define_procedure(gtk_window_begin_move_drag, gxg_gtk_window_begin_move_drag_w, 5, 0, 0, H_gtk_window_begin_move_drag, pl_tui); Xg_define_procedure(gtk_window_set_default_size, gxg_gtk_window_set_default_size_w, 3, 0, 0, H_gtk_window_set_default_size, pl_tui); Xg_define_procedure(gtk_window_get_default_size, gxg_gtk_window_get_default_size_w, 1, 2, 0, H_gtk_window_get_default_size, pl_tu); Xg_define_procedure(gtk_window_resize, gxg_gtk_window_resize_w, 3, 0, 0, H_gtk_window_resize, pl_tui); Xg_define_procedure(gtk_window_get_size, gxg_gtk_window_get_size_w, 1, 2, 0, H_gtk_window_get_size, pl_tu); Xg_define_procedure(gtk_window_move, gxg_gtk_window_move_w, 3, 0, 0, H_gtk_window_move, pl_tui); Xg_define_procedure(gtk_window_get_position, gxg_gtk_window_get_position_w, 1, 2, 0, H_gtk_window_get_position, pl_tu); Xg_define_procedure(gtk_window_parse_geometry, gxg_gtk_window_parse_geometry_w, 2, 0, 0, H_gtk_window_parse_geometry, pl_bus); Xg_define_procedure(pango_color_copy, gxg_pango_color_copy_w, 1, 0, 0, H_pango_color_copy, pl_pu); Xg_define_procedure(pango_color_free, gxg_pango_color_free_w, 1, 0, 0, H_pango_color_free, pl_tu); Xg_define_procedure(pango_color_parse, gxg_pango_color_parse_w, 2, 0, 0, H_pango_color_parse, pl_bus); Xg_define_procedure(pango_attr_type_register, gxg_pango_attr_type_register_w, 1, 0, 0, H_pango_attr_type_register, pl_is); Xg_define_procedure(pango_attribute_copy, gxg_pango_attribute_copy_w, 1, 0, 0, H_pango_attribute_copy, pl_pu); Xg_define_procedure(pango_attribute_destroy, gxg_pango_attribute_destroy_w, 1, 0, 0, H_pango_attribute_destroy, pl_tu); Xg_define_procedure(pango_attribute_equal, gxg_pango_attribute_equal_w, 2, 0, 0, H_pango_attribute_equal, pl_bu); Xg_define_procedure(pango_attr_language_new, gxg_pango_attr_language_new_w, 1, 0, 0, H_pango_attr_language_new, pl_pu); Xg_define_procedure(pango_attr_family_new, gxg_pango_attr_family_new_w, 1, 0, 0, H_pango_attr_family_new, pl_ps); Xg_define_procedure(pango_attr_foreground_new, gxg_pango_attr_foreground_new_w, 3, 0, 0, H_pango_attr_foreground_new, pl_pi); Xg_define_procedure(pango_attr_background_new, gxg_pango_attr_background_new_w, 3, 0, 0, H_pango_attr_background_new, pl_pi); Xg_define_procedure(pango_attr_size_new, gxg_pango_attr_size_new_w, 1, 0, 0, H_pango_attr_size_new, pl_pi); Xg_define_procedure(pango_attr_style_new, gxg_pango_attr_style_new_w, 1, 0, 0, H_pango_attr_style_new, pl_pi); Xg_define_procedure(pango_attr_weight_new, gxg_pango_attr_weight_new_w, 1, 0, 0, H_pango_attr_weight_new, pl_pi); Xg_define_procedure(pango_attr_variant_new, gxg_pango_attr_variant_new_w, 1, 0, 0, H_pango_attr_variant_new, pl_pi); Xg_define_procedure(pango_attr_stretch_new, gxg_pango_attr_stretch_new_w, 1, 0, 0, H_pango_attr_stretch_new, pl_pi); Xg_define_procedure(pango_attr_font_desc_new, gxg_pango_attr_font_desc_new_w, 1, 0, 0, H_pango_attr_font_desc_new, pl_pu); Xg_define_procedure(pango_attr_underline_new, gxg_pango_attr_underline_new_w, 1, 0, 0, H_pango_attr_underline_new, pl_pi); Xg_define_procedure(pango_attr_strikethrough_new, gxg_pango_attr_strikethrough_new_w, 1, 0, 0, H_pango_attr_strikethrough_new, pl_pb); Xg_define_procedure(pango_attr_rise_new, gxg_pango_attr_rise_new_w, 1, 0, 0, H_pango_attr_rise_new, pl_pi); Xg_define_procedure(pango_attr_shape_new, gxg_pango_attr_shape_new_w, 2, 0, 0, H_pango_attr_shape_new, pl_pu); Xg_define_procedure(pango_attr_scale_new, gxg_pango_attr_scale_new_w, 1, 0, 0, H_pango_attr_scale_new, pl_pr); Xg_define_procedure(pango_attr_list_new, gxg_pango_attr_list_new_w, 0, 0, 0, H_pango_attr_list_new, pl_p); Xg_define_procedure(pango_attr_list_unref, gxg_pango_attr_list_unref_w, 1, 0, 0, H_pango_attr_list_unref, pl_tu); Xg_define_procedure(pango_attr_list_copy, gxg_pango_attr_list_copy_w, 1, 0, 0, H_pango_attr_list_copy, pl_pu); Xg_define_procedure(pango_attr_list_insert, gxg_pango_attr_list_insert_w, 2, 0, 0, H_pango_attr_list_insert, pl_tu); Xg_define_procedure(pango_attr_list_insert_before, gxg_pango_attr_list_insert_before_w, 2, 0, 0, H_pango_attr_list_insert_before, pl_tu); Xg_define_procedure(pango_attr_list_change, gxg_pango_attr_list_change_w, 2, 0, 0, H_pango_attr_list_change, pl_tu); Xg_define_procedure(pango_attr_list_splice, gxg_pango_attr_list_splice_w, 4, 0, 0, H_pango_attr_list_splice, pl_tuui); Xg_define_procedure(pango_attr_list_get_iterator, gxg_pango_attr_list_get_iterator_w, 1, 0, 0, H_pango_attr_list_get_iterator, pl_pu); Xg_define_procedure(pango_attr_iterator_range, gxg_pango_attr_iterator_range_w, 1, 2, 0, H_pango_attr_iterator_range, pl_tu); Xg_define_procedure(pango_attr_iterator_next, gxg_pango_attr_iterator_next_w, 1, 0, 0, H_pango_attr_iterator_next, pl_bu); Xg_define_procedure(pango_attr_iterator_copy, gxg_pango_attr_iterator_copy_w, 1, 0, 0, H_pango_attr_iterator_copy, pl_pu); Xg_define_procedure(pango_attr_iterator_destroy, gxg_pango_attr_iterator_destroy_w, 1, 0, 0, H_pango_attr_iterator_destroy, pl_tu); Xg_define_procedure(pango_attr_iterator_get, gxg_pango_attr_iterator_get_w, 2, 0, 0, H_pango_attr_iterator_get, pl_pui); Xg_define_procedure(pango_attr_iterator_get_font, gxg_pango_attr_iterator_get_font_w, 2, 2, 0, H_pango_attr_iterator_get_font, pl_tu); Xg_define_procedure(pango_parse_markup, gxg_pango_parse_markup_w, 6, 1, 0, H_pango_parse_markup, pl_bsiiuusu); Xg_define_procedure(pango_break, gxg_pango_break_w, 5, 0, 0, H_pango_break, pl_tsiuui); Xg_define_procedure(pango_find_paragraph_boundary, gxg_pango_find_paragraph_boundary_w, 2, 2, 0, H_pango_find_paragraph_boundary, pl_tsiu); Xg_define_procedure(pango_get_log_attrs, gxg_pango_get_log_attrs_w, 6, 0, 0, H_pango_get_log_attrs, pl_tsiiuui); Xg_define_procedure(pango_context_list_families, gxg_pango_context_list_families_w, 1, 2, 0, H_pango_context_list_families, pl_tu); Xg_define_procedure(pango_context_load_font, gxg_pango_context_load_font_w, 2, 0, 0, H_pango_context_load_font, pl_pu); Xg_define_procedure(pango_context_load_fontset, gxg_pango_context_load_fontset_w, 3, 0, 0, H_pango_context_load_fontset, pl_pu); Xg_define_procedure(pango_context_get_metrics, gxg_pango_context_get_metrics_w, 3, 0, 0, H_pango_context_get_metrics, pl_pu); Xg_define_procedure(pango_context_set_font_description, gxg_pango_context_set_font_description_w, 2, 0, 0, H_pango_context_set_font_description, pl_tu); Xg_define_procedure(pango_context_get_font_description, gxg_pango_context_get_font_description_w, 1, 0, 0, H_pango_context_get_font_description, pl_pu); Xg_define_procedure(pango_context_get_language, gxg_pango_context_get_language_w, 1, 0, 0, H_pango_context_get_language, pl_pu); Xg_define_procedure(pango_context_set_language, gxg_pango_context_set_language_w, 2, 0, 0, H_pango_context_set_language, pl_tu); Xg_define_procedure(pango_context_set_base_dir, gxg_pango_context_set_base_dir_w, 2, 0, 0, H_pango_context_set_base_dir, pl_tui); Xg_define_procedure(pango_context_get_base_dir, gxg_pango_context_get_base_dir_w, 1, 0, 0, H_pango_context_get_base_dir, pl_iu); Xg_define_procedure(pango_itemize, gxg_pango_itemize_w, 6, 0, 0, H_pango_itemize, pl_pusiiu); Xg_define_procedure(pango_coverage_new, gxg_pango_coverage_new_w, 0, 0, 0, H_pango_coverage_new, pl_p); Xg_define_procedure(pango_coverage_ref, gxg_pango_coverage_ref_w, 1, 0, 0, H_pango_coverage_ref, pl_pu); Xg_define_procedure(pango_coverage_unref, gxg_pango_coverage_unref_w, 1, 0, 0, H_pango_coverage_unref, pl_tu); Xg_define_procedure(pango_coverage_copy, gxg_pango_coverage_copy_w, 1, 0, 0, H_pango_coverage_copy, pl_pu); Xg_define_procedure(pango_coverage_get, gxg_pango_coverage_get_w, 2, 0, 0, H_pango_coverage_get, pl_iui); Xg_define_procedure(pango_coverage_set, gxg_pango_coverage_set_w, 3, 0, 0, H_pango_coverage_set, pl_tui); Xg_define_procedure(pango_coverage_max, gxg_pango_coverage_max_w, 2, 0, 0, H_pango_coverage_max, pl_tu); Xg_define_procedure(pango_coverage_to_bytes, gxg_pango_coverage_to_bytes_w, 1, 2, 0, H_pango_coverage_to_bytes, pl_tu); Xg_define_procedure(pango_coverage_from_bytes, gxg_pango_coverage_from_bytes_w, 2, 0, 0, H_pango_coverage_from_bytes, pl_psi); Xg_define_procedure(pango_font_description_new, gxg_pango_font_description_new_w, 0, 0, 0, H_pango_font_description_new, pl_p); Xg_define_procedure(pango_font_description_copy, gxg_pango_font_description_copy_w, 1, 0, 0, H_pango_font_description_copy, pl_pu); Xg_define_procedure(pango_font_description_copy_static, gxg_pango_font_description_copy_static_w, 1, 0, 0, H_pango_font_description_copy_static, pl_pu); Xg_define_procedure(pango_font_description_hash, gxg_pango_font_description_hash_w, 1, 0, 0, H_pango_font_description_hash, pl_iu); Xg_define_procedure(pango_font_description_equal, gxg_pango_font_description_equal_w, 2, 0, 0, H_pango_font_description_equal, pl_bu); Xg_define_procedure(pango_font_description_free, gxg_pango_font_description_free_w, 1, 0, 0, H_pango_font_description_free, pl_tu); Xg_define_procedure(pango_font_descriptions_free, gxg_pango_font_descriptions_free_w, 2, 0, 0, H_pango_font_descriptions_free, pl_tui); Xg_define_procedure(pango_font_description_set_family, gxg_pango_font_description_set_family_w, 2, 0, 0, H_pango_font_description_set_family, pl_tus); Xg_define_procedure(pango_font_description_set_family_static, gxg_pango_font_description_set_family_static_w, 2, 0, 0, H_pango_font_description_set_family_static, pl_tus); Xg_define_procedure(pango_font_description_get_family, gxg_pango_font_description_get_family_w, 1, 0, 0, H_pango_font_description_get_family, pl_su); Xg_define_procedure(pango_font_description_set_style, gxg_pango_font_description_set_style_w, 2, 0, 0, H_pango_font_description_set_style, pl_tui); Xg_define_procedure(pango_font_description_get_style, gxg_pango_font_description_get_style_w, 1, 0, 0, H_pango_font_description_get_style, pl_iu); Xg_define_procedure(pango_font_description_set_variant, gxg_pango_font_description_set_variant_w, 2, 0, 0, H_pango_font_description_set_variant, pl_tui); Xg_define_procedure(pango_font_description_get_variant, gxg_pango_font_description_get_variant_w, 1, 0, 0, H_pango_font_description_get_variant, pl_iu); Xg_define_procedure(pango_font_description_set_weight, gxg_pango_font_description_set_weight_w, 2, 0, 0, H_pango_font_description_set_weight, pl_tui); Xg_define_procedure(pango_font_description_get_weight, gxg_pango_font_description_get_weight_w, 1, 0, 0, H_pango_font_description_get_weight, pl_iu); Xg_define_procedure(pango_font_description_set_stretch, gxg_pango_font_description_set_stretch_w, 2, 0, 0, H_pango_font_description_set_stretch, pl_tui); Xg_define_procedure(pango_font_description_get_stretch, gxg_pango_font_description_get_stretch_w, 1, 0, 0, H_pango_font_description_get_stretch, pl_iu); Xg_define_procedure(pango_font_description_set_size, gxg_pango_font_description_set_size_w, 2, 0, 0, H_pango_font_description_set_size, pl_tui); Xg_define_procedure(pango_font_description_get_size, gxg_pango_font_description_get_size_w, 1, 0, 0, H_pango_font_description_get_size, pl_iu); Xg_define_procedure(pango_font_description_get_set_fields, gxg_pango_font_description_get_set_fields_w, 1, 0, 0, H_pango_font_description_get_set_fields, pl_iu); Xg_define_procedure(pango_font_description_unset_fields, gxg_pango_font_description_unset_fields_w, 2, 0, 0, H_pango_font_description_unset_fields, pl_tui); Xg_define_procedure(pango_font_description_merge, gxg_pango_font_description_merge_w, 3, 0, 0, H_pango_font_description_merge, pl_tuub); Xg_define_procedure(pango_font_description_merge_static, gxg_pango_font_description_merge_static_w, 3, 0, 0, H_pango_font_description_merge_static, pl_tuub); Xg_define_procedure(pango_font_description_better_match, gxg_pango_font_description_better_match_w, 3, 0, 0, H_pango_font_description_better_match, pl_bu); Xg_define_procedure(pango_font_description_from_string, gxg_pango_font_description_from_string_w, 1, 0, 0, H_pango_font_description_from_string, pl_ps); Xg_define_procedure(pango_font_description_to_string, gxg_pango_font_description_to_string_w, 1, 0, 0, H_pango_font_description_to_string, pl_su); Xg_define_procedure(pango_font_description_to_filename, gxg_pango_font_description_to_filename_w, 1, 0, 0, H_pango_font_description_to_filename, pl_su); Xg_define_procedure(pango_font_metrics_ref, gxg_pango_font_metrics_ref_w, 1, 0, 0, H_pango_font_metrics_ref, pl_pu); Xg_define_procedure(pango_font_metrics_unref, gxg_pango_font_metrics_unref_w, 1, 0, 0, H_pango_font_metrics_unref, pl_tu); Xg_define_procedure(pango_font_metrics_get_ascent, gxg_pango_font_metrics_get_ascent_w, 1, 0, 0, H_pango_font_metrics_get_ascent, pl_iu); Xg_define_procedure(pango_font_metrics_get_descent, gxg_pango_font_metrics_get_descent_w, 1, 0, 0, H_pango_font_metrics_get_descent, pl_iu); Xg_define_procedure(pango_font_metrics_get_approximate_char_width, gxg_pango_font_metrics_get_approximate_char_width_w, 1, 0, 0, H_pango_font_metrics_get_approximate_char_width, pl_iu); Xg_define_procedure(pango_font_metrics_get_approximate_digit_width, gxg_pango_font_metrics_get_approximate_digit_width_w, 1, 0, 0, H_pango_font_metrics_get_approximate_digit_width, pl_iu); Xg_define_procedure(pango_font_family_list_faces, gxg_pango_font_family_list_faces_w, 1, 2, 0, H_pango_font_family_list_faces, pl_tu); Xg_define_procedure(pango_font_family_get_name, gxg_pango_font_family_get_name_w, 1, 0, 0, H_pango_font_family_get_name, pl_su); Xg_define_procedure(pango_font_face_describe, gxg_pango_font_face_describe_w, 1, 0, 0, H_pango_font_face_describe, pl_pu); Xg_define_procedure(pango_font_face_get_face_name, gxg_pango_font_face_get_face_name_w, 1, 0, 0, H_pango_font_face_get_face_name, pl_su); Xg_define_procedure(pango_font_describe, gxg_pango_font_describe_w, 1, 0, 0, H_pango_font_describe, pl_pu); Xg_define_procedure(pango_font_get_coverage, gxg_pango_font_get_coverage_w, 2, 0, 0, H_pango_font_get_coverage, pl_pu); Xg_define_procedure(pango_font_get_metrics, gxg_pango_font_get_metrics_w, 2, 0, 0, H_pango_font_get_metrics, pl_pu); Xg_define_procedure(pango_font_get_glyph_extents, gxg_pango_font_get_glyph_extents_w, 4, 0, 0, H_pango_font_get_glyph_extents, pl_tuiu); Xg_define_procedure(pango_font_map_load_font, gxg_pango_font_map_load_font_w, 3, 0, 0, H_pango_font_map_load_font, pl_pu); Xg_define_procedure(pango_font_map_load_fontset, gxg_pango_font_map_load_fontset_w, 4, 0, 0, H_pango_font_map_load_fontset, pl_pu); Xg_define_procedure(pango_font_map_list_families, gxg_pango_font_map_list_families_w, 1, 2, 0, H_pango_font_map_list_families, pl_tu); Xg_define_procedure(pango_glyph_string_new, gxg_pango_glyph_string_new_w, 0, 0, 0, H_pango_glyph_string_new, pl_p); Xg_define_procedure(pango_glyph_string_set_size, gxg_pango_glyph_string_set_size_w, 2, 0, 0, H_pango_glyph_string_set_size, pl_tui); Xg_define_procedure(pango_glyph_string_copy, gxg_pango_glyph_string_copy_w, 1, 0, 0, H_pango_glyph_string_copy, pl_pu); Xg_define_procedure(pango_glyph_string_free, gxg_pango_glyph_string_free_w, 1, 0, 0, H_pango_glyph_string_free, pl_tu); Xg_define_procedure(pango_glyph_string_extents, gxg_pango_glyph_string_extents_w, 4, 0, 0, H_pango_glyph_string_extents, pl_tu); Xg_define_procedure(pango_glyph_string_extents_range, gxg_pango_glyph_string_extents_range_w, 6, 0, 0, H_pango_glyph_string_extents_range, pl_tuiiu); Xg_define_procedure(pango_glyph_string_get_logical_widths, gxg_pango_glyph_string_get_logical_widths_w, 4, 1, 0, H_pango_glyph_string_get_logical_widths, pl_tusiiu); Xg_define_procedure(pango_glyph_string_index_to_x, gxg_pango_glyph_string_index_to_x_w, 6, 1, 0, H_pango_glyph_string_index_to_x, pl_tusiuibu); Xg_define_procedure(pango_glyph_string_x_to_index, gxg_pango_glyph_string_x_to_index_w, 5, 2, 0, H_pango_glyph_string_x_to_index, pl_tusiuiu); Xg_define_procedure(pango_shape, gxg_pango_shape_w, 4, 0, 0, H_pango_shape, pl_tsiu); Xg_define_procedure(pango_reorder_items, gxg_pango_reorder_items_w, 1, 0, 0, H_pango_reorder_items, pl_pu); Xg_define_procedure(pango_item_new, gxg_pango_item_new_w, 0, 0, 0, H_pango_item_new, pl_p); Xg_define_procedure(pango_item_copy, gxg_pango_item_copy_w, 1, 0, 0, H_pango_item_copy, pl_pu); Xg_define_procedure(pango_item_free, gxg_pango_item_free_w, 1, 0, 0, H_pango_item_free, pl_tu); Xg_define_procedure(pango_item_split, gxg_pango_item_split_w, 3, 0, 0, H_pango_item_split, pl_pui); Xg_define_procedure(pango_layout_new, gxg_pango_layout_new_w, 1, 0, 0, H_pango_layout_new, pl_pu); Xg_define_procedure(pango_layout_copy, gxg_pango_layout_copy_w, 1, 0, 0, H_pango_layout_copy, pl_pu); Xg_define_procedure(pango_layout_get_context, gxg_pango_layout_get_context_w, 1, 0, 0, H_pango_layout_get_context, pl_pu); Xg_define_procedure(pango_layout_set_attributes, gxg_pango_layout_set_attributes_w, 2, 0, 0, H_pango_layout_set_attributes, pl_tu); Xg_define_procedure(pango_layout_get_attributes, gxg_pango_layout_get_attributes_w, 1, 0, 0, H_pango_layout_get_attributes, pl_pu); Xg_define_procedure(pango_layout_set_text, gxg_pango_layout_set_text_w, 3, 0, 0, H_pango_layout_set_text, pl_tusi); Xg_define_procedure(pango_layout_get_text, gxg_pango_layout_get_text_w, 1, 0, 0, H_pango_layout_get_text, pl_su); Xg_define_procedure(pango_layout_set_markup, gxg_pango_layout_set_markup_w, 3, 0, 0, H_pango_layout_set_markup, pl_tusi); Xg_define_procedure(pango_layout_set_markup_with_accel, gxg_pango_layout_set_markup_with_accel_w, 5, 0, 0, H_pango_layout_set_markup_with_accel, pl_tusiis); Xg_define_procedure(pango_layout_set_font_description, gxg_pango_layout_set_font_description_w, 2, 0, 0, H_pango_layout_set_font_description, pl_tu); Xg_define_procedure(pango_layout_set_width, gxg_pango_layout_set_width_w, 2, 0, 0, H_pango_layout_set_width, pl_tui); Xg_define_procedure(pango_layout_get_width, gxg_pango_layout_get_width_w, 1, 0, 0, H_pango_layout_get_width, pl_iu); Xg_define_procedure(pango_layout_set_wrap, gxg_pango_layout_set_wrap_w, 2, 0, 0, H_pango_layout_set_wrap, pl_tui); Xg_define_procedure(pango_layout_get_wrap, gxg_pango_layout_get_wrap_w, 1, 0, 0, H_pango_layout_get_wrap, pl_iu); Xg_define_procedure(pango_layout_set_indent, gxg_pango_layout_set_indent_w, 2, 0, 0, H_pango_layout_set_indent, pl_tui); Xg_define_procedure(pango_layout_get_indent, gxg_pango_layout_get_indent_w, 1, 0, 0, H_pango_layout_get_indent, pl_iu); Xg_define_procedure(pango_layout_set_spacing, gxg_pango_layout_set_spacing_w, 2, 0, 0, H_pango_layout_set_spacing, pl_tui); Xg_define_procedure(pango_layout_get_spacing, gxg_pango_layout_get_spacing_w, 1, 0, 0, H_pango_layout_get_spacing, pl_iu); Xg_define_procedure(pango_layout_set_justify, gxg_pango_layout_set_justify_w, 2, 0, 0, H_pango_layout_set_justify, pl_tub); Xg_define_procedure(pango_layout_get_justify, gxg_pango_layout_get_justify_w, 1, 0, 0, H_pango_layout_get_justify, pl_bu); Xg_define_procedure(pango_layout_set_alignment, gxg_pango_layout_set_alignment_w, 2, 0, 0, H_pango_layout_set_alignment, pl_tui); Xg_define_procedure(pango_layout_get_alignment, gxg_pango_layout_get_alignment_w, 1, 0, 0, H_pango_layout_get_alignment, pl_iu); Xg_define_procedure(pango_layout_set_tabs, gxg_pango_layout_set_tabs_w, 2, 0, 0, H_pango_layout_set_tabs, pl_tu); Xg_define_procedure(pango_layout_get_tabs, gxg_pango_layout_get_tabs_w, 1, 0, 0, H_pango_layout_get_tabs, pl_pu); Xg_define_procedure(pango_layout_set_single_paragraph_mode, gxg_pango_layout_set_single_paragraph_mode_w, 2, 0, 0, H_pango_layout_set_single_paragraph_mode, pl_tub); Xg_define_procedure(pango_layout_get_single_paragraph_mode, gxg_pango_layout_get_single_paragraph_mode_w, 1, 0, 0, H_pango_layout_get_single_paragraph_mode, pl_bu); Xg_define_procedure(pango_layout_context_changed, gxg_pango_layout_context_changed_w, 1, 0, 0, H_pango_layout_context_changed, pl_tu); Xg_define_procedure(pango_layout_get_log_attrs, gxg_pango_layout_get_log_attrs_w, 1, 2, 0, H_pango_layout_get_log_attrs, pl_tu); Xg_define_procedure(pango_layout_index_to_pos, gxg_pango_layout_index_to_pos_w, 3, 0, 0, H_pango_layout_index_to_pos, pl_tuiu); Xg_define_procedure(pango_layout_get_cursor_pos, gxg_pango_layout_get_cursor_pos_w, 4, 0, 0, H_pango_layout_get_cursor_pos, pl_tuiu); Xg_define_procedure(pango_layout_move_cursor_visually, gxg_pango_layout_move_cursor_visually_w, 7, 0, 0, H_pango_layout_move_cursor_visually, pl_tubiiiu); Xg_define_procedure(pango_layout_xy_to_index, gxg_pango_layout_xy_to_index_w, 3, 2, 0, H_pango_layout_xy_to_index, pl_buiiu); Xg_define_procedure(pango_layout_get_extents, gxg_pango_layout_get_extents_w, 3, 0, 0, H_pango_layout_get_extents, pl_tu); Xg_define_procedure(pango_layout_get_pixel_extents, gxg_pango_layout_get_pixel_extents_w, 3, 0, 0, H_pango_layout_get_pixel_extents, pl_tu); Xg_define_procedure(pango_layout_get_size, gxg_pango_layout_get_size_w, 1, 2, 0, H_pango_layout_get_size, pl_tu); Xg_define_procedure(pango_layout_get_pixel_size, gxg_pango_layout_get_pixel_size_w, 1, 2, 0, H_pango_layout_get_pixel_size, pl_tu); Xg_define_procedure(pango_layout_get_line_count, gxg_pango_layout_get_line_count_w, 1, 0, 0, H_pango_layout_get_line_count, pl_iu); Xg_define_procedure(pango_layout_get_line, gxg_pango_layout_get_line_w, 2, 0, 0, H_pango_layout_get_line, pl_pui); Xg_define_procedure(pango_layout_get_lines, gxg_pango_layout_get_lines_w, 1, 0, 0, H_pango_layout_get_lines, pl_pu); Xg_define_procedure(pango_layout_line_unref, gxg_pango_layout_line_unref_w, 1, 0, 0, H_pango_layout_line_unref, pl_tu); Xg_define_procedure(pango_layout_line_x_to_index, gxg_pango_layout_line_x_to_index_w, 2, 2, 0, H_pango_layout_line_x_to_index, pl_buiu); Xg_define_procedure(pango_layout_line_index_to_x, gxg_pango_layout_line_index_to_x_w, 3, 1, 0, H_pango_layout_line_index_to_x, pl_tuibu); Xg_define_procedure(pango_layout_line_get_x_ranges, gxg_pango_layout_line_get_x_ranges_w, 3, 2, 0, H_pango_layout_line_get_x_ranges, pl_tuiiu); Xg_define_procedure(pango_layout_line_get_extents, gxg_pango_layout_line_get_extents_w, 3, 0, 0, H_pango_layout_line_get_extents, pl_tu); Xg_define_procedure(pango_layout_line_get_pixel_extents, gxg_pango_layout_line_get_pixel_extents_w, 3, 0, 0, H_pango_layout_line_get_pixel_extents, pl_tu); Xg_define_procedure(pango_layout_get_iter, gxg_pango_layout_get_iter_w, 1, 0, 0, H_pango_layout_get_iter, pl_pu); Xg_define_procedure(pango_layout_iter_free, gxg_pango_layout_iter_free_w, 1, 0, 0, H_pango_layout_iter_free, pl_tu); Xg_define_procedure(pango_layout_iter_get_index, gxg_pango_layout_iter_get_index_w, 1, 0, 0, H_pango_layout_iter_get_index, pl_iu); Xg_define_procedure(pango_layout_iter_get_run, gxg_pango_layout_iter_get_run_w, 1, 0, 0, H_pango_layout_iter_get_run, pl_pu); Xg_define_procedure(pango_layout_iter_get_line, gxg_pango_layout_iter_get_line_w, 1, 0, 0, H_pango_layout_iter_get_line, pl_pu); Xg_define_procedure(pango_layout_iter_at_last_line, gxg_pango_layout_iter_at_last_line_w, 1, 0, 0, H_pango_layout_iter_at_last_line, pl_bu); Xg_define_procedure(pango_layout_iter_next_char, gxg_pango_layout_iter_next_char_w, 1, 0, 0, H_pango_layout_iter_next_char, pl_bu); Xg_define_procedure(pango_layout_iter_next_cluster, gxg_pango_layout_iter_next_cluster_w, 1, 0, 0, H_pango_layout_iter_next_cluster, pl_bu); Xg_define_procedure(pango_layout_iter_next_run, gxg_pango_layout_iter_next_run_w, 1, 0, 0, H_pango_layout_iter_next_run, pl_bu); Xg_define_procedure(pango_layout_iter_next_line, gxg_pango_layout_iter_next_line_w, 1, 0, 0, H_pango_layout_iter_next_line, pl_bu); Xg_define_procedure(pango_layout_iter_get_char_extents, gxg_pango_layout_iter_get_char_extents_w, 2, 0, 0, H_pango_layout_iter_get_char_extents, pl_tu); Xg_define_procedure(pango_layout_iter_get_cluster_extents, gxg_pango_layout_iter_get_cluster_extents_w, 3, 0, 0, H_pango_layout_iter_get_cluster_extents, pl_tu); Xg_define_procedure(pango_layout_iter_get_run_extents, gxg_pango_layout_iter_get_run_extents_w, 3, 0, 0, H_pango_layout_iter_get_run_extents, pl_tu); Xg_define_procedure(pango_layout_iter_get_line_extents, gxg_pango_layout_iter_get_line_extents_w, 3, 0, 0, H_pango_layout_iter_get_line_extents, pl_tu); Xg_define_procedure(pango_layout_iter_get_line_yrange, gxg_pango_layout_iter_get_line_yrange_w, 1, 2, 0, H_pango_layout_iter_get_line_yrange, pl_tu); Xg_define_procedure(pango_layout_iter_get_layout_extents, gxg_pango_layout_iter_get_layout_extents_w, 3, 0, 0, H_pango_layout_iter_get_layout_extents, pl_tu); Xg_define_procedure(pango_layout_iter_get_baseline, gxg_pango_layout_iter_get_baseline_w, 1, 0, 0, H_pango_layout_iter_get_baseline, pl_iu); Xg_define_procedure(pango_language_from_string, gxg_pango_language_from_string_w, 1, 0, 0, H_pango_language_from_string, pl_ps); Xg_define_procedure(pango_language_matches, gxg_pango_language_matches_w, 2, 0, 0, H_pango_language_matches, pl_bus); Xg_define_procedure(G_OBJECT_TYPE, gxg_G_OBJECT_TYPE_w, 1, 0, 0, H_G_OBJECT_TYPE, pl_iu); Xg_define_procedure(gtk_tree_model_get_string_from_iter, gxg_gtk_tree_model_get_string_from_iter_w, 2, 0, 0, H_gtk_tree_model_get_string_from_iter, pl_su); Xg_define_procedure(gtk_tree_model_sort_iter_is_valid, gxg_gtk_tree_model_sort_iter_is_valid_w, 2, 0, 0, H_gtk_tree_model_sort_iter_is_valid, pl_bu); Xg_define_procedure(gtk_tree_view_expand_to_path, gxg_gtk_tree_view_expand_to_path_w, 2, 0, 0, H_gtk_tree_view_expand_to_path, pl_tu); Xg_define_procedure(gtk_tree_selection_get_selected_rows, gxg_gtk_tree_selection_get_selected_rows_w, 2, 0, 0, H_gtk_tree_selection_get_selected_rows, pl_pu); Xg_define_procedure(gtk_tree_selection_count_selected_rows, gxg_gtk_tree_selection_count_selected_rows_w, 1, 0, 0, H_gtk_tree_selection_count_selected_rows, pl_iu); Xg_define_procedure(gtk_menu_shell_select_first, gxg_gtk_menu_shell_select_first_w, 2, 0, 0, H_gtk_menu_shell_select_first, pl_tub); Xg_define_procedure(gtk_notebook_get_n_pages, gxg_gtk_notebook_get_n_pages_w, 1, 0, 0, H_gtk_notebook_get_n_pages, pl_iu); Xg_define_procedure(gtk_list_store_reorder, gxg_gtk_list_store_reorder_w, 2, 0, 0, H_gtk_list_store_reorder, pl_tu); Xg_define_procedure(gtk_list_store_swap, gxg_gtk_list_store_swap_w, 3, 0, 0, H_gtk_list_store_swap, pl_tu); Xg_define_procedure(gtk_list_store_move_after, gxg_gtk_list_store_move_after_w, 3, 0, 0, H_gtk_list_store_move_after, pl_tu); Xg_define_procedure(gtk_list_store_move_before, gxg_gtk_list_store_move_before_w, 3, 0, 0, H_gtk_list_store_move_before, pl_tu); Xg_define_procedure(gtk_tree_store_reorder, gxg_gtk_tree_store_reorder_w, 3, 0, 0, H_gtk_tree_store_reorder, pl_tu); Xg_define_procedure(gtk_tree_store_swap, gxg_gtk_tree_store_swap_w, 3, 0, 0, H_gtk_tree_store_swap, pl_tu); Xg_define_procedure(gdk_display_open, gxg_gdk_display_open_w, 1, 0, 0, H_gdk_display_open, pl_ps); Xg_define_procedure(gdk_display_get_name, gxg_gdk_display_get_name_w, 1, 0, 0, H_gdk_display_get_name, pl_su); Xg_define_procedure(gdk_display_get_screen, gxg_gdk_display_get_screen_w, 2, 0, 0, H_gdk_display_get_screen, pl_pui); Xg_define_procedure(gdk_display_get_default_screen, gxg_gdk_display_get_default_screen_w, 1, 0, 0, H_gdk_display_get_default_screen, pl_pu); Xg_define_procedure(gdk_display_beep, gxg_gdk_display_beep_w, 1, 0, 0, H_gdk_display_beep, pl_tu); Xg_define_procedure(gdk_display_sync, gxg_gdk_display_sync_w, 1, 0, 0, H_gdk_display_sync, pl_tu); Xg_define_procedure(gdk_display_close, gxg_gdk_display_close_w, 1, 0, 0, H_gdk_display_close, pl_tu); Xg_define_procedure(gdk_display_get_event, gxg_gdk_display_get_event_w, 1, 0, 0, H_gdk_display_get_event, pl_pu); Xg_define_procedure(gdk_display_peek_event, gxg_gdk_display_peek_event_w, 1, 0, 0, H_gdk_display_peek_event, pl_pu); Xg_define_procedure(gdk_display_put_event, gxg_gdk_display_put_event_w, 2, 0, 0, H_gdk_display_put_event, pl_tu); Xg_define_procedure(gdk_display_set_double_click_time, gxg_gdk_display_set_double_click_time_w, 2, 0, 0, H_gdk_display_set_double_click_time, pl_tui); Xg_define_procedure(gdk_display_get_default, gxg_gdk_display_get_default_w, 0, 0, 0, H_gdk_display_get_default, pl_p); Xg_define_procedure(gdk_screen_get_system_visual, gxg_gdk_screen_get_system_visual_w, 1, 0, 0, H_gdk_screen_get_system_visual, pl_pu); Xg_define_procedure(gdk_screen_get_root_window, gxg_gdk_screen_get_root_window_w, 1, 0, 0, H_gdk_screen_get_root_window, pl_pu); Xg_define_procedure(gdk_screen_get_display, gxg_gdk_screen_get_display_w, 1, 0, 0, H_gdk_screen_get_display, pl_pu); Xg_define_procedure(gdk_screen_get_number, gxg_gdk_screen_get_number_w, 1, 0, 0, H_gdk_screen_get_number, pl_iu); Xg_define_procedure(gdk_screen_get_width, gxg_gdk_screen_get_width_w, 1, 0, 0, H_gdk_screen_get_width, pl_iu); Xg_define_procedure(gdk_screen_get_height, gxg_gdk_screen_get_height_w, 1, 0, 0, H_gdk_screen_get_height, pl_iu); Xg_define_procedure(gdk_screen_get_width_mm, gxg_gdk_screen_get_width_mm_w, 1, 0, 0, H_gdk_screen_get_width_mm, pl_iu); Xg_define_procedure(gdk_screen_get_height_mm, gxg_gdk_screen_get_height_mm_w, 1, 0, 0, H_gdk_screen_get_height_mm, pl_iu); Xg_define_procedure(gdk_screen_list_visuals, gxg_gdk_screen_list_visuals_w, 1, 0, 0, H_gdk_screen_list_visuals, pl_pu); Xg_define_procedure(gdk_screen_get_toplevel_windows, gxg_gdk_screen_get_toplevel_windows_w, 1, 0, 0, H_gdk_screen_get_toplevel_windows, pl_pu); Xg_define_procedure(gdk_screen_make_display_name, gxg_gdk_screen_make_display_name_w, 1, 0, 0, H_gdk_screen_make_display_name, pl_su); Xg_define_procedure(gdk_screen_get_n_monitors, gxg_gdk_screen_get_n_monitors_w, 1, 0, 0, H_gdk_screen_get_n_monitors, pl_iu); Xg_define_procedure(gdk_screen_get_monitor_geometry, gxg_gdk_screen_get_monitor_geometry_w, 3, 0, 0, H_gdk_screen_get_monitor_geometry, pl_tuiu); Xg_define_procedure(gdk_screen_get_monitor_at_point, gxg_gdk_screen_get_monitor_at_point_w, 3, 0, 0, H_gdk_screen_get_monitor_at_point, pl_iui); Xg_define_procedure(gdk_screen_get_monitor_at_window, gxg_gdk_screen_get_monitor_at_window_w, 2, 0, 0, H_gdk_screen_get_monitor_at_window, pl_iu); Xg_define_procedure(gdk_screen_get_default, gxg_gdk_screen_get_default_w, 0, 0, 0, H_gdk_screen_get_default, pl_p); Xg_define_procedure(gtk_clipboard_get_for_display, gxg_gtk_clipboard_get_for_display_w, 2, 0, 0, H_gtk_clipboard_get_for_display, pl_put); Xg_define_procedure(gtk_clipboard_get_display, gxg_gtk_clipboard_get_display_w, 1, 0, 0, H_gtk_clipboard_get_display, pl_pu); Xg_define_procedure(gtk_widget_get_screen, gxg_gtk_widget_get_screen_w, 1, 0, 0, H_gtk_widget_get_screen, pl_pu); Xg_define_procedure(gtk_widget_has_screen, gxg_gtk_widget_has_screen_w, 1, 0, 0, H_gtk_widget_has_screen, pl_bu); Xg_define_procedure(gtk_widget_get_display, gxg_gtk_widget_get_display_w, 1, 0, 0, H_gtk_widget_get_display, pl_pu); Xg_define_procedure(gtk_widget_get_clipboard, gxg_gtk_widget_get_clipboard_w, 2, 0, 0, H_gtk_widget_get_clipboard, pl_put); Xg_define_procedure(g_list_free, gxg_g_list_free_w, 1, 0, 0, H_g_list_free, pl_tu); Xg_define_procedure(g_list_reverse, gxg_g_list_reverse_w, 1, 0, 0, H_g_list_reverse, pl_pu); Xg_define_procedure(g_list_copy, gxg_g_list_copy_w, 1, 0, 0, H_g_list_copy, pl_pu); Xg_define_procedure(g_list_last, gxg_g_list_last_w, 1, 0, 0, H_g_list_last, pl_pu); Xg_define_procedure(g_list_first, gxg_g_list_first_w, 1, 0, 0, H_g_list_first, pl_pu); Xg_define_procedure(g_list_length, gxg_g_list_length_w, 1, 0, 0, H_g_list_length, pl_iu); Xg_define_procedure(g_free, gxg_g_free_w, 1, 0, 0, H_g_free, pl_t); Xg_define_procedure(g_list_remove_link, gxg_g_list_remove_link_w, 2, 0, 0, H_g_list_remove_link, pl_pu); Xg_define_procedure(g_object_get_data, gxg_g_object_get_data_w, 2, 0, 0, H_g_object_get_data, pl_tus); Xg_define_procedure(g_object_set_data, gxg_g_object_set_data_w, 3, 0, 0, H_g_object_set_data, pl_tust); Xg_define_procedure(gdk_cursor_new_from_pixbuf, gxg_gdk_cursor_new_from_pixbuf_w, 4, 0, 0, H_gdk_cursor_new_from_pixbuf, pl_puui); Xg_define_procedure(gdk_display_flush, gxg_gdk_display_flush_w, 1, 0, 0, H_gdk_display_flush, pl_tu); Xg_define_procedure(gdk_display_supports_cursor_alpha, gxg_gdk_display_supports_cursor_alpha_w, 1, 0, 0, H_gdk_display_supports_cursor_alpha, pl_bu); Xg_define_procedure(gdk_display_supports_cursor_color, gxg_gdk_display_supports_cursor_color_w, 1, 0, 0, H_gdk_display_supports_cursor_color, pl_bu); Xg_define_procedure(gdk_display_get_default_cursor_size, gxg_gdk_display_get_default_cursor_size_w, 1, 0, 0, H_gdk_display_get_default_cursor_size, pl_iu); Xg_define_procedure(gdk_display_get_maximal_cursor_size, gxg_gdk_display_get_maximal_cursor_size_w, 1, 2, 0, H_gdk_display_get_maximal_cursor_size, pl_tu); Xg_define_procedure(gdk_window_set_keep_above, gxg_gdk_window_set_keep_above_w, 2, 0, 0, H_gdk_window_set_keep_above, pl_tub); Xg_define_procedure(gdk_window_set_keep_below, gxg_gdk_window_set_keep_below_w, 2, 0, 0, H_gdk_window_set_keep_below, pl_tub); Xg_define_procedure(gtk_button_box_get_child_secondary, gxg_gtk_button_box_get_child_secondary_w, 2, 0, 0, H_gtk_button_box_get_child_secondary, pl_bu); Xg_define_procedure(gtk_calendar_set_display_options, gxg_gtk_calendar_set_display_options_w, 2, 0, 0, H_gtk_calendar_set_display_options, pl_tui); Xg_define_procedure(gtk_calendar_get_display_options, gxg_gtk_calendar_get_display_options_w, 1, 0, 0, H_gtk_calendar_get_display_options, pl_iu); Xg_define_procedure(gtk_check_menu_item_set_draw_as_radio, gxg_gtk_check_menu_item_set_draw_as_radio_w, 2, 0, 0, H_gtk_check_menu_item_set_draw_as_radio, pl_tub); Xg_define_procedure(gtk_check_menu_item_get_draw_as_radio, gxg_gtk_check_menu_item_get_draw_as_radio_w, 1, 0, 0, H_gtk_check_menu_item_get_draw_as_radio, pl_bu); Xg_define_procedure(gtk_entry_set_completion, gxg_gtk_entry_set_completion_w, 2, 0, 0, H_gtk_entry_set_completion, pl_tu); Xg_define_procedure(gtk_entry_get_completion, gxg_gtk_entry_get_completion_w, 1, 0, 0, H_gtk_entry_get_completion, pl_pu); Xg_define_procedure(gtk_event_box_get_visible_window, gxg_gtk_event_box_get_visible_window_w, 1, 0, 0, H_gtk_event_box_get_visible_window, pl_bu); Xg_define_procedure(gtk_event_box_set_visible_window, gxg_gtk_event_box_set_visible_window_w, 2, 0, 0, H_gtk_event_box_set_visible_window, pl_tub); Xg_define_procedure(gtk_event_box_get_above_child, gxg_gtk_event_box_get_above_child_w, 1, 0, 0, H_gtk_event_box_get_above_child, pl_bu); Xg_define_procedure(gtk_event_box_set_above_child, gxg_gtk_event_box_set_above_child_w, 2, 0, 0, H_gtk_event_box_set_above_child, pl_tub); Xg_define_procedure(gtk_menu_attach, gxg_gtk_menu_attach_w, 6, 0, 0, H_gtk_menu_attach, pl_tuui); Xg_define_procedure(gtk_text_buffer_select_range, gxg_gtk_text_buffer_select_range_w, 3, 0, 0, H_gtk_text_buffer_select_range, pl_tu); Xg_define_procedure(gtk_text_view_set_overwrite, gxg_gtk_text_view_set_overwrite_w, 2, 0, 0, H_gtk_text_view_set_overwrite, pl_tub); Xg_define_procedure(gtk_text_view_get_overwrite, gxg_gtk_text_view_get_overwrite_w, 1, 0, 0, H_gtk_text_view_get_overwrite, pl_bu); Xg_define_procedure(gtk_text_view_set_accepts_tab, gxg_gtk_text_view_set_accepts_tab_w, 2, 0, 0, H_gtk_text_view_set_accepts_tab, pl_tub); Xg_define_procedure(gtk_text_view_get_accepts_tab, gxg_gtk_text_view_get_accepts_tab_w, 1, 0, 0, H_gtk_text_view_get_accepts_tab, pl_bu); Xg_define_procedure(gtk_toolbar_insert, gxg_gtk_toolbar_insert_w, 3, 0, 0, H_gtk_toolbar_insert, pl_tuui); Xg_define_procedure(gtk_toolbar_get_item_index, gxg_gtk_toolbar_get_item_index_w, 2, 0, 0, H_gtk_toolbar_get_item_index, pl_iu); Xg_define_procedure(gtk_toolbar_get_n_items, gxg_gtk_toolbar_get_n_items_w, 1, 0, 0, H_gtk_toolbar_get_n_items, pl_iu); Xg_define_procedure(gtk_toolbar_get_nth_item, gxg_gtk_toolbar_get_nth_item_w, 2, 0, 0, H_gtk_toolbar_get_nth_item, pl_pui); Xg_define_procedure(gtk_toolbar_set_show_arrow, gxg_gtk_toolbar_set_show_arrow_w, 2, 0, 0, H_gtk_toolbar_set_show_arrow, pl_tub); Xg_define_procedure(gtk_toolbar_get_show_arrow, gxg_gtk_toolbar_get_show_arrow_w, 1, 0, 0, H_gtk_toolbar_get_show_arrow, pl_bu); Xg_define_procedure(gtk_toolbar_get_relief_style, gxg_gtk_toolbar_get_relief_style_w, 1, 0, 0, H_gtk_toolbar_get_relief_style, pl_iu); Xg_define_procedure(gtk_toolbar_get_drop_index, gxg_gtk_toolbar_get_drop_index_w, 3, 0, 0, H_gtk_toolbar_get_drop_index, pl_iui); Xg_define_procedure(gtk_tree_view_column_set_expand, gxg_gtk_tree_view_column_set_expand_w, 2, 0, 0, H_gtk_tree_view_column_set_expand, pl_tub); Xg_define_procedure(gtk_tree_view_column_get_expand, gxg_gtk_tree_view_column_get_expand_w, 1, 0, 0, H_gtk_tree_view_column_get_expand, pl_bu); Xg_define_procedure(gtk_widget_set_no_show_all, gxg_gtk_widget_set_no_show_all_w, 2, 0, 0, H_gtk_widget_set_no_show_all, pl_tub); Xg_define_procedure(gtk_widget_get_no_show_all, gxg_gtk_widget_get_no_show_all_w, 1, 0, 0, H_gtk_widget_get_no_show_all, pl_bu); Xg_define_procedure(gtk_widget_queue_resize_no_redraw, gxg_gtk_widget_queue_resize_no_redraw_w, 1, 0, 0, H_gtk_widget_queue_resize_no_redraw, pl_tu); Xg_define_procedure(gtk_window_set_default_icon, gxg_gtk_window_set_default_icon_w, 1, 0, 0, H_gtk_window_set_default_icon, pl_tu); Xg_define_procedure(gtk_window_set_keep_above, gxg_gtk_window_set_keep_above_w, 2, 0, 0, H_gtk_window_set_keep_above, pl_tub); Xg_define_procedure(gtk_window_set_keep_below, gxg_gtk_window_set_keep_below_w, 2, 0, 0, H_gtk_window_set_keep_below, pl_tub); Xg_define_procedure(gtk_file_chooser_dialog_new, gxg_gtk_file_chooser_dialog_new_w, 3, 1, 0, H_gtk_file_chooser_dialog_new, pl_psuit); Xg_define_procedure(gtk_file_chooser_widget_new, gxg_gtk_file_chooser_widget_new_w, 1, 0, 0, H_gtk_file_chooser_widget_new, pl_pi); Xg_define_procedure(gtk_tree_model_filter_new, gxg_gtk_tree_model_filter_new_w, 2, 0, 0, H_gtk_tree_model_filter_new, pl_pu); Xg_define_procedure(gtk_tree_model_filter_set_visible_column, gxg_gtk_tree_model_filter_set_visible_column_w, 2, 0, 0, H_gtk_tree_model_filter_set_visible_column, pl_tui); Xg_define_procedure(gtk_tree_model_filter_get_model, gxg_gtk_tree_model_filter_get_model_w, 1, 0, 0, H_gtk_tree_model_filter_get_model, pl_pu); Xg_define_procedure(gtk_tree_model_filter_convert_iter_to_child_iter, gxg_gtk_tree_model_filter_convert_iter_to_child_iter_w, 3, 0, 0, H_gtk_tree_model_filter_convert_iter_to_child_iter, pl_tu); Xg_define_procedure(gtk_tree_model_filter_convert_child_path_to_path, gxg_gtk_tree_model_filter_convert_child_path_to_path_w, 2, 0, 0, H_gtk_tree_model_filter_convert_child_path_to_path, pl_pu); Xg_define_procedure(gtk_tree_model_filter_convert_path_to_child_path, gxg_gtk_tree_model_filter_convert_path_to_child_path_w, 2, 0, 0, H_gtk_tree_model_filter_convert_path_to_child_path, pl_pu); Xg_define_procedure(gtk_tree_model_filter_refilter, gxg_gtk_tree_model_filter_refilter_w, 1, 0, 0, H_gtk_tree_model_filter_refilter, pl_tu); Xg_define_procedure(gtk_tree_model_filter_clear_cache, gxg_gtk_tree_model_filter_clear_cache_w, 1, 0, 0, H_gtk_tree_model_filter_clear_cache, pl_tu); Xg_define_procedure(gtk_combo_box_new, gxg_gtk_combo_box_new_w, 0, 0, 0, H_gtk_combo_box_new, pl_p); Xg_define_procedure(gtk_combo_box_new_with_model, gxg_gtk_combo_box_new_with_model_w, 1, 0, 0, H_gtk_combo_box_new_with_model, pl_pu); Xg_define_procedure(gtk_combo_box_set_model, gxg_gtk_combo_box_set_model_w, 2, 0, 0, H_gtk_combo_box_set_model, pl_tu); Xg_define_procedure(gtk_combo_box_set_wrap_width, gxg_gtk_combo_box_set_wrap_width_w, 2, 0, 0, H_gtk_combo_box_set_wrap_width, pl_tui); Xg_define_procedure(gtk_combo_box_set_row_span_column, gxg_gtk_combo_box_set_row_span_column_w, 2, 0, 0, H_gtk_combo_box_set_row_span_column, pl_tui); Xg_define_procedure(gtk_combo_box_set_column_span_column, gxg_gtk_combo_box_set_column_span_column_w, 2, 0, 0, H_gtk_combo_box_set_column_span_column, pl_tui); Xg_define_procedure(gtk_combo_box_get_active, gxg_gtk_combo_box_get_active_w, 1, 0, 0, H_gtk_combo_box_get_active, pl_iu); Xg_define_procedure(gtk_combo_box_set_active, gxg_gtk_combo_box_set_active_w, 2, 0, 0, H_gtk_combo_box_set_active, pl_tui); Xg_define_procedure(gtk_combo_box_get_active_iter, gxg_gtk_combo_box_get_active_iter_w, 2, 0, 0, H_gtk_combo_box_get_active_iter, pl_bu); Xg_define_procedure(gtk_combo_box_set_active_iter, gxg_gtk_combo_box_set_active_iter_w, 2, 0, 0, H_gtk_combo_box_set_active_iter, pl_tu); Xg_define_procedure(gtk_combo_box_get_model, gxg_gtk_combo_box_get_model_w, 1, 0, 0, H_gtk_combo_box_get_model, pl_pu); Xg_define_procedure(gtk_expander_new, gxg_gtk_expander_new_w, 1, 0, 0, H_gtk_expander_new, pl_ps); Xg_define_procedure(gtk_expander_new_with_mnemonic, gxg_gtk_expander_new_with_mnemonic_w, 1, 0, 0, H_gtk_expander_new_with_mnemonic, pl_ps); Xg_define_procedure(gtk_expander_set_expanded, gxg_gtk_expander_set_expanded_w, 2, 0, 0, H_gtk_expander_set_expanded, pl_tub); Xg_define_procedure(gtk_expander_get_expanded, gxg_gtk_expander_get_expanded_w, 1, 0, 0, H_gtk_expander_get_expanded, pl_bu); Xg_define_procedure(gtk_expander_set_spacing, gxg_gtk_expander_set_spacing_w, 2, 0, 0, H_gtk_expander_set_spacing, pl_tui); Xg_define_procedure(gtk_expander_get_spacing, gxg_gtk_expander_get_spacing_w, 1, 0, 0, H_gtk_expander_get_spacing, pl_iu); Xg_define_procedure(gtk_expander_set_label, gxg_gtk_expander_set_label_w, 2, 0, 0, H_gtk_expander_set_label, pl_tus); Xg_define_procedure(gtk_expander_get_label, gxg_gtk_expander_get_label_w, 1, 0, 0, H_gtk_expander_get_label, pl_su); Xg_define_procedure(gtk_expander_set_use_underline, gxg_gtk_expander_set_use_underline_w, 2, 0, 0, H_gtk_expander_set_use_underline, pl_tub); Xg_define_procedure(gtk_expander_get_use_underline, gxg_gtk_expander_get_use_underline_w, 1, 0, 0, H_gtk_expander_get_use_underline, pl_bu); Xg_define_procedure(gtk_expander_set_label_widget, gxg_gtk_expander_set_label_widget_w, 2, 0, 0, H_gtk_expander_set_label_widget, pl_tu); Xg_define_procedure(gtk_expander_get_label_widget, gxg_gtk_expander_get_label_widget_w, 1, 0, 0, H_gtk_expander_get_label_widget, pl_pu); Xg_define_procedure(gtk_expander_set_use_markup, gxg_gtk_expander_set_use_markup_w, 2, 0, 0, H_gtk_expander_set_use_markup, pl_tub); Xg_define_procedure(gtk_expander_get_use_markup, gxg_gtk_expander_get_use_markup_w, 1, 0, 0, H_gtk_expander_get_use_markup, pl_bu); Xg_define_procedure(gtk_font_button_new, gxg_gtk_font_button_new_w, 0, 0, 0, H_gtk_font_button_new, pl_p); Xg_define_procedure(gtk_font_button_new_with_font, gxg_gtk_font_button_new_with_font_w, 1, 0, 0, H_gtk_font_button_new_with_font, pl_ps); Xg_define_procedure(gtk_font_button_get_title, gxg_gtk_font_button_get_title_w, 1, 0, 0, H_gtk_font_button_get_title, pl_su); Xg_define_procedure(gtk_font_button_set_title, gxg_gtk_font_button_set_title_w, 2, 0, 0, H_gtk_font_button_set_title, pl_tus); Xg_define_procedure(gtk_font_button_get_use_font, gxg_gtk_font_button_get_use_font_w, 1, 0, 0, H_gtk_font_button_get_use_font, pl_bu); Xg_define_procedure(gtk_font_button_set_use_font, gxg_gtk_font_button_set_use_font_w, 2, 0, 0, H_gtk_font_button_set_use_font, pl_tub); Xg_define_procedure(gtk_font_button_get_use_size, gxg_gtk_font_button_get_use_size_w, 1, 0, 0, H_gtk_font_button_get_use_size, pl_bu); Xg_define_procedure(gtk_font_button_set_use_size, gxg_gtk_font_button_set_use_size_w, 2, 0, 0, H_gtk_font_button_set_use_size, pl_tub); Xg_define_procedure(gtk_font_button_get_font_name, gxg_gtk_font_button_get_font_name_w, 1, 0, 0, H_gtk_font_button_get_font_name, pl_su); Xg_define_procedure(gtk_font_button_set_font_name, gxg_gtk_font_button_set_font_name_w, 2, 0, 0, H_gtk_font_button_set_font_name, pl_bus); Xg_define_procedure(gtk_font_button_get_show_style, gxg_gtk_font_button_get_show_style_w, 1, 0, 0, H_gtk_font_button_get_show_style, pl_bu); Xg_define_procedure(gtk_font_button_set_show_style, gxg_gtk_font_button_set_show_style_w, 2, 0, 0, H_gtk_font_button_set_show_style, pl_tub); Xg_define_procedure(gtk_font_button_get_show_size, gxg_gtk_font_button_get_show_size_w, 1, 0, 0, H_gtk_font_button_get_show_size, pl_bu); Xg_define_procedure(gtk_font_button_set_show_size, gxg_gtk_font_button_set_show_size_w, 2, 0, 0, H_gtk_font_button_set_show_size, pl_tub); Xg_define_procedure(gtk_entry_completion_new, gxg_gtk_entry_completion_new_w, 0, 0, 0, H_gtk_entry_completion_new, pl_p); Xg_define_procedure(gtk_entry_completion_get_entry, gxg_gtk_entry_completion_get_entry_w, 1, 0, 0, H_gtk_entry_completion_get_entry, pl_pu); Xg_define_procedure(gtk_entry_completion_set_model, gxg_gtk_entry_completion_set_model_w, 2, 0, 0, H_gtk_entry_completion_set_model, pl_tu); Xg_define_procedure(gtk_entry_completion_get_model, gxg_gtk_entry_completion_get_model_w, 1, 0, 0, H_gtk_entry_completion_get_model, pl_pu); Xg_define_procedure(gtk_entry_completion_set_match_func, gxg_gtk_entry_completion_set_match_func_w, 4, 0, 0, H_gtk_entry_completion_set_match_func, pl_tut); Xg_define_procedure(gtk_entry_completion_set_minimum_key_length, gxg_gtk_entry_completion_set_minimum_key_length_w, 2, 0, 0, H_gtk_entry_completion_set_minimum_key_length, pl_tui); Xg_define_procedure(gtk_entry_completion_get_minimum_key_length, gxg_gtk_entry_completion_get_minimum_key_length_w, 1, 0, 0, H_gtk_entry_completion_get_minimum_key_length, pl_iu); Xg_define_procedure(gtk_entry_completion_complete, gxg_gtk_entry_completion_complete_w, 1, 0, 0, H_gtk_entry_completion_complete, pl_tu); Xg_define_procedure(gtk_entry_completion_insert_action_text, gxg_gtk_entry_completion_insert_action_text_w, 3, 0, 0, H_gtk_entry_completion_insert_action_text, pl_tuis); Xg_define_procedure(gtk_entry_completion_insert_action_markup, gxg_gtk_entry_completion_insert_action_markup_w, 3, 0, 0, H_gtk_entry_completion_insert_action_markup, pl_tuis); Xg_define_procedure(gtk_entry_completion_delete_action, gxg_gtk_entry_completion_delete_action_w, 2, 0, 0, H_gtk_entry_completion_delete_action, pl_tui); Xg_define_procedure(gtk_entry_completion_set_text_column, gxg_gtk_entry_completion_set_text_column_w, 2, 0, 0, H_gtk_entry_completion_set_text_column, pl_tui); Xg_define_procedure(gtk_radio_tool_button_new, gxg_gtk_radio_tool_button_new_w, 1, 0, 0, H_gtk_radio_tool_button_new, pl_pu); Xg_define_procedure(gtk_radio_tool_button_new_from_widget, gxg_gtk_radio_tool_button_new_from_widget_w, 1, 0, 0, H_gtk_radio_tool_button_new_from_widget, pl_pu); Xg_define_procedure(gtk_radio_tool_button_get_group, gxg_gtk_radio_tool_button_get_group_w, 1, 0, 0, H_gtk_radio_tool_button_get_group, pl_pu); Xg_define_procedure(gtk_radio_tool_button_set_group, gxg_gtk_radio_tool_button_set_group_w, 2, 0, 0, H_gtk_radio_tool_button_set_group, pl_tu); Xg_define_procedure(gtk_separator_tool_item_new, gxg_gtk_separator_tool_item_new_w, 0, 0, 0, H_gtk_separator_tool_item_new, pl_p); Xg_define_procedure(gtk_separator_tool_item_get_draw, gxg_gtk_separator_tool_item_get_draw_w, 1, 0, 0, H_gtk_separator_tool_item_get_draw, pl_bu); Xg_define_procedure(gtk_separator_tool_item_set_draw, gxg_gtk_separator_tool_item_set_draw_w, 2, 0, 0, H_gtk_separator_tool_item_set_draw, pl_tub); Xg_define_procedure(gtk_toggle_tool_button_new, gxg_gtk_toggle_tool_button_new_w, 0, 0, 0, H_gtk_toggle_tool_button_new, pl_p); Xg_define_procedure(gtk_toggle_tool_button_set_active, gxg_gtk_toggle_tool_button_set_active_w, 2, 0, 0, H_gtk_toggle_tool_button_set_active, pl_tub); Xg_define_procedure(gtk_toggle_tool_button_get_active, gxg_gtk_toggle_tool_button_get_active_w, 1, 0, 0, H_gtk_toggle_tool_button_get_active, pl_bu); Xg_define_procedure(g_timeout_add_full, gxg_g_timeout_add_full_w, 5, 0, 0, H_g_timeout_add_full, pl_iiit); Xg_define_procedure(g_timeout_add, gxg_g_timeout_add_w, 2, 1, 0, H_g_timeout_add, pl_iit); Xg_define_procedure(g_idle_add, gxg_g_idle_add_w, 1, 1, 0, H_g_idle_add, pl_it); Xg_define_procedure(g_idle_add_full, gxg_g_idle_add_full_w, 4, 0, 0, H_g_idle_add_full, pl_iit); Xg_define_procedure(g_idle_remove_by_data, gxg_g_idle_remove_by_data_w, 1, 0, 0, H_g_idle_remove_by_data, pl_bt); Xg_define_procedure(g_source_remove, gxg_g_source_remove_w, 1, 0, 0, H_g_source_remove, pl_bi); Xg_define_procedure(gtk_file_filter_new, gxg_gtk_file_filter_new_w, 0, 0, 0, H_gtk_file_filter_new, pl_p); Xg_define_procedure(gtk_file_filter_set_name, gxg_gtk_file_filter_set_name_w, 2, 0, 0, H_gtk_file_filter_set_name, pl_tus); Xg_define_procedure(gtk_file_filter_get_name, gxg_gtk_file_filter_get_name_w, 1, 0, 0, H_gtk_file_filter_get_name, pl_su); Xg_define_procedure(gtk_file_filter_add_mime_type, gxg_gtk_file_filter_add_mime_type_w, 2, 0, 0, H_gtk_file_filter_add_mime_type, pl_tus); Xg_define_procedure(gtk_file_filter_add_pattern, gxg_gtk_file_filter_add_pattern_w, 2, 0, 0, H_gtk_file_filter_add_pattern, pl_tus); Xg_define_procedure(gtk_file_filter_add_custom, gxg_gtk_file_filter_add_custom_w, 5, 0, 0, H_gtk_file_filter_add_custom, pl_tuit); Xg_define_procedure(gtk_file_filter_get_needed, gxg_gtk_file_filter_get_needed_w, 1, 0, 0, H_gtk_file_filter_get_needed, pl_iu); Xg_define_procedure(gtk_file_filter_filter, gxg_gtk_file_filter_filter_w, 2, 0, 0, H_gtk_file_filter_filter, pl_bu); Xg_define_procedure(gtk_cell_layout_pack_start, gxg_gtk_cell_layout_pack_start_w, 3, 0, 0, H_gtk_cell_layout_pack_start, pl_tuub); Xg_define_procedure(gtk_cell_layout_pack_end, gxg_gtk_cell_layout_pack_end_w, 3, 0, 0, H_gtk_cell_layout_pack_end, pl_tuub); Xg_define_procedure(gtk_cell_layout_clear, gxg_gtk_cell_layout_clear_w, 1, 0, 0, H_gtk_cell_layout_clear, pl_tu); Xg_define_procedure(gtk_cell_layout_set_attributes, gxg_gtk_cell_layout_set_attributes_w, 3, 0, 0, H_gtk_cell_layout_set_attributes, pl_tuut); Xg_define_procedure(gtk_cell_layout_add_attribute, gxg_gtk_cell_layout_add_attribute_w, 4, 0, 0, H_gtk_cell_layout_add_attribute, pl_tuusi); Xg_define_procedure(gtk_cell_layout_set_cell_data_func, gxg_gtk_cell_layout_set_cell_data_func_w, 5, 0, 0, H_gtk_cell_layout_set_cell_data_func, pl_tuut); Xg_define_procedure(gtk_cell_layout_clear_attributes, gxg_gtk_cell_layout_clear_attributes_w, 2, 0, 0, H_gtk_cell_layout_clear_attributes, pl_tu); Xg_define_procedure(gtk_file_chooser_set_action, gxg_gtk_file_chooser_set_action_w, 2, 0, 0, H_gtk_file_chooser_set_action, pl_tui); Xg_define_procedure(gtk_file_chooser_get_action, gxg_gtk_file_chooser_get_action_w, 1, 0, 0, H_gtk_file_chooser_get_action, pl_iu); Xg_define_procedure(gtk_file_chooser_set_local_only, gxg_gtk_file_chooser_set_local_only_w, 2, 0, 0, H_gtk_file_chooser_set_local_only, pl_tub); Xg_define_procedure(gtk_file_chooser_get_local_only, gxg_gtk_file_chooser_get_local_only_w, 1, 0, 0, H_gtk_file_chooser_get_local_only, pl_bu); Xg_define_procedure(gtk_file_chooser_set_select_multiple, gxg_gtk_file_chooser_set_select_multiple_w, 2, 0, 0, H_gtk_file_chooser_set_select_multiple, pl_tub); Xg_define_procedure(gtk_file_chooser_get_select_multiple, gxg_gtk_file_chooser_get_select_multiple_w, 1, 0, 0, H_gtk_file_chooser_get_select_multiple, pl_bu); Xg_define_procedure(gtk_file_chooser_set_current_name, gxg_gtk_file_chooser_set_current_name_w, 2, 0, 0, H_gtk_file_chooser_set_current_name, pl_tus); Xg_define_procedure(gtk_file_chooser_get_filename, gxg_gtk_file_chooser_get_filename_w, 1, 0, 0, H_gtk_file_chooser_get_filename, pl_su); Xg_define_procedure(gtk_file_chooser_set_filename, gxg_gtk_file_chooser_set_filename_w, 2, 0, 0, H_gtk_file_chooser_set_filename, pl_bus); Xg_define_procedure(gtk_file_chooser_select_filename, gxg_gtk_file_chooser_select_filename_w, 2, 0, 0, H_gtk_file_chooser_select_filename, pl_bus); Xg_define_procedure(gtk_file_chooser_unselect_filename, gxg_gtk_file_chooser_unselect_filename_w, 2, 0, 0, H_gtk_file_chooser_unselect_filename, pl_tus); Xg_define_procedure(gtk_file_chooser_select_all, gxg_gtk_file_chooser_select_all_w, 1, 0, 0, H_gtk_file_chooser_select_all, pl_tu); Xg_define_procedure(gtk_file_chooser_unselect_all, gxg_gtk_file_chooser_unselect_all_w, 1, 0, 0, H_gtk_file_chooser_unselect_all, pl_tu); Xg_define_procedure(gtk_file_chooser_get_filenames, gxg_gtk_file_chooser_get_filenames_w, 1, 0, 0, H_gtk_file_chooser_get_filenames, pl_pu); Xg_define_procedure(gtk_file_chooser_set_current_folder, gxg_gtk_file_chooser_set_current_folder_w, 2, 0, 0, H_gtk_file_chooser_set_current_folder, pl_bus); Xg_define_procedure(gtk_file_chooser_get_current_folder, gxg_gtk_file_chooser_get_current_folder_w, 1, 0, 0, H_gtk_file_chooser_get_current_folder, pl_su); Xg_define_procedure(gtk_file_chooser_get_uri, gxg_gtk_file_chooser_get_uri_w, 1, 0, 0, H_gtk_file_chooser_get_uri, pl_su); Xg_define_procedure(gtk_file_chooser_set_uri, gxg_gtk_file_chooser_set_uri_w, 2, 0, 0, H_gtk_file_chooser_set_uri, pl_bus); Xg_define_procedure(gtk_file_chooser_select_uri, gxg_gtk_file_chooser_select_uri_w, 2, 0, 0, H_gtk_file_chooser_select_uri, pl_bus); Xg_define_procedure(gtk_file_chooser_unselect_uri, gxg_gtk_file_chooser_unselect_uri_w, 2, 0, 0, H_gtk_file_chooser_unselect_uri, pl_tus); Xg_define_procedure(gtk_file_chooser_get_uris, gxg_gtk_file_chooser_get_uris_w, 1, 0, 0, H_gtk_file_chooser_get_uris, pl_pu); Xg_define_procedure(gtk_file_chooser_set_current_folder_uri, gxg_gtk_file_chooser_set_current_folder_uri_w, 2, 0, 0, H_gtk_file_chooser_set_current_folder_uri, pl_bus); Xg_define_procedure(gtk_file_chooser_get_current_folder_uri, gxg_gtk_file_chooser_get_current_folder_uri_w, 1, 0, 0, H_gtk_file_chooser_get_current_folder_uri, pl_su); Xg_define_procedure(gtk_file_chooser_set_preview_widget, gxg_gtk_file_chooser_set_preview_widget_w, 2, 0, 0, H_gtk_file_chooser_set_preview_widget, pl_tu); Xg_define_procedure(gtk_file_chooser_get_preview_widget, gxg_gtk_file_chooser_get_preview_widget_w, 1, 0, 0, H_gtk_file_chooser_get_preview_widget, pl_pu); Xg_define_procedure(gtk_file_chooser_set_preview_widget_active, gxg_gtk_file_chooser_set_preview_widget_active_w, 2, 0, 0, H_gtk_file_chooser_set_preview_widget_active, pl_tub); Xg_define_procedure(gtk_file_chooser_get_preview_widget_active, gxg_gtk_file_chooser_get_preview_widget_active_w, 1, 0, 0, H_gtk_file_chooser_get_preview_widget_active, pl_bu); Xg_define_procedure(gtk_file_chooser_get_preview_filename, gxg_gtk_file_chooser_get_preview_filename_w, 1, 0, 0, H_gtk_file_chooser_get_preview_filename, pl_su); Xg_define_procedure(gtk_file_chooser_get_preview_uri, gxg_gtk_file_chooser_get_preview_uri_w, 1, 0, 0, H_gtk_file_chooser_get_preview_uri, pl_su); Xg_define_procedure(gtk_file_chooser_set_extra_widget, gxg_gtk_file_chooser_set_extra_widget_w, 2, 0, 0, H_gtk_file_chooser_set_extra_widget, pl_tu); Xg_define_procedure(gtk_file_chooser_get_extra_widget, gxg_gtk_file_chooser_get_extra_widget_w, 1, 0, 0, H_gtk_file_chooser_get_extra_widget, pl_pu); Xg_define_procedure(gtk_file_chooser_add_filter, gxg_gtk_file_chooser_add_filter_w, 2, 0, 0, H_gtk_file_chooser_add_filter, pl_tu); Xg_define_procedure(gtk_file_chooser_remove_filter, gxg_gtk_file_chooser_remove_filter_w, 2, 0, 0, H_gtk_file_chooser_remove_filter, pl_tu); Xg_define_procedure(gtk_file_chooser_list_filters, gxg_gtk_file_chooser_list_filters_w, 1, 0, 0, H_gtk_file_chooser_list_filters, pl_pu); Xg_define_procedure(gtk_file_chooser_set_filter, gxg_gtk_file_chooser_set_filter_w, 2, 0, 0, H_gtk_file_chooser_set_filter, pl_tu); Xg_define_procedure(gtk_file_chooser_get_filter, gxg_gtk_file_chooser_get_filter_w, 1, 0, 0, H_gtk_file_chooser_get_filter, pl_pu); Xg_define_procedure(gtk_file_chooser_add_shortcut_folder, gxg_gtk_file_chooser_add_shortcut_folder_w, 2, 1, 0, H_gtk_file_chooser_add_shortcut_folder, pl_busu); Xg_define_procedure(gtk_file_chooser_remove_shortcut_folder, gxg_gtk_file_chooser_remove_shortcut_folder_w, 2, 1, 0, H_gtk_file_chooser_remove_shortcut_folder, pl_busu); Xg_define_procedure(gtk_file_chooser_list_shortcut_folders, gxg_gtk_file_chooser_list_shortcut_folders_w, 1, 0, 0, H_gtk_file_chooser_list_shortcut_folders, pl_pu); Xg_define_procedure(gtk_file_chooser_add_shortcut_folder_uri, gxg_gtk_file_chooser_add_shortcut_folder_uri_w, 2, 1, 0, H_gtk_file_chooser_add_shortcut_folder_uri, pl_busu); Xg_define_procedure(gtk_file_chooser_remove_shortcut_folder_uri, gxg_gtk_file_chooser_remove_shortcut_folder_uri_w, 2, 1, 0, H_gtk_file_chooser_remove_shortcut_folder_uri, pl_busu); Xg_define_procedure(gtk_file_chooser_list_shortcut_folder_uris, gxg_gtk_file_chooser_list_shortcut_folder_uris_w, 1, 0, 0, H_gtk_file_chooser_list_shortcut_folder_uris, pl_pu); Xg_define_procedure(gtk_icon_theme_new, gxg_gtk_icon_theme_new_w, 0, 0, 0, H_gtk_icon_theme_new, pl_p); Xg_define_procedure(gtk_icon_theme_get_default, gxg_gtk_icon_theme_get_default_w, 0, 0, 0, H_gtk_icon_theme_get_default, pl_p); Xg_define_procedure(gtk_icon_theme_get_for_screen, gxg_gtk_icon_theme_get_for_screen_w, 1, 0, 0, H_gtk_icon_theme_get_for_screen, pl_pu); Xg_define_procedure(gtk_icon_theme_set_screen, gxg_gtk_icon_theme_set_screen_w, 2, 0, 0, H_gtk_icon_theme_set_screen, pl_tu); Xg_define_procedure(gtk_icon_theme_get_search_path, gxg_gtk_icon_theme_get_search_path_w, 1, 2, 0, H_gtk_icon_theme_get_search_path, pl_tu); Xg_define_procedure(gtk_icon_theme_append_search_path, gxg_gtk_icon_theme_append_search_path_w, 2, 0, 0, H_gtk_icon_theme_append_search_path, pl_tus); Xg_define_procedure(gtk_icon_theme_prepend_search_path, gxg_gtk_icon_theme_prepend_search_path_w, 2, 0, 0, H_gtk_icon_theme_prepend_search_path, pl_tus); Xg_define_procedure(gtk_icon_theme_set_custom_theme, gxg_gtk_icon_theme_set_custom_theme_w, 2, 0, 0, H_gtk_icon_theme_set_custom_theme, pl_tus); Xg_define_procedure(gtk_icon_theme_has_icon, gxg_gtk_icon_theme_has_icon_w, 2, 0, 0, H_gtk_icon_theme_has_icon, pl_bus); Xg_define_procedure(gtk_icon_theme_lookup_icon, gxg_gtk_icon_theme_lookup_icon_w, 4, 0, 0, H_gtk_icon_theme_lookup_icon, pl_pusi); Xg_define_procedure(gtk_icon_theme_load_icon, gxg_gtk_icon_theme_load_icon_w, 4, 1, 0, H_gtk_icon_theme_load_icon, pl_pusiiu); Xg_define_procedure(gtk_icon_theme_list_icons, gxg_gtk_icon_theme_list_icons_w, 2, 0, 0, H_gtk_icon_theme_list_icons, pl_pus); Xg_define_procedure(gtk_icon_theme_get_example_icon_name, gxg_gtk_icon_theme_get_example_icon_name_w, 1, 0, 0, H_gtk_icon_theme_get_example_icon_name, pl_su); Xg_define_procedure(gtk_icon_theme_rescan_if_needed, gxg_gtk_icon_theme_rescan_if_needed_w, 1, 0, 0, H_gtk_icon_theme_rescan_if_needed, pl_bu); Xg_define_procedure(gtk_icon_info_get_base_size, gxg_gtk_icon_info_get_base_size_w, 1, 0, 0, H_gtk_icon_info_get_base_size, pl_iu); Xg_define_procedure(gtk_icon_info_get_filename, gxg_gtk_icon_info_get_filename_w, 1, 0, 0, H_gtk_icon_info_get_filename, pl_su); Xg_define_procedure(gtk_icon_info_load_icon, gxg_gtk_icon_info_load_icon_w, 1, 1, 0, H_gtk_icon_info_load_icon, pl_pu); Xg_define_procedure(gtk_tool_button_new, gxg_gtk_tool_button_new_w, 2, 0, 0, H_gtk_tool_button_new, pl_pus); Xg_define_procedure(gtk_tool_button_set_label, gxg_gtk_tool_button_set_label_w, 2, 0, 0, H_gtk_tool_button_set_label, pl_tus); Xg_define_procedure(gtk_tool_button_get_label, gxg_gtk_tool_button_get_label_w, 1, 0, 0, H_gtk_tool_button_get_label, pl_su); Xg_define_procedure(gtk_tool_button_set_use_underline, gxg_gtk_tool_button_set_use_underline_w, 2, 0, 0, H_gtk_tool_button_set_use_underline, pl_tub); Xg_define_procedure(gtk_tool_button_get_use_underline, gxg_gtk_tool_button_get_use_underline_w, 1, 0, 0, H_gtk_tool_button_get_use_underline, pl_bu); Xg_define_procedure(gtk_tool_button_set_icon_widget, gxg_gtk_tool_button_set_icon_widget_w, 2, 0, 0, H_gtk_tool_button_set_icon_widget, pl_tu); Xg_define_procedure(gtk_tool_button_get_icon_widget, gxg_gtk_tool_button_get_icon_widget_w, 1, 0, 0, H_gtk_tool_button_get_icon_widget, pl_pu); Xg_define_procedure(gtk_tool_button_set_label_widget, gxg_gtk_tool_button_set_label_widget_w, 2, 0, 0, H_gtk_tool_button_set_label_widget, pl_tu); Xg_define_procedure(gtk_tool_button_get_label_widget, gxg_gtk_tool_button_get_label_widget_w, 1, 0, 0, H_gtk_tool_button_get_label_widget, pl_pu); Xg_define_procedure(gtk_tool_item_new, gxg_gtk_tool_item_new_w, 0, 0, 0, H_gtk_tool_item_new, pl_p); Xg_define_procedure(gtk_tool_item_set_homogeneous, gxg_gtk_tool_item_set_homogeneous_w, 2, 0, 0, H_gtk_tool_item_set_homogeneous, pl_tub); Xg_define_procedure(gtk_tool_item_get_homogeneous, gxg_gtk_tool_item_get_homogeneous_w, 1, 0, 0, H_gtk_tool_item_get_homogeneous, pl_bu); Xg_define_procedure(gtk_tool_item_set_expand, gxg_gtk_tool_item_set_expand_w, 2, 0, 0, H_gtk_tool_item_set_expand, pl_tub); Xg_define_procedure(gtk_tool_item_get_expand, gxg_gtk_tool_item_get_expand_w, 1, 0, 0, H_gtk_tool_item_get_expand, pl_bu); Xg_define_procedure(gtk_tool_item_set_use_drag_window, gxg_gtk_tool_item_set_use_drag_window_w, 2, 0, 0, H_gtk_tool_item_set_use_drag_window, pl_tub); Xg_define_procedure(gtk_tool_item_get_use_drag_window, gxg_gtk_tool_item_get_use_drag_window_w, 1, 0, 0, H_gtk_tool_item_get_use_drag_window, pl_bu); Xg_define_procedure(gtk_tool_item_set_visible_horizontal, gxg_gtk_tool_item_set_visible_horizontal_w, 2, 0, 0, H_gtk_tool_item_set_visible_horizontal, pl_tub); Xg_define_procedure(gtk_tool_item_get_visible_horizontal, gxg_gtk_tool_item_get_visible_horizontal_w, 1, 0, 0, H_gtk_tool_item_get_visible_horizontal, pl_bu); Xg_define_procedure(gtk_tool_item_set_visible_vertical, gxg_gtk_tool_item_set_visible_vertical_w, 2, 0, 0, H_gtk_tool_item_set_visible_vertical, pl_tub); Xg_define_procedure(gtk_tool_item_get_visible_vertical, gxg_gtk_tool_item_get_visible_vertical_w, 1, 0, 0, H_gtk_tool_item_get_visible_vertical, pl_bu); Xg_define_procedure(gtk_tool_item_get_is_important, gxg_gtk_tool_item_get_is_important_w, 1, 0, 0, H_gtk_tool_item_get_is_important, pl_bu); Xg_define_procedure(gtk_tool_item_set_is_important, gxg_gtk_tool_item_set_is_important_w, 2, 0, 0, H_gtk_tool_item_set_is_important, pl_tub); Xg_define_procedure(gtk_tool_item_get_orientation, gxg_gtk_tool_item_get_orientation_w, 1, 0, 0, H_gtk_tool_item_get_orientation, pl_iu); Xg_define_procedure(gtk_tool_item_get_toolbar_style, gxg_gtk_tool_item_get_toolbar_style_w, 1, 0, 0, H_gtk_tool_item_get_toolbar_style, pl_iu); Xg_define_procedure(gtk_tool_item_get_relief_style, gxg_gtk_tool_item_get_relief_style_w, 1, 0, 0, H_gtk_tool_item_get_relief_style, pl_iu); Xg_define_procedure(gtk_tool_item_retrieve_proxy_menu_item, gxg_gtk_tool_item_retrieve_proxy_menu_item_w, 1, 0, 0, H_gtk_tool_item_retrieve_proxy_menu_item, pl_pu); Xg_define_procedure(gtk_tool_item_get_proxy_menu_item, gxg_gtk_tool_item_get_proxy_menu_item_w, 2, 0, 0, H_gtk_tool_item_get_proxy_menu_item, pl_pus); Xg_define_procedure(gtk_tool_item_set_proxy_menu_item, gxg_gtk_tool_item_set_proxy_menu_item_w, 3, 0, 0, H_gtk_tool_item_set_proxy_menu_item, pl_tusu); Xg_define_procedure(gtk_list_store_remove, gxg_gtk_list_store_remove_w, 2, 0, 0, H_gtk_list_store_remove, pl_bu); Xg_define_procedure(gdk_display_set_double_click_distance, gxg_gdk_display_set_double_click_distance_w, 2, 0, 0, H_gdk_display_set_double_click_distance, pl_tui); Xg_define_procedure(gdk_display_get_default_group, gxg_gdk_display_get_default_group_w, 1, 0, 0, H_gdk_display_get_default_group, pl_pu); Xg_define_procedure(gdk_window_get_group, gxg_gdk_window_get_group_w, 1, 0, 0, H_gdk_window_get_group, pl_pu); Xg_define_procedure(gtk_cell_layout_reorder, gxg_gtk_cell_layout_reorder_w, 3, 0, 0, H_gtk_cell_layout_reorder, pl_tuui); Xg_define_procedure(gtk_clipboard_request_targets, gxg_gtk_clipboard_request_targets_w, 2, 1, 0, H_gtk_clipboard_request_targets, pl_tut); Xg_define_procedure(gtk_clipboard_wait_for_targets, gxg_gtk_clipboard_wait_for_targets_w, 1, 2, 0, H_gtk_clipboard_wait_for_targets, pl_bu); Xg_define_procedure(gtk_menu_shell_cancel, gxg_gtk_menu_shell_cancel_w, 1, 0, 0, H_gtk_menu_shell_cancel, pl_tu); Xg_define_procedure(gtk_paned_get_child1, gxg_gtk_paned_get_child1_w, 1, 0, 0, H_gtk_paned_get_child1, pl_pu); Xg_define_procedure(gtk_paned_get_child2, gxg_gtk_paned_get_child2_w, 1, 0, 0, H_gtk_paned_get_child2, pl_pu); Xg_define_procedure(gtk_window_set_accept_focus, gxg_gtk_window_set_accept_focus_w, 2, 0, 0, H_gtk_window_set_accept_focus, pl_tub); Xg_define_procedure(gtk_window_get_accept_focus, gxg_gtk_window_get_accept_focus_w, 1, 0, 0, H_gtk_window_get_accept_focus, pl_bu); Xg_define_procedure(g_list_nth_data, gxg_g_list_nth_data_w, 2, 0, 0, H_g_list_nth_data, pl_tui); Xg_define_procedure(gtk_accel_map_get, gxg_gtk_accel_map_get_w, 0, 0, 0, H_gtk_accel_map_get, pl_p); Xg_define_procedure(gtk_combo_box_popup, gxg_gtk_combo_box_popup_w, 1, 0, 0, H_gtk_combo_box_popup, pl_tu); Xg_define_procedure(gtk_combo_box_popdown, gxg_gtk_combo_box_popdown_w, 1, 0, 0, H_gtk_combo_box_popdown, pl_tu); Xg_define_procedure(gtk_radio_menu_item_new_from_widget, gxg_gtk_radio_menu_item_new_from_widget_w, 1, 0, 0, H_gtk_radio_menu_item_new_from_widget, pl_pu); Xg_define_procedure(gtk_radio_menu_item_new_with_mnemonic_from_widget, gxg_gtk_radio_menu_item_new_with_mnemonic_from_widget_w, 2, 0, 0, H_gtk_radio_menu_item_new_with_mnemonic_from_widget, pl_pus); Xg_define_procedure(gtk_radio_menu_item_new_with_label_from_widget, gxg_gtk_radio_menu_item_new_with_label_from_widget_w, 2, 0, 0, H_gtk_radio_menu_item_new_with_label_from_widget, pl_pus); Xg_define_procedure(gtk_scale_get_layout, gxg_gtk_scale_get_layout_w, 1, 0, 0, H_gtk_scale_get_layout, pl_pu); Xg_define_procedure(gtk_scale_get_layout_offsets, gxg_gtk_scale_get_layout_offsets_w, 1, 2, 0, H_gtk_scale_get_layout_offsets, pl_tu); Xg_define_procedure(gtk_drag_source_get_target_list, gxg_gtk_drag_source_get_target_list_w, 1, 0, 0, H_gtk_drag_source_get_target_list, pl_pu); Xg_define_procedure(gtk_drag_source_set_target_list, gxg_gtk_drag_source_set_target_list_w, 2, 0, 0, H_gtk_drag_source_set_target_list, pl_tu); Xg_define_procedure(gtk_entry_set_alignment, gxg_gtk_entry_set_alignment_w, 2, 0, 0, H_gtk_entry_set_alignment, pl_tur); Xg_define_procedure(gtk_entry_get_alignment, gxg_gtk_entry_get_alignment_w, 1, 0, 0, H_gtk_entry_get_alignment, pl_du); Xg_define_procedure(gtk_file_chooser_set_use_preview_label, gxg_gtk_file_chooser_set_use_preview_label_w, 2, 0, 0, H_gtk_file_chooser_set_use_preview_label, pl_tub); Xg_define_procedure(gtk_file_chooser_get_use_preview_label, gxg_gtk_file_chooser_get_use_preview_label_w, 1, 0, 0, H_gtk_file_chooser_get_use_preview_label, pl_bu); Xg_define_procedure(gtk_widget_list_mnemonic_labels, gxg_gtk_widget_list_mnemonic_labels_w, 1, 0, 0, H_gtk_widget_list_mnemonic_labels, pl_pu); Xg_define_procedure(gtk_widget_add_mnemonic_label, gxg_gtk_widget_add_mnemonic_label_w, 2, 0, 0, H_gtk_widget_add_mnemonic_label, pl_tu); Xg_define_procedure(gtk_widget_remove_mnemonic_label, gxg_gtk_widget_remove_mnemonic_label_w, 2, 0, 0, H_gtk_widget_remove_mnemonic_label, pl_tu); Xg_define_procedure(gtk_window_activate_key, gxg_gtk_window_activate_key_w, 2, 0, 0, H_gtk_window_activate_key, pl_bu); Xg_define_procedure(gtk_window_propagate_key_event, gxg_gtk_window_propagate_key_event_w, 2, 0, 0, H_gtk_window_propagate_key_event, pl_bu); Xg_define_procedure(g_quark_from_string, gxg_g_quark_from_string_w, 1, 0, 0, H_g_quark_from_string, pl_is); Xg_define_procedure(g_quark_to_string, gxg_g_quark_to_string_w, 1, 0, 0, H_g_quark_to_string, pl_si); Xg_define_procedure(gtk_cell_view_new, gxg_gtk_cell_view_new_w, 0, 0, 0, H_gtk_cell_view_new, pl_p); Xg_define_procedure(gtk_cell_view_new_with_text, gxg_gtk_cell_view_new_with_text_w, 1, 0, 0, H_gtk_cell_view_new_with_text, pl_ps); Xg_define_procedure(gtk_cell_view_new_with_markup, gxg_gtk_cell_view_new_with_markup_w, 1, 0, 0, H_gtk_cell_view_new_with_markup, pl_ps); Xg_define_procedure(gtk_cell_view_new_with_pixbuf, gxg_gtk_cell_view_new_with_pixbuf_w, 1, 0, 0, H_gtk_cell_view_new_with_pixbuf, pl_pu); Xg_define_procedure(gtk_cell_view_set_model, gxg_gtk_cell_view_set_model_w, 2, 0, 0, H_gtk_cell_view_set_model, pl_tu); Xg_define_procedure(gtk_cell_view_set_displayed_row, gxg_gtk_cell_view_set_displayed_row_w, 2, 0, 0, H_gtk_cell_view_set_displayed_row, pl_tu); Xg_define_procedure(gtk_cell_view_get_displayed_row, gxg_gtk_cell_view_get_displayed_row_w, 1, 0, 0, H_gtk_cell_view_get_displayed_row, pl_pu); Xg_define_procedure(gtk_combo_box_get_wrap_width, gxg_gtk_combo_box_get_wrap_width_w, 1, 0, 0, H_gtk_combo_box_get_wrap_width, pl_iu); Xg_define_procedure(gtk_combo_box_get_row_span_column, gxg_gtk_combo_box_get_row_span_column_w, 1, 0, 0, H_gtk_combo_box_get_row_span_column, pl_iu); Xg_define_procedure(gtk_combo_box_get_column_span_column, gxg_gtk_combo_box_get_column_span_column_w, 1, 0, 0, H_gtk_combo_box_get_column_span_column, pl_iu); Xg_define_procedure(gtk_drag_dest_add_text_targets, gxg_gtk_drag_dest_add_text_targets_w, 1, 0, 0, H_gtk_drag_dest_add_text_targets, pl_tu); Xg_define_procedure(gtk_drag_source_add_text_targets, gxg_gtk_drag_source_add_text_targets_w, 1, 0, 0, H_gtk_drag_source_add_text_targets, pl_tu); Xg_define_procedure(gtk_entry_completion_insert_prefix, gxg_gtk_entry_completion_insert_prefix_w, 1, 0, 0, H_gtk_entry_completion_insert_prefix, pl_tu); Xg_define_procedure(gtk_entry_completion_set_inline_completion, gxg_gtk_entry_completion_set_inline_completion_w, 2, 0, 0, H_gtk_entry_completion_set_inline_completion, pl_tub); Xg_define_procedure(gtk_entry_completion_get_inline_completion, gxg_gtk_entry_completion_get_inline_completion_w, 1, 0, 0, H_gtk_entry_completion_get_inline_completion, pl_bu); Xg_define_procedure(gtk_entry_completion_set_popup_completion, gxg_gtk_entry_completion_set_popup_completion_w, 2, 0, 0, H_gtk_entry_completion_set_popup_completion, pl_tub); Xg_define_procedure(gtk_entry_completion_get_popup_completion, gxg_gtk_entry_completion_get_popup_completion_w, 1, 0, 0, H_gtk_entry_completion_get_popup_completion, pl_bu); Xg_define_procedure(gtk_entry_completion_get_text_column, gxg_gtk_entry_completion_get_text_column_w, 1, 0, 0, H_gtk_entry_completion_get_text_column, pl_iu); Xg_define_procedure(gtk_icon_theme_get_icon_sizes, gxg_gtk_icon_theme_get_icon_sizes_w, 2, 0, 0, H_gtk_icon_theme_get_icon_sizes, pl_pus); Xg_define_procedure(gtk_menu_get_for_attach_widget, gxg_gtk_menu_get_for_attach_widget_w, 1, 0, 0, H_gtk_menu_get_for_attach_widget, pl_pu); Xg_define_procedure(gtk_tree_view_set_fixed_height_mode, gxg_gtk_tree_view_set_fixed_height_mode_w, 2, 0, 0, H_gtk_tree_view_set_fixed_height_mode, pl_tub); Xg_define_procedure(gtk_tree_view_get_fixed_height_mode, gxg_gtk_tree_view_get_fixed_height_mode_w, 1, 0, 0, H_gtk_tree_view_get_fixed_height_mode, pl_bu); Xg_define_procedure(gtk_tree_view_set_hover_selection, gxg_gtk_tree_view_set_hover_selection_w, 2, 0, 0, H_gtk_tree_view_set_hover_selection, pl_tub); Xg_define_procedure(gtk_tree_view_get_hover_selection, gxg_gtk_tree_view_get_hover_selection_w, 1, 0, 0, H_gtk_tree_view_get_hover_selection, pl_bu); Xg_define_procedure(gtk_tree_view_set_row_separator_func, gxg_gtk_tree_view_set_row_separator_func_w, 4, 0, 0, H_gtk_tree_view_set_row_separator_func, pl_tut); Xg_define_procedure(gtk_window_set_focus_on_map, gxg_gtk_window_set_focus_on_map_w, 2, 0, 0, H_gtk_window_set_focus_on_map, pl_tub); Xg_define_procedure(gtk_window_get_focus_on_map, gxg_gtk_window_get_focus_on_map_w, 1, 0, 0, H_gtk_window_get_focus_on_map, pl_bu); Xg_define_procedure(gtk_window_set_icon_name, gxg_gtk_window_set_icon_name_w, 2, 0, 0, H_gtk_window_set_icon_name, pl_tus); Xg_define_procedure(gtk_window_get_icon_name, gxg_gtk_window_get_icon_name_w, 1, 0, 0, H_gtk_window_get_icon_name, pl_su); Xg_define_procedure(gtk_window_set_default_icon_name, gxg_gtk_window_set_default_icon_name_w, 1, 0, 0, H_gtk_window_set_default_icon_name, pl_ts); Xg_define_procedure(gtk_about_dialog_new, gxg_gtk_about_dialog_new_w, 0, 0, 0, H_gtk_about_dialog_new, pl_p); Xg_define_procedure(gtk_about_dialog_get_version, gxg_gtk_about_dialog_get_version_w, 1, 0, 0, H_gtk_about_dialog_get_version, pl_su); Xg_define_procedure(gtk_about_dialog_set_version, gxg_gtk_about_dialog_set_version_w, 2, 0, 0, H_gtk_about_dialog_set_version, pl_tus); Xg_define_procedure(gtk_about_dialog_get_copyright, gxg_gtk_about_dialog_get_copyright_w, 1, 0, 0, H_gtk_about_dialog_get_copyright, pl_su); Xg_define_procedure(gtk_about_dialog_set_copyright, gxg_gtk_about_dialog_set_copyright_w, 2, 0, 0, H_gtk_about_dialog_set_copyright, pl_tus); Xg_define_procedure(gtk_about_dialog_get_comments, gxg_gtk_about_dialog_get_comments_w, 1, 0, 0, H_gtk_about_dialog_get_comments, pl_su); Xg_define_procedure(gtk_about_dialog_set_comments, gxg_gtk_about_dialog_set_comments_w, 2, 0, 0, H_gtk_about_dialog_set_comments, pl_tus); Xg_define_procedure(gtk_about_dialog_get_website, gxg_gtk_about_dialog_get_website_w, 1, 0, 0, H_gtk_about_dialog_get_website, pl_su); Xg_define_procedure(gtk_about_dialog_set_website, gxg_gtk_about_dialog_set_website_w, 2, 0, 0, H_gtk_about_dialog_set_website, pl_tus); Xg_define_procedure(gtk_about_dialog_get_website_label, gxg_gtk_about_dialog_get_website_label_w, 1, 0, 0, H_gtk_about_dialog_get_website_label, pl_su); Xg_define_procedure(gtk_about_dialog_set_website_label, gxg_gtk_about_dialog_set_website_label_w, 2, 0, 0, H_gtk_about_dialog_set_website_label, pl_tus); Xg_define_procedure(gtk_about_dialog_get_authors, gxg_gtk_about_dialog_get_authors_w, 1, 0, 0, H_gtk_about_dialog_get_authors, pl_pu); Xg_define_procedure(gtk_about_dialog_set_authors, gxg_gtk_about_dialog_set_authors_w, 2, 0, 0, H_gtk_about_dialog_set_authors, pl_tu); Xg_define_procedure(gtk_about_dialog_get_documenters, gxg_gtk_about_dialog_get_documenters_w, 1, 0, 0, H_gtk_about_dialog_get_documenters, pl_pu); Xg_define_procedure(gtk_about_dialog_set_documenters, gxg_gtk_about_dialog_set_documenters_w, 2, 0, 0, H_gtk_about_dialog_set_documenters, pl_tu); Xg_define_procedure(gtk_about_dialog_get_artists, gxg_gtk_about_dialog_get_artists_w, 1, 0, 0, H_gtk_about_dialog_get_artists, pl_pu); Xg_define_procedure(gtk_about_dialog_set_artists, gxg_gtk_about_dialog_set_artists_w, 2, 0, 0, H_gtk_about_dialog_set_artists, pl_tu); Xg_define_procedure(gtk_about_dialog_get_translator_credits, gxg_gtk_about_dialog_get_translator_credits_w, 1, 0, 0, H_gtk_about_dialog_get_translator_credits, pl_su); Xg_define_procedure(gtk_about_dialog_set_translator_credits, gxg_gtk_about_dialog_set_translator_credits_w, 2, 0, 0, H_gtk_about_dialog_set_translator_credits, pl_tus); Xg_define_procedure(gtk_about_dialog_get_logo, gxg_gtk_about_dialog_get_logo_w, 1, 0, 0, H_gtk_about_dialog_get_logo, pl_pu); Xg_define_procedure(gtk_about_dialog_set_logo, gxg_gtk_about_dialog_set_logo_w, 2, 0, 0, H_gtk_about_dialog_set_logo, pl_tu); Xg_define_procedure(gtk_about_dialog_get_program_name, gxg_gtk_about_dialog_get_program_name_w, 1, 0, 0, H_gtk_about_dialog_get_program_name, pl_su); Xg_define_procedure(gtk_about_dialog_set_program_name, gxg_gtk_about_dialog_set_program_name_w, 2, 0, 0, H_gtk_about_dialog_set_program_name, pl_tus); Xg_define_procedure(gtk_icon_view_new, gxg_gtk_icon_view_new_w, 0, 0, 0, H_gtk_icon_view_new, pl_p); Xg_define_procedure(gtk_icon_view_new_with_model, gxg_gtk_icon_view_new_with_model_w, 1, 0, 0, H_gtk_icon_view_new_with_model, pl_pu); Xg_define_procedure(gtk_icon_view_set_model, gxg_gtk_icon_view_set_model_w, 2, 0, 0, H_gtk_icon_view_set_model, pl_tu); Xg_define_procedure(gtk_icon_view_get_model, gxg_gtk_icon_view_get_model_w, 1, 0, 0, H_gtk_icon_view_get_model, pl_pu); Xg_define_procedure(gtk_icon_view_set_text_column, gxg_gtk_icon_view_set_text_column_w, 2, 0, 0, H_gtk_icon_view_set_text_column, pl_tui); Xg_define_procedure(gtk_icon_view_get_text_column, gxg_gtk_icon_view_get_text_column_w, 1, 0, 0, H_gtk_icon_view_get_text_column, pl_iu); Xg_define_procedure(gtk_icon_view_set_markup_column, gxg_gtk_icon_view_set_markup_column_w, 2, 0, 0, H_gtk_icon_view_set_markup_column, pl_tui); Xg_define_procedure(gtk_icon_view_get_markup_column, gxg_gtk_icon_view_get_markup_column_w, 1, 0, 0, H_gtk_icon_view_get_markup_column, pl_iu); Xg_define_procedure(gtk_icon_view_set_pixbuf_column, gxg_gtk_icon_view_set_pixbuf_column_w, 2, 0, 0, H_gtk_icon_view_set_pixbuf_column, pl_tui); Xg_define_procedure(gtk_icon_view_get_pixbuf_column, gxg_gtk_icon_view_get_pixbuf_column_w, 1, 0, 0, H_gtk_icon_view_get_pixbuf_column, pl_iu); Xg_define_procedure(gtk_icon_view_get_path_at_pos, gxg_gtk_icon_view_get_path_at_pos_w, 3, 0, 0, H_gtk_icon_view_get_path_at_pos, pl_pui); Xg_define_procedure(gtk_icon_view_selected_foreach, gxg_gtk_icon_view_selected_foreach_w, 2, 1, 0, H_gtk_icon_view_selected_foreach, pl_tut); Xg_define_procedure(gtk_icon_view_set_selection_mode, gxg_gtk_icon_view_set_selection_mode_w, 2, 0, 0, H_gtk_icon_view_set_selection_mode, pl_tui); Xg_define_procedure(gtk_icon_view_get_selection_mode, gxg_gtk_icon_view_get_selection_mode_w, 1, 0, 0, H_gtk_icon_view_get_selection_mode, pl_iu); Xg_define_procedure(gtk_icon_view_select_path, gxg_gtk_icon_view_select_path_w, 2, 0, 0, H_gtk_icon_view_select_path, pl_tu); Xg_define_procedure(gtk_icon_view_unselect_path, gxg_gtk_icon_view_unselect_path_w, 2, 0, 0, H_gtk_icon_view_unselect_path, pl_tu); Xg_define_procedure(gtk_icon_view_path_is_selected, gxg_gtk_icon_view_path_is_selected_w, 2, 0, 0, H_gtk_icon_view_path_is_selected, pl_bu); Xg_define_procedure(gtk_icon_view_get_selected_items, gxg_gtk_icon_view_get_selected_items_w, 1, 0, 0, H_gtk_icon_view_get_selected_items, pl_pu); Xg_define_procedure(gtk_icon_view_select_all, gxg_gtk_icon_view_select_all_w, 1, 0, 0, H_gtk_icon_view_select_all, pl_tu); Xg_define_procedure(gtk_icon_view_unselect_all, gxg_gtk_icon_view_unselect_all_w, 1, 0, 0, H_gtk_icon_view_unselect_all, pl_tu); Xg_define_procedure(gtk_icon_view_item_activated, gxg_gtk_icon_view_item_activated_w, 2, 0, 0, H_gtk_icon_view_item_activated, pl_tu); Xg_define_procedure(gtk_cell_renderer_combo_new, gxg_gtk_cell_renderer_combo_new_w, 0, 0, 0, H_gtk_cell_renderer_combo_new, pl_p); Xg_define_procedure(gtk_cell_renderer_progress_new, gxg_gtk_cell_renderer_progress_new_w, 0, 0, 0, H_gtk_cell_renderer_progress_new, pl_p); Xg_define_procedure(gtk_combo_box_set_row_separator_func, gxg_gtk_combo_box_set_row_separator_func_w, 4, 0, 0, H_gtk_combo_box_set_row_separator_func, pl_tut); Xg_define_procedure(gtk_label_set_ellipsize, gxg_gtk_label_set_ellipsize_w, 2, 0, 0, H_gtk_label_set_ellipsize, pl_tui); Xg_define_procedure(gtk_label_get_ellipsize, gxg_gtk_label_get_ellipsize_w, 1, 0, 0, H_gtk_label_get_ellipsize, pl_iu); Xg_define_procedure(pango_attr_fallback_new, gxg_pango_attr_fallback_new_w, 1, 0, 0, H_pango_attr_fallback_new, pl_pb); Xg_define_procedure(pango_attr_letter_spacing_new, gxg_pango_attr_letter_spacing_new_w, 1, 0, 0, H_pango_attr_letter_spacing_new, pl_pi); Xg_define_procedure(pango_attr_list_filter, gxg_pango_attr_list_filter_w, 3, 0, 0, H_pango_attr_list_filter, pl_put); Xg_define_procedure(pango_attr_iterator_get_attrs, gxg_pango_attr_iterator_get_attrs_w, 1, 0, 0, H_pango_attr_iterator_get_attrs, pl_pu); Xg_define_procedure(pango_font_metrics_get_underline_position, gxg_pango_font_metrics_get_underline_position_w, 1, 0, 0, H_pango_font_metrics_get_underline_position, pl_iu); Xg_define_procedure(pango_font_metrics_get_underline_thickness, gxg_pango_font_metrics_get_underline_thickness_w, 1, 0, 0, H_pango_font_metrics_get_underline_thickness, pl_iu); Xg_define_procedure(pango_font_metrics_get_strikethrough_position, gxg_pango_font_metrics_get_strikethrough_position_w, 1, 0, 0, H_pango_font_metrics_get_strikethrough_position, pl_iu); Xg_define_procedure(pango_font_metrics_get_strikethrough_thickness, gxg_pango_font_metrics_get_strikethrough_thickness_w, 1, 0, 0, H_pango_font_metrics_get_strikethrough_thickness, pl_iu); Xg_define_procedure(pango_font_family_is_monospace, gxg_pango_font_family_is_monospace_w, 1, 0, 0, H_pango_font_family_is_monospace, pl_bu); Xg_define_procedure(pango_font_face_list_sizes, gxg_pango_font_face_list_sizes_w, 1, 2, 0, H_pango_font_face_list_sizes, pl_tu); Xg_define_procedure(pango_layout_set_auto_dir, gxg_pango_layout_set_auto_dir_w, 2, 0, 0, H_pango_layout_set_auto_dir, pl_tub); Xg_define_procedure(pango_layout_get_auto_dir, gxg_pango_layout_get_auto_dir_w, 1, 0, 0, H_pango_layout_get_auto_dir, pl_bu); Xg_define_procedure(pango_script_for_unichar, gxg_pango_script_for_unichar_w, 1, 0, 0, H_pango_script_for_unichar, pl_i); Xg_define_procedure(pango_script_iter_new, gxg_pango_script_iter_new_w, 2, 0, 0, H_pango_script_iter_new, pl_psi); Xg_define_procedure(pango_script_iter_get_range, gxg_pango_script_iter_get_range_w, 1, 3, 0, H_pango_script_iter_get_range, pl_tu); Xg_define_procedure(pango_script_iter_next, gxg_pango_script_iter_next_w, 1, 0, 0, H_pango_script_iter_next, pl_bu); Xg_define_procedure(pango_script_iter_free, gxg_pango_script_iter_free_w, 1, 0, 0, H_pango_script_iter_free, pl_tu); Xg_define_procedure(gtk_file_chooser_button_new_with_dialog, gxg_gtk_file_chooser_button_new_with_dialog_w, 1, 0, 0, H_gtk_file_chooser_button_new_with_dialog, pl_pu); Xg_define_procedure(gtk_file_chooser_button_get_title, gxg_gtk_file_chooser_button_get_title_w, 1, 0, 0, H_gtk_file_chooser_button_get_title, pl_su); Xg_define_procedure(gtk_file_chooser_button_set_title, gxg_gtk_file_chooser_button_set_title_w, 2, 0, 0, H_gtk_file_chooser_button_set_title, pl_tus); Xg_define_procedure(gdk_drag_drop_succeeded, gxg_gdk_drag_drop_succeeded_w, 1, 0, 0, H_gdk_drag_drop_succeeded, pl_bu); Xg_define_procedure(gtk_entry_layout_index_to_text_index, gxg_gtk_entry_layout_index_to_text_index_w, 2, 0, 0, H_gtk_entry_layout_index_to_text_index, pl_iui); Xg_define_procedure(gtk_entry_text_index_to_layout_index, gxg_gtk_entry_text_index_to_layout_index_w, 2, 0, 0, H_gtk_entry_text_index_to_layout_index, pl_iui); Xg_define_procedure(gtk_file_chooser_set_show_hidden, gxg_gtk_file_chooser_set_show_hidden_w, 2, 0, 0, H_gtk_file_chooser_set_show_hidden, pl_tub); Xg_define_procedure(gtk_file_chooser_get_show_hidden, gxg_gtk_file_chooser_get_show_hidden_w, 1, 0, 0, H_gtk_file_chooser_get_show_hidden, pl_bu); Xg_define_procedure(gtk_tree_view_set_hover_expand, gxg_gtk_tree_view_set_hover_expand_w, 2, 0, 0, H_gtk_tree_view_set_hover_expand, pl_tub); Xg_define_procedure(gtk_tree_view_get_hover_expand, gxg_gtk_tree_view_get_hover_expand_w, 1, 0, 0, H_gtk_tree_view_get_hover_expand, pl_bu); Xg_define_procedure(gtk_tool_item_rebuild_menu, gxg_gtk_tool_item_rebuild_menu_w, 1, 0, 0, H_gtk_tool_item_rebuild_menu, pl_tu); Xg_define_procedure(gtk_menu_tool_button_new, gxg_gtk_menu_tool_button_new_w, 2, 0, 0, H_gtk_menu_tool_button_new, pl_pus); Xg_define_procedure(gtk_menu_tool_button_set_menu, gxg_gtk_menu_tool_button_set_menu_w, 2, 0, 0, H_gtk_menu_tool_button_set_menu, pl_tu); Xg_define_procedure(gtk_menu_tool_button_get_menu, gxg_gtk_menu_tool_button_get_menu_w, 1, 0, 0, H_gtk_menu_tool_button_get_menu, pl_pu); Xg_define_procedure(gdk_display_supports_clipboard_persistence, gxg_gdk_display_supports_clipboard_persistence_w, 1, 0, 0, H_gdk_display_supports_clipboard_persistence, pl_bu); Xg_define_procedure(gtk_about_dialog_get_logo_icon_name, gxg_gtk_about_dialog_get_logo_icon_name_w, 1, 0, 0, H_gtk_about_dialog_get_logo_icon_name, pl_su); Xg_define_procedure(gtk_about_dialog_set_logo_icon_name, gxg_gtk_about_dialog_set_logo_icon_name_w, 2, 0, 0, H_gtk_about_dialog_set_logo_icon_name, pl_tus); Xg_define_procedure(gtk_accelerator_get_label, gxg_gtk_accelerator_get_label_w, 2, 0, 0, H_gtk_accelerator_get_label, pl_si); Xg_define_procedure(gtk_clipboard_wait_is_target_available, gxg_gtk_clipboard_wait_is_target_available_w, 2, 0, 0, H_gtk_clipboard_wait_is_target_available, pl_but); Xg_define_procedure(gtk_clipboard_set_can_store, gxg_gtk_clipboard_set_can_store_w, 3, 0, 0, H_gtk_clipboard_set_can_store, pl_tuui); Xg_define_procedure(gtk_clipboard_store, gxg_gtk_clipboard_store_w, 1, 0, 0, H_gtk_clipboard_store, pl_tu); Xg_define_procedure(gtk_drag_dest_add_image_targets, gxg_gtk_drag_dest_add_image_targets_w, 1, 0, 0, H_gtk_drag_dest_add_image_targets, pl_tu); Xg_define_procedure(gtk_drag_dest_add_uri_targets, gxg_gtk_drag_dest_add_uri_targets_w, 1, 0, 0, H_gtk_drag_dest_add_uri_targets, pl_tu); Xg_define_procedure(gtk_drag_source_add_image_targets, gxg_gtk_drag_source_add_image_targets_w, 1, 0, 0, H_gtk_drag_source_add_image_targets, pl_tu); Xg_define_procedure(gtk_drag_source_add_uri_targets, gxg_gtk_drag_source_add_uri_targets_w, 1, 0, 0, H_gtk_drag_source_add_uri_targets, pl_tu); Xg_define_procedure(gtk_file_chooser_button_get_width_chars, gxg_gtk_file_chooser_button_get_width_chars_w, 1, 0, 0, H_gtk_file_chooser_button_get_width_chars, pl_iu); Xg_define_procedure(gtk_file_chooser_button_set_width_chars, gxg_gtk_file_chooser_button_set_width_chars_w, 2, 0, 0, H_gtk_file_chooser_button_set_width_chars, pl_tui); Xg_define_procedure(gtk_image_set_pixel_size, gxg_gtk_image_set_pixel_size_w, 2, 0, 0, H_gtk_image_set_pixel_size, pl_tui); Xg_define_procedure(gtk_image_get_pixel_size, gxg_gtk_image_get_pixel_size_w, 1, 0, 0, H_gtk_image_get_pixel_size, pl_iu); Xg_define_procedure(gtk_label_set_width_chars, gxg_gtk_label_set_width_chars_w, 2, 0, 0, H_gtk_label_set_width_chars, pl_tui); Xg_define_procedure(gtk_label_get_width_chars, gxg_gtk_label_get_width_chars_w, 1, 0, 0, H_gtk_label_get_width_chars, pl_iu); Xg_define_procedure(gtk_target_list_add_text_targets, gxg_gtk_target_list_add_text_targets_w, 2, 0, 0, H_gtk_target_list_add_text_targets, pl_tui); Xg_define_procedure(gtk_target_list_add_image_targets, gxg_gtk_target_list_add_image_targets_w, 3, 0, 0, H_gtk_target_list_add_image_targets, pl_tuib); Xg_define_procedure(gtk_target_list_add_uri_targets, gxg_gtk_target_list_add_uri_targets_w, 2, 0, 0, H_gtk_target_list_add_uri_targets, pl_tui); Xg_define_procedure(gtk_selection_data_set_pixbuf, gxg_gtk_selection_data_set_pixbuf_w, 2, 0, 0, H_gtk_selection_data_set_pixbuf, pl_bu); Xg_define_procedure(gtk_selection_data_get_pixbuf, gxg_gtk_selection_data_get_pixbuf_w, 1, 0, 0, H_gtk_selection_data_get_pixbuf, pl_pu); Xg_define_procedure(gtk_selection_data_set_uris, gxg_gtk_selection_data_set_uris_w, 2, 0, 0, H_gtk_selection_data_set_uris, pl_bu); Xg_define_procedure(gtk_selection_data_get_uris, gxg_gtk_selection_data_get_uris_w, 1, 0, 0, H_gtk_selection_data_get_uris, pl_pu); Xg_define_procedure(gtk_text_buffer_backspace, gxg_gtk_text_buffer_backspace_w, 4, 0, 0, H_gtk_text_buffer_backspace, pl_buub); Xg_define_procedure(gtk_clipboard_set_image, gxg_gtk_clipboard_set_image_w, 2, 0, 0, H_gtk_clipboard_set_image, pl_tu); Xg_define_procedure(gtk_clipboard_request_image, gxg_gtk_clipboard_request_image_w, 2, 1, 0, H_gtk_clipboard_request_image, pl_tut); Xg_define_procedure(gtk_clipboard_wait_for_image, gxg_gtk_clipboard_wait_for_image_w, 1, 0, 0, H_gtk_clipboard_wait_for_image, pl_pu); Xg_define_procedure(gtk_clipboard_wait_is_image_available, gxg_gtk_clipboard_wait_is_image_available_w, 1, 0, 0, H_gtk_clipboard_wait_is_image_available, pl_bu); Xg_define_procedure(gtk_file_filter_add_pixbuf_formats, gxg_gtk_file_filter_add_pixbuf_formats_w, 1, 0, 0, H_gtk_file_filter_add_pixbuf_formats, pl_tu); Xg_define_procedure(gtk_label_set_single_line_mode, gxg_gtk_label_set_single_line_mode_w, 2, 0, 0, H_gtk_label_set_single_line_mode, pl_tub); Xg_define_procedure(gtk_label_get_single_line_mode, gxg_gtk_label_get_single_line_mode_w, 1, 0, 0, H_gtk_label_get_single_line_mode, pl_bu); Xg_define_procedure(gtk_progress_bar_set_ellipsize, gxg_gtk_progress_bar_set_ellipsize_w, 2, 0, 0, H_gtk_progress_bar_set_ellipsize, pl_tui); Xg_define_procedure(gtk_progress_bar_get_ellipsize, gxg_gtk_progress_bar_get_ellipsize_w, 1, 0, 0, H_gtk_progress_bar_get_ellipsize, pl_iu); Xg_define_procedure(gtk_selection_data_targets_include_image, gxg_gtk_selection_data_targets_include_image_w, 2, 0, 0, H_gtk_selection_data_targets_include_image, pl_bub); Xg_define_procedure(gtk_button_set_image, gxg_gtk_button_set_image_w, 2, 0, 0, H_gtk_button_set_image, pl_tu); Xg_define_procedure(gtk_button_get_image, gxg_gtk_button_get_image_w, 1, 0, 0, H_gtk_button_get_image, pl_pu); Xg_define_procedure(gtk_label_set_angle, gxg_gtk_label_set_angle_w, 2, 0, 0, H_gtk_label_set_angle, pl_tur); Xg_define_procedure(gtk_label_get_angle, gxg_gtk_label_get_angle_w, 1, 0, 0, H_gtk_label_get_angle, pl_du); Xg_define_procedure(gtk_menu_set_screen, gxg_gtk_menu_set_screen_w, 2, 0, 0, H_gtk_menu_set_screen, pl_tu); Xg_define_procedure(pango_attr_underline_color_new, gxg_pango_attr_underline_color_new_w, 3, 0, 0, H_pango_attr_underline_color_new, pl_pi); Xg_define_procedure(pango_attr_strikethrough_color_new, gxg_pango_attr_strikethrough_color_new_w, 3, 0, 0, H_pango_attr_strikethrough_color_new, pl_pi); Xg_define_procedure(pango_renderer_draw_layout, gxg_pango_renderer_draw_layout_w, 4, 0, 0, H_pango_renderer_draw_layout, pl_tuui); Xg_define_procedure(pango_renderer_draw_layout_line, gxg_pango_renderer_draw_layout_line_w, 4, 0, 0, H_pango_renderer_draw_layout_line, pl_tuui); Xg_define_procedure(pango_renderer_draw_glyphs, gxg_pango_renderer_draw_glyphs_w, 5, 0, 0, H_pango_renderer_draw_glyphs, pl_tuuui); Xg_define_procedure(pango_renderer_draw_rectangle, gxg_pango_renderer_draw_rectangle_w, 6, 0, 0, H_pango_renderer_draw_rectangle, pl_tui); Xg_define_procedure(pango_renderer_draw_error_underline, gxg_pango_renderer_draw_error_underline_w, 5, 0, 0, H_pango_renderer_draw_error_underline, pl_tui); Xg_define_procedure(pango_renderer_draw_trapezoid, gxg_pango_renderer_draw_trapezoid_w, 0, 0, 1, H_pango_renderer_draw_trapezoid, pl_tuir); Xg_define_procedure(pango_renderer_draw_glyph, gxg_pango_renderer_draw_glyph_w, 5, 0, 0, H_pango_renderer_draw_glyph, pl_tuuir); Xg_define_procedure(pango_renderer_activate, gxg_pango_renderer_activate_w, 1, 0, 0, H_pango_renderer_activate, pl_tu); Xg_define_procedure(pango_renderer_deactivate, gxg_pango_renderer_deactivate_w, 1, 0, 0, H_pango_renderer_deactivate, pl_tu); Xg_define_procedure(pango_renderer_part_changed, gxg_pango_renderer_part_changed_w, 2, 0, 0, H_pango_renderer_part_changed, pl_tui); Xg_define_procedure(pango_renderer_set_color, gxg_pango_renderer_set_color_w, 3, 0, 0, H_pango_renderer_set_color, pl_tuiu); Xg_define_procedure(pango_renderer_get_color, gxg_pango_renderer_get_color_w, 2, 0, 0, H_pango_renderer_get_color, pl_pui); Xg_define_procedure(pango_renderer_set_matrix, gxg_pango_renderer_set_matrix_w, 2, 0, 0, H_pango_renderer_set_matrix, pl_tu); Xg_define_procedure(g_log_set_handler, gxg_g_log_set_handler_w, 3, 1, 0, H_g_log_set_handler, pl_isit); Xg_define_procedure(g_log_remove_handler, gxg_g_log_remove_handler_w, 2, 0, 0, H_g_log_remove_handler, pl_tsi); Xg_define_procedure(gtk_cell_renderer_stop_editing, gxg_gtk_cell_renderer_stop_editing_w, 2, 0, 0, H_gtk_cell_renderer_stop_editing, pl_tub); Xg_define_procedure(gtk_file_chooser_button_new, gxg_gtk_file_chooser_button_new_w, 2, 0, 0, H_gtk_file_chooser_button_new, pl_psi); Xg_define_procedure(gtk_icon_view_set_columns, gxg_gtk_icon_view_set_columns_w, 2, 0, 0, H_gtk_icon_view_set_columns, pl_tui); Xg_define_procedure(gtk_icon_view_get_columns, gxg_gtk_icon_view_get_columns_w, 1, 0, 0, H_gtk_icon_view_get_columns, pl_iu); Xg_define_procedure(gtk_icon_view_set_item_width, gxg_gtk_icon_view_set_item_width_w, 2, 0, 0, H_gtk_icon_view_set_item_width, pl_tui); Xg_define_procedure(gtk_icon_view_get_item_width, gxg_gtk_icon_view_get_item_width_w, 1, 0, 0, H_gtk_icon_view_get_item_width, pl_iu); Xg_define_procedure(gtk_icon_view_set_spacing, gxg_gtk_icon_view_set_spacing_w, 2, 0, 0, H_gtk_icon_view_set_spacing, pl_tui); Xg_define_procedure(gtk_icon_view_get_spacing, gxg_gtk_icon_view_get_spacing_w, 1, 0, 0, H_gtk_icon_view_get_spacing, pl_iu); Xg_define_procedure(gtk_icon_view_set_row_spacing, gxg_gtk_icon_view_set_row_spacing_w, 2, 0, 0, H_gtk_icon_view_set_row_spacing, pl_tui); Xg_define_procedure(gtk_icon_view_get_row_spacing, gxg_gtk_icon_view_get_row_spacing_w, 1, 0, 0, H_gtk_icon_view_get_row_spacing, pl_iu); Xg_define_procedure(gtk_icon_view_set_column_spacing, gxg_gtk_icon_view_set_column_spacing_w, 2, 0, 0, H_gtk_icon_view_set_column_spacing, pl_tui); Xg_define_procedure(gtk_icon_view_get_column_spacing, gxg_gtk_icon_view_get_column_spacing_w, 1, 0, 0, H_gtk_icon_view_get_column_spacing, pl_iu); Xg_define_procedure(gtk_icon_view_set_margin, gxg_gtk_icon_view_set_margin_w, 2, 0, 0, H_gtk_icon_view_set_margin, pl_tui); Xg_define_procedure(gtk_icon_view_get_margin, gxg_gtk_icon_view_get_margin_w, 1, 0, 0, H_gtk_icon_view_get_margin, pl_iu); Xg_define_procedure(gtk_label_set_max_width_chars, gxg_gtk_label_set_max_width_chars_w, 2, 0, 0, H_gtk_label_set_max_width_chars, pl_tui); Xg_define_procedure(gtk_label_get_max_width_chars, gxg_gtk_label_get_max_width_chars_w, 1, 0, 0, H_gtk_label_get_max_width_chars, pl_iu); Xg_define_procedure(gtk_list_store_insert_with_values, gxg_gtk_list_store_insert_with_values_w, 3, 0, 0, H_gtk_list_store_insert_with_values, pl_tuui); Xg_define_procedure(gtk_list_store_insert_with_valuesv, gxg_gtk_list_store_insert_with_valuesv_w, 6, 0, 0, H_gtk_list_store_insert_with_valuesv, pl_tuuiuui); Xg_define_procedure(gtk_text_view_get_iter_at_position, gxg_gtk_text_view_get_iter_at_position_w, 4, 1, 0, H_gtk_text_view_get_iter_at_position, pl_tuuui); Xg_define_procedure(pango_attr_size_new_absolute, gxg_pango_attr_size_new_absolute_w, 1, 0, 0, H_pango_attr_size_new_absolute, pl_pi); Xg_define_procedure(pango_font_description_set_absolute_size, gxg_pango_font_description_set_absolute_size_w, 2, 0, 0, H_pango_font_description_set_absolute_size, pl_tur); Xg_define_procedure(pango_layout_get_font_description, gxg_pango_layout_get_font_description_w, 1, 0, 0, H_pango_layout_get_font_description, pl_pu); Xg_define_procedure(gdk_cursor_new_from_name, gxg_gdk_cursor_new_from_name_w, 2, 0, 0, H_gdk_cursor_new_from_name, pl_pus); Xg_define_procedure(gdk_cursor_get_image, gxg_gdk_cursor_get_image_w, 1, 0, 0, H_gdk_cursor_get_image, pl_pu); Xg_define_procedure(gdk_screen_get_rgba_visual, gxg_gdk_screen_get_rgba_visual_w, 1, 0, 0, H_gdk_screen_get_rgba_visual, pl_pu); Xg_define_procedure(gdk_window_set_urgency_hint, gxg_gdk_window_set_urgency_hint_w, 2, 0, 0, H_gdk_window_set_urgency_hint, pl_tub); Xg_define_procedure(gtk_dialog_get_response_for_widget, gxg_gtk_dialog_get_response_for_widget_w, 2, 0, 0, H_gtk_dialog_get_response_for_widget, pl_iu); Xg_define_procedure(gtk_drag_source_set_icon_name, gxg_gtk_drag_source_set_icon_name_w, 2, 0, 0, H_gtk_drag_source_set_icon_name, pl_tus); Xg_define_procedure(gtk_drag_set_icon_name, gxg_gtk_drag_set_icon_name_w, 4, 0, 0, H_gtk_drag_set_icon_name, pl_tusi); Xg_define_procedure(gtk_entry_completion_set_popup_set_width, gxg_gtk_entry_completion_set_popup_set_width_w, 2, 0, 0, H_gtk_entry_completion_set_popup_set_width, pl_tub); Xg_define_procedure(gtk_entry_completion_get_popup_set_width, gxg_gtk_entry_completion_get_popup_set_width_w, 1, 0, 0, H_gtk_entry_completion_get_popup_set_width, pl_bu); Xg_define_procedure(gtk_entry_completion_set_popup_single_match, gxg_gtk_entry_completion_set_popup_single_match_w, 2, 0, 0, H_gtk_entry_completion_set_popup_single_match, pl_tub); Xg_define_procedure(gtk_entry_completion_get_popup_single_match, gxg_gtk_entry_completion_get_popup_single_match_w, 1, 0, 0, H_gtk_entry_completion_get_popup_single_match, pl_bu); Xg_define_procedure(gtk_icon_view_get_item_at_pos, gxg_gtk_icon_view_get_item_at_pos_w, 3, 2, 0, H_gtk_icon_view_get_item_at_pos, pl_buiiu); Xg_define_procedure(gtk_icon_view_get_visible_range, gxg_gtk_icon_view_get_visible_range_w, 1, 2, 0, H_gtk_icon_view_get_visible_range, pl_bu); Xg_define_procedure(gtk_icon_view_set_cursor, gxg_gtk_icon_view_set_cursor_w, 4, 0, 0, H_gtk_icon_view_set_cursor, pl_tuuub); Xg_define_procedure(gtk_icon_view_get_cursor, gxg_gtk_icon_view_get_cursor_w, 1, 2, 0, H_gtk_icon_view_get_cursor, pl_bu); Xg_define_procedure(gtk_icon_view_scroll_to_path, gxg_gtk_icon_view_scroll_to_path_w, 5, 0, 0, H_gtk_icon_view_scroll_to_path, pl_tuubr); Xg_define_procedure(gtk_icon_view_enable_model_drag_source, gxg_gtk_icon_view_enable_model_drag_source_w, 5, 0, 0, H_gtk_icon_view_enable_model_drag_source, pl_tuiui); Xg_define_procedure(gtk_icon_view_enable_model_drag_dest, gxg_gtk_icon_view_enable_model_drag_dest_w, 4, 0, 0, H_gtk_icon_view_enable_model_drag_dest, pl_tuui); Xg_define_procedure(gtk_icon_view_unset_model_drag_source, gxg_gtk_icon_view_unset_model_drag_source_w, 1, 0, 0, H_gtk_icon_view_unset_model_drag_source, pl_tu); Xg_define_procedure(gtk_icon_view_unset_model_drag_dest, gxg_gtk_icon_view_unset_model_drag_dest_w, 1, 0, 0, H_gtk_icon_view_unset_model_drag_dest, pl_tu); Xg_define_procedure(gtk_icon_view_set_reorderable, gxg_gtk_icon_view_set_reorderable_w, 2, 0, 0, H_gtk_icon_view_set_reorderable, pl_tub); Xg_define_procedure(gtk_icon_view_get_reorderable, gxg_gtk_icon_view_get_reorderable_w, 1, 0, 0, H_gtk_icon_view_get_reorderable, pl_bu); Xg_define_procedure(gtk_icon_view_set_drag_dest_item, gxg_gtk_icon_view_set_drag_dest_item_w, 3, 0, 0, H_gtk_icon_view_set_drag_dest_item, pl_tuui); Xg_define_procedure(gtk_icon_view_get_drag_dest_item, gxg_gtk_icon_view_get_drag_dest_item_w, 1, 2, 0, H_gtk_icon_view_get_drag_dest_item, pl_tu); Xg_define_procedure(gtk_icon_view_get_dest_item_at_pos, gxg_gtk_icon_view_get_dest_item_at_pos_w, 3, 2, 0, H_gtk_icon_view_get_dest_item_at_pos, pl_buiiu); Xg_define_procedure(gtk_image_clear, gxg_gtk_image_clear_w, 1, 0, 0, H_gtk_image_clear, pl_tu); Xg_define_procedure(gtk_menu_bar_get_pack_direction, gxg_gtk_menu_bar_get_pack_direction_w, 1, 0, 0, H_gtk_menu_bar_get_pack_direction, pl_iu); Xg_define_procedure(gtk_menu_bar_set_pack_direction, gxg_gtk_menu_bar_set_pack_direction_w, 2, 0, 0, H_gtk_menu_bar_set_pack_direction, pl_tui); Xg_define_procedure(gtk_menu_bar_get_child_pack_direction, gxg_gtk_menu_bar_get_child_pack_direction_w, 1, 0, 0, H_gtk_menu_bar_get_child_pack_direction, pl_iu); Xg_define_procedure(gtk_menu_bar_set_child_pack_direction, gxg_gtk_menu_bar_set_child_pack_direction_w, 2, 0, 0, H_gtk_menu_bar_set_child_pack_direction, pl_tui); Xg_define_procedure(gtk_menu_shell_get_take_focus, gxg_gtk_menu_shell_get_take_focus_w, 1, 0, 0, H_gtk_menu_shell_get_take_focus, pl_bu); Xg_define_procedure(gtk_menu_shell_set_take_focus, gxg_gtk_menu_shell_set_take_focus_w, 2, 0, 0, H_gtk_menu_shell_set_take_focus, pl_tub); Xg_define_procedure(gtk_size_group_set_ignore_hidden, gxg_gtk_size_group_set_ignore_hidden_w, 2, 0, 0, H_gtk_size_group_set_ignore_hidden, pl_tub); Xg_define_procedure(gtk_size_group_get_ignore_hidden, gxg_gtk_size_group_get_ignore_hidden_w, 1, 0, 0, H_gtk_size_group_get_ignore_hidden, pl_bu); Xg_define_procedure(gtk_text_iter_forward_visible_line, gxg_gtk_text_iter_forward_visible_line_w, 1, 0, 0, H_gtk_text_iter_forward_visible_line, pl_bu); Xg_define_procedure(gtk_text_iter_backward_visible_line, gxg_gtk_text_iter_backward_visible_line_w, 1, 0, 0, H_gtk_text_iter_backward_visible_line, pl_bu); Xg_define_procedure(gtk_text_iter_forward_visible_lines, gxg_gtk_text_iter_forward_visible_lines_w, 2, 0, 0, H_gtk_text_iter_forward_visible_lines, pl_bui); Xg_define_procedure(gtk_text_iter_backward_visible_lines, gxg_gtk_text_iter_backward_visible_lines_w, 2, 0, 0, H_gtk_text_iter_backward_visible_lines, pl_bui); Xg_define_procedure(gtk_tool_button_set_icon_name, gxg_gtk_tool_button_set_icon_name_w, 2, 0, 0, H_gtk_tool_button_set_icon_name, pl_tus); Xg_define_procedure(gtk_tool_button_get_icon_name, gxg_gtk_tool_button_get_icon_name_w, 1, 0, 0, H_gtk_tool_button_get_icon_name, pl_su); Xg_define_procedure(gtk_window_set_urgency_hint, gxg_gtk_window_set_urgency_hint_w, 2, 0, 0, H_gtk_window_set_urgency_hint, pl_tub); Xg_define_procedure(gtk_window_get_urgency_hint, gxg_gtk_window_get_urgency_hint_w, 1, 0, 0, H_gtk_window_get_urgency_hint, pl_bu); Xg_define_procedure(gtk_window_present_with_time, gxg_gtk_window_present_with_time_w, 2, 0, 0, H_gtk_window_present_with_time, pl_tui); Xg_define_procedure(gtk_file_chooser_set_do_overwrite_confirmation, gxg_gtk_file_chooser_set_do_overwrite_confirmation_w, 2, 0, 0, H_gtk_file_chooser_set_do_overwrite_confirmation, pl_tub); Xg_define_procedure(gtk_file_chooser_get_do_overwrite_confirmation, gxg_gtk_file_chooser_get_do_overwrite_confirmation_w, 1, 0, 0, H_gtk_file_chooser_get_do_overwrite_confirmation, pl_bu); Xg_define_procedure(gtk_tree_row_reference_get_model, gxg_gtk_tree_row_reference_get_model_w, 1, 0, 0, H_gtk_tree_row_reference_get_model, pl_pu); Xg_define_procedure(gtk_tree_view_column_queue_resize, gxg_gtk_tree_view_column_queue_resize_w, 1, 0, 0, H_gtk_tree_view_column_queue_resize, pl_tu); Xg_define_procedure(gtk_tree_view_get_visible_range, gxg_gtk_tree_view_get_visible_range_w, 1, 2, 0, H_gtk_tree_view_get_visible_range, pl_bu); Xg_define_procedure(gtk_text_attributes_ref, gxg_gtk_text_attributes_ref_w, 1, 0, 0, H_gtk_text_attributes_ref, pl_pu); Xg_define_procedure(pango_attr_list_ref, gxg_pango_attr_list_ref_w, 1, 0, 0, H_pango_attr_list_ref, pl_pu); Xg_define_procedure(pango_layout_line_ref, gxg_pango_layout_line_ref_w, 1, 0, 0, H_pango_layout_line_ref, pl_pu); Xg_define_procedure(pango_layout_index_to_line_x, gxg_pango_layout_index_to_line_x_w, 3, 2, 0, H_pango_layout_index_to_line_x, pl_tuibu); Xg_define_procedure(gtk_target_list_ref, gxg_gtk_target_list_ref_w, 1, 0, 0, H_gtk_target_list_ref, pl_pu); Xg_define_procedure(gdk_display_supports_shapes, gxg_gdk_display_supports_shapes_w, 1, 0, 0, H_gdk_display_supports_shapes, pl_bu); Xg_define_procedure(gdk_display_supports_input_shapes, gxg_gdk_display_supports_input_shapes_w, 1, 0, 0, H_gdk_display_supports_input_shapes, pl_bu); Xg_define_procedure(gdk_screen_is_composited, gxg_gdk_screen_is_composited_w, 1, 0, 0, H_gdk_screen_is_composited, pl_bu); Xg_define_procedure(gdk_screen_set_resolution, gxg_gdk_screen_set_resolution_w, 2, 0, 0, H_gdk_screen_set_resolution, pl_tur); Xg_define_procedure(gdk_screen_get_resolution, gxg_gdk_screen_get_resolution_w, 1, 0, 0, H_gdk_screen_get_resolution, pl_du); Xg_define_procedure(gdk_screen_get_active_window, gxg_gdk_screen_get_active_window_w, 1, 0, 0, H_gdk_screen_get_active_window, pl_pu); Xg_define_procedure(gdk_screen_get_window_stack, gxg_gdk_screen_get_window_stack_w, 1, 0, 0, H_gdk_screen_get_window_stack, pl_pu); Xg_define_procedure(gdk_window_get_type_hint, gxg_gdk_window_get_type_hint_w, 1, 0, 0, H_gdk_window_get_type_hint, pl_iu); Xg_define_procedure(gtk_clipboard_request_rich_text, gxg_gtk_clipboard_request_rich_text_w, 3, 1, 0, H_gtk_clipboard_request_rich_text, pl_tuut); Xg_define_procedure(gtk_clipboard_wait_for_rich_text, gxg_gtk_clipboard_wait_for_rich_text_w, 3, 1, 0, H_gtk_clipboard_wait_for_rich_text, pl_pu); Xg_define_procedure(gtk_clipboard_wait_is_rich_text_available, gxg_gtk_clipboard_wait_is_rich_text_available_w, 2, 0, 0, H_gtk_clipboard_wait_is_rich_text_available, pl_bu); Xg_define_procedure(gtk_drag_dest_set_track_motion, gxg_gtk_drag_dest_set_track_motion_w, 2, 0, 0, H_gtk_drag_dest_set_track_motion, pl_tub); Xg_define_procedure(gtk_drag_dest_get_track_motion, gxg_gtk_drag_dest_get_track_motion_w, 1, 0, 0, H_gtk_drag_dest_get_track_motion, pl_bu); Xg_define_procedure(gtk_notebook_get_tab_reorderable, gxg_gtk_notebook_get_tab_reorderable_w, 2, 0, 0, H_gtk_notebook_get_tab_reorderable, pl_bu); Xg_define_procedure(gtk_notebook_set_tab_reorderable, gxg_gtk_notebook_set_tab_reorderable_w, 3, 0, 0, H_gtk_notebook_set_tab_reorderable, pl_tuub); Xg_define_procedure(gtk_notebook_get_tab_detachable, gxg_gtk_notebook_get_tab_detachable_w, 2, 0, 0, H_gtk_notebook_get_tab_detachable, pl_bu); Xg_define_procedure(gtk_notebook_set_tab_detachable, gxg_gtk_notebook_set_tab_detachable_w, 3, 0, 0, H_gtk_notebook_set_tab_detachable, pl_tuub); Xg_define_procedure(gtk_range_set_lower_stepper_sensitivity, gxg_gtk_range_set_lower_stepper_sensitivity_w, 2, 0, 0, H_gtk_range_set_lower_stepper_sensitivity, pl_tui); Xg_define_procedure(gtk_range_get_lower_stepper_sensitivity, gxg_gtk_range_get_lower_stepper_sensitivity_w, 1, 0, 0, H_gtk_range_get_lower_stepper_sensitivity, pl_iu); Xg_define_procedure(gtk_range_set_upper_stepper_sensitivity, gxg_gtk_range_set_upper_stepper_sensitivity_w, 2, 0, 0, H_gtk_range_set_upper_stepper_sensitivity, pl_tui); Xg_define_procedure(gtk_range_get_upper_stepper_sensitivity, gxg_gtk_range_get_upper_stepper_sensitivity_w, 1, 0, 0, H_gtk_range_get_upper_stepper_sensitivity, pl_iu); Xg_define_procedure(gtk_scrolled_window_unset_placement, gxg_gtk_scrolled_window_unset_placement_w, 1, 0, 0, H_gtk_scrolled_window_unset_placement, pl_tu); Xg_define_procedure(gtk_target_list_add_rich_text_targets, gxg_gtk_target_list_add_rich_text_targets_w, 4, 0, 0, H_gtk_target_list_add_rich_text_targets, pl_tuibu); Xg_define_procedure(gtk_target_table_new_from_list, gxg_gtk_target_table_new_from_list_w, 1, 1, 0, H_gtk_target_table_new_from_list, pl_pu); Xg_define_procedure(gtk_target_table_free, gxg_gtk_target_table_free_w, 2, 0, 0, H_gtk_target_table_free, pl_tui); Xg_define_procedure(gtk_selection_data_targets_include_rich_text, gxg_gtk_selection_data_targets_include_rich_text_w, 2, 0, 0, H_gtk_selection_data_targets_include_rich_text, pl_bu); Xg_define_procedure(gtk_selection_data_targets_include_uri, gxg_gtk_selection_data_targets_include_uri_w, 1, 0, 0, H_gtk_selection_data_targets_include_uri, pl_bu); Xg_define_procedure(gtk_targets_include_text, gxg_gtk_targets_include_text_w, 2, 0, 0, H_gtk_targets_include_text, pl_bui); Xg_define_procedure(gtk_targets_include_rich_text, gxg_gtk_targets_include_rich_text_w, 3, 0, 0, H_gtk_targets_include_rich_text, pl_buiu); Xg_define_procedure(gtk_targets_include_image, gxg_gtk_targets_include_image_w, 3, 0, 0, H_gtk_targets_include_image, pl_buib); Xg_define_procedure(gtk_targets_include_uri, gxg_gtk_targets_include_uri_w, 2, 0, 0, H_gtk_targets_include_uri, pl_bui); Xg_define_procedure(gtk_size_group_get_widgets, gxg_gtk_size_group_get_widgets_w, 1, 0, 0, H_gtk_size_group_get_widgets, pl_pu); Xg_define_procedure(gtk_text_buffer_get_has_selection, gxg_gtk_text_buffer_get_has_selection_w, 1, 0, 0, H_gtk_text_buffer_get_has_selection, pl_bu); Xg_define_procedure(gtk_text_buffer_get_copy_target_list, gxg_gtk_text_buffer_get_copy_target_list_w, 1, 0, 0, H_gtk_text_buffer_get_copy_target_list, pl_pu); Xg_define_procedure(gtk_text_buffer_get_paste_target_list, gxg_gtk_text_buffer_get_paste_target_list_w, 1, 0, 0, H_gtk_text_buffer_get_paste_target_list, pl_pu); Xg_define_procedure(gtk_tree_view_get_headers_clickable, gxg_gtk_tree_view_get_headers_clickable_w, 1, 0, 0, H_gtk_tree_view_get_headers_clickable, pl_bu); Xg_define_procedure(gtk_tree_view_get_search_entry, gxg_gtk_tree_view_get_search_entry_w, 1, 0, 0, H_gtk_tree_view_get_search_entry, pl_pu); Xg_define_procedure(gtk_tree_view_set_search_entry, gxg_gtk_tree_view_set_search_entry_w, 2, 0, 0, H_gtk_tree_view_set_search_entry, pl_tu); Xg_define_procedure(gtk_tree_view_get_search_position_func, gxg_gtk_tree_view_get_search_position_func_w, 1, 0, 0, H_gtk_tree_view_get_search_position_func, pl_tu); Xg_define_procedure(gtk_tree_view_set_search_position_func, gxg_gtk_tree_view_set_search_position_func_w, 3, 1, 0, H_gtk_tree_view_set_search_position_func, pl_tut); Xg_define_procedure(gtk_widget_is_composited, gxg_gtk_widget_is_composited_w, 1, 0, 0, H_gtk_widget_is_composited, pl_bu); Xg_define_procedure(gtk_window_set_deletable, gxg_gtk_window_set_deletable_w, 2, 0, 0, H_gtk_window_set_deletable, pl_tub); Xg_define_procedure(gtk_window_get_deletable, gxg_gtk_window_get_deletable_w, 1, 0, 0, H_gtk_window_get_deletable, pl_bu); Xg_define_procedure(gtk_assistant_new, gxg_gtk_assistant_new_w, 0, 0, 0, H_gtk_assistant_new, pl_p); Xg_define_procedure(gtk_assistant_get_current_page, gxg_gtk_assistant_get_current_page_w, 1, 0, 0, H_gtk_assistant_get_current_page, pl_iu); Xg_define_procedure(gtk_assistant_set_current_page, gxg_gtk_assistant_set_current_page_w, 2, 0, 0, H_gtk_assistant_set_current_page, pl_tui); Xg_define_procedure(gtk_assistant_get_n_pages, gxg_gtk_assistant_get_n_pages_w, 1, 0, 0, H_gtk_assistant_get_n_pages, pl_iu); Xg_define_procedure(gtk_assistant_get_nth_page, gxg_gtk_assistant_get_nth_page_w, 2, 0, 0, H_gtk_assistant_get_nth_page, pl_pui); Xg_define_procedure(gtk_assistant_prepend_page, gxg_gtk_assistant_prepend_page_w, 2, 0, 0, H_gtk_assistant_prepend_page, pl_iu); Xg_define_procedure(gtk_assistant_append_page, gxg_gtk_assistant_append_page_w, 2, 0, 0, H_gtk_assistant_append_page, pl_iu); Xg_define_procedure(gtk_assistant_insert_page, gxg_gtk_assistant_insert_page_w, 3, 0, 0, H_gtk_assistant_insert_page, pl_iuui); Xg_define_procedure(gtk_assistant_set_forward_page_func, gxg_gtk_assistant_set_forward_page_func_w, 3, 1, 0, H_gtk_assistant_set_forward_page_func, pl_tut); Xg_define_procedure(gtk_assistant_set_page_type, gxg_gtk_assistant_set_page_type_w, 3, 0, 0, H_gtk_assistant_set_page_type, pl_tuui); Xg_define_procedure(gtk_assistant_get_page_type, gxg_gtk_assistant_get_page_type_w, 2, 0, 0, H_gtk_assistant_get_page_type, pl_iu); Xg_define_procedure(gtk_assistant_set_page_title, gxg_gtk_assistant_set_page_title_w, 3, 0, 0, H_gtk_assistant_set_page_title, pl_tuus); Xg_define_procedure(gtk_assistant_get_page_title, gxg_gtk_assistant_get_page_title_w, 2, 0, 0, H_gtk_assistant_get_page_title, pl_su); Xg_define_procedure(gtk_assistant_set_page_complete, gxg_gtk_assistant_set_page_complete_w, 3, 0, 0, H_gtk_assistant_set_page_complete, pl_tuub); Xg_define_procedure(gtk_assistant_get_page_complete, gxg_gtk_assistant_get_page_complete_w, 2, 0, 0, H_gtk_assistant_get_page_complete, pl_bu); Xg_define_procedure(gtk_assistant_add_action_widget, gxg_gtk_assistant_add_action_widget_w, 2, 0, 0, H_gtk_assistant_add_action_widget, pl_tu); Xg_define_procedure(gtk_assistant_remove_action_widget, gxg_gtk_assistant_remove_action_widget_w, 2, 0, 0, H_gtk_assistant_remove_action_widget, pl_tu); Xg_define_procedure(gtk_assistant_update_buttons_state, gxg_gtk_assistant_update_buttons_state_w, 1, 0, 0, H_gtk_assistant_update_buttons_state, pl_tu); Xg_define_procedure(gtk_cell_renderer_accel_new, gxg_gtk_cell_renderer_accel_new_w, 0, 0, 0, H_gtk_cell_renderer_accel_new, pl_p); Xg_define_procedure(gtk_cell_renderer_spin_new, gxg_gtk_cell_renderer_spin_new_w, 0, 0, 0, H_gtk_cell_renderer_spin_new, pl_p); Xg_define_procedure(gtk_link_button_new, gxg_gtk_link_button_new_w, 1, 0, 0, H_gtk_link_button_new, pl_ps); Xg_define_procedure(gtk_link_button_new_with_label, gxg_gtk_link_button_new_with_label_w, 2, 0, 0, H_gtk_link_button_new_with_label, pl_ps); Xg_define_procedure(gtk_link_button_get_uri, gxg_gtk_link_button_get_uri_w, 1, 0, 0, H_gtk_link_button_get_uri, pl_su); Xg_define_procedure(gtk_link_button_set_uri, gxg_gtk_link_button_set_uri_w, 2, 0, 0, H_gtk_link_button_set_uri, pl_tus); Xg_define_procedure(gtk_recent_chooser_error_quark, gxg_gtk_recent_chooser_error_quark_w, 0, 0, 0, H_gtk_recent_chooser_error_quark, pl_i); Xg_define_procedure(gtk_recent_chooser_set_show_private, gxg_gtk_recent_chooser_set_show_private_w, 2, 0, 0, H_gtk_recent_chooser_set_show_private, pl_tub); Xg_define_procedure(gtk_recent_chooser_get_show_private, gxg_gtk_recent_chooser_get_show_private_w, 1, 0, 0, H_gtk_recent_chooser_get_show_private, pl_bu); Xg_define_procedure(gtk_recent_chooser_set_show_not_found, gxg_gtk_recent_chooser_set_show_not_found_w, 2, 0, 0, H_gtk_recent_chooser_set_show_not_found, pl_tub); Xg_define_procedure(gtk_recent_chooser_get_show_not_found, gxg_gtk_recent_chooser_get_show_not_found_w, 1, 0, 0, H_gtk_recent_chooser_get_show_not_found, pl_bu); Xg_define_procedure(gtk_recent_chooser_set_select_multiple, gxg_gtk_recent_chooser_set_select_multiple_w, 2, 0, 0, H_gtk_recent_chooser_set_select_multiple, pl_tub); Xg_define_procedure(gtk_recent_chooser_get_select_multiple, gxg_gtk_recent_chooser_get_select_multiple_w, 1, 0, 0, H_gtk_recent_chooser_get_select_multiple, pl_bu); Xg_define_procedure(gtk_recent_chooser_set_limit, gxg_gtk_recent_chooser_set_limit_w, 2, 0, 0, H_gtk_recent_chooser_set_limit, pl_tui); Xg_define_procedure(gtk_recent_chooser_get_limit, gxg_gtk_recent_chooser_get_limit_w, 1, 0, 0, H_gtk_recent_chooser_get_limit, pl_iu); Xg_define_procedure(gtk_recent_chooser_set_local_only, gxg_gtk_recent_chooser_set_local_only_w, 2, 0, 0, H_gtk_recent_chooser_set_local_only, pl_tub); Xg_define_procedure(gtk_recent_chooser_get_local_only, gxg_gtk_recent_chooser_get_local_only_w, 1, 0, 0, H_gtk_recent_chooser_get_local_only, pl_bu); Xg_define_procedure(gtk_recent_chooser_set_show_tips, gxg_gtk_recent_chooser_set_show_tips_w, 2, 0, 0, H_gtk_recent_chooser_set_show_tips, pl_tub); Xg_define_procedure(gtk_recent_chooser_get_show_tips, gxg_gtk_recent_chooser_get_show_tips_w, 1, 0, 0, H_gtk_recent_chooser_get_show_tips, pl_bu); Xg_define_procedure(gtk_recent_chooser_set_show_icons, gxg_gtk_recent_chooser_set_show_icons_w, 2, 0, 0, H_gtk_recent_chooser_set_show_icons, pl_tub); Xg_define_procedure(gtk_recent_chooser_get_show_icons, gxg_gtk_recent_chooser_get_show_icons_w, 1, 0, 0, H_gtk_recent_chooser_get_show_icons, pl_bu); Xg_define_procedure(gtk_recent_chooser_set_sort_type, gxg_gtk_recent_chooser_set_sort_type_w, 2, 0, 0, H_gtk_recent_chooser_set_sort_type, pl_tui); Xg_define_procedure(gtk_recent_chooser_get_sort_type, gxg_gtk_recent_chooser_get_sort_type_w, 1, 0, 0, H_gtk_recent_chooser_get_sort_type, pl_iu); Xg_define_procedure(gtk_recent_chooser_set_sort_func, gxg_gtk_recent_chooser_set_sort_func_w, 3, 1, 0, H_gtk_recent_chooser_set_sort_func, pl_tut); Xg_define_procedure(gtk_recent_chooser_set_current_uri, gxg_gtk_recent_chooser_set_current_uri_w, 2, 1, 0, H_gtk_recent_chooser_set_current_uri, pl_busu); Xg_define_procedure(gtk_recent_chooser_get_current_uri, gxg_gtk_recent_chooser_get_current_uri_w, 1, 0, 0, H_gtk_recent_chooser_get_current_uri, pl_su); Xg_define_procedure(gtk_recent_chooser_get_current_item, gxg_gtk_recent_chooser_get_current_item_w, 1, 0, 0, H_gtk_recent_chooser_get_current_item, pl_pu); Xg_define_procedure(gtk_recent_chooser_select_uri, gxg_gtk_recent_chooser_select_uri_w, 2, 1, 0, H_gtk_recent_chooser_select_uri, pl_busu); Xg_define_procedure(gtk_recent_chooser_unselect_uri, gxg_gtk_recent_chooser_unselect_uri_w, 2, 0, 0, H_gtk_recent_chooser_unselect_uri, pl_tus); Xg_define_procedure(gtk_recent_chooser_select_all, gxg_gtk_recent_chooser_select_all_w, 1, 0, 0, H_gtk_recent_chooser_select_all, pl_tu); Xg_define_procedure(gtk_recent_chooser_unselect_all, gxg_gtk_recent_chooser_unselect_all_w, 1, 0, 0, H_gtk_recent_chooser_unselect_all, pl_tu); Xg_define_procedure(gtk_recent_chooser_get_items, gxg_gtk_recent_chooser_get_items_w, 1, 0, 0, H_gtk_recent_chooser_get_items, pl_pu); Xg_define_procedure(gtk_recent_chooser_get_uris, gxg_gtk_recent_chooser_get_uris_w, 1, 1, 0, H_gtk_recent_chooser_get_uris, pl_pu); Xg_define_procedure(gtk_recent_chooser_add_filter, gxg_gtk_recent_chooser_add_filter_w, 2, 0, 0, H_gtk_recent_chooser_add_filter, pl_tu); Xg_define_procedure(gtk_recent_chooser_remove_filter, gxg_gtk_recent_chooser_remove_filter_w, 2, 0, 0, H_gtk_recent_chooser_remove_filter, pl_tu); Xg_define_procedure(gtk_recent_chooser_list_filters, gxg_gtk_recent_chooser_list_filters_w, 1, 0, 0, H_gtk_recent_chooser_list_filters, pl_pu); Xg_define_procedure(gtk_recent_chooser_set_filter, gxg_gtk_recent_chooser_set_filter_w, 2, 0, 0, H_gtk_recent_chooser_set_filter, pl_tu); Xg_define_procedure(gtk_recent_chooser_get_filter, gxg_gtk_recent_chooser_get_filter_w, 1, 0, 0, H_gtk_recent_chooser_get_filter, pl_pu); Xg_define_procedure(gtk_recent_chooser_menu_new, gxg_gtk_recent_chooser_menu_new_w, 0, 0, 0, H_gtk_recent_chooser_menu_new, pl_p); Xg_define_procedure(gtk_recent_chooser_menu_new_for_manager, gxg_gtk_recent_chooser_menu_new_for_manager_w, 1, 0, 0, H_gtk_recent_chooser_menu_new_for_manager, pl_pu); Xg_define_procedure(gtk_recent_chooser_menu_get_show_numbers, gxg_gtk_recent_chooser_menu_get_show_numbers_w, 1, 0, 0, H_gtk_recent_chooser_menu_get_show_numbers, pl_bu); Xg_define_procedure(gtk_recent_chooser_menu_set_show_numbers, gxg_gtk_recent_chooser_menu_set_show_numbers_w, 2, 0, 0, H_gtk_recent_chooser_menu_set_show_numbers, pl_tub); Xg_define_procedure(gtk_recent_chooser_widget_new, gxg_gtk_recent_chooser_widget_new_w, 0, 0, 0, H_gtk_recent_chooser_widget_new, pl_p); Xg_define_procedure(gtk_recent_chooser_widget_new_for_manager, gxg_gtk_recent_chooser_widget_new_for_manager_w, 1, 0, 0, H_gtk_recent_chooser_widget_new_for_manager, pl_pu); Xg_define_procedure(gtk_recent_filter_new, gxg_gtk_recent_filter_new_w, 0, 0, 0, H_gtk_recent_filter_new, pl_p); Xg_define_procedure(gtk_recent_filter_set_name, gxg_gtk_recent_filter_set_name_w, 2, 0, 0, H_gtk_recent_filter_set_name, pl_tus); Xg_define_procedure(gtk_recent_filter_get_name, gxg_gtk_recent_filter_get_name_w, 1, 0, 0, H_gtk_recent_filter_get_name, pl_su); Xg_define_procedure(gtk_recent_filter_add_mime_type, gxg_gtk_recent_filter_add_mime_type_w, 2, 0, 0, H_gtk_recent_filter_add_mime_type, pl_tus); Xg_define_procedure(gtk_recent_filter_add_pattern, gxg_gtk_recent_filter_add_pattern_w, 2, 0, 0, H_gtk_recent_filter_add_pattern, pl_tus); Xg_define_procedure(gtk_recent_filter_add_pixbuf_formats, gxg_gtk_recent_filter_add_pixbuf_formats_w, 1, 0, 0, H_gtk_recent_filter_add_pixbuf_formats, pl_tu); Xg_define_procedure(gtk_recent_filter_add_application, gxg_gtk_recent_filter_add_application_w, 2, 0, 0, H_gtk_recent_filter_add_application, pl_tus); Xg_define_procedure(gtk_recent_filter_add_group, gxg_gtk_recent_filter_add_group_w, 2, 0, 0, H_gtk_recent_filter_add_group, pl_tus); Xg_define_procedure(gtk_recent_filter_add_age, gxg_gtk_recent_filter_add_age_w, 2, 0, 0, H_gtk_recent_filter_add_age, pl_tui); Xg_define_procedure(gtk_recent_manager_error_quark, gxg_gtk_recent_manager_error_quark_w, 0, 0, 0, H_gtk_recent_manager_error_quark, pl_i); Xg_define_procedure(gtk_recent_manager_new, gxg_gtk_recent_manager_new_w, 0, 0, 0, H_gtk_recent_manager_new, pl_p); Xg_define_procedure(gtk_recent_manager_get_default, gxg_gtk_recent_manager_get_default_w, 0, 0, 0, H_gtk_recent_manager_get_default, pl_p); Xg_define_procedure(gtk_recent_manager_remove_item, gxg_gtk_recent_manager_remove_item_w, 2, 1, 0, H_gtk_recent_manager_remove_item, pl_busu); Xg_define_procedure(gtk_recent_manager_lookup_item, gxg_gtk_recent_manager_lookup_item_w, 2, 1, 0, H_gtk_recent_manager_lookup_item, pl_pusu); Xg_define_procedure(gtk_recent_manager_has_item, gxg_gtk_recent_manager_has_item_w, 2, 0, 0, H_gtk_recent_manager_has_item, pl_bus); Xg_define_procedure(gtk_recent_manager_move_item, gxg_gtk_recent_manager_move_item_w, 3, 1, 0, H_gtk_recent_manager_move_item, pl_bussu); Xg_define_procedure(gtk_recent_manager_get_items, gxg_gtk_recent_manager_get_items_w, 1, 0, 0, H_gtk_recent_manager_get_items, pl_pu); Xg_define_procedure(gtk_recent_manager_purge_items, gxg_gtk_recent_manager_purge_items_w, 1, 1, 0, H_gtk_recent_manager_purge_items, pl_iu); Xg_define_procedure(gtk_recent_info_ref, gxg_gtk_recent_info_ref_w, 1, 0, 0, H_gtk_recent_info_ref, pl_pu); Xg_define_procedure(gtk_recent_info_unref, gxg_gtk_recent_info_unref_w, 1, 0, 0, H_gtk_recent_info_unref, pl_tu); Xg_define_procedure(gtk_recent_info_get_uri, gxg_gtk_recent_info_get_uri_w, 1, 0, 0, H_gtk_recent_info_get_uri, pl_su); Xg_define_procedure(gtk_recent_info_get_display_name, gxg_gtk_recent_info_get_display_name_w, 1, 0, 0, H_gtk_recent_info_get_display_name, pl_su); Xg_define_procedure(gtk_recent_info_get_description, gxg_gtk_recent_info_get_description_w, 1, 0, 0, H_gtk_recent_info_get_description, pl_su); Xg_define_procedure(gtk_recent_info_get_mime_type, gxg_gtk_recent_info_get_mime_type_w, 1, 0, 0, H_gtk_recent_info_get_mime_type, pl_su); Xg_define_procedure(gtk_recent_info_get_added, gxg_gtk_recent_info_get_added_w, 1, 0, 0, H_gtk_recent_info_get_added, pl_tu); Xg_define_procedure(gtk_recent_info_get_modified, gxg_gtk_recent_info_get_modified_w, 1, 0, 0, H_gtk_recent_info_get_modified, pl_tu); Xg_define_procedure(gtk_recent_info_get_visited, gxg_gtk_recent_info_get_visited_w, 1, 0, 0, H_gtk_recent_info_get_visited, pl_tu); Xg_define_procedure(gtk_recent_info_get_private_hint, gxg_gtk_recent_info_get_private_hint_w, 1, 0, 0, H_gtk_recent_info_get_private_hint, pl_bu); Xg_define_procedure(gtk_recent_info_get_applications, gxg_gtk_recent_info_get_applications_w, 1, 1, 0, H_gtk_recent_info_get_applications, pl_pu); Xg_define_procedure(gtk_recent_info_last_application, gxg_gtk_recent_info_last_application_w, 1, 0, 0, H_gtk_recent_info_last_application, pl_su); Xg_define_procedure(gtk_recent_info_has_application, gxg_gtk_recent_info_has_application_w, 2, 0, 0, H_gtk_recent_info_has_application, pl_bus); Xg_define_procedure(gtk_recent_info_get_groups, gxg_gtk_recent_info_get_groups_w, 1, 1, 0, H_gtk_recent_info_get_groups, pl_pu); Xg_define_procedure(gtk_recent_info_has_group, gxg_gtk_recent_info_has_group_w, 2, 0, 0, H_gtk_recent_info_has_group, pl_bus); Xg_define_procedure(gtk_recent_info_get_icon, gxg_gtk_recent_info_get_icon_w, 2, 0, 0, H_gtk_recent_info_get_icon, pl_pui); Xg_define_procedure(gtk_recent_info_get_short_name, gxg_gtk_recent_info_get_short_name_w, 1, 0, 0, H_gtk_recent_info_get_short_name, pl_su); Xg_define_procedure(gtk_recent_info_get_uri_display, gxg_gtk_recent_info_get_uri_display_w, 1, 0, 0, H_gtk_recent_info_get_uri_display, pl_su); Xg_define_procedure(gtk_recent_info_get_age, gxg_gtk_recent_info_get_age_w, 1, 0, 0, H_gtk_recent_info_get_age, pl_iu); Xg_define_procedure(gtk_recent_info_is_local, gxg_gtk_recent_info_is_local_w, 1, 0, 0, H_gtk_recent_info_is_local, pl_bu); Xg_define_procedure(gtk_recent_info_exists, gxg_gtk_recent_info_exists_w, 1, 0, 0, H_gtk_recent_info_exists, pl_bu); Xg_define_procedure(gtk_recent_info_match, gxg_gtk_recent_info_match_w, 2, 0, 0, H_gtk_recent_info_match, pl_bu); Xg_define_procedure(gtk_text_buffer_register_serialize_format, gxg_gtk_text_buffer_register_serialize_format_w, 5, 0, 0, H_gtk_text_buffer_register_serialize_format, pl_tust); Xg_define_procedure(gtk_text_buffer_register_serialize_tagset, gxg_gtk_text_buffer_register_serialize_tagset_w, 2, 0, 0, H_gtk_text_buffer_register_serialize_tagset, pl_tus); Xg_define_procedure(gtk_text_buffer_register_deserialize_format, gxg_gtk_text_buffer_register_deserialize_format_w, 5, 0, 0, H_gtk_text_buffer_register_deserialize_format, pl_tust); Xg_define_procedure(gtk_text_buffer_register_deserialize_tagset, gxg_gtk_text_buffer_register_deserialize_tagset_w, 2, 0, 0, H_gtk_text_buffer_register_deserialize_tagset, pl_tus); Xg_define_procedure(gtk_text_buffer_unregister_serialize_format, gxg_gtk_text_buffer_unregister_serialize_format_w, 2, 0, 0, H_gtk_text_buffer_unregister_serialize_format, pl_tut); Xg_define_procedure(gtk_text_buffer_unregister_deserialize_format, gxg_gtk_text_buffer_unregister_deserialize_format_w, 2, 0, 0, H_gtk_text_buffer_unregister_deserialize_format, pl_tut); Xg_define_procedure(gtk_text_buffer_deserialize_set_can_create_tags, gxg_gtk_text_buffer_deserialize_set_can_create_tags_w, 3, 0, 0, H_gtk_text_buffer_deserialize_set_can_create_tags, pl_tutb); Xg_define_procedure(gtk_text_buffer_deserialize_get_can_create_tags, gxg_gtk_text_buffer_deserialize_get_can_create_tags_w, 2, 0, 0, H_gtk_text_buffer_deserialize_get_can_create_tags, pl_but); Xg_define_procedure(gtk_text_buffer_get_serialize_formats, gxg_gtk_text_buffer_get_serialize_formats_w, 1, 1, 0, H_gtk_text_buffer_get_serialize_formats, pl_pu); Xg_define_procedure(gtk_text_buffer_get_deserialize_formats, gxg_gtk_text_buffer_get_deserialize_formats_w, 1, 1, 0, H_gtk_text_buffer_get_deserialize_formats, pl_pu); Xg_define_procedure(gtk_text_buffer_serialize, gxg_gtk_text_buffer_serialize_w, 5, 1, 0, H_gtk_text_buffer_serialize, pl_puutu); Xg_define_procedure(gtk_text_buffer_deserialize, gxg_gtk_text_buffer_deserialize_w, 6, 1, 0, H_gtk_text_buffer_deserialize, pl_buutuuiu); Xg_define_procedure(gtk_recent_manager_add_item, gxg_gtk_recent_manager_add_item_w, 2, 0, 0, H_gtk_recent_manager_add_item, pl_bus); Xg_define_procedure(gtk_recent_manager_add_full, gxg_gtk_recent_manager_add_full_w, 3, 0, 0, H_gtk_recent_manager_add_full, pl_busu); Xg_define_procedure(gtk_tree_model_filter_convert_child_iter_to_iter, gxg_gtk_tree_model_filter_convert_child_iter_to_iter_w, 3, 0, 0, H_gtk_tree_model_filter_convert_child_iter_to_iter, pl_bu); Xg_define_procedure(gtk_tree_view_get_grid_lines, gxg_gtk_tree_view_get_grid_lines_w, 1, 0, 0, H_gtk_tree_view_get_grid_lines, pl_iu); Xg_define_procedure(gtk_tree_view_set_grid_lines, gxg_gtk_tree_view_set_grid_lines_w, 2, 0, 0, H_gtk_tree_view_set_grid_lines, pl_tui); Xg_define_procedure(gtk_tree_view_get_enable_tree_lines, gxg_gtk_tree_view_get_enable_tree_lines_w, 1, 0, 0, H_gtk_tree_view_get_enable_tree_lines, pl_bu); Xg_define_procedure(gtk_tree_view_set_enable_tree_lines, gxg_gtk_tree_view_set_enable_tree_lines_w, 2, 0, 0, H_gtk_tree_view_set_enable_tree_lines, pl_tub); Xg_define_procedure(gtk_label_set_line_wrap_mode, gxg_gtk_label_set_line_wrap_mode_w, 2, 0, 0, H_gtk_label_set_line_wrap_mode, pl_tui); Xg_define_procedure(gtk_label_get_line_wrap_mode, gxg_gtk_label_get_line_wrap_mode_w, 1, 0, 0, H_gtk_label_get_line_wrap_mode, pl_iu); Xg_define_procedure(gtk_print_context_get_cairo_context, gxg_gtk_print_context_get_cairo_context_w, 1, 0, 0, H_gtk_print_context_get_cairo_context, pl_pu); Xg_define_procedure(gtk_print_context_get_page_setup, gxg_gtk_print_context_get_page_setup_w, 1, 0, 0, H_gtk_print_context_get_page_setup, pl_pu); Xg_define_procedure(gtk_print_context_get_width, gxg_gtk_print_context_get_width_w, 1, 0, 0, H_gtk_print_context_get_width, pl_du); Xg_define_procedure(gtk_print_context_get_height, gxg_gtk_print_context_get_height_w, 1, 0, 0, H_gtk_print_context_get_height, pl_du); Xg_define_procedure(gtk_print_context_get_dpi_x, gxg_gtk_print_context_get_dpi_x_w, 1, 0, 0, H_gtk_print_context_get_dpi_x, pl_du); Xg_define_procedure(gtk_print_context_get_dpi_y, gxg_gtk_print_context_get_dpi_y_w, 1, 0, 0, H_gtk_print_context_get_dpi_y, pl_du); Xg_define_procedure(gtk_print_context_create_pango_context, gxg_gtk_print_context_create_pango_context_w, 1, 0, 0, H_gtk_print_context_create_pango_context, pl_pu); Xg_define_procedure(gtk_print_context_create_pango_layout, gxg_gtk_print_context_create_pango_layout_w, 1, 0, 0, H_gtk_print_context_create_pango_layout, pl_pu); Xg_define_procedure(gtk_print_context_set_cairo_context, gxg_gtk_print_context_set_cairo_context_w, 4, 0, 0, H_gtk_print_context_set_cairo_context, pl_tuur); Xg_define_procedure(gtk_print_operation_new, gxg_gtk_print_operation_new_w, 0, 0, 0, H_gtk_print_operation_new, pl_p); Xg_define_procedure(gtk_print_operation_set_default_page_setup, gxg_gtk_print_operation_set_default_page_setup_w, 2, 0, 0, H_gtk_print_operation_set_default_page_setup, pl_tu); Xg_define_procedure(gtk_print_operation_get_default_page_setup, gxg_gtk_print_operation_get_default_page_setup_w, 1, 0, 0, H_gtk_print_operation_get_default_page_setup, pl_pu); Xg_define_procedure(gtk_print_operation_set_print_settings, gxg_gtk_print_operation_set_print_settings_w, 2, 0, 0, H_gtk_print_operation_set_print_settings, pl_tu); Xg_define_procedure(gtk_print_operation_get_print_settings, gxg_gtk_print_operation_get_print_settings_w, 1, 0, 0, H_gtk_print_operation_get_print_settings, pl_pu); Xg_define_procedure(gtk_print_operation_set_job_name, gxg_gtk_print_operation_set_job_name_w, 2, 0, 0, H_gtk_print_operation_set_job_name, pl_tus); Xg_define_procedure(gtk_print_operation_set_n_pages, gxg_gtk_print_operation_set_n_pages_w, 2, 0, 0, H_gtk_print_operation_set_n_pages, pl_tui); Xg_define_procedure(gtk_print_operation_set_current_page, gxg_gtk_print_operation_set_current_page_w, 2, 0, 0, H_gtk_print_operation_set_current_page, pl_tui); Xg_define_procedure(gtk_print_operation_set_use_full_page, gxg_gtk_print_operation_set_use_full_page_w, 2, 0, 0, H_gtk_print_operation_set_use_full_page, pl_tub); Xg_define_procedure(gtk_print_operation_set_unit, gxg_gtk_print_operation_set_unit_w, 2, 0, 0, H_gtk_print_operation_set_unit, pl_tut); Xg_define_procedure(gtk_print_operation_set_export_filename, gxg_gtk_print_operation_set_export_filename_w, 2, 0, 0, H_gtk_print_operation_set_export_filename, pl_tus); Xg_define_procedure(gtk_print_operation_set_track_print_status, gxg_gtk_print_operation_set_track_print_status_w, 2, 0, 0, H_gtk_print_operation_set_track_print_status, pl_tub); Xg_define_procedure(gtk_print_operation_set_show_progress, gxg_gtk_print_operation_set_show_progress_w, 2, 0, 0, H_gtk_print_operation_set_show_progress, pl_tub); Xg_define_procedure(gtk_print_operation_set_allow_async, gxg_gtk_print_operation_set_allow_async_w, 2, 0, 0, H_gtk_print_operation_set_allow_async, pl_tub); Xg_define_procedure(gtk_print_operation_set_custom_tab_label, gxg_gtk_print_operation_set_custom_tab_label_w, 2, 0, 0, H_gtk_print_operation_set_custom_tab_label, pl_tus); Xg_define_procedure(gtk_print_operation_run, gxg_gtk_print_operation_run_w, 3, 1, 0, H_gtk_print_operation_run, pl_iuiu); Xg_define_procedure(gtk_print_operation_get_error, gxg_gtk_print_operation_get_error_w, 1, 1, 0, H_gtk_print_operation_get_error, pl_tu); Xg_define_procedure(gtk_print_operation_get_status, gxg_gtk_print_operation_get_status_w, 1, 0, 0, H_gtk_print_operation_get_status, pl_iu); Xg_define_procedure(gtk_print_operation_get_status_string, gxg_gtk_print_operation_get_status_string_w, 1, 0, 0, H_gtk_print_operation_get_status_string, pl_su); Xg_define_procedure(gtk_print_operation_is_finished, gxg_gtk_print_operation_is_finished_w, 1, 0, 0, H_gtk_print_operation_is_finished, pl_bu); Xg_define_procedure(gtk_print_operation_cancel, gxg_gtk_print_operation_cancel_w, 1, 0, 0, H_gtk_print_operation_cancel, pl_tu); Xg_define_procedure(gtk_print_run_page_setup_dialog, gxg_gtk_print_run_page_setup_dialog_w, 3, 0, 0, H_gtk_print_run_page_setup_dialog, pl_pu); Xg_define_procedure(gtk_print_run_page_setup_dialog_async, gxg_gtk_print_run_page_setup_dialog_async_w, 5, 0, 0, H_gtk_print_run_page_setup_dialog_async, pl_tuuut); Xg_define_procedure(gtk_print_operation_preview_render_page, gxg_gtk_print_operation_preview_render_page_w, 2, 0, 0, H_gtk_print_operation_preview_render_page, pl_tui); Xg_define_procedure(gtk_print_operation_preview_end_preview, gxg_gtk_print_operation_preview_end_preview_w, 1, 0, 0, H_gtk_print_operation_preview_end_preview, pl_tu); Xg_define_procedure(gtk_print_operation_preview_is_selected, gxg_gtk_print_operation_preview_is_selected_w, 2, 0, 0, H_gtk_print_operation_preview_is_selected, pl_bui); Xg_define_procedure(gtk_print_settings_new, gxg_gtk_print_settings_new_w, 0, 0, 0, H_gtk_print_settings_new, pl_p); Xg_define_procedure(gtk_print_settings_copy, gxg_gtk_print_settings_copy_w, 1, 0, 0, H_gtk_print_settings_copy, pl_pu); Xg_define_procedure(gtk_print_settings_has_key, gxg_gtk_print_settings_has_key_w, 2, 0, 0, H_gtk_print_settings_has_key, pl_bus); Xg_define_procedure(gtk_print_settings_get, gxg_gtk_print_settings_get_w, 2, 0, 0, H_gtk_print_settings_get, pl_sus); Xg_define_procedure(gtk_print_settings_set, gxg_gtk_print_settings_set_w, 3, 0, 0, H_gtk_print_settings_set, pl_tus); Xg_define_procedure(gtk_print_settings_unset, gxg_gtk_print_settings_unset_w, 2, 0, 0, H_gtk_print_settings_unset, pl_tus); Xg_define_procedure(gtk_print_settings_foreach, gxg_gtk_print_settings_foreach_w, 3, 0, 0, H_gtk_print_settings_foreach, pl_tut); Xg_define_procedure(gtk_print_settings_get_bool, gxg_gtk_print_settings_get_bool_w, 2, 0, 0, H_gtk_print_settings_get_bool, pl_bus); Xg_define_procedure(gtk_print_settings_set_bool, gxg_gtk_print_settings_set_bool_w, 3, 0, 0, H_gtk_print_settings_set_bool, pl_tusb); Xg_define_procedure(gtk_print_settings_get_double, gxg_gtk_print_settings_get_double_w, 2, 0, 0, H_gtk_print_settings_get_double, pl_dus); Xg_define_procedure(gtk_print_settings_get_double_with_default, gxg_gtk_print_settings_get_double_with_default_w, 3, 0, 0, H_gtk_print_settings_get_double_with_default, pl_dusr); Xg_define_procedure(gtk_print_settings_set_double, gxg_gtk_print_settings_set_double_w, 3, 0, 0, H_gtk_print_settings_set_double, pl_tusr); Xg_define_procedure(gtk_print_settings_get_length, gxg_gtk_print_settings_get_length_w, 3, 0, 0, H_gtk_print_settings_get_length, pl_dust); Xg_define_procedure(gtk_print_settings_set_length, gxg_gtk_print_settings_set_length_w, 4, 0, 0, H_gtk_print_settings_set_length, pl_tusrt); Xg_define_procedure(gtk_print_settings_get_int, gxg_gtk_print_settings_get_int_w, 2, 0, 0, H_gtk_print_settings_get_int, pl_ius); Xg_define_procedure(gtk_print_settings_get_int_with_default, gxg_gtk_print_settings_get_int_with_default_w, 3, 0, 0, H_gtk_print_settings_get_int_with_default, pl_iusi); Xg_define_procedure(gtk_print_settings_set_int, gxg_gtk_print_settings_set_int_w, 3, 0, 0, H_gtk_print_settings_set_int, pl_tusi); Xg_define_procedure(gtk_print_settings_get_printer, gxg_gtk_print_settings_get_printer_w, 1, 0, 0, H_gtk_print_settings_get_printer, pl_su); Xg_define_procedure(gtk_print_settings_set_printer, gxg_gtk_print_settings_set_printer_w, 2, 0, 0, H_gtk_print_settings_set_printer, pl_tus); Xg_define_procedure(gtk_print_settings_get_orientation, gxg_gtk_print_settings_get_orientation_w, 1, 0, 0, H_gtk_print_settings_get_orientation, pl_tu); Xg_define_procedure(gtk_print_settings_set_orientation, gxg_gtk_print_settings_set_orientation_w, 2, 0, 0, H_gtk_print_settings_set_orientation, pl_tut); Xg_define_procedure(gtk_print_settings_get_paper_size, gxg_gtk_print_settings_get_paper_size_w, 1, 0, 0, H_gtk_print_settings_get_paper_size, pl_pu); Xg_define_procedure(gtk_print_settings_set_paper_size, gxg_gtk_print_settings_set_paper_size_w, 2, 0, 0, H_gtk_print_settings_set_paper_size, pl_tu); Xg_define_procedure(gtk_print_settings_get_paper_width, gxg_gtk_print_settings_get_paper_width_w, 2, 0, 0, H_gtk_print_settings_get_paper_width, pl_dut); Xg_define_procedure(gtk_print_settings_set_paper_width, gxg_gtk_print_settings_set_paper_width_w, 3, 0, 0, H_gtk_print_settings_set_paper_width, pl_turt); Xg_define_procedure(gtk_print_settings_get_paper_height, gxg_gtk_print_settings_get_paper_height_w, 2, 0, 0, H_gtk_print_settings_get_paper_height, pl_dut); Xg_define_procedure(gtk_print_settings_set_paper_height, gxg_gtk_print_settings_set_paper_height_w, 3, 0, 0, H_gtk_print_settings_set_paper_height, pl_turt); Xg_define_procedure(gtk_print_settings_get_use_color, gxg_gtk_print_settings_get_use_color_w, 1, 0, 0, H_gtk_print_settings_get_use_color, pl_bu); Xg_define_procedure(gtk_print_settings_set_use_color, gxg_gtk_print_settings_set_use_color_w, 2, 0, 0, H_gtk_print_settings_set_use_color, pl_tub); Xg_define_procedure(gtk_print_settings_get_collate, gxg_gtk_print_settings_get_collate_w, 1, 0, 0, H_gtk_print_settings_get_collate, pl_bu); Xg_define_procedure(gtk_print_settings_set_collate, gxg_gtk_print_settings_set_collate_w, 2, 0, 0, H_gtk_print_settings_set_collate, pl_tub); Xg_define_procedure(gtk_print_settings_get_reverse, gxg_gtk_print_settings_get_reverse_w, 1, 0, 0, H_gtk_print_settings_get_reverse, pl_bu); Xg_define_procedure(gtk_print_settings_set_reverse, gxg_gtk_print_settings_set_reverse_w, 2, 0, 0, H_gtk_print_settings_set_reverse, pl_tub); Xg_define_procedure(gtk_print_settings_get_duplex, gxg_gtk_print_settings_get_duplex_w, 1, 0, 0, H_gtk_print_settings_get_duplex, pl_tu); Xg_define_procedure(gtk_print_settings_set_duplex, gxg_gtk_print_settings_set_duplex_w, 2, 0, 0, H_gtk_print_settings_set_duplex, pl_tut); Xg_define_procedure(gtk_print_settings_get_quality, gxg_gtk_print_settings_get_quality_w, 1, 0, 0, H_gtk_print_settings_get_quality, pl_tu); Xg_define_procedure(gtk_print_settings_set_quality, gxg_gtk_print_settings_set_quality_w, 2, 0, 0, H_gtk_print_settings_set_quality, pl_tut); Xg_define_procedure(gtk_print_settings_get_n_copies, gxg_gtk_print_settings_get_n_copies_w, 1, 0, 0, H_gtk_print_settings_get_n_copies, pl_iu); Xg_define_procedure(gtk_print_settings_set_n_copies, gxg_gtk_print_settings_set_n_copies_w, 2, 0, 0, H_gtk_print_settings_set_n_copies, pl_tui); Xg_define_procedure(gtk_print_settings_get_number_up, gxg_gtk_print_settings_get_number_up_w, 1, 0, 0, H_gtk_print_settings_get_number_up, pl_iu); Xg_define_procedure(gtk_print_settings_set_number_up, gxg_gtk_print_settings_set_number_up_w, 2, 0, 0, H_gtk_print_settings_set_number_up, pl_tui); Xg_define_procedure(gtk_print_settings_get_resolution, gxg_gtk_print_settings_get_resolution_w, 1, 0, 0, H_gtk_print_settings_get_resolution, pl_iu); Xg_define_procedure(gtk_print_settings_set_resolution, gxg_gtk_print_settings_set_resolution_w, 2, 0, 0, H_gtk_print_settings_set_resolution, pl_tui); Xg_define_procedure(gtk_print_settings_get_scale, gxg_gtk_print_settings_get_scale_w, 1, 0, 0, H_gtk_print_settings_get_scale, pl_du); Xg_define_procedure(gtk_print_settings_set_scale, gxg_gtk_print_settings_set_scale_w, 2, 0, 0, H_gtk_print_settings_set_scale, pl_tur); Xg_define_procedure(gtk_print_settings_get_print_pages, gxg_gtk_print_settings_get_print_pages_w, 1, 0, 0, H_gtk_print_settings_get_print_pages, pl_tu); Xg_define_procedure(gtk_print_settings_set_print_pages, gxg_gtk_print_settings_set_print_pages_w, 2, 0, 0, H_gtk_print_settings_set_print_pages, pl_tut); Xg_define_procedure(gtk_print_settings_get_page_ranges, gxg_gtk_print_settings_get_page_ranges_w, 2, 0, 0, H_gtk_print_settings_get_page_ranges, pl_pu); Xg_define_procedure(gtk_print_settings_set_page_ranges, gxg_gtk_print_settings_set_page_ranges_w, 3, 0, 0, H_gtk_print_settings_set_page_ranges, pl_tuui); Xg_define_procedure(gtk_print_settings_get_page_set, gxg_gtk_print_settings_get_page_set_w, 1, 0, 0, H_gtk_print_settings_get_page_set, pl_tu); Xg_define_procedure(gtk_print_settings_set_page_set, gxg_gtk_print_settings_set_page_set_w, 2, 0, 0, H_gtk_print_settings_set_page_set, pl_tut); Xg_define_procedure(gtk_print_settings_get_default_source, gxg_gtk_print_settings_get_default_source_w, 1, 0, 0, H_gtk_print_settings_get_default_source, pl_su); Xg_define_procedure(gtk_print_settings_set_default_source, gxg_gtk_print_settings_set_default_source_w, 2, 0, 0, H_gtk_print_settings_set_default_source, pl_tus); Xg_define_procedure(gtk_print_settings_get_media_type, gxg_gtk_print_settings_get_media_type_w, 1, 0, 0, H_gtk_print_settings_get_media_type, pl_su); Xg_define_procedure(gtk_print_settings_set_media_type, gxg_gtk_print_settings_set_media_type_w, 2, 0, 0, H_gtk_print_settings_set_media_type, pl_tus); Xg_define_procedure(gtk_print_settings_get_dither, gxg_gtk_print_settings_get_dither_w, 1, 0, 0, H_gtk_print_settings_get_dither, pl_su); Xg_define_procedure(gtk_print_settings_set_dither, gxg_gtk_print_settings_set_dither_w, 2, 0, 0, H_gtk_print_settings_set_dither, pl_tus); Xg_define_procedure(gtk_print_settings_get_finishings, gxg_gtk_print_settings_get_finishings_w, 1, 0, 0, H_gtk_print_settings_get_finishings, pl_su); Xg_define_procedure(gtk_print_settings_set_finishings, gxg_gtk_print_settings_set_finishings_w, 2, 0, 0, H_gtk_print_settings_set_finishings, pl_tus); Xg_define_procedure(gtk_print_settings_get_output_bin, gxg_gtk_print_settings_get_output_bin_w, 1, 0, 0, H_gtk_print_settings_get_output_bin, pl_su); Xg_define_procedure(gtk_print_settings_set_output_bin, gxg_gtk_print_settings_set_output_bin_w, 2, 0, 0, H_gtk_print_settings_set_output_bin, pl_tus); Xg_define_procedure(gtk_settings_get_for_screen, gxg_gtk_settings_get_for_screen_w, 1, 0, 0, H_gtk_settings_get_for_screen, pl_pu); Xg_define_procedure(pango_cairo_create_layout, gxg_pango_cairo_create_layout_w, 1, 0, 0, H_pango_cairo_create_layout, pl_pu); Xg_define_procedure(pango_cairo_update_layout, gxg_pango_cairo_update_layout_w, 2, 0, 0, H_pango_cairo_update_layout, pl_tu); Xg_define_procedure(pango_cairo_update_context, gxg_pango_cairo_update_context_w, 2, 0, 0, H_pango_cairo_update_context, pl_tu); Xg_define_procedure(pango_cairo_context_set_font_options, gxg_pango_cairo_context_set_font_options_w, 2, 0, 0, H_pango_cairo_context_set_font_options, pl_tu); Xg_define_procedure(pango_cairo_context_get_font_options, gxg_pango_cairo_context_get_font_options_w, 1, 0, 0, H_pango_cairo_context_get_font_options, pl_pu); Xg_define_procedure(pango_cairo_context_set_resolution, gxg_pango_cairo_context_set_resolution_w, 2, 0, 0, H_pango_cairo_context_set_resolution, pl_tur); Xg_define_procedure(pango_cairo_context_get_resolution, gxg_pango_cairo_context_get_resolution_w, 1, 0, 0, H_pango_cairo_context_get_resolution, pl_du); Xg_define_procedure(pango_cairo_show_glyph_string, gxg_pango_cairo_show_glyph_string_w, 3, 0, 0, H_pango_cairo_show_glyph_string, pl_tu); Xg_define_procedure(pango_cairo_show_layout_line, gxg_pango_cairo_show_layout_line_w, 2, 0, 0, H_pango_cairo_show_layout_line, pl_tu); Xg_define_procedure(pango_cairo_show_layout, gxg_pango_cairo_show_layout_w, 2, 0, 0, H_pango_cairo_show_layout, pl_tu); Xg_define_procedure(pango_cairo_show_error_underline, gxg_pango_cairo_show_error_underline_w, 5, 0, 0, H_pango_cairo_show_error_underline, pl_tur); Xg_define_procedure(pango_cairo_glyph_string_path, gxg_pango_cairo_glyph_string_path_w, 3, 0, 0, H_pango_cairo_glyph_string_path, pl_tu); Xg_define_procedure(pango_cairo_layout_line_path, gxg_pango_cairo_layout_line_path_w, 2, 0, 0, H_pango_cairo_layout_line_path, pl_tu); Xg_define_procedure(pango_cairo_layout_path, gxg_pango_cairo_layout_path_w, 2, 0, 0, H_pango_cairo_layout_path, pl_tu); Xg_define_procedure(pango_cairo_error_underline_path, gxg_pango_cairo_error_underline_path_w, 5, 0, 0, H_pango_cairo_error_underline_path, pl_tur); Xg_define_procedure(gdk_cairo_set_source_pixbuf, gxg_gdk_cairo_set_source_pixbuf_w, 4, 0, 0, H_gdk_cairo_set_source_pixbuf, pl_tuur); Xg_define_procedure(gdk_cairo_rectangle, gxg_gdk_cairo_rectangle_w, 2, 0, 0, H_gdk_cairo_rectangle, pl_tu); Xg_define_procedure(gdk_event_request_motions, gxg_gdk_event_request_motions_w, 1, 0, 0, H_gdk_event_request_motions, pl_tu); Xg_define_procedure(gdk_notify_startup_complete_with_id, gxg_gdk_notify_startup_complete_with_id_w, 1, 0, 0, H_gdk_notify_startup_complete_with_id, pl_ts); Xg_define_procedure(gdk_threads_add_idle_full, gxg_gdk_threads_add_idle_full_w, 4, 0, 0, H_gdk_threads_add_idle_full, pl_iit); Xg_define_procedure(gdk_threads_add_idle, gxg_gdk_threads_add_idle_w, 1, 1, 0, H_gdk_threads_add_idle, pl_it); Xg_define_procedure(gdk_threads_add_timeout_full, gxg_gdk_threads_add_timeout_full_w, 5, 0, 0, H_gdk_threads_add_timeout_full, pl_iiit); Xg_define_procedure(gdk_threads_add_timeout, gxg_gdk_threads_add_timeout_w, 2, 1, 0, H_gdk_threads_add_timeout, pl_iit); Xg_define_procedure(gdk_window_set_startup_id, gxg_gdk_window_set_startup_id_w, 2, 0, 0, H_gdk_window_set_startup_id, pl_tus); Xg_define_procedure(gdk_window_beep, gxg_gdk_window_beep_w, 1, 0, 0, H_gdk_window_beep, pl_tu); Xg_define_procedure(gdk_window_set_opacity, gxg_gdk_window_set_opacity_w, 2, 0, 0, H_gdk_window_set_opacity, pl_tur); Xg_define_procedure(gtk_binding_entry_skip, gxg_gtk_binding_entry_skip_w, 3, 0, 0, H_gtk_binding_entry_skip, pl_tui); Xg_define_procedure(gtk_cell_layout_get_cells, gxg_gtk_cell_layout_get_cells_w, 1, 0, 0, H_gtk_cell_layout_get_cells, pl_pu); Xg_define_procedure(gtk_entry_completion_set_inline_selection, gxg_gtk_entry_completion_set_inline_selection_w, 2, 0, 0, H_gtk_entry_completion_set_inline_selection, pl_tub); Xg_define_procedure(gtk_entry_completion_get_inline_selection, gxg_gtk_entry_completion_get_inline_selection_w, 1, 0, 0, H_gtk_entry_completion_get_inline_selection, pl_bu); Xg_define_procedure(gtk_entry_completion_get_completion_prefix, gxg_gtk_entry_completion_get_completion_prefix_w, 1, 0, 0, H_gtk_entry_completion_get_completion_prefix, pl_su); Xg_define_procedure(gtk_entry_set_cursor_hadjustment, gxg_gtk_entry_set_cursor_hadjustment_w, 2, 0, 0, H_gtk_entry_set_cursor_hadjustment, pl_tu); Xg_define_procedure(gtk_entry_get_cursor_hadjustment, gxg_gtk_entry_get_cursor_hadjustment_w, 1, 0, 0, H_gtk_entry_get_cursor_hadjustment, pl_pu); Xg_define_procedure(gtk_icon_theme_list_contexts, gxg_gtk_icon_theme_list_contexts_w, 1, 0, 0, H_gtk_icon_theme_list_contexts, pl_pu); Xg_define_procedure(gtk_print_settings_new_from_file, gxg_gtk_print_settings_new_from_file_w, 1, 1, 0, H_gtk_print_settings_new_from_file, pl_psu); Xg_define_procedure(gtk_print_settings_to_file, gxg_gtk_print_settings_to_file_w, 2, 1, 0, H_gtk_print_settings_to_file, pl_busu); Xg_define_procedure(gtk_range_set_show_fill_level, gxg_gtk_range_set_show_fill_level_w, 2, 0, 0, H_gtk_range_set_show_fill_level, pl_tub); Xg_define_procedure(gtk_range_get_show_fill_level, gxg_gtk_range_get_show_fill_level_w, 1, 0, 0, H_gtk_range_get_show_fill_level, pl_bu); Xg_define_procedure(gtk_range_set_restrict_to_fill_level, gxg_gtk_range_set_restrict_to_fill_level_w, 2, 0, 0, H_gtk_range_set_restrict_to_fill_level, pl_tub); Xg_define_procedure(gtk_range_get_restrict_to_fill_level, gxg_gtk_range_get_restrict_to_fill_level_w, 1, 0, 0, H_gtk_range_get_restrict_to_fill_level, pl_bu); Xg_define_procedure(gtk_range_set_fill_level, gxg_gtk_range_set_fill_level_w, 2, 0, 0, H_gtk_range_set_fill_level, pl_tur); Xg_define_procedure(gtk_range_get_fill_level, gxg_gtk_range_get_fill_level_w, 1, 0, 0, H_gtk_range_get_fill_level, pl_du); Xg_define_procedure(gtk_tree_view_set_show_expanders, gxg_gtk_tree_view_set_show_expanders_w, 2, 0, 0, H_gtk_tree_view_set_show_expanders, pl_tub); Xg_define_procedure(gtk_tree_view_get_show_expanders, gxg_gtk_tree_view_get_show_expanders_w, 1, 0, 0, H_gtk_tree_view_get_show_expanders, pl_bu); Xg_define_procedure(gtk_tree_view_set_level_indentation, gxg_gtk_tree_view_set_level_indentation_w, 2, 0, 0, H_gtk_tree_view_set_level_indentation, pl_tui); Xg_define_procedure(gtk_tree_view_get_level_indentation, gxg_gtk_tree_view_get_level_indentation_w, 1, 0, 0, H_gtk_tree_view_get_level_indentation, pl_iu); Xg_define_procedure(gtk_widget_keynav_failed, gxg_gtk_widget_keynav_failed_w, 2, 0, 0, H_gtk_widget_keynav_failed, pl_bui); Xg_define_procedure(gtk_widget_error_bell, gxg_gtk_widget_error_bell_w, 1, 0, 0, H_gtk_widget_error_bell, pl_tu); Xg_define_procedure(gtk_widget_set_tooltip_window, gxg_gtk_widget_set_tooltip_window_w, 2, 0, 0, H_gtk_widget_set_tooltip_window, pl_tu); Xg_define_procedure(gtk_widget_get_tooltip_window, gxg_gtk_widget_get_tooltip_window_w, 1, 0, 0, H_gtk_widget_get_tooltip_window, pl_pu); Xg_define_procedure(gtk_widget_trigger_tooltip_query, gxg_gtk_widget_trigger_tooltip_query_w, 1, 0, 0, H_gtk_widget_trigger_tooltip_query, pl_tu); Xg_define_procedure(gtk_window_set_startup_id, gxg_gtk_window_set_startup_id_w, 2, 0, 0, H_gtk_window_set_startup_id, pl_tus); Xg_define_procedure(gtk_text_buffer_add_mark, gxg_gtk_text_buffer_add_mark_w, 3, 0, 0, H_gtk_text_buffer_add_mark, pl_tu); Xg_define_procedure(gtk_text_mark_new, gxg_gtk_text_mark_new_w, 2, 0, 0, H_gtk_text_mark_new, pl_psb); Xg_define_procedure(gtk_tree_view_column_get_tree_view, gxg_gtk_tree_view_column_get_tree_view_w, 1, 0, 0, H_gtk_tree_view_column_get_tree_view, pl_pu); Xg_define_procedure(gtk_tooltip_set_text, gxg_gtk_tooltip_set_text_w, 2, 0, 0, H_gtk_tooltip_set_text, pl_tus); Xg_define_procedure(gtk_tree_view_convert_widget_to_tree_coords, gxg_gtk_tree_view_convert_widget_to_tree_coords_w, 3, 2, 0, H_gtk_tree_view_convert_widget_to_tree_coords, pl_tuiiu); Xg_define_procedure(gtk_tree_view_convert_tree_to_widget_coords, gxg_gtk_tree_view_convert_tree_to_widget_coords_w, 3, 2, 0, H_gtk_tree_view_convert_tree_to_widget_coords, pl_tuiiu); Xg_define_procedure(gtk_tree_view_convert_widget_to_bin_window_coords, gxg_gtk_tree_view_convert_widget_to_bin_window_coords_w, 3, 2, 0, H_gtk_tree_view_convert_widget_to_bin_window_coords, pl_tuiiu); Xg_define_procedure(gtk_tree_view_convert_bin_window_to_widget_coords, gxg_gtk_tree_view_convert_bin_window_to_widget_coords_w, 3, 2, 0, H_gtk_tree_view_convert_bin_window_to_widget_coords, pl_tuiiu); Xg_define_procedure(gtk_tree_view_convert_tree_to_bin_window_coords, gxg_gtk_tree_view_convert_tree_to_bin_window_coords_w, 3, 2, 0, H_gtk_tree_view_convert_tree_to_bin_window_coords, pl_tuiiu); Xg_define_procedure(gtk_tree_view_convert_bin_window_to_tree_coords, gxg_gtk_tree_view_convert_bin_window_to_tree_coords_w, 3, 2, 0, H_gtk_tree_view_convert_bin_window_to_tree_coords, pl_tuiiu); Xg_define_procedure(gtk_widget_set_tooltip_text, gxg_gtk_widget_set_tooltip_text_w, 2, 0, 0, H_gtk_widget_set_tooltip_text, pl_tus); Xg_define_procedure(gtk_widget_get_tooltip_text, gxg_gtk_widget_get_tooltip_text_w, 1, 0, 0, H_gtk_widget_get_tooltip_text, pl_su); Xg_define_procedure(gtk_widget_set_tooltip_markup, gxg_gtk_widget_set_tooltip_markup_w, 2, 0, 0, H_gtk_widget_set_tooltip_markup, pl_tus); Xg_define_procedure(gtk_widget_get_tooltip_markup, gxg_gtk_widget_get_tooltip_markup_w, 1, 0, 0, H_gtk_widget_get_tooltip_markup, pl_su); Xg_define_procedure(gtk_tree_view_is_rubber_banding_active, gxg_gtk_tree_view_is_rubber_banding_active_w, 1, 0, 0, H_gtk_tree_view_is_rubber_banding_active, pl_bu); Xg_define_procedure(gtk_icon_view_convert_widget_to_bin_window_coords, gxg_gtk_icon_view_convert_widget_to_bin_window_coords_w, 3, 2, 0, H_gtk_icon_view_convert_widget_to_bin_window_coords, pl_tuiiu); Xg_define_procedure(gtk_icon_view_set_tooltip_item, gxg_gtk_icon_view_set_tooltip_item_w, 3, 0, 0, H_gtk_icon_view_set_tooltip_item, pl_tu); Xg_define_procedure(gtk_icon_view_set_tooltip_cell, gxg_gtk_icon_view_set_tooltip_cell_w, 4, 0, 0, H_gtk_icon_view_set_tooltip_cell, pl_tu); Xg_define_procedure(gtk_icon_view_get_tooltip_context, gxg_gtk_icon_view_get_tooltip_context_w, 3, 4, 0, H_gtk_icon_view_get_tooltip_context, pl_buuubu); Xg_define_procedure(gtk_icon_view_set_tooltip_column, gxg_gtk_icon_view_set_tooltip_column_w, 2, 0, 0, H_gtk_icon_view_set_tooltip_column, pl_tui); Xg_define_procedure(gtk_icon_view_get_tooltip_column, gxg_gtk_icon_view_get_tooltip_column_w, 1, 0, 0, H_gtk_icon_view_get_tooltip_column, pl_iu); Xg_define_procedure(gtk_menu_tool_button_set_arrow_tooltip_text, gxg_gtk_menu_tool_button_set_arrow_tooltip_text_w, 2, 0, 0, H_gtk_menu_tool_button_set_arrow_tooltip_text, pl_tus); Xg_define_procedure(gtk_menu_tool_button_set_arrow_tooltip_markup, gxg_gtk_menu_tool_button_set_arrow_tooltip_markup_w, 2, 0, 0, H_gtk_menu_tool_button_set_arrow_tooltip_markup, pl_tus); Xg_define_procedure(gtk_tool_item_set_tooltip_text, gxg_gtk_tool_item_set_tooltip_text_w, 2, 0, 0, H_gtk_tool_item_set_tooltip_text, pl_tus); Xg_define_procedure(gtk_tool_item_set_tooltip_markup, gxg_gtk_tool_item_set_tooltip_markup_w, 2, 0, 0, H_gtk_tool_item_set_tooltip_markup, pl_tus); Xg_define_procedure(gtk_tooltip_set_tip_area, gxg_gtk_tooltip_set_tip_area_w, 2, 0, 0, H_gtk_tooltip_set_tip_area, pl_tu); Xg_define_procedure(gtk_tree_view_set_tooltip_row, gxg_gtk_tree_view_set_tooltip_row_w, 3, 0, 0, H_gtk_tree_view_set_tooltip_row, pl_tu); Xg_define_procedure(gtk_tree_view_set_tooltip_cell, gxg_gtk_tree_view_set_tooltip_cell_w, 5, 0, 0, H_gtk_tree_view_set_tooltip_cell, pl_tu); Xg_define_procedure(gtk_tree_view_get_tooltip_context, gxg_gtk_tree_view_get_tooltip_context_w, 3, 4, 0, H_gtk_tree_view_get_tooltip_context, pl_buuubu); Xg_define_procedure(gtk_tree_view_set_tooltip_column, gxg_gtk_tree_view_set_tooltip_column_w, 2, 0, 0, H_gtk_tree_view_set_tooltip_column, pl_tui); Xg_define_procedure(gtk_tree_view_get_tooltip_column, gxg_gtk_tree_view_get_tooltip_column_w, 1, 0, 0, H_gtk_tree_view_get_tooltip_column, pl_iu); Xg_define_procedure(gtk_widget_set_has_tooltip, gxg_gtk_widget_set_has_tooltip_w, 2, 0, 0, H_gtk_widget_set_has_tooltip, pl_tub); Xg_define_procedure(gtk_widget_get_has_tooltip, gxg_gtk_widget_get_has_tooltip_w, 1, 0, 0, H_gtk_widget_get_has_tooltip, pl_bu); #if GTK_CHECK_VERSION(2, 14, 0) Xg_define_procedure(gtk_calendar_set_detail_func, gxg_gtk_calendar_set_detail_func_w, 4, 0, 0, H_gtk_calendar_set_detail_func, pl_tut); Xg_define_procedure(gtk_calendar_set_detail_width_chars, gxg_gtk_calendar_set_detail_width_chars_w, 2, 0, 0, H_gtk_calendar_set_detail_width_chars, pl_tui); Xg_define_procedure(gtk_calendar_set_detail_height_rows, gxg_gtk_calendar_set_detail_height_rows_w, 2, 0, 0, H_gtk_calendar_set_detail_height_rows, pl_tui); Xg_define_procedure(gtk_calendar_get_detail_width_chars, gxg_gtk_calendar_get_detail_width_chars_w, 1, 0, 0, H_gtk_calendar_get_detail_width_chars, pl_iu); Xg_define_procedure(gtk_calendar_get_detail_height_rows, gxg_gtk_calendar_get_detail_height_rows_w, 1, 0, 0, H_gtk_calendar_get_detail_height_rows, pl_iu); Xg_define_procedure(gdk_screen_get_monitor_width_mm, gxg_gdk_screen_get_monitor_width_mm_w, 2, 0, 0, H_gdk_screen_get_monitor_width_mm, pl_iui); Xg_define_procedure(gdk_screen_get_monitor_height_mm, gxg_gdk_screen_get_monitor_height_mm_w, 2, 0, 0, H_gdk_screen_get_monitor_height_mm, pl_iui); Xg_define_procedure(gdk_screen_get_monitor_plug_name, gxg_gdk_screen_get_monitor_plug_name_w, 2, 0, 0, H_gdk_screen_get_monitor_plug_name, pl_sui); Xg_define_procedure(gtk_accel_group_get_is_locked, gxg_gtk_accel_group_get_is_locked_w, 1, 0, 0, H_gtk_accel_group_get_is_locked, pl_bu); Xg_define_procedure(gtk_container_get_focus_child, gxg_gtk_container_get_focus_child_w, 1, 0, 0, H_gtk_container_get_focus_child, pl_pu); Xg_define_procedure(gtk_dialog_get_content_area, gxg_gtk_dialog_get_content_area_w, 1, 0, 0, H_gtk_dialog_get_content_area, pl_pu); Xg_define_procedure(gtk_entry_set_overwrite_mode, gxg_gtk_entry_set_overwrite_mode_w, 2, 0, 0, H_gtk_entry_set_overwrite_mode, pl_tub); Xg_define_procedure(gtk_entry_get_overwrite_mode, gxg_gtk_entry_get_overwrite_mode_w, 1, 0, 0, H_gtk_entry_get_overwrite_mode, pl_bu); Xg_define_procedure(gtk_entry_get_text_length, gxg_gtk_entry_get_text_length_w, 1, 0, 0, H_gtk_entry_get_text_length, pl_iu); Xg_define_procedure(gtk_layout_get_bin_window, gxg_gtk_layout_get_bin_window_w, 1, 0, 0, H_gtk_layout_get_bin_window, pl_pu); Xg_define_procedure(gtk_menu_get_accel_path, gxg_gtk_menu_get_accel_path_w, 1, 0, 0, H_gtk_menu_get_accel_path, pl_su); Xg_define_procedure(gtk_menu_get_monitor, gxg_gtk_menu_get_monitor_w, 1, 0, 0, H_gtk_menu_get_monitor, pl_iu); Xg_define_procedure(gtk_menu_item_get_accel_path, gxg_gtk_menu_item_get_accel_path_w, 1, 0, 0, H_gtk_menu_item_get_accel_path, pl_su); Xg_define_procedure(gtk_scale_button_get_plus_button, gxg_gtk_scale_button_get_plus_button_w, 1, 0, 0, H_gtk_scale_button_get_plus_button, pl_pu); Xg_define_procedure(gtk_scale_button_get_minus_button, gxg_gtk_scale_button_get_minus_button_w, 1, 0, 0, H_gtk_scale_button_get_minus_button, pl_pu); Xg_define_procedure(gtk_scale_button_get_popup, gxg_gtk_scale_button_get_popup_w, 1, 0, 0, H_gtk_scale_button_get_popup, pl_pu); Xg_define_procedure(gtk_selection_data_get_target, gxg_gtk_selection_data_get_target_w, 1, 0, 0, H_gtk_selection_data_get_target, pl_tu); Xg_define_procedure(gtk_selection_data_get_data_type, gxg_gtk_selection_data_get_data_type_w, 1, 0, 0, H_gtk_selection_data_get_data_type, pl_tu); Xg_define_procedure(gtk_selection_data_get_format, gxg_gtk_selection_data_get_format_w, 1, 0, 0, H_gtk_selection_data_get_format, pl_iu); Xg_define_procedure(gtk_selection_data_get_display, gxg_gtk_selection_data_get_display_w, 1, 0, 0, H_gtk_selection_data_get_display, pl_pu); Xg_define_procedure(gtk_widget_get_window, gxg_gtk_widget_get_window_w, 1, 0, 0, H_gtk_widget_get_window, pl_pu); Xg_define_procedure(gtk_accel_group_get_modifier_mask, gxg_gtk_accel_group_get_modifier_mask_w, 1, 0, 0, H_gtk_accel_group_get_modifier_mask, pl_iu); Xg_define_procedure(gdk_threads_add_timeout_seconds_full, gxg_gdk_threads_add_timeout_seconds_full_w, 5, 0, 0, H_gdk_threads_add_timeout_seconds_full, pl_iiit); Xg_define_procedure(gdk_threads_add_timeout_seconds, gxg_gdk_threads_add_timeout_seconds_w, 2, 1, 0, H_gdk_threads_add_timeout_seconds, pl_iit); Xg_define_procedure(gtk_adjustment_get_lower, gxg_gtk_adjustment_get_lower_w, 1, 0, 0, H_gtk_adjustment_get_lower, pl_du); Xg_define_procedure(gtk_adjustment_set_lower, gxg_gtk_adjustment_set_lower_w, 2, 0, 0, H_gtk_adjustment_set_lower, pl_tur); Xg_define_procedure(gtk_adjustment_get_upper, gxg_gtk_adjustment_get_upper_w, 1, 0, 0, H_gtk_adjustment_get_upper, pl_du); Xg_define_procedure(gtk_adjustment_set_upper, gxg_gtk_adjustment_set_upper_w, 2, 0, 0, H_gtk_adjustment_set_upper, pl_tur); Xg_define_procedure(gtk_adjustment_get_step_increment, gxg_gtk_adjustment_get_step_increment_w, 1, 0, 0, H_gtk_adjustment_get_step_increment, pl_du); Xg_define_procedure(gtk_adjustment_set_step_increment, gxg_gtk_adjustment_set_step_increment_w, 2, 0, 0, H_gtk_adjustment_set_step_increment, pl_tur); Xg_define_procedure(gtk_adjustment_get_page_increment, gxg_gtk_adjustment_get_page_increment_w, 1, 0, 0, H_gtk_adjustment_get_page_increment, pl_du); Xg_define_procedure(gtk_adjustment_set_page_increment, gxg_gtk_adjustment_set_page_increment_w, 2, 0, 0, H_gtk_adjustment_set_page_increment, pl_tur); Xg_define_procedure(gtk_adjustment_get_page_size, gxg_gtk_adjustment_get_page_size_w, 1, 0, 0, H_gtk_adjustment_get_page_size, pl_du); Xg_define_procedure(gtk_adjustment_set_page_size, gxg_gtk_adjustment_set_page_size_w, 2, 0, 0, H_gtk_adjustment_set_page_size, pl_tur); Xg_define_procedure(gtk_adjustment_configure, gxg_gtk_adjustment_configure_w, 7, 0, 0, H_gtk_adjustment_configure, pl_tur); Xg_define_procedure(gtk_combo_box_set_button_sensitivity, gxg_gtk_combo_box_set_button_sensitivity_w, 2, 0, 0, H_gtk_combo_box_set_button_sensitivity, pl_tui); Xg_define_procedure(gtk_combo_box_get_button_sensitivity, gxg_gtk_combo_box_get_button_sensitivity_w, 1, 0, 0, H_gtk_combo_box_get_button_sensitivity, pl_iu); Xg_define_procedure(gtk_file_chooser_get_file, gxg_gtk_file_chooser_get_file_w, 1, 0, 0, H_gtk_file_chooser_get_file, pl_pu); Xg_define_procedure(gtk_file_chooser_set_file, gxg_gtk_file_chooser_set_file_w, 2, 1, 0, H_gtk_file_chooser_set_file, pl_bu); Xg_define_procedure(gtk_file_chooser_select_file, gxg_gtk_file_chooser_select_file_w, 2, 1, 0, H_gtk_file_chooser_select_file, pl_bu); Xg_define_procedure(gtk_file_chooser_unselect_file, gxg_gtk_file_chooser_unselect_file_w, 2, 0, 0, H_gtk_file_chooser_unselect_file, pl_tu); Xg_define_procedure(gtk_file_chooser_get_files, gxg_gtk_file_chooser_get_files_w, 1, 0, 0, H_gtk_file_chooser_get_files, pl_pu); Xg_define_procedure(gtk_file_chooser_set_current_folder_file, gxg_gtk_file_chooser_set_current_folder_file_w, 2, 1, 0, H_gtk_file_chooser_set_current_folder_file, pl_bu); Xg_define_procedure(gtk_file_chooser_get_current_folder_file, gxg_gtk_file_chooser_get_current_folder_file_w, 1, 0, 0, H_gtk_file_chooser_get_current_folder_file, pl_pu); Xg_define_procedure(gtk_file_chooser_get_preview_file, gxg_gtk_file_chooser_get_preview_file_w, 1, 0, 0, H_gtk_file_chooser_get_preview_file, pl_pu); Xg_define_procedure(gtk_window_get_default_widget, gxg_gtk_window_get_default_widget_w, 1, 0, 0, H_gtk_window_get_default_widget, pl_pu); #endif #if GTK_CHECK_VERSION(2, 16, 0) Xg_define_procedure(gtk_link_button_get_visited, gxg_gtk_link_button_get_visited_w, 1, 0, 0, H_gtk_link_button_get_visited, pl_bu); Xg_define_procedure(gtk_link_button_set_visited, gxg_gtk_link_button_set_visited_w, 2, 0, 0, H_gtk_link_button_set_visited, pl_tub); Xg_define_procedure(gdk_keymap_get_caps_lock_state, gxg_gdk_keymap_get_caps_lock_state_w, 1, 0, 0, H_gdk_keymap_get_caps_lock_state, pl_bu); Xg_define_procedure(gtk_cell_view_get_model, gxg_gtk_cell_view_get_model_w, 1, 0, 0, H_gtk_cell_view_get_model, pl_pu); Xg_define_procedure(gtk_entry_unset_invisible_char, gxg_gtk_entry_unset_invisible_char_w, 1, 0, 0, H_gtk_entry_unset_invisible_char, pl_tu); Xg_define_procedure(gtk_entry_set_progress_fraction, gxg_gtk_entry_set_progress_fraction_w, 2, 0, 0, H_gtk_entry_set_progress_fraction, pl_tur); Xg_define_procedure(gtk_entry_get_progress_fraction, gxg_gtk_entry_get_progress_fraction_w, 1, 0, 0, H_gtk_entry_get_progress_fraction, pl_du); Xg_define_procedure(gtk_entry_set_progress_pulse_step, gxg_gtk_entry_set_progress_pulse_step_w, 2, 0, 0, H_gtk_entry_set_progress_pulse_step, pl_tur); Xg_define_procedure(gtk_entry_get_progress_pulse_step, gxg_gtk_entry_get_progress_pulse_step_w, 1, 0, 0, H_gtk_entry_get_progress_pulse_step, pl_du); Xg_define_procedure(gtk_entry_progress_pulse, gxg_gtk_entry_progress_pulse_w, 1, 0, 0, H_gtk_entry_progress_pulse, pl_tu); Xg_define_procedure(gtk_entry_set_icon_from_pixbuf, gxg_gtk_entry_set_icon_from_pixbuf_w, 3, 0, 0, H_gtk_entry_set_icon_from_pixbuf, pl_tuiu); Xg_define_procedure(gtk_entry_set_icon_from_icon_name, gxg_gtk_entry_set_icon_from_icon_name_w, 3, 0, 0, H_gtk_entry_set_icon_from_icon_name, pl_tuis); Xg_define_procedure(gtk_entry_set_icon_from_gicon, gxg_gtk_entry_set_icon_from_gicon_w, 3, 0, 0, H_gtk_entry_set_icon_from_gicon, pl_tuiu); Xg_define_procedure(gtk_entry_get_icon_name, gxg_gtk_entry_get_icon_name_w, 2, 0, 0, H_gtk_entry_get_icon_name, pl_sui); Xg_define_procedure(gtk_entry_set_icon_activatable, gxg_gtk_entry_set_icon_activatable_w, 3, 0, 0, H_gtk_entry_set_icon_activatable, pl_tuib); Xg_define_procedure(gtk_entry_get_icon_activatable, gxg_gtk_entry_get_icon_activatable_w, 2, 0, 0, H_gtk_entry_get_icon_activatable, pl_bui); Xg_define_procedure(gtk_entry_set_icon_sensitive, gxg_gtk_entry_set_icon_sensitive_w, 3, 0, 0, H_gtk_entry_set_icon_sensitive, pl_tuib); Xg_define_procedure(gtk_entry_get_icon_sensitive, gxg_gtk_entry_get_icon_sensitive_w, 2, 0, 0, H_gtk_entry_get_icon_sensitive, pl_bui); Xg_define_procedure(gtk_entry_get_icon_at_pos, gxg_gtk_entry_get_icon_at_pos_w, 3, 0, 0, H_gtk_entry_get_icon_at_pos, pl_iui); Xg_define_procedure(gtk_entry_set_icon_tooltip_text, gxg_gtk_entry_set_icon_tooltip_text_w, 3, 0, 0, H_gtk_entry_set_icon_tooltip_text, pl_tuis); Xg_define_procedure(gtk_entry_set_icon_tooltip_markup, gxg_gtk_entry_set_icon_tooltip_markup_w, 3, 0, 0, H_gtk_entry_set_icon_tooltip_markup, pl_tuis); Xg_define_procedure(gtk_entry_set_icon_drag_source, gxg_gtk_entry_set_icon_drag_source_w, 4, 0, 0, H_gtk_entry_set_icon_drag_source, pl_tuiui); Xg_define_procedure(gtk_entry_get_current_icon_drag_source, gxg_gtk_entry_get_current_icon_drag_source_w, 1, 0, 0, H_gtk_entry_get_current_icon_drag_source, pl_iu); Xg_define_procedure(gtk_menu_item_set_label, gxg_gtk_menu_item_set_label_w, 2, 0, 0, H_gtk_menu_item_set_label, pl_tus); Xg_define_procedure(gtk_menu_item_get_label, gxg_gtk_menu_item_get_label_w, 1, 0, 0, H_gtk_menu_item_get_label, pl_su); Xg_define_procedure(gtk_menu_item_set_use_underline, gxg_gtk_menu_item_set_use_underline_w, 2, 0, 0, H_gtk_menu_item_set_use_underline, pl_tub); Xg_define_procedure(gtk_menu_item_get_use_underline, gxg_gtk_menu_item_get_use_underline_w, 1, 0, 0, H_gtk_menu_item_get_use_underline, pl_bu); Xg_define_procedure(gtk_selection_data_get_selection, gxg_gtk_selection_data_get_selection_w, 1, 0, 0, H_gtk_selection_data_get_selection, pl_tu); Xg_define_procedure(gtk_entry_get_icon_tooltip_text, gxg_gtk_entry_get_icon_tooltip_text_w, 2, 0, 0, H_gtk_entry_get_icon_tooltip_text, pl_sui); Xg_define_procedure(gtk_entry_get_icon_tooltip_markup, gxg_gtk_entry_get_icon_tooltip_markup_w, 2, 0, 0, H_gtk_entry_get_icon_tooltip_markup, pl_sui); Xg_define_procedure(gtk_scale_add_mark, gxg_gtk_scale_add_mark_w, 4, 0, 0, H_gtk_scale_add_mark, pl_turis); Xg_define_procedure(gtk_scale_clear_marks, gxg_gtk_scale_clear_marks_w, 1, 0, 0, H_gtk_scale_clear_marks, pl_tu); #endif #if GTK_CHECK_VERSION(2, 18, 0) Xg_define_procedure(gtk_window_get_default_icon_name, gxg_gtk_window_get_default_icon_name_w, 0, 0, 0, H_gtk_window_get_default_icon_name, pl_s); Xg_define_procedure(gtk_label_get_current_uri, gxg_gtk_label_get_current_uri_w, 1, 0, 0, H_gtk_label_get_current_uri, pl_su); Xg_define_procedure(gtk_info_bar_new, gxg_gtk_info_bar_new_w, 0, 0, 0, H_gtk_info_bar_new, pl_p); Xg_define_procedure(gtk_info_bar_get_action_area, gxg_gtk_info_bar_get_action_area_w, 1, 0, 0, H_gtk_info_bar_get_action_area, pl_pu); Xg_define_procedure(gtk_info_bar_get_content_area, gxg_gtk_info_bar_get_content_area_w, 1, 0, 0, H_gtk_info_bar_get_content_area, pl_pu); Xg_define_procedure(gtk_info_bar_add_action_widget, gxg_gtk_info_bar_add_action_widget_w, 3, 0, 0, H_gtk_info_bar_add_action_widget, pl_tuui); Xg_define_procedure(gtk_info_bar_add_button, gxg_gtk_info_bar_add_button_w, 3, 0, 0, H_gtk_info_bar_add_button, pl_pusi); Xg_define_procedure(gtk_info_bar_set_response_sensitive, gxg_gtk_info_bar_set_response_sensitive_w, 3, 0, 0, H_gtk_info_bar_set_response_sensitive, pl_tuib); Xg_define_procedure(gtk_info_bar_set_default_response, gxg_gtk_info_bar_set_default_response_w, 2, 0, 0, H_gtk_info_bar_set_default_response, pl_tui); Xg_define_procedure(gtk_info_bar_response, gxg_gtk_info_bar_response_w, 2, 0, 0, H_gtk_info_bar_response, pl_tui); Xg_define_procedure(gtk_info_bar_set_message_type, gxg_gtk_info_bar_set_message_type_w, 2, 0, 0, H_gtk_info_bar_set_message_type, pl_tui); Xg_define_procedure(gtk_info_bar_get_message_type, gxg_gtk_info_bar_get_message_type_w, 1, 0, 0, H_gtk_info_bar_get_message_type, pl_iu); Xg_define_procedure(gdk_window_ensure_native, gxg_gdk_window_ensure_native_w, 1, 0, 0, H_gdk_window_ensure_native, pl_bu); Xg_define_procedure(gdk_window_get_root_coords, gxg_gdk_window_get_root_coords_w, 3, 2, 0, H_gdk_window_get_root_coords, pl_tuiiu); Xg_define_procedure(gdk_offscreen_window_set_embedder, gxg_gdk_offscreen_window_set_embedder_w, 2, 0, 0, H_gdk_offscreen_window_set_embedder, pl_tu); Xg_define_procedure(gdk_offscreen_window_get_embedder, gxg_gdk_offscreen_window_get_embedder_w, 1, 0, 0, H_gdk_offscreen_window_get_embedder, pl_pu); Xg_define_procedure(gdk_window_geometry_changed, gxg_gdk_window_geometry_changed_w, 1, 0, 0, H_gdk_window_geometry_changed, pl_tu); Xg_define_procedure(gtk_menu_set_reserve_toggle_size, gxg_gtk_menu_set_reserve_toggle_size_w, 2, 0, 0, H_gtk_menu_set_reserve_toggle_size, pl_tub); Xg_define_procedure(gtk_menu_get_reserve_toggle_size, gxg_gtk_menu_get_reserve_toggle_size_w, 1, 0, 0, H_gtk_menu_get_reserve_toggle_size, pl_bu); Xg_define_procedure(gtk_entry_new_with_buffer, gxg_gtk_entry_new_with_buffer_w, 1, 0, 0, H_gtk_entry_new_with_buffer, pl_pu); Xg_define_procedure(gtk_entry_get_buffer, gxg_gtk_entry_get_buffer_w, 1, 0, 0, H_gtk_entry_get_buffer, pl_pu); Xg_define_procedure(gtk_entry_set_buffer, gxg_gtk_entry_set_buffer_w, 2, 0, 0, H_gtk_entry_set_buffer, pl_tu); Xg_define_procedure(gtk_label_set_track_visited_links, gxg_gtk_label_set_track_visited_links_w, 2, 0, 0, H_gtk_label_set_track_visited_links, pl_tub); Xg_define_procedure(gtk_label_get_track_visited_links, gxg_gtk_label_get_track_visited_links_w, 1, 0, 0, H_gtk_label_get_track_visited_links, pl_bu); Xg_define_procedure(gtk_print_operation_set_embed_page_setup, gxg_gtk_print_operation_set_embed_page_setup_w, 2, 0, 0, H_gtk_print_operation_set_embed_page_setup, pl_tub); Xg_define_procedure(gtk_print_operation_get_embed_page_setup, gxg_gtk_print_operation_get_embed_page_setup_w, 1, 0, 0, H_gtk_print_operation_get_embed_page_setup, pl_bu); Xg_define_procedure(gtk_entry_buffer_new, gxg_gtk_entry_buffer_new_w, 2, 0, 0, H_gtk_entry_buffer_new, pl_psi); Xg_define_procedure(gtk_entry_buffer_get_bytes, gxg_gtk_entry_buffer_get_bytes_w, 1, 0, 0, H_gtk_entry_buffer_get_bytes, pl_iu); Xg_define_procedure(gtk_entry_buffer_get_length, gxg_gtk_entry_buffer_get_length_w, 1, 0, 0, H_gtk_entry_buffer_get_length, pl_iu); Xg_define_procedure(gtk_entry_buffer_get_text, gxg_gtk_entry_buffer_get_text_w, 1, 0, 0, H_gtk_entry_buffer_get_text, pl_su); Xg_define_procedure(gtk_entry_buffer_set_text, gxg_gtk_entry_buffer_set_text_w, 3, 0, 0, H_gtk_entry_buffer_set_text, pl_tusi); Xg_define_procedure(gtk_entry_buffer_set_max_length, gxg_gtk_entry_buffer_set_max_length_w, 2, 0, 0, H_gtk_entry_buffer_set_max_length, pl_tui); Xg_define_procedure(gtk_entry_buffer_get_max_length, gxg_gtk_entry_buffer_get_max_length_w, 1, 0, 0, H_gtk_entry_buffer_get_max_length, pl_iu); Xg_define_procedure(gtk_entry_buffer_insert_text, gxg_gtk_entry_buffer_insert_text_w, 4, 0, 0, H_gtk_entry_buffer_insert_text, pl_iuisi); Xg_define_procedure(gtk_entry_buffer_delete_text, gxg_gtk_entry_buffer_delete_text_w, 3, 0, 0, H_gtk_entry_buffer_delete_text, pl_iui); Xg_define_procedure(gtk_entry_buffer_emit_inserted_text, gxg_gtk_entry_buffer_emit_inserted_text_w, 4, 0, 0, H_gtk_entry_buffer_emit_inserted_text, pl_tuisi); Xg_define_procedure(gtk_entry_buffer_emit_deleted_text, gxg_gtk_entry_buffer_emit_deleted_text_w, 3, 0, 0, H_gtk_entry_buffer_emit_deleted_text, pl_tui); Xg_define_procedure(gtk_cell_renderer_set_alignment, gxg_gtk_cell_renderer_set_alignment_w, 3, 0, 0, H_gtk_cell_renderer_set_alignment, pl_tur); Xg_define_procedure(gtk_cell_renderer_get_alignment, gxg_gtk_cell_renderer_get_alignment_w, 1, 2, 0, H_gtk_cell_renderer_get_alignment, pl_tu); Xg_define_procedure(gtk_cell_renderer_set_padding, gxg_gtk_cell_renderer_set_padding_w, 3, 0, 0, H_gtk_cell_renderer_set_padding, pl_tui); Xg_define_procedure(gtk_cell_renderer_get_padding, gxg_gtk_cell_renderer_get_padding_w, 1, 2, 0, H_gtk_cell_renderer_get_padding, pl_tu); Xg_define_procedure(gtk_cell_renderer_set_visible, gxg_gtk_cell_renderer_set_visible_w, 2, 0, 0, H_gtk_cell_renderer_set_visible, pl_tub); Xg_define_procedure(gtk_cell_renderer_get_visible, gxg_gtk_cell_renderer_get_visible_w, 1, 0, 0, H_gtk_cell_renderer_get_visible, pl_bu); Xg_define_procedure(gtk_cell_renderer_set_sensitive, gxg_gtk_cell_renderer_set_sensitive_w, 2, 0, 0, H_gtk_cell_renderer_set_sensitive, pl_tub); Xg_define_procedure(gtk_cell_renderer_get_sensitive, gxg_gtk_cell_renderer_get_sensitive_w, 1, 0, 0, H_gtk_cell_renderer_get_sensitive, pl_bu); Xg_define_procedure(gtk_cell_renderer_toggle_get_activatable, gxg_gtk_cell_renderer_toggle_get_activatable_w, 1, 0, 0, H_gtk_cell_renderer_toggle_get_activatable, pl_bu); Xg_define_procedure(gtk_cell_renderer_toggle_set_activatable, gxg_gtk_cell_renderer_toggle_set_activatable_w, 2, 0, 0, H_gtk_cell_renderer_toggle_set_activatable, pl_tub); Xg_define_procedure(gtk_widget_set_can_focus, gxg_gtk_widget_set_can_focus_w, 2, 0, 0, H_gtk_widget_set_can_focus, pl_tub); Xg_define_procedure(gtk_widget_get_can_focus, gxg_gtk_widget_get_can_focus_w, 1, 0, 0, H_gtk_widget_get_can_focus, pl_bu); Xg_define_procedure(gtk_widget_has_focus, gxg_gtk_widget_has_focus_w, 1, 0, 0, H_gtk_widget_has_focus, pl_bu); Xg_define_procedure(gtk_widget_set_can_default, gxg_gtk_widget_set_can_default_w, 2, 0, 0, H_gtk_widget_set_can_default, pl_tub); Xg_define_procedure(gtk_widget_get_can_default, gxg_gtk_widget_get_can_default_w, 1, 0, 0, H_gtk_widget_get_can_default, pl_bu); Xg_define_procedure(gtk_widget_has_default, gxg_gtk_widget_has_default_w, 1, 0, 0, H_gtk_widget_has_default, pl_bu); Xg_define_procedure(gtk_widget_get_sensitive, gxg_gtk_widget_get_sensitive_w, 1, 0, 0, H_gtk_widget_get_sensitive, pl_bu); Xg_define_procedure(gtk_widget_is_sensitive, gxg_gtk_widget_is_sensitive_w, 1, 0, 0, H_gtk_widget_is_sensitive, pl_bu); Xg_define_procedure(gtk_widget_set_has_window, gxg_gtk_widget_set_has_window_w, 2, 0, 0, H_gtk_widget_set_has_window, pl_tub); Xg_define_procedure(gtk_widget_get_has_window, gxg_gtk_widget_get_has_window_w, 1, 0, 0, H_gtk_widget_get_has_window, pl_bu); Xg_define_procedure(gtk_widget_get_app_paintable, gxg_gtk_widget_get_app_paintable_w, 1, 0, 0, H_gtk_widget_get_app_paintable, pl_bu); Xg_define_procedure(gdk_window_get_cursor, gxg_gdk_window_get_cursor_w, 1, 0, 0, H_gdk_window_get_cursor, pl_pu); Xg_define_procedure(gtk_file_chooser_set_create_folders, gxg_gtk_file_chooser_set_create_folders_w, 2, 0, 0, H_gtk_file_chooser_set_create_folders, pl_tub); Xg_define_procedure(gtk_file_chooser_get_create_folders, gxg_gtk_file_chooser_get_create_folders_w, 1, 0, 0, H_gtk_file_chooser_get_create_folders, pl_bu); Xg_define_procedure(gtk_icon_view_set_item_padding, gxg_gtk_icon_view_set_item_padding_w, 2, 0, 0, H_gtk_icon_view_set_item_padding, pl_tui); Xg_define_procedure(gtk_icon_view_get_item_padding, gxg_gtk_icon_view_get_item_padding_w, 1, 0, 0, H_gtk_icon_view_get_item_padding, pl_iu); Xg_define_procedure(gtk_widget_has_grab, gxg_gtk_widget_has_grab_w, 1, 0, 0, H_gtk_widget_has_grab, pl_bu); Xg_define_procedure(gtk_widget_set_visible, gxg_gtk_widget_set_visible_w, 2, 0, 0, H_gtk_widget_set_visible, pl_tub); Xg_define_procedure(gtk_widget_get_visible, gxg_gtk_widget_get_visible_w, 1, 0, 0, H_gtk_widget_get_visible, pl_bu); Xg_define_procedure(gtk_range_set_flippable, gxg_gtk_range_set_flippable_w, 2, 0, 0, H_gtk_range_set_flippable, pl_tub); Xg_define_procedure(gtk_range_get_flippable, gxg_gtk_range_get_flippable_w, 1, 0, 0, H_gtk_range_get_flippable, pl_bu); Xg_define_procedure(gtk_widget_is_toplevel, gxg_gtk_widget_is_toplevel_w, 1, 0, 0, H_gtk_widget_is_toplevel, pl_bu); Xg_define_procedure(gtk_widget_is_drawable, gxg_gtk_widget_is_drawable_w, 1, 0, 0, H_gtk_widget_is_drawable, pl_bu); Xg_define_procedure(gtk_widget_set_window, gxg_gtk_widget_set_window_w, 2, 0, 0, H_gtk_widget_set_window, pl_tu); Xg_define_procedure(gdk_window_is_destroyed, gxg_gdk_window_is_destroyed_w, 1, 0, 0, H_gdk_window_is_destroyed, pl_bu); Xg_define_procedure(gdk_window_restack, gxg_gdk_window_restack_w, 3, 0, 0, H_gdk_window_restack, pl_tuub); Xg_define_procedure(gtk_widget_set_receives_default, gxg_gtk_widget_set_receives_default_w, 2, 0, 0, H_gtk_widget_set_receives_default, pl_tub); Xg_define_procedure(gtk_widget_get_receives_default, gxg_gtk_widget_get_receives_default_w, 1, 0, 0, H_gtk_widget_get_receives_default, pl_bu); #endif #if GTK_CHECK_VERSION(2, 20, 0) Xg_define_procedure(gtk_dialog_get_widget_for_response, gxg_gtk_dialog_get_widget_for_response_w, 2, 0, 0, H_gtk_dialog_get_widget_for_response, pl_pui); Xg_define_procedure(gtk_viewport_get_bin_window, gxg_gtk_viewport_get_bin_window_w, 1, 0, 0, H_gtk_viewport_get_bin_window, pl_pu); Xg_define_procedure(gtk_spinner_new, gxg_gtk_spinner_new_w, 0, 0, 0, H_gtk_spinner_new, pl_p); Xg_define_procedure(gtk_spinner_start, gxg_gtk_spinner_start_w, 1, 0, 0, H_gtk_spinner_start, pl_tu); Xg_define_procedure(gtk_spinner_stop, gxg_gtk_spinner_stop_w, 1, 0, 0, H_gtk_spinner_stop, pl_tu); Xg_define_procedure(gtk_cell_renderer_spinner_new, gxg_gtk_cell_renderer_spinner_new_w, 0, 0, 0, H_gtk_cell_renderer_spinner_new, pl_p); Xg_define_procedure(gtk_notebook_get_action_widget, gxg_gtk_notebook_get_action_widget_w, 2, 0, 0, H_gtk_notebook_get_action_widget, pl_pui); Xg_define_procedure(gtk_notebook_set_action_widget, gxg_gtk_notebook_set_action_widget_w, 3, 0, 0, H_gtk_notebook_set_action_widget, pl_tuui); Xg_define_procedure(gtk_statusbar_get_message_area, gxg_gtk_statusbar_get_message_area_w, 1, 0, 0, H_gtk_statusbar_get_message_area, pl_pu); Xg_define_procedure(gtk_tool_item_get_ellipsize_mode, gxg_gtk_tool_item_get_ellipsize_mode_w, 1, 0, 0, H_gtk_tool_item_get_ellipsize_mode, pl_iu); Xg_define_procedure(gtk_tool_item_get_text_alignment, gxg_gtk_tool_item_get_text_alignment_w, 1, 0, 0, H_gtk_tool_item_get_text_alignment, pl_du); Xg_define_procedure(gtk_tool_item_get_text_orientation, gxg_gtk_tool_item_get_text_orientation_w, 1, 0, 0, H_gtk_tool_item_get_text_orientation, pl_iu); Xg_define_procedure(gtk_tool_item_get_text_size_group, gxg_gtk_tool_item_get_text_size_group_w, 1, 0, 0, H_gtk_tool_item_get_text_size_group, pl_pu); Xg_define_procedure(gtk_tool_palette_new, gxg_gtk_tool_palette_new_w, 0, 0, 0, H_gtk_tool_palette_new, pl_p); Xg_define_procedure(gtk_tool_palette_set_group_position, gxg_gtk_tool_palette_set_group_position_w, 3, 0, 0, H_gtk_tool_palette_set_group_position, pl_tuui); Xg_define_procedure(gtk_tool_palette_set_exclusive, gxg_gtk_tool_palette_set_exclusive_w, 3, 0, 0, H_gtk_tool_palette_set_exclusive, pl_tuub); Xg_define_procedure(gtk_tool_palette_set_expand, gxg_gtk_tool_palette_set_expand_w, 3, 0, 0, H_gtk_tool_palette_set_expand, pl_tuub); Xg_define_procedure(gtk_tool_palette_get_group_position, gxg_gtk_tool_palette_get_group_position_w, 2, 0, 0, H_gtk_tool_palette_get_group_position, pl_iu); Xg_define_procedure(gtk_tool_palette_get_exclusive, gxg_gtk_tool_palette_get_exclusive_w, 2, 0, 0, H_gtk_tool_palette_get_exclusive, pl_bu); Xg_define_procedure(gtk_tool_palette_get_expand, gxg_gtk_tool_palette_get_expand_w, 2, 0, 0, H_gtk_tool_palette_get_expand, pl_bu); Xg_define_procedure(gtk_tool_palette_unset_icon_size, gxg_gtk_tool_palette_unset_icon_size_w, 1, 0, 0, H_gtk_tool_palette_unset_icon_size, pl_tu); Xg_define_procedure(gtk_tool_palette_set_style, gxg_gtk_tool_palette_set_style_w, 2, 0, 0, H_gtk_tool_palette_set_style, pl_tui); Xg_define_procedure(gtk_tool_palette_unset_style, gxg_gtk_tool_palette_unset_style_w, 1, 0, 0, H_gtk_tool_palette_unset_style, pl_tu); Xg_define_procedure(gtk_tool_palette_get_style, gxg_gtk_tool_palette_get_style_w, 1, 0, 0, H_gtk_tool_palette_get_style, pl_iu); Xg_define_procedure(gtk_tool_palette_get_drop_item, gxg_gtk_tool_palette_get_drop_item_w, 3, 0, 0, H_gtk_tool_palette_get_drop_item, pl_pui); Xg_define_procedure(gtk_tool_palette_get_drop_group, gxg_gtk_tool_palette_get_drop_group_w, 3, 0, 0, H_gtk_tool_palette_get_drop_group, pl_pui); Xg_define_procedure(gtk_tool_palette_get_drag_item, gxg_gtk_tool_palette_get_drag_item_w, 2, 0, 0, H_gtk_tool_palette_get_drag_item, pl_pu); Xg_define_procedure(gtk_tool_palette_set_drag_source, gxg_gtk_tool_palette_set_drag_source_w, 2, 0, 0, H_gtk_tool_palette_set_drag_source, pl_tui); Xg_define_procedure(gtk_tool_palette_add_drag_dest, gxg_gtk_tool_palette_add_drag_dest_w, 5, 0, 0, H_gtk_tool_palette_add_drag_dest, pl_tuui); Xg_define_procedure(gtk_tool_palette_get_drag_target_item, gxg_gtk_tool_palette_get_drag_target_item_w, 0, 0, 0, H_gtk_tool_palette_get_drag_target_item, pl_p); Xg_define_procedure(gtk_tool_palette_get_drag_target_group, gxg_gtk_tool_palette_get_drag_target_group_w, 0, 0, 0, H_gtk_tool_palette_get_drag_target_group, pl_p); Xg_define_procedure(gtk_tool_item_group_new, gxg_gtk_tool_item_group_new_w, 1, 0, 0, H_gtk_tool_item_group_new, pl_ps); Xg_define_procedure(gtk_tool_item_group_set_label, gxg_gtk_tool_item_group_set_label_w, 2, 0, 0, H_gtk_tool_item_group_set_label, pl_tus); Xg_define_procedure(gtk_tool_item_group_set_label_widget, gxg_gtk_tool_item_group_set_label_widget_w, 2, 0, 0, H_gtk_tool_item_group_set_label_widget, pl_tu); Xg_define_procedure(gtk_tool_item_group_set_collapsed, gxg_gtk_tool_item_group_set_collapsed_w, 2, 0, 0, H_gtk_tool_item_group_set_collapsed, pl_tub); Xg_define_procedure(gtk_tool_item_group_set_ellipsize, gxg_gtk_tool_item_group_set_ellipsize_w, 2, 0, 0, H_gtk_tool_item_group_set_ellipsize, pl_tui); Xg_define_procedure(gtk_tool_item_group_set_header_relief, gxg_gtk_tool_item_group_set_header_relief_w, 2, 0, 0, H_gtk_tool_item_group_set_header_relief, pl_tui); Xg_define_procedure(gtk_tool_item_group_get_label, gxg_gtk_tool_item_group_get_label_w, 1, 0, 0, H_gtk_tool_item_group_get_label, pl_su); Xg_define_procedure(gtk_tool_item_group_get_label_widget, gxg_gtk_tool_item_group_get_label_widget_w, 1, 0, 0, H_gtk_tool_item_group_get_label_widget, pl_pu); Xg_define_procedure(gtk_tool_item_group_get_collapsed, gxg_gtk_tool_item_group_get_collapsed_w, 1, 0, 0, H_gtk_tool_item_group_get_collapsed, pl_bu); Xg_define_procedure(gtk_tool_item_group_get_ellipsize, gxg_gtk_tool_item_group_get_ellipsize_w, 1, 0, 0, H_gtk_tool_item_group_get_ellipsize, pl_iu); Xg_define_procedure(gtk_tool_item_group_get_header_relief, gxg_gtk_tool_item_group_get_header_relief_w, 1, 0, 0, H_gtk_tool_item_group_get_header_relief, pl_iu); Xg_define_procedure(gtk_tool_item_group_insert, gxg_gtk_tool_item_group_insert_w, 3, 0, 0, H_gtk_tool_item_group_insert, pl_tuui); Xg_define_procedure(gtk_tool_item_group_set_item_position, gxg_gtk_tool_item_group_set_item_position_w, 3, 0, 0, H_gtk_tool_item_group_set_item_position, pl_tuui); Xg_define_procedure(gtk_tool_item_group_get_item_position, gxg_gtk_tool_item_group_get_item_position_w, 2, 0, 0, H_gtk_tool_item_group_get_item_position, pl_iu); Xg_define_procedure(gtk_tool_item_group_get_n_items, gxg_gtk_tool_item_group_get_n_items_w, 1, 0, 0, H_gtk_tool_item_group_get_n_items, pl_iu); Xg_define_procedure(gtk_tool_item_group_get_nth_item, gxg_gtk_tool_item_group_get_nth_item_w, 2, 0, 0, H_gtk_tool_item_group_get_nth_item, pl_pui); Xg_define_procedure(gtk_tool_item_group_get_drop_item, gxg_gtk_tool_item_group_get_drop_item_w, 3, 0, 0, H_gtk_tool_item_group_get_drop_item, pl_pui); Xg_define_procedure(gdk_screen_get_primary_monitor, gxg_gdk_screen_get_primary_monitor_w, 1, 0, 0, H_gdk_screen_get_primary_monitor, pl_iu); Xg_define_procedure(gtk_window_set_mnemonics_visible, gxg_gtk_window_set_mnemonics_visible_w, 2, 0, 0, H_gtk_window_set_mnemonics_visible, pl_tub); Xg_define_procedure(gtk_window_get_mnemonics_visible, gxg_gtk_window_get_mnemonics_visible_w, 1, 0, 0, H_gtk_window_get_mnemonics_visible, pl_bu); Xg_define_procedure(gtk_range_set_slider_size_fixed, gxg_gtk_range_set_slider_size_fixed_w, 2, 0, 0, H_gtk_range_set_slider_size_fixed, pl_tub); Xg_define_procedure(gtk_range_get_slider_size_fixed, gxg_gtk_range_get_slider_size_fixed_w, 1, 0, 0, H_gtk_range_get_slider_size_fixed, pl_bu); Xg_define_procedure(gtk_range_set_min_slider_size, gxg_gtk_range_set_min_slider_size_w, 2, 0, 0, H_gtk_range_set_min_slider_size, pl_tub); Xg_define_procedure(gtk_range_get_min_slider_size, gxg_gtk_range_get_min_slider_size_w, 1, 0, 0, H_gtk_range_get_min_slider_size, pl_iu); Xg_define_procedure(gtk_range_get_range_rect, gxg_gtk_range_get_range_rect_w, 2, 0, 0, H_gtk_range_get_range_rect, pl_tu); Xg_define_procedure(gtk_range_get_slider_range, gxg_gtk_range_get_slider_range_w, 1, 2, 0, H_gtk_range_get_slider_range, pl_tu); Xg_define_procedure(gtk_paned_get_handle_window, gxg_gtk_paned_get_handle_window_w, 1, 0, 0, H_gtk_paned_get_handle_window, pl_pu); Xg_define_procedure(gtk_widget_set_realized, gxg_gtk_widget_set_realized_w, 2, 0, 0, H_gtk_widget_set_realized, pl_tub); Xg_define_procedure(gtk_widget_get_realized, gxg_gtk_widget_get_realized_w, 1, 0, 0, H_gtk_widget_get_realized, pl_bu); Xg_define_procedure(gtk_widget_set_mapped, gxg_gtk_widget_set_mapped_w, 2, 0, 0, H_gtk_widget_set_mapped, pl_tub); Xg_define_procedure(gtk_widget_get_mapped, gxg_gtk_widget_get_mapped_w, 1, 0, 0, H_gtk_widget_get_mapped, pl_bu); #endif #if GTK_CHECK_VERSION(3, 0, 0) Xg_define_procedure(gdk_cairo_create, gxg_gdk_cairo_create_w, 1, 0, 0, H_gdk_cairo_create, pl_pu); Xg_define_procedure(gdk_window_get_geometry, gxg_gdk_window_get_geometry_w, 1, 4, 0, H_gdk_window_get_geometry, pl_tu); Xg_define_procedure(gdk_keymap_add_virtual_modifiers, gxg_gdk_keymap_add_virtual_modifiers_w, 2, 0, 0, H_gdk_keymap_add_virtual_modifiers, pl_tu); Xg_define_procedure(gdk_window_coords_to_parent, gxg_gdk_window_coords_to_parent_w, 3, 2, 0, H_gdk_window_coords_to_parent, pl_turru); Xg_define_procedure(gdk_window_coords_from_parent, gxg_gdk_window_coords_from_parent_w, 3, 2, 0, H_gdk_window_coords_from_parent, pl_turru); Xg_define_procedure(gdk_window_get_effective_parent, gxg_gdk_window_get_effective_parent_w, 1, 0, 0, H_gdk_window_get_effective_parent, pl_pu); Xg_define_procedure(gdk_window_get_effective_toplevel, gxg_gdk_window_get_effective_toplevel_w, 1, 0, 0, H_gdk_window_get_effective_toplevel, pl_pu); Xg_define_procedure(gtk_accessible_get_widget, gxg_gtk_accessible_get_widget_w, 1, 0, 0, H_gtk_accessible_get_widget, pl_pu); Xg_define_procedure(gtk_widget_send_focus_change, gxg_gtk_widget_send_focus_change_w, 2, 0, 0, H_gtk_widget_send_focus_change, pl_bu); Xg_define_procedure(gdk_display_get_device_manager, gxg_gdk_display_get_device_manager_w, 1, 0, 0, H_gdk_display_get_device_manager, pl_pu); Xg_define_procedure(gdk_drag_context_set_device, gxg_gdk_drag_context_set_device_w, 2, 0, 0, H_gdk_drag_context_set_device, pl_tu); Xg_define_procedure(gdk_drag_context_get_device, gxg_gdk_drag_context_get_device_w, 1, 0, 0, H_gdk_drag_context_get_device, pl_pu); Xg_define_procedure(gdk_drag_context_list_targets, gxg_gdk_drag_context_list_targets_w, 1, 0, 0, H_gdk_drag_context_list_targets, pl_pu); Xg_define_procedure(gdk_event_set_device, gxg_gdk_event_set_device_w, 2, 0, 0, H_gdk_event_set_device, pl_tu); Xg_define_procedure(gdk_event_get_device, gxg_gdk_event_get_device_w, 1, 0, 0, H_gdk_event_get_device, pl_pu); Xg_define_procedure(gdk_events_get_distance, gxg_gdk_events_get_distance_w, 2, 1, 0, H_gdk_events_get_distance, pl_bu); Xg_define_procedure(gdk_events_get_angle, gxg_gdk_events_get_angle_w, 2, 1, 0, H_gdk_events_get_angle, pl_bu); Xg_define_procedure(gdk_events_get_center, gxg_gdk_events_get_center_w, 2, 2, 0, H_gdk_events_get_center, pl_bu); Xg_define_procedure(gdk_window_get_accept_focus, gxg_gdk_window_get_accept_focus_w, 1, 0, 0, H_gdk_window_get_accept_focus, pl_bu); Xg_define_procedure(gdk_window_get_focus_on_map, gxg_gdk_window_get_focus_on_map_w, 1, 0, 0, H_gdk_window_get_focus_on_map, pl_bu); Xg_define_procedure(gdk_window_is_input_only, gxg_gdk_window_is_input_only_w, 1, 0, 0, H_gdk_window_is_input_only, pl_bu); Xg_define_procedure(gdk_window_is_shaped, gxg_gdk_window_is_shaped_w, 1, 0, 0, H_gdk_window_is_shaped, pl_bu); Xg_define_procedure(gdk_window_get_modal_hint, gxg_gdk_window_get_modal_hint_w, 1, 0, 0, H_gdk_window_get_modal_hint, pl_bu); Xg_define_procedure(gdk_window_set_device_cursor, gxg_gdk_window_set_device_cursor_w, 3, 0, 0, H_gdk_window_set_device_cursor, pl_tu); Xg_define_procedure(gdk_window_get_device_cursor, gxg_gdk_window_get_device_cursor_w, 2, 0, 0, H_gdk_window_get_device_cursor, pl_pu); Xg_define_procedure(gdk_window_get_device_position, gxg_gdk_window_get_device_position_w, 2, 3, 0, H_gdk_window_get_device_position, pl_pu); Xg_define_procedure(gdk_window_set_device_events, gxg_gdk_window_set_device_events_w, 3, 0, 0, H_gdk_window_set_device_events, pl_tuui); Xg_define_procedure(gdk_window_get_device_events, gxg_gdk_window_get_device_events_w, 2, 0, 0, H_gdk_window_get_device_events, pl_iu); Xg_define_procedure(gtk_combo_box_popup_for_device, gxg_gtk_combo_box_popup_for_device_w, 2, 0, 0, H_gtk_combo_box_popup_for_device, pl_tu); Xg_define_procedure(gtk_device_grab_add, gxg_gtk_device_grab_add_w, 3, 0, 0, H_gtk_device_grab_add, pl_tuub); Xg_define_procedure(gtk_device_grab_remove, gxg_gtk_device_grab_remove_w, 2, 0, 0, H_gtk_device_grab_remove, pl_tu); Xg_define_procedure(gtk_get_current_event_device, gxg_gtk_get_current_event_device_w, 0, 0, 0, H_gtk_get_current_event_device, pl_p); Xg_define_procedure(gtk_paned_new, gxg_gtk_paned_new_w, 1, 0, 0, H_gtk_paned_new, pl_pi); Xg_define_procedure(gtk_scale_new, gxg_gtk_scale_new_w, 2, 0, 0, H_gtk_scale_new, pl_piu); Xg_define_procedure(gtk_scale_new_with_range, gxg_gtk_scale_new_with_range_w, 4, 0, 0, H_gtk_scale_new_with_range, pl_pir); Xg_define_procedure(gtk_scrollbar_new, gxg_gtk_scrollbar_new_w, 2, 0, 0, H_gtk_scrollbar_new, pl_piu); Xg_define_procedure(gtk_separator_new, gxg_gtk_separator_new_w, 1, 0, 0, H_gtk_separator_new, pl_pi); Xg_define_procedure(gtk_widget_device_is_shadowed, gxg_gtk_widget_device_is_shadowed_w, 2, 0, 0, H_gtk_widget_device_is_shadowed, pl_bu); Xg_define_procedure(gtk_widget_set_device_events, gxg_gtk_widget_set_device_events_w, 3, 0, 0, H_gtk_widget_set_device_events, pl_tuui); Xg_define_procedure(gtk_widget_add_device_events, gxg_gtk_widget_add_device_events_w, 3, 0, 0, H_gtk_widget_add_device_events, pl_tuui); Xg_define_procedure(gtk_widget_get_support_multidevice, gxg_gtk_widget_get_support_multidevice_w, 1, 0, 0, H_gtk_widget_get_support_multidevice, pl_bu); Xg_define_procedure(gtk_widget_set_support_multidevice, gxg_gtk_widget_set_support_multidevice_w, 2, 0, 0, H_gtk_widget_set_support_multidevice, pl_tub); Xg_define_procedure(gtk_widget_get_device_events, gxg_gtk_widget_get_device_events_w, 2, 0, 0, H_gtk_widget_get_device_events, pl_iu); Xg_define_procedure(gtk_icon_view_get_item_row, gxg_gtk_icon_view_get_item_row_w, 2, 0, 0, H_gtk_icon_view_get_item_row, pl_iu); Xg_define_procedure(gtk_icon_view_get_item_column, gxg_gtk_icon_view_get_item_column_w, 2, 0, 0, H_gtk_icon_view_get_item_column, pl_iu); Xg_define_procedure(gtk_statusbar_remove_all, gxg_gtk_statusbar_remove_all_w, 2, 0, 0, H_gtk_statusbar_remove_all, pl_tui); Xg_define_procedure(gtk_window_has_group, gxg_gtk_window_has_group_w, 1, 0, 0, H_gtk_window_has_group, pl_bu); Xg_define_procedure(gtk_calendar_select_month, gxg_gtk_calendar_select_month_w, 3, 0, 0, H_gtk_calendar_select_month, pl_tui); Xg_define_procedure(gtk_calendar_mark_day, gxg_gtk_calendar_mark_day_w, 2, 0, 0, H_gtk_calendar_mark_day, pl_tui); Xg_define_procedure(gtk_calendar_unmark_day, gxg_gtk_calendar_unmark_day_w, 2, 0, 0, H_gtk_calendar_unmark_day, pl_tui); Xg_define_procedure(gdk_drag_context_get_source_window, gxg_gdk_drag_context_get_source_window_w, 1, 0, 0, H_gdk_drag_context_get_source_window, pl_pu); Xg_define_procedure(gtk_viewport_get_view_window, gxg_gtk_viewport_get_view_window_w, 1, 0, 0, H_gtk_viewport_get_view_window, pl_pu); Xg_define_procedure(gtk_accessible_set_widget, gxg_gtk_accessible_set_widget_w, 2, 0, 0, H_gtk_accessible_set_widget, pl_tu); Xg_define_procedure(gtk_button_get_event_window, gxg_gtk_button_get_event_window_w, 1, 0, 0, H_gtk_button_get_event_window, pl_pu); Xg_define_procedure(gtk_message_dialog_get_message_area, gxg_gtk_message_dialog_get_message_area_w, 1, 0, 0, H_gtk_message_dialog_get_message_area, pl_pu); Xg_define_procedure(gtk_selection_data_get_length, gxg_gtk_selection_data_get_length_w, 1, 0, 0, H_gtk_selection_data_get_length, pl_iu); Xg_define_procedure(gdk_pango_layout_line_get_clip_region, gxg_gdk_pango_layout_line_get_clip_region_w, 5, 0, 0, H_gdk_pango_layout_line_get_clip_region, pl_puiiui); Xg_define_procedure(gdk_pango_layout_get_clip_region, gxg_gdk_pango_layout_get_clip_region_w, 5, 0, 0, H_gdk_pango_layout_get_clip_region, pl_puiiui); Xg_define_procedure(gdk_window_shape_combine_region, gxg_gdk_window_shape_combine_region_w, 4, 0, 0, H_gdk_window_shape_combine_region, pl_tuui); Xg_define_procedure(gdk_window_invalidate_region, gxg_gdk_window_invalidate_region_w, 3, 0, 0, H_gdk_window_invalidate_region, pl_tuub); Xg_define_procedure(gdk_window_get_update_area, gxg_gdk_window_get_update_area_w, 1, 0, 0, H_gdk_window_get_update_area, pl_pu); Xg_define_procedure(gdk_window_begin_paint_region, gxg_gdk_window_begin_paint_region_w, 2, 0, 0, H_gdk_window_begin_paint_region, pl_tu); Xg_define_procedure(gdk_window_move_region, gxg_gdk_window_move_region_w, 4, 0, 0, H_gdk_window_move_region, pl_tuui); Xg_define_procedure(gdk_keymap_get_num_lock_state, gxg_gdk_keymap_get_num_lock_state_w, 1, 0, 0, H_gdk_keymap_get_num_lock_state, pl_bu); Xg_define_procedure(gdk_window_has_native, gxg_gdk_window_has_native_w, 1, 0, 0, H_gdk_window_has_native, pl_bu); Xg_define_procedure(gdk_cursor_get_cursor_type, gxg_gdk_cursor_get_cursor_type_w, 1, 0, 0, H_gdk_cursor_get_cursor_type, pl_iu); Xg_define_procedure(gdk_display_is_closed, gxg_gdk_display_is_closed_w, 1, 0, 0, H_gdk_display_is_closed, pl_bu); Xg_define_procedure(gdk_window_get_background_pattern, gxg_gdk_window_get_background_pattern_w, 1, 0, 0, H_gdk_window_get_background_pattern, pl_pu); Xg_define_procedure(gdk_window_create_similar_surface, gxg_gdk_window_create_similar_surface_w, 4, 0, 0, H_gdk_window_create_similar_surface, pl_pui); Xg_define_procedure(gtk_expander_set_label_fill, gxg_gtk_expander_set_label_fill_w, 2, 0, 0, H_gtk_expander_set_label_fill, pl_tub); Xg_define_procedure(gtk_expander_get_label_fill, gxg_gtk_expander_get_label_fill_w, 1, 0, 0, H_gtk_expander_get_label_fill, pl_bu); Xg_define_procedure(gtk_calendar_get_day_is_marked, gxg_gtk_calendar_get_day_is_marked_w, 2, 0, 0, H_gtk_calendar_get_day_is_marked, pl_bui); Xg_define_procedure(gtk_progress_bar_set_inverted, gxg_gtk_progress_bar_set_inverted_w, 2, 0, 0, H_gtk_progress_bar_set_inverted, pl_tub); Xg_define_procedure(gtk_progress_bar_get_inverted, gxg_gtk_progress_bar_get_inverted_w, 1, 0, 0, H_gtk_progress_bar_get_inverted, pl_bu); Xg_define_procedure(gtk_radio_button_join_group, gxg_gtk_radio_button_join_group_w, 2, 0, 0, H_gtk_radio_button_join_group, pl_tu); Xg_define_procedure(gtk_adjustment_new, gxg_gtk_adjustment_new_w, 6, 0, 0, H_gtk_adjustment_new, pl_pr); Xg_define_procedure(gtk_binding_set_activate, gxg_gtk_binding_set_activate_w, 4, 0, 0, H_gtk_binding_set_activate, pl_buiiu); Xg_define_procedure(gtk_bindings_activate, gxg_gtk_bindings_activate_w, 3, 0, 0, H_gtk_bindings_activate, pl_bui); Xg_define_procedure(gtk_icon_view_create_drag_icon, gxg_gtk_icon_view_create_drag_icon_w, 2, 0, 0, H_gtk_icon_view_create_drag_icon, pl_pu); Xg_define_procedure(gtk_tree_view_create_row_drag_icon, gxg_gtk_tree_view_create_row_drag_icon_w, 2, 0, 0, H_gtk_tree_view_create_row_drag_icon, pl_pu); Xg_define_procedure(gdk_cairo_get_clip_rectangle, gxg_gdk_cairo_get_clip_rectangle_w, 2, 0, 0, H_gdk_cairo_get_clip_rectangle, pl_bu); Xg_define_procedure(gdk_cairo_region_create_from_surface, gxg_gdk_cairo_region_create_from_surface_w, 1, 0, 0, H_gdk_cairo_region_create_from_surface, pl_pu); Xg_define_procedure(gdk_window_get_visual, gxg_gdk_window_get_visual_w, 1, 0, 0, H_gdk_window_get_visual, pl_pu); Xg_define_procedure(gdk_window_get_screen, gxg_gdk_window_get_screen_w, 1, 0, 0, H_gdk_window_get_screen, pl_pu); Xg_define_procedure(gdk_window_get_display, gxg_gdk_window_get_display_w, 1, 0, 0, H_gdk_window_get_display, pl_pu); Xg_define_procedure(gdk_window_get_width, gxg_gdk_window_get_width_w, 1, 0, 0, H_gdk_window_get_width, pl_iu); Xg_define_procedure(gdk_window_get_height, gxg_gdk_window_get_height_w, 1, 0, 0, H_gdk_window_get_height, pl_iu); Xg_define_procedure(gtk_cell_renderer_get_request_mode, gxg_gtk_cell_renderer_get_request_mode_w, 1, 0, 0, H_gtk_cell_renderer_get_request_mode, pl_iu); Xg_define_procedure(gtk_cell_renderer_get_preferred_width, gxg_gtk_cell_renderer_get_preferred_width_w, 2, 2, 0, H_gtk_cell_renderer_get_preferred_width, pl_tu); Xg_define_procedure(gtk_cell_renderer_get_preferred_height_for_width, gxg_gtk_cell_renderer_get_preferred_height_for_width_w, 3, 2, 0, H_gtk_cell_renderer_get_preferred_height_for_width, pl_tuuiu); Xg_define_procedure(gtk_cell_renderer_get_preferred_height, gxg_gtk_cell_renderer_get_preferred_height_w, 2, 2, 0, H_gtk_cell_renderer_get_preferred_height, pl_tu); Xg_define_procedure(gtk_cell_renderer_get_preferred_width_for_height, gxg_gtk_cell_renderer_get_preferred_width_for_height_w, 3, 2, 0, H_gtk_cell_renderer_get_preferred_width_for_height, pl_tuuiu); Xg_define_procedure(gtk_container_class_handle_border_width, gxg_gtk_container_class_handle_border_width_w, 1, 0, 0, H_gtk_container_class_handle_border_width, pl_tu); Xg_define_procedure(gtk_drag_set_icon_surface, gxg_gtk_drag_set_icon_surface_w, 2, 0, 0, H_gtk_drag_set_icon_surface, pl_tu); Xg_define_procedure(gtk_notebook_set_group_name, gxg_gtk_notebook_set_group_name_w, 2, 0, 0, H_gtk_notebook_set_group_name, pl_tus); Xg_define_procedure(gtk_notebook_get_group_name, gxg_gtk_notebook_get_group_name_w, 1, 0, 0, H_gtk_notebook_get_group_name, pl_su); Xg_define_procedure(gtk_widget_draw, gxg_gtk_widget_draw_w, 2, 0, 0, H_gtk_widget_draw, pl_tu); Xg_define_procedure(gtk_widget_get_request_mode, gxg_gtk_widget_get_request_mode_w, 1, 0, 0, H_gtk_widget_get_request_mode, pl_iu); Xg_define_procedure(gtk_widget_get_preferred_width, gxg_gtk_widget_get_preferred_width_w, 1, 2, 0, H_gtk_widget_get_preferred_width, pl_tu); Xg_define_procedure(gtk_widget_get_preferred_height_for_width, gxg_gtk_widget_get_preferred_height_for_width_w, 2, 2, 0, H_gtk_widget_get_preferred_height_for_width, pl_tuiu); Xg_define_procedure(gtk_widget_get_preferred_height, gxg_gtk_widget_get_preferred_height_w, 1, 2, 0, H_gtk_widget_get_preferred_height, pl_tu); Xg_define_procedure(gtk_widget_get_preferred_width_for_height, gxg_gtk_widget_get_preferred_width_for_height_w, 2, 2, 0, H_gtk_widget_get_preferred_width_for_height, pl_tuiu); Xg_define_procedure(gtk_widget_get_allocated_width, gxg_gtk_widget_get_allocated_width_w, 1, 0, 0, H_gtk_widget_get_allocated_width, pl_iu); Xg_define_procedure(gtk_widget_get_allocated_height, gxg_gtk_widget_get_allocated_height_w, 1, 0, 0, H_gtk_widget_get_allocated_height, pl_iu); Xg_define_procedure(gtk_widget_set_visual, gxg_gtk_widget_set_visual_w, 2, 0, 0, H_gtk_widget_set_visual, pl_tu); Xg_define_procedure(gtk_widget_get_halign, gxg_gtk_widget_get_halign_w, 1, 0, 0, H_gtk_widget_get_halign, pl_iu); Xg_define_procedure(gtk_widget_set_halign, gxg_gtk_widget_set_halign_w, 2, 0, 0, H_gtk_widget_set_halign, pl_tui); Xg_define_procedure(gtk_widget_get_valign, gxg_gtk_widget_get_valign_w, 1, 0, 0, H_gtk_widget_get_valign, pl_iu); Xg_define_procedure(gtk_widget_set_valign, gxg_gtk_widget_set_valign_w, 2, 0, 0, H_gtk_widget_set_valign, pl_tui); Xg_define_procedure(gtk_widget_get_margin_top, gxg_gtk_widget_get_margin_top_w, 1, 0, 0, H_gtk_widget_get_margin_top, pl_iu); Xg_define_procedure(gtk_widget_set_margin_top, gxg_gtk_widget_set_margin_top_w, 2, 0, 0, H_gtk_widget_set_margin_top, pl_tui); Xg_define_procedure(gtk_widget_get_margin_bottom, gxg_gtk_widget_get_margin_bottom_w, 1, 0, 0, H_gtk_widget_get_margin_bottom, pl_iu); Xg_define_procedure(gtk_widget_set_margin_bottom, gxg_gtk_widget_set_margin_bottom_w, 2, 0, 0, H_gtk_widget_set_margin_bottom, pl_tui); Xg_define_procedure(gtk_widget_shape_combine_region, gxg_gtk_widget_shape_combine_region_w, 2, 0, 0, H_gtk_widget_shape_combine_region, pl_tu); Xg_define_procedure(gtk_widget_input_shape_combine_region, gxg_gtk_widget_input_shape_combine_region_w, 2, 0, 0, H_gtk_widget_input_shape_combine_region, pl_tu); Xg_define_procedure(gtk_cairo_should_draw_window, gxg_gtk_cairo_should_draw_window_w, 2, 0, 0, H_gtk_cairo_should_draw_window, pl_bu); Xg_define_procedure(gtk_cairo_transform_to_window, gxg_gtk_cairo_transform_to_window_w, 3, 0, 0, H_gtk_cairo_transform_to_window, pl_tu); Xg_define_procedure(gtk_combo_box_new_with_entry, gxg_gtk_combo_box_new_with_entry_w, 0, 0, 0, H_gtk_combo_box_new_with_entry, pl_p); Xg_define_procedure(gtk_combo_box_get_has_entry, gxg_gtk_combo_box_get_has_entry_w, 1, 0, 0, H_gtk_combo_box_get_has_entry, pl_bu); Xg_define_procedure(gtk_combo_box_set_entry_text_column, gxg_gtk_combo_box_set_entry_text_column_w, 2, 0, 0, H_gtk_combo_box_set_entry_text_column, pl_tui); Xg_define_procedure(gtk_combo_box_get_entry_text_column, gxg_gtk_combo_box_get_entry_text_column_w, 1, 0, 0, H_gtk_combo_box_get_entry_text_column, pl_iu); Xg_define_procedure(gtk_target_entry_new, gxg_gtk_target_entry_new_w, 3, 0, 0, H_gtk_target_entry_new, pl_psi); Xg_define_procedure(gtk_target_entry_copy, gxg_gtk_target_entry_copy_w, 1, 0, 0, H_gtk_target_entry_copy, pl_pu); Xg_define_procedure(gtk_target_entry_free, gxg_gtk_target_entry_free_w, 1, 0, 0, H_gtk_target_entry_free, pl_tu); Xg_define_procedure(gtk_widget_get_hexpand, gxg_gtk_widget_get_hexpand_w, 1, 0, 0, H_gtk_widget_get_hexpand, pl_bu); Xg_define_procedure(gtk_widget_set_hexpand, gxg_gtk_widget_set_hexpand_w, 2, 0, 0, H_gtk_widget_set_hexpand, pl_tub); Xg_define_procedure(gtk_widget_get_hexpand_set, gxg_gtk_widget_get_hexpand_set_w, 1, 0, 0, H_gtk_widget_get_hexpand_set, pl_bu); Xg_define_procedure(gtk_widget_set_hexpand_set, gxg_gtk_widget_set_hexpand_set_w, 2, 0, 0, H_gtk_widget_set_hexpand_set, pl_tub); Xg_define_procedure(gtk_widget_get_vexpand, gxg_gtk_widget_get_vexpand_w, 1, 0, 0, H_gtk_widget_get_vexpand, pl_bu); Xg_define_procedure(gtk_widget_set_vexpand, gxg_gtk_widget_set_vexpand_w, 2, 0, 0, H_gtk_widget_set_vexpand, pl_tub); Xg_define_procedure(gtk_widget_get_vexpand_set, gxg_gtk_widget_get_vexpand_set_w, 1, 0, 0, H_gtk_widget_get_vexpand_set, pl_bu); Xg_define_procedure(gtk_widget_set_vexpand_set, gxg_gtk_widget_set_vexpand_set_w, 2, 0, 0, H_gtk_widget_set_vexpand_set, pl_tub); Xg_define_procedure(gtk_widget_queue_compute_expand, gxg_gtk_widget_queue_compute_expand_w, 1, 0, 0, H_gtk_widget_queue_compute_expand, pl_tu); Xg_define_procedure(gtk_widget_compute_expand, gxg_gtk_widget_compute_expand_w, 2, 0, 0, H_gtk_widget_compute_expand, pl_bui); Xg_define_procedure(gtk_window_set_default_geometry, gxg_gtk_window_set_default_geometry_w, 3, 0, 0, H_gtk_window_set_default_geometry, pl_tui); Xg_define_procedure(gtk_window_resize_to_geometry, gxg_gtk_window_resize_to_geometry_w, 3, 0, 0, H_gtk_window_resize_to_geometry, pl_tui); Xg_define_procedure(gtk_combo_box_text_new, gxg_gtk_combo_box_text_new_w, 0, 0, 0, H_gtk_combo_box_text_new, pl_p); Xg_define_procedure(gtk_combo_box_text_new_with_entry, gxg_gtk_combo_box_text_new_with_entry_w, 0, 0, 0, H_gtk_combo_box_text_new_with_entry, pl_p); Xg_define_procedure(gtk_combo_box_text_append_text, gxg_gtk_combo_box_text_append_text_w, 2, 0, 0, H_gtk_combo_box_text_append_text, pl_tus); Xg_define_procedure(gtk_combo_box_text_insert_text, gxg_gtk_combo_box_text_insert_text_w, 3, 0, 0, H_gtk_combo_box_text_insert_text, pl_tuis); Xg_define_procedure(gtk_combo_box_text_prepend_text, gxg_gtk_combo_box_text_prepend_text_w, 2, 0, 0, H_gtk_combo_box_text_prepend_text, pl_tus); Xg_define_procedure(gtk_combo_box_text_remove, gxg_gtk_combo_box_text_remove_w, 2, 0, 0, H_gtk_combo_box_text_remove, pl_tui); Xg_define_procedure(gtk_combo_box_text_get_active_text, gxg_gtk_combo_box_text_get_active_text_w, 1, 0, 0, H_gtk_combo_box_text_get_active_text, pl_su); Xg_define_procedure(gdk_cairo_set_source_rgba, gxg_gdk_cairo_set_source_rgba_w, 2, 0, 0, H_gdk_cairo_set_source_rgba, pl_tu); Xg_define_procedure(gdk_window_set_background_rgba, gxg_gdk_window_set_background_rgba_w, 2, 0, 0, H_gdk_window_set_background_rgba, pl_tu); Xg_define_procedure(gtk_cell_view_set_background_rgba, gxg_gtk_cell_view_set_background_rgba_w, 2, 0, 0, H_gtk_cell_view_set_background_rgba, pl_tu); Xg_define_procedure(gtk_combo_box_text_remove_all, gxg_gtk_combo_box_text_remove_all_w, 1, 0, 0, H_gtk_combo_box_text_remove_all, pl_tu); Xg_define_procedure(gtk_combo_box_set_popup_fixed_width, gxg_gtk_combo_box_set_popup_fixed_width_w, 2, 0, 0, H_gtk_combo_box_set_popup_fixed_width, pl_tub); Xg_define_procedure(gtk_combo_box_get_popup_fixed_width, gxg_gtk_combo_box_get_popup_fixed_width_w, 1, 0, 0, H_gtk_combo_box_get_popup_fixed_width, pl_bu); Xg_define_procedure(gtk_scrolled_window_get_min_content_width, gxg_gtk_scrolled_window_get_min_content_width_w, 1, 0, 0, H_gtk_scrolled_window_get_min_content_width, pl_iu); Xg_define_procedure(gtk_scrolled_window_set_min_content_width, gxg_gtk_scrolled_window_set_min_content_width_w, 2, 0, 0, H_gtk_scrolled_window_set_min_content_width, pl_tui); Xg_define_procedure(gtk_scrolled_window_get_min_content_height, gxg_gtk_scrolled_window_get_min_content_height_w, 1, 0, 0, H_gtk_scrolled_window_get_min_content_height, pl_iu); Xg_define_procedure(gtk_scrolled_window_set_min_content_height, gxg_gtk_scrolled_window_set_min_content_height_w, 2, 0, 0, H_gtk_scrolled_window_set_min_content_height, pl_tui); Xg_define_procedure(gtk_grid_new, gxg_gtk_grid_new_w, 0, 0, 0, H_gtk_grid_new, pl_p); Xg_define_procedure(gtk_grid_attach, gxg_gtk_grid_attach_w, 6, 0, 0, H_gtk_grid_attach, pl_tuui); Xg_define_procedure(gtk_grid_attach_next_to, gxg_gtk_grid_attach_next_to_w, 6, 0, 0, H_gtk_grid_attach_next_to, pl_tuuui); Xg_define_procedure(gtk_grid_set_row_homogeneous, gxg_gtk_grid_set_row_homogeneous_w, 2, 0, 0, H_gtk_grid_set_row_homogeneous, pl_tub); Xg_define_procedure(gtk_grid_get_row_homogeneous, gxg_gtk_grid_get_row_homogeneous_w, 1, 0, 0, H_gtk_grid_get_row_homogeneous, pl_bu); Xg_define_procedure(gtk_grid_set_row_spacing, gxg_gtk_grid_set_row_spacing_w, 2, 0, 0, H_gtk_grid_set_row_spacing, pl_tui); Xg_define_procedure(gtk_grid_get_row_spacing, gxg_gtk_grid_get_row_spacing_w, 1, 0, 0, H_gtk_grid_get_row_spacing, pl_iu); Xg_define_procedure(gtk_grid_set_column_homogeneous, gxg_gtk_grid_set_column_homogeneous_w, 2, 0, 0, H_gtk_grid_set_column_homogeneous, pl_tub); Xg_define_procedure(gtk_grid_get_column_homogeneous, gxg_gtk_grid_get_column_homogeneous_w, 1, 0, 0, H_gtk_grid_get_column_homogeneous, pl_bu); Xg_define_procedure(gtk_grid_set_column_spacing, gxg_gtk_grid_set_column_spacing_w, 2, 0, 0, H_gtk_grid_set_column_spacing, pl_tui); Xg_define_procedure(gtk_grid_get_column_spacing, gxg_gtk_grid_get_column_spacing_w, 1, 0, 0, H_gtk_grid_get_column_spacing, pl_iu); Xg_define_procedure(gtk_scrollable_get_hadjustment, gxg_gtk_scrollable_get_hadjustment_w, 1, 0, 0, H_gtk_scrollable_get_hadjustment, pl_pu); Xg_define_procedure(gtk_scrollable_set_hadjustment, gxg_gtk_scrollable_set_hadjustment_w, 2, 0, 0, H_gtk_scrollable_set_hadjustment, pl_tu); Xg_define_procedure(gtk_scrollable_get_vadjustment, gxg_gtk_scrollable_get_vadjustment_w, 1, 0, 0, H_gtk_scrollable_get_vadjustment, pl_pu); Xg_define_procedure(gtk_scrollable_set_vadjustment, gxg_gtk_scrollable_set_vadjustment_w, 2, 0, 0, H_gtk_scrollable_set_vadjustment, pl_tu); Xg_define_procedure(gtk_assistant_next_page, gxg_gtk_assistant_next_page_w, 1, 0, 0, H_gtk_assistant_next_page, pl_tu); Xg_define_procedure(gtk_assistant_previous_page, gxg_gtk_assistant_previous_page_w, 1, 0, 0, H_gtk_assistant_previous_page, pl_tu); Xg_define_procedure(gtk_combo_box_new_with_model_and_entry, gxg_gtk_combo_box_new_with_model_and_entry_w, 1, 0, 0, H_gtk_combo_box_new_with_model_and_entry, pl_pu); Xg_define_procedure(gtk_scrollable_get_hscroll_policy, gxg_gtk_scrollable_get_hscroll_policy_w, 1, 0, 0, H_gtk_scrollable_get_hscroll_policy, pl_iu); Xg_define_procedure(gtk_scrollable_set_hscroll_policy, gxg_gtk_scrollable_set_hscroll_policy_w, 2, 0, 0, H_gtk_scrollable_set_hscroll_policy, pl_tui); Xg_define_procedure(gtk_scrollable_get_vscroll_policy, gxg_gtk_scrollable_get_vscroll_policy_w, 1, 0, 0, H_gtk_scrollable_get_vscroll_policy, pl_iu); Xg_define_procedure(gtk_scrollable_set_vscroll_policy, gxg_gtk_scrollable_set_vscroll_policy_w, 2, 0, 0, H_gtk_scrollable_set_vscroll_policy, pl_tui); Xg_define_procedure(gtk_switch_new, gxg_gtk_switch_new_w, 0, 0, 0, H_gtk_switch_new, pl_p); Xg_define_procedure(gtk_switch_set_active, gxg_gtk_switch_set_active_w, 2, 0, 0, H_gtk_switch_set_active, pl_tub); Xg_define_procedure(gtk_switch_get_active, gxg_gtk_switch_get_active_w, 1, 0, 0, H_gtk_switch_get_active, pl_bu); Xg_define_procedure(gdk_window_get_clip_region, gxg_gdk_window_get_clip_region_w, 1, 0, 0, H_gdk_window_get_clip_region, pl_pu); Xg_define_procedure(gdk_window_get_visible_region, gxg_gdk_window_get_visible_region_w, 1, 0, 0, H_gdk_window_get_visible_region, pl_pu); Xg_define_procedure(gtk_border_new, gxg_gtk_border_new_w, 0, 0, 0, H_gtk_border_new, pl_p); Xg_define_procedure(gtk_border_copy, gxg_gtk_border_copy_w, 1, 0, 0, H_gtk_border_copy, pl_pu); Xg_define_procedure(gtk_border_free, gxg_gtk_border_free_w, 1, 0, 0, H_gtk_border_free, pl_tu); Xg_define_procedure(gtk_combo_box_get_id_column, gxg_gtk_combo_box_get_id_column_w, 1, 0, 0, H_gtk_combo_box_get_id_column, pl_iu); Xg_define_procedure(gtk_combo_box_set_id_column, gxg_gtk_combo_box_set_id_column_w, 2, 0, 0, H_gtk_combo_box_set_id_column, pl_tui); Xg_define_procedure(gtk_combo_box_get_active_id, gxg_gtk_combo_box_get_active_id_w, 1, 0, 0, H_gtk_combo_box_get_active_id, pl_su); Xg_define_procedure(gtk_combo_box_text_insert, gxg_gtk_combo_box_text_insert_w, 4, 0, 0, H_gtk_combo_box_text_insert, pl_tuis); Xg_define_procedure(gtk_combo_box_text_append, gxg_gtk_combo_box_text_append_w, 3, 0, 0, H_gtk_combo_box_text_append, pl_tus); Xg_define_procedure(gtk_combo_box_text_prepend, gxg_gtk_combo_box_text_prepend_w, 3, 0, 0, H_gtk_combo_box_text_prepend, pl_tus); Xg_define_procedure(gtk_button_box_new, gxg_gtk_button_box_new_w, 1, 0, 0, H_gtk_button_box_new, pl_pi); Xg_define_procedure(gtk_box_new, gxg_gtk_box_new_w, 2, 0, 0, H_gtk_box_new, pl_pi); Xg_define_procedure(gtk_tree_view_set_cursor_on_cell, gxg_gtk_tree_view_set_cursor_on_cell_w, 5, 0, 0, H_gtk_tree_view_set_cursor_on_cell, pl_tuuuub); Xg_define_procedure(gtk_tree_view_set_rubber_banding, gxg_gtk_tree_view_set_rubber_banding_w, 2, 0, 0, H_gtk_tree_view_set_rubber_banding, pl_tub); Xg_define_procedure(gtk_tree_view_get_rubber_banding, gxg_gtk_tree_view_get_rubber_banding_w, 1, 0, 0, H_gtk_tree_view_get_rubber_banding, pl_bu); Xg_define_procedure(gtk_tooltip_set_markup, gxg_gtk_tooltip_set_markup_w, 2, 0, 0, H_gtk_tooltip_set_markup, pl_tus); Xg_define_procedure(gtk_tooltip_set_icon, gxg_gtk_tooltip_set_icon_w, 2, 0, 0, H_gtk_tooltip_set_icon, pl_tu); Xg_define_procedure(gtk_tooltip_set_custom, gxg_gtk_tooltip_set_custom_w, 2, 0, 0, H_gtk_tooltip_set_custom, pl_tu); Xg_define_procedure(gtk_tooltip_trigger_tooltip_query, gxg_gtk_tooltip_trigger_tooltip_query_w, 1, 0, 0, H_gtk_tooltip_trigger_tooltip_query, pl_tu); Xg_define_procedure(gtk_button_set_image_position, gxg_gtk_button_set_image_position_w, 2, 0, 0, H_gtk_button_set_image_position, pl_tui); Xg_define_procedure(gtk_button_get_image_position, gxg_gtk_button_get_image_position_w, 1, 0, 0, H_gtk_button_get_image_position, pl_iu); Xg_define_procedure(gtk_show_uri, gxg_gtk_show_uri_w, 3, 1, 0, H_gtk_show_uri, pl_busiu); Xg_define_procedure(gtk_tree_view_column_new_with_area, gxg_gtk_tree_view_column_new_with_area_w, 1, 0, 0, H_gtk_tree_view_column_new_with_area, pl_pu); Xg_define_procedure(gtk_tree_view_column_get_button, gxg_gtk_tree_view_column_get_button_w, 1, 0, 0, H_gtk_tree_view_column_get_button, pl_pu); Xg_define_procedure(gtk_tree_view_column_focus_cell, gxg_gtk_tree_view_column_focus_cell_w, 2, 0, 0, H_gtk_tree_view_column_focus_cell, pl_tu); Xg_define_procedure(gtk_clipboard_wait_is_uris_available, gxg_gtk_clipboard_wait_is_uris_available_w, 1, 0, 0, H_gtk_clipboard_wait_is_uris_available, pl_bu); Xg_define_procedure(gtk_toolbar_set_drop_highlight_item, gxg_gtk_toolbar_set_drop_highlight_item_w, 3, 0, 0, H_gtk_toolbar_set_drop_highlight_item, pl_tuui); Xg_define_procedure(gtk_tool_item_toolbar_reconfigured, gxg_gtk_tool_item_toolbar_reconfigured_w, 1, 0, 0, H_gtk_tool_item_toolbar_reconfigured, pl_tu); Xg_define_procedure(gtk_orientable_set_orientation, gxg_gtk_orientable_set_orientation_w, 2, 0, 0, H_gtk_orientable_set_orientation, pl_tui); Xg_define_procedure(gtk_orientable_get_orientation, gxg_gtk_orientable_get_orientation_w, 1, 0, 0, H_gtk_orientable_get_orientation, pl_iu); Xg_define_procedure(gtk_parse_args, gxg_gtk_parse_args_w, 0, 2, 0, H_gtk_parse_args, pl_tu); Xg_define_procedure(gtk_get_major_version, gxg_gtk_get_major_version_w, 0, 0, 0, H_gtk_get_major_version, pl_i); Xg_define_procedure(gtk_get_minor_version, gxg_gtk_get_minor_version_w, 0, 0, 0, H_gtk_get_minor_version, pl_i); Xg_define_procedure(gtk_get_micro_version, gxg_gtk_get_micro_version_w, 0, 0, 0, H_gtk_get_micro_version, pl_i); Xg_define_procedure(gtk_get_binary_age, gxg_gtk_get_binary_age_w, 0, 0, 0, H_gtk_get_binary_age, pl_i); Xg_define_procedure(gtk_get_interface_age, gxg_gtk_get_interface_age_w, 0, 0, 0, H_gtk_get_interface_age, pl_i); Xg_define_procedure(gtk_progress_bar_set_show_text, gxg_gtk_progress_bar_set_show_text_w, 2, 0, 0, H_gtk_progress_bar_set_show_text, pl_tub); Xg_define_procedure(gtk_progress_bar_get_show_text, gxg_gtk_progress_bar_get_show_text_w, 1, 0, 0, H_gtk_progress_bar_get_show_text, pl_bu); Xg_define_procedure(gtk_invisible_new_for_screen, gxg_gtk_invisible_new_for_screen_w, 1, 0, 0, H_gtk_invisible_new_for_screen, pl_pu); Xg_define_procedure(gtk_invisible_set_screen, gxg_gtk_invisible_set_screen_w, 2, 0, 0, H_gtk_invisible_set_screen, pl_tu); Xg_define_procedure(gtk_invisible_get_screen, gxg_gtk_invisible_get_screen_w, 1, 0, 0, H_gtk_invisible_get_screen, pl_pu); Xg_define_procedure(gtk_entry_get_icon_storage_type, gxg_gtk_entry_get_icon_storage_type_w, 2, 0, 0, H_gtk_entry_get_icon_storage_type, pl_iui); Xg_define_procedure(gtk_entry_get_icon_pixbuf, gxg_gtk_entry_get_icon_pixbuf_w, 2, 0, 0, H_gtk_entry_get_icon_pixbuf, pl_pui); Xg_define_procedure(gtk_entry_get_icon_gicon, gxg_gtk_entry_get_icon_gicon_w, 2, 0, 0, H_gtk_entry_get_icon_gicon, pl_pui); Xg_define_procedure(gtk_container_propagate_draw, gxg_gtk_container_propagate_draw_w, 3, 0, 0, H_gtk_container_propagate_draw, pl_tu); Xg_define_procedure(gtk_container_set_focus_chain, gxg_gtk_container_set_focus_chain_w, 2, 0, 0, H_gtk_container_set_focus_chain, pl_tu); Xg_define_procedure(gtk_container_get_focus_chain, gxg_gtk_container_get_focus_chain_w, 1, 1, 0, H_gtk_container_get_focus_chain, pl_bu); Xg_define_procedure(gtk_container_unset_focus_chain, gxg_gtk_container_unset_focus_chain_w, 1, 0, 0, H_gtk_container_unset_focus_chain, pl_tu); Xg_define_procedure(gtk_container_set_focus_child, gxg_gtk_container_set_focus_child_w, 2, 0, 0, H_gtk_container_set_focus_child, pl_tu); Xg_define_procedure(gtk_container_set_focus_vadjustment, gxg_gtk_container_set_focus_vadjustment_w, 2, 0, 0, H_gtk_container_set_focus_vadjustment, pl_tu); Xg_define_procedure(gtk_container_get_focus_vadjustment, gxg_gtk_container_get_focus_vadjustment_w, 1, 0, 0, H_gtk_container_get_focus_vadjustment, pl_pu); Xg_define_procedure(gtk_container_set_focus_hadjustment, gxg_gtk_container_set_focus_hadjustment_w, 2, 0, 0, H_gtk_container_set_focus_hadjustment, pl_tu); Xg_define_procedure(gtk_container_get_focus_hadjustment, gxg_gtk_container_get_focus_hadjustment_w, 1, 0, 0, H_gtk_container_get_focus_hadjustment, pl_pu); Xg_define_procedure(gtk_assistant_commit, gxg_gtk_assistant_commit_w, 1, 0, 0, H_gtk_assistant_commit, pl_tu); Xg_define_procedure(gtk_window_set_skip_taskbar_hint, gxg_gtk_window_set_skip_taskbar_hint_w, 2, 0, 0, H_gtk_window_set_skip_taskbar_hint, pl_tub); Xg_define_procedure(gtk_window_get_skip_taskbar_hint, gxg_gtk_window_get_skip_taskbar_hint_w, 1, 0, 0, H_gtk_window_get_skip_taskbar_hint, pl_bu); Xg_define_procedure(gtk_window_set_skip_pager_hint, gxg_gtk_window_set_skip_pager_hint_w, 2, 0, 0, H_gtk_window_set_skip_pager_hint, pl_tub); Xg_define_procedure(gtk_window_get_skip_pager_hint, gxg_gtk_window_get_skip_pager_hint_w, 1, 0, 0, H_gtk_window_get_skip_pager_hint, pl_bu); Xg_define_procedure(gtk_window_set_screen, gxg_gtk_window_set_screen_w, 2, 0, 0, H_gtk_window_set_screen, pl_tu); Xg_define_procedure(gtk_window_get_screen, gxg_gtk_window_get_screen_w, 1, 0, 0, H_gtk_window_get_screen, pl_pu); Xg_define_procedure(gtk_window_set_icon_from_file, gxg_gtk_window_set_icon_from_file_w, 2, 1, 0, H_gtk_window_set_icon_from_file, pl_busu); Xg_define_procedure(gtk_window_set_default_icon_from_file, gxg_gtk_window_set_default_icon_from_file_w, 1, 1, 0, H_gtk_window_set_default_icon_from_file, pl_bsu); Xg_define_procedure(gtk_window_fullscreen, gxg_gtk_window_fullscreen_w, 1, 0, 0, H_gtk_window_fullscreen, pl_tu); Xg_define_procedure(gtk_window_unfullscreen, gxg_gtk_window_unfullscreen_w, 1, 0, 0, H_gtk_window_unfullscreen, pl_tu); Xg_define_procedure(gtk_window_get_window_type, gxg_gtk_window_get_window_type_w, 1, 0, 0, H_gtk_window_get_window_type, pl_iu); Xg_define_procedure(gtk_window_group_add_window, gxg_gtk_window_group_add_window_w, 2, 0, 0, H_gtk_window_group_add_window, pl_tu); Xg_define_procedure(gtk_window_group_remove_window, gxg_gtk_window_group_remove_window_w, 2, 0, 0, H_gtk_window_group_remove_window, pl_tu); Xg_define_procedure(gtk_window_group_new, gxg_gtk_window_group_new_w, 0, 0, 0, H_gtk_window_group_new, pl_p); Xg_define_procedure(gtk_window_get_group, gxg_gtk_window_get_group_w, 1, 0, 0, H_gtk_window_get_group, pl_pu); Xg_define_procedure(gtk_window_group_list_windows, gxg_gtk_window_group_list_windows_w, 1, 0, 0, H_gtk_window_group_list_windows, pl_pu); Xg_define_procedure(gtk_window_group_get_current_device_grab, gxg_gtk_window_group_get_current_device_grab_w, 2, 0, 0, H_gtk_window_group_get_current_device_grab, pl_pu); Xg_define_procedure(gtk_window_group_get_current_grab, gxg_gtk_window_group_get_current_grab_w, 1, 0, 0, H_gtk_window_group_get_current_grab, pl_pu); Xg_define_procedure(gtk_selection_data_get_data, gxg_gtk_selection_data_get_data_w, 1, 0, 0, H_gtk_selection_data_get_data, pl_su); Xg_define_procedure(gtk_selection_owner_set_for_display, gxg_gtk_selection_owner_set_for_display_w, 4, 0, 0, H_gtk_selection_owner_set_for_display, pl_buuti); Xg_define_procedure(gtk_tool_shell_get_text_orientation, gxg_gtk_tool_shell_get_text_orientation_w, 1, 0, 0, H_gtk_tool_shell_get_text_orientation, pl_iu); Xg_define_procedure(gtk_tool_shell_get_text_alignment, gxg_gtk_tool_shell_get_text_alignment_w, 1, 0, 0, H_gtk_tool_shell_get_text_alignment, pl_du); Xg_define_procedure(gtk_tool_shell_get_ellipsize_mode, gxg_gtk_tool_shell_get_ellipsize_mode_w, 1, 0, 0, H_gtk_tool_shell_get_ellipsize_mode, pl_iu); Xg_define_procedure(gtk_tool_shell_get_text_size_group, gxg_gtk_tool_shell_get_text_size_group_w, 1, 0, 0, H_gtk_tool_shell_get_text_size_group, pl_pu); Xg_define_procedure(gtk_tool_shell_get_orientation, gxg_gtk_tool_shell_get_orientation_w, 1, 0, 0, H_gtk_tool_shell_get_orientation, pl_iu); Xg_define_procedure(gtk_tool_shell_get_style, gxg_gtk_tool_shell_get_style_w, 1, 0, 0, H_gtk_tool_shell_get_style, pl_iu); Xg_define_procedure(gtk_tool_shell_get_relief_style, gxg_gtk_tool_shell_get_relief_style_w, 1, 0, 0, H_gtk_tool_shell_get_relief_style, pl_iu); Xg_define_procedure(gtk_tool_shell_rebuild_menu, gxg_gtk_tool_shell_rebuild_menu_w, 1, 0, 0, H_gtk_tool_shell_rebuild_menu, pl_tu); Xg_define_procedure(gtk_accel_map_lock_path, gxg_gtk_accel_map_lock_path_w, 1, 0, 0, H_gtk_accel_map_lock_path, pl_ts); Xg_define_procedure(gtk_accel_map_unlock_path, gxg_gtk_accel_map_unlock_path_w, 1, 0, 0, H_gtk_accel_map_unlock_path, pl_ts); Xg_define_procedure(gtk_icon_theme_lookup_by_gicon, gxg_gtk_icon_theme_lookup_by_gicon_w, 4, 0, 0, H_gtk_icon_theme_lookup_by_gicon, pl_puui); Xg_define_procedure(gtk_icon_info_new_for_pixbuf, gxg_gtk_icon_info_new_for_pixbuf_w, 2, 0, 0, H_gtk_icon_info_new_for_pixbuf, pl_pu); Xg_define_procedure(gtk_icon_view_set_item_orientation, gxg_gtk_icon_view_set_item_orientation_w, 2, 0, 0, H_gtk_icon_view_set_item_orientation, pl_tui); Xg_define_procedure(gtk_icon_view_get_item_orientation, gxg_gtk_icon_view_get_item_orientation_w, 1, 0, 0, H_gtk_icon_view_get_item_orientation, pl_iu); Xg_define_procedure(gtk_text_view_im_context_filter_keypress, gxg_gtk_text_view_im_context_filter_keypress_w, 2, 0, 0, H_gtk_text_view_im_context_filter_keypress, pl_bu); Xg_define_procedure(gtk_text_view_reset_im_context, gxg_gtk_text_view_reset_im_context_w, 1, 0, 0, H_gtk_text_view_reset_im_context, pl_tu); Xg_define_procedure(gdk_device_get_position, gxg_gdk_device_get_position_w, 2, 2, 0, H_gdk_device_get_position, pl_tu); Xg_define_procedure(gdk_device_get_window_at_position, gxg_gdk_device_get_window_at_position_w, 1, 2, 0, H_gdk_device_get_window_at_position, pl_pu); Xg_define_procedure(gtk_cell_view_get_draw_sensitive, gxg_gtk_cell_view_get_draw_sensitive_w, 1, 0, 0, H_gtk_cell_view_get_draw_sensitive, pl_bu); Xg_define_procedure(gtk_cell_view_set_draw_sensitive, gxg_gtk_cell_view_set_draw_sensitive_w, 2, 0, 0, H_gtk_cell_view_set_draw_sensitive, pl_tub); Xg_define_procedure(gtk_cell_view_get_fit_model, gxg_gtk_cell_view_get_fit_model_w, 1, 0, 0, H_gtk_cell_view_get_fit_model, pl_bu); Xg_define_procedure(gtk_cell_view_set_fit_model, gxg_gtk_cell_view_set_fit_model_w, 2, 0, 0, H_gtk_cell_view_set_fit_model, pl_tub); Xg_define_procedure(gtk_combo_box_new_with_area, gxg_gtk_combo_box_new_with_area_w, 1, 0, 0, H_gtk_combo_box_new_with_area, pl_pu); Xg_define_procedure(gtk_combo_box_new_with_area_and_entry, gxg_gtk_combo_box_new_with_area_and_entry_w, 1, 0, 0, H_gtk_combo_box_new_with_area_and_entry, pl_pu); Xg_define_procedure(gtk_icon_view_new_with_area, gxg_gtk_icon_view_new_with_area_w, 1, 0, 0, H_gtk_icon_view_new_with_area, pl_pu); Xg_define_procedure(gtk_menu_item_set_reserve_indicator, gxg_gtk_menu_item_set_reserve_indicator_w, 2, 0, 0, H_gtk_menu_item_set_reserve_indicator, pl_tub); Xg_define_procedure(gtk_menu_item_get_reserve_indicator, gxg_gtk_menu_item_get_reserve_indicator_w, 1, 0, 0, H_gtk_menu_item_get_reserve_indicator, pl_bu); Xg_define_procedure(gtk_menu_shell_get_selected_item, gxg_gtk_menu_shell_get_selected_item_w, 1, 0, 0, H_gtk_menu_shell_get_selected_item, pl_pu); Xg_define_procedure(gtk_menu_shell_get_parent_shell, gxg_gtk_menu_shell_get_parent_shell_w, 1, 0, 0, H_gtk_menu_shell_get_parent_shell, pl_pu); Xg_define_procedure(gtk_selection_data_get_data_with_length, gxg_gtk_selection_data_get_data_with_length_w, 1, 1, 0, H_gtk_selection_data_get_data_with_length, pl_su); Xg_define_procedure(gtk_tree_model_iter_previous, gxg_gtk_tree_model_iter_previous_w, 2, 0, 0, H_gtk_tree_model_iter_previous, pl_bu); Xg_define_procedure(gtk_tree_view_is_blank_at_pos, gxg_gtk_tree_view_is_blank_at_pos_w, 3, 4, 0, H_gtk_tree_view_is_blank_at_pos, pl_buiiu); Xg_define_procedure(gtk_widget_set_device_enabled, gxg_gtk_widget_set_device_enabled_w, 3, 0, 0, H_gtk_widget_set_device_enabled, pl_tuub); Xg_define_procedure(gtk_widget_get_device_enabled, gxg_gtk_widget_get_device_enabled_w, 2, 0, 0, H_gtk_widget_get_device_enabled, pl_bu); Xg_define_procedure(gtk_window_set_has_user_ref_count, gxg_gtk_window_set_has_user_ref_count_w, 2, 0, 0, H_gtk_window_set_has_user_ref_count, pl_tub); Xg_define_procedure(gdk_selection_send_notify, gxg_gdk_selection_send_notify_w, 5, 0, 0, H_gdk_selection_send_notify, pl_tuttti); Xg_define_procedure(gdk_selection_send_notify_for_display, gxg_gdk_selection_send_notify_for_display_w, 6, 0, 0, H_gdk_selection_send_notify_for_display, pl_tuuttti); Xg_define_procedure(gdk_rgba_copy, gxg_gdk_rgba_copy_w, 1, 0, 0, H_gdk_rgba_copy, pl_pu); Xg_define_procedure(gdk_rgba_free, gxg_gdk_rgba_free_w, 1, 0, 0, H_gdk_rgba_free, pl_tu); Xg_define_procedure(gdk_rgba_parse, gxg_gdk_rgba_parse_w, 2, 0, 0, H_gdk_rgba_parse, pl_bus); Xg_define_procedure(gdk_rgba_to_string, gxg_gdk_rgba_to_string_w, 1, 0, 0, H_gdk_rgba_to_string, pl_su); Xg_define_procedure(gtk_widget_set_state_flags, gxg_gtk_widget_set_state_flags_w, 3, 0, 0, H_gtk_widget_set_state_flags, pl_tuib); Xg_define_procedure(gtk_widget_unset_state_flags, gxg_gtk_widget_unset_state_flags_w, 2, 0, 0, H_gtk_widget_unset_state_flags, pl_tui); Xg_define_procedure(gtk_widget_get_state_flags, gxg_gtk_widget_get_state_flags_w, 1, 0, 0, H_gtk_widget_get_state_flags, pl_iu); #endif #if GTK_CHECK_VERSION(3, 2, 0) Xg_define_procedure(gtk_entry_get_placeholder_text, gxg_gtk_entry_get_placeholder_text_w, 1, 0, 0, H_gtk_entry_get_placeholder_text, pl_su); Xg_define_procedure(gtk_entry_set_placeholder_text, gxg_gtk_entry_set_placeholder_text_w, 2, 0, 0, H_gtk_entry_set_placeholder_text, pl_tus); Xg_define_procedure(gtk_expander_set_resize_toplevel, gxg_gtk_expander_set_resize_toplevel_w, 2, 0, 0, H_gtk_expander_set_resize_toplevel, pl_tub); Xg_define_procedure(gtk_expander_get_resize_toplevel, gxg_gtk_expander_get_resize_toplevel_w, 1, 0, 0, H_gtk_expander_get_resize_toplevel, pl_bu); Xg_define_procedure(gtk_widget_path_to_string, gxg_gtk_widget_path_to_string_w, 1, 0, 0, H_gtk_widget_path_to_string, pl_su); Xg_define_procedure(gtk_button_box_get_child_non_homogeneous, gxg_gtk_button_box_get_child_non_homogeneous_w, 2, 0, 0, H_gtk_button_box_get_child_non_homogeneous, pl_bu); Xg_define_procedure(gtk_button_box_set_child_non_homogeneous, gxg_gtk_button_box_set_child_non_homogeneous_w, 3, 0, 0, H_gtk_button_box_set_child_non_homogeneous, pl_tuub); Xg_define_procedure(gtk_container_child_notify, gxg_gtk_container_child_notify_w, 3, 0, 0, H_gtk_container_child_notify, pl_tuus); Xg_define_procedure(gtk_drag_source_set_icon_gicon, gxg_gtk_drag_source_set_icon_gicon_w, 2, 0, 0, H_gtk_drag_source_set_icon_gicon, pl_tu); Xg_define_procedure(gtk_drag_set_icon_gicon, gxg_gtk_drag_set_icon_gicon_w, 4, 0, 0, H_gtk_drag_set_icon_gicon, pl_tuui); Xg_define_procedure(gtk_combo_box_set_active_id, gxg_gtk_combo_box_set_active_id_w, 2, 0, 0, H_gtk_combo_box_set_active_id, pl_bus); Xg_define_procedure(gtk_tree_view_column_get_x_offset, gxg_gtk_tree_view_column_get_x_offset_w, 1, 0, 0, H_gtk_tree_view_column_get_x_offset, pl_iu); Xg_define_procedure(gtk_overlay_new, gxg_gtk_overlay_new_w, 0, 0, 0, H_gtk_overlay_new, pl_p); Xg_define_procedure(gtk_overlay_add_overlay, gxg_gtk_overlay_add_overlay_w, 2, 0, 0, H_gtk_overlay_add_overlay, pl_tu); Xg_define_procedure(gtk_adjustment_get_minimum_increment, gxg_gtk_adjustment_get_minimum_increment_w, 1, 0, 0, H_gtk_adjustment_get_minimum_increment, pl_du); Xg_define_procedure(gtk_grid_insert_row, gxg_gtk_grid_insert_row_w, 2, 0, 0, H_gtk_grid_insert_row, pl_tui); Xg_define_procedure(gtk_grid_insert_column, gxg_gtk_grid_insert_column_w, 2, 0, 0, H_gtk_grid_insert_column, pl_tui); Xg_define_procedure(gtk_grid_insert_next_to, gxg_gtk_grid_insert_next_to_w, 3, 0, 0, H_gtk_grid_insert_next_to, pl_tuui); Xg_define_procedure(gtk_text_iter_assign, gxg_gtk_text_iter_assign_w, 2, 0, 0, H_gtk_text_iter_assign, pl_tu); Xg_define_procedure(gtk_widget_has_visible_focus, gxg_gtk_widget_has_visible_focus_w, 1, 0, 0, H_gtk_widget_has_visible_focus, pl_bu); Xg_define_procedure(gtk_window_set_focus_visible, gxg_gtk_window_set_focus_visible_w, 2, 0, 0, H_gtk_window_set_focus_visible, pl_tub); Xg_define_procedure(gtk_window_get_focus_visible, gxg_gtk_window_get_focus_visible_w, 1, 0, 0, H_gtk_window_get_focus_visible, pl_bu); Xg_define_procedure(gtk_font_chooser_dialog_new, gxg_gtk_font_chooser_dialog_new_w, 2, 0, 0, H_gtk_font_chooser_dialog_new, pl_psu); Xg_define_procedure(gdk_event_get_button, gxg_gdk_event_get_button_w, 2, 0, 0, H_gdk_event_get_button, pl_bu); Xg_define_procedure(gdk_event_get_click_count, gxg_gdk_event_get_click_count_w, 2, 0, 0, H_gdk_event_get_click_count, pl_bu); Xg_define_procedure(gdk_event_get_keyval, gxg_gdk_event_get_keyval_w, 2, 0, 0, H_gdk_event_get_keyval, pl_bu); Xg_define_procedure(gdk_event_get_keycode, gxg_gdk_event_get_keycode_w, 2, 0, 0, H_gdk_event_get_keycode, pl_bu); Xg_define_procedure(gdk_event_get_scroll_direction, gxg_gdk_event_get_scroll_direction_w, 1, 1, 0, H_gdk_event_get_scroll_direction, pl_bu); Xg_define_procedure(gtk_grid_get_child_at, gxg_gtk_grid_get_child_at_w, 3, 0, 0, H_gtk_grid_get_child_at, pl_pui); Xg_define_procedure(gtk_font_chooser_get_font_family, gxg_gtk_font_chooser_get_font_family_w, 1, 0, 0, H_gtk_font_chooser_get_font_family, pl_pu); Xg_define_procedure(gtk_font_chooser_get_font_face, gxg_gtk_font_chooser_get_font_face_w, 1, 0, 0, H_gtk_font_chooser_get_font_face, pl_pu); Xg_define_procedure(gtk_font_chooser_get_font_size, gxg_gtk_font_chooser_get_font_size_w, 1, 0, 0, H_gtk_font_chooser_get_font_size, pl_iu); Xg_define_procedure(gtk_font_chooser_get_font_desc, gxg_gtk_font_chooser_get_font_desc_w, 1, 0, 0, H_gtk_font_chooser_get_font_desc, pl_pu); Xg_define_procedure(gtk_font_chooser_set_font_desc, gxg_gtk_font_chooser_set_font_desc_w, 2, 0, 0, H_gtk_font_chooser_set_font_desc, pl_tu); Xg_define_procedure(gtk_font_chooser_get_font, gxg_gtk_font_chooser_get_font_w, 1, 0, 0, H_gtk_font_chooser_get_font, pl_su); Xg_define_procedure(gtk_font_chooser_set_font, gxg_gtk_font_chooser_set_font_w, 2, 0, 0, H_gtk_font_chooser_set_font, pl_tus); Xg_define_procedure(gtk_font_chooser_get_preview_text, gxg_gtk_font_chooser_get_preview_text_w, 1, 0, 0, H_gtk_font_chooser_get_preview_text, pl_su); Xg_define_procedure(gtk_font_chooser_set_preview_text, gxg_gtk_font_chooser_set_preview_text_w, 2, 0, 0, H_gtk_font_chooser_set_preview_text, pl_tus); Xg_define_procedure(gtk_font_chooser_get_show_preview_entry, gxg_gtk_font_chooser_get_show_preview_entry_w, 1, 0, 0, H_gtk_font_chooser_get_show_preview_entry, pl_bu); Xg_define_procedure(gtk_font_chooser_set_show_preview_entry, gxg_gtk_font_chooser_set_show_preview_entry_w, 2, 0, 0, H_gtk_font_chooser_set_show_preview_entry, pl_tub); Xg_define_procedure(gtk_font_chooser_widget_new, gxg_gtk_font_chooser_widget_new_w, 0, 0, 0, H_gtk_font_chooser_widget_new, pl_p); #endif #if GTK_CHECK_VERSION(3, 4, 0) Xg_define_procedure(gdk_keymap_get_modifier_mask, gxg_gdk_keymap_get_modifier_mask_w, 2, 0, 0, H_gdk_keymap_get_modifier_mask, pl_iui); Xg_define_procedure(gdk_window_begin_resize_drag_for_device, gxg_gdk_window_begin_resize_drag_for_device_w, 7, 0, 0, H_gdk_window_begin_resize_drag_for_device, pl_tuiui); Xg_define_procedure(gdk_window_begin_move_drag_for_device, gxg_gdk_window_begin_move_drag_for_device_w, 6, 0, 0, H_gdk_window_begin_move_drag_for_device, pl_tuui); Xg_define_procedure(gtk_accelerator_parse_with_keycode, gxg_gtk_accelerator_parse_with_keycode_w, 4, 0, 0, H_gtk_accelerator_parse_with_keycode, pl_tsu); Xg_define_procedure(gtk_accelerator_name_with_keycode, gxg_gtk_accelerator_name_with_keycode_w, 4, 0, 0, H_gtk_accelerator_name_with_keycode, pl_sui); Xg_define_procedure(gtk_accelerator_get_label_with_keycode, gxg_gtk_accelerator_get_label_with_keycode_w, 4, 0, 0, H_gtk_accelerator_get_label_with_keycode, pl_sui); Xg_define_procedure(gdk_screen_get_monitor_workarea, gxg_gdk_screen_get_monitor_workarea_w, 3, 0, 0, H_gdk_screen_get_monitor_workarea, pl_tuiu); Xg_define_procedure(gtk_application_get_app_menu, gxg_gtk_application_get_app_menu_w, 1, 0, 0, H_gtk_application_get_app_menu, pl_pu); Xg_define_procedure(gtk_application_set_app_menu, gxg_gtk_application_set_app_menu_w, 2, 0, 0, H_gtk_application_set_app_menu, pl_tu); Xg_define_procedure(gtk_application_get_menubar, gxg_gtk_application_get_menubar_w, 1, 0, 0, H_gtk_application_get_menubar, pl_pu); Xg_define_procedure(gtk_application_set_menubar, gxg_gtk_application_set_menubar_w, 2, 0, 0, H_gtk_application_set_menubar, pl_tu); Xg_define_procedure(gtk_entry_completion_compute_prefix, gxg_gtk_entry_completion_compute_prefix_w, 2, 0, 0, H_gtk_entry_completion_compute_prefix, pl_sus); Xg_define_procedure(gtk_scale_set_has_origin, gxg_gtk_scale_set_has_origin_w, 2, 0, 0, H_gtk_scale_set_has_origin, pl_tub); Xg_define_procedure(gtk_scale_get_has_origin, gxg_gtk_scale_get_has_origin_w, 1, 0, 0, H_gtk_scale_get_has_origin, pl_bu); Xg_define_procedure(gtk_window_set_hide_titlebar_when_maximized, gxg_gtk_window_set_hide_titlebar_when_maximized_w, 2, 0, 0, H_gtk_window_set_hide_titlebar_when_maximized, pl_tub); Xg_define_procedure(gtk_window_get_hide_titlebar_when_maximized, gxg_gtk_window_get_hide_titlebar_when_maximized_w, 1, 0, 0, H_gtk_window_get_hide_titlebar_when_maximized, pl_bu); Xg_define_procedure(gtk_application_window_new, gxg_gtk_application_window_new_w, 1, 0, 0, H_gtk_application_window_new, pl_pu); Xg_define_procedure(gtk_application_window_set_show_menubar, gxg_gtk_application_window_set_show_menubar_w, 2, 0, 0, H_gtk_application_window_set_show_menubar, pl_tub); Xg_define_procedure(gtk_application_window_get_show_menubar, gxg_gtk_application_window_get_show_menubar_w, 1, 0, 0, H_gtk_application_window_get_show_menubar, pl_bu); Xg_define_procedure(gtk_image_new_from_resource, gxg_gtk_image_new_from_resource_w, 1, 0, 0, H_gtk_image_new_from_resource, pl_ps); Xg_define_procedure(gtk_image_set_from_resource, gxg_gtk_image_set_from_resource_w, 2, 0, 0, H_gtk_image_set_from_resource, pl_tus); Xg_define_procedure(gtk_window_set_attached_to, gxg_gtk_window_set_attached_to_w, 2, 0, 0, H_gtk_window_set_attached_to, pl_tu); Xg_define_procedure(gtk_window_get_attached_to, gxg_gtk_window_get_attached_to_w, 1, 0, 0, H_gtk_window_get_attached_to, pl_pu); Xg_define_procedure(gtk_about_dialog_add_credit_section, gxg_gtk_about_dialog_add_credit_section_w, 3, 0, 0, H_gtk_about_dialog_add_credit_section, pl_tusu); Xg_define_procedure(gdk_keymap_get_modifier_state, gxg_gdk_keymap_get_modifier_state_w, 1, 0, 0, H_gdk_keymap_get_modifier_state, pl_iu); Xg_define_procedure(gtk_hsv_to_rgb, gxg_gtk_hsv_to_rgb_w, 3, 3, 0, H_gtk_hsv_to_rgb, pl_trrru); Xg_define_procedure(gtk_rgb_to_hsv, gxg_gtk_rgb_to_hsv_w, 3, 3, 0, H_gtk_rgb_to_hsv, pl_trrru); Xg_define_procedure(gtk_color_chooser_get_rgba, gxg_gtk_color_chooser_get_rgba_w, 2, 0, 0, H_gtk_color_chooser_get_rgba, pl_tu); Xg_define_procedure(gtk_color_chooser_set_rgba, gxg_gtk_color_chooser_set_rgba_w, 2, 0, 0, H_gtk_color_chooser_set_rgba, pl_tu); Xg_define_procedure(gtk_color_chooser_get_use_alpha, gxg_gtk_color_chooser_get_use_alpha_w, 1, 0, 0, H_gtk_color_chooser_get_use_alpha, pl_bu); Xg_define_procedure(gtk_color_chooser_set_use_alpha, gxg_gtk_color_chooser_set_use_alpha_w, 2, 0, 0, H_gtk_color_chooser_set_use_alpha, pl_tub); Xg_define_procedure(gtk_color_chooser_dialog_new, gxg_gtk_color_chooser_dialog_new_w, 2, 0, 0, H_gtk_color_chooser_dialog_new, pl_psu); Xg_define_procedure(gtk_color_chooser_widget_new, gxg_gtk_color_chooser_widget_new_w, 0, 0, 0, H_gtk_color_chooser_widget_new, pl_p); #endif #if GTK_CHECK_VERSION(3, 6, 0) Xg_define_procedure(gdk_event_get_scroll_deltas, gxg_gdk_event_get_scroll_deltas_w, 1, 2, 0, H_gdk_event_get_scroll_deltas, pl_bu); Xg_define_procedure(gtk_color_chooser_add_palette, gxg_gtk_color_chooser_add_palette_w, 5, 0, 0, H_gtk_color_chooser_add_palette, pl_tuiiiu); Xg_define_procedure(gtk_button_set_always_show_image, gxg_gtk_button_set_always_show_image_w, 2, 0, 0, H_gtk_button_set_always_show_image, pl_tub); Xg_define_procedure(gtk_button_get_always_show_image, gxg_gtk_button_get_always_show_image_w, 1, 0, 0, H_gtk_button_get_always_show_image, pl_bu); Xg_define_procedure(gtk_tree_view_get_n_columns, gxg_gtk_tree_view_get_n_columns_w, 1, 0, 0, H_gtk_tree_view_get_n_columns, pl_iu); Xg_define_procedure(gtk_menu_button_new, gxg_gtk_menu_button_new_w, 0, 0, 0, H_gtk_menu_button_new, pl_p); Xg_define_procedure(gtk_menu_button_set_menu_model, gxg_gtk_menu_button_set_menu_model_w, 2, 0, 0, H_gtk_menu_button_set_menu_model, pl_tu); Xg_define_procedure(gtk_menu_button_get_menu_model, gxg_gtk_menu_button_get_menu_model_w, 1, 0, 0, H_gtk_menu_button_get_menu_model, pl_pu); Xg_define_procedure(gtk_menu_button_set_align_widget, gxg_gtk_menu_button_set_align_widget_w, 2, 0, 0, H_gtk_menu_button_set_align_widget, pl_tu); Xg_define_procedure(gtk_menu_button_get_align_widget, gxg_gtk_menu_button_get_align_widget_w, 1, 0, 0, H_gtk_menu_button_get_align_widget, pl_pu); Xg_define_procedure(gtk_search_entry_new, gxg_gtk_search_entry_new_w, 0, 0, 0, H_gtk_search_entry_new, pl_p); Xg_define_procedure(gtk_level_bar_new, gxg_gtk_level_bar_new_w, 0, 0, 0, H_gtk_level_bar_new, pl_p); Xg_define_procedure(gtk_level_bar_new_for_interval, gxg_gtk_level_bar_new_for_interval_w, 2, 0, 0, H_gtk_level_bar_new_for_interval, pl_pr); Xg_define_procedure(gtk_level_bar_set_mode, gxg_gtk_level_bar_set_mode_w, 2, 0, 0, H_gtk_level_bar_set_mode, pl_tui); Xg_define_procedure(gtk_level_bar_get_mode, gxg_gtk_level_bar_get_mode_w, 1, 0, 0, H_gtk_level_bar_get_mode, pl_iu); Xg_define_procedure(gtk_level_bar_set_value, gxg_gtk_level_bar_set_value_w, 2, 0, 0, H_gtk_level_bar_set_value, pl_tur); Xg_define_procedure(gtk_level_bar_get_value, gxg_gtk_level_bar_get_value_w, 1, 0, 0, H_gtk_level_bar_get_value, pl_du); Xg_define_procedure(gtk_level_bar_set_min_value, gxg_gtk_level_bar_set_min_value_w, 2, 0, 0, H_gtk_level_bar_set_min_value, pl_tur); Xg_define_procedure(gtk_level_bar_get_min_value, gxg_gtk_level_bar_get_min_value_w, 1, 0, 0, H_gtk_level_bar_get_min_value, pl_du); Xg_define_procedure(gtk_level_bar_set_max_value, gxg_gtk_level_bar_set_max_value_w, 2, 0, 0, H_gtk_level_bar_set_max_value, pl_tur); Xg_define_procedure(gtk_level_bar_get_max_value, gxg_gtk_level_bar_get_max_value_w, 1, 0, 0, H_gtk_level_bar_get_max_value, pl_du); Xg_define_procedure(gtk_level_bar_add_offset_value, gxg_gtk_level_bar_add_offset_value_w, 3, 0, 0, H_gtk_level_bar_add_offset_value, pl_tusr); Xg_define_procedure(gtk_level_bar_remove_offset_value, gxg_gtk_level_bar_remove_offset_value_w, 2, 0, 0, H_gtk_level_bar_remove_offset_value, pl_tus); Xg_define_procedure(gtk_level_bar_get_offset_value, gxg_gtk_level_bar_get_offset_value_w, 2, 1, 0, H_gtk_level_bar_get_offset_value, pl_busu); Xg_define_procedure(gtk_application_get_active_window, gxg_gtk_application_get_active_window_w, 1, 0, 0, H_gtk_application_get_active_window, pl_pu); Xg_define_procedure(gtk_entry_set_input_purpose, gxg_gtk_entry_set_input_purpose_w, 2, 0, 0, H_gtk_entry_set_input_purpose, pl_tui); Xg_define_procedure(gtk_entry_get_input_purpose, gxg_gtk_entry_get_input_purpose_w, 1, 0, 0, H_gtk_entry_get_input_purpose, pl_iu); Xg_define_procedure(gtk_entry_set_input_hints, gxg_gtk_entry_set_input_hints_w, 2, 0, 0, H_gtk_entry_set_input_hints, pl_tui); Xg_define_procedure(gtk_entry_get_input_hints, gxg_gtk_entry_get_input_hints_w, 1, 0, 0, H_gtk_entry_get_input_hints, pl_iu); Xg_define_procedure(gtk_menu_button_get_popup, gxg_gtk_menu_button_get_popup_w, 1, 0, 0, H_gtk_menu_button_get_popup, pl_pu); Xg_define_procedure(gtk_text_view_set_input_purpose, gxg_gtk_text_view_set_input_purpose_w, 2, 0, 0, H_gtk_text_view_set_input_purpose, pl_tui); Xg_define_procedure(gtk_text_view_get_input_purpose, gxg_gtk_text_view_get_input_purpose_w, 1, 0, 0, H_gtk_text_view_get_input_purpose, pl_iu); Xg_define_procedure(gtk_text_view_set_input_hints, gxg_gtk_text_view_set_input_hints_w, 2, 0, 0, H_gtk_text_view_set_input_hints, pl_tui); Xg_define_procedure(gtk_text_view_get_input_hints, gxg_gtk_text_view_get_input_hints_w, 1, 0, 0, H_gtk_text_view_get_input_hints, pl_iu); Xg_define_procedure(gtk_entry_set_attributes, gxg_gtk_entry_set_attributes_w, 2, 0, 0, H_gtk_entry_set_attributes, pl_tu); Xg_define_procedure(gtk_entry_get_attributes, gxg_gtk_entry_get_attributes_w, 1, 0, 0, H_gtk_entry_get_attributes, pl_pu); Xg_define_procedure(gtk_accel_label_set_accel, gxg_gtk_accel_label_set_accel_w, 3, 0, 0, H_gtk_accel_label_set_accel, pl_tui); Xg_define_procedure(gtk_menu_shell_bind_model, gxg_gtk_menu_shell_bind_model_w, 4, 0, 0, H_gtk_menu_shell_bind_model, pl_tuusb); #endif #if GTK_CHECK_VERSION(3, 8, 0) Xg_define_procedure(gtk_level_bar_set_inverted, gxg_gtk_level_bar_set_inverted_w, 2, 0, 0, H_gtk_level_bar_set_inverted, pl_tub); Xg_define_procedure(gtk_level_bar_get_inverted, gxg_gtk_level_bar_get_inverted_w, 1, 0, 0, H_gtk_level_bar_get_inverted, pl_bu); Xg_define_procedure(gtk_widget_is_visible, gxg_gtk_widget_is_visible_w, 1, 0, 0, H_gtk_widget_is_visible, pl_bu); Xg_define_procedure(gdk_window_set_fullscreen_mode, gxg_gdk_window_set_fullscreen_mode_w, 2, 0, 0, H_gdk_window_set_fullscreen_mode, pl_tui); Xg_define_procedure(gdk_window_get_fullscreen_mode, gxg_gdk_window_get_fullscreen_mode_w, 1, 0, 0, H_gdk_window_get_fullscreen_mode, pl_iu); Xg_define_procedure(gtk_icon_view_set_activate_on_single_click, gxg_gtk_icon_view_set_activate_on_single_click_w, 2, 0, 0, H_gtk_icon_view_set_activate_on_single_click, pl_tub); Xg_define_procedure(gtk_icon_view_get_activate_on_single_click, gxg_gtk_icon_view_get_activate_on_single_click_w, 1, 0, 0, H_gtk_icon_view_get_activate_on_single_click, pl_bu); Xg_define_procedure(gtk_tree_view_get_activate_on_single_click, gxg_gtk_tree_view_get_activate_on_single_click_w, 1, 0, 0, H_gtk_tree_view_get_activate_on_single_click, pl_bu); Xg_define_procedure(gtk_tree_view_set_activate_on_single_click, gxg_gtk_tree_view_set_activate_on_single_click_w, 2, 0, 0, H_gtk_tree_view_set_activate_on_single_click, pl_tub); Xg_define_procedure(gtk_widget_register_window, gxg_gtk_widget_register_window_w, 2, 0, 0, H_gtk_widget_register_window, pl_tu); Xg_define_procedure(gtk_widget_unregister_window, gxg_gtk_widget_unregister_window_w, 2, 0, 0, H_gtk_widget_unregister_window, pl_tu); Xg_define_procedure(gtk_widget_set_opacity, gxg_gtk_widget_set_opacity_w, 2, 0, 0, H_gtk_widget_set_opacity, pl_tur); Xg_define_procedure(gtk_widget_get_opacity, gxg_gtk_widget_get_opacity_w, 1, 0, 0, H_gtk_widget_get_opacity, pl_du); Xg_define_procedure(pango_font_map_changed, gxg_pango_font_map_changed_w, 1, 0, 0, H_pango_font_map_changed, pl_tu); #endif #if GTK_CHECK_VERSION(3, 10, 0) Xg_define_procedure(gdk_set_allowed_backends, gxg_gdk_set_allowed_backends_w, 1, 0, 0, H_gdk_set_allowed_backends, pl_ts); Xg_define_procedure(gtk_box_set_baseline_position, gxg_gtk_box_set_baseline_position_w, 2, 0, 0, H_gtk_box_set_baseline_position, pl_tui); Xg_define_procedure(gtk_box_get_baseline_position, gxg_gtk_box_get_baseline_position_w, 1, 0, 0, H_gtk_box_get_baseline_position, pl_iu); Xg_define_procedure(gtk_grid_remove_row, gxg_gtk_grid_remove_row_w, 2, 0, 0, H_gtk_grid_remove_row, pl_tui); Xg_define_procedure(gtk_grid_remove_column, gxg_gtk_grid_remove_column_w, 2, 0, 0, H_gtk_grid_remove_column, pl_tui); Xg_define_procedure(gtk_grid_set_row_baseline_position, gxg_gtk_grid_set_row_baseline_position_w, 3, 0, 0, H_gtk_grid_set_row_baseline_position, pl_tui); Xg_define_procedure(gtk_grid_get_row_baseline_position, gxg_gtk_grid_get_row_baseline_position_w, 2, 0, 0, H_gtk_grid_get_row_baseline_position, pl_iui); Xg_define_procedure(gtk_grid_set_baseline_row, gxg_gtk_grid_set_baseline_row_w, 2, 0, 0, H_gtk_grid_set_baseline_row, pl_tui); Xg_define_procedure(gtk_grid_get_baseline_row, gxg_gtk_grid_get_baseline_row_w, 1, 0, 0, H_gtk_grid_get_baseline_row, pl_iu); Xg_define_procedure(gtk_widget_size_allocate_with_baseline, gxg_gtk_widget_size_allocate_with_baseline_w, 3, 0, 0, H_gtk_widget_size_allocate_with_baseline, pl_tuui); Xg_define_procedure(gtk_widget_get_preferred_height_and_baseline_for_width, gxg_gtk_widget_get_preferred_height_and_baseline_for_width_w, 2, 4, 0, H_gtk_widget_get_preferred_height_and_baseline_for_width, pl_tuiu); Xg_define_procedure(gtk_widget_get_allocated_baseline, gxg_gtk_widget_get_allocated_baseline_w, 1, 0, 0, H_gtk_widget_get_allocated_baseline, pl_iu); Xg_define_procedure(gtk_widget_get_valign_with_baseline, gxg_gtk_widget_get_valign_with_baseline_w, 1, 0, 0, H_gtk_widget_get_valign_with_baseline, pl_iu); Xg_define_procedure(gtk_widget_init_template, gxg_gtk_widget_init_template_w, 1, 0, 0, H_gtk_widget_init_template, pl_tu); Xg_define_procedure(gtk_window_set_titlebar, gxg_gtk_window_set_titlebar_w, 2, 0, 0, H_gtk_window_set_titlebar, pl_tu); Xg_define_procedure(gtk_places_sidebar_new, gxg_gtk_places_sidebar_new_w, 0, 0, 0, H_gtk_places_sidebar_new, pl_p); Xg_define_procedure(gtk_places_sidebar_get_open_flags, gxg_gtk_places_sidebar_get_open_flags_w, 1, 0, 0, H_gtk_places_sidebar_get_open_flags, pl_iu); Xg_define_procedure(gtk_places_sidebar_set_open_flags, gxg_gtk_places_sidebar_set_open_flags_w, 2, 0, 0, H_gtk_places_sidebar_set_open_flags, pl_tui); Xg_define_procedure(gtk_places_sidebar_get_location, gxg_gtk_places_sidebar_get_location_w, 1, 0, 0, H_gtk_places_sidebar_get_location, pl_pu); Xg_define_procedure(gtk_places_sidebar_set_location, gxg_gtk_places_sidebar_set_location_w, 2, 0, 0, H_gtk_places_sidebar_set_location, pl_tu); Xg_define_procedure(gtk_places_sidebar_get_show_desktop, gxg_gtk_places_sidebar_get_show_desktop_w, 1, 0, 0, H_gtk_places_sidebar_get_show_desktop, pl_bu); Xg_define_procedure(gtk_places_sidebar_set_show_desktop, gxg_gtk_places_sidebar_set_show_desktop_w, 2, 0, 0, H_gtk_places_sidebar_set_show_desktop, pl_tub); Xg_define_procedure(gtk_places_sidebar_add_shortcut, gxg_gtk_places_sidebar_add_shortcut_w, 2, 0, 0, H_gtk_places_sidebar_add_shortcut, pl_tu); Xg_define_procedure(gtk_places_sidebar_remove_shortcut, gxg_gtk_places_sidebar_remove_shortcut_w, 2, 0, 0, H_gtk_places_sidebar_remove_shortcut, pl_tu); Xg_define_procedure(gtk_places_sidebar_list_shortcuts, gxg_gtk_places_sidebar_list_shortcuts_w, 1, 0, 0, H_gtk_places_sidebar_list_shortcuts, pl_pu); Xg_define_procedure(gtk_places_sidebar_get_nth_bookmark, gxg_gtk_places_sidebar_get_nth_bookmark_w, 2, 0, 0, H_gtk_places_sidebar_get_nth_bookmark, pl_pui); Xg_define_procedure(gtk_stack_switcher_new, gxg_gtk_stack_switcher_new_w, 0, 0, 0, H_gtk_stack_switcher_new, pl_p); Xg_define_procedure(gtk_stack_switcher_set_stack, gxg_gtk_stack_switcher_set_stack_w, 2, 0, 0, H_gtk_stack_switcher_set_stack, pl_tu); Xg_define_procedure(gtk_stack_switcher_get_stack, gxg_gtk_stack_switcher_get_stack_w, 1, 0, 0, H_gtk_stack_switcher_get_stack, pl_pu); Xg_define_procedure(gtk_stack_new, gxg_gtk_stack_new_w, 0, 0, 0, H_gtk_stack_new, pl_p); Xg_define_procedure(gtk_stack_add_named, gxg_gtk_stack_add_named_w, 3, 0, 0, H_gtk_stack_add_named, pl_tuus); Xg_define_procedure(gtk_stack_add_titled, gxg_gtk_stack_add_titled_w, 4, 0, 0, H_gtk_stack_add_titled, pl_tuus); Xg_define_procedure(gtk_stack_set_visible_child, gxg_gtk_stack_set_visible_child_w, 2, 0, 0, H_gtk_stack_set_visible_child, pl_tu); Xg_define_procedure(gtk_stack_get_visible_child, gxg_gtk_stack_get_visible_child_w, 1, 0, 0, H_gtk_stack_get_visible_child, pl_pu); Xg_define_procedure(gtk_stack_set_visible_child_name, gxg_gtk_stack_set_visible_child_name_w, 2, 0, 0, H_gtk_stack_set_visible_child_name, pl_tus); Xg_define_procedure(gtk_stack_get_visible_child_name, gxg_gtk_stack_get_visible_child_name_w, 1, 0, 0, H_gtk_stack_get_visible_child_name, pl_su); Xg_define_procedure(gtk_stack_set_visible_child_full, gxg_gtk_stack_set_visible_child_full_w, 3, 0, 0, H_gtk_stack_set_visible_child_full, pl_tusi); Xg_define_procedure(gtk_stack_set_homogeneous, gxg_gtk_stack_set_homogeneous_w, 2, 0, 0, H_gtk_stack_set_homogeneous, pl_tub); Xg_define_procedure(gtk_stack_get_homogeneous, gxg_gtk_stack_get_homogeneous_w, 1, 0, 0, H_gtk_stack_get_homogeneous, pl_bu); Xg_define_procedure(gtk_stack_set_transition_duration, gxg_gtk_stack_set_transition_duration_w, 2, 0, 0, H_gtk_stack_set_transition_duration, pl_tui); Xg_define_procedure(gtk_stack_get_transition_duration, gxg_gtk_stack_get_transition_duration_w, 1, 0, 0, H_gtk_stack_get_transition_duration, pl_iu); Xg_define_procedure(gtk_stack_set_transition_type, gxg_gtk_stack_set_transition_type_w, 2, 0, 0, H_gtk_stack_set_transition_type, pl_tui); Xg_define_procedure(gtk_stack_get_transition_type, gxg_gtk_stack_get_transition_type_w, 1, 0, 0, H_gtk_stack_get_transition_type, pl_iu); Xg_define_procedure(gtk_revealer_new, gxg_gtk_revealer_new_w, 0, 0, 0, H_gtk_revealer_new, pl_p); Xg_define_procedure(gtk_revealer_get_reveal_child, gxg_gtk_revealer_get_reveal_child_w, 1, 0, 0, H_gtk_revealer_get_reveal_child, pl_bu); Xg_define_procedure(gtk_revealer_set_reveal_child, gxg_gtk_revealer_set_reveal_child_w, 2, 0, 0, H_gtk_revealer_set_reveal_child, pl_tub); Xg_define_procedure(gtk_revealer_get_child_revealed, gxg_gtk_revealer_get_child_revealed_w, 1, 0, 0, H_gtk_revealer_get_child_revealed, pl_bu); Xg_define_procedure(gtk_revealer_get_transition_duration, gxg_gtk_revealer_get_transition_duration_w, 1, 0, 0, H_gtk_revealer_get_transition_duration, pl_iu); Xg_define_procedure(gtk_revealer_set_transition_duration, gxg_gtk_revealer_set_transition_duration_w, 2, 0, 0, H_gtk_revealer_set_transition_duration, pl_tui); Xg_define_procedure(gtk_revealer_set_transition_type, gxg_gtk_revealer_set_transition_type_w, 2, 0, 0, H_gtk_revealer_set_transition_type, pl_tui); Xg_define_procedure(gtk_revealer_get_transition_type, gxg_gtk_revealer_get_transition_type_w, 1, 0, 0, H_gtk_revealer_get_transition_type, pl_iu); Xg_define_procedure(gtk_header_bar_new, gxg_gtk_header_bar_new_w, 0, 0, 0, H_gtk_header_bar_new, pl_p); Xg_define_procedure(gtk_header_bar_set_title, gxg_gtk_header_bar_set_title_w, 2, 0, 0, H_gtk_header_bar_set_title, pl_tus); Xg_define_procedure(gtk_header_bar_get_title, gxg_gtk_header_bar_get_title_w, 1, 0, 0, H_gtk_header_bar_get_title, pl_su); Xg_define_procedure(gtk_header_bar_set_subtitle, gxg_gtk_header_bar_set_subtitle_w, 2, 0, 0, H_gtk_header_bar_set_subtitle, pl_tus); Xg_define_procedure(gtk_header_bar_get_subtitle, gxg_gtk_header_bar_get_subtitle_w, 1, 0, 0, H_gtk_header_bar_get_subtitle, pl_su); Xg_define_procedure(gtk_header_bar_set_custom_title, gxg_gtk_header_bar_set_custom_title_w, 2, 0, 0, H_gtk_header_bar_set_custom_title, pl_tu); Xg_define_procedure(gtk_header_bar_get_custom_title, gxg_gtk_header_bar_get_custom_title_w, 1, 0, 0, H_gtk_header_bar_get_custom_title, pl_pu); Xg_define_procedure(gtk_header_bar_pack_start, gxg_gtk_header_bar_pack_start_w, 2, 0, 0, H_gtk_header_bar_pack_start, pl_tu); Xg_define_procedure(gtk_header_bar_pack_end, gxg_gtk_header_bar_pack_end_w, 2, 0, 0, H_gtk_header_bar_pack_end, pl_tu); Xg_define_procedure(gtk_list_box_row_new, gxg_gtk_list_box_row_new_w, 0, 0, 0, H_gtk_list_box_row_new, pl_p); Xg_define_procedure(gtk_list_box_row_get_header, gxg_gtk_list_box_row_get_header_w, 1, 0, 0, H_gtk_list_box_row_get_header, pl_pu); Xg_define_procedure(gtk_list_box_row_set_header, gxg_gtk_list_box_row_set_header_w, 2, 0, 0, H_gtk_list_box_row_set_header, pl_tu); Xg_define_procedure(gtk_list_box_row_changed, gxg_gtk_list_box_row_changed_w, 1, 0, 0, H_gtk_list_box_row_changed, pl_tu); Xg_define_procedure(gtk_list_box_get_selected_row, gxg_gtk_list_box_get_selected_row_w, 1, 0, 0, H_gtk_list_box_get_selected_row, pl_pu); Xg_define_procedure(gtk_list_box_get_row_at_index, gxg_gtk_list_box_get_row_at_index_w, 2, 0, 0, H_gtk_list_box_get_row_at_index, pl_pui); Xg_define_procedure(gtk_list_box_get_row_at_y, gxg_gtk_list_box_get_row_at_y_w, 2, 0, 0, H_gtk_list_box_get_row_at_y, pl_pui); Xg_define_procedure(gtk_list_box_select_row, gxg_gtk_list_box_select_row_w, 2, 0, 0, H_gtk_list_box_select_row, pl_tu); Xg_define_procedure(gtk_list_box_set_placeholder, gxg_gtk_list_box_set_placeholder_w, 2, 0, 0, H_gtk_list_box_set_placeholder, pl_tu); Xg_define_procedure(gtk_list_box_set_adjustment, gxg_gtk_list_box_set_adjustment_w, 2, 0, 0, H_gtk_list_box_set_adjustment, pl_tu); Xg_define_procedure(gtk_list_box_get_adjustment, gxg_gtk_list_box_get_adjustment_w, 1, 0, 0, H_gtk_list_box_get_adjustment, pl_pu); Xg_define_procedure(gtk_list_box_set_selection_mode, gxg_gtk_list_box_set_selection_mode_w, 2, 0, 0, H_gtk_list_box_set_selection_mode, pl_tui); Xg_define_procedure(gtk_list_box_get_selection_mode, gxg_gtk_list_box_get_selection_mode_w, 1, 0, 0, H_gtk_list_box_get_selection_mode, pl_iu); Xg_define_procedure(gtk_list_box_invalidate_filter, gxg_gtk_list_box_invalidate_filter_w, 1, 0, 0, H_gtk_list_box_invalidate_filter, pl_tu); Xg_define_procedure(gtk_list_box_invalidate_sort, gxg_gtk_list_box_invalidate_sort_w, 1, 0, 0, H_gtk_list_box_invalidate_sort, pl_tu); Xg_define_procedure(gtk_list_box_invalidate_headers, gxg_gtk_list_box_invalidate_headers_w, 1, 0, 0, H_gtk_list_box_invalidate_headers, pl_tu); Xg_define_procedure(gtk_list_box_set_activate_on_single_click, gxg_gtk_list_box_set_activate_on_single_click_w, 2, 0, 0, H_gtk_list_box_set_activate_on_single_click, pl_tub); Xg_define_procedure(gtk_list_box_get_activate_on_single_click, gxg_gtk_list_box_get_activate_on_single_click_w, 1, 0, 0, H_gtk_list_box_get_activate_on_single_click, pl_bu); Xg_define_procedure(gtk_list_box_drag_unhighlight_row, gxg_gtk_list_box_drag_unhighlight_row_w, 1, 0, 0, H_gtk_list_box_drag_unhighlight_row, pl_tu); Xg_define_procedure(gtk_list_box_drag_highlight_row, gxg_gtk_list_box_drag_highlight_row_w, 2, 0, 0, H_gtk_list_box_drag_highlight_row, pl_tu); Xg_define_procedure(gtk_list_box_new, gxg_gtk_list_box_new_w, 0, 0, 0, H_gtk_list_box_new, pl_p); Xg_define_procedure(gtk_search_bar_new, gxg_gtk_search_bar_new_w, 0, 0, 0, H_gtk_search_bar_new, pl_p); Xg_define_procedure(gtk_search_bar_connect_entry, gxg_gtk_search_bar_connect_entry_w, 2, 0, 0, H_gtk_search_bar_connect_entry, pl_tu); Xg_define_procedure(gtk_search_bar_get_search_mode, gxg_gtk_search_bar_get_search_mode_w, 1, 0, 0, H_gtk_search_bar_get_search_mode, pl_bu); Xg_define_procedure(gtk_search_bar_set_search_mode, gxg_gtk_search_bar_set_search_mode_w, 2, 0, 0, H_gtk_search_bar_set_search_mode, pl_tub); Xg_define_procedure(gtk_search_bar_get_show_close_button, gxg_gtk_search_bar_get_show_close_button_w, 1, 0, 0, H_gtk_search_bar_get_show_close_button, pl_bu); Xg_define_procedure(gtk_search_bar_set_show_close_button, gxg_gtk_search_bar_set_show_close_button_w, 2, 0, 0, H_gtk_search_bar_set_show_close_button, pl_tub); Xg_define_procedure(gtk_search_bar_handle_event, gxg_gtk_search_bar_handle_event_w, 2, 0, 0, H_gtk_search_bar_handle_event, pl_bu); Xg_define_procedure(gtk_file_chooser_get_current_name, gxg_gtk_file_chooser_get_current_name_w, 1, 0, 0, H_gtk_file_chooser_get_current_name, pl_su); Xg_define_procedure(gdk_cairo_surface_create_from_pixbuf, gxg_gdk_cairo_surface_create_from_pixbuf_w, 3, 0, 0, H_gdk_cairo_surface_create_from_pixbuf, pl_puiu); Xg_define_procedure(gdk_device_get_position_double, gxg_gdk_device_get_position_double_w, 1, 3, 0, H_gdk_device_get_position_double, pl_tu); Xg_define_procedure(gdk_device_get_window_at_position_double, gxg_gdk_device_get_window_at_position_double_w, 1, 2, 0, H_gdk_device_get_window_at_position_double, pl_pu); Xg_define_procedure(gdk_screen_get_monitor_scale_factor, gxg_gdk_screen_get_monitor_scale_factor_w, 2, 0, 0, H_gdk_screen_get_monitor_scale_factor, pl_iui); Xg_define_procedure(gdk_window_get_scale_factor, gxg_gdk_window_get_scale_factor_w, 1, 0, 0, H_gdk_window_get_scale_factor, pl_iu); Xg_define_procedure(gdk_window_get_device_position_double, gxg_gdk_window_get_device_position_double_w, 2, 3, 0, H_gdk_window_get_device_position_double, pl_pu); Xg_define_procedure(gdk_window_create_similar_image_surface, gxg_gdk_window_create_similar_image_surface_w, 5, 0, 0, H_gdk_window_create_similar_image_surface, pl_pui); Xg_define_procedure(gtk_icon_theme_lookup_icon_for_scale, gxg_gtk_icon_theme_lookup_icon_for_scale_w, 5, 0, 0, H_gtk_icon_theme_lookup_icon_for_scale, pl_pusi); Xg_define_procedure(gtk_icon_theme_load_icon_for_scale, gxg_gtk_icon_theme_load_icon_for_scale_w, 5, 1, 0, H_gtk_icon_theme_load_icon_for_scale, pl_pusiiiu); Xg_define_procedure(gtk_icon_theme_load_surface, gxg_gtk_icon_theme_load_surface_w, 6, 1, 0, H_gtk_icon_theme_load_surface, pl_pusiiuiu); Xg_define_procedure(gtk_icon_theme_lookup_by_gicon_for_scale, gxg_gtk_icon_theme_lookup_by_gicon_for_scale_w, 5, 0, 0, H_gtk_icon_theme_lookup_by_gicon_for_scale, pl_puui); Xg_define_procedure(gtk_icon_info_get_base_scale, gxg_gtk_icon_info_get_base_scale_w, 1, 0, 0, H_gtk_icon_info_get_base_scale, pl_iu); Xg_define_procedure(gtk_icon_info_load_surface, gxg_gtk_icon_info_load_surface_w, 2, 1, 0, H_gtk_icon_info_load_surface, pl_pu); Xg_define_procedure(gtk_image_new_from_surface, gxg_gtk_image_new_from_surface_w, 1, 0, 0, H_gtk_image_new_from_surface, pl_pu); Xg_define_procedure(gtk_image_set_from_surface, gxg_gtk_image_set_from_surface_w, 2, 0, 0, H_gtk_image_set_from_surface, pl_tu); Xg_define_procedure(gtk_list_box_row_get_index, gxg_gtk_list_box_row_get_index_w, 1, 0, 0, H_gtk_list_box_row_get_index, pl_iu); Xg_define_procedure(gtk_widget_get_scale_factor, gxg_gtk_widget_get_scale_factor_w, 1, 0, 0, H_gtk_widget_get_scale_factor, pl_iu); Xg_define_procedure(gtk_window_close, gxg_gtk_window_close_w, 1, 0, 0, H_gtk_window_close, pl_tu); Xg_define_procedure(gtk_info_bar_set_show_close_button, gxg_gtk_info_bar_set_show_close_button_w, 2, 0, 0, H_gtk_info_bar_set_show_close_button, pl_tub); Xg_define_procedure(gtk_info_bar_get_show_close_button, gxg_gtk_info_bar_get_show_close_button_w, 1, 0, 0, H_gtk_info_bar_get_show_close_button, pl_bu); Xg_define_procedure(gtk_tree_model_rows_reordered_with_length, gxg_gtk_tree_model_rows_reordered_with_length_w, 5, 0, 0, H_gtk_tree_model_rows_reordered_with_length, pl_tuuuui); Xg_define_procedure(gdk_cursor_new_from_surface, gxg_gdk_cursor_new_from_surface_w, 4, 0, 0, H_gdk_cursor_new_from_surface, pl_puur); Xg_define_procedure(gdk_cursor_get_surface, gxg_gdk_cursor_get_surface_w, 1, 2, 0, H_gdk_cursor_get_surface, pl_pu); Xg_define_procedure(gdk_event_get_event_type, gxg_gdk_event_get_event_type_w, 1, 0, 0, H_gdk_event_get_event_type, pl_iu); Xg_define_procedure(gtk_entry_set_tabs, gxg_gtk_entry_set_tabs_w, 2, 0, 0, H_gtk_entry_set_tabs, pl_tu); Xg_define_procedure(gtk_entry_get_tabs, gxg_gtk_entry_get_tabs_w, 1, 0, 0, H_gtk_entry_get_tabs, pl_pu); Xg_define_procedure(gtk_header_bar_get_show_close_button, gxg_gtk_header_bar_get_show_close_button_w, 1, 0, 0, H_gtk_header_bar_get_show_close_button, pl_bu); Xg_define_procedure(gtk_header_bar_set_show_close_button, gxg_gtk_header_bar_set_show_close_button_w, 2, 0, 0, H_gtk_header_bar_set_show_close_button, pl_tub); Xg_define_procedure(gtk_list_box_prepend, gxg_gtk_list_box_prepend_w, 2, 0, 0, H_gtk_list_box_prepend, pl_tu); Xg_define_procedure(gtk_list_box_insert, gxg_gtk_list_box_insert_w, 3, 0, 0, H_gtk_list_box_insert, pl_tuui); Xg_define_procedure(gdk_window_set_opaque_region, gxg_gdk_window_set_opaque_region_w, 2, 0, 0, H_gdk_window_set_opaque_region, pl_tu); Xg_define_procedure(gtk_label_set_lines, gxg_gtk_label_set_lines_w, 2, 0, 0, H_gtk_label_set_lines, pl_tui); Xg_define_procedure(gtk_label_get_lines, gxg_gtk_label_get_lines_w, 1, 0, 0, H_gtk_label_get_lines, pl_iu); Xg_define_procedure(gdk_event_get_window, gxg_gdk_event_get_window_w, 1, 0, 0, H_gdk_event_get_window, pl_pu); #endif #if GTK_CHECK_VERSION(3, 12, 0) Xg_define_procedure(gtk_flow_box_child_new, gxg_gtk_flow_box_child_new_w, 0, 0, 0, H_gtk_flow_box_child_new, pl_p); Xg_define_procedure(gtk_flow_box_child_get_index, gxg_gtk_flow_box_child_get_index_w, 1, 0, 0, H_gtk_flow_box_child_get_index, pl_iu); Xg_define_procedure(gtk_flow_box_child_is_selected, gxg_gtk_flow_box_child_is_selected_w, 1, 0, 0, H_gtk_flow_box_child_is_selected, pl_bu); Xg_define_procedure(gtk_flow_box_child_changed, gxg_gtk_flow_box_child_changed_w, 1, 0, 0, H_gtk_flow_box_child_changed, pl_tu); Xg_define_procedure(gtk_flow_box_new, gxg_gtk_flow_box_new_w, 0, 0, 0, H_gtk_flow_box_new, pl_p); Xg_define_procedure(gtk_flow_box_set_homogeneous, gxg_gtk_flow_box_set_homogeneous_w, 2, 0, 0, H_gtk_flow_box_set_homogeneous, pl_tub); Xg_define_procedure(gtk_flow_box_get_homogeneous, gxg_gtk_flow_box_get_homogeneous_w, 1, 0, 0, H_gtk_flow_box_get_homogeneous, pl_bu); Xg_define_procedure(gtk_flow_box_set_row_spacing, gxg_gtk_flow_box_set_row_spacing_w, 2, 0, 0, H_gtk_flow_box_set_row_spacing, pl_tui); Xg_define_procedure(gtk_flow_box_get_row_spacing, gxg_gtk_flow_box_get_row_spacing_w, 1, 0, 0, H_gtk_flow_box_get_row_spacing, pl_iu); Xg_define_procedure(gtk_flow_box_set_column_spacing, gxg_gtk_flow_box_set_column_spacing_w, 2, 0, 0, H_gtk_flow_box_set_column_spacing, pl_tui); Xg_define_procedure(gtk_flow_box_get_column_spacing, gxg_gtk_flow_box_get_column_spacing_w, 1, 0, 0, H_gtk_flow_box_get_column_spacing, pl_iu); Xg_define_procedure(gtk_flow_box_set_min_children_per_line, gxg_gtk_flow_box_set_min_children_per_line_w, 2, 0, 0, H_gtk_flow_box_set_min_children_per_line, pl_tui); Xg_define_procedure(gtk_flow_box_get_min_children_per_line, gxg_gtk_flow_box_get_min_children_per_line_w, 1, 0, 0, H_gtk_flow_box_get_min_children_per_line, pl_iu); Xg_define_procedure(gtk_flow_box_set_max_children_per_line, gxg_gtk_flow_box_set_max_children_per_line_w, 2, 0, 0, H_gtk_flow_box_set_max_children_per_line, pl_tui); Xg_define_procedure(gtk_flow_box_get_max_children_per_line, gxg_gtk_flow_box_get_max_children_per_line_w, 1, 0, 0, H_gtk_flow_box_get_max_children_per_line, pl_iu); Xg_define_procedure(gtk_flow_box_set_activate_on_single_click, gxg_gtk_flow_box_set_activate_on_single_click_w, 2, 0, 0, H_gtk_flow_box_set_activate_on_single_click, pl_tub); Xg_define_procedure(gtk_flow_box_get_activate_on_single_click, gxg_gtk_flow_box_get_activate_on_single_click_w, 1, 0, 0, H_gtk_flow_box_get_activate_on_single_click, pl_bu); Xg_define_procedure(gtk_flow_box_insert, gxg_gtk_flow_box_insert_w, 3, 0, 0, H_gtk_flow_box_insert, pl_tuui); Xg_define_procedure(gtk_flow_box_get_child_at_index, gxg_gtk_flow_box_get_child_at_index_w, 2, 0, 0, H_gtk_flow_box_get_child_at_index, pl_pui); Xg_define_procedure(gtk_flow_box_get_selected_children, gxg_gtk_flow_box_get_selected_children_w, 1, 0, 0, H_gtk_flow_box_get_selected_children, pl_pu); Xg_define_procedure(gtk_flow_box_select_child, gxg_gtk_flow_box_select_child_w, 2, 0, 0, H_gtk_flow_box_select_child, pl_tu); Xg_define_procedure(gtk_flow_box_unselect_child, gxg_gtk_flow_box_unselect_child_w, 2, 0, 0, H_gtk_flow_box_unselect_child, pl_tu); Xg_define_procedure(gtk_flow_box_select_all, gxg_gtk_flow_box_select_all_w, 1, 0, 0, H_gtk_flow_box_select_all, pl_tu); Xg_define_procedure(gtk_flow_box_unselect_all, gxg_gtk_flow_box_unselect_all_w, 1, 0, 0, H_gtk_flow_box_unselect_all, pl_tu); Xg_define_procedure(gtk_flow_box_set_selection_mode, gxg_gtk_flow_box_set_selection_mode_w, 2, 0, 0, H_gtk_flow_box_set_selection_mode, pl_tui); Xg_define_procedure(gtk_flow_box_get_selection_mode, gxg_gtk_flow_box_get_selection_mode_w, 1, 0, 0, H_gtk_flow_box_get_selection_mode, pl_iu); Xg_define_procedure(gtk_flow_box_set_hadjustment, gxg_gtk_flow_box_set_hadjustment_w, 2, 0, 0, H_gtk_flow_box_set_hadjustment, pl_tu); Xg_define_procedure(gtk_flow_box_set_vadjustment, gxg_gtk_flow_box_set_vadjustment_w, 2, 0, 0, H_gtk_flow_box_set_vadjustment, pl_tu); Xg_define_procedure(gtk_flow_box_invalidate_filter, gxg_gtk_flow_box_invalidate_filter_w, 1, 0, 0, H_gtk_flow_box_invalidate_filter, pl_tu); Xg_define_procedure(gtk_flow_box_invalidate_sort, gxg_gtk_flow_box_invalidate_sort_w, 1, 0, 0, H_gtk_flow_box_invalidate_sort, pl_tu); Xg_define_procedure(gdk_window_set_event_compression, gxg_gdk_window_set_event_compression_w, 2, 0, 0, H_gdk_window_set_event_compression, pl_tub); Xg_define_procedure(gdk_window_get_event_compression, gxg_gdk_window_get_event_compression_w, 1, 0, 0, H_gdk_window_get_event_compression, pl_bu); Xg_define_procedure(gtk_places_sidebar_set_local_only, gxg_gtk_places_sidebar_set_local_only_w, 2, 0, 0, H_gtk_places_sidebar_set_local_only, pl_tub); Xg_define_procedure(gtk_places_sidebar_get_local_only, gxg_gtk_places_sidebar_get_local_only_w, 1, 0, 0, H_gtk_places_sidebar_get_local_only, pl_bu); Xg_define_procedure(gtk_stack_get_transition_running, gxg_gtk_stack_get_transition_running_w, 1, 0, 0, H_gtk_stack_get_transition_running, pl_bu); Xg_define_procedure(gtk_widget_get_margin_start, gxg_gtk_widget_get_margin_start_w, 1, 0, 0, H_gtk_widget_get_margin_start, pl_iu); Xg_define_procedure(gtk_widget_set_margin_start, gxg_gtk_widget_set_margin_start_w, 2, 0, 0, H_gtk_widget_set_margin_start, pl_tui); Xg_define_procedure(gtk_widget_get_margin_end, gxg_gtk_widget_get_margin_end_w, 1, 0, 0, H_gtk_widget_get_margin_end, pl_iu); Xg_define_procedure(gtk_widget_set_margin_end, gxg_gtk_widget_set_margin_end_w, 2, 0, 0, H_gtk_widget_set_margin_end, pl_tui); Xg_define_procedure(gtk_accel_label_get_accel, gxg_gtk_accel_label_get_accel_w, 1, 2, 0, H_gtk_accel_label_get_accel, pl_tu); Xg_define_procedure(gdk_window_set_shadow_width, gxg_gdk_window_set_shadow_width_w, 5, 0, 0, H_gdk_window_set_shadow_width, pl_tui); Xg_define_procedure(gtk_action_bar_new, gxg_gtk_action_bar_new_w, 0, 0, 0, H_gtk_action_bar_new, pl_p); Xg_define_procedure(gtk_action_bar_get_center_widget, gxg_gtk_action_bar_get_center_widget_w, 1, 0, 0, H_gtk_action_bar_get_center_widget, pl_pu); Xg_define_procedure(gtk_action_bar_set_center_widget, gxg_gtk_action_bar_set_center_widget_w, 2, 0, 0, H_gtk_action_bar_set_center_widget, pl_tu); Xg_define_procedure(gtk_action_bar_pack_start, gxg_gtk_action_bar_pack_start_w, 2, 0, 0, H_gtk_action_bar_pack_start, pl_tu); Xg_define_procedure(gtk_action_bar_pack_end, gxg_gtk_action_bar_pack_end_w, 2, 0, 0, H_gtk_action_bar_pack_end, pl_tu); Xg_define_procedure(gtk_header_bar_set_has_subtitle, gxg_gtk_header_bar_set_has_subtitle_w, 2, 0, 0, H_gtk_header_bar_set_has_subtitle, pl_tub); Xg_define_procedure(gtk_header_bar_get_has_subtitle, gxg_gtk_header_bar_get_has_subtitle_w, 1, 0, 0, H_gtk_header_bar_get_has_subtitle, pl_bu); Xg_define_procedure(gtk_header_bar_set_decoration_layout, gxg_gtk_header_bar_set_decoration_layout_w, 2, 0, 0, H_gtk_header_bar_set_decoration_layout, pl_tus); Xg_define_procedure(gtk_header_bar_get_decoration_layout, gxg_gtk_header_bar_get_decoration_layout_w, 1, 0, 0, H_gtk_header_bar_get_decoration_layout, pl_su); Xg_define_procedure(gtk_icon_info_is_symbolic, gxg_gtk_icon_info_is_symbolic_w, 1, 0, 0, H_gtk_icon_info_is_symbolic, pl_bu); Xg_define_procedure(gtk_get_locale_direction, gxg_gtk_get_locale_direction_w, 0, 0, 0, H_gtk_get_locale_direction, pl_i); Xg_define_procedure(gtk_window_is_maximized, gxg_gtk_window_is_maximized_w, 1, 0, 0, H_gtk_window_is_maximized, pl_bu); Xg_define_procedure(gtk_dialog_get_header_bar, gxg_gtk_dialog_get_header_bar_w, 1, 0, 0, H_gtk_dialog_get_header_bar, pl_pu); Xg_define_procedure(gtk_popover_new, gxg_gtk_popover_new_w, 1, 0, 0, H_gtk_popover_new, pl_pu); Xg_define_procedure(gtk_popover_set_relative_to, gxg_gtk_popover_set_relative_to_w, 2, 0, 0, H_gtk_popover_set_relative_to, pl_tu); Xg_define_procedure(gtk_popover_get_relative_to, gxg_gtk_popover_get_relative_to_w, 1, 0, 0, H_gtk_popover_get_relative_to, pl_pu); Xg_define_procedure(gtk_popover_set_position, gxg_gtk_popover_set_position_w, 2, 0, 0, H_gtk_popover_set_position, pl_tui); Xg_define_procedure(gtk_popover_get_position, gxg_gtk_popover_get_position_w, 1, 0, 0, H_gtk_popover_get_position, pl_iu); Xg_define_procedure(gtk_popover_set_modal, gxg_gtk_popover_set_modal_w, 2, 0, 0, H_gtk_popover_set_modal, pl_tub); Xg_define_procedure(gtk_popover_get_modal, gxg_gtk_popover_get_modal_w, 1, 0, 0, H_gtk_popover_get_modal, pl_bu); Xg_define_procedure(gtk_box_set_center_widget, gxg_gtk_box_set_center_widget_w, 2, 0, 0, H_gtk_box_set_center_widget, pl_tu); Xg_define_procedure(gtk_box_get_center_widget, gxg_gtk_box_get_center_widget_w, 1, 0, 0, H_gtk_box_get_center_widget, pl_pu); Xg_define_procedure(gtk_entry_set_max_width_chars, gxg_gtk_entry_set_max_width_chars_w, 2, 0, 0, H_gtk_entry_set_max_width_chars, pl_tui); Xg_define_procedure(gtk_entry_get_max_width_chars, gxg_gtk_entry_get_max_width_chars_w, 1, 0, 0, H_gtk_entry_get_max_width_chars, pl_iu); Xg_define_procedure(gdk_device_get_last_event_window, gxg_gdk_device_get_last_event_window_w, 1, 0, 0, H_gdk_device_get_last_event_window, pl_pu); #endif #if GTK_CHECK_VERSION(3, 14, 0) Xg_define_procedure(gtk_list_box_row_is_selected, gxg_gtk_list_box_row_is_selected_w, 1, 0, 0, H_gtk_list_box_row_is_selected, pl_bu); Xg_define_procedure(gtk_list_box_unselect_row, gxg_gtk_list_box_unselect_row_w, 2, 0, 0, H_gtk_list_box_unselect_row, pl_tu); Xg_define_procedure(gtk_list_box_select_all, gxg_gtk_list_box_select_all_w, 1, 0, 0, H_gtk_list_box_select_all, pl_tu); Xg_define_procedure(gtk_list_box_unselect_all, gxg_gtk_list_box_unselect_all_w, 1, 0, 0, H_gtk_list_box_unselect_all, pl_tu); Xg_define_procedure(gtk_places_sidebar_get_show_enter_location, gxg_gtk_places_sidebar_get_show_enter_location_w, 1, 0, 0, H_gtk_places_sidebar_get_show_enter_location, pl_bu); Xg_define_procedure(gtk_places_sidebar_set_show_enter_location, gxg_gtk_places_sidebar_set_show_enter_location_w, 2, 0, 0, H_gtk_places_sidebar_set_show_enter_location, pl_tub); Xg_define_procedure(gtk_switch_set_state, gxg_gtk_switch_set_state_w, 2, 0, 0, H_gtk_switch_set_state, pl_tub); Xg_define_procedure(gtk_switch_get_state, gxg_gtk_switch_get_state_w, 1, 0, 0, H_gtk_switch_get_state, pl_bu); Xg_define_procedure(gdk_window_show_window_menu, gxg_gdk_window_show_window_menu_w, 2, 0, 0, H_gdk_window_show_window_menu, pl_bu); Xg_define_procedure(gtk_widget_set_clip, gxg_gtk_widget_set_clip_w, 2, 0, 0, H_gtk_widget_set_clip, pl_tu); Xg_define_procedure(gtk_widget_get_clip, gxg_gtk_widget_get_clip_w, 2, 0, 0, H_gtk_widget_get_clip, pl_tu); Xg_define_procedure(gtk_gesture_get_device, gxg_gtk_gesture_get_device_w, 1, 0, 0, H_gtk_gesture_get_device, pl_pu); Xg_define_procedure(gtk_gesture_set_state, gxg_gtk_gesture_set_state_w, 2, 0, 0, H_gtk_gesture_set_state, pl_but); Xg_define_procedure(gtk_gesture_get_sequence_state, gxg_gtk_gesture_get_sequence_state_w, 2, 0, 0, H_gtk_gesture_get_sequence_state, pl_tu); Xg_define_procedure(gtk_gesture_set_sequence_state, gxg_gtk_gesture_set_sequence_state_w, 3, 0, 0, H_gtk_gesture_set_sequence_state, pl_buut); Xg_define_procedure(gtk_gesture_get_sequences, gxg_gtk_gesture_get_sequences_w, 1, 0, 0, H_gtk_gesture_get_sequences, pl_pu); Xg_define_procedure(gtk_gesture_get_last_updated_sequence, gxg_gtk_gesture_get_last_updated_sequence_w, 1, 0, 0, H_gtk_gesture_get_last_updated_sequence, pl_pu); Xg_define_procedure(gtk_gesture_handles_sequence, gxg_gtk_gesture_handles_sequence_w, 2, 0, 0, H_gtk_gesture_handles_sequence, pl_bu); Xg_define_procedure(gtk_gesture_get_last_event, gxg_gtk_gesture_get_last_event_w, 2, 0, 0, H_gtk_gesture_get_last_event, pl_pu); Xg_define_procedure(gtk_gesture_get_point, gxg_gtk_gesture_get_point_w, 2, 2, 0, H_gtk_gesture_get_point, pl_bu); Xg_define_procedure(gtk_gesture_get_bounding_box, gxg_gtk_gesture_get_bounding_box_w, 2, 0, 0, H_gtk_gesture_get_bounding_box, pl_bu); Xg_define_procedure(gtk_gesture_get_bounding_box_center, gxg_gtk_gesture_get_bounding_box_center_w, 1, 2, 0, H_gtk_gesture_get_bounding_box_center, pl_bu); Xg_define_procedure(gtk_gesture_is_active, gxg_gtk_gesture_is_active_w, 1, 0, 0, H_gtk_gesture_is_active, pl_bu); Xg_define_procedure(gtk_gesture_is_recognized, gxg_gtk_gesture_is_recognized_w, 1, 0, 0, H_gtk_gesture_is_recognized, pl_bu); Xg_define_procedure(gtk_gesture_get_window, gxg_gtk_gesture_get_window_w, 1, 0, 0, H_gtk_gesture_get_window, pl_pu); Xg_define_procedure(gtk_gesture_set_window, gxg_gtk_gesture_set_window_w, 2, 0, 0, H_gtk_gesture_set_window, pl_tu); Xg_define_procedure(gtk_gesture_group, gxg_gtk_gesture_group_w, 2, 0, 0, H_gtk_gesture_group, pl_tu); Xg_define_procedure(gtk_gesture_ungroup, gxg_gtk_gesture_ungroup_w, 1, 0, 0, H_gtk_gesture_ungroup, pl_tu); Xg_define_procedure(gtk_gesture_get_group, gxg_gtk_gesture_get_group_w, 1, 0, 0, H_gtk_gesture_get_group, pl_pu); Xg_define_procedure(gtk_gesture_is_grouped_with, gxg_gtk_gesture_is_grouped_with_w, 2, 0, 0, H_gtk_gesture_is_grouped_with, pl_bu); Xg_define_procedure(gtk_gesture_drag_new, gxg_gtk_gesture_drag_new_w, 1, 0, 0, H_gtk_gesture_drag_new, pl_pu); Xg_define_procedure(gtk_gesture_drag_get_start_point, gxg_gtk_gesture_drag_get_start_point_w, 1, 2, 0, H_gtk_gesture_drag_get_start_point, pl_bu); Xg_define_procedure(gtk_gesture_drag_get_offset, gxg_gtk_gesture_drag_get_offset_w, 1, 2, 0, H_gtk_gesture_drag_get_offset, pl_bu); Xg_define_procedure(gtk_gesture_long_press_new, gxg_gtk_gesture_long_press_new_w, 1, 0, 0, H_gtk_gesture_long_press_new, pl_pu); Xg_define_procedure(gtk_gesture_pan_new, gxg_gtk_gesture_pan_new_w, 2, 0, 0, H_gtk_gesture_pan_new, pl_pui); Xg_define_procedure(gtk_gesture_pan_get_orientation, gxg_gtk_gesture_pan_get_orientation_w, 1, 0, 0, H_gtk_gesture_pan_get_orientation, pl_iu); Xg_define_procedure(gtk_gesture_pan_set_orientation, gxg_gtk_gesture_pan_set_orientation_w, 2, 0, 0, H_gtk_gesture_pan_set_orientation, pl_tui); Xg_define_procedure(gtk_gesture_multi_press_new, gxg_gtk_gesture_multi_press_new_w, 1, 0, 0, H_gtk_gesture_multi_press_new, pl_pu); Xg_define_procedure(gtk_gesture_multi_press_set_area, gxg_gtk_gesture_multi_press_set_area_w, 2, 0, 0, H_gtk_gesture_multi_press_set_area, pl_tu); Xg_define_procedure(gtk_gesture_multi_press_get_area, gxg_gtk_gesture_multi_press_get_area_w, 2, 0, 0, H_gtk_gesture_multi_press_get_area, pl_bu); Xg_define_procedure(gtk_gesture_rotate_new, gxg_gtk_gesture_rotate_new_w, 1, 0, 0, H_gtk_gesture_rotate_new, pl_pu); Xg_define_procedure(gtk_gesture_rotate_get_angle_delta, gxg_gtk_gesture_rotate_get_angle_delta_w, 1, 0, 0, H_gtk_gesture_rotate_get_angle_delta, pl_du); Xg_define_procedure(gtk_gesture_single_get_touch_only, gxg_gtk_gesture_single_get_touch_only_w, 1, 0, 0, H_gtk_gesture_single_get_touch_only, pl_bu); Xg_define_procedure(gtk_gesture_single_set_touch_only, gxg_gtk_gesture_single_set_touch_only_w, 2, 0, 0, H_gtk_gesture_single_set_touch_only, pl_tub); Xg_define_procedure(gtk_gesture_single_get_exclusive, gxg_gtk_gesture_single_get_exclusive_w, 1, 0, 0, H_gtk_gesture_single_get_exclusive, pl_bu); Xg_define_procedure(gtk_gesture_single_set_exclusive, gxg_gtk_gesture_single_set_exclusive_w, 2, 0, 0, H_gtk_gesture_single_set_exclusive, pl_tub); Xg_define_procedure(gtk_gesture_single_get_button, gxg_gtk_gesture_single_get_button_w, 1, 0, 0, H_gtk_gesture_single_get_button, pl_iu); Xg_define_procedure(gtk_gesture_single_set_button, gxg_gtk_gesture_single_set_button_w, 2, 0, 0, H_gtk_gesture_single_set_button, pl_tui); Xg_define_procedure(gtk_gesture_single_get_current_button, gxg_gtk_gesture_single_get_current_button_w, 1, 0, 0, H_gtk_gesture_single_get_current_button, pl_iu); Xg_define_procedure(gtk_gesture_single_get_current_sequence, gxg_gtk_gesture_single_get_current_sequence_w, 1, 0, 0, H_gtk_gesture_single_get_current_sequence, pl_pu); Xg_define_procedure(gtk_gesture_swipe_new, gxg_gtk_gesture_swipe_new_w, 1, 0, 0, H_gtk_gesture_swipe_new, pl_pu); Xg_define_procedure(gtk_gesture_swipe_get_velocity, gxg_gtk_gesture_swipe_get_velocity_w, 1, 2, 0, H_gtk_gesture_swipe_get_velocity, pl_bu); Xg_define_procedure(gtk_gesture_zoom_new, gxg_gtk_gesture_zoom_new_w, 1, 0, 0, H_gtk_gesture_zoom_new, pl_pu); Xg_define_procedure(gtk_gesture_zoom_get_scale_delta, gxg_gtk_gesture_zoom_get_scale_delta_w, 1, 0, 0, H_gtk_gesture_zoom_get_scale_delta, pl_du); Xg_define_procedure(gtk_event_controller_get_widget, gxg_gtk_event_controller_get_widget_w, 1, 0, 0, H_gtk_event_controller_get_widget, pl_pu); Xg_define_procedure(gtk_event_controller_handle_event, gxg_gtk_event_controller_handle_event_w, 2, 0, 0, H_gtk_event_controller_handle_event, pl_bu); Xg_define_procedure(gtk_event_controller_reset, gxg_gtk_event_controller_reset_w, 1, 0, 0, H_gtk_event_controller_reset, pl_tu); Xg_define_procedure(gtk_event_controller_get_propagation_phase, gxg_gtk_event_controller_get_propagation_phase_w, 1, 0, 0, H_gtk_event_controller_get_propagation_phase, pl_tu); Xg_define_procedure(gtk_event_controller_set_propagation_phase, gxg_gtk_event_controller_set_propagation_phase_w, 2, 0, 0, H_gtk_event_controller_set_propagation_phase, pl_tut); Xg_define_procedure(gtk_icon_theme_add_resource_path, gxg_gtk_icon_theme_add_resource_path_w, 2, 0, 0, H_gtk_icon_theme_add_resource_path, pl_tus); Xg_define_procedure(gtk_list_box_row_set_activatable, gxg_gtk_list_box_row_set_activatable_w, 2, 0, 0, H_gtk_list_box_row_set_activatable, pl_tub); Xg_define_procedure(gtk_list_box_row_get_activatable, gxg_gtk_list_box_row_get_activatable_w, 1, 0, 0, H_gtk_list_box_row_get_activatable, pl_bu); Xg_define_procedure(gtk_list_box_row_set_selectable, gxg_gtk_list_box_row_set_selectable_w, 2, 0, 0, H_gtk_list_box_row_set_selectable, pl_tub); Xg_define_procedure(gtk_list_box_row_get_selectable, gxg_gtk_list_box_row_get_selectable_w, 1, 0, 0, H_gtk_list_box_row_get_selectable, pl_bu); Xg_define_procedure(gtk_widget_path_iter_get_state, gxg_gtk_widget_path_iter_get_state_w, 2, 0, 0, H_gtk_widget_path_iter_get_state, pl_iui); Xg_define_procedure(gtk_widget_path_iter_set_state, gxg_gtk_widget_path_iter_set_state_w, 3, 0, 0, H_gtk_widget_path_iter_set_state, pl_tui); #endif #if GTK_CHECK_VERSION(3, 16, 0) Xg_define_procedure(gdk_cairo_draw_from_gl, gxg_gdk_cairo_draw_from_gl_w, 0, 0, 1, H_gdk_cairo_draw_from_gl, pl_tuui); Xg_define_procedure(gdk_window_mark_paint_from_clip, gxg_gdk_window_mark_paint_from_clip_w, 2, 0, 0, H_gdk_window_mark_paint_from_clip, pl_tu); Xg_define_procedure(gtk_label_set_xalign, gxg_gtk_label_set_xalign_w, 2, 0, 0, H_gtk_label_set_xalign, pl_tur); Xg_define_procedure(gtk_label_get_xalign, gxg_gtk_label_get_xalign_w, 1, 0, 0, H_gtk_label_get_xalign, pl_du); Xg_define_procedure(gtk_label_set_yalign, gxg_gtk_label_set_yalign_w, 2, 0, 0, H_gtk_label_set_yalign, pl_tur); Xg_define_procedure(gtk_label_get_yalign, gxg_gtk_label_get_yalign_w, 1, 0, 0, H_gtk_label_get_yalign, pl_du); Xg_define_procedure(gtk_paned_set_wide_handle, gxg_gtk_paned_set_wide_handle_w, 2, 0, 0, H_gtk_paned_set_wide_handle, pl_tub); Xg_define_procedure(gtk_paned_get_wide_handle, gxg_gtk_paned_get_wide_handle_w, 1, 0, 0, H_gtk_paned_get_wide_handle, pl_bu); Xg_define_procedure(gtk_scrolled_window_set_overlay_scrolling, gxg_gtk_scrolled_window_set_overlay_scrolling_w, 2, 0, 0, H_gtk_scrolled_window_set_overlay_scrolling, pl_tub); Xg_define_procedure(gtk_scrolled_window_get_overlay_scrolling, gxg_gtk_scrolled_window_get_overlay_scrolling_w, 1, 0, 0, H_gtk_scrolled_window_get_overlay_scrolling, pl_bu); Xg_define_procedure(gtk_text_view_set_monospace, gxg_gtk_text_view_set_monospace_w, 2, 0, 0, H_gtk_text_view_set_monospace, pl_tub); Xg_define_procedure(gtk_text_view_get_monospace, gxg_gtk_text_view_get_monospace_w, 1, 0, 0, H_gtk_text_view_get_monospace, pl_bu); Xg_define_procedure(gtk_window_get_titlebar, gxg_gtk_window_get_titlebar_w, 1, 0, 0, H_gtk_window_get_titlebar, pl_pu); Xg_define_procedure(gtk_gl_area_new, gxg_gtk_gl_area_new_w, 0, 0, 0, H_gtk_gl_area_new, pl_p); Xg_define_procedure(gtk_gl_area_get_has_alpha, gxg_gtk_gl_area_get_has_alpha_w, 1, 0, 0, H_gtk_gl_area_get_has_alpha, pl_bu); Xg_define_procedure(gtk_gl_area_set_has_alpha, gxg_gtk_gl_area_set_has_alpha_w, 2, 0, 0, H_gtk_gl_area_set_has_alpha, pl_tub); Xg_define_procedure(gtk_gl_area_get_has_depth_buffer, gxg_gtk_gl_area_get_has_depth_buffer_w, 1, 0, 0, H_gtk_gl_area_get_has_depth_buffer, pl_bu); Xg_define_procedure(gtk_gl_area_set_has_depth_buffer, gxg_gtk_gl_area_set_has_depth_buffer_w, 2, 0, 0, H_gtk_gl_area_set_has_depth_buffer, pl_tub); Xg_define_procedure(gtk_gl_area_get_context, gxg_gtk_gl_area_get_context_w, 1, 0, 0, H_gtk_gl_area_get_context, pl_pu); Xg_define_procedure(gtk_gl_area_make_current, gxg_gtk_gl_area_make_current_w, 1, 0, 0, H_gtk_gl_area_make_current, pl_tu); Xg_define_procedure(gtk_render_check, gxg_gtk_render_check_w, 6, 0, 0, H_gtk_render_check, pl_tuur); Xg_define_procedure(gtk_render_option, gxg_gtk_render_option_w, 6, 0, 0, H_gtk_render_option, pl_tuur); Xg_define_procedure(gtk_render_arrow, gxg_gtk_render_arrow_w, 6, 0, 0, H_gtk_render_arrow, pl_tuur); Xg_define_procedure(gtk_render_background, gxg_gtk_render_background_w, 6, 0, 0, H_gtk_render_background, pl_tuur); Xg_define_procedure(gtk_render_frame, gxg_gtk_render_frame_w, 6, 0, 0, H_gtk_render_frame, pl_tuur); Xg_define_procedure(gtk_render_expander, gxg_gtk_render_expander_w, 6, 0, 0, H_gtk_render_expander, pl_tuur); Xg_define_procedure(gtk_render_focus, gxg_gtk_render_focus_w, 6, 0, 0, H_gtk_render_focus, pl_tuur); Xg_define_procedure(gtk_render_layout, gxg_gtk_render_layout_w, 5, 0, 0, H_gtk_render_layout, pl_tuurru); Xg_define_procedure(gtk_render_line, gxg_gtk_render_line_w, 6, 0, 0, H_gtk_render_line, pl_tuur); Xg_define_procedure(gtk_render_slider, gxg_gtk_render_slider_w, 7, 0, 0, H_gtk_render_slider, pl_tuurrrri); Xg_define_procedure(gtk_render_frame_gap, gxg_gtk_render_frame_gap_w, 0, 0, 1, H_gtk_render_frame_gap, pl_tuurrrrir); Xg_define_procedure(gtk_render_extension, gxg_gtk_render_extension_w, 7, 0, 0, H_gtk_render_extension, pl_tuurrrri); Xg_define_procedure(gtk_render_handle, gxg_gtk_render_handle_w, 6, 0, 0, H_gtk_render_handle, pl_tuur); Xg_define_procedure(gtk_render_activity, gxg_gtk_render_activity_w, 6, 0, 0, H_gtk_render_activity, pl_tuur); Xg_define_procedure(gtk_render_icon, gxg_gtk_render_icon_w, 5, 0, 0, H_gtk_render_icon, pl_tuuur); Xg_define_procedure(gtk_render_icon_surface, gxg_gtk_render_icon_surface_w, 5, 0, 0, H_gtk_render_icon_surface, pl_tuuur); Xg_define_procedure(gdk_gl_context_get_window, gxg_gdk_gl_context_get_window_w, 1, 0, 0, H_gdk_gl_context_get_window, pl_pu); Xg_define_procedure(gdk_gl_context_make_current, gxg_gdk_gl_context_make_current_w, 1, 0, 0, H_gdk_gl_context_make_current, pl_tu); Xg_define_procedure(gdk_gl_context_get_current, gxg_gdk_gl_context_get_current_w, 0, 0, 0, H_gdk_gl_context_get_current, pl_p); Xg_define_procedure(gdk_gl_context_clear_current, gxg_gdk_gl_context_clear_current_w, 0, 0, 0, H_gdk_gl_context_clear_current, pl_t); Xg_define_procedure(gtk_stack_set_hhomogeneous, gxg_gtk_stack_set_hhomogeneous_w, 2, 0, 0, H_gtk_stack_set_hhomogeneous, pl_tub); Xg_define_procedure(gtk_stack_get_hhomogeneous, gxg_gtk_stack_get_hhomogeneous_w, 1, 0, 0, H_gtk_stack_get_hhomogeneous, pl_bu); Xg_define_procedure(gtk_stack_set_vhomogeneous, gxg_gtk_stack_set_vhomogeneous_w, 2, 0, 0, H_gtk_stack_set_vhomogeneous, pl_tub); Xg_define_procedure(gtk_stack_get_vhomogeneous, gxg_gtk_stack_get_vhomogeneous_w, 1, 0, 0, H_gtk_stack_get_vhomogeneous, pl_bu); Xg_define_procedure(gdk_gl_context_get_display, gxg_gdk_gl_context_get_display_w, 1, 0, 0, H_gdk_gl_context_get_display, pl_pu); Xg_define_procedure(gtk_gl_area_get_has_stencil_buffer, gxg_gtk_gl_area_get_has_stencil_buffer_w, 1, 0, 0, H_gtk_gl_area_get_has_stencil_buffer, pl_bu); Xg_define_procedure(gtk_gl_area_set_has_stencil_buffer, gxg_gtk_gl_area_set_has_stencil_buffer_w, 2, 0, 0, H_gtk_gl_area_set_has_stencil_buffer, pl_tub); Xg_define_procedure(gtk_gl_area_get_auto_render, gxg_gtk_gl_area_get_auto_render_w, 1, 0, 0, H_gtk_gl_area_get_auto_render, pl_bu); Xg_define_procedure(gtk_gl_area_set_auto_render, gxg_gtk_gl_area_set_auto_render_w, 2, 0, 0, H_gtk_gl_area_set_auto_render, pl_tub); Xg_define_procedure(gtk_gl_area_queue_render, gxg_gtk_gl_area_queue_render_w, 1, 0, 0, H_gtk_gl_area_queue_render, pl_tu); Xg_define_procedure(gtk_gl_area_attach_buffers, gxg_gtk_gl_area_attach_buffers_w, 1, 0, 0, H_gtk_gl_area_attach_buffers, pl_tu); Xg_define_procedure(gtk_gl_area_get_error, gxg_gtk_gl_area_get_error_w, 1, 0, 0, H_gtk_gl_area_get_error, pl_pu); Xg_define_procedure(gtk_popover_menu_new, gxg_gtk_popover_menu_new_w, 0, 0, 0, H_gtk_popover_menu_new, pl_p); Xg_define_procedure(gtk_popover_menu_open_submenu, gxg_gtk_popover_menu_open_submenu_w, 2, 0, 0, H_gtk_popover_menu_open_submenu, pl_tus); Xg_define_procedure(gtk_entry_grab_focus_without_selecting, gxg_gtk_entry_grab_focus_without_selecting_w, 1, 0, 0, H_gtk_entry_grab_focus_without_selecting, pl_tu); Xg_define_procedure(gtk_scrollable_get_border, gxg_gtk_scrollable_get_border_w, 2, 0, 0, H_gtk_scrollable_get_border, pl_bu); Xg_define_procedure(gtk_text_buffer_insert_markup, gxg_gtk_text_buffer_insert_markup_w, 4, 0, 0, H_gtk_text_buffer_insert_markup, pl_tuusi); Xg_define_procedure(gdk_device_get_vendor_id, gxg_gdk_device_get_vendor_id_w, 1, 0, 0, H_gdk_device_get_vendor_id, pl_su); Xg_define_procedure(gdk_device_get_product_id, gxg_gdk_device_get_product_id_w, 1, 0, 0, H_gdk_device_get_product_id, pl_su); Xg_define_procedure(gdk_gl_context_get_shared_context, gxg_gdk_gl_context_get_shared_context_w, 1, 0, 0, H_gdk_gl_context_get_shared_context, pl_pu); Xg_define_procedure(gdk_gl_context_set_required_version, gxg_gdk_gl_context_set_required_version_w, 3, 0, 0, H_gdk_gl_context_set_required_version, pl_tui); Xg_define_procedure(gdk_gl_context_get_required_version, gxg_gdk_gl_context_get_required_version_w, 1, 2, 0, H_gdk_gl_context_get_required_version, pl_tu); Xg_define_procedure(gdk_gl_context_set_debug_enabled, gxg_gdk_gl_context_set_debug_enabled_w, 2, 0, 0, H_gdk_gl_context_set_debug_enabled, pl_tub); Xg_define_procedure(gdk_gl_context_get_debug_enabled, gxg_gdk_gl_context_get_debug_enabled_w, 1, 0, 0, H_gdk_gl_context_get_debug_enabled, pl_bu); Xg_define_procedure(gdk_gl_context_set_forward_compatible, gxg_gdk_gl_context_set_forward_compatible_w, 2, 0, 0, H_gdk_gl_context_set_forward_compatible, pl_tub); Xg_define_procedure(gdk_gl_context_get_forward_compatible, gxg_gdk_gl_context_get_forward_compatible_w, 1, 0, 0, H_gdk_gl_context_get_forward_compatible, pl_bu); Xg_define_procedure(gdk_gl_context_realize, gxg_gdk_gl_context_realize_w, 1, 1, 0, H_gdk_gl_context_realize, pl_bu); Xg_define_procedure(gtk_clipboard_get_default, gxg_gtk_clipboard_get_default_w, 1, 0, 0, H_gtk_clipboard_get_default, pl_pu); Xg_define_procedure(gtk_drag_cancel, gxg_gtk_drag_cancel_w, 1, 0, 0, H_gtk_drag_cancel, pl_tu); Xg_define_procedure(gtk_search_entry_handle_event, gxg_gtk_search_entry_handle_event_w, 2, 0, 0, H_gtk_search_entry_handle_event, pl_bu); Xg_define_procedure(gdk_gl_context_get_version, gxg_gdk_gl_context_get_version_w, 1, 2, 0, H_gdk_gl_context_get_version, pl_tu); Xg_define_procedure(gtk_gl_area_set_required_version, gxg_gtk_gl_area_set_required_version_w, 3, 0, 0, H_gtk_gl_area_set_required_version, pl_tui); Xg_define_procedure(gtk_gl_area_get_required_version, gxg_gtk_gl_area_get_required_version_w, 1, 2, 0, H_gtk_gl_area_get_required_version, pl_tu); Xg_define_procedure(gtk_notebook_detach_tab, gxg_gtk_notebook_detach_tab_w, 2, 0, 0, H_gtk_notebook_detach_tab, pl_tu); Xg_define_procedure(gtk_stack_sidebar_new, gxg_gtk_stack_sidebar_new_w, 0, 0, 0, H_gtk_stack_sidebar_new, pl_p); Xg_define_procedure(gtk_stack_sidebar_set_stack, gxg_gtk_stack_sidebar_set_stack_w, 2, 0, 0, H_gtk_stack_sidebar_set_stack, pl_tu); Xg_define_procedure(gtk_stack_sidebar_get_stack, gxg_gtk_stack_sidebar_get_stack_w, 1, 0, 0, H_gtk_stack_sidebar_get_stack, pl_pu); Xg_define_procedure(gtk_popover_set_transitions_enabled, gxg_gtk_popover_set_transitions_enabled_w, 2, 0, 0, H_gtk_popover_set_transitions_enabled, pl_tub); Xg_define_procedure(gtk_popover_get_transitions_enabled, gxg_gtk_popover_get_transitions_enabled_w, 1, 0, 0, H_gtk_popover_get_transitions_enabled, pl_bu); #endif #if GTK_CHECK_VERSION(3, 18, 0) Xg_define_procedure(gdk_keymap_get_scroll_lock_state, gxg_gdk_keymap_get_scroll_lock_state_w, 1, 0, 0, H_gdk_keymap_get_scroll_lock_state, pl_bu); Xg_define_procedure(gtk_radio_menu_item_join_group, gxg_gtk_radio_menu_item_join_group_w, 2, 0, 0, H_gtk_radio_menu_item_join_group, pl_tu); Xg_define_procedure(gtk_font_chooser_set_font_map, gxg_gtk_font_chooser_set_font_map_w, 2, 0, 0, H_gtk_font_chooser_set_font_map, pl_tu); Xg_define_procedure(gtk_font_chooser_get_font_map, gxg_gtk_font_chooser_get_font_map_w, 1, 0, 0, H_gtk_font_chooser_get_font_map, pl_pu); Xg_define_procedure(gtk_popover_set_default_widget, gxg_gtk_popover_set_default_widget_w, 2, 0, 0, H_gtk_popover_set_default_widget, pl_tu); Xg_define_procedure(gtk_popover_get_default_widget, gxg_gtk_popover_get_default_widget_w, 1, 0, 0, H_gtk_popover_get_default_widget, pl_pu); Xg_define_procedure(gdk_window_set_pass_through, gxg_gdk_window_set_pass_through_w, 2, 0, 0, H_gdk_window_set_pass_through, pl_tub); Xg_define_procedure(gdk_window_get_pass_through, gxg_gdk_window_get_pass_through_w, 1, 0, 0, H_gdk_window_get_pass_through, pl_bu); Xg_define_procedure(gtk_overlay_reorder_overlay, gxg_gtk_overlay_reorder_overlay_w, 3, 0, 0, H_gtk_overlay_reorder_overlay, pl_tuui); Xg_define_procedure(gtk_overlay_get_overlay_pass_through, gxg_gtk_overlay_get_overlay_pass_through_w, 2, 0, 0, H_gtk_overlay_get_overlay_pass_through, pl_bu); Xg_define_procedure(gtk_overlay_set_overlay_pass_through, gxg_gtk_overlay_set_overlay_pass_through_w, 3, 0, 0, H_gtk_overlay_set_overlay_pass_through, pl_tuub); Xg_define_procedure(gtk_places_sidebar_get_show_recent, gxg_gtk_places_sidebar_get_show_recent_w, 1, 0, 0, H_gtk_places_sidebar_get_show_recent, pl_bu); Xg_define_procedure(gtk_places_sidebar_set_show_recent, gxg_gtk_places_sidebar_set_show_recent_w, 2, 0, 0, H_gtk_places_sidebar_set_show_recent, pl_tub); Xg_define_procedure(gtk_places_sidebar_set_drop_targets_visible, gxg_gtk_places_sidebar_set_drop_targets_visible_w, 3, 0, 0, H_gtk_places_sidebar_set_drop_targets_visible, pl_tubu); Xg_define_procedure(gtk_places_sidebar_get_show_trash, gxg_gtk_places_sidebar_get_show_trash_w, 1, 0, 0, H_gtk_places_sidebar_get_show_trash, pl_bu); Xg_define_procedure(gtk_places_sidebar_set_show_trash, gxg_gtk_places_sidebar_set_show_trash_w, 2, 0, 0, H_gtk_places_sidebar_set_show_trash, pl_tub); Xg_define_procedure(gtk_places_sidebar_set_show_other_locations, gxg_gtk_places_sidebar_set_show_other_locations_w, 2, 0, 0, H_gtk_places_sidebar_set_show_other_locations, pl_tub); Xg_define_procedure(gtk_places_sidebar_get_show_other_locations, gxg_gtk_places_sidebar_get_show_other_locations_w, 1, 0, 0, H_gtk_places_sidebar_get_show_other_locations, pl_bu); Xg_define_procedure(gtk_stack_set_interpolate_size, gxg_gtk_stack_set_interpolate_size_w, 2, 0, 0, H_gtk_stack_set_interpolate_size, pl_tub); Xg_define_procedure(gtk_stack_get_interpolate_size, gxg_gtk_stack_get_interpolate_size_w, 1, 0, 0, H_gtk_stack_get_interpolate_size, pl_bu); Xg_define_procedure(gtk_widget_set_font_options, gxg_gtk_widget_set_font_options_w, 2, 0, 0, H_gtk_widget_set_font_options, pl_tu); Xg_define_procedure(gtk_widget_get_font_options, gxg_gtk_widget_get_font_options_w, 1, 0, 0, H_gtk_widget_get_font_options, pl_pu); Xg_define_procedure(gtk_widget_set_font_map, gxg_gtk_widget_set_font_map_w, 2, 0, 0, H_gtk_widget_set_font_map, pl_tu); Xg_define_procedure(gtk_widget_get_font_map, gxg_gtk_widget_get_font_map_w, 1, 0, 0, H_gtk_widget_get_font_map, pl_pu); Xg_define_procedure(gdk_window_fullscreen_on_monitor, gxg_gdk_window_fullscreen_on_monitor_w, 2, 0, 0, H_gdk_window_fullscreen_on_monitor, pl_tui); Xg_define_procedure(gtk_window_fullscreen_on_monitor, gxg_gtk_window_fullscreen_on_monitor_w, 3, 0, 0, H_gtk_window_fullscreen_on_monitor, pl_tuui); Xg_define_procedure(gtk_text_view_set_top_margin, gxg_gtk_text_view_set_top_margin_w, 2, 0, 0, H_gtk_text_view_set_top_margin, pl_tui); Xg_define_procedure(gtk_text_view_get_top_margin, gxg_gtk_text_view_get_top_margin_w, 1, 0, 0, H_gtk_text_view_get_top_margin, pl_iu); Xg_define_procedure(gtk_text_view_set_bottom_margin, gxg_gtk_text_view_set_bottom_margin_w, 2, 0, 0, H_gtk_text_view_set_bottom_margin, pl_tui); Xg_define_procedure(gtk_text_view_get_bottom_margin, gxg_gtk_text_view_get_bottom_margin_w, 1, 0, 0, H_gtk_text_view_get_bottom_margin, pl_iu); #endif #if GTK_CHECK_VERSION(3, 20, 0) Xg_define_procedure(gdk_gl_context_is_legacy, gxg_gdk_gl_context_is_legacy_w, 1, 0, 0, H_gdk_gl_context_is_legacy, pl_bu); Xg_define_procedure(gdk_rectangle_equal, gxg_gdk_rectangle_equal_w, 1, 0, 0, H_gdk_rectangle_equal, pl_bu); Xg_define_procedure(gtk_application_window_set_help_overlay, gxg_gtk_application_window_set_help_overlay_w, 2, 0, 0, H_gtk_application_window_set_help_overlay, pl_tu); Xg_define_procedure(gtk_settings_reset_property, gxg_gtk_settings_reset_property_w, 2, 0, 0, H_gtk_settings_reset_property, pl_tus); Xg_define_procedure(gtk_text_tag_changed, gxg_gtk_text_tag_changed_w, 2, 0, 0, H_gtk_text_tag_changed, pl_tub); Xg_define_procedure(gtk_widget_path_iter_get_object_name, gxg_gtk_widget_path_iter_get_object_name_w, 2, 0, 0, H_gtk_widget_path_iter_get_object_name, pl_sui); Xg_define_procedure(gtk_widget_path_iter_set_object_name, gxg_gtk_widget_path_iter_set_object_name_w, 3, 0, 0, H_gtk_widget_path_iter_set_object_name, pl_tuis); Xg_define_procedure(gtk_widget_queue_allocate, gxg_gtk_widget_queue_allocate_w, 1, 0, 0, H_gtk_widget_queue_allocate, pl_tu); Xg_define_procedure(gtk_widget_set_focus_on_click, gxg_gtk_widget_set_focus_on_click_w, 2, 0, 0, H_gtk_widget_set_focus_on_click, pl_tub); Xg_define_procedure(gtk_widget_get_focus_on_click, gxg_gtk_widget_get_focus_on_click_w, 1, 0, 0, H_gtk_widget_get_focus_on_click, pl_bu); Xg_define_procedure(gtk_widget_get_allocated_size, gxg_gtk_widget_get_allocated_size_w, 1, 2, 0, H_gtk_widget_get_allocated_size, pl_tu); #endif Xg_define_procedure(cairo_create, gxg_cairo_create_w, 1, 0, 0, H_cairo_create, pl_pu); Xg_define_procedure(cairo_version, gxg_cairo_version_w, 0, 0, 0, H_cairo_version, pl_i); Xg_define_procedure(cairo_version_string, gxg_cairo_version_string_w, 0, 0, 0, H_cairo_version_string, pl_s); Xg_define_procedure(cairo_reference, gxg_cairo_reference_w, 1, 0, 0, H_cairo_reference, pl_pu); Xg_define_procedure(cairo_destroy, gxg_cairo_destroy_w, 1, 0, 0, H_cairo_destroy, pl_tu); Xg_define_procedure(cairo_save, gxg_cairo_save_w, 1, 0, 0, H_cairo_save, pl_tu); Xg_define_procedure(cairo_restore, gxg_cairo_restore_w, 1, 0, 0, H_cairo_restore, pl_tu); Xg_define_procedure(cairo_push_group, gxg_cairo_push_group_w, 1, 0, 0, H_cairo_push_group, pl_tu); Xg_define_procedure(cairo_push_group_with_content, gxg_cairo_push_group_with_content_w, 2, 0, 0, H_cairo_push_group_with_content, pl_tui); Xg_define_procedure(cairo_pop_group, gxg_cairo_pop_group_w, 1, 0, 0, H_cairo_pop_group, pl_pu); Xg_define_procedure(cairo_pop_group_to_source, gxg_cairo_pop_group_to_source_w, 1, 0, 0, H_cairo_pop_group_to_source, pl_tu); Xg_define_procedure(cairo_set_operator, gxg_cairo_set_operator_w, 2, 0, 0, H_cairo_set_operator, pl_tui); Xg_define_procedure(cairo_set_source, gxg_cairo_set_source_w, 2, 0, 0, H_cairo_set_source, pl_tu); Xg_define_procedure(cairo_set_source_rgb, gxg_cairo_set_source_rgb_w, 4, 0, 0, H_cairo_set_source_rgb, pl_tur); Xg_define_procedure(cairo_set_source_rgba, gxg_cairo_set_source_rgba_w, 5, 0, 0, H_cairo_set_source_rgba, pl_tur); Xg_define_procedure(cairo_set_source_surface, gxg_cairo_set_source_surface_w, 4, 0, 0, H_cairo_set_source_surface, pl_tuur); Xg_define_procedure(cairo_set_tolerance, gxg_cairo_set_tolerance_w, 2, 0, 0, H_cairo_set_tolerance, pl_tur); Xg_define_procedure(cairo_set_antialias, gxg_cairo_set_antialias_w, 2, 0, 0, H_cairo_set_antialias, pl_tui); Xg_define_procedure(cairo_set_fill_rule, gxg_cairo_set_fill_rule_w, 2, 0, 0, H_cairo_set_fill_rule, pl_tui); Xg_define_procedure(cairo_set_line_width, gxg_cairo_set_line_width_w, 2, 0, 0, H_cairo_set_line_width, pl_tur); Xg_define_procedure(cairo_set_line_cap, gxg_cairo_set_line_cap_w, 2, 0, 0, H_cairo_set_line_cap, pl_tui); Xg_define_procedure(cairo_set_line_join, gxg_cairo_set_line_join_w, 2, 0, 0, H_cairo_set_line_join, pl_tui); Xg_define_procedure(cairo_set_dash, gxg_cairo_set_dash_w, 4, 0, 0, H_cairo_set_dash, pl_tuuir); Xg_define_procedure(cairo_set_miter_limit, gxg_cairo_set_miter_limit_w, 2, 0, 0, H_cairo_set_miter_limit, pl_tur); Xg_define_procedure(cairo_translate, gxg_cairo_translate_w, 3, 0, 0, H_cairo_translate, pl_tur); Xg_define_procedure(cairo_scale, gxg_cairo_scale_w, 3, 0, 0, H_cairo_scale, pl_tur); Xg_define_procedure(cairo_rotate, gxg_cairo_rotate_w, 2, 0, 0, H_cairo_rotate, pl_tur); Xg_define_procedure(cairo_transform, gxg_cairo_transform_w, 2, 0, 0, H_cairo_transform, pl_tu); Xg_define_procedure(cairo_set_matrix, gxg_cairo_set_matrix_w, 2, 0, 0, H_cairo_set_matrix, pl_tu); Xg_define_procedure(cairo_identity_matrix, gxg_cairo_identity_matrix_w, 1, 0, 0, H_cairo_identity_matrix, pl_tu); Xg_define_procedure(cairo_user_to_device, gxg_cairo_user_to_device_w, 1, 2, 0, H_cairo_user_to_device, pl_tu); Xg_define_procedure(cairo_user_to_device_distance, gxg_cairo_user_to_device_distance_w, 1, 2, 0, H_cairo_user_to_device_distance, pl_tu); Xg_define_procedure(cairo_device_to_user, gxg_cairo_device_to_user_w, 1, 2, 0, H_cairo_device_to_user, pl_tu); Xg_define_procedure(cairo_device_to_user_distance, gxg_cairo_device_to_user_distance_w, 1, 2, 0, H_cairo_device_to_user_distance, pl_tu); Xg_define_procedure(cairo_new_path, gxg_cairo_new_path_w, 1, 0, 0, H_cairo_new_path, pl_tu); Xg_define_procedure(cairo_move_to, gxg_cairo_move_to_w, 3, 0, 0, H_cairo_move_to, pl_tur); Xg_define_procedure(cairo_new_sub_path, gxg_cairo_new_sub_path_w, 1, 0, 0, H_cairo_new_sub_path, pl_tu); Xg_define_procedure(cairo_line_to, gxg_cairo_line_to_w, 3, 0, 0, H_cairo_line_to, pl_tur); Xg_define_procedure(cairo_curve_to, gxg_cairo_curve_to_w, 7, 0, 0, H_cairo_curve_to, pl_tur); Xg_define_procedure(cairo_arc, gxg_cairo_arc_w, 6, 0, 0, H_cairo_arc, pl_tur); Xg_define_procedure(cairo_arc_negative, gxg_cairo_arc_negative_w, 6, 0, 0, H_cairo_arc_negative, pl_tur); Xg_define_procedure(cairo_rel_move_to, gxg_cairo_rel_move_to_w, 3, 0, 0, H_cairo_rel_move_to, pl_tur); Xg_define_procedure(cairo_rel_line_to, gxg_cairo_rel_line_to_w, 3, 0, 0, H_cairo_rel_line_to, pl_tur); Xg_define_procedure(cairo_rel_curve_to, gxg_cairo_rel_curve_to_w, 7, 0, 0, H_cairo_rel_curve_to, pl_tur); Xg_define_procedure(cairo_rectangle, gxg_cairo_rectangle_w, 5, 0, 0, H_cairo_rectangle, pl_tur); Xg_define_procedure(cairo_close_path, gxg_cairo_close_path_w, 1, 0, 0, H_cairo_close_path, pl_tu); Xg_define_procedure(cairo_paint, gxg_cairo_paint_w, 1, 0, 0, H_cairo_paint, pl_tu); Xg_define_procedure(cairo_paint_with_alpha, gxg_cairo_paint_with_alpha_w, 2, 0, 0, H_cairo_paint_with_alpha, pl_tur); Xg_define_procedure(cairo_mask, gxg_cairo_mask_w, 2, 0, 0, H_cairo_mask, pl_tu); Xg_define_procedure(cairo_mask_surface, gxg_cairo_mask_surface_w, 4, 0, 0, H_cairo_mask_surface, pl_tuur); Xg_define_procedure(cairo_stroke, gxg_cairo_stroke_w, 1, 0, 0, H_cairo_stroke, pl_tu); Xg_define_procedure(cairo_stroke_preserve, gxg_cairo_stroke_preserve_w, 1, 0, 0, H_cairo_stroke_preserve, pl_tu); Xg_define_procedure(cairo_fill, gxg_cairo_fill_w, 1, 0, 0, H_cairo_fill, pl_tu); Xg_define_procedure(cairo_fill_preserve, gxg_cairo_fill_preserve_w, 1, 0, 0, H_cairo_fill_preserve, pl_tu); Xg_define_procedure(cairo_copy_page, gxg_cairo_copy_page_w, 1, 0, 0, H_cairo_copy_page, pl_tu); Xg_define_procedure(cairo_show_page, gxg_cairo_show_page_w, 1, 0, 0, H_cairo_show_page, pl_tu); Xg_define_procedure(cairo_in_stroke, gxg_cairo_in_stroke_w, 3, 0, 0, H_cairo_in_stroke, pl_bur); Xg_define_procedure(cairo_in_fill, gxg_cairo_in_fill_w, 3, 0, 0, H_cairo_in_fill, pl_bur); Xg_define_procedure(cairo_reset_clip, gxg_cairo_reset_clip_w, 1, 0, 0, H_cairo_reset_clip, pl_tu); Xg_define_procedure(cairo_clip, gxg_cairo_clip_w, 1, 0, 0, H_cairo_clip, pl_tu); Xg_define_procedure(cairo_clip_preserve, gxg_cairo_clip_preserve_w, 1, 0, 0, H_cairo_clip_preserve, pl_tu); Xg_define_procedure(cairo_font_options_create, gxg_cairo_font_options_create_w, 0, 0, 0, H_cairo_font_options_create, pl_p); Xg_define_procedure(cairo_font_options_copy, gxg_cairo_font_options_copy_w, 1, 0, 0, H_cairo_font_options_copy, pl_pu); Xg_define_procedure(cairo_font_options_destroy, gxg_cairo_font_options_destroy_w, 1, 0, 0, H_cairo_font_options_destroy, pl_tu); Xg_define_procedure(cairo_font_options_status, gxg_cairo_font_options_status_w, 1, 0, 0, H_cairo_font_options_status, pl_iu); Xg_define_procedure(cairo_font_options_merge, gxg_cairo_font_options_merge_w, 2, 0, 0, H_cairo_font_options_merge, pl_tu); Xg_define_procedure(cairo_font_options_equal, gxg_cairo_font_options_equal_w, 2, 0, 0, H_cairo_font_options_equal, pl_bu); Xg_define_procedure(cairo_font_options_hash, gxg_cairo_font_options_hash_w, 1, 0, 0, H_cairo_font_options_hash, pl_iu); Xg_define_procedure(cairo_font_options_set_antialias, gxg_cairo_font_options_set_antialias_w, 2, 0, 0, H_cairo_font_options_set_antialias, pl_tui); Xg_define_procedure(cairo_font_options_get_antialias, gxg_cairo_font_options_get_antialias_w, 1, 0, 0, H_cairo_font_options_get_antialias, pl_iu); Xg_define_procedure(cairo_font_options_set_subpixel_order, gxg_cairo_font_options_set_subpixel_order_w, 2, 0, 0, H_cairo_font_options_set_subpixel_order, pl_tui); Xg_define_procedure(cairo_font_options_get_subpixel_order, gxg_cairo_font_options_get_subpixel_order_w, 1, 0, 0, H_cairo_font_options_get_subpixel_order, pl_iu); Xg_define_procedure(cairo_font_options_set_hint_style, gxg_cairo_font_options_set_hint_style_w, 2, 0, 0, H_cairo_font_options_set_hint_style, pl_tui); Xg_define_procedure(cairo_font_options_get_hint_style, gxg_cairo_font_options_get_hint_style_w, 1, 0, 0, H_cairo_font_options_get_hint_style, pl_iu); Xg_define_procedure(cairo_font_options_set_hint_metrics, gxg_cairo_font_options_set_hint_metrics_w, 2, 0, 0, H_cairo_font_options_set_hint_metrics, pl_tui); Xg_define_procedure(cairo_font_options_get_hint_metrics, gxg_cairo_font_options_get_hint_metrics_w, 1, 0, 0, H_cairo_font_options_get_hint_metrics, pl_iu); Xg_define_procedure(cairo_select_font_face, gxg_cairo_select_font_face_w, 4, 0, 0, H_cairo_select_font_face, pl_tusi); Xg_define_procedure(cairo_set_font_size, gxg_cairo_set_font_size_w, 2, 0, 0, H_cairo_set_font_size, pl_tur); Xg_define_procedure(cairo_set_font_matrix, gxg_cairo_set_font_matrix_w, 2, 0, 0, H_cairo_set_font_matrix, pl_tu); Xg_define_procedure(cairo_get_font_matrix, gxg_cairo_get_font_matrix_w, 2, 0, 0, H_cairo_get_font_matrix, pl_tu); Xg_define_procedure(cairo_set_font_options, gxg_cairo_set_font_options_w, 2, 0, 0, H_cairo_set_font_options, pl_tu); Xg_define_procedure(cairo_get_font_options, gxg_cairo_get_font_options_w, 2, 0, 0, H_cairo_get_font_options, pl_tu); Xg_define_procedure(cairo_set_scaled_font, gxg_cairo_set_scaled_font_w, 2, 0, 0, H_cairo_set_scaled_font, pl_tu); Xg_define_procedure(cairo_show_text, gxg_cairo_show_text_w, 2, 0, 0, H_cairo_show_text, pl_tus); Xg_define_procedure(cairo_show_glyphs, gxg_cairo_show_glyphs_w, 3, 0, 0, H_cairo_show_glyphs, pl_tuui); Xg_define_procedure(cairo_get_font_face, gxg_cairo_get_font_face_w, 1, 0, 0, H_cairo_get_font_face, pl_pu); Xg_define_procedure(cairo_font_extents, gxg_cairo_font_extents_w, 2, 0, 0, H_cairo_font_extents, pl_tu); Xg_define_procedure(cairo_set_font_face, gxg_cairo_set_font_face_w, 2, 0, 0, H_cairo_set_font_face, pl_tu); Xg_define_procedure(cairo_text_extents, gxg_cairo_text_extents_w, 3, 0, 0, H_cairo_text_extents, pl_tusu); Xg_define_procedure(cairo_glyph_extents, gxg_cairo_glyph_extents_w, 4, 0, 0, H_cairo_glyph_extents, pl_tuuiu); Xg_define_procedure(cairo_text_path, gxg_cairo_text_path_w, 2, 0, 0, H_cairo_text_path, pl_tus); Xg_define_procedure(cairo_glyph_path, gxg_cairo_glyph_path_w, 3, 0, 0, H_cairo_glyph_path, pl_tuui); Xg_define_procedure(cairo_font_face_reference, gxg_cairo_font_face_reference_w, 1, 0, 0, H_cairo_font_face_reference, pl_pu); Xg_define_procedure(cairo_font_face_destroy, gxg_cairo_font_face_destroy_w, 1, 0, 0, H_cairo_font_face_destroy, pl_tu); Xg_define_procedure(cairo_font_face_status, gxg_cairo_font_face_status_w, 1, 0, 0, H_cairo_font_face_status, pl_iu); Xg_define_procedure(cairo_font_face_get_user_data, gxg_cairo_font_face_get_user_data_w, 2, 0, 0, H_cairo_font_face_get_user_data, pl_tu); Xg_define_procedure(cairo_font_face_set_user_data, gxg_cairo_font_face_set_user_data_w, 4, 0, 0, H_cairo_font_face_set_user_data, pl_iuut); Xg_define_procedure(cairo_scaled_font_create, gxg_cairo_scaled_font_create_w, 4, 0, 0, H_cairo_scaled_font_create, pl_pu); Xg_define_procedure(cairo_scaled_font_reference, gxg_cairo_scaled_font_reference_w, 1, 0, 0, H_cairo_scaled_font_reference, pl_pu); Xg_define_procedure(cairo_scaled_font_destroy, gxg_cairo_scaled_font_destroy_w, 1, 0, 0, H_cairo_scaled_font_destroy, pl_tu); Xg_define_procedure(cairo_scaled_font_status, gxg_cairo_scaled_font_status_w, 1, 0, 0, H_cairo_scaled_font_status, pl_iu); Xg_define_procedure(cairo_scaled_font_extents, gxg_cairo_scaled_font_extents_w, 2, 0, 0, H_cairo_scaled_font_extents, pl_tu); Xg_define_procedure(cairo_scaled_font_text_extents, gxg_cairo_scaled_font_text_extents_w, 3, 0, 0, H_cairo_scaled_font_text_extents, pl_tusu); Xg_define_procedure(cairo_scaled_font_glyph_extents, gxg_cairo_scaled_font_glyph_extents_w, 4, 0, 0, H_cairo_scaled_font_glyph_extents, pl_tuuiu); Xg_define_procedure(cairo_scaled_font_get_font_face, gxg_cairo_scaled_font_get_font_face_w, 1, 0, 0, H_cairo_scaled_font_get_font_face, pl_pu); Xg_define_procedure(cairo_scaled_font_get_font_matrix, gxg_cairo_scaled_font_get_font_matrix_w, 2, 0, 0, H_cairo_scaled_font_get_font_matrix, pl_tu); Xg_define_procedure(cairo_scaled_font_get_ctm, gxg_cairo_scaled_font_get_ctm_w, 2, 0, 0, H_cairo_scaled_font_get_ctm, pl_tu); Xg_define_procedure(cairo_scaled_font_get_font_options, gxg_cairo_scaled_font_get_font_options_w, 2, 0, 0, H_cairo_scaled_font_get_font_options, pl_tu); Xg_define_procedure(cairo_get_operator, gxg_cairo_get_operator_w, 1, 0, 0, H_cairo_get_operator, pl_iu); Xg_define_procedure(cairo_get_source, gxg_cairo_get_source_w, 1, 0, 0, H_cairo_get_source, pl_pu); Xg_define_procedure(cairo_get_tolerance, gxg_cairo_get_tolerance_w, 1, 0, 0, H_cairo_get_tolerance, pl_du); Xg_define_procedure(cairo_get_antialias, gxg_cairo_get_antialias_w, 1, 0, 0, H_cairo_get_antialias, pl_iu); Xg_define_procedure(cairo_get_current_point, gxg_cairo_get_current_point_w, 1, 2, 0, H_cairo_get_current_point, pl_tu); Xg_define_procedure(cairo_get_fill_rule, gxg_cairo_get_fill_rule_w, 1, 0, 0, H_cairo_get_fill_rule, pl_iu); Xg_define_procedure(cairo_get_line_width, gxg_cairo_get_line_width_w, 1, 0, 0, H_cairo_get_line_width, pl_du); Xg_define_procedure(cairo_get_line_cap, gxg_cairo_get_line_cap_w, 1, 0, 0, H_cairo_get_line_cap, pl_iu); Xg_define_procedure(cairo_get_line_join, gxg_cairo_get_line_join_w, 1, 0, 0, H_cairo_get_line_join, pl_iu); Xg_define_procedure(cairo_get_miter_limit, gxg_cairo_get_miter_limit_w, 1, 0, 0, H_cairo_get_miter_limit, pl_du); Xg_define_procedure(cairo_get_matrix, gxg_cairo_get_matrix_w, 2, 0, 0, H_cairo_get_matrix, pl_tu); Xg_define_procedure(cairo_get_target, gxg_cairo_get_target_w, 1, 0, 0, H_cairo_get_target, pl_pu); Xg_define_procedure(cairo_get_group_target, gxg_cairo_get_group_target_w, 1, 0, 0, H_cairo_get_group_target, pl_pu); Xg_define_procedure(cairo_copy_path, gxg_cairo_copy_path_w, 1, 0, 0, H_cairo_copy_path, pl_pu); Xg_define_procedure(cairo_copy_path_flat, gxg_cairo_copy_path_flat_w, 1, 0, 0, H_cairo_copy_path_flat, pl_pu); Xg_define_procedure(cairo_append_path, gxg_cairo_append_path_w, 2, 0, 0, H_cairo_append_path, pl_tu); Xg_define_procedure(cairo_path_destroy, gxg_cairo_path_destroy_w, 1, 0, 0, H_cairo_path_destroy, pl_tu); Xg_define_procedure(cairo_status, gxg_cairo_status_w, 1, 0, 0, H_cairo_status, pl_iu); Xg_define_procedure(cairo_status_to_string, gxg_cairo_status_to_string_w, 1, 0, 0, H_cairo_status_to_string, pl_si); Xg_define_procedure(cairo_surface_create_similar, gxg_cairo_surface_create_similar_w, 4, 0, 0, H_cairo_surface_create_similar, pl_pui); Xg_define_procedure(cairo_surface_reference, gxg_cairo_surface_reference_w, 1, 0, 0, H_cairo_surface_reference, pl_pu); Xg_define_procedure(cairo_surface_finish, gxg_cairo_surface_finish_w, 1, 0, 0, H_cairo_surface_finish, pl_tu); Xg_define_procedure(cairo_surface_destroy, gxg_cairo_surface_destroy_w, 1, 0, 0, H_cairo_surface_destroy, pl_tu); Xg_define_procedure(cairo_surface_status, gxg_cairo_surface_status_w, 1, 0, 0, H_cairo_surface_status, pl_iu); Xg_define_procedure(cairo_surface_get_content, gxg_cairo_surface_get_content_w, 1, 0, 0, H_cairo_surface_get_content, pl_iu); Xg_define_procedure(cairo_surface_get_user_data, gxg_cairo_surface_get_user_data_w, 2, 0, 0, H_cairo_surface_get_user_data, pl_tu); Xg_define_procedure(cairo_surface_set_user_data, gxg_cairo_surface_set_user_data_w, 4, 0, 0, H_cairo_surface_set_user_data, pl_iuut); Xg_define_procedure(cairo_surface_get_font_options, gxg_cairo_surface_get_font_options_w, 2, 0, 0, H_cairo_surface_get_font_options, pl_tu); Xg_define_procedure(cairo_surface_flush, gxg_cairo_surface_flush_w, 1, 0, 0, H_cairo_surface_flush, pl_tu); Xg_define_procedure(cairo_surface_mark_dirty, gxg_cairo_surface_mark_dirty_w, 1, 0, 0, H_cairo_surface_mark_dirty, pl_tu); Xg_define_procedure(cairo_surface_mark_dirty_rectangle, gxg_cairo_surface_mark_dirty_rectangle_w, 5, 0, 0, H_cairo_surface_mark_dirty_rectangle, pl_tui); Xg_define_procedure(cairo_surface_set_device_offset, gxg_cairo_surface_set_device_offset_w, 3, 0, 0, H_cairo_surface_set_device_offset, pl_tur); Xg_define_procedure(cairo_surface_get_device_offset, gxg_cairo_surface_get_device_offset_w, 1, 2, 0, H_cairo_surface_get_device_offset, pl_tu); Xg_define_procedure(cairo_surface_set_fallback_resolution, gxg_cairo_surface_set_fallback_resolution_w, 3, 0, 0, H_cairo_surface_set_fallback_resolution, pl_tur); Xg_define_procedure(cairo_image_surface_create, gxg_cairo_image_surface_create_w, 3, 0, 0, H_cairo_image_surface_create, pl_pi); Xg_define_procedure(cairo_image_surface_create_for_data, gxg_cairo_image_surface_create_for_data_w, 5, 0, 0, H_cairo_image_surface_create_for_data, pl_psi); Xg_define_procedure(cairo_image_surface_get_data, gxg_cairo_image_surface_get_data_w, 1, 0, 0, H_cairo_image_surface_get_data, pl_su); Xg_define_procedure(cairo_image_surface_get_format, gxg_cairo_image_surface_get_format_w, 1, 0, 0, H_cairo_image_surface_get_format, pl_iu); Xg_define_procedure(cairo_image_surface_get_width, gxg_cairo_image_surface_get_width_w, 1, 0, 0, H_cairo_image_surface_get_width, pl_iu); Xg_define_procedure(cairo_image_surface_get_height, gxg_cairo_image_surface_get_height_w, 1, 0, 0, H_cairo_image_surface_get_height, pl_iu); Xg_define_procedure(cairo_image_surface_get_stride, gxg_cairo_image_surface_get_stride_w, 1, 0, 0, H_cairo_image_surface_get_stride, pl_iu); Xg_define_procedure(cairo_pattern_create_rgb, gxg_cairo_pattern_create_rgb_w, 3, 0, 0, H_cairo_pattern_create_rgb, pl_pr); Xg_define_procedure(cairo_pattern_create_rgba, gxg_cairo_pattern_create_rgba_w, 4, 0, 0, H_cairo_pattern_create_rgba, pl_pr); Xg_define_procedure(cairo_pattern_create_for_surface, gxg_cairo_pattern_create_for_surface_w, 1, 0, 0, H_cairo_pattern_create_for_surface, pl_pu); Xg_define_procedure(cairo_pattern_create_linear, gxg_cairo_pattern_create_linear_w, 4, 0, 0, H_cairo_pattern_create_linear, pl_pr); Xg_define_procedure(cairo_pattern_create_radial, gxg_cairo_pattern_create_radial_w, 6, 0, 0, H_cairo_pattern_create_radial, pl_pr); Xg_define_procedure(cairo_pattern_reference, gxg_cairo_pattern_reference_w, 1, 0, 0, H_cairo_pattern_reference, pl_pu); Xg_define_procedure(cairo_pattern_destroy, gxg_cairo_pattern_destroy_w, 1, 0, 0, H_cairo_pattern_destroy, pl_tu); Xg_define_procedure(cairo_pattern_status, gxg_cairo_pattern_status_w, 1, 0, 0, H_cairo_pattern_status, pl_iu); Xg_define_procedure(cairo_pattern_add_color_stop_rgb, gxg_cairo_pattern_add_color_stop_rgb_w, 5, 0, 0, H_cairo_pattern_add_color_stop_rgb, pl_tur); Xg_define_procedure(cairo_pattern_add_color_stop_rgba, gxg_cairo_pattern_add_color_stop_rgba_w, 6, 0, 0, H_cairo_pattern_add_color_stop_rgba, pl_tur); Xg_define_procedure(cairo_pattern_set_matrix, gxg_cairo_pattern_set_matrix_w, 2, 0, 0, H_cairo_pattern_set_matrix, pl_tu); Xg_define_procedure(cairo_pattern_get_matrix, gxg_cairo_pattern_get_matrix_w, 2, 0, 0, H_cairo_pattern_get_matrix, pl_tu); Xg_define_procedure(cairo_pattern_set_extend, gxg_cairo_pattern_set_extend_w, 2, 0, 0, H_cairo_pattern_set_extend, pl_tui); Xg_define_procedure(cairo_pattern_get_extend, gxg_cairo_pattern_get_extend_w, 1, 0, 0, H_cairo_pattern_get_extend, pl_iu); Xg_define_procedure(cairo_pattern_set_filter, gxg_cairo_pattern_set_filter_w, 2, 0, 0, H_cairo_pattern_set_filter, pl_tui); Xg_define_procedure(cairo_pattern_get_filter, gxg_cairo_pattern_get_filter_w, 1, 0, 0, H_cairo_pattern_get_filter, pl_iu); Xg_define_procedure(cairo_matrix_init, gxg_cairo_matrix_init_w, 7, 0, 0, H_cairo_matrix_init, pl_tur); Xg_define_procedure(cairo_matrix_init_identity, gxg_cairo_matrix_init_identity_w, 1, 0, 0, H_cairo_matrix_init_identity, pl_tu); Xg_define_procedure(cairo_matrix_init_translate, gxg_cairo_matrix_init_translate_w, 3, 0, 0, H_cairo_matrix_init_translate, pl_tur); Xg_define_procedure(cairo_matrix_init_scale, gxg_cairo_matrix_init_scale_w, 3, 0, 0, H_cairo_matrix_init_scale, pl_tur); Xg_define_procedure(cairo_matrix_init_rotate, gxg_cairo_matrix_init_rotate_w, 2, 0, 0, H_cairo_matrix_init_rotate, pl_tur); Xg_define_procedure(cairo_matrix_translate, gxg_cairo_matrix_translate_w, 3, 0, 0, H_cairo_matrix_translate, pl_tur); Xg_define_procedure(cairo_matrix_scale, gxg_cairo_matrix_scale_w, 3, 0, 0, H_cairo_matrix_scale, pl_tur); Xg_define_procedure(cairo_matrix_rotate, gxg_cairo_matrix_rotate_w, 2, 0, 0, H_cairo_matrix_rotate, pl_tur); Xg_define_procedure(cairo_matrix_invert, gxg_cairo_matrix_invert_w, 1, 0, 0, H_cairo_matrix_invert, pl_iu); Xg_define_procedure(cairo_matrix_multiply, gxg_cairo_matrix_multiply_w, 3, 0, 0, H_cairo_matrix_multiply, pl_tu); Xg_define_procedure(cairo_matrix_transform_distance, gxg_cairo_matrix_transform_distance_w, 1, 2, 0, H_cairo_matrix_transform_distance, pl_tu); Xg_define_procedure(cairo_matrix_transform_point, gxg_cairo_matrix_transform_point_w, 1, 2, 0, H_cairo_matrix_transform_point, pl_tu); Xg_define_procedure(cairo_get_reference_count, gxg_cairo_get_reference_count_w, 1, 0, 0, H_cairo_get_reference_count, pl_iu); Xg_define_procedure(cairo_get_user_data, gxg_cairo_get_user_data_w, 2, 0, 0, H_cairo_get_user_data, pl_pu); Xg_define_procedure(cairo_set_user_data, gxg_cairo_set_user_data_w, 4, 0, 0, H_cairo_set_user_data, pl_iuuut); Xg_define_procedure(cairo_clip_extents, gxg_cairo_clip_extents_w, 1, 4, 0, H_cairo_clip_extents, pl_tu); Xg_define_procedure(cairo_copy_clip_rectangle_list, gxg_cairo_copy_clip_rectangle_list_w, 1, 0, 0, H_cairo_copy_clip_rectangle_list, pl_pu); Xg_define_procedure(cairo_rectangle_list_destroy, gxg_cairo_rectangle_list_destroy_w, 1, 0, 0, H_cairo_rectangle_list_destroy, pl_tu); Xg_define_procedure(cairo_font_face_get_reference_count, gxg_cairo_font_face_get_reference_count_w, 1, 0, 0, H_cairo_font_face_get_reference_count, pl_iu); Xg_define_procedure(cairo_scaled_font_get_reference_count, gxg_cairo_scaled_font_get_reference_count_w, 1, 0, 0, H_cairo_scaled_font_get_reference_count, pl_iu); Xg_define_procedure(cairo_scaled_font_get_user_data, gxg_cairo_scaled_font_get_user_data_w, 2, 0, 0, H_cairo_scaled_font_get_user_data, pl_pu); Xg_define_procedure(cairo_scaled_font_set_user_data, gxg_cairo_scaled_font_set_user_data_w, 4, 0, 0, H_cairo_scaled_font_set_user_data, pl_iuuut); Xg_define_procedure(cairo_get_dash_count, gxg_cairo_get_dash_count_w, 1, 0, 0, H_cairo_get_dash_count, pl_iu); Xg_define_procedure(cairo_get_dash, gxg_cairo_get_dash_w, 1, 2, 0, H_cairo_get_dash, pl_tu); Xg_define_procedure(cairo_surface_get_reference_count, gxg_cairo_surface_get_reference_count_w, 1, 0, 0, H_cairo_surface_get_reference_count, pl_iu); Xg_define_procedure(cairo_pattern_get_reference_count, gxg_cairo_pattern_get_reference_count_w, 1, 0, 0, H_cairo_pattern_get_reference_count, pl_iu); Xg_define_procedure(cairo_pattern_get_user_data, gxg_cairo_pattern_get_user_data_w, 2, 0, 0, H_cairo_pattern_get_user_data, pl_pu); Xg_define_procedure(cairo_pattern_set_user_data, gxg_cairo_pattern_set_user_data_w, 4, 0, 0, H_cairo_pattern_set_user_data, pl_iuuut); Xg_define_procedure(cairo_pattern_get_rgba, gxg_cairo_pattern_get_rgba_w, 1, 4, 0, H_cairo_pattern_get_rgba, pl_iu); Xg_define_procedure(cairo_pattern_get_surface, gxg_cairo_pattern_get_surface_w, 1, 1, 0, H_cairo_pattern_get_surface, pl_iu); Xg_define_procedure(cairo_pattern_get_color_stop_rgba, gxg_cairo_pattern_get_color_stop_rgba_w, 2, 5, 0, H_cairo_pattern_get_color_stop_rgba, pl_iuiu); Xg_define_procedure(cairo_pattern_get_color_stop_count, gxg_cairo_pattern_get_color_stop_count_w, 1, 1, 0, H_cairo_pattern_get_color_stop_count, pl_iu); Xg_define_procedure(cairo_pattern_get_linear_points, gxg_cairo_pattern_get_linear_points_w, 1, 4, 0, H_cairo_pattern_get_linear_points, pl_iu); Xg_define_procedure(cairo_pattern_get_radial_circles, gxg_cairo_pattern_get_radial_circles_w, 1, 6, 0, H_cairo_pattern_get_radial_circles, pl_iu); Xg_define_procedure(cairo_get_scaled_font, gxg_cairo_get_scaled_font_w, 1, 0, 0, H_cairo_get_scaled_font, pl_pu); Xg_define_procedure(cairo_path_extents, gxg_cairo_path_extents_w, 1, 4, 0, H_cairo_path_extents, pl_tu); Xg_define_procedure(cairo_has_current_point, gxg_cairo_has_current_point_w, 1, 0, 0, H_cairo_has_current_point, pl_bu); Xg_define_procedure(cairo_surface_copy_page, gxg_cairo_surface_copy_page_w, 1, 0, 0, H_cairo_surface_copy_page, pl_tu); Xg_define_procedure(cairo_surface_show_page, gxg_cairo_surface_show_page_w, 1, 0, 0, H_cairo_surface_show_page, pl_tu); Xg_define_procedure(cairo_format_stride_for_width, gxg_cairo_format_stride_for_width_w, 2, 0, 0, H_cairo_format_stride_for_width, pl_i); Xg_define_procedure(cairo_image_surface_create_from_png, gxg_cairo_image_surface_create_from_png_w, 1, 0, 0, H_cairo_image_surface_create_from_png, pl_ps); Xg_define_procedure(cairo_surface_write_to_png, gxg_cairo_surface_write_to_png_w, 2, 0, 0, H_cairo_surface_write_to_png, pl_ius); #if HAVE_CAIRO_1_8 Xg_define_procedure(cairo_glyph_allocate, gxg_cairo_glyph_allocate_w, 1, 0, 0, H_cairo_glyph_allocate, pl_pi); Xg_define_procedure(cairo_glyph_free, gxg_cairo_glyph_free_w, 1, 0, 0, H_cairo_glyph_free, pl_tu); Xg_define_procedure(cairo_text_cluster_allocate, gxg_cairo_text_cluster_allocate_w, 1, 0, 0, H_cairo_text_cluster_allocate, pl_pi); Xg_define_procedure(cairo_text_cluster_free, gxg_cairo_text_cluster_free_w, 1, 0, 0, H_cairo_text_cluster_free, pl_tu); Xg_define_procedure(cairo_show_text_glyphs, gxg_cairo_show_text_glyphs_w, 0, 0, 1, H_cairo_show_text_glyphs, pl_tusiuiuit); Xg_define_procedure(cairo_scaled_font_text_to_glyphs, gxg_cairo_scaled_font_text_to_glyphs_w, 0, 0, 1, H_cairo_scaled_font_text_to_glyphs, pl_iurrsiu); Xg_define_procedure(cairo_scaled_font_get_scale_matrix, gxg_cairo_scaled_font_get_scale_matrix_w, 2, 0, 0, H_cairo_scaled_font_get_scale_matrix, pl_tu); Xg_define_procedure(cairo_toy_font_face_create, gxg_cairo_toy_font_face_create_w, 3, 0, 0, H_cairo_toy_font_face_create, pl_psi); Xg_define_procedure(cairo_toy_font_face_get_family, gxg_cairo_toy_font_face_get_family_w, 1, 0, 0, H_cairo_toy_font_face_get_family, pl_su); Xg_define_procedure(cairo_toy_font_face_get_slant, gxg_cairo_toy_font_face_get_slant_w, 1, 0, 0, H_cairo_toy_font_face_get_slant, pl_iu); Xg_define_procedure(cairo_toy_font_face_get_weight, gxg_cairo_toy_font_face_get_weight_w, 1, 0, 0, H_cairo_toy_font_face_get_weight, pl_iu); Xg_define_procedure(cairo_user_font_face_create, gxg_cairo_user_font_face_create_w, 0, 0, 0, H_cairo_user_font_face_create, pl_p); Xg_define_procedure(cairo_surface_get_fallback_resolution, gxg_cairo_surface_get_fallback_resolution_w, 1, 2, 0, H_cairo_surface_get_fallback_resolution, pl_tu); Xg_define_procedure(cairo_surface_has_show_text_glyphs, gxg_cairo_surface_has_show_text_glyphs_w, 1, 0, 0, H_cairo_surface_has_show_text_glyphs, pl_iu); #endif #if HAVE_CAIRO_1_9_12 && GTK_CHECK_VERSION(3, 0, 0) Xg_define_procedure(cairo_in_clip, gxg_cairo_in_clip_w, 3, 0, 0, H_cairo_in_clip, pl_iur); Xg_define_procedure(cairo_device_reference, gxg_cairo_device_reference_w, 1, 0, 0, H_cairo_device_reference, pl_pu); Xg_define_procedure(cairo_device_status, gxg_cairo_device_status_w, 1, 0, 0, H_cairo_device_status, pl_iu); Xg_define_procedure(cairo_device_acquire, gxg_cairo_device_acquire_w, 1, 0, 0, H_cairo_device_acquire, pl_iu); Xg_define_procedure(cairo_device_release, gxg_cairo_device_release_w, 1, 0, 0, H_cairo_device_release, pl_tu); Xg_define_procedure(cairo_device_flush, gxg_cairo_device_flush_w, 1, 0, 0, H_cairo_device_flush, pl_tu); Xg_define_procedure(cairo_device_finish, gxg_cairo_device_finish_w, 1, 0, 0, H_cairo_device_finish, pl_tu); Xg_define_procedure(cairo_device_destroy, gxg_cairo_device_destroy_w, 1, 0, 0, H_cairo_device_destroy, pl_tu); Xg_define_procedure(cairo_device_get_reference_count, gxg_cairo_device_get_reference_count_w, 1, 0, 0, H_cairo_device_get_reference_count, pl_iu); Xg_define_procedure(cairo_device_get_user_data, gxg_cairo_device_get_user_data_w, 2, 0, 0, H_cairo_device_get_user_data, pl_pu); Xg_define_procedure(cairo_device_set_user_data, gxg_cairo_device_set_user_data_w, 4, 0, 0, H_cairo_device_set_user_data, pl_iuuut); Xg_define_procedure(cairo_surface_create_for_rectangle, gxg_cairo_surface_create_for_rectangle_w, 5, 0, 0, H_cairo_surface_create_for_rectangle, pl_pur); Xg_define_procedure(cairo_surface_get_device, gxg_cairo_surface_get_device_w, 1, 0, 0, H_cairo_surface_get_device, pl_pu); Xg_define_procedure(cairo_surface_set_mime_data, gxg_cairo_surface_set_mime_data_w, 6, 0, 0, H_cairo_surface_set_mime_data, pl_iussitu); Xg_define_procedure(cairo_recording_surface_create, gxg_cairo_recording_surface_create_w, 2, 0, 0, H_cairo_recording_surface_create, pl_piu); Xg_define_procedure(cairo_recording_surface_ink_extents, gxg_cairo_recording_surface_ink_extents_w, 5, 0, 0, H_cairo_recording_surface_ink_extents, pl_tu); Xg_define_procedure(cairo_region_create, gxg_cairo_region_create_w, 0, 0, 0, H_cairo_region_create, pl_p); Xg_define_procedure(cairo_region_create_rectangle, gxg_cairo_region_create_rectangle_w, 1, 0, 0, H_cairo_region_create_rectangle, pl_pu); Xg_define_procedure(cairo_region_create_rectangles, gxg_cairo_region_create_rectangles_w, 2, 0, 0, H_cairo_region_create_rectangles, pl_pui); Xg_define_procedure(cairo_region_copy, gxg_cairo_region_copy_w, 1, 0, 0, H_cairo_region_copy, pl_pu); Xg_define_procedure(cairo_region_reference, gxg_cairo_region_reference_w, 1, 0, 0, H_cairo_region_reference, pl_pu); Xg_define_procedure(cairo_region_destroy, gxg_cairo_region_destroy_w, 1, 0, 0, H_cairo_region_destroy, pl_tu); Xg_define_procedure(cairo_region_equal, gxg_cairo_region_equal_w, 2, 0, 0, H_cairo_region_equal, pl_iu); Xg_define_procedure(cairo_region_status, gxg_cairo_region_status_w, 1, 0, 0, H_cairo_region_status, pl_iu); Xg_define_procedure(cairo_region_get_extents, gxg_cairo_region_get_extents_w, 2, 0, 0, H_cairo_region_get_extents, pl_tu); Xg_define_procedure(cairo_region_num_rectangles, gxg_cairo_region_num_rectangles_w, 1, 0, 0, H_cairo_region_num_rectangles, pl_iu); Xg_define_procedure(cairo_region_get_rectangle, gxg_cairo_region_get_rectangle_w, 3, 0, 0, H_cairo_region_get_rectangle, pl_tuiu); Xg_define_procedure(cairo_region_is_empty, gxg_cairo_region_is_empty_w, 1, 0, 0, H_cairo_region_is_empty, pl_iu); Xg_define_procedure(cairo_region_contains_rectangle, gxg_cairo_region_contains_rectangle_w, 2, 0, 0, H_cairo_region_contains_rectangle, pl_tu); Xg_define_procedure(cairo_region_contains_point, gxg_cairo_region_contains_point_w, 3, 0, 0, H_cairo_region_contains_point, pl_iui); Xg_define_procedure(cairo_region_translate, gxg_cairo_region_translate_w, 3, 0, 0, H_cairo_region_translate, pl_tui); Xg_define_procedure(cairo_region_subtract, gxg_cairo_region_subtract_w, 2, 0, 0, H_cairo_region_subtract, pl_iu); Xg_define_procedure(cairo_region_subtract_rectangle, gxg_cairo_region_subtract_rectangle_w, 2, 0, 0, H_cairo_region_subtract_rectangle, pl_iu); Xg_define_procedure(cairo_region_intersect, gxg_cairo_region_intersect_w, 2, 0, 0, H_cairo_region_intersect, pl_iu); Xg_define_procedure(cairo_region_intersect_rectangle, gxg_cairo_region_intersect_rectangle_w, 2, 0, 0, H_cairo_region_intersect_rectangle, pl_iu); Xg_define_procedure(cairo_region_union, gxg_cairo_region_union_w, 2, 0, 0, H_cairo_region_union, pl_iu); Xg_define_procedure(cairo_region_union_rectangle, gxg_cairo_region_union_rectangle_w, 2, 0, 0, H_cairo_region_union_rectangle, pl_iu); Xg_define_procedure(cairo_region_xor, gxg_cairo_region_xor_w, 2, 0, 0, H_cairo_region_xor, pl_iu); Xg_define_procedure(cairo_region_xor_rectangle, gxg_cairo_region_xor_rectangle_w, 2, 0, 0, H_cairo_region_xor_rectangle, pl_iu); #endif Xg_define_procedure(GPOINTER, gxg_GPOINTER_w, 1, 0, 0, "(GPOINTER obj) casts obj to GPOINTER", NULL); Xg_define_procedure(GDK_DRAG_CONTEXT, gxg_GDK_DRAG_CONTEXT_w, 1, 0, 0, "(GDK_DRAG_CONTEXT obj) casts obj to GDK_DRAG_CONTEXT", NULL); Xg_define_procedure(GDK_DEVICE, gxg_GDK_DEVICE_w, 1, 0, 0, "(GDK_DEVICE obj) casts obj to GDK_DEVICE", NULL); Xg_define_procedure(GDK_KEYMAP, gxg_GDK_KEYMAP_w, 1, 0, 0, "(GDK_KEYMAP obj) casts obj to GDK_KEYMAP", NULL); Xg_define_procedure(GDK_VISUAL, gxg_GDK_VISUAL_w, 1, 0, 0, "(GDK_VISUAL obj) casts obj to GDK_VISUAL", NULL); Xg_define_procedure(GDK_WINDOW, gxg_GDK_WINDOW_w, 1, 0, 0, "(GDK_WINDOW obj) casts obj to GDK_WINDOW", NULL); Xg_define_procedure(GDK_PIXBUF, gxg_GDK_PIXBUF_w, 1, 0, 0, "(GDK_PIXBUF obj) casts obj to GDK_PIXBUF", NULL); Xg_define_procedure(GDK_PIXBUF_ANIMATION, gxg_GDK_PIXBUF_ANIMATION_w, 1, 0, 0, "(GDK_PIXBUF_ANIMATION obj) casts obj to GDK_PIXBUF_ANIMATION", NULL); Xg_define_procedure(GDK_PIXBUF_ANIMATION_ITER, gxg_GDK_PIXBUF_ANIMATION_ITER_w, 1, 0, 0, "(GDK_PIXBUF_ANIMATION_ITER obj) casts obj to GDK_PIXBUF_ANIMATION_ITER", NULL); Xg_define_procedure(GTK_ACCEL_GROUP, gxg_GTK_ACCEL_GROUP_w, 1, 0, 0, "(GTK_ACCEL_GROUP obj) casts obj to GTK_ACCEL_GROUP", NULL); Xg_define_procedure(GTK_ACCEL_LABEL, gxg_GTK_ACCEL_LABEL_w, 1, 0, 0, "(GTK_ACCEL_LABEL obj) casts obj to GTK_ACCEL_LABEL", NULL); Xg_define_procedure(GTK_ACCESSIBLE, gxg_GTK_ACCESSIBLE_w, 1, 0, 0, "(GTK_ACCESSIBLE obj) casts obj to GTK_ACCESSIBLE", NULL); Xg_define_procedure(GTK_ADJUSTMENT, gxg_GTK_ADJUSTMENT_w, 1, 0, 0, "(GTK_ADJUSTMENT obj) casts obj to GTK_ADJUSTMENT", NULL); Xg_define_procedure(GTK_ASPECT_FRAME, gxg_GTK_ASPECT_FRAME_w, 1, 0, 0, "(GTK_ASPECT_FRAME obj) casts obj to GTK_ASPECT_FRAME", NULL); Xg_define_procedure(GTK_BUTTON_BOX, gxg_GTK_BUTTON_BOX_w, 1, 0, 0, "(GTK_BUTTON_BOX obj) casts obj to GTK_BUTTON_BOX", NULL); Xg_define_procedure(GTK_BIN, gxg_GTK_BIN_w, 1, 0, 0, "(GTK_BIN obj) casts obj to GTK_BIN", NULL); Xg_define_procedure(GTK_BOX, gxg_GTK_BOX_w, 1, 0, 0, "(GTK_BOX obj) casts obj to GTK_BOX", NULL); Xg_define_procedure(GTK_BUTTON, gxg_GTK_BUTTON_w, 1, 0, 0, "(GTK_BUTTON obj) casts obj to GTK_BUTTON", NULL); Xg_define_procedure(GTK_CALENDAR, gxg_GTK_CALENDAR_w, 1, 0, 0, "(GTK_CALENDAR obj) casts obj to GTK_CALENDAR", NULL); Xg_define_procedure(GTK_CELL_EDITABLE, gxg_GTK_CELL_EDITABLE_w, 1, 0, 0, "(GTK_CELL_EDITABLE obj) casts obj to GTK_CELL_EDITABLE", NULL); Xg_define_procedure(GTK_CELL_RENDERER, gxg_GTK_CELL_RENDERER_w, 1, 0, 0, "(GTK_CELL_RENDERER obj) casts obj to GTK_CELL_RENDERER", NULL); Xg_define_procedure(GTK_CELL_RENDERER_PIXBUF, gxg_GTK_CELL_RENDERER_PIXBUF_w, 1, 0, 0, "(GTK_CELL_RENDERER_PIXBUF obj) casts obj to GTK_CELL_RENDERER_PIXBUF", NULL); Xg_define_procedure(GTK_CELL_RENDERER_TEXT, gxg_GTK_CELL_RENDERER_TEXT_w, 1, 0, 0, "(GTK_CELL_RENDERER_TEXT obj) casts obj to GTK_CELL_RENDERER_TEXT", NULL); Xg_define_procedure(GTK_CELL_RENDERER_TOGGLE, gxg_GTK_CELL_RENDERER_TOGGLE_w, 1, 0, 0, "(GTK_CELL_RENDERER_TOGGLE obj) casts obj to GTK_CELL_RENDERER_TOGGLE", NULL); Xg_define_procedure(GTK_CHECK_BUTTON, gxg_GTK_CHECK_BUTTON_w, 1, 0, 0, "(GTK_CHECK_BUTTON obj) casts obj to GTK_CHECK_BUTTON", NULL); Xg_define_procedure(GTK_CHECK_MENU_ITEM, gxg_GTK_CHECK_MENU_ITEM_w, 1, 0, 0, "(GTK_CHECK_MENU_ITEM obj) casts obj to GTK_CHECK_MENU_ITEM", NULL); Xg_define_procedure(GTK_CONTAINER, gxg_GTK_CONTAINER_w, 1, 0, 0, "(GTK_CONTAINER obj) casts obj to GTK_CONTAINER", NULL); Xg_define_procedure(GTK_DIALOG, gxg_GTK_DIALOG_w, 1, 0, 0, "(GTK_DIALOG obj) casts obj to GTK_DIALOG", NULL); Xg_define_procedure(GTK_DRAWING_AREA, gxg_GTK_DRAWING_AREA_w, 1, 0, 0, "(GTK_DRAWING_AREA obj) casts obj to GTK_DRAWING_AREA", NULL); Xg_define_procedure(GTK_EDITABLE, gxg_GTK_EDITABLE_w, 1, 0, 0, "(GTK_EDITABLE obj) casts obj to GTK_EDITABLE", NULL); Xg_define_procedure(GTK_ENTRY, gxg_GTK_ENTRY_w, 1, 0, 0, "(GTK_ENTRY obj) casts obj to GTK_ENTRY", NULL); Xg_define_procedure(GTK_EVENT_BOX, gxg_GTK_EVENT_BOX_w, 1, 0, 0, "(GTK_EVENT_BOX obj) casts obj to GTK_EVENT_BOX", NULL); Xg_define_procedure(GTK_FIXED, gxg_GTK_FIXED_w, 1, 0, 0, "(GTK_FIXED obj) casts obj to GTK_FIXED", NULL); Xg_define_procedure(GTK_FRAME, gxg_GTK_FRAME_w, 1, 0, 0, "(GTK_FRAME obj) casts obj to GTK_FRAME", NULL); Xg_define_procedure(GTK_IMAGE, gxg_GTK_IMAGE_w, 1, 0, 0, "(GTK_IMAGE obj) casts obj to GTK_IMAGE", NULL); Xg_define_procedure(GTK_IM_CONTEXT, gxg_GTK_IM_CONTEXT_w, 1, 0, 0, "(GTK_IM_CONTEXT obj) casts obj to GTK_IM_CONTEXT", NULL); Xg_define_procedure(GTK_IM_CONTEXT_SIMPLE, gxg_GTK_IM_CONTEXT_SIMPLE_w, 1, 0, 0, "(GTK_IM_CONTEXT_SIMPLE obj) casts obj to GTK_IM_CONTEXT_SIMPLE", NULL); Xg_define_procedure(GTK_INVISIBLE, gxg_GTK_INVISIBLE_w, 1, 0, 0, "(GTK_INVISIBLE obj) casts obj to GTK_INVISIBLE", NULL); Xg_define_procedure(GTK_LABEL, gxg_GTK_LABEL_w, 1, 0, 0, "(GTK_LABEL obj) casts obj to GTK_LABEL", NULL); Xg_define_procedure(GTK_LAYOUT, gxg_GTK_LAYOUT_w, 1, 0, 0, "(GTK_LAYOUT obj) casts obj to GTK_LAYOUT", NULL); Xg_define_procedure(GTK_LIST_STORE, gxg_GTK_LIST_STORE_w, 1, 0, 0, "(GTK_LIST_STORE obj) casts obj to GTK_LIST_STORE", NULL); Xg_define_procedure(GTK_MENU_BAR, gxg_GTK_MENU_BAR_w, 1, 0, 0, "(GTK_MENU_BAR obj) casts obj to GTK_MENU_BAR", NULL); Xg_define_procedure(GTK_MENU, gxg_GTK_MENU_w, 1, 0, 0, "(GTK_MENU obj) casts obj to GTK_MENU", NULL); Xg_define_procedure(GTK_MENU_ITEM, gxg_GTK_MENU_ITEM_w, 1, 0, 0, "(GTK_MENU_ITEM obj) casts obj to GTK_MENU_ITEM", NULL); Xg_define_procedure(GTK_MENU_SHELL, gxg_GTK_MENU_SHELL_w, 1, 0, 0, "(GTK_MENU_SHELL obj) casts obj to GTK_MENU_SHELL", NULL); Xg_define_procedure(GTK_NOTEBOOK, gxg_GTK_NOTEBOOK_w, 1, 0, 0, "(GTK_NOTEBOOK obj) casts obj to GTK_NOTEBOOK", NULL); Xg_define_procedure(GTK_PANED, gxg_GTK_PANED_w, 1, 0, 0, "(GTK_PANED obj) casts obj to GTK_PANED", NULL); Xg_define_procedure(GTK_PROGRESS_BAR, gxg_GTK_PROGRESS_BAR_w, 1, 0, 0, "(GTK_PROGRESS_BAR obj) casts obj to GTK_PROGRESS_BAR", NULL); Xg_define_procedure(GTK_RADIO_BUTTON, gxg_GTK_RADIO_BUTTON_w, 1, 0, 0, "(GTK_RADIO_BUTTON obj) casts obj to GTK_RADIO_BUTTON", NULL); Xg_define_procedure(GTK_RADIO_MENU_ITEM, gxg_GTK_RADIO_MENU_ITEM_w, 1, 0, 0, "(GTK_RADIO_MENU_ITEM obj) casts obj to GTK_RADIO_MENU_ITEM", NULL); Xg_define_procedure(GTK_RANGE, gxg_GTK_RANGE_w, 1, 0, 0, "(GTK_RANGE obj) casts obj to GTK_RANGE", NULL); Xg_define_procedure(GTK_SCALE, gxg_GTK_SCALE_w, 1, 0, 0, "(GTK_SCALE obj) casts obj to GTK_SCALE", NULL); Xg_define_procedure(GTK_SCROLLBAR, gxg_GTK_SCROLLBAR_w, 1, 0, 0, "(GTK_SCROLLBAR obj) casts obj to GTK_SCROLLBAR", NULL); Xg_define_procedure(GTK_SCROLLED_WINDOW, gxg_GTK_SCROLLED_WINDOW_w, 1, 0, 0, "(GTK_SCROLLED_WINDOW obj) casts obj to GTK_SCROLLED_WINDOW", NULL); Xg_define_procedure(GTK_SEPARATOR, gxg_GTK_SEPARATOR_w, 1, 0, 0, "(GTK_SEPARATOR obj) casts obj to GTK_SEPARATOR", NULL); Xg_define_procedure(GTK_SEPARATOR_MENU_ITEM, gxg_GTK_SEPARATOR_MENU_ITEM_w, 1, 0, 0, "(GTK_SEPARATOR_MENU_ITEM obj) casts obj to GTK_SEPARATOR_MENU_ITEM", NULL); Xg_define_procedure(GTK_SETTINGS, gxg_GTK_SETTINGS_w, 1, 0, 0, "(GTK_SETTINGS obj) casts obj to GTK_SETTINGS", NULL); Xg_define_procedure(GTK_SIZE_GROUP, gxg_GTK_SIZE_GROUP_w, 1, 0, 0, "(GTK_SIZE_GROUP obj) casts obj to GTK_SIZE_GROUP", NULL); Xg_define_procedure(GTK_SPIN_BUTTON, gxg_GTK_SPIN_BUTTON_w, 1, 0, 0, "(GTK_SPIN_BUTTON obj) casts obj to GTK_SPIN_BUTTON", NULL); Xg_define_procedure(GTK_STATUSBAR, gxg_GTK_STATUSBAR_w, 1, 0, 0, "(GTK_STATUSBAR obj) casts obj to GTK_STATUSBAR", NULL); Xg_define_procedure(GTK_TEXT_BUFFER, gxg_GTK_TEXT_BUFFER_w, 1, 0, 0, "(GTK_TEXT_BUFFER obj) casts obj to GTK_TEXT_BUFFER", NULL); Xg_define_procedure(GTK_TEXT_CHILD_ANCHOR, gxg_GTK_TEXT_CHILD_ANCHOR_w, 1, 0, 0, "(GTK_TEXT_CHILD_ANCHOR obj) casts obj to GTK_TEXT_CHILD_ANCHOR", NULL); Xg_define_procedure(GTK_TEXT_MARK, gxg_GTK_TEXT_MARK_w, 1, 0, 0, "(GTK_TEXT_MARK obj) casts obj to GTK_TEXT_MARK", NULL); Xg_define_procedure(GTK_TEXT_TAG, gxg_GTK_TEXT_TAG_w, 1, 0, 0, "(GTK_TEXT_TAG obj) casts obj to GTK_TEXT_TAG", NULL); Xg_define_procedure(GTK_TEXT_TAG_TABLE, gxg_GTK_TEXT_TAG_TABLE_w, 1, 0, 0, "(GTK_TEXT_TAG_TABLE obj) casts obj to GTK_TEXT_TAG_TABLE", NULL); Xg_define_procedure(GTK_TEXT_VIEW, gxg_GTK_TEXT_VIEW_w, 1, 0, 0, "(GTK_TEXT_VIEW obj) casts obj to GTK_TEXT_VIEW", NULL); Xg_define_procedure(GTK_TOGGLE_BUTTON, gxg_GTK_TOGGLE_BUTTON_w, 1, 0, 0, "(GTK_TOGGLE_BUTTON obj) casts obj to GTK_TOGGLE_BUTTON", NULL); Xg_define_procedure(GTK_TOOLBAR, gxg_GTK_TOOLBAR_w, 1, 0, 0, "(GTK_TOOLBAR obj) casts obj to GTK_TOOLBAR", NULL); Xg_define_procedure(GTK_TREE_DRAG_SOURCE, gxg_GTK_TREE_DRAG_SOURCE_w, 1, 0, 0, "(GTK_TREE_DRAG_SOURCE obj) casts obj to GTK_TREE_DRAG_SOURCE", NULL); Xg_define_procedure(GTK_TREE_DRAG_DEST, gxg_GTK_TREE_DRAG_DEST_w, 1, 0, 0, "(GTK_TREE_DRAG_DEST obj) casts obj to GTK_TREE_DRAG_DEST", NULL); Xg_define_procedure(GTK_TREE_MODEL, gxg_GTK_TREE_MODEL_w, 1, 0, 0, "(GTK_TREE_MODEL obj) casts obj to GTK_TREE_MODEL", NULL); Xg_define_procedure(GTK_TREE_MODEL_SORT, gxg_GTK_TREE_MODEL_SORT_w, 1, 0, 0, "(GTK_TREE_MODEL_SORT obj) casts obj to GTK_TREE_MODEL_SORT", NULL); Xg_define_procedure(GTK_TREE_SELECTION, gxg_GTK_TREE_SELECTION_w, 1, 0, 0, "(GTK_TREE_SELECTION obj) casts obj to GTK_TREE_SELECTION", NULL); Xg_define_procedure(GTK_TREE_SORTABLE, gxg_GTK_TREE_SORTABLE_w, 1, 0, 0, "(GTK_TREE_SORTABLE obj) casts obj to GTK_TREE_SORTABLE", NULL); Xg_define_procedure(GTK_TREE_STORE, gxg_GTK_TREE_STORE_w, 1, 0, 0, "(GTK_TREE_STORE obj) casts obj to GTK_TREE_STORE", NULL); Xg_define_procedure(GTK_TREE_VIEW_COLUMN, gxg_GTK_TREE_VIEW_COLUMN_w, 1, 0, 0, "(GTK_TREE_VIEW_COLUMN obj) casts obj to GTK_TREE_VIEW_COLUMN", NULL); Xg_define_procedure(GTK_TREE_VIEW, gxg_GTK_TREE_VIEW_w, 1, 0, 0, "(GTK_TREE_VIEW obj) casts obj to GTK_TREE_VIEW", NULL); Xg_define_procedure(GTK_VIEWPORT, gxg_GTK_VIEWPORT_w, 1, 0, 0, "(GTK_VIEWPORT obj) casts obj to GTK_VIEWPORT", NULL); Xg_define_procedure(GTK_WIDGET, gxg_GTK_WIDGET_w, 1, 0, 0, "(GTK_WIDGET obj) casts obj to GTK_WIDGET", NULL); Xg_define_procedure(GTK_WINDOW, gxg_GTK_WINDOW_w, 1, 0, 0, "(GTK_WINDOW obj) casts obj to GTK_WINDOW", NULL); Xg_define_procedure(PANGO_CONTEXT, gxg_PANGO_CONTEXT_w, 1, 0, 0, "(PANGO_CONTEXT obj) casts obj to PANGO_CONTEXT", NULL); Xg_define_procedure(PANGO_FONT_FAMILY, gxg_PANGO_FONT_FAMILY_w, 1, 0, 0, "(PANGO_FONT_FAMILY obj) casts obj to PANGO_FONT_FAMILY", NULL); Xg_define_procedure(PANGO_FONT_FACE, gxg_PANGO_FONT_FACE_w, 1, 0, 0, "(PANGO_FONT_FACE obj) casts obj to PANGO_FONT_FACE", NULL); Xg_define_procedure(PANGO_FONT, gxg_PANGO_FONT_w, 1, 0, 0, "(PANGO_FONT obj) casts obj to PANGO_FONT", NULL); Xg_define_procedure(PANGO_FONT_MAP, gxg_PANGO_FONT_MAP_w, 1, 0, 0, "(PANGO_FONT_MAP obj) casts obj to PANGO_FONT_MAP", NULL); Xg_define_procedure(PANGO_LAYOUT, gxg_PANGO_LAYOUT_w, 1, 0, 0, "(PANGO_LAYOUT obj) casts obj to PANGO_LAYOUT", NULL); Xg_define_procedure(G_OBJECT, gxg_G_OBJECT_w, 1, 0, 0, "(G_OBJECT obj) casts obj to G_OBJECT", NULL); Xg_define_procedure(GDK_SCREEN, gxg_GDK_SCREEN_w, 1, 0, 0, "(GDK_SCREEN obj) casts obj to GDK_SCREEN", NULL); Xg_define_procedure(GDK_DISPLAY_OBJECT, gxg_GDK_DISPLAY_OBJECT_w, 1, 0, 0, "(GDK_DISPLAY_OBJECT obj) casts obj to GDK_DISPLAY_OBJECT", NULL); Xg_define_procedure(GDK_EVENT, gxg_GDK_EVENT_w, 1, 0, 0, "(GDK_EVENT obj) casts obj to GDK_EVENT", NULL); Xg_define_procedure(GDK_EVENT_ANY, gxg_GDK_EVENT_ANY_w, 1, 0, 0, "(GDK_EVENT_ANY obj) casts obj to GDK_EVENT_ANY", NULL); Xg_define_procedure(GDK_EVENT_EXPOSE, gxg_GDK_EVENT_EXPOSE_w, 1, 0, 0, "(GDK_EVENT_EXPOSE obj) casts obj to GDK_EVENT_EXPOSE", NULL); Xg_define_procedure(GDK_EVENT_NOEXPOSE, gxg_GDK_EVENT_NOEXPOSE_w, 1, 0, 0, "(GDK_EVENT_NOEXPOSE obj) casts obj to GDK_EVENT_NOEXPOSE", NULL); Xg_define_procedure(GDK_EVENT_VISIBILITY, gxg_GDK_EVENT_VISIBILITY_w, 1, 0, 0, "(GDK_EVENT_VISIBILITY obj) casts obj to GDK_EVENT_VISIBILITY", NULL); Xg_define_procedure(GDK_EVENT_MOTION, gxg_GDK_EVENT_MOTION_w, 1, 0, 0, "(GDK_EVENT_MOTION obj) casts obj to GDK_EVENT_MOTION", NULL); Xg_define_procedure(GDK_EVENT_BUTTON, gxg_GDK_EVENT_BUTTON_w, 1, 0, 0, "(GDK_EVENT_BUTTON obj) casts obj to GDK_EVENT_BUTTON", NULL); Xg_define_procedure(GDK_EVENT_SCROLL, gxg_GDK_EVENT_SCROLL_w, 1, 0, 0, "(GDK_EVENT_SCROLL obj) casts obj to GDK_EVENT_SCROLL", NULL); Xg_define_procedure(GDK_EVENT_KEY, gxg_GDK_EVENT_KEY_w, 1, 0, 0, "(GDK_EVENT_KEY obj) casts obj to GDK_EVENT_KEY", NULL); Xg_define_procedure(GDK_EVENT_CROSSING, gxg_GDK_EVENT_CROSSING_w, 1, 0, 0, "(GDK_EVENT_CROSSING obj) casts obj to GDK_EVENT_CROSSING", NULL); Xg_define_procedure(GDK_EVENT_FOCUS, gxg_GDK_EVENT_FOCUS_w, 1, 0, 0, "(GDK_EVENT_FOCUS obj) casts obj to GDK_EVENT_FOCUS", NULL); Xg_define_procedure(GDK_EVENT_CONFIGURE, gxg_GDK_EVENT_CONFIGURE_w, 1, 0, 0, "(GDK_EVENT_CONFIGURE obj) casts obj to GDK_EVENT_CONFIGURE", NULL); Xg_define_procedure(GDK_EVENT_PROPERTY, gxg_GDK_EVENT_PROPERTY_w, 1, 0, 0, "(GDK_EVENT_PROPERTY obj) casts obj to GDK_EVENT_PROPERTY", NULL); Xg_define_procedure(GDK_EVENT_SELECTION, gxg_GDK_EVENT_SELECTION_w, 1, 0, 0, "(GDK_EVENT_SELECTION obj) casts obj to GDK_EVENT_SELECTION", NULL); Xg_define_procedure(GDK_EVENT_PROXIMITY, gxg_GDK_EVENT_PROXIMITY_w, 1, 0, 0, "(GDK_EVENT_PROXIMITY obj) casts obj to GDK_EVENT_PROXIMITY", NULL); Xg_define_procedure(GDK_EVENT_SETTING, gxg_GDK_EVENT_SETTING_w, 1, 0, 0, "(GDK_EVENT_SETTING obj) casts obj to GDK_EVENT_SETTING", NULL); Xg_define_procedure(GDK_EVENT_WINDOWSTATE, gxg_GDK_EVENT_WINDOWSTATE_w, 1, 0, 0, "(GDK_EVENT_WINDOWSTATE obj) casts obj to GDK_EVENT_WINDOWSTATE", NULL); Xg_define_procedure(GDK_EVENT_DND, gxg_GDK_EVENT_DND_w, 1, 0, 0, "(GDK_EVENT_DND obj) casts obj to GDK_EVENT_DND", NULL); Xg_define_procedure(GTK_FILE_CHOOSER_DIALOG, gxg_GTK_FILE_CHOOSER_DIALOG_w, 1, 0, 0, "(GTK_FILE_CHOOSER_DIALOG obj) casts obj to GTK_FILE_CHOOSER_DIALOG", NULL); Xg_define_procedure(GTK_FILE_CHOOSER_WIDGET, gxg_GTK_FILE_CHOOSER_WIDGET_w, 1, 0, 0, "(GTK_FILE_CHOOSER_WIDGET obj) casts obj to GTK_FILE_CHOOSER_WIDGET", NULL); Xg_define_procedure(GTK_TREE_MODEL_FILTER, gxg_GTK_TREE_MODEL_FILTER_w, 1, 0, 0, "(GTK_TREE_MODEL_FILTER obj) casts obj to GTK_TREE_MODEL_FILTER", NULL); Xg_define_procedure(GTK_COMBO_BOX, gxg_GTK_COMBO_BOX_w, 1, 0, 0, "(GTK_COMBO_BOX obj) casts obj to GTK_COMBO_BOX", NULL); Xg_define_procedure(GTK_EXPANDER, gxg_GTK_EXPANDER_w, 1, 0, 0, "(GTK_EXPANDER obj) casts obj to GTK_EXPANDER", NULL); Xg_define_procedure(GTK_FONT_BUTTON, gxg_GTK_FONT_BUTTON_w, 1, 0, 0, "(GTK_FONT_BUTTON obj) casts obj to GTK_FONT_BUTTON", NULL); Xg_define_procedure(GTK_COLOR_BUTTON, gxg_GTK_COLOR_BUTTON_w, 1, 0, 0, "(GTK_COLOR_BUTTON obj) casts obj to GTK_COLOR_BUTTON", NULL); Xg_define_procedure(GTK_ENTRY_COMPLETION, gxg_GTK_ENTRY_COMPLETION_w, 1, 0, 0, "(GTK_ENTRY_COMPLETION obj) casts obj to GTK_ENTRY_COMPLETION", NULL); Xg_define_procedure(GTK_RADIO_TOOL_BUTTON, gxg_GTK_RADIO_TOOL_BUTTON_w, 1, 0, 0, "(GTK_RADIO_TOOL_BUTTON obj) casts obj to GTK_RADIO_TOOL_BUTTON", NULL); Xg_define_procedure(GTK_SEPARATOR_TOOL_ITEM, gxg_GTK_SEPARATOR_TOOL_ITEM_w, 1, 0, 0, "(GTK_SEPARATOR_TOOL_ITEM obj) casts obj to GTK_SEPARATOR_TOOL_ITEM", NULL); Xg_define_procedure(GTK_TOGGLE_TOOL_BUTTON, gxg_GTK_TOGGLE_TOOL_BUTTON_w, 1, 0, 0, "(GTK_TOGGLE_TOOL_BUTTON obj) casts obj to GTK_TOGGLE_TOOL_BUTTON", NULL); Xg_define_procedure(GTK_FILE_FILTER, gxg_GTK_FILE_FILTER_w, 1, 0, 0, "(GTK_FILE_FILTER obj) casts obj to GTK_FILE_FILTER", NULL); Xg_define_procedure(GTK_CELL_LAYOUT, gxg_GTK_CELL_LAYOUT_w, 1, 0, 0, "(GTK_CELL_LAYOUT obj) casts obj to GTK_CELL_LAYOUT", NULL); Xg_define_procedure(GTK_CLIPBOARD, gxg_GTK_CLIPBOARD_w, 1, 0, 0, "(GTK_CLIPBOARD obj) casts obj to GTK_CLIPBOARD", NULL); Xg_define_procedure(GTK_FILE_CHOOSER, gxg_GTK_FILE_CHOOSER_w, 1, 0, 0, "(GTK_FILE_CHOOSER obj) casts obj to GTK_FILE_CHOOSER", NULL); Xg_define_procedure(GTK_ICON_THEME, gxg_GTK_ICON_THEME_w, 1, 0, 0, "(GTK_ICON_THEME obj) casts obj to GTK_ICON_THEME", NULL); Xg_define_procedure(GTK_TOOL_BUTTON, gxg_GTK_TOOL_BUTTON_w, 1, 0, 0, "(GTK_TOOL_BUTTON obj) casts obj to GTK_TOOL_BUTTON", NULL); Xg_define_procedure(GTK_TOOL_ITEM, gxg_GTK_TOOL_ITEM_w, 1, 0, 0, "(GTK_TOOL_ITEM obj) casts obj to GTK_TOOL_ITEM", NULL); Xg_define_procedure(GTK_ACCEL_MAP, gxg_GTK_ACCEL_MAP_w, 1, 0, 0, "(GTK_ACCEL_MAP obj) casts obj to GTK_ACCEL_MAP", NULL); Xg_define_procedure(GTK_CELL_VIEW, gxg_GTK_CELL_VIEW_w, 1, 0, 0, "(GTK_CELL_VIEW obj) casts obj to GTK_CELL_VIEW", NULL); Xg_define_procedure(GTK_ABOUT_DIALOG, gxg_GTK_ABOUT_DIALOG_w, 1, 0, 0, "(GTK_ABOUT_DIALOG obj) casts obj to GTK_ABOUT_DIALOG", NULL); Xg_define_procedure(GTK_CELL_RENDERER_COMBO, gxg_GTK_CELL_RENDERER_COMBO_w, 1, 0, 0, "(GTK_CELL_RENDERER_COMBO obj) casts obj to GTK_CELL_RENDERER_COMBO", NULL); Xg_define_procedure(GTK_CELL_RENDERER_PROGRESS, gxg_GTK_CELL_RENDERER_PROGRESS_w, 1, 0, 0, "(GTK_CELL_RENDERER_PROGRESS obj) casts obj to GTK_CELL_RENDERER_PROGRESS", NULL); Xg_define_procedure(GTK_ICON_VIEW, gxg_GTK_ICON_VIEW_w, 1, 0, 0, "(GTK_ICON_VIEW obj) casts obj to GTK_ICON_VIEW", NULL); Xg_define_procedure(GTK_FILE_CHOOSER_BUTTON, gxg_GTK_FILE_CHOOSER_BUTTON_w, 1, 0, 0, "(GTK_FILE_CHOOSER_BUTTON obj) casts obj to GTK_FILE_CHOOSER_BUTTON", NULL); Xg_define_procedure(GTK_MENU_TOOL_BUTTON, gxg_GTK_MENU_TOOL_BUTTON_w, 1, 0, 0, "(GTK_MENU_TOOL_BUTTON obj) casts obj to GTK_MENU_TOOL_BUTTON", NULL); Xg_define_procedure(GTK_ASSISTANT, gxg_GTK_ASSISTANT_w, 1, 0, 0, "(GTK_ASSISTANT obj) casts obj to GTK_ASSISTANT", NULL); Xg_define_procedure(GTK_CELL_RENDERER_ACCEL, gxg_GTK_CELL_RENDERER_ACCEL_w, 1, 0, 0, "(GTK_CELL_RENDERER_ACCEL obj) casts obj to GTK_CELL_RENDERER_ACCEL", NULL); Xg_define_procedure(GTK_CELL_RENDERER_SPIN, gxg_GTK_CELL_RENDERER_SPIN_w, 1, 0, 0, "(GTK_CELL_RENDERER_SPIN obj) casts obj to GTK_CELL_RENDERER_SPIN", NULL); Xg_define_procedure(GTK_LINK_BUTTON, gxg_GTK_LINK_BUTTON_w, 1, 0, 0, "(GTK_LINK_BUTTON obj) casts obj to GTK_LINK_BUTTON", NULL); Xg_define_procedure(GTK_RECENT_CHOOSER_DIALOG, gxg_GTK_RECENT_CHOOSER_DIALOG_w, 1, 0, 0, "(GTK_RECENT_CHOOSER_DIALOG obj) casts obj to GTK_RECENT_CHOOSER_DIALOG", NULL); Xg_define_procedure(GTK_RECENT_CHOOSER, gxg_GTK_RECENT_CHOOSER_w, 1, 0, 0, "(GTK_RECENT_CHOOSER obj) casts obj to GTK_RECENT_CHOOSER", NULL); Xg_define_procedure(GTK_RECENT_CHOOSER_MENU, gxg_GTK_RECENT_CHOOSER_MENU_w, 1, 0, 0, "(GTK_RECENT_CHOOSER_MENU obj) casts obj to GTK_RECENT_CHOOSER_MENU", NULL); Xg_define_procedure(GTK_RECENT_CHOOSER_WIDGET, gxg_GTK_RECENT_CHOOSER_WIDGET_w, 1, 0, 0, "(GTK_RECENT_CHOOSER_WIDGET obj) casts obj to GTK_RECENT_CHOOSER_WIDGET", NULL); Xg_define_procedure(GTK_RECENT_FILTER, gxg_GTK_RECENT_FILTER_w, 1, 0, 0, "(GTK_RECENT_FILTER obj) casts obj to GTK_RECENT_FILTER", NULL); Xg_define_procedure(GTK_RECENT_MANAGER, gxg_GTK_RECENT_MANAGER_w, 1, 0, 0, "(GTK_RECENT_MANAGER obj) casts obj to GTK_RECENT_MANAGER", NULL); Xg_define_procedure(GTK_PRINT_CONTEXT, gxg_GTK_PRINT_CONTEXT_w, 1, 0, 0, "(GTK_PRINT_CONTEXT obj) casts obj to GTK_PRINT_CONTEXT", NULL); Xg_define_procedure(GTK_PRINT_OPERATION, gxg_GTK_PRINT_OPERATION_w, 1, 0, 0, "(GTK_PRINT_OPERATION obj) casts obj to GTK_PRINT_OPERATION", NULL); Xg_define_procedure(GTK_PRINT_OPERATION_PREVIEW, gxg_GTK_PRINT_OPERATION_PREVIEW_w, 1, 0, 0, "(GTK_PRINT_OPERATION_PREVIEW obj) casts obj to GTK_PRINT_OPERATION_PREVIEW", NULL); Xg_define_procedure(GTK_PRINT_SETTINGS, gxg_GTK_PRINT_SETTINGS_w, 1, 0, 0, "(GTK_PRINT_SETTINGS obj) casts obj to GTK_PRINT_SETTINGS", NULL); Xg_define_procedure(GTK_TOOLTIP, gxg_GTK_TOOLTIP_w, 1, 0, 0, "(GTK_TOOLTIP obj) casts obj to GTK_TOOLTIP", NULL); #if GTK_CHECK_VERSION(2, 18, 0) Xg_define_procedure(GTK_INFO_BAR, gxg_GTK_INFO_BAR_w, 1, 0, 0, "(GTK_INFO_BAR obj) casts obj to GTK_INFO_BAR", NULL); Xg_define_procedure(GTK_ENTRY_BUFFER, gxg_GTK_ENTRY_BUFFER_w, 1, 0, 0, "(GTK_ENTRY_BUFFER obj) casts obj to GTK_ENTRY_BUFFER", NULL); #endif #if GTK_CHECK_VERSION(2, 20, 0) Xg_define_procedure(GTK_SPINNER, gxg_GTK_SPINNER_w, 1, 0, 0, "(GTK_SPINNER obj) casts obj to GTK_SPINNER", NULL); Xg_define_procedure(GTK_CELL_RENDERER_SPINNER, gxg_GTK_CELL_RENDERER_SPINNER_w, 1, 0, 0, "(GTK_CELL_RENDERER_SPINNER obj) casts obj to GTK_CELL_RENDERER_SPINNER", NULL); Xg_define_procedure(GTK_TOOL_PALETTE, gxg_GTK_TOOL_PALETTE_w, 1, 0, 0, "(GTK_TOOL_PALETTE obj) casts obj to GTK_TOOL_PALETTE", NULL); Xg_define_procedure(GTK_TOOL_ITEM_GROUP, gxg_GTK_TOOL_ITEM_GROUP_w, 1, 0, 0, "(GTK_TOOL_ITEM_GROUP obj) casts obj to GTK_TOOL_ITEM_GROUP", NULL); #endif #if GTK_CHECK_VERSION(3, 0, 0) Xg_define_procedure(GTK_COMBO_BOX_TEXT, gxg_GTK_COMBO_BOX_TEXT_w, 1, 0, 0, "(GTK_COMBO_BOX_TEXT obj) casts obj to GTK_COMBO_BOX_TEXT", NULL); Xg_define_procedure(GTK_GRID, gxg_GTK_GRID_w, 1, 0, 0, "(GTK_GRID obj) casts obj to GTK_GRID", NULL); Xg_define_procedure(GTK_SCROLLABLE, gxg_GTK_SCROLLABLE_w, 1, 0, 0, "(GTK_SCROLLABLE obj) casts obj to GTK_SCROLLABLE", NULL); Xg_define_procedure(GDK_RGBA, gxg_GDK_RGBA_w, 1, 0, 0, "(GDK_RGBA obj) casts obj to GDK_RGBA", NULL); Xg_define_procedure(GTK_SWITCH, gxg_GTK_SWITCH_w, 1, 0, 0, "(GTK_SWITCH obj) casts obj to GTK_SWITCH", NULL); Xg_define_procedure(GTK_ORIENTABLE, gxg_GTK_ORIENTABLE_w, 1, 0, 0, "(GTK_ORIENTABLE obj) casts obj to GTK_ORIENTABLE", NULL); Xg_define_procedure(GTK_WINDOW_GROUP, gxg_GTK_WINDOW_GROUP_w, 1, 0, 0, "(GTK_WINDOW_GROUP obj) casts obj to GTK_WINDOW_GROUP", NULL); Xg_define_procedure(GTK_TOOL_SHELL, gxg_GTK_TOOL_SHELL_w, 1, 0, 0, "(GTK_TOOL_SHELL obj) casts obj to GTK_TOOL_SHELL", NULL); #endif #if GTK_CHECK_VERSION(3, 2, 0) Xg_define_procedure(GTK_OVERLAY, gxg_GTK_OVERLAY_w, 1, 0, 0, "(GTK_OVERLAY obj) casts obj to GTK_OVERLAY", NULL); Xg_define_procedure(GTK_FONT_CHOOSER, gxg_GTK_FONT_CHOOSER_w, 1, 0, 0, "(GTK_FONT_CHOOSER obj) casts obj to GTK_FONT_CHOOSER", NULL); Xg_define_procedure(GTK_FONT_CHOOSER_DIALOG, gxg_GTK_FONT_CHOOSER_DIALOG_w, 1, 0, 0, "(GTK_FONT_CHOOSER_DIALOG obj) casts obj to GTK_FONT_CHOOSER_DIALOG", NULL); Xg_define_procedure(GTK_FONT_CHOOSER_WIDGET, gxg_GTK_FONT_CHOOSER_WIDGET_w, 1, 0, 0, "(GTK_FONT_CHOOSER_WIDGET obj) casts obj to GTK_FONT_CHOOSER_WIDGET", NULL); #endif #if GTK_CHECK_VERSION(3, 4, 0) Xg_define_procedure(GTK_APPLICATION_WINDOW, gxg_GTK_APPLICATION_WINDOW_w, 1, 0, 0, "(GTK_APPLICATION_WINDOW obj) casts obj to GTK_APPLICATION_WINDOW", NULL); Xg_define_procedure(GTK_COLOR_CHOOSER_DIALOG, gxg_GTK_COLOR_CHOOSER_DIALOG_w, 1, 0, 0, "(GTK_COLOR_CHOOSER_DIALOG obj) casts obj to GTK_COLOR_CHOOSER_DIALOG", NULL); Xg_define_procedure(GTK_COLOR_CHOOSER_WIDGET, gxg_GTK_COLOR_CHOOSER_WIDGET_w, 1, 0, 0, "(GTK_COLOR_CHOOSER_WIDGET obj) casts obj to GTK_COLOR_CHOOSER_WIDGET", NULL); #endif #if GTK_CHECK_VERSION(3, 6, 0) Xg_define_procedure(GTK_MENU_BUTTON, gxg_GTK_MENU_BUTTON_w, 1, 0, 0, "(GTK_MENU_BUTTON obj) casts obj to GTK_MENU_BUTTON", NULL); Xg_define_procedure(GTK_SEARCH_ENTRY, gxg_GTK_SEARCH_ENTRY_w, 1, 0, 0, "(GTK_SEARCH_ENTRY obj) casts obj to GTK_SEARCH_ENTRY", NULL); Xg_define_procedure(GTK_LEVEL_BAR, gxg_GTK_LEVEL_BAR_w, 1, 0, 0, "(GTK_LEVEL_BAR obj) casts obj to GTK_LEVEL_BAR", NULL); #endif #if GTK_CHECK_VERSION(3, 10, 0) Xg_define_procedure(GTK_PLACES_SIDEBAR, gxg_GTK_PLACES_SIDEBAR_w, 1, 0, 0, "(GTK_PLACES_SIDEBAR obj) casts obj to GTK_PLACES_SIDEBAR", NULL); Xg_define_procedure(GTK_STACK_SWITCHER, gxg_GTK_STACK_SWITCHER_w, 1, 0, 0, "(GTK_STACK_SWITCHER obj) casts obj to GTK_STACK_SWITCHER", NULL); Xg_define_procedure(GTK_STACK, gxg_GTK_STACK_w, 1, 0, 0, "(GTK_STACK obj) casts obj to GTK_STACK", NULL); Xg_define_procedure(GTK_REVEALER, gxg_GTK_REVEALER_w, 1, 0, 0, "(GTK_REVEALER obj) casts obj to GTK_REVEALER", NULL); Xg_define_procedure(GTK_HEADER_BAR, gxg_GTK_HEADER_BAR_w, 1, 0, 0, "(GTK_HEADER_BAR obj) casts obj to GTK_HEADER_BAR", NULL); Xg_define_procedure(GTK_LIST_BOX, gxg_GTK_LIST_BOX_w, 1, 0, 0, "(GTK_LIST_BOX obj) casts obj to GTK_LIST_BOX", NULL); Xg_define_procedure(GTK_LIST_BOX_ROW, gxg_GTK_LIST_BOX_ROW_w, 1, 0, 0, "(GTK_LIST_BOX_ROW obj) casts obj to GTK_LIST_BOX_ROW", NULL); Xg_define_procedure(GTK_SEARCH_BAR, gxg_GTK_SEARCH_BAR_w, 1, 0, 0, "(GTK_SEARCH_BAR obj) casts obj to GTK_SEARCH_BAR", NULL); #endif #if GTK_CHECK_VERSION(3, 12, 0) Xg_define_procedure(GTK_FLOW_BOX, gxg_GTK_FLOW_BOX_w, 1, 0, 0, "(GTK_FLOW_BOX obj) casts obj to GTK_FLOW_BOX", NULL); Xg_define_procedure(GTK_FLOW_BOX_CHILD, gxg_GTK_FLOW_BOX_CHILD_w, 1, 0, 0, "(GTK_FLOW_BOX_CHILD obj) casts obj to GTK_FLOW_BOX_CHILD", NULL); Xg_define_procedure(GTK_ACTION_BAR, gxg_GTK_ACTION_BAR_w, 1, 0, 0, "(GTK_ACTION_BAR obj) casts obj to GTK_ACTION_BAR", NULL); Xg_define_procedure(GTK_POPOVER, gxg_GTK_POPOVER_w, 1, 0, 0, "(GTK_POPOVER obj) casts obj to GTK_POPOVER", NULL); #endif #if GTK_CHECK_VERSION(3, 14, 0) Xg_define_procedure(GTK_GESTURE, gxg_GTK_GESTURE_w, 1, 0, 0, "(GTK_GESTURE obj) casts obj to GTK_GESTURE", NULL); Xg_define_procedure(GTK_GESTURE_DRAG, gxg_GTK_GESTURE_DRAG_w, 1, 0, 0, "(GTK_GESTURE_DRAG obj) casts obj to GTK_GESTURE_DRAG", NULL); Xg_define_procedure(GTK_GESTURE_LONG_PRESS, gxg_GTK_GESTURE_LONG_PRESS_w, 1, 0, 0, "(GTK_GESTURE_LONG_PRESS obj) casts obj to GTK_GESTURE_LONG_PRESS", NULL); Xg_define_procedure(GTK_GESTURE_ZOOM, gxg_GTK_GESTURE_ZOOM_w, 1, 0, 0, "(GTK_GESTURE_ZOOM obj) casts obj to GTK_GESTURE_ZOOM", NULL); Xg_define_procedure(GTK_GESTURE_SWIPE, gxg_GTK_GESTURE_SWIPE_w, 1, 0, 0, "(GTK_GESTURE_SWIPE obj) casts obj to GTK_GESTURE_SWIPE", NULL); Xg_define_procedure(GTK_GESTURE_SINGLE, gxg_GTK_GESTURE_SINGLE_w, 1, 0, 0, "(GTK_GESTURE_SINGLE obj) casts obj to GTK_GESTURE_SINGLE", NULL); Xg_define_procedure(GTK_GESTURE_PAN, gxg_GTK_GESTURE_PAN_w, 1, 0, 0, "(GTK_GESTURE_PAN obj) casts obj to GTK_GESTURE_PAN", NULL); Xg_define_procedure(GTK_GESTURE_MULTI_PRESS, gxg_GTK_GESTURE_MULTI_PRESS_w, 1, 0, 0, "(GTK_GESTURE_MULTI_PRESS obj) casts obj to GTK_GESTURE_MULTI_PRESS", NULL); Xg_define_procedure(GTK_GESTURE_ROTATE, gxg_GTK_GESTURE_ROTATE_w, 1, 0, 0, "(GTK_GESTURE_ROTATE obj) casts obj to GTK_GESTURE_ROTATE", NULL); Xg_define_procedure(GTK_EVENT_CONTROLLER, gxg_GTK_EVENT_CONTROLLER_w, 1, 0, 0, "(GTK_EVENT_CONTROLLER obj) casts obj to GTK_EVENT_CONTROLLER", NULL); #endif #if GTK_CHECK_VERSION(3, 16, 0) Xg_define_procedure(GTK_GL_AREA, gxg_GTK_GL_AREA_w, 1, 0, 0, "(GTK_GL_AREA obj) casts obj to GTK_GL_AREA", NULL); Xg_define_procedure(GDK_GL_CONTEXT, gxg_GDK_GL_CONTEXT_w, 1, 0, 0, "(GDK_GL_CONTEXT obj) casts obj to GDK_GL_CONTEXT", NULL); Xg_define_procedure(GTK_POPOVER_MENU, gxg_GTK_POPOVER_MENU_w, 1, 0, 0, "(GTK_POPOVER_MENU obj) casts obj to GTK_POPOVER_MENU", NULL); Xg_define_procedure(GTK_STACK_SIDEBAR, gxg_GTK_STACK_SIDEBAR_w, 1, 0, 0, "(GTK_STACK_SIDEBAR obj) casts obj to GTK_STACK_SIDEBAR", NULL); #endif Xg_define_procedure(c-array->list, c_array_to_xen_list_w, 2, 0, 0, NULL, NULL); Xg_define_procedure(list->c-array, xen_list_to_c_array_w, 2, 0, 0, NULL, NULL); Xg_define_procedure(make-target-entry, gxg_make_target_entry_w, 1, 0, 0, H_make_target_entry, NULL); Xg_define_procedure(g_object_get, xg_object_get_w, 3, 0, 0, NULL, NULL); Xg_define_procedure(g_object_set, xg_object_set_w, 3, 0, 0, NULL, NULL); Xg_define_procedure(gtk_event_keyval, xg_gtk_event_keyval_w, 1, 0, 0, NULL, NULL); Xg_define_procedure(gtk_init, gxg_gtk_init_w, 0, 2, 0, H_gtk_init, NULL); Xg_define_procedure(gtk_init_check, gxg_gtk_init_check_w, 0, 2, 0, H_gtk_init_check, NULL); Xg_define_procedure(GDK_IS_DRAG_CONTEXT, gxg_GDK_IS_DRAG_CONTEXT_w, 1, 0, 0, "(GDK_IS_DRAG_CONTEXT obj): " PROC_TRUE " if obj is a GDK_IS_DRAG_CONTEXT", NULL); Xg_define_procedure(GDK_IS_DEVICE, gxg_GDK_IS_DEVICE_w, 1, 0, 0, "(GDK_IS_DEVICE obj): " PROC_TRUE " if obj is a GDK_IS_DEVICE", NULL); Xg_define_procedure(GDK_IS_KEYMAP, gxg_GDK_IS_KEYMAP_w, 1, 0, 0, "(GDK_IS_KEYMAP obj): " PROC_TRUE " if obj is a GDK_IS_KEYMAP", NULL); Xg_define_procedure(GDK_IS_VISUAL, gxg_GDK_IS_VISUAL_w, 1, 0, 0, "(GDK_IS_VISUAL obj): " PROC_TRUE " if obj is a GDK_IS_VISUAL", NULL); Xg_define_procedure(GDK_IS_WINDOW, gxg_GDK_IS_WINDOW_w, 1, 0, 0, "(GDK_IS_WINDOW obj): " PROC_TRUE " if obj is a GDK_IS_WINDOW", NULL); Xg_define_procedure(GDK_IS_PIXBUF, gxg_GDK_IS_PIXBUF_w, 1, 0, 0, "(GDK_IS_PIXBUF obj): " PROC_TRUE " if obj is a GDK_IS_PIXBUF", NULL); Xg_define_procedure(GDK_IS_PIXBUF_ANIMATION, gxg_GDK_IS_PIXBUF_ANIMATION_w, 1, 0, 0, "(GDK_IS_PIXBUF_ANIMATION obj): " PROC_TRUE " if obj is a GDK_IS_PIXBUF_ANIMATION", NULL); Xg_define_procedure(GDK_IS_PIXBUF_ANIMATION_ITER, gxg_GDK_IS_PIXBUF_ANIMATION_ITER_w, 1, 0, 0, "(GDK_IS_PIXBUF_ANIMATION_ITER obj): " PROC_TRUE " if obj is a GDK_IS_PIXBUF_ANIMATION_ITER", NULL); Xg_define_procedure(GTK_IS_ACCEL_GROUP, gxg_GTK_IS_ACCEL_GROUP_w, 1, 0, 0, "(GTK_IS_ACCEL_GROUP obj): " PROC_TRUE " if obj is a GTK_IS_ACCEL_GROUP", NULL); Xg_define_procedure(GTK_IS_ACCEL_LABEL, gxg_GTK_IS_ACCEL_LABEL_w, 1, 0, 0, "(GTK_IS_ACCEL_LABEL obj): " PROC_TRUE " if obj is a GTK_IS_ACCEL_LABEL", NULL); Xg_define_procedure(GTK_IS_ACCESSIBLE, gxg_GTK_IS_ACCESSIBLE_w, 1, 0, 0, "(GTK_IS_ACCESSIBLE obj): " PROC_TRUE " if obj is a GTK_IS_ACCESSIBLE", NULL); Xg_define_procedure(GTK_IS_ADJUSTMENT, gxg_GTK_IS_ADJUSTMENT_w, 1, 0, 0, "(GTK_IS_ADJUSTMENT obj): " PROC_TRUE " if obj is a GTK_IS_ADJUSTMENT", NULL); Xg_define_procedure(GTK_IS_ASPECT_FRAME, gxg_GTK_IS_ASPECT_FRAME_w, 1, 0, 0, "(GTK_IS_ASPECT_FRAME obj): " PROC_TRUE " if obj is a GTK_IS_ASPECT_FRAME", NULL); Xg_define_procedure(GTK_IS_BUTTON_BOX, gxg_GTK_IS_BUTTON_BOX_w, 1, 0, 0, "(GTK_IS_BUTTON_BOX obj): " PROC_TRUE " if obj is a GTK_IS_BUTTON_BOX", NULL); Xg_define_procedure(GTK_IS_BIN, gxg_GTK_IS_BIN_w, 1, 0, 0, "(GTK_IS_BIN obj): " PROC_TRUE " if obj is a GTK_IS_BIN", NULL); Xg_define_procedure(GTK_IS_BOX, gxg_GTK_IS_BOX_w, 1, 0, 0, "(GTK_IS_BOX obj): " PROC_TRUE " if obj is a GTK_IS_BOX", NULL); Xg_define_procedure(GTK_IS_BUTTON, gxg_GTK_IS_BUTTON_w, 1, 0, 0, "(GTK_IS_BUTTON obj): " PROC_TRUE " if obj is a GTK_IS_BUTTON", NULL); Xg_define_procedure(GTK_IS_CALENDAR, gxg_GTK_IS_CALENDAR_w, 1, 0, 0, "(GTK_IS_CALENDAR obj): " PROC_TRUE " if obj is a GTK_IS_CALENDAR", NULL); Xg_define_procedure(GTK_IS_CELL_EDITABLE, gxg_GTK_IS_CELL_EDITABLE_w, 1, 0, 0, "(GTK_IS_CELL_EDITABLE obj): " PROC_TRUE " if obj is a GTK_IS_CELL_EDITABLE", NULL); Xg_define_procedure(GTK_IS_CELL_RENDERER, gxg_GTK_IS_CELL_RENDERER_w, 1, 0, 0, "(GTK_IS_CELL_RENDERER obj): " PROC_TRUE " if obj is a GTK_IS_CELL_RENDERER", NULL); Xg_define_procedure(GTK_IS_CELL_RENDERER_PIXBUF, gxg_GTK_IS_CELL_RENDERER_PIXBUF_w, 1, 0, 0, "(GTK_IS_CELL_RENDERER_PIXBUF obj): " PROC_TRUE " if obj is a GTK_IS_CELL_RENDERER_PIXBUF", NULL); Xg_define_procedure(GTK_IS_CELL_RENDERER_TEXT, gxg_GTK_IS_CELL_RENDERER_TEXT_w, 1, 0, 0, "(GTK_IS_CELL_RENDERER_TEXT obj): " PROC_TRUE " if obj is a GTK_IS_CELL_RENDERER_TEXT", NULL); Xg_define_procedure(GTK_IS_CELL_RENDERER_TOGGLE, gxg_GTK_IS_CELL_RENDERER_TOGGLE_w, 1, 0, 0, "(GTK_IS_CELL_RENDERER_TOGGLE obj): " PROC_TRUE " if obj is a GTK_IS_CELL_RENDERER_TOGGLE", NULL); Xg_define_procedure(GTK_IS_CHECK_BUTTON, gxg_GTK_IS_CHECK_BUTTON_w, 1, 0, 0, "(GTK_IS_CHECK_BUTTON obj): " PROC_TRUE " if obj is a GTK_IS_CHECK_BUTTON", NULL); Xg_define_procedure(GTK_IS_CHECK_MENU_ITEM, gxg_GTK_IS_CHECK_MENU_ITEM_w, 1, 0, 0, "(GTK_IS_CHECK_MENU_ITEM obj): " PROC_TRUE " if obj is a GTK_IS_CHECK_MENU_ITEM", NULL); Xg_define_procedure(GTK_IS_CONTAINER, gxg_GTK_IS_CONTAINER_w, 1, 0, 0, "(GTK_IS_CONTAINER obj): " PROC_TRUE " if obj is a GTK_IS_CONTAINER", NULL); Xg_define_procedure(GTK_IS_DIALOG, gxg_GTK_IS_DIALOG_w, 1, 0, 0, "(GTK_IS_DIALOG obj): " PROC_TRUE " if obj is a GTK_IS_DIALOG", NULL); Xg_define_procedure(GTK_IS_DRAWING_AREA, gxg_GTK_IS_DRAWING_AREA_w, 1, 0, 0, "(GTK_IS_DRAWING_AREA obj): " PROC_TRUE " if obj is a GTK_IS_DRAWING_AREA", NULL); Xg_define_procedure(GTK_IS_EDITABLE, gxg_GTK_IS_EDITABLE_w, 1, 0, 0, "(GTK_IS_EDITABLE obj): " PROC_TRUE " if obj is a GTK_IS_EDITABLE", NULL); Xg_define_procedure(GTK_IS_ENTRY, gxg_GTK_IS_ENTRY_w, 1, 0, 0, "(GTK_IS_ENTRY obj): " PROC_TRUE " if obj is a GTK_IS_ENTRY", NULL); Xg_define_procedure(GTK_IS_EVENT_BOX, gxg_GTK_IS_EVENT_BOX_w, 1, 0, 0, "(GTK_IS_EVENT_BOX obj): " PROC_TRUE " if obj is a GTK_IS_EVENT_BOX", NULL); Xg_define_procedure(GTK_IS_FIXED, gxg_GTK_IS_FIXED_w, 1, 0, 0, "(GTK_IS_FIXED obj): " PROC_TRUE " if obj is a GTK_IS_FIXED", NULL); Xg_define_procedure(GTK_IS_FRAME, gxg_GTK_IS_FRAME_w, 1, 0, 0, "(GTK_IS_FRAME obj): " PROC_TRUE " if obj is a GTK_IS_FRAME", NULL); Xg_define_procedure(GTK_IS_IMAGE, gxg_GTK_IS_IMAGE_w, 1, 0, 0, "(GTK_IS_IMAGE obj): " PROC_TRUE " if obj is a GTK_IS_IMAGE", NULL); Xg_define_procedure(GTK_IS_IM_CONTEXT, gxg_GTK_IS_IM_CONTEXT_w, 1, 0, 0, "(GTK_IS_IM_CONTEXT obj): " PROC_TRUE " if obj is a GTK_IS_IM_CONTEXT", NULL); Xg_define_procedure(GTK_IS_IM_CONTEXT_SIMPLE, gxg_GTK_IS_IM_CONTEXT_SIMPLE_w, 1, 0, 0, "(GTK_IS_IM_CONTEXT_SIMPLE obj): " PROC_TRUE " if obj is a GTK_IS_IM_CONTEXT_SIMPLE", NULL); Xg_define_procedure(GTK_IS_INVISIBLE, gxg_GTK_IS_INVISIBLE_w, 1, 0, 0, "(GTK_IS_INVISIBLE obj): " PROC_TRUE " if obj is a GTK_IS_INVISIBLE", NULL); Xg_define_procedure(GTK_IS_LABEL, gxg_GTK_IS_LABEL_w, 1, 0, 0, "(GTK_IS_LABEL obj): " PROC_TRUE " if obj is a GTK_IS_LABEL", NULL); Xg_define_procedure(GTK_IS_LAYOUT, gxg_GTK_IS_LAYOUT_w, 1, 0, 0, "(GTK_IS_LAYOUT obj): " PROC_TRUE " if obj is a GTK_IS_LAYOUT", NULL); Xg_define_procedure(GTK_IS_LIST_STORE, gxg_GTK_IS_LIST_STORE_w, 1, 0, 0, "(GTK_IS_LIST_STORE obj): " PROC_TRUE " if obj is a GTK_IS_LIST_STORE", NULL); Xg_define_procedure(GTK_IS_MENU_BAR, gxg_GTK_IS_MENU_BAR_w, 1, 0, 0, "(GTK_IS_MENU_BAR obj): " PROC_TRUE " if obj is a GTK_IS_MENU_BAR", NULL); Xg_define_procedure(GTK_IS_MENU, gxg_GTK_IS_MENU_w, 1, 0, 0, "(GTK_IS_MENU obj): " PROC_TRUE " if obj is a GTK_IS_MENU", NULL); Xg_define_procedure(GTK_IS_MENU_ITEM, gxg_GTK_IS_MENU_ITEM_w, 1, 0, 0, "(GTK_IS_MENU_ITEM obj): " PROC_TRUE " if obj is a GTK_IS_MENU_ITEM", NULL); Xg_define_procedure(GTK_IS_MENU_SHELL, gxg_GTK_IS_MENU_SHELL_w, 1, 0, 0, "(GTK_IS_MENU_SHELL obj): " PROC_TRUE " if obj is a GTK_IS_MENU_SHELL", NULL); Xg_define_procedure(GTK_IS_NOTEBOOK, gxg_GTK_IS_NOTEBOOK_w, 1, 0, 0, "(GTK_IS_NOTEBOOK obj): " PROC_TRUE " if obj is a GTK_IS_NOTEBOOK", NULL); Xg_define_procedure(GTK_IS_PANED, gxg_GTK_IS_PANED_w, 1, 0, 0, "(GTK_IS_PANED obj): " PROC_TRUE " if obj is a GTK_IS_PANED", NULL); Xg_define_procedure(GTK_IS_PROGRESS_BAR, gxg_GTK_IS_PROGRESS_BAR_w, 1, 0, 0, "(GTK_IS_PROGRESS_BAR obj): " PROC_TRUE " if obj is a GTK_IS_PROGRESS_BAR", NULL); Xg_define_procedure(GTK_IS_RADIO_BUTTON, gxg_GTK_IS_RADIO_BUTTON_w, 1, 0, 0, "(GTK_IS_RADIO_BUTTON obj): " PROC_TRUE " if obj is a GTK_IS_RADIO_BUTTON", NULL); Xg_define_procedure(GTK_IS_RADIO_MENU_ITEM, gxg_GTK_IS_RADIO_MENU_ITEM_w, 1, 0, 0, "(GTK_IS_RADIO_MENU_ITEM obj): " PROC_TRUE " if obj is a GTK_IS_RADIO_MENU_ITEM", NULL); Xg_define_procedure(GTK_IS_RANGE, gxg_GTK_IS_RANGE_w, 1, 0, 0, "(GTK_IS_RANGE obj): " PROC_TRUE " if obj is a GTK_IS_RANGE", NULL); Xg_define_procedure(GTK_IS_SCALE, gxg_GTK_IS_SCALE_w, 1, 0, 0, "(GTK_IS_SCALE obj): " PROC_TRUE " if obj is a GTK_IS_SCALE", NULL); Xg_define_procedure(GTK_IS_SCROLLBAR, gxg_GTK_IS_SCROLLBAR_w, 1, 0, 0, "(GTK_IS_SCROLLBAR obj): " PROC_TRUE " if obj is a GTK_IS_SCROLLBAR", NULL); Xg_define_procedure(GTK_IS_SCROLLED_WINDOW, gxg_GTK_IS_SCROLLED_WINDOW_w, 1, 0, 0, "(GTK_IS_SCROLLED_WINDOW obj): " PROC_TRUE " if obj is a GTK_IS_SCROLLED_WINDOW", NULL); Xg_define_procedure(GTK_IS_SEPARATOR, gxg_GTK_IS_SEPARATOR_w, 1, 0, 0, "(GTK_IS_SEPARATOR obj): " PROC_TRUE " if obj is a GTK_IS_SEPARATOR", NULL); Xg_define_procedure(GTK_IS_SEPARATOR_MENU_ITEM, gxg_GTK_IS_SEPARATOR_MENU_ITEM_w, 1, 0, 0, "(GTK_IS_SEPARATOR_MENU_ITEM obj): " PROC_TRUE " if obj is a GTK_IS_SEPARATOR_MENU_ITEM", NULL); Xg_define_procedure(GTK_IS_SETTINGS, gxg_GTK_IS_SETTINGS_w, 1, 0, 0, "(GTK_IS_SETTINGS obj): " PROC_TRUE " if obj is a GTK_IS_SETTINGS", NULL); Xg_define_procedure(GTK_IS_SIZE_GROUP, gxg_GTK_IS_SIZE_GROUP_w, 1, 0, 0, "(GTK_IS_SIZE_GROUP obj): " PROC_TRUE " if obj is a GTK_IS_SIZE_GROUP", NULL); Xg_define_procedure(GTK_IS_SPIN_BUTTON, gxg_GTK_IS_SPIN_BUTTON_w, 1, 0, 0, "(GTK_IS_SPIN_BUTTON obj): " PROC_TRUE " if obj is a GTK_IS_SPIN_BUTTON", NULL); Xg_define_procedure(GTK_IS_STATUSBAR, gxg_GTK_IS_STATUSBAR_w, 1, 0, 0, "(GTK_IS_STATUSBAR obj): " PROC_TRUE " if obj is a GTK_IS_STATUSBAR", NULL); Xg_define_procedure(GTK_IS_TEXT_BUFFER, gxg_GTK_IS_TEXT_BUFFER_w, 1, 0, 0, "(GTK_IS_TEXT_BUFFER obj): " PROC_TRUE " if obj is a GTK_IS_TEXT_BUFFER", NULL); Xg_define_procedure(GTK_IS_TEXT_CHILD_ANCHOR, gxg_GTK_IS_TEXT_CHILD_ANCHOR_w, 1, 0, 0, "(GTK_IS_TEXT_CHILD_ANCHOR obj): " PROC_TRUE " if obj is a GTK_IS_TEXT_CHILD_ANCHOR", NULL); Xg_define_procedure(GTK_IS_TEXT_MARK, gxg_GTK_IS_TEXT_MARK_w, 1, 0, 0, "(GTK_IS_TEXT_MARK obj): " PROC_TRUE " if obj is a GTK_IS_TEXT_MARK", NULL); Xg_define_procedure(GTK_IS_TEXT_TAG, gxg_GTK_IS_TEXT_TAG_w, 1, 0, 0, "(GTK_IS_TEXT_TAG obj): " PROC_TRUE " if obj is a GTK_IS_TEXT_TAG", NULL); Xg_define_procedure(GTK_IS_TEXT_TAG_TABLE, gxg_GTK_IS_TEXT_TAG_TABLE_w, 1, 0, 0, "(GTK_IS_TEXT_TAG_TABLE obj): " PROC_TRUE " if obj is a GTK_IS_TEXT_TAG_TABLE", NULL); Xg_define_procedure(GTK_IS_TEXT_VIEW, gxg_GTK_IS_TEXT_VIEW_w, 1, 0, 0, "(GTK_IS_TEXT_VIEW obj): " PROC_TRUE " if obj is a GTK_IS_TEXT_VIEW", NULL); Xg_define_procedure(GTK_IS_TOGGLE_BUTTON, gxg_GTK_IS_TOGGLE_BUTTON_w, 1, 0, 0, "(GTK_IS_TOGGLE_BUTTON obj): " PROC_TRUE " if obj is a GTK_IS_TOGGLE_BUTTON", NULL); Xg_define_procedure(GTK_IS_TOOLBAR, gxg_GTK_IS_TOOLBAR_w, 1, 0, 0, "(GTK_IS_TOOLBAR obj): " PROC_TRUE " if obj is a GTK_IS_TOOLBAR", NULL); Xg_define_procedure(GTK_IS_TREE_DRAG_SOURCE, gxg_GTK_IS_TREE_DRAG_SOURCE_w, 1, 0, 0, "(GTK_IS_TREE_DRAG_SOURCE obj): " PROC_TRUE " if obj is a GTK_IS_TREE_DRAG_SOURCE", NULL); Xg_define_procedure(GTK_IS_TREE_DRAG_DEST, gxg_GTK_IS_TREE_DRAG_DEST_w, 1, 0, 0, "(GTK_IS_TREE_DRAG_DEST obj): " PROC_TRUE " if obj is a GTK_IS_TREE_DRAG_DEST", NULL); Xg_define_procedure(GTK_IS_TREE_MODEL, gxg_GTK_IS_TREE_MODEL_w, 1, 0, 0, "(GTK_IS_TREE_MODEL obj): " PROC_TRUE " if obj is a GTK_IS_TREE_MODEL", NULL); Xg_define_procedure(GTK_IS_TREE_MODEL_SORT, gxg_GTK_IS_TREE_MODEL_SORT_w, 1, 0, 0, "(GTK_IS_TREE_MODEL_SORT obj): " PROC_TRUE " if obj is a GTK_IS_TREE_MODEL_SORT", NULL); Xg_define_procedure(GTK_IS_TREE_SELECTION, gxg_GTK_IS_TREE_SELECTION_w, 1, 0, 0, "(GTK_IS_TREE_SELECTION obj): " PROC_TRUE " if obj is a GTK_IS_TREE_SELECTION", NULL); Xg_define_procedure(GTK_IS_TREE_SORTABLE, gxg_GTK_IS_TREE_SORTABLE_w, 1, 0, 0, "(GTK_IS_TREE_SORTABLE obj): " PROC_TRUE " if obj is a GTK_IS_TREE_SORTABLE", NULL); Xg_define_procedure(GTK_IS_TREE_STORE, gxg_GTK_IS_TREE_STORE_w, 1, 0, 0, "(GTK_IS_TREE_STORE obj): " PROC_TRUE " if obj is a GTK_IS_TREE_STORE", NULL); Xg_define_procedure(GTK_IS_TREE_VIEW_COLUMN, gxg_GTK_IS_TREE_VIEW_COLUMN_w, 1, 0, 0, "(GTK_IS_TREE_VIEW_COLUMN obj): " PROC_TRUE " if obj is a GTK_IS_TREE_VIEW_COLUMN", NULL); Xg_define_procedure(GTK_IS_TREE_VIEW, gxg_GTK_IS_TREE_VIEW_w, 1, 0, 0, "(GTK_IS_TREE_VIEW obj): " PROC_TRUE " if obj is a GTK_IS_TREE_VIEW", NULL); Xg_define_procedure(GTK_IS_VIEWPORT, gxg_GTK_IS_VIEWPORT_w, 1, 0, 0, "(GTK_IS_VIEWPORT obj): " PROC_TRUE " if obj is a GTK_IS_VIEWPORT", NULL); Xg_define_procedure(GTK_IS_WIDGET, gxg_GTK_IS_WIDGET_w, 1, 0, 0, "(GTK_IS_WIDGET obj): " PROC_TRUE " if obj is a GTK_IS_WIDGET", NULL); Xg_define_procedure(GTK_IS_WINDOW, gxg_GTK_IS_WINDOW_w, 1, 0, 0, "(GTK_IS_WINDOW obj): " PROC_TRUE " if obj is a GTK_IS_WINDOW", NULL); Xg_define_procedure(PANGO_IS_CONTEXT, gxg_PANGO_IS_CONTEXT_w, 1, 0, 0, "(PANGO_IS_CONTEXT obj): " PROC_TRUE " if obj is a PANGO_IS_CONTEXT", NULL); Xg_define_procedure(PANGO_IS_FONT_FAMILY, gxg_PANGO_IS_FONT_FAMILY_w, 1, 0, 0, "(PANGO_IS_FONT_FAMILY obj): " PROC_TRUE " if obj is a PANGO_IS_FONT_FAMILY", NULL); Xg_define_procedure(PANGO_IS_FONT_FACE, gxg_PANGO_IS_FONT_FACE_w, 1, 0, 0, "(PANGO_IS_FONT_FACE obj): " PROC_TRUE " if obj is a PANGO_IS_FONT_FACE", NULL); Xg_define_procedure(PANGO_IS_FONT, gxg_PANGO_IS_FONT_w, 1, 0, 0, "(PANGO_IS_FONT obj): " PROC_TRUE " if obj is a PANGO_IS_FONT", NULL); Xg_define_procedure(PANGO_IS_FONT_MAP, gxg_PANGO_IS_FONT_MAP_w, 1, 0, 0, "(PANGO_IS_FONT_MAP obj): " PROC_TRUE " if obj is a PANGO_IS_FONT_MAP", NULL); Xg_define_procedure(PANGO_IS_LAYOUT, gxg_PANGO_IS_LAYOUT_w, 1, 0, 0, "(PANGO_IS_LAYOUT obj): " PROC_TRUE " if obj is a PANGO_IS_LAYOUT", NULL); Xg_define_procedure(G_IS_OBJECT, gxg_G_IS_OBJECT_w, 1, 0, 0, "(G_IS_OBJECT obj): " PROC_TRUE " if obj is a G_IS_OBJECT", NULL); Xg_define_procedure(GDK_IS_SCREEN, gxg_GDK_IS_SCREEN_w, 1, 0, 0, "(GDK_IS_SCREEN obj): " PROC_TRUE " if obj is a GDK_IS_SCREEN", NULL); Xg_define_procedure(GDK_IS_DISPLAY, gxg_GDK_IS_DISPLAY_w, 1, 0, 0, "(GDK_IS_DISPLAY obj): " PROC_TRUE " if obj is a GDK_IS_DISPLAY", NULL); Xg_define_procedure(GTK_IS_FILE_CHOOSER_DIALOG, gxg_GTK_IS_FILE_CHOOSER_DIALOG_w, 1, 0, 0, "(GTK_IS_FILE_CHOOSER_DIALOG obj): " PROC_TRUE " if obj is a GTK_IS_FILE_CHOOSER_DIALOG", NULL); Xg_define_procedure(GTK_IS_FILE_CHOOSER_WIDGET, gxg_GTK_IS_FILE_CHOOSER_WIDGET_w, 1, 0, 0, "(GTK_IS_FILE_CHOOSER_WIDGET obj): " PROC_TRUE " if obj is a GTK_IS_FILE_CHOOSER_WIDGET", NULL); Xg_define_procedure(GTK_IS_TREE_MODEL_FILTER, gxg_GTK_IS_TREE_MODEL_FILTER_w, 1, 0, 0, "(GTK_IS_TREE_MODEL_FILTER obj): " PROC_TRUE " if obj is a GTK_IS_TREE_MODEL_FILTER", NULL); Xg_define_procedure(GTK_IS_COMBO_BOX, gxg_GTK_IS_COMBO_BOX_w, 1, 0, 0, "(GTK_IS_COMBO_BOX obj): " PROC_TRUE " if obj is a GTK_IS_COMBO_BOX", NULL); Xg_define_procedure(GTK_IS_EXPANDER, gxg_GTK_IS_EXPANDER_w, 1, 0, 0, "(GTK_IS_EXPANDER obj): " PROC_TRUE " if obj is a GTK_IS_EXPANDER", NULL); Xg_define_procedure(GTK_IS_FONT_BUTTON, gxg_GTK_IS_FONT_BUTTON_w, 1, 0, 0, "(GTK_IS_FONT_BUTTON obj): " PROC_TRUE " if obj is a GTK_IS_FONT_BUTTON", NULL); Xg_define_procedure(GTK_IS_COLOR_BUTTON, gxg_GTK_IS_COLOR_BUTTON_w, 1, 0, 0, "(GTK_IS_COLOR_BUTTON obj): " PROC_TRUE " if obj is a GTK_IS_COLOR_BUTTON", NULL); Xg_define_procedure(GTK_IS_ENTRY_COMPLETION, gxg_GTK_IS_ENTRY_COMPLETION_w, 1, 0, 0, "(GTK_IS_ENTRY_COMPLETION obj): " PROC_TRUE " if obj is a GTK_IS_ENTRY_COMPLETION", NULL); Xg_define_procedure(GTK_IS_RADIO_TOOL_BUTTON, gxg_GTK_IS_RADIO_TOOL_BUTTON_w, 1, 0, 0, "(GTK_IS_RADIO_TOOL_BUTTON obj): " PROC_TRUE " if obj is a GTK_IS_RADIO_TOOL_BUTTON", NULL); Xg_define_procedure(GTK_IS_SEPARATOR_TOOL_ITEM, gxg_GTK_IS_SEPARATOR_TOOL_ITEM_w, 1, 0, 0, "(GTK_IS_SEPARATOR_TOOL_ITEM obj): " PROC_TRUE " if obj is a GTK_IS_SEPARATOR_TOOL_ITEM", NULL); Xg_define_procedure(GTK_IS_TOGGLE_TOOL_BUTTON, gxg_GTK_IS_TOGGLE_TOOL_BUTTON_w, 1, 0, 0, "(GTK_IS_TOGGLE_TOOL_BUTTON obj): " PROC_TRUE " if obj is a GTK_IS_TOGGLE_TOOL_BUTTON", NULL); Xg_define_procedure(GTK_IS_FILE_FILTER, gxg_GTK_IS_FILE_FILTER_w, 1, 0, 0, "(GTK_IS_FILE_FILTER obj): " PROC_TRUE " if obj is a GTK_IS_FILE_FILTER", NULL); Xg_define_procedure(GTK_IS_CELL_LAYOUT, gxg_GTK_IS_CELL_LAYOUT_w, 1, 0, 0, "(GTK_IS_CELL_LAYOUT obj): " PROC_TRUE " if obj is a GTK_IS_CELL_LAYOUT", NULL); Xg_define_procedure(GTK_IS_CLIPBOARD, gxg_GTK_IS_CLIPBOARD_w, 1, 0, 0, "(GTK_IS_CLIPBOARD obj): " PROC_TRUE " if obj is a GTK_IS_CLIPBOARD", NULL); Xg_define_procedure(GTK_IS_FILE_CHOOSER, gxg_GTK_IS_FILE_CHOOSER_w, 1, 0, 0, "(GTK_IS_FILE_CHOOSER obj): " PROC_TRUE " if obj is a GTK_IS_FILE_CHOOSER", NULL); Xg_define_procedure(GTK_IS_ICON_THEME, gxg_GTK_IS_ICON_THEME_w, 1, 0, 0, "(GTK_IS_ICON_THEME obj): " PROC_TRUE " if obj is a GTK_IS_ICON_THEME", NULL); Xg_define_procedure(GTK_IS_TOOL_BUTTON, gxg_GTK_IS_TOOL_BUTTON_w, 1, 0, 0, "(GTK_IS_TOOL_BUTTON obj): " PROC_TRUE " if obj is a GTK_IS_TOOL_BUTTON", NULL); Xg_define_procedure(GTK_IS_TOOL_ITEM, gxg_GTK_IS_TOOL_ITEM_w, 1, 0, 0, "(GTK_IS_TOOL_ITEM obj): " PROC_TRUE " if obj is a GTK_IS_TOOL_ITEM", NULL); Xg_define_procedure(GTK_IS_ACCEL_MAP, gxg_GTK_IS_ACCEL_MAP_w, 1, 0, 0, "(GTK_IS_ACCEL_MAP obj): " PROC_TRUE " if obj is a GTK_IS_ACCEL_MAP", NULL); Xg_define_procedure(GTK_IS_CELL_VIEW, gxg_GTK_IS_CELL_VIEW_w, 1, 0, 0, "(GTK_IS_CELL_VIEW obj): " PROC_TRUE " if obj is a GTK_IS_CELL_VIEW", NULL); Xg_define_procedure(GTK_IS_ABOUT_DIALOG, gxg_GTK_IS_ABOUT_DIALOG_w, 1, 0, 0, "(GTK_IS_ABOUT_DIALOG obj): " PROC_TRUE " if obj is a GTK_IS_ABOUT_DIALOG", NULL); Xg_define_procedure(GTK_IS_CELL_RENDERER_COMBO, gxg_GTK_IS_CELL_RENDERER_COMBO_w, 1, 0, 0, "(GTK_IS_CELL_RENDERER_COMBO obj): " PROC_TRUE " if obj is a GTK_IS_CELL_RENDERER_COMBO", NULL); Xg_define_procedure(GTK_IS_CELL_RENDERER_PROGRESS, gxg_GTK_IS_CELL_RENDERER_PROGRESS_w, 1, 0, 0, "(GTK_IS_CELL_RENDERER_PROGRESS obj): " PROC_TRUE " if obj is a GTK_IS_CELL_RENDERER_PROGRESS", NULL); Xg_define_procedure(GTK_IS_ICON_VIEW, gxg_GTK_IS_ICON_VIEW_w, 1, 0, 0, "(GTK_IS_ICON_VIEW obj): " PROC_TRUE " if obj is a GTK_IS_ICON_VIEW", NULL); Xg_define_procedure(GTK_IS_FILE_CHOOSER_BUTTON, gxg_GTK_IS_FILE_CHOOSER_BUTTON_w, 1, 0, 0, "(GTK_IS_FILE_CHOOSER_BUTTON obj): " PROC_TRUE " if obj is a GTK_IS_FILE_CHOOSER_BUTTON", NULL); Xg_define_procedure(GTK_IS_MENU_TOOL_BUTTON, gxg_GTK_IS_MENU_TOOL_BUTTON_w, 1, 0, 0, "(GTK_IS_MENU_TOOL_BUTTON obj): " PROC_TRUE " if obj is a GTK_IS_MENU_TOOL_BUTTON", NULL); Xg_define_procedure(GTK_IS_ASSISTANT, gxg_GTK_IS_ASSISTANT_w, 1, 0, 0, "(GTK_IS_ASSISTANT obj): " PROC_TRUE " if obj is a GTK_IS_ASSISTANT", NULL); Xg_define_procedure(GTK_IS_CELL_RENDERER_ACCEL, gxg_GTK_IS_CELL_RENDERER_ACCEL_w, 1, 0, 0, "(GTK_IS_CELL_RENDERER_ACCEL obj): " PROC_TRUE " if obj is a GTK_IS_CELL_RENDERER_ACCEL", NULL); Xg_define_procedure(GTK_IS_CELL_RENDERER_SPIN, gxg_GTK_IS_CELL_RENDERER_SPIN_w, 1, 0, 0, "(GTK_IS_CELL_RENDERER_SPIN obj): " PROC_TRUE " if obj is a GTK_IS_CELL_RENDERER_SPIN", NULL); Xg_define_procedure(GTK_IS_LINK_BUTTON, gxg_GTK_IS_LINK_BUTTON_w, 1, 0, 0, "(GTK_IS_LINK_BUTTON obj): " PROC_TRUE " if obj is a GTK_IS_LINK_BUTTON", NULL); Xg_define_procedure(GTK_IS_RECENT_CHOOSER_DIALOG, gxg_GTK_IS_RECENT_CHOOSER_DIALOG_w, 1, 0, 0, "(GTK_IS_RECENT_CHOOSER_DIALOG obj): " PROC_TRUE " if obj is a GTK_IS_RECENT_CHOOSER_DIALOG", NULL); Xg_define_procedure(GTK_IS_RECENT_CHOOSER, gxg_GTK_IS_RECENT_CHOOSER_w, 1, 0, 0, "(GTK_IS_RECENT_CHOOSER obj): " PROC_TRUE " if obj is a GTK_IS_RECENT_CHOOSER", NULL); Xg_define_procedure(GTK_IS_RECENT_CHOOSER_MENU, gxg_GTK_IS_RECENT_CHOOSER_MENU_w, 1, 0, 0, "(GTK_IS_RECENT_CHOOSER_MENU obj): " PROC_TRUE " if obj is a GTK_IS_RECENT_CHOOSER_MENU", NULL); Xg_define_procedure(GTK_IS_RECENT_CHOOSER_WIDGET, gxg_GTK_IS_RECENT_CHOOSER_WIDGET_w, 1, 0, 0, "(GTK_IS_RECENT_CHOOSER_WIDGET obj): " PROC_TRUE " if obj is a GTK_IS_RECENT_CHOOSER_WIDGET", NULL); Xg_define_procedure(GTK_IS_RECENT_FILTER, gxg_GTK_IS_RECENT_FILTER_w, 1, 0, 0, "(GTK_IS_RECENT_FILTER obj): " PROC_TRUE " if obj is a GTK_IS_RECENT_FILTER", NULL); Xg_define_procedure(GTK_IS_RECENT_MANAGER, gxg_GTK_IS_RECENT_MANAGER_w, 1, 0, 0, "(GTK_IS_RECENT_MANAGER obj): " PROC_TRUE " if obj is a GTK_IS_RECENT_MANAGER", NULL); Xg_define_procedure(GTK_IS_PRINT_CONTEXT, gxg_GTK_IS_PRINT_CONTEXT_w, 1, 0, 0, "(GTK_IS_PRINT_CONTEXT obj): " PROC_TRUE " if obj is a GTK_IS_PRINT_CONTEXT", NULL); Xg_define_procedure(GTK_IS_PRINT_OPERATION, gxg_GTK_IS_PRINT_OPERATION_w, 1, 0, 0, "(GTK_IS_PRINT_OPERATION obj): " PROC_TRUE " if obj is a GTK_IS_PRINT_OPERATION", NULL); Xg_define_procedure(GTK_IS_PRINT_OPERATION_PREVIEW, gxg_GTK_IS_PRINT_OPERATION_PREVIEW_w, 1, 0, 0, "(GTK_IS_PRINT_OPERATION_PREVIEW obj): " PROC_TRUE " if obj is a GTK_IS_PRINT_OPERATION_PREVIEW", NULL); Xg_define_procedure(GTK_IS_PRINT_SETTINGS, gxg_GTK_IS_PRINT_SETTINGS_w, 1, 0, 0, "(GTK_IS_PRINT_SETTINGS obj): " PROC_TRUE " if obj is a GTK_IS_PRINT_SETTINGS", NULL); Xg_define_procedure(GTK_IS_TOOLTIP, gxg_GTK_IS_TOOLTIP_w, 1, 0, 0, "(GTK_IS_TOOLTIP obj): " PROC_TRUE " if obj is a GTK_IS_TOOLTIP", NULL); #if GTK_CHECK_VERSION(2, 18, 0) Xg_define_procedure(GTK_IS_INFO_BAR, gxg_GTK_IS_INFO_BAR_w, 1, 0, 0, "(GTK_IS_INFO_BAR obj): " PROC_TRUE " if obj is a GTK_IS_INFO_BAR", NULL); Xg_define_procedure(GTK_IS_ENTRY_BUFFER, gxg_GTK_IS_ENTRY_BUFFER_w, 1, 0, 0, "(GTK_IS_ENTRY_BUFFER obj): " PROC_TRUE " if obj is a GTK_IS_ENTRY_BUFFER", NULL); #endif #if GTK_CHECK_VERSION(2, 20, 0) Xg_define_procedure(GTK_IS_SPINNER, gxg_GTK_IS_SPINNER_w, 1, 0, 0, "(GTK_IS_SPINNER obj): " PROC_TRUE " if obj is a GTK_IS_SPINNER", NULL); Xg_define_procedure(GTK_IS_CELL_RENDERER_SPINNER, gxg_GTK_IS_CELL_RENDERER_SPINNER_w, 1, 0, 0, "(GTK_IS_CELL_RENDERER_SPINNER obj): " PROC_TRUE " if obj is a GTK_IS_CELL_RENDERER_SPINNER", NULL); Xg_define_procedure(GTK_IS_TOOL_PALETTE, gxg_GTK_IS_TOOL_PALETTE_w, 1, 0, 0, "(GTK_IS_TOOL_PALETTE obj): " PROC_TRUE " if obj is a GTK_IS_TOOL_PALETTE", NULL); Xg_define_procedure(GTK_IS_TOOL_ITEM_GROUP, gxg_GTK_IS_TOOL_ITEM_GROUP_w, 1, 0, 0, "(GTK_IS_TOOL_ITEM_GROUP obj): " PROC_TRUE " if obj is a GTK_IS_TOOL_ITEM_GROUP", NULL); #endif #if GTK_CHECK_VERSION(3, 0, 0) Xg_define_procedure(GTK_IS_COMBO_BOX_TEXT, gxg_GTK_IS_COMBO_BOX_TEXT_w, 1, 0, 0, "(GTK_IS_COMBO_BOX_TEXT obj): " PROC_TRUE " if obj is a GTK_IS_COMBO_BOX_TEXT", NULL); Xg_define_procedure(GTK_IS_GRID, gxg_GTK_IS_GRID_w, 1, 0, 0, "(GTK_IS_GRID obj): " PROC_TRUE " if obj is a GTK_IS_GRID", NULL); Xg_define_procedure(GTK_IS_SCROLLABLE, gxg_GTK_IS_SCROLLABLE_w, 1, 0, 0, "(GTK_IS_SCROLLABLE obj): " PROC_TRUE " if obj is a GTK_IS_SCROLLABLE", NULL); Xg_define_procedure(GTK_IS_SWITCH, gxg_GTK_IS_SWITCH_w, 1, 0, 0, "(GTK_IS_SWITCH obj): " PROC_TRUE " if obj is a GTK_IS_SWITCH", NULL); Xg_define_procedure(GTK_IS_ORIENTABLE, gxg_GTK_IS_ORIENTABLE_w, 1, 0, 0, "(GTK_IS_ORIENTABLE obj): " PROC_TRUE " if obj is a GTK_IS_ORIENTABLE", NULL); Xg_define_procedure(GTK_IS_WINDOW_GROUP, gxg_GTK_IS_WINDOW_GROUP_w, 1, 0, 0, "(GTK_IS_WINDOW_GROUP obj): " PROC_TRUE " if obj is a GTK_IS_WINDOW_GROUP", NULL); Xg_define_procedure(GTK_IS_TOOL_SHELL, gxg_GTK_IS_TOOL_SHELL_w, 1, 0, 0, "(GTK_IS_TOOL_SHELL obj): " PROC_TRUE " if obj is a GTK_IS_TOOL_SHELL", NULL); #endif #if GTK_CHECK_VERSION(3, 2, 0) Xg_define_procedure(GTK_IS_OVERLAY, gxg_GTK_IS_OVERLAY_w, 1, 0, 0, "(GTK_IS_OVERLAY obj): " PROC_TRUE " if obj is a GTK_IS_OVERLAY", NULL); Xg_define_procedure(GTK_IS_FONT_CHOOSER, gxg_GTK_IS_FONT_CHOOSER_w, 1, 0, 0, "(GTK_IS_FONT_CHOOSER obj): " PROC_TRUE " if obj is a GTK_IS_FONT_CHOOSER", NULL); Xg_define_procedure(GTK_IS_FONT_CHOOSER_DIALOG, gxg_GTK_IS_FONT_CHOOSER_DIALOG_w, 1, 0, 0, "(GTK_IS_FONT_CHOOSER_DIALOG obj): " PROC_TRUE " if obj is a GTK_IS_FONT_CHOOSER_DIALOG", NULL); Xg_define_procedure(GTK_IS_FONT_CHOOSER_WIDGET, gxg_GTK_IS_FONT_CHOOSER_WIDGET_w, 1, 0, 0, "(GTK_IS_FONT_CHOOSER_WIDGET obj): " PROC_TRUE " if obj is a GTK_IS_FONT_CHOOSER_WIDGET", NULL); #endif #if GTK_CHECK_VERSION(3, 4, 0) Xg_define_procedure(GTK_IS_APPLICATION_WINDOW, gxg_GTK_IS_APPLICATION_WINDOW_w, 1, 0, 0, "(GTK_IS_APPLICATION_WINDOW obj): " PROC_TRUE " if obj is a GTK_IS_APPLICATION_WINDOW", NULL); Xg_define_procedure(GTK_IS_COLOR_CHOOSER_DIALOG, gxg_GTK_IS_COLOR_CHOOSER_DIALOG_w, 1, 0, 0, "(GTK_IS_COLOR_CHOOSER_DIALOG obj): " PROC_TRUE " if obj is a GTK_IS_COLOR_CHOOSER_DIALOG", NULL); Xg_define_procedure(GTK_IS_COLOR_CHOOSER_WIDGET, gxg_GTK_IS_COLOR_CHOOSER_WIDGET_w, 1, 0, 0, "(GTK_IS_COLOR_CHOOSER_WIDGET obj): " PROC_TRUE " if obj is a GTK_IS_COLOR_CHOOSER_WIDGET", NULL); #endif #if GTK_CHECK_VERSION(3, 6, 0) Xg_define_procedure(GTK_IS_MENU_BUTTON, gxg_GTK_IS_MENU_BUTTON_w, 1, 0, 0, "(GTK_IS_MENU_BUTTON obj): " PROC_TRUE " if obj is a GTK_IS_MENU_BUTTON", NULL); Xg_define_procedure(GTK_IS_SEARCH_ENTRY, gxg_GTK_IS_SEARCH_ENTRY_w, 1, 0, 0, "(GTK_IS_SEARCH_ENTRY obj): " PROC_TRUE " if obj is a GTK_IS_SEARCH_ENTRY", NULL); Xg_define_procedure(GTK_IS_LEVEL_BAR, gxg_GTK_IS_LEVEL_BAR_w, 1, 0, 0, "(GTK_IS_LEVEL_BAR obj): " PROC_TRUE " if obj is a GTK_IS_LEVEL_BAR", NULL); #endif #if GTK_CHECK_VERSION(3, 10, 0) Xg_define_procedure(GTK_IS_PLACES_SIDEBAR, gxg_GTK_IS_PLACES_SIDEBAR_w, 1, 0, 0, "(GTK_IS_PLACES_SIDEBAR obj): " PROC_TRUE " if obj is a GTK_IS_PLACES_SIDEBAR", NULL); Xg_define_procedure(GTK_IS_STACK_SWITCHER, gxg_GTK_IS_STACK_SWITCHER_w, 1, 0, 0, "(GTK_IS_STACK_SWITCHER obj): " PROC_TRUE " if obj is a GTK_IS_STACK_SWITCHER", NULL); Xg_define_procedure(GTK_IS_STACK, gxg_GTK_IS_STACK_w, 1, 0, 0, "(GTK_IS_STACK obj): " PROC_TRUE " if obj is a GTK_IS_STACK", NULL); Xg_define_procedure(GTK_IS_REVEALER, gxg_GTK_IS_REVEALER_w, 1, 0, 0, "(GTK_IS_REVEALER obj): " PROC_TRUE " if obj is a GTK_IS_REVEALER", NULL); Xg_define_procedure(GTK_IS_HEADER_BAR, gxg_GTK_IS_HEADER_BAR_w, 1, 0, 0, "(GTK_IS_HEADER_BAR obj): " PROC_TRUE " if obj is a GTK_IS_HEADER_BAR", NULL); Xg_define_procedure(GTK_IS_LIST_BOX, gxg_GTK_IS_LIST_BOX_w, 1, 0, 0, "(GTK_IS_LIST_BOX obj): " PROC_TRUE " if obj is a GTK_IS_LIST_BOX", NULL); Xg_define_procedure(GTK_IS_LIST_BOX_ROW, gxg_GTK_IS_LIST_BOX_ROW_w, 1, 0, 0, "(GTK_IS_LIST_BOX_ROW obj): " PROC_TRUE " if obj is a GTK_IS_LIST_BOX_ROW", NULL); Xg_define_procedure(GTK_IS_SEARCH_BAR, gxg_GTK_IS_SEARCH_BAR_w, 1, 0, 0, "(GTK_IS_SEARCH_BAR obj): " PROC_TRUE " if obj is a GTK_IS_SEARCH_BAR", NULL); #endif #if GTK_CHECK_VERSION(3, 12, 0) Xg_define_procedure(GTK_IS_FLOW_BOX, gxg_GTK_IS_FLOW_BOX_w, 1, 0, 0, "(GTK_IS_FLOW_BOX obj): " PROC_TRUE " if obj is a GTK_IS_FLOW_BOX", NULL); Xg_define_procedure(GTK_IS_FLOW_BOX_CHILD, gxg_GTK_IS_FLOW_BOX_CHILD_w, 1, 0, 0, "(GTK_IS_FLOW_BOX_CHILD obj): " PROC_TRUE " if obj is a GTK_IS_FLOW_BOX_CHILD", NULL); Xg_define_procedure(GTK_IS_ACTION_BAR, gxg_GTK_IS_ACTION_BAR_w, 1, 0, 0, "(GTK_IS_ACTION_BAR obj): " PROC_TRUE " if obj is a GTK_IS_ACTION_BAR", NULL); Xg_define_procedure(GTK_IS_POPOVER, gxg_GTK_IS_POPOVER_w, 1, 0, 0, "(GTK_IS_POPOVER obj): " PROC_TRUE " if obj is a GTK_IS_POPOVER", NULL); #endif #if GTK_CHECK_VERSION(3, 14, 0) Xg_define_procedure(GTK_IS_GESTURE, gxg_GTK_IS_GESTURE_w, 1, 0, 0, "(GTK_IS_GESTURE obj): " PROC_TRUE " if obj is a GTK_IS_GESTURE", NULL); Xg_define_procedure(GTK_IS_GESTURE_DRAG, gxg_GTK_IS_GESTURE_DRAG_w, 1, 0, 0, "(GTK_IS_GESTURE_DRAG obj): " PROC_TRUE " if obj is a GTK_IS_GESTURE_DRAG", NULL); Xg_define_procedure(GTK_IS_GESTURE_LONG_PRESS, gxg_GTK_IS_GESTURE_LONG_PRESS_w, 1, 0, 0, "(GTK_IS_GESTURE_LONG_PRESS obj): " PROC_TRUE " if obj is a GTK_IS_GESTURE_LONG_PRESS", NULL); Xg_define_procedure(GTK_IS_GESTURE_ZOOM, gxg_GTK_IS_GESTURE_ZOOM_w, 1, 0, 0, "(GTK_IS_GESTURE_ZOOM obj): " PROC_TRUE " if obj is a GTK_IS_GESTURE_ZOOM", NULL); Xg_define_procedure(GTK_IS_GESTURE_SWIPE, gxg_GTK_IS_GESTURE_SWIPE_w, 1, 0, 0, "(GTK_IS_GESTURE_SWIPE obj): " PROC_TRUE " if obj is a GTK_IS_GESTURE_SWIPE", NULL); Xg_define_procedure(GTK_IS_GESTURE_SINGLE, gxg_GTK_IS_GESTURE_SINGLE_w, 1, 0, 0, "(GTK_IS_GESTURE_SINGLE obj): " PROC_TRUE " if obj is a GTK_IS_GESTURE_SINGLE", NULL); Xg_define_procedure(GTK_IS_GESTURE_PAN, gxg_GTK_IS_GESTURE_PAN_w, 1, 0, 0, "(GTK_IS_GESTURE_PAN obj): " PROC_TRUE " if obj is a GTK_IS_GESTURE_PAN", NULL); Xg_define_procedure(GTK_IS_GESTURE_MULTI_PRESS, gxg_GTK_IS_GESTURE_MULTI_PRESS_w, 1, 0, 0, "(GTK_IS_GESTURE_MULTI_PRESS obj): " PROC_TRUE " if obj is a GTK_IS_GESTURE_MULTI_PRESS", NULL); Xg_define_procedure(GTK_IS_GESTURE_ROTATE, gxg_GTK_IS_GESTURE_ROTATE_w, 1, 0, 0, "(GTK_IS_GESTURE_ROTATE obj): " PROC_TRUE " if obj is a GTK_IS_GESTURE_ROTATE", NULL); Xg_define_procedure(GTK_IS_EVENT_CONTROLLER, gxg_GTK_IS_EVENT_CONTROLLER_w, 1, 0, 0, "(GTK_IS_EVENT_CONTROLLER obj): " PROC_TRUE " if obj is a GTK_IS_EVENT_CONTROLLER", NULL); #endif #if GTK_CHECK_VERSION(3, 16, 0) Xg_define_procedure(GTK_IS_GL_AREA, gxg_GTK_IS_GL_AREA_w, 1, 0, 0, "(GTK_IS_GL_AREA obj): " PROC_TRUE " if obj is a GTK_IS_GL_AREA", NULL); Xg_define_procedure(GDK_IS_GL_CONTEXT, gxg_GDK_IS_GL_CONTEXT_w, 1, 0, 0, "(GDK_IS_GL_CONTEXT obj): " PROC_TRUE " if obj is a GDK_IS_GL_CONTEXT", NULL); Xg_define_procedure(GTK_IS_POPOVER_MENU, gxg_GTK_IS_POPOVER_MENU_w, 1, 0, 0, "(GTK_IS_POPOVER_MENU obj): " PROC_TRUE " if obj is a GTK_IS_POPOVER_MENU", NULL); Xg_define_procedure(GTK_IS_STACK_SIDEBAR, gxg_GTK_IS_STACK_SIDEBAR_w, 1, 0, 0, "(GTK_IS_STACK_SIDEBAR obj): " PROC_TRUE " if obj is a GTK_IS_STACK_SIDEBAR", NULL); #endif } /* ---------------------------------------- constants ---------------------------------------- */ static void define_integers(void) { #define define_integer(Name) Xen_define(Xg_pre #Name Xg_post, C_int_to_Xen_integer(Name)) #if !GLIB_CHECK_VERSION(2,35,0) g_type_init(); #endif define_integer(G_NORMALIZE_DEFAULT); define_integer(G_NORMALIZE_NFD); define_integer(G_NORMALIZE_DEFAULT_COMPOSE); define_integer(G_NORMALIZE_NFC); define_integer(G_NORMALIZE_ALL); define_integer(G_NORMALIZE_NFKD); define_integer(G_NORMALIZE_ALL_COMPOSE); define_integer(G_NORMALIZE_NFKC); define_integer(G_SIGNAL_RUN_FIRST); define_integer(G_SIGNAL_RUN_LAST); define_integer(G_SIGNAL_RUN_CLEANUP); define_integer(G_SIGNAL_NO_RECURSE); define_integer(G_SIGNAL_DETAILED); define_integer(G_SIGNAL_ACTION); define_integer(G_SIGNAL_NO_HOOKS); define_integer(G_CONNECT_AFTER); define_integer(G_CONNECT_SWAPPED); define_integer(G_SIGNAL_MATCH_ID); define_integer(G_SIGNAL_MATCH_DETAIL); define_integer(G_SIGNAL_MATCH_CLOSURE); define_integer(G_SIGNAL_MATCH_FUNC); define_integer(G_SIGNAL_MATCH_DATA); define_integer(G_SIGNAL_MATCH_UNBLOCKED); define_integer(GDK_X_CURSOR); define_integer(GDK_ARROW); define_integer(GDK_BASED_ARROW_DOWN); define_integer(GDK_BASED_ARROW_UP); define_integer(GDK_BOAT); define_integer(GDK_BOGOSITY); define_integer(GDK_BOTTOM_LEFT_CORNER); define_integer(GDK_BOTTOM_RIGHT_CORNER); define_integer(GDK_BOTTOM_SIDE); define_integer(GDK_BOTTOM_TEE); define_integer(GDK_BOX_SPIRAL); define_integer(GDK_CENTER_PTR); define_integer(GDK_CIRCLE); define_integer(GDK_CLOCK); define_integer(GDK_COFFEE_MUG); define_integer(GDK_CROSS); define_integer(GDK_CROSS_REVERSE); define_integer(GDK_CROSSHAIR); define_integer(GDK_DIAMOND_CROSS); define_integer(GDK_DOT); define_integer(GDK_DOTBOX); define_integer(GDK_DOUBLE_ARROW); define_integer(GDK_DRAFT_LARGE); define_integer(GDK_DRAFT_SMALL); define_integer(GDK_DRAPED_BOX); define_integer(GDK_EXCHANGE); define_integer(GDK_FLEUR); define_integer(GDK_GOBBLER); define_integer(GDK_GUMBY); define_integer(GDK_HAND1); define_integer(GDK_HAND2); define_integer(GDK_HEART); define_integer(GDK_ICON); define_integer(GDK_IRON_CROSS); define_integer(GDK_LEFT_PTR); define_integer(GDK_LEFT_SIDE); define_integer(GDK_LEFT_TEE); define_integer(GDK_LEFTBUTTON); define_integer(GDK_LL_ANGLE); define_integer(GDK_LR_ANGLE); define_integer(GDK_MAN); define_integer(GDK_MIDDLEBUTTON); define_integer(GDK_MOUSE); define_integer(GDK_PENCIL); define_integer(GDK_PIRATE); define_integer(GDK_PLUS); define_integer(GDK_QUESTION_ARROW); define_integer(GDK_RIGHT_PTR); define_integer(GDK_RIGHT_SIDE); define_integer(GDK_RIGHT_TEE); define_integer(GDK_RIGHTBUTTON); define_integer(GDK_RTL_LOGO); define_integer(GDK_SAILBOAT); define_integer(GDK_SB_DOWN_ARROW); define_integer(GDK_SB_H_DOUBLE_ARROW); define_integer(GDK_SB_LEFT_ARROW); define_integer(GDK_SB_RIGHT_ARROW); define_integer(GDK_SB_UP_ARROW); define_integer(GDK_SB_V_DOUBLE_ARROW); define_integer(GDK_SHUTTLE); define_integer(GDK_SIZING); define_integer(GDK_SPIDER); define_integer(GDK_SPRAYCAN); define_integer(GDK_STAR); define_integer(GDK_TARGET); define_integer(GDK_TCROSS); define_integer(GDK_TOP_LEFT_ARROW); define_integer(GDK_TOP_LEFT_CORNER); define_integer(GDK_TOP_RIGHT_CORNER); define_integer(GDK_TOP_SIDE); define_integer(GDK_TOP_TEE); define_integer(GDK_TREK); define_integer(GDK_UL_ANGLE); define_integer(GDK_UMBRELLA); define_integer(GDK_UR_ANGLE); define_integer(GDK_WATCH); define_integer(GDK_XTERM); define_integer(GDK_LAST_CURSOR ); define_integer(GDK_ACTION_DEFAULT); define_integer(GDK_ACTION_COPY); define_integer(GDK_ACTION_MOVE); define_integer(GDK_ACTION_LINK); define_integer(GDK_ACTION_PRIVATE); define_integer(GDK_ACTION_ASK); define_integer(GDK_PRIORITY_EVENTS); define_integer(GDK_PRIORITY_REDRAW); define_integer(GDK_NOTHING); define_integer(GDK_DELETE); define_integer(GDK_DESTROY); define_integer(GDK_EXPOSE); define_integer(GDK_MOTION_NOTIFY); define_integer(GDK_BUTTON_PRESS); define_integer(GDK_2BUTTON_PRESS); define_integer(GDK_3BUTTON_PRESS); define_integer(GDK_BUTTON_RELEASE); define_integer(GDK_KEY_PRESS); define_integer(GDK_KEY_RELEASE); define_integer(GDK_ENTER_NOTIFY); define_integer(GDK_LEAVE_NOTIFY); define_integer(GDK_FOCUS_CHANGE); define_integer(GDK_CONFIGURE); define_integer(GDK_MAP); define_integer(GDK_UNMAP); define_integer(GDK_PROPERTY_NOTIFY); define_integer(GDK_SELECTION_CLEAR); define_integer(GDK_SELECTION_REQUEST); define_integer(GDK_SELECTION_NOTIFY); define_integer(GDK_PROXIMITY_IN); define_integer(GDK_PROXIMITY_OUT); define_integer(GDK_DRAG_ENTER); define_integer(GDK_DRAG_LEAVE); define_integer(GDK_DRAG_MOTION); define_integer(GDK_DRAG_STATUS); define_integer(GDK_DROP_START); define_integer(GDK_DROP_FINISHED); define_integer(GDK_CLIENT_EVENT); define_integer(GDK_VISIBILITY_NOTIFY); define_integer(GDK_SCROLL); define_integer(GDK_WINDOW_STATE); define_integer(GDK_SETTING); define_integer(GDK_OWNER_CHANGE); define_integer(GDK_GRAB_BROKEN); define_integer(GDK_EXPOSURE_MASK); define_integer(GDK_POINTER_MOTION_MASK); define_integer(GDK_BUTTON_MOTION_MASK); define_integer(GDK_BUTTON1_MOTION_MASK); define_integer(GDK_BUTTON2_MOTION_MASK); define_integer(GDK_BUTTON3_MOTION_MASK); define_integer(GDK_BUTTON_PRESS_MASK); define_integer(GDK_BUTTON_RELEASE_MASK); define_integer(GDK_KEY_PRESS_MASK); define_integer(GDK_KEY_RELEASE_MASK); define_integer(GDK_ENTER_NOTIFY_MASK); define_integer(GDK_LEAVE_NOTIFY_MASK); define_integer(GDK_FOCUS_CHANGE_MASK); define_integer(GDK_STRUCTURE_MASK); define_integer(GDK_PROPERTY_CHANGE_MASK); define_integer(GDK_VISIBILITY_NOTIFY_MASK); define_integer(GDK_PROXIMITY_IN_MASK); define_integer(GDK_PROXIMITY_OUT_MASK); define_integer(GDK_SUBSTRUCTURE_MASK); define_integer(GDK_SCROLL_MASK); define_integer(GDK_ALL_EVENTS_MASK); define_integer(GDK_SCROLL_UP); define_integer(GDK_SCROLL_DOWN); define_integer(GDK_SCROLL_LEFT); define_integer(GDK_SCROLL_RIGHT); define_integer(GDK_NOTIFY_ANCESTOR); define_integer(GDK_NOTIFY_VIRTUAL); define_integer(GDK_NOTIFY_INFERIOR); define_integer(GDK_NOTIFY_NONLINEAR); define_integer(GDK_NOTIFY_NONLINEAR_VIRTUAL); define_integer(GDK_NOTIFY_UNKNOWN); define_integer(GDK_CROSSING_NORMAL); define_integer(GDK_CROSSING_GRAB); define_integer(GDK_CROSSING_UNGRAB); define_integer(GDK_PROPERTY_NEW_VALUE); define_integer(GDK_PROPERTY_DELETE); define_integer(GDK_WINDOW_STATE_WITHDRAWN); define_integer(GDK_WINDOW_STATE_ICONIFIED); define_integer(GDK_WINDOW_STATE_MAXIMIZED); define_integer(GDK_WINDOW_STATE_STICKY); define_integer(GDK_SETTING_ACTION_NEW); define_integer(GDK_SETTING_ACTION_CHANGED); define_integer(GDK_SETTING_ACTION_DELETED); define_integer(GDK_PROP_MODE_REPLACE); define_integer(GDK_PROP_MODE_PREPEND); define_integer(GDK_PROP_MODE_APPEND); define_integer(GDK_CURRENT_TIME); define_integer(GDK_PARENT_RELATIVE); define_integer(GDK_LSB_FIRST); define_integer(GDK_MSB_FIRST); define_integer(GDK_SHIFT_MASK); define_integer(GDK_LOCK_MASK); define_integer(GDK_CONTROL_MASK); define_integer(GDK_MOD1_MASK); define_integer(GDK_MOD2_MASK); define_integer(GDK_MOD3_MASK); define_integer(GDK_MOD4_MASK); define_integer(GDK_MOD5_MASK); define_integer(GDK_BUTTON1_MASK); define_integer(GDK_BUTTON2_MASK); define_integer(GDK_BUTTON3_MASK); define_integer(GDK_BUTTON4_MASK); define_integer(GDK_BUTTON5_MASK); define_integer(GDK_RELEASE_MASK); define_integer(GDK_MODIFIER_MASK); define_integer(GDK_OK); define_integer(GDK_ERROR); define_integer(GDK_ERROR_PARAM); define_integer(GDK_ERROR_FILE); define_integer(GDK_ERROR_MEM); define_integer(GDK_GRAB_SUCCESS); define_integer(GDK_GRAB_ALREADY_GRABBED); define_integer(GDK_GRAB_INVALID_TIME); define_integer(GDK_GRAB_NOT_VIEWABLE); define_integer(GDK_GRAB_FROZEN); define_integer(GDK_VISUAL_STATIC_GRAY); define_integer(GDK_VISUAL_GRAYSCALE); define_integer(GDK_VISUAL_STATIC_COLOR); define_integer(GDK_VISUAL_PSEUDO_COLOR); define_integer(GDK_VISUAL_TRUE_COLOR); define_integer(GDK_VISUAL_DIRECT_COLOR); define_integer(GDK_INPUT_OUTPUT); define_integer(GDK_INPUT_ONLY); define_integer(GDK_WINDOW_ROOT); define_integer(GDK_WINDOW_TOPLEVEL); define_integer(GDK_WINDOW_CHILD); define_integer(GDK_WINDOW_TEMP); define_integer(GDK_WINDOW_FOREIGN); define_integer(GDK_WA_TITLE); define_integer(GDK_WA_X); define_integer(GDK_WA_Y); define_integer(GDK_WA_CURSOR); define_integer(GDK_WA_VISUAL); define_integer(GDK_WA_WMCLASS); define_integer(GDK_WA_NOREDIR); define_integer(GDK_HINT_POS); define_integer(GDK_HINT_MIN_SIZE); define_integer(GDK_HINT_MAX_SIZE); define_integer(GDK_HINT_BASE_SIZE); define_integer(GDK_HINT_ASPECT); define_integer(GDK_HINT_RESIZE_INC); define_integer(GDK_HINT_WIN_GRAVITY); define_integer(GDK_HINT_USER_POS); define_integer(GDK_HINT_USER_SIZE); define_integer(GDK_WINDOW_TYPE_HINT_NORMAL); define_integer(GDK_WINDOW_TYPE_HINT_DIALOG); define_integer(GDK_WINDOW_TYPE_HINT_MENU); define_integer(GDK_WINDOW_TYPE_HINT_TOOLBAR); define_integer(GDK_DECOR_ALL); define_integer(GDK_DECOR_BORDER); define_integer(GDK_DECOR_RESIZEH); define_integer(GDK_DECOR_TITLE); define_integer(GDK_DECOR_MENU); define_integer(GDK_DECOR_MINIMIZE); define_integer(GDK_DECOR_MAXIMIZE); define_integer(GDK_FUNC_ALL); define_integer(GDK_FUNC_RESIZE); define_integer(GDK_FUNC_MOVE); define_integer(GDK_FUNC_MINIMIZE); define_integer(GDK_FUNC_MAXIMIZE); define_integer(GDK_FUNC_CLOSE); define_integer(GDK_GRAVITY_NORTH_WEST); define_integer(GDK_GRAVITY_NORTH); define_integer(GDK_GRAVITY_NORTH_EAST); define_integer(GDK_GRAVITY_WEST); define_integer(GDK_GRAVITY_CENTER); define_integer(GDK_GRAVITY_EAST); define_integer(GDK_GRAVITY_SOUTH_WEST); define_integer(GDK_GRAVITY_SOUTH); define_integer(GDK_GRAVITY_SOUTH_EAST); define_integer(GDK_GRAVITY_STATIC); define_integer(GDK_WINDOW_EDGE_NORTH_WEST); define_integer(GDK_WINDOW_EDGE_NORTH); define_integer(GDK_WINDOW_EDGE_NORTH_EAST); define_integer(GDK_WINDOW_EDGE_WEST); define_integer(GDK_WINDOW_EDGE_EAST); define_integer(GDK_WINDOW_EDGE_SOUTH_WEST); define_integer(GDK_WINDOW_EDGE_SOUTH); define_integer(GDK_WINDOW_EDGE_SOUTH_EAST); define_integer(GDK_PIXBUF_ALPHA_BILEVEL); define_integer(GDK_PIXBUF_ALPHA_FULL); define_integer(GDK_COLORSPACE_RGB); define_integer(GDK_PIXBUF_ERROR_CORRUPT_IMAGE); define_integer(GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY); define_integer(GDK_PIXBUF_ERROR_BAD_OPTION); define_integer(GDK_PIXBUF_ERROR_UNKNOWN_TYPE); define_integer(GDK_PIXBUF_ERROR_UNSUPPORTED_OPERATION); define_integer(GDK_PIXBUF_ERROR_FAILED); define_integer(GDK_INTERP_NEAREST); define_integer(GDK_INTERP_TILES); define_integer(GDK_INTERP_BILINEAR); define_integer(GDK_INTERP_HYPER); define_integer(GTK_ACCEL_VISIBLE); define_integer(GTK_ACCEL_LOCKED); define_integer(GTK_ACCEL_MASK); define_integer(GTK_CALENDAR_SHOW_HEADING); define_integer(GTK_CALENDAR_SHOW_DAY_NAMES); define_integer(GTK_CALENDAR_NO_MONTH_CHANGE); define_integer(GTK_CALENDAR_SHOW_WEEK_NUMBERS); define_integer(GTK_CELL_RENDERER_SELECTED); define_integer(GTK_CELL_RENDERER_PRELIT); define_integer(GTK_CELL_RENDERER_INSENSITIVE); define_integer(GTK_CELL_RENDERER_SORTED); define_integer(GTK_CELL_RENDERER_FOCUSED); define_integer(GTK_DIALOG_MODAL); define_integer(GTK_DIALOG_DESTROY_WITH_PARENT); define_integer(GTK_RESPONSE_NONE); define_integer(GTK_RESPONSE_REJECT); define_integer(GTK_RESPONSE_ACCEPT); define_integer(GTK_RESPONSE_DELETE_EVENT); define_integer(GTK_RESPONSE_OK); define_integer(GTK_RESPONSE_CANCEL); define_integer(GTK_RESPONSE_CLOSE); define_integer(GTK_RESPONSE_YES); define_integer(GTK_RESPONSE_NO); define_integer(GTK_RESPONSE_APPLY); define_integer(GTK_RESPONSE_HELP); define_integer(GTK_DEST_DEFAULT_MOTION); define_integer(GTK_DEST_DEFAULT_HIGHLIGHT); define_integer(GTK_DEST_DEFAULT_DROP); define_integer(GTK_DEST_DEFAULT_ALL); define_integer(GTK_BUTTONBOX_SPREAD); define_integer(GTK_BUTTONBOX_EDGE); define_integer(GTK_BUTTONBOX_START); define_integer(GTK_BUTTONBOX_END); define_integer(GTK_BUTTONBOX_CENTER); define_integer(GTK_DELETE_CHARS); define_integer(GTK_DELETE_WORD_ENDS); define_integer(GTK_DELETE_WORDS); define_integer(GTK_DELETE_DISPLAY_LINES); define_integer(GTK_DELETE_DISPLAY_LINE_ENDS); define_integer(GTK_DELETE_PARAGRAPH_ENDS); define_integer(GTK_DELETE_PARAGRAPHS); define_integer(GTK_DELETE_WHITESPACE); define_integer(GTK_DIR_TAB_FORWARD); define_integer(GTK_DIR_TAB_BACKWARD); define_integer(GTK_DIR_UP); define_integer(GTK_DIR_DOWN); define_integer(GTK_DIR_LEFT); define_integer(GTK_DIR_RIGHT); define_integer(GTK_TEXT_DIR_NONE); define_integer(GTK_TEXT_DIR_LTR); define_integer(GTK_TEXT_DIR_RTL); define_integer(GTK_JUSTIFY_LEFT); define_integer(GTK_JUSTIFY_RIGHT); define_integer(GTK_JUSTIFY_CENTER); define_integer(GTK_JUSTIFY_FILL); define_integer(GTK_MENU_DIR_PARENT); define_integer(GTK_MENU_DIR_CHILD); define_integer(GTK_MENU_DIR_NEXT); define_integer(GTK_MENU_DIR_PREV); define_integer(GTK_MOVEMENT_LOGICAL_POSITIONS); define_integer(GTK_MOVEMENT_VISUAL_POSITIONS); define_integer(GTK_MOVEMENT_WORDS); define_integer(GTK_MOVEMENT_DISPLAY_LINES); define_integer(GTK_MOVEMENT_DISPLAY_LINE_ENDS); define_integer(GTK_MOVEMENT_PARAGRAPHS); define_integer(GTK_MOVEMENT_PARAGRAPH_ENDS); define_integer(GTK_MOVEMENT_PAGES); define_integer(GTK_MOVEMENT_BUFFER_ENDS); define_integer(GTK_ORIENTATION_HORIZONTAL); define_integer(GTK_ORIENTATION_VERTICAL); define_integer(GTK_CORNER_TOP_LEFT); define_integer(GTK_CORNER_BOTTOM_LEFT); define_integer(GTK_CORNER_TOP_RIGHT); define_integer(GTK_CORNER_BOTTOM_RIGHT); define_integer(GTK_PACK_START); define_integer(GTK_PACK_END); define_integer(GTK_POLICY_ALWAYS); define_integer(GTK_POLICY_AUTOMATIC); define_integer(GTK_POLICY_NEVER); define_integer(GTK_POS_LEFT); define_integer(GTK_POS_RIGHT); define_integer(GTK_POS_TOP); define_integer(GTK_POS_BOTTOM); define_integer(GTK_RELIEF_NORMAL); define_integer(GTK_RELIEF_HALF); define_integer(GTK_RELIEF_NONE); define_integer(GTK_RESIZE_PARENT); define_integer(GTK_RESIZE_QUEUE); define_integer(GTK_RESIZE_IMMEDIATE); define_integer(GTK_SCROLL_NONE); define_integer(GTK_SCROLL_JUMP); define_integer(GTK_SCROLL_STEP_BACKWARD); define_integer(GTK_SCROLL_STEP_FORWARD); define_integer(GTK_SCROLL_PAGE_BACKWARD); define_integer(GTK_SCROLL_PAGE_FORWARD); define_integer(GTK_SCROLL_STEP_UP); define_integer(GTK_SCROLL_STEP_DOWN); define_integer(GTK_SCROLL_PAGE_UP); define_integer(GTK_SCROLL_PAGE_DOWN); define_integer(GTK_SCROLL_STEP_LEFT); define_integer(GTK_SCROLL_STEP_RIGHT); define_integer(GTK_SCROLL_PAGE_LEFT); define_integer(GTK_SCROLL_PAGE_RIGHT); define_integer(GTK_SCROLL_START); define_integer(GTK_SCROLL_END); define_integer(GTK_SELECTION_NONE); define_integer(GTK_SELECTION_SINGLE); define_integer(GTK_SELECTION_BROWSE); define_integer(GTK_SELECTION_MULTIPLE); define_integer(GTK_SHADOW_NONE); define_integer(GTK_SHADOW_IN); define_integer(GTK_SHADOW_OUT); define_integer(GTK_SHADOW_ETCHED_IN); define_integer(GTK_SHADOW_ETCHED_OUT); define_integer(GTK_TOOLBAR_ICONS); define_integer(GTK_TOOLBAR_TEXT); define_integer(GTK_TOOLBAR_BOTH); define_integer(GTK_TOOLBAR_BOTH_HORIZ); define_integer(GTK_WIN_POS_NONE); define_integer(GTK_WIN_POS_CENTER); define_integer(GTK_WIN_POS_MOUSE); define_integer(GTK_WIN_POS_CENTER_ALWAYS); define_integer(GTK_WIN_POS_CENTER_ON_PARENT); define_integer(GTK_WINDOW_TOPLEVEL); define_integer(GTK_WINDOW_POPUP); define_integer(GTK_WRAP_NONE); define_integer(GTK_WRAP_CHAR); define_integer(GTK_WRAP_WORD); define_integer(GTK_SORT_ASCENDING); define_integer(GTK_SORT_DESCENDING); define_integer(GTK_IMAGE_EMPTY); define_integer(GTK_IMAGE_PIXBUF); define_integer(GTK_IMAGE_STOCK); define_integer(GTK_IMAGE_ICON_SET); define_integer(GTK_IMAGE_ANIMATION); define_integer(GTK_MAX_COMPOSE_LEN); define_integer(GTK_PRIORITY_RESIZE); define_integer(GTK_MESSAGE_INFO); define_integer(GTK_MESSAGE_WARNING); define_integer(GTK_MESSAGE_QUESTION); define_integer(GTK_MESSAGE_ERROR); define_integer(GTK_BUTTONS_NONE); define_integer(GTK_BUTTONS_OK); define_integer(GTK_BUTTONS_CLOSE); define_integer(GTK_BUTTONS_CANCEL); define_integer(GTK_BUTTONS_YES_NO); define_integer(GTK_BUTTONS_OK_CANCEL); define_integer(GTK_NOTEBOOK_TAB_FIRST); define_integer(GTK_NOTEBOOK_TAB_LAST); define_integer(GTK_SIZE_GROUP_NONE); define_integer(GTK_SIZE_GROUP_HORIZONTAL); define_integer(GTK_SIZE_GROUP_VERTICAL); define_integer(GTK_SIZE_GROUP_BOTH); define_integer(GTK_INPUT_ERROR); define_integer(GTK_UPDATE_ALWAYS); define_integer(GTK_UPDATE_IF_VALID); define_integer(GTK_SPIN_STEP_FORWARD); define_integer(GTK_SPIN_STEP_BACKWARD); define_integer(GTK_SPIN_PAGE_FORWARD); define_integer(GTK_SPIN_PAGE_BACKWARD); define_integer(GTK_SPIN_HOME); define_integer(GTK_SPIN_END); define_integer(GTK_SPIN_USER_DEFINED); define_integer(GTK_TEXT_SEARCH_VISIBLE_ONLY); define_integer(GTK_TEXT_SEARCH_TEXT_ONLY); define_integer(GTK_TEXT_WINDOW_PRIVATE); define_integer(GTK_TEXT_WINDOW_WIDGET); define_integer(GTK_TEXT_WINDOW_TEXT); define_integer(GTK_TEXT_WINDOW_LEFT); define_integer(GTK_TEXT_WINDOW_RIGHT); define_integer(GTK_TEXT_WINDOW_TOP); define_integer(GTK_TEXT_WINDOW_BOTTOM); define_integer(GTK_TEXT_VIEW_PRIORITY_VALIDATE); define_integer(GTK_TREE_MODEL_ITERS_PERSIST); define_integer(GTK_TREE_MODEL_LIST_ONLY); define_integer(GTK_TREE_VIEW_COLUMN_GROW_ONLY); define_integer(GTK_TREE_VIEW_COLUMN_AUTOSIZE); define_integer(GTK_TREE_VIEW_COLUMN_FIXED); define_integer(GTK_TREE_VIEW_DROP_BEFORE); define_integer(GTK_TREE_VIEW_DROP_AFTER); define_integer(GTK_TREE_VIEW_DROP_INTO_OR_BEFORE); define_integer(GTK_TREE_VIEW_DROP_INTO_OR_AFTER); define_integer(PANGO_ATTR_INVALID); define_integer(PANGO_ATTR_LANGUAGE); define_integer(PANGO_ATTR_FAMILY); define_integer(PANGO_ATTR_STYLE); define_integer(PANGO_ATTR_WEIGHT); define_integer(PANGO_ATTR_VARIANT); define_integer(PANGO_ATTR_STRETCH); define_integer(PANGO_ATTR_SIZE); define_integer(PANGO_ATTR_FONT_DESC); define_integer(PANGO_ATTR_FOREGROUND); define_integer(PANGO_ATTR_BACKGROUND); define_integer(PANGO_ATTR_UNDERLINE); define_integer(PANGO_ATTR_STRIKETHROUGH); define_integer(PANGO_ATTR_RISE); define_integer(PANGO_ATTR_SHAPE); define_integer(PANGO_ATTR_SCALE); define_integer(PANGO_UNDERLINE_NONE); define_integer(PANGO_UNDERLINE_SINGLE); define_integer(PANGO_UNDERLINE_DOUBLE); define_integer(PANGO_UNDERLINE_LOW); define_integer(PANGO_COVERAGE_NONE); define_integer(PANGO_COVERAGE_FALLBACK); define_integer(PANGO_COVERAGE_APPROXIMATE); define_integer(PANGO_COVERAGE_EXACT); define_integer(PANGO_STYLE_NORMAL); define_integer(PANGO_STYLE_OBLIQUE); define_integer(PANGO_STYLE_ITALIC); define_integer(PANGO_VARIANT_NORMAL); define_integer(PANGO_VARIANT_SMALL_CAPS); define_integer(PANGO_WEIGHT_ULTRALIGHT); define_integer(PANGO_WEIGHT_LIGHT); define_integer(PANGO_WEIGHT_NORMAL); define_integer(PANGO_WEIGHT_BOLD); define_integer(PANGO_WEIGHT_ULTRABOLD); define_integer(PANGO_WEIGHT_HEAVY); define_integer(PANGO_STRETCH_ULTRA_CONDENSED); define_integer(PANGO_STRETCH_EXTRA_CONDENSED); define_integer(PANGO_STRETCH_CONDENSED); define_integer(PANGO_STRETCH_SEMI_CONDENSED); define_integer(PANGO_STRETCH_NORMAL); define_integer(PANGO_STRETCH_SEMI_EXPANDED); define_integer(PANGO_STRETCH_EXPANDED); define_integer(PANGO_STRETCH_EXTRA_EXPANDED); define_integer(PANGO_STRETCH_ULTRA_EXPANDED); define_integer(PANGO_FONT_MASK_FAMILY); define_integer(PANGO_FONT_MASK_STYLE); define_integer(PANGO_FONT_MASK_VARIANT); define_integer(PANGO_FONT_MASK_WEIGHT); define_integer(PANGO_FONT_MASK_STRETCH); define_integer(PANGO_FONT_MASK_SIZE); define_integer(PANGO_ALIGN_LEFT); define_integer(PANGO_ALIGN_CENTER); define_integer(PANGO_ALIGN_RIGHT); define_integer(PANGO_WRAP_WORD); define_integer(PANGO_WRAP_CHAR); define_integer(PANGO_DIRECTION_LTR); define_integer(PANGO_DIRECTION_RTL); define_integer(PANGO_DIRECTION_TTB_LTR); define_integer(PANGO_DIRECTION_TTB_RTL); define_integer(GDK_WINDOW_STATE_FULLSCREEN); define_integer(GDK_WINDOW_STATE_ABOVE); define_integer(GDK_WINDOW_STATE_BELOW); define_integer(GTK_MOVEMENT_HORIZONTAL_PAGES); define_integer(GTK_SCROLL_STEPS); define_integer(GTK_SCROLL_PAGES); define_integer(GTK_SCROLL_ENDS); define_integer(GTK_SCROLL_HORIZONTAL_STEPS); define_integer(GTK_SCROLL_HORIZONTAL_PAGES); define_integer(GTK_SCROLL_HORIZONTAL_ENDS); define_integer(GTK_WRAP_WORD_CHAR); define_integer(GTK_FILE_FILTER_FILENAME); define_integer(GTK_FILE_FILTER_URI); define_integer(GTK_FILE_FILTER_DISPLAY_NAME); define_integer(GTK_FILE_FILTER_MIME_TYPE); define_integer(GTK_ICON_LOOKUP_NO_SVG); define_integer(GTK_ICON_LOOKUP_FORCE_SVG); define_integer(GTK_ICON_LOOKUP_USE_BUILTIN); define_integer(GTK_ICON_LOOKUP_GENERIC_FALLBACK); define_integer(GTK_FILE_CHOOSER_ACTION_OPEN); define_integer(GTK_FILE_CHOOSER_ACTION_SAVE); define_integer(GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER); define_integer(GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER); define_integer(G_PRIORITY_HIGH); define_integer(G_PRIORITY_DEFAULT); define_integer(G_PRIORITY_HIGH_IDLE); define_integer(G_PRIORITY_DEFAULT_IDLE); define_integer(G_PRIORITY_LOW); define_integer(PANGO_ATTR_FALLBACK); define_integer(PANGO_ATTR_LETTER_SPACING); define_integer(PANGO_UNDERLINE_ERROR); define_integer(PANGO_WRAP_WORD_CHAR); define_integer(PANGO_ELLIPSIZE_NONE); define_integer(PANGO_ELLIPSIZE_START); define_integer(PANGO_ELLIPSIZE_MIDDLE); define_integer(PANGO_ELLIPSIZE_END); define_integer(PANGO_SCRIPT_INVALID_CODE); define_integer(PANGO_SCRIPT_COMMON); define_integer(PANGO_SCRIPT_INHERITED); define_integer(PANGO_SCRIPT_ARABIC); define_integer(PANGO_SCRIPT_ARMENIAN); define_integer(PANGO_SCRIPT_BENGALI); define_integer(PANGO_SCRIPT_BOPOMOFO); define_integer(PANGO_SCRIPT_CHEROKEE); define_integer(PANGO_SCRIPT_COPTIC); define_integer(PANGO_SCRIPT_CYRILLIC); define_integer(PANGO_SCRIPT_DESERET); define_integer(PANGO_SCRIPT_DEVANAGARI); define_integer(PANGO_SCRIPT_ETHIOPIC); define_integer(PANGO_SCRIPT_GEORGIAN); define_integer(PANGO_SCRIPT_GOTHIC); define_integer(PANGO_SCRIPT_GREEK); define_integer(PANGO_SCRIPT_GUJARATI); define_integer(PANGO_SCRIPT_GURMUKHI); define_integer(PANGO_SCRIPT_HAN); define_integer(PANGO_SCRIPT_HANGUL); define_integer(PANGO_SCRIPT_HEBREW); define_integer(PANGO_SCRIPT_HIRAGANA); define_integer(PANGO_SCRIPT_KANNADA); define_integer(PANGO_SCRIPT_KATAKANA); define_integer(PANGO_SCRIPT_KHMER); define_integer(PANGO_SCRIPT_LAO); define_integer(PANGO_SCRIPT_LATIN); define_integer(PANGO_SCRIPT_MALAYALAM); define_integer(PANGO_SCRIPT_MONGOLIAN); define_integer(PANGO_SCRIPT_MYANMAR); define_integer(PANGO_SCRIPT_OGHAM); define_integer(PANGO_SCRIPT_OLD_ITALIC); define_integer(PANGO_SCRIPT_ORIYA); define_integer(PANGO_SCRIPT_RUNIC); define_integer(PANGO_SCRIPT_SINHALA); define_integer(PANGO_SCRIPT_SYRIAC); define_integer(PANGO_SCRIPT_TAMIL); define_integer(PANGO_SCRIPT_TELUGU); define_integer(PANGO_SCRIPT_THAANA); define_integer(PANGO_SCRIPT_THAI); define_integer(PANGO_SCRIPT_TIBETAN); define_integer(PANGO_SCRIPT_CANADIAN_ABORIGINAL); define_integer(PANGO_SCRIPT_YI); define_integer(PANGO_SCRIPT_TAGALOG); define_integer(PANGO_SCRIPT_HANUNOO); define_integer(PANGO_SCRIPT_BUHID); define_integer(PANGO_SCRIPT_TAGBANWA); define_integer(PANGO_SCRIPT_BRAILLE); define_integer(PANGO_SCRIPT_CYPRIOT); define_integer(PANGO_SCRIPT_LIMBU); define_integer(PANGO_SCRIPT_OSMANYA); define_integer(PANGO_SCRIPT_SHAVIAN); define_integer(PANGO_SCRIPT_LINEAR_B); define_integer(PANGO_SCRIPT_TAI_LE); define_integer(PANGO_SCRIPT_UGARITIC); define_integer(PANGO_TAB_LEFT); define_integer(PANGO_DIRECTION_WEAK_LTR); define_integer(PANGO_DIRECTION_WEAK_RTL); define_integer(PANGO_DIRECTION_NEUTRAL); define_integer(GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID); define_integer(GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID); define_integer(GTK_IMAGE_ICON_NAME); define_integer(PANGO_ATTR_UNDERLINE_COLOR); define_integer(PANGO_ATTR_STRIKETHROUGH_COLOR); define_integer(PANGO_RENDER_PART_FOREGROUND); define_integer(PANGO_RENDER_PART_BACKGROUND); define_integer(PANGO_RENDER_PART_UNDERLINE); define_integer(PANGO_RENDER_PART_STRIKETHROUGH); define_integer(G_LOG_FLAG_RECURSION); define_integer(G_LOG_FLAG_FATAL); define_integer(G_LOG_LEVEL_ERROR); define_integer(G_LOG_LEVEL_CRITICAL); define_integer(G_LOG_LEVEL_WARNING); define_integer(G_LOG_LEVEL_MESSAGE); define_integer(G_LOG_LEVEL_INFO); define_integer(G_LOG_LEVEL_DEBUG); define_integer(G_LOG_LEVEL_MASK); define_integer(G_LOG_FATAL_MASK); define_integer(PANGO_WEIGHT_SEMIBOLD); define_integer(GTK_PACK_DIRECTION_LTR); define_integer(GTK_PACK_DIRECTION_RTL); define_integer(GTK_PACK_DIRECTION_TTB); define_integer(GTK_PACK_DIRECTION_BTT); define_integer(GTK_ICON_VIEW_NO_DROP); define_integer(GTK_ICON_VIEW_DROP_INTO); define_integer(GTK_ICON_VIEW_DROP_LEFT); define_integer(GTK_ICON_VIEW_DROP_RIGHT); define_integer(GTK_ICON_VIEW_DROP_ABOVE); define_integer(GTK_ICON_VIEW_DROP_BELOW); define_integer(GTK_FILE_CHOOSER_CONFIRMATION_CONFIRM); define_integer(GTK_FILE_CHOOSER_CONFIRMATION_ACCEPT_FILENAME); define_integer(GTK_FILE_CHOOSER_CONFIRMATION_SELECT_AGAIN); define_integer(PANGO_SCRIPT_NEW_TAI_LUE); define_integer(PANGO_SCRIPT_BUGINESE); define_integer(PANGO_SCRIPT_GLAGOLITIC); define_integer(PANGO_SCRIPT_TIFINAGH); define_integer(PANGO_SCRIPT_SYLOTI_NAGRI); define_integer(PANGO_SCRIPT_OLD_PERSIAN); define_integer(PANGO_SCRIPT_KHAROSHTHI); define_integer(GDK_SUPER_MASK); define_integer(GDK_HYPER_MASK); define_integer(GDK_META_MASK); define_integer(GTK_SENSITIVITY_AUTO); define_integer(GTK_SENSITIVITY_ON); define_integer(GTK_SENSITIVITY_OFF); define_integer(GTK_TEXT_BUFFER_TARGET_INFO_BUFFER_CONTENTS); define_integer(GTK_TEXT_BUFFER_TARGET_INFO_RICH_TEXT); define_integer(GTK_TEXT_BUFFER_TARGET_INFO_TEXT); define_integer(GTK_ASSISTANT_PAGE_CONTENT); define_integer(GTK_ASSISTANT_PAGE_INTRO); define_integer(GTK_ASSISTANT_PAGE_CONFIRM); define_integer(GTK_ASSISTANT_PAGE_SUMMARY); define_integer(GTK_ASSISTANT_PAGE_PROGRESS); define_integer(GTK_CELL_RENDERER_ACCEL_MODE_GTK); define_integer(GTK_CELL_RENDERER_ACCEL_MODE_OTHER); define_integer(GTK_RECENT_SORT_NONE); define_integer(GTK_RECENT_SORT_MRU); define_integer(GTK_RECENT_SORT_LRU); define_integer(GTK_RECENT_SORT_CUSTOM); define_integer(GTK_RECENT_CHOOSER_ERROR_NOT_FOUND); define_integer(GTK_RECENT_CHOOSER_ERROR_INVALID_URI); define_integer(GTK_RECENT_MANAGER_ERROR_NOT_FOUND); define_integer(GTK_RECENT_MANAGER_ERROR_INVALID_URI); define_integer(GTK_RECENT_MANAGER_ERROR_INVALID_ENCODING); define_integer(GTK_RECENT_MANAGER_ERROR_NOT_REGISTERED); define_integer(GTK_RECENT_MANAGER_ERROR_READ); define_integer(GTK_RECENT_MANAGER_ERROR_WRITE); define_integer(GTK_RECENT_MANAGER_ERROR_UNKNOWN); define_integer(GTK_MESSAGE_OTHER); define_integer(GTK_TREE_VIEW_GRID_LINES_NONE); define_integer(GTK_TREE_VIEW_GRID_LINES_HORIZONTAL); define_integer(GTK_TREE_VIEW_GRID_LINES_VERTICAL); define_integer(GTK_TREE_VIEW_GRID_LINES_BOTH); define_integer(GTK_PRINT_STATUS_INITIAL); define_integer(GTK_PRINT_STATUS_PREPARING); define_integer(GTK_PRINT_STATUS_GENERATING_DATA); define_integer(GTK_PRINT_STATUS_SENDING_DATA); define_integer(GTK_PRINT_STATUS_PENDING); define_integer(GTK_PRINT_STATUS_PENDING_ISSUE); define_integer(GTK_PRINT_STATUS_PRINTING); define_integer(GTK_PRINT_STATUS_FINISHED); define_integer(GTK_PRINT_STATUS_FINISHED_ABORTED); define_integer(GTK_PRINT_OPERATION_RESULT_ERROR); define_integer(GTK_PRINT_OPERATION_RESULT_APPLY); define_integer(GTK_PRINT_OPERATION_RESULT_CANCEL); define_integer(GTK_PRINT_OPERATION_RESULT_IN_PROGRESS); define_integer(GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG); define_integer(GTK_PRINT_OPERATION_ACTION_PRINT); define_integer(GTK_PRINT_OPERATION_ACTION_PREVIEW); define_integer(GTK_PRINT_OPERATION_ACTION_EXPORT); define_integer(GTK_PRINT_ERROR_GENERAL); define_integer(GTK_PRINT_ERROR_INTERNAL_ERROR); define_integer(GTK_PRINT_ERROR_NOMEM); define_integer(GTK_PRINT_ERROR_INVALID_FILE); define_integer(GTK_DRAG_RESULT_SUCCESS); define_integer(GTK_DRAG_RESULT_NO_TARGET); define_integer(GTK_DRAG_RESULT_USER_CANCELLED); define_integer(GTK_DRAG_RESULT_TIMEOUT_EXPIRED); define_integer(GTK_DRAG_RESULT_GRAB_BROKEN); define_integer(GTK_DRAG_RESULT_ERROR); #if GTK_CHECK_VERSION(2, 14, 0) define_integer(GTK_CALENDAR_SHOW_DETAILS); define_integer(GDK_CROSSING_GTK_GRAB); define_integer(GDK_CROSSING_GTK_UNGRAB); define_integer(GDK_CROSSING_STATE_CHANGED); #endif #if GTK_CHECK_VERSION(2, 16, 0) define_integer(GTK_ENTRY_ICON_PRIMARY); define_integer(GTK_ENTRY_ICON_SECONDARY); define_integer(GDK_BLANK_CURSOR ); #endif #if GTK_CHECK_VERSION(2, 18, 0) define_integer(PANGO_WEIGHT_THIN); define_integer(PANGO_WEIGHT_BOOK); define_integer(PANGO_WEIGHT_MEDIUM); define_integer(GDK_WINDOW_OFFSCREEN); define_integer(GTK_ENTRY_BUFFER_MAX_SIZE); #endif #if GTK_CHECK_VERSION(3, 0, 0) define_integer(GDK_KEY_VoidSymbol); define_integer(GDK_KEY_BackSpace); define_integer(GDK_KEY_Tab); define_integer(GDK_KEY_Linefeed); define_integer(GDK_KEY_Clear); define_integer(GDK_KEY_Return); define_integer(GDK_KEY_Pause); define_integer(GDK_KEY_Scroll_Lock); define_integer(GDK_KEY_Sys_Req); define_integer(GDK_KEY_Escape); define_integer(GDK_KEY_Delete); define_integer(GDK_KEY_Home); define_integer(GDK_KEY_Left); define_integer(GDK_KEY_Up); define_integer(GDK_KEY_Right); define_integer(GDK_KEY_Down); define_integer(GDK_KEY_Prior); define_integer(GDK_KEY_Page_Up); define_integer(GDK_KEY_Next); define_integer(GDK_KEY_Page_Down); define_integer(GDK_KEY_End); define_integer(GDK_KEY_Begin); define_integer(GDK_KEY_Select); define_integer(GDK_KEY_Print); define_integer(GDK_KEY_Execute); define_integer(GDK_KEY_Insert); define_integer(GDK_KEY_Undo); define_integer(GDK_KEY_Redo); define_integer(GDK_KEY_Menu); define_integer(GDK_KEY_Find); define_integer(GDK_KEY_Cancel); define_integer(GDK_KEY_Help); define_integer(GDK_KEY_Break); define_integer(GDK_KEY_Mode_switch); define_integer(GDK_KEY_script_switch); define_integer(GDK_KEY_Num_Lock); define_integer(GDK_KEY_KP_Space); define_integer(GDK_KEY_KP_Tab); define_integer(GDK_KEY_KP_Enter); define_integer(GDK_KEY_KP_F1); define_integer(GDK_KEY_KP_F2); define_integer(GDK_KEY_KP_F3); define_integer(GDK_KEY_KP_F4); define_integer(GDK_KEY_KP_Home); define_integer(GDK_KEY_KP_Left); define_integer(GDK_KEY_KP_Up); define_integer(GDK_KEY_KP_Right); define_integer(GDK_KEY_KP_Down); define_integer(GDK_KEY_KP_Prior); define_integer(GDK_KEY_KP_Page_Up); define_integer(GDK_KEY_KP_Next); define_integer(GDK_KEY_KP_Page_Down); define_integer(GDK_KEY_KP_End); define_integer(GDK_KEY_KP_Begin); define_integer(GDK_KEY_KP_Insert); define_integer(GDK_KEY_KP_Delete); define_integer(GDK_KEY_KP_Equal); define_integer(GDK_KEY_KP_Multiply); define_integer(GDK_KEY_KP_Add); define_integer(GDK_KEY_KP_Separator); define_integer(GDK_KEY_KP_Subtract); define_integer(GDK_KEY_KP_Decimal); define_integer(GDK_KEY_KP_Divide); define_integer(GDK_KEY_KP_0); define_integer(GDK_KEY_KP_1); define_integer(GDK_KEY_KP_2); define_integer(GDK_KEY_KP_3); define_integer(GDK_KEY_KP_4); define_integer(GDK_KEY_KP_5); define_integer(GDK_KEY_KP_6); define_integer(GDK_KEY_KP_7); define_integer(GDK_KEY_KP_8); define_integer(GDK_KEY_KP_9); define_integer(GDK_KEY_F1); define_integer(GDK_KEY_F2); define_integer(GDK_KEY_F3); define_integer(GDK_KEY_F4); define_integer(GDK_KEY_F5); define_integer(GDK_KEY_F6); define_integer(GDK_KEY_F7); define_integer(GDK_KEY_F8); define_integer(GDK_KEY_F9); define_integer(GDK_KEY_F10); define_integer(GDK_KEY_F11); define_integer(GDK_KEY_L1); define_integer(GDK_KEY_F12); define_integer(GDK_KEY_L2); define_integer(GDK_KEY_F13); define_integer(GDK_KEY_L3); define_integer(GDK_KEY_F14); define_integer(GDK_KEY_L4); define_integer(GDK_KEY_F15); define_integer(GDK_KEY_L5); define_integer(GDK_KEY_F16); define_integer(GDK_KEY_L6); define_integer(GDK_KEY_F17); define_integer(GDK_KEY_L7); define_integer(GDK_KEY_F18); define_integer(GDK_KEY_L8); define_integer(GDK_KEY_F19); define_integer(GDK_KEY_L9); define_integer(GDK_KEY_F20); define_integer(GDK_KEY_L10); define_integer(GDK_KEY_F21); define_integer(GDK_KEY_R1); define_integer(GDK_KEY_F22); define_integer(GDK_KEY_R2); define_integer(GDK_KEY_F23); define_integer(GDK_KEY_R3); define_integer(GDK_KEY_F24); define_integer(GDK_KEY_R4); define_integer(GDK_KEY_F25); define_integer(GDK_KEY_R5); define_integer(GDK_KEY_F26); define_integer(GDK_KEY_R6); define_integer(GDK_KEY_F27); define_integer(GDK_KEY_R7); define_integer(GDK_KEY_F28); define_integer(GDK_KEY_R8); define_integer(GDK_KEY_F29); define_integer(GDK_KEY_R9); define_integer(GDK_KEY_F30); define_integer(GDK_KEY_R10); define_integer(GDK_KEY_F31); define_integer(GDK_KEY_R11); define_integer(GDK_KEY_F32); define_integer(GDK_KEY_R12); define_integer(GDK_KEY_F33); define_integer(GDK_KEY_R13); define_integer(GDK_KEY_F34); define_integer(GDK_KEY_R14); define_integer(GDK_KEY_F35); define_integer(GDK_KEY_R15); define_integer(GDK_KEY_Shift_L); define_integer(GDK_KEY_Shift_R); define_integer(GDK_KEY_Control_L); define_integer(GDK_KEY_Control_R); define_integer(GDK_KEY_Caps_Lock); define_integer(GDK_KEY_Shift_Lock); define_integer(GDK_KEY_Meta_L); define_integer(GDK_KEY_Meta_R); define_integer(GDK_KEY_Alt_L); define_integer(GDK_KEY_Alt_R); define_integer(GDK_KEY_space); define_integer(GDK_KEY_exclam); define_integer(GDK_KEY_quotedbl); define_integer(GDK_KEY_numbersign); define_integer(GDK_KEY_dollar); define_integer(GDK_KEY_percent); define_integer(GDK_KEY_ampersand); define_integer(GDK_KEY_apostrophe); define_integer(GDK_KEY_quoteright); define_integer(GDK_KEY_parenleft); define_integer(GDK_KEY_parenright); define_integer(GDK_KEY_asterisk); define_integer(GDK_KEY_plus); define_integer(GDK_KEY_comma); define_integer(GDK_KEY_minus); define_integer(GDK_KEY_period); define_integer(GDK_KEY_slash); define_integer(GDK_KEY_0); define_integer(GDK_KEY_1); define_integer(GDK_KEY_2); define_integer(GDK_KEY_3); define_integer(GDK_KEY_4); define_integer(GDK_KEY_5); define_integer(GDK_KEY_6); define_integer(GDK_KEY_7); define_integer(GDK_KEY_8); define_integer(GDK_KEY_9); define_integer(GDK_KEY_colon); define_integer(GDK_KEY_semicolon); define_integer(GDK_KEY_less); define_integer(GDK_KEY_equal); define_integer(GDK_KEY_greater); define_integer(GDK_KEY_question); define_integer(GDK_KEY_at); define_integer(GDK_KEY_A); define_integer(GDK_KEY_B); define_integer(GDK_KEY_C); define_integer(GDK_KEY_D); define_integer(GDK_KEY_E); define_integer(GDK_KEY_F); define_integer(GDK_KEY_G); define_integer(GDK_KEY_H); define_integer(GDK_KEY_I); define_integer(GDK_KEY_J); define_integer(GDK_KEY_K); define_integer(GDK_KEY_L); define_integer(GDK_KEY_M); define_integer(GDK_KEY_N); define_integer(GDK_KEY_O); define_integer(GDK_KEY_P); define_integer(GDK_KEY_Q); define_integer(GDK_KEY_R); define_integer(GDK_KEY_S); define_integer(GDK_KEY_T); define_integer(GDK_KEY_U); define_integer(GDK_KEY_V); define_integer(GDK_KEY_W); define_integer(GDK_KEY_X); define_integer(GDK_KEY_Y); define_integer(GDK_KEY_Z); define_integer(GDK_KEY_bracketleft); define_integer(GDK_KEY_backslash); define_integer(GDK_KEY_bracketright); define_integer(GDK_KEY_asciicircum); define_integer(GDK_KEY_underscore); define_integer(GDK_KEY_grave); define_integer(GDK_KEY_quoteleft); define_integer(GDK_KEY_a); define_integer(GDK_KEY_b); define_integer(GDK_KEY_c); define_integer(GDK_KEY_d); define_integer(GDK_KEY_e); define_integer(GDK_KEY_f); define_integer(GDK_KEY_g); define_integer(GDK_KEY_h); define_integer(GDK_KEY_i); define_integer(GDK_KEY_j); define_integer(GDK_KEY_k); define_integer(GDK_KEY_l); define_integer(GDK_KEY_m); define_integer(GDK_KEY_n); define_integer(GDK_KEY_o); define_integer(GDK_KEY_p); define_integer(GDK_KEY_q); define_integer(GDK_KEY_r); define_integer(GDK_KEY_s); define_integer(GDK_KEY_t); define_integer(GDK_KEY_u); define_integer(GDK_KEY_v); define_integer(GDK_KEY_w); define_integer(GDK_KEY_x); define_integer(GDK_KEY_y); define_integer(GDK_KEY_z); define_integer(GDK_KEY_braceleft); define_integer(GDK_KEY_bar); define_integer(GDK_KEY_braceright); define_integer(GDK_KEY_asciitilde); define_integer(GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH); define_integer(GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT); define_integer(GTK_ASSISTANT_PAGE_CUSTOM); define_integer(GTK_TEXT_SEARCH_CASE_INSENSITIVE); define_integer(GTK_SCROLL_MINIMUM); define_integer(GTK_SCROLL_NATURAL); define_integer(GTK_TARGET_SAME_APP); define_integer(GTK_TARGET_SAME_WIDGET); define_integer(GTK_TARGET_OTHER_APP); define_integer(GTK_TARGET_OTHER_WIDGET); define_integer(GTK_ALIGN_FILL); define_integer(GTK_ALIGN_START); define_integer(GTK_ALIGN_END); define_integer(GTK_ALIGN_CENTER); define_integer(GTK_TOOL_PALETTE_DRAG_ITEMS); define_integer(GTK_TOOL_PALETTE_DRAG_GROUPS); define_integer(GTK_IMAGE_GICON); define_integer(GTK_FILE_CHOOSER_ERROR); define_integer(GTK_FILE_CHOOSER_ERROR_NONEXISTENT); define_integer(GTK_FILE_CHOOSER_ERROR_BAD_FILENAME); define_integer(GTK_FILE_CHOOSER_ERROR_ALREADY_EXISTS); define_integer(GTK_FILE_CHOOSER_ERROR_INCOMPLETE_HOSTNAME); define_integer(GTK_ICON_LOOKUP_FORCE_SIZE); define_integer(GTK_ICON_THEME_NOT_FOUND); define_integer(GTK_ICON_THEME_FAILED); define_integer(GTK_STATE_FLAG_NORMAL); define_integer(GTK_STATE_FLAG_ACTIVE); define_integer(GTK_STATE_FLAG_PRELIGHT); define_integer(GTK_STATE_FLAG_SELECTED); define_integer(GTK_STATE_FLAG_INSENSITIVE); define_integer(GTK_STATE_FLAG_INCONSISTENT); define_integer(GTK_STATE_FLAG_FOCUSED); #endif #if GTK_CHECK_VERSION(3, 2, 0) define_integer(GTK_SIZE_REQUEST_CONSTANT_SIZE); #endif #if GTK_CHECK_VERSION(3, 4, 0) define_integer(GDK_MODIFIER_INTENT_PRIMARY_ACCELERATOR); define_integer(GDK_MODIFIER_INTENT_CONTEXT_MENU); define_integer(GDK_MODIFIER_INTENT_EXTEND_SELECTION); define_integer(GDK_MODIFIER_INTENT_MODIFY_SELECTION); define_integer(GDK_MODIFIER_INTENT_NO_TEXT_INPUT); define_integer(GDK_MODIFIER_INTENT_SHIFT_GROUP); define_integer(GTK_REGION_ONLY); define_integer(GDK_WINDOW_STATE_FOCUSED); define_integer(GTK_CELL_RENDERER_EXPANDABLE); define_integer(GTK_CELL_RENDERER_EXPANDED); define_integer(GTK_STATE_FLAG_BACKDROP); #endif #if GTK_CHECK_VERSION(3, 6, 0) define_integer(GDK_TOUCH_BEGIN); define_integer(GDK_TOUCH_UPDATE); define_integer(GDK_TOUCH_END); define_integer(GDK_TOUCH_CANCEL); define_integer(GDK_SCROLL_SMOOTH); define_integer(GDK_CROSSING_TOUCH_BEGIN); define_integer(GDK_CROSSING_TOUCH_END); define_integer(GDK_CROSSING_DEVICE_SWITCH); define_integer(GDK_TOUCH_MASK); define_integer(GDK_SMOOTH_SCROLL_MASK); define_integer(GTK_LEVEL_BAR_MODE_CONTINUOUS); define_integer(GTK_LEVEL_BAR_MODE_DISCRETE); define_integer(GTK_INPUT_PURPOSE_FREE_FORM); define_integer(GTK_INPUT_PURPOSE_ALPHA); define_integer(GTK_INPUT_PURPOSE_DIGITS); define_integer(GTK_INPUT_PURPOSE_NUMBER); define_integer(GTK_INPUT_PURPOSE_PHONE); define_integer(GTK_INPUT_PURPOSE_URL); define_integer(GTK_INPUT_PURPOSE_EMAIL); define_integer(GTK_INPUT_PURPOSE_NAME); define_integer(GTK_INPUT_PURPOSE_PASSWORD); define_integer(GTK_INPUT_PURPOSE_PIN); define_integer(GTK_INPUT_HINT_NONE); define_integer(GTK_INPUT_HINT_SPELLCHECK); define_integer(GTK_INPUT_HINT_NO_SPELLCHECK); define_integer(GTK_INPUT_HINT_WORD_COMPLETION); define_integer(GTK_INPUT_HINT_LOWERCASE); define_integer(GTK_INPUT_HINT_UPPERCASE_CHARS); define_integer(GTK_INPUT_HINT_UPPERCASE_WORDS); define_integer(GTK_INPUT_HINT_UPPERCASE_SENTENCES); define_integer(GTK_INPUT_HINT_INHIBIT_OSK); #endif #if GTK_CHECK_VERSION(3, 8, 0) define_integer(GTK_STATE_FLAG_DIR_LTR); define_integer(GTK_STATE_FLAG_DIR_RTL); define_integer(GDK_FULLSCREEN_ON_CURRENT_MONITOR); define_integer(GDK_FULLSCREEN_ON_ALL_MONITORS); #endif #if GTK_CHECK_VERSION(3, 10, 0) define_integer(GTK_ALIGN_BASELINE); define_integer(GTK_BASELINE_POSITION_TOP); define_integer(GTK_BASELINE_POSITION_CENTER); define_integer(GTK_BASELINE_POSITION_BOTTOM); define_integer(GTK_PLACES_OPEN_NORMAL); define_integer(GTK_PLACES_OPEN_NEW_TAB); define_integer(GTK_PLACES_OPEN_NEW_WINDOW); define_integer(GTK_STACK_TRANSITION_TYPE_NONE); define_integer(GTK_STACK_TRANSITION_TYPE_CROSSFADE); define_integer(GTK_STACK_TRANSITION_TYPE_SLIDE_RIGHT); define_integer(GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT); define_integer(GTK_STACK_TRANSITION_TYPE_SLIDE_UP); define_integer(GTK_STACK_TRANSITION_TYPE_SLIDE_DOWN); define_integer(GTK_REVEALER_TRANSITION_TYPE_NONE); define_integer(GTK_REVEALER_TRANSITION_TYPE_CROSSFADE); define_integer(GTK_REVEALER_TRANSITION_TYPE_SLIDE_RIGHT); define_integer(GTK_REVEALER_TRANSITION_TYPE_SLIDE_LEFT); define_integer(GTK_REVEALER_TRANSITION_TYPE_SLIDE_UP); define_integer(GTK_REVEALER_TRANSITION_TYPE_SLIDE_DOWN); define_integer(GDK_WINDOW_STATE_TILED); #endif #if GTK_CHECK_VERSION(3, 12, 0) define_integer(GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT_RIGHT); define_integer(GTK_STACK_TRANSITION_TYPE_SLIDE_UP_DOWN); define_integer(GTK_STACK_TRANSITION_TYPE_OVER_UP); define_integer(GTK_STACK_TRANSITION_TYPE_OVER_DOWN); define_integer(GTK_STACK_TRANSITION_TYPE_OVER_LEFT); define_integer(GTK_STACK_TRANSITION_TYPE_OVER_RIGHT); define_integer(GTK_STACK_TRANSITION_TYPE_UNDER_UP); define_integer(GTK_STACK_TRANSITION_TYPE_UNDER_DOWN); define_integer(GTK_STACK_TRANSITION_TYPE_UNDER_LEFT); define_integer(GTK_STACK_TRANSITION_TYPE_UNDER_RIGHT); define_integer(GTK_STACK_TRANSITION_TYPE_OVER_UP_DOWN); #endif #if GTK_CHECK_VERSION(3, 14, 0) define_integer(GTK_TEXT_VIEW_LAYER_BELOW); define_integer(GTK_TEXT_VIEW_LAYER_ABOVE); #endif #if GTK_CHECK_VERSION(3, 16, 0) define_integer(GTK_POLICY_EXTERNAL); define_integer(PANGO_WEIGHT_SEMILIGHT); define_integer(GTK_TEXT_EXTEND_SELECTION_WORD); define_integer(GTK_TEXT_EXTEND_SELECTION_LINE); #endif #if GTK_CHECK_VERSION(3, 18, 0) define_integer(GDK_TOUCHPAD_SWIPE); define_integer(GDK_TOUCHPAD_PINCH); define_integer(GDK_TOUCHPAD_GESTURE_PHASE_BEGIN); define_integer(GDK_TOUCHPAD_GESTURE_PHASE_UPDATE); define_integer(GDK_TOUCHPAD_GESTURE_PHASE_END); define_integer(GDK_TOUCHPAD_GESTURE_PHASE_CANCEL); define_integer(GDK_TOUCHPAD_GESTURE_MASK); define_integer(GDK_MODIFIER_INTENT_DEFAULT_MOD_MASK); #endif #if GTK_CHECK_VERSION(3, 20, 0) define_integer(GTK_SHORTCUT_ACCELERATOR); define_integer(GTK_SHORTCUT_GESTURE_PINCH); define_integer(GTK_SHORTCUT_GESTURE_STRETCH); define_integer(GTK_SHORTCUT_GESTURE_ROTATE_CLOCKWISE); define_integer(GTK_SHORTCUT_GESTURE_ROTATE_COUNTERCLOCKWISE); define_integer(GTK_SHORTCUT_GESTURE_TWO_FINGER_SWIPE_LEFT); define_integer(GTK_SHORTCUT_GESTURE_TWO_FINGER_SWIPE_RIGHT); define_integer(GTK_SHORTCUT_GESTURE); #endif define_integer(CAIRO_STATUS_SUCCESS); define_integer(CAIRO_STATUS_NO_MEMORY); define_integer(CAIRO_STATUS_INVALID_RESTORE); define_integer(CAIRO_STATUS_INVALID_POP_GROUP); define_integer(CAIRO_STATUS_NO_CURRENT_POINT); define_integer(CAIRO_STATUS_INVALID_MATRIX); define_integer(CAIRO_STATUS_INVALID_STATUS); define_integer(CAIRO_STATUS_NULL_POINTER); define_integer(CAIRO_STATUS_INVALID_STRING); define_integer(CAIRO_STATUS_INVALID_PATH_DATA); define_integer(CAIRO_STATUS_READ_ERROR); define_integer(CAIRO_STATUS_WRITE_ERROR); define_integer(CAIRO_STATUS_SURFACE_FINISHED); define_integer(CAIRO_STATUS_SURFACE_TYPE_MISMATCH); define_integer(CAIRO_STATUS_PATTERN_TYPE_MISMATCH); define_integer(CAIRO_STATUS_INVALID_CONTENT); define_integer(CAIRO_STATUS_INVALID_FORMAT); define_integer(CAIRO_STATUS_INVALID_VISUAL); define_integer(CAIRO_STATUS_FILE_NOT_FOUND); define_integer(CAIRO_STATUS_INVALID_DASH); define_integer(CAIRO_STATUS_INVALID_DSC_COMMENT); define_integer(CAIRO_STATUS_INVALID_INDEX); define_integer(CAIRO_STATUS_CLIP_NOT_REPRESENTABLE); define_integer(CAIRO_STATUS_TEMP_FILE_ERROR); define_integer(CAIRO_STATUS_INVALID_STRIDE); define_integer(CAIRO_CONTENT_COLOR); define_integer(CAIRO_CONTENT_ALPHA); define_integer(CAIRO_CONTENT_COLOR_ALPHA); define_integer(CAIRO_OPERATOR_CLEAR); define_integer(CAIRO_OPERATOR_SOURCE); define_integer(CAIRO_OPERATOR_OVER); define_integer(CAIRO_OPERATOR_IN); define_integer(CAIRO_OPERATOR_OUT); define_integer(CAIRO_OPERATOR_ATOP); define_integer(CAIRO_OPERATOR_DEST); define_integer(CAIRO_OPERATOR_DEST_OVER); define_integer(CAIRO_OPERATOR_DEST_IN); define_integer(CAIRO_OPERATOR_DEST_OUT); define_integer(CAIRO_OPERATOR_DEST_ATOP); define_integer(CAIRO_OPERATOR_XOR); define_integer(CAIRO_OPERATOR_ADD); define_integer(CAIRO_OPERATOR_SATURATE); define_integer(CAIRO_ANTIALIAS_DEFAULT); define_integer(CAIRO_ANTIALIAS_NONE); define_integer(CAIRO_ANTIALIAS_GRAY); define_integer(CAIRO_ANTIALIAS_SUBPIXEL); define_integer(CAIRO_FILL_RULE_WINDING); define_integer(CAIRO_FILL_RULE_EVEN_ODD); define_integer(CAIRO_LINE_CAP_BUTT); define_integer(CAIRO_LINE_CAP_ROUND); define_integer(CAIRO_LINE_CAP_SQUARE); define_integer(CAIRO_LINE_JOIN_MITER); define_integer(CAIRO_LINE_JOIN_ROUND); define_integer(CAIRO_LINE_JOIN_BEVEL); define_integer(CAIRO_FONT_SLANT_NORMAL); define_integer(CAIRO_FONT_SLANT_ITALIC); define_integer(CAIRO_FONT_SLANT_OBLIQUE); define_integer(CAIRO_FONT_WEIGHT_NORMAL); define_integer(CAIRO_FONT_WEIGHT_BOLD); define_integer(CAIRO_SUBPIXEL_ORDER_DEFAULT); define_integer(CAIRO_SUBPIXEL_ORDER_RGB); define_integer(CAIRO_SUBPIXEL_ORDER_BGR); define_integer(CAIRO_SUBPIXEL_ORDER_VRGB); define_integer(CAIRO_SUBPIXEL_ORDER_VBGR); define_integer(CAIRO_HINT_STYLE_DEFAULT); define_integer(CAIRO_HINT_STYLE_NONE); define_integer(CAIRO_HINT_STYLE_SLIGHT); define_integer(CAIRO_HINT_STYLE_MEDIUM); define_integer(CAIRO_HINT_STYLE_FULL); define_integer(CAIRO_HINT_METRICS_DEFAULT); define_integer(CAIRO_HINT_METRICS_OFF); define_integer(CAIRO_HINT_METRICS_ON); define_integer(CAIRO_FONT_TYPE_TOY); define_integer(CAIRO_FONT_TYPE_FT); define_integer(CAIRO_FONT_TYPE_WIN32); define_integer(CAIRO_FONT_TYPE_QUARTZ); define_integer(CAIRO_PATH_MOVE_TO); define_integer(CAIRO_PATH_LINE_TO); define_integer(CAIRO_PATH_CURVE_TO); define_integer(CAIRO_PATH_CLOSE_PATH); define_integer(CAIRO_SURFACE_TYPE_IMAGE); define_integer(CAIRO_SURFACE_TYPE_PDF); define_integer(CAIRO_SURFACE_TYPE_PS); define_integer(CAIRO_SURFACE_TYPE_XLIB); define_integer(CAIRO_SURFACE_TYPE_XCB); define_integer(CAIRO_SURFACE_TYPE_GLITZ); define_integer(CAIRO_SURFACE_TYPE_QUARTZ); define_integer(CAIRO_SURFACE_TYPE_WIN32); define_integer(CAIRO_SURFACE_TYPE_BEOS); define_integer(CAIRO_SURFACE_TYPE_DIRECTFB); define_integer(CAIRO_SURFACE_TYPE_SVG); define_integer(CAIRO_SURFACE_TYPE_OS2); define_integer(CAIRO_SURFACE_TYPE_WIN32_PRINTING); define_integer(CAIRO_SURFACE_TYPE_QUARTZ_IMAGE); define_integer(CAIRO_FORMAT_ARGB32); define_integer(CAIRO_FORMAT_RGB24); define_integer(CAIRO_FORMAT_A8); define_integer(CAIRO_FORMAT_A1); define_integer(CAIRO_PATTERN_TYPE_SOLID); define_integer(CAIRO_PATTERN_TYPE_SURFACE); define_integer(CAIRO_PATTERN_TYPE_LINEAR); define_integer(CAIRO_PATTERN_TYPE_RADIAL); define_integer(CAIRO_EXTEND_NONE); define_integer(CAIRO_EXTEND_REPEAT); define_integer(CAIRO_EXTEND_REFLECT); define_integer(CAIRO_EXTEND_PAD); define_integer(CAIRO_FILTER_FAST); define_integer(CAIRO_FILTER_GOOD); define_integer(CAIRO_FILTER_BEST); define_integer(CAIRO_FILTER_NEAREST); define_integer(CAIRO_FILTER_BILINEAR); define_integer(CAIRO_FILTER_GAUSSIAN); #if HAVE_CAIRO_1_8 define_integer(CAIRO_STATUS_FONT_TYPE_MISMATCH); define_integer(CAIRO_STATUS_USER_FONT_IMMUTABLE); define_integer(CAIRO_STATUS_USER_FONT_ERROR); define_integer(CAIRO_STATUS_NEGATIVE_COUNT); define_integer(CAIRO_STATUS_INVALID_CLUSTERS); define_integer(CAIRO_STATUS_INVALID_SLANT); define_integer(CAIRO_STATUS_INVALID_WEIGHT); #endif #if HAVE_CAIRO_1_9_12 && GTK_CHECK_VERSION(3, 0, 0) define_integer(CAIRO_STATUS_INVALID_SIZE); define_integer(CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED); define_integer(CAIRO_STATUS_DEVICE_TYPE_MISMATCH); define_integer(CAIRO_STATUS_DEVICE_ERROR); define_integer(CAIRO_OPERATOR_MULTIPLY); define_integer(CAIRO_OPERATOR_SCREEN); define_integer(CAIRO_OPERATOR_OVERLAY); define_integer(CAIRO_OPERATOR_DARKEN); define_integer(CAIRO_OPERATOR_LIGHTEN); define_integer(CAIRO_OPERATOR_COLOR_DODGE); define_integer(CAIRO_OPERATOR_COLOR_BURN); define_integer(CAIRO_OPERATOR_HARD_LIGHT); define_integer(CAIRO_OPERATOR_SOFT_LIGHT); define_integer(CAIRO_OPERATOR_DIFFERENCE); define_integer(CAIRO_OPERATOR_EXCLUSION); define_integer(CAIRO_OPERATOR_HSL_HUE); define_integer(CAIRO_OPERATOR_HSL_SATURATION); define_integer(CAIRO_OPERATOR_HSL_COLOR); define_integer(CAIRO_OPERATOR_HSL_LUMINOSITY); define_integer(CAIRO_SURFACE_TYPE_SCRIPT); define_integer(CAIRO_SURFACE_TYPE_QT); define_integer(CAIRO_SURFACE_TYPE_RECORDING); define_integer(CAIRO_SURFACE_TYPE_VG); define_integer(CAIRO_SURFACE_TYPE_GL); define_integer(CAIRO_SURFACE_TYPE_DRM); define_integer(CAIRO_SURFACE_TYPE_TEE); define_integer(CAIRO_SURFACE_TYPE_XML); define_integer(CAIRO_SURFACE_TYPE_SKIA); #endif } static void define_doubles(void) { #define define_double(Name) Xen_define(Xg_pre #Name Xg_post, C_double_to_Xen_real(Name)) define_double(PANGO_SCALE_XX_SMALL); define_double(PANGO_SCALE_X_SMALL); define_double(PANGO_SCALE_SMALL); define_double(PANGO_SCALE_MEDIUM); define_double(PANGO_SCALE_LARGE); define_double(PANGO_SCALE_X_LARGE); define_double(PANGO_SCALE_XX_LARGE); } /* -------------------------------- predefined Atoms -------------------------------- */ static void define_atoms(void) { #define define_atom(Name) Xen_define(Xg_pre #Name Xg_post, C_to_Xen_GdkAtom(Name)) define_atom(GDK_SELECTION_PRIMARY); define_atom(GDK_SELECTION_SECONDARY); define_atom(GDK_SELECTION_CLIPBOARD); define_atom(GDK_TARGET_BITMAP); define_atom(GDK_TARGET_DRAWABLE); define_atom(GDK_TARGET_STRING); define_atom(GDK_SELECTION_TYPE_ATOM); define_atom(GDK_SELECTION_TYPE_BITMAP); define_atom(GDK_SELECTION_TYPE_DRAWABLE); define_atom(GDK_SELECTION_TYPE_INTEGER); define_atom(GDK_SELECTION_TYPE_WINDOW); define_atom(GDK_SELECTION_TYPE_STRING); define_atom(GDK_NONE); } /* -------------------------------- symbols -------------------------------- */ static void define_symbols(void) { xg_GtkAllocation_symbol = C_string_to_Xen_symbol("GtkAllocation"); xg_GtkShortcutsWindow__symbol = C_string_to_Xen_symbol("GtkShortcutsWindow_"); xg_GtkStackSidebar__symbol = C_string_to_Xen_symbol("GtkStackSidebar_"); xg_GtkSearchEntry__symbol = C_string_to_Xen_symbol("GtkSearchEntry_"); xg_GtkPopoverMenu__symbol = C_string_to_Xen_symbol("GtkPopoverMenu_"); xg_GtkStyleContext__symbol = C_string_to_Xen_symbol("GtkStyleContext_"); xg_GdkGLContext__symbol = C_string_to_Xen_symbol("GdkGLContext_"); xg_GtkGLArea__symbol = C_string_to_Xen_symbol("GtkGLArea_"); xg_GtkPropagationPhase_symbol = C_string_to_Xen_symbol("GtkPropagationPhase"); xg_GtkEventController__symbol = C_string_to_Xen_symbol("GtkEventController_"); xg_GtkGestureZoom__symbol = C_string_to_Xen_symbol("GtkGestureZoom_"); xg_GtkGestureSwipe__symbol = C_string_to_Xen_symbol("GtkGestureSwipe_"); xg_GtkGestureSingle__symbol = C_string_to_Xen_symbol("GtkGestureSingle_"); xg_GtkGestureRotate__symbol = C_string_to_Xen_symbol("GtkGestureRotate_"); xg_GtkGestureMultiPress__symbol = C_string_to_Xen_symbol("GtkGestureMultiPress_"); xg_GtkGesturePan__symbol = C_string_to_Xen_symbol("GtkGesturePan_"); xg_GtkGestureDrag__symbol = C_string_to_Xen_symbol("GtkGestureDrag_"); xg_GdkEventSequence__symbol = C_string_to_Xen_symbol("GdkEventSequence_"); xg_GtkEventSequenceState_symbol = C_string_to_Xen_symbol("GtkEventSequenceState"); xg_GtkGesture__symbol = C_string_to_Xen_symbol("GtkGesture_"); xg_GtkPopover__symbol = C_string_to_Xen_symbol("GtkPopover_"); xg_GtkActionBar__symbol = C_string_to_Xen_symbol("GtkActionBar_"); xg_GtkFlowBox__symbol = C_string_to_Xen_symbol("GtkFlowBox_"); xg_GtkFlowBoxChild__symbol = C_string_to_Xen_symbol("GtkFlowBoxChild_"); xg_GdkEventType_symbol = C_string_to_Xen_symbol("GdkEventType"); xg_GtkSearchBar__symbol = C_string_to_Xen_symbol("GtkSearchBar_"); xg_GtkListBox__symbol = C_string_to_Xen_symbol("GtkListBox_"); xg_GtkListBoxRow__symbol = C_string_to_Xen_symbol("GtkListBoxRow_"); xg_GtkHeaderBar__symbol = C_string_to_Xen_symbol("GtkHeaderBar_"); xg_GtkRevealerTransitionType_symbol = C_string_to_Xen_symbol("GtkRevealerTransitionType"); xg_GtkRevealer__symbol = C_string_to_Xen_symbol("GtkRevealer_"); xg_GtkStackTransitionType_symbol = C_string_to_Xen_symbol("GtkStackTransitionType"); xg_GtkStack__symbol = C_string_to_Xen_symbol("GtkStack_"); xg_GtkStackSwitcher__symbol = C_string_to_Xen_symbol("GtkStackSwitcher_"); xg_GtkPlacesSidebar__symbol = C_string_to_Xen_symbol("GtkPlacesSidebar_"); xg_GtkPlacesOpenFlags_symbol = C_string_to_Xen_symbol("GtkPlacesOpenFlags"); xg_GtkBaselinePosition_symbol = C_string_to_Xen_symbol("GtkBaselinePosition"); xg_GdkFullscreenMode_symbol = C_string_to_Xen_symbol("GdkFullscreenMode"); xg_GtkInputHints_symbol = C_string_to_Xen_symbol("GtkInputHints"); xg_GtkInputPurpose_symbol = C_string_to_Xen_symbol("GtkInputPurpose"); xg_GtkLevelBarMode_symbol = C_string_to_Xen_symbol("GtkLevelBarMode"); xg_GtkLevelBar__symbol = C_string_to_Xen_symbol("GtkLevelBar_"); xg_GtkMenuButton__symbol = C_string_to_Xen_symbol("GtkMenuButton_"); xg_GtkColorChooser__symbol = C_string_to_Xen_symbol("GtkColorChooser_"); xg_GtkApplicationWindow__symbol = C_string_to_Xen_symbol("GtkApplicationWindow_"); xg_GtkApplication__symbol = C_string_to_Xen_symbol("GtkApplication_"); xg_GMenuModel__symbol = C_string_to_Xen_symbol("GMenuModel_"); xg_guint___symbol = C_string_to_Xen_symbol("guint__"); xg_GdkModifierIntent_symbol = C_string_to_Xen_symbol("GdkModifierIntent"); xg_GtkFontChooser__symbol = C_string_to_Xen_symbol("GtkFontChooser_"); xg_GdkScrollDirection_symbol = C_string_to_Xen_symbol("GdkScrollDirection"); xg_GtkOverlay__symbol = C_string_to_Xen_symbol("GtkOverlay_"); xg_GtkWidgetPath__symbol = C_string_to_Xen_symbol("GtkWidgetPath_"); xg_GtkStateFlags_symbol = C_string_to_Xen_symbol("GtkStateFlags"); xg_GdkScreen___symbol = C_string_to_Xen_symbol("GdkScreen__"); xg_GtkToolShell__symbol = C_string_to_Xen_symbol("GtkToolShell_"); xg_GtkWindowGroup__symbol = C_string_to_Xen_symbol("GtkWindowGroup_"); xg_GtkInvisible__symbol = C_string_to_Xen_symbol("GtkInvisible_"); xg_GtkOrientable__symbol = C_string_to_Xen_symbol("GtkOrientable_"); xg_GtkCellArea__symbol = C_string_to_Xen_symbol("GtkCellArea_"); xg_GtkBorder__symbol = C_string_to_Xen_symbol("GtkBorder_"); xg_GtkSwitch__symbol = C_string_to_Xen_symbol("GtkSwitch_"); xg_GtkScrollablePolicy_symbol = C_string_to_Xen_symbol("GtkScrollablePolicy"); xg_GtkScrollable__symbol = C_string_to_Xen_symbol("GtkScrollable_"); xg_GtkGrid__symbol = C_string_to_Xen_symbol("GtkGrid_"); xg_GdkRGBA__symbol = C_string_to_Xen_symbol("GdkRGBA_"); xg_GtkComboBoxText__symbol = C_string_to_Xen_symbol("GtkComboBoxText_"); xg_GtkAlign_symbol = C_string_to_Xen_symbol("GtkAlign"); xg_GtkContainerClass__symbol = C_string_to_Xen_symbol("GtkContainerClass_"); xg_GtkSizeRequestMode_symbol = C_string_to_Xen_symbol("GtkSizeRequestMode"); xg_cairo_region_overlap_t_symbol = C_string_to_Xen_symbol("cairo_region_overlap_t"); xg_cairo_rectangle_int_t__symbol = C_string_to_Xen_symbol("cairo_rectangle_int_t_"); xg_double__symbol = C_string_to_Xen_symbol("double_"); xg_cairo_rectangle_t__symbol = C_string_to_Xen_symbol("cairo_rectangle_t_"); xg_cairo_device_t__symbol = C_string_to_Xen_symbol("cairo_device_t_"); xg_cairo_bool_t_symbol = C_string_to_Xen_symbol("cairo_bool_t"); xg_cairo_text_cluster_flags_t__symbol = C_string_to_Xen_symbol("cairo_text_cluster_flags_t_"); xg_cairo_text_cluster_t___symbol = C_string_to_Xen_symbol("cairo_text_cluster_t__"); xg_cairo_glyph_t___symbol = C_string_to_Xen_symbol("cairo_glyph_t__"); xg_cairo_text_cluster_flags_t_symbol = C_string_to_Xen_symbol("cairo_text_cluster_flags_t"); xg_cairo_text_cluster_t__symbol = C_string_to_Xen_symbol("cairo_text_cluster_t_"); xg_cairo_region_t__symbol = C_string_to_Xen_symbol("cairo_region_t_"); xg_GtkMessageDialog__symbol = C_string_to_Xen_symbol("GtkMessageDialog_"); xg_GdkDevice__symbol = C_string_to_Xen_symbol("GdkDevice_"); xg_GdkDeviceManager__symbol = C_string_to_Xen_symbol("GdkDeviceManager_"); xg_GtkAccessible__symbol = C_string_to_Xen_symbol("GtkAccessible_"); xg_GdkModifierType__symbol = C_string_to_Xen_symbol("GdkModifierType_"); xg_GtkToolPaletteDragTargets_symbol = C_string_to_Xen_symbol("GtkToolPaletteDragTargets"); xg_GtkToolItemGroup__symbol = C_string_to_Xen_symbol("GtkToolItemGroup_"); xg_GtkToolPalette__symbol = C_string_to_Xen_symbol("GtkToolPalette_"); xg_GtkSpinner__symbol = C_string_to_Xen_symbol("GtkSpinner_"); xg_GtkEntryBuffer__symbol = C_string_to_Xen_symbol("GtkEntryBuffer_"); xg_GtkMessageType_symbol = C_string_to_Xen_symbol("GtkMessageType"); xg_GtkInfoBar__symbol = C_string_to_Xen_symbol("GtkInfoBar_"); xg_GIcon__symbol = C_string_to_Xen_symbol("GIcon_"); xg_GtkEntryIconPosition_symbol = C_string_to_Xen_symbol("GtkEntryIconPosition"); xg_GFile__symbol = C_string_to_Xen_symbol("GFile_"); xg_GtkScaleButton__symbol = C_string_to_Xen_symbol("GtkScaleButton_"); xg_GtkCalendarDetailFunc_symbol = C_string_to_Xen_symbol("GtkCalendarDetailFunc"); xg_GtkTooltip__symbol = C_string_to_Xen_symbol("GtkTooltip_"); xg_cairo_rectangle_list_t__symbol = C_string_to_Xen_symbol("cairo_rectangle_list_t_"); xg_void__symbol = C_string_to_Xen_symbol("void_"); xg_cairo_filter_t_symbol = C_string_to_Xen_symbol("cairo_filter_t"); xg_cairo_extend_t_symbol = C_string_to_Xen_symbol("cairo_extend_t"); xg_cairo_format_t_symbol = C_string_to_Xen_symbol("cairo_format_t"); xg_cairo_path_t__symbol = C_string_to_Xen_symbol("cairo_path_t_"); xg_cairo_destroy_func_t_symbol = C_string_to_Xen_symbol("cairo_destroy_func_t"); xg_cairo_user_data_key_t__symbol = C_string_to_Xen_symbol("cairo_user_data_key_t_"); xg_cairo_text_extents_t__symbol = C_string_to_Xen_symbol("cairo_text_extents_t_"); xg_cairo_font_extents_t__symbol = C_string_to_Xen_symbol("cairo_font_extents_t_"); xg_cairo_font_face_t__symbol = C_string_to_Xen_symbol("cairo_font_face_t_"); xg_cairo_glyph_t__symbol = C_string_to_Xen_symbol("cairo_glyph_t_"); xg_cairo_scaled_font_t__symbol = C_string_to_Xen_symbol("cairo_scaled_font_t_"); xg_cairo_font_weight_t_symbol = C_string_to_Xen_symbol("cairo_font_weight_t"); xg_cairo_font_slant_t_symbol = C_string_to_Xen_symbol("cairo_font_slant_t"); xg_cairo_hint_metrics_t_symbol = C_string_to_Xen_symbol("cairo_hint_metrics_t"); xg_cairo_hint_style_t_symbol = C_string_to_Xen_symbol("cairo_hint_style_t"); xg_cairo_subpixel_order_t_symbol = C_string_to_Xen_symbol("cairo_subpixel_order_t"); xg_cairo_status_t_symbol = C_string_to_Xen_symbol("cairo_status_t"); xg_bool_symbol = C_string_to_Xen_symbol("bool"); xg_cairo_matrix_t__symbol = C_string_to_Xen_symbol("cairo_matrix_t_"); xg_cairo_line_join_t_symbol = C_string_to_Xen_symbol("cairo_line_join_t"); xg_cairo_line_cap_t_symbol = C_string_to_Xen_symbol("cairo_line_cap_t"); xg_cairo_fill_rule_t_symbol = C_string_to_Xen_symbol("cairo_fill_rule_t"); xg_cairo_antialias_t_symbol = C_string_to_Xen_symbol("cairo_antialias_t"); xg_cairo_operator_t_symbol = C_string_to_Xen_symbol("cairo_operator_t"); xg_cairo_pattern_t__symbol = C_string_to_Xen_symbol("cairo_pattern_t_"); xg_cairo_content_t_symbol = C_string_to_Xen_symbol("cairo_content_t"); xg_GtkPageSet_symbol = C_string_to_Xen_symbol("GtkPageSet"); xg_GtkPageRange__symbol = C_string_to_Xen_symbol("GtkPageRange_"); xg_GtkPrintPages_symbol = C_string_to_Xen_symbol("GtkPrintPages"); xg_GtkPrintQuality_symbol = C_string_to_Xen_symbol("GtkPrintQuality"); xg_GtkPrintDuplex_symbol = C_string_to_Xen_symbol("GtkPrintDuplex"); xg_GtkPaperSize__symbol = C_string_to_Xen_symbol("GtkPaperSize_"); xg_GtkPageOrientation_symbol = C_string_to_Xen_symbol("GtkPageOrientation"); xg_GtkPrintSettingsFunc_symbol = C_string_to_Xen_symbol("GtkPrintSettingsFunc"); xg_GtkPrintOperationPreview__symbol = C_string_to_Xen_symbol("GtkPrintOperationPreview_"); xg_GtkPageSetupDoneFunc_symbol = C_string_to_Xen_symbol("GtkPageSetupDoneFunc"); xg_GtkPrintStatus_symbol = C_string_to_Xen_symbol("GtkPrintStatus"); xg_GtkPrintOperationAction_symbol = C_string_to_Xen_symbol("GtkPrintOperationAction"); xg_GtkPrintOperationResult_symbol = C_string_to_Xen_symbol("GtkPrintOperationResult"); xg_GtkUnit_symbol = C_string_to_Xen_symbol("GtkUnit"); xg_GtkPrintSettings__symbol = C_string_to_Xen_symbol("GtkPrintSettings_"); xg_GtkPrintOperation__symbol = C_string_to_Xen_symbol("GtkPrintOperation_"); xg_GtkPageSetup__symbol = C_string_to_Xen_symbol("GtkPageSetup_"); xg_GtkPrintContext__symbol = C_string_to_Xen_symbol("GtkPrintContext_"); xg_cairo_surface_t__symbol = C_string_to_Xen_symbol("cairo_surface_t_"); xg_GtkTreeViewGridLines_symbol = C_string_to_Xen_symbol("GtkTreeViewGridLines"); xg_GtkRecentData__symbol = C_string_to_Xen_symbol("GtkRecentData_"); xg_GtkTextBufferDeserializeFunc_symbol = C_string_to_Xen_symbol("GtkTextBufferDeserializeFunc"); xg_GtkTextBufferSerializeFunc_symbol = C_string_to_Xen_symbol("GtkTextBufferSerializeFunc"); xg_time_t_symbol = C_string_to_Xen_symbol("time_t"); xg_GtkRecentChooserMenu__symbol = C_string_to_Xen_symbol("GtkRecentChooserMenu_"); xg_GtkRecentManager__symbol = C_string_to_Xen_symbol("GtkRecentManager_"); xg_GtkRecentFilter__symbol = C_string_to_Xen_symbol("GtkRecentFilter_"); xg_GtkRecentSortFunc_symbol = C_string_to_Xen_symbol("GtkRecentSortFunc"); xg_GtkRecentSortType_symbol = C_string_to_Xen_symbol("GtkRecentSortType"); xg_GtkRecentChooser__symbol = C_string_to_Xen_symbol("GtkRecentChooser_"); xg_GtkLinkButton__symbol = C_string_to_Xen_symbol("GtkLinkButton_"); xg_GtkAssistantPageType_symbol = C_string_to_Xen_symbol("GtkAssistantPageType"); xg_GtkAssistantPageFunc_symbol = C_string_to_Xen_symbol("GtkAssistantPageFunc"); xg_GtkAssistant__symbol = C_string_to_Xen_symbol("GtkAssistant_"); xg_GDestroyNotify_symbol = C_string_to_Xen_symbol("GDestroyNotify"); xg_GtkTreeViewSearchPositionFunc_symbol = C_string_to_Xen_symbol("GtkTreeViewSearchPositionFunc"); xg_GtkSensitivityType_symbol = C_string_to_Xen_symbol("GtkSensitivityType"); xg_GtkClipboardRichTextReceivedFunc_symbol = C_string_to_Xen_symbol("GtkClipboardRichTextReceivedFunc"); xg_GtkMenuBar__symbol = C_string_to_Xen_symbol("GtkMenuBar_"); xg_GtkPackDirection_symbol = C_string_to_Xen_symbol("GtkPackDirection"); xg_GtkIconViewDropPosition_symbol = C_string_to_Xen_symbol("GtkIconViewDropPosition"); xg_GValue__symbol = C_string_to_Xen_symbol("GValue_"); xg_GLogFunc_symbol = C_string_to_Xen_symbol("GLogFunc"); xg_PangoMatrix__symbol = C_string_to_Xen_symbol("PangoMatrix_"); xg_PangoRenderPart_symbol = C_string_to_Xen_symbol("PangoRenderPart"); xg_PangoRenderer__symbol = C_string_to_Xen_symbol("PangoRenderer_"); xg_GtkClipboardImageReceivedFunc_symbol = C_string_to_Xen_symbol("GtkClipboardImageReceivedFunc"); xg_GtkMenuToolButton__symbol = C_string_to_Xen_symbol("GtkMenuToolButton_"); xg_GtkFileChooserButton__symbol = C_string_to_Xen_symbol("GtkFileChooserButton_"); xg_PangoScriptIter__symbol = C_string_to_Xen_symbol("PangoScriptIter_"); xg_PangoScript_symbol = C_string_to_Xen_symbol("PangoScript"); xg_PangoAttrFilterFunc_symbol = C_string_to_Xen_symbol("PangoAttrFilterFunc"); xg_PangoEllipsizeMode_symbol = C_string_to_Xen_symbol("PangoEllipsizeMode"); xg_GtkIconViewForeachFunc_symbol = C_string_to_Xen_symbol("GtkIconViewForeachFunc"); xg_GtkAboutDialog__symbol = C_string_to_Xen_symbol("GtkAboutDialog_"); xg_GtkTreeViewRowSeparatorFunc_symbol = C_string_to_Xen_symbol("GtkTreeViewRowSeparatorFunc"); xg_GtkCellView__symbol = C_string_to_Xen_symbol("GtkCellView_"); xg_GtkAccelMap__symbol = C_string_to_Xen_symbol("GtkAccelMap_"); xg_GtkClipboardTargetsReceivedFunc_symbol = C_string_to_Xen_symbol("GtkClipboardTargetsReceivedFunc"); xg_GtkOrientation_symbol = C_string_to_Xen_symbol("GtkOrientation"); xg_GtkToolButton__symbol = C_string_to_Xen_symbol("GtkToolButton_"); xg_GtkIconLookupFlags_symbol = C_string_to_Xen_symbol("GtkIconLookupFlags"); xg_GtkIconInfo__symbol = C_string_to_Xen_symbol("GtkIconInfo_"); xg_GtkIconTheme__symbol = C_string_to_Xen_symbol("GtkIconTheme_"); xg_GtkFileChooser__symbol = C_string_to_Xen_symbol("GtkFileChooser_"); xg_GtkCellLayoutDataFunc_symbol = C_string_to_Xen_symbol("GtkCellLayoutDataFunc"); xg_GtkCellLayout__symbol = C_string_to_Xen_symbol("GtkCellLayout_"); xg_GtkFileFilterFunc_symbol = C_string_to_Xen_symbol("GtkFileFilterFunc"); xg_GtkFileFilterFlags_symbol = C_string_to_Xen_symbol("GtkFileFilterFlags"); xg_GtkFileFilter__symbol = C_string_to_Xen_symbol("GtkFileFilter_"); xg_GSourceFunc_symbol = C_string_to_Xen_symbol("GSourceFunc"); xg_GtkToggleToolButton__symbol = C_string_to_Xen_symbol("GtkToggleToolButton_"); xg_GtkSeparatorToolItem__symbol = C_string_to_Xen_symbol("GtkSeparatorToolItem_"); xg_GtkRadioToolButton__symbol = C_string_to_Xen_symbol("GtkRadioToolButton_"); xg_GtkEntryCompletionMatchFunc_symbol = C_string_to_Xen_symbol("GtkEntryCompletionMatchFunc"); xg_GtkFontButton__symbol = C_string_to_Xen_symbol("GtkFontButton_"); xg_GtkExpander__symbol = C_string_to_Xen_symbol("GtkExpander_"); xg_GtkComboBox__symbol = C_string_to_Xen_symbol("GtkComboBox_"); xg_GtkTreeModelFilter__symbol = C_string_to_Xen_symbol("GtkTreeModelFilter_"); xg_GtkFileChooserAction_symbol = C_string_to_Xen_symbol("GtkFileChooserAction"); xg_GtkToolItem__symbol = C_string_to_Xen_symbol("GtkToolItem_"); xg_GtkEventBox__symbol = C_string_to_Xen_symbol("GtkEventBox_"); xg_GtkCalendarDisplayOptions_symbol = C_string_to_Xen_symbol("GtkCalendarDisplayOptions"); xg_GdkScreen__symbol = C_string_to_Xen_symbol("GdkScreen_"); xg_PangoLayoutRun__symbol = C_string_to_Xen_symbol("PangoLayoutRun_"); xg_PangoLayoutIter__symbol = C_string_to_Xen_symbol("PangoLayoutIter_"); xg_PangoLayoutLine__symbol = C_string_to_Xen_symbol("PangoLayoutLine_"); xg_int__symbol = C_string_to_Xen_symbol("int_"); xg_PangoAlignment_symbol = C_string_to_Xen_symbol("PangoAlignment"); xg_PangoWrapMode_symbol = C_string_to_Xen_symbol("PangoWrapMode"); xg_PangoItem__symbol = C_string_to_Xen_symbol("PangoItem_"); xg_PangoGlyphString__symbol = C_string_to_Xen_symbol("PangoGlyphString_"); xg_PangoFontMap__symbol = C_string_to_Xen_symbol("PangoFontMap_"); xg_PangoGlyph_symbol = C_string_to_Xen_symbol("PangoGlyph"); xg_PangoFontFace__symbol = C_string_to_Xen_symbol("PangoFontFace_"); xg_PangoFontFace___symbol = C_string_to_Xen_symbol("PangoFontFace__"); xg_PangoFontFamily__symbol = C_string_to_Xen_symbol("PangoFontFamily_"); xg_PangoFontMask_symbol = C_string_to_Xen_symbol("PangoFontMask"); xg_PangoFontDescription___symbol = C_string_to_Xen_symbol("PangoFontDescription__"); xg_PangoCoverageLevel_symbol = C_string_to_Xen_symbol("PangoCoverageLevel"); xg_PangoCoverage__symbol = C_string_to_Xen_symbol("PangoCoverage_"); xg_PangoFontMetrics__symbol = C_string_to_Xen_symbol("PangoFontMetrics_"); xg_PangoFontset__symbol = C_string_to_Xen_symbol("PangoFontset_"); xg_PangoFont__symbol = C_string_to_Xen_symbol("PangoFont_"); xg_PangoFontFamily___symbol = C_string_to_Xen_symbol("PangoFontFamily__"); xg_PangoLogAttr__symbol = C_string_to_Xen_symbol("PangoLogAttr_"); xg_PangoAnalysis__symbol = C_string_to_Xen_symbol("PangoAnalysis_"); xg_PangoAttrList___symbol = C_string_to_Xen_symbol("PangoAttrList__"); xg_PangoAttrIterator__symbol = C_string_to_Xen_symbol("PangoAttrIterator_"); xg_PangoRectangle__symbol = C_string_to_Xen_symbol("PangoRectangle_"); xg_PangoUnderline_symbol = C_string_to_Xen_symbol("PangoUnderline"); xg_PangoStretch_symbol = C_string_to_Xen_symbol("PangoStretch"); xg_PangoVariant_symbol = C_string_to_Xen_symbol("PangoVariant"); xg_PangoWeight_symbol = C_string_to_Xen_symbol("PangoWeight"); xg_PangoStyle_symbol = C_string_to_Xen_symbol("PangoStyle"); xg_guint16_symbol = C_string_to_Xen_symbol("guint16"); xg_PangoAttribute__symbol = C_string_to_Xen_symbol("PangoAttribute_"); xg_PangoAttrType_symbol = C_string_to_Xen_symbol("PangoAttrType"); xg_PangoColor__symbol = C_string_to_Xen_symbol("PangoColor_"); xg_GdkGravity_symbol = C_string_to_Xen_symbol("GdkGravity"); xg_GtkWindowPosition_symbol = C_string_to_Xen_symbol("GtkWindowPosition"); xg_GtkWindowType_symbol = C_string_to_Xen_symbol("GtkWindowType"); xg_GtkWindow__symbol = C_string_to_Xen_symbol("GtkWindow_"); xg_GtkTextDirection_symbol = C_string_to_Xen_symbol("GtkTextDirection"); xg_AtkObject__symbol = C_string_to_Xen_symbol("AtkObject_"); xg_GtkDirectionType_symbol = C_string_to_Xen_symbol("GtkDirectionType"); xg_GtkAllocation__symbol = C_string_to_Xen_symbol("GtkAllocation_"); xg_GtkViewport__symbol = C_string_to_Xen_symbol("GtkViewport_"); xg_GtkTreeViewSearchEqualFunc_symbol = C_string_to_Xen_symbol("GtkTreeViewSearchEqualFunc"); xg_GtkTreeViewDropPosition_symbol = C_string_to_Xen_symbol("GtkTreeViewDropPosition"); xg_GtkTreeViewMappingFunc_symbol = C_string_to_Xen_symbol("GtkTreeViewMappingFunc"); xg_GtkTreeViewColumnDropFunc_symbol = C_string_to_Xen_symbol("GtkTreeViewColumnDropFunc"); xg_GtkTreeViewColumnSizing_symbol = C_string_to_Xen_symbol("GtkTreeViewColumnSizing"); xg_GtkTreeCellDataFunc_symbol = C_string_to_Xen_symbol("GtkTreeCellDataFunc"); xg_GtkTreeStore__symbol = C_string_to_Xen_symbol("GtkTreeStore_"); xg_GtkTreeIterCompareFunc_symbol = C_string_to_Xen_symbol("GtkTreeIterCompareFunc"); xg_GtkSortType_symbol = C_string_to_Xen_symbol("GtkSortType"); xg_GtkTreeSortable__symbol = C_string_to_Xen_symbol("GtkTreeSortable_"); xg_GtkTreeSelectionForeachFunc_symbol = C_string_to_Xen_symbol("GtkTreeSelectionForeachFunc"); xg_GtkTreeModel___symbol = C_string_to_Xen_symbol("GtkTreeModel__"); xg_GtkTreeSelectionFunc_symbol = C_string_to_Xen_symbol("GtkTreeSelectionFunc"); xg_GtkSelectionMode_symbol = C_string_to_Xen_symbol("GtkSelectionMode"); xg_GtkTreeModelSort__symbol = C_string_to_Xen_symbol("GtkTreeModelSort_"); xg_GtkTreeModelForeachFunc_symbol = C_string_to_Xen_symbol("GtkTreeModelForeachFunc"); xg_GtkTreeModelFlags_symbol = C_string_to_Xen_symbol("GtkTreeModelFlags"); xg_GtkTreeRowReference__symbol = C_string_to_Xen_symbol("GtkTreeRowReference_"); xg_GtkTreeDragDest__symbol = C_string_to_Xen_symbol("GtkTreeDragDest_"); xg_GtkTreeDragSource__symbol = C_string_to_Xen_symbol("GtkTreeDragSource_"); xg_GtkToolbarStyle_symbol = C_string_to_Xen_symbol("GtkToolbarStyle"); xg_GtkToolbar__symbol = C_string_to_Xen_symbol("GtkToolbar_"); xg_GtkToggleButton__symbol = C_string_to_Xen_symbol("GtkToggleButton_"); xg_PangoTabArray__symbol = C_string_to_Xen_symbol("PangoTabArray_"); xg_GtkWrapMode_symbol = C_string_to_Xen_symbol("GtkWrapMode"); xg_GtkTextWindowType_symbol = C_string_to_Xen_symbol("GtkTextWindowType"); xg_GtkTextView__symbol = C_string_to_Xen_symbol("GtkTextView_"); xg_GtkTextTagTableForeach_symbol = C_string_to_Xen_symbol("GtkTextTagTableForeach"); xg_GtkTextSearchFlags_symbol = C_string_to_Xen_symbol("GtkTextSearchFlags"); xg_GtkTextCharPredicate_symbol = C_string_to_Xen_symbol("GtkTextCharPredicate"); xg_GtkTextAttributes__symbol = C_string_to_Xen_symbol("GtkTextAttributes_"); xg_GtkTextMark__symbol = C_string_to_Xen_symbol("GtkTextMark_"); xg_GtkTextChildAnchor__symbol = C_string_to_Xen_symbol("GtkTextChildAnchor_"); xg_GtkTextIter__symbol = C_string_to_Xen_symbol("GtkTextIter_"); xg_GtkTextTagTable__symbol = C_string_to_Xen_symbol("GtkTextTagTable_"); xg_GtkTextBuffer__symbol = C_string_to_Xen_symbol("GtkTextBuffer_"); xg_GtkStatusbar__symbol = C_string_to_Xen_symbol("GtkStatusbar_"); xg_GtkSpinType_symbol = C_string_to_Xen_symbol("GtkSpinType"); xg_GtkSpinButtonUpdatePolicy_symbol = C_string_to_Xen_symbol("GtkSpinButtonUpdatePolicy"); xg_GtkSpinButton__symbol = C_string_to_Xen_symbol("GtkSpinButton_"); xg_GtkSizeGroupMode_symbol = C_string_to_Xen_symbol("GtkSizeGroupMode"); xg_GtkSizeGroup__symbol = C_string_to_Xen_symbol("GtkSizeGroup_"); xg_GtkSettings__symbol = C_string_to_Xen_symbol("GtkSettings_"); xg_GtkCornerType_symbol = C_string_to_Xen_symbol("GtkCornerType"); xg_GtkPolicyType_symbol = C_string_to_Xen_symbol("GtkPolicyType"); xg_GtkScrolledWindow__symbol = C_string_to_Xen_symbol("GtkScrolledWindow_"); xg_GtkScale__symbol = C_string_to_Xen_symbol("GtkScale_"); xg_GtkRange__symbol = C_string_to_Xen_symbol("GtkRange_"); xg_GtkRadioMenuItem__symbol = C_string_to_Xen_symbol("GtkRadioMenuItem_"); xg_GtkRadioButton__symbol = C_string_to_Xen_symbol("GtkRadioButton_"); xg_GtkProgressBar__symbol = C_string_to_Xen_symbol("GtkProgressBar_"); xg_GtkPaned__symbol = C_string_to_Xen_symbol("GtkPaned_"); xg_GtkPositionType_symbol = C_string_to_Xen_symbol("GtkPositionType"); xg_GtkNotebook__symbol = C_string_to_Xen_symbol("GtkNotebook_"); xg_GtkMenuShell__symbol = C_string_to_Xen_symbol("GtkMenuShell_"); xg_GtkMenuItem__symbol = C_string_to_Xen_symbol("GtkMenuItem_"); xg_GtkMenuPositionFunc_symbol = C_string_to_Xen_symbol("GtkMenuPositionFunc"); xg_PangoLanguage__symbol = C_string_to_Xen_symbol("PangoLanguage_"); xg_GtkListStore__symbol = C_string_to_Xen_symbol("GtkListStore_"); xg_GtkLayout__symbol = C_string_to_Xen_symbol("GtkLayout_"); xg_GtkJustification_symbol = C_string_to_Xen_symbol("GtkJustification"); xg_GtkLabel__symbol = C_string_to_Xen_symbol("GtkLabel_"); xg_guint16__symbol = C_string_to_Xen_symbol("guint16_"); xg_GtkIMContextSimple__symbol = C_string_to_Xen_symbol("GtkIMContextSimple_"); xg_GdkEventKey__symbol = C_string_to_Xen_symbol("GdkEventKey_"); xg_PangoAttrList__symbol = C_string_to_Xen_symbol("PangoAttrList_"); xg_GtkIMContext__symbol = C_string_to_Xen_symbol("GtkIMContext_"); xg_GtkImageType_symbol = C_string_to_Xen_symbol("GtkImageType"); xg_GtkImage__symbol = C_string_to_Xen_symbol("GtkImage_"); xg_GtkShadowType_symbol = C_string_to_Xen_symbol("GtkShadowType"); xg_GtkFrame__symbol = C_string_to_Xen_symbol("GtkFrame_"); xg_GtkFixed__symbol = C_string_to_Xen_symbol("GtkFixed_"); xg_PangoLayout__symbol = C_string_to_Xen_symbol("PangoLayout_"); xg_GtkEntry__symbol = C_string_to_Xen_symbol("GtkEntry_"); xg_GtkEditable__symbol = C_string_to_Xen_symbol("GtkEditable_"); xg_GtkTargetList__symbol = C_string_to_Xen_symbol("GtkTargetList_"); xg_GtkDestDefaults_symbol = C_string_to_Xen_symbol("GtkDestDefaults"); xg_etc_symbol = C_string_to_Xen_symbol("etc"); xg_GtkDialog__symbol = C_string_to_Xen_symbol("GtkDialog_"); xg_GtkCallback_symbol = C_string_to_Xen_symbol("GtkCallback"); xg_GtkContainer__symbol = C_string_to_Xen_symbol("GtkContainer_"); xg_GtkClipboardTextReceivedFunc_symbol = C_string_to_Xen_symbol("GtkClipboardTextReceivedFunc"); xg_GtkClipboardReceivedFunc_symbol = C_string_to_Xen_symbol("GtkClipboardReceivedFunc"); xg_GtkClipboardClearFunc_symbol = C_string_to_Xen_symbol("GtkClipboardClearFunc"); xg_GtkClipboardGetFunc_symbol = C_string_to_Xen_symbol("GtkClipboardGetFunc"); xg_GtkTargetEntry__symbol = C_string_to_Xen_symbol("GtkTargetEntry_"); xg_GtkCheckMenuItem__symbol = C_string_to_Xen_symbol("GtkCheckMenuItem_"); xg_GtkCellRendererToggle__symbol = C_string_to_Xen_symbol("GtkCellRendererToggle_"); xg_GtkCellRendererText__symbol = C_string_to_Xen_symbol("GtkCellRendererText_"); xg_GtkCellRendererState_symbol = C_string_to_Xen_symbol("GtkCellRendererState"); xg_GtkCellEditable__symbol = C_string_to_Xen_symbol("GtkCellEditable_"); xg_GtkCalendar__symbol = C_string_to_Xen_symbol("GtkCalendar_"); xg_GtkReliefStyle_symbol = C_string_to_Xen_symbol("GtkReliefStyle"); xg_GtkButton__symbol = C_string_to_Xen_symbol("GtkButton_"); xg_GtkPackType_symbol = C_string_to_Xen_symbol("GtkPackType"); xg_GtkBox__symbol = C_string_to_Xen_symbol("GtkBox_"); xg_GtkBin__symbol = C_string_to_Xen_symbol("GtkBin_"); xg_GtkBindingSet__symbol = C_string_to_Xen_symbol("GtkBindingSet_"); xg_GtkButtonBox__symbol = C_string_to_Xen_symbol("GtkButtonBox_"); xg_GtkButtonBoxStyle_symbol = C_string_to_Xen_symbol("GtkButtonBoxStyle"); xg_GtkAspectFrame__symbol = C_string_to_Xen_symbol("GtkAspectFrame_"); xg_GtkAdjustment__symbol = C_string_to_Xen_symbol("GtkAdjustment_"); xg_GtkAccelMapForeach_symbol = C_string_to_Xen_symbol("GtkAccelMapForeach"); xg_GtkAccelLabel__symbol = C_string_to_Xen_symbol("GtkAccelLabel_"); xg_GtkAccelGroupEntry__symbol = C_string_to_Xen_symbol("GtkAccelGroupEntry_"); xg_lambda3_symbol = C_string_to_Xen_symbol("lambda3"); xg_GSList__symbol = C_string_to_Xen_symbol("GSList_"); xg_GObject__symbol = C_string_to_Xen_symbol("GObject_"); xg_GtkAccelFlags_symbol = C_string_to_Xen_symbol("GtkAccelFlags"); xg_GtkAccelGroup__symbol = C_string_to_Xen_symbol("GtkAccelGroup_"); xg_GTimeVal__symbol = C_string_to_Xen_symbol("GTimeVal_"); xg_GdkPixbufAnimationIter__symbol = C_string_to_Xen_symbol("GdkPixbufAnimationIter_"); xg_GdkPixbufAnimation__symbol = C_string_to_Xen_symbol("GdkPixbufAnimation_"); xg_GdkInterpType_symbol = C_string_to_Xen_symbol("GdkInterpType"); xg_double_symbol = C_string_to_Xen_symbol("double"); xg_gfloat_symbol = C_string_to_Xen_symbol("gfloat"); xg_guchar_symbol = C_string_to_Xen_symbol("guchar"); xg_char___symbol = C_string_to_Xen_symbol("char__"); xg_GdkPixbufDestroyNotify_symbol = C_string_to_Xen_symbol("GdkPixbufDestroyNotify"); xg_GError__symbol = C_string_to_Xen_symbol("GError_"); xg_int_symbol = C_string_to_Xen_symbol("int"); xg_GdkColorspace_symbol = C_string_to_Xen_symbol("GdkColorspace"); xg_GdkWindowTypeHint_symbol = C_string_to_Xen_symbol("GdkWindowTypeHint"); xg_GdkWindowHints_symbol = C_string_to_Xen_symbol("GdkWindowHints"); xg_GdkGeometry__symbol = C_string_to_Xen_symbol("GdkGeometry_"); xg_GdkWindowEdge_symbol = C_string_to_Xen_symbol("GdkWindowEdge"); xg_GdkWMFunction_symbol = C_string_to_Xen_symbol("GdkWMFunction"); xg_GdkWMDecoration_symbol = C_string_to_Xen_symbol("GdkWMDecoration"); xg_GdkEventMask_symbol = C_string_to_Xen_symbol("GdkEventMask"); xg_GdkWindowState_symbol = C_string_to_Xen_symbol("GdkWindowState"); xg_GdkFilterFunc_symbol = C_string_to_Xen_symbol("GdkFilterFunc"); xg_GdkWindowType_symbol = C_string_to_Xen_symbol("GdkWindowType"); xg_GdkWindowAttr__symbol = C_string_to_Xen_symbol("GdkWindowAttr_"); xg_GdkVisualType__symbol = C_string_to_Xen_symbol("GdkVisualType_"); xg_gint__symbol = C_string_to_Xen_symbol("gint_"); xg_GdkVisualType_symbol = C_string_to_Xen_symbol("GdkVisualType"); xg_GdkPropMode_symbol = C_string_to_Xen_symbol("GdkPropMode"); xg_guchar__symbol = C_string_to_Xen_symbol("guchar_"); xg_PangoContext__symbol = C_string_to_Xen_symbol("PangoContext_"); xg_PangoDirection_symbol = C_string_to_Xen_symbol("PangoDirection"); xg_GdkKeymapKey__symbol = C_string_to_Xen_symbol("GdkKeymapKey_"); xg_GdkKeymap__symbol = C_string_to_Xen_symbol("GdkKeymap_"); xg_GdkRectangle__symbol = C_string_to_Xen_symbol("GdkRectangle_"); xg_char__symbol = C_string_to_Xen_symbol("char_"); xg_gchar___symbol = C_string_to_Xen_symbol("gchar__"); xg_GdkEventFunc_symbol = C_string_to_Xen_symbol("GdkEventFunc"); xg_gdouble_symbol = C_string_to_Xen_symbol("gdouble"); xg_GList__symbol = C_string_to_Xen_symbol("GList_"); xg_GdkWindow__symbol = C_string_to_Xen_symbol("GdkWindow_"); xg_guint32_symbol = C_string_to_Xen_symbol("guint32"); xg_GdkDragAction_symbol = C_string_to_Xen_symbol("GdkDragAction"); xg_GdkDragContext__symbol = C_string_to_Xen_symbol("GdkDragContext_"); xg_GdkCursorType_symbol = C_string_to_Xen_symbol("GdkCursorType"); xg_GdkDisplay__symbol = C_string_to_Xen_symbol("GdkDisplay_"); xg_GdkCursor__symbol = C_string_to_Xen_symbol("GdkCursor_"); xg_GdkVisual__symbol = C_string_to_Xen_symbol("GdkVisual_"); xg_GSignalMatchType_symbol = C_string_to_Xen_symbol("GSignalMatchType"); xg_GConnectFlags_symbol = C_string_to_Xen_symbol("GConnectFlags"); xg_GtkDestroyNotify_symbol = C_string_to_Xen_symbol("GtkDestroyNotify"); xg_GSignalEmissionHook_symbol = C_string_to_Xen_symbol("GSignalEmissionHook"); xg_gulong_symbol = C_string_to_Xen_symbol("gulong"); xg_GSignalInvocationHint__symbol = C_string_to_Xen_symbol("GSignalInvocationHint_"); xg_GQuark_symbol = C_string_to_Xen_symbol("GQuark"); xg_guint__symbol = C_string_to_Xen_symbol("guint_"); xg_GSignalQuery__symbol = C_string_to_Xen_symbol("GSignalQuery_"); xg_GType__symbol = C_string_to_Xen_symbol("GType_"); xg_GSignalCMarshaller_symbol = C_string_to_Xen_symbol("GSignalCMarshaller"); xg_gpointer_symbol = C_string_to_Xen_symbol("gpointer"); xg_GSignalAccumulator_symbol = C_string_to_Xen_symbol("GSignalAccumulator"); xg_GSignalFlags_symbol = C_string_to_Xen_symbol("GSignalFlags"); xg_GType_symbol = C_string_to_Xen_symbol("GType"); xg_GClosureNotify_symbol = C_string_to_Xen_symbol("GClosureNotify"); xg_GCallback_symbol = C_string_to_Xen_symbol("GCallback"); xg_GNormalizeMode_symbol = C_string_to_Xen_symbol("GNormalizeMode"); xg_glong_symbol = C_string_to_Xen_symbol("glong"); xg_gssize_symbol = C_string_to_Xen_symbol("gssize"); xg_gunichar__symbol = C_string_to_Xen_symbol("gunichar_"); xg_void_symbol = C_string_to_Xen_symbol("void"); xg_GtkRecentInfo__symbol = C_string_to_Xen_symbol("GtkRecentInfo_"); xg_gsize_symbol = C_string_to_Xen_symbol("gsize"); xg_guint8__symbol = C_string_to_Xen_symbol("guint8_"); xg_GdkAtom_symbol = C_string_to_Xen_symbol("GdkAtom"); xg_GLogLevelFlags_symbol = C_string_to_Xen_symbol("GLogLevelFlags"); xg_GdkPixbuf__symbol = C_string_to_Xen_symbol("GdkPixbuf_"); xg_GtkIconView__symbol = C_string_to_Xen_symbol("GtkIconView_"); xg_GtkEntryCompletion__symbol = C_string_to_Xen_symbol("GtkEntryCompletion_"); xg_GtkFileFilterInfo__symbol = C_string_to_Xen_symbol("GtkFileFilterInfo_"); xg_GtkTreeSelection__symbol = C_string_to_Xen_symbol("GtkTreeSelection_"); xg_GtkCellRenderer__symbol = C_string_to_Xen_symbol("GtkCellRenderer_"); xg_GtkTreeViewColumn__symbol = C_string_to_Xen_symbol("GtkTreeViewColumn_"); xg_GtkTreeView__symbol = C_string_to_Xen_symbol("GtkTreeView_"); xg_gunichar_symbol = C_string_to_Xen_symbol("gunichar"); xg_GdkAtom__symbol = C_string_to_Xen_symbol("GdkAtom_"); xg_GtkSelectionData__symbol = C_string_to_Xen_symbol("GtkSelectionData_"); xg_GtkClipboard__symbol = C_string_to_Xen_symbol("GtkClipboard_"); xg_GtkTreeIter__symbol = C_string_to_Xen_symbol("GtkTreeIter_"); xg_GtkTreePath__symbol = C_string_to_Xen_symbol("GtkTreePath_"); xg_GtkTreeModel__symbol = C_string_to_Xen_symbol("GtkTreeModel_"); xg_GdkModifierType_symbol = C_string_to_Xen_symbol("GdkModifierType"); xg_guint_symbol = C_string_to_Xen_symbol("guint"); xg_gchar__symbol = C_string_to_Xen_symbol("gchar_"); xg_GtkTextTag__symbol = C_string_to_Xen_symbol("GtkTextTag_"); xg_gboolean_symbol = C_string_to_Xen_symbol("gboolean"); xg_gint_symbol = C_string_to_Xen_symbol("gint"); xg_GtkMenu__symbol = C_string_to_Xen_symbol("GtkMenu_"); xg_GdkXEvent__symbol = C_string_to_Xen_symbol("GdkXEvent_"); xg_GtkWidget__symbol = C_string_to_Xen_symbol("GtkWidget_"); xg_lambda_data_symbol = C_string_to_Xen_symbol("lambda_data"); xg_GClosure__symbol = C_string_to_Xen_symbol("GClosure_"); xg_GtkAccelKey__symbol = C_string_to_Xen_symbol("GtkAccelKey_"); xg_GdkEventMotion__symbol = C_string_to_Xen_symbol("GdkEventMotion_"); xg_gdouble__symbol = C_string_to_Xen_symbol("gdouble_"); xg_GdkEventAny__symbol = C_string_to_Xen_symbol("GdkEventAny_"); xg_GdkEvent__symbol = C_string_to_Xen_symbol("GdkEvent_"); xg_cairo_t__symbol = C_string_to_Xen_symbol("cairo_t_"); xg_cairo_font_options_t__symbol = C_string_to_Xen_symbol("cairo_font_options_t_"); xg_PangoFontDescription__symbol = C_string_to_Xen_symbol("PangoFontDescription_"); xg_idler_symbol = C_string_to_Xen_symbol("idler"); xg_GtkCellRendererPixbuf__symbol = C_string_to_Xen_symbol("GtkCellRendererPixbuf_"); xg_GtkCheckButton__symbol = C_string_to_Xen_symbol("GtkCheckButton_"); xg_GtkDrawingArea__symbol = C_string_to_Xen_symbol("GtkDrawingArea_"); xg_GtkScrollbar__symbol = C_string_to_Xen_symbol("GtkScrollbar_"); xg_GtkSeparator__symbol = C_string_to_Xen_symbol("GtkSeparator_"); xg_GtkSeparatorMenuItem__symbol = C_string_to_Xen_symbol("GtkSeparatorMenuItem_"); xg_GdkEventExpose__symbol = C_string_to_Xen_symbol("GdkEventExpose_"); xg_GdkEventNoExpose__symbol = C_string_to_Xen_symbol("GdkEventNoExpose_"); xg_GdkEventVisibility__symbol = C_string_to_Xen_symbol("GdkEventVisibility_"); xg_GdkEventButton__symbol = C_string_to_Xen_symbol("GdkEventButton_"); xg_GdkEventScroll__symbol = C_string_to_Xen_symbol("GdkEventScroll_"); xg_GdkEventCrossing__symbol = C_string_to_Xen_symbol("GdkEventCrossing_"); xg_GdkEventFocus__symbol = C_string_to_Xen_symbol("GdkEventFocus_"); xg_GdkEventConfigure__symbol = C_string_to_Xen_symbol("GdkEventConfigure_"); xg_GdkEventProperty__symbol = C_string_to_Xen_symbol("GdkEventProperty_"); xg_GdkEventSelection__symbol = C_string_to_Xen_symbol("GdkEventSelection_"); xg_GdkEventProximity__symbol = C_string_to_Xen_symbol("GdkEventProximity_"); xg_GdkEventSetting__symbol = C_string_to_Xen_symbol("GdkEventSetting_"); xg_GdkEventWindowState__symbol = C_string_to_Xen_symbol("GdkEventWindowState_"); xg_GdkEventDND__symbol = C_string_to_Xen_symbol("GdkEventDND_"); xg_GtkFileChooserDialog__symbol = C_string_to_Xen_symbol("GtkFileChooserDialog_"); xg_GtkFileChooserWidget__symbol = C_string_to_Xen_symbol("GtkFileChooserWidget_"); xg_GtkColorButton__symbol = C_string_to_Xen_symbol("GtkColorButton_"); xg_GtkAccelMap_symbol = C_string_to_Xen_symbol("GtkAccelMap"); xg_GtkCellRendererCombo__symbol = C_string_to_Xen_symbol("GtkCellRendererCombo_"); xg_GtkCellRendererProgress__symbol = C_string_to_Xen_symbol("GtkCellRendererProgress_"); xg_GtkCellRendererAccel__symbol = C_string_to_Xen_symbol("GtkCellRendererAccel_"); xg_GtkCellRendererSpin__symbol = C_string_to_Xen_symbol("GtkCellRendererSpin_"); xg_GtkRecentChooserDialog__symbol = C_string_to_Xen_symbol("GtkRecentChooserDialog_"); xg_GtkRecentChooserWidget__symbol = C_string_to_Xen_symbol("GtkRecentChooserWidget_"); xg_GtkCellRendererSpinner__symbol = C_string_to_Xen_symbol("GtkCellRendererSpinner_"); xg_gboolean__symbol = C_string_to_Xen_symbol("gboolean_"); xg_GtkFontChooserDialog__symbol = C_string_to_Xen_symbol("GtkFontChooserDialog_"); xg_GtkFontChooserWidget__symbol = C_string_to_Xen_symbol("GtkFontChooserWidget_"); xg_GtkColorChooserDialog__symbol = C_string_to_Xen_symbol("GtkColorChooserDialog_"); xg_GtkColorChooserWidget__symbol = C_string_to_Xen_symbol("GtkColorChooserWidget_"); xg_GtkColorWidget__symbol = C_string_to_Xen_symbol("GtkColorWidget_"); xg_GtkGestureLongPress__symbol = C_string_to_Xen_symbol("GtkGestureLongPress_"); } /* -------------------------------- strings -------------------------------- */ static void define_strings(void) { #define define_string(Name) Xen_define(Xg_pre #Name Xg_post, C_string_to_Xen_string(Name)) define_string(GTK_PRINT_SETTINGS_PRINTER); define_string(GTK_PRINT_SETTINGS_ORIENTATION); define_string(GTK_PRINT_SETTINGS_PAPER_FORMAT); define_string(GTK_PRINT_SETTINGS_PAPER_WIDTH); define_string(GTK_PRINT_SETTINGS_PAPER_HEIGHT); define_string(GTK_PRINT_SETTINGS_N_COPIES); define_string(GTK_PRINT_SETTINGS_DEFAULT_SOURCE); define_string(GTK_PRINT_SETTINGS_QUALITY); define_string(GTK_PRINT_SETTINGS_RESOLUTION); define_string(GTK_PRINT_SETTINGS_USE_COLOR); define_string(GTK_PRINT_SETTINGS_DUPLEX); define_string(GTK_PRINT_SETTINGS_COLLATE); define_string(GTK_PRINT_SETTINGS_REVERSE); define_string(GTK_PRINT_SETTINGS_MEDIA_TYPE); define_string(GTK_PRINT_SETTINGS_DITHER); define_string(GTK_PRINT_SETTINGS_SCALE); define_string(GTK_PRINT_SETTINGS_PRINT_PAGES); define_string(GTK_PRINT_SETTINGS_PAGE_RANGES); define_string(GTK_PRINT_SETTINGS_PAGE_SET); define_string(GTK_PRINT_SETTINGS_FINISHINGS); define_string(GTK_PRINT_SETTINGS_NUMBER_UP); define_string(GTK_PRINT_SETTINGS_OUTPUT_BIN); define_string(GTK_PRINT_SETTINGS_OUTPUT_FILE_FORMAT); define_string(GTK_PRINT_SETTINGS_OUTPUT_URI); #if GTK_CHECK_VERSION(3, 0, 0) define_string(GTK_STYLE_CLASS_HIGHLIGHT); define_string(GTK_STYLE_CLASS_FRAME); define_string(GTK_STYLE_CLASS_DND); define_string(GTK_STYLE_CLASS_HORIZONTAL); define_string(GTK_STYLE_CLASS_VERTICAL); #endif #if HAVE_CAIRO_1_9_12 && GTK_CHECK_VERSION(3, 0, 0) define_string(CAIRO_MIME_TYPE_JPEG); define_string(CAIRO_MIME_TYPE_PNG); define_string(CAIRO_MIME_TYPE_JP2); define_string(CAIRO_MIME_TYPE_URI); #endif } /* -------------------------------- initialization -------------------------------- */ static bool xg_already_inited = false; void Init_libxg(void); void Init_libxg(void) { if (!xg_already_inited) { define_symbols(); define_xm_obj(); define_integers(); define_doubles(); define_functions(); define_atoms(); define_strings(); define_structs(); Xen_provide_feature("xg"); #if GTK_CHECK_VERSION(3, 0, 0) Xen_provide_feature("gtk3"); #else Xen_provide_feature("gtk2"); #endif Xen_define("xg-version", C_string_to_Xen_string("26-Nov-15")); xg_already_inited = true; #if HAVE_SCHEME #if USE_SND /* these are macros in glib/gobject/gsignal.h, but we want the types handled in some convenient way in the extension language */ s7_define(s7, s7_nil(s7), s7_make_symbol(s7, "g_signal_connect"), Xen_eval_C_string("(lambda (obj name func . data)\ ((*gtk* 'g_signal_connect_data) ((*gtk* 'GPOINTER) obj) name func (and (pair? data) (car data)) #f 0))")); s7_define(s7, s7_nil(s7), s7_make_symbol(s7, "g_signal_connect_after"), Xen_eval_C_string("(lambda (obj name func . data)\ ((*gtk* 'g_signal_connect_data) ((*gtk* 'GPOINTER) obj) name func (and (pair? data) (car data)) #f (*gtk* 'G_CONNECT_AFTER)))")); s7_define(s7, s7_nil(s7), s7_make_symbol(s7, "g_signal_connect_swapped"), Xen_eval_C_string("(lambda (obj name func . data)\ ((*gtk* 'g_signal_connect_data) ((*gtk* 'GPOINTER) obj) name func (and (pair? data) (car data)) #f (*gtk* 'G_CONNECT_SWAPPED)))")); #else Xen_eval_C_string("(define (g_signal_connect obj name func . data) (g_signal_connect_data (GPOINTER obj) name func (and (pair? data) (car data)) #f 0))"); Xen_eval_C_string("(define (g_signal_connect_after obj name func . data) (g_signal_connect_data (GPOINTER obj) name func (and (pair? data) (car data)) #f G_CONNECT_AFTER))"); Xen_eval_C_string("(define (g_signal_connect_swapped obj name func . data) (g_signal_connect_data (GPOINTER obj) name func (and (pair? data) (car data)) #f G_CONNECT_SWAPPED))"); #endif #endif #if HAVE_RUBY Xen_eval_C_string("def Rg_signal_connect(obj, name, func, data = false); Rg_signal_connect_data(RGPOINTER(obj), name, func, data, false, 0); end"); Xen_eval_C_string("def Rg_signal_connect_after(obj, name, func, data = false); Rg_signal_connect_data(RGPOINTER(obj), name, func, data, false, RG_CONNECT_AFTER); end"); Xen_eval_C_string("def Rg_signal_connect_swapped(obj, name, func, data = false); Rg_signal_connect_data(RGPOINTER(obj), name, func, data, false, RG_CONNECT_SWAPPED); end"); #endif #if HAVE_FORTH Xen_eval_C_string(": Fg_signal_connect <{ obj name func :optional data #f -- n }> obj FGPOINTER name func data #f 0 Fg_signal_connect_data ;"); Xen_eval_C_string(": Fg_signal_connect_after <{ obj name func :optional data #f -- n }> obj FGPOINTER name func data #f FG_CONNECT_AFTER Fg_signal_connect_data ;"); Xen_eval_C_string(": Fg_signal_connect_swapped <{ obj name func :optional data #f -- n }> obj FGPOINTER name func data #f FG_CONNECT_SWAPPED Fg_signal_connect_data ;"); #endif } } #else void Init_libxg(void); void Init_libxg(void) { } #endif snd-16.1/rgb.scm0000644000076400007640000007376212306421671011632 0ustar bilbil;;; X11 color names converted to Snd colors (provide 'snd-rgb.scm) ;; tan -> tawny 24-Aug-01 (define snow (make-color 1.00 0.98 0.98)) (define ghost-white (make-color 0.97 0.97 1.00)) (define white-smoke (make-color 0.96 0.96 0.96)) (define gainsboro (make-color 0.86 0.86 0.86)) (define floral-white (make-color 1.00 0.98 0.94)) (define old-lace (make-color 0.99 0.96 0.90)) (define linen (make-color 0.98 0.94 0.90)) (define antique-white (make-color 0.98 0.92 0.84)) (define papaya-whip (make-color 1.00 0.93 0.83)) (define blanched-almond (make-color 1.00 0.92 0.80)) (define bisque (make-color 1.00 0.89 0.77)) (define peach-puff (make-color 1.00 0.85 0.72)) (define navajo-white (make-color 1.00 0.87 0.68)) (define moccasin (make-color 1.00 0.89 0.71)) (define cornsilk (make-color 1.00 0.97 0.86)) (define ivory (make-color 1.00 1.00 0.94)) (define lemon-chiffon (make-color 1.00 0.98 0.80)) (define seashell (make-color 1.00 0.96 0.93)) (define honeydew (make-color 0.94 1.00 0.94)) (define mint-cream (make-color 0.96 1.00 0.98)) (define azure (make-color 0.94 1.00 1.00)) (define alice-blue (make-color 0.94 0.97 1.00)) (define lavender (make-color 0.90 0.90 0.98)) (define lavender-blush (make-color 1.00 0.94 0.96)) (define misty-rose (make-color 1.00 0.89 0.88)) (define white (make-color 1.00 1.00 1.00)) (define black (make-color 0.00 0.00 0.00)) (define dark-slate-gray (make-color 0.18 0.31 0.31)) (define dark-slate-grey (make-color 0.18 0.31 0.31)) (define dim-gray (make-color 0.41 0.41 0.41)) (define dim-grey (make-color 0.41 0.41 0.41)) (define slate-gray (make-color 0.44 0.50 0.56)) (define slate-grey (make-color 0.44 0.50 0.56)) (define light-slate-gray (make-color 0.46 0.53 0.60)) (define light-slate-grey (make-color 0.46 0.53 0.60)) (define gray (make-color 0.74 0.74 0.74)) (define grey (make-color 0.74 0.74 0.74)) (define light-grey (make-color 0.82 0.82 0.82)) (define light-gray (make-color 0.82 0.82 0.82)) (define midnight-blue (make-color 0.10 0.10 0.44)) (define navy (make-color 0.00 0.00 0.50)) (define navy-blue (make-color 0.00 0.00 0.50)) (define cornflower-blue (make-color 0.39 0.58 0.93)) (define dark-slate-blue (make-color 0.28 0.24 0.54)) (define slate-blue (make-color 0.41 0.35 0.80)) (define medium-slate-blue (make-color 0.48 0.41 0.93)) (define light-slate-blue (make-color 0.52 0.44 1.00)) (define medium-blue (make-color 0.00 0.00 0.80)) (define royal-blue (make-color 0.25 0.41 0.88)) (define blue (make-color 0.00 0.00 1.00)) (define dodger-blue (make-color 0.12 0.56 1.00)) (define deep-sky-blue (make-color 0.00 0.75 1.00)) (define sky-blue (make-color 0.53 0.80 0.92)) (define light-sky-blue (make-color 0.53 0.80 0.98)) (define steel-blue (make-color 0.27 0.51 0.70)) (define light-steel-blue (make-color 0.69 0.77 0.87)) (define light-blue (make-color 0.68 0.84 0.90)) (define powder-blue (make-color 0.69 0.87 0.90)) (define pale-turquoise (make-color 0.68 0.93 0.93)) (define dark-turquoise (make-color 0.00 0.80 0.82)) (define medium-turquoise (make-color 0.28 0.82 0.80)) (define turquoise (make-color 0.25 0.87 0.81)) (define cyan (make-color 0.00 1.00 1.00)) (define light-cyan (make-color 0.87 1.00 1.00)) (define cadet-blue (make-color 0.37 0.62 0.62)) (define medium-aquamarine (make-color 0.40 0.80 0.66)) (define aquamarine (make-color 0.50 1.00 0.83)) (define dark-green (make-color 0.00 0.39 0.00)) (define dark-olive-green (make-color 0.33 0.42 0.18)) (define dark-sea-green (make-color 0.56 0.73 0.56)) (define sea-green (make-color 0.18 0.54 0.34)) (define medium-sea-green (make-color 0.23 0.70 0.44)) (define light-sea-green (make-color 0.12 0.70 0.66)) (define pale-green (make-color 0.59 0.98 0.59)) (define spring-green (make-color 0.00 1.00 0.50)) (define lawn-green (make-color 0.48 0.98 0.00)) (define green (make-color 0.00 1.00 0.00)) (define chartreuse (make-color 0.50 1.00 0.00)) (define medium-spring-green (make-color 0.00 0.98 0.60)) (define green-yellow (make-color 0.68 1.00 0.18)) (define lime-green (make-color 0.20 0.80 0.20)) (define yellow-green (make-color 0.60 0.80 0.20)) (define forest-green (make-color 0.13 0.54 0.13)) (define olive-drab (make-color 0.42 0.55 0.14)) (define dark-khaki (make-color 0.74 0.71 0.42)) (define khaki (make-color 0.94 0.90 0.55)) (define pale-goldenrod (make-color 0.93 0.91 0.66)) (define light-goldenrod-yellow (make-color 0.98 0.98 0.82)) (define light-yellow (make-color 1.00 1.00 0.87)) (define yellow (make-color 1.00 1.00 0.00)) (define gold (make-color 1.00 0.84 0.00)) (define light-goldenrod (make-color 0.93 0.86 0.51)) (define goldenrod (make-color 0.85 0.64 0.12)) (define dark-goldenrod (make-color 0.72 0.52 0.04)) (define rosy-brown (make-color 0.73 0.56 0.56)) (define indian-red (make-color 0.80 0.36 0.36)) (define saddle-brown (make-color 0.54 0.27 0.07)) (define sienna (make-color 0.62 0.32 0.18)) (define peru (make-color 0.80 0.52 0.25)) (define burlywood (make-color 0.87 0.72 0.53)) (define beige (make-color 0.96 0.96 0.86)) (define wheat (make-color 0.96 0.87 0.70)) (define sandy-brown (make-color 0.95 0.64 0.37)) (define tawny (make-color 0.82 0.70 0.55)) ; tan collides with Scheme built-in -- tawny suggested by Dave Phillips (define chocolate (make-color 0.82 0.41 0.12)) (define firebrick (make-color 0.70 0.13 0.13)) (define brown (make-color 0.64 0.16 0.16)) (define dark-salmon (make-color 0.91 0.59 0.48)) (define salmon (make-color 0.98 0.50 0.45)) (define light-salmon (make-color 1.00 0.62 0.48)) (define orange (make-color 1.00 0.64 0.00)) (define dark-orange (make-color 1.00 0.55 0.00)) (define coral (make-color 1.00 0.50 0.31)) (define light-coral (make-color 0.94 0.50 0.50)) (define tomato (make-color 1.00 0.39 0.28)) (define orange-red (make-color 1.00 0.27 0.00)) (define red (make-color 1.00 0.00 0.00)) (define hot-pink (make-color 1.00 0.41 0.70)) (define deep-pink (make-color 1.00 0.08 0.57)) (define pink (make-color 1.00 0.75 0.79)) (define light-pink (make-color 1.00 0.71 0.75)) (define pale-violet-red (make-color 0.86 0.44 0.57)) (define maroon (make-color 0.69 0.19 0.37)) (define medium-violet-red (make-color 0.78 0.08 0.52)) (define violet-red (make-color 0.81 0.12 0.56)) (define magenta (make-color 1.00 0.00 1.00)) (define violet (make-color 0.93 0.51 0.93)) (define plum (make-color 0.86 0.62 0.86)) (define orchid (make-color 0.85 0.44 0.84)) (define medium-orchid (make-color 0.73 0.33 0.82)) (define dark-orchid (make-color 0.60 0.20 0.80)) (define dark-violet (make-color 0.58 0.00 0.82)) (define blue-violet (make-color 0.54 0.17 0.88)) (define purple (make-color 0.62 0.12 0.94)) (define medium-purple (make-color 0.57 0.44 0.86)) (define thistle (make-color 0.84 0.75 0.84)) (define snow1 (make-color 1.00 0.98 0.98)) (define snow2 (make-color 0.93 0.91 0.91)) (define snow3 (make-color 0.80 0.79 0.79)) (define snow4 (make-color 0.54 0.54 0.54)) (define seashell1 (make-color 1.00 0.96 0.93)) (define seashell2 (make-color 0.93 0.89 0.87)) (define seashell3 (make-color 0.80 0.77 0.75)) (define seashell4 (make-color 0.54 0.52 0.51)) (define antiquewhite1 (make-color 1.00 0.93 0.86)) (define antiquewhite2 (make-color 0.93 0.87 0.80)) (define antiquewhite3 (make-color 0.80 0.75 0.69)) (define antiquewhite4 (make-color 0.54 0.51 0.47)) (define bisque1 (make-color 1.00 0.89 0.77)) (define bisque2 (make-color 0.93 0.83 0.71)) (define bisque3 (make-color 0.80 0.71 0.62)) (define bisque4 (make-color 0.54 0.49 0.42)) (define peachpuff1 (make-color 1.00 0.85 0.72)) (define peachpuff2 (make-color 0.93 0.79 0.68)) (define peachpuff3 (make-color 0.80 0.68 0.58)) (define peachpuff4 (make-color 0.54 0.46 0.39)) (define navajowhite1 (make-color 1.00 0.87 0.68)) (define navajowhite2 (make-color 0.93 0.81 0.63)) (define navajowhite3 (make-color 0.80 0.70 0.54)) (define navajowhite4 (make-color 0.54 0.47 0.37)) (define lemonchiffon1 (make-color 1.00 0.98 0.80)) (define lemonchiffon2 (make-color 0.93 0.91 0.75)) (define lemonchiffon3 (make-color 0.80 0.79 0.64)) (define lemonchiffon4 (make-color 0.54 0.54 0.44)) (define cornsilk1 (make-color 1.00 0.97 0.86)) (define cornsilk2 (make-color 0.93 0.91 0.80)) (define cornsilk3 (make-color 0.80 0.78 0.69)) (define cornsilk4 (make-color 0.54 0.53 0.47)) (define ivory1 (make-color 1.00 1.00 0.94)) (define ivory2 (make-color 0.93 0.93 0.87)) (define ivory3 (make-color 0.80 0.80 0.75)) (define ivory4 (make-color 0.54 0.54 0.51)) (define honeydew1 (make-color 0.94 1.00 0.94)) (define honeydew2 (make-color 0.87 0.93 0.87)) (define honeydew3 (make-color 0.75 0.80 0.75)) (define honeydew4 (make-color 0.51 0.54 0.51)) (define lavenderblush1 (make-color 1.00 0.94 0.96)) (define lavenderblush2 (make-color 0.93 0.87 0.89)) (define lavenderblush3 (make-color 0.80 0.75 0.77)) (define lavenderblush4 (make-color 0.54 0.51 0.52)) (define mistyrose1 (make-color 1.00 0.89 0.88)) (define mistyrose2 (make-color 0.93 0.83 0.82)) (define mistyrose3 (make-color 0.80 0.71 0.71)) (define mistyrose4 (make-color 0.54 0.49 0.48)) (define azure1 (make-color 0.94 1.00 1.00)) (define azure2 (make-color 0.87 0.93 0.93)) (define azure3 (make-color 0.75 0.80 0.80)) (define azure4 (make-color 0.51 0.54 0.54)) (define slateblue1 (make-color 0.51 0.43 1.00)) (define slateblue2 (make-color 0.48 0.40 0.93)) (define slateblue3 (make-color 0.41 0.35 0.80)) (define slateblue4 (make-color 0.28 0.23 0.54)) (define royalblue1 (make-color 0.28 0.46 1.00)) (define royalblue2 (make-color 0.26 0.43 0.93)) (define royalblue3 (make-color 0.23 0.37 0.80)) (define royalblue4 (make-color 0.15 0.25 0.54)) (define blue1 (make-color 0.00 0.00 1.00)) (define blue2 (make-color 0.00 0.00 0.93)) (define blue3 (make-color 0.00 0.00 0.80)) (define blue4 (make-color 0.00 0.00 0.54)) (define dodgerblue1 (make-color 0.12 0.56 1.00)) (define dodgerblue2 (make-color 0.11 0.52 0.93)) (define dodgerblue3 (make-color 0.09 0.45 0.80)) (define dodgerblue4 (make-color 0.06 0.30 0.54)) (define steelblue1 (make-color 0.39 0.72 1.00)) (define steelblue2 (make-color 0.36 0.67 0.93)) (define steelblue3 (make-color 0.31 0.58 0.80)) (define steelblue4 (make-color 0.21 0.39 0.54)) (define deepskyblue1 (make-color 0.00 0.75 1.00)) (define deepskyblue2 (make-color 0.00 0.70 0.93)) (define deepskyblue3 (make-color 0.00 0.60 0.80)) (define deepskyblue4 (make-color 0.00 0.41 0.54)) (define skyblue1 (make-color 0.53 0.80 1.00)) (define skyblue2 (make-color 0.49 0.75 0.93)) (define skyblue3 (make-color 0.42 0.65 0.80)) (define skyblue4 (make-color 0.29 0.44 0.54)) (define lightskyblue1 (make-color 0.69 0.88 1.00)) (define lightskyblue2 (make-color 0.64 0.82 0.93)) (define lightskyblue3 (make-color 0.55 0.71 0.80)) (define lightskyblue4 (make-color 0.37 0.48 0.54)) (define slategray1 (make-color 0.77 0.88 1.00)) (define slategray2 (make-color 0.72 0.82 0.93)) (define slategray3 (make-color 0.62 0.71 0.80)) (define slategray4 (make-color 0.42 0.48 0.54)) (define lightsteelblue1 (make-color 0.79 0.88 1.00)) (define lightsteelblue2 (make-color 0.73 0.82 0.93)) (define lightsteelblue3 (make-color 0.63 0.71 0.80)) (define lightsteelblue4 (make-color 0.43 0.48 0.54)) (define lightblue1 (make-color 0.75 0.93 1.00)) (define lightblue2 (make-color 0.70 0.87 0.93)) (define lightblue3 (make-color 0.60 0.75 0.80)) (define lightblue4 (make-color 0.41 0.51 0.54)) (define lightcyan1 (make-color 0.87 1.00 1.00)) (define lightcyan2 (make-color 0.82 0.93 0.93)) (define lightcyan3 (make-color 0.70 0.80 0.80)) (define lightcyan4 (make-color 0.48 0.54 0.54)) (define paleturquoise1 (make-color 0.73 1.00 1.00)) (define paleturquoise2 (make-color 0.68 0.93 0.93)) (define paleturquoise3 (make-color 0.59 0.80 0.80)) (define paleturquoise4 (make-color 0.40 0.54 0.54)) (define cadetblue1 (make-color 0.59 0.96 1.00)) (define cadetblue2 (make-color 0.55 0.89 0.93)) (define cadetblue3 (make-color 0.48 0.77 0.80)) (define cadetblue4 (make-color 0.32 0.52 0.54)) (define turquoise1 (make-color 0.00 0.96 1.00)) (define turquoise2 (make-color 0.00 0.89 0.93)) (define turquoise3 (make-color 0.00 0.77 0.80)) (define turquoise4 (make-color 0.00 0.52 0.54)) (define cyan1 (make-color 0.00 1.00 1.00)) (define cyan2 (make-color 0.00 0.93 0.93)) (define cyan3 (make-color 0.00 0.80 0.80)) (define cyan4 (make-color 0.00 0.54 0.54)) (define darkslategray1 (make-color 0.59 1.00 1.00)) (define darkslategray2 (make-color 0.55 0.93 0.93)) (define darkslategray3 (make-color 0.47 0.80 0.80)) (define darkslategray4 (make-color 0.32 0.54 0.54)) (define aquamarine1 (make-color 0.50 1.00 0.83)) (define aquamarine2 (make-color 0.46 0.93 0.77)) (define aquamarine3 (make-color 0.40 0.80 0.66)) (define aquamarine4 (make-color 0.27 0.54 0.45)) (define darkseagreen1 (make-color 0.75 1.00 0.75)) (define darkseagreen2 (make-color 0.70 0.93 0.70)) (define darkseagreen3 (make-color 0.61 0.80 0.61)) (define darkseagreen4 (make-color 0.41 0.54 0.41)) (define seagreen1 (make-color 0.33 1.00 0.62)) (define seagreen2 (make-color 0.30 0.93 0.58)) (define seagreen3 (make-color 0.26 0.80 0.50)) (define seagreen4 (make-color 0.18 0.54 0.34)) (define palegreen1 (make-color 0.60 1.00 0.60)) (define palegreen2 (make-color 0.56 0.93 0.56)) (define palegreen3 (make-color 0.48 0.80 0.48)) (define palegreen4 (make-color 0.33 0.54 0.33)) (define springgreen1 (make-color 0.00 1.00 0.50)) (define springgreen2 (make-color 0.00 0.93 0.46)) (define springgreen3 (make-color 0.00 0.80 0.40)) (define springgreen4 (make-color 0.00 0.54 0.27)) (define green1 (make-color 0.00 1.00 0.00)) (define green2 (make-color 0.00 0.93 0.00)) (define green3 (make-color 0.00 0.80 0.00)) (define green4 (make-color 0.00 0.54 0.00)) (define chartreuse1 (make-color 0.50 1.00 0.00)) (define chartreuse2 (make-color 0.46 0.93 0.00)) (define chartreuse3 (make-color 0.40 0.80 0.00)) (define chartreuse4 (make-color 0.27 0.54 0.00)) (define olivedrab1 (make-color 0.75 1.00 0.24)) (define olivedrab2 (make-color 0.70 0.93 0.23)) (define olivedrab3 (make-color 0.60 0.80 0.20)) (define olivedrab4 (make-color 0.41 0.54 0.13)) (define darkolivegreen1 (make-color 0.79 1.00 0.44)) (define darkolivegreen2 (make-color 0.73 0.93 0.41)) (define darkolivegreen3 (make-color 0.63 0.80 0.35)) (define darkolivegreen4 (make-color 0.43 0.54 0.24)) (define khaki1 (make-color 1.00 0.96 0.56)) (define khaki2 (make-color 0.93 0.90 0.52)) (define khaki3 (make-color 0.80 0.77 0.45)) (define khaki4 (make-color 0.54 0.52 0.30)) (define lightgoldenrod1 (make-color 1.00 0.92 0.54)) (define lightgoldenrod2 (make-color 0.93 0.86 0.51)) (define lightgoldenrod3 (make-color 0.80 0.74 0.44)) (define lightgoldenrod4 (make-color 0.54 0.50 0.30)) (define lightyellow1 (make-color 1.00 1.00 0.87)) (define lightyellow2 (make-color 0.93 0.93 0.82)) (define lightyellow3 (make-color 0.80 0.80 0.70)) (define lightyellow4 (make-color 0.54 0.54 0.48)) (define yellow1 (make-color 1.00 1.00 0.00)) (define yellow2 (make-color 0.93 0.93 0.00)) (define yellow3 (make-color 0.80 0.80 0.00)) (define yellow4 (make-color 0.54 0.54 0.00)) (define gold1 (make-color 1.00 0.84 0.00)) (define gold2 (make-color 0.93 0.79 0.00)) (define gold3 (make-color 0.80 0.68 0.00)) (define gold4 (make-color 0.54 0.46 0.00)) (define goldenrod1 (make-color 1.00 0.75 0.14)) (define goldenrod2 (make-color 0.93 0.70 0.13)) (define goldenrod3 (make-color 0.80 0.61 0.11)) (define goldenrod4 (make-color 0.54 0.41 0.08)) (define darkgoldenrod1 (make-color 1.00 0.72 0.06)) (define darkgoldenrod2 (make-color 0.93 0.68 0.05)) (define darkgoldenrod3 (make-color 0.80 0.58 0.05)) (define darkgoldenrod4 (make-color 0.54 0.39 0.03)) (define rosybrown1 (make-color 1.00 0.75 0.75)) (define rosybrown2 (make-color 0.93 0.70 0.70)) (define rosybrown3 (make-color 0.80 0.61 0.61)) (define rosybrown4 (make-color 0.54 0.41 0.41)) (define indianred1 (make-color 1.00 0.41 0.41)) (define indianred2 (make-color 0.93 0.39 0.39)) (define indianred3 (make-color 0.80 0.33 0.33)) (define indianred4 (make-color 0.54 0.23 0.23)) (define sienna1 (make-color 1.00 0.51 0.28)) (define sienna2 (make-color 0.93 0.47 0.26)) (define sienna3 (make-color 0.80 0.41 0.22)) (define sienna4 (make-color 0.54 0.28 0.15)) (define burlywood1 (make-color 1.00 0.82 0.61)) (define burlywood2 (make-color 0.93 0.77 0.57)) (define burlywood3 (make-color 0.80 0.66 0.49)) (define burlywood4 (make-color 0.54 0.45 0.33)) (define wheat1 (make-color 1.00 0.90 0.73)) (define wheat2 (make-color 0.93 0.84 0.68)) (define wheat3 (make-color 0.80 0.73 0.59)) (define wheat4 (make-color 0.54 0.49 0.40)) (define tan1 (make-color 1.00 0.64 0.31)) (define tan2 (make-color 0.93 0.60 0.29)) (define tan3 (make-color 0.80 0.52 0.25)) (define tan4 (make-color 0.54 0.35 0.17)) (define chocolate1 (make-color 1.00 0.50 0.14)) (define chocolate2 (make-color 0.93 0.46 0.13)) (define chocolate3 (make-color 0.80 0.40 0.11)) (define chocolate4 (make-color 0.54 0.27 0.07)) (define firebrick1 (make-color 1.00 0.19 0.19)) (define firebrick2 (make-color 0.93 0.17 0.17)) (define firebrick3 (make-color 0.80 0.15 0.15)) (define firebrick4 (make-color 0.54 0.10 0.10)) (define brown1 (make-color 1.00 0.25 0.25)) (define brown2 (make-color 0.93 0.23 0.23)) (define brown3 (make-color 0.80 0.20 0.20)) (define brown4 (make-color 0.54 0.14 0.14)) (define salmon1 (make-color 1.00 0.55 0.41)) (define salmon2 (make-color 0.93 0.51 0.38)) (define salmon3 (make-color 0.80 0.44 0.33)) (define salmon4 (make-color 0.54 0.30 0.22)) (define lightsalmon1 (make-color 1.00 0.62 0.48)) (define lightsalmon2 (make-color 0.93 0.58 0.45)) (define lightsalmon3 (make-color 0.80 0.50 0.38)) (define lightsalmon4 (make-color 0.54 0.34 0.26)) (define orange1 (make-color 1.00 0.64 0.00)) (define orange2 (make-color 0.93 0.60 0.00)) (define orange3 (make-color 0.80 0.52 0.00)) (define orange4 (make-color 0.54 0.35 0.00)) (define darkorange1 (make-color 1.00 0.50 0.00)) (define darkorange2 (make-color 0.93 0.46 0.00)) (define darkorange3 (make-color 0.80 0.40 0.00)) (define darkorange4 (make-color 0.54 0.27 0.00)) (define coral1 (make-color 1.00 0.45 0.34)) (define coral2 (make-color 0.93 0.41 0.31)) (define coral3 (make-color 0.80 0.36 0.27)) (define coral4 (make-color 0.54 0.24 0.18)) (define tomato1 (make-color 1.00 0.39 0.28)) (define tomato2 (make-color 0.93 0.36 0.26)) (define tomato3 (make-color 0.80 0.31 0.22)) (define tomato4 (make-color 0.54 0.21 0.15)) (define orangered1 (make-color 1.00 0.27 0.00)) (define orangered2 (make-color 0.93 0.25 0.00)) (define orangered3 (make-color 0.80 0.21 0.00)) (define orangered4 (make-color 0.54 0.14 0.00)) (define red1 (make-color 1.00 0.00 0.00)) (define red2 (make-color 0.93 0.00 0.00)) (define red3 (make-color 0.80 0.00 0.00)) (define red4 (make-color 0.54 0.00 0.00)) (define deeppink1 (make-color 1.00 0.08 0.57)) (define deeppink2 (make-color 0.93 0.07 0.54)) (define deeppink3 (make-color 0.80 0.06 0.46)) (define deeppink4 (make-color 0.54 0.04 0.31)) (define hotpink1 (make-color 1.00 0.43 0.70)) (define hotpink2 (make-color 0.93 0.41 0.65)) (define hotpink3 (make-color 0.80 0.37 0.56)) (define hotpink4 (make-color 0.54 0.23 0.38)) (define pink1 (make-color 1.00 0.71 0.77)) (define pink2 (make-color 0.93 0.66 0.72)) (define pink3 (make-color 0.80 0.57 0.62)) (define pink4 (make-color 0.54 0.39 0.42)) (define lightpink1 (make-color 1.00 0.68 0.72)) (define lightpink2 (make-color 0.93 0.63 0.68)) (define lightpink3 (make-color 0.80 0.55 0.58)) (define lightpink4 (make-color 0.54 0.37 0.39)) (define palevioletred1 (make-color 1.00 0.51 0.67)) (define palevioletred2 (make-color 0.93 0.47 0.62)) (define palevioletred3 (make-color 0.80 0.41 0.54)) (define palevioletred4 (make-color 0.54 0.28 0.36)) (define maroon1 (make-color 1.00 0.20 0.70)) (define maroon2 (make-color 0.93 0.19 0.65)) (define maroon3 (make-color 0.80 0.16 0.56)) (define maroon4 (make-color 0.54 0.11 0.38)) (define violetred1 (make-color 1.00 0.24 0.59)) (define violetred2 (make-color 0.93 0.23 0.55)) (define violetred3 (make-color 0.80 0.20 0.47)) (define violetred4 (make-color 0.54 0.13 0.32)) (define magenta1 (make-color 1.00 0.00 1.00)) (define magenta2 (make-color 0.93 0.00 0.93)) (define magenta3 (make-color 0.80 0.00 0.80)) (define magenta4 (make-color 0.54 0.00 0.54)) (define orchid1 (make-color 1.00 0.51 0.98)) (define orchid2 (make-color 0.93 0.48 0.91)) (define orchid3 (make-color 0.80 0.41 0.79)) (define orchid4 (make-color 0.54 0.28 0.54)) (define plum1 (make-color 1.00 0.73 1.00)) (define plum2 (make-color 0.93 0.68 0.93)) (define plum3 (make-color 0.80 0.59 0.80)) (define plum4 (make-color 0.54 0.40 0.54)) (define mediumorchid1 (make-color 0.87 0.40 1.00)) (define mediumorchid2 (make-color 0.82 0.37 0.93)) (define mediumorchid3 (make-color 0.70 0.32 0.80)) (define mediumorchid4 (make-color 0.48 0.21 0.54)) (define darkorchid1 (make-color 0.75 0.24 1.00)) (define darkorchid2 (make-color 0.70 0.23 0.93)) (define darkorchid3 (make-color 0.60 0.20 0.80)) (define darkorchid4 (make-color 0.41 0.13 0.54)) (define purple1 (make-color 0.61 0.19 1.00)) (define purple2 (make-color 0.57 0.17 0.93)) (define purple3 (make-color 0.49 0.15 0.80)) (define purple4 (make-color 0.33 0.10 0.54)) (define mediumpurple1 (make-color 0.67 0.51 1.00)) (define mediumpurple2 (make-color 0.62 0.47 0.93)) (define mediumpurple3 (make-color 0.54 0.41 0.80)) (define mediumpurple4 (make-color 0.36 0.28 0.54)) (define thistle1 (make-color 1.00 0.88 1.00)) (define thistle2 (make-color 0.93 0.82 0.93)) (define thistle3 (make-color 0.80 0.71 0.80)) (define thistle4 (make-color 0.54 0.48 0.54)) (define gray0 (make-color 0.00 0.00 0.00)) (define grey0 (make-color 0.00 0.00 0.00)) (define gray1 (make-color 0.01 0.01 0.01)) (define grey1 (make-color 0.01 0.01 0.01)) (define gray2 (make-color 0.02 0.02 0.02)) (define grey2 (make-color 0.02 0.02 0.02)) (define gray3 (make-color 0.03 0.03 0.03)) (define grey3 (make-color 0.03 0.03 0.03)) (define gray4 (make-color 0.04 0.04 0.04)) (define grey4 (make-color 0.04 0.04 0.04)) (define gray5 (make-color 0.05 0.05 0.05)) (define grey5 (make-color 0.05 0.05 0.05)) (define gray6 (make-color 0.06 0.06 0.06)) (define grey6 (make-color 0.06 0.06 0.06)) (define gray7 (make-color 0.07 0.07 0.07)) (define grey7 (make-color 0.07 0.07 0.07)) (define gray8 (make-color 0.08 0.08 0.08)) (define grey8 (make-color 0.08 0.08 0.08)) (define gray9 (make-color 0.09 0.09 0.09)) (define grey9 (make-color 0.09 0.09 0.09)) (define gray10 (make-color 0.10 0.10 0.10)) (define grey10 (make-color 0.10 0.10 0.10)) (define gray11 (make-color 0.11 0.11 0.11)) (define grey11 (make-color 0.11 0.11 0.11)) (define gray12 (make-color 0.12 0.12 0.12)) (define grey12 (make-color 0.12 0.12 0.12)) (define gray13 (make-color 0.13 0.13 0.13)) (define grey13 (make-color 0.13 0.13 0.13)) (define gray14 (make-color 0.14 0.14 0.14)) (define grey14 (make-color 0.14 0.14 0.14)) (define gray15 (make-color 0.15 0.15 0.15)) (define grey15 (make-color 0.15 0.15 0.15)) (define gray16 (make-color 0.16 0.16 0.16)) (define grey16 (make-color 0.16 0.16 0.16)) (define gray17 (make-color 0.17 0.17 0.17)) (define grey17 (make-color 0.17 0.17 0.17)) (define gray18 (make-color 0.18 0.18 0.18)) (define grey18 (make-color 0.18 0.18 0.18)) (define gray19 (make-color 0.19 0.19 0.19)) (define grey19 (make-color 0.19 0.19 0.19)) (define gray20 (make-color 0.20 0.20 0.20)) (define grey20 (make-color 0.20 0.20 0.20)) (define gray21 (make-color 0.21 0.21 0.21)) (define grey21 (make-color 0.21 0.21 0.21)) (define gray22 (make-color 0.22 0.22 0.22)) (define grey22 (make-color 0.22 0.22 0.22)) (define gray23 (make-color 0.23 0.23 0.23)) (define grey23 (make-color 0.23 0.23 0.23)) (define gray24 (make-color 0.24 0.24 0.24)) (define grey24 (make-color 0.24 0.24 0.24)) (define gray25 (make-color 0.25 0.25 0.25)) (define grey25 (make-color 0.25 0.25 0.25)) (define gray26 (make-color 0.26 0.26 0.26)) (define grey26 (make-color 0.26 0.26 0.26)) (define gray27 (make-color 0.27 0.27 0.27)) (define grey27 (make-color 0.27 0.27 0.27)) (define gray28 (make-color 0.28 0.28 0.28)) (define grey28 (make-color 0.28 0.28 0.28)) (define gray29 (make-color 0.29 0.29 0.29)) (define grey29 (make-color 0.29 0.29 0.29)) (define gray30 (make-color 0.30 0.30 0.30)) (define grey30 (make-color 0.30 0.30 0.30)) (define gray31 (make-color 0.31 0.31 0.31)) (define grey31 (make-color 0.31 0.31 0.31)) (define gray32 (make-color 0.32 0.32 0.32)) (define grey32 (make-color 0.32 0.32 0.32)) (define gray33 (make-color 0.33 0.33 0.33)) (define grey33 (make-color 0.33 0.33 0.33)) (define gray34 (make-color 0.34 0.34 0.34)) (define grey34 (make-color 0.34 0.34 0.34)) (define gray35 (make-color 0.35 0.35 0.35)) (define grey35 (make-color 0.35 0.35 0.35)) (define gray36 (make-color 0.36 0.36 0.36)) (define grey36 (make-color 0.36 0.36 0.36)) (define gray37 (make-color 0.37 0.37 0.37)) (define grey37 (make-color 0.37 0.37 0.37)) (define gray38 (make-color 0.38 0.38 0.38)) (define grey38 (make-color 0.38 0.38 0.38)) (define gray39 (make-color 0.39 0.39 0.39)) (define grey39 (make-color 0.39 0.39 0.39)) (define gray40 (make-color 0.40 0.40 0.40)) (define grey40 (make-color 0.40 0.40 0.40)) (define gray41 (make-color 0.41 0.41 0.41)) (define grey41 (make-color 0.41 0.41 0.41)) (define gray42 (make-color 0.42 0.42 0.42)) (define grey42 (make-color 0.42 0.42 0.42)) (define gray43 (make-color 0.43 0.43 0.43)) (define grey43 (make-color 0.43 0.43 0.43)) (define gray44 (make-color 0.44 0.44 0.44)) (define grey44 (make-color 0.44 0.44 0.44)) (define gray45 (make-color 0.45 0.45 0.45)) (define grey45 (make-color 0.45 0.45 0.45)) (define gray46 (make-color 0.46 0.46 0.46)) (define grey46 (make-color 0.46 0.46 0.46)) (define gray47 (make-color 0.47 0.47 0.47)) (define grey47 (make-color 0.47 0.47 0.47)) (define gray48 (make-color 0.48 0.48 0.48)) (define grey48 (make-color 0.48 0.48 0.48)) (define gray49 (make-color 0.49 0.49 0.49)) (define grey49 (make-color 0.49 0.49 0.49)) (define gray50 (make-color 0.50 0.50 0.50)) (define grey50 (make-color 0.50 0.50 0.50)) (define gray51 (make-color 0.51 0.51 0.51)) (define grey51 (make-color 0.51 0.51 0.51)) (define gray52 (make-color 0.52 0.52 0.52)) (define grey52 (make-color 0.52 0.52 0.52)) (define gray53 (make-color 0.53 0.53 0.53)) (define grey53 (make-color 0.53 0.53 0.53)) (define gray54 (make-color 0.54 0.54 0.54)) (define grey54 (make-color 0.54 0.54 0.54)) (define gray55 (make-color 0.55 0.55 0.55)) (define grey55 (make-color 0.55 0.55 0.55)) (define gray56 (make-color 0.56 0.56 0.56)) (define grey56 (make-color 0.56 0.56 0.56)) (define gray57 (make-color 0.57 0.57 0.57)) (define grey57 (make-color 0.57 0.57 0.57)) (define gray58 (make-color 0.58 0.58 0.58)) (define grey58 (make-color 0.58 0.58 0.58)) (define gray59 (make-color 0.59 0.59 0.59)) (define grey59 (make-color 0.59 0.59 0.59)) (define gray60 (make-color 0.60 0.60 0.60)) (define grey60 (make-color 0.60 0.60 0.60)) (define gray61 (make-color 0.61 0.61 0.61)) (define grey61 (make-color 0.61 0.61 0.61)) (define gray62 (make-color 0.62 0.62 0.62)) (define grey62 (make-color 0.62 0.62 0.62)) (define gray63 (make-color 0.63 0.63 0.63)) (define grey63 (make-color 0.63 0.63 0.63)) (define gray64 (make-color 0.64 0.64 0.64)) (define grey64 (make-color 0.64 0.64 0.64)) (define gray65 (make-color 0.65 0.65 0.65)) (define grey65 (make-color 0.65 0.65 0.65)) (define gray66 (make-color 0.66 0.66 0.66)) (define grey66 (make-color 0.66 0.66 0.66)) (define gray67 (make-color 0.67 0.67 0.67)) (define grey67 (make-color 0.67 0.67 0.67)) (define gray68 (make-color 0.68 0.68 0.68)) (define grey68 (make-color 0.68 0.68 0.68)) (define gray69 (make-color 0.69 0.69 0.69)) (define grey69 (make-color 0.69 0.69 0.69)) (define gray70 (make-color 0.70 0.70 0.70)) (define grey70 (make-color 0.70 0.70 0.70)) (define gray71 (make-color 0.71 0.71 0.71)) (define grey71 (make-color 0.71 0.71 0.71)) (define gray72 (make-color 0.72 0.72 0.72)) (define grey72 (make-color 0.72 0.72 0.72)) (define gray73 (make-color 0.73 0.73 0.73)) (define grey73 (make-color 0.73 0.73 0.73)) (define gray74 (make-color 0.74 0.74 0.74)) (define grey74 (make-color 0.74 0.74 0.74)) (define gray75 (make-color 0.75 0.75 0.75)) (define grey75 (make-color 0.75 0.75 0.75)) (define gray76 (make-color 0.76 0.76 0.76)) (define grey76 (make-color 0.76 0.76 0.76)) (define gray77 (make-color 0.77 0.77 0.77)) (define grey77 (make-color 0.77 0.77 0.77)) (define gray78 (make-color 0.78 0.78 0.78)) (define grey78 (make-color 0.78 0.78 0.78)) (define gray79 (make-color 0.79 0.79 0.79)) (define grey79 (make-color 0.79 0.79 0.79)) (define gray80 (make-color 0.80 0.80 0.80)) (define grey80 (make-color 0.80 0.80 0.80)) (define gray81 (make-color 0.81 0.81 0.81)) (define grey81 (make-color 0.81 0.81 0.81)) (define gray82 (make-color 0.82 0.82 0.82)) (define grey82 (make-color 0.82 0.82 0.82)) (define gray83 (make-color 0.83 0.83 0.83)) (define grey83 (make-color 0.83 0.83 0.83)) (define gray84 (make-color 0.84 0.84 0.84)) (define grey84 (make-color 0.84 0.84 0.84)) (define gray85 (make-color 0.85 0.85 0.85)) (define grey85 (make-color 0.85 0.85 0.85)) (define gray86 (make-color 0.86 0.86 0.86)) (define grey86 (make-color 0.86 0.86 0.86)) (define gray87 (make-color 0.87 0.87 0.87)) (define grey87 (make-color 0.87 0.87 0.87)) (define gray88 (make-color 0.87 0.87 0.87)) (define grey88 (make-color 0.87 0.87 0.87)) (define gray89 (make-color 0.89 0.89 0.89)) (define grey89 (make-color 0.89 0.89 0.89)) (define gray90 (make-color 0.89 0.89 0.89)) (define grey90 (make-color 0.89 0.89 0.89)) (define gray91 (make-color 0.91 0.91 0.91)) (define grey91 (make-color 0.91 0.91 0.91)) (define gray92 (make-color 0.92 0.92 0.92)) (define grey92 (make-color 0.92 0.92 0.92)) (define gray93 (make-color 0.93 0.93 0.93)) (define grey93 (make-color 0.93 0.93 0.93)) (define gray94 (make-color 0.94 0.94 0.94)) (define grey94 (make-color 0.94 0.94 0.94)) (define gray95 (make-color 0.95 0.95 0.95)) (define grey95 (make-color 0.95 0.95 0.95)) (define gray96 (make-color 0.96 0.96 0.96)) (define grey96 (make-color 0.96 0.96 0.96)) (define gray97 (make-color 0.96 0.96 0.96)) (define grey97 (make-color 0.96 0.96 0.96)) (define gray98 (make-color 0.98 0.98 0.98)) (define grey98 (make-color 0.98 0.98 0.98)) (define gray99 (make-color 0.98 0.98 0.98)) (define grey99 (make-color 0.98 0.98 0.98)) (define gray100 (make-color 1.00 1.00 1.00)) (define grey100 (make-color 1.00 1.00 1.00)) (define dark-grey (make-color 0.66 0.66 0.66)) (define dark-gray (make-color 0.66 0.66 0.66)) (define dark-blue (make-color 0.00 0.00 0.54)) (define dark-cyan (make-color 0.00 0.54 0.54)) (define dark-magenta (make-color 0.54 0.00 0.54)) (define dark-red (make-color 0.54 0.00 0.00)) (define light-green (make-color 0.56 0.93 0.56)) snd-16.1/dsp.rb0000644000076400007640000023672012476114577011476 0ustar bilbil# dsp.rb -- dsp.scm --> dsp.rb # Translator: Michael Scholz # Created: 05/03/07 13:50:44 # Changed: 15/03/04 17:18:38 # comments are taken mostly from dsp.scm # # module Dsp # src_duration(e) # dolph(n, gamma) # dolph_1(n, gamma) # down_oct(n, snd, chn) # edot_product(freq, data) # stretch_sound_via_dft(factor, snd, chn) # compute_uniform_circular_string(size, x0, x1, x2, mass, xspring, damp) # testunif(mass, xspring, damp) # test_scanned_synthesis(amp, dur, mass, xspring, damp) # compute_string(size, x0, x1, x2, masses, xsprings, esprings, damps, haptics) # freqdiv(n, snd, chn) # adsat(size, beg, dur, snd, chn) # spike(snd, chn) # spot_freq(samp, snd, chn) # class Flanger < Musgen # initialize(time, amount, speed) # inspect # to_s # run_func(val1, val2) # flanger(inval) # make_flanger(time, amount, speed) # flanger?(obj) # flanger(gen, inval) # chorus(size) # chordalize(amount, base, chord) # zero_phase(snd, chn) # rotate_phase(func, snd, chn) # class Asyfm < Musgen # initialize(*args) # inspect # to_s # run_func(val1, val2) # asyfm_J(input) # asyfm_I(input) # make_asyfm(*args) # asyfm?(obj) # asyfm_J(gen, input) # asyfm_I(gen, input) # cosine_summation(gen, r) # kosine_summation(gen, r, k) # fejer_sum(angle, n) # legendre_sum(angle, n) # sum_of_n_sines(angle, n) # sum_of_n_odd_sines(angle, n) # sum_of_n_odd_cosines(angle, n) # band_limited_sawtooth(x, a, n, fi) # brighten_slightly(amount, snd, chn) # brighten_slightly_1(coeffs, snd, chn) # spectrum2coeffs(order, spectr) # fltit_1(order, spectr) # make_hilbert_transform(len) # make_highpass(fc, len) # make_lowpass(fc, len) # make_bandpass(flo, fhi, len) # make_bandstop(flo, fhi, len) # make_differentiator(len) # make_butter_high_pass(freq) # make_butter_low_pass(freq) # make_butter_band_pass(freq, band) # make_butter_band_reject(freq, band) # make_biquad(a0, a1, a2, b1, b2) # make_iir_low_pass_2(fc, din) # make_iir_high_pass_2(fc, din) # make_iir_band_pass_2(f1, f2) # make_iir_band_stop_2(f1, f2) # make_eliminate_hum(hum_freq, hum_harmonics, bandwidth) # eliminate_hum(gens, x0) # make_peaking_2(f1, f2, m) # cascade2canonical(a) # make_butter_lp(m, fc) # make_butter_hp(m, fc) # make_butter_bp(m, f1, f2) # make_butter_bs(m, f1, f2) # make_notch_frequency_response(cur_srate, freqs, notch_width) # notch_channel(freqs, filter_order, beg, dur, snd, chn, edpos, trc, n_width) # notch_sound(freqs, filter_order, snd, chn, notch_width) # notch_selection(freqs, filter_order, snd, chn, notch_width) # fractional_fourier_transform(fr, fi, n, v) # z_transform(f, n, z) # dht(data) # find_sine(freq, beg, dur, snd) # goertzel(freq, beg, dur, snd) # make_spencer_filter # any_random(amount, e) # gaussian_distribution(s) # pareto_distribution(a) # inverse_integrate(dist, data_size, e_size) # gaussian_envelope(s) # channel_mean(snd, chn) # channel_total_energy(snd, chn) # channel_average_power(snd, chn) # channel_rms(snd, chn) # channel_variance(snd, chn) # channel_norm(snd, chn) # channel_lp(p, snd, chn) # channel_lp_inf(snd, chn) # channel2_inner_product(s1, c1, s2, c2) # channel2_angle(s1, c1, s2, c2) # channel2_orthogonal?(s1, c1, s2, c2) # channel2_coefficient_of_projection(s1, c1, s2, c2) # channel_distance(s1, c1, s2, c2) # periodogram(n) # shift_channel_pitch(freq, order, beg, dur, snd, chn, edpos) # hz_to_2pi(freq) # ssb_bank(old_freq, new_freq, pairs, order, bw, beg, dur, snd, chn, edpos) # ssb_bank_env(old_freq, new_freq, fq_env, pairs, ord, bw, beg, dur, s, c, ep) # # vct_polynomial(v, coeffs) # channel_polynomial(coeffs, snd, chn) # spectral_polynomial(coeffs, snd, chn) # scentroid(file, beg, dur, db_floor, rfreq, fftsize) # invert_filter(fcoeffs) # # class Volterra_filter < Musgen # initialize(acoeffs, bcoeffs) # inspect # to_s # run_func(val1, val2) # volterra_filter(x) # # make_volterra_filter(acoeffs, bcoeffs) # volterra_filter(flt, x) # make_moving_sum(size) # moving_sum(gen, y) # make_moving_rms(size) # moving_rms(gen, y) # make_moving_length(size) # moving_length(gen, y) # harmonicizer(freq, coeffs, pairs, order, bw, beg, dur, snd, chn, edpos) # linear_src_channel(srinc, snd, chn) # # class Mfilter < Musgen # initialize(decay, freq) # inspect # to_s # mfilter(x_input, y_input) # # make_mfilter(*args) # mfilter(m, x_input, y_input) # # class Display_bark_fft # display_bark_fft(snd, chn) # mark_bark_labels(snd, chn) # choose_bark_ticks(snd, chn, button, state, x, y, axis) # # display_bark_fft(off) # undisplay_bark_fft require "ws" require "env" module Dsp # src_duration (see src-channel in extsnd.html) add_help(:src_duration, "src_duration(envelope) \ Returns the new duration of a sound after using ENVELOPE for \ time-varying sampling-rate conversion.") def src_duration(e) e.map! do |x| x.to_f end ex0 = e.first ex1 = e[-2] all_x = ex1 - ex0 dur = 0.0 0.step(e.length - 3, 2) do |i| x0, xy0, x1, xy1 = e[i, 4] y0 = xy0.zero? ? 1.0 : (1.0 / xy0) y1 = xy1.zero? ? 1.0 : (1.0 / xy1) area = if (xy0 - xy1).abs < 0.0001 y0 * ((x1 - x0) / all_x) else ((log(y1) - log(y0)) / (xy0 - xy1)) * ((x1 - x0) / all_x) end dur += area.abs end dur end # Dolph-Chebyshev window # # formula taken from Richard Lyons, "Understanding DSP" # see clm.c for C version (using either GSL's or GCC's complex trig functions) add_help(:dolph, "dolph(n, gamma) \ Produces a Dolph-Chebyshev FFT data window of N points \ using GAMMA as the window parameter.") def dolph(n, gamma) alpha = cosh(acosh(10.0 ** gamma) / n) den = 1.0 / cosh(n * acosh(alpha)) freq = PI / n rl = make_vct(n) im = make_vct(n) phase = 0.0 n.times do |i| val = den * cos(n * acos(alpha * cos(phase))) rl[i] = val.real im[i] = val.imag phase += freq end fft(rl, im, -1) vct_scale!(rl, 1.0 / vct_peak(rl)) j = n / 2 n.times do |i| im[i] = rl[j] j += 1 if j == n j = 0 end end im end if defined? acosh # this version taken from Julius Smith's "Spectral Audio..." with # three changes it does the DFT by hand, and is independent of # anything from Snd (fft, vcts etc) add_help(:dolph_1, "dolph_1(n, gamma) \ Produces a Dolph-Chebyshev FFT data window of N points \ using GAMMA as the window parameter.") def dolph_1(n, gamma) alpha = cosh(acosh(10.0 ** gamma) / n) den = 1.0 / cosh(n * acosh(alpha)) freq = PI / n vals = make_array(n) w = make_array(n) pk = 0.0 mult = -1.0 phase = -HALF_PI n.times do |i| vals[i] = mult * den * cos(n * acos(alpha * cos(phase))) mult *= -1.0 phase += freq end n.times do |i| sum = 0.0 n.times do |j| sum = sum + vals[j] * exp((2.0 * Complex(0.0, 1.0) * PI * j * i) / n) end w[i] = sum.abs if w[i] > pk pk = w[i] end end w.map! do |val| val / pk end end if defined? acosh # move sound down by n (a power of 2) # I think this is "stretch" in DSP jargon -- to interpolate in the # time domain we're squeezing the frequency domain the power-of-2 # limitation is based on the underlying fft function's insistence on # power-of-2 data sizes see stretch-sound-via-dft below for a # general version add_help(:down_oct, "down_oct(n, snd=false, chn=false) \ Moves a sound down by power of 2 N.") def down_oct(n, snd = false, chn = false) len = framples(snd, chn) pow2 = (log(len) / log(2)).ceil fftlen = (2 ** pow2).round fftscale = 1.0 / fftlen rl1 = channel2vct(0, fftlen, snd, chn) im1 = make_vct(fftlen) fft(rl1, im1, 1) vct_scale!(rl1, fftscale) vct_scale!(im1, fftscale) rl2 = make_vct(2 * fftlen) im2 = make_vct(2 * fftlen) k = fftlen - 1 j = fftlen * n - 1 (0...(fftlen / 2)).each do |i| vct_set!(rl2, i, rl1[i]) vct_set!(rl2, j, rl1[k]) vct_set!(im2, i, im1[i]) vct_set!(im2, j, im1[k]) k -= 1 j -= 1 end fft(rl2, im2, -1) vct2channel(rl2, 0, n * len, snd, chn, false, format("%s(%s", get_func_name, n)) end add_help(:edot_product, "edot_product(freq, data) \ Sum of (e^freq*i) * data[i]") def edot_product(freq, data) sum = 0.0 data.each_with_index do |val, i| sum = sum + exp(i.to_f * freq) * val end sum end unless defined? edot_product add_help(:stretch_sound_via_dft, "stretch_sound_via_dft(factor, snd=false, chn=false) \ Makes the given channel longer (FACTOR should be > 1.0) by \ squeezing in the frequency domain, \ then using the inverse DFT to get the time domain result.") def stretch_sound_via_dft(factor, snd = false, chn = false) factor = factor.to_f n = framples(snd, chn) n2 = (n / 2.0).floor out_n = (n * factor).round in_data = channel2vct(0, n, snd, chn) out_data = make_vct(out_n) fr = make_array(out_n, 0.0) freq = (PI * 2) / n n.times do |i| d = edot_product(freq * Complex(0.0, 1.0) * i, in_data) if i < n2 fr[i] = d else fr[i + (out_n - n - 1)] = d end end freq = (PI * 2) / out_n out_n.times do |i| out_data[i] = (edot_product(freq * Complex(0.0, 1.0) * i, fr) / n).real end vct2channel(out_data, 0, out_n, snd, chn, false, format("%s(%s", get_func_name, factor)) end # compute-uniform-circular-string # # this is a simplification of the underlying table-filling routine # for "scanned synthesis". To watch the wave, open some sound (so # Snd has some place to put the graph), turn off the time domain # display (to give our graph all the window -- to do this in a much # more elegant manner, see snd-motif.scm under scanned-synthesis). def compute_uniform_circular_string(size, x0, x1, x2, mass, xspring, damp) circle_vct_ref = lambda do |v, i| if i < 0 v[i + size] elsif i >= size v[i - size] else v[i] end end dm = damp / mass.to_f km = xspring / mass.to_f denom = 1.0 + dm p1 = (2.0 + (dm - 2.0 * km)) / denom p2 = km / denom p3 = -1.0 / denom size.times do |i| x0[i] = p1 * x1[i] + p2 * (circle_vct_ref.call(x1, i - 1) + circle_vct_ref.call(x1, i + 1)) + p3 * x2[i] end vct_fill!(x2, 0.0) vct_add!(x2, x1) vct_fill!(x1, 0.0) vct_add!(x1, x0) end def testunif(mass, xspring, damp) size = 128 x0 = make_vct(size) x1 = make_vct(size) x2 = make_vct(size) 12.times do |i| x1[i + size / 4 - 6] = sin((TWO_PI * i) / 12.0) end 1024.times do |i| compute_uniform_circular_string(size, x0, x1, x2, mass, xspring, damp) graph(x0, "string", 0, 1.0, -10.0, 10.0) end end def test_scanned_synthesis(amp, dur, mass, xspring, damp) size = 256 x0 = make_vct(size) gx1 = make_vct(size) gx2 = make_vct(size) 12.times do |i| gx1[i + size / 4 - 6] = sin((TWO_PI * i) / 12.0) end gen1 = make_table_lookup(440.0, :wave, gx1) gen2 = make_table_lookup(440.0, :wave, gx2) x1 = gen1.data x2 = gen2.data recompute_samps = 30.0 k = 0.0 kincr = 1.0 / recompute_samps data = make_vct!(dur) do |i| if k >= 1.0 k = 0.0 compute_uniform_circular_string(size, x0, x1, x2, mass, xspring, damp) else k += kincr end g1 = table_lookup(gen1) g2 = table_lookup(gen2) g2 + k * (g1 - g2) end vct_scale!(data, amp / vct_peak(data)) vct2channel(data, 0, dur) end # this is the more general form def compute_string(size, x0, x1, x2, masses, xsprings, esprings, damps, haptics) circle_vct_ref = lambda do |v, i| if i < 0 v[i + size] elsif i >= size v[i - size] else v[i] end end size.times do |i| dm = damps[i] / masses[i] km = xsprings[i] / masses[i] cm = esprings[i] / masses[i] denom = 1.0 + dm + cm p1 = (2.0 + (dm - 2.0 * km)) / denom p2 = km / denom p3 = -1.0 / denom p4 = haptics / (masses[i] * denom) x0[i] = p1 * x1[i] + p2 * (circle_vct_ref.call(x1, i - 1) + circle_vct_ref.call(x1, i + 1)) + p3 * x2[i] + p4 end size.times do |i| x2[i], x1[i] = x1[i], x0[i] end end # "frequency division" -- an effect from sed_sed@my-dejanews.com add_help(:freqdiv, "freqdiv(n, snd=false, chn=false) \ Repeats each nth sample N times (clobbering the intermediate samples): \ freqdiv(8)") def freqdiv(n, snd = false, chn = false) div = 0 curval = 0.0 map_channel(lambda do |val| curval = val if div.zero? div += 1 div = 0 if div == n curval end, 0, false, snd, chn, false, format("%s(%s", get_func_name, n)) end # "adaptive saturation" -- an effect from sed_sed@my-dejanews.com # # a more extreme effect is "saturation": # (map-channel (lambda (val) # (if (< (abs val) .1) val (if (>= val 0.0) 0.25 -0.25)))) add_help(:adsat, "adsat(size, beg=false, dur=false, snd=false, chn=false) \ Is an 'adaptive saturation' sound effect.") def adsat(size, beg = false, dur = false, snd = false, chn = false) mn = 0.0 mx = 0.0 n = 0 vals = make_vct(size) map_channel(lambda do |val| if n == size size.times do |i| if vals[i] >= 0.0 vals[i] = mx else vals[i] = mn end end n = 0 mx = 0.0 mn = 0.0 vals else vals[n] = val mx = val if val > mx mn = val if val < mn n += 1 false end end, beg, dur, snd, chn, false, format("%s(%s, %s, %s", get_func_name, size, beg, dur)) end # spike # # makes sound more spikey -- sometimes a nice effect add_help(:spike, "spike(snd=false, chn=false) \ Multiplies successive samples together to make a sound more spikey.") def spike(snd = false, chn = false) x1 = x2 = 0.0 amp = maxamp(snd, chn) map_channel(lambda do |x0| res = (x0 / (amp * amp)) * x2.abs * x1.abs x2, x1 = x1, x0 res end, 0, false, snd, chn, false, "spike(") end # easily-fooled autocorrelation-based pitch tracker add_help(:spot_freq, "spot_freq(samp=0, snd=false, chn=false) \ Tries to determine the current pitch: spot_freq(left_sample)") def spot_freq(samp = 0, snd = false, chn = false) pow2 = (log(srate(snd) / 20.0) / log(2)).ceil fftlen = (2 ** pow2).round data = autocorrelate(channel2vct(samp, fftlen, snd, chn)) cor_peak = vct_peak(data) cor_peak2 = 2.0 * cor_peak ret = 0.0 (1...fftlen - 2).each do |i| if data[i] < data[i + 1] and data[i + 2] < data[i + 1] logla = log10((cor_peak + data[i]) / cor_peak2) logca = log10((cor_peak + data[i + 1]) / cor_peak2) logra = log10((cor_peak + data[i + 2]) / cor_peak2) offset = (0.5 * (logla - logra)) / (logla + logra + -2.0 * logca) ret = srate(snd) / (2.0 * (i + 1 + offset)) break end end ret end # $graph_hook.add_hook!("examp-left-sample-hook") do |snd, chn, y0, y1| # msg = format("(freq: %.3f)", spot_freq(left_sample(snd, chn))) # status_report(msg, snd) # end # # or # # $mouse_click_hook.add_hook!("examp-cursor-hook") do |snd, chn, # button, state, # x, y, axis| # if axis == Time_graph # status_report(format("(freq: %.3f)", spot_freq(cursor(snd, chn))), snd) # end # end # chorus (doesn't always work and needs speedup) class Flanger < Musgen def initialize(time = 0.05, amount = 20.0, speed = 10.0) super() @time = time @amount = amount @speed = speed @randind = make_rand_interp(:frequency, speed, :amplitude, amount) @data = @randind.data @length = @randind.length len = random(3.0 * time * mus_srate()).floor @flanger = make_delay(:size, len, :max_size, (len + amount + 1).to_i) end def inspect format("%s.new(%s, %s, %s)", self.class, @time, @amount, @speed) end def to_s format("#<%s time: %1.3f, amount: %1.3f, speed: %1.3f>", self.class, @time, @amount, @speed) end def run_func(val1 = 0.0, val2 = 0.0) flanger(val1) end def flanger(inval) inval + delay(@flanger, inval, rand_interp(@randind)) end end def make_flanger(time = 0.05, amount = 20.0, speed = 10.0) Flanger.new(time, amount, speed) end def flanger?(obj) obj.kind_of?(Flanger) end def flanger(gen, inval) gen.flanger(inval) end add_help(:chorus, "chorus(size=5) \ Tries to produce the chorus sound effect.") def chorus(size = 5) dlys = make_array(size) do make_flanger end sum = 0.0 lambda do |inval| dlys.each do |dly| sum += dly.flanger(inval) end sum * 0.25 end end # chordalize (comb filters to make a chord using chordalize-amount # and chordalize-base) add_help(:chordalize, "chordalize(amount=0.95, base=100, chord=[1.00, 0.75, 1.25]) \ Uses harmonically-related comb-filters to bring out a chord in a sound.") def chordalize(amount = 0.95, base = 100, chord = [1.00, 0.75, 1.25]) combs = chord.map do |interval| make_comb(:scaler, amount, :size, (base * interval).round) end scaler = 0.5 / chord.length lambda do |x| val = 0.0 combs.each do |c| val += comb(c, x) end scaler * val end end # zero-phase, rotate-phase # fft games (from the "phazor" package of Scott McNab) add_help(:zero_phase, "zero_phase(snd=false, chn=false) \ Calls fft, sets all phases to 0, and un-ffts.") def zero_phase(snd = false, chn = false) len = framples(snd, chn) pow2 = (log(len) / log(2)).ceil fftlen = (2 ** pow2).round fftscale = 1.0 / fftlen rl = channel2vct(0, fftlen, snd, chn) old_pk = vct_peak(rl) im = make_vct(fftlen) fft(rl, im, 1) rectangular2polar(rl, im) vct_scale!(rl, fftscale) vct_scale!(im, 0.0) fft(rl, im, -1) pk = vct_peak(rl) vct2channel(rl.scale(old_pk / pk), 0, len, snd, chn, false, "zero_phase(") end # (set_)edit_list_proc_counter is defined in clm.rb # It's necessary to produce a uniq method name. add_help(:rotate_phase, "rotate_phase(func, snd=false, chn=false) \ Calls fft, applies func to each phase, then un-ffts.") def rotate_phase(func, snd = false, chn = false) func_name = format("%s_%d", get_func_name, set_edit_list_proc_counter).intern # Proc converted to Method (ie. normal function) for edit_list2function func.to_method(func_name) len = framples(snd, chn) pow2 = (log(len) / log(2)).ceil fftlen = (2 ** pow2).round fftlen2 = (fftlen / 2).floor fftscale = 1.0 / fftlen rl = channel2vct(0, fftlen, snd, chn) im = make_vct(fftlen) old_pk = rl.peak fft(rl, im, 1) rectangular2polar(rl, im) rl.scale!(fftscale) im[0] = 0.0 j = fftlen - 1 (1...fftlen2).each do |i| im[i] = snd_func(func_name, im[i]) im[j] = -im[i] j -= 1 end polar2rectangular(rl, im) fft(rl, im, -1) pk = rl.peak vct2channel(rl.scale(old_pk / pk), 0, len, snd, chn, false, format("%s(Proc.new {|val_r| %s(val_r) }", get_func_name, func_name)) end # rotate_phase(lambda {|x| 0.0 }) # is the same as (zero-phase) # rotate_phase(lambda {|x| random(PI) }) # randomizes phases # rotate_phase(lambda {|x| x }) # returns original # rotate_phase(lambda {|x| -x }) # reverses original # # (might want to write fftlen samps here) # asymmetric FM (bes-i0 case) class Asyfm < Musgen def initialize(*args) super() frequency, ratio, r, index, phase = nil optkey(args, binding, [:frequency, $clm_default_frequency], [:ratio, 1.0], [:r, 1.0], [:index, 1.0], [:phase, 0.0]) @frequency = frequency.to_f @ratio = ratio.to_f @r = r.to_f @index = index.to_f @freq = hz2radians(@frequency) @phase = phase.to_f end attr_accessor :ratio, :r, :index def inspect format("%s.new(:frequency, %s, :ratio, %s, :r, %s, \ :index, %s, :freq, %s, :phase, %s)", self.class, @frequency, @ratio, @r, @index, @freq, @phase) end def to_s format("#<%s freq: %1.3f, ratio: %1.3f, r: %1.3f, \ index: %1.3f, freq: %1.3f, phase: %1.3f>", self.class, @frequency, @ratio, @r, @index, @freq, @phase) end def run_func(val1 = 0.0, val2 = 0.0) asyfm_J(val1) end def asyfm_J(input) # It follows now asyfm-J in generators.scm, not dsp-asyfm-J in clm23.scm. r1 = 1.0 / @r one = ((@r > 1.0) or (@r < 0.0 and @r > -1.0)) ? -1.0 : 1.0 modphase = @ratio * @phase result = exp(0.5 * @index * (@r - r1) * (one + cos(modphase))) * cos(@phase + 0.5 * @index * (@r + r1) * sin(modphase)) @phase = @phase + input + @freq result end def asyfm_I(input) r1 = 1.0 / @r modphase = @ratio * @phase result = exp(0.5 * @index * (@r + r1) * (cos(modphase) - 1.0)) - cos(@phase + 0.5 * @index * (@r - r1) * sin(modphase)) @phase = @phase + input + @freq result end end def make_asyfm(*args) Asyfm.new(*args) end def asyfm?(obj) obj.kind_of?(Asyfm) end def asyfm_J(gen, input) gen.asyfm_J(input) end def asyfm_I(gen, input) gen.asyfm_I(input) end # cosine-summation (a simpler version of sine-summation) # # from Andrews, Askey, Roy "Special Functions" 5.1.16 add_help(:cosine_summation, "cosine_summation(gen, r) \ Is a variant of the CLM sine-summation generator; \ R controls successive sinusoid amplitudes.") def cosine_summation(gen, r) rr = r * r rrp1 = 1.0 + rr rrm1 = 1.0 - rr r2 = 2.0 * r ((rrm1 / (rrp1 - r2 * oscil(gen))) - 1.0) * ((1.0 - r) / r2) end alias make_cosine_summation make_oscil # kosine-summation # # from Askey "Ramanujan and Hypergeometric Series" in Berndt and # Rankin "Ramanujan: Essays and Surveys" # # this gives a sum of cosines of decreasing amp where the "k" # parameter determines the "index" (in FM nomenclature) -- higher k # = more cosines; the actual amount of the nth cos involves # hypergeometric series (looks like r^n/n! (~=e^n?) with a million # other terms). add_help(:kosine_summation, "kosine_summation(gen, r, k) \ Is a variant of sum-of-cosines; \ R controls successive sinusoid amplitude; \ K controls how many sinusoids are produced.") def kosine_summation(gen, r, k) r2 = r * r ((1.0 + r2) - 2 * r * oscil(gen)) ** -k * ((1.0 + r2) - 2 * r) ** k end alias make_kosine_summation make_oscil # legendre, fejer def fejer_sum(angle, n) if angle.zero? 1.0 else val = sin(0.5 * (n + 1) * angle) / (2.0 * sin(0.5 * angle)) 2.0 * ((val * val) / (n + 1)) end end def legendre_sum(angle, n) val = sin(angle * (n + 0.5)) / sin(0.5 * angle) val * val end # variations on sum-of-cosines # from "Trigonometric Delights" by Eli Maor def sum_of_n_sines(angle, n) a2 = angle * 0.5 den = sin(a2) if den.zero? 0.0 else (sin(n * a2) * sin((n + 1) * a2)) / den end end def sum_of_n_odd_sines(angle, n) angle = angle.to_f n = n.to_f den = sin(angle) na = sin(n * angle) if den.zero? 0.0 else (na * na) / den end end def sum_of_n_odd_cosines(angle, n) angle = angle.to_f n = n.to_f den = 2.0 * sin(angle) if den.zero? n else sin(2.0 * n * angle) / den end end # x = current phase, a = amp (more or less), N = 1..10 or # thereabouts, fi = phase increment Alexander Kritov suggests # time-varying "a" is good (this is a translation of his code) from # Stilson/Smith apparently -- was named "Discrete Summation Formula" # which doesn't convey anything to me def band_limited_sawtooth(x, a, n, fi) s4 = 1.0 + -2.0 * a * cos(x) + a * a if s4.zero? 0.0 else s1 = a ** (n - 1.0) * sin((n - 1.0) * x + fi) s2 = a ** n * sin(n * x + fi) s3 = a * sin(x + fi) (sin(fi) + -s3 + -s2 + s1) / s4 end end # brighten-slightly add_help(:brighten_slightly, "brighten_slightly(amount, snd=false, chn=false) \ Is a form of contrast-enhancement (AMOUNT between ca 0.1 and 1.0).") def brighten_slightly(amount, snd = false, chn = false) mx = maxamp brt = (TWO_PI * amount) / mx map_channel(lambda do |y| mx * sin(y * brt) end, 0, false, snd, chn, false, format("%s(%s", get_func_name, amount)) end add_help(:brighten_slightly_1, "brighten_slightly_1(coeffs, snd=false, chn=false) \ Is a form of contrast-enhancement: brighten_slightly-1([1, 0.5, 3, 1])") def brighten_slightly_1(coeffs, snd = false, chn = false) pcoeffs = partials2polynomial(coeffs) mx = maxamp(snd, chn) map_channel(lambda do |y| mx * polynomial(pcoeffs, y / mx) end, 0, false, snd, chn, false, format("%s(%s", get_func_name, coeffs)) end # FIR filters # Snd's (very simple) spectrum->coefficients procedure is: add_help(:spectrum2coeffs, "spectrum2coeffs(order, spectr) \ Returns FIR filter coefficients given the filter ORDER \ and desired spectral envelope (a vct).") def spectrum2coeffs(order, spectr) coeffs = make_vct(order) n = order m = ((n + 1) / 2.0).floor am = 0.5 * (n + 1) q = (PI * 2.0) / n jj = n - 1 m.times do |j| xt = 0.5 * spectr[0] (1...m).each do |i| xt = xt + spectr[i] * cos(q * i * (am - j - 1)) end coeff = 2.0 * (xt / n) coeffs[j] = coeff coeffs[jj] = coeff jj -= 1 end coeffs end add_help(:fltit_1, "fltit_1(order, spectrum) \ Creates an FIR filter from SPECTRUM and ORDER and \ returns a closure that calls it: \ map_channel(fltit_1(10, vct(0, 1.0, 0, 0, 0, 0, 0, 0, 1.0, 0)))") def fltit_1(order, spectr) flt = make_fir_filter(order, spectrum2coeffs(order, spectr)) lambda do |x| fir_filter(flt, x) end end # Hilbert transform add_help(:make_hilbert_transform, "make_hilbert_transform(len=30) \ Makes a Hilbert transform filter.") def make_hilbert_transform(len = 30) arrlen = len * 2 + 1 arr = make_vct(arrlen) (-len...len).each do |i| k = i + len denom = PI * i num = 1.0 - cos(denom) if num.zero? or i.zero? arr[k] = 0.0 else arr[k] = (num / denom) * (0.54 + 0.46 * cos(denom / len)) end end make_fir_filter(arrlen, arr) end add_help(:hilbert_transform, "hilbert_transform(f, in) \ Is the generator corresponding to make_hilbert_transform.") alias hilbert_transform fir_filter # highpass filter add_help(:make_highpass, "make_highpass(fc, len=30) \ Makes an FIR highpass filter.") def make_highpass(fc, len = 30) fc = fc.to_f arrlen = len * 2 + 1 arr = make_vct(arrlen) (-len...len).each do |i| k = i + len denom = PI * i num = -sin(fc * i) if i.zero? arr[k] = 1.0 - fc / PI else arr[k] = (num / denom) * (0.54 + 0.46 * cos((PI * i) / len)) end end make_fir_filter(arrlen, arr) end add_help(:highpass, "highpass(f, in) \ Is the generator corresponding to make_highpass.") alias highpass fir_filter # lowpass filter add_help(:make_lowpass, "make_lowpass(fc, len=30) \ Makes an FIR lowpass filter.") def make_lowpass(fc, len = 30) fc = fc.to_f arrlen = len * 2 + 1 arr = make_vct(arrlen) (-len...len).each do |i| k = i + len denom = PI * i num = sin(fc * i) if i.zero? arr[k] = fc / PI else arr[k] = (num / denom) * (0.54 + 0.46 * cos((PI * i) / len)) end end make_fir_filter(arrlen, arr) end add_help(:lowpass, "lowpass(f, in) \ Is the generator corresponding to make_lowpass.") alias lowpass fir_filter # bandpass filter add_help(:make_bandpass, "make_bandpass(flo, fhi, len=30) \ Makes an FIR bandpass filter.") def make_bandpass(flo, fhi, len = 30) flo = flo.to_f fhi = fhi.to_f arrlen = len * 2 + 1 arr = make_vct(arrlen) (-len...len).each do |i| k = i + len denom = PI * i num = sin(fhi * i) - sin(flo * i) if i.zero? arr[k] = (fhi - flo) / PI else arr[k] = (num / denom) * (0.54 + 0.46 * cos((PI * i) / len)) end end make_fir_filter(arrlen, arr) end add_help(:bandpass, "bandpass(f, in) \ Is the generator corresponding to make_bandpass.") alias bandpass fir_filter # bandstop filter add_help(:make_bandstop, "make_bandstop(flo, fhi, len=30) \ Makes an FIR bandstop (notch) filter.") def make_bandstop(flo, fhi, len = 30) flo = flo.to_f fhi = fhi.to_f arrlen = len * 2 + 1 arr = make_vct(arrlen) (-len...len).each do |i| k = i + len denom = PI * i num = sin(flo * i) - sin(fhi * i) if i.zero? arr[k] = 1.0 - (fhi - flo) / PI else arr[k] = (num / denom) * (0.54 + 0.46 * cos((PI * i) / len)) end end make_fir_filter(arrlen, arr) end add_help(:bandstop, "bandstop(f, in) \ Is the generator corresponding to make_bandstop.") alias bandstop fir_filter # differentiator add_help(:make_differentiator, "make_differentiator(len=30) \ Makes an FIR differentiator (highpass) filter.") def make_differentiator(len = 30) arrlen = len * 2 + 1 arr = make_vct(arrlen) (-len...len).each do |i| k = i + len if i.zero? arr[k] = 0.0 else arr[k] = (cos(PI * i) / i - sin(PI * i) / (PI * i * i)) * (0.54 + 0.46 * cos((PI * i) / len)) end end make_fir_filter(arrlen, arr) end add_help(:differentiator, "differentiator(f, in) \ Is the generator corresponding to make_differentiator.") alias differentiator fir_filter # IIR filters # # Butterworth filters (see also further below -- make-butter-lp et al) # # translated from CLM butterworth.cl: # # Sam Heisz, January 1998 # inspired by some unit generators written for Csound by Paris # Smaragdis who based his work on formulas from Charles Dodge, # Computer music: synthesis, composition, and performance. add_help(:butter, "butter(b, sig) \ Is the generator side for the various make_butter procedure.") alias butter filter add_help(:make_butter_high_pass, "make_butter_high_pass(freq) \ Makes a Butterworth filter with high pass cutoff at FREQ.") def make_butter_high_pass(freq) r = tan(PI * freq / srate()) r2 = r * r c1 = 1.0 / (1.0 + r * sqrt(2.0) + r2) c2 = -2.0 * c1 c3 = c1 c4 = 2.0 * (r2 - 1.0) * c1 c5 = ((1.0 - r * sqrt(2.0)) + r2) * c1 make_filter(3, vct(c1, c2, c3), vct(0.0, c4, c5)) end add_help(:make_butter_low_pass, "make_butter_low_pass(freq) \ Makes a Butterworth filter with high pass cutoff at FREQ. \ The result can be used directly: \ filter_sound(make_butter_low_pass(500.0)), or via the 'butter' generator.") def make_butter_low_pass(freq) r = 1.0 / tan(PI * freq / srate()) r2 = r * r c1 = 1.0 / (1.0 + r * sqrt(2.0) + r2) c2 = 2.0 * c1 c3 = c1 c4 = 2.0 * (1.0 - r2) * c1 c5 = ((1.0 - r * sqrt(2.0)) + r2) * c1 make_filter(3, vct(c1, c2, c3), vct(0.0, c4, c5)) end add_help(:make_butter_band_pass, "make_butter_band_pass(freq, band) \ Makes a bandpass Butterworth filter with low edge at FREQ and width BAND.") def make_butter_band_pass(freq, band) d = 2.0 * cos(2.0 * PI * freq / srate()) c = 1.0 / tan(PI * band / srate()) c1 = 1.0 / (1.0 + c) c2 = 0.0 c3 = -c1 c4 = -c * d * c1 c5 = (c - 1.0) * c1 make_filter(3, vct(c1, c2, c3), vct(0.0, c4, c5)) end add_help(:make_butter_band_reject, "make_butter_band_reject(freq, band) \ Makes a band-reject Butterworth filter with low edge at FREQ and width BAND.") def make_butter_band_reject(freq, band) d = 2.0 * cos(2.0 * PI * freq / srate()) c = tan(PI * band / srate()) c1 = 1.0 / (1.0 + c) c2 = -d * c1 c3 = c1 c4 = c2 c5 = (1.0 - c) * c1 make_filter(3, vct(c1, c2, c3), vct(0.0, c4, c5)) end # from "DSP Filter Cookbook" by Lane et al, Prompt Pubs, 2001 # # use with the filter generator # (define gen (make-iir-high-pass-2 1000)) # (filter gen 1.0) # etc add_help(:make_biquad, "make_biquad(a0, a1, a2, b1, b2) \ Returns a biquad filter (use with the CLM filter gen).") def make_biquad(a0, a1, a2, b1, b2) make_filter(3, vct(a0, a1, a2), vct(0.0, b1, b2)) end # din=(sqrt 2.0) for example (suggested range 0.2...10) def make_iir_low_pass_2(fc, din = false) fc = fc.to_f theta = (TWO_PI * fc) / mus_srate() d = (din or sqrt(2.0)) beta = 0.5 * ((1.0 - (d / 2.0) * sin(theta)) / (1.0 + (d / 2.0) * sin(theta))) gamma = (0.5 + beta) * cos(theta) alpha = 0.5 * (0.5 + beta + -gamma) make_filter(3, vct(alpha, 2.0 * alpha, alpha), vct(0.0, -2.0 * gamma, 2.0 * beta)) end def make_iir_high_pass_2(fc, din = false) fc = fc.to_f theta = (TWO_PI * fc) / mus_srate() d = (din or sqrt(2.0)) beta = 0.5 * ((1.0 - (d / 2.0) * sin(theta)) / (1.0 + (d / 2.0) * sin(theta))) gamma = (0.5 + beta) * cos(theta) alpha = 0.5 * (0.5 + beta + gamma) make_filter(3, vct(alpha, -2.0 * alpha, alpha), vct(0.0, -2.0 * gamma, 2.0 * beta)) end def make_iir_band_pass_2(f1, f2) f1 = f1.to_f f2 = f2.to_f theta = (TWO_PI * sqrt(f1 * f2)) / mus_srate() q = sqrt(f1 * f2) / (f2 - f1) t2 = tan(theta / (2 * q)) beta = 0.5 * ((1.0 - t2) / (1.0 + t2)) gamma = (0.5 + beta) * cos(theta) alpha = 0.5 - beta make_filter(3, vct(alpha, 0.0, -alpha), vct(0.0, -2.0 * gamma, 2.0 * beta)) end def make_iir_band_stop_2(f1, f2) f1 = f1.to_f f2 = f2.to_f theta = (TWO_PI * sqrt(f1 * f2)) / mus_srate() q = sqrt(f1 * f2) / (f2 - f1) t2 = tan(theta / (2 * q)) beta = 0.5 * ((1.0 - t2) / (1.0 + t2)) gamma = (0.5 + beta) * cos(theta) alpha = 0.5 + beta make_filter(3, vct(alpha, -2.0 * gamma, alpha), vct(0.0, -2.0 * gamma, 2.0 * beta)) end def make_eliminate_hum(hum_freq = 60.0, hum_harmonics = 5, bandwidth = 10) b2 = 0.5 * bandwidth make_array(hum_harmonics) do |i| center = (i + 1.0) * hum_freq make_iir_band_stop_2(center - b2, center + b2) end end def eliminate_hum(gens, x0) val = x0 gens.each do |gen| val = filter(gen, val) end val end # bandpass, m is gain at center of peak # use map-channel with this one (not clm-channel or filter) def make_peaking_2(f1, f2, m) f1 = f1.to_f f2 = f2.to_f theta = (TWO_PI * sqrt(f1 * f2)) / mus_srate() q = sqrt(f1 * f2) / (f2 - f1) t2 = (4.0 / (m + 1.0)) * tan(theta / (2 * q)) beta = 0.5 * ((1.0 - t2) / (1.0 + t2)) gamma = (0.5 + beta) * cos(theta) alpha = 0.5 - beta flt = make_filter(3, vct(alpha, 0.0, -alpha), vct(0.0, -2.0 * gamma, 2.0 * beta)) lambda do |x| x + (m - 1.0) * filter(flt, x) end end # convert cascade coeffs to canonical form # from Orfanidis "Introduction to Signal Processing def c2c_conv(m, h, l, x, y) (l + m).times do |i| y[i] = 0.0 ([0, i - (1 + l)].max..[i, m].min).each do |j| y[i] = y[i] + h[j] * x[i - j] end end end add_help(:cascade2canonical, "cascade2canonical(a) \ Converts a list of cascade coeffs (vcts with 3 entries) to canonical form.") def cascade2canonical(a) k = a.length d = make_vct(2 * k + 1) a1 = make_vct(2 * k + 1) a1[0] = 1.0 k.times do |i| c2c_conv(2, a[i], 2 * i + 1, a1, d) (2 * i + 3).times do |j| a1[j] = d[j] end end a1 end # order is M*2, fc is cutoff freq (Hz) add_help(:make_butter_lp, "make_butter_lp(m, fc) \ Returns a butterworth low-pass filter; \ its order is M * 2, FC is the cutoff frequency in Hz.") def make_butter_lp(m, fc) fc = fc.to_f xcoeffs = make_array(m) ycoeffs = make_array(m) theta = (TWO_PI * fc) / mus_srate() st = sin(theta) ct = cos(theta) m.times do |k| d = 2.0 * sin((PI * (2.0 * (k + 1.0) - 1.0)) / (4.0 * m)) beta = 0.5 * ((1.0 - 0.5 * d * st) / (1.0 + 0.5 * d * st)) gamma = ct * (0.5 + beta) alpha = 0.25 * (0.5 + beta + -gamma) xcoeffs[k] = vct(2.0 * alpha, 4.0 * alpha, 2.0 * alpha) ycoeffs[k] = vct(1.0, -2.0 * gamma, 2.0 * beta) end make_filter(2 * m + 1, cascade2canonical(xcoeffs), cascade2canonical(ycoeffs)) end # order is M*2, fc is cutoff freq (Hz) add_help(:make_butter_hp, "make_butter_hp(m, fc) \ Returns a butterworth high-pass filter; \ its order is M * 2, FC is the cutoff frequency in Hz.") def make_butter_hp(m, fc) fc = fc.to_f xcoeffs = make_array(m) ycoeffs = make_array(m) theta = (TWO_PI * fc) / mus_srate() st = sin(theta) ct = cos(theta) m.times do |k| d = 2.0 * sin((PI * (2.0 * (k + 1.0) - 1.0)) / (4.0 * m)) beta = 0.5 * ((1.0 - 0.5 * d * st) / (1.0 + 0.5 * d * st)) gamma = ct * (0.5 + beta) alpha = 0.25 * (0.5 + beta + gamma) xcoeffs[k] = vct(2.0 * alpha, -4 * alpha, 2.0 * alpha) ycoeffs[k] = vct(1.0, -2.0 * gamma, 2.0 * beta) end make_filter(2 * m + 1, cascade2canonical(xcoeffs), cascade2canonical(ycoeffs)) end # order is M*2, f1 and f2 are band edge freqs (Hz) add_help(:make_butter_bp, "make_butter_bp(m, f1, f2) \ Returns a butterworth band-pass filter; \ its order is M * 2, F1 and F2 are the band edge frequencies in Hz.") def make_butter_bp(m, f1, f2) f1 = f1.to_f f2 = f2.to_f xcoeffs = make_array(m) ycoeffs = make_array(m) f0 = sqrt(f1 * f2) q = f0 / (f2 - f1) theta0 = (TWO_PI * f0) / mus_srate() de = (2.0 * tan(theta0 / (2.0 * q))) / sin(theta0) de2 = de / 2.0 tn0 = tan(theta0 * 0.5) k = j = 1 m.times do |i| dk = 2.0 * sin((PI * (2.0 * k - 1.0)) / (2.0 * m)) ak = (1.0 + de2 * de2) / (dk * de2) dk1 = sqrt((de * dk) / (ak + sqrt(ak * ak - 1.0))) bk = de2 * (dk / dk1) wk = (bk + sqrt(bk * bk - 1.0)).real thetajk = ((j == 1) ? (2.0 * atan(tn0 / wk)) : (2.0 * atan(tn0 * wk))) betajk = 0.5 * ((1.0 - 0.5 * dk1 * sin(thetajk)) / (1.0 + 0.5 * dk1 * sin(thetajk))) gammajk = (0.5 + betajk) * cos(thetajk) wk2 = (wk - 1.0 / wk) / dk1 alphajk = 0.5 * (0.5 - betajk) * sqrt(1.0 + wk2 * wk2) xcoeffs[i] = vct(2.0 * alphajk, 0.0, -2.0 * alphajk) ycoeffs[i] = vct(1.0, -2.0 * gammajk, 2.0 * betajk) if j == 1 j = 2 else k += 1 j = 1 end end make_filter(2 * m + 1, cascade2canonical(xcoeffs), cascade2canonical(ycoeffs)) end # order is M*2, f1 and f2 are band edge freqs (Hz) add_help(:make_butter_bs, "make_butter_bs(m, f1, f2) \ Returns a butterworth band-stop filter; \ its order is M * 2, F1 and F2 are the band edge frequencies in Hz.") def make_butter_bs(m, f1, f2) f1 = f1.to_f f2 = f2.to_f xcoeffs = make_array(m) ycoeffs = make_array(m) f0 = sqrt(f1 * f2) q = f0 / (f2 - f1) theta0 = (TWO_PI * f0) / mus_srate() de = (2.0 * tan(theta0 / (2.0 * q))) / sin(theta0) de2 = de / 2.0 ct = cos(theta0) tn0 = tan(theta0 * 0.5) k = j = 1 m.times do |i| dk = 2.0 * sin((PI * (2.0 * k - 1.0)) / (2.0 * m)) ak = (1.0 + de2 * de2) / (dk * de2) dk1 = sqrt((de * dk) / (ak + sqrt(ak * ak - 1.0))) bk = de2 * (dk / dk1) wk = (bk + sqrt(bk * bk - 1.0)).real thetajk = ((j == 1) ? (2.0 * atan(tn0 / wk)) : (2.0 * atan(tn0 * wk))) betajk = 0.5 * ((1.0 - 0.5 * dk1 * sin(thetajk)) / (1.0 + 0.5 * dk1 * sin(thetajk))) gammajk = (0.5 + betajk) * cos(thetajk) alphajk = 0.5 * (0.5 + betajk) * ((1.0 - cos(thetajk)) / (1.0 - ct)) xcoeffs[i] = vct(2.0 * alphajk, -4.0 * ct * alphajk, 2.0 * alphajk) ycoeffs[i] = vct(1.0, -2.0 * gammajk, 2.0 * betajk) if j == 1 j = 2 else k += 1 j = 1 end end make_filter(2 * m + 1, cascade2canonical(xcoeffs), cascade2canonical(ycoeffs)) end # notch filters def make_notch_frequency_response(cur_srate, freqs, notch_width = 2) cur_srate = cur_srate.to_f notch_width = notch_width.to_f freq_response = [0.0, 1.0] freqs.each do |f| # left upper y hz freq_response.push((2.0 * (f - notch_width)) / cur_srate) # left upper y resp freq_response.push(1.0) # left bottom y hz freq_response.push((2.0 * (f - notch_width / 2.0)) / cur_srate) # left bottom y resp freq_response.push(0.0) # right bottom y hz freq_response.push((2.0 * (f + notch_width / 2.0)) / cur_srate) # right bottom y resp freq_response.push(0.0) # right upper y hz freq_response.push((2.0 * (f + notch_width)) / cur_srate) # right upper y resp freq_response.push(1.0) end freq_response.push(1.0, 1.0) end add_help(:notch_channel, "notch_channel(freqs, order=false, beg=false, dur=false, \ snd=false, chn=false, edpos=false, trunc=true, notch_width=2) \ Returns notch filter removing freqs.") def notch_channel(freqs, filter_order = false, beg = false, dur = false, snd = false, chn = false, edpos = false, truncate = true, notch_width = 2) sr = srate(snd).to_f lm = [framples(snd, chn), 2 ** (log(sr / notch_width) / log(2.0)).floor].min filter_channel(make_notch_frequency_response(sr, freqs, notch_width), (filter_order or lm), beg, dur, snd, chn, edpos, truncate, format("%s(%p, %s, %s, %s", get_func_name, freqs, filter_order, beg, dur)) end add_help(:notch_sound, "notch_sound(freqs, order=false, \ snd=false, chn=false, notch_width=2) \ Returns notch filter removing freqs.") def notch_sound(freqs, filter_order = false, snd = false, chn = false, notch_width = 2) sr = srate(snd).to_f lm = [framples(snd, chn), 2 ** (log(sr / notch_width) / log(2.0)).floor].min filter_sound(make_notch_frequency_response(sr, freqs, notch_width), (filter_order or lm), snd, chn, false, format("%s(%p, %s, 0, false", get_func_name, freqs, filter_order)) end add_help(:notch_selection, "notch_selection(freqs, order=false, notch_width=2) \ Returns notch filter removing freqs.") def notch_selection(freqs, filter_order = false, snd = false, chn = false, notch_width = 2) if selection? sr = selection_srate.to_f fr = selection_framples() lm = [fr, 2 ** (log(sr / notch_width) / log(2.0)).floor].min filter_selection(make_notch_frequency_response(sr, freqs, notch_width), (filter_order or lm)) end end # fractional Fourier Transform, z transform # # translated from the fxt package of Joerg Arndt add_help(:fractional_fourier_transform, "fractional_fourier_transform(real, imaginary, n, angle) \ Performs a fractional Fourier transform on data; \ if angle=1.0, you get a normal Fourier transform.") def fractional_fourier_transform(fr, fi, n, v) hr = make_vct(n) hi = make_vct(n) ph0 = (v * TWO_PI) / n n.times do |w| sr = 0.0 si = 0.0 n.times do |k| phase = ph0 * k * w c = cos(phase) s = sin(phase) x = fr[k] y = fi[k] r = x * c - y * s i = y * c + x * s sr += r si += i hr[w] = sr hi[w] = si end end [hr, hi] end # using vector to allow complex sums (z=e^2*pi*i/n -> fourier transform) # z_transform(data, n, exp(Complex(0.0, (2.0 / n) * PI))) add_help(:z_transform, "z_transform(data, n, z) \ Performs a Z transform on data; \ if z=e^2*pi*j/n you get a Fourier transform; \ complex results in returned vector.") def z_transform(f, n, z) make_array(n) do |w| sum = 0.0 t = 1.0 m = z ** w n.times do |k| sum = sum + f[k] * t t *= m end sum end end # slow Hartley transform # # taken from Perry Cook's SignalProcessor.m (the slow version of the # Hartley transform) add_help(:dht, "dht(data) \ Returns the Hartley transform of DATA.") def dht(data) len = data.length arr = make_vct(len) w = TWO_PI / len len.times do |i| data.each_with_index do |val, j| arr[i] = arr[i] + val * (cos(i * j * w) + sin(i * j * w)) end end arr end add_help(:find_sine, "find_sine(freq, beg, dur, snd=false) \ Returns the amplitude and initial-phase (for sin) at FREQ between BEG and DUR.") def find_sine(freq, beg, dur, snd = false) incr = (TWO_PI * freq) / srate(snd) sw = 0.0 cw = 0.0 reader = make_sampler(beg, snd) dur.times do |i| samp = next_sample(reader) inc = i * incr sw = sw + samp * sin(inc) cw = cw + samp * cos(inc) end [2.0 * (sqrt(sw * sw + cw * cw) / dur), atan2(cw, sw)] end # this is a faster version of find-sine using the "Goertzel algorithm" # taken from R Lyons "Understanding DSP" p 529 # it returns the same result as find_sine above if you take (* 2 (/ # (goertzel...) dur)) -- see snd-test.rb examples add_help(:goertzel, "goertzel(freq, beg=0, dur=false, snd=false) \ Returns the amplitude of the FREQ spectral component.") def goertzel(freq, beg = 0, dur = false, snd = false) y0 = 0.0 y1 = 0.0 y2 = 0.0 rfreq = (TWO_PI * freq) / srate(snd) cs = 2.0 * cos(rfreq) scan_channel(lambda do |y| y2, y1 = y1, y0 y0 = (y1 * cs - y2) + y false end, beg, (dur or framples(snd)), snd) (y0 - y1 * exp(Complex(0.0, -rfreq))).abs end add_help(:make_spencer_filter, "make_spencer_filter() \ Is a version of make_fir_filter; \ it returns one of the standard smoothing filters from \ the era when computers were human beings.") def make_spencer_filter data = vct(-3, -6, -5, 3, 21, 46, 67, 74, 67, 46, 21, 3, -5, -6, -3) data.map! do |n| n / 320.0 end make_fir_filter(data.length, data) end # any-random # # arbitrary random number distributions via the "rejection method" def any_random(amount, e = false) if amount.zero? 0.0 else unless e random(amount) else next_random = lambda do | | len = e.length x = random(e[len - 2].to_f) y = random(1.0) if y <= envelope_interp(x, e) x else next_random.call end end.call end end end def gaussian_distribution(s) e = [] den = 2.0 * s * s x = 0.0 y = -4.0 21.times do |i| e.push(exp(-((y * y) / den))) e.push(x) x += 0.05 y += 0.4 end e end def pareto_distribution(a) e = [] scl = 1.0 ** (a + 1.0) / a x = 0.0 y = 1.0 21.times do |i| e.push(scl * (a / y ** (a + 1.0))) e.push(x) x += 0.05 y += 0.2 end e end # uniform distribution # map_channel(lambda do |y| any_random(1.0, [0, 1, 1, 1])) # mostly toward 1.0 # map_channel(lambda do |y| any_random(1.0, [0, 0, 0.95, 0.1, 1, 1])) # let(gaussian-distribution(1.0)) do |g| # map_channel(lambda do |y| any_random(1.0, g)) # end # let(pareto-distribution(1.0)) do |g| # map_channel(lambda do |y| any_random(1.0, g)) # end # this is the inverse integration function used by CLM to turn a # distribution function into a weighting function def inverse_integrate(dist, data_size = 512, e_size = 50) first_sum = sum = dist[1].to_f x0 = dist[0].to_f x1 = dist[-2].to_f xincr = (x1 - x0) / e_size.to_f x = x0 e = make_array(e_size * 2) 0.step(e_size * 2 - 1, 2) do |i| e[i + 1] = x e[i] = sum sum += envelope_interp(x, dist) x += xincr end incr = (e[-2] - first_sum) / (data_size - 1) x = first_sum - incr make_vct!(data_size) do x += incr envelope_interp(x, e) end end def gaussian_envelope(s) den = 2.0 * s * s x = -1.0 y = -4.0 e = make_array(42) 0.step(41, 2) do |i| e[i] = x e[i + 1] = exp(-((y * y) / den)) x += 0.1 y += 0.4 end e end # make_rand(:envelope, gaussian-envelope(1.0)) # Julius Smith stuff # # these are from "Mathematics of the DFT", W3K Pubs add_help(:channel_mean, "channel_mean(snd, chn) \ Returns the average of the samples in the given channel: /n") def channel_mean(snd, chn) sum = 0.0 n = framples(snd, chn) scan_channel(lambda do |y| sum += y false end, 0, n, snd, chn) sum / n end add_help(:channel_total_energy, "channel_total_energy(snd, chn) \ Returns the sum of the squares of all the samples in the given channel: ") def channel_total_energy(snd, chn) sum = 0.0 scan_channel(lambda do |y| sum = sum + y * y false end, 0, framples(snd, chn), snd, chn) sum end add_help(:channel_average_power, "channel_average_power(snd, chn) \ Returns the average power in the given channel: /n") def channel_average_power(snd, chn) channel_total_energy(snd, chn) / framples(snd, chn) end add_help(:channel_rms, "channel_rms(snd, chn) \ Returns the RMS value of the samples in the given channel: sqrt(/n)") def channel_rms(snd, chn) sqrt(channel_average_power(snd, chn)) end add_help(:channel_variance, "channel_variance(snd, chn) \ Returns the sample variance in the given channel: -((/ n)^2") def channel_variance(snd, chn) n = framples(snd, chn).to_f mu = (n / (n - 1.0)) * channel_mean(snd, chn) p = channel_total_energy(snd, chn) p - mu * mu end add_help(:channel_norm, "channel_norm(snd, chn) \ Returns the norm of the samples in the given channel: sqrt()") def channel_norm(snd, chn) sqrt(channel_total_energy(snd, chn)) end add_help(:channel_lp, "channel_lp(p, snd, chn) \ Returns the Lp norm of the samples in the given channel.") def channel_lp(lp, snd, chn) sum = 0.0 scan_channel(lambda do |y| sum = sum + y.abs ** lp false end, 0, framples(snd, chn), snd, chn) sum ** (1.0 / lp) end add_help(:channel_lp_inf, "channel_lp_inf(snd, chn) \ Returns the maxamp in the given channel (the name is \ just math jargon for maxamp).") def channel_lp_inf(snd, chn) mx = 0.0 scan_channel(lambda do |y| mx = [mx, y.abs].max false end, 0, framples(snd, chn), snd, chn) mx end add_help(:channel2_inner_product, "channel2_inner_product(s1, c1, s2, c2) \ Returns the inner-product of the two channels: ") def channel2_inner_product(s1, c1, s2, c2) sum = 0.0 r1 = make_sampler(0, s1, c1) r2 = make_sampler(0, s2, c2) framples(s1, c1).times do |i| sum = sum + r1.call * r2.call end sum end add_help(:channel2_angle, "channel2_angle(s1, c1, s2, c2) \ Treats the two channels as vectors, \ returning the ANGLE between them: acos(/(sqrt()*sqrt()))") def channel2_angle(s1, c1, s2, c2) inprod = channel2_inner_product(s1, c1, s2, c2) norm1 = channel_norm(s1, c1) norm2 = channel_norm(s2, c2) acos(inprod / (norm1 * norm2)) end if defined? acos add_help(:channel2_orthogonal?, "channel2_orthogonal?(s1, c1, s2, c2) \ Returns true if the two channels' inner-product is 0: ==0") def channel2_orthogonal?(s1, c1, s2, c2) channel2_inner_product(s1, c1, s2, c2).zero? end add_help(:channel2_coefficient_of_projection, "channel2_coefficient_of_projection(s1, c1, s2, c2) \ Returns /") def channel2_coefficient_of_projection(s1, c1, s2, c2) channel2_inner_product(s1, c1, s2, c2) / channel_total_energy(s1, c1) end # end of JOS stuff add_help(:channel_distance, "channel_distance(s1, c1, s2, c2) \ Returns the euclidean distance between the two channels: sqrt()") def channel_distance(s1, c1, s2, c2) r1 = make_sampler(0, s1, c1) r2 = make_sampler(0, s2, c2) sum = 0.0 [framples(s1, c1), framples(s2, c2)].min.times do diff = r1.call - r2.call sum = sum + diff * diff end sqrt(sum) end add_help(:periodogram, "periodogram(n) \ Displays an N point Bartlett periodogram of the samples in the current channel") def periodogram(n) len = framples() average_data = make_vct(n) rd = make_sampler(0) n2 = n * 2 rl = make_vct(n2) im = make_vct(n2) len.times do vct_scale!(rl, 0.0) vct_scale!(im, 0.0) n.times do |k| rl[k] = rd.call end mus_fft(rl, im) n.times do |k| average_data[k] = average_data[k] + rl[k] * rl[k] + im[k] * im[k] end end graph(vct_scale!(average_data, 1.0 / (len.to_f / n).ceil)) end # ssb-am friends add_help(:shift_channel_pitch, "shift_channel_pitch(freq, order=40, beg=0, dur=false, \ snd=false, chn=false, edpos=false) \ Uses the ssb-am CLM generator to shift the given channel \ in pitch without changing its length. \ The higher ORDER, the better usually.") def shift_channel_pitch(freq, order = 40, beg = 0, dur = false, snd = false, chn = false, edpos = false) gen = make_ssb_am(freq, order) map_channel(lambda do |y| ssb_am(gen, y) end, beg, dur, snd, chn, edpos, format("%s(%s, %s, %s, %s", get_func_name, freq, order, beg, dur)) end add_help(:hz_to_2pi, "hz_to_2pi(freq) \ Is like hz2radians but uses the current sound's srate, not mus_srate.") def hz_to_2pi(freq) (TWO_PI * freq) / srate() end def ssb_bank(old_freq, new_freq, pairs, order = 40, bw = 50.0, beg = 0, dur = false, snd = false, chn = false, edpos = false) factor = (new_freq - old_freq.to_f) / old_freq mx = maxamp ssbs = make_array(pairs) bands = make_array(pairs) do |i| aff = (i + 1.0) * old_freq bwf = bw * (1.0 + (i + 1.0) / (2.0 * pairs)) ssbs[i] = make_ssb_am((i + 1.0) * factor * old_freq) make_bandpass(hz_to_2pi(aff - bwf), hz_to_2pi(aff + bwf), order) end as_one_edit_rb("%s(%s, %s, %s, %s, %s, %s, %s", get_func_name, old_freq, new_freq, pairs, order, bw, beg, dur) do | | nmx = 0.0 map_channel_rb(beg, dur, snd, chn, edpos) do |y| sum = 0.0 ssbs.zip(bands) do |sbs, bds| sum += ssb_am(sbs, bandpass(bds, y)) end nmx = [nmx, sum.abs].max sum end scale_channel(mx / nmx, beg, dur, snd, chn) end end # this version adds a frequency envelope # ssb_bank_env(557, 880, [0, 0, 1, 100.0], 7) def ssb_bank_env(old_freq, new_freq, freq_env, pairs, order = 40, bw = 50.0, beg = 0, dur = false, snd = false, chn = false, edpos = false) factor = (new_freq - old_freq.to_f) / old_freq mx = maxamp ssbs = make_array(pairs) frenvs = make_array(pairs) bands = make_array(pairs) do |i| aff = (i + 1.0) * old_freq bwf = bw * (1.0 + (i + 1.0) / (2.0 * pairs)) ssbs[i] = make_ssb_am((i + 1.0) * factor * old_freq) frenvs[i] = make_env(:envelope, freq_env, :scaler, hz2radians(i.to_f), :length, framples(snd, chn) - 1) make_bandpass(hz_to_2pi(aff - bwf), hz_to_2pi(aff + bwf), order) end as_one_edit_rb("%s(%s, %s, %s, %s, %s, %s, %s, %s", get_func_name, old_freq, new_freq, freq_env.inspect, pairs, order, bw, beg, dur) do | | nmx = 0.0 map_channel_rb(beg, dur, snd, chn, edpos) do |y| sum = 0.0 ssbs.each_with_index do |sbs, i| sum += ssb_am(sbs, bandpass(bands[i], y), env(frenvs[i])) end nmx = [nmx, sum.abs].max sum end scale_channel(mx / nmx, beg, dur, snd, chn) end end #vct|channel|spectral-polynomial def vct_polynomial(v, coeffs) new_v = Vct.new(v.length, coeffs.last) (coeffs.length - 2).downto(0) do |i| new_v.multiply!(v).offset!(coeffs[i]) end new_v end def channel_polynomial(coeffs, snd = false, chn = false) len = framples(snd, chn) v = channel2vct(0, len, snd, chn) vct2channel(vct_polynomial(v, coeffs), 0, len, snd, chn, false, format("%s(%s", get_func_name, coeffs.to_str)) end # channel_polynomial(vct(0.0, 0.5)) = x*0.5 # channel_polynomial(vct(0.0, 1.0, 1.0, 1.0)) = x*x*x + x*x + x # # convolution -> * in freq def spectral_polynomial(coeffs, snd = false, chn = false) len = framples(snd, chn) sound = channel2vct(0, len, snd, chn) num_coeffs = coeffs.length fft_len = if num_coeffs < 2 len else (2.0 ** (log((num_coeffs - 1.0) * len) / log(2.0)).ceil).to_i end rl1 = make_vct(fft_len) rl2 = make_vct(fft_len) new_sound = make_vct(fft_len) if coeffs[0] > 0.0 new_sound.map! do mus_random(coeffs[0]) end end if num_coeffs > 1 new_sound.add!(sound.scale(coeffs[1])) if num_coeffs > 2 peak = maxamp(snd, chn) rl1.scale!(0.0).add!(sound) (2...num_coeffs).each do |i| convolution(rl1, rl2.scale!(0.0).add(sound), fft_len) new_sound.add!(rl1.scale((coeffs[i] * peak) / rl1.peak)) end new_sound.scale!(peak / new_sound.peak) end end vct2channel(new_sound, 0, [len, len * (num_coeffs - 1)].max, snd, chn, false, format("%s(%s", get_func_name, coeffs.to_str)) end # SCENTROID # # by Bret Battey # Version 1.0 July 13, 2002 # translated to Snd/Scheme Bill S 19-Jan-05 # # Returns the continuous spectral centroid envelope of a sound. The # spectral centroid is the "center of gravity" of the spectrum, and it # has a rough correlation to our sense of "brightness" of a sound. # # [Beauchamp, J., "Synthesis by spectral amplitude and 'brightness' matching # analyzed musical sounds". # Journal of Audio Engineering Society 30(6), 396-406] # # The formula used is: # C = [SUMF(n)A(n)] / [SUMA(n)] # Where j is the number of bins in the analysis, # F(n) is the frequency of a given bin, # A(n) is the magnitude of the given bin. # # If a pitch envelope for the analyzed sound is available, the results # of SCENTROID can be used with the function NORMALIZE-CENTROID, # below, to provide a "normalized spectral centroid". # # DB-FLOOR -- Frames below this decibel level (0 dB = max) will be # discarded and returned with spectral centroid = 0 # # RFREQ -- Rendering frequency. Number of measurements per second. # # FFTSIZE -- FFT window size. Must be a power of 2. 4096 is # recommended. add_help(:scentroid, "scentroid(file, beg=0, dur=false, db_floor=-40, \ rfreq=100, fftsize=4096) \ Returns the spectral centroid envelope of a sound; \ RFREQ is the rendering frequency, the number of measurements per second; \ DB_FLOOR is the level below which data will be ignored.") def scentroid(file, beg = 0.0, dur = false, db_floor = -40, rfreq = 100.0, fftsize = 4096) assert_type(File.exist?(file), file, 0, "an existing file") fsr = srate(file) incrsamps = (fsr / rfreq).floor start = (beg * fsr).floor ende = (start + (dur ? (dur * fsr).floor : (framples(file) - beg))).floor fdr = make_vct(fftsize) fdi = make_vct(fftsize) windows = ((ende - start) / incrsamps).floor + 1 results = make_vct(windows) fft2 = (fftsize / 2.0).floor binwidth = fsr / fftsize.to_f rd = make_readin(file) loc = 0 start.step(ende, incrsamps) do |i| rd.location = i sum_of_squares = 0.0 fdr.map! do val = readin(rd) sum_of_squares = sum_of_squares + val * val val end if linear2db(sqrt(sum_of_squares / fftsize.to_f)) >= db_floor numsum = 0.0 densum = 0.0 fdi.map! do |x| 0.0 end mus_fft(fdr, fdi, fftsize) rectangular2polar(fdr, fdi) fft2.times do |j| numsum = numsum + j * binwidth * fdr[j] densum += fdr[j] end results[loc] = numsum / densum end loc += 1 end results end # invert_filter inverts an FIR filter # # say we previously filtered a sound via filter_channel(vct(0.5, 0.25, 0.125)) # and we want to undo it without using undo_edit: # filter_channel(invert_filter(vct(0.5, 0.25, 0.125))) # # there are a million gotchas here. The primary one is that the inverse # filtercan "explode" -- the coefficients can grow without bound. For # example, any filter returned by spectrum2coeffs above will be a problem # (it always returns a "linear phase" filter). add_help(:invert_filter, "invert_filter(coeffs) \ Tries to return an inverse filter to undo the effect of the FIR filter coeffs.") def invert_filter(fcoeffs) order = fcoeffs.length + 32 coeffs = Vct.new(order) fcoeffs.each_with_index do |val, i| coeffs[i] = val end nfilt = Vct.new(order) nfilt[0] = 1.0 / coeffs.first (1...order).each do |i| sum = 0.0 k = i i.times do |j| sum = sum + nfilt[j] * coeffs[k] k -= 1 nfilt[i] = sum / -coeffs.first end end nfilt end # Volterra filter # # one of the standard non-linear filters # this version is taken from Monson Hayes "Statistical DSP and Modeling" # it is a slight specialization of the form mentioned by J O Smith and others class Volterra_filter < Musgen def initialize(acoeffs, bcoeffs) super() @as = acoeffs @bs = bcoeffs @xs = Vct.new([acoeffs.length, bcoeffs.length].max) end def inspect format("%s.new(%s, %s)", self.class, @as.to_str, @bs.to_str) end def to_s format("#<%s acoeffs: %s, bcoeffs: %s>", self.class, @as, @bs) end def run_func(val1 = 0.0, val2 = 0.0) volterra_filter(val1) end def volterra_filter(x) xlen = @xs.length @xs.move!(xlen - 1, xlen - 2, true) @xs.first = x sum = dot_product(@as, @xs, @as.length) @bs.length.times do |i| @bs.length.times do |j| sum = sum + @bs[j] * @xs[i] * @xs[j] end end sum end end add_help(:make_volterra_filter, "make_volterra_filter(acoeffs, bcoeffs) \ Returns a list for use with volterra-filter, \ producing one of the standard non-linear filters.") def make_volterra_filter(acoeffs, bcoeffs) Volterra_filter.new(acoeffs, bcoeffs) end add_help(:volterra_filter, "volterra_filter(flt, x) \ Takes FLT, a Volterra_filter object returned by make_volterra_filter, \ and an input X, and returns the (non-linear filtered) result.") def volterra_filter(flt, x) flt.volterra_filter(x) end # flt = make_volterra_filter(vct(0.5, 0.1), vct(0.3, 0.2, 0.1)) # map_channel(lambda do |y| volterra_filter(flt, y) end) # moving-sum generator (the sum norm or 1-norm) add_help(:make_moving_sum, "make_moving_sum(size=128) \ Returns a moving-sum generator. \ The generator keeps a running window of the last SIZE inputs, \ returning the sum of the absolute values of the samples in that window.") def make_moving_sum(size = 128) gen = make_moving_average(size) gen.increment = 1.0 gen end add_help(:moving_sum, "moving_sum(gen, y) \ Returns the sum of the absolute values in a moving \ window over the last few inputs.") def moving_sum(gen, y) moving_average(gen, y.abs) end def make_unmoving_sum() make_one_pole(1.0, -1.0) end alias unmoving_sum one_pole # moving-rms generator add_help(:make_moving_rms, "make_moving_rms(size=128) \ Returns a moving-rms generator. \ The generator keeps a running window of the last SIZE inputs, \ returning the rms of the samples in that window.") def make_moving_rms(size = 128) make_moving_average(size) end add_help(:moving_rms, "moving_rms(gen, y) \ Returns the rms of the values in a window over the last few inputs.") def moving_rms(gen, y) sqrt([0.0, moving_average(gen, y * y)].max) end # moving-length generator (euclidean norm or 2-norm) add_help(:make_moving_length, "make_moving_length(size=128) \ Returns a moving-length generator. \ The generator keeps a running window of the last SIZE inputs, \ returning the euclidean length of the vector in that window.") alias make_moving_length make_moving_sum add_help(:moving_length, "moving_length(gen, y) \ Returns the length of the values in a window over the last few inputs.") alias moving_length moving_rms # harmonicizer # (each harmonic is split into a set of harmonics via Chebyshev polynomials) # obviously very similar to ssb_bank above, but splits harmonics # individually, rather than pitch-shifting them add_help(:harmonicizer, "harmonicizer(freq, coeffs, pairs, order=40, bw=50.0, \ beg=0, dur=false, snd=false, chn=false, edpos=false) \ Splits out each harmonic and replaces it with the spectrum given in coeffs.") def harmonicizer(freq, coeffs, pairs, order = 40, bw = 50.0, beg = 0, dur = false, snd = false, chn = false, edpos = false) bands = make_array(pairs) pcoeffs = partials2polynomial(coeffs) avgs = make_array(pairs) peaks = make_array(pairs) flt = make_filter(2, vct(1, -1), vct(0, -0.9)) old_mx = maxamp new_mx = 0.0 ctr = 40 1.upto(pairs) do |i| aff = i * freq bwf = bw * (1.0 + i / (2 * pairs)) peaks[i - 1] = make_moving_max(128) avgs[i - 1] = make_moving_average(128) bands[i - 1] = make_bandpass(hz_to_2pi(aff - bwf), hz_to_2pi(aff + bwf), order) end as_one_edit_rb do map_channel_rb(beg, dur, snd, chn, edpos) do |y| sum = 0.0 bands.zip(peaks, avgs) do |bs, ps, as| sig = bandpass(bs, y) mx = moving_max(ps, sig) amp = moving_average(as, mx > 0.0 ? [100.0, 1.0 / mx].min : 0.0) if amp > 0.0 sum = sum + mx * polynomial(pcoeffs, amp * sig) end end val = filter(flt, sum) new_mx = [new_mx, val.abs].max if ctr.zero? val else ctr -= 1 0.0 end end if new_mx > 0.0 scale_channel(old_mx / new_mx, beg, dur, snd, chn) end end end # linear sampling rate conversion add_help(:linear_src_channel, "linear_src_channel(sr, snd=false, chn=false) \ Performs sampling rate conversion using linear interpolation.") def linear_src_channel(srinc, snd = false, chn = false) rd = make_sampler(0, snd, chn) last = rd.call nxt = rd.call intrp = 0.0 tempfile = with_sound(:clm, true, :output, snd_tempnam, :srate, srate(snd)) do samp = 0 until sampler_at_end?(rd) if (pos = intrp) >= 1.0 pos.floor.times do |i| last, nxt = nxt, rd.call end pos -= pos.floor end intrp = pos + pos.floor out_any(samp, last + pos * (nxt - last), 0, $output) samp += 1 end end.output len = mus_sound_framples(tempfile) set_samples(0, len - 1, tempfile, snd, chn, true, "%s(%s", get_func_name, srinc, 0, false, true) # first true=truncate to new length, false=at current edpos, # true=auto delete temp file end # Mathews/Smith High-Q filter as described in # http://ccrma.stanford.edu/~jos/smac03maxjos/ class Mfilter < Musgen def initialize(decay, freq) super() @decay = decay.to_f @frequency = freq.to_f @eps = 2.0 * sin((PI * freq) / mus_srate()) @xn = @yn = 0.0 end attr_accessor :decay, :eps def inspect format("%s.new(%0.3f, %0.3f)", self.class, @decay, @frequency) end def to_s format("#<%s decay: %0.3f, frequency: %0.3f>", self.class, @decay, @frequency) end def mfilter(x_input = 0.0, y_input = 0.0) @xn = x_input + @decay * (@xn - @eps * @yn) @yn = y_input + @decay * (@eps * @xn + @yn) end end def make_mfilter(*args) Mfilter.new(get_args(args, :decay, 0.99), get_args(args, :frequency, 1000.0)) end def mfilter(m, x_input = 0.0, y_input = 0.0) m.mfilter(x_input, y_input) end =begin with_sound(:clm, true) do rd = make_sampler(0, "now.snd") m = make_mfilter 10000.times do |i| outa(i, mfilter(m, 0.1 * rd.call), $output) end end =end # # sweep center freq: =begin with_sound(:clm, true) do rd = make_sampler(0, "oboe.snd") m = make_mfilter(:decay, 0.99, :frequency, 1000) e = make_env([0, 100, 1, 2000], :length, 10000) 10000.times do |i| outa(i, mfilter(m, 0.1 * rd.call), $output) m.eps = 2.0 * sind((PI * env(e)) / mus_srate()) end end =end # # harmonics: =begin with_sound(:clm, true, :statistics, true) do noi = make_rand(10000) filters = make_array(9) do make_mfilter(:decay, 0.999, :frequency, 400.0 * (i + 1)) end 10000.times do |i| sum = 0.0 input = 0.01 * rand(noi) filters.each do |f| sum = sum + (1.0 / (j + 1)) * mfilter(f, input) end outa(i, sum $output) end end =end # # spectrum displayed in various frequency scales # class Display_bark_fft # click in lisp-graph to change the tick placement choice def initialize @bark_fft_size = 0 @bark_tick_function = 0 end attr_reader :bark_tick_function def display_bark_fft(snd, chn) ls = left_sample(snd, chn) rs = right_sample(snd, chn) fftlen = (2 ** (log((rs - ls) + 1.0) / log(2.0)).ceil.to_i).to_i if fftlen > 0 data = channel2vct(ls, fftlen, snd, chn) normalized = (transform_normalization(snd, chn) != Dont_normalize) linear = true if vct?(data) fft = snd_spectrum(data, fft_window(snd, chn), fftlen, linear, fft_window_beta(snd, chn), false, normalized) if vct?(fft) sr = srate(snd) mx = fft.peak data_len = fft.length # bark settings bark_low = bark(20.0).floor bark_high = bark(0.5 * sr).ceil bark_frqscl = data_len / (bark_high - bark_low) bark_data = Vct.new(data_len) # mel settings mel_low = mel(20.0).floor mel_high = mel(0.5 * sr).ceil mel_frqscl = data_len / (mel_high - mel_low) mel_data = Vct.new(data_len) # erb settings erb_low = erb(20.0).floor erb_high = erb(0.5 * sr).ceil erb_frqscl = data_len / (erb_high - erb_low) erb_data = Vct.new(data_len) @bark_fft_size = fftlen fftlenf = fftlen.to_f fft.each_with_index do |val, i| frq = sr * (i / fftlenf) bark_bin = (bark_frqscl * (bark(frq) - bark_low)).round mel_bin = (mel_frqscl * (mel(frq) - mel_low)).round erb_bin = (erb_frqscl * (erb(frq) - erb_low)).round if bark_bin.between?(0, data_len - 1) bark_data[bark_bin] += val end if mel_bin.between?(0, data_len - 1) mel_data[mel_bin] += val end if erb_bin.between?(0, data_len - 1) erb_data[erb_bin] += val end end if normalized bmx = bark_data.peak mmx = mel_data.peak emx = erb_data.peak if (mx - bmx).abs > 0.01 bark_data.scale!(mx / bmx) end if (mx - mmx).abs > 0.01 mel_data.scale!(mx / mmx) end if (mx - emx).abs > 0.01 erb_data.scale!(mx / emx) end end graph([bark_data, mel_data, erb_data], "ignored", 20.0, 0.5 * sr, 0.0, (normalized ? 1.0 : data_len * y_zoom_slider(snd, chn)), snd, chn, false, Show_bare_x_axis) end end end false end def mark_bark_labels(snd, chn) # at this point the x axis has no markings, but there is room # for labels and ticks old_foreground_color = foreground_color(snd, chn, Copy_context) # assume at start the foreground color is correct axinfo = axis_info(snd, chn, Lisp_graph) axis_x0 = axinfo[10] axis_x1 = axinfo[12] axis_y0 = axinfo[13] axis_y1 = axinfo[11] label_height = 15 char_width = 8 sr2 = 0.5 * srate(snd) minor_tick_len = 6 major_tick_len = 12 tick_y0 = axis_y1 minor_y0 = axis_y1 + minor_tick_len major_y0 = axis_y1 + major_tick_len bark_label_font = snd_font(3) bark_numbers_font = snd_font(2) label_pos = (axis_x0 + 0.45 * (axis_x1 - axis_x0)).to_i cr = make_cairo(channel_widgets(snd, chn)[0]) scale_position = lambda do |scale, f| b20 = scale.call(20.0) (axis_x0 + ((axis_x1 - axis_x0) * (scale.call(f) - b20)) / (scale.call(sr2) - b20)).round end bark_position = lambda do |f| scale_position.call(method(:bark).to_proc, f) end mel_position = lambda do |f| scale_position.call(method(:mel).to_proc, f) end erb_position = lambda do |f| scale_position.call(method(:erb).to_proc, f) end draw_bark_ticks = lambda do |bark_function| if bark_numbers_font set_current_font(bark_numbers_font, snd, chn, Copy_context) end draw_line(axis_x0, tick_y0, axis_x0, major_y0, snd, chn, Copy_context, cr) i1000 = scale_position.call(bark_function, 1000.0) i10000 = scale_position.call(bark_function, 10000.0) draw_line(i1000, tick_y0, i1000, major_y0, snd, chn, Copy_context, cr) draw_line(i10000, tick_y0, i10000, major_y0, snd, chn, Copy_context, cr) draw_string("20", axis_x0, major_y0, snd, chn, Copy_context, cr) draw_string("1000", i1000 - 3 * 4, major_y0, snd, chn, Copy_context, cr) draw_string("10000", i10000 - 6 * 4, major_y0, snd, chn, Copy_context, cr) draw_string("fft size: #{@bark_fft_size}", axis_x0 + 10, axis_y0, snd, chn, Copy_context, cr) 100.step(1000, 100) do |i| i100 = scale_position.call(bark_function, i) draw_line(i100, tick_y0, i100, minor_y0, snd, chn, Copy_context, cr) end 2000.step(10000, 1000) do |i| i1000 = scale_position.call(bark_function, i) draw_line(i1000, tick_y0, i1000, minor_y0, snd, chn, Copy_context, cr) end end # bark label/ticks if self.bark_tick_function.zero? draw_bark_ticks.call(bark_position) end if bark_label_font set_current_font(bark_label_font, snd, chn, Copy_context) end draw_string("bark,", label_pos, axis_y1 + label_height, snd, chn, Copy_context, cr) # mel label/ticks set_foreground_color(snd_color(2), snd, chn, Copy_context) if self.bark_tick_function == 1 draw_bark_ticks.call(mel_position) end if bark_label_font set_current_font(bark_label_font, snd, chn, Copy_context) end draw_string("mel,", char_width * 6 + label_pos, axis_y1 + label_height, snd, chn, Copy_context, cr) # erb label/ticks set_foreground_color(snd_color(4), snd, chn, Copy_context) if self.bark_tick_function == 2 draw_bark_ticks.call(erb_position) end if bark_label_font set_current_font(bark_label_font, snd, chn, Copy_context) end draw_string("erb", char_width * (6 + 5) + label_pos, axis_y1 + label_height, snd, chn, Copy_context, cr) set_foreground_color(old_foreground_color, snd, chn, Copy_context) free_cairo(cr) end # mouse click = move to next scale's ticks def choose_bark_ticks(snd, chn, button, state, x, y, axis) if axis == Lisp_graph @bark_tick_function += 1 if @bark_tick_function > 2 @bark_tick_function = 0 end update_lisp_graph(snd, chn) end end private def bark(f) f2 = f / 7500.0 13.5 * atan(0.00076 * f) + (3.5 * atan(f2 * f2)) end def mel(f) 1127.0 * log(1.0 + f / 700.0) end def erb(f) 43.0 + 11.17 * log((f + 312.0) / (f + 14675.0)) end end # user's view of display-bark-fft function def display_bark_fft(off = false) if off.kind_of?(FalseClass) db = Display_bark_fft.new $lisp_graph_hook.add_hook!("display-bark-fft") do |snd, chn| db.display_bark_fft(snd, chn) end $after_lisp_graph_hook.add_hook!("make-bark-label") do |snd, chn| db.mark_bark_labels(snd, chn) end $mouse_click_hook.add_hook!("choose-bark-ticks") do |s, c, b, st, x, y, a| db.choose_bark_ticks(s, c, b, st, x, y, a) end Snd.sounds.each do |snd| channels(snd).times do |chn| update_lisp_graph(snd, chn) end end else $lisp_graph_hook.remove_hook!("display-bark-fft") $after_lisp_graph_hook.remove_hook!("make-bark-label") $mouse_click_hook.remove_hook!("choose-bark-ticks") Snd.sounds.each do |snd| channels(snd).times do |chn| set_lisp_graph?(false, snd, chn) end end end off end def undisplay_bark_fft display_bark_fft(true) end end include Dsp # dsp.rb ends here snd-16.1/snd-file.h0000644000076400007640000000407512471674502012223 0ustar bilbil#ifndef SND_FILE_H #define SND_FILE_H char *dialog_get_title(widget_t dialog); const char **header_type_and_sample_type_to_position(file_data *fdat, mus_header_t header_type, mus_sample_t sample_type); void position_to_header_type_and_sample_type(file_data *fdat, int pos); mus_sample_t position_to_sample_type(mus_header_t header, int pos); mus_header_t position_to_header_type(int pos); const char **short_writable_headers(int *len); const char **short_readable_headers(int *len); const char **short_builtin_headers(int *len); bool header_is_encoded(mus_header_t header_type); void snd_encode(mus_header_t type, const char *input_filename, const char *output_filename); snd_info *file_is_open_elsewhere_and_has_unsaved_edits(snd_info *sp, const char *fullname); snd_info *finish_opening_sound(snd_info *sp, bool selected); bool edit_header_callback(snd_info *sp, file_data *edit_header_data, void (*outer_handler)(const char *error_msg, void *ufd), void (*inner_handler)(const char *error_msg, void *ufd)); void raw_data_dialog_to_file_info(const char *filename, char *title, char *info, read_only_t read_only, bool selected); #if USE_GTK #define position_t gdouble #define POSITION_UNKNOWN 0.0 #else #define position_t int #define POSITION_UNKNOWN 0 #endif typedef struct { time_t time; mus_long_t samps; char *filename, *full_filename; } sort_info; typedef struct { sort_info **files; char *dir_name; int len; int size; } dir_info; enum {NO_FILE_FILTER, JUST_SOUNDS_FILTER}; dir_info *free_dir_info (dir_info *dp); dir_info *find_files_in_dir(const char *name); dir_info *find_filtered_files_in_dir(const char *name, int filter_choice); dir_info *find_filtered_files_in_dir_with_pattern(const char *name, int filter_choice, const char *pattern); const char *short_sample_type_name(mus_sample_t sndlib_sample_type, const char *filename); #define FILENAME_LIST_SIZE 16 void remember_filename(const char *filename, char **names); char **make_filename_list(void); void preload_filenames(char **files); dir_info *find_sound_files_in_dir(const char *name); #endif snd-16.1/snd-0.h0000644000076400007640000020500612545516512011436 0ustar bilbil#ifndef SND_0_H #define SND_0_H #if HAVE_RUBY #undef _ #endif #if HAVE_SCHEME #define DISPLAY(Obj) s7_object_to_c_string(s7, Obj) #endif #define NO_SUCH_ENVELOPE Xen_make_error_type("no-such-envelope") #define NO_SUCH_SAMPLE Xen_make_error_type("no-such-sample") #define NO_SUCH_EDIT Xen_make_error_type("no-such-edit") #define CANNOT_SAVE Xen_make_error_type("cannot-save") #define CANT_UPDATE_FILE Xen_make_error_type("cant-update-file") #if (SIZEOF_VOID_P == 4) typedef int pointer_or_int_t; #else typedef long long int pointer_or_int_t; #endif #ifndef STRFTIME_FORMAT #define STRFTIME_FORMAT "%a %d-%b-%Y %H:%M %Z" #endif #ifndef _MSC_VER #define STRCMP(a, b) strcasecmp(a, b) #define STRNCMP(a, b, c) strncasecmp(a, b, c) #else #define STRCMP(a, b) strcmp(a, b) #define STRNCMP(a, b, c) strncmp(a, b, c) #endif #define strcopy(Dest, Src, Len) snprintf(Dest, Len, "%s", Src) #define unpack_sound(a) ((int)a >> 16) #define unpack_channel(a) ((int)a & 0xff) #define pack_sound_and_channel(a, b) ((a << 16) | b) #define POINT_BUFFER_SIZE 8192 #define FILE_BUFFER_SIZE 8192 #define MAX_BUFFER_SIZE 65536 #define PRINT_BUFFER_SIZE 512 #define LABEL_BUFFER_SIZE 128 #define REPORTING_SIZE (MAX_BUFFER_SIZE * 32) /* progress bar (hourglass icon) is displayed if more than this many samples are being processed */ #if (!USE_NO_GUI) #define NUM_HOURGLASSES 15 #else #define NUM_HOURGLASSES 1 #endif #define PEAK_ENV_CUTOFF 50000 #define MIN_INIT 1000000.0 #define MAX_INIT -1000000.0 #define DEFAULT_OUTPUT_CHANS 1 #define DEFAULT_OUTPUT_SRATE 44100 #define DEFAULT_OUTPUT_HEADER_TYPE MUS_NEXT /* mus-next is probably best here since intermediate/temp files can be any length (> 2^32 bytes) * and the next header-specified size, although 32 bits, is explicitly "advisory". */ #if MUS_LITTLE_ENDIAN #define DEFAULT_OUTPUT_SAMPLE_TYPE MUS_LFLOAT #else #define DEFAULT_OUTPUT_SAMPLE_TYPE MUS_BFLOAT #endif #define NO_COMPLETER -1 #define NO_SELECTION -1 #define NO_END_SPECIFIED -1 #define NO_MIX_TAG -1 #define INVALID_MIX_ID -1 #define SAVE_ALL_CHANS -1 #define ANY_MIX_ID -2 #define NO_COLOR -1 #define NOT_A_GC_LOC -1 #define NOT_A_SOUND -1 #define MIX_FILE_NO_MIX -1 #define MIX_FILE_NO_FILE -2 #define MIX_FILE_NO_SP -3 #define MIX_FILE_NO_TEMP_FILE -4 #ifndef POPUP_BUTTON #define POPUP_BUTTON 3 #endif #define I_HELP "Help" #define I_GO_AWAY "Go away" #define I_NEXT "Next" #define I_PREVIOUS "Previous" #define I_FIND "Find" #define I_find "find:" #define I_STOP "Stop" typedef enum {SOUND_SAVE_AS, SELECTION_SAVE_AS, REGION_SAVE_AS} save_dialog_t; typedef enum {NOT_IN_BACKGROUND, IN_BACKGROUND} play_process_t; typedef enum {WITHOUT_VIRTUAL_CHANNELS, WITH_VIRTUAL_CHANNELS} virtual_channels_t; typedef enum {WITH_FW_BUTTONS, WITH_ARROWS} fw_button_t; typedef enum {WITHOUT_HOOK, WITH_HOOK} with_hook_t; typedef enum {WITHOUT_WORD_WRAP, WITH_WORD_WRAP} with_word_wrap_t; typedef enum {DRAG_ENTER, DRAG_LEAVE, DRAG_MOTION} drag_style_t; typedef enum {ENVED_AMPLITUDE, ENVED_SPECTRUM, ENVED_SRATE} enved_target_t; typedef enum {ENVELOPE_LINEAR, ENVELOPE_EXPONENTIAL} env_type_t; typedef enum {GRAPH_LINES, GRAPH_DOTS, GRAPH_FILLED, GRAPH_DOTS_AND_LINES, GRAPH_LOLLIPOPS, NUM_GRAPH_STYLES} graph_style_t; typedef enum {APPLY_TO_SOUND, APPLY_TO_CHANNEL, APPLY_TO_SELECTION} snd_apply_t; typedef enum {GRAPH_ONCE, GRAPH_AS_SONOGRAM, GRAPH_AS_SPECTROGRAM, GRAPH_AS_WAVOGRAM} graph_type_t; typedef enum {ZOOM_FOCUS_LEFT, ZOOM_FOCUS_RIGHT, ZOOM_FOCUS_ACTIVE, ZOOM_FOCUS_MIDDLE, ZOOM_FOCUS_PROC} zoom_focus_t; typedef enum {DONT_DELETE_ME, DELETE_ME, ALREADY_DELETED, MULTICHANNEL_DELETION, MULTICHANNEL_DELETION_IF_FILE} file_delete_t; typedef enum {SND_REOPEN_CLOSED_FILE, SND_OPEN_CHANNEL, SND_COPY_READER, SND_INSERT_FILE, SND_CHANGE_FILE, SND_OVERRIDE_FILE, SND_MIX_FILE} open_reason_t; typedef enum {CURSOR_CROSS, CURSOR_LINE, CURSOR_PROC} cursor_style_t; typedef enum {SHOW_NO_AXES, SHOW_ALL_AXES, SHOW_X_AXIS, SHOW_ALL_AXES_UNLABELLED, SHOW_X_AXIS_UNLABELLED, SHOW_BARE_X_AXIS, NUM_SHOW_AXES} show_axes_t; typedef enum {DONT_NORMALIZE, NORMALIZE_BY_CHANNEL, NORMALIZE_BY_SOUND, NORMALIZE_GLOBALLY, NUM_TRANSFORM_NORMALIZATIONS} fft_normalize_t; typedef enum {NO_DISK_SPACE, NOT_ENOUGH_DISK_SPACE, DISK_SPACE_OK} disk_space_t; typedef enum {CHAN_GC, CHAN_IGC, CHAN_SELGC, CHAN_CGC, CHAN_MGC, CHAN_MXGC, CHAN_TMPGC} chan_gc_t; typedef enum {NOT_A_VIEWER, FILE_VIEWER, REGION_VIEWER} file_viewer_t; /* 1 and 2, according to docs for mouse-enter-label-hook */ typedef enum {COLOR_ORIENTATION_DIALOG, ENVED_DIALOG, TRANSFORM_DIALOG, FILE_OPEN_DIALOG, SOUND_SAVE_AS_DIALOG, VIEW_FILES_DIALOG, RAW_DATA_DIALOG, NEW_FILE_DIALOG, FILE_MIX_DIALOG, EDIT_HEADER_DIALOG, FIND_DIALOG, HELP_DIALOG, MIX_DIALOG, PRINT_DIALOG, REGION_DIALOG, POST_IT_DIALOG, CONTROLS_DIALOG, SELECTION_SAVE_AS_DIALOG, FILE_INSERT_DIALOG, REGION_SAVE_AS_DIALOG, PREFERENCES_DIALOG, NUM_DIALOGS} snd_dialog_t; typedef enum {SOUND_IDLE, SOUND_NORMAL, SOUND_WRAPPER, SOUND_REGION, SOUND_READER} sound_inuse_t; typedef enum {IO_NO_ERROR, IO_SAVE_HOOK_CANCELLATION, IO_BAD_CHANNEL, IO_CANT_REOPEN_FILE, IO_TOO_MANY_OPEN_FILES, IO_UNKNOWN_SNDLIB_ERROR, IO_NO_MEMORY, IO_CANT_OPEN_FILE, IO_NO_FILENAME, IO_BAD_SAMPLE_TYPE, IO_BAD_HEADER_TYPE, IO_SNDLIB_UNINITIALIZED, IO_NOT_A_SOUND_FILE, IO_FILE_CLOSED, IO_WRITE_ERROR, IO_INTERRUPTED, IO_CANT_CLOSE_FILE, IO_BAD_HEADER, IO_DISK_FULL, IO_WRITE_PROTECTED, IO_CANT_READ_SELECTION_FILE, IO_NEED_WRITE_CONFIRMATION, IO_NO_CHANGES, IO_EDIT_HOOK_CANCELLATION, IO_CANT_CREATE_FILE, IO_ERROR_NUM} io_error_t; typedef enum {INSERTION_EDIT, DELETION_EDIT, CHANGE_EDIT, INITIALIZE_EDIT, SCALED_EDIT, ZERO_EDIT, RAMP_EDIT, EXTEND_EDIT, MIX_EDIT, CHANGE_MIX_EDIT, NUM_EDIT_TYPES} edit_t; typedef enum {SAMPLER, REGION_READER, MIX_READER} reader_t; typedef enum {MIX_FOLLOWS_SYNC, MIX_SETS_SYNC_LOCALLY} mix_sync_t; typedef enum {CHANNEL_FREED, CHANNEL_INACTIVE, CHANNEL_INITIALIZED, CHANNEL_HAS_EDIT_LIST, CHANNEL_HAS_AXES} channel_state_t; enum {BLACK_AND_WHITE_COLORMAP, GRAY_COLORMAP, HOT_COLORMAP, COOL_COLORMAP, BONE_COLORMAP, COPPER_COLORMAP, PINK_COLORMAP, JET_COLORMAP, PRISM_COLORMAP, AUTUMN_COLORMAP, WINTER_COLORMAP, SPRING_COLORMAP, SUMMER_COLORMAP, RAINBOW_COLORMAP, FLAG_COLORMAP, PHASES_COLORMAP, NUM_BUILTIN_COLORMAPS}; #define is_serious_io_error(Err) ((Err != IO_NO_ERROR) && \ (Err != IO_EDIT_HOOK_CANCELLATION) && \ (Err != IO_SAVE_HOOK_CANCELLATION) && \ (Err != IO_INTERRUPTED) && \ (Err != IO_NEED_WRITE_CONFIRMATION) && \ (Err != IO_NO_CHANGES)) enum {FILE_OPENED, FILE_CLOSED}; typedef enum {WITH_READABLE_HEADERS, WITH_WRITABLE_HEADERS, WITH_BUILTIN_HEADERS} header_choice_t; enum {SORT_A_TO_Z, SORT_Z_TO_A, SORT_NEW_TO_OLD, SORT_OLD_TO_NEW, SORT_SMALL_TO_BIG, SORT_BIG_TO_SMALL, SORT_XEN}; typedef enum {FILE_READ_WRITE, FILE_READ_ONLY} read_only_t; #define FORCE_REFFT true #define DONT_FORCE_REFFT false #define FORCE_REDISPLAY true #define DONT_FORCE_REDISPLAY false #define WITH_EVENTS true #define WITHOUT_EVENTS false #define NOT_IN_AS_ONE_EDIT false #define IN_AS_ONE_EDIT true #define FILE_SELECTED true #define FILE_NOT_SELECTED false #define EXIT_FORCED true #define EXIT_NOT_FORCED false #if HAVE_RUBY #define to_proc_name(Str) xen_scheme_procedure_to_ruby(Str) #define TO_VAR_NAME(Str) xen_scheme_constant_to_ruby(Str) #define PROC_OPEN "(" #define PROC_SEP ", " #define LIST_OPEN "[" #define LIST_CLOSE "]" #define BPAREN "" #define EPAREN "" #define PROC_FALSE "false" #define PROC_TRUE "true" #define PROC_QUOTE "" #endif #if HAVE_FORTH #define to_proc_name(Str) Str #define TO_VAR_NAME(Str) Str #define PROC_OPEN " " #define PROC_SEP " " #define LIST_OPEN " '( " #define LIST_CLOSE " ) " #define BPAREN "" #define EPAREN " drop" #define PROC_FALSE "#f" #define PROC_TRUE "#t" #define PROC_QUOTE "" #endif #if HAVE_SCHEME || (!HAVE_EXTENSION_LANGUAGE) #define to_proc_name(Str) Str #define TO_VAR_NAME(Str) Str #define PROC_OPEN " " #define PROC_SEP " " #define LIST_OPEN "(list " #define LIST_CLOSE ")" #define BPAREN "(" #define EPAREN ")" #define PROC_FALSE "#f" #define PROC_TRUE "#t" #define PROC_QUOTE "'" #endif #define MAX_MAIN_MENUS 64 #define NO_REGIONS -2 #define INVALID_REGION -1 #define NO_LIST -1 typedef enum {READ_FORWARD, READ_BACKWARD} read_direction_t; typedef enum {DONT_TRACK, TRACK_AND_RETURN, TRACK_AND_STAY} tracking_cursor_t; typedef enum {DONT_UPDATE_DISPLAY, UPDATE_DISPLAY} cut_selection_regraph_t; typedef enum {IGNORE_CACHE, REMOVE_FROM_CACHE} cache_remove_t; typedef enum {FFT_UNCHANGED, FFT_CHANGED, FFT_CHANGE_LOCKED} fft_change_t; typedef enum {WITHOUT_GRAPH, WITH_GRAPH, WITHOUT_INITIAL_GRAPH_HOOK} channel_graph_t; typedef enum {NOT_PRINTING, PRINTING} printing_t; typedef enum {NO_X_AXIS, WITH_X_AXIS} with_x_axis_t; typedef enum {NO_GRID, WITH_GRID} with_grid_t; typedef enum {WITH_LINEAR_AXES, WITH_LOG_X_AXIS, WITH_LOG_Y_AXIS} log_axis_t; #define GET_NEW_SYNC -1 #define GET_ORIGINAL_SYNC -2 #define OVER_SELECTION true #define OVER_SOUND false #define AT_CURRENT_EDIT_POSITION -1 typedef enum {X_AXIS_IN_SECONDS, X_AXIS_IN_SAMPLES, X_AXIS_AS_PERCENTAGE, X_AXIS_IN_BEATS, X_AXIS_IN_MEASURES, X_AXIS_AS_CLOCK, NUM_X_AXIS_STYLES} x_axis_style_t; typedef enum {SPEED_CONTROL_AS_FLOAT, SPEED_CONTROL_AS_RATIO, SPEED_CONTROL_AS_SEMITONE, NUM_SPEED_CONTROL_STYLES} speed_style_t; typedef enum {CURSOR_IN_VIEW, CURSOR_ON_LEFT, CURSOR_ON_RIGHT, CURSOR_IN_MIDDLE, KEYBOARD_NO_ACTION} kbd_cursor_t; typedef enum {CHANNELS_SEPARATE, CHANNELS_COMBINED, CHANNELS_SUPERIMPOSED, NOT_A_CHANNEL_STYLE} channel_style_t; #define NUM_CHANNEL_STYLES 3 typedef enum {SYNC_NONE, SYNC_ALL, SYNC_BY_SOUND} sync_style_t; #define NUM_SYNC_STYLES 3 typedef enum {FD_CLOSED, FD_OPEN} fd_open_t; typedef enum {PRINT_SND, PRINT_ENV} print_choice_t; typedef enum {SND_DATA_NO_DATA, SND_DATA_FILE, SND_DATA_BUFFER} snd_data_file_t; typedef enum {SOUNDS_VERTICAL, SOUNDS_HORIZONTAL, SOUNDS_IN_NOTEBOOK, SOUNDS_IN_SEPARATE_WINDOWS} sound_style_t; enum {FOURIER, WAVELET, WALSH, AUTOCORRELATION, CEPSTRUM, HAAR, NUM_BUILTIN_TRANSFORM_TYPES}; /* not typedef'd -- grows as new ones are added */ #define NUM_WAVELETS 48 typedef enum {FCP_X_ANGLE, FCP_X_SCALE, FCP_Y_ANGLE, FCP_Y_SCALE, FCP_Z_ANGLE, FCP_Z_SCALE, FCP_SPECTRUM_END, FCP_SPECTRUM_START, FCP_ALPHA, FCP_BETA, FCP_BEATS} fcp_t; typedef enum {TIME_AXIS_INFO, TRANSFORM_AXIS_INFO, LISP_AXIS_INFO} axis_info_t; typedef enum {COLOR_POSITION, COLOR_ZOOM} slider_choice_t; typedef enum {PLAY_COMPLETE, PLAY_CLOSE, PLAY_BUTTON_UNSET, PLAY_STOP_CALLED, PLAY_C_G, PLAY_NO_CHANNEL, PLAY_ERROR, PLAY_APPLY, PLAY_EDIT, PLAY_C_T} play_stop_t; typedef enum {NO_REQUESTOR, FROM_UPDATE, FROM_VIEW_FILES, FROM_DRAG_AND_DROP, FROM_OPEN_DIALOG, FROM_KEYBOARD, FROM_STARTUP, FROM_REGION_EDIT, FROM_NEW_FILE_DIALOG, FROM_OPEN_SOUND, FROM_OPEN_RAW_SOUND, FROM_VIEW_SOUND, FROM_NEW_SOUND, FROM_RAW_DATA_DIALOG, FROM_MIX_DIALOG, FROM_INSERT_DIALOG, FROM_VIEW_FILES_MIX_DIALOG, FROM_VIEW_FILES_INSERT_DIALOG, FROM_OPEN_RECENT_MENU, FROM_OPEN_DIALOG_POPUP, FROM_POPUP_CUT_TO_NEW} open_requestor_t; #define DEFAULT_AMP_CONTROL 1.0 #define DEFAULT_CONTRAST_CONTROL 0.0 #define DEFAULT_EXPAND_CONTROL 1.0 #define DEFAULT_REVERB_CONTROL_LENGTH 1.0 #define DEFAULT_REVERB_CONTROL_SCALE 0.0 #define DEFAULT_SPEED_CONTROL 1.0 #define DEFAULT_CONTRAST_CONTROL_ON false #define DEFAULT_EXPAND_CONTROL_ON false #define DEFAULT_FILTER_CONTROL_ON false #define DEFAULT_REVERB_CONTROL_ON false #define filter_control_in_dB(ss) ss->Filter_Control_In_Db #if HAVE_SCHEME #define in_set_filter_control_in_dB(ss, val) {ss->Filter_Control_In_Db = val; s7_symbol_set_value(s7, ss->filter_control_in_db_symbol, s7_make_boolean(s7, val));} #else #define in_set_filter_control_in_dB(ss, val) ss->Filter_Control_In_Db = val #endif #define DEFAULT_FILTER_CONTROL_IN_DB false #define filter_control_in_hz(ss) ss->Filter_Control_In_Hz #if HAVE_SCHEME #define in_set_filter_control_in_hz(ss, val) {ss->Filter_Control_In_Hz = val; s7_symbol_set_value(s7, ss->filter_control_in_hz_symbol, s7_make_boolean(s7, val));} #else #define in_set_filter_control_in_hz(ss, val) ss->Filter_Control_In_Hz = val #endif #define DEFAULT_FILTER_CONTROL_IN_HZ false #define speed_control_tones(ss) ss->Speed_Control_Tones #if HAVE_SCHEME #define in_set_speed_control_tones(ss, val) {ss->Speed_Control_Tones = val; s7_symbol_set_value(s7, ss->speed_control_tones_symbol, s7_make_integer(s7, val));} #else #define in_set_speed_control_tones(ss, val) ss->Speed_Control_Tones = val #endif #define DEFAULT_SPEED_CONTROL_TONES 12 #define speed_control_style(ss) ss->Speed_Control_Style #if HAVE_SCHEME #define in_set_speed_control_style(ss, val) {ss->Speed_Control_Style = val; s7_symbol_set_value(s7, ss->speed_control_style_symbol, s7_make_integer(s7, val));} #else #define in_set_speed_control_style(ss, val) ss->Speed_Control_Style = val #endif #define DEFAULT_SPEED_CONTROL_STYLE SPEED_CONTROL_AS_FLOAT #define expand_control_length(ss) ss->Expand_Control_Length #if HAVE_SCHEME #define in_set_expand_control_length(ss, val) {ss->Expand_Control_Length = val; s7_symbol_set_value(s7, ss->expand_control_length_symbol, s7_make_real(s7, val));} #else #define in_set_expand_control_length(ss, val) ss->Expand_Control_Length = val #endif #define DEFAULT_EXPAND_CONTROL_LENGTH 0.15 #define expand_control_ramp(ss) ss->Expand_Control_Ramp #if HAVE_SCHEME #define in_set_expand_control_ramp(ss, val) {ss->Expand_Control_Ramp = val; s7_symbol_set_value(s7, ss->expand_control_ramp_symbol, s7_make_real(s7, val));} #else #define in_set_expand_control_ramp(ss, val) ss->Expand_Control_Ramp = val #endif #define DEFAULT_EXPAND_CONTROL_RAMP 0.4 #define expand_control_hop(ss) ss->Expand_Control_Hop #if HAVE_SCHEME #define in_set_expand_control_hop(ss, val) {ss->Expand_Control_Hop = val; s7_symbol_set_value(s7, ss->expand_control_hop_symbol, s7_make_real(s7, val));} #else #define in_set_expand_control_hop(ss, val) ss->Expand_Control_Hop = val #endif #define DEFAULT_EXPAND_CONTROL_HOP 0.05 #define expand_control_jitter(ss) ss->Expand_Control_Jitter #if HAVE_SCHEME #define in_set_expand_control_jitter(ss, val) {ss->Expand_Control_Jitter = val; s7_symbol_set_value(s7, ss->expand_control_jitter_symbol, s7_make_real(s7, val));} #else #define in_set_expand_control_jitter(ss, val) ss->Expand_Control_Jitter = val #endif #define DEFAULT_EXPAND_CONTROL_JITTER 0.1 #define contrast_control_amp(ss) ss->Contrast_Control_Amp #if HAVE_SCHEME #define in_set_contrast_control_amp(ss, val) {ss->Contrast_Control_Amp = val; s7_symbol_set_value(s7, ss->contrast_control_amp_symbol, s7_make_real(s7, val));} #else #define in_set_contrast_control_amp(ss, val) ss->Contrast_Control_Amp = val #endif #define DEFAULT_CONTRAST_CONTROL_AMP 1.0 #define reverb_control_feedback(ss) ss->Reverb_Control_Feedback #if HAVE_SCHEME #define in_set_reverb_control_feedback(ss, val) {ss->Reverb_Control_Feedback = val; s7_symbol_set_value(s7, ss->reverb_control_feedback_symbol, s7_make_real(s7, val));} #else #define in_set_reverb_control_feedback(ss, val) ss->Reverb_Control_Feedback = val #endif #define DEFAULT_REVERB_CONTROL_FEEDBACK 1.09 #define reverb_control_lowpass(ss) ss->Reverb_Control_Lowpass #if HAVE_SCHEME #define in_set_reverb_control_lowpass(ss, val) {ss->Reverb_Control_Lowpass = val; s7_symbol_set_value(s7, ss->reverb_control_lowpass_symbol, s7_make_real(s7, val));} #else #define in_set_reverb_control_lowpass(ss, val) ss->Reverb_Control_Lowpass = val #endif #define DEFAULT_REVERB_CONTROL_LOWPASS 0.7 #define reverb_control_decay(ss) ss->Reverb_Control_Decay #if HAVE_SCHEME #define in_set_reverb_control_decay(ss, val) {ss->Reverb_Control_Decay = val; s7_symbol_set_value(s7, ss->reverb_control_decay_symbol, s7_make_real(s7, val));} #else #define in_set_reverb_control_decay(ss, val) ss->Reverb_Control_Decay = val #endif #define DEFAULT_REVERB_CONTROL_DECAY 1.0 #define contrast_control_min(ss) ss->Contrast_Control_Min #define in_set_contrast_control_min(ss, val) ss->Contrast_Control_Min = val #define DEFAULT_CONTRAST_CONTROL_MIN 0.0 #define contrast_control_max(ss) ss->Contrast_Control_Max #define in_set_contrast_control_max(ss, val) ss->Contrast_Control_Max = val #define DEFAULT_CONTRAST_CONTROL_MAX 10.0 #define expand_control_min(ss) ss->Expand_Control_Min #define in_set_expand_control_min(ss, val) ss->Expand_Control_Min = val #define DEFAULT_EXPAND_CONTROL_MIN 0.05 #define expand_control_max(ss) ss->Expand_Control_Max #define in_set_expand_control_max(ss, val) ss->Expand_Control_Max = val #define DEFAULT_EXPAND_CONTROL_MAX 20.0 #define speed_control_min(ss) ss->Speed_Control_Min #define in_set_speed_control_min(ss, val) ss->Speed_Control_Min = val #define DEFAULT_SPEED_CONTROL_MIN 0.05 #define speed_control_max(ss) ss->Speed_Control_Max #define in_set_speed_control_max(ss, val) ss->Speed_Control_Max = val #define DEFAULT_SPEED_CONTROL_MAX 20.0 #define amp_control_min(ss) ss->Amp_Control_Min #define in_set_amp_control_min(ss, val) ss->Amp_Control_Min = val #define DEFAULT_AMP_CONTROL_MIN 0.0 #define amp_control_max(ss) ss->Amp_Control_Max #define in_set_amp_control_max(ss, val) ss->Amp_Control_Max = val #define DEFAULT_AMP_CONTROL_MAX 8.0 #define reverb_control_scale_min(ss) ss->Reverb_Control_Scale_Min #define in_set_reverb_control_scale_min(ss, val) ss->Reverb_Control_Scale_Min = val #define DEFAULT_REVERB_CONTROL_SCALE_MIN 0.0 #define reverb_control_scale_max(ss) ss->Reverb_Control_Scale_Max #define in_set_reverb_control_scale_max(ss, val) ss->Reverb_Control_Scale_Max = val #define DEFAULT_REVERB_CONTROL_SCALE_MAX 4.0 #define reverb_control_length_min(ss) ss->Reverb_Control_Length_Min #define in_set_reverb_control_length_min(ss, val) ss->Reverb_Control_Length_Min = val #define DEFAULT_REVERB_CONTROL_LENGTH_MIN 0.0 #define reverb_control_length_max(ss) ss->Reverb_Control_Length_Max #define in_set_reverb_control_length_max(ss, val) ss->Reverb_Control_Length_Max = val #define DEFAULT_REVERB_CONTROL_LENGTH_MAX 5.0 #define filter_control_order(ss) ss->Filter_Control_Order #if HAVE_SCHEME #define in_set_filter_control_order(ss, val) {ss->Filter_Control_Order = val; s7_symbol_set_value(s7, ss->filter_control_order_symbol, s7_make_integer(s7, val));} #else #define in_set_filter_control_order(ss, val) ss->Filter_Control_Order = val #endif #define DEFAULT_FILTER_CONTROL_ORDER 20 #define in_show_controls(ss) ss->Show_Controls #if HAVE_SCHEME #define in_set_show_controls(ss, val) \ do {\ ss->Show_Controls = val; \ s7_symbol_set_value(s7, ss->show_controls_symbol, s7_make_boolean(s7, ss->Show_Controls));\ } while (0) #else #define in_set_show_controls(ss, val) ss->Show_Controls = val #endif #define DEFAULT_SHOW_CONTROLS false #define with_tracking_cursor(ss) ss->With_Tracking_Cursor #if HAVE_SCHEME #define set_with_tracking_cursor(ss, val) \ do {\ ss->With_Tracking_Cursor = val; \ s7_symbol_set_value(s7, ss->with_tracking_cursor_symbol, s7_make_integer(s7, (int)(ss->With_Tracking_Cursor))); \ } while (0) #else #define set_with_tracking_cursor(ss, val) ss->With_Tracking_Cursor = val #endif #define DEFAULT_WITH_TRACKING_CURSOR DONT_TRACK #define just_sounds(ss) ss->Just_Sounds #if HAVE_SCHEME #define set_just_sounds(val) \ do {\ ss->Just_Sounds = val; \ s7_symbol_set_value(s7, ss->just_sounds_symbol, s7_make_boolean(s7, ss->Just_Sounds));\ } while (0) #else #define set_just_sounds(val) ss->Just_Sounds = val #endif #define DEFAULT_JUST_SOUNDS true #define DEFAULT_SYNC 0 #define DEFAULT_INIT_WINDOW_X -1 #define DEFAULT_INIT_WINDOW_Y -1 #define DEFAULT_INIT_WINDOW_WIDTH 0 #define DEFAULT_INIT_WINDOW_HEIGHT 0 #define default_output_header_type(ss) ss->Default_Output_Header_Type #if HAVE_SCHEME #define set_default_output_header_type(a) \ do {\ ss->Default_Output_Header_Type = (mus_header_t)a; \ s7_symbol_set_value(s7, ss->default_output_header_type_symbol, s7_make_integer(s7, (s7_int)(ss->Default_Output_Header_Type))); \ } while (0) #else #define set_default_output_header_type(a) ss->Default_Output_Header_Type = (mus_header_t)a #endif #define default_output_chans(ss) ss->Default_Output_Chans #if HAVE_SCHEME #define set_default_output_chans(a) \ do {\ ss->Default_Output_Chans = a; \ s7_symbol_set_value(s7, ss->default_output_chans_symbol, s7_make_integer(s7, ss->Default_Output_Chans));\ } while (0) #else #define set_default_output_chans(a) ss->Default_Output_Chans = a #endif #define default_output_srate(ss) ss->Default_Output_Srate #if HAVE_SCHEME #define set_default_output_srate(a) \ do {\ ss->Default_Output_Srate = a; \ s7_symbol_set_value(s7, ss->default_output_srate_symbol, s7_make_integer(s7, ss->Default_Output_Srate));\ } while (0) #else #define set_default_output_srate(a) ss->Default_Output_Srate = a #endif #define default_output_sample_type(ss) ss->Default_Output_Sample_Type #if HAVE_SCHEME #define set_default_output_sample_type(a) \ do {\ ss->Default_Output_Sample_Type = (mus_sample_t)a; \ s7_symbol_set_value(s7, ss->default_output_sample_type_symbol, s7_make_integer(s7, (s7_int)ss->Default_Output_Sample_Type)); \ } while (0) #else #define set_default_output_sample_type(a) ss->Default_Output_Sample_Type = (mus_sample_t)a #endif #define dac_size(ss) ss->Dac_Size #if HAVE_SCHEME #define set_dac_size(a) \ do {\ ss->Dac_Size = a; \ s7_symbol_set_value(s7, ss->dac_size_symbol, s7_make_integer(s7, ss->Dac_Size));\ } while (0) #else #define set_dac_size(a) ss->Dac_Size = a #endif #if (HAVE_OSS || HAVE_ALSA) #define DEFAULT_DAC_SIZE 256 #else #if __APPLE__ #define DEFAULT_DAC_SIZE 64 #else #define DEFAULT_DAC_SIZE 1024 #endif #endif #define dac_combines_channels(ss) ss->Dac_Combines_Channels #if HAVE_SCHEME #define set_dac_combines_channels(a) \ do {\ ss->Dac_Combines_Channels = a; \ s7_symbol_set_value(s7, ss->dac_combines_channels_symbol, s7_make_boolean(s7, ss->Dac_Combines_Channels));\ } while (0) #else #define set_dac_combines_channels(a) ss->Dac_Combines_Channels = a #endif #define DEFAULT_DAC_COMBINES_CHANNELS true #define max_regions(ss) ss->Max_Regions #if HAVE_SCHEME #define in_set_max_regions(a) \ do {\ ss->Max_Regions = a; \ s7_symbol_set_value(s7, ss->max_regions_symbol, s7_make_integer(s7, ss->Max_Regions));\ } while (0) #else #define in_set_max_regions(a) ss->Max_Regions = a #endif #define DEFAULT_MAX_REGIONS 16 #define max_transform_peaks(ss) ss->Max_Transform_Peaks #if HAVE_SCHEME #define in_set_max_transform_peaks(a) \ do {\ ss->Max_Transform_Peaks = a; \ s7_symbol_set_value(s7, ss->max_transform_peaks_symbol, s7_make_integer(s7, ss->Max_Transform_Peaks));\ } while (0) #else #define in_set_max_transform_peaks(a) ss->Max_Transform_Peaks = a #endif #define DEFAULT_MAX_TRANSFORM_PEAKS 100 #define auto_resize(ss) ss->Auto_Resize #if HAVE_SCHEME #define set_auto_resize(a) \ do {\ ss->Auto_Resize = a; \ s7_symbol_set_value(s7, ss->auto_resize_symbol, s7_make_boolean(s7, ss->Auto_Resize));\ } while (0) #else #define set_auto_resize(a) ss->Auto_Resize = a #endif #if HAVE_GTK #define DEFAULT_AUTO_RESIZE false #else #define DEFAULT_AUTO_RESIZE true #endif #define auto_update(ss) ss->Auto_Update #if HAVE_SCHEME #define set_auto_update(a) \ do {\ ss->Auto_Update = a; \ s7_symbol_set_value(s7, ss->auto_update_symbol, s7_make_boolean(s7, ss->Auto_Update));\ } while (0) #else #define set_auto_update(a) ss->Auto_Update = a #endif #define DEFAULT_AUTO_UPDATE false #define auto_update_interval(ss) ss->Auto_Update_Interval #if HAVE_SCHEME #define set_auto_update_interval(a) \ do {\ ss->Auto_Update_Interval = a; \ s7_symbol_set_value(s7, ss->auto_update_interval_symbol, s7_make_real(s7, ss->Auto_Update_Interval));\ } while (0) #else #define set_auto_update_interval(a) ss->Auto_Update_Interval = a #endif #define DEFAULT_AUTO_UPDATE_INTERVAL 60.0 #define cursor_update_interval(ss) ss->Cursor_Update_Interval #if HAVE_SCHEME #define set_cursor_update_interval(a) \ do {\ ss->Cursor_Update_Interval = a; \ s7_symbol_set_value(s7, ss->cursor_update_interval_symbol, s7_make_real(s7, ss->Cursor_Update_Interval));\ } while (0) #else #define set_cursor_update_interval(a) ss->Cursor_Update_Interval = a #endif #define DEFAULT_CURSOR_UPDATE_INTERVAL 0.05 #define cursor_location_offset(ss) ss->Cursor_Location_Offset #if HAVE_SCHEME #define set_cursor_location_offset(a) \ do {\ ss->Cursor_Location_Offset = a; \ s7_symbol_set_value(s7, ss->cursor_location_offset_symbol, s7_make_integer(s7, ss->Cursor_Location_Offset));\ } while (0) #else #define set_cursor_location_offset(a) ss->Cursor_Location_Offset = a #endif #define DEFAULT_CURSOR_LOCATION_OFFSET 0 #define color_cutoff(ss) ss->Color_Cutoff #if HAVE_SCHEME #define in_set_color_cutoff(a) \ do {\ ss->Color_Cutoff = a; \ s7_symbol_set_value(s7, ss->color_cutoff_symbol, s7_make_real(s7, ss->Color_Cutoff));\ } while (0) #else #define in_set_color_cutoff(a) ss->Color_Cutoff = a #endif #define DEFAULT_COLOR_CUTOFF 0.003 #define color_inverted(ss) ss->Color_Inverted #if HAVE_SCHEME #define in_set_color_inverted(a) \ do {\ ss->Color_Inverted = a; \ s7_symbol_set_value(s7, ss->color_inverted_symbol, s7_make_boolean(s7, ss->Color_Inverted));\ } while (0) #else #define in_set_color_inverted(a) ss->Color_Inverted = a #endif #define DEFAULT_COLOR_INVERTED true #define color_scale(ss) ss->Color_Scale #if HAVE_SCHEME #define in_set_color_scale(a) \ do {\ ss->Color_Scale = a; \ s7_symbol_set_value(s7, ss->color_scale_symbol, s7_make_real(s7, ss->Color_Scale));\ } while (0) #else #define in_set_color_scale(a) ss->Color_Scale = a #endif #define DEFAULT_COLOR_SCALE 1.0 #define fft_window_alpha(ss) ss->Fft_Window_Alpha #if HAVE_SCHEME #define in_set_fft_window_alpha(a) \ do {\ ss->Fft_Window_Alpha = a; \ s7_symbol_set_value(s7, ss->fft_window_alpha_symbol, s7_make_real(s7, ss->Fft_Window_Alpha));\ } while (0) #else #define in_set_fft_window_alpha(a) ss->Fft_Window_Alpha = a #endif #define DEFAULT_FFT_WINDOW_ALPHA 0.0 #define fft_window_beta(ss) ss->Fft_Window_Beta #if HAVE_SCHEME #define in_set_fft_window_beta(a) \ do {\ ss->Fft_Window_Beta = a; \ s7_symbol_set_value(s7, ss->fft_window_beta_symbol, s7_make_real(s7, ss->Fft_Window_Beta));\ } while (0) #else #define in_set_fft_window_beta(a) ss->Fft_Window_Beta = a #endif #define DEFAULT_FFT_WINDOW_BETA 0.0 #define transform_size(ss) ss->Transform_Size #if HAVE_SCHEME #define in_set_transform_size(a) \ do {\ ss->Transform_Size = a; \ s7_symbol_set_value(s7, ss->transform_size_symbol, s7_make_integer(s7, ss->Transform_Size));\ } while (0) #else #define in_set_transform_size(a) ss->Transform_Size = a #endif #define DEFAULT_TRANSFORM_SIZE 512 #define transform_graph_type(ss) ss->Transform_Graph_Type #if HAVE_SCHEME #define in_set_transform_graph_type_1(a) \ do {\ ss->Transform_Graph_Type = a; \ s7_symbol_set_value(s7, ss->transform_graph_type_symbol, s7_make_integer(s7, ss->Transform_Graph_Type));\ } while (0) #else #define in_set_transform_graph_type_1(a) ss->Transform_Graph_Type = a #endif #define DEFAULT_TRANSFORM_GRAPH_TYPE GRAPH_ONCE #define time_graph_type(ss) ss->Time_Graph_Type #if HAVE_SCHEME #define in_set_time_graph_type(a) \ do {\ ss->Time_Graph_Type = a; \ s7_symbol_set_value(s7, ss->time_graph_type_symbol, s7_make_integer(s7, ss->Time_Graph_Type));\ } while (0) #else #define in_set_time_graph_type(a) ss->Time_Graph_Type = a #endif #define DEFAULT_TIME_GRAPH_TYPE GRAPH_ONCE #define fft_window(ss) ss->Fft_Window #if HAVE_SCHEME #define in_set_fft_window_1(a) \ do {\ ss->Fft_Window = a; \ s7_symbol_set_value(s7, ss->fft_window_symbol, s7_make_integer(s7, ss->Fft_Window));\ } while (0) #else #define in_set_fft_window_1(a) ss->Fft_Window = a #endif #define DEFAULT_FFT_WINDOW MUS_BLACKMAN2_WINDOW #define log_freq_start(ss) ss->Log_Freq_Start #if HAVE_SCHEME #define in_set_log_freq_start(a) \ do {\ ss->Log_Freq_Start = a; \ s7_symbol_set_value(s7, ss->log_freq_start_symbol, s7_make_real(s7, ss->Log_Freq_Start));\ } while (0) #else #define in_set_log_freq_start(a) ss->Log_Freq_Start = a #endif #define DEFAULT_LOG_FREQ_START 32.0 #define dot_size(ss) ss->Dot_Size #if HAVE_SCHEME #define in_set_dot_size(a) \ do {\ ss->Dot_Size = a; \ s7_symbol_set_value(s7, ss->dot_size_symbol, s7_make_integer(s7, ss->Dot_Size));\ } while (0) #else #define in_set_dot_size(a) ss->Dot_Size = a #endif #define DEFAULT_DOT_SIZE 1 #define MIN_DOT_SIZE 0 #define MAX_DOT_SIZE 100 #define grid_density(ss) ss->Grid_Density #if HAVE_SCHEME #define in_set_grid_density(a) \ do {\ ss->Grid_Density = a; \ s7_symbol_set_value(s7, ss->grid_density_symbol, s7_make_real(s7, ss->Grid_Density));\ } while (0) #else #define in_set_grid_density(a) ss->Grid_Density = a #endif #define DEFAULT_GRID_DENSITY 1.0 #define transform_normalization(ss) ss->Transform_Normalization #if HAVE_SCHEME #define in_set_transform_normalization(a) \ do {\ ss->Transform_Normalization = a; \ s7_symbol_set_value(s7, ss->transform_normalization_symbol, s7_make_integer(s7, ss->Transform_Normalization));\ } while (0) #else #define in_set_transform_normalization(a) ss->Transform_Normalization = a #endif #define DEFAULT_TRANSFORM_NORMALIZATION NORMALIZE_BY_CHANNEL #define ask_before_overwrite(ss) ss->Ask_Before_Overwrite #if HAVE_SCHEME #define set_ask_before_overwrite(a) \ do {\ ss->Ask_Before_Overwrite = a; \ s7_symbol_set_value(s7, ss->ask_before_overwrite_symbol, s7_make_boolean(s7, ss->Ask_Before_Overwrite));\ } while (0) #else #define set_ask_before_overwrite(a) ss->Ask_Before_Overwrite = a #endif #define DEFAULT_ASK_BEFORE_OVERWRITE false #define with_toolbar(ss) ss->With_Toolbar #if HAVE_SCHEME #define set_with_toolbar(a) \ do {\ ss->With_Toolbar = a; \ s7_symbol_set_value(s7, ss->with_toolbar_symbol, s7_make_boolean(s7, ss->With_Toolbar));\ } while (0) #else #define set_with_toolbar(a) ss->With_Toolbar = a #endif #if USE_GTK #define DEFAULT_WITH_TOOLBAR true #else #define DEFAULT_WITH_TOOLBAR false #endif #define with_tooltips(ss) ss->With_Tooltips #if HAVE_SCHEME #define in_set_with_tooltips(a) \ do {\ ss->With_Tooltips = a; \ s7_symbol_set_value(s7, ss->with_tooltips_symbol, s7_make_boolean(s7, ss->With_Tooltips));\ } while (0) #else #define in_set_with_tooltips(a) ss->With_Tooltips = a #endif #define DEFAULT_WITH_TOOLTIPS true #define with_menu_icons(ss) ss->With_Menu_Icons #if HAVE_SCHEME #define in_set_with_menu_icons(a) \ do {\ ss->With_Menu_Icons = a; \ s7_symbol_set_value(s7, ss->with_menu_icons_symbol, s7_make_boolean(s7, ss->With_Menu_Icons));\ } while (0) #else #define in_set_with_menu_icons(a) ss->With_Menu_Icons = a #endif #define DEFAULT_WITH_MENU_ICONS true #define save_as_dialog_src(ss) ss->Save_As_Dialog_Src #if HAVE_SCHEME #define in_set_save_as_dialog_src(a) \ do {\ ss->Save_As_Dialog_Src = a; \ s7_symbol_set_value(s7, ss->save_as_dialog_src_symbol, s7_make_boolean(s7, ss->Save_As_Dialog_Src));\ } while (0) #else #define in_set_save_as_dialog_src(a) ss->Save_As_Dialog_Src = a #endif #define DEFAULT_SAVE_AS_DIALOG_SRC false #define save_as_dialog_auto_comment(ss) ss->Save_As_Dialog_Auto_Comment #if HAVE_SCHEME #define in_set_save_as_dialog_auto_comment(a) \ do {\ ss->Save_As_Dialog_Auto_Comment = a; \ s7_symbol_set_value(s7, ss->save_as_dialog_auto_comment_symbol, s7_make_boolean(s7, ss->Save_As_Dialog_Auto_Comment));\ } while (0) #else #define in_set_save_as_dialog_auto_comment(a) ss->Save_As_Dialog_Auto_Comment = a #endif #define DEFAULT_SAVE_AS_DIALOG_AUTO_COMMENT false #define remember_sound_state(ss) ss->Remember_Sound_State #if HAVE_SCHEME #define set_remember_sound_state(a) \ do {\ ss->Remember_Sound_State = a; \ s7_symbol_set_value(s7, ss->remember_sound_state_symbol, s7_make_boolean(s7, ss->Remember_Sound_State));\ } while (0) #else #define set_remember_sound_state(a) ss->Remember_Sound_State = a #endif #define DEFAULT_REMEMBER_SOUND_STATE false #define ask_about_unsaved_edits(ss) ss->Ask_About_Unsaved_Edits #if HAVE_SCHEME #define set_ask_about_unsaved_edits(a) \ do {\ ss->Ask_About_Unsaved_Edits = a; \ s7_symbol_set_value(s7, ss->ask_about_unsaved_edits_symbol, s7_make_boolean(s7, ss->Ask_About_Unsaved_Edits));\ } while (0) #else #define set_ask_about_unsaved_edits(a) ss->Ask_About_Unsaved_Edits = a #endif #define DEFAULT_ASK_ABOUT_UNSAVED_EDITS false #define show_full_duration(ss) ss->Show_Full_Duration #if HAVE_SCHEME #define set_show_full_duration(a) \ do {\ ss->Show_Full_Duration = a; \ s7_symbol_set_value(s7, ss->show_full_duration_symbol, s7_make_boolean(s7, ss->Show_Full_Duration));\ } while (0) #else #define set_show_full_duration(a) ss->Show_Full_Duration = a #endif #define DEFAULT_SHOW_FULL_DURATION false #define initial_beg(ss) ss->Initial_Beg #if HAVE_SCHEME #define set_initial_beg(a) \ do {\ ss->Initial_Beg = a; \ s7_symbol_set_value(s7, ss->initial_beg_symbol, s7_make_real(s7, ss->Initial_Beg));\ } while (0) #else #define set_initial_beg(a) ss->Initial_Beg = a #endif #define DEFAULT_INITIAL_BEG 0.0 #define initial_dur(ss) ss->Initial_Dur #if HAVE_SCHEME #define set_initial_dur(a) \ do {\ ss->Initial_Dur = a; \ s7_symbol_set_value(s7, ss->initial_dur_symbol, s7_make_real(s7, ss->Initial_Dur));\ } while (0) #else #define set_initial_dur(a) ss->Initial_Dur = a #endif #define DEFAULT_INITIAL_DUR 0.1 #define show_full_range(ss) ss->Show_Full_Range #if HAVE_SCHEME #define set_show_full_range(a) \ do {\ ss->Show_Full_Range = a; \ s7_symbol_set_value(s7, ss->show_full_range_symbol, s7_make_boolean(s7, ss->Show_Full_Range));\ } while (0) #else #define set_show_full_range(a) ss->Show_Full_Range = a #endif #define DEFAULT_SHOW_FULL_RANGE false #define spectrum_end(ss) ss->Spectrum_End #if HAVE_SCHEME #define in_set_spectrum_end(a) \ do {\ ss->Spectrum_End = a; \ s7_symbol_set_value(s7, ss->spectrum_end_symbol, s7_make_real(s7, ss->Spectrum_End));\ } while (0) #else #define in_set_spectrum_end(a) ss->Spectrum_End = a #endif #define DEFAULT_SPECTRUM_END 1.0 #define spectrum_start(ss) ss->Spectrum_Start #if HAVE_SCHEME #define in_set_spectrum_start(a) \ do {\ ss->Spectrum_Start = a; \ s7_symbol_set_value(s7, ss->spectrum_start_symbol, s7_make_real(s7, ss->Spectrum_Start));\ } while (0) #else #define in_set_spectrum_start(a) ss->Spectrum_Start = a #endif #define DEFAULT_SPECTRUM_START 0.0 #define spectro_x_angle(ss) ss->Spectro_X_Angle #if HAVE_SCHEME #define in_set_spectro_x_angle(a) \ do {\ ss->Spectro_X_Angle = a; \ s7_symbol_set_value(s7, ss->spectro_x_angle_symbol, s7_make_real(s7, ss->Spectro_X_Angle));\ } while (0) #else #define in_set_spectro_x_angle(a) ss->Spectro_X_Angle = a #endif #if HAVE_GL #define DEFAULT_SPECTRO_X_ANGLE 300.0 #else #define DEFAULT_SPECTRO_X_ANGLE 90.0 #endif #define spectro_y_angle(ss) ss->Spectro_Y_Angle #if HAVE_SCHEME #define in_set_spectro_y_angle(a) \ do {\ ss->Spectro_Y_Angle = a; \ s7_symbol_set_value(s7, ss->spectro_y_angle_symbol, s7_make_real(s7, ss->Spectro_Y_Angle));\ } while (0) #else #define in_set_spectro_y_angle(a) ss->Spectro_Y_Angle = a #endif #if HAVE_GL #define DEFAULT_SPECTRO_Y_ANGLE 320.0 #else #define DEFAULT_SPECTRO_Y_ANGLE 0.0 #endif #define spectro_z_angle(ss) ss->Spectro_Z_Angle #if HAVE_SCHEME #define in_set_spectro_z_angle(a) \ do {\ ss->Spectro_Z_Angle = a; \ s7_symbol_set_value(s7, ss->spectro_z_angle_symbol, s7_make_real(s7, ss->Spectro_Z_Angle));\ } while (0) #else #define in_set_spectro_z_angle(a) ss->Spectro_Z_Angle = a #endif #if HAVE_GL #define DEFAULT_SPECTRO_Z_ANGLE 0.0 #else #define DEFAULT_SPECTRO_Z_ANGLE 358.0 #endif #define spectro_x_scale(ss) ss->Spectro_X_Scale #if HAVE_SCHEME #define in_set_spectro_x_scale(a) \ do {\ ss->Spectro_X_Scale = a; \ s7_symbol_set_value(s7, ss->spectro_x_scale_symbol, s7_make_real(s7, ss->Spectro_X_Scale));\ } while (0) #else #define in_set_spectro_x_scale(a) ss->Spectro_X_Scale = a #endif #if HAVE_GL #define DEFAULT_SPECTRO_X_SCALE 1.5 #define SPECTRO_X_SCALE_MAX 4.0 #else #define DEFAULT_SPECTRO_X_SCALE 1.0 #define SPECTRO_X_SCALE_MAX 2.0 #endif #define spectro_y_scale(ss) ss->Spectro_Y_Scale #if HAVE_SCHEME #define in_set_spectro_y_scale(a) \ do {\ ss->Spectro_Y_Scale = a; \ s7_symbol_set_value(s7, ss->spectro_y_scale_symbol, s7_make_real(s7, ss->Spectro_Y_Scale));\ } while (0) #else #define in_set_spectro_y_scale(a) ss->Spectro_Y_Scale = a #endif #if HAVE_GL #define DEFAULT_SPECTRO_Y_SCALE 1.0 #define SPECTRO_Y_SCALE_MAX 4.0 #else #define DEFAULT_SPECTRO_Y_SCALE 1.0 #define SPECTRO_Y_SCALE_MAX 2.0 #endif #define spectro_z_scale(ss) ss->Spectro_Z_Scale #if HAVE_SCHEME #define in_set_spectro_z_scale(a) \ do {\ ss->Spectro_Z_Scale = a; \ s7_symbol_set_value(s7, ss->spectro_z_scale_symbol, s7_make_real(s7, ss->Spectro_Z_Scale));\ } while (0) #else #define in_set_spectro_z_scale(a) ss->Spectro_Z_Scale = a #endif #if HAVE_GL #define DEFAULT_SPECTRO_Z_SCALE 1.0 #define SPECTRO_Z_SCALE_MAX 4.0 #else #define DEFAULT_SPECTRO_Z_SCALE 0.1 #define SPECTRO_Z_SCALE_MAX 1.0 #endif #define spectro_hop(ss) ss->Spectro_Hop #if HAVE_SCHEME #define in_set_spectro_hop(a) \ do {\ ss->Spectro_Hop = a; \ s7_symbol_set_value(s7, ss->spectro_hop_symbol, s7_make_integer(s7, ss->Spectro_Hop));\ } while (0) #else #define in_set_spectro_hop(a) ss->Spectro_Hop = a #endif #define DEFAULT_SPECTRO_HOP 4 #define color_map(ss) ss->Color_Map #if HAVE_SCHEME #define in_set_color_map(a) \ do {\ ss->Color_Map = a; \ s7_symbol_set_value(s7, ss->color_map_symbol, s7_make_integer(s7, ss->Color_Map));\ } while (0) #else #define in_set_color_map(a) ss->Color_Map = a #endif #define DEFAULT_COLOR_MAP 2 #define color_map_size(ss) ss->Color_Map_Size #if HAVE_SCHEME #define set_color_map_size(a) \ do {\ ss->Color_Map_Size = a; \ s7_symbol_set_value(s7, ss->color_map_size_symbol, s7_make_integer(s7, ss->Color_Map_Size));\ } while (0) #else #define set_color_map_size(a) ss->Color_Map_Size = a #endif #define DEFAULT_COLOR_MAP_SIZE 512 #define graph_style(ss) ss->Graph_Style #if HAVE_SCHEME #define in_set_graph_style(a) \ do {\ ss->Graph_Style = a; \ s7_symbol_set_value(s7, ss->graph_style_symbol, s7_make_integer(s7, ss->Graph_Style));\ } while (0) #else #define in_set_graph_style(a) ss->Graph_Style = a #endif #define DEFAULT_GRAPH_STYLE GRAPH_LINES #define region_graph_style(ss) ss->Region_Graph_Style #if HAVE_SCHEME #define set_region_graph_style(a) \ do {\ ss->Region_Graph_Style = a; \ s7_symbol_set_value(s7, ss->region_graph_style_symbol, s7_make_integer(s7, ss->Region_Graph_Style));\ } while (0) #else #define set_region_graph_style(a) ss->Region_Graph_Style = a #endif #define sinc_width(ss) ss->Sinc_Width #if HAVE_SCHEME #define set_sinc_width(a) \ do {\ ss->Sinc_Width = a; \ s7_symbol_set_value(s7, ss->sinc_width_symbol, s7_make_integer(s7, ss->Sinc_Width));\ } while (0) #else #define set_sinc_width(a) ss->Sinc_Width = a #endif #define DEFAULT_SINC_WIDTH 10 #define with_verbose_cursor(ss) ss->With_Verbose_Cursor #if HAVE_SCHEME #define in_set_with_verbose_cursor(a) \ do {\ ss->With_Verbose_Cursor = a; \ s7_symbol_set_value(s7, ss->with_verbose_cursor_symbol, s7_make_boolean(s7, ss->With_Verbose_Cursor));\ } while (0) #else #define in_set_with_verbose_cursor(a) ss->With_Verbose_Cursor = a #endif #define DEFAULT_WITH_VERBOSE_CURSOR false #define with_inset_graph(ss) ss->With_Inset_Graph #if HAVE_SCHEME #define set_with_inset_graph(a) \ do {\ ss->With_Inset_Graph = a; \ s7_symbol_set_value(s7, ss->with_inset_graph_symbol, s7_make_boolean(s7, ss->With_Inset_Graph));\ } while (0) #else #define set_with_inset_graph(a) ss->With_Inset_Graph = a #endif #define DEFAULT_WITH_INSET_GRAPH false #define with_interrupts(ss) ss->With_Interrupts #if HAVE_SCHEME #define set_with_interrupts(a) \ do {\ ss->With_Interrupts = a; \ s7_symbol_set_value(s7, ss->with_interrupts_symbol, s7_make_boolean(s7, ss->With_Interrupts));\ } while (0) #else #define set_with_interrupts(a) ss->With_Interrupts = a #endif #define DEFAULT_WITH_INTERRUPTS true #define with_smpte_label(ss) ss->With_Smpte_Label #if HAVE_SCHEME #define set_with_smpte_label(a) \ do {\ ss->With_Smpte_Label = a; \ s7_symbol_set_value(s7, ss->with_smpte_label_symbol, s7_make_boolean(s7, ss->With_Smpte_Label));\ } while (0) #else #define set_with_smpte_label(a) ss->With_Smpte_Label = a #endif #define DEFAULT_WITH_SMPTE_LABEL false #define with_pointer_focus(ss) ss->With_Pointer_Focus #if HAVE_SCHEME #define set_with_pointer_focus(a) \ do {\ ss->With_Pointer_Focus = a; \ s7_symbol_set_value(s7, ss->with_pointer_focus_symbol, s7_make_boolean(s7, ss->With_Pointer_Focus));\ } while (0) #else #define set_with_pointer_focus(a) ss->With_Pointer_Focus = a #endif #define DEFAULT_WITH_POINTER_FOCUS false #define selection_creates_region(ss) ss->Selection_Creates_Region #if HAVE_SCHEME #define set_selection_creates_region(a) \ do {\ ss->Selection_Creates_Region = a; \ s7_symbol_set_value(s7, ss->selection_creates_region_symbol, s7_make_boolean(s7, ss->Selection_Creates_Region));\ } while (0) #else #define set_selection_creates_region(a) ss->Selection_Creates_Region = a #endif #define DEFAULT_SELECTION_CREATES_REGION true #define zoom_focus_style(ss) ss->Zoom_Focus_Style #if HAVE_SCHEME #define set_zoom_focus_style(a) \ do {\ ss->Zoom_Focus_Style = a; \ s7_symbol_set_value(s7, ss->zoom_focus_style_symbol, s7_make_integer(s7, ss->Zoom_Focus_Style));\ } while (0) #else #define set_zoom_focus_style(a) ss->Zoom_Focus_Style = a #endif #define DEFAULT_ZOOM_FOCUS_STYLE ZOOM_FOCUS_ACTIVE #define eps_file(ss) ss->Eps_File #if HAVE_SCHEME #define set_eps_file(a) \ do {\ ss->Eps_File = a; \ s7_symbol_set_value(s7, ss->eps_file_symbol, s7_make_string(s7, ss->Eps_File));\ } while (0) #else #define set_eps_file(a) ss->Eps_File = a #endif #define DEFAULT_EPS_FILE "snd.eps" #define eps_left_margin(ss) ss->Eps_Left_Margin #if HAVE_SCHEME #define set_eps_left_margin(a) \ do {\ ss->Eps_Left_Margin = a; \ s7_symbol_set_value(s7, ss->eps_left_margin_symbol, s7_make_real(s7, ss->Eps_Left_Margin));\ } while (0) #else #define set_eps_left_margin(a) ss->Eps_Left_Margin = a #endif #define DEFAULT_EPS_LEFT_MARGIN 0.0 #define eps_bottom_margin(ss) ss->Eps_Bottom_Margin #if HAVE_SCHEME #define set_eps_bottom_margin(a) \ do {\ ss->Eps_Bottom_Margin = a; \ s7_symbol_set_value(s7, ss->eps_bottom_margin_symbol, s7_make_real(s7, ss->Eps_Bottom_Margin));\ } while (0) #else #define set_eps_bottom_margin(a) ss->Eps_Bottom_Margin = a #endif #define DEFAULT_EPS_BOTTOM_MARGIN 0.0 #define eps_size(ss) ss->Eps_Size #if HAVE_SCHEME #define set_eps_size(a) \ do {\ ss->Eps_Size = a; \ s7_symbol_set_value(s7, ss->eps_size_symbol, s7_make_real(s7, ss->Eps_Size));\ } while (0) #else #define set_eps_size(a) ss->Eps_Size = a #endif #define DEFAULT_EPS_SIZE 1.0 #define tiny_font(ss) ss->Tiny_Font #if HAVE_SCHEME #define in_set_tiny_font(a) \ do {\ ss->Tiny_Font = a; \ s7_symbol_set_value(s7, ss->tiny_font_symbol, s7_make_string(s7, ss->Tiny_Font));\ } while (0) #else #define in_set_tiny_font(a) ss->Tiny_Font = a #endif #define peaks_font(ss) ss->Peaks_Font #if HAVE_SCHEME #define in_set_peaks_font(a) \ do {\ ss->Peaks_Font = a; \ s7_symbol_set_value(s7, ss->peaks_font_symbol, s7_make_string(s7, ss->Peaks_Font));\ } while (0) #else #define in_set_peaks_font(a) ss->Peaks_Font = a #endif #define bold_peaks_font(ss) ss->Bold_Peaks_Font #if HAVE_SCHEME #define in_set_bold_peaks_font(a) \ do {\ ss->Bold_Peaks_Font = a; \ s7_symbol_set_value(s7, ss->bold_peaks_font_symbol, s7_make_string(s7, ss->Bold_Peaks_Font));\ } while (0) #else #define in_set_bold_peaks_font(a) ss->Bold_Peaks_Font = a #endif #define axis_label_font(ss) ss->Axis_Label_Font #if HAVE_SCHEME #define in_set_axis_label_font(a) \ do {\ ss->Axis_Label_Font = a; \ s7_symbol_set_value(s7, ss->axis_label_font_symbol, s7_make_string(s7, ss->Axis_Label_Font));\ } while (0) #else #define in_set_axis_label_font(a) ss->Axis_Label_Font = a #endif #define axis_numbers_font(ss) ss->Axis_Numbers_Font #if HAVE_SCHEME #define in_set_axis_numbers_font(a) \ do {\ ss->Axis_Numbers_Font = a; \ s7_symbol_set_value(s7, ss->axis_numbers_font_symbol, s7_make_string(s7, ss->Axis_Numbers_Font));\ } while (0) #else #define in_set_axis_numbers_font(a) ss->Axis_Numbers_Font = a #endif #define listener_font(ss) ss->Listener_Font #if HAVE_SCHEME #define in_set_listener_font(a) \ do {\ ss->Listener_Font = a; \ s7_symbol_set_value(s7, ss->listener_font_symbol, s7_make_string(s7, ss->Listener_Font));\ } while (0) #else #define in_set_listener_font(a) ss->Listener_Font = a #endif #define save_state_file(ss) ss->Save_State_File #if HAVE_SCHEME #define in_set_save_state_file(a) \ do {\ ss->Save_State_File = a; \ s7_symbol_set_value(s7, ss->save_state_file_symbol, s7_make_string(s7, ss->Save_State_File));\ } while (0) #else #define in_set_save_state_file(a) ss->Save_State_File = a #endif #define DEFAULT_SAVE_STATE_FILE "saved-snd." Xen_file_extension #define temp_dir(ss) ss->Temp_Dir #if HAVE_SCHEME #define set_temp_dir(a) \ do {\ ss->Temp_Dir = a; \ s7_symbol_set_value(s7, ss->temp_dir_symbol, s7_make_string(s7, ss->Temp_Dir));\ } while (0) #else #define set_temp_dir(a) ss->Temp_Dir = a #endif #ifndef MUS_DEFAULT_TEMP_DIR #define MUS_DEFAULT_TEMP_DIR NULL #endif #define save_dir(ss) ss->Save_Dir #if HAVE_SCHEME #define set_save_dir(a) \ do {\ ss->Save_Dir = a; \ s7_symbol_set_value(s7, ss->save_dir_symbol, s7_make_string(s7, ss->Save_Dir));\ } while (0) #else #define set_save_dir(a) ss->Save_Dir = a #endif #ifndef MUS_DEFAULT_SAVE_DIR #define MUS_DEFAULT_SAVE_DIR NULL #endif #define ladspa_dir(ss) ss->Ladspa_Dir #if HAVE_SCHEME #define set_ladspa_dir(a) \ do {\ ss->Ladspa_Dir = a; \ s7_symbol_set_value(s7, ss->ladspa_dir_symbol, s7_make_string(s7, ss->Ladspa_Dir));\ } while (0) #else #define set_ladspa_dir(a) ss->Ladspa_Dir = a #endif #ifndef DEFAULT_LADSPA_DIR #define DEFAULT_LADSPA_DIR NULL #endif #define peak_env_dir(ss) ss->Peak_Env_Dir #if HAVE_SCHEME #define set_peak_env_dir(a) \ do {\ ss->Peak_Env_Dir = a; \ s7_symbol_set_value(s7, ss->peak_env_dir_symbol, s7_make_string(s7, ss->Peak_Env_Dir));\ } while (0) #else #define set_peak_env_dir(a) ss->Peak_Env_Dir = a #endif #ifndef DEFAULT_PEAK_ENV_DIR #define DEFAULT_PEAK_ENV_DIR NULL #endif #define open_file_dialog_directory(ss) ss->Open_File_Dialog_Directory #if HAVE_SCHEME #define set_open_file_dialog_directory(a) \ do {\ ss->Open_File_Dialog_Directory = a; \ s7_symbol_set_value(s7, ss->open_file_dialog_directory_symbol, s7_make_string(s7, ss->Open_File_Dialog_Directory));\ } while (0) #else #define set_open_file_dialog_directory(a) ss->Open_File_Dialog_Directory = a #endif #define wavelet_type(ss) ss->Wavelet_Type #if HAVE_SCHEME #define in_set_wavelet_type(a) \ do {\ ss->Wavelet_Type = a; \ s7_symbol_set_value(s7, ss->wavelet_type_symbol, s7_make_integer(s7, ss->Wavelet_Type));\ } while (0) #else #define in_set_wavelet_type(a) ss->Wavelet_Type = a #endif #define DEFAULT_WAVELET_TYPE 0 #define transform_type(ss) ss->Transform_Type #if HAVE_SCHEME #define in_set_transform_type(a) \ do {\ ss->Transform_Type = a; \ s7_symbol_set_value(s7, ss->transform_type_symbol, s7_make_integer(s7, ss->Transform_Type));\ } while (0) #else #define in_set_transform_type(a) ss->Transform_Type = a #endif #define DEFAULT_TRANSFORM_TYPE FOURIER #define show_selection_transform(ss) ss->Show_Selection_Transform #if HAVE_SCHEME #define in_set_show_selection_transform(a) \ do {\ ss->Show_Selection_Transform = a; \ s7_symbol_set_value(s7, ss->show_selection_transform_symbol, s7_make_boolean(s7, ss->Show_Selection_Transform));\ } while (0) #else #define in_set_show_selection_transform(a) ss->Show_Selection_Transform = a #endif #define DEFAULT_SHOW_SELECTION_TRANSFORM false #define with_mix_tags(ss) ss->With_Mix_Tags #if HAVE_SCHEME #define set_with_mix_tags(a) \ do {\ ss->With_Mix_Tags = a; \ s7_symbol_set_value(s7, ss->with_mix_tags_symbol, s7_make_boolean(s7, ss->With_Mix_Tags));\ } while (0) #else #define set_with_mix_tags(a) ss->With_Mix_Tags = a #endif #if USE_NO_GUI #define DEFAULT_WITH_MIX_TAGS false #else #define DEFAULT_WITH_MIX_TAGS true #endif #define with_relative_panes(ss) ss->With_Relative_Panes #if HAVE_SCHEME #define set_with_relative_panes(a) \ do {\ ss->With_Relative_Panes = a; \ s7_symbol_set_value(s7, ss->with_relative_panes_symbol, s7_make_boolean(s7, ss->With_Relative_Panes));\ } while (0) #else #define set_with_relative_panes(a) ss->With_Relative_Panes = a #endif #define DEFAULT_WITH_RELATIVE_PANES true #define with_gl(ss) ss->With_GL #if HAVE_SCHEME #define in_set_with_gl(a) \ do {\ ss->With_GL = a; \ s7_symbol_set_value(s7, ss->with_gl_symbol, s7_make_boolean(s7, ss->With_GL));\ } while (0) #else #define in_set_with_gl(a) ss->With_GL = a #endif #if HAVE_GL #define DEFAULT_WITH_GL true #else #define DEFAULT_WITH_GL false #endif #define with_background_processes(ss) ss->With_Background_Processes #if HAVE_SCHEME #define set_with_background_processes(a) \ do {\ ss->With_Background_Processes = a; \ s7_symbol_set_value(s7, ss->with_background_processes_symbol, s7_make_boolean(s7, ss->With_Background_Processes));\ } while (0) #else #define set_with_background_processes(a) ss->With_Background_Processes = a #endif #define DEFAULT_WITH_BACKGROUND_PROCESSES true #define with_file_monitor(ss) ss->With_File_Monitor #if HAVE_SCHEME #define set_with_file_monitor(a) \ do {\ ss->With_File_Monitor = a; \ s7_symbol_set_value(s7, ss->with_file_monitor_symbol, s7_make_boolean(s7, ss->With_File_Monitor));\ } while (0) #else #define set_with_file_monitor(a) ss->With_File_Monitor = a #endif #define DEFAULT_WITH_FILE_MONITOR true #define wavo_hop(ss) ss->Wavo_Hop #if HAVE_SCHEME #define in_set_wavo_hop(a) \ do {\ ss->Wavo_Hop = a; \ s7_symbol_set_value(s7, ss->wavo_hop_symbol, s7_make_integer(s7, ss->Wavo_Hop));\ } while (0) #else #define in_set_wavo_hop(a) ss->Wavo_Hop = a #endif #define DEFAULT_WAVO_HOP 3 #define wavo_trace(ss) ss->Wavo_Trace #if HAVE_SCHEME #define in_set_wavo_trace(a) \ do {\ ss->Wavo_Trace = a; \ s7_symbol_set_value(s7, ss->wavo_trace_symbol, s7_make_integer(s7, ss->Wavo_Trace));\ } while (0) #else #define in_set_wavo_trace(a) ss->Wavo_Trace = a #endif #define DEFAULT_WAVO_TRACE 64 #define x_axis_style(ss) ss->X_Axis_Style #if HAVE_SCHEME #define in_set_x_axis_style(a) \ do {\ ss->X_Axis_Style = a; \ s7_symbol_set_value(s7, ss->x_axis_style_symbol, s7_make_integer(s7, ss->X_Axis_Style));\ } while (0) #else #define in_set_x_axis_style(a) ss->X_Axis_Style = a #endif #define DEFAULT_X_AXIS_STYLE X_AXIS_IN_SECONDS #define beats_per_minute(ss) ss->Beats_Per_Minute #if HAVE_SCHEME #define in_set_beats_per_minute(a) \ do {\ ss->Beats_Per_Minute = a; \ s7_symbol_set_value(s7, ss->beats_per_minute_symbol, s7_make_real(s7, ss->Beats_Per_Minute));\ } while (0) #else #define in_set_beats_per_minute(a) ss->Beats_Per_Minute = a #endif #define DEFAULT_BEATS_PER_MINUTE 60.0 #define beats_per_measure(ss) ss->Beats_Per_Measure #if HAVE_SCHEME #define in_set_beats_per_measure(a) \ do {\ ss->Beats_Per_Measure = a; \ s7_symbol_set_value(s7, ss->beats_per_measure_symbol, s7_make_integer(s7, ss->Beats_Per_Measure));\ } while (0) #else #define in_set_beats_per_measure(a) ss->Beats_Per_Measure = a #endif #define DEFAULT_BEATS_PER_MEASURE 4 #define zero_pad(ss) ss->Zero_Pad #if HAVE_SCHEME #define in_set_zero_pad(a) \ do {\ ss->Zero_Pad = a; \ s7_symbol_set_value(s7, ss->zero_pad_symbol, s7_make_integer(s7, ss->Zero_Pad));\ } while (0) #else #define in_set_zero_pad(a) ss->Zero_Pad = a #endif #define DEFAULT_ZERO_PAD 0 #define MAX_ZERO_PAD 1000 #define show_transform_peaks(ss) ss->Show_Transform_Peaks #if HAVE_SCHEME #define in_set_show_transform_peaks(a) \ do {\ ss->Show_Transform_Peaks = a; \ s7_symbol_set_value(s7, ss->show_transform_peaks_symbol, s7_make_boolean(s7, ss->Show_Transform_Peaks));\ } while (0) #else #define in_set_show_transform_peaks(a) ss->Show_Transform_Peaks = a #endif #define DEFAULT_SHOW_TRANSFORM_PEAKS false #define show_indices(ss) ss->Show_Indices #if HAVE_SCHEME #define set_show_indices(a) \ do {\ ss->Show_Indices = a; \ s7_symbol_set_value(s7, ss->show_indices_symbol, s7_make_boolean(s7, ss->Show_Indices));\ } while (0) #else #define set_show_indices(a) ss->Show_Indices = a #endif #define DEFAULT_SHOW_INDICES false #define show_y_zero(ss) ss->Show_Y_Zero #if HAVE_SCHEME #define in_set_show_y_zero(a) \ do {\ ss->Show_Y_Zero = a; \ s7_symbol_set_value(s7, ss->show_y_zero_symbol, s7_make_boolean(s7, ss->Show_Y_Zero));\ } while (0) #else #define in_set_show_y_zero(a) ss->Show_Y_Zero = a #endif #define DEFAULT_SHOW_Y_ZERO false #define show_grid(ss) ss->Show_Grid #if HAVE_SCHEME #define in_set_show_grid(a) \ do {\ ss->Show_Grid = a; \ s7_symbol_set_value(s7, ss->show_grid_symbol, s7_make_boolean(s7, ss->Show_Grid));\ } while (0) #else #define in_set_show_grid(a) ss->Show_Grid = a #endif #define DEFAULT_SHOW_GRID NO_GRID #define show_sonogram_cursor(ss) ss->Show_Sonogram_Cursor #if HAVE_SCHEME #define in_set_show_sonogram_cursor(a) \ do {\ ss->Show_Sonogram_Cursor = a; \ s7_symbol_set_value(s7, ss->show_sonogram_cursor_symbol, s7_make_boolean(s7, ss->Show_Sonogram_Cursor));\ } while (0) #else #define in_set_show_sonogram_cursor(a) ss->Show_Sonogram_Cursor = a #endif #define DEFAULT_SHOW_SONOGRAM_CURSOR false #define show_axes(ss) ss->Show_Axes #if HAVE_SCHEME #define in_set_show_axes(a) \ do {\ ss->Show_Axes = a; \ s7_symbol_set_value(s7, ss->show_axes_symbol, s7_make_integer(s7, ss->Show_Axes));\ } while (0) #else #define in_set_show_axes(a) ss->Show_Axes = a #endif #define DEFAULT_SHOW_AXES SHOW_ALL_AXES #define show_mix_waveforms(ss) ss->Show_Mix_Waveforms #if HAVE_SCHEME #define in_set_show_mix_waveforms(a) \ do {\ ss->Show_Mix_Waveforms = a; \ s7_symbol_set_value(s7, ss->show_mix_waveforms_symbol, s7_make_boolean(s7, ss->Show_Mix_Waveforms));\ } while (0) #else #define in_set_show_mix_waveforms(a) ss->Show_Mix_Waveforms = a #endif #define DEFAULT_SHOW_MIX_WAVEFORMS true #define mix_waveform_height(ss) ss->Mix_Waveform_Height #if HAVE_SCHEME #define in_set_mix_waveform_height(a) \ do {\ ss->Mix_Waveform_Height = a; \ s7_symbol_set_value(s7, ss->mix_waveform_height_symbol, s7_make_integer(s7, ss->Mix_Waveform_Height));\ } while (0) #else #define in_set_mix_waveform_height(a) ss->Mix_Waveform_Height = a #endif #define DEFAULT_MIX_WAVEFORM_HEIGHT 20 #define show_marks(ss) ss->Show_Marks #if HAVE_SCHEME #define in_set_show_marks(a) \ do {\ ss->Show_Marks = a; \ s7_symbol_set_value(s7, ss->show_marks_symbol, s7_make_boolean(s7, ss->Show_Marks));\ } while (0) #else #define in_set_show_marks(a) ss->Show_Marks = a #endif #define DEFAULT_SHOW_MARKS true #define fft_log_magnitude(ss) ss->Fft_Log_Magnitude #if HAVE_SCHEME #define in_set_fft_log_magnitude(a) \ do {\ ss->Fft_Log_Magnitude = a; \ s7_symbol_set_value(s7, ss->fft_log_magnitude_symbol, s7_make_boolean(s7, ss->Fft_Log_Magnitude));\ } while (0) #else #define in_set_fft_log_magnitude(a) ss->Fft_Log_Magnitude = a #endif #define DEFAULT_FFT_LOG_MAGNITUDE false #define fft_log_frequency(ss) ss->Fft_Log_Frequency #if HAVE_SCHEME #define in_set_fft_log_frequency(a) \ do {\ ss->Fft_Log_Frequency = a; \ s7_symbol_set_value(s7, ss->fft_log_frequency_symbol, s7_make_boolean(s7, ss->Fft_Log_Frequency));\ } while (0) #else #define in_set_fft_log_frequency(a) ss->Fft_Log_Frequency = a #endif #define DEFAULT_FFT_LOG_FREQUENCY false #define fft_with_phases(ss) ss->Fft_With_Phases #if HAVE_SCHEME #define in_set_fft_with_phases(a) \ do {\ ss->Fft_With_Phases = a; \ s7_symbol_set_value(s7, ss->fft_with_phases_symbol, s7_make_boolean(s7, ss->Fft_With_Phases));\ } while (0) #else #define in_set_fft_with_phases(a) ss->Fft_With_Phases = a #endif #define DEFAULT_FFT_WITH_PHASES false #define cursor_style(ss) ss->Cursor_Style #if HAVE_SCHEME #define in_set_cursor_style(a) \ do {\ ss->Cursor_Style = a; \ s7_symbol_set_value(s7, ss->cursor_style_symbol, s7_make_integer(s7, ss->Cursor_Style));\ } while (0) #else #define in_set_cursor_style(a) ss->Cursor_Style = a #endif #define DEFAULT_CURSOR_STYLE CURSOR_CROSS #define tracking_cursor_style(ss) ss->Tracking_Cursor_Style #if HAVE_SCHEME #define in_set_tracking_cursor_style(a) \ do {\ ss->Tracking_Cursor_Style = a; \ s7_symbol_set_value(s7, ss->tracking_cursor_style_symbol, s7_make_integer(s7, ss->Tracking_Cursor_Style));\ } while (0) #else #define in_set_tracking_cursor_style(a) ss->Tracking_Cursor_Style = a #endif #define DEFAULT_TRACKING_CURSOR_STYLE CURSOR_LINE #define cursor_size(ss) ss->Cursor_Size #if HAVE_SCHEME #define in_set_cursor_size(a) \ do {\ ss->Cursor_Size = a; \ s7_symbol_set_value(s7, ss->cursor_size_symbol, s7_make_integer(s7, ss->Cursor_Size));\ } while (0) #else #define in_set_cursor_size(a) ss->Cursor_Size = a #endif #define DEFAULT_CURSOR_SIZE 15 #define channel_style(ss) ss->Channel_Style #if HAVE_SCHEME #define in_set_channel_style(a) \ do {\ ss->Channel_Style = a; \ s7_symbol_set_value(s7, ss->channel_style_symbol, s7_make_integer(s7, ss->Channel_Style));\ } while (0) #else #define in_set_channel_style(a) ss->Channel_Style = a #endif #define DEFAULT_CHANNEL_STYLE CHANNELS_COMBINED #define sync_style(ss) ss->Sync_Style #if HAVE_SCHEME #define set_sync_style(a) \ do {\ ss->Sync_Style = a; \ s7_symbol_set_value(s7, ss->sync_style_symbol, s7_make_integer(s7, ss->Sync_Style));\ } while (0) #else #define set_sync_style(a) ss->Sync_Style = a #endif #define DEFAULT_SYNC_STYLE SYNC_BY_SOUND #define sound_style(ss) ss->Sound_Style #define set_sound_style(a) ss->Sound_Style = a #define DEFAULT_SOUND_STYLE SOUNDS_VERTICAL #define listener_prompt(ss) ss->Listener_Prompt #if HAVE_SCHEME #define in_set_listener_prompt(a) \ do {\ ss->Listener_Prompt = a; \ s7_symbol_set_value(s7, ss->listener_prompt_symbol, s7_make_string(s7, ss->Listener_Prompt));\ } while (0) #else #define in_set_listener_prompt(a) ss->Listener_Prompt = a #endif #define DEFAULT_LISTENER_PROMPT ">" #define print_length(ss) ss->Print_Length #if HAVE_SCHEME #define set_print_length(a) \ do {\ ss->Print_Length = a; \ s7_symbol_set_value(s7, ss->print_length_symbol, s7_make_integer(s7, ss->Print_Length));\ } while (0) #else #define set_print_length(a) ss->Print_Length = a #endif #define DEFAULT_PRINT_LENGTH 12 #define view_files_sort(ss) ss->View_Files_Sort #if HAVE_SCHEME #define set_view_files_sort(a) \ do {\ ss->View_Files_Sort = a; \ s7_symbol_set_value(s7, ss->view_files_sort_symbol, s7_make_integer(s7, ss->View_Files_Sort));\ } while (0) #else #define set_view_files_sort(a) ss->View_Files_Sort = a #endif #define DEFAULT_VIEW_FILES_SORT SORT_A_TO_Z #define enved_clipping(ss) ss->enved->clipping #define in_set_enved_clipping(a) ss->enved->clipping = a #define DEFAULT_ENVED_CLIPPING true #define enved_with_wave(ss) ss->Enved_With_Wave #if HAVE_SCHEME #define in_set_enved_with_wave(a) \ do {\ ss->Enved_With_Wave = a; \ s7_symbol_set_value(s7, ss->enved_with_wave_symbol, s7_make_boolean(s7, ss->Enved_With_Wave));\ } while (0) #else #define in_set_enved_with_wave(a) ss->Enved_With_Wave = a #endif #define DEFAULT_ENVED_WITH_WAVE false #define enved_filter_order(ss) ss->Enved_Filter_Order #if HAVE_SCHEME #define in_set_enved_filter_order(a) \ do {\ ss->Enved_Filter_Order = a; \ s7_symbol_set_value(s7, ss->enved_filter_order_symbol, s7_make_integer(s7, ss->Enved_Filter_Order));\ } while (0) #else #define in_set_enved_filter_order(a) ss->Enved_Filter_Order = a #endif #define DEFAULT_ENVED_FILTER_ORDER 40 #define enved_in_dB(ss) ss->enved->in_dB #define in_set_enved_in_dB(a) ss->enved->in_dB = a #define DEFAULT_ENVED_IN_DB false #define enved_target(ss) ss->Enved_Target #if HAVE_SCHEME #define in_set_enved_target(a) \ do {\ ss->Enved_Target = a; \ s7_symbol_set_value(s7, ss->enved_target_symbol, s7_make_integer(s7, ss->Enved_Target));\ } while (0) #else #define in_set_enved_target(a) ss->Enved_Target = a #endif #define DEFAULT_ENVED_TARGET ENVED_AMPLITUDE #define enved_base(ss) ss->Enved_Base #if HAVE_SCHEME #define in_set_enved_base(a) \ do {\ ss->Enved_Base = a; \ s7_symbol_set_value(s7, ss->enved_base_symbol, s7_make_real(s7, ss->Enved_Base));\ } while (0) #else #define in_set_enved_base(a) ss->Enved_Base = a #endif #define DEFAULT_ENVED_BASE 1.0 #define enved_power(ss) ss->Enved_Power #if HAVE_SCHEME #define set_enved_power(a) \ do {\ ss->Enved_Power = a; \ s7_symbol_set_value(s7, ss->enved_power_symbol, s7_make_real(s7, ss->Enved_Power));\ } while (0) #else #define set_enved_power(a) ss->Enved_Power = a #endif #define DEFAULT_ENVED_POWER 3.0 #define enved_style(ss) ss->Enved_Style #if HAVE_SCHEME #define set_enved_style(a) \ do {\ ss->Enved_Style = a; \ s7_symbol_set_value(s7, ss->enved_style_symbol, s7_make_integer(s7, ss->Enved_Style));\ } while (0) #else #define set_enved_style(a) ss->Enved_Style = a #endif #define DEFAULT_ENVED_STYLE ENVELOPE_LINEAR #define in_graph_cursor(ss) ss->Graph_Cursor #define clipping(ss) ss->Clipping #if HAVE_SCHEME #define set_clipping(a) \ do {\ ss->Clipping = a; \ s7_symbol_set_value(s7, ss->clipping_symbol, s7_make_boolean(s7, ss->Clipping));\ } while (0) #else #define set_clipping(a) ss->Clipping = a #endif #define DEFAULT_CLIPPING false #define html_dir(ss) ss->HTML_Dir #if HAVE_SCHEME #define set_html_dir_1(a) \ do {\ ss->HTML_Dir = a; \ s7_symbol_set_value(s7, ss->html_dir_symbol, s7_make_string(s7, ss->HTML_Dir));\ } while (0) #else #define set_html_dir_1(a) ss->HTML_Dir = a #endif #define DEFAULT_HTML_DIR "." #define html_program(ss) ss->HTML_Program #if HAVE_SCHEME #define set_html_program(a) \ do {\ ss->HTML_Program = a; \ s7_symbol_set_value(s7, ss->html_program_symbol, s7_make_string(s7, ss->HTML_Program));\ } while (0) #else #define set_html_program(a) ss->HTML_Program = a #endif #define DEFAULT_HTML_PROGRAM "firefox" #define graphs_horizontal(ss) ss->Graphs_Horizontal #if HAVE_SCHEME #define in_set_graphs_horizontal(a) \ do {\ ss->Graphs_Horizontal = a; \ s7_symbol_set_value(s7, ss->graphs_horizontal_symbol, s7_make_boolean(s7, ss->Graphs_Horizontal));\ } while (0) #else #define in_set_graphs_horizontal(a) ss->Graphs_Horizontal = a #endif #define DEFAULT_GRAPHS_HORIZONTAL true #define mix_tag_width(ss) ss->Mix_Tag_Width #if HAVE_SCHEME #define set_mix_tag_width(a) \ do {\ ss->Mix_Tag_Width = a; \ s7_symbol_set_value(s7, ss->mix_tag_width_symbol, s7_make_integer(s7, ss->Mix_Tag_Width));\ } while (0) #else #define set_mix_tag_width(a) ss->Mix_Tag_Width = a #endif #define DEFAULT_MIX_TAG_WIDTH 6 #define mix_tag_height(ss) ss->Mix_Tag_Height #if HAVE_SCHEME #define set_mix_tag_height(a) \ do {\ ss->Mix_Tag_Height = a; \ s7_symbol_set_value(s7, ss->mix_tag_height_symbol, s7_make_integer(s7, ss->Mix_Tag_Height));\ } while (0) #else #define set_mix_tag_height(a) ss->Mix_Tag_Height = a #endif #define DEFAULT_MIX_TAG_HEIGHT 14 #define mark_tag_width(ss) ss->Mark_Tag_Width #if HAVE_SCHEME #define set_mark_tag_width(a) \ do {\ ss->Mark_Tag_Width = a; \ s7_symbol_set_value(s7, ss->mark_tag_width_symbol, s7_make_integer(s7, ss->Mark_Tag_Width));\ } while (0) #else #define set_mark_tag_width(a) ss->Mark_Tag_Width = a #endif #define DEFAULT_MARK_TAG_WIDTH 10 #define mark_tag_height(ss) ss->Mark_Tag_Height #if HAVE_SCHEME #define set_mark_tag_height(a) \ do {\ ss->Mark_Tag_Height = a; \ s7_symbol_set_value(s7, ss->mark_tag_height_symbol, s7_make_integer(s7, ss->Mark_Tag_Height));\ } while (0) #else #define set_mark_tag_height(a) ss->Mark_Tag_Height = a #endif #define DEFAULT_MARK_TAG_HEIGHT 4 #define min_dB(ss) ss->Min_dB #if HAVE_SCHEME #define set_min_dB(a) \ do {\ ss->Min_dB = a; \ s7_symbol_set_value(s7, ss->min_db_symbol, s7_make_real(s7, ss->Min_dB));\ } while (0) #else #define set_min_dB(a) ss->Min_dB = a #endif #define DEFAULT_MIN_DB -60.0 #define play_arrow_size(ss) ss->Play_Arrow_Size #if HAVE_SCHEME #define set_play_arrow_size(a) \ do {\ ss->Play_Arrow_Size = a; \ s7_symbol_set_value(s7, ss->play_arrow_size_symbol, s7_make_integer(s7, ss->Play_Arrow_Size));\ } while (0) #else #define set_play_arrow_size(a) ss->Play_Arrow_Size = a #endif #define DEFAULT_PLAY_ARROW_SIZE 10 #define HAVE_GTK use USE_GTK not HAVE! #define HAVE_MOTIF use USE_MOTIF not HAVE! /* I keep using these HAVE_* forms by mistake */ #endif snd-16.1/sndins/0000755000076400007640000000000012004766107011634 5ustar bilbilsnd-16.1/sndins/Makefile.in0000644000076400007640000000233512433105741013701 0ustar bilbil# Makefile for libsndins.so prefix = @prefix@ srcdir = @srcdir@ libdir = $(prefix)/lib top_builddir = .. top_srcdir = @top_srcdir@ VPATH = @srcdir@ includedir = @includedir@ SHELL = @SHELL@ mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CC = @CC@ DEFS = -DUSE_SND=0 @DEFS@ LDFLAGS = @LDFLAGS@ CFLAGS = @CFLAGS@ -fPIC @XEN_CFLAGS@ @GSL_CFLAGS@ LIBS = @LIBS@ @XEN_LIBS@ @GSL_LIBS@ INSTALL = @INSTALL@ SO_INSTALL = @SO_INSTALL@ SO_LD = @SO_LD@ A_LD = ar A_LD_FLAGS = cr LD_FLAGS = @LD_FLAGS@ LDSO_FLAGS = @LDSO_FLAGS@ OBJS = sndins.o $(top_builddir)/sndlib.a SO_TARGET = libsndins.so A_TARGET = libsndins.a LIB_TARGET = sndins.so .c.o: $(CC) -c $(DEFS) $(CFLAGS) -I$(top_builddir) -I$(top_srcdir) $< sndins: $(OBJS) $(SO_LD) $(LDSO_FLAGS) $(LDFLAGS) -o $(SO_TARGET) $(OBJS) $(LIBS) $(A_LD) $(A_LD_FLAGS) $(A_TARGET) $(OBJS) ranlib $(A_TARGET) cp $(SO_TARGET) $(LIB_TARGET) install: sndins $(mkinstalldirs) $(libdir) $(mkinstalldirs) $(includedir) $(INSTALL) $(A_TARGET) $(libdir)/$(A_TARGET) $(SO_INSTALL) $(SO_TARGET) $(libdir)/$(SO_TARGET) uninstall: rm -f $(libdir)/$(A_TARGET) rm -f $(libdir)/$(SO_TARGET) clean: rm -f *.so *.a *.o *.core core distclean: clean rm -f Makefile *~ # Makefile ends here snd-16.1/sndins/sndins.c0000644000076400007640000020734112433105741013302 0ustar bilbil/* sndins.c -- Sndins for Snd/CLM * * Copyright (c) 2003-2014 Michael Scholz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)sndins.c 1.11 11/18/14 */ /* * instruments: fm-violin, jc-reverb, nrev, freeverb * * mus_any *mus_make_fcomb(mus_float_t scaler, int size, * mus_float_t a0, mus_float_t a1); * int mus_is_fcomb(mus_any *ptr); * mus_float_t mus_fcomb(mus_any *ptr, mus_float_t input, mus_float_t ignored); * * mus_long_t ins_fm_violin(mus_float_t start, mus_float_t dur, [...]); * mus_long_t ins_jc_reverb(mus_float_t start, mus_float_t dur, [...]); * mus_long_t ins_nrev(mus_float_t start, mus_float_t dur, [...]); * mus_long_t ins_freeverb(mus_float_t start, mus_float_t dur, [...]); * * void Init_sndins(void); */ #if defined(HAVE_CONFIG_H) #include #endif #include #include #include #include #include #include #include "_sndlib.h" #include "xen.h" #include "clm.h" #include "vct.h" #include "clm2xen.h" #include "sndins.h" #if !defined(Xen_is_provided) #if defined(HAVE_SCHEME) #define Xen_is_provided(feature) \ Xen_boolean_to_C_bool(Xen_member(C_string_to_Xen_symbol(feature),\ C_string_to_Xen_value("*features*"))) #elif HAVE_RUBY #define Xen_is_provided(feature) Xen_boolean_to_C_bool(rb_provided(feature)) #elif HAVE_FORTH #define Xen_is_provided(feature) fth_provided_p(feature) #else #define Xen_is_provided(feature) false #endif #endif /* Xen_is_provided */ #define INS_NO_MEMORY Xen_make_error_type("sndins-no-memory-error") #define INS_MISC Xen_make_error_type("sndins-misc-error") #define INS_ERROR(Error, Caller, Msg) \ Xen_error(Error, \ Xen_list_2(C_string_to_Xen_string(Caller), \ C_string_to_Xen_string(Msg))) #define INS_MISC_ERROR(Caller, Msg) INS_ERROR(INS_MISC, Caller, Msg) #define INS_NO_MEMORY_ERROR(Caller) \ INS_ERROR(INS_NO_MEMORY, Caller, "cannot allocate memory") #define SC_startime "startime" #define SC_duration "duration" #define SC_frequency "frequency" #define SC_amplitude "amplitude" #define SC_degree "degree" #define SC_distance "distance" #define SC_volume "volume" #define SC_delay1 "delay1" #define SC_delay2 "delay2" #define SC_delay3 "delay3" #define SC_delay4 "delay4" #define SC_doubled "doubled" #define SC_base "base" #define SC_damping "damping" #define SC_global "global" #define SC_predelay "predelay" #define SC_combtuning "combtuning" #define SC_allpasstuning "allpasstuning" #define SC_scaler "scaler" #define SC_size "size" #define SC_a0 "a0" #define SC_a1 "a1" #if defined(HAVE_RUBY) #define SC_amp_env "amp_env" #define SC_fm_index "fm_index" #define SC_reverb_amount "reverb_amount" #define SC_low_pass "low_pass" #define SC_periodic_vibrato_rate "periodic_vibrato_rate" #define SC_periodic_vibrato_amplitude "periodic_vibrato_amplitude" #define SC_random_vibrato_rate "random_vibrato_rate" #define SC_random_vibrato_amplitude "random_vibrato_amplitude" #define SC_noise_freq "noise_freq" #define SC_noise_amount "noise_amount" #define SC_ind_noise_freq "ind_noise_freq" #define SC_ind_noise_amount "ind_noise_amount" #define SC_amp_noise_freq "amp_noise_freq" #define SC_amp_noise_amount "amp_noise_amount" #define SC_gliss_env "gliss_env" #define SC_glissando_amount "glissando_amount" #define SC_fm1_env "fm1_env" #define SC_fm2_env "fm2_env" #define SC_fm3_env "fm3_env" #define SC_fm1_rat "fm1_rat" #define SC_fm2_rat "fm2_rat" #define SC_fm3_rat "fm3_rat" #define SC_fm1_index "fm1_index" #define SC_fm2_index "fm2_index" #define SC_fm3_index "fm3_index" #define SC_index_type "index_type" #define SC_no_waveshaping "no_waveshaping" #define SC_reverb_factor "reverb_factor" #define SC_lp_coeff "lp_coeff" #define SC_lp_out_coeff "lp_out_coeff" #define SC_output_scale "output_scale" #define SC_room_decay "room_decay" #define SC_output_gain "output_gain" #define SC_output_mixer "output_mixer" #define SC_scale_room_decay "scale_room_decay" #define SC_offset_room_decay "offset_room_decay" #define SC_scale_damping "scale_dumping" #define SC_stereo_spread "stereo_spread" #else /* !HAVE_RUBY */ #define SC_amp_env "amp-env" #define SC_fm_index "fm-index" #define SC_reverb_amount "reverb-amount" #define SC_low_pass "low-pass" #define SC_periodic_vibrato_rate "periodic-vibrato-rate" #define SC_periodic_vibrato_amplitude "periodic-vibrato-amplitude" #define SC_random_vibrato_rate "random-vibrato-rate" #define SC_random_vibrato_amplitude "random-vibrato-amplitude" #define SC_noise_freq "noise-freq" #define SC_noise_amount "noise-amount" #define SC_ind_noise_freq "ind-noise-freq" #define SC_ind_noise_amount "ind-noise-amount" #define SC_amp_noise_freq "amp-noise-freq" #define SC_amp_noise_amount "amp-noise-amount" #define SC_gliss_env "gliss-env" #define SC_glissando_amount "glissando-amount" #define SC_fm1_env "fm1-env" #define SC_fm2_env "fm2-env" #define SC_fm3_env "fm3-env" #define SC_fm1_rat "fm1-rat" #define SC_fm2_rat "fm2-rat" #define SC_fm3_rat "fm3-rat" #define SC_fm1_index "fm1-index" #define SC_fm2_index "fm2-index" #define SC_fm3_index "fm3-index" #define SC_index_type "index-type" #define SC_no_waveshaping "no-waveshaping" #define SC_reverb_factor "reverb-factor" #define SC_lp_coeff "lp-coeff" #define SC_lp_out_coeff "lp-out-coeff" #define SC_output_scale "output-scale" #define SC_room_decay "room-decay" #define SC_output_gain "output-gain" #define SC_output_mixer "output-mixer" #define SC_scale_room_decay "scale-room-decay" #define SC_offset_room_decay "offset-room-decay" #define SC_scale_damping "scale-dumping" #define SC_stereo_spread "stereo-spread" #endif /* HAVE_RUBY */ enum { C_startime, C_duration, C_frequency, C_amplitude, C_amp_env, C_fm_index, C_reverb_amount, C_degree, C_distance, C_periodic_vibrato_rate, C_periodic_vibrato_amplitude, C_random_vibrato_rate, C_random_vibrato_amplitude, C_noise_freq, C_noise_amount, C_ind_noise_freq, C_ind_noise_amount, C_amp_noise_freq, C_amp_noise_amount, C_gliss_env, C_glissando_amount, C_fm1_env, C_fm2_env, C_fm3_env, C_fm1_rat, C_fm2_rat, C_fm3_rat, C_fm1_index, C_fm2_index, C_fm3_index, C_base, C_index_type, C_no_waveshaping, C_low_pass, C_volume, C_delay1, C_delay2, C_delay3, C_delay4, C_doubled, C_reverb_factor, C_lp_coeff, C_lp_out_coeff, C_output_scale, C_room_decay, C_damping, C_global, C_predelay, C_output_gain, C_output_mixer, C_scale_room_decay, C_offset_room_decay, C_combtuning, C_allpasstuning, C_scale_damping, C_stereo_spread, C_scaler, C_size, C_a0, C_a1, NKEYS }; static char *keywords[NKEYS] = { SC_startime, SC_duration, SC_frequency, SC_amplitude, SC_amp_env, SC_fm_index, SC_reverb_amount, SC_degree, SC_distance, SC_periodic_vibrato_rate, SC_periodic_vibrato_amplitude, SC_random_vibrato_rate, SC_random_vibrato_amplitude, SC_noise_freq, SC_noise_amount, SC_ind_noise_freq, SC_ind_noise_amount, SC_amp_noise_freq, SC_amp_noise_amount, SC_gliss_env, SC_glissando_amount, SC_fm1_env, SC_fm2_env, SC_fm3_env, SC_fm1_rat, SC_fm2_rat, SC_fm3_rat, SC_fm1_index, SC_fm2_index, SC_fm3_index, SC_base, SC_index_type, SC_no_waveshaping, SC_low_pass, SC_volume, SC_delay1, SC_delay2, SC_delay3, SC_delay4, SC_doubled, SC_reverb_factor, SC_lp_coeff, SC_lp_out_coeff, SC_output_scale, SC_room_decay, SC_damping, SC_global, SC_predelay, SC_output_gain, SC_output_mixer, SC_scale_room_decay, SC_offset_room_decay, SC_combtuning, SC_allpasstuning, SC_scale_damping, SC_stereo_spread, SC_scaler, SC_size, SC_a0, SC_a1 }; #if defined(HAVE_RUBY) #define INS_OUTPUT "output" #define INS_REVERB "reverb" #define INS_VERBOSE "clm_verbose" #define INS_LOCSIG_TYPE "clm_locsig_type" #define INS_DECAY_TIME "clm_decay_time" #define INS_LIST_BEG "[" #define INS_LIST_END "]" #define INS_FALSE "false" #define INS_TRUE "true" #define INS_SYMBOL_PREFIX ":" #else #define INS_OUTPUT "*output*" #define INS_REVERB "*reverb*" #define INS_VERBOSE "*clm-verbose*" #define INS_LOCSIG_TYPE "*clm-locsig-type*" #define INS_DECAY_TIME "*clm-decay-time*" #define INS_LIST_BEG "'(" #define INS_LIST_END ")" #define INS_FALSE "#f" #define INS_TRUE "#t" #define INS_SYMBOL_PREFIX "'" #endif /* utility functions */ static mus_float_t *array2array(mus_float_t *list, int len); static bool array_equal_p(mus_float_t *env1, int len1, mus_float_t *env2, int len2); static int feq(mus_float_t x, int i); static char *format_array(mus_float_t *line, int size); static bool get_global_boolean(const char *name, bool def); static mus_float_t get_global_float(const char *name, mus_float_t def); static int get_global_int(const char *name, int def); static mus_any *get_global_mus_gen(const char *name); static int ins_message(const char *fmt,...); static int *int_array2array(int *list, int len); static bool prime_p(int x); static mus_float_t *xen_list2array(Xen list); static int *xen_list2iarray(Xen list); static vct *mus_optkey_to_vct(Xen key, const char *caller, int n, vct *def); /* fcomb generator */ static char *fcomb_describe(mus_any *ptr); static bool fcomb_equal_p(mus_any *p1, mus_any *p2); static int fcomb_free(mus_any *ptr); static mus_long_t fcomb_length(mus_any *ptr); static mus_float_t fcomb_scaler(mus_any *ptr); /* Xen fcomb */ static Xen c_fcomb(Xen gen, Xen input); static Xen c_is_fcomb(Xen gen); static Xen c_make_fcomb(Xen args); /* instruments */ #if defined(HAVE_FORTH) static void c_fm_violin(Xen args); static void c_freeverb(Xen args); static void c_jc_reverb(Xen args); static void c_nrev(Xen args); #else static Xen c_fm_violin(Xen args); static Xen c_freeverb(Xen args); static Xen c_jc_reverb(Xen args); static Xen c_nrev(Xen args); #endif static Xen allkeys[NKEYS]; static void init_keywords(void) { int i; for (i = 0; i < NKEYS; i++) allkeys[i] = Xen_make_keyword(keywords[i]); } /* * from clm2xen.c */ static vct * mus_optkey_to_vct(Xen key, const char *caller, int n, vct *def) { if (mus_is_vct(key)) return(Xen_to_vct(key)); if ((!(Xen_is_keyword(key))) && (!(Xen_is_false(key)))) Xen_check_type(false, key, n, caller, "a " S_vct); return(def); } /* * Required for getting $output|$reverb (Ruby) and *output*|*reverb* (Fth). * * XXX: *output*|*reverb* (S7) * Doesn't work for S7. (Tue Nov 18 22:43:18 CET 2014) */ static mus_any * get_global_mus_gen(const char *name) { #if !defined(HAVE_SCHEME) Xen value; if (Xen_is_defined(name)) { value = C_string_to_Xen_value(name); if (mus_is_xen(value)) return (Xen_to_mus_any(value)); } #endif return (NULL); } static bool get_global_boolean(const char *name, bool def) { if (Xen_is_defined(name)) { Xen value; value = C_string_to_Xen_value(name); if (Xen_is_boolean(value)) return (Xen_boolean_to_C_bool(value)); } return (def); } static int get_global_int(const char *name, int def) { if (Xen_is_defined(name)) { Xen value; value = C_string_to_Xen_value(name); if (Xen_is_number(value)) return (Xen_integer_to_C_int(value)); } return (def); } static mus_float_t get_global_float(const char *name, mus_float_t def) { if (Xen_is_defined(name)) { Xen value; value = C_string_to_Xen_value(name); if (Xen_is_number(value)) return (Xen_real_to_C_double(value)); } return (def); } /* * Return mus_float_t array initialized with contents of Xen list. * (mus_make_env()) */ static mus_float_t * xen_list2array(Xen list) { int len, i = 0; mus_float_t *flist; Xen lst; len = Xen_list_length(list); if (len == 0) return (NULL); flist = malloc(len * sizeof(mus_float_t)); if (flist == NULL) { INS_NO_MEMORY_ERROR("xen_list2array"); /* NOTREACHED */ return (NULL); } for (i = 0, lst = Xen_copy_arg(list); i < len; i++, lst = Xen_cdr(lst)) flist[i] = Xen_real_to_C_double(Xen_car(lst)); return (flist); } /* * Return int array initialized with contents of Xen list. * (mus_make_mixer()) */ static int * xen_list2iarray(Xen list) { int len, i = 0; int *ilist; Xen lst; len = Xen_list_length(list); if (len == 0) return (NULL); ilist = malloc(len * sizeof(int)); if (ilist == NULL) { INS_NO_MEMORY_ERROR("xen_list2iarray"); /* NOTREACHED */ return (NULL); } for (i = 0, lst = Xen_copy_arg(list); i < len; i++, lst = Xen_cdr(lst)) ilist[i] = Xen_integer_to_C_int(Xen_car(lst)); return (ilist); } /* * Return mus_float_t array initialized with contents of mus_float_t list. * (mus_make_env()) */ static mus_float_t * array2array(mus_float_t *list, int len) { int i = 0; mus_float_t *flist; if (len == 0) return (NULL); flist = malloc(len * sizeof(mus_float_t)); if (flist == NULL) { INS_NO_MEMORY_ERROR("array2array"); /* NOTREACHED */ return (NULL); } for (i = 0; i < len; i++) flist[i] = (mus_float_t)list[i]; return (flist); } /* * Return int array initialized with contents of int list. * (mus_make_mixer()) */ static int * int_array2array(int *list, int len) { int i = 0; int *ilist; if (len == 0) return (NULL); ilist = malloc(len * sizeof(int)); if (ilist == NULL) { INS_NO_MEMORY_ERROR("int_array2array"); /* NOTREACHED */ return (NULL); } for (i = 0; i < len; i++) ilist[i] = (int)list[i]; return (ilist); } /* * ins_fm_violin: easy_case */ static bool array_equal_p(mus_float_t *env1, int len1, mus_float_t *env2, int len2) { if (env1 != NULL && env2 != NULL && len1 == len2) { int i; for (i = 0; i < len1; i++) if (env1[i] != env2[i]) return (false); return (true); } return (false); } /* * Print message in listener. */ static int ins_message(const char *fmt,...) { int len, result; va_list ap; char *s; len = strlen(fmt) + 128; s = malloc(len * sizeof(char)); if (s == NULL) { INS_NO_MEMORY_ERROR("ins_message"); /* NOTREACHED */ return (-1); } va_start(ap, fmt); result = vsnprintf(s, len, fmt, ap); va_end(ap); if (Xen_is_provided("snd") && !Xen_is_provided("snd-nogui")) mus_print(Xen_comment_mark " %s", s); else fprintf(stdout, Xen_comment_mark " %s", s); free(s); return (result); } static int feq(mus_float_t x, int i) { return (fabs(x - i) < 0.00001); } static bool prime_p(int x) { if (x == 2) return (true); if (x % 2) { int i; for (i = 3; i < sqrt(x); i += 2) if ((x % i) == 0) return (false); return (true); } return (false); } #define INS_FMT_SIZE 128 static char * format_array(mus_float_t *line, int size) { int i, lim; char *s, *t; lim = size; s = NULL; if (lim > mus_array_print_length()) lim = mus_array_print_length(); s = calloc(INS_FMT_SIZE * lim * 2, sizeof(char)); if (s == NULL) { INS_NO_MEMORY_ERROR("format_array"); /* NOTREACHED */ return (NULL); } if (line == NULL) return (strcpy(s, "nil")); strcpy(s, "["); for (i = 0; i < lim - 1; i++) { t = mus_format("%.3f ", line[i]); strcat(s, t); free(t); } t = mus_format("%.3f%s]", line[i], (size > lim) ? "..." : ""); strcat(s, t); free(t); return (s); } /* --- fcomb --- */ typedef struct { mus_any_class *core; int loc; int size; /* mus_length(gen) */ mus_float_t *line; /* mus_data(gen) */ mus_float_t xs[2]; /* a0, a1; mus_xcoeff(gen, 0 or 1) */ mus_float_t xscl; /* mus_scaler(gen) */ mus_float_t x1; } fcomb; static int MUS_FCOMB = 0; int mus_is_fcomb(mus_any *ptr) { return (ptr != NULL && mus_type(ptr) == MUS_FCOMB); } #define INS_DESCRIBE_SIZE 2048 static char * fcomb_describe(mus_any *ptr) { char *s, *t; fcomb *gen; gen = (fcomb *)ptr; t = format_array(gen->line, gen->size); s = mus_format("fcomb: scaler: " "%.3f, a0: %.3f, a1: %.3f, x1: %.3f, line[%d]: %s", gen->xscl, gen->xs[0], gen->xs[1], gen->x1, gen->size, t); free(t); return (s); } static bool fcomb_equal_p(mus_any *p1, mus_any *p2) { fcomb *g1, *g2; g1 = (fcomb *)p1; g2 = (fcomb *)p2; return (mus_is_fcomb(p1) && ((p1 == p2) || (mus_is_fcomb(p2) && g1->xs[0] == g2->xs[0] && g1->xs[1] == g2->xs[1] && g1->x1 == g2->x1))); } static mus_long_t fcomb_length(mus_any *ptr) { fcomb *gen; gen = (fcomb *)ptr; return ((mus_long_t)(gen->size)); } static mus_float_t fcomb_scaler(mus_any *ptr) { fcomb *gen; gen = (fcomb *)ptr; return (gen->xscl); } static int fcomb_free(mus_any *ptr) { fcomb *gen; gen = (fcomb *)ptr; if (gen != NULL) { if (gen->line != NULL) free(gen->line); gen->line = NULL; free(gen); } return (0); } /* * Now the actual run-time code executed by fcomb the extra "ignored" * argument is for the run method */ mus_float_t mus_fcomb(mus_any *ptr, mus_float_t input, mus_float_t ignored __attribute__((unused))) { fcomb *gen; mus_float_t tap_result, filter_result; gen = (fcomb *)ptr; tap_result = gen->line[gen->loc]; filter_result = (gen->xs[0] * tap_result) + (gen->xs[1] * gen->x1); gen->x1 = tap_result; gen->line[gen->loc] = input + filter_result * gen->xscl; gen->loc++; if (gen->loc >= gen->size) gen->loc = 0; return (tap_result); } /* * Now a function to make a new generator. */ mus_any * mus_make_fcomb(mus_float_t scaler, int size, mus_float_t a0, mus_float_t a1) { fcomb *gen; int i; gen = calloc(1, sizeof(fcomb)); if (gen == NULL) { INS_NO_MEMORY_ERROR("mus_make_fcomb"); /* NOTREACHED */ return (NULL); } gen->line = calloc(size, sizeof(mus_float_t)); if (gen->line == NULL) { INS_NO_MEMORY_ERROR("mus_make_fcomb"); /* NOTREACHED */ return (NULL); } for (i = 0; i < size; i++) gen->line[i] = 0.0; MUS_FCOMB = mus_make_generator_type(); gen->core = mus_make_generator(MUS_FCOMB, "fcomb", fcomb_free, fcomb_describe, fcomb_equal_p); if (gen->core == NULL) { INS_NO_MEMORY_ERROR("mus_make_fcomb"); /* NOTREACHED */ return (NULL); } gen->loc = 0; gen->xscl = scaler; gen->x1 = 0.0; gen->xs[0] = a0; gen->xs[1] = a1; gen->size = size; mus_generator_set_length(gen->core, fcomb_length); mus_generator_set_scaler(gen->core, fcomb_scaler); return ((mus_any *)gen); } /* * That is the end of the C side; the rest ties this generator into * Scheme/Ruby/Forth via the Xen package in Snd's case, it's actually * not needed because the generator is only called from C. */ #define h_make_fcomb_args "\ keyword arguments with default values:\n\ :scaler 1.0\n\ :size 1\n\ :a0 0.0\n\ :a1 0.0\n\ Return new fcomb generator." #if defined(HAVE_RUBY) #define S_make_fcomb "make_fcomb" #else #define S_make_fcomb "make-fcomb" #endif #if defined(HAVE_RUBY) #define H_make_fcomb S_make_fcomb "(*args)\n" h_make_fcomb_args #elif defined(HAVE_FORTH) #define H_make_fcomb S_make_fcomb " ( args -- gen )\n" h_make_fcomb_args #else /* HAVE_SCHEME */ #define H_make_fcomb "(" S_make_fcomb " . args)\n" h_make_fcomb_args #endif #define MAX_TABLE_SIZE (1024 * 1024 * 20) static Xen c_make_fcomb(Xen args) { #define FCOMB_LAST_KEY 4 int i, keyn, argn, vals, lst_len, size; mus_float_t scaler, a0, a1; Xen kargs[FCOMB_LAST_KEY * 2], keys[FCOMB_LAST_KEY]; int orig_arg[FCOMB_LAST_KEY] = {0}; mus_any *ge; argn = 0; lst_len = Xen_list_length(args); size = 1; scaler = 1.0; a0 = a1 = 0.0; keys[argn++] = allkeys[C_scaler]; keys[argn++] = allkeys[C_size]; keys[argn++] = allkeys[C_a0]; keys[argn++] = allkeys[C_a1]; for (i = 0; i < FCOMB_LAST_KEY * 2; i++) kargs[i] = Xen_undefined; for (i = 0; i < lst_len; i++) kargs[i] = Xen_list_ref(args, i); vals = mus_optkey_unscramble(S_make_fcomb, argn, keys, kargs, orig_arg); if (vals > 0) { keyn = 0; scaler = mus_optkey_to_float(keys[keyn], S_make_fcomb, orig_arg[keyn], scaler); keyn++; size = mus_optkey_to_int(keys[keyn], S_make_fcomb, orig_arg[keyn], size); if (size < 0) Xen_out_of_range_error(S_make_fcomb, orig_arg[keyn], keys[keyn], "size < 0?"); if (size > MAX_TABLE_SIZE) Xen_out_of_range_error(S_make_fcomb, orig_arg[keyn], keys[keyn], "size too large"); keyn++; a0 = mus_optkey_to_float(keys[keyn], S_make_fcomb, orig_arg[keyn], a0); keyn++; a1 = mus_optkey_to_float(keys[keyn], S_make_fcomb, orig_arg[keyn], a1); } ge = mus_make_fcomb(scaler, size, a0, a1); if (ge) { fcomb *g; mus_xen *fc; Xen v1, v2; g = (fcomb *)ge; /* wrapper set v->dont_free = true */ v1 = xen_make_vct_wrapper(size, g->line); v2 = xen_make_vct_wrapper(2, g->xs); fc = mus_any_to_mus_xen_with_two_vcts(ge, v1, v2); return (mus_xen_to_object(fc)); } return (Xen_false); } #define S_is_fcomb "fcomb?" #define h_is_fcomb_doc "\ Return " INS_TRUE " if GEN is an fcomb generator, otherwise " INS_FALSE "." #if defined(HAVE_RUBY) #define H_is_fcomb S_is_fcomb "(gen) " h_is_fcomb_doc #elif defined(HAVE_FORTH) #define H_is_fcomb S_is_fcomb " ( gen -- f ) " h_is_fcomb_doc #else /* HAVE_SCHEME */ #define H_is_fcomb "(" S_is_fcomb " gen) " h_is_fcomb_doc #endif #define Xen_is_fcomb(obj) \ (mus_is_xen(obj) && mus_is_fcomb(Xen_to_mus_any(obj))) static Xen c_is_fcomb(Xen obj) { return (C_bool_to_Xen_boolean(Xen_is_fcomb(obj))); } #define S_fcomb "fcomb" #define h_fcomb_doc "Return result of running fcomb generator." #if defined(HAVE_RUBY) #define H_fcomb S_fcomb "(gen, input=0.0) " h_fcomb_doc #elif defined(HAVE_FORTH) #define H_fcomb S_fcomb " ( gen input=0.0 -- res ) " h_fcomb_doc #else /* HAVE_SCHEME */ #define H_fcomb "(" S_fcomb " gen (input 0.0)) " h_fcomb_doc #endif static Xen c_fcomb(Xen gen, Xen input) { mus_any *ge; mus_float_t fm; fm = 0.0; ge = Xen_to_mus_any(gen); Xen_check_type(mus_is_fcomb(ge), gen, 1, S_fcomb, "an fcomb"); if (Xen_is_bound(input)) fm = Xen_real_to_C_double(input); return (C_double_to_Xen_real(mus_fcomb(ge, fm, 0.0))); } /* --- instruments --- */ #if defined(HAVE_RUBY) #define S_fm_violin "fm_violin" #define S_jc_reverb "jc_reverb" #else #define S_fm_violin "fm-violin" #define S_jc_reverb "jc-reverb" #endif #define S_nrev "nrev" #define S_freeverb "freeverb" mus_long_t ins_fm_violin(mus_float_t start, mus_float_t dur, mus_float_t freq, mus_float_t amp, mus_float_t fm_index, mus_float_t *amp_env, int amp_len, mus_float_t periodic_vibrato_rate, mus_float_t periodic_vibrato_amp, mus_float_t random_vibrato_rate, mus_float_t random_vibrato_amp, mus_float_t noise_freq, mus_float_t noise_amount, mus_float_t ind_noise_freq, mus_float_t ind_noise_amount, mus_float_t amp_noise_freq, mus_float_t amp_noise_amount, mus_float_t *gliss_env, int gliss_len, mus_float_t gliss_amount, mus_float_t *fm1_env, int fm1_len, mus_float_t *fm2_env, int fm2_len, mus_float_t *fm3_env, int fm3_len, mus_float_t fm1_rat, mus_float_t fm2_rat, mus_float_t fm3_rat, mus_float_t fm1_index, mus_float_t fm2_index, mus_float_t fm3_index, mus_float_t base, mus_float_t degree, mus_float_t distance, mus_float_t reverb_amount, bool index_type, bool no_waveshaping, mus_any *out, mus_any *rev, mus_interp_t mode) { mus_long_t i, beg, len; int out_chans, rev_chans; bool vln, easy_case, modulate; mus_float_t frq_scl, maxdev, index1, index2, index3, vib; mus_float_t logfrq, sqrtfrq, norm, mod; mus_float_t *partials = NULL; mus_float_t fuzz, ind_fuzz, amp_fuzz; mus_any *carrier, *fmosc1, *fmosc2 = NULL, *fmosc3 = NULL; mus_any *ampf, *indf1, *indf2 = NULL, *indf3 = NULL, *pervib; mus_any *fm_noi = NULL, *ind_noi = NULL, *amp_noi = NULL; mus_any *ranvib, *frqf = NULL, *loc; out_chans = 1; rev_chans = 0; vln = true; easy_case = modulate = false; frq_scl = maxdev = index1 = index2 = index3 = vib = 0.0; logfrq = sqrtfrq = norm = mod = fuzz = 0.0; ind_fuzz = amp_fuzz = 1.0; beg = mus_seconds_to_samples(start); len = beg + mus_seconds_to_samples(dur); frq_scl = mus_hz_to_radians(freq); modulate = (fm_index != 0.0); maxdev = frq_scl * fm_index; logfrq = log(freq); sqrtfrq = sqrt(freq); vln = index_type; /* true: violin, false: cello */ if (fm1_index != 0.0) index1 = fm1_index; else { index1 = vln ? (maxdev * 5.0 / logfrq) : (maxdev * 7.5 / logfrq); if (index1 > M_PI) index1 = M_PI; } if (fm2_index != 0.0) index2 = fm2_index; else { index2 = vln ? (maxdev * 3.0 * (8.5 - logfrq) / (3.0 + freq * 0.001)) : (maxdev * 3.0 * 15.0 / sqrtfrq); if (index2 > M_PI) index2 = M_PI; } if (fm3_index != 0.0) index3 = fm3_index; else { index3 = vln ? (maxdev * 4.0 / sqrtfrq) : (maxdev * 8.0 / sqrtfrq); if (index3 > M_PI) index3 = M_PI; } easy_case = (noise_amount == 0.0 && !no_waveshaping && array_equal_p(fm1_env, fm1_len, fm2_env, fm2_len) && array_equal_p(fm1_env, fm1_len, fm3_env, fm3_len) && feq(fm1_rat, (int)floor(fm1_rat)) && feq(fm2_rat, (int)floor(fm2_rat)) && feq(fm3_rat, (int)floor(fm3_rat))); if (easy_case && modulate) norm = 1.0; else norm = index1; carrier = mus_make_oscil(freq, 0.0); if (modulate) { if (easy_case) { int nparts; nparts = (int)floor(fm1_rat); if ((int)floor(fm2_rat) > nparts) nparts = (int)floor(fm2_rat); if ((int)floor(fm3_rat) > nparts) nparts = (int)floor(fm3_rat); nparts++; partials = calloc(nparts, sizeof(mus_float_t)); partials[(int)(fm1_rat)] = index1; partials[(int)(fm2_rat)] = index2; partials[(int)(fm3_rat)] = index3; fmosc1 = mus_make_polyshape(freq * fm1_rat, 0.0, mus_partials_to_polynomial(nparts, partials, 1), nparts, MUS_CHEBYSHEV_FIRST_KIND); } else fmosc1 = mus_make_oscil(freq * fm1_rat, 0.0); indf1 = mus_make_env(fm1_env, fm1_len / 2, norm, 0.0, 1.0, dur, 0, NULL); if (!easy_case) { fmosc2 = mus_make_oscil(freq * fm2_rat, 0.0); fmosc3 = mus_make_oscil(freq * fm3_rat, 0.0); indf2 = mus_make_env(fm2_env, fm2_len / 2, index2, 0.0, 1.0, dur, 0, NULL); indf3 = mus_make_env(fm3_env, fm3_len / 2, index3, 0.0, 1.0, dur, 0, NULL); } } ampf = mus_make_env(amp_env, amp_len / 2, amp, 0.0, base, dur, 0, NULL); frqf = mus_make_env(gliss_env, gliss_len / 2, gliss_amount * frq_scl, 0.0, 1.0, dur, 0, NULL); pervib = mus_make_triangle_wave(periodic_vibrato_rate, periodic_vibrato_amp * frq_scl, 0.0); ranvib = mus_make_rand_interp(random_vibrato_rate, random_vibrato_amp * frq_scl); if (noise_amount != 0.0) fm_noi = mus_make_rand(noise_freq, noise_amount * M_PI); if (ind_noise_amount != 0.0 && ind_noise_freq != 0.0) ind_noi = mus_make_rand_interp(ind_noise_freq, ind_noise_amount); if (amp_noise_amount != 0.0 && amp_noise_freq != 0.0) amp_noi = mus_make_rand_interp(amp_noise_freq, amp_noise_amount); if (degree == 0.0) degree = mus_random(90.0); if (out) out_chans = mus_channels(out); if (rev) rev_chans = mus_channels(rev); loc = mus_make_locsig(degree, distance, reverb_amount, out_chans, out, rev_chans, rev, mode); for (i = beg; i < len; i++) { if (fm_noi) fuzz = mus_rand(fm_noi, 0.0); vib = mus_env(frqf) + mus_triangle_wave(pervib, 0.0) + mus_rand_interp(ranvib, 0.0); if (ind_noi) ind_fuzz = 1.0 + mus_rand_interp(ind_noi, 0.0); if (amp_noi) amp_fuzz = 1.0 + mus_rand_interp(amp_noi, 0.0); if (modulate) { if (easy_case) mod = mus_env(indf1) * mus_polyshape_unmodulated(fmosc1, vib); else mod = mus_env(indf1) * mus_oscil(fmosc1, fuzz + fm1_rat * vib, 0.0) + mus_env(indf2) * mus_oscil(fmosc2, fuzz + fm2_rat * vib, 0.0) + mus_env(indf3) * mus_oscil(fmosc3, fuzz + fm3_rat * vib, 0.0); } mus_locsig(loc, i, mus_env(ampf) * amp_fuzz * mus_oscil(carrier, vib + ind_fuzz * mod, 0.0)); } mus_free(pervib); mus_free(ranvib); mus_free(carrier); mus_free(fmosc1); mus_free(ampf); mus_free(indf1); mus_free(loc); if (fm_noi) mus_free(fm_noi); if (ind_noi) mus_free(ind_noi); if (amp_noi) mus_free(amp_noi); if (frqf) mus_free(frqf); if (fmosc2) mus_free(fmosc2); if (fmosc3) mus_free(fmosc3); if (indf2) mus_free(indf2); if (indf3) mus_free(indf3); if (partials) free(partials); return (i); } #define JC_WARN "is not set up for doubled reverb in quad" mus_long_t ins_jc_reverb(mus_float_t start, mus_float_t dur, mus_float_t volume, bool low_pass, bool doubled, mus_float_t delay1, mus_float_t delay2, mus_float_t delay3, mus_float_t delay4, mus_float_t *amp_env, int amp_len, mus_any *out, mus_any *rev) { mus_long_t i, beg, len; int del_len, chans, rev_chans; bool chan2, chan4; mus_float_t delA, delB; mus_float_t allpass_sum, comb_sum, comb_sum_1, comb_sum_2, all_sums; mus_any *allpass1, *allpass2, *allpass3; mus_any *comb1, *comb2, *comb3, *comb4; mus_any *outdel1, *outdel2 = NULL, *outdel3 = NULL, *outdel4 = NULL; mus_any *env_a = NULL; del_len = chans = rev_chans = 0; chan2 = chan4 = false; delA = delB = 0.0; allpass_sum = comb_sum = comb_sum_1 = comb_sum_2 = all_sums = 0.0; beg = mus_seconds_to_samples(start); if (dur > 0.0) len = beg + mus_seconds_to_samples(dur); else len = beg + mus_seconds_to_samples(1.0) + mus_sound_framples(mus_file_name(rev)); chans = mus_channels(out); rev_chans = mus_channels(rev); allpass1 = mus_make_all_pass(-0.7, 0.7, 1051, NULL, 1051, MUS_INTERP_LINEAR); allpass2 = mus_make_all_pass(-0.7, 0.7, 337, NULL, 337, MUS_INTERP_LINEAR); allpass3 = mus_make_all_pass(-0.7, 0.7, 113, NULL, 113, MUS_INTERP_LINEAR); comb1 = mus_make_comb(0.742, 4799, NULL, 4799, MUS_INTERP_LINEAR); comb2 = mus_make_comb(0.733, 4999, NULL, 4999, MUS_INTERP_LINEAR); comb3 = mus_make_comb(0.715, 5399, NULL, 5399, MUS_INTERP_LINEAR); comb4 = mus_make_comb(0.697, 5801, NULL, 5801, MUS_INTERP_LINEAR); if (chans > 1) chan2 = true; if (chans == 4) chan4 = true; del_len = mus_seconds_to_samples(delay1); outdel1 = mus_make_delay(del_len, NULL, del_len, MUS_INTERP_LINEAR); if (chan2) { del_len = mus_seconds_to_samples(delay2); outdel2 = mus_make_delay(del_len, NULL, del_len, MUS_INTERP_LINEAR); } if (doubled || chan4) { del_len = mus_seconds_to_samples(delay3); outdel3 = mus_make_delay(del_len, NULL, del_len, MUS_INTERP_LINEAR); } if (chan4 || (doubled && chan2)) { del_len = mus_seconds_to_samples(delay4); outdel4 = mus_make_delay(del_len, NULL, del_len, MUS_INTERP_LINEAR); } if (amp_env) env_a = mus_make_env(amp_env, amp_len / 2, volume, 0.0, 1.0, dur, 0, NULL); if (doubled && chan4) INS_MISC_ERROR(S_jc_reverb, JC_WARN); for (i = beg; i < len; i++) { int j; mus_float_t ho; for (j = 0, ho = 0.0; j < rev_chans; j++) ho += mus_in_any(i, j, rev); allpass_sum = mus_all_pass_unmodulated(allpass3, mus_all_pass_unmodulated(allpass2, mus_all_pass_unmodulated(allpass1, ho))); comb_sum_2 = comb_sum_1; comb_sum_1 = comb_sum; comb_sum = mus_comb_unmodulated(comb1, allpass_sum) + mus_comb_unmodulated(comb2, allpass_sum) + mus_comb_unmodulated(comb3, allpass_sum) + mus_comb_unmodulated(comb4, allpass_sum); if (low_pass) all_sums = 0.25 * (comb_sum + comb_sum_2) + 0.5 * comb_sum_1; else all_sums = comb_sum; delA = mus_delay_unmodulated(outdel1, all_sums); if (doubled) delA += mus_delay_unmodulated(outdel3, all_sums); if (env_a) volume = mus_env(env_a); mus_out_any(i, delA * volume, 0, out); if (chan2) { delB = mus_delay_unmodulated(outdel2, all_sums); if (doubled) delB += mus_delay_unmodulated(outdel4, all_sums); mus_out_any(i, delB * volume, 1, out); if (chan4) { mus_out_any(i, volume * mus_delay_unmodulated(outdel3, all_sums), 2, out); mus_out_any(i, volume * mus_delay_unmodulated(outdel4, all_sums), 3, out); } } } mus_free(allpass1); mus_free(allpass2); mus_free(allpass3); mus_free(comb1); mus_free(comb2); mus_free(comb3); mus_free(comb4); mus_free(outdel1); if (outdel2) mus_free(outdel2); if (outdel3) mus_free(outdel3); if (outdel4) mus_free(outdel4); if (env_a) mus_free(env_a); return (i); } mus_long_t ins_nrev(mus_float_t start, mus_float_t dur, mus_float_t reverb_factor, mus_float_t lp_coeff, mus_float_t lp_out_coeff, mus_float_t output_scale, mus_float_t volume, mus_float_t *amp_env, int amp_len, mus_any *out, mus_any *rev) { mus_long_t i, beg, len; int chans, rev_chans, val; int dly_len[15] = {1433, 1601, 1867, 2053, 2251, 2399, 347, 113, 37, 59, 53, 43, 37, 29, 19}; mus_float_t srscale; mus_float_t sample_a, sample_b, sample_c, sample_d; mus_float_t inrev, outrev; mus_any *allpass1, *allpass2, *allpass3, *allpass4; mus_any *allpass5, *allpass6, *allpass7, *allpass8; mus_any *comb1, *comb2, *comb3, *comb4, *comb5, *comb6; mus_any *low, *low_a, *low_b, *low_c, *low_d, *env_a; chans = rev_chans = val = 0; srscale = mus_srate() / 25641.0; sample_a = sample_b = sample_c = sample_d = inrev = outrev = 0.0; beg = mus_seconds_to_samples(start); if (dur > 0.0) len = beg + mus_seconds_to_samples(dur); else len = beg + mus_seconds_to_samples(1.0) + mus_sound_framples(mus_file_name(rev)); chans = mus_channels(out); rev_chans = mus_channels(rev); env_a = mus_make_env(amp_env, amp_len / 2, output_scale, 0.0, 1.0, dur, 0, NULL); for (i = 0; i < 14; i++) { int x; x = dly_len[i]; val = (int)floor(srscale * x); if ((val % 2) == 0) val++; while (!prime_p(val)) val += 2; dly_len[i] = val; } i = 0; comb1 = mus_make_comb(reverb_factor * 0.822, dly_len[i], NULL, dly_len[i], MUS_INTERP_LINEAR); i++; comb2 = mus_make_comb(reverb_factor * 0.802, dly_len[i], NULL, dly_len[i], MUS_INTERP_LINEAR); i++; comb3 = mus_make_comb(reverb_factor * 0.773, dly_len[i], NULL, dly_len[i], MUS_INTERP_LINEAR); i++; comb4 = mus_make_comb(reverb_factor * 0.753, dly_len[i], NULL, dly_len[i], MUS_INTERP_LINEAR); i++; comb5 = mus_make_comb(reverb_factor * 0.753, dly_len[i], NULL, dly_len[i], MUS_INTERP_LINEAR); i++; comb6 = mus_make_comb(reverb_factor * 0.733, dly_len[i], NULL, dly_len[i], MUS_INTERP_LINEAR); i++; low = mus_make_one_pole(lp_out_coeff, lp_coeff - 1.0); low_a = mus_make_one_pole(lp_out_coeff, lp_coeff - 1.0); low_b = mus_make_one_pole(lp_out_coeff, lp_coeff - 1.0); low_c = mus_make_one_pole(lp_out_coeff, lp_coeff - 1.0); low_d = mus_make_one_pole(lp_out_coeff, lp_coeff - 1.0); allpass1 = mus_make_all_pass(-0.7, 0.7, dly_len[i], NULL, dly_len[i], MUS_INTERP_LINEAR); i++; allpass2 = mus_make_all_pass(-0.7, 0.7, dly_len[i], NULL, dly_len[i], MUS_INTERP_LINEAR); i++; allpass3 = mus_make_all_pass(-0.7, 0.7, dly_len[i], NULL, dly_len[i], MUS_INTERP_LINEAR); i += 2; allpass4 = mus_make_all_pass(-0.7, 0.7, dly_len[i], NULL, dly_len[i], MUS_INTERP_LINEAR); i++; allpass5 = mus_make_all_pass(-0.7, 0.7, dly_len[i], NULL, dly_len[i], MUS_INTERP_LINEAR); i++; allpass6 = mus_make_all_pass(-0.7, 0.7, dly_len[i], NULL, dly_len[i], MUS_INTERP_LINEAR); i++; allpass7 = mus_make_all_pass(-0.7, 0.7, dly_len[i], NULL, dly_len[i], MUS_INTERP_LINEAR); i++; allpass8 = mus_make_all_pass(-0.7, 0.7, dly_len[i], NULL, dly_len[i], MUS_INTERP_LINEAR); for (i = beg; i < len; i++) { int j; mus_float_t ho; for (j = 0, ho = 0.0; j < rev_chans; j++) ho += mus_in_any(i, j, rev); inrev = volume * mus_env(env_a) * ho; outrev = mus_all_pass_unmodulated(allpass4, mus_one_pole(low, mus_all_pass_unmodulated(allpass3, mus_all_pass_unmodulated(allpass2, mus_all_pass_unmodulated(allpass1, mus_comb_unmodulated(comb1, inrev) + mus_comb_unmodulated(comb2, inrev) + mus_comb_unmodulated(comb3, inrev) + mus_comb_unmodulated(comb4, inrev) + mus_comb_unmodulated(comb5, inrev) + mus_comb_unmodulated(comb6, inrev)))))); sample_a = output_scale * mus_one_pole(low_a, mus_all_pass_unmodulated(allpass5, outrev)); sample_b = output_scale * mus_one_pole(low_b, mus_all_pass_unmodulated(allpass6, outrev)); sample_c = output_scale * mus_one_pole(low_c, mus_all_pass_unmodulated(allpass7, outrev)); sample_d = output_scale * mus_one_pole(low_d, mus_all_pass_unmodulated(allpass8, outrev)); if (chans == 2) mus_out_any(i, (sample_a + sample_d) / 2.0, 0, out); else mus_out_any(i, sample_a, 0, out); if (chans == 2 || chans == 4) { if (chans == 2) mus_out_any(i, (sample_b + sample_c) / 2.0, 1, out); else mus_out_any(i, sample_b, 1, out); } if (chans == 4) { mus_out_any(i, sample_c, 2, out); mus_out_any(i, sample_d, 3, out); } } mus_free(allpass1); mus_free(allpass2); mus_free(allpass3); mus_free(allpass4); mus_free(allpass5); mus_free(allpass6); mus_free(allpass7); mus_free(allpass8); mus_free(comb1); mus_free(comb2); mus_free(comb3); mus_free(comb4); mus_free(comb5); mus_free(comb6); mus_free(env_a); mus_free(low); mus_free(low_a); mus_free(low_b); mus_free(low_c); mus_free(low_d); return (i); } #define FV_WARN "input must be mono or in channels must equal out channels" #define ins_fcomb(Gen, Val) mus_fcomb(Gen, Val, 0.0) #define ins_delay(Gen, Val) mus_delay_unmodulated(Gen, Val) #define ins_all_pass(Gen, Val) mus_all_pass_unmodulated(Gen, Val) mus_long_t ins_freeverb(mus_float_t start, mus_float_t dur, mus_float_t room_decay, mus_float_t damping, mus_float_t global, mus_float_t predelay, mus_float_t output_gain, mus_float_t scale_room_decay, mus_float_t offset_room_decay, mus_float_t scale_damping, mus_float_t stereo_spread, int *combtuning, int comb_len, int *allpasstuning, int all_len, vct *output_mixer, mus_any *out, mus_any *rev) { mus_long_t i, beg, len; int out_chans, in_chans, j, k, size; mus_float_t srate_scale; mus_float_t local_gain, global_gain; mus_float_t room_decay_val, tmp; vct *out_mix = NULL, *out_buf = NULL, *f_out = NULL, *f_in = NULL; mus_any **predelays, ***allpasses, ***combs; mus_any *g; mus_float_t *om, *ob, *fo; out_chans = in_chans = 0; srate_scale = mus_srate() / 44100.0; local_gain = global_gain = 0.0; beg = mus_seconds_to_samples(start); if (dur > 0.0) len = beg + mus_seconds_to_samples(dur); else len = beg + mus_seconds_to_samples(1.0) + mus_sound_framples(mus_file_name(rev)); out_chans = mus_channels(out); in_chans = mus_channels(rev); if (in_chans > 1 && in_chans != out_chans) INS_MISC_ERROR(S_freeverb, FV_WARN); out_buf = mus_vct_make(out_chans); f_out = mus_vct_make(out_chans); f_in = mus_vct_make(in_chans); local_gain = (1.0 - global)*(1.0 - 1.0 / out_chans) + 1.0 / out_chans; tmp = (out_chans * out_chans - out_chans); if (tmp < 1.0) tmp = 1.0; global_gain = (out_chans - local_gain * out_chans) / tmp; if (output_mixer != NULL) out_mix = output_mixer; else { out_mix = mus_vct_make(out_chans * out_chans); for (i = 0; i < out_chans; i++) { int j; for (j = 0; j < out_chans; j++) { if (i == j) tmp = output_gain * local_gain; else tmp = output_gain * global_gain; mus_vct_data(out_mix)[i + j] = tmp / out_chans; } } } predelays = malloc(in_chans * sizeof(mus_any *)); if (predelays == NULL) INS_NO_MEMORY_ERROR("ins_freeverb"); allpasses = malloc(out_chans * sizeof(mus_any **)); if (allpasses == NULL) INS_NO_MEMORY_ERROR("ins_freeverb"); combs = malloc(out_chans * sizeof(mus_any **)); if (combs == NULL) INS_NO_MEMORY_ERROR("ins_freeverb"); room_decay_val = room_decay * scale_room_decay + offset_room_decay; for (i = 0; i < out_chans; i++) { allpasses[i] = malloc(all_len * sizeof(mus_any *)); if (allpasses[i] == NULL) INS_NO_MEMORY_ERROR("ins_freeverb"); combs[i] = malloc(comb_len * sizeof(mus_any *)); if (combs[i] == NULL) INS_NO_MEMORY_ERROR("ins_freeverb"); } /* predelays */ for (i = 0; i < in_chans; i++) { size = (int)floor(mus_srate() * predelay); predelays[i] = mus_make_delay(size, NULL, size, MUS_INTERP_LINEAR); } for (i = 0; i < out_chans; i++) { /* comb filters */ for (j = 0; j < comb_len; j++) { tmp = scale_damping * damping; size = (int)floor(srate_scale * combtuning[j]); if ((i % 2) != 0) size += (int)floor(srate_scale * stereo_spread); combs[i][j] = mus_make_fcomb(room_decay_val, size, 1.0 - tmp, tmp); } /* allpass filters */ for (j = 0; j < all_len; j++) { size = (int)floor(srate_scale * allpasstuning[j]); if ((i % 2) != 0) size += (int)floor(srate_scale * stereo_spread); allpasses[i][j] = mus_make_all_pass(0.5, -1.0, size, NULL, size, MUS_INTERP_LINEAR); } } om = mus_vct_data(out_mix); ob = mus_vct_data(out_buf); fo = mus_vct_data(f_out); /* run loop */ if (in_chans == 1) { mus_float_t f; for (i = beg; i < len; i++) { f = mus_file_to_sample(rev, i, 0); f = ins_delay(predelays[0], f); for (j = 0; j < out_chans; j++) { fo[j] = 0.0; for (k = 0; k < comb_len; k++) fo[j] += ins_fcomb(combs[j][k], f); } for (j = 0; j < out_chans; j++) for (k = 0; k < all_len; k++) { g = allpasses[j][k]; fo[j] = ins_all_pass(g, fo[j]); } ob = mus_frample_to_frample(om, out_chans, fo, out_chans, ob, out_chans); mus_frample_to_file(out, i, ob); } } else { mus_float_t *fi, f; fi = mus_vct_data(f_in); for (i = beg; i < len; i++) { fi = mus_file_to_frample(rev, i, fi); for (j = 0; j < out_chans; j++) { f = ins_delay(predelays[j], fi[j]); fo[j] = 0.0; for (k = 0; k < comb_len; k++) fo[j] += ins_fcomb(combs[j][k], f); } for (j = 0; j < out_chans; j++) for (k = 0; k < all_len; k++) { g = allpasses[j][k]; fo[j] = ins_all_pass(g, fo[j]); } ob = mus_frample_to_frample(om, out_chans, fo, out_chans, ob, out_chans); mus_frample_to_file(out, i, ob); } } /* run loop */ for (i = 0; i < in_chans; i++) mus_free(predelays[i]); free(predelays); for (i = 0; i < out_chans; i++) { for (j = 0; j < comb_len; j++) mus_free(combs[i][j]); free(combs[i]); for (j = 0; j < all_len; j++) mus_free(allpasses[i][j]); free(allpasses[i]); } free(combs); free(allpasses); if (!output_mixer) mus_vct_free(out_mix); mus_vct_free(out_buf); mus_vct_free(f_out); mus_vct_free(f_in); return (i); } #define h_fm_violin_args "\ keyword arguments with default values:\n\ :startime 0.0\n\ :duration 1.0\n\ :frequency 440.0\n\ :amplitude 0.5\n\ :fm-index 1.0\n\ :amp-env " INS_LIST_BEG " 0 0 25 1 75 1 100 0 " INS_LIST_END "\n\ :periodic-vibrato-rate 5.0\n\ :periodic-vibrato-amplitude 0.0025\n\ :random-vibrato-rate 16.0\n\ :random-vibrato-amplitude 0.005\n\ :noise-freq 1000.0\n\ :noise-amount 0.0\n\ :ind-noise-freq 10.0\n\ :ind-noise-amount 0.0\n\ :amp-noise-freq 20.0\n\ :amp-noise-amount 0.0\n\ :gliss-env " INS_LIST_BEG " 0 0 100 0 " INS_LIST_END "\n\ :glissando-amount 0.0\n\ :fm1-env " INS_LIST_BEG " 0 1 25 0.4 75 0.6 100 0 " INS_LIST_END "\n\ :fm2-env " INS_LIST_BEG " 0 1 25 0.4 75 0.6 100 0 " INS_LIST_END "\n\ :fm3-env " INS_LIST_BEG " 0 1 25 0.4 75 0.6 100 0 " INS_LIST_END "\n\ :fm1-rat 1.0\n\ :fm2-rat 3.0\n\ :fm3-rat 4.0\n\ :fm1-index " INS_FALSE "\n\ :fm2-index " INS_FALSE "\n\ :fm3-index " INS_FALSE "\n\ :base 1.0\n\ :degree 0.0\n\ :distance 1.0\n\ :reverb-amount 0.01\n\ :index-type " INS_SYMBOL_PREFIX "violin (" INS_SYMBOL_PREFIX "cello or " INS_SYMBOL_PREFIX "violin)\n\ :no-waveshaping " INS_FALSE #if defined(HAVE_RUBY) #define H_fm_violin S_fm_violin "(*args)\n" h_fm_violin_args "\n\ require 'ws'\n\ require 'sndins'\n\ with_sound(:reverb, :jc_reverb, :reverb_data, [:volume, 0.8]) do\n\ fm_violin(0, 1, 440, 0.2, :fm_index, 1.3)\n\ end" #elif defined(HAVE_FORTH) #define H_fm_violin S_fm_violin " ( args -- )\n" h_fm_violin_args "\n\ require clm\n\ dl-load sndins Init_sndins\n\ 0 1 440 0.2 :fm-index 1.3 <'> fm-violin\n\ :reverb <'> jc-reverb :reverb-data #( :volume 0.8 ) with-sound" #else /* HAVE_SCHEME */ #define H_fm_violin "(" S_fm_violin " . args)\n" h_fm_violin_args "\n\ (load \"ws.scm\")\n\ (load-extension \"libsndins\" \"Init_sndins\")\n\ (with-sound (:reverb jc-reverb :reverb-data '(:volume 0.8))\n\ (fm-violin 0 1 440 0.2 :fm-index 1.3))" #endif #if defined(HAVE_FORTH) static void #else static Xen #endif c_fm_violin(Xen args) { #define V_LAST_KEY 33 #define V_INS_VIOLIN 1 #define V_INS_CELLO 0 mus_long_t result; int i, vals, lst_len, mode, amp_len, gls_len; int fm1_len, fm2_len, fm3_len; bool index_type, no_waveshaping; bool amp_del, gls_del, fm1_del, fm2_del, fm3_del; mus_float_t start, dur, freq, amp, fm_index; mus_float_t tamp_env[8] = {0.0, 0.0, 25.0, 1.0, 75.0, 1.0, 100.0, 0.0}; mus_float_t periodic_vibrato_rate, periodic_vibrato_amp; mus_float_t random_vibrato_rate, random_vibrato_amp; mus_float_t noise_freq, noise_amount; mus_float_t ind_noise_freq, ind_noise_amount; mus_float_t amp_noise_freq, amp_noise_amount; mus_float_t tgliss_env[4] = {0.0, 0.0, 100.0, 0.0}; mus_float_t gliss_amount; mus_float_t tfm_env[8] = {0.0, 1.0, 25.0, 0.4, 75.0, 0.6, 100.0, 0.0}; mus_float_t fm1_rat, fm2_rat, fm3_rat; mus_float_t fm1_index, fm2_index, fm3_index, base; mus_float_t degree, distance, reverb_amount; mus_float_t *amp_env = NULL, *gliss_env = NULL; mus_float_t *fm1_env = NULL, *fm2_env = NULL, *fm3_env = NULL; mus_any *out = NULL, *rev = NULL; Xen kargs[V_LAST_KEY * 2], keys[V_LAST_KEY]; int orig_arg[V_LAST_KEY] = {0}; lst_len = Xen_list_length(args); mode = MUS_INTERP_LINEAR; amp_len = fm1_len = fm2_len = fm3_len = 8; gls_len = 4; index_type = (bool)V_INS_VIOLIN; no_waveshaping = amp_del = gls_del = false; fm1_del = fm2_del = fm3_del = false; start = 0.0; dur = 1.0; freq = 440.0; amp = 0.5; fm_index = 1.0; periodic_vibrato_rate = 5.0; periodic_vibrato_amp = 0.0025; random_vibrato_rate = 16.0; random_vibrato_amp = 0.005; noise_freq = 1000.0; noise_amount = 0.0; ind_noise_freq = 10.0; ind_noise_amount = 0.0; amp_noise_freq = 20.0; amp_noise_amount = 0.0; gliss_amount = 0.0; fm1_rat = 1.0; fm2_rat = 3.0; fm3_rat = 4.0; fm1_index = fm2_index = fm3_index = 0.0; base = 1.0; degree = 0.0; distance = 1.0; reverb_amount = 0.01; i = 0; keys[i++] = allkeys[C_startime]; keys[i++] = allkeys[C_duration]; keys[i++] = allkeys[C_frequency]; keys[i++] = allkeys[C_amplitude]; keys[i++] = allkeys[C_fm_index]; keys[i++] = allkeys[C_amp_env]; keys[i++] = allkeys[C_periodic_vibrato_rate]; keys[i++] = allkeys[C_periodic_vibrato_amplitude]; keys[i++] = allkeys[C_random_vibrato_rate]; keys[i++] = allkeys[C_random_vibrato_amplitude]; keys[i++] = allkeys[C_noise_freq]; keys[i++] = allkeys[C_noise_amount]; keys[i++] = allkeys[C_ind_noise_freq]; keys[i++] = allkeys[C_ind_noise_amount]; keys[i++] = allkeys[C_amp_noise_freq]; keys[i++] = allkeys[C_amp_noise_amount]; keys[i++] = allkeys[C_gliss_env]; keys[i++] = allkeys[C_glissando_amount]; keys[i++] = allkeys[C_fm1_env]; keys[i++] = allkeys[C_fm2_env]; keys[i++] = allkeys[C_fm3_env]; keys[i++] = allkeys[C_fm1_rat]; keys[i++] = allkeys[C_fm2_rat]; keys[i++] = allkeys[C_fm3_rat]; keys[i++] = allkeys[C_fm1_index]; keys[i++] = allkeys[C_fm2_index]; keys[i++] = allkeys[C_fm3_index]; keys[i++] = allkeys[C_base]; keys[i++] = allkeys[C_degree]; keys[i++] = allkeys[C_distance]; keys[i++] = allkeys[C_reverb_amount]; keys[i++] = allkeys[C_index_type]; keys[i++] = allkeys[C_no_waveshaping]; for (i = 0; i < V_LAST_KEY * 2; i++) kargs[i] = Xen_undefined; for (i = 0; i < lst_len; i++) kargs[i] = Xen_list_ref(args, i); vals = mus_optkey_unscramble(S_fm_violin, V_LAST_KEY, keys, kargs, orig_arg); if (vals > 0) { i = 0; start = mus_optkey_to_float(keys[i], S_fm_violin, orig_arg[i], start); i++; dur = mus_optkey_to_float(keys[i], S_fm_violin, orig_arg[i], dur); i++; freq = mus_optkey_to_float(keys[i], S_fm_violin, orig_arg[i], freq); i++; amp = mus_optkey_to_float(keys[i], S_fm_violin, orig_arg[i], amp); i++; fm_index = mus_optkey_to_float(keys[i], S_fm_violin, orig_arg[i], fm_index); i++; if (!(Xen_is_keyword(keys[i]))) { Xen_check_type(Xen_is_list(keys[i]), keys[i], orig_arg[i], S_fm_violin, "a list"); amp_env = xen_list2array(keys[i]); amp_len = Xen_list_length(keys[i]); } i++; periodic_vibrato_rate = mus_optkey_to_float(keys[i], S_fm_violin, orig_arg[i], periodic_vibrato_rate); i++; periodic_vibrato_amp = mus_optkey_to_float(keys[i], S_fm_violin, orig_arg[i], periodic_vibrato_amp); i++; random_vibrato_rate = mus_optkey_to_float(keys[i], S_fm_violin, orig_arg[i], random_vibrato_rate); i++; random_vibrato_amp = mus_optkey_to_float(keys[i], S_fm_violin, orig_arg[i], random_vibrato_amp); i++; noise_freq = mus_optkey_to_float(keys[i], S_fm_violin, orig_arg[i], noise_freq); i++; noise_amount = mus_optkey_to_float(keys[i], S_fm_violin, orig_arg[i], noise_amount); i++; ind_noise_freq = mus_optkey_to_float(keys[i], S_fm_violin, orig_arg[i], ind_noise_freq); i++; ind_noise_amount = mus_optkey_to_float(keys[i], S_fm_violin, orig_arg[i], ind_noise_amount); i++; amp_noise_freq = mus_optkey_to_float(keys[i], S_fm_violin, orig_arg[i], amp_noise_freq); i++; amp_noise_amount = mus_optkey_to_float(keys[i], S_fm_violin, orig_arg[i], amp_noise_amount); i++; if (!(Xen_is_keyword(keys[i]))) { Xen_check_type(Xen_is_list(keys[i]), keys[i], orig_arg[i], S_fm_violin, "a list"); gliss_env = xen_list2array(keys[i]); gls_len = Xen_list_length(keys[i]); } i++; gliss_amount = mus_optkey_to_float(keys[i], S_fm_violin, orig_arg[i], gliss_amount); i++; if (!(Xen_is_keyword(keys[i]))) { Xen_check_type(Xen_is_list(keys[i]), keys[i], orig_arg[i], S_fm_violin, "a list"); fm1_env = xen_list2array(keys[i]); fm1_len = Xen_list_length(keys[i]); } i++; if (!(Xen_is_keyword(keys[i]))) { Xen_check_type(Xen_is_list(keys[i]), keys[i], orig_arg[i], S_fm_violin, "a list"); fm2_env = xen_list2array(keys[i]); fm2_len = Xen_list_length(keys[i]); } i++; if (!(Xen_is_keyword(keys[i]))) { Xen_check_type(Xen_is_list(keys[i]), keys[i], orig_arg[i], S_fm_violin, "a list"); fm3_env = xen_list2array(keys[i]); fm3_len = Xen_list_length(keys[i]); } i++; fm1_rat = mus_optkey_to_float(keys[i], S_fm_violin, orig_arg[i], fm1_rat); i++; fm2_rat = mus_optkey_to_float(keys[i], S_fm_violin, orig_arg[i], fm2_rat); i++; fm3_rat = mus_optkey_to_float(keys[i], S_fm_violin, orig_arg[i], fm3_rat); i++; if (!(Xen_is_keyword(keys[i]))) if (Xen_is_number(keys[i])) fm1_index = Xen_real_to_C_double(keys[i]); i++; if (!(Xen_is_keyword(keys[i]))) if (Xen_is_number(keys[i])) fm2_index = Xen_real_to_C_double(keys[i]); i++; if (!(Xen_is_keyword(keys[i]))) if (Xen_is_number(keys[i])) fm3_index = Xen_real_to_C_double(keys[i]); i++; base = mus_optkey_to_float(keys[i], S_fm_violin, orig_arg[i], base); i++; degree = mus_optkey_to_float(keys[i], S_fm_violin, orig_arg[i], degree); i++; distance = mus_optkey_to_float(keys[i], S_fm_violin, orig_arg[i], distance); i++; reverb_amount = mus_optkey_to_float(keys[i], S_fm_violin, orig_arg[i], reverb_amount); i++; if (!(Xen_is_keyword(keys[i]))) { /* cello == 0, violin == 1 */ if (Xen_is_symbol(keys[i])) { if (Xen_is_eq(keys[i], C_string_to_Xen_symbol("cello"))) index_type = V_INS_CELLO; } else if (Xen_is_integer(keys[i])) index_type = Xen_integer_to_C_int(keys[i]); } i++; if (!(Xen_is_keyword(keys[i]))) { Xen_check_type(Xen_is_boolean(keys[i]), keys[i], orig_arg[i], S_fm_violin, "a bool"); no_waveshaping = Xen_boolean_to_C_bool(keys[i]); } } if (amp_env == NULL) { amp_env = array2array(tamp_env, 8); amp_del = true; } if (gliss_env == NULL) { gliss_env = array2array(tgliss_env, 4); gls_del = true; } if (fm1_env == NULL) { fm1_env = array2array(tfm_env, 8); fm1_del = true; } if (fm2_env == NULL) { fm2_env = array2array(tfm_env, 8); fm2_del = true; } if (fm3_env == NULL) { fm3_env = array2array(tfm_env, 8); fm3_del = true; } out = get_global_mus_gen(INS_OUTPUT); if (!mus_is_output(out)) INS_MISC_ERROR(S_fm_violin, "needs an output generator"); rev = get_global_mus_gen(INS_REVERB); mode = get_global_int(INS_LOCSIG_TYPE, MUS_INTERP_LINEAR); result = ins_fm_violin(start, dur, freq, amp, fm_index, amp_env, amp_len, periodic_vibrato_rate, periodic_vibrato_amp, random_vibrato_rate, random_vibrato_amp, noise_freq, noise_amount, ind_noise_freq, ind_noise_amount, amp_noise_freq, amp_noise_amount, gliss_env, gls_len, gliss_amount, fm1_env, fm1_len, fm2_env, fm2_len, fm3_env, fm3_len, fm1_rat, fm2_rat, fm3_rat, fm1_index, fm2_index, fm3_index, base, degree, distance, reverb_amount, index_type, no_waveshaping, out, rev, mode); if (amp_del) free(amp_env); if (gls_del) free(gliss_env); if (fm1_del) free(fm1_env); if (fm2_del) free(fm2_env); if (fm3_del) free(fm3_env); #if !defined(HAVE_FORTH) return (C_int_to_Xen_integer(result)); #endif } #define INS_REV_MSG(caller, in_chans, out_chans) \ ins_message("%s on %d in and %d out channels\n", \ caller, in_chans, out_chans) #define INS_REV_DUR(rev) \ (mus_samples_to_seconds(mus_length(rev)) + \ get_global_float(INS_DECAY_TIME, 1.0)) #define h_jc_reverb_args "\ keyword arguments with default values:\n\ :volume 1.0\n\ :delay1 0.013\n\ :delay2 0.011\n\ :delay3 0.015\n\ :delay4 0.017\n\ :low-pass " INS_FALSE "\n\ :doubled " INS_FALSE "\n\ :amp-env " INS_FALSE #if defined(HAVE_RUBY) #define H_jc_reverb S_jc_reverb "(*args)\n" h_jc_reverb_args "\n\ require 'ws'\n\ require 'sndins'\n\ with_sound(:reverb, :jc_reverb, :reverb_data, [:volume, 0.8]) do\n\ fm_violin(0, 1, 440, 0.2, :fm_index, 1.3)\n\ end" #elif defined(HAVE_FORTH) #define H_jc_reverb S_jc_reverb " ( args -- )\n" h_jc_reverb_args "\n\ require clm\n\ dl-load sndins Init_sndins\n\ 0 1 440 0.2 :fm-index 1.3 <'> fm-violin\n\ :reverb <'> jc-reverb :reverb-data #( :volume 0.8 ) with-sound" #else /* HAVE_SCHEME */ #define H_jc_reverb "(" S_jc_reverb " . args)\n" h_jc_reverb_args "\n\ (load-from-path \"ws.scm\")\n\ (load-extension \"libsndins\" \"Init_sndins\")\n\ (with-sound (:reverb jc-reverb :reverb-data '(:volume 0.8))\n\ (fm-violin 0 1 440 0.2 :fm-index 1.3))" #endif #if defined(HAVE_FORTH) static void #else static Xen #endif c_jc_reverb(Xen args) { #define JC_LAST_KEY 8 mus_long_t result; int i, vals, lst_len, amp_len; bool low_pass, doubled; mus_float_t volume, delay1, delay2, delay3, delay4; mus_float_t *amp_env = NULL; mus_any *out = NULL, *rev = NULL; int orig_arg[JC_LAST_KEY] = {0}; Xen kargs[JC_LAST_KEY * 2], keys[JC_LAST_KEY]; amp_len = 0; lst_len = Xen_list_length(args); low_pass = doubled = false; volume = 1.0; delay1 = 0.013; delay2 = 0.011; delay3 = 0.015; delay4 = 0.017; i = 0; keys[i++] = allkeys[C_low_pass]; keys[i++] = allkeys[C_volume]; keys[i++] = allkeys[C_doubled]; keys[i++] = allkeys[C_delay1]; keys[i++] = allkeys[C_delay2]; keys[i++] = allkeys[C_delay3]; keys[i++] = allkeys[C_delay4]; keys[i++] = allkeys[C_amp_env]; for (i = 0; i < JC_LAST_KEY * 2; i++) kargs[i] = Xen_undefined; for (i = 0; i < lst_len; i++) kargs[i] = Xen_list_ref(args, i); vals = mus_optkey_unscramble(S_jc_reverb, JC_LAST_KEY, keys, kargs, orig_arg); if (vals > 0) { i = 0; if (!(Xen_is_keyword(keys[i]))) { Xen_check_type(Xen_is_boolean(keys[i]), keys[i], orig_arg[i], S_jc_reverb, "a bool"); low_pass = Xen_boolean_to_C_bool(keys[i]); } i++; volume = mus_optkey_to_float(keys[i], S_jc_reverb, orig_arg[i], volume); i++; if (!(Xen_is_keyword(keys[i]))) { Xen_check_type(Xen_is_boolean(keys[i]), keys[i], orig_arg[i], S_jc_reverb, "a bool"); doubled = Xen_boolean_to_C_bool(keys[i]); } i++; delay1 = mus_optkey_to_float(keys[i], S_jc_reverb, orig_arg[i], delay1); i++; delay2 = mus_optkey_to_float(keys[i], S_jc_reverb, orig_arg[i], delay2); i++; delay3 = mus_optkey_to_float(keys[i], S_jc_reverb, orig_arg[i], delay3); i++; delay4 = mus_optkey_to_float(keys[i], S_jc_reverb, orig_arg[i], delay4); i++; if (!(Xen_is_keyword(keys[i]))) { Xen_check_type(Xen_is_list(keys[i]), keys[i], orig_arg[i], S_jc_reverb, "a list"); amp_env = xen_list2array(keys[i]); amp_len = Xen_list_length(keys[i]); } } out = get_global_mus_gen(INS_OUTPUT); if (!mus_is_output(out)) INS_MISC_ERROR(S_jc_reverb, "needs an output generator"); rev = get_global_mus_gen(INS_REVERB); if (!mus_is_input(rev)) INS_MISC_ERROR(S_jc_reverb, "needs an input generator"); if (get_global_boolean(INS_VERBOSE, false)) INS_REV_MSG(S_jc_reverb, mus_channels(rev), mus_channels(out)); result = ins_jc_reverb(0.0, INS_REV_DUR(rev), volume, low_pass, doubled, delay1, delay2, delay3, delay4, amp_env, amp_len, out, rev); #if !defined(HAVE_FORTH) return (C_int_to_Xen_integer(result)); #endif } #define h_nrev_args "\ keyword arguments with default values:\n\ :reverb-factor 1.09\n\ :lp-coeff 0.7\n\ :lp-out-coeff 0.85\n\ :output-scale 1.0\n\ :amp-env " INS_LIST_BEG " 0 1 1 1 " INS_LIST_END "\n\ :volume 1.0" #if defined(HAVE_RUBY) #define H_nrev S_nrev "(*args)\n" h_nrev_args "\n\ require 'ws'\n\ require 'sndins'\n\ with_sound(:reverb, :nrev, :reverb_data, [:lp_coeff, 0.6]) do\n\ fm_violin(0, 1, 440, 0.7, :fm_index, 1.3)\n\ end" #elif defined(HAVE_FORTH) #define H_nrev S_nrev " ( args -- )\n" h_nrev_args "\n\ require clm\n\ dl-load sndins Init_sndins\n\ 0 1 440 0.7 :fm-index 1.3 <'> fm-violin\n\ :reverb <'> nrev :reverb-data #( :lp-coeff 0.6 ) with-sound" #else /* HAVE_SCHEME */ #define H_nrev "(" S_nrev " . args)\n" h_nrev_args "\n\ (load \"ws.scm\")\n\ (load-extension \"libsndins\" \"Init_sndins\")\n\ (with-sound (:reverb nrev :reverb-data '(:lp-coeff 0.6))\n\ (fm-violin 0 1 440 0.7 :fm-index 1.3))" #endif #if defined(HAVE_FORTH) static void #else static Xen #endif c_nrev(Xen args) { #define N_LAST_KEY 6 mus_long_t result; int i, vals, lst_len, amp_len; bool amp_del; mus_float_t lp_coeff, lp_out_coeff; mus_float_t output_scale, reverb_factor, volume; mus_float_t tamp_env[4] = {0, 1, 1, 1}; mus_float_t *amp_env = NULL; mus_any *out = NULL, *rev = NULL; int orig_arg[N_LAST_KEY] = {0}; Xen kargs[N_LAST_KEY * 2], keys[N_LAST_KEY]; lst_len = Xen_list_length(args); amp_len = 4; amp_del = false; lp_coeff = 0.7; lp_out_coeff = 0.85; output_scale = 1.0; reverb_factor = 1.09; volume = 1.0; i = 0; keys[i++] = allkeys[C_reverb_factor]; keys[i++] = allkeys[C_lp_coeff]; keys[i++] = allkeys[C_lp_out_coeff]; keys[i++] = allkeys[C_output_scale]; keys[i++] = allkeys[C_amp_env]; keys[i++] = allkeys[C_volume]; for (i = 0; i < N_LAST_KEY * 2; i++) kargs[i] = Xen_undefined; for (i = 0; i < lst_len; i++) kargs[i] = Xen_list_ref(args, i); vals = mus_optkey_unscramble(S_nrev, N_LAST_KEY, keys, kargs, orig_arg); if (vals > 0) { i = 0; reverb_factor = mus_optkey_to_float(keys[i], S_nrev, orig_arg[i], reverb_factor); i++; lp_coeff = mus_optkey_to_float(keys[i], S_nrev, orig_arg[i], lp_coeff); i++; lp_out_coeff = mus_optkey_to_float(keys[i], S_nrev, orig_arg[i], lp_out_coeff); i++; output_scale = mus_optkey_to_float(keys[i], S_nrev, orig_arg[i], output_scale); i++; if (!(Xen_is_keyword(keys[i]))) { Xen_check_type(Xen_is_list(keys[i]), keys[i], orig_arg[i], S_nrev, "a list"); amp_env = xen_list2array(keys[i]); amp_len = Xen_list_length(keys[i]); } i++; volume = mus_optkey_to_float(keys[i], S_nrev, orig_arg[i], volume); } if (amp_env == NULL) { amp_env = array2array(tamp_env, 4); amp_del = true; } out = get_global_mus_gen(INS_OUTPUT); if (!mus_is_output(out)) INS_MISC_ERROR(S_nrev, "needs an output generator"); rev = get_global_mus_gen(INS_REVERB); if (!mus_is_input(rev)) INS_MISC_ERROR(S_nrev, "needs an input generator"); if (get_global_boolean(INS_VERBOSE, false)) INS_REV_MSG(S_nrev, mus_channels(rev), mus_channels(out)); result = ins_nrev(0.0, INS_REV_DUR(rev), reverb_factor, lp_coeff, lp_out_coeff, output_scale, volume, amp_env, amp_len, out, rev); if (amp_del) free(amp_env); #if !defined(HAVE_FORTH) return (C_int_to_Xen_integer(result)); #endif } #define h_freeverb_args "\ keyword arguments with default values:\n\ :room-decay 0.5\n\ :damping 0.5\n\ :global 0.3\n\ :predelay 0.03\n\ :output-gain 1.0\n\ :output-mixer " INS_FALSE "\n\ :scale-room-decay 0.28\n\ :offset-room-decay 0.7\n\ :combtuning " INS_LIST_BEG " 1116 1188 1277 1356 1422 1491 1557 1617 " INS_LIST_END "\n\ :allpasstuning " INS_LIST_BEG " 556 441 341 225 " INS_LIST_END "\n\ :scale-damping 0.4\n\ :stereo-spread 23.0" #if defined(HAVE_RUBY) #define H_freeverb S_freeverb "(*args)\n" h_freeverb_args "\n\ require 'ws'\n\ require 'sndins'\n\ with_sound(:reverb, :freeverb, :reverb_data, [:room_decay, 0.8]) do\n\ fm_violin(0, 1, 440, 0.7)\n\ end" #elif defined(HAVE_FORTH) #define H_freeverb S_freeverb " ( args -- )\n" h_freeverb_args "\n\ require clm\n\ dl-load sndins Init_sndins\n\ 0 1 440 0.7 <'> fm-violin\n\ :reverb <'> freeverb\n\ :reverb-data #( :room-decay 0.8 ) with-sound" #else /* HAVE_SCHEME */ #define H_freeverb "(" S_freeverb " . args)\n" h_freeverb_args "\n\ (load \"ws.scm\")\n\ (load-extension \"libsndins\" \"Init_sndins\")\n\ (with-sound (:reverb freeverb :reverb-data '(:room-decay 0.8))\n\ (fm-violin 0 1 440 0.7))" #endif #if defined(HAVE_FORTH) static void #else static Xen #endif c_freeverb(Xen args) { #define F_LAST_KEY 12 mus_long_t result; int i, vals, lst_len, numcombs, numallpasses; int tcombtun[8] = {1116, 1188, 1277, 1356, 1422, 1491, 1557, 1617}; int tallpass[4] = {556, 441, 341, 225}; int *combtuning = NULL, *allpasstuning = NULL; bool comb_del, allpass_del; mus_float_t room_decay, global, damping; mus_float_t predelay, output_gain, scale_room_decay; mus_float_t offset_room_decay, scale_damping, stereo_spread; vct *output_mixer = NULL; mus_any *out = NULL, *rev = NULL; int orig_arg[F_LAST_KEY] = {0}; Xen kargs[F_LAST_KEY * 2], keys[F_LAST_KEY]; lst_len = Xen_list_length(args); numcombs = 8; numallpasses = 4; comb_del = allpass_del = false; room_decay = 0.5; global = 0.3; damping = 0.5; predelay = 0.03; output_gain = 1.0; scale_room_decay = 0.28; offset_room_decay = 0.7; scale_damping = 0.4; stereo_spread = 23.0; i = 0; keys[i++] = allkeys[C_room_decay]; keys[i++] = allkeys[C_damping]; keys[i++] = allkeys[C_global]; keys[i++] = allkeys[C_predelay]; keys[i++] = allkeys[C_output_gain]; keys[i++] = allkeys[C_output_mixer]; keys[i++] = allkeys[C_scale_room_decay]; keys[i++] = allkeys[C_offset_room_decay]; keys[i++] = allkeys[C_combtuning]; keys[i++] = allkeys[C_allpasstuning]; keys[i++] = allkeys[C_scale_damping]; keys[i++] = allkeys[C_stereo_spread]; for (i = 0; i < F_LAST_KEY * 2; i++) kargs[i] = Xen_undefined; for (i = 0; i < lst_len; i++) kargs[i] = Xen_list_ref(args, i); vals = mus_optkey_unscramble(S_freeverb, F_LAST_KEY, keys, kargs, orig_arg); if (vals > 0) { i = 0; room_decay = mus_optkey_to_float(keys[i], S_freeverb, orig_arg[i], room_decay); i++; damping = mus_optkey_to_float(keys[i], S_freeverb, orig_arg[i], damping); i++; global = mus_optkey_to_float(keys[i], S_freeverb, orig_arg[i], global); i++; predelay = mus_optkey_to_float(keys[i], S_freeverb, orig_arg[i], predelay); i++; output_gain = mus_optkey_to_float(keys[i], S_freeverb, orig_arg[i], output_gain); i++; output_mixer = mus_optkey_to_vct(keys[i], S_freeverb, orig_arg[i], output_mixer); i++; scale_room_decay = mus_optkey_to_float(keys[i], S_freeverb, orig_arg[i], scale_room_decay); i++; offset_room_decay = mus_optkey_to_float(keys[i], S_freeverb, orig_arg[i], offset_room_decay); i++; if (!(Xen_is_keyword(keys[i]))) { Xen_check_type(Xen_is_list(keys[i]), keys[i], orig_arg[i], S_freeverb, "a list"); combtuning = xen_list2iarray(keys[i]); numcombs = Xen_list_length(keys[i]); } i++; if (!(Xen_is_keyword(keys[i]))) { Xen_check_type(Xen_is_list(keys[i]), keys[i], orig_arg[i], S_freeverb, "a list"); allpasstuning = xen_list2iarray(keys[i]); numallpasses = Xen_list_length(keys[i]); } i++; scale_damping = mus_optkey_to_float(keys[i], S_freeverb, orig_arg[i], scale_damping); i++; stereo_spread = mus_optkey_to_float(keys[i], S_freeverb, orig_arg[i], stereo_spread); } if (!combtuning) { combtuning = int_array2array(tcombtun, 8); comb_del = true; } if (!allpasstuning) { allpasstuning = int_array2array(tallpass, 4); allpass_del = true; } out = get_global_mus_gen(INS_OUTPUT); if (!mus_is_output(out)) INS_MISC_ERROR(S_freeverb, "needs an output generator"); rev = get_global_mus_gen(INS_REVERB); if (!mus_is_input(rev)) INS_MISC_ERROR(S_freeverb, "needs an input generator"); if (get_global_boolean(INS_VERBOSE, false)) INS_REV_MSG(S_freeverb, mus_channels(rev), mus_channels(out)); result = ins_freeverb(0.0, INS_REV_DUR(rev), room_decay, damping, global, predelay, output_gain, scale_room_decay, offset_room_decay, scale_damping, stereo_spread, combtuning, numcombs, allpasstuning, numallpasses, output_mixer, out, rev); if (comb_del) free(combtuning); if (allpass_del) free(allpasstuning); #if !defined(HAVE_FORTH) return (C_int_to_Xen_integer(result)); #endif } #if defined(Xen_wrap_1_optional_arg) Xen_wrap_any_args(x_make_fcomb, c_make_fcomb) Xen_wrap_2_optional_args(x_fcomb, c_fcomb) Xen_wrap_1_arg(x_is_fcomb, c_is_fcomb) #if defined(HAVE_FORTH) /* these are void functions */ #define x_fm_violin c_fm_violin #define x_jc_reverb c_jc_reverb #define x_nrev c_nrev #define x_freeverb c_freeverb #else Xen_wrap_any_args(x_fm_violin, c_fm_violin) Xen_wrap_any_args(x_jc_reverb, c_jc_reverb) Xen_wrap_any_args(x_nrev, c_nrev) Xen_wrap_any_args(x_freeverb, c_freeverb) #endif #else /* !Xen_wrap_1_optional_arg */ #define x_make_fcomb c_make_fcomb #define x_fcomb c_fcomb #define x_is_fcomb c_is_fcomb #define x_fm_violin c_fm_violin #define x_jc_reverb c_jc_reverb #define x_nrev c_nrev #define x_freeverb c_freeverb #endif /* Xen_wrap_1_optional_arg */ void Init_sndins(void) { #if defined(HAVE_SCHEME) if (s7 == NULL) s7 = s7_init(); #endif init_keywords(); Xen_define_procedure(S_make_fcomb, x_make_fcomb, 0, 0, 1, H_make_fcomb); Xen_define_procedure(S_fcomb, x_fcomb, 1, 1, 0, H_fcomb); Xen_define_procedure(S_is_fcomb, x_is_fcomb, 1, 0, 0, H_is_fcomb); #if defined(HAVE_FORTH) #define Xen_define_void_proc(Name, Func, Req, Opt, Rest, Help) \ fth_define_void_procedure(Name, Func, Req, Opt, Rest, Help) Xen_define_void_proc(S_fm_violin, x_fm_violin, 0, 0, 1, H_fm_violin); Xen_define_void_proc(S_jc_reverb, x_jc_reverb, 0, 0, 1, H_jc_reverb); Xen_define_void_proc(S_nrev, x_nrev, 0, 0, 1, H_nrev); Xen_define_void_proc(S_freeverb, x_freeverb, 0, 0, 1, H_freeverb); #else Xen_define_procedure(S_fm_violin, x_fm_violin, 0, 0, 1, H_fm_violin); Xen_define_procedure(S_jc_reverb, x_jc_reverb, 0, 0, 1, H_jc_reverb); Xen_define_procedure(S_nrev, x_nrev, 0, 0, 1, H_nrev); Xen_define_procedure(S_freeverb, x_freeverb, 0, 0, 1, H_freeverb); #endif Xen_provide_feature("sndins"); } /* * sndins.c ends here */ snd-16.1/sndins/sndins.h0000644000076400007640000000773512433105741013314 0ustar bilbil/* sndins.h -- Sndins for Snd/CLM * * Copyright (c) 2003-2014 Michael Scholz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)sndins.h 1.6 11/18/14 */ #ifndef _SNDINS_H_ #define _SNDINS_H_ #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus #define __BEGIN_DECLS extern "C" { #define __END_DECLS } #else #define __BEGIN_DECLS #define __END_DECLS #endif __BEGIN_DECLS mus_any *mus_make_fcomb(mus_float_t scaler, int size, mus_float_t a0, mus_float_t a1); int mus_fcomb_p(mus_any *ptr); mus_float_t mus_fcomb(mus_any *ptr, mus_float_t input, mus_float_t ignored); mus_long_t ins_fm_violin(mus_float_t start, mus_float_t dur, mus_float_t freq, mus_float_t amp, mus_float_t fm_index, mus_float_t *amp_env, int amp_len, mus_float_t periodic_vibrato_rate, mus_float_t periodic_vibrato_amp, mus_float_t random_vibrato_rate, mus_float_t random_vibrato_amp, mus_float_t noise_freq, mus_float_t noise_amount, mus_float_t ind_noise_freq, mus_float_t ind_noise_amount, mus_float_t amp_noise_freq, mus_float_t amp_noise_amount, mus_float_t *gliss_env, int gliss_len, mus_float_t gliss_amount, mus_float_t *fm1_env, int fm1_len, mus_float_t *fm2_env, int fm2_len, mus_float_t *fm3_env, int fm3_len, mus_float_t fm1_rat, mus_float_t fm2_rat, mus_float_t fm3_rat, mus_float_t fm1_index, mus_float_t fm2_index, mus_float_t fm3_index, mus_float_t base, mus_float_t degree, mus_float_t distance, mus_float_t reverb_amount, bool index_type, bool no_waveshaping, mus_any *out, mus_any *rev, mus_interp_t mode); mus_long_t ins_jc_reverb(mus_float_t start, mus_float_t dur, mus_float_t volume, bool low_pass, bool doubled, mus_float_t delay1, mus_float_t delay2, mus_float_t delay3, mus_float_t delay4, mus_float_t *amp_env, int amp_len, mus_any *out, mus_any *rev); mus_long_t ins_nrev(mus_float_t start, mus_float_t dur, mus_float_t reverb_factor, mus_float_t lp_coeff, mus_float_t lp_out_coeff, mus_float_t output_scale, mus_float_t volume, mus_float_t *amp_env, int amp_len, mus_any *out, mus_any *rev); mus_long_t ins_freeverb(mus_float_t start, mus_float_t dur, mus_float_t room_decay, mus_float_t damping, mus_float_t global, mus_float_t predelay, mus_float_t output_gain, mus_float_t scale_room_decay, mus_float_t offset_room_decay, mus_float_t scale_damping, mus_float_t stereo_spread, int *combtuning, int comb_len, int *allpasstuning, int all_len, vct *output_mixer, mus_any *out, mus_any *rev); void Init_sndins(void); __END_DECLS #endif /* _SNDINS_H_ */ /* * sndins.h ends here */ snd-16.1/sndins/README0000644000076400007640000002677712433106015012527 0ustar bilbil* Introduction The C/XEN library `libsndins.so' provides the instrument FM-VIOLIN and the reverberators JC-REVERB, NREV, and FREEVERB to use them in longer notelists in Snd/Ruby, or Snd/Forth. They are not so fast as Lisp's FFI versions, at least not on my machine, but they run much faster than Ruby or Forth variants. In addition I have added the FCOMB example from sndscm.html which is used in freeverb. The library is based on Bill Schottstaedt's `xen' and `sndlib' libraries and the Snd editor itself. Thank you for these great music programs and libraries! * XEN-Instruments The following generator and instruments are accessible from S7, Ruby and Forth. ** make-fcomb, fcomb?, and fcomb These are the examples from sndscm.html. *** (make-fcomb (:scaler 1.0) (:size 1) (:a0 0.0) (:a1 0.0)) *** make_fcomb(:scaler, 1.0, :size, 1, :a0, 0.0, :a1, 0.0) *** make-fcomb ( :scaler 1.0 :size 1 :a0 0.0 :a1 0.0 -- gen ) Return a new fcomb generator. *** (fcomb? gen) *** fcomb?(gen) *** fcomb? ( gen -- f ) Test if GEN is an fcomb generator. *** (fcomb gen (input 0.0)) *** fcomb(gen[, input=0.0]) *** fcomb ( gen input=0.0 -- result ) Return the next value of the fcomb generator GEN. *** (mus-describe gen) *** gen.to_s *** object->string ( gen -- str ) Show the inspect string of the fcomb GEN. *** (mus-length gen) *** gen.length *** mus-length ( gen -- len ) Show length of delay line. *** (mus-scaler gen) (set! (mus-scaler gen) scl) *** gen.scaler gen.scaler = scl *** mus-scaler ( gen -- scl ) set-mus-scaler ( gen scl -- scl ) Show the scaler value, settable. *** (mus-xcoeff gen index) (set! (mus-xcoeff gen index) val) *** gen.xcoeff(index) gen.xcoeff = [index, val] *** mus-xcoeff ( gen index -- val ) set-mus-xcoeff ( gen index val -- val ) Show the a0/a1 values, settable (index == 0: a0, index == 1: a1) ** fm-violin Keyword options for fm-violin (v.ins, v.scm, examp.rb, clm-ins.fs). *** :startime 0.0 *** :duration 1.0 *** :frequency 440.0 *** :amplitude 0.5 *** :fm-index 1.0 *** :amp-env '( 0 0 25 1 75 1 100 0 ) *** :periodic-vibrato-rate 5.0 *** :periodic-vibrato-amplitude 0.0025 *** :random-vibrato-rate 16.0 *** :random-vibrato-amplitude 0.005 *** :noise-freq 1000.0 *** :noise-amount 0.0 *** :ind-noise-freq 10.0 *** :ind-noise-amount 0.0 *** :amp-noise-freq 20.0 *** :amp-noise-amount 0.0 *** :gliss-env '( 0 0 100 0 ) *** :glissando-amount 0.0 *** :fm1-env '( 0 1 25 0.4 75 0.6 100 0 ) *** :fm2-env '( 0 1 25 0.4 75 0.6 100 0 ) *** :fm3-env '( 0 1 25 0.4 75 0.6 100 0 ) *** :fm1-rat 1.0 *** :fm2-rat 3.0 *** :fm3-rat 4.0 *** :fm1-index #f *** :fm2-index #f *** :fm3-index #f *** :base 1.0 *** :degree 0.0 *** :distance 1.0 *** :reverb-amount 0.01 *** :index-type 'violin ('cello or 'violin) *** :no-waveshaping #f ** jc-reverb Keyword options for jc-reverb (jcrev.ins, jcrev.scm, examp.rb, clm-ins.fs). *** :volume 1.0 *** :delay1 0.013 *** :delay2 0.011 *** :delay3 0.015 *** :delay4 0.017 *** :low-pass #f *** :doubled #f *** :amp-env #f If more than one reverb channel exist, the values from them are collected together before computing the result. ** nrev Keyword options for nrev (nrev.ins, clm-ins.scm, clm-ins.rb). *** :reverb-factor 1.09 *** :lp-coeff 0.7 *** :lp-out-coeff 0.85 *** :output-scale 1.0 *** :amp-env '( 0 1 1 1 ) *** :volume 1.0 If more than one reverb channel exist, the values from them are collected together before computing the result. ** freeverb Keyword options for freeverb (freeverb.ins, freeverb.scm, freeverb.rb). *** :room-decay 0.5 *** :damping 0.5 *** :global 0.3 *** :predelay 0.03 *** :output-gain 1.0 *** :output-mixer #f *** :scale-room-decay 0.28 *** :offset-room-decay 0.7 *** :combtuning '( 1116 1188 1277 1356 1422 1491 1557 1617 ) *** :allpasstuning '( 556 441 341 225 ) *** :scale-damping 0.4 *** :stereo-spread 23.0 Works with one reverb channel or the same number of reverb channels like output channels. * C-Instruments The following functions are accessible from C. ** mus_any *mus_make_fcomb(mus_float_t scaler, int size, mus_float_t a0, mus_float_t a1); ** int mus_fcomb_p(mus_any *ptr); ** mus_float_t mus_fcomb(mus_any *ptr, mus_float_t input, mus_float_t ignored); ** mus_long_t ins_fm_violin(mus_float_t start, mus_float_t dur, mus_float_t freq, mus_float_t amp, mus_float_t fm_index, mus_float_t *amp_env, int amp_len, mus_float_t periodic_vibrato_rate, mus_float_t periodic_vibrato_amp, mus_float_t random_vibrato_rate, mus_float_t random_vibrato_amp, mus_float_t noise_freq, mus_float_t noise_amount, mus_float_t ind_noise_freq, mus_float_t ind_noise_amount, mus_float_t amp_noise_freq, mus_float_t amp_noise_amount, mus_float_t *gliss_env, int gliss_len, mus_float_t gliss_amount, mus_float_t *fm1_env, int fm1_len, mus_float_t *fm2_env, int fm2_len, mus_float_t *fm3_env, int fm3_len, mus_float_t fm1_rat, mus_float_t fm2_rat, mus_float_t fm3_rat, mus_float_t fm1_index, mus_float_t fm2_index, mus_float_t fm3_index, mus_float_t base, mus_float_t degree, mus_float_t distance, mus_float_t reverb_amount, bool index_type, bool no_waveshaping, mus_any *out, mus_any *rev, mus_interp_t mode); ** mus_long_t ins_jc_reverb(mus_float_t start, mus_float_t dur, mus_float_t volume, bool low_pass, bool doubled, mus_float_t delay1, mus_float_t delay2, mus_float_t delay3, mus_float_t delay4, mus_float_t *amp_env, int amp_len, mus_any *out, mus_any *rev); ** mus_long_t ins_nrev(mus_float_t start, mus_float_t dur, mus_float_t reverb_factor, mus_float_t lp_coeff, mus_float_t lp_out_coeff, mus_float_t output_scale, mus_float_t volume, mus_float_t *amp_env, int amp_len, mus_any *out, mus_any *rev); ** mus_long_t ins_freeverb(mus_float_t start, mus_float_t dur, mus_float_t room_decay, mus_float_t damping, mus_float_t global, mus_float_t predelay, mus_float_t output_gain, mus_float_t scale_room_decay, mus_float_t offset_room_decay, mus_float_t scale_damping, mus_float_t stereo_spread, int *combtuning, int comb_len, int *allpasstuning, int all_len, vct *output_mixer, mus_any *out, mus_any *rev); * Prerequisite Sndins depends on a configured and compiled, but not necessary installed, libsndlib.a one directory in the hierarchy above sndins. Configuring sndlib from sndlib.tar.gz creates a Makefile in sndlib/sndins, sndlib's mus-config.h is needed as well and the compiled sndlib/libsndlib.a will be linked in sndlib/sndins/libsndins.* * Compilation Running Sndlib's configure script in sndlib path creates sndins/Makefile from sndins/Makefile.in so we can use the configured variables from Sndlib. Then one can cd to sndins and run make. Again: Sndlib must be configured before! cd sndins make * Installation ** S7 You can install libsndlib.so and libsndins.so to ${prefix}/lib with the usual `make install' command. Again: Sndlib must be configured before! cd ${compile_sndlib_dir} make make install cd sndins make make install The library path should be in your LD_LIBRARY_PATH, e.g. if you have installed the library in the unusual path /usr/opt/lib., you can add it by: (csh) setenv LD_LIBRARY_PATH /usr/opt/lib:${LD_LIBRARY_PATH} (sh) LD_LIBRARY_PATH=/usr/opt/lib:${LD_LIBRARY_PATH} (sh) export LD_LIBRARY_PATH In Snd/S7 one can add to the ~/.snd_s7 init file: (begin (if (not (provided? 'sndlib)) (let ((hsndlib (dlopen "sndlib.so"))) (if (string? hsndlib) (snd-error (format #f "script needs the sndlib module: ~A" hsndlib)) (dlinit hsndlib "Init_sndlib")))) (if (not (provided? 'sndins)) (let ((hsndins (dlopen "sndins.so"))) (if (string? hsndins) (snd-error (format #f "script needs the sndins module: ~A" hsndins)) (dlinit hsndins "Init_sndins"))))) ** Ruby You can install sndlib.so and sndins.so in the ruby library path, e.g. (csh) setenv RUBYLIB ${HOME}/share/snd:${HOME}/lib/ruby/site-ruby (sh) RUBYLIB=${HOME}/share/snd:${HOME}/lib/ruby/site-ruby; export RUBYLIB cd ${compile_sndlib_dir} make install -c sndlib.so ~/lib/ruby/site-ruby/ cd sndins make install -c sndins.so ~/lib/ruby/site-ruby/ In Snd/Ruby one can add to the ~/.snd_ruby init file: require "sndlib" require "sndins" ** Forth Installing so-libs in Forth is possible with these command lines: (csh) setenv FTH_FTHPATH ${HOME}/share/fth/site-fth (csh) setenv FTH_LIBPATH ${HOME}/lib/fth (sh) FTH_FTHPATH=${HOME}/share/fth/site-fth; export FTH_FTHPATH (sh) FTH_LIBPATH=${HOME}/lib/fth; export FTH_LIBPATH cd ${compile_sndlib_dir} make fth -e "install sndlib.so" cd sndins make fth -e "install sndins.so" These lines install the libraries in ~/lib/fth, the first user writeable path in $FTH_LIBPATH. Then in Snd/Forth one can add to the ~/.snd_forth init file: dl-load sndlib Init_sndlib dl-load sndins Init_sndins * Samples You can load the sample files into Snd, with Ruby and Forth you can test them in a shell too. One may set with-sound variables in agn.* and fmviolin.* files. The agn.* files are translations of clm/clm-example.clm into S7, Ruby, and Forth as a test case. The fmviolin.* files are translations of clm/fmviolin.clm into S7, Ruby, and Forth as a test case. ** S7 You can load the *.scm scripts into Snd. If you have compiled and installed the S7 sndlib and sndins libraries, you can type (do-agn) ;; agn.scm (short-example) ;; fmviolin.scm (long-example) ;; fmviolin.scm ** Ruby If you have compiled and installed the Ruby sndlib and sndins libraries, you can type in a shell ./agn.rb [ outfile.rbm ] ./fmviolin.rb [ /dev/null ] The default outfile is agn.rbm. A different outfile name may end in *.rbm. The option /dev/null can be everything, its only meaning is to choose the short_example, without an option long_example is chosen. You can load these scripts into Snd too. ** Forth If you have compiled and installed the Forth sndlib and sndins libraries, you can type ./agn.fth [ outfile.fsm ] ./fmviolin.fth [ /dev/null ] The default outfile is agn.fsm. A different outfile name should end in *.fsm. The option /dev/null can be everything, its only meaning is to choose the short-example, without an option long-example is chosen. You can load these scripts into Snd too. * README ends here snd-16.1/sndins/samples/0000755000076400007640000000000012004766240013276 5ustar bilbilsnd-16.1/sndins/samples/fmviolin.fth0000755000076400007640000026020612433105741015634 0ustar bilbil#! /usr/bin/env fth \ fmviolin.fth -- CLM fmviolin.clm \ Translator/Author: Michael Scholz \ Created: 04/12/06 17:23:22 \ Changed: 14/11/19 01:00:53 \ A translation of Bill Schottstaedt's clm/fmviolin.clm from Lisp \ into Fth. \ short-example \ long-example #t value *clm-c-version* dl-load sndlib Init_sndlib *clm-c-version* [if] dl-load sndins Init_sndins [else] require clm-ins <'> noop alias freeverb [then] require clm "test-ins-f.snd" to *clm-file-name* #t to *clm-play* #t to *clm-statistics* #t to *clm-verbose* 44100 to *clm-srate* 2 to *clm-channels* 2 to *clm-reverb-channels* #t to *clm-delete-reverb* mus-next to *clm-header-type* mus-bfloat to *clm-sample-type* 1.0 value fmv-fm-index '( 0 0 25 1 75 1 100 0 ) value fmv-amp-env 5.0 value fmv-periodic-vibrato-rate 0.0025 value fmv-periodic-vibrato-amp 16.0 value fmv-random-vibrato-rate 0.005 value fmv-random-vibrato-amp 1000.0 value fmv-noise-freq 0.0 value fmv-noise-amount 10.0 value fmv-ind-noise-freq 0.0 value fmv-ind-noise-amount 20.0 value fmv-amp-noise-freq 0.0 value fmv-amp-noise-amount '( 0 0 100 0 ) value fmv-gliss-env 0.0 value fmv-glissando-amount '( 0 1 25 0.4 75 0.6 100 0 ) value fmv-fm1-env '( 0 1 25 0.4 75 0.6 100 0 ) value fmv-fm2-env '( 0 1 25 0.4 75 0.6 100 0 ) value fmv-fm3-env 1.0 value fmv-fm1-rat 3.0 value fmv-fm2-rat 4.0 value fmv-fm3-rat #f value fmv-fm1-index #f value fmv-fm2-index #f value fmv-fm3-index 0.0 value fmv-base 0.01 value fmv-reverb-amount 0.0 value fmv-degree 1.0 value fmv-distance 'violin value fmv-index-type : restore-fm-violin-defaults ( -- ) 1.0 to fmv-fm-index '( 0 0 25 1 75 1 100 0 ) to fmv-amp-env 5.0 to fmv-periodic-vibrato-rate 0.0025 to fmv-periodic-vibrato-amp 16.0 to fmv-random-vibrato-rate 0.005 to fmv-random-vibrato-amp 1000.0 to fmv-noise-freq 0.0 to fmv-noise-amount 10.0 to fmv-ind-noise-freq 0.0 to fmv-ind-noise-amount 20.0 to fmv-amp-noise-freq 0.0 to fmv-amp-noise-amount '( 0 0 100 0 ) to fmv-gliss-env 0.0 to fmv-glissando-amount '( 0 1 25 0.4 75 0.6 100 0 ) to fmv-fm1-env '( 0 1 25 0.4 75 0.6 100 0 ) to fmv-fm2-env '( 0 1 25 0.4 75 0.6 100 0 ) to fmv-fm3-env 1.0 to fmv-fm1-rat 3.0 to fmv-fm2-rat 4.0 to fmv-fm3-rat #f to fmv-fm1-index #f to fmv-fm2-index #f to fmv-fm3-index 0.0 to fmv-base 0.0 to fmv-degree 1.0 to fmv-distance 0.01 to fmv-reverb-amount 'violin to fmv-index-type ; : old-fm-violin ( start dur freq amp keyword-args -- ) :fm-index fmv-fm-index get-args { fm-index } :amp-env fmv-amp-env get-args { amp-env } :periodic-vibrato-rate fmv-periodic-vibrato-rate get-args { pvrate } :periodic-vibrato-amplitude fmv-periodic-vibrato-amp get-args { pvamp } :random-vibrato-rate fmv-random-vibrato-rate get-args { rvrate } :random-vibrato-amplitude fmv-random-vibrato-amp get-args { rvamp } :noise-freq fmv-noise-freq get-args { noise-freq } :noise-amount fmv-noise-amount get-args { noise-amount } :ind-noise-freq fmv-ind-noise-freq get-args { ind-noise-freq } :ind-noise-amount fmv-ind-noise-amount get-args { ind-noise-amount } :amp-noise-freq fmv-amp-noise-freq get-args { amp-noise-freq } :amp-noise-amount fmv-amp-noise-amount get-args { amp-noise-amount } :gliss-env fmv-gliss-env get-args { gliss-env } :glissando-amount fmv-glissando-amount get-args { gliss-amount } :fm1-env fmv-fm1-env get-args { fm1-env } :fm2-env fmv-fm2-env get-args { fm2-env } :fm3-env fmv-fm3-env get-args { fm3-env } :fm1-rat fmv-fm1-rat get-args { fm1-rat } :fm2-rat fmv-fm2-rat get-args { fm2-rat } :fm3-rat fmv-fm3-rat get-args { fm3-rat } :fm1-index fmv-fm1-index get-args { fm1-index } :fm2-index fmv-fm2-index get-args { fm2-index } :fm3-index fmv-fm3-index get-args { fm3-index } :base fmv-base get-args { base } :degree fmv-degree get-args { degree } :distance fmv-distance get-args { distance } :reverb-amount fmv-reverb-amount get-args { revamount } :index-type fmv-index-type get-args { index-type } { start dur freq amp } start dur freq amp 0.125 f* :fm-index fm-index :amp-env amp-env :periodic-vibrato-rate pvrate :periodic-vibrato-amplitude pvamp :random-vibrato-rate rvrate :random-vibrato-amplitude rvamp :noise-freq noise-freq :noise-amount noise-amount :ind-noise-freq ind-noise-freq :ind-noise-amount ind-noise-amount :amp-noise-freq amp-noise-freq :amp-noise-amount amp-noise-amount :gliss-env gliss-env :glissando-amount gliss-amount :fm1-env fm1-env :fm2-env fm2-env :fm3-env fm3-env :fm1-rat fm1-rat :fm2-rat fm2-rat :fm3-rat fm3-rat :fm1-index fm1-index :fm2-index fm2-index :fm3-index fm3-index :base base :degree degree :distance distance :reverb-amount revamount :index-type index-type fm-violin ; : vln-one-sin ( start dur freq amp keyword-args -- ) :degree 0 get-args drop :noise-amount 0 get-args drop :degree 90.0 random :noise-amount 0.0 old-fm-violin ; : vln-one-sin-ran ( start dur freq amp keyword-args -- ) :degree 0 get-args drop :degree 90.0 random old-fm-violin ; : vln-one-sin-exp ( start dur freq amp keyword-args -- ) :base 0 get-args drop :base 0.03125 vln-one-sin ; : cel-one-sum ( start dur freq amp keyword-args -- ) :degree 0 get-args drop :index-type 0 get-args drop :degree 90.0 random :index-type 'cello old-fm-violin ; : violin-new ( start dur freq amp keyword-args -- ) :fm-index 1.0 get-args { fm-index } :amp-env '( 0 0 221 1 240 0 ) get-args { amp-env } :reverb-amount 0.2 get-args { rev-amt } { start dur freq amp } 6 0 do 1.0 random 0.05 f* i f* start f+ \ start 1.0 random 0.10 f* i f* dur f+ \ dur freq 400.0 f> if 1.0 random 0.02 f* 0.99 f+ else 1.0 random freq 200.0 f> if 0.01 f* 0.995 f+ else 0.002 f* 0.999 f+ then then freq f* \ freq amp \ amp :fm-index fm-index 1.0 random 0.75 f+ f* :amp-env amp-env :reverb-amount rev-amt fm-violin loop ; event: fth-short-example ( -- ) '( 0 0 221 1 240 0 ) { amp-env } '( 0 -1 5 0.25 10 0 100 0.1 ) to fmv-gliss-env 12.0 to fmv-random-vibrato-rate 0.01 to fmv-random-vibrato-amp 0.01 to fmv-glissando-amount 0.002 to fmv-noise-amount 0 8.53 993.323 0.03 :fm-index 0.75 :reverb-amount 0.2 :amp-env amp-env violin-new 5 4.53 5/6 993.323 f* 0.02 :fm-index 0.55 :reverb-amount 0.2 :amp-env amp-env violin-new ;event 0 value *counter* #f value *timer* : test-info { ctime -- } *counter* 1+ to *counter* *timer* stop-timer "\\ %02d: score %3d utime %7.3f\n" '( *counter* ctime *timer* user-time@ ) fth-print ; event: fth-long-example ( -- ) '( 0 0 1 1 99 1 100 0 ) { tap } '( 0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0 ) { metalamp } '( 0 0 75 0.1 90 0.3 97 0.6 100 1 ) { whoosh } '( 0 0 50 1 100 0 ) { mamp } '( 0 0 65 1 100 0 ) { n-amp } 0 { beg } 0 to *counter* make-timer to *timer* beg test-info \ 1, score 0 restore-fm-violin-defaults 0 to fmv-glissando-amount 0.1 to fmv-reverb-amount metalamp to fmv-amp-env 6.718 to fmv-fm1-rat 4.414 to fmv-fm2-rat 5.141 to fmv-fm3-rat beg 0.0000 f+ 1.6 164.5868 0.16 :fm-index 2.1087 vln-one-sin beg 0.0003 f+ 4 164.5868 0.2600 :fm-index 1.5488 vln-one-sin beg 0.0005 f+ 1.2 125.9513 0.2600 :fm-index 2.2999 vln-one-sin beg 0.0005 f+ 2.8 125.9513 0.16 :fm-index 1.6818 vln-one-sin beg 0.0013 f+ 4 24.4994 0.3 :fm-index 2.4557 vln-one-sin beg 0.0033 f+ 3 24.4994 0.3 :fm-index 1.9387 vln-one-sin beg 0.0035 f+ 2.8 24.4994 0.2600 :fm-index 2.3828 vln-one-sin beg 0.0040 f+ 0.8 24.4994 0.16 :fm-index 1.7348 vln-one-sin beg 0.0043 f+ 4 24.4994 0.3 :fm-index 2.0886 vln-one-sin beg 6 + dup to beg test-info \ 2, score 6 2.718 to fmv-fm1-rat 4.414 to fmv-fm2-rat 3.141 to fmv-fm3-rat beg 0.0003 f+ 1.2 88.8854 0.16 :fm-index 2.0711 vln-one-sin beg 0.0003 f+ 4 88.8854 0.2600 :fm-index 2.0225 vln-one-sin beg 0.0005 f+ 1.2 102.7186 0.2600 :fm-index 1.9300 vln-one-sin beg 0.0010 f+ 1.2 32.7025 0.3600 :fm-index 1.9269 vln-one-sin beg 0.0015 f+ 2.8 32.7025 0.2600 :fm-index 2.2153 vln-one-sin beg 0.0023 f+ 2 32.7025 0.2600 :fm-index 2.1968 vln-one-sin beg 0.0023 f+ 4 32.7025 0.3600 :fm-index 1.6091 vln-one-sin beg 0.0025 f+ 2 32.7025 0.2600 :fm-index 2.1766 vln-one-sin beg 0.0035 f+ 1.2 32.7025 0.16 :fm-index 1.5157 vln-one-sin beg 0.0040 f+ 0.8 32.7025 0.16 :fm-index 1.8092 vln-one-sin beg 0.0043 f+ 2 32.7025 0.2600 :fm-index 1.6198 vln-one-sin beg 6 + dup to beg test-info \ 3, score 12 0.2 to fmv-reverb-amount 5.141 to fmv-fm3-rat beg 0.0003 f+ 1.2 177.7708 0.3 :fm-index 1.9631 vln-one-sin beg 0.0003 f+ 4 177.7708 0.3 :fm-index 1.9647 vln-one-sin beg 0.0005 f+ 2.8 336.2471 0.16 :fm-index 2.3977 vln-one-sin beg 0.0008 f+ 1.2 336.2471 0.25 :fm-index 2.4103 vln-one-sin beg 0.0010 f+ 2 65.4050 0.3 :fm-index 1.8419 vln-one-sin beg 0.0033 f+ 2 65.4050 0.3 :fm-index 2.4540 vln-one-sin beg 0.0043 f+ 4 65.4050 0.16 :fm-index 2.2909 vln-one-sin beg 6 + dup to beg test-info \ 4, score 18 0.1 to fmv-reverb-amount beg 0.0003 f+ 1.2 11.1107 0.3 :fm-index 1.8715 vln-one-sin beg 0.0003 f+ 4 11.1107 0.3 :fm-index 2.4590 vln-one-sin beg 0.0005 f+ 2.8 21.0154 0.16 :fm-index 2.3802 vln-one-sin beg 0.0008 f+ 1.2 21.0154 0.25 :fm-index 1.7564 vln-one-sin beg 0.0010 f+ 2 4.0878 0.3 :fm-index 2.2529 vln-one-sin beg 0.0033 f+ 2 4.0878 0.3 :fm-index 1.9693 vln-one-sin beg 0.0043 f+ 4 4.0878 0.16 :fm-index 2.2534 vln-one-sin beg 6 + dup to beg test-info \ 5, score 24 restore-fm-violin-defaults 0.1 to fmv-noise-amount beg 0.0000 f+ 5.4 116.5400 0.25 :fm-index 2.2822 :reverb-amount 0.0280 :amp-env '( 0 0 0.0556 1 4.0937 0.6 9.1414 0.3 24.2845 0.1 100.0 0 ) vln-one-sin-ran beg 0.0100 f+ 5.4 43.6538 0.25 :fm-index 2.0867 :reverb-amount 0.0202 :amp-env '( 0 0 0.0556 1 4.0937 0.6 9.1414 0.3 24.2845 0.1 100.0 0 ) vln-one-sin-ran beg 0.0200 f+ 5.4 130.8100 0.25 :fm-index 1.9652 :reverb-amount 0.0270 :amp-env '( 0 0 0.0556 1 4.0937 0.6 9.1414 0.3 24.2845 0.1 100.0 0 ) vln-one-sin-ran beg 0.0250 f+ 5.4 87.3075 0.25 :fm-index 2.1524 :reverb-amount 0.0260 :amp-env '( 0 0 0.0556 1 4.0937 0.6 9.1414 0.3 24.2845 0.1 100.0 0 ) vln-one-sin-ran beg 0.0300 f+ 4.5 261.6200 0.15 :fm-index 2.1384 :reverb-amount 0.0242 :amp-env '( 0 0 0.0667 1 4.1044 0.6 9.1515 0.3 24.2929 0.1 100 0 ) vln-one-sin-ran beg 0.0300 f+ 4.5 174.6150 0.15 :fm-index 2.1425 :reverb-amount 0.0265 :amp-env '( 0 0 0.0667 1 4.1044 0.6 9.1515 0.3 24.2929 0.1 100 0 ) vln-one-sin-ran beg 0.0300 f+ 4.5 130.8100 0.15 :fm-index 1.9805 :reverb-amount 0.0201 :amp-env '( 0 0 0.0667 1 4.1044 0.6 9.1515 0.3 24.2929 0.1 100 0 ) vln-one-sin-ran beg 0.0350 f+ 4.5 43.6538 0.15 :fm-index 2.4876 :reverb-amount 0.0329 :amp-env '( 0 0 0.0667 1 4.1044 0.6 9.1515 0.3 24.2929 0.1 100 0 ) vln-one-sin-ran beg 0.0400 f+ 3.6 220 0.15 :fm-index 1.8282 :reverb-amount 0.0244 :amp-env '( 0 0 0.0833 1 4.1204 0.6 9.1667 0.3 24.3056 0.1 100.0 0 ) :noise-amount 0.15 vln-one-sin-ran beg 0.0400 f+ 3.6 174.6150 0.15 :fm-index 2.3479 :reverb-amount 0.0200 :amp-env '( 0 0 0.0833 1 4.1204 0.6 9.1667 0.3 24.3056 0.1 100.0 0 ) :noise-amount 0.15 vln-one-sin-ran beg 0.0400 f+ 3.6 523.2400 0.15 :fm-index 1.6424 :reverb-amount 0.0286 :amp-env '( 0 0 0.0833 1 4.1204 0.6 9.1667 0.3 24.3056 0.1 100.0 0 ) :noise-amount 0.15 vln-one-sin-ran beg 0.0450 f+ 3.6 349.2300 0.15 :fm-index 1.6449 :reverb-amount 0.0333 :amp-env '( 0 0 0.0833 1 4.1204 0.6 9.1667 0.3 24.3056 0.1 100.0 0 ) :noise-amount 0.15 vln-one-sin-ran beg 0.0500 f+ 6 699.4600 0.15 :fm-index 1.5570 :reverb-amount 0.13 :amp-env tap vln-one-sin-ran beg 0.0500 f+ 6 1397.9200 0.15 :fm-index 1.5131 :reverb-amount 0.13 :amp-env tap vln-one-sin-ran beg 0.0500 f+ 6 783.9800 0.15 :fm-index 2.2031 :reverb-amount 0.13 :amp-env tap vln-one-sin-ran beg 0.0500 f+ 6 1046.4800 0.15 :fm-index 2.2724 :reverb-amount 0.13 :amp-env tap vln-one-sin-ran beg 0.0600 f+ 9 21.8269 0.15 :fm-index 2.1048 :reverb-amount 0.1 :amp-env tap vln-one-sin-ran beg 0.0600 f+ 8 87.3075 0.15 :fm-index 1.8854 :reverb-amount 0.1 :amp-env tap vln-one-sin-ran beg 0.0600 f+ 7 65.4050 0.15 :fm-index 1.6781 :reverb-amount 0.1 :amp-env tap vln-one-sin-ran beg 0.0600 f+ 8 43.6538 0.15 :fm-index 1.7862 :reverb-amount 0.1 :amp-env tap vln-one-sin-ran beg 0.0700 f+ 6 175.6150 0.15 :fm-index 2.2656 :reverb-amount 0.1 :amp-env tap vln-one-sin-ran beg 0.0700 f+ 6 350.2300 0.15 :fm-index 2.4241 :reverb-amount 0.1 :amp-env tap vln-one-sin-ran beg 0.0700 f+ 6 131.8100 0.15 :fm-index 2.4294 :reverb-amount 0.1 :amp-env tap vln-one-sin-ran beg 0.0700 f+ 6 32.7025 0.15 :fm-index 1.5779 :reverb-amount 0.1 :amp-env tap vln-one-sin-ran beg 0.0800 f+ 6 196.9950 0.15 :fm-index 1.8511 :reverb-amount 0.1 :amp-env tap vln-one-sin-ran beg 0.0800 f+ 6 1047.4800 0.15 :fm-index 2.2148 :reverb-amount 0.1 :amp-env tap vln-one-sin-ran beg 0.0800 f+ 6 831.6200 0.15 :fm-index 1.9913 :reverb-amount 0.1 :amp-env tap vln-one-sin-ran beg 0.2700 f+ 6 784.9800 0.16 :fm-index 2.0693 :reverb-amount 0.1 :amp-env tap vln-one-sin-ran beg 0.2700 f+ 6 64.4050 0.16 :fm-index 1.6920 :reverb-amount 0.1 :amp-env tap vln-one-sin-ran beg 0.2700 f+ 6 208.6550 0.16 :fm-index 2.2597 :reverb-amount 0.1 :amp-env tap vln-one-sin-ran beg 0.2700 f+ 6 43.6538 0.16 :fm-index 2.2522 :reverb-amount 0.1 :amp-env tap vln-one-sin-ran beg 12 + dup to beg test-info \ 6, score 36 restore-fm-violin-defaults beg 0.0000 f+ 1.8 349.2300 0.16 :fm-index 2.1541 :reverb-amount 0.0225 :amp-env '( 0 0 0.1667 1 4.2003 0.6 9.2424 0.3 24.3687 0.1 100 0 ) :noise-amount 0.0500 vln-one-sin-ran beg 0.0100 f+ 2.7 146.8300 0.16 :fm-index 2.3335 :reverb-amount 0.0274 :amp-env '( 0 0 0.1111 1 4.1470 0.6 9.1919 0.3 24.3266 0.1 100.0 0 ) :noise-amount 0.0500 vln-one-sin-ran beg 0.0200 f+ 1.8 880 0.16 :fm-index 2.1910 :reverb-amount 0.0279 :amp-env '( 0 0 0.1667 1 4.2003 0.6 9.2424 0.3 24.3687 0.1 100 0 ) :noise-amount 0.0500 vln-one-sin-ran beg 0.0250 f+ 3.6 73.4150 0.16 :fm-index 2.1410 :reverb-amount 0.0223 :amp-env '( 0 0 0.0833 1 4.1204 0.6 9.1667 0.3 24.3056 0.1 100.0 0 ) :noise-amount 0.0500 vln-one-sin-ran beg 0.0300 f+ 2.7 87.3075 0.16 :fm-index 1.8491 :reverb-amount 0.0217 :amp-env '( 0 0 0.1111 1 4.1470 0.6 9.1919 0.3 24.3266 0.1 100.0 0 ) :noise-amount 0.0010 vln-one-sin-ran beg 0.0300 f+ 2.7 75.5662 0.16 :fm-index 1.9191 :reverb-amount 0.0204 :amp-env '( 0 0 0.1111 1 4.1470 0.6 9.1919 0.3 24.3266 0.1 100.0 0 ) :noise-amount 0.0010 vln-one-sin-ran beg 0.0400 f+ 3.6 52.3432 0.16 :fm-index 1.6090 :reverb-amount 0.0296 :amp-env '( 0 0 0.0833 1 4.1204 0.6 9.1667 0.3 24.3056 0.1 100.0 0 ) :noise-amount 0.0010 vln-one-sin-ran beg 0.0450 f+ 1.8 73.4150 0.16 :fm-index 2.2201 :reverb-amount 0.0221 :amp-env '( 0 0 0.1667 1 4.2003 0.6 9.2424 0.3 24.3687 0.1 100 0 ) :noise-amount 0.0010 vln-one-sin-ran beg 0.0500 f+ 4 116.5400 0.06 :fm-index 2.0230 :reverb-amount 0.1 :amp-env tap :noise-amount 0.0010 vln-one-sin-ran beg 0.0500 f+ 4 97.9975 0.06 :fm-index 1.7284 :reverb-amount 0.1 :amp-env tap :noise-amount 0.0010 vln-one-sin-ran beg 0.0600 f+ 4 36.7075 0.06 :fm-index 1.6845 :reverb-amount 0.1 :amp-env tap :noise-amount 0.0010 vln-one-sin-ran beg 0.0650 f+ 4 97.9975 0.06 :fm-index 2.4616 :reverb-amount 0.1 :amp-env tap :noise-amount 0.0010 vln-one-sin-ran beg 7 + dup to beg test-info \ 7, score 43 beg 0.0000 f+ 1.8 261.6200 0.16 :fm-index 2.2576 :reverb-amount 0.0286 :amp-env '( 0 0 0.1667 1 4.2003 0.6 9.2424 0.3 24.3687 0.1 100 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.0100 f+ 2.7 130.8100 0.16 :fm-index 2.1530 :reverb-amount 0.0330 :amp-env '( 0 0 0.1111 1 4.1470 0.6 9.1919 0.3 24.3266 0.1 100.0 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.0200 f+ 1.8 523.2400 0.16 :fm-index 2.0608 :reverb-amount 0.0235 :amp-env '( 0 0 0.1667 1 4.2003 0.6 9.2424 0.3 24.3687 0.1 100 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.0250 f+ 3.6 65.4050 0.16 :fm-index 2.2203 :reverb-amount 0.0234 :amp-env '( 0 0 0.0833 1 4.1204 0.6 9.1667 0.3 24.3056 0.1 100.0 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.0300 f+ 2.7 65.4050 0.16 :fm-index 1.7089 :reverb-amount 0.0208 :amp-env '( 0 0 0.1111 1 4.1470 0.6 9.1919 0.3 24.3266 0.1 100.0 0 ) :noise-amount 0.0010 vln-one-sin-ran beg 0.0300 f+ 2.7 130.8100 0.16 :fm-index 2.2948 :reverb-amount 0.0269 :amp-env '( 0 0 0.1111 1 4.1470 0.6 9.1919 0.3 24.3266 0.1 100.0 0 ) :noise-amount 0.0010 vln-one-sin-ran beg 0.0400 f+ 3.6 32.7025 0.16 :fm-index 1.7677 :reverb-amount 0.0288 :amp-env '( 0 0 0.0833 1 4.1204 0.6 9.1667 0.3 24.3056 0.1 100.0 0 ) :noise-amount 0.0010 vln-one-sin-ran beg 0.0450 f+ 1.8 32.7025 0.16 :fm-index 1.9030 :reverb-amount 0.0209 :amp-env '( 0 0 0.1667 1 4.2003 0.6 9.2424 0.3 24.3687 0.1 100 0 ) :noise-amount 0.0010 vln-one-sin-ran beg 0.0500 f+ 4 65.4050 0.06 :fm-index 2.2757 :reverb-amount 0.1 :amp-env tap :noise-amount 0.0010 vln-one-sin-ran beg 0.0500 f+ 4 65.4050 0.06 :fm-index 2.2435 :reverb-amount 0.1 :amp-env tap :noise-amount 0.0010 vln-one-sin-ran beg 0.0600 f+ 4 32.7025 0.06 :fm-index 1.9619 :reverb-amount 0.1 :amp-env tap :noise-amount 0.0010 vln-one-sin-ran beg 0.0650 f+ 4 65.4050 0.06 :fm-index 2.0207 :reverb-amount 0.1 :amp-env tap :noise-amount 0.0010 vln-one-sin-ran beg 6 + dup to beg test-info \ 8, score 49 beg 0.0100 f+ 0.9 3135.9200 0.16 :fm-index 2.1204 :reverb-amount 0.0024 :amp-env '( 0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.4950 0.1 100.0 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.0100 f+ 0.45 1567.96 0.16 :fm-index 2.0691 :reverb-amount 0.0025 :amp-env '( 0 0 0.6667 1 4.6801 0.6 9.6970 0.3 24.7475 0.1 100 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.0200 f+ 0.9 6271.8400 0.16 :fm-index 2.2081 :reverb-amount 0.0022 :amp-env '( 0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.4950 0.1 100.0 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.0250 f+ 0.9 783.9800 0.16 :fm-index 1.8719 :reverb-amount 0.0022 :amp-env '( 0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.4950 0.1 100.0 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.0300 f+ 0.27 783.9800 0.16 :fm-index 1.9705 :reverb-amount 0.0020 :amp-env '( 0 0 1.1111 1 5.1066 0.6 10.1010 0.3 25.0842 0.1 100.0 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.0300 f+ 0.63 1567.96 0.16 :fm-index 1.6778 :reverb-amount 0.0021 :amp-env '( 0 0 0.4762 1 4.4974 0.6 9.5238 0.3 24.6032 0.1 100.0 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.0400 f+ 0.9 391.9900 0.16 :fm-index 1.9558 :reverb-amount 0.0023 :amp-env '( 0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.4950 0.1 100.0 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.0450 f+ 0.45 195.9950 0.16 :fm-index 2.1344 :reverb-amount 0.0027 :amp-env '( 0 0 0.6667 1 4.6801 0.6 9.6970 0.3 24.7475 0.1 100 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.050 f+ 2 783.980 0.16 :reverb-amount 0.01 :amp-env tap :noise-amount 0.009 vln-one-sin-ran beg 0.050 f+ 1 1567.960 0.16 :reverb-amount 0.01 :amp-env tap :noise-amount 0.009 vln-one-sin-ran beg 0.060 f+ 2 391.990 0.16 :reverb-amount 0.01 :amp-env tap :noise-amount 0.009 vln-one-sin-ran beg 0.065 f+ 1 783.980 0.16 :reverb-amount 0.01 :amp-env tap :noise-amount 0.009 vln-one-sin-ran beg 0.070 f+ 2 195.995 0.16 :reverb-amount 0.01 :amp-env tap :noise-amount 0.004 vln-one-sin-ran beg 0.070 f+ 1 1567.960 0.16 :reverb-amount 0.01 :amp-env tap :noise-amount 0.004 vln-one-sin-ran beg 0.080 f+ 1 784.980 0.16 :reverb-amount 0.01 :amp-env tap :noise-amount 0.004 vln-one-sin-ran beg 0.085 f+ 2 391.990 0.16 :reverb-amount 0.01 :amp-env tap :noise-amount 0.004 vln-one-sin-ran beg 6 + dup to beg test-info \ 9, score 55 beg 0.0100 f+ 0.9 97.9975 0.1 :fm-index 2.0885 :reverb-amount 0.0031 :amp-env '( 0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.4950 0.1 100.0 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.0100 f+ 1.8 48.9988 0.1 :fm-index 2.2269 :reverb-amount 0.0026 :amp-env '( 0 0 0.1667 1 4.2003 0.6 9.2424 0.3 24.3687 0.1 100 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.0200 f+ 0.9 195.9950 0.1 :fm-index 2.0305 :reverb-amount 0.0032 :amp-env '( 0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.4950 0.1 100.0 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.0250 f+ 0.9 24.4994 0.1 :fm-index 2.4934 :reverb-amount 0.0025 :amp-env '( 0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.4950 0.1 100.0 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.0300 f+ 1.8 97.9975 0.1 :fm-index 2.4039 :reverb-amount 0.0023 :amp-env '( 0 0 0.1667 1 4.2003 0.6 9.2424 0.3 24.3687 0.1 100 0 ) :noise-amount 0.0400 vln-one-sin-ran beg 0.0300 f+ 0.9 195.9950 0.1 :fm-index 1.5159 :reverb-amount 0.0021 :amp-env '( 0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.4950 0.1 100.0 0 ) :noise-amount 0.0400 vln-one-sin-ran beg 0.0300 f+ 0.9 392.9900 0.1 :fm-index 2.2122 :reverb-amount 0.0028 :amp-env '( 0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.4950 0.1 100.0 0 ) :noise-amount 0.0400 vln-one-sin-ran beg 0.0300 f+ 1.8 784.9800 0.1 :fm-index 2.1574 :reverb-amount 0.0020 :amp-env '( 0 0 0.1667 1 4.2003 0.6 9.2424 0.3 24.3687 0.1 100 0 ) :noise-amount 0.0400 vln-one-sin-ran beg 0.0300 f+ 2.7 24.4994 0.1 :fm-index 2.1963 :reverb-amount 0.0031 :amp-env '( 0 0 0.1111 1 4.1470 0.6 9.1919 0.3 24.3266 0.1 100.0 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.0300 f+ 1.8 48.9988 0.1 :fm-index 1.9761 :reverb-amount 0.0032 :amp-env '( 0 0 0.1667 1 4.2003 0.6 9.2424 0.3 24.3687 0.1 100 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.0400 f+ 2.7 12.2497 0.1 :fm-index 1.5088 :reverb-amount 0.0021 :amp-env '( 0 0 0.1111 1 4.1470 0.6 9.1919 0.3 24.3266 0.1 100.0 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.0450 f+ 1.8 6.1248 0.1 :fm-index 1.7384 :reverb-amount 0.0021 :amp-env '( 0 0 0.1667 1 4.2003 0.6 9.2424 0.3 24.3687 0.1 100 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.050 f+ 2 24.4994 0.1 :reverb-amount 0.1 :amp-env tap :noise-amount 0.004 vln-one-sin-ran beg 0.050 f+ 1 48.9988 0.1 :reverb-amount 0.1 :amp-env tap :noise-amount 0.004 vln-one-sin-ran beg 0.060 f+ 2 12.2497 0.1 :reverb-amount 0.1 :amp-env tap :noise-amount 0.004 vln-one-sin-ran beg 0.065 f+ 1 24.4994 0.1 :reverb-amount 0.1 :amp-env tap :noise-amount 0.004 vln-one-sin-ran beg 0.070 f+ 2 6.1248 0.1 :fm-index 1.2474 :reverb-amount 0.1 :amp-env tap :noise-amount 0.004 vln-one-sin-ran beg 0.070 f+ 1 48.9988 0.1 :fm-index 0.7526 :reverb-amount 0.1 :amp-env tap :noise-amount 0.004 vln-one-sin-ran beg 0.080 f+ 1 25.4994 0.1 :fm-index 1.1080 :reverb-amount 0.1 :amp-env tap :noise-amount 0.004 vln-one-sin-ran beg 0.085 f+ 2 12.2497 0.1 :fm-index 1.0859 :reverb-amount 0.1 :amp-env tap :noise-amount 0.004 vln-one-sin-ran beg 0.090 f+ 4 97.9975 0.1 :fm-index 2.4788 :reverb-amount 0.1 :amp-env tap :noise-amount 0.004 vln-one-sin-ran beg 0.090 f+ 3 48.9988 0.1 :fm-index 1.8980 :reverb-amount 0.1 :amp-env tap :noise-amount 0.004 vln-one-sin-ran beg 0.090 f+ 3 25.4994 0.1 :fm-index 2.1151 :reverb-amount 0.1 :amp-env tap :noise-amount 0.004 vln-one-sin-ran beg 0.095 f+ 5 12.2497 0.1 :fm-index 2.3224 :reverb-amount 0.1 :amp-env tap :noise-amount 0.004 vln-one-sin-ran beg 6 + dup to beg test-info \ 10, score 61 beg 0.2100 f+ 0.9 123.4725 0.1 :reverb-amount 0.0031 :amp-env '( 0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.4950 0.1 100.0 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.2100 f+ 1.8 61.7363 0.1 :reverb-amount 0.0023 :amp-env '( 0 0 0.1667 1 4.2003 0.6 9.2424 0.3 24.3687 0.1 100 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.2200 f+ 0.9 246.9450 0.1 :reverb-amount 0.0023 :amp-env '( 0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.4950 0.1 100.0 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.2250 f+ 0.9 30.8681 0.1 :reverb-amount 0.0026 :amp-env '( 0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.4950 0.1 100.0 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.2300 f+ 1.8 123.4725 0.1 :reverb-amount 0.0027 :amp-env '( 0 0 0.1667 1 4.2003 0.6 9.2424 0.3 24.3687 0.1 100 0 ) :noise-amount 0.0400 vln-one-sin-ran beg 0.2300 f+ 0.9 246.9450 0.1 :reverb-amount 0.0026 :amp-env '( 0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.4950 0.1 100.0 0 ) :noise-amount 0.0400 vln-one-sin-ran beg 0.2300 f+ 0.9 494.8900 0.1 :reverb-amount 0.0020 :amp-env '( 0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.4950 0.1 100.0 0 ) :noise-amount 0.0400 vln-one-sin-ran beg 0.2300 f+ 1.8 988.7800 0.1 :reverb-amount 0.0025 :amp-env '( 0 0 0.1667 1 4.2003 0.6 9.2424 0.3 24.3687 0.1 100 0 ) :noise-amount 0.0400 vln-one-sin-ran beg 0.2300 f+ 2.7 30.8681 0.1 :reverb-amount 0.0028 :amp-env '( 0 0 0.1111 1 4.1470 0.6 9.1919 0.3 24.3266 0.1 100.0 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.2300 f+ 1.8 61.7363 0.1 :reverb-amount 0.0023 :amp-env '( 0 0 0.1667 1 4.2003 0.6 9.2424 0.3 24.3687 0.1 100 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.2400 f+ 2.7 15.4341 0.1 :reverb-amount 0.0030 :amp-env '( 0 0 0.1111 1 4.1470 0.6 9.1919 0.3 24.3266 0.1 100.0 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.2450 f+ 1.8 20.5788 0.1 :reverb-amount 0.0023 :amp-env '( 0 0 0.1667 1 4.2003 0.6 9.2424 0.3 24.3687 0.1 100 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.250 f+ 2 30.8681 0.1 :reverb-amount 0.1 :amp-env tap :noise-amount 0.009 vln-one-sin-ran beg 0.250 f+ 1 61.7363 0.1 :reverb-amount 0.1 :amp-env tap :noise-amount 0.009 vln-one-sin-ran beg 0.260 f+ 2 15.4341 0.1 :reverb-amount 0.1 :amp-env tap :noise-amount 0.009 vln-one-sin-ran beg 0.265 f+ 1 30.8681 0.1 :reverb-amount 0.1 :amp-env tap :noise-amount 0.009 vln-one-sin-ran beg 0.271 f+ 2 30.8681 0.1 :reverb-amount 0.1 :amp-env tap :noise-amount 0.004 vln-one-sin-ran beg 0.271 f+ 1 61.7363 0.1 :reverb-amount 0.1 :amp-env tap :noise-amount 0.004 vln-one-sin-ran beg 0.281 f+ 1 31.8681 0.1 :reverb-amount 0.1 :amp-env tap :noise-amount 0.004 vln-one-sin-ran beg 0.286 f+ 2 15.4341 0.1 :reverb-amount 0.1 :amp-env tap :noise-amount 0.004 vln-one-sin-ran beg 8 + dup to beg test-info \ 11, score 69 '( 0 0 1 1 100 0 ) { yup } beg 0.0100 f+ 0.9 3135.9200 0.16 :fm-index 1.7299 :reverb-amount 0.0026 :amp-env '( 0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.4950 0.1 100.0 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.0100 f+ 0.45 1464.6987 0.16 :fm-index 1.9173 :reverb-amount 0.0027 :amp-env '( 0 0 0.6667 1 4.6801 0.6 9.6970 0.3 24.7475 0.1 100 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.0200 f+ 0.9 6714.0048 0.16 :fm-index 2.4604 :reverb-amount 0.0032 :amp-env '( 0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.4950 0.1 100.0 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.0250 f+ 0.9 684.1190 0.16 :fm-index 1.9969 :reverb-amount 0.0021 :amp-env '( 0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.4950 0.1 100.0 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.0300 f+ 0.27 684.1190 0.16 :fm-index 2.0022 :reverb-amount 0.0026 :amp-env '( 0 0 1.1111 1 5.1066 0.6 10.1010 0.3 25.0842 0.1 100.0 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.0300 f+ 0.63 1464.6987 0.16 :fm-index 2.1058 :reverb-amount 0.0027 :amp-env '( 0 0 0.4762 1 4.4974 0.6 9.5238 0.3 24.6032 0.1 100.0 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.0400 f+ 0.9 319.5325 0.16 :fm-index 2.2293 :reverb-amount 0.0029 :amp-env '( 0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.4950 0.1 100.0 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.0450 f+ 0.45 149.2445 0.16 :fm-index 1.5780 :reverb-amount 0.0025 :amp-env '( 0 0 0.6667 1 4.6801 0.6 9.6970 0.3 24.7475 0.1 100 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.050 f+ 1 684.1190 0.16 :reverb-amount 0.01 :amp-env yup :noise-amount 0.009 vln-one-sin-ran beg 0.050 f+ 1 1464.6987 0.16 :reverb-amount 0.01 :amp-env yup :noise-amount 0.009 vln-one-sin-ran beg 0.060 f+ 1 319.5325 0.16 :reverb-amount 0.01 :amp-env yup :noise-amount 0.009 vln-one-sin-ran beg 0.065 f+ 1 684.1190 0.16 :reverb-amount 0.01 :amp-env yup :noise-amount 0.009 vln-one-sin-ran beg 0.070 f+ 1 149.2445 0.16 :reverb-amount 0.01 :amp-env yup :noise-amount 0.004 vln-one-sin-ran beg 0.070 f+ 1 1464.6987 0.16 :reverb-amount 0.01 :amp-env yup :noise-amount 0.004 vln-one-sin-ran beg 0.080 f+ 1 561.6022 0.16 :reverb-amount 0.01 :amp-env yup :noise-amount 0.004 vln-one-sin-ran beg 0.085 f+ 1 319.5325 0.16 :reverb-amount 0.01 :amp-env yup :noise-amount 0.004 vln-one-sin-ran beg 3 + dup to beg test-info \ 12, score 72 beg 0.0100 f+ 0.9 3135.9200 0.16 :fm-index 1.6329 :reverb-amount 0.0031 :amp-env '( 0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.4950 0.1 100.0 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.0100 f+ 0.45 1810.5774 0.16 :fm-index 1.8298 :reverb-amount 0.0031 :amp-env '( 0 0 0.6667 1 4.6801 0.6 9.6970 0.3 24.7475 0.1 100 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.0200 f+ 0.9 5431.4135 0.16 :fm-index 2.1640 :reverb-amount 0.0022 :amp-env '( 0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.4950 0.1 100.0 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.0250 f+ 0.9 1045.3680 0.16 :fm-index 1.6971 :reverb-amount 0.0032 :amp-env '( 0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.4950 0.1 100.0 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.0300 f+ 0.27 1045.3680 0.16 :fm-index 2.4855 :reverb-amount 0.0028 :amp-env '( 0 0 1.1111 1 5.1066 0.6 10.1010 0.3 25.0842 0.1 100.0 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.0300 f+ 0.63 1810.5774 0.16 :fm-index 2.1604 :reverb-amount 0.0020 :amp-env '( 0 0 0.4762 1 4.4974 0.6 9.5238 0.3 24.6032 0.1 100.0 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.0400 f+ 0.9 603.5612 0.16 :fm-index 2.4204 :reverb-amount 0.0031 :amp-env '( 0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.4950 0.1 100.0 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.0450 f+ 0.4500 348.4765 0.16 :fm-index 2.3918 :reverb-amount 0.0026 :amp-env '( 0 0 0.6667 1 4.6801 0.6 9.6970 0.3 24.7475 0.1 100 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.0460 f+ 0.9 201.1989 0.16 :fm-index 1.5205 :reverb-amount 0.0024 :amp-env '( 0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.4950 0.1 100.0 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.0460 f+ 0.9 116.1656 0.16 :fm-index 2.3049 :reverb-amount 0.0028 :amp-env '( 0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.4950 0.1 100.0 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.0500 f+ 0.9 3135.9200 0.16 :fm-index 2.4363 :reverb-amount 0.0021 :amp-env '( 0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.4950 0.1 100.0 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.0500 f+ 0.45 1464.6987 0.16 :fm-index 2.3865 :reverb-amount 0.0027 :amp-env '( 0 0 0.6667 1 4.6801 0.6 9.6970 0.3 24.7475 0.1 100 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.0600 f+ 0.9 6714.0048 0.16 :fm-index 1.7354 :reverb-amount 0.0021 :amp-env '( 0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.4950 0.1 100.0 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.0650 f+ 0.9 684.1190 0.16 :fm-index 1.8282 :reverb-amount 0.0025 :amp-env '( 0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.4950 0.1 100.0 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.0700 f+ 0.2700 684.1190 0.16 :fm-index 2.3923 :reverb-amount 0.0025 :amp-env '( 0 0 1.1111 1 5.1066 0.6 10.1010 0.3 25.0842 0.1 100.0 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.0700 f+ 0.63 1464.6987 0.16 :fm-index 2.2789 :reverb-amount 0.0028 :amp-env '( 0 0 0.4762 1 4.4974 0.6 9.5238 0.3 24.6032 0.1 100.0 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.0800 f+ 0.9 319.5325 0.16 :fm-index 1.5438 :reverb-amount 0.0027 :amp-env '( 0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.4950 0.1 100.0 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.0850 f+ 0.4500 149.2445 0.16 :fm-index 2.4210 :reverb-amount 0.0028 :amp-env '( 0 0 0.6667 1 4.6801 0.6 9.6970 0.3 24.7475 0.1 100 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.0860 f+ 0.9 69.7078 0.16 :fm-index 2.0288 :reverb-amount 0.0029 :amp-env '( 0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.4950 0.1 100.0 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 0.0860 f+ 0.9 32.5585 0.16 :fm-index 1.8254 :reverb-amount 0.0028 :amp-env '( 0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.4950 0.1 100.0 0 ) :noise-amount 0.0100 vln-one-sin-ran beg 3 + dup to beg test-info \ 13, score 75 0 to fmv-reverb-amount 0.01 to fmv-noise-amount beg 0.0500 f+ 0.9 3135.9200 0.16 :fm-index 1.7334 :amp-env '( 0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.4950 0.1 100.0 0 ) vln-one-sin-ran beg 0.0500 f+ 0.45 1810.5774 0.16 :fm-index 2.3629 :amp-env '( 0 0 0.6667 1 4.6801 0.6 9.6970 0.3 24.7475 0.1 100 0 ) vln-one-sin-ran beg 0.0600 f+ 0.9 5431.4135 0.16 :fm-index 2.2744 :amp-env '( 0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.4950 0.1 100.0 0 ) vln-one-sin-ran beg 0.0650 f+ 0.9 1045.3680 0.16 :fm-index 1.8722 :amp-env '( 0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.4950 0.1 100.0 0 ) vln-one-sin-ran beg 0.1100 f+ 0.27 1045.3680 0.16 :fm-index 2.3139 :amp-env '( 0 0 1.1111 1 5.1066 0.6 10.101 0.3 25.0842 0.1 100.0 0 ) vln-one-sin-ran beg 0.1100 f+ 0.63 1810.5774 0.16 :fm-index 1.6216 :amp-env '( 0 0 0.4762 1 4.4974 0.6 9.5238 0.3 24.6032 0.1 100.0 0 ) vln-one-sin-ran beg 0.1200 f+ 0.9 603.5612 0.16 :fm-index 1.5308 :amp-env '( 0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.4950 0.1 100.0 0 ) vln-one-sin-ran beg 0.1650 f+ 0.45 348.4765 0.16 :fm-index 2.0346 :amp-env '( 0 0 0.6667 1 4.6801 0.6 9.6970 0.3 24.7475 0.1 100 0 ) vln-one-sin-ran beg 0.1660 f+ 0.9 201.1989 0.16 :fm-index 1.8176 :amp-env '( 0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.4950 0.1 100.0 0 ) vln-one-sin-ran beg 0.1660 f+ 0.9 116.1656 0.16 :fm-index 1.7145 :amp-env '( 0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.4950 0.1 100.0 0 ) vln-one-sin-ran beg 0.1700 f+ 0.9 3135.9200 0.16 :fm-index 2.4459 :amp-env '( 0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.4950 0.1 100.0 0 ) vln-one-sin-ran beg 0.1700 f+ 0.45 1464.6987 0.16 :fm-index 2.4644 :amp-env '( 0 0 0.6667 1 4.6801 0.6 9.6970 0.3 24.7475 0.1 100 0 ) vln-one-sin-ran beg 0.1800 f+ 0.9 6714.0048 0.16 :fm-index 1.9985 :amp-env '( 0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.4950 0.1 100.0 0 ) vln-one-sin-ran beg 0.1850 f+ 0.9 684.1190 0.16 :fm-index 2.4542 :amp-env '( 0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.4950 0.1 100.0 0 ) vln-one-sin-ran beg 0.2900 f+ 0.27 684.1190 0.16 :fm-index 2.3391 :amp-env '( 0 0 1.1111 1 5.1066 0.6 10.101 0.3 25.0842 0.1 100.0 0 ) vln-one-sin-ran beg 0.2900 f+ 0.63 1464.6987 0.16 :fm-index 1.5138 :amp-env '( 0 0 0.4762 1 4.4974 0.6 9.5238 0.3 24.6032 0.1 100.0 0 ) vln-one-sin-ran beg 0.3 f+ 0.9 319.5325 0.16 :fm-index 1.5440 :amp-env '( 0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.4950 0.1 100.0 0 ) vln-one-sin-ran beg 0.3050 f+ 0.45 149.2445 0.16 :fm-index 2.2283 :amp-env '( 0 0 0.6667 1 4.6801 0.6 9.6970 0.3 24.7475 0.1 100 0 ) vln-one-sin-ran beg 0.3060 f+ 0.9 69.7078 0.16 :fm-index 1.9498 :amp-env '( 0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.4950 0.1 100.0 0 ) vln-one-sin-ran beg 0.3060 f+ 0.9 32.5585 0.16 :fm-index 2.2943 :amp-env '( 0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.4950 0.1 100.0 0 ) vln-one-sin-ran beg 3 + dup to beg test-info \ 14, score 78 restore-fm-violin-defaults metalamp to fmv-amp-env 0 to fmv-glissando-amount 0.01 to fmv-reverb-amount 2.718 to fmv-fm1-rat 1.414 to fmv-fm2-rat 3.141 to fmv-fm3-rat beg 0.2600 f+ 1.2 355.5416 0.16 :fm-index 2.0375 vln-one-sin beg 0.2600 f+ 1.5 354.8319 0.16 :fm-index 1.8744 vln-one-sin beg 0.2603 f+ 0.9 356.2527 0.16 :fm-index 1.8743 vln-one-sin beg 0.2605 f+ 0.9 409.2356 0.16 :fm-index 2.0808 vln-one-sin beg 0.2605 f+ 2.1 410.0541 0.16 :fm-index 1.9219 vln-one-sin beg 0.2608 f+ 1.2 130.8100 0.16 :fm-index 1.5746 vln-one-sin beg 0.2613 f+ 3 130.2883 0.16 :fm-index 2.3771 vln-one-sin beg 0.2615 f+ 0.9 130.2883 0.16 :fm-index 1.7765 vln-one-sin beg 0.2615 f+ 2.1 130.5489 0.26 :fm-index 1.6485 vln-one-sin beg 0.2625 f+ 2 130.8100 0.16 :fm-index 2.1416 vln-one-sin beg 0.2633 f+ 2 130.5488 0.16 :fm-index 2.0883 vln-one-sin beg 4 + dup to beg test-info \ 15, score 82 '( 0 0 0.5 1 5 1 10 0.5 15 0.25 35 0.1 100 0 ) to fmv-amp-env 0.0001 to fmv-noise-amount 0.01 to fmv-reverb-amount beg 0.2605 f+ 0.8 523.2400 0.16 :fm-index 2.3056 vln-one-sin-ran beg 0.2605 f+ 1 247.1611 0.16 :fm-index 1.6308 vln-one-sin-ran beg 0.2610 f+ 0.6 1107.6991 0.16 :fm-index 1.9364 vln-one-sin-ran beg 0.2613 f+ 2 116.7506 0.16 :fm-index 2.3740 vln-one-sin-ran beg 0.2615 f+ 0.6 116.7506 0.16 :fm-index 1.8374 vln-one-sin-ran beg 0.2615 f+ 1.4 247.1611 0.16 :fm-index 1.7250 vln-one-sin-ran beg 0.2620 f+ 0.6 55.1491 0.16 :fm-index 1.5495 vln-one-sin-ran beg 0.2623 f+ 1 26.0506 0.16 :fm-index 1.7235 vln-one-sin-ran beg 0.2623 f+ 2 12.3054 0.16 :fm-index 1.8818 vln-one-sin-ran beg 0.2623 f+ 2 5.8127 0.16 :fm-index 1.9537 vln-one-sin-ran beg 0.2625 f+ 2 523.2400 0.16 :fm-index 2.1593 vln-one-sin-ran beg 0.2625 f+ 1 256.2390 0.16 :fm-index 1.9851 vln-one-sin-ran beg 0.2630 f+ 2 1068.4561 0.16 :fm-index 1.8015 vln-one-sin-ran beg 0.2633 f+ 2 125.4843 0.16 :fm-index 1.6161 vln-one-sin-ran beg 0.2635 f+ 0.6 125.4843 0.16 :fm-index 2.2767 vln-one-sin-ran beg 0.2635 f+ 1.4 256.2390 0.16 :fm-index 2.0835 vln-one-sin-ran beg 0.2640 f+ 0.4 61.4517 0.16 :fm-index 1.5310 vln-one-sin-ran beg 0.2643 f+ 1 30.0939 0.16 :fm-index 1.5803 vln-one-sin-ran beg 0.2643 f+ 2 14.7374 0.16 :fm-index 1.9586 vln-one-sin-ran beg 0.2643 f+ 2 7.2172 0.16 :fm-index 1.7270 vln-one-sin-ran beg 0.2645 f+ 6 28.4710 0.16 :fm-index 1.5983 vln-one-sin-ran beg 0.2648 f+ 10 25.6239 0.16 :fm-index 1.7285 vln-one-sin-ran beg 0.2648 f+ 8 21.3532 0.16 :fm-index 1.7955 vln-one-sin-ran beg 0.2648 f+ 8 17.0826 0.16 :fm-index 2.0866 vln-one-sin-ran beg 4 + dup to beg test-info \ 16, score 86 0.001 to fmv-reverb-amount 0.004 to fmv-noise-amount 3.141 to fmv-fm1-rat 1.414 to fmv-fm2-rat 2.718 to fmv-fm3-rat beg 0.2600 f+ 1.6 1643.4968 0.16 :fm-index 2.1104 vln-one-sin-ran beg 0.2600 f+ 2 1643.4968 0.16 :fm-index 1.5191 vln-one-sin-ran beg 0.2603 f+ 1.2 1643.4968 0.16 :fm-index 2.0478 vln-one-sin-ran beg 0.2603 f+ 4 1643.4968 0.16 :fm-index 2.0473 vln-one-sin-ran beg 0.2605 f+ 1.2 1422.1663 0.16 :fm-index 1.9845 vln-one-sin-ran beg 0.2605 f+ 2.8 1422.1663 0.16 :fm-index 2.0429 vln-one-sin-ran beg 0.2605 f+ 1.2 1422.1663 0.16 :fm-index 1.6184 vln-one-sin-ran beg 0.2608 f+ 1.6 523.2400 0.16 :fm-index 2.3908 vln-one-sin-ran beg 0.2608 f+ 2 523.2400 0.16 :fm-index 1.6733 vln-one-sin-ran beg 0.2610 f+ 1.2 523.2400 0.16 :fm-index 2.0431 vln-one-sin-ran beg 0.2610 f+ 4 523.2400 0.16 :fm-index 1.7430 vln-one-sin-ran beg 0.2613 f+ 1.2 523.2400 0.16 :fm-index 2.2030 vln-one-sin-ran beg 0.2613 f+ 2.8 523.2400 0.16 :fm-index 2.0149 vln-one-sin-ran beg 0.2615 f+ 1.2 523.2400 0.16 :fm-index 2.2310 vln-one-sin-ran beg 0.2615 f+ 2 523.2400 0.16 :fm-index 2.1625 vln-one-sin-ran beg 0.2618 f+ 4 523.2400 0.16 :fm-index 2.0000 vln-one-sin-ran beg 0.2618 f+ 4 523.2400 0.16 :fm-index 2.2034 vln-one-sin-ran beg 0.2620 f+ 3 523.2400 0.16 :fm-index 2.0186 vln-one-sin-ran beg 0.2620 f+ 1.5 523.2400 0.16 :fm-index 2.1373 vln-one-sin-ran beg 0.2623 f+ 3 523.2400 0.16 :fm-index 1.9046 vln-one-sin-ran beg 0.2623 f+ 3 523.2400 0.16 :fm-index 2.1834 vln-one-sin-ran beg 0.2625 f+ 1.2 523.2400 0.16 :fm-index 1.8266 vln-one-sin-ran beg 0.2625 f+ 2.8 523.2400 0.16 :fm-index 1.5937 vln-one-sin-ran beg 0.2628 f+ 0.8 523.2400 0.16 :fm-index 1.9762 vln-one-sin-ran beg 0.2628 f+ 2 523.2400 0.16 :fm-index 1.8954 vln-one-sin-ran beg 0.2630 f+ 4 523.2400 0.16 :fm-index 2.3302 vln-one-sin-ran beg 0.2630 f+ 4 523.2400 0.16 :fm-index 2.4949 vln-one-sin-ran beg 4 + dup to beg test-info \ 17, score 90 3.414 to fmv-fm1-rat 1.414 to fmv-fm2-rat 2.718 to fmv-fm3-rat beg 0.2600 f+ 1.6 821.7484 0.16 :fm-index 2.4793 vln-one-sin-ran beg 0.2600 f+ 2 821.7484 0.16 :fm-index 2.4789 vln-one-sin-ran beg 0.2603 f+ 1.2 821.7484 0.16 :fm-index 2.0827 vln-one-sin-ran beg 0.2603 f+ 4 821.7484 0.16 :fm-index 2.4769 vln-one-sin-ran beg 0.2605 f+ 1.2 711.0832 0.16 :fm-index 2.4094 vln-one-sin-ran beg 0.2605 f+ 2.8 711.0832 0.16 :fm-index 2.4031 vln-one-sin-ran beg 0.2605 f+ 1.2 711.0832 0.16 :fm-index 2.1428 vln-one-sin-ran beg 0.2608 f+ 1.6 261.6200 0.16 :fm-index 2.3129 vln-one-sin-ran beg 0.2608 f+ 2 261.6200 0.16 :fm-index 2.3488 vln-one-sin-ran beg 0.2610 f+ 1.2 261.6200 0.16 :fm-index 2.1466 vln-one-sin-ran beg 0.2610 f+ 4 261.6200 0.16 :fm-index 1.6938 vln-one-sin-ran beg 0.2613 f+ 1.2 261.6200 0.16 :fm-index 2.1287 vln-one-sin-ran beg 0.2613 f+ 2.8 261.6200 0.16 :fm-index 2.1917 vln-one-sin-ran beg 0.2615 f+ 1.2 261.6200 0.16 :fm-index 2.3583 vln-one-sin-ran beg 0.2615 f+ 2 261.6200 0.16 :fm-index 1.8368 vln-one-sin-ran beg 0.2618 f+ 4 261.6200 0.16 :fm-index 1.5107 vln-one-sin-ran beg 0.2618 f+ 4 261.6200 0.16 :fm-index 1.6218 vln-one-sin-ran beg 0.2620 f+ 3 261.6200 0.16 :fm-index 1.9041 vln-one-sin-ran beg 0.2620 f+ 1.5 261.6200 0.16 :fm-index 1.5748 vln-one-sin-ran beg 0.2623 f+ 3 261.6200 0.16 :fm-index 1.9339 vln-one-sin-ran beg 0.2623 f+ 3 261.6200 0.16 :fm-index 2.0489 vln-one-sin-ran beg 0.2625 f+ 1.2 261.6200 0.16 :fm-index 2.0888 vln-one-sin-ran beg 0.2625 f+ 2.8 261.6200 0.16 :fm-index 1.7306 vln-one-sin-ran beg 0.2628 f+ 0.8 261.6200 0.16 :fm-index 2.3257 vln-one-sin-ran beg 0.2628 f+ 2 261.6200 0.16 :fm-index 2.4755 vln-one-sin-ran beg 0.2630 f+ 4 261.6200 0.16 :fm-index 1.9459 vln-one-sin-ran beg 0.2630 f+ 4 261.6200 0.16 :fm-index 1.5782 vln-one-sin-ran beg 4 + dup to beg test-info \ 18, score 94 3.414 to fmv-fm1-rat 1.414 to fmv-fm2-rat 2.718 to fmv-fm3-rat beg 0.2600 f+ 1.6 3286.9937 0.16 :fm-index 1.6655 vln-one-sin-ran beg 0.2600 f+ 2 3286.9937 0.16 :fm-index 1.9356 vln-one-sin-ran beg 0.2603 f+ 1.2 3286.9937 0.16 :fm-index 1.5665 vln-one-sin-ran beg 0.2603 f+ 4 3286.9937 0.16 :fm-index 1.6701 vln-one-sin-ran beg 0.2605 f+ 1.2 2844.3326 0.16 :fm-index 2.3273 vln-one-sin-ran beg 0.2605 f+ 2.8 2844.3326 0.16 :fm-index 1.5520 vln-one-sin-ran beg 0.2605 f+ 1.2 2844.3326 0.16 :fm-index 2.4104 vln-one-sin-ran beg 0.2608 f+ 1.6 1046.4800 0.16 :fm-index 2.1075 vln-one-sin-ran beg 0.2608 f+ 2 1046.4800 0.16 :fm-index 1.7004 vln-one-sin-ran beg 0.2610 f+ 1.2 1046.4800 0.16 :fm-index 1.6502 vln-one-sin-ran beg 0.2610 f+ 4 1046.4800 0.16 :fm-index 2.4591 vln-one-sin-ran beg 0.2613 f+ 1.2 1046.4800 0.16 :fm-index 2.1491 vln-one-sin-ran beg 0.2613 f+ 2.8 1046.4800 0.16 :fm-index 2.1594 vln-one-sin-ran beg 0.2615 f+ 1.2 1046.4800 0.16 :fm-index 2.4783 vln-one-sin-ran beg 0.2615 f+ 2 1046.4800 0.16 :fm-index 2.2080 vln-one-sin-ran beg 0.2618 f+ 4 1046.4800 0.16 :fm-index 1.5844 vln-one-sin-ran beg 0.2618 f+ 4 1046.4800 0.16 :fm-index 1.5440 vln-one-sin-ran beg 0.2620 f+ 3 1046.4800 0.16 :fm-index 1.9857 vln-one-sin-ran beg 0.2620 f+ 1.5 1046.4800 0.16 :fm-index 1.5165 vln-one-sin-ran beg 0.2623 f+ 3 1046.4800 0.16 :fm-index 1.8309 vln-one-sin-ran beg 0.2623 f+ 3 1046.4800 0.16 :fm-index 2.1236 vln-one-sin-ran beg 0.2625 f+ 1.2 1046.4800 0.1 :fm-index 2.4074 vln-one-sin-ran beg 0.2625 f+ 2.8 1046.4800 0.1 :fm-index 1.6315 vln-one-sin-ran beg 0.2628 f+ 0.8 1046.4800 0.1 :fm-index 1.8061 vln-one-sin-ran beg 0.2628 f+ 2 1046.4800 0.1 :fm-index 2.3664 vln-one-sin-ran beg 0.2630 f+ 4 1046.4800 0.1 :fm-index 2.2490 vln-one-sin-ran beg 0.2630 f+ 4 1046.4800 0.1 :fm-index 2.4081 vln-one-sin-ran beg 4 + dup to beg test-info \ 19, score 98 0.01 to fmv-reverb-amount beg 0.2600 f+ 1.6 1643.4968 0.16 :fm-index 1.9284 vln-one-sin-ran beg 0.2600 f+ 2 1643.4968 0.16 :fm-index 2.2171 vln-one-sin-ran beg 0.2603 f+ 1.2 1643.4968 0.16 :fm-index 2.2272 vln-one-sin-ran beg 0.2603 f+ 4 1643.4968 0.16 :fm-index 1.5677 vln-one-sin-ran beg 0.2605 f+ 1.2 1422.1663 0.16 :fm-index 2.0476 vln-one-sin-ran beg 0.2605 f+ 2.8 1422.1663 0.16 :fm-index 2.3289 vln-one-sin-ran beg 0.2605 f+ 1.2 1422.1663 0.16 :fm-index 2.0269 vln-one-sin-ran beg 0.2608 f+ 1.6 523.2400 0.16 :fm-index 1.7767 vln-one-sin-ran beg 0.2608 f+ 2 523.2400 0.16 :fm-index 1.8117 vln-one-sin-ran beg 0.2610 f+ 1.2 523.2400 0.16 :fm-index 1.5694 vln-one-sin-ran beg 0.2610 f+ 4 523.2400 0.16 :fm-index 1.6869 vln-one-sin-ran beg 0.2613 f+ 1.2 523.2400 0.16 :fm-index 1.9340 vln-one-sin-ran beg 0.2613 f+ 2.8 523.2400 0.16 :fm-index 2.3986 vln-one-sin-ran beg 0.2615 f+ 1.2 523.2400 0.16 :fm-index 2.4593 vln-one-sin-ran beg 0.2615 f+ 2 523.2400 0.16 :fm-index 2.3430 vln-one-sin-ran beg 0.2618 f+ 4 523.2400 0.16 :fm-index 2.2650 vln-one-sin-ran beg 0.2618 f+ 4 523.2400 0.16 :fm-index 2.3015 vln-one-sin-ran beg 0.2620 f+ 3 523.2400 0.16 :fm-index 1.9909 vln-one-sin-ran beg 0.2620 f+ 1.5 523.2400 0.16 :fm-index 2.3916 vln-one-sin-ran beg 0.2623 f+ 3 523.2400 0.16 :fm-index 2.0401 vln-one-sin-ran beg 0.2623 f+ 3 523.2400 0.16 :fm-index 1.8484 vln-one-sin-ran beg 0.2625 f+ 1.2 523.2400 0.16 :fm-index 2.3138 vln-one-sin-ran beg 0.2625 f+ 2.8 523.2400 0.16 :fm-index 1.6295 vln-one-sin-ran beg 0.2628 f+ 0.8 523.2400 0.16 :fm-index 2.2344 vln-one-sin-ran beg 0.2628 f+ 2 523.2400 0.16 :fm-index 1.8423 vln-one-sin-ran beg 0.2630 f+ 4 523.2400 0.16 :fm-index 2.2086 vln-one-sin-ran beg 0.2630 f+ 4 523.2400 0.16 :fm-index 2.3130 vln-one-sin-ran beg 4 + dup to beg test-info \ 20, score 102 0.0001 to fmv-noise-amount 0.01 to fmv-reverb-amount 2.718 to fmv-fm1-rat 1.141 to fmv-fm2-rat 3.141 to fmv-fm3-rat beg 0.2605 f+ 0.8 523.2400 0.16 :fm-index 2.0123 vln-one-sin-ran beg 0.2605 f+ 1 493.8728 0.16 :fm-index 2.1176 vln-one-sin-ran beg 0.2610 f+ 0.6 554.3535 0.16 :fm-index 1.9163 vln-one-sin-ran beg 0.2613 f+ 2 466.1539 0.16 :fm-index 1.5048 vln-one-sin-ran beg 0.2615 f+ 0.6 466.1539 0.16 :fm-index 1.5242 vln-one-sin-ran beg 0.2615 f+ 1.4 493.8728 0.16 :fm-index 1.9509 vln-one-sin-ran beg 0.2620 f+ 0.6 439.9907 0.16 :fm-index 2.2131 vln-one-sin-ran beg 0.2623 f+ 1 415.2959 0.16 :fm-index 1.7326 vln-one-sin-ran beg 0.2623 f+ 2 391.9871 0.16 :fm-index 1.9936 vln-one-sin-ran beg 0.2623 f+ 2 369.9866 0.16 :fm-index 2.1103 vln-one-sin-ran beg 0.2625 f+ 2 523.2400 0.16 :fm-index 1.6206 vln-one-sin-ran beg 0.2625 f+ 1 522.7173 0.16 :fm-index 1.8598 vln-one-sin-ran beg 0.2630 f+ 2 523.7632 0.16 :fm-index 1.8015 vln-one-sin-ran beg 0.2633 f+ 2 522.1951 0.16 :fm-index 2.3575 vln-one-sin-ran beg 0.2635 f+ 0.6 522.1951 0.16 :fm-index 1.5010 vln-one-sin-ran beg 0.2635 f+ 1.4 522.7173 0.16 :fm-index 2.4075 vln-one-sin-ran beg 0.2640 f+ 0.4 521.6734 0.16 :fm-index 2.0721 vln-one-sin-ran beg 0.2643 f+ 1 521.1523 0.16 :fm-index 2.0433 vln-one-sin-ran beg 0.2643 f+ 2 520.6316 0.16 :fm-index 1.9788 vln-one-sin-ran beg 0.2643 f+ 2 520.1115 0.16 :fm-index 1.6770 vln-one-sin-ran beg 8 + dup to beg test-info \ 21, score 110 0.004 to fmv-noise-amount beg 0.2600 f+ 0.8 1046.4800 0.16 :fm-index 1.5610 vln-one-sin-ran beg 0.2600 f+ 1 1044.3912 0.16 :fm-index 2.3514 vln-one-sin-ran beg 0.2603 f+ 0.6 1048.5730 0.16 :fm-index 1.9958 vln-one-sin-ran beg 0.2603 f+ 2 1042.3066 0.16 :fm-index 1.9654 vln-one-sin-ran beg 0.2605 f+ 0.6 1042.3066 0.16 :fm-index 1.5285 vln-one-sin-ran beg 0.2605 f+ 1.4 1044.3912 0.16 :fm-index 1.8881 vln-one-sin-ran beg 0.2608 f+ 0.6 1040.2262 0.16 :fm-index 1.8682 vln-one-sin-ran beg 0.2608 f+ 0.8 523.2400 0.16 :fm-index 1.8296 vln-one-sin-ran beg 0.2610 f+ 1 522.1956 0.16 :fm-index 2.1899 vln-one-sin-ran beg 0.2610 f+ 0.6 524.2865 0.16 :fm-index 1.9614 vln-one-sin-ran beg 0.2613 f+ 2 521.1533 0.16 :fm-index 1.7483 vln-one-sin-ran beg 0.2615 f+ 0.6 521.1533 0.16 :fm-index 1.8717 vln-one-sin-ran beg 0.2615 f+ 1.4 522.1956 0.16 :fm-index 1.5619 vln-one-sin-ran beg 0.2620 f+ 0.6 520.1131 0.16 :fm-index 2.4331 vln-one-sin-ran beg 0.2623 f+ 1 519.0749 0.16 :fm-index 2.4153 vln-one-sin-ran beg 0.2623 f+ 2 518.0388 0.16 :fm-index 1.5477 vln-one-sin-ran beg 0.2623 f+ 2 517.0048 0.16 :fm-index 1.9956 vln-one-sin-ran beg 0.2625 f+ 2 523.2400 0.16 :fm-index 1.8111 vln-one-sin-ran beg 0.2625 f+ 1 522.7173 0.16 :fm-index 2.4820 vln-one-sin-ran beg 0.2630 f+ 2 523.7632 0.16 :fm-index 1.5744 vln-one-sin-ran beg 0.2633 f+ 2 522.1951 0.16 :fm-index 1.9950 vln-one-sin-ran beg 0.2635 f+ 0.6 522.1951 0.16 :fm-index 1.9792 vln-one-sin-ran beg 0.2635 f+ 1.4 522.7173 0.16 :fm-index 1.7415 vln-one-sin-ran beg 0.2640 f+ 0.4 521.6734 0.16 :fm-index 2.0884 vln-one-sin-ran beg 0.2643 f+ 1 521.1523 0.16 :fm-index 2.3605 vln-one-sin-ran beg 0.2643 f+ 2 520.6316 0.16 :fm-index 1.7817 vln-one-sin-ran beg 0.2643 f+ 2 520.1115 0.16 :fm-index 2.0283 vln-one-sin-ran beg 4 + dup to beg test-info \ 22, score 114 0.1 to fmv-reverb-amount 0 to fmv-glissando-amount 2.718 to fmv-fm1-rat 1.414 to fmv-fm2-rat 3.141 to fmv-fm3-rat beg 0.2600 f+ 1.6 177.7708 0.16 :fm-index 1.6447 vln-one-sin-ran beg 0.2600 f+ 2 177.7708 0.16 :fm-index 2.4875 vln-one-sin-ran beg 0.2603 f+ 1.2 177.7708 0.16 :fm-index 1.6126 vln-one-sin-ran beg 0.2603 f+ 4 177.7708 0.16 :fm-index 2.3122 vln-one-sin-ran beg 0.2605 f+ 1.2 205.4371 0.16 :fm-index 2.4116 vln-one-sin-ran beg 0.2605 f+ 2.8 205.4371 0.16 :fm-index 1.5337 vln-one-sin-ran beg 0.2608 f+ 1.2 205.4371 0.16 :fm-index 2.0307 vln-one-sin-ran beg 0.2608 f+ 1.6 65.4050 0.16 :fm-index 2.2341 vln-one-sin-ran beg 0.2610 f+ 2 65.4050 0.16 :fm-index 2.4683 vln-one-sin-ran beg 0.2610 f+ 1.2 65.4050 0.16 :fm-index 2.0643 vln-one-sin-ran beg 0.2613 f+ 4 65.4050 0.16 :fm-index 2.1925 vln-one-sin-ran beg 0.2615 f+ 1.2 65.4050 0.16 :fm-index 2.1325 vln-one-sin-ran beg 0.2615 f+ 2.8 65.4050 0.16 :fm-index 1.5847 vln-one-sin-ran beg 0.2620 f+ 1.2 65.4050 0.16 :fm-index 1.8781 vln-one-sin-ran beg 0.2623 f+ 2 65.4050 0.16 :fm-index 2.0283 vln-one-sin-ran beg 0.2623 f+ 4 65.4050 0.16 :fm-index 2.4739 vln-one-sin-ran beg 0.2623 f+ 4 65.4050 0.16 :fm-index 2.2333 vln-one-sin-ran beg 0.2625 f+ 2 65.4050 0.16 :fm-index 2.2194 vln-one-sin-ran beg 0.2625 f+ 1 65.4050 0.16 :fm-index 2.4491 vln-one-sin-ran beg 0.2630 f+ 2 65.4050 0.16 :fm-index 1.5672 vln-one-sin-ran beg 0.2633 f+ 2 65.4050 0.16 :fm-index 2.3254 vln-one-sin-ran beg 0.2635 f+ 1.2 65.4050 0.16 :fm-index 1.8302 vln-one-sin-ran beg 0.2635 f+ 2.8 65.4050 0.16 :fm-index 1.9201 vln-one-sin-ran beg 0.2640 f+ 0.8 65.4050 0.16 :fm-index 1.9164 vln-one-sin-ran beg 0.2643 f+ 2 65.4050 0.16 :fm-index 1.9483 vln-one-sin-ran beg 0.2643 f+ 4 65.4050 0.16 :fm-index 2.4247 vln-one-sin-ran beg 0.2643 f+ 4 65.4050 0.16 :fm-index 2.0419 vln-one-sin-ran beg 4 + dup to beg test-info \ 23, score 118 2.718 to fmv-fm1-rat 4.414 to fmv-fm2-rat 3.141 to fmv-fm3-rat beg 0.2600 f+ 1.6 88.8854 0.16 :fm-index 2.2832 vln-one-sin-ran beg 0.2600 f+ 2 88.8854 0.16 :fm-index 1.6588 vln-one-sin-ran beg 0.2603 f+ 1.2 88.8854 0.16 :fm-index 2.2392 vln-one-sin-ran beg 0.2603 f+ 4 88.8854 0.16 :fm-index 1.7354 vln-one-sin-ran beg 0.2605 f+ 1.2 102.7186 0.16 :fm-index 1.6692 vln-one-sin-ran beg 0.2605 f+ 2.8 102.7186 0.16 :fm-index 2.1518 vln-one-sin-ran beg 0.2608 f+ 1.2 102.7186 0.16 :fm-index 2.2439 vln-one-sin-ran beg 0.2608 f+ 1.6 32.7025 0.16 :fm-index 2.1665 vln-one-sin-ran beg 0.2610 f+ 2 32.7025 0.16 :fm-index 1.7947 vln-one-sin-ran beg 0.2610 f+ 1.2 32.7025 0.16 :fm-index 2.0740 vln-one-sin-ran beg 0.2613 f+ 4 32.7025 0.16 :fm-index 1.9705 vln-one-sin-ran beg 0.2615 f+ 1.2 32.7025 0.16 :fm-index 1.9447 vln-one-sin-ran beg 0.2615 f+ 2.8 32.7025 0.16 :fm-index 2.4918 vln-one-sin-ran beg 0.2620 f+ 1.2 32.7025 0.16 :fm-index 1.6275 vln-one-sin-ran beg 0.2623 f+ 2 32.7025 0.16 :fm-index 2.2355 vln-one-sin-ran beg 0.2623 f+ 4 32.7025 0.16 :fm-index 2.0084 vln-one-sin-ran beg 0.2623 f+ 4 32.7025 0.16 :fm-index 1.8964 vln-one-sin-ran beg 0.2625 f+ 2 32.7025 0.16 :fm-index 2.3937 vln-one-sin-ran beg 0.2625 f+ 1 32.7025 0.16 :fm-index 1.8634 vln-one-sin-ran beg 0.2630 f+ 2 32.7025 0.16 :fm-index 1.5217 vln-one-sin-ran beg 0.2633 f+ 2 32.7025 0.16 :fm-index 1.9275 vln-one-sin-ran beg 0.2635 f+ 1.2 32.7025 0.16 :fm-index 2.4413 vln-one-sin-ran beg 0.2635 f+ 2.8 32.7025 0.16 :fm-index 2.3242 vln-one-sin-ran beg 0.2640 f+ 0.8 32.7025 0.16 :fm-index 2.3267 vln-one-sin-ran beg 0.2643 f+ 2 32.7025 0.16 :fm-index 1.7004 vln-one-sin-ran beg 0.2643 f+ 4 32.7025 0.16 :fm-index 1.8785 vln-one-sin-ran beg 0.2643 f+ 4 32.7025 0.16 :fm-index 2.4573 vln-one-sin-ran beg 4 + dup to beg test-info \ 24, score 122 2.718 to fmv-fm1-rat 4.414 to fmv-fm2-rat 5.141 to fmv-fm3-rat beg 0.2600 f+ 1.6 22.2213 0.16 :fm-index 1.6232 vln-one-sin-ran beg 0.2600 f+ 2 22.2213 0.16 :fm-index 1.5982 vln-one-sin-ran beg 0.2603 f+ 1.2 22.2213 0.16 :fm-index 2.1585 vln-one-sin-ran beg 0.2603 f+ 4 22.2213 0.16 :fm-index 2.2207 vln-one-sin-ran beg 0.2605 f+ 1.2 42.0309 0.16 :fm-index 1.5294 vln-one-sin-ran beg 0.2605 f+ 2.8 42.0309 0.16 :fm-index 1.9544 vln-one-sin-ran beg 0.2608 f+ 1.2 42.0309 0.16 :fm-index 2.4016 vln-one-sin-ran beg 0.2608 f+ 1.6 8.1756 0.16 :fm-index 1.5267 vln-one-sin-ran beg 0.2610 f+ 2 8.1756 0.16 :fm-index 2.4190 vln-one-sin-ran beg 0.2610 f+ 1.2 8.1756 0.16 :fm-index 2.2757 vln-one-sin-ran beg 0.2613 f+ 4 8.1756 0.16 :fm-index 2.3607 vln-one-sin-ran beg 0.2615 f+ 1.2 8.1756 0.16 :fm-index 1.8698 vln-one-sin-ran beg 0.2615 f+ 2.8 8.1756 0.16 :fm-index 2.3753 vln-one-sin-ran beg 0.2620 f+ 1.2 8.1756 0.16 :fm-index 2.3392 vln-one-sin-ran beg 0.2623 f+ 2 8.1756 0.16 :fm-index 1.5088 vln-one-sin-ran beg 0.2623 f+ 4 8.1756 0.16 :fm-index 2.2084 vln-one-sin-ran beg 0.2623 f+ 4 8.1756 0.16 :fm-index 1.9512 vln-one-sin-ran beg 0.2625 f+ 2 8.1756 0.16 :fm-index 2.0399 vln-one-sin-ran beg 0.2625 f+ 1 8.1756 0.16 :fm-index 1.7053 vln-one-sin-ran beg 0.2630 f+ 2 8.1756 0.16 :fm-index 2.3204 vln-one-sin-ran beg 0.2633 f+ 2 8.1756 0.16 :fm-index 1.6336 vln-one-sin-ran beg 0.2635 f+ 1.2 8.1756 0.16 :fm-index 1.9483 vln-one-sin-ran beg 0.2635 f+ 2.8 8.1756 0.16 :fm-index 2.3255 vln-one-sin-ran beg 0.2640 f+ 0.8 8.1756 0.16 :fm-index 1.7331 vln-one-sin-ran beg 0.2643 f+ 2 8.1756 0.16 :fm-index 1.9318 vln-one-sin-ran beg 0.2643 f+ 4 8.1756 0.16 :fm-index 1.6908 vln-one-sin-ran beg 0.2643 f+ 4 8.1756 0.16 :fm-index 2.4103 vln-one-sin-ran beg 4 + dup to beg test-info \ 25, score 126 beg 0.2600 f+ 1.6 11.1107 0.16 :fm-index 1.6371 vln-one-sin-ran beg 0.2600 f+ 2 11.1107 0.16 :fm-index 1.8971 vln-one-sin-ran beg 0.2603 f+ 1.2 11.1107 0.16 :fm-index 1.9065 vln-one-sin-ran beg 0.2603 f+ 4 11.1107 0.16 :fm-index 2.2143 vln-one-sin-ran beg 0.2605 f+ 1.2 21.0154 0.16 :fm-index 1.8011 vln-one-sin-ran beg 0.2605 f+ 2.8 21.0154 0.16 :fm-index 2.1950 vln-one-sin-ran beg 0.2608 f+ 1.2 21.0154 0.16 :fm-index 2.3563 vln-one-sin-ran beg 0.2608 f+ 1.6 4.0878 0.16 :fm-index 2.3181 vln-one-sin-ran beg 0.2610 f+ 2 4.0878 0.16 :fm-index 2.0776 vln-one-sin-ran beg 0.2610 f+ 1.2 4.0878 0.16 :fm-index 1.8336 vln-one-sin-ran beg 0.2613 f+ 4 4.0878 0.16 :fm-index 1.5019 vln-one-sin-ran beg 0.2615 f+ 1.2 4.0878 0.16 :fm-index 2.2368 vln-one-sin-ran beg 0.2615 f+ 2.8 4.0878 0.16 :fm-index 1.7462 vln-one-sin-ran beg 0.2620 f+ 1.2 4.0878 0.16 :fm-index 1.9604 vln-one-sin-ran beg 0.2623 f+ 2 4.0878 0.16 :fm-index 2.2361 vln-one-sin-ran beg 0.2623 f+ 4 4.0878 0.16 :fm-index 1.9972 vln-one-sin-ran beg 0.2623 f+ 4 4.0878 0.16 :fm-index 2.4870 vln-one-sin-ran beg 0.2625 f+ 2 4.0878 0.16 :fm-index 2.0762 vln-one-sin-ran beg 0.2625 f+ 1 4.0878 0.16 :fm-index 2.2973 vln-one-sin-ran beg 0.2630 f+ 2 4.0878 0.16 :fm-index 2.2350 vln-one-sin-ran beg 0.2633 f+ 2 4.0878 0.16 :fm-index 2.1613 vln-one-sin-ran beg 0.2635 f+ 1.2 4.0878 0.16 :fm-index 2.0640 vln-one-sin-ran beg 0.2635 f+ 2.8 4.0878 0.16 :fm-index 2.1738 vln-one-sin-ran beg 0.2640 f+ 0.8 4.0878 0.16 :fm-index 1.5188 vln-one-sin-ran beg 0.2643 f+ 2 4.0878 0.16 :fm-index 1.8766 vln-one-sin-ran beg 0.2643 f+ 4 4.0878 0.16 :fm-index 2.3083 vln-one-sin-ran beg 0.2643 f+ 4 4.0878 0.16 :fm-index 2.2215 vln-one-sin-ran beg 4 + dup to beg test-info \ 26, score 130 beg 0.2600 f+ 1.6 66.5893 0.16 :fm-index 1.7041 vln-one-sin-ran beg 0.2600 f+ 2 66.4564 0.16 :fm-index 2.0296 vln-one-sin-ran beg 0.2603 f+ 1.2 66.7225 0.16 :fm-index 1.8321 vln-one-sin-ran beg 0.2603 f+ 4 66.3237 0.16 :fm-index 2.1550 vln-one-sin-ran beg 0.2605 f+ 1.2 125.4490 0.16 :fm-index 2.1806 vln-one-sin-ran beg 0.2605 f+ 2.8 125.6999 0.16 :fm-index 2.3570 vln-one-sin-ran beg 0.2608 f+ 1.2 125.1986 0.16 :fm-index 1.9861 vln-one-sin-ran beg 0.2608 f+ 1.6 24.4994 0.16 :fm-index 1.6412 vln-one-sin-ran beg 0.2610 f+ 2 24.4505 0.16 :fm-index 1.9770 vln-one-sin-ran beg 0.2610 f+ 1.2 24.5484 0.16 :fm-index 2.0103 vln-one-sin-ran beg 0.2613 f+ 4 24.4017 0.16 :fm-index 2.0663 vln-one-sin-ran beg 0.2615 f+ 1.2 24.4017 0.16 :fm-index 2.1521 vln-one-sin-ran beg 0.2615 f+ 2.8 24.4505 0.16 :fm-index 2.4453 vln-one-sin-ran beg 0.2620 f+ 1.2 24.3530 0.16 :fm-index 2.0930 vln-one-sin-ran beg 0.2623 f+ 2 24.6960 0.16 :fm-index 2.3423 vln-one-sin-ran beg 0.2623 f+ 4 24.7454 0.16 :fm-index 2.0856 vln-one-sin-ran beg 0.2623 f+ 4 24.7948 0.16 :fm-index 1.9570 vln-one-sin-ran beg 0.2625 f+ 2 24.4994 0.16 :fm-index 2.4642 vln-one-sin-ran beg 0.2625 f+ 1 24.4749 0.16 :fm-index 1.9901 vln-one-sin-ran beg 0.2630 f+ 2 24.5239 0.16 :fm-index 1.9972 vln-one-sin-ran beg 0.2633 f+ 2 24.4505 0.16 :fm-index 1.9148 vln-one-sin-ran beg 0.2635 f+ 1.2 24.4505 0.16 :fm-index 1.9017 vln-one-sin-ran beg 0.2635 f+ 2.8 24.4749 0.16 :fm-index 2.4958 vln-one-sin-ran beg 0.2640 f+ 0.8 24.4260 0.16 :fm-index 2.2518 vln-one-sin-ran beg 0.2643 f+ 2 24.5975 0.16 :fm-index 2.1120 vln-one-sin-ran beg 0.2643 f+ 4 24.6221 0.16 :fm-index 2.3154 vln-one-sin-ran beg 0.2643 f+ 4 24.6467 0.16 :fm-index 1.9240 vln-one-sin-ran beg 4 + dup to beg test-info \ 27, score 134 6.718 to fmv-fm1-rat 4.414 to fmv-fm2-rat 5.141 to fmv-fm3-rat beg 0.2600 f+ 1.6 164.5868 0.16 :fm-index 1.9587 vln-one-sin-ran beg 0.2600 f+ 2 164.5868 0.16 :fm-index 1.5071 vln-one-sin-ran beg 0.2603 f+ 1.2 164.5868 0.16 :fm-index 1.7690 vln-one-sin-ran beg 0.2603 f+ 4 164.5868 0.16 :fm-index 1.7686 vln-one-sin-ran beg 0.2605 f+ 1.2 125.9513 0.16 :fm-index 1.5702 vln-one-sin-ran beg 0.2605 f+ 2.8 125.9513 0.16 :fm-index 2.1962 vln-one-sin-ran beg 0.2608 f+ 1.2 125.9513 0.16 :fm-index 1.7701 vln-one-sin-ran beg 0.2608 f+ 1.6 24.4994 0.16 :fm-index 2.1665 vln-one-sin-ran beg 0.2610 f+ 2 24.4994 0.16 :fm-index 1.9345 vln-one-sin-ran beg 0.2610 f+ 1.2 24.4994 0.16 :fm-index 2.2037 vln-one-sin-ran beg 0.2613 f+ 4 24.4994 0.16 :fm-index 1.6826 vln-one-sin-ran beg 0.2615 f+ 1.2 24.4994 0.16 :fm-index 1.5410 vln-one-sin-ran beg 0.2615 f+ 2.8 24.4994 0.16 :fm-index 1.8293 vln-one-sin-ran beg 0.2620 f+ 1.2 24.4994 0.16 :fm-index 2.1468 vln-one-sin-ran beg 0.2623 f+ 2 24.4994 0.16 :fm-index 2.0758 vln-one-sin-ran beg 0.2623 f+ 4 24.4994 0.16 :fm-index 2.4138 vln-one-sin-ran beg 0.2623 f+ 4 24.4994 0.16 :fm-index 1.8479 vln-one-sin-ran beg 0.2625 f+ 3 24.4994 0.16 :fm-index 2.4639 vln-one-sin-ran beg 0.2625 f+ 1.5 24.4994 0.16 :fm-index 2.3995 vln-one-sin-ran beg 0.2630 f+ 3 24.4994 0.16 :fm-index 1.8609 vln-one-sin-ran beg 0.2633 f+ 3 24.4994 0.16 :fm-index 2.4506 vln-one-sin-ran beg 0.2635 f+ 1.2 24.4994 0.16 :fm-index 2.1577 vln-one-sin-ran beg 0.2635 f+ 2.8 24.4994 0.16 :fm-index 1.6663 vln-one-sin-ran beg 0.2640 f+ 0.8 24.4994 0.16 :fm-index 2.1166 vln-one-sin-ran beg 0.2643 f+ 2 24.4994 0.16 :fm-index 1.9362 vln-one-sin-ran beg 0.2643 f+ 4 24.4994 0.16 :fm-index 2.2052 vln-one-sin-ran beg 0.2643 f+ 4 24.4994 0.16 :fm-index 2.0102 vln-one-sin-ran beg 4 + dup to beg test-info \ 28, score 138 restore-fm-violin-defaults whoosh to fmv-gliss-env metalamp to fmv-amp-env 0.8 to fmv-glissando-amount 0.01 to fmv-reverb-amount 2.718 to fmv-fm1-rat 1.141 to fmv-fm2-rat 3.141 to fmv-fm3-rat beg 0.2600 f+ 0.4 1046.4800 0.16 :fm-index 2.3870 vln-one-sin beg 0.2600 f+ 0.5 1044.3912 0.16 :fm-index 2.4309 vln-one-sin beg 0.2603 f+ 0.3 1048.5730 0.16 :fm-index 2.15 vln-one-sin beg 0.2603 f+ 0.5 1042.3066 0.16 :fm-index 1.7211 vln-one-sin beg 0.2610 f+ 0.3 524.2865 0.16 :fm-index 2.1751 vln-one-sin beg 0.2620 f+ 0.3 520.1131 0.16 :fm-index 1.5433 vln-one-sin beg 0.2623 f+ 0.4 517.0048 0.16 :fm-index 2.4335 vln-one-sin beg 0.2625 f+ 0.4 523.2400 0.16 :fm-index 2.2778 vln-one-sin beg 0.2635 f+ 0.3 522.1951 0.16 :fm-index 1.9441 vln-one-sin beg 0.2643 f+ 0.4 520.6316 0.16 :fm-index 2.4656 vln-one-sin beg 4 + dup to beg test-info \ 29, score 142 restore-fm-violin-defaults beg 0.1200 f+ 0.4 2092.9600 0.16 :fm-index 3 :reverb-amount 0 :amp-env metalamp :fm2-rat 1.1410 :fm3-rat 3.1410 :fm1-rat 2.7180 vln-one-sin beg 0.1200 f+ 0.5 2088.7820 0.16 :fm-index 3 :reverb-amount 0 :amp-env metalamp :fm2-rat 1.1410 :fm3-rat 3.1410 :fm1-rat 2.7180 vln-one-sin beg 0.1200 f+ 0.3 2097.1460 0.16 :fm-index 3 :reverb-amount 0 :amp-env metalamp :fm2-rat 1.1410 :fm3-rat 3.1410 :fm1-rat 2.7180 vln-one-sin beg 0.1200 f+ 0.5 2084.6130 0.16 :fm-index 3 :reverb-amount 0 :amp-env metalamp :fm2-rat 1.1410 :fm3-rat 3.1410 :fm1-rat 2.7180 vln-one-sin beg 0.1210 f+ 0.3 1048.5730 0.16 :fm-index 3 :reverb-amount 0 :amp-env metalamp :fm2-rat 1.1410 :fm3-rat 3.1410 :fm1-rat 2.7180 vln-one-sin beg 0.1220 f+ 0.3 1040.2260 0.16 :fm-index 3 :reverb-amount 0 :amp-env metalamp :fm2-rat 1.1410 :fm3-rat 3.1410 :fm1-rat 2.7180 vln-one-sin beg 0.1220 f+ 0.5 1034.0100 0.16 :fm-index 3 :reverb-amount 0 :amp-env metalamp :fm2-rat 1.1410 :fm3-rat 3.1410 :fm1-rat 2.7180 vln-one-sin beg 0.1230 f+ 0.5 1046.4800 0.16 :fm-index 3 :reverb-amount 0 :amp-env metalamp :fm2-rat 1.1410 :fm3-rat 3.1410 :fm1-rat 2.7180 vln-one-sin beg 0.1240 f+ 0.3 1044.3900 0.16 :fm-index 3 :reverb-amount 0 :amp-env metalamp :fm2-rat 1.1410 :fm3-rat 3.1410 :fm1-rat 2.7180 vln-one-sin beg 0.1240 f+ 0.5 1041.2630 0.16 :fm-index 3 :reverb-amount 0 :amp-env metalamp :fm2-rat 1.1410 :fm3-rat 3.1410 :fm1-rat 2.7180 vln-one-sin beg 2 + dup to beg test-info \ 30, score 144 '( 0 0 20 0.5000 40 0.1 60 0.2 80 1 100 0 ) { z1amp } '( 0 0 20 1 60 0.1 75 0.3 100 0 ) { z2amp } 2.718 to fmv-fm1-rat 4.414 to fmv-fm2-rat 5.141 to fmv-fm3-rat beg 0.4880 f+ 1.1770 416.6072 0.0110 :fm-index 1.1140 :reverb-amount 0.1 :amp-env z1amp :noise-amount 0.0050 vln-one-sin-ran beg 0.5050 f+ 2.4900 859.5863 0.0083 :fm-index 0.5890 :reverb-amount 0.1 :amp-env z2amp :noise-amount 0.0050 vln-one-sin-ran beg 1 + to beg beg 0.0590 f+ 1.0550 1758.0816 0.0053 :fm-index 1.8640 :reverb-amount 0.1 :amp-env z2amp :noise-amount 0.0050 vln-one-sin-ran beg 0.0930 f+ 1.8580 229.0566 0.0110 :fm-index 1.9690 :reverb-amount 0.1 :amp-env z2amp :noise-amount 0.0050 vln-one-sin-ran beg 0.3490 f+ 3.3680 479.1994 0.0083 :fm-index 1.9970 :reverb-amount 0.1 :amp-env z1amp :noise-amount 0.0050 vln-one-sin-ran beg 0.5010 f+ 3.0680 411.8241 0.0110 :fm-index 1.5390 :reverb-amount 0.1 :amp-env z2amp :noise-amount 0.0050 vln-one-sin-ran beg 0.5200 f+ 2.8290 984.8456 0.0053 :fm-index 0.0560 :reverb-amount 0.1 :amp-env z1amp :noise-amount 0.0050 vln-one-sin-ran beg 0.6100 f+ 0.7040 1767.7444 0.0053 :fm-index 1.2620 :reverb-amount 0.1 :amp-env z2amp :noise-amount 0.0050 vln-one-sin-ran beg 0.8480 f+ 3.0510 859.7203 0.0083 :fm-index 1.6080 :reverb-amount 0.1 :amp-env z2amp :noise-amount 0.0050 vln-one-sin-ran beg 1 + to beg beg 0.4880 f+ 3.2350 231.9431 0.0110 :fm-index 0.9690 :reverb-amount 0.1 :amp-env z1amp :noise-amount 0.0050 vln-one-sin-ran beg 0.5610 f+ 3.2810 475.2009 0.0083 :fm-index 0.3740 :reverb-amount 0.1 :amp-env z2amp :noise-amount 0.0050 vln-one-sin-ran beg 0.7970 f+ 2.8400 988.8375 0.0053 :fm-index 0.4200 :reverb-amount 0.1 :amp-env z2amp :noise-amount 0.0050 vln-one-sin-ran beg 1 + to beg beg 0.0620 f+ 1.0210 411.7247 0.0110 :fm-index 0.1370 :reverb-amount 0.1 :amp-env z2amp :noise-amount 0.0050 vln-one-sin-ran beg 0.2130 f+ 1.1610 848.5959 0.0083 :fm-index 1.3120 :reverb-amount 0.1 :amp-env z2amp :noise-amount 0.0050 vln-one-sin-ran beg 0.4410 f+ 2.6160 390.0600 0.0110 :fm-index 1.9030 :reverb-amount 0.1 :amp-env z1amp :noise-amount 0.0050 vln-one-sin-ran beg 0.4490 f+ 0.7000 802.3538 0.0083 :fm-index 1.5940 :reverb-amount 0.1 :amp-env z2amp :noise-amount 0.0050 vln-one-sin-ran beg 0.5270 f+ 2.5080 1773.9366 0.0053 :fm-index 1.8030 :reverb-amount 0.1 :amp-env z1amp :noise-amount 0.0050 vln-one-sin-ran beg 0.7820 f+ 2.7990 232.4344 0.0110 :fm-index 0.0590 :reverb-amount 0.1 :amp-env z2amp :noise-amount 0.0050 vln-one-sin-ran beg 0.7830 f+ 2.7660 1650.1434 0.0053 :fm-index 0.4400 :reverb-amount 0.1 :amp-env z2amp :noise-amount 0.0050 vln-one-sin-ran beg 0.7890 f+ 3.1560 475.7231 0.0083 :fm-index 0.7370 :reverb-amount 0.1 :amp-env z2amp :noise-amount 0.0050 vln-one-sin-ran beg 1 + to beg beg 0.1540 f+ 2.1290 976.0237 0.0053 :fm-index 1.2690 :reverb-amount 0.1 :amp-env z2amp :noise-amount 0.0050 vln-one-sin-ran beg 0.4890 f+ 3.3650 390.0525 0.0110 :fm-index 1.4580 :reverb-amount 0.1 :amp-env z2amp :noise-amount 0.0050 vln-one-sin-ran beg 0.7450 f+ 1.5070 1665.9722 0.0053 :fm-index 1.9330 :reverb-amount 0.1 :amp-env z2amp :noise-amount 0.0050 vln-one-sin-ran beg 0.8320 f+ 1.4430 798.1238 0.0083 :fm-index 0.8560 :reverb-amount 0.1 :amp-env z1amp :noise-amount 0.0050 vln-one-sin-ran beg 0.9440 f+ 3.1560 229.0528 0.0110 :fm-index 1.8300 :reverb-amount 0.1 :amp-env z2amp :noise-amount 0.0050 vln-one-sin-ran beg 1 + to beg beg 0.3930 f+ 1.1100 473.7225 0.0083 :fm-index 1.6260 :reverb-amount 0.1 :amp-env z1amp :noise-amount 0.0050 vln-one-sin-ran beg 0.6970 f+ 1.6170 988.7953 0.0053 :fm-index 0.4230 :reverb-amount 0.1 :amp-env z2amp :noise-amount 0.0050 vln-one-sin-ran beg 1 + to beg beg 0.0620 f+ 1.3190 390.9769 0.0110 :fm-index 0.4100 :reverb-amount 0.1 :amp-env z2amp :noise-amount 0.0050 vln-one-sin-ran beg 0.0840 f+ 3.3660 804.6413 0.0083 :fm-index 1.8760 :reverb-amount 0.1 :amp-env z2amp :noise-amount 0.0050 vln-one-sin-ran beg 0.1740 f+ 2.7210 418.6819 0.0110 :fm-index 0.0910 :reverb-amount 0.1 :amp-env z2amp :noise-amount 0.0050 vln-one-sin-ran beg 0.5700 f+ 3.4460 845.4019 0.0077 :fm-index 0.7660 :reverb-amount 0.1 :amp-env z2amp :noise-amount 0.0050 vln-one-sin-ran beg 0.6440 f+ 1.1790 1656.5756 0.0049 :fm-index 0.2960 :reverb-amount 0.1 :amp-env z1amp :noise-amount 0.0050 vln-one-sin-ran beg 0.6600 f+ 2.8520 1758.9788 0.0049 :fm-index 0.4520 :reverb-amount 0.1 :amp-env z2amp :noise-amount 0.0050 vln-one-sin-ran beg 0.8270 f+ 1.8840 387.0009 0.0099 :fm-index 1.3010 :reverb-amount 0.1 :amp-env z1amp :noise-amount 0.0050 vln-one-sin-ran beg 0.8870 f+ 3.4040 796.7213 0.0077 :fm-index 1.1820 :reverb-amount 0.1 :amp-env z2amp :noise-amount 0.0050 vln-one-sin-ran beg 0.9640 f+ 3.3230 416.3916 0.0099 :fm-index 0.6290 :reverb-amount 0.1 :amp-env z2amp :noise-amount 0.0050 vln-one-sin-ran beg 1 + to beg beg 0.1320 f+ 1.7050 1637.2303 0.0049 :fm-index 1.0570 :reverb-amount 0.1 :amp-env z1amp :noise-amount 0.0050 vln-one-sin-ran beg 0.15 f+ 3.1250 1762.4906 0.0049 :fm-index 1.3170 :reverb-amount 0.1 :amp-env z2amp :noise-amount 0.0050 vln-one-sin-ran beg 0.3860 f+ 2.9670 852.0487 0.0077 :fm-index 1.4790 :reverb-amount 0.1 :amp-env z1amp :noise-amount 0.0050 vln-one-sin-ran beg 0.6670 f+ 0.6780 413.7094 0.0099 :fm-index 0.9470 :reverb-amount 0.1 :amp-env z2amp :noise-amount 0.0050 vln-one-sin-ran beg 0.8780 f+ 2.7490 1749.7509 0.0049 :fm-index 0.5040 :reverb-amount 0.1 :amp-env z1amp :noise-amount 0.0050 vln-one-sin-ran beg 0.9730 f+ 0.5990 848.1253 0.0077 :fm-index 1.9380 :reverb-amount 0.1 :amp-env z1amp :noise-amount 0.0050 vln-one-sin-ran beg 1 + to beg beg 0.0880 f+ 3.3360 229.9144 0.0099 :fm-index 1.3930 :reverb-amount 0.1 :amp-env z2amp :noise-amount 0.0050 vln-one-sin-ran beg 0.1170 f+ 1.1300 984.0816 0.0049 :fm-index 0.3560 :reverb-amount 0.1 :amp-env z2amp :noise-amount 0.0050 vln-one-sin-ran beg 0.4640 f+ 1.7330 478.7184 0.0077 :fm-index 0.2840 :reverb-amount 0.1 :amp-env z2amp :noise-amount 0.0050 vln-one-sin-ran beg 0.5760 f+ 0.5680 413.4253 0.0099 :fm-index 1.5020 :reverb-amount 0.1 :amp-env z2amp :noise-amount 0.0050 vln-one-sin-ran beg 0.8200 f+ 1.2150 230.9588 0.0099 :fm-index 1.0990 :reverb-amount 0.1 :amp-env z1amp :noise-amount 0.0050 vln-one-sin-ran beg 0.8320 f+ 3.4590 473.8903 0.0077 :fm-index 0.7680 :reverb-amount 0.1 :amp-env z2amp :noise-amount 0.0050 vln-one-sin-ran beg 0.8320 f+ 0.7260 857.2875 0.0077 :fm-index 0.7520 :reverb-amount 0.1 :amp-env z2amp :noise-amount 0.0050 vln-one-sin-ran beg 4 + dup to beg test-info \ 31, score 156 '( 0 1 20 0 100 0 ) { indfunc } '( 0 1 90 1 100 0 ) { indfunc2 } '( 0 1 6 1 10 0.5 20 0.3630 30 0.27 40 0.2 50 0.12 60 0.08 70 0.04 100 0 ) { ampfunc } '( 0 0 1 1 3 1 10 0.5 30 0.2 60 0.05 100 0 ) { ampfunc1 } restore-fm-violin-defaults beg 0.2600 f+ 0.0500 80 0.8 :fm-index 5 :reverb-amount 0 :amp-env ampfunc1 :fm1-env indfunc2 vln-one-sin beg 1 + to beg beg 0.2610 f+ 0.2 80 0.8 :fm-index 4 :reverb-amount 0 :amp-env ampfunc :fm1-env indfunc :fm2-rat 0.6875 vln-one-sin beg 1 + to beg beg 0.2600 f+ 0.05 80 0.8 :fm-index 5 :reverb-amount 0 :amp-env ampfunc1 :fm1-env indfunc2 vln-one-sin beg 0.2620 f+ 0.2 80 0.8 :fm-index 5 :reverb-amount 0 :amp-env ampfunc :fm1-env indfunc :fm2-rat 0.6875 vln-one-sin beg 1 + to beg beg 0.2600 f+ 0.0500 80 0.8 :fm-index 6 :reverb-amount 0 :amp-env ampfunc1 :fm1-env indfunc2 vln-one-sin beg 0.2630 f+ 0.2 80 0.8 :fm-index 6 :reverb-amount 0 :amp-env ampfunc :fm1-env indfunc :fm2-rat 0.6875 vln-one-sin beg 1 + to beg beg 0.2600 f+ 0.0500 80 0.3 :fm-index 4 :reverb-amount 0 :amp-env ampfunc1 :fm1-env indfunc2 vln-one-sin beg 0.2620 f+ 0.1 160 0.3 :fm-index 4 :reverb-amount 0 :amp-env ampfunc :fm1-env indfunc :fm2-rat 0.6875 vln-one-sin beg 0.2620 f+ 0.2500 80 0.8 :fm-index 4 :reverb-amount 0 :amp-env ampfunc :fm1-env indfunc :fm2-rat 0.6875 vln-one-sin beg 1 + to beg beg 0.2600 f+ 0.0500 80 0.5000 :fm-index 4 :reverb-amount 0 :amp-env ampfunc1 :fm1-env indfunc2 vln-one-sin beg 0.2610 f+ 0.1 210 0.3 :fm-index 4 :reverb-amount 0 :amp-env ampfunc :fm1-env indfunc :fm2-rat 0.6875 vln-one-sin beg 0.2620 f+ 0.2 80 0.1 :fm-index 4 :reverb-amount 0 :amp-env ampfunc :fm1-env indfunc :fm2-rat 0.6875 vln-one-sin beg 0.2630 f+ 0.2500 320 0.1 :fm-index 2 :reverb-amount 0 :amp-env ampfunc :fm1-env indfunc :fm2-rat 0.6875 vln-one-sin beg 1 + to beg beg 0.2600 f+ 0.0500 80 0.8 :fm-index 4 :reverb-amount 0 :amp-env ampfunc1 :fm1-env indfunc2 vln-one-sin beg 0.2610 f+ 0.1 210 0.1 :fm-index 2 :reverb-amount 0 :amp-env ampfunc :fm1-env indfunc :fm2-rat 0.6875 vln-one-sin beg 0.2620 f+ 0.2 80 0.2 :fm-index 4 :reverb-amount 0 :amp-env ampfunc :fm1-env indfunc :fm2-rat 0.6875 vln-one-sin beg 0.2630 f+ 0.2500 320 0.3 :reverb-amount 0 :amp-env ampfunc :fm1-env indfunc :fm2-rat 0.6875 vln-one-sin beg 1 + to beg beg 0.2600 f+ 0.0500 80 0.8 :fm-index 2 :reverb-amount 0 :amp-env ampfunc1 :fm1-env indfunc2 vln-one-sin beg 0.2610 f+ 0.1 210 0.1 :fm-index 2 :reverb-amount 0 :amp-env ampfunc :fm1-env indfunc :fm2-rat 0.6875 vln-one-sin beg 0.2620 f+ 0.2 80 0.2 :fm-index 2 :reverb-amount 0 :amp-env ampfunc :fm1-env indfunc :fm2-rat 0.6875 vln-one-sin beg 0.2630 f+ 0.2500 320 0.3 :reverb-amount 0 :amp-env ampfunc :fm1-env indfunc :fm2-rat 0.6875 vln-one-sin beg 1 + dup to beg test-info \ 32, score 164 0 to fmv-glissando-amount 0.004 to fmv-noise-amount 3.141 to fmv-fm1-rat 4.414 to fmv-fm2-rat 2.718 to fmv-fm3-rat beg 0.2600 f+ 4 3286.9937 0.16 :fm-index 2.2165 :reverb-amount 0.01 :amp-env n-amp :fm1-env n-amp vln-one-sin-ran beg 0.2603 f+ 4 1046.4800 0.16 :fm-index 2.3234 :reverb-amount 0.01 :amp-env n-amp :fm1-env n-amp vln-one-sin-ran beg 0.2605 f+ 4 2844.3326 0.16 :fm-index 2.4790 :reverb-amount 0.1 :amp-env n-amp :fm1-env n-amp vln-one-sin-ran beg 0.2608 f+ 4 821.7484 0.1 :fm-index 1.8667 :reverb-amount 0.01 :amp-env n-amp :fm1-env n-amp vln-one-sin-ran beg 0.2610 f+ 4 261.6200 0.1 :fm-index 1.8523 :reverb-amount 0.01 :amp-env n-amp :fm1-env n-amp vln-one-sin-ran beg 0.2613 f+ 4 711.0832 0.1 :fm-index 2.2300 :reverb-amount 0.1 :amp-env n-amp :fm1-env n-amp vln-one-sin-ran beg 0.2615 f+ 4 205.4371 0.06 :fm-index 1.5187 :reverb-amount 0.01 :amp-env n-amp :fm1-env n-amp vln-one-sin-ran beg 0.2618 f+ 4 65.4050 0.06 :fm-index 2.4074 :reverb-amount 0.01 :amp-env n-amp :fm1-env n-amp vln-one-sin-ran beg 0.2620 f+ 4 177.7708 0.06 :fm-index 2.4481 :reverb-amount 0.1 :amp-env n-amp :fm1-env n-amp vln-one-sin-ran beg 0.2623 f+ 4 51.3593 0.01 :fm-index 2.3069 :reverb-amount 0.01 :amp-env n-amp :fm1-env n-amp vln-one-sin-ran beg 0.2625 f+ 4 16.3513 0.01 :fm-index 2.1008 :reverb-amount 0.01 :amp-env n-amp :fm1-env n-amp vln-one-sin-ran beg 0.2628 f+ 4 44.4427 0.01 :fm-index 2.4860 :reverb-amount 0.1 :amp-env n-amp :fm1-env n-amp vln-one-sin-ran beg 8 + dup to beg test-info \ 33, score 172 restore-fm-violin-defaults beg 0.2603 f+ 1.2 88.8854 0.1 :fm-index 2.3144 :reverb-amount 0.2 :amp-env mamp :fm2-rat 4.4140 :fm3-rat 5.1410 :fm1-rat 2.7180 vln-one-sin beg 0.2603 f+ 4 88.8854 0.1 :fm-index 2.1690 :reverb-amount 0.2 :amp-env mamp :fm2-rat 4.4140 :fm3-rat 5.1410 :fm1-rat 2.7180 vln-one-sin beg 0.2605 f+ 2.8 168.1236 0.05 :fm-index 2.1850 :reverb-amount 0.2 :amp-env mamp :fm2-rat 4.4140 :fm3-rat 5.1410 :fm1-rat 2.7180 vln-one-sin beg 0.2608 f+ 1.2 168.1236 0.08 :fm-index 1.7743 :reverb-amount 0.2 :amp-env mamp :fm2-rat 4.4140 :fm3-rat 5.1410 :fm1-rat 2.7180 vln-one-sin beg 0.2610 f+ 2 32.7025 0.1 :fm-index 2.4925 :reverb-amount 0.2 :amp-env mamp :fm2-rat 4.4140 :fm3-rat 5.1410 :fm1-rat 2.7180 vln-one-sin beg 0.2633 f+ 2 32.7025 0.1 :fm-index 2.1325 :reverb-amount 0.2 :amp-env mamp :fm2-rat 4.4140 :fm3-rat 5.1410 :fm1-rat 2.7180 vln-one-sin beg 0.2643 f+ 4 32.7025 0.05 :fm-index 1.7578 :reverb-amount 0.2 :amp-env mamp :fm2-rat 4.4140 :fm3-rat 5.1410 :fm1-rat 2.7180 vln-one-sin beg 8 + dup to beg test-info \ 34, score 180 beg 0.2600 f+ 6.6830 244.8160 0.0060 :fm-index 2 :reverb-amount 0.2 :noise-amount 0.0040 vln-one-sin-ran beg 0.2600 f+ 5.5170 495.4040 0.0060 :fm-index 2 :reverb-amount 0.2 :noise-amount 0.0040 vln-one-sin-ran beg 0.2600 f+ 7.5350 980.6190 0.0020 :fm-index 2 :reverb-amount 0.2 :noise-amount 0.0040 vln-one-sin-ran beg 0.2600 f+ 7.1990 1965.4290 0.0020 :fm-index 0.8 :reverb-amount 0.2 :noise-amount 0.0040 vln-one-sin-ran beg 0.2600 f+ 4.0790 3835.3170 0.0020 :fm-index 0.8 :reverb-amount 0.2 :noise-amount 0.0040 vln-one-sin-ran beg 0.5170 f+ 4.7400 1320.9670 0.0020 :fm-index 0.8 :reverb-amount 0.2 :noise-amount 0.0040 vln-one-sin-ran beg 0.7040 f+ 7.2080 655.5670 0.0040 :fm-index 2 :reverb-amount 0.2 :noise-amount 0.0040 vln-one-sin-ran beg 9 + dup to beg test-info \ 35, score 189 '( 0 0 15 1 100 0 ) { updown } 0 to fmv-glissando-amount 0.9 to fmv-reverb-amount beg 0.5450 f+ 6.4650 366.3330 0.0320 :fm-index 1.0480 :amp-env '( 0 0 1.5468 1 2.0882 0.7 2.3202 1 98.4532 0.7500 100 0 ) vln-one-sin-exp beg 0.5950 f+ 8.4340 1172.5830 0.0180 :fm-index 1.1350 :amp-env '( 0 0 1.1857 1.0 1.6007 0.7 1.7785 1 98.8143 0.5556 100 0 ) vln-one-sin-exp beg 0.7650 f+ 1.6210 369.9940 0.0170 :fm-index 0.0960 :amp-env '( 0 0 6.1690 1.0 8.3282 0.7 9.2535 1 93.8310 0.5294 100 0 ) vln-one-sin-exp beg 0.8820 f+ 3.0640 246.9420 0.0170 :fm-index 0.0020 :amp-env '( 0 0 3.2637 1 4.4060 0.7 4.8956 1.0 96.7363 0.5294 100 0 ) vln-one-sin-exp beg 0.9250 f+ 3.1170 123.4710 0.0380 :fm-index 0.2330 :amp-env '( 0 0 3.2082 1 4.3311 0.7 4.8123 1 96.7918 0.7895 100 0 ) vln-one-sin-exp beg 0.9810 f+ 3.5670 123.4710 0.0420 :fm-index 0.2330 :amp-env '( 0 0 2.8035 1 3.7847 0.7 4.2052 1.0 97.1965 0.8095 100 0 ) vln-one-sin-exp beg 1 + to beg beg 0.1280 f+ 1.0450 246.9420 0.0170 :fm-index 1.2050 :amp-env '( 0 0 9.5694 1 12.9187 0.7 14.3541 1 90.4306 0.5294 100 0 ) vln-one-sin-exp beg 0.2550 f+ 3.3870 374.1370 0.0170 :fm-index 0.1800 :amp-env '( 0 0 2.9525 1.0 3.9858 0.7 4.4287 1 97.0475 0.5294 100 0 ) vln-one-sin-exp beg 0.2990 f+ 8.3050 1576.9120 0.0200 :fm-index 0.2990 :amp-env '( 0 0 1.2041 1 1.6255 0.7 1.8061 1 98.7959 0.6 100 0 ) vln-one-sin-exp beg 0.3300 f+ 4.4630 246.9420 0.0170 :fm-index 0.0020 :amp-env '( 0 0 2.2406 1 3.0249 0.7 3.3610 1.0 97.7594 0.5294 100 0 ) vln-one-sin-exp beg 0.6600 f+ 8.9940 1576.9120 0.0200 :fm-index 0.2990 :amp-env '( 0 0 1.1119 1 1.5010 0.7 1.6678 1 98.8881 0.6 100 0 ) vln-one-sin-exp beg 0.9060 f+ 8.8360 1172.5830 0.0180 :fm-index 1.1350 :amp-env '( 0 0 1.1317 1 1.5278 0.7 1.6976 1 98.8683 0.5556 100 0 ) vln-one-sin-exp beg 1 + to beg beg 0.1510 f+ 4.9320 374.1370 0.0170 :fm-index 0.1800 :amp-env '( 0 0 2.0276 1 2.7372 0.7 3.0414 1 97.9724 0.5294 100 0 ) vln-one-sin-exp beg 0.2720 f+ 2.3250 369.9940 0.0170 :fm-index 1.1030 :amp-env '( 0 0 4.3011 1 5.8065 0.7 6.4516 1 95.6989 0.5294 100 0 ) vln-one-sin-exp beg 1 + to beg beg 0.6960 f+ 3.5540 366.3330 0.0310 :fm-index 1.0480 :amp-env '( 0 0 2.8137 1 3.7985 0.7 4.2206 1 97.1863 0.7419 100 0 ) vln-one-sin-exp beg 1 + to beg beg 0.7240 f+ 0.6040 246.9420 0.0170 :fm-index 1.2050 :amp-env '( 0 0 16.5563 1 22.351 0.7 24.8344 1 83.4437 0.5294 100 0 ) vln-one-sin-exp beg 0.9420 f+ 2.5010 123.4710 0.0330 :fm-index 0.2330 :amp-env '( 0 0 3.9984 1 5.3978 0.7 5.9976 1 96.0016 0.7576 100 0 ) vln-one-sin-exp beg 1 + to beg beg 0.0340 f+ 2.3860 246.9420 0.0170 :fm-index 0.0020 :amp-env '( 0 0 4.1911 1 5.6580 0.7 6.2867 1 95.8089 0.5294 100 0 ) vln-one-sin-exp beg 0.3850 f+ 1.4510 369.9940 0.0170 :fm-index 1.1030 :amp-env '( 0 0 6.8918 1 9.3039 0.7 10.3377 1 93.1082 0.5294 100 0 ) vln-one-sin-exp beg 0.5670 f+ 2.6550 374.1370 0.0170 :fm-index 0.1800 :amp-env '( 0 0 3.7665 1 5.0847 0.7 5.6497 1 96.2335 0.5294 100 0 ) vln-one-sin-exp beg 0.9830 f+ 2.9860 123.4710 0.0380 :fm-index 0.2330 :amp-env '( 0 0 3.3490 1 4.5211 0.7 5.0234 1 96.6510 0.7895 100 0 ) vln-one-sin-exp beg 1 + to beg beg 0.4910 f+ 0.6110 123.9770 0.0170 :fm-index 0.7550 :amp-env '( 0 0 16.3666 1 22.0949 0.7 24.55 1 83.6334 0.5294 100 0 ) vln-one-sin-exp beg 0.7570 f+ 1.4440 123.4710 0.0170 :fm-index 0.0020 :amp-env '( 0 0 6.9252 1 9.3490 0.7 10.3878 1 93.0748 0.5294 100 0 ) vln-one-sin-exp beg 0.7750 f+ 0.5370 92.4435 0.0330 :fm-index 0.9200 :amp-env '( 0 0 18.622 1 25.1397 0.7 27.9330 1 81.3780 0.7576 100 0 ) vln-one-sin-exp beg 0.7750 f+ 10.537 92.4435 0.0130 :fm-index 0.9200 :amp-env '( 0 0 0.9490 1 1.2812 0.7 1.4236 1 99.0510 0.3846 100 0 ) vln-one-sin-exp beg 0.9380 f+ 0.6520 122.2995 0.0170 :fm-index 1.8380 :amp-env '( 0 0 15.3374 1 20.706 0.7 23.0061 1 84.6626 0.5294 100 0 ) vln-one-sin-exp beg 1 + to beg beg 0.2350 f+ 3.7250 586.2915 0.0180 :fm-index 1.1350 :amp-env '( 0 0 2.6846 1 3.6242 0.7 4.0268 1 97.3154 0.5556 100 0 ) vln-one-sin-exp beg 0.2560 f+ 2.8900 183.1665 0.0260 :fm-index 1.0480 :amp-env '( 0 0 3.4602 1 4.6713 0.7 5.1903 1 96.5398 0.6923 100 0 ) vln-one-sin-exp beg 0.2710 f+ 1.6210 187.0685 0.0170 :fm-index 0.1800 :amp-env '( 0 0 6.169 1.0 8.3282 0.7 9.2535 1 93.8310 0.5294 100 0 ) vln-one-sin-exp beg 0.2920 f+ 2.0160 183.1665 0.0290 :fm-index 1.0480 :amp-env '( 0 0 4.9603 1 6.6964 0.7 7.4405 1 95.0397 0.7241 100 0 ) vln-one-sin-exp beg 0.2920 f+ 12.016 183.1665 0.0290 :fm-index 1.0480 :amp-env '( 0 0 0.832 1 1.1235 0.7 1.248 1.0 99.1678 0.7241 100 0 ) vln-one-sin-exp beg 0.3300 f+ 0.7300 184.9970 0.0170 :fm-index 0.0960 :amp-env '( 0 0 13.699 1 18.4932 0.7 20.548 1.0 86.3014 0.529 100 0 ) vln-one-sin-exp beg 0.3570 f+ 1.9600 183.1665 0.0280 :fm-index 1.0480 :amp-env '( 0 0 5.1020 1.0 6.8878 0.7 7.6531 1 94.8980 0.7143 100 0 ) vln-one-sin-exp beg 0.3820 f+ 2.2450 61.7355 0.0330 :fm-index 0.2330 :amp-env '( 0 0 4.4543 1 6.0134 0.7 6.6815 1 95.5457 0.7576 100 0 ) vln-one-sin-exp beg 0.3820 f+ 12.2450 61.7355 0.0330 :fm-index 0.2330 :amp-env '( 0 0 0.8167 1 1.1025 0.7 1.2250 1 99.1833 0.7576 100 0 ) vln-one-sin-exp beg 0.5410 f+ 3.0130 246.5050 0.0360 :fm-index 1.1350 :amp-env '( 0 0 3.3190 1.0 4.4806 0.7 4.9784 1 96.6810 0.7778 100 0 ) vln-one-sin-exp beg 0.5570 f+ 2.322 1251.5960 0.0400 :fm-index 0.2990 :amp-env '( 0 0 4.3066 1 5.8140 0.7 6.4599 1 95.6934 0.8 100 0 ) vln-one-sin-exp beg 0.5570 f+ 18.322 1251.5960 0.020 :fm-index 0.2990 :amp-env '( 0 0 0.5458 1.000 0.7368 0.7 0.8187 1 99.4542 0.6 100 0 ) vln-one-sin-exp beg 1 + to beg beg 0.1060 f+ 1.9900 183.1665 0.0230 :fm-index 1.0480 :amp-env '( 0 0 5.0251 1.0 6.7839 0.7 7.5377 1 94.9749 0.6522 100 0 ) vln-one-sin-exp beg 0.2570 f+ 1.9180 61.7355 0.0330 :fm-index 0.2330 :amp-env '( 0 0 5.2138 1 7.0386 0.7 7.8206 1 94.7862 0.7576 100 0 ) vln-one-sin-exp beg 0.6370 f+ 1.3090 183.1665 0.0310 :fm-index 1.0480 :amp-env '( 0 0 7.6394 1 10.3132 0.7 11.4591 1 92.3606 0.7419 100 0 ) vln-one-sin-exp beg 1 + to beg beg 0.0330 f+ 1.1590 183.1665 0.0250 :fm-index 1.0480 :amp-env '( 0 0 8.6281 1 11.6480 0.7 12.9422 1 91.3719 0.6800 100 0 ) vln-one-sin-exp beg 0.0980 f+ 1.2400 30.8675 0.0330 :fm-index 0.2330 :amp-env '( 0 0 8.0645 1 10.8871 0.7 12.0968 1 91.9355 0.7576 100 0 ) vln-one-sin-exp beg 0.0980 f+ 11.2400 30.8675 0.0130 :fm-index 0.2330 :amp-env '( 0 0 0.8897 1 1.2011 0.7 1.3345 1 99.1103 0.3846 100 0 ) vln-one-sin-exp beg 0.1260 f+ 0.2600 123.4710 0.0170 :fm-index 1.2050 :amp-env '( 0 0 38.462 1 51.9231 0.7 57.6923 1 61.5385 0.5294 100 0 ) vln-one-sin-exp beg 0.1260 f+ 10.26 123.4710 0.0170 :fm-index 1.2050 :amp-env '( 0 0 0.9747 1 1.3158 0.7 1.4620 1 99.0253 0.5294 100 0 ) vln-one-sin-exp beg 0.0600 f+ 13.877 3951.1200 0.009 :amp-env updown vln-one-sin beg 0.2600 f+ 14.877 123.4725 0.017 :fm-index 1.5 :amp-env updown vln-one-sin beg 0.2600 f+ 13.877 61.7363 0.017 :fm-index 1.5 :amp-env updown vln-one-sin beg 0.2600 f+ 12.877 30.8681 0.017 :fm-index 1.5 :amp-env updown vln-one-sin beg 0.2600 f+ 11.877 15.4341 0.017 :fm-index 1.5 :amp-env updown vln-one-sin beg 19 + dup to beg test-info \ 36, score 217 restore-fm-violin-defaults beg 0.2620 f+ 0.3906 440 0.4500 :fm-index 1.2 :reverb-amount 0.0013 :amp-env '( 0 0 0.7680 1 4.7774 0.6 9.7891 0.3 24.8243 0.1 100 0 ) cel-one-sum beg 0.2640 f+ 0.5220 220 0.4500 :fm-index 1.2 :reverb-amount 0.0012 :amp-env '( 0 0 0.5747 1.0 4.5919 0.6 9.6134 0.3 24.6778 0.1 100 0 ) cel-one-sum beg 0.2660 f+ 1.5660 880 0.4500 :fm-index 1.2 :reverb-amount 0.0014 :amp-env '( 0 0 0.1916 1.0 4.2242 0.6 9.2651 0.3 24.3876 0.1 100 0 ) cel-one-sum beg 0.2680 f+ 1.5660 110 0.4500 :fm-index 1.2 :reverb-amount 0.0013 :amp-env '( 0 0 0.1916 1.0 4.2242 0.6 9.2651 0.3 24.3876 0.1 100 0 ) cel-one-sum beg 3 + dup to beg test-info \ 37, score 220 beg 0.8600 f+ 0.9 733.3330 0.1875 :fm-index 0.2 :distance 1.0 :reverb-amount 0.0012 :amp-env '( 0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.4950 0.1 100 0 ) vln-one-sin beg 0.8600 f+ 0.225 550 0.1875 :fm-index 0.2 :distance 1.0 :reverb-amount 0.0015 :amp-env '( 0 0 1.3333 1 5.3199 0.6 10.3030 0.3 25.2525 0.1 100 0 ) vln-one-sin beg 0.8600 f+ 0.45 586.6670 0.3750 :fm-index 0.2 :distance 1.0 :reverb-amount 0.0013 :amp-env '( 0 0 0.6667 1 4.6801 0.6 9.6970 0.3 24.7475 0.1 100 0 ) vln-one-sin beg 0.9020 f+ 0.9 733.3330 0.1875 :fm-index 0.4 :distance 1.0 :reverb-amount 0.0013 :amp-env '( 0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.4950 0.1 100 0 ) vln-one-sin beg 0.9020 f+ 0.225 550 0.1875 :fm-index 0.4 :distance 1.0 :reverb-amount 0.0010 :amp-env '( 0 0 1.3333 1 5.3199 0.6 10.3030 0.3 25.2525 0.1 100 0 ) vln-one-sin beg 0.9020 f+ 0.45 586.6670 0.3750 :fm-index 0.4 :distance 1.0 :reverb-amount 0.0015 :amp-env '( 0 0 0.6667 1 4.6801 0.6 9.6970 0.3 24.7475 0.1 100 0 ) vln-one-sin beg 0.9430 f+ 0.9 366.6670 0.1875 :fm-index 0.6 :distance 1.0 :reverb-amount 0.0016 :amp-env '( 0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.4950 0.1 100 0 ) vln-one-sin beg 0.9430 f+ 0.225 275 0.1875 :fm-index 0.6 :distance 1.0 :reverb-amount 0.0015 :amp-env '( 0 0 1.3333 1 5.3199 0.6 10.3030 0.3 25.2525 0.1 100 0 ) vln-one-sin beg 0.9430 f+ 0.45 293.3340 0.3750 :fm-index 0.6 :distance 1.0 :reverb-amount 0.0015 :amp-env '( 0 0 0.6667 1 4.6801 0.6 9.6970 0.3 24.7475 0.1 100 0 ) vln-one-sin beg 0.9850 f+ 0.9 733.3330 0.1875 :fm-index 0.8 :distance 1.0 :reverb-amount 0.0010 :amp-env '( 0 0 0.3333 1 4.3603 0.6 9.3939 0.3 24.4950 0.1 100 0 ) vln-one-sin beg 0.9850 f+ 0.225 550 0.1875 :fm-index 0.8 :distance 1.0 :reverb-amount 0.0013 :amp-env '( 0 0 1.3333 1 5.3199 0.6 10.3030 0.3 25.2525 0.1 100 0 ) vln-one-sin ;event : long-example ( -- ) <'> fth-long-example *clm-c-version* if \ we have only a C version of freeverb :reverb <'> freeverb :reverb-data '( :room-decay 0.8 ) else :reverb <'> nrev :reverb-data '( :lp-coeff 0.6 ) then with-sound ; : short-example ( -- ) <'> fth-short-example :reverb <'> nrev :reverb-data '( :lp-coeff 0.6 ) with-sound ; 'snd provided? [unless] *argc* 2 > [if] short-example [else] long-example [then] [then] \ fmviolin.fth ends here snd-16.1/sndins/samples/fmviolin.rb0000755000076400007640000027023412433105741015460 0ustar bilbil#! /usr/bin/env ruby # fmviolin.rb -- CLM fmviolin.clm --> RBM fmviolin.rb # Translator/Author: Michael Scholz # Created: 02/10/18 11:29:08 # Changed: 14/11/18 23:51:41 # A translation of Bill Schottstaedt's clm/fmviolin.clm from Lisp # into Ruby. # short_example # long_example $clm_c_version = true require "sndlib" if $clm_c_version require "sndins" else require "v" # fm_violin, jc_reverb require "clm-ins" # nrev require "freeverb" # freeverb end require "clm" require "ws" $clm_file_name = "test-ins-r.snd" $clm_play = true $clm_statistics = true $clm_verbose = true $clm_srate = 44100 $clm_channels = 2 $clm_reverb_channels = 2 $clm_delete_reverb = true $clm_header_type = Mus_next $clm_sample_type = Mus_bfloat # show progress of long example $show = true $t = 0.0 def main ARGV.length > 0 ? short_example() : long_example() end CELLO = 0 VIOLIN = 1 def restore_fm_violin_defaults $fm_index = 1.0 $amp_env = [0, 0, 25, 1, 75, 1, 100, 0] $periodic_vibrato_rate = 5.0 $periodic_vibrato_amplitude = 0.0025 $random_vibrato_rate = 16.0 $random_vibrato_amplitude = 0.005 $noise_freq = 1000.0 $noise_amount = 0.0 $ind_noise_freq = 10.0 $ind_noise_amount = 0.0 $amp_noise_freq = 20.0 $amp_noise_amount = 0.0 $gliss_env = [0, 0, 100, 0] $glissando_amount = 0.0 $fm1_env = [0, 1, 25, 0.4, 75, 0.6, 100, 0] $fm2_env = [0, 1, 25, 0.4, 75, 0.6, 100, 0] $fm3_env = [0, 1, 25, 0.4, 75, 0.6, 100, 0] $fm1_rat = 1.0 $fm2_rat = 3.0 $fm3_rat = 4.0 $fm1_index = false $fm2_index = false $fm3_index = false $base = 0.0 $degree = 0.0 $distance = 1.0 $reverb_amount = 0.01 $index_type = VIOLIN $no_waveshaping = false end def old_fm_violin(start, dur, freq, amp, *args) fm_violin(start, dur, freq, amp, :fm_index, get_args(args, :fm_index, $fm_index), :amp_env, get_args(args, :amp_env, $amp_env), :periodic_vibrato_rate, get_args(args, :periodic_vibrato_rate, $periodic_vibrato_rate), :periodic_vibrato_amplitude, get_args(args, :periodic_vibrato_amplitude, $periodic_vibrato_amplitude), :random_vibrato_rate, get_args(args, :random_vibrato_rate, $random_vibrato_rate), :random_vibrato_amplitude, get_args(args, :random_vibrato_amplitude, $random_vibrato_amplitude), :noise_freq, get_args(args, :noise_freq, $noise_freq), :noise_amount, get_args(args, :noise_amount, $noise_amount), :ind_noise_freq, get_args(args, :ind_noise_freq, $ind_noise_freq), :ind_noise_amount, get_args(args, :ind_noise_amount, $ind_noise_amount), :amp_noise_freq, get_args(args, :amp_noise_freq, $amp_noise_freq), :amp_noise_amount, get_args(args, :amp_noise_amount, $amp_noise_amount), :gliss_env, get_args(args, :gliss_env, $gliss_env), :glissando_amount, get_args(args, :glissando_amount, $glissando_amount), :fm1_env, get_args(args, :fm1_env, $fm1_env), :fm2_env, get_args(args, :fm2_env, $fm2_env), :fm3_env, get_args(args, :fm3_env, $fm3_env), :fm1_rat, get_args(args, :fm1_rat, $fm1_rat), :fm2_rat, get_args(args, :fm2_rat, $fm2_rat), :fm3_rat, get_args(args, :fm3_rat, $fm3_rat), :fm1_index, get_args(args, :fm1_index, $fm1_index), :fm2_index, get_args(args, :fm2_index, $fm2_index), :fm3_index, get_args(args, :fm3_index, $fm3_index), :base, get_args(args, :base, $base), :degree, get_args(args, :degree, $degree), :distance, get_args(args, :distance, $distance), :reverb_amount, get_args(args, :reverb_amount, $reverb_amount), :index_type, get_args(args, :index_type, $index_type), :no_waveshaping, get_args(args, :no_waveshaping, $no_waveshaping)) end def vln_one_sin(start, dur, freq, amp, *args) old_fm_violin(start, dur, freq, amp * 0.125, *args + [:degree, random(90.0), :noise_amount, 0.0]) end def vln_one_sin_ran(start, dur, freq, amp, *args) old_fm_violin(start, dur, freq, amp * 0.125, *args + [:degree, random(90.0)]) end def vln_one_sin_exp(start, dur, freq, amp, *args) vln_one_sin(start, dur, freq, amp, *args + [:base, 0.03125]) end alias violin vln_one_sin def cel_one_sum(start, dur, freq, amp, *args) old_fm_violin(start, dur, freq, amp * 0.125, *args + [:degree, random(90.0), :index_type, CELLO]) end restore_fm_violin_defaults() def violin_new(beg, dur, freq, amp, *args) fm_index = get_args(args, :fm_index, 1.0) amp_env = get_args(args, :amp_env, [0, 0, 221, 1, 240, 0]) reverb_amount = get_args(args, :reverb_amount, 0.2) nfreq = if(freq > 400.0) freq * (0.99 + 0.02 * random(1.0)) else if(freq > 200.0) freq * (0.995 + 0.01 * random(1.0)) else freq * (0.999 + 0.002 * random(1.0)) end end 6.times do |i| fm_violin(beg + i * 0.05 * random(1.0), dur + i * 0.1 * random(1.0), nfreq, amp, :reverb_amount, reverb_amount, :fm_index, fm_index * (0.75 + random(1.0)), :amp_env, amp_env) end end def short_example with_sound(:reverb, :nrev, :reverb_data, [:lp_coeff, 0.6]) do violin_new(0, 8.53, 993.323, 0.03, :fm_index, 0.75, :reverb_amount, 0.2, :amp_env, [0, 0, 221, 1, 240, 0]) violin_new(5, 4.53, 993.323 * 5.0 / 6.0, 0.02, :fm_index, 0.55, :reverb_amount, 0.2, :amp_env, [0, 0, 221, 1, 240, 0]) end end def my_times if defined? Process.times Process.times else Time.times end end def long_example i = 0 st = my_times trace_var(:$t) do |t| if $show message("%2d: score %3d utime %7.3f", i += 1, t, my_times.utime - st.utime) end end with_sound(:reverb, :freeverb, :reverb_data, [:room_decay, 0.8]) do tap = [0, 0, 1, 1, 99, 1, 100, 0] metalamp = [0, 0, 0.5000, 1, 5, 1, 10, 0.5000, 15, 0.2500, 35, 0.1, 100, 0] whoosh = [0, 0, 75, 0.1, 90, 0.3, 97, 0.6, 100, 1] mamp = [0, 0, 50, 1, 100, 0] n_amp = [0, 0, 65, 1, 100, 0] $t = 0.0 restore_fm_violin_defaults() $glissando_amount = 0.0 $reverb_amount = 0.1 $amp_env = metalamp $fm1_rat = 6.718 $fm2_rat = 4.414 $fm3_rat = 5.141 vln_one_sin($t + 0, 1.6, 164.5868, 0.16, :fm_index, 2.1087) vln_one_sin($t + 0.0003, 4, 164.5868, 0.2600, :fm_index, 1.5488) vln_one_sin($t + 0.0005, 1.2, 125.9513, 0.2600, :fm_index, 2.2999) vln_one_sin($t + 0.0005, 2.8, 125.9513, 0.16, :fm_index, 1.6818) vln_one_sin($t + 0.0013, 4, 24.4994, 0.3, :fm_index, 2.4557) vln_one_sin($t + 0.0033, 3, 24.4994, 0.3, :fm_index, 1.9387) vln_one_sin($t + 0.0035, 2.8, 24.4994, 0.2600, :fm_index, 2.3828) vln_one_sin($t + 0.0040, 0.8, 24.4994, 0.16, :fm_index, 1.7348) vln_one_sin($t + 0.0043, 4, 24.4994, 0.3, :fm_index, 2.0886) $t += 6.0 $fm1_rat = 2.718 $fm2_rat = 4.414 $fm3_rat = 3.141 vln_one_sin($t + 0.0003, 1.2, 88.8854, 0.16, :fm_index, 2.0711) vln_one_sin($t + 0.0003, 4, 88.8854, 0.2600, :fm_index, 2.0225) vln_one_sin($t + 0.0005, 1.2, 102.7186, 0.2600, :fm_index, 1.9300) vln_one_sin($t + 0.0010, 1.2, 32.7025, 0.3600, :fm_index, 1.9269) vln_one_sin($t + 0.0015, 2.8, 32.7025, 0.2600, :fm_index, 2.2153) vln_one_sin($t + 0.0023, 2, 32.7025, 0.2600, :fm_index, 2.1968) vln_one_sin($t + 0.0023, 4, 32.7025, 0.3600, :fm_index, 1.6091) vln_one_sin($t + 0.0025, 2, 32.7025, 0.2600, :fm_index, 2.1766) vln_one_sin($t + 0.0035, 1.2, 32.7025, 0.16, :fm_index, 1.5157) vln_one_sin($t + 0.0040, 0.8, 32.7025, 0.16, :fm_index, 1.8092) vln_one_sin($t + 0.0043, 2, 32.7025, 0.2600, :fm_index, 1.6198) $t += 6.0 $reverb_amount = 0.2 $fm3_rat = 5.141 vln_one_sin($t + 0.0003, 1.2, 177.7708, 0.3, :fm_index, 1.9631) vln_one_sin($t + 0.0003, 4, 177.7708, 0.3, :fm_index, 1.9647) vln_one_sin($t + 0.0005, 2.8, 336.2471, 0.16, :fm_index, 2.3977) vln_one_sin($t + 0.0008, 1.2, 336.2471, 0.2500, :fm_index, 2.4103) vln_one_sin($t + 0.0010, 2, 65.4050, 0.3, :fm_index, 1.8419) vln_one_sin($t + 0.0033, 2, 65.4050, 0.3, :fm_index, 2.4540) vln_one_sin($t + 0.0043, 4, 65.4050, 0.16, :fm_index, 2.2909) $t += 6.0 $reverb_amount = 0.1 vln_one_sin($t + 0.0003, 1.2, 11.1107, 0.3, :fm_index, 1.8715) vln_one_sin($t + 0.0003, 4, 11.1107, 0.3, :fm_index, 2.4590) vln_one_sin($t + 0.0005, 2.8, 21.0154, 0.16, :fm_index, 2.3802) vln_one_sin($t + 0.0008, 1.2, 21.0154, 0.2500, :fm_index, 1.7564) vln_one_sin($t + 0.0010, 2, 4.0878, 0.3, :fm_index, 2.2529) vln_one_sin($t + 0.0033, 2, 4.0878, 0.3, :fm_index, 1.9693) vln_one_sin($t + 0.0043, 4, 4.0878, 0.16, :fm_index, 2.2534) $t += 6.0 restore_fm_violin_defaults() $noise_amount = 0.1 vln_one_sin_ran($t + 0, 5.4, 116.5400, 0.2500, :fm_index, 2.2822, :reverb_amount, 0.0280, :amp_env, [0, 0, 0.0556, 1, 4.0937, 0.6, 9.1414, 0.3, 24.2845, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0100, 5.4, 43.6538, 0.2500, :fm_index, 2.0867, :reverb_amount, 0.0202, :amp_env, [0, 0, 0.0556, 1, 4.0937, 0.6, 9.1414, 0.3, 24.2845, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0200, 5.4, 130.8100, 0.2500, :fm_index, 1.9652, :reverb_amount, 0.0270, :amp_env, [0, 0, 0.0556, 1, 4.0937, 0.6, 9.1414, 0.3, 24.2845, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0250, 5.4, 87.3075, 0.2500, :fm_index, 2.1524, :reverb_amount, 0.0260, :amp_env, [0, 0, 0.0556, 1, 4.0937, 0.6, 9.1414, 0.3, 24.2845, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0300, 4.5, 261.6200, 0.15, :fm_index, 2.1384, :reverb_amount, 0.0242, :amp_env, [0, 0, 0.0667, 1, 4.1044, 0.6, 9.1515, 0.3, 24.2929, 0.1, 100, 0]) vln_one_sin_ran($t + 0.0300, 4.5, 174.6150, 0.15, :fm_index, 2.1425, :reverb_amount, 0.0265, :amp_env, [0, 0, 0.0667, 1, 4.1044, 0.6, 9.1515, 0.3, 24.2929, 0.1, 100, 0]) vln_one_sin_ran($t + 0.0300, 4.5, 130.8100, 0.15, :fm_index, 1.9805, :reverb_amount, 0.0201, :amp_env, [0, 0, 0.0667, 1, 4.1044, 0.6, 9.1515, 0.3, 24.2929, 0.1, 100, 0]) vln_one_sin_ran($t + 0.0350, 4.5, 43.6538, 0.15, :fm_index, 2.4876, :reverb_amount, 0.0329, :amp_env, [0, 0, 0.0667, 1, 4.1044, 0.6, 9.1515, 0.3, 24.2929, 0.1, 100, 0]) vln_one_sin_ran($t + 0.0400, 3.6, 220, 0.15, :fm_index, 1.8282, :reverb_amount, 0.0244, :noise_amount, 0.15, :amp_env, [0, 0, 0.0833, 1, 4.1204, 0.6, 9.1667, 0.3, 24.3056, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0400, 3.6, 174.6150, 0.15, :fm_index, 2.3479, :reverb_amount, 0.0200, :noise_amount, 0.15, :amp_env, [0, 0, 0.0833, 1, 4.1204, 0.6, 9.1667, 0.3, 24.3056, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0400, 3.6, 523.2400, 0.15, :fm_index, 1.6424, :reverb_amount, 0.0286, :noise_amount, 0.15, :amp_env, [0, 0, 0.0833, 1, 4.1204, 0.6, 9.1667, 0.3, 24.3056, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0450, 3.6, 349.2300, 0.15, :fm_index, 1.6449, :reverb_amount, 0.0333, :noise_amount, 0.15, :amp_env, [0, 0, 0.0833, 1, 4.1204, 0.6, 9.1667, 0.3, 24.3056, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0500, 6, 699.4600, 0.15, :fm_index, 1.5570, :reverb_amount, 0.1300, :amp_env, tap) vln_one_sin_ran($t + 0.0500, 6, 1397.9200, 0.15, :fm_index, 1.5131, :reverb_amount, 0.1300, :amp_env, tap) vln_one_sin_ran($t + 0.0500, 6, 783.9800, 0.15, :fm_index, 2.2031, :reverb_amount, 0.1300, :amp_env, tap) vln_one_sin_ran($t + 0.0500, 6, 1046.4800, 0.15, :fm_index, 2.2724, :reverb_amount, 0.1300, :amp_env, tap) vln_one_sin_ran($t + 0.0600, 9, 21.8269, 0.15, :fm_index, 2.1048, :reverb_amount, 0.1, :amp_env, tap) vln_one_sin_ran($t + 0.0600, 8, 87.3075, 0.15, :fm_index, 1.8854, :reverb_amount, 0.1, :amp_env, tap) vln_one_sin_ran($t + 0.0600, 7, 65.4050, 0.15, :fm_index, 1.6781, :reverb_amount, 0.1, :amp_env, tap) vln_one_sin_ran($t + 0.0600, 8, 43.6538, 0.15, :fm_index, 1.7862, :reverb_amount, 0.1, :amp_env, tap) vln_one_sin_ran($t + 0.0700, 6, 175.6150, 0.15, :fm_index, 2.2656, :reverb_amount, 0.1, :amp_env, tap) vln_one_sin_ran($t + 0.0700, 6, 350.2300, 0.15, :fm_index, 2.4241, :reverb_amount, 0.1, :amp_env, tap) vln_one_sin_ran($t + 0.0700, 6, 131.8100, 0.15, :fm_index, 2.4294, :reverb_amount, 0.1, :amp_env, tap) vln_one_sin_ran($t + 0.0700, 6, 32.7025, 0.15, :fm_index, 1.5779, :reverb_amount, 0.1, :amp_env, tap) vln_one_sin_ran($t + 0.0800, 6, 196.9950, 0.15, :fm_index, 1.8511, :reverb_amount, 0.1, :amp_env, tap) vln_one_sin_ran($t + 0.0800, 6, 1047.4800, 0.15, :fm_index, 2.2148, :reverb_amount, 0.1, :amp_env, tap) vln_one_sin_ran($t + 0.0800, 6, 831.6200, 0.15, :fm_index, 1.9913, :reverb_amount, 0.1, :amp_env, tap) vln_one_sin_ran($t + 0.0800, 6, 2793.8400, 0.15, :fm_index, 2.2607, :reverb_amount, 0.1, :amp_env, tap) vln_one_sin_ran($t + 0.2700, 6, 784.9800, 0.16, :fm_index, 2.0693, :reverb_amount, 0.1, :amp_env, tap) vln_one_sin_ran($t + 0.2700, 6, 64.4050, 0.16, :fm_index, 1.6920, :reverb_amount, 0.1, :amp_env, tap) vln_one_sin_ran($t + 0.2700, 6, 208.6550, 0.16, :fm_index, 2.2597, :reverb_amount, 0.1, :amp_env, tap) vln_one_sin_ran($t + 0.2700, 6, 43.6538, 0.16, :fm_index, 2.2522, :reverb_amount, 0.1, :amp_env, tap) $t += 12.0 restore_fm_violin_defaults() vln_one_sin_ran($t + 0, 1.8, 349.2300, 0.16, :fm_index, 2.1541, :reverb_amount, 0.0225, :noise_amount, 0.0500, :amp_env, [0, 0, 0.1667, 1, 4.2003, 0.6, 9.2424, 0.3, 24.3687, 0.1, 100, 0]) vln_one_sin_ran($t + 0.0100, 2.7000, 146.8300, 0.16, :fm_index, 2.3335, :reverb_amount, 0.0274, :noise_amount, 0.0500, :amp_env, [0, 0, 0.1111, 1, 4.1470, 0.6, 9.1919, 0.3, 24.3266, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0200, 1.8, 880, 0.16, :fm_index, 2.1910, :reverb_amount, 0.0279, :noise_amount, 0.0500, :amp_env, [0, 0, 0.1667, 1, 4.2003, 0.6, 9.2424, 0.3, 24.3687, 0.1, 100, 0]) vln_one_sin_ran($t + 0.0250, 3.6, 73.4150, 0.16, :fm_index, 2.1410, :reverb_amount, 0.0223, :noise_amount, 0.0500, :amp_env, [0, 0, 0.0833, 1, 4.1204, 0.6, 9.1667, 0.3, 24.3056, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0300, 2.7000, 87.3075, 0.16, :fm_index, 1.8491, :reverb_amount, 0.0217, :noise_amount, 0.0010, :amp_env, [0, 0, 0.1111, 1, 4.1470, 0.6, 9.1919, 0.3, 24.3266, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0300, 2.7000, 75.5662, 0.16, :fm_index, 1.9191, :reverb_amount, 0.0204, :noise_amount, 0.0010, :amp_env, [0, 0, 0.1111, 1, 4.1470, 0.6, 9.1919, 0.3, 24.3266, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0400, 3.6, 52.3432, 0.16, :fm_index, 1.6090, :reverb_amount, 0.0296, :noise_amount, 0.0010, :amp_env, [0, 0, 0.0833, 1, 4.1204, 0.6, 9.1667, 0.3, 24.3056, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0450, 1.8, 73.4150, 0.16, :fm_index, 2.2201, :reverb_amount, 0.0221, :noise_amount, 0.0010, :amp_env, [0, 0, 0.1667, 1, 4.2003, 0.6, 9.2424, 0.3, 24.3687, 0.1, 100, 0]) vln_one_sin_ran($t + 0.0500, 4, 116.5400, 0.0600, :fm_index, 2.0230, :reverb_amount, 0.1, :amp_env, tap, :noise_amount, 0.0010) vln_one_sin_ran($t + 0.0500, 4, 97.9975, 0.0600, :fm_index, 1.7284, :reverb_amount, 0.1, :amp_env, tap, :noise_amount, 0.0010) vln_one_sin_ran($t + 0.0600, 4, 36.7075, 0.0600, :fm_index, 1.6845, :reverb_amount, 0.1, :amp_env, tap, :noise_amount, 0.0010) vln_one_sin_ran($t + 0.0650, 4, 97.9975, 0.0600, :fm_index, 2.4616, :reverb_amount, 0.1, :amp_env, tap, :noise_amount, 0.0010) $t += 7.0 vln_one_sin_ran($t + 0, 1.8, 261.6200, 0.16, :fm_index, 2.2576, :reverb_amount, 0.0286, :noise_amount, 0.0100, :amp_env, [0, 0, 0.1667, 1, 4.2003, 0.6, 9.2424, 0.3, 24.3687, 0.1, 100, 0]) vln_one_sin_ran($t + 0.0100, 2.7000, 130.8100, 0.16, :fm_index, 2.1530, :reverb_amount, 0.0330, :noise_amount, 0.0100, :amp_env, [0, 0, 0.1111, 1, 4.1470, 0.6, 9.1919, 0.3, 24.3266, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0200, 1.8, 523.2400, 0.16, :fm_index, 2.0608, :reverb_amount, 0.0235, :noise_amount, 0.0100, :amp_env, [0, 0, 0.1667, 1, 4.2003, 0.6, 9.2424, 0.3, 24.3687, 0.1, 100, 0]) vln_one_sin_ran($t + 0.0250, 3.6, 65.4050, 0.16, :fm_index, 2.2203, :reverb_amount, 0.0234, :noise_amount, 0.0100, :amp_env, [0, 0, 0.0833, 1, 4.1204, 0.6, 9.1667, 0.3, 24.3056, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0300, 2.7000, 65.4050, 0.16, :fm_index, 1.7089, :reverb_amount, 0.0208, :noise_amount, 0.0010, :amp_env, [0, 0, 0.1111, 1, 4.1470, 0.6, 9.1919, 0.3, 24.3266, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0300, 2.7000, 130.8100, 0.16, :fm_index, 2.2948, :reverb_amount, 0.0269, :noise_amount, 0.0010, :amp_env, [0, 0, 0.1111, 1, 4.1470, 0.6, 9.1919, 0.3, 24.3266, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0400, 3.6, 32.7025, 0.16, :fm_index, 1.7677, :reverb_amount, 0.0288, :noise_amount, 0.0010, :amp_env, [0, 0, 0.0833, 1, 4.1204, 0.6, 9.1667, 0.3, 24.3056, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0450, 1.8, 32.7025, 0.16, :fm_index, 1.9030, :reverb_amount, 0.0209, :noise_amount, 0.0010, :amp_env, [0, 0, 0.1667, 1, 4.2003, 0.6, 9.2424, 0.3, 24.3687, 0.1, 100, 0]) vln_one_sin_ran($t + 0.0500, 4, 65.4050, 0.0600, :fm_index, 2.2757, :reverb_amount, 0.1, :amp_env, tap, :noise_amount, 0.0010) vln_one_sin_ran($t + 0.0500, 4, 65.4050, 0.0600, :fm_index, 2.2435, :reverb_amount, 0.1, :amp_env, tap, :noise_amount, 0.0010) vln_one_sin_ran($t + 0.0600, 4, 32.7025, 0.0600, :fm_index, 1.9619, :reverb_amount, 0.1, :amp_env, tap, :noise_amount, 0.0010) vln_one_sin_ran($t + 0.0650, 4, 65.4050, 0.0600, :fm_index, 2.0207, :reverb_amount, 0.1, :amp_env, tap, :noise_amount, 0.0010) $t += 6.0 vln_one_sin_ran($t + 0.0100, 0.9, 3135.9200, 0.16, :fm_index, 2.1204, :reverb_amount, 0.0024, :noise_amount, 0.0100, :amp_env, [0, 0, 0.3333, 1, 4.3603, 0.6, 9.3939, 0.3, 24.4950, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0100, 0.4500, 1567.96, 0.16, :fm_index, 2.0691, :reverb_amount, 0.0025, :noise_amount, 0.0100, :amp_env, [0, 0, 0.6667, 1, 4.6801, 0.6, 9.6970, 0.3, 24.7475, 0.1, 100, 0]) vln_one_sin_ran($t + 0.0200, 0.9, 6271.8400, 0.16, :fm_index, 2.2081, :reverb_amount, 0.0022, :noise_amount, 0.0100, :amp_env, [0, 0, 0.3333, 1, 4.3603, 0.6, 9.3939, 0.3, 24.4950, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0250, 0.9, 783.9800, 0.16, :fm_index, 1.8719, :reverb_amount, 0.0022, :noise_amount, 0.0100, :amp_env, [0, 0, 0.3333, 1, 4.3603, 0.6, 9.3939, 0.3, 24.4950, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0300, 0.2700, 783.9800, 0.16, :fm_index, 1.9705, :reverb_amount, 0.0020, :noise_amount, 0.0100, :amp_env, [0, 0, 1.1111, 1, 5.1066, 0.6, 10.1010, 0.3, 25.0842, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0300, 0.6300, 1567.96, 0.16, :fm_index, 1.6778, :reverb_amount, 0.0021, :noise_amount, 0.0100, :amp_env, [0, 0, 0.4762, 1, 4.4974, 0.6, 9.5238, 0.3, 24.6032, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0400, 0.9, 391.9900, 0.16, :fm_index, 1.9558, :reverb_amount, 0.0023, :noise_amount, 0.0100, :amp_env, [0, 0, 0.3333, 1, 4.3603, 0.6, 9.3939, 0.3, 24.4950, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0450, 0.4500, 195.9950, 0.16, :fm_index, 2.1344, :reverb_amount, 0.0027, :noise_amount, 0.0100, :amp_env, [0, 0, 0.6667, 1, 4.6801, 0.6, 9.6970, 0.3, 24.7475, 0.1, 100, 0]) vln_one_sin_ran($t + 0.0500, 2, 783.9800, 0.16, :reverb_amount, 0.0100, :amp_env, tap, :noise_amount, 0.0090) vln_one_sin_ran($t + 0.0500, 1, 1567.9600, 0.16, :reverb_amount, 0.0100, :amp_env, tap, :noise_amount, 0.0090) vln_one_sin_ran($t + 0.0600, 2, 391.9900, 0.16, :reverb_amount, 0.0100, :amp_env, tap, :noise_amount, 0.0090) vln_one_sin_ran($t + 0.0650, 1, 783.9800, 0.16, :reverb_amount, 0.0100, :amp_env, tap, :noise_amount, 0.0090) vln_one_sin_ran($t + 0.0700, 2, 195.9950, 0.16, :reverb_amount, 0.0100, :amp_env, tap, :noise_amount, 0.0040) vln_one_sin_ran($t + 0.0700, 1, 1567.9600, 0.16, :reverb_amount, 0.0100, :amp_env, tap, :noise_amount, 0.0040) vln_one_sin_ran($t + 0.0800, 1, 784.9800, 0.16, :reverb_amount, 0.0100, :amp_env, tap, :noise_amount, 0.0040) vln_one_sin_ran($t + 0.0850, 2, 391.9900, 0.16, :reverb_amount, 0.0100, :amp_env, tap, :noise_amount, 0.0040) $t += 6.0 vln_one_sin_ran($t + 0.0100, 0.9, 97.9975, 0.1, :fm_index, 2.0885, :reverb_amount, 0.0031, :noise_amount, 0.0100, :amp_env, [0, 0, 0.3333, 1, 4.3603, 0.6, 9.3939, 0.3, 24.4950, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0100, 1.8, 48.9988, 0.1, :fm_index, 2.2269, :reverb_amount, 0.0026, :noise_amount, 0.0100, :amp_env, [0, 0, 0.1667, 1, 4.2003, 0.6, 9.2424, 0.3, 24.3687, 0.1, 100, 0]) vln_one_sin_ran($t + 0.0200, 0.9, 195.9950, 0.1, :fm_index, 2.0305, :reverb_amount, 0.0032, :noise_amount, 0.0100, :amp_env, [0, 0, 0.3333, 1, 4.3603, 0.6, 9.3939, 0.3, 24.4950, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0250, 0.9, 24.4994, 0.1, :fm_index, 2.4934, :reverb_amount, 0.0025, :noise_amount, 0.0100, :amp_env, [0, 0, 0.3333, 1, 4.3603, 0.6, 9.3939, 0.3, 24.4950, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0300, 1.8, 97.9975, 0.1, :fm_index, 2.4039, :reverb_amount, 0.0023, :noise_amount, 0.0400, :amp_env, [0, 0, 0.1667, 1, 4.2003, 0.6, 9.2424, 0.3, 24.3687, 0.1, 100, 0]) vln_one_sin_ran($t + 0.0300, 0.9, 195.9950, 0.1, :fm_index, 1.5159, :reverb_amount, 0.0021, :noise_amount, 0.0400, :amp_env, [0, 0, 0.3333, 1, 4.3603, 0.6, 9.3939, 0.3, 24.4950, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0300, 0.9, 392.9900, 0.1, :fm_index, 2.2122, :reverb_amount, 0.0028, :noise_amount, 0.0400, :amp_env, [0, 0, 0.3333, 1, 4.3603, 0.6, 9.3939, 0.3, 24.4950, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0300, 1.8, 784.9800, 0.1, :fm_index, 2.1574, :reverb_amount, 0.0020, :noise_amount, 0.0400, :amp_env, [0, 0, 0.1667, 1, 4.2003, 0.6, 9.2424, 0.3, 24.3687, 0.1, 100, 0]) vln_one_sin_ran($t + 0.0300, 2.7000, 24.4994, 0.1, :fm_index, 2.1963, :reverb_amount, 0.0031, :noise_amount, 0.0100, :amp_env, [0, 0, 0.1111, 1, 4.1470, 0.6, 9.1919, 0.3, 24.3266, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0300, 1.8, 48.9988, 0.1, :fm_index, 1.9761, :reverb_amount, 0.0032, :noise_amount, 0.0100, :amp_env, [0, 0, 0.1667, 1, 4.2003, 0.6, 9.2424, 0.3, 24.3687, 0.1, 100, 0]) vln_one_sin_ran($t + 0.0400, 2.7000, 12.2497, 0.1, :fm_index, 1.5088, :reverb_amount, 0.0021, :noise_amount, 0.0100, :amp_env, [0, 0, 0.1111, 1, 4.1470, 0.6, 9.1919, 0.3, 24.3266, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0450, 1.8, 6.1248, 0.1, :fm_index, 1.7384, :reverb_amount, 0.0021, :noise_amount, 0.0100, :amp_env, [0, 0, 0.1667, 1, 4.2003, 0.6, 9.2424, 0.3, 24.3687, 0.1, 100, 0]) vln_one_sin_ran($t + 0.0500, 2, 24.4994, 0.1, :reverb_amount, 0.1, :amp_env, tap, :noise_amount, 0.0040) vln_one_sin_ran($t + 0.0500, 1, 48.9988, 0.1, :reverb_amount, 0.1, :amp_env, tap, :noise_amount, 0.0040) vln_one_sin_ran($t + 0.0600, 2, 12.2497, 0.1, :reverb_amount, 0.1, :amp_env, tap, :noise_amount, 0.0040) vln_one_sin_ran($t + 0.0650, 1, 24.4994, 0.1, :reverb_amount, 0.1, :amp_env, tap, :noise_amount, 0.0040) vln_one_sin_ran($t + 0.0700, 2, 6.1248, 0.1, :fm_index, 1.2474, :reverb_amount, 0.1, :amp_env, tap, :noise_amount, 0.0040) vln_one_sin_ran($t + 0.0800, 1, 25.4994, 0.1, :fm_index, 1.1080, :reverb_amount, 0.1, :amp_env, tap, :noise_amount, 0.0040) vln_one_sin_ran($t + 0.0850, 2, 12.2497, 0.1, :fm_index, 1.0859, :reverb_amount, 0.1, :amp_env, tap, :noise_amount, 0.0040) vln_one_sin_ran($t + 0.0900, 4, 97.9975, 0.1, :fm_index, 2.4788, :reverb_amount, 0.1, :amp_env, tap, :noise_amount, 0.0040) vln_one_sin_ran($t + 0.0900, 3, 48.9988, 0.1, :fm_index, 1.8980, :reverb_amount, 0.1, :amp_env, tap, :noise_amount, 0.0040) vln_one_sin_ran($t + 0.0900, 3, 25.4994, 0.1, :fm_index, 2.1151, :reverb_amount, 0.1, :amp_env, tap, :noise_amount, 0.0040) vln_one_sin_ran($t + 0.0950, 5, 12.2497, 0.1, :fm_index, 2.3224, :reverb_amount, 0.1, :amp_env, tap, :noise_amount, 0.0040) $t += 6.0 vln_one_sin_ran($t + 0.2100, 0.9, 123.4725, 0.1, :reverb_amount, 0.0031, :amp_env, [0, 0, 0.3333, 1, 4.3603, 0.6, 9.3939, 0.3, 24.4950, 0.1, 100.0, 0], :noise_amount, 0.0100) vln_one_sin_ran($t + 0.2100, 1.8, 61.7363, 0.1, :reverb_amount, 0.0023, :amp_env, [0, 0, 0.1667, 1, 4.2003, 0.6, 9.2424, 0.3, 24.3687, 0.1, 100, 0], :noise_amount, 0.0100) vln_one_sin_ran($t + 0.2200, 0.9, 246.9450, 0.1, :reverb_amount, 0.0023, :amp_env, [0, 0, 0.3333, 1, 4.3603, 0.6, 9.3939, 0.3, 24.4950, 0.1, 100.0, 0], :noise_amount, 0.0100) vln_one_sin_ran($t + 0.2250, 0.9, 30.8681, 0.1, :reverb_amount, 0.0026, :amp_env, [0, 0, 0.3333, 1, 4.3603, 0.6, 9.3939, 0.3, 24.4950, 0.1, 100.0, 0], :noise_amount, 0.0100) vln_one_sin_ran($t + 0.2300, 1.8, 123.4725, 0.1, :reverb_amount, 0.0027, :amp_env, [0, 0, 0.1667, 1, 4.2003, 0.6, 9.2424, 0.3, 24.3687, 0.1, 100, 0], :noise_amount, 0.0400) vln_one_sin_ran($t + 0.2300, 0.9, 246.9450, 0.1, :reverb_amount, 0.0026, :amp_env, [0, 0, 0.3333, 1, 4.3603, 0.6, 9.3939, 0.3, 24.4950, 0.1, 100.0, 0], :noise_amount, 0.0400) vln_one_sin_ran($t + 0.2300, 0.9, 494.8900, 0.1, :reverb_amount, 0.0020, :amp_env, [0, 0, 0.3333, 1, 4.3603, 0.6, 9.3939, 0.3, 24.4950, 0.1, 100.0, 0], :noise_amount, 0.0400) vln_one_sin_ran($t + 0.2300, 1.8, 988.7800, 0.1, :reverb_amount, 0.0025, :amp_env, [0, 0, 0.1667, 1, 4.2003, 0.6, 9.2424, 0.3, 24.3687, 0.1, 100, 0], :noise_amount, 0.0400) vln_one_sin_ran($t + 0.2300, 2.7000, 30.8681, 0.1, :reverb_amount, 0.0028, :amp_env, [0, 0, 0.1111, 1, 4.1470, 0.6, 9.1919, 0.3, 24.3266, 0.1, 100.0, 0], :noise_amount, 0.0100) vln_one_sin_ran($t + 0.2300, 1.8, 61.7363, 0.1, :reverb_amount, 0.0023, :amp_env, [0, 0, 0.1667, 1, 4.2003, 0.6, 9.2424, 0.3, 24.3687, 0.1, 100, 0], :noise_amount, 0.0100) vln_one_sin_ran($t + 0.2400, 2.7000, 15.4341, 0.1, :reverb_amount, 0.0030, :amp_env, [0, 0, 0.1111, 1, 4.1470, 0.6, 9.1919, 0.3, 24.3266, 0.1, 100.0, 0], :noise_amount, 0.0100) vln_one_sin_ran($t + 0.2450, 1.8, 20.5788, 0.1, :reverb_amount, 0.0023, :amp_env, [0, 0, 0.1667, 1, 4.2003, 0.6, 9.2424, 0.3, 24.3687, 0.1, 100, 0], :noise_amount, 0.0100) vln_one_sin_ran($t + 0.2500, 2, 30.8681, 0.1, :reverb_amount, 0.1, :amp_env, tap, :noise_amount, 0.0090) vln_one_sin_ran($t + 0.2500, 1, 61.7363, 0.1, :reverb_amount, 0.1, :amp_env, tap, :noise_amount, 0.0090) vln_one_sin_ran($t + 0.2600, 2, 15.4341, 0.1, :reverb_amount, 0.1, :amp_env, tap, :noise_amount, 0.0090) vln_one_sin_ran($t + 0.2650, 1, 30.8681, 0.1, :reverb_amount, 0.1, :amp_env, tap, :noise_amount, 0.0090) vln_one_sin_ran($t + 0.2710, 2, 30.8681, 0.1, :reverb_amount, 0.1, :amp_env, tap, :noise_amount, 0.0040) vln_one_sin_ran($t + 0.2710, 1, 61.7363, 0.1, :reverb_amount, 0.1, :amp_env, tap, :noise_amount, 0.0040) vln_one_sin_ran($t + 0.2810, 1, 31.8681, 0.1, :reverb_amount, 0.1, :amp_env, tap, :noise_amount, 0.0040) vln_one_sin_ran($t + 0.2860, 2, 15.4341, 0.1, :reverb_amount, 0.1, :amp_env, tap, :noise_amount, 0.0040) $t += 8.0 yup = [0, 0, 1, 1, 100, 0] vln_one_sin_ran($t + 0.0100, 0.9, 3135.9200, 0.16, :fm_index, 1.7299, :reverb_amount, 0.0026, :noise_amount, 0.0100, :amp_env, [0, 0, 0.3333, 1, 4.3603, 0.6, 9.3939, 0.3, 24.4950, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0100, 0.45, 1464.6987, 0.16, :fm_index, 1.9173, :reverb_amount, 0.0027, :noise_amount, 0.0100, :amp_env, [0, 0, 0.6667, 1, 4.6801, 0.6, 9.6970, 0.3, 24.7475, 0.1, 100, 0]) vln_one_sin_ran($t + 0.0200, 0.9, 6714.0048, 0.16, :fm_index, 2.4604, :reverb_amount, 0.0032, :noise_amount, 0.0100, :amp_env, [0, 0, 0.3333, 1, 4.3603, 0.6, 9.3939, 0.3, 24.4950, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0250, 0.9, 684.1190, 0.16, :fm_index, 1.9969, :reverb_amount, 0.0021, :noise_amount, 0.0100, :amp_env, [0, 0, 0.3333, 1, 4.3603, 0.6, 9.3939, 0.3, 24.4950, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0300, 0.2700, 684.1190, 0.16, :fm_index, 2.0022, :reverb_amount, 0.0026, :noise_amount, 0.0100, :amp_env, [0, 0, 1.1111, 1, 5.1066, 0.6, 10.1010, 0.3, 25.0842, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0300, 0.63, 1464.6987, 0.16, :fm_index, 2.1058, :reverb_amount, 0.0027, :noise_amount, 0.0100, :amp_env, [0, 0, 0.4762, 1, 4.4974, 0.6, 9.5238, 0.3, 24.6032, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0400, 0.9, 319.5325, 0.16, :fm_index, 2.2293, :reverb_amount, 0.0029, :noise_amount, 0.0100, :amp_env, [0, 0, 0.3333, 1, 4.3603, 0.6, 9.3939, 0.3, 24.4950, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0450, 0.4500, 149.2445, 0.16, :fm_index, 1.5780, :reverb_amount, 0.0025, :noise_amount, 0.0100, :amp_env, [0, 0, 0.6667, 1, 4.6801, 0.6, 9.6970, 0.3, 24.7475, 0.1, 100, 0]) vln_one_sin_ran($t + 0.0500, 1, 684.1190, 0.16, :reverb_amount, 0.0100, :amp_env, yup, :noise_amount, 0.0090) vln_one_sin_ran($t + 0.0500, 1, 1464.6987, 0.16, :reverb_amount, 0.0100, :amp_env, yup, :noise_amount, 0.0090) vln_one_sin_ran($t + 0.0600, 1, 319.5325, 0.16, :reverb_amount, 0.0100, :amp_env, yup, :noise_amount, 0.0090) vln_one_sin_ran($t + 0.0650, 1, 684.1190, 0.16, :reverb_amount, 0.0100, :amp_env, yup, :noise_amount, 0.0090) vln_one_sin_ran($t + 0.0700, 1, 149.2445, 0.16, :reverb_amount, 0.0100, :amp_env, yup, :noise_amount, 0.0040) vln_one_sin_ran($t + 0.0700, 1, 1464.6987, 0.16, :reverb_amount, 0.0100, :amp_env, yup, :noise_amount, 0.0040) vln_one_sin_ran($t + 0.0800, 1, 561.6022, 0.16, :reverb_amount, 0.0100, :amp_env, yup, :noise_amount, 0.0040) vln_one_sin_ran($t + 0.0850, 1, 319.5325, 0.16, :reverb_amount, 0.0100, :amp_env, yup, :noise_amount, 0.0040) $t += 3.0 vln_one_sin_ran($t + 0.0100, 0.9, 3135.9200, 0.16, :fm_index, 1.6329, :reverb_amount, 0.0031, :noise_amount, 0.0100, :amp_env, [0, 0, 0.3333, 1, 4.3603, 0.6, 9.3939, 0.3, 24.4950, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0100, 0.45, 1810.5774, 0.16, :fm_index, 1.8298, :reverb_amount, 0.0031, :noise_amount, 0.0100, :amp_env, [0, 0, 0.6667, 1, 4.6801, 0.6, 9.6970, 0.3, 24.7475, 0.1, 100, 0]) vln_one_sin_ran($t + 0.0200, 0.9, 5431.4135, 0.16, :fm_index, 2.1640, :reverb_amount, 0.0022, :noise_amount, 0.0100, :amp_env, [0, 0, 0.3333, 1, 4.3603, 0.6, 9.3939, 0.3, 24.4950, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0250, 0.9, 1045.3680, 0.16, :fm_index, 1.6971, :reverb_amount, 0.0032, :noise_amount, 0.0100, :amp_env, [0, 0, 0.3333, 1, 4.3603, 0.6, 9.3939, 0.3, 24.4950, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0300, 0.27, 1045.3680, 0.16, :fm_index, 2.4855, :reverb_amount, 0.0028, :noise_amount, 0.0100, :amp_env, [0, 0, 1.1111, 1, 5.1066, 0.6, 10.1010, 0.3, 25.0842, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0300, 0.63, 1810.5774, 0.16, :fm_index, 2.1604, :reverb_amount, 0.0020, :noise_amount, 0.0100, :amp_env, [0, 0, 0.4762, 1, 4.4974, 0.6, 9.5238, 0.3, 24.6032, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0400, 0.9, 603.5612, 0.16, :fm_index, 2.4204, :reverb_amount, 0.0031, :noise_amount, 0.0100, :amp_env, [0, 0, 0.3333, 1, 4.3603, 0.6, 9.3939, 0.3, 24.4950, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0450, 0.4500, 348.4765, 0.16, :fm_index, 2.3918, :reverb_amount, 0.0026, :noise_amount, 0.0100, :amp_env, [0, 0, 0.6667, 1, 4.6801, 0.6, 9.6970, 0.3, 24.7475, 0.1, 100, 0]) vln_one_sin_ran($t + 0.0460, 0.9, 201.1989, 0.16, :fm_index, 1.5205, :reverb_amount, 0.0024, :noise_amount, 0.0100, :amp_env, [0, 0, 0.3333, 1, 4.3603, 0.6, 9.3939, 0.3, 24.4950, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0460, 0.9, 116.1656, 0.16, :fm_index, 2.3049, :reverb_amount, 0.0028, :noise_amount, 0.0100, :amp_env, [0, 0, 0.3333, 1, 4.3603, 0.6, 9.3939, 0.3, 24.4950, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0500, 0.9, 3135.9200, 0.16, :fm_index, 2.4363, :reverb_amount, 0.0021, :noise_amount, 0.0100, :amp_env, [0, 0, 0.3333, 1, 4.3603, 0.6, 9.3939, 0.3, 24.4950, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0500, 0.45, 1464.6987, 0.16, :fm_index, 2.3865, :reverb_amount, 0.0027, :noise_amount, 0.0100, :amp_env, [0, 0, 0.6667, 1, 4.6801, 0.6, 9.6970, 0.3, 24.7475, 0.1, 100, 0]) vln_one_sin_ran($t + 0.0600, 0.9, 6714.0048, 0.16, :fm_index, 1.7354, :reverb_amount, 0.0021, :noise_amount, 0.0100, :amp_env, [0, 0, 0.3333, 1, 4.3603, 0.6, 9.3939, 0.3, 24.4950, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0650, 0.9, 684.1190, 0.16, :fm_index, 1.8282, :reverb_amount, 0.0025, :noise_amount, 0.0100, :amp_env, [0, 0, 0.3333, 1, 4.3603, 0.6, 9.3939, 0.3, 24.4950, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0700, 0.2700, 684.1190, 0.16, :fm_index, 2.3923, :reverb_amount, 0.0025, :noise_amount, 0.0100, :amp_env, [0, 0, 1.1111, 1, 5.1066, 0.6, 10.1010, 0.3, 25.0842, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0700, 0.63, 1464.6987, 0.16, :fm_index, 2.2789, :reverb_amount, 0.0028, :noise_amount, 0.0100, :amp_env, [0, 0, 0.4762, 1, 4.4974, 0.6, 9.5238, 0.3, 24.6032, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0800, 0.9, 319.5325, 0.16, :fm_index, 1.5438, :reverb_amount, 0.0027, :noise_amount, 0.0100, :amp_env, [0, 0, 0.3333, 1, 4.3603, 0.6, 9.3939, 0.3, 24.4950, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0850, 0.4500, 149.2445, 0.16, :fm_index, 2.4210, :reverb_amount, 0.0028, :noise_amount, 0.0100, :amp_env, [0, 0, 0.6667, 1, 4.6801, 0.6, 9.6970, 0.3, 24.7475, 0.1, 100, 0]) vln_one_sin_ran($t + 0.0860, 0.9, 69.7078, 0.16, :fm_index, 2.0288, :reverb_amount, 0.0029, :noise_amount, 0.0100, :amp_env, [0, 0, 0.3333, 1, 4.3603, 0.6, 9.3939, 0.3, 24.4950, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0860, 0.9, 32.5585, 0.16, :fm_index, 1.8254, :reverb_amount, 0.0028, :noise_amount, 0.0100, :amp_env, [0, 0, 0.3333, 1, 4.3603, 0.6, 9.3939, 0.3, 24.4950, 0.1, 100.0, 0]) $t += 3.0 $reverb_amount = 0.0 $noise_amount = 0.01 vln_one_sin_ran($t + 0.0500, 0.9, 3135.9200, 0.16, :fm_index, 1.7334, :amp_env, [0, 0, 0.3333, 1, 4.3603, 0.6, 9.3939, 0.3, 24.4950, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0500, 0.4500, 1810.5774, 0.16, :fm_index, 2.3629, :amp_env, [0, 0, 0.6667, 1, 4.6801, 0.6, 9.6970, 0.3, 24.7475, 0.1, 100, 0]) vln_one_sin_ran($t + 0.0600, 0.9, 5431.4135, 0.16, :fm_index, 2.2744, :amp_env, [0, 0, 0.3333, 1, 4.3603, 0.6, 9.3939, 0.3, 24.4950, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.0650, 0.9, 1045.3680, 0.16, :fm_index, 1.8722, :amp_env, [0, 0, 0.3333, 1, 4.3603, 0.6, 9.3939, 0.3, 24.4950, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.1100, 0.2700, 1045.3680, 0.16, :fm_index, 2.3139, :amp_env, [0, 0, 1.1111, 1, 5.1066, 0.6, 10.101, 0.3, 25.0842, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.1100, 0.6300, 1810.5774, 0.16, :fm_index, 1.6216, :amp_env, [0, 0, 0.4762, 1, 4.4974, 0.6, 9.5238, 0.3, 24.6032, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.1200, 0.9, 603.5612, 0.16, :fm_index, 1.5308, :amp_env, [0, 0, 0.3333, 1, 4.3603, 0.6, 9.3939, 0.3, 24.4950, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.1650, 0.4500, 348.4765, 0.16, :fm_index, 2.0346, :amp_env, [0, 0, 0.6667, 1, 4.6801, 0.6, 9.6970, 0.3, 24.7475, 0.1, 100, 0]) vln_one_sin_ran($t + 0.1660, 0.9, 201.1989, 0.16, :fm_index, 1.8176, :amp_env, [0, 0, 0.3333, 1, 4.3603, 0.6, 9.3939, 0.3, 24.4950, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.1660, 0.9, 116.1656, 0.16, :fm_index, 1.7145, :amp_env, [0, 0, 0.3333, 1, 4.3603, 0.6, 9.3939, 0.3, 24.4950, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.1700, 0.9, 3135.9200, 0.16, :fm_index, 2.4459, :amp_env, [0, 0, 0.3333, 1, 4.3603, 0.6, 9.3939, 0.3, 24.4950, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.1700, 0.4500, 1464.6987, 0.16, :fm_index, 2.4644, :amp_env, [0, 0, 0.6667, 1, 4.6801, 0.6, 9.6970, 0.3, 24.7475, 0.1, 100, 0]) vln_one_sin_ran($t + 0.1800, 0.9, 6714.0048, 0.16, :fm_index, 1.9985, :amp_env, [0, 0, 0.3333, 1, 4.3603, 0.6, 9.3939, 0.3, 24.4950, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.1850, 0.9, 684.1190, 0.16, :fm_index, 2.4542, :amp_env, [0, 0, 0.3333, 1, 4.3603, 0.6, 9.3939, 0.3, 24.4950, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.2900, 0.2700, 684.1190, 0.16, :fm_index, 2.3391, :amp_env, [0, 0, 1.1111, 1, 5.1066, 0.6, 10.101, 0.3, 25.0842, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.2900, 0.6300, 1464.6987, 0.16, :fm_index, 1.5138, :amp_env, [0, 0, 0.4762, 1, 4.4974, 0.6, 9.5238, 0.3, 24.6032, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.3, 0.9, 319.5325, 0.16, :fm_index, 1.5440, :amp_env, [0, 0, 0.3333, 1, 4.3603, 0.6, 9.3939, 0.3, 24.4950, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.3050, 0.4500, 149.2445, 0.16, :fm_index, 2.2283, :amp_env, [0, 0, 0.6667, 1, 4.6801, 0.6, 9.6970, 0.3, 24.7475, 0.1, 100, 0]) vln_one_sin_ran($t + 0.3060, 0.9, 69.7078, 0.16, :fm_index, 1.9498, :amp_env, [0, 0, 0.3333, 1, 4.3603, 0.6, 9.3939, 0.3, 24.4950, 0.1, 100.0, 0]) vln_one_sin_ran($t + 0.3060, 0.9, 32.5585, 0.16, :fm_index, 2.2943, :amp_env, [0, 0, 0.3333, 1, 4.3603, 0.6, 9.3939, 0.3, 24.4950, 0.1, 100.0, 0]) $t += 3.0 restore_fm_violin_defaults() $amp_env = metalamp $glissando_amount = 0.0 $reverb_amount = 0.01 $fm1_rat = 2.718 $fm2_rat = 1.414 $fm3_rat = 3.141 vln_one_sin($t + 0.2600, 1.2, 355.5416, 0.16, :fm_index, 2.0375) vln_one_sin($t + 0.2600, 1.5, 354.8319, 0.16, :fm_index, 1.8744) vln_one_sin($t + 0.2603, 0.9, 356.2527, 0.16, :fm_index, 1.8743) vln_one_sin($t + 0.2605, 0.9, 409.2356, 0.16, :fm_index, 2.0808) vln_one_sin($t + 0.2605, 2.1, 410.0541, 0.16, :fm_index, 1.9219) vln_one_sin($t + 0.2608, 1.2, 130.8100, 0.16, :fm_index, 1.5746) vln_one_sin($t + 0.2613, 3, 130.2883, 0.16, :fm_index, 2.3771) vln_one_sin($t + 0.2615, 0.9, 130.2883, 0.16, :fm_index, 1.7765) vln_one_sin($t + 0.2615, 2.1, 130.5489, 0.2600, :fm_index, 1.6485) vln_one_sin($t + 0.2625, 2, 130.8100, 0.16, :fm_index, 2.1416) vln_one_sin($t + 0.2633, 2, 130.5488, 0.16, :fm_index, 2.0883) $t += 4.0 newf = [0, 0, 0.5, 1, 5, 1, 10, 0.5, 15, 0.25, 35, 0.1, 100, 0] $noise_amount = 0.0001 $emp_env = newf $reverb_amount = 0.01 vln_one_sin_ran($t + 0.2605, 0.8, 523.2400, 0.16, :fm_index, 2.3056) vln_one_sin_ran($t + 0.2605, 1, 247.1611, 0.16, :fm_index, 1.6308) vln_one_sin_ran($t + 0.2610, 0.6, 1107.6991, 0.16, :fm_index, 1.9364) vln_one_sin_ran($t + 0.2613, 2, 116.7506, 0.16, :fm_index, 2.3740) vln_one_sin_ran($t + 0.2615, 0.6, 116.7506, 0.16, :fm_index, 1.8374) vln_one_sin_ran($t + 0.2615, 1.4, 247.1611, 0.16, :fm_index, 1.7250) vln_one_sin_ran($t + 0.2620, 0.6, 55.1491, 0.16, :fm_index, 1.5495) vln_one_sin_ran($t + 0.2623, 1, 26.0506, 0.16, :fm_index, 1.7235) vln_one_sin_ran($t + 0.2623, 2, 12.3054, 0.16, :fm_index, 1.8818) vln_one_sin_ran($t + 0.2623, 2, 5.8127, 0.16, :fm_index, 1.9537) vln_one_sin_ran($t + 0.2625, 2, 523.2400, 0.16, :fm_index, 2.1593) vln_one_sin_ran($t + 0.2625, 1, 256.2390, 0.16, :fm_index, 1.9851) vln_one_sin_ran($t + 0.2630, 2, 1068.4561, 0.16, :fm_index, 1.8015) vln_one_sin_ran($t + 0.2633, 2, 125.4843, 0.16, :fm_index, 1.6161) vln_one_sin_ran($t + 0.2635, 0.6, 125.4843, 0.16, :fm_index, 2.2767) vln_one_sin_ran($t + 0.2635, 1.4, 256.2390, 0.16, :fm_index, 2.0835) vln_one_sin_ran($t + 0.2640, 0.4, 61.4517, 0.16, :fm_index, 1.5310) vln_one_sin_ran($t + 0.2643, 1, 30.0939, 0.16, :fm_index, 1.5803) vln_one_sin_ran($t + 0.2643, 2, 14.7374, 0.16, :fm_index, 1.9586) vln_one_sin_ran($t + 0.2643, 2, 7.2172, 0.16, :fm_index, 1.7270) vln_one_sin_ran($t + 0.2645, 6, 28.4710, 0.16, :fm_index, 1.5983) vln_one_sin_ran($t + 0.2648, 10, 25.6239, 0.16, :fm_index, 1.7285) vln_one_sin_ran($t + 0.2648, 8, 21.3532, 0.16, :fm_index, 1.7955) vln_one_sin_ran($t + 0.2648, 8, 17.0826, 0.16, :fm_index, 2.0866) $t += 4.0 $reverb_amount = 0.001 $noise_amount = 0.004 $fm1_rat = 3.141 $fm2_rat = 1.414 $fm3_rat = 2.718 vln_one_sin_ran($t + 0.2600, 1.6, 1643.4968, 0.16, :fm_index, 2.1104) vln_one_sin_ran($t + 0.2600, 2, 1643.4968, 0.16, :fm_index, 1.5191) vln_one_sin_ran($t + 0.2603, 1.2, 1643.4968, 0.16, :fm_index, 2.0478) vln_one_sin_ran($t + 0.2603, 4, 1643.4968, 0.16, :fm_index, 2.0473) vln_one_sin_ran($t + 0.2605, 1.2, 1422.1663, 0.16, :fm_index, 1.9845) vln_one_sin_ran($t + 0.2605, 2.8, 1422.1663, 0.16, :fm_index, 2.0429) vln_one_sin_ran($t + 0.2605, 1.2, 1422.1663, 0.16, :fm_index, 1.6184) vln_one_sin_ran($t + 0.2608, 1.6, 523.2400, 0.16, :fm_index, 2.3908) vln_one_sin_ran($t + 0.2608, 2, 523.2400, 0.16, :fm_index, 1.6733) vln_one_sin_ran($t + 0.2610, 1.2, 523.2400, 0.16, :fm_index, 2.0431) vln_one_sin_ran($t + 0.2610, 4, 523.2400, 0.16, :fm_index, 1.7430) vln_one_sin_ran($t + 0.2613, 1.2, 523.2400, 0.16, :fm_index, 2.2030) vln_one_sin_ran($t + 0.2613, 2.8, 523.2400, 0.16, :fm_index, 2.0149) vln_one_sin_ran($t + 0.2615, 1.2, 523.2400, 0.16, :fm_index, 2.2310) vln_one_sin_ran($t + 0.2615, 2, 523.2400, 0.16, :fm_index, 2.1625) vln_one_sin_ran($t + 0.2618, 4, 523.2400, 0.16, :fm_index, 2.0000) vln_one_sin_ran($t + 0.2618, 4, 523.2400, 0.16, :fm_index, 2.2034) vln_one_sin_ran($t + 0.2620, 3, 523.2400, 0.16, :fm_index, 2.0186) vln_one_sin_ran($t + 0.2620, 1.5, 523.2400, 0.16, :fm_index, 2.1373) vln_one_sin_ran($t + 0.2623, 3, 523.2400, 0.16, :fm_index, 1.9046) vln_one_sin_ran($t + 0.2623, 3, 523.2400, 0.16, :fm_index, 2.1834) vln_one_sin_ran($t + 0.2625, 1.2, 523.2400, 0.16, :fm_index, 1.8266) vln_one_sin_ran($t + 0.2625, 2.8, 523.2400, 0.16, :fm_index, 1.5937) vln_one_sin_ran($t + 0.2628, 0.8, 523.2400, 0.16, :fm_index, 1.9762) vln_one_sin_ran($t + 0.2628, 2, 523.2400, 0.16, :fm_index, 1.8954) vln_one_sin_ran($t + 0.2630, 4, 523.2400, 0.16, :fm_index, 2.3302) vln_one_sin_ran($t + 0.2630, 4, 523.2400, 0.16, :fm_index, 2.4949) $t += 4.0 $fm1_rat = 3.414 $fm2_rat = 1.414 $fm3_rat = 2.718 vln_one_sin_ran($t + 0.2600, 1.6, 821.7484, 0.16, :fm_index, 2.4793) vln_one_sin_ran($t + 0.2600, 2, 821.7484, 0.16, :fm_index, 2.4789) vln_one_sin_ran($t + 0.2603, 1.2, 821.7484, 0.16, :fm_index, 2.0827) vln_one_sin_ran($t + 0.2603, 4, 821.7484, 0.16, :fm_index, 2.4769) vln_one_sin_ran($t + 0.2605, 1.2, 711.0832, 0.16, :fm_index, 2.4094) vln_one_sin_ran($t + 0.2605, 2.8, 711.0832, 0.16, :fm_index, 2.4031) vln_one_sin_ran($t + 0.2605, 1.2, 711.0832, 0.16, :fm_index, 2.1428) vln_one_sin_ran($t + 0.2608, 1.6, 261.6200, 0.16, :fm_index, 2.3129) vln_one_sin_ran($t + 0.2608, 2, 261.6200, 0.16, :fm_index, 2.3488) vln_one_sin_ran($t + 0.2610, 1.2, 261.6200, 0.16, :fm_index, 2.1466) vln_one_sin_ran($t + 0.2610, 4, 261.6200, 0.16, :fm_index, 1.6938) vln_one_sin_ran($t + 0.2613, 1.2, 261.6200, 0.16, :fm_index, 2.1287) vln_one_sin_ran($t + 0.2613, 2.8, 261.6200, 0.16, :fm_index, 2.1917) vln_one_sin_ran($t + 0.2615, 1.2, 261.6200, 0.16, :fm_index, 2.3583) vln_one_sin_ran($t + 0.2615, 2, 261.6200, 0.16, :fm_index, 1.8368) vln_one_sin_ran($t + 0.2618, 4, 261.6200, 0.16, :fm_index, 1.5107) vln_one_sin_ran($t + 0.2618, 4, 261.6200, 0.16, :fm_index, 1.6218) vln_one_sin_ran($t + 0.2620, 3, 261.6200, 0.16, :fm_index, 1.9041) vln_one_sin_ran($t + 0.2620, 1.5, 261.6200, 0.16, :fm_index, 1.5748) vln_one_sin_ran($t + 0.2623, 3, 261.6200, 0.16, :fm_index, 1.9339) vln_one_sin_ran($t + 0.2623, 3, 261.6200, 0.16, :fm_index, 2.0489) vln_one_sin_ran($t + 0.2625, 1.2, 261.6200, 0.16, :fm_index, 2.0888) vln_one_sin_ran($t + 0.2625, 2.8, 261.6200, 0.16, :fm_index, 1.7306) vln_one_sin_ran($t + 0.2628, 0.8, 261.6200, 0.16, :fm_index, 2.3257) vln_one_sin_ran($t + 0.2628, 2, 261.6200, 0.16, :fm_index, 2.4755) vln_one_sin_ran($t + 0.2630, 4, 261.6200, 0.16, :fm_index, 1.9459) vln_one_sin_ran($t + 0.2630, 4, 261.6200, 0.16, :fm_index, 1.5782) $t += 4.0 $fm1_rat = 3.414 $fm2_rat = 1.414 $fm3_rat = 2.718 vln_one_sin_ran($t + 0.2600, 1.6, 3286.9937, 0.16, :fm_index, 1.6655) vln_one_sin_ran($t + 0.2600, 2, 3286.9937, 0.16, :fm_index, 1.9356) vln_one_sin_ran($t + 0.2603, 1.2, 3286.9937, 0.16, :fm_index, 1.5665) vln_one_sin_ran($t + 0.2603, 4, 3286.9937, 0.16, :fm_index, 1.6701) vln_one_sin_ran($t + 0.2605, 1.2, 2844.3326, 0.16, :fm_index, 2.3273) vln_one_sin_ran($t + 0.2605, 2.8, 2844.3326, 0.16, :fm_index, 1.5520) vln_one_sin_ran($t + 0.2605, 1.2, 2844.3326, 0.16, :fm_index, 2.4104) vln_one_sin_ran($t + 0.2608, 1.6, 1046.4800, 0.16, :fm_index, 2.1075) vln_one_sin_ran($t + 0.2608, 2, 1046.4800, 0.16, :fm_index, 1.7004) vln_one_sin_ran($t + 0.2610, 1.2, 1046.4800, 0.16, :fm_index, 1.6502) vln_one_sin_ran($t + 0.2610, 4, 1046.4800, 0.16, :fm_index, 2.4591) vln_one_sin_ran($t + 0.2613, 1.2, 1046.4800, 0.16, :fm_index, 2.1491) vln_one_sin_ran($t + 0.2613, 2.8, 1046.4800, 0.16, :fm_index, 2.1594) vln_one_sin_ran($t + 0.2615, 1.2, 1046.4800, 0.16, :fm_index, 2.4783) vln_one_sin_ran($t + 0.2615, 2, 1046.4800, 0.16, :fm_index, 2.2080) vln_one_sin_ran($t + 0.2618, 4, 1046.4800, 0.16, :fm_index, 1.5844) vln_one_sin_ran($t + 0.2618, 4, 1046.4800, 0.16, :fm_index, 1.5440) vln_one_sin_ran($t + 0.2620, 3, 1046.4800, 0.16, :fm_index, 1.9857) vln_one_sin_ran($t + 0.2620, 1.5, 1046.4800, 0.16, :fm_index, 1.5165) vln_one_sin_ran($t + 0.2623, 3, 1046.4800, 0.16, :fm_index, 1.8309) vln_one_sin_ran($t + 0.2623, 3, 1046.4800, 0.16, :fm_index, 2.1236) vln_one_sin_ran($t + 0.2625, 1.2, 1046.4800, 0.1, :fm_index, 2.4074) vln_one_sin_ran($t + 0.2625, 2.8, 1046.4800, 0.1, :fm_index, 1.6315) vln_one_sin_ran($t + 0.2628, 0.8, 1046.4800, 0.1, :fm_index, 1.8061) vln_one_sin_ran($t + 0.2628, 2, 1046.4800, 0.1, :fm_index, 2.3664) vln_one_sin_ran($t + 0.2630, 4, 1046.4800, 0.1, :fm_index, 2.2490) vln_one_sin_ran($t + 0.2630, 4, 1046.4800, 0.1, :fm_index, 2.4081) $t += 4.0 $reverb_amount = 0.01 vln_one_sin_ran($t + 0.2600, 1.6, 1643.4968, 0.16, :fm_index, 1.9284) vln_one_sin_ran($t + 0.2600, 2, 1643.4968, 0.16, :fm_index, 2.2171) vln_one_sin_ran($t + 0.2603, 1.2, 1643.4968, 0.16, :fm_index, 2.2272) vln_one_sin_ran($t + 0.2603, 4, 1643.4968, 0.16, :fm_index, 1.5677) vln_one_sin_ran($t + 0.2605, 1.2, 1422.1663, 0.16, :fm_index, 2.0476) vln_one_sin_ran($t + 0.2605, 2.8, 1422.1663, 0.16, :fm_index, 2.3289) vln_one_sin_ran($t + 0.2605, 1.2, 1422.1663, 0.16, :fm_index, 2.0269) vln_one_sin_ran($t + 0.2608, 1.6, 523.2400, 0.16, :fm_index, 1.7767) vln_one_sin_ran($t + 0.2608, 2, 523.2400, 0.16, :fm_index, 1.8117) vln_one_sin_ran($t + 0.2610, 1.2, 523.2400, 0.16, :fm_index, 1.5694) vln_one_sin_ran($t + 0.2610, 4, 523.2400, 0.16, :fm_index, 1.6869) vln_one_sin_ran($t + 0.2613, 1.2, 523.2400, 0.16, :fm_index, 1.9340) vln_one_sin_ran($t + 0.2613, 2.8, 523.2400, 0.16, :fm_index, 2.3986) vln_one_sin_ran($t + 0.2615, 1.2, 523.2400, 0.16, :fm_index, 2.4593) vln_one_sin_ran($t + 0.2615, 2, 523.2400, 0.16, :fm_index, 2.3430) vln_one_sin_ran($t + 0.2618, 4, 523.2400, 0.16, :fm_index, 2.2650) vln_one_sin_ran($t + 0.2618, 4, 523.2400, 0.16, :fm_index, 2.3015) vln_one_sin_ran($t + 0.2620, 3, 523.2400, 0.16, :fm_index, 1.9909) vln_one_sin_ran($t + 0.2620, 1.5, 523.2400, 0.16, :fm_index, 2.3916) vln_one_sin_ran($t + 0.2623, 3, 523.2400, 0.16, :fm_index, 2.0401) vln_one_sin_ran($t + 0.2623, 3, 523.2400, 0.16, :fm_index, 1.8484) vln_one_sin_ran($t + 0.2625, 1.2, 523.2400, 0.16, :fm_index, 2.3138) vln_one_sin_ran($t + 0.2625, 2.8, 523.2400, 0.16, :fm_index, 1.6295) vln_one_sin_ran($t + 0.2628, 0.8, 523.2400, 0.16, :fm_index, 2.2344) vln_one_sin_ran($t + 0.2628, 2, 523.2400, 0.16, :fm_index, 1.8423) vln_one_sin_ran($t + 0.2630, 4, 523.2400, 0.16, :fm_index, 2.2086) vln_one_sin_ran($t + 0.2630, 4, 523.2400, 0.16, :fm_index, 2.3130) $t += 4.0 $noise_amount = 0.0001 $fm1_rat = 2.718 $fm2_rat = 1.141 $fm3_rat = 3.141 $reverb_amount = 0.01 vln_one_sin_ran($t + 0.2605, 0.8, 523.2400, 0.16, :fm_index, 2.0123) vln_one_sin_ran($t + 0.2605, 1, 493.8728, 0.16, :fm_index, 2.1176) vln_one_sin_ran($t + 0.2610, 0.6, 554.3535, 0.16, :fm_index, 1.9163) vln_one_sin_ran($t + 0.2613, 2, 466.1539, 0.16, :fm_index, 1.5048) vln_one_sin_ran($t + 0.2615, 0.6, 466.1539, 0.16, :fm_index, 1.5242) vln_one_sin_ran($t + 0.2615, 1.4, 493.8728, 0.16, :fm_index, 1.9509) vln_one_sin_ran($t + 0.2620, 0.6, 439.9907, 0.16, :fm_index, 2.2131) vln_one_sin_ran($t + 0.2623, 1, 415.2959, 0.16, :fm_index, 1.7326) vln_one_sin_ran($t + 0.2623, 2, 391.9871, 0.16, :fm_index, 1.9936) vln_one_sin_ran($t + 0.2623, 2, 369.9866, 0.16, :fm_index, 2.1103) vln_one_sin_ran($t + 0.2625, 2, 523.2400, 0.16, :fm_index, 1.6206) vln_one_sin_ran($t + 0.2625, 1, 522.7173, 0.16, :fm_index, 1.8598) vln_one_sin_ran($t + 0.2630, 2, 523.7632, 0.16, :fm_index, 1.8015) vln_one_sin_ran($t + 0.2633, 2, 522.1951, 0.16, :fm_index, 2.3575) vln_one_sin_ran($t + 0.2635, 0.6, 522.1951, 0.16, :fm_index, 1.5010) vln_one_sin_ran($t + 0.2635, 1.4, 522.7173, 0.16, :fm_index, 2.4075) vln_one_sin_ran($t + 0.2640, 0.4, 521.6734, 0.16, :fm_index, 2.0721) vln_one_sin_ran($t + 0.2643, 1, 521.1523, 0.16, :fm_index, 2.0433) vln_one_sin_ran($t + 0.2643, 2, 520.6316, 0.16, :fm_index, 1.9788) vln_one_sin_ran($t + 0.2643, 2, 520.1115, 0.16, :fm_index, 1.6770) $t += 8.0 $noise_amount = 0.004 vln_one_sin_ran($t + 0.2600, 0.8, 1046.4800, 0.16, :fm_index, 1.5610) vln_one_sin_ran($t + 0.2600, 1, 1044.3912, 0.16, :fm_index, 2.3514) vln_one_sin_ran($t + 0.2603, 0.6, 1048.5730, 0.16, :fm_index, 1.9958) vln_one_sin_ran($t + 0.2603, 2, 1042.3066, 0.16, :fm_index, 1.9654) vln_one_sin_ran($t + 0.2605, 0.6, 1042.3066, 0.16, :fm_index, 1.5285) vln_one_sin_ran($t + 0.2605, 1.4, 1044.3912, 0.16, :fm_index, 1.8881) vln_one_sin_ran($t + 0.2608, 0.6, 1040.2262, 0.16, :fm_index, 1.8682) vln_one_sin_ran($t + 0.2608, 0.8, 523.2400, 0.16, :fm_index, 1.8296) vln_one_sin_ran($t + 0.2610, 1, 522.1956, 0.16, :fm_index, 2.1899) vln_one_sin_ran($t + 0.2610, 0.6, 524.2865, 0.16, :fm_index, 1.9614) vln_one_sin_ran($t + 0.2613, 2, 521.1533, 0.16, :fm_index, 1.7483) vln_one_sin_ran($t + 0.2615, 0.6, 521.1533, 0.16, :fm_index, 1.8717) vln_one_sin_ran($t + 0.2615, 1.4, 522.1956, 0.16, :fm_index, 1.5619) vln_one_sin_ran($t + 0.2620, 0.6, 520.1131, 0.16, :fm_index, 2.4331) vln_one_sin_ran($t + 0.2623, 1, 519.0749, 0.16, :fm_index, 2.4153) vln_one_sin_ran($t + 0.2623, 2, 518.0388, 0.16, :fm_index, 1.5477) vln_one_sin_ran($t + 0.2623, 2, 517.0048, 0.16, :fm_index, 1.9956) vln_one_sin_ran($t + 0.2625, 2, 523.2400, 0.16, :fm_index, 1.8111) vln_one_sin_ran($t + 0.2625, 1, 522.7173, 0.16, :fm_index, 2.4820) vln_one_sin_ran($t + 0.2630, 2, 523.7632, 0.16, :fm_index, 1.5744) vln_one_sin_ran($t + 0.2633, 2, 522.1951, 0.16, :fm_index, 1.9950) vln_one_sin_ran($t + 0.2635, 0.6, 522.1951, 0.16, :fm_index, 1.9792) vln_one_sin_ran($t + 0.2635, 1.4, 522.7173, 0.16, :fm_index, 1.7415) vln_one_sin_ran($t + 0.2640, 0.4, 521.6734, 0.16, :fm_index, 2.0884) vln_one_sin_ran($t + 0.2643, 1, 521.1523, 0.16, :fm_index, 2.3605) vln_one_sin_ran($t + 0.2643, 2, 520.6316, 0.16, :fm_index, 1.7817) vln_one_sin_ran($t + 0.2643, 2, 520.1115, 0.16, :fm_index, 2.0283) $t += 4.0 $reverb_amount = 0.1 $fm1_rat = 2.718 $fm2_rat = 1.414 $fm3_rat = 3.141 $glissando_amount = 0.0 vln_one_sin_ran($t + 0.2600, 1.6, 177.7708, 0.16, :fm_index, 1.6447) vln_one_sin_ran($t + 0.2600, 2, 177.7708, 0.16, :fm_index, 2.4875) vln_one_sin_ran($t + 0.2603, 1.2, 177.7708, 0.16, :fm_index, 1.6126) vln_one_sin_ran($t + 0.2603, 4, 177.7708, 0.16, :fm_index, 2.3122) vln_one_sin_ran($t + 0.2605, 1.2, 205.4371, 0.16, :fm_index, 2.4116) vln_one_sin_ran($t + 0.2605, 2.8, 205.4371, 0.16, :fm_index, 1.5337) vln_one_sin_ran($t + 0.2608, 1.2, 205.4371, 0.16, :fm_index, 2.0307) vln_one_sin_ran($t + 0.2608, 1.6, 65.4050, 0.16, :fm_index, 2.2341) vln_one_sin_ran($t + 0.2610, 2, 65.4050, 0.16, :fm_index, 2.4683) vln_one_sin_ran($t + 0.2610, 1.2, 65.4050, 0.16, :fm_index, 2.0643) vln_one_sin_ran($t + 0.2613, 4, 65.4050, 0.16, :fm_index, 2.1925) vln_one_sin_ran($t + 0.2615, 1.2, 65.4050, 0.16, :fm_index, 2.1325) vln_one_sin_ran($t + 0.2615, 2.8, 65.4050, 0.16, :fm_index, 1.5847) vln_one_sin_ran($t + 0.2620, 1.2, 65.4050, 0.16, :fm_index, 1.8781) vln_one_sin_ran($t + 0.2623, 2, 65.4050, 0.16, :fm_index, 2.0283) vln_one_sin_ran($t + 0.2623, 4, 65.4050, 0.16, :fm_index, 2.4739) vln_one_sin_ran($t + 0.2623, 4, 65.4050, 0.16, :fm_index, 2.2333) vln_one_sin_ran($t + 0.2625, 2, 65.4050, 0.16, :fm_index, 2.2194) vln_one_sin_ran($t + 0.2625, 1, 65.4050, 0.16, :fm_index, 2.4491) vln_one_sin_ran($t + 0.2630, 2, 65.4050, 0.16, :fm_index, 1.5672) vln_one_sin_ran($t + 0.2633, 2, 65.4050, 0.16, :fm_index, 2.3254) vln_one_sin_ran($t + 0.2635, 1.2, 65.4050, 0.16, :fm_index, 1.8302) vln_one_sin_ran($t + 0.2635, 2.8, 65.4050, 0.16, :fm_index, 1.9201) vln_one_sin_ran($t + 0.2640, 0.8, 65.4050, 0.16, :fm_index, 1.9164) vln_one_sin_ran($t + 0.2643, 2, 65.4050, 0.16, :fm_index, 1.9483) vln_one_sin_ran($t + 0.2643, 4, 65.4050, 0.16, :fm_index, 2.4247) vln_one_sin_ran($t + 0.2643, 4, 65.4050, 0.16, :fm_index, 2.0419) $t += 4.0 $fm1_rat = 2.718 $fm2_rat = 4.414 $fm3_rat = 3.141 vln_one_sin_ran($t + 0.2600, 1.6, 88.8854, 0.16, :fm_index, 2.2832) vln_one_sin_ran($t + 0.2600, 2, 88.8854, 0.16, :fm_index, 1.6588) vln_one_sin_ran($t + 0.2603, 1.2, 88.8854, 0.16, :fm_index, 2.2392) vln_one_sin_ran($t + 0.2603, 4, 88.8854, 0.16, :fm_index, 1.7354) vln_one_sin_ran($t + 0.2605, 1.2, 102.7186, 0.16, :fm_index, 1.6692) vln_one_sin_ran($t + 0.2605, 2.8, 102.7186, 0.16, :fm_index, 2.1518) vln_one_sin_ran($t + 0.2608, 1.2, 102.7186, 0.16, :fm_index, 2.2439) vln_one_sin_ran($t + 0.2608, 1.6, 32.7025, 0.16, :fm_index, 2.1665) vln_one_sin_ran($t + 0.2610, 2, 32.7025, 0.16, :fm_index, 1.7947) vln_one_sin_ran($t + 0.2610, 1.2, 32.7025, 0.16, :fm_index, 2.0740) vln_one_sin_ran($t + 0.2613, 4, 32.7025, 0.16, :fm_index, 1.9705) vln_one_sin_ran($t + 0.2615, 1.2, 32.7025, 0.16, :fm_index, 1.9447) vln_one_sin_ran($t + 0.2615, 2.8, 32.7025, 0.16, :fm_index, 2.4918) vln_one_sin_ran($t + 0.2620, 1.2, 32.7025, 0.16, :fm_index, 1.6275) vln_one_sin_ran($t + 0.2623, 2, 32.7025, 0.16, :fm_index, 2.2355) vln_one_sin_ran($t + 0.2623, 4, 32.7025, 0.16, :fm_index, 2.0084) vln_one_sin_ran($t + 0.2623, 4, 32.7025, 0.16, :fm_index, 1.8964) vln_one_sin_ran($t + 0.2625, 2, 32.7025, 0.16, :fm_index, 2.3937) vln_one_sin_ran($t + 0.2625, 1, 32.7025, 0.16, :fm_index, 1.8634) vln_one_sin_ran($t + 0.2630, 2, 32.7025, 0.16, :fm_index, 1.5217) vln_one_sin_ran($t + 0.2633, 2, 32.7025, 0.16, :fm_index, 1.9275) vln_one_sin_ran($t + 0.2635, 1.2, 32.7025, 0.16, :fm_index, 2.4413) vln_one_sin_ran($t + 0.2635, 2.8, 32.7025, 0.16, :fm_index, 2.3242) vln_one_sin_ran($t + 0.2640, 0.8, 32.7025, 0.16, :fm_index, 2.3267) vln_one_sin_ran($t + 0.2643, 2, 32.7025, 0.16, :fm_index, 1.7004) vln_one_sin_ran($t + 0.2643, 4, 32.7025, 0.16, :fm_index, 1.8785) vln_one_sin_ran($t + 0.2643, 4, 32.7025, 0.16, :fm_index, 2.4573) $t += 4.0 $fm1_rat = 2.718 $fm2_rat = 4.414 $fm3_rat = 5.141 vln_one_sin_ran($t + 0.2600, 1.6, 22.2213, 0.16, :fm_index, 1.6232) vln_one_sin_ran($t + 0.2600, 2, 22.2213, 0.16, :fm_index, 1.5982) vln_one_sin_ran($t + 0.2603, 1.2, 22.2213, 0.16, :fm_index, 2.1585) vln_one_sin_ran($t + 0.2603, 4, 22.2213, 0.16, :fm_index, 2.2207) vln_one_sin_ran($t + 0.2605, 1.2, 42.0309, 0.16, :fm_index, 1.5294) vln_one_sin_ran($t + 0.2605, 2.8, 42.0309, 0.16, :fm_index, 1.9544) vln_one_sin_ran($t + 0.2608, 1.2, 42.0309, 0.16, :fm_index, 2.4016) vln_one_sin_ran($t + 0.2608, 1.6, 8.1756, 0.16, :fm_index, 1.5267) vln_one_sin_ran($t + 0.2610, 2, 8.1756, 0.16, :fm_index, 2.4190) vln_one_sin_ran($t + 0.2610, 1.2, 8.1756, 0.16, :fm_index, 2.2757) vln_one_sin_ran($t + 0.2613, 4, 8.1756, 0.16, :fm_index, 2.3607) vln_one_sin_ran($t + 0.2615, 1.2, 8.1756, 0.16, :fm_index, 1.8698) vln_one_sin_ran($t + 0.2615, 2.8, 8.1756, 0.16, :fm_index, 2.3753) vln_one_sin_ran($t + 0.2620, 1.2, 8.1756, 0.16, :fm_index, 2.3392) vln_one_sin_ran($t + 0.2623, 2, 8.1756, 0.16, :fm_index, 1.5088) vln_one_sin_ran($t + 0.2623, 4, 8.1756, 0.16, :fm_index, 2.2084) vln_one_sin_ran($t + 0.2623, 4, 8.1756, 0.16, :fm_index, 1.9512) vln_one_sin_ran($t + 0.2625, 2, 8.1756, 0.16, :fm_index, 2.0399) vln_one_sin_ran($t + 0.2625, 1, 8.1756, 0.16, :fm_index, 1.7053) vln_one_sin_ran($t + 0.2630, 2, 8.1756, 0.16, :fm_index, 2.3204) vln_one_sin_ran($t + 0.2633, 2, 8.1756, 0.16, :fm_index, 1.6336) vln_one_sin_ran($t + 0.2635, 1.2, 8.1756, 0.16, :fm_index, 1.9483) vln_one_sin_ran($t + 0.2635, 2.8, 8.1756, 0.16, :fm_index, 2.3255) vln_one_sin_ran($t + 0.2640, 0.8, 8.1756, 0.16, :fm_index, 1.7331) vln_one_sin_ran($t + 0.2643, 2, 8.1756, 0.16, :fm_index, 1.9318) vln_one_sin_ran($t + 0.2643, 4, 8.1756, 0.16, :fm_index, 1.6908) vln_one_sin_ran($t + 0.2643, 4, 8.1756, 0.16, :fm_index, 2.4103) $t += 4.0 vln_one_sin_ran($t + 0.2600, 1.6, 11.1107, 0.16, :fm_index, 1.6371) vln_one_sin_ran($t + 0.2600, 2, 11.1107, 0.16, :fm_index, 1.8971) vln_one_sin_ran($t + 0.2603, 1.2, 11.1107, 0.16, :fm_index, 1.9065) vln_one_sin_ran($t + 0.2603, 4, 11.1107, 0.16, :fm_index, 2.2143) vln_one_sin_ran($t + 0.2605, 1.2, 21.0154, 0.16, :fm_index, 1.8011) vln_one_sin_ran($t + 0.2605, 2.8, 21.0154, 0.16, :fm_index, 2.1950) vln_one_sin_ran($t + 0.2608, 1.2, 21.0154, 0.16, :fm_index, 2.3563) vln_one_sin_ran($t + 0.2608, 1.6, 4.0878, 0.16, :fm_index, 2.3181) vln_one_sin_ran($t + 0.2610, 2, 4.0878, 0.16, :fm_index, 2.0776) vln_one_sin_ran($t + 0.2610, 1.2, 4.0878, 0.16, :fm_index, 1.8336) vln_one_sin_ran($t + 0.2613, 4, 4.0878, 0.16, :fm_index, 1.5019) vln_one_sin_ran($t + 0.2615, 1.2, 4.0878, 0.16, :fm_index, 2.2368) vln_one_sin_ran($t + 0.2615, 2.8, 4.0878, 0.16, :fm_index, 1.7462) vln_one_sin_ran($t + 0.2620, 1.2, 4.0878, 0.16, :fm_index, 1.9604) vln_one_sin_ran($t + 0.2623, 2, 4.0878, 0.16, :fm_index, 2.2361) vln_one_sin_ran($t + 0.2623, 4, 4.0878, 0.16, :fm_index, 1.9972) vln_one_sin_ran($t + 0.2623, 4, 4.0878, 0.16, :fm_index, 2.4870) vln_one_sin_ran($t + 0.2625, 2, 4.0878, 0.16, :fm_index, 2.0762) vln_one_sin_ran($t + 0.2625, 1, 4.0878, 0.16, :fm_index, 2.2973) vln_one_sin_ran($t + 0.2630, 2, 4.0878, 0.16, :fm_index, 2.2350) vln_one_sin_ran($t + 0.2633, 2, 4.0878, 0.16, :fm_index, 2.1613) vln_one_sin_ran($t + 0.2635, 1.2, 4.0878, 0.16, :fm_index, 2.0640) vln_one_sin_ran($t + 0.2635, 2.8, 4.0878, 0.16, :fm_index, 2.1738) vln_one_sin_ran($t + 0.2640, 0.8, 4.0878, 0.16, :fm_index, 1.5188) vln_one_sin_ran($t + 0.2643, 2, 4.0878, 0.16, :fm_index, 1.8766) vln_one_sin_ran($t + 0.2643, 4, 4.0878, 0.16, :fm_index, 2.3083) vln_one_sin_ran($t + 0.2643, 4, 4.0878, 0.16, :fm_index, 2.2215) $t += 4.0 vln_one_sin_ran($t + 0.2600, 1.6, 66.5893, 0.16, :fm_index, 1.7041) vln_one_sin_ran($t + 0.2600, 2, 66.4564, 0.16, :fm_index, 2.0296) vln_one_sin_ran($t + 0.2603, 1.2, 66.7225, 0.16, :fm_index, 1.8321) vln_one_sin_ran($t + 0.2603, 4, 66.3237, 0.16, :fm_index, 2.1550) vln_one_sin_ran($t + 0.2605, 1.2, 125.4490, 0.16, :fm_index, 2.1806) vln_one_sin_ran($t + 0.2605, 2.8, 125.6999, 0.16, :fm_index, 2.3570) vln_one_sin_ran($t + 0.2608, 1.2, 125.1986, 0.16, :fm_index, 1.9861) vln_one_sin_ran($t + 0.2608, 1.6, 24.4994, 0.16, :fm_index, 1.6412) vln_one_sin_ran($t + 0.2610, 2, 24.4505, 0.16, :fm_index, 1.9770) vln_one_sin_ran($t + 0.2610, 1.2, 24.5484, 0.16, :fm_index, 2.0103) vln_one_sin_ran($t + 0.2613, 4, 24.4017, 0.16, :fm_index, 2.0663) vln_one_sin_ran($t + 0.2615, 1.2, 24.4017, 0.16, :fm_index, 2.1521) vln_one_sin_ran($t + 0.2615, 2.8, 24.4505, 0.16, :fm_index, 2.4453) vln_one_sin_ran($t + 0.2620, 1.2, 24.3530, 0.16, :fm_index, 2.0930) vln_one_sin_ran($t + 0.2623, 2, 24.6960, 0.16, :fm_index, 2.3423) vln_one_sin_ran($t + 0.2623, 4, 24.7454, 0.16, :fm_index, 2.0856) vln_one_sin_ran($t + 0.2623, 4, 24.7948, 0.16, :fm_index, 1.9570) vln_one_sin_ran($t + 0.2625, 2, 24.4994, 0.16, :fm_index, 2.4642) vln_one_sin_ran($t + 0.2625, 1, 24.4749, 0.16, :fm_index, 1.9901) vln_one_sin_ran($t + 0.2630, 2, 24.5239, 0.16, :fm_index, 1.9972) vln_one_sin_ran($t + 0.2633, 2, 24.4505, 0.16, :fm_index, 1.9148) vln_one_sin_ran($t + 0.2635, 1.2, 24.4505, 0.16, :fm_index, 1.9017) vln_one_sin_ran($t + 0.2635, 2.8, 24.4749, 0.16, :fm_index, 2.4958) vln_one_sin_ran($t + 0.2640, 0.8, 24.4260, 0.16, :fm_index, 2.2518) vln_one_sin_ran($t + 0.2643, 2, 24.5975, 0.16, :fm_index, 2.1120) vln_one_sin_ran($t + 0.2643, 4, 24.6221, 0.16, :fm_index, 2.3154) vln_one_sin_ran($t + 0.2643, 4, 24.6467, 0.16, :fm_index, 1.9240) $t += 4.0 $fm1_rat = 6.718 $fm2_rat = 4.414 $fm3_rat = 5.141 vln_one_sin_ran($t + 0.2600, 1.6, 164.5868, 0.16, :fm_index, 1.9587) vln_one_sin_ran($t + 0.2600, 2, 164.5868, 0.16, :fm_index, 1.5071) vln_one_sin_ran($t + 0.2603, 1.2, 164.5868, 0.16, :fm_index, 1.7690) vln_one_sin_ran($t + 0.2603, 4, 164.5868, 0.16, :fm_index, 1.7686) vln_one_sin_ran($t + 0.2605, 1.2, 125.9513, 0.16, :fm_index, 1.5702) vln_one_sin_ran($t + 0.2605, 2.8, 125.9513, 0.16, :fm_index, 2.1962) vln_one_sin_ran($t + 0.2608, 1.2, 125.9513, 0.16, :fm_index, 1.7701) vln_one_sin_ran($t + 0.2608, 1.6, 24.4994, 0.16, :fm_index, 2.1665) vln_one_sin_ran($t + 0.2610, 2, 24.4994, 0.16, :fm_index, 1.9345) vln_one_sin_ran($t + 0.2610, 1.2, 24.4994, 0.16, :fm_index, 2.2037) vln_one_sin_ran($t + 0.2613, 4, 24.4994, 0.16, :fm_index, 1.6826) vln_one_sin_ran($t + 0.2615, 1.2, 24.4994, 0.16, :fm_index, 1.5410) vln_one_sin_ran($t + 0.2615, 2.8, 24.4994, 0.16, :fm_index, 1.8293) vln_one_sin_ran($t + 0.2620, 1.2, 24.4994, 0.16, :fm_index, 2.1468) vln_one_sin_ran($t + 0.2623, 2, 24.4994, 0.16, :fm_index, 2.0758) vln_one_sin_ran($t + 0.2623, 4, 24.4994, 0.16, :fm_index, 2.4138) vln_one_sin_ran($t + 0.2623, 4, 24.4994, 0.16, :fm_index, 1.8479) vln_one_sin_ran($t + 0.2625, 3, 24.4994, 0.16, :fm_index, 2.4639) vln_one_sin_ran($t + 0.2625, 1.5, 24.4994, 0.16, :fm_index, 2.3995) vln_one_sin_ran($t + 0.2630, 3, 24.4994, 0.16, :fm_index, 1.8609) vln_one_sin_ran($t + 0.2633, 3, 24.4994, 0.16, :fm_index, 2.4506) vln_one_sin_ran($t + 0.2635, 1.2, 24.4994, 0.16, :fm_index, 2.1577) vln_one_sin_ran($t + 0.2635, 2.8, 24.4994, 0.16, :fm_index, 1.6663) vln_one_sin_ran($t + 0.2640, 0.8, 24.4994, 0.16, :fm_index, 2.1166) vln_one_sin_ran($t + 0.2643, 2, 24.4994, 0.16, :fm_index, 1.9362) vln_one_sin_ran($t + 0.2643, 4, 24.4994, 0.16, :fm_index, 2.2052) vln_one_sin_ran($t + 0.2643, 4, 24.4994, 0.16, :fm_index, 2.0102) $t += 4.0 restore_fm_violin_defaults() $glissando_amount = 0.8 $reverb_amount = 0.01 $gliss_env = whoosh $amp_env = metalamp $fm1_rat = 2.718 $fm2_rat = 1.141 $fm3_rat = 3.141 vln_one_sin($t + 0.2600, 0.4, 1046.4800, 0.16, :fm_index, 2.3870) vln_one_sin($t + 0.2600, 0.5000, 1044.3912, 0.16, :fm_index, 2.4309) vln_one_sin($t + 0.2603, 0.3, 1048.5730, 0.16, :fm_index, 2.15) vln_one_sin($t + 0.2603, 0.5000, 1042.3066, 0.16, :fm_index, 1.7211) vln_one_sin($t + 0.2610, 0.3, 524.2865, 0.16, :fm_index, 2.1751) vln_one_sin($t + 0.2620, 0.3, 520.1131, 0.16, :fm_index, 1.5433) vln_one_sin($t + 0.2623, 0.4, 517.0048, 0.16, :fm_index, 2.4335) vln_one_sin($t + 0.2625, 0.4, 523.2400, 0.16, :fm_index, 2.2778) vln_one_sin($t + 0.2635, 0.3, 522.1951, 0.16, :fm_index, 1.9441) vln_one_sin($t + 0.2643, 0.4, 520.6316, 0.16, :fm_index, 2.4656) $t += 4.0 restore_fm_violin_defaults() vln_one_sin($t + 0.1200, 0.4, 2092.9600, 0.16, :fm_index, 3, :reverb_amount, 0, :amp_env, metalamp, :fm2_rat, 1.1410, :fm3_rat, 3.1410, :fm1_rat, 2.7180) vln_one_sin($t + 0.1200, 0.5000, 2088.7820, 0.16, :fm_index, 3, :reverb_amount, 0, :amp_env, metalamp, :fm2_rat, 1.1410, :fm3_rat, 3.1410, :fm1_rat, 2.7180) vln_one_sin($t + 0.1200, 0.3, 2097.1460, 0.16, :fm_index, 3, :reverb_amount, 0, :amp_env, metalamp, :fm2_rat, 1.1410, :fm3_rat, 3.1410, :fm1_rat, 2.7180) vln_one_sin($t + 0.1200, 0.5000, 2084.6130, 0.16, :fm_index, 3, :reverb_amount, 0, :amp_env, metalamp, :fm2_rat, 1.1410, :fm3_rat, 3.1410, :fm1_rat, 2.7180) vln_one_sin($t + 0.1210, 0.3, 1048.5730, 0.16, :fm_index, 3, :reverb_amount, 0, :amp_env, metalamp, :fm2_rat, 1.1410, :fm3_rat, 3.1410, :fm1_rat, 2.7180) vln_one_sin($t + 0.1220, 0.3, 1040.2260, 0.16, :fm_index, 3, :reverb_amount, 0, :amp_env, metalamp, :fm2_rat, 1.1410, :fm3_rat, 3.1410, :fm1_rat, 2.7180) vln_one_sin($t + 0.1220, 0.5000, 1034.0100, 0.16, :fm_index, 3, :reverb_amount, 0, :amp_env, metalamp, :fm2_rat, 1.1410, :fm3_rat, 3.1410, :fm1_rat, 2.7180) vln_one_sin($t + 0.1230, 0.5000, 1046.4800, 0.16, :fm_index, 3, :reverb_amount, 0, :amp_env, metalamp, :fm2_rat, 1.1410, :fm3_rat, 3.1410, :fm1_rat, 2.7180) vln_one_sin($t + 0.1240, 0.3, 1044.3900, 0.16, :fm_index, 3, :reverb_amount, 0, :amp_env, metalamp, :fm2_rat, 1.1410, :fm3_rat, 3.1410, :fm1_rat, 2.7180) z1amp = [0, 0, 20, 0.5000, 40, 0.1, 60, 0.2, 80, 1, 100, 0] z2amp = [0, 0, 20, 1, 60, 0.1, 75, 0.3, 100, 0] $fm1_rat = 2.718 $fm2_rat = 4.414 $fm3_rat = 5.141 vln_one_sin($t + 0.1240, 0.5000, 1041.2630, 0.16, :fm_index, 3, :reverb_amount, 0, :amp_env, metalamp, :fm2_rat, 1.1410, :fm3_rat, 3.1410, :fm1_rat, 2.7180) $t += 2.0 vln_one_sin_ran($t + 0.4880, 1.1770, 416.6072, 0.0110, :fm_index, 1.1140, :reverb_amount, 0.1, :amp_env, z1amp, :noise_amount, 0.0050) vln_one_sin_ran($t + 0.5050, 2.4900, 859.5863, 0.0083, :fm_index, 0.5890, :reverb_amount, 0.1, :amp_env, z2amp, :noise_amount, 0.0050) vln_one_sin_ran($t + 1.0590, 1.0550, 1758.0816, 0.0053, :fm_index, 1.8640, :reverb_amount, 0.1, :amp_env, z2amp, :noise_amount, 0.0050) vln_one_sin_ran($t + 1.0930, 1.8580, 229.0566, 0.0110, :fm_index, 1.9690, :reverb_amount, 0.1, :amp_env, z2amp, :noise_amount, 0.0050) vln_one_sin_ran($t + 1.3490, 3.3680, 479.1994, 0.0083, :fm_index, 1.9970, :reverb_amount, 0.1, :amp_env, z1amp, :noise_amount, 0.0050) vln_one_sin_ran($t + 1.5010, 3.0680, 411.8241, 0.0110, :fm_index, 1.5390, :reverb_amount, 0.1, :amp_env, z2amp, :noise_amount, 0.0050) vln_one_sin_ran($t + 1.5200, 2.8290, 984.8456, 0.0053, :fm_index, 0.0560, :reverb_amount, 0.1, :amp_env, z1amp, :noise_amount, 0.0050) vln_one_sin_ran($t + 1.6100, 0.7040, 1767.7444, 0.0053, :fm_index, 1.2620, :reverb_amount, 0.1, :amp_env, z2amp, :noise_amount, 0.0050) vln_one_sin_ran($t + 1.8480, 3.0510, 859.7203, 0.0083, :fm_index, 1.6080, :reverb_amount, 0.1, :amp_env, z2amp, :noise_amount, 0.0050) vln_one_sin_ran($t + 2.4880, 3.2350, 231.9431, 0.0110, :fm_index, 0.9690, :reverb_amount, 0.1, :amp_env, z1amp, :noise_amount, 0.0050) vln_one_sin_ran($t + 2.5610, 3.2810, 475.2009, 0.0083, :fm_index, 0.3740, :reverb_amount, 0.1, :amp_env, z2amp, :noise_amount, 0.0050) vln_one_sin_ran($t + 2.7970, 2.8400, 988.8375, 0.0053, :fm_index, 0.4200, :reverb_amount, 0.1, :amp_env, z2amp, :noise_amount, 0.0050) vln_one_sin_ran($t + 3.0620, 1.0210, 411.7247, 0.0110, :fm_index, 0.1370, :reverb_amount, 0.1, :amp_env, z2amp, :noise_amount, 0.0050) vln_one_sin_ran($t + 3.2130, 1.1610, 848.5959, 0.0083, :fm_index, 1.3120, :reverb_amount, 0.1, :amp_env, z2amp, :noise_amount, 0.0050) vln_one_sin_ran($t + 3.4410, 2.6160, 390.0600, 0.0110, :fm_index, 1.9030, :reverb_amount, 0.1, :amp_env, z1amp, :noise_amount, 0.0050) vln_one_sin_ran($t + 3.4490, 0.7000, 802.3538, 0.0083, :fm_index, 1.5940, :reverb_amount, 0.1, :amp_env, z2amp, :noise_amount, 0.0050) vln_one_sin_ran($t + 3.5270, 2.5080, 1773.9366, 0.0053, :fm_index, 1.8030, :reverb_amount, 0.1, :amp_env, z1amp, :noise_amount, 0.0050) vln_one_sin_ran($t + 3.7820, 2.7990, 232.4344, 0.0110, :fm_index, 0.0590, :reverb_amount, 0.1, :amp_env, z2amp, :noise_amount, 0.0050) vln_one_sin_ran($t + 3.7830, 2.7660, 1650.1434, 0.0053, :fm_index, 0.4400, :reverb_amount, 0.1, :amp_env, z2amp, :noise_amount, 0.0050) vln_one_sin_ran($t + 3.7890, 3.1560, 475.7231, 0.0083, :fm_index, 0.7370, :reverb_amount, 0.1, :amp_env, z2amp, :noise_amount, 0.0050) vln_one_sin_ran($t + 4.1540, 2.1290, 976.0237, 0.0053, :fm_index, 1.2690, :reverb_amount, 0.1, :amp_env, z2amp, :noise_amount, 0.0050) vln_one_sin_ran($t + 4.4890, 3.3650, 390.0525, 0.0110, :fm_index, 1.4580, :reverb_amount, 0.1, :amp_env, z2amp, :noise_amount, 0.0050) vln_one_sin_ran($t + 4.7450, 1.5070, 1665.9722, 0.0053, :fm_index, 1.9330, :reverb_amount, 0.1, :amp_env, z2amp, :noise_amount, 0.0050) vln_one_sin_ran($t + 4.8320, 1.4430, 798.1238, 0.0083, :fm_index, 0.8560, :reverb_amount, 0.1, :amp_env, z1amp, :noise_amount, 0.0050) vln_one_sin_ran($t + 4.9440, 3.1560, 229.0528, 0.0110, :fm_index, 1.8300, :reverb_amount, 0.1, :amp_env, z2amp, :noise_amount, 0.0050) vln_one_sin_ran($t + 5.3930, 1.1100, 473.7225, 0.0083, :fm_index, 1.6260, :reverb_amount, 0.1, :amp_env, z1amp, :noise_amount, 0.0050) vln_one_sin_ran($t + 5.6970, 1.6170, 988.7953, 0.0053, :fm_index, 0.4230, :reverb_amount, 0.1, :amp_env, z2amp, :noise_amount, 0.0050) vln_one_sin_ran($t + 6.0620, 1.3190, 390.9769, 0.0110, :fm_index, 0.4100, :reverb_amount, 0.1, :amp_env, z2amp, :noise_amount, 0.0050) vln_one_sin_ran($t + 6.0840, 3.3660, 804.6413, 0.0083, :fm_index, 1.8760, :reverb_amount, 0.1, :amp_env, z2amp, :noise_amount, 0.0050) vln_one_sin_ran($t + 6.1740, 2.7210, 418.6819, 0.0110, :fm_index, 0.0910, :reverb_amount, 0.1, :amp_env, z2amp, :noise_amount, 0.0050) vln_one_sin_ran($t + 6.5700, 3.4460, 845.4019, 0.0077, :fm_index, 0.7660, :reverb_amount, 0.1, :amp_env, z2amp, :noise_amount, 0.0050) vln_one_sin_ran($t + 6.6440, 1.1790, 1656.5756, 0.0049, :fm_index, 0.2960, :reverb_amount, 0.1, :amp_env, z1amp, :noise_amount, 0.0050) vln_one_sin_ran($t + 6.6600, 2.8520, 1758.9788, 0.0049, :fm_index, 0.4520, :reverb_amount, 0.1, :amp_env, z2amp, :noise_amount, 0.0050) vln_one_sin_ran($t + 6.8270, 1.8840, 387.0009, 0.0099, :fm_index, 1.3010, :reverb_amount, 0.1, :amp_env, z1amp, :noise_amount, 0.0050) vln_one_sin_ran($t + 6.8870, 3.4040, 796.7213, 0.0077, :fm_index, 1.1820, :reverb_amount, 0.1, :amp_env, z2amp, :noise_amount, 0.0050) vln_one_sin_ran($t + 6.9640, 3.3230, 416.3916, 0.0099, :fm_index, 0.6290, :reverb_amount, 0.1, :amp_env, z2amp, :noise_amount, 0.0050) vln_one_sin_ran($t + 7.1320, 1.7050, 1637.2303, 0.0049, :fm_index, 1.0570, :reverb_amount, 0.1, :amp_env, z1amp, :noise_amount, 0.0050) vln_one_sin_ran($t + 7.15, 3.1250, 1762.4906, 0.0049, :fm_index, 1.3170, :reverb_amount, 0.1, :amp_env, z2amp, :noise_amount, 0.0050) vln_one_sin_ran($t + 7.3860, 2.9670, 852.0487, 0.0077, :fm_index, 1.4790, :reverb_amount, 0.1, :amp_env, z1amp, :noise_amount, 0.0050) vln_one_sin_ran($t + 7.6670, 0.6780, 413.7094, 0.0099, :fm_index, 0.9470, :reverb_amount, 0.1, :amp_env, z2amp, :noise_amount, 0.0050) vln_one_sin_ran($t + 7.8780, 2.7490, 1749.7509, 0.0049, :fm_index, 0.5040, :reverb_amount, 0.1, :amp_env, z1amp, :noise_amount, 0.0050) vln_one_sin_ran($t + 7.9730, 0.5990, 848.1253, 0.0077, :fm_index, 1.9380, :reverb_amount, 0.1, :amp_env, z1amp, :noise_amount, 0.0050) vln_one_sin_ran($t + 8.0880, 3.3360, 229.9144, 0.0099, :fm_index, 1.3930, :reverb_amount, 0.1, :amp_env, z2amp, :noise_amount, 0.0050) vln_one_sin_ran($t + 8.1170, 1.1300, 984.0816, 0.0049, :fm_index, 0.3560, :reverb_amount, 0.1, :amp_env, z2amp, :noise_amount, 0.0050) vln_one_sin_ran($t + 8.4640, 1.7330, 478.7184, 0.0077, :fm_index, 0.2840, :reverb_amount, 0.1, :amp_env, z2amp, :noise_amount, 0.0050) vln_one_sin_ran($t + 8.5760, 0.5680, 413.4253, 0.0099, :fm_index, 1.5020, :reverb_amount, 0.1, :amp_env, z2amp, :noise_amount, 0.0050) vln_one_sin_ran($t + 8.8200, 1.2150, 230.9588, 0.0099, :fm_index, 1.0990, :reverb_amount, 0.1, :amp_env, z1amp, :noise_amount, 0.0050) vln_one_sin_ran($t + 8.8320, 3.4590, 473.8903, 0.0077, :fm_index, 0.7680, :reverb_amount, 0.1, :amp_env, z2amp, :noise_amount, 0.0050) vln_one_sin_ran($t + 8.8320, 0.7260, 857.2875, 0.0077, :fm_index, 0.7520, :reverb_amount, 0.1, :amp_env, z2amp, :noise_amount, 0.0050) $t += 12.0 indfunc = [0, 1, 20, 0, 100, 0] indfunc2 = [0, 1, 90, 1, 100, 0] ampfunc = [0, 1, 6, 1, 10, 0.5000, 20, 0.3630, 30, 0.2700, 40, 0.2, 50, 0.1200, 60, 0.0800, 70, 0.0400, 100, 0] ampfunc1 = [0, 0, 1, 1, 3, 1, 10, 0.5000, 30, 0.2, 60, 0.0500, 100, 0] restore_fm_violin_defaults() vln_one_sin($t + 0.2600, 0.0500, 80, 0.8, :fm_index, 5, :reverb_amount, 0, :amp_env, ampfunc1, :fm1_env, indfunc2) vln_one_sin($t + 1.2610, 0.2, 80, 0.8, :fm_index, 4, :reverb_amount, 0, :amp_env, ampfunc, :fm1_env, indfunc, :fm2_rat, 0.6875) vln_one_sin($t + 2.2600, 0.0500, 80, 0.8, :fm_index, 5, :reverb_amount, 0, :amp_env, ampfunc1, :fm1_env, indfunc2) vln_one_sin($t + 2.2620, 0.2, 80, 0.8, :fm_index, 5, :reverb_amount, 0, :amp_env, ampfunc, :fm1_env, indfunc, :fm2_rat, 0.6875) vln_one_sin($t + 3.2600, 0.0500, 80, 0.8, :fm_index, 6, :reverb_amount, 0, :amp_env, ampfunc1, :fm1_env, indfunc2) vln_one_sin($t + 3.2630, 0.2, 80, 0.8, :fm_index, 6, :reverb_amount, 0, :amp_env, ampfunc, :fm1_env, indfunc, :fm2_rat, 0.6875) vln_one_sin($t + 4.2600, 0.0500, 80, 0.3, :fm_index, 4, :reverb_amount, 0, :amp_env, ampfunc1, :fm1_env, indfunc2) vln_one_sin($t + 4.2620, 0.1, 160, 0.3, :fm_index, 4, :reverb_amount, 0, :amp_env, ampfunc, :fm1_env, indfunc, :fm2_rat, 0.6875) vln_one_sin($t + 4.2620, 0.2500, 80, 0.8, :fm_index, 4, :reverb_amount, 0, :amp_env, ampfunc, :fm1_env, indfunc, :fm2_rat, 0.6875) vln_one_sin($t + 5.2600, 0.0500, 80, 0.500, :fm_index, 4, :reverb_amount, 0, :amp_env, ampfunc1, :fm1_env, indfunc2) vln_one_sin($t + 5.2610, 0.1, 210, 0.3, :fm_index, 4, :reverb_amount, 0, :amp_env, ampfunc, :fm1_env, indfunc, :fm2_rat, 0.6875) vln_one_sin($t + 5.2620, 0.2, 80, 0.1, :fm_index, 4, :reverb_amount, 0, :amp_env, ampfunc, :fm1_env, indfunc, :fm2_rat, 0.6875) vln_one_sin($t + 5.2630, 0.2500, 320, 0.1, :fm_index, 2, :reverb_amount, 0, :amp_env, ampfunc, :fm1_env, indfunc, :fm2_rat, 0.6875) vln_one_sin($t + 6.2600, 0.0500, 80, 0.8, :fm_index, 4, :reverb_amount, 0, :amp_env, ampfunc1, :fm1_env, indfunc2) vln_one_sin($t + 6.2610, 0.1, 210, 0.1, :fm_index, 2, :reverb_amount, 0, :amp_env, ampfunc, :fm1_env, indfunc, :fm2_rat, 0.6875) vln_one_sin($t + 6.2620, 0.2, 80, 0.2, :fm_index, 4, :reverb_amount, 0, :amp_env, ampfunc, :fm1_env, indfunc, :fm2_rat, 0.6875) vln_one_sin($t + 6.2630, 0.2500, 320, 0.3, :reverb_amount, 0, :amp_env, ampfunc, :fm1_env, indfunc, :fm2_rat, 0.6875) vln_one_sin($t + 7.2600, 0.0500, 80, 0.8, :fm_index, 2, :reverb_amount, 0, :amp_env, ampfunc1, :fm1_env, indfunc2) vln_one_sin($t + 7.2610, 0.1, 210, 0.1, :fm_index, 2, :reverb_amount, 0, :amp_env, ampfunc, :fm1_env, indfunc, :fm2_rat, 0.6875) vln_one_sin($t + 7.2620, 0.2, 80, 0.2, :fm_index, 2, :reverb_amount, 0, :amp_env, ampfunc, :fm1_env, indfunc, :fm2_rat, 0.6875) vln_one_sin($t + 7.2630, 0.2500, 320, 0.3, :reverb_amount, 0, :amp_env, ampfunc, :fm1_env, indfunc, :fm2_rat, 0.6875) $t += 8.0 $glissando_amount = 0.0 $noise_amount = 0.004 $fm1_rat = 3.141 $fm2_rat = 4.414 $fm3_rat = 2.718 vln_one_sin_ran($t + 0.2600, 4, 3286.9937, 0.16, :fm_index, 2.2165, :reverb_amount, 0.0100, :amp_env, n_amp, :fm1_env, n_amp) vln_one_sin_ran($t + 0.2603, 4, 1046.4800, 0.16, :fm_index, 2.3234, :reverb_amount, 0.0100, :amp_env, n_amp, :fm1_env, n_amp) vln_one_sin_ran($t + 0.2605, 4, 2844.3326, 0.16, :fm_index, 2.4790, :reverb_amount, 0.1, :amp_env, n_amp, :fm1_env, n_amp) vln_one_sin_ran($t + 0.2608, 4, 821.7484, 0.1, :fm_index, 1.8667, :reverb_amount, 0.0100, :amp_env, n_amp, :fm1_env, n_amp) vln_one_sin_ran($t + 0.2610, 4, 261.6200, 0.1, :fm_index, 1.8523, :reverb_amount, 0.0100, :amp_env, n_amp, :fm1_env, n_amp) vln_one_sin_ran($t + 0.2613, 4, 711.0832, 0.1, :fm_index, 2.2300, :reverb_amount, 0.1, :amp_env, n_amp, :fm1_env, n_amp) vln_one_sin_ran($t + 0.2615, 4, 205.4371, 0.0600, :fm_index, 1.5187, :reverb_amount, 0.0100, :amp_env, n_amp, :fm1_env, n_amp) vln_one_sin_ran($t + 0.2618, 4, 65.4050, 0.0600, :fm_index, 2.4074, :reverb_amount, 0.0100, :amp_env, n_amp, :fm1_env, n_amp) vln_one_sin_ran($t + 0.2620, 4, 177.7708, 0.0600, :fm_index, 2.4481, :reverb_amount, 0.1, :amp_env, n_amp, :fm1_env, n_amp) vln_one_sin_ran($t + 0.2623, 4, 51.3593, 0.0100, :fm_index, 2.3069, :reverb_amount, 0.0100, :amp_env, n_amp, :fm1_env, n_amp) vln_one_sin_ran($t + 0.2625, 4, 16.3513, 0.0100, :fm_index, 2.1008, :reverb_amount, 0.0100, :amp_env, n_amp, :fm1_env, n_amp) vln_one_sin_ran($t + 0.2628, 4, 44.4427, 0.0100, :fm_index, 2.4860, :reverb_amount, 0.1, :amp_env, n_amp, :fm1_env, n_amp) $t += 8.0 restore_fm_violin_defaults() vln_one_sin($t + 0.2603, 1.2, 88.8854, 0.1, :fm_index, 2.3144, :reverb_amount, 0.2, :amp_env, mamp, :fm2_rat, 4.4140, :fm3_rat, 5.1410, :fm1_rat, 2.7180) vln_one_sin($t + 0.2603, 4, 88.8854, 0.1, :fm_index, 2.1690, :reverb_amount, 0.2, :amp_env, mamp, :fm2_rat, 4.4140, :fm3_rat, 5.1410, :fm1_rat, 2.7180) vln_one_sin($t + 0.2605, 2.8, 168.1236, 0.0500, :fm_index, 2.1850, :reverb_amount, 0.2, :amp_env, mamp, :fm2_rat, 4.4140, :fm3_rat, 5.1410, :fm1_rat, 2.7180) vln_one_sin($t + 0.2608, 1.2, 168.1236, 0.0800, :fm_index, 1.7743, :reverb_amount, 0.2, :amp_env, mamp, :fm2_rat, 4.4140, :fm3_rat, 5.1410, :fm1_rat, 2.7180) vln_one_sin($t + 0.2610, 2, 32.7025, 0.1, :fm_index, 2.4925, :reverb_amount, 0.2, :amp_env, mamp, :fm2_rat, 4.4140, :fm3_rat, 5.1410, :fm1_rat, 2.7180) vln_one_sin($t + 0.2633, 2, 32.7025, 0.1, :fm_index, 2.1325, :reverb_amount, 0.2, :amp_env, mamp, :fm2_rat, 4.4140, :fm3_rat, 5.1410, :fm1_rat, 2.7180) vln_one_sin($t + 0.2643, 4, 32.7025, 0.0500, :fm_index, 1.7578, :reverb_amount, 0.2, :amp_env, mamp, :fm2_rat, 4.4140, :fm3_rat, 5.1410, :fm1_rat, 2.7180) $t += 8.0 vln_one_sin_ran($t + 0.2600, 6.6830, 244.8160, 0.0060, :fm_index, 2, :reverb_amount, 0.2, :noise_amount, 0.0040) vln_one_sin_ran($t + 0.2600, 5.5170, 495.4040, 0.0060, :fm_index, 2, :reverb_amount, 0.2, :noise_amount, 0.0040) vln_one_sin_ran($t + 0.2600, 7.5350, 980.6190, 0.0020, :fm_index, 2, :reverb_amount, 0.2, :noise_amount, 0.0040) vln_one_sin_ran($t + 0.2600, 7.1990, 1965.4290, 0.0020, :fm_index, 0.8, :reverb_amount, 0.2, :noise_amount, 0.0040) vln_one_sin_ran($t + 0.2600, 4.0790, 3835.3170, 0.0020, :fm_index, 0.8, :reverb_amount, 0.2, :noise_amount, 0.0040) vln_one_sin_ran($t + 0.5170, 4.7400, 1320.9670, 0.0020, :fm_index, 0.8, :reverb_amount, 0.2, :noise_amount, 0.0040) vln_one_sin_ran($t + 0.7040, 7.2080, 655.5670, 0.0040, :fm_index, 2, :reverb_amount, 0.2, :noise_amount, 0.0040) $t += 9.0 updown = [0, 0, 15, 1, 100, 0] $glissando_amount = 0.0 $reverb_amount = 0.9 vln_one_sin_exp($t + 0.5450, 6.4650, 366.3330, 0.0320, :fm_index, 1.0480, :amp_env, [0, 0, 1.5468, 1, 2.0882, 0.7, 2.3202, 1, 98.4532, 0.7500, 100, 0]) vln_one_sin_exp($t + 0.5950, 8.4340, 1172.5830, 0.0180, :fm_index, 1.1350, :amp_env, [0, 0, 1.1857, 1.0, 1.6007, 0.7, 1.7785, 1, 98.8143, 0.5556, 100, 0]) vln_one_sin_exp($t + 0.7650, 1.6210, 369.9940, 0.0170, :fm_index, 0.0960, :amp_env, [0, 0, 6.1690, 1.0, 8.3282, 0.7, 9.2535, 1, 93.8310, 0.5294, 100, 0]) vln_one_sin_exp($t + 0.8820, 3.0640, 246.9420, 0.0170, :fm_index, 0.0020, :amp_env, [0, 0, 3.2637, 1, 4.4060, 0.7, 4.8956, 1.0, 96.7363, 0.5294, 100, 0]) vln_one_sin_exp($t + 0.9250, 3.1170, 123.4710, 0.0380, :fm_index, 0.2330, :amp_env, [0, 0, 3.2082, 1, 4.3311, 0.7, 4.8123, 1, 96.7918, 0.7895, 100, 0]) vln_one_sin_exp($t + 0.9810, 3.5670, 123.4710, 0.0420, :fm_index, 0.2330, :amp_env, [0, 0, 2.8035, 1, 3.7847, 0.7, 4.2052, 1.0, 97.1965, 0.8095, 100, 0]) vln_one_sin_exp($t + 1.1280, 1.0450, 246.9420, 0.0170, :fm_index, 1.2050, :amp_env, [0, 0, 9.5694, 1, 12.9187, 0.7, 14.3541, 1, 90.4306, 0.5294, 100, 0]) vln_one_sin_exp($t + 1.2550, 3.3870, 374.1370, 0.0170, :fm_index, 0.1800, :amp_env, [0, 0, 2.9525, 1.0, 3.9858, 0.7, 4.4287, 1, 97.0475, 0.5294, 100, 0]) vln_one_sin_exp($t + 1.2990, 8.3050, 1576.9120, 0.0200, :fm_index, 0.2990, :amp_env, [0, 0, 1.2041, 1, 1.6255, 0.7, 1.8061, 1, 98.7959, 0.6, 100, 0]) vln_one_sin_exp($t + 1.3300, 4.4630, 246.9420, 0.0170, :fm_index, 0.0020, :amp_env, [0, 0, 2.2406, 1, 3.0249, 0.7, 3.3610, 1.0, 97.7594, 0.5294, 100, 0]) vln_one_sin_exp($t + 1.6600, 8.9940, 1576.9120, 0.0200, :fm_index, 0.2990, :amp_env, [0, 0, 1.1119, 1, 1.5010, 0.7, 1.6678, 1, 98.8881, 0.6, 100, 0]) vln_one_sin_exp($t + 1.9060, 8.8360, 1172.5830, 0.0180, :fm_index, 1.1350, :amp_env, [0, 0, 1.1317, 1, 1.5278, 0.7, 1.6976, 1, 98.8683, 0.5556, 100, 0]) vln_one_sin_exp($t + 2.1510, 4.9320, 374.1370, 0.0170, :fm_index, 0.1800, :amp_env, [0, 0, 2.0276, 1, 2.7372, 0.7, 3.0414, 1, 97.9724, 0.5294, 100, 0]) vln_one_sin_exp($t + 2.2720, 2.3250, 369.9940, 0.0170, :fm_index, 1.1030, :amp_env, [0, 0, 4.3011, 1, 5.8065, 0.7, 6.4516, 1, 95.6989, 0.5294, 100, 0]) vln_one_sin_exp($t + 3.6960, 3.5540, 366.3330, 0.0310, :fm_index, 1.0480, :amp_env, [0, 0, 2.8137, 1, 3.7985, 0.7, 4.2206, 1, 97.1863, 0.7419, 100, 0]) vln_one_sin_exp($t + 4.7240, 0.6040, 246.9420, 0.0170, :fm_index, 1.2050, :amp_env, [0, 0, 16.5563, 1, 22.351, 0.7, 24.8344, 1, 83.4437, 0.5294, 100, 0]) vln_one_sin_exp($t + 4.9420, 2.5010, 123.4710, 0.0330, :fm_index, 0.2330, :amp_env, [0, 0, 3.9984, 1, 5.3978, 0.7, 5.9976, 1, 96.0016, 0.7576, 100, 0]) vln_one_sin_exp($t + 5.0340, 2.3860, 246.9420, 0.0170, :fm_index, 0.0020, :amp_env, [0, 0, 4.1911, 1, 5.6580, 0.7, 6.2867, 1, 95.8089, 0.5294, 100, 0]) vln_one_sin_exp($t + 5.3850, 1.4510, 369.9940, 0.0170, :fm_index, 1.1030, :amp_env, [0, 0, 6.8918, 1, 9.3039, 0.7, 10.3377, 1, 93.1082, 0.5294, 100, 0]) vln_one_sin_exp($t + 5.5670, 2.6550, 374.1370, 0.0170, :fm_index, 0.1800, :amp_env, [0, 0, 3.7665, 1, 5.0847, 0.7, 5.6497, 1, 96.2335, 0.5294, 100, 0]) vln_one_sin_exp($t + 5.9830, 2.9860, 123.4710, 0.0380, :fm_index, 0.2330, :amp_env, [0, 0, 3.3490, 1, 4.5211, 0.7, 5.0234, 1, 96.6510, 0.7895, 100, 0]) vln_one_sin_exp($t + 6.4910, 0.6110, 123.9770, 0.0170, :fm_index, 0.7550, :amp_env, [0, 0, 16.3666, 1, 22.0949, 0.7, 24.55, 1, 83.6334, 0.5294, 100, 0]) vln_one_sin_exp($t + 6.7570, 1.4440, 123.4710, 0.0170, :fm_index, 0.0020, :amp_env, [0, 0, 6.9252, 1, 9.3490, 0.7, 10.3878, 1, 93.0748, 0.5294, 100, 0]) vln_one_sin_exp($t + 6.7750, 0.5370, 92.4435, 0.0330, :fm_index, 0.9200, :amp_env, [0, 0, 18.622, 1, 25.1397, 0.7, 27.9330, 1, 81.3780, 0.7576, 100, 0]) vln_one_sin_exp($t + 6.7750, 10.5370, 92.4435, 0.0130, :fm_index, 0.9200, :amp_env, [0, 0, 0.9490, 1, 1.2812, 0.7, 1.4236, 1, 99.0510, 0.3846, 100, 0]) vln_one_sin_exp($t + 6.9380, 0.6520, 122.2995, 0.0170, :fm_index, 1.8380, :amp_env, [0, 0, 15.3374, 1, 20.706, 0.7, 23.0061, 1, 84.6626, 0.5294, 100, 0]) vln_one_sin_exp($t + 7.2350, 3.7250, 586.2915, 0.0180, :fm_index, 1.1350, :amp_env, [0, 0, 2.6846, 1, 3.6242, 0.7, 4.0268, 1, 97.3154, 0.5556, 100, 0]) vln_one_sin_exp($t + 7.2560, 2.8900, 183.1665, 0.0260, :fm_index, 1.0480, :amp_env, [0, 0, 3.4602, 1, 4.6713, 0.7, 5.1903, 1, 96.5398, 0.6923, 100, 0]) vln_one_sin_exp($t + 7.2710, 1.6210, 187.0685, 0.0170, :fm_index, 0.1800, :amp_env, [0, 0, 6.169, 1.0, 8.3282, 0.7, 9.2535, 1, 93.8310, 0.5294, 100, 0]) vln_one_sin_exp($t + 7.2920, 2.0160, 183.1665, 0.0290, :fm_index, 1.0480, :amp_env, [0, 0, 4.9603, 1, 6.6964, 0.7, 7.4405, 1, 95.0397, 0.7241, 100, 0]) vln_one_sin_exp($t + 7.2920, 12.0160, 183.1665, 0.0290, :fm_index, 1.0480, :amp_env, [0, 0, 0.832, 1, 1.1235, 0.7, 1.248, 1.0, 99.1678, 0.7241, 100, 0]) vln_one_sin_exp($t + 7.3300, 0.7300, 184.9970, 0.0170, :fm_index, 0.0960, :amp_env, [0, 0, 13.699, 1, 18.4932, 0.7, 20.548, 1.0, 86.3014, 0.529, 100, 0]) vln_one_sin_exp($t + 7.3570, 1.9600, 183.1665, 0.0280, :fm_index, 1.0480, :amp_env, [0, 0, 5.1020, 1.0, 6.8878, 0.7, 7.6531, 1, 94.8980, 0.7143, 100, 0]) vln_one_sin_exp($t + 7.3820, 2.2450, 61.7355, 0.0330, :fm_index, 0.2330, :amp_env, [0, 0, 4.4543, 1, 6.0134, 0.7, 6.6815, 1, 95.5457, 0.7576, 100, 0]) vln_one_sin_exp($t + 7.3820, 12.2450, 61.7355, 0.0330, :fm_index, 0.2330, :amp_env, [0, 0, 0.8167, 1, 1.1025, 0.7, 1.2250, 1, 99.1833, 0.7576, 100, 0]) vln_one_sin_exp($t + 7.5410, 3.0130, 246.5050, 0.0360, :fm_index, 1.1350, :amp_env, [0, 0, 3.3190, 1.0, 4.4806, 0.7, 4.9784, 1, 96.6810, 0.7778, 100, 0]) vln_one_sin_exp($t + 7.5570, 2.3220, 1251.5960, 0.0400, :fm_index, 0.2990, :amp_env, [0, 0, 4.3066, 1, 5.8140, 0.7, 6.4599, 1, 95.6934, 0.8, 100, 0]) vln_one_sin_exp($t + 7.5570, 18.3220, 1251.5960, 0.0200, :fm_index, 0.2990, :amp_env, [0, 0, 0.5458, 1.000, 0.7368, 0.7, 0.8187, 1, 99.4542, 0.6, 100, 0]) vln_one_sin_exp($t + 8.1060, 1.9900, 183.1665, 0.0230, :fm_index, 1.0480, :amp_env, [0, 0, 5.0251, 1.0, 6.7839, 0.7, 7.5377, 1, 94.9749, 0.6522, 100, 0]) vln_one_sin_exp($t + 8.2570, 1.9180, 61.7355, 0.0330, :fm_index, 0.2330, :amp_env, [0, 0, 5.2138, 1, 7.0386, 0.7, 7.8206, 1, 94.7862, 0.7576, 100, 0]) vln_one_sin_exp($t + 8.6370, 1.3090, 183.1665, 0.0310, :fm_index, 1.0480, :amp_env, [0, 0, 7.6394, 1, 10.3132, 0.7, 11.4591, 1, 92.3606, 0.7419, 100, 0]) vln_one_sin_exp($t + 9.0330, 1.1590, 183.1665, 0.0250, :fm_index, 1.0480, :amp_env, [0, 0, 8.6281, 1, 11.6480, 0.7, 12.9422, 1, 91.3719, 0.6800, 100, 0]) vln_one_sin_exp($t + 9.0980, 1.2400, 30.8675, 0.0330, :fm_index, 0.2330, :amp_env, [0, 0, 8.0645, 1, 10.8871, 0.7, 12.0968, 1, 91.9355, 0.7576, 100, 0]) vln_one_sin_exp($t + 9.0980, 11.2400, 30.8675, 0.0130, :fm_index, 0.2330, :amp_env, [0, 0, 0.8897, 1, 1.2011, 0.7, 1.3345, 1, 99.1103, 0.3846, 100, 0]) vln_one_sin_exp($t + 9.1260, 0.2600, 123.4710, 0.0170, :fm_index, 1.2050, :amp_env, [0, 0, 38.462, 1, 51.9231, 0.7, 57.6923, 1, 61.5385, 0.5294, 100, 0]) vln_one_sin_exp($t + 9.1260, 10.2600, 123.4710, 0.0170, :fm_index, 1.2050, :amp_env, [0, 0, 0.9747, 1, 1.3158, 0.7, 1.4620, 1, 99.0253, 0.5294, 100, 0]) vln_one_sin($t + 0.0600, 13.8770, 3951.1200, 0.0090, :amp_env, updown) vln_one_sin($t + 0.2600, 14.8770, 123.4725, 0.0170, :fm_index, 1.5, :amp_env, updown) vln_one_sin($t + 0.2600, 13.8770, 61.7363, 0.0170, :fm_index, 1.5, :amp_env, updown) vln_one_sin($t + 0.2600, 12.8770, 30.8681, 0.0170, :fm_index, 1.5, :amp_env, updown) vln_one_sin($t + 0.2600, 11.8770, 15.4341, 0.0170, :fm_index, 1.5, :amp_env, updown) $t += 28.0 restore_fm_violin_defaults() cel_one_sum($t + 0.2620, 0.3906, 440, 0.4500, :fm_index, 1.2, :reverb_amount, 0.0013, :amp_env, [0, 0, 0.7680, 1, 4.7774, 0.6, 9.7891, 0.3, 24.8243, 0.1, 100, 0]) cel_one_sum($t + 0.2640, 0.5220, 220, 0.4500, :fm_index, 1.2, :reverb_amount, 0.0012, :amp_env, [0, 0, 0.5747, 1.0, 4.5919, 0.6, 9.6134, 0.3, 24.6778, 0.1, 100, 0]) cel_one_sum($t + 0.2660, 1.5660, 880, 0.4500, :fm_index, 1.2, :reverb_amount, 0.0014, :amp_env, [0, 0, 0.1916, 1.0, 4.2242, 0.6, 9.2651, 0.3, 24.3876, 0.1, 100, 0]) cel_one_sum($t + 0.2680, 1.5660, 110, 0.4500, :fm_index, 1.2, :reverb_amount, 0.0013, :amp_env, [0, 0, 0.1916, 1.0, 4.2242, 0.6, 9.2651, 0.3, 24.3876, 0.1, 100, 0]) $t += 3.0 vln_one_sin($t + 0.8600, 0.9, 733.3330, 0.1875, :fm_index, 0.2, :distance, 1.0, :reverb_amount, 0.0012, :amp_env, [0, 0, 0.3333, 1, 4.3603, 0.6, 9.3939, 0.3, 24.4950, 0.1, 100, 0]) vln_one_sin($t + 0.8600, 0.2250, 550, 0.1875, :fm_index, 0.2, :distance, 1.0, :reverb_amount, 0.0015, :amp_env, [0, 0, 1.3333, 1, 5.3199, 0.6, 10.3030, 0.3, 25.2525, 0.1, 100, 0]) vln_one_sin($t + 0.8600, 0.4500, 586.6670, 0.3750, :fm_index, 0.2, :distance, 1.0, :reverb_amount, 0.0013, :amp_env, [0, 0, 0.6667, 1, 4.6801, 0.6, 9.6970, 0.3, 24.7475, 0.1, 100, 0]) vln_one_sin($t + 0.9020, 0.9, 733.3330, 0.1875, :fm_index, 0.4, :distance, 1.0, :reverb_amount, 0.0013, :amp_env, [0, 0, 0.3333, 1, 4.3603, 0.6, 9.3939, 0.3, 24.4950, 0.1, 100, 0]) vln_one_sin($t + 0.9020, 0.2250, 550, 0.1875, :fm_index, 0.4, :distance, 1.0, :reverb_amount, 0.0010, :amp_env, [0, 0, 1.3333, 1, 5.3199, 0.6, 10.3030, 0.3, 25.2525, 0.1, 100, 0]) vln_one_sin($t + 0.9020, 0.4500, 586.6670, 0.3750, :fm_index, 0.4, :distance, 1.0, :reverb_amount, 0.0015, :amp_env, [0, 0, 0.6667, 1, 4.6801, 0.6, 9.6970, 0.3, 24.7475, 0.1, 100, 0]) vln_one_sin($t + 0.9430, 0.9, 366.6670, 0.1875, :fm_index, 0.6, :distance, 1.0, :reverb_amount, 0.0016, :amp_env, [0, 0, 0.3333, 1, 4.3603, 0.6, 9.3939, 0.3, 24.4950, 0.1, 100, 0]) vln_one_sin($t + 0.9430, 0.2250, 275, 0.1875, :fm_index, 0.6, :distance, 1.0, :reverb_amount, 0.0015, :amp_env, [0, 0, 1.3333, 1, 5.3199, 0.6, 10.3030, 0.3, 25.2525, 0.1, 100, 0]) vln_one_sin($t + 0.9430, 0.4500, 293.3340, 0.3750, :fm_index, 0.6, :distance, 1.0, :reverb_amount, 0.0015, :amp_env, [0, 0, 0.6667, 1, 4.6801, 0.6, 9.6970, 0.3, 24.7475, 0.1, 100, 0]) vln_one_sin($t + 0.9850, 0.9, 733.3330, 0.1875, :fm_index, 0.8, :distance, 1.0, :reverb_amount, 0.0010, :amp_env, [0, 0, 0.3333, 1, 4.3603, 0.6, 9.3939, 0.3, 24.4950, 0.1, 100, 0]) vln_one_sin($t + 0.9850, 0.2250, 550, 0.1875, :fm_index, 0.8, :distance, 1.0, :reverb_amount, 0.0013, :amp_env, [0, 0, 1.3333, 1, 5.3199, 0.6, 10.3030, 0.3, 25.2525, 0.1, 100, 0]) untrace_var(:$t) end end unless provided?(:snd) main() end # fmviolin.rb ends here snd-16.1/sndins/samples/agn.fth0000755000076400007640000001012012433105741014542 0ustar bilbil#! /usr/bin/env fth \ agn.fth -- Bill Schottstaedt's agn.cl \ (see clm-2/clm-example.clm and clm-2/bess5.cl) \ Translator/Author: Michael Scholz \ Created: 04/12/15 23:30:43 \ Changed: 14/11/17 23:06:11 \ Type do-agn \ or start the script in a shell. #t value *clm-c-version* dl-load sndlib Init_sndlib *clm-c-version* [if] dl-load sndins Init_sndins [else] require clm-ins [then] require clm require env *argc* 2 > [if] *argv* 2 array-ref [else] "agn.fsm" [then] value agn-test-file 60.0 value agn-time #t to *clm-play* #t to *clm-statistics* #t to *clm-verbose* 44100 to *clm-srate* 2 to *clm-channels* <'> jc-reverb to *clm-reverb* '( :volume 0.8 ) to *clm-reverb-data* 2 to *clm-reverb-channels* #t to *clm-delete-reverb* mus-next to *clm-header-type* mus-bfloat to *clm-sample-type* : rbell ( x -- r ) 100 f* '( 0 0 10 0.25 90 1 100 1 ) 1.0 envelope-interp ; : tune ( x -- r ) { x } #( 1 256/243 9/8 32/27 81/64 4/3 1024/729 3/2 128/81 27/16 16/9 243/128 2 ) x 12.0 fmod f>s array-ref 2.0 x 12.0 f/ floor f** f* ; #( 0 0 2 4 11 11 5 6 7 9 2 0 0 ) constant agn-mode 256 constant agn-lim #f value agn-octs #f value agn-pits #f value agn-rhys #f value agn-amps #f value agn-begs : agn-init ( -- ) agn-lim make-array map! 1.0 random rbell f2* 4.0 f+ floor end-map to agn-octs agn-lim make-array map! agn-mode 1.0 random 12.0 f* floor f>s array-ref end-map to agn-pits agn-lim make-array map! 1.0 random 6.0 f* 4.0 f+ end-map to agn-rhys agn-lim make-array map! 1.0 random rbell 8.0 f* 1.0 f+ end-map to agn-amps agn-lim make-array map! 1.0 random 0.9 f< if 1.0 random f2* 4.0 f+ else 4.0 random 6.0 f* then end-map to agn-begs ; : agn ( fname -- ) ( fname ) io-open-write { io } io "\\ from agn.cl (clm-2/clm-example.clm, clm-2/bess5.cl)\n" io-write io "\\\n" io-write io "%s\n" '( make-default-comment ) io-write-format #( '( 0 0 40 0.1 60 0.2 75 0.4 82 1 90 1 100 0 ) '( 0 0 60 0.1 80 0.2 90 0.4 95 1 100 0 ) '( 0 0 10 1 16 0 32 0.1 50 1 56 0 60 0 90 0.3 100 0 ) '( 0 0 30 1 56 0 60 0 90 0.3 100 0 ) '( 0 0 50 1 80 0.3 100 0 ) '( 0 0 40 0.1 60 0.2 75 0.4 82 1 90 1 100 0 ) '( 0 0 40 0.1 60 0.2 75 0.4 82 1 90 1 100 0 ) '( 0 0 10 1 32 0.1 50 1 90 0.3 100 0 ) '( 0 0 60 0.1 80 0.3 95 1 100 0 ) '( 0 0 80 0.1 90 1 100 0 ) ) { wins } agn-init 4 1 do 0 4 0 { cellbeg cellsiz cellctr } 1 i s>f i 1- s>f 0.2 { whichway base mi mytempo } 0.0 0.0 { nextbeg beg } begin beg agn-time f< cellctr agn-lim < and while beg nextbeg f+ to beg mytempo 1.0 random 0.2 f* 0.9 f+ f* ( r ) agn-rhys cellctr array-ref f* 0.25 fmax to nextbeg 16.352 2.0 mi f** f/ ( r1 ) agn-pits cellctr array-ref tune f* ( r1 r2 ) 2.0 agn-octs cellctr array-ref f** f* { freq } ( r1 ) freq 100.0 f< if nextbeg f2* else nextbeg then { dur } ( r1 ) agn-amps cellctr array-ref 60.0 base f* 1/f f* 0.003 fmax { amp } ( r1 ) 1.0 random f2* base f* { ind } ( r1 ) base 0.1 f* { revamt } ( r1 ) 10.0 beg beg floor f- f* floor f>s { winnum } ( r1 ) 0.00001 freq 2.0 flogn 4.0 f- 4.0 f** ( r1 r2 ) f* { ranamt } io " %f %f %f %f :fm-index %f :amp-env %S :reverb-amount %f :noise-amount %f fm-violin" '( beg dur freq amp ind wins winnum array-ref revamt ranamt ) io-write-format cellctr 1+ to cellctr cellctr cellsiz cellbeg + > if cellbeg 1+ to cellbeg 1.0 random 0.5 f> if cellsiz whichway + to cellsiz then cellsiz 16 > 1.0 random 0.99 f> && if -2 to whichway else cellsiz 12 > 1.0 random 0.999 f> && if -1 to whichway else cellsiz 4 < if 1 to whichway then then then cellbeg 3 + to cellbeg cellbeg to cellctr then repeat loop io "\n\n\\ %s ends here\n" '( agn-test-file ) io-write-format io io-close ; : do-agn ( -- ) agn-test-file undef file-basename ".snd" $+ { sndfile } "\\ writing \"%s\"\n" '( agn-test-file ) fth-print agn-test-file agn :output sndfile agn-test-file clm-load ; 'snd provided? [unless] do-agn [then] \ agn.fth ends here snd-16.1/sndins/samples/agn.rb0000755000076400007640000001005312433105741014371 0ustar bilbil#! /usr/bin/env ruby # agn.rb -- Bill Schottstaedt's agn.cl # (see clm-2/clm-example.clm and clm-2/bess5.cl) # Translator/Author: Michael Scholz # Created: 03/05/24 20:35:03 # Changed: 14/11/18 23:29:44 # Type do_agn # or start the script in a shell. $clm_c_version = true require "sndlib" if $clm_c_version require "sndins" else require "v" # fm_violin, jc_reverb require "clm-ins" # nrev end require "clm" require "ws" require "env" $clm_play = true $clm_statistics = true $clm_verbose = true $clm_srate = 44100 $clm_channels = 2 $clm_reverb = :jc_reverb $clm_reverb_data = [:volume, 0.8] $clm_reverb_channels = 2 $clm_delete_reverb = true $clm_header_type = Mus_next $clm_sample_type = Mus_bfloat class Agn include Math include Env Limit = 256 Time = 60 def initialize mode = [0, 0, 2, 4, 11, 11, 5, 6, 7, 0, 0, 0, 0] @octs = make_array(Limit) do |i| (4 + 2 * rbell(random(1.0))).floor end @pits = make_array(Limit) do |i| mode[(12 * random(1.0)).floor] end @rhys = make_array(Limit) do |i| (4 + 6 * random(1.0)).floor end @amps = make_array(Limit) do |i| (1 + 8 * rbell(random(1.0))).floor end end def tune(x) [1.0, 256.0 / 243, 9.0 / 8, 32.0 / 27, 81.0 / 64, 4.0 / 3, 1024.0 / 729, 3.0 / 2, 128.0 / 81, 27.0 / 16, 16.0 / 9, 243.0 / 128, 2.0].at(x % 12) * 2 ** x.divmod(12).first end def rbell(x) envelope_interp(x * 100, [0, 0, 10, 0.25, 90, 1.0, 100, 1.0]) end def agn(file) File.open(file, "w") do |f| f << "# from agn.cl (clm-2/clm-example.clm, clm-2/bess5.cl)\n" f << "#\n" f << make_default_comment() << "\n\n" wins = [[0, 0, 40, 0.1, 60, 0.2, 75, 0.4, 82, 1, 90, 1, 100, 0], [0, 0, 60, 0.1, 80, 0.2, 90, 0.4, 95, 1, 100, 0], [0, 0, 10, 1, 16, 0, 32, 0.1, 50, 1, 56, 0, 60, 0, 90, 0.3,100,0], [0, 0, 30, 1, 56, 0, 60, 0, 90, 0.3, 100, 0], [0, 0, 50, 1, 80, 0.3, 100, 0], [0, 0, 40, 0.1, 60, 0.2, 75, 0.4, 82, 1, 90, 1, 100, 0], [0, 0, 40, 0.1, 60, 0.2, 75, 0.4, 82, 1, 90, 1, 100, 0], [0, 0, 10, 1, 32, 0.1, 50, 1, 90, 0.3, 100, 0], [0, 0, 60, 0.1, 80, 0.3, 95, 1, 100, 0], [0, 0, 80, 0.1, 90, 1, 100, 0]] (1..3).each do |i| cellbeg, cellsiz, cellctr = 0, 4, 0 whichway, base, mi, winnum, mytempo = 1, i, i - 1, 0, 0.2 nextbeg = revamt = ranamt = beg = dur = freq = ampl = ind = 0.0 while beg < Time and cellctr < Limit beg += nextbeg nextbeg = dur = [ 0.25, mytempo * (0.9 + 0.2 * random(1.0)) * @rhys[cellctr]].max freq = (16.352 / 2 ** mi) * tune(@pits[cellctr]) * 2 ** @octs[cellctr] dur += dur if freq < 100 ampl = [0.003, @amps[cellctr] * (1.0 / (60 * base))].max ind = random(1.0) * 2 * base revamt = base * 0.1 winnum = (10 * (beg - beg.floor)).floor ranamt = 0.00001 * (logn(freq, 2.0) - 4) ** 4 f << format("\ fm_violin(%f, %f, %f, %f, :fm_index, %f, :amp_env, %s, :reverb_amount, %f, :noise_amount, %f)\n", beg, dur, freq, ampl, ind, wins[winnum].inspect, revamt, ranamt) cellctr += 1 if cellctr > (cellsiz + cellbeg) cellbeg += 1 if random(1.0) > 0.5 cellsiz += whichway end if cellsiz > 16 and random(1.0) > 0.99 whichway = -2 if cellsiz > 12 and random(1.0) > 0.999 whichway = -1 if cellsiz < 4 whichway = 1 end end end cellbeg += 3 cellctr = cellbeg end end end f << "\n# " + file + " ends here\n" end file end end def do_agn(file = "agn.rbm") sndfile = File.basename(file, ".*") + ".snd" message("Writing %s", file.inspect) Agn.new.agn(file) clm_load(file, :clm, true, :output, sndfile) end unless provided?(:snd) do_agn((ARGV[0] or "agn.rbm")) end # agn.rb ends here snd-16.1/sndins/samples/agn.scm0000644000076400007640000001224512433105741014552 0ustar bilbil#! /usr/opt/bin/snd-s7-nogui -noinit !# ;;; agn.scm -- Bill Schottstaedt's agn.cl ;;; (see clm-2/clm-example.clm and clm-2/bess5.cl) ;; Translator/Author: Michael Scholz ;; Created: 03/06/24 19:05:06 ;; Changed: 14/11/18 22:59:13 ;; Try (do-agn) (define *clm-c-version* #t) (if (not (provided? 'snd)) (begin (define (snd-error . args) (apply format #t args) (exit 1)))) (if (not (provided? 'sndlib)) (let ((hsndlib (dlopen "libsndlib.so"))) (if (string? hsndlib) (snd-error (format #f "script needs the sndlib module: ~A" hsndlib)) (dlinit hsndlib "Init_sndlib")))) (if *clm-c-version* (if (not (provided? 'sndins)) (let ((hsndins (dlopen "libsndins.so"))) (if (string? hsndins) (snd-error (format #f "script needs the sndins module: ~A" hsndins)) (dlinit hsndins "Init_sndins")))) (load "v.scm")) (if (provided? 'snd) (load "ws.scm") (load "sndlib-ws.scm")) (set! *clm-play* #t) (set! *clm-statistics* #t) (set! *clm-verbose* #t) (set! *clm-srate* 44100) (set! *clm-channels* 2) (set! *clm-reverb* jc-reverb) (set! *clm-reverb-data* '(:volume 0.8)) (set! *clm-reverb-channels* 2) (set! *clm-delete-reverb* #t) (set! *clm-header-type* mus-next) (set! *clm-sample-type* mus-bfloat) (define (snd-msg frm . args) (snd-print (apply format (append (list #f frm) args)))) (define (main args) (do-agn (if (= 2 (length args)) (cadr args) "agn.clm"))) (define* (do-agn (file "agn.clm")) (let ((sndfile (format #f "~A.snd" "agn"))) (snd-msg ";; Writing ~S~%" file) (agn file) (with-sound (:output sndfile) (snd-msg ";; Loading ~S~%" file) (load file)))) (define lim 256) (define time 60) (define mode (list->vector '(0 0 2 4 11 11 5 6 7 0 0 0 0))) (define rats (list->vector '(1.0 256/243 9/8 32/27 81/64 4/3 1024/729 3/2 128/81 27/16 16/9 243/128 2.0))) (define bell '(0 0 10 0.25 90 1.0 100 1.0)) (define octs (make-vector (1+ lim))) (define pits (make-vector (1+ lim))) (define rhys (make-vector (1+ lim))) (define amps (make-vector (1+ lim))) (define (tune x) (let* ((pit (modulo x 12)) (oct (inexact->exact (floor (/ x 12)))) (base (vector-ref rats pit))) (* base (expt 2 oct)))) (define (rbell x) (envelope-interp (* x 100) bell)) (define* (glog r b) (if (<= r 0) (error "r must be > 0")) (if (and b (<= b 0)) (error "b must be > 0")) (if b (/ (log r) (log b)) (log r))) (define (agn file) (let ((wins (list->vector '((0 0 40 0.1 60 0.2 75 0.4 82 1 90 1 100 0) (0 0 60 0.1 80 0.2 90 0.4 95 1 100 0) (0 0 10 1 16 0 32 0.1 50 1 56 0 60 0 90 0.3 100 0) (0 0 30 1 56 0 60 0 90 0.3 100 0) (0 0 50 1 80 0.3 100 0) (0 0 40 0.1 60 0.2 75 0.4 82 1 90 1 100 0) (0 0 40 0.1 60 0.2 75 0.4 82 1 90 1 100 0) (0 0 10 1 32 0.1 50 1 90 0.3 100 0) (0 0 60 0.1 80 0.3 95 1 100 0) (0 0 80 0.1 90 1 100 0))))) (do ((i 0 (1+ i))) ((= i (+ lim 1))) (vector-set! octs i (inexact->exact (floor (+ 4 (* 2 (rbell (random 1.0))))))) (vector-set! pits i (vector-ref mode (inexact->exact (floor (* 12 (random 1.0)))))) (vector-set! rhys i (inexact->exact (floor (+ 4 (* 6 (random 1.0)))))) (vector-set! amps i (inexact->exact (floor (+ 1 (* 8 (rbell (random 1.0)))))))) (call-with-output-file file (lambda (out-port) (format out-port ";; from agn.cl (see clm-2/clm-example.clm and clm-2/bess5.cl)~%") (do ((i 1 (1+ i))) ((> i 3)) (let ((cellbeg 0) (cellsiz 4) (cellctr 0) (whichway 1) (base i) (mi (- i 1)) (winnum 0) (mytempo 0.2) (nextbeg 0.0) (revamt 0.0) (ranamt 0.0) (beg 0.0) (dur 0.0) (freq 0.0) (ampl 0.0) (ind 0.0)) (while (and (< beg time) (< cellctr lim)) (set! beg (+ beg nextbeg)) (set! nextbeg (max 0.25 (* mytempo (+ 0.9 (* 0.2 (random 0.1))) (vector-ref rhys cellctr)))) (set! freq (* (/ 16.352 (expt 2 mi)) (tune (vector-ref pits cellctr)) (expt 2 (vector-ref octs cellctr)))) (set! dur nextbeg) (if (< freq 100) (set! dur (+ dur dur))) (set! ampl (max 0.003 (* (vector-ref amps cellctr) (/ (* 60 base))))) (set! ind (* (random 1.0) 2 base)) (set! cellctr (1+ cellctr)) (set! revamt (* base 0.1)) (set! winnum (inexact->exact (floor (* 10 (- beg (floor beg)))))) (set! ranamt (* 0.00001 (expt (- (glog freq 2.0) 4) 4))) (format out-port " (fm-violin ~F ~F ~F ~F :fm-index ~F :amp-env '~S :reverb-amount ~F :noise-amount ~F)" beg dur freq ampl ind (vector-ref wins winnum) revamt ranamt) (set! cellctr (1+ cellctr)) (if (> cellctr (+ cellsiz cellbeg)) (begin (set! cellbeg (1+ cellbeg)) (if (> (random 1.0) 0.5) (set! cellsiz (+ cellsiz whichway))) (if (and (> cellsiz 16) (> (random 1.0) 0.99)) (begin (set! whichway -2) (if (and (> cellsiz 12) (> (random 1.0) 0.999)) (begin (set! whichway -1) (if (< cellsiz 4) (set! whichway 1)))))) (set! cellbeg (+ cellbeg 3)) (set! cellctr cellbeg)))))) (format out-port "~%~%;; ~A ends here~%" file)))) file) (do-agn) (exit 0) ;; agn.scm ends here snd-16.1/sndins/samples/fmviolin.scm0000644000076400007640000026550112433105741015635 0ustar bilbil#! /usr/opt/bin/snd-s7-nogui -noinit !# ;;; Examples of the fm violin (see v.ins) ;;; This file semi-automatically translated from a sambox note list ca 1983. ;;; ;; Translator/Author: Michael Scholz ;; Created: 03/06/24 19:05:06 ;; Changed: 14/11/18 23:54:35 ;; Type (short-example) ;; or (long-example) (define *clm-c-version* #f) (if (not (provided? 'sndlib)) (let ((hsndlib (dlopen "libsndlib.so"))) (if (string? hsndlib) (snd-error (format #f "script needs the sndlib module: ~A" hsndlib)) (dlinit hsndlib "Init_sndlib")))) (if *clm-c-version* (if (not (provided? 'sndins)) (let ((hsndins (dlopen "libsndins.so"))) (if (string? hsndins) (snd-error (format #f "script needs the sndins module: ~A" hsndins)) (dlinit hsndins "Init_sndins")))) (begin (load "v.scm") (load "freeverb.scm"))) (if (provided? 'snd) (load "ws.scm") (load "sndlib-ws.scm")) (set! *clm-file-name* "test-ins-s.snd") (set! *clm-play* #t) (set! *clm-statistics* #t) (set! *clm-verbose* #t) (set! *clm-srate* 44100) (set! *clm-channels* 2) (set! *clm-reverb-channels* 2) (set! *clm-delete-reverb* #t) (set! *clm-header-type* mus-next) (set! *clm-sample-type* mus-bfloat) ;; (script-args): ("-noinit" "./fmviolin.scm") (define (main) (if (> (length (script-args)) 2) (short-example) (long-example))) ;;show progress of long example (define show #t) (define start-time 0) (define counter 0) (define (snd-msg frm . args) (snd-print (apply format (append (list #f frm) args)))) (define (current-score-time time) (set! counter (+ counter 1)) (if show (snd-msg ";; ~2D: score ~3D utime ~7,3F~%" counter (- time 24) (/ (- (get-internal-real-time) start-time) 100.0)))) (definstrument (violin-new beg dur freq amp fm1-rat fm2-rat fm3-rat fm-index reverb-amount amp-env) (do ((i 0 (1+ i))) ((= 5 i)) (fm-violin (+ beg (* i .05 (random 1.0))) (+ dur (* i .1 (random 1.0))) (if (> freq 400) (* freq (+ .99 (* .02 (random 1.0)))) (if (> freq 200) (* freq (+ .995 (* .01 (random 1.0)))) (* freq (+ .999 (* .002 (random 1.0)))))) amp :reverb-amount (or reverb-amount .2) :fm-index (* fm-index (+ .75 (random 1.0))) :amp-env amp-env))) (define (short-example) (with-sound (:reverb nrev :reverb-data '(:lp-coeff 0.6)) (violin-new 0 8.53 993.323 .03 :fm-index .75 :reverb-amount .20 :amp-env (list 0 0 221.00 1 240.00 0)) (violin-new 5 4.53 (* 5/6 993.323) .02 :fm-index .55 :reverb-amount .20 :amp-env (list 0 0 221.00 1 240.00 0)))) (define pna '(0 0 1 1 10 .6000 25 .3 100 0)) (define ind2 '(0 1 25 .4 75 .6000 100 0)) (define high_att_ind '(0 1 25 .2000 75 .4 100 0)) (define no_att_ind '(0 .6000 75 .6000 100 0)) (define no_dec_ind '(0 1 25 .4 75 .6000 100 .6000)) (define no_att_or_dec_ind '(0 .6000 100 .6000)) (define amp '(0 0 25 1 60 .7000 75 1 100 0)) (define ramp '(0 0 100 1)) (define fast_up '(0 0 25 1 100 1)) (define slow_up '(0 0 25 0 100 1)) (define skwfrq '(0 -1 5 .2500 10 0 100 .1)) (define circle '(0 90 0 90 0 90 0 90)) (define oldpizzf '(0 0 1 1 5 .6000 10 .3 25 .1 100 0)) (define newpizzf '(0 0 1 1 5 .6000 10 .3 25 .1 99 .0200 100 0)) (define pizzf '(0 0 1 1 5 .6000 10 .3 25 .1 100 0)) (define legatof '(0 0 30 1 90 1 100 0)) (define marcatof '(0 0 3 1 10 .8000 95 1 100 0)) (define one '(0 1 100 1)) (define mod_up '(0 0 25 0 75 1 100 1)) (define mod_down '(0 1 25 1 75 0 100 0)) (define one_to_zero '(0 1 75 1 100 0)) (define zero_to_one '(0 0 75 0 100 1)) (define down_flat '(0 1 25 0 75 .0500 100 0)) (define down_down '(0 1 25 0 75 .0500 100 -1)) (define down_up '(0 1 25 0 75 .0500 100 1)) (define flat_down '(0 -.1000 10 .1 25 0 75 .0500 100 -1)) (define flat_up '(0 -.1000 10 .1 25 0 75 0 100 1)) (define up_flat '(0 -1 25 .0500 75 0 100 0)) (define up_up '(0 -1 25 .0500 75 0 100 1)) (define up_down '(0 -1 25 .0500 75 0 100 -1)) (define swellf '(0 0 25 .8000 50 1 75 .8000 100 0)) (define fpf '(0 0 25 1 50 .3 75 .3 100 0)) (define indswell '(1 1 25 .4 75 1 100 0)) (define pyr '(0 1 25 .1 95 .1 100 0)) (define fbell '(0 1 2 1.1000 25 .7500 75 .5 100 .2000)) (define lowbell '(0 1 5 1.2500 25 .8000 75 .5 100 .2000)) (define abell '(0 0 .1 1 10 .6000 25 .3 50 .1500 90 .1 100 0)) (define dwnup '(0 1 10 .4 20 1 35 .3 45 .8000 60 .2000 80 .6000 100 0)) (define up50down '(0 0 50 1 100 0)) (define slowupfastdown '(0 0 25 1 97 1 100 0)) (define slowup '(0 0 50 .1 95 1 100 0)) (define indtoone '(0 1 25 .4 100 .6500)) (define tap '(0 0 1 1 99 1 100 0)) (define metalamp '(0 0 .5 1 5 1 10 .5 15 .2500 35 .1 100 0)) (define whoosh '(0 0 75 .1 90 .3 97 .6000 100 1)) (define mamp '(0 0 50 1 100 0)) (define n_amp '(0 0 65 1 100 0)) (define updown '(0 0 15 1 100 0)) (define indfunc '(0 1 20 0 100 0)) (define indfunc2 '(0 1 90 1 100 0)) (define ampfunc '(0 1 6 1 10 .5 20 .363 30 .27 40 .2 50 .12 60 .08 70 .04 100 0)) (define ampfunc1 '(0 0 1 1 3 1 10 .5 30 .2000 60 .0500 100 0)) (define z1amp '(0 0 20 .5 40 .1 60 .2000 80 1 100 0)) (define z2amp '(0 0 20 1 60 .1 75 .3 100 0)) (define newf '(0 0 .5 1 5 1 10 .5 15 .2500 35 .1 100 0)) (define yup '(0 0 1 1 100 0)) (define fm-violin-random-vibrato-rate 12.0) (define fm-violin-random-vibrato-amplitude .01) (define fm-violin-gliss-env skwfrq) (define fm-violin-glissando-amount .01) (define fm-violin-noise-amount .002) (define fm-violin-fm-index 1.0) (define fm-violin-amp-env '(0 0 25 1 75 1 100 0)) (define fm-violin-periodic-vibrato-rate 5.0) (define fm-violin-random-vibrato-rate 16.0) (define fm-violin-periodic-vibrato-amplitude 0.0025) (define fm-violin-random-vibrato-amplitude 0.005) (define fm-violin-noise-amount 0.0) (define fm-violin-noise-freq 1000.0) (define fm-violin-ind-noise-amount 0.0) (define fm-violin-ind-noise-freq 10.0) (define fm-violin-amp-noise-amount 0.0) (define fm-violin-amp-noise-freq 20.0) (define fm-violin-gliss-env '(0 0 100 0)) (define fm-violin-glissando-amount 0.0) (define fm-violin-fm1-env '(0 1 25 .4 75 .6 100 0)) (define fm-violin-fm2-env fm-violin-fm1-env) (define fm-violin-fm3-env fm-violin-fm1-env) (define fm-violin-fm1-rat 1.0) (define fm-violin-fm2-rat 3.0) (define fm-violin-fm3-rat 4.0) (define fm-violin-base 0.0) (define fm-violin-reverb-amount 0.01) (define fm-violin-index-type 1) (define fm-violin-index1 #f) (define fm-violin-index2 #f) (define fm-violin-index3 #f) (define (restore-fm-violin-defaults) (set! fm-violin-fm-index 1.0) (set! fm-violin-amp-env '(0 0 25 1 75 1 100 0)) (set! fm-violin-periodic-vibrato-rate 5.0) (set! fm-violin-random-vibrato-rate 16.0) (set! fm-violin-periodic-vibrato-amplitude 0.0025) (set! fm-violin-random-vibrato-amplitude 0.005) (set! fm-violin-noise-amount 0.0) (set! fm-violin-noise-freq 1000.0) (set! fm-violin-ind-noise-amount 0.0) (set! fm-violin-ind-noise-freq 10.0) (set! fm-violin-gliss-env '(0 0 100 0)) (set! fm-violin-glissando-amount 0.0) (set! fm-violin-fm1-env '(0 1 25 .4 75 .6 100 0)) (set! fm-violin-fm2-env fm-violin-fm1-env) (set! fm-violin-fm3-env fm-violin-fm1-env) (set! fm-violin-fm1-rat 1.0) (set! fm-violin-fm2-rat 3.0) (set! fm-violin-fm3-rat 4.0) (set! fm-violin-base 0.0) (set! fm-violin-reverb-amount 0.01) (set! fm-violin-index-type 1) (set! fm-violin-index1 #f) (set! fm-violin-index2 #f) (set! fm-violin-index3 #f)) (definstrument (old-fm-violin startime dur frequency amplitude (fm-index fm-violin-fm-index) (amp-env fm-violin-amp-env) (periodic-vibrato-rate fm-violin-periodic-vibrato-rate) (random-vibrato-rate fm-violin-random-vibrato-rate) (periodic-vibrato-amplitude fm-violin-periodic-vibrato-amplitude) (random-vibrato-amplitude fm-violin-random-vibrato-amplitude) (noise-amount fm-violin-noise-amount) (noise-freq fm-violin-noise-freq) (ind-noise-freq fm-violin-ind-noise-freq) (ind-noise-amount fm-violin-ind-noise-amount) (amp-noise-freq fm-violin-amp-noise-freq) (amp-noise-amount fm-violin-amp-noise-amount) (gliss-env fm-violin-gliss-env) (glissando-amount fm-violin-glissando-amount) (fm1-env fm-violin-fm1-env) (fm2-env fm-violin-fm2-env) (fm3-env fm-violin-fm3-env) (fm1-rat fm-violin-fm1-rat) (fm2-rat fm-violin-fm2-rat) (fm3-rat fm-violin-fm3-rat) (fm1-index fm-violin-index1) (fm2-index fm-violin-index2) (fm3-index fm-violin-index3) (degree 0.0) (distance 1.0) (reverb-amount fm-violin-reverb-amount) (base fm-violin-base) (index-type fm-violin-index-type)) (if *clm-c-version* (fm-violin startime dur frequency amplitude :fm-index fm-index :amp-env amp-env :periodic-vibrato-rate periodic-vibrato-rate :random-vibrato-rate random-vibrato-rate :periodic-vibrato-amplitude periodic-vibrato-amplitude :random-vibrato-amplitude random-vibrato-amplitude :noise-amount noise-amount :noise-freq noise-freq :ind-noise-freq ind-noise-freq :ind-noise-amount ind-noise-amount :amp-noise-freq amp-noise-freq :amp-noise-amount amp-noise-amount :gliss-env gliss-env :glissando-amount glissando-amount :fm1-env fm1-env :fm2-env fm2-env :fm3-env fm3-env :fm1-rat fm1-rat :fm2-rat fm2-rat :fm3-rat fm3-rat :fm1-index fm1-index :fm2-index fm2-index :fm3-index fm3-index :degree degree :distance distance :reverb-amount reverb-amount :base base :index-type index-type) (fm-violin startime dur frequency amplitude :fm-index fm-index :amp-env amp-env :periodic-vibrato-rate periodic-vibrato-rate :random-vibrato-rate random-vibrato-rate :periodic-vibrato-amplitude periodic-vibrato-amplitude :random-vibrato-amplitude random-vibrato-amplitude :noise-amount noise-amount :noise-freq noise-freq :ind-noise-freq ind-noise-freq :ind-noise-amount ind-noise-amount :amp-noise-freq amp-noise-freq :amp-noise-amount amp-noise-amount :gliss-env gliss-env :glissando-amount glissando-amount :fm1-env fm1-env :fm2-env fm2-env :fm3-env fm3-env :fm1-rat fm1-rat :fm2-rat fm2-rat :fm3-rat fm3-rat :fm1-index fm1-index :fm2-index fm2-index :fm3-index fm3-index :degree degree :distance distance :reverb-amount reverb-amount :base base))) (define fullbeg 24.0) (define-macro (vln_one_sin start-time duration frequency amplitude . rest) `(old-fm-violin ,(- start-time fullbeg) ,duration ,frequency ,(* amplitude .125) :degree (random 90.0) :noise-amount 0.0 ,@rest)) (define-macro (vln_one_sin_ran start-time duration frequency amplitude . rest) `(old-fm-violin ,(- start-time fullbeg) ,duration ,frequency ,(* amplitude .125) :degree (random 90.0) ,@rest)) (define-macro (vln_one_sin_exp start dur freq amp . rest) `(vln_one_sin ,start ,dur ,freq ,amp :base 0.03125 ,@rest)) (define-macro (violin start dur freq amp . rest) `(vln_one_sin ,start ,dur ,freq ,amp ,@rest)) (define-macro (cel_one_sum start-time duration frequency amplitude . rest) `(old-fm-violin ,(- start-time fullbeg) ,duration ,frequency ,(* amplitude .125) :degree (random 90.0) :index-type 0 ,@rest)) (define (long-example) (set! start-time (get-internal-real-time)) (with-sound (:reverb freeverb :reverb-data '(:room-decay 0.8)) (set! fm-violin-glissando-amount 0.0) (set! fm-violin-reverb-amount .1) (set! fm-violin-amp-env metalamp) (set! fm-violin-fm1-rat 6.718) (set! fm-violin-fm2-rat 4.414) (set! fm-violin-fm3-rat 5.141) (current-score-time 24) (vln_one_sin 24 1.6000 164.5868 .1600 :fm-index 2.1087) (vln_one_sin 24.0003 4 164.5868 .2600 :fm-index 1.5488) (vln_one_sin 24.0005 1.2000 125.9513 .2600 :fm-index 2.2999) (vln_one_sin 24.0005 2.8000 125.9513 .1600 :fm-index 1.6818) (vln_one_sin 24.0013 4 24.4994 .3 :fm-index 2.4557) (vln_one_sin 24.0033 3 24.4994 .3 :fm-index 1.9387) (vln_one_sin 24.0035 2.8000 24.4994 .2600 :fm-index 2.3828) (vln_one_sin 24.0040 .8000 24.4994 .1600 :fm-index 1.7348) (vln_one_sin 24.0043 4 24.4994 .3 :fm-index 2.0886) (set! fm-violin-fm1-rat 2.718) (set! fm-violin-fm2-rat 4.414) (set! fm-violin-fm3-rat 3.141) (current-score-time 30) (vln_one_sin 30.0003 1.2000 88.8854 .1600 :fm-index 2.0711) (vln_one_sin 30.0003 4 88.8854 .2600 :fm-index 2.0225) (vln_one_sin 30.0005 1.2000 102.7186 .2600 :fm-index 1.9300) (vln_one_sin 30.0010 1.2000 32.7025 .3600 :fm-index 1.9269) (vln_one_sin 30.0015 2.8000 32.7025 .2600 :fm-index 2.2153) (vln_one_sin 30.0023 2 32.7025 .2600 :fm-index 2.1968) (vln_one_sin 30.0023 4 32.7025 .3600 :fm-index 1.6091) (vln_one_sin 30.0025 2 32.7025 .2600 :fm-index 2.1766) (vln_one_sin 30.0035 1.2000 32.7025 .1600 :fm-index 1.5157) (vln_one_sin 30.0040 .8000 32.7025 .1600 :fm-index 1.8092) (vln_one_sin 30.0043 2 32.7025 .2600 :fm-index 1.6198) (set! fm-violin-reverb-amount .2) (set! fm-violin-fm3-rat 5.141) (current-score-time 36) (vln_one_sin 36.0003 1.2000 177.7708 .3 :fm-index 1.9631) (vln_one_sin 36.0003 4 177.7708 .3 :fm-index 1.9647) (vln_one_sin 36.0005 2.8000 336.2471 .1600 :fm-index 2.3977) (vln_one_sin 36.0008 1.2000 336.2471 .2500 :fm-index 2.4103) (vln_one_sin 36.0010 2 65.4050 .3 :fm-index 1.8419) (vln_one_sin 36.0033 2 65.4050 .3 :fm-index 2.4540) (vln_one_sin 36.0043 4 65.4050 .1600 :fm-index 2.2909) (set! fm-violin-reverb-amount .1) (current-score-time 42) (vln_one_sin 42.0003 1.2000 11.1107 .3 :fm-index 1.8715) (vln_one_sin 42.0003 4 11.1107 .3 :fm-index 2.4590) (vln_one_sin 42.0005 2.8000 21.0154 .1600 :fm-index 2.3802) (vln_one_sin 42.0008 1.2000 21.0154 .2500 :fm-index 1.7564) (vln_one_sin 42.0010 2 4.0878 .3 :fm-index 2.2529) (vln_one_sin 42.0033 2 4.0878 .3 :fm-index 1.9693) (vln_one_sin 42.0043 4 4.0878 .1600 :fm-index 2.2534) (restore-fm-violin-defaults) (set! fm-violin-noise-amount .1) (current-score-time 48) (vln_one_sin_ran 48 5.4000 116.5400 .2500 :fm-index 2.2822 :reverb-amount .0280 :amp-env '(0 0 .0556 1 4.0937 .6000 9.1414 .3 24.2845 .1 100.0 0)) (vln_one_sin_ran 48.0100 5.4000 43.6538 .2500 :fm-index 2.0867 :reverb-amount .0202 :amp-env '(0 0 .0556 1 4.0937 .6000 9.1414 .3 24.2845 .1 100.0 0)) (vln_one_sin_ran 48.0200 5.4000 130.8100 .2500 :fm-index 1.9652 :reverb-amount .0270 :amp-env '(0 0 .0556 1 4.0937 .6000 9.1414 .3 24.2845 .1 100.0 0)) (vln_one_sin_ran 48.0250 5.4000 87.3075 .2500 :fm-index 2.1524 :reverb-amount .0260 :amp-env '(0 0 .0556 1 4.0937 .6000 9.1414 .3 24.2845 .1 100.0 0)) (vln_one_sin_ran 48.0300 4.5000 261.6200 .1500 :fm-index 2.1384 :reverb-amount .0242 :amp-env '(0 0 .0667 1 4.1044 .6000 9.1515 .3 24.2929 .1 100 0)) (vln_one_sin_ran 48.0300 4.5000 174.6150 .1500 :fm-index 2.1425 :reverb-amount .0265 :amp-env '(0 0 .0667 1 4.1044 .6000 9.1515 .3 24.2929 .1 100 0)) (vln_one_sin_ran 48.0300 4.5000 130.8100 .1500 :fm-index 1.9805 :reverb-amount .0201 :amp-env '(0 0 .0667 1 4.1044 .6000 9.1515 .3 24.2929 .1 100 0)) (vln_one_sin_ran 48.0350 4.5000 43.6538 .1500 :fm-index 2.4876 :reverb-amount .0329 :amp-env '(0 0 .0667 1 4.1044 .6000 9.1515 .3 24.2929 .1 100 0)) (vln_one_sin_ran 48.0400 3.6000 220 .1500 :fm-index 1.8282 :reverb-amount .0244 :amp-env '(0 0 .0833 1 4.1204 .6000 9.1667 .3 24.3056 .1 100.0 0) :noise-amount .1500) (vln_one_sin_ran 48.0400 3.6000 174.6150 .1500 :fm-index 2.3479 :reverb-amount .0200 :amp-env '(0 0 .0833 1 4.1204 .6000 9.1667 .3 24.3056 .1 100.0 0) :noise-amount .1500) (vln_one_sin_ran 48.0400 3.6000 523.2400 .1500 :fm-index 1.6424 :reverb-amount .0286 :amp-env '(0 0 .0833 1 4.1204 .6000 9.1667 .3 24.3056 .1 100.0 0) :noise-amount .1500) (vln_one_sin_ran 48.0450 3.6000 349.2300 .1500 :fm-index 1.6449 :reverb-amount .0333 :amp-env '(0 0 .0833 1 4.1204 .6000 9.1667 .3 24.3056 .1 100.0 0) :noise-amount .1500) (vln_one_sin_ran 48.0500 6 699.4600 .1500 :fm-index 1.5570 :reverb-amount .1300 :amp-env tap) (vln_one_sin_ran 48.0500 6 1397.9200 .1500 :fm-index 1.5131 :reverb-amount .1300 :amp-env tap) (vln_one_sin_ran 48.0500 6 783.9800 .1500 :fm-index 2.2031 :reverb-amount .1300 :amp-env tap) (vln_one_sin_ran 48.0500 6 1046.4800 .1500 :fm-index 2.2724 :reverb-amount .1300 :amp-env tap) (vln_one_sin_ran 48.0600 9 21.8269 .1500 :fm-index 2.1048 :reverb-amount .1 :amp-env tap) (vln_one_sin_ran 48.0600 8 87.3075 .1500 :fm-index 1.8854 :reverb-amount .1 :amp-env tap) (vln_one_sin_ran 48.0600 7 65.4050 .1500 :fm-index 1.6781 :reverb-amount .1 :amp-env tap) (vln_one_sin_ran 48.0600 8 43.6538 .1500 :fm-index 1.7862 :reverb-amount .1 :amp-env tap) (vln_one_sin_ran 48.0700 6 175.6150 .1500 :fm-index 2.2656 :reverb-amount .1 :amp-env tap) (vln_one_sin_ran 48.0700 6 350.2300 .1500 :fm-index 2.4241 :reverb-amount .1 :amp-env tap) (vln_one_sin_ran 48.0700 6 131.8100 .1500 :fm-index 2.4294 :reverb-amount .1 :amp-env tap) (vln_one_sin_ran 48.0700 6 32.7025 .1500 :fm-index 1.5779 :reverb-amount .1 :amp-env tap) (vln_one_sin_ran 48.0800 6 196.9950 .1500 :fm-index 1.8511 :reverb-amount .1 :amp-env tap) (vln_one_sin_ran 48.0800 6 1047.4800 .1500 :fm-index 2.2148 :reverb-amount .1 :amp-env tap) (vln_one_sin_ran 48.0800 6 831.6200 .1500 :fm-index 1.9913 :reverb-amount .1 :amp-env tap) (vln_one_sin_ran 48.0800 6 2793.8400 .1500 :fm-index 2.2607 :reverb-amount .1 :amp-env tap) (vln_one_sin_ran 48.2700 6 784.9800 .1600 :fm-index 2.0693 :reverb-amount .1 :amp-env tap) (vln_one_sin_ran 48.2700 6 64.4050 .1600 :fm-index 1.6920 :reverb-amount .1 :amp-env tap) (vln_one_sin_ran 48.2700 6 208.6550 .1600 :fm-index 2.2597 :reverb-amount .1 :amp-env tap) ; from lizard (vln_one_sin_ran 48.2700 6 43.6538 .1600 :fm-index 2.2522 :reverb-amount .1 :amp-env tap) (current-score-time 60) (restore-fm-violin-defaults) (vln_one_sin_ran 60 1.8000 349.2300 .1600 :fm-index 2.1541 :reverb-amount .0225 :amp-env '(0 0 .1667 1 4.2003 .6000 9.2424 .3 24.3687 .1 100 0) :noise-amount .0500) (vln_one_sin_ran 60.0100 2.7000 146.8300 .1600 :fm-index 2.3335 :reverb-amount .0274 :amp-env '(0 0 .1111 1 4.1470 .6000 9.1919 .3 24.3266 .1 100.0 0) :noise-amount .0500) (vln_one_sin_ran 60.0200 1.8000 880 .1600 :fm-index 2.1910 :reverb-amount .0279 :amp-env '(0 0 .1667 1 4.2003 .6000 9.2424 .3 24.3687 .1 100 0) :noise-amount .0500) (vln_one_sin_ran 60.0250 3.6000 73.4150 .1600 :fm-index 2.1410 :reverb-amount .0223 :amp-env '(0 0 .0833 1 4.1204 .6000 9.1667 .3 24.3056 .1 100.0 0) :noise-amount .0500) (vln_one_sin_ran 60.0300 2.7000 87.3075 .1600 :fm-index 1.8491 :reverb-amount .0217 :amp-env '(0 0 .1111 1 4.1470 .6000 9.1919 .3 24.3266 .1 100.0 0) :noise-amount .0010) (vln_one_sin_ran 60.0300 2.7000 75.5662 .1600 :fm-index 1.9191 :reverb-amount .0204 :amp-env '(0 0 .1111 1 4.1470 .6000 9.1919 .3 24.3266 .1 100.0 0) :noise-amount .0010) (vln_one_sin_ran 60.0400 3.6000 52.3432 .1600 :fm-index 1.6090 :reverb-amount .0296 :amp-env '(0 0 .0833 1 4.1204 .6000 9.1667 .3 24.3056 .1 100.0 0) :noise-amount .0010) (vln_one_sin_ran 60.0450 1.8000 73.4150 .1600 :fm-index 2.2201 :reverb-amount .0221 :amp-env '(0 0 .1667 1 4.2003 .6000 9.2424 .3 24.3687 .1 100 0) :noise-amount .0010) (vln_one_sin_ran 60.0500 4 116.5400 .0600 :fm-index 2.0230 :reverb-amount .1 :amp-env tap :noise-amount .0010) (vln_one_sin_ran 60.0500 4 97.9975 .0600 :fm-index 1.7284 :reverb-amount .1 :amp-env tap :noise-amount .0010) (vln_one_sin_ran 60.0600 4 36.7075 .0600 :fm-index 1.6845 :reverb-amount .1 :amp-env tap :noise-amount .0010) (vln_one_sin_ran 60.0650 4 97.9975 .0600 :fm-index 2.4616 :reverb-amount .1 :amp-env tap :noise-amount .0010) (current-score-time 67) (vln_one_sin_ran 67 1.8000 261.6200 .1600 :fm-index 2.2576 :reverb-amount .0286 :amp-env '(0 0 .1667 1 4.2003 .6000 9.2424 .3 24.3687 .1 100 0) :noise-amount .0100) (vln_one_sin_ran 67.0100 2.7000 130.8100 .1600 :fm-index 2.1530 :reverb-amount .0330 :amp-env '(0 0 .1111 1 4.1470 .6000 9.1919 .3 24.3266 .1 100.0 0) :noise-amount .0100) (vln_one_sin_ran 67.0200 1.8000 523.2400 .1600 :fm-index 2.0608 :reverb-amount .0235 :amp-env '(0 0 .1667 1 4.2003 .6000 9.2424 .3 24.3687 .1 100 0) :noise-amount .0100) (vln_one_sin_ran 67.0250 3.6000 65.4050 .1600 :fm-index 2.2203 :reverb-amount .0234 :amp-env '(0 0 .0833 1 4.1204 .6000 9.1667 .3 24.3056 .1 100.0 0) :noise-amount .0100) (vln_one_sin_ran 67.0300 2.7000 65.4050 .1600 :fm-index 1.7089 :reverb-amount .0208 :amp-env '(0 0 .1111 1 4.1470 .6000 9.1919 .3 24.3266 .1 100.0 0) :noise-amount .0010) (vln_one_sin_ran 67.0300 2.7000 130.8100 .1600 :fm-index 2.2948 :reverb-amount .0269 :amp-env '(0 0 .1111 1 4.1470 .6000 9.1919 .3 24.3266 .1 100.0 0) :noise-amount .0010) (vln_one_sin_ran 67.0400 3.6000 32.7025 .1600 :fm-index 1.7677 :reverb-amount .0288 :amp-env '(0 0 .0833 1 4.1204 .6000 9.1667 .3 24.3056 .1 100.0 0) :noise-amount .0010) (vln_one_sin_ran 67.0450 1.8000 32.7025 .1600 :fm-index 1.9030 :reverb-amount .0209 :amp-env '(0 0 .1667 1 4.2003 .6000 9.2424 .3 24.3687 .1 100 0) :noise-amount .0010) (vln_one_sin_ran 67.0500 4 65.4050 .0600 :fm-index 2.2757 :reverb-amount .1 :amp-env tap :noise-amount .0010) (vln_one_sin_ran 67.0500 4 65.4050 .0600 :fm-index 2.2435 :reverb-amount .1 :amp-env tap :noise-amount .0010) (vln_one_sin_ran 67.0600 4 32.7025 .0600 :fm-index 1.9619 :reverb-amount .1 :amp-env tap :noise-amount .0010) (vln_one_sin_ran 67.0650 4 65.4050 .0600 :fm-index 2.0207 :reverb-amount .1 :amp-env tap :noise-amount .0010) (current-score-time 73) (vln_one_sin_ran 73.0100 .9000 3135.9200 .1600 :fm-index 2.1204 :reverb-amount .0024 :amp-env '(0 0 .3333 1 4.3603 .6000 9.3939 .3 24.4950 .1 100.0 0) :noise-amount .0100) (vln_one_sin_ran 73.0100 .4500 1567.9600 .1600 :fm-index 2.0691 :reverb-amount .0025 :amp-env '(0 0 .6667 1 4.6801 .6000 9.6970 .3 24.7475 .1 100 0) :noise-amount .0100) (vln_one_sin_ran 73.0200 .9000 6271.8400 .1600 :fm-index 2.2081 :reverb-amount .0022 :amp-env '(0 0 .3333 1 4.3603 .6000 9.3939 .3 24.4950 .1 100.0 0) :noise-amount .0100) (vln_one_sin_ran 73.0250 .9000 783.9800 .1600 :fm-index 1.8719 :reverb-amount .0022 :amp-env '(0 0 .3333 1 4.3603 .6000 9.3939 .3 24.4950 .1 100.0 0) :noise-amount .0100) (vln_one_sin_ran 73.0300 .2700 783.9800 .1600 :fm-index 1.9705 :reverb-amount .0020 :amp-env '(0 0 1.1111 1 5.1066 .6000 10.1010 .3 25.0842 .1 100.0 0) :noise-amount .0100) (vln_one_sin_ran 73.0300 .6300 1567.9600 .1600 :fm-index 1.6778 :reverb-amount .0021 :amp-env '(0 0 .4762 1 4.4974 .6000 9.5238 .3 24.6032 .1 100.0 0) :noise-amount .0100) (vln_one_sin_ran 73.0400 .9000 391.9900 .1600 :fm-index 1.9558 :reverb-amount .0023 :amp-env '(0 0 .3333 1 4.3603 .6000 9.3939 .3 24.4950 .1 100.0 0) :noise-amount .0100) (vln_one_sin_ran 73.0450 .4500 195.9950 .1600 :fm-index 2.1344 :reverb-amount .0027 :amp-env '(0 0 .6667 1 4.6801 .6000 9.6970 .3 24.7475 .1 100 0) :noise-amount .0100) (vln_one_sin_ran 73.0500 2 783.9800 .1600 :reverb-amount .0100 :amp-env tap :noise-amount .0090) (vln_one_sin_ran 73.0500 1 1567.9600 .1600 :reverb-amount .0100 :amp-env tap :noise-amount .0090) (vln_one_sin_ran 73.0600 2 391.9900 .1600 :reverb-amount .0100 :amp-env tap :noise-amount .0090) (vln_one_sin_ran 73.0650 1 783.9800 .1600 :reverb-amount .0100 :amp-env tap :noise-amount .0090) (vln_one_sin_ran 73.0700 2 195.9950 .1600 :reverb-amount .0100 :amp-env tap :noise-amount .0040) (vln_one_sin_ran 73.0700 1 1567.9600 .1600 :reverb-amount .0100 :amp-env tap :noise-amount .0040) (vln_one_sin_ran 73.0800 1 784.9800 .1600 :reverb-amount .0100 :amp-env tap :noise-amount .0040) (vln_one_sin_ran 73.0850 2 391.9900 .1600 :reverb-amount .0100 :amp-env tap :noise-amount .0040) (current-score-time 79) (vln_one_sin_ran 79.0100 .9000 97.9975 .1 :fm-index 2.0885 :reverb-amount .0031 :amp-env '(0 0 .3333 1 4.3603 .6000 9.3939 .3 24.4950 .1 100.0 0) :noise-amount .0100) (vln_one_sin_ran 79.0100 1.8000 48.9988 .1 :fm-index 2.2269 :reverb-amount .0026 :amp-env '(0 0 .1667 1 4.2003 .6000 9.2424 .3 24.3687 .1 100 0) :noise-amount .0100) (vln_one_sin_ran 79.0200 .9000 195.9950 .1 :fm-index 2.0305 :reverb-amount .0032 :amp-env '(0 0 .3333 1 4.3603 .6000 9.3939 .3 24.4950 .1 100.0 0) :noise-amount .0100) (vln_one_sin_ran 79.0250 .9000 24.4994 .1 :fm-index 2.4934 :reverb-amount .0025 :amp-env '(0 0 .3333 1 4.3603 .6000 9.3939 .3 24.4950 .1 100.0 0) :noise-amount .0100) (vln_one_sin_ran 79.0300 1.8000 97.9975 .1 :fm-index 2.4039 :reverb-amount .0023 :amp-env '(0 0 .1667 1 4.2003 .6000 9.2424 .3 24.3687 .1 100 0) :noise-amount .0400) (vln_one_sin_ran 79.0300 .9000 195.9950 .1 :fm-index 1.5159 :reverb-amount .0021 :amp-env '(0 0 .3333 1 4.3603 .6000 9.3939 .3 24.4950 .1 100.0 0) :noise-amount .0400) (vln_one_sin_ran 79.0300 .9000 392.9900 .1 :fm-index 2.2122 :reverb-amount .0028 :amp-env '(0 0 .3333 1 4.3603 .6000 9.3939 .3 24.4950 .1 100.0 0) :noise-amount .0400) (vln_one_sin_ran 79.0300 1.8000 784.9800 .1 :fm-index 2.1574 :reverb-amount .0020 :amp-env '(0 0 .1667 1 4.2003 .6000 9.2424 .3 24.3687 .1 100 0) :noise-amount .0400) (vln_one_sin_ran 79.0300 2.7000 24.4994 .1 :fm-index 2.1963 :reverb-amount .0031 :amp-env '(0 0 .1111 1 4.1470 .6000 9.1919 .3 24.3266 .1 100.0 0) :noise-amount .0100) (vln_one_sin_ran 79.0300 1.8000 48.9988 .1 :fm-index 1.9761 :reverb-amount .0032 :amp-env '(0 0 .1667 1 4.2003 .6000 9.2424 .3 24.3687 .1 100 0) :noise-amount .0100) (vln_one_sin_ran 79.0400 2.7000 12.2497 .1 :fm-index 1.5088 :reverb-amount .0021 :amp-env '(0 0 .1111 1 4.1470 .6000 9.1919 .3 24.3266 .1 100.0 0) :noise-amount .0100) (vln_one_sin_ran 79.0450 1.8000 6.1248 .1 :fm-index 1.7384 :reverb-amount .0021 :amp-env '(0 0 .1667 1 4.2003 .6000 9.2424 .3 24.3687 .1 100 0) :noise-amount .0100) (vln_one_sin_ran 79.0500 2 24.4994 .1 :reverb-amount .1 :amp-env tap :noise-amount .0040) (vln_one_sin_ran 79.0500 1 48.9988 .1 :reverb-amount .1 :amp-env tap :noise-amount .0040) (vln_one_sin_ran 79.0600 2 12.2497 .1 :reverb-amount .1 :amp-env tap :noise-amount .0040) (vln_one_sin_ran 79.0650 1 24.4994 .1 :reverb-amount .1 :amp-env tap :noise-amount .0040) (vln_one_sin_ran 79.0700 2 6.1248 .1 :fm-index 1.2474 :reverb-amount .1 :amp-env tap :noise-amount .0040) (vln_one_sin_ran 79.0700 1 48.9988 .1 :fm-index .7526 :reverb-amount .1 :amp-env tap :noise-amount .0040) (vln_one_sin_ran 79.0800 1 25.4994 .1 :fm-index 1.1080 :reverb-amount .1 :amp-env tap :noise-amount .0040) (vln_one_sin_ran 79.0850 2 12.2497 .1 :fm-index 1.0859 :reverb-amount .1 :amp-env tap :noise-amount .0040) (vln_one_sin_ran 79.0900 4 97.9975 .1 :fm-index 2.4788 :reverb-amount .1 :amp-env tap :noise-amount .0040) (vln_one_sin_ran 79.0900 3 48.9988 .1 :fm-index 1.8980 :reverb-amount .1 :amp-env tap :noise-amount .0040) (vln_one_sin_ran 79.0900 3 25.4994 .1 :fm-index 2.1151 :reverb-amount .1 :amp-env tap :noise-amount .0040) (vln_one_sin_ran 79.0950 5 12.2497 .1 :fm-index 2.3224 :reverb-amount .1 :amp-env tap :noise-amount .0040) (current-score-time 85) (vln_one_sin_ran 85.2100 .9000 123.4725 .1 :reverb-amount .0031 :amp-env '(0 0 .3333 1 4.3603 .6000 9.3939 .3 24.4950 .1 100.0 0) :noise-amount .0100) (vln_one_sin_ran 85.2100 1.8000 61.7363 .1 :reverb-amount .0023 :amp-env '(0 0 .1667 1 4.2003 .6000 9.2424 .3 24.3687 .1 100 0) :noise-amount .0100) (vln_one_sin_ran 85.2200 .9000 246.9450 .1 :reverb-amount .0023 :amp-env '(0 0 .3333 1 4.3603 .6000 9.3939 .3 24.4950 .1 100.0 0) :noise-amount .0100) (vln_one_sin_ran 85.2250 .9000 30.8681 .1 :reverb-amount .0026 :amp-env '(0 0 .3333 1 4.3603 .6000 9.3939 .3 24.4950 .1 100.0 0) :noise-amount .0100) (vln_one_sin_ran 85.2300 1.8000 123.4725 .1 :reverb-amount .0027 :amp-env '(0 0 .1667 1 4.2003 .6000 9.2424 .3 24.3687 .1 100 0) :noise-amount .0400) (vln_one_sin_ran 85.2300 .9000 246.9450 .1 :reverb-amount .0026 :amp-env '(0 0 .3333 1 4.3603 .6000 9.3939 .3 24.4950 .1 100.0 0) :noise-amount .0400) (vln_one_sin_ran 85.2300 .9000 494.8900 .1 :reverb-amount .0020 :amp-env '(0 0 .3333 1 4.3603 .6000 9.3939 .3 24.4950 .1 100.0 0) :noise-amount .0400) (vln_one_sin_ran 85.2300 1.8000 988.7800 .1 :reverb-amount .0025 :amp-env '(0 0 .1667 1 4.2003 .6000 9.2424 .3 24.3687 .1 100 0) :noise-amount .0400) (vln_one_sin_ran 85.2300 2.7000 30.8681 .1 :reverb-amount .0028 :amp-env '(0 0 .1111 1 4.1470 .6000 9.1919 .3 24.3266 .1 100.0 0) :noise-amount .0100) (vln_one_sin_ran 85.2300 1.8000 61.7363 .1 :reverb-amount .0023 :amp-env '(0 0 .1667 1 4.2003 .6000 9.2424 .3 24.3687 .1 100 0) :noise-amount .0100) (vln_one_sin_ran 85.2400 2.7000 15.4341 .1 :reverb-amount .0030 :amp-env '(0 0 .1111 1 4.1470 .6000 9.1919 .3 24.3266 .1 100.0 0) :noise-amount .0100) (vln_one_sin_ran 85.2450 1.8000 20.5788 .1 :reverb-amount .0023 :amp-env '(0 0 .1667 1 4.2003 .6000 9.2424 .3 24.3687 .1 100 0) :noise-amount .0100) (vln_one_sin_ran 85.2500 2 30.8681 .1 :reverb-amount .1 :amp-env tap :noise-amount .0090) (vln_one_sin_ran 85.2500 1 61.7363 .1 :reverb-amount .1 :amp-env tap :noise-amount .0090) (vln_one_sin_ran 85.2600 2 15.4341 .1 :reverb-amount .1 :amp-env tap :noise-amount .0090) (vln_one_sin_ran 85.2650 1 30.8681 .1 :reverb-amount .1 :amp-env tap :noise-amount .0090) (vln_one_sin_ran 85.2710 2 30.8681 .1 :reverb-amount .1 :amp-env tap :noise-amount .0040) (vln_one_sin_ran 85.2710 1 61.7363 .1 :reverb-amount .1 :amp-env tap :noise-amount .0040) (vln_one_sin_ran 85.2810 1 31.8681 .1 :reverb-amount .1 :amp-env tap :noise-amount .0040) (vln_one_sin_ran 85.2860 2 15.4341 .1 :reverb-amount .1 :amp-env tap :noise-amount .0040) (current-score-time 93) (vln_one_sin_ran 93.0100 .9000 3135.9200 .1600 :fm-index 1.7299 :reverb-amount .0026 :amp-env '(0 0 .3333 1 4.3603 .6000 9.3939 .3 24.4950 .1 100.0 0) :noise-amount .0100) (vln_one_sin_ran 93.0100 .4500 1464.6987 .1600 :fm-index 1.9173 :reverb-amount .0027 :amp-env '(0 0 .6667 1 4.6801 .6000 9.6970 .3 24.7475 .1 100 0) :noise-amount .0100) (vln_one_sin_ran 93.0200 .9000 6714.0048 .1600 :fm-index 2.4604 :reverb-amount .0032 :amp-env '(0 0 .3333 1 4.3603 .6000 9.3939 .3 24.4950 .1 100.0 0) :noise-amount .0100) (vln_one_sin_ran 93.0250 .9000 684.1190 .1600 :fm-index 1.9969 :reverb-amount .0021 :amp-env '(0 0 .3333 1 4.3603 .6000 9.3939 .3 24.4950 .1 100.0 0) :noise-amount .0100) (vln_one_sin_ran 93.0300 .2700 684.1190 .1600 :fm-index 2.0022 :reverb-amount .0026 :amp-env '(0 0 1.1111 1 5.1066 .6000 10.1010 .3 25.0842 .1 100.0 0) :noise-amount .0100) (vln_one_sin_ran 93.0300 .6300 1464.6987 .1600 :fm-index 2.1058 :reverb-amount .0027 :amp-env '(0 0 .4762 1 4.4974 .6000 9.5238 .3 24.6032 .1 100.0 0) :noise-amount .0100) (vln_one_sin_ran 93.0400 .9000 319.5325 .1600 :fm-index 2.2293 :reverb-amount .0029 :amp-env '(0 0 .3333 1 4.3603 .6000 9.3939 .3 24.4950 .1 100.0 0) :noise-amount .0100) (vln_one_sin_ran 93.0450 .4500 149.2445 .1600 :fm-index 1.5780 :reverb-amount .0025 :amp-env '(0 0 .6667 1 4.6801 .6000 9.6970 .3 24.7475 .1 100 0) :noise-amount .0100) (vln_one_sin_ran 93.0500 1 684.1190 .1600 :reverb-amount .0100 :amp-env yup :noise-amount .0090) (vln_one_sin_ran 93.0500 1 1464.6987 .1600 :reverb-amount .0100 :amp-env yup :noise-amount .0090) (vln_one_sin_ran 93.0600 1 319.5325 .1600 :reverb-amount .0100 :amp-env yup :noise-amount .0090) (vln_one_sin_ran 93.0650 1 684.1190 .1600 :reverb-amount .0100 :amp-env yup :noise-amount .0090) (vln_one_sin_ran 93.0700 1 149.2445 .1600 :reverb-amount .0100 :amp-env yup :noise-amount .0040) (vln_one_sin_ran 93.0700 1 1464.6987 .1600 :reverb-amount .0100 :amp-env yup :noise-amount .0040) (vln_one_sin_ran 93.0800 1 561.6022 .160 :reverb-amount .0100 :amp-env yup :noise-amount .0040) (vln_one_sin_ran 93.0850 1 319.5325 .1600 :reverb-amount .0100 :amp-env yup :noise-amount .0040) (current-score-time 96) (vln_one_sin_ran 96.0100 .9000 3135.9200 .1600 :fm-index 1.6329 :reverb-amount .0031 :amp-env '(0 0 .3333 1 4.3603 .6000 9.3939 .3 24.4950 .1 100.0 0) :noise-amount .0100) (vln_one_sin_ran 96.0100 .4500 1810.5774 .1600 :fm-index 1.8298 :reverb-amount .0031 :amp-env '(0 0 .6667 1 4.6801 .6000 9.6970 .3 24.7475 .1 100 0) :noise-amount .0100) (vln_one_sin_ran 96.0200 .9000 5431.4135 .1600 :fm-index 2.1640 :reverb-amount .0022 :amp-env '(0 0 .3333 1 4.3603 .6000 9.3939 .3 24.4950 .1 100.0 0) :noise-amount .0100) (vln_one_sin_ran 96.0250 .9000 1045.3680 .1600 :fm-index 1.6971 :reverb-amount .0032 :amp-env '(0 0 .3333 1 4.3603 .6000 9.3939 .3 24.4950 .1 100.0 0) :noise-amount .0100) (vln_one_sin_ran 96.0300 .2700 1045.3680 .1600 :fm-index 2.4855 :reverb-amount .0028 :amp-env '(0 0 1.1111 1 5.1066 .6000 10.1010 .3 25.0842 .1 100.0 0) :noise-amount .0100) (vln_one_sin_ran 96.0300 .6300 1810.5774 .1600 :fm-index 2.1604 :reverb-amount .0020 :amp-env '(0 0 .4762 1 4.4974 .6000 9.5238 .3 24.6032 .1 100.0 0) :noise-amount .0100) (vln_one_sin_ran 96.0400 .9000 603.5612 .1600 :fm-index 2.4204 :reverb-amount .0031 :amp-env '(0 0 .3333 1 4.3603 .6000 9.3939 .3 24.4950 .1 100.0 0) :noise-amount .0100) (vln_one_sin_ran 96.0450 .4500 348.4765 .1600 :fm-index 2.3918 :reverb-amount .0026 :amp-env '(0 0 .6667 1 4.6801 .6000 9.6970 .3 24.7475 .1 100 0) :noise-amount .0100) (vln_one_sin_ran 96.0460 .9000 201.1989 .1600 :fm-index 1.5205 :reverb-amount .0024 :amp-env '(0 0 .3333 1 4.3603 .6000 9.3939 .3 24.4950 .1 100.0 0) :noise-amount .0100) (vln_one_sin_ran 96.0460 .9000 116.1656 .1600 :fm-index 2.3049 :reverb-amount .0028 :amp-env '(0 0 .3333 1 4.3603 .6000 9.3939 .3 24.4950 .1 100.0 0) :noise-amount .0100) (vln_one_sin_ran 96.0500 .9000 3135.9200 .1600 :fm-index 2.4363 :reverb-amount .0021 :amp-env '(0 0 .3333 1 4.3603 .6000 9.3939 .3 24.4950 .1 100.0 0) :noise-amount .0100) (vln_one_sin_ran 96.0500 .4500 1464.6987 .1600 :fm-index 2.3865 :reverb-amount .0027 :amp-env '(0 0 .6667 1 4.6801 .6000 9.6970 .3 24.7475 .1 100 0) :noise-amount .0100) (vln_one_sin_ran 96.0600 .9000 6714.0048 .1600 :fm-index 1.7354 :reverb-amount .0021 :amp-env '(0 0 .3333 1 4.3603 .6000 9.3939 .3 24.4950 .1 100.0 0) :noise-amount .0100) (vln_one_sin_ran 96.0650 .9000 684.1190 .1600 :fm-index 1.8282 :reverb-amount .0025 :amp-env '(0 0 .3333 1 4.3603 .6000 9.3939 .3 24.4950 .1 100.0 0) :noise-amount .0100) (vln_one_sin_ran 96.0700 .2700 684.1190 .1600 :fm-index 2.3923 :reverb-amount .0025 :amp-env '(0 0 1.1111 1 5.1066 .6000 10.1010 .3 25.0842 .1 100.0 0) :noise-amount .0100) (vln_one_sin_ran 96.0700 .6300 1464.6987 .1600 :fm-index 2.2789 :reverb-amount .0028 :amp-env '(0 0 .4762 1 4.4974 .6000 9.5238 .3 24.6032 .1 100.0 0) :noise-amount .0100) (vln_one_sin_ran 96.0800 .9000 319.5325 .1600 :fm-index 1.5438 :reverb-amount .0027 :amp-env '(0 0 .3333 1 4.3603 .6000 9.3939 .3 24.4950 .1 100.0 0) :noise-amount .0100) (vln_one_sin_ran 96.0850 .4500 149.2445 .1600 :fm-index 2.4210 :reverb-amount .0028 :amp-env '(0 0 .6667 1 4.6801 .6000 9.6970 .3 24.7475 .1 100 0) :noise-amount .0100) (vln_one_sin_ran 96.0860 .9000 69.7078 .1600 :fm-index 2.0288 :reverb-amount .0029 :amp-env '(0 0 .3333 1 4.3603 .6000 9.3939 .3 24.4950 .1 100.0 0) :noise-amount .0100) (vln_one_sin_ran 96.0860 .9000 32.5585 .1600 :fm-index 1.8254 :reverb-amount .0028 :amp-env '(0 0 .3333 1 4.3603 .6000 9.3939 .3 24.4950 .1 100.0 0) :noise-amount .0100) (set! fm-violin-reverb-amount 0.0) (set! fm-violin-noise-amount 0.01) (current-score-time 99) (vln_one_sin_ran 99.0500 .9000 3135.9200 .1600 :fm-index 1.7334 :amp-env '(0 0 .3333 1 4.3603 .6000 9.3939 .3 24.4950 .1 100.0 0)) (vln_one_sin_ran 99.0500 .4500 1810.5774 .1600 :fm-index 2.3629 :amp-env '(0 0 .6667 1 4.6801 .6000 9.6970 .3 24.7475 .1 100 0)) (vln_one_sin_ran 99.0600 .9000 5431.4135 .1600 :fm-index 2.2744 :amp-env '(0 0 .3333 1 4.3603 .6000 9.3939 .3 24.4950 .1 100.0 0)) (vln_one_sin_ran 99.0650 .9000 1045.3680 .1600 :fm-index 1.8722 :amp-env '(0 0 .3333 1 4.3603 .6000 9.3939 .3 24.4950 .1 100.0 0)) (vln_one_sin_ran 99.1100 .2700 1045.3680 .1600 :fm-index 2.3139 :amp-env '(0 0 1.1111 1 5.1066 .6000 10.1010 .3 25.0842 .1 100.0 0)) (vln_one_sin_ran 99.1100 .6300 1810.5774 .1600 :fm-index 1.6216 :amp-env '(0 0 .4762 1 4.4974 .6000 9.5238 .3 24.6032 .1 100.0 0)) (vln_one_sin_ran 99.1200 .9000 603.5612 .1600 :fm-index 1.5308 :amp-env '(0 0 .3333 1 4.3603 .6000 9.3939 .3 24.4950 .1 100.0 0)) (vln_one_sin_ran 99.1650 .4500 348.4765 .1600 :fm-index 2.0346 :amp-env '(0 0 .6667 1 4.6801 .6000 9.6970 .3 24.7475 .1 100 0)) (vln_one_sin_ran 99.1660 .9000 201.1989 .1600 :fm-index 1.8176 :amp-env '(0 0 .3333 1 4.3603 .6000 9.3939 .3 24.4950 .1 100.0 0)) (vln_one_sin_ran 99.1660 .9000 116.1656 .1600 :fm-index 1.7145 :amp-env '(0 0 .3333 1 4.3603 .6000 9.3939 .3 24.4950 .1 100.0 0)) (vln_one_sin_ran 99.1700 .9000 3135.9200 .1600 :fm-index 2.4459 :amp-env '(0 0 .3333 1 4.3603 .6000 9.3939 .3 24.4950 .1 100.0 0)) (vln_one_sin_ran 99.1700 .4500 1464.6987 .1600 :fm-index 2.4644 :amp-env '(0 0 .6667 1 4.6801 .6000 9.6970 .3 24.7475 .1 100 0)) (vln_one_sin_ran 99.1800 .9000 6714.0048 .1600 :fm-index 1.9985 :amp-env '(0 0 .3333 1 4.3603 .6000 9.3939 .3 24.4950 .1 100.0 0)) (vln_one_sin_ran 99.1850 .9000 684.1190 .1600 :fm-index 2.4542 :amp-env '(0 0 .3333 1 4.3603 .6000 9.3939 .3 24.4950 .1 100.0 0)) (vln_one_sin_ran 99.2900 .2700 684.1190 .1600 :fm-index 2.3391 :amp-env '(0 0 1.1111 1 5.1066 .6000 10.1010 .3 25.0842 .1 100.0 0)) (vln_one_sin_ran 99.2900 .6300 1464.6987 .1600 :fm-index 1.5138 :amp-env '(0 0 .4762 1 4.4974 .6000 9.5238 .3 24.6032 .1 100.0 0)) (vln_one_sin_ran 99.3000 .9000 319.5325 .1600 :fm-index 1.5440 :amp-env '(0 0 .3333 1 4.3603 .6000 9.3939 .3 24.4950 .1 100.0 0)) (vln_one_sin_ran 99.3050 .4500 149.2445 .1600 :fm-index 2.2283 :amp-env '(0 0 .6667 1 4.6801 .6000 9.6970 .3 24.7475 .1 100 0)) (vln_one_sin_ran 99.3060 .9000 69.7078 .1600 :fm-index 1.9498 :amp-env '(0 0 .3333 1 4.3603 .6000 9.3939 .3 24.4950 .1 100.0 0)) (vln_one_sin_ran 99.3060 .9000 32.5585 .1600 :fm-index 2.2943 :amp-env '(0 0 .3333 1 4.3603 .6000 9.3939 .3 24.4950 .1 100.0 0)) (restore-fm-violin-defaults) (set! fm-violin-amp-env metalamp) (set! fm-violin-glissando-amount 0.0) (set! fm-violin-reverb-amount 0.01) (set! fm-violin-fm1-rat 2.718) (set! fm-violin-fm2-rat 1.414) (set! fm-violin-fm3-rat 3.141) (current-score-time 102) (vln_one_sin 102.2600 1.2000 355.5416 .1600 :fm-index 2.0375) (vln_one_sin 102.2600 1.5000 354.8319 .1600 :fm-index 1.8744) (vln_one_sin 102.2603 .9000 356.2527 .1600 :fm-index 1.8743) (vln_one_sin 102.2605 .9000 409.2356 .1600 :fm-index 2.0808) (vln_one_sin 102.2605 2.1000 410.0541 .1600 :fm-index 1.9219) (vln_one_sin 102.2608 1.2000 130.8100 .1600 :fm-index 1.5746) (vln_one_sin 102.2613 3 130.2883 .1600 :fm-index 2.3771) (vln_one_sin 102.2615 .9000 130.2883 .1600 :fm-index 1.7765) (vln_one_sin 102.2615 2.1000 130.5489 .2600 :fm-index 1.6485) (vln_one_sin 102.2625 2 130.8100 .1600 :fm-index 2.1416) (vln_one_sin 102.2633 2 130.5488 .1600 :fm-index 2.0883) (set! fm-violin-noise-amount .0001) (set! fm-violin-amp-env newf) (set! fm-violin-reverb-amount .01) (current-score-time 106) (vln_one_sin_ran 106.2605 .8000 523.2400 .1600 :fm-index 2.3056) (vln_one_sin_ran 106.2605 1 247.1611 .1600 :fm-index 1.6308) (vln_one_sin_ran 106.2610 .6000 1107.6991 .1600 :fm-index 1.9364) (vln_one_sin_ran 106.2613 2 116.7506 .1600 :fm-index 2.3740) (vln_one_sin_ran 106.2615 .6000 116.7506 .1600 :fm-index 1.8374) (vln_one_sin_ran 106.2615 1.4000 247.1611 .1600 :fm-index 1.7250) (vln_one_sin_ran 106.2620 .6000 55.1491 .1600 :fm-index 1.5495) (vln_one_sin_ran 106.2623 1 26.0506 .1600 :fm-index 1.7235) (vln_one_sin_ran 106.2623 2 12.3054 .1600 :fm-index 1.8818) (vln_one_sin_ran 106.2623 2 5.8127 .1600 :fm-index 1.9537) (vln_one_sin_ran 106.2625 2 523.2400 .1600 :fm-index 2.1593) (vln_one_sin_ran 106.2625 1 256.2390 .1600 :fm-index 1.9851) (vln_one_sin_ran 106.2630 2 1068.4561 .1600 :fm-index 1.8015) (vln_one_sin_ran 106.2633 2 125.4843 .1600 :fm-index 1.6161) (vln_one_sin_ran 106.2635 .6000 125.4843 .1600 :fm-index 2.2767) (vln_one_sin_ran 106.2635 1.4000 256.2390 .1600 :fm-index 2.0835) (vln_one_sin_ran 106.2640 .4 61.4517 .1600 :fm-index 1.5310) (vln_one_sin_ran 106.2643 1 30.0939 .1600 :fm-index 1.5803) (vln_one_sin_ran 106.2643 2 14.7374 .1600 :fm-index 1.9586) (vln_one_sin_ran 106.2643 2 7.2172 .1600 :fm-index 1.7270) (vln_one_sin_ran 106.2645 6 28.4710 .1600 :fm-index 1.5983) (vln_one_sin_ran 106.2648 10 25.6239 .1600 :fm-index 1.7285) (vln_one_sin_ran 106.2648 8 21.3532 .1600 :fm-index 1.7955) (vln_one_sin_ran 106.2648 8 17.0826 .1600 :fm-index 2.0866) (set! fm-violin-reverb-amount .001) (set! fm-violin-noise-amount .004) (set! fm-violin-fm1-rat 3.141) (set! fm-violin-fm2-rat 1.414) (set! fm-violin-fm3-rat 2.718) (current-score-time 110) (vln_one_sin_ran 110.2600 1.6000 1643.4968 .1600 :fm-index 2.1104) (vln_one_sin_ran 110.2600 2 1643.4968 .1600 :fm-index 1.5191) (vln_one_sin_ran 110.2603 1.2000 1643.4968 .1600 :fm-index 2.0478) (vln_one_sin_ran 110.2603 4 1643.4968 .1600 :fm-index 2.0473) (vln_one_sin_ran 110.2605 1.2000 1422.1663 .1600 :fm-index 1.9845) (vln_one_sin_ran 110.2605 2.8000 1422.1663 .1600 :fm-index 2.0429) (vln_one_sin_ran 110.2605 1.2000 1422.1663 .1600 :fm-index 1.6184) (vln_one_sin_ran 110.2608 1.6000 523.2400 .1600 :fm-index 2.3908) (vln_one_sin_ran 110.2608 2 523.2400 .1600 :fm-index 1.6733) (vln_one_sin_ran 110.2610 1.2000 523.2400 .1600 :fm-index 2.0431) (vln_one_sin_ran 110.2610 4 523.2400 .1600 :fm-index 1.7430) (vln_one_sin_ran 110.2613 1.2000 523.2400 .1600 :fm-index 2.2030) (vln_one_sin_ran 110.2613 2.8000 523.2400 .1600 :fm-index 2.0149) (vln_one_sin_ran 110.2615 1.2000 523.2400 .1600 :fm-index 2.2310) (vln_one_sin_ran 110.2615 2 523.2400 .1600 :fm-index 2.1625) (vln_one_sin_ran 110.2618 4 523.2400 .1600 :fm-index 2.0000) (vln_one_sin_ran 110.2618 4 523.2400 .1600 :fm-index 2.2034) (vln_one_sin_ran 110.2620 3 523.2400 .1600 :fm-index 2.0186) (vln_one_sin_ran 110.2620 1.5000 523.2400 .1600 :fm-index 2.1373) (vln_one_sin_ran 110.2623 3 523.2400 .1600 :fm-index 1.9046) (vln_one_sin_ran 110.2623 3 523.2400 .1600 :fm-index 2.1834) (vln_one_sin_ran 110.2625 1.2000 523.2400 .1600 :fm-index 1.8266) (vln_one_sin_ran 110.2625 2.8000 523.2400 .1600 :fm-index 1.5937) (vln_one_sin_ran 110.2628 .8000 523.2400 .1600 :fm-index 1.9762) (vln_one_sin_ran 110.2628 2 523.2400 .1600 :fm-index 1.8954) (vln_one_sin_ran 110.2630 4 523.2400 .1600 :fm-index 2.3302) (vln_one_sin_ran 110.2630 4 523.2400 .1600 :fm-index 2.4949) (set! fm-violin-fm1-rat 3.414) (set! fm-violin-fm2-rat 1.414) (set! fm-violin-fm3-rat 2.718) (current-score-time 114) (vln_one_sin_ran 114.2600 1.6000 821.7484 .1600 :fm-index 2.4793) (vln_one_sin_ran 114.2600 2 821.7484 .1600 :fm-index 2.4789) (vln_one_sin_ran 114.2603 1.2000 821.7484 .1600 :fm-index 2.0827) (vln_one_sin_ran 114.2603 4 821.7484 .1600 :fm-index 2.4769) (vln_one_sin_ran 114.2605 1.2000 711.0832 .1600 :fm-index 2.4094) (vln_one_sin_ran 114.2605 2.8000 711.0832 .1600 :fm-index 2.4031) (vln_one_sin_ran 114.2605 1.2000 711.0832 .1600 :fm-index 2.1428) (vln_one_sin_ran 114.2608 1.6000 261.6200 .1600 :fm-index 2.3129) (vln_one_sin_ran 114.2608 2 261.6200 .1600 :fm-index 2.3488) (vln_one_sin_ran 114.2610 1.2000 261.6200 .1600 :fm-index 2.1466) (vln_one_sin_ran 114.2610 4 261.6200 .1600 :fm-index 1.6938) (vln_one_sin_ran 114.2613 1.2000 261.6200 .1600 :fm-index 2.1287) (vln_one_sin_ran 114.2613 2.8000 261.6200 .1600 :fm-index 2.1917) (vln_one_sin_ran 114.2615 1.2000 261.6200 .1600 :fm-index 2.3583) (vln_one_sin_ran 114.2615 2 261.6200 .1600 :fm-index 1.8368) (vln_one_sin_ran 114.2618 4 261.6200 .1600 :fm-index 1.5107) (vln_one_sin_ran 114.2618 4 261.6200 .1600 :fm-index 1.6218) (vln_one_sin_ran 114.2620 3 261.6200 .1600 :fm-index 1.9041) (vln_one_sin_ran 114.2620 1.5000 261.6200 .1600 :fm-index 1.5748) (vln_one_sin_ran 114.2623 3 261.6200 .1600 :fm-index 1.9339) (vln_one_sin_ran 114.2623 3 261.6200 .1600 :fm-index 2.0489) (vln_one_sin_ran 114.2625 1.2000 261.6200 .1600 :fm-index 2.0888) (vln_one_sin_ran 114.2625 2.8000 261.6200 .1600 :fm-index 1.7306) (vln_one_sin_ran 114.2628 .8000 261.6200 .1600 :fm-index 2.3257) (vln_one_sin_ran 114.2628 2 261.6200 .1600 :fm-index 2.4755) (vln_one_sin_ran 114.2630 4 261.6200 .1600 :fm-index 1.9459) (vln_one_sin_ran 114.2630 4 261.6200 .1600 :fm-index 1.5782) (set! fm-violin-fm1-rat 3.414) (set! fm-violin-fm2-rat 1.414) (set! fm-violin-fm3-rat 2.718) (current-score-time 118) (vln_one_sin_ran 118.2600 1.6000 3286.9937 .1600 :fm-index 1.6655) (vln_one_sin_ran 118.2600 2 3286.9937 .1600 :fm-index 1.9356) (vln_one_sin_ran 118.2603 1.2000 3286.9937 .1600 :fm-index 1.5665) (vln_one_sin_ran 118.2603 4 3286.9937 .1600 :fm-index 1.6701) (vln_one_sin_ran 118.2605 1.2000 2844.3326 .1600 :fm-index 2.3273) (vln_one_sin_ran 118.2605 2.8000 2844.3326 .1600 :fm-index 1.5520) (vln_one_sin_ran 118.2605 1.2000 2844.3326 .1600 :fm-index 2.4104) (vln_one_sin_ran 118.2608 1.6000 1046.4800 .1600 :fm-index 2.1075) (vln_one_sin_ran 118.2608 2 1046.4800 .1600 :fm-index 1.7004) (vln_one_sin_ran 118.2610 1.2000 1046.4800 .1600 :fm-index 1.6502) (vln_one_sin_ran 118.2610 4 1046.4800 .1600 :fm-index 2.4591) (vln_one_sin_ran 118.2613 1.2000 1046.4800 .1600 :fm-index 2.1491) (vln_one_sin_ran 118.2613 2.8000 1046.4800 .1600 :fm-index 2.1594) (vln_one_sin_ran 118.2615 1.2000 1046.4800 .1600 :fm-index 2.4783) (vln_one_sin_ran 118.2615 2 1046.4800 .1600 :fm-index 2.2080) (vln_one_sin_ran 118.2618 4 1046.4800 .1600 :fm-index 1.5844) (vln_one_sin_ran 118.2618 4 1046.4800 .1600 :fm-index 1.5440) (vln_one_sin_ran 118.2620 3 1046.4800 .1600 :fm-index 1.9857) (vln_one_sin_ran 118.2620 1.5000 1046.4800 .1600 :fm-index 1.5165) (vln_one_sin_ran 118.2623 3 1046.4800 .1600 :fm-index 1.8309) (vln_one_sin_ran 118.2623 3 1046.4800 .1600 :fm-index 2.1236) (vln_one_sin_ran 118.2625 1.2000 1046.4800 .1 :fm-index 2.4074) (vln_one_sin_ran 118.2625 2.8000 1046.4800 .1 :fm-index 1.6315) (vln_one_sin_ran 118.2628 .8000 1046.4800 .1 :fm-index 1.8061) (vln_one_sin_ran 118.2628 2 1046.4800 .1 :fm-index 2.3664) (vln_one_sin_ran 118.2630 4 1046.4800 .1 :fm-index 2.2490) (vln_one_sin_ran 118.2630 4 1046.4800 .1 :fm-index 2.4081) (set! fm-violin-reverb-amount .01) (current-score-time 122) (vln_one_sin_ran 122.2600 1.6000 1643.4968 .1600 :fm-index 1.9284) (vln_one_sin_ran 122.2600 2 1643.4968 .1600 :fm-index 2.2171) (vln_one_sin_ran 122.2603 1.2000 1643.4968 .1600 :fm-index 2.2272) (vln_one_sin_ran 122.2603 4 1643.4968 .1600 :fm-index 1.5677) (vln_one_sin_ran 122.2605 1.2000 1422.1663 .1600 :fm-index 2.0476) (vln_one_sin_ran 122.2605 2.8000 1422.1663 .1600 :fm-index 2.3289) (vln_one_sin_ran 122.2605 1.2000 1422.1663 .1600 :fm-index 2.0269) (vln_one_sin_ran 122.2608 1.6000 523.2400 .1600 :fm-index 1.7767) (vln_one_sin_ran 122.2608 2 523.2400 .1600 :fm-index 1.8117) (vln_one_sin_ran 122.2610 1.2000 523.2400 .1600 :fm-index 1.5694) (vln_one_sin_ran 122.2610 4 523.2400 .1600 :fm-index 1.6869) (vln_one_sin_ran 122.2613 1.2000 523.2400 .1600 :fm-index 1.9340) (vln_one_sin_ran 122.2613 2.8000 523.2400 .1600 :fm-index 2.3986) (vln_one_sin_ran 122.2615 1.2000 523.2400 .1600 :fm-index 2.4593) (vln_one_sin_ran 122.2615 2 523.2400 .1600 :fm-index 2.3430) (vln_one_sin_ran 122.2618 4 523.2400 .1600 :fm-index 2.2650) (vln_one_sin_ran 122.2618 4 523.2400 .1600 :fm-index 2.3015) (vln_one_sin_ran 122.2620 3 523.2400 .1600 :fm-index 1.9909) (vln_one_sin_ran 122.2620 1.5000 523.2400 .1600 :fm-index 2.3916) (vln_one_sin_ran 122.2623 3 523.2400 .1600 :fm-index 2.0401) (vln_one_sin_ran 122.2623 3 523.2400 .1600 :fm-index 1.8484) (vln_one_sin_ran 122.2625 1.2000 523.2400 .1600 :fm-index 2.3138) (vln_one_sin_ran 122.2625 2.8000 523.2400 .1600 :fm-index 1.6295) (vln_one_sin_ran 122.2628 .8000 523.2400 .1600 :fm-index 2.2344) (vln_one_sin_ran 122.2628 2 523.2400 .1600 :fm-index 1.8423) (vln_one_sin_ran 122.2630 4 523.2400 .1600 :fm-index 2.2086) (vln_one_sin_ran 122.2630 4 523.2400 .1600 :fm-index 2.3130) (set! fm-violin-noise-amount .0001) (set! fm-violin-fm1-rat 2.718) (set! fm-violin-fm2-rat 1.141) (set! fm-violin-fm3-rat 3.141) (set! fm-violin-reverb-amount .01) (current-score-time 126) (vln_one_sin_ran 126.2605 .8000 523.2400 .1600 :fm-index 2.0123) (vln_one_sin_ran 126.2605 1 493.8728 .1600 :fm-index 2.1176) (vln_one_sin_ran 126.2610 .6000 554.3535 .1600 :fm-index 1.9163) (vln_one_sin_ran 126.2613 2 466.1539 .1600 :fm-index 1.5048) (vln_one_sin_ran 126.2615 .6000 466.1539 .1600 :fm-index 1.5242) (vln_one_sin_ran 126.2615 1.4000 493.8728 .1600 :fm-index 1.9509) (vln_one_sin_ran 126.2620 .6000 439.9907 .1600 :fm-index 2.2131) (vln_one_sin_ran 126.2623 1 415.2959 .1600 :fm-index 1.7326) (vln_one_sin_ran 126.2623 2 391.9871 .1600 :fm-index 1.9936) (vln_one_sin_ran 126.2623 2 369.9866 .1600 :fm-index 2.1103) (vln_one_sin_ran 126.2625 2 523.2400 .1600 :fm-index 1.6206) (vln_one_sin_ran 126.2625 1 522.7173 .1600 :fm-index 1.8598) (vln_one_sin_ran 126.2630 2 523.7632 .1600 :fm-index 1.8015) (vln_one_sin_ran 126.2633 2 522.1951 .1600 :fm-index 2.3575) (vln_one_sin_ran 126.2635 .6000 522.1951 .1600 :fm-index 1.5010) (vln_one_sin_ran 126.2635 1.4000 522.7173 .1600 :fm-index 2.4075) (vln_one_sin_ran 126.2640 .4 521.6734 .1600 :fm-index 2.0721) (vln_one_sin_ran 126.2643 1 521.1523 .1600 :fm-index 2.0433) (vln_one_sin_ran 126.2643 2 520.6316 .1600 :fm-index 1.9788) (vln_one_sin_ran 126.2643 2 520.1115 .1600 :fm-index 1.6770) (set! fm-violin-noise-amount .004) (current-score-time 134) (vln_one_sin_ran 134.2600 .8000 1046.4800 .1600 :fm-index 1.5610) (vln_one_sin_ran 134.2600 1 1044.3912 .1600 :fm-index 2.3514) (vln_one_sin_ran 134.2603 .6000 1048.5730 .1600 :fm-index 1.9958) (vln_one_sin_ran 134.2603 2 1042.3066 .1600 :fm-index 1.9654) (vln_one_sin_ran 134.2605 .6000 1042.3066 .1600 :fm-index 1.5285) (vln_one_sin_ran 134.2605 1.4000 1044.3912 .1600 :fm-index 1.8881) (vln_one_sin_ran 134.2608 .6000 1040.2262 .1600 :fm-index 1.8682) (vln_one_sin_ran 134.2608 .8000 523.2400 .1600 :fm-index 1.8296) (vln_one_sin_ran 134.2610 1 522.1956 .1600 :fm-index 2.1899) (vln_one_sin_ran 134.2610 .6000 524.2865 .1600 :fm-index 1.9614) (vln_one_sin_ran 134.2613 2 521.1533 .1600 :fm-index 1.7483) (vln_one_sin_ran 134.2615 .6000 521.1533 .1600 :fm-index 1.8717) (vln_one_sin_ran 134.2615 1.4000 522.1956 .1600 :fm-index 1.5619) (vln_one_sin_ran 134.2620 .6000 520.1131 .1600 :fm-index 2.4331) (vln_one_sin_ran 134.2623 1 519.0749 .1600 :fm-index 2.4153) (vln_one_sin_ran 134.2623 2 518.0388 .1600 :fm-index 1.5477) (vln_one_sin_ran 134.2623 2 517.0048 .1600 :fm-index 1.9956) (vln_one_sin_ran 134.2625 2 523.2400 .1600 :fm-index 1.8111) (vln_one_sin_ran 134.2625 1 522.7173 .1600 :fm-index 2.4820) (vln_one_sin_ran 134.2630 2 523.7632 .1600 :fm-index 1.5744) (vln_one_sin_ran 134.2633 2 522.1951 .1600 :fm-index 1.9950) (vln_one_sin_ran 134.2635 .6000 522.1951 .1600 :fm-index 1.9792) (vln_one_sin_ran 134.2635 1.4000 522.7173 .1600 :fm-index 1.7415) (vln_one_sin_ran 134.2640 .4 521.6734 .1600 :fm-index 2.0884) (vln_one_sin_ran 134.2643 1 521.1523 .1600 :fm-index 2.3605) (vln_one_sin_ran 134.2643 2 520.6316 .1600 :fm-index 1.7817) (vln_one_sin_ran 134.2643 2 520.1115 .1600 :fm-index 2.0283) (set! fm-violin-reverb-amount .1) (set! fm-violin-fm1-rat 2.718) (set! fm-violin-fm2-rat 1.414) (set! fm-violin-fm3-rat 3.141) (set! fm-violin-glissando-amount 0.0) (current-score-time 138) (vln_one_sin_ran 138.2600 1.6000 177.7708 .1600 :fm-index 1.6447) (vln_one_sin_ran 138.2600 2 177.7708 .1600 :fm-index 2.4875) (vln_one_sin_ran 138.2603 1.2000 177.7708 .1600 :fm-index 1.6126) (vln_one_sin_ran 138.2603 4 177.7708 .1600 :fm-index 2.3122) (vln_one_sin_ran 138.2605 1.2000 205.4371 .1600 :fm-index 2.4116) (vln_one_sin_ran 138.2605 2.8000 205.4371 .1600 :fm-index 1.5337) (vln_one_sin_ran 138.2608 1.2000 205.4371 .1600 :fm-index 2.0307) (vln_one_sin_ran 138.2608 1.6000 65.4050 .1600 :fm-index 2.2341) (vln_one_sin_ran 138.2610 2 65.4050 .1600 :fm-index 2.4683) (vln_one_sin_ran 138.2610 1.2000 65.4050 .1600 :fm-index 2.0643) (vln_one_sin_ran 138.2613 4 65.4050 .1600 :fm-index 2.1925) (vln_one_sin_ran 138.2615 1.2000 65.4050 .1600 :fm-index 2.1325) (vln_one_sin_ran 138.2615 2.8000 65.4050 .1600 :fm-index 1.5847) (vln_one_sin_ran 138.2620 1.2000 65.4050 .1600 :fm-index 1.8781) (vln_one_sin_ran 138.2623 2 65.4050 .1600 :fm-index 2.0283) (vln_one_sin_ran 138.2623 4 65.4050 .1600 :fm-index 2.4739) (vln_one_sin_ran 138.2623 4 65.4050 .1600 :fm-index 2.2333) (vln_one_sin_ran 138.2625 2 65.4050 .1600 :fm-index 2.2194) (vln_one_sin_ran 138.2625 1 65.4050 .1600 :fm-index 2.4491) (vln_one_sin_ran 138.2630 2 65.4050 .1600 :fm-index 1.5672) (vln_one_sin_ran 138.2633 2 65.4050 .1600 :fm-index 2.3254) (vln_one_sin_ran 138.2635 1.2000 65.4050 .1600 :fm-index 1.8302) (vln_one_sin_ran 138.2635 2.8000 65.4050 .1600 :fm-index 1.9201) (vln_one_sin_ran 138.2640 .8000 65.4050 .1600 :fm-index 1.9164) (vln_one_sin_ran 138.2643 2 65.4050 .1600 :fm-index 1.9483) (vln_one_sin_ran 138.2643 4 65.4050 .1600 :fm-index 2.4247) (vln_one_sin_ran 138.2643 4 65.4050 .1600 :fm-index 2.0419) (set! fm-violin-fm1-rat 2.718) (set! fm-violin-fm2-rat 4.414) (set! fm-violin-fm3-rat 3.141) (current-score-time 142) (vln_one_sin_ran 142.2600 1.6000 88.8854 .1600 :fm-index 2.2832) (vln_one_sin_ran 142.2600 2 88.8854 .1600 :fm-index 1.6588) (vln_one_sin_ran 142.2603 1.2000 88.8854 .1600 :fm-index 2.2392) (vln_one_sin_ran 142.2603 4 88.8854 .1600 :fm-index 1.7354) (vln_one_sin_ran 142.2605 1.2000 102.7186 .1600 :fm-index 1.6692) (vln_one_sin_ran 142.2605 2.8000 102.7186 .1600 :fm-index 2.1518) (vln_one_sin_ran 142.2608 1.2000 102.7186 .1600 :fm-index 2.2439) (vln_one_sin_ran 142.2608 1.6000 32.7025 .1600 :fm-index 2.1665) (vln_one_sin_ran 142.2610 2 32.7025 .1600 :fm-index 1.7947) (vln_one_sin_ran 142.2610 1.2000 32.7025 .1600 :fm-index 2.0740) (vln_one_sin_ran 142.2613 4 32.7025 .1600 :fm-index 1.9705) (vln_one_sin_ran 142.2615 1.2000 32.7025 .1600 :fm-index 1.9447) (vln_one_sin_ran 142.2615 2.8000 32.7025 .1600 :fm-index 2.4918) (vln_one_sin_ran 142.2620 1.2000 32.7025 .1600 :fm-index 1.6275) (vln_one_sin_ran 142.2623 2 32.7025 .1600 :fm-index 2.2355) (vln_one_sin_ran 142.2623 4 32.7025 .1600 :fm-index 2.0084) (vln_one_sin_ran 142.2623 4 32.7025 .1600 :fm-index 1.8964) (vln_one_sin_ran 142.2625 2 32.7025 .1600 :fm-index 2.3937) (vln_one_sin_ran 142.2625 1 32.7025 .1600 :fm-index 1.8634) (vln_one_sin_ran 142.2630 2 32.7025 .1600 :fm-index 1.5217) (vln_one_sin_ran 142.2633 2 32.7025 .1600 :fm-index 1.9275) (vln_one_sin_ran 142.2635 1.2000 32.7025 .1600 :fm-index 2.4413) (vln_one_sin_ran 142.2635 2.8000 32.7025 .1600 :fm-index 2.3242) (vln_one_sin_ran 142.2640 .8000 32.7025 .1600 :fm-index 2.3267) (vln_one_sin_ran 142.2643 2 32.7025 .1600 :fm-index 1.7004) (vln_one_sin_ran 142.2643 4 32.7025 .1600 :fm-index 1.8785) (vln_one_sin_ran 142.2643 4 32.7025 .1600 :fm-index 2.4573) (set! fm-violin-fm1-rat 2.718) (set! fm-violin-fm2-rat 4.414) (set! fm-violin-fm3-rat 5.141) (current-score-time 146) (vln_one_sin_ran 146.2600 1.6000 22.2213 .1600 :fm-index 1.6232) (vln_one_sin_ran 146.2600 2 22.2213 .1600 :fm-index 1.5982) (vln_one_sin_ran 146.2603 1.2000 22.2213 .1600 :fm-index 2.1585) (vln_one_sin_ran 146.2603 4 22.2213 .1600 :fm-index 2.2207) (vln_one_sin_ran 146.2605 1.2000 42.0309 .1600 :fm-index 1.5294) (vln_one_sin_ran 146.2605 2.8000 42.0309 .1600 :fm-index 1.9544) (vln_one_sin_ran 146.2608 1.2000 42.0309 .1600 :fm-index 2.4016) (vln_one_sin_ran 146.2608 1.6000 8.1756 .1600 :fm-index 1.5267) (vln_one_sin_ran 146.2610 2 8.1756 .1600 :fm-index 2.4190) (vln_one_sin_ran 146.2610 1.2000 8.1756 .1600 :fm-index 2.2757) (vln_one_sin_ran 146.2613 4 8.1756 .1600 :fm-index 2.3607) (vln_one_sin_ran 146.2615 1.2000 8.1756 .1600 :fm-index 1.8698) (vln_one_sin_ran 146.2615 2.8000 8.1756 .1600 :fm-index 2.3753) (vln_one_sin_ran 146.2620 1.2000 8.1756 .1600 :fm-index 2.3392) (vln_one_sin_ran 146.2623 2 8.1756 .1600 :fm-index 1.5088) (vln_one_sin_ran 146.2623 4 8.1756 .1600 :fm-index 2.2084) (vln_one_sin_ran 146.2623 4 8.1756 .1600 :fm-index 1.9512) (vln_one_sin_ran 146.2625 2 8.1756 .1600 :fm-index 2.0399) (vln_one_sin_ran 146.2625 1 8.1756 .1600 :fm-index 1.7053) (vln_one_sin_ran 146.2630 2 8.1756 .1600 :fm-index 2.3204) (vln_one_sin_ran 146.2633 2 8.1756 .1600 :fm-index 1.6336) (vln_one_sin_ran 146.2635 1.2000 8.1756 .1600 :fm-index 1.9483) (vln_one_sin_ran 146.2635 2.8000 8.1756 .1600 :fm-index 2.3255) (vln_one_sin_ran 146.2640 .8000 8.1756 .1600 :fm-index 1.7331) (vln_one_sin_ran 146.2643 2 8.1756 .1600 :fm-index 1.9318) (vln_one_sin_ran 146.2643 4 8.1756 .1600 :fm-index 1.6908) (vln_one_sin_ran 146.2643 4 8.1756 .1600 :fm-index 2.4103) (current-score-time 150) (vln_one_sin_ran 150.2600 1.6000 11.1107 .1600 :fm-index 1.6371) (vln_one_sin_ran 150.2600 2 11.1107 .1600 :fm-index 1.8971) (vln_one_sin_ran 150.2603 1.2000 11.1107 .1600 :fm-index 1.9065) (vln_one_sin_ran 150.2603 4 11.1107 .1600 :fm-index 2.2143) (vln_one_sin_ran 150.2605 1.2000 21.0154 .1600 :fm-index 1.8011) (vln_one_sin_ran 150.2605 2.8000 21.0154 .1600 :fm-index 2.1950) (vln_one_sin_ran 150.2608 1.2000 21.0154 .1600 :fm-index 2.3563) (vln_one_sin_ran 150.2608 1.6000 4.0878 .1600 :fm-index 2.3181) (vln_one_sin_ran 150.2610 2 4.0878 .1600 :fm-index 2.0776) (vln_one_sin_ran 150.2610 1.2000 4.0878 .1600 :fm-index 1.8336) (vln_one_sin_ran 150.2613 4 4.0878 .1600 :fm-index 1.5019) (vln_one_sin_ran 150.2615 1.2000 4.0878 .1600 :fm-index 2.2368) (vln_one_sin_ran 150.2615 2.8000 4.0878 .1600 :fm-index 1.7462) (vln_one_sin_ran 150.2620 1.2000 4.0878 .1600 :fm-index 1.9604) (vln_one_sin_ran 150.2623 2 4.0878 .1600 :fm-index 2.2361) (vln_one_sin_ran 150.2623 4 4.0878 .1600 :fm-index 1.9972) (vln_one_sin_ran 150.2623 4 4.0878 .1600 :fm-index 2.4870) (vln_one_sin_ran 150.2625 2 4.0878 .1600 :fm-index 2.0762) (vln_one_sin_ran 150.2625 1 4.0878 .1600 :fm-index 2.2973) (vln_one_sin_ran 150.2630 2 4.0878 .1600 :fm-index 2.2350) (vln_one_sin_ran 150.2633 2 4.0878 .1600 :fm-index 2.1613) (vln_one_sin_ran 150.2635 1.2000 4.0878 .1600 :fm-index 2.0640) (vln_one_sin_ran 150.2635 2.8000 4.0878 .1600 :fm-index 2.1738) (vln_one_sin_ran 150.2640 .8000 4.0878 .1600 :fm-index 1.5188) (vln_one_sin_ran 150.2643 2 4.0878 .1600 :fm-index 1.8766) (vln_one_sin_ran 150.2643 4 4.0878 .1600 :fm-index 2.3083) (vln_one_sin_ran 150.2643 4 4.0878 .1600 :fm-index 2.2215) (current-score-time 154) (vln_one_sin_ran 154.2600 1.6000 66.5893 .1600 :fm-index 1.7041) (vln_one_sin_ran 154.2600 2 66.4564 .1600 :fm-index 2.0296) (vln_one_sin_ran 154.2603 1.2000 66.7225 .1600 :fm-index 1.8321) (vln_one_sin_ran 154.2603 4 66.3237 .1600 :fm-index 2.1550) (vln_one_sin_ran 154.2605 1.2000 125.4490 .1600 :fm-index 2.1806) (vln_one_sin_ran 154.2605 2.8000 125.6999 .1600 :fm-index 2.3570) (vln_one_sin_ran 154.2608 1.2000 125.1986 .1600 :fm-index 1.9861) (vln_one_sin_ran 154.2608 1.6000 24.4994 .1600 :fm-index 1.6412) (vln_one_sin_ran 154.2610 2 24.4505 .1600 :fm-index 1.9770) (vln_one_sin_ran 154.2610 1.2000 24.5484 .1600 :fm-index 2.0103) (vln_one_sin_ran 154.2613 4 24.4017 .1600 :fm-index 2.0663) (vln_one_sin_ran 154.2615 1.2000 24.4017 .1600 :fm-index 2.1521) (vln_one_sin_ran 154.2615 2.8000 24.4505 .1600 :fm-index 2.4453) (vln_one_sin_ran 154.2620 1.2000 24.3530 .1600 :fm-index 2.0930) (vln_one_sin_ran 154.2623 2 24.6960 .1600 :fm-index 2.3423) (vln_one_sin_ran 154.2623 4 24.7454 .1600 :fm-index 2.0856) (vln_one_sin_ran 154.2623 4 24.7948 .1600 :fm-index 1.9570) (vln_one_sin_ran 154.2625 2 24.4994 .1600 :fm-index 2.4642) (vln_one_sin_ran 154.2625 1 24.4749 .1600 :fm-index 1.9901) (vln_one_sin_ran 154.2630 2 24.5239 .1600 :fm-index 1.9972) (vln_one_sin_ran 154.2633 2 24.4505 .1600 :fm-index 1.9148) (vln_one_sin_ran 154.2635 1.2000 24.4505 .1600 :fm-index 1.9017) (vln_one_sin_ran 154.2635 2.8000 24.4749 .1600 :fm-index 2.4958) (vln_one_sin_ran 154.2640 .8000 24.4260 .1600 :fm-index 2.2518) (vln_one_sin_ran 154.2643 2 24.5975 .1600 :fm-index 2.1120) (vln_one_sin_ran 154.2643 4 24.6221 .1600 :fm-index 2.3154) (vln_one_sin_ran 154.2643 4 24.6467 .1600 :fm-index 1.9240) (set! fm-violin-fm1-rat 6.718) (set! fm-violin-fm2-rat 4.414) (set! fm-violin-fm3-rat 5.141) (current-score-time 158) (vln_one_sin_ran 158.2600 1.6000 164.5868 .1600 :fm-index 1.9587) (vln_one_sin_ran 158.2600 2 164.5868 .1600 :fm-index 1.5071) (vln_one_sin_ran 158.2603 1.2000 164.5868 .1600 :fm-index 1.7690) (vln_one_sin_ran 158.2603 4 164.5868 .1600 :fm-index 1.7686) (vln_one_sin_ran 158.2605 1.2000 125.9513 .1600 :fm-index 1.5702) (vln_one_sin_ran 158.2605 2.8000 125.9513 .1600 :fm-index 2.1962) (vln_one_sin_ran 158.2608 1.2000 125.9513 .1600 :fm-index 1.7701) (vln_one_sin_ran 158.2608 1.6000 24.4994 .1600 :fm-index 2.1665) (vln_one_sin_ran 158.2610 2 24.4994 .1600 :fm-index 1.9345) (vln_one_sin_ran 158.2610 1.2000 24.4994 .1600 :fm-index 2.2037) (vln_one_sin_ran 158.2613 4 24.4994 .1600 :fm-index 1.6826) (vln_one_sin_ran 158.2615 1.2000 24.4994 .1600 :fm-index 1.5410) (vln_one_sin_ran 158.2615 2.8000 24.4994 .1600 :fm-index 1.8293) (vln_one_sin_ran 158.2620 1.2000 24.4994 .1600 :fm-index 2.1468) (vln_one_sin_ran 158.2623 2 24.4994 .1600 :fm-index 2.0758) (vln_one_sin_ran 158.2623 4 24.4994 .1600 :fm-index 2.4138) (vln_one_sin_ran 158.2623 4 24.4994 .1600 :fm-index 1.8479) (vln_one_sin_ran 158.2625 3 24.4994 .1600 :fm-index 2.4639) (vln_one_sin_ran 158.2625 1.5000 24.4994 .1600 :fm-index 2.3995) (vln_one_sin_ran 158.2630 3 24.4994 .1600 :fm-index 1.8609) (vln_one_sin_ran 158.2633 3 24.4994 .1600 :fm-index 2.4506) (vln_one_sin_ran 158.2635 1.2000 24.4994 .1600 :fm-index 2.1577) (vln_one_sin_ran 158.2635 2.8000 24.4994 .1600 :fm-index 1.6663) (vln_one_sin_ran 158.2640 .8000 24.4994 .1600 :fm-index 2.1166) (vln_one_sin_ran 158.2643 2 24.4994 .1600 :fm-index 1.9362) (vln_one_sin_ran 158.2643 4 24.4994 .1600 :fm-index 2.2052) (vln_one_sin_ran 158.2643 4 24.4994 .1600 :fm-index 2.0102) (restore-fm-violin-defaults) (set! fm-violin-glissando-amount .8) (set! fm-violin-reverb-amount .01) (set! fm-violin-gliss-env whoosh) (set! fm-violin-amp-env metalamp) (set! fm-violin-fm1-rat 2.718) (set! fm-violin-fm2-rat 1.141) (set! fm-violin-fm3-rat 3.141) (current-score-time 162) (vln_one_sin 162.2600 .4 1046.4800 .1600 :fm-index 2.3870) (vln_one_sin 162.2600 .5 1044.3912 .1600 :fm-index 2.4309) (vln_one_sin 162.2603 .3 1048.5730 .1600 :fm-index 2.1500) (vln_one_sin 162.2603 .5 1042.3066 .1600 :fm-index 1.7211) (vln_one_sin 162.2610 .3 524.2865 .1600 :fm-index 2.1751) (vln_one_sin 162.2620 .3 520.1131 .1600 :fm-index 1.5433) (vln_one_sin 162.2623 .4 517.0048 .1600 :fm-index 2.4335) (vln_one_sin 162.2625 .4 523.2400 .1600 :fm-index 2.2778) (vln_one_sin 162.2635 .3 522.1951 .1600 :fm-index 1.9441) (vln_one_sin 162.2643 .4 520.6316 .1600 :fm-index 2.4656) (restore-fm-violin-defaults) (current-score-time 166) (vln_one_sin 166.1200 .4 2092.9600 .1600 :fm-index 3 :reverb-amount 0 :amp-env metalamp :fm2-rat 1.1410 :fm3-rat 3.1410 :fm1-rat 2.7180) (vln_one_sin 166.1200 .5 2088.7820 .1600 :fm-index 3 :reverb-amount 0 :amp-env metalamp :fm2-rat 1.1410 :fm3-rat 3.1410 :fm1-rat 2.7180) (vln_one_sin 166.1200 .3 2097.1460 .1600 :fm-index 3 :reverb-amount 0 :amp-env metalamp :fm2-rat 1.1410 :fm3-rat 3.1410 :fm1-rat 2.7180) (vln_one_sin 166.1200 .5 2084.6130 .1600 :fm-index 3 :reverb-amount 0 :amp-env metalamp :fm2-rat 1.1410 :fm3-rat 3.1410 :fm1-rat 2.7180) (vln_one_sin 166.1210 .3 1048.5730 .1600 :fm-index 3 :reverb-amount 0 :amp-env metalamp :fm2-rat 1.1410 :fm3-rat 3.1410 :fm1-rat 2.7180) (vln_one_sin 166.1220 .3 1040.2260 .1600 :fm-index 3 :reverb-amount 0 :amp-env metalamp :fm2-rat 1.1410 :fm3-rat 3.1410 :fm1-rat 2.7180) (vln_one_sin 166.1220 .5 1034.0100 .1600 :fm-index 3 :reverb-amount 0 :amp-env metalamp :fm2-rat 1.1410 :fm3-rat 3.1410 :fm1-rat 2.7180) (vln_one_sin 166.1230 .5 1046.4800 .1600 :fm-index 3 :reverb-amount 0 :amp-env metalamp :fm2-rat 1.1410 :fm3-rat 3.1410 :fm1-rat 2.7180) (vln_one_sin 166.1240 .3 1044.3900 .1600 :fm-index 3 :reverb-amount 0 :amp-env metalamp :fm2-rat 1.1410 :fm3-rat 3.1410 :fm1-rat 2.7180) (set! fm-violin-fm1-rat 2.718) (set! fm-violin-fm2-rat 4.414) (set! fm-violin-fm3-rat 5.141) (vln_one_sin 166.1240 .5 1041.2630 .1600 :fm-index 3 :reverb-amount 0 :amp-env metalamp :fm2-rat 1.1410 :fm3-rat 3.1410 :fm1-rat 2.7180) (current-score-time 168) (vln_one_sin_ran 168.4880 1.1770 416.6072 .0110 :fm-index 1.1140 :reverb-amount .1 :amp-env z1amp :noise-amount .0050) (vln_one_sin_ran 168.5050 2.4900 859.5863 .0083 :fm-index .5890 :reverb-amount .1 :amp-env z2amp :noise-amount .0050) (vln_one_sin_ran 169.0590 1.0550 1758.0816 .0053 :fm-index 1.8640 :reverb-amount .1 :amp-env z2amp :noise-amount .0050) (vln_one_sin_ran 169.0930 1.8580 229.0566 .0110 :fm-index 1.9690 :reverb-amount .1 :amp-env z2amp :noise-amount .0050) (vln_one_sin_ran 169.3490 3.3680 479.1994 .0083 :fm-index 1.9970 :reverb-amount .1 :amp-env z1amp :noise-amount .0050) (vln_one_sin_ran 169.5010 3.0680 411.8241 .0110 :fm-index 1.5390 :reverb-amount .1 :amp-env z2amp :noise-amount .0050) (vln_one_sin_ran 169.5200 2.8290 984.8456 .0053 :fm-index .0560 :reverb-amount .1 :amp-env z1amp :noise-amount .0050) (vln_one_sin_ran 169.6100 .7040 1767.7444 .0053 :fm-index 1.2620 :reverb-amount .1 :amp-env z2amp :noise-amount .0050) (vln_one_sin_ran 169.8480 3.0510 859.7203 .0083 :fm-index 1.6080 :reverb-amount .1 :amp-env z2amp :noise-amount .0050) (vln_one_sin_ran 170.4880 3.2350 231.9431 .0110 :fm-index .9690 :reverb-amount .1 :amp-env z1amp :noise-amount .0050) (vln_one_sin_ran 170.5610 3.2810 475.2009 .0083 :fm-index .3740 :reverb-amount .1 :amp-env z2amp :noise-amount .0050) (vln_one_sin_ran 170.7970 2.8400 988.8375 .0053 :fm-index .4200 :reverb-amount .1 :amp-env z2amp :noise-amount .0050) (vln_one_sin_ran 171.0620 1.0210 411.7247 .0110 :fm-index .1370 :reverb-amount .1 :amp-env z2amp :noise-amount .0050) (vln_one_sin_ran 171.2130 1.1610 848.5959 .0083 :fm-index 1.3120 :reverb-amount .1 :amp-env z2amp :noise-amount .0050) (vln_one_sin_ran 171.4410 2.6160 390.0600 .0110 :fm-index 1.9030 :reverb-amount .1 :amp-env z1amp :noise-amount .0050) (vln_one_sin_ran 171.4490 .7000 802.3538 .0083 :fm-index 1.5940 :reverb-amount .1 :amp-env z2amp :noise-amount .0050) (vln_one_sin_ran 171.5270 2.5080 1773.9366 .0053 :fm-index 1.8030 :reverb-amount .1 :amp-env z1amp :noise-amount .0050) (vln_one_sin_ran 171.7820 2.7990 232.4344 .0110 :fm-index .0590 :reverb-amount .1 :amp-env z2amp :noise-amount .0050) (vln_one_sin_ran 171.7830 2.7660 1650.1434 .0053 :fm-index .4400 :reverb-amount .1 :amp-env z2amp :noise-amount .0050) (vln_one_sin_ran 171.7890 3.1560 475.7231 .0083 :fm-index .7370 :reverb-amount .1 :amp-env z2amp :noise-amount .0050) (vln_one_sin_ran 172.1540 2.1290 976.0237 .0053 :fm-index 1.2690 :reverb-amount .1 :amp-env z2amp :noise-amount .0050) (vln_one_sin_ran 172.4890 3.3650 390.0525 .0110 :fm-index 1.4580 :reverb-amount .1 :amp-env z2amp :noise-amount .0050) (vln_one_sin_ran 172.7450 1.5070 1665.9722 .0053 :fm-index 1.9330 :reverb-amount .1 :amp-env z2amp :noise-amount .0050) (vln_one_sin_ran 172.8320 1.4430 798.1238 .0083 :fm-index .8560 :reverb-amount .1 :amp-env z1amp :noise-amount .0050) (vln_one_sin_ran 172.9440 3.1560 229.0528 .0110 :fm-index 1.8300 :reverb-amount .1 :amp-env z2amp :noise-amount .0050) (vln_one_sin_ran 173.3930 1.1100 473.7225 .0083 :fm-index 1.6260 :reverb-amount .1 :amp-env z1amp :noise-amount .0050) (vln_one_sin_ran 173.6970 1.6170 988.7953 .0053 :fm-index .4230 :reverb-amount .1 :amp-env z2amp :noise-amount .0050) (vln_one_sin_ran 174.0620 1.3190 390.9769 .0110 :fm-index .4100 :reverb-amount .1 :amp-env z2amp :noise-amount .0050) (vln_one_sin_ran 174.0840 3.3660 804.6413 .0083 :fm-index 1.8760 :reverb-amount .1 :amp-env z2amp :noise-amount .0050) (vln_one_sin_ran 174.1740 2.7210 418.6819 .0110 :fm-index .0910 :reverb-amount .1 :amp-env z2amp :noise-amount .0050) (vln_one_sin_ran 174.5700 3.4460 845.4019 .0077 :fm-index .7660 :reverb-amount .1 :amp-env z2amp :noise-amount .0050) (vln_one_sin_ran 174.6440 1.1790 1656.5756 .0049 :fm-index .2960 :reverb-amount .1 :amp-env z1amp :noise-amount .0050) (vln_one_sin_ran 174.6600 2.8520 1758.9788 .0049 :fm-index .4520 :reverb-amount .1 :amp-env z2amp :noise-amount .0050) (vln_one_sin_ran 174.8270 1.8840 387.0009 .0099 :fm-index 1.3010 :reverb-amount .1 :amp-env z1amp :noise-amount .0050) (vln_one_sin_ran 174.8870 3.4040 796.7213 .0077 :fm-index 1.1820 :reverb-amount .1 :amp-env z2amp :noise-amount .0050) (vln_one_sin_ran 174.9640 3.3230 416.3916 .0099 :fm-index .6290 :reverb-amount .1 :amp-env z2amp :noise-amount .0050) (vln_one_sin_ran 175.1320 1.7050 1637.2303 .0049 :fm-index 1.0570 :reverb-amount .1 :amp-env z1amp :noise-amount .0050) (vln_one_sin_ran 175.1500 3.1250 1762.4906 .0049 :fm-index 1.3170 :reverb-amount .1 :amp-env z2amp :noise-amount .0050) (vln_one_sin_ran 175.3860 2.9670 852.0487 .0077 :fm-index 1.4790 :reverb-amount .1 :amp-env z1amp :noise-amount .0050) (vln_one_sin_ran 175.6670 .6780 413.7094 .0099 :fm-index .9470 :reverb-amount .1 :amp-env z2amp :noise-amount .0050) (vln_one_sin_ran 175.8780 2.7490 1749.7509 .0049 :fm-index .5040 :reverb-amount .1 :amp-env z1amp :noise-amount .0050) (vln_one_sin_ran 175.9730 .5990 848.1253 .0077 :fm-index 1.9380 :reverb-amount .1 :amp-env z1amp :noise-amount .0050) (vln_one_sin_ran 176.0880 3.3360 229.9144 .0099 :fm-index 1.3930 :reverb-amount .1 :amp-env z2amp :noise-amount .0050) (vln_one_sin_ran 176.1170 1.1300 984.0816 .0049 :fm-index .3560 :reverb-amount .1 :amp-env z2amp :noise-amount .0050) (vln_one_sin_ran 176.4640 1.7330 478.7184 .0077 :fm-index .2840 :reverb-amount .1 :amp-env z2amp :noise-amount .0050) (vln_one_sin_ran 176.5760 .5680 413.4253 .0099 :fm-index 1.5020 :reverb-amount .1 :amp-env z2amp :noise-amount .0050) (vln_one_sin_ran 176.8200 1.2150 230.9588 .0099 :fm-index 1.0990 :reverb-amount .1 :amp-env z1amp :noise-amount .0050) (vln_one_sin_ran 176.8320 3.4590 473.8903 .0077 :fm-index .7680 :reverb-amount .1 :amp-env z2amp :noise-amount .0050) (vln_one_sin_ran 176.8320 .7260 857.2875 .0077 :fm-index .7520 :reverb-amount .1 :amp-env z2amp :noise-amount .0050) (restore-fm-violin-defaults) (current-score-time 180) (violin 180.2600 .0500 80 .8000 :fm-index 5 :reverb-amount 0 :amp-env ampfunc1 :fm1-env indfunc2) (violin 181.2610 .2000 80 .8000 :fm-index 4 :reverb-amount 0 :amp-env ampfunc :fm1-env indfunc :fm2-rat .6875) (violin 182.2600 .0500 80 .8000 :fm-index 5 :reverb-amount 0 :amp-env ampfunc1 :fm1-env indfunc2) (violin 182.2620 .2000 80 .8000 :fm-index 5 :reverb-amount 0 :amp-env ampfunc :fm1-env indfunc :fm2-rat .6875) (violin 183.2600 .0500 80 .8000 :fm-index 6 :reverb-amount 0 :amp-env ampfunc1 :fm1-env indfunc2) (violin 183.2630 .2000 80 .8000 :fm-index 6 :reverb-amount 0 :amp-env ampfunc :fm1-env indfunc :fm2-rat .6875) (violin 184.2600 .0500 80 .3 :fm-index 4 :reverb-amount 0 :amp-env ampfunc1 :fm1-env indfunc2) (violin 184.2620 .1 160 .3 :fm-index 4 :reverb-amount 0 :amp-env ampfunc :fm1-env indfunc :fm2-rat .6875) (violin 184.2620 .2500 80 .8000 :fm-index 4 :reverb-amount 0 :amp-env ampfunc :fm1-env indfunc :fm2-rat .6875) (violin 185.2600 .0500 80 .5 :fm-index 4 :reverb-amount 0 :amp-env ampfunc1 :fm1-env indfunc2) (violin 185.2610 .1 210 .3 :fm-index 4 :reverb-amount 0 :amp-env ampfunc :fm1-env indfunc :fm2-rat .6875) (violin 185.2620 .2000 80 .1 :fm-index 4 :reverb-amount 0 :amp-env ampfunc :fm1-env indfunc :fm2-rat .6875) (violin 185.2630 .2500 320 .1 :fm-index 2 :reverb-amount 0 :amp-env ampfunc :fm1-env indfunc :fm2-rat .6875) (violin 186.2600 .0500 80 .8000 :fm-index 4 :reverb-amount 0 :amp-env ampfunc1 :fm1-env indfunc2) (violin 186.2610 .1 210 .1 :fm-index 2 :reverb-amount 0 :amp-env ampfunc :fm1-env indfunc :fm2-rat .6875) (violin 186.2620 .2000 80 .2000 :fm-index 4 :reverb-amount 0 :amp-env ampfunc :fm1-env indfunc :fm2-rat .6875) (violin 186.2630 .2500 320 .3 :reverb-amount 0 :amp-env ampfunc :fm1-env indfunc :fm2-rat .6875) (violin 187.2600 .0500 80 .8000 :fm-index 2 :reverb-amount 0 :amp-env ampfunc1 :fm1-env indfunc2) (violin 187.2610 .1 210 .1 :fm-index 2 :reverb-amount 0 :amp-env ampfunc :fm1-env indfunc :fm2-rat .6875) (violin 187.2620 .2000 80 .2000 :fm-index 2 :reverb-amount 0 :amp-env ampfunc :fm1-env indfunc :fm2-rat .6875) (violin 187.2630 .2500 320 .3 :reverb-amount 0 :amp-env ampfunc :fm1-env indfunc :fm2-rat .6875) (set! fm-violin-glissando-amount 0.0) (set! fm-violin-noise-amount 0.004) (set! fm-violin-fm1-rat 3.141) (set! fm-violin-fm2-rat 4.414) (set! fm-violin-fm3-rat 2.718) (current-score-time 188) (vln_one_sin_ran 188.2600 4 3286.9937 .1600 :fm-index 2.2165 :reverb-amount .0100 :amp-env n_amp :fm1-env n_amp) (vln_one_sin_ran 188.2603 4 1046.4800 .1600 :fm-index 2.3234 :reverb-amount .0100 :amp-env n_amp :fm1-env n_amp) (vln_one_sin_ran 188.2605 4 2844.3326 .1600 :fm-index 2.4790 :reverb-amount .1 :amp-env n_amp :fm1-env n_amp) (vln_one_sin_ran 188.2608 4 821.7484 .1 :fm-index 1.8667 :reverb-amount .0100 :amp-env n_amp :fm1-env n_amp) (vln_one_sin_ran 188.2610 4 261.6200 .1 :fm-index 1.8523 :reverb-amount .0100 :amp-env n_amp :fm1-env n_amp) (vln_one_sin_ran 188.2613 4 711.0832 .1 :fm-index 2.2300 :reverb-amount .1 :amp-env n_amp :fm1-env n_amp) (vln_one_sin_ran 188.2615 4 205.4371 .0600 :fm-index 1.5187 :reverb-amount .0100 :amp-env n_amp :fm1-env n_amp) (vln_one_sin_ran 188.2618 4 65.4050 .0600 :fm-index 2.4074 :reverb-amount .0100 :amp-env n_amp :fm1-env n_amp) (vln_one_sin_ran 188.2620 4 177.7708 .0600 :fm-index 2.4481 :reverb-amount .1 :amp-env n_amp :fm1-env n_amp) (vln_one_sin_ran 188.2623 4 51.3593 .0100 :fm-index 2.3069 :reverb-amount .0100 :amp-env n_amp :fm1-env n_amp) (vln_one_sin_ran 188.2625 4 16.3513 .0100 :fm-index 2.1008 :reverb-amount .0100 :amp-env n_amp :fm1-env n_amp) (vln_one_sin_ran 188.2628 4 44.4427 .0100 :fm-index 2.4860 :reverb-amount .1 :amp-env n_amp :fm1-env n_amp) (restore-fm-violin-defaults) (current-score-time 196) (vln_one_sin 196.2603 1.2000 88.8854 .1 :fm-index 2.3144 :reverb-amount .2000 :amp-env mamp :fm2-rat 4.4140 :fm3-rat 5.1410 :fm1-rat 2.7180) (vln_one_sin 196.2603 4 88.8854 .1 :fm-index 2.1690 :reverb-amount .2000 :amp-env mamp :fm2-rat 4.4140 :fm3-rat 5.1410 :fm1-rat 2.7180) (vln_one_sin 196.2605 2.8000 168.1236 .0500 :fm-index 2.1850 :reverb-amount .2000 :amp-env mamp :fm2-rat 4.4140 :fm3-rat 5.1410 :fm1-rat 2.7180) (vln_one_sin 196.2608 1.2000 168.1236 .0800 :fm-index 1.7743 :reverb-amount .2000 :amp-env mamp :fm2-rat 4.4140 :fm3-rat 5.1410 :fm1-rat 2.7180) (vln_one_sin 196.2610 2 32.7025 .1 :fm-index 2.4925 :reverb-amount .2000 :amp-env mamp :fm2-rat 4.4140 :fm3-rat 5.1410 :fm1-rat 2.7180) (vln_one_sin 196.2633 2 32.7025 .1 :fm-index 2.1325 :reverb-amount .2000 :amp-env mamp :fm2-rat 4.4140 :fm3-rat 5.1410 :fm1-rat 2.7180) (vln_one_sin 196.2643 4 32.7025 .0500 :fm-index 1.7578 :reverb-amount .2000 :amp-env mamp :fm2-rat 4.4140 :fm3-rat 5.1410 :fm1-rat 2.7180) (current-score-time 204) (vln_one_sin_ran 204.2600 6.6830 244.8160 .0060 :fm-index 2 :reverb-amount .2000 :noise-amount .0040) (vln_one_sin_ran 204.2600 5.5170 495.4040 .0060 :fm-index 2 :reverb-amount .2000 :noise-amount .0040) (vln_one_sin_ran 204.2600 7.5350 980.6190 .0020 :fm-index 2 :reverb-amount .2000 :noise-amount .0040) (vln_one_sin_ran 204.2600 7.1990 1965.4290 .0020 :fm-index .8000 :reverb-amount .2000 :noise-amount .0040) (vln_one_sin_ran 204.2600 4.0790 3835.3170 .0020 :fm-index .8000 :reverb-amount .2000 :noise-amount .0040) (vln_one_sin_ran 204.5170 4.7400 1320.9670 .0020 :fm-index .8000 :reverb-amount .2000 :noise-amount .0040) (vln_one_sin_ran 204.7040 7.2080 655.5670 .0040 :fm-index 2 :reverb-amount .2000 :noise-amount .0040) (vln_one_sin_ran 205.0490 6.6530 169.4230 .0040 :fm-index 2 :reverb-amount .2000 :noise-amount .0040) (set! fm-violin-glissando-amount 0.0) (set! fm-violin-reverb-amount .9) (current-score-time 213) (vln_one_sin_exp 213.5450 6.4650 366.3330 .0320 :fm-index 1.0480 :amp-env '(0 0 1.5468 1 2.0882 .7000 2.3202 1 98.4532 .7500 100.0 0)) (vln_one_sin_exp 213.5950 8.4340 1172.5830 .0180 :fm-index 1.1350 :amp-env '(0 0 1.1857 1.0 1.6007 .7000 1.7785 1 98.8143 .5556 100.0 0)) (vln_one_sin_exp 213.7650 1.6210 369.9940 .0170 :fm-index .0960 :amp-env '(0 0 6.1690 1.0 8.3282 .7000 9.2535 1.0 93.8310 .5294 100.0 0)) (vln_one_sin_exp 213.8820 3.0640 246.9420 .0170 :fm-index .0020 :amp-env '(0 0 3.2637 1 4.4060 .7000 4.8956 1.0 96.7363 .5294 100.0 0)) (vln_one_sin_exp 213.9250 3.1170 123.4710 .0380 :fm-index .2330 :amp-env '(0 0 3.2082 1 4.3311 .7000 4.8123 1 96.7918 .7895 100.0 0)) (vln_one_sin_exp 213.9810 3.5670 123.4710 .0420 :fm-index .2330 :amp-env '(0 0 2.8035 1 3.7847 .7 4.2052 1.0 97.1965 .8095 100.0 0)) (vln_one_sin_exp 214.1280 1.0450 246.9420 .0170 :fm-index 1.2050 :amp-env '(0 0 9.5694 1 12.9187 .7000 14.3541 1 90.4306 .5294 100.0 0)) (vln_one_sin_exp 214.2550 3.3870 374.1370 .0170 :fm-index .1800 :amp-env '(0 0 2.9525 1.0 3.9858 .7000 4.4287 1.0 97.0475 .5294 100.0 0)) (vln_one_sin_exp 214.2990 8.3050 1576.9120 .0200 :fm-index .2990 :amp-env '(0 0 1.2041 1 1.6255 .7000 1.8061 1 98.7959 .6000 100.0 0)) (vln_one_sin_exp 214.3300 4.4630 246.9420 .0170 :fm-index .0020 :amp-env '(0 0 2.2406 1 3.0249 .7 3.3610 1.0 97.7594 .5294 100.0 0)) (vln_one_sin_exp 214.6600 8.9940 1576.9120 .0200 :fm-index .2990 :amp-env '(0 0 1.1119 1 1.5010 .7000 1.6678 1 98.8881 .6000 100.0 0)) (vln_one_sin_exp 214.9060 8.8360 1172.5830 .0180 :fm-index 1.1350 :amp-env '(0 0 1.1317 1 1.5278 .7000 1.6976 1 98.8683 .5556 100.0 0)) (vln_one_sin_exp 215.1510 4.9320 374.1370 .0170 :fm-index .1800 :amp-env '(0 0 2.0276 1 2.7372 .7000 3.0414 1 97.9724 .5294 100.0 0)) (vln_one_sin_exp 215.2720 2.3250 369.9940 .0170 :fm-index 1.1030 :amp-env '(0 0 4.3011 1 5.8065 .7000 6.4516 1 95.6989 .5294 100.0 0)) (vln_one_sin_exp 216.6960 3.5540 366.3330 .0310 :fm-index 1.0480 :amp-env '(0 0 2.8137 1 3.7985 .7000 4.2206 1 97.1863 .7419 100.0 0)) (vln_one_sin_exp 217.7240 .6040 246.9420 .0170 :fm-index 1.2050 :amp-env '(0 0 16.5563 1 22.3510 .7000 24.8344 1 83.4437 .5294 100 0)) (vln_one_sin_exp 217.9420 2.5010 123.4710 .0330 :fm-index .2330 :amp-env '(0 0 3.9984 1 5.3978 .7000 5.9976 1 96.0016 .7576 100.0 0)) (vln_one_sin_exp 218.0340 2.3860 246.9420 .0170 :fm-index .0020 :amp-env '(0 0 4.1911 1 5.6580 .7000 6.2867 1 95.8089 .5294 100.0 0)) (vln_one_sin_exp 218.3850 1.4510 369.9940 .0170 :fm-index 1.1030 :amp-env '(0 0 6.8918 1 9.3039 .7000 10.3377 1 93.1082 .5294 100.0 0)) (vln_one_sin_exp 218.5670 2.6550 374.1370 .0170 :fm-index .1800 :amp-env '(0 0 3.7665 1 5.0847 .7000 5.6497 1 96.2335 .5294 100.0 0)) (vln_one_sin_exp 218.9830 2.9860 123.4710 .0380 :fm-index .2330 :amp-env '(0 0 3.3490 1 4.5211 .7000 5.0234 1 96.6510 .7895 100.0 0)) (vln_one_sin_exp 219.4910 .6110 123.9770 .0170 :fm-index .7550 :amp-env '(0 0 16.3666 1 22.0949 .7000 24.5499 1 83.6334 .5294 100.0 0)) (vln_one_sin_exp 219.7570 1.4440 123.4710 .0170 :fm-index .0020 :amp-env '(0 0 6.9252 1 9.3490 .7000 10.3878 1 93.0748 .5294 100.0 0)) (vln_one_sin_exp 219.7750 .5370 92.4435 .0330 :fm-index .9200 :amp-env '(0 0 18.6220 1 25.1397 .7000 27.9330 1 81.3780 .7576 100.0 0)) (vln_one_sin_exp 219.7750 10.5370 92.4435 .0130 :fm-index .9200 :amp-env '(0 0 .9490 1 1.2812 .7000 1.4236 1 99.0510 .3846 100.0 0)) (vln_one_sin_exp 219.9380 .6520 122.2995 .0170 :fm-index 1.8380 :amp-env '(0 0 15.3374 1 20.7055 .7 23.0061 1 84.6626 .5294 100.0 0)) (vln_one_sin_exp 220.2350 3.7250 586.2915 .0180 :fm-index 1.1350 :amp-env '(0 0 2.6846 1 3.6242 .7 4.0268 1 97.3154 .5556 100.0 0)) (vln_one_sin_exp 220.2560 2.8900 183.1665 .0260 :fm-index 1.0480 :amp-env '(0 0 3.4602 1 4.6713 .7000 5.1903 1 96.5398 .6923 100.0 0)) (vln_one_sin_exp 220.2710 1.6210 187.0685 .0170 :fm-index .1800 :amp-env '(0 0 6.1690 1.0 8.3282 .7 9.2535 1.0 93.8310 .5294 100.0 0)) (vln_one_sin_exp 220.2920 2.0160 183.1665 .0290 :fm-index 1.0480 :amp-env '(0 0 4.9603 1 6.6964 .7000 7.4405 1 95.0397 .7241 100.0 0)) (vln_one_sin_exp 220.2920 12.0160 183.1665 .0290 :fm-index 1.0480 :amp-env '(0 0 .8322 1 1.1235 .7000 1.2483 1.0000 99.1678 .7241 100.0 0)) (vln_one_sin_exp 220.3300 .7300 184.9970 .0170 :fm-index .0960 :amp-env '(0 0 13.6986 1 18.4932 .7 20.5479 1.0 86.3014 .5294 100 0)) (vln_one_sin_exp 220.3570 1.9600 183.1665 .0280 :fm-index 1.0480 :amp-env '(0 0 5.1020 1.0 6.8878 .7 7.6531 1.0 94.8980 .7143 100.0 0)) (vln_one_sin_exp 220.3820 2.2450 61.7355 .0330 :fm-index .2330 :amp-env '(0 0 4.4543 1 6.0134 .7000 6.6815 1 95.5457 .7576 100.0 0)) (vln_one_sin_exp 220.3820 12.2450 61.7355 .0330 :fm-index .2330 :amp-env '(0 0 .8167 1 1.1025 .7000 1.2250 1 99.1833 .7576 100.0 0)) (vln_one_sin_exp 220.5410 3.0130 246.5050 .0360 :fm-index 1.1350 :amp-env '(0 0 3.3190 1.0 4.4806 .7 4.9784 1.0 96.6810 .7778 100.0 0)) (vln_one_sin_exp 220.5570 2.3220 1251.5960 .0400 :fm-index .2990 :amp-env '(0 0 4.3066 1 5.8140 .7000 6.4599 1 95.6934 .8000 100.0 0)) (vln_one_sin_exp 220.5570 18.3220 1251.5960 .0200 :fm-index .2990 :amp-env '(0 0 .5458 1.0000 .7368 .7000 .8187 1 99.4542 .6000 100.0 0)) (vln_one_sin 220.5600 13.8770 3951.1200 .0060 :fm-index .5 :amp-env updown) (vln_one_sin 220.7600 17.8770 493.8900 .0170 :fm-index .5280 :amp-env updown) (vln_one_sin_exp 221.1060 1.9900 183.1665 .0230 :fm-index 1.0480 :amp-env '(0 0 5.0251 1.0 6.7839 .7 7.5377 1 94.9749 .6522 100.0 0)) (vln_one_sin 221.1600 13.8770 1975.5600 .0110 :fm-index 1.2000 :amp-env updown) (vln_one_sin_exp 221.2570 1.9180 61.7355 .0330 :fm-index .2330 :amp-env '(0 0 5.2138 1 7.0386 .7000 7.8206 1 94.7862 .7576 100.0 0)) (vln_one_sin 221.2600 15.8770 246.9450 .0170 :fm-index .5280 :amp-env updown) (vln_one_sin_exp 221.6370 1.3090 183.1665 .0310 :fm-index 1.0480 :amp-env '(0 0 7.6394 1 10.3132 .7000 11.4591 1 92.3606 .7419 100.0 0)) (vln_one_sin 221.8600 16.8770 987.7800 .0130 :fm-index 1.5000 :amp-env updown) (vln_one_sin_exp 222.0330 1.1590 183.1665 .0250 :fm-index 1.0480 :amp-env '(0 0 8.6281 1 11.648 .7 12.9422 1.0 91.3719 .68 100.0 0)) (vln_one_sin 222.0600 13.8770 3951.1200 .0090 :amp-env updown) (vln_one_sin_exp 222.0980 1.2400 30.8675 .0330 :fm-index .2330 :amp-env '(0 0 8.0645 1 10.8871 .7000 12.0968 1 91.9355 .7576 100.0 0)) (vln_one_sin_exp 222.0980 11.2400 30.8675 .0130 :fm-index .2330 :amp-env '(0 0 .8897 1 1.2011 .7000 1.3345 1 99.1103 .3846 100.0 0)) (vln_one_sin_exp 222.1260 .2600 123.4710 .0170 :fm-index 1.2050 :amp-env '(0 0 38.4615 1 51.9231 .7000 57.6923 1 61.5385 .5294 100.0 0)) (vln_one_sin_exp 222.1260 10.2600 123.4710 .0170 :fm-index 1.2050 :amp-env '(0 0 .9747 1 1.3158 .7000 1.4620 1 99.0253 .5294 100.0 0)) (vln_one_sin 222.2600 14.8770 123.4725 .0170 :fm-index 1.5000 :amp-env updown) (vln_one_sin 222.2600 13.8770 61.7363 .0170 :fm-index 1.5000 :amp-env updown) (vln_one_sin 222.2600 12.8770 30.8681 .0170 :fm-index 1.5000 :amp-env updown) (vln_one_sin 222.2600 11.8770 15.4341 .0170 :fm-index 1.5000 :amp-env updown) (restore-fm-violin-defaults) (current-score-time 241) (cel_one_sum 241.2620 .3906 440 .4500 :fm-index 1.2000 :reverb-amount .0013 :amp-env '(0 0 .7680 1 4.7774 .6000 9.7891 .3 24.8243 .1 100 0)) (cel_one_sum 241.2640 .5220 220 .4500 :fm-index 1.2000 :reverb-amount .0012 :amp-env '(0 0 .5747 1.0000 4.5919 .6000 9.6134 .3 24.6778 .1 100 0)) (cel_one_sum 241.2660 1.5660 880 .4500 :fm-index 1.2000 :reverb-amount .0014 :amp-env '(0 0 .1916 1.0000 4.2242 .6000 9.2651 .3 24.3876 .1 100.0 0)) (cel_one_sum 241.2680 1.5660 110 .4500 :fm-index 1.2000 :reverb-amount .0013 :amp-env '(0 0 .1916 1.0000 4.2242 .6000 9.2651 .3 24.3876 .1 100.0 0)) (current-score-time 244) (vln_one_sin 244.8600 .9000 733.3330 .1875 :fm-index .2000 :distance 1 :reverb-amount .0012 :amp-env '(0 0 .3333 1 4.3603 .6000 9.3939 .3 24.4950 .1 100.0 0)) (vln_one_sin 244.8600 .2250 550 .1875 :fm-index .2000 :distance 1 :reverb-amount .0015 :amp-env '(0 0 1.3333 1 5.3199 .6000 10.3030 .3 25.2525 .1 100 0)) (vln_one_sin 244.8600 .4500 586.6670 .3750 :fm-index .2000 :distance 1 :reverb-amount .0013 :amp-env '(0 0 .6667 1 4.6801 .6000 9.6970 .3 24.7475 .1 100 0)) (vln_one_sin 244.9020 .9000 733.3330 .1875 :fm-index .4 :distance 1 :reverb-amount .0013 :amp-env '(0 0 .3333 1 4.3603 .6000 9.3939 .3 24.4950 .1 100.0 0)) (vln_one_sin 244.9020 .2250 550 .1875 :fm-index .4 :distance 1 :reverb-amount .0010 :amp-env '(0 0 1.3333 1 5.3199 .6000 10.3030 .3 25.2525 .1 100 0)) (vln_one_sin 244.9020 .4500 586.6670 .3750 :fm-index .4 :distance 1 :reverb-amount .0015 :amp-env '(0 0 .6667 1 4.6801 .6000 9.6970 .3 24.7475 .1 100 0)) (vln_one_sin 244.9430 .9000 366.6670 .1875 :fm-index .6000 :distance 1 :reverb-amount .0016 :amp-env '(0 0 .3333 1 4.3603 .6000 9.3939 .3 24.4950 .1 100.0 0)) (vln_one_sin 244.9430 .2250 275 .1875 :fm-index .6000 :distance 1 :reverb-amount .0015 :amp-env '(0 0 1.3333 1 5.3199 .6000 10.3030 .3 25.2525 .1 100 0)) (vln_one_sin 244.9430 .4500 293.3340 .3750 :fm-index .6000 :distance 1 :reverb-amount .0015 :amp-env '(0 0 .6667 1 4.6801 .6000 9.6970 .3 24.7475 .1 100 0)) (vln_one_sin 244.9850 .9000 733.3330 .1875 :fm-index .8000 :distance 1 :reverb-amount .0010 :amp-env '(0 0 .3333 1 4.3603 .6000 9.3939 .3 24.4950 .1 100.0 0)) (vln_one_sin 244.9850 .2250 550 .1875 :fm-index .8000 :distance 1 :reverb-amount .0013 :amp-env '(0 0 1.3333 1 5.3199 .6000 10.3030 .3 25.2525 .1 100 0)))) (main) (exit 0) ;; fmviolin.scm ends here snd-16.1/snd-mix.c0000644000076400007640000031704412603035272012067 0ustar bilbil#include "snd.h" static bool mix_vct_untagged(vct *v, chan_info *cp, mus_long_t beg, const char *origin) { mus_float_t *data, *vdata; int i, len; snd_fd *sf; bool result = false; len = mus_vct_length(v); vdata = mus_vct_data(v); data = (mus_float_t *)calloc(len, sizeof(mus_float_t)); /* don't add into v->data! */ sf = init_sample_read(beg, cp, READ_FORWARD); samples_to_vct_with_reader(len, data, sf); for (i = 0; i < len; i++) data[i] += vdata[i]; sf = free_snd_fd(sf); result = change_samples(beg, len, data, cp, origin, cp->edit_ctr, -1.0); /* cp->edit_ctr since mix-vct has no edpos arg, similarly mix */ if (result) update_graph(cp); free(data); return(result); } static bool mix_file_untagged(const char *filename, int in_chan, chan_info *cp, mus_long_t beg, mus_long_t num, file_delete_t auto_delete, const char *origin) { file_info *ihdr, *ohdr; char *ofile; int ofd, ifd = -1; io_error_t io_err = IO_NO_ERROR; snd_fd *sf = NULL; mus_long_t i, j, size, in_chans; int err = 0; mus_float_t **data; mus_float_t *chandata; if ((num <= 0) || (!is_editable(cp))) return(false); ihdr = make_file_info(filename, FILE_READ_ONLY, FILE_NOT_SELECTED); if (!ihdr) return(false); if (in_chan >= ihdr->chans) { free_file_info(ihdr); return(false); } ofile = snd_tempnam(); ohdr = make_temp_header(ofile, snd_srate(cp->sound), 1, 0, (char *)origin); ofd = open_temp_file(ofile, 1, ohdr, &io_err); if (ofd == -1) { free_file_info(ihdr); free_file_info(ohdr); snd_error("%s mix temp file %s: %s", (io_err != IO_NO_ERROR) ? io_error_name(io_err) : "can't open", ofile, snd_open_strerror()); return(false); } if ((disk_has_space(num * mus_bytes_per_sample(ohdr->sample_type), ofile)) != DISK_SPACE_OK) return(false); sf = init_sample_read(beg, cp, READ_FORWARD); if (sf) ifd = snd_open_read(filename); if ((!sf) || (ifd < 0)) { if (sf) free_snd_fd(sf); free_file_info(ihdr); free_file_info(ohdr); mus_file_close(ofd); snd_remove(ofile, REMOVE_FROM_CACHE); free(ofile); return(false); } if (beg < 0) beg = 0; in_chans = ihdr->chans; snd_file_open_descriptors(ifd, filename, ihdr->sample_type, ihdr->data_location, ihdr->chans, ihdr->type); during_open(ifd, filename, SND_MIX_FILE); if (num < MAX_BUFFER_SIZE) size = num; else size = MAX_BUFFER_SIZE; data = (mus_float_t **)calloc(in_chans, sizeof(mus_float_t *)); data[in_chan] = (mus_float_t *)calloc(size, sizeof(mus_float_t)); chandata = data[in_chan]; sampler_set_safe(sf, num); lseek(ofd, ohdr->data_location, SEEK_SET); lseek(ifd, ihdr->data_location, SEEK_SET); mus_file_read_chans(ifd, 0, size, in_chans, data, data); for (i = 0, j = 0; i < num; i++) { if (j == size) { err = mus_file_write(ofd, 0, size - 1, 1, &chandata); mus_file_read_chans(ifd, i, size, in_chans, data, data); j = 0; if (err != MUS_NO_ERROR) break; } chandata[j] += read_sample(sf); j++; } if (j > 0) mus_file_write(ofd, 0, j - 1, 1, &chandata); close_temp_file(ofile, ofd, ohdr->type, num * mus_bytes_per_sample(ohdr->sample_type)); mus_file_close(ifd); sf = free_snd_fd(sf); free(data[in_chan]); free(data); free_file_info(ihdr); free_file_info(ohdr); file_change_samples(beg, num, ofile, cp, 0, DELETE_ME, origin, cp->edit_ctr); if (ofile) free(ofile); if (auto_delete == DELETE_ME) snd_remove(filename, REMOVE_FROM_CACHE); update_graph(cp); return(true); } int mix_complete_file_at_cursor(snd_info *sp, const char *filename) { if ((sp) && (filename) && (*filename)) { chan_info *cp; int err = 0; char *fullname; fullname = mus_expand_filename(filename); cp = any_selected_channel(sp); err = mix_complete_file(sp, cursor_sample(cp), fullname, with_mix_tags(ss), DONT_DELETE_ME, MIX_FOLLOWS_SYNC, NULL); if (err == MIX_FILE_NO_FILE) snd_error("can't mix file: %s, %s", filename, snd_io_strerror()); else { if (err == MIX_FILE_NO_MIX) snd_error("no data to mix in %s", filename); } if (fullname) free(fullname); return(err); } return(MIX_FILE_NO_SP); } void drag_and_drop_mix_at_x_y(int data, const char *filename, int x, int y) { int chn, snd; chn = unpack_channel(data); snd = unpack_sound(data); if ((snd >= 0) && (snd < ss->max_sounds) && (snd_ok(ss->sounds[snd])) && (chn >= 0) && (chn < ss->sounds[snd]->nchans) && (mus_file_probe(filename))) { snd_info *sp = NULL; chan_info *cp; mus_long_t sample; char *fullname = NULL; sp = ss->sounds[snd]; cp = sp->chans[chn]; if ((sp->nchans > 1) && (sp->channel_style == CHANNELS_COMBINED)) { cp = which_channel(sp, y); chn = cp->chan; } select_channel(sp, chn); sample = snd_round_mus_long_t(ungrf_x(cp->axis, x) * (double)(snd_srate(sp))); if (sample < 0) sample = 0; fullname = mus_expand_filename(filename); mix_complete_file(sp, sample, fullname, with_mix_tags(ss), DONT_DELETE_ME, MIX_FOLLOWS_SYNC, NULL); if (fullname) free(fullname); } } int mix_complete_file(snd_info *sp, mus_long_t beg, const char *fullname, bool with_tag, file_delete_t auto_delete, mix_sync_t all_chans, int *out_chans) { chan_info *cp; chan_info **cps = NULL; int chans, id = MIX_FILE_NO_MIX, old_sync; mus_long_t len; sync_info *si = NULL; len = mus_sound_framples(fullname); if (len < 0) return(MIX_FILE_NO_FILE); if (len == 0) return(MIX_FILE_NO_MIX); cp = any_selected_channel(sp); old_sync = sp->sync; if ((old_sync == 0) && (all_chans == MIX_SETS_SYNC_LOCALLY)) { sp->sync = ss->sound_sync_max + 1; ss->sound_sync_max++; } if (sp->sync != 0) { si = snd_sync(sp->sync); cps = si->cps; chans = si->chans; } else { cps = (chan_info **)calloc(1, sizeof(chan_info *)); cps[0] = cp; chans = 1; } if (out_chans) (*out_chans) = chans; id = mix_file(beg, len, chans, cps, fullname, auto_delete, NULL, with_tag, 0); if (si) si = free_sync_info(si); else { if (cps) free(cps); } sp->sync = old_sync; return(id); } static const char *b2s(bool val) { return((val) ? PROC_TRUE : PROC_FALSE); /* cast needed by g++ > 3.4 */ } static int mix_infos_ctr = 0; static char *tagged_mix_to_string(const char *mixinfile, mus_long_t beg, int file_channel, bool delete_file) { #if HAVE_FORTH return(mus_format("\"%s\" %lld %d snd chn %s %s %s to -mix-%d", mixinfile, beg, file_channel, b2s(true), b2s(delete_file), S_mix, mix_infos_ctr)); #endif #if HAVE_SCHEME return(mus_format("(set! -mix-%d (%s \"%s\" %lld %d snd chn %s %s))", mix_infos_ctr, S_mix, mixinfile, beg, file_channel, b2s(true), b2s(delete_file))); #endif #if HAVE_RUBY return(mus_format("_mix_%d = %s(\"%s\", %lld, %d, snd, chn, %s, %s)", mix_infos_ctr, to_proc_name(S_mix), mixinfile, beg, file_channel, b2s(true), b2s(delete_file))); #endif #if (!HAVE_EXTENSION_LANGUAGE) return(NULL); #endif } static char *untagged_mix_to_string(const char *mixinfile, mus_long_t beg, int file_channel, bool delete_file) { #if HAVE_FORTH return(mus_format("\"%s\" %lld %d snd chn %s %s %s", mixinfile, beg, file_channel, b2s(false), b2s(delete_file), S_mix)); #endif #if HAVE_SCHEME return(mus_format("(%s \"%s\" %lld %d snd chn %s %s)", S_mix, mixinfile, beg, file_channel, b2s(false), b2s(delete_file))); #endif #if HAVE_RUBY return(mus_format("%s(\"%s\", %lld, %d, snd, chn, %s, %s)", to_proc_name(S_mix), mixinfile, beg, file_channel, b2s(false), b2s(delete_file))); #endif #if (!HAVE_EXTENSION_LANGUAGE) return(NULL); #endif } int mix_file(mus_long_t beg, mus_long_t num, int chans, chan_info **cps, const char *mixinfile, file_delete_t temp, const char *origin, bool with_tag, int start_chan) { /* used in mix_selection and paste(mix)_region, and in mix_complete_file */ int i, id = MIX_FILE_NO_MIX, in_chans; char *new_origin = NULL; in_chans = mus_sound_chans(mixinfile); if (chans > in_chans) chans = in_chans; if (temp == MULTICHANNEL_DELETION) remember_temp(mixinfile, in_chans); for (i = 0; i < chans; i++) { chan_info *cp; cp = cps[i]; if ((!with_tag) || (!virtual_mix_ok(cp, cp->edit_ctr))) { /* not a virtual mix */ if (!origin) new_origin = untagged_mix_to_string(mixinfile, beg, start_chan + i, temp != DONT_DELETE_ME); else new_origin = mus_strdup(origin); mix_file_untagged(mixinfile, i + start_chan, cp, beg, num, temp, new_origin); } else { /* virtual mix */ int cur_id; if (!origin) new_origin = tagged_mix_to_string(mixinfile, beg, start_chan + i, temp != DONT_DELETE_ME); else new_origin = mus_strdup(origin); cur_id = mix_file_with_tag(cp, mixinfile, i + start_chan, beg, temp, new_origin); if (id == MIX_FILE_NO_MIX) id = cur_id; } if (new_origin) { free(new_origin); new_origin = NULL; } } for (i = 0; i < chans; i++) update_graph(cps[i]); return(id); } static mix_state *free_mix_state(mix_state *ms) { if (ms) { if (ms->amp_env) ms->amp_env = free_env(ms->amp_env); free(ms); } return(NULL); } static mix_state *make_mix_state(int id, int index, mus_long_t beg, mus_long_t len) { mix_state *ms; ms = (mix_state *)calloc(1, sizeof(mix_state)); ms->mix_id = id; ms->scaler = 1.0; ms->speed = 1.0; ms->beg = beg; ms->len = len; ms->amp_env = NULL; ms->index = index; return(ms); } mix_state *copy_mix_state(mix_state *old_ms) { mix_state *ms; ms = (mix_state *)calloc(1, sizeof(mix_state)); ms->mix_id = old_ms->mix_id; ms->scaler = old_ms->scaler; ms->speed = old_ms->speed; ms->beg = old_ms->beg; ms->len = old_ms->len; ms->index = old_ms->index; ms->amp_env = copy_env(old_ms->amp_env); /* this is the amp env (not the peak env) */ return(ms); } /* this is the edit list header for the list of mix states: ed_list->mixes (void* in snd-1.h) */ typedef struct { int size; mix_state **list; } mix_list; void free_ed_mixes(void *ptr) { if (ptr) { int i; mix_list *mxl = (mix_list *)ptr; for (i = 0; i < mxl->size; i++) if (mxl->list[i]) mxl->list[i] = free_mix_state(mxl->list[i]); free(mxl->list); free(mxl); } } void add_ed_mix(ed_list *ed, mix_state *ms) { mix_list *mxl; int loc = -1; if (!(ed->mixes)) { ed->mixes = (mix_list *)calloc(1, sizeof(mix_list)); mxl = (mix_list *)(ed->mixes); mxl->size = 2; mxl->list = (mix_state **)calloc(mxl->size, sizeof(mix_state *)); loc = 0; } else { int i; mxl = (mix_list *)(ed->mixes); for (i = 0; i < mxl->size; i++) if (mxl->list[i] == NULL) { loc = i; break; } if (loc == -1) { loc = mxl->size; mxl->size *= 2; mxl->list = (mix_state **)realloc(mxl->list, mxl->size * sizeof(mix_state *)); for (i = loc; i < mxl->size; i++) mxl->list[i] = NULL; } } mxl->list[loc] = ms; } void preload_mixes(mix_state **mixes, int low_id, ed_list *ed) { mix_list *mxl; mxl = (mix_list *)(ed->mixes); if (mxl) { int i; for (i = 0; i < mxl->size; i++) if (mxl->list[i]) mixes[mxl->list[i]->mix_id - low_id] = mxl->list[i]; } } static mix_state *ed_mix_state(ed_list *ed, int mix_id) { mix_list *mxl; mxl = (mix_list *)(ed->mixes); if (mxl) { int i; for (i = 0; i < mxl->size; i++) if ((mxl->list[i]) && (mxl->list[i]->mix_id == mix_id)) return(mxl->list[i]); } return(NULL); } /* these are the nominally unchanging fields in a mix (they don't follow the edit lists) */ #define MIX_TAG_ERASED -1 #define ORIGINAL_SYNC_UNSET -1 typedef struct { int id; char *name; chan_info *cp; int original_index; /* index into cp->sounds array for original mix data */ char *in_filename; mus_long_t in_samps; int in_chan; int tag_x, tag_y; int sync, original_sync; file_delete_t temporary; /* in-filename was written by us and needs to be deleted when mix state is deleted */ peak_env_info *peak_env; Xen properties; int properties_gc_loc; color_t color, original_color; int x, y; /* these are needed to know where to erase while dragging the tag */ } mix_info; static mix_state *current_mix_state(mix_info *md) { if (md) return(ed_mix_state(md->cp->edits[md->cp->edit_ctr], md->id)); return(NULL); } #if 0 /* if edpos args to various mix field (getters anyway), mix? mixes make-mix-sampler... */ static mix_state *mix_state_at_edpos(mix_info *md, int edpos) { if (md) { if (edpos == AT_CURRENT_EDIT_POSITION) return(current_mix_state(md)); else { chan_info *cp; cp = md->cp; if ((edpos >= 0) && (edpos < cp->edit_size) && (cp->edits[edpos])) return(ed_mix_state(cp->edits[edpos], md->id)); } } return(NULL); } #endif /* for ease of access, all tagged mixes that are still accessible (perhaps via undo from fixed state, etc) * are saved in an array indexed by the mix id. A mix is "ok" if it's still in this array, and "active" * if it's represented in the current edit's mix list. */ #define MIX_INFO_INCREMENT 16 static mix_info **mix_infos = NULL; static int mix_infos_size = 0; bool mix_exists(int n) { return((n >= 0) && (n < mix_infos_size) && (mix_infos[n])); } bool mix_is_active(int n) { return((mix_exists(n)) && (current_mix_state(mix_infos[n]))); } static mix_info *md_from_id(int n) { if (mix_exists(n)) return(mix_infos[n]); return(NULL); } int any_mix_id(void) { int i; for (i = 0; i < mix_infos_ctr; i++) if (mix_is_active(i)) return(i); return(INVALID_MIX_ID); } int next_mix_id(int id) { int i; for (i = id + 1; i < mix_infos_ctr; i++) if (mix_is_active(i)) return(i); return(INVALID_MIX_ID); } int previous_mix_id(int id) { int i, top; top = id - 1; if (top >= mix_infos_ctr) top = mix_infos_ctr - 1; for (i = top; i >= 0; i--) if (mix_is_active(i)) return(i); return(INVALID_MIX_ID); } int lowest_mix_id(void) { int i; for (i = 0; i < mix_infos_ctr; i++) if (mix_infos[i]) return(i); return(INVALID_MIX_ID); } int highest_mix_id(void) { int i; for (i = mix_infos_ctr - 1; i >= 0; i--) if (mix_infos[i]) return(i); return(INVALID_MIX_ID); } static mix_info *free_mix_info(mix_info *md) { if (md) { if (md->name) {free(md->name); md->name = NULL;} mix_infos[md->id] = NULL; if (md->temporary == DELETE_ME) { if (mus_file_probe(md->in_filename)) snd_remove(md->in_filename, REMOVE_FROM_CACHE); } if (md->in_filename) {free(md->in_filename); md->in_filename = NULL;} if (md->properties_gc_loc != NOT_A_GC_LOC) { snd_unprotect_at(md->properties_gc_loc); md->properties_gc_loc = NOT_A_GC_LOC; md->properties = Xen_false; } if (md->peak_env) md->peak_env = free_peak_env_info(md->peak_env); free(md); } return(NULL); } void free_channel_mixes(chan_info *cp) { /* called in snd-data.c during chan_info cleanup */ int i; for (i = 0; i < mix_infos_ctr; i++) { mix_info *md; md = mix_infos[i]; if ((md) && (md->cp == cp)) mix_infos[i] = free_mix_info(md); } } void reset_mix_ctr(void) { mix_infos_ctr = 0; } const char *mix_name(int id) { if (mix_exists(id)) return(mix_infos[id]->name); return(NULL); } const char *mix_file_name(int id) { if (mix_exists(id)) return(mix_infos[id]->in_filename); return(NULL); } int mix_name_to_id(const char *name) { int i, loc_so_far = -1; chan_info *selected_cp = NULL; selected_cp = selected_channel(); for (i = 0; i < mix_infos_size; i++) if ((mix_infos[i]) && (mus_strcmp(mix_infos[i]->name, name))) { if ((!selected_cp) || (mix_infos[i]->cp == selected_cp)) /* try to find mix in the currently selected channel (possible name collisions) */ return(i); if (loc_so_far == -1) loc_so_far = i; } return(loc_so_far); } static mix_info *make_mix_info(chan_info *cp) { mix_info *md; if (mix_infos == NULL) { mix_infos_size = MIX_INFO_INCREMENT; mix_infos = (mix_info **)calloc(mix_infos_size, sizeof(mix_info *)); } else { if (mix_infos_ctr >= mix_infos_size) { int i; mix_infos_size += MIX_INFO_INCREMENT; mix_infos = (mix_info **)realloc(mix_infos, mix_infos_size * sizeof(mix_info *)); for (i = mix_infos_size - MIX_INFO_INCREMENT; i < mix_infos_size; i++) mix_infos[i] = NULL; } } md = (mix_info *)calloc(1, sizeof(mix_info)); mix_infos[mix_infos_ctr] = md; md->id = mix_infos_ctr++; md->cp = cp; md->temporary = DONT_DELETE_ME; md->color = ss->mix_color; md->original_color = md->color; md->tag_y = 0; md->tag_x = 0; md->name = NULL; md->y = MIX_TAG_ERASED; md->peak_env = NULL; md->properties_gc_loc = NOT_A_GC_LOC; md->properties = Xen_false; md->sync = 0; md->original_sync = ORIGINAL_SYNC_UNSET; return(md); } mix_state *prepare_mix_state_for_channel(chan_info *cp, int mix_loc, mus_long_t beg, mus_long_t len) { mix_info *md; md = make_mix_info(cp); /* make the mix_info data for this virtual mix */ md->original_index = mix_loc; md->in_samps = len; return(make_mix_state(md->id, mix_loc, beg, len)); } static void for_each_channel_mix(chan_info *cp, void (*func)(mix_info *umx)) { int i; for (i = 0; i < mix_infos_ctr; i++) { mix_info *md; md = mix_infos[i]; if ((md) && (md->cp == cp)) (*func)(md); } } static void for_each_syncd_mix(int current_mix_id, void (*func)(mix_info *md, void *data), void *udata) { int sync; sync = mix_sync_from_id(current_mix_id); if (sync != 0) { int i; for (i = 0; i < mix_infos_ctr; i++) if ((i != current_mix_id) && (mix_is_active(i))) { mix_info *md; md = mix_infos[i]; if ((md) && (md->sync == sync)) (*func)(md, udata); } } } bool channel_has_mixes(chan_info *cp) { int i; for (i = 0; i < mix_infos_ctr; i++) { mix_info *md; md = mix_infos[i]; if ((md) && (md->cp == cp)) return(true); } return(false); } bool channel_has_active_mixes(chan_info *cp) { return(cp->edits[cp->edit_ctr]->mixes != NULL); } static void remove_temporary_mix_file(mix_info *md) { if ((md->temporary == DELETE_ME) && (mus_file_probe(md->in_filename))) snd_remove(md->in_filename, REMOVE_FROM_CACHE); } void delete_any_remaining_mix_temp_files_at_exit(chan_info *cp) { for_each_channel_mix(cp, remove_temporary_mix_file); } static int compare_mix_positions(const void *umx1, const void *umx2) { mus_long_t mx1, mx2; mx1 = (*((mus_long_t *)umx1)); mx2 = (*((mus_long_t *)umx2)); if (mx1 > mx2) return(1); if (mx1 == mx2) return(0); return(-1); } void goto_mix(chan_info *cp, int count) { /* C-x C-j */ mix_list *mxl; if (!cp) return; mxl = (mix_list *)(cp->edits[cp->edit_ctr]->mixes); /* active mixes in the current edit of this channel */ if (mxl) { int i, k = 0; for (i = 0; i < mxl->size; i++) if (mxl->list[i]) k++; if (k > 0) { int j = 0; mus_long_t *begs; begs = (mus_long_t *)calloc(k, sizeof(mus_long_t)); for (i = 0; i < mxl->size; i++) if (mxl->list[i]) begs[j++] = mxl->list[i]->beg; if (k == 1) cursor_moveto(cp, begs[0]); else { qsort((void *)begs, j, sizeof(mus_long_t), compare_mix_positions); /* now find where we are via cursor_sample(cp) and go forward or back as per count */ if (count > 0) { for (i = 0; i < j; i++) if (begs[i] > cursor_sample(cp)) { count--; if (count == 0) { cursor_moveto(cp, begs[i]); break; } } if ((count > 0) && (cursor_sample(cp) < begs[j - 1])) cursor_moveto(cp, begs[j - 1]); } else { for (i = j - 1; i >= 0; i--) if (begs[i] < cursor_sample(cp)) { count++; if (count == 0) { cursor_moveto(cp, begs[i]); break; } } if ((count < 0) && (cursor_sample(cp) > begs[0])) cursor_moveto(cp, begs[0]); } } free(begs); } } } mus_long_t zoom_focus_mix_in_channel_to_position(chan_info *cp) { mix_list *mxl; mxl = (mix_list *)(cp->edits[cp->edit_ctr]->mixes); if (mxl) { mus_long_t lo, hi; int i; lo = cp->axis->losamp; hi = cp->axis->hisamp; for (i = 0; i < mxl->size; i++) { mix_state *ms; ms = mxl->list[i]; if ((ms) && (ms->beg >= lo) && (ms->beg <= hi)) return(ms->beg); } } return(-1); } /* follow edit list */ mus_long_t mix_position_from_id(int id) { mix_state *ms; ms = current_mix_state(md_from_id(id)); if (ms) return(ms->beg); return(0); } mus_long_t mix_length_from_id(int id) { mix_state *ms; ms = current_mix_state(md_from_id(id)); if (ms) return(ms->len); return(0); } mus_float_t mix_amp_from_id(int id) { mix_state *ms; ms = current_mix_state(md_from_id(id)); if (ms) return(ms->scaler); return(0.0); } mus_float_t mix_speed_from_id(int id) { mix_state *ms; ms = current_mix_state(md_from_id(id)); if (ms) return(ms->speed); return(0.0); } env *mix_amp_env_from_id(int id) { mix_state *ms; ms = current_mix_state(md_from_id(id)); if (ms) return(ms->amp_env); return(NULL); } /* stable (not in edit list) */ int mix_sync_from_id(int id) { mix_info *md; md = md_from_id(id); if (md) return(md->sync); return(0); } static int current_mix_sync_max = 0; int mix_set_sync_from_id(int id, int new_sync) { mix_info *md; md = md_from_id(id); if (md) { if (new_sync == GET_NEW_SYNC) { new_sync = current_mix_sync_max + 1; md->original_sync = new_sync; } else { if (new_sync == GET_ORIGINAL_SYNC) { if (md->original_sync == ORIGINAL_SYNC_UNSET) new_sync = current_mix_sync_max + 1; else new_sync = md->original_sync; } else { if (new_sync != 0) md->original_sync = new_sync; } } md->sync = new_sync; if (new_sync > current_mix_sync_max) current_mix_sync_max = new_sync; return(md->sync); } return(0); } static const char *mix_name_from_id(int id) { mix_info *md; md = md_from_id(id); if (md) return(md->name); return(NULL); } static const char *mix_set_name_from_id(int id, const char *new_name) { mix_info *md; md = md_from_id(id); if (md) { if (md->name) free(md->name); md->name = mus_strdup(new_name); return(new_name); } return(NULL); } chan_info *mix_chan_info_from_id(int id) { mix_info *md; md = md_from_id(id); if (md) return(md->cp); return(NULL); } static int mix_tag_y_from_id(int id) { mix_info *md; md = md_from_id(id); if (md) return(md->tag_y); return(0); } color_t mix_color_from_id(int mix_id) { mix_info *md; md = md_from_id(mix_id); if (md) return(md->color); return(ss->mix_color); } color_t mix_set_color_from_id(int id, color_t new_color) { mix_info *md; md = md_from_id(id); if (md) md->color = new_color; return(new_color); } void mix_unset_color_from_id(int id) { mix_info *md; md = md_from_id(id); if (md) md->color = md->original_color; } static void syncd_mix_unset_color_1(mix_info *md, void *ignore) { md->color = md->original_color; } void syncd_mix_unset_color(int id) { for_each_syncd_mix(id, syncd_mix_unset_color_1, NULL); } static void syncd_mix_set_color_1(mix_info *md, void *ignore) { /* assume red (this is from the mix dialog) */ md->color = ss->red; } void syncd_mix_set_color(int id, color_t col) { for_each_syncd_mix(id, syncd_mix_set_color_1, NULL); } bool mix_set_amp_edit(int id, mus_float_t amp) { mix_info *md; bool edited = false; mix_state *old_ms = NULL; md = md_from_id(id); if (md) old_ms = current_mix_state(md); /* needed for edit bounds and existence check */ if (old_ms) { if (old_ms->scaler != amp) { char *origin = NULL; #if HAVE_FORTH origin = mus_format("-mix-%d %.4f set-mix-amp", id, amp); #endif #if HAVE_SCHEME origin = mus_format("(set! (mix-amp -mix-%d) %.4f)", id, amp); #endif #if HAVE_RUBY origin = mus_format("set_mix_amp(_mix_%d, %.4f)", id, amp); #endif edited = begin_mix_op(md->cp, old_ms->beg, old_ms->len, old_ms->beg, old_ms->len, md->cp->edit_ctr, origin); free(origin); if (edited) { mix_state *ms; ms = current_mix_state(md); /* this is the new copy reflecting this edit */ ms->scaler = amp; end_mix_op(md->cp, 0, 0); } } } return(edited); } typedef struct {mus_float_t amp;} syncd_amp_info; static void syncd_mix_set_amp_1(mix_info *md, void *amp) { mus_long_t beg, len; syncd_amp_info *ai = (syncd_amp_info *)amp; mix_set_amp_edit(md->id, ai->amp); beg = mix_position_from_id(md->id); len = mix_length_from_id(md->id); mix_display_during_drag(md->id, beg, beg + len); } void syncd_mix_set_amp(int id, mus_float_t amp) { syncd_amp_info *ai; ai = (syncd_amp_info *)malloc(sizeof(syncd_amp_info)); ai->amp = amp; for_each_syncd_mix(id, syncd_mix_set_amp_1, (void *)ai); free(ai); } static mus_float_t src_input(void *arg, int direction) { return(read_sample((snd_fd *)arg)); } static int remake_mix_data(mix_state *ms, mix_info *md) { chan_info *cp; mus_long_t len; snd_fd *mix_reader; mus_float_t old_amp; mus_any *egen = NULL, *src_gen = NULL; env *e; cp = md->cp; old_amp = ms->scaler; ms->scaler = 1.0; len = snd_round_mus_long_t((double)(md->in_samps) / (double)(ms->speed)); e = ms->amp_env; mix_reader = make_virtual_mix_reader(cp, 0, md->in_samps, md->original_index, 1.0, READ_FORWARD); if (e) egen = mus_make_env(e->data, e->pts, 1.0, 0.0, 1.0, 0.0, len - 1, NULL); if (ms->speed != 1.0) src_gen = mus_make_src(&src_input, ms->speed, sinc_width(ss), (void *)mix_reader); prepare_sound_list(cp); if (cp->sounds[md->original_index]->type == SND_DATA_BUFFER) { int i; mus_float_t *new_buffer; new_buffer = (mus_float_t *)malloc(len * sizeof(mus_float_t)); if (!src_gen) { for (i = 0; i < len; i++) new_buffer[i] = (mus_env(egen) * read_sample(mix_reader)); } else { if (!egen) { for (i = 0; i < len; i++) new_buffer[i] = (mus_src(src_gen, 0.0, &src_input)); } else { for (i = 0; i < len; i++) new_buffer[i] = (mus_src(src_gen, 0.0, &src_input) * mus_env(egen)); } } cp->sounds[cp->sound_ctr] = make_snd_data_buffer(new_buffer, (int)len, cp->edit_ctr); free(new_buffer); } else { mus_long_t i; file_info *hdr; int fd, err = 0; char *temp_file; io_error_t io_err = IO_NO_ERROR; mus_float_t **data; mus_float_t *new_buffer; int j = 0; temp_file = snd_tempnam(); hdr = make_temp_header(temp_file, snd_srate(cp->sound), 1, len, S_set S_mix_amp_env); fd = open_temp_file(temp_file, 1, hdr, &io_err); data = (mus_float_t **)malloc(sizeof(mus_float_t *)); new_buffer = (mus_float_t *)malloc(MAX_BUFFER_SIZE * sizeof(mus_float_t)); data[0] = new_buffer; if (!src_gen) { for (i = 0; i < len; i++) { new_buffer[j++] = (read_sample(mix_reader) * mus_env(egen)); if (j == MAX_BUFFER_SIZE) { err = mus_file_write(fd, 0, j - 1, 1, data); j = 0; if (err != MUS_NO_ERROR) break; } } } else { if (!egen) { for (i = 0; i < len; i++) { new_buffer[j++] = (mus_src(src_gen, 0.0, &src_input)); if (j == MAX_BUFFER_SIZE) { err = mus_file_write(fd, 0, j - 1, 1, data); j = 0; if (err != MUS_NO_ERROR) break; } } } else { for (i = 0; i < len; i++) { new_buffer[j++] = (mus_src(src_gen, 0.0, &src_input) * mus_env(egen)); if (j == MAX_BUFFER_SIZE) { err = mus_file_write(fd, 0, j - 1, 1, data); j = 0; if (err != MUS_NO_ERROR) break; } } } } if (j > 0) mus_file_write(fd, 0, j - 1, 1, data); close_temp_file(temp_file, fd, hdr->type, len * mus_bytes_per_sample(hdr->sample_type)); free_file_info(hdr); hdr = make_file_info(temp_file, FILE_READ_ONLY, FILE_NOT_SELECTED); fd = snd_open_read(temp_file); snd_file_open_descriptors(fd, temp_file, hdr->sample_type, hdr->data_location, hdr->chans, hdr->type); cp->sounds[cp->sound_ctr] = make_snd_data_file(temp_file, make_file_state(fd, hdr, 0, 0, FILE_BUFFER_SIZE), hdr, DELETE_ME, cp->edit_ctr, 0); free(temp_file); free(new_buffer); free(data); } free_snd_fd(mix_reader); if (egen) mus_free(egen); if (src_gen) mus_free(src_gen); ms->scaler = old_amp; return(cp->sound_ctr); } bool mix_set_amp_env_edit(int id, env *e) { mix_info *md; bool edited = false; mix_state *old_ms = NULL; md = md_from_id(id); if (md) old_ms = current_mix_state(md); /* needed for edit bounds and existence check */ if (old_ms) { if (!(envs_equal(old_ms->amp_env, e))) { chan_info *cp; char *origin = NULL, *envstr; envstr = env_to_string(e); #if HAVE_FORTH origin = mus_format("-mix-%d %s set-mix-amp-env", id, envstr); #endif #if HAVE_SCHEME origin = mus_format("(set! (mix-amp-env -mix-%d) %s)", id, envstr); #endif #if HAVE_RUBY origin = mus_format("set_mix_amp_env(_mix_%d, %s)", id, envstr); #endif free(envstr); cp = md->cp; edited = begin_mix_op(cp, old_ms->beg, old_ms->len, old_ms->beg, old_ms->len, cp->edit_ctr, origin); /* this does not change beg or len */ free(origin); if (edited) { mix_state *ms; ms = current_mix_state(md); /* this is the new copy reflecting this edit */ if (ms->amp_env) free_env(ms->amp_env); ms->amp_env = copy_env(e); /* can't use mus_env (as the reader op) here because we need to run backwards */ if ((e) || (ms->speed != 1.0)) ms->index = remake_mix_data(ms, md); else ms->index = md->original_index; end_mix_op(cp, 0, 0); } } } return(edited); } static void syncd_mix_set_amp_env_1(mix_info *md, void *e) { mus_long_t beg, len; env *amp_env = (env *)e; mix_set_amp_env_edit(md->id, amp_env); beg = mix_position_from_id(md->id); len = mix_length_from_id(md->id); mix_display_during_drag(md->id, beg, beg + len); } void syncd_mix_set_amp_env(int id, env *e) { for_each_syncd_mix(id, syncd_mix_set_amp_env_1, (void *)e); } bool mix_set_position_edit(int id, mus_long_t pos) { mix_info *md; bool edited = false; mix_state *old_ms = NULL; if (pos < 0) pos = 0; md = md_from_id(id); if (md) old_ms = current_mix_state(md); if (old_ms) { if (old_ms->beg != pos) { char *origin = NULL; #if HAVE_FORTH origin = mus_format("-mix-%d %lld set-mix-position", id, pos); #endif #if HAVE_SCHEME origin = mus_format("(set! (mix-position -mix-%d) %lld)", id, pos); #endif #if HAVE_RUBY origin = mus_format("set_mix_position(_mix_%d, %lld)", id, pos); #endif edited = begin_mix_op(md->cp, old_ms->beg, old_ms->len, pos, old_ms->len, md->cp->edit_ctr, origin); /* this does not change beg or len */ free(origin); if (edited) { mix_state *ms; ms = current_mix_state(md); /* this is the new copy reflecting this edit */ unmix(md->cp, ms); ms->beg = pos; remix(md->cp, ms); end_mix_op(md->cp, (old_ms->beg != pos) ? old_ms->beg : 0, old_ms->len); } } } return(edited); } bool mix_set_speed_edit(int id, mus_float_t spd) { mix_info *md; bool edited = false; mix_state *old_ms = NULL; md = md_from_id(id); if (md) old_ms = current_mix_state(md); /* needed for edit bounds and existence check */ if (old_ms) { if (old_ms->speed != spd) { chan_info *cp; mus_long_t len; char *origin = NULL; #if HAVE_FORTH origin = mus_format("-mix-%d %.4f set-mix-speed", id, spd); #endif #if HAVE_SCHEME origin = mus_format("(set! (mix-speed -mix-%d) %.4f)", id, spd); #endif #if HAVE_RUBY origin = mus_format("set_mix_speed(_mix_%d, %.4f)", id, spd); #endif cp = md->cp; len = snd_round_mus_long_t((double)(md->in_samps) / (double)spd); edited = begin_mix_op(cp, old_ms->beg, old_ms->len, old_ms->beg, len, cp->edit_ctr, origin); free(origin); if (edited) { mix_state *ms; ms = current_mix_state(md); /* this is the new copy reflecting this edit */ unmix(cp, ms); /* but unmix before changing mix length! */ ms->speed = spd; ms->len = len; if ((ms->speed != 1.0) || (ms->amp_env)) ms->index = remake_mix_data(ms, md); else ms->index = md->original_index; remix(cp, ms); end_mix_op(cp, 0, 0); /* old_ms->beg, old_ms->len); */ } } } return(edited); } typedef struct {mus_float_t speed;} syncd_speed_info; static void syncd_mix_set_speed_1(mix_info *md, void *speed) { mus_long_t beg, len; syncd_speed_info *ai = (syncd_speed_info *)speed; mix_set_speed_edit(md->id, ai->speed); beg = mix_position_from_id(md->id); len = mix_length_from_id(md->id); mix_display_during_drag(md->id, beg, beg + len); } void syncd_mix_set_speed(int id, mus_float_t speed) { syncd_speed_info *ai; ai = (syncd_speed_info *)malloc(sizeof(syncd_speed_info)); ai->speed = speed; for_each_syncd_mix(id, syncd_mix_set_speed_1, (void *)ai); free(ai); } /* mix-samples/set-mix-samples? * combine mix_set_amp_env_edit with remake_mix_data accepting either vct or filename * one problem is how to handle md->peak_env: currently I think it is based on the original * and src stretches/mix-env uses env-on-env, so it's never remade. */ /* edit-list->function support for mixes: * mix list search for current channel, make outer let holding all names as (-mix-### ###) * origins for make-mix procs: (set! -mix-### (...)) * origins otherwise, reference to mix: -mix-### */ char *edit_list_mix_init(chan_info *cp) { char *new_list = NULL; mix_list *mxl; mxl = (mix_list *)(cp->edits[cp->edit_ctr]->mixes); if (mxl) { int i; for (i = 0; i < mxl->size; i++) if (mxl->list[i]) { char *old_list; int id; id = mxl->list[i]->mix_id; old_list = new_list; #if HAVE_SCHEME new_list = mus_format("%s%s(-mix-%d #f)", (old_list) ? old_list : "", (old_list) ? " " : "", /* strcat of previous + possible space */ id); #endif #if HAVE_RUBY new_list = mus_format("%s%s_mix_%d = false", (old_list) ? old_list : "", (old_list) ? "; " : "", /* strcat of previous + possible space */ id); #endif #if HAVE_FORTH new_list = mus_format("%s%s#f { -mix-%d }", (old_list) ? old_list : "", (old_list) ? " " : "", /* strcat of previous + possible space */ id); #endif if (old_list) free(old_list); } } return(new_list); } #define MIX_TAG_Y_OFFSET mix_tag_height(ss) int hit_mix(chan_info *cp, int x, int y) /* mix tag press in snd-chn.c */ { #define SLOPPY_MOUSE 3 mix_list *mxl; mxl = (mix_list *)(cp->edits[cp->edit_ctr]->mixes); /* active mixes in the current edit of this channel */ if (mxl) { int i, width, height; width = mix_tag_width(ss); height = mix_tag_height(ss); for (i = 0; i < mxl->size; i++) { mix_state *ms; ms = mxl->list[i]; if (ms) { int mx, my; mx = mix_infos[ms->mix_id]->tag_x; if (mx <= 0) mx = grf_x((double)(ms->beg) / (double)(snd_srate(cp->sound)), cp->axis); my = mix_infos[ms->mix_id]->tag_y + MIX_TAG_Y_OFFSET + cp->axis->y_offset; if ((x + SLOPPY_MOUSE >= (mx - width / 2)) && (x - SLOPPY_MOUSE <= (mx + width / 2)) && (y + SLOPPY_MOUSE >= (my - height)) && (y - SLOPPY_MOUSE <= (my + 0))) return(ms->mix_id); } } } return(NO_MIX_TAG); } #if USE_MOTIF #define STRING_Y_OFFSET 3 #define STRING_HEIGHT 12 #else #define STRING_Y_OFFSET -8 #define STRING_HEIGHT 12 #endif #define HIT_SLOP 4 int hit_mix_triangle(chan_info *cp, int x, int y) { mix_list *mxl; mxl = (mix_list *)(cp->edits[cp->edit_ctr]->mixes); /* active mixes in the current edit of this channel */ if (mxl) { int i; for (i = 0; i < mxl->size; i++) { mix_state *ms; ms = mxl->list[i]; if (ms) { int mx, my; mx = mix_infos[ms->mix_id]->tag_x; if (mx <= 0) mx = grf_x((double)(ms->beg) / (double)(snd_srate(cp->sound)), cp->axis); my = mix_infos[ms->mix_id]->tag_y + MIX_TAG_Y_OFFSET + STRING_HEIGHT + cp->axis->y_offset; if ((mx < (x + HIT_SLOP)) && ((mx + play_arrow_size(ss) + HIT_SLOP) >= x) && ((y + HIT_SLOP) > my) && (y < (my + 2 * play_arrow_size(ss) + HIT_SLOP))) return(ms->mix_id); } } } return(NO_MIX_TAG); } /* mix display */ void channel_set_mix_tags_erased(chan_info *cp) { mix_list *mxl; mxl = (mix_list *)(cp->edits[cp->edit_ctr]->mixes); if (mxl) { int i; for (i = 0; i < mxl->size; i++) if (mxl->list[i]) { mix_info *md; md = mix_infos[mxl->list[i]->mix_id]; md->y = MIX_TAG_ERASED; } } } static Xen draw_mix_hook; static void draw_mix_tag(mix_info *md, int x, int y) { chan_info *cp; int width, height; graphics_context *ax; char *lab = NULL; if (Xen_hook_has_list(draw_mix_hook)) { Xen res; res = run_progn_hook(draw_mix_hook, Xen_list_5(new_xen_mix(md->id), C_int_to_Xen_integer(md->x), C_int_to_Xen_integer(md->y), C_int_to_Xen_integer(x), C_int_to_Xen_integer(y)), S_draw_mix_hook); if (!(Xen_is_false(res))) { md->x = x; md->y = y; if (Xen_is_list(res)) { md->tag_x = Xen_integer_to_C_int(Xen_car(res)); md->tag_y = Xen_integer_to_C_int(Xen_cadr(res)); } return; } } cp = md->cp; /* draw the mix tag */ width = mix_tag_width(ss); height = mix_tag_height(ss); if (md->y != MIX_TAG_ERASED) { /* erase old tag and name */ ax = erase_context(cp); fill_rectangle(ax, md->x - width / 2 - 1, md->y - height - 1, width + 2, height + STRING_HEIGHT); md->y = MIX_TAG_ERASED; } md->x = x; md->y = y; /* redraw the mix id */ ax = copy_context(cp); set_tiny_numbers_font(cp, ax); if (cp->printing) ps_set_tiny_numbers_font(); if (md->name) lab = mus_strdup(md->name); else { lab = (char *)calloc(16, sizeof(char)); snprintf(lab, 16, "%d", md->id); } draw_string(ax, x - width / 2, y - height / 2 + STRING_Y_OFFSET, lab, strlen(lab)); if (cp->printing) ps_draw_string(cp->axis, x - width / 2, y - height / 2 + STRING_Y_OFFSET, lab); if (lab) {free(lab); lab = NULL;} ax = mix_waveform_context(cp); set_foreground_color(ax, md->color); fill_rectangle(ax, x - width / 2, y - height + STRING_HEIGHT, width, height); /* now draw the play triangle below the tag */ y += (height - 4); fill_polygon(ax, 4, x, y, x + play_arrow_size(ss), y + play_arrow_size(ss), x, y + 2 * play_arrow_size(ss), x, y); } static int local_grf_x(double val, axis_info *ap) { if (val >= ap->x1) return(ap->x_axis_x1); if (val <= ap->x0) return(ap->x_axis_x0); return((int)(ap->x_base + val * ap->x_scale)); } #define MIX_PEAK_ENV_CUTOFF 20000 static peak_env_info *make_mix_input_peak_env(mix_info *md) { mix_state *ms; ms = current_mix_state(md); if (ms->len >= MIX_PEAK_ENV_CUTOFF) { peak_env_info *ep; snd_fd *sf; int val, sb = 0; mus_long_t n; ep = (peak_env_info *)calloc(1, sizeof(peak_env_info)); val = (int)(log((double)(ms->len))); if (val > 20) val = 20; ep->peak_env_size = snd_int_pow2(val); ep->samps_per_bin = (int)(ceil((double)(ms->len) / (double)(ep->peak_env_size))); ep->data_max = (mus_float_t *)calloc(ep->peak_env_size, sizeof(mus_float_t)); ep->data_min = (mus_float_t *)calloc(ep->peak_env_size, sizeof(mus_float_t)); ep->fmin = MIN_INIT; ep->fmax = MAX_INIT; sf = make_virtual_mix_reader(md->cp, 0, ms->len, ms->index, 1.0, READ_FORWARD); for (n = 0; n < ms->len; n += ep->samps_per_bin) { mus_float_t ymin, ymax, val; int i; val = read_sample(sf); ymin = val; ymax = val; for (i = 1; i < ep->samps_per_bin; i++) { val = read_sample(sf); if (ymin > val) ymin = val; else if (ymax < val) ymax = val; } ep->data_max[sb] = ymax; ep->data_min[sb++] = ymin; if (ymin < ep->fmin) ep->fmin = ymin; if (ymax > ep->fmax) ep->fmax = ymax; } ep->completed = true; free_snd_fd(sf); return(ep); } return(NULL); } static bool mix_input_peak_env_usable(mix_info *md, mus_float_t samples_per_pixel) { if (!(md->peak_env)) md->peak_env = make_mix_input_peak_env(md); return((md->peak_env) && (samples_per_pixel >= (mus_float_t)(md->peak_env->samps_per_bin))); } static peak_env_info *env_on_env(env *e, peak_env_info *peaks) { peak_env_info *ep; ep = copy_peak_env_info(peaks, false); if (ep) { int i; mus_any *me; me = mus_make_env(e->data, e->pts, 1.0, 0.0, e->base, 0.0, ep->peak_env_size - 1, NULL); for (i = 0; i < ep->peak_env_size; i++) { mus_float_t val; val = mus_env(me); if (val >= 0.0) { ep->data_min[i] = ep->data_min[i] * val; ep->data_max[i] = ep->data_max[i] * val; } else { ep->data_min[i] = ep->data_max[i] * val; ep->data_max[i] = ep->data_min[i] * val; } } mus_free(me); } return(ep); } static int prepare_mix_peak_env(mix_info *md, mus_float_t scl, int yoff, mus_long_t newbeg, mus_long_t newend, double srate, axis_info *ap) { int i, j, mix_start; int lastx; double xend, xstart, xstep, mix_samps_per_bin; peak_env_info *ep; env *amp_env; mus_float_t ymin = 0.0, ymax = 0.0; amp_env = mix_amp_env_from_id(md->id); if (!amp_env) ep = md->peak_env; else ep = env_on_env(amp_env, md->peak_env); mix_samps_per_bin = (double)(ep->samps_per_bin) / mix_speed_from_id(md->id); /* mix starts at newbeg, current display starts at lo, mix goes to newend, current display goes to hi, */ if (ap->losamp > newbeg) { mix_start = snd_round((double)(ap->losamp - newbeg) / mix_samps_per_bin); xstart = ap->x0; } else { mix_start = 0; xstart = (double)(newbeg) / srate; } if (ap->hisamp < newend) xend = ap->x1; else xend = (double)(newend) / srate; xstep = mix_samps_per_bin / srate; lastx = local_grf_x(xstart, ap); for (i = mix_start, j = 0; (xstart < xend) && (i < ep->peak_env_size); xstart += xstep, i++) { mus_float_t low, high; int newx; low = ep->data_min[i]; high = ep->data_max[i]; newx = local_grf_x(xstart, ap); if (newx > lastx) /* set lastx's bin (j) from min/max for that output bin */ { set_grf_points(lastx, j++, (int)(yoff - scl * ymin), (int)(yoff - scl * ymax)); if (j >= POINT_BUFFER_SIZE) break; lastx = newx; ymin = low; ymax = high; } else { if (high > ymax) ymax = high; if (low < ymin) ymin = low; } } if (amp_env) free_peak_env_info(ep); return(j); } static int prepare_mix_waveform(mix_info *md, mix_state *ms, axis_info *ap, mus_float_t scl, int yoff, double cur_srate, bool *two_sided) { mus_long_t i, newbeg, newend; int pts = 0; mus_long_t samps; mus_float_t samples_per_pixel; double x; mus_long_t lo, hi; snd_fd *sf = NULL; int x_start, x_end; double start_time; newbeg = ms->beg; newend = newbeg + ms->len; lo = ap->losamp; hi = ap->hisamp; if ((newend <= lo) || (newbeg >= hi)) return(0); if ((ap->y_axis_y0 - ap->y_axis_y1) < scl) return(0); start_time = (double)(ap->losamp) / cur_srate; x_start = ap->x_axis_x0; x_end = ap->x_axis_x1; if (newend > hi) newend = hi; samps = ap->hisamp - ap->losamp + 1; samples_per_pixel = (mus_float_t)((double)(samps - 1) / (mus_float_t)(x_end - x_start)); if ((samples_per_pixel < 1.0) || ((samples_per_pixel < 5.0) && (samps < POINT_BUFFER_SIZE))) { int j; bool widely_spaced; double incr, initial_x; if (newbeg < lo) /* mix starts before current left x0 point */ { sf = make_virtual_mix_reader(md->cp, lo - newbeg, ms->len, ms->index, ms->scaler * scl, READ_FORWARD); newbeg = lo; } else sf = make_virtual_mix_reader(md->cp, 0, ms->len, ms->index, ms->scaler * scl, READ_FORWARD); if (!sf) return(0); if (samples_per_pixel < 1.0) { incr = 1.0 / samples_per_pixel; initial_x = x_start; widely_spaced = true; } else { incr = (double)1.0 /cur_srate; initial_x = start_time; widely_spaced = false; } x = initial_x + (incr * (newbeg - lo)); for (j = 0, i = newbeg; i <= newend; i++, j++, x += incr) { int ina_i; ina_i = (int)(yoff - read_sample(sf)); if (widely_spaced) set_grf_point((int)x, j, ina_i); else set_grf_point(local_grf_x(x, ap), j, ina_i); } free_snd_fd(sf); pts = j; (*two_sided) = false; } else { (*two_sided) = true; if (mix_input_peak_env_usable(md, samples_per_pixel)) pts = prepare_mix_peak_env(md, ms->scaler * scl, yoff, newbeg, newend, (double)cur_srate, ap); else { int xi, j; mus_long_t endi; mus_float_t ymin, ymax, xf; if (newbeg < lo) { sf = make_virtual_mix_reader(md->cp, lo - newbeg, ms->len, ms->index, ms->scaler * scl, READ_FORWARD); newbeg = lo; } else sf = make_virtual_mix_reader(md->cp, 0, ms->len, ms->index, ms->scaler * scl, READ_FORWARD); if (!sf) return(0); j = 0; /* graph point counter */ x = ap->x0; xi = local_grf_x(x, ap); xf = 0.0; /* samples per pixel counter */ ymin = 100.0; ymax = -100.0; if (newend < hi) endi = newend; else endi = hi; for (i = lo; i < newbeg; i++) { xf += 1.0; if (xf > samples_per_pixel) { xi++; xf -= samples_per_pixel; } } for (i = newbeg; i <= endi; i++) { mus_float_t ina; ina = read_sample(sf); if (ina > ymax) ymax = ina; if (ina < ymin) ymin = ina; xf += 1.0; if (xf > samples_per_pixel) { set_grf_points(xi, j, (int)(yoff - ymin), (int)(yoff - ymax)); j++; ymin = 100.0; ymax = -100.0; xi++; xf -= samples_per_pixel; } } pts = j; free_snd_fd(sf); } } return(pts); } int prepare_mix_dialog_waveform(int mix_id, axis_info *ap, bool *two_sided) { mix_info *md; mix_state *ms; mus_float_t scl, x0, x1, y0, y1; mus_long_t old_lo, old_hi; double cur_srate; int pts; md = md_from_id(mix_id); if (!md) return(0); scl = ap->y_axis_y0 - ap->y_axis_y1; old_lo = ap->losamp; old_hi = ap->hisamp; x0 = ap->x0; x1 = ap->x1; y0 = ap->y0; y1 = ap->y1; cur_srate = (double)snd_srate(md->cp->sound); ms = current_mix_state(md); ap->losamp = ms->beg; ap->hisamp = ms->beg + ms->len; ap->x0 = (double)(ap->losamp) / cur_srate; ap->x1 = (double)(ap->hisamp) / cur_srate; ap->y0 = -1.0; ap->y1 = 1.0; init_axis_scales(ap); pts = prepare_mix_waveform(md, ms, ap, scl * .5, (int)(scl * .5), cur_srate, two_sided); ap->x0 = x0; ap->x1 = x1; ap->y0 = y0; ap->y1 = y1; ap->losamp = old_lo; ap->hisamp = old_hi; init_axis_scales(ap); return(pts); } static void erase_mix_tag_and_waveform(mix_state *ms, chan_info *cp, axis_info *ap, graphics_context *ax, int x, int y) { int wave_width, wave_height, old_x; if (ap->hisamp > ap->losamp) wave_width = (int)(ms->len * ((double)(ap->x_axis_x1 - ap->x_axis_x0) / (double)(ap->hisamp - ap->losamp))); else wave_width = 0; wave_height = mix_waveform_height(ss); old_x = x + mix_tag_width(ss) - 2; if ((old_x + wave_width) > ap->x_axis_x1) wave_width = ap->x_axis_x1 - old_x; fill_rectangle(ax, old_x, y - wave_height + 6, wave_width + 2, wave_height + 12); } static void draw_mix_tag_and_waveform(mix_info *md, mix_state *ms, int x) { bool show_wave; int y; chan_info *cp; axis_info *ap; cp = md->cp; ap = cp->axis; show_wave = ((show_mix_waveforms(ss)) && (cp->show_mix_waveforms)); y = ap->y_offset + md->tag_y + MIX_TAG_Y_OFFSET; if (ms->beg >= ap->losamp) draw_mix_tag(md, x, y); if (show_wave) { bool two_sided = false; int pts; pts = prepare_mix_waveform(md, ms, ap, mix_waveform_height(ss), y + STRING_HEIGHT / 2, (double)snd_srate(cp->sound), &two_sided); if (pts > 0) { graphics_context *ax; ax = mix_waveform_context(cp); if (two_sided) draw_both_grf_points(cp->dot_size, ax, pts, cp->time_graph_style); else draw_grf_points(cp->dot_size, ax, pts, ap, ungrf_y(ap, y), cp->time_graph_style); copy_context(cp); } } } static void display_one_mix_with_bounds(mix_state *ms, chan_info *cp, axis_info *ap, mus_long_t beg, mus_long_t end) { if ((ms) && (ms->beg + ms->len > beg) && (ms->beg < end)) { mix_info *md; int x; md = mix_infos[ms->mix_id]; x = grf_x((double)(ms->beg) / (double)snd_srate(cp->sound), ap); if ((x + mix_tag_width(ss)) <= ap->x_axis_x1) /* not cut off on right */ draw_mix_tag_and_waveform(md, ms, x); } } static void display_one_mix(mix_state *ms, chan_info *cp) { display_one_mix_with_bounds(ms, cp, cp->axis, cp->axis->losamp, cp->axis->hisamp); } static void display_channel_mixes_with_bounds(chan_info *cp, mus_long_t beg, mus_long_t end) { /* called in display_channel_data if cp has active mixes * it used to draw the tag and waveform if show_mix_waveforms(ss), but I think the tag should be drawn in any case */ mix_list *mxl; if ((cp->sound->channel_style == CHANNELS_SUPERIMPOSED) || (cp->squelch_update)) return; mxl = (mix_list *)(cp->edits[cp->edit_ctr]->mixes); /* active mixes in the current edit of this channel */ if (mxl) { int i; for (i = 0; i < mxl->size; i++) display_one_mix_with_bounds(mxl->list[i], cp, cp->axis, beg, end); } } void display_channel_mixes(chan_info *cp) { display_channel_mixes_with_bounds(cp, cp->axis->losamp, cp->axis->hisamp); } #define MIX_WAIT_TIME 50 static timeout_result_t watch_mix_proc = 0; static void stop_watch_mix_proc(void) { if (watch_mix_proc != 0) { TIMEOUT_REMOVE(watch_mix_proc); watch_mix_proc = 0; } } static float watch_mix_x_incr = 1.0; #if (!USE_NO_GUI) static TIMEOUT_TYPE watch_mix(TIMEOUT_ARGS) { mix_info *md = (mix_info *)context; if (watch_mix_proc != 0) { watch_mix_x_incr *= 1.1; move_mix_tag(md->id, (int)(md->x + watch_mix_x_incr), md->y); watch_mix_proc = CALL_TIMEOUT(watch_mix, MIX_WAIT_TIME, md); } TIMEOUT_RESULT } #endif static int edpos_before_drag = 0; static with_hook_t hookable_before_drag; static bool mix_dragged = false; static Xen mix_release_hook; static Xen mix_drag_hook; static mus_long_t orig_beg = 0; /* also mix_click_hook in snd-chn.c */ static mus_long_t drag_beg = 0, drag_end = 0; typedef struct {mus_long_t beg; bool axis_changed;} move_mix_data; static mus_long_t syncd_mix_position(int id); static void move_syncd_mix(mix_info *md, void *data) { move_mix_data *mmd = (move_mix_data *)data; mix_set_position_edit(md->id, syncd_mix_position(md->id) + mmd->beg); if (!mmd->axis_changed) mix_display_during_drag(md->id, drag_beg, drag_end); } void move_mix_tag(int mix_id, int x, int y) { /* dragging mix, hit_mix returns id, called only from snd-chn.c and above (watch_mix) */ mix_info *md; mix_state *ms; axis_info *ap; chan_info *cp; bool axis_changed = false; mus_long_t pos; md = md_from_id(mix_id); cp = md->cp; if (!mix_dragged) /* starting to drag -- unmix now while we know the original position */ { edpos_before_drag = cp->edit_ctr; hookable_before_drag = cp->hookable; cp->hookable = WITHOUT_HOOK; drag_beg = mix_position_from_id(mix_id); orig_beg = drag_beg; drag_end = drag_beg + mix_length_from_id(mix_id); start_dragging_syncd_mixes(mix_id); } else { cp->edit_ctr = edpos_before_drag; keep_dragging_syncd_mixes(mix_id); } pos = snd_round_mus_long_t(ungrf_x(cp->axis, x) * (double)(snd_srate(cp->sound))); mix_set_position_edit(mix_id, pos); mix_dragged = true; ap = cp->axis; ms = current_mix_state(md); if ((x > ap->x_axis_x1) || (x < ap->x_axis_x0)) { /* we're outside the graph */ if (watch_mix_proc != 0) { if ((x < ap->x_axis_x0) && (ap->x0 == ap->xmin)) return; if ((x > ap->x_axis_x1) && (ap->x1 == ap->xmax)) return; } else { if (mix_dragged) { if (x < ap->x_axis_x0) watch_mix_x_incr = -1.0; else watch_mix_x_incr = 1.0; watch_mix_proc = CALL_TIMEOUT(watch_mix, MIX_WAIT_TIME, md); } } x = move_axis(cp, x); /* calls update_graph eventually (in snd-chn.c reset_x_display) */ axis_changed = true; } else { if (watch_mix_proc != 0) { stop_watch_mix_proc(); watch_mix_proc = 0; } } reflect_mix_change(mix_id); { move_mix_data *mmd; mmd = (move_mix_data *)malloc(sizeof(move_mix_data)); mmd->beg = pos - orig_beg; mmd->axis_changed = axis_changed; for_each_syncd_mix(mix_id, move_syncd_mix, (void *)mmd); /* syncd mixes drag together */ free(mmd); } if ((axis_changed) || (cp->sound->channel_style == CHANNELS_SUPERIMPOSED)) display_channel_time_data(cp); else { mus_long_t cur_end; cur_end = ms->beg + ms->len; if (cur_end > drag_end) drag_end = cur_end; if (ms->beg < drag_beg) drag_beg = ms->beg; #if USE_MOTIF make_partial_graph(cp, drag_beg, drag_end); display_channel_mixes_with_bounds(cp, drag_beg, drag_end); #else display_channel_data(cp); #endif } if (Xen_hook_has_list(mix_drag_hook)) run_hook(mix_drag_hook, Xen_list_3(new_xen_mix(mix_id), C_int_to_Xen_integer(x), C_int_to_Xen_integer(y)), S_mix_drag_hook); } static void syncd_mix_set_position_1(mix_info *md, void *data) { move_mix_data *mmd = (move_mix_data *)data; mix_set_position_edit(md->id, syncd_mix_position(md->id) + mmd->beg); after_edit(md->cp); update_graph(md->cp); } static void syncd_mix_set_position(int mix_id, mus_long_t pos) { move_mix_data *pos_data; pos_data = (move_mix_data *)malloc(sizeof(move_mix_data)); pos_data->beg = pos; for_each_syncd_mix(mix_id, syncd_mix_set_position_1, pos_data); free(pos_data); } void finish_moving_mix_tag(int mix_id, int x) { /* from mouse release after tag drag in snd-chn.c only */ mix_info *md; mus_long_t pos; Xen res = Xen_false; chan_info *cp; mix_dragged = false; if (watch_mix_proc != 0) { stop_watch_mix_proc(); watch_mix_proc = 0; } md = md_from_id(mix_id); if (!md) return; cp = md->cp; pos = snd_round_mus_long_t(ungrf_x(cp->axis, x) * (double)(snd_srate(cp->sound))); if (pos < 0) pos = 0; cp->hookable = hookable_before_drag; if (cp->edit_ctr > edpos_before_drag) /* possibly dragged it back to start point, so no edit took place */ cp->edit_ctr--; keep_dragging_syncd_mixes(mix_id); /* fixup edpos */ if (Xen_hook_has_list(mix_release_hook)) res = run_progn_hook(mix_release_hook, Xen_list_2(new_xen_mix(mix_id), C_llong_to_Xen_llong(pos - mix_position_from_id(mix_id))), S_mix_release_hook); if (!(Xen_is_true(res))) { mus_long_t old_pos; old_pos = mix_position_from_id(mix_id); if (mix_set_position_edit(mix_id, pos)) { cursor_sample(cp) = pos; after_edit(cp); update_graph(cp); /* this causes flashing, but it's next to impossible to fix * display_channel_id assumes previous id was erased, as does any after_graph_hook function * and we have to run lisp/fft graphs in any case (and the hook), * but display_channel_data_1 erases the old graph, so it's hard to specialize for this case */ syncd_mix_set_position(mix_id, pos - old_pos); /* assumes syncd_mixes list exists */ } } stop_dragging_syncd_mixes(mix_id); } /* View:Mixes dialog display */ void mix_display_during_drag(int mix_id, mus_long_t drag_beg, mus_long_t drag_end) { chan_info *cp; cp = mix_chan_info_from_id(mix_id); if (cp->sound->channel_style == CHANNELS_SUPERIMPOSED) display_channel_time_data(cp); else { #if USE_MOTIF mus_long_t cur_end, ms_beg; ms_beg = mix_position_from_id(mix_id); cur_end = ms_beg + mix_length_from_id(mix_id); if (cur_end > drag_end) drag_end = cur_end; if (ms_beg < drag_beg) drag_beg = ms_beg; make_partial_graph(cp, drag_beg, drag_end); display_channel_mixes_with_bounds(cp, drag_beg, drag_end); #else display_channel_data(cp); #endif } } static Xen snd_no_such_mix_error(const char *caller, Xen n) { Xen_error(Xen_make_error_type("no-such-mix"), Xen_list_3(C_string_to_Xen_string("~A: no such mix, ~A"), C_string_to_Xen_string(caller), n)); return(Xen_false); } void after_mix_edit(int id) { mix_info *md; md = md_from_id(id); if ((md) && (md->cp)) { after_edit(md->cp); update_graph(md->cp); } } /* ---------------------------------------- syncd mixes ---------------------------------------- */ typedef struct { int mix_id, orig_edpos; mus_long_t orig_beg; chan_info *cp; } syncd_mix_info; static syncd_mix_info *syncd_mixes = NULL; static int syncd_mixes_length = 0; static mus_long_t syncd_mix_position(int id) { if (syncd_mixes) { int i; for (i = 0; i < syncd_mixes_length; i++) if (id == syncd_mixes[i].mix_id) return(syncd_mixes[i].orig_beg); } return(-1); } static void add_syncd_mix(mix_info *md, void *ignore) { mus_long_t pos; int i, mix_id; mix_id = md->id; pos = mix_position_from_id(mix_id); i = syncd_mixes_length++; syncd_mixes[i].mix_id = mix_id; syncd_mixes[i].orig_beg = pos; syncd_mixes[i].orig_edpos = md->cp->edit_ctr; syncd_mixes[i].cp = md->cp; } static void count_syncd_mixes(mix_info *md, void *ignore) { syncd_mixes_length++; } void start_dragging_syncd_mixes(int mix_id) { syncd_mixes_length = 0; for_each_syncd_mix(mix_id, count_syncd_mixes, NULL); if (syncd_mixes_length > 0) { syncd_mixes = (syncd_mix_info *)calloc(syncd_mixes_length, sizeof(syncd_mix_info)); syncd_mixes_length = 0; for_each_syncd_mix(mix_id, add_syncd_mix, NULL); } } void keep_dragging_syncd_mixes(int mix_id) { int i; for (i = 0; i < syncd_mixes_length; i++) syncd_mixes[i].cp->edit_ctr = syncd_mixes[i].orig_edpos; } void stop_dragging_syncd_mixes(int mix_id) { /* undo edit? */ if (syncd_mixes) { free(syncd_mixes); syncd_mixes = NULL; syncd_mixes_length = 0; } } static void syncd_mix_change_position_1(mix_info *md, void *data) { move_mix_data *mmd = (move_mix_data *)data; mix_set_position_edit(md->id, mix_position_from_id(md->id) + mmd->beg); if (!mmd->axis_changed) mix_display_during_drag(md->id, drag_beg, drag_end); } void syncd_mix_change_position(int mix_id, mus_long_t change) { move_mix_data *pos_data; pos_data = (move_mix_data *)malloc(sizeof(move_mix_data)); pos_data->beg = change; for_each_syncd_mix(mix_id, syncd_mix_change_position_1, pos_data); free(pos_data); } static int ms_chans = 0; static chan_info **ms_cps = NULL; static void update_syncd_chans(mix_info *md, void *ignore) { int i; for (i = 0; i < ms_chans; i++) if (md->cp == ms_cps[i]) return; ms_cps[ms_chans++] = md->cp; update_graph(md->cp); } void after_syncd_mix_edit(int id) { ms_chans = active_channels(WITH_VIRTUAL_CHANNELS); if (ms_chans > 1) { ms_cps = (chan_info **)calloc(ms_chans, sizeof(chan_info *)); ms_chans = 1; ms_cps[0] = mix_chan_info_from_id(id); /* base cp handled elsewhere */ for_each_syncd_mix(id, update_syncd_chans, NULL); ms_chans = 0; free(ms_cps); ms_cps = NULL; } } /* ---------------------------------------- mix objects ---------------------------------------- */ typedef struct { int n; } xen_mix; /* md->cp->sounds[md->original_index] is the original mix data */ #define Xen_to_xen_mix(arg) ((xen_mix *)Xen_object_ref(arg)) int xen_mix_to_int(Xen n) { xen_mix *mx; mx = Xen_to_xen_mix(n); return(mx->n); } static Xen_object_type_t xen_mix_tag; bool xen_is_mix(Xen obj) { return(Xen_c_object_is_type(obj, xen_mix_tag)); } static void xen_mix_free(xen_mix *v) {if (v) free(v);} Xen_wrap_free(xen_mix, free_xen_mix, xen_mix_free) static char *xen_mix_to_string(xen_mix *v) { #define xen_is_mixRINT_BUFFER_SIZE 64 char *buf; if (v == NULL) return(NULL); buf = (char *)calloc(xen_is_mixRINT_BUFFER_SIZE, sizeof(char)); snprintf(buf, xen_is_mixRINT_BUFFER_SIZE, "#", v->n); return(buf); } Xen_wrap_print(xen_mix, print_xen_mix, xen_mix_to_string) #if HAVE_FORTH || HAVE_RUBY static Xen g_xen_mix_to_string(Xen obj) { char *vstr; Xen result; #define S_xen_mix_to_string "mix->string" Xen_check_type(xen_is_mix(obj), obj, 1, S_xen_mix_to_string, "a mix"); vstr = xen_mix_to_string(Xen_to_xen_mix(obj)); result = C_string_to_Xen_string(vstr); free(vstr); return(result); } #endif #if (!HAVE_SCHEME) static bool xen_mix_equalp(xen_mix *v1, xen_mix *v2) { return((v1 == v2) || (v1->n == v2->n)); } static Xen equalp_xen_mix(Xen obj1, Xen obj2) { if ((!(xen_is_mix(obj1))) || (!(xen_is_mix(obj2)))) return(Xen_false); return(C_bool_to_Xen_boolean(xen_mix_equalp(Xen_to_xen_mix(obj1), Xen_to_xen_mix(obj2)))); } #endif static xen_mix *xen_mix_make(int n) { xen_mix *new_v; new_v = (xen_mix *)malloc(sizeof(xen_mix)); new_v->n = n; return(new_v); } Xen new_xen_mix(int n) { xen_mix *mx; if (n < 0) return(Xen_false); mx = xen_mix_make(n); return(Xen_make_object(xen_mix_tag, mx, 0, free_xen_mix)); } #if HAVE_SCHEME static Xen s7_xen_mix_length(s7_scheme *sc, s7_pointer obj) { return(g_mix_length(obj)); } static bool s7_xen_mix_equalp(void *obj1, void *obj2) { return((obj1 == obj2) || (((xen_mix *)obj1)->n == ((xen_mix *)obj2)->n)); } static Xen s7_xen_mix_copy(s7_scheme *sc, s7_pointer args) { s7_pointer obj; obj = s7_car(args); return(new_xen_mix(copy_mix(Xen_mix_to_C_int(obj)))); } #endif static void init_xen_mix(void) { #if HAVE_SCHEME xen_mix_tag = s7_new_type_x(s7, "", print_xen_mix, free_xen_mix, s7_xen_mix_equalp, NULL, NULL, NULL, s7_xen_mix_length, s7_xen_mix_copy, NULL, NULL); #else #if HAVE_RUBY xen_mix_tag = Xen_make_object_type("XenMix", sizeof(xen_mix)); #else xen_mix_tag = Xen_make_object_type("Mix", sizeof(xen_mix)); #endif #endif #if HAVE_FORTH fth_set_object_inspect(xen_mix_tag, print_xen_mix); fth_set_object_dump(xen_mix_tag, g_xen_mix_to_string); fth_set_object_equal(xen_mix_tag, equalp_xen_mix); fth_set_object_length(xen_mix_tag, g_mix_length); fth_set_object_free(xen_mix_tag, free_xen_mix); #endif #if HAVE_RUBY rb_define_method(xen_mix_tag, "to_s", Xen_procedure_cast print_xen_mix, 0); rb_define_method(xen_mix_tag, "eql?", Xen_procedure_cast equalp_xen_mix, 1); rb_define_method(xen_mix_tag, "==", Xen_procedure_cast equalp_xen_mix, 1); rb_define_method(xen_mix_tag, "length", Xen_procedure_cast g_mix_length, 0); rb_define_method(xen_mix_tag, "to_str", Xen_procedure_cast g_xen_mix_to_string, 0); #endif } /* -------------------------------------------------------------------------------- */ static Xen g_integer_to_mix(Xen n) { #define H_integer_to_mix "(" S_integer_to_mix " n) returns a mix object corresponding to the given integer" Xen_check_type(Xen_is_integer(n), n, 1, S_integer_to_mix, "an integer"); return(new_xen_mix(Xen_integer_to_C_int(n))); } static Xen g_mix_to_integer(Xen n) { #define H_mix_to_integer "(" S_mix_to_integer " id) returns the integer corresponding to the given mix object" Xen_check_type(xen_is_mix(n), n, 1, S_mix_to_integer, "a mix"); return(C_int_to_Xen_integer(xen_mix_to_int(n))); } Xen g_mix_length(Xen n) { #define H_mix_length "(" S_mix_length " id): mix's length in samples" int id; Xen_check_type(xen_is_mix(n), n, 1, S_mix_length, "a mix"); id = Xen_mix_to_C_int(n); if (mix_is_active(id)) return(C_llong_to_Xen_llong(mix_length_from_id(id))); return(snd_no_such_mix_error(S_mix_length, n)); } static Xen g_mix_position(Xen n) { int id; #define H_mix_position "(" S_mix_position " id): mix's begin time in the output in samples" Xen_check_type(xen_is_mix(n), n, 1, S_mix_position, "a mix"); id = Xen_mix_to_C_int(n); if (mix_is_active(id)) return(C_llong_to_Xen_llong(mix_position_from_id(id))); return(snd_no_such_mix_error(S_mix_position, n)); } static Xen g_set_mix_position(Xen n, Xen pos) { int id; mus_long_t beg; Xen_check_type(xen_is_mix(n), n, 1, S_set S_mix_position, "a mix"); Xen_check_type(Xen_is_llong(pos), pos, 2, S_set S_mix_position, "an integer"); id = Xen_mix_to_C_int(n); if (!(mix_is_active(id))) return(snd_no_such_mix_error(S_set S_mix_position, n)); beg = beg_to_sample(pos, S_set S_mix_position); if (mix_set_position_edit(id, beg)) after_mix_edit(id); return(pos); } static Xen g_mix_amp(Xen n) { #define H_mix_amp "(" S_mix_amp " id): mix's scaler" int id; Xen_check_type(xen_is_mix(n), n, 1, S_mix_amp, "a mix"); id = Xen_mix_to_C_int(n); if (mix_is_active(id)) return(C_double_to_Xen_real(mix_amp_from_id(id))); return(snd_no_such_mix_error(S_mix_amp, n)); } static Xen g_set_mix_amp(Xen n, Xen uval) { int id; Xen_check_type(xen_is_mix(n), n, 1, S_set S_mix_amp, "a mix"); Xen_check_type(Xen_is_number(uval), uval, 2, S_set S_mix_amp, "a number"); id = Xen_mix_to_C_int(n); if (!(mix_is_active(id))) return(snd_no_such_mix_error(S_set S_mix_amp, n)); if (mix_set_amp_edit(id, Xen_real_to_C_double(uval))) after_mix_edit(id); return(uval); } static Xen g_mix_amp_env(Xen n) { #define H_mix_amp_env "(" S_mix_amp_env " id): amplitude envelope applied to mix" int id; Xen_check_type(xen_is_mix(n), n, 1, S_mix_amp_env, "a mix"); id = Xen_mix_to_C_int(n); if (mix_is_active(id)) return(env_to_xen(mix_amp_env_from_id(id))); return(snd_no_such_mix_error(S_mix_amp_env, n)); } static Xen g_set_mix_amp_env(Xen n, Xen val) { env *e = NULL; int id; Xen_check_type(xen_is_mix(n), n, 1, S_set S_mix_amp_env, "a mix"); Xen_check_type(Xen_is_list(val) || Xen_is_false(val), val, 2, S_set S_mix_amp_env, "a list or " PROC_FALSE); id = Xen_mix_to_C_int(n); if (!(mix_is_active(id))) return(snd_no_such_mix_error(S_set S_mix_amp_env, n)); if (Xen_is_list(val)) e = get_env(val, S_set S_mix_amp_env); if (mix_set_amp_env_edit(id, e)) after_mix_edit(id); /* e is copied by mix_set_amp_env_edit, and created by get_env (xen_to_env), so it should be freed here */ if (e) free_env(e); return(val); } static Xen g_mix_speed(Xen n) { #define H_mix_speed "(" S_mix_speed " id): mix's resampling ratio" int id; Xen_check_type(xen_is_mix(n), n, 1, S_mix_speed, "a mix"); id = Xen_mix_to_C_int(n); if (mix_is_active(id)) return(C_double_to_Xen_real(mix_speed_from_id(id))); return(snd_no_such_mix_error(S_mix_speed, n)); } static Xen g_set_mix_speed(Xen n, Xen uval) { int id; Xen_check_type(xen_is_mix(n), n, 1, S_set S_mix_speed, "a mix"); Xen_check_type(Xen_is_number(uval), uval, 2, S_set S_mix_speed, "a number"); id = Xen_mix_to_C_int(n); if (!(mix_is_active(id))) return(snd_no_such_mix_error(S_set S_mix_speed, n)); if (mix_set_speed_edit(id, Xen_real_to_C_double(uval))) after_mix_edit(id); return(uval); } static Xen g_mix_name(Xen n) { #define H_mix_name "(" S_mix_name " id): name of mix" int id; Xen_check_type(xen_is_mix(n), n, 1, S_mix_name, "a mix"); id = Xen_mix_to_C_int(n); if (mix_exists(id)) return(C_string_to_Xen_string(mix_name_from_id(id))); return(snd_no_such_mix_error(S_mix_name, n)); } static Xen g_set_mix_name(Xen n, Xen val) { int id; Xen_check_type(xen_is_mix(n), n, 1, S_set S_mix_name, "a mix"); Xen_check_type(Xen_is_string(val) || Xen_is_false(val), val, 2, S_set S_mix_name, "a string"); id = Xen_mix_to_C_int(n); if (mix_exists(id)) { mix_set_name_from_id(id, (Xen_is_string(val) ? Xen_string_to_C_string(val) : NULL)); update_graph(mix_chan_info_from_id(id)); } else return(snd_no_such_mix_error(S_set S_mix_name, n)); return(val); } Xen g_mix_sync(Xen n) { #define H_mix_sync "(" S_mix_sync " id): mix sync field (an integer)" int id; Xen_check_type(xen_is_mix(n), n, 1, S_mix_sync, "a mix"); id = Xen_mix_to_C_int(n); if (mix_exists(id)) return(C_int_to_Xen_integer(mix_sync_from_id(id))); return(snd_no_such_mix_error(S_mix_sync, n)); } Xen g_set_mix_sync(Xen n, Xen val) { int id; Xen_check_type(xen_is_mix(n), n, 1, S_set S_mix_sync, "a mix"); Xen_check_type(Xen_is_integer(val), val, 2, S_set S_mix_sync, "an integer"); id = Xen_mix_to_C_int(n); if (mix_exists(id)) mix_set_sync_from_id(id, Xen_integer_to_C_int(val)); else return(snd_no_such_mix_error(S_set S_mix_sync, n)); return(val); } static Xen g_mix_sync_max(void) { #define H_mix_sync_max "(" S_mix_sync_max "): max mix sync value seen so far" return(C_int_to_Xen_integer(current_mix_sync_max)); } static Xen g_mix_tag_y(Xen n) { #define H_mix_tag_y "(" S_mix_tag_y " id): height of mix's tag" int id; Xen_check_type(xen_is_mix(n), n, 1, S_mix_tag_y, "a mix"); id = Xen_mix_to_C_int(n); if (mix_exists(id)) return(C_int_to_Xen_integer(mix_tag_y_from_id(id))); return(snd_no_such_mix_error(S_mix_tag_y, n)); } static Xen g_set_mix_tag_y(Xen n, Xen val) { int id; Xen_check_type(xen_is_mix(n), n, 1, S_set S_mix_tag_y, "a mix"); Xen_check_type(Xen_is_integer(val), val, 2, S_set S_mix_tag_y, "an integer"); id = Xen_mix_to_C_int(n); if (mix_exists(id)) { chan_info *cp; mix_state *ms; mix_info *md; md = md_from_id(id); ms = current_mix_state(md); cp = md->cp; if ((cp) && (!(cp->squelch_update))) { graphics_context *ax; ax = erase_context(cp); #if USE_GTK ss->cr = make_cairo(ax->wn); #endif erase_mix_tag_and_waveform(ms, cp, cp->axis, ax, md->x, cp->axis->y_offset + md->tag_y + MIX_TAG_Y_OFFSET); md->tag_y = Xen_integer_to_C_int(val); display_one_mix(ms, cp); #if USE_GTK free_cairo(ss->cr); ss->cr = NULL; copy_context(cp); #endif } else md->tag_y = Xen_integer_to_C_int(val); } else return(snd_no_such_mix_error(S_set S_mix_tag_y, n)); return(val); } static Xen g_mix_properties(Xen n) { #define H_mix_properties "(" S_mix_properties " id): A property list associated with the given mix." mix_info *md; Xen_check_type(xen_is_mix(n), n, 1, S_mix_properties, "a mix"); md = md_from_id(Xen_mix_to_C_int(n)); if (md == NULL) return(snd_no_such_mix_error(S_mix_properties, n)); if (!(Xen_is_vector(md->properties))) { md->properties = Xen_make_vector(1, Xen_empty_list); md->properties_gc_loc = snd_protect(md->properties); } return(Xen_vector_ref(md->properties, 0)); } static Xen g_set_mix_properties(Xen n, Xen val) { mix_info *md; Xen_check_type(xen_is_mix(n), n, 1, S_mix_properties, "a mix"); md = md_from_id(Xen_mix_to_C_int(n)); if (md == NULL) return(snd_no_such_mix_error(S_set S_mix_properties, n)); if (!(Xen_is_vector(md->properties))) { md->properties = Xen_make_vector(1, Xen_empty_list); md->properties_gc_loc = snd_protect(md->properties); } Xen_vector_set(md->properties, 0, val); return(Xen_vector_ref(md->properties, 0)); } static Xen g_mix_property(Xen key, Xen id) { #define H_mix_property "(" S_mix_property " key id) returns the value associated with 'key' in the given mix's property list, or " PROC_FALSE "." Xen_check_type(xen_is_mix(id), id, 2, S_mix_property, "a mix"); return(Xen_assoc_ref(key, g_mix_properties(id))); } static Xen g_set_mix_property(Xen key, Xen id, Xen val) { Xen_check_type(xen_is_mix(id), id, 2, S_mix_property, "a mix"); g_set_mix_properties(id, Xen_assoc_set(key, val, g_mix_properties(id))); return(val); } static Xen g_mix_home(Xen n) { #define H_mix_home "(" S_mix_home " id): list of sound index and channel for the output of the mix, and the \ filename or " PROC_FALSE " and the input channel for its data." mix_info *md; Xen_check_type(xen_is_mix(n), n, 1, S_mix_home, "a mix"); md = md_from_id(Xen_mix_to_C_int(n)); if (md == NULL) return(snd_no_such_mix_error(S_mix_home, n)); return(Xen_list_4(C_int_to_Xen_sound((md->cp->sound)->index), C_int_to_Xen_integer((md->cp->chan)), (md->in_filename) ? C_string_to_Xen_string(md->in_filename) : Xen_false, C_int_to_Xen_integer(md->in_chan))); } void color_mixes(color_t color) { int i; set_mix_color(color); for (i = 0; i < mix_infos_ctr; i++) if (mix_infos[i]) { mix_infos[i]->color = color; mix_infos[i]->original_color = color; } } static double mix_maxamp(int mix_id) { mix_info *md; mix_state *ms; snd_fd *sf; mus_long_t n; mus_float_t mx = 0.0; md = md_from_id(mix_id); if (md == NULL) return(0.0); ms = current_mix_state(md); sf = make_virtual_mix_reader(md->cp, 0, ms->len, ms->index, 1.0, READ_FORWARD); for (n = 0; n < ms->len; n++) { mus_float_t val; val = fabs(read_sample(sf)); if (val > mx) mx = val; } free_snd_fd(sf); return(mx); } Xen g_mix_maxamp(Xen mix_id) { return(C_double_to_Xen_real(mix_maxamp(Xen_mix_to_C_int(mix_id)))); } /* mix-related globals */ static void update_mix_waveforms(chan_info *cp) { if ((cp) && (channel_has_active_mixes(cp))) update_graph(cp); } void set_mix_waveform_height(int new_val) { in_set_mix_waveform_height(new_val); for_each_normal_chan(update_mix_waveforms); } static Xen g_mix_waveform_height(void) { #define H_mix_waveform_height "(" S_mix_waveform_height "): max height (pixels) of mix waveforms (20)" return(C_int_to_Xen_integer(mix_waveform_height(ss))); } static Xen g_set_mix_waveform_height(Xen val) { int new_val; Xen_check_type(Xen_is_integer(val), val, 1, S_set S_mix_waveform_height, "an integer"); new_val = mus_iclamp(0, Xen_integer_to_C_int(val), LOTSA_PIXELS); set_mix_waveform_height(new_val); return(C_int_to_Xen_integer(mix_waveform_height(ss))); } static Xen g_with_mix_tags(void) { #define H_with_mix_tags "(" S_with_mix_tags "): " PROC_TRUE " if Snd should try to use virtual (tagged) mixing" return(C_bool_to_Xen_boolean(with_mix_tags(ss))); } static Xen g_set_with_mix_tags(Xen val) { Xen_check_type(Xen_is_boolean(val), val, 1, S_set S_with_mix_tags, "a boolean"); set_with_mix_tags(Xen_boolean_to_C_bool(val)); return(C_bool_to_Xen_boolean(with_mix_tags(ss))); } static Xen g_mix_tag_width(void) { #define H_mix_tag_width "(" S_mix_tag_width "): width (pixels) of mix tags (6)" return(C_int_to_Xen_integer(mix_tag_width(ss))); } static Xen g_set_mix_tag_width(Xen val) { int width; Xen_check_type(Xen_is_integer(val), val, 1, S_set S_mix_tag_width, "an integer"); width = mus_iclamp(0, Xen_integer_to_C_int(val), LOTSA_PIXELS); set_mix_tag_width(width); for_each_normal_chan(update_graph); return(C_int_to_Xen_integer(mix_tag_width(ss))); } static Xen g_mix_tag_height(void) { #define H_mix_tag_height "(" S_mix_tag_height "): height (pixels) of mix tags (14)" return(C_int_to_Xen_integer(mix_tag_height(ss))); } static Xen g_set_mix_tag_height(Xen val) { int height; Xen_check_type(Xen_is_integer(val), val, 1, S_set S_mix_tag_height, "an integer"); height = mus_iclamp(0, Xen_integer_to_C_int(val), LOTSA_PIXELS); set_mix_tag_height(height); for_each_normal_chan(update_graph); return(C_int_to_Xen_integer(mix_tag_height(ss))); } static Xen g_is_mix(Xen n) { #define H_is_mix "(" S_is_mix " id): returns " PROC_TRUE " if the 'n' is a mix that exists somewhere in the edit list." return(C_bool_to_Xen_boolean((xen_is_mix(n)) && (mix_exists(Xen_mix_to_C_int(n))))); } static Xen g_mixes(Xen snd, Xen chn) { #define H_mixes "(" S_mixes " :optional snd chn): list of active mixes (ids) associated with snd and chn" snd_info *sp; Xen res1 = Xen_empty_list; Snd_assert_channel(S_mixes, snd, chn, 0); if (Xen_is_integer(snd) || xen_is_sound(snd)) { int i; if (Xen_is_integer(chn)) { /* scan all mixes for any associated with this channel */ chan_info *cp; cp = get_cp(snd, chn, S_mixes); if (!cp) return(Xen_false); for (i = mix_infos_ctr - 1; i >= 0; i--) if ((mix_is_active(i)) && (mix_infos[i]->cp == cp)) res1 = Xen_cons(new_xen_mix(i), res1); } else { sp = get_sp(snd); if (sp == NULL) return(snd_no_such_sound_error(S_mixes, snd)); for (i = sp->nchans - 1; i >= 0; i--) res1 = Xen_cons(g_mixes(snd, C_int_to_Xen_integer(i)), res1); } } else { int j; for (j = ss->max_sounds - 1; j >= 0; j--) { sp = ss->sounds[j]; if ((sp) && (sp->inuse == SOUND_NORMAL)) res1 = Xen_cons(g_mixes(C_int_to_Xen_integer(j), Xen_undefined), res1); } } return(res1); } static Xen g_mix_vct(Xen obj, Xen beg, Xen snd, Xen chn, Xen with_tag, Xen origin) { #define H_mix_vct "(" S_mix_vct " data :optional (beg 0) snd chn (with-tag " S_with_mix_tags ") origin): \ mix data (a " S_vct ") into snd's channel chn starting at beg; return the new mix id, if any" vct *v; mus_long_t bg; chan_info *cp; const char *edname = NULL; mus_float_t *data; int len, mix_id = NO_MIX_TAG; bool with_mixer; Xen_check_type(mus_is_vct(obj), obj, 1, S_mix_vct, "a " S_vct); Snd_assert_channel(S_mix_vct, snd, chn, 3); Xen_check_type(Xen_is_integer_or_unbound(beg), beg, 2, S_mix_vct, "an integer"); Xen_check_type(Xen_is_boolean_or_unbound(with_tag), with_tag, 5, S_mix_vct, "a boolean"); Xen_check_type(Xen_is_string_or_unbound(origin), origin, 6, S_mix_vct, "a string"); cp = get_cp(snd, chn, S_mix_vct); if (!cp) return(Xen_false); if (!(is_editable(cp))) return(Xen_false); if (Xen_is_string(origin)) edname = Xen_string_to_C_string(origin); else edname = S_mix_vct; bg = beg_to_sample(beg, S_mix_vct); v = Xen_to_vct(obj); len = mus_vct_length(v); with_mixer = virtual_mix_ok(cp, cp->edit_ctr); if (with_mixer) { if (!Xen_is_bound(with_tag)) with_mixer = with_mix_tags(ss); else with_mixer = Xen_boolean_to_C_bool(with_tag); } if (!with_mixer) return(C_bool_to_Xen_boolean(mix_vct_untagged(v, cp, bg, edname))); data = mus_vct_data(v); /* make_snd_data_buffer copies the data array, so we don't need GC protection */ /* we can't use v->data directly because the user might change it */ { char *new_origin; /* (mix-vct (vct .1 .2 .3) 100 0 0 #t "mix-vct (vct .1 .2 .3)") */ #if HAVE_FORTH /* vct( 0.1 0.2 0.3 ) 100 snd chn #t "vct( 0.1 0.2, 0.3 )" mix-vct */ { if (edname && *edname) { char *name; if ((name = strrchr(edname, ' '))) name++; else name = S_mix_vct; new_origin = mus_format("%.*s %lld snd chn %s to -mix-%d", (int)(strlen(edname) - strlen(name) - 1), edname, bg, name, mix_infos_ctr); } else new_origin = mus_format("vct( 0 ) %lld snd chn %s to -mix-%d", bg, S_mix_vct, mix_infos_ctr); } #endif #if HAVE_SCHEME new_origin = mus_format("(set! -mix-%d (%s %lld snd chn))", mix_infos_ctr, edname, bg); #endif #if HAVE_RUBY /* mix_vct(vct(0.1, 0.2, 0.3), 100, snd, chn, true, "mix_vct(vct(0.1, 0.2, 0.3)") */ new_origin = mus_format("_mix_%d = %s, %lld, snd, chn)", mix_infos_ctr, edname, bg); #endif mix_id = mix_buffer_with_tag(cp, data, bg, len, new_origin); free(new_origin); } update_graph(cp); return(new_xen_mix(mix_id)); } static Xen g_mix(Xen file, Xen chn_samp_n, Xen file_chn, Xen snd_n, Xen chn_n, Xen tag, Xen auto_delete) { #define H_mix "(" S_mix " file :optional (beg 0) (in-chan 0) snd chn (with-tag " S_with_mix_tags ") auto-delete): \ mix channel in-chan of file into snd's channel chn starting at beg (in the output), returning a list of the new mixes. \ If in-chan is " PROC_TRUE ", all input channels are mixed into successive channels of snd, starting at chn. \ if with-tag is " PROC_FALSE ", no draggable tag is created. If \ auto-delete is " PROC_TRUE ", the input file is deleted when it is no longer needed." chan_info *cp = NULL; static char *name = NULL; int chans, id = NO_MIX_TAG, file_channel = 0; bool with_mixer; mus_long_t beg = 0, len = 0; /* it might be nice to make mix generic: vct=mix-vct, region=mix-region, sound-data=mix-sound-data * also mix-sound|mix-channel (sound object/int), but arg order is confusing (file-chn...) * and mix-vct has "origin", also file_chn might be env: pan-mix-* [vector list?] * * mix-vct origin arg is not used (externally) except as a comment * * mix object :channel :out-channel :start (:end?) :with-tag :auto-delete (:edit-position?) (:channels?) :origin * or * mix object :start :end :channel :edit-position :out-channel :with-tag :auto-delete :origin ? * mix in-object out-object :start :end :channel :edit-position :out-channel :with-tag :auto-delete :origin ? * from * play object :start :end :channel :edit-position :out-channel :with-sync :wait :stop): * save_sound_as :file :sound :srate :sample-type :header-type :channel :edit-position :comment): */ Xen_check_type(Xen_is_string(file), file, 1, S_mix, "a string"); Xen_check_type(Xen_is_number_or_unbound(chn_samp_n), chn_samp_n, 2, S_mix, "an integer"); Xen_check_type(Xen_is_integer_boolean_or_unbound(file_chn), file_chn, 3, S_mix, "an integer or " PROC_TRUE); Snd_assert_channel(S_mix, snd_n, chn_n, 4); Xen_check_type(Xen_is_boolean_or_unbound(tag), tag, 6, S_mix, "a boolean"); Xen_check_type(Xen_is_integer_boolean_or_unbound(auto_delete), auto_delete, 7, S_mix, "a boolean or an integer"); if (name) free(name); name = mus_expand_filename(Xen_string_to_C_string(file)); if (!(mus_file_probe(name))) return(snd_no_such_file_error(S_mix, file)); cp = get_cp(snd_n, chn_n, S_mix); if (!cp) return(Xen_false); if (Xen_is_llong(chn_samp_n)) beg = Xen_llong_to_C_llong(chn_samp_n); chans = mus_sound_chans(name); if (chans <= 0) { Xen_error(BAD_HEADER, Xen_list_3(C_string_to_Xen_string(S_mix ": ~S chans <= 0? (~A)"), file, C_int_to_Xen_integer(chans))); } if (Xen_is_integer(file_chn)) { file_channel = Xen_integer_to_C_int(file_chn); if ((file_channel >= chans) || (file_channel < 0)) { Xen_error(NO_SUCH_CHANNEL, Xen_list_4(C_string_to_Xen_string(S_mix ": chan: ~A, but ~S chans: ~A"), file_chn, file, C_int_to_Xen_integer(chans))); } } else { if (Xen_is_true(file_chn)) /* this used to be the default as well -- !Xen_is_bound case */ { int i, out_chans = 1; Xen result = Xen_empty_list; file_delete_t delete_choice = DONT_DELETE_ME; if (Xen_is_integer(auto_delete)) delete_choice = (file_delete_t)Xen_integer_to_C_int(auto_delete); else { if (Xen_is_boolean(auto_delete)) { if (Xen_boolean_to_C_bool(auto_delete)) { if ((chans > 1) && (cp->sound->nchans > 1)) /* mix_complete_file sets sync locally so all we care about here is nchans */ { remember_temp(name, chans); delete_choice = MULTICHANNEL_DELETION; } else delete_choice = DELETE_ME; } else delete_choice = DONT_DELETE_ME; } } id = mix_complete_file(cp->sound, beg, name, (!Xen_is_bound(tag)) ? with_mix_tags(ss) : Xen_boolean_to_C_bool(tag), delete_choice, MIX_SETS_SYNC_LOCALLY, &out_chans); if (id == -1) return(Xen_false); for (i = 0; i < out_chans; i++) result = Xen_cons(new_xen_mix(id + i), result); return(Xen_list_reverse(result)); } } len = mus_sound_framples(name); if (len <= 0) return(Xen_false); with_mixer = virtual_mix_ok(cp, cp->edit_ctr); if (with_mixer) { if (!Xen_is_bound(tag)) with_mixer = with_mix_tags(ss); else with_mixer = Xen_boolean_to_C_bool(tag); } { file_delete_t delete_file = DONT_DELETE_ME; delete_file = xen_to_file_delete_t(auto_delete, S_mix); if ((delete_file == MULTICHANNEL_DELETION) || (delete_file == MULTICHANNEL_DELETION_IF_FILE)) remember_temp(name, chans); if (!with_mixer) { char *origin; origin = untagged_mix_to_string(name, beg, file_channel, delete_file == DELETE_ME); mix_file_untagged(name, file_channel, cp, beg, len, delete_file, origin); free(origin); } else { char *origin; origin = tagged_mix_to_string(name, beg, file_channel, delete_file == DELETE_ME); if (len < FILE_BUFFER_SIZE) { mus_float_t *data; data = (mus_float_t *)malloc(len * sizeof(mus_float_t)); len = mus_file_to_array(name, file_channel, 0, len, data); if (len > 0) id = mix_buffer_with_tag(cp, data, beg, len, origin); free(data); if (delete_file == DELETE_ME) snd_remove(name, REMOVE_FROM_CACHE); else { if (delete_file == MULTICHANNEL_DELETION_IF_FILE) forget_temp(name, file_channel); } } else { id = mix_file_with_tag(cp, name, file_channel, beg, delete_file, origin); if (mix_exists(id)) /* if edit is blocked, mix_file can return NO_MIX_TAG (-1) */ { mix_info *md; md = md_from_id(id); if (!md->in_filename) md->in_filename = mus_strdup(name); } } free(origin); } } update_graph(cp); if (id == NO_MIX_TAG) return(Xen_false); return(Xen_list_1(new_xen_mix(id))); } /* ---------------- mix samplers ---------------- */ typedef struct mix_fd { mix_info *md; snd_fd *sf; } mix_fd; static Xen_object_type_t mf_tag; bool is_mix_sampler(Xen obj) { return(Xen_c_object_is_type(obj, mf_tag)); } #define Xen_to_mix_sampler(obj) ((mix_fd *)Xen_object_ref(obj)) static Xen g_is_mix_sampler(Xen obj) { #define H_is_mix_sampler "(" S_is_mix_sampler " obj): " PROC_TRUE " if obj is a mix-sampler" return(C_bool_to_Xen_boolean(is_mix_sampler(obj))); } static char *mix_sampler_to_string(mix_fd *fd) { char *desc; desc = (char *)calloc(PRINT_BUFFER_SIZE, sizeof(char)); if ((fd == NULL) || (fd->sf == NULL)) snprintf(desc, PRINT_BUFFER_SIZE, "#"); else { if ((mix_is_active(fd->sf->region)) && (fd->md) && (fd->sf->region == (fd->md->id))) { mix_info *md; md = fd->md; snprintf(desc, PRINT_BUFFER_SIZE, "#", md->id, fd->sf->initial_samp, fd->sf->loc, (fd->sf->at_eof) ? ", at eof" : "", (md->in_filename) ? md->in_filename : S_vct); } else snprintf(desc, PRINT_BUFFER_SIZE, "#"); } return(desc); } Xen_wrap_print(mix_fd, print_mf, mix_sampler_to_string) static void mf_free(mix_fd *fd) { if (fd) { if (fd->sf) free_snd_fd(fd->sf); fd->sf = NULL; fd->md = NULL; free(fd); } } Xen_wrap_free(mix_fd, free_mf, mf_free) #if HAVE_SCHEME static bool s7_equalp_mf(void *m1, void *m2) { return(m1 == m2); } #endif Xen g_make_mix_sampler(Xen mix_id, Xen ubeg) { #define H_make_mix_sampler "(" S_make_mix_sampler " id :optional (beg 0)): return a reader ready to access mix id" mix_info *md = NULL; mix_state *ms; mus_long_t beg; Xen_check_type(xen_is_mix(mix_id), mix_id, 1, S_make_mix_sampler, "a mix"); Snd_assert_sample_type(S_make_mix_sampler, ubeg, 2); md = md_from_id(Xen_mix_to_C_int(mix_id)); if (md == NULL) return(snd_no_such_mix_error(S_make_mix_sampler, mix_id)); beg = beg_to_sample(ubeg, S_make_mix_sampler); ms = current_mix_state(md); if (ms) { mix_fd *mf = NULL; mf = (mix_fd *)calloc(1, sizeof(mix_fd)); mf->md = md; mf->sf = make_virtual_mix_reader(md->cp, beg, ms->len, ms->index, ms->scaler, READ_FORWARD); if (mf->sf) { mf->sf->region = md->id; return(Xen_make_object(mf_tag, mf, 0, free_mf)); } } return(Xen_false); } static Xen g_read_mix_sample(Xen obj) { mix_fd *mf; #define H_read_mix_sample "(" S_read_mix_sample " reader): read sample from mix reader" Xen_check_type(is_mix_sampler(obj), obj, 1, S_read_mix_sample, "a mix-sampler"); mf = Xen_to_mix_sampler(obj); return(C_double_to_Xen_real(read_sample(mf->sf))); } snd_fd *xen_mix_to_snd_fd(Xen obj) { mix_fd *mf; mf = Xen_to_mix_sampler(obj); return(mf->sf); } snd_fd *mf_to_snd_fd(void *p) {return(((mix_fd *)p)->sf);} #if HAVE_SCHEME static Xen s7_read_mix_sample(s7_scheme *sc, Xen obj, Xen args) { return(g_read_mix_sample(obj)); } #endif Xen g_copy_mix_sampler(Xen obj) { mix_fd *mf; mf = Xen_to_mix_sampler(obj); return(g_make_mix_sampler(new_xen_mix(mf->md->id), C_llong_to_Xen_llong(current_location(mf->sf)))); } Xen g_mix_sampler_home(Xen obj) { mix_fd *mf; mf = Xen_to_mix_sampler(obj); return(new_xen_mix(mf->md->id)); } static bool mix_sampler_is_at_end(void *ptr) { mix_fd *mf = (mix_fd *)ptr; return(mf->sf->at_eof); } Xen g_mix_sampler_is_at_end(Xen obj) { mix_fd *mf; mf = Xen_to_mix_sampler(obj); return(C_bool_to_Xen_boolean(mix_sampler_is_at_end(mf))); } Xen g_mix_sampler_position(Xen obj) { mix_fd *mf; mf = Xen_to_mix_sampler(obj); if (mix_sampler_is_at_end(mf)) return(Xen_integer_zero); return(C_llong_to_Xen_llong(current_location(mf->sf))); } Xen g_free_mix_sampler(Xen obj) { mix_fd *mf; mf = Xen_to_mix_sampler(obj); if (mf) { if (mf->sf) mf->sf = free_snd_fd(mf->sf); mf->md = NULL; } return(Xen_false); } static io_error_t save_mix(int id, const char *name, mus_header_t head_type, mus_sample_t samp_type) { mix_info *md; chan_info *cp; snd_info *sp; mix_state *ms; io_error_t io_err = IO_NO_ERROR; mus_long_t framples; md = md_from_id(id); cp = md->cp; sp = cp->sound; ms = current_mix_state(md); framples = ms->len; io_err = snd_write_header(name, head_type, snd_srate(sp), 1, framples, samp_type, NULL, NULL); if (io_err == IO_NO_ERROR) { mus_long_t oloc; int ofd; oloc = mus_header_data_location(); ofd = snd_reopen_write(name); if (ofd != -1) { mus_float_t **bufs; mus_float_t *data; mus_long_t i; mix_fd *mf = NULL; snd_file_open_descriptors(ofd, name, samp_type, oloc, 1, head_type); mus_file_set_clipping(ofd, clipping(ss)); lseek(ofd, oloc, SEEK_SET); mf = (mix_fd *)calloc(1, sizeof(mix_fd)); mf->md = md; mf->sf = make_virtual_mix_reader(md->cp, 0, ms->len, ms->index, ms->scaler, READ_FORWARD); mf->sf->region = md->id; bufs = (mus_float_t **)calloc(1, sizeof(mus_float_t *)); bufs[0] = (mus_float_t *)calloc(FILE_BUFFER_SIZE, sizeof(mus_float_t)); data = bufs[0]; for (i = 0; i < framples; i += FILE_BUFFER_SIZE) { int err; int cursamples, k; if ((i + FILE_BUFFER_SIZE) < framples) cursamples = FILE_BUFFER_SIZE; else cursamples = (framples - i); for (k = 0; k < cursamples; k++) data[k] = read_sample(mf->sf); err = mus_file_write(ofd, 0, cursamples - 1, 1, bufs); if (err != MUS_NO_ERROR) { snd_warning("write error while saving mix"); break; } } free_snd_fd(mf->sf); free(mf); free(bufs[0]); data = NULL; free(bufs); mus_file_close(ofd); } else snd_error("%s %d in %s: %s", S_save_mix, id, name, snd_io_strerror()); } else snd_error("%s %d in %s: %s", S_save_mix, id, name, snd_io_strerror()); return(io_err); } #define MIX_TAG_Y_SEPARATION 20 int copy_mix(int id) { int new_id; mus_long_t pos; char *filename, *origin; mix_info *md, *new_md; md = md_from_id(id); if (!md) return(-1); filename = snd_tempnam(); save_mix(id, filename, MUS_NEXT, MUS_OUT_SAMPLE_TYPE); pos = mix_position_from_id(id); origin = tagged_mix_to_string(filename, pos, 0, true); /* true = file should be auto-deleted, I think */ new_id = mix_file_with_tag(md->cp, filename, 0, pos, DELETE_ME, origin); new_md = md_from_id(new_id); if (!new_md->in_filename) new_md->in_filename = mus_strdup(filename); new_md->tag_y = md->tag_y + MIX_TAG_Y_SEPARATION; free(origin); free(filename); return(new_id); } static Xen g_save_mix(Xen m, Xen file) { #define H_save_mix "(" S_save_mix " mix filename) saves mix's samples in the file 'filename'" int id; Xen_check_type(xen_is_mix(m), m, 1, S_save_mix, "a mix"); id = Xen_mix_to_C_int(m); if (mix_is_active(id)) { Xen_check_type(Xen_is_string(file), file, 2, S_save_mix, "a filename"); save_mix(id, Xen_string_to_C_string(file), MUS_NEXT, MUS_OUT_SAMPLE_TYPE); return(m); } return(snd_no_such_mix_error(S_save_mix, m)); } static Xen g_view_mixes_dialog(void) { #define H_view_mixes_dialog "(" S_view_mixes_dialog "): start the Mix browser" return(Xen_wrap_widget(make_mix_dialog())); } static Xen g_mix_dialog_mix(void) { #define H_mix_dialog_mix "(" S_mix_dialog_mix "): current mix id displayed in mix dialog." return(new_xen_mix(mix_dialog_mix())); } static Xen g_set_mix_dialog_mix(Xen val) { Xen_check_type(xen_is_mix(val), val, 1, S_set S_mix_dialog_mix, "a mix"); mix_dialog_set_mix(Xen_mix_to_C_int(val)); return(val); } static bool play_mix(mix_info *md, mus_long_t beg, bool start_playing) { mix_state *ms; ms = current_mix_state(md); if (!ms) { int i; for (i = md->cp->edit_ctr - 1; (ms == NULL) && (i < 0); i--) ms = ed_mix_state(md->cp->edits[i], md->id); } if (ms) return(add_mix_to_play_list(ms, md->cp, beg, start_playing)); return(false); } static void syncd_mix_play_1(mix_info *md, void *ignore) { play_mix(md, 0, false); } void syncd_mix_play(int id) { /* add any syncd mixes to the play list (started later) */ for_each_syncd_mix(id, syncd_mix_play_1, NULL); } Xen g_play_mix(Xen num, mus_long_t samp) { mix_info *md; md = md_from_id(Xen_mix_to_C_int(num)); if (md == NULL) return(snd_no_such_mix_error(S_play, num)); play_mix(md, samp, true); return(num); } bool play_mix_from_id(int mix_id) { mix_info *md; md = md_from_id(mix_id); if (md) return(play_mix(md, 0, true)); return(false); } #if HAVE_SCHEME #define S_mix_to_vct "mix->float-vector" #else #define S_mix_to_vct "mix->vct" #endif Xen g_mix_to_vct(Xen mix_n, Xen beg_n, Xen num) { mus_float_t *data; mix_info *md; mus_long_t beg, len; mus_long_t i; mix_fd *mf = NULL; mix_state *ms; Xen_check_type(xen_is_mix(mix_n), mix_n, 1, S_mix_to_vct, "a mix"); Xen_check_type(Xen_is_integer_or_unbound(beg_n), beg_n, 2, S_mix_to_vct, "an integer"); Xen_check_type(Xen_is_integer_or_unbound(num), num, 3, S_mix_to_vct, "an integer"); md = md_from_id(Xen_mix_to_C_int(mix_n)); if (md == NULL) return(snd_no_such_mix_error(S_mix_to_vct, mix_n)); ms = current_mix_state(md); if (Xen_is_integer(num)) { len = Xen_llong_to_C_llong(num); if (len < 0) Xen_out_of_range_error(S_mix_to_vct, 2, num, "length < 0?"); if (len > mix_length_from_id(md->id)) len = mix_length_from_id(md->id); } else len = mix_length_from_id(md->id); beg = beg_to_sample(beg_n, S_mix_to_vct); if (beg >= len) return(Xen_false); mf = (mix_fd *)calloc(1, sizeof(mix_fd)); mf->md = md; mf->sf = make_virtual_mix_reader(md->cp, beg, ms->len, ms->index, ms->scaler, READ_FORWARD); mf->sf->region = md->id; data = (mus_float_t *)calloc(len, sizeof(mus_float_t)); for (i = 0; i < len; i++) data[i] = read_sample(mf->sf); free_snd_fd(mf->sf); free(mf); return(xen_make_vct(len, data)); } Xen_wrap_1_arg(g_mix_position_w, g_mix_position) Xen_wrap_2_args(g_set_mix_position_w, g_set_mix_position) Xen_wrap_1_arg(g_mix_speed_w, g_mix_speed) Xen_wrap_2_args(g_set_mix_speed_w, g_set_mix_speed) Xen_wrap_1_arg(g_mix_amp_w, g_mix_amp) Xen_wrap_2_args(g_set_mix_amp_w, g_set_mix_amp) Xen_wrap_1_arg(g_mix_amp_env_w, g_mix_amp_env) Xen_wrap_2_args(g_set_mix_amp_env_w, g_set_mix_amp_env) Xen_wrap_1_arg(g_mix_name_w, g_mix_name) Xen_wrap_2_args(g_set_mix_name_w, g_set_mix_name) Xen_wrap_1_arg(g_mix_tag_y_w, g_mix_tag_y) Xen_wrap_2_args(g_set_mix_tag_y_w, g_set_mix_tag_y) Xen_wrap_1_arg(g_mix_sync_w, g_mix_sync) Xen_wrap_2_args(g_set_mix_sync_w, g_set_mix_sync) Xen_wrap_no_args(g_mix_sync_max_w, g_mix_sync_max) Xen_wrap_1_arg(g_mix_length_w, g_mix_length) Xen_wrap_1_arg(g_integer_to_mix_w, g_integer_to_mix) Xen_wrap_1_arg(g_mix_to_integer_w, g_mix_to_integer) Xen_wrap_1_arg(g_mix_home_w, g_mix_home) Xen_wrap_1_arg(g_mix_properties_w, g_mix_properties) Xen_wrap_2_args(g_set_mix_properties_w, g_set_mix_properties) Xen_wrap_2_args(g_mix_property_w, g_mix_property) Xen_wrap_3_args(g_set_mix_property_w, g_set_mix_property) Xen_wrap_no_args(g_mix_waveform_height_w, g_mix_waveform_height) Xen_wrap_1_arg(g_set_mix_waveform_height_w, g_set_mix_waveform_height) Xen_wrap_no_args(g_with_mix_tags_w, g_with_mix_tags) Xen_wrap_1_arg(g_set_with_mix_tags_w, g_set_with_mix_tags) Xen_wrap_no_args(g_mix_tag_width_w, g_mix_tag_width) Xen_wrap_1_arg(g_set_mix_tag_width_w, g_set_mix_tag_width) Xen_wrap_no_args(g_mix_tag_height_w, g_mix_tag_height) Xen_wrap_1_arg(g_set_mix_tag_height_w, g_set_mix_tag_height) Xen_wrap_1_arg(g_is_mix_w, g_is_mix) Xen_wrap_2_optional_args(g_mixes_w, g_mixes) Xen_wrap_7_optional_args(g_mix_w, g_mix) Xen_wrap_6_optional_args(g_mix_vct_w, g_mix_vct) Xen_wrap_2_optional_args(g_make_mix_sampler_w, g_make_mix_sampler) Xen_wrap_1_arg(g_read_mix_sample_w, g_read_mix_sample) Xen_wrap_1_arg(g_is_mix_sampler_w, g_is_mix_sampler) Xen_wrap_2_args(g_save_mix_w, g_save_mix) Xen_wrap_no_args(g_view_mixes_dialog_w, g_view_mixes_dialog) Xen_wrap_no_args(g_mix_dialog_mix_w, g_mix_dialog_mix) Xen_wrap_1_arg(g_set_mix_dialog_mix_w, g_set_mix_dialog_mix) #if HAVE_SCHEME static s7_pointer acc_mix_tag_height(s7_scheme *sc, s7_pointer args) {return(g_set_mix_tag_height(s7_cadr(args)));} static s7_pointer acc_mix_tag_width(s7_scheme *sc, s7_pointer args) {return(g_set_mix_tag_width(s7_cadr(args)));} static s7_pointer acc_mix_waveform_height(s7_scheme *sc, s7_pointer args) {return(g_set_mix_waveform_height(s7_cadr(args)));} static s7_pointer acc_with_mix_tags(s7_scheme *sc, s7_pointer args) {return(g_set_with_mix_tags(s7_cadr(args)));} #endif void g_init_mix(void) { init_xen_mix(); #if HAVE_SCHEME mf_tag = s7_new_type_x(s7, "", print_mf, free_mf, s7_equalp_mf, NULL, s7_read_mix_sample, NULL, NULL, NULL, NULL, NULL); #else mf_tag = Xen_make_object_type("MixSampler", sizeof(mix_fd)); #endif #if HAVE_RUBY rb_define_method(mf_tag, "to_s", Xen_procedure_cast print_mf, 0); rb_define_method(mf_tag, "call", Xen_procedure_cast g_read_mix_sample, 0); #endif #if HAVE_FORTH fth_set_object_inspect(mf_tag, print_mf); fth_set_object_free(mf_tag, free_mf); fth_set_object_apply(mf_tag, Xen_procedure_cast g_read_mix_sample, 0, 0, 0); #endif Xen_define_safe_procedure(S_make_mix_sampler, g_make_mix_sampler_w, 1, 1, 0, H_make_mix_sampler); Xen_define_safe_procedure(S_read_mix_sample, g_read_mix_sample_w, 1, 0, 0, H_read_mix_sample); Xen_define_safe_procedure(S_is_mix_sampler, g_is_mix_sampler_w, 1, 0, 0, H_is_mix_sampler); Xen_define_procedure(S_save_mix, g_save_mix_w, 2, 0, 0, H_save_mix); Xen_define_procedure(S_mix, g_mix_w, 1, 6, 0, H_mix); Xen_define_procedure(S_mix_vct, g_mix_vct_w, 1, 5, 0, H_mix_vct); Xen_define_safe_procedure(S_mixes, g_mixes_w, 0, 2, 0, H_mixes); Xen_define_safe_procedure(S_mix_home, g_mix_home_w, 1, 0, 0, H_mix_home); Xen_define_safe_procedure(S_is_mix, g_is_mix_w, 1, 0, 0, H_is_mix); Xen_define_safe_procedure(S_mix_length, g_mix_length_w, 1, 0, 0, H_mix_length); Xen_define_safe_procedure(S_integer_to_mix, g_integer_to_mix_w, 1, 0, 0, H_integer_to_mix); Xen_define_safe_procedure(S_mix_to_integer, g_mix_to_integer_w, 1, 0, 0, H_mix_to_integer); Xen_define_safe_procedure(S_view_mixes_dialog, g_view_mixes_dialog_w, 0, 0, 0, H_view_mixes_dialog); Xen_define_safe_procedure(S_mix_sync_max, g_mix_sync_max_w, 0, 0, 0, H_mix_sync_max); Xen_define_dilambda(S_mix_position, g_mix_position_w, H_mix_position, S_set S_mix_position, g_set_mix_position_w, 1, 0, 2, 0); Xen_define_dilambda(S_mix_speed, g_mix_speed_w, H_mix_speed, S_set S_mix_speed, g_set_mix_speed_w, 1, 0, 2, 0); Xen_define_dilambda(S_mix_amp, g_mix_amp_w, H_mix_amp, S_set S_mix_amp, g_set_mix_amp_w, 1, 0, 2, 0); Xen_define_dilambda(S_mix_amp_env, g_mix_amp_env_w, H_mix_amp_env, S_set S_mix_amp_env, g_set_mix_amp_env_w, 1, 0, 2, 0); Xen_define_dilambda(S_mix_name, g_mix_name_w, H_mix_name, S_set S_mix_name, g_set_mix_name_w, 1, 0, 2, 0); Xen_define_dilambda(S_mix_sync, g_mix_sync_w, H_mix_sync, S_set S_mix_sync, g_set_mix_sync_w, 1, 0, 2, 0); Xen_define_dilambda(S_mix_properties, g_mix_properties_w, H_mix_properties, S_set S_mix_properties, g_set_mix_properties_w, 1, 0, 2, 0); Xen_define_dilambda(S_mix_property, g_mix_property_w, H_mix_property, S_set S_mix_property, g_set_mix_property_w, 2, 0, 3, 0); Xen_define_dilambda(S_mix_tag_y, g_mix_tag_y_w, H_mix_tag_y, S_set S_mix_tag_y, g_set_mix_tag_y_w, 1, 0, 2, 0); Xen_define_dilambda(S_mix_tag_width, g_mix_tag_width_w, H_mix_tag_width, S_set S_mix_tag_width, g_set_mix_tag_width_w, 0, 0, 1, 0); Xen_define_dilambda(S_mix_tag_height, g_mix_tag_height_w, H_mix_tag_height, S_set S_mix_tag_height, g_set_mix_tag_height_w, 0, 0, 1, 0); Xen_define_dilambda(S_mix_waveform_height, g_mix_waveform_height_w, H_mix_waveform_height, S_set S_mix_waveform_height, g_set_mix_waveform_height_w, 0, 0, 1, 0); Xen_define_dilambda(S_with_mix_tags, g_with_mix_tags_w, H_with_mix_tags, S_set S_with_mix_tags, g_set_with_mix_tags_w, 0, 0, 1, 0); Xen_define_dilambda(S_mix_dialog_mix, g_mix_dialog_mix_w, H_mix_dialog_mix, S_set S_mix_dialog_mix, g_set_mix_dialog_mix_w, 0, 0, 1, 0); #define H_mix_release_hook S_mix_release_hook " (id samples): called after the mouse has dragged a mix to some new position. \ 'samples' = samples moved in the course of the drag. If it returns " PROC_TRUE ", the actual remix is the hook's responsibility." mix_release_hook = Xen_define_hook(S_mix_release_hook, "(make-hook 'id 'samples)", 2, H_mix_release_hook); #define H_mix_drag_hook S_mix_drag_hook " (id x y): called when a mix is dragged" mix_drag_hook = Xen_define_hook(S_mix_drag_hook, "(make-hook 'id 'x 'y)", 3, H_mix_drag_hook); /* args = id, mouse x, mouse or tag y */ /* the name draw-mix-hook is inconsistent with the other mix hooks (mix-draw-hook?), but is intended to parallel draw-mark-hook */ #define H_draw_mix_hook S_draw_mix_hook " (id old-x old-y x y): called when a mix tag is about to be displayed" draw_mix_hook = Xen_define_hook(S_draw_mix_hook, "(make-hook 'id 'old-x 'old-y 'x 'y)", 5, H_draw_mix_hook); #if HAVE_SCHEME s7_symbol_set_access(s7, ss->mix_tag_height_symbol, s7_make_function(s7, "[acc-" S_mix_tag_height "]", acc_mix_tag_height, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->mix_tag_width_symbol, s7_make_function(s7, "[acc-" S_mix_tag_width "]", acc_mix_tag_width, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->mix_waveform_height_symbol, s7_make_function(s7, "[acc-" S_mix_waveform_height "]", acc_mix_waveform_height, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->with_mix_tags_symbol, s7_make_function(s7, "[acc-" S_with_mix_tags "]", acc_with_mix_tags, 2, 0, false, "accessor")); s7_symbol_set_documentation(s7, ss->mix_tag_height_symbol, "*mix-tag-height*: height (pixels) of mix tags (14)"); s7_symbol_set_documentation(s7, ss->mix_tag_width_symbol, "*mix-tag-width*: width (pixels) of mix tags (6)"); s7_symbol_set_documentation(s7, ss->mix_waveform_height_symbol, "*mix-waveform-height*: max height (pixels) of mix waveforms (20)"); s7_symbol_set_documentation(s7, ss->with_mix_tags_symbol, "*with-mix-tags*: #t if Snd should try to use virtual (tagged) mixing"); #endif } snd-16.1/s7-slib-init.scm0000644000076400007640000003124312622705137013270 0ustar bilbil;;; "s7.init" Initialization for SLIB for S7 -*-scheme-*- ;;; Author: Aubrey Jaffer ;;; ;;; This code is in the public domain. ;;; S7 is embedded in Snd or Sndlib; ;;; It does not exist as a stand-alone program. ;;@ (software-type) should be set to the generic operating system type. ;;; unix, vms, macos, amiga and ms-dos are supported. (define (software-type) 'unix) ;;@ (scheme-implementation-type) should return the name of the scheme ;;; implementation loading this file. (define (scheme-implementation-type) 's7) ;;@ (scheme-implementation-home-page) should return a (string) URI ;;; (Uniform Resource Identifier) for this scheme implementation's home ;;; page; or false if there isn't one. (define (scheme-implementation-home-page) "http://ccrma.stanford.edu/software/snd/") ;;@ (scheme-implementation-version) should return a string describing ;;; the version the scheme implementation loading this file. (define scheme-implementation-version s7-version) ;;@ (implementation-vicinity) should be defined to be the pathname of ;;; the directory where any auxillary files to your Scheme ;;; implementation reside. (define implementation-vicinity (let ((impl-path (or (getenv "S7_IMPLEMENTATION_PATH") (case (software-type) ((unix) "/usr/local/share/snd/") ((vms) "scheme$src:") ((ms-dos) "C:\\Program Files\\snd\\") (else ""))))) (lambda () impl-path))) ;;@ (library-vicinity) should be defined to be the pathname of the ;;; directory where files of Scheme library functions reside. (define library-vicinity (let ((library-path (or ;; Use this getenv if your implementation supports it. (getenv "SCHEME_LIBRARY_PATH") ;; Use this path if your scheme does not support GETENV ;; or if SCHEME_LIBRARY_PATH is not set. (case (software-type) ((unix) "/usr/local/lib/slib/") ((vms) "lib$scheme:") ((ms-dos) "C:\\Program Files\\slib\\") (else ""))))) (lambda () library-path))) ;;@ (home-vicinity) should return the vicinity of the user's HOME ;;; directory, the directory which typically contains files which ;;; customize a computer environment for a user. (define (home-vicinity) (let ((home (getenv "HOME"))) (and home (case (software-type) ((unix coherent ms-dos) ;V7 unix has a / on HOME (if (eqv? #\/ (string-ref home (+ -1 (string-length home)))) home (string-append home "/"))) (else home))))) ;@ (define in-vicinity string-append) ;@ (define (user-vicinity) (case (software-type) ((vms) "[.]") (else ""))) (define *load-pathname* #f) ; *load-path* is a list of dirs in s7 ;@ (define vicinity:suffix? (let ((suffi (case (software-type) ((amiga) '(#\: #\/)) ((macos thinkc) '(#\:)) ((ms-dos windows atarist os/2) '(#\\ #\/)) ((nosve) '(#\: #\.)) ((unix coherent plan9) '(#\/)) ((vms) '(#\: #\])) (else (slib:warn "require.scm" 'unknown 'software-type (software-type)) "/")))) (lambda (chr) (memv chr suffi)))) ;@ (define (pathname->vicinity pathname) (let loop ((i (- (string-length pathname) 1))) (cond ((negative? i) "") ((vicinity:suffix? (string-ref pathname i)) (substring pathname 0 (+ i 1))) (else (loop (- i 1)))))) (define (program-vicinity) (if *load-pathname* (pathname->vicinity *load-pathname*) (slib:error 'program-vicinity " called; use slib:load to load"))) ;@ (define sub-vicinity (case (software-type) ((vms) (lambda (vic name) (let ((l (string-length vic))) (if (or (zero? (string-length vic)) (not (char=? #\] (string-ref vic (- l 1))))) (string-append vic "[" name "]") (string-append (substring vic 0 (- l 1)) "." name "]"))))) (else (let ((*vicinity-suffix* (case (software-type) ((nosve) ".") ((macos thinkc) ":") ((ms-dos windows atarist os/2) "\\") ((unix coherent plan9 amiga) "/")))) (lambda (vic name) (string-append vic name *vicinity-suffix*)))))) ;@ (define (make-vicinity ) ) ;@ (define with-load-pathname (let ((exchange (lambda (new) (let ((old *load-pathname*)) (set! *load-pathname* new) old)))) (lambda (path thunk) (let ((old #f)) (dynamic-wind (lambda () (set! old (exchange path))) thunk (lambda () (exchange old))))))) ;;@ SLIB:FEATURES is a list of symbols naming the (SLIB) features ;;; initially supported by this implementation. (define slib:features '( source ;can load scheme source files ;(SLIB:LOAD-SOURCE "filename") ;;; compiled ;can load compiled files ;(SLIB:LOAD-COMPILED "filename") vicinity srfi-59 srfi-96 ;; Scheme report features ;; R5RS-compliant implementations should provide all 9 features. ;;; r5rs ;conforms to eval ;R5RS two-argument eval values ;R5RS multiple values dynamic-wind ;R5RS dynamic-wind macro ;R5RS high level macros ;;; delay ;has DELAY and FORCE multiarg-apply ;APPLY can take more than 2 args. char-ready? rev4-optional-procedures ;LIST-TAIL, STRING-COPY, ;STRING-FILL!, and VECTOR-FILL! ;; These four features are optional in both R4RS and R5RS multiarg/and- ;/ and - can take more than 2 args. rationalize ;;; transcript ;TRANSCRIPT-ON and TRANSCRIPT-OFF with-file ;has WITH-INPUT-FROM-FILE and ;WITH-OUTPUT-TO-FILE ;;; r4rs ;conforms to ;;; ieee-p1178 ;conforms to ;;; I don't know what ieee-p1178 is ;;; r3rs ;conforms to ;;; I don't know what this means ;;; rev2-procedures ;SUBSTRING-MOVE-LEFT!, ;SUBSTRING-MOVE-RIGHT!, ;SUBSTRING-FILL!, ;STRING-NULL?, APPEND!, 1+, ;-1+, ?, >=? ;;; object-hash ;has OBJECT-HASH full-continuation ;can return multiple times ;;; ieee-floating-point ;conforms to IEEE Standard 754-1985 ;IEEE Standard for Binary ;Floating-Point Arithmetic. ;;; if this means all the NaN and inf stuff, then s7 does not conform ;; Other common features ;;; srfi-0 ;srfi-0, COND-EXPAND finds all srfi-* ;;; sicp ;runs code from Structure and ;Interpretation of Computer ;Programs by Abelson and Sussman. ;;; ?? never tried to run it defmacro ;has Common Lisp DEFMACRO ;;; syntax-case ;has syncase:eval and syncase:load ;;; record ;has user defined data structures string-port ;has CALL-WITH-INPUT-STRING and ;CALL-WITH-OUTPUT-STRING ;;; sort ;;; s7 has sort! but not merge etc ;;; pretty-print object->string format ;Common-lisp output formatting ;;; trace ;has macros: TRACE and UNTRACE ;;; s7 does have these functions, but not "print-call-stack" ;;; compiler ;has (COMPILER) ;;; ed ;(ED) is editor system ;posix (system ) getenv ;posix (getenv ) ;;; program-arguments ;returns list of strings (argv) ;;; current-time ;returns time in seconds since 1/1/1970 ;; Implementation Specific features random )) ;;@ (FILE-POSITION . ) (define (file-position . args) #f) ;;@ (OUTPUT-PORT-WIDTH ) (define (output-port-width . arg) 79) ;;@ (OUTPUT-PORT-HEIGHT ) (define (output-port-height . arg) 24) ;;@ (CURRENT-ERROR-PORT) (define current-error-port (let ((port (current-output-port))) (lambda () port))) ;;@ (TMPNAM) makes a temporary file name. (define tmpnam (let ((cntr 100)) (lambda () (set! cntr (+ 1 cntr)) (string-append "slib_" (number->string cntr))))) ;;@ (FILE-EXISTS? ) ;(define (file-exists? f) #f) ;;@ (DELETE-FILE ) ;(define (delete-file f) #f) ;;@ FORCE-OUTPUT flushes any pending output on optional arg output port ;;; use this definition if your system doesn't have such a procedure. (define (force-output . arg) #t) ;;; CALL-WITH-INPUT-STRING and CALL-WITH-OUTPUT-STRING are the string ;;; port versions of CALL-WITH-*PUT-FILE. ;;@ "rationalize" adjunct procedures. ;;(define (find-ratio x e) ;; (let ((rat (rationalize x e))) ;; (list (numerator rat) (denominator rat)))) ;;(define (find-ratio-between x y) ;; (find-ratio (/ (+ x y) 2) (/ (- x y) 2))) ;;@ CHAR-CODE-LIMIT is one greater than the largest integer which can ;;; be returned by CHAR->INTEGER. (define char-code-limit 256) ;;@ MOST-POSITIVE-FIXNUM is used in modular.scm ;;(define most-positive-fixnum #x0FFFFFFF) ;;@ Return argument (define (identity x) x) ;;@ SLIB:EVAL is single argument eval using the top-level (user) environment. (define slib:eval eval) (define *defmacros* (list (cons 'defmacro (lambda (name parms . body) `(set! *defmacros* (cons (cons ',name (lambda ,parms ,@body)) *defmacros*)))))) ;@ (define (defmacro? m) (assq m *defmacros*)) ;@ (define (macroexpand-1 e) (if (pair? e) (let ((a (car e))) (cond ((symbol? a) (set! a (assq a *defmacros*)) (if a (apply (cdr a) (cdr e)) e)) (else e))) e)) ;@ (define (macroexpand e) (if (pair? e) (let ((a (car e))) (cond ((symbol? a) (set! a (assq a *defmacros*)) (if a (macroexpand (apply (cdr a) (cdr e))) e)) (else e))) e)) ;@ (define gentemp (let ((*gensym-counter* -1)) (lambda () (set! *gensym-counter* (+ *gensym-counter* 1)) (string->symbol (string-append "slib:G" (number->string *gensym-counter*)))))) (define base:eval slib:eval) ;@ (define (defmacro:eval x) (base:eval (defmacro:expand* x))) (define (defmacro:expand* x) (slib:require 'defmacroexpand) (apply defmacro:expand* x ())) ;@ (define (defmacro:load ) (slib:eval-load defmacro:eval)) ;@ (define slib:warn (lambda args (let ((cep (current-error-port))) (if (provided? 'trace) (print-call-stack cep)) (display "Warn: " cep) (for-each (lambda (x) (display #\space cep) (write x cep)) args) (newline cep)))) ;;@ define an error procedure for the library (define slib:error error) ;@ (define (make-exchanger obj) (lambda (rep) (let ((old obj)) (set! obj rep) old))) (define (open-file filename modes) (case modes ((r rb) (open-input-file filename)) ((w wb) (open-output-file filename)) (else (slib:error 'open-file 'mode? modes)))) (define (port? obj) (or (input-port? obj) (output-port? obj))) (define (call-with-open-ports . ports) (define proc (car ports)) (cond ((procedure? proc) (set! ports (cdr ports))) (else (set! ports (reverse ports)) (set! proc (car ports)) (set! ports (reverse (cdr ports))))) (let ((ans (apply proc ports))) (for-each close-port ports) ans)) (define (close-port port) (cond ((input-port? port) (close-input-port port) (if (output-port? port) (close-output-port port))) ((output-port? port) (close-output-port port)) (else (slib:error 'close-port 'port? port)))) ;@ (define (browse-url url) (define (try cmd end) (zero? (system (string-append cmd url end)))) (or (try "netscape-remote -remote 'openURL(" ")'") (try "netscape -remote 'openURL(" ")'") (try "netscape '" "'&") (try "netscape '" "'"))) ;;@ define these as appropriate for your system. (define slib:tab (integer->char 9)) (define slib:form-feed (integer->char 12)) ;;@ Support for older versions of Scheme. Not enough code for its own file. (define (last-pair l) (if (pair? (cdr l)) (last-pair (cdr l)) l)) (define t #t) (define nil #f) ;;@ Define these if your implementation's syntax can support it and if ;;; they are not already defined. (define (1+ n) (+ n 1)) (define (-1+ n) (+ n -1)) (define 1- -1+) ;;@ Define SLIB:EXIT to be the implementation procedure to exit or ;;; return if exiting not supported. (define slib:exit exit) ;;@ Here for backward compatability (define scheme-file-suffix (let ((suffix (case (software-type) ((nosve) "_scm") (else ".scm")))) (lambda () suffix))) ;;@ (SLIB:LOAD-SOURCE "foo") should load "foo.scm" or with whatever ;;; suffix all the module files in SLIB have. See feature 'SOURCE. (define (slib:load-source f) (load (string-append f ".scm"))) ;;@ (SLIB:LOAD-COMPILED "foo") should load the file that was produced ;;; by compiling "foo.scm" if this implementation can compile files. ;;; See feature 'COMPILED. (define slib:load-compiled load) ;;@ At this point SLIB:LOAD must be able to load SLIB files. (define slib:load slib:load-source) ;;; If your implementation provides R4RS macros: (define macro:eval slib:eval) (define macro:load slib:load-source) ;;; If your implementation provides syntax-case macros: ;;(define syncase:eval slib:eval) ;;(define syncase:load slib:load-source) (slib:load (in-vicinity (library-vicinity) "require")) ;;; -------------------------------------------------------------------------------- ;;; for wttree.scm (set! *#readers* (cons (cons #\F (lambda (str) (not (string=? str "")))) *#readers*)) ;;; for r4syn.scm (set! *#readers* (cons (cons #\T (lambda (str) (string=? str ""))) *#readers*)) snd-16.1/ws.scm0000644000076400007640000007346212616767665011532 0ustar bilbil;;; with-sound and friends (provide 'snd-ws.scm) ;;; -------- with-sound defaults -------- (set! *clm-srate* *default-output-srate*) (define *clm-file-name* "test.snd") (define *clm-reverb-file-name* "test.rev") (define *clm-channels* *default-output-chans*) (define *clm-sample-type* *default-output-sample-type*) (define *clm-header-type* *default-output-header-type*) (define *clm-verbose* #f) (define *clm-play* #f) (define *clm-statistics* #f) (define *clm-reverb* #f) (define *clm-reverb-channels* 1) (define *clm-reverb-data* ()) (define *clm-locsig-type* mus-interp-linear) (define *clm-clipped* #t) (define *clm-array-print-length* *print-length*) (define *clm-player* #f) (define *clm-notehook* #f) (define *clm-with-sound-depth* 0) ; for CM, not otherwise used (define *clm-delete-reverb* #f) ; should with-sound clean up reverb stream (define *to-snd* #t) (define *default-player* (lambda (s) (play s :wait #t))) (set! *clm-file-buffer-size* 65536) (define times->samples (let ((documentation "(times->samples beg dur) converts beg and (+ beg dur) to samples, returning both in a list")) (lambda (beg dur) (list (seconds->samples beg) (seconds->samples (+ beg dur)))))) ;;; -------- definstrument -------- ;(define definstrument define*) -- old form 2-Nov-05 (define *definstrument-hook* #f) ; for CM (define-macro (definstrument args . body) (let* ((name (car args)) (targs (cdr args)) (utargs (let ((arg-names ())) (for-each (lambda (a) (if (not (keyword? a)) (if (symbol? a) (set! arg-names (cons a arg-names)) (set! arg-names (cons (car a) arg-names))))) targs) (reverse arg-names)))) (if (string? (car body)) `(begin (define ,name (let ((documentation ,(car body))) (lambda* ,targs (if *clm-notehook* (*clm-notehook* (symbol->string ',name) ,@utargs)) ,@(cdr body)))) ,@(if *definstrument-hook* (list (*definstrument-hook* name targs)) (list))) `(begin (define* (,name ,@targs) (if *clm-notehook* (*clm-notehook* (symbol->string ',name) ,@utargs)) ,@body) ,@(if *definstrument-hook* (list (*definstrument-hook* name targs)) (list)))))) ;;; -------- with-sound -------- (define* (with-sound-helper thunk (output *clm-file-name*) (channels *clm-channels*) (srate *clm-srate*) (sample-type *clm-sample-type*) (header-type *clm-header-type*) comment (verbose *clm-verbose*) (reverb *clm-reverb*) (revfile *clm-reverb-file-name*) (reverb-data *clm-reverb-data*) (reverb-channels *clm-reverb-channels*) continue-old-file (statistics *clm-statistics*) scaled-to (play *clm-play*) (to-snd *to-snd*) (clipped 'unset) (notehook *clm-notehook*) ; (with-sound (:notehook (lambda args (display args))) (fm-violin 0 1 440 .1)) scaled-by ignore-output) (let ((old-srate *clm-srate*) (old-*output* *output*) (old-*reverb* *reverb*) (old-notehook *clm-notehook*) (old-verbose *clm-verbose*) (old-auto-update-interval *auto-update-interval*) (output-1 output) ; protect during nesting (output-to-file (string? output)) (reverb-1 revfile) (reverb-to-file (and reverb (string? revfile)))) (if ignore-output (begin (set! output-1 *clm-file-name*) (set! output-to-file (string? output-1)))) (dynamic-wind (lambda () (set! *clm-verbose* verbose) (set! *clm-notehook* notehook) (set! (locsig-type) *clm-locsig-type*) (set! *mus-array-print-length* *clm-array-print-length*) (set! *auto-update-interval* 0.0) (if (eq? clipped 'unset) (if (and (or scaled-by scaled-to) (member sample-type (list mus-bfloat mus-lfloat mus-bdouble mus-ldouble))) (set! (mus-clipping) #f) (set! (mus-clipping) *clm-clipped*)) (set! (mus-clipping) clipped)) (set! *clm-srate* srate)) (lambda () (if output-to-file (begin (if continue-old-file (begin (set! *output* (continue-sample->file output-1)) (set! *clm-srate* (mus-sound-srate output-1)) ; "srate" arg shadows the generic func (let ((ind (find-sound output-1))) (if (sound? ind) (close-sound ind)))) (begin (if (file-exists? output-1) (delete-file output-1)) (set! *output* (make-sample->file output-1 channels sample-type header-type comment))))) (begin (if (and (not continue-old-file) (vector? output-1)) (fill! output-1 0.0)) (set! *output* output-1))) (if reverb (if reverb-to-file (begin (if continue-old-file (set! *reverb* (continue-sample->file reverb-1)) (begin (if (file-exists? reverb-1) (delete-file reverb-1)) (set! *reverb* (make-sample->file reverb-1 reverb-channels (if (mus-header-writable header-type mus-ldouble) mus-ldouble sample-type) header-type))))) (begin (if (and (not continue-old-file) (vector? reverb-1)) (fill! reverb-1 0.0)) (set! *reverb* reverb-1)))) (let ((start (if statistics (get-internal-real-time))) (flush-reverb #f) (cycles 0) (revmax #f)) (catch 'mus-error (lambda () (catch 'with-sound-interrupt thunk (lambda args (snd-print (format #f "with-sound interrupted: ~{~A~^ ~}" (cdr args))) (set! flush-reverb #t) args))) (lambda args ;; hit mus-error, for example: ;; (with-sound () (fm-violin 0 1 440 .1 :amp-env '(0 0 1 1 1 2 3 0))) ;; user might have listener closed, or no listener so... (format #t ";~%with-sound mus-error: ~{~A~^ ~}~%" (cdr args)) ;; now try to get something to listener, since there may be no stdout (snd-print (format #f ";~%with-sound mus-error: ~{~A~^ ~}~%" (cdr args))) (set! flush-reverb #t))) (if (and reverb (not flush-reverb)) ; i.e. not interrupted by error and trying to jump out (begin (if reverb-to-file (mus-close *reverb*)) (if (and statistics (or reverb-to-file (vector? reverb-1))) (set! revmax (maxamp reverb-1))) (if reverb-to-file (set! *reverb* (make-file->sample reverb-1))) (apply reverb reverb-data) ; here is the reverb call(!) (if reverb-to-file (mus-close *reverb*)) (if (and reverb-to-file *clm-delete-reverb*) (delete-file reverb-1)))) (if output-to-file (mus-close *output*)) (let ((snd-output #f) (cur-sync #f)) (if statistics (set! cycles (* 1.0 (- (get-internal-real-time) start)))) (if (and to-snd output-to-file) (let ((cur (find-sound output-1))) (set! cur-sync (and cur (sync cur))) (if cur (set! snd-output (update-sound cur)) (if (= header-type mus-raw) (set! snd-output (open-raw-sound output-1 channels (floor srate) sample-type)) ;; open-sound here would either ask for raw settings or use possibly irrelevant defaults (set! snd-output (open-sound output-1)))) (set! (sync snd-output) #t))) (if statistics ((if (procedure? statistics) ; :statistics (lambda (str) (snd-print str)) -- intended for auto test suite statistics (if to-snd snd-print display)) (format #f (if (not (member sample-type (list mus-bdouble mus-ldouble))) "~%;~A:~% maxamp~A:~{ ~,4F~}~%~A compute time: ~,3F~%" "~%;~A:~% maxamp~A:~{ ~,8F~}~%~A compute time: ~,3F~%") (if output-to-file output-1 (if (vector? output-1) "vector" "flush")) (if (or scaled-to scaled-by) " (before scaling)" "") (if output-to-file (if to-snd (maxamp snd-output #t) ; this is a list of chan maxs '(.1 .2) (let ((lst (mus-sound-maxamp output-1))) (do ((i 0 (+ i 2))) ((>= i (length lst))) (set! (lst i) (/ (lst i) *clm-srate*))) lst)) (if (vector? output-1) (list (maxamp output-1)) '(0.0))) (if revmax (format #f " rev max: ~,4F~%" revmax) "") cycles))) (if (or scaled-to scaled-by) (if output-to-file (let* ((scale-output (or snd-output (open-sound output-1))) (old-sync (sync scale-output))) (set! (sync scale-output) (+ (sync-max) 1)) ; make sure scaling doesn't follow sync (if scaled-to (scale-to scaled-to scale-output) (scale-by scaled-by scale-output)) (set! (sync scale-output) old-sync) (save-sound scale-output) (if (not to-snd) (close-sound scale-output))) (if (float-vector? output-1) (if scaled-to (let ((pk (float-vector-peak output-1))) (if (> pk 0.0) (float-vector-scale! output-1 (/ scaled-to pk)))) (float-vector-scale! output-1 scaled-by)) (if (vector? output-1) (if scaled-to (let ((pk (maxamp output-1))) (if (> pk 0.0) (let ((scl (/ scaled-to pk))) (do ((i 0 (+ i 1))) ((= i (length output-1))) (set! (output-1 i) (* scl (output-1 i))))))) (do ((i 0 (+ i 1))) ((= i (length output-1))) (set! (output-1 i) (* scaled-by (output-1 i))))))))) (if (and play output-to-file) (if to-snd (if *clm-player* (*clm-player* snd-output) (*default-player* snd-output)) (*default-player* output-1))) (if (and to-snd output-to-file) (begin (update-time-graph snd-output) (goto-listener-end) (if (number? cur-sync) (set! (sync snd-output) cur-sync))))) output-1)) (lambda () (set! *clm-verbose* old-verbose) (set! *clm-notehook* old-notehook) (set! *auto-update-interval* old-auto-update-interval) (if *reverb* (begin (mus-close *reverb*) (set! *reverb* old-*reverb*))) (if *output* (begin (if (mus-output? *output*) (mus-close *output*)) (set! *output* old-*output*))) (set! *clm-srate* old-srate))))) (define-macro (with-sound args . body) `(with-sound-helper (lambda () ,@body) ,@args)) ;;; -------- with-full-sound -------- (define-macro (with-full-sound args . body) ;; with-sound but display full sound in Snd window `(let ((snd (with-sound-helper (lambda () ,@body) ,@args))) (set! (x-bounds *snd-opened-sound*) (list 0.0 (/ (framples *snd-opened-sound*) (srate *snd-opened-sound*)))) (let ((mx (apply max (maxamp *snd-opened-sound* #t)))) (if (> mx 1.0) (set! (y-bounds *snd-opened-sound*) (list (- mx) mx)))) snd)) (define-macro (with-fullest-sound args . body) ;; with-sound but display full sound in Snd window `(let ((snd (with-sound-helper (lambda () ,@body) ,@args))) (set! (x-bounds *snd-opened-sound*) (list 0.0 (/ (framples *snd-opened-sound*) (srate *snd-opened-sound*)))) (set! (channel-style *snd-opened-sound*) channels-separate) (do ((chn 0 (+ chn 1))) ((= chn (channels *snd-opened-sound*))) (let ((mx (maxamp *snd-opened-sound* chn))) (if (> mx 1.0) (set! (y-bounds *snd-opened-sound* chn) (list (- mx) mx))))) snd)) ;;; -------- with-temp-sound -------- (define-macro (with-temp-sound args . body) `(let ((old-file-name *clm-file-name*) (old-to-snd *to-snd*)) ;; with-sound but using tempnam for output (can be over-ridden by explicit :output) and does not open result in Snd (dynamic-wind (lambda () (set! *clm-file-name* (snd-tempnam)) (set! *to-snd* #f)) (lambda () (with-sound-helper (lambda () ,@body) ,@args)) ; dynamic-wind returns this as its result (lambda () (set! *to-snd* old-to-snd) (set! *clm-file-name* old-file-name))))) ;;; -------- clm-load -------- (define clm-load (let ((documentation "(clm-load file . args) loads 'file' in the context of with-sound")) (lambda (file . args) (apply with-sound-helper (lambda () (load file)) args)))) ;;; -------- with-mixed-sound -------- (define (with-mixed-sound-mix-info id snd) (define (find-if pred l) (cond ((null? l) #f) ((pred (car l)) (car l)) (else (find-if pred (cdr l))))) (let ((all-info (sound-property 'with-mixed-sound-info snd))) ;; each entry is '(mx-id beg chans note) (find-if (lambda (info) (and (>= id (car info)) (< id (+ (car info) (caddr info))))) all-info))) (define-macro (with-mixed-sound args . body) `(let* ((output (with-sound-helper (lambda () #f) ,@args :to-snd #t)) ; pick up args for output (outsnd (find-sound output))) (if (sound? outsnd) (let ((mix-info ()) (old-sync (sync outsnd))) ;; if multichannel output, make sure cross-chan mixes move together (if (> (channels outsnd) 1) (begin (set! (hook-functions mix-release-hook) ()) (hook-push mix-release-hook (lambda (hook) (let ((id (hook 'id)) (samps-moved (hook 'samples))) (let ((new-pos (+ samps-moved (mix-position id))) (base (sync id))) (do ((mx (integer->mix base) (integer->mix (+ (mix->integer mx) 1)))) ((or (not (mix? mx)) (not (= (sync mx) base)))) (set! (mix-position mx) new-pos)) (set! (hook 'result) #t))))))) ;; click shows the original note list entry (set! (hook-functions mix-click-hook) ()) (hook-push mix-click-hook (lambda (hook) (let ((info (with-mixed-sound-mix-info (hook 'id) outsnd))) (status-report (format #f "mix ~A: ~A" (hook 'id) (or (and info (cadddr info)) (/ (mix-position id) (* 1.0 (srate outsnd)))))) (set! (hook 'result) #t)))) ; #t -> don't print the mix id in the status area (dynamic-wind (lambda () (set! (sync outsnd) 0) (do ((chan 0 (+ 1 chan))) ((= chan (channels outsnd))) (set! (squelch-update outsnd chan) #t))) (lambda () (for-each (lambda (note) (let* ((snd (with-temp-sound (,@args :ignore-output #t :clipped #f) (eval (append (list (car note) 0.0) (cddr note)) (curlet)))) ;; I can't immediately find a way around the "eval" (beg (floor (* (srate outsnd) (cadr note)))) ;; can't use seconds->samples here because the global mus-srate value might not match the local one (mx (car (mix snd beg #t outsnd #f #t #t))) ; all chans mixed, current output sound, with mixes, with auto-delete (chans (mus-sound-chans snd))) (set! (mix-name mx) (format #f "(~A ~A)" (car note) (cadr note))) (do ((chan 0 (+ 1 chan))) ((= chan chans)) (set! (sync (integer->mix (+ (mix->integer mx) chan))) (mix->integer mx))) (set! mix-info (cons (list mx beg chans note) mix-info)))) ',body) (set! (sound-property 'with-mixed-sound-info outsnd) (reverse mix-info))) (lambda () (set! (sync outsnd) old-sync) (do ((chan 0 (+ 1 chan))) ((= chan (channels outsnd))) (set! (squelch-update outsnd chan) #f) ;; fixup y bounds to show waveform unclipped (let ((mx (ceiling (maxamp outsnd chan)))) (set! (y-bounds outsnd chan) (list (- mx) mx))) ;; fixup mix tags so they overlap less often (let ((mxs (mixes outsnd chan))) (let ((hgt 0)) (for-each (lambda (m) (set! (mix-tag-y m) hgt) (set! hgt (modulo (+ hgt 30) 100))) mxs))) (update-time-graph outsnd chan)))))) output)) ;(with-mixed-sound () (fm-violin 0 .1 440 .1) (fm-violin 1 .1 660 .1)) ;(with-mixed-sound (:channels 2) (fm-violin 0 .1 440 .1 :degree 0) (fm-violin 1 .1 660 .1 :degree 45)) (define* (with-mixed-sound->notelist (output-file "temp.scm") snd) (let* ((outsnd (or snd (selected-sound) (car (sounds)))) (mix-info (sound-property 'with-mixed-sound-info outsnd))) (if (not mix-info) (error 'no-such-mixed-sound (list "with-mixed-sound->notelist" outsnd)) (let ((cur-mixes (mixes outsnd 0)) ; for now assume each mix is multichannel (oput (open-output-file output-file))) (format oput "(with-sound (:channels ~D)~%" (channels snd)) (for-each (lambda (id) (let ((info (with-mixed-sound-mix-info id snd))) (if info (let ((call (cadddr info))) (if (not (= (cadr info) (mix-position id))) (format oput " (~A ~,3F~{ ~A~})~%" (car call) (/ (mix-position id) (* 1.0 (srate snd))) (cddr call)) (format oput " ~A~%" call))) (status-report "can't find note associated with mix ~A" id)))) cur-mixes) (format oput ")~%") (close-output-port oput))))) ;;; -------- with-marked-sound -------- (define-macro (with-marked-sound args . body) `(let ((old-notehook *clm-notehook*) (mark-list ())) (dynamic-wind (lambda () (set! *clm-notehook* (lambda (name . args) (set! mark-list (cons (append (list name) args) mark-list))))) (lambda () (let* ((result (with-sound-helper (lambda () ,@body) ,@args)) (snd (find-sound result)) (old-update (squelch-update snd 0))) (dynamic-wind (lambda () (set! (squelch-update snd 0) #t)) (lambda () (for-each (lambda (descr) (let ((m (add-mark (floor (* (srate snd) (cadr descr))) snd))) (set! (mark-name m) (format #f "~A ~A ~A" (car descr) (cadr descr) (caddr descr))))) mark-list)) (lambda () (set! (squelch-update snd 0) old-update))) result)) (lambda () (set! *clm-notehook* old-notehook))))) ;;; (with-marked-sound () (do ((i 0 (+ 1 i))) ((= i 5)) (fm-violin i .1 440 .1))) ;;; -------- sound-let -------- ;;; ;;; (with-sound () (sound-let ((a () (fm-violin 0 .1 440 .1))) (mus-mix "test.snd" a))) (define-macro (sound-let snds . body) `(let ((temp-files ()) (old-hook-list (hook-functions new-sound-hook))) ; save old new-sound-hook (nested sound-lets etc) (set! (hook-functions new-sound-hook) (list (lambda (hook) ; save current sound-let temp file list (let ((file (hook 'name))) (if (string? file) ; try to ignore float-vectors (set! temp-files (cons file temp-files))))))) (let ((val (let ,(map (lambda (arg) (if (> (length arg) 2) ; if with-sound, embed with-temp-sound `(,(car arg) (with-temp-sound ,(cadr arg) ,@(cddr arg))) arg)) ; else use direct (normal var in the let) snds) ,@body))) ; sound-let body (for-each (lambda (file) ; clean up all local temps (if (and (string? file) ; is it a file? (might be a float-vector) (file-exists? file)) (delete-file file))) temp-files) (set! (hook-functions new-sound-hook) old-hook-list) val))) ;;; -------- Common Music -------- (define* (init-with-sound (srate *clm-srate*) (output *clm-file-name*) (channels *clm-channels*) (header-type *clm-header-type*) data-format (sample-type *clm-sample-type*) comment ;(verbose *clm-verbose*) ; why is this commented out? (reverb *clm-reverb*) (revfile *clm-reverb-file-name*) (reverb-data *clm-reverb-data*) (reverb-channels *clm-reverb-channels*) continue-old-file (statistics *clm-statistics*) scaled-to (play *clm-play*) (to-snd *to-snd*) scaled-by) (let ((old-srate *clm-srate*) (start (if statistics (get-internal-real-time))) (output-to-file (string? output)) (reverb-to-file (and reverb (string? revfile)))) (set! *clm-srate* srate) (if output-to-file (if continue-old-file (begin (set! *output* (continue-sample->file output)) (set! *clm-srate* (mus-sound-srate output)) (let ((ind (find-sound output))) (if (sound? ind) (close-sound ind)))) (begin (if (file-exists? output) (delete-file output)) (set! *output* (make-sample->file output channels (or data-format sample-type) header-type comment)))) (begin (if (and (not continue-old-file) (vector? output)) (fill! output 0.0)) (set! *output* output))) (if reverb (if reverb-to-file (if continue-old-file (set! *reverb* (continue-sample->file revfile)) (begin (if (file-exists? revfile) (delete-file revfile)) (set! *reverb* (make-sample->file revfile reverb-channels (or data-format sample-type) header-type)))) (begin (if (and (not continue-old-file) (vector? revfile)) (fill! revfile 0.0)) (set! *reverb* revfile)))) (list 'with-sound-data output reverb revfile old-srate statistics to-snd scaled-to scaled-by play reverb-data start))) (define (finish-with-sound wsd) (if (eq? (car wsd) 'with-sound-data) (let ((cycles 0) (output (wsd 1)) (reverb (wsd 2)) (revfile (wsd 3)) (old-srate (wsd 4)) (statistics (wsd 5)) (to-snd (wsd 6)) (scaled-to (wsd 7)) (scaled-by (wsd 8)) (play (wsd 9)) (reverb-data (wsd 10)) (start (wsd 11))) (if reverb (begin (mus-close *reverb*) (if (string? revfile) (set! *reverb* (make-file->sample revfile)) (set! *reverb* revfile)) (apply reverb reverb-data) (mus-close *reverb*))) (if (mus-output? *output*) (mus-close *output*)) (if statistics (set! cycles (/ (- (get-internal-real-time) start) 100))) (if (and to-snd (string? output)) (let ((snd-output (open-sound output))) (set! (sync snd-output) #t) (if statistics (snd-print (format #f "~A:~% maxamp: ~A,~% compute time: ~A~%" output (maxamp snd-output #t) cycles))) (if (or scaled-to scaled-by) (begin (if scaled-to (scale-to scaled-to snd-output) (if scaled-by (scale-by scaled-by snd-output))) (save-sound snd-output))) (if play (*default-player* snd-output)) (update-time-graph snd-output))) (set! *clm-srate* old-srate) output) (error 'wrong-type-arg (list "finish-with-sound" wsd)))) (define wsdat-play ; for cm (dilambda (let ((documentation "accessor for play field of init-with-sound struct")) (lambda (w) (w 9))) (lambda (w val) (set! (w 9) val)))) ;;; -------- with-sound save state -------- (define ws-save-state (let ((documentation "(ws-save-state filename) is an after-save-state-hook function that saves the current with-sound global settings")) (lambda (hook) (let ((filename (hook 'name))) (define (open-appending filename) (open-output-file filename "a")) (define close-appending close-output-port) (let ((fd (open-appending filename))) ;; fd is a Scheme port at this point (not an integer), so we can use format etc ;; should the save-state file load this file if it hasn't been loaded? (what path?) (format fd "~%~%;;; from ws.scm~%") (format fd "(if (defined? '*clm-srate*)~%") (format fd " (begin~%") (format fd " (set! *clm-srate* ~A)~%" *clm-srate*) (format fd " (set! *clm-file-name* ~S)~%" *clm-file-name*) (format fd " (set! *clm-channels* ~A)~%" *clm-channels*) (format fd " (set! *clm-sample-type* ~A)~%" (mus-sample-type->string *clm-sample-type*)) (format fd " (set! *clm-header-type* ~A)))~%" (mus-header-type->string *clm-header-type*)) (close-appending fd)))))) (if (not (member ws-save-state (hook-functions after-save-state-hook) eq?)) (set! (hook-functions after-save-state-hook) (list ws-save-state))) ;;; -------- ->frequency -------- (define ->frequency (let ((main-pitch (/ 440.0 (expt 2.0 (/ 57 12)))) ; a4 = 440Hz is pitch 57 in our numbering (last-octave 0) ; octave number can be omitted (ratios (vector 1.0 256/243 9/8 32/27 81/64 4/3 1024/729 3/2 128/81 27/16 16/9 243/128 2.0)) (documentation "(->frequency pitch pythagorean) returns the frequency (Hz) of the 'pitch', a CLM/CM style note name as a \ symbol: 'e4 for example. If 'pythagorean', the frequency calculation uses small-integer ratios, rather than equal-tempered tuning.")) (lambda* (pitch pythagorean) ; pitch can be pitch name or actual frequency (if (symbol? pitch) (let* ((name (string-downcase (symbol->string pitch))) (base-char (name 0)) (sign-char (and (> (length name) 1) (not (char-numeric? (name 1))) (not (char=? (name 1) #\n)) (name 1))) (octave-char (if (and (> (length name) 1) (char-numeric? (name 1))) (name 1) (and (> (length name) 2) (char-numeric? (name 2)) (name 2)))) (base (modulo (+ 5 (- (char->integer base-char) (char->integer #\a))) 7)) ; c-based (diatonic) octaves (sign (if (not sign-char) 0 (if (char=? sign-char #\f) -1 1))) (octave (if octave-char (- (char->integer octave-char) (char->integer #\0)) last-octave)) (base-pitch (+ sign (case base ((0) 0) ((1) 2) ((2) 4) ((3) 5) ((4) 7) ((5) 9) ((6) 11)))) (et-pitch (+ base-pitch (* 12 octave)))) (set! last-octave octave) (if pythagorean (* main-pitch (expt 2 octave) (ratios base-pitch)) (* main-pitch (expt 2.0 (/ et-pitch 12))))) pitch)))) ;;; -------- ->sample -------- (define ->sample (let ((documentation "(->sample time-in-seconds) -> time-in-samples")) (lambda (beg) (round (* (if (pair? (sounds)) (srate) *clm-srate*) beg))))) ;;; -------- defgenerator -------- ;;; (defgenerator osc a b) ;;; (defgenerator (osc :methods (list (cons 'mus-frequency (lambda (obj) 100.0)))) a b) (define-macro (defgenerator struct-name . fields) (define (list->bindings lst) (let ((len (length lst))) (let ((nlst (make-list (* len 2)))) (do ((old lst (cdr old)) (nsym nlst (cddr nsym))) ((null? old) nlst) (if (pair? (car old)) (begin (set-car! (cdr nsym) (caar old)) (set-car! nsym (list 'quote (caar old)))) (begin (set-car! (cdr nsym) (car old)) (set-car! nsym (list 'quote (car old))))))))) (let* ((name (if (pair? struct-name) (car struct-name) struct-name)) (sname (if (string? name) name (symbol->string name))) (wrapper (or (and (pair? struct-name) (or (and (> (length struct-name) 2) (eq? (struct-name 1) :make-wrapper) (struct-name 2)) (and (= (length struct-name) 5) (eq? (struct-name 3) :make-wrapper) (struct-name 4)))) (lambda (gen) gen))) (methods (and (pair? struct-name) (or (and (> (length struct-name) 2) (eq? (struct-name 1) :methods) (struct-name 2)) (and (= (length struct-name) 5) (eq? (struct-name 3) :methods) (struct-name 4)))))) `(begin (define ,(string->symbol (string-append sname "?")) #f) (define ,(string->symbol (string-append "make-" sname)) #f) (let ((gen-type ',(string->symbol (string-append "+" sname "+"))) (gen-methods (and ,methods (apply inlet ,methods)))) (set! ,(string->symbol (string-append sname "?")) (lambda (obj) (and (let? obj) (eq? (obj 'mus-generator-type) gen-type)))) (set! ,(string->symbol (string-append "make-" sname)) (lambda* ,(map (lambda (n) (if (pair? n) n (list n 0.0))) fields) (,wrapper (openlet ,(if methods `(sublet gen-methods ,@(list->bindings (reverse fields)) 'mus-generator-type gen-type) `(inlet 'mus-generator-type gen-type ,@(list->bindings fields))))))))))) ;;; -------- clm-display-globals -------- ;;; ;;; display all the globals that might affect with-sound unexpectedly (define (clm-display-globals) (format #f ";CLM globals:~%; *clm-srate*: ~A (default: ~A)~%; *clm-file-name*: ~A~%; *clm-channels: ~A (default: ~A)~%; *clm-sample-type*: ~A (default: ~A)~%; *clm-header-type*: ~A (default: ~A)~%; *clm-reverb-channels*: ~A, *clm-reverb-data*: ~A~%; *clm-table-size*: ~A~%; *clm-file-buffer-size*: ~A~%; *clm-locsig-type*: ~A~%; *clm-array-print-length*: ~A (~A)~%; *clm-notehook*: ~A~%; *clm-default-frequency*: ~A~%; *clm-clipped*: ~A, mus-clipping: ~A~%~%" *clm-srate* *default-output-srate* *clm-file-name* *clm-channels* *default-output-chans* (mus-sample-type->string *clm-sample-type*) (mus-sample-type->string *default-output-sample-type*) (mus-header-type->string *clm-header-type*) (mus-header-type->string *default-output-header-type*) *clm-reverb-channels* *clm-reverb-data* *clm-table-size* *clm-file-buffer-size* *clm-locsig-type* *clm-array-print-length* *print-length* *clm-notehook* *clm-default-frequency* *clm-clipped* (mus-clipping))) ;;; -------- *clm-search-list* (define *clm-search-list* (list ".")) (define (clm-find-file name) (if (file-exists? name) name (call-with-exit (lambda (return) (for-each (lambda (path) (let ((len (length path))) (if (> len 0) (let ((new-name (string-append path (if (not (char=? (path (- len 1)) #\/)) "/" "") name))) (if (file-exists? new-name) (return new-name)))))) *clm-search-list*) #f)))) #| (with-sound () (let ((fd (make-file->sample "oboe.snd")) (len (mus-sound-framples "oboe.snd"))) (do ((i 0 (+ i 1))) ((= i len)) (outa i (* .5 (file->sample fd i 0)))))) |# (define (mix-notelists . notelists) ;; assume the second parameter is the begin time in seconds (the 1st is the instrument name) (sort! (apply append notelists) (lambda (note1 note2) (< (cadr note1) (cadr note2))))) #| (mix-notelists '((fm-violin 0 1 440 .1) (fm-violin 1 1 550 .1)) '((bird 0 .1 ) (bird .2 .1) (bird 1.2 .3) (bird .5 .5))) ((bird 0 0.1) (fm-violin 0 1 440 0.1) (bird 0.2 0.1) (bird 0.5 0.5) (fm-violin 1 1 550 0.1) (bird 1.2 0.3)) |# (define* (with-simple-sound-helper thunk (output "test.snd") (channels 1) (srate 44100) (sample-type mus-lfloat) (header-type mus-next)) (let ((old-output *output*)) (dynamic-wind (lambda () (if (string? output) (set! *output* (make-sample->file output channels sample-type header-type "with-simple-sound output")) (set! *output* output))) (lambda () (thunk) output) (lambda () (if (string? output) (mus-close *output*)) (set! *output* old-output))))) (define-macro (with-simple-sound args . body) `(with-simple-sound-helper (lambda () ,@body) ,@args)) snd-16.1/leslie.cms0000644000076400007640000001724112421527425012325 0ustar bilbil;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; leslie.cms ;; ;; Time varying delay-lines ;; ======================== ;; Doppler shift for Leslie ;; ;; Based on: ;; Abel, Berners, Serafin, Smith J.O ;; "Doppler Simulation and the Leslie", ;; Proc. of DAFx-02, September, 2002 ;; ;; Thanks to Patty Huang ;; ;; ;; Syntax: CLM-4, S7 ;; ;; ;; juanig@ccrma ;; ;; First version March 20, 2004 ;; Last update September 12, 2014 ;; ;; NOTES: ;; Get Leslie effect on a pulse-train waveshape. Try acceleration with the vel-envelope. ;; It can also be used to apply a Leslie effect to a soundfile. Just switch to the ;; 'make-readin', readin ug. ;; ;; 06/20/2014 fixed delays and delay lines length ;; 09/10/2014 added reflection delay lines ;; 09/12/2014 added lowport baffle section using a lowpass butterworth ;; 09/18/2014 S7 .cms version ;; ;; (define sspeed 345.12) ;; Velocity of sound (define twopi (* 2 pi)) (define oneturn (* pi 2)) ;; We need a Lowpass filter for the lower part, low frequency (baffle) ;; of the Leslie cabinet ;; A butterworth Lowpass filter (as in dsp.scm). (define (make-butter-low-pass fq) (let* ((r (/ 1.0 (tan (/ (* pi fq) *clm-srate*)))) (r2 (* r r)) (c1 (/ 1.0 (+ 1.0 (* r (sqrt 2.0)) r2))) (c2 (* 2.0 c1)) (c3 c1) (c4 (* 2.0 (- 1.0 r2) c1)) (c5 (* (+ (- 1.0 (* r (sqrt 2.0))) r2) c1)) (arra (make-float-vector 3 )) (arrb (make-float-vector 3 ))) (set! (arra 0) c1) (set! (arra 1) c2) (set! (arra 2) c3) (set! (arrb 0) 0.0) (set! (arrb 1) c4) (set! (arrb 2) c5) (make-filter 3 arra arrb) )) ;;; Macros to handle Lowpass filter ;; (define (butter f sample0) (filter f sample0)) ;; macro to sweep frequencies ;; (define (sweep-butterfq b freq) `(let* ((fq ,freq) (r (/ 1.0 (tan (/ (* pi fq) *srate*)))) (r2 (* r r)) (c1 (/ 1.0 (+ 1.0 (* r (sqrt 2.0)) r2)))) (set! (mus-xcoeff ,b 0) c1) (set! (mus-xcoeff ,b 1) (* 2.0 c1)) (set! (mus-xcoeff ,b 2) c1) (set! (mus-ycoeff ,b 1) (* 2.0 (- 1.0 r2) c1)) (set! (mus-ycoeff ,b 2) (* (+ (- 1.0 (* r (sqrt 2.0))) r2) c1)) )) (definstrument (rotates start dur freq (speedsl 3.33) ;; Speed source listener mts/sec (velenv '(0 1 100 1)) ;; Velocity envelope (gain 0.125) ;; scales output ;; (onset 0.0) ;; onset values in case of reading a soundfile (rev-amount 0.025)) ;; very short reverb (let* ((beg (seconds->samples start)) (sig (make-pulse-train :frequency freq)) ;;; (rdA (make-readin :file file ;; just in case you want to read ;;; :start (seconds->samples onset)) ;; a soundfile instead ;;; (maxddelayl (if (= *clm-srate* 44100) (values 96) (values 104))) (startddelay (if (= *clm-srate* 44100) (values 48) (values 52))) (m2samp (/ *clm-srate* sspeed)) (vel-env (make-env velenv :duration (* dur 0.5))) ;;; ;;; Doppler delay lines ;;; (dpdelays (make-vector 4)) (dshift (make-vector 4 startddelay)) ;; ;;; ;;; Reflection path delay arrays ;;; (refldelays (make-vector 4)) (reflectlen (make-vector 4)) (reflections (make-vector 4 0.0)) (hornout (make-vector 4 0.0)) ;; ;; Lowpass (baffle) 'frequency shift' array (fshift (make-vector 4)) (baffleout (make-vector 4)) ;; (bfila (make-butter-low-pass 200)) (bfilb (make-butter-low-pass 200)) (bfilc (make-butter-low-pass 200)) (bfild (make-butter-low-pass 200)) ;; (growf0 0.0) (growf1 0.0) (growfa 0.0) (growfb 0.0) ;; (hornangvel 1.0) (baffleangvel 1.0) (hornangle 0.0) (hornradius 0.18) (baffleangle 0.0) (baffleradius 0.19050) ;; (xdev 0.0) (ydev 0.0) (cabinetlen 0.71) (cabinetwid 0.52) ;; (end (+ beg (seconds->samples dur))) ) ;; ;; Make delays ;; (do ((i 0 (1+ i))) ((= i 4 )) (set! (dpdelays i) (make-delay :size startddelay :max-size maxddelayl :type mus-interp-linear)) (set! (refldelays i) (make-delay ))) ;; ;; ;;; ;;; main loop ;;; (do ((i beg (1+ i))) ((= i end )) ;; (let ((sample (pulse-train sig)) ;;; (sample (readin rdA)) switch in case of reading a soundfile (deltavel (env vel-env)) (sigouta 0.0) (sigoutb 0.0) ;; horn (sigoutc 0.0) (sigoutd 0.0) ;; reflections (woofera 0.0) (wooferb 0.0)) ;; low baffle output ;; ;; set acceleration of horn (set! hornangvel (* speedsl deltavel)) (set! hornangle (+ hornangle (* twopi (/ hornangvel *clm-srate*)))) ;; baffle lower port (set! baffleangvel (* 0.98 speedsl )) (set! baffleangle (+ baffleangle (* twopi (/ baffleangvel *clm-srate*)))) ;; (if (> hornangle twopi) (set! hornangle (- hornangle twopi))) (if (> baffleangle twopi) (set! baffleangle (- baffleangle twopi))) ;; ;; calculate grow functions for delay line size (horn Doppler shifts) (set! growf0 (/ (*(* (- twopi) hornradius) (* hornangvel (cos hornangle))) sspeed)) (set! growf1 (/ (*(* (- twopi) hornradius) (* hornangvel (sin hornangle))) sspeed)) ;; (set! (dshift 0) (- (dshift 0) growf0)) (set! (dshift 1) (- (dshift 1) growf1)) (set! (dshift 2) (- (dshift 2) (- growf0))) (set! (dshift 3) (- (dshift 3) (- growf1))) ;; (do ((j 0 (1+ j))) ((= j 4)) (set! (hornout j ) (delay (dpdelays j) sample (dshift j))) ) ;; ;; Reflections ;; (set! xdev (* hornradius (cos hornangle))) (set! ydev (* hornradius (sin hornangle))) (set! (reflectlen 0) (* (+ (/ cabinetwid 2) ydev) m2samp)) (set! (reflectlen 1) (* (- cabinetlen xdev) m2samp)) (set! (reflectlen 2) (* 1.5 (- cabinetwid ydev) m2samp)) (set! (reflectlen 3) (* (+ cabinetlen xdev) m2samp)) ;; ;; Need to add these reflections to *reverb* (do ((j 0 (1+ j))) ((= j 4)) (set! (reflections j) (delay (refldelays j) (hornout j) (reflectlen j)))) ;; (set! sigouta (+ (hornout 0) (hornout 2))) (set! sigoutb (+ (hornout 1) (hornout 3))) (set! sigoutc (+ (reflections 0) (reflections 2))) (set! sigoutd (+ (reflections 1) (reflections 3))) ;; ;; Grow functions baffle low port section (set! growfa (* (- twopi) baffleradius baffleangvel (cos baffleangle))) (set! growfb (* (- twopi) baffleradius baffleangvel (sin baffleangle))) ;; (set! (fshift 0) (+ 250 (* growfa 50))) (set! (fshift 1) (+ 250 (* growfb 50))) (set! (fshift 2) (+ 250 (* (- growfa) 50))) (set! (fshift 3) (+ 250 (* (- growfb) 50))) ;; (sweep-butterfq bfila (fshift 0)) (sweep-butterfq bfilb (fshift 1)) (sweep-butterfq bfilc (fshift 2)) (sweep-butterfq bfild (fshift 3)) ;; (set! (baffleout 0) (butter bfila sample)) (set! (baffleout 1) (butter bfilb sample)) (set! (baffleout 2) (butter bfilc sample)) (set! (baffleout 3) (butter bfild sample)) ;; (set! woofera (+ (baffleout 0) (baffleout 2))) (set! wooferb (+ (baffleout 1) (baffleout 3))) ;; (outa i (* gain (+ sigouta sigoutc woofera))) (outb i (* gain (+ sigoutb sigoutd wooferb))) ;;; (if *reverb* (progn (outa i (* (* 0.5 gain) (+ sigoutc woofera) rev-amount) *reverb*) (outb i (* (* 0.5 gain) (+ sigoutd wooferb) rev-amount) *reverb*) )) )) )) ;;; (with-sound (:channels 2) (rotates 0 1 800)) ;;; (with-sound (:channels 2) (rotates 0 3 200)) ;;; (with-sound (:channels 2) (rotates 0 8 300 :speedsl 1.0)) ;;; (with-sound (:channels 2) (rotates 0 3 500 :speedsl 1.0)) ;;; (with-sound (:channels 2) (rotates 0 3 500 :velenv '(0 0 100 1))) ;;; (with-sound (:channels 2) (rotates 0 3 500 :velenv '(0 1 100 0.25))) ;;; (load "nrev.ins") ;;; (with-sound (:channels 2 :reverb nrev :reverb-channels 2) (rotates 0 5 500 :velenv '(0 1 100 0.25))) snd-16.1/big-gens.scm0000644000076400007640000001426312462206766012553 0ustar bilbil(provide 'snd-big-gens.scm) (require snd-generators.scm) ;;; -------- conversions -------- (define (big-hz->radians hz) (/ (* hz 2 pi) *clm-srate*)) (define (big-radians->hz rad) (/ (* rad *clm-srate*) (* 2 pi))) (define (big-db->linear x) (expt 10.0 (/ x 20.0))) (define (big-linear->db x) (if (> x 0.0) (* 20.0 (log x 10)) -100.0)) (define (big-degrees->radians deg) (* (/ pi 180) deg)) (define (big-radians->degrees rad) (/ (* rad 180) pi)) (define (big-seconds->samples secs) (round (* secs *clm-srate*))) (define (big-samples->seconds samps) (/ samps *clm-srate*)) (define (big-rectangular->polar rl im) (let ((len (length rl))) (do ((i 0 (+ i 1))) ((= i len)) (let ((rl1 (rl i)) (im1 (im i))) (set! (rl i) (sqrt (+ (* rl1 rl1) (* im1 im1)))) (set! (im i) (- (atan im1 rl1))))))) (define (big-polar->rectangular mag ang) (let ((len (length mag))) (do ((i 0 (+ i 1))) ((= i len)) (let ((mag1 (mag i)) (ang1 (- (ang i)))) (set! (mag i) (* mag1 (cos ang1))) (set! (ang i) (* mag1 (sin ang1))))))) ;;; -------- arrays (vectors in this context) -------- (define (big-array-clear v) (fill! v 0.0)) (define (big-array-normalize v) (let ((len (length v)) (pk 0.0)) (do ((i 0 (+ i 1))) ((= i len)) (set! pk (max pk (abs (v i))))) (if (and (not (= pk 0.0)) (not (= pk 1.0))) (do ((i 0 (+ i 1))) ((= i len)) (set! (v i) (/ (v i) pk)))) v)) (define (big-array-interp wave x n) (let* ((xx (modulo x n)) (ipart (floor xx)) (fpart (- xx ipart))) (if (zero? fpart) (wave ipart) (+ (wave ipart) (* fpart (- (wave (modulo (+ ipart 1) n)) (wave ipart))))))) ;;; -------- polynomial -------- (define (big-polynomial coeffs x) (let* ((top (- (length coeffs) 1)) (sum (coeffs top))) (do ((i (- top 1) (- i 1))) ((< i 0) sum) (set! sum (+ (* x sum) (coeffs i)))))) ;;; -------- dot-product -------- (define (big-dot-product v1 v2) (let ((len (min (length v1) (length v2)))) (do ((sum 0.0) (i 0 (+ i 1))) ((= i len) sum) (set! sum (+ sum (* (v1 i) (v2 i))))))) ;;; -------- ring-modulate -------- (define big-ring-modulate *) ;;; -------- amplitude-modulate -------- (define (big-amplitude-modulate carrier in1 in2) (* in1 (+ carrier in2))) ;;; -------- contrast-enhancement -------- (define* (big-contrast-enhancement in1 (index 1.0)) (sin (+ (* in1 (/ pi 2)) (* index (sin (* 2 pi in1)))))) ;;; -------- oscil -------- (defgenerator (big-oscil :make-wrapper (lambda (g) (set! (g 'frequency) (big-hz->radians (g 'frequency))) g)) (frequency *clm-default-frequency*) (angle 0.0)) (define* (big-oscil gen (fm 0.0) (pm 0.0)) (let ((x (gen 'angle))) (set! (gen 'angle) (+ fm x (gen 'frequency))) (sin (+ x pm)))) #| (with-sound (:statistics #t :clipped #f) (let ((g (make-big-oscil 440.0))) (do ((i 0 (+ i 1))) ((= i 22050)) (outa i (* .5 (big-oscil g)))))) |# ;;; -------- ncos -------- (defgenerator (big-ncos :make-wrapper (lambda (g) (if (<= (g 'n) 0) (set! (g 'n) 1)) (set! (g 'r) (/ (g 'n))) (set! (g 'frequency) (big-hz->radians (g 'frequency))) g)) (frequency *clm-default-frequency*) (n 1) (angle 0.0) (r 1.0)) (define* (big-ncos gen (fm 0.0)) (let* ((n (gen 'n)) (x (gen 'angle)) (scl (gen 'r)) (den (* 2 (sin (/ x 2))))) (set! (gen 'angle) (+ fm x (gen 'frequency))) (if (= den 0.0) 1.0 (min 1.0 (* scl (- (/ (sin (* (+ n 1/2) x)) den) 1/2)))))) #| (with-sound (:statistics #t :clipped #f) (let ((g (make-big-ncos 100.0 10))) (do ((i 0 (+ i 1))) ((= i 22050)) (outa i (* .5 (big-ncos g)))))) |# ;;; -------- nsin -------- (defgenerator (big-nsin :make-wrapper (lambda (g) (letrec ((ns (lambda (x n) (let* ((a2 (/ x 2)) (den (sin a2))) (if (= den 0.0) 0.0 (/ (* (sin (* n a2)) (sin (* (+ n 1) a2))) den))))) (find-scaler (lambda (n lo hi) (let ((mid (/ (+ lo hi) 2)) (ylo (ns lo n)) (yhi (ns hi n))) (if (< (abs (- yhi ylo)) 1e-12) (ns mid n) (if (> ylo yhi) (find-scaler n lo mid) (find-scaler n mid hi))))))) (if (<= (g 'n) 0) (set! (g 'n) 1)) (set! (g 'r) (/ 1.0 (find-scaler (g 'n) 0.0 (/ pi (+ (g 'n) 1/2))))) (set! (g 'frequency) (big-hz->radians (g 'frequency))) g))) (frequency *clm-default-frequency*) (n 1) (angle 0.0) (r 1.0)) (define* (big-nsin gen (fm 0.0)) (let* ((n (gen 'n)) (x (gen 'angle)) (a2 (/ x 2)) (scl (gen 'r)) (den (sin a2))) (set! (gen 'angle) (+ fm x (gen 'frequency))) (if (= den 0.0) 0.0 (/ (* scl (sin (* n a2)) (sin (* (+ n 1) a2))) den)))) #| (with-sound (:statistics #t :clipped #f) (let ((g (make-big-nsin 100.0 10))) (do ((i 0 (+ i 1))) ((= i 22050)) (outa i (* .5 (big-nsin g)))))) |# ;;; -------- table-lookup -------- (defgenerator (big-table-lookup :make-wrapper (lambda (g) (if (not (g 'wave)) (set! (g 'wave) (make-vector (g 'size) 0.0)) (set! (g 'size) (length (g 'wave)))) (set! (g 'frequency) (/ (* (g 'frequency) (g 'size)) *clm-srate*)) (set! (g 'angle) (/ (* (g 'angle) (g 'size)) (* 2 pi))) g)) (frequency *clm-default-frequency*) (angle 0.0) (wave #f) (size *clm-table-size*)) (define* (big-table-lookup gen (fm 0.0)) (let ((x (gen 'angle)) (w (gen 'wave)) (n (gen 'size))) (set! (gen 'angle) (+ x (gen 'frequency) (/ (* fm n) (* 2 pi)))) (big-array-interp w x n))) #| (with-sound (:statistics #t :clipped #f) (let ((g (make-big-table-lookup 100.0 0.0 (let ((w (make-vector 32))) (do ((i 0 (+ i 1))) ((= i 32) w) (set! (w i) (sin (/ (* i pi) 16)))))))) (do ((i 0 (+ i 1))) ((= i 22050)) (outa i (* .5 (big-table-lookup g)))))) |# ;;; -------- one-zero -------- (defgenerator big-one-zero (a0 1.0) (a1 0.0) (x1 0.0)) (define* (big-one-zero gen x) (let ((val (+ (* x (gen 'a0)) (* (gen 'x1) (gen 'a1))))) (set! (gen 'x1) x) val)) ;;; -------- one-pole -------- (defgenerator big-one-pole (a0 1.0) (b1 0.0) (y1 0.0)) (define* (big-one-pole gen x) (let ((val (- (* x (gen 'a0)) (* (gen 'y1) (gen 'b1))))) (set! (gen 'y1) val))) snd-16.1/maxf.scm0000644000076400007640000002501412446655017012006 0ustar bilbil;;; maxf.scm -- CLM -> Snd/Scheme translation of maxf.ins ;; Translator/Author: Michael Scholz ;; Last: Tue Mar 25 04:32:23 CET 2003 ;; Version: $Revision: 1.2 $ ;; array -> vector functions added by Bill S, 18-Apr-11 ;; defgenerator changes (Bill 25-Jul-12) ;; It follows the original header by Juan Reyes. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; maxf.ins ;; This is Max Mathews (mvm) new filter (2002) ;; High-Q, 2-Integrator, filter with ;; Two Poles, and one Zero at the Origin ;; ;; It synthesizes equal-tempered frequencies ;; integer & just scales out of a wide-band input ;; signal. ;; Based on Max's code (filter.cpp) ;; ;; This heuristic might be called Modal Synthesis. ;; But as well it can also be additive synthesis in ;; which a resonator is initialized to generate the ;; exponentially decaying sinusoids at the desired ;; phase. ;; ;; This implementation written by Juan Reyes with dsp ;; assistance from JOS. ;; This version Oct-30, 2002 ;; ;; Change gain(att) of input file if clipping ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (provide 'snd-maxf.scm) (if (provided? 'snd) (require snd-ws.scm) (require sndlib-ws.scm)) (define *locsig-type* mus-interp-sinusoidal) (define (snd-msg frm . args) (let ((str (apply format (append (list #f frm) args)))) (if (getenv "EMACS") (display str) (snd-print str)))) (defgenerator mvm sample pp1 pp2 pp3 yy1 yy2 zz1 zz2 out) (define (mvmfilt b sample0) (let-set! b 'sample sample0) (with-let b (set! yy2 (- (+ (* pp1 yy1) (* pp2 zz1)) (* pp3 sample))) (set! zz2 (- zz1 (* pp2 yy2))) (set! zz1 zz2) (set! yy1 yy2) (set! out yy1))) (define pi2s (/ (* 2.0 pi) *clm-srate*)) (define i2s (/ 2.0 *clm-srate*)) (define tper (/ 1.0 *clm-srate*)) (define (set-coeffs b famp ffreq fdecay) (let ((centerfreq (* ffreq pi2s))) (let ((maxdecay (/ (* 2.0 tper) (* centerfreq centerfreq))) (mindecay (/ tper centerfreq))) ;; Conditions for JOS constraints ;; maxdecay: Filter may be unstable ;; mindecay: Filter may not oscillate (if (>= fdecay maxdecay) (set! fdecay maxdecay) (if (<= fdecay mindecay) (set! fdecay mindecay))) (set! (b 'pp1) (- 1.0 (/ i2s fdecay))) (set! (b 'pp2) (* ffreq pi2s)) (set! (b 'pp3) (* (b 'pp2) famp))))) (define (make-array initial-value dim1 dim2) ; I'm guessing ... (make-vector (list dim1 dim2) initial-value)) (define (array-set! arr val i1 i2) (set! (arr i1 i2) val)) (define array-ref vector-ref) (define maxfilter (let ((documentation "(maxfilter file beg (att 1.0) (numf 1) (freqfactor 1.0) (amplitude 1.0) (amp-env '(0 1 100 1)) (degree (random 90.0)) (distance 1.0) (reverb-amount 0.2)) This is Max Mathews (mvm) new filter (2002) High-Q, 2-Integrator, filter with Two Poles, and one Zero at the Origin It synthesizes equal-tempered frequencies integer & just scales out of a wide-band input signal. Based on Max's code (filter.cpp) This heuristic might be called Modal Synthesis. But as well it can also be additive synthesis in which a resonator is initialized to generate the exponentially decaying sinusoids at the desired phase. (att 1) in-file attenuation (numf 1) 1 filter (numf 4) 4 filters (numf 9) 9 filters (numf 12) 12 filters (numf 13) 13 filters")) (lambda* (file beg (att 1.0) (numf 1) (freqfactor 1.0) (amplitude 1.0) (amp-env '(0 1 100 1)) (degree (random 90.0)) (distance 1.0) (reverb-amount 0.2)) (let ((beg (floor (* beg *clm-srate*))) (dur (mus-sound-framples file))) (let ((formfil (make-mvm)) (end (+ beg dur)) (rdA (make-readin :file file :channel 0)) (ampf (make-env :envelope amp-env :scaler amplitude :length dur)) (state-0 (make-array 0.0 1 3)) (state-1 (make-array 0.0 12 3)) (state-2 (make-array 0.0 9 3)) (state-3 (make-array 0.0 13 3)) (state-4 (make-array 0.0 4 3)) (state-5 (make-array 0.0 2 3)) (loc (make-locsig :degree degree :distance distance :reverb reverb-amount :type *locsig-type*))) (cond ((= numf 1) (snd-msg ";;;; State 0 (default): One filter~%") (array-set! state-0 7.54e-002 0 0) (array-set! state-0 (* 2000 freqfactor) 0 1) (array-set! state-0 2.0 0 2)) ;; ((= numf 2) (snd-msg ";;;; State 5: Two filters~%") (array-set! state-5 7.54e-003 0 0) (array-set! state-5 (* 200.0 freqfactor) 0 1) (array-set! state-5 4.0 0 2) ;; (array-set! state-5 7.54e-004 1 0) (array-set! state-5 (* 800.0 freqfactor) 1 1) (array-set! state-5 1.0 1 2)) ;; ((= numf 4) (snd-msg ";;;; State 4: Four filters~%") (array-set! state-4 7.54e-002 0 0) (array-set! state-4 (* 1000.0 freqfactor) 0 1) (array-set! state-4 0.5 0 2) ;; (array-set! state-4 3.225e-002 1 0) (array-set! state-4 (* 400.0 freqfactor) 1 1) (array-set! state-4 3.0 1 2) ;; (array-set! state-4 1.14e-002 2 0) (array-set! state-4 (* 800.0 freqfactor) 2 1) (array-set! state-4 2.8 2 2) ;; (array-set! state-4 7.54e-002 3 0) (array-set! state-4 (* 1600.0 freqfactor) 3 1) (array-set! state-4 1.0 3 2)) ;; ((= numf 9) (snd-msg ";;;; State 2: Streached overtone string 9 filters~%") (array-set! state-2 1.07e-002 0 0) (array-set! state-2 100.0 0 1) (array-set! state-2 2.5 0 2) ;; (array-set! state-2 1.07e-002 1 0) (array-set! state-2 202.0 1 1) (array-set! state-2 0.75 1 2) ;; (array-set! state-2 1.07e-002 2 0) (array-set! state-2 305.0 2 1) (array-set! state-2 0.5 2 2) ;; (array-set! state-2 7.077e-003 3 0) (array-set! state-2 408.0 3 1) (array-set! state-2 0.4 3 2) ;; (array-set! state-2 1.07e-002 4 0) (array-set! state-2 501.0 4 1) (array-set! state-2 0.3 4 2) ;; (array-set! state-2 1.07e-002 5 0) (array-set! state-2 612.0 5 1) (array-set! state-2 0.25 5 2) ;; (array-set! state-2 1.07e-003 6 0) (array-set! state-2 715.0 6 1) (array-set! state-2 0.25 6 2) ;; (array-set! state-2 1.07e-002 7 0) (array-set! state-2 817.0 7 1) (array-set! state-2 0.2 7 2) ;; (array-set! state-2 1.07e-002 8 0) (array-set! state-2 920.0 8 1) (array-set! state-2 0.18 8 2)) ;; ((= numf 12) (snd-msg ";;;; State 1: Risset bell long 12 filters~%") (array-set! state-1 5.025e-002 0 0) (array-set! state-1 224.0 0 1) (array-set! state-1 3.7 0 2) ;; (array-set! state-1 5.025e-002 1 0) (array-set! state-1 225.0 1 1) (array-set! state-1 3.3 1 2) ;; (array-set! state-1 5.025e-002 2 0) (array-set! state-1 368.0 2 1) (array-set! state-1 2.8 2 2) ;; (array-set! state-1 5.025e-002 3 0) (array-set! state-1 369.0 3 1) (array-set! state-1 2.4 3 2) ;; (array-set! state-1 1.047e-002 4 0) (array-set! state-1 476.0 4 1) (array-set! state-1 1.9 4 2) ;; (array-set! state-1 5.025e-002 5 0) (array-set! state-1 680.0 5 1) (array-set! state-1 1.7 5 2) ;; (array-set! state-1 5.025e-002 6 0) (array-set! state-1 800.0 6 1) (array-set! state-1 1.5 6 2) ;; (array-set! state-1 4.05e-002 7 0) (array-set! state-1 1096.0 7 1) (array-set! state-1 1.1 7 2) ;; (array-set! state-1 4.05e-002 8 0) (array-set! state-1 1099.0 8 1) (array-set! state-1 0.9 8 2) ;; (array-set! state-1 4.05e-002 9 0) (array-set! state-1 1200.0 9 1) (array-set! state-1 0.6 9 2) ;; (array-set! state-1 3.78e-002 10 0) (array-set! state-1 1504.0 10 1) (array-set! state-1 0.4 10 2) ;; (array-set! state-1 4.05e-002 11 0) (array-set! state-1 1628.0 11 1) (array-set! state-1 0.3 11 2)) ;; ((= numf 13) (snd-msg ";;;; State 3: Open major chord with repeated octave 12 filters~%") (array-set! state-3 5.025e-002 0 0) (array-set! state-3 100.0 0 1) (array-set! state-3 2.0 0 2) ;; (array-set! state-3 5.025e-002 1 0) (array-set! state-3 251.0 1 1) (array-set! state-3 2.0 1 2) ;; (array-set! state-3 5.025e-002 2 0) (array-set! state-3 299.0 2 1) (array-set! state-3 2.0 2 2) ;; (array-set! state-3 5.025e-002 3 0) (array-set! state-3 401.0 3 1) (array-set! state-3 2.0 3 2) ;; (array-set! state-3 5.025e-002 4 0) (array-set! state-3 199.0 4 1) (array-set! state-3 2.0 4 2) ;; (array-set! state-3 5.025e-002 5 0) (array-set! state-3 501.0 5 1) (array-set! state-3 2.0 5 2) ;; (array-set! state-3 5.025e-002 6 0) (array-set! state-3 599.0 6 1) (array-set! state-3 2.0 6 2) ;; (array-set! state-3 5.025e-002 7 0) (array-set! state-3 801.0 7 1) (array-set! state-3 2.0 7 2) ;; (array-set! state-3 5.025e-002 8 0) (array-set! state-3 201.0 8 1) (array-set! state-3 2.0 8 2) ;; (array-set! state-3 5.025e-002 9 0) (array-set! state-3 749.0 9 1) (array-set! state-3 2.0 9 2) ;; (array-set! state-3 5.025e-002 10 0) (array-set! state-3 900.0 10 1) (array-set! state-3 2.0 10 2) ;; (array-set! state-3 5.025e-004 11 0) (array-set! state-3 1205.0 11 1) (array-set! state-3 2.0 11 2) ;; (array-set! state-3 5.025e-004 12 0) (array-set! state-3 1205.0 12 1) (array-set! state-3 2.0 12 2)) (t (snd-msg "Please leave default or enter [1] [2] [4] [9] [12] [13]~%") (set! numf 1))) (let ((run-state (case numf ((1) state-0) ((2) state-5) ((4) state-4) ((9) state-2) ((12) state-1) ((13) state-3)))) (do ((i beg (+ 1 i))) ((= i end)) (let ((outvalA (* att (readin rdA))) (add-fl 0.0)) (do ((j 0 (+ 1 j))) ((= j numf)) (set-coeffs formfil (array-ref run-state j 0) (array-ref run-state j 1) (array-ref run-state j 2)) (set! add-fl (+ add-fl (mvmfilt formfil outvalA)))) (locsig loc i (* (env ampf) add-fl)))))))))) ;; (let* ((ifile "dog.snd") ;; (ofile "gmax_dog.snd") ;; (snd (find-sound ofile)) ;; (number-ary '(1 2 4 9 12 13))) ;; (if snd ;; (close-sound snd)) ;; (with-sound (:play 1 :statistics #t :channels 4 :output ofile :reverb jc-reverb ;; :comment ;; (format #f "maxfilter test, filters ~S, source ~A" number-ary ifile)) ;; (do ((i 0 (+ 1 i)) ;; (nary number-ary (cdr nary))) ;; ((null? nary)) ;; (maxfilter ifile i :numf (car nary) :degree (random 3454))))) ;; (with-sound () (maxfilter "dog.snd" 0)) ;; (with-sound (:srate 44100) (maxfilter "dog.snd" 0 :numf 12)) ;; (with-sound (:srate 44100) (maxfilter "dog.snd" 0 :numf 13 :att 0.75)) ;; (with-sound (:srate 44100) (maxfilter "dog.snd" 0 :numf 2 :att 0.25 :freqfactor 0.5)) ;; maxf.scm ends here snd-16.1/spokenword.scm0000644000076400007640000001444412446652237013254 0ustar bilbil; spokenword.scm ; ; April 17th 2007 ; ; Ville Koskinen ; j.v.o.koskinen@gmail.com ; ; Scripts to make editing spoken word files faster and easier. See "Variables" below for fine tuning. ; ; New keybindings are as follows: ; - left/right: Move 0.05 sec to left or right ; - C-left/right: Move to the previous or next "phrase" ; - i: Insert an "In" mark ; - o: Insert an "Out" mark ; - l: Listen to 3 secs from cursor, or if "In" and "Out" marks have been defined, 3 secs ; prior to the out-mark and 3 secs after the in-mark. In effect preview delete before ; commiting it. If already playing, stop. Cursor does not follow. ; - C-backspace: Delete audio between "Out" and "In" and smooth the splice ; - C-c: Clear all marks ; - p: Play from cursor with tracking cursor. If already playing, stop. ; Variables ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (define secs->samples (lambda (time) (define sr 44100) (round (* sr time)))) (define size (secs->samples 0.10)) ;length of the window for rms and peak calculations (define some-size (secs->samples 0.05)) ;length of the cursor step for right/left movement (define peak-threshold 0.15) ;threshold for non-silence peak detection (define rms-threshold 0.01) ;threshold for rms in silence detection (define phrase-look-offset (secs->samples 0.10)) ;offset for detection of a start of a phrase (define jump-length (secs->samples 0.10)) ;step size for phrase lookup (define preview-length (secs->samples 3)) ;length for listening a preview of delete or from cursor ; Procedures ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (define local-data (lambda (position) (channel->float-vector (max 0 (- position (* size .5))) size))) (define local-rms (lambda (position) (let ((data (local-data position))) (sqrt (/ (dot-product data data) size))))) (define local-peak (lambda (position) (let ((data (local-data position))) (float-vector-peak data)))) (define local-smooth (lambda (position) (smooth-channel (- position 16) 32))) (define silence? (lambda (position) (< (local-rms position) rms-threshold))) (define phrase? (lambda (position) (and (> (local-peak position) peak-threshold) (> (local-rms position) rms-threshold)))) (define phrase-start? (lambda (position) (and (silence? position) (phrase? (+ position phrase-look-offset))))) (define next-phrase (lambda (position) (do ((i 0 (+ i 1)) (found #f)) ((or (= i 100) found (= position (framples))) position) (set! position (min (framples) (+ position jump-length))) (set! found (phrase-start? position))))) (define previous-phrase (lambda (position) (do ((i 0 (+ i 1)) (found #f)) ((or (= i 100) found (= position 0)) position) (set! position (max 0 (- position jump-length))) (set! found (phrase-start? position))))) (define mark-out (lambda (position) (let ((in-mark (find-mark "In")) (out-mark (find-mark "Out"))) (if (and in-mark (<= (mark-sample in-mark) position)) (delete-mark in-mark)) (if (not out-mark) (add-mark position 0 0 "Out") (set! (mark-sample out-mark) position))))) (define mark-in (lambda (position) (let ((in-mark (find-mark "In")) (out-mark (find-mark "Out"))) (if (and out-mark (>= (mark-sample out-mark) position)) (delete-mark out-mark)) (if (not in-mark) (add-mark position 0 0 "In") (set! (mark-sample in-mark) position))))) (define delete-from-out-to-in (lambda () (let ((in-mark (find-mark "In")) (out-mark (find-mark "Out"))) (if (and in-mark out-mark (< (mark-sample out-mark) (mark-sample in-mark))) (begin (set! (cursor) (mark-sample out-mark)) (as-one-edit (lambda() (delete-samples (mark-sample out-mark) (- (+ (mark-sample in-mark) 1) (mark-sample out-mark))) (local-smooth (cursor))))))))) (define (play-preview) (let* ((in-mark (find-mark "In")) (out-mark (find-mark "Out")) (in-position (if in-mark (mark-sample in-mark) 0)) (out-position (if out-mark (mark-sample out-mark) 0))) (define (play-next reason) (if (= reason 0) (begin (play (selected-sound) in-position (+ in-position preview-length))))) (if (and in-mark out-mark) (if (< out-position in-position) (play (max 0 (- out-position preview-length)) #f #f #f out-position #f play-next)) (play (selected-sound) (cursor) (+ (cursor) preview-length))))) (set! *with-tracking-cursor* :track-and-stay) ; Key bindings ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (bind-key #\i 0 (lambda () ; Mark an in-position (mark-in (cursor)) cursor-in-view)) (bind-key #\o 0 (lambda () ; Mark an out-position (mark-out (cursor)) cursor-in-view)) (bind-key #\c 4 (lambda () ; Clear all marks (delete-marks) cursor-in-view)) (bind-key "BackSpace" 4 (lambda () ; Commit delete from mark Out to mark In (delete-from-out-to-in) cursor-in-view)) (bind-key #\p 0 (lambda () ; Play from cursor (set! *with-tracking-cursor* #t) (if (playing) (stop-playing) (play (selected-sound) (cursor))) cursor-in-view)) (bind-key #\l 0 (lambda () ; Listen to a preview before commiting delete or listen from cursor (set! *with-tracking-cursor* #f) (if (playing) (stop-playing) (play-preview)) cursor-in-view)) (bind-key "Right" 0 (lambda () ; Move cursor to the right (set! (cursor) (+ (cursor) some-size)) cursor-in-view)) (bind-key "Right" 4 (lambda () ; Move cursor to next interesting position (set! (cursor) (next-phrase (cursor))) cursor-in-view)) (bind-key "Left" 0 (lambda () ; Move cursor to the left (set! (cursor) (- (cursor) some-size)) cursor-in-view)) (bind-key "Left" 4 (lambda () ; Move cursor to previous interesting position (set! (cursor) (previous-phrase (cursor))) cursor-in-view))snd-16.1/xm-enved.scm0000644000076400007640000003201512446652237012576 0ustar bilbil;;; envelope editor based on xm module (cf enved.scm) ;;; ;;; (xe-create-enved name parent args axis-bounds) -> new envelope editor (returned value is list) ;;; (xe-envelope editor) -> current envelope (settable) (provide 'snd-xm-enved.scm) (if (and (provided? 'snd-motif) (not (provided? 'snd-snd-motif.scm))) (load "snd-motif.scm")) (define xe-envelope (dilambda (lambda (drawer) (or (car drawer) (let ((ax-inf (drawer 3))) (list (ax-inf 0) (ax-inf 1) (ax-inf 2) (ax-inf 3))))) ; was 1? (lambda (drawer new-env) (set! (drawer 0) new-env) (xe-redraw drawer)))) (define (xe-create-enved name parent args axis-bounds) (define (xe-add-envelope-point x y cur-env) (let ((new-env ())) (define (search-point e) (if (null? e) (append new-env (list x y)) (if (= (car e) x) (append new-env (list x y) (cddr e)) (if (> (car e) x) (append new-env (list x y) e) (begin (set! new-env (append new-env (list (car e) (cadr e)))) (search-point (cddr e))))))) (search-point cur-env))) (define (xe-edit-envelope-point pos x y cur-env) (let ((new-env ())) (define (search-point e npos) (if (= npos pos) (append new-env (list x y) (cddr e)) (begin (set! new-env (append new-env (list (car e) (cadr e)))) (search-point (cddr e) (+ npos 2))))) (search-point cur-env 0))) (define (xe-remove-envelope-point pos cur-env) (let ((new-env ())) (define (search-point e npos) (if (null? e) new-env (if (= pos npos) (append new-env (cddr e)) (begin (set! new-env (append new-env (list (car e) (cadr e)))) (search-point (cddr e) (+ npos 2)))))) (search-point cur-env 0))) (define (xe-envelope-position x cur-env) (define (search-point e pos) (if (= (car e) x) pos (search-point (cddr e) (+ pos 2)))) (search-point cur-env 0)) (define (xe-on-dot? x y cur-env pos) (define xe-mouse-radius .03) (and (pair? cur-env) (or (and (< (abs (- (car cur-env) x)) xe-mouse-radius) (< (abs (- (cadr cur-env) y)) xe-mouse-radius) pos) (xe-on-dot? x y (cddr cur-env) (+ pos 2))))) (define (xe-ungrfy drawer y) (let* ((bounds (drawer 3)) (locs (drawer 2)) (ay0 (bounds 1)) (ay1 (bounds 3)) (py0 (locs 1)) (py1 (locs 3))) (if (= py0 py1) ay1 (min ay1 (max ay0 (+ ay0 (* (- ay1 ay0) (/ (- py0 y) (- py0 py1))))))))) (define (xe-ungrfx drawer x) (let* ((bounds (drawer 3)) (locs (drawer 2)) (ax0 (bounds 0)) (ax1 (bounds 2)) (px0 (locs 0)) (px1 (locs 2))) (if (= px0 px1) ax0 (min ax1 (max ax0 (+ ax0 (* (- ax1 ax0) (/ (- x px0) (- px1 px0))))))))) (define xe-mouse-down 0) (define xe-mouse-up 0) (define xe-click-time .1) (define xe-mouse-pos 0) (define xe-mouse-new #f) (define (xe-mouse-press drawer xx yy) (let* ((cur-env (xe-envelope drawer)) (x (xe-ungrfx drawer xx)) (y (xe-ungrfy drawer yy)) (pos (xe-on-dot? x y cur-env 0))) (set! xe-mouse-new (not pos)) (set! xe-mouse-down (get-internal-real-time)) (if (not pos) (begin (set! (xe-envelope drawer) (xe-add-envelope-point x y cur-env)) (set! xe-mouse-pos (xe-envelope-position x (xe-envelope drawer)))) (set! xe-mouse-pos pos)))) (define (xe-mouse-drag drawer xx yy) ;; point exists, needs to be edited with check for various bounds (let* ((cur-env (xe-envelope drawer)) (x (xe-ungrfx drawer xx)) (y (xe-ungrfy drawer yy)) (lx (if (= xe-mouse-pos 0) (car cur-env) (if (>= xe-mouse-pos (- (length cur-env) 2)) (cur-env (- (length cur-env) 2)) (max (cur-env (- xe-mouse-pos 2)) (min x (cur-env (+ xe-mouse-pos 2)))))))) (set! (xe-envelope drawer) (xe-edit-envelope-point xe-mouse-pos lx y cur-env)) (xe-redraw drawer))) (define (xe-mouse-release drawer xx yy) (let ((cur-env (xe-envelope drawer))) (set! xe-mouse-up (get-internal-real-time)) (if (and (not xe-mouse-new) (<= (- xe-mouse-up xe-mouse-down) xe-click-time) (not (= xe-mouse-pos 0)) (< xe-mouse-pos (- (length cur-env) 2))) (set! (xe-envelope drawer) (xe-remove-envelope-point xe-mouse-pos cur-env))) (xe-redraw drawer) (set! xe-mouse-new #f))) (if (provided? 'snd-motif) (with-let (sublet *motif* 'args args 'parent parent 'axis-bounds axis-bounds 'name name 'xe-redraw xe-redraw 'xe-mouse-press xe-mouse-press 'xe-mouse-drag xe-mouse-drag 'xe-mouse-release xe-mouse-release) (if (not (member XmNbackground args)) (set! args (append args (list XmNbackground *graph-color*)))) (if (not (member XmNforeground args)) (set! args (append args (list XmNforeground *data-color*)))) (let* ((drawer (XtCreateManagedWidget name xmDrawingAreaWidgetClass parent args)) (gc (car (snd-gcs))) (x0 (car axis-bounds)) (x1 (cadr axis-bounds)) ; too confusing! -- change internally below (y0 (caddr axis-bounds)) (y1 (cadddr axis-bounds)) (arrow-cursor (XCreateFontCursor (XtDisplay (cadr (main-widgets))) XC_crosshair)) (editor (list (list x0 y0 x1 y0) ; needs to be in user-coordinates (graph size can change) drawer #f ; axis pixel locs filled in when drawn (list x0 y0 x1 y1) (list gc #f) name))) (XtAddCallback drawer XmNresizeCallback (lambda (w context info) (set! (editor 2) (apply draw-axes drawer gc name axis-bounds)) (xe-redraw editor))) (XtAddCallback drawer XmNexposeCallback (lambda (w context info) (set! (editor 2) (apply draw-axes drawer gc name axis-bounds)) (xe-redraw editor))) (XtAddEventHandler drawer ButtonPressMask #f (lambda (w context ev flag) (xe-mouse-press editor (.x ev) (.y ev)))) (XtAddEventHandler drawer ButtonMotionMask #f (lambda (w context ev flag) (xe-mouse-drag editor (.x ev) (.y ev)))) (XtAddEventHandler drawer ButtonReleaseMask #f (lambda (w context ev flag) (xe-mouse-release editor (.x ev) (.y ev)))) (XtAddEventHandler drawer EnterWindowMask #f (lambda (w context ev flag) (XDefineCursor (XtDisplay w) (XtWindow w) arrow-cursor))) (XtAddEventHandler drawer LeaveWindowMask #f (lambda (w context ev flag) (XUndefineCursor (XtDisplay w) (XtWindow w)))) editor)) (with-let (sublet *gtk* 'args args 'parent parent 'axis-bounds axis-bounds 'name name 'xe-redraw xe-redraw 'xe-mouse-press xe-mouse-press 'xe-mouse-drag xe-mouse-drag 'xe-mouse-release xe-mouse-release) (let* ((drawer (gtk_drawing_area_new)) (gc (car (snd-gcs))) (x0 (car axis-bounds)) (x1 (cadr axis-bounds)) (y0 (caddr axis-bounds)) (y1 (cadddr axis-bounds)) (arrow-cursor (gdk_cursor_new_for_display (gdk_display_get_default) GDK_CROSSHAIR)) (old-cursor (gdk_cursor_new_for_display (gdk_display_get_default) GDK_LEFT_PTR)) (editor (list (list x0 y0 x1 y0) ; needs to be in user-coordinates (graph size can change) drawer #f ; axis pixel locs filled in when drawn (list x0 y0 x1 y1) (list gc #f) name)) (dragging #f)) ;; (xe-create-enved "hi" ((sound-widgets 0) 9) () '(0.0 1.0 0.0 1.0)) (define (local-draw-axes wid gc label x0 x1 y0 y1) (let ((cr (make-cairo wid))) (let ((val (draw-axes wid gc label x0 x1 y0 y1 x-axis-in-seconds show-all-axes cr))) (free-cairo cr) val))) (gtk_widget_set_events drawer GDK_ALL_EVENTS_MASK) (gtk_box_pack_start (GTK_BOX parent) drawer #t #t 10) (gtk_widget_show drawer) (gtk_widget_set_size_request drawer -1 200) (g_signal_connect_closure_by_id (GPOINTER drawer) (g_signal_lookup "draw" (G_OBJECT_TYPE (G_OBJECT drawer))) 0 (g_cclosure_new (lambda (w e d) (set! (editor 2) (apply local-draw-axes drawer gc name axis-bounds)) (xe-redraw editor) #f) #f #f) #f) (g_signal_connect_closure_by_id (GPOINTER drawer) (g_signal_lookup "configure_event" (G_OBJECT_TYPE (G_OBJECT drawer))) 0 (g_cclosure_new (lambda (w e d) (set! (editor 2) (apply local-draw-axes drawer gc name axis-bounds)) (xe-redraw editor) #f) #f #f) #f) (g_signal_connect_closure_by_id (GPOINTER drawer) (g_signal_lookup "button_press_event" (G_OBJECT_TYPE (G_OBJECT drawer))) 0 (g_cclosure_new (lambda (w e d) (let* ((ev (GDK_EVENT e)) (coords (gdk_event_get_coords ev)) (x (cadr coords)) (y (caddr coords))) (set! dragging #t) (xe-mouse-press editor x y)) #f) #f #f) #f) (g_signal_connect_closure_by_id (GPOINTER drawer) (g_signal_lookup "button_release_event" (G_OBJECT_TYPE (G_OBJECT drawer))) 0 (g_cclosure_new (lambda (w e d) (let* ((ev (GDK_EVENT e)) (coords (gdk_event_get_coords ev)) (x (cadr coords)) (y (caddr coords))) (set! dragging #f) (xe-mouse-release editor x y)) #f) #f #f) #f) (g_signal_connect_closure_by_id (GPOINTER drawer) (g_signal_lookup "motion_notify_event" (G_OBJECT_TYPE (G_OBJECT drawer))) 0 (g_cclosure_new (lambda (w e d) (if dragging (let* ((ev (GDK_EVENT e)) (coords (gdk_event_get_coords ev)) (x (cadr coords)) (y (caddr coords))) (xe-mouse-drag editor x y))) #f) #f #f) #f) (g_signal_connect_closure_by_id (GPOINTER drawer) (g_signal_lookup "enter_notify_event" (G_OBJECT_TYPE (G_OBJECT drawer))) 0 (g_cclosure_new (lambda (w e d) (gdk_window_set_cursor (gtk_widget_get_window w) arrow-cursor) #f) #f #f) #f) (g_signal_connect_closure_by_id (GPOINTER drawer) (g_signal_lookup "leave_notify_event" (G_OBJECT_TYPE (G_OBJECT drawer))) 0 (g_cclosure_new (lambda (w e d) (gdk_window_set_cursor (gtk_widget_get_window w) old-cursor) #f) #f #f) #f) editor)))) (define (xe-redraw drawer) (let* ((cur-env (xe-envelope drawer)) (widget (drawer 1)) (dpy (and (provided? 'snd-motif) ((*motif* 'XtDisplay) widget))) (wn (if (provided? 'snd-motif) ((*motif* 'XtWindow) widget) ((*gtk* 'gtk_widget_get_window) widget))) (ax-pix (drawer 2)) (ax-inf (drawer 3)) (gc (car (drawer 4))) (name (drawer 5)) (len (and (list? cur-env) (length cur-env))) (get_realized (if (provided? 'snd-gtk) (*gtk* 'gtk_widget_get_realized)))) (if (and (list? ax-pix) (list? cur-env) (if (provided? 'snd-motif) ((*motif* 'XtIsManaged) widget) (get_realized widget))) (let ((px0 (ax-pix 0)) (px1 (ax-pix 2)) (py0 (ax-pix 1)) (py1 (ax-pix 3)) (ix0 (ax-inf 0)) (ix1 (ax-inf 2)) (iy0 (ax-inf 1)) (iy1 (ax-inf 3)) (mouse-d 10) (mouse-r 5)) (define (xe-grfx drawer x) (if (= px0 px1) px0 (min px1 (max px0 (floor (+ px0 (* (- px1 px0) (/ (- x ix0) (- ix1 ix0))))))))) (define (xe-grfy drawer y) (if (= py0 py1) py0 (min py0 ; grows downward so y1 < y0 (max py1 (floor (+ py1 (* (- py0 py1) (/ (- y iy1) (- iy0 iy1))))))))) (if (> py0 py1) (begin (if (provided? 'snd-motif) (begin ((*motif* 'XClearWindow) dpy wn) (draw-axes widget gc name ix0 ix1 iy0 iy1) (let ((lx #f) (ly #f)) (do ((i 0 (+ i 2))) ((= i len)) (let ((cx (xe-grfx drawer (cur-env i))) (cy (xe-grfy drawer (cur-env (+ i 1))))) ((*motif* 'XFillArc) dpy wn gc (- cx mouse-r) (- cy mouse-r) mouse-d mouse-d 0 (* 360 64)) (if lx ((*motif* 'XDrawLine) dpy wn gc lx ly cx cy)) (set! lx cx) (set! ly cy))))) ;; *gtk* (let ((lx #f) (ly #f) (cr ((*gtk* 'gdk_cairo_create) ((*gtk* 'GDK_WINDOW) wn))) (size (widget-size ((*gtk* 'GTK_WIDGET) widget)))) ((*gtk* 'cairo_push_group) cr) ((*gtk* 'cairo_set_source_rgb) cr 1.0 1.0 1.0) ((*gtk* 'cairo_rectangle) cr 0 0 (car size) (cadr size)) ((*gtk* 'cairo_fill) cr) (draw-axes widget gc name ix0 ix1 iy0 iy1 x-axis-in-seconds show-all-axes cr) ((*gtk* 'cairo_set_line_width) cr 1.0) ((*gtk* 'cairo_set_source_rgb) cr 0.0 0.0 0.0) (do ((i 0 (+ i 2))) ((= i len)) (let ((cx (xe-grfx drawer (cur-env i))) (cy (xe-grfy drawer (cur-env (+ i 1))))) ((*gtk* 'cairo_arc) cr cx cy mouse-r 0.0 (* 2 pi)) ((*gtk* 'cairo_fill) cr) (if lx (begin ((*gtk* 'cairo_move_to) cr lx ly) ((*gtk* 'cairo_line_to) cr cx cy) ((*gtk* 'cairo_stroke) cr))) (set! lx cx) (set! ly cy))) ((*gtk* 'cairo_pop_group_to_source) cr) ((*gtk* 'cairo_paint) cr) ((*gtk* 'cairo_destroy) cr))))))))) snd-16.1/rubber.scm0000644000076400007640000002236112620464322012325 0ustar bilbil;;; rubber.scm: rubber-sound stretches or contracts a sound (in time) ;;; (rubber-sound 1.5) makes it 50% longer ;;; rubber-sound looks for stable portions and either inserts or deletes periods ;;; period length is determined via autocorrelation (provide 'snd-rubber.scm) (define zeros-checked 8) (define extension 10.0) (define show-details #f) ;;; remove anything below 16Hz ;;; extend (src by 1/extension) ;;; collect upward zero-crossings ;;; collect weights for each across next zeros-checked crossings ;;; sort by least weight ;;; ramp (out or in) and check if done (define* (rubber-sound stretch snd chn) ;; prepare sound (get rid of low freqs, resample) (define* (add-named-mark samp name snd chn) (let ((m (add-mark samp snd chn))) (set! (mark-name m) name) m)) (define* (derumble-sound snd chn) (let* ((old-length (framples snd chn)) (pow2 (ceiling (log (min old-length (srate snd)) 2))) (fftlen (floor (expt 2 pow2))) (flt-env (list 0.0 0.0 (/ (* 2 16.0) (srate snd)) 0.0 (/ (* 2 20.0) (srate snd)) 1.0 1.0 1.0))) (filter-sound flt-env fftlen snd chn) (set! (framples snd chn) old-length))) (define* (sample-sound snd chn) (if (not (= extension 1.0)) (src-sound (/ 1.0 extension) 1.0 snd chn))) (define* (unsample-sound snd chn) ;; undo earlier interpolation (if (not (= extension 1.0)) (src-sound extension 1.0 snd chn))) (define (crossings) ;; return number of upward zero crossings that don't look like silence (let* ((crosses 0) (sr0 (make-sampler 0)) (samp0 (next-sample sr0)) (len (framples)) (sum 0.0) (last-cross 0) (silence (* extension .001))) (do ((i 0 (+ i 1))) ((= i len)) (let ((samp1 (next-sample sr0))) (if (and (<= samp0 0.0) (> samp1 0.0) (> (- i last-cross) 4) (> sum silence)) (begin (set! crosses (+ crosses 1)) (set! last-cross i) (set! sum 0.0))) (set! sum (+ sum (abs samp0))) (set! samp0 samp1))) crosses)) (define (env-add s0 s1 samps) (let ((data (make-float-vector samps)) (x 1.0) (xinc (/ 1.0 samps)) (sr0 (make-sampler (floor s0))) (sr1 (make-sampler (floor s1)))) (do ((i 0 (+ i 1))) ((= i samps)) (set! (data i) (+ (* x (next-sample sr0)) (* (- 1.0 x) (next-sample sr1)))) (set! x (+ x xinc))) data)) (as-one-edit (lambda () (derumble-sound snd chn) (sample-sound snd chn) (let* ((crosses (crossings)) (cross-samples (make-float-vector crosses)) (cross-weights (make-float-vector crosses)) (cross-marks (make-float-vector crosses)) (cross-periods (make-float-vector crosses))) (let* ((sr0 (make-sampler 0 snd chn)) ;; get cross points (sample numbers) (samp0 (next-sample sr0)) (len (framples)) (sum 0.0) (last-cross 0) (cross 0) (silence (* extension .001))) (do ((i 0 (+ i 1))) ((= i len)) (let ((samp1 (next-sample sr0))) (if (and (<= samp0 0.0) (> samp1 0.0) (> (- i last-cross) 40) (> sum silence)) (begin (set! last-cross i) (set! sum 0.0) (set! (cross-samples cross) i) (set! cross (+ cross 1)))) (set! sum (+ sum (abs samp0))) (set! samp0 samp1)))) ;; now run through crosses getting period match info (do ((i 0 (+ i 1))) ((= i (- crosses 1))) (let ((start (floor (cross-samples i))) (autolen 0)) (let* ((s0 start) (pow2 (ceiling (log (* extension (/ (srate snd) 40.0)) 2))) (fftlen (floor (expt 2 pow2))) (len4 (/ fftlen 4)) (data (samples (floor s0) fftlen))) (autocorrelate data) (set! autolen 0) (let ((happy #f)) (do ((j 1 (+ 1 j))) ((or happy (= j len4))) (if (and (< (data j) (data (+ j 1))) (> (data (+ j 1)) (data (+ j 2)))) (begin (set! autolen (* j 2)) (set! happy #t)))))) (let* ((next-start (+ start autolen)) (min-i (+ i 1)) (min-samps (floor (abs (- (cross-samples min-i) next-start)))) (mink (min crosses (+ i zeros-checked)))) (do ((k (+ i 2) (+ k 1))) ((= k mink)) (let ((dist (floor (abs (- (cross-samples k) next-start))))) (if (< dist min-samps) (begin (set! min-samps dist) (set! min-i k))))) (let ((current-mark min-i) (current-min 0.0)) (let* ((s0 start) (s1 (floor (cross-samples current-mark))) (len autolen) (sr0 (make-sampler (floor s0))) (sr1 (make-sampler (floor s1))) (ampsum (make-one-pole 1.0 -1.0)) (diffsum (make-one-pole 1.0 -1.0)) (samp0 0.0)) (do ((i 0 (+ i 1))) ((= i len)) (set! samp0 (next-sample sr0)) (one-pole ampsum (abs samp0)) (one-pole diffsum (abs (- (next-sample sr1) samp0)))) (set! diffsum (one-pole diffsum 0.0)) (set! ampsum (one-pole ampsum 0.0)) (if (= diffsum 0.0) (set! current-min 0.0) (set! current-min (/ diffsum ampsum)))) (set! min-samps (round (* 0.5 current-min))) (let ((top (min (- crosses 1) current-mark (+ i zeros-checked)))) (do ((k (+ i 1) (+ k 1))) ((= k top)) (let ((wgt 0.0)) (let* ((s0 start) (s1 (floor (cross-samples k))) (len autolen) (sr0 (make-sampler (floor s0))) (sr1 (make-sampler (floor s1))) (ampsum (make-one-pole 1.0 -1.0)) (diffsum (make-one-pole 1.0 -1.0)) (samp0 0.0)) (do ((i 0 (+ i 1))) ((= i len)) (set! samp0 (next-sample sr0)) (one-pole ampsum (abs samp0)) (one-pole diffsum (abs (- (next-sample sr1) samp0)))) (set! diffsum (one-pole diffsum 0.0)) (set! ampsum (one-pole ampsum 0.0)) (if (= diffsum 0.0) (set! wgt 0.0) (set! wgt (/ diffsum ampsum)))) (if (< wgt min-samps) (begin (set! min-samps (floor wgt)) (set! min-i k)))))) (if (not (= current-mark min-i)) (set! (cross-weights i) 1000.0) ; these are confused, so effectively erase them (begin (set! (cross-weights i) current-min) (set! (cross-marks i) current-mark) (set! (cross-periods i) (- (cross-samples current-mark) (cross-samples i))) )) )) )) ;; now sort weights to scatter the changes as evenly as possible (let* ((len (framples snd chn)) (adding (> stretch 1.0)) (samps (floor (* (abs (- stretch 1.0)) len))) (needed-samps (if adding samps (min len (* samps 2)))) (handled 0) (mult 1) (curs 0) (weights (length cross-weights)) (edits (make-float-vector weights))) (do () ((or (= curs weights) (>= handled needed-samps))) ;; need to find (more than) enough splice points to delete samps (let ((best-mark -1) (old-handled handled)) (let ((cur 0) (curmin (cross-weights 0)) (len (length cross-weights))) (do ((i 0 (+ i 1))) ((= i len)) (if (< (cross-weights i) curmin) (begin (set! cur i) (set! curmin (cross-weights i))))) (set! best-mark cur)) (set! handled (+ handled (floor (cross-periods best-mark)))) (if (or (< handled needed-samps) (< (- handled needed-samps) (- needed-samps old-handled))) (begin (set! (edits curs) best-mark) (set! curs (+ 1 curs)))) (set! (cross-weights best-mark) 1000.0))) (if (>= curs weights) (set! mult (ceiling (/ needed-samps handled)))) (let ((changed-len 0) (weights (length cross-weights))) (do ((i 0 (+ i 1))) ((or (= i curs) (> changed-len samps))) (let* ((best-mark (floor (edits i))) (beg (floor (cross-samples best-mark))) (next-beg (floor (cross-samples (floor (cross-marks best-mark))))) (len (floor (cross-periods best-mark)))) (if (> len 0) (if adding (let ((new-samps (env-add beg next-beg len))) (if show-details (add-named-mark beg (format #f "~D:~D" i (floor (/ len extension))))) (insert-samples beg len new-samps) (if (> mult 1) (do ((k 1 (+ k 1))) ((= k mult)) (insert-samples (+ beg (* k len)) len new-samps))) (set! changed-len (+ changed-len (* mult len))) (do ((j 0 (+ 1 j))) ((= j weights)) (let ((curbeg (floor (cross-samples j)))) (if (> curbeg beg) (set! (cross-samples j) (+ curbeg len)))))) (begin (if (>= beg (framples)) (snd-print (format #f "trouble at ~D: ~D of ~D~%" i beg (framples)))) (if show-details (add-named-mark (- beg 1) (format #f "~D:~D" i (floor (/ len extension))))) (delete-samples beg len) (set! changed-len (+ changed-len len)) (let ((end (+ beg len))) (do ((j 0 (+ 1 j))) ((= j weights)) (let ((curbeg (floor (cross-samples j)))) (if (> curbeg beg) (if (< curbeg end) (set! (cross-periods j) 0) (set! (cross-samples j) (- curbeg len)))))))))))) (if show-details (snd-print (format #f "wanted: ~D, got ~D~%" (floor samps) (floor changed-len))))) )) ;; and return to original srate (unsample-sound snd chn) (if show-details (snd-print (format #f "~A -> ~A (~A)~%" (framples snd chn 0) (framples snd chn) (floor (* stretch (framples snd chn 0)))))) ) ; end of as-one-edit thunk (format #f "rubber-sound ~A" stretch))) snd-16.1/_sndlib.h0000644000076400007640000000411612555416057012132 0ustar bilbil#ifndef _SNDLIB_H #define _SNDLIB_H #include #ifndef _MSC_VER #include #endif #include #include #if ((!__NetBSD__) && ((_MSC_VER) || (!defined(__STC__)) || (defined(__STDC_VERSION__) && (__STDC_VERSION__ < 199901L)))) #define __func__ __FUNCTION__ #endif #if (!defined(M_PI)) #define M_PI 3.14159265358979323846264338327 #define M_PI_2 (M_PI / 2.0) #endif #define is_power_of_2(x) ((((x) - 1) & (x)) == 0) #define MUS_MAX_MALLOC_DEFAULT (1 << 26) #define MUS_MAX_TABLE_SIZE_DEFAULT (1024 * 1024 * 20) /* delay line allocation etc */ #ifndef SEEK_SET #define SEEK_SET 0 #define SEEK_END 2 #endif #ifdef _MSC_VER #ifdef FOPEN #undef FOPEN #endif #if USE_SND #define OPEN(File, Flags, Mode) snd_open((File), (Flags), 0) #else #define OPEN(File, Flags, Mode) open((File), (Flags)) #endif #else #if USE_SND #define OPEN(File, Flags, Mode) snd_open((File), (Flags), (Mode)) #else #define OPEN(File, Flags, Mode) open((File), (Flags), (Mode)) #endif #endif #if USE_SND #define FOPEN(File, Flags) snd_fopen((File), (Flags)) #define CREAT(File, Flags) snd_creat((File), (Flags)) #define REMOVE(OldF) snd_remove(OldF, IGNORE_CACHE) #define STRERROR(Err) snd_io_strerror() #define CLOSE(Fd, Name) snd_close(Fd, Name) #define FCLOSE(Fd, Name) snd_fclose(Fd, Name) #else #define FOPEN(File, Flags) fopen((File), (Flags)) #define CREAT(File, Flags) creat((File), (Flags)) #define REMOVE(OldF) remove(OldF) #define STRERROR(Err) strerror(Err) #define CLOSE(Fd, Name) close(Fd) #define FCLOSE(Fd, Name) fclose(Fd) #endif #ifndef S_set #if (!HAVE_EXTENSION_LANGUAGE) #define S_set "set-" #else #if HAVE_RUBY #define S_set "set_" #else #if HAVE_SCHEME #define S_set "set! " #else #if HAVE_FORTH #define S_set "set-" #endif #endif #endif #endif #endif #define MUS_LOOP_INFO_SIZE 8 #define MUS_ALSA_API 0 #define MUS_OSS_API 1 #define MUS_JACK_API 2 #define G7XX 0 #include "sndlib.h" #include "xen.h" #include "vct.h" #endif snd-16.1/generators.scm0000644000076400007640000063664112621406747013241 0ustar bilbil(provide 'snd-generators.scm) (if (provided? 'snd) (require snd-ws.scm) (require sndlib-ws.scm)) ;;; it is dangerous to use a method within a generator's definition of that method -- ;;; if the gen is used as the environment in with-let, the embedded call ;;; becomes a recursive call on that method. You either need to check the type ;;; of the method argument, or use #_method to override the name lookup, or use ;;; the explicit call style: (((gen 'embedded-gen) 'shared-method) ...) ;;; if gen has embedded gen, mus-copy needs a special copy method (see adjustable-oscil) ;;; a problem with a special copy method: if you change the generator, remember to change its copy method! ;;; also, I think (inlet e) is a way to copy e without accidentally invoking any 'copy method in e (define nearly-zero 1.0e-10) ; 1.0e-14 in clm.c, but that is trouble here (noddcos) (define two-pi (* 2.0 pi)) ;;; -------------------------------------------------------------------------------- ;;; nssb (see nxycos) -- wouldn't a more consistent name be nxycos? but it already exists -- perhaps delete nssb? (defgenerator (nssb :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) g)) (frequency *clm-default-frequency*) (ratio 1.0) (n 1) (angle 0.0) fm) (define nssb (let ((documentation "(make-nssb frequency (ratio 1.0) (n 1)) creates an nssb generator, similar to nxysin. (nssb gen (fm 0.0)) returns n sinusoids from frequency spaced by frequency * ratio.")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let* ((cx angle) (mx (* cx ratio)) (den (sin (* 0.5 mx)))) (set! angle (+ angle fm frequency)) (if (< (abs den) nearly-zero) -1.0 (/ (- (* (sin cx) (sin (* mx (/ (+ n 1) 2))) (sin (/ (* n mx) 2))) (* (cos cx) 0.5 (+ den (sin (* mx (+ n 0.5)))))) (* (+ n 1) den)))))))) #| (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-nssb 1000.0 0.1 3))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (nssb gen))))) (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-nssb 1000.0 0.1 3)) (vib (make-oscil 5.0)) (ampf (make-env '(0 0 1 1 2 1 3 0) :length 20000 :scaler 1.0))) (do ((i 0 (+ i 1))) ((= i 20000)) (outa i (* (env ampf) (nssb gen (* (hz->radians 100.0) (oscil vib)))))))) |# ;;; -------------------------------------------------------------------------------- ;;; G&R first col rows 1&2 (define (find-nxysin-max n ratio) (define (ns x n) (let* ((a2 (/ x 2)) (den (sin a2))) (if (= den 0.0) 0.0 (/ (* (sin (* n a2)) (sin (* (+ 1 n) a2))) den)))) (define (nodds x n) (let ((den (sin x)) (num (sin (* n x)))) (if (= den 0.0) 0.0 (/ (* num num) den)))) (define (find-mid-max n lo hi) (let ((mid (/ (+ lo hi) 2))) (let ((ylo (ns lo n)) (yhi (ns hi n))) (if (< (abs (- ylo yhi)) nearly-zero) ; was e-100 but that hangs if not using doubles (ns mid n) (if (> ylo yhi) (find-mid-max n lo mid) (find-mid-max n mid hi)))))) (define (find-nodds-mid-max n lo hi) (let ((mid (/ (+ lo hi) 2))) (let ((ylo (nodds lo n)) (yhi (nodds hi n))) (if (< (abs (- ylo yhi)) nearly-zero) (nodds mid n) (if (> ylo yhi) (find-nodds-mid-max n lo mid) (find-nodds-mid-max n mid hi)))))) (if (= ratio 1) (find-mid-max n 0.0 (/ pi (+ n .5))) (if (= ratio 2) (find-nodds-mid-max n 0.0 (/ pi (+ (* 2 n) 0.5))) n))) (defgenerator (nxysin :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) (set! (g 'norm) (/ 1.0 (find-nxysin-max (g 'n) (g 'ratio)))) g)) (frequency *clm-default-frequency*) (ratio 1.0) (n 1) (angle 0.0) fm (norm 1.0)) (define nxysin (let ((documentation "(make-nxysin frequency (ratio 1.0) (n 1)) creates an nxysin generator. (nxysin gen (fm 0.0)) returns n sines from frequency spaced by frequency * ratio.")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let* ((x angle) (y (* x ratio)) (den (sin (* y 0.5)))) (set! angle (+ angle fm frequency)) (if (< (abs den) nearly-zero) 0.0 (/ (* (sin (+ x (* 0.5 (- n 1) y))) (sin (* 0.5 n y)) norm) den))))))) ;;; if x (angle) is constant (an initial-phase offset for a sum of sines, ;;; the peak amp is nsin-max(n) + abs(sin(initial-phase))*(1 - nsin-max(n)) ;;; that is, it varys sinusoidally from a sum-of-sines .7245 to a sum-of-cosines 1 ;;; since we're treating "x" as the carrier (it's not a constant phase offset in this case) ;;; the output varies as x does, so we have a maxamp of n? There are special cases ;;; for low n and low integer ratio: ;;; ratio (4): (40): (400): ;;; 1: 3.23 29.34 290.1 ;;; 2: 2.9404 28.97 289.7 ;;; 3: 3.85 38.6 346.8 ;;; 1.123: n ;;; .5: 3.55 30.0 290 ;;; a ratio of 1 gives a sum of equal amplitude sines, so we could use nsin-max? ;;; 2 odd harmonics -- use noddsin? ;;; else use n (not so great for ratio: 3, but not way off) ;;; worst case right now is probably ratio .5 #| (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-nxysin 300 1/3 3))) (do ((i 0 (+ i 1))) ((= i 20000)) (outa i (nxysin gen))))) ;;; here's the varying initial-phase case: (with-sound (:clipped #f) (let ((x 0.0) (ix (/ pi 1000)) (n 100)) (do ((i 0 (+ i 1))) ((= i 1000)) (let ((pk 0.0) (phi x) (y 0.0) (iy (/ (* 2 pi) 10000))) (set! x (+ x ix)) (do ((k 0 (+ k 1))) ((= k 10000)) ;; x = phi (let ((den (sin (/ y 2)))) (if (not (= den 0.0)) (let ((sum (abs (/ (* (sin (+ phi (* y (/ (- n 1) 2)))) (sin (/ (* n y) 2))) den)))) (if (> sum pk) (set! pk sum))))) (set! y (+ y iy))) (outa i pk))))) |# (defgenerator (nxycos :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) g)) (frequency *clm-default-frequency*) (ratio 1.0) (n 1) (angle 0.0) fm) (define nxycos (let ((documentation "(make-nxycos frequency (ratio 1.0) (n 1)) creates an nxycos generator. (nxycos gen (fm 0.0)) returns n cosines from frequency spaced by frequency * ratio.")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let* ((x angle) (y (* x ratio)) (den (sin (* y 0.5)))) (set! angle (+ angle fm frequency)) (if (< (abs den) nearly-zero) 1.0 (/ (* (cos (+ x (* 0.5 (- n 1) y))) (sin (* 0.5 n y))) (* n den)))))))) ; n=normalization #| (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-nxycos 300 1/3 3))) (do ((i 0 (+ i 1))) ((= i 20000)) (outa i (* .5 (nxycos gen)))))) |# ;;; -------------------------------------------------------------------------------- ;;; ;;; G&R first col rows 3 4 (defgenerator (nxy1cos :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) g)) (frequency *clm-default-frequency*) (ratio 1.0) (n 1) (angle 0.0) fm) (define nxy1cos (let ((documentation "(make-nxy1cos frequency (ratio 1.0) (n 1)) creates an nxy1cos generator. (nxy1cos gen (fm 0.0)) returns 2n cosines from frequency spaced by frequency * ratio with every other cosine multiplied by -1.")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let* ((x angle) (y (* x ratio)) (den (cos (* y 0.5)))) (set! angle (+ angle fm frequency)) (if (< (abs den) nearly-zero) -1.0 (max -1.0 (min 1.0 (/ (* (sin (* n y)) (sin (+ x (* (- n 0.5) y)))) (* 2 n den)))))))))) #| (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-nxy1cos 300 1/3 3))) (do ((i 0 (+ i 1))) ((= i 20000)) (outa i (nxy1cos gen))))) (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-nxy1cos 300 1/3 3)) (gen1 (make-nxycos 300 1/3 6))) (do ((i 0 (+ i 1))) ((= i 20000)) (outa i (* 0.4 (+ (nxycos gen1 0.0) (nxy1cos gen))))))) (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-nxy1cos (radians->hz (* .01 pi)) 1.0 3))) (do ((i 0 (+ i 1))) ((= i 20000)) (outa i (nxy1cos gen))))) |# (defgenerator (nxy1sin :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) g)) (frequency *clm-default-frequency*) (ratio 1.0) (n 1) (angle 0.0) fm) (define nxy1sin (let ((documentation "(make-nxy1sin frequency (ratio 1.0) (n 1)) creates an nxy1sin generator. (nxy1sin gen (fm 0.0)) returns n sines from frequency spaced by frequency * ratio with every other sine multiplied by -1.")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let* ((x angle) (y (* x ratio)) (den (cos (* y 0.5)))) (set! angle (+ angle fm frequency)) (/ (* (sin (+ x (* 0.5 (- n 1) (+ y pi)))) (sin (* 0.5 n (+ y pi)))) (* n den))))))) #| (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-nxy1sin 300 1/3 3))) (do ((i 0 (+ i 1))) ((= i 20000)) (outa i (nxy1sin gen))))) |# ;;; we can get the sinusoidally varying maxamp by using e.g. (make-nxy1sin 1 1000 3) ;;; the peak starts at ca .72 and goes to 1 etc ;;; the peak is just offset from pi (either way) ;;; -------------------------------------------------------------------------------- ;;; n odd sinusoids: noddsin, noddcos, noddssb ;;; sndclm.html (G&R) first col 5th row (sum of odd sines) (define (find-noddsin-max n) (define (nodds x n) (let ((den (sin x)) (num (sin (* n x)))) (if (= den 0.0) 0.0 (/ (* num num) den)))) (define (find-mid-max n lo hi) (let ((mid (/ (+ lo hi) 2))) (let ((ylo (nodds lo n)) (yhi (nodds hi n))) (if (< (abs (- ylo yhi)) 1e-9) (nodds mid n) (if (> ylo yhi) (find-mid-max n lo mid) (find-mid-max n mid hi)))))) (find-mid-max n 0.0 (/ pi (+ (* 2 n) 0.5)))) (define noddsin-maxes (make-float-vector 100)) (defgenerator (noddsin :make-wrapper (lambda (g) (if (< (g 'n) 1) (set! (g 'n) 1)) (set! (g 'frequency) (hz->radians (g 'frequency))) (if (and (< (g 'n) 100) (> (noddsin-maxes (g 'n)) 0.0)) (set! (g 'norm) (/ 1.0 (noddsin-maxes (g 'n)))) (begin (set! (noddsin-maxes (g 'n)) (find-noddsin-max (g 'n))) (set! (g 'norm) (/ 1.0 (noddsin-maxes (g 'n)))))) g)) (frequency *clm-default-frequency*) (n 1) (angle 0.0) (norm 1.0) fm) (define noddsin (let ((documentation "(make-noddsin frequency (n 1)) creates an noddsin generator. (noddsin gen (fm 0.0)) returns n odd-numbered sines spaced by frequency.")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let ((snx (sin (* n angle))) (den (sin angle))) (set! angle (+ angle fm frequency)) (if (< (abs den) nearly-zero) 0.0 (/ (* norm snx snx) den))))))) ;;; max is at about: 3*pi/(8*n) -- essentially half of the nsin peak ;;; and we end up with the same max amp as nsin!! ;;; :(/ (* 8 (sin (* pi 3/8)) (sin (* pi 3/8))) (* 3 pi)) ;;; 7.245186202974229185687564326622851596478E-1 #| ;;; clarinety (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-noddsin 300 :n 3)) (ampf (make-env '(0 0 1 1 2 1 3 0) :length 40000 :scaler .5))) (do ((i 0 (+ i 1))) ((= i 40000)) (outa i (* (env ampf) (noddsin gen)))))) |# (defgenerator (noddcos :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) g)) (frequency *clm-default-frequency*) (n 1) (angle 0.0) fm) (define noddcos (let ((documentation "(make-noddcos frequency (n 1)) creates an noddcos generator. (noddcos gen (fm 0.0)) returns n odd-numbered cosines spaced by frequency.")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let ((cx angle) (den (* 2 n (sin angle)))) ; "n" here is normalization (set! angle (+ angle fm frequency)) (if (< (abs den) nearly-zero) (let ((fang (modulo (abs cx) (* 2 pi)))) ;; hopefully this almost never happens... (if (or (< fang 0.001) (< (abs (- fang (* 2 pi))) 0.001)) 1.0 -1.0)) (/ (sin (* 2 n cx)) den))))))) ;;; (Gradshteyn and Ryzhik 1.342) #| (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-noddcos 100 :n 10))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (* .5 (noddcos gen)))))) |# (defgenerator (noddssb :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) g)) (frequency *clm-default-frequency*) (ratio 1.0) (n 1) (angle 0.0) fm) (define noddssb (let ((documentation "(make-noddssb frequency (ratio 1.0) (n 1)) creates an noddssb generator. (noddssb gen (fm 0.0)) returns n sinusoids from frequency spaced by 2 * ratio * frequency.")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let* ((cx angle) (mx (* cx ratio)) (x (- cx mx)) (sinnx (sin (* n mx))) (den (* n (sin mx)))) ; "n" is normalization (set! angle (+ angle fm frequency)) (if (< (abs den) nearly-zero) (if (< (modulo (abs mx) (* 2 pi)) .1) -1.0 1.0) (- (* (sin x) (/ (* sinnx sinnx) den)) (* (cos x) (/ (sin (* 2 n mx)) (* 2 den)))))))))) #| (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-noddssb 1000.0 0.1 5))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (* .5 (noddssb gen)))))) (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-noddssb 1000.0 0.1 5)) (vib (make-oscil 5.0))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (* .5 (noddssb gen (* (hz->radians 100.0) (oscil vib)))))))) |# ;;; -------------------------------------------------------------------------------- ;;; ;;; various kernels: ncos2 = ncos squared (Fejer), ncos4 = ncos2 squared (Jackson), npcos = Poussin kernel (defgenerator (ncos2 :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) g)) (frequency *clm-default-frequency*) (n 1) (angle 0.0) fm) (define ncos2 (let ((documentation "(make-ncos2 frequency (n 1)) creates an ncos2 (Fejer kernel) generator. (ncos2 gen (fm 0.0)) returns n sinusoids spaced by frequency scaled by (n-k)/(n+1)")) ;; from "Trigonometric Series" Zygmund p88 with changes suggested by Katznelson "Introduction to Harmonic Analysis" p12, and ;; scaling by an extra factor of 1/n+1 to make sure we always peak at 1.0 (I assume callers in this context are interested ;; in the pulse-train aspect and want easily predictable peak amp). Harmonics go as (n-i)/n+1. (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let* ((x angle) (den (sin (* 0.5 x)))) (set! angle (+ angle fm frequency)) (if (< (abs den) nearly-zero) 1.0 (let ((val (/ (sin (* 0.5 (+ n 1) x)) (* (+ n 1) den)))) (* val val)))))))) ;;; can't use two oscils here because the angles have to line up perfectly #| (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-ncos2 100.0 :n 10))) (do ((i 0 (+ i 1))) ((= i 20000)) (outa i (* .5 (ncos2 gen)))))) |# (define make-ncos4 make-ncos2) ;; Katznelson p16 (define ncos4 (let ((documentation "(make-ncos4 frequency (n 1)) creates an ncos4 (Jackson kernel) generator. (ncos4 gen (fm 0.0)) returns n sinusoids spaced by frequency scaled by ((n-k)/(n+1))^2")) (lambda* (gen (fm 0.0)) (let ((val (ncos2 gen fm))) (* val val))))) ; we already normalized this to 1.0 #| (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-ncos4 100.0 :n 10))) (do ((i 0 (+ i 1))) ((= i 20000)) (outa i (* .5 (ncos4 gen)))))) |# (defgenerator (npcos :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) g)) (frequency *clm-default-frequency*) (n 1) (angle 0.0) fm) (define npcos (let ((documentation "(make-npcos frequency (n 1)) creates an npcos (Poussin kernel) generator. (npcos gen (fm 0.0)) returns n*2+1 sinusoids spaced by frequency with amplitudes in a sort of tent shape.")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let* ((den (sin (* 0.5 angle))) (result (if (< (abs den) nearly-zero) 1.0 (let* ((n1 (+ n 1)) (result1 (let ((val (/ (sin (* 0.5 n1 angle)) (* n1 den)))) (* val val))) (p2n2 (+ (* 2 n) 2)) (result2 (let ((val (/ (sin (* 0.5 p2n2 angle)) (* p2n2 den)))) (* val val)))) (- (* 2 result2) result1))))) (set! angle (+ angle fm frequency)) result))))) #| (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-npcos 100.0 :n 10))) (do ((i 0 (+ i 1))) ((= i 20000)) (outa i (* .5 (npcos gen)))))) |# #| ;;; ncos5 and nsin5 are minor variants of nsin and ncos -- the last component is at half amplitude (defgenerator (ncos5 :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) g)) (frequency *clm-default-frequency*) (n 1) (angle 0.0) fm) (define ncos5 (let ((documentation "(make-ncos5 frequency (n 1)) creates an ncos5 generator. (ncos5 gen (fm 0.0)) returns n cosines spaced by frequency. All are equal amplitude except the first and last at half amp.")) ;; from "Chebyshev Polynomials", Mason and Handscomb, p87 (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let* ((x angle) (den (tan (* 0.5 x)))) (set! angle (+ angle fm frequency)) (if (< (abs den) nearly-zero) 1.0 (/ (- (/ (sin (* n x)) (* 2 den)) 0.5) (- n 0.5)))))))) (with-sound (:clipped #f :statistics #t) (let ((gen (make-ncos5 100.0 :n 10))) (do ((i 0 (+ i 1))) ((= i 20000)) (outa i (* .5 (ncos5 gen)))))) (define (find-nsin5-max n) (define (ns x n) (let* ((den (tan (* 0.5 x)))) (if (< (abs den) nearly-zero) 0.0 (/ (- 1.0 (cos (* n x))) den)))) (define (find-mid-max n lo hi) (let ((mid (/ (+ lo hi) 2))) (let ((ylo (ns lo n)) (yhi (ns hi n))) (if (< (abs (- ylo yhi)) 1e-9) (ns mid n) (if (> ylo yhi) (find-mid-max n lo mid) (find-mid-max n mid hi)))))) (find-mid-max n 0.0 (/ pi (+ n .5)))) (defgenerator (nsin5 :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) (set! (g 'n) (max 2 (g 'n))) (set! (g 'norm) (find-nsin5-max (g 'n))) g)) (frequency *clm-default-frequency*) (n 2) (angle 0.0) (norm 1.0) fm) (define nsin5 (let ((documentation "(make-nsin5 frequency (n 1)) creates an nsin5 generator. (nsin5 gen (fm 0.0)) returns n sines spaced by frequency. All are equal amplitude except last at half amp.")) ;; from "Chebyshev Polynomials", Mason and Handscomb, p100 (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let* ((x angle) (den (tan (* 0.5 x)))) (set! angle (+ angle fm frequency)) (if (< (abs den) nearly-zero) 0.0 (/ (- 1.0 (cos (* n x))) (* den norm)))))))) (define (find-nsin-max n) (define (ns x n) (let* ((a2 (/ x 2)) (den (sin a2))) (if (= den 0.0) 0.0 (/ (* (sin (* n a2)) (sin (* (+ 1 n) a2))) den)))) (define (find-mid-max n lo hi) (let ((mid (/ (+ lo hi) 2))) (let ((ylo (ns lo n)) (yhi (ns hi n))) (if (< (abs (- ylo yhi)) 1e-14) (ns mid n) ; rationalize (/ mid pi) for location (if (> ylo yhi) (find-mid-max n lo mid) (find-mid-max n mid hi)))))) (find-mid-max n 0.0 (/ pi (+ n .5)))) (with-sound (:clipped #f :statistics #t) (let ((gen (make-nsin5 100.0 :n 10))) (do ((i 0 (+ i 1))) ((= i 20000)) (outa i (nsin5 gen))))) (let ((norms (list 1.0 0.0))) (do ((i 2 (+ i 1))) ((= i 40)) (let* ((res (with-sound (:clipped #f) (let ((gen (make-nsin5 100.0 :n i))) (do ((i 0 (+ i 1))) ((= i 20000)) (outa i (nsin5 gen)))))) (snd (find-sound res))) (format #t ";~D: ~A" i (maxamp snd 0)) (set! norms (cons (maxamp snd 0) norms)))) (reverse norms)) ;;; from the same book p 110 is atan(x)/x, if x=cos we get: (with-sound (:clipped #f :statistics #t) (let* ((x 0.0) (freq (hz->radians 100.0))) (do ((i 0 (+ i 1))) ((= i 20000)) (outa i (/ (- (/ (atan (cos x)) (cos x)) (* 0.5 1.76275)) -0.1187)) (set! x (+ x freq))))) (let ((sum 0.0)) (do ((s 1 (+ s 2))) ((>= s 100)) (set! sum (+ sum (* 4 (/ (expt (- (sqrt 2.0) 1.0) (+ (* 2 s) 1)) (+ (* 2 s) 1)))))) sum) ; ~ 0.096 ;;; the evens cancel, each of the odds gets through once |# (define generator-max-r 0.999999) (define generator-min-r -0.999999) (define (generator-clamp-r r) (min generator-max-r (max generator-min-r r))) ;;; -------------------------------------------------------------------------------- ;;; ;;; n sinusoids scaled by r: nrsin, nrcos, nrssb #| (define nrsin-methods (list (cons 'mus-frequency (dilambda (lambda (g) (mus-frequency (g 'gen))) (lambda (g val) (set! (mus-frequency (g 'gen)) val)))) (cons 'mus-scaler (dilambda (lambda (g) (mus-scaler (g 'gen))) (lambda (g val) (set! (mus-scaler (g 'gen)) val)))))) (defgenerator (nrsin :make-wrapper (lambda (g) (set! (g 'r) (generator-clamp-r (g 'r))) (set! (g 'gen) (make-nrxysin (g 'frequency) 1.0 (g 'n) (g 'r))) g) :methods nrsin-methods) (frequency *clm-default-frequency*) (n 1) (r 0.5) (gen #f)) |# (define make-nrsin make-nrxysin) (define nrsin nrxysin) (define nrsin? nrxysin?) ;; "(make-nrsin frequency (n 1) (r 0.5)) creates an nrsin generator.\n\ ;; (nrsin gen (fm 0.0)) returns n sines spaced by frequency with amplitudes scaled by r^k." (define (nrcos-set-scaler g val) (set! (g 'r) (min 0.999999 (max -0.999999 val))) (with-let g (let ((absr (abs r))) (set! rr (* r r)) (set! r1 (+ 1.0 rr)) (set! norm (- (/ (- (expt absr n) 1) (- absr 1)) 1.0)) (set! trouble (or (= n 1) (< absr 1.0e-12))))) val) (define nrcos-methods (list (cons 'mus-order (dilambda (lambda (g) (- (g 'n) 1)) (lambda (g val) (set! (g 'n) (+ 1 val)) (set! (g 'e1) (expt (g 'r) (g 'n))) (set! (g 'e2) (expt (g 'r) (+ (g 'n) 1))) (set! (g 'norm) (- (/ (- (expt (abs (g 'r)) (g 'n)) 1) (- (abs (g 'r)) 1)) 1.0)) (set! (g 'trouble) (or (= (g 'n) 1) (< (abs (g 'r)) nearly-zero))) val))) (cons 'mus-frequency (dilambda (lambda (g) (radians->hz (g 'frequency))) (lambda (g val) (set! (g 'frequency) (hz->radians val))))) (cons 'mus-scaler (dilambda (lambda (g) (g 'r)) nrcos-set-scaler)))) (defgenerator (nrcos :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) (set! (g 'n) (+ 1 (g 'n))) (set! (g 'r) (generator-clamp-r (g 'r))) (set! (g 'rr) (* (g 'r) (g 'r))) (set! (g 'r1) (+ 1.0 (g 'rr))) (set! (g 'e1) (expt (g 'r) (g 'n))) (set! (g 'e2) (expt (g 'r) (+ (g 'n) 1))) (set! (g 'norm) (- (/ (- (expt (abs (g 'r)) (g 'n)) 1) (- (abs (g 'r)) 1)) 1.0)) ; n+1?? (set! (g 'trouble) (or (= (g 'n) 1) (< (abs (g 'r)) nearly-zero))) g) :methods nrcos-methods) (frequency *clm-default-frequency*) (n 1) (r 0.5) (angle 0.0) fm rr r1 e1 e2 norm trouble) (define nrcos (let ((documentation "(make-nrcos frequency (n 1) (r 0.5)) creates an nrcos generator. (nrcos gen (fm 0.0)) returns n cosines spaced by frequency with amplitudes scaled by r^k.")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let ((x angle) (rcos (* r (cos angle)))) (set! angle (+ angle fm frequency)) (if trouble 0.0 (/ (+ (- rcos (* e1 (cos (* n x))) rr) (* e2 (cos (* (- n 1) x)))) (* norm (+ r1 (* -2.0 rcos)))))))))) ;; it's faster to use polywave here and nrcos->polywave for the partials list (animals.scm) if n is not enormous ;;; formula changed to start at k=1 and n increased so we get 1 to n ;;; here is the preoptimization form: #| (with-let gen (let ((x angle)) (set! angle (+ angle fm frequency)) (if (or (= n 1) (< (abs r) nearly-zero)) 0.0 (let ((norm (- (/ (- (expt (abs r) n) 1) (- (abs r) 1)) 1.0))) ; n+1?? (/ (+ (- (* r (cos x)) (* (expt r n) (cos (* n x))) (* r r)) (* (expt r (+ n 1)) (cos (* (- n 1) x)))) (* norm (+ 1.0 (* -2.0 r (cos x)) (* r r)))))))) |# #| (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-nrcos 400.0 :n 5 :r 0.5))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (* .5 (nrcos gen)))))) (with-sound (:clipped #f :statistics #t :play #t :scaled-to .1) (let ((gen (make-nrcos 1200.0 :n 3 :r 0.99)) (mod (make-oscil 400.0)) ; multi-carrier fm (index 0.01)) (do ((i 0 (+ i 1))) ((= i 30000)) (outa i (nrcos gen (* index (oscil mod))))))) (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-nrcos 2000.0 :n 3 :r 0.5)) (mod (make-oscil 400.0)) ; multi-carrier fm (index 0.02)) (do ((i 0 (+ i 1))) ((= i 30000)) (outa i (* .5 (nrcos gen (* index (oscil mod)))))))) (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-nrcos 2000.0 :n 3 :r 0.5)) (mod (make-oscil 400.0)) (index (make-env '(0 0 1 .1) :length 30000))) ; or '(0 .4 1 0) (do ((i 0 (+ i 1))) ((= i 30000)) (outa i (* .5 (nrcos gen (* (env index) (oscil mod)))))))) |# (definstrument (lutish beg dur freq amp) (let ((res1 (max 1 (round (/ 1000.0 (max 1.0 (min 1000.0 freq)))))) (maxind (max .01 (min .3 (/ (- (log freq) 3.5) 8.0))))) (let ((gen (make-nrcos (* freq res1) :n (max 1 (- res1 2)))) (mod (make-oscil freq)) (start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (index (make-env (list 0 maxind 1 (* maxind .25) (max dur 2.0) 0.0) :duration dur)) (amplitude (make-env (list 0 0 .01 1 .2 1 .5 .5 1 .25 (max dur 2.0) 0.0) :duration dur :scaler amp))) (do ((i start (+ i 1))) ((= i stop)) (let ((ind (env index))) (set! (gen 'r) ind) (outa i (* (env amplitude) (nrcos gen (* ind (oscil mod)))))))))) #| (with-sound (:clipped #f :statistics #t :play #t) (lutish 0 1 440 .1)) (with-sound (:clipped #f :statistics #t :play #t) (do ((i 0 (+ i 1))) ((= i 10)) (lutish (* i .1) 2 (* 100 (+ i 1)) .05))) |# ;;; G&R second col first and second rows (defgenerator (nrssb :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) (set! (g 'r) (generator-clamp-r (g 'r))) (if (< (g 'r) 0.0) (set! (g 'r) 0.0)) (set! (g 'rn) (- (expt (g 'r) (g 'n)))) (set! (g 'rn1) (expt (g 'r) (+ (g 'n) 1))) (set! (g 'norm) (/ (- (g 'rn) 1) (- (g 'r) 1))) g)) (frequency *clm-default-frequency*) (ratio 1.0) (n 1) (r 0.5) (angle 0.0) fm interp rn rn1 norm) (define nrssb (let ((documentation "(make-nrssb frequency (ratio 1.0) (n 1) (r 0.5)) creates an nrssb generator. (nrssb gen (fm 0.0)) returns n sinusoids from frequency spaced by frequency * ratio with amplitudes scaled by r^k.")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let* ((cx angle) (mx (* cx ratio))) (let ((nmx (* n mx)) (n1mx (* (- n 1) mx)) (den (* norm (+ 1.0 (* -2.0 r (cos mx)) (* r r))))) (set! angle (+ angle fm frequency)) (/ (- (* (sin cx) (+ (* r (sin mx)) (* rn (sin nmx)) (* rn1 (sin n1mx)))) (* (cos cx) (+ 1.0 (* -1.0 r (cos mx)) (* rn (cos nmx)) (* rn1 (cos n1mx))))) den))))))) (define nrssb-interp (let ((documentation "(make-nrssb frequency (ratio 1.0) (n 1) (r 0.5)) creates an nrssb generator for use with nrssb-interp. (nrssb-interp gen fm interp) returns n sinusoids from frequency spaced by frequency * ratio with amplitudes scaled by r^k. The 'interp' argument determines whether the sidebands are above (1.0) or below (-1.0) frequency.")) (lambda (gen fm interp) (let-set! gen 'fm fm) (let-set! gen 'interp interp) (with-let gen (let* ((cx angle) (mx (* cx ratio))) (let ((nmx (* n mx)) (n1mx (* (- n 1) mx)) (den (* norm (+ 1.0 (* -2.0 r (cos mx)) (* r r))))) (set! angle (+ angle fm frequency)) (/ (- (* interp (sin cx) (+ (* r (sin mx)) (* rn (sin nmx)) (* rn1 (sin n1mx)))) (* (cos cx) (+ 1.0 (* -1.0 r (cos mx)) (* rn (cos nmx)) (* rn1 (cos n1mx))))) den))))))) #| (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-nrssb 1000 0.1 5 0.5))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (nrssb gen))))) (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-nrssb 1000 0.1 5 0.5)) (vib (make-oscil 5))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (nrssb gen (* (hz->radians 100) (oscil vib))))))) |# (definstrument (oboish beg dur freq amp aenv) (let ((res1 (max 1 (round (/ 1400.0 (max 1.0 (min 1400.0 freq)))))) (mod1 (make-oscil 5.0)) (res2 (max 1 (round (/ 2400.0 (max 1.0 (min 2400.0 freq)))))) (gen3 (make-oscil freq)) (start (seconds->samples beg)) (amplitude (make-env aenv :duration dur :base 4 :scaler amp)) (skenv (make-env (list 0.0 0.0 1 1 2.0 (mus-random 1.0) 3.0 0.0 (max 4.0 (* dur 20.0)) 0.0) :duration dur :scaler (hz->radians (random (* freq .05))))) (relamp (+ .85 (random .1))) (avib (make-rand-interp 5 .2)) (hfreq (hz->radians freq)) (h3freq (hz->radians (* .003 freq))) (scl (/ 0.05 amp))) (let ((gen (make-nrssb (* freq res1) (/ res1) :n res1 :r 0.75)) (gen2 (make-oscil (* freq res2))) (stop (+ start (seconds->samples dur)))) (do ((i start (+ i 1))) ((= i stop)) (let* ((vol (* (+ .8 (rand-interp avib)) (env amplitude))) (vib (+ (* h3freq (oscil mod1)) (env skenv))) (vola (* scl vol)) (result (* vol (+ (* (- relamp vola) (nrssb-interp gen (* res1 vib) -1.0)) (* (+ (- 1.0 relamp) vola) (oscil gen2 (+ (* vib res2) (* hfreq (oscil gen3 vib))))))))) (outa i result) (if *reverb* (outa i (* .01 result) *reverb*))))))) #| (with-sound (:clipped #f :statistics #t :play #t) (oboish 0 1 300 .1 '(0 0 1 1 2 0))) (with-sound (:clipped #f :statistics #t :play #t) (do ((i 0 (+ i 1))) ((= i 10)) (oboish (* i .3) .4 (+ 100 (* 50 i)) .05 '(0 0 1 1 2 1 3 0)))) (with-sound (:clipped #f :statistics #t :play #t) (let ((rats (vector 1 256/243 9/8 32/27 81/64 4/3 1024/729 3/2 128/81 27/16 16/9 243/128 2)) (mode (vector 0 0 2 4 11 11 5 6 7 9 2 12 0))) (do ((i 0 (+ i 1))) ((= i 20)) (oboish (/ (random 32) 8) (/ (+ 3 (random 8)) 8) (* 16.351 16 (rats (mode (random 12)))) (+ .25 (random .25)) (let* ((pt1 (random 1.0)) (pt2 (+ pt1 (random 1.0))) (pt3 (+ pt2 (random 1.0)))) (list 0 0 pt1 1 pt2 .5 pt3 0)))))) ;;; .85 .15 (* 2 freq) 300, 2400 + 0.5*vib |# ;;; -------------------------------------------------------------------------------- ;;; ;;; n sinusoids scaled by k: nkssb ;;; G&R first col ksinkx cases (define nkssb-methods (list (cons 'mus-order (dilambda (lambda (g) (- (g 'n) 1)) (lambda (g val) (set! (g 'n) (+ 1 val)) (set! (g 'norm) (/ (* 0.5 val (- val 1))))))))) ; nominal n is off by 1 (defgenerator (nkssb :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) (set! (g 'n) (+ 1 (g 'n))) ; sum goes 1 to n-1 (set! (g 'norm) (/ (* 0.5 (g 'n) (- (g 'n) 1)))) g) :methods nkssb-methods) (frequency *clm-default-frequency*) (ratio 1.0) (n 1) (angle 0.0) fm interp norm) (define nkssb (let ((documentation "(make-nkssb frequency (ratio 1.0) (n 1)) creates an nkssb generator. (nkssb gen (fm 0.0)) returns n sinusoids from frequency spaced by frequency * ratio with amplitude k.")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let ((x (* angle ratio))) (let ((cxx (- angle x)) (sx2 (sin (* 0.5 x))) (nx (* n x)) (nx2 (* 0.5 (- (* 2 n) 1) x))) (let ((sx22 (* 2 sx2)) (sxsx (* 4 sx2 sx2))) (set! angle (+ angle fm frequency)) (if (< (abs sx2) 1.0e-8) -1.0 (let ((s1 (- (/ (sin nx) sxsx) (/ (* n (cos nx2)) sx22))) (c1 (- (/ (* n (sin nx2)) sx22) (/ (- 1.0 (cos nx)) sxsx)))) (* (- (* s1 (sin cxx)) (* c1 (cos cxx))) norm)))))))))) (define nkssb-interp (let ((documentation " (make-nkssb-interp frequency (ratio 1.0) (n 1)) creates an nkssb generator for nkssb-interp. (nkssb-interp gen fm interp) returns n sinusoids from frequency spaced by frequency * ratio with amplitude k. The 'interp' argument determines whether the sidebands are above (1.0) or below (-1.0) frequency.")) (lambda (gen fm interp) (let-set! gen 'fm fm) (let-set! gen 'interp interp) (with-let gen (let ((x (* angle ratio))) (let ((cxx (- angle x)) (sx2 (sin (* 0.5 x)))) (let ((sx22 (* 2 sx2)) (sxsx (* 4 sx2 sx2)) (nx (* n x)) (nx2 (* 0.5 (- (* 2 n) 1) x))) (set! angle (+ angle fm frequency)) (if (< (abs sx2) 1.0e-8) 1.0 (let ((s1 (- (/ (sin nx) sxsx) (/ (* n (cos nx2)) sx22))) (c1 (- (/ (* n (sin nx2)) sx22) (/ (- 1.0 (cos nx)) sxsx)))) (* (- (* c1 (cos cxx)) (* interp (sin cxx) s1)) norm)))))))))) ; peak seems to be solid right through the interpolation #| (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-nkssb 1000.0 0.1 5))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (nkssb gen))))) (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-nkssb 1000.0 0.1 5)) (vib (make-oscil 5.0)) (vibamp (hz->radians 50.0))) (do ((i 0 (+ i 1))) ((= i 30000)) (outa i (nkssb gen (* vibamp (oscil vib))))))) |# (definstrument (nkssber beg dur freq mfreq n vibfreq amp) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (gen (make-nkssb freq (/ mfreq freq) n)) (move (make-env '(0 1 1 -1) :duration dur)) (vib (make-polywave vibfreq (list 1 (hz->radians (* (/ freq mfreq) 5.0))) mus-chebyshev-second-kind)) (ampf (make-env '(0 0 1 1 5 1 6 0) :scaler amp :duration dur))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (nkssb-interp gen (polywave vib) (env move))) ; interp env )))) #| (with-sound (:play #t) (nkssber 0 1 1000 100 5 5 0.5) (nkssber 1 2 600 100 4 1 0.5) (nkssber 3 2 1000 540 3 3 0.5) (nkssber 5 4 300 120 2 0.25 0.5) (nkssber 9 1 30 4 40 0.5 0.5) (nkssber 10 1 20 6 80 0.5 0.5)) (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-nkssb 1000.0 0.1 5)) (move (make-env '(0 1 1 -1) :length 30000)) (vib (make-oscil 5.0)) (vibamp (hz->radians 50.0))) (do ((i 0 (+ i 1))) ((= i 30000)) (outa i (* 0.5 (nkssb-interp gen (* vibamp (oscil vib)) (env move))) ; interp env )))) (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-nkssb 600.0 1/6 4)) (vib (make-oscil 1.0)) (vibamp (hz->radians 30.0))) (do ((i 0 (+ i 1))) ((= i 100000)) (let ((intrp (oscil vib))) (outa i (* 0.5 (nkssb-interp gen (* vibamp intrp) intrp))))))) (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-nkssb 1000.0 (/ 540 1000) 3)) (vib (make-oscil 3.0)) ; 0.3 or 125 + 0.25 and 2 -> circling sound (vibamp (hz->radians (* (/ 1000 540) 5.0)))) (do ((i 0 (+ i 1))) ((= i 100000)) (let ((intrp (oscil vib))) (outa i (* 0.5 (nkssb-interp gen (* vibamp intrp) intrp))))))) (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-nkssb 300.0 (/ 120 300) 2)) (vib (make-oscil 0.25)) (vibamp (hz->radians (* (/ 300 120) 5.0)))) (do ((i 0 (+ i 1))) ((= i 300000)) (let ((intrp (oscil vib))) (outa i (* 0.5 (nkssb-interp gen (* vibamp intrp) intrp))))))) (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-nkssb 30.0 (/ 4 30) 40)) (vib (make-oscil 0.5)) (vibamp (hz->radians (* (/ 30 4) 5.0)))) (do ((i 0 (+ i 1))) ((= i 300000)) (let ((intrp (oscil vib))) (outa i (* 0.5 (nkssb-interp gen (* vibamp intrp) intrp))))))) (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-nkssb 20.0 (/ 6 20) 80)) ; 120 8 80 (100), 6 400 (vib (make-oscil 0.5)) (vibamp (hz->radians (* (/ 20 6) 5.0)))) (do ((i 0 (+ i 1))) ((= i 300000)) (let ((intrp (oscil vib))) (outa i (* 0.5 (nkssb-interp gen (* vibamp intrp) intrp))))))) |# ;;; -------------------------------------------------------------------------------- ;;; n cos scaled by sin(k*pi/(n+1))/sin(pi/(n+1)) ;;; "Biased Trigonometric Polynomials", Montgomery and Vorhauer ;;; American Math Monthly vol 114 no 9 Nov 2007 (defgenerator (nsincos :make-wrapper (lambda (g) (let ((n (g 'n))) (set! (g 'frequency) (hz->radians (g 'frequency))) (set! (g 'n2) (/ (+ n 1) 2)) (set! (g 'cosn) (cos (/ pi (+ n 1)))) (do ((k 1 (+ k 1))) ((> k n)) (set! (g 'norm) (+ (g 'norm) (/ (sin (/ (* k pi) (+ n 1))) (sin (/ pi (+ n 1))))))) g))) (frequency *clm-default-frequency*) (n 1) (angle 0.0) (n2 1.0) (cosn 1.0) (norm 0.0) fm) (define nsincos (let ((documentation "(make-nsincos frequency (n 1)) creates an nsincos generator. (nsincos gen (fm 0.0)) returns n cosines spaced by frequency with amplitude sin(k*pi/(n+1))/sin(pi/(n+1))")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let* ((x angle) (num (cos (* n2 x)))) (set! angle (+ angle fm frequency)) (/ (* num num) (* norm (- (cos x) cosn)))))))) #| (with-sound (:clipped #f :statistics #t :play #f) (let ((gen (make-nsincos 100.0 3))) (do ((i 0 (+ i 1))) ((= i 20000)) (outa i (nsincos gen))))) |# ;;; -------------------------------------------------------------------------------- ;;; ;;; Ramanujan, "On certain Arithmetical Functions" (defgenerator (n1cos :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) g)) (frequency *clm-default-frequency*) (n 1) (angle 0.0) fm) (define* (n1cos gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let* ((x angle) (tn (tan (* 0.5 x)))) (set! angle (+ angle fm frequency)) (if (< (abs tn) 1.0e-6) 1.0 (/ (- 1.0 (cos (* n x))) (* tn tn n n 2)))))) ; normalization -- this still has the very large DC term #| (with-sound (:clipped #f) (let ((gen (make-n1cos 100.0 10))) (do ((i 0 (+ i 1))) ((= i 44100)) (outa i (n1cos gen))))) |# #| ;;; -------------------------------------------------------------------------------- ;;; not sure the next two are interesting -- 2 more kernels ;;; Dimitrov and Merlo (defgenerator (npos1cos :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) g)) (frequency *clm-default-frequency*) (n 1) (angle 0.0) fm) (define npos1cos (let ((documentation "(make-npos1cos frequency (n 1)) creates an npos1cos generator. (npos1cos gen (fm 0.0)) returns n cosines spaced by frequency.")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let* ((x angle) (num (- (* (+ n 2) (sin (/ (* n x) 2))) (* n (sin (/ (* (+ n 2) x) 2))))) (sx (sin (/ x 2))) (den (* 4 n (+ n 1) (+ n 2) sx sx sx sx))) (set! angle (+ angle fm frequency)) (if (< (abs den) nearly-zero) 0.0 (/ (* 3 num num) den))))))) ;;; needs normalization and no DC. side amps seem close (with-sound (:clipped #f :statistics #t :play #f) (let ((gen (make-npos1cos 100.0 3))) (do ((i 0 (+ i 1))) ((= i 20000)) (outa i (npos1cos gen))))) (defgenerator (npos3cos :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) g)) (frequency *clm-default-frequency*) (n 1) (angle 0.0) fm) (define npos3cos (let ((documentation "(make-npos3cos frequency (n 1)) creates an npos3cos generator. (npos3cos gen (fm 0.0)) returns n cosines spaced by frequency.")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let* ((x angle) (sx (sin (/ x 2))) (den (* (+ (* 4 n) 2) sx sx))) (set! angle (+ angle fm frequency)) (if (< (abs den) nearly-zero) (* 1.0 n) (/ (- 2 (cos (* n x)) (cos (* (+ n 1) x))) den))))))) ;;; needs normalization and no DC, peak at den=0 not right. side amps seem close (with-sound (:clipped #f :statistics #t :play #f) (let ((gen (make-npos3cos 100.0 3))) (do ((i 0 (+ i 1))) ((= i 20000)) (outa i (npos3cos gen))))) |# ;;; -------------------------------------------------------------------------------- ;;; ;;; inf sinusoids scaled by r: rcos, rssb (define rcos-methods (list (cons 'mus-frequency (dilambda (lambda (g) (mus-frequency (g 'osc))) (lambda (g val) (set! (mus-frequency (g 'osc)) val)))) (cons 'mus-scaler (dilambda (lambda (g) (g 'r)) (lambda (g val) (set! (g 'r) (generator-clamp-r val)) (set! (g 'rr) (* (g 'r) (g 'r))) (set! (g 'rr+1) (+ 1.0 (g 'rr))) (set! (g 'rr-1) (- 1.0 (g 'rr))) (set! (g 'r2) (* 2.0 (g 'r))) (let ((absr (abs (g 'r)))) (if (< absr nearly-zero) (set! (g 'norm) 0.0) (set! (g 'norm) (/ (- 1.0 absr) (* 2.0 absr))))) val))) (cons 'mus-phase (dilambda (lambda (g) (mus-phase (g 'osc))) (lambda (g val) (set! (mus-phase (g 'osc)) val)))))) (defgenerator (rcos :make-wrapper (lambda (g) (set! (g 'osc) (make-oscil (g 'frequency) (* 0.5 pi))) (set! (g 'r) (generator-clamp-r (g 'r))) (set! (g 'rr) (* (g 'r) (g 'r))) (set! (g 'rr+1) (+ 1.0 (g 'rr))) (set! (g 'rr-1) (- 1.0 (g 'rr))) (set! (g 'r2) (* 2.0 (g 'r))) (let ((absr (abs (g 'r)))) (if (< absr nearly-zero) (set! (g 'norm) 0.0) (set! (g 'norm) (/ (- 1.0 absr) (* 2.0 absr))))) g) :methods rcos-methods) (frequency *clm-default-frequency*) (r 0.5) fm (osc #f) rr norm rr+1 rr-1 r2) (define rcos (let ((documentation "(make-rcos frequency (r 0.5)) creates an rcos generator. (rcos gen (fm 0.0)) returns many cosines spaced by frequency with amplitude r^k.")) ;; from Andrews, Askey, Roy "Special Functions" 5.1.16, p243. r^k cos sum ;; a variant of the G&R second col 4th row (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (* (- (/ rr-1 (- rr+1 (* r2 (oscil osc fm)))) 1.0) norm))))) #| (with-let gen (let ((absr (abs r)) (rr (* r r))) (if (< absr nearly-zero) 0.0 ; 1.0 from the formula, but we're subtracting out DC (* (- (/ (- 1.0 rr) (- (+ 1.0 rr) (* 2.0 r (oscil osc fm)))) 1.0) (/ (- 1.0 absr) (* 2.0 absr))))))) ; normalization |# #| ;;; G&R form: (define* (rcos gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let* ((absr (abs r)) (rcosx (* r (oscil osc fm)))) (* (- (/ (- 1.0 rcosx) (+ 1.0 (* r r) (* -2.0 rcosx))) 1.0) (/ (- 1.0 absr) absr))))) ; normalization |# ;;; if r>0 we get the spike at multiples of 2pi, since the k*pi case is flipping -1 1 -1 etc ;;; if r<0, we get the spike at multiples of (2k-1)pi since the r sign now counteracts the cos k*pi sign ;;; so the peak amp is the same in the two cases, so the normalization has to use abs(r)! ;;; but in the k*pi case we tend to miss k*pi (whereas we never miss 0 since we start there), ;;; so the actual maxamp may be less than 1.0 #| (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-rcos 100.0 :r 0.5))) (do ((i 0 (+ i 1))) ((= i 20000)) (outa i (rcos gen))))) |# ;; this uses rkoddssb below (definstrument (stringy beg dur freq amp) (let ((n (floor (/ *clm-srate* (* 3 freq))))) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (r (expt .001 (/ n)))) (let ((carrier (make-rcos freq (* .5 r))) (clang (make-rkoddssb (* freq 2) (/ 1.618 2) r)) (ampf (make-env '(0 0 1 1 2 .5 4 .25 10 0) :scaler amp :duration dur)) (clangf (make-env (list 0 0 .1 1 .2 .1 .3 0) :scaler (* amp .5) :duration .1)) (rf (make-env (list 0 1 1 0) :scaler (* 0.5 r) :duration dur)) (crf (make-env (list 0 1 1 0) :scaler r :duration .1))) (let ((set-clang-scaler (procedure-setter (clang 'mus-scaler)))) (do ((i start (+ i 1))) ((= i stop)) (set-clang-scaler clang (env crf)) ;(set! (mus-scaler clang) (env crf)) (set! (carrier 'r) (env rf)) (outa i (+ (* (env clangf) (rkoddssb clang 0.0)) (* (env ampf) (rcos carrier 0.0)))))))))) #| (with-sound (:clipped #f :statistics #t :play #t) (stringy 0 1 1000 .5)) (with-sound (:clipped #f :statistics #t :play #t) (do ((i 0 (+ i 1))) ((= i 10)) (stringy (* i .3) .3 (+ 200 (* 100 i)) .5))) |# (define rssb-methods (list (cons 'mus-scaler (dilambda (lambda (g) (g 'r)) (lambda (g val) (set! (g 'r) (generator-clamp-r val))))))) (defgenerator (rssb :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) (set! (g 'r) (generator-clamp-r (g 'r))) g) :methods rssb-methods) (frequency *clm-default-frequency*) (ratio 1.0) (r 0.5) (angle 0.0) fm interp) (define rssb (let ((documentation "(make-rssb frequency (ratio 1.0) (r 0.5)) creates an rssb generator. (rssb gen (fm 0.0)) returns many cosines from frequency spaced by frequency * ratio with amplitude r^k.")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let* ((angle1 angle) (angle2 (* angle1 ratio)) (carsin (sin angle1)) (canrcos (cos angle1)) (den (+ 1.0 (* r r) (* -2.0 r (cos angle2)))) (sumsin (* r (sin angle2))) (sumcos (- 1.0 (* r (cos angle2))))) (set! angle (+ angle1 fm frequency)) (/ (- (* carsin sumsin) (* canrcos sumcos)) (* 2 den))))))) (define rssb-interp (let ((documentation "(make-rssb frequency (ratio 1.0) (r 0.5)) creates an rssb generator for rssb-interp. (rssb-interp gen fm interp) returns many cosines from frequency spaced by frequency * ratio with amplitude r^k. The 'interp' argument determines whether the sidebands are above (1.0) or below (-1.0) frequency.")) (lambda (gen fm interp) (let-set! gen 'fm fm) (let-set! gen 'interp interp) (with-let gen (let* ((angle1 angle) (angle2 (* angle1 ratio)) (carsin (sin angle1)) (canrcos (cos angle1)) (den (+ 1.0 (* r r) (* -2.0 r (cos angle2)))) (sumsin (* r (sin angle2))) (sumcos (- 1.0 (* r (cos angle2))))) (set! angle (+ angle1 fm frequency)) (/ (- (* carsin sumsin) (* interp canrcos sumcos)) (* 2 den))))))) (definstrument (bump beg dur freq amp f0 f1 f2) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (res0 (round (/ f0 freq))) (res1 (round (/ f1 freq))) (res2 (round (/ f2 freq)))) (let ((gen1 (make-rssb (* res0 freq) (/ res0) .4)) (gen2 (make-rssb (* res1 freq) (/ res1) .5)) (gen3 (make-rssb (* res2 freq) (/ res2) .6)) (ampf (make-env '(0 0 .1 1 2 .5 3 .1 4 1 5 .4 6 .1 80 0) :scaler amp :base 32 :duration dur)) ; or 50 at end ;; or '(0 0 .1 1 2 .5 3 .1 4 .3 5 .1 40 0) (pervib (make-triangle-wave 5.0 (hz->radians 3.0))) (ranvib (make-rand-interp 12.0 (hz->radians 2.0)))) (do ((i start (+ i 1))) ((= i stop)) (let ((vib (+ (rand-interp ranvib) (triangle-wave pervib)))) (outa i (* (env ampf) (+ (* .85 (rssb-interp gen1 (* res0 vib) -1)) (* .1 (rssb-interp gen2 (* res1 vib) 0)) (* .05 (rssb-interp gen3 (* res2 vib) 1)))))))))) #| (with-sound (:play #t) (do ((k 0 (+ k 1))) ((= k 10)) (bump (* 0.4 k) 1 (* 16.3 (expt 2.0 (+ 3 (/ k 12)))) .5 520 1190 2390)) (do ((k 0 (+ k 1))) ((= k 10)) (let* ((freq (* 16.3 (expt 2.0 (+ 3 (/ k 12))))) (scl (sqrt (/ freq 120)))) (bump (+ 4 (* 0.4 k)) 1 freq .5 (* scl 520) (* scl 1190) (* scl 2390))))) (with-sound (:clipped #f :statistics #t :play #t) (do ((k 0 (+ k 1))) ((= k 10)) (let* ((freq (* 16.3 (expt 2.0 (+ 3 (/ k 12))))) ; if oct=5 (and env end at 100), sort of hammered string effect (f0 520) ; "uh" (f1 1190) (f2 2390) ;; "ah" is good: 730 1090 2440 ;; it might be smoother to scale the formant freqs by (sqrt (/ freq 120)) or even (expt (/ freq 120) 0.3) (res0 (round (/ f0 freq))) (res1 (round (/ f1 freq))) (res2 (round (/ f2 freq))) (gen1 (make-rssb (* res0 freq) (/ res0) .4)) (gen2 (make-rssb (* res1 freq) (/ res1) .5)) (gen3 (make-rssb (* res2 freq) (/ res2) .6)) (ampf (make-env '(0 0 .1 1 2 .5 3 .1 4 1 5 .4 6 .1 80 0) :scaler .5 :base 32 :length 60000)) ; or 50 at end ;; or '(0 0 .1 1 2 .5 3 .1 4 .3 5 .1 40 0) (pervib (make-triangle-wave 5.0 (hz->radians 3.0))) (ranvib (make-rand-interp 12.0 (hz->radians 2.0)))) (do ((i 0 (+ i 1))) ((= i 60000)) (let ((vib (+ (rand-interp ranvib) (triangle-wave pervib)))) (outa (+ i (* k 30000)) (* (env ampf) (+ (* .85 (rssb-interp gen1 (* res0 vib) -1)) (* .1 (rssb-interp gen2 (* res1 vib) 0)) (* .05 (rssb-interp gen3 (* res2 vib) 1)))))))))) (with-sound (:clipped #f :statistics #t :play #t) (do ((k 0 (+ k 1))) ((= k 10)) (let* ((freq (* 16.3 (expt 2.0 (+ 3 (/ k 12))))) ; froggy if oct=1 or 2 and "ah" (env end at 10 = cycling) ("er" is good too at oct=2) (scl (sqrt (/ freq 120))) (f0 (* scl 520)) ; "uh" (f1 (* scl 1190)) (f2 (* scl 2390)) ;; "ah" is good: 730 1090 2440 (res0 (floor (/ f0 freq))) (res1 (floor (/ f1 freq))) (res2 (floor (/ f2 freq))) (gen1 (make-rk!ssb (* res0 freq) (/ res0) 2.4)) (gen2 (make-rssb (* res1 freq) (/ res1) .5)) (gen3 (make-rssb (* res2 freq) (/ res2) .6)) (ampf (make-env '(0 0 .1 1 2 .5 3 .1 4 .3 5 .4 6 .1 40 0) :scaler .5 :base 32 :length 60000)) ; or 50 at end ;; or '(0 0 .1 1 2 .5 3 .1 4 .3 5 .1 40 0) (pervib (make-triangle-wave 5.0 (hz->radians 3.0))) (ranvib (make-rand-interp 12.0 (hz->radians 2.0)))) (do ((i 0 (+ i 1))) ((= i 60000)) (let ((vib (+ (rand-interp ranvib) (triangle-wave pervib)))) (outa (+ i (* k 30000)) (* (env ampf) (+ (* .85 (rk!ssb gen1 (* res0 vib))) (* .1 (rssb-interp gen2 (* res1 vib) 0)) (* .05 (rssb-interp gen3 (* res2 vib) 1)))))))))) (with-sound (:clipped #f :statistics #t :play #t) (do ((k 0 (+ k 1))) ((= k 10)) (let* ((freq (* 16.3 (expt 2.0 (+ 3 (/ k 12))))) (scl (sqrt (/ freq 120))) (f0 (* scl 490)) ; "uh" (f1 (* scl 1350)) (f2 (* scl 2440)) ;; "ah" is good: 730 1090 2440 (res0 (floor (/ f0 freq))) (res1 (floor (/ f1 freq))) (res2 (floor (/ f2 freq))) (gen1 (make-rk!ssb (* res0 freq) (/ res0) 2)) (gen2 (make-rk!ssb (* res1 freq) (/ res1) 3)) (gen3 (make-rk!ssb (* res2 freq) (/ res2) 3)) (ampf (make-env '(0 0 .1 1 2 .5 3 .1 4 .3 5 .4 6 .1 40 0) :scaler .5 :base 32 :length 30000)) (pervib (make-triangle-wave 5.0 (hz->radians 3.0))) (ranvib (make-rand-interp 12.0 (hz->radians 2.0)))) (do ((i 0 (+ i 1))) ((= i 30000)) (let ((vib (+ (rand-interp ranvib) (triangle-wave pervib)))) (outa (+ i (* k 30000)) (* (env ampf) (+ (* .85 (rk!ssb gen1 (* res0 vib))) (* .1 (rk!ssb gen2 (* res1 vib))) (* .05 (rk!ssb gen3 (* res2 vib))))))))))) (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-rssb 2000.0 (/ 103.0 2000) 0.5))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (rssb gen))))) |# ;;; -------------------------------------------------------------------------------- ;;; ;;; rxysin ;;; ;;; similar to rssb: (JO first) (define rxysin-methods (list (cons 'mus-scaler (dilambda (lambda (g) (g 'r)) (lambda (g val) (set! (g 'r) (generator-clamp-r val)) (set! (g 'r2) (* -2.0 (g 'r))) (set! (g 'rr) (+ 1.0 (* (g 'r) (g 'r))))))))) (defgenerator (rxysin :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) (set! (g 'r) (generator-clamp-r (g 'r))) (set! (g 'r2) (* -2.0 (g 'r))) (set! (g 'rr) (+ 1.0 (* (g 'r) (g 'r)))) g) :methods rxysin-methods) (frequency *clm-default-frequency*) (ratio 1.0) (r 0.5) (angle 0.0) fm rr r2) (define rxysin (let ((documentation "(make-rxysin frequency (ratio 1.0) (r 0.5)) creates an rxysin generator (similar to rssb). (rxysin gen (fm 0.0)) returns many sines from frequency spaced by frequency * ratio with amplitude r^k.")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let* ((x angle) (y (* x ratio))) (set! angle (+ angle fm frequency)) (/ (- (sin x) (* r (sin (- x y)))) (+ rr (* r2 (cos y))))))))) #| (with-sound (:clipped #f :statistics #t :play #t :scaled-to .5) (let ((gen (make-rxysin 1000 0.1 0.5))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (rxysin gen))))) |# (define rxycos-methods (list (cons 'mus-scaler (dilambda (lambda (g) (g 'r)) (lambda (g val) (set! (g 'r) (generator-clamp-r val)) (set! (g 'r2) (* -2.0 (g 'r))) (set! (g 'rr) (+ 1.0 (* (g 'r) (g 'r)))) (set! (g 'norm) (- 1.0 (abs (g 'r))))))))) (defgenerator (rxycos :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) (set! (g 'r) (generator-clamp-r (g 'r))) (set! (g 'r2) (* -2.0 (g 'r))) (set! (g 'rr) (+ 1.0 (* (g 'r) (g 'r)))) (set! (g 'norm) (- 1.0 (abs (g 'r)))) ; abs for negative r g) :methods rxycos-methods) (frequency *clm-default-frequency*) (ratio 1.0) (r 0.5) (angle 0.0) fm norm rr r2) (define rxycos (let ((documentation "(make-rxycos frequency (ratio 1.0) (r 0.5)) creates an rxycos generator. (rxycos gen (fm 0.0)) returns many cosines from frequency spaced by frequency * ratio with amplitude r^k.")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let* ((x angle) (y (* x ratio))) (set! angle (+ angle fm frequency)) (* (/ (- (cos x) (* r (cos (- x y)))) (+ rr (* r2 (cos y)))) norm)))))) #| (with-sound (:clipped #f :statistics #t) (let ((gen (make-rxycos 1000 0.1 0.5))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (rxycos gen))))) |# (define* (clamp-rxycos-r gen (fm 0.0)) ;; in this case we need to track ratio, as well as r, since the ;; highest frequency goes as x+ky (y=ratio*x); we want the value of k when ;; we reach srate/3, then solve for the corresponding r. (let-set! gen 'fm fm) (with-let gen (let ((maxr (expt cutoff (/ (floor (- (/ two-pi (* 3 ratio (+ fm frequency))) (/ ratio))))))) (if (>= r 0.0) (min r maxr) (max r (- maxr)))))) (define safe-rxycos-methods (list (cons 'mus-scaler (dilambda (lambda (g) (g 'r)) (lambda (g val) (set! (g 'r) val) (set! (g 'r) (clamp-rxycos-r g 0.0))))) (cons 'mus-frequency (dilambda (lambda (g) (radians->hz (g 'frequency))) (lambda (g val) (set! (g 'frequency) (hz->radians val)) (set! (g 'r) (clamp-rxycos-r g 0.0)) val))) (cons 'mus-offset ; ratio accessor in defgenerator (dilambda (lambda (g) (g 'ratio)) (lambda (g val) (set! (g 'ratio) val) (set! (g 'r) (clamp-rxycos-r g 0.0)) val))))) (defgenerator (safe-rxycos :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) (set! (g 'r) (clamp-rxycos-r g 0.0)) g) :methods safe-rxycos-methods) (frequency *clm-default-frequency*) (ratio 1.0) (r 0.5) (angle 0.0) (cutoff 0.001) fm) (define safe-rxycos (let ((documentation "(make-safe-rxycos frequency (ratio 1.0) (r 0.5)) creates a safe-rxycos generator. (safe-rxycos gen (fm 0.0)) returns many cosines from frequency spaced by frequency * ratio with amplitude r^k where 'r' is restricted to a safe value.")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let ((x angle) (y (* angle ratio))) (set! angle (+ angle fm frequency)) (if (not (= fm 0.0)) ;(set! r (clamp-rxycos-r (curlet) fm)) (let ((maxr (expt cutoff (/ (floor (- (/ two-pi (* 3 ratio (+ fm frequency))) (/ ratio))))))) (if (>= r 0.0) (set! r (min r maxr)) (set! r (max r (- maxr)))))) (* (/ (- (cos x) (* r (cos (- x y)))) (+ 1.0 (* -2.0 r (cos y)) (* r r))) (- 1.0 (abs r)))))))) ; norm, abs for negative r #| (with-sound (:clipped #f :statistics #t) (let ((gen (make-safe-rxycos 1000 0.1 0.99))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (safe-rxycos gen))))) |# ;;; -------------------------------------------------------------------------------- ;;; inf cosines scaled by e^-r (special case of rcos): ercos, erssb ;;; sndclm.html G&R second col last row (with normalization) (define ercos-methods (list (cons 'mus-frequency (dilambda (lambda (g) (mus-frequency (g 'osc))) (lambda (g val) (set! (mus-frequency (g 'osc)) val)))) (cons 'mus-phase (dilambda (lambda (g) (mus-phase (g 'osc))) (lambda (g val) (set! (mus-phase (g 'osc)) val)))))) (defgenerator (ercos :make-wrapper (lambda (g) (if (<= (g 'r) 0.0) (set! (g 'r) 0.00001)) (set! (g 'cosh-t) (cosh (g 'r))) (set! (g 'osc) (make-polywave (g 'frequency) (list 0 (g 'cosh-t) 1 -1.0) mus-chebyshev-second-kind)) (let ((exp-t (exp (- (g 'r))))) (set! (g 'offset) (/ (- 1.0 exp-t) (* 2.0 exp-t))) (set! (g 'scaler) (* (sinh (g 'r)) (g 'offset)))) g) :methods ercos-methods) (frequency *clm-default-frequency*) (r 1.0) fm (osc #f) scaler offset cosh-t) (define ercos (let ((documentation "(make-ercos frequency (r 0.5)) creates an ercos generator (a special case of rcos). (ercos gen (fm 0.0)) returns many cosines from frequency with amplitude e^(-kr).")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (- (/ scaler (polywave osc fm)) offset))))) #| (with-let gen (- (/ scaler (- cosh-t (oscil osc fm))) offset))) (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-ercos 100 :r 1.0))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (ercos gen))))) |# (definstrument (ercoser beg dur freq amp r) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (gen (make-ercos freq :r r)) (t-env (make-env '(0 .1 1 2) :duration dur))) (with-let (varlet gen (cons 'start start) (cons 'stop stop) (cons 'amp amp) (cons 't-env t-env) (cons 'gen gen)) (do ((i start (+ i 1))) ((= i stop)) (set! r (env t-env)) (set! cosh-t (cosh r)) (set! ((mus-data osc) 0) cosh-t) (let ((exp-t (exp (- r)))) (set! offset (/ (- 1.0 exp-t) (* 2.0 exp-t))) (set! scaler (* (sinh r) offset))) (outa i (* amp (ercos gen))))))) #| ;;; same, but slightly slower (definstrument (ercoser beg dur freq amp r) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (gen (make-ercos freq :r r)) (t-env (make-env '(0 .1 1 2) :duration dur))) (do ((i start (+ i 1))) ((= i stop)) (let ((r (env t-env))) (set! (gen 'r) r) (set! (gen 'cosh-t) (cosh r)) (set! ((mus-data (gen 'osc)) 0) (gen 'cosh-t)) (let ((exp-t (exp (- r)))) (set! (gen 'offset) (/ (- 1.0 exp-t) (* 2.0 exp-t))) (set! (gen 'scaler) (* (sinh r) (gen 'offset)))) (outa i (* amp (ercos gen))))))) |# #| ;; change "t" during note -- smoothly changing sum-of-cosines spectra (damped "lute-stop" effect) (with-sound (:play #t) (ercoser 0 1 100 .5 0.1)) |# (defgenerator (erssb :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) g)) (frequency *clm-default-frequency*) (ratio 1.0) (r 0.5) (angle 0.0) fm) (define erssb (let ((documentation "(make-erssb frequency (ratio 1.0) (r 0.5)) creates an erssb generator (a special case of rssb). (erssb gen (fm 0.0)) returns many sinusoids from frequency spaced by frequency * ratio with amplitude e^(-kr).")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let* ((cx angle) (mx (* cx ratio)) (cxx (- cx mx)) (ccmx (- (cosh r) (cos mx)))) (set! angle (+ angle fm frequency)) (if (< (abs ccmx) nearly-zero) 1.0 (/ (- (* (cos cxx) (- (/ (sinh r) ccmx) 1.0)) (* (sin cxx) (/ (sin mx) ccmx))) (* 2.0 (- (/ 1.0 (- 1.0 (exp (- r)))) 1.0))))))))) ; normalization #| (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-erssb 1000.0 0.1 1.0))) (do ((i 0 (+ i 1))) ((= i 20000)) (outa i (erssb gen))))) |# #| ;;; -------------------------------------------------------------------------------- ;;; removed 8-May-08 -- not useful or different from (for example) rk!cos ;;; inf sinusoids scaled by r^2: r2cos, r2sin, r2ssb ;;; Jolley second col second row (first row is cos tweak of this) (defgenerator (r2sin :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) (if (>= (* (g 'r) (g 'r)) 1.0) (set! (g 'r) 0.9999999)) g)) (frequency *clm-default-frequency*) (r 0.5) (angle 0.0) fm) (define r2sin (let ((documentation "(make-r2sin frequency (r 0.5)) creates an r2sin generator. (r2sin gen (fm 0.0)) returns many even-numbered sines from frequency with amplitude r^(2k)/(2k)!.")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let* ((x angle)) (set! angle (+ angle fm frequency)) (* (sinh (* r (cos x))) (sin (* r (sin x))))))))) ;;; even harmonics, but we can't push the upper partials past the (2k)! range, so not very flexible (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-r2sin 100.0 :r 0.5))) (do ((i 0 (+ i 1))) ((= i 20000)) (outa i (r2sin gen))))) (defgenerator (r2cos :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) (if (>= (* (g 'r) (g 'r)) 1.0) (set! (g 'r) 0.9999999)) g)) (frequency *clm-default-frequency*) (r 0.5) (angle 0.0) fm) (define r2cos (let ((documentation "(make-r2cos frequency (r 0.5)) creates an r2cos generator. (r2cos gen (fm 0.0)) returns many even-numbered cosines from frequency with amplitude r^(2k)/(2k)!.")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let* ((x angle)) (set! angle (+ angle fm frequency)) (/ (- (* (cosh (* r (cos x))) (cos (* r (sin x)))) 1.0) ; omit DC (- (cosh r) 1.0))))))) ; normalize ;;; odd harmonics, but we can't push the upper partials past the (2k)! range, so not very flexible (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-r2cos 100.0 :r 0.5))) (do ((i 0 (+ i 1))) ((= i 20000)) (outa i (r2cos gen))))) (defgenerator (r2ssb :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) g)) (frequency *clm-default-frequency*) (ratio 1.0) (r 0.5) (angle 0.0) fm) (define r2ssb (let ((documentation "(make-r2ssb frequency (ratio 1.0) (r 0.5)) creates an r2ssb generator. (r2ssb gen (fm 0.0)) returns many even-numbered sinusoids from frequency spaced by frequency * ratio, if that makes any sense, with amplitude r^(2k)/(2k)!.")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let* ((cx angle) (mx (* cx ratio)) (a r) (asinx (* a (sin mx))) (acosx (* a (cos mx)))) (set! angle (+ angle fm frequency)) (/ (- (* (cos cx) (cosh acosx) (cos asinx)) (* (sin cx) (sinh acosx) (sin asinx))) (cosh a))))))) ; normalization (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-r2ssb 1000.0 0.1 0.5))) (do ((i 0 (+ i 1))) ((= i 20000)) (outa i (r2ssb gen))))) (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-r2ssb 1000.0 0.1 0.5)) (vib (make-oscil 5))) (do ((i 0 (+ i 1))) ((= i 20000)) (outa i (r2ssb gen (* (hz->radians 100.0) (oscil vib))))))) |# ;;; -------------------------------------------------------------------------------- ;;; ;;; inf odd cosines scaled by e^-r: eoddcos ;;; Jolley first col second row ;;; heads toward a square wave as "r" -> 0.0 (odd harmonics, 1/k amp) ;;; this is the cos side of rkoddssb with r=e^-a (define eoddcos-methods (list (cons 'mus-frequency (dilambda (lambda (g) (mus-frequency (g 'osc))) (lambda (g val) (set! (mus-frequency (g 'osc)) val)))) (cons 'mus-phase (dilambda (lambda (g) (mus-phase (g 'osc))) (lambda (g val) (set! (mus-phase (g 'osc)) val)))))) (defgenerator (eoddcos :make-wrapper (lambda (g) (set! (g 'osc) (make-oscil (g 'frequency) (* 0.5 pi))) g) :methods eoddcos-methods) (frequency *clm-default-frequency*) (r 1.0) fm (osc #f)) (define eoddcos (let ((documentation "(make-eoddcos frequency (r 0.5)) creates an eoddcos generator. (eoddcos gen (fm 0.0)) returns many cosines from spaced by frequency with amplitude e^(-r).")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let* ((a r) (sinha (sinh a))) (if (zero? sinha) 0.0 ; just a guess (/ (atan (oscil osc fm) sinha) (atan 1.0 sinha)))))))) ; normalization #| (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-eoddcos 400.0 :r 1.0))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (eoddcos gen))))) (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-eoddcos 400.0 :r 0.0)) (a-env (make-env '(0 0 1 1) :length 10000))) (do ((i 0 (+ i 1))) ((= i 10000)) (set! (gen 'r) (env a-env)) (outa i (eoddcos gen))))) (with-sound (:clipped #f :statistics #t :play #t) (let ((gen1 (make-eoddcos 400.0 :r 0.0)) (gen2 (make-oscil 400.0)) (a-env (make-env '(0 0 1 1) :length 10000))) (do ((i 0 (+ i 1))) ((= i 10000)) (set! (gen 'r1) (env a-env)) (outa i (* .5 (eoddcos gen1 (* .1 (oscil gen2)))))))) |# #| ;;; -------------------------------------------------------------------------------- ;;; removed 6-May-08 ;;; inf odd cosines scaled by complicated mess: koddcos ;;; Jolley first col 5th row (define make-koddcos make-oscil) (define koddcos (let ((documentation "(make-koddcos frequency) creates a koddcos generator. (koddcos gen (fm 0.0)) returns many cosines from spaced by frequency with amplitude too messy to write down, and the output looks wrong anyway.")) (lambda* (gen (fm 0.0)) (let ((arg (* 2.0 (oscil gen fm)))) (if (>= arg 0.0) (/ (acos (- 1.0 arg)) pi) (/ (acos (+ 1.0 arg)) (- pi))))))) (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-koddcos 400.0))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (* .3 (koddcos gen)))))) ;;; as printed in J, this is not usable -- 1-2sin can be 3 so acos will be complex -- looks like we're missing: x < pi ;;; we get odd harmonics but wrong amps |# ;;; -------------------------------------------------------------------------------- ;;; inf cosines scaled by r^k/k: rkcos, rksin, rkssb ;;; G&R second col 6th row, also J 536 ;;; r^k/k -- this sums to ln(1/(1-x)) if x<1 (J 118) (define rkcos-methods (list (cons 'mus-frequency (dilambda (lambda (g) (mus-frequency (g 'osc))) (lambda (g val) (set! (mus-frequency (g 'osc)) val)))) (cons 'mus-scaler (dilambda (lambda (g) (g 'r)) (lambda (g val) (set! (g 'r) (generator-clamp-r val))))) (cons 'mus-phase (dilambda (lambda (g) (mus-phase (g 'osc))) (lambda (g val) (set! (mus-phase (g 'osc)) val)))))) (defgenerator (rkcos :make-wrapper (lambda (g) (set! (g 'osc) (make-oscil (g 'frequency) (* 0.5 pi))) (set! (g 'r) (generator-clamp-r (g 'r))) ; or clip at 0.0? (set! (g 'norm) (log (- 1.0 (abs (g 'r))))) g) :methods rkcos-methods) (frequency *clm-default-frequency*) (r 0.5) norm fm (osc #f)) ;;; not very flexible, and very similar to others in the r^k mold (define rkcos (let ((documentation "(make-rkcos frequency (r 0.5)) creates an rkcos generator. (rkcos gen (fm 0.0)) returns many cosines from spaced by frequency with amplitude (r^k)/k.")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let ((cs (oscil osc fm))) (/ (* 0.5 (log (+ 1.0 (* -2.0 r cs) (* r r)))) norm)))))) #| (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-rkcos 440.0 :r 0.5))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (rkcos gen))))) |# (define rksin-methods (list (cons 'mus-scaler (dilambda (lambda (g) (g 'r)) (lambda (g val) (set! (g 'r) (generator-clamp-r val))))))) (defgenerator (rksin :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) g) :methods rksin-methods) (frequency *clm-default-frequency*) (r 0.5) (angle 0.0) fm) ;;; normalization based on 0 of derivative of atan arg (for max) at cos x = r, ;;; so we get a maxamp here of (atan (/ (* r (sin (acos r))) (- 1.0 (* r r)))) (define rksin (let ((documentation "(make-rksin frequency (r 0.5)) creates an rksin generator. (rksin gen (fm 0.0)) returns many sines from spaced by frequency with amplitude (r^k)/k.")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let ((x angle)) (set! angle (+ angle fm frequency)) (/ (atan (* r (sin x)) (- 1.0 (* r (cos x)))) (atan (* r (sin (acos r))) ; normalization (- 1.0 (* r r))))))))) #| (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-rksin 100.0 :r 0.5))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (rksin gen))))) |# (define rkssb-methods (list (cons 'mus-scaler (dilambda (lambda (g) (g 'r)) (lambda (g val) (set! (g 'r) (generator-clamp-r val))))))) (defgenerator (rkssb :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) g) :methods rkssb-methods) (frequency *clm-default-frequency*) (ratio 1.0) (r 0.5) (angle 0.0) fm) (define rkssb (let ((documentation "(make-rkssb frequency (ratio 1.0) (r 0.5)) creates an rkssb generator. (rkssb gen (fm 0.0)) returns many sinusoids from frequency from spaced by frequency * ratio with amplitude (r^k)/k.")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let* ((cx angle) (mx (* cx ratio)) (cxx (* (- 1.0 ratio) cx)) (rcosmx (* r (cos mx)))) (set! angle (+ angle fm frequency)) (/ (- (* (cos cxx) -0.5 (log (+ 1.0 (* -2.0 rcosmx) (* r r)))) (* (sin cxx) (atan (* r (sin mx)) (- 1.0 rcosmx)))) (- (log (- 1.0 (abs r)))))))))) ; normalization #| (with-sound (:clipped #f :statistics #t :play #t :scaled-to .5) (let ((gen (make-rkssb 1000.0 0.5 :r 0.75)) ; (make-rkssb 300.0 3.0 :r 0.5) (ampf (make-env '(0 0 1 1 2 1 3 0) :length 20000))) (do ((i 0 (+ i 1))) ((= i 20000)) (outa i (* (env ampf) (rkssb gen)))))) |# ;;; -------------------------------------------------------------------------------- ;;; inf cosines scaled by r^k/k!: rk!cos, rk!ssb ;;; G&R second col third from last (simplified) (define rk!cos-methods (list (cons 'mus-phase (dilambda (lambda (g) (g 'angle)) (lambda (g val) (set! (g 'angle) val)))))) (defgenerator (rk!cos :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) (set! (g 'norm) (/ 1.0 (- (exp (abs r)) 1.0))) g) :methods rk!cos-methods) (frequency *clm-default-frequency*) (r 0.5) (angle 0.0) fm norm) (define rk!cos (let ((documentation "(make-rk!cos frequency (r 0.5)) creates an rk!cos generator. (rk!cos gen (fm 0.0)) returns many cosines spaced by frequency with amplitude (r^k)/k!.")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let ((x angle)) (set! angle (+ angle fm frequency)) (* (- (* (exp (* r (cos x))) (cos (* r (sin x)))) 1.0) ; omit DC norm)))))) #| (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-rk!cos 440.0 :r 0.5))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (* .5 (rk!cos gen)))))) |# ;;; the k! denominator dominates, so r * ratio = formant center approximately; (n!)^(1/n) ;;; so freq=100, r=30, the center of the spectrum is around 3kHz: #| (with-sound (:clipped #f :statistics #t :play #t :scaled-to .5) (let ((gen (make-rk!cos 100.0 :r 40.0)) (r 40.0) (incr (/ -40.0 100000))) (do ((i 0 (+ i 1))) ((= i 100000)) (set! (gen 'r) r) (set! r (+ r incr)) (outa i (rk!cos gen))))) (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-rk!cos 300.0 :r 10.0)) (ampf (make-env '(0 0 .1 1 .2 1 3 .5 5 .25 10 0) :scaler .5 :length 10000)) (r 10.0) (incr (/ -10.0 10000))) (do ((i 0 (+ i 1))) ((= i 10000)) (set! (gen 'r) r) (set! r (+ r incr)) (outa i (* (env ampf) (rk!cos gen)))))) (with-sound (:clipped #f :statistics #t :play #t :scaled-to .5) (let ((gen (make-rk!cos 1000.0 :r 8.0)) (frqf (make-env '(0 1 1 0) :base 32 :scaler (hz->radians 1000) :length 10000))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (rk!cos gen (env frqf)))))) (with-sound (:clipped #f :statistics #t :play #t :scaled-to .5) (let ((gen (make-rk!cos 3000.0 :r 1.0)) (ampf (make-env '(0 0 1 1 10 1 11 0) :length 10000)) (frqf (make-env '(0 1 1 0 2 .25 3 0) :base 3 :scaler (hz->radians 2000) :length 10000))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (* (env ampf) (rk!cos gen (env frqf))))))) (with-sound (:play #t :scaled-to .5) (do ((k 0 (+ k 1))) ((= k 6)) (let ((gen (make-rk!cos 3000.0 :r 0.6)) (ampf (make-env '(0 0 1 1 2 1 3 0) :length 3000)) (frqf (make-env '(0 0 1 1) :base .1 :scaler (hz->radians 2000) :length 3000))) ; '(0 .5 1 1 2 0 3 0) '(0 1 1 0 2 1 6 -1) (do ((i 0 (+ i 1))) ((= i 3000)) (outa (+ i (* k 4000)) (* (env ampf) (rk!cos gen (env frqf)))))))) (with-sound (:clipped #f :statistics #t :play #t :scaled-to .5) (do ((k 0 (+ k 1))) ((= k 6)) (let ((gen (make-rk!cos 1000.0 :r 1.0)) (ampf (make-env '(0 0 1 1 2 1 3 0) :length 3000)) (frqf (make-env '(0 .9 1 1 2 -1) :base .1 :scaler (hz->radians 500) :length 3000))) (do ((i 0 (+ i 1))) ((= i 3000)) (outa (+ i (* k 10000)) (* (env ampf) (rk!cos gen (env frqf)))))))) (with-sound (:clipped #f :statistics #t :play #t :scaled-to .5) (do ((k 0 (+ k 1))) ((= k 6)) (let ((gen (make-rk!cos 500.0 :r 1.5)) (ampf (make-env '(0 0 1 1 2 1 3 0) :length 3000)) (frqf (make-env '(0 1 1 1 2 -1) :base .5 :scaler (hz->radians 400) :length 3000))) (do ((i 0 (+ i 1))) ((= i 3000)) (outa (+ i (* k 10000)) (* (env ampf) (rk!cos gen (env frqf)))))))) |# (defgenerator (rk!ssb :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) g)) (frequency *clm-default-frequency*) (ratio 1.0) (r 1.0) (angle 0.0) fm) (define rk!ssb (let ((documentation "(make-rk!ssb frequency (ratio 1.0) (r 0.5)) creates an rk!ssb generator. (rk!ssb gen (fm 0.0)) returns many sinusoids from frequency spaced by frequency * ratio with amplitude (r^k)/k!.")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let* ((cx angle) (mx (* cx ratio)) (ercosmx (exp (* r (cos mx)))) (rsinmx (* r (sin mx)))) (set! angle (+ angle fm frequency)) (/ (- (* (cos cx) ercosmx (cos rsinmx)) (* (sin cx) ercosmx (sin rsinmx))) (exp (abs r)))))))) ; normalization (keeping DC term here to get "carrier") #| (with-sound (:clipped #f :statistics #t :play #t :scaled-to .5) (let ((gen (make-rk!ssb 1000.0 0.1 :r 0.5)) ; (make-rk!ssb 200.0 3.0 :r 2) (ampf (make-env '(0 0 1 1 2 1 3 0) :length 20000))) (do ((i 0 (+ i 1))) ((= i 20000)) (outa i (* (env ampf) (rk!ssb gen)))))) ; (make-rk!ssb 0.0 120.0 :r 15) gives a widely separated wave-train of pulses ; so (make-rk!ssb 0.0 40.0 :r 70) is insecty (:r 100) ; (make-rk!ssb 0.0 10.0 :r 100) -- some bird? (make-rk!ssb 0.0 15.0 :r 300) ; (make-rk!ssb 1000.0 25.0 :r 10) (make-rk!ssb 3000.0 25.0 :r 100) -- another bird (5000) |# (definstrument (bouncy beg dur freq amp (bounce-freq 5) (bounce-amp 20)) (let ((len (seconds->samples dur)) (start (seconds->samples beg))) (let ((gen (make-rk!ssb (* freq 4) 1/4 :r 1.0)) (gen1 (make-oscil bounce-freq)) (bouncef (make-env '(0 1 1 0) :base 32 :scaler bounce-amp :duration 1.0)) (rf (make-env (list 0 0 1 1 (max 2.0 dur) 0) :base 32 :scaler 3 :duration dur)) (ampf (make-env (list 0 0 .01 1 .03 1 1 .15 (max 2 dur) 0.0) :base 32 :scaler amp :duration dur)) (stop (+ start len)) (fv (make-float-vector len))) (do ((i 0 (+ i 1))) ((= i len)) (float-vector-set! fv i (+ (env rf) (abs (* (env bouncef) (oscil gen1)))))) (do ((i start (+ i 1)) (j 0 (+ j 1))) ((= i stop)) (set! (gen 'r) (float-vector-ref fv j)) (outa i (* (env ampf) (rk!ssb gen))))))) #| (with-sound (:statistics #t :play #t :clipped #f) (bouncy 0 2 300 .5 5 10)) (with-sound (:statistics #t :play #t :clipped #f) (bouncy 0 2 200 .5 3 2)) |# #| ;;; -------------------------------------------------------------------------------- ;;; rxyk!cos ;;; moved to clm.c 18-Apr-13) (defgenerator (rxyk!sin :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) g)) (frequency *clm-default-frequency*) (ratio 1.0) (r 0.5) (angle 0.0) fm) (define rxyk!sin (let ((documentation "(make-rxyk!sin frequency (ratio 1.0) (r 0.5)) creates an rxyk!sin generator. (rxyk!sin gen (fm 0.0)) returns many sines from frequency spaced by frequency * ratio with amplitude r^k/k!.")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let* ((x angle) (y (* x ratio))) (set! angle (+ angle fm frequency)) (/ (* (exp (* r (cos y))) (sin (+ x (* r (sin y))))) ; was cos by mistake (18-Apr-13) (exp (abs r)))))))) (with-sound (:clipped #f :statistics #t :play #t :scaled-to .5) (let ((gen (make-rxyk!sin 1000 0.1 0.5))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (rxyk!sin gen))))) (defgenerator (rxyk!cos :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) (set! (g 'ar) (/ 1.0 (exp (abs (g 'r))))) g)) (frequency *clm-default-frequency*) (ratio 1.0) (r 0.5) (angle 0.0) fm ar) (define rxyk!cos (let ((documentation "(make-rxyk!cos frequency (ratio 1.0) (r 0.5)) creates an rxyk!cos generator. (rxyk!cos gen (fm 0.0)) returns many cosines from frequency spaced by frequency * ratio with amplitude r^k/k!.")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let* ((x angle) (y (* x ratio))) (set! angle (+ angle fm frequency)) (* (exp (* r (cos y))) (cos (+ x (* r (sin y)))) ar)))))) (with-sound (:clipped #f :statistics #t :play #t :scaled-to .5) (let ((gen (make-rxyk!cos 1000 0.1 0.5))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (rxyk!cos gen))))) |# (definstrument (brassy beg dur freq amp ampf freqf gliss) (let ((pitch-time .05) (amp-time .1)) (let ((gen (make-rxyk!cos freq :r 0.0)) (start (seconds->samples beg)) (end (seconds->samples (+ beg dur))) (amp-env (make-env ampf :duration dur :scaler amp)) (pitch-env (make-env freqf :scaler (/ gliss freq) :duration dur)) (slant (make-moving-average (seconds->samples pitch-time))) (vib (make-polywave 5 (list 1 (hz->radians 4.0)) mus-chebyshev-second-kind)) (harmfrq 0.0) (harmonic 0) (dist 0.0)) (set! (mus-increment slant) (* (hz->radians freq) (mus-increment slant))) (do ((i start (+ i 1))) ((= i end)) (set! harmfrq (env pitch-env)) (set! harmonic (floor harmfrq)) (set! dist (abs (- harmfrq harmonic))) (set! (mus-scaler gen) (* 20.0 (min amp-time dist (- 1.0 dist)))) (outa i (* (env amp-env) (rxyk!cos gen (+ (moving-average slant harmonic) (polywave vib))))))))) #| (with-sound (:statistics #t :play #t) (brassy 0 4 50 .05 '(0 0 1 1 10 1 11 0) '(0 1 1 0) 1000)) |# ;;; -------------------------------------------------------------------------------- ;;; inf cosines scaled by complicated mess: r2k!cos ;;; from Askey "Ramanujan and Hypergeometric Series" in Berndt and Rankin "Ramanujan: Essays and Surveys" p283 ;;; ;;; this gives a sum of cosines of decreasing amp where the "k" parameter determines ;;; the "index" (in FM nomenclature) -- higher k = more cosines (define r2k!cos-methods (list (cons 'mus-frequency (dilambda (lambda (g) (mus-frequency (g 'osc))) (lambda (g val) (set! (mus-frequency (g 'osc)) val)))) (cons 'mus-phase (dilambda (lambda (g) (mus-phase (g 'osc))) (lambda (g val) (set! (mus-phase (g 'osc)) val)))) (cons 'mus-copy copy))) (defgenerator (r2k!cos :make-wrapper (lambda (g) (set! (g 'rr1) (+ 1.0 (* (g 'r) (g 'r)))) (set! (g 'r2) (* 2.0 (abs (g 'r)))) (set! (g 'norm) (expt (- (g 'rr1) (g 'r2)) (g 'k))) (set! (g 'osc) (make-polywave (g 'frequency) (list 0 (g 'rr1) 1 (- (g 'r2))) mus-chebyshev-second-kind)) (set! (g 'k) (- (g 'k))) g) :methods r2k!cos-methods) (frequency *clm-default-frequency*) (r 0.5) (k 0.0) rr1 r2 norm fm (osc #f)) (define r2k!cos (let ((documentation "(make-2rk!cos frequency (r 0.5) (k 0.0)) creates an r2k!cos generator. (r2k!cos gen (fm 0.0)) returns many cosines spaced by frequency with amplitude too messy to write down.")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (* (expt (polywave osc fm) k) norm))))) #| ;;; old form (with-let gen (let ((rr1 (+ 1.0 (* r r))) (r2 (* 2 (abs r)))) ; abs for negative r (* (expt (- rr1 (* r2 (oscil osc fm))) (- k)) (expt (- rr1 r2) k))))) ; amplitude normalization |# ;;; there is still noticable DC offset if r != 0.5 -- could precompute it and subtract (and there's lots of DC anyway) #| (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-r2k!cos 440.0 :r 0.5 :k 3.0))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (r2k!cos gen))))) (with-sound (:clipped #f :statistics #t :play #t :scaled-to .5) (let ((gen (make-r2k!cos 440.0 :r 0.5 :k 3.0)) (indf (make-env '(0 1 1 0 10 0) :length 80000 :scaler 10.0 :offset 1))) (do ((i 0 (+ i 1))) ((= i 80000)) (set! (gen 'k) (env indf)) (outa i (r2k!cos gen))))) |# (definstrument (pianoy beg dur freq amp) (let ((gen (make-r2k!cos freq :r 0.5 :k 3.0)) (ampf (make-env (list 0 0 .01 1 .03 1 1 .15 (max 2 dur) 0.0) :base 32 :scaler amp :duration dur)) (start (seconds->samples beg)) (stop (seconds->samples (+ beg dur)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* (env ampf) (r2k!cos gen)))))) ;;; (with-sound (:statistics #t :play #t :clipped #f) (pianoy 0 3 100 .5)) ;;; this can be combined with bouncy-like changes to get an evolving sound (definstrument (pianoy1 beg dur freq amp (bounce-freq 5) (bounce-amp 20)) (let ((len (seconds->samples dur)) (start (seconds->samples beg))) (let ((gen (make-r2k!cos freq :r 0.5 :k 3.0)) (gen1 (make-oscil bounce-freq)) (bouncef (make-env '(0 1 1 0) :base 32 :scaler bounce-amp :duration 1.0)) (rf (make-env (list 0 0 1 1 (max 2.0 dur) 0) :base 32 :scaler .1 :offset .25 :duration dur)) (ampf (make-env (list 0 0 .01 1 .03 1 1 .15 (max 2 dur) 0.0) :base 32 :scaler amp :duration dur)) (stop (+ start len)) (fv (make-float-vector len))) (do ((i 0 (+ i 1))) ((= i len)) (float-vector-set! fv i (+ (env rf) (abs (* (env bouncef) (oscil gen1)))))) (do ((i start (+ i 1)) (j 0 (+ j 1))) ((= i stop)) (set! (gen 'r) (float-vector-ref fv j)) (outa i (* (env ampf) (r2k!cos gen))))))) #| (with-sound (:statistics #t :play #t :clipped #f) (pianoy1 0 4 200 .5 1 .1)) |# (definstrument (pianoy2 beg dur freq amp) (let ((gen (make-r2k!cos freq :r 0.5 :k 3.0)) (ampf (make-env (list 0 0 .01 1 .03 1 1 .15 (max 2 dur) 0.0) :base 32 :scaler amp :duration dur)) (knock (make-fmssb 10.0 20.0 :index 1.0)) (kmpf (make-env '(0 0 1 1 3 1 100 0) :base 3 :scaler .05 :length 30000)) (indf (make-env '(0 1 1 0) :length 30000 :base 3 :scaler 10)) (start (seconds->samples beg)) (stop (seconds->samples (+ beg dur)))) (do ((i start (+ i 1))) ((= i stop)) (set! (knock 'index) (env indf)) (outa i (+ (* (env ampf) (r2k!cos gen)) (* (env kmpf) (fmssb knock 0.0))))))) #| (with-sound (:clipped #f :statistics #t :play #t) (pianoy2 0 1 100 .5)) |# ;;; -------------------------------------------------------------------------------- ;;; inf sines scaled by 1/2^k: k2sin ;;; Jolley first col first row ;;; not flexible -- very similar to several others (defgenerator (k2sin :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) g)) (frequency *clm-default-frequency*) (angle 0.0) fm) (define k2sin (let ((documentation "(make-k2sin frequency) creates a k2sin generator. (k2sin gen (fm 0.0)) returns many sines spaced by frequency with amplitude 1/(2^k).")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let ((x angle)) (set! angle (+ angle fm frequency)) (/ (* 3.0 (sin x)) ; 3 rather than 4 for normalization (- 5.0 (* 4.0 (cos x))))))))) #| (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-k2sin 440.0))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (k2sin gen))))) |# ;;; using the second Sansone formula, we get the sum of cos case by using a=-5b/4 or 3/(4cosx-5) (defgenerator (k2cos :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) g)) (frequency *clm-default-frequency*) (angle 0.0) fm) (define k2cos (let ((documentation "(make-k2cos frequency) creates a k2cos generator. (k2cos gen (fm 0.0)) returns many cosines spaced by frequency with amplitude 1/(2^k).")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let ((x angle)) (set! angle (+ angle fm frequency)) (* 0.5 (- (/ 3.0 (- 5.0 (* 4.0 (cos x)))) 1.0))))))) #| (with-sound (:clipped #f :statistics #t :play #t :scaled-to .5) (let ((gen (make-k2cos 440.0))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (k2cos gen))))) |# (defgenerator (k2ssb :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) g)) (frequency *clm-default-frequency*) (ratio 1.0) (angle 0.0) fm) (define k2ssb (let ((documentation "(make-k2ssb frequency (ratio 1.0)) creates a k2ssb generator. (k2ssb gen (fm 0.0)) returns many sinusoids from frequency spaced by frequency * ratio with amplitude 1/(2^k).")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let* ((cx angle) (mx (* cx ratio))) (set! angle (+ angle fm frequency)) (/ (- (* 3 (cos cx)) (* (sin cx) 4.0 (sin mx))) (* 3.0 (- 5.0 (* 4.0 (cos mx)))))))))) #| (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-k2ssb 1000.0 0.1))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (* .5 (k2ssb gen)))))) |# ;;; -------------------------------------------------------------------------------- ;;; this was inspired by Andrews, Askey, Roy "Special Functions" p396, but there's an error somewhere... ;;; it produces sum r^k sin(2k-1)x ;;; (not normalized) (define dblsum-methods (list (cons 'mus-frequency (dilambda (lambda (g) (radians->hz (* 0.5 (g 'frequency)))) (lambda (g val) (set! (g 'frequency) (hz->radians (* 2 val))) val))))) (defgenerator (dblsum :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (* 2 (g 'frequency)))) g) :methods dblsum-methods) (frequency *clm-default-frequency*) (r 0.5) (angle 0.0) fm) (define dblsum (let ((documentation "(make-dblsum frequency (r 0.5)) creates a dblsum generator. (dblsum gen (fm 0.0)) returns many sines from frequency spaced by frequency * (2k -1) with amplitude r^k (this is buggy).")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let ((x angle)) (set! angle (+ angle fm frequency)) (/ (* (+ 1 r) (sin (* 0.5 x))) (* (- 1 r) (+ 1.0 (* -2.0 r (cos x)) (* r r))))))))) #| (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-dblsum 100 0.5))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (* .25 (dblsum gen)))))) |# ;;; -------------------------------------------------------------------------------- ;;; inf odd sinusoids scaled by r^odd-k/odd-k: rkoddssb ;;; G&R second col rows 7&8 (odd r^k/k) (define rkoddssb-methods (list (cons 'mus-scaler (dilambda (lambda (g) (g 'r)) (lambda (g val) (set! (g 'r) (generator-clamp-r val)) (set! (g 'rr1) (+ 1.0 (* (g 'r) (g 'r)))) (set! (g 'norm) (/ 1.0 (- (log (+ 1.0 (g 'r))) (log (- 1.0 (g 'r))))))))))) (defgenerator (rkoddssb :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) (set! (g 'r) (generator-clamp-r (g 'r))) (set! (g 'rr1) (+ 1.0 (* (g 'r) (g 'r)))) (set! (g 'norm) (/ 1.0 (- (log (+ 1.0 (g 'r))) (log (- 1.0 (g 'r)))))) g) :methods rkoddssb-methods) (frequency *clm-default-frequency*) (ratio 1.0) (r 0.5) (angle 0.0) fm rr1 norm) (define rkoddssb (let ((documentation "(make-rkoddssb frequency (ratio 1.0) (r 0.5)) creates an rkoddssb generator. (rkoddssb gen (fm 0.0)) returns many sinusoids from frequency spaced by frequency * 2 * ratio with amplitude (r^(2k-1))/(2k-1).")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let* ((cx angle) (mx (* cx ratio)) (cxx (- cx mx)) (cmx (* 2.0 r (cos mx)))) (set! angle (+ angle fm frequency)) (* (- (* (cos cxx) 0.5 (log (/ (+ rr1 cmx) (- rr1 cmx)))) (* (sin cxx) (atan (* 2.0 r (sin mx)) (- 1.0 (* r r))))) norm)))))) #| (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-rkoddssb 1000.0 0.1 0.5))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (* .5 (rkoddssb gen)))))) |# (definstrument (glassy beg dur freq amp) (let* ((n (floor (/ *clm-srate* (* 3 freq)))) (r (expt .001 (/ n)))) (let ((start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (clang (make-rkoddssb (* freq 2) (/ 1.618 2) r)) (clangf (make-env (list 0 0 .01 1 .1 1 .2 .4 (max .3 dur) 0) :scaler amp :duration dur)) (crf (make-env (list 0 1 1 0) :scaler r :duration dur))) (do ((i start (+ i 1))) ((= i stop)) (set! (clang 'r) (env crf)) (outa i (* (env clangf) (rkoddssb clang 0.0))))))) #| (with-sound (:clipped #f :statistics #t :play #t) (glassy 0 .1 1000 .5)) (with-sound (:clipped #f :statistics #t :play #t) (do ((i 0 (+ i 1))) ((= i 10)) (glassy (* i .3) .1 (+ 400 (* 100 i)) .5))) (with-sound (:statistics #t :play #t :scaled-to .5) (let ((gen (make-rkoddssb 5000.0 0.1 0.95)) (ampf (make-env '(0 0 9 1 10 0) :base 32 :length 10000)) (noi (make-rand 10000 .1))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (* (env ampf) (sin (rkoddssb gen (rand noi)))))))) |# ;;; -------------------------------------------------------------------------------- ;;; inf sinusoids scaled by kr^k: krksin ;;; Zygmund first ;;; this looks interesting, but how to normalize? sum of sines is bad enough, kr^k -> r/(1-r)^2 if x^2<1 (since n=inf) ;;; for low n, we could use the Tn roots stuff (clm.c) ;;; the formula must be assuming r<1.0 -- if greater than 1 it's acting like r2k! above (defgenerator (krksin :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) g)) (frequency *clm-default-frequency*) (r 0.5) (angle 0.0) fm) (define krksin (let ((documentation "(make-krksin frequency (r 0.5)) creates a krksin generator. (krksin gen (fm 0.0)) returns many sines spaced by frequency with amplitude kr^k.")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let* ((x angle) (r1 (- 1.0 r)) (r2 (* r r)) (r3 (if (> r .9) r1 1.0)) ; not right yet... (den (+ 1.0 (* -2.0 r (cos x)) r2))) (set! angle (+ angle fm frequency)) (/ (* r1 r1 r3 (sin x)) (* den den))))))) #| (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-krksin 440.0 0.5))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (krksin gen))))) (with-sound (:clipped #f :statistics #t :scaled-to .5 :play #t) (let ((gen (make-krksin 6.0 0.965))) ; 60 .6 also (do ((i 0 (+ i 1))) ((= i 100000)) (outa i (krksin gen))))) (do ((i 0 (+ i 1))) ((= i 10)) (let ((mx (maxamp (with-sound (:clipped #f :output (make-float-vector 10000)) (let ((gen (make-krksin 20.0 (* i 0.1)))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (krksin gen)))))))) (format #t ";~A: ~A" (* 0.1 i) mx))) ;;; relation between 1/(1-x)^2 and peak amp: (with-sound (:clipped #f) (do ((i 0 (+ i 1)) (r 0.0 (+ r .01))) ((= i 100)) (let ((val (/ 1.0 (expt (- 1 r) 2)))) (let ((pk 0.0)) (let ((gen (make-krksin 1.0 r))) (do ((k 0 (+ k 1))) ((= k 100000)) (let ((x (abs (krksin gen)))) (if (> x pk) (set! pk x))))) (outa i (/ pk val)))))) ;;; r 0: 1.0 (sin(x) in this case) ;;; else min den is (1-2r+r^2) so peak should be around (/ (expt (+ 1 (* - 2 r) (* r r)) 2)) ;;; but at that point sin(x)->0 as x |# #| ;;; -------------------------------------------------------------------------------- ;;; absolute value of oscil: abssin ;;; Zygmund second -- not actually very useful, but shows cos 2nx of abs (define abssin-methods (list (cons 'mus-frequency (dilambda (lambda (g) (mus-frequency (g 'osc))) (lambda (g val) (set! (mus-frequency (g 'osc)) val)))) (cons 'mus-phase (dilambda (lambda (g) (mus-phase (g 'osc))) (lambda (g val) (set! (mus-phase (g 'osc)) val)))))) (defgenerator (abssin :make-wrapper (lambda (g) (set! (g 'osc) (make-oscil (g 'frequency))) g) :methods abssin-methods) (frequency *clm-default-frequency*) fm (osc #f)) (define abssin (let ((documentation "(make-abssin frequency) creates an abssin generator. (abssin gen (fm 0.0)) returns (abs oscil).")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (/ (- (abs (oscil osc fm)) (/ 2.0 pi)) (/ 2.0 pi)))))) ; original went from 0 to 1.0, subtract 2/pi, and we get peak at -2/pi ;; DC: sin^2 x = 1/2 - cos 2x, ;; so every term in the sum adds 1/(2(4k^2-1)) -> 1/4 (J 397 or 373) ;; so DC is 2/pi = 0.6366 (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-abssin 440.0))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (abssin gen))))) (with-sound (:clipped #f :statistics #t :play #t) (let ((vib (make-abssin 100.0)) ; spacing will be 200, if FM you get index-proportional amount as constant offset (gen (make-oscil 1000.0)) (ampf (make-env '(0 0 1 1 2 1 3 0) :scaler .5 :length 20000))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (* (env ampf) (oscil gen 0.0 (* 3 (abssin vib 0.0)))))))) ;;; pitch is 2*freq, 200 1, 400 .203, 600 .087, 800 .049, 1000 .031, 1200 .021 ;;; 1 .2 .086 .048 .030 .021 -- (/ 3.0 (- (* 4 (* 6 6)) 1)) |# ;;; -------------------------------------------------------------------------------- ;;; inf cosines, scaled by (-a+sqrt(a^2-b^2))^n/b^n: abcos ;;; from Sansone, p182, assumptions: a not 0, b not 0, b/a real, abs(b/a)<1 (b less than a) (defgenerator (abcos :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) (set! (g 'ab) (sqrt (- (* (g 'a) (g 'a)) (* (g 'b) (g 'b))))) (set! (g 'norm) (/ 0.5 (- (/ 1.0 (- 1.0 (/ (abs (- (g 'ab) (g 'a))) (g 'b)))) 1.0))) ;; i.e. 1/(1-r) -1 because we start at k=1, r=the complicated a/b business g)) (frequency *clm-default-frequency*) (a 0.5) (b 0.25) (angle 0.0) ab norm fm) (define abcos (let ((documentation "(make-abcos frequency (a 0.5) (b 0.25)) creates an abcos generator. (abcos gen (fm 0.0)) returns many cosines spaced by frequency with amplitude (-a+sqrt(a^2-b^2))^k/b^k.")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let ((x angle)) (set! angle (+ angle fm frequency)) (* norm (- (/ ab (+ a (* b (cos x)))) 1.0))))))) #| (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-abcos 100.0 0.5 0.25))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (abcos gen))))) |# (defgenerator (absin :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) (set! (g 'ab) (sqrt (- (* (g 'a) (g 'a)) (* (g 'b) (g 'b))))) g)) (frequency *clm-default-frequency*) (a 0.5) (b 0.25) (angle 0.0) ab fm) (define absin (let ((documentation "(make-absin frequency (a 0.5) (b 0.25)) creates an absin generator. (absin gen (fm 0.0)) returns many sines spaced by frequency with amplitude (-a+sqrt(a^2-b^2))^k/b^k.")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let ((x angle)) (set! angle (+ angle fm frequency)) (/ (* ab (sin x) ) (+ a (* b (cos x))))))))) #| (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-absin 100.0 0.5 0.25))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (* .5 (absin gen)))))) |# ;;; -------------------------------------------------------------------------------- ;;; inf cosines scaled by 1/(r^2+k^2): r2k2cos ;;; J second col third row (defgenerator (r2k2cos :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) g)) (frequency *clm-default-frequency*) (r 1.0) (angle 0.0) fm) (define (r2k2cos-norm a) ;; J 124 (- (* (/ pi (* 2 a)) (/ (cosh (* pi a)) (sinh (* pi a)))) (/ 1.0 (* 2 a a)))) (define r2k2cos (let ((documentation "(make-r2k2cos frequency (r 1.0)) creates an r2k2cos generator. (r2k2cos gen (fm 0.0)) returns many cosines spaced by frequency with amplitude 1/(r^2+k^2).")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let ((x angle) (a r)) (if (> x (* 2 pi)) (set! x (modulo x (* 2 pi)))) (set! angle (+ x fm frequency)) (/ (- (* pi (/ (cosh (* a (- pi x))) (sinh (* a pi)))) (/ a)) (* 2 a (r2k2cos-norm a)))))))) #| (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-r2k2cos 100.0 1.0))) ; 400 .25 -- this isn't very flexible (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (* .5 (r2k2cos gen)))))) |# ;;; -------------------------------------------------------------------------------- ;;; coskx/k = -ln(2sin(x/2)) or 1/2ln(1/(2-2cosx)) ;;; sinkx/k = (pi-x)/2 both 0..2pi ;;; similarly -1^k : x/2 and ln(2cos(x/2)) (p44..46) ;;; 2k-1: pi/x and 1/2ln cot (x/2) 0..2pi and 0..pi ;;; but all of these are unbounded, and discontinuous ;;; -------------------------------------------------------------------------------- #| ;;; from Stilson/Smith apparently -- was named "Discrete Summation Formula" which doesn't convey anything to me ;;; Alexander Kritov suggests time-varying "a" is good (this is a translation of his code) (defgenerator (blsaw :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) g)) (frequency *clm-default-frequency*) (n 1) (r 0.5) (angle 0.0) fm) (define blsaw (let ((documentation "(make-blsaw frequency (n 1) (r 0.5)) creates a blsaw generator. (blsaw gen (fm 0.0)) returns a band-limited sawtooth wave.")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let* ((a r) (N n) (x angle) (incr frequency) (den (+ 1.0 (* -2.0 a (cos x)) (* a a)))) (set! angle (+ angle fm incr)) (if (< (abs den) nearly-zero) 0.0 (let* ((s1 (* (expt a (- N 1.0)) (sin (+ (* (- N 1.0) x) incr)))) (s2 (* (expt a N) (sin (+ (* N x) incr)))) (s3 (* a (sin (+ x incr))))) (/ (+ (sin incr) (- s3) (- s2) s1) den)))))))) (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-blsaw 440.0 :r 0.5 :n 3))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (blsaw gen))))) |# ;;; -------------------------------------------------------------------------------- ;;; asymmetric fm gens (defgenerator (asyfm :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) g)) (frequency *clm-default-frequency*) (ratio 1.0) (r 1.0) (index 1.0) (phase 0.0) fm) (define asyfm-J (let ((documentation "(asyfm-J gen fm) is the same as the CLM asymmetric-fm generator (index=1.0), set r != 1.0 to get the asymmetric spectra")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let* ((r1 (/ r)) (one (if (or (> r 1.0) (< -1.0 r 0.0)) -1.0 1.0)) (modphase (* ratio phase)) (result (* (exp (* 0.5 index (- r r1) (+ one (cos modphase)))) (cos (+ phase (* 0.5 index (+ r r1) (sin modphase))))))) ; use cos, not sin, to get predictable amp (set! phase (+ phase fm frequency)) result))))) #| (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-asyfm 2000.0 :ratio .1))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (* .5 (asyfm-J gen)))))) (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-asyfm 2000.0 :ratio .1 :index 1)) (r-env (make-env '(0 -4 1 -1) :length 20000))) (do ((i 0 (+ i 1))) ((= i 20000)) (set! (gen 'r) (env r-env)) (outa i (asyfm-J gen))))) (define (val index r) (let ((sum 0.0)) (do ((i -20 (+ i 1))) ((= i 21)) (set! sum (+ sum (* (expt r i) (bes-jn i index))))) (let ((norm (exp (* 0.5 index (- r (/ r)))))) (list sum norm)))) (for-each (lambda (index) (for-each (lambda (r) (let ((peak (maxamp (with-sound (:clipped #f :output (make-float-vector 1000)) (let ((gen (make-asymmetric-fm 2000.0 :ratio .1 :r r))) (do ((i 0 (+ i 1))) ((= i 1000)) (outa i (asymmetric-fm gen index)))))))) (if (> (abs (- peak 1.0)) .1) (format #t ";asymmetric-fm peak: ~A, index: ~A, r: ~A" peak index r)))) (list -10.0 -1.5 -0.5 0.5 1.0 1.5 10.0))) (list 1.0 3.0 10.0)) |# (define asyfm-I (let ((documentation "(asyfm-I gen fm) is the I0 case of the asymmetric-fm generator")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let* ((r1 (/ r)) (modphase (* ratio phase)) (result (* (exp (* 0.5 index (+ r r1) (- (cos modphase) 1.0))) (cos (+ phase (* 0.5 index (- r r1) (sin modphase))))))) (set! phase (+ phase fm frequency)) result))))) #| (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-asyfm 2000.0 :ratio .1))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (* .5 (asyfm-I gen)))))) |# ;;; -------------------------------------------------------------------------------- ;;; bess (returns bes-jn, like oscil returns sin) normalized to peak at 1.0 ;;; frequency here is the frequency in Hz of the damped sinusoid part of the bessel function (define bessel-peaks (vector 1.000 0.582 0.487 0.435 0.400 0.375 0.355 0.338 0.325 0.313 0.303 0.294 0.286 0.279 0.273 0.267 0.262 0.257 0.252 0.248)) (defgenerator (bess :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) (if (>= (g 'n) (length bessel-peaks)) (set! (g 'norm) (/ 0.67 (expt (g 'n) 1/3))) ;; this formula comes from V P Krainov, "Selected Mathetical Methods in Theoretical Physics" (set! (g 'norm) (bessel-peaks (g 'n)))) g)) (frequency *clm-default-frequency*) (n 0) (angle 0.0) (norm 1.0) fm) (define bess (let ((documentation "(make-bess frequency (n 0)) creates a bessel function (Jn) generator. (bess gen (fm 0.0)) returns Jn.")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let ((result (/ (bes-jn n angle) norm))) (set! angle (+ angle frequency fm)) result))))) #| (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-bess 100.0 :n 0))) (do ((i 0 (+ i 1))) ((= i 1000)) (outa i (bess gen))))) (with-sound (:clipped #f :statistics #t :play #t) (let ((gen1 (make-bess 400.0 :n 1)) (gen2 (make-bess 400.0 :n 1)) (vol (make-env '(0 0 1 1 9 1 10 0) :scaler 2.0 :length 20000))) (do ((i 0 (+ i 1))) ((= i 20000)) (outa i (bess gen1 (* (env vol) (bess gen2 0.0))))))) ;;; max amps: (do ((i 1 (+ i 1))) ((= i 100)) (let ((mx 0.0)) (do ((k 0.0 (+ k .001))) ((> k 200)) (let ((val (bes-jn i k))) (if (> (abs val) mx) (set! mx (abs val))))) (format #t ";~A" (+ mx .001)))) (with-sound (:clipped #f :statistics #t :play #t) (let ((gen1 (make-bess 400.0 :n 1)) (gen2 (make-oscil 400.0)) (vol (make-env '(0 1 1 0) :scaler 1.0 :length 20000))) (do ((i 0 (+ i 1))) ((= i 20000)) (outa i (bess gen1 (* (env vol) (oscil gen2 0.0))))))) ;;; also gen2 800, env scl 0.2 |# ;;; -------------------------------------------------------------------------------- ;;; Watson "Bessel Functions" p358 127 128 (J0(k sqrt(r^2+a^2- 2ar cos x)) = sum em Jm(ka)Jm(kr) cos mx ;;; em here is "Neumann's factor" (p22) = 1 if m=0, 2 otherwise (defgenerator (jjcos :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) g)) (frequency *clm-default-frequency*) (r 0.5) (a 1.0) (k 1.0) (angle 0.0) fm) (define jjcos (let ((documentation "(make-jjcos frequency (r 0.5) (a 1.0) (k 1)) creates a jjcos generator. (jjcos gen (fm 0.0)) returns a sum of cosines scaled by a product of Bessel functions.")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let* ((x angle) (dc (* (bes-j0 (* k a)) (bes-j0 (* k r)))) (norm (- (bes-j0 (* k (sqrt (+ (* a a) (* r r) (* -2 a r))))) dc))) ;; this norm only works if the a/r/k values all small enough that the initial J0 bump dominates ;; if they're large (k=10 for example), later maxes come into play. ;; we need a formula for a sum of JJ's ;; ;; the resultant spectra are similar to FM (we can get sharper bumps, or low-passed bumps, etc) (set! angle (+ angle fm frequency)) (/ (- (bes-j0 (* k (sqrt (+ (* r r) (* a a) (* a (* -2.0 r (cos x))))))) dc) ; get rid of DC component norm)))))) #| (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-jjcos 100.0 :a 1.0 :r 1.0 :k 1))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (* .5 (jjcos gen)))))) ;;; example: (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-jjcos 100.0 :a 2.0 :r 1.0 :k 1))) (do ((i 0 (+ i 1))) ((= i 20000)) (outa i (jjcos gen))))) :(* (bes-jn 1 1) (bes-jn 1 2)) 0.253788089467046 :(* (bes-jn 2 1) (bes-jn 2 2)) 0.0405418594904987 :(* (bes-jn 3 1) (bes-jn 3 2)) 0.00252256243314325 :(* (bes-jn 4 1) (bes-jn 4 2)) 8.41951242883886e-5 which matches perfectly set k=10 :(* (bes-jn 1 10) (bes-jn 1 20)) 0.00290541944296873 :(* (bes-jn 2 10) (bes-jn 2 20)) -0.0408277687368493 :(* (bes-jn 3 10) (bes-jn 3 20)) -0.00577380202685643 :(* (bes-jn 4 10) (bes-jn 4 20)) -0.0286956880041051 :(* (bes-jn 5 10) (bes-jn 5 20)) -0.0353830269096024 :(* (bes-jn 6 10) (bes-jn 6 20)) 7.96480491715688e-4 :(* (bes-jn 7 10) (bes-jn 7 20)) -0.0399227881572529 :(* (bes-jn 8 10) (bes-jn 8 20)) -0.0234795438775677 :(* (bes-jn 9 10) (bes-jn 9 20)) 0.0365188087949483 :(* (bes-jn 10 10) (bes-jn 10 20)) 0.0386925399194178 :(* (bes-jn 11 10) (bes-jn 11 20)) 0.00755397504265978 :(* (bes-jn 12 10) (bes-jn 12 20)) -0.00754046620160803 :(* (bes-jn 13 10) (bes-jn 13 20)) -0.00591450759566936 :(* (bes-jn 14 10) (bes-jn 14 20)) -0.00175050411436045 :(* (bes-jn 15 10) (bes-jn 15 20)) -3.66078549147997e-6 which again matches (define* (jjsin gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let ((x angle)) (set! angle (+ angle fm frequency)) (* (sin x) (bes-j0 (* k (sqrt (+ (* r r) (* a a) (* a (* -2.0 r (cos x))))))))))) (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-jjcos 100.0 :a 1.0 :r 1.0 :k 1))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (jjsin gen))))) (define* (jjesin gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let ((x angle)) (set! angle (+ angle fm frequency)) (* (exp (* r (- (cos x) 1.0))) ; -1 for norm , but there's huge DC offset (bes-j0 (* r (sin x))))))) (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-jjcos 100.0 :a 1.0 :r 1.0 :k 1))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (jjesin gen))))) |# ;;; -------------------------------------------------------------------------------- ;;; check J0(zsinx) formula ;;; main difference from FM: index is divided by 2, J value is squared, else just like cos(sin) (defgenerator (j0evencos :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) g)) (frequency *clm-default-frequency*) (index 1.0) (angle 0.0) fm) (define j0evencos (let ((documentation "(make-j0evencos frequency (index 1.0)) creates a j0evencos generator. (j0evencos gen (fm 0.0)) returns a sum of cosines scaled Jk^2(index/2).")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let* ((x angle) (z index) (j0 (bes-j0 (* 0.5 z))) (dc (* j0 j0))) (set! angle (+ angle fm frequency)) (if (= dc 1.0) 1.0 (/ (- (bes-j0 (* z (sin x))) dc) ; get rid of DC component (- 1.0 dc)))))))) ; normalize #| (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-j0evencos 100.0 1.0))) (do ((i 0 (+ i 1))) ((= i 30000)) (outa i (* .5 (j0evencos gen)))))) index 10 (so 10/2 is the bes-jn arg): (let ((base (* (bes-jn 4 5.0) (bes-jn 4 5.0)))) ; max (fft norms -> 1.0) (do ((i 1 (+ i 1))) ((= i 11)) (format #t ";~A: ~A ~A" i (* (bes-jn i 5.0) (bes-jn i 5.0)) (/ (* (bes-jn i 5.0) (bes-jn i 5.0)) base)))) ;1: 0.107308091385168 0.701072497819036 ;2: 0.00216831005396058 0.0141661502497507 ;3: 0.133101826831083 0.86958987897572 ;4: 0.153062759870046 1.0 ;5: 0.0681943848279407 0.445532178342005 ;6: 0.0171737701015899 0.112200839160164 ;7: 0.00284904116112987 0.0186135488707298 ;8: 3.38752000110201e-4 0.00221315753353599 ;9: 3.04735259399795e-5 1.99091705688911e-4 ;10: 2.15444461145164e-6 1.4075563600714e-5 (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-j0evencos 100.0 0.0)) (indf (make-env '(0 0 1 20) :length 30000))) (do ((i 0 (+ i 1))) ((= i 30000)) (set! (gen 'index) (env indf)) (outa i (* 0.5 (j0evencos gen)))))) (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-j0evencos 100.0 0.0)) (indf (make-env '(0 0 1 20) :length 30000)) (carrier (make-oscil 2000.0))) (do ((i 0 (+ i 1))) ((= i 30000)) (set! (gen 'index) (env indf)) (outa i (* 0.5 (oscil carrier) (j0evencos gen)))))) ;;; why no "carrier"? I subtracted DC out above -- to make this look right, I need to use the bes(sin) without any fixup. (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-j0evencos 100.0 0.0)) (indf (make-env '(0 20 1 0) :length 30000)) (carrier (make-oscil 2000.0))) (do ((i 0 (+ i 1))) ((= i 30000)) (set! (gen 'index) (env indf)) (outa i (* 0.5 (j0evencos gen (oscil carrier))))))) (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-j0evencos 100.0 0.0)) ; also 20 800, 20 200 (less index mvt), or 200 50 (indf (make-env '(0 10 1 0) :length 30000)) (carrier (make-oscil 2000.0))) (do ((i 0 (+ i 1))) ((= i 30000)) (set! (gen 'index) (env indf)) (outa i (* 0.5 (j0evencos gen (* .1 (oscil carrier)))))))) (define (j0even beg dur freq amp mc-ratio index) (let* ((gen (make-j0evencos (* mc-ratio freq) 0.0)) (indf (make-env '(0 10 1 0) :duration dur)) (carrier (make-oscil freq)) (start (seconds->samples beg)) (end (+ start (seconds->samples dur)))) (do ((i start (+ i 1))) ((= i end)) (set! (gen 'index) (env indf)) (outa i (* 0.5 (j0evencos gen (* index (oscil carrier)))))))) (with-sound (:clipped #f :statistics #t :play #t) (do ((i 0 (+ i 1))) ((= i 10)) (j0even i 1.0 2000.0 0.5 (+ .1 (* .05 i)) 0.1))) (define* (jfm beg dur freq amp mc-ratio index (index-env '(0 1 1 1 2 0))) (let* ((start (seconds->samples beg)) (end (+ start (seconds->samples dur))) (md (make-j0evencos (* freq mc-ratio))) (cr (make-oscil 2000)) (vib (make-oscil 5)) (vibamp (hz->radians (* freq .01))) (ampf (make-env '(0 0 1 1 20 1 21 0) :scaler amp :duration dur)) (indf (make-env index-env :scaler index :duration dur))) (do ((i start (+ i 1))) ((= i end)) (let ((vb (* vibamp (oscil vib)))) (set! (md 'index) (env indf)) (outa i (* (env ampf) (oscil cr vb) (j0evencos md (* vb mc-ratio)))))))) (with-sound ("test1.snd" :play #t) (jfm 0 3.0 400.0 0.5 .5 4.0 '(0 1 1 2 2 .5))) |# ;;; -------------------------------------------------------------------------------- (defgenerator (j2cos :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) (if (< (g 'n) 1) (set! (g 'n) 1)) g)) (frequency *clm-default-frequency*) (r 0.5) (n 1) (angle 0.0) fm) (define j2cos (let ((documentation "(make-j2cos frequency (r 0.5) (n 1)) creates a j2cos generator. (j2cos gen (fm 0.0)) returns a sum of cosines scaled in a very complicated way.")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let* ((x angle) (rsinx2 (* 2.0 r (sin (* 0.5 x))))) (set! angle (+ angle fm frequency)) (if (< (abs rsinx2) nearly-zero) 1.0 (/ (bes-jn n rsinx2) rsinx2))))))) ;;; this goes berserk if n=0, needs normalization, dc omission, doc/test ;;; if n=1, sample 0 = 1, the rest are in the .5 range! ;;; maybe j2cos isn't all that useful... #| (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-j2cos 100.0 :r 1.0 :n 0))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (* .5 (j2cos gen)))))) |# ;;; -------------------------------------------------------------------------------- (defgenerator (jpcos :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) (if (= (g 'r) (g 'a)) (begin (snd-warning (format #f ";jpcos r and a can't be equal (~A)" (g 'r))) (set! (g 'r) (+ (g 'a) .01)))) g)) (frequency *clm-default-frequency*) (r 0.5) (a 0.0) (k 1.0) (angle 0.0) fm) (define jpcos (let ((documentation "(make-jpcos frequency (r 0.5) (a 0.0) (k 1)) creates a jpcos generator. (jpcos gen (fm 0.0)) returns a sum of cosines scaled in a very complicated way.")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let* ((x angle) ;; (dc (/ (* (sin (* k a)) (sin (* k r))) (* k a r))) ;; from P0(x)=1, J[1/2](x)=sqrt(2/(pi x))sin(x), omitting original 1/pi ;; G&R 914 (8.464), 974 (8.912), but it's missing some remaining (small) component ;; also omitting the original divide by (* pi (sqrt arg)) -- it's just an amplitude scaler ;; and in this context, we get -1..1 peak amps from the sin anyway. (arg (+ (* r r) (* a a) (* a (* -2.0 r (cos x)))))) (set! angle (+ angle fm frequency)) (if (< (abs arg) nearly-zero) ; r = a, darn it! This will produce a spike, but at least it's not a NaN 1.0 (sin (* k (sqrt arg))))))))) #| (with-sound (:clipped #f :statistics #t) (let ((gen (make-jpcos 100.0 :a 1.0 :r 0.5 :k 1))) (do ((i 0 (+ i 1))) ((= i 210000)) (outa i (jpcos gen))))) (with-sound (:clipped #f :statistics #t) (let* ((gen (make-jpcos 400.0 :a 1.0 :r 0.5 :k 10)) (dur 1.0) (samps (seconds->samples dur)) (ampf (make-env '(0 0 1 1 10 1 11 0) :duration dur :scaler 0.5)) (indf (make-env '(0 0 1 1) :duration dur :scaler 1.0))) (do ((i 0 (+ i 1))) ((= i samps)) (set! (gen 'r) (env indf)) (outa i (* (env ampf) (jpcos gen)))))) ;;; -.725, 1/.275 (with-sound (:clipped #f :scaled-to .5) (let* ((gen (make-oscil 100.0))) (do ((i 0 (+ i 1))) ((= i 44100)) (outa i (sqrt (+ 1.0 (oscil gen))))))) (with-sound (:clipped #f :scaled-to .5) (let* ((gen (make-oscil 100.0)) (indf (make-env '(0 .1 1 .9) :length 44100))) (do ((i 0 (+ i 1))) ((= i 44100)) (let ((ind (env indf))) (outa i (sqrt (+ (* 1.0 1.0) (* ind ind) (* -2 1.0 ind (oscil gen))))))))) ;;; rkcos r=.4 or so (.6?), so rkcos+indf is mostly equivalent? (k=scaler in both) (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-rkcos 440.0 :r 0.6)) (gen1 (make-oscil 440.0)) (indf (make-env '(0 .1 1 .8) :length 50000))) (do ((i 0 (+ i 1))) ((= i 50000)) (set! (gen 'r) (env indf)) (outa i (oscil gen1 (* (gen 'r) (rkcos gen))))))) |# ;;; -------------------------------------------------------------------------------- (defgenerator (jncos :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) (set! (g 'ra) (+ (* (g 'a) (g 'a)) (* (g 'r) (g 'r)))) g)) (frequency *clm-default-frequency*) (r 0.5) (a 1.0) (n 0) (angle 0.0) ra fm) (define jncos (let ((documentation "(make-jncos frequency (r 0.5) (a 1.0) (n 0)) creates a jncos generator. (jncos gen (fm 0.0)) returns a sum of cosines scaled in a very complicated way.")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let ((arg (sqrt (+ ra (* a (* -2.0 r (cos angle))))))) (set! angle (+ angle fm frequency)) (if (< arg nearly-zero) 1.0 (/ (bes-jn n arg) (expt arg n)))))))) #| (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-jncos 100.0 :a 0.5 :r 1.0 :n 0))) (do ((i 0 (+ i 1))) ((= i 41000)) (outa i (jncos gen))))) |# ;;; -------------------------------------------------------------------------------- ;;; use J0(cos)+J1(cos) to get full spectrum (defgenerator (j0j1cos :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) g)) (frequency *clm-default-frequency*) (index 1.0) (angle 0.0) fm) (define j0j1cos (let ((documentation "(make-j0j1cos frequency (index 1.0)) creates a j0j1cos generator. (j0j1cos gen (fm 0.0)) returns a sum of cosines scaled in a very complicated way.")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let* ((x angle) (z index) (j0 (bes-j0 (* 0.5 z))) (dc (* j0 j0)) (arg (* z (cos x)))) (set! angle (+ angle fm frequency)) (/ (- (+ (bes-j0 arg) (bes-j1 arg)) dc) ; get rid of DC component 1.215)))))) ; not the best... ; need to normalize j0j1cos -- min depends on index, so peak depends on max and min and dc ; (max (- 1.2154 dc) ; (- -0.5530 dc) #| (let ((mx 0.0) (x 0.0) (saved-x 0.0)) (do ((i 0 (+ i 1))) ((= i 1000)) (let ((val (+ (bes-j0 x) (bes-j1 x)))) (if (> (abs val) mx) (begin (set! mx (abs val)) (set! saved-x x))) (set! x (+ x .001)))) (list mx saved-x)) (1.21533317877749 0.825000000000001) (1.21533318495717 0.824863000002882) (1.21533318495718 0.824863061409846) (-0.552933995255066 4.57000000000269) (-0.552933995483144 4.56997100028488) (do ((i 0 (+ i 1))) ((= i 10)) (let ((pk (maxamp (with-sound ((make-float-vector 10000)) (let ((gen (make-j0j1cos 100.0 i))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (j0j1cos gen)))))))) (format #t ";~A: ~A" i pk))) ;0: 0.0 ;1: 0.555559098720551 ;2: 0.938335597515106 ;3: 0.953315675258636 ;4: 1.16509592533112 ;5: 1.21275520324707 ;6: 1.14727067947388 ;7: 1.07083106040955 ;8: 1.05760526657104 ;9: 1.11238932609558 ;10: 1.1824289560318 ;11: 1.21528387069702 ;12: 1.19094204902649 ;13: 1.14720714092255 ;14: 1.12512302398682 |# #| (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-j0j1cos 100.0 1.0))) (do ((i 0 (+ i 1))) ((= i 30000)) (outa i (j0j1cos gen))))) |# ;;; -------------------------------------------------------------------------------- (defgenerator (jycos :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) (set! (g 'r) (max .0001 (g 'r))) ; 0->inf in bes-y0 (let ((a (g 'a)) ; "c" (r (g 'r))); "b" (if (<= r a) (format #t ";jycos a: ~A must be < r: ~A" a r)) (if (<= (+ (* a a) (* r r)) (* 2 a r)) (format #t ";jycos a: ~A, r: ~A will cause bes-y0 to return -inf!" a r))) g)) (frequency *clm-default-frequency*) (r 1.0) (a 0.5) ; "b" and "c" in the docs (angle 0.0) fm) (define jycos (let ((documentation "(make-jycos frequency (r 1.0) (a 0.5)) creates a jycos generator. (jycos gen (fm 0.0)) returns a sum of cosines scaled by Yn(r)*Jn(r).")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let* ((x angle) (b r) (c a) (b2c2 (+ (* b b) (* c c))) (dc (* (bes-y0 b) (bes-j0 c))) (norm (abs (- (bes-y0 (sqrt (+ b2c2 (* -2 b c)))) dc)))) (set! angle (+ angle fm frequency)) (/ (- (bes-y0 (sqrt (+ b2c2 (* -2.0 b c (cos x))))) dc) norm)))))) ;;; oops -- bes-y0(0) is -inf! ;;; norm only works for "reasonable" a and r #| (with-sound (:clipped #f :statistics #t :play #f) (let ((gen (make-jycos 100.0 1.5 1.0)) (af (make-env '(0 0 1 1) :length 30000)) (rf (make-env '(0 3 1 3) :length 30000)) (ampf (make-env '(0 0 1 1 10 1 11 0) :scaler 0.5 :length 30000))) (do ((i 0 (+ i 1))) ((= i 30000)) (set! (gen 'a) (env af)) (set! (gen 'r) (env rf)) (outa i (* (env ampf) (jycos gen)))))) :(* (bes-yn 1 1.5) (bes-jn 1 1.0)) -0.181436652807559 :(* (bes-yn 2 1.5) (bes-jn 2 1.0)) -0.107112311628537 :(* (bes-yn 3 1.5) (bes-jn 3 1.0)) -0.0405654243875417 :(/ .107 .181) 0.591160220994475 [0.600] :(/ .040 .181) 0.220994475138122 [0.228] |# ;;; -------------------------------------------------------------------------------- #| (defgenerator (jcos :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) g)) (frequency *clm-default-frequency*) (n 0) (r 1.0) (a 0.5) ; "b" and "c" in the docs (angle 0.0) fm) (define jcos (let ((documentation "(make-jcos frequency (n 0) (r 1.0) (a 0.5)) creates a jcos generator. (jcos gen (fm 0.0)) returns a sum of cosines scaled in some complex manner.")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let* ((x angle) (b r) (c a) (dc (* (bes-j0 b) (bes-j0 c)))) (set! angle (+ angle fm frequency)) (- (bes-jn n (* (+ n 1) (sqrt (+ (* b b) (* c c) (* -2.0 b c (cos x)))))) dc)))))) (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-jcos 100.0 0 1.0 1.0))) (do ((i 0 (+ i 1))) ((= i 30000)) (outa i (jcos gen))))) |# ;;; -------------------------------------------------------------------------------- #| (defgenerator (sin2n :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) g)) (frequency *clm-default-frequency*) (n 1) (r 1.0) (angle 0.0) fm) (define sin2n (let ((documentation "(make-sin2n frequency (n 0) (r 1.0)) creates a sin2n generator. (sin2n gen (fm 0.0)) returns (r*sin)^(2n)")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let* ((x angle)) (set! angle (+ angle fm frequency)) (expt (* r (sin x)) (* 2 n))))))) (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-sin2n 100.0 2 1.0))) (do ((i 0 (+ i 1))) ((= i 30000)) (outa i (sin2n gen))))) |# ;;; -------------------------------------------------------------------------------- #| ;;; do we need modulo 2*pi for the angles? (it is not used in clm.c) :(let ((ph 0.0)) (do ((i 0 (+ i 1))) ((= i 22050)) (set! ph (+ ph (hz->radians 100.0)))) ph) 628.31850751536 :(let ((ph (* 2 pi 1000000))) (do ((i 0 (+ i 1))) ((= i 22050)) (set! ph (+ ph (hz->radians 100.0)))) (- ph (* 2 pi 1000000))) 628.318502381444 :(let ((ph (* 2 pi 1000000000))) (do ((i 0 (+ i 1))) ((= i 22050)) (set! ph (+ ph (hz->radians 100.0)))) (- ph (* 2 pi 1000000000))) 628.311109542847 :(let ((ph (* 2 pi 1000000000000))) (do ((i 0 (+ i 1))) ((= i 22050)) (set! ph (+ ph (hz->radians 100.0)))) (- ph (* 2 pi 1000000000000))) 624.462890625 ;; similar results from running oscil with 0.0 initial-phase, and 2*pi*1000000000, or running one ;; oscil for 3 hours at 6000 Hz -- the sinusoid is clean even around an angle of a billion -- worst ;; case increment is pi, so we get (say) a billion samples before we may notice a sag => ca. 8 hours. ;; I think that's a long enough tone... (In clm.c and here, the phase and increment are both doubles; ;; 53 bits of mantissa, billion=30, so we still have about 23 bits, which actually matches results above). |# ;;; -------------------------------------------------------------------------------- ;;; blackman as a waveform -- all the other fft windows could be implemented ;;; perhaps most useful as an amplitude envelope #| (defgenerator (blackman :make-wrapper (lambda (g) (let ((n (g 'n))) (set! n (min (max n 1) 10)) (set! (g 'frequency) (hz->radians (g 'frequency))) (case n ((1) (set! (g 'coeffs) (float-vector 0.54 -0.46))) ((2) (set! (g 'coeffs) (float-vector 0.34401 -0.49755 0.15844))) ((3) (set! (g 'coeffs) (float-vector 0.21747 -0.45325 0.28256 -0.04672))) ((4) (set! (g 'coeffs) (float-vector 0.084037 -0.29145 0.375696 -0.20762 0.041194))) ((5) (set! (g 'coeffs) (float-vector 0.097167 -0.3088448 0.3626224 -0.1889530 0.04020952 -0.0022008))) ((6) (set! (g 'coeffs) (float-vector 0.063964353 -0.239938736 0.3501594961 -0.247740954 0.0854382589 -0.012320203 0.0004377882))) ((7) (set! (g 'coeffs) (float-vector 0.04210723 -0.18207621 0.3177137375 -0.284437984 0.1367622316 -0.033403806 0.0034167722 -0.000081965))) ((8) (set! (g 'coeffs) (float-vector 0.027614462 -0.135382235 0.2752871215 -0.298843294 0.1853193194 -0.064888448 0.0117641902 -0.000885987 0.0000148711))) ((9) (set! (g 'coeffs) (float-vector 0.01799071953 -0.098795950 0.2298837751 -0.294112951 0.2243389785 -0.103248745 0.0275674108 -0.003839580 0.0002189716 -0.000002630))) ((10) (set! (g 'coeffs) (float-vector 0.0118717384 -0.071953468 0.1878870875 -0.275808066 0.2489042133 -0.141729787 0.0502002984 -0.010458985 0.0011361511 -0.000049617 0.0000004343)))) g)) :methods (list (cons 'mus-reset (lambda (g) (set! (g 'angle) 0.0))))) (frequency *clm-default-frequency*) (n 4) (coeffs #f) (angle 0.0) fm) (define blackman (let ((documentation "(make-blackman frequency (n 4)) creates a blackman generator. (blackman gen (fm 0.0)) returns the nth Blackman-Harris fft data window as a periodic waveform. (n <= 10)")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let ((x angle)) (set! angle (+ angle fm frequency)) (polynomial coeffs (cos x))))))) |# #| (with-sound (:clipped #f :statistics #t :play #t) (let ((black4 (make-blackman 440.0))) (do ((i 0 (+ i 1))) ((= i 20000)) (outa i (blackman black4 0.0))))) |# ;;; but that is the same as polyshape/polywave! (define blackman polywave) (define blackman? polywave?) (define* (make-blackman (frequency 440.0) (n 4)) (make-polywave frequency (case n ;; this data is from clm.c ((0) (list 0 0)) ((1) (list 0 0.54 1 -0.46)) ((2) (list 0 0.42323 1 -0.49755 2 0.078279)) ((3) (list 0 0.35875 1 0.48829 2 0.14128 3 -0.01168)) ((4) (list 0 0.287333 1 -0.44716 2 0.20844 3 -0.05190 4 0.005149)) ((5) (list 0 .293557 1 -.451935 2 .201416 3 -.047926 4 .00502619 5 -.000137555)) ((6) (list 0 .2712203 1 -.4334446 2 .2180041 3 -.0657853 4 .010761867 5 -.0007700127 6 .00001368088)) ((7) (list 0 .2533176 1 -.4163269 2 .2288396 3 -.08157508 4 .017735924 5 -.0020967027 6 .00010677413 7 -.0000012807)) ((8) (list 0 .2384331 1 -.4005545 2 .2358242 3 -.09527918 4 .025373955 5 -.0041524329 6 .00036856041 7 -.00001384355 8 .0000001161808)) ((9) (list 0 .2257345 1 -.3860122 2 .2401294 3 -.1070542 4 .03325916 5 -.00687337 6 .0008751673 7 -.0000600859 8 .000001710716 9 -.00000001027272)) ((10) (list 0 .2151527 1 -.3731348 2 .2424243 3 -.1166907 4 .04077422 5 -.01000904 6 .0016398069 7 -.0001651660 8 .000008884663 9 -.000000193817 10 .00000000084824))))) ;;; -------------------------------------------------------------------------------- ;;; we can add the sin(cos) and sin(sin) cases, using -index in the latter to get ;;; asymmetric fm since Jn(-B) = (-1)^n Jn(B) ;;; ;;; the same trick would work in the other two cases -- gapped spectra (defgenerator (fmssb :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) g)) (frequency *clm-default-frequency*) (ratio 1.0) (index 1.0) (angle 0.0) fm) (define fmssb (let ((documentation "(make-fmssb frequency (ratio 1.0) (index 1.0)) creates an fmssb generator. (fmssb gen (fm 0.0)) returns single-sideband FM.")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let* ((cx angle) (mx (* cx ratio))) (set! angle (+ angle fm frequency)) (- (* (cos cx) (sin (* index (cos mx)))) (* (sin cx) (sin (* index (sin mx)))))))))) ; use -index for the other side ;;; FM with complex index (define* (fpmc beg dur freq amp mc-ratio fm-index interp) (let* ((start (seconds->samples beg)) (end (+ start (seconds->samples dur))) (cr 0.0) (cr-frequency (hz->radians freq)) (md-frequency (hz->radians (* freq mc-ratio))) (md 0.0)) (do ((i start (+ i 1))) ((= i end)) (let ((val (sin (+ cr (* fm-index (sin md)))))) (outa i (* amp (+ (* (- 1.0 interp) (real-part val)) (* interp (imag-part val))))) (set! cr (+ cr cr-frequency)) (set! md (+ md md-frequency)))))) #| (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-fmssb 1000.0 0.1 :index 8.0))) ; 1 3 7 11 ... -- interesting effect (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (* .3 (fmssb gen)))))) (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-fmssb 1000.0 0.1 :index 8.0)) (ampf (make-env '(0 0 1 1 100 0) :base 32 :scaler .3 :length 30000)) (indf (make-env '(0 1 1 0) :length 30000 :scaler 8))) (do ((i 0 (+ i 1))) ((= i 30000)) (set! (gen 'index) (env indf)) (outa i (* (env ampf) (fmssb gen)))))) (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-fmssb 1000.0 0.05 :index 1.0)) (ampf (make-env '(0 0 1 1 100 0) :base 32 :scaler .3 :length 30000)) (indf (make-env '(0 1 1 0) :length 30000 :base 32 :scaler 10))) (do ((i 0 (+ i 1))) ((= i 30000)) (set! (gen 'index) (env indf)) (outa i (* (env ampf) (fmssb gen)))))) (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-fmssb 100.0 5.4 :index 1.0)) ; also 100 700 (ampf (make-env '(0 0 1 1 100 0) :base 32 :scaler .3 :length 30000)) ; also 0 0 1 1 3 1 100 0... ;; '(0 0 1 .75 2 1 3 .95 4 .5 10 0) -> bowed effect, '(0 0 1 .75 2 1 3 .125 4 .25 5 1 6 .8 20 0) ;; '(0 0 1 .75 2 1 3 .1 4 .7 5 1 6 .8 100 0) -> clickier attack (300 too) (indf (make-env '(0 1 1 0) :length 30000 :base 32 :scaler 10))) ;; '(0 0 1 1 3 0) (do ((i 0 (+ i 1))) ((= i 30000)) (set! (gen 'index) (env indf)) (outa i (* (env ampf) (fmssb gen)))))) (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-fmssb 10.0 2.0 :index 1.0)) (ampf (make-env '(0 0 1 1 3 1 100 0) :base 32 :scaler .3 :length 30000)) (indf (make-env '(0 1 1 0) :length 30000 :base 32 :scaler 10))) (do ((i 0 (+ i 1))) ((= i 30000)) (set! (gen 'index) (env indf)) (outa i (* (env ampf) (fmssb gen)))))) (with-sound (:statistics #t :scaled-to .5 :play #t) (let ((gen1 (make-fmssb 500 1)) (gen2 (make-fmssb 1000 .2)) (ampf (make-env '(0 0 1 1 100 0) :base 32 :length 30000)) (indf (make-env '(0 1 1 1 10 0) :scaler 5.0 :base 32 :length 30000))) (do ((i 0 (+ i 1))) ((= i 30000)) (let ((ind (env indf))) (set! (gen1 'index) ind) (set! (gen2 'index) ind) (outa i (* (env ampf) (+ (fmssb gen1 0.0) (fmssb gen2 0.0)))))))) ;;; imaginary machines (also imaginary beasts) |# (definstrument (machine1 beg dur cfreq mfreq amp index gliss) (let ((gen (make-fmssb cfreq (/ mfreq cfreq) :index 1.0)) (start (seconds->samples beg)) (stop (seconds->samples (+ beg dur))) (ampf (make-env '(0 0 1 .75 2 1 3 .1 4 .7 5 1 6 .8 100 0) :base 32 :scaler amp :duration dur)) (indf (make-env '(0 0 1 1 3 0) :duration dur :base 32 :scaler index)) (frqf (make-env (if (> gliss 0.0) '(0 0 1 1) '(0 1 1 0)) :duration dur :scaler (hz->radians (* (/ cfreq mfreq) (abs gliss)))))) (do ((i start (+ i 1))) ((= i stop)) (set! (gen 'index) (env indf)) (outa i (* (env ampf) (fmssb gen (env frqf))))))) #| (with-sound (:statistics #t :play #t) (do ((i 0.0 (+ i .5))) ((>= i 2.0)) (machine1 i .3 100 540 0.5 3.0 0.0) (machine1 i .1 100 1200 .5 10.0 200.0) (machine1 i .3 100 50 .75 10.0 0.0) (machine1 (+ i .1) .1 100 1200 .5 20.0 1200.0) (machine1 (+ i .3) .1 100 1200 .5 20.0 1200.0) (machine1 (+ i .3) .1 100 200 .5 10.0 200.0) (machine1 (+ i .36) .1 100 200 .5 10.0 200.0) (machine1 (+ i .4) .1 400 300 .5 10.0 -900.0) (machine1 (+ i .4) .21 100 50 .75 10.0 1000.0) )) (with-sound (:statistics #t :play #t) (do ((i 0.0 (+ i .2))) ((>= i 2.0)) (machine1 i .3 100 540 0.5 4.0 0.0) (machine1 (+ i .1) .3 200 540 0.5 3.0 0.0)) (do ((i 0.0 (+ i .6))) ((>= i 2.0)) (machine1 i .3 1000 540 0.5 6.0 0.0) (machine1 (+ i .1) .1 2000 540 0.5 1.0 0.0) )) (with-sound (:statistics #t :play #t :scaled-to .5) (let ((gen (make-rkoddssb 1000.0 2.0 0.875)) (noi (make-rand 15000 .02)) (gen1 (make-rkoddssb 100.0 0.1 0.9)) (ampf (make-env '(0 0 1 1 11 1 12 0) :duration 11.0 :scaler .5)) (frqf (make-env '(0 0 1 1 2 0 10 0 11 1 12 0 20 0) :duration 11.0 :scaler (hz->radians 10.0)))) (do ((i 0 (+ i 1))) ((= i (* 12 44100))) (outa i (* (env ampf) (+ (rkoddssb gen1 (env frqf)) (* .2 (sin (rkoddssb gen (rand noi))))))))) (do ((i 0.0 (+ i 2))) ((>= i 10.0)) (machine1 i 3 100 700 0.5 4.0 0.0) (machine1 (+ i 1) 3 200 700 0.5 3.0 0.0)) (do ((i 0.0 (+ i 6))) ((>= i 10.0)) (machine1 i 3 1000 540 0.5 6.0 0.0) (machine1 (+ i 1) 1 2000 540 0.5 1.0 0.0) )) (with-sound (:statistics #t :play #t) (do ((i 0.0 (+ i .2))) ((>= i 2.0)) (machine1 i .3 1200 540 0.5 40.0 0.0) (machine1 (+ i .1) .3 2400 540 0.5 3.0 0.0)) (do ((i 0.0 (+ i .6))) ((>= i 2.0)) (machine1 i .3 1000 540 0.5 6.0 0.0) (machine1 (+ i .1) .1 2000 540 0.5 10.0 100.0) )) ;;; same as above but up octave (with-sound (:statistics #t :play #t) (do ((i 0.0 (+ i .1))) ((>= i 2.0)) (machine1 i .15 2400 1080 0.25 40.0 0.0) (machine1 (+ i .05) .2 4800 1080 0.5 3.0 0.0)) (do ((i 0.0 (+ i .3))) ((>= i 2.0)) (machine1 i .15 2000 1080 0.5 6.0 0.0) (machine1 (+ i .05) .1 4000 1080 0.5 10.0 100.0) )) |# (define (fm-cancellation beg dur frequency ratio amp index) (let* ((cx 0.0) (mx 0.0) (car-frequency (hz->radians frequency)) (mod-frequency (hz->radians ratio)) (start (seconds->samples beg)) (stop (+ start (seconds->samples dur)))) (do ((i start (+ i 1))) ((= i stop)) (outa i (* amp (- (* (cos cx) (sin (* index (cos mx)))) (* (sin cx) (sin (* index (sin mx)))))) ;; use -index for reflection ) (set! cx (+ cx car-frequency)) (set! mx (+ mx mod-frequency))))) ;(with-sound () (fm-cancellation 0 1 1000.0 100.0 0.3 9.0)) ;;; -------------------------------------------------------------------------------- ;;; k3sin (define k3sin-methods (list (cons 'mus-reset (lambda (g) (set! (g 'frequency) 0.0) (set! (g 'angle) 0.0))))) (defgenerator (k3sin :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) (set! (g 'coeffs) (float-vector 0.0 (/ (* pi pi) 6.0) (/ pi -4.0) (/ 12.0))) g) :methods k3sin-methods) (frequency *clm-default-frequency*) (angle 0.0) (coeffs #f) fm) (define k3sin (let ((documentation "(make-k3sin frequency) creates a k3sin generator. (k3sin gen (fm 0.0)) returns a sum of sines scaled by k^3.")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let ((x angle)) (if (not (<= 0.0 x two-pi)) (set! x (modulo x two-pi))) (set! angle (+ x fm frequency)) (polynomial coeffs x)))))) #| (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-k3sin 100.0))) (do ((i 0 (+ i 1))) ((= i 30000)) (outa i (k3sin gen))))) |# ;;; -------------------------------------------------------------------------------- ;;; I(z) case A&S (define izcos-methods (list (cons 'mus-scaler (dilambda (lambda (g) (g 'r)) (lambda (g val) (set! (g 'r) val) (set! (g 'dc) (bes-i0 val)) (set! (g 'norm) (- (exp val) (g 'dc))) (set! (g 'inorm) (/ (g 'norm))) val))))) (defgenerator (izcos :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) (set! (g 'dc) (bes-i0 (g 'r))) (set! (g 'norm) (- (exp (g 'r)) (g 'dc))) (set! (g 'inorm) (/ (g 'norm))) g) :methods izcos-methods) (frequency *clm-default-frequency*) (r 1.0) (angle 0.0) (dc 0.0) (norm 1.0) inorm fm) (define izcos (let ((documentation "(make-izcos frequency (r 1.0)) creates an izcos generator. (izcos gen (fm 0.0)) returns a sum of sines scaled by In(r).")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let ((x angle)) (set! angle (+ angle fm frequency)) (if (< (abs norm) nearly-zero) 1.0 (* (- (exp (* r (cos x))) dc) inorm))))))) #| (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-izcos 100.0 1.0))) (do ((i 0 (+ i 1))) ((= i 30000)) (outa i (* .5 (izcos gen)))))) (with-sound (:clipped #f :statistics #t) (let ((gen (make-izcos 100.0 1.0)) (indf (make-env '(0 0 1 3) :length 30000))) (do ((i 0 (+ i 1))) ((= i 30000)) (set! (mus-scaler gen) (env indf)) (outa i (izcos gen))))) |# ;;; -------------------------------------------------------------------------------- (definstrument (organish beg dur freq amp fm-index amp-env) ;; this has an organ-style chiff (better than fm index sweep) (let ((start (seconds->samples beg)) (carriers (make-vector 3 #f)) (fmoscs (make-vector 3 #f)) (ampfs (make-vector 3 #f)) (pervib (make-triangle-wave 5 (hz->radians (* freq .003)))) (ranvib (make-rand-interp 6 (hz->radians (* freq .002)))) (resc (make-nrssb 340.0 1.0 5 .5)) (resf (make-env (list 0 0 .05 1 .1 0 dur 0) :scaler (* amp .05) :duration dur))) (let ((stop (+ start (seconds->samples dur)))) (do ((i 0 (+ i 1))) ((= i 3)) (let* ((frq (* freq (expt 2 i))) (index1 (hz->radians (* fm-index frq (/ 5.0 (log frq))))) (index2 (hz->radians (* fm-index frq 3.0 (/ (- 8.5 (log frq)) (+ 3.0 (* frq .001)))))) (index3 (hz->radians (* fm-index frq (/ 4.0 (sqrt frq)))))) (set! (carriers i) (make-oscil frq)) (set! (fmoscs i) (make-polywave frq :partials (list 1 index1 3 index2 4 index3))))) (set! (ampfs 0) (make-env (or amp-env '(0 0 1 1 2 1 3 0)) :scaler amp :duration dur)) (set! (ampfs 1) (make-env (list 0 0 .04 1 .075 0 dur 0) :scaler (* amp .0125) :duration dur)) (set! (ampfs 2) (make-env (list 0 0 .02 1 .05 0 dur 0) :scaler (* amp .025) :duration dur)) ;; also good: ;; (set! (ampfs 1) (make-env (list 0 0 .02 1 .05 0 (- dur .1) 0 (- dur .05) 1 dur 0) :scaler (* amp .025) :duration dur)) ;; (set! (ampfs 2) (make-env (list 0 0 .01 1 .025 0 (- dur .15) 0 (- dur .1) 1 dur 0) :scaler (* amp .05) :duration dur)) (do ((i start (+ i 1))) ((= i stop)) (let ((vib (+ (triangle-wave pervib) (rand-interp ranvib)))) (outa i (+ (* (env resf) (nrssb resc 0.0)) (* (env (vector-ref ampfs 0)) (oscil (vector-ref carriers 0) (+ vib (polywave (vector-ref fmoscs 0) vib)))) (* (env (vector-ref ampfs 1)) (oscil (vector-ref carriers 1) (+ (* 2 vib) (polywave (vector-ref fmoscs 1) (* 2 vib))))) (* (env (vector-ref ampfs 2)) (oscil (vector-ref carriers 2) (+ (* 4 vib) (polywave (vector-ref fmoscs 2) (* 4 vib)))))))))))) #| (with-sound (:clipped #f :statistics #t :play #t) (do ((i 0 (+ i 1))) ((= i 10)) (organish (* i .3) .4 (+ 100 (* 50 i)) .5 1.0 #f))) (with-sound (:clipped #f :statistics #t :play #t) (do ((i 0 (+ i 1))) ((= i 10)) (organish (* i .3) .4 (+ 100 (* 50 i)) .5 1.0 '(0 0 1 1 2 .5 3 .25 4 .125 10 0)))) |# ;;; -------------------------------------------------------------------------------- (define adjustable-square-wave-methods (list (cons 'mus-frequency (dilambda (lambda (g) (mus-frequency (g 'p1))) (lambda (g val) (set! (mus-frequency (g 'p1)) val)))) (cons 'mus-phase (dilambda (lambda (g) (mus-phase (g 'p1))) (lambda (g val) (set! (mus-phase (g 'p1)) val)))) (cons 'mus-scaler (dilambda (lambda (g) (g 'duty-factor)) (lambda (g val) (set! (g 'duty-factor) val) (set! (mus-phase (g 'p2)) (* two-pi (- 1.0 (g 'duty-factor)))) val))))) (defgenerator (adjustable-square-wave :make-wrapper (lambda (g) (set! (g 'p1) (make-pulse-train (g 'frequency) (g 'amplitude))) (set! (g 'p2) (make-pulse-train (g 'frequency) (- (g 'amplitude)) (* two-pi (- 1.0 (g 'duty-factor))))) g) :methods adjustable-square-wave-methods) (frequency *clm-default-frequency*) (duty-factor 0.5) (amplitude 1.0) (sum 0.0) (p1 #f) (p2 #f) fm) (define adjustable-square-wave (let ((documentation "(make-adjustable-square-wave frequency (duty-factor 0.5) (amplitude 1.0)) creates an adjustable-square-wave generator. (adjustable-square-wave gen (fm 0.0)) returns a square-wave where the duty-factor sets the ratio of pulse duration to pulse period.")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (set! sum (+ sum (pulse-train p1 fm) (pulse-train p2 fm))))))) #| (with-sound () (let ((gen (make-adjustable-square-wave 100 .2 .5))) (do ((i 0 (+ i 1))) ((= i 22050)) (outa i (adjustable-square-wave gen))))) |# (define adjustable-triangle-wave-methods (list (cons 'mus-frequency (dilambda (lambda (g) (mus-frequency (g 'gen))) (lambda (g val) (set! (mus-frequency (g 'gen)) val)))) (cons 'mus-phase (dilambda (lambda (g) (mus-phase (g 'gen))) (lambda (g val) (set! (mus-phase (g 'gen)) val)))) (cons 'mus-scaler (dilambda (lambda (g) (g 'duty-factor)) (lambda (g val) (set! (g 'duty-factor) val) (set! (g 'top) (- 1.0 val)) (if (not (= val 0.0)) (set! (g 'scl) (/ (g 'amplitude) val))) val))))) (defgenerator (adjustable-triangle-wave :make-wrapper (lambda (g) (let ((df (g 'duty-factor))) (set! (g 'gen) (make-triangle-wave (g 'frequency))) (set! (g 'top) (- 1.0 df)) (set! (g 'mtop) (- (g 'top))) (if (not (= df 0.0)) (set! (g 'scl) (/ (g 'amplitude) df))) g)) :methods adjustable-triangle-wave-methods) (frequency *clm-default-frequency*) (duty-factor 0.5) (amplitude 1.0) (gen #f) (top 0.0) (mtop 0.0) (scl 0.0) val fm) (define adjustable-triangle-wave (let ((documentation "(make-adjustable-triangle-wave frequency (duty-factor 0.5) (amplitude 1.0)) creates an adjustable-triangle-wave generator. (adjustable-triangle-wave gen (fm 0.0)) returns a triangle-wave where the duty-factor sets the ratio of pulse duration to pulse period.")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (set! val (triangle-wave gen fm)) (* scl (- val (max mtop (min top val)))))))) #| (with-sound () (let ((gen (make-adjustable-triangle-wave 100 .2 .5))) (do ((i 0 (+ i 1))) ((= i 22050)) (outa i (adjustable-triangle-wave gen))))) |# (define adjustable-sawtooth-wave-methods (list (cons 'mus-frequency (dilambda (lambda (g) (mus-frequency (g 'gen))) (lambda (g val) (set! (mus-frequency (g 'gen)) val)))) (cons 'mus-phase (dilambda (lambda (g) (mus-phase (g 'gen))) (lambda (g val) (set! (mus-phase (g 'gen)) val)))) (cons 'mus-scaler (dilambda (lambda (g) (g 'duty-factor)) (lambda (g val) (set! (g 'duty-factor) val) (set! (g 'top) (- 1.0 val)) (set! (g 'mtop) (- val 1.0)) (if (not (= val 0.0)) (set! (g 'scl) (/ (g 'amplitude) val))) val))))) (defgenerator (adjustable-sawtooth-wave :make-wrapper (lambda (g) (let ((df (g 'duty-factor))) (set! (g 'gen) (make-sawtooth-wave (g 'frequency))) (set! (g 'top) (- 1.0 df)) (set! (g 'mtop) (- df 1.0)) (if (not (= df 0.0)) (set! (g 'scl) (/ (g 'amplitude) df))) g)) :methods adjustable-sawtooth-wave-methods) (frequency *clm-default-frequency*) (duty-factor 0.5) (amplitude 1.0) (gen #f) (top 0.0) (mtop 0.0) (scl 0.0) val fm) (define adjustable-sawtooth-wave (let ((documentation "(make-adjustable-sawtooth-wave frequency (duty-factor 0.5) (amplitude 1.0)) creates an adjustable-sawtooth-wave generator. (adjustable-sawtooth-wave gen (fm 0.0)) returns a sawtooth-wave where the duty-factor sets the ratio of pulse duration to pulse period.")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (set! val (sawtooth-wave gen fm)) (* scl (- val (max mtop (min top val)))))))) #| (with-sound () (let ((gen (make-adjustable-sawtooth-wave 100 .2 .5))) (do ((i 0 (+ i 1))) ((= i 22050)) (outa i (adjustable-sawtooth-wave gen))))) |# ;;; and just for laughs... (almost anything would fit in this hack) (define adjustable-oscil-methods (let ((copy-func (lambda (g) (let ((e (inlet g))) ; (copy g) without invoking (g 'copy) (let-set! e 'gen (mus-copy (g 'gen))) e)))) (list (cons 'mus-frequency (dilambda (lambda (g) (mus-frequency (g 'gen))) (lambda (g val) (set! (mus-frequency (g 'gen)) val)))) (cons 'mus-phase (dilambda (lambda (g) (mus-phase (g 'gen))) (lambda (g val) (set! (mus-phase (g 'gen)) val)))) (cons 'mus-scaler (dilambda (lambda (g) (g 'duty-factor)) (lambda (g val) (set! (g 'duty-factor) val) (set! (g 'top) (- 1.0 val)) (set! (g 'mtop) (- val 1.0)) (if (not (= val 0.0)) (set! (g 'scl) (/ val))) val))) (cons 'copy copy-func) (cons 'mus-copy copy-func)))) (defgenerator (adjustable-oscil :make-wrapper (lambda (g) (let ((df (g 'duty-factor))) (set! (g 'gen) (make-oscil (g 'frequency))) (set! (g 'top) (- 1.0 df)) (set! (g 'mtop) (- df 1.0)) (if (not (= df 0.0)) (set! (g 'scl) (/ df))) g)) :methods adjustable-oscil-methods) (frequency *clm-default-frequency*) (duty-factor 0.5) (gen #f) (top 0.0) (mtop 0.0) (scl 0.0) val fm) (define adjustable-oscil (let ((documentation "(make-adjustable-oscil frequency (duty-factor 0.5)) creates an adjustable-oscil generator. (adjustable-oscil gen (fm 0.0)) returns a sinusoid where the duty-factor sets the ratio of pulse duration to pulse period.")) (lambda* (g (fm 0.0)) (let-set! g 'fm fm) (with-let g (set! val (oscil gen fm)) (* scl (- val (max mtop (min top val)))))))) #| (with-sound (:statistics #t) (let ((gen (make-adjustable-oscil 100 .2))) (do ((i 0 (+ i 1))) ((= i 22050)) (outa i (adjustable-oscil gen))))) |# ;;;-------------------------------------------------------------------------------- (define* (make-table-lookup-with-env frequency pulse-env size) (let* ((len (or size *clm-table-size*)) (ve (make-float-vector len)) (e (make-env pulse-env :length len))) (do ((i 0 (+ i 1))) ((= i len)) (float-vector-set! ve i (env e))) (make-table-lookup frequency 0.0 ve len))) (define* (make-wave-train-with-env frequency pulse-env size) (let* ((len (or size *clm-table-size*)) (ve (make-float-vector len)) (e (make-env pulse-env :length len))) (do ((i 0 (+ i 1))) ((= i len)) (float-vector-set! ve i (env e))) (make-wave-train frequency 0.0 ve len))) ;;; -------------------------------------------------------------------------------- (define round-interp-methods (list (cons 'mus-frequency (dilambda (lambda (g) (mus-frequency (g 'rnd))) (lambda (g val) (set! (mus-frequency (g 'rnd)) val)))) (cons 'mus-phase (dilambda (lambda (g) (mus-phase (g 'rnd))) (lambda (g val) (set! (mus-phase (g 'rnd)) val)))))) (defgenerator (round-interp :make-wrapper (lambda (g) (set! (g 'rnd) (make-rand-interp (g 'frequency) (g 'amplitude))) (set! (g 'flt) (make-moving-average (g 'n))) g) :methods round-interp-methods) (frequency *clm-default-frequency*) (n 1) (amplitude 1.0) (rnd #f) (flt #f) fm) (define round-interp (let ((documentation "(make-round-interp frequency (n 1) (amplitude 1.0)) creates a round-interp generator. (round-interp gen (fm 0.0)) returns a rand-interp sequence low-pass filtered by a moving-average generator of length n.")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (moving-average flt (rand-interp rnd fm)))))) #| (with-sound (:channels 5) (let ((gen0 (make-round-interp 100 1)) (gen1 (make-round-interp 100 10)) (gen2 (make-round-interp 100 100)) (gen3 (make-round-interp 100 1000)) (gen4 (make-round-interp 100 10000))) (do ((i 0 (+ i 1))) ((= i 100000)) (out-any i (round-interp gen0 0.0) 0) (out-any i (round-interp gen1 0.0) 1) (out-any i (round-interp gen2 0.0) 2) (out-any i (round-interp gen3 0.0) 3) (out-any i (round-interp gen4 0.0) 4)))) |# ;;; -------------------------------------------------------------------------------- ;;; ;;; env-any functions (define (sine-env e) (env-any e (lambda (y) (* 0.5 (+ 1.0 (sin (+ (* -0.5 pi) (* pi y)))))))) (define (square-env e) (env-any e (lambda (y) (* y y)))) (define (blackman4-env e) (env-any e (lambda (y) (let ((cx (cos (* pi y)))) (+ 0.084037 (* cx (+ -.29145 (* cx (+ .375696 (* cx (+ -.20762 (* cx .041194)))))))))))) (define (multi-expt-env e expts) (env-any e (lambda (y) (let ((b (expts (modulo (channels e) (length expts))))) (/ (- (expt b y) 1.0) (- b 1.0)))))) ;;; -------------------------------------------------------------------------------- ;;; ;;; pm with any generator that has mus-phase and mus-run: (define (run-with-fm-and-pm gen fm pm) (set! (mus-phase gen) (+ (mus-phase gen) pm)) (let ((result (mus-run gen fm 0.0))) (set! (mus-phase gen) (- (mus-phase gen) pm)) result)) #| (let ((gen1 (make-oscil 440.0)) (gen2 (make-oscil 440.0))) (do ((i 0 (+ i 1))) ((= i 1000)) (let* ((pm (mus-random 1.0)) (val1 (oscil gen1 0.0 pm)) (val2 (run-with-fm-and-pm gen2 0.0 pm))) (if (fneq val1 val2) (format #t ";run-with-fm-and-pm: ~A ~A" val1 val2))))) |# ;;; -------------------------------------------------------------------------------- ;;; cos^n J 121 (defgenerator (nchoosekcos :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) g)) (frequency *clm-default-frequency*) (ratio 1.0) (n 1) (angle 0.0) fm) (define nchoosekcos (let ((documentation "(make-nchoosekcos frequency (ratio 1.0) (n 1)) creates an nchoosekcos generator. (nchoosekcos gen (fm 0.0)) returns a sum of cosines scaled by the binomial coeffcients.")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let* ((x angle) (y (* x ratio))) (set! angle (+ angle fm frequency)) (real-part (* (cos x) (expt (cos y) n)))))))) #| (with-sound (:clipped #f :statistics #t :play #t) (let ((gen (make-nchoosekcos 2000.0 0.05 10))) (do ((i 0 (+ i 1))) ((= i 30000)) (outa i (* .5 (nchoosekcos gen)))))) |# ;;; -------------------------------------------------------------------------------- ;;; ;;; sinc-train (define sinc-train-methods (list (cons 'mus-order (dilambda (lambda (g) (g 'original-n)) (lambda (g val) (if (<= val 0) (begin (set! (g 'original-n) 1) (set! (g 'n) 3)) (begin (set! (g 'original-n) val) (set! (g 'n) (+ 1 (* 2 val))))) (set! (g 'frequency) (* 0.5 (g 'n) (hz->radians (g 'original-frequency)))) (g 'original-n)))) (cons 'mus-frequency (dilambda (lambda (g) (g 'original-frequency)) (lambda (g val) (set! (g 'original-frequency) val) (set! (g 'frequency) (* 0.5 (g 'n) (hz->radians val))) val))))) (defgenerator (sinc-train :make-wrapper (lambda (g) (if (<= (g 'n) 0) (begin (set! (g 'original-n) 1) (set! (g 'n) 3)) (begin (set! (g 'original-n) (g 'n)) (set! (g 'n) (+ 1 (* 2 (g 'n)))))) ; mimic ncos (set! (g 'original-frequency) (g 'frequency)) (set! (g 'frequency) (* 0.5 (g 'n) (hz->radians (g 'frequency)))) g) :methods sinc-train-methods) (frequency *clm-default-frequency*) (n 1) (angle 0.0) (original-n 1) (original-frequency 0.0) fm) (define sinc-train (let ((documentation "(make-sinc-train frequency (n 1)) creates a sinc-train generator with n components. (sinc-train gen (fm 0.0)) returns a sinc-train")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let* ((x angle) (max-angle (* pi 0.5 n)) (new-angle (+ x fm frequency)) (DC (/ 1.0 n)) (norm (/ n (- n 1)))) (if (> new-angle max-angle) (set! new-angle (- new-angle (* pi n)))) (set! angle new-angle) (if (< (abs x) nearly-zero) 1.0 (* norm (- (/ (sin x) x) DC)))))))) #| (with-sound (:clipped #f :statistics #t) (let* ((g (make-sinc-train 100.0 40))) (do ((i 0 (+ i 1))) ((= i 44100)) (outa i (* .5 (sinc-train g 0.0)))))) |# ;;; -------------------------------------------------------------------------------- ;;; ;;; pink-noise (based on rand-bank idea of Orfanidis) #| (defgenerator (pink-noise :make-wrapper (lambda (g) (if (<= (g 'n) 0) (set! (g 'n) 1)) (let ((n (g 'n))) (set! (g 'rands) (make-vector n)) (do ((i 0 (+ i 1))) ((= i n)) (set! ((g 'rands) i) (make-rand :frequency (/ *clm-srate* (expt 2 i)))) (set! (mus-phase ((g 'rands) i)) (random pi)))) g)) (n 1) (rands #f)) (define pink-noise (let ((documentation "(make-pink-noise (n 1)) creates a pink-noise generator with n octaves of rand (12 is recommended). (pink-noise gen) returns the next random value in the 1/f stream produced by gen.")) (lambda (gen) (with-let gen (/ (rand-bank rands) (* 2.5 (sqrt n))))))) ; this normalization is not quite right |# (define* (make-pink-noise (n 1)) (let ((v (make-float-vector (* n 2))) (amp (/ (* 2.5 (sqrt n))))) (set! (v 0) amp) (do ((i 2 (+ i 2))) ((= i (* 2 n))) (set! (v i) (mus-random amp)) (set! (v (+ i 1)) (random 1.0))) v)) (define pink-noise? float-vector?) ;;; pink-noise func is in clm2xen.c #| (define (pink-noise v) (let ((amp (v 0)) (sum 0.0) (p 0.0) (len (length v))) (do ((i 2 (+ i 2)) (x 0.5 (* x 0.5))) ((= i len) (+ sum (mus-random amp))) (set! sum (+ sum (v i))) (set! p (- (v (+ i 1)) x)) (if (negative? p) (begin (set! (v (+ i 1)) (+ p 1.0)) (set! (v i) (mus-random amp))) (set! (v (+ i 1)) p))))) |# #| (with-sound (:clipped #f :statistics #t) (let ((gen (make-pink-noise 12))) (do ((i 0 (+ i 1))) ((= i 44100)) (outa i (pink-noise gen))))) (with-sound (:statistics #t) (let ((gen (make-pink-noise 12))) (do ((i 0 (+ i 1))) ((= i 441000)) (outa i (pink-noise gen))))) |# ;;; -------------------------------------------------------------------------------- ;;; ;;; brown-noise (defgenerator (brown-noise :make-wrapper (lambda (g) (set! (g 'gr) (make-rand (g 'frequency) (g 'amplitude))) g)) (frequency *clm-default-frequency*) (amplitude 1.0) fm gr (sum 0.0) (prev 0.0)) (define brown-noise (let ((documentation "(make-brown-noise frequency (amplitude 1.0)) returns a generator that produces brownian noise. (brown-noise gen (fm 0.0)) returns the next brownian noise sample.")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let ((val (rand gr fm))) (if (not (= val prev)) (begin (set! prev val) (set! sum (+ sum val)))) sum))))) #| ;; this is slightly faster, but ugly (define* (make-brown-noise (frequency 440.0) (amplitude 1.0)) (vector 0.0 0.0 (make-rand frequency amplitude))) (define (brown-noise? g) (and (vector? g) (= (length g) 3) (rand? (g 2)))) (define* (brown-noise g (fm 0.0)) (let ((val (rand (vector-ref g 2) fm))) (if (not (= val (vector-ref g 1))) (begin (vector-set! g 1 val) (vector-set! g 0 (+ (vector-ref g 0) val)))) (vector-ref g 0))) (with-sound (:clipped #f :statistics #t) (let* ((gen (make-brown-noise 1000))) (do ((i 0 (+ i 1))) ((= i 44100)) (outa i (* .01 (brown-noise gen)))))) |# ;;; -------------------------------------------------------------------------------- ;;; ;;; green-noise (defgenerator (green-noise :make-wrapper (lambda (g) (set! (g 'gr) (make-rand (g 'frequency) (g 'amplitude))) (set! (g 'sum) (* 0.5 (+ (g 'low) (g 'high)))) g)) (frequency *clm-default-frequency*) (amplitude 1.0) (low -1.0) (high 1.0) fm gr (sum 0.0) (prev 0.0)) (define green-noise (let ((documentation "(make-green-noise frequency (amplitude 1.0) (low -1.0) (high 1.0)) returns a new green-noise (bounded brownian noise) generator. (green-noise gen (fm 0.0)) returns the next sample in a sequence of bounded brownian noise samples.")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let ((val (rand gr fm))) (if (not (= val prev)) (begin (set! prev val) (set! sum (+ sum val)) (if (not (<= low sum high)) (set! sum (- sum (* 2 val)))))) sum))))) #| (define* (make-green-noise (frequency 440.0) (amplitude 1.0) (low -1.0) (high 1.0)) (vector 0.0 0.0 low high (make-rand frequency amplitude))) (define (green-noise? g) (and (vector? g) (= (length g) 5) (rand? (g 4)))) (define* (green-noise g (fm 0.0)) (let ((val (rand (g 4) fm))) (if (not (= val (g 1))) (begin (set! (g 1) val) (set! (g 0) (+ (g 0) val)) (if (not (<= (g 2) (g 0) (g 3))) (set! (g 0) (- (g 0) (* 2.0 val)))))) (g 0))) (with-sound (:clipped #f :statistics #t) (let* ((gen (make-green-noise 1000))) (do ((i 0 (+ i 1))) ((= i 44100)) (outa i (green-noise gen))))) |# ;;; -------------------------------------------------------------------------------- ;;; ;;; green-noise-interp (defgenerator (green-noise-interp :make-wrapper (lambda (g) (set! (g 'sum) (* 0.5 (+ (g 'low) (g 'high)))) (set! (g 'dv) (/ 1.0 (ceiling (/ *clm-srate* (max 1.0 (g 'frequency)))))) (set! (g 'frequency) (hz->radians (g 'frequency))) (set! (g 'incr) (* (mus-random (g 'amplitude)) dv)) g)) (frequency *clm-default-frequency*) (amplitude 1.0) (low -1.0) (high 1.0) (angle 0.0) (sum 0.0) (incr 0.0) fm dv) (define green-noise-interp (let ((documentation "(make-green-noise-interp frequency (amplitude 1.0) (low -1.0) (high 1.0)) returns a new interpolating green noise (bounded brownian noise) generator. (green-noise-interp gen (fm 0.0)) returns the next sample in a sequence of interpolated bounded brownian noise samples.")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (if (not (<= 0.0 angle two-pi)) (let ((val (mus-random amplitude))) (set! angle (modulo angle two-pi)) (if (< angle 0.0) (set! angle (+ angle two-pi))) (if (not (<= low (+ sum val) high)) (set! val (min (- high sum) (max (- low sum) (- val))))) ; at least bounce (set! incr (* dv val)))) (set! angle (+ angle fm frequency)) (set! sum (+ sum incr)))))) #| (with-sound (:clipped #f :statistics #t) (let* ((gen (make-green-noise-interp 1000))) (do ((i 0 (+ i 1))) ((= i 44100)) (outa i (green-noise-interp gen))))) (definstrument (green1 beg end freq amp lo hi) (let ((grn (make-green-noise :frequency freq :amplitude amp :high hi :low lo))) (do ((i beg (+ i 1))) ((= i end)) (outa i (green-noise grn 0.0))))) (definstrument (green2 beg end freq amp lo hi) (let ((grn (make-green-noise-interp :frequency freq :amplitude amp :high hi :low lo))) (do ((i beg (+ i 1))) ((= i end)) (outa i (green-noise-interp grn 0.0))))) (with-sound () (green1 0 10000 1000 0.1 -0.5 0.5) (green2 10000 20000 1000 0.1 -0.5 0.5)) (definstrument (green3 start dur freq amp amp-env noise-freq noise-width noise-max-step) ;; brownian noise on amp env (let ((grn (make-green-noise-interp :frequency noise-freq :amplitude noise-max-step :high (* 0.5 noise-width) :low (* -0.5 noise-width))) (osc (make-oscil freq)) (e (make-env amp-env :scaler amp :duration dur)) (beg (seconds->samples start)) (end (seconds->samples (+ start dur)))) (do ((i beg (+ i 1))) ((= i end)) (outa i (* (env e) (+ 1.0 (green-noise-interp grn 0.0)) (oscil osc)))))) (with-sound () (green3 0 2.0 440 .5 '(0 0 1 1 2 1 3 0) 100 .2 .02)) (definstrument (green4 start dur freq amp freq-env gliss noise-freq noise-width noise-max-step) ;; same but on freq env (let ((grn (make-green-noise-interp :frequency noise-freq :amplitude (hz->radians noise-max-step) :high (hz->radians (* 0.5 noise-width)) :low (hz->radians (* -0.5 noise-width)))) (osc (make-oscil freq)) (e (make-env freq-env :scaler (hz->radians gliss) :duration dur)) (beg (seconds->samples start)) (end (seconds->samples (+ start dur)))) (do ((i beg (+ i 1))) ((= i end)) (outa i (* amp (oscil osc (+ (env e) (green-noise-interp grn 0.0)))))))) (with-sound (:statistics #t) (green4 0 2.0 440 .5 '(0 0 1 1 2 1 3 0) 440 100 100 10)) |# ;;; -------------------------------------------------------------------------------- ;;; ;;; moving-sum (defgenerator (moving-sum :make-wrapper (lambda (g) (let ((dly (make-moving-average (g 'n)))) (set! (g 'gen) dly) (set! (mus-increment dly) 1.0) ; this is 1/n by default g))) (n 128) (gen #f)) (define moving-sum (let ((documentation "(make-moving-sum (n 128)) returns a moving-sum generator. (moving-sum gen input) returns the sum of the absolute values in a moving window over the last n inputs.")) (lambda (gen y) (moving-average (gen 'gen) (abs y))))) (define (make-unmoving-sum) (make-one-pole 1.0 -1.0)) (define unmoving-sum one-pole) ;;; -------------------------------------------------------------------------------- ;;; ;;; moving-variance ;;; ;;; this taken from the dsp bboard -- untested! (defgenerator (moving-variance :make-wrapper (lambda (g) (let ((g1 (make-moving-average (g 'n))) (g2 (make-moving-average (g 'n)))) (set! (g 'gen1) g1) (set! (mus-increment g1) 1.0) (set! (g 'gen2) g2) (set! (mus-increment g2) 1.0) g))) (n 128) (gen1 #f) (gen2 #f) y) (define (moving-variance gen y) (let-set! gen 'y y) (with-let gen (let ((x1 (moving-average gen1 y)) (x2 (moving-average gen2 (* y y)))) (/ (- (* n x2) (* x1 x1)) (* n (- n 1)))))) #| (with-sound (:clipped #f) (let ((gen (make-moving-variance 128))) (do ((i 0 (+ i 1))) ((= i 10000)) (outa i (moving-variance gen (random 1.0)))))) |# ;;; similarly (moving-inner-product x y) -> (moving-sum (* x y)), ;;; (moving-distance x y) -> (sqrt (moving-sum (* (- x y) (- x y)))) ;;; -------------------------------------------------------------------------------- ;;; ;;; moving-rms (defgenerator (moving-rms :make-wrapper (lambda (g) (set! (g 'gen) (make-moving-average (g 'n))) g)) (n 128) (gen #f) y) (define moving-rms (let ((documentation "(make-moving-rms (n 128) returns a moving-rms generator. (moving-rms gen input) returns the rms of the values in a window over the last n inputs.")) (lambda (gen y) (let-set! gen 'y y) (with-let gen (sqrt (max 0.0 ;; this is tricky -- due to floating point inaccuracy, we can get negative output ;; from moving-rms even if all the inputs are positive! The sqrt then returns ;; a complex number and all hell breaks loose (moving-average gen (* y y)))))))) ;;; -------------------------------------------------------------------------------- ;;; ;;; moving-length (defgenerator (moving-length :make-wrapper (lambda (g) (let ((dly (make-moving-average (g 'n)))) (set! (g 'gen) dly) (set! (mus-increment dly) 1.0) g))) (n 128) (gen #f) y) (define moving-length (let ((documentation "(make-moving-length (n 128) returns a moving-length generator. (moving-length gen input) returns the length of the values in a window over the last few inputs.")) (lambda (gen y) (let-set! gen 'y y) (with-let gen (sqrt (max 0.0 (moving-average gen (* y y)))))))) #| (let ((ml (make-moving-length 128)) (rd (make-readin "oboe.snd"))) (with-sound () (do ((i 0 (+ i 1))) ((= i 50828)) (outa i (moving-length ml (readin rd)))))) |# #| ;; perhaps also use moving-rms gen to avoid amplifying noise-sections (or even squlech them) (define* (agc (ramp-speed .001) (window-size 512)) (let ((maxer (make-moving-max window-size)) (mult 1.0)) (map-channel (lambda (y) (let* ((curmax (moving-max maxer y)) (diff (- 0.5 (* mult curmax))) (this-incr (* diff ramp-speed))) (set! mult (+ mult this-incr)) (* y mult)))))) ;;; moving-mean = average |# ;;; -------------------------------------------------------------------------------- ;;; ;;; weighted-moving-average ;;; ;;; arithmetic (1/n) weights (defgenerator (weighted-moving-average :make-wrapper (lambda (g) (let ((n (g 'n))) (let ((dly (make-moving-average n))) (set! (mus-increment dly) 1.0) (set! (g 'dly) dly) (set! (g 'den) (* 0.5 (+ n 1) n)) g)))) (n 128) (dly #f) (num 0.0) (sum 0.0) y den) (define weighted-moving-average (let ((documentation "(make-weighted-moving-average (n 128)) returns a weighted-moving-average generator. (weighted-moving-average gen y) returns the sum of the last n inputs weighted by 1/n")) (lambda (gen y) (let-set! gen 'y y) (with-let gen (set! num (- (+ num (* n y)) sum)) (set! sum (moving-average dly y)) (/ num den))))) ;;; -------------------------------------------------------------------------------- ;;; ;;; exponentially-weighted-moving-average ;;; ;;; geometric (r^n) weights #| (defgenerator (exponentially-weighted-moving-average :make-wrapper (lambda (g) (let* ((n (g 'n)) (flt (make-one-pole (/ 1.0 n) (/ (- n) (+ 1.0 n))))) (set! (g 'gen) flt) g))) (n 128) (gen #f)) (define exponentially-weighted-moving-average (let ((documentation "(make-exponentially-weighted-moving-average (n 128) returns an exponentially-weighted-moving-average generator. (exponentially-weighted-moving-average gen y) returns the sum of the last n inputs weighted by (-n/(n+1))^k")) (lambda (gen y) (one-pole (gen 'gen) y)))) |# (define* (make-exponentially-weighted-moving-average (n 128)) (make-one-pole (/ 1.0 n) (/ (- n) (+ 1.0 n)))) (define exponentially-weighted-moving-average? one-pole?) (define exponentially-weighted-moving-average one-pole) ;;; -------------------------------------------------------------------------------- ;;; ;;; polyoid -- Tn + Un to get arbitrary initial-phases #| ;;; old form, now replaced by built-in code (clm.c) (defgenerator (polyoid :make-wrapper (lambda (g) (let* ((lst (g 'partial-amps-and-phases)) (len (length lst)) (topk (let ((n 0)) (do ((i 0 (+ i 3))) ((>= i len)) (set! n (max n (floor (lst i))))) n)) (sin-amps (make-float-vector (+ topk 1) 0.0)) (cos-amps (make-float-vector (+ topk 1) 0.0))) (do ((j 0 (+ j 3))) ((>= j len)) (let ((n (floor (lst j))) (amp (lst (+ j 1))) (phase (lst (+ j 2)))) (if (> n 0) ; constant only applies to cos side (set! (sin-amps n) (* amp (cos phase)))) (set! (cos-amps n) (* amp (sin phase))))) (set! (g 'tn) cos-amps) (set! (g 'un) sin-amps) (set! (g 'frequency) (hz->radians (g 'frequency))) g)) :methods (list (cons 'mus-data (lambda (g) (g 'tn))) (cons 'mus-xcoeffs (lambda (g) (g 'tn))) (cons 'mus-ycoeffs (lambda (g) (g 'un))) (cons 'mus-xcoeff (dilambda (lambda (g ind) ((g 'tn) ind)) (lambda (g ind val) (float-vector-set! (g 'tn) ind val)))) (cons 'mus-ycoeff (dilambda (lambda (g ind) ((g 'un) ind)) (lambda (g ind val) (float-vector-set! (g 'un) ind val)))))) (frequency *clm-default-frequency*) (partial-amps-and-phases #f) (angle 0.0) (tn #f) (un #f) fm) (define* (polyoid gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let ((x angle)) (set! angle (+ angle fm frequency)) (mus-chebyshev-tu-sum x tn un)))) |# (define polyoid polywave) (define (polyoid? g) (and (polywave? g) (= (mus-channel g) mus-chebyshev-both-kinds))) (define polyoid-tn mus-xcoeffs) (define polyoid-un mus-ycoeffs) (define* (make-polyoid (frequency *clm-default-frequency*) partial-amps-and-phases) (let* ((lst partial-amps-and-phases) (len (length lst)) (topk (let ((n 0)) (do ((i 0 (+ i 3))) ((>= i len)) (set! n (max n (floor (lst i))))) n)) (sin-amps (make-float-vector (+ topk 1) 0.0)) (cos-amps (make-float-vector (+ topk 1) 0.0))) (do ((j 0 (+ j 3))) ((>= j len)) (let ((n (floor (lst j))) (amp (lst (+ j 1))) (phase (lst (+ j 2)))) (if (> n 0) ; constant only applies to cos side (set! (sin-amps n) (* amp (cos phase)))) (set! (cos-amps n) (* amp (sin phase))))) (make-polywave frequency :xcoeffs cos-amps :ycoeffs sin-amps))) (define (polyoid-env gen fm amps phases) ;; amps and phases are the envelopes, one for each harmonic, setting the sample-wise amp and phase (let* ((original-data (polyoid-partial-amps-and-phases gen)) (data-len (length original-data)) (amps-len (length amps)) (tn (polyoid-tn gen)) (un (polyoid-un gen))) (do ((i 0 (+ i 3)) (j 0 (+ j 1))) ((or (= j amps-len) (= i data-len))) (let ((hn (floor (original-data i))) (amp (env (amps j))) (phase (env (phases j)))) (set! (tn hn) (* amp (sin phase))) (set! (un hn) (* amp (cos phase))))) (polyoid gen fm))) #| (with-sound (:clipped #f) (let ((samps 44100) (gen (make-polyoid 100.0 (vector 1 1 0.0)))) (do ((i 0 (+ i 1))) ((= i samps)) (outa i (polyoid gen))))) (with-sound (:clipped #f) (let ((samps 44100) (gen (make-polywave 100.0 '(1 1) mus-chebyshev-second-kind)) (gen1 (make-oscil 100.0))) (set! (mus-phase gen) (* 0.5 pi)) (do ((i 0 (+ i 1))) ((= i samps)) (outa i (* (oscil gen1) (polywave gen)))))) (with-sound (:clipped #f :statistics #t) (let ((samps 44100) (gen (make-polyoid 100.0 (vector 1 0.5 0.0 51 0.25 0.0 64 .25 (/ pi 2))))) (do ((i 0 (+ i 1))) ((= i samps)) (outa i (polyoid gen))))) (define (test-polyoid n) (let* ((res (with-sound (:channels 2 :clipped #f) (let ((freqs (make-float-vector n)) (phases (make-float-vector n)) ; for oscil-bank (cur-phases (make-float-vector (* 3 n))) ; for polyoid (amp (/ 1.0 n))) (do ((i 0 (+ i 1)) (j 0 (+ j 3))) ((= i n)) (set! (cur-phases j) (+ i 1)) (set! (cur-phases (+ j 1)) (/ 1.0 n)) (set! (cur-phases (+ j 2)) (random (* 2 pi))) (set! (freqs i) (hz->radians (+ i 1.0))) (set! (phases i) (cur-phases (+ j 2)))) (let ((gen (make-polyoid 1.0 cur-phases)) (obank (make-oscil-bank freqs phases (make-float-vector n 1.0) #t))) (do ((i 0 (+ i 1))) ((= i 88200)) (outa i (* amp (oscil-bank obank)))) (do ((i 0 (+ i 1))) ((= i 88200)) (outb i (polyoid gen 0.0))))))) (snd (find-sound res))) (channel-distance snd 0 snd 1))) ;;; 0 diff up to 4096 so far (unopt and opt) -- 1.0e-12 at 4096, opt is more than 20 times as fast (with-sound (:clipped #f :channels 2 :statistics #t) (let* ((samps 44100) (gen1 (make-polyoid 100.0 (vector 1 0.5 0.0 3 0.25 0.0 4 .25 0.0))) (gen2 (make-polyoid 100.0 (vector 1 0.5 0.0 3 0.25 0.0 4 .25 0.0))) (amps1 (vector (make-env '(0 0 1 1 2 0) :end samps :scaler 0.5) (make-env '(0 1 1 0 2 1) :end samps :scaler 0.25) (make-env '(0 1 1 0) :end samps :scaler 0.25))) (phases1 (vector (make-env '(0 0 1 1) :end samps :scaler (/ pi 2)) (make-env '(0 0 1 1) :end samps :scaler (/ pi 2)) (make-env '(0 1 1 0) :end samps :scaler (/ pi 2)))) (amps2 (vector (make-env '(0 0 1 1 2 0) :end samps :scaler 0.5) (make-env '(0 1 1 0 2 1) :end samps :scaler 0.25) (make-env '(0 1 1 0) :end samps :scaler 0.25))) (phases2 (vector (make-env '(0 0 1 0) :end samps) (make-env '(0 0 1 0) :end samps) (make-env '(0 0 1 0) :end samps)))) (do ((i 0 (+ i 1))) ((= i samps)) (outa i (polyoid-env gen1 0.0 amps1 phases1)) (outb i (polyoid-env gen2 0.0 amps2 phases2))))) (with-sound (:clipped #f :channels 2 :channels 3 :statistics #t) (let* ((samps 44100) (gen1 (make-polyoid 100.0 (vector 1 1 0 2 1 0 3 1 0))) (gen2 (make-polyoid 100.0 (vector 1 1 0 2 1 0 3 1 0))) (gen3 (make-polyoid 100.0 (vector 1 1 (/ pi 2) 2 1 (/ pi 2) 3 1 (/ pi 2)))) (amps1 (vector (make-env '(0 1 1 1) :end samps) (make-env '(0 1 1 1) :end samps) (make-env '(0 1 1 1) :end samps))) (amps2 (vector (make-env '(0 1 1 1) :end samps) (make-env '(0 1 1 1) :end samps) (make-env '(0 1 1 1) :end samps))) (amps3 (vector (make-env '(0 1 1 1) :end samps) (make-env '(0 1 1 1) :end samps) (make-env '(0 1 1 1) :end samps))) (phases1 (vector (make-env '(0 0 1 0) :end samps) (make-env '(0 0 1 0) :end samps) (make-env '(0 0 1 0) :end samps))) (phases2 (vector (make-env '(0 0 .1 0 .9 1 1 1) :end samps :scaler (/ pi 2)) (make-env '(0 0 .1 0 .9 1 1 1) :end samps :scaler (/ pi 2)) (make-env '(0 0 .1 0 .9 1 1 1) :end samps :scaler (/ pi 2)))) (phases3 (vector (make-env '(0 1 1 1) :end samps :scaler (/ pi 2)) (make-env '(0 1 1 1) :end samps :scaler (/ pi 2)) (make-env '(0 1 1 1) :end samps :scaler (/ pi 2))))) (do ((i 0 (+ i 1))) ((= i samps)) (outa i (* .1 (polyoid-env gen1 0.0 amps1 phases1))) (outb i (* .1 (polyoid-env gen2 0.0 amps2 phases2))) (outc i (* .1 (polyoid-env gen3 0.0 amps3 phases3)))))) |# ;;; -------------------------------------------------------------------------------- ;;; ;;; noid -- sum of n sinusoids at arbitrary (default=random) initial phases ;;; ;;; for max peak (all cos), set phases arg to (make-vector n (/ pi 2)) ;;; for min peak, use one of the sets in peak-phases.scm (multiplied through by pi) ;;; ;;; since initial phases are 0 or pi in peak-phases.scm if n>20, this code could be optimized (define* (make-noid (frequency 0.0) (n 1) phases (choice 'all)) (make-polyoid frequency (let ((amps (make-vector (* 3 n) 0.0))) (do ((i 1 (+ i 1)) (j 0 (+ j 3))) ((> i n)) (case choice ((all) (set! (amps j) i)) ((odd) (set! (amps j) (- (* 2 i) 1))) ((prime) (set! (amps j) (some-primes (- i 1)))) ; defined below up to 1024th or so -- probably should use low-primes.scm ((even) (set! (amps j) (max 1 (* 2 (- i 1)))))) (set! (amps (+ j 1)) (/ 1.0 n)) (if (vector? phases) (set! (amps (+ j 2)) (phases (- i 1))) (if (not phases) (set! (amps (+ j 2)) (random (* 2 pi))) (if (eq? phases 'max-peak) (set! (amps (+ j 2)) (/ pi 2)) ;; else min-peak, handled below )))) (if (eq? phases 'min-peak) (let ((vector-find-if (lambda (func vect) (let ((len (length vect)) (result #f)) (do ((i 0 (+ i 1))) ((or (= i len) result) result) (set! result (func (vect i)))))))) (if (not (defined? 'noid-min-peak-phases)) (load "peak-phases.scm")) (let ((min-dat (vector-find-if (lambda (val) (and val (vector? val) (= (val 0) n) (let* ((a-val (val 1)) (a-len (length val)) (a-data (list a-val (val 2)))) (do ((k 2 (+ k 1))) ((= k a-len)) (if (and (number? (val k)) (< (val k) a-val)) (begin (set! a-val (val k)) (set! a-data (list a-val (val (+ k 1))))))) a-data))) (case choice ((all) noid-min-peak-phases) ((odd) nodd-min-peak-phases) ((prime) primoid-min-peak-phases) ((even) neven-min-peak-phases))))) (if min-dat (let (;(norm (car min-dat)) (rats (cadr min-dat))) (do ((i 1 (+ i 1)) (j 0 (+ j 3))) ((> i n)) (set! (amps (+ j 1)) (/ 1.0 n)) ;(/ 0.999 norm)) -- can't decide about this -- I guess it should be consistent with the #f case (set! (amps (+ j 2)) (* pi (rats (- i 1)))))))))) amps))) (define noid polyoid) (define noid? polyoid?) (define some-primes (vector 1 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199 211 223 227 229 233 239 241 251 257 263 269 271 277 281 283 293 307 311 313 317 331 337 347 349 353 359 367 373 379 383 389 397 401 409 419 421 431 433 439 443 449 457 461 463 467 479 487 491 499 503 509 521 523 541 547 557 563 569 571 577 587 593 599 601 607 613 617 619 631 641 643 647 653 659 661 673 677 683 691 701 709 719 727 733 739 743 751 757 761 769 773 787 797 809 811 821 823 827 829 839 853 857 859 863 877 881 883 887 907 911 919 929 937 941 947 953 967 971 977 983 991 997 1009 1013 1019 1021 1031 1033 1039 1049 1051 1061 1063 1069 1087 1091 1093 1097 1103 1109 1117 1123 1129 1151 1153 1163 1171 1181 1187 1193 1201 1213 1217 1223 1229 1231 1237 1249 1259 1277 1279 1283 1289 1291 1297 1301 1303 1307 1319 1321 1327 1361 1367 1373 1381 1399 1409 1423 1427 1429 1433 1439 1447 1451 1453 1459 1471 1481 1483 1487 1489 1493 1499 1511 1523 1531 1543 1549 1553 1559 1567 1571 1579 1583 1597 1601 1607 1609 1613 1619 1621 1627 1637 1657 1663 1667 1669 1693 1697 1699 1709 1721 1723 1733 1741 1747 1753 1759 1777 1783 1787 1789 1801 1811 1823 1831 1847 1861 1867 1871 1873 1877 1879 1889 1901 1907 1913 1931 1933 1949 1951 1973 1979 1987 1993 1997 1999 2003 2011 2017 2027 2029 2039 2053 2063 2069 2081 2083 2087 2089 2099 2111 2113 2129 2131 2137 2141 2143 2153 2161 2179 2203 2207 2213 2221 2237 2239 2243 2251 2267 2269 2273 2281 2287 2293 2297 2309 2311 2333 2339 2341 2347 2351 2357 2371 2377 2381 2383 2389 2393 2399 2411 2417 2423 2437 2441 2447 2459 2467 2473 2477 2503 2521 2531 2539 2543 2549 2551 2557 2579 2591 2593 2609 2617 2621 2633 2647 2657 2659 2663 2671 2677 2683 2687 2689 2693 2699 2707 2711 2713 2719 2729 2731 2741 2749 2753 2767 2777 2789 2791 2797 2801 2803 2819 2833 2837 2843 2851 2857 2861 2879 2887 2897 2903 2909 2917 2927 2939 2953 2957 2963 2969 2971 2999 3001 3011 3019 3023 3037 3041 3049 3061 3067 3079 3083 3089 3109 3119 3121 3137 3163 3167 3169 3181 3187 3191 3203 3209 3217 3221 3229 3251 3253 3257 3259 3271 3299 3301 3307 3313 3319 3323 3329 3331 3343 3347 3359 3361 3371 3373 3389 3391 3407 3413 3433 3449 3457 3461 3463 3467 3469 3491 3499 3511 3517 3527 3529 3533 3539 3541 3547 3557 3559 3571 3581 3583 3593 3607 3613 3617 3623 3631 3637 3643 3659 3671 3673 3677 3691 3697 3701 3709 3719 3727 3733 3739 3761 3767 3769 3779 3793 3797 3803 3821 3823 3833 3847 3851 3853 3863 3877 3881 3889 3907 3911 3917 3919 3923 3929 3931 3943 3947 3967 3989 4001 4003 4007 4013 4019 4021 4027 4049 4051 4057 4073 4079 4091 4093 4099 4111 4127 4129 4133 4139 4153 4157 4159 4177 4201 4211 4217 4219 4229 4231 4241 4243 4253 4259 4261 4271 4273 4283 4289 4297 4327 4337 4339 4349 4357 4363 4373 4391 4397 4409 4421 4423 4441 4447 4451 4457 4463 4481 4483 4493 4507 4513 4517 4519 4523 4547 4549 4561 4567 4583 4591 4597 4603 4621 4637 4639 4643 4649 4651 4657 4663 4673 4679 4691 4703 4721 4723 4729 4733 4751 4759 4783 4787 4789 4793 4799 4801 4813 4817 4831 4861 4871 4877 4889 4903 4909 4919 4931 4933 4937 4943 4951 4957 4967 4969 4973 4987 4993 4999 5003 5009 5011 5021 5023 5039 5051 5059 5077 5081 5087 5099 5101 5107 5113 5119 5147 5153 5167 5171 5179 5189 5197 5209 5227 5231 5233 5237 5261 5273 5279 5281 5297 5303 5309 5323 5333 5347 5351 5381 5387 5393 5399 5407 5413 5417 5419 5431 5437 5441 5443 5449 5471 5477 5479 5483 5501 5503 5507 5519 5521 5527 5531 5557 5563 5569 5573 5581 5591 5623 5639 5641 5647 5651 5653 5657 5659 5669 5683 5689 5693 5701 5711 5717 5737 5741 5743 5749 5779 5783 5791 5801 5807 5813 5821 5827 5839 5843 5849 5851 5857 5861 5867 5869 5879 5881 5897 5903 5923 5927 5939 5953 5981 5987 6007 6011 6029 6037 6043 6047 6053 6067 6073 6079 6089 6091 6101 6113 6121 6131 6133 6143 6151 6163 6173 6197 6199 6203 6211 6217 6221 6229 6247 6257 6263 6269 6271 6277 6287 6299 6301 6311 6317 6323 6329 6337 6343 6353 6359 6361 6367 6373 6379 6389 6397 6421 6427 6449 6451 6469 6473 6481 6491 6521 6529 6547 6551 6553 6563 6569 6571 6577 6581 6599 6607 6619 6637 6653 6659 6661 6673 6679 6689 6691 6701 6703 6709 6719 6733 6737 6761 6763 6779 6781 6791 6793 6803 6823 6827 6829 6833 6841 6857 6863 6869 6871 6883 6899 6907 6911 6917 6947 6949 6959 6961 6967 6971 6977 6983 6991 6997 7001 7013 7019 7027 7039 7043 7057 7069 7079 7103 7109 7121 7127 7129 7151 7159 7177 7187 7193 7207 7211 7213 7219 7229 7237 7243 7247 7253 7283 7297 7307 7309 7321 7331 7333 7349 7351 7369 7393 7411 7417 7433 7451 7457 7459 7477 7481 7487 7489 7499 7507 7517 7523 7529 7537 7541 7547 7549 7559 7561 7573 7577 7583 7589 7591 7603 7607 7621 7639 7643 7649 7669 7673 7681 7687 7691 7699 7703 7717 7723 7727 7741 7753 7757 7759 7789 7793 7817 7823 7829 7841 7853 7867 7873 7877 7879 7883 7901 7907 7919 7927 7933 7937 7949 7951 7963 7993 8009 8011 8017 8039 8053 8059 8069 8081 8087 8089 8093 8101 8111 8117 8123 8147 8161 8167 8171)) #| (with-sound (:clipped #f) (let ((samps 44100) (gen (make-noid 100.0 3))) (do ((i 0 (+ i 1))) ((= i samps)) (outa i (noid gen))))) (with-sound (:clipped #f :channels 2) (let* ((samps 44100) (n 10) (gen (make-noid 1.0 n 'min-peak)) (gen2 (make-oscil n ((polyoid-partial-amps-and-phases gen) (- (length (polyoid-partial-amps-and-phases gen)) 1))))) (do ((i 0 (+ i 1))) ((= i samps)) (outa i (noid gen)) (outb i (oscil gen2))))) (with-sound (:clipped #f) (let ((samps 44100) (gen (make-noid 100.0 10 'min-peak))) (do ((i 0 (+ i 1))) ((= i samps)) (outa i (noid gen))))) (with-sound (:clipped #f :statistics #t) (let ((samps 44100) (gen (make-noid 10.0 1024 'min-peak))) (do ((i 0 (+ i 1))) ((= i samps)) (outa i (noid gen))))) (with-sound (:clipped #f :channels 4) (let ((samps 44100) (gen1 (make-noid 100.0 32 'max-peak)) (gen2 (make-noid 100.0 32 (make-vector 32 0.0))) (gen3 (make-noid 100.0 32)) (gen4 (make-noid 100.0 32 'min-peak))) (do ((i 0 (+ i 1))) ((= i samps)) (outa i (noid gen1 0.0)) (outb i (noid gen2 0.0)) (outc i (noid gen3 0.0)) (outd i (noid gen4 0.0))))) (do ((i 0 (+ i 1))) ((= i 4)) (with-sound (:clipped #f :output (string-append "test-noid-" (number->string i) ".snd")) (let ((samps 44100) (gen (make-noid 100.0 32 (if (= i 0) 'max-peak (if (= i 1) (make-vector 32 0.0) (if (= i 2) #f 'min-peak)))))) (do ((i 0 (+ i 1))) ((= i samps)) (outa i (noid gen)))))) (define (knoid n) (with-sound (:channels 4 :statistics #t) (let ((samps 100000) (gen1 (make-noid 10.0 n 'min-peak 'all)) (gen2 (make-noid 10.0 n 'min-peak 'odd)) (gen3 (make-noid 10.0 n 'min-peak 'even)) (gen4 (make-noid 10.0 n 'min-peak 'prime))) (do ((i 0 (+ i 1))) ((= i samps)) (outa i (* 0.5 (noid gen1 0.0))) (outb i (* 0.5 (noid gen2 0.0))) (outc i (* 0.5 (noid gen3 0.0))) (outd i (* 0.5 (noid gen4 0.0))))))) (with-sound (:clipped #f) (let ((samps 44100) (gen (make-noid 100.0 19 (apply vector (map (lambda (n) (* pi n)) (list 0 1 0 0 1 1 1 1 1 1 0 0 1 1 1 0 1 0 1) ))))) (do ((i 0 (+ i 1))) ((= i samps)) (outa i (noid gen))))) |# #| ;;; -------------------------------------------------------------------------------- ;;; ;;; roid -- sum of n sinusoids at arbitrary (default=random) initial phases and amp r^n (define* (make-roid (frequency 0.0) (n 1) (r 1.0) (phases #f)) (make-polyoid frequency (let ((amps (make-vector (* 3 n) 0.0)) (rn (/ 1.0 n))) (do ((i 1 (+ i 1)) (j 0 (+ j 3))) ((> i n)) (set! (amps j) i) (set! (amps (+ j 1)) rn) (set! rn (* rn r)) (if (vector? phases) (set! (amps (+ j 2)) (phases (- i 1))) (if (not phases) (set! (amps (+ j 2)) (random (* 2 pi))) (if (eq? phases 'max-peak) (set! (amps (+ j 2)) (/ pi 2)) ;; else min-peak, handled separately )))) (if (eq? phases 'min-peak) (let ((vector-find-if (lambda (func vect) (let ((len (length vect)) (result #f)) (do ((i 0 (+ i 1))) ((or (= i len) result) result) (set! result (func (vect i)))))))) (if (not (defined? 'roid-min-peak-phases)) (load "peak-phases.scm")) (let ((min-dat (vector-find-if (lambda (val) (and val (vector? val) (= (val 0) n) (let* ((a-val (val 1)) (a-len (length val)) (a-data (list a-val (val 2)))) (do ((k 2 (+ k 1))) ((= k a-len)) (if (and (number? (val k)) (< (val k) a-val)) (begin (set! a-val (val k)) (set! a-data (list a-val (val (+ k 1))))))) a-data))) roid-min-peak-phases))) (if min-dat (let* ((norm (car min-dat)) (rats (cadr min-dat)) (rn (/ 0.999 norm))) (do ((i 1 (+ i 1)) (j 0 (+ j 3))) ((> i n)) (set! (amps (+ j 1)) rn) (set! rn (* rn r)) (set! (amps (+ j 2)) (* pi (rats (- i 1)))))))))) amps))) (define roid polyoid) (define roid? polyoid?) |# #| (with-sound (:clipped #f) (let ((samps 44100) (gen (make-roid 100.0 6 0.5 'min-peak))) (do ((i 0 (+ i 1))) ((= i samps)) (outa i (roid gen))))) |# ;;; ---------------- old waveshape generator ---------------- (define waveshape? polyshape?) (define waveshape polyshape) (define* (make-waveshape (frequency *clm-default-frequency*) (partials '(1 1)) wave (size *clm-table-size*)) ; size arg is for backwards compatibility (if (not wave) (make-polyshape frequency :partials partials) (make-polyshape frequency :coeffs wave))) (define* (partials->waveshape partials (size *clm-table-size*)) (partials->polynomial partials)) ;;; ---------------- tanh(sin(x)) ---------------- (defgenerator (tanhsin :make-wrapper (lambda (g) (set! (g 'osc) (make-oscil (g 'frequency) (g 'initial-phase))) (set! (g 'frequency) (hz->radians (g 'frequency))) ; so that mus-frequency works at least read side g)) (frequency *clm-default-frequency*) (r 1.0) (initial-phase 0.0) (osc #f) fm) (define tanhsin (let ((documentation "(make-tanhsin (frequency 0.0) (r 1.0) (initial-phase 0.0) returns a tanhsin generator. (tanhsin gen (fm 0.0)) produces tanh(r*sin) which approaches a square wave as r increases.")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (tanh (* r (oscil osc fm))))))) ;;; ---------------- moving-fft ---------------- (define last-moving-fft-window #f) (define moving-fft-methods (list (cons 'mus-data (lambda (g) (g 'data))) (cons 'mus-xcoeffs (lambda (g) (g 'rl))) (cons 'mus-ycoeffs (lambda (g) (g 'im))) (cons 'mus-run (lambda (g arg1 arg2) (moving-fft g))))) (defgenerator (moving-fft :make-wrapper (lambda (g) (let ((n (g 'n))) (set! (g 'rl) (make-float-vector n)) (set! (g 'im) (make-float-vector n)) (set! (g 'data) (make-float-vector n)) (set! (g 'window) (if (and last-moving-fft-window (= n (length last-moving-fft-window))) last-moving-fft-window (set! last-moving-fft-window (make-fft-window hamming-window n)))) (float-vector-scale! (g 'window) (/ 2.0 (* 0.54 n))) (set! (g 'outctr) (+ n 1)) ; first time fill flag g)) :methods moving-fft-methods) (input #f) (n 512) (hop 128) (outctr 0) (rl #f) (im #f) (data #f) (window #f)) (define moving-fft (let ((documentation "(make-moving-fft reader (size 512) (hop 128)) returns a moving-fft generator. (moving-fft gen) produces an FFT (polar form) of 'size' samples every 'hop' samples, taking input from the readin generator 'reader'. The magnitudes are available as mus-xcoeffs, the phases as mus-ycoeffs, and the current input data as mus-data.")) (lambda (gen) (with-let gen (let ((new-data #f)) (if (>= outctr hop) (let ((fft-window window)) (if (> outctr n) ; must be first time through -- fill data array (do ((i 0 (+ i 1))) ((= i n)) (float-vector-set! data i (readin input))) (let ((mid (- n hop))) (float-vector-move! data 0 hop) (do ((i mid (+ i 1))) ((= i n)) (float-vector-set! data i (readin input))))) (set! outctr 0) (set! new-data #t) (fill! im 0.0) (float-vector-subseq data 0 n rl) (float-vector-multiply! rl fft-window) (mus-fft rl im n 1) (rectangular->polar rl im))) (set! outctr (+ outctr 1)) new-data))))) #| (let* ((snd (new-sound)) (rd (make-readin "oboe.snd")) (ft (make-moving-fft rd)) (data (make-float-vector 256))) (set! (lisp-graph?) #t) (do ((i 0 (+ i 1))) ((= i 10000)) (if (moving-fft ft) (begin (float-vector-subseq (mus-xcoeffs ft) 0 255 data) (graph data "fft" 0.0 11025.0 0.0 0.1 snd 0 #t)))) (close-sound snd)) |# ;;; ---------------- moving spectrum ---------------- (defgenerator (moving-spectrum :make-wrapper (lambda (g) (let ((n (g 'n))) (set! (g 'amps) (make-float-vector n)) (set! (g 'phases) (make-float-vector n)) (set! (g 'amp-incs) (make-float-vector n)) (set! (g 'freqs) (make-float-vector n)) (set! (g 'freq-incs) (make-float-vector n)) (set! (g 'new-freq-incs) (make-float-vector n)) (set! (g 'data) (make-float-vector n)) (set! (g 'fft-window) (make-fft-window hamming-window n)) (float-vector-scale! (g 'fft-window) (/ 2.0 (* 0.54 n))) (set! (g 'outctr) (+ n 1)) ; first time fill flag g))) (input #f) (n 512) (hop 128) (outctr 0) (amps #f) (phases #f) (amp-incs #f) (freqs #f) (freq-incs #f) (new-freq-incs #f) (fft-window #f) (data #f) (dataloc 0)) (define (moving-spectrum gen) (with-let gen (let ((n2 (/ n 2))) (if (>= outctr hop) (begin (if (> outctr n) ; must be first time through -- fill data array (do ((i 0 (+ i 1))) ((= i n)) (float-vector-set! data i (readin input))) (begin (float-vector-move! data 0 hop) (do ((i (- n hop) (+ i 1))) ((= i n)) (float-vector-set! data i (readin input))))) (set! outctr 0) ; -1?? (set! dataloc (modulo dataloc n)) (fill! new-freq-incs 0.0) (do ((i 0 (+ i 1)) (j dataloc (+ j 1))) ((= j n)) (float-vector-set! amp-incs j (* (float-vector-ref fft-window i) (float-vector-ref data i)))) (if (> dataloc 0) (do ((i (- n dataloc) (+ i 1)) (j 0 (+ j 1))) ((= j dataloc)) (float-vector-set! amp-incs j (* (float-vector-ref fft-window i) (float-vector-ref data i))))) (set! dataloc (+ dataloc hop)) (mus-fft amp-incs new-freq-incs n 1) (rectangular->polar amp-incs new-freq-incs) (let ((scl (/ 1.0 hop)) (kscl (/ two-pi n))) (float-vector-subtract! amp-incs amps) (float-vector-scale! amp-incs scl) (do ((i 0 (+ i 1)) (ks 0.0 (+ ks kscl))) ((= i n2)) (let ((diff (modulo (- (new-freq-incs i) (freq-incs i)) two-pi))) (set! (freq-incs i) (new-freq-incs i)) (if (> diff pi) (set! diff (- diff (* 2 pi)))) (if (< diff (- pi)) (set! diff (+ diff (* 2 pi)))) (set! (new-freq-incs i) (+ (* diff scl) ks)))) (float-vector-subtract! new-freq-incs freqs) (float-vector-scale! new-freq-incs scl)))) (set! outctr (+ outctr 1)) (float-vector-add! amps amp-incs) (float-vector-add! freqs new-freq-incs) (float-vector-add! phases freqs)))) (define (test-sv) ;; sv-amps = pv-amps (but len is diff) ;; sv-phases = pv-phases ;; sv-freqs = pv-phase-increments (let ((pv (make-phase-vocoder (make-readin "oboe.snd") )) (sv (make-moving-spectrum (make-readin "oboe.snd")))) (let ((pv-amps (phase-vocoder-amps pv)) (pv-incrs (phase-vocoder-phase-increments pv)) (sv-amps (sv 'amps)) (sv-freqs (sv 'freqs))) (call-with-exit (lambda (quit) (do ((k 0 (+ k 1))) ((= k 20)) (do ((i 0 (+ i 1))) ((= i 2000)) (phase-vocoder pv)) (do ((i 0 (+ i 1))) ((= i 2000)) (moving-spectrum sv)) (do ((i 0 (+ i 1))) ((= i 256)) (if (fneq (sv-amps i) (pv-amps i)) (begin (format *stderr* ";test-sv (generators) ~D amps: ~A ~A" i (sv-amps i) (pv-amps i)) (quit))) (if (> (abs (- (sv-freqs i) (pv-incrs i))) .25) (begin (format *stderr* ";test-sv (generators) ~D freqs: ~A ~A" i (sv-freqs i) (pv-incrs i)) (quit)))))))))) #| (define* (sine-bank amps phases size) (let ((len (or size (length amps))) (sum 0.0)) (do ((i 0 (+ i 1))) ((= i len)) (set! sum (+ sum (* (amps i) (sin (phases i)))))) sum)) (with-sound (:channels 2) (let* ((gen (make-moving-spectrum (make-readin "oboe.snd"))) (pv (make-phase-vocoder (make-readin "oboe.snd"))) (samps (framples "oboe.snd"))) (do ((i 0 (+ i 1))) ((= i samps)) (moving-spectrum gen) (outa i (sine-bank (gen 'amps) (gen 'phases) 256)) ; size = n/2 as in pv (outb i (phase-vocoder pv))))) ; :(channel-distance 0 0 0 1) ; 7.902601100022e-9 |# ;;; moving spectrum returns freqs in radians, and does not try to find the interpolated peak, ;;; so we need another version that returns current freq/amp pairs that can be used directly in oscil ;;; This is the main portion of the "pins" instrument (also find-pitch in examp.scm) ;;; ---------------- moving scentroid ---------------- (defgenerator (moving-scentroid :make-wrapper (lambda (g) (let ((n (g 'size))) (set! (g 'rl) (make-float-vector n)) (set! (g 'im) (make-float-vector n)) (set! (g 'dly) (make-delay n)) (set! (g 'rms) (make-moving-rms n)) (set! (g 'hop) (floor (/ *clm-srate* (g 'rfreq)))) (set! (g 'binwidth) (/ *clm-srate* n)) g))) (dbfloor -40.0) (rfreq 100.0) (size 4096) (hop 1024) (outctr 0) (curval 0.0) (binwidth 1.0) (rl #f) (im #f) (dly #f) (rms #f) x) (define* (moving-scentroid gen (x 0.0)) (let-set! gen 'x x) (with-let gen (let ((rms (moving-rms rms x))) (if (>= outctr hop) (begin (set! outctr 0) (if (< (linear->db rms) dbfloor) (set! curval 0.0) (let* ((data (mus-data dly)) (n size) (fft2 (/ n 2)) (numsum 0.0) (densum 0.0)) (fill! im 0.0) (float-vector-subseq data 0 (- n 1) rl) (mus-fft rl im n 1) ; we can use the delay line contents un-reordered because phases are ignored here (rectangular->magnitudes rl im) (do ((k 0 (+ k 1))) ((= k fft2)) (set! numsum (+ numsum (* k (rl k)))) (set! densum (+ densum (rl k)))) (set! curval (/ (* binwidth numsum) densum))))))) (delay dly x) ; our "sliding window" on the input data (set! outctr (+ outctr 1)) curval)) #| (let* ((snd (open-sound "oboe.snd")) (cur-srate (srate snd)) (old-srate *clm-srate*)) (set! *clm-srate* cur-srate) (let ((scn (make-moving-scentroid -40.0 100.0 128)) (vals (scentroid "oboe.snd" 0.0 1.1 -40.0 100.0 128)) (k 0)) (let ((data (channel->float-vector 0 22050 snd 0))) (close-sound snd) (do ((i 0 (+ i 1))) ((= i (scn 'size))) (moving-scentroid scn (data i))) (set! (scn 'outctr) (scn 'hop)) (do ((i (scn 'size) (+ i 1)) (j 0 (+ j 1))) ((= i 22050)) (let ((val (moving-scentroid scn (data i)))) (if (= (modulo j (scn 'hop)) 0) (begin (format #t "[~A ~A]~%" val (vals k)) (set! k (+ k 1))))))) (set! *clm-srate* old-srate))) |# ;;; ---------------- moving-autocorrelation ---------------- (define moving-autocorrelation-methods (list (cons 'mus-run (lambda (g arg1 arg2) (moving-autocorrelation g))) (cons 'mus-data (lambda (g) (g 'rl))))) (defgenerator (moving-autocorrelation :make-wrapper (lambda (g) (let ((n (g 'n))) (set! (g 'rl) (make-float-vector n)) (set! (g 'im) (make-float-vector n)) (set! (g 'data) (make-float-vector n)) (set! (g 'outctr) (+ n 1)) ; first time fill flag g)) :methods moving-autocorrelation-methods) (input #f) (n 512) (hop 128) (outctr 0) (rl #f) (im #f) (data #f)) (define moving-autocorrelation (let ((documentation "(make-moving-autocorrelation reader (size 512) (hop 128)) returns a moving-autocorrelation generator. (moving-autocorrelation gen) produces the autocorrelation of 'size' samples every 'hop' samples, taking input from the readin generator 'reader'. The output data is available via mus-data.")) (lambda (gen) (with-let gen (let ((new-data #f)) (if (>= outctr hop) (begin (if (> outctr n) ; must be first time through -- fill data array (do ((i 0 (+ i 1))) ((= i n)) (float-vector-set! data i (readin input))) (begin (float-vector-move! data 0 hop) (do ((i (- n hop) (+ i 1))) ((= i n)) (float-vector-set! data i (readin input))))) (set! outctr 0) (set! new-data #t) (fill! im 0.0) (float-vector-subseq data 0 (- n 1) rl) (autocorrelate rl))) (set! outctr (+ outctr 1)) new-data))))) ;;; ---------------- moving-pitch ---------------- (define moving-pitch-methods (list (cons 'mus-run (lambda (g arg1 arg2) (moving-pitch g))))) (defgenerator (moving-pitch :make-wrapper (lambda (g) (set! (g 'ac) (make-moving-autocorrelation (g 'input) (g 'n) (g 'hop))) g) :methods moving-pitch-methods) (input #f) (n 512) (hop 128) (ac #f) (val 0.0)) (define (moving-pitch gen) (with-let gen (if (moving-autocorrelation ac) (let* ((data (mus-data ac)) (peak 0.0) (peak-loc 0) (len (length data))) (do ((i 8 (+ i 1))) ; assume we're not in the top few octaves ((= i len)) (let ((apk (abs (data i)))) (if (> apk peak) (begin (set! peak apk) (set! peak-loc i))))) (if (or (= peak 0.0) (= peak-loc 0)) (set! val 0.0) (let* ((la (data (- peak-loc 1))) (ra (data (+ peak-loc 1))) (logla (log (/ (max la .0000001) peak) 10)) ; (positive la)? (logra (log (/ (max ra .0000001) peak) 10))) (set! val (/ *clm-srate* (+ peak-loc (/ (* 0.5 (- logla logra)) (+ logla logra))))))))) val)) #| (let* ((rd (make-readin "oboe.snd")) (cur-srate (srate "oboe.snd")) (old-srate *clm-srate*)) (set! *clm-srate* cur-srate) (let* ((scn (make-moving-pitch rd)) (last-pitch 0.0) (pitch 0.0)) (do ((i 0 (+ i 1))) ((= i 22050)) (set! last-pitch pitch) (set! pitch (moving-pitch scn)) (if (not (= last-pitch pitch)) (format #t "~A: ~A~%" (* 1.0 (/ i cur-srate)) pitch)))) (set! *clm-srate* old-srate)) |# #| (define (abel k) ;; sum i from 1 to k (-1)^(i + 1) * (sin i) / i (with-sound (:clipped #f :statistics #t) (let ((harmonics (make-float-vector (* 2 k)))) (do ((i 1 (+ i 1)) (j 0 (+ j 2)) (n -1 (- n))) ((= i k)) (set! (harmonics j) i) (set! (harmonics (+ j 1)) (/ n i))) (let ((gen (make-polywave 100.0 :partials (normalize-partials harmonics)))) (do ((i 0 (+ i 1))) ((= i 100000)) (outa i (polywave gen))))))) (define* (adds num freq e amp v (type mus-chebyshev-first-kind)) (with-sound (:clipped #f :statistics #t :play #t) (let ((harmonics (make-float-vector (* 2 num))) (freqe (make-env e :length num))) (do ((i 1 (+ i 1)) (j 0 (+ j 2))) ((= i num)) (set! (harmonics j) i) (set! (harmonics (+ j 1)) (env freqe))) (let ((gen (make-polywave freq :partials (normalize-partials harmonics) :type type)) (vib (make-oscil 5))) (do ((i 0 (+ i 1))) ((= i 100000)) (outa i (* amp (polywave gen (* (hz->radians v) (oscil vib)))))))))) ;(adds 200 20 '(0 0 10 1 12 0 20 0 24 .2 35 0 46 0 57 .1 68 0) .5 2) ;(adds 300 15 '(0 0 10 1 12 0 20 0 24 .2 35 0 46 0 57 .1 68 0) .5 3) |# #| (defgenerator (circler :make-wrapper (lambda (g) (set! (g 'frequency) (hz->radians (g 'frequency))) g)) (frequency *clm-default-frequency*) (angle 0.0) fm) (define circler (let ((documentation "(make-circler (frequency 0.0) returns a circler generator. (circler gen (fm 0.0)) produces a waveform made up of half circles")) (lambda* (gen (fm 0.0)) (let-set! gen 'fm fm) (with-let gen (let* ((x (modulo angle (* 2 pi))) (xx (/ (* 4 x) (* 2 pi))) (y (if (< xx 2) (sqrt (- 1 (* (- 1 xx) (- 1 xx)))) (- (sqrt (- 1 (* (- 3 xx) (- 3 xx)))))))) (set! angle (+ x fm frequency)) y))))) (with-sound (:clipped #f :statistics #t) (let ((gen (make-circler 10.0))) (do ((i 0 (+ i 1))) ((= i 20000)) (outa i (circler gen))))) ;;; odd harmonics: 1, .18 .081 .048 .033 .024, .019 |# #| ;; "extremal trigonometric polynomials" (define (extremal-trig N freq) (with-sound () (let ((tan-scl (tan (/ pi (* 2 (+ N 1))))) (incr (hz->radians freq))) (do ((k 1 (+ k 1))) ((= k N)) (let ((cos-coeff (* tan-scl (sin (/ (* k pi) (+ N 1))))) (kincr (* k incr))) (do ((i 0 (+ i 1)) (x 0.0 (+ x kincr))) ((= i 40000)) (outa i (* cos-coeff (cos x))))))))) |# ;;; ---------------- flocsig (flanged locsig) ---------------- (defgenerator (flocsig ;; assume stereo out/rev :make-wrapper (lambda (g) (set! (g 'maxd) (ceiling (g 'amplitude))) ; was amplitude? (set! (g 'out1) (make-float-vector (g 'maxd))) (set! (g 'out2) (make-float-vector (g 'maxd))) (set! (g 'ri) (make-rand-interp :frequency (g 'frequency) :amplitude (- (g 'amplitude) 1.0))) (if (not (g 'offset)) (set! (g 'offset) (mus-random (* 0.3 (g 'amplitude))))) g)) (reverb-amount 0.0) (frequency 1.0) (amplitude 2.0) offset (maxd 0) (out1 #f) (out2 #f) (outloc 0) (ri #f) samp input) (define 1/sqrt2 (/ 1.0 (sqrt 2.0))) (define (flocsig gen samp input) ;; signal position and per-channel-delay depends on rand-interp (let-set! gen 'samp samp) (let-set! gen 'input input) (with-let gen (let* ((rpos (rand-interp ri)) (pos (min (max (+ rpos offset) (- amplitude)) amplitude)) (amp1 (if (<= pos -1.0) 1.0 (if (>= pos 1.0) 0.0 (* (sqrt (- 1.0 pos)) 1/sqrt2)))) (amp2 (if (<= pos -1.0) 0.0 (if (>= pos 1.0) 1.0 (* (sqrt (+ 1.0 pos)) 1/sqrt2)))) (dly1 (abs (min 0.0 pos))) (frac1 (- dly1 (floor dly1))) (dly2 (max 0.0 pos)) (frac2 (- dly2 (floor dly2))) (loc outloc) (size maxd) (loc10 (modulo (+ loc (floor dly1)) size)) (loc11 (modulo (+ loc 1 (floor dly1)) size)) (loc20 (modulo (+ loc (floor dly2)) size)) (loc21 (modulo (+ loc 1 (floor dly2)) size)) (rev reverb-amount)) (set! (out1 loc10) (+ (out1 loc10) (* amp1 input (- 1.0 frac1)))) (set! (out1 loc11) (+ (out1 loc11) (* amp1 input frac1))) (set! (out2 loc20) (+ (out2 loc20) (* amp2 input (- 1.0 frac2)))) (set! (out2 loc21) (+ (out2 loc21) (* amp2 input frac2))) (let ((val1 (out1 loc)) (val2 (out2 loc))) (set! (out1 loc) 0.0) (set! (out2 loc) 0.0) (set! loc (+ loc 1)) (if (= loc size) (set! loc 0)) (outa samp val1) (outb samp val2) (if (> rev 0.0) (begin (outa samp (* rev val1) *reverb*) (outb samp (* rev val2) *reverb*))) (set! outloc loc))))) ;;; -------------------------------------------------------------------------------- ;;; old version of one-pole-all-pass #| (defgenerator one-pole-allpass coeff input x1 y1) (define (one-pole-allpass gen input) (let-set! gen 'input input) (with-let gen (set! y1 (+ x1 (* coeff (- input y1)))) (set! x1 input) y1)) (defgenerator one-pole-allpass-bank coeff input x1 y1 x2 y2 x3 y3 x4 y4 x5 y5 x6 y6 x7 y7 x8 y8) (define (one-pole-allpass-bank gen input) (let-set! gen 'input input) (with-let gen (set! y1 (+ x1 (* coeff (- input y1)))) (set! x1 input) (set! y2 (+ x2 (* coeff (- y1 y2)))) (set! x2 y1) (set! y3 (+ x3 (* coeff (- y2 y3)))) (set! x3 y2) (set! y4 (+ x4 (* coeff (- y3 y4)))) (set! x4 y3) (set! y5 (+ x5 (* coeff (- y4 y5)))) (set! x5 y4) (set! y6 (+ x6 (* coeff (- y5 y6)))) (set! x6 y5) (set! y7 (+ x7 (* coeff (- y6 y7)))) (set! x7 y6) (set! y8 (+ x8 (* coeff (- y7 y8)))) (set! x8 y7) y8)) (defgenerator expseg currentValue targetValue r) (define (expseg gen r) (let-set! gen 'r r) (with-let gen (set! currentValue (+ (* r targetValue) (* (- 1.0 r) currentValue))))) ;(set! currentValue (+ currentValue (* r (- targetValue currentValue)))))) ;; (bil) this is slightly different (getting clicks) (define (make-one-pole-swept) (vector 0.0)) (define (one-pole-swept gen input coef) ;; signal controlled one-pole lowpass filter (set! (gen 0) (- (* (+ 1.0 coef) input) (* coef (gen 0))))) (define (make-pnoise) (vector 16383)) (define (pnoise gen x) ;; very special noise generator (set! (gen 0) (logand (floor (+ (* (gen 0) 1103515245) 12345)) #xffffffff)) ;; (bil) added the logand -- otherwise we get an overflow somewhere (* x (- (* (modulo (floor (/ (gen 0) 65536.0)) 65536) 0.0000305185) 1.0))) ;; this looks nutty to me -- was it originally running in 32 bits? (define pn-gen 16383) (define (pnoise x) ;; very special noise generator (set! pn-gen (logand (+ (* pn-gen 1103515245) 12345) #xffffffff)) ;; (bil) added the logand -- otherwise we get an overflow somewhere, also removed floor (* x (- (* pn-gen 4.6566128730774e-10) 1.0))) |# ;;; -------------------------------------------------------------------------------- (define (calling-all-generators) ;; for snd-test (with-sound (:play #f) (lutish 0 1 440 .1) (oboish 1 1 300 .1 '(0 0 1 1 2 0)) (nkssber 2 1 1000 100 5 5 0.5) (stringy 3 1 1000 .5) (ercoser 4 1 100 .5 0.1) (bouncy 5 2 300 .5 5 10) (pianoy 6 3 100 .5) (pianoy1 7 4 200 .5 1 .1) (pianoy2 8 1 100 .5) (glassy 9 .1 1000 .5) (machine1 10 .3 100 540 0.5 3.0 0.0) (organish 11 .4 100 .5 1.0 #f) (brassy 12 4 50 .5 '(0 0 1 1 10 1 11 0) '(0 1 1 0) 1000))) snd-16.1/snd-fft.c0000644000076400007640000031420512603035272012045 0ustar bilbil#include "snd.h" #include "clm2xen.h" #include "sndlib2xen.h" /* -------------------------------- WAVELET TRANSFORM -------------------------------- */ /* * taken from wavelets.cl in clm which is taken from * M. J. Shensa Naval Ocean Systems Center, * Wickerhauser "Adapted Wavelet Analysis", * and the UBC Imager Wavelet Package by Bob Lewis * later stuff from Numerical Recipes */ static void wavelet_transform(mus_float_t *data, mus_long_t num, mus_float_t *cc, mus_long_t cc_size) { mus_float_t *data1 = NULL; mus_float_t sig = -1.0; mus_float_t *cr = NULL; mus_long_t i, j, n, ii, ni, k, jf; cr = (mus_float_t *)malloc(cc_size * sizeof(mus_float_t)); for (i = 0, j = cc_size - 1; i < cc_size; i++, j--) { cr[j] = sig * cc[i]; sig = -sig; } for (n = num; n >= 4; n /= 2) { mus_long_t n1, nh, nmod, joff; if (data1) free(data1); data1 = (mus_float_t *)calloc(n, sizeof(mus_float_t)); n1 = n - 1; nmod = cc_size * n; nh = n >> 1; joff = -(cc_size >> 1); for (ii = 0, i = 1; i <= n; i += 2, ii++) { ni = i + nmod + joff; for (k = 0; k < cc_size; k++) { jf = n1 & (ni + k + 1); data1[ii] += cc[k] * data[jf]; data1[ii + nh] += cr[k] * data[jf]; } } memcpy((void *)data, (void *)data1, n * sizeof(mus_float_t)); } if (data1) free(data1); if (cr) free(cr); } /* these are from daub.h musicdsp.org, Computed by Kazuo Hatano, Aichi Institute of Technology. */ /* static mus_float_t Daub1[2] = { 7.07106781186e-01, 7.07106781186e-01}; */ static mus_float_t Daub2[4] = { 4.82962913144e-01, 8.36516303737e-01, 2.24143868042e-01,-1.29409522551e-01}; static mus_float_t Daub3[6] = { 3.32670552950e-01, 8.06891509311e-01, 4.59877502118e-01,-1.35011020010e-01,-8.54412738820e-02, 3.52262918857e-02}; static mus_float_t Daub4[8] = { 2.30377813308e-01, 7.14846570552e-01, 6.30880767929e-01,-2.79837694168e-02,-1.87034811719e-01, 3.08413818355e-02, 3.28830116668e-02,-1.05974017850e-02}; static mus_float_t Daub5[10] = { 1.60102397974e-01, 6.03829269797e-01, 7.24308528437e-01, 1.38428145901e-01,-2.42294887066e-01,-3.22448695846e-02, 7.75714938400e-02,-6.24149021279e-03,-1.25807519990e-02, 3.33572528547e-03}; static mus_float_t Daub6[12] = { 1.11540743350e-01, 4.94623890398e-01, 7.51133908021e-01, 3.15250351709e-01, -2.26264693965e-01,-1.29766867567e-01, 9.75016055873e-02, 2.75228655303e-02,-3.15820393174e-02, 5.53842201161e-04, 4.77725751094e-03,-1.07730108530e-03}; static mus_float_t Daub7[14] = { 7.78520540850e-02, 3.96539319481e-01, 7.29132090846e-01, 4.69782287405e-01,-1.43906003928e-01,-2.24036184993e-01, 7.13092192668e-02, 8.06126091510e-02,-3.80299369350e-02,-1.65745416306e-02, 1.25509985560e-02, 4.29577972921e-04,-1.80164070404e-03, 3.53713799974e-04}; static mus_float_t Daub8[16] = { 5.44158422431e-02, 3.12871590914e-01, 6.75630736297e-01, 5.85354683654e-01,-1.58291052563e-02,-2.84015542961e-01, 4.72484573913e-04, 1.28747426620e-01,-1.73693010018e-02,-4.40882539307e-02, 1.39810279173e-02, 8.74609404740e-03,-4.87035299345e-03,-3.91740373376e-04, 6.75449406450e-04,-1.17476784124e-04}; static mus_float_t Daub9[18] = { 3.80779473638e-02, 2.43834674612e-01, 6.04823123690e-01, 6.57288078051e-01, 1.33197385825e-01,-2.93273783279e-01,-9.68407832229e-02, 1.48540749338e-01, 3.07256814793e-02,-6.76328290613e-02, 2.50947114831e-04, 2.23616621236e-02,-4.72320475775e-03,-4.28150368246e-03, 1.84764688305e-03, 2.30385763523e-04,-2.51963188942e-04, 3.93473203162e-05}; static mus_float_t Daub10[20] = { 2.66700579005e-02, 1.88176800077e-01, 5.27201188931e-01, 6.88459039453e-01, 2.81172343660e-01,-2.49846424327e-01,-1.95946274377e-01, 1.27369340335e-01, 9.30573646035e-02,-7.13941471663e-02,-2.94575368218e-02, 3.32126740593e-02, 3.60655356695e-03,-1.07331754833e-02, 1.39535174705e-03, 1.99240529518e-03,-6.85856694959e-04,-1.16466855129e-04, 9.35886703200e-05,-1.32642028945e-05}; static mus_float_t Daub11[22] = { 1.86942977614e-02, 1.44067021150e-01, 4.49899764356e-01, 6.85686774916e-01, 4.11964368947e-01,-1.62275245027e-01,-2.74230846817e-01, 6.60435881966e-02, 1.49812012466e-01,-4.64799551166e-02,-6.64387856950e-02, 3.13350902190e-02, 2.08409043601e-02,-1.53648209062e-02,-3.34085887301e-03, 4.92841765605e-03,-3.08592858815e-04,-8.93023250666e-04, 2.49152523552e-04, 5.44390746993e-05,-3.46349841869e-05, 4.49427427723e-06}; static mus_float_t Daub12[24] = { 1.31122579572e-02, 1.09566272821e-01, 3.77355135214e-01, 6.57198722579e-01, 5.15886478427e-01,-4.47638856537e-02,-3.16178453752e-01,-2.37792572560e-02, 1.82478605927e-01, 5.35956967435e-03,-9.64321200965e-02, 1.08491302558e-02, 4.15462774950e-02,-1.22186490697e-02,-1.28408251983e-02, 6.71149900879e-03, 2.24860724099e-03,-2.17950361862e-03, 6.54512821250e-06, 3.88653062820e-04,-8.85041092082e-05,-2.42415457570e-05, 1.27769522193e-05,-1.52907175806e-06}; static mus_float_t Daub13[26] = { 9.20213353896e-03, 8.28612438729e-02, 3.11996322160e-01, 6.11055851158e-01, 5.88889570431e-01, 8.69857261796e-02,-3.14972907711e-01,-1.24576730750e-01, 1.79476079429e-01, 7.29489336567e-02,-1.05807618187e-01,-2.64884064753e-02, 5.61394771002e-02, 2.37997225405e-03,-2.38314207103e-02, 3.92394144879e-03, 7.25558940161e-03,-2.76191123465e-03,-1.31567391189e-03, 9.32326130867e-04, 4.92515251262e-05,-1.65128988556e-04, 3.06785375793e-05, 1.04419305714e-05,-4.70041647936e-06, 5.22003509845e-07}; static mus_float_t Daub14[28] = { 6.46115346008e-03, 6.23647588493e-02, 2.54850267792e-01, 5.54305617940e-01, 6.31187849104e-01, 2.18670687758e-01,-2.71688552278e-01,-2.18033529993e-01, 1.38395213864e-01, 1.39989016584e-01,-8.67484115681e-02,-7.15489555040e-02, 5.52371262592e-02, 2.69814083079e-02,-3.01853515403e-02,-5.61504953035e-03, 1.27894932663e-02,-7.46218989268e-04,-3.84963886802e-03, 1.06169108560e-03, 7.08021154235e-04,-3.86831947312e-04,-4.17772457703e-05, 6.87550425269e-05,-1.03372091845e-05,-4.38970490178e-06, 1.72499467536e-06,-1.78713996831e-07}; static mus_float_t Daub15[30] = { 4.53853736157e-03, 4.67433948927e-02, 2.06023863986e-01, 4.92631771708e-01, 6.45813140357e-01, 3.39002535454e-01,-1.93204139609e-01,-2.88882596566e-01, 6.52829528487e-02, 1.90146714007e-01,-3.96661765557e-02,-1.11120936037e-01, 3.38771439235e-02, 5.47805505845e-02,-2.57670073284e-02,-2.08100501696e-02, 1.50839180278e-02, 5.10100036040e-03,-6.48773456031e-03,-2.41756490761e-04, 1.94332398038e-03,-3.73482354137e-04,-3.59565244362e-04, 1.55896489920e-04, 2.57926991553e-05,-2.81332962660e-05, 3.36298718173e-06, 1.81127040794e-06,-6.31688232588e-07, 6.13335991330e-08}; static mus_float_t Daub16[32] = { 3.18922092534e-03, 3.49077143236e-02, 1.65064283488e-01, 4.30312722846e-01, 6.37356332083e-01, 4.40290256886e-01,-8.97510894024e-02,-3.27063310527e-01,-2.79182081330e-02, 2.11190693947e-01, 2.73402637527e-02,-1.32388305563e-01,-6.23972275247e-03, 7.59242360442e-02,-7.58897436885e-03,-3.68883976917e-02, 1.02976596409e-02, 1.39937688598e-02,-6.99001456341e-03,-3.64427962149e-03, 3.12802338120e-03, 4.07896980849e-04,-9.41021749359e-04, 1.14241520038e-04, 1.74787245225e-04,-6.10359662141e-05,-1.39456689882e-05, 1.13366086612e-05,-1.04357134231e-06,-7.36365678545e-07, 2.30878408685e-07,-2.10933963010e-08}; static mus_float_t Daub17[34] = { 2.24180700103e-03, 2.59853937036e-02, 1.31214903307e-01, 3.70350724152e-01, 6.10996615684e-01, 5.18315764056e-01, 2.73149704032e-02,-3.28320748363e-01,-1.26599752215e-01, 1.97310589565e-01, 1.01135489177e-01,-1.26815691778e-01,-5.70914196316e-02, 8.11059866541e-02, 2.23123361781e-02,-4.69224383892e-02,-3.27095553581e-03, 2.27336765839e-02,-3.04298998135e-03,-8.60292152032e-03, 2.96799669152e-03, 2.30120524215e-03,-1.43684530480e-03,-3.28132519409e-04, 4.39465427768e-04,-2.56101095665e-05,-8.20480320245e-05, 2.31868137987e-05, 6.99060098507e-06,-4.50594247722e-06, 3.01654960999e-07, 2.95770093331e-07,-8.42394844600e-08, 7.26749296856e-09}; static mus_float_t Daub18[36] = { 1.57631021844e-03, 1.92885317241e-02, 1.03588465822e-01, 3.14678941337e-01, 5.71826807766e-01, 5.71801654888e-01, 1.47223111969e-01,-2.93654040736e-01,-2.16480934005e-01, 1.49533975565e-01, 1.67081312763e-01,-9.23318841508e-02,-1.06752246659e-01, 6.48872162119e-02, 5.70512477385e-02,-4.45261419029e-02,-2.37332103958e-02, 2.66707059264e-02, 6.26216795430e-03,-1.30514809466e-02, 1.18630033858e-04, 4.94334360546e-03,-1.11873266699e-03,-1.34059629833e-03, 6.28465682965e-04, 2.13581561910e-04,-1.98648552311e-04,-1.53591712353e-07, 3.74123788074e-05,-8.52060253744e-06,-3.33263447888e-06, 1.76871298362e-06,-7.69163268988e-08,-1.17609876702e-07, 3.06883586304e-08,-2.50793445494e-09}; static mus_float_t Daub19[38] = { 1.10866976318e-03, 1.42810984507e-02, 8.12781132654e-02, 2.64388431740e-01, 5.24436377464e-01, 6.01704549127e-01, 2.60894952651e-01,-2.28091394215e-01,-2.85838631755e-01, 7.46522697081e-02, 2.12349743306e-01,-3.35185419023e-02,-1.42785695038e-01, 2.75843506256e-02, 8.69067555558e-02,-2.65012362501e-02,-4.56742262772e-02, 2.16237674095e-02, 1.93755498891e-02,-1.39883886785e-02,-5.86692228101e-03, 7.04074736710e-03, 7.68954359257e-04,-2.68755180070e-03, 3.41808653458e-04, 7.35802520505e-04,-2.60676135678e-04,-1.24600791734e-04, 8.71127046721e-05, 5.10595048707e-06,-1.66401762971e-05, 3.01096431629e-06, 1.53193147669e-06,-6.86275565776e-07, 1.44708829879e-08, 4.63693777578e-08,-1.11640206703e-08, 8.66684883899e-10}; static mus_float_t Daub20[40] = { 7.79953613666e-04, 1.05493946249e-02, 6.34237804590e-02, 2.19942113551e-01, 4.72696185310e-01, 6.10493238938e-01, 3.61502298739e-01,-1.39212088011e-01,-3.26786800434e-01,-1.67270883090e-02, 2.28291050819e-01, 3.98502464577e-02,-1.55458750707e-01,-2.47168273386e-02, 1.02291719174e-01, 5.63224685730e-03,-6.17228996246e-02, 5.87468181181e-03, 3.22942995307e-02,-8.78932492390e-03,-1.38105261371e-02, 6.72162730225e-03, 4.42054238704e-03,-3.58149425960e-03,-8.31562172822e-04, 1.39255961932e-03,-5.34975984399e-05,-3.85104748699e-04, 1.01532889736e-04, 6.77428082837e-05,-3.71058618339e-05,-4.37614386218e-06, 7.24124828767e-06,-1.01199401001e-06,-6.84707959700e-07, 2.63392422627e-07, 2.01432202355e-10,-1.81484324829e-08, 4.05612705555e-09,-2.99883648961e-10}; static mus_float_t Daub21[42] = { 5.48822509852e-04, 7.77663905235e-03, 4.92477715381e-02, 1.81359625440e-01, 4.19687944939e-01, 6.01506094935e-01, 4.44590451927e-01,-3.57229196172e-02,-3.35664089530e-01,-1.12397071568e-01, 2.11564527680e-01, 1.15233298439e-01,-1.39940424932e-01,-8.17759429808e-02, 9.66003903237e-02, 4.57234057492e-02,-6.49775048937e-02,-1.86538592021e-02, 3.97268354278e-02, 3.35775639033e-03,-2.08920536779e-02, 2.40347092080e-03, 8.98882438197e-03,-2.89133434858e-03,-2.95837403893e-03, 1.71660704063e-03, 6.39418500512e-04,-6.90671117082e-04,-3.19640627768e-05, 1.93664650416e-04,-3.63552025008e-05,-3.49966598498e-05, 1.53548250927e-05, 2.79033053981e-06,-3.09001716454e-06, 3.16609544236e-07, 2.99213663046e-07,-1.00040087903e-07,-2.25401497467e-09, 7.05803354123e-09,-1.47195419765e-09, 1.03880557102e-10}; static mus_float_t Daub22[44] = { 3.86263231491e-04, 5.72185463133e-03, 3.80699372364e-02, 1.48367540890e-01, 3.67728683446e-01, 5.78432731009e-01, 5.07901090622e-01, 7.37245011836e-02,-3.12726580428e-01,-2.00568406104e-01, 1.64093188106e-01, 1.79973187992e-01,-9.71107984091e-02,-1.31768137686e-01, 6.80763143927e-02, 8.45573763668e-02,-5.13642542974e-02,-4.65308118275e-02, 3.69708466206e-02, 2.05867076275e-02,-2.34800013444e-02,-6.21378284936e-03, 1.25647252183e-02, 3.00137398507e-04,-5.45569198615e-03, 1.04426073918e-03, 1.82701049565e-03,-7.70690988123e-04,-4.23787399839e-04, 3.28609414213e-04, 4.34589990453e-05,-9.40522363481e-05, 1.13743496621e-05, 1.73737569575e-05,-6.16672931646e-06,-1.56517913199e-06, 1.29518205731e-06,-8.77987987336e-08,-1.28333622875e-07, 3.76122874933e-08, 1.68017140492e-09,-2.72962314663e-09, 5.33593882166e-10,-3.60211348433e-11}; static mus_float_t Daub23[46] = { 2.71904194128e-04, 4.20274889318e-03, 2.93100036578e-02, 1.20515531783e-01, 3.18450813852e-01, 5.44931147873e-01, 5.51018517241e-01, 1.81392625363e-01,-2.61392148030e-01,-2.71402098607e-01, 9.21254070824e-02, 2.23573658242e-01,-3.30374470942e-02,-1.64011321531e-01, 2.02830745756e-02, 1.12297043618e-01,-2.11262123562e-02,-7.02073915749e-02, 2.17658568344e-02, 3.84953325225e-02,-1.85235136501e-02,-1.75371010030e-02, 1.27519439315e-02, 6.03184065002e-03,-7.07531927370e-03,-1.13486547335e-03, 3.12287644981e-03,-2.46501400516e-04,-1.06123122888e-03, 3.19420492709e-04, 2.56762452007e-04,-1.50021850349e-04,-3.37889483412e-05, 4.42607120310e-05,-2.63520788924e-06,-8.34787556785e-06, 2.39756954684e-06, 8.14757483477e-07,-5.33900540520e-07, 1.85309178563e-08, 5.41754917953e-08,-1.39993549543e-08,-9.47288590181e-10, 1.05044645369e-09,-1.93240511131e-10, 1.25020330235e-11}; static mus_float_t Daub24[48] = { 1.91435800947e-04, 3.08208171490e-03, 2.24823399497e-02, 9.72622358336e-02, 2.72908916067e-01, 5.04371040839e-01, 5.74939221095e-01, 2.80985553233e-01,-1.87271406885e-01,-3.17943078999e-01, 4.77661368434e-03, 2.39237388780e-01, 4.25287296414e-02,-1.71175351370e-01,-3.87771735779e-02, 1.21016303469e-01, 2.09801137091e-02,-8.21616542080e-02,-4.57843624181e-03, 5.13016200399e-02,-4.94470942812e-03,-2.82131070949e-02, 7.66172188164e-03, 1.30499708710e-02,-6.29143537001e-03,-4.74656878632e-03, 3.73604617828e-03, 1.15376493683e-03,-1.69645681897e-03,-4.41618485614e-05, 5.86127059318e-04,-1.18123323796e-04,-1.46007981776e-04, 6.55938863930e-05, 2.18324146046e-05,-2.02288829261e-05, 1.34115775080e-08, 3.90110033859e-06,-8.98025314393e-07,-4.03250775687e-07, 2.16633965327e-07,-5.05764541979e-10,-2.25574038817e-08, 5.15777678967e-09, 4.74837582425e-10,-4.02465864458e-10, 6.99180115763e-11,-4.34278250380e-12}; static mus_float_t Daub25[50] = { 1.34802979347e-04, 2.25695959185e-03, 1.71867412540e-02, 7.80358628721e-02, 2.31693507886e-01, 4.59683415146e-01, 5.81636896746e-01, 3.67885074802e-01,-9.71746409646e-02,-3.36473079641e-01,-8.75876145876e-02, 2.24537819745e-01, 1.18155286719e-01,-1.50560213750e-01,-9.85086152899e-02, 1.06633805018e-01, 6.67521644940e-02,-7.70841110565e-02,-3.71739628611e-02, 5.36179093987e-02, 1.55426059291e-02,-3.40423204606e-02,-3.07983679484e-03, 1.89228044766e-02,-1.98942578220e-03,-8.86070261804e-03, 2.72693625873e-03, 3.32270777397e-03,-1.84248429020e-03,-8.99977423746e-04, 8.77258193674e-04, 1.15321244046e-04,-3.09880099098e-04, 3.54371452327e-05, 7.90464000396e-05,-2.73304811996e-05,-1.27719529319e-05, 8.99066139306e-06, 5.23282770815e-07,-1.77920133265e-06, 3.21203751886e-07, 1.92280679014e-07,-8.65694173227e-08,-2.61159855611e-09, 9.27922448008e-09,-1.88041575506e-09,-2.22847491022e-10, 1.53590157016e-10,-2.52762516346e-11, 1.50969208282e-12}; static mus_float_t Daub26[52] = { 9.49379575071e-05, 1.65052023353e-03, 1.30975542925e-02, 6.22747440251e-02, 1.95039438716e-01, 4.13292962278e-01, 5.73669043034e-01, 4.39158311789e-01, 1.77407678098e-03,-3.26384593691e-01,-1.74839961289e-01, 1.81291832311e-01, 1.82755409589e-01,-1.04323900285e-01,-1.47977193275e-01, 6.98231861132e-02, 1.06482405249e-01,-5.34485616814e-02,-6.86547596040e-02, 4.22321857963e-02, 3.85357159711e-02,-3.13781103630e-02,-1.77609035683e-02, 2.07349201799e-02, 5.82958055531e-03,-1.17854979061e-02,-5.28738399262e-04, 5.60194723942e-03,-9.39058250473e-04,-2.14553028156e-03, 8.38348805654e-04, 6.16138220457e-04,-4.31955707426e-04,-1.06057474828e-04, 1.57479523860e-04,-5.27779549303e-06,-4.10967399639e-05, 1.07422154087e-05, 7.00007868296e-06,-3.88740016185e-06,-4.65046322064e-07, 7.93921063370e-07,-1.07900423757e-07,-8.90446637016e-08, 3.40779562129e-08, 2.16932825985e-09,-3.77601047853e-09, 6.78004724582e-10, 1.00230319104e-10,-5.84040818534e-11, 9.13051001637e-12,-5.25187122424e-13}; static mus_float_t Daub27[54] = { 6.68713138543e-05, 1.20553123167e-03, 9.95258878087e-03, 4.94525999829e-02, 1.62922027502e-01, 3.67110214125e-01, 5.53849860990e-01, 4.93406122677e-01, 1.02840855061e-01,-2.89716803314e-01,-2.48264581903e-01, 1.14823019517e-01, 2.27273288414e-01,-3.87864186318e-02,-1.78031740959e-01, 1.57993974602e-02, 1.31197971717e-01,-1.40627515558e-02,-9.10229065295e-02, 1.73110182654e-02, 5.79694057347e-02,-1.85124935619e-02,-3.27390666310e-02, 1.61469669223e-02, 1.56655956489e-02,-1.15771864589e-02,-5.86209634546e-03, 6.85663560968e-03, 1.34262687730e-03,-3.33285446952e-03, 1.45752962593e-04, 1.30117745024e-03,-3.41835122691e-04,-3.87901857410e-04, 2.01971987969e-04, 7.66005838706e-05,-7.71114551779e-05,-3.51748361490e-06, 2.06344264773e-05,-3.90116407063e-06,-3.65750090818e-06, 1.63436962472e-06, 3.05088068625e-07,-3.47246814739e-07, 3.28655896805e-08, 4.02625505286e-08,-1.32133227399e-08,-1.30946560685e-09, 1.52161498477e-09,-2.41552692801e-10,-4.37498622429e-11, 2.21366208806e-11,-3.29579012247e-12, 1.82818835288e-13}; static mus_float_t Daub28[56] = { 4.71080777501e-05, 8.79498515984e-04, 7.54265037764e-03, 3.90926081154e-02, 1.35137914253e-01, 3.22563361285e-01, 5.24998231630e-01, 5.30516293441e-01, 2.00176144045e-01,-2.30498954047e-01,-3.01327809532e-01, 3.28578791633e-02, 2.45808151373e-01, 3.69068853157e-02,-1.82877330732e-01,-4.68382337445e-02, 1.34627567910e-01, 3.44786312750e-02,-9.76853558056e-02,-1.73419228313e-02, 6.77478955019e-02, 3.44801895554e-03,-4.33333686160e-02, 4.43173291006e-03, 2.46880600101e-02,-6.81554976455e-03,-1.20635919682e-02, 5.83881662774e-03, 4.78486311245e-03,-3.72546124707e-03,-1.36037384563e-03, 1.87599866820e-03, 1.41567239314e-04,-7.48674955911e-04, 1.15465606365e-04, 2.29579098223e-04,-8.90390149004e-05,-4.90771341619e-05, 3.64140121105e-05, 4.63866498139e-06,-1.00432604133e-05, 1.24790031757e-06, 1.84036373451e-06,-6.67021547995e-07,-1.75746117320e-07, 1.49066001353e-07,-8.26238731562e-09,-1.78413869087e-08, 5.04404705638e-09, 6.94454032894e-10,-6.07704124722e-10, 8.49222001105e-11, 1.86736726378e-11,-8.36549047125e-12, 1.18885053340e-12,-6.36777235471e-14}; static mus_float_t Daub29[58] = { 3.31896627984e-05, 6.40951680304e-04, 5.70212651777e-03, 3.07735802214e-02, 1.11370116951e-01, 2.80653455970e-01, 4.89758804762e-01, 5.51374432758e-01, 2.89105238335e-01,-1.54028734459e-01,-3.30040948917e-01,-5.57068000729e-02, 2.36105236153e-01, 1.12419174873e-01,-1.60877988594e-01,-1.07845949938e-01, 1.14472295893e-01, 8.32207471624e-02,-8.51254926156e-02,-5.50274895253e-02, 6.34791645842e-02, 3.05315432727e-02,-4.51879812777e-02,-1.29171425542e-02, 2.94704318717e-02, 2.64832730767e-03,-1.70412245736e-02, 1.73788033272e-03, 8.46972549356e-03,-2.55080712778e-03,-3.47379898968e-03, 1.87712092572e-03, 1.08705394222e-03,-1.00077832708e-03,-2.00071136307e-04, 4.11128345474e-04,-2.29201804121e-05,-1.29304484008e-04, 3.64502606856e-05, 2.91334475016e-05,-1.65732839530e-05,-3.59364480402e-06, 4.75060924645e-06,-3.02905459205e-07,-8.97570175063e-07, 2.63389838699e-07, 9.38719741109e-08,-6.28615692201e-08, 1.07659190661e-09, 7.76897885477e-09,-1.89399538617e-09,-3.42680086326e-10, 2.40709945350e-10,-2.94058925076e-11,-7.83250973362e-12, 3.15276241337e-12,-4.28565487006e-13, 2.21919131158e-14}; static mus_float_t Daub30[60] = { 2.33861617273e-05, 4.66637950428e-04, 4.30079716504e-03, 2.41308326715e-02, 9.12383040670e-02, 2.42020670940e-01, 4.50487821853e-01, 5.57572232912e-01, 3.66242683371e-01,-6.61836707759e-02,-3.32966975020e-01,-1.41968513330e-01, 1.99462121580e-01, 1.77829873244e-01,-1.14558219432e-01,-1.57236817959e-01, 7.27786589703e-02, 1.22747746045e-01,-5.38064654582e-02,-8.76586900363e-02, 4.38016646714e-02, 5.67123657447e-02,-3.56733974967e-02,-3.22637589193e-02, 2.70786195952e-02, 1.52879607698e-02,-1.83997438681e-02,-5.29685966613e-03, 1.09156316583e-02, 6.19671756497e-04,-5.53073014819e-03, 8.43384586662e-04, 2.32452009406e-03,-8.60927696811e-04,-7.67878250438e-04, 5.05094823903e-04, 1.72482584235e-04,-2.16171830116e-04,-8.54830546758e-06, 6.98200837080e-05,-1.33971686329e-05,-1.63615247872e-05, 7.25214553589e-06, 2.32754909849e-06,-2.18726767699e-06, 1.09947433852e-08, 4.26166232601e-07,-1.00041468235e-07,-4.76437996513e-08, 2.60544275497e-08, 5.55339786139e-10,-3.33110568046e-09, 6.98486269183e-10, 1.61362297827e-10,-9.46138799727e-11, 1.00010513139e-11, 3.23942863853e-12,-1.18523759210e-12, 1.54399757084e-13,-7.73794263095e-15}; static mus_float_t Daub31[62] = { 1.64801338645e-05, 3.39412203776e-04, 3.23688406862e-03, 1.88536916129e-02, 7.43360930116e-02, 2.07012874485e-01, 4.09192200037e-01, 5.51139840914e-01, 4.29468808206e-01, 2.71692124973e-02,-3.10955118319e-01,-2.17978485523e-01, 1.40178288765e-01, 2.24966711473e-01,-4.99263491604e-02,-1.86962360895e-01, 1.54369884294e-02, 1.45089500931e-01,-8.13983227346e-03,-1.07612773323e-01, 1.09412974523e-02, 7.53536117432e-02,-1.48800266181e-02,-4.86190754648e-02, 1.61541715659e-02, 2.80476193667e-02,-1.42762752777e-02,-1.39005529392e-02, 1.05176394873e-02, 5.51616357331e-03,-6.52085237587e-03,-1.42826422321e-03, 3.39306677671e-03,-6.39790110601e-05,-1.45904174198e-03, 3.43139829690e-04, 4.99881617563e-04,-2.39658346940e-04,-1.24341161725e-04, 1.08958435041e-04, 1.50133572744e-05,-3.63125515786e-05, 4.03452023518e-06, 8.79530134269e-06,-3.03514236589e-06,-1.36906023094e-06, 9.81001542204e-07, 5.32725065697e-08,-1.97592512917e-07, 3.61682651733e-08, 2.32830971382e-08,-1.06152960215e-08,-6.47431168795e-10, 1.40856815102e-09,-2.52404395415e-10,-7.34893003248e-11, 3.69210880887e-11,-3.32700896712e-12,-1.32433491724e-12, 4.44546709629e-13,-5.55944205057e-14, 2.69938287976e-15}; static mus_float_t Daub32[64] = { 1.16146330213e-05, 2.46656690638e-04, 2.43126191957e-03, 1.46810463814e-02, 6.02574991203e-02, 1.75750783639e-01, 3.67509628597e-01, 5.34317919340e-01, 4.77809163733e-01, 1.20630538265e-01,-2.66698181476e-01,-2.77421581558e-01, 6.47133548055e-02, 2.48310642356e-01, 2.46624448396e-02,-1.92102344708e-01,-4.89951171846e-02, 1.45232079475e-01, 4.44049081999e-02,-1.09456113116e-01,-2.96278725084e-02, 8.08741406384e-02, 1.41061515161e-02,-5.69263140624e-02,-2.38026446493e-03, 3.70514579235e-02,-4.14590766082e-03,-2.16628228363e-02, 6.16752731068e-03, 1.10174007154e-02,-5.41156825727e-03,-4.64921675118e-03, 3.62722464068e-03, 1.46895510046e-03,-1.96474055582e-03,-2.21167872957e-04, 8.67305851845e-04,-1.02453731060e-04,-3.05965442382e-04, 1.05391546173e-04, 8.10367832913e-05,-5.25980928268e-05,-1.29404577940e-05, 1.82426840198e-05,-6.36178153226e-07,-4.55830957626e-06, 1.20288903632e-06, 7.56004762559e-07,-4.28597069315e-07,-5.00336186874e-08, 8.96596631195e-08,-1.21992435948e-08,-1.10438302172e-08, 4.25042231198e-09, 4.38438779994e-10,-5.88109146263e-10, 8.90472379622e-11, 3.26327074133e-11,-1.43091876516e-11, 1.07561065350e-12, 5.36148222961e-13,-1.66380048943e-13, 2.00071530381e-14,-9.42101913953e-16}; static mus_float_t Daub33[66] = { 8.18635831417e-06, 1.79101615370e-04, 1.82270943516e-03, 1.13959433745e-02, 4.86146665317e-02, 1.48186313180e-01, 3.26718130117e-01, 5.09376172514e-01, 5.11254770583e-01, 2.09582350713e-01,-2.04202622398e-01,-3.15997410766e-01,-1.92783394369e-02, 2.45420612119e-01, 9.98515586803e-02,-1.71428099051e-01,-1.10844133116e-01, 1.21967856403e-01, 9.47880880506e-02,-9.11469683513e-02,-7.03024850540e-02, 7.01911439409e-02, 4.57345618938e-02,-5.34712513358e-02,-2.52485829774e-02, 3.86870607602e-02, 1.07032658200e-02,-2.57287617547e-02,-2.16775861735e-03, 1.53169541158e-02,-1.59428878241e-03,-7.95354038705e-03, 2.38906240816e-03, 3.48080095340e-03,-1.86071821445e-03,-1.20430925760e-03, 1.07438069635e-03, 2.72730584733e-04,-4.90832900759e-04, 4.39316625176e-06, 1.78043189825e-04,-4.16043851627e-05,-4.92956442341e-05, 2.42333539881e-05, 9.07080575782e-06,-8.86612136675e-06,-3.60751610287e-07, 2.28837127614e-06,-4.42692340795e-07,-3.98579129198e-07, 1.82244333257e-07, 3.37797270373e-08,-3.98783819851e-08, 3.67286357683e-09, 5.11121185734e-09,-1.67139267725e-09,-2.49640210524e-10, 2.42683310230e-10,-3.04957445394e-11,-1.42023685988e-11, 5.50941472076e-12,-3.34348121895e-13,-2.15248838683e-13, 6.21474024717e-14,-7.19651054536e-15, 3.28937367841e-16}; static mus_float_t Daub34[68] = { 5.77051063273e-06, 1.29947620067e-04, 1.36406139005e-03, 8.81988940388e-03, 3.90488413517e-02, 1.24152482111e-01, 2.87765059233e-01, 4.78478746279e-01, 5.30555099656e-01, 2.90366329507e-01,-1.28246842174e-01,-3.31525301508e-01,-1.03891915515e-01, 2.16907220187e-01, 1.66601750412e-01,-1.27337358223e-01,-1.60924927177e-01, 7.79918469379e-02, 1.34125960271e-01,-5.44829680641e-02,-1.02947596992e-01, 4.35760946496e-02, 7.31852354367e-02,-3.70128384178e-02,-4.74385596452e-02, 3.07397465739e-02, 2.72283507563e-02,-2.36717379228e-02,-1.31439800166e-02, 1.64093741998e-02, 4.71364926099e-03,-1.00455067083e-02,-6.19474884515e-04, 5.33495076875e-03,-7.69212797506e-04,-2.39945394353e-03, 8.58995987436e-04, 8.75199906407e-04,-5.52735576214e-04,-2.32673214023e-04, 2.65077239755e-04, 2.66005001845e-05,-9.91469777078e-05, 1.35311722724e-05, 2.84495141969e-05,-1.05765749425e-05,-5.71082651099e-06, 4.16987175854e-06, 4.97971810142e-07,-1.11630653481e-06, 1.44819570833e-07, 2.02599066666e-07,-7.52670174041e-08,-1.99034650153e-08, 1.74042333293e-08,-8.66574426136e-10,-2.31650194699e-09, 6.44637821032e-10, 1.30041031860e-10,-9.90477453763e-11, 1.00420873546e-11, 6.08012535400e-12,-2.10787910891e-12, 9.79945115821e-14, 8.57919405179e-14,-2.31708370390e-14, 2.58733838193e-15,-1.14894475448e-16}; static mus_float_t Daub35[70] = { 4.06793406114e-06, 9.42146947557e-05, 1.01912268037e-03, 6.80729288431e-03, 3.12362885114e-02, 1.03404455861e-01, 2.51307378994e-01, 4.43592739224e-01, 5.37008427509e-01, 3.60345640518e-01,-4.38838818739e-02,-3.23822864912e-01,-1.81786976766e-01, 1.66041357490e-01, 2.17299289321e-01,-6.52628713106e-02,-1.91919589298e-01, 1.93095446660e-02, 1.55292480396e-01,-4.75268083411e-03,-1.20585522643e-01, 4.73422917264e-03, 8.99135475707e-02,-9.31855894990e-03,-6.33560374404e-02, 1.32285495850e-02, 4.12546930647e-02,-1.43668397842e-02,-2.41694978016e-02, 1.27664567156e-02, 1.22894360081e-02,-9.57779789923e-03,-5.08599164923e-03, 6.13775458674e-03, 1.42808879407e-03,-3.35764438092e-03, 7.61596943517e-06, 1.54963746970e-03,-3.34669216425e-04,-5.86481031899e-04, 2.64832881996e-04, 1.70001228366e-04,-1.36588307226e-04,-2.97699596284e-05, 5.30414312291e-05,-2.43700152682e-06,-1.57244207727e-05, 4.30804786171e-06, 3.35334586287e-06,-1.89592961769e-06,-3.90393173328e-07, 5.30236861690e-07,-3.70030837820e-08,-9.99039694453e-08, 3.00818865071e-08, 1.08490273378e-08,-7.45811655289e-09, 5.89795131038e-11, 1.03082334548e-09,-2.43354557375e-10,-6.40793825650e-11, 4.00053662725e-11,-3.12563935710e-12,-2.56706547615e-12, 8.01508853368e-13,-2.59795432889e-14,-3.39772085679e-14, 8.62403743472e-15,-9.29801252932e-16, 4.01462871233e-17}; static mus_float_t Daub36[72] = { 2.86792518275e-06, 6.82602867854e-05, 7.60215109966e-04, 5.24029737740e-03, 2.48905656448e-02, 8.56520925952e-02, 2.17756953097e-01, 4.06433697708e-01, 5.32266895260e-01, 4.17875335600e-01, 4.39751975293e-02,-2.94421039589e-01,-2.46807036978e-01, 9.81142041631e-02, 2.46537277608e-01, 7.27851509579e-03,-1.99337205608e-01,-4.58614007463e-02, 1.54106236627e-01, 5.02761800735e-02,-1.18803754310e-01,-3.98808535755e-02, 9.11567822580e-02, 2.50387214495e-02,-6.82090166368e-02,-1.13191003168e-02, 4.85130835478e-02, 1.42497266176e-03,-3.19807206776e-02, 3.98404019871e-03, 1.90635947806e-02,-5.65781324505e-03,-9.99026347328e-03, 5.02298910666e-03, 4.41348483535e-03,-3.48454144540e-03,-1.50307406629e-03, 1.99079377185e-03, 2.77681279571e-04,-9.46340382326e-04, 8.61456575899e-05, 3.69350728496e-04,-1.15511889584e-04,-1.13189946808e-04, 6.69474119693e-05, 2.37510668366e-05,-2.73139082465e-05,-1.18347105998e-06, 8.37221819816e-06,-1.58614578243e-06,-1.87081160285e-06, 8.31142127970e-07, 2.54842352255e-07,-2.45537765843e-07, 2.75324907333e-09, 4.79904346545e-08,-1.15609368881e-08,-5.61278434332e-09, 3.13884169578e-09, 1.09081555371e-10,-4.51254577856e-10, 8.96241820385e-11, 3.03742909811e-11,-1.59971668926e-11, 8.87684628721e-13, 1.07096935711e-12,-3.02928502697e-13, 5.54226318263e-15, 1.33807138629e-14,-3.20462854340e-15, 3.33997198481e-16,-1.40327417537e-17}; static mus_float_t Daub37[74] = { 2.02206086249e-06, 4.94234375062e-05, 5.66241837706e-04, 4.02414036825e-03, 1.97622861538e-02, 7.05848259771e-02, 1.87326331862e-01, 3.68440972400e-01, 5.18167040855e-01, 4.62207553661e-01, 1.30878963233e-01,-2.46180429761e-01,-2.94375915262e-01, 1.96715004523e-02, 2.51523254360e-01, 8.18060283872e-02,-1.81962291778e-01,-1.08451713823e-01, 1.29929646959e-01, 1.01780296838e-01,-9.66075406166e-02,-8.23302119065e-02, 7.50476199483e-02, 5.95674108715e-02,-5.92568156326e-02,-3.82538294793e-02, 4.58079441512e-02, 2.09728005925e-02,-3.35235840641e-02,-8.83349389041e-03, 2.26186515445e-02, 1.69047238348e-03,-1.37639819628e-02, 1.51930577883e-03, 7.38775745285e-03,-2.24805318700e-03,-3.39452327640e-03, 1.81687134380e-03, 1.26393425811e-03,-1.11148486531e-03,-3.28078847088e-04, 5.49053277337e-04, 1.53443902319e-05,-2.20894403245e-04, 4.33672612594e-05, 7.05513878206e-05,-3.09866292761e-05,-1.63916249616e-05, 1.35432771841e-05, 1.84994500311e-06,-4.30994155659e-06, 4.85473139699e-07, 1.00212139929e-06,-3.49494860344e-07,-1.50988538867e-07, 1.10903123221e-07, 5.35065751546e-09,-2.25219383672e-08, 4.22448570636e-09, 2.79397446595e-09,-1.29720500146e-09,-1.03141112909e-10, 1.94616489408e-10,-3.20339824412e-11,-1.39841571553e-11, 6.33495544097e-12,-2.09636319423e-13,-4.42161240987e-13, 1.13805283092e-13,-4.51888960746e-16,-5.24302569188e-15, 1.18901238750e-15,-1.19928033585e-16, 4.90661506493e-18}; static mus_float_t Daub38[76] = { 1.42577664167e-06, 3.57625199426e-05, 4.21170266472e-04, 3.08308811925e-03, 1.56372493475e-02, 5.78899436128e-02, 1.60071993564e-01, 3.30775781411e-01, 4.96591175311e-01, 4.93356078517e-01, 2.13050571355e-01,-1.82867667708e-01,-3.21675637808e-01,-6.22665060478e-02, 2.32125963835e-01, 1.49985119618e-01,-1.41795685973e-01,-1.59912565158e-01, 8.56381215561e-02, 1.41414734073e-01,-5.65864586307e-02,-1.14731170710e-01, 4.30958954330e-02, 8.72043982620e-02,-3.66051034028e-02,-6.17662087084e-02, 3.19898775315e-02, 4.00549811051e-02,-2.68914938808e-02,-2.31141340205e-02, 2.09046452556e-02, 1.12904972786e-02,-1.47018820653e-02,-4.13130665603e-03, 9.21478503219e-03, 5.62571574840e-04,-5.07131450921e-03, 7.16982182106e-04, 2.40069778189e-03,-8.44862666553e-04,-9.42461407722e-04, 5.81075975053e-04, 2.81763925038e-04,-3.03102046072e-04,-4.55568269666e-05, 1.26204335016e-04,-1.15540910383e-05,-4.17514164854e-05, 1.33417614992e-05, 1.03735918404e-05,-6.45673042846e-06,-1.55084435011e-06, 2.14996026993e-06,-8.48708758607e-08,-5.18773373887e-07, 1.39637754550e-07, 8.40035104689e-08,-4.88475793745e-08,-5.42427480028e-09, 1.03470453927e-08,-1.43632948779e-09,-1.34919775398e-09, 5.26113255735e-10, 6.73233649018e-11,-8.27825652253e-11, 1.10169293459e-11, 6.29153731703e-12,-2.48478923756e-12, 2.62649650406e-14, 1.80866123627e-13,-4.24981781957e-14,-4.56339716212e-16, 2.04509967678e-15,-4.40530704248e-16, 4.30459683955e-17,-1.71615245108e-18}; static mus_float_t Battle_Lemarie[24] = {-0.0028284274, -0.004242641, 0.008485282, 0.008485282, -0.018384777, -0.016970564, 0.042426407, 0.032526914, -0.11030867, -0.049497478, 0.4341636, 0.7665038, 0.4341636, -0.049497478, -0.11030867, 0.032526914, 0.042426407, -0.016970564, -0.018384777, 0.008485282, 0.008485282, -0.004242641, -0.0028284274, 0.0}; static mus_float_t Burt_Adelson[6] = {-0.07071068, 0.3535534, 0.8485282, 0.3535534, -0.07071068, 0.0}; static mus_float_t Beylkin[18] = {0.099305765374353, 0.424215360812961, 0.699825214056600, 0.449718251149468, -.110927598348234, -.264497231446384, 0.026900308803690, 0.155538731877093, -.017520746266529, -.088543630622924, 0.019679866044322, 0.042916387274192, -.017460408696028, -.014365807968852, 0.010040411844631, .0014842347824723, -.002736031626258, .0006404853285212}; static mus_float_t coif2[6] = {0.038580775, -0.12696913, -0.07716155, 0.6074917, 0.74568766, 0.2265843}; static mus_float_t coif4[12] = {0.0011945726958388, -0.01284557955324, 0.024804330519353, 0.050023519962135, -0.15535722285996, -0.071638282295294, 0.57046500145033, 0.75033630585287, 0.28061165190244, -0.0074103835186718, -0.014611552521451, -0.0013587990591632}; static mus_float_t coif6[18] = {-0.0016918510194918, -0.00348787621998426, 0.019191160680044, 0.021671094636352, -0.098507213321468, -0.056997424478478, 0.45678712217269, 0.78931940900416, 0.38055713085151, -0.070438748794943, -0.056514193868065, 0.036409962612716, 0.0087601307091635, -0.011194759273835, -0.0019213354141368, 0.0020413809772660, 0.00044583039753204, -0.00021625727664696}; static mus_float_t sym2[5] = {-0.1767767, 0.3535534, 1.0606602, 0.3535534, -0.1767767}; static mus_float_t sym3[4] = {0.1767767, 0.5303301, 0.5303301, 0.1767767}; static mus_float_t sym4[10] = {0.033145633, -0.066291265, -0.1767767, 0.4198447, 0.994369, 0.4198447, -0.1767767, -0.066291265, 0.033145633, 0.0}; static mus_float_t sym5[8] = {0.066291265, -0.19887379, -0.15467963, 0.994369, 0.994369, -0.15467963, -0.19887379, 0.066291265}; static mus_float_t sym6[16] = {-0.0030210863, -0.009063259, -0.016831767, 0.07466399, 0.03133298, -0.30115914, -0.026499243, 0.9516422, 0.9516422, -0.026499243, -0.30115914, 0.03133298, 0.07466399, -0.016831767, -0.009063259, -0.0030210863}; static const char *wavelet_names_1[NUM_WAVELETS] = {"daub4", "daub6", "daub8", "daub10", "daub12", "daub14", "daub16", "daub18", "daub20", "battle-lemarie", "burt-adelson", "beylkin", "coif2", "coif4", "coif6", "sym2", "sym3", "sym4", "sym5", "sym6", "daub22", "daub24", "daub26", "daub28", "daub30", "daub32", "daub34", "daub36", "daub38", "daub40", "daub42", "daub44", "daub46", "daub48", "daub50", "daub52", "daub54", "daub56", "daub58", "daub60", "daub62", "daub64", "daub66", "daub68", "daub70", "daub72", "daub74", "daub76"}; static int wavelet_sizes[NUM_WAVELETS] = {4, 6, 8, 10, 12, 14, 16, 18, 20, 24, 6, 18, 6, 12, 18, 5, 4, 10, 8, 16, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76}; static mus_float_t *wavelet_data[NUM_WAVELETS] = {Daub2, Daub3, Daub4, Daub5, Daub6, Daub7, Daub8, Daub9, Daub10, Battle_Lemarie, Burt_Adelson, Beylkin, coif2, coif4, coif6, sym2, sym3, sym4, sym5, sym6, Daub11, Daub12, Daub13, Daub14, Daub15, Daub16, Daub17, Daub18, Daub19, Daub20, Daub21, Daub22, Daub23, Daub24, Daub25, Daub26, Daub27, Daub28, Daub29, Daub30, Daub31, Daub32, Daub33, Daub34, Daub35, Daub36, Daub37, Daub38}; const char *wavelet_name(int i) {return(wavelet_names_1[i]);} const char **wavelet_names(void) {return(wavelet_names_1);} /* -------------------------------- HAAR TRANSFORM -------------------------------- */ /* * from fxt/haar/haar.cc */ static void haar_transform(mus_float_t *f, mus_long_t n) { mus_long_t m, i, j, k; mus_float_t s2; mus_float_t v = 1.0; mus_float_t x, y; mus_float_t *g; s2 = sqrt(0.5); g = (mus_float_t *)calloc(n, sizeof(mus_float_t)); for (m = n; m > 1; m >>= 1) { mus_long_t mh; v *= s2; mh = (m >> 1); for (j = 0, k = 0; j < m; j += 2, k++) { x = f[j]; y = f[j + 1]; g[k] = x + y; g[mh + k] = (x - y) * v; } for (i = m - 1; i >= 0; i--) f[i] = g[i]; } f[0] *= v; free(g); } /* -------------------------------- WALSH TRANSFORM -------------------------------- */ /* borrowed from walsh/walshdit2.cc in the fxt package fxt970929.tgz written by (and copyright) Joerg Arndt * arndt@spektracom.de, arndt@jjj.de, http://www.spektracom.de/~arndt/joerg.html, http://www.jjj.de/fxt/ * fxt.doc appears to say I can use it here (Snd is freeware and I've modified the original to some extent). */ static void walsh_transform(mus_float_t *data, mus_long_t n) { int i, ipow; ipow = (int)((log(n) / log(2)) + .0001); /* added fudge factor 21-Sep-01 -- (int)3.0000 = 2 on PC */ for (i = ipow; i >= 1; --i) { mus_long_t r, m, mh, t1, t2; m = (1 << i); mh = (m >> 1); for (r = 0; r < n; r += m) { int j; for (j = 0, t1 = r, t2 = r + mh; j < mh; ++j, ++t1, ++t2) { mus_float_t u, v; u = data[t1]; v = data[t2]; data[t1] = u + v; data[t2] = u - v; } } } } static int compare_peaks(const void *pk1, const void *pk2) { if (((fft_peak *)pk1)->freq > ((fft_peak *)pk2)->freq) return(1); if (((fft_peak *)pk1)->freq == ((fft_peak *)pk2)->freq) return(0); return(-1); } int find_and_sort_peaks(mus_float_t *buf, fft_peak *found, int num_peaks, mus_long_t losamp, mus_long_t hisamp) { /* in the fft peak finder below we assume data between 0 and 1 */ /* this procedure is for the list graph -- see below for fft */ mus_long_t i, j; int pks, minpk; mus_float_t minval, la, ra, ca; mus_float_t *peaks; mus_long_t *inds; if (num_peaks <= 0) return(0); peaks = (mus_float_t *)calloc(num_peaks, sizeof(mus_float_t)); inds = (mus_long_t *)calloc(num_peaks, sizeof(mus_long_t)); pks = 0; la = 0.0; ca = 0.0; ra = 0.0; minval = 0.00001; for (i = losamp; i < hisamp; i++) { la = ca; ca = ra; ra = buf[i]; if ((ca > minval) && (ca > ra) && (ca > la)) { if (pks < num_peaks) { inds[pks] = i - 1; peaks[pks++] = ca; } else { minval = peaks[0]; minpk = 0; for (j = 1; j < num_peaks; j++) if (peaks[j] < minval) { minval = peaks[j]; minpk = j; } if (ca > minval) { inds[minpk] = i - 1; peaks[minpk] = ca; } } } } for (i = 0; i < pks; i++) { j = inds[i]; found[i].amp = buf[j]; found[i].freq = (mus_float_t)j; } if (pks > 0) qsort((void *)found, pks, sizeof(fft_peak), compare_peaks); free(peaks); free(inds); return(pks); } #define MIN_CHECK 0.000001 int find_and_sort_transform_peaks(mus_float_t *buf, fft_peak *found, int num_peaks, mus_long_t losamp, mus_long_t hisamp, mus_float_t samps_per_pixel, mus_float_t fft_scale) { /* we want to reflect the graph as displayed, so each "bin" is samps_per_pixel wide */ mus_long_t i, j, k, hop, pkj; int pks, minpk; mus_float_t minval, la, ra, ca, logca, logra, logla, offset, fscl, ascl, bscl, fftsize2; mus_float_t *peaks; mus_long_t *inds; fftsize2 = (mus_float_t)hisamp; peaks = (mus_float_t *)calloc(num_peaks, sizeof(mus_float_t)); inds = (mus_long_t *)calloc(num_peaks, sizeof(mus_long_t)); fscl = 1.0 / fftsize2; hop = (mus_long_t)(samps_per_pixel + 0.5); if (hop < 1) hop = 1; pks = 0; la = 0.0; ca = 0.0; ra = 0.0; minval = 0.0; ascl = 0.0; pkj = 0; for (i = losamp; i < hisamp - hop; i += hop) { mus_long_t oldpkj; la = ca; ca = ra; oldpkj = pkj; ra = 0.0; for (k = 0; k < hop; k++) if (buf[i + k] > ra) { pkj = i + k; ra = buf[pkj]; /* reflect user's view of the graph */ } if ((ca > minval) && (ca > ra) && (ca > la)) { if (ascl < ca) ascl = ca; if (pks < num_peaks) { inds[pks] = oldpkj; peaks[pks] = ca; pks++; } else { minval = peaks[0]; minpk = 0; for (j = 1; j < num_peaks; j++) { if (peaks[j] < minval) { minval = peaks[j]; minpk = j; } } if (ca > minval) { inds[minpk] = oldpkj; peaks[minpk] = ca; } } } } /* now we have the peaks; turn these into interpolated peaks/amps, and sort */ if (ascl > 0.0) ascl = 1.0 / ascl; else ascl = 1.0; if (fft_scale > 0.0) bscl = fft_scale / ascl; else bscl = 1.0; for (i = 0, k = 0; i < pks; i++) { j = inds[i]; ca = buf[j] * ascl; if (j > 0) la = buf[j - 1] * ascl; else la = ca; ra = buf[j + 1] * ascl; if ((la < MIN_CHECK) || (ra < MIN_CHECK)) { found[k].amp = bscl * ca; found[k].freq = fscl * j; } else { logla = log10(la); logca = log10(ca); logra = log10(ra); offset = (0.5 * (logla - logra)) / (logla + logra - 2 * logca); /* this assumes amps < 1.0 (from XJS sms code) */ found[k].amp = bscl * pow(10.0, logca - 0.25 * offset * (logla - logra)); if ((found[k].amp > 1.0) && (fft_scale > 0.0)) found[k].amp = 1.0; found[k].freq = fscl * (j + offset); } if (found[k].freq < 0.0) found[k].freq = 0.0; if (found[k].amp > 0.0) k++; } for (i = k; i < num_peaks; i++) found[i].freq = 1.0; /* move blank case to end of sorted list */ qsort((void *)found, pks, sizeof(fft_peak), compare_peaks); free(peaks); free(inds); return(k); } static mus_float_t beta_maxes[MUS_NUM_FFT_WINDOWS] = {1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 15.0 /* kaiser */, 10.0, 10.0, 10.0, 1.0, 18.0 /* dolph */, 10.0, 1.0, 18.0 /* samaraki */, 18.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.24}; mus_float_t fft_beta_max(mus_fft_window_t win) {return(beta_maxes[(int)win]);} static const char *transform_type_names[NUM_BUILTIN_TRANSFORM_TYPES] = {"Fourier", "Wavelet", "Walsh", "Autocorrelate", "Cepstrum", "Haar"}; static const char *transform_type_program_names[NUM_BUILTIN_TRANSFORM_TYPES] = { S_fourier_transform, S_wavelet_transform, S_walsh_transform, S_autocorrelation, S_cepstrum, S_haar_transform}; typedef struct { char *name, *xlabel; mus_float_t lo, hi; Xen proc; int type, row, gc_loc; } added_transform; static added_transform **added_transforms = NULL; static int added_transforms_size = 0; static added_transform *new_transform(void) { int loc = -1; if (added_transforms == NULL) { loc = 0; added_transforms_size = 4; added_transforms = (added_transform **)calloc(added_transforms_size, sizeof(added_transform *)); } else { int i; for (i = 0; i < added_transforms_size; i++) if (added_transforms[i] == NULL) { loc = i; break; } if (loc == -1) { int i; loc = added_transforms_size; added_transforms_size += 4; added_transforms = (added_transform **)realloc(added_transforms, added_transforms_size * sizeof(added_transform *)); for (i = loc; i < added_transforms_size; i++) added_transforms[i] = NULL; } } added_transforms[loc] = (added_transform *)calloc(1, sizeof(added_transform)); added_transforms[loc]->type = loc + NUM_BUILTIN_TRANSFORM_TYPES; return(added_transforms[loc]); } static int add_transform(const char *name, const char *xlabel, mus_float_t lo, mus_float_t hi, Xen proc) { added_transform *af; af = new_transform(); af->name = mus_strdup(name); af->xlabel = mus_strdup(xlabel); af->lo = lo; af->hi = hi; af->proc = proc; af->gc_loc = snd_protect(proc); make_transform_type_list(); return(af->type); } static added_transform *type_to_transform(int type) { int loc; loc = type - NUM_BUILTIN_TRANSFORM_TYPES; if ((loc >= 0) && (loc < added_transforms_size)) return(added_transforms[loc]); return(NULL); } bool is_transform(int type) { if (type < 0) return(false); if (type < NUM_BUILTIN_TRANSFORM_TYPES) return(true); return(type_to_transform(type) != NULL); } /* delete-transform would also need to remove its name from the various UI lists */ const char *transform_name(int type) { if (is_transform(type)) { added_transform *af; if (type < NUM_BUILTIN_TRANSFORM_TYPES) return(transform_type_names[type]); af = type_to_transform(type); return(af->name); } return("unknown"); } const char *transform_program_name(int type) { if (is_transform(type)) { added_transform *af; if (type < NUM_BUILTIN_TRANSFORM_TYPES) return(transform_type_program_names[type]); af = type_to_transform(type); return(af->name); } return("unknown"); } static const char *added_transform_xlabel(int type) { added_transform *af; af = type_to_transform(type); if (af) return(af->xlabel); return("unknown"); } static mus_float_t added_transform_lo(int type) { added_transform *af; af = type_to_transform(type); if (af) return(af->lo); return(0.0); } static mus_float_t added_transform_hi(int type) { added_transform *af; af = type_to_transform(type); if (af) return(af->hi); return(1.0); } static Xen added_transform_proc(int type) { added_transform *af; af = type_to_transform(type); if (af) return(af->proc); return(Xen_false); } void set_transform_position(int i, int j) { if (i >= NUM_BUILTIN_TRANSFORM_TYPES) { added_transform *af; af = type_to_transform(i); af->row = j; } } int max_transform_type(void) { return(NUM_BUILTIN_TRANSFORM_TYPES + added_transforms_size); } int transform_type_to_position(int type) { added_transform *af; if (type < NUM_BUILTIN_TRANSFORM_TYPES) return(type); af = type_to_transform(type); if (af) return(af->row); return(-1); } int transform_position_to_type(int pos) { int i; if (pos < NUM_BUILTIN_TRANSFORM_TYPES) return(pos); for (i = 0; i < added_transforms_size; i++) { added_transform *af; af = added_transforms[i]; if ((af) && (af->row = pos)) return(af->type); } return(-1); } static const char *spectro_xlabel(chan_info *cp) { switch (cp->transform_type) { case FOURIER: if (cp->fft_log_frequency) return("log freq"); else return("frequency"); break; case WAVELET: return(wavelet_names_1[cp->wavelet_type]); break; case HAAR: return("Haar spectrum"); break; case CEPSTRUM: return("cepstrum"); break; /* "quefrency" is the jokey name */ case WALSH: return("Sequency"); break; case AUTOCORRELATION: return("Lag time"); break; default: return(added_transform_xlabel(cp->transform_type)); break; } return(NULL); } static void make_sonogram_axes(chan_info *cp) { fft_info *fp; fp = cp->fft; if (fp) { axis_info *ap; mus_float_t max_freq, min_freq, yang; ap = cp->axis; if (cp->transform_type == FOURIER) { max_freq = cp->spectrum_end * (mus_float_t)snd_srate(cp->sound) * 0.5; if ((cp->fft_log_frequency) && ((snd_srate(cp->sound) * 0.5 * cp->spectrum_start) < log_freq_start(ss))) min_freq = log_freq_start(ss); else min_freq = cp->spectrum_start * (mus_float_t)snd_srate(cp->sound) * 0.5; } else { if ((cp->transform_type == AUTOCORRELATION) || (cp->transform_type == CEPSTRUM)) { max_freq = fp->current_size * cp->spectrum_end / 2; min_freq = fp->current_size * cp->spectrum_start / 2; } else { max_freq = fp->current_size * cp->spectrum_end; min_freq = fp->current_size * cp->spectrum_start; } } yang = fmod(cp->spectro_y_angle, 360.0); if (yang < 0.0) yang += 360.0; if (cp->transform_graph_type == GRAPH_AS_SPECTROGRAM) { const char *xlabel; if (cp->transform_type == FOURIER) { if (yang < 45.0) xlabel = "frequency"; else if (yang < 135.0) xlabel = "time"; else if (yang < 225.0) xlabel = "wavelength?"; else if (yang < 315.0) xlabel = "reversed time?"; else xlabel = "frequency"; } else xlabel = spectro_xlabel(cp); fp->axis = make_axis_info(cp, min_freq, max_freq, ap->x0, ap->x1, xlabel, min_freq, max_freq, ap->x0, ap->x1, fp->axis); } else { if (fp->xlabel == NULL) fp->xlabel = mus_strdup("time"); fp->axis = make_axis_info(cp, ap->x0, ap->x1, min_freq, max_freq, fp->xlabel, ap->x0, ap->x1, min_freq, max_freq, fp->axis); } } } typedef struct fft_state { mus_long_t size; mus_fft_window_t wintype; graph_type_t graph_type; bool done; chan_info *cp; mus_float_t *window; mus_float_t *data; mus_float_t alpha, beta; int wavelet_choice, transform_type; mus_long_t beg, databeg, datalen; mus_long_t losamp; int edit_ctr; bool dBing, lfreq, with_phases; int pad_zero; mus_float_t cutoff; } fft_state; static mus_float_t *fs_idata = NULL; static mus_long_t fs_idata_size = 0; void fourier_spectrum(snd_fd *sf, mus_float_t *fft_data, mus_long_t fft_size, mus_long_t data_len, mus_float_t *window, chan_info *cp) { mus_long_t i, j, lim; if (window) { for (i = 0; i < data_len; i++) fft_data[i] = window[i] * read_sample(sf); } else { for (i = 0; i < data_len; i++) fft_data[i] = read_sample(sf); } if (data_len < fft_size) memset((void *)(fft_data + data_len), 0, (fft_size - data_len) * sizeof(mus_float_t)); if (fft_size <= fs_idata_size) memset((void *)fs_idata, 0, fft_size * sizeof(mus_float_t)); else { if (!fs_idata) fs_idata = (mus_float_t *)malloc(fft_size * sizeof(mus_float_t)); else fs_idata = (mus_float_t *)realloc(fs_idata, fft_size * sizeof(mus_float_t)); memset((void *)fs_idata, 0, fft_size * sizeof(mus_float_t)); fs_idata_size = fft_size; } mus_fft(fft_data, fs_idata, fft_size, 1); lim = fft_size / 2; if ((cp) && (cp->fft_with_phases)) { fft_data[0] = hypot(fft_data[0], fs_idata[0]); cp->fft->phases[0] = -atan2(fs_idata[0], fft_data[0]); for (i = 1, j = fft_size - 1; i < lim; i++, j--) { fft_data[i] = hypot(fft_data[i], fs_idata[i]); fft_data[j] = fft_data[i]; cp->fft->phases[i] = -atan2(fs_idata[i], fft_data[i]); cp->fft->phases[j] = -cp->fft->phases[i]; } } else { fft_data[0] = hypot(fft_data[0], fs_idata[0]); for (i = 1, j = fft_size - 1; i < lim; i++, j--) { fft_data[i] = hypot(fft_data[i], fs_idata[i]); fft_data[j] = fft_data[i]; } } if (fs_idata_size >= 4194304) { free(fs_idata); fs_idata = NULL; fs_idata_size = 0; } } static Xen before_transform_hook; static void apply_fft(fft_state *fs) { mus_long_t i, ind0, data_len; mus_float_t *fft_data; snd_fd *sf; chan_info *cp; cp = fs->cp; fft_data = fs->data; data_len = cp->transform_size; if ((show_selection_transform(ss)) && (selection_is_active_in_channel(cp)) && (fs->datalen > 0)) { ind0 = fs->databeg; if (cp->transform_graph_type == GRAPH_ONCE) data_len = fs->datalen; } else { if (Xen_hook_has_list(before_transform_hook)) { Xen res; res = run_progn_hook(before_transform_hook, Xen_list_2(C_int_to_Xen_sound(cp->sound->index), C_int_to_Xen_integer(cp->chan)), S_before_transform_hook); if (Xen_is_llong(res)) ind0 = Xen_llong_to_C_llong(res) + fs->beg; else ind0 = cp->axis->losamp + fs->beg; } else ind0 = cp->axis->losamp + fs->beg; } if (data_len > fs->size) data_len = fs->size; sf = init_sample_read(ind0, cp, READ_FORWARD); if (sf == NULL) return; switch (cp->transform_type) { case FOURIER: fourier_spectrum(sf, fft_data, fs->size, data_len, fs->window, cp); break; case WAVELET: for (i = 0; i < data_len; i++) fft_data[i] = read_sample(sf); if (data_len < fs->size) memset((void *)(fft_data + data_len), 0, (fs->size - data_len) * sizeof(mus_float_t)); wavelet_transform(fft_data, fs->size, wavelet_data[cp->wavelet_type], wavelet_sizes[cp->wavelet_type]); break; case HAAR: for (i = 0; i < data_len; i++) fft_data[i] = read_sample(sf); if (data_len < fs->size) memset((void *)(fft_data + data_len), 0, (fs->size - data_len) * sizeof(mus_float_t)); haar_transform(fft_data, fs->size); break; case CEPSTRUM: for (i = 0; i < data_len; i++) fft_data[i] = read_sample(sf); if (data_len < fs->size) memset((void *)(fft_data + data_len), 0, (fs->size - data_len) * sizeof(mus_float_t)); mus_cepstrum(fft_data, fs->size); break; case WALSH: for (i = 0; i < data_len; i++) fft_data[i] = read_sample(sf); if (data_len < fs->size) memset((void *)(fft_data + data_len), 0, (fs->size - data_len) * sizeof(mus_float_t)); walsh_transform(fft_data, fs->size); break; case AUTOCORRELATION: for (i = 0; i < data_len; i++) fft_data[i] = read_sample(sf); if (data_len < fs->size) memset((void *)(fft_data + data_len), 0, (fs->size - data_len) * sizeof(mus_float_t)); mus_autocorrelate(fft_data, fs->size); break; default: { Xen res, sfd; int gc_loc, sf_loc; sfd = g_c_make_sampler(sf); sf_loc = snd_protect(sfd); res = Xen_call_with_2_args(added_transform_proc(cp->transform_type), C_llong_to_Xen_llong(data_len), sfd, "added transform func"); gc_loc = snd_protect(res); if (mus_is_vct(res)) { vct *v; mus_long_t len; v = Xen_to_vct(res); len = mus_vct_length(v); memcpy((void *)fft_data, (void *)(mus_vct_data(v)), len * sizeof(mus_float_t)); } snd_unprotect_at(gc_loc); snd_unprotect_at(sf_loc); free_snd_fd_almost(sf); return; } break; } free_snd_fd(sf); } static void display_fft(fft_state *fs) { fft_info *fp; chan_info *cp; mus_float_t max_freq = 0.0, min_freq = 0.0, max_val, min_val, data_max = 0.0, scale = 1.0; const char *xlabel; fft_info *nfp; mus_float_t *data, *tdata; chan_info *ncp; snd_info *sp; mus_long_t i, lo, hi; cp = fs->cp; if ((cp == NULL) || (cp->active < CHANNEL_HAS_AXES)) return; if (cp->transform_graph_type != GRAPH_ONCE) return; fp = cp->fft; if (fp == NULL) return; /* can happen if selection transform set, but no selection */ data = fp->data; if (data == NULL) return; sp = cp->sound; if (fp->xlabel == NULL) xlabel = spectro_xlabel(cp); else xlabel = fp->xlabel; /* this only works until the fft data is remade in some way, then the label reverts to "frequency" */ switch (cp->transform_type) { case FOURIER: max_freq = ((mus_float_t)(snd_srate(sp)) * 0.5 * cp->spectrum_end); if ((cp->fft_log_frequency) && ((snd_srate(sp) * 0.5 * cp->spectrum_start) < log_freq_start(ss))) min_freq = log_freq_start(ss); else min_freq = ((mus_float_t)(snd_srate(sp)) * 0.5 * cp->spectrum_start); break; case WAVELET: case WALSH: case HAAR: max_freq = fs->size * cp->spectrum_end; min_freq = fs->size * cp->spectrum_start; break; case AUTOCORRELATION: case CEPSTRUM: max_freq = fs->size * cp->spectrum_end / 2; min_freq = fs->size * cp->spectrum_start / 2; break; default: min_freq = added_transform_lo(cp->transform_type) * fs->size * cp->spectrum_end; max_freq = added_transform_hi(cp->transform_type) * fs->size * cp->spectrum_end; break; } if (cp->transform_normalization == DONT_NORMALIZE) { lo = 0; hi = (int)(fp->current_size / 2); } else { if (cp->transform_type == FOURIER) { hi = (int)(fs->size * cp->spectrum_end / 2); lo = (int)(fs->size * cp->spectrum_start / 2); } else { hi = (int)(fs->size * cp->spectrum_end); lo = (int)(fs->size * cp->spectrum_start); } } data_max = 0.0; if ((cp->transform_normalization == NORMALIZE_BY_SOUND) || ((cp->transform_normalization == DONT_NORMALIZE) && (sp->nchans > 1) && (sp->channel_style == CHANNELS_SUPERIMPOSED))) { int j; for (j = 0; j < sp->nchans; j++) { ncp = sp->chans[j]; if ((ncp->graph_transform_on) && (ncp->fft)) /* normalize-by-sound but not ffting all chans? */ { nfp = ncp->fft; tdata = nfp->data; for (i = lo; i < hi; i++) if (tdata[i] > data_max) data_max = tdata[i]; } } } else { if (cp->transform_type == FOURIER) { for (i = lo; i < hi; i++) if (data[i] > data_max) data_max = data[i]; } else { for (i = lo; i < hi; i++) { if (data[i] > data_max) data_max = data[i]; else if (data[i] < -data_max) data_max = -data[i]; } } } if (data_max == 0.0) data_max = 1.0; if (cp->transform_normalization != DONT_NORMALIZE) scale = 1.0 / data_max; else { if (cp->transform_type == FOURIER) { int di; scale = 2.0 / (mus_float_t)(fs->size); di = (int)(10 * data_max * scale + 1); if (di == 1) { di = (int)(100 * data_max * scale + 1); if (di == 1) { di = (int)(1000 * data_max * scale + 1); data_max = (mus_float_t)di / 1000.0; } else data_max = (mus_float_t)di / 100.0; } else data_max = (mus_float_t)di / 10.0; } else { scale = 1.0; } } if (cp->fft_log_magnitude) { /* the DONT_NORMALIZE option is ignored because it really looks dumb in this context */ max_val = 0.0; min_val = cp->min_dB; } else { if (cp->transform_normalization == DONT_NORMALIZE) { if (cp->transform_type == FOURIER) min_val = 0.0; else min_val = -data_max; max_val = data_max; } else { if (cp->transform_type == FOURIER) min_val = 0.0; else min_val = -1.0; max_val = 1.0; } } fp->scale = scale; fp->axis = make_axis_info(cp, min_freq, max_freq, min_val, max_val, xlabel, min_freq, max_freq, min_val, max_val, fp->axis); } static fft_state *free_fft_state(fft_state *fs) { if (fs) { if (fs->window) {free(fs->window); fs->window = NULL;} free(fs); } return(NULL); } void cp_free_fft_state(chan_info *cp) { if (cp->fft_data) cp->fft_data = (fft_state *)free_fft_state(cp->fft_data); } bool fft_window_beta_in_use(mus_fft_window_t win) { return((win == MUS_KAISER_WINDOW) || (win == MUS_CAUCHY_WINDOW) || (win == MUS_POISSON_WINDOW) || (win == MUS_GAUSSIAN_WINDOW) || (win == MUS_TUKEY_WINDOW) || (win == MUS_DOLPH_CHEBYSHEV_WINDOW) || (win == MUS_HANN_POISSON_WINDOW) || (win == MUS_SAMARAKI_WINDOW) || (win == MUS_ULTRASPHERICAL_WINDOW) || (win == MUS_DPSS_WINDOW)); } bool fft_window_alpha_in_use(mus_fft_window_t win) { return(win == MUS_ULTRASPHERICAL_WINDOW); } static fft_state *make_fft_state(chan_info *cp, bool force_recalc) { fft_state *fs = NULL; axis_info *ap; bool reuse_old = false; mus_long_t fftsize; mus_long_t dbeg = 0, dlen = 0; ap = cp->axis; if ((show_selection_transform(ss)) && (cp->transform_graph_type == GRAPH_ONCE) && (selection_is_active_in_channel(cp))) { /* override transform_size(ss) in this case (sonograms cover selection but use preset size) */ dbeg = selection_beg(cp); dlen = selection_len(); /* these need to be handled at the same time, and not re-examined until the next call */ /* if we're sweeping the mouse defining the selection, by the time we get to apply_fft, selection_len() can change */ fftsize = snd_mus_long_t_pow2((int)ceil(log(dlen * (1 + cp->zero_pad) + 1) / log(2.0))); if (fftsize < 2) fftsize = 2; cp->selection_transform_size = fftsize; } else { if ((cp->zero_pad == 0) && (is_power_of_2(cp->transform_size))) fftsize = cp->transform_size; else fftsize = snd_mus_long_t_pow2((int)(ceil(log((mus_float_t)(cp->transform_size * (1 + cp->zero_pad))) / log(2.0)))); if (fftsize < 2) fftsize = 2; cp->selection_transform_size = 0; } if ((!force_recalc) && (cp->fft_data) && (cp->selection_transform_size == 0)) { fs = cp->fft_data; if ((fs->losamp == ap->losamp) && (!(Xen_hook_has_list(before_transform_hook))) && (fs->size == fftsize) && (fs->transform_type == cp->transform_type) && (fs->wintype == cp->fft_window) && ((!(fft_window_alpha_in_use(fs->wintype))) || (fs->alpha == cp->fft_window_alpha)) && ((!(fft_window_beta_in_use(fs->wintype))) || (fs->beta == cp->fft_window_beta)) && (fs->dBing == cp->fft_log_magnitude) && (fs->lfreq == cp->fft_log_frequency) && (fs->with_phases == cp->fft_with_phases) && (fs->pad_zero == cp->zero_pad) && (fs->cutoff == cp->spectrum_end) && (fs->graph_type == cp->transform_graph_type) && (fs->wavelet_choice == cp->wavelet_type) && (fs->edit_ctr == cp->edit_ctr)) reuse_old = true; } if (!reuse_old) { cp_free_fft_state(cp); fs = (fft_state *)calloc(1, sizeof(fft_state)); fs->cp = cp; fs->cutoff = cp->spectrum_end; fs->size = fftsize; fs->pad_zero = cp->zero_pad; fs->wintype = cp->fft_window; fs->dBing = cp->fft_log_magnitude; fs->lfreq = cp->fft_log_frequency; fs->with_phases = cp->fft_with_phases; fs->window = NULL; fs->losamp = ap->losamp; fs->edit_ctr = cp->edit_ctr; fs->wavelet_choice = cp->wavelet_type; fs->transform_type = cp->transform_type; fs->graph_type = cp->transform_graph_type; fs->alpha = cp->fft_window_alpha; fs->beta = cp->fft_window_beta; } fs->done = reuse_old; fs->beg = 0; /* offset from losamp */ fs->databeg = dbeg; fs->datalen = dlen; return(fs); } static fft_info *make_fft_info(mus_long_t size, mus_fft_window_t window, mus_float_t alpha, mus_float_t beta) { fft_info *fp; fp = (fft_info *)calloc(1, sizeof(fft_info)); fp->size = size; fp->window = window; fp->alpha = alpha; fp->beta = beta; fp->xlabel = NULL; fp->data = (mus_float_t *)calloc(size + 1, sizeof(mus_float_t)); /* + 1 for complex storage or starts at 1 or something */ fp->phases = NULL; return(fp); } void set_fft_info_xlabel(chan_info *cp, const char *new_label) { if ((cp) && (cp->fft)) { if (cp->fft->xlabel) free(cp->fft->xlabel); if (new_label) cp->fft->xlabel = mus_strdup(new_label); else cp->fft->xlabel = NULL; } } fft_info *free_fft_info(fft_info *fp) { fp->chan = NULL; if (fp->data) free(fp->data); if (fp->phases) free(fp->phases); if (fp->axis) free_axis_info(fp->axis); if (fp->xlabel) free(fp->xlabel); free(fp); return(NULL); } static void one_fft(fft_state *fs) { if (!fs->done) { /* allocate arrays if needed */ fft_info *fp; chan_info *cp; cp = fs->cp; fp = cp->fft; if (!fp) /* associated channel hasn't done any ffts yet, so there's no struct */ { cp->fft = make_fft_info(fs->size, fs->wintype, fs->alpha, fs->beta); fp = cp->fft; } else { if ((!fp->data) || (fs->size > fp->size)) { fp->size = fs->size; if (fp->data) free(fp->data); fp->data = (mus_float_t *)calloc(fp->size + 1, sizeof(mus_float_t)); if (fp->phases) free(fp->phases); fp->phases = NULL; } } if ((cp->fft_with_phases) && (!(fp->phases))) fp->phases = (mus_float_t *)calloc(fp->size + 1, sizeof(mus_float_t)); fp->current_size = fs->size; /* protect against parallel size change via fft size menu */ fs->data = fp->data; if (fs->window == NULL) { static mus_long_t last_size = 0; static int last_zero = 0; static mus_fft_window_t last_wintype = MUS_RECTANGULAR_WINDOW; static mus_float_t last_beta = 0.0; static mus_float_t last_alpha = 0.0; static mus_float_t *last_window = NULL; fs->window = (mus_float_t *)calloc(fs->size, sizeof(mus_float_t)); if ((fs->wintype != last_wintype) || (fs->size != last_size) || (fs->beta != last_beta) || (fs->alpha != last_alpha) || (fs->pad_zero != last_zero)) { if (last_window) free(last_window); last_window = (mus_float_t *)calloc(fs->size, sizeof(mus_float_t)); if (cp->selection_transform_size > 0) mus_make_fft_window_with_window(fs->wintype, cp->selection_transform_size, fs->beta * beta_maxes[fs->wintype], fs->alpha, last_window); else mus_make_fft_window_with_window(fs->wintype, cp->transform_size, fs->beta * beta_maxes[fs->wintype], fs->alpha, last_window); last_size = fs->size; last_alpha = fs->alpha; last_beta = fs->beta; last_wintype = fs->wintype; last_zero = fs->pad_zero; } memcpy(fs->window, (void *)last_window, fs->size * sizeof(mus_float_t)); } apply_fft(fs); } display_fft(fs); } void single_fft(chan_info *cp, bool update_display, bool force_recalc) { if (cp->transform_size < 2) return; cp->fft_data = make_fft_state(cp, force_recalc); one_fft(cp->fft_data); #if (!USE_GTK) if (update_display) display_channel_fft_data(cp); #else if (update_display) display_channel_data(cp); #endif } /* -------------------------------- GRAPH_AS_SONOGRAM -------------------------------- */ /* * calls calculate_fft for each slice, each bin being a gray-scaled rectangle in the display */ /* as we run the ffts, we need to save the fft data for subsequent redisplay/printing etc */ /* many of these can be running in parallel so the pointers can't be global */ /* this work proc calls a loop by pixels (hop depends on pixel/samps decision) each pixel(group) sets up the fft_state pointer with beg reflecting hop then loops, each time called, calling fft_in_slices until it returns true. then grab that data, update the channel display, look to see if we're behind the times, if so cleanup and exit, else jump back to outer loop. */ typedef enum {SONO_INIT, SONO_RUN, SONO_QUIT, SONO_DONE} sono_slice_t; typedef struct sonogram_state { sono_slice_t slice; int outlim, outer; fft_state *fs; chan_info *cp; int spectrum_size; sono_info *scp; mus_long_t beg, losamp, hisamp; bool done; double acc_hop, hop; mus_fft_window_t window; int msg_ctr; int edit_ctr; mus_float_t old_scale, alpha, beta; graph_type_t graph_type; int transform_type, w_choice; bool old_logxing; bool status_needs_to_be_cleared; bool force_recalc; } sonogram_state; void clear_transform_edit_ctrs(chan_info *cp) { if (cp->fft_data) { fft_state *fs; fs = cp->fft_data; fs->edit_ctr = -1; } if (cp->last_sonogram) { sonogram_state *lsg; lsg = (sonogram_state *)(cp->last_sonogram); lsg->edit_ctr = -1; } } void *make_sonogram_state(chan_info *cp, bool force_recalc) { sonogram_state *sg; fft_state *fs; sg = (sonogram_state *)calloc(1, sizeof(sonogram_state)); sg->cp = cp; sg->done = false; sg->force_recalc = force_recalc; fs = make_fft_state(cp, true); cp->fft_data = NULL; sg->fs = fs; sg->msg_ctr = 8; sg->transform_type = cp->transform_type; sg->w_choice = cp->wavelet_type; sg->status_needs_to_be_cleared = false; if (cp->temp_sonogram) { sonogram_state *temp_sg; /* we must have restarted fft process without letting the previous run at all */ temp_sg = (sonogram_state *)(cp->temp_sonogram); if (temp_sg->fs) temp_sg->fs = free_fft_state(temp_sg->fs); free(temp_sg); /* cp->last_sonogram = NULL; */ } cp->temp_sonogram = sg; /* background process may never run, so we need a way to find this pointer at cleanup time */ return((void *)sg); } void free_sonogram_fft_state(void *ptr) { sonogram_state *sg = (sonogram_state *)ptr; if (sg->fs) free_fft_state(sg->fs); sg->fs = NULL; } void free_sono_info(chan_info *cp) { sono_info *si; si = cp->sonogram_data; if (si) { if (si->begs) free(si->begs); if (si->data) { int i; for (i = 0; i < si->total_slices; i++) if (si->data[i]) free(si->data[i]); free(si->data); } free(si); cp->sonogram_data = NULL; } } static bool memory_is_available(mus_long_t slices, mus_long_t bins) { /* as far as I can tell, the approved way to make sure we can allocate enough memory is to allocate it... */ mus_long_t bytes_needed; /* "mus_long_t" throughout is vital here */ bytes_needed = (mus_long_t)(slices * (sizeof(mus_long_t) + sizeof(mus_float_t *))) + /* begs + pointer to each slice data */ (mus_long_t)(bins * slices * sizeof(mus_float_t)) + /* data for all the slices */ (mus_long_t)(bins * 2 * sizeof(double)); /* FFT space */ /* apparently Linux always returns a pointer, even when it will fail later, so we have to * touch the memory to find out if it's there; but this works only if we then try another alloc! * this is ridiculous... */ if (bytes_needed > 100000000) /* assume 100 MBytes is ok */ { char *check_alloc[10]; int i; mus_long_t bytes_needed_10; bytes_needed_10 = bytes_needed / 10; for (i = 0; i < 10; i++) { check_alloc[i] = (char *)malloc(bytes_needed_10); if (check_alloc[i] == NULL) { int j; snd_warning("can't allocate enough memory to run this set of FFTS: %lld bytes needed", bytes_needed); for (j = 0; j < i; j++) free(check_alloc[j]); return(false); } check_alloc[i][0] = ' '; /* touch it! */ } for (i = 0; i < 10; i++) free(check_alloc[i]); } return(true); } static sono_slice_t set_up_sonogram(sonogram_state *sg) { /* return SONO_RUN to go on, SONO_QUIT to quit early */ sono_info *si; axis_info *ap; chan_info *cp; sonogram_state *lsg = NULL; int i, dpys = 1; cp = sg->cp; if (cp->fft_changed != FFT_CHANGE_LOCKED) cp->fft_changed = FFT_UNCHANGED; else cp->fft_changed = FFT_CHANGED; if ((!(cp->graph_transform_on)) || (cp->transform_size <= 2)) return(SONO_QUIT); ap = cp->axis; sg->slice = SONO_INIT; sg->outer = 0; sg->beg = ap->losamp; sg->losamp = ap->losamp; sg->hisamp = ap->hisamp; sg->window = cp->fft_window; sg->alpha = cp->fft_window_alpha; sg->beta = cp->fft_window_beta; if (cp->graph_time_on) dpys++; if (cp->graph_lisp_on) dpys++; if (cp->transform_graph_type == GRAPH_AS_SPECTROGRAM) sg->outlim = ap->height / cp->spectro_hop; else sg->outlim = ap->window_width / dpys; if (sg->outlim <= 1) return(SONO_QUIT); /* sg->hop = (int)(ceil((double)(ap->hisamp - ap->losamp + 1) / (double)(sg->outlim))); */ /* this ^ old form causes a noticeable step in the zoom sequence when the hop value changes */ sg->hop = (double)(ap->hisamp - ap->losamp + 1) / (double)(sg->outlim); sg->acc_hop = 0.0; /* if fewer samps than pixels, draw rectangles */ if ((cp->transform_type == FOURIER) || (cp->transform_type == AUTOCORRELATION) || (cp->transform_type == CEPSTRUM)) sg->spectrum_size = sg->fs->size / 2; else sg->spectrum_size = sg->fs->size; if (sg->spectrum_size <= 0) return(SONO_QUIT); sg->edit_ctr = cp->edit_ctr; si = cp->sonogram_data; if (!si) { si = (sono_info *)calloc(1, sizeof(sono_info)); si->total_bins = sg->spectrum_size; si->total_slices = snd_to_int_pow2(sg->outlim); if (!memory_is_available((mus_long_t)(si->total_slices), (mus_long_t)(si->total_bins))) { free(si); return(SONO_QUIT); } cp->sonogram_data = si; si->begs = (mus_long_t *)calloc(si->total_slices, sizeof(mus_long_t)); si->data = (mus_float_t **)calloc(si->total_slices, sizeof(mus_float_t *)); for (i = 0; i < si->total_slices; i++) si->data[i] = (mus_float_t *)calloc(si->total_bins, sizeof(mus_float_t)); } else if ((si->total_slices < sg->outlim) || (si->total_bins < sg->spectrum_size)) { int tempsize; tempsize = snd_to_int_pow2(sg->outlim); if (!memory_is_available((mus_long_t)tempsize, (mus_long_t)(sg->spectrum_size))) return(SONO_QUIT); for (i = 0; i < si->total_slices; i++) if (si->data[i]) { free(si->data[i]); si->data[i] = NULL; } if (si->total_slices < tempsize) { si->total_slices = tempsize; free(si->data); si->begs = (mus_long_t *)realloc(si->begs, si->total_slices * sizeof(mus_long_t)); si->data = (mus_float_t **)calloc(si->total_slices, sizeof(mus_float_t *)); } if (si->total_bins < sg->spectrum_size) si->total_bins = sg->spectrum_size; for (i = 0; i < si->total_slices; i++) si->data[i] = (mus_float_t *)calloc(si->total_bins, sizeof(mus_float_t)); } sg->scp = si; si->target_bins = sg->spectrum_size; si->active_slices = 0; si->target_slices = sg->outlim; si->scale = 0.0; if ((!(sg->force_recalc)) && (cp->last_sonogram)) /* there was a previous run */ { lsg = (sonogram_state *)(cp->last_sonogram); if ((lsg->done) && /* it completed all ffts */ (lsg->outlim == sg->outlim) && /* the number of ffts is the same */ (lsg->spectrum_size == sg->spectrum_size) && /* ditto fft sizes [fs->size] */ (lsg->losamp == sg->losamp) && /* begins are same */ (lsg->hisamp == sg->hisamp) && /* ends are same */ (lsg->window == sg->window) && /* data windows are same [fs->wintype, cp->fft_window] */ (lsg->transform_type == sg->transform_type) && /* transform types are the same */ (lsg->w_choice == sg->w_choice) && /* wavelets are the same [cp->wavelet_type] */ (lsg->edit_ctr == sg->edit_ctr) && /* underlying data is the same */ ((!(fft_window_alpha_in_use(sg->window))) || (lsg->alpha == sg->alpha)) && ((!(fft_window_beta_in_use(sg->window))) || (lsg->beta == sg->beta))) { sg->outer = sg->outlim; /* fake up the run */ si->active_slices = si->target_slices; sg->old_scale = lsg->old_scale; si->scale = sg->old_scale; if ((lsg->graph_type != cp->transform_graph_type) || (lsg->old_logxing != cp->fft_log_frequency)) make_sonogram_axes(cp); /* may need to fixup frequency axis labels */ sg->graph_type = cp->transform_graph_type; sg->old_logxing = cp->fft_log_frequency; return(SONO_QUIT); /* so skip the ffts! */ } } cp->fft_changed = FFT_CHANGED; start_progress_report(cp); sg->status_needs_to_be_cleared = true; return(SONO_RUN); } static sono_slice_t run_all_ffts(sonogram_state *sg) { fft_state *fs; sono_info *si; chan_info *cp; axis_info *ap; /* check for losamp/hisamp change? */ one_fft((fft_state *)(sg->fs)); fs = sg->fs; cp = sg->cp; si = cp->sonogram_data; if (si->active_slices < si->total_slices) si->begs[si->active_slices] = sg->beg + fs->beg; sg->msg_ctr--; if (sg->msg_ctr == 0) { progress_report(cp, ((mus_float_t)(si->active_slices) / (mus_float_t)(si->target_slices))); sg->status_needs_to_be_cleared = true; sg->msg_ctr = 8; if ((!(cp->graph_transform_on)) || (cp->active < CHANNEL_HAS_AXES)) return(SONO_QUIT); } if (si->active_slices < si->total_slices) { int i; mus_float_t val; if (cp->transform_type == FOURIER) { for (i = 0; i < sg->spectrum_size; i++) { val = fs->data[i]; if (val > si->scale) si->scale = val; si->data[si->active_slices][i] = val; } } else { for (i = 0; i < sg->spectrum_size; i++) { val = fs->data[i]; if (val < 0.0) val = -val; /* kinda dubious but I can't think of a good alternative */ if (val > si->scale) si->scale = val; si->data[si->active_slices][i] = val; } } si->active_slices++; } sg->outer++; if ((sg->outer == sg->outlim) || (!(cp->graph_transform_on)) || (cp->transform_graph_type == GRAPH_ONCE)) return(SONO_QUIT); sg->acc_hop += sg->hop; fs->beg = (mus_long_t)(sg->acc_hop); ap = cp->axis; if ((sg->losamp != ap->losamp) || (sg->hisamp != ap->hisamp)) { fs->beg = 0; return(SONO_INIT); } return(SONO_RUN); } static void finish_sonogram(sonogram_state *sg) { if (sg) { chan_info *cp; cp = sg->cp; if ((cp->active < CHANNEL_HAS_AXES) || (!(cp->graph_transform_on))) { if (sg->fs) sg->fs = free_fft_state(sg->fs); } else { if ((sg->scp != NULL) && (sg->outlim > 1)) make_sonogram_axes(cp); if (sg->fs) sg->fs = free_fft_state(sg->fs); cp->fft_data = NULL; set_chan_fft_in_progress(cp, 0); /* i.e. clear it */ if ((sg->scp != NULL) && (sg->outlim > 1)) { display_channel_fft_data(cp); if (sg->outer == sg->outlim) sg->done = true; sg->old_scale = (sg->scp)->scale; } else sg->done = true; if ((cp->last_sonogram) && (cp->last_sonogram != sg)) free(cp->last_sonogram); cp->last_sonogram = sg; if (sg->status_needs_to_be_cleared) { finish_progress_report(cp); sg->status_needs_to_be_cleared = false; } } } } idle_func_t sonogram_in_slices(void *sono) { sonogram_state *sg = (sonogram_state *)sono; chan_info *cp; cp = sg->cp; cp->temp_sonogram = NULL; if ((cp->active < CHANNEL_HAS_AXES) || (!(cp->graph_transform_on))) { if ((sg) && (sg->fs)) sg->fs = free_fft_state(sg->fs); return(BACKGROUND_QUIT); } switch (sg->slice) { case SONO_INIT: sg->slice = set_up_sonogram(sg); break; case SONO_RUN: sg->slice = run_all_ffts(sg); break; case SONO_QUIT: default: finish_sonogram(sg); return(BACKGROUND_QUIT); break; } return(BACKGROUND_CONTINUE); } void sono_update(chan_info *cp) { if (cp->transform_graph_type != GRAPH_ONCE) make_sonogram_axes(cp); update_graph(cp); } static void spectral_multiply(mus_float_t *rl1, mus_float_t *rl2, mus_long_t n) { mus_long_t j, n2; mus_float_t invn; n2 = (int)(n * 0.5); invn = 0.25 / n; rl1[0] = ((rl1[0] * rl2[0]) / n); rl2[0] = 0.0; for (j = 1; j <= n2; j++) { mus_long_t nn2; mus_float_t rem, rep, aim, aip; nn2 = n - j; rep = (rl1[j] + rl1[nn2]); rem = (rl1[j] - rl1[nn2]); aip = (rl2[j] + rl2[nn2]); aim = (rl2[j] - rl2[nn2]); rl1[j] = invn * (rep * aip + aim * rem); rl1[nn2] = rl1[j]; rl2[j] = invn * (aim * aip - rep * rem); rl2[nn2] = -rl2[j]; } } void c_convolve(const char *fname, mus_float_t amp, int filec, mus_long_t filehdr, int filterc, mus_long_t filterhdr, mus_long_t filtersize, mus_long_t fftsize, int filter_chans, int filter_chan, mus_long_t data_size, snd_info *gsp) { int err; /* need file to hold convolution output */ err = mus_write_header(fname, MUS_NEXT, DEFAULT_OUTPUT_SRATE, 1, data_size * mus_bytes_per_sample(MUS_OUT_SAMPLE_TYPE), MUS_OUT_SAMPLE_TYPE, "c_convolve temp"); if (err != MUS_NO_ERROR) snd_error("can't open convolution temp file %s: %s", fname, snd_io_strerror()); else { mus_float_t *rl0 = NULL, *rl1 = NULL, *rl2 = NULL; mus_float_t **pbuffer = NULL, **fbuffer = NULL; mus_long_t oloc; oloc = mus_header_data_location(); /* get to start point in the two sound files and allocate space */ lseek(filec, filehdr, SEEK_SET); lseek(filterc, filterhdr, SEEK_SET); rl0 = (mus_float_t *)calloc(fftsize, sizeof(mus_float_t)); if (rl0) rl1 = (mus_float_t *)calloc(fftsize, sizeof(mus_float_t)); if (rl1) pbuffer = (mus_float_t **)calloc(1, sizeof(mus_float_t *)); if (pbuffer) pbuffer[0] = (mus_float_t *)calloc(data_size, sizeof(mus_float_t)); fbuffer = (mus_float_t **)calloc(filter_chans, sizeof(mus_float_t *)); if (fbuffer) fbuffer[filter_chan] = (mus_float_t *)calloc(filtersize, sizeof(mus_float_t)); if ((rl0 == NULL) || (rl1 == NULL) || (pbuffer == NULL) || (pbuffer[0] == NULL) || (fbuffer == NULL) || (fbuffer[filter_chan] == NULL)) { snd_error("not enough memory for convolve of %s (filter size: %lld, fft size: %lld)", fname, filtersize, fftsize); } else { mus_float_t *pbuf = NULL; mus_long_t i; int tempfile; chan_info *gcp; gcp = gsp->chans[0]; start_progress_report(gcp); tempfile = snd_reopen_write(fname); snd_file_open_descriptors(tempfile, fname, MUS_OUT_SAMPLE_TYPE, oloc, 1, MUS_NEXT); lseek(tempfile, oloc, SEEK_SET); /* read in the "impulse response" */ pbuf = pbuffer[0]; mus_file_read_any(filterc, 0, filter_chans, filtersize, fbuffer, fbuffer); for (i = 0; i < filtersize; i++) rl1[i] = fbuffer[filter_chan][i]; progress_report(gcp, .1); /* get the convolution data */ mus_file_read_any(filec, 0, 1, data_size, pbuffer, pbuffer); for (i = 0; i < data_size; i++) rl0[i] = pbuf[i]; progress_report(gcp, .3); mus_fft(rl0, rl1, fftsize, 1); progress_report(gcp, .5); spectral_multiply(rl0, rl1, fftsize); progress_report(gcp, .6); mus_fft(rl0, rl1, fftsize, -1); progress_report(gcp, .8); if (amp != 0.0) { mus_float_t scl; /* normalize the results */ scl = 0.0; for (i = 0; i < data_size; i++) { mus_float_t val; val = fabs(rl0[i]); if (val > scl) scl = val; } if (scl != 0.0) scl = amp / scl; for (i = 0; i < data_size; i++) pbuf[i] = (scl * rl0[i]); } else { /* amp == 0.0 means un-normalized output */ memcpy((void *)pbuf, (void *)rl0, data_size * sizeof(mus_float_t)); } progress_report(gcp, .9); /* and save as temp file */ mus_file_write(tempfile, 0, data_size - 1, 1, &(pbuf)); finish_progress_report(gcp); if (mus_file_close(tempfile) != 0) snd_error("convolve: can't close temp file %s!", fname); } if (rl0) free(rl0); if (rl1) free(rl1); if (rl2) free(rl2); if (pbuffer) { if (pbuffer[0]) free(pbuffer[0]); free(pbuffer); } if (fbuffer) { if (fbuffer[filter_chan]) free(fbuffer[filter_chan]); free(fbuffer); } } } /* -------------------------------------------------------------------------------- */ static void update_log_freq_fft_graph(chan_info *cp) { if ((cp->active < CHANNEL_HAS_AXES) || (cp->sounds == NULL) || (cp->sounds[cp->sound_ctr] == NULL) || (!(cp->graph_transform_on)) || (!(cp->fft_log_frequency)) || (chan_fft_in_progress(cp))) return; calculate_fft(cp); } void set_log_freq_start(mus_float_t base) { in_set_log_freq_start(base); for_each_chan(update_log_freq_fft_graph); } static Xen g_log_freq_start(void) {return(C_double_to_Xen_real(log_freq_start(ss)));} static Xen g_set_log_freq_start(Xen val) { mus_float_t base; #define H_log_freq_start "(" S_log_freq_start "): log freq base (default: 25.0)" Xen_check_type(Xen_is_number(val), val, 1, S_set S_log_freq_start, "a number"); base = Xen_real_to_C_double(val); if ((base < 0.0) || (base > 100000.0)) Xen_out_of_range_error(S_log_freq_start, 1, val, "base should be between 0 and srate/2"); set_log_freq_start(base); reflect_log_freq_start_in_transform_dialog(); return(C_double_to_Xen_real(log_freq_start(ss))); } static Xen g_show_selection_transform(void) {return(C_bool_to_Xen_boolean(show_selection_transform(ss)));} static Xen g_set_show_selection_transform(Xen val) { #define H_show_selection_transform "(" S_show_selection_transform "): " PROC_TRUE " if transform display reflects selection, not time-domain window" Xen_check_type(Xen_is_boolean(val), val, 1, S_set S_show_selection_transform, "a boolean"); set_show_selection_transform(Xen_boolean_to_C_bool(val)); return(C_bool_to_Xen_boolean(show_selection_transform(ss))); } static Xen g_transform_framples(Xen snd, Xen chn) { #define H_transform_framples "(" S_transform_framples " :optional snd chn): \ return a description of transform graph data in snd's channel chn, based on " S_transform_graph_type ".\ If there is no transform graph, return 0; if " S_graph_once ", return " S_transform_size ",\ and otherwise return a list (spectrum-cutoff time-slices fft-bins)" chan_info *cp; sono_info *si; Snd_assert_channel(S_transform_framples, snd, chn, 1); cp = get_cp(snd, chn, S_transform_framples); if (!cp) return(Xen_false); if (!(cp->graph_transform_on)) return(Xen_integer_zero); if (cp->transform_graph_type == GRAPH_ONCE) return(C_int_to_Xen_integer(cp->transform_size)); si = cp->sonogram_data; if (si) return(Xen_list_3(C_double_to_Xen_real(cp->spectrum_end), C_llong_to_Xen_llong(si->active_slices), C_llong_to_Xen_llong(si->target_bins))); return(Xen_integer_zero); } static Xen g_transform_sample(Xen bin, Xen slice, Xen snd, Xen chn_n) { #define H_transform_sample "(" S_transform_sample " :optional (bin 0) (slice 0) snd chn): \ return the current transform sample at bin and slice in snd channel chn (assuming sonogram or spectrogram)" chan_info *cp; Xen_check_type(Xen_is_llong_or_unbound(bin), bin, 1, S_transform_sample, "an integer"); Xen_check_type(Xen_is_llong_or_unbound(slice), slice, 2, S_transform_sample, "an integer"); Snd_assert_channel(S_transform_sample, snd, chn_n, 3); cp = get_cp(snd, chn_n, S_transform_sample); if (!cp) return(Xen_false); if (cp->graph_transform_on) { fft_info *fp; fp = cp->fft; if (fp) { mus_long_t fbin = 0; if (Xen_is_llong(bin)) fbin = Xen_llong_to_C_llong(bin); if (fbin < fp->current_size) { if (cp->transform_graph_type == GRAPH_ONCE) return(C_double_to_Xen_real(fp->data[fbin])); else { mus_long_t fslice = 0; sono_info *si; if (Xen_is_llong(slice)) fslice = Xen_llong_to_C_llong(slice); si = cp->sonogram_data; if ((si) && (fbin < si->target_bins) && (fslice < si->active_slices)) return(C_double_to_Xen_real(si->data[fslice][fbin])); else Xen_error(NO_SUCH_SAMPLE, Xen_list_8(C_string_to_Xen_string(S_transform_sample ": no such sample, bin: ~A, max bin: ~A, slice: ~A, max slice: ~A, sound index: ~A (~A), chan: ~A"), bin, C_int_to_Xen_integer((si) ? si->target_bins : 0), slice, C_int_to_Xen_integer((si) ? si->active_slices : 0), snd, C_string_to_Xen_string(cp->sound->short_filename), chn_n)); } } else Xen_error(NO_SUCH_SAMPLE, Xen_list_6(C_string_to_Xen_string(S_transform_sample ": no such sample, bin: ~A, max bin: ~A, sound index: ~A (~A), chan: ~A"), bin, C_int_to_Xen_integer(fp->current_size), snd, C_string_to_Xen_string(cp->sound->short_filename), chn_n)); } } return(Xen_false); } static Xen g_transform_to_vct(Xen snd, Xen chn_n, Xen v) { #define H_transform_to_vct "(" S_transform_to_vct " :optional snd chn obj): \ return a " S_vct " (obj if it's passed), with the current transform data from snd's channel chn" chan_info *cp; vct *v1; v1 = xen_to_vct(v); Snd_assert_channel(S_transform_to_vct, snd, chn_n, 1); cp = get_cp(snd, chn_n, S_transform_to_vct); if (!cp) return(Xen_false); if ((cp->graph_transform_on) && (cp->fft)) { mus_long_t len; mus_float_t *fvals; if (cp->transform_graph_type == GRAPH_ONCE) { fft_info *fp; fp = cp->fft; len = fp->current_size; if (v1) fvals = mus_vct_data(v1); else fvals = (mus_float_t *)malloc(len * sizeof(mus_float_t)); memcpy((void *)fvals, (void *)(fp->data), len * sizeof(mus_float_t)); if (v1) return(v); else return(xen_make_vct(len, fvals)); } else { sono_info *si; si = cp->sonogram_data; if (si) { int i, j, k, bins, slices; slices = si->active_slices; bins = si->target_bins; len = bins * slices; if (v1) fvals = mus_vct_data(v1); else fvals = (mus_float_t *)calloc(len, sizeof(mus_float_t)); for (i = 0, k = 0; i < slices; i++) for (j = 0; j < bins; j++, k++) fvals[k] = si->data[i][j]; if (v1) return(v); else return(xen_make_vct(len, fvals)); } } } return(Xen_false); } /* ---------------------------------------- transform objects ---------------------------------------- */ typedef struct { int n; } xen_transform; #define Xen_to_xen_transform(arg) ((xen_transform *)Xen_object_ref(arg)) int xen_transform_to_int(Xen n) { xen_transform *col; col = Xen_to_xen_transform(n); return(col->n); } static Xen_object_type_t xen_transform_tag; bool xen_is_transform(Xen obj) { return(Xen_c_object_is_type(obj, xen_transform_tag)); } static void xen_transform_free(xen_transform *v) {if (v) free(v);} Xen_wrap_free(xen_transform, free_xen_transform, xen_transform_free) static char *xen_transform_to_string(xen_transform *v) { #define TRANSFORM_PRINT_BUFFER_SIZE 64 char *buf; if (v == NULL) return(NULL); buf = (char *)calloc(TRANSFORM_PRINT_BUFFER_SIZE, sizeof(char)); snprintf(buf, TRANSFORM_PRINT_BUFFER_SIZE, "#", transform_name(v->n)); return(buf); } Xen_wrap_print(xen_transform, print_xen_transform, xen_transform_to_string) #if HAVE_FORTH || HAVE_RUBY static Xen g_xen_transform_to_string(Xen obj) { char *vstr; Xen result; #define S_xen_transform_to_string "transform->string" Xen_check_type(xen_is_transform(obj), obj, 1, S_xen_transform_to_string, "a transform"); vstr = xen_transform_to_string(Xen_to_xen_transform(obj)); result = C_string_to_Xen_string(vstr); free(vstr); return(result); } #endif #if (!HAVE_SCHEME) static bool xen_transform_equalp(xen_transform *v1, xen_transform *v2) { return((v1 == v2) || (v1->n == v2->n)); } static Xen equalp_xen_transform(Xen obj1, Xen obj2) { if ((!(xen_is_transform(obj1))) || (!(xen_is_transform(obj2)))) return(Xen_false); return(C_bool_to_Xen_boolean(xen_transform_equalp(Xen_to_xen_transform(obj1), Xen_to_xen_transform(obj2)))); } #endif static xen_transform *xen_transform_make(int n) { xen_transform *new_v; new_v = (xen_transform *)malloc(sizeof(xen_transform)); new_v->n = n; return(new_v); } Xen new_xen_transform(int n) { xen_transform *mx; if (n < 0) return(Xen_false); mx = xen_transform_make(n); return(Xen_make_object(xen_transform_tag, mx, 0, free_xen_transform)); } #define C_int_to_Xen_transform(Val) new_xen_transform(Val) #if HAVE_SCHEME static bool s7_xen_transform_equalp(void *obj1, void *obj2) { return((obj1 == obj2) || (((xen_transform *)obj1)->n == ((xen_transform *)obj2)->n)); } static Xen s7_xen_transform_length(s7_scheme *sc, Xen obj) { return(C_int_to_Xen_integer(transform_size(ss))); } #endif static void init_xen_transform(void) { #if HAVE_SCHEME xen_transform_tag = s7_new_type_x(s7, "", print_xen_transform, free_xen_transform, s7_xen_transform_equalp, NULL, NULL, NULL, s7_xen_transform_length, NULL, NULL, NULL); #else #if HAVE_RUBY xen_transform_tag = Xen_make_object_type("XenTransform", sizeof(xen_transform)); #else xen_transform_tag = Xen_make_object_type("Transform", sizeof(xen_transform)); #endif #endif #if HAVE_FORTH fth_set_object_inspect(xen_transform_tag, print_xen_transform); fth_set_object_dump(xen_transform_tag, g_xen_transform_to_string); fth_set_object_equal(xen_transform_tag, equalp_xen_transform); fth_set_object_free(xen_transform_tag, free_xen_transform); #endif #if HAVE_RUBY rb_define_method(xen_transform_tag, "to_s", Xen_procedure_cast print_xen_transform, 0); rb_define_method(xen_transform_tag, "eql?", Xen_procedure_cast equalp_xen_transform, 1); rb_define_method(xen_transform_tag, "==", Xen_procedure_cast equalp_xen_transform, 1); rb_define_method(xen_transform_tag, "to_str", Xen_procedure_cast g_xen_transform_to_string, 0); #endif } static Xen g_integer_to_transform(Xen n) { #define H_integer_to_transform "(" S_integer_to_transform " n) returns a transform object corresponding to the given integer" Xen_check_type(Xen_is_integer(n), n, 1, S_integer_to_transform, "an integer"); return(new_xen_transform(Xen_integer_to_C_int(n))); } static Xen g_transform_to_integer(Xen n) { #define H_transform_to_integer "(" S_transform_to_integer " id) returns the integer corresponding to the given transform" Xen_check_type(xen_is_transform(n), n, 1, S_transform_to_integer, "a transform"); return(C_int_to_Xen_integer(xen_transform_to_int(n))); } static Xen g_is_transform(Xen type) { #define H_is_transform "(" S_is_transform " obj): " PROC_TRUE " if 'obj' is a transform object." return(C_bool_to_Xen_boolean(xen_is_transform(type) && is_transform(Xen_transform_to_C_int(type)))); } static Xen g_snd_transform(Xen type, Xen data, Xen hint) { #define H_snd_transform "(snd-transform type data choice) calls whatever FFT is being used by the \ display. 'type' is a transform object such as " S_fourier_transform "; 'data' is a " S_vct ". In the wavelet case, \ 'choice' is the wavelet to use." int trf, hnt; mus_long_t i, j, n2, vlen; vct *v; mus_float_t *dat, *vdata; Xen_check_type(xen_is_transform(type), type, 1, "snd-transform", "a transform object"); Xen_check_type(mus_is_vct(data), data, 2, "snd-transform", "a " S_vct); trf = Xen_transform_to_C_int(type); if ((trf < 0) || (trf > HAAR)) Xen_out_of_range_error("snd-transform", 1, type, "invalid transform choice"); v = Xen_to_vct(data); vlen = mus_vct_length(v); vdata = mus_vct_data(v); switch (trf) { case FOURIER: n2 = vlen / 2; dat = (mus_float_t *)calloc(vlen, sizeof(mus_float_t)); mus_fft(vdata, dat, vlen, 1); vdata[0] *= vdata[0]; vdata[n2] *= vdata[n2]; for (i = 1, j = vlen - 1; i < n2; i++, j--) { vdata[i] = vdata[i] * vdata[i] + dat[i] * dat[i]; vdata[j] = vdata[i]; } free(dat); break; case WAVELET: hnt = Xen_integer_to_C_int(hint); if (hnt < NUM_WAVELETS) wavelet_transform(vdata, vlen, wavelet_data[hnt], wavelet_sizes[hnt]); break; case HAAR: haar_transform(vdata, vlen); break; case CEPSTRUM: mus_cepstrum(vdata, vlen); break; case WALSH: walsh_transform(vdata, vlen); break; case AUTOCORRELATION: mus_autocorrelate(vdata, vlen); break; } return(data); } static Xen g_add_transform(Xen name, Xen xlabel, Xen lo, Xen hi, Xen proc) { #define H_add_transform "(" S_add_transform " name x-label low high func): add the transform func \ to the transform lists; func should be a function of two arguments, the length of the transform \ and a sampler to get the data, and should return a " S_vct " containing the transform results. \ name is the transform's name, x-label is its x-axis label, and the relevant returned data \ to be displayed goes from low to high (normally 0.0 to 1.0). " S_add_transform " returns the new transform object." char *errmsg; errmsg = procedure_ok(proc, 2, S_add_transform, "transform", 5); if (errmsg) { Xen errstr; errstr = C_string_to_Xen_string(errmsg); free(errmsg); return(snd_bad_arity_error(S_add_transform, errstr, proc)); } #if HAVE_SCHEME if (mus_is_xen(proc)) /* happens a lot in snd-test.scm, so add a check */ Xen_wrong_type_arg_error(S_add_transform, 5, proc, "a procedure"); #endif Xen_check_type(Xen_is_string(name), name, 1, S_add_transform, "a string"); Xen_check_type(Xen_is_string(xlabel), xlabel, 2, S_add_transform, "a string"); Xen_check_type(Xen_is_number(lo), lo, 3, S_add_transform, "a number"); Xen_check_type(Xen_is_number(hi), hi, 4, S_add_transform, "a number"); Xen_check_type(Xen_is_procedure(proc), proc, 5, S_add_transform, "a procedure"); return(C_int_to_Xen_transform(add_transform(Xen_string_to_C_string(name), Xen_string_to_C_string(xlabel), Xen_real_to_C_double(lo), Xen_real_to_C_double(hi), proc))); } static int deleted_type = 0; static void unset_deleted_transform_type(chan_info *cp) { if (cp->transform_type == deleted_type) cp->transform_type = DEFAULT_TRANSFORM_TYPE; } static Xen g_delete_transform(Xen type) { int typ; added_transform *af; #define H_delete_transform "(" S_delete_transform " obj) deletes the specified transform if it was created via " S_add_transform "." Xen_check_type(xen_is_transform(type), type, 1, S_delete_transform, "a transform"); typ = Xen_transform_to_C_int(type); if ((typ < NUM_BUILTIN_TRANSFORM_TYPES) || (!is_transform(typ))) Xen_out_of_range_error(S_delete_transform, 1, type, "an integer (an active added transform)"); af = type_to_transform(typ); if (af) { added_transforms[af->type - NUM_BUILTIN_TRANSFORM_TYPES] = NULL; free(af->xlabel); free(af->name); snd_unprotect_at(af->gc_loc); af->proc = Xen_false; free(af); /* now make sure nobody expects to use that transform */ if (transform_type(ss) == typ) set_transform_type(DEFAULT_TRANSFORM_TYPE); deleted_type = typ; for_each_chan(unset_deleted_transform_type); return(Xen_true); } return(Xen_false); } Xen_wrap_2_optional_args(g_transform_framples_w, g_transform_framples) Xen_wrap_4_optional_args(g_transform_sample_w, g_transform_sample) Xen_wrap_3_optional_args(g_transform_to_vct_w, g_transform_to_vct) Xen_wrap_5_args(g_add_transform_w, g_add_transform) Xen_wrap_3_optional_args(g_snd_transform_w, g_snd_transform) Xen_wrap_1_arg(g_is_transform_w, g_is_transform) Xen_wrap_1_arg(g_delete_transform_w, g_delete_transform) Xen_wrap_no_args(g_log_freq_start_w, g_log_freq_start) Xen_wrap_1_arg(g_set_log_freq_start_w, g_set_log_freq_start) Xen_wrap_no_args(g_show_selection_transform_w, g_show_selection_transform) Xen_wrap_1_arg(g_set_show_selection_transform_w, g_set_show_selection_transform) Xen_wrap_1_arg(g_integer_to_transform_w, g_integer_to_transform) Xen_wrap_1_arg(g_transform_to_integer_w, g_transform_to_integer) #if HAVE_SCHEME static s7_pointer acc_log_freq_start(s7_scheme *sc, s7_pointer args) {return(g_set_log_freq_start(s7_cadr(args)));} static s7_pointer acc_show_selection_transform(s7_scheme *sc, s7_pointer args) {return(g_set_show_selection_transform(s7_cadr(args)));} #endif #if (!HAVE_SCHEME) static Xen transform_temp[6]; /* static for Ruby's sake */ #endif void g_init_fft(void) { #if HAVE_SCHEME #define H_before_transform_hook S_before_transform_hook " (snd chn): called just before a transform is calculated. If it returns \ an integer, it is used as the starting point of the transform. The following \ somewhat brute-force code shows a way to have the transform reflect the position \ of a moving mark:\n\ (define transform-position #f)\n\ (hook-push " S_before_transform_hook "\n\ (lambda (snd chn) transform-position))\n\ (hook-push " S_mark_drag_hook "\n\ (lambda (id)\n\ (set! transform-position (" S_mark_sample " id))\n\ (" S_update_transform_graph ")))" #endif #if HAVE_RUBY #define H_before_transform_hook S_before_transform_hook " (snd chn): called just before a transform is calculated. If it returns \ an integer, it is used as the starting point of the transform. The following \ somewhat brute-force code shows a way to have the transform reflect the position \ of a moving mark:\n\ $transform_position = false\n\ $before_transform_hook.add_hook!(\"snd-fft\") |snd, chn|\n\ $transform_position\n\ end\n\ $mark_drag_hook.add_hook!(\"snd-fft\") |id|\n\ $transform_position = " S_mark_sample "(id)\n\ " S_update_transform_graph "\n\ end" #endif #if HAVE_FORTH #define H_before_transform_hook S_before_transform_hook " (snd chn): called just before a transform is calculated. If it returns \ an integer, it is used as the starting point of the transform. The following \ somewhat brute-force code shows a way to have the transform reflect the position \ of a moving mark:\n\ #f value transform-position\n\ " S_before_transform_hook " lambda: <{ snd chn }> transform-position ; add-hook!\n\ " S_mark_drag_hook " lambda: <{ id }>\n\ id " S_mark_sample " to transform-position\n\ " S_update_transform_graph "\n\ ; add-hook!" #endif init_xen_transform(); before_transform_hook = Xen_define_hook(S_before_transform_hook, "(make-hook 'snd 'chn)", 2, H_before_transform_hook); #if HAVE_SCHEME s7_define_constant(s7, S_fourier_transform, C_int_to_Xen_transform(FOURIER)); s7_define_constant(s7, S_wavelet_transform, C_int_to_Xen_transform(WAVELET)); s7_define_constant(s7, S_haar_transform, C_int_to_Xen_transform(HAAR)); s7_define_constant(s7, S_cepstrum, C_int_to_Xen_transform(CEPSTRUM)); s7_define_constant(s7, S_walsh_transform, C_int_to_Xen_transform(WALSH)); s7_define_constant(s7, S_autocorrelation, C_int_to_Xen_transform(AUTOCORRELATION)); /* *transform-type* is # by default */ #else Xen_define_variable(S_fourier_transform, transform_temp[0], C_int_to_Xen_transform(FOURIER)); Xen_define_variable(S_wavelet_transform, transform_temp[1], C_int_to_Xen_transform(WAVELET)); Xen_define_variable(S_haar_transform, transform_temp[2], C_int_to_Xen_transform(HAAR)); Xen_define_variable(S_cepstrum, transform_temp[3], C_int_to_Xen_transform(CEPSTRUM)); Xen_define_variable(S_walsh_transform, transform_temp[4], C_int_to_Xen_transform(WALSH)); Xen_define_variable(S_autocorrelation, transform_temp[5], C_int_to_Xen_transform(AUTOCORRELATION)); #endif #define H_dont_normalize "The value for " S_transform_normalization " that causes the transform to display raw data" #define H_normalize_by_channel "The value for " S_transform_normalization " that causes the transform to be normalized in each channel independently" #define H_normalize_by_sound "The value for " S_transform_normalization " that causes the transform to be normalized across a sound's channels" #define H_normalize_globally "The value for " S_transform_normalization " that causes the transform to be normalized across all sounds" Xen_define_constant(S_dont_normalize, DONT_NORMALIZE, H_dont_normalize); Xen_define_constant(S_normalize_by_channel, NORMALIZE_BY_CHANNEL, H_normalize_by_channel); Xen_define_constant(S_normalize_by_sound, NORMALIZE_BY_SOUND, H_normalize_by_sound); Xen_define_constant(S_normalize_globally, NORMALIZE_GLOBALLY, H_normalize_globally); Xen_define_safe_procedure(S_transform_framples, g_transform_framples_w, 0, 2, 0, H_transform_framples); Xen_define_safe_procedure(S_transform_sample, g_transform_sample_w, 0, 4, 0, H_transform_sample); Xen_define_safe_procedure(S_transform_to_vct, g_transform_to_vct_w, 0, 3, 0, H_transform_to_vct); Xen_define_safe_procedure(S_add_transform, g_add_transform_w, 5, 0, 0, H_add_transform); Xen_define_safe_procedure(S_is_transform, g_is_transform_w, 1, 0, 0, H_is_transform); Xen_define_safe_procedure(S_delete_transform, g_delete_transform_w, 1, 0, 0, H_delete_transform); Xen_define_safe_procedure("snd-transform", g_snd_transform_w, 2, 1, 0, H_snd_transform); Xen_define_dilambda(S_log_freq_start, g_log_freq_start_w, H_log_freq_start, S_set S_log_freq_start, g_set_log_freq_start_w, 0, 0, 1, 0); Xen_define_dilambda(S_show_selection_transform, g_show_selection_transform_w, H_show_selection_transform, S_set S_show_selection_transform, g_set_show_selection_transform_w, 0, 0, 1, 0); Xen_define_safe_procedure(S_integer_to_transform, g_integer_to_transform_w, 1, 0, 0, H_integer_to_transform); Xen_define_safe_procedure(S_transform_to_integer, g_transform_to_integer_w, 1, 0, 0, H_transform_to_integer); #if HAVE_SCHEME s7_symbol_set_access(s7, ss->log_freq_start_symbol, s7_make_function(s7, "[acc-" S_log_freq_start "]", acc_log_freq_start, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->show_selection_transform_symbol, s7_make_function(s7, "[acc-" S_show_selection_transform "]", acc_show_selection_transform, 2, 0, false, "accessor")); s7_symbol_set_documentation(s7, ss->log_freq_start_symbol, "*log-freq-start*: log freq base (25.0)"); s7_symbol_set_documentation(s7, ss->show_selection_transform_symbol, "*show-selection-transform*: #t if transform display reflects selection, not time-domain window"); #endif } /* display by wavelength is not so useful in the context of sound because * the frequencies span say 8-10 octaves. Even if we place the start point * at 20Hz, that still puts the (linear) middle at 40 Hz (17 meters->1 inch * is basically the range); if we goof around with log freq axis, why bother * with the inverse? */ snd-16.1/makefile.in0000644000076400007640000001720612406321452012445 0ustar bilbilCC = @CC@ SHELL = @SHELL@ INSTALL = @INSTALL@ INSTALL_DATA = ${INSTALL} -m 0644 CFLAGS = @CFLAGS@ GTK_CFLAGS = @GTK_CFLAGS@ XEN_CFLAGS = @XEN_CFLAGS@ CAIRO_CFLAGS = @CAIRO_CFLAGS@ FFTW_CFLAGS = @FFTW_CFLAGS@ GL_FLAGS = @GL_FLAGS@ GSL_FLAGS = @GSL_CFLAGS@ JACK_FLAGS = @JACK_FLAGS@ ORIGINAL_LDFLAGS = @ORIGINAL_LDFLAGS@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ XEN_LIBS = @XEN_LIBS@ GTK_LIBS = @GTK_LIBS@ GTK_LD_LIBS = @GTK_LD_LIBS@ AUDIO_LIB = @AUDIO_LIB@ GSL_LIBS = @GSL_LIBS@ GL_LIBS = @GL_LIBS@ GL_FILES = @GL_FILES@ FFTW_LIBS = @FFTW_LIBS@ JACK_LIBS = @JACK_LIBS@ GMP_LIBS = @GMP_LIBS@ LDSO_FLAGS = @LDSO_FLAGS@ SO_FLAGS = @SO_FLAGS@ SO_LD = @SO_LD@ prefix = @prefix@ exec_prefix = @exec_prefix@ datadir = @datadir@ bindir = @bindir@ srcdir = @srcdir@ VPATH = @srcdir@ mandir = @mandir@ top_srcdir = @top_srcdir@ datarootdir = ${prefix}/share pkgdatadir = ${datarootdir}/snd DEFS = -DSCRIPTS_DIR=\"$(pkgdatadir)\" GX_FILES = $(@GX_FILES@) GX_HEADERS = $(@GX_HEADERS@) .SUFFIXES: .SUFFIXES: .c .o .c.o: $(CC) -c $(DEFS) $(GTK_CFLAGS) $(CAIRO_CFLAGS) $(CFLAGS) $(XEN_CFLAGS) $(GSL_FLAGS) $(GL_FLAGS) $(JACK_FLAGS) $(FFTW_CFLAGS) $< SND_SCRIPTS = *.scm *.fs *.rb *.fsm SNDLIB_HEADERS = mus-config.h sndlib.h _sndlib.h sndlib-strings.h clm.h vct.h sndlib2xen.h clm2xen.h xen.h clm-strings.h SND_HEADERS = mus-config.h sndlib.h _sndlib.h clm.h snd.h snd-0.h snd-1.h snd-strings.h xen.h snd-menu.h snd-file.h SND_X_HEADERS = snd-x0.h snd-x1.h SND_G_HEADERS = snd-g0.h snd-g1.h glistener.h SNDLIB_O_FILES = headers.o audio.o io.o sound.o clm.o xen.o vct.o sndlib2xen.o clm2xen.o S7_HEADERS = s7.h mus-config.h S7_FILES = s7.c S7_O_FILES = @S7_LIB@ NO_GUI_HEADERS = snd-nogui0.h snd-nogui1.h O_FILES = snd-io.o snd-utils.o snd-listener.o snd-completion.o snd-menu.o snd-axis.o snd-data.o snd-fft.o snd-marks.o snd-file.o snd-edits.o snd-chn.o snd-dac.o snd-region.o snd-select.o snd-find.o snd-snd.o snd-help.o snd-main.o snd-print.o snd-trans.o snd-mix.o snd.o snd-env.o snd-xen.o snd-ladspa.o snd-kbd.o snd-sig.o snd-draw.o MOTIF_O_FILES = snd-gxbitmaps.o snd-gxcolormaps.o snd-motif.o xm.o GTK_O_FILES = snd-gutils.o snd-ghelp.o snd-gfind.o snd-gmenu.o snd-gdraw.o snd-glistener.o glistener.o snd-gchn.o snd-gsnd.o snd-gregion.o snd-gmain.o snd-gmix.o snd-genv.o snd-gxbitmaps.o snd-gxcolormaps.o snd-gfft.o snd-gfile.o snd-gprefs.o xg.o NO_GUI_O_FILES = snd-nogui.o GM_FILES = xm.o GM_SO_FILE = xm.so GG_FILES = xg.o GG_SO_FILE = xg.so NO_FILES = main_target: @MAKE_TARGET@ snd: $(SNDLIB_HEADERS) $(SND_HEADERS) $(GX_HEADERS) $(S7_HEADERS) $(S7_O_FILES) $(SNDLIB_O_FILES) $(O_FILES) $(GX_FILES) $(GL_FILES) $(CC) $(LDFLAGS) $(CFLAGS) $(S7_O_FILES) $(SNDLIB_O_FILES) $(O_FILES) $(GX_FILES) $(GL_FILES) -o snd $(SNDLIB_LIB) $(XEN_LIBS) $(GTK_LIBS) $(GL_LIBS) $(JACK_LIBS) $(AUDIO_LIB) $(FFTW_LIBS) $(GSL_LIBS) $(GMP_LIBS) $(LIBS) xm: xen.h mus-config.h $(S7_HEADERS) $(CC) -c xm.c -DUSE_SND=0 $(DEFS) $(SO_FLAGS) $(GTK_CFLAGS) $(CAIRO_CFLAGS) $(CFLAGS) $(XEN_CFLAGS) $(GSL_FLAGS) $(JACK_FLAGS) $(GL_FLAGS) $(SO_LD) $(GM_FILES) -o $(GM_SO_FILE) $(SO_FLAGS) $(LDSO_FLAGS) $(ORIGINAL_LDFLAGS) $(GL_LIBS) $(GMP_LIBS) $(LIBS) xg: xen.h mus-config.h $(S7_HEADERS) $(CC) -c xg.c -DUSE_SND=0 $(DEFS) $(SO_FLAGS) $(GTK_CFLAGS) $(CAIRO_CFLAGS) $(CFLAGS) $(XEN_CFLAGS) $(GSL_FLAGS) $(JACK_FLAGS) $(GL_FLAGS) $(SO_LD) $(GG_FILES) -o $(GG_SO_FILE) $(LDSO_FLAGS) $(ORIGINAL_LDFLAGS) $(GTK_LD_LIBS) $(GMP_LIBS) $(LIBS) libxm: xen.h mus-config.h $(S7_HEADERS) $(S7_O_FILES) rm -f xen.o $(CC) -c xen.c -DUSE_SND=0 $(DEFS) $(SO_FLAGS) $(GTK_CFLAGS) $(CAIRO_CFLAGS) $(CFLAGS) $(XEN_CFLAGS) $(GSL_FLAGS) $(JACK_FLAGS) $(GL_FLAGS) $(CC) -c xm.c -DUSE_SND=0 $(DEFS) $(SO_FLAGS) $(GTK_CFLAGS) $(CAIRO_CFLAGS) $(CFLAGS) $(XEN_CFLAGS) $(GSL_FLAGS) $(JACK_FLAGS) $(GL_FLAGS) $(SO_LD) xen.o $(S7_O_FILES) $(GM_FILES) -o libxm.so $(SO_FLAGS) $(LDSO_FLAGS) $(ORIGINAL_LDFLAGS) $(GL_LIBS) $(GMP_LIBS) $(XEN_LIBS) $(LIBS) libxg: xen.h mus-config.h $(S7_HEADERS) $(S7_O_FILES) rm -f xen.o $(CC) -c xen.c -DUSE_SND=0 $(DEFS) $(SO_FLAGS) $(GTK_CFLAGS) $(CAIRO_CFLAGS) $(CFLAGS) $(XEN_CFLAGS) $(GSL_FLAGS) $(JACK_FLAGS) $(GL_FLAGS) $(CC) -c xg.c -DUSE_SND=0 $(DEFS) $(SO_FLAGS) $(GTK_CFLAGS) $(CAIRO_CFLAGS) $(CFLAGS) $(XEN_CFLAGS) $(GSL_FLAGS) $(JACK_FLAGS) $(GL_FLAGS) $(SO_LD) xen.o $(S7_O_FILES) $(GG_FILES) -o libxg.so $(LDSO_FLAGS) $(ORIGINAL_LDFLAGS) $(GTK_LD_LIBS) $(GMP_LIBS) $(XEN_LIBS) $(LIBS) widget: snd_widget.o snd_widget.o: $(SNDLIB_HEADERS) $(SND_HEADERS) $(GX_HEADERS) $(S7_HEADERS) $(SNDLIB_O_FILES) $(O_FILES) $(GX_FILES) $(GL_FILES) $(LD) -r $(LDFLAGS) $(SNDLIB_O_FILES) $(O_FILES) $(GX_FILES) $(GL_FILES) -o snd_widget.o $(SNDLIB_O_FILES): $(SNDLIB_HEADERS) $(SND_HEADERS) $(S7_HEADERS) $(O_FILES): $(SNDLIB_HEADERS) $(SND_HEADERS) $(SND_X_HEADERS) $(S7_HEADERS) $(MOTIF_O_FILES): $(SNDLIB_HEADERS) $(SND_HEADERS) $(SND_X_HEADERS) $(S7_HEADERS) $(GTK_O_FILES): $(SNDLIB_HEADERS) $(SND_HEADERS) $(SND_G_HEADERS) $(S7_HEADERS) $(S7_O_FILES): $(S7_HEADERS) $(S7_FILES) clean: rm -f $(SNDLIB_O_FILES) rm -f $(O_FILES) rm -f $(MOTIF_O_FILES) rm -f $(GTK_O_FILES) rm -f $(NO_GUI_O_FILES) rm -f $(GM_FILES) rm -f $(GM_SO_FILE) rm -f $(GG_FILES) rm -f $(GG_SO_FILE) rm -f $(GL_FILES) rm -f $(S7_O_FILES) rm -f sndplay.o sndinfo.o rm -f snd sndplay sndinfo distclean: clean rm -f mus-config.h config.log config.status makefile clmclean: rm io.o headers.o audio.o sound.o clm.o allclean: rm -f *.o rm -f *.so rm -f *.a rm -f snd sndplay sndinfo sndplay: $(SNDLIB_HEADERS) $(S7_HEADERS) $(CC) -c $(DEFS) $(CFLAGS) -DUSE_SND=0 -DHAVE_EXTENSION_LANGUAGE=0 headers.c $(CC) -c $(DEFS) $(CFLAGS) -DUSE_SND=0 -DHAVE_EXTENSION_LANGUAGE=0 io.c $(CC) -c $(DEFS) $(CFLAGS) -DUSE_SND=0 -DHAVE_EXTENSION_LANGUAGE=0 audio.c $(CC) -c $(DEFS) $(CFLAGS) -DUSE_SND=0 -DHAVE_EXTENSION_LANGUAGE=0 sound.c $(CC) -c $(DEFS) $(CFLAGS) -DUSE_SND=0 -DHAVE_EXTENSION_LANGUAGE=0 sndplay.c $(CC) $(LDFLAGS) $(CFLAGS) headers.o io.o audio.o sound.o sndplay.o -o sndplay $(JACK_LIBS) $(AUDIO_LIB) $(LIBS) sndinfo: $(SNDLIB_HEADERS) $(S7_HEADERS) $(CC) -c $(DEFS) $(CFLAGS) -DUSE_SND=0 -DHAVE_EXTENSION_LANGUAGE=0 headers.c $(CC) -c $(DEFS) $(CFLAGS) -DUSE_SND=0 -DHAVE_EXTENSION_LANGUAGE=0 io.c $(CC) -c $(DEFS) $(CFLAGS) -DUSE_SND=0 -DHAVE_EXTENSION_LANGUAGE=0 audio.c $(CC) -c $(DEFS) $(CFLAGS) -DUSE_SND=0 -DHAVE_EXTENSION_LANGUAGE=0 sound.c $(CC) -c $(DEFS) $(CFLAGS) -DUSE_SND=0 -DHAVE_EXTENSION_LANGUAGE=0 sndinfo.c $(CC) $(LDFLAGS) $(CFLAGS) headers.o io.o audio.o sound.o sndinfo.o -o sndinfo $(JACK_LIBS) $(AUDIO_LIB) $(LIBS) install: snd ${SHELL} ${top_srcdir}/mkinstalldirs $(DESTDIR)${bindir} ${SHELL} ${top_srcdir}/mkinstalldirs $(DESTDIR)${mandir} ${SHELL} ${top_srcdir}/mkinstalldirs $(DESTDIR)${mandir}/man1 ${SHELL} ${top_srcdir}/mkinstalldirs $(DESTDIR)${pkgdatadir} $(INSTALL) snd $(DESTDIR)${bindir}/snd $(INSTALL_DATA) ${top_srcdir}/snd.1 $(DESTDIR)${mandir}/man1 (cd ${top_srcdir} && for f in ${SND_SCRIPTS}; do ${INSTALL_DATA} $${f} $(DESTDIR)${pkgdatadir}/$${f}; done) uninstall: rm -f $(DESTDIR)${bindir}/snd rm -f $(DESTDIR)${mandir}/man1/snd.1 for f in ${SND_SCRIPTS}; do rm -f $(DESTDIR)${pkgdatadir}/$${f}; done install-strip: snd ${SHELL} ${top_srcdir}/mkinstalldirs $(DESTDIR)${bindir} ${SHELL} ${top_srcdir}/mkinstalldirs $(DESTDIR)${mandir} ${SHELL} ${top_srcdir}/mkinstalldirs $(DESTDIR)${mandir}/man1 ${SHELL} ${top_srcdir}/mkinstalldirs $(DESTDIR)${pkgdatadir} $(INSTALL) -s snd $(DESTDIR)${bindir}/snd $(INSTALL_DATA) ${top_srcdir}/snd.1 $(DESTDIR)${mandir}/man1 (cd ${top_srcdir} && for f in ${SND_SCRIPTS}; do ${INSTALL_DATA} $${f} $(DESTDIR)${pkgdatadir}/$${f}; done) Makefile: Makefile.in config.status ./config.status config.status: configure ./config.status --recheck configure: configure.in cd $(srcdir); autoconf snd-16.1/clm-ins.rb0000644000076400007640000045032712440052536012236 0ustar bilbil# clm-ins.rb -- CLM instruments translated to Snd/Ruby # Translator: Michael Scholz # Created: 03/09/16 01:27:09 # Changed: 14/11/28 02:16:54 # Instruments work with # with_sound (CLM (sample2file gens) and Snd) # with_dac (dac output, except at least for fullmix) # # Tested with Snd 15.x and Ruby 2.x.x # pluck reson # vox cellon # fofins jl_reverb # fm_trumpet gran_synth # pqw_vox touch_tone # stereo_flute spectra # fm_bell two_tab # fm_insect lbj_piano # fm_drum resflt # gong scratch # attract pins # pqw zc # tubebell zn # wurley za # rhodey clm_expsrc exp_snd # hammondoid expfil # metal graph_eq # drone anoi # canter fullmix # nrev grani # # class Ssb_fm < Musgen # initialize(freq) # inspect # to_s # run_func(val1, val2) # ssb_fm(modsig) # bes_fm(start, dur, freq, amp, ratio, index) # # make_ssb_fm(freq) # ssb_fm?(obj) # ssb_fm(gen, modsig) # # class Fm2 < Musgen # initialize(f1, f2, f3, f4, p1, p2, p3, p4) # inspect # to_s # run_func(val1, val2) # fm2(index) # # make_fm2(f1, f2, f3, f4, p1, p2, p3, p4) # fm2?(obj) # fm2(gen, index) # comments from clm-ins.scm $now = 0.0 require "ws" require "spectr" require "env" include Math with_silence do require "matrix" end def normalize_partials(partials) sum = 0.0 parts = partials.dup len = parts.length 1.step(len - 1, 2) do |i| sum += parts[i].abs end 1.step(len - 1, 2) do |i| parts[i] /= sum end parts end unless defined? normalize_partials # violin is defined as an example in ws.rb def violin_test(start = 0.0, dur = 1.0) violin(start, dur, 440, 0.5) $now = start + dur + 0.2 end require "v" # fm_violin is defined in v.rb def fm_violin_test(start = 0.0, dur = 1.0) fm_violin(start, dur, 440, 0.5) $now = start + dur + 0.2 end # PLUCK # # The Karplus-Strong algorithm as extended by David Jaffe and Julius # Smith -- see Jaffe and Smith, "Extensions of the Karplus-Strong # Plucked-String Algorithm" CMJ vol 7 no 2 Summer 1983, reprinted in # "The Music Machine". translated from CLM's pluck.ins add_help(:pluck, "pluck(start, dur, freq, amp, weighting, lossfact) \ Implements the Jaffe-Smith plucked string physical model. WEIGHTING is the ratio of the once-delayed to the twice-delayed samples. \ It defaults to 0.5=shortest decay. Anything other than 0.5 = longer decay. \ Must be between 0 and less than 1.0. LOSSFACT can be used to shorten decays. \ Most useful values are between 0.8 and 1.0. pluck(0, 1, 330, 0.3, 0.95, 0.95)") def pluck(start, dur, freq, amp, weighting = 0.5, lossfact = 0.9) get_optimum_c = lambda do |s, o, p| pa = (1.0 / o) * atan2(s * sin(o), (1.0 - s) + s * cos(o)) tmp_int = (p - pa).floor pc = p - pa - tmp_int until pc >= 0.1 tmp_int -= 1 pc += 1.0 end [tmp_int, (sin(o) - sin(o * pc)) / sin(o + o * pc)] end tune_it = lambda do |f, s1| p = @srate / f s = s1.zero? ? 0.5 : s1 o = hz2radians(f) t1, c1 = get_optimum_c.call(s, o, p) t2, c2 = get_optimum_c.call(1.0 - s, o, p) if s != 0.5 and c1.abs < c2.abs [1.0 - s, c1, t1] else [s, c2, t2] end end wt0, c, dlen = tune_it.call(freq, weighting) lf = lossfact.zero? ? 1.0 : [1.0, lossfact].min wt = wt0.zero? ? 0.5 : [1.0, wt0].min tab = make_vct(dlen) # get initial waveform in "tab" -- here we can introduce 0's to # simulate different pick positions, and so on -- see the CMJ # article for numerous extensions. The normal case is to load it # with white noise (between -1 and 1). allp = make_one_zero(lf * (1.0 - wt), lf * wt) feedb = make_one_zero(c, 1.0) # or feedb = make_one_zero(1.0, c) dlen.times do |i| tab[i] = 1.0 - random(2.0) end run_instrument(start, dur) do val = tab.clm_cycle tab[tab.clm_cycle_index] = (1.0 - c) * one_zero(feedb, one_zero(allp, val)) amp * val end end def pluck_test(start = 0.0, dur = 1.0) pluck(start, dur, 330, 0.3, 0.95, 0.95) $now = start + dur + 0.2 end # formant center frequencies for a male speaker (vox and pqw_vox) Formants = { :I => [390, 1990, 2550], :E => [530, 1840, 2480], :AE => [660, 1720, 2410], :UH => [520, 1190, 2390], :A => [730, 1090, 2440], :OW => [570, 840, 2410], :U => [440, 1020, 2240], :OO => [300, 870, 2240], :ER => [490, 1350, 1690], :W => [300, 610, 2200], :LL => [380, 880, 2575], :R => [420, 1300, 1600], :Y => [300, 2200, 3065], :EE => [260, 3500, 3800], :LH => [280, 1450, 1600], :L => [300, 1300, 3000], :I2 => [350, 2300, 3340], :B => [200, 800, 1750], :D => [300, 1700, 2600], :G => [250, 1350, 2000], :M => [280, 900, 2200], :N => [280, 1700, 2600], :NG => [280, 2300, 2750], :P => [300, 800, 1750], :T => [200, 1700, 2600], :K => [350, 1350, 2000], :F => [175, 900, 4400], :TH => [200, 1400, 2200], :S => [200, 1300, 2500], :SH => [200, 1800, 2000], :V => [175, 1100, 2400], :THE => [200, 1600, 2200], :Z => [200, 1300, 2500], :ZH => [175, 1800, 2000], :ZZ => [900, 2400, 3800], :VV => [565, 1045, 2400]} # MLBVOI # # translation from MUS10 of Marc LeBrun's waveshaping voice instrument # (using FM here) this version translated (and simplified slightly) # from CLM's mlbvoi.ins def vox(start, dur, freq, amp, ampfun, freqfun, freqscl, voxfun, index, vibscl) f1 = [] f2 = [] f3 = [] (voxfun.length - 1).step(1, -2) do |i| phon = Formants[voxfun[i]] x = voxfun[i - 1] f1.unshift(phon[0]) f1.unshift(x) f2.unshift(phon[1]) f2.unshift(x) f3.unshift(phon[2]) f3.unshift(x) end car_os = make_oscil(:frequency, 0) of0 = make_oscil(:frequency, 0) of1 = make_oscil(:frequency, 0) of2 = make_oscil(:frequency, 0) of3 = make_oscil(:frequency, 0) of4 = make_oscil(:frequency, 0) of5 = make_oscil(:frequency, 0) ampf = make_env(:envelope, ampfun, :scaler, amp, :duration, dur) frmf1 = make_env(:envelope, f1, :duration, dur) frmf2 = make_env(:envelope, f2, :duration, dur) frmf3 = make_env(:envelope, f3, :duration, dur) freqf = make_env(:envelope, freqfun, :duration, dur, :scaler, freqscl * freq, :offset, freq) per_vib = make_triangle_wave(:frequency, 6, :amplitude, freq * vibscl) ran_vib = make_rand_interp(:frequency, 20, :amplitude, freq * 0.01) run_instrument(start, dur) do frq = env(freqf) + triangle_wave(per_vib) + rand_interp(ran_vib) car = index * oscil(car_os, hz2radians(frq)) frm = env(frmf1) frm0 = frm / frq.to_f frm_int = frm0.floor if frm_int.even? frq0 = hz2radians(frm_int * frq) frq1 = hz2radians((frm_int + 1) * frq) amp1 = frm0 - frm_int amp0 = 1.0 - amp1 else frq1 = hz2radians(frm_int * frq) frq0 = hz2radians((frm_int + 1) * frq) amp0 = frm0 - frm_int amp1 = 1.0 - amp0 end frm = env(frmf2) frm0 = frm / frq.to_f frm_int = frm0.floor if frm_int.even? frq2 = hz2radians(frm_int * frq) frq3 = hz2radians((frm_int + 1) * frq) amp3 = frm0 - frm_int amp2 = 1.0 - amp3 else frq3 = hz2radians(frm_int * frq) frq2 = hz2radians((frm_int + 1) * frq) amp2 = frm0 - frm_int amp3 = 1.0 - amp2 end frm = env(frmf3) frm0 = frm / frq.to_f frm_int = frm0.floor if frm_int.even? frq4 = hz2radians(frm_int * frq) frq5 = hz2radians((frm_int + 1) * frq) amp5 = frm0 - frm_int amp4 = 1.0 - amp5 else frq5 = hz2radians(frm_int * frq) frq4 = hz2radians((frm_int + 1) * frq) amp4 = frm0 - frm_int amp5 = 1.0 - amp4 end env(ampf) * (0.8 * (amp0 * oscil(of0, frq0 + 0.2 * car) + amp1 * oscil(of1, frq1 + 0.2 * car)) + 0.15 * (amp2 * oscil(of2, frq2 + 0.5 * car) + amp3 * oscil(of3, frq3 + 0.5 * car)) + 0.05 * (amp4 * oscil(of4, frq4 + car) + amp5 * oscil(of5, frq5 + car))) end end def vox_test(start = 0.0, dur = 1.0) amp_env = [0, 0, 25, 1, 75, 1, 100, 0] frq_env = [0, 0, 5, 0.5, 10, 0, 100, 1] examp1 = [0, :E, 25, :AE, 35, :ER, 65, :ER, 75, :I, 100, :UH] examp2 = [0, :I, 5, :OW, 10, :I, 50, :AE, 100, :OO] $now = start vox($now, dur, 170, 0.4, amp_env, frq_env, 0.1, examp1, 0.05, 0.1) $now += dur + 0.2 vox($now, dur, 300, 0.4, amp_env, frq_env, 0.1, examp2, 0.02, 0.1) $now += dur + 0.2 vox($now, 5, 600, 0.4, amp_env, frq_env, 0.1, examp2, 0.01, 0.1) $now += 5.0 + 0.2 end # FOF example add_help(:fofins, "fofins(beg, dur, frq, amp, vib, f0, a0, f1, a1, \ f2, a2, ae=[0, 0, 25, 1, 75, 1, 100, 0]) \ Produces FOF synthesis: \ fofins(0, 1, 270, 0.2, 0.001, 730, 0.6, 1090, 0.3, 2440, 0.1)") def fofins(start, dur, frq, amp, vib, f0, a0, f1, a1, f2, a2, ae = [0, 0, 25, 1, 75, 1, 100,0]) ampf = make_env(:envelope, ae, :scaler, amp, :duration, dur) frq0 = hz2radians(f0) frq1 = hz2radians(f1) frq2 = hz2radians(f2) foflen = @srate == 22050.0 ? 100 : 200 vibr = make_oscil(:frequency, 6) win_freq = TWO_PI / foflen wt0 = make_wave_train(:size, foflen, :frequency, frq) foftab = mus_data(wt0) foflen.times do |i| foftab[i] = (a0 * sin(i * frq0) + a1 * sin(i * frq1) + a2 * sin(i * frq2)) * 0.5 * (1.0 - cos(i * win_freq)) end run_instrument(start, dur) do env(ampf) * wave_train(wt0, vib * oscil(vibr)) end end def fofins_test(start = 0.0, dur = 1.0) fofins(start, dur, 270, 0.2, 0.001, 730, 0.6, 1090, 0.3, 2440, 0.1) $now = start + dur + 0.2 end # FM TRUMPET # # Dexter Morrill's FM-trumpet: from CMJ feb 77 p51 def fm_trumpet(start, dur, *args) frq1, frq2, amp1, amp2, ampatt1, ampdec1, ampatt2, ampdec2 = nil modfrq1, modind11, modind12, modfrq2, modind21, modind22 = nil rvibamp, rvibfrq, vibamp, vibfrq, vibatt, vibdec = nil frqskw, frqatt, ampenv1, ampenv2 = nil indenv1, indenv2, degree, distance, reverb_amount = nil optkey(args, binding, [:frq1, 250.0], [:frq2, 1500.0], [:amp1, 0.5], [:amp2, 0.1], [:ampatt1, 0.03], [:ampdec1, 0.35], [:ampatt2, 0.03], [:ampdec2, 0.3], [:modfrq1, 250.0], [:modind11, 0.0], [:modind12, 2.66], [:modfrq2, 250.0], [:modind21, 0.0], [:modind22, 1.8], [:rvibamp, 0.007], [:rvibfrq, 125.0], [:vibamp, 0.007], [:vibfrq, 7.0], [:vibatt, 0.6], [:vibdec, 0.2], [:frqskw, 0.03], [:frqatt, 0.06], [:ampenv1, [0, 0, 25, 1, 75, 0.9, 100, 0]], [:ampenv2, [0, 0, 25, 1, 75, 0.9, 100, 0]], [:indenv1, [0, 0, 25, 1, 75, 0.9, 100, 0]], [:indenv2, [0, 0, 25, 1, 75, 0.9, 100, 0]], [:degree, 0.0], [:distance, 1.0], [:reverb_amount, 0.005]) dur = dur.to_f per_vib_f = make_env(:envelope, stretch_envelope([0, 1, 25, 0.1, 75, 0, 100, 0], 25, [100 * (vibatt / dur), 45].min, 75, [100 * (1.0 - vibdec / dur), 55].max), :scaler, vibamp, :duration, dur) ran_vib = make_rand_interp(:frequency, rvibfrq, :amplitude, rvibamp) per_vib = make_oscil(:frequency, vibfrq) dec_01 = [75, 100 * (1.0 - 0.01 / dur)].max frq_f = make_env(:envelope, stretch_envelope([0, 0, 25, 1, 75, 1, 100, 0], 25, [25, 100 * (frqatt / dur)].min, 75, dec_01), :scaler, frqskw, :duration, dur) ampattpt1 = [25, 100 * (ampatt1 / dur)].min ampdecpt1 = [75, 100 * (1.0 - ampdec1 / dur)].max ampattpt2 = [25, 100 * (ampatt2 / dur)].min ampdecpt2 = [75, 100 * (1.0 - ampdec2 / dur)].max mod1_f = make_env(:envelope, stretch_envelope(indenv1, 25, ampattpt1, 75, dec_01), :scaler, modfrq1 * (modind12 - modind11), :duration, dur) mod1 = make_oscil(:frequency, 0.0) car1 = make_oscil(:frequency, 0.0) # set frequency to zero here because it is handled multiplicatively below car1_f = make_env(:envelope, stretch_envelope(ampenv1, 25, ampattpt1, 75, ampdecpt1), :scaler, amp1, :duration, dur) mod2_f = make_env(:envelope, stretch_envelope(indenv2, 25, ampattpt2, 75, dec_01), :scaler, modfrq2 * (modind22 - modind21), :duration, dur) mod2 = make_oscil(:frequency, 0.0) car2 = make_oscil(:frequency, 0.0) car2_f = make_env(:envelope, stretch_envelope(ampenv2, 25, ampattpt2, 75, ampdecpt2), :scaler, amp2, :duration, dur) run_instrument(start, dur, :degree, degree, :distance, distance, :reverb_amount, reverb_amount) do frq_change = hz2radians((1.0 + rand_interp(ran_vib)) * (1.0 + env(per_vib_f) * oscil(per_vib)) * (1.0 + env(frq_f))) env(car1_f) * oscil(car1, frq_change * (frq1 + env(mod1_f) * oscil(mod1, modfrq1 * frq_change))) + env(car2_f) * oscil(car2, frq_change * (frq2 + env(mod2_f) * oscil(mod2, modfrq2 * frq_change))) end end def fm_trumpet_test(start = 0.0, dur = 1.0) fm_trumpet(start, dur) $now = start + dur + 0.2 end # PQWVOX # # translation of CLM pqwvox.ins (itself translated from MUS10 of MLB's # waveshaping voice instrument (using phase quadrature waveshaping)) add_help(:pqw_vox, "pqw_vox(start, dur, freq, spacing_freq, \ amp, ampfun, freqfun, freqscl, phonemes, formant_amps, formant_shapes) \ Produces vocal sounds using phase quadrature waveshaping.") def pqw_vox(start, dur, freq, spacing_freq, amp, ampfun, freqfun, freqscl, phonemes, formant_amps, formant_shapes) vox_fun = lambda do |phons, which, newenv| # make an envelope from which entry of phoneme data referred to by phons if phons.empty? newenv else vox_fun.call(phons[2..-1], which, newenv + [phons[0], Formants[phons[1]][which]]) end end car_sin = make_oscil(:frequency, 0.0) car_cos = make_oscil(:frequency, 0.0, :initial_phase, HALF_PI) frq_ratio = spacing_freq / freq.to_f fs = formant_amps.length sin_evens = Array.new(fs) cos_evens = Array.new(fs) sin_odds = Array.new(fs) cos_odds = Array.new(fs) amps = Array.new(fs) frmfs = Array.new(fs) sin_coeffs = Array.new(fs) cos_coeffs = Array.new(fs) ampf = make_env(:envelope, ampfun, :scaler, amp, :duration, dur) freqf = make_env(:envelope, freqfun, :scaler, freqscl * freq, :duration, dur, :offset, freq) per_vib = make_triangle_wave(:frequency, 6.0, :amplitude, freq * 0.1) ran_vib = make_rand_interp(:frequency, 20.0, :amplitude, freq * 0.05) fs.times do |i| sin_evens[i] = make_oscil(:frequency, 0.0) sin_odds[i] = make_oscil(:frequency, 0.0) cos_evens[i] = make_oscil(:frequency, 0.0, :initial_phase, HALF_PI) cos_odds[i] = make_oscil(:frequency, 0.0, :initial_phase, HALF_PI) amps[i] = formant_amps[i] shape = normalize_partials(formant_shapes[i]) cos_coeffs[i] = partials2polynomial(shape, 1) sin_coeffs[i] = partials2polynomial(shape, 0) frmfs[i] = make_env(:envelope, vox_fun.call(phonemes, i, []), :duration, dur) end run_instrument(start, dur) do frq = env(freqf) + triangle_wave(per_vib) + rand_interp(ran_vib) frqscl = hz2radians(frq * frq_ratio) carsin = oscil(car_sin, frqscl) carcos = oscil(car_cos, frqscl) sum = 0.0 fs.times do |j| frm = env(frmfs[j]) frm0 = frm / frq frm_int = frm0.floor if frm_int.even? even_freq = hz2radians(frm_int * frq) odd_freq = hz2radians((frm_int + 1.0) * frq) odd_amp = frm0 - frm_int even_amp = 1.0 - odd_amp else odd_freq = hz2radians(frm_int * frq) even_freq = hz2radians((frm_int + 1.0) * frq) even_amp = frm0 - frm_int odd_amp = 1.0 - even_amp end fax = polynomial(cos_coeffs[j], carcos) yfax = carsin * polynomial(sin_coeffs[j], carcos) sum = sum + amps[j] * (even_amp * (yfax * oscil(sin_evens[j], even_freq) - fax * oscil(cos_evens[j], even_freq)) + odd_amp * (yfax * oscil(sin_odds[j], odd_freq) - fax * oscil(cos_odds[j], odd_freq))) end env(ampf) * sum end end def pqw_vox_test(start = 0.0, dur = 1.0) ampfun = [0, 0, 50, 1, 100, 0] freqfun = [0, 0, 100, 0] freqramp = [0, 0, 100, 1] sh1 = [[1, 1, 2, 0.5], [1, 0.5, 2, 0.5, 3, 1], [1, 1, 4, 0.5]] sh2 = [[1, 1, 2, 0.5], [1, 1, 2, 0.5, 3, 0.2, 4, 0.1], [1, 1, 3, 0.1, 4, 0.5]] sh3 = [[1, 1, 2, 0.5], [1, 1, 4, 0.1], [1, 1, 2, 0.1, 4, 0.05]] sh4 = [[1, 1, 2, 0.5, 3, 0.1, 4, 0.01], [1, 1, 4, 0.1], [1, 1, 2, 0.1, 4, 0.05]] $now = start pqw_vox($now, dur, 300, 300, 0.5, ampfun, freqfun, 0.0, [0, :L, 100, :L], [0.33, 0.33, 0.33], sh1) $now += dur + 0.2 pqw_vox($now, dur, 200, 200, 0.1, ampfun, freqramp, 0.1, [0, :UH, 100, :ER], [0.8, 0.15, 0.05], sh2) $now += dur + 0.2 pqw_vox($now, dur, 100, 314, 0.1, ampfun, freqramp, 0.1, [0, :UH, 100, :ER], [0.8, 0.15, 0.05], sh2) $now += dur + 0.2 pqw_vox($now, dur, 200, 314, 0.1, ampfun, freqramp, 0.01, [0, :UH, 100, :ER], [0.8, 0.15, 0.05], sh3) $now += dur + 0.2 pqw_vox($now, dur, 100, 414, 0.2, ampfun, freqramp, 0.01, [0, :OW, 50, :E, 100, :ER], [0.8, 0.15, 0.05], sh4) $now += dur + 0.2 end # STEREO-FLUTE # slightly simplified [MS] add_help(:stereo_flute, "stereo_flute(start, dur, freq, flow, *key_args) :flow_envelope = [0, 1, 100, 1] :decay = 0.01 :noise = 0.0356 :embouchure_size = 0.5 :fbk_scl1 = 0.5 :fbk_scl2 = 0.55 :out_scl = 1.0 :a0 = 0.7 :b1 = -0.3 :vib_rate = 5 :vib_amount = 0.03 :ran_rate = 5 :ran_amount = 0.03 is a physical model of a flute: \ stereo_flute(0, 1, 440, 0.55, :flow_envelope, [0, 0, 1, 1, 2, 1, 3, 0])") def stereo_flute(start, dur, freq, flow, *args) flow_envelope, decay, noise, embouchure_size = nil fbk_scl1, fbk_scl2, out_scl = nil a0, b1, vib_rate, vib_amount, ran_rate, ran_amount = nil optkey(args, binding, [:flow_envelope, [0, 1, 100, 1]], [:decay, 0.01], # additional time for instrument to decay [:noise, 0.0356], [:embouchure_size, 0.5], [:fbk_scl1, 0.5], # these two are crucial for good results [:fbk_scl2, 0.55], [:out_scl, 1.0], [:a0, 0.7], # filter coefficients [:b1, -0.3], [:vib_rate, 5], [:vib_amount, 0.03], [:ran_rate, 5], [:ran_amount, 0.03]) flowf = make_env(:envelope, flow_envelope, :scaler, flow, :length, seconds2samples(dur - decay)) periodic_vib = make_oscil(:frequency, vib_rate) ran_vib = make_rand_interp(:frequency, ran_rate) breath = make_rand(:frequency, @srate / 2.0, :amplitude, 1) period_samples = (@srate / freq).floor embouchure_samples = (embouchure_size * period_samples).floor embouchure = make_delay(embouchure_samples, :initial_element, 0.0) bore = make_delay(period_samples) reflection_lp_filter = make_one_pole(a0, b1) out_sig = current_diff = previous_out_sig = previous_dc_blocked_a = 0.0 run_instrument(start, dur) do delay_sig = delay(bore, out_sig) emb_sig = delay(embouchure, current_diff) current_flow = vib_amount * oscil(periodic_vib) + ran_amount * rand_interp(ran_vib) + env(flowf) current_diff = (current_flow + noise * current_flow * rand(breath)) + fbk_scl1 * delay_sig current_exitation = emb_sig - emb_sig * emb_sig * emb_sig out_sig = one_pole(reflection_lp_filter, current_exitation + fbk_scl2 * delay_sig) # NB the DC blocker is not in the cicuit. It is applied to the # out_sig but the result is not fed back into the system. dc_blocked_a = (out_sig - previous_out_sig) + 0.995 * previous_dc_blocked_a previous_out_sig = out_sig previous_dc_blocked_a = dc_blocked_a out_scl * dc_blocked_a end end def flute_test(start = 0.0, dur = 1.0) stereo_flute(start, dur, 440, 0.55, :flow_envelope, [0, 0, 1, 1, 2, 1, 3, 0]) $now = start + dur + 0.2 end # FM-BELL add_help(:fm_bell, "fm_bell(startime, dur, frequency, amplitude, \ amp-env=[...], index_env=[...], index=1.0) \ Mixes in one fm bell note." ) def fm_bell(start, dur, freq, amp, amp_env = [0, 0, 0.1, 1, 10, 0.6, 25, 0.3, 50, 0.15, 90, 0.1, 100, 0], index_env = [0, 1, 2, 1.1, 25, 0.75, 75, 0.5, 100, 0.2], index = 1.0) fm_ind1 = hz2radians(32.0 * freq) fm_ind2 = hz2radians(4.0 * (8.0 - freq / 50.0)) fm_ind3 = fm_ind2 * 0.705 * (1.4 - freq / 250.0) fm_ind4 = hz2radians(32.0 * (20.0 - freq / 20.0)) mod1 = make_oscil(:frequency, freq * 2.0) mod2 = make_oscil(:frequency, freq * 1.41) mod3 = make_oscil(:frequency, freq * 2.82) mod4 = make_oscil(:frequency, freq * 2.4) car1 = make_oscil(:frequency, freq) car2 = make_oscil(:frequency, freq) car3 = make_oscil(:frequency, freq * 2.4) indf = make_env(:envelope, index_env, :scaler, index, :duration, dur) ampf = make_env(:envelope, amp_env, :scaler, amp, :duration, dur) run_instrument(start, dur) do fmenv = env(indf) env(ampf) * (oscil(car1, fmenv * fm_ind1 * oscil(mod1)) + 0.15 * oscil(car2, fmenv * (fm_ind2 * oscil(mod2) + fm_ind3 * oscil(mod3))) + 0.15 * oscil(car3, fmenv * fm_ind4 * oscil(mod4))) end end def fm_bell_test(start = 0.0, dur = 1.0) fm_bell(start, dur, 440, 0.5) $now = start + dur + 0.2 end # FM-INSECT def fm_insect(start, dur, freq, amp, amp_env, mod_freq, mod_skew, mod_freq_env, mod_index, mod_index_env, fm_index, fm_ratio, *args) degree, distance, reverb_amount = nil optkey(args, binding, [:degree, 0.0], [:distance, 1.0], [:reverb_amount, 0.005]) carrier = make_oscil(:frequency, freq) fm1_osc = make_oscil(:frequency, mod_freq) fm2_osc = make_oscil(:frequency, fm_ratio * freq) ampf = make_env(:envelope, amp_env, :scaler, amp, :duration, dur) indf = make_env(:envelope, mod_index_env, :scaler, hz2radians(mod_index), :duration, dur) modfrqf = make_env(:envelope, mod_freq_env, :scaler, hz2radians(mod_skew), :duration, dur) fm2_amp = hz2radians(fm_index * fm_ratio * freq) run_instrument(start, dur, :degree, degree, :distance, distance, :reverb_amount, reverb_amount) do garble_in = env(indf) * oscil(fm1_osc, env(modfrqf)) garble_out = fm2_amp * oscil(fm2_osc, garble_in) env(ampf) * oscil(carrier, garble_out + garble_in) end end def fm_insect_test(start = 0.0, dur = 1.0) locust = [0, 0, 40, 1, 95, 1, 100, 0.5] bug_hi = [0, 1, 25, 0.7, 75, 0.78, 100, 1] amp = [0, 0, 25, 1, 75, 0.7, 100, 0] $now = start fm_insect($now + 0.000, 1.699, 4142.627, 0.015, amp, 60, -16.707, locust, 500.866, bug_hi, 0.346, 0.5) fm_insect($now + 0.195, 0.233, 4126.284, 0.030, amp, 60, -12.142, locust, 649.490, bug_hi, 0.407, 0.5) fm_insect($now + 0.217, 2.057, 3930.258, 0.045, amp, 60, -3.011, locust, 562.087, bug_hi, 0.591, 0.5) fm_insect($now + 2.100, 1.500, 900.627, 0.060, amp, 40, -16.707, locust, 300.866, bug_hi, 0.346, 0.5) fm_insect($now + 3.000, 1.500, 900.627, 0.060, amp, 40, -16.707, locust, 300.866, bug_hi, 0.046, 0.5) fm_insect($now + 3.450, 1.500, 900.627, 0.090, amp, 40, -16.707, locust, 300.866, bug_hi, 0.006, 0.5) fm_insect($now + 3.950, 1.500, 900.627, 0.120, amp, 40, -10.707, locust, 300.866, bug_hi, 0.346, 0.5) fm_insect($now + 4.300, 1.500, 900.627, 0.090, amp, 40, -20.707, locust, 300.866, bug_hi, 0.246, 0.5) $now += 6.0 end # FM-DRUM # # Jan Mattox's fm drum: def fm_drum(start, dur, freq, amp, index, high = false, degree = 0.0, distance = 1.0, rev_amount = 0.01) casrat = high ? 8.525 : 3.515 fmrat = high ? 3.414 : 1.414 glsf = make_env(:envelope, [0, 0, 25, 0, 75, 1, 100, 1], :scaler, high ? hz2radians(66) : 0.0, :duration, dur) ampfun = [0, 0, 3, 0.05, 5, 0.2, 7, 0.8, 8, 0.95, 10, 1.0, 12, 0.95, 20, 0.3, 30, 0.1, 100, 0] atdrpt = 100 * (high ? 0.01 : 0.015) / dur ampf = make_env(:envelope, stretch_envelope(ampfun, 10, atdrpt, 15, [atdrpt + 1, 100 - 100 * ((dur - 0.2) / dur)].max), :scaler, amp, :duration, dur) indxfun = [0, 0, 5, 0.014, 10, 0.033, 15, 0.061, 20, 0.099, 25, 0.153, 30, 0.228, 35, 0.332, 40, 0.477, 45, 0.681, 50, 0.964, 55, 0.681, 60, 0.478, 65, 0.332, 70, 0.228, 75, 0.153, 80, 0.099, 85, 0.061, 90, 0.033, 95, 0.0141, 100, 0] indxpt = 100 - 100 * ((dur - 0.1) / dur) divindxf = stretch_envelope(indxfun, 50, atdrpt, 65, indxpt) indxf = make_env(:envelope, divindxf, :duration, dur, :scaler, [hz2radians(index * fmrat * freq), PI].min) mindxf = make_env(:envelope, divindxf, :duration, dur, :scaler, [hz2radians(index * casrat * freq), PI].min) devf = make_env(:envelope, stretch_envelope(ampfun, 10, atdrpt, 90, [atdrpt + 1, 100 - 100 * ((dur - 0.05) / dur)].max), :scaler, [hz2radians(7000), PI].min, :duration, dur) rn = make_rand(:frequency, 7000, :amplitude, 1) carrier = make_oscil(:frequency, freq) fmosc = make_oscil(:frequency, freq * fmrat) cascade = make_oscil(:frequency, freq * casrat) run_instrument(start, dur, :degree, degree, :distance, distance, :reverb_amount, rev_amount) do gls = env(glsf) env(ampf) * oscil(carrier, gls + env(indxf) * oscil(fmosc, gls * fmrat + env(mindxf) * oscil(cascade, gls * casrat + env(devf) * rand(rn)))) end end def fm_drum_test(start = 0.0, dur = 1.0) $now = start fm_drum($now, dur, 55, 0.3, 5, false) $now += dur + 0.2 fm_drum($now, dur, 66, 0.3, 4, true) $now += dur + 0.2 end # FM-GONG # # Paul Weineke's gong. def gong(start, dur, freq, amp, *args) degree, distance, reverb_amount = nil optkey(args, binding, [:degree, 0.0], [:distance, 1.0], [:reverb_amount, 0.005]) mfq1 = freq * 1.16 mfq2 = freq * 3.14 mfq3 = freq * 1.005 indx01 = hz2radians(0.01 * mfq1) indx11 = hz2radians(0.30 * mfq1) indx02 = hz2radians(0.01 * mfq2) indx12 = hz2radians(0.38 * mfq2) indx03 = hz2radians(0.01 * mfq3) indx13 = hz2radians(0.50 * mfq3) atpt = 5 atdur = 100 * (0.002 / dur) expf = [0, 0, 3, 1, 15, 0.5, 27, 0.25, 50, 0.1, 100, 0] rise = [0, 0, 15, 0.3, 30, 1.0, 75, 0.5, 100, 0] fmup = [0, 0, 75, 1.0, 98, 1.0, 100, 0] fmdwn = [0, 0, 2, 1.0, 100, 0] ampfun = make_env(:envelope, stretch_envelope(expf, atpt, atdur), :scaler, amp, :duration, dur) indxfun1 = make_env(:envelope, fmup, :scaler, indx11 - indx01, :duration, dur, :offset, indx01) indxfun2 = make_env(:envelope, fmdwn, :scaler, indx12 - indx02, :duration, dur, :offset, indx02) indxfun3 = make_env(:envelope, rise, :scaler, indx13 - indx03, :duration, dur, :offset, indx03) carrier = make_oscil(:frequency, freq) mod1 = make_oscil(:frequency, mfq1) mod2 = make_oscil(:frequency, mfq2) mod3 = make_oscil(:frequency, mfq3) run_instrument(start, dur, :degree, degree, :distance, distance, :reverb_amount, reverb_amount) do env(ampfun) * oscil(carrier, env(indxfun1) * oscil(mod1) + env(indxfun2) * oscil(mod2) + env(indxfun3) * oscil(mod3)) end end def gong_test(start = 0.0, dur = 1.0) gong(start, dur, 261.61, 0.6) $now = start + dur + 0.2 end # ATTRACT # # by James McCartney, from CMJ vol 21 no 3 p 6 def attract(start, dur, amp, c) a = b = 0.2 dt = 0.04 scale = (0.5 * amp) / c x = -1.0 y = z = 0.0 run_instrument(start, dur) do x1 = x - dt * (y + z) y = y + dt * (x + a * y) z = z + dt * ((b + x * z) - c * z) x = x1 scale * x end end def attract_test(start = 0.0, dur = 1.0) attract(start, dur, 0.5, 2.0) $now = start + dur + 0.2 end # PQW # # phase-quadrature waveshaping used to create asymmetric (i.e. single # side-band) spectra. The basic idea here is a variant of sin x sin y # - cos x cos y = cos (x + y) def pqw(start, dur, spacing_freq, carrier_freq, amp, ampfun, indexfun, partials, *args) degree, distance, reverb_amount = nil optkey(args, binding, [:degree, 0.0], [:distance, 1.0], [:reverb_amount, 0.005]) normalized_partials = normalize_partials(partials) spacing_cos = make_oscil(:frequency, spacing_freq, :initial_phase, HALF_PI) spacing_sin = make_oscil(:frequency, spacing_freq) carrier_cos = make_oscil(:frequency, carrier_freq, :initial_phase, HALF_PI) carrier_sin = make_oscil(:frequency, carrier_freq) sin_coeffs = partials2polynomial(normalized_partials, 0) cos_coeffs = partials2polynomial(normalized_partials, 1) amp_env = make_env(:envelope, ampfun, :scaler, amp, :duration, dur) ind_env = make_env(:envelope, indexfun, :duration, dur) r = carrier_freq / spacing_freq.to_f tr = make_triangle_wave(:frequency, 5, :amplitude, hz2radians(0.005 * spacing_freq)) rn = make_rand_interp(:frequency, 12, :amplitude, hz2radians(0.005 * spacing_freq)) run_instrument(start, dur, :degree, degree, :distance, distance, :reverb_amount, reverb_amount) do vib = triangle_wave(tr) + rand_interp(rn) ax = [1.0, env(ind_env)].min * oscil(spacing_cos, vib) fax = polynomial(cos_coeffs, ax) yfax = oscil(spacing_sin, vib) * polynomial(sin_coeffs, ax) env(amp_env) * (oscil(carrier_sin, vib * r) * yfax - oscil(carrier_cos, vib * r) * fax) end end def pqw_test(start = 0.0, dur = 1.0) pqw(start, dur, 200, 1000, 0.2, [0, 0, 25, 1, 100, 0], [0, 1, 100, 0], [2, 0.1, 3, 0.3, 6, 0.5]) $now = start + dur + 0.2 # to see the asymmetric spectrum most clearly, set the index function # above to [0, 1, 100, 1] end # taken from Perry Cook's stkv1.tar.Z (Synthesis Toolkit), but I was # in a bit of a hurry and may not have made slavishly accurate # translations. Please let me (bil@ccrma.stanford.edu) know of any # serious (non-envelope) errors. # # from Perry Cook's TubeBell.cpp def tubebell(start, dur, freq, amp, base = 32.0) osc0 = make_oscil(freq * 0.995) osc1 = make_oscil(freq * 0.995 * 1.414) osc2 = make_oscil(freq * 1.005) osc3 = make_oscil(freq * 1.414) ampenv1 = make_env(:envelope, [0, 0, 0.005, 1, dur, 0], :base, base, :duration, dur) ampenv2 = make_env(:envelope, [0, 0, 0.001, 1, dur, 0], :base, 2 * base, :duration, dur) ampmod = make_oscil(:frequency, 2.0) g0 = 0.5 * amp * 0.707 g1 = 0.203 g2 = 0.5 * amp g3 = 0.144 run_instrument(start, dur) do (0.007 * oscil(ampmod) + 0.993) * (g0 * env(ampenv1) * oscil(osc0, g1 * oscil(osc1)) + g2 * env(ampenv2) * oscil(osc2, g3 * oscil(osc3))) end end def tubebell_test(start = 0.0, dur = 1.0) tubebell(start, dur, 440, 0.2, 32) $now = start + dur + 0.2 end # from Perry Cook's Wurley.cpp def wurley(start, dur, freq, amp) osc0 = make_oscil(freq) osc1 = make_oscil(freq * 4.0) osc2 = make_oscil(510.0) osc3 = make_oscil(510.0) ampmod = make_oscil(:frequency, 8.0) g0 = 0.5 * amp g1 = 0.307 g2 = 0.5 * amp * 0.307 g3 = 0.117 dur = [dur, 0.3].max ampenv = make_env(:envelope, [0, 0, 1, 1, 9, 1, 10, 0], :duration, dur) indenv = make_env(:envelope, [0, 0, 0.001, 1, 0.15, 0, dur, 0], :duration, dur) resenv = make_env(:envelope, [0, 0, 0.001, 1, 0.25, 0, dur, 0], :duration, dur) run_instrument(start, dur) do env(ampenv) * (1.0 + 0.007 * oscil(ampmod)) * (g0 * oscil(osc0, g1 * oscil(osc1)) + env(resenv) * g2 * oscil(osc2, g3 * env(indenv) * oscil(osc3))) end end def wurley_test(start = 0.0, dur = 1.0) wurley(start, dur, 440, 0.2) $now = start + dur + 0.2 end # from Perry Cook's Rhodey.cpp def rhodey(start, dur, freq, amp, base = 0.5) osc0 = make_oscil(freq) osc1 = make_oscil(freq * 0.5) osc2 = make_oscil(freq) osc3 = make_oscil(freq * 15.0) dur = [dur, 0.3].max ampenv1 = make_env(:envelope, [0, 0, 0.005, 1, dur, 0], :base, base, :duration, dur) ampenv2 = make_env(:envelope, [0, 0, 0.001, 1, dur, 0], :base, base * 1.5, :duration, dur) ampenv3 = make_env(:envelope, [0, 0, 0.001, 1, 0.25, 0, dur, 0], :base, base * 4, :duration, dur) g0 = 0.5 * amp g1 = 0.535 g2 = 0.5 * amp g3 = 0.109 run_instrument(start, dur) do g0 * env(ampenv1) * oscil(osc0, g1 * oscil(osc1)) + g2 * env(ampenv2) * oscil(osc2, env(ampenv3) * g3 * oscil(osc3)) end end def rhodey_test(start = 0.0, dur = 1.0) rhodey(start, dur, 440, 0.2, 0.5) $now = start + dur + 0.2 end # from Perry Cook's BeeThree.cpp def hammondoid(start, dur, freq, amp) osc0 = make_oscil(freq * 0.999) osc1 = make_oscil(freq * 1.997) osc2 = make_oscil(freq * 3.006) osc3 = make_oscil(freq * 6.009) dur = [dur, 0.1].max ampenv1 = make_env(:envelope, [0, 0, 0.005, 1, dur - 0.008, 1, dur, 0], :duration, dur) ampenv2 = make_env(:envelope, [0, 0, 0.005, 1, dur, 0], :duration, dur) g0 = 0.25 * 0.75 * amp g1 = 0.25 * 0.75 * amp g2 = 0.5 * amp g3 = 0.5 * 0.75 * amp run_instrument(start, dur) do env(ampenv1) * (g0 * oscil(osc0) + g1 * oscil(osc1) + g2 * oscil(osc2)) + env(ampenv2) * g3 * oscil(osc3) end end def hammondoid_test(start = 0.0, dur = 1.0) hammondoid(start, dur, 440, 0.2) $now = start + dur + 0.2 end # from Perry Cook's HeavyMtl.cpp def metal(start, dur, freq, amp) osc0 = make_oscil(freq) osc1 = make_oscil(freq * 4.0 * 0.999) osc2 = make_oscil(freq * 3.0 * 1.001) osc3 = make_oscil(freq * 0.5 * 1.002) dur = [dur, 0.1].max ampenv0 = make_env(:envelope, [0, 0, 0.001, 1, dur - 0.002, 1, dur, 0], :duration, dur) ampenv1 = make_env(:envelope, [0, 0, 0.001, 1, dur - 0.011, 1, dur, 0], :duration, dur) ampenv2 = make_env(:envelope, [0, 0, 0.01, 1, dur - 0.015, 1, dur, 0], :duration, dur) ampenv3 = make_env(:envelope, [0, 0, 0.03, 1, dur - 0.04, 1, dur, 0], :duration, dur) g0 = 0.615 * amp g1 = 0.202 g2 = 0.574 g3 = 0.116 run_instrument(start, dur) do g0 * env(ampenv0) * oscil(osc0, g1 * env(ampenv1) * oscil(osc1, g2 * env(ampenv2) * oscil(osc2)) + g3 * env(ampenv3) * oscil(osc3)) end end def metal_test(start = 0.0, dur = 1.0) metal(start, dur, 440, 0.2) $now = start + dur + 0.2 end # DRONE def drone(start, dur, freq, amp, ampfun, synth, ampat, ampdc, amtrev, deg, dis, rvibamt, rvibfreq) waveform = partials2wave(synth) amp *= 0.25 s = make_table_lookup(:frequency, freq, :wave, waveform) amp_env = make_env(:envelope, stretch_envelope(ampfun, 25, 100 * (ampat / dur.to_f), 75, 100 - 100 * (ampdc / dur.to_f)), :scaler, amp, :duration, dur) ran_vib = make_rand(:frequency, rvibfreq, :amplitude, hz2radians(rvibamt * freq)) run_instrument(start, dur, :distance, dis, :degree, deg, :reverb_amount, amtrev) do env(amp_env) * table_lookup(s, rand(ran_vib).abs) end end # CANTER def canter(start, dur, pitch, amp, deg, dis, pcrev, ampfun, ranfun, skewfun, skewpc, ranpc, ranfreq, indexfun, atdr, dcdr, ampfun1, indfun1, fmtfun1, ampfun2, indfun2, fmtfun2, ampfun3, indfun3, fmtfun3, ampfun4, indfun4, fmtfun4) amp *= 0.25 dur = dur.to_f pitch = pitch.to_f rangetop = 910.0 rangebot = 400.0 k = (100 * (log(pitch / rangebot) / log(rangetop / rangebot))).floor mfq = pitch atpt = 100 * (atdr / dur) dcpt = 100 - 100 * (dcdr / dur) lfmt1 = envelope_interp(k, fmtfun1) harm1 = (0.5 + lfmt1 / pitch).floor dev11 = hz2radians(envelope_interp(k, indfun1) * mfq) dev01 = dev11 * 0.5 lamp1 = envelope_interp(k, ampfun1) * amp * (1 - (harm1 - lfmt1 / pitch).abs) lfmt2 = envelope_interp(k, fmtfun2) harm2 = (0.5 + lfmt2 / pitch).floor dev12 = hz2radians(envelope_interp(k, indfun2) * mfq) dev02 = dev12 * 0.5 lamp2 = envelope_interp(k, ampfun2) * amp * (1 - (harm2 - lfmt2 / pitch).abs) lfmt3 = envelope_interp(k, fmtfun3) harm3 = (0.5 + lfmt3 / pitch).floor dev13 = hz2radians(envelope_interp(k, indfun3) * mfq) dev03 = dev13 * 0.5 lamp3 = envelope_interp(k, ampfun3) * amp * (1 - (harm3 - lfmt3 / pitch).abs) lfmt4 = envelope_interp(k, fmtfun4) harm4 = (0.5 + lfmt4 / pitch).floor dev14 = hz2radians(envelope_interp(k, indfun4) * mfq) dev04 = dev14 * 0.5 lamp4 = envelope_interp(k, ampfun4) * amp * (1 - (harm4 - lfmt4 / pitch).abs) tampfun = make_env(:envelope, stretch_envelope(ampfun, 25, atpt, 75, dcpt), :duration, dur) tskwfun = make_env(:envelope, stretch_envelope(skewfun, 25, atpt, 75, dcpt), :scaler, hz2radians(pitch * skewpc.to_f), :duration, dur) tranfun = make_env(:envelope, stretch_envelope(ranfun, 25, atpt, 75, dcpt), :duration, dur) tidxfun = make_env(:envelope, stretch_envelope(indexfun, 25, atpt, 75, dcpt), :duration, dur) modgen = make_oscil(:frequency, pitch) gen1 = make_oscil(:frequency, pitch * harm1) gen2 = make_oscil(:frequency, pitch * harm2) gen3 = make_oscil(:frequency, pitch * harm3) gen4 = make_oscil(:frequency, pitch * harm4) ranvib = make_rand(:frequency, ranfreq, :amplitude, hz2radians(ranpc * pitch)) run_instrument(start, dur, :degree, deg, :distance, dis, :reverb_amount, pcrev) do frqval = env(tskwfun) + env(tranfun) * rand(ranvib) modval = oscil(modgen, frqval) ampval = env(tampfun) indval = env(tidxfun) lamp1 * ampval * oscil(gen1, ((dev01 + indval * dev11) * modval + frqval) * harm1) + lamp2 * ampval * oscil(gen2, ((dev02 + indval * dev12) * modval + frqval) * harm2) + lamp3 * ampval * oscil(gen3, ((dev03 + indval * dev13) * modval + frqval) * harm3) + lamp4 * ampval * oscil(gen4, ((dev04 + indval * dev14) * modval + frqval) * harm4) end end # NREV (the most popular Samson box reverb) # # reverb_factor controls the length of the decay -- it should not # exceed (/ 1.0 .823) # lp_coeff controls the strength of the low pass filter inserted # in the feedback loop # volume can be used to boost the reverb output def nrev(*args) reverb_factor, lp_coeff, volume = nil optkey(args, binding, [:reverb_factor, 1.09], [:lp_coeff, 0.7], [:volume, 1.0]) next_prime = lambda do |val| if val.prime? val else next_prime.call(val + 2) end end srscale = @srate / 25641 dly_len = [1433, 1601, 1867, 2053, 2251, 2399, 347, 113, 37, 59, 53, 43, 37, 29, 19] dly_len.map! do |x| val = (x * srscale).round val += 1 if val.even? next_prime.call(val) end comb1 = make_comb(0.822 * reverb_factor, dly_len[0]) comb2 = make_comb(0.802 * reverb_factor, dly_len[1]) comb3 = make_comb(0.773 * reverb_factor, dly_len[2]) comb4 = make_comb(0.753 * reverb_factor, dly_len[3]) comb5 = make_comb(0.753 * reverb_factor, dly_len[4]) comb6 = make_comb(0.733 * reverb_factor, dly_len[5]) low = make_one_pole(lp_coeff, lp_coeff - 1.0) chan2 = (@channels > 1) chan4 = (@channels == 4) allpass1 = make_all_pass(-0.7, 0.7, dly_len[6]) allpass2 = make_all_pass(-0.7, 0.7, dly_len[7]) allpass3 = make_all_pass(-0.7, 0.7, dly_len[8]) allpass4 = make_all_pass(-0.7, 0.7, dly_len[9]) # 10 for quad allpass5 = make_all_pass(-0.7, 0.7, dly_len[11]) allpass6 = (chan2 ? make_all_pass(-0.7, 0.7, dly_len[12]) : nil) allpass7 = (chan4 ? make_all_pass(-0.7, 0.7, dly_len[13]) : nil) allpass8 = (chan4 ? make_all_pass(-0.7, 0.7, dly_len[14]) : nil) out_frample = Vct.new(@channels, 0.0) run_reverb() do |val, i| rev = volume * val outrev = all_pass(allpass4, one_pole(low, all_pass(allpass3, all_pass(allpass2, all_pass(allpass1, comb(comb1, rev) + comb(comb2, rev) + comb(comb3, rev) + comb(comb4, rev) + comb(comb5, rev) + comb(comb6, rev)))))) out_frample[0] = all_pass(allpass5, outrev) if chan2 out_frample[1] = all_pass(allpass6, outrev) end if chan4 out_frample[2] = all_pass(allpass7, outrev) out_frample[3] = all_pass(allpass8, outrev) end out_frample end end def drone_canter_test(start = 0.0, dur = 1.0) fmt1 = [0, 1200, 100, 1000] fmt2 = [0, 2250, 100, 1800] fmt3 = [0, 4500, 100, 4500] fmt4 = [0, 6750, 100, 8100] amp1 = [0, 0.67, 100, 0.7] amp2 = [0, 0.95, 100, 0.95] amp3 = [0, 0.28, 100, 0.33] amp4 = [0, 0.14, 100, 0.15] ind1 = [0, 0.75, 100, 0.65] ind2 = [0, 0.75, 100, 0.75] ind3 = [0, 1, 100, 1] ind4 = [0, 1, 100, 1] skwf = [0, 0, 100, 0] ampf = [0, 0, 25, 1, 75, 1, 100, 0] ranf = [0, 0.5, 100, 0.5] index = [0, 1, 100, 1] solid = [0, 0, 5, 1, 95, 1, 100, 0] bassdr2 = [0.5, 0.06, 1, 0.62, 1.5, 0.07, 2, 0.6, 2.5, 0.08, 3, 0.56, 4, 0.24, 5, 0.98, 6, 0.53, 7, 0.16, 8, 0.33, 9, 0.62, 10, 0.12, 12, 0.14, 14, 0.86, 16, 0.12, 23, 0.14, 24, 0.17] tenordr = [0.3, 0.04, 1, 0.81, 2, 0.27, 3, 0.2, 4, 0.21, 5, 0.18, 6, 0.35, 7, 0.03, 8, 0.07, 9, 0.02, 10, 0.025, 11, 0.035] $now = start drone($now, 4, 115, 0.125, solid, bassdr2, 0.1, 0.5, 0.03, 45, 1, 0.01, 10) drone($now, 4, 229, 0.125, solid, tenordr, 0.1, 0.5, 0.03, 45, 1, 0.01, 11) drone($now, 4, 229.5, 0.125, solid, tenordr, 0.1, 0.5, 0.03, 45, 1, 0.01, 9) canter($now, 2.100, 918.000, 0.175, 45.0, 1, 0.05, ampf, ranf, skwf, 0.050, 0.01, 10, index, 0.005, 0.005, amp1, ind1, fmt1, amp2, ind2, fmt2, amp3, ind3, fmt3, amp4, ind4, fmt4) canter($now + 2.100, 0.300, 688.500, 0.175, 45.0, 1, 0.05, ampf, ranf, skwf, 0.050, 0.01, 10, index, 0.005, 0.005, amp1, ind1, fmt1, amp2, ind2, fmt2, amp3, ind3, fmt3, amp4, ind4, fmt4) canter($now + 2.400, 0.040, 826.200, 0.175, 45.0, 1, 0.05, ampf, ranf, skwf, 0.050, 0.01, 10, index, 0.005, 0.005, amp1, ind1, fmt1, amp2, ind2, fmt2, amp3, ind3, fmt3, amp4, ind4, fmt4) canter($now + 2.440, 0.560, 459.000, 0.175, 45.0, 1, 0.05, ampf, ranf, skwf, 0.050, 0.01, 10, index, 0.005, 0.005, amp1, ind1, fmt1, amp2, ind2, fmt2, amp3, ind3, fmt3, amp4, ind4, fmt4) canter($now + 3.000, 0.040, 408.000, 0.175, 45.0, 1, 0.05, ampf, ranf, skwf, 0.050, 0.01, 10, index, 0.005, 0.005, amp1, ind1, fmt1, amp2, ind2, fmt2, amp3, ind3, fmt3, amp4, ind4, fmt4) canter($now + 3.040, 0.040, 619.650, 0.175, 45.0, 1, 0.05, ampf, ranf, skwf, 0.050, 0.01, 10, index, 0.005, 0.005, amp1, ind1, fmt1, amp2, ind2, fmt2, amp3, ind3, fmt3, amp4, ind4, fmt4) canter($now + 3.080, 0.040, 408.000, 0.175, 45.0, 1, 0.05, ampf, ranf, skwf, 0.050, 0.01, 10, index, 0.005, 0.005, amp1, ind1, fmt1, amp2, ind2, fmt2, amp3, ind3, fmt3, amp4, ind4, fmt4) canter($now + 3.120, 0.040, 688.500, 0.175, 45.0, 1, 0.05, ampf, ranf, skwf, 0.050, 0.01, 10, index, 0.005, 0.005, amp1, ind1, fmt1, amp2, ind2, fmt2, amp3, ind3, fmt3, amp4, ind4, fmt4) canter($now + 3.160, 0.290, 459.000, 0.175, 45.0, 1, 0.05, ampf, ranf, skwf, 0.050, 0.01, 10, index, 0.005, 0.005, amp1, ind1, fmt1, amp2, ind2, fmt2, amp3, ind3, fmt3, amp4, ind4, fmt4) canter($now + 3.450, 0.150, 516.375, 0.175, 45.0, 1, 0.05, ampf, ranf, skwf, 0.050, 0.01, 10, index, 0.005, 0.005, amp1, ind1, fmt1, amp2, ind2, fmt2, amp3, ind3, fmt3, amp4, ind4, fmt4) canter($now + 3.600, 0.040, 826.200, 0.175, 45.0, 1, 0.05, ampf, ranf, skwf, 0.050, 0.01, 10, index, 0.005, 0.005, amp1, ind1, fmt1, amp2, ind2, fmt2, amp3, ind3, fmt3, amp4, ind4, fmt4) canter($now + 3.640, 0.040, 573.750, 0.175, 45.0, 1, 0.05, ampf, ranf, skwf, 0.050, 0.01, 10, index, 0.005, 0.005, amp1, ind1, fmt1, amp2, ind2, fmt2, amp3, ind3, fmt3, amp4, ind4, fmt4) canter($now + 3.680, 0.040, 619.650, 0.175, 45.0, 1, 0.05, ampf, ranf, skwf, 0.050, 0.01, 10, index, 0.005, 0.005, amp1, ind1, fmt1, amp2, ind2, fmt2, amp3, ind3, fmt3, amp4, ind4, fmt4) canter($now + 3.720, 0.180, 573.750, 0.175, 45.0, 1, 0.05, ampf, ranf, skwf, 0.050, 0.01, 10, index, 0.005, 0.005, amp1, ind1, fmt1, amp2, ind2, fmt2, amp3, ind3, fmt3, amp4, ind4, fmt4) canter($now + 3.900, 0.040, 688.500, 0.175, 45.0, 1, 0.05, ampf, ranf, skwf, 0.050, 0.01, 10, index, 0.005, 0.005, amp1, ind1, fmt1, amp2, ind2, fmt2, amp3, ind3, fmt3, amp4, ind4, fmt4) canter($now + 3.940, 0.260, 459.000, 0.175, 45.0, 1, 0.05, ampf, ranf, skwf, 0.050, 0.01, 10, index, 0.005, 0.005, amp1, ind1, fmt1, amp2, ind2, fmt2, amp3, ind3, fmt3, amp4, ind4, fmt4) $now += 4.4 end # RESON def reson(start, dur, pitch, amp, numformants, indxfun, skewfun, pcskew, skewat, skewdc, vibfreq, vibpc, ranvibfreq, ranvibpc, degree, distance, rev_amount, data) # data is a list of lists of form # [ampf, resonfrq, resonamp, ampat, ampdc, dev0, dev1, indxat, indxdc] dur = dur.to_f pitch = pitch.to_f modulator = make_oscil(:frequency, pitch) carriers = Array.new(numformants) ampfs = Array.new(numformants) indfs = Array.new(numformants) c_rats = Array.new(numformants) frqf = make_env(:envelope, stretch_envelope(skewfun, 25, 100 * (skewat / dur), 75, 100 - (100 * (skewdc / dur))), :scaler, hz2radians(pcskew * pitch), :duration, dur) pervib = make_triangle_wave(:frequency, vibfreq, :amplitude, hz2radians(vibpc * pitch)) ranvib = make_rand_interp(:frequency, ranvibfreq, :amplitude, hz2radians(ranvibpc * pitch)) totalamp = 0.0 numformants.times do |i| totalamp += data[i][2] end numformants.times do |i| frmdat = data[i] ampf = frmdat[0] freq = frmdat[1] rfamp = frmdat[2] ampat = 100 * (frmdat[3] / dur) ampdc = 100 - 100 * (frmdat[4] / dur) dev0 = hz2radians(frmdat[5] * freq) dev1 = hz2radians(frmdat[6] * freq) indxat = 100 * (frmdat[7] / dur) indxdc = 100 - 100 * (frmdat[8] / dur) harm = (freq / pitch).round rsamp = 1.0 - (harm - freq / pitch).abs cfq = pitch * harm ampat = 25 if ampat.zero? ampdc = 75 if ampdc.zero? indxat = 25 if indxat.zero? indxdc = 75 if indxdc.zero? indfs[i] = make_env(:envelope, stretch_envelope(indxfun, 25, indxat, 75, indxdc), :scaler, dev1 - dev0, :offset, dev0, :duration, dur) ampfs[i] = make_env(:envelope, stretch_envelope(ampf, 25, ampat, 75, ampdc), :scaler, rsamp * amp * (rfamp / totalamp), :duration, dur) c_rats[i] = harm carriers[i] = make_oscil(:frequency, cfq) end run_instrument(start, dur, :degree, degree, :distance, distance, :reverb_amount, rev_amount) do vib = triangle_wave(pervib) + rand_interp(ranvib) + env(frqf) modsig = oscil(modulator, vib) outsum = 0.0 numformants.times do |j| outsum += env(ampfs[j]) * oscil(carriers[j], vib * c_rats[j] + env(indfs[j]) * modsig) end outsum end end def reson_test(start = 0.0, dur = 1.0) data = [[[0, 0, 100, 1], 1200, 0.5, 0.1, 0.1, 0, 1.0, 0.1, 0.1], [[0, 1, 100, 0], 2400, 0.5, 0.1, 0.1, 0, 1.0, 0.1, 0.1]] reson(start, dur, 440, 0.5, 2, [0, 0, 100, 1], [0, 0, 100, 1], 0.1, 0.1, 0.1, 5, 0.01, 5, 0.01, 0, 1.0, 0.01, data) $now = start + dur + 0.2 end # STK's feedback-fm instrument named CelloN in Sambox-land def cellon(start, dur, pitch0, amp, ampfun, betafun, beta0, beta1, betaat, betadc, ampat, ampdc, dis, pcrev, deg, pitch1, glissfun = [0, 0, 100, 0], glissat = 0.0, glissdc = 0.0, pvibfreq = 0.0, pvibpc = 0.0, pvibfun = [0, 1, 100, 1], pvibat = 0.0, pvibdc = 0.0, rvibfreq = 0.0, rvibpc = 0.0, rvibfun = [0, 1, 100, 1]) pit1 = pitch1.zero? ? pitch0 : pitch1 car = make_oscil(:frequency, pitch0) low = make_one_zero(0.5, -0.5) fmosc = make_oscil(:frequency, pitch0) fm = 0.0 dur = dur.to_f pitch0 = pitch0.to_f pvib = make_triangle_wave(:frequency, pvibfreq, :amplitude, 1.0) rvib = make_rand_interp(:frequency, rvibfreq, :amplitude, 1.0) ampap = (ampat > 0.0 ? (100 * (ampat / dur)) : 25) ampdp = (ampdc > 0.0 ? (100 * (1.0 - ampdc / dur)) : 75) glsap = (glissat > 0.0 ? (100 * (glissat / dur)) : 25) glsdp = (glissdc > 0.0 ? (100 * (1.0 - glissdc / dur)) : 75) betap = (betaat > 0.0 ? (100 * (betaat / dur)) : 25) betdp = (betadc > 0.0 ? (100 * (1.0 - betadc / dur)) : 75) pvbap = (pvibat > 0.0 ? (100 * (pvibat / dur)) : 25) pvbdp = (pvibdc > 0.0 ? (100 * (1.0 - pvibdc / dur)) : 75) pvibenv = make_env(:envelope, stretch_envelope(pvibfun, 25, pvbap, 75, pvbdp), :scaler, hz2radians(pvibpc * pitch0), :duration, dur) rvibenv = make_env(:envelope, stretch_envelope(rvibfun), :duration, dur, :scaler, hz2radians(rvibpc * pitch0)) glisenv = make_env(:envelope, stretch_envelope(glissfun, 25, glsap, 75, glsdp), :scaler, hz2radians(pit1 - pitch0), :duration, dur) amplenv = make_env(:envelope, stretch_envelope(ampfun, 25, ampap, 75, ampdp), :scaler, amp, :duration, dur) betaenv = make_env(:envelope, stretch_envelope(betafun, 25, betap, 75, betdp), :scaler, beta1 - beta0, :offset, beta0, :duration, dur) run_instrument(start, dur, :degree, deg, :distance, dis, :reverb_amount, pcrev) do vib = env(pvibenv) * triangle_wave(pvib) + env(rvibenv) * rand_interp(rvib) + env(glisenv) fm = one_zero(low, env(betaenv) * oscil(fmosc, fm + vib)) env(amplenv) * oscil(car, fm + vib) end end def cellon_test(start = 0.0, dur = 1.0) cellon(start, dur, 220, 0.5, [0, 0, 25, 1, 75, 1, 100, 0], # ampfun [0, 0, 25, 1, 75, 1, 100, 0], # betafun 0.75, 1.0, 0, 0, 0, 0, 1, 0, 0, 220, [0, 0, 25, 1, 75, 1, 100, 0], # glissfun 0, 0, 0, 0, [0, 0, 100, 0], # pvibfun 0, 0, 0, 0, [0, 0, 100, 0]) # rvibfun $now = start + dur + 0.2 end # JL-REVERB def jl_reverb(*args) allpass1 = make_all_pass(-0.7, 0.7, 2111) allpass2 = make_all_pass(-0.7, 0.7, 673) allpass3 = make_all_pass(-0.7, 0.7, 223) comb1 = make_comb(0.742, 9601) comb2 = make_comb(0.733, 10007) comb3 = make_comb(0.715, 10799) comb4 = make_comb(0.697, 11597) outdel1 = make_delay((0.013 * @srate).round) outdel2 = (@channels > 1 ? make_delay((0.011 * @srate).round) : false) out_frample = Vct.new(@channels, 0.0) run_reverb() do |ho, i| allpass_sum = all_pass(allpass3, all_pass(allpass2, all_pass(allpass1, ho))) comb_sum = (comb(comb1, allpass_sum) + comb(comb2, allpass_sum) + comb(comb3, allpass_sum) + comb(comb4, allpass_sum)) out_frample[0] = delay(outdel1, comb_sum) if outdel2 out_frample[1] = delay(outdel2, comb_sum) end out_frample end end # GRAN-SYNTH def gran_synth(start, dur, freq, grain_dur, interval, amp) grain_env = make_env(:envelope, [0, 0, 25, 1, 75, 1, 100, 0], :duration, grain_dur) carrier = make_oscil(:frequency, freq) grain_size = ([grain_dur, interval].max * @srate).ceil grains = make_wave_train(:size, grain_size, :frequency, 1.0 / interval) grain = mus_data(grains) grain_size.times do |i| grain[i] = env(grain_env) * oscil(carrier) end run_instrument(start, dur) do amp * wave_train(grains) end end def gran_synth_test(start = 0.0, dur = 1.0) gran_synth(start, dur, 100, 0.0189, 0.02, 0.4) $now = start + dur + 0.2 end # TOUCH-TONE def touch_tone(start, number) touch_tab_1 = [0, 697, 697, 697, 770, 770, 770, 852, 852, 852, 941, 941, 941] touch_tab_2 = [0, 1209, 1336, 1477, 1209, 1336, 1477, 1209, 1336, 1477, 1209, 1336, 1477] number.length.times do |i| k = number[i] ii = if k.kind_of?(Numeric) k.zero? ? 11 : k else k == ?* ? 10 : 12 end frq1 = make_oscil(:frequency, touch_tab_1[ii]) frq2 = make_oscil(:frequency, touch_tab_2[ii]) run_instrument(start + i * 0.3, 0.2) do 0.25 * (oscil(frq1) + oscil(frq2)) end end end def touch_tone_test(start = 0.0, dur = 1.0) touch_tone(start, [4, 8, 3, 4, 6, 2, 1]) $now = start + dur * 7 + 0.2 # 7 digits end # SPECTRA def spectra(start, dur, freq, amp, partials = [1, 1, 2, 0.5], amp_envelope = [0, 0, 50, 1, 100, 0], vibrato_amplitude = 0.005, vibrato_speed = 5.0, degree = 0.0, distance = 1.0, rev_amount = 0.005) waveform = partials2wave(partials) frq = hz2radians(freq) s = make_table_lookup(:frequency, freq, :wave, waveform) amp_env = make_env(:envelope, amp_envelope, :scaler, amp, :duration, dur) per_vib = make_triangle_wave(:frequency, vibrato_speed, :amplitude, vibrato_amplitude * frq) ran_vib = make_rand_interp(:frequency, vibrato_speed + 1.0, :amplitude, vibrato_amplitude * frq) run_instrument(start, dur, :degree, degree, :distance, distance, :reverb_amount, rev_amount) do env(amp_env) * table_lookup(s, triangle_wave(per_vib) + rand_interp(ran_vib)) end end def spectra_test(start = 0.0, dur = 1.0) spectra(start, dur, 440.0, 0.8, P_a4, [0, 0, 1, 1, 5, 0.9, 12, 0.5, 25, 0.25, 100, 0]) $now = start + dur + 0.2 end # TWO-TAB # # interpolate between two waveforms (this could be extended to # implement all the various wavetable-based synthesis techniques). def two_tab(start, dur, freq, amp, partial_1 = [1.0, 1.0, 2.0, 0.5], partial_2 = [1.0, 0.0, 3.0, 1.0], amp_envelope = [0, 0, 50, 1, 100, 0], interp_func = [0, 1, 100, 0], vibrato_amplitude = 0.005, vibrato_speed = 5.0, degree = 0.0, distance = 1.0, rev_amount = 0.005) waveform_1 = partials2wave(partial_1) waveform_2 = partials2wave(partial_2) frq = hz2radians(freq) s_1 = make_table_lookup(:frequency, freq, :wave, waveform_1) s_2 = make_table_lookup(:frequency, freq, :wave, waveform_2) amp_env = make_env(:envelope, amp_envelope, :scaler, amp, :duration, dur) interp_env = make_env(:envelope, interp_func, :duration, dur) per_vib = make_triangle_wave(:frequency, vibrato_speed, :amplitude, vibrato_amplitude * frq) ran_vib = make_rand_interp(:frequency, vibrato_speed + 1.0, :amplitude, vibrato_amplitude * frq) run_instrument(start, dur, :degree, degree, :distance, distance, :reverb_amount, rev_amount) do vib = triangle_wave(per_vib) + rand_interp(ran_vib) intrp = env(interp_env) env(amp_env) * (intrp * table_lookup(s_1, vib) + (1.0 - intrp) * table_lookup(s_2, vib)) end end def two_tab_test(start = 0.0, dur = 1.0) two_tab(start, dur, 440, 0.5) $now = start + dur + 0.2 end # LBJ-PIANO $clm_piano_attack_duration = 0.04 $clm_piano_release_duration = 0.2 $clm_db_drop_per_second = -10.0 Piano_Spectra = [[1.97, 0.0326, 2.99, 0.0086, 3.95, 0.0163, 4.97, 0.0178, 5.98, 0.0177, 6.95, 0.0315, 8.02, 0.0001, 8.94, 0.0076, 9.96, 0.0134, 10.99, 0.0284, 11.98, 0.0229, 13.02, 0.0229, 13.89, 0.0010, 15.06, 0.0090, 16.00, 0.0003, 17.08, 0.0078, 18.16, 0.0064, 19.18, 0.0129, 20.21, 0.0085, 21.27, 0.0225, 22.32, 0.0061, 23.41, 0.0102, 24.48, 0.0005, 25.56, 0.0016, 26.64, 0.0018, 27.70, 0.0113, 28.80, 0.0111, 29.91, 0.0158, 31.06, 0.0093, 32.17, 0.0017, 33.32, 0.0002, 34.42, 0.0018, 35.59, 0.0027, 36.74, 0.0055, 37.90, 0.0037, 39.06, 0.0064, 40.25, 0.0033, 41.47, 0.0014, 42.53, 0.0004, 43.89, 0.0010, 45.12, 0.0039, 46.33, 0.0039, 47.64, 0.0009, 48.88, 0.0016, 50.13, 0.0006, 51.37, 0.0010, 52.70, 0.0002, 54.00, 0.0004, 55.30, 0.0008, 56.60, 0.0025, 57.96, 0.0010, 59.30, 0.0012, 60.67, 0.0011, 61.99, 0.0003, 62.86, 0.0001, 64.36, 0.0005, 64.86, 0.0001, 66.26, 0.0004, 67.70, 0.0006, 68.94, 0.0002, 70.10, 0.0001, 70.58, 0.0002, 72.01, 0.0007, 73.53, 0.0006, 75.00, 0.0002, 77.03, 0.0005, 78.00, 0.0002, 79.57, 0.0006, 81.16, 0.0005, 82.70, 0.0005, 84.22, 0.0003, 85.41, 0.0002, 87.46, 0.0001, 90.30, 0.0001, 94.02, 0.0001, 95.26, 0.0002, 109.39, 0.0003], [1.98, 0.0194, 2.99, 0.0210, 3.97, 0.0276, 4.96, 0.0297, 5.96, 0.0158, 6.99, 0.0207, 8.01, 0.0009, 9.00, 0.0101, 10.00, 0.0297, 11.01, 0.0289, 12.02, 0.0211, 13.04, 0.0127, 14.07, 0.0061, 15.08, 0.0174, 16.13, 0.0009, 17.12, 0.0093, 18.16, 0.0117, 19.21, 0.0122, 20.29, 0.0108, 21.30, 0.0077, 22.38, 0.0132, 23.46, 0.0073, 24.14, 0.0002, 25.58, 0.0026, 26.69, 0.0035, 27.77, 0.0053, 28.88, 0.0024, 30.08, 0.0027, 31.13, 0.0075, 32.24, 0.0027, 33.36, 0.0004, 34.42, 0.0004, 35.64, 0.0019, 36.78, 0.0037, 38.10, 0.0009, 39.11, 0.0027, 40.32, 0.0010, 41.51, 0.0013, 42.66, 0.0019, 43.87, 0.0007, 45.13, 0.0017, 46.35, 0.0019, 47.65, 0.0021, 48.89, 0.0014, 50.18, 0.0023, 51.42, 0.0015, 52.73, 0.0002, 54.00, 0.0005, 55.34, 0.0006, 56.60, 0.0010, 57.96, 0.0016, 58.86, 0.0005, 59.30, 0.0004, 60.75, 0.0005, 62.22, 0.0003, 63.55, 0.0005, 64.82, 0.0003, 66.24, 0.0003, 67.63, 0.0011, 69.09, 0.0007, 70.52, 0.0004, 72.00, 0.0005, 73.50, 0.0008, 74.95, 0.0003, 77.13, 0.0013, 78.02, 0.0002, 79.48, 0.0004, 82.59, 0.0004, 84.10, 0.0003], [2.00, 0.0313, 2.99, 0.0109, 4.00, 0.0215, 5.00, 0.0242, 5.98, 0.0355, 7.01, 0.0132, 8.01, 0.0009, 9.01, 0.0071, 10.00, 0.0258, 11.03, 0.0221, 12.02, 0.0056, 13.06, 0.0196, 14.05, 0.0160, 15.11, 0.0107, 16.11, 0.0003, 17.14, 0.0111, 18.21, 0.0085, 19.23, 0.0010, 20.28, 0.0048, 21.31, 0.0128, 22.36, 0.0051, 23.41, 0.0041, 24.05, 0.0006, 25.54, 0.0019, 26.62, 0.0028, 27.72, 0.0034, 28.82, 0.0062, 29.89, 0.0039, 30.98, 0.0058, 32.08, 0.0011, 33.21, 0.0002, 34.37, 0.0008, 35.46, 0.0018, 36.62, 0.0036, 37.77, 0.0018, 38.92, 0.0042, 40.07, 0.0037, 41.23, 0.0011, 42.67, 0.0003, 43.65, 0.0018, 44.68, 0.0025, 45.99, 0.0044, 47.21, 0.0051, 48.40, 0.0044, 49.67, 0.0005, 50.88, 0.0019, 52.15, 0.0003, 53.42, 0.0008, 54.69, 0.0010, 55.98, 0.0005, 57.26, 0.0013, 58.53, 0.0027, 59.83, 0.0011, 61.21, 0.0027, 62.54, 0.0003, 63.78, 0.0003, 65.20, 0.0001, 66.60, 0.0006, 67.98, 0.0008, 69.37, 0.0019, 70.73, 0.0007, 72.14, 0.0004, 73.62, 0.0002, 74.40, 0.0003, 76.52, 0.0006, 77.97, 0.0002, 79.49, 0.0004, 80.77, 0.0003, 81.00, 0.0001, 82.47, 0.0005, 83.97, 0.0001, 87.27, 0.0002], [2.00, 0.0257, 2.99, 0.0142, 3.97, 0.0202, 4.95, 0.0148, 5.95, 0.0420, 6.95, 0.0037, 7.94, 0.0004, 8.94, 0.0172, 9.95, 0.0191, 10.96, 0.0115, 11.97, 0.0059, 12.98, 0.0140, 14.00, 0.0178, 15.03, 0.0121, 16.09, 0.0002, 17.07, 0.0066, 18.08, 0.0033, 19.15, 0.0022, 20.18, 0.0057, 21.22, 0.0077, 22.29, 0.0037, 23.33, 0.0066, 24.97, 0.0002, 25.49, 0.0019, 26.55, 0.0042, 27.61, 0.0043, 28.73, 0.0038, 29.81, 0.0084, 30.91, 0.0040, 32.03, 0.0025, 33.14, 0.0005, 34.26, 0.0003, 35.38, 0.0019, 36.56, 0.0037, 37.68, 0.0049, 38.86, 0.0036, 40.11, 0.0011, 41.28, 0.0008, 42.50, 0.0004, 43.60, 0.0002, 44.74, 0.0022, 45.99, 0.0050, 47.20, 0.0009, 48.40, 0.0036, 49.68, 0.0004, 50.92, 0.0009, 52.17, 0.0005, 53.46, 0.0007, 54.76, 0.0006, 56.06, 0.0005, 57.34, 0.0011, 58.67, 0.0005, 59.95, 0.0015, 61.37, 0.0008, 62.72, 0.0004, 65.42, 0.0009, 66.96, 0.0003, 68.18, 0.0003, 69.78, 0.0003, 71.21, 0.0004, 72.45, 0.0002, 74.22, 0.0003, 75.44, 0.0001, 76.53, 0.0003, 78.31, 0.0004, 79.83, 0.0003, 80.16, 0.0001, 81.33, 0.0003, 82.44, 0.0001, 83.17, 0.0002, 84.81, 0.0003, 85.97, 0.0003, 89.08, 0.0001, 90.70, 0.0002, 92.30, 0.0002, 95.59, 0.0002, 97.22, 0.0003, 98.86, 0.0001, 108.37, 0.0001, 125.54, 0.0001], [1.99, 0.0650, 3.03, 0.0040, 4.03, 0.0059, 5.02, 0.0090, 5.97, 0.0227, 6.98, 0.0050, 8.04, 0.0020, 9.00, 0.0082, 9.96, 0.0078, 11.01, 0.0056, 12.01, 0.0095, 13.02, 0.0050, 14.04, 0.0093, 15.08, 0.0064, 16.14, 0.0017, 17.06, 0.0020, 18.10, 0.0025, 19.14, 0.0023, 20.18, 0.0015, 21.24, 0.0032, 22.29, 0.0029, 23.32, 0.0014, 24.37, 0.0005, 25.43, 0.0030, 26.50, 0.0022, 27.60, 0.0027, 28.64, 0.0024, 29.76, 0.0035, 30.81, 0.0136, 31.96, 0.0025, 33.02, 0.0003, 34.13, 0.0005, 35.25, 0.0007, 36.40, 0.0014, 37.51, 0.0020, 38.64, 0.0012, 39.80, 0.0019, 40.97, 0.0004, 42.09, 0.0003, 43.24, 0.0003, 44.48, 0.0002, 45.65, 0.0024, 46.86, 0.0005, 48.07, 0.0013, 49.27, 0.0008, 50.49, 0.0006, 52.95, 0.0001, 54.23, 0.0005, 55.45, 0.0004, 56.73, 0.0001, 58.03, 0.0003, 59.29, 0.0002, 60.59, 0.0003, 62.04, 0.0002, 65.89, 0.0002, 67.23, 0.0002, 68.61, 0.0002, 69.97, 0.0004, 71.36, 0.0005, 85.42, 0.0001], [1.98, 0.0256, 2.96, 0.0158, 3.95, 0.0310, 4.94, 0.0411, 5.95, 0.0238, 6.94, 0.0152, 7.93, 0.0011, 8.95, 0.0185, 9.92, 0.0166, 10.93, 0.0306, 11.94, 0.0258, 12.96, 0.0202, 13.97, 0.0403, 14.95, 0.0228, 15.93, 0.0005, 17.01, 0.0072, 18.02, 0.0034, 19.06, 0.0028, 20.08, 0.0124, 21.13, 0.0137, 22.16, 0.0102, 23.19, 0.0058, 23.90, 0.0013, 25.30, 0.0039, 26.36, 0.0039, 27.41, 0.0025, 28.47, 0.0071, 29.64, 0.0031, 30.60, 0.0027, 31.71, 0.0021, 32.84, 0.0003, 33.82, 0.0002, 35.07, 0.0019, 36.09, 0.0054, 37.20, 0.0038, 38.33, 0.0024, 39.47, 0.0055, 40.55, 0.0016, 41.77, 0.0006, 42.95, 0.0002, 43.27, 0.0018, 44.03, 0.0006, 45.25, 0.0019, 46.36, 0.0033, 47.50, 0.0024, 48.87, 0.0012, 50.03, 0.0016, 51.09, 0.0004, 53.52, 0.0017, 54.74, 0.0012, 56.17, 0.0003, 57.40, 0.0011, 58.42, 0.0020, 59.70, 0.0007, 61.29, 0.0008, 62.56, 0.0003, 63.48, 0.0002, 64.83, 0.0002, 66.12, 0.0012, 67.46, 0.0017, 68.81, 0.0003, 69.13, 0.0003, 70.53, 0.0002, 71.84, 0.0001, 73.28, 0.0002, 75.52, 0.0010, 76.96, 0.0005, 77.93, 0.0003, 78.32, 0.0003, 79.73, 0.0003, 81.69, 0.0002, 82.52, 0.0001, 84.01, 0.0001, 84.61, 0.0002, 86.88, 0.0001, 88.36, 0.0002, 89.85, 0.0002, 91.35, 0.0003, 92.86, 0.0002, 93.40, 0.0001, 105.28, 0.0002, 106.22, 0.0002, 107.45, 0.0001, 108.70, 0.0003, 122.08, 0.0002], [1.97, 0.0264, 2.97, 0.0211, 3.98, 0.0234, 4.98, 0.0307, 5.96, 0.0085, 6.94, 0.0140, 7.93, 0.0005, 8.96, 0.0112, 9.96, 0.0209, 10.98, 0.0194, 11.98, 0.0154, 12.99, 0.0274, 13.99, 0.0127, 15.01, 0.0101, 15.99, 0.0002, 17.04, 0.0011, 18.08, 0.0032, 19.14, 0.0028, 20.12, 0.0054, 21.20, 0.0053, 22.13, 0.0028, 23.22, 0.0030, 24.32, 0.0006, 25.24, 0.0004, 26.43, 0.0028, 27.53, 0.0048, 28.52, 0.0039, 29.54, 0.0047, 30.73, 0.0044, 31.82, 0.0007, 32.94, 0.0008, 34.04, 0.0012, 35.13, 0.0018, 36.29, 0.0007, 37.35, 0.0075, 38.51, 0.0045, 39.66, 0.0014, 40.90, 0.0004, 41.90, 0.0002, 43.08, 0.0002, 44.24, 0.0017, 45.36, 0.0013, 46.68, 0.0020, 47.79, 0.0015, 48.98, 0.0010, 50.21, 0.0012, 51.34, 0.0001, 53.82, 0.0003, 55.09, 0.0004, 56.23, 0.0005, 57.53, 0.0004, 58.79, 0.0005, 59.30, 0.0002, 60.03, 0.0002, 61.40, 0.0003, 62.84, 0.0001, 66.64, 0.0001, 67.97, 0.0001, 69.33, 0.0001, 70.68, 0.0001, 73.57, 0.0002, 75.76, 0.0002, 76.45, 0.0001, 79.27, 0.0001, 80.44, 0.0002, 81.87, 0.0002], [2.00, 0.0311, 2.99, 0.0086, 3.99, 0.0266, 4.97, 0.0123, 5.98, 0.0235, 6.97, 0.0161, 7.97, 0.0008, 8.96, 0.0088, 9.96, 0.0621, 10.99, 0.0080, 11.99, 0.0034, 12.99, 0.0300, 14.03, 0.0228, 15.04, 0.0105, 16.03, 0.0004, 17.06, 0.0036, 18.09, 0.0094, 18.95, 0.0009, 20.17, 0.0071, 21.21, 0.0161, 22.25, 0.0106, 23.28, 0.0104, 24.33, 0.0008, 25.38, 0.0030, 26.46, 0.0035, 27.50, 0.0026, 28.59, 0.0028, 29.66, 0.0128, 30.75, 0.0139, 31.81, 0.0038, 32.93, 0.0006, 34.04, 0.0004, 35.16, 0.0005, 36.25, 0.0023, 37.35, 0.0012, 38.46, 0.0021, 39.59, 0.0035, 40.71, 0.0006, 41.86, 0.0007, 42.42, 0.0001, 43.46, 0.0003, 44.17, 0.0032, 45.29, 0.0013, 46.57, 0.0004, 47.72, 0.0011, 48.79, 0.0005, 50.11, 0.0005, 51.29, 0.0003, 52.47, 0.0002, 53.68, 0.0004, 55.02, 0.0005, 56.18, 0.0003, 57.41, 0.0003, 58.75, 0.0007, 59.33, 0.0009, 60.00, 0.0004, 61.34, 0.0001, 64.97, 0.0003, 65.20, 0.0002, 66.48, 0.0002, 67.83, 0.0002, 68.90, 0.0003, 70.25, 0.0003, 71.59, 0.0002, 73.68, 0.0001, 75.92, 0.0001, 77.08, 0.0002, 78.45, 0.0002, 81.56, 0.0002, 82.99, 0.0001, 88.39, 0.0001], [0.97, 0.0059, 1.98, 0.0212, 2.99, 0.0153, 3.99, 0.0227, 4.96, 0.0215, 5.97, 0.0153, 6.98, 0.0085, 7.98, 0.0007, 8.97, 0.0179, 9.98, 0.0512, 10.98, 0.0322, 12.00, 0.0098, 13.02, 0.0186, 14.00, 0.0099, 15.05, 0.0109, 15.88, 0.0011, 17.07, 0.0076, 18.11, 0.0071, 19.12, 0.0045, 20.16, 0.0038, 21.23, 0.0213, 22.27, 0.0332, 23.34, 0.0082, 24.34, 0.0014, 25.42, 0.0024, 26.47, 0.0012, 27.54, 0.0014, 28.60, 0.0024, 29.72, 0.0026, 30.10, 0.0008, 31.91, 0.0021, 32.13, 0.0011, 33.02, 0.0007, 34.09, 0.0014, 35.17, 0.0007, 36.27, 0.0024, 37.39, 0.0029, 38.58, 0.0014, 39.65, 0.0017, 40.95, 0.0012, 41.97, 0.0004, 42.43, 0.0002, 43.49, 0.0001, 44.31, 0.0012, 45.42, 0.0031, 46.62, 0.0017, 47.82, 0.0013, 49.14, 0.0013, 50.18, 0.0010, 51.54, 0.0003, 53.90, 0.0006, 55.06, 0.0010, 56.31, 0.0003, 57.63, 0.0001, 59.02, 0.0003, 60.09, 0.0004, 60.35, 0.0004, 61.62, 0.0009, 63.97, 0.0001, 65.19, 0.0001, 65.54, 0.0002, 66.92, 0.0002, 67.94, 0.0002, 69.17, 0.0003, 69.60, 0.0004, 70.88, 0.0002, 72.24, 0.0002, 76.12, 0.0001, 78.94, 0.0001, 81.75, 0.0001, 82.06, 0.0001, 83.53, 0.0001, 90.29, 0.0002, 91.75, 0.0001, 92.09, 0.0002, 93.28, 0.0001, 97.07, 0.0001], [1.98, 0.0159, 2.98, 0.1008, 3.98, 0.0365, 4.98, 0.0133, 5.97, 0.0101, 6.97, 0.0115, 7.97, 0.0007, 8.99, 0.0349, 10.01, 0.0342, 11.01, 0.0236, 12.00, 0.0041, 13.02, 0.0114, 14.05, 0.0137, 15.06, 0.0100, 16.05, 0.0007, 17.04, 0.0009, 18.12, 0.0077, 19.15, 0.0023, 20.12, 0.0017, 21.24, 0.0113, 22.26, 0.0126, 23.30, 0.0093, 24.36, 0.0007, 25.43, 0.0007, 26.47, 0.0009, 27.55, 0.0013, 28.59, 0.0025, 29.61, 0.0010, 30.77, 0.0021, 31.86, 0.0023, 32.96, 0.0003, 34.03, 0.0007, 35.06, 0.0005, 36.20, 0.0006, 37.34, 0.0006, 38.36, 0.0009, 39.60, 0.0016, 40.69, 0.0005, 41.77, 0.0002, 42.92, 0.0002, 44.02, 0.0003, 45.24, 0.0006, 46.33, 0.0004, 47.50, 0.0007, 48.71, 0.0007, 49.87, 0.0002, 51.27, 0.0002, 53.42, 0.0003, 55.88, 0.0003, 57.10, 0.0004, 58.34, 0.0002, 59.86, 0.0003, 61.13, 0.0003, 67.18, 0.0001, 68.50, 0.0001, 71.17, 0.0001, 83.91, 0.0001, 90.55, 0.0001], [0.98, 0.0099, 2.00, 0.0181, 2.99, 0.0353, 3.98, 0.0285, 4.97, 0.0514, 5.96, 0.0402, 6.96, 0.0015, 7.98, 0.0012, 8.98, 0.0175, 9.98, 0.0264, 10.98, 0.0392, 11.98, 0.0236, 13.00, 0.0153, 14.04, 0.0049, 15.00, 0.0089, 16.01, 0.0001, 17.03, 0.0106, 18.03, 0.0028, 19.05, 0.0024, 20.08, 0.0040, 21.11, 0.0103, 22.12, 0.0104, 23.20, 0.0017, 24.19, 0.0008, 25.20, 0.0007, 26.24, 0.0011, 27.36, 0.0009, 27.97, 0.0030, 29.40, 0.0044, 30.37, 0.0019, 31.59, 0.0017, 32.65, 0.0008, 33.59, 0.0005, 34.79, 0.0009, 35.75, 0.0027, 36.88, 0.0035, 37.93, 0.0039, 39.00, 0.0031, 40.08, 0.0025, 41.16, 0.0010, 43.25, 0.0004, 44.52, 0.0012, 45.62, 0.0023, 45.85, 0.0012, 47.00, 0.0006, 47.87, 0.0008, 48.99, 0.0003, 50.48, 0.0003, 51.62, 0.0001, 52.43, 0.0001, 53.56, 0.0002, 54.76, 0.0002, 56.04, 0.0002, 56.68, 0.0006, 57.10, 0.0003, 58.28, 0.0005, 59.47, 0.0003, 59.96, 0.0002, 60.67, 0.0001, 63.08, 0.0002, 64.29, 0.0002, 66.72, 0.0001, 67.97, 0.0001, 68.65, 0.0001, 70.43, 0.0001, 79.38, 0.0001, 80.39, 0.0001, 82.39, 0.0001], [1.00, 0.0765, 1.99, 0.0151, 2.99, 0.0500, 3.99, 0.0197, 5.00, 0.0260, 6.00, 0.0145, 6.98, 0.0128, 7.97, 0.0004, 8.98, 0.0158, 9.99, 0.0265, 11.02, 0.0290, 12.02, 0.0053, 13.03, 0.0242, 14.03, 0.0103, 15.06, 0.0054, 16.04, 0.0006, 17.08, 0.0008, 18.10, 0.0058, 19.16, 0.0011, 20.16, 0.0055, 21.18, 0.0040, 22.20, 0.0019, 23.22, 0.0014, 24.05, 0.0005, 25.31, 0.0019, 26.38, 0.0018, 27.44, 0.0022, 28.45, 0.0024, 29.57, 0.0073, 30.58, 0.0032, 31.66, 0.0071, 32.73, 0.0015, 33.85, 0.0005, 34.96, 0.0003, 36.00, 0.0020, 37.11, 0.0018, 38.18, 0.0055, 39.23, 0.0006, 40.33, 0.0004, 41.52, 0.0003, 43.41, 0.0028, 45.05, 0.0003, 45.99, 0.0002, 47.07, 0.0003, 48.52, 0.0002, 49.48, 0.0003, 50.63, 0.0003, 51.81, 0.0002, 54.05, 0.0002, 55.24, 0.0001, 56.62, 0.0001, 57.81, 0.0004, 59.16, 0.0013, 60.23, 0.0003, 66.44, 0.0001, 68.99, 0.0004, 75.49, 0.0001, 87.56, 0.0004], [0.98, 0.0629, 1.99, 0.0232, 2.98, 0.0217, 4.00, 0.0396, 4.98, 0.0171, 5.97, 0.0098, 6.99, 0.0167, 7.99, 0.0003, 8.98, 0.0192, 9.98, 0.0266, 10.99, 0.0256, 12.01, 0.0061, 13.02, 0.0135, 14.02, 0.0062, 15.05, 0.0158, 16.06, 0.0018, 17.08, 0.0101, 18.09, 0.0053, 19.11, 0.0074, 20.13, 0.0020, 21.17, 0.0052, 22.22, 0.0077, 23.24, 0.0035, 24.00, 0.0009, 25.32, 0.0016, 26.40, 0.0022, 27.43, 0.0005, 28.55, 0.0026, 29.60, 0.0026, 30.65, 0.0010, 31.67, 0.0019, 32.77, 0.0008, 33.81, 0.0003, 34.91, 0.0003, 36.01, 0.0005, 37.11, 0.0010, 38.20, 0.0014, 39.29, 0.0039, 40.43, 0.0012, 41.50, 0.0006, 43.38, 0.0017, 43.75, 0.0002, 44.94, 0.0005, 46.13, 0.0002, 47.11, 0.0003, 48.28, 0.0005, 48.42, 0.0005, 49.44, 0.0003, 50.76, 0.0004, 51.93, 0.0002, 54.15, 0.0003, 55.31, 0.0005, 55.50, 0.0003, 56.98, 0.0003, 57.90, 0.0004, 60.33, 0.0002, 61.39, 0.0001, 61.59, 0.0001, 65.09, 0.0002, 66.34, 0.0001, 68.85, 0.0001, 70.42, 0.0002, 71.72, 0.0001, 73.05, 0.0003, 79.65, 0.0001, 85.28, 0.0002, 93.52, 0.0001], [1.02, 0.0185, 1.99, 0.0525, 2.98, 0.0613, 3.99, 0.0415, 4.98, 0.0109, 5.97, 0.0248, 6.99, 0.0102, 7.98, 0.0005, 8.98, 0.0124, 9.99, 0.0103, 10.99, 0.0124, 12.00, 0.0016, 13.01, 0.0029, 14.03, 0.0211, 15.04, 0.0128, 16.07, 0.0021, 17.09, 0.0009, 18.09, 0.0043, 19.14, 0.0022, 20.13, 0.0016, 21.20, 0.0045, 22.21, 0.0088, 23.26, 0.0046, 24.29, 0.0013, 25.35, 0.0009, 26.39, 0.0028, 27.49, 0.0009, 28.51, 0.0006, 29.58, 0.0012, 30.70, 0.0010, 31.74, 0.0019, 32.75, 0.0002, 33.85, 0.0001, 34.95, 0.0005, 36.02, 0.0003, 37.16, 0.0009, 38.25, 0.0018, 39.35, 0.0008, 40.54, 0.0004, 41.61, 0.0002, 43.40, 0.0004, 43.74, 0.0003, 45.05, 0.0001, 46.11, 0.0003, 47.40, 0.0002, 48.36, 0.0004, 49.55, 0.0004, 50.72, 0.0002, 52.00, 0.0001, 55.58, 0.0002, 57.02, 0.0001, 57.98, 0.0002, 59.13, 0.0003, 61.56, 0.0001, 66.56, 0.0001, 87.65, 0.0002], [1.00, 0.0473, 1.99, 0.0506, 2.99, 0.0982, 3.99, 0.0654, 5.00, 0.0196, 5.99, 0.0094, 6.99, 0.0118, 7.93, 0.0001, 8.99, 0.0057, 10.01, 0.0285, 11.01, 0.0142, 12.03, 0.0032, 13.03, 0.0056, 14.06, 0.0064, 15.06, 0.0059, 16.11, 0.0005, 17.09, 0.0033, 18.14, 0.0027, 19.15, 0.0014, 20.17, 0.0010, 21.21, 0.0059, 22.26, 0.0043, 23.31, 0.0031, 24.31, 0.0018, 25.33, 0.0009, 26.41, 0.0005, 27.47, 0.0015, 28.53, 0.0015, 29.58, 0.0041, 30.65, 0.0025, 31.73, 0.0011, 32.83, 0.0010, 34.98, 0.0003, 36.07, 0.0009, 37.23, 0.0001, 38.26, 0.0020, 39.41, 0.0014, 40.53, 0.0005, 41.40, 0.0003, 42.80, 0.0002, 43.48, 0.0028, 43.93, 0.0001, 45.03, 0.0003, 46.18, 0.0007, 47.41, 0.0001, 48.57, 0.0002, 49.67, 0.0001, 50.83, 0.0002, 54.39, 0.0001, 55.58, 0.0002, 57.97, 0.0005, 58.11, 0.0002, 59.21, 0.0001, 60.42, 0.0002, 61.66, 0.0001], [1.00, 0.0503, 2.00, 0.0963, 2.99, 0.1304, 3.99, 0.0218, 4.98, 0.0041, 5.98, 0.0292, 6.98, 0.0482, 7.99, 0.0005, 8.99, 0.0280, 10.00, 0.0237, 11.00, 0.0152, 12.02, 0.0036, 12.95, 0.0022, 14.06, 0.0111, 15.07, 0.0196, 16.08, 0.0016, 17.11, 0.0044, 18.13, 0.0073, 19.17, 0.0055, 20.19, 0.0028, 21.20, 0.0012, 22.27, 0.0068, 23.30, 0.0036, 24.35, 0.0012, 25.35, 0.0002, 26.46, 0.0005, 27.47, 0.0005, 28.59, 0.0009, 29.65, 0.0021, 30.70, 0.0020, 31.78, 0.0012, 32.89, 0.0010, 35.06, 0.0005, 36.16, 0.0008, 37.27, 0.0010, 38.36, 0.0010, 39.47, 0.0014, 40.58, 0.0004, 41.43, 0.0007, 41.82, 0.0003, 43.48, 0.0008, 44.53, 0.0001, 45.25, 0.0003, 46.43, 0.0002, 47.46, 0.0002, 48.76, 0.0005, 49.95, 0.0004, 50.96, 0.0002, 51.12, 0.0002, 52.33, 0.0001, 54.75, 0.0001, 55.75, 0.0002, 56.90, 0.0002, 58.17, 0.0002, 59.40, 0.0004, 60.62, 0.0002, 65.65, 0.0001, 66.91, 0.0002, 69.91, 0.0001, 71.25, 0.0002], [1.00, 0.1243, 1.98, 0.1611, 3.00, 0.0698, 3.98, 0.0390, 5.00, 0.0138, 5.99, 0.0154, 7.01, 0.0287, 8.01, 0.0014, 9.01, 0.0049, 10.00, 0.0144, 11.01, 0.0055, 12.05, 0.0052, 13.01, 0.0011, 14.05, 0.0118, 15.07, 0.0154, 16.12, 0.0028, 17.14, 0.0061, 18.25, 0.0007, 19.22, 0.0020, 20.24, 0.0011, 21.27, 0.0029, 22.30, 0.0046, 23.34, 0.0049, 24.35, 0.0004, 25.45, 0.0003, 26.47, 0.0007, 27.59, 0.0008, 28.16, 0.0009, 29.12, 0.0002, 29.81, 0.0006, 30.81, 0.0009, 31.95, 0.0004, 33.00, 0.0011, 34.12, 0.0005, 35.18, 0.0003, 36.30, 0.0008, 37.38, 0.0003, 38.55, 0.0003, 39.64, 0.0006, 40.77, 0.0007, 41.52, 0.0006, 41.89, 0.0006, 43.04, 0.0011, 43.60, 0.0009, 44.31, 0.0002, 45.68, 0.0002, 46.56, 0.0003, 47.60, 0.0001, 48.83, 0.0006, 50.01, 0.0003, 51.27, 0.0003, 56.04, 0.0005, 57.21, 0.0003, 58.56, 0.0004, 59.83, 0.0003, 61.05, 0.0001, 62.20, 0.0001, 67.37, 0.0002, 76.53, 0.0001], [0.99, 0.0222, 1.99, 0.0678, 2.99, 0.0683, 4.00, 0.0191, 5.00, 0.0119, 6.01, 0.0232, 6.98, 0.0336, 7.99, 0.0082, 9.01, 0.0201, 10.01, 0.0189, 11.01, 0.0041, 12.01, 0.0053, 13.05, 0.0154, 14.04, 0.0159, 15.06, 0.0092, 16.11, 0.0038, 17.12, 0.0014, 18.15, 0.0091, 19.16, 0.0006, 20.30, 0.0012, 21.25, 0.0061, 22.28, 0.0099, 23.34, 0.0028, 24.38, 0.0012, 25.43, 0.0016, 26.49, 0.0048, 27.55, 0.0025, 28.62, 0.0015, 29.71, 0.0032, 30.78, 0.0077, 31.88, 0.0011, 32.97, 0.0007, 34.08, 0.0006, 35.16, 0.0008, 36.28, 0.0004, 37.41, 0.0006, 38.54, 0.0005, 39.62, 0.0002, 40.80, 0.0003, 41.93, 0.0001, 43.06, 0.0002, 44.21, 0.0003, 45.38, 0.0002, 46.54, 0.0007, 47.78, 0.0003, 48.95, 0.0004, 50.10, 0.0003, 51.37, 0.0002, 53.79, 0.0003, 56.20, 0.0001, 58.71, 0.0002, 66.47, 0.0003], [1.01, 0.0241, 1.99, 0.1011, 2.98, 0.0938, 3.98, 0.0081, 4.99, 0.0062, 5.99, 0.0291, 6.99, 0.0676, 7.59, 0.0004, 8.98, 0.0127, 9.99, 0.0112, 10.99, 0.0142, 12.00, 0.0029, 13.02, 0.0071, 14.02, 0.0184, 15.03, 0.0064, 16.07, 0.0010, 17.09, 0.0011, 18.11, 0.0010, 19.15, 0.0060, 20.19, 0.0019, 21.24, 0.0025, 22.29, 0.0013, 23.31, 0.0050, 25.41, 0.0030, 26.50, 0.0018, 27.53, 0.0006, 28.63, 0.0012, 29.66, 0.0013, 30.77, 0.0020, 31.84, 0.0006, 34.04, 0.0001, 35.14, 0.0001, 36.32, 0.0004, 37.41, 0.0007, 38.53, 0.0007, 39.67, 0.0009, 40.85, 0.0003, 45.49, 0.0002, 46.65, 0.0001, 47.81, 0.0004, 49.01, 0.0002, 53.91, 0.0002, 55.14, 0.0002, 57.69, 0.0002], [1.00, 0.0326, 2.00, 0.1066, 2.99, 0.1015, 4.00, 0.0210, 4.97, 0.0170, 5.99, 0.0813, 6.98, 0.0820, 7.96, 0.0011, 8.99, 0.0248, 10.03, 0.0107, 11.01, 0.0126, 12.01, 0.0027, 13.01, 0.0233, 14.04, 0.0151, 15.05, 0.0071, 16.04, 0.0002, 17.10, 0.0061, 18.12, 0.0059, 19.15, 0.0087, 20.23, 0.0005, 21.25, 0.0040, 22.30, 0.0032, 23.35, 0.0004, 24.40, 0.0001, 25.45, 0.0030, 26.54, 0.0022, 27.60, 0.0003, 28.70, 0.0009, 29.80, 0.0029, 30.85, 0.0006, 31.97, 0.0006, 34.19, 0.0004, 35.30, 0.0003, 36.43, 0.0007, 37.56, 0.0005, 38.68, 0.0019, 39.88, 0.0013, 41.00, 0.0003, 43.35, 0.0003, 44.51, 0.0002, 45.68, 0.0006, 46.93, 0.0010, 48.11, 0.0006, 49.29, 0.0003, 55.58, 0.0002], [0.98, 0.0113, 1.99, 0.0967, 3.00, 0.0719, 3.98, 0.0345, 4.98, 0.0121, 6.00, 0.0621, 7.00, 0.0137, 7.98, 0.0006, 9.01, 0.0314, 10.01, 0.0171, 11.02, 0.0060, 12.03, 0.0024, 13.05, 0.0077, 14.07, 0.0040, 15.12, 0.0032, 16.13, 0.0004, 17.15, 0.0011, 18.20, 0.0028, 19.18, 0.0003, 20.26, 0.0003, 21.31, 0.0025, 22.35, 0.0021, 23.39, 0.0005, 25.55, 0.0002, 26.62, 0.0014, 27.70, 0.0003, 28.78, 0.0005, 29.90, 0.0030, 31.01, 0.0011, 32.12, 0.0005, 34.31, 0.0001, 35.50, 0.0002, 36.62, 0.0002, 37.76, 0.0005, 38.85, 0.0002, 40.09, 0.0004, 43.60, 0.0001, 44.73, 0.0002, 46.02, 0.0002, 47.25, 0.0004, 48.44, 0.0004], [0.99, 0.0156, 1.98, 0.0846, 2.98, 0.0178, 3.98, 0.0367, 4.98, 0.0448, 5.98, 0.0113, 6.99, 0.0189, 8.00, 0.0011, 9.01, 0.0247, 10.02, 0.0089, 11.01, 0.0184, 12.03, 0.0105, 13.00, 0.0039, 14.07, 0.0116, 15.09, 0.0078, 16.13, 0.0008, 17.14, 0.0064, 18.19, 0.0029, 19.22, 0.0028, 20.25, 0.0017, 21.32, 0.0043, 22.37, 0.0055, 23.42, 0.0034, 24.48, 0.0004, 25.54, 0.0002, 26.61, 0.0017, 27.70, 0.0011, 28.80, 0.0002, 29.89, 0.0019, 30.97, 0.0028, 32.09, 0.0007, 34.30, 0.0002, 35.44, 0.0003, 36.55, 0.0001, 37.69, 0.0004, 38.93, 0.0002, 40.05, 0.0005, 41.20, 0.0005, 42.37, 0.0002, 43.54, 0.0003, 44.73, 0.0001, 45.95, 0.0002, 47.16, 0.0001, 48.43, 0.0005, 49.65, 0.0004, 55.90, 0.0002, 59.81, 0.0004], [1.01, 0.0280, 2.00, 0.0708, 2.99, 0.0182, 3.99, 0.0248, 4.98, 0.0245, 5.98, 0.0279, 6.98, 0.0437, 7.99, 0.0065, 8.99, 0.0299, 10.00, 0.0073, 10.99, 0.0011, 12.03, 0.0122, 13.03, 0.0028, 14.08, 0.0044, 15.11, 0.0097, 16.15, 0.0010, 17.17, 0.0025, 18.19, 0.0017, 19.24, 0.0008, 20.28, 0.0040, 21.32, 0.0024, 22.38, 0.0008, 23.46, 0.0032, 24.52, 0.0010, 25.59, 0.0008, 26.68, 0.0009, 27.76, 0.0012, 28.88, 0.0003, 29.95, 0.0005, 31.05, 0.0017, 32.14, 0.0002, 33.29, 0.0003, 37.88, 0.0002, 39.03, 0.0002, 40.19, 0.0004, 41.37, 0.0003, 43.74, 0.0002, 46.20, 0.0001, 48.68, 0.0001, 49.93, 0.0001, 51.19, 0.0002], [1.00, 0.0225, 1.99, 0.0921, 2.98, 0.0933, 3.99, 0.0365, 4.99, 0.0100, 5.98, 0.0213, 6.98, 0.0049, 7.98, 0.0041, 8.98, 0.0090, 9.99, 0.0068, 11.01, 0.0040, 12.03, 0.0086, 13.02, 0.0015, 14.04, 0.0071, 15.09, 0.0082, 16.14, 0.0011, 17.15, 0.0014, 18.18, 0.0010, 19.26, 0.0013, 20.26, 0.0005, 21.33, 0.0006, 22.36, 0.0011, 23.46, 0.0016, 24.52, 0.0004, 25.59, 0.0002, 26.70, 0.0006, 27.78, 0.0007, 28.87, 0.0002, 30.03, 0.0008, 31.14, 0.0010, 32.24, 0.0006, 33.37, 0.0002, 35.67, 0.0003, 37.99, 0.0004, 39.17, 0.0004, 40.35, 0.0005, 41.53, 0.0001, 46.42, 0.0001], [1.00, 0.0465, 1.99, 0.0976, 2.98, 0.0678, 4.00, 0.0727, 4.99, 0.0305, 5.98, 0.0210, 6.98, 0.0227, 8.00, 0.0085, 9.01, 0.0183, 10.02, 0.0258, 11.05, 0.0003, 12.06, 0.0061, 13.05, 0.0021, 14.10, 0.0089, 15.12, 0.0077, 16.16, 0.0016, 17.21, 0.0061, 18.23, 0.0011, 19.29, 0.0031, 20.36, 0.0031, 21.41, 0.0007, 22.48, 0.0013, 23.55, 0.0020, 24.64, 0.0004, 25.74, 0.0005, 26.81, 0.0006, 27.95, 0.0006, 29.03, 0.0001, 30.22, 0.0010, 31.30, 0.0004, 32.48, 0.0001, 33.60, 0.0002, 38.30, 0.0003], [1.00, 0.0674, 1.99, 0.0841, 2.98, 0.0920, 3.99, 0.0328, 4.99, 0.0368, 5.98, 0.0206, 6.99, 0.0246, 8.01, 0.0048, 9.01, 0.0218, 10.03, 0.0155, 11.05, 0.0048, 12.06, 0.0077, 13.00, 0.0020, 14.10, 0.0083, 15.15, 0.0084, 16.18, 0.0015, 17.22, 0.0039, 18.27, 0.0032, 19.34, 0.0026, 20.40, 0.0012, 21.47, 0.0009, 22.54, 0.0008, 23.62, 0.0016, 24.71, 0.0005, 25.82, 0.0004, 26.91, 0.0002, 28.03, 0.0008, 29.17, 0.0002, 30.32, 0.0028, 31.45, 0.0004, 32.61, 0.0005, 33.77, 0.0001, 36.14, 0.0003, 37.32, 0.0002, 38.54, 0.0005, 39.75, 0.0002, 42.23, 0.0002, 48.65, 0.0001], [1.01, 0.0423, 1.99, 0.0240, 2.98, 0.0517, 4.00, 0.0493, 5.00, 0.0324, 6.00, 0.0094, 6.99, 0.0449, 7.99, 0.0050, 9.00, 0.0197, 10.03, 0.0132, 11.03, 0.0009, 12.07, 0.0017, 13.08, 0.0023, 14.12, 0.0094, 15.16, 0.0071, 16.21, 0.0020, 17.25, 0.0005, 18.30, 0.0027, 19.04, 0.0004, 20.43, 0.0022, 21.51, 0.0002, 22.59, 0.0006, 23.72, 0.0018, 24.80, 0.0002, 25.88, 0.0002, 27.03, 0.0002, 28.09, 0.0006, 29.31, 0.0002, 30.46, 0.0004, 31.61, 0.0007, 32.78, 0.0005, 33.95, 0.0001, 36.34, 0.0002, 37.56, 0.0001, 38.80, 0.0001, 40.02, 0.0001, 44.14, 0.0001], [1.00, 0.0669, 1.99, 0.0909, 2.99, 0.0410, 3.98, 0.0292, 4.98, 0.0259, 5.98, 0.0148, 6.98, 0.0319, 7.99, 0.0076, 9.01, 0.0056, 10.02, 0.0206, 11.04, 0.0032, 12.05, 0.0085, 13.08, 0.0040, 14.12, 0.0037, 15.16, 0.0030, 16.20, 0.0013, 17.24, 0.0021, 18.30, 0.0010, 19.36, 0.0015, 20.44, 0.0013, 21.50, 0.0009, 22.60, 0.0015, 23.69, 0.0014, 24.80, 0.0006, 25.87, 0.0002, 27.02, 0.0006, 28.12, 0.0002, 29.28, 0.0003, 30.43, 0.0002, 31.59, 0.0007, 32.79, 0.0001, 35.14, 0.0001, 37.57, 0.0001, 40.03, 0.0002, 41.28, 0.0004, 44.10, 0.0001], [0.99, 0.0421, 1.99, 0.1541, 2.98, 0.0596, 3.98, 0.0309, 4.98, 0.0301, 5.99, 0.0103, 7.00, 0.0240, 8.01, 0.0073, 9.01, 0.0222, 10.04, 0.0140, 11.05, 0.0033, 12.08, 0.0045, 13.13, 0.0009, 14.13, 0.0015, 15.21, 0.0026, 16.24, 0.0003, 17.30, 0.0004, 18.35, 0.0010, 19.39, 0.0003, 20.50, 0.0015, 21.57, 0.0003, 22.68, 0.0011, 23.80, 0.0005, 24.90, 0.0008, 26.02, 0.0002, 27.16, 0.0001, 28.30, 0.0006, 29.48, 0.0002, 31.81, 0.0005, 33.00, 0.0003, 34.21, 0.0001, 37.89, 0.0001], [0.99, 0.0389, 2.00, 0.2095, 3.00, 0.0835, 3.99, 0.0289, 5.00, 0.0578, 5.99, 0.0363, 7.01, 0.0387, 8.01, 0.0056, 9.04, 0.0173, 10.05, 0.0175, 11.08, 0.0053, 12.10, 0.0056, 13.15, 0.0064, 14.19, 0.0036, 15.22, 0.0019, 16.29, 0.0010, 17.36, 0.0017, 18.43, 0.0018, 19.51, 0.0004, 20.60, 0.0011, 21.70, 0.0003, 22.82, 0.0003, 23.95, 0.0001, 25.05, 0.0004, 26.17, 0.0001, 28.50, 0.0003, 29.68, 0.0001, 32.07, 0.0003, 33.28, 0.0004, 34.52, 0.0001], [1.00, 0.1238, 1.99, 0.2270, 3.00, 0.0102, 3.99, 0.0181, 4.98, 0.0415, 6.00, 0.0165, 7.01, 0.0314, 8.02, 0.0148, 9.04, 0.0203, 10.05, 0.0088, 11.07, 0.0062, 12.11, 0.0070, 13.14, 0.0054, 14.19, 0.0028, 15.24, 0.0044, 16.30, 0.0029, 17.38, 0.0009, 18.45, 0.0026, 19.56, 0.0003, 20.65, 0.0025, 21.74, 0.0014, 22.87, 0.0013, 23.99, 0.0007, 25.15, 0.0002, 27.46, 0.0004, 28.39, 0.0006, 28.65, 0.0004, 29.85, 0.0001, 31.05, 0.0002, 32.27, 0.0003, 33.52, 0.0002, 34.76, 0.0003], [1.00, 0.1054, 2.00, 0.2598, 2.99, 0.0369, 3.98, 0.0523, 4.99, 0.0020, 5.99, 0.0051, 7.00, 0.0268, 8.01, 0.0027, 9.04, 0.0029, 10.05, 0.0081, 11.08, 0.0047, 12.12, 0.0051, 13.16, 0.0091, 14.19, 0.0015, 15.27, 0.0030, 16.34, 0.0017, 17.42, 0.0006, 18.51, 0.0003, 19.61, 0.0007, 20.72, 0.0003, 21.84, 0.0001, 22.99, 0.0010, 24.13, 0.0001, 28.44, 0.0001, 30.09, 0.0001], [0.99, 0.0919, 2.00, 0.0418, 2.99, 0.0498, 3.99, 0.0135, 4.99, 0.0026, 6.00, 0.0155, 7.01, 0.0340, 8.02, 0.0033, 9.04, 0.0218, 10.08, 0.0084, 11.11, 0.0057, 12.15, 0.0051, 13.21, 0.0043, 14.25, 0.0015, 15.31, 0.0023, 16.40, 0.0008, 17.48, 0.0004, 18.59, 0.0016, 19.71, 0.0010, 20.84, 0.0018, 21.98, 0.0002, 23.11, 0.0013, 24.26, 0.0003, 26.67, 0.0002, 29.12, 0.0002, 30.37, 0.0002, 31.62, 0.0003, 32.92, 0.0001], [0.99, 0.1174, 1.99, 0.1126, 2.99, 0.0370, 3.99, 0.0159, 5.01, 0.0472, 6.01, 0.0091, 7.03, 0.0211, 8.05, 0.0015, 9.07, 0.0098, 10.11, 0.0038, 11.15, 0.0042, 12.20, 0.0018, 13.24, 0.0041, 14.32, 0.0033, 15.41, 0.0052, 16.49, 0.0001, 17.61, 0.0004, 18.71, 0.0004, 19.84, 0.0004, 20.99, 0.0002, 22.14, 0.0006, 23.31, 0.0006, 24.50, 0.0004, 25.70, 0.0002, 28.09, 0.0002, 28.66, 0.0002, 32.00, 0.0001], [1.00, 0.1085, 2.00, 0.1400, 2.99, 0.0173, 3.99, 0.0229, 5.00, 0.0272, 6.02, 0.0077, 7.03, 0.0069, 8.04, 0.0017, 9.08, 0.0045, 10.10, 0.0030, 11.15, 0.0040, 12.20, 0.0007, 13.25, 0.0019, 14.32, 0.0008, 15.42, 0.0024, 16.50, 0.0002, 17.59, 0.0005, 18.71, 0.0003, 19.83, 0.0002, 20.98, 0.0005, 23.29, 0.0008], [1.00, 0.0985, 2.00, 0.1440, 2.99, 0.0364, 3.99, 0.0425, 5.00, 0.0190, 6.01, 0.0089, 7.03, 0.0278, 8.04, 0.0006, 9.07, 0.0083, 10.10, 0.0021, 11.14, 0.0050, 12.18, 0.0005, 13.26, 0.0036, 14.33, 0.0005, 15.41, 0.0026, 17.62, 0.0004, 18.75, 0.0004, 19.89, 0.0003, 21.04, 0.0012, 22.21, 0.0002, 23.38, 0.0004, 27.04, 0.0001], [0.99, 0.1273, 2.00, 0.1311, 2.99, 0.0120, 4.00, 0.0099, 5.00, 0.0235, 6.02, 0.0068, 7.03, 0.0162, 8.06, 0.0009, 9.08, 0.0083, 10.12, 0.0014, 11.17, 0.0050, 12.24, 0.0010, 13.29, 0.0013, 14.39, 0.0022, 15.48, 0.0011, 16.59, 0.0002, 17.70, 0.0003, 18.84, 0.0010, 20.00, 0.0003, 21.17, 0.0003, 23.56, 0.0004, 28.79, 0.0003], [1.00, 0.1018, 2.00, 0.1486, 3.00, 0.0165, 4.00, 0.0186, 5.01, 0.0194, 6.02, 0.0045, 7.04, 0.0083, 8.06, 0.0012, 9.10, 0.0066, 10.15, 0.0009, 11.19, 0.0008, 12.26, 0.0011, 13.34, 0.0028, 14.45, 0.0006, 15.53, 0.0009, 16.66, 0.0002, 17.79, 0.0006, 18.94, 0.0005, 20.11, 0.0003, 21.29, 0.0005, 22.49, 0.0003, 23.73, 0.0005, 26.22, 0.0001, 27.52, 0.0001, 28.88, 0.0002], [1.00, 0.1889, 1.99, 0.1822, 3.00, 0.0363, 4.00, 0.0047, 5.01, 0.0202, 6.03, 0.0053, 7.05, 0.0114, 8.01, 0.0002, 9.13, 0.0048, 10.17, 0.0010, 11.23, 0.0033, 12.30, 0.0010, 13.38, 0.0006, 14.50, 0.0002, 15.62, 0.0010, 20.27, 0.0001, 21.47, 0.0001], [1.00, 0.0522, 1.99, 0.0763, 2.99, 0.0404, 4.00, 0.0139, 5.01, 0.0185, 6.01, 0.0021, 7.06, 0.0045, 8.09, 0.0002, 9.11, 0.0003, 10.17, 0.0006, 11.25, 0.0004, 12.32, 0.0005, 13.40, 0.0003, 14.53, 0.0003, 15.65, 0.0007, 16.80, 0.0001, 17.95, 0.0002, 19.14, 0.0006, 20.34, 0.0002, 21.56, 0.0003], [0.99, 0.1821, 1.99, 0.0773, 3.00, 0.0125, 4.01, 0.0065, 5.01, 0.0202, 6.03, 0.0071, 7.05, 0.0090, 8.08, 0.0006, 9.13, 0.0008, 10.18, 0.0013, 11.25, 0.0010, 12.33, 0.0012, 13.42, 0.0006, 14.54, 0.0005, 15.65, 0.0004, 17.97, 0.0002, 19.15, 0.0001], [1.00, 0.1868, 2.00, 0.0951, 3.00, 0.0147, 4.01, 0.0134, 5.02, 0.0184, 6.04, 0.0132, 7.06, 0.0011, 8.11, 0.0008, 9.15, 0.0010, 10.22, 0.0012, 11.30, 0.0011, 12.40, 0.0003, 13.11, 0.0004, 13.49, 0.0002, 14.62, 0.0003, 15.77, 0.0001], [1.00, 0.1933, 2.00, 0.0714, 3.00, 0.0373, 4.00, 0.0108, 5.02, 0.0094, 6.02, 0.0010, 7.07, 0.0022, 8.11, 0.0002, 9.16, 0.0065, 10.23, 0.0015, 11.31, 0.0023, 12.40, 0.0003, 13.53, 0.0014, 14.66, 0.0002, 15.81, 0.0011, 18.20, 0.0002, 19.41, 0.0001], [0.99, 0.2113, 1.99, 0.0877, 3.00, 0.0492, 4.01, 0.0094, 5.02, 0.0144, 6.04, 0.0103, 7.07, 0.0117, 8.12, 0.0006, 9.19, 0.0019, 10.25, 0.0007, 11.35, 0.0017, 12.45, 0.0010, 13.58, 0.0003, 14.74, 0.0003, 15.91, 0.0003, 19.57, 0.0002], [0.99, 0.2455, 1.99, 0.0161, 3.00, 0.0215, 4.01, 0.0036, 5.03, 0.0049, 6.04, 0.0012, 7.09, 0.0036, 8.14, 0.0011, 9.21, 0.0009, 10.30, 0.0001, 11.40, 0.0012, 12.50, 0.0001, 13.66, 0.0005, 14.84, 0.0001], [1.00, 0.1132, 2.00, 0.0252, 3.00, 0.0292, 4.01, 0.0136, 5.03, 0.0045, 6.06, 0.0022, 7.11, 0.0101, 8.17, 0.0004, 9.23, 0.0010, 10.33, 0.0012, 11.44, 0.0013, 12.58, 0.0011, 13.75, 0.0002, 14.93, 0.0005, 16.14, 0.0002], [1.00, 0.1655, 2.00, 0.0445, 3.00, 0.0120, 4.00, 0.0038, 5.02, 0.0015, 6.07, 0.0038, 7.11, 0.0003, 8.19, 0.0002, 9.25, 0.0010, 10.36, 0.0011, 11.48, 0.0005, 12.63, 0.0002, 13.79, 0.0003, 16.24, 0.0002], [0.99, 0.3637, 1.99, 0.0259, 3.01, 0.0038, 4.01, 0.0057, 5.03, 0.0040, 6.07, 0.0067, 7.12, 0.0014, 8.19, 0.0004, 9.27, 0.0003, 10.38, 0.0002, 12.67, 0.0001], [1.00, 0.1193, 2.00, 0.0230, 3.00, 0.0104, 4.01, 0.0084, 5.04, 0.0047, 6.08, 0.0035, 7.13, 0.0041, 8.20, 0.0002, 9.29, 0.0005, 10.40, 0.0005, 11.53, 0.0003, 12.70, 0.0002, 13.91, 0.0002], [1.00, 0.0752, 2.00, 0.0497, 3.00, 0.0074, 4.02, 0.0076, 5.05, 0.0053, 6.09, 0.0043, 7.15, 0.0024, 8.22, 0.0001, 9.32, 0.0006, 10.45, 0.0002, 11.58, 0.0001, 12.78, 0.0001, 15.22, 0.0001], [1.00, 0.2388, 2.00, 0.0629, 3.01, 0.0159, 4.04, 0.0063, 5.07, 0.0051, 6.12, 0.0045, 7.19, 0.0026, 8.29, 0.0015, 9.43, 0.0001, 11.75, 0.0002], [1.00, 0.1919, 2.01, 0.0116, 3.01, 0.0031, 4.03, 0.0090, 5.07, 0.0061, 6.13, 0.0036, 7.19, 0.0013, 8.30, 0.0016, 9.13, 0.0001, 10.59, 0.0002, 11.78, 0.0002], [1.00, 0.1296, 2.00, 0.0135, 3.01, 0.0041, 4.04, 0.0045, 5.09, 0.0028, 6.14, 0.0046, 7.23, 0.0007, 8.32, 0.0007, 9.50, 0.0001], [1.00, 0.0692, 2.00, 0.0209, 3.02, 0.0025, 4.05, 0.0030, 5.09, 0.0047, 6.17, 0.0022, 7.25, 0.0015, 8.36, 0.0015, 9.53, 0.0010, 10.69, 0.0001, 13.40, 0.0001], [1.00, 0.1715, 2.00, 0.0142, 3.01, 0.0024, 4.03, 0.0015, 5.07, 0.0017, 6.13, 0.0018, 7.22, 0.0009, 8.33, 0.0014, 9.51, 0.0007, 10.69, 0.0002], [1.00, 0.1555, 2.01, 0.0148, 3.02, 0.0007, 4.06, 0.0006, 5.10, 0.0005, 6.16, 0.0008, 7.26, 0.0009, 8.39, 0.0008, 9.58, 0.0002], [1.00, 0.1357, 2.00, 0.0116, 3.02, 0.0026, 4.04, 0.0009, 5.09, 0.0004, 6.17, 0.0005, 7.27, 0.0002, 8.40, 0.0001], [1.00, 0.2185, 2.01, 0.0087, 3.03, 0.0018, 4.06, 0.0025, 5.11, 0.0020, 6.20, 0.0012, 7.32, 0.0005, 8.46, 0.0001, 9.66, 0.0003], [1.00, 0.2735, 2.00, 0.0038, 3.02, 0.0008, 4.06, 0.0012, 5.12, 0.0008, 6.22, 0.0011, 7.35, 0.0003, 8.50, 0.0002], [1.00, 0.1441, 1.99, 0.0062, 3.01, 0.0023, 4.05, 0.0011, 5.11, 0.0012, 6.20, 0.0003, 7.33, 0.0004, 8.50, 0.0001], [1.00, 0.0726, 2.01, 0.0293, 3.03, 0.0022, 5.14, 0.0005, 6.26, 0.0011, 7.41, 0.0002, 8.63, 0.0002], [1.00, 0.0516, 2.00, 0.0104, 3.02, 0.0029, 5.15, 0.0002, 6.27, 0.0001], [1.00, 0.0329, 2.00, 0.0033, 3.03, 0.0013, 4.10, 0.0005, 5.19, 0.0004, 6.32, 0.0002], [1.00, 0.0179, 1.99, 0.0012, 3.04, 0.0005, 4.10, 0.0017, 5.20, 0.0005, 6.35, 0.0001], [1.00, 0.0334, 2.01, 0.0033, 3.04, 0.0011, 4.13, 0.0003, 5.22, 0.0003], [0.99, 0.0161, 2.01, 0.0100, 3.04, 0.0020, 4.13, 0.0003], [1.00, 0.0475, 1.99, 0.0045, 3.03, 0.0035, 4.12, 0.0011], [1.00, 0.0593, 2.00, 0.0014, 4.17, 0.0002], [1.00, 0.0249, 2.01, 0.0016], [1.00, 0.0242, 2.00, 0.0038, 4.19, 0.0002], [1.00, 0.0170, 2.02, 0.0030], [1.00, 0.0381, 2.00, 0.0017, 3.09, 0.0002], [1.00, 0.0141, 2.03, 0.0005, 3.11, 0.0003, 4.26, 0.0001], [1.00, 0.0122, 2.03, 0.0024], [1.00, 0.0107, 2.07, 0.0007, 3.12, 0.0004], [1.00, 0.0250, 2.02, 0.0026, 3.15, 0.0002], [1.01, 0.0092], [1.01, 0.0102, 2.09, 0.0005], [1.00, 0.0080, 2.00, 0.0005, 3.19, 0.0001], [1.01, 0.0298, 2.01, 0.0005]] def lbj_piano(start, dur, freq, amp, *args) pfreq, degree, distance, reverb_amount = nil optkey(args, binding, [:pfreq, freq], [:degree, 45.0], [:distance, 1.0], [:reverb_amount, 0.0]) get_piano_partials = lambda do |frq| Piano_Spectra[(12 * (log(frq / 32.703) / log(2))).round] end make_piano_ampfun = lambda do |dr| release_amp = db2linear($clm_db_drop_per_second * dr) attack_time = $clm_piano_attack_duration * 100.0 / dr [0, 0, attack_time / 4, 1.0, attack_time, 1.0, 100, release_amp] end # This thing sounds pretty good down low, below middle c or so. # Unfortunately, there are some tens of partials down there and # we're using exponential envelopes. You're going to wait for a # long long time just to hear a single low note. The high notes # sound pretty rotten--they just don't sparkle; I have a feeling # that this is due to the low amplitude of the original data, and # the lack of mechanical noise. # # The only thing you can do to alter the sound of a piano note is to # set the pfreq parameter. Pfreq is used to look up the partials. # By default, it's set to the requested frequency. Setting it to a # neighboring freq is useful when you're repeating notes. Note that # there's no nyquist detection; a high freq with a low pfreq, will # give you fold over (hmmm...maybe I can get those high notes to # sparkle after all). partials = normalize_partials(get_piano_partials.call(pfreq)) newdur = dur + $clm_piano_attack_duration + $clm_piano_release_duration env1dur = newdur - $clm_piano_release_duration env1samples = (env1dur * @srate).floor siz = (partials.length / 2).floor oscils = Array.new(siz) alist = make_vct(siz) ampfun1 = make_piano_ampfun.call(env1dur) ampenv1 = make_env(:envelope, ampfun1, :scaler, amp, :duration, env1dur, :base, 10000.0) releaseamp = ampfun1.last ampenv2 = make_env(:envelope, [0, 1, 100, 0], :scaler, amp * releaseamp, :duration, env1dur, :base, 1.0) sktr = j = 0 0.step(partials.length - 1, 2) do |i| alist[j] = partials[i + 1] oscils[j] = make_oscil(:frequency, partials[i] * freq) j += 1 end run_instrument(start, newdur, :degree, degree, :distance, distance, :reverb_amount, reverb_amount) do sktr += 1 let(0.0) do |sum| oscils.each_with_index do |osc, i| sum = sum + oscil(osc) * alist[i] end sum * env(((sktr > env1samples) ? ampenv2 : ampenv1)) end end end def lbj_piano_test(start = 0.0, dur = 1.0) lbj_piano(start, dur, 440.0, 0.5) $now = start + dur + 0.24 + 0.2 end # RESFLT def resflt(start, dur, driver, ranfreq, noiamp, noifun, cosamp, cosfreq1, cosfreq0, cosnum, ampcosfun, freqcosfun, frq1, r1, g1, frq2, r2, g2, frq3, r3, g3, *args) degree, distance, reverb_amount = nil optkey(args, binding, [:degree, 0.0], [:distance, 1.0], [:reverb_amount, 0.005]) # driver=0 -- use sum of cosines to drive the filter, # driver=1 -- use white noise # if noise used, ranfreq=frequency of random number generator, # noiamp=amplitude thereof, # noifun=amplitude envelope on white noise # if sum-of-cosines (i.e. a band-limited pulse train), # cosamp=amplitude of pulse train, # cosfreq1=top frequency (given freqcosfun) # (i.e. pulse frequency) # cosfreq0=bottom frequency, # cosnum=number of cosines in the pulse, # ampcosfun=amplitude envelope on pulse train # freqcosfun=frequency envelope on pulse train # There are then 3 resonators, centered at frq1, frq2, frq3, # with pole-radius r1, r2, and r3 respectively, and # with gains of g1, g2, and g3. f1 = make_two_pole(frq1, r1) f2 = make_two_pole(frq2, r2) f3 = make_two_pole(frq3, r3) with_noise = (driver == 1) frqf = if with_noise nil else make_env(:envelope, freqcosfun, :duration, dur, :scaler, hz2radians(cosfreq1 - cosfreq0)) end ampf = if with_noise make_env(:envelope, noifun, :scaler, noiamp, :duration, dur) else make_env(:envelope, ampcosfun, :scaler, cosamp, :duration, dur) end rn = if with_noise make_rand(:frequency, ranfreq) else nil end cn = if with_noise nil else make_sum_of_cosines(:frequency, cosfreq0, :cosines, cosnum) end if with_noise run_instrument(start, dur, :distance, distance, :degree, degree, :reverb_amount, reverb_amount) do input1 = env(ampf) * rand(rn) two_pole(f1, input1 * g1) + two_pole(f2, input1 * g2) + two_pole(f3, input1 * g3) end else run_instrument(start, dur, :distance, distance, :degree, degree, :reverb_amount, reverb_amount) do input1 = env(ampf) * sum_of_cosines(cn, env(frqf)) two_pole(f1, input1 * g1) + two_pole(f2, input1 * g2) + two_pole(f3, input1 * g3) end end end def resflt_test(start = 0.0, dur = 1.0) $now = start resflt($now, dur, 0, 0, 0, nil, 0.1, 200, 230, 10, [0, 0, 50, 1, 100, 0], [0, 0, 100, 1], 500, 0.995, 0.1, 1000, 0.995, 0.1, 2000, 0.995, 0.1) $now += dur + 0.2 resflt($now, dur, 1, 10000, 0.01, [0, 0, 50, 1, 100, 0], 0, 0, 0, 0, nil, nil, 500, 0.995, 0.1, 1000, 0.995, 0.1, 2000, 0.995, 0.1) $now += dur + 0.2 end # SCRATCH def scratch(start, file, src_ratio, turntable) assert_type(File.exist?(file), file, 1, "an existing file") f = make_file2sample(file) turn_i = 1 turns = turntable.length cur_sample = seconds2samples(turntable[0]) turn_sample = seconds2samples(turntable[turn_i]) rd = make_src(:srate, src_ratio) forwards = (src_ratio > 0.0) set_mus_increment(rd, -src_ratio) if forwards and turn_sample < cur_sample turning = 0 last_val = last_val2 = 0.0 run_instrument(start, ws_duration(file)) do break if turn_i >= turns val = src(rd, 0.0, lambda do |dir| inval = file2sample(f, cur_sample) cur_sample += dir inval end) if turning.zero? # we past turn point going forwards if forwards and cur_sample >= turn_sample turning = 1 # we past turn point going backwards elsif (not forwards) and cur_sample <= turn_sample turning = -1 end else # wait for an inflection... if (last_val2 <= last_val and last_val >= val) or (last_val2 >= last_val and last_val <= val) turn_i += 1 if turn_i < turns turn_sample = seconds2samples(turntable[turn_i]) forwards = (not forwards) set_mus_increment(rd, -mus_increment(rd)) end turning = 0 end end last_val2, last_val = last_val, val val end mus_close(f) end def scratch_test(start = 0.0, dur = 1.0) scratch(start, "fyow.snd", [dur, 1.5].min, [0.0, 0.5, 0.25, 1.0]) $now = start + mus_sound_duration("fyow.snd") + 0.2 end # PINS # # spectral modeling (SMS) def pins(start, dur, file, amp, *args) assert_type(File.exist?(file), file, 2, "an existing file") transposition, time_scaler, fftsize, highest_bin, max_peaks, attack = nil optkey(args, binding, [:transposition, 1.0], # this can be used to transpose the sound [:time_scaler, 1.0], # this can make things happen faster # (< 1.0)/slower (> 1.0) in the output [:fftsize, 256], # should be a power of 2 # at 22050 srate, this is ok for # sounds above 300Hz or so, below that # you need 512 or 1024, at 44100, # probably best to double these sizes # -- it takes some searching # sometimes. [:highest_bin, 128], # how high in fft data should we search for pks [:max_peaks, 16], # how many spectral peaks to track at the max :attack) # whether to use original attack via time domain # splice do the sliding fft shuffle, # translate to polar coordinates, find # spectral peaks, match with current, # do some interesting transformation, # resynthesize using oscils All the # envelopes are created on the fly. # max-peaks is how many of these peaks # we are willing to track at any given # time. fil = make_file2sample(file) file_duration = ws_duration(file) fdr = make_vct(fftsize) fdi = make_vct(fftsize) window = make_fft_window(Blackman2_window, fftsize) fftamps = make_vct(fftsize) max_oscils = 2 * max_peaks current_peak_freqs = make_vct(max_oscils) last_peak_freqs = make_vct(max_oscils) current_peak_amps = make_vct(max_oscils) last_peak_amps = make_vct(max_oscils) peak_amps = make_vct(max_peaks) peak_freqs = make_vct(max_peaks) resynth_oscils = make_array(max_oscils) do make_oscil(:frequency, 0) end # run-time generated amplitude and frequency envelopes amps = make_vct(max_oscils) rates = make_vct(max_oscils) freqs = make_vct(max_oscils) sweeps = make_vct(max_oscils) lowest_magnitude = 0.001 hop = (fftsize / 4).floor outhop = (time_scaler * hop).floor ifreq = 1.0 / outhop ihifreq = hz2radians(ifreq) # integrate Blackman-Harris window = .42323*window fftscale = 1.0 / (fftsize * 0.42323) # width and shift by fftsize fft_mag = @srate / fftsize furthest_away_accepted = 0.1 filptr = 0 cur_oscils = max_oscils ramped = (attack or 0) splice_attack = attack.kind_of?(Numeric) attack_size = (attack or 1) ramp_ind = 0 ramped_attack = make_vct(attack_size) if (dur / time_scaler) > file_duration error("%s is %1.3f seconds long, \ but we'll need %1.3f seconds of data for this note", file, file_duration, dur / time_scaler) end trigger = outhop vct_scale!(window, fftscale) run_instrument(start, dur) do if splice_attack ramp = 1.0 / attack_size # my experience in translating SMS, and rumor via Greg Sandell # leads me to believe that there is in fact no way to model some # attacks successfully in this manner, so this block simply # splices the original attack on to the rest of the note. # "attack" is the number of samples to include bodily. out_val = amp * file2sample(fil, filptr) filptr += 1 if filptr > attack_size mult = 1.0 attack_size.times do |j| ramped_attack[j] = mult * file2sample(fil, filptr + j) mult -= ramp end splice_attack = false end # if out_val out_val else if trigger >= outhop peaks = 0 # get next block of data and apply window to it trigger = 0 fftsize.times do |j| fdr[j] = window[j] * file2sample(fil, filptr) filptr += 1 end vct_fill!(fdi, 0.0) filptr -= fftsize - hop # get the fft mus_fft(fdr, fdi, fftsize, 1) # change to polar coordinates (ignoring phases) highest_bin.times do |j| # no need to paw through the upper half # (so (<= highest-bin (floor fft-size 2))) x = fdr[j] y = fdi[j] fftamps[j] = 2.0 * sqrt(x * x + y * y) end max_oscils.times do |j| last_peak_freqs[j] = current_peak_freqs[j] last_peak_amps[j] = current_peak_amps[j] current_peak_amps[j] = 0.0 end vct_fill!(peak_amps, 0.0) ra = fftamps[0] la = ca = 0.0 # search for current peaks following Xavier Serra's recommendations in # "A System for Sound Analysis/Transformation/Synthesis # Based on a Deterministic Plus Stochastic Decomposition" highest_bin.times do |j| la, ca, ra = ca, ra, fftamps[j] if ca > lowest_magnitude and ca > ra and ca > la # found a local maximum above the current threshold # (its bin number is j-1) logla = log10(la) logca = log10(ca) logra = log10(ra) offset = (0.5 * (logla - logra)) / (logla + -2 * logca + logra) amp_1 = 10.0 ** (logca - (0.25 * (logla - logra) * offset)) freq = fft_mag * (j + offset - 1) if peaks == max_peaks # gotta either flush this peak, # or find current lowest and flush him minp = 0 minpeak = peak_amps[0] 1.upto(max_peaks - 1) do |k| if peak_amps[k] < minpeak minp = k minpeak = peak_amps[k] end end if amp_1 > minpeak peak_freqs[minp] = freq peak_amps[minp] = amp_1 end else peak_freqs[peaks] = freq peak_amps[peaks] = amp_1 peaks += 1 end end end # now we have the current peaks -- match them to the previous # set and do something interesting with the result the end # results are reflected in the updated values in the rates and # sweeps arrays. search for fits between last and current, # set rates/sweeps for those found try to go by largest amp # first peaks.times do |j| maxp = 0 maxpk = peak_amps[0] 1.upto(max_peaks - 1) do |k| if peak_amps[k] > maxpk maxp = k maxpk = peak_amps[k] end end # now maxp points to next largest unmatched peak if maxpk > 0.0 closestp = -1 closestamp = 10.0 current_freq = peak_freqs[maxp] icf = 1.0 / current_freq max_peaks.times do |k| if last_peak_amps[k] > 0.0 closeness = icf * (last_peak_freqs[k] - current_freq).abs if closeness < closestamp closestamp = closeness closestp = k end end end if closestamp < furthest_away_accepted # peak_amp is transferred to appropriate current_amp and zeroed, current_peak_amps[closestp] = peak_amps[maxp] peak_amps[maxp] = 0.0 current_peak_freqs[closestp] = current_freq end end end max_peaks.times do |j| if peak_amps[j] > 0.0 # find a place for a new oscil and start it up new_place = -1 max_oscils.times do |k| if last_peak_amps[k].zero? and current_peak_amps[k].zero? new_place = k break end end current_peak_amps[new_place] = peak_amps[j] peak_amps[j] = 0.0 current_peak_freqs[new_place] = peak_freqs[j] last_peak_freqs[new_place] = peak_freqs[j] set_mus_frequency(resynth_oscils[new_place], transposition * peak_freqs[j]) end end cur_oscils = 0 max_oscils.times do |j| rates[j] = ifreq * (current_peak_amps[j] - last_peak_amps[j]) if current_peak_amps[j].nonzero? or last_peak_amps[j].nonzero? cur_oscils = j end sweeps[j] = ihifreq * transposition * (current_peak_freqs[j] - last_peak_freqs[j]) end cur_oscils += 1 end # run oscils, update envelopes trigger += 1 if ramped.zero? sum = 0.0 else sum = ramped_attack[ramp_ind] ramp_ind += 1 ramped = 0 if ramp_ind == ramped end cur_oscils.times do |j| if amps[j].nonzero? or rates[j].nonzero? sum = sum + amps[j] * oscil(resynth_oscils[j], freqs[j]) amps[j] += rates[j] freqs[j] += sweeps[j] end end # else out_val amp * sum end end mus_close(fil) end def pins_test(start = 0.0, dur = 1.0) pins(start, dur, "fyow.snd", 1, :time_scaler, 2) $now = start + dur + 0.2 end # ZC def zc(start, dur, freq, amp, length1, length2, feedback) s = make_pulse_train(:frequency, freq) d0 = make_comb(:size, length1, :max_size, [length1, length2].max + 1, :scaler, feedback) zenv = make_env(:envelope, [0, 0, 1, 1], :scaler, length2 - length1, :duration, dur) run_instrument(start, dur) do comb(d0, amp * pulse_train(s), env(zenv)) end end def zc_test(start = 0.0, dur = 1.0) $now = start zc($now, dur, 100, 0.4, 20, 100, 0.95) $now += dur + 0.2 zc($now, dur, 100, 0.4, 100, 20, 0.95) $now += dur + 0.2 end # ZN # # notches are spaced at srate/len, feedforward sets depth thereof so # sweep of len from 20 to 100 sweeps the notches down from 1000 Hz to # ca 200 Hz so we hear our downward glissando beneath the pulses. def zn(start, dur, freq, amp, length1, length2, feedforward) s = make_pulse_train(:frequency, freq) d0 = make_notch(:size, length1, :max_size, [length1, length2].max + 1, :scaler, feedforward) zenv = make_env(:envelope, [0, 0, 1, 1], :scaler, length2 - length1, :duration, dur) run_instrument(start, dur) do notch(d0, amp * pulse_train(s), env(zenv)) end end def zn_test(start = 0.0, dur = 1.0) $now = start zn($now, dur, 100, 0.5, 20, 100, 0.95) $now += dur + 0.2 zn($now, dur, 100, 0.5, 100, 20, 0.95) $now += dur + 0.2 end # ZA def za(start, dur, freq, amp, length1, length2, feedback, feedforward) s = make_pulse_train(:frequency, freq) d0 = make_all_pass(:feedback, feedback, :feedforward, feedforward, :size, length1, :max_size, [length1, length2].max + 1) zenv = make_env(:envelope, [0, 0, 1, 1], :scaler, length2 - length1, :duration, dur) run_instrument(start, dur) do all_pass(d0, amp * pulse_train(s), env(zenv)) end end def za_test(start = 0.0, dur = 1.0) $now = start za($now, dur, 100, 0.3, 20, 100, 0.95, 0.95) $now += dur + 0.2 za($now, dur, 100, 0.3, 100, 20, 0.95, 0.95) $now += dur + 0.2 end # CLM-EXPSRC def clm_expsrc(start, dur, in_file, exp_ratio, src_ratio, amp, rev = false, start_in_file = 0) assert_type(File.exist?(in_file), in_file, 0, "an existing file") stf = (start_in_file * srate(in_file)).floor fda = make_readin(in_file, :channel, 0, :start, stf) exa = make_granulate(lambda do |dir| readin(fda) end, :expansion, exp_ratio) srca = make_src(lambda do |dir| granulate(exa) end, :srate, src_ratio) two_chans = (channels(in_file) == 2) and (channels(@ws_output) == 2) revit = @reverb and rev beg = seconds2samples(start) fin = seconds2samples(dur) + beg # to satisfy with_sound-option :info and :notehook with_sound_info(get_func_name, start, dur) if two_chans fdb = make_readin(in_file, :channel, 1, :srate, stf) exb = make_granulate(lambda do |dir| readin(fdb) end, :expansion, exp_ratio) srcb = make_src(lambda do |dir| granulate(exb) end, :srate, src_ratio) if revit rev_amp = rev * 0.5 (beg..fin).each do |i| vala = src(srca) * amp valb = src(srcb) * amp outa(i, vala, @ws_output) outb(i, valb, @ws_output) outa(i, (vala + valb) * rev_amp, @reverb) end else # !revit (beg..fin).each do |i| outa(i, src(srca) * amp, @ws_output) outb(i, src(srcb) * amp, @ws_output) end end # revit else # !two_chans if revit rev_amp = rev (beg..fin).each do |i| vala = src(srca) * amp outa(i, vala, @ws_output) outa(i, vala * rev_amp, @ws_reverb) end else # !revit (beg..fin).each do |i| outa(i, src(srca) * amp, @ws_output) end end # revit end # two_chans end def clm_expsrc_test(start = 0.0, dur = 1.0) clm_expsrc(start, dur, "oboe.snd", 2.0, 1.0, 1.0, 0.05) $now = start + dur + 0.2 end # EXP-SND # # granulate with envelopes on the expansion amount, segment envelope # shape, segment length, hop length, and input file resampling rate def exp_snd(file, start, dur, amp, exp_amt = 1.0, ramp = 0.4, seglen = 0.15, sr = 1.0, hop = 0.05, ampenv = nil) assert_type(File.exist?(file), file, 0, "an existing file") f0 = make_ws_reader(file, :start, 0) expenv = make_env(:envelope, (exp_amt.kind_of?(Array) ? exp_amt : [0, exp_amt, 1, exp_amt]), :duration, dur) lenenv = make_env(:envelope, (seglen.kind_of?(Array) ? seglen : [0, seglen, 1, seglen]), :duration, dur) max_seg_len, initial_seg_len = if seglen if seglen.kind_of?(Array) [max_envelope(seglen), seglen[1]] else [seglen, seglen] end else [0.15, 0.15] end scaler_amp = ((max_seg_len > 0.15) ? ((0.6 * 0.15) / max_seg_len) : 0.6) srenv = make_env(:envelope, (sr.kind_of?(Array) ? sr : [0, sr, 1, sr]), :duration, dur) rampdata = (ramp.kind_of?(Array) ? ramp : [0, ramp, 1, ramp]) rampenv = make_env(:envelope, rampdata, :duration, dur) initial_ramp_time = if ramp if ramp.kind_of?(Array) ramp[1] else ramp end else 0.4 end hopenv = make_env(:envelope, (hop.kind_of?(Array) ? hop : [0, hop, 1, hop]), :duration, dur) max_out_hop, initial_out_hop = if hop if hop.kind_of?(Array) [max_envelope(hop), hop[1]] else [hop, hop] end else [0.05, 0.05] end min_exp_amt, initial_exp_amt = if exp_amt if exp_amt.kind_of?(Array) [min_envelope(exp_amt), exp_amt[1]] else [exp_amt, exp_amt] end else [1.0, 1.0] end max_in_hop = max_out_hop / min_exp_amt.to_f max_len = (@srate * ([max_out_hop, max_in_hop].max + max_seg_len)).ceil ampe = make_env(:envelope, (ampenv or [0, 0, 0.5, 1, 1, 0]), :scaler, amp, :duration, dur) ex_a = make_granulate(:input, lambda do |dir| ws_readin(f0) end, :expansion, initial_exp_amt, :max_size, max_len, :ramp, initial_ramp_time, :hop, initial_out_hop, :length, initial_seg_len, :scaler, scaler_amp) ex_samp = next_samp = 0.0 vol = env(ampe) val_a0 = vol * granulate(ex_a) val_a1 = vol * granulate(ex_a) if min_envelope(rampdata) <= 0.0 or max_envelope(rampdata) >= 0.5 error("ramp argument to expand must always be between 0.0 and 0.5: %1.3f", ramp) else run_instrument(start, dur) do expa = env(expenv) # current expansion amount segl = env(lenenv) # current segment length resa = env(srenv) # current resampling increment rmpl = env(rampenv) # current ramp length (0 to 0.5) hp = env(hopenv) # current hop size # now we set the granulate generator internal state to reflect all # these envelopes sl = (segl * @srate).floor rl = (rmpl * sl).floor vol = env(ampe) set_mus_length(ex_a, sl) set_mus_ramp(ex_a, rl) set_mus_frequency(ex_a, hp) set_mus_increment(ex_a, expa) next_samp += resa if next_samp > (ex_samp + 1) (next_samp - ex_samp).floor.times do val_a0, val_a1 = val_a1, vol * granulate(ex_a) ex_samp += 1 end end if next_samp == ex_samp val_a0 else val_a0 + (next_samp - ex_samp) * (val_a1 - val_a0) end end close_ws_reader(f0) end end def exp_snd_test(start = 0.0, dur = 1.0) $now = start exp_snd("fyow.snd", $now, dur, 1, [0, 1, 1, 3], 0.4, 0.15, [0, 2, 1, 0.5], 0.05) $now += dur + 0.2 exp_snd("oboe.snd", $now, dur, 1, [0, 1, 1, 3], 0.4, 0.15, [0, 2, 1, 0.5], 0.2) $now += dur + 0.2 end # EXPFIL Grn = Struct.new("Grn", :rampval, :rampinc, :loc, :segctr, :whichseg, :ramplen, :steadylen, :trigger) def expfil(start, dur, hopsecs, rampsecs, steadysecs, file1, file2) assert_type(File.exist?(file1), file1, 5, "an existing file") assert_type(File.exist?(file2), file2, 6, "an existing file") fil1 = make_file2sample(file1) fil2 = make_file2sample(file2) hop = seconds2samples(hopsecs) ramplen = seconds2samples(rampsecs) steadylen = seconds2samples(steadysecs) grn1 = Grn.new(0.0, 1.0 / ramplen, 0, 0, 0, ramplen, steadylen, 0) grn2 = Grn.new(0.0, 1.0 / ramplen, 0, 0, 0, ramplen, steadylen, 0) beg = seconds2samples(start) out1 = beg out2 = hop + beg run_instrument(start, dur) do |i| val = 0.0 if i == out1 inval = ina(grn1.loc, fil1) grn1.loc += 1 if grn1.whichseg.zero? # ramp-up inval *= grn1.rampval grn1.rampval += grn1.rampinc grn1.segctr += 1 if grn1.segctr == grn1.ramplen grn1.segctr = 0 grn1.whichseg += 1 end else if grn1.whichseg == 1 # steady-state grn1.segctr += 1 if grn1.segctr == grn1.steadylen grn1.segctr = 0 grn1.whichseg += 1 end else # ramp-down inval *= grn1.rampval grn1.segctr += 1 grn1.rampval -= grn1.rampinc if grn1.segctr == grn1.ramplen grn1.segctr = 0 grn1.trigger = 1 grn1.whichseg = 0 grn1.rampval = 0.0 end end end val += inval out1 += 1 if grn1.trigger == 1 grn1.trigger = 0 out1 += hop end end if i == out2 inval = ina(grn2.loc, fil2) grn2.loc += 1 if grn2.whichseg.zero? # ramp-up inval *= grn2.rampval grn2.rampval += grn2.rampinc grn2.segctr += 1 if grn2.segctr == grn2.ramplen grn2.segctr = 0 grn2.whichseg += 1 end else if grn2.whichseg == 1 # steady-state grn2.segctr += 1 if grn2.segctr == grn2.steadylen grn2.segctr = 0 grn2.whichseg += 1 end else # ramp-down inval *= grn2.rampval grn2.segctr += 1 grn2.rampval -= grn2.rampinc if grn2.segctr == grn2.ramplen grn2.segctr = 0 grn2.trigger = 1 grn2.whichseg = 0 grn2.rampval = 0.0 end end end val += inval out2 += 1 if grn2.trigger == 1 grn2.trigger = 0 out2 += hop end end val end end def expfil_test(start = 0.0, dur = 1.0) expfil(start, dur, 0.2, 0.01, 0.1, "oboe.snd", "fyow.snd") $now = start + dur + 0.2 end # GRAPH-EQ # =begin From: Marco Trevisani This should work like a Graphic Equalizer.... Very easy to use. Just some note: "amp" & "amp-env" apply an enveloppe to the final result of the filtering. "dur" as ""standard"" in my instruments, when dur = 0 it will take the length of the sndfile input, otherwise the duration in seconds. "gain-freq-list" is a list of gains and frequencies to filter --in this order gain and frequencies--. There is no limit to the size of the list. Gain can be a number or an envelope. Unfortunatelly in this version they cant alternate, one should chose, all envelopes or all numbers i.e.: case 1 -> '( .1 440.0 .3 1500.0 .2 330.0 ...etc) or case 2 -> '((0 .1 1 .5) 440.0 (0 1 1 .01) 1500 (0 .3 1 .5) 330.0 ...etc) '( .1 440.0 (0 1 1 .01) 1500 ..etc) <<< again, this is not allowed .. "offset-gain" This apply to all the gains if case 1. It adds or subtracts an offset to all the gains in the list. This number can be positive or negative. In case the result is a negative number --let's say offset = -.4 and, like in case 1, the first gain is .1, the result would be -.3 -- the instrument will pass a gain equal to 0. "filt-gain-scale" & "filt-gain-base" will apply to the elements of the envelopes if we are in case 2, gains are envelopes. "stats" if #t --default-- prints the number of seconds processed, if nil doesnt print anything, which will speed up a bit the process. =end # def graph_eq(file, start, dur, *args) assert_type(File.exist?(file), file, 0, "an existing file") or_beg, amplitude, amp_env, amp_base, offset_gain = nil gain_freq_list, filt_gain_scale, filt_gain_base, a1 = nil optkey(args, binding, [:or_beg, 0], [:amplitude, 1], [:amp_env, [0, 1, 0.8, 1, 1, 0]], [:amp_base, 1], [:offset_gain, 0], [:gain_freq_list, [[0, 1, 1, 0], 440, [0, 0, 1, 1], 660]], [:filt_gain_scale, 1], [:filt_gain_base, 1], [:a1, 0.99]) durata = (dur.zero? ? ws_duration(file) : dur) len = seconds2samples(durata) or_start = (or_beg * ws_srate(file)).round rd_a = make_ws_reader(file, :start, or_start) half_list = gain_freq_list.length / 2 ampenv = make_env(:envelope, amp_env, :scaler, amplitude, :duration, durata, :base, amp_base) gain_list = [] 0.step(gain_freq_list.length - 1, 2) do |i| gain_list << gain_freq_list[i] end freq_list = [] 1.step(gain_freq_list.length - 1, 2) do |i| freq_list << gain_freq_list[i] end if_list_in_gain = gain_list[0].kind_of?(Array) env_size = (if_list_in_gain ? Array.new(freq_list.length) : nil) frm_size = Array.new(freq_list.length) gains = Vct.new(len, 1.0) half_list.times do |i| gval = gain_list[i] fval = freq_list[i] if gval.kind_of?(Array) env_size[i] = make_env(:envelope, gval, :scaler, filt_gain_scale, :duration, durata, :base, filt_gain_base) frm_size[i] = make_formant(fval, a1) else gains[i] = (offset_gain + gval < 0) ? 0 : (offset_gain + gain) frm_size[i] = make_formant(fval, a1) end end run_instrument(start, durata) do outval = 0.0 inval = ws_readin(rd_a) half_list.times do |j| if if_list_in_gain gains[j] = env(env_size[j]) * (1.0 - a1) end outval = outval + gains[j] * formant(frm_size[j], inval) end env(ampenv) * outval end close_ws_reader(rd_a) end def graph_eq_test(start = 0.0, dur = 1.0) graph_eq("oboe.snd", start, dur, :amplitude, 50.0) $now = start + dur + 0.2 end # ANOI # # a kind of noise reduction -- on-going average spectrum is squelched # to some extent obviously aimed at intermittent signal in background # noise # this is based on Perry Cook's Scrubber.m def anoi(infile, start, dur, fftsize = 128, amp_scaler = 1.0, r = TWO_PI) assert_type(File.exist?(infile), infile, 0, "an existing file") freq_inc = (fftsize / 2).floor fdi = make_vct(fftsize) fdr = make_vct(fftsize) spectr = make_vct(freq_inc, 1.0) scales = make_vct(freq_inc, 1.0) diffs = make_vct(freq_inc) win = make_fft_window(Blackman2_window, fftsize) k = 0 amp = 0.0 incr = amp_scaler * 4.0 / @srate file = make_file2sample(infile) radius = 1.0 - r / fftsize.to_f bin = @srate / fftsize fs = make_array(freq_inc) do |i| make_formant(i * bin, radius) end samp = 0 run_instrument(start, dur) do inval = file2sample(file, samp) samp += 1 fdr[k] = inval k += 1 amp += incr if amp < amp_scaler if k >= fftsize k = 0 spectrum(fdr, fdi, win, 1) freq_inc.times do |j| spectr[j] = 0.9 * spectr[j] + 0.1 * fdr[j] if spectr[j] >= fdr[j] diffs[j] = scales[j] / -fftsize else diffs[j] = ((fdr[j] - spectr[j]) / fdr[j] - scales[j]) / fftsize end end end outval = 0.0 1.upto(freq_inc - 1) do |j| cur_scale = scales[j] outval = outval + cur_scale * formant(fs[j], inval) scales[j] += diffs[j] end amp * outval end end def anoi_test(start = 0.0, dur = 1.0) anoi("fyow.snd", start, dur, 128, 2.0) $now = start + dur + 0.2 end =begin Date: Fri, 25 Sep 1998 09:56:41 +0300 From: Matti Koskinen To: linux-audio-dev@ginette.musique.umontreal.ca Subject: [linux-audio-dev] Announce: alpha version of denoising [...] I wrote a simple denoiser called anoi after it's parent clm-instrument anoi.ins. anoi tries to remove white noise like tape hiss from wav- files. Removing of noise succeeds ok, but depending of the original sound, some distortion can be audible. If someone is interested, http://www.sci.fi/~mjkoskin contains tarred and gzipped file. Now only monophonic wav-files can be denoised, but adding others isn't too difficult. -matti mjkoskin@sci.fi =end # FULLMIX # # ;; "matrix" can be a simple amplitude or a list of lists each inner # ;; list represents one input channel's amps into one output channel # ;; each element of the list can be a number, a list (turned into an # ;; env) or an env # ;; # ;; "srate" can be a negative number (read in reverse), or an envelope. def fullmix(in_file, start = 0.0, outdur = false, inbeg = 0.0, matrix = false, srate = false, reverb_amount = false) unless File.exist?(in_file) Snd.raise(:no_such_file, in_file, "no such file") end unless start start = 0.0 end unless inbeg inbeg = 0.0 end if number?(outdur) dur = outdur else sr = number?(srate) ? srate.abs : 1.0 dur = (mus_sound_duration(in_file) - inbeg) / sr end in_chans = channels(in_file) reversed = ((number?(srate) and srate.negative?) or (array?(srate) and srate.cadr.negative?)) inloc = (Float(inbeg) * mus_sound_srate(in_file)).round ochans = [in_chans, @channels].max if @ws_reverb and number?(reverb_amount) and reverb_amount.positive? rev_mx = Vct.new(in_chans * in_chans, reverb_amount) else rev_mx = false end dir = (reversed ? -1 : 1) if (not srate) or (number?(srate) and srate == 1.0) file = make_file2frample(in_file) else file = make_array(in_chans) do |i| make_readin(in_file, i, inloc, :direction, dir) end end envs = false if array?(srate) srcenv = make_env(srate, :duration, dur, :scaler, Float(dir)) else srcenv = false end case matrix when Array mx = Vct.new(ochans * ochans, 0.0) matrix.each_with_index do |inlist, inp| break if inp >= in_chans inlist.each_with_index do |outn, outp| break if outp >= @channels case outn when Numeric # mx[inp][outp] = outn mx[inp * ochans + outp] = outn when Array, Mus unless envs envs = Array.new(in_chans * @channels, false) end if env?(outn) envs[inp * @channels + outp] = outn else envs[inp * @channels + outp] = make_env(outn, :duration, dur) end else Snd.warning("unknown element in matrix: %p", outn) end end end when Numeric # ; matrix is a number in this case (a global scaler) mx = Vct.new(ochans * ochans, matrix) else mx = Vct.new(ochans * ochans, 1.0) end # to satisfy with_sound-option :info and :notehook with_sound_info(get_func_name, start, dur) beg = seconds2samples(start) samps = seconds2samples(dur) if (not array?(file)) mxe = envs if envs mxe = Array.new(in_chans) do |i| Array.new(@channels) do |j| envs[i * @channels + j] end end end if sound?(@ws_output) output = file_name(@ws_output) if sound?(@ws_reverb) revout = file_name(@ws_reverb) end else output = @ws_output revout = @ws_reverb end mus_file_mix(output, file, beg, samps, inloc, mx, mxe) if rev_mx mus_file_mix(revout, file, beg, samps, inloc, rev_mx) end else if sound?(@ws_output) Snd.raise(:wrong_type_arg, "don't use :to_snd true") end sr = (number?(srate) ? srate.abs : 0.0) srcs = Array.new(in_chans) do |i| make_src(:input, file[i], :srate, sr) end mus_file_mix_with_envs(file, beg, samps, mx, rev_mx, envs, srcs, srcenv, @ws_output, @ws_reverb) end end def fullmix_test(start = 0.0, dur = 1.0) $now = start fullmix("pistol.snd", $now, dur) $now += dur + 0.2 fullmix("oboe.snd", $now, dur, 0, [[0.1, make_env([0, 0, 1, 1], :duration, dur, :scaler, 0.5)]]) $now += dur + 0.2 end # Original header: # ;;; grani: a granular synthesis instrument # ;;; by Fernando Lopez-Lezcano # ;;; http://ccrma.stanford.edu/~nando/clm/grani/ # ;;; # ;;; Original grani.ins instrument written for the 220a Course by # ;;; Fernando Lopez-Lezcano & Juan Pampin, November 6 1996 # ;;; # ;;; Mar 21 1997: working with hop and grain-dur envelopes # ;;; Mar 22 1997: working with src envelope (grain wise) & src spread # ;;; Jan 26 1998: started work on new version # ;;; Nov 7 1998: input soundfile duration calculation wrong # ;;; Nov 10 1998: bug in in-samples (thanks to Kristopher D. Giesing for this one) # ;;; Dec 20 1998: added standard locsig code # ;;; Feb 19 1999: added "nil" as default value of where to avoid warning (by bill) # ;;; Jan 10 2000: added input-channel to select which channel of the input file # ;;; to process. # ;;; added grain-start-in-seconds to be able to specify input file # ;;; locations in seconds for the grain-start envelope # ;;; May 06 2002: fixed array passing of where-bins in clisp (reported by Charles # ;;; Nichols and jennifer l doering # ;;; Mar 27 2003: added option for sending grains to all channels (requested by # ;;; Oded Ben-Tal) # ;;; calculate a random spread around a center of 0 def random_spread(spread) spread.nonzero? ? (random(spread) - spread / 2.0) : 0.0 end # ;;; create a constant envelope if argument is a number def envelope_or_number(val) assert_type((number?(val) or array?(val) or vct?(val)), val, 0, "a number, an array or a vct") case val when Numeric [0, Float(val), 1, Float(val)] when Vct val.to_a when Array val end end # ;;; create a vct from an envelope def make_gr_env(env, length = 512) length_1 = (length - 1).to_f make_vct!(length) do |i| envelope_interp(i / length_1, env) end end # ;;; Grain envelopes def raised_cosine(*args) duty_cycle, length = nil optkey(args, binding, [:duty_cycle, 100], [:length, 128]) active = length * duty_cycle.to_f * 0.01 incr = PI / (active - 1.0) start = (length - active) / 2.0 fin = (length + active) / 2.0 s = -1 make_vct!(length) do |i| sine = if i >= start and i < fin s += 1 sin(s * incr) else 0.0 end sine * sine end end # ;;;============================================================================= # ;;; Granular synthesis instrument # ;;;============================================================================= # # ;;; input-channel: # ;;; from which channel in the input file are samples read # ;;; amp-envelope: # ;;; amplitude envelope for the note # ;;; grain-envelope: # ;;; grain-envelope-end: # ;;; envelopes for each individual grain. The envelope applied in the result # ;;; of interpolating both envelopes. The interpolation is controlled by # ;;; grain-envelope-trasition. If "grain-envelope-end" is nil interpolation # ;;; is turned off and only grain-envelope is applied to the grains. # ;;; grain-envelope-trasition: # ;;; an enveloper that controls the interpolation between the two grain envelopes # ;;; 0 -> selects "grain-envelope" # ;;; 1 -> selects "grain-envelope-end" # ;;; grain-envelope-array-size # ;;; size of the array passed to make-table-lookup # ;;; grain-duration: # ;;; envelope that controls grain duration in seconds # ;;; srate-linear: # ;;; t -> sample rate envelope is linear # ;;; nil -> sample rate envelope is exponential # ;;; srate: # ;;; envelope that controls sample rate conversion. The envelope is an # ;;; exponential envelope, the base and error bound of the conversion # ;;; are controlled by "srate-base" and "srate-error". # ;;; srate-spread: # ;;; random spread of sample rate conversion around "srate" # ;;; srate-base: # ;;; base for the exponential conversion # ;;; for example: base = (expt 2 (/ 12)) creates a semitone envelope # ;;; srate-error: # ;;; error bound for the exponential conversion. # ;;; grain-start: # ;;; envelope that determines the starting point of the current grain in # ;;; the input file. "y"->0 starts the grain at the beginning of the input # ;;; file. "y"->1 starts the grain at the end of the input file. # ;;; grain-start-spread: # ;;; random spread around the value of "grain-start" # ;;; grain-start-in-seconds: # ;;; nil -> grain-start y envelope expressed in percent of the duration of the input file # ;;; t -> grain-start y envelope expressed in seconds # ;;; grain-density: # ;;; envelope that controls the number of grains per second generated in the output file # ;;; grain-density-spread: Grani_to_locsig = 0 Grani_to_grain_duration = 1 Grani_to_grain_start = 2 Grani_to_grain_sample_rate = 3 Grani_to_grain_random = 4 Grani_to_grain_allchans = 5 def grani(start, dur, amp, file, *args) assert_type(File.exist?(file), file, 3, "an existing file") input_channel = nil grains, amp_envelope, grain_envelope, grain_envelope_end = nil grain_envelope_transition, grain_envelope_array_size, grain_duration = nil grain_duration_spread, grain_duration_limit, srate, srate_spread = nil srate_linear, srate_base, srate_error, grain_start, grain_start_spread = nil grain_start_in_seconds, grain_density, grain_density_spread = nil reverb_amount, reverse, where_to, where_bins, grain_distance = nil grain_distance_spread, grain_degree, grain_degree_spread = nil optkey(args, binding, [:input_channel, 0], [:grains, 0], [:amp_envelope, [0, 0, 0.3, 1, 0.7, 1, 1, 0]], [:grain_envelope, [0, 0, 0.3, 1, 0.7, 1, 1, 0]], [:grain_envelope_end, false], [:grain_envelope_transition, [0, 0, 1, 1]], [:grain_envelope_array_size, 512], [:grain_duration, 0.1], [:grain_duration_spread, 0.0], [:grain_duration_limit, 0.002], [:srate, 0.0], [:srate_spread, 0.0], [:srate_linear, false], [:srate_base, 2.0 ** (1.0 / 12)], [:srate_error, 0.01], [:grain_start, [0, 0, 1, 1]], [:grain_start_spread, 0.0], [:grain_start_in_seconds, false], [:grain_density, 10.0], [:grain_density_spread, 0.0], [:reverb_amount, 0.01], [:reverse, false], [:where_to, 0], [:where_bins, []], [:grain_distance, 1.0], [:grain_distance_spread, 0.0], [:grain_degree, 45.0], [:grain_degree_spread, 0.0]) beg, fin = times2samples(start, dur) in_file_channels = ws_channels(file) in_file_sr = ws_srate(file) in_file_dur = ws_duration(file) rd = make_ws_reader(file, :channel, [input_channel, in_file_channels - 1].min, :vct?, true) in_file_reader = make_src(:input, lambda do |dir| ws_readin(rd) end, :srate, 1.0) set_mus_increment(in_file_reader, -1) if reverse last_in_sample = (in_file_dur * in_file_sr).round srate_ratio = in_file_sr / mus_srate() sr_env = make_env(:envelope, if srate_linear envelope_or_number(srate) else exp_envelope(envelope_or_number(srate), :base, srate_base, :error, srate_error) end, :scaler, srate_ratio, :duration, dur) sr_spread_env = make_env(:envelope, envelope_or_number(srate_spread), :duration, dur) amp_env = make_env(:envelope, amp_envelope, :scaler, amp, :duration, dur) gr_dur = make_env(:envelope, envelope_or_number(grain_duration), :duration, dur) gr_dur_spread = make_env(:envelope, envelope_or_number(grain_duration_spread), :duration, dur) gr_start_scaler = (grain_start_in_seconds ? 1.0 : in_file_dur) gr_start = make_env(:envelope, envelope_or_number(grain_start), :duration, dur) gr_start_spread = make_env(:envelope, envelope_or_number(grain_start_spread), :duration, dur) gr_dens_env = make_env(:envelope, envelope_or_number(grain_density), :duration, dur) gr_dens_spread_env = make_env(:envelope, envelope_or_number(grain_density_spread), :duration, dur) if vct?(grain_envelope) ge = grain_envelope else ge = make_gr_env(grain_envelope, grain_envelope_array_size) end gr_env = make_table_lookup(:frequency, 1.0, :initial_phase, 0, :wave, ge) if grain_envelope_end if vct?(grain_envelope_end) ge = grain_envelope_end else ge = make_gr_env(grain_envelope_end, grain_envelope_array_size) end else ge = make_vct(512) end gr_env_end = make_table_lookup(:frequency, 1.0, :initial_phase, 0, :wave, ge) gr_int_env = make_env(:envelope, envelope_or_number(grain_envelope_transition), :duration, dur) gr_dist = make_env(:envelope, envelope_or_number(grain_distance), :duration, dur) gr_dist_spread = make_env(:envelope, envelope_or_number(grain_distance_spread), :duration, dur) gr_degree = make_env(:envelope, envelope_or_number(grain_degree), :duration, dur) gr_degree_spread = make_env(:envelope, envelope_or_number(grain_degree_spread), :duration, dur) gr_start_sample = beg gr_samples = 0 gr_offset = 1 gr_dens = 0.0 gr_dens_spread = 0.0 grain_counter = 0 samples = 0 first_grain = true case grain_duration when Numeric dur += grain_duration when Array dur += grain_duration.last end run_instrument(start, dur, :degree, 45.0) do if gr_offset < gr_samples gr_offset += 1 (if grain_envelope_end gr_where = env(gr_int_env) (1 - gr_where) * table_lookup(gr_env) + gr_where * table_lookup(gr_env_end) else table_lookup(gr_env) end) * env(amp_env) * src(in_file_reader) else if first_grain first_grain = false gr_start_sample = beg else gr_start_sample += seconds2samples(1.0 / (gr_dens + gr_dens_spread)) if (gr_start_sample > fin) or (grains.nonzero? and (grain_counter >= grains)) break end end gr_offset = 0 gr_from_beg = gr_start_sample - beg set_mus_location(amp_env, gr_from_beg) set_mus_location(gr_dur, gr_from_beg) set_mus_location(gr_dur_spread, gr_from_beg) set_mus_location(sr_env, gr_from_beg) set_mus_location(sr_spread_env, gr_from_beg) set_mus_location(gr_start, gr_from_beg) set_mus_location(gr_start_spread, gr_from_beg) set_mus_location(gr_dens_env, gr_from_beg) set_mus_location(gr_dens_spread_env, gr_from_beg) in_start_value = env(gr_start) * gr_start_scaler + random_spread(env(gr_start_spread) * gr_start_scaler) in_start = (in_start_value * in_file_sr).round gr_duration = [grain_duration_limit, env(gr_dur) + random_spread(env(gr_dur_spread))].max gr_samples = seconds2samples(gr_duration) gr_srate = if srate_linear env(sr_env) + random_spread(env(sr_spread_env)) else env(sr_env) * srate_base ** random_spread(env(sr_spread_env)) end set_mus_increment(in_file_reader, gr_srate) in_samples = (gr_samples / (1.0 / srate_ratio)).round set_mus_phase(gr_env, 0.0) set_mus_phase(gr_env_end, 0.0) set_mus_frequency(gr_env, 1.0 / gr_duration) set_mus_frequency(gr_env_end, 1.0 / gr_duration) gr_dens = env(gr_dens_env) gr_dens_spread = random_spread(env(gr_dens_spread_env)) samples += gr_samples grain_counter += 1 where = case where_to when Grani_to_grain_duration gr_duration when Grani_to_grain_start in_start_value when Grani_to_grain_sample_rate gr_srate when Grani_to_grain_random random(1.0) else Grani_to_locsig end if where.nonzero? and where_bins.length > 0 (where_bins.length - 1).times do |chn| locsig_set!(@locsig, chn, (where.between?(where_bins[chn], where_bins[chn + 1]) ? 1.0 : 0.0)) end else if where_to == Grani_to_grain_allchans @channels.times do |chn| locsig_set!(@locsig, chn, 1.0) end else set_mus_location(gr_dist, gr_from_beg) set_mus_location(gr_dist_spread, gr_from_beg) set_mus_location(gr_degree, gr_from_beg) set_mus_location(gr_degree_spread, gr_from_beg) deg = env(gr_degree) + random_spread(env(gr_degree_spread)) dist = env(gr_dist) + random_spread(env(gr_dist_spread)) dist_scl = 1.0 / [dist, 1.0].max if sample2file?(@ws_reverb) locsig_reverb_set!(@locsig, 0, reverb_amount * (1.0 / sqrt([dist, 1.0].max))) end if @channels == 1 locsig_set!(@locsig, 0, dist_scl) else if @channels == 2 frac = [90.0, [0.0, deg].max].min / 90.0 locsig_set!(@locsig, 0, dist_scl * (1.0 - frac)) locsig_set!(@locsig, 1, dist_scl * frac) else if @channels > 2 locsig_set!(@locsig, 0, if deg.between?(0, 90) dist_scl * ((90.0 - deg) / 90.0) else if deg.between?(270, 360) dist_scl * ((deg - 270.0) / 90.0) else 0.0 end end) locsig_set!(@locsig, 1, if deg.between?(90, 180) dist_scl * (180.0 - deg) / 90.0 else if deg.between?(0, 90) dist_scl * (deg / 90.0) else 0.0 end end) locsig_set!(@locsig, 2, if deg.between?(180, 270) dist_scl * (270.0 - deg) / 90.0 else if deg.between?(90, 180) dist_scl * (deg - 90.0) / 90.0 else 0.0 end end) if @channels > 3 locsig_set!(@locsig, 3, if deg.between?(270, 360) dist_scl * (360.0 - deg) / 90.0 else if deg.between?(180, 270) dist_scl * (deg - 180.0) / 90.0 else 0.0 end end) end end end end end end in_start = if (in_start + in_samples) > last_in_sample last_in_sample - in_samples else [in_start, 0].max end set_ws_location(rd, in_start) 0.0 end end close_ws_reader(rd) end def grani_test(start = 0.0, dur = 1.0) grani(start, dur, 5.0, "oboe.snd", :grain_envelope, raised_cosine()) $now = start + dur + 0.2 end # BES-FM def bes_fm(start, dur, freq, amp, ratio, index) car_ph = mod_ph = 0.0 car_incr = hz2radians(freq) mod_incr = ratio.to_f * car_incr ampenv = make_env(:envelope, [0, 0, 25, 1, 75, 1, 100, 0], :scaler, amp, :duration, dur) run_instrument(start, dur) do out_val = env(ampenv) * bes_j1(car_ph) car_ph = car_ph + car_incr + index.to_f * bes_j1(mod_ph) mod_ph += mod_incr out_val end end def bes_fm_test(start = 0.0, dur = 1.0) bes_fm(start, dur, 440, 10, 1, 4) $now = start + dur + 0.2 end # SSB_FM class Ssb_fm < Musgen def initialize(freq) super() @frequency = freq @osc1 = make_oscil(freq, 0) @osc2 = make_oscil(freq, HALF_PI) @osc3 = make_oscil(0, 0) @osc4 = make_oscil(0, HALF_PI) @hilbert = make_hilbert_transform(40) @delay = make_delay(40) end def inspect format("%s.new(%s)", self.class, @frequency) end def to_s format("#<%s freq: %s>", self.class, @frequency) end def run_func(val1 = 0.0, val2 = 0.0) ssb_fm(val1) end def ssb_fm(modsig) am0 = oscil(@osc1) am1 = oscil(@osc2) car0 = oscil(@osc3, hilbert_transform(@hilbert, modsig)) car1 = oscil(@osc4, delay(@delay, modsig)) am0 * car0 + am1 * car1 end end def make_ssb_fm(freq = 440.0) Ssb_fm.new(freq) end def ssb_fm?(obj) obj.kind_of?(Ssb_fm) end def ssb_fm(gen, modsig = 0.0) gen.ssb_fm(modsig) end # FM2 class Fm2 < Musgen def initialize(f1, f2, f3, f4, p1, p2, p3, p4) super() @osc1 = make_oscil(f1, p1) @osc2 = make_oscil(f2, p2) @osc3 = make_oscil(f3, p3) @osc4 = make_oscil(f4, p4) end def inspect format("%s.new(%s, %s, %s, %s, %s, %s, %s, %s)", self.class, @f1, @f2, @f3, @f4, @p1, @p2, @p3, @p4) end def to_s format("#<%s %1.3f, %1.3f, %1.3f, %1.3f, %1.3f, %1.3f, %1.3f, %1.3f>", self.class, @f1, @f2, @f3, @f4, @p1, @p2, @p3, @p4) end def run_func(val1 = 0.0, val2 = 0.0) fm2(val1) end def fm2(index) (oscil(@osc1, index * oscil(@osc2)) + oscil(@osc3, index * oscil(@osc4))) * 0.25 end end # make_fm2(1000, 100, 1000, 100, 0, 0, HALF_PI, HALF_PI) # make_fm2(1000, 100, 1000, 100, 0, 0, 0, HALF_PI) def make_fm2(f1, f2, f3, f4, p1, p2, p3, p4) Fm2.new(f1, f2, f3, f4, p1, p2, p3, p4) end def fm2?(obj) obj.kind_of?(Fm2) end def fm2(gen, index = 0.0) gen.fm2(index) end def clm_ins_test(start = 0.0, dur = 1.0) $now = start violin_test($now, dur) fm_violin_test($now, dur) pluck_test($now, dur) vox_test($now, dur) fofins_test($now, dur) fm_trumpet_test($now, dur) pqw_vox_test($now, dur) flute_test($now, dur) fm_bell_test($now, dur) fm_insect_test($now, dur) fm_drum_test($now, dur) gong_test($now, dur) attract_test($now, dur) pqw_test($now, dur) tubebell_test($now, dur) wurley_test($now, dur) rhodey_test($now, dur) hammondoid_test($now, dur) metal_test($now, dur) drone_canter_test($now, dur) reson_test($now, dur) cellon_test($now, dur) gran_synth_test($now, dur) touch_tone_test($now, dur) spectra_test($now, dur) two_tab_test($now, dur) lbj_piano_test($now, dur) resflt_test($now, dur) scratch_test($now, dur) pins_test($now, dur) zc_test($now, dur) zn_test($now, dur) za_test($now, dur) clm_expsrc_test($now, dur) exp_snd_test($now, dur) expfil_test($now, dur) graph_eq_test($now, dur) anoi_test($now, dur) fullmix_test($now, dur) grani_test($now, dur) bes_fm_test($now, dur) end # clm-ins.rb ends here snd-16.1/grfsnd.html0000644000076400007640000024206712623732553012527 0ustar bilbil Snd Customization and Extension
Snd Customization and Extension Part 2
this file:extsnd.html:
Snd startup
Snd invocation flags

Snd recognizes the following switches in its command line:

-h -horizontal          layout sounds as horizontal panes
-v -vertical            layout sounds vertically (the default)
-notebook               layout sounds in a notebook widget (Motif 2.0 or later)
-separate               layout sounds each in a separate window (listener is in main window)
--help                  print some help, version info, and exit
--version               print version info
-noglob                 don't read /etc/snd.conf
-noinit                 don't read ~/.snd
-nostdin                don't watch for possible input from stdin
-p -preload <dir>       add sound files in directory <dir> to the View:Files list (snd -p .)
-l -load <file>         load Scheme, Ruby, or Forth code in <file> (snd -l test.scm)
-e -eval expr           evaluate expr
-b -batch <file>        load Scheme, Ruby, or Forth code in <file> as a batch (no GUI) job
-I <dir>                add <dir> to the load search list
notebook
snd -notebook oboe.snd pistol.snd
(set! (graph-style) graph-lollipops)
(set! (dot-size) 8)

The -e switch evaluates its argument. The initialization file, if any, is loaded first, then the arguments are processed in order:

snd -e "(set! (data-color) (make-color 1 0 0))" oboe.snd

reads ~/.snd, if any, then sets the (unselected) data color to red, then opens oboe.snd.

snd -eval '(begin (display (+ 1 2)) (exit))'

prints "3" and exits. The "-title" argument works in both versions of Snd. The following adds "WAV" to the sound file extension table before adding all the sound files in the directory to the View:Files dialog's list:

snd -e '(add-sound-file-extension "WAV")' -p /home/bil/sounds
black background
snd oboe.snd
(set! *selected-data-color* (make-color 1 1 1))
(set! *selected-graph-color* (make-color 0 0 0))
(set! (graphs-horizontal) #f)
(set! (transform-graph?) #t)
(set! (show-transform-peaks) #t)
The initialization file

When Snd starts, it looks for an initialization file, normally named "~/.snd". This optional file is supposed to be similar to Emacs' .emacs file, containing any customizations or extensions that you want loaded whenever Snd starts. Say we want the Snd window to start out 800x500, want to predefine an envelope named "env1", and want the file selection box to show just sound files. We make ~/.snd and put in it:

Scheme:
    (set! (window-width) 800)
    (set! (window-height) 500)
    (set! *just-sounds* #t)
    (define-envelope env1 '(0 0 1 1 2 0))

Ruby:
    set_window_width(800)
    set_window_height(500)
    set_just_sounds(true)
    define_envelope("env1", [0, 0, 1, 1, 2, 0])

Forth:
    800 set-window-width drop
    500 set-window-height drop
    #t set-just-sounds drop
    $" env1" '( 0.0 0.0 1.0 1.0 2.0 0.0 ) 1.0 define-envelope drop

In more complex situations, you may want an initialization file particular to a given extension language, machine, or global across users; the name of this optional global initialization file is "/etc/snd.conf". It is read before your local file; both can, of course, be absent. To override reading the global init file when Snd is invoked, include the switch -noglob. To override the local init file, use -noinit.

The initialization files particular to a given extension language have names such as ~/.snd_s7 and ~/.snd_prefs_ruby. Currently the possibilities are: ~/.snd_prefs_ruby|forth|s7, /etc/snd_ruby|forth|s7.conf, ~/.snd_ruby|forth|s7 (the notation "ruby|forth" means either "ruby" or "forth", so the file names spelled out completely are "/etc/snd_ruby.conf", etc; which one is loaded obviously depends on which language you chose during configuration). The save-options (preferences dialog) process writes to .snd_prefs_* which is loaded first, if it exists; then Snd looks for .snd_* (s7, ruby, or forth); then .snd. If you're always using just one version of Snd, it's simplest to stick with .snd. The actual load sequence is:

/etc/snd_ruby|forth|s7.conf    (these two canceled by -noglob)
/etc/snd.conf               
~/.snd_prefs_ruby|forth|s7     (the rest canceled by -noinit)
~/.snd_ruby|forth|s7
~/.snd                         (also SND_INIT_FILE_ENVRIONMENT_NAME)

Here's a more elaborate initialization file (~/.snd_s7):

(set! (window-width) 800)           ;these set the initial window size
(set! (window-height) 500)

(if (provided? 'snd-motif)          ;Motif and Gtk use different font naming conventions
    (begin
      (set! *listener-font* "9x15")
      (set! *axis-label-font* "-*-times-medium-r-normal-*-18-*-*-*-*-*-*-*")
      (set! *axis-numbers-font* "9x15"))
    (begin
      (set! *listener-font* "Sans 10")
      (set! *axis-label-font* "Times Medium 14")
      (set! *axis-numbers-font* "Sans 10")))

(set! *listener-prompt* ":")        ;change listener prompt from the default ">" to ":"
(set! (show-listener) #t)           ;include the listener window initially

(define beige (make-color 0.96 0.96 0.86))
(define blue (make-color 0 0 1))
(set! *selected-graph-color* beige) ;selected graph background is beige
(set! *selected-data-color* blue)   ;selected graph data is blue

(set! *save-dir* "/zap/snd")        ;save-state files are placed in /zap/snd
(set! *temp-dir* "/zap/tmp")        ;temp files are placed in /zap/tmp
(set! *peak-env-dir* "~/peaks")

(load "hooks.scm")
(load "extensions.scm")

(set! *with-inset-graph* #t)        ;display an overview of the current window in the upper right
(set! *with-pointer-focus* #t)      ;automatically focus on (activate) the widget under the mouse

(hook-push after-open-hook          ;if sound has many chans, use just one pane for all
  (lambda (hook)
    (let ((snd (hook 'snd)))
      (if (> (channels snd) 4)
          (set! (channel-style snd) channels-combined)))))

(set! *selection-creates-region* #f) ;turn off automatic region creation

A similar Ruby initialization file (~/.snd_ruby):

require "draw"

set_window_width 800
set_window_height 500

set_listener_font "9x15"
set_axis_numbers_font "9x15"

set_show_mix_waveforms true
set_listener_prompt ":"
set_show_listener true

beige = make_color 0.96, 0.96, 0.86
blue = make_color 0, 0, 1
set_selected_graph_color beige
set_selected_data_color blue
make_current_window_display

$mouse_enter_graph_hook.add_hook!("focus") do |snd, chn|
  focus_widget(channel_widgets(snd, chn)[0])
end
$mouse_enter_listener_hook.add_hook!("focus") do |widget| focus_widget(widget) end
$mouse_enter_text_hook.add_hook!("focus") do |widget| focus_widget(widget) end

And Forth (~/.snd_forth):

\ .snd_forth — start up file for Snd/Forth -*- snd-forth -*-

\ You can install the *.fs scripts with:
\ 
\   cd ${top_srcdir}/examples/site-lib
\   ./install.fth
\ 
\ or even better
\
\   cd ${top_builddir}
\   make install
\
\ If you have installed *.fs scripts with one of the above mentioned
\ commands, you don't need to add a path to *load-path*.
\ ${prefix}/share/fth/site-fth is already included.  Otherwise you can
\ add a path with e.g.:
\ 
\   "/home/mike/snd" add-load-path

\ A special *SND-HOME* path points here to ~/.snd.d (similar to ~/.emacs.d):
\ 
\ ~/.snd.d            directory for save-state-file
\ ~/.snd.d/sound      directory for *clm-file-name*
\                                   add-directory-to-view-files-list
\                                   set-open-file-dialog-director
\ ~/.snd.d/zap        directory for set-temp-dir
\                                   set-save-dir
\ ~/.snd.d/peaks      directory for set-peak-env-dir
\
\ "HOME" getenv       value *home*
\ *home* "/.snd.d" $+ value *snd-home*
\
\ Change these paths to fit your needs!
\

#t to *fth-verbose*
#f to *fth-debug*

#f value *init-with-peaks*		\ with peak-env support
#f value *init-graph-extra-hooks*	\ with display-correlate, zoom-spectrum, superimpose-ffts
#f value *init-lisp-graph-extra-hooks*	\ with display-energy, display-db

: print-loading-file { fname -- }
  *fth-verbose* if $" \\ loading %s\n" '( fname ) clm-print then
;

*filename* print-loading-file

"HOME" getenv                     value *home*
*home* "/.snd.d"               $+ value *snd-home*
hostname                          value *hostname*
*hostname* /\\./ string-split car value *short-hostname*
*argv* length 0> [if] *argv* car undef file-basename [else] "snd" [then] value *program-name*

before-load-hook lambda: <{ fname -- f }>
  fname print-loading-file
  #t
; add-hook!

\ if configured --with-shared-sndlib
dl-load sndlib Init_sndlib

\ Set them before loading clm.fs.
2                      set-default-output-chans   drop
48000    	       set-default-output-srate   drop
512                    set-dac-size               drop
mus-clipping           set-clipping               drop
1024 1024 *            set-mus-file-buffer-size   drop
24                     set-mus-array-print-length drop
mus-array-print-length set-print-length           drop
128                    set-object-print-length

require clm
require clm-ins

\ Environment variable CLM_SEARCH_PATH
\ Path variable where sound files reside.
\ csh: setenv CLM_SEARCH_PATH /usr/gnu/sound/SFiles:${HOME}/.snd.d/sound
\  sh: CLM_SEARCH_PATH=/usr/gnu/sound/SFiles:${HOME}/.snd.d/sound; export CLM_SEARCH_PATH

"CLM_SEARCH_PATH" getenv dup [if]
  ":" string-split [each] *clm-search-list* swap array-push to *clm-search-list* [end-each]
[else]
  drop
  *clm-search-list* *snd-home* "/sound" $+ array-push to *clm-search-list*
[then]
#t                                     to *clm-play*
#t                                     to *clm-statistics*
#t                                     to *clm-verbose*
#f                                     to *clm-debug*
*snd-home* "/sound/fth-test.snd"    $+ to *clm-file-name*
*snd-home* "/sound/fth-test.reverb" $+ to *clm-reverb-file-name*
#t                                     to *clm-delete-reverb*
lambda: <{ ins beg dur -- }> $" %14s: %5.2f %5.2f" '( ins beg dur ) clm-message ; to *clm-notehook*

'snd-nogui provided? [if]
  \ snd-nogui repl and prompt hooks
  before-repl-hook reset-hook!		\ remove default hook
  before-repl-hook lambda: <{ -- }>
    "" #f clm-message
    $" Starting session on %s." '( $" %Ev %Er" current-time strftime ) clm-message
    "" #f clm-message
  ; add-hook!
  after-repl-hook lambda: <{ history -- }>
    "" #f clm-message
    $" Thank you for using %s!" #( *program-name* string-upcase ) clm-message
    "" #f clm-message
    1 sleep
  ; add-hook!
  
  \ A more elaborated prompt for fth and snd-forth-nogui.
  before-prompt-hook lambda: <{ prompt pos -- new-prompt }>
    "%EI:%EM%p" current-time strftime string-downcase! { tm }
    "(/usr)?" *home* $+ make-regexp file-pwd "~" regexp-replace { path }
    $" (%s:%s)\n[%s %s] (%d)> " #( *short-hostname* path *program-name* tm pos ) string-format
  ; add-hook!
[then]

*snd-home* add-load-path
*init-with-peaks* [if]
  *snd-home* "/peaks"      $+ set-peak-env-dir               drop
[then]
*snd-home* "/snd-saved.fs" $+ set-save-state-file            drop
*snd-home* "/zap"          $+ set-temp-dir                   drop
*snd-home* "/zap"          $+ set-save-dir                   drop
*snd-home* "/sound"        $+ set-open-file-dialog-directory drop
"/usr/gnu/cvs/snd"            set-html-dir                   drop
"BROWSER" getenv "firefox" || set-html-program               drop
#t                            set-show-listener              drop
0.0               	      set-auto-update-interval       drop
"rev"           	      add-sound-file-extension       drop
"reverb"        	      add-sound-file-extension       drop
"wave"          	      add-sound-file-extension       drop
*clm-search-list* [each] ( dir ) undef add-directory-to-view-files-list drop [end-each]

before-save-state-hook lambda: <{ fname -- f }>
  $" \\ -*- snd-forth -*-\n" :filename fname with-output-port
  #t				      \ #t --> append mode
; add-hook!

\ make-default-comment from clm.fs
output-comment-hook lambda: <{ str -- s }>
  str empty? if make-default-comment else str then
; add-hook!

'snd-nogui provided? [unless]
  'snd-motif provided? [if]
    require snd-xm
    add-mark-pane
    #t with-smpte-label
    after-open-hook <'> show-disk-space add-hook!

    require effects
    #f to use-combo-box-for-fft-size	\ boolean (default #f)

    edhist-save-hook lambda: <{ prc -- }> "%S" #( prc ) clm-message ; add-hook!
  [then]

  'snd-gtk provided? [if]
    $" Serif 10" set-axis-label-font drop
  [then]

  require extensions
  #t set-emacs-style-save-as
  #t set-ask-about-unsaved-edits
  *snd-home* "/snd-remember-sound.fs" $+ to remember-sound-filename
  3 remember-sound-state
  0.00 0.10 #t prefs-activate-initial-bounds
  with-buffers-menu
  2 set-sync-style

  require examp
  *init-graph-extra-hooks* [if]
    graph-hook         <'> display-correlate  add-hook!
    graph-hook         <'> zoom-spectrum      add-hook!
    graph-hook         <'> superimpose-ffts   add-hook!
  [then]
  *init-lisp-graph-extra-hooks* [if]
    lisp-graph-hook    <'> display-energy     add-hook!
    lisp-graph-hook    <'> display-db         add-hook!
  [then]
  after-transform-hook <'> fft-peak           add-hook!

  require mix
  mix-click-hook       <'> mix-click-sets-amp add-hook!
  mix-click-hook       <'> mix-click-info     add-hook!

  require marks
  save-mark-properties
  mark-click-hook      <'> mark-click-info    add-hook!

  require dsp
  graph-hook lambda: <{ snd chn y0 y1 -- #f }>
    $" freq: %.3f" #( snd chn left-sample  snd chn spot-freq ) string-format
    snd status-report drop
    #f
  ; add-hook!

  mouse-click-hook lambda: <{ snd chn button state x y axis -- a }>
    axis time-graph = if
      $" freq: %.3f" #( snd chn #f cursor  snd chn spot-freq ) string-format
      snd status-report
    else
      #f
    then
  ; add-hook!

  require env
  enved-hook lambda: <{ en pt x y reason -- en'|#f }>
    reason enved-move-point = if
      x en 0 array-ref f> x en -2 array-ref f< && if
	en en pt 2* array-ref x #f #f stretch-envelope ( new-en ) dup pt 2* 1+ y array-set!
      else
	#f
      then
    else
      #f
    then
  ; add-hook!

  require rgb
  beige                  set-selected-graph-color    drop
  blue                   set-selected-data-color     drop

  #t           	         set-show-indices            drop
  #f		         set-with-verbose-cursor     drop
  #t                     set-with-inset-graph        drop
  #t                     set-with-pointer-focus      drop
  #t  			 set-just-sounds             drop
  #t  			 set-enved-wave?             drop
  #t  			 set-show-y-zero             drop
  #t                     set-show-transform-peaks    drop
  speed-control-as-ratio set-speed-control-style     drop
  graph-as-spectrogram   set-transform-graph-type    drop \ graph-once graph-as-sonogram
  rainbow-colormap	 set-colormap                drop
  $" snd> "              set-listener-prompt         drop
  160 		         set-window-x                drop
  0 			 set-window-y                drop
  800 		         set-window-width            drop
  600 		         set-window-height           drop

  exit-hook lambda: <{ -- f }>
    save-state-file save-state drop
    sounds each close-sound drop end-each
    #t
  ; add-hook! 

  after-open-hook lambda: <{ snd -- }>
    snd channels 0 ?do snd short-file-name snd i time-graph set-x-axis-label drop loop
    #t snd set-with-tracking-cursor drop
    channels-combined snd set-channel-style
  ; add-hook!

  : snd-set-cursor-style { snd kind -- #f }
    snd sound? if kind snd #t set-cursor-style drop then
    #f
  ;
  start-playing-hook lambda: <{ snd -- f }> snd cursor-line  snd-set-cursor-style ; add-hook!
  stop-playing-hook  lambda: <{ snd -- f }> snd cursor-cross snd-set-cursor-style ; add-hook!

  \ bind-key ( key modifiers func :optional extended=#f origin="" prefs-info="" -- val )
  \ 
  \ modifiers:
  \   0 normal
  \   1 shift
  \   4 control
  \   8 meta
  \ 
  \ extended (prefix key):
  \   #t  C-x
  \   #f  none
  \
  \ func ( -- val )
  \
  \ val should be:
  \   cursor-in-view
  \   cursor-on-left
  \   cursor-on-right
  \   cursor-in-middle
  \   keyboard-no-action
  \ 
  \ C-x C-c terminate Snd
  <char> c 4 lambda: <{ -- val }>
    0 snd-exit drop
    cursor-in-view
  ; #t $" terminate Snd" "terminate-snd" bind-key drop
  \ C-x k close selected sound
  <char> k 0 lambda: <{ -- val }>
    selected-sound close-sound-extend
    cursor-in-view
  ; #t $" close sound and jump to next open" "close-current-sound" bind-key drop
  \ C-x C-k show listener
  <char> k 4 lambda: <{ -- val }>
    #t set-show-listener drop
    cursor-in-view
  ; #t $" show listener" "show-listener" bind-key drop
  \ C-x C-n hide listener
  <char> n 4 lambda: <{ -- val }>
    #f set-show-listener drop
    cursor-in-view
  ; #t $" hide listener" "hide-listener" bind-key drop
  \ C-x C-x play
  <char> x 4 lambda: <{ -- val }>
    #t play drop
    cursor-in-view
  ; #t $" play current sound" "play-current-sound" bind-key drop
  \ C-x C-t play from cursor
  <char> t 4 lambda: <{ -- val }>
    selected-sound :start undef undef undef cursor play drop
    cursor-in-view
  ; #t $" play from cursor" "play-from-cursor" bind-key drop
  \ C-x x eval over selection
  <char> x 0 lambda: <{ -- val }>
    undef selection? if
      $" selection-eval:" <'> eval-over-selection #f #f prompt-in-minibuffer
    else
      $" no selection" #f status-report
    then drop
    cursor-in-view
  ; #t $" eval over selection" "eval-over-selection" bind-key drop
[then]					\ not snd-nogui

'snd-nogui provided? [unless]
  save-state-file file-exists? [if] require snd-saved [then]
[then]

\ find-file searchs in *clm-search-list*
sounds empty? [if]
  *clm-file-name* find-file dup [if] open-sound [then] drop cr
[then]

$" Snd of %s (Fth %s)" #( snd-version fth-version ) clm-message

\ .snd_forth ends here

If you loaded Snd with GSL, and have set the GSL_IEEE_MODE environment variable, it will override Snd's default arithmetic mode settings. GSL recommends the setting:

GSL_IEEE_MODE=double-precision,mask-underflow,mask-denormalized

For more complex initialization files, see snd_conffile.scm, snd_frg.scm, and edit123.scm.

Normally, the initialization file also adds the Snd sources directory to the load path. For more temporary situations, you can use the environment variable SND_PATH. It is a colon-separated list of directories that will be added to the load path when Snd starts.

Configuration choices

The configuration process is controlled by a set of switches, some specific to Snd. The latter are (configure --help):

Audio choices (normally this is decided automatically):
    --with-alsa              use ALSA (the default in Linux)
    --with-oss               use OSS
    --with-jack              use JACK (Linux audio stream sharing support, can be used with ALSA)
    --with-pulseaudio        use pulseaudio (may not work yet)
    --with-portaudio         use portaudio (may not work yet)


Graphics choices:
    --with-gtk               use Gtk+ to build Snd (Gtk+ version 2.0 or later)
    --with-motif             use Motif (version 2.0 or later) to build Snd (the default), Lesstif is not supported
    --with-gui               make Snd with graphics support (--without-gui is the intended use)
    --with-gl                include OpenGL support (spectrogram, etc, Motif only)
    --with-gl2ps             include gl2ps (GL to Postscript code, Motif only)
    --with-editres           include editres in xm (default: no)


Language choices:
    --with-forth             use Forth as the extension language
    --with-ruby              use Ruby as the extension language; version 1.6.4 or later
    --with-s7                use s7 as the extension language (default = yes)
    --without-extension-language 


Library choices:
    --with-gsl               use GSL (for Chebyshev window), default: yes if local C does not support complex trig
    --with-fftw              use fftw, default: yes; fallback fft is built-in
    --with-gmp               use gmp, mpfr, and mpc to implement multiprecision arithmetic (default: no)
    --with-ladspa            include support for LADSPA plugins (in Linux default: yes)
    --disable-deprecated     do not include any deprecated stuff from gtk, s7, sndlib, xen, clm, etc


Directory choices:
    --with-temp-dir          directory to use for temp files (default: ".")
    --with-save-dir          directory to use for saved-state files (default: ".")
    --with-doc-dir           directory to search for documentation (html-dir, elaborate set of defaults)
./configure
make
make install

tries to use s7, Motif, ALSA (if Linux), and a float sample representation, then installs the snd executable in /usr/local/bin, with a brief blurb in /usr/local/man/man1. Here at CCRMA, we normally use:

./configure --with-alsa --with-temp-dir=/zap

There are many more examples in tools/compsnd. Depending on how Snd is configured, any of the following symbols may be "provided" (on the *features* list in Scheme):

clm            clm module (always included — once upon a time it was optional)
gl             OpenGL callable from Scheme/Ruby/Forth (--with-gl switch)
snd-ladspa     LADSPA loaded (--with-ladspa)
sndlib         sndlib module (always included)
snd-motif      Motif used as GUI toolkit (--with-motif)
snd-gtk        Gtk+ used as GUI toolkit (--with-gtk, now the default)
snd-nogui      No GUI built-in (--without-gui)
snd-forth      Forth as extension language (--with-forth)
snd-ruby       Ruby as extension language (--with-ruby)
snd-s7         s7 as extension language (--with-s7)
snd            It's Snd, ferchrissake... (always included)
gsl            GSL is loaded (--with-gsl)
alsa           ALSA is in use, rather than OSS (--with-alsa)

To check whether something is available in the current Snd, use:

Scheme:  (provided? 'snd-gtk)
Ruby:    provided? :snd-gtk
Forth:   "snd-gtk" defined?
Environment variables

There are several environment variables specific to Snd:

SND_PATH                        Snd source load path list (a colon separated directory list)
SND_INIT_FILE_ENVIRONMENT_NAME  init file name
LADSPA_PATH                     Ladspa modules directory
MUS_ALSA_PLAYBACK_DEVICE        name of playback device (Alsa only)
MUS_ALSA_CAPTURE_DEVICE         name of capture device (Alsa only)
MUS_ALSA_DEVICE                 name of the playback and capture device (Alsa only)
MUS_ALSA_BUFFERS                number of "periods" used (Alsa only)
MUS_ALSA_BUFFER_SIZE            number of samples per channel per buffer (Alsa only)
AUDIODEV                        audio device name (Sun and related drivers)
Runtime modules and external programs
Snd as an Emacs subjob

Snd watches stdin; any input received is evaluated as if typed in Snd's listener; any subsequent output is sent to stdout. Presumably any process could communicate with Snd in this manner, but the real reason for this is to make it possible to run Snd as a subjob of Emacs. The simplest way to enable that is to use inf-snd.el by Michael Scholz. It starts with a long and detailed commentary.

Dynamically loaded modules

You can load shared object files into Snd at any time. In s7, load knows how to handle ".so" files:

(load "/home/bil/cl/cscm.so")

load assumes the library has a function that ties the library functions into s7 (via s7_define_function and so on). This function is named "init_func" in the load's current environment, so if our library calls it init_ex, we add it to the loader's environment as follows:

(load so-file-name 
  (sublet (curlet)
    (cons 'init_func 'init_ex)))

See cload.scm for a much more friendly approach.

Snd and CLM

The files clm.c, clm.h, and clm2xen.c implement CLM (a Music V implementation), always included in Snd. You can see what a generator does, or a group of generators, by running them in the listener, and using the graph and spectrum functions. Say we have these declarations in ~/.snd:

(define data-size 1024)
(define data (make-float-vector data-size 0.0))

(define (run-gen func)        ; func is a function of no arguments (a "thunk")
  (do ((i 0 (+ i 1))) 
      ((= i data-size))
    (set! (data i) (func))) ; fill data float-vector with output of 'func'
  (graph data))               ; display data as a graph

(define (run-fft func)
  (do ((i 0 (+ i 1))) 
      ((= i data-size))
    (set! (data i) (func)))
  (graph (snd-spectrum data blackman2-window data-size #t)))

Now we can open the listener, and type:

(define hi (make-oscil))
(run-gen (lambda () (oscil hi)))
(define ho (make-oscil))
(run-fft (lambda () (oscil hi (* .5 (oscil ho)))))

Any CLM instrument or function can be used in this way to edit sounds. Say we want an echo effect:

(define echo 
  (lambda (scaler secs)
    (let ((del (make-delay (round (* secs (srate))))))
      (lambda (inval)
        (+ inval (delay del (* scaler (+ (tap del) inval))))))))

Here 'scaler' sets how loud subsequent echos are, and 'secs' sets how far apart they are in seconds. 'echo' uses the 'secs' argument to create a delay line (make-delay) using the current sound's sampling rate to turn the 'secs' parameter into samples. echo then returns a closure, that is, a function with associated variables (in this case 'del' and 'scaler'); the returned function (the second lambda) takes one argument ('inval') and returns the result of passing that value to the delay with scaling. The upshot of all this is that we can use:

(map-channel (echo .5 .75) 0 44100)

to take the current active channel and return 44100 samples of echos, each echo half the amplitude of the previous, and spaced by .75 seconds. map-channel's first argument is a function of one argument, the current sample; when we pass it (echo ...), it evaluates the echo call, which returns the function that actually runs the delay line, producing the echo.

If we want "pre-echoes" instead (echoes of the future):

(reverse-sound)
(map-channel (echo .5 .75) 0 44100)
(reverse-sound)

Generators are "applicable" in most versions of Snd: the generator knows its type, so the explicit "oscil" function (for example) isn't needed.

> (define hi (make-oscil 440.0))
#<unspecified>
> (hi)
0.0
> (oscil hi)
0.125050634145737

We can make a generator that is either an oscil or a sawtooth-wave:

> (define sine-or-sawtooth
   (lambda (sine)
     (let ((gen ((if sine make-oscil make-sawtooth-wave) 440.0)))
       (lambda (fm)
         (gen fm)))))
#<unspecified>
> (define osc (sine-or-sawtooth #t))
#<unspecified>
> (osc 0.0)
0.0
> (osc 0.0)
0.125050634145737

Here are a few more examples, taken from examp.scm.

(define comb-filter 
  (lambda (scaler size)
    (let ((cmb (make-comb scaler size)))
      (lambda (x) (comb cmb x)))))

; (map-channel (comb-filter .8 32))

;;; by using filters at harmonically related sizes, we can get chords:

(define comb-chord
  (lambda (scaler size amp)
    (let ((c1 (make-comb scaler size))
	  (c2 (make-comb scaler (* size .75)))
	  (c3 (make-comb scaler (* size 1.2))))
      (lambda (x)
        (* amp (+ (comb c1 x) (comb c2 x) (comb c3 x)))))))

; (map-channel (comb-chord .95 60 .3))

;;; or change the comb length via an envelope:

(define max-envelope
  (lambda (e mx)
    (if (null? e)
	mx
      (max-envelope (cddr e) (max mx (abs (cadr e)))))))

(define zcomb
  (lambda (scaler size pm)
    (let ((cmb (make-comb scaler size :max-size (+ size 1 (max-envelope pm 0))))
	  (penv (make-env pm :length (framples))))
      (lambda (x) (comb cmb x (env penv))))))

; (map-channel (zcomb .8 32 '(0 0 1 10)))

;;; to impose several formants, just add them in parallel:

(define formants
  (lambda (r1 f1 r2 f2 r3 f3)
    (let ((fr1 (make-formant f1 r1))
	  (fr2 (make-formant f2 r2))
	  (fr3 (make-formant f3 r3)))
      (lambda (x)
	(+ (formant fr1 x)
	   (formant fr2 x)
	   (formant fr3 x))))))

; (map-channel (formants .01 900 .02 1800 .01 2700))

;;; to get a moving formant:

(define moving-formant
  (lambda (radius move)
    (let ((frm (make-formant (cadr move) radius))
	  (menv (make-env move :length (framples))))
      (lambda (x)
        (let ((val (formant frm x)))
	  (set! (mus-frequency frm) (env menv))
	  val)))))

; (map-channel (moving-formant .01 '(0 1200 1 2400)))


;;; -------- shift pitch keeping duration constant
;;;
;;; both src and granulate take a function argument to get input whenever it is needed.
;;; in this case, src calls granulate which reads the currently selected file.

(define expsrc
  (lambda (rate)
    (let* ((gr (make-granulate :expansion rate))
	   (sr (make-src :srate rate))
	   (vsize 1024)
	   (vbeg 0)
	   (v (channel->float-vector 0 vsize))
	   (inctr 0))
      (lambda (inval)
        (src sr 0.0
	  (lambda (dir)
	    (granulate gr
	      (lambda (dir)
		(let ((val (v inctr)))
		  (set! inctr (+ inctr dir))
		  (if (>= inctr vsize)
		      (begin
			(set! vbeg (+ vbeg inctr))
			(set! inctr 0)
			(channel->float-vector vbeg vsize 0 0 v)))
		  val)))))))))

Geez, I haven't had this much fun in a long time! Check out examp.scm and snd-test.scm for more. You can load Rick Taube's CM into Snd as Scheme code:

snd -l /home/bil/test/cm-2.8.0/src/cm.scm

and all of CM is at your disposal! See also Snd and Common Music.

In most CLM instruments, including all those in clm-ins.scm, the assumption is that you're reading and writing a temp file, calling the instruments within with-sound. The special generator snd->sample provides a way to redirect the CLM input handlers (in-any in particular) to a Snd sound (via its index).

Snd and Common Music

Under construction?

Snd and Motif

It is possible to add your own user-interface elements using the xm (for Motif) or xg (for Gtk) modules included with Snd. In the motif case, all the functions and constants are placed in the *motif* environment. Here's a dialog window with a slider:

(with-let *motif*
  (define scale-dialog #f)
  (define current-scaler 1.0)

(define (create-scale-dialog parent)
  (if (not (Widget? scale-dialog))
      (let ((xdismiss (XmStringCreate "Dismiss" XmFONTLIST_DEFAULT_TAG))
	    (xhelp (XmStringCreate "Help" XmFONTLIST_DEFAULT_TAG))
	    (titlestr (XmStringCreate "Scaling" XmFONTLIST_DEFAULT_TAG)))
	(set! scale-dialog 
	      (XmCreateTemplateDialog parent "Scaling"
                (list XmNcancelLabelString   xdismiss
		      XmNhelpLabelString     xhelp
		      XmNautoUnmanage        #f
		      XmNdialogTitle         titlestr
		      XmNresizePolicy        XmRESIZE_GROW
	              XmNnoResize            #f
		      XmNtransient           #f)))
	(XtAddCallback scale-dialog 
		       XmNcancelCallback (lambda (w context info)
					   (XtUnmanageChild scale-dialog)))
	(XtAddCallback scale-dialog 
		       XmNhelpCallback (lambda (w context info)
					 (snd-print "move the slider to affect the volume")))
	(XmStringFree xhelp)
	(XmStringFree xdismiss)
	(XmStringFree titlestr)

	(let* ((mainform 
		(XtCreateManagedWidget "formd" xmFormWidgetClass scale-dialog
                  (list XmNleftAttachment    XmATTACH_FORM
		        XmNrightAttachment   XmATTACH_FORM
		        XmNtopAttachment     XmATTACH_FORM
		        XmNbottomAttachment  XmATTACH_WIDGET
		        XmNbottomWidget      (XmMessageBoxGetChild scale-dialog XmDIALOG_SEPARATOR))))
	       (scale
		(XtCreateManagedWidget "" xmScaleWidgetClass mainform
		  (list XmNorientation XmHORIZONTAL
			XmNshowValue   #t
			XmNvalue       100
			XmNmaximum     500
			XmNdecimalPoints 2))))

      (XtAddCallback scale XmNvalueChangedCallback (lambda (w context info)
					     (set! current-scaler (/ (.value info) 100.0))))
      (XtAddCallback scale XmNdragCallback (lambda (w context info)
					     (set! current-scaler (/ (.value info) 100.0)))))))
  (XtManageChild scale-dialog))

(create-scale-dialog (cadr (main-widgets))))

which creates a little dialog:

scale dialog

In Ruby, this is:

$scale_dialog = false
$current_scaler = 1.0

def create_scale_dialog(parent)
  if !RWidget?($scale_dialog) 
    then
      xdismiss = RXmStringCreate("Dismiss", RXmFONTLIST_DEFAULT_TAG)
      xhelp = RXmStringCreate("Help", RXmFONTLIST_DEFAULT_TAG)
      titlestr = RXmStringCreate("Scaling", RXmFONTLIST_DEFAULT_TAG)
      $scale_dialog = RXmCreateTemplateDialog(parent, "Scaling",
                   	[RXmNcancelLabelString,  xdismiss,
                      	 RXmNhelpLabelString,    xhelp,
                      	 RXmNautoUnmanage,       false,
                      	 RXmNdialogTitle,        titlestr,
                      	 RXmNresizePolicy,       RXmRESIZE_GROW,
                      	 RXmNnoResize,           false,
                       	 RXmNtransient,          false])
      RXtAddCallback($scale_dialog, RXmNcancelCallback, 
                     Proc.new { |w, context, info| RXtUnmanageChild($scale_dialog)})
      RXtAddCallback($scale_dialog, RXmNhelpCallback, 
                     Proc.new { |w, context, info| snd_print "move the slider to affect the volume"})
      RXmStringFree xhelp
      RXmStringFree xdismiss
      RXmStringFree titlestr
      mainform = RXtCreateManagedWidget("formd", RxmFormWidgetClass, $scale_dialog,
                  	[RXmNleftAttachment,      RXmATTACH_FORM,
                         RXmNrightAttachment,     RXmATTACH_FORM,
                         RXmNtopAttachment,       RXmATTACH_FORM,
                         RXmNbottomAttachment,    RXmATTACH_WIDGET,
                         RXmNbottomWidget,        RXmMessageBoxGetChild($scale_dialog, RXmDIALOG_SEPARATOR)])
      scale = RXtCreateManagedWidget("", RxmScaleWidgetClass, mainform,
                  	[RXmNorientation, RXmHORIZONTAL,
                         RXmNshowValue,   true,
                         RXmNvalue,       100,
                         RXmNmaximum,     500,
                         RXmNdecimalPoints, 2])
      RXtAddCallback(scale, RXmNvalueChangedCallback, 
                     Proc.new { |w, context, info| $current_scaler = Rvalue(info) / 100.0})
      RXtAddCallback(scale, RXmNdragCallback, 
                     Proc.new { |w, context, info| $current_scaler = Rvalue(info) / 100.0})
      RXtManageChild $scale_dialog
    end
end

$Snd_widgets = main_widgets()
create_scale_dialog $Snd_widgets[1]

All of Snd is at your disposal once this module is loaded.

Snd and Gtk+

There are tons of examples of using the gtk module. snd-gtk.scm is one place to start. All of gtk and cairo, and much of pango and glib are accessible from the extension language. Here's the scale-dialog in xg/gtk:

(with-let *gtk*
  (define scale-dialog #f)
  (define current-scaler 1.0)

  (define (create-scale-dialog parent)
    (unless scale-dialog
	(set! scale-dialog (gtk_dialog_new))
	(g_signal_connect scale-dialog "delete-event"
			     (lambda (w ev info)
			       (gtk_widget_hide w)))
	(gtk_window_set_title (GTK_WINDOW scale-dialog) "Scale")
	(gtk_widget_realize scale-dialog)
	(let ((dismiss (gtk_button_new_with_label "Dismiss"))
	      (help (gtk_button_new_with_label "Help")))
	  (gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG scale-dialog))) dismiss #t #t 4)
	  (gtk_box_pack_end (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG scale-dialog))) help #t #t 4)	
	  (g_signal_connect dismiss "clicked"
			       (lambda (w info)
				 (gtk_widget_hide scale-dialog)))
	  (g_signal_connect help "clicked"
			       (lambda (w info)
				 (help-dialog "Scaler Dialog" "move the slider to affect the volume")))
	  (gtk_widget_show dismiss)
	  (gtk_widget_show help)
	  (let* ((adj (gtk_adjustment_new 0.0 0.0 1.01 0.01 0.01 .01))
		 (scale (gtk_scale_new GTK_ORIENTATION_HORIZONTAL (GTK_ADJUSTMENT adj))))
	    (gtk_scale_set_draw_value (GTK_SCALE scale) #t)
	    (gtk_scale_set_digits (GTK_SCALE scale) 2)
	    (g_signal_connect adj "value_changed"
				 (lambda (wadj info)
				   (set! current-scaler (gtk_adjustment_get_value (GTK_ADJUSTMENT wadj)))))
	    (gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG scale-dialog))) scale #f #f 6)
	    (gtk_widget_show scale))))
    (gtk_widget_show scale-dialog))

(create-scale-dialog (cadr (main-widgets))))

The only change from the C code is the addition of GTK_ADJUSTMENT in the scale value_changed callback — currently the xg module assumes the first argument to the two-argument callback is a GtkWidget, so we have to cast a GtkAdjustment back to its original type.

Snd with no GUI and as scripting engine

If Snd is built without a graphical user interface (by specifying --without-gui to configure), it runs the extension language's read-eval-print loop, with input from stdin. All the non-interface related functions are available, so you can do things like:

SchemeRubyForth
snd
:(new-sound "test.snd")
#<sound 0>
:(mix "oboe.snd")
(#<mix 0>)
:(framples)
50828
:(play)
#f
:(exit)
snd
> new_sound("test.snd")
0
> mix("oboe.snd")
[#<mix 0>]
> framples
50828
> play
false
> exit
snd
"test.snd" new-sound
0 ok
"oboe.snd" mix
-1 ok
framples
50828 ok
play
#f ok
snd-exit

Since there's no graphics toolkit event loop to get in your way, you can treat this version of Snd as a scripting engine. For example, if you have an executable file with:

#!/home/bil/test/snd-16/snd -l
!#
(define a-test 32)
(display "hiho")
(newline)

it can be executed just like any such script.

/home/bil/test/snd-16/ script
hiho
> a-test
32
> (exit)
/home/bil/test/snd-16/ 

As noted above, you can use the -e switch to use Snd as a pure command-line program, and, of course, (exit) to drop back to the shell. Here's a script that doubles every sample in "oboe.snd" and writes the result as "test.snd":

SchemeRubyForth
#!/home/bil/snd-16/snd -l
!#
(open-sound "oboe.snd")
(scale-by 2.0)
(save-sound-as "test.snd")
(exit)
#!/home/bil/snd-16/snd -batch
open_sound "oboe.snd"
scale_by 2.0
save_sound_as "test.snd"
exit
#! /usr/bin/env /home/bil/forth-snd/snd
"oboe.snd" open-sound drop
2.0 #f #f scale-by drop
"test.snd" save-sound-as
snd-exit

The functions script-args and script-arg can be used to access the script's arguments, and if necessary (if not exiting) tell Snd to ignore arguments. script-args returns a list of strings giving the arguments. The first two are always "-l" and the script file name. The current argument is (script-arg). If you set this to a higher value, Snd will subsequently ignore the intervening arguments as it scans the startup arguments (see snd-test.scm).

#!/home/bil/test/snd-16/snd -l
!#
(if (= (length (script-args)) 2) ;i.e. ("-l" "script")
  (display "usage: script file-name...")
  (begin
    (open-sound ((script-args) (+ (script-arg) 1)))
    (scale-by 2.0)
    (save-sound-as "test.snd")))
(exit)

This either grumbles if no argument is given, or scales its argument sound by 2.0:

script pistol.snd

And we can run through the entire argument list, doubling all the sounds or whatever by using a do loop — the following displays all the comments it finds:

#!/home/bil/cl/snd -l
!#
(if (= (length (script-args)) 2) ;i.e. ("-l" "script")
  (display "usage: script file-name...")
  (do ((arg (+ (script-arg) 1) (+ 1 arg)))
      ((= arg (length (script-args))))
    (let ((name ((script-args) arg)))
      (display (format #f "~A: ~A~%" name (mus-sound-comment name))))))
(exit)

Say we save this as the file "comments".

/home/bil/cl/comments *.snd

If you like, you can use env:

#!/usr/bin/env snd
!#

But if that works, so will:

#!snd -l
!#

This scripting mechanism actually will work in any version of Snd; to keep the Snd window from popping up, use the -b (-batch) switch in place of -l. Here's another script; it looks for any sounds that are longer than 40 seconds in duration, and truncates them to 40 seconds:

#!/usr/local/bin/snd -l
!#
(if (= (length (script-args)) 2)
  (display "usage: trunc.scm file-name...")
  (do ((arg (+ (script-arg) 1) (+ 1 arg)))
      ((= arg (length (script-args))))
    (let* ((name ((script-args) arg)))
      (if (> (mus-sound-duration name) 40.0)
	  (let* ((ind (open-sound name)))
	    (set! (framples ind) (* 40 (srate ind)))
	    (save-sound ind)
	    (close-sound ind))))))
(exit)

Here's a sndplay replacement script:

#!snd -b
!#
(play ((script-args) (+ (script-arg) 1)) :wait #t)
(exit)

And here's a script that splits a multichannel file into a bunch of mono files:

#!snd -b
!#
(if (= (length (script-args)) 2)
  (display "usage: split.scm filename")
  (let* ((name ((script-args) (+ 1 (script-arg))))
	 (chns (channels name)))
    (if (> chns 1)
	(let ((ind (open-sound name)))
	  (do ((i 0 (+ i 1)))
	      ((= i chns))
	    (display (format #f "~A.~D " name i))
	    (save-sound-as (format #f "~A.~D" name i)
			   ind
			   (srate ind)
			   (sample-type ind)
			   (header-type ind)
			   i))
	  (close-sound ind)))))
(exit)
Snd with Ruby

Ruby is an extension language described as an "object-oriented Perl". It provides a different syntax from that of Scheme; most of the *.scm (Scheme) files have corresponding *.rb (Ruby) files (written by Mike Scholz), so there's no penalty for using Ruby rather than Scheme. The only drawback is that the documentation uses Scheme. The differences between Scheme and Ruby, however, are not too severe. In Ruby, the following changes are made in the function names (as presented in Scheme): "-" becomes "_", "->" becomes "2", hooks and current_sound have "$" prepended (since they are global variables from Ruby's point of view), and all the constants are capitalized (e.g. Autocorrelation). The generalized set! functions are replaced by "set_" plus the base name (e.g. set_window_width), with arguments reordered in some cases to place the optional values after the new value. That is, (set! (sync snd) 1) becomes set_sync(1, snd). Hooks in Ruby (which have little or nothing to do with Ruby's "hookable variables") are just procedures or nil, not lists of procedures as in Scheme. Here's a Ruby version of the init file given above (named ~/.snd_ruby):

set_window_width 800
set_window_height 500

set_listener_font "9x15"
set_axis_numbers_font "9x15"

set_show_mix_waveforms true
set_show_indices true

set_listener_prompt ":"
show_listener

beige = make_color 0.96, 0.96, 0.86
blue = make_color 0, 0, 1
set_selected_graph_color beige
set_selected_data_color blue

Procedures are created via Proc.new, so to set the open-hook to print the file name,

>$open_hook = Proc.new { |name| snd_print name }
#<Proc:0x40221b84>
>open_sound "oboe.snd"
/home/bil/cl/oboe.snd
0

(The trailing "0" is the result of open_sound). The Scheme hook list support procedures aren't included in Ruby — simply set the variable to the procedure you want, or false to clear it.

Vcts mixin "Comparable" and "Enumerable", and respond to various array-like methods:

>v1 = make_vct 4
#<vct[len=4]: 0.000 0.000 0.000 0.000>
>v1[3] = 1.0
1.0
>v1.sort
0.00.00.01.0 # I don't know why it prints this way but ...
>v1
#<vct[len=4]: 0.000 0.000 0.000 1.000>
>v1.max
1.0

Keywords, CLM generic functions, and optional arguments work as in Scheme:

>osc = make_oscil(:frequency, 440)
oscil freq: 440.000Hz, phase: 0.000
>oscil osc
0.0
>oscil osc
0.1250506192
>osc.frequency
440.0

Lists (from the Scheme point of view) are arrays (vectors) in Ruby. Here's one more example, a translation of display-energy in draw.scm:

def display_energy(snd, chn)
  ls = left_sample
  rs = right_sample
  data1 = make_graph_data(snd, chn)
  data = data1
  if not vct? data
    data = data1[1]
  end
  len = vct_length data
  sr = srate snd
  y_max = y_zoom_slider(snd, chn)
  vct_multiply!(data, data)
  graph(data, "energy", ls / sr, rs / sr, 0.0, y_max * y_max, snd, chn, false)
  end

# $lisp_graph_hook = Proc.new {|snd, chn| display_energy(snd, chn)}

In Ruby you make a symbol by prepending ":", so Scheme's

(list 'KeySym (char->integer #\F))

becomes

[:KeySym, ?F]

In the listener, everything is line-oriented (that is, I'm not trying to catch incomplete expressions). And it appears that in Ruby, variables defined within a file are considered local to that file(?). For Ruby as an Emacs subjob, see inf-snd.el.

Snd with Forth

Snd can be built with Forth as its extension language. Forth is available at:

http://sourceforge.net/projects/fth

An example initialization file (~/.snd_forth) is given in the initialization section. Mike Scholz (creator of the Forth library we use) has provided a bunch of Forth files along the lines of the Scheme and Ruby files described above — see *.fs. See also Mike's very fine documentation in the fth package. Here's an example from his fth.texi file showing how to define an instrument and use it in with-sound:

instrument: src-simp { start dur amp sr sr-env fname -- }
    :file fname make-readin { f }
    :input f input-fn :srate sr make-src { sr }
    :envelope sr-env :duration dur make-env { en }
    start dur run
        i                 \ sample position for outa
        sr en env #f src
        amp f*
        *output* outa drop
    loop
    f mus-close drop
;instrument
"/usr/gnu/sound/SFiles/fyow.snd" value fyow-snd
#( 0.0 0.0 50.0 1.0 100.0 0.0 ) value sr-env
0.0 1.5 0.5 0.2 sr-env array->list fyow-snd ' src-simp with-sound
Snd with s7

s7 is a Scheme implementation included in the Snd tarball and described in s7.html. It is now the Snd default extension language.

The s7 initialization file is ~/.snd_s7.

Snd and LADSPA Plugins
init-ladspa
list-ladspa
analyse-ladspa library plugin [also analyze-ladspa]
ladspa-descriptor library plugin
apply-ladspa reader data duration origin snd chn

ladspa-instantiate descriptor srate
ladspa-activate descriptor handle
ladspa-deactivate descriptor handle
ladspa-cleanup descriptor handle
ladspa-connect-port descriptor handle port float-vector
ladspa-run descriptor handle count
ladspa-run-adding descriptor handle count
ladspa-set-run-adding-gain descriptor handle gain

Richard Furse has provided a module to support LADSPA plugins in Snd. Here is his documentation:

Supporting functions are:

	(init-ladspa)

	Performs a search of LADSPA_PATH for plugins, doesn't need to be called 
as LADSPA automatically initialises on first use however can be used to 
reinitialise if new plugins have arrived.

	(list-ladspa)

	Returns a list of lists where each inner list contains a string to 
identify the plugin library and a string to identify the plugin type within 
the library.

	(analyse-ladspa plugin-library plugin-type)

	Returns a list of assorted data about a particular plugin including a 
list of port descriptions. plugin-library and plugin-type are as provided 
by list-ladspa.

The main function is:

	(apply-ladspa reader (plugin-library plugin-type [param1 [param2 ...]]) samples origin snd chn)

	Applies a LADSPA plugin to a block of samples. 
An example call to apply the low-pass-filter in the CMT plugin library is 
(apply-ladspa (make-sampler 0) (list "cmt" "lpf" 1000) 10000 "origin").

Dave Phillips in Linux Audio Plug-Ins: A Look Into LADSPA adds this:

(apply-ladspa (make-sampler 57264) (list "cmt" "delay_5s" .3 .5) 32556 "ibm.wav")

"This sequence tells Snd to read a block of 32556 samples from the ibm.wav file, starting at sample number 57264, and apply the delay_5s LADSPA plug-in (Richard Furse's delay plug-in, also found in cmt.so) with a delay time of .3 seconds and a 50/50 dry/wet balance."

To help Snd find the plugin library, set either the Snd variable ladspa-dir or the environment variable LADSPA_PATH to the directory. If, for example, cmt.so is in /usr/local/lib/ladspa, (and you're using tcsh), then

setenv LADSPA_PATH /usr/local/lib/ladspa

or

(set! *ladspa-dir* "/usr/local/lib/ladspa")

Snd plugins may have any number of inputs and outputs; if more than one input is required, the first argument to apply-ladspa should be a list of readers:

(apply-ladspa (list (make-sampler 0 0 0)  ;chan 0
                      (make-sampler 0 0 1)) ;chan 1
                (list "cmt" "freeverb3" 0 .5 .5 .5 .5 .5) 
                100000 "freeverb")

The "regularized" version of apply-ladspa could be defined:

(define* (ladspa-channel ladspa-data (beg 0) ndur snd chn (edpos -1))
  (let ((dur (or ndur (- (framples snd chn) beg)))
	(reader (make-sampler beg snd chn 1 edpos)))
    (let ((result (apply-ladspa reader ladspa-data dur "apply-ladspa" snd chn)))
      (free-sampler reader)
      result)))

There are also functions to access the LADSPA descriptor directly:

(define ptr (ladspa-descriptor "amp" "amp_mono"))
(.Label ptr)
    "amp_mono"
(.Name ptr)
    "Mono Amplifier"
(.Copyright ptr)
    "None"
(.Maker ptr)
    "Richard Furse (LADSPA example plugins)"
(.Properties ptr)
    4
(.UniqueID ptr)
    1048
(.PortNames ptr)
    ("Gain" "Input" "Output")
(.PortRangeHints ptr)
    ((593 0.0 0.0) (0 0.0 0.0) (0 0.0 0.0))
(.PortCount ptr)
    3
(.PortDescriptors ptr)
    (5 9 10)
(logand (cadr (.PortDescriptors ptr)) LADSPA_PORT_INPUT)
    1

See ladspa.h for full details. We could replace analyse-ladspa using these functions:

(define (analyze-ladspa library label)
  (let* ((descriptor (ladspa-descriptor library label))
	 (data ())
	 (names (.PortNames descriptor))
	 (hints (.PortRangeHints descriptor))
	 (descriptors (.PortDescriptors descriptor))
	 (name (.Name descriptor))
	 (maker (.Maker descriptor))
	 (copy (.Copyright descriptor)))
    (for-each
     (lambda (port ranges port-name)
       (if (and (not (= (logand port LADSPA_PORT_CONTROL) 0))
		(not (= (logand port LADSPA_PORT_INPUT) 0)))
	   (let ((ldata ())
		 (hint (car ranges))
		 (lo (cadr ranges))
		 (hi (caddr ranges)))
	     (if (not (= (logand hint LADSPA_HINT_TOGGLED) 0)) (set! ldata (cons "toggle" ldata)))
	     (if (not (= (logand hint LADSPA_HINT_LOGARITHMIC) 0)) (set! ldata (cons "logarithmic" ldata)))
	     (if (not (= (logand hint LADSPA_HINT_INTEGER) 0)) (set! ldata (cons "integer" ldata)))
	     (if (not (= (logand hint LADSPA_HINT_SAMPLE_RATE) 0)) (set! ldata (cons "sample_rate" ldata)))
	     (if (not (= (logand hint LADSPA_HINT_BOUNDED_ABOVE) 0)) 
		 (set! ldata (cons "maximum" (cons hi ldata))))
	     (if (not (= (logand hint LADSPA_HINT_BOUNDED_BELOW) 0))
	         (set! ldata (cons "minimum" (cons lo ldata))))
	     (set! ldata (cons port-name ldata))
	     (set! data (cons ldata data)))))
     descriptors hints names)
    (append (list name maker copy) data)))
Snd and ALSA

(This section is a lightly edited copy of some notes Fernando sent me). The default ALSA device in Snd is "default". This virtual device tries to play sounds at any sampling rate, provide any number of input channels, handle sample type conversions, and so on. Experts will probably want to use the "hw:0" device instead (this is the first hardware device; "hw:1" is the second, and so on), but in that case, ALSA provides only whatever sampling rates the hardware provides. To change the device, or the internal buffering amounts, you can either set up environment variables, or use the parallel Scheme/Ruby/Forth variables mus-alsa-*. The environment variables are:

MUS_ALSA_PLAYBACK_DEVICE   name of playback device ("default")
MUS_ALSA_CAPTURE_DEVICE    name of capture (recording) device ("default")
MUS_ALSA_DEVICE            name of the playback and capture device ("sndlib")
MUS_ALSA_BUFFERS           number of "periods" (buffers) used
MUS_ALSA_BUFFER_SIZE       number of samples per channel per buffer

These can be set either in your shell initialization file (~/.cshrc for tcsh), or in the shell:

setenv MUS_ALSA_DEVICE "hw:0"   ; tcsh
MUS_ALSA_DEVICE="hw:0"          ; bash

or run Snd with a temporary setting:

MUS_ALSA_DEVICE="plughw:0" snd somefile.wav

The parallel variables (for ~/.snd and friends, or at any time in the listener), are:

mus-alsa-playback-device     name of playback device ("default")
mus-alsa-capture-device      name of capture (recording) device ("default")
mus-alsa-device              name of the playback and capture device ("sndlib")
mus-alsa-buffers             number of "periods" (buffers) used
mus-alsa-buffer-size         number of samples per channel per buffer

So, to use the "plughw" device, we could:

(set! (mus-alsa-device) "plughw:0")

It's also possible to define your own device, apparently, but that part of ALSA is beyond my ken.

Snd and Jack

(This section is from Kjetil Matheussen).

SNDLIB_JACK_DONT_AUTOCONNECT   If set, snd won't autoconnect jack ports
SNDLIB_NUM_JACK_CHANNELS       Number of in and out jack ports created by snd
Snd and OpenGL

Snd with Motif can be used in conjunction with OpenGL. If it is configured with the switch --with-gl or --with-just-gl, the top level Snd shell is setup to handle OpenGL graphics. These are used automatically by the spectrogram display; the colormap and viewing angle are set by either the View:Color/Orientation dialog or colormap, and the various spectro-* variables.

gl

The GL-to-Scheme bindings are in gl.c, and follow the same name and type conventions of the Motif bindings in xm.c. Any of the Snd drawing area widgets (or your own) can receive GL graphics commands. Here is a translation of the SGI/xjournal glxmotif program:

(define (draw-it)
  (glXMakeCurrent (XtDisplay (cadr (main-widgets))) 
		  (XtWindow (car (channel-widgets)))
		  (snd-glx-context)) ; the GL context
  (glEnable GL_DEPTH_TEST)
  (glDepthFunc GL_LEQUAL)
  (glClearDepth 1.0)
  (glClearColor 0.0 0.0 0.0 0.0)
  (glLoadIdentity)
  (gluPerspective 40.0 1.0 10.0 200.0)
  (glTranslatef 0.0 0.0 -50.0)
  (glRotatef -58.0 0.0 1.0 0.0)
  (let ((vals (XtVaGetValues (car (channel-widgets)) (list XmNwidth 0 XmNheight 0))))
    (glViewport 0 0 (vals 1) (vals 3)))
  (glClear (logior GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT))
  (glBegin GL_POLYGON)
  (glColor3f 0.0 0.0 0.0)   (glVertex3f -10.0 -10.0 0.0)
  (glColor3f 0.7 0.7 0.7)   (glVertex3f 10.0 -10.0 0.0)
  (glColor3f 1.0 1.0 1.0)   (glVertex3f -10.0 10.0 0.0)
  (glEnd)
  (glBegin GL_POLYGON)
  (glColor3f 1.0 1.0 0.0)   (glVertex3f 0.0 -10.0 -10.0)
  (glColor3f 0.0 1.0 0.7)   (glVertex3f 0.0 -10.0 10.0)
  (glColor3f 0.0 0.0 1.0)   (glVertex3f 0.0 5.0 -10.0)
  (glEnd)
  (glBegin GL_POLYGON)
  (glColor3f 1.0 1.0 0.0)   (glVertex3f -10.0 6.0 4.0)
  (glColor3f 1.0 0.0 1.0)   (glVertex3f -10.0 3.0 4.0)
  (glColor3f 0.0 0.0 1.0)   (glVertex3f 4.0 -9.0 -10.0)
  (glColor3f 1.0 0.0 1.0)   (glVertex3f 4.0 -6.0 -10.0)
  (glEnd)
  (glXSwapBuffers (XtDisplay (cadr (main-widgets))) 
		  (XtWindow (car (channel-widgets))))
  (glFlush))

See snd-gl.scm. To turn these graphs into Postscript files, include the --with-gl2ps switch at configuration time, and use the gl-graph->ps function.

Snd and GSL

If the GSL library is available, the following functions are imported into Snd:

gsl-eigenvectors matrix

gsl-eigenvectors returns the eigenvalues and corresponding eigenvectors of "matrix", a float-vector in s7, a vct otherwise. The value returned is a list of two elements. The first is a vector containing the eigenvalues, the second is a vector containing the corresponding eigenvectors (as vectors).

gsl-ellipk k
gsl-ellipj j u m

These are calls on the functions gsl_sf_ellint_Kcomp and gsl_sf_elljac_e. See the elliptic filter code in analog-filter.scm for an example.

gsl-roots poly

This returns the roots of the polynomial "poly" via gsl_poly_complex_solve. See analog-filter.scm for an example.

Snd and multiprecision arithmetic

Multiprecision arithmetic for integer, ratio, real, and complex numbers is available in Snd via the gmp, mpfr, and mpc libraries and s7. Use the --with-gmp configuration switch. This version of s7 also supplies the functions:

bignum num

bignum converts its argument (a string) into a big number. This is the most convenient way to force a calculation to use big numbers.

> (sqrt 2)
1.4142135623731
> (sqrt (bignum "2"))
1.414213562373095048801688724209698078569E0

s7 uses normal C arithmetic unless something causes it to be suspicious. Since a number like 1.2345e-14 does not trigger an underflow in C, and is short (it's written with less than 20 characters), s7 trusts it even in a case such as:

> (+ 1.2345e-15 1.0 -1.0)
1.3322676295502e-15

In any case like this where C doubles are going to lose, you can force big float arithmetic by making one of the operands a bignum:

> (+ (bignum "1.2345e-15") 1.0 -1.0)
1.234500000000000042481989819014552503046E-15

There are lots of similar cases:

> (* 2e-170 3e-170 4e+170 5e+170)
0.0
> (* (bignum "2e-170") 3e-170 4e+170 5e+170)
1.200000000000000019643628722298292475697E2

but presumably you know when you're using these kinds of numbers.

bignum? num

bignum? returns #t if its argument is a big number.

bignum-fft rl im size sign

bignum-fft performs an FFT using big floats; rl and im are vectors of big floats.

(*s7* 'bignum-precision)

bignum-precision sets the number of bits used in floating-point big numbers (integer bignums have whatever size it takes to represent them). The default is 128 which gives about 40 decimal digits.

> (* 2 pi)
6.283185307179586476925286766559005768391E0
> (set! (*s7* 'bignum-precision) 256)
256
> (* 2 pi)
6.283185307179586476925286766559005768394338798750211641949889184615632812572396E0

If a big float is so large that the current bignum-precision has to approximate it, you can get confusing results:

> (rationalize 385817946978768113605842402465609185854927496022065152.5)
385817946978768113605842402465609185854927496022065152
> (set! (*s7* 'bignum-precision) 512)
512
> (rationalize 385817946978768113605842402465609185854927496022065152.5)
771635893957536227211684804931218371709854992044130305/2

Yet another source of confusion involves the conversion of the string representation of a bigfloat:

> (bignum "0.1")
1.000000000000000055511151231257827021182E-1
> (/ (bignum "1.0") 10)
1.000000000000000000000000000000000000001E-1
Other stuff

lint.scm is a lint program for s7 scheme.

primes.scm is a list of primes for the peak phases functions.

The tools directory has several things that might be of interest. sam.c is a Samson box emulator. crossref.c is a cross-referencer for the Snd sources. xgdata.scm and makexg.scm create xg.c, the Gtk bindings. Similarly gldata.scm and makegl.scm create gl.c, the OpenGL bindings. make-index.scm creates index.html, the overall Snd index, and performs a lot of HTML error checks. snd.supp is the suppressions list for valgrind. table.scm creates the table of contents at the start of snd-test.scm. The other files in the tools directory are intended for semi-automatic regression testing.

snd-16.1/rubber.fs0000644000076400007640000002034312327441227012154 0ustar bilbil\ rubber.fs -- rubber.scm --> rubber.fs \ Translator: Michael Scholz \ Created: 06/01/06 05:32:57 \ Changed: 14/04/28 03:52:17 \ \ @(#)rubber.fs 1.15 4/28/14 \ original comments are taken from rubber.scm [ms] \ \ ;;; rubber.scm: rubber-sound stretches or contracts a sound (in time) \ ;;; (rubber-sound 1.5) makes it 50% longer \ ;;; rubber-sound looks for stable portions and either inserts or deletes \ ;;; periods period length is determined via autocorrelation require clm require marks 8 value zeros-checked 10.0 value extension *fth-verbose* value show-details hide \ ;;; remove anything below 16Hz \ ;;; extend (src by 1/extension) \ ;;; collect upward zero-crossings \ ;;; collect weights for each across next zeros-checked crossings \ ;;; sort by least weight \ ;;; ramp (out or in) and check if done : derumble-sound { snd chn -- } \ ;; remove rumbles and DC etc (since we're using zero crossings \ ;; to find period starts) snd chn #f framples { old-len } snd srate { sr } #( 0.0 0.0 16.0 f2* sr f/ 0.0 20.0 f2* sr f/ 1.0 1.0 1.0 ) ( flt-lst ) 2.0 old-len sr min flog 2.0 flog f/ fceil ( pow2 ) f** f>s ( fftlen ) snd chn #f undef filter-sound drop old-len snd chn set-framples drop ; : sample-sound { snd chn -- } \ ;; prepare sound for analysis by interpolating samples extension 1.0 f<> if extension 1/f 1.0 snd chn #f src-sound drop then ; : unsample-sound { snd chn -- } \ ;; undo earlier interpolation extension 1.0 f<> if extension 1.0 snd chn #f src-sound drop then ; : crossings { snd chn -- n } \ ;; return number of upward zero crossings that don't look like silence 0 0 { crosses last-cross } 0 snd chn 1 #f make-sampler { sr0 } sr0 next-sample { samp0 } 0.0 { sum } extension 0.001 f* { silence } snd chn #f framples 0 ?do sr0 next-sample { samp1 } samp0 f0<= samp1 f0> && i last-cross - 4 > && sum silence f> && if crosses 1+ to crosses i to last-cross 0.0 to sum then samp0 fabs sum f+ to sum samp1 to samp0 loop crosses ; : env-add { s0 s1 samps snd chn -- vct } 1.0 { x } samps 1/f { xinc } s0 snd chn 1 #f make-sampler { sr0 } s1 snd chn 1 #f make-sampler { sr1 } samps 0.0 make-vct map! sr0 next-sample x f* sr1 next-sample 1.0 x f- f* f+ ( val ) x xinc f+ to x ( val ) end-map ( data ) ; : rubber-cb { stretch snd chn -- prc; self -- } 0 proc-create ( prc ) chn , snd , stretch , does> { self -- } self @ { chn } self cell+ @ { snd } self 2 cells + @ { stretch } \ ;; prepare sound (get rid of low freqs, resample) snd chn derumble-sound snd chn sample-sound snd chn crossings { crosses } crosses :initial-element 0 make-array { cross-samples } crosses :initial-element 0 make-array { cross-weights } crosses :initial-element 0 make-array { cross-marks } crosses :initial-element 0 make-array { cross-periods } \ ;; get cross points (sample numbers) 0 snd chn 1 #f make-sampler { sr0 } sr0 next-sample { samp0 } 0.0 { sum } 0 { last-cross } extension 0.001 f* { silence } snd chn #f framples 0 ?do sr0 next-sample { samp1 } samp0 f0<= samp1 f0> && i last-cross - 40 > && sum silence f> && if i to last-cross 0.0 to sum cross-samples i cycle-set! then samp0 fabs sum f+ to sum samp1 to samp0 loop \ ;; now run through crosses getting period match info crosses 1- 0 ?do cross-samples i array-ref { start } 0 { autolen } 2.0 extension snd srate 40.0 f/ f* flog 2.0 flog f/ fceil ( pow2 ) f** f>s { fftlen } fftlen 4 / { len4 } start snd chn 1 #f make-sampler { rd } fftlen 0.0 make-vct map! rd next-sample end-map { data } data autocorrelate drop len4 1 ?do data i vct-ref data i 1+ vct-ref f< data i 1+ vct-ref data i 2 + vct-ref f> && if i 2* to autolen leave then loop start autolen + { next-start } i 1+ { min-i } cross-samples min-i array-ref next-start - abs { min-samps } crosses i zeros-checked + min i 2 + ?do cross-samples i array-ref next-start - abs { dist } dist min-samps < if dist to min-samps i to min-i then loop min-i { current-mark } 0.0 { current-min } cross-samples current-mark array-ref { s1 } start snd chn 1 #f make-sampler { sr0 } s1 snd chn 1 #f make-sampler { sr1 } 0.0 0.0 { ampsum diffsum } autolen 0 ?do sr0 next-sample { samp0 } sr1 next-sample { samp1 } samp0 fabs ampsum f+ to ampsum samp1 samp0 f- fabs diffsum f+ to diffsum loop diffsum f0= if 0.0 else diffsum ampsum f/ then to current-min current-min f2/ fround->s to min-samps current-mark zeros-checked i + min crosses 1- min { top } top i 1+ ?do 0.0 { wgt } cross-samples i array-ref { s1 } start snd chn 1 #f make-sampler { sr0 } s1 snd chn 1 #f make-sampler { sr1 } 0.0 0.0 { ampsum diffsum } autolen 0 ?do sr0 next-sample { samp0 } sr1 next-sample { samp1 } samp0 fabs ampsum f+ to ampsum samp1 samp0 f- fabs diffsum f+ to diffsum loop diffsum f0= if 0.0 else diffsum ampsum f/ then to wgt wgt min-samps f< if wgt f>s to min-samps i to min-i then loop current-mark min-i <> if \ ;; these are confused, so effectively erase them cross-weights i 1000.0 array-set! else cross-weights i current-min array-set! cross-marks i current-mark array-set! cross-periods i cross-samples current-mark array-ref cross-samples i array-ref - array-set! then loop \ ;; now sort weights to scatter the changes as evenly as possible snd chn #f framples { len } stretch 1.0 f> { adding } stretch 1.0 f- fabs len f* floor f>s { samps } adding if samps else len samps 2* min then { needed-samps } 0 { handled } #() { edits } begin \ ;; need to find (more than) enough splice pts to delete samps -1 { best-mark } handled { old-handled } 0 { cur } cross-weights 0 array-ref { curmin } cross-weights each { val } val curmin f< if i to cur val to curmin then end-each cur to best-mark cross-periods best-mark array-ref handled + to handled handled needed-samps < handled needed-samps - needed-samps old-handled - < || if edits best-mark array-push drop then cross-weights best-mark 1000.0 array-set! edits length crosses = handled needed-samps >= || until edits length crosses >= if needed-samps handled f/ fceil f>s else 1 then { mult } 0 { changed-len } edits each { best-mark } changed-len samps > ?leave cross-samples best-mark array-ref { beg } cross-samples cross-marks best-mark array-ref array-ref { next-beg } cross-periods best-mark array-ref { len } len 0> if adding if beg next-beg len snd chn env-add { new-samps } show-details if beg "%d:%d" #( i len extension f/ f>s ) string-format snd chn add-named-mark drop then beg len new-samps snd chn #f insert-samples drop mult 1 ?do beg len i * + len new-samps snd chn #f insert-samples drop loop len mult * changed-len + to changed-len cross-samples each { curbeg } curbeg beg > if cross-samples i curbeg len + array-set! then end-each else beg snd chn #f framples >= if "trouble at %d: %d of %d" #( i beg snd chn #f framples ) clm-message then show-details if beg 1- "%d:%d" #( i len extension f/ f>s ) string-format snd chn add-named-mark drop then beg len snd chn #f delete-samples drop changed-len len + to changed-len beg len + { end } cross-samples each { curbeg } curbeg beg > if curbeg end < if cross-periods i 0 array-set! else cross-samples i curbeg len - array-set! then then end-each then then end-each show-details if "wanted: %d, got %d" #( samps changed-len ) clm-message then \ ;; and return to original srate snd chn unsample-sound show-details if snd chn 0 framples { frms0 } snd chn undef framples { frms } "%d -> %d (%d)" #( frms0 frms frms0 stretch f* floor f>s ) clm-message then ; set-current : rubber-sound { stretch snd chn -- res } "%s %s" #( stretch get-func-name ) string-format { origin } stretch snd chn rubber-cb origin as-one-edit ; previous \ rubber.fs ends here snd-16.1/sndlib-strings.h0000644000076400007640000001131212524201704013441 0ustar bilbil#ifndef SNDLIB_STRINGS_H #define SNDLIB_STRINGS_H #define S_array_to_file "array->file" #define S_file_to_array "file->array" #define S_mus_aifc "mus-aifc" #define S_mus_aiff "mus-aiff" #define S_mus_alaw "mus-alaw" #define S_mus_alsa_buffer_size "mus-alsa-buffer-size" #define S_mus_alsa_buffers "mus-alsa-buffers" #define S_mus_alsa_capture_device "mus-alsa-capture-device" #define S_mus_alsa_device "mus-alsa-device" #define S_mus_alsa_playback_device "mus-alsa-playback-device" #define S_mus_alsa_squelch_warning "mus-alsa-squelch-warning" #define S_mus_b24int "mus-b24int" #define S_mus_bdouble "mus-bdouble" #define S_mus_bdouble_unscaled "mus-bdouble-unscaled" #define S_mus_bfloat "mus-bfloat" #define S_mus_bfloat_unscaled "mus-bfloat-unscaled" #define S_mus_bicsf "mus-bicsf" #define S_mus_bint "mus-bint" #define S_mus_bintn "mus-bintn" #define S_mus_bshort "mus-bshort" #define S_mus_byte "mus-byte" #define S_mus_bytes_per_sample "mus-bytes-per-sample" #define S_mus_caff "mus-caff" #define S_mus_clipping "mus-clipping" #define S_mus_sample_type_name "mus-sample-type-name" #define S_mus_sample_type_to_string "mus-sample-type->string" #define S_mus_error_type_to_string "mus-error-type->string" #define S_mus_expand_filename "mus-expand-filename" #define S_mus_file_clipping "mus-file-clipping" #define S_mus_header_raw_defaults "mus-header-raw-defaults" #define S_mus_header_type_name "mus-header-type-name" #define S_mus_header_type_to_string "mus-header-type->string" #define S_mus_header_writable "mus-header-writable" #define S_mus_ircam "mus-ircam" #define S_mus_l24int "mus-l24int" #define S_mus_ldouble "mus-ldouble" #define S_mus_ldouble_unscaled "mus-ldouble-unscaled" #define S_mus_lfloat "mus-lfloat" #define S_mus_lfloat_unscaled "mus-lfloat-unscaled" #define S_mus_lint "mus-lint" #define S_mus_lintn "mus-lintn" #define S_mus_lshort "mus-lshort" #define S_mus_max_malloc "mus-max-malloc" #define S_mus_max_table_size "mus-max-table-size" #define S_mus_mulaw "mus-mulaw" #define S_mus_next "mus-next" #define S_mus_nist "mus-nist" #define S_mus_oss_set_buffers "mus-oss-set-buffers" #define S_mus_out_format "mus-out-format" #define S_mus_raw "mus-raw" #define S_mus_rf64 "mus-rf64" #define S_mus_riff "mus-riff" #define S_mus_sound_chans "mus-sound-chans" #define S_mus_sound_comment "mus-sound-comment" #define S_mus_sound_sample_type "mus-sound-sample-type" #define S_mus_sound_data_location "mus-sound-data-location" #define S_mus_sound_datum_size "mus-sound-datum-size" #define S_mus_sound_duration "mus-sound-duration" #define S_mus_sound_forget "mus-sound-forget" #define S_mus_sound_framples "mus-sound-framples" #define S_mus_sound_header_type "mus-sound-header-type" #define S_mus_sound_length "mus-sound-length" #define S_mus_sound_loop_info "mus-sound-loop-info" #define S_mus_sound_mark_info "mus-sound-mark-info" #define S_mus_sound_maxamp "mus-sound-maxamp" #define S_mus_sound_maxamp_exists "mus-sound-maxamp-exists?" #define S_mus_sound_path "mus-sound-path" #define S_mus_sound_prune "mus-sound-prune" #define S_mus_sound_report_cache "mus-sound-report-cache" #define S_mus_sound_samples "mus-sound-samples" #define S_mus_sound_srate "mus-sound-srate" #define S_mus_sound_type_specifier "mus-sound-type-specifier" #define S_mus_sound_write_date "mus-sound-write-date" #define S_mus_soundfont "mus-soundfont" #define S_mus_svx "mus-svx" #define S_mus_ubshort "mus-ubshort" #define S_mus_ubyte "mus-ubyte" #define S_mus_ulshort "mus-ulshort" #define S_mus_unknown_header "mus-unknown-header" #define S_mus_unknown_sample "mus-unknown-sample" #define S_mus_voc "mus-voc" #define S_new_sound_hook "new-sound-hook" #endif snd-16.1/snd-nogui1.h0000644000076400007640000002630412471670274012507 0ustar bilbil#ifndef SND_NOGUI1_H #define SND_NOGUI1_H /* -------- snd-xhelp.c -------- */ int snd_help(const char *subject, const char *help, with_word_wrap_t with_wrap); int snd_help_with_xrefs(const char *subject, const char *helpstr, with_word_wrap_t with_wrap, const char **xrefs, const char **urls); int help_text_width(const char *txt, int start, int end); void snd_help_append(const char *text); void snd_help_back_to_top(void); /* -------- snd-xdraw.c -------- */ void draw_line(graphics_context *ax, int x0, int y0, int x1, int y1); void fill_rectangle(graphics_context *ax, int x0, int y0, int width, int height); void erase_rectangle(chan_info *cp, graphics_context *ax, int x0, int y0, int width, int height); void fill_polygon(graphics_context *ax, int points, ...); void fill_polygons(graphics_context *ax, point_t *points, int num, int y0); void fill_two_sided_polygons(graphics_context *ax, point_t *points, point_t *points1, int num); void draw_string(graphics_context *ax, int x0, int y0, const char *str, int len); void draw_dot(graphics_context *ax, int x, int y, int size); void setup_graphics_context(chan_info *cp, graphics_context *ax); void draw_spectro_line(graphics_context *ax, int color, int x0, int y0, int x1, int y1); void allocate_color_map(int colormap); void allocate_sono_rects(int size); void set_sono_rectangle(int j, int color, int x, int y, int width, int height); void draw_sono_rectangles(graphics_context *ax, int color, int jmax); void draw_colored_lines(chan_info *cp, graphics_context *ax, point_t *points, int num, int *colors, int axis_y0, color_t default_color); widget_t make_color_orientation_dialog(bool managed); void set_color_scale(mus_float_t val); void set_color_inverted(bool val); void set_color_cutoff(mus_float_t val); void set_spectro_hop(int val); void set_spectro_x_angle(mus_float_t val); void set_spectro_y_angle(mus_float_t val); void set_spectro_z_angle(mus_float_t val); void set_spectro_x_scale(mus_float_t val); void set_spectro_y_scale(mus_float_t val); void set_spectro_z_scale(mus_float_t val); bool color_orientation_dialog_is_active(void); void reflect_spectro(void); void set_with_gl(bool val, bool dpys); /* -------- snd-xfind.c -------- */ bool find_dialog_is_active(void); void save_find_dialog_state(FILE *fd); /* -------- snd-xlistener.c -------- */ void append_listener_text(int end, const char *msg); int save_listener_text(FILE *fp); void listener_append_and_prompt(const char *msg); void goto_listener(void); void listener_append(const char *msg); void handle_listener(bool new_state); bool listener_exists(void); int listener_height(void); int listener_width(void); void clear_listener(void); /* -------- snd-xmenu.c -------- */ void check_menu_labels(int key, int state, bool extended); void reflect_play_selection_stop(void); int menu_widget(int which_menu); void set_button_label(int label, const char *str); void post_basic_popup_menu(void *ev); void post_lisp_popup_menu(void *ev); void post_fft_popup_menu(void *ev); void post_selection_popup_menu(void *ev); /* -------- snd-xmain.c -------- */ color_t get_in_between_color(color_t fg, color_t bg); void snd_doit(int argc, char **argv); void auto_update_restart(void); void save_colors(FILE *Fp); /* -------- snd-xfft.c -------- */ void set_fft_window_beta(mus_float_t val); void set_fft_window_alpha(mus_float_t val); void set_transform_size(mus_long_t val); void set_fft_window(mus_fft_window_t val); void set_wavelet_type(int val); int make_transform_dialog(bool managed); bool transform_dialog_is_active(void); void set_transform_type(int val); void set_show_transform_peaks(bool val); void set_fft_log_magnitude(bool val); void set_fft_with_phases(bool val); void set_fft_log_frequency(bool val); void set_transform_normalization(fft_normalize_t val); void set_show_selection_transform(bool show); void set_transform_graph_type(graph_type_t val); void set_spectrum_start(mus_float_t val); void set_spectrum_end(mus_float_t val); void reflect_peaks_in_transform_dialog(void); void reflect_log_freq_start_in_transform_dialog(void); void reflect_min_db_in_transform_dialog(void); void make_transform_type_list(void); /* -------- snd-xregion.c -------- */ int update_region_browser(bool grf_too); bool region_browser_is_active(void); void delete_region_and_update_browser(int n); void reflect_play_region_stop(int n); bool region_dialog_is_active(void); void allocate_region_rows(int n); void reflect_regions_in_region_browser(void); void reflect_no_regions_in_region_browser(void); void reflect_region_graph_style(void); /* -------- snd-xutils.c -------- */ void goto_window(int text); bool set_tiny_font(const char *font); bool set_listener_font(const char *font); bool set_peaks_font(const char *font); bool set_bold_peaks_font(const char *font); bool set_axis_label_font(const char *font); bool set_axis_numbers_font(const char *font); int label_width(const char *txt, bool use_tiny_font); int number_width(const char *num, bool use_tiny_font); int number_height(int fnt); int label_height(bool use_tiny_font); int mark_name_width(const char *txt); void clear_window(graphics_context *ax); void set_title(const char *title); void check_for_event(void); void recolor_graph(chan_info *cp, bool selected); void set_sensitive(int wid, bool val); void set_toggle_button(int wid, bool val, bool passed, void *data); int widget_height(int w); int widget_width(int w); void set_widget_size(int w, int width, int height); int widget_x(int w); int widget_y(int w); void set_widget_x(int w, int x); void set_widget_y(int w, int y); void set_mix_color(int color); void ensure_scrolled_window_row_visible(widget_t list, int pos, int num_rows); /* -------- snd-xchn.c -------- */ int channel_w(chan_info *cp); int channel_f(chan_info *cp); int channel_graph(chan_info *cp); bool channel_graph_is_visible(chan_info *cp); void change_gzy(mus_float_t val, chan_info *cp); mus_float_t gsy_value(chan_info *cp); mus_float_t gsy_size(chan_info *cp); void initialize_scrollbars(chan_info *cp); void set_z_scrollbars(chan_info *cp, axis_info *ap); void resize_sx(chan_info *cp); void resize_sy(chan_info *cp); void resize_sy_and_zy(chan_info *cp); void resize_sx_and_zx(chan_info *cp); void channel_open_pane(chan_info *cp); void reflect_edit_history_change(chan_info *cp); void reflect_edit_counter_change(chan_info *cp); void set_peak_numbers_font(chan_info *cp, graphics_context *ax); void set_bold_peak_numbers_font(chan_info *cp, graphics_context *ax); void set_tiny_numbers_font(chan_info *cp, graphics_context *ax); color_t get_foreground_color(graphics_context *ax); void set_foreground_color(graphics_context *ax, int color); void cleanup_cw(chan_info *cp); void get_current_color(int colormap, int j, rgb_t *r, rgb_t *g, rgb_t *b); void change_channel_style(snd_info *sp, channel_style_t new_style); int add_channel_window(snd_info *sound, int channel, int chan_y, int insertion, widget_t main, fw_button_t arrows, bool with_events); /* -------- snd-xsnd.c -------- */ void set_status(snd_info *sp, const char *str, bool update); void snd_info_cleanup(snd_info *sp); void set_amp(snd_info *sp, mus_float_t val); void set_expand(snd_info *sp, mus_float_t val); void set_contrast(snd_info *sp, mus_float_t val); void set_speed(snd_info *sp, mus_float_t val); void set_revlen(snd_info *sp, mus_float_t val); void set_revscl(snd_info *sp, mus_float_t val); void set_filter_order(snd_info *sp, int val); void set_filter_text(snd_info *sp, const char *str); void display_filter_env(snd_info *sp); void toggle_expand_button(snd_info *sp, bool state); void toggle_contrast_button(snd_info *sp, bool state); void toggle_reverb_button(snd_info *sp, bool state); void toggle_filter_button(snd_info *sp, bool state); void toggle_direction_arrow(snd_info *sp, bool state); void set_filter_in_dB(snd_info *sp, bool val); void set_filter_in_hz(snd_info *sp, bool val); void filter_env_changed(snd_info *sp, env *e); void set_play_button(snd_info *sp, bool val); void play_button_pause(bool pausing); void syncb(snd_info *sp, int on); void show_lock(snd_info *sp); void hide_lock(snd_info *sp); void start_bomb(snd_info *sp); void stop_bomb(snd_info *sp); snd_info *add_sound_window(char *filename, read_only_t read_only, file_info *hdr); void set_sound_pane_file_label(snd_info *sp, const char *str); void show_controls(snd_info *sp); void hide_controls(snd_info *sp); bool showing_controls(snd_info *sp); void start_progress_report(chan_info *cp); void finish_progress_report(chan_info *cp); void progress_report(chan_info *cp, mus_float_t pct); void reflect_sound_selection(snd_info *sp); void update_sound_label(snd_info *sp); /* -------- snd-xfile.c -------- */ void cleanup_file_monitor(void); void *unmonitor_file(void *watcher); void monitor_sound(snd_info *sp); char *get_file_dialog_sound_attributes(file_data *fdat, int *srate, int *chans, mus_header_t *header_type, mus_sample_t *sample_type, mus_long_t *location, mus_long_t *samples, int min_chan); widget_t make_new_file_dialog(bool managed); int edit_header(snd_info *sp); void save_edit_header_dialog_state(FILE *fd); widget_t make_open_file_dialog(read_only_t read_only, bool managed); void set_open_file_play_button(bool val); widget_t make_selection_save_as_dialog(bool managed); widget_t make_region_save_as_dialog(bool managed); widget_t make_sound_save_as_dialog(bool managed); widget_t make_mix_file_dialog(bool managed); widget_t make_insert_file_dialog(bool managed); widget_t post_it(const char *subject, const char *str); void save_post_it_dialog_state(FILE *fd); void reflect_just_sounds(void); void save_file_dialog_state(FILE *fd); void reflect_selection_in_save_as_dialog(bool on); void reflect_save_as_src(bool val); void reflect_save_as_auto_comment(bool val); void reflect_save_as_sound_selection(const char *sound_name); /* -------- snd-xenv.c -------- */ axis_info *enved_make_axis(const char *name, graphics_context *ax, int ex0, int ey0, int width, int height, mus_float_t xmin, mus_float_t xmax, mus_float_t ymin, mus_float_t ymax, printing_t printing); void display_enved_env_with_selection(env *e, const char *name, int x0, int y0, int width, int height, bool dots, printing_t printing); void set_enved_redo_sensitive(bool val); void set_enved_revert_sensitive(bool val); void set_enved_undo_sensitive(bool val); void set_enved_save_sensitive(bool val); void set_enved_show_sensitive(bool val); void enved_reflect_selection(bool on); void make_scrolled_env_list(void); void enved_reflect_peak_env_completion(snd_info *sp); void new_active_channel_alert(void); void env_redisplay(void); void env_redisplay_with_print(void); void update_enved_background_waveform(chan_info *cp); int create_envelope_editor(void); void set_enved_clipping(bool val); void reflect_enved_style(void); void set_enved_base(mus_float_t val); void set_enved_target(enved_target_t val); void set_enved_with_wave(bool val); void set_enved_in_dB(bool val); bool enved_dialog_is_active(void); void set_enved_filter_order(int order); /* -------- snd-xmix.c -------- */ void reflect_mix_change(int mix_id); int make_mix_dialog(void); void reflect_mix_play_stop(void); int mix_dialog_mix(void); void mix_dialog_set_mix(int id); /* -------- snd-xprint.c -------- */ widget_t make_file_print_dialog(bool managed, bool direct_to_printer); /* -------- snd-xprefs.c -------- */ widget_t make_preferences_dialog(void); #endif snd-16.1/snd-gxbitmaps.c0000644000076400007640000033377312306421667013306 0ustar bilbil#include "snd.h" /* -------------------------------- PROGRAM ICON -------------------------------- * * apparently only a GdkPixbuf can be a program icon in Gtk? */ static const char *snd_icon_xpm[] = { "48 48 5 1", ". c white m white", "B c black m black", "a c white m white s basiccolor", "r c red m black s cursorcolor", "g c lightblue m black s listenercolor", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "aaBBBB.........................................a", "aaBBBB.........................................a", "aaBBBB.........................................a", "aaBBBB.........................................a", "aaBBBB.........................................a", "aaBBBB.........................................a", "aaBBBB............BBBB.........................a", "aaBBBB..........BB....BB.......................a", "aaBBBB........BB.......BB......................a", "aaBBBB......BB..........BB.....................a", "aaBBBB.....BB............BB....................a", "aaBBBB....BB.............BB....................a", "aaBBBB...BB..............BB....................a", "aaBBBB..BB................BB...................a", "aaBBBBBB..................BB...................a", "aaBBBB.....................BB..................a", "aaBBBB.....................BB.................Ba", "aaBBBB......................BB...............BBa", "aaBBBB.......................BB.............BB.a", "aaBBBB.........................BB..........BB..a", "aaBBBB..........................BB.......BB....a", "aaBBBB...........................BB....BB......a", "aaBBBB.............................BBB.........a", "aaBBBB.........................................a", "aaBBBB.........................................a", "aaBBBB.........................................a", "aaBBBB.........................................a", "aaBBBB.........................................a", "aaBBBB.........................................a", "aaBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBaa", "aaBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBaa", "aaaaaa.........................................a", "aaaaaa.........................................a", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "agggggggggggggggggggggggggggggggggggggggggggggga", "agggggggggggggggggggggggggggggggggggggggggggggga", "agggggggggggggggggggggggggggggggggggggggggggggga", "agggggggggggggggggggggggggggggggggggggggggggggga", "agggggggggggggggggggggggggggggggggggggggggggggga", "aggggggggggggggggggggggggggggggggggggggggggggggg", "aggggggggggggggggggggggggggggggggggggggggggggggg", "aggggggggggggggggggggggggggggggggggggggggggggggg", "agggggggggggggggggggggggggggggggggggggggggggggga", "agggggggggggggggggggggggggggggggggggggggggggggga", "agggggggggggggggggggggggggggggggggggggggggggggga", "agggggggggggggggggggggggggggggggggggggggggggggga", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}; const char **snd_icon_bits(void) {return(snd_icon_xpm);} #if USE_MOTIF #include static const char *mini_lock_xpm[] = { "16 14 5 1", "- c None s None", ". c gray50", "X c black", "o c white", "O c yellow", "------.XXX.-----", "-----X.ooo.X----", "----..oXXXo..---", "----XoX...XoX---", "----XoX.--XoX.--", "----XoX.--XoX.--", "---XXXXXXXXXXX--", "---XOOOOOOOOOX.-", "---XO.......OX.-", "---XOOOOOOOOOX.-", "---XO.......OX.-", "---XOOOOOOOOOX.-", "---XXXXXXXXXXX.-", "----...........-"}; const char **mini_lock_bits(void) {return(mini_lock_xpm);} static const char * close_icon_xpm[] = { "16 14 5 1", "- c None s None", ". c gray50", "X c black", "o c white", "O c yellow", "----------------", "----------------", "----------------", "--XX.------XX.--", "---XX.----XX.---", "----XX.--XX.----", "-----XX.XX.-----", "------XXX.------", "------XXX.------", "-----XX.XX.-----", "----XX.--XX.----", "---XX.----XX.---", "--XX.------XX.--", "----------------"}; const char **close_icon_bits(void) {return(close_icon_xpm);} static const char *blank_xpm[] = { "18 18 5 1", "- c None s None", ". c gray50", "X c black", "o c white", "O c yellow", "------------------", "------------------", "------------------", "------------------", "------------------", "------------------", "------------------", "------------------", "------------------", "------------------", "------------------", "------------------", "------------------", "------------------", "------------------", "------------------", "------------------", "------------------"}; const char **blank_bits(void) {return(blank_xpm);} /* bomb for out-of-date in-core data fuse shortens with sparks flying off; */ static const char * mini_bomb0_xpm[] = { "16 14 7 1","- c None s None",". c black","X c gray50","o c gray85","O c red","# c white","Y c yellow", "-------...------","------.---.-----","-----.-----.----","----...-----.---","---.....----.---","--.X#o...----.--","-X.#X....X---.--", "-..oX.....---O-O","-.......O.-O-OO-","-......Xo.--OOO-","-X.....X.X--O---","--.......-------","---X...X--------","----------------"}; static const char * mini_bomb1_xpm[] = { "16 14 7 1","- c None s None",". c black","X c gray50","o c gray85","O c red","# c white","Y c yellow", "-------...------","------.---.-----","-----.-----.----","----...-----.---","---.....----.---","--.X#o...----.--","-X.#X....X---Y--", "-..oX.....---YYY","-.......O.-YYOOY","-......Xo.--OOY-","-X.....X.X--Y---","--.......-------","---X...X--------","----------------"}; static const char * mini_bomb2_xpm[] = { "16 14 7 1","- c None s None",". c black","X c gray50","o c gray85","O c red","# c white","Y c yellow", "-------...------","------.---.-----","-----.-----.----","----...-----.---","---.....----.---","--.X#o...----Y--","-X.#X....X---YY-", "-..oX.....---OYO","-.......O.--O-OO","-......Xo.--Y-Y-","-X.....X.X------","--.......----Y--","---X...X--------","----------------"}; static const char * mini_bomb3_xpm[] = { "16 14 7 1","- c None s None",". c black","X c gray50","o c gray85","O c red","# c white","Y c yellow", "-------...------","------.---.-----","-----.-----.----","----...-----.---","---.....----.---","--.X#o...----Y--","-X.#X....X---OO-", "-..oX.....-YYYYO","-.......O.----O-","-......Xo.----O-","-X.....X.X----Y-","--.......-------","---X...X--------","------------YY--"}; static const char * mini_bomb4_xpm[] = { "16 14 7 1","- c None s None",". c black","X c gray50","o c gray85","O c red","# c white","Y c yellow", "-------...------","------.---.-----","-----.-----.--Y-","----...-----.---","---.....----O---","--.X#o...---OO--","-X.#X....X-YOYO-", "-..oX.....--OYY-","-.......O.------","-......Xo.-Y----","-X.....X.X------","--.......-------","---X...X--------","----------------"}; static const char * mini_bomb5_xpm[] = { "16 14 7 1","- c None s None",". c black","X c gray50","o c gray85","O c red","# c white","Y c yellow", "-------...------","------.---.-----","-----.-----.----","----...-----Y---","---.....----OO--","--.X#o...--OOO--","-X.#X....X---YO-", "-..oX.....---YY-","-.......O.-----Y","-......Xo.-----O","-X.....X.X------","--.......-------","---X...X--------","----------------"}; static const char * mini_bomb6_xpm[] = { "16 14 7 1","- c None s None",". c black","X c gray50","o c gray85","O c red","# c white","Y c yellow", "-------...------","------.---.-----","-----.-----OO-O-","----...-----YO--","---.....----O---","--.X#o...-YY-OO-","-X.#X....X--Y---", "-..oX.....------","-.......O.------","-......Xo.------","-X.....X.X------","--.......-----OO","---X...X------Y-","----------------"}; static const char * mini_bomb7_xpm[] = { "16 14 7 1","- c None s None",". c black","X c gray50","o c gray85","O c red","# c white","Y c yellow", "-------...----OO","------.---O-----","-----.-----OOYY-","----...-----YOO-","---.....-YY-O---","--.X#o...-------","-X.#X....X--YO--", "-..oX.....---Y--","-.......O.------","-......Xo.------","-X.....X.X------","--.......-------","---X...X--------","--------------YY"}; static const char * mini_bomb8_xpm[] = { "16 14 7 1","- c None s None",". c black","X c gray50","o c gray85","O c red","# c white","Y c yellow", "-------..Y------","------.--OO-----","-----.----OOO-Y-","----...---OO--O-","---.....-YY----O","--.X#o...-------","-X.#X....X------", "-..oX.....--YO--","-.......O.---O--","-......Xo.------","-X.....X.X------","--.......-------","---X...X--------","----------------"}; static const char * mini_bomb9_xpm[] = { "16 14 7 1","- c None s None",". c black","X c gray50","o c gray85","O c red","# c white","Y c yellow", "-------YOY--O---","------.---YO----","-----.----OYY---","----...---------","---.....----YY--","--.X#o...-------","-X.#X....X------", "-..oX.....------","-.......O.--YO--","-......Xo.---Y--","-X.....X.X------","--.......-------","---X...X--------","----------------"}; static const char * mini_bomb10_xpm[] = { "16 14 7 1","- c None s None",". c black","X c gray50","o c gray85","O c red","# c white","Y c yellow", "-----OYYOYOO----","-----YOO--YO----","-----.-----YY---","----...---------","---.....--------","--.X#o...----OO-","-X.#X....X---Y--", "-..oX.....------","-.......O.------","-......Xo.------","-X.....X.X------","--.......-------","---X...X--------","----------------"}; static const char * mini_bomb11_xpm[] = { "16 14 7 1","- c None s None",". c black","X c gray50","o c gray85","O c red","# c white","Y c yellow", "-----OOYOO--O---","----OOY----O----","---OOOO---------","----...---------","---.....--------","--.X#o...-------","-X.#X....X------", "-..oX.....------","-.......O.------","-......Xo.------","-X.....X.X------","--.......---OO--","---X...X--------","----------------"}; static const char * mini_bomb12_xpm[] = { "16 14 7 1","- c None s None",". c black","X c gray50","o c gray85","O c red","# c white","Y c yellow", "-----OO---------","--YYOOYYY-------","YYOOOOYYYY------","--OOOOO---------","---.....--------","--.X#o...-------","-X.#X....X------", "-..oX.....------","-.......O.------","-......Xo.------","-X.....X.X------","--.......-------","---X...X--------","------------YY--"}; static const char * mini_bomb13_xpm[] = { "16 14 7 1","- c None s None",". c black","X c gray50","o c gray85","O c red","# c white","Y c yellow", "----------------","----OOY---------","--YYYYY-Y-------","--Y-OOO---------","---.YOY.--------","--.X#o...-------","-X.#X....X------", "-..oX.....------","-.......O.------","-......Xo.------","-X.....X.X------","--.......-------","---X...X--------","----------------"}; static const char * mini_bomb14_xpm[] = { "16 14 7 1","- c None s None",". c black","X c gray50","o c gray85","O c red","# c white","Y c yellow", "----------------","----------------","----------------","----------------","---.....--------","--.X#o...-------","-X.#X....X------", "-..oX.....------","-.......O.------","-......Xo.------","-X.....X.X------","--.......-------","---X...X--------","----------------"}; const char **mini_bomb_bits(int n) { switch (n) { case 0: return(mini_bomb0_xpm); break; case 1: return(mini_bomb1_xpm); break; case 2: return(mini_bomb2_xpm); break; case 3: return(mini_bomb3_xpm); break; case 4: return(mini_bomb4_xpm); break; case 5: return(mini_bomb5_xpm); break; case 6: return(mini_bomb6_xpm); break; case 7: return(mini_bomb7_xpm); break; case 8: return(mini_bomb8_xpm); break; case 9: return(mini_bomb9_xpm); break; case 10: return(mini_bomb10_xpm); break; case 11: return(mini_bomb11_xpm); break; case 12: return(mini_bomb12_xpm); break; case 13: return(mini_bomb13_xpm); break; case 14: return(mini_bomb14_xpm); break; default: return(NULL); break; } } static const char * mini_glass0_xpm[] = {"16 14 6 1","- c None s None",". c ivory4","c c gray50","X c black","o c white","O c tan", "-XXXXXXXXXXXXXX-","-c.OOOOOOOOOO.c-","-.cOOOOOOOOOOc.-","--cOOOOOOOOOOc--","----cOOOOOOc----","-----.cOOc.-----","-------cc-------", "-----.cooc.-----","----cooooooc----","---cooooooooc---","--cooooooooooc--","-.cooooooooooc.-","-cooooooooooooc-","-XXXXXXXXXXXXXX-"}; static const char * mini_glass1_xpm[] = {"16 14 6 1","- c None s None",". c ivory4","c c gray50","X c black","o c white","O c tan", "-XXXXXXXXXXXXXX-","-c.OOOOoOOOOO.c-","-.cOOOOOOOOOOc.-","--cOOOOOOOOOOc--","----cOOOOOOc----","-----.coOc.-----","-------cc-------", "-----.cooc.-----","----cooooooc----","---coooOooooc---","--cooooooooooc--","-.cooooooooooc.-","-coooooOooooooc-","-XXXXXXXXXXXXXX-"}; static const char * mini_glass2_xpm[] = {"16 14 6 1","- c None s None",". c ivory4","c c gray50","X c black","o c white","O c tan", "-XXXXXXXXXXXXXX-","-c.OOOOoooOOO.c-","-.cOOOOOOOOOOc.-","--cOOOOOOOOOOc--","----cOOOOOOc----","-----.cOoc.-----","-------cc-------", "-----.cooc.-----","----cooooooc----","---cooooooooc---","--cooooooooooc--","-.cooooOoooooc.-","-cooooOOOoooooc-","-XXXXXXXXXXXXXX-"}; static const char * mini_glass3_xpm[] = {"16 14 6 1","- c None s None",". c ivory4","c c gray50","X c black","o c white","O c tan", "-XXXXXXXXXXXXXX-","-c.OOOoooOOOO.c-","-.cOOOOooOOOOc.-","--cOOOOOOOOOOc--","----cOOOOOOc----","-----.coOc.-----","-------cc-------", "-----.cOoc.-----","----cooooooc----","---cooooooooc---","--cooooooooooc--","-.coooOooooooc.-","-coooOOOOoooooc-","-XXXXXXXXXXXXXX-"}; static const char * mini_glass4_xpm[] = {"16 14 6 1","- c None s None",". c ivory4","c c gray50","X c black","o c white","O c tan", "-XXXXXXXXXXXXXX-","-c.OOOooooOOO.c-","-.cOOOOoooOOOc.-","--cOOOOOoOOOOc--","----cOOoOOOc----","-----.cOOc.-----","-------cc-------", "-----.coOc.-----","----cooooooc----","---cooooooooc---","--cooooooooooc--","-.coooOOOooooc.-","-coooOOOOoooooc-","-XXXXXXXXXXXXXX-"}; static const char * mini_glass5_xpm[] = {"16 14 6 1","- c None s None",". c ivory4","c c gray50","X c black","o c white","O c tan", "-XXXXXXXXXXXXXX-","-c.OOOoooooOO.c-","-.cOOOOooooOOc.-","--cOOOOOoOOOOc--","----cOOOOOOc----","-----.cOOc.-----","-------cc-------", "-----.cooc.-----","----cooooooc----","---cooooooooc---","--coooOooooooc--","-.coooOOOOoooc.-","-coooOOOOOooooc-","-XXXXXXXXXXXXXX-"}; static const char * mini_glass6_xpm[] = {"16 14 6 1","- c None s None",". c ivory4","c c gray50","X c black","o c white","O c tan", "-XXXXXXXXXXXXXX-","-c.OOOoooooOO.c-","-.cOOOOooooOOc.-","--cOOOOoooOOOc--","----cOOOOoOc----","-----.cOOc.-----","-------cc-------", "-----.cOoc.-----","----coooOooc----","---cooooooooc---","--cooooooooooc--","-.coooOOOOoooc.-","-coooOOOOOOoooc-","-XXXXXXXXXXXXXX-"}; static const char * mini_glass7_xpm[] = {"16 14 6 1","- c None s None",". c ivory4","c c gray50","X c black","o c white","O c tan", "-XXXXXXXXXXXXXX-","-c.OOooooooOO.c-","-.cOOOoooooOOc.-","--cOOOOoOoOOOc--","----cOOoOOOc----","-----.cOOc.-----","-------cc-------", "-----.cooc.-----","----cooooooc----","---cooooOoooc---","--coooOOoooooc--","-.cooOOOOOoooc.-","-cooOOOOOOOoooc-","-XXXXXXXXXXXXXX-"}; static const char * mini_glass8_xpm[] = {"16 14 6 1","- c None s None",". c ivory4","c c gray50","X c black","o c white","O c tan", "-XXXXXXXXXXXXXX-","-c.OoooooooOO.c-","-.cOOooooooOOc.-","--cOOOooooOOOc--","----cOOOOOOc----","-----.cOOc.-----","-------cc-------", "-----.cooc.-----","----cooooooc----","---cooooooooc---","--coooOOOooooc--","-.cooOOOOOoooc.-","-cooOOOOOOOOOoc-","-XXXXXXXXXXXXXX-"}; static const char * mini_glass9_xpm[] = {"16 14 6 1","- c None s None",". c ivory4","c c gray50","X c black","o c white","O c tan", "-XXXXXXXXXXXXXX-","-c.ooooooooOO.c-","-.cOoooooooOOc.-","--cOOoooooOOOc--","----cOOoOOOc----","-----.cOOc.-----","-------cc-------", "-----.cooc.-----","----cooOoooc----","---cooooooooc---","--cooOOOOOOOoc--","-.coOOOOOOOOooc.-","-coOOOOOOOOOOOoc-","-XXXXXXXXXXXXXX-"}; static const char * mini_glass10_xpm[] = {"16 14 6 1","- c None s None",". c ivory4","c c gray50","X c black","o c white","O c tan", "-XXXXXXXXXXXXXX-","-c.oooooooooo.c-","-.cOoooooooooc.-","--cOOooooooOOc--","----cOOooOOc----","-----.coOc.-----","-------cc-------", "-----.cooc.-----","----cooooooc----","---cooOOOOooc---","--cooOOOOOOooc--","-.coOOOOOOOOoc.-","-cOOOOOOOOOOOoc-","-XXXXXXXXXXXXXX-"}; static const char * mini_glass11_xpm[] = {"16 14 6 1","- c None s None",". c ivory4","c c gray50","X c black","o c white","O c tan", "-XXXXXXXXXXXXXX-","-c.oooooooooo.c-","-.cooooooooooc.-","--cOOooooooooc--","----cOOooOOc----","-----.coOc.-----","-------cc-------", "-----.cooc.-----","----cooOoooc----","---cooOOOOooc---","--coOOOOOOOooc--","-.cOOOOOOOOOoc.-","-cOOOOOOOOOOOoc-","-XXXXXXXXXXXXXX-"}; static const char * mini_glass12_xpm[] = {"16 14 6 1","- c None s None",". c ivory4","c c gray50","X c black","o c white","O c tan", "-XXXXXXXXXXXXXX-","-c.oooooooooo.c-","-.cooooooooooc.-","--cooooooooooc--","----cOoooOOc----","-----.cOOc.-----","-------cc-------", "-----.cooc.-----","----cooOOooc----","---coOOOOOooc---","--cOOOOOOOOOoc--","-.cOOOOOOOOOOc.-","-cOOOOOOOOOOOOc-","-XXXXXXXXXXXXXX-"}; static const char * mini_glass13_xpm[] = {"16 14 6 1","- c None s None",". c ivory4","c c gray50","X c black","o c white","O c tan", "-XXXXXXXXXXXXXX-","-c.oooooooooo.c-","-.cooooooooooc.-","--cooooooooooc--","----cooooooc----","-----.cOOc.-----","-------cc-------", "-----.cooc.-----","----cooOOooc----","---cOOOOOOOOc---","--cOOOOOOOOOOc--","-.cOOOOOOOOOOc.-","-cOOOOOOOOOOOOc-","-XXXXXXXXXXXXXX-"}; static const char * mini_glass14_xpm[] = {"16 14 6 1","- c None s None",". c ivory4","c c gray50","X c black","o c white","O c tan", "-XXXXXXXXXXXXXX-","-c.oooooooooo.c-","-.cooooooooooc.-","--cooooooooooc--","----cooooooc----","-----.cooc.-----","-------cc-------", "-----.cOOc.-----","----cOOOOOOc----","---cOOOOOOOOc---","--cOOOOOOOOOOc--","-.cOOOOOOOOOOc.-","-cOOOOOOOOOOOOc-","-XXXXXXXXXXXXXX-"}; const char **mini_glass_bits(int n) { switch (n) { case 0: return(mini_glass0_xpm); break; case 1: return(mini_glass1_xpm); break; case 2: return(mini_glass2_xpm); break; case 3: return(mini_glass3_xpm); break; case 4: return(mini_glass4_xpm); break; case 5: return(mini_glass5_xpm); break; case 6: return(mini_glass6_xpm); break; case 7: return(mini_glass7_xpm); break; case 8: return(mini_glass8_xpm); break; case 9: return(mini_glass9_xpm); break; case 10: return(mini_glass10_xpm); break; case 11: return(mini_glass11_xpm); break; case 12: return(mini_glass12_xpm); break; case 13: return(mini_glass13_xpm); break; case 14: return(mini_glass14_xpm); break; default: return(NULL); break; } } /* from HView */ /* there are at least 3 stop signs in Snd. This one for the Motif name-box, * the big one for the toolbar (below), and the gtk built-in stop sign * for the gtk name-box. */ static const char *stop_sign_xpm[] = { "17 17 3 1", "- c None s None", ". c red", "X c white", "----XXXXXXXXX----", "---X.........X---", "--X...........X--", "-X.............X-", "X...............X", "X...............X", "X.XX.XXX.XX..XX.X", "X.X...X.X..X.X.XX", "X..X..X.X..X.XX.X", "X.XX..X..XX..X..X", "X...............X", "X...............X", "X...............X", "-X.............X-", "--X...........X--", "---X.........X---", "----XXXXXXXXX----"}; const char **stop_sign_bits(void) {return(stop_sign_xpm);} /* these are taken mainly from emacs */ static const char *zoom_in_xpm[] = { "24 24 132 2", " c None", ". c #343434", "+ c #2D2D2D", "@ c #292929", "# c #262626", "$ c #2E2E2E", "% c #303030", "& c #737373", "* c #A1A1A1", "= c #B4B4B4", "- c #B2B2B2", "; c #9D9D9D", "> c #676767", ", c #202020", "' c #1C1C1C", ") c #272727", "! c #616161", "~ c #CACACA", "{ c #CFCFCF", "] c #D0D0D0", "^ c #CECECE", "/ c #C9C9C9", "( c #C1C1C1", "_ c #A7A7A7", ": c #4C4C4C", "< c #131313", "[ c #222222", "} c #757575", "| c #D3D3D3", "1 c #DBDBDB", "2 c #E7E7E7", "3 c #EFEFEF", "4 c #F3F3F3", "5 c #F1F1F1", "6 c #E5E5E5", "7 c #D2D2D2", "8 c #BCBCBC", "9 c #5E5E5E", "0 c #101010", "a c #212121", "b c #5B5B5B", "c c #CCCCCC", "d c #D7D7D7", "e c #F5F5F5", "f c #FAFAFA", "g c #FBFBFB", "h c #F8F8F8", "i c #F0F0F0", "j c #E1E1E1", "k c #C2C2C2", "l c #434343", "m c #0F0F0F", "n c #1F1F1F", "o c #B9B9B9", "p c #D6D6D6", "q c #F9F9F9", "r c #FDFDFD", "s c #454545", "t c #F2F2F2", "u c #ECECEC", "v c #E4E4E4", "w c #ABABAB", "x c #0E0E0E", "y c #1B1B1B", "z c #6D6D6D", "A c #FEFEFE", "B c #FCFCFC", "C c #EEEEEE", "D c #E6E6E6", "E c #575757", "F c #090909", "G c #141414", "H c #A8A8A8", "I c #D8D8D8", "J c #F6F6F6", "K c #F4F4F4", "L c #DCDCDC", "M c #9B9B9B", "N c #060606", "O c #111111", "P c #C5C5C5", "Q c #DFDFDF", "R c #444444", "S c #424242", "T c #EDEDED", "U c #BFBFBF", "V c #C6C6C6", "W c #E3E3E3", "X c #414141", "Y c #EAEAEA", "Z c #E0E0E0", "` c #BABABA", " . c #050505", ".. c #0B0B0B", "+. c #A5A5A5", "@. c #D1D1D1", "#. c #939393", "$. c #020202", "%. c #0A0A0A", "&. c #5F5F5F", "*. c #D9D9D9", "=. c #EBEBEB", "-. c #E9E9E9", ";. c #D4D4D4", ">. c #000000", ",. c #E2E2E2", "'. c #3F3F3F", "). c #DADADA", "!. c #CBCBCB", "~. c #3B3B3B", "{. c #D5D5D5", "]. c #C8C8C8", "^. c #BDBDBD", "/. c #515151", "(. c #C7C7C7", "_. c #CDCDCD", ":. c #B8B8B8", "<. c #030303", "[. c #313131", "}. c #999999", "|. c #BBBBBB", "1. c #B6B6B6", "2. c #909090", "3. c #2B2B2B", "4. c #010101", "5. c #7A7A7A", "6. c #9A9A9A", "7. c #777777", "8. c #3C3C3C", "9. c #686868", "0. c #797979", "a. c #3A3A3A", " ", " . + @ # # # ", " $ % & * = - ; > , ' ", " ) ! = ~ { ] ^ / ( _ : < ", " [ } ~ | 1 2 3 4 5 6 7 8 9 0 ", " a b c d 6 e f g f h e i j k l m ", " n o p 2 q g r s s g h t u v w x ", " y z 7 j e f r A s s B q e C D 1 E F ", " G H I C J q B A s s g h K C D L M N ", " O P Q 3 e R R s s s R l S T 6 1 U N ", " x V W u t l R R R R l S X Y Z d ` . ", " ..+.j 2 T 5 K J l l 4 3 u v 1 @.#.$. ", " %.&.*.j D =.C 3 X X T -.v 1 ;.~ : >. ", " %.= I L ,.6 D '.'.W Q ).;.!.* $. ", " N ~.c 7 ;.).1 ).1 I {.] ].^.$ >. ", " ./.k (.!.c _.!.!.].k :.s >. ", " <.[.}.|.^.8 8 8 1.2.3.>.>.>. ", " 4.<.X 5.6.6.7.8.>.>. >.>.>.>. ", " >.>.>.>.>.>. , , >.>. ", " >.9.. >.>. ", " >.0.a.>.>. ", " >.9.n >. ", " >.>. ", " "}; static const char *zoom_out_xpm[] = { "24 24 131 2", " c None", ". c #343434", "+ c #2D2D2D", "@ c #292929", "# c #262626", "$ c #2E2E2E", "% c #303030", "& c #737373", "* c #A1A1A1", "= c #B4B4B4", "- c #B2B2B2", "; c #9D9D9D", "> c #676767", ", c #202020", "' c #1C1C1C", ") c #272727", "! c #616161", "~ c #CACACA", "{ c #CFCFCF", "] c #D0D0D0", "^ c #CECECE", "/ c #C9C9C9", "( c #C1C1C1", "_ c #A7A7A7", ": c #4C4C4C", "< c #131313", "[ c #222222", "} c #757575", "| c #D3D3D3", "1 c #DBDBDB", "2 c #E7E7E7", "3 c #EFEFEF", "4 c #F3F3F3", "5 c #F1F1F1", "6 c #E5E5E5", "7 c #D2D2D2", "8 c #BCBCBC", "9 c #5E5E5E", "0 c #101010", "a c #212121", "b c #5B5B5B", "c c #CCCCCC", "d c #D7D7D7", "e c #F5F5F5", "f c #FAFAFA", "g c #FBFBFB", "h c #F8F8F8", "i c #F0F0F0", "j c #E1E1E1", "k c #C2C2C2", "l c #434343", "m c #0F0F0F", "n c #1F1F1F", "o c #B9B9B9", "p c #D6D6D6", "q c #F9F9F9", "r c #FDFDFD", "s c #FCFCFC", "t c #F2F2F2", "u c #ECECEC", "v c #E4E4E4", "w c #ABABAB", "x c #0E0E0E", "y c #1B1B1B", "z c #6D6D6D", "A c #FEFEFE", "B c #EEEEEE", "C c #E6E6E6", "D c #575757", "E c #090909", "F c #141414", "G c #A8A8A8", "H c #D8D8D8", "I c #F6F6F6", "J c #F4F4F4", "K c #DCDCDC", "L c #9B9B9B", "M c #060606", "N c #111111", "O c #C5C5C5", "P c #DFDFDF", "Q c #444444", "R c #454545", "S c #424242", "T c #EDEDED", "U c #BFBFBF", "V c #C6C6C6", "W c #E3E3E3", "X c #414141", "Y c #EAEAEA", "Z c #E0E0E0", "` c #BABABA", " . c #050505", ".. c #0B0B0B", "+. c #A5A5A5", "@. c #D1D1D1", "#. c #939393", "$. c #020202", "%. c #0A0A0A", "&. c #5F5F5F", "*. c #D9D9D9", "=. c #EBEBEB", "-. c #E9E9E9", ";. c #D4D4D4", ">. c #000000", ",. c #E2E2E2", "'. c #DADADA", "). c #CBCBCB", "!. c #3B3B3B", "~. c #D5D5D5", "{. c #C8C8C8", "]. c #BDBDBD", "^. c #515151", "/. c #C7C7C7", "(. c #CDCDCD", "_. c #B8B8B8", ":. c #030303", "<. c #313131", "[. c #999999", "}. c #BBBBBB", "|. c #B6B6B6", "1. c #909090", "2. c #2B2B2B", "3. c #010101", "4. c #7A7A7A", "5. c #9A9A9A", "6. c #777777", "7. c #3C3C3C", "8. c #686868", "9. c #797979", "0. c #3A3A3A", " ", " . + @ # # # ", " $ % & * = - ; > , ' ", " ) ! = ~ { ] ^ / ( _ : < ", " [ } ~ | 1 2 3 4 5 6 7 8 9 0 ", " a b c d 6 e f g f h e i j k l m ", " n o p 2 q g r r s g h t u v w x ", " y z 7 j e f r A A r s q e B C 1 D E ", " F G H B I q s A A r g h J B C K L M ", " N O P 3 e Q Q R R R Q l S T 6 1 U M ", " x V W u t l Q Q Q Q l S X Y Z d ` . ", " ..+.j 2 T 5 J I I e 4 3 u v 1 @.#.$. ", " %.&.*.j C =.B 3 3 B T -.v 1 ;.~ : >. ", " %.= H K ,.6 C C 2 W P '.;.).* $. ", " M !.c 7 ;.'.1 '.1 H ~.] {.].$ >. ", " .^.k /.).c (.).).{.k _.R >. ", " :.<.[.}.].8 8 8 |.1.2.>.>.>. ", " 3.:.X 4.5.5.6.7.>.>. >.>.>.>. ", " >.>.>.>.>.>. , , >.>. ", " >.8.. >.>. ", " >.9.0.>.>. ", " >.8.n >. ", " >.>. ", " "}; static const char *cut_xpm[] = { "24 24 40 1", " c None", ". c #000000", "+ c #C9C7C2", "@ c #E6E4E0", "# c #EFEEED", "$ c #494946", "% c #73726E", "& c #F0EEED", "* c #7F7D75", "= c #F2F1EF", "- c #D2CFC8", "; c #E7E7E4", "> c #BAB5AB", ", c #565653", "' c #EDECE9", ") c #A4A097", "! c #817F7E", "~ c #4E4C48", "{ c #F6F5F4", "] c #474541", "^ c #EFEEEC", "/ c #8C8B8A", "( c #F3F2F0", "_ c #77746D", ": c #323232", "< c #EBEBEA", "[ c #605D58", "} c #F5F4F3", "| c #CECCC7", "1 c #363634", "2 c #6F6E6D", "3 c #BEBDBB", "4 c #EAE7E4", "5 c #B8B5B1", "6 c #474747", "7 c #DAD8D4", "8 c #9B9996", "9 c #161615", "0 c #6D6B6A", "a c #3A3837", " ", " ", " . . ", " . . ", " .+. .@. ", " .#$ %@. ", " .&*. .=-. ", " .;>, %'). ", " !#*. .=-~ ", " .{>] ~^>. ", " /(_.:<-[ ", " .}|123>. ", " .456>. ", " .78.. ", " .90a. ", " ............. ", " . ... ... ... ", " .. .. .. .. ", " . . . . ", " .. .. .. .. ", " .... .. . ", " .... .... ", " ", " "}; static const char *paste_xpm[] = { "24 24 89 1", " c None", ". c #000000", "+ c #B9B9B9", "@ c #FEFEFE", "# c #F9F9F9", "$ c #757575", "% c #F5F5E8", "& c #565651", "* c #FFFFFF", "= c #A0A0A0", "- c #939393", "; c #7C7C7C", "> c #C5C5BB", ", c #CFC6A0", "' c #D7CEAA", ") c #ADA689", "! c #4B483C", "~ c #6D6D6D", "{ c #6C6C6C", "] c #A9A9A9", "^ c #3D3A30", "/ c #979178", "( c #C1B898", "_ c #8A793D", ": c #C3BB9A", "< c #AFA78A", "[ c #444236", "} c #FAFAFA", "| c #EFEFEF", "1 c #C7C7C7", "2 c #D8D8D8", "3 c #D2D2D2", "4 c #7B7B7B", "5 c #302E26", "6 c #89846C", "7 c #C4BC9A", "8 c #847235", "9 c #C5C5C5", "0 c #A7A7A7", "a c #ADADAD", "b c #9A9A9A", "c c #9B9B9B", "d c #868686", "e c #424242", "f c #847033", "g c #C9C09E", "h c #464337", "i c #35332A", "j c #2D2B23", "k c #C6BE9D", "l c #826F33", "m c #7F7964", "n c #4C493C", "o c #171612", "p c #13120F", "q c #3E3B31", "r c #282210", "s c #474438", "t c #B3B3B3", "u c #D6D6D6", "v c #B7AE90", "w c #B1AA8C", "x c #37352B", "y c #151410", "z c #8F8F8F", "A c #989898", "B c #C6C6C6", "C c #B9B293", "D c #11100D", "E c #434035", "F c #636363", "G c #767676", "H c #AAA48B", "I c #A5A086", "J c #A19A7F", "K c #312F26", "L c #AFA88C", "M c #050403", "N c #12110E", "O c #A9A489", "P c #A39E85", "Q c #EBE7D0", "R c #D2C9A5", "S c #A29053", "T c #8E7C3D", "U c #88793B", "V c #806C2F", "W c #78652B", "X c #251F0C", " .... ", " ......+@#$...... ", ".%%%%%&*=-;&>%%%,. ", ".%''')!*~{]^/(''_. ", ".%::<[}|123456<78. ", ".%''!900abcde!)'f. ", ".%g:6hijjjjj56 c #CCCCCC", ", c #AFAFAF", "' c #D3D1CB", ") c #C1C0BF", "! c #F0EFED", "~ c #797772", "{ c #DCDCDC", "] c #A5A19C", "^ c #EAE9E5", "/ c #F3F1F0", "( c #EDEDED", "_ c #A19D96", ": c #C1BDB4", "< c #DBD8D3", "[ c #D9D6D1", "} c #89857E", "| c #FCFCFC", "1 c #EAE9E6", "2 c #F5F4F3", "3 c #C6C2BA", "4 c #F0EFEE", "5 c #F4F4F3", "6 c #CBC7C0", "7 c #ECECEB", "8 c #676560", "9 c #54524D", "0 c #777676", "a c #797978", "b c #85827E", "c c #79756F", "d c #7590AE", "e c #A4BAD0", "f c #90A6BE", "g c #9F9F9E", "h c #BEBDBC", "i c #B8B4AD", "j c #87837C", "k c #D3DFEA", "l c #A2AEBC", "m c #9DB6CE", "n c #637B95", "o c #E2E2E2", "p c #EEEEED", "q c #849CB6", "r c #D7E2ED", "s c #8D98A5", "t c #9DB8D2", "u c #607791", "v c #EDEDEC", "w c #99ADC3", "x c #DFE7F0", "y c #8193A9", "z c #586D84", "A c #5B7189", "B c #F1F1F1", "C c #EEEDEB", "D c #A7A6A5", "E c #726F6A", "F c #A1B4C8", "G c #EEF3F6", "H c #60768F", "I c #DEDDDC", "J c #787776", "K c #4E4E4D", "L c #91A6BE", "M c #F0F4F7", "N c #97A5B6", "O c #BFBEBD", "P c #AAAAA9", "Q c #ACACAB", "R c #B0C6DB", "S c #EDF2F6", "T c #818A95", "U c #6C85A1", "V c #C0D1E2", " .. ", " .+@#. ", " .$%+. .. ", " .&$. .*=. ", " .. -;$. .*>,. ", " .' ..)!+~. .{,. ", " .]%%^/+++. .(.. ", " ._:%$<[+}. .|. ", " .....123}..>. ", " .456.,. ", " .7.,.. ", " .,.89. ", " ....,.0abc. ", " .def.. .ghij. ", " .dklmn. .op6}. ", " .qrsntu. .v/$}. ", " .wxyztdA. .BCDE..", " .FGyHtdA. .IJK,.", " .LMNHtdA. .OPQ.", " .RSTtdA.. ... ", " .UtVLA.. ", " .UUn.. ", " ... ", " "}; static const char * close_xpm[] = { "24 24 5 1", " c None s None", ". c gray50", "X c black", "o c white", "O c yellow", " ", " ", " ", " ", " ", " ", " ", " XX. XX. ", " XX. XX. ", " XX. XX. ", " XX.XX. ", " XXX. ", " XXX. ", " XX.XX. ", " XX. XX. ", " XX. XX. ", " XX. XX. ", " ", " ", " ", " ", " ", " ", " "}; static const char *redo_xpm[] = { "24 24 42 1", " c None", ". c #000000", "+ c #939A8D", "@ c #BAD09D", "# c #92998C", "$ c #818F71", "% c #ADBDA0", "& c #C2D5AA", "* c #D1DFBE", "= c #BED2A3", "- c #99A28F", "; c #A8BCA6", "> c #D5E1C6", ", c #CDDCBC", "' c #D2E0BF", ") c #C5D7AE", "! c #919889", "~ c #8C9A7F", "{ c #D4E0C5", "] c #D3E0C1", "^ c #BFD3A6", "/ c #9BAA87", "( c #B5C3A9", "_ c #92AD62", ": c #7C9B40", "< c #59702D", "[ c #7F8E6B", "} c #C8D9B2", "| c #85A24D", "1 c #53692A", "2 c #A4B690", "3 c #9BB572", "4 c #6D8839", "5 c #95A77E", "6 c #8BA859", "7 c #657255", "8 c #98AF74", "9 c #AFC394", "0 c #6D7A5B", "a c #9CAF84", "b c #748261", "c c #879772", " ", " ", " ", " . ", " .. ", " .+. ", " ....@#. ", " .$%&*=@-. ", " .;>,')@@@!. ", " .~{]*^@@@@@/. ", " .(>_::::::<. ", " .[}|::::::1. ", " .23:<...:1. ", " .@:4. .<. ", " .@:.. .. ", " .56. . ", " .78. ", " .9. ", " .0a. ", " .bc. ", " ... ", " ", " ", " "}; static const char *undo_xpm[] = { "24 24 31 1", " c None", ". c #000000", "+ c #EFE5BA", "@ c #EFE7C1", "# c #EED680", "$ c #EFE4B6", "% c #D5B75D", "& c #B29544", "* c #D1B051", "= c #C0AF73", "- c #C0A048", "; c #986B07", "> c #D1940C", ", c #E0B74C", "' c #D9C374", ") c #8F6406", "! c #D59D1C", "~ c #B1933F", "{ c #DFB74A", "] c #CCB76D", "^ c #B8820A", "/ c #D9A72E", "( c #D7A62C", "_ c #C7B26A", ": c #D4B150", "< c #A39256", "[ c #E2CB79", "} c #C9B46B", "| c #8D7E4A", "1 c #AE9C5C", "2 c #96864F", " ", " ", " ", " . ", " .. ", " .+. ", " .@#.... ", " .$####%&. ", " .+#######*. ", " .=#########-. ", " .;>>>>>>,#'.. ", " .)>>>>>>!#~. ", " .)>...;>{]. ", " .;. ..^/#. ", " .. ..>#. ", " . .(_. ", " .:<. ", " .[. ", " .}|. ", " .12. ", " .. ", " ", " ", " "}; static const char *save_xpm[] = { "24 24 220 2", " c None", ". c #000000", "+ c #C3D7F4", "@ c #A9CDE5", "# c #75757A", "$ c #EFC5BB", "% c #F1C8BE", "& c #F0C6BC", "* c #EEBCB2", "= c #EEBEB5", "- c #EEC1B8", "; c #EDBFB6", "> c #E9B7AD", ", c #E9B8AF", "' c #E9B9B1", ") c #E5BFBA", "! c #737277", "~ c #B3CDE3", "{ c #A1BED6", "] c #BBD6E8", "^ c #8AAAC5", "/ c #605F68", "( c #E08D7E", "_ c #E0826E", ": c #E0806E", "< c #DC7A68", "[ c #DC8171", "} c #DA7868", "| c #D48173", "1 c #D47D6E", "2 c #CE7265", "3 c #CF7264", "4 c #CE7567", "5 c #C4675B", "6 c #C36558", "7 c #626169", "8 c #87A3B7", "9 c #567187", "0 c #BAD5E9", "a c #88A7C3", "b c #686670", "c c #C8817B", "d c #CB7C74", "e c #CB7A73", "f c #CB7B73", "g c #CC7C72", "h c #CB7D73", "i c #BF6B64", "j c #CC7A70", "k c #C16A62", "l c #CC7C73", "m c #C2655B", "n c #C36459", "o c #BA6C6A", "p c #819EB6", "q c #547086", "r c #B6D3E7", "s c #87ABC1", "t c #737373", "u c #FFFFFF", "v c #83A0B8", "w c #526C80", "x c #B9D3E7", "y c #85A4BF", "z c #4F697C", "A c #B9D3E6", "B c #84A3BF", "C c #CECECE", "D c #CDCDCD", "E c #BFBFBF", "F c #88A4BB", "G c #486276", "H c #B7D2E7", "I c #82A0BB", "J c #636363", "K c #465E70", "L c #B5CAE5", "M c #7FA2B9", "N c #87A3BA", "O c #455C6D", "P c #AECCE5", "Q c #7DA0B6", "R c #C5C5C5", "S c #546069", "T c #B0D1E4", "U c #83A1B6", "V c #735B5B", "W c #515C64", "X c #AACEE3", "Y c #7B9BB2", "Z c #7A8E9A", "` c #7A7A7A", " . c #6B6F72", ".. c #6F6F6F", "+. c #696969", "@. c #6F777E", "#. c #86A2B9", "$. c #3A515D", "%. c #A9C9E2", "&. c #7494AF", "*. c #829FB7", "=. c #7F9DB6", "-. c #7E9CB5", ";. c #7998B2", ">. c #85A1B8", ",. c #8CA7BD", "'. c #8AA5BB", "). c #364A59", "!. c #ABC4E2", "~. c #7294AD", "{. c #6F90AC", "]. c #7192AE", "^. c #414A4E", "/. c #424A51", "(. c #525B63", "_. c #626F79", ":. c #5F6C76", "<. c #5C6971", "[. c #5A666F", "}. c #58636B", "|. c #57636A", "1. c #3B5360", "2. c #39424B", "3. c #7897B3", "4. c #A4B9CB", "5. c #364853", "6. c #AAC9E2", "7. c #7091AA", "8. c #6F8FA7", "9. c #4A5359", "0. c #97938C", "a. c #DFDDDA", "b. c #E3E1DE", "c. c #EBEAE8", "d. c #EAE9E7", "e. c #CFCEC9", "f. c #C9C6C0", "g. c #9B968E", "h. c #566168", "i. c #4B657A", "j. c #54738C", "k. c #AAC6DD", "l. c #34464E", "m. c #AAC9E1", "n. c #6C8EA6", "o. c #6C8CA4", "p. c #40474D", "q. c #DAD8D3", "r. c #E7E6E2", "s. c #67655E", "t. c #524F47", "u. c #D9D7D4", "v. c #C7C5BF", "w. c #C0BCB5", "x. c #B8B3AB", "y. c #434C54", "z. c #4D697F", "A. c #4F6F84", "B. c #B3CADC", "C. c #313E49", "D. c #A8C8E1", "E. c #6B8DA6", "F. c #728FA4", "G. c #E2E1DD", "H. c #F0EFEC", "I. c #CDCAC6", "J. c #C2BFB9", "K. c #CAC6C0", "L. c #DCDAD7", "M. c #4B555D", "N. c #4E697F", "O. c #BACCDC", "P. c #A4C4DE", "Q. c #698BA3", "R. c #708AA1", "S. c #383E43", "T. c #E0DEDA", "U. c #514E46", "V. c #4F4C44", "W. c #C7C4BE", "X. c #CBC8C2", "Y. c #E1E0DC", "Z. c #E9E8E6", "`. c #475158", " + c #4E6879", ".+ c #4D6C80", "++ c #A3C3DB", "@+ c #383F43", "#+ c #778999", "$+ c #6E899E", "%+ c #65859C", "&+ c #33383C", "*+ c #D7D4D0", "=+ c #D6D4D0", "-+ c #4E4A43", ";+ c #4D4942", ">+ c #D1CEC9", ",+ c #E6E5E2", "'+ c #EDECEA", ")+ c #454F55", "!+ c #486173", "~+ c #4D6678", "{+ c #A1C1DA", "]+ c #373C40", "^+ c #0C0D0F", "/+ c #4E5E6A", "(+ c #5B6E7C", "_+ c #4F5B62", ":+ c #A4A099", "<+ c #CCC9C3", "[+ c #D7D5D1", "}+ c #E4E2E0", "|+ c #DDDBD7", "1+ c #B8B5B0", "2+ c #3E474D", "3+ c #4A6176", "4+ c #4A6070", "5+ c #9BC3D8", "6+ c #363C41", "7+ c #28323E", " ", " ", " . . . . . . . . . . . . . . . . . . . ", " . + @ # $ % & * = - ; > , > , ' ) ! ~ { . ", " . ] ^ / ( _ : < [ } | 1 2 3 4 5 6 7 8 9 . ", " . 0 a b c d e f g h i j k l m n o b p q . ", " . r s t u u u u u u u u u u u u u t v w . ", " . x y t u u u u u u u u u u u u u t v z . ", " . A B t C D D D D D D D D D D D E t F G . ", " . H I J u u u u u u u u u u u u u t F K . ", " . L M t u u u u u u u u u u u u u t N O . ", " . P Q t C D D D D D D D D D D D R t N S . ", " . T U V u u u u u u u u u u u u u t v W . ", " . X Y Z ` t t t t t ...t t t t +.@.#.$.. ", " . %.&.p v #.*.=.-.*.;.#.>.>.N *.,.v '.).. ", " . !.~.{.].^./.(._.:.<.[.}.|.(.1.2.3.4.5.. ", " . 6.7.8.9.0.a.b.c.c.d.a.e.f.g.h.i.j.k.l.. ", " . m.n.o.p.q.r.s.t.t.u.v.w.x.e.y.z.A.B.C.. ", " . D.E.F.p.G.H.s.t.t.I.J.w.K.L.M.N.A.O.C.. ", " . P.Q.R.S.T.c.U.V.V.W.w.X.Y.Z.`. +.+++@+. ", " . #+$+%+&+*+=+-+;+;+w.>+,+'+,+)+!+~+{+]+. ", " ^+/+(+_+:+w.x.<+<+[+}+d.|+1+2+3+4+5+6+. ", " . . . . . . . . . . . . . . . . 7+. ", " "}; static const char *saveas_xpm[] = { "24 24 262 2", " c None", ". c #000000", "+ c #FBE73B", "@ c #F2B64D", "# c #FCEB3D", "$ c #F7B544", "% c #5D502C", "& c #C3D7F4", "* c #A9CDE5", "= c #75757A", "- c #EFC5BB", "; c #F1C8BE", "> c #F0C6BC", ", c #EEBCB2", "' c #EEBEB5", ") c #EEC1B8", "! c #EDBFB6", "~ c #E8B6AC", "{ c #FCE93B", "] c #F7B545", "^ c #6C5F34", "/ c #434345", "( c #92A7B9", "_ c #96B1C7", ": c #BBD6E8", "< c #8AAAC5", "[ c #605F68", "} c #E08D7E", "| c #E0826E", "1 c #E0806E", "2 c #DC7A68", "3 c #DC8171", "4 c #DA7868", "5 c #D38072", "6 c #FAE43A", "7 c #F4B244", "8 c #615030", "9 c #783E35", "0 c #4D4C52", "a c #7790A2", "b c #526D82", "c c #BAD5E9", "d c #88A7C3", "e c #686670", "f c #C8817B", "g c #CB7C74", "h c #CB7A73", "i c #CB7B73", "j c #CC7C72", "k c #CA7C72", "l c #F9DF39", "m c #F3AF42", "n c #614F2F", "o c #8F4941", "p c #945554", "q c #5B5A62", "r c #7B97AE", "s c #536F84", "t c #B6D3E7", "u c #87ABC1", "v c #737373", "w c #FFFFFF", "x c #FEFEFE", "y c #F9DC38", "z c #EFB44D", "A c #665A32", "B c #BBBBBB", "C c #CDCDCD", "D c #E4E4E4", "E c #6E6E6E", "F c #819EB6", "G c #526C80", "H c #B9D3E7", "I c #85A4BF", "J c #F8D837", "K c #F0A93F", "L c #655930", "M c #BABABA", "N c #CCCCCC", "O c #E5E5E5", "P c #F7F7F7", "Q c #727272", "R c #83A0B8", "S c #4F697C", "T c #B9D3E6", "U c #84A3BF", "V c #CECECE", "W c #F6D236", "X c #EDA43E", "Y c #5C5130", "Z c #949494", "` c #A3A3A3", " . c #B7B7B7", ".. c #C6C6C6", "+. c #BDBDBD", "@. c #88A4BB", "#. c #486276", "$. c #B7D2E7", "%. c #82A0BB", "&. c #636363", "*. c #FDFDFD", "=. c #D7AE74", "-. c #61562F", ";. c #465E70", ">. c #B5CAE5", ",. c #7FA2B9", "'. c #4F4115", "). c #87A3BA", "!. c #455C6D", "~. c #AECCE5", "{. c #7DA0B6", "]. c #CBCBCB", "^. c #9B9B9B", "/. c #9C9C9C", "(. c #A7A7A7", "_. c #B8B8B8", ":. c #C5C5C5", "<. c #546069", "[. c #B0D1E4", "}. c #83A1B6", "|. c #735B5B", "1. c #F0F0F0", "2. c #D9D9D9", "3. c #D3D3D3", "4. c #E1E1E1", "5. c #EDEDED", "6. c #F8F8F8", "7. c #515C64", "8. c #AACEE3", "9. c #7B9BB2", "0. c #7A8E9A", "a. c #7A7A7A", "b. c #707070", "c. c #6C6C6C", "d. c #6F6F6F", "e. c #6A6E71", "f. c #696969", "g. c #6F777E", "h. c #86A2B9", "i. c #3A515D", "j. c #A9C9E2", "k. c #7494AF", "l. c #7E9BB4", "m. c #7D9AB3", "n. c #7998B2", "o. c #85A1B8", "p. c #829FB7", "q. c #8CA7BD", "r. c #8AA5BB", "s. c #364A59", "t. c #ABC4E2", "u. c #7294AD", "v. c #6F90AC", "w. c #7192AE", "x. c #414A4E", "y. c #424A51", "z. c #525B63", "A. c #626F79", "B. c #5F6C76", "C. c #5C6971", "D. c #5A666F", "E. c #58636B", "F. c #57636A", "G. c #3B5360", "H. c #39424B", "I. c #7897B3", "J. c #A4B9CB", "K. c #364853", "L. c #AAC9E2", "M. c #7091AA", "N. c #6F8FA7", "O. c #4A5359", "P. c #97938C", "Q. c #DFDDDA", "R. c #E3E1DE", "S. c #EBEAE8", "T. c #EAE9E7", "U. c #CFCEC9", "V. c #C9C6C0", "W. c #9B968E", "X. c #566168", "Y. c #4B657A", "Z. c #54738C", "`. c #AAC6DD", " + c #34464E", ".+ c #AAC9E1", "++ c #6C8EA6", "@+ c #6C8CA4", "#+ c #40474D", "$+ c #DAD8D3", "%+ c #E7E6E2", "&+ c #67655E", "*+ c #524F47", "=+ c #D9D7D4", "-+ c #C7C5BF", ";+ c #C0BCB5", ">+ c #B8B3AB", ",+ c #434C54", "'+ c #4D697F", ")+ c #4F6F84", "!+ c #B3CADC", "~+ c #313E49", "{+ c #A8C8E1", "]+ c #6B8DA6", "^+ c #728FA4", "/+ c #E2E1DD", "(+ c #F0EFEC", "_+ c #CDCAC6", ":+ c #C2BFB9", "<+ c #CAC6C0", "[+ c #DCDAD7", "}+ c #4B555D", "|+ c #4E697F", "1+ c #BACCDC", "2+ c #A4C4DE", "3+ c #698BA3", "4+ c #708AA1", "5+ c #383E43", "6+ c #E0DEDA", "7+ c #514E46", "8+ c #4F4C44", "9+ c #C7C4BE", "0+ c #CBC8C2", "a+ c #E1E0DC", "b+ c #E9E8E6", "c+ c #475158", "d+ c #4E6879", "e+ c #4D6C80", "f+ c #A3C3DB", "g+ c #383F43", "h+ c #778999", "i+ c #6E899E", "j+ c #65859C", "k+ c #33383C", "l+ c #D7D4D0", "m+ c #D6D4D0", "n+ c #4E4A43", "o+ c #4D4942", "p+ c #D1CEC9", "q+ c #E6E5E2", "r+ c #EDECEA", "s+ c #454F55", "t+ c #486173", "u+ c #4D6678", "v+ c #A1C1DA", "w+ c #373C40", "x+ c #0C0D0F", "y+ c #4E5E6A", "z+ c #5B6E7C", "A+ c #4F5B62", "B+ c #A4A099", "C+ c #CCC9C3", "D+ c #D7D5D1", "E+ c #E4E2E0", "F+ c #DDDBD7", "G+ c #B8B5B0", "H+ c #3E474D", "I+ c #4A6176", "J+ c #4A6070", "K+ c #9BC3D8", "L+ c #363C41", "M+ c #28323E", " . . ", " . + @ . ", " . . . . . . . . . . . . . # $ % . . . ", " . & * = - ; > , ' ) ! ~ . { ] ^ . / ( _ . ", " . : < [ } | 1 2 3 4 5 . 6 7 8 . 9 0 a b . ", " . c d e f g h i j k . l m n . o p q r s . ", " . t u v w w w w x . y z A . B C D E F G . ", " . H I v w w w x . J K L . M N O P Q R S . ", " . T U v V C N . W X Y . Z ` ...+.v @.#.. ", " . $.%.&.w w *.. =.-.. M N D P *.w v @.;.. ", " . >.,.v w x . '.. . M N D P *.w w v ).!.. ", " . ~.{.v V ].. . ^./.(._...].C C :.v ).<.. ", " . [.}.|.w *.1.2.3.4.5.6.x w w w w v R 7.. ", " . 8.9.0.a.Q b.c.c.d.e.E v v v v f.g.h.i.. ", " . j.k.F R h.F l.m.F n.h.o.o.).p.q.R r.s.. ", " . t.u.v.w.x.y.z.A.B.C.D.E.F.z.G.H.I.J.K.. ", " . L.M.N.O.P.Q.R.S.S.T.Q.U.V.W.X.Y.Z.`. +. ", " . .+++@+#+$+%+&+*+*+=+-+;+>+U.,+'+)+!+~+. ", " . {+]+^+#+/+(+&+*+*+_+:+;+<+[+}+|+)+1+~+. ", " . 2+3+4+5+6+S.7+8+8+9+;+0+a+b+c+d+e+f+g+. ", " . h+i+j+k+l+m+n+o+o+;+p+q+r+q+s+t+u+v+w+. ", " x+y+z+A+B+;+>+C+C+D+E+T.F+G+H+I+J+K+L+. ", " . . . . . . . . . . . . . . . . M+. ", " "}; static const char *new_xpm[] = { "24 24 127 2", " c None", ". c #000000", "+ c #D3D3D3", "@ c #F6F6F6", "# c #FFFFFF", "$ c #F9F9F9", "% c #DADADA", "& c #585858", "* c #C7C7C7", "= c #D1D1D1", "- c #D6D6D6", "; c #FEFEFE", "> c #FDFDFD", ", c #C0C0C0", "' c #E1E1E1", ") c #F0F0F0", "! c #9B9B9B", "~ c #FCFCFB", "{ c #FBFBFB", "] c #AFAFAE", "^ c #E9E9E9", "/ c #DFDFDF", "( c #8F8F8F", "_ c #FAFAF9", ": c #F9F9F8", "< c #A4A4A3", "[ c #F4F4F4", "} c #CFCFCF", "| c #A2A2A2", "1 c #F8F8F7", "2 c #F8F7F6", "3 c #9E9E9E", "4 c #F7F6F5", "5 c #F6F6F4", "6 c #F4F3F2", "7 c #DEDDDC", "8 c #D3D2D0", "9 c #B7B7B5", "0 c #9F9E9D", "a c #706F6F", "b c #65625A", "c c #F5F4F3", "d c #F2F2F0", "e c #E4E4E2", "f c #DAD9D7", "g c #D8D8D6", "h c #CDCCCA", "i c #AFAEAC", "j c #88847B", "k c #F3F3F1", "l c #EFEFED", "m c #EEEDEB", "n c #EDECEA", "o c #E9E8E6", "p c #D5D4D3", "q c #C4C3C2", "r c #8F8A81", "s c #F6F5F4", "t c #F5F5F3", "u c #F1F1EF", "v c #F1F0EE", "w c #ECEBE9", "x c #EAE9E7", "y c #E5E4E2", "z c #E4E3E0", "A c #D2D1CE", "B c #8D887E", "C c #F3F2F1", "D c #F0F0EE", "E c #F0EFED", "F c #EFEEEC", "G c #E8E7E5", "H c #E5E4E1", "I c #E2E1DE", "J c #E1DFDC", "K c #979288", "L c #A49E93", "M c #E8E7E4", "N c #E7E6E3", "O c #E3E2DF", "P c #E2E0DD", "Q c #E1E0DC", "R c #E0DFDB", "S c #A19C90", "T c #EDEDEB", "U c #EBEAE8", "V c #E9E8E5", "W c #E6E4E1", "X c #E3E2DE", "Y c #DFDEDA", "Z c #DEDDD9", "` c #DDDCD8", " . c #A19B90", ".. c #E7E5E2", "+. c #E4E3DF", "@. c #DCDBD7", "#. c #E6E5E2", "$. c #E5E4E0", "%. c #E2E1DD", "&. c #DBD9D5", "*. c #D9D7D3", "=. c #9F998D", "-. c #E4E2DF", ";. c #DDDBD7", ">. c #DCDAD6", ",. c #D8D6D2", "'. c #9E988D", "). c #EDEDED", "!. c #E1E0DD", "~. c #E0DEDA", "{. c #D8D6D1", "]. c #D7D5D1", "^. c #9D978B", "/. c #E1DFDB", "(. c #DEDCD8", "_. c #D7D6D1", ":. c #D5D3CE", "<. c #9B958A", "[. c #999891", "}. c #A39E92", "|. c #A39D92", "1. c #A39D91", "2. c #A29C90", "3. c #A19B8F", "4. c #9D978C", "5. c #9B968A", "6. c #676359", " ", " . . . . . . . . . . . . . ", " . + @ # # # # # # # # $ % & . ", " . @ # # # # # # # # # # * = - . ", " . # # # # # # # ; # ; > , ' ) ! . ", " . # # # # # ; > ~ > ~ { ] ^ # / ( . ", " . # # # ; > ~ { _ { _ : < ) # [ } | . ", " . # ; > ~ { _ : 1 : 1 2 3 . . . . . . . ", " . # ~ { _ : 1 2 4 2 4 5 6 7 8 9 0 a b . ", " . # _ : 1 2 4 5 c 5 c 6 d e f g h i j . ", " . # 1 2 4 5 c 6 k 6 k d l m n o p q r . ", " . # s t 6 6 k d u d u v m w x y z A B . ", " . # 6 C d D l v E v E F w G H z I J K . ", " . # 6 C d D l v E v E F w G H z I J L . ", " . # D l l F m n n n n w M N O P Q R S . ", " . # T n w w w U V U V V H W X Y Z ` .. ", " . # U o o G M M N M N ..+.X R Z ` @. .. ", " . # N #.#.#.H W $.W $.+.%.R Z @.&.*.=.. ", " . $ z O X -.+.%.X %.X Q Q Z ;.>.*.,.'.. ", " . ).!.J Q R %.R Q R Q Y ~.;.>.*.{.].^.. ", " . = /.~.Y Z R Z ~.Z ~.(.(.>.>.,._.:.<.. ", " . [.}.L |.1.|.S 2.S 2.3. .=.=.4.4.5.6.. ", " . . . . . . . . . . . . . . . . . . ", " "}; static const char *open_xpm[] = { "24 24 173 2", " c None", ". c #000000", "+ c #010100", "@ c #B5B8A5", "# c #E4E7D2", "$ c #878A76", "% c #33342B", "& c #0B0B0B", "* c #E2E5CF", "= c #CFD4AF", "- c #CED3AE", "; c #B2B696", "> c #2D2D25", ", c #23241D", "' c #9D9F90", ") c #C6CAA6", "! c #C4C9A5", "~ c #C6CBA7", "{ c #C7CCA8", "] c #C9CEA9", "^ c #555847", "/ c #1A1B15", "( c #20201A", "_ c #D4D6C2", ": c #BEC2A0", "< c #B3B896", "[ c #B0B595", "} c #B3B797", "| c #B6BB99", "1 c #BBC09E", "2 c #BCC19F", "3 c #81856C", "4 c #3E3F32", "5 c #010101", "6 c #DADDC8", "7 c #AFB494", "8 c #AAAF8F", "9 c #A3A789", "0 c #A6AA8B", "a c #A9AD8E", "b c #A7AB8D", "c c #A4A88A", "d c #A1A588", "e c #AAAD96", "f c #B3B5A5", "g c #B8BBAA", "h c #BABCAB", "i c #C1C3B2", "j c #C7CAB7", "k c #CACDBB", "l c #BABDA8", "m c #0C0C09", "n c #DDDFCB", "o c #969B7E", "p c #9DA286", "q c #95987C", "r c #96997E", "s c #9A9D81", "t c #999D80", "u c #9DA184", "v c #A5AA8B", "w c #A4A98A", "x c #A3A889", "y c #A2A588", "z c #A2A587", "A c #9FA386", "B c #9B9E83", "C c #898D74", "D c #D8DBC9", "E c #84866E", "F c #7D8169", "G c #151612", "H c #D7DAC9", "I c #797D67", "J c #3D3F34", "K c #E0E0D9", "L c #EBEDDD", "M c #E8EBD9", "N c #E7EAD8", "O c #E3E6D4", "P c #DEE1D0", "Q c #DADCCC", "R c #DADCD1", "S c #2B2C28", "T c #D7DAC6", "U c #6F735E", "V c #0D0D0D", "W c #F4F4EC", "X c #CACFAB", "Y c #C6CBA8", "Z c #C2C6A4", "` c #ABB091", " . c #23251E", ".. c #494B3D", "+. c #DCDCD4", "@. c #EAECDD", "#. c #CDD2AD", "$. c #CCD1AC", "%. c #CACFAA", "&. c #BABF9D", "*. c #B5B999", "=. c #81836C", "-. c #070806", ";. c #D5D8C4", ">. c #161616", ",. c #F2F2EA", "'. c #C9CEAA", "). c #C8CDA9", "!. c #C4C9A6", "~. c #C1C5A3", "{. c #BCC09F", "]. c #B6BB9A", "^. c #B0B494", "/. c #9DA185", "(. c #535445", "_. c #B6B8A7", ":. c #747470", "<. c #ECECE2", "[. c #C3C8A5", "}. c #C2C7A4", "|. c #C0C5A2", "1. c #BFC4A1", "2. c #BDC2A0", "3. c #B9BD9C", "4. c #B9BE9D", "5. c #A9AD8F", "6. c #A3A78A", "7. c #80836D", "8. c #020201", "9. c #A6A998", "0. c #B8BC9B", "a. c #AFB394", "b. c #ACB091", "c. c #A8AC8E", "d. c #A6AA8C", "e. c #9FA286", "f. c #9B9F83", "g. c #9A9D82", "h. c #8A8D75", "i. c #4F5243", "j. c #070705", "k. c #9E9F91", "l. c #E5E6DA", "m. c #ADB192", "n. c #A5A98C", "o. c #9FA387", "p. c #999D81", "q. c #95987E", "r. c #92957B", "s. c #8C8F76", "t. c #8A8D74", "u. c #71735F", "v. c #080908", "w. c #E3E5D9", "x. c #C0C3AF", "y. c #94987C", "z. c #8F9379", "A. c #8B8F75", "B. c #8A8E74", "C. c #888C73", "D. c #858970", "E. c #868971", "F. c #82866E", "G. c #80836C", "H. c #7D8069", "I. c #797C66", "J. c #727560", "K. c #717460", "L. c #71745F", "M. c #6A6D59", "N. c #434538", "O. c #080907", "P. c #050504", " ", " ", " ", " . . . . . . . ", " + @ # # # # # $ % ", " & * = = = - - ; > ", ", ' * ) ! ~ { ] ] ^ / ", "( _ : < [ } | 1 2 3 4 5 . . . . . . . ", ", 6 7 8 9 0 8 a b c d e f g h i j k l . ", "m n o p q r s t r u v w x y 9 z A B C . ", ". D E F G . . . . . . . . . . . . . . . 5 5 ", ". H I J K L M M M M M M M M M M M N O P Q R S ", ". T U V W = = = = = = = = = - - - X Y Z 1 ` . ", ". T ..+.@.#.- - #.- #.#.#.#.#.$.%.Y Z &.*.=.-. ", ". ;.>.,.X %.X %.'.%.'.{ ).).Y !.~.{.].^./.(.m ", ". _.:.<.[.}.}.Z |.Z 1.2.|.2.3.4.} [ 5.6.7.8. ", ". 9.+.0.0.*.} } [ [ a.a.a.b.c.d.e.f.g.h.i.j. ", ". k.l.m.5.d.n.6.6.d o.e.f.p.q.r.s.t.t.u.v. ", ". w.x.y.z.A.B.C.C.D.E.F.G.H.I.J.K.L.M.N.O. ", " . . . . . . . . . . . . . . . . . . P. ", " ", " ", " ", " "}; static const char *exit_xpm[] = { "24 24 140 2", " c None", ". c #000000", "+ c #D6D6D4", "@ c #BDBDBC", "# c #A8A8A4", "$ c #92928F", "% c #727370", "& c #61615E", "* c #20201F", "= c #F1F1EF", "- c #E6E6E4", "; c #DADAD7", "> c #CFCFCD", ", c #C4C4C1", "' c #A8A8A5", ") c #767674", "! c #777774", "~ c #1E1E1D", "{ c #B9B9B7", "] c #AEAEAC", "^ c #8F8F8D", "/ c #262626", "( c #414140", "_ c #E9836C", ": c #DEDEDC", "< c #C5C5C2", "[ c #636362", "} c #040504", "| c #040604", "1 c #050705", "2 c #E87B62", "3 c #E67056", "4 c #D5D5D3", "5 c #DBDBD8", "6 c #D0D0CE", "7 c #080A07", "8 c #0A0C09", "9 c #0A0D09", "0 c #0B0E0A", "a c #F0B0A1", "b c #EB8D77", "c c #DF421E", "d c #E97E66", "e c #CBCBC8", "f c #0C0F0B", "g c #0F130D", "h c #10140E", "i c #11150F", "j c #EFA392", "k c #BFBFBD", "l c #5D5D5C", "m c #10150F", "n c #141912", "o c #161C14", "p c #171D15", "q c #B7B7B4", "r c #0C0C0C", "s c #192017", "t c #1C2319", "u c #1D241A", "v c #CD8484", "w c #990000", "x c #701616", "y c #A6A6A5", "z c #181E16", "A c #1E261B", "B c #212A1E", "C c #222B1F", "D c #4F0000", "E c #AEAEAB", "F c #1D261B", "G c #242E21", "H c #273224", "I c #283325", "J c #580000", "K c #B5B5B3", "L c #293426", "M c #2D3929", "N c #2E3A2A", "O c #7C4343", "P c #6A0000", "Q c #720000", "R c #BDBDBB", "S c #232C20", "T c #2A3526", "U c #303C2B", "V c #33402E", "W c #C5C5C3", "X c #1E261C", "Y c #303D2C", "Z c #374532", "` c #394834", " . c #500000", ".. c #CDCDCB", "+. c #1B2319", "@. c #253022", "#. c #303E2D", "$. c #394934", "%. c #3D4E38", "&. c #9D9D9B", "*. c #565655", "=. c #2C3828", "-. c #40503A", ";. c #43553E", ">. c #BABAB7", ",. c #777776", "'. c #323830", "). c #232C1F", "!. c #313E2D", "~. c #3B4A36", "{. c #43553D", "]. c #485B42", "^. c #4A5E44", "/. c #F0F0EE", "(. c #E5E5E3", "_. c #C6C6C3", ":. c #ACACAB", "<. c #8B8B8A", "[. c #32392F", "}. c #2C3728", "|. c #3F503A", "1. c #465840", "2. c #4B5E44", "3. c #4E6347", "4. c #506549", "5. c #DADAD8", "6. c #7A7D78", "7. c #333C30", "8. c #475A41", "9. c #4F6348", "0. c #53694C", "a. c #566C4E", "b. c #576D4F", "c. c #91968F", "d. c #3B4736", "e. c #42543C", "f. c #51674A", "g. c #586F50", "h. c #5B7353", "i. c #5C7454", " ", " . . . . . . . . . . . . . . . . ", " . + @ # $ % & & & * . . . . . . ", " . = - ; > , ' ) ! ~ . . . . . . ", " . . = - ; > , { ] ^ / . . . . . . ", " . . . = - ; > , { { { ( . . . . . . ", " . _ . : - ; > < { { { [ } | 1 1 1 . ", ". . . . . . 2 3 . 4 5 6 < { { { [ 7 8 9 0 0 . ", ". a 2 2 2 2 b c d . e 6 < { { { [ f g h i i . ", ". j c c c c c c c 3 . k < { l { [ m n o p p . ", ". j c c c c c c c c 3 . q { l r [ n s t u u . ", ". v w w w w w w w w w x . y r { [ z A B C C . ", ". v w w w w w w w w D . E { { { [ F G H I I . ", ". v w w w w w w w J . K < { { { [ C L M N N . ", ". O P P P P Q w J . R 6 < { { { [ S T U V V . ", ". . . . . . Q J . W 5 6 < { { { [ X H Y Z ` . ", " . .. ..- 5 6 < { { { [ +.@.#.$.%.. ", " . . . = - 5 6 < { ] &.*.B =.Z -.;.. ", " . . = - 5 6 >.&.,.'.).!.~.{.].^.. ", " . /.(._.:.<.[.}.Z |.1.2.3.4.4.. ", " . 5.k 6.7.Z -.8.9.0.a.a.b.b.b.. ", " . c.d.e.^.f.g.h.i.i.i.i.i.i.i.. ", " . . . . . . . . . . . . . . . . ", " "}; static const char *separator_xpm[] = { "3 24 4 1", " c None", ". c #DBD3CB", "+ c #FCFBFA", "g c #777777", "g.+", "g.+", "g.+", "g.+", "g.+", "g.+", "g.+", "g.+", "g.+", "g.+", "g.+", "g.+", "g.+", "g.+", "g.+", "g.+", "g.+", "g.+", "g.+", "g.+", "g.+", "g.+", "g.+", "g.+"}; static const char *up_node2_xpm[] = { "24 24 18 1", " c None", ". c #000000", "+ c #FFFFFF", "@ c #DADAD6", "# c #BCBCB8", "$ c #778E6F", "% c #506B46", "& c #0F1308", "* c #6B9060", "= c #445B2C", "- c #A9C7A6", "; c #BDD3B8", "> c #77A16E", ", c #C2D7BE", "' c #C1D6BD", ") c #B0CAAD", "! c #A4C3A2", "~ c #8CA782", " .................. ", " .+++++++++++++++@#. ", " .+++++++++++++++#+#. ", " .+++++++++++++++#$%&. ", " .+++++++++++++++@$%&. ", " .+++++++++++++++++@#. ", " .++++++++++++@@@@@@#. ", " .+++++++++++++@@@@@#. ", " .++++++++++++@@@@@@#. ", " .+++++@@##$####@#@@#. ", " .+++@+@@#..$$####@@#. ", " .++++@@#.*=.%####@##. ", " .+++@@#.*-*=.$$###@#. ", " .+++@#.*-;**=.%###@#. ", " .++@#.*--;***=.$$###. ", " .++#.*---;****=.$###. ", " .+#.>,,;-;*****=.#@#. ", " .+%....')'***.....@#. ", " .++++@.'-;***.$#####. ", " .++++@.'-;***.###@##. ", " .+++++.'-;***.#@++##. ", " .......'-;***........ ", " .,,@!~>. ", " ........ "}; static const char *stop_xpm[] = { "24 24 3 1", " c None", ". c #cc0033", "X c #FFFFFFFFFFFF", " ", " ", " .......... ", " ............ ", " .............. ", " ................ ", " .................. ", " ..XX..XXX..XX..XXX.. ", " .X..X..X..X..X.X..X. ", " .X.....X..X..X.X..X. ", " .X.....X..X..X.X..X. ", " ..X....X..X..X.X..X. ", " ...X...X..X..X.XXX.. ", " ....X..X..X..X.X.... ", " ....X..X..X..X.X.... ", " .X..X..X..X..X.X.... ", " ..XX...X...XX..X.... ", " .................. ", " ................ ", " .............. ", " ............ ", " .......... ", " ", " "}; static const char *home_xpm[] = { "24 24 101 2", " c None", ". c #000000", "+ c #212121", "@ c #2C2C2C", "# c #C1665A", "$ c #924B37", "% c #2A2A2A", "& c #333333", "* c #343434", "= c #242424", "- c #944D3A", "; c #A05443", "> c #181818", ", c #474747", "' c #555555", ") c #8D8D8D", "! c #383838", "~ c #191919", "{ c #974F3C", "] c #222222", "^ c #313131", "/ c #A1A1A1", "( c #676767", "_ c #ACACAC", ": c #BCBCBC", "< c #585858", "[ c #141414", "} c #1C1C1C", "| c #464646", "1 c #666666", "2 c #BABABA", "3 c #7E7E7E", "4 c #D2D2D2", "5 c #FFFFFF", "6 c #4F4F4F", "7 c #262626", "8 c #232323", "9 c #505050", "0 c #B2B2B2", "a c #909090", "b c #9A9A9A", "c c #838383", "d c #171717", "e c #202020", "f c #717171", "g c #A6A6A6", "h c #616161", "i c #1D1D1D", "j c #1F1F1F", "k c #C4C4C4", "l c #CACACA", "m c #AEAEAE", "n c #D1D1D1", "o c #7C7C7C", "p c #BFBFBF", "q c #6C6C6C", "r c #EEEEEE", "s c #949494", "t c #C7C7C7", "u c #EBEBEB", "v c #7D7D7D", "w c #6E6E6E", "x c #A9A9A9", "y c #E99E8F", "z c #DD806D", "A c #9B5343", "B c #CECECE", "C c #626262", "D c #858585", "E c #ECA292", "F c #D0533A", "G c #934F3E", "H c #6D6D6D", "I c #ECA291", "J c #CF543C", "K c #371D16", "L c #5D5D5D", "M c #868686", "N c #787878", "O c #ECA696", "P c #C95C49", "Q c #E17C66", "R c #924E3D", "S c #888888", "T c #A0A0A0", "U c #3D1208", "V c #D15137", "W c #919191", "X c #879981", "Y c #82947C", "Z c #8A9B85", "` c #6E8467", " . c #5D7555", ".. c #4C6042", "+. c #3F4F37", "@. c #303D2A", "#. c #7F8F7A", "$. c #64785E", "%. c #44563E", "&. c #657460", "*. c #40503A", " ", " . . ", " . . . . . + @ . ", " . # $ . . % & * = . ", " . - ; . > , ' ) ! ~ . ", " . { . ] ^ / ( _ : < [ . ", " . . } | 1 2 3 4 : 5 6 7 . ", " . 8 9 0 a 4 b 5 : 5 : c d . ", " . e f g 4 b 5 : 5 : 5 : 5 h i . ", " . j k k l 5 m 5 2 5 2 5 : 5 n o } . ", " . 8 m p p p p p p p p . . . . . a q = . ", " . . . . r 5 5 5 5 5 5 5 . s t u . v . . . . ", " . 4 5 . . . . . 5 . : 5 5 . w . ", " . x 5 . y z A . 5 . B 5 5 . C . ", " . D 5 . E F G . 5 . . . . . H . ", " . . 5 . I J K . k s L L M N . . ", " . . r . O P G . 5 5 5 5 5 2 . ", " . 2 . Q # R . : : : : : S . ", " . T U V # A . 5 5 5 5 5 W . ", " . . . . . . . . . . . . . . . . . . . . . ", " } X Y Z X ` ...+.@.. Y #.$.%.&.*.. ", " . . . . . . . . . . . . . . . . . ", " . . . ", " "}; static const char *left_arrow_xpm[] = { "24 24 43 1", " c None", ". c #000000", "+ c #B9D0B9", "@ c #CDDECB", "# c #B6C7B6", "$ c #B1C9B0", "% c #B3C4B3", "& c #B4CBB2", "* c #B5CEB5", "= c #B7CCB5", "- c #B9CEB7", "; c #BAD1BA", "> c #BBCFBA", ", c #BBD0B9", "' c #B2C9B0", ") c #7EAB78", "! c #AAC7A8", "~ c #B3CAB1", "{ c #B0C9B0", "] c #B0C9AE", "^ c #AEC7AC", "/ c #AAC5A8", "( c #A9C4A7", "_ c #698267", ": c #2D2D2D", "< c #CFDFCC", "[ c #ADC8AB", "} c #B0C7AE", "| c #ADC6AB", "1 c #678C63", "2 c #9BAD9A", "3 c #85AE81", "4 c #87AF84", "5 c #87B083", "6 c #88AF84", "7 c #88B085", "8 c #86AF82", "9 c #547150", "0 c #3C5235", "a c #5B7950", "b c #4A6342", "c c #3B5035", "d c #415639", " ", " ", " ", " . ", " .. ", " .+. ", " .@#. ", " .@$%........ ", " .@&*=-;->,'). ", " .@!~{]^///^(_. ", " :<[}||[!^^}^[1. ", " .23444445645789. ", " .0aaaaaaaaaaab. ", " .0aaaaaaaaaab. ", " .0aabccccccd. ", " .0ab........ ", " .0b. ", " .b. ", " .. ", " . ", " ", " ", " ", " "}; static const char *right_arrow_xpm[] = { "24 24 41 1", " c None", ". c #000000", "+ c #8CA782", "@ c #B1CDAE", "# c #77A16E", "$ c #B4CEB1", "% c #ACC8A9", "& c #709867", "* c #C1D6BD", "= c #BDD3B8", "- c #BFD4BB", "; c #C2D7BE", "> c #B0CAAD", ", c #B2CBB0", "' c #AAC7A8", ") c #0F1308", "! c #AEC5A8", "~ c #AEC8AD", "{ c #ABC7A8", "] c #AAC6A7", "^ c #A8C6A5", "/ c #ADC8AD", "( c #A8C7A8", "_ c #A5C4A3", ": c #7F9F76", "< c #A6BFA0", "[ c #ABC7AA", "} c #A7C5A4", "| c #A9C7A6", "1 c #AFC8AD", "2 c #A4C3A2", "3 c #6B9060", "4 c #778E6F", "5 c #698D60", "6 c #6B9063", "7 c #445B2C", "8 c #6B8661", "9 c #5B7950", "0 c #6C8562", "a c #65815C", "b c #506B46", " ", " ", " ", " . ", " .. ", " .+. ", " .@#. ", " ........$%&. ", " .*=-;;;;>,'&) ", " .!~{{{]^'/(_:. ", " .<[^}^|{%'{123. ", " .45666666666657. ", " .8999999999997. ", " .099999999997. ", " .abbbbbb9997. ", " ........b97. ", " .b7. ", " .7. ", " .. ", " . ", " ", " ", " ", " "}; static const char *back_arrow_xpm[] = { "24 24 43 1", " c None", ". c #000000", "+ c #B9D0B9", "@ c #CDDECB", "# c #B6C7B6", "$ c #B1C9B0", "% c #B3C4B3", "& c #B4CBB2", "* c #B5CEB5", "= c #B7CCB5", "- c #B9CEB7", "; c #BAD1BA", "> c #BBCFBA", ", c #BBD0B9", "' c #B2C9B0", ") c #7EAB78", "! c #AAC7A8", "~ c #B3CAB1", "{ c #B0C9B0", "] c #B0C9AE", "^ c #AEC7AC", "/ c #AAC5A8", "( c #A9C4A7", "_ c #698267", ": c #2D2D2D", "< c #CFDFCC", "[ c #ADC8AB", "} c #B0C7AE", "| c #ADC6AB", "1 c #678C63", "2 c #9BAD9A", "3 c #85AE81", "4 c #87AF84", "5 c #87B083", "6 c #88AF84", "7 c #88B085", "8 c #86AF82", "9 c #547150", "0 c #3C5235", "a c #5B7950", "b c #4A6342", "c c #3B5035", "d c #415639", " ", " ", " ... ", " ... . ", " ... .. ", " ... .+. ", " ... .@#. ", " ... .@$%........ ", " ... .@&*=-;->,'). ", " ... .@!~{]^///^(_. ", " ...:<[}||[!^^}^[1. ", " ...23444445645789. ", " ....0aaaaaaaaaaab. ", " ... .0aaaaaaaaaab. ", " ... .0aabccccccd. ", " ... .0ab........ ", " ... .0b. ", " ... .b. ", " ... .. ", " ... . ", " ... ", " ", " ", " "}; static const char *fwd_arrow_xpm[] = { "24 24 41 1", " c None", ". c #000000", "+ c #8CA782", "@ c #B1CDAE", "# c #77A16E", "$ c #B4CEB1", "% c #ACC8A9", "& c #709867", "* c #C1D6BD", "= c #BDD3B8", "- c #BFD4BB", "; c #C2D7BE", "> c #B0CAAD", ", c #B2CBB0", "' c #AAC7A8", ") c #0F1308", "! c #AEC5A8", "~ c #AEC8AD", "{ c #ABC7A8", "] c #AAC6A7", "^ c #A8C6A5", "/ c #ADC8AD", "( c #A8C7A8", "_ c #A5C4A3", ": c #7F9F76", "< c #A6BFA0", "[ c #ABC7AA", "} c #A7C5A4", "| c #A9C7A6", "1 c #AFC8AD", "2 c #A4C3A2", "3 c #6B9060", "4 c #778E6F", "5 c #698D60", "6 c #6B9063", "7 c #445B2C", "8 c #6B8661", "9 c #5B7950", "0 c #6C8562", "a c #65815C", "b c #506B46", " ", " ", " ... ", " . ... ", " .. ... ", " .+. ... ", " .@#. ... ", " ........$%&. ... ", " .*=-;;;;>,'&) ... ", " .!~{{{]^'/(_:. ... ", " .<[^}^|{%'{123.... ", " .45666666666657... ", " .8999999999997.... ", " .099999999997. ... ", " .abbbbbb9997. ... ", " ........b97. ... ", " .b7. ... ", " .7. ... ", " .. ... ", " . ... ", " ... ", " ", " ", " "}; /* ---------------- */ static const char *cursor_play_xpm[] = { "24 24 2 1", " c None", ". c #000000", " ", " ", " ", " . . ", " .. .. ", " ... ... ", " .... .... ", " ..... ..... ", " ...... ...... ", " ....... ....... ", " ........ ........ ", " .................. ", " .................. ", " ........ ........ ", " ....... ....... ", " ...... ...... ", " ..... ..... ", " .... .... ", " ... ... ", " .. .. ", " . . ", " ", " ", " "}; static const char *play_xpm[] = { " 24 24 2 1", " c None", "# c #000000", " ", " ", " ", " # ", " ## ", " ### ", " #### ", " ##### ", " ###### ", " ####### ", " ######## ", " ######### ", " ######### ", " ######## ", " ####### ", " ###### ", " ##### ", " #### ", " ### ", " ## ", " # ", " ", " ", " " }; static const char *stop_play_xpm[] = { " 24 24 2 1", " c None", "# c #000000", " ", " ", " ", " ", " ", " ########### ", " ########### ", " ########### ", " ########### ", " ########### ", " ########### ", " ########### ", " ########### ", " ########### ", " ########### ", " ########### ", " ########### ", " ########### ", " ########### ", " ", " ", " ", " ", " " }; static Pixmap toolbar_pixmaps[NUM_TOOLBAR_PIXMAPS]; void make_toolbar_icons(Widget w) { Pixmap shape1, shape2; XpmAttributes attributes; XpmColorSymbol symbols[1]; int i, scr; Display *dp; Drawable wn; for (i = 0; i < NUM_TOOLBAR_PIXMAPS; i++) toolbar_pixmaps[i] = None; dp = XtDisplay(w); wn = XtWindow(w); scr = DefaultScreen(dp); XtVaGetValues(w, XmNdepth, &attributes.depth, XmNcolormap, &attributes.colormap, NULL); attributes.visual = DefaultVisual(dp, scr); symbols[0].name = (char *)"basiccolor"; symbols[0].value = NULL; symbols[0].pixel = ss->basic_color; attributes.colorsymbols = symbols; attributes.numsymbols = 1; attributes.valuemask = XpmColorSymbols | XpmDepth | XpmColormap | XpmVisual; XpmCreatePixmapFromData(dp, wn, (char **)back_arrow_xpm, &toolbar_pixmaps[SND_XPM_BACK_ARROW], &shape1, &attributes); XpmCreatePixmapFromData(dp, wn, (char **)fwd_arrow_xpm, &toolbar_pixmaps[SND_XPM_FORWARD_ARROW], &shape1, &attributes); XpmCreatePixmapFromData(dp, wn, (char **)zoom_in_xpm, &toolbar_pixmaps[SND_XPM_ZOOM_IN], &shape1, &attributes); XpmCreatePixmapFromData(dp, wn, (char **)zoom_out_xpm, &toolbar_pixmaps[SND_XPM_ZOOM_OUT], &shape1, &attributes); XpmCreatePixmapFromData(dp, wn, (char **)cut_xpm, &toolbar_pixmaps[SND_XPM_CUT], &shape1, &attributes); XpmCreatePixmapFromData(dp, wn, (char **)paste_xpm, &toolbar_pixmaps[SND_XPM_PASTE], &shape1, &attributes); XpmCreatePixmapFromData(dp, wn, (char **)preferences_xpm, &toolbar_pixmaps[SND_XPM_PREFERENCES], &shape1, &attributes); XpmCreatePixmapFromData(dp, wn, (char **)close_xpm, &toolbar_pixmaps[SND_XPM_CLOSE], &shape1, &attributes); XpmCreatePixmapFromData(dp, wn, (char **)redo_xpm, &toolbar_pixmaps[SND_XPM_REDO], &shape1, &attributes); XpmCreatePixmapFromData(dp, wn, (char **)undo_xpm, &toolbar_pixmaps[SND_XPM_UNDO], &shape1, &attributes); XpmCreatePixmapFromData(dp, wn, (char **)save_xpm, &toolbar_pixmaps[SND_XPM_SAVE], &shape1, &attributes); XpmCreatePixmapFromData(dp, wn, (char **)saveas_xpm, &toolbar_pixmaps[SND_XPM_SAVE_AS], &shape1, &attributes); XpmCreatePixmapFromData(dp, wn, (char **)new_xpm, &toolbar_pixmaps[SND_XPM_NEW], &shape1, &attributes); XpmCreatePixmapFromData(dp, wn, (char **)open_xpm, &toolbar_pixmaps[SND_XPM_OPEN], &shape1, &attributes); XpmCreatePixmapFromData(dp, wn, (char **)right_arrow_xpm, &toolbar_pixmaps[SND_XPM_NEXT], &shape1, &attributes); XpmCreatePixmapFromData(dp, wn, (char **)left_arrow_xpm, &toolbar_pixmaps[SND_XPM_BACK], &shape1, &attributes); XpmCreatePixmapFromData(dp, wn, (char **)exit_xpm, &toolbar_pixmaps[SND_XPM_EXIT], &shape1, &attributes); XpmCreatePixmapFromData(dp, wn, (char **)separator_xpm, &toolbar_pixmaps[SND_XPM_SEPARATOR], &shape2, &attributes); XpmCreatePixmapFromData(dp, wn, (char **)up_node2_xpm, &toolbar_pixmaps[SND_XPM_UP], &shape1, &attributes); XpmCreatePixmapFromData(dp, wn, (char **)stop_xpm, &toolbar_pixmaps[SND_XPM_STOP], &shape1, &attributes); XpmCreatePixmapFromData(dp, wn, (char **)home_xpm, &toolbar_pixmaps[SND_XPM_REVERT], &shape1, &attributes); XpmCreatePixmapFromData(dp, wn, (char **)play_xpm, &toolbar_pixmaps[SND_XPM_PLAY], &shape1, &attributes); XpmCreatePixmapFromData(dp, wn, (char **)cursor_play_xpm, &toolbar_pixmaps[SND_XPM_CURSOR_PLAY], &shape1, &attributes); XpmCreatePixmapFromData(dp, wn, (char **)stop_play_xpm, &toolbar_pixmaps[SND_XPM_STOP_PLAY], &shape1, &attributes); } Pixmap toolbar_icon(int which) { switch (which) { case SND_XPM_BACK_ARROW: return(toolbar_pixmaps[SND_XPM_BACK_ARROW]); case SND_XPM_FORWARD_ARROW: return(toolbar_pixmaps[SND_XPM_FORWARD_ARROW]); case SND_XPM_ZOOM_IN: return(toolbar_pixmaps[SND_XPM_ZOOM_IN]); case SND_XPM_ZOOM_OUT: return(toolbar_pixmaps[SND_XPM_ZOOM_OUT]); case SND_XPM_CUT: return(toolbar_pixmaps[SND_XPM_CUT]); case SND_XPM_PASTE: return(toolbar_pixmaps[SND_XPM_PASTE]); case SND_XPM_PREFERENCES: return(toolbar_pixmaps[SND_XPM_PREFERENCES]); case SND_XPM_CLOSE: return(toolbar_pixmaps[SND_XPM_CLOSE]); case SND_XPM_REDO: return(toolbar_pixmaps[SND_XPM_REDO]); case SND_XPM_UNDO: return(toolbar_pixmaps[SND_XPM_UNDO]); case SND_XPM_SAVE: return(toolbar_pixmaps[SND_XPM_SAVE]); case SND_XPM_SAVE_AS: return(toolbar_pixmaps[SND_XPM_SAVE_AS]); case SND_XPM_NEW: return(toolbar_pixmaps[SND_XPM_NEW]); case SND_XPM_OPEN: return(toolbar_pixmaps[SND_XPM_OPEN]); case SND_XPM_NEXT: return(toolbar_pixmaps[SND_XPM_NEXT]); case SND_XPM_BACK: return(toolbar_pixmaps[SND_XPM_BACK]); case SND_XPM_EXIT: return(toolbar_pixmaps[SND_XPM_EXIT]); case SND_XPM_SEPARATOR: return(toolbar_pixmaps[SND_XPM_SEPARATOR]); case SND_XPM_UP: return(toolbar_pixmaps[SND_XPM_UP]); case SND_XPM_STOP: return(toolbar_pixmaps[SND_XPM_STOP]); case SND_XPM_REVERT: return(toolbar_pixmaps[SND_XPM_REVERT]); case SND_XPM_PLAY: return(toolbar_pixmaps[SND_XPM_PLAY]); case SND_XPM_CURSOR_PLAY: return(toolbar_pixmaps[SND_XPM_CURSOR_PLAY]); case SND_XPM_STOP_PLAY: return(toolbar_pixmaps[SND_XPM_STOP_PLAY]); } return(None); } #define NUM_BOMBS 15 void make_icons_transparent(const char *color) { static char *bg1 = NULL; static char *bg4 = NULL; int i; const char **tmp; if (bg1) free(bg1); bg1 = mus_format("- c %s s %s", color, color); /* the background color isn't known at compile time */ mini_lock_xpm[1] = bg1; close_icon_xpm[1] = bg1; stop_sign_xpm[1] = bg1; blank_xpm[1] = bg1; for (i = 0; i < NUM_BOMBS; i++) { tmp = mini_bomb_bits(i); tmp[1] = bg1; } for (i = 0; i < NUM_HOURGLASSES; i++) { tmp = mini_glass_bits(i); tmp[1] = bg1; } if (bg4) free(bg4); bg4 = mus_format(" c %s", color); back_arrow_xpm[1] = bg4; fwd_arrow_xpm[1] = bg4; zoom_in_xpm[1] = bg4; zoom_out_xpm[1] = bg4; cut_xpm[1] = bg4; paste_xpm[1] = bg4; preferences_xpm[1] = bg4; close_xpm[1] = bg4; redo_xpm[1] = bg4; undo_xpm[1] = bg4; save_xpm[1] = bg4; saveas_xpm[1] = bg4; new_xpm[1] = bg4; open_xpm[1] = bg4; right_arrow_xpm[1] = bg4; left_arrow_xpm[1] = bg4; exit_xpm[1] = bg4; separator_xpm[1] = bg4; up_node2_xpm[1] = bg4; stop_xpm[1] = bg4; home_xpm[1] = bg4; play_xpm[1] = bg4; cursor_play_xpm[1] = bg4; stop_play_xpm[1] = bg4; } #endif #if USE_GTK /* /usr/share/icons/gnome/16x16/status/changes-prevent.png */ static unsigned char lock_data[845] = { 0211, 0120, 0116, 0107, 0015, 0012, 0032, 0012, 0000, 0000, 0000, 0015, 0111, 0110, 0104, 0122, 0000, 0000, 0000, 0020, 0000, 0000, 0000, 0020, 0010, 0006, 0000, 0000, 0000, 0037, 0363, 0377, 0141, 0000, 0000, 0000, 0004, 0163, 0102, 0111, 0124, 0010, 0010, 0010, 0010, 0174, 0010, 0144, 0210, 0000, 0000, 0000, 0011, 0160, 0110, 0131, 0163, 0000, 0000, 0015, 0327, 0000, 0000, 0015, 0327, 0001, 0102, 0050, 0233, 0170, 0000, 0000, 0000, 0031, 0164, 0105, 0130, 0164, 0123, 0157, 0146, 0164, 0167, 0141, 0162, 0145, 0000, 0167, 0167, 0167, 0056, 0151, 0156, 0153, 0163, 0143, 0141, 0160, 0145, 0056, 0157, 0162, 0147, 0233, 0356, 0074, 0032, 0000, 0000, 0000, 0023, 0164, 0105, 0130, 0164, 0124, 0151, 0164, 0154, 0145, 0000, 0117, 0160, 0164, 0151, 0143, 0141, 0154, 0040, 0104, 0162, 0151, 0166, 0145, 0076, 0147, 0272, 0014, 0000, 0000, 0000, 0026, 0164, 0105, 0130, 0164, 0101, 0165, 0164, 0150, 0157, 0162, 0000, 0114, 0141, 0160, 0157, 0040, 0103, 0141, 0154, 0155, 0141, 0156, 0144, 0162, 0145, 0151, 0267, 0216, 0123, 0046, 0000, 0000, 0000, 0043, 0164, 0105, 0130, 0164, 0123, 0157, 0165, 0162, 0143, 0145, 0000, 0150, 0164, 0164, 0160, 0072, 0057, 0057, 0164, 0141, 0156, 0147, 0157, 0056, 0146, 0162, 0145, 0145, 0144, 0145, 0163, 0153, 0164, 0157, 0160, 0056, 0157, 0162, 0147, 0175, 0262, 0214, 0247, 0000, 0000, 0002, 0132, 0111, 0104, 0101, 0124, 0070, 0215, 0225, 0123, 0317, 0113, 0124, 0121, 0030, 0075, 0367, 0307, 0233, 0171, 0372, 0306, 0231, 0046, 0053, 0312, 0037, 0040, 0005, 0115, 0116, 0105, 0144, 0201, 0324, 0037, 0120, 0020, 0101, 0104, 0033, 0167, 0105, 0320, 0274, 0300, 0105, 0320, 0246, 0331, 0230, 0030, 0021, 0043, 0046, 0102, 0213, 0104, 0322, 0126, 0055, 0132, 0271, 0227, 0152, 0025, 0256, 0102, 0112, 0115, 0041, 0261, 0115, 0042, 0051, 0223, 0062, 0063, 0157, 0346, 0275, 0231, 0171, 0357, 0336, 0257, 0315, 0250, 0243, 0102, 0330, 0201, 0263, 0373, 0316, 0341, 0273, 0337, 0071, 0227, 0021, 0021, 0366, 0200, 0015, 0015, 0145, 0356, 0112, 0103, 0074, 0016, 0264, 0072, 0011, 0015, 0041, 0004, 0377, 0345, 0007, 0152, 0042, 0036, 0153, 0036, 0111, 0245, 0122, 0376, 0256, 0341, 0275, 0006, 0303, 0043, 0103, 0237, 0314, 0106, 0263, 0373, 0154, 0262, 0323, 0212, 0106, 0243, 0140, 0034, 0050, 0024, 0034, 0054, 0377, 0130, 0052, 0345, 0362, 0316, 0317, 0142, 0301, 0273, 0324, 0337, 0337, 0037, 0154, 0315, 0313, 0172, 0161, 0146, 0370, 0105, 0052, 0032, 0211, 0164, 0137, 0271, 0332, 0155, 0315, 0317, 0055, 0170, 0233, 0033, 0233, 0112, 0153, 0315, 0342, 0207, 0343, 0164, 0241, 0353, 0142, 0144, 0366, 0333, 0354, 0051, 0200, 0322, 0000, 0236, 0157, 0151, 0170, 0275, 0101, 0110, 0030, 0017, 0222, 0311, 0244, 0365, 0175, 0156, 0261, 0224, 0135, 0317, 0116, 0372, 0025, 0257, 0113, 0007, 0225, 0363, 0331, 0077, 0331, 0361, 0231, 0057, 0063, 0245, 0304, 0231, 0204, 0045, 0270, 0354, 0251, 0327, 0154, 0033, 0330, 0066, 0063, 0224, 0322, 0211, 0246, 0150, 0024, 0371, 0174, 0236, 0134, 0177, 0155, 0320, 0135, 0354, 0133, 0051, 0055, 0364, 0375, 0016, 0066, 0346, 0063, 0216, 0343, 0204, 0042, 0226, 0005, 0202, 0356, 0260, 0155, 0146, 0354, 0062, 0030, 0110, 0261, 0173, 0255, 0234, 0273, 0104, 0101, 0223, 0224, 0022, 0201, 0137, 0215, 0140, 0145, 0354, 0053, 0157, 0014, 0027, 0105, 0143, 0270, 0250, 0162, 0223, 0253, 0132, 0005, 0206, 0326, 0004, 0220, 0266, 0132, 0030, 0367, 0236, 0075, 0144, 0217, 0166, 0156, 0300, 0060, 0232, 0036, 0034, 0227, 0257, 0306, 0327, 0241, 0124, 0000, 0115, 0200, 0235, 0176, 0043, 0314, 0160, 0030, 0206, 0041, 0121, 0056, 0373, 0170, 0373, 0176, 0031, 0225, 0152, 0031, 0134, 0110, 0074, 0311, 0114, 0210, 0301, 0364, 0375, 0227, 0266, 0315, 0136, 0163, 0000, 0040, 0100, 0206, 0314, 0004, 0072, 0332, 0343, 0370, 0060, 0365, 0021, 0307, 0216, 0206, 0041, 0215, 0103, 0340, 0062, 0006, 0056, 0143, 0020, 0106, 0014, 0155, 0307, 0243, 0230, 0376, 0074, 0215, 0366, 0226, 0006, 0230, 0326, 0071, 0110, 0021, 0142, 0055, 0125, 0210, 0355, 0024, 0064, 0105, 0160, 0347, 0366, 0065, 0200, 0231, 0000, 0371, 0120, 0312, 0007, 0100, 0040, 0322, 0010, 0163, 0215, 0133, 0067, 0133, 0241, 0211, 0300, 0030, 0301, 0055, 0255, 0042, 0010, 0374, 0335, 0061, 0372, 0336, 0034, 0230, 0077, 0005, 0243, 0341, 0062, 0312, 0356, 0052, 0112, 0205, 0045, 0270, 0136, 0016, 0236, 0353, 0154, 0323, 0365, 0012, 0320, 0312, 0305, 0351, 0316, 0033, 0373, 0123, 0040, 0000, 0014, 0254, 0126, 0057, 0016, 0060, 0206, 0203, 0140, 0247, 0007, 0244, 0016, 0044, 0370, 0207, 0101, 0025, 0373, 0176, 0305, 0377, 0030, 0020, 0005, 0000, 0152, 0133, 0120, 0000, 0020, 0253, 0075, 0145, 0207, 0254, 0306, 0172, 0154, 0365, 0040, 0160, 0066, 0027, 0144, 0363, 0211, 0353, 0200, 0074, 0002, 0156, 0306, 0021, 0246, 0066, 0040, 0124, 0200, 0010, 0345, 0140, 0230, 0016, 0114, 0313, 0103, 0103, 0305, 0005, 0351, 0012, 0212, 0205, 0015, 0150, 0150, 0132, 0013, 0101, 0061, 0042, 0302, 0100, 0212, 0365, 0050, 0340, 0035, 0010, 0342, 0040, 0153, 0063, 0006, 0045, 0004, 0172, 0237, 0216, 0322, 0330, 0137, 0070, 0154, 0010, 0037, 0320, 0076, 0105, 0075, 0000, 0000, 0000, 0000, 0111, 0105, 0116, 0104, 0256, 0102, 0140, 0202}; /* /usr/share/icons/gnome/16x16/actions/stop.png */ static unsigned char stop_data[664] = { 0211, 0120, 0116, 0107, 0015, 0012, 0032, 0012, 0000, 0000, 0000, 0015, 0111, 0110, 0104, 0122, 0000, 0000, 0000, 0020, 0000, 0000, 0000, 0020, 0010, 0006, 0000, 0000, 0000, 0037, 0363, 0377, 0141, 0000, 0000, 0000, 0004, 0163, 0102, 0111, 0124, 0010, 0010, 0010, 0010, 0174, 0010, 0144, 0210, 0000, 0000, 0000, 0011, 0160, 0110, 0131, 0163, 0000, 0000, 0015, 0327, 0000, 0000, 0015, 0327, 0001, 0102, 0050, 0233, 0170, 0000, 0000, 0000, 0031, 0164, 0105, 0130, 0164, 0123, 0157, 0146, 0164, 0167, 0141, 0162, 0145, 0000, 0167, 0167, 0167, 0056, 0151, 0156, 0153, 0163, 0143, 0141, 0160, 0145, 0056, 0157, 0162, 0147, 0233, 0356, 0074, 0032, 0000, 0000, 0000, 0023, 0164, 0105, 0130, 0164, 0124, 0151, 0164, 0154, 0145, 0000, 0117, 0160, 0164, 0151, 0143, 0141, 0154, 0040, 0104, 0162, 0151, 0166, 0145, 0076, 0147, 0272, 0014, 0000, 0000, 0001, 0366, 0111, 0104, 0101, 0124, 0070, 0215, 0255, 0323, 0075, 0113, 0133, 0121, 0030, 0007, 0360, 0377, 0163, 0316, 0211, 0046, 0067, 0157, 0213, 0203, 0120, 0244, 0275, 0122, 0024, 0132, 0154, 0213, 0012, 0035, 0274, 0245, 0111, 0276, 0205, 0004, 0164, 0250, 0366, 0053, 0070, 0165, 0312, 0224, 0017, 0241, 0240, 0040, 0116, 0165, 0353, 0032, 0245, 0352, 0046, 0016, 0015, 0035, 0264, 0045, 0267, 0064, 0264, 0103, 0307, 0244, 0001, 0223, 0363, 0362, 0164, 0310, 0275, 0061, 0057, 0155, 0207, 0322, 0077, 0234, 0345, 0302, 0363, 0273, 0347, 0171, 0316, 0071, 0304, 0314, 0210, 0123, 0255, 0126, 0226, 0204, 0232, 0272, 0160, 0316, 0146, 0061, 0026, 0051, 0105, 0313, 0152, 0035, 0354, 0354, 0274, 0251, 0017, 0177, 0247, 0030, 0250, 0126, 0053, 0113, 0052, 0061, 0175, 0126, 0054, 0224, 0162, 0276, 0357, 0323, 0070, 0020, 0206, 0041, 0237, 0234, 0326, 0132, 0106, 0167, 0137, 0014, 0043, 0304, 0314, 0043, 0305, 0351, 0353, 0033, 0272, 0332, 0330, 0204, 0063, 0346, 0356, 0057, 0112, 0141, 0365, 0350, 0020, 0077, 0347, 0347, 0047, 0020, 0231, 0112, 0311, 0273, 0342, 0117, 0237, 0251, 0276, 0375, 0032, 0317, 0147, 0147, 0361, 0150, 0146, 0006, 0367, 0263, 0131, 0314, 0245, 0323, 0310, 0013, 0201, 0217, 0157, 0217, 0061, 0027, 0004, 0164, 0157, 0145, 0145, 0372, 0153, 0263, 0131, 0076, 0173, 0137, 0173, 0027, 0004, 0057, 0177, 0010, 0231, 0110, 0234, 0027, 0013, 0245, 0134, 0246, 0321, 0240, 0372, 0326, 0066, 0236, 0345, 0363, 0310, 0050, 0005, 0347, 0034, 0230, 0031, 0314, 0214, 0264, 0224, 0170, 0110, 0204, 0017, 0257, 0266, 0220, 0276, 0276, 0241, 0142, 0241, 0224, 0023, 0152, 0352, 0002, 0000, 0204, 0265, 0056, 0347, 0373, 0076, 0135, 0256, 0227, 0361, 0330, 0363, 0340, 0111, 0011, 0255, 0065, 0214, 0326, 0160, 0326, 0366, 0041, 0347, 0340, 0011, 0201, 0007, 0306, 0340, 0152, 0143, 0023, 0276, 0357, 0123, 0074, 0150, 0025, 0367, 0311, 0306, 0040, 0105, 0004, 0243, 0065, 0010, 0000, 0063, 0303, 0071, 0007, 0153, 0055, 0254, 0265, 0160, 0326, 0042, 0011, 0214, 0314, 0146, 0004, 0000, 0000, 0243, 0065, 0004, 0021, 0100, 0064, 0330, 0276, 0213, 0200, 0030, 0031, 0317, 0004, 0100, 0021, 0200, 0030, 0160, 0256, 0217, 0030, 0003, 0373, 0067, 0100, 0050, 0205, 0166, 0267, 0213, 0224, 0224, 0375, 0026, 0242, 0066, 0070, 0006, 0254, 0305, 0155, 0164, 0244, 0303, 0021, 0102, 0310, 0166, 0030, 0206, 0274, 0174, 0260, 0217, 0057, 0021, 0242, 0265, 0206, 0351, 0365, 0372, 0113, 0353, 0101, 0361, 0067, 0317, 0303, 0352, 0321, 0041, 0302, 0060, 0144, 0051, 0105, 0013, 0000, 0204, 0063, 0275, 0265, 0223, 0323, 0132, 0253, 0263, 0270, 0300, 0117, 0366, 0166, 0321, 0114, 0046, 0321, 0211, 0266, 0033, 0037, 0345, 0055, 0200, 0357, 0236, 0207, 0247, 0173, 0273, 0203, 0313, 0144, 0265, 0016, 0176, 0173, 0023, 0063, 0215, 0006, 0135, 0256, 0227, 0301, 0103, 0323, 0026, 0112, 0141, 0371, 0140, 0037, 0235, 0305, 0205, 0211, 0233, 0370, 0177, 0336, 0102, 0234, 0152, 0265, 0262, 0044, 0023, 0211, 0163, 0153, 0135, 0156, 0034, 0020, 0102, 0266, 0235, 0351, 0255, 0375, 0361, 0065, 0376, 0153, 0176, 0001, 0260, 0151, 0115, 0356, 0212, 0245, 0300, 0236, 0000, 0000, 0000, 0000, 0111, 0105, 0116, 0104, 0256, 0102, 0140, 0202}; /* /usr/share/icons/gnome/16x16/status/audio-volume-medium.png */ static unsigned char speaker_data[709] = { 0211, 0120, 0116, 0107, 0015, 0012, 0032, 0012, 0000, 0000, 0000, 0015, 0111, 0110, 0104, 0122, 0000, 0000, 0000, 0020, 0000, 0000, 0000, 0020, 0010, 0006, 0000, 0000, 0000, 0037, 0363, 0377, 0141, 0000, 0000, 0000, 0004, 0163, 0102, 0111, 0124, 0010, 0010, 0010, 0010, 0174, 0010, 0144, 0210, 0000, 0000, 0000, 0011, 0160, 0110, 0131, 0163, 0000, 0000, 0015, 0327, 0000, 0000, 0015, 0327, 0001, 0102, 0050, 0233, 0170, 0000, 0000, 0000, 0031, 0164, 0105, 0130, 0164, 0123, 0157, 0146, 0164, 0167, 0141, 0162, 0145, 0000, 0167, 0167, 0167, 0056, 0151, 0156, 0153, 0163, 0143, 0141, 0160, 0145, 0056, 0157, 0162, 0147, 0233, 0356, 0074, 0032, 0000, 0000, 0002, 0102, 0111, 0104, 0101, 0124, 0070, 0215, 0245, 0223, 0121, 0110, 0123, 0121, 0034, 0306, 0277, 0273, 0173, 0266, 0353, 0346, 0326, 0234, 0256, 0034, 0065, 0163, 0054, 0103, 0222, 0234, 0071, 0067, 0326, 0130, 0057, 0076, 0011, 0215, 0105, 0010, 0021, 0004, 0126, 0220, 0017, 0265, 0300, 0325, 0154, 0303, 0352, 0251, 0007, 0261, 0007, 0173, 0212, 0036, 0043, 0044, 0010, 0021, 0174, 0021, 0045, 0207, 0214, 0211, 0046, 0124, 0232, 0212, 0271, 0302, 0207, 0044, 0020, 0264, 0061, 0357, 0066, 0247, 0273, 0167, 0153, 0133, 0247, 0007, 0141, 0154, 0266, 0010, 0362, 0300, 0377, 0345, 0073, 0037, 0077, 0176, 0374, 0071, 0207, 0241, 0224, 0342, 0060, 0107, 0122, 0056, 0274, 0357, 0277, 0343, 0360, 0075, 0352, 0231, 0374, 0057, 0300, 0075, 0237, 0333, 0044, 0223, 0162, 0157, 0163, 0331, 0134, 0107, 0161, 0156, 0164, 0366, 0327, 0377, 0023, 0340, 0365, 0272, 0215, 0122, 0102, 0246, 0335, 0267, 0075, 0252, 0342, 0274, 0361, 0322, 0063, 0055, 0005, 0073, 0157, 0160, 0015, 0330, 0377, 0012, 0360, 0373, 0357, 0352, 0130, 0216, 0314, 0335, 0350, 0272, 0245, 0326, 0037, 0257, 0103, 0145, 0245, 0262, 0120, 0132, 0033, 0353, 0335, 0146, 0030, 0111, 0067, 0107, 0144, 0243, 0015, 0235, 0203, 0307, 0212, 0001, 0304, 0367, 0320, 0063, 0233, 0317, 0347, 0317, 0023, 0102, 0162, 0227, 0135, 0235, 0122, 0103, 0275, 0121, 0302, 0262, 0004, 0255, 0055, 0155, 0000, 0000, 0303, 0305, 0247, 0275, 0171, 0066, 0077, 0274, 0061, 0376, 0170, 0314, 0336, 0375, 0362, 0212, 0204, 0260, 0127, 0001, 0074, 0057, 0030, 0244, 0063, 0331, 0013, 0136, 0117, 0037, 0021, 0323, 0331, 0012, 0163, 0253, 0225, 0345, 0371, 0030, 0050, 0245, 0130, 0136, 0131, 0332, 0057, 0060, 0214, 0234, 0344, 0045, 0203, 0000, 0240, 0321, 0250, 0106, 0152, 0252, 0325, 0256, 0022, 0203, 0346, 0246, 0026, 0350, 0117, 0350, 0321, 0334, 0324, 0202, 0150, 0064, 0202, 0371, 0305, 0217, 0070, 0252, 0255, 0101, 0064, 0032, 0005, 0000, 0150, 0153, 0125, 0103, 0232, 0052, 0355, 0002, 0000, 0050, 0225, 0352, 0071, 0271, 0102, 0366, 0272, 0144, 0007, 0123, 0301, 0040, 0302, 0341, 0060, 0246, 0202, 0101, 0174, 0135, 0373, 0202, 0365, 0157, 0353, 0110, 0011, 0002, 0104, 0061, 0015, 0000, 0320, 0310, 0253, 0241, 0077, 0251, 0223, 0000, 0200, 0102, 0041, 0325, 0250, 0224, 0212, 0130, 0211, 0301, 0346, 0126, 0004, 0201, 0100, 0000, 0233, 0133, 0021, 0034, 0121, 0126, 0201, 0347, 0171, 0044, 0223, 0111, 0010, 0102, 0006, 0000, 0260, 0275, 0227, 0354, 0142, 0066, 0330, 0020, 0000, 0144, 0062, 0077, 0353, 0050, 0150, 0244, 0004, 0040, 0212, 0231, 0205, 0241, 0067, 0303, 0226, 0012, 0071, 0227, 0231, 0171, 0067, 0313, 0312, 0010, 0107, 0142, 0074, 0137, 0060, 0340, 0371, 0030, 0223, 0210, 0307, 0037, 0000, 0100, 0042, 0276, 0333, 0043, 0345, 0310, 0150, 0011, 0140, 0361, 0303, 0173, 0053, 0000, 0264, 0073, 0235, 0272, 0320, 0364, 0314, 0322, 0231, 0306, 0323, 0265, 0051, 0041, 0305, 0010, 0342, 0276, 0301, 0367, 0361, 0276, 0176, 0000, 0260, 0134, 0177, 0141, 0043, 0122, 0316, 0042, 0377, 0105, 0256, 0225, 0175, 0007, 0241, 0211, 0211, 0037, 0251, 0235, 0135, 0307, 0247, 0345, 0317, 0211, 0225, 0325, 0125, 0052, 0010, 0351, 0102, 0351, 0154, 0373, 0023, 0145, 0054, 0266, 0067, 0222, 0340, 0167, 0274, 0241, 0127, 0067, 0323, 0305, 0000, 0120, 0112, 0113, 0306, 0154, 0263, 0231, 0054, 0166, 0173, 0322, 0324, 0146, 0245, 0305, 0371, 0251, 0216, 0201, 0206, 0203, 0135, 0112, 0351, 0237, 0000, 0112, 0051, 0316, 0131, 0054, 0016, 0263, 0315, 0076, 0131, 0356, 0356, 0340, 0060, 0207, 0375, 0316, 0277, 0001, 0307, 0174, 0034, 0051, 0156, 0365, 0066, 0020, 0000, 0000, 0000, 0000, 0111, 0105, 0116, 0104, 0256, 0102, 0140, 0202}; /* /usr/share/icons/oxygen/16x16/status/dialog-warning.png */ static unsigned char bomb_data[596] = { 0211, 0120, 0116, 0107, 0015, 0012, 0032, 0012, 0000, 0000, 0000, 0015, 0111, 0110, 0104, 0122, 0000, 0000, 0000, 0020, 0000, 0000, 0000, 0020, 0010, 0006, 0000, 0000, 0000, 0037, 0363, 0377, 0141, 0000, 0000, 0000, 0004, 0163, 0102, 0111, 0124, 0010, 0010, 0010, 0010, 0174, 0010, 0144, 0210, 0000, 0000, 0000, 0011, 0160, 0110, 0131, 0163, 0000, 0000, 0001, 0273, 0000, 0000, 0001, 0273, 0001, 0072, 0354, 0343, 0342, 0000, 0000, 0000, 0031, 0164, 0105, 0130, 0164, 0123, 0157, 0146, 0164, 0167, 0141, 0162, 0145, 0000, 0167, 0167, 0167, 0056, 0151, 0156, 0153, 0163, 0143, 0141, 0160, 0145, 0056, 0157, 0162, 0147, 0233, 0356, 0074, 0032, 0000, 0000, 0001, 0321, 0111, 0104, 0101, 0124, 0170, 0332, 0245, 0222, 0275, 0153, 0123, 0121, 0030, 0207, 0237, 0367, 0334, 0357, 0336, 0336, 0174, 0124, 0323, 0350, 0140, 0205, 0024, 0127, 0035, 0072, 0166, 0120, 0212, 0372, 0007, 0050, 0342, 0242, 0213, 0272, 0110, 0121, 0227, 0342, 0042, 0024, 0034, 0265, 0010, 0132, 0024, 0104, 0161, 0322, 0105, 0161, 0020, 0203, 0330, 0072, 0364, 0057, 0350, 0052, 0124, 0021, 0007, 0151, 0051, 0105, 0152, 0022, 0233, 0064, 0311, 0375, 0310, 0021, 0162, 0301, 0273, 0330, 0264, 0322, 0007, 0176, 0160, 0016, 0234, 0363, 0360, 0173, 0017, 0107, 0264, 0326, 0354, 0007, 0305, 0000, 0242, 0252, 0175, 0065, 0171, 0357, 0134, 0140, 0020, 0132, 0353, 0177, 0046, 0136, 0264, 0056, 0106, 0213, 0247, 0172, 0321, 0322, 0071, 0335, 0135, 0260, 0056, 0355, 0164, 0116, 0355, 0050, 0016, 0335, 0207, 0346, 0330, 0264, 0030, 0245, 0363, 0310, 0266, 0375, 0340, 0277, 0106, 0350, 0175, 0062, 0246, 0305, 0077, 0163, 0010, 0303, 0100, 0014, 0120, 0301, 0311, 0321, 0350, 0243, 0175, 0153, 0317, 0202, 0044, 0366, 0357, 0032, 0007, 0047, 0131, 0176, 0162, 0237, 0345, 0247, 0217, 0120, 0205, 0343, 0350, 0330, 0234, 0335, 0223, 0040, 0136, 0260, 0356, 0310, 0360, 0344, 0001, 0330, 0242, 0261, 0362, 0225, 0306, 0227, 0157, 0210, 0324, 0120, 0376, 0211, 0221, 0360, 0203, 0065, 0273, 0273, 0040, 0011, 0156, 0033, 0305, 0012, 0260, 0206, 0243, 0244, 0037, 0324, 0052, 0106, 0056, 0240, 0027, 0173, 0063, 0003, 0005, 0235, 0252, 0272, 0147, 0004, 0225, 0234, 0030, 0353, 0140, 0156, 0342, 0005, 0171, 0374, 0221, 0121, 0160, 0132, 0210, 0327, 0104, 0025, 0307, 0202, 0366, 0073, 0065, 0007, 0031, 0331, 0107, 0172, 0046, 0126, 0253, 0350, 0066, 0206, 0216, 0046, 0236, 0130, 0021, 0030, 0360, 0375, 0125, 0011, 0235, 0204, 0214, 0137, 0153, 0200, 0200, 0116, 0034, 0232, 0237, 0165, 0073, 0030, 0017, 0363, 0114, 0350, 0010, 0300, 0204, 0224, 0346, 0220, 0074, 0066, 0013, 0256, 0047, 0371, 0072, 0230, 0364, 0123, 0271, 0361, 0063, 0355, 0050, 0364, 0221, 0136, 0027, 0253, 0134, 0360, 0232, 0053, 0321, 0374, 0360, 0004, 0327, 0263, 0006, 0057, 0305, 0157, 0164, 0162, 0265, 0334, 0124, 0333, 0022, 0067, 0112, 0005, 0026, 0254, 0317, 0027, 0000, 0070, 0074, 0123, 0207, 0036, 0020, 0203, 0356, 0172, 0374, 0256, 0112, 0324, 0361, 0266, 0213, 0345, 0313, 0272, 0245, 0000, 0032, 0165, 0136, 0330, 0025, 0057, 0275, 0154, 0003, 0116, 0032, 0023, 0301, 0024, 0001, 0223, 0254, 0205, 0152, 0143, 0037, 0013, 0054, 0267, 0306, 0363, 0277, 0043, 0164, 0327, 0230, 0012, 0316, 0006, 0151, 0335, 0170, 0003, 0064, 0220, 0100, 0351, 0146, 0055, 0135, 0157, 0245, 0173, 0142, 0200, 0062, 0316, 0221, 0074, 0315, 0245, 0315, 0323, 0331, 0033, 0030, 0352, 0355, 0257, 0067, 0077, 0256, 0204, 0253, 0241, 0146, 0127, 0066, 0020, 0267, 0246, 0225, 0037, 0277, 0316, 0336, 0140, 0037, 0374, 0001, 0075, 0255, 0302, 0111, 0346, 0040, 0215, 0173, 0000, 0000, 0000, 0000, 0111, 0105, 0116, 0104, 0256, 0102, 0140, 0202}; #if 0 static unsigned char bomb_data_24[2010] = { 0211, 0120, 0116, 0107, 0015, 0012, 0032, 0012, 0000, 0000, 0000, 0015, 0111, 0110, 0104, 0122, 0000, 0000, 0000, 0030, 0000, 0000, 0000, 0030, 0010, 0006, 0000, 0000, 0000, 0340, 0167, 0075, 0370, 0000, 0000, 0000, 0006, 0142, 0113, 0107, 0104, 0000, 0376, 0000, 0376, 0000, 0376, 0353, 0030, 0324, 0202, 0000, 0000, 0000, 0011, 0160, 0110, 0131, 0163, 0000, 0000, 0015, 0326, 0000, 0000, 0015, 0326, 0001, 0220, 0157, 0171, 0234, 0000, 0000, 0000, 0011, 0166, 0160, 0101, 0147, 0000, 0000, 0000, 0030, 0000, 0000, 0000, 0030, 0000, 0170, 0114, 0245, 0246, 0000, 0000, 0003, 0300, 0111, 0104, 0101, 0124, 0110, 0307, 0265, 0225, 0115, 0150, 0134, 0125, 0030, 0206, 0237, 0163, 0316, 0235, 0073, 0223, 0073, 0223, 0111, 0234, 0144, 0222, 0114, 0046, 0115, 0310, 0044, 0326, 0332, 0304, 0104, 0353, 0137, 0301, 0126, 0254, 0165, 0241, 0124, 0020, 0225, 0210, 0240, 0304, 0240, 0050, 0126, 0011, 0052, 0102, 0177, 0124, 0064, 0320, 0215, 0202, 0042, 0245, 0324, 0212, 0340, 0312, 0215, 0210, 0113, 0105, 0167, 0041, 0065, 0125, 0101, 0233, 0022, 0321, 0032, 0264, 0155, 0114, 0332, 0116, 0232, 0304, 0114, 0376, 0347, 0357, 0336, 0173, 0216, 0213, 0321, 0272, 0150, 0143, 0223, 0246, 0276, 0360, 0155, 0316, 0371, 0316, 0373, 0234, 0157, 0361, 0361, 0302, 0377, 0054, 0261, 0332, 0306, 0305, 0327, 0354, 0267, 0254, 0326, 0235, 0373, 0105, 0054, 0045, 0374, 0343, 0037, 0017, 0073, 0052, 0277, 0125, 0364, 0241, 0257, 0311, 0057, 0262, 0173, 0150, 0310, 0176, 0270, 0075, 0357, 0215, 0016, 0030, 0357, 0217, 0101, 0223, 0373, 0254, 0247, 0260, 0264, 0227, 0047, 0127, 0363, 0126, 0256, 0246, 0311, 0267, 0043, 0357, 0132, 0167, 0074, 0153, 0233, 0314, 0050, 0172, 0154, 0220, 0300, 0315, 0217, 0333, 0204, 0052, 0336, 0067, 0175, 0330, 0353, 0006, 0054, 0354, 0341, 0006, 0253, 0345, 0236, 0207, 0125, 0174, 0223, 0320, 0323, 0043, 0230, 0205, 0064, 0040, 0260, 0266, 0164, 0127, 0054, 0144, 0171, 0141, 0335, 0000, 0023, 0212, 0036, 0016, 0334, 0332, 0035, 0320, 0027, 0176, 0102, 0140, 0020, 0001, 0007, 0075, 0376, 0035, 0126, 0373, 0043, 0001, 0053, 0022, 0077, 0060, 0325, 0107, 0344, 0252, 0001, 0363, 0373, 0270, 0335, 0112, 0335, 0273, 0215, 0160, 0134, 0350, 0364, 0020, 0262, 0152, 0003, 0252, 0261, 0003, 0063, 0067, 0016, 0113, 0223, 0310, 0055, 0117, 0205, 0354, 0054, 0373, 0256, 0032, 0340, 0212, 0350, 0021, 0273, 0375, 0041, 0133, 0217, 0035, 0003, 0343, 0041, 0343, 0315, 0210, 0362, 0132, 0104, 0044, 0206, 0177, 0246, 0237, 0100, 0152, 0273, 0245, 0303, 0211, 0127, 0027, 0173, 0211, 0257, 0031, 0060, 0371, 0012, 0367, 0251, 0226, 0273, 0333, 0261, 0202, 0102, 0247, 0117, 0240, 0152, 0132, 0110, 0117, 0057, 0060, 0236, 0276, 0200, 0111, 0154, 0306, 0054, 0116, 0140, 0376, 0374, 0015, 0273, 0363, 0261, 0300, 0262, 0342, 0300, 0232, 0000, 0006, 0204, 0253, 0312, 0217, 0224, 0155, 0334, 0021, 0324, 0243, 0003, 0010, 0051, 0220, 0325, 0115, 0034, 0376, 0364, 0033, 0366, 0037, 0374, 0002, 0337, 0166, 0020, 0225, 0011, 0374, 0321, 0243, 0330, 0311, 0016, 0245, 0243, 0015, 0075, 0351, 0027, 0151, 0132, 0065, 0140, 0274, 0227, 0107, 0355, 0346, 0255, 0015, 0322, 0270, 0350, 0311, 0223, 0310, 0344, 0046, 0060, 0105, 0052, 0034, 0211, 0205, 0117, 0110, 0272, 0130, 0015, 0155, 0230, 0334, 0014, 0146, 0342, 0004, 0221, 0366, 0373, 0255, 0274, 0340, 0275, 0125, 0001, 0114, 0027, 0312, 0227, 0341, 0203, 0221, 0324, 0155, 0041, 0075, 0172, 0024, 0031, 0014, 0042, 0143, 0365, 0030, 0057, 0107, 0165, 0104, 0022, 0055, 0023, 0030, 0057, 0017, 0266, 0215, 0214, 0067, 0241, 0307, 0276, 0045, 0024, 0333, 0240, 0144, 0064, 0271, 0353, 0324, 0363, 0264, 0137, 0021, 0060, 0122, 0311, 0323, 0201, 0144, 0147, 0114, 0345, 0147, 0321, 0063, 0247, 0120, 0015, 0067, 0202, 0237, 0003, 0057, 0107, 0074, 0252, 0210, 0072, 0200, 0237, 0005, 0157, 0031, 0225, 0110, 0141, 0346, 0307, 0361, 0177, 0377, 0232, 0150, 0343, 0346, 0240, 0147, 0070, 0364, 0237, 0200, 0321, 0036, 0102, 0332, 0262, 0337, 0216, 0065, 0156, 0014, 0351, 0261, 0143, 0310, 0160, 0024, 0121, 0131, 0005, 0136, 0016, 0274, 0045, 0232, 0253, 0064, 0101, 0177, 0036, 0226, 0322, 0260, 0174, 0036, 0241, 0263, 0250, 0372, 0024, 0372, 0334, 0017, 0070, 0321, 0353, 0204, 0050, 0253, 0272, 0363, 0347, 0147, 0270, 0153, 0105, 0300, 0054, 0274, 0344, 0324, 0266, 0224, 0311, 0345, 0363, 0230, 0271, 0061, 0124, 0175, 0013, 0046, 0077, 0003, 0271, 0111, 0130, 0236, 0244, 0055, 0141, 0330, 0275, 0253, 0261, 0064, 0221, 0357, 0202, 0056, 0042, 0233, 0072, 0020, 0226, 0205, 0116, 0017, 0021, 0157, 0155, 0013, 0271, 0206, 0017, 0056, 0013, 0370, 0361, 0071, 0052, 0214, 0120, 0157, 0124, 0045, 0022, 0145, 0346, 0354, 0367, 0210, 0110, 0024, 0021, 0166, 0300, 0315, 0142, 0274, 0074, 0106, 0027, 0171, 0140, 0357, 0127, 0354, 0170, 0371, 0113, 0062, 0163, 0113, 0030, 0135, 0304, 0150, 0027, 0041, 0101, 0065, 0167, 0142, 0062, 0247, 0161, 0202, 0122, 0250, 0160, 0374, 0372, 0343, 0335, 0074, 0170, 0011, 0300, 0313, 0362, 0172, 0171, 0115, 0062, 0020, 0130, 0236, 0300, 0024, 0027, 0261, 0122, 0067, 0201, 0166, 0057, 0226, 0361, 0135, 0026, 0263, 0245, 0362, 0375, 0142, 0351, 0334, 0057, 0335, 0251, 0144, 0053, 0042, 0350, 0240, 0047, 0117, 0122, 0337, 0324, 0130, 0346, 0032, 0016, 0231, 0276, 0222, 0267, 0005, 0320, 0337, 0105, 0235, 0207, 0352, 0255, 0253, 0213, 0005, 0165, 0346, 0127, 0144, 0145, 0015, 0302, 0011, 0227, 0114, 0204, 0004, 0041, 0021, 0010, 0372, 0337, 0331, 0106, 0321, 0323, 0070, 0101, 0001, 0176, 0261, 0264, 0061, 0106, 0203, 0321, 0310, 0144, 0053, 0376, 0351, 0141, 0302, 0221, 0070, 0301, 0362, 0130, 0315, 0340, 0110, 0346, 0011, 0340, 0023, 0013, 0300, 0207, 0335, 0065, 0261, 0162, 0151, 0025, 0146, 0060, 0136, 0001, 0075, 0073, 0105, 0141, 0340, 0363, 0313, 0156, 0246, 0002, 0012, 0254, 0054, 0263, 0220, 0046, 0131, 0023, 0166, 0176, 0231, 0311, 0274, 0171, 0021, 0260, 0120, 0040, 0222, 0020, 0312, 0106, 0052, 0104, 0105, 0003, 0030, 0303, 0125, 0113, 0052, 0334, 0371, 0002, 0256, 0056, 0145, 0205, 0005, 0060, 0064, 0305, 0200, 0045, 0147, 0272, 0306, 0317, 0146, 0352, 0244, 0224, 0172, 0015, 0111, 0172, 0351, 0004, 0332, 0107, 0033, 0123, 0030, 0236, 0346, 0043, 0370, 0327, 0251, 0072, 0000, 0055, 0267, 0324, 0022, 0227, 0152, 0035, 0356, 0177, 0153, 0044, 0303, 0374, 0134, 0236, 0163, 0300, 0231, 0177, 0314, 0002, 0100, 0045, 0134, 0071, 0002, 0127, 0051, 0037, 0230, 0007, 0162, 0327, 0310, 0157, 0145, 0375, 0005, 0324, 0210, 0175, 0376, 0216, 0127, 0307, 0103, 0000, 0000, 0000, 0045, 0164, 0105, 0130, 0164, 0144, 0141, 0164, 0145, 0072, 0143, 0162, 0145, 0141, 0164, 0145, 0000, 0062, 0060, 0060, 0071, 0055, 0061, 0061, 0055, 0062, 0063, 0124, 0061, 0065, 0072, 0065, 0067, 0072, 0061, 0071, 0053, 0060, 0061, 0072, 0060, 0060, 0362, 0065, 0257, 0206, 0000, 0000, 0000, 0045, 0164, 0105, 0130, 0164, 0144, 0141, 0164, 0145, 0072, 0155, 0157, 0144, 0151, 0146, 0171, 0000, 0062, 0060, 0060, 0071, 0055, 0061, 0061, 0055, 0062, 0063, 0124, 0061, 0065, 0072, 0065, 0067, 0072, 0061, 0071, 0053, 0060, 0061, 0072, 0060, 0060, 0203, 0150, 0027, 0072, 0000, 0000, 0000, 0031, 0164, 0105, 0130, 0164, 0123, 0157, 0146, 0164, 0167, 0141, 0162, 0145, 0000, 0167, 0167, 0167, 0056, 0151, 0156, 0153, 0163, 0143, 0141, 0160, 0145, 0056, 0157, 0162, 0147, 0233, 0356, 0074, 0032, 0000, 0000, 0000, 0000, 0111, 0105, 0116, 0104, 0256, 0102, 0140, 0202}; #endif /* /usr/share/icons/gnome/16x16/actions/go-next.png */ static unsigned char right_arrow_data[641] = { 0211, 0120, 0116, 0107, 0015, 0012, 0032, 0012, 0000, 0000, 0000, 0015, 0111, 0110, 0104, 0122, 0000, 0000, 0000, 0020, 0000, 0000, 0000, 0020, 0010, 0006, 0000, 0000, 0000, 0037, 0363, 0377, 0141, 0000, 0000, 0000, 0004, 0163, 0102, 0111, 0124, 0010, 0010, 0010, 0010, 0174, 0010, 0144, 0210, 0000, 0000, 0000, 0011, 0160, 0110, 0131, 0163, 0000, 0000, 0015, 0327, 0000, 0000, 0015, 0327, 0001, 0102, 0050, 0233, 0170, 0000, 0000, 0000, 0031, 0164, 0105, 0130, 0164, 0123, 0157, 0146, 0164, 0167, 0141, 0162, 0145, 0000, 0167, 0167, 0167, 0056, 0151, 0156, 0153, 0163, 0143, 0141, 0160, 0145, 0056, 0157, 0162, 0147, 0233, 0356, 0074, 0032, 0000, 0000, 0000, 0023, 0164, 0105, 0130, 0164, 0124, 0151, 0164, 0154, 0145, 0000, 0117, 0160, 0164, 0151, 0143, 0141, 0154, 0040, 0104, 0162, 0151, 0166, 0145, 0076, 0147, 0272, 0014, 0000, 0000, 0001, 0337, 0111, 0104, 0101, 0124, 0070, 0215, 0225, 0223, 0115, 0117, 0023, 0121, 0024, 0206, 0337, 0371, 0052, 0244, 0123, 0326, 0044, 0044, 0376, 0013, 0067, 0166, 0341, 0326, 0030, 0115, 0014, 0311, 0135, 0130, 0100, 0124, 0242, 0321, 0040, 0215, 0330, 0301, 0231, 0164, 0054, 0024, 0010, 0026, 0246, 0261, 0222, 0206, 0220, 0360, 0141, 0232, 0252, 0213, 0156, 0272, 0102, 0211, 0155, 0360, 0167, 0230, 0052, 0020, 0304, 0064, 0272, 0223, 0224, 0151, 0321, 0351, 0235, 0341, 0270, 0122, 0011, 0231, 0051, 0172, 0222, 0273, 0170, 0223, 0347, 0175, 0026, 0047, 0347, 0012, 0104, 0004, 0277, 0261, 0254, 0247, 0121, 0210, 0102, 0036, 0204, 0043, 0020, 0062, 0206, 0141, 0126, 0375, 0070, 0321, 0267, 0015, 0200, 0104, 0141, 0341, 0312, 0345, 0253, 0347, 0357, 0336, 0271, 0167, 0121, 0355, 0211, 0274, 0315, 0146, 0347, 0331, 0177, 0011, 0004, 0102, 0157, 0250, 0053, 0204, 0110, 0244, 0007, 0267, 0157, 0216, 0310, 0341, 0210, 0132, 0362, 0223, 0004, 0012, 0040, 0042, 0121, 0251, 0126, 0334, 0257, 0337, 0352, 0120, 0224, 0120, 0240, 0044, 0120, 0140, 0114, 0230, 0233, 0077, 0217, 0176, 0304, 0066, 0336, 0154, 0164, 0226, 0020, 0121, 0307, 0147, 0131, 0031, 0226, 0137, 0132, 0344, 0173, 0237, 0167, 0311, 0161, 0034, 0152, 0066, 0155, 0132, 0132, 0316, 0163, 0313, 0312, 0060, 0042, 0202, 0100, 0104, 0130, 0314, 0347, 0146, 0074, 0317, 0323, 0044, 0111, 0312, 0075, 0172, 0250, 0245, 0117, 0347, 0271, 0371, 0031, 0246, 0206, 0325, 0122, 0377, 0265, 0176, 0271, 0257, 0357, 0034, 0070, 0157, 0343, 0105, 0141, 0315, 0155, 0331, 0255, 0101, 0021, 0000, 0074, 0317, 0323, 0046, 0022, 0272, 0352, 0171, 0236, 0346, 0227, 0123, 0311, 0164, 0371, 0260, 0321, 0130, 0256, 0124, 0337, 0001, 0000, 0024, 0045, 0204, 0350, 0205, 0250, 0314, 0335, 0366, 0053, 0021, 0000, 0044, 0111, 0312, 0075, 0173, 0236, 0155, 0111, 0222, 0224, 0363, 0313, 0346, 0244, 0301, 0272, 0272, 0273, 0037, 0014, 0015, 0336, 0002, 0000, 0324, 0353, 0137, 0260, 0365, 0176, 0313, 0155, 0273, 0174, 0370, 0314, 0035, 0350, 0272, 0306, 0146, 0347, 0246, 0271, 0155, 0037, 0222, 0343, 0070, 0264, 0263, 0373, 0211, 0246, 0147, 0247, 0270, 0256, 0153, 0214, 0210, 0072, 0057, 0161, 0134, 0213, 0263, 0251, 0164, 0352, 0157, 0171, 0347, 0043, 0245, 0046, 0115, 0076, 0256, 0305, 0331, 0157, 0046, 0260, 0074, 0066, 0166, 0377, 0122, 0362, 0211, 0361, 0247, 0274, 0275, 0135, 0043, 0043, 0371, 0230, 0217, 0306, 0107, 0331, 0111, 0116, 0016, 0272, 0203, 0266, 0353, 0232, 0003, 0327, 0007, 0144, 0105, 0121, 0260, 0277, 0277, 0207, 0325, 0265, 0125, 0267, 0151, 0333, 0261, 0225, 0225, 0365, 0362, 0111, 0056, 0120, 0300, 0071, 0017, 0177, 0077, 0070, 0100, 0255, 0366, 0001, 0205, 0142, 0321, 0265, 0233, 0215, 0130, 0141, 0375, 0145, 0371, 0064, 0047, 0004, 0375, 0306, 0033, 0043, 0261, 0250, 0160, 0054, 0054, 0000, 0102, 0057, 0341, 0070, 0361, 0272, 0130, 0332, 0364, 0343, 0002, 0005, 0377, 0072, 0277, 0000, 0342, 0107, 0151, 0320, 0260, 0266, 0113, 0201, 0000, 0000, 0000, 0000, 0111, 0105, 0116, 0104, 0256, 0102, 0140, 0202}; /* /usr/share/icons/gnome/16x16/actions/go-previous.png */ static unsigned char left_arrow_data[677] = { 0211, 0120, 0116, 0107, 0015, 0012, 0032, 0012, 0000, 0000, 0000, 0015, 0111, 0110, 0104, 0122, 0000, 0000, 0000, 0020, 0000, 0000, 0000, 0020, 0010, 0006, 0000, 0000, 0000, 0037, 0363, 0377, 0141, 0000, 0000, 0000, 0004, 0163, 0102, 0111, 0124, 0010, 0010, 0010, 0010, 0174, 0010, 0144, 0210, 0000, 0000, 0000, 0011, 0160, 0110, 0131, 0163, 0000, 0000, 0015, 0327, 0000, 0000, 0015, 0327, 0001, 0102, 0050, 0233, 0170, 0000, 0000, 0000, 0031, 0164, 0105, 0130, 0164, 0123, 0157, 0146, 0164, 0167, 0141, 0162, 0145, 0000, 0167, 0167, 0167, 0056, 0151, 0156, 0153, 0163, 0143, 0141, 0160, 0145, 0056, 0157, 0162, 0147, 0233, 0356, 0074, 0032, 0000, 0000, 0000, 0023, 0164, 0105, 0130, 0164, 0124, 0151, 0164, 0154, 0145, 0000, 0117, 0160, 0164, 0151, 0143, 0141, 0154, 0040, 0104, 0162, 0151, 0166, 0145, 0076, 0147, 0272, 0014, 0000, 0000, 0002, 0003, 0111, 0104, 0101, 0124, 0070, 0215, 0143, 0374, 0377, 0377, 0077, 0003, 0056, 0320, 0331, 0323, 0346, 0315, 0360, 0217, 0241, 0357, 0077, 0043, 0303, 0113, 0306, 0177, 0377, 0053, 0312, 0313, 0253, 0217, 0241, 0253, 0141, 0302, 0245, 0271, 0253, 0253, 0075, 0204, 0233, 0213, 0147, 0103, 0132, 0132, 0206, 0232, 0217, 0247, 0217, 0055, 0003, 0023, 0343, 0104, 0154, 0352, 0130, 0160, 0151, 0346, 0342, 0341, 0136, 0236, 0030, 0237, 0304, 0302, 0312, 0312, 0306, 0300, 0302, 0302, 0314, 0300, 0360, 0237, 0341, 0033, 0066, 0265, 0030, 0056, 0100, 0327, 0374, 0354, 0371, 0023, 0206, 0135, 0173, 0166, 0377, 0141, 0370, 0317, 0320, 0106, 0320, 0000, 0154, 0232, 0067, 0155, 0336, 0364, 0347, 0307, 0267, 0357, 0221, 0345, 0345, 0125, 0073, 0261, 0372, 0365, 0377, 0377, 0377, 0014, 0377, 0377, 0377, 0147, 0350, 0354, 0154, 0013, 0231, 0074, 0165, 0342, 0357, 0057, 0137, 0076, 0377, 0377, 0371, 0363, 0347, 0377, 0373, 0017, 0356, 0376, 0237, 0070, 0271, 0377, 0167, 0147, 0147, 0133, 0010, 0114, 0015, 0066, 0314, 0302, 0300, 0300, 0300, 0320, 0326, 0326, 0034, 0306, 0315, 0313, 0275, 0024, 0156, 0363, 0263, 0307, 0014, 0353, 0067, 0256, 0377, 0363, 0365, 0333, 0327, 0310, 0232, 0312, 0372, 0065, 0375, 0023, 0173, 0033, 0377, 0376, 0375, 0133, 0314, 0314, 0314, 0334, 0133, 0230, 0137, 0134, 0217, 0314, 0147, 0252, 0151, 0255, 0221, 0375, 0375, 0347, 0327, 0042, 0053, 0113, 0053, 0026, 0126, 0126, 0066, 0006, 0006, 0006, 0006, 0206, 0035, 0073, 0267, 0063, 0174, 0372, 0370, 0161, 0152, 0115, 0145, 0375, 0032, 0006, 0006, 0006, 0206, 0277, 0177, 0377, 0026, 0227, 0024, 0225, 0161, 0377, 0375, 0373, 0267, 0030, 0235, 0317, 0174, 0150, 0357, 0241, 0117, 0273, 0367, 0356, 0272, 0365, 0370, 0361, 0343, 0100, 0071, 0131, 0071, 0046, 0076, 0076, 0176, 0006, 0155, 0155, 0135, 0206, 0163, 0347, 0317, 0232, 0154, 0333, 0261, 0365, 0272, 0263, 0223, 0353, 0265, 0223, 0247, 0116, 0260, 0037, 0075, 0166, 0304, 0204, 0231, 0231, 0271, 0327, 0322, 0302, 0352, 0000, 0062, 0037, 0356, 0227, 0262, 0262, 0342, 0220, 0206, 0246, 0272, 0337, 0167, 0356, 0336, 0372, 0377, 0363, 0347, 0317, 0377, 0237, 0077, 0177, 0372, 0337, 0324, 0322, 0360, 0273, 0254, 0254, 0030, 0157, 0030, 0240, 0160, 0012, 0212, 0163, 0103, 0152, 0152, 0253, 0176, 0337, 0271, 0163, 0023, 0156, 0110, 0135, 0175, 0315, 0357, 0202, 0342, 0134, 0234, 0206, 0140, 0010, 0144, 0345, 0146, 0205, 0224, 0127, 0226, 0376, 0276, 0175, 0373, 0006, 0334, 0220, 0312, 0352, 0362, 0337, 0231, 0271, 0231, 0336, 0330, 0014, 0300, 0110, 0110, 0123, 0047, 0115, 0135, 0363, 0341, 0335, 0373, 0310, 0031, 0063, 0147, 0376, 0171, 0370, 0360, 0076, 0003, 0053, 0053, 0053, 0103, 0154, 0164, 0054, 0313, 0337, 0077, 0277, 0373, 0210, 0112, 0211, 0014, 0014, 0014, 0014, 0063, 0146, 0314, 0136, 0363, 0356, 0303, 0333, 0310, 0051, 0323, 0246, 0376, 0271, 0172, 0365, 0062, 0303, 0353, 0067, 0157, 0030, 0176, 0377, 0372, 0375, 0022, 0233, 0132, 0106, 0174, 0271, 0061, 0056, 0056, 0332, 0375, 0077, 0023, 0103, 0025, 0043, 0003, 0003, 0327, 0177, 0246, 0177, 0371, 0213, 0347, 0055, 0307, 0310, 0215, 0170, 0015, 0040, 0006, 0000, 0000, 0004, 0240, 0165, 0354, 0235, 0304, 0333, 0013, 0000, 0000, 0000, 0000, 0111, 0105, 0116, 0104, 0256, 0102, 0140, 0202}; /* /usr/share/gtk-doc/html/libgnomeui/stock_menu_blank.png */ static unsigned char blank_data[253] = { 0211, 0120, 0116, 0107, 0015, 0012, 0032, 0012, 0000, 0000, 0000, 0015, 0111, 0110, 0104, 0122, 0000, 0000, 0000, 0020, 0000, 0000, 0000, 0020, 0010, 0002, 0000, 0000, 0000, 0220, 0221, 0150, 0066, 0000, 0000, 0000, 0006, 0164, 0122, 0116, 0123, 0000, 0000, 0000, 0000, 0000, 0000, 0156, 0246, 0007, 0221, 0000, 0000, 0000, 0006, 0142, 0113, 0107, 0104, 0000, 0275, 0000, 0275, 0000, 0275, 0151, 0102, 0325, 0250, 0000, 0000, 0000, 0020, 0111, 0104, 0101, 0124, 0170, 0332, 0143, 0140, 0030, 0005, 0243, 0140, 0024, 0300, 0000, 0000, 0003, 0020, 0000, 0001, 0327, 0055, 0204, 0143, 0000, 0000, 0000, 0105, 0172, 0124, 0130, 0164, 0123, 0157, 0146, 0164, 0167, 0141, 0162, 0145, 0000, 0000, 0170, 0332, 0163, 0320, 0120, 0326, 0364, 0314, 0115, 0114, 0117, 0365, 0115, 0114, 0317, 0114, 0316, 0126, 0060, 0321, 0063, 0320, 0063, 0121, 0260, 0264, 0320, 0067, 0060, 0321, 0067, 0060, 0124, 0110, 0056, 0312, 0054, 0056, 0251, 0164, 0050, 0256, 0314, 0055, 0110, 0054, 0311, 0114, 0316, 0327, 0313, 0057, 0112, 0007, 0000, 0174, 0152, 0017, 0371, 0170, 0366, 0024, 0302, 0000, 0000, 0000, 0063, 0172, 0124, 0130, 0164, 0123, 0151, 0147, 0156, 0141, 0164, 0165, 0162, 0145, 0000, 0000, 0170, 0332, 0063, 0110, 0063, 0066, 0061, 0116, 0062, 0260, 0064, 0066, 0064, 0064, 0062, 0113, 0064, 0062, 0110, 0063, 0064, 0066, 0116, 0061, 0063, 0117, 0066, 0112, 0062, 0060, 0264, 0110, 0064, 0116, 0002, 0000, 0200, 0262, 0010, 0020, 0207, 0362, 0015, 0215, 0000, 0000, 0000, 0000, 0111, 0105, 0116, 0104, 0256, 0102, 0140, 0202}; typedef struct {unsigned char *png; int loc;} png_info; static cairo_status_t png_read(void *closure, unsigned char *data, unsigned int size) { /* put the next size bytes in data from whatever we're reading */ png_info *p = (png_info *)closure; memcpy((void *)data, (void *)(p->png + p->loc), size); p->loc += size; return(CAIRO_STATUS_SUCCESS); } static cairo_surface_t *png_to_surface(unsigned char *png_data) { png_info *p; p = (png_info *)malloc(sizeof(png_info)); p->png = png_data; p->loc = 0; return(cairo_image_surface_create_from_png_stream((cairo_read_func_t)png_read, (void *)p)); } static cairo_surface_t *lock_icon = NULL, *stop_icon = NULL, *bomb_icon = NULL, *right_arrow_icon = NULL; static cairo_surface_t *left_arrow_icon = NULL, *blank_icon = NULL, *speaker_icon = NULL; cairo_surface_t *snd_icon(int which) { switch (which) { case SND_PNG_LOCK: if (!lock_icon) lock_icon = png_to_surface(lock_data); return(lock_icon); break; case SND_PNG_STOP: if (!stop_icon) stop_icon = png_to_surface(stop_data); return(stop_icon); break; case SND_PNG_BLANK: if (!blank_icon) blank_icon = png_to_surface(blank_data); return(blank_icon); break; case SND_PNG_RIGHT_ARROW: if (!right_arrow_icon) right_arrow_icon = png_to_surface(right_arrow_data); return(right_arrow_icon); break; case SND_PNG_LEFT_ARROW: if (!left_arrow_icon) left_arrow_icon = png_to_surface(left_arrow_data); return(left_arrow_icon); break; case SND_PNG_BOMB: if (!bomb_icon) bomb_icon = png_to_surface(bomb_data); return(bomb_icon); break; case SND_PNG_SPEAKER: if (!speaker_icon) speaker_icon = png_to_surface(speaker_data); return(speaker_icon); break; } return(NULL); } #endif snd-16.1/snd-motif.scm0000644000076400007640000034702312624451315012753 0ustar bilbil;;; snd-motif.scm -- Motif-related procedures (all use xm.so, most assume Motif 2) ;;; ;;; (install-searcher proc) -- use proc as File Selection Box filter, also install-searcher-with-colors ;;; (zync) and (unzync) -- cause y-zoom sliders to move together ;;; (for-each-child w func) -- apply func to w and all its children, similarly find-child and display-widget-tree ;;; (create-fmv-dialog) for "real-time" control of the fm-violin in fmv.scm ;;; (make-pixmap strs) turns xpm-style description into pixmap ;;; (display-scanned-synthesis) opens a scanned-synthesis viewer ;;; (disable-control-panel) does away with the control panel ;;; (add-mark-pane) adds a pane of mark locations to each channel that has marks ;;; (snd-clock-icon snd hour) show an animated clock icon ;;; (make-sound-box name parent select-func peak-func sounds args) makes a box of sound icons ;;; (make-channel-drop-site snd chn) -- add a drop site ;;; (set-channel-drop drop snd chn) -- change given graph drop callback to drop ;;; (select-file func title dir filter help) starts a Snd-like File Selection Dialog running func if a file is selected ;;; (show-disk-space snd) adds a label to the status-area area showing the current free space ;;; (keep-file-dialog-open-upon-ok) changes File:Open so that clicking "ok" does not "unmanage" the dialog ;;; (add-amp-controls) adds amp sliders to the control panel for multi-channel sounds ;;; (remove-main-menu menu) removes a top-level menu ;;; add delete and rename options to the file menu (add-delete-option) (add-rename-option) ;;; (mark-sync-color new-color) sets the color of syncd marks ;;; (add-tooltip widget tip) adds tooltip tip to widget ;;; (menu-option name) to access menu items ;;; (show-all-atoms) shows all X atoms ;;; show-widget-font shows what fonts are associated with a widget ;;; add-find-to-listener enables C-s and C-r in the listener ;;; add a function to be called when the window manager sends us a "save yourself" message ;;; add-text-to-status-area puts a text widget in the notebook status area ;;; make-variable-display displays an arbitrary set of expressions/variables in a notebook widget ;;; with-minmax-button adds an open/close button to each sound pane ;;; notebook-with-top-tabs (for Xemacs-like list of open files across the top of the window) ;;; create-audit-dialog ;;; equalize-panes (provide 'snd-snd-motif.scm) (require snd-motif snd-extensions.scm snd-play.scm snd-dsp.scm) (with-let *motif* (define (find-if pred l) (cond ((null? l) #f) ((pred (car l)) (car l)) (else (find-if pred (cdr l))))) (define load-font (let ((documentation "(load-font name) loads the font 'name', returning the font id")) (lambda (name) (let ((fs (XLoadQueryFont (XtDisplay (cadr (main-widgets))) name))) (and fs (XFontStruct? fs) (.fid fs)))))) (define current-screen (let ((documentation "(current-screen) returns the current X screen number of the current display")) (lambda () (DefaultScreenOfDisplay (XtDisplay (cadr (main-widgets))))))) (define white-pixel (let ((documentation "(white-pixel) returns a white pixel")) (lambda () (WhitePixelOfScreen (current-screen))))) (define black-pixel (let ((documentation "(black-pixel) returns a black pixel")) (lambda () (BlackPixelOfScreen (current-screen))))) (define screen-depth (let ((documentation "(screen-depth) returns the current screen depth")) (lambda () (DefaultDepthOfScreen (current-screen))))) (define xm-clean-string (let ((documentation "(xm-clean-string str) changes slash to underbar in the filename 'str' (for the peak env file)")) (lambda (str) ;; full file name should be unique, so I think we need only fix it up to look like a flat name (let* ((len (length str)) (new-str (make-string len #\.))) (do ((i 0 (+ i 1))) ((= i len) new-str) (let ((c (str i))) (if (memq c '(#\\ #\/)) (set! (new-str i) #\_) (set! (new-str i) c)))))))) ;;; -------- apply func to every widget belonging to w (and w) -------- (define for-each-child (let ((documentation "(for-each-child w func) applies func to w and its descendents")) (lambda (w func) (func w) (if (XtIsComposite w) (for-each (lambda (n) (for-each-child n func)) (cadr (XtGetValues w (list XmNchildren 0) 1))))))) (define find-child (let ((documentation "(find-child widget name) returns a widget named 'name', if one can be found in the widget hierarchy beneath 'widget'")) (lambda (widget name) ;; unfortunately, if the widget's name has been set for some non-English locale, this ;; won't work -- we need to add gettext support (see snd.c for an example) (call-with-exit (lambda (return) (for-each-child widget (lambda (child) (if (string=? (XtName child) name) (return child)))) (throw 'no-such-widget (list "find-child" name))))))) (define display-widget-tree (let ((documentation "(display-widget-tree widget) displays the hierarchy of widgets beneath 'widget'")) (lambda (widget) (define (display-widget w spaces) (let ((name (XtName w))) (if (or (not (string? name)) (= (length name) 0)) (set! name "")) (format #t "~A~A~%" spaces name) (if (XtIsComposite w) (for-each (lambda (n) (display-widget n (string-append spaces " "))) (cadr (XtGetValues w (list XmNchildren 0) 1)))))) (display-widget widget "")))) (define set-main-color-of-widget (let ((documentation "(set-main-color-of-widget w) sets the background color of widget 'w'")) (lambda (w) (for-each-child w (lambda (n) (if (XtIsWidget n) (if (XmIsScrollBar n) (XmChangeColor n *position-color*) (XmChangeColor n *basic-color*)))))))) (define host-name (let ((documentation "(host-name) -> name of current machine")) (lambda () (let* ((dpy (XtDisplay (cadr (main-widgets)))) (win (XtWindow (cadr (main-widgets)))) (host (XGetWindowProperty dpy win (XInternAtom (XtDisplay (cadr (main-widgets))) "WM_CLIENT_MACHINE" #f) 0 32 #f XA_STRING))) (and host (host 5)))))) ;;; -------- install-searcher -------- ;;; ;;; replaces the current file search procedure in the File Selection Box (define (install-searcher-with-colors proc) (define match-sound-files (lambda args (let ((func (car args)) (matches ())) (for-each (lambda (file) (if (func file) (set! matches (cons file matches)))) (sound-files-in-directory (if (null? (cdr args)) "." (cadr args)))) matches))) (define (XmString->string str) (XmStringUnparse str #f XmCHARSET_TEXT XmCHARSET_TEXT #f 0 XmOUTPUT_ALL)) (let* ((dialog (open-file-dialog #f)) ;; (XtGetValues dialog (XmNfileSearchProc 0)) to get the default (shell (cadr (main-widgets))) (tags (list "one" "two" "three" "four")) (colors (list "black" "red" "blue" "orange")) (pixels (let* ((dpy (XtDisplay shell)) (scr (DefaultScreen dpy)) (cmap (DefaultColormap dpy scr))) (map (lambda (color) (let ((col (XColor))) (if (= (XAllocNamedColor dpy cmap color col col) 0) (snd-error (format #f "can't allocate ~A" color)) (.pixel col)))) colors))) (rendertable (XmRenderTableAddRenditions #f (map (lambda (tag pix) (XmRenditionCreate (cadr (main-widgets)) tag (list XmNrenditionForeground pix XmNfontName "9x15" XmNfontType XmFONT_IS_FONT))) tags pixels) (length tags) XmMERGE_NEW))) (XtSetValues dialog (list XmNfileSearchProc (lambda (widget info) (let* ((dir (XmString->string (.dir info))) ; may need filter text here? (files (sort! (map (lambda (n) (string-append dir n)) (match-sound-files proc dir)) stringradians frequency)) (maxdev (* frq-scl fm-index)) (logfreq (log frequency)) (index1 (min pi (* maxdev (/ 5.0 logfreq)))) (index2 (min pi (* maxdev 3.0 (/ (- 8.5 logfreq) (+ 3.0 (* frequency .001)))))) (index3 (min pi (* maxdev (/ 4.0 (sqrt frequency))))) (carrier (make-oscil frequency)) (fmosc1 (make-oscil (* fm1-rat frequency))) (fmosc2 (make-oscil (* fm2-rat frequency))) (fmosc3 (make-oscil (* fm3-rat frequency))) (pervib (make-triangle-wave periodic-vibrato-rate (* periodic-vibrato-amplitude frq-scl))) (ranvib (make-rand-interp random-vibrato-rate (* random-vibrato-amplitude frq-scl))) (fm-noi (make-rand noise-freq (* pi noise-amount)))) (letrec ((v (lambda () (let ((vib (+ (triangle-wave pervib) (rand-interp ranvib))) (fuzz (rand fm-noi))) (* amplitude (oscil carrier (+ vib (* index1 (oscil fmosc1 (+ (* fm1-rat vib) fuzz))) (* index2 (oscil fmosc2 (+ (* fm2-rat vib) fuzz))) (* index3 (oscil fmosc3 (+ (* fm3-rat vib) fuzz))))))))) (set-frequency (lambda (frq) (set! frequency frq) (set! frq-scl (hz->radians frequency)) (set! maxdev (* frq-scl fm-index)) (set! logfreq (log frequency)) (set! index1 (min pi (* maxdev (/ 5.0 logfreq)))) (set! index2 (min pi (* maxdev 3.0 (/ (- 8.5 logfreq) (+ 3.0 (* frequency .001)))))) (set! index3 (min pi (* maxdev (/ 4.0 (sqrt frequency))))) (set! (mus-frequency carrier) frequency) (set! (mus-frequency fmosc1) (* fm1-rat frequency)) (set! (mus-frequency fmosc2) (* fm2-rat frequency)) (set! (mus-frequency fmosc3) (* fm3-rat frequency)))) (set-index (lambda (ind) (set! fm-index ind) (set! maxdev (* frq-scl fm-index)) (set! index1 (min pi (* maxdev (/ 5.0 logfreq)))) (set! index2 (min pi (* maxdev 3.0 (/ (- 8.5 logfreq) (+ 3.0 (* frequency .001)))))) (set! index3 (min pi (* maxdev (/ 4.0 (sqrt frequency))))))) (set-noise (lambda (noi) (set! noise-amount noi) (set! (mus-scaler fm-noi) (* pi noise-amount))))) (let* ((mainform (XtCreateManagedWidget "formd" xmRowColumnWidgetClass fmv-dialog (list XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_WIDGET XmNbottomWidget (XmMessageBoxGetChild fmv-dialog XmDIALOG_SEPARATOR) XmNbackground *basic-color* XmNorientation XmVERTICAL))) (button (XtCreateManagedWidget "play" xmToggleButtonWidgetClass mainform (list XmNbackground *basic-color*))) (ampstr (XmStringCreate "amp" XmFONTLIST_DEFAULT_TAG)) (amp-scale (XtCreateManagedWidget "amp" xmScaleWidgetClass mainform (list XmNorientation XmHORIZONTAL XmNshowValue #t XmNbackground *basic-color* XmNvalue (floor (* amplitude 100)) XmNmaximum 100 XmNtitleString ampstr XmNdecimalPoints 2))) (freqstr (XmStringCreate "freq" XmFONTLIST_DEFAULT_TAG)) (freq-scale (XtCreateManagedWidget "freq" xmScaleWidgetClass mainform (list XmNorientation XmHORIZONTAL XmNshowValue #t XmNbackground *basic-color* XmNvalue (floor frequency) XmNmaximum 1000 XmNtitleString freqstr XmNdecimalPoints 0))) (indexstr (XmStringCreate "index" XmFONTLIST_DEFAULT_TAG)) (index-scale (XtCreateManagedWidget "index" xmScaleWidgetClass mainform (list XmNorientation XmHORIZONTAL XmNshowValue #t XmNbackground *basic-color* XmNvalue (floor (* 10 fm-index)) XmNmaximum 100 XmNtitleString indexstr XmNdecimalPoints 1))) (noisestr (XmStringCreate "noise" XmFONTLIST_DEFAULT_TAG)) (noise-scale (XtCreateManagedWidget "noise" xmScaleWidgetClass mainform (list XmNorientation XmHORIZONTAL XmNshowValue #t XmNbackground *basic-color* XmNvalue (floor (* 100 noise-amount)) XmNmaximum 100 XmNtitleString noisestr XmNdecimalPoints 3)))) (XmStringFree ampstr) (XmStringFree freqstr) (XmStringFree indexstr) (XmStringFree noisestr) (XtAddCallback amp-scale XmNvalueChangedCallback (lambda (w context info) (set! amplitude (* .01 (.value info))))) (XtAddCallback amp-scale XmNdragCallback (lambda (w context info) (set! amplitude (* .01 (.value info))))) (XtAddCallback freq-scale XmNvalueChangedCallback (lambda (w context info) (set-frequency (.value info)))) (XtAddCallback freq-scale XmNdragCallback (lambda (w context info) (set-frequency (.value info)))) (XtAddCallback index-scale XmNvalueChangedCallback (lambda (w context info) (set-index (* .1 (.value info))))) (XtAddCallback index-scale XmNdragCallback (lambda (w context info) (set-index (* .1 (.value info))))) (XtAddCallback noise-scale XmNvalueChangedCallback (lambda (w context info) (set-noise (* .001 (.value info))))) (XtAddCallback noise-scale XmNdragCallback (lambda (w context info) (set-noise (* .001 (.value info))))) (XtAddCallback button XmNvalueChangedCallback (lambda (w context info) (if running (set! running #f) (let* ((audio-info (open-play-output 1 44100 #f 128)) (audio-fd (car audio-info)) (outchans (cadr audio-info)) (len (caddr audio-info)) (data (make-float-vector (list outchans len) 0.0))) (if (not (= audio-fd -1)) (begin (set! running #t) (do () ((not running) (begin (set! running #f) (mus-audio-close audio-fd))) (do ((k 0 (+ k 1))) ((= k len)) (vector-set! data 0 k (v))) (mus-audio-write audio-fd data len))))))))))))) (XtManageChild fmv-dialog)))) |# ;;; -------- make-pixmap -------- (define arrow-strs (list "16 12 6 1" " c None s None" ". c gray50" "X c black" "o c white" "O c yellow" "- c ivory2 s basiccolor" "--------X---------" "---------X--------" "----------X-------" "-----------X------" "------------X-----" "XXXXXXXXXXXXXX----" "------------X-----" "-----------X------" "----------X-------" "---------X--------" "--------X---------" "-------X----------")) (define make-pixmap (let ((documentation "(make-pixmap w strs) creates a pixmap using the X/Xpm string-based pixmap description")) (lambda (widget strs) ; strs is list of strings as in arrow-strs above (and (defined? 'XpmAttributes) (let* ((attr (XpmAttributes)) (symb (XpmColorSymbol "basiccolor" #f *basic-color*)) (dpy (XtDisplay widget)) (win (XtWindow widget)) (scr (DefaultScreen dpy)) (depth (cadr (XtGetValues widget (list XmNdepth 0)))) (colormap (cadr (XtGetValues widget (list XmNcolormap 0))))) (set! (.depth attr) depth) (set! (.colormap attr) colormap) (set! (.visual attr) (DefaultVisual dpy scr)) (set! (.colorsymbols attr) (list symb)) (set! (.numsymbols attr) 1) (set! (.valuemask attr) (logior XpmColorSymbols XpmDepth XpmColormap XpmVisual)) (cadr (XpmCreatePixmapFromData dpy win strs attr))))))) ; (XtSetValues ((sound-widgets) 8) (list XmNlabelPixmap (make-pixmap (cadr (main-widgets)) arrow-strs)))) ;;; if you have a nice background pixmap, you can map it over all of Snd with: #| (load "new-backgrounds.scm") (define wd (make-pixmap (cadr (main-widgets)) wood)) (define (paint-all widget) (for-each-child widget (lambda (w) (XtSetValues w (list XmNbackgroundPixmap wd)) (if (XmIsLabel w) (let ((val (cadr (XtVaGetValues w (list XmNlabelType 0))))) (if (= val XmPIXMAP) (XtVaSetValues w (list XmNlabelPixmap wd)))))))) (paint-all (cadr (main-widgets))) (for-each (lambda (w) (if w (paint-all w))) (dialog-widgets)) (hook-push new-widget-hook (lambda (hook) (paint-all (hook 'widget)))) |# (define right-arrow (list #x00 #x04 #x10 #x08 #x00 #x10 #x04 #x20 #x00 #x40 #xa5 #xbf #x00 #x40 #x04 #x20 #x00 #x10 #x10 #x08 #x00 #x04 #x00 #x00)) (define bitmap->pixmap (let ((documentation "(bitmap->pixmap widget bits width height) takes an X-style bitmap and turns it into a pixmap")) (lambda (widget bits width height) (XCreateBitmapFromData (XtDisplay widget) (XtWindow widget) bits width height)))) ; (XtSetValues ((sound-widgets) 8) (list XmNlabelPixmap (bitmap->pixmap ((sound-widgets) 8) iconw right-arrow 16 12))) #| ;;; -------- display-scanned-synthesis -------- ;;; ;;; open a new main pane below the listener, with two sections ;;; on the left various controls, on the right a graph ;;; push 'start' to start the scanned synthesis display ;;; if spring > mass, you'll get overflows (define (display-scanned-synthesis) (define (add-main-pane name type args) (XtCreateManagedWidget name type ((main-widgets) 3) args)) (define compute-uniform-circular-string ;; copied from dsp.scm to simplify life (lambda (size x0 x1 x2 mass xspring damp) (define circle-float-vector-ref (lambda (v i) (if (< i 0) (v (+ size i)) (if (>= i size) (v (- i size)) (v i))))) (let* ((dm (/ damp mass)) (km (/ xspring mass)) (denom (+ 1.0 dm)) (p1 (/ (+ 2.0 (- dm (* 2.0 km))) denom)) (p2 (/ km denom)) (p3 (/ -1.0 denom))) (do ((i 0 (+ i 1))) ((= i size)) (set! (x0 i) (min (+ (* p1 (x1 i)) (* p2 (+ (circle-float-vector-ref x1 (- i 1)) (circle-float-vector-ref x1 (+ i 1)))) (* p3 (x2 i))) 1000.0))) (copy x1 x2) (copy x0 x1)))) (if (< (window-height) 520) (set! (window-height) 520)) (set! *clm-srate* 22050.0) (let* ((mass 1.0) (xspring 0.1) (damp 0.0) (bounds ()) (pts0 #f) (pts1 #f) (playing #f) ;; (frequency 440.0) (amplitude 0.02) (ax0 0) (ax1 0) (ay0 0) (ay1 0) (gc (car (snd-gcs))) (egc ((snd-gcs) 7)) (app (car (main-widgets))) ;; now set up a paned window in the main Snd window with controllers on the left and the graph on the right (scan-outer (add-main-pane "Scanned Synthesis" xmFormWidgetClass (list XmNbackground *basic-color* XmNpaneMinimum 520))) (scan-row (XtCreateManagedWidget "row" xmRowColumnWidgetClass scan-outer (list XmNbackground *basic-color* XmNorientation XmVERTICAL XmNleftAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_POSITION XmNrightPosition 32))) ;; the graph (scan-pane (XtCreateManagedWidget "draw" xmDrawingAreaWidgetClass scan-outer (list XmNbackground *graph-color* XmNforeground *data-color* XmNleftAttachment XmATTACH_WIDGET XmNleftWidget scan-row XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM))) ;; the controllers (scan-start (XtCreateManagedWidget "Start" xmPushButtonWidgetClass scan-row (list XmNbackground *basic-color* XmNarmColor *selection-color*))) (scan-continue (XtCreateManagedWidget "Continue" xmPushButtonWidgetClass scan-row (list XmNbackground *basic-color* XmNarmColor *selection-color*))) (scan-stop (XtCreateManagedWidget "Stop" xmPushButtonWidgetClass scan-row (list XmNbackground *basic-color* XmNarmColor *selection-color*))) (size 128) (tbl (make-table-lookup :size size)) (gx0 (mus-data tbl)) (gx1 (make-float-vector size)) (gx2 (make-float-vector size)) (vect (make-vector (* 2 size))) (work-proc 0)) (define (y->grfy y range) (min ay1 (max ay0 (round (+ ay0 (* range (- 10.0 y))))))) (define (draw-graph) (if (and (> ax1 ax0) (> ay1 ay0)) (let ((diff (* 0.05 (- ay1 ay0))) ; assuming -10 to 10 (dpy (XtDisplay scan-pane)) (wn (XtWindow scan-pane)) (xincr (* 1.0 (/ (- ax1 ax0) size)))) (if pts1 (XDrawLinesDirect dpy wn egc pts1 size 0) (XFillRectangle dpy wn egc ; erase previous graph (+ ax0 2) ay0 (- ax1 ax0 2) (- ay1 ay0))) (do ((i 0 (+ i 1)) (j 0 (+ j 2)) (xi ax0 (+ xi xincr))) ((= i size)) (set! (vect j) (floor xi)) (set! (vect (+ j 1)) (y->grfy (gx0 i) diff))) (if pts1 (freeXPoints pts1)) (set! pts0 (vector->XPoints vect)) (set! pts1 pts0) (XDrawLinesDirect dpy wn gc pts0 size 0)))) (define (redraw-graph) (set! bounds (draw-axes scan-pane gc "scanned synthesis" 0.0 1.0 -10.0 10.0)) (set! ax0 (+ (car bounds) 2)) (set! ax1 (caddr bounds)) (set! ay1 (cadr bounds)) (set! ay0 (cadddr bounds)) (draw-graph)) (define (tick-synthesis n) ;; background process (compute-uniform-circular-string size gx0 gx1 gx2 mass xspring damp) (draw-graph) #f) (define (stop-synthesis) (if (XtWorkProcId? work-proc) (XtRemoveWorkProc work-proc)) (set! work-proc 0) (set! playing #f)) (define (start-synthesis) (stop-synthesis) (fill! gx0 0.0) (fill! gx1 0.0) (fill! gx2 0.0) (do ((i 0 (+ i 1))) ((= i 12)) (let ((val (sin (/ (* 2 pi i) 12.0)))) (set! (gx1 (+ i (- (/ size 4) 6))) val))) (set! work-proc (XtAppAddWorkProc app tick-synthesis))) (define (continue-synthesis) (stop-synthesis) (set! work-proc (XtAppAddWorkProc app tick-synthesis))) ;; controller callbacks (for-each (lambda (data) (let* ((title (XmStringCreate (car data) XmFONTLIST_DEFAULT_TAG)) (button (XtCreateManagedWidget (car data) xmScaleWidgetClass scan-row (list XmNbackground *basic-color* XmNorientation XmHORIZONTAL XmNshowValue #t XmNminimum (data 1) XmNmaximum (data 2) XmNvalue (data 3) XmNdecimalPoints (data 4) XmNtitleString title)))) (XtAddCallback button XmNdragCallback (lambda (w c i) ((data 5) (.value i)))) (XtAddCallback button XmNvalueChangedCallback (lambda (w c i) ((data 5) (.value i)))) (XmStringFree title))) (list (list "mass" 1 200 100 2 (lambda (val) (set! mass (/ val 100.0)))) (list "spring" 1 100 10 2 (lambda (val) (set! xspring (/ val 100.0)))) (list "damping" 0 100 0 4 (lambda (val) (set! damp (/ val 10000.0)))))) (let* ((scan-size (XtCreateManagedWidget "srow" xmFormWidgetClass scan-row (list XmNbackground *basic-color*))) (scan-label (XtCreateManagedWidget "Size:" xmLabelWidgetClass scan-size (list XmNbackground *basic-color* XmNleftAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_NONE))) (scan-text (XtCreateManagedWidget "stext" xmTextFieldWidgetClass scan-size (list XmNbackground *basic-color* XmNvalue (number->string size) XmNleftAttachment XmATTACH_WIDGET XmNleftWidget scan-label XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM))) (play-button (XtCreateManagedWidget "play" xmToggleButtonWidgetClass scan-row (list XmNbackground *basic-color* XmNselectColor *selection-color*))) (freq-str (XmStringCreate "frequency" XmFONTLIST_DEFAULT_TAG)) (freq-scale (XtCreateManagedWidget "frequency" xmScaleWidgetClass scan-row (list XmNbackground *basic-color* XmNorientation XmHORIZONTAL XmNshowValue #t XmNminimum 20 XmNmaximum 1000 XmNvalue 440 XmNdecimalPoints 0 XmNtitleString freq-str))) (amp-str (XmStringCreate "amplitude" XmFONTLIST_DEFAULT_TAG)) (amp-scale (XtCreateManagedWidget "amplitude" xmScaleWidgetClass scan-row (list XmNbackground *basic-color* XmNorientation XmHORIZONTAL XmNshowValue #t XmNminimum 0 XmNmaximum 100 XmNvalue 10 XmNdecimalPoints 3 XmNtitleString amp-str)))) (XmStringFree freq-str) (XmStringFree amp-str) (XtAddEventHandler scan-text EnterWindowMask #f (lambda (w context ev flag) (XmProcessTraversal w XmTRAVERSE_CURRENT) (XtSetValues w (list XmNbackground (white-pixel))))) (XtAddEventHandler scan-text LeaveWindowMask #f (lambda (w context ev flag) (XtSetValues w (list XmNbackground *basic-color*)))) (XtAddCallback scan-text XmNactivateCallback (lambda (w c i) (stop-synthesis) (set! size (string->number (cadr (XtGetValues scan-text (list XmNvalue 0))))) (set! tbl (make-table-lookup :size size)) (set! gx0 (mus-data tbl)) (set! gx1 (make-float-vector size)) (set! gx2 (make-float-vector size)) (set! vect (make-vector (* size 2))))) (XtAddCallback freq-scale XmNdragCallback (lambda (w c i) (set! (mus-frequency tbl) (.value i)))) (XtAddCallback freq-scale XmNvalueChangedCallback (lambda (w c i) (set! (mus-frequency tbl) (.value i)))) (XtAddCallback amp-scale XmNdragCallback (lambda (w c i) (set! amplitude (* .001 (.value i))))) (XtAddCallback amp-scale XmNvalueChangedCallback (lambda (w c i) (set! amplitude (* .001 (.value i))))) (XtAddCallback play-button XmNvalueChangedCallback (lambda (w context info) (if playing (set! playing #f) (let* ((audio-info (open-play-output 1 22050 #f 128)) (audio-fd (car audio-info)) (outchans (cadr audio-info)) (len (caddr audio-info)) (data (make-float-vector (list outchans len) 0.0))) (set! playing #t) (if (not (= audio-fd -1)) (do () ((not playing) ; can also happen if top Stop button pressed (begin (set! playing #f) (XmToggleButtonSetValue play-button 0 #f) ; don't send event (mus-audio-close audio-fd))) (tick-synthesis work-proc) (do ((k 0 (+ k 1))) ((= k len)) (vector-set! data 0 k (* amplitude (table-lookup tbl)))) (mus-audio-write audio-fd data len)) (set! playing #f))))))) (XtAddCallback scan-pane XmNresizeCallback (lambda (w context info) (redraw-graph))) (XtAddCallback scan-pane XmNexposeCallback (lambda (w context info) (redraw-graph))) (XtAddEventHandler scan-pane ButtonPressMask #f (lambda (w context ev flag) (if (not (XtWorkProcId? work-proc)) (if (= (.button ev) 2) (continue-synthesis) (start-synthesis)) (stop-synthesis)))) (XtAddCallback scan-start XmNactivateCallback (lambda (w c i) (start-synthesis))) (XtAddCallback scan-continue XmNactivateCallback (lambda (w c i) (continue-synthesis))) (XtAddCallback scan-stop XmNactivateCallback (lambda (w c i) (stop-synthesis))) #t ; for slightly prettier listener output )) (define close-scanned-synthesis-pane (let ((documentation "(close-scanned-synthesis-pane) closes the Scanned Sythesis sound pane")) (lambda () (for-each-child (cadr (main-widgets)) ; this is Snd's outermost shell (lambda (n) (if (string=? (XtName n) "Scanned Synthesis") (XtUnmanageChild n))))))) |# ;;; -------- add-mark-pane -------- ;;; ;;; adds a pane to each channel giving the current mark locations (sample values) ;;; these can be edited to move the mark, or deleted to delete the mark ;;; can't use channel-property here because the widget lists are permanent (just unmanaged) (define including-mark-pane #f) ; for prefs (define (add-mark-pane) (define (find-mark-list snd chn dats) (and (pair? dats) (let ((cur (car dats))) (if (and (equal? (car cur) snd) (= (cadr cur) chn)) (caddr cur) (find-mark-list snd chn (cdr dats)))))) (define mark-list-length (let ((mark-list-lengths ())) (define (remove-mark-list snd chn) (set! mark-list-lengths (remove-if (lambda (n) (and (equal? (car n) snd) (= (cadr n) chn))) mark-list-lengths))) (dilambda (lambda (snd chn) (or (find-mark-list snd chn mark-list-lengths) 0)) (lambda (snd chn len) (remove-mark-list snd chn) (set! mark-list-lengths (cons (list snd chn len) mark-list-lengths)))))) (define mark-list (let ((mark-lists ())) (dilambda (lambda (snd chn) (let ((dat (find-mark-list snd chn mark-lists))) (and dat (caddr dat)))) (lambda (snd chn wid) (set! mark-lists (cons (list snd chn wid) mark-lists)))))) (define (deactivate-mark-list snd chn) (let ((current-mark-list-length (mark-list-length snd chn))) (if (and (> current-mark-list-length 0) (Widget? (mark-list snd chn))) (for-each XtUnmanageChild (cadr (XtGetValues (mark-list snd chn) (list XmNchildren 0) 1)))))) (define (make-mark-list snd chn) (let ((current-mark-list-length (mark-list-length snd chn))) (deactivate-mark-list snd chn) (if (not (Widget? (mark-list snd chn))) (let* ((mark-box (add-channel-pane snd chn "mark-box" xmFormWidgetClass (list XmNbackground *basic-color* XmNorientation XmVERTICAL XmNpaneMinimum 100 XmNbottomAttachment XmATTACH_FORM))) (mark-label (XtCreateManagedWidget "Marks" xmLabelWidgetClass mark-box (list XmNbackground *highlight-color* XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNalignment XmALIGNMENT_CENTER XmNtopAttachment XmATTACH_FORM))) (mark-scroller (XtCreateManagedWidget "mark-scroller" xmScrolledWindowWidgetClass mark-box (list XmNbackground *basic-color* XmNscrollingPolicy XmAUTOMATIC XmNscrollBarDisplayPolicy XmSTATIC XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_WIDGET XmNtopWidget mark-label XmNbottomAttachment XmATTACH_FORM))) (mlist (XtCreateManagedWidget "mark-list" xmRowColumnWidgetClass mark-scroller (list XmNorientation XmVERTICAL XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_FORM XmNspacing 0)))) (set-main-color-of-widget mark-scroller) (XtSetValues mark-box (list XmNpaneMinimum 1)) (set! (mark-list snd chn) (list snd chn mlist)))) (let ((new-marks (marks snd chn))) (if (> (length new-marks) current-mark-list-length) (let ((lst (mark-list snd chn))) (do ((i current-mark-list-length (+ i 1))) ((= i (length new-marks))) (let ((tf (XtCreateWidget "field" xmTextFieldWidgetClass lst (list XmNbackground *basic-color*)))) (XtAddCallback tf XmNfocusCallback (lambda (w c i) (XtSetValues w (list XmNbackground (white-pixel))))) (XtAddCallback tf XmNlosingFocusCallback (lambda (w c i) (XtSetValues w (list XmNbackground *basic-color*)))) (XtAddCallback tf XmNactivateCallback (lambda (w c i) (let* ((id (integer->mark (cadr (XtGetValues w (list XmNuserData 0))))) (txt (cadr (XtGetValues w (list XmNvalue 0)))) (samp (and (string? txt) (> (length txt) 0) (string->number txt)))) (if samp (if (mark? id) (set! (mark-sample id) samp)) (delete-mark id)) (XtSetValues w (list XmNbackground *basic-color*))))))))) (set! (mark-list-length snd chn) (length new-marks)) (let ((lst (mark-list snd chn))) (call-with-exit (lambda (quit) (for-each (lambda (n) (if (null? new-marks) (quit #f)) (if (XmIsTextField n) (begin (XtSetValues n (list XmNvalue (number->string (mark-sample (car new-marks))) XmNuserData (mark->integer (car new-marks)))) (XtManageChild n) (set! new-marks (cdr new-marks))))) (cadr (XtGetValues lst (list XmNchildren 0) 1))))))) #f)) (define (remark hook) (make-mark-list (hook 'snd) (hook 'chn))) (define (unremark hook) (do ((i 0 (+ i 1))) ((= i (channels (hook 'snd)))) (deactivate-mark-list (hook 'snd) i))) (define (open-remarks hook) (let ((snd (hook 'snd))) (do ((i 0 (+ i 1))) ((= i (channels snd))) (hook-push (after-edit-hook snd i) (lambda (hook) (if (Widget? (mark-list snd i)) (make-mark-list snd i)))) (hook-push (undo-hook snd i) (lambda (hook) (if (Widget? (mark-list snd i)) (make-mark-list snd i))))))) (set! including-mark-pane #t) (hook-push mark-hook remark) (hook-push close-hook unremark) (hook-push after-open-hook open-remarks) (hook-push update-hook (lambda (hook) ;; update-sound (called if header is changed, for example), calls open-sound ;; which restores our channel-local mark-pane hooks, but doesn't re-activate ;; the mark pane itself. So, we return a procedure from the update-hook ;; evaluation that will recreate our pane immediately upon update completion. (set! (hook 'result) (lambda (updated-snd) ;; this is the procedure to be called when the update is done (do ((i 0 (+ i 1))) ((= i (channels updated-snd))) (make-mark-list updated-snd i)))))) ) ;;; -------- select-file -------- ;;; ;;; (select-file func title dir filter help) ;;; starts a Snd-like File Selection Dialog, runs func if a file is selected ;;; ;;; (add-to-menu 0 "Insert File" ;;; (lambda () ;;; (select-file ;;; (lambda (filename) ;;; (insert-sound filename)) ;;; "Insert File" "." "*" "file will be inserted at cursor"))) (define select-file (let ((file-selector-dialogs ())) ;; (list (list widget inuse func title help) ...) (define (find-free-dialog ds) (and (pair? ds) (if (not (cadr (car ds))) (begin (set! ((car ds) 1) #t) (caar ds)) (find-free-dialog (cdr ds))))) (define (find-dialog-widget wid ds) (and (pair? ds) (if (equal? wid (caar ds)) (car ds) (find-dialog-widget wid (cdr ds))))) (lambda args ;; (file-select func title dir filter help) (let* ((func (and (> (length args) 0) (args 0))) (title (if (> (length args) 1) (args 1) "select file")) (dir (if (> (length args) 2) (args 2) ".")) (filter (if (> (length args) 3) (args 3) "*")) (help (and (> (length args) 4) (args 4))) (dialog (or (find-free-dialog file-selector-dialogs) (let ((new-dialog (XmCreateFileSelectionDialog (cadr (main-widgets)) title (list XmNbackground *basic-color*)))) (XtAddCallback new-dialog XmNhelpCallback (lambda (w c i) (let ((lst (find-dialog-widget w file-selector-dialogs))) (if (lst 4) (help-dialog (lst 3) (lst 4)))))) (XtAddCallback new-dialog XmNokCallback (lambda (w c i) (let ((lst (find-dialog-widget w file-selector-dialogs))) ((lst 2) (XmStringUnparse (.value i) #f XmCHARSET_TEXT XmCHARSET_TEXT #f 0 XmOUTPUT_ALL)) (set! (lst 1) #f) (XtUnmanageChild w)))) (XtAddCallback new-dialog XmNcancelCallback (lambda (w c i) (let ((lst (find-dialog-widget w file-selector-dialogs))) (set! (lst 1) #f) (XtUnmanageChild w)))) (set! file-selector-dialogs (cons (list new-dialog #t func title help) file-selector-dialogs)) (set-main-color-of-widget new-dialog) (XtSetValues (XmFileSelectionBoxGetChild new-dialog XmDIALOG_DIR_LIST) (list XmNbackground (white-pixel))) (XtSetValues (XmFileSelectionBoxGetChild new-dialog XmDIALOG_LIST) (list XmNbackground (white-pixel))) (XtSetValues (XtNameToWidget new-dialog "Cancel") (list XmNarmColor *selection-color*)) (XtSetValues (XtNameToWidget new-dialog "Help") (list XmNarmColor *selection-color*)) (XtSetValues (XtNameToWidget new-dialog "OK") (list XmNarmColor *selection-color*)) new-dialog)))) (if (not help) (XtUnmanageChild (XmFileSelectionBoxGetChild dialog XmDIALOG_HELP_BUTTON)) (XtManageChild (XmFileSelectionBoxGetChild dialog XmDIALOG_HELP_BUTTON))) (let ((dirstr (XmStringCreateLocalized dir)) (patstr (XmStringCreateLocalized filter)) (titlestr (XmStringCreateLocalized title))) (XtSetValues dialog (list XmNdirectory dirstr XmNpattern patstr XmNdialogTitle titlestr)) (XmStringFree dirstr) (XmStringFree patstr) (XmStringFree titlestr) (XtManageChild dialog)))))) ; (select-file (lambda (n) (snd-print n))) ;;; -------- snd-clock-icon -------- ;;; ;;; a clock icon to replace Snd's hourglass ;;; call from a work proc or whatever with hour going from 0 to 12 then #f (define snd-clock-icon (let* ((shell ((main-widgets) 1)) (dpy (XtDisplay shell)) (win (XtWindow shell)) (clock-pixmaps (make-vector 12)) (dgc (car (snd-gcs)))) (do ((i 0 (+ i 1))) ((= i 12)) ;; it's actually possible to simply redraw on one pixmap, but updates are unpredictable (let* ((pix (XCreatePixmap dpy win 16 16 (screen-depth))) (pixwin (list 'Window (cadr pix)))) ; C-style cast to Window for X graphics procedures (set! (clock-pixmaps i) pix) (XSetForeground dpy dgc *basic-color*) (XFillRectangle dpy pixwin dgc 0 0 16 16) (XSetForeground dpy dgc (white-pixel)) (XFillArc dpy pixwin dgc 1 1 14 14 0 (* 64 360)) (XSetForeground dpy dgc (black-pixel)) (XDrawArc dpy pixwin dgc 1 1 14 14 0 (* 64 360)) (XDrawLine dpy pixwin dgc 8 8 (+ 8 (round (* 7 (sin (* i (/ 3.1416 6.0)))))) (- 8 (round (* 7 (cos (* i (/ 3.1416 6.0))))))))) (XSetBackground dpy dgc *graph-color*) (XSetForeground dpy dgc *data-color*) (lambda (snd hour) (if hour (XtSetValues ((sound-widgets snd) 8) (list XmNlabelPixmap (clock-pixmaps hour))) (bomb snd #f))))) ; using bomb to clear the icon ;;; -------- make-sound-box -------- ;;; ;;; make-sound-box makes a container of sound file icons, each icon ;;; containing a little sketch of the waveform, the length of the ;;; file, and the filename. What happens when an icon is selected ;;; is up to caller-supplied procedure. However, if you drag (via ;;; button 2) the icon to the menubar, that sound will be opened, ;;; and if you drag it to a channel graph, it will be mixed at the ;;; drag point in that channel. (define thumbnail-graph (let ((documentation "(thumbnail-graph dpy wn gc pts width height) makes a little graph of the data")) (lambda (dpy wn gc pts width height) (let* ((top-margin 2) (bottom-margin 6) (left-margin 2) (right-margin 2) (ay1 top-margin) (ay0 (- height bottom-margin)) (range (/ (- height top-margin bottom-margin) 2))) (define (y->grfy y height) (min ay0 (max ay1 (round (+ ay1 (* height (- 1.0 y))))))) (let* ((ly (y->grfy (pts 0) range)) (lx left-margin) (len (length pts)) (xinc (/ (- width left-margin right-margin) len)) (y 0)) (do ((i 1 (+ i 1)) (x lx (+ x xinc))) ((= i len)) (set! y (y->grfy (pts i) range)) (XDrawLine dpy wn gc lx ly (round x) y) (set! lx (round x)) (set! ly y))))))) (define make-sound-box ;; graphics stuff (fonts etc) (let* ((gv (XGCValues)) (shell ((main-widgets) 1)) (button-fontstruct (XLoadQueryFont (XtDisplay shell) (if (> (length *listener-font*) 0) *listener-font* "9x15")))) (set! (.foreground gv) *data-color*) (set! (.background gv) *basic-color*) (if (and button-fontstruct (.fid button-fontstruct)) (set! (.font gv) (.fid button-fontstruct))) (let ((gc (XCreateGC (XtDisplay shell) (XtWindow shell) (logior GCForeground GCBackground GCFont) gv)) (sound-buttons ())) ;; button data list handlers (define sound-button-gc (dilambda (lambda (data) (data 0)) (lambda (data val) (set! (data 0) val)))) (define sound-button-filename (dilambda (lambda (data) (data 1)) (lambda (data val) (set! (data 1) val)))) (define sound-button (dilambda (lambda (data) (data 2)) (lambda (data val) (set! (data 2) val)))) (define sound-button-peaks (dilambda (lambda (data) (data 3)) (lambda (data val) (set! (data 3) val)))) #| (define (sound-button-data button) (define (sb-data lst) (if (null? lst) #f (if (equal? button (sound-button (car lst))) (car lst) (sb-data (cdr lst))))) (sb-data sound-buttons)) |# (define (make-sound-button-pixmap dpy wn data width height) (if (pair? (sound-button-peaks data)) (let ((mins (car (sound-button-peaks data))) (maxes (cadr (sound-button-peaks data))) (gc (sound-button-gc data)) ;;(name (sound-button-filename data)) ) (let* ((secs (format #f "~,1F" (mus-sound-duration (sound-button-filename data)))) (size (XTextWidth button-fontstruct secs (length secs)))) (if (<= size width) (XDrawString dpy wn gc (- width size) height secs (length secs)))) (thumbnail-graph dpy wn gc mins width height) (thumbnail-graph dpy wn gc maxes width height)))) (define (make-sound-icon filename parent peak-func gc width height args) (define (cast-to-window n) (list 'Window (cadr n))) (let* ((dpy (XtDisplay parent)) (win (XtWindow parent)) (pix (XCreatePixmap dpy win width height (screen-depth))) (str (XmStringCreateLocalized filename)) (data (list gc filename #f (channel-amp-envs filename 0 width peak-func)))) (XSetForeground dpy gc *basic-color*) (XFillRectangle dpy (cast-to-window pix) gc 0 0 width height) (XSetForeground dpy gc *data-color*) (make-sound-button-pixmap dpy (cast-to-window pix) data width height) (let ((icon (XtCreateManagedWidget filename xmIconGadgetClass parent (append (list XmNbackground *basic-color* XmNforeground *data-color* XmNlabelString str XmNlargeIconPixmap pix XmNsmallIconPixmap pix) args)))) (set! (sound-button data) icon) (set! sound-buttons (cons data sound-buttons)) icon))) ;; now the actual sound-box maker (lambda (name parent select-func peak-func snds args) ;; select-func called when sound selected and passed sound file name ;; peak-func (if any) tells icon where to find peak-env-info-file (if any) ;; snds is list of sound file names ;; args is list of resource settings for each icon ;; (make-sound-box name parent select-func peak-func sounds args) makes a box of sound icons (let ((container (XtCreateManagedWidget name xmContainerWidgetClass parent (list XmNlayoutType XmSPATIAL XmNspatialResizeModel XmGROW_BALANCED XmNbackground (white-pixel) XmNentryViewType XmANY_ICON XmNlargeCellWidth 120)))) (XtVaSetValues parent (list XmNworkWindow container)) (XtAddCallback container XmNselectionCallback (lambda (w c i) (if (and (= (.auto_selection_type i) XmAUTO_BEGIN) ; just click to select for now (pair? (.selected_items i))) (select-func (XtName (car (.selected_items i))))))) (for-each (lambda (file) (make-sound-icon file container peak-func gc 96 64 args)) snds) container))))) (define show-sounds-in-directory (let ((documentation "(show-sounds-in-directory (dir \".\")) calls make-sound-box with the given directory")) (lambda* ((dir ".")) (make-sound-box "sounds" (XtCreateManagedWidget "scrolled-window" xmScrolledWindowWidgetClass ((main-widgets) 3) (list XmNscrollBarDisplayPolicy XmAS_NEEDED XmNbackground *basic-color* XmNvisualPolicy XmVARIABLE XmNscrollingPolicy XmAUTOMATIC)) open-sound (lambda (file chn) (format #f "~~/peaks/~A-peaks-~D" (xm-clean-string (file-name file)) chn)) (sound-files-in-directory dir) ())))) #| ;;; -------- show-smpte-label ;;; ;;; (show-smpte-label on-or-off) ;;; turns on/off a label in the time-domain graph showing the current smpte frame of the leftmost sample ;;; this is now built-in under with-smpte-label (define smpte-frames-per-second 24.0) (define draw-smpte-label (let* ((dpy (XtDisplay (cadr (main-widgets)))) (fs (XLoadQueryFont dpy *axis-numbers-font*)) (width (+ 8 (XTextWidth fs "00:00:00:00" 11))) (height (+ 8 (caddr (XTextExtents fs "0" 1))))) (define (smpte-label samp sr) (define (round-down val) (truncate val)) (let* ((seconds (/ samp sr)) (len (* seconds smpte-frames-per-second)) (minutes (round-down (/ seconds 60))) (hours (round-down (/ minutes 60)))) (format #f "~2,'0D:~2,'0D:~2,'0D:~2,'0D" hours (- minutes (* hours 60)) (round-down (- seconds (* minutes 60))) (round-down (- len (* (round-down seconds) smpte-frames-per-second)))))) (let ((documentation "(draw-smpte-label snd chn) draws a SMPTE time stamp in a box on a graph")) (lambda (hook) (let ((snd (hook 'snd)) (chn (hook 'chn))) (let* ((axinf (axis-info snd chn)) (x (axinf 10)) (y (axinf 13)) (grf-width (- (axinf 12) x)) (grf-height (- (axinf 11) y))) (if (and (> grf-height (* 2 height)) (> grf-width (* 1.5 width)) (time-graph? snd chn)) (let* ((smpte (smpte-label (car axinf) (srate snd))) (samp (car axinf))) (fill-rectangle x y width 2 snd chn) (fill-rectangle x (+ y height) width 2 snd chn) (fill-rectangle x y 2 height snd chn) (fill-rectangle (+ x width -2) y 2 height snd chn) (if (and fs (.fid fs)) (XSetFont dpy (if (= chn (selected-channel snd)) (cadr (snd-gcs)) (car (snd-gcs))) (.fid fs))) (draw-string smpte (+ x 4) (+ y 4) snd chn))))))))) (define show-smpte-label (let ((documentation "(show-smpte-label on-or-off) turns on/off a label in the time-domain graph showing the current smpte frame of the leftmost sample")) (lambda arg (if (or (null? arg) (car arg)) (if (not (member draw-smpte-label (hook-functions after-graph-hook))) (begin (hook-push after-graph-hook draw-smpte-label) (update-time-graph #t #t))) (begin (hook-remove after-graph-hook draw-smpte-label) (update-time-graph #t #t)))))) (define smpte-is-on ; for prefs dialog (let ((documentation "(smpte-is-on) is #t if we are drawing SMPTE time stamps")) (lambda () (member draw-smpte-label (hook-functions after-graph-hook))))) |# (define red-pixel (let ((pix #f) (documentation "(red-pixel) returns a red pixel")) (lambda () (if (not pix) (let* ((shell (cadr (main-widgets))) (dpy (XtDisplay shell)) (scr (DefaultScreen dpy)) (cmap (DefaultColormap dpy scr)) (col (XColor))) (if (= (XAllocNamedColor dpy cmap "red" col col) 0) (snd-error "can't allocate red!") (set! pix (.pixel col))))) pix))) #| ;;; -------- with-level-meters, make-level-meter, display-level (define make-level-meter (let ((documentation "(make-level-meter parent width height args (resizable #t)) makes a VU level meter")) (lambda* (parent width height args (resizable #t)) (let* ((frame (XtCreateManagedWidget "meter-frame" xmFrameWidgetClass parent (append (list XmNshadowType XmSHADOW_ETCHED_IN XmNwidth width XmNheight height XmNshadowThickness (if (> width 500) 6 3)) args))) (meter (XtCreateManagedWidget "meter" xmDrawingAreaWidgetClass frame (if resizable (list XmNbackground (white-pixel) XmNforeground (black-pixel) XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_FORM XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM) (list XmNbackground (white-pixel) XmNforeground (black-pixel) XmNwidth width XmNheight height XmNresizePolicy XmRESIZE_NONE XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_FORM XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM)))) (context (list meter 0.0 1.0 0.0 0.0 width height))) (XtAddCallback meter XmNexposeCallback (lambda (w c i) (display-level c)) context) (if resizable (XtAddCallback meter XmNresizeCallback (lambda (w c i) (set! (c 5) (cadr (XtGetValues w (list XmNwidth 0)))) (set! (c 6) (cadr (XtGetValues w (list XmNheight 0)))) (display-level c)) context)) context)))) (define display-level (let ((documentation "(display-level meter-data) displays a VU level meter")) (lambda (meter-data) (let* ((meter (car meter-data)) (level (meter-data 1)) (last-level (meter-data 3)) (red-deg (meter-data 4)) (width (meter-data 5)) (height (meter-data 6)) ;; (size (meter-data 2)) (dpy (XtDisplay meter)) (win (XtWindow meter)) (major-tick (round (/ width 24))) (minor-tick (round (* major-tick .6))) (ang0 (* 45 64)) (ang1 (* 90 64)) (wid2 (floor (/ width 2))) (gc (car (snd-gcs))) (top (round (/ height 3.2)))) ; distance of label from top of meter (if (and (> top 10) (> width 10) (> height 10)) (begin (XSetForeground dpy gc (white-pixel)) (XFillRectangle dpy win gc 0 0 width height) (XSetForeground dpy gc (black-pixel)) (XDrawArc dpy win gc 0 top width width ang0 ang1) (XDrawArc dpy win gc 0 (- top 1) width width ang0 ang1) (if (> width 100) (XDrawArc dpy win gc 0 (- top 2) width width ang0 ang1)) (XDrawArc dpy win gc 4 (+ top 4) (- width 8) (- width 8) ang0 ang1) (do ((i 0 (+ i 1))) ((= i 5)) (let* ((rdeg (degrees->radians (- 45 (* i 22.5)))) (sinr (sin rdeg)) (cosr (cos rdeg)) (x0 (round (+ wid2 (* wid2 sinr)))) (y0 (round (- (+ wid2 top) (* wid2 cosr)))) (x1 (round (+ wid2 (* (+ wid2 major-tick) sinr)))) (y1 (round (- (+ wid2 top) (* (+ wid2 major-tick) cosr))))) (XDrawLine dpy win gc x0 y0 x1 y1) (XDrawLine dpy win gc (+ x0 1) y0 (+ x1 1) y1) (if (< i 4) (do ((j 1 (+ 1 j))) ((= j 6)) (let* ((rdeg (degrees->radians (- 45 (* i 22.5) (* j (/ 90.0 20.0))))) (sinr (sin rdeg)) (cosr (cos rdeg)) (x0 (round (* wid2 (+ 1.0 sinr)))) (y0 (round (- (+ wid2 top) (* wid2 cosr)))) (x1 (round (+ wid2 (* (+ wid2 minor-tick) sinr)))) (y1 (round (- (+ wid2 top) (* (+ wid2 minor-tick) cosr))))) (XDrawLine dpy win gc x0 y0 x1 y1)))))) (let* ((needle-speed 0.25) (bubble-speed 0.025) (bubble-size (* 15 64)) (val (+ (* level needle-speed) (* last-level (- 1.0 needle-speed)))) (deg (- (* val 90.0) 45.0)) (rdeg (degrees->radians deg)) (nx1 (round (+ wid2 (* (+ wid2 major-tick) (sin rdeg))))) (ny1 (round (- (+ wid2 top) (* (+ wid2 major-tick) (cos rdeg)))))) (XDrawLine dpy win gc wid2 (+ top wid2) nx1 ny1) (set! (meter-data 3) val) (if (> val red-deg) (set! (meter-data 4) val) (set! (meter-data 4) (+ (* val bubble-speed) (* red-deg (- 1.0 bubble-speed))))) (if (> (meter-data 4) .01) (begin (XSetForeground dpy gc (red-pixel)) (let* ((redx (floor (* (meter-data 4) 90 64))) (redy (min redx bubble-size))) (do ((i 0 (+ i 1))) ((= i 4)) (XDrawArc dpy win gc i (+ top i) (- width (* i 2)) (- width (* i 2)) (- (* 135 64) redx) redy)) (XSetForeground dpy gc (black-pixel)))))))))))) (define with-level-meters (let ((documentation "(with-level-meters n) adds 'n' level meters to a pane at the top of the Snd window")) (lambda (n) (let* ((parent ((main-widgets) 3)) (height 70) (width (floor (/ (cadr (XtGetValues parent (list XmNwidth 0))) n))) (meters (XtCreateManagedWidget "meters" xmFormWidgetClass parent (list XmNpositionIndex 0 ; top pane XmNbackground *basic-color* XmNfractionBase (* n 10) XmNpaneMinimum height))) (meter-list ())) (do ((i 0 (+ i 1))) ((= i n)) (set! meter-list (cons (make-level-meter meters width height (list XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_FORM XmNleftAttachment XmATTACH_POSITION XmNleftPosition (* i 10) XmNrightAttachment XmATTACH_POSITION XmNrightPosition (* (+ 1 i) 10))) meter-list))) (hook-push dac-hook (lambda (hook) (let ((maxes (map float-vector-peak (hook 'data)))) (for-each (lambda (meter) (if (null? maxes) (set! (meter 1) 0.0) (begin (set! (meter 1) (car maxes)) (display-level meter) (set! maxes (cdr maxes))))) (reverse meter-list))))) (hook-push stop-dac-hook (lambda (hook) ; drain away the bubble (XtAppAddWorkProc (car (main-widgets)) (let ((ctr 0)) (lambda (ignored) (for-each (lambda (meter) (set! (meter 1) 0.0) (display-level meter)) meter-list) (set! ctr (+ ctr 1)) (> ctr 200)))))) (XtSetValues meters (list XmNpaneMinimum 1)) meter-list)))) |# ;;; -------- add a drop site ;;; ;;; this adds a pane to the current channel which can respond to drag-and-drop operations ;;; (this is a Motif 1.2 style drop -- I've had trouble getting the new style to work at all) (define make-channel-drop-site (let ((documentation "(make-channel-drop-site snd) adds a drop site pane to the current channel")) (lambda args (let* ((snd (if (> (length args) 0) (car args) (selected-sound))) (chn (selected-channel snd)) (widget (add-channel-pane snd chn "drop here" xmDrawingAreaWidgetClass (list XmNbackground (white-pixel) XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_FORM)))) (XmDropSiteRegister widget (list XmNdropSiteOperations XmDROP_COPY XmNimportTargets (list XA_STRING) ; list of Atoms we can deal with -- in this case, just strings XmNnumImportTargets 1 XmNdropProc (lambda (w c i) ;; i is the callback data (XmDropProcCallbackStruct), c is always #f (if (or (not (= (.dropAction i) XmDROP)) (not (= (.operation i) XmDROP_COPY))) (set! (.dropSiteStatus i) XmINVALID_DROP_SITE) (begin (set! (.operation i) XmDROP_COPY) ; tell system drop has succeeded (XmDropTransferStart (.dragContext i) (list XmNdropTransfers (list XA_STRING) XmNnumDropTransfers 1 XmNtransferProc (lambda (w context selection type val len fmt) ;; the actual in-coming string (properly terminated in xm.c) is 'value' (snd-print (format #f "got: ~A ~A ~A ~A ~A ~A ~A~%" w context selection type val len fmt)))))))))))))) ;;; -------- change a drop callback ;;; ;;; drop arg is 3-arg func: filename snd chn (define set-channel-drop (let ((documentation "(set-channel-drop drop snd chn) changes a drop callback function; 'drop' is function of 3 args (filename snd chn)")) (lambda (drop snd chn) (XmDropSiteUpdate (car (channel-widgets snd chn)) (list XmNdropProc (lambda (w c i) (if (or (not (= (.dropAction i) XmDROP)) (not (= (.operation i) XmDROP_COPY))) (set! (.dropSiteStatus i) XmINVALID_DROP_SITE) (begin (set! (.operation i) XmDROP_COPY) (XmDropTransferStart (.dragContext i) (list XmNdropTransfers (list (XInternAtom (XtDisplay (cadr (main-widgets))) "FILE_NAME" #f)) ;; this is saying that the in-coming drag-and-drop is expected to pass us a FILE_NAME atom ;; to find out what Atoms the selection translator can handle, use ;; (XtVaGetValues (.dragContext i) (list XmNexportTargets 0)) ;; which will return a list of acceptable Atoms XmNnumDropTransfers 1 XmNtransferProc (lambda (w context selection type val len fmt) (drop val snd chn)))))))))))) ;;; -------- show-disk-space ;;; ;;; adds a label to the status-area area showing the current free space (define showing-disk-space #f) ; for prefs dialog (define show-disk-space (let ((labelled-snds ())) (define (kmg num) (if (<= num 0) "disk full!" (if (> num 1024) (if (> num (* 1024 1024)) (format #f "space: ~6,3FG" (/ num (* 1024.0 1024.0))) (format #f "space: ~6,3FM" (/ num 1024.0))) (format #f "space: ~10DK" num)))) (define (show-label data id) (if (sound? (car data)) (let* ((space (kmg (disk-kspace (file-name (car data))))) (str (XmStringCreateLocalized space))) (XtSetValues (cadr data) (list XmNlabelString str)) (XmStringFree str) (XtAppAddTimeOut (caddr data) 10000 show-label data)))) (let ((documentation "(show-disk-space snd) adds a label to snd's status-area area showing the current free space (for use with after-open-hook)")) (lambda (hook) (let* ((snd (hook 'snd)) (previous-label (find-if (lambda (n) (equal? (car n) snd)) labelled-snds))) (if (not previous-label) (if (not snd) (snd-error "no sound found for disk space label") (let* ((app (car (main-widgets))) (widgets (sound-widgets snd)) (status-area (widgets 3)) (unite-button (widgets 6)) (sync-button (widgets 9)) (name-form (XtParent status-area)) ; "snd-name-form" (space (kmg (disk-kspace (file-name snd)))) (str (XmStringCreateLocalized space))) (set! showing-disk-space #t) (XtUnmanageChild status-area) (XtVaSetValues status-area (list XmNrightAttachment XmATTACH_NONE)) (let ((new-label (XtCreateManagedWidget "space:" xmLabelWidgetClass name-form (list XmNbackground *basic-color* XmNleftAttachment XmATTACH_NONE XmNlabelString str XmNrightAttachment XmATTACH_WIDGET XmNrightWidget (if (XtIsManaged unite-button) unite-button sync-button) XmNtopAttachment XmATTACH_FORM)))) (XtVaSetValues status-area (list XmNrightWidget new-label XmNrightAttachment XmATTACH_WIDGET)) (XtManageChild status-area) (XmStringFree str) (set! previous-label (list snd new-label app)) (set! labelled-snds (cons previous-label labelled-snds)) (XtAppAddTimeOut (caddr previous-label) 10000 show-label previous-label)))))))))) ;;; -------- add amp sliders in control panel for multi-channel sounds ;;; ;;; use control-button to move all at once ;;; ;;; the max scrollbar value can change (it's now 10000), so ideally this code should notice it (define add-amp-controls (let ((documentation "(add-amp-controls) adds amplitude sliders to the control panel for each channel in multi-channel sounds")) (lambda () (define (label-name chan) (if (= chan 0) "amp-label" (format #f "amp-label-~D" chan))) (define (number-name chan) (if (= chan 0) "amp-number" (format #f "amp-number-~D" chan))) (define (scroller-name chan) (if (= chan 0) "amp" (format #f "amp-~D" chan))) (define (amp->scroll minval val maxval) (if (<= val minval) 0 (if (>= val maxval) 9000 (if (>= val 1.0) (floor (* 4500 (+ 1.0 (/ (- val 1.0) (- maxval 1.0))))) (floor (* 4500 (/ (- val minval) (- 1.0 minval)))))))) (define (scroll->amp snd val) (if (<= val 0) (car (amp-control-bounds snd)) (if (>= val 9000) (cadr (amp-control-bounds snd)) (if (> val 4500) (+ (* (- (/ val 4500.0) 1.0) (- (cadr (amp-control-bounds snd)) 1.0)) 1.0) (+ (* val (/ (- 1.0 (car (amp-control-bounds snd))) 4500.0)) (car (amp-control-bounds snd))))))) (define (amp-callback w c info) ;; c is (list number-widget snd chan) (let* ((snd (cadr c)) (amp (scroll->amp snd (.value info))) (ampstr (XmStringCreateLocalized (format #f "~,3F " amp))) (top-chn (- (channels snd) 1)) (chn (- top-chn (caddr c))) (ctrl (and (.event info) (not (= (logand (.state (.event info)) ControlMask) 0))))) (XtSetValues (car c) (list XmNlabelString ampstr)) (XmStringFree ampstr) (if ctrl (let* ((wids (sound-widgets snd)) (ctrls (wids 2)) (snd-amp (find-child ctrls "snd-amp")) (chns (channels snd))) (do ((i 0 (+ i 1))) ((= i chns)) (let* ((ampscr (find-child snd-amp (scroller-name i))) (ampvals (XmScrollBarGetValues ampscr))) (XmScrollBarSetValues ampscr (.value info) (cadr ampvals) (caddr ampvals) (cadddr ampvals) #t) (set! (amp-control snd i) amp)))) (set! (amp-control snd chn) amp)))) (define (reset-to-one scroller number) (XtSetValues scroller (list XmNvalue 4500)) (let ((ampstr (XmStringCreateLocalized "1.000 "))) (XtSetValues number (list XmNlabelString ampstr)) (XmStringFree ampstr))) (define (make-amp-control snd chan parent) (let* ((s1 (XmStringCreateLocalized "amp:")) (label (XtCreateManagedWidget (label-name chan) xmPushButtonWidgetClass parent (list XmNbackground *basic-color* XmNalignment XmALIGNMENT_BEGINNING XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_NONE XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_NONE XmNlabelString s1 XmNmarginHeight 1 XmNrecomputeSize #f XmNshadowThickness 0 XmNhighlightThickness 0 XmNfillOnArm #f))) (s2 (XmStringCreateLocalized "1.000 ")) (number (XtCreateManagedWidget (number-name chan) xmLabelWidgetClass parent (list XmNbackground *basic-color* XmNalignment XmALIGNMENT_BEGINNING XmNtopAttachment XmATTACH_OPPOSITE_WIDGET XmNtopWidget label XmNbottomAttachment XmATTACH_NONE XmNleftAttachment XmATTACH_WIDGET XmNleftWidget label XmNrightAttachment XmATTACH_NONE XmNlabelString s2 XmNmarginHeight 1 XmNmarginRight 3 XmNrecomputeSize #f))) (scroll (XtCreateManagedWidget (scroller-name chan) xmScrollBarWidgetClass parent (list XmNbackground *position-color* XmNtopAttachment XmATTACH_OPPOSITE_WIDGET XmNtopWidget label XmNbottomAttachment XmATTACH_NONE XmNheight 16 XmNleftAttachment XmATTACH_WIDGET XmNleftWidget number XmNrightAttachment XmATTACH_FORM XmNorientation XmHORIZONTAL XmNmaximum 10000 XmNvalue 4500 XmNdragCallback (list amp-callback (list number snd chan)) XmNvalueChangedCallback (list amp-callback (list number snd chan)))))) (XtOverrideTranslations scroll (XtParseTranslationTable "c: Select() c: Moved() c: Release()")) (XtAddCallback label XmNactivateCallback (lambda (w c i) (reset-to-one scroll number))) (XmStringFree s1) (XmStringFree s2) label)) (define (amp-controls-reflect-chans snd) (let* ((wids (sound-widgets snd)) (ctrls (wids 2)) (snd-amp (find-child ctrls "snd-amp")) (chns (channels snd))) (if (Widget? snd-amp) (let ((height (cadr (XtGetValues ctrls (list XmNheight 0)))) (panemin (cadr (XtGetValues ctrls (list XmNpaneMinimum 0)))) (panemax (cadr (XtGetValues ctrls (list XmNpaneMaximum 0))))) (XtUnmanageChild ctrls) (if (not (sound-property 'amp-controls snd)) (let ((orig-amp (find-child snd-amp "amp"))) (XtOverrideTranslations orig-amp (XtParseTranslationTable "c: Select() c: Moved() c: Release()")) (XtAddCallback orig-amp XmNdragCallback (lambda (w c info) (if (and (.event info) (not (= (logand (.state (.event info)) ControlMask) 0))) (do ((i 1 (+ i 1))) ((= i chns)) (let* ((ampscr (find-child snd-amp (scroller-name i))) (ampvals (XmScrollBarGetValues ampscr))) (XmScrollBarSetValues ampscr (.value info) (cadr ampvals) (caddr ampvals) (cadddr ampvals) #t)))))))) (let ((existing-controls (or (sound-property 'amp-controls snd) 1))) (if (< existing-controls chns) (begin (if (> height 20) (set! height (+ height (* 18 (- chns existing-controls))))) (do ((i existing-controls (+ i 1))) ((= i chns)) (make-amp-control snd i snd-amp)) (set! (sound-property 'amp-controls snd) chns) (set! existing-controls chns))) (do ((i 0 (+ i 1))) ((= i existing-controls)) (let ((ampc (find-child snd-amp (label-name i))) (ampn (find-child snd-amp (number-name i))) (amp (find-child snd-amp (scroller-name i)))) (XtUnmanageChild ampc) (XtUnmanageChild ampn) (XtUnmanageChild amp))) (do ((i 0 (+ i 1))) ((= i chns)) (let ((ampc (find-child snd-amp (label-name i))) (ampn (find-child snd-amp (number-name i))) (amp (find-child snd-amp (scroller-name i))) (next-amp (and (< i (- chns 1)) (find-child snd-amp (label-name (+ i 1)))))) (reset-to-one amp ampn) (if next-amp (XtSetValues ampc (list XmNtopAttachment XmATTACH_WIDGET XmNtopWidget next-amp)) (XtSetValues ampc (list XmNtopAttachment XmATTACH_FORM))) (XtManageChild ampc) (XtManageChild ampn) (XtManageChild amp)))) (XtSetValues ctrls (list XmNpaneMinimum height XmNpaneMaximum height)) (XtManageChild ctrls) (XtSetValues ctrls (list XmNpaneMinimum panemin XmNpaneMaximum panemax)))))) (define (amp-controls-clear snd) (if (> (channels snd) 1) (let* ((wids (sound-widgets snd)) (ctrls (wids 2)) (snd-amp (find-child ctrls "snd-amp")) (top (- (channels snd) 1))) (do ((i 1 (+ i 1))) ((= i (channels snd))) (let ((ampn (find-child snd-amp (number-name i))) (amp (find-child snd-amp (scroller-name i)))) (reset-to-one amp ampn) (set! (amp-control snd (- top i)) 1.0)))))) (hook-push after-open-hook (lambda (hook) (amp-controls-reflect-chans (hook 'snd)))) (hook-push after-apply-controls-hook (lambda (hook) (amp-controls-clear (hook 'snd))))))) ;(add-amp-controls) ;;; -------- remove top level menu ;;; ;;; (remove-main-menu 5) removes the Help menu (define remove-main-menu (let ((documentation "(remove-main-menu menu) removes the specified top-level menu: (remove-main-menu 5) removes the Help menu")) (lambda (menu) (let* ((cascade ((menu-widgets) menu)) (top (cadr (XtGetValues cascade (list XmNsubMenuId 0))))) (XtUnmanageChild cascade) (XtUnmanageChild top))))) ;;; -------- add delete and rename options to the file menu (define add-delete-option (let ((documentation "(add-delete-option) adds a delete (file) option to the File menu")) (lambda () (add-to-menu 0 "Delete" ; add Delete option to File menu (lambda () ;; close current sound and delete it (if (selected-sound) (let ((filename (file-name))) (close-sound) (delete-file filename)))) 8)))) ; place after File:New (define add-rename-option (let ((documentation "(add-rename-option) adds a rename (file) option to the File menu")) (lambda () (let ((rename-dialog #f) (rename-text #f)) (add-to-menu 0 "Rename" (lambda () ;; open dialog to get new name, save-as that name, open (if (not rename-dialog) ;; make a standard dialog (let* ((xdismiss (XmStringCreate "Go Away" XmFONTLIST_DEFAULT_TAG)) (xhelp (XmStringCreate "Help" XmFONTLIST_DEFAULT_TAG)) (xok (XmStringCreate "DoIt" XmFONTLIST_DEFAULT_TAG)) (titlestr (XmStringCreate "Rename" XmFONTLIST_DEFAULT_TAG)) (new-dialog (XmCreateTemplateDialog (cadr (main-widgets)) "Rename" (list XmNcancelLabelString xdismiss XmNhelpLabelString xhelp XmNokLabelString xok XmNautoUnmanage #f XmNdialogTitle titlestr XmNresizePolicy XmRESIZE_GROW XmNnoResize #f XmNbackground *basic-color* XmNtransient #f)))) (for-each (lambda (button color) (XtVaSetValues (XmMessageBoxGetChild new-dialog button) (list XmNarmColor *selection-color* XmNbackground color))) (list XmDIALOG_HELP_BUTTON XmDIALOG_CANCEL_BUTTON XmDIALOG_OK_BUTTON) (list *highlight-color* *highlight-color* *highlight-color*)) (XtAddCallback new-dialog XmNcancelCallback (lambda (w c i) (XtUnmanageChild w))) (XtAddCallback new-dialog XmNhelpCallback (lambda (w c i) (help-dialog "Rename" "give a new file name to rename the currently selected sound"))) (XtAddCallback new-dialog XmNokCallback (lambda (w c i) (let ((new-name (XmTextFieldGetString rename-text))) (if (and (string? new-name) (> (length new-name) 0) (selected-sound)) (let ();(current-name (file-name))) (save-sound-as new-name) (close-sound) ;(rename-file current-name new-name) ; was this from Guile? ;(system (format #f "mv ~A ~A" new-name current-name)) ; surely it should be (delete-file current-name)? (open-sound new-name) (XtUnmanageChild w)))))) (XmStringFree xhelp) (XmStringFree xok) (XmStringFree xdismiss) (XmStringFree titlestr) (set! rename-dialog new-dialog) (let* ((mainform (XtCreateManagedWidget "formd" xmRowColumnWidgetClass rename-dialog (list XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_WIDGET XmNbottomWidget (XmMessageBoxGetChild rename-dialog XmDIALOG_SEPARATOR) XmNorientation XmVERTICAL XmNbackground *basic-color*))) (label (XtCreateManagedWidget "new name:" xmLabelWidgetClass mainform (list XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_NONE XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_FORM XmNbackground *basic-color*)))) (set! rename-text (XtCreateManagedWidget "newname" xmTextFieldWidgetClass mainform (list XmNleftAttachment XmATTACH_WIDGET XmNleftWidget label XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_FORM XmNbackground *basic-color*))) (XtAddEventHandler rename-text EnterWindowMask #f (lambda (w context ev flag) (XmProcessTraversal w XmTRAVERSE_CURRENT) (XtSetValues w (list XmNbackground (white-pixel))))) (XtAddEventHandler rename-text LeaveWindowMask #f (lambda (w context ev flag) (XtSetValues w (list XmNbackground *basic-color*))))))) (if (not (XtIsManaged rename-dialog)) (XtManageChild rename-dialog) (raise-dialog rename-dialog))) 8))))) (define change-label (let ((documentation "(change-label widget new-label) changes widget's label to new-label")) (lambda (widget new-label) (let ((str (XmStringCreateLocalized new-label))) (XtSetValues widget (list XmNlabelString str)) (XmStringFree str))))) ;;; this deletes the play button ;(hook-push after-open-hook ; (lambda (hook) ; (let* ((ctrls ((sound-widgets (hook 'snd)) 2)) ; (play-button (find-child ctrls "play")) ; (sync-button (find-child ctrls "sync"))) ; (XtUnmanageChild play-button) ; (XtVaSetValues sync-button (list XmNrightAttachment XmATTACH_FORM))))) ;;; -------- mark-sync-color ;;; ;;; (mark-sync-color "blue") (define mark-sync-color (let ((documentation "(mark-sync-color new-color) sets the color for sync'd marks")) (lambda (new-color) (define get-color (lambda (color-name) (let* ((col (XColor)) (dpy (XtDisplay (cadr (main-widgets)))) (scr (DefaultScreen dpy)) (cmap (DefaultColormap dpy scr))) (if (= (XAllocNamedColor dpy cmap color-name col col) 0) (snd-error (format #f "can't allocate ~A" color-name)) (.pixel col))))) (let ((mark-gc ((snd-gcs) 9)) (selected-mark-gc ((snd-gcs) 10)) (dpy (XtDisplay (cadr (main-widgets)))) (original-mark-color (list 'Pixel (logxor (cadr *mark-color*) (cadr *graph-color*)))) (original-selected-mark-color (list 'Pixel (logxor (cadr *mark-color*) (cadr *selected-graph-color*)))) (new-mark-color (list 'Pixel (logxor (cadr *graph-color*) (cadr (get-color new-color))))) (new-selected-mark-color (list 'Pixel (logxor (cadr *selected-graph-color*) (cadr (get-color new-color)))))) (if (pair? (hook-functions draw-mark-hook)) (set! (hook-functions draw-mark-hook) ())) (hook-push draw-mark-hook (lambda (hook) (if (> (sync (hook 'id)) 0) (begin (XSetForeground dpy mark-gc new-mark-color) (XSetForeground dpy selected-mark-gc new-selected-mark-color)) (begin (XSetForeground dpy mark-gc original-mark-color) (XSetForeground dpy selected-mark-gc original-selected-mark-color))) #f)))))) ;;; -------- add "tooltip" to a widget ;;; ;;; (add-tooltip (cadr (channel-widgets)) "the w button") (define tooltip-shell #f) (define tooltip-label #f) (define add-tooltip (let ((documentation "(add-tooltip widget tip) adds the tooltip 'tip' to the widget")) (lambda (widget tip) (let ((tool-proc #f) (quit-proc #f) (timeout 500) ; millisecs after mouse enters widget to tip display (quittime 3000) ; millisecs to show tip (if pointer not already moved out of widget) (last-time 0)) ; try to squelch "fluttering" (define (stop-tooltip) (if tool-proc (begin (XtRemoveTimeOut tool-proc) (set! tool-proc #f))) (if quit-proc (begin (XtRemoveTimeOut quit-proc) (set! quit-proc #f))) (if (and tooltip-shell (XtIsManaged tooltip-shell)) (XtUnmanageChild tooltip-shell))) (define (start-tooltip ev) (if (and *with-tooltips* (not tool-proc)) (set! tool-proc (XtAppAddTimeOut (car (main-widgets)) timeout (lambda (data id) (if (not tooltip-shell) (begin (set! tooltip-shell (XtCreatePopupShell tip overrideShellWidgetClass (cadr (main-widgets)) (list XmNallowShellResize #t))) (set! tooltip-label (XtCreateManagedWidget tip xmLabelWidgetClass tooltip-shell (list XmNrecomputeSize #t XmNbackground *highlight-color*)))) (change-label tooltip-label tip)) (let ((loc (XtTranslateCoords widget (.x ev) (.y ev)))) (XtVaSetValues tooltip-shell (list XmNx (car loc) XmNy (cadr loc)))) (XtManageChild tooltip-shell) (set! quit-proc (XtAppAddTimeOut (car (main-widgets)) quittime (lambda (data id) (XtUnmanageChild tooltip-shell) (set! quit-proc #f))))))))) (XtAddEventHandler widget EnterWindowMask #f (lambda (w c ev flag) (if (> (- (cadr (.time ev)) last-time) 50) (start-tooltip ev)) (set! last-time (cadr (.time ev))))) (XtAddEventHandler widget LeaveWindowMask #f (lambda (w c ev flag) (set! last-time (cadr (.time ev))) (stop-tooltip))))))) (define menu-option (let ((documentation "(menu-option name) finds the widget associated with a given menu item name")) (lambda (name) (call-with-exit (lambda (return) (for-each (lambda (top-menu) (for-each-child top-menu (lambda (w) (let ((option-holder (cadr (XtGetValues w (list XmNsubMenuId 0))))) (for-each-child option-holder (lambda (menu) (if (string=? name (XtName menu)) (return menu) (if (XmIsCascadeButton menu) (let ((options (cadr (XtGetValues menu (list XmNsubMenuId 0))))) (for-each-child options (lambda (inner-menu) (if (string=? name (XtName inner-menu)) (return inner-menu))))))))))))) (cdr (menu-widgets))) (throw 'no-such-menu (list "menu-option" name))))))) (define show-all-atoms (let ((documentation "(show-all-atoms) displays all current X atom names")) (lambda () (let ((i 1) (dpy (XtDisplay (cadr (main-widgets)))) (happy #t)) (XSetErrorHandler (lambda (dpy err) (set! happy #f))) (while happy (let ((name (XGetAtomName dpy (list 'Atom i)))) (if (string? name) (format #t "~D: ~A~%" i name) (set! happy #f))) (set! i (+ i 1))) (XSetErrorHandler #f))))) ;;; -------- enable C-s and C-r in listener (define add-find-to-listener (let ((dialog #f) (find-text #f) (find-forward #t) (find-new #t) (listener-text ((main-widgets) 4)) (shell (cadr (main-widgets))) (snd-app (car (main-widgets)))) (lambda () (define (start-dialog) (if (not dialog) (let ((xdismiss (XmStringCreate "Go Away" XmFONTLIST_DEFAULT_TAG)) (xhelp (XmStringCreate "Help" XmFONTLIST_DEFAULT_TAG)) (xfind (XmStringCreate "Find" XmFONTLIST_DEFAULT_TAG))) (set! dialog (XmCreateMessageDialog shell "Find" (list XmNcancelLabelString xdismiss XmNokLabelString xfind XmNhelpLabelString xhelp XmNautoUnmanage #f XmNresizePolicy XmRESIZE_GROW XmNnoResize #f XmNtransient #f XmNbackground *basic-color*))) (for-each (lambda (button color) (XtVaSetValues (XmMessageBoxGetChild dialog button) (list XmNarmColor *selection-color* XmNbackground color))) (list XmDIALOG_HELP_BUTTON XmDIALOG_CANCEL_BUTTON XmDIALOG_OK_BUTTON) (list *highlight-color* *highlight-color* *highlight-color*)) (XtAddCallback dialog XmNcancelCallback (lambda (w context info) (XtUnmanageChild dialog))) (XtAddCallback dialog XmNhelpCallback (lambda (w context info) (help-dialog "Find" "no help yet"))) (XtAddCallback dialog XmNokCallback (lambda (w context info) (let* ((search-str (XmTextFieldGetString find-text)) (len (length search-str)) (pos (XmTextFindString listener-text (+ (XmTextGetCursorPosition listener-text) (if find-new 0 (if find-forward 1 -1))) search-str (if find-forward XmTEXT_FORWARD XmTEXT_BACKWARD)))) (if (not pos) (set! pos (XmTextFindString listener-text (if find-forward 0 (XmTextGetLastPosition listener-text)) search-str (if find-forward XmTEXT_FORWARD XmTEXT_BACKWARD)))) (if (number? pos) (begin (XmTextSetInsertionPosition listener-text pos) (XmTextSetHighlight listener-text pos (+ pos len) XmHIGHLIGHT_SELECTED) ; flash the string briefly (XtAppAddTimeOut snd-app 200 (lambda (context id) (XmTextSetHighlight listener-text pos (+ pos len) XmHIGHLIGHT_NORMAL))))) (set! find-new #f)))) (XmStringFree xhelp) (XmStringFree xdismiss) (XmStringFree xfind) (set! find-text (XtCreateManagedWidget "text" xmTextFieldWidgetClass dialog (list XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_WIDGET XmNbottomWidget (XmMessageBoxGetChild dialog XmDIALOG_SEPARATOR) XmNbackground *basic-color*))) (XtAddCallback find-text XmNfocusCallback (lambda (w c i) (XtVaSetValues w (list XmNbackground (WhitePixelOfScreen (DefaultScreenOfDisplay (XtDisplay shell))))))) (XtAddCallback find-text XmNlosingFocusCallback (lambda (w c i) (XtSetValues w (list XmNbackground *basic-color*)))) (XtAddCallback find-text XmNvalueChangedCallback (lambda (w c i) (set! find-new #t))))) (XtManageChild dialog)) (XtAppAddActions snd-app (list (list "search-forward" (lambda args (set! find-forward #t) (start-dialog))) (list "search-backward" (lambda args (set! find-forward #f) (start-dialog))))) (XtOverrideTranslations listener-text (XtParseTranslationTable "Ctrl s: search-forward() Ctrl r: search-backward()"))))) ;;; -------- add a function to be called when the window manager sends us a "save yourself" or "take focus" message (define upon-save-yourself (let ((documentation "(upon-save-yourself thunk) causes 'thunk' to be called if a 'save yourself' message is received")) (lambda (thunk) (XmAddWMProtocolCallback (cadr (main-widgets)) (XmInternAtom (XtDisplay (cadr (main-widgets))) "WM_SAVE_YOURSELF" #f) (lambda (w c i) (thunk)) #f)))) ;;; similarly for "take focus" (define upon-take-focus (let ((documentation "(upon-take-focus thunk) causes 'thunk' to be called if a 'take focus' message is received")) (lambda (thunk) (XmAddWMProtocolCallback (cadr (main-widgets)) (XmInternAtom (XtDisplay (cadr (main-widgets))) "WM_TAKE_FOCUS" #f) (lambda (w c i) (thunk)) #f)))) ;;; -------- add text widget to notebook "status" area -------- (define add-text-to-status-area (let ((documentation "(add-text-to-status-area) adds a text widget to the notebook status area")) (lambda () ;; it might be a better use of this space to put dlp's icon row in it (let ((notebook ((main-widgets) 3))) (and (XmIsNotebook notebook) (let ((text (XtCreateManagedWidget "notebook-text" xmTextFieldWidgetClass notebook (list XmNbackground *basic-color*)))) (XtAddCallback text XmNfocusCallback (lambda (w c i) (XtSetValues w (list XmNbackground (white-pixel))))) (XtAddCallback text XmNlosingFocusCallback (lambda (w c i) (XtSetValues w (list XmNbackground *basic-color*)))) text)))))) ;;; -------- variable display panel -------- (define variables-dialog #f) (define variables-notebook #f) (define variables-pages ()) (define make-variables-dialog (let ((documentation "(make-variables-dialog) makes a variable-display dialog")) (lambda () (let ((xdismiss (XmStringCreate "Go Away" XmFONTLIST_DEFAULT_TAG)) (titlestr (XmStringCreate "Variables" XmFONTLIST_DEFAULT_TAG))) (set! variables-dialog (XmCreateTemplateDialog (cadr (main-widgets)) "variables-dialog" (list XmNokLabelString xdismiss XmNautoUnmanage #f XmNdialogTitle titlestr XmNresizePolicy XmRESIZE_GROW XmNnoResize #f XmNtransient #f XmNheight 400 XmNwidth 400 XmNbackground *basic-color*))) (XtVaSetValues (XmMessageBoxGetChild variables-dialog XmDIALOG_OK_BUTTON) (list XmNarmColor *selection-color* XmNbackground *highlight-color*)) (XtAddCallback variables-dialog XmNokCallback (lambda (w context info) (XtUnmanageChild variables-dialog))) (XmStringFree xdismiss) (XmStringFree titlestr) (set! variables-notebook (XtCreateManagedWidget "variables-notebook" xmNotebookWidgetClass variables-dialog (list XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_WIDGET XmNbottomWidget (XmMessageBoxGetChild variables-dialog XmDIALOG_SEPARATOR) XmNbackground *basic-color* XmNframeBackground *zoom-color* XmNbindingWidth 14))) (XtManageChild variables-dialog) variables-dialog)))) (define make-variable-display (let ((documentation "(make-variable-display page-name variable-name (type 'text) (range (list 0.0 1.0))) makes a variable \ display widget; type = 'text, 'meter, 'graph, 'spectrum, 'scale")) (lambda* (page-name variable-name (type 'text) (range (list 0.0 1.0))) (if (not (Widget? variables-dialog)) (make-variables-dialog)) ;; rowColumn widget gets confused by drawingareas, so I'll split them out into separate panes (let ((page-info (assoc page-name variables-pages))) (if (not page-info) (let* ((panes (XtCreateManagedWidget page-name xmPanedWindowWidgetClass variables-notebook ())) (simple-cases (XtCreateManagedWidget page-name xmRowColumnWidgetClass panes (list XmNorientation XmVERTICAL XmNpaneMinimum 30 XmNbackground *basic-color*)))) (set! page-info (list page-name panes simple-cases)) (XtCreateManagedWidget page-name xmPushButtonWidgetClass variables-notebook (list XmNnotebookChildType XmMAJOR_TAB XmNbackground *basic-color*)) (set! variables-pages (cons page-info variables-pages)))) (let ((row-pane (caddr page-info)) (pane (cadr page-info)) (var-label (string-append variable-name ":"))) (case type ((text) ;; add a horizontal pair: label text (let ((row (XtCreateManagedWidget (string-append variable-name "-row") xmRowColumnWidgetClass row-pane (list XmNorientation XmHORIZONTAL XmNbackground *basic-color*)))) (XtCreateManagedWidget var-label xmLabelWidgetClass row (list XmNbackground *basic-color*)) (XtCreateManagedWidget (string-append variable-name "-value") xmTextFieldWidgetClass row (list XmNeditable #f XmNresizeWidth #t XmNbackground (WhitePixelOfScreen (DefaultScreenOfDisplay (XtDisplay variables-dialog))))))) ((scale) ;; scale bar with red "thermometer" (let* ((title (XmStringCreate var-label XmFONTLIST_DEFAULT_TAG)) (scl (XtCreateManagedWidget variable-name xmScaleWidgetClass row-pane (list XmNbackground *basic-color* XmNslidingMode XmTHERMOMETER XmNminimum (floor (* 100 (car range))) XmNmaximum (floor (* 100 (cadr range))) XmNdecimalPoints 2 XmNtitleString title XmNorientation XmHORIZONTAL XmNshowValue XmNEAR_BORDER)))) (XtVaSetValues (find-child scl "Scrollbar") (list XmNtroughColor (red-pixel))) (XmStringFree title) scl)) #| ((meter) ;; using the level meters in snd-motif.scm (let ((height 70) (width 210)) (XtCreateManagedWidget var-label xmLabelWidgetClass row-pane (list XmNbackground *basic-color*)) (make-level-meter row-pane width height () #f))) |# ((graph) (let* ((form (XtCreateManagedWidget var-label xmFormWidgetClass pane (list XmNpaneMinimum 100))) (snd (make-variable-graph form (string-append variable-name ": time") 2048 (floor *clm-srate*)))) (list (sound->integer snd) (channel-data snd 0)))) ((spectrum) (let* ((form (XtCreateManagedWidget var-label xmFormWidgetClass pane (list XmNpaneMinimum 100))) (snd (make-variable-graph form variable-name 2048 (floor *clm-srate*)))) (set! (time-graph? snd 0) #f) (set! (transform-graph? snd 0) #t) (set! (x-axis-label snd 0 transform-graph) (string-append variable-name ": frequency")) (list (sound->integer snd) (channel-data snd 0)))) (else #f))))))) (define variable-display (let ((documentation "(variable-display var widget) displays the value of 'var' in 'widget'")) (lambda (var widget) (if (Widget? widget) (if (XmIsTextField widget) ;; text representation (let ((old-str (XmTextFieldGetString widget)) (new-str (object->string var))) (if (not (string=? old-str new-str)) (begin (XmTextFieldSetString widget new-str) (if (XtIsManaged widget) (XmUpdateDisplay widget))))) (if (XmIsScale widget) ;; thermometer (XmScaleSetValue widget (floor (* 100 var))))) (if (and (pair? widget) (or (number? (car widget)) (sound? (car widget)))) ;; graph/spectrum -- does this need an explicit update? (let* ((snd (car widget)) (data (cadr widget)) (len (length data)) (loc (cursor snd 0))) (set! (data loc) var) (if (time-graph? snd) (update-time-graph snd)) (if (transform-graph? snd) (update-transform-graph snd)) (if (= (+ loc 1) len) (set! (cursor snd 0) 0) (set! (cursor snd 0) (+ loc 1)))))) var))) (define variable-display-reset (let ((documentation "(variable-display-reset widget) restarts the variable graphs -- this is intended for the start (or perhaps end) of a note")) (lambda (widget) (if (and (pair? widget) (number? (car widget))) ;; graph/spectrum (let* ((snd (car widget)) (data (cadr widget)) (len (length data))) (set! (cursor snd 0) 0) (do ((i 0 (+ i 1))) ((= i len)) (vector-set! data 0 i 0.0))))))) #| (define wid (make-variable-display "do-loop" "i*2" 'text)) (define wid1 (make-variable-display "do-loop" "i" 'text)) (do ((i 0 (+ i 1))) ((= i 10)) (variable-display (* (variable-display i wid1) 2) wid)) (define wid2 (make-variable-display "a-loop" "k*2" 'meter)) ;(define wid3 (make-variable-display "a-loop" "k" 'scale '(0 40))) (do ((k 0 (+ k 1))) ((= k 11)) (variable-display (* k .02) wid2)) |# (define with-minmax-button (let ((maxed-snds ())) (lambda (snd) (let ((previous-minmax (find-if (lambda (n) (equal? (car n) snd)) maxed-snds))) (if (not previous-minmax) (let* ((widgets (sound-widgets snd)) (status-area (widgets 3)) (play-button (widgets 4)) (cur-size (cadr (XtVaGetValues (car widgets) (list XmNheight 0))))) (XtUnmanageChild play-button) (let* ((name-form (XtParent status-area)) ; "snd-name-form" (new-minmax (XtCreateManagedWidget "." xmPushButtonWidgetClass name-form (list XmNbackground *basic-color* XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_FORM XmNmarginWidth 2 XmNmarginHeight 0 XmNshadowThickness 0 )))) (XtVaSetValues play-button (list XmNrightAttachment XmATTACH_WIDGET XmNrightWidget new-minmax)) (XtManageChild play-button) (XtAddCallback new-minmax XmNactivateCallback (lambda (w c i) (let ((mv (find-if (lambda (n) (equal? (car n) c)) maxed-snds))) (if mv (let ((maxed (caddr mv))) (if maxed (begin (set! (mv 3) (cadr (XtVaGetValues (car (sound-widgets c)) (list XmNheight 0)))) (set! (mv 4) (show-controls c)) (do ((i 0 (+ i 1))) ((= i (channels c))) (XtUnmanageChild ((channel-widgets c i) 10))) (set! (show-controls c) #f) (XmChangeColor new-minmax (make-color 1 1 0)) (XtVaSetValues (car (sound-widgets c)) (list XmNpaneMaximum 25))) (let ((prev-size (mv 3))) (do ((i 0 (+ i 1))) ((= i (channels c))) (XtManageChild ((channel-widgets c i) 10))) (if (mv 4) (set! (show-controls c) #t)) (XmChangeColor new-minmax *basic-color*) (XtVaSetValues (car (sound-widgets c)) (list XmNpaneMaximum prev-size XmNpaneMinimum (- prev-size 1))) (XtVaSetValues (car (sound-widgets c)) (list XmNpaneMaximum 1000 XmNpaneMinimum 1)))) (set! (mv 2) (not maxed)))))) snd) (set! previous-minmax (list snd new-minmax #t cur-size (show-controls snd))) (set! maxed-snds (cons previous-minmax maxed-snds))))) #f)))) ;(hook-push after-open-hook (lambda (hook) (with-minmax-button (hook 'snd)))) #| (define set-root-window-color (let ((documentation "(set-root-window-color color) sets the color of the overall X background")) (lambda (color) (let* ((dpy (XtDisplay (cadr (main-widgets)))) (root-window (DefaultRootWindow dpy))) (XSetWindowBackground dpy root-window color) (XClearWindow dpy root-window))))) |# ;;; you can get a different scrollbar style with: ;;; (XtVaSetValues (XmGetXmDisplay (XtDisplay (cadr (main-widgets)))) (list XmNenableThinThickness #t)) ;;; get open file list across top of window (like Xemacs): use -notebook, then: ;;; this is now the default (define notebook-with-top-tabs (let ((documentation "(notebook-with-top-tabs) posts the list of open sounds across the top of the Snd window (like the Emacs buffer list)")) (lambda () (let ((nb ((main-widgets) 3))) (XtVaSetValues nb (list XmNorientation XmVERTICAL XmNbindingType XmNONE XmNbackPagePlacement XmTOP_RIGHT)))))) #| ;;; -------- create-ssb-dialog -------- ;;; ;;; this needs auto-pitch detection (define ssb-dialog #f) (define create-ssb-dialog (let ((documentation "(create-ssb-dialog) creates a dialog for testing the ssb-am stuff")) (lambda () (if (not (Widget? ssb-dialog)) (let ((xdismiss (XmStringCreate "Go Away" XmFONTLIST_DEFAULT_TAG)) (xhelp (XmStringCreate "Help" XmFONTLIST_DEFAULT_TAG)) (titlestr (XmStringCreate "SSB-Expand" XmFONTLIST_DEFAULT_TAG)) (running #f)) (set! ssb-dialog (XmCreateTemplateDialog (cadr (main-widgets)) "ssb-expand" (list XmNcancelLabelString xdismiss XmNhelpLabelString xhelp XmNautoUnmanage #f XmNdialogTitle titlestr XmNresizePolicy XmRESIZE_GROW XmNnoResize #f XmNbackground *basic-color* XmNwidth 400 XmNtransient #f) )) (XtAddCallback ssb-dialog XmNcancelCallback (lambda (w context info) (if running (set! running #f)) (XtUnmanageChild ssb-dialog))) (XtAddCallback ssb-dialog XmNhelpCallback (lambda (w context info) (snd-print "set 'play' and move the sliders!"))) (XmStringFree xhelp) (XmStringFree xdismiss) (XmStringFree titlestr) (let ((ratio 1.0) (old-freq 550.0) (new-freq 550.0) (hilbert-order 40) (ssb-pairs 10) (bw 50.0) (ssbs (make-vector 512)) (bands (make-vector 512)) (reader #f)) (letrec ((ssb-expand (lambda () (let ((sum 0.0) (sig (reader))) (do ((i 0 (+ i 1))) ((= i ssb-pairs) sum) (set! sum (+ sum (ssb-am (ssbs i) (fir-filter (bands i) sig)))))))) (set-freq (lambda (nfreq) (set! old-freq nfreq) (set! ratio (/ (- new-freq old-freq) old-freq)) (if running (do ((i 0 (+ i 1))) ((= i ssb-pairs)) (set! (mus-frequency (ssbs i)) (* (+ i 1) ratio old-freq)))))) (set-ratio (lambda (nfreq) (set! new-freq nfreq) (set! ratio (/ (- new-freq old-freq) old-freq)) (if running (do ((i 0 (+ i 1))) ((= i ssb-pairs)) (set! (mus-frequency (ssbs i)) (* (+ i 1) ratio old-freq)))))) (set-pairs (lambda (pairs) (set! ssb-pairs pairs))) (set-order (lambda (order) (set! hilbert-order order)))) (let* ((mainform (XtCreateManagedWidget "formd" xmRowColumnWidgetClass ssb-dialog (list XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_WIDGET XmNbottomWidget (XmMessageBoxGetChild ssb-dialog XmDIALOG_SEPARATOR) XmNbackground *basic-color* XmNorientation XmVERTICAL))) (button (XtCreateManagedWidget "play" xmToggleButtonWidgetClass mainform (list XmNbackground *basic-color*))) (freqstr (XmStringCreate "original freq" XmFONTLIST_DEFAULT_TAG)) (freq-scale (XtCreateManagedWidget "frq" xmScaleWidgetClass mainform (list XmNorientation XmHORIZONTAL XmNshowValue #t XmNbackground *basic-color* XmNvalue (floor old-freq) XmNmaximum 1000 XmNtitleString freqstr XmNdecimalPoints 0))) (ratiostr (XmStringCreate "new freq" XmFONTLIST_DEFAULT_TAG)) (ratio-scale (XtCreateManagedWidget "nfrq" xmScaleWidgetClass mainform (list XmNorientation XmHORIZONTAL XmNshowValue #t XmNbackground *basic-color* XmNvalue (floor new-freq) XmNmaximum 1000 XmNtitleString ratiostr XmNdecimalPoints 0))) (orderstr (XmStringCreate "order" XmFONTLIST_DEFAULT_TAG)) (order-scale (XtCreateManagedWidget "order" xmScaleWidgetClass mainform (list XmNorientation XmHORIZONTAL XmNshowValue #t XmNbackground *basic-color* XmNvalue hilbert-order XmNmaximum 100 XmNtitleString orderstr XmNdecimalPoints 0))) (pairsstr (XmStringCreate "ssbs" XmFONTLIST_DEFAULT_TAG)) (pairs-scale (XtCreateManagedWidget "pairs" xmScaleWidgetClass mainform (list XmNorientation XmHORIZONTAL XmNshowValue #t XmNbackground *basic-color* XmNvalue ssb-pairs XmNmaximum 100 XmNtitleString pairsstr XmNdecimalPoints 0)))) (XmStringFree freqstr) (XmStringFree ratiostr) (XmStringFree orderstr) (XmStringFree pairsstr) (XtAddCallback freq-scale XmNvalueChangedCallback (lambda (w context info) (set-freq (.value info)))) (XtAddCallback freq-scale XmNdragCallback (lambda (w context info) (set-freq (.value info)))) (XtAddCallback ratio-scale XmNvalueChangedCallback (lambda (w context info) (set-ratio (.value info)))) (XtAddCallback ratio-scale XmNdragCallback (lambda (w context info) (set-ratio (.value info)))) (XtAddCallback order-scale XmNvalueChangedCallback (lambda (w context info) (set-order (.value info)))) (XtAddCallback order-scale XmNdragCallback (lambda (w context info) (set-order (.value info)))) (XtAddCallback pairs-scale XmNvalueChangedCallback (lambda (w context info) (set-pairs (.value info)))) (XtAddCallback pairs-scale XmNdragCallback (lambda (w context info) (set-pairs (.value info)))) (XtAddCallback button XmNvalueChangedCallback (lambda (w context info) (if running (set! running #f) (let* ((audio-info (open-play-output 1 44100 #f 128)) (audio-fd (car audio-info)) (outchans (cadr audio-info)) (len (caddr audio-info)) (data (make-float-vector (list outchans len) 0.0))) (if (not (= audio-fd -1)) (begin (do ((i 1 (+ i 1))) ((> i ssb-pairs)) (let ((aff (* i old-freq)) (bwf (* bw (+ 1.0 (/ i (* 2 ssb-pairs)))))) (set! (ssbs (- i 1)) (make-ssb-am (* i ratio old-freq))) (set! (bands (- i 1)) (make-bandpass (hz->radians (- aff bwf)) (hz->radians (+ aff bwf)) hilbert-order)))) (set! reader (make-sampler 0)) (set! running #t) (do () ((or (not running) (sampler-at-end? reader)) (begin (XmToggleButtonSetValue button 0 #f) (set! running #f) (free-sampler reader) (mus-audio-close audio-fd))) (do ((k 0 (+ k 1))) ((= k len)) (vector-set! data 0 k (ssb-expand))) (mus-audio-write audio-fd data len))))))))))))) (XtManageChild ssb-dialog)))) ;;; -------- create-audit-dialog -------- ;;; ;;; amp + freq sliders up to 20KHz (define audit-dialog #f) (define create-audit-dialog (let ((documentation "(create-audit-dialog) creates a slightly dangerous hearing test dialog (don't push the amps way up if you can't hear anything)")) (lambda () (if (not (Widget? audit-dialog)) (let ((xdismiss (XmStringCreate "Go Away" XmFONTLIST_DEFAULT_TAG)) (xhelp (XmStringCreate "Help" XmFONTLIST_DEFAULT_TAG)) (titlestr (XmStringCreate "Hear Anything Yet?" XmFONTLIST_DEFAULT_TAG)) (running #f)) (set! audit-dialog (XmCreateTemplateDialog (cadr (main-widgets)) "audit" (list XmNcancelLabelString xdismiss XmNhelpLabelString xhelp XmNautoUnmanage #f XmNdialogTitle titlestr XmNresizePolicy XmRESIZE_GROW XmNnoResize #f XmNbackground *basic-color* XmNwidth 400 XmNtransient #f) )) (XtAddCallback audit-dialog XmNcancelCallback (lambda (w context info) (if running (set! running #f)) (XtUnmanageChild audit-dialog))) (XtAddCallback audit-dialog XmNhelpCallback (lambda (w context info) (snd-print "set 'play' and move the sliders!"))) (XmStringFree xhelp) (XmStringFree xdismiss) (XmStringFree titlestr) (set! *clm-srate* 44100) (let* ((frequency 440.0) (amplitude 0.1) (carrier (make-oscil frequency))) (letrec ((v (lambda () (* amplitude (oscil carrier))))) (let* ((mainform (XtCreateManagedWidget "formd" xmRowColumnWidgetClass audit-dialog (list XmNleftAttachment XmATTACH_FORM XmNrightAttachment XmATTACH_FORM XmNtopAttachment XmATTACH_FORM XmNbottomAttachment XmATTACH_WIDGET XmNbottomWidget (XmMessageBoxGetChild audit-dialog XmDIALOG_SEPARATOR) XmNbackground *basic-color* XmNorientation XmVERTICAL))) (button (XtCreateManagedWidget "play" xmToggleButtonWidgetClass mainform (list XmNbackground *basic-color*))) (ampstr (XmStringCreate "amp" XmFONTLIST_DEFAULT_TAG)) (amp-scale (XtCreateManagedWidget "amp" xmScaleWidgetClass mainform (list XmNorientation XmHORIZONTAL XmNshowValue #t XmNbackground *basic-color* XmNvalue (floor (* amplitude 100)) XmNmaximum 100 XmNtitleString ampstr XmNdecimalPoints 2))) (freqstr (XmStringCreate "freq" XmFONTLIST_DEFAULT_TAG)) (freq-scale (XtCreateManagedWidget "freq" xmScaleWidgetClass mainform (list XmNorientation XmHORIZONTAL XmNshowValue #t XmNbackground *basic-color* XmNvalue (floor frequency) XmNmaximum 20000 XmNtitleString freqstr XmNdecimalPoints 0)))) (XmStringFree ampstr) (XmStringFree freqstr) (XtAddCallback amp-scale XmNvalueChangedCallback (lambda (w context info) (set! amplitude (* .01 (.value info))))) (XtAddCallback amp-scale XmNdragCallback (lambda (w context info) (set! amplitude (* .01 (.value info))))) (XtAddCallback freq-scale XmNvalueChangedCallback (lambda (w context info) (set! (mus-frequency carrier) (.value info)))) (XtAddCallback freq-scale XmNdragCallback (lambda (w context info) (set! (mus-frequency carrier) (.value info)))) (XtAddCallback button XmNvalueChangedCallback (lambda (w context info) (if running (set! running #f) (let* ((audio-info (open-play-output 1 44100 #f 256)) (audio-fd (car audio-info)) (outchans (cadr audio-info)) (len (caddr audio-info)) (data (make-float-vector (list outchans len) 0.0))) (if (not (= audio-fd -1)) (begin (set! running #t) (do () ((not running) (begin (set! running #f) (mus-audio-close audio-fd))) (do ((k 0 (+ k 1))) ((= k len)) (vector-set! data 0 k (v))) (mus-audio-write audio-fd data len))))))))))))) (XtManageChild audit-dialog)))) |# ;;; -------- equalize-panes ;;; ;;; this used to be built-in, but never really worked right (define* (equalize-panes snd) (define (equalize-sound ind) (let ((old-style (channel-style ind))) (set! (channel-style ind) channels-combined) (set! (channel-style ind) old-style))) (if snd (equalize-sound snd) (for-each equalize-sound (sounds)))) ) ; end with-let *motif* snd-16.1/ws.rb0000644000076400007640000016324312476114577011340 0ustar bilbil# ws.rb -- with_sound and friends for Snd/Ruby # Copyright (c) 2003-2015 Michael Scholz # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # Created: 03/04/08 17:05:03 # Changed: 15/03/04 16:38:12 # module WS # ws_getlogin # ws_gethostname # ws_break(*rest) # with_sound(*args) do ... end # with_dac(*args) do ... end # with_snd(*args) do ... end # with_clm(*args) do ... end # with_full_sound(*args) do ... end # with_temp_sound(*args) do ... end # with_temp_snd(snd) do |temp_snd_file_name| ... end # clm_load(rbm_file, *args) # make_default_comment # remove_file(file) # each_sample(start, dur) do |samp| ... end # process_times # # class XenSound # name # length # update # revert # save # close # snd_file_name # snd_maxamp(chn, edpos) # snd_framples(chn, edpos) # snd_sample_type snd_sample_type=(v) # snd_header_type snd_header_type=(v) # snd_comment snd_comment=(v) # snd_srate snd_srate=(v) # snd_channels snd_channels=(v) # # class With_sound # initialize(*args, &body) # # properties: # output # file name (String) # out_snd # sound index (XenSound) # with_sound_note_hook # note hook (Hook) # # methods: # help (or description, info) # inspect # to_s # describe (show_local_variables) # with_sound(*args) do ... end # with_current_sound(*args) do ... end # scaled_to(scale) do ... end # scaled_by(scale) do ... end # with_offset(secs) do ... end # sound_let(*args) do |*sl_args| ... end # with_mix(*args, file[, beg_time], body_string) # with_sound_info(instrument_name, start, dur, binding) # run_instrument(start, dur, *locsig_args) do |samp| ... end # run_reverb do |ho, samp| ... end # run do ... end # clm_mix(infile, *args) # # class Instrument # ws_simp(start, dur, freq, amp, amp_env) # ws_violin(start, dur, freq, amp, fm_index, amp_env) # make_ws_reader(file, *args) # ws_readin(rd) # close_ws_reader(rd) # ws_location(rd) # set_ws_location(rd, v) # ws_increment(rd) # set_ws_increment(rd, v) # ws_srate(file) # ws_channels(file) # ws_duration(file) # # Instruments have access to @ws_output and @ws_reverb variables as # well as @srate, @channels, @reverb_channels etc. It is no longer # necessary (but possible) to use the global variables $output and # $reverb. # # The classes (Snd_|CLM_)Instrument are not really necessary, but the # name may be more clear if special instruments are added. # # With_sound # | # v # --- Instrument --- # | | # v v # Snd_Instrument CLM_Instrument # | | | # v v v # With_Snd With_DAC With_CLM # # Instruments can use the generalized run-loop 'run_instrument'. # # RUN_INSTRUMENT(start, dur, *locsig_args) do |samp| # ... # (return next sample) # end # # The body (or block) of 'run_instrument' should return the next sample, e.g.: # # class Instrument # def my_simp(start, dur, freq, amp, amp_env = [0, 1, 1, 1]) # os = make_oscil(:frequency, freq) # en = make_env(:envelope, amp_env, :scaler, amp, :duration, dur) # run_instrument(start, dur) do # env(en) * oscil(os) # end # end # end # # In Snd as well as in a Ruby script: # with_sound do my_simp(0, 1, 440, 0.2) end # # If the reverb file has only one channel, reverb instruments can use # the generalized run-loop 'run_reverb'. # # RUN_REVERB() do |ho, samp| ... (return next frample) end # # HO is the sample on location SAMP of reverb file. # It replaces # # (beg...len).each do |i| # ho = ina(i, @ws_reverb) # ... # end # # with # # run_reverb() do |ho, i| # ... # end # # The body should return a vct of @channels length, the out_frample. # The body is called seconds2sample(dur + @decay_time) times. # # def my_reverb(start, dur, *rest) # ... # out_frample = Vct.new(@channels, 0.0) # run_reverb() do |ho, i| # ... # out_frample[0] = val0 # if @channels > 1 # out_frample[1] = val1 # end # ... # out_frample # end # end # # The classes Snd_Instrument and CLM_Instrument can be used to define # special instruments, see FULLMIX in clm-ins.rb. # # Class Snd_Instrument instruments can only be used in Snd. The # buffer can be created by with_sound or you can provide vcts for # output and revout. # # with_sound(:out_buffer, Vct.new(22050)) # # Class CLM_Instrument instruments use sample2file output and can be # used in Snd as well as in Ruby scripts, @ws_output and $output are # the same, @ws_reverb and $reverb are the same too. # Global variables can be set in ~/.snd_ruby or in other scripts # before or after loading ws.rb. # # with_sound(:play, 3, :statistics, true, :reverb, :jc_reverb) do # fm_violin(0, 1, 440, 0.3) # end # # clm_load("test.rbm", :play, 1, :statistics, true, :verbose, true) # # These functions can be called within with_sound or clm_load: # scaled_to(scale, &body) # scaled_by(scale, &body) # with_offset(secs, &body) # with_current_sound(*args, &body) # sound_let(*args, &body) # with_mix(*args) (does not use a block but a string as "body") # # SOUND_LET # # sound_let(*args) do |*sl_args| ... end # args: [with_sound-args1, with_sound-body1], # [with_sound-args2, with_sound-body2], # with_sound_body3, # let_args1, # let_args2, ... # # sound_let works like let except for procedures which are handled by # with_sound. with_sound returns a filename which can be used in the # sound_let body. # # sound_let(Proc.new do fm_violin(0, 1, 330, 0.5) end, # 1024) do |tmp_file, val| # end # # TMP_FILE is returned by with_sound and VAL is connected to 1024. # # If with_sound needs args, the args and the procedure must be in an # array. # # sound_let([:scaled_to, 0.3, :output, "sl.snd", # Proc.new do fm_violin(0, 1, 330, 0.5) end], # 1024) do |tmp_file, val| # end # # Examples: # # One with_sound-call and one temporary file name, arbitrary called TMP: # # sound_let([:reverb, :jc_reverb, # Proc.new do fm_violin(0, 1, 220, 0.2) end]) do |tmp| # mus_mix(@output, tmp) # end # # Two with_sound-calls and two temporary file names, arbitrary # called TEMP_1 and TEMP_2: # # sound_let([:reverb, :jc_reverb, # Proc.new do fm_violin(0, 1, 220, 0.2) end], # Proc.new do fm_violin(0.5, 1, 440, 0.3) end) do |temp_1, temp_2| # mus_mix(temp_1, temp_2) # mus_mix(@output, temp_1) # end # # WITH_MIX # # with_mix(file, body_string) # with_mix(file, beg_time, body_string) # with_mix(with_sound-args, file, beg_time, body_string) # # The FILE and BODY_STRING are necessary, BEG_TIME and # WITH_SOUND-ARGS are optional, BEG_TIME defaults to 0. # # Creates a text file named FILE.rbm with contents BODY_STRING and a # sound file named FILE.snd, the result of clm_load(FILE.rbm). If # BODY_STRING is changed, clm_load(FILE.rbm) is called before mixing # FILE.snd in the underlying @output of with_sound. # # Example: # # with_sound() do # with_mix(:reverb, :jc_reverb, "foo", 0.2, %Q{ # fm_violin(0, 1, 440, 0.1) # }) # end # # with_sound's NOTEHOOK and INFO options: # # Every time an instrument starts computing, @with_sound_note_hook is # called with the instrument name, the start time and the duration. # # def my_notehook(name, start, dur) # if name =~ /violin/ # Snd.message("%s: start %1.3f, dur %1.3f", name, start, dur) # end # end # # with_sound(:notehook, :my_notehook) do # fm_violin(0, 1, 440, 0.1) # fbell = [0, 1, 2, 1.1, 25, 0.75, 75, 0.5, 100, 0.2] # abell = [0, 0, 0.1, 1, 10, 0.6, 25, 0.3, 50, 0.15, 90, 0.1, 100, 0] # fm_bell(0.5, 2.0, 220, 0.5, abell, fbell, 1) # end # # installs the @with_sound_note_hook and prints the line # # '# fm_violin: start 0.000, dur 1.000' # # If option :info is true, every instrument-call prints the line # mentioned above. # # with_sound's SAVE_BODY option: # # Works only if proc (the with_sound-body) is located in a source file # and proc.to_s returns something like # # (older Ruby versions # return only #, so we can't find the source file and # line number). # # Tries to locate the body code and saves it in the comment string of # the sound file. Scanning the source code is very simple and may not # work in every case. # CLM examples (see clm.html) and their Snd/Ruby counterparts: # # ;; CLM examples # (with-sound () # (mix (with-sound (:output "hiho.snd") # (fm-violin 0 1 440 .1)) # :amplitude .5)) # # (with-sound () # (with-mix () "s1" 0 # (sound-let ((tmp () # (fm-violin 0 1 440 .1))) # (mix tmp)))) # # (with-sound (:verbose t) # (with-mix () "s6" 0 # (sound-let ((tmp () # (fm-violin 0 1 440 .1)) # (tmp1 (:reverb nrev) # (mix "oboe.snd"))) # (mix tmp1) # (mix tmp :amplitude .2 :output-frame *srate*)) # (fm-violin .5 .1 330 .1))) # # (with-sound (:verbose t) # (sound-let ((tmp () # (with-mix () "s7" 0 # (sound-let ((tmp () # (fm-violin 0 1 440 .1)) # (tmp1 () # (mix "oboe.snd"))) # (mix tmp1) # (mix tmp :output-frame *srate*)) # (fm-violin .5 .1 330 .1)))) # (mix tmp :amplitude .5))) =begin # Snd/Ruby examples with_sound() do clm_mix(with_sound(:output, "hiho.snd") do fm_violin(0, 1, 440, 0.1) end.output, :scaler, 0.5) end with_sound() do with_mix "s1", %Q{ sound_let(Proc.new do fm_violin(0, 1, 440, 0.1) end) do |tmp| clm_mix(tmp) end } end with_sound(:verbose, true) do with_mix "s6", %Q{ sound_let(Proc.new do fm_violin(0, 1, 440, 0.1) end, [:reverb, :nrev, Proc.new do clm_mix("oboe.snd") end]) do |tmp, tmp1| clm_mix(tmp1) clm_mix(tmp, :scaler, 0.2, :output_frame, seconds2samples(1)) end fm_violin(0.5, 0.1, 330, 0.1) } end with_sound(:verbose, true) do sound_let(Proc.new do with_mix "s7", 0, %Q{ sound_let(Proc.new do fm_violin(0, 1, 440, 0.1) end, Proc.new do clm_mix("oboe.snd") end) do |t1, t2| clm_mix(t2) clm_mix(t1, :output_frame, @srate) end fm_violin(0.5, 0.1, 330, 0.1) } end) do |t0| clm_mix(t0, :scaler, 0.5) end end =end require "clm" require "hooks" def clm_find_sound_file(file) if File.exist?(file) file else fname = false if array?($clm_search_list) $clm_search_list.each do |path| if File.exist?(fs = path + "/" + file) fname = fs break end end end fname end end def clm_player(s) fs = nil if string?(s) fs = clm_find_sound_file(s) unless File.exist?(fs) Snd.raise(:no_such_file, s, "need a sound index or a file name") end elsif sound?(s) fs = s else Snd.raise(:no_such_sound, s, "need a sound index or a file name") end if provided?(:snd) play(fs, :wait, true) else system("sndplay #{fs}") end end trace_var(:$clm_default_frequency) do |val| set_clm_default_frequency(val) end trace_var(:$clm_table_size) do |val| set_clm_table_size(val) end with_silence do # warning: undefined variable $clm_version = "ruby 2015/03/04" $output ||= false $reverb ||= false $clm_array_print_length ||= 8 $clm_clipped ||= true $clm_comment ||= nil $clm_decay_time ||= 1.0 $clm_delete_reverb ||= false $clm_file_buffer_size ||= 65536 $clm_file_name ||= "test.snd" $clm_info ||= false $clm_notehook ||= nil $clm_play ||= 0 $clm_player ||= false $clm_reverb ||= nil $clm_reverb_channels ||= 1 $clm_reverb_data ||= [] $clm_reverb_file_name ||= nil $clm_statistics ||= false $clm_table_size ||= 512 $clm_verbose ||= false $clm_default_frequency ||= 0.0 $clm_locsig_type ||= locsig_type $clm_search_list ||= (ENV["CLM_SEARCH_PATH"] or ".").split(/:/) if provided? :snd $clm_channels ||= default_output_chans $clm_srate ||= default_output_srate $clm_header_type ||= default_output_header_type $clm_sample_type ||= default_output_sample_type $clm_dac_size ||= dac_size else $clm_channels ||= 1 $clm_srate ||= 44100 $clm_header_type ||= Mus_next $clm_sample_type ||= Mus_lfloat $clm_dac_size ||= 1024 end end # for backward compatibility $clm_data_format = $clm_sample_type trace_var(:$clm_data_format) do |val| $clm_sample_type = val end $clm_rt_bufsize = $clm_dac_size trace_var(:$clm_rt_bufsize) do |val| $clm_dac_size = val end module WS ws_ht = mus_header_type2string($clm_header_type) ws_st = mus_sample_type2string($clm_sample_type) if string?(ws_fn = $clm_file_name) ws_fn = File.basename(ws_fn) end if string?(ws_rf = $clm_reverb_file_name) ws_rf = File.basename(ws_rf) end ws_doc = "\ with_sound(*args) do ... end :output $clm_file_name (#{ws_fn.inspect}) :channels $clm_channels (#{$clm_channels}) :srate $clm_srate (#{$clm_srate}) :header_type $clm_header_type (#{ws_ht}) :sample_type $clm_sample_type (#{ws_st}) :reverb $clm_reverb (#{$clm_reverb.inspect}) :reverb_data $clm_reverb_data (#{$clm_reverb_data}) :reverb_channels $clm_reverb_channels (#{$clm_reverb_channels}) :revfile $clm_reverb_file_name (#{ws_rf.inspect}) :delete_reverb $clm_delete_reverb (#{$clm_delete_reverb}) :decay_time $clm_decay_time (#{$clm_decay_time}) :scaled_to false :scaled_by false :continue_old_file false :notehook $clm_notehook (#{$clm_notehook}) :dac_size $clm_dac_size (#{$clm_dac_size}) :play $clm_play (#{$clm_play}) :statistics $clm_statistics (#{$clm_statistics}) :comment $clm_comment (#{$clm_comment.inspect}) :locsig_type $clm_locsig_type (Mus_interp_linear) :verbose $clm_verbose (#{$clm_verbose}) :save_body false :info $clm_info (#{$clm_info}) :clipped $clm_clipped (#{$clm_clipped}) :player $clm_player (#{$clm_player.inspect}) :to_snd (true, false, nil) :clm (true, false, nil) :help Usage: with_sound(:play, 1, :statistics, true) do fm_violin end" with_silence do unless defined? Etc.getlogin require "etc" end unless defined? Socket.gethostname require "socket" end end def ws_getlogin if defined? Etc.getlogin Etc.getlogin else ENV["USER"] or "xen" end end def ws_gethostname if defined? Socket.gethostname Socket.gethostname else ENV["HOST"] or "localhost" end end def ws_break(*rest) msg = format("%s received Break", get_func_name(2)) unless rest.null? msg += ":" rest.each do |s| msg += format(" %s,", s) end end raise(Break, msg.chomp(","), caller(1)) end # :to_snd has the following arguments: # :snd or true => With_Snd # :clm or false => With_CLM # :dac or nil => With_DAC # :clm has these (false and true swapped) # :snd or false => With_Snd # :clm or true => With_CLM # :dac or nil => With_DAC # :output "dac" => With_DAC add_help(:with_sound, ws_doc) def with_sound(*args, &body) if args.member?(:help) return Snd.display(get_help(:with_sound)) end if (not provided?(:snd)) klass = With_CLM elsif args.member?(:output) and args[args.index(:output) + 1] == "dac" klass = With_DAC elsif args.member?(:to_snd) case args[args.index(:to_snd) + 1] when :snd, TrueClass klass = With_Snd when :clm, FalseClass klass = With_CLM when :dac, NilClass klass = With_DAC end elsif args.member?(:clm) case args[args.index(:clm) + 1] when :snd, FalseClass klass = With_Snd when :clm, TrueClass klass = With_CLM when :dac, NilClass klass = With_DAC end else klass = With_CLM end ws = klass.new(*args, &body) ws.run(&body) ws end # require "v" # with_dac(:statistics, true, # :info, true, # :dac_size, 8192 * 4, # :srate, 22050) do # violin(0.5, 2.5, 440, 0.2, 0.1, [0, 0, 25, 1, 75, 1, 100, 0]) # fm_violin(0, 5, 330, 0.2, :fm_index, 10.5) # fm_violin(1, 2, 660, 0.2, :fm_index, 0.8) # end add_help(:with_dac, ws_doc) def with_dac(*args, &body) with_sound(:to_snd, :dac, *args, &body) end add_help(:with_snd, ws_doc) def with_snd(*args, &body) with_sound(:to_snd, :snd, *args, &body) end add_help(:with_clm, ws_doc) def with_clm(*args, &body) with_sound(:to_snd, :clm, *args, &body) end add_help(:with_full_sound, ws_doc) def with_full_sound(*args, &body) ws = with_sound(:to_snd, :snd, *args, &body) len = framples($snd_opened_sound) / srate($snd_opened_sound).to_f set_x_bounds([0, len], $snd_opened_sound) ws end add_help(:with_temp_sound, ws_doc) def with_temp_sound(*args, &body) ws = with_sound(:to_snd, :clm, :output, tempnam(), *args, &body) remove_file(ws.output) ws end add_help(:with_temp_snd, "with_temp_snd(snd=false) do |temp_snd_file_name| ... end \ Saves SND in a temporary file, which name can be accessed in the body code. \ After finishing the body, the file will be removed.") def with_temp_snd(snd = false, &body) t = tempnam() save_sound_as(t, snd) ret = body.call(t) remove_file(t) ret end add_help(:clm_load, "clm_load(rbm_file, *with_sound_args)\n" + ws_doc) def clm_load(rbm_file, *args) assert_type(File.exist?(rbm_file), rbm_file, 1, "an existing file") with_sound(*args) do if @verbose Snd.message("Loading %s", rbm_file.inspect) end eval(File.open(rbm_file).read, nil, "(clm_load #{rbm_file})", 1) end end if defined? snd_tempnam alias tempnam snd_tempnam else $file_number = 0 def tempnam dir = (ENV.map do |k, v| v if /TMP/ =~ k end.compact.first or "/tmp") format("%s/snd_%d_%d.snd", dir, $$, $file_number += 1) end end def make_default_comment format("# Written %s by %s at %s using clm (%s)", Time.new.localtime.strftime("%a %d-%b-%y %H:%M %z"), ws_getlogin, ws_gethostname, $clm_version) end def remove_file(file) if provided?(:snd) and sound?(snd = find_sound(file)) snd.revert close_sound_extend(snd) end File.owned?(file) and File.unlink(file) end def each_sample(start, dur, &body) beg, ends = times2samples(start, dur) (beg...ends).each(&body) end def process_times if defined? Process.times Process.times else Time.times end end end class XenSound def name self.class.name end def length framples(self, false, false) end def update update_sound(self) end def revert revert_sound(self) end def save save_sound(self) end def close close_sound(self) end def snd_file_name file_name(self) end def snd_maxamp(chn = false, edpos = false) maxamp(self, chn, edpos) end def snd_framples(chn = false, edpos = false) framples(self, chn, edpos) end def snd_sample_type sample_type(self) end def snd_sample_type=(v) set_sample_type(self, v) end def snd_header_type header_type(self) end def snd_header_type=(v) set_header_type(self, v) end def snd_comment comment(self) end def snd_comment=(v) set_comment(self, v) end def snd_srate srate(self) end def snd_srate=(v) set_srate(self, v) end def snd_channels channels(self) end def snd_channels=(v) set_channels(self, v) end end class With_sound include Info include WS def initialize(*args, &body) @output = get_args(args, :output, $clm_file_name) @channels = get_args(args, :channels, $clm_channels) @srate = get_args(args, :srate, $clm_srate) @header_type = get_args(args, :header_type, $clm_header_type) # for backward compatibility @sample_type = get_args(args, :data_format, $clm_sample_type) @sample_type = get_args(args, :sample_type, $clm_sample_type) @out_buffer = get_args(args, :out_buffer, false) @reverb = get_args(args, :reverb, $clm_reverb) @reverb_data = get_args(args, :reverb_data, $clm_reverb_data) @reverb_channels = get_args(args, :reverb_channels, $clm_reverb_channels) @revfile = get_args(args, :reverb_file_name, nil) @delete_reverb = get_args(args, :delete_reverb, $clm_delete_reverb) @rev_buffer = get_args(args, :rev_buffer, false) @decay_time = get_args(args, :decay_time, $clm_decay_time) @scaled_to = get_args(args, :scaled_to, false) @scaled_by = get_args(args, :scaled_by, false) @continue = get_args(args, :continue_old_file, false) @notehook = get_args(args, :notehook, $clm_notehook) @dac_size = get_args(args, :dac_size, $clm_dac_size) @save_body = get_args(args, :save_body, false) @player = get_args(args, :player, $clm_player) @play = get_args(args, :play, $clm_play) @statistics = get_args(args, :statistics, $clm_statistics) @verbose = get_args(args, :verbose, $clm_verbose) @info = get_args(args, :info, $clm_info) @comment = get_args(args, :comment, $clm_comment) @locsig_type = get_args(args, :locsig_type, $clm_locsig_type) @clipped = get_args(args, :clipped, :undefined) @offset = get_args(args, :offset, 0.0) @rtime = @utime = @stime = 0.0 @stat_framples = 0 @stat_sample_type = false @stat_header_type = false @stat_comment = nil @stat_maxamp = nil @stat_revamp = nil if @reverb and @revfile.null? @revfile = make_reverb_file_name end # play: either :play, true # or :play, false # or :play, nil # or :play, integer (times to play) @play = case @play when TrueClass 1 when FalseClass, NilClass 0 when Numeric Integer(@play).abs else 0 end # without reverb: either :reverb_channels, 0 # or :reverb, false if @reverb_channels.zero? @reverb = $reverb = false end unless string?(@comment) @comment = make_default_comment end if @save_body and proc?(body) @comment << "\n" << body.to_body end @old_srate = mus_srate @old_update_interval = if defined? auto_update_interval auto_update_interval else false end @start_frame = 0 $output = @ws_output = false $reverb = @ws_reverb = false @out_snd = @rev_snd = false @clm_instruments = Hash.new @with_sound_note_hook = Hook.new("@with_sound_note_hook", 3, "\ lambda do |inst_name, start, dur| ... end: called if an instrument has \ the run_instrument/run_reverb loop included. Every time an instrument starts computing, @with_sound_note_hook is \ called with the instrument name INST_NAME, the start time START, and \ the duration DUR. def my_notehook(name, start, dur) if name =~ /violin/ Snd.message(\"%s: start %1.3f, dur %1.3f\", name, start, dur) end end with_sound(:notehook, :my_notehook) do fm_violin(0, 1, 440, 0.1) fbell = [0, 1, 2, 1.1, 25, 0.75, 75, 0.5, 100, 0.2] abell = [0, 0, 0.1, 1, 10, 0.6, 25, 0.3, 50, 0.15, 90, 0.1, 100, 0] fm_bell(0.5, 2.0, 220, 0.5, abell, fbell, 1) end installs the @with_sound_note_hook and prints the line '# fm_violin: start 0.000, dur 1.000'.") case @notehook when Proc @with_sound_note_hook.add_hook!("wsnh") do |name, start, dur| @notehook.call(name, start, dur) end when Symbol, String @with_sound_note_hook.add_hook!("wsnh") do |name, start, dur| snd_func(@notehook, name, start, dur) end end self.description = get_help(:with_sound) end attr_reader :output, :out_snd, :with_sound_note_hook alias help description def inspect s = self.to_s unless @clm_instruments.empty? s += "\n# b[1][1] end.each do |k, v| s += format("%s [%1.3f-%1.3f]\n", *v) s += " " * 19 end s.strip! s += ">" end s end def to_s if @reverb s = format(", reverb: %s, reverb-channels: %d", @reverb, @reverb_channels) else s = "" end format("#<%s: output: %p, channels: %d, srate: %d%s>", self.class, @output, @channels, @srate.to_i, s) end def describe show_local_variables end def with_sound(*args, &body) com = format("%s#%s: temporary sound, args %p", self.class, get_func_name, args) ws = self.class.new(:output, get_args(args, :output, @output), :comment, get_args(args, :comment, com), :play, get_args(args, :play, false), :statistics, get_args(args, :statistics, false), :reverb, get_args(args, :reverb, false), :reverb_data, get_args(args, :reverb_data, @reverb_data), :reverb_file_name, get_args(args, :reverb_file_name, @revfile), :reverb_channels, get_args(args, :reverb_channels, @reverb_channels), :delete_reverb, get_args(args, :delete_reverb, @delete_reverb), :decay_time, get_args(args, :decay_time, @decay_time), :continue_old_file, get_args(args, :continue_old_file, @continue), :out_buffer, get_args(args, :out_buffer, @out_buffer), :rev_buffer, get_args(args, :rev_buffer, @rev_buffer), :scaled_to, get_args(args, :scaled_to, @scaled_to), :scaled_by, get_args(args, :scaled_by, @scaled_by), :notehook, get_args(args, :notehook, @notehook), :save_body, get_args(args, :save_body, @save_body), :channels, get_args(args, :channels, @channels), :srate, get_args(args, :srate, @srate), :header_type, get_args(args, :header_type, @header_type), # for backward compatibility :sample_type, get_args(args, :data_format, @sample_type), :sample_type, get_args(args, :sample_type, @sample_type), :verbose, get_args(args, :verbose, @verbose), :info, get_args(args, :info, @info), :clipped, get_args(args, :clipped, @clipped), :offset, get_args(args, :offset, 0.0), &body) ws.run(&body) ws end def with_current_sound(*args, &body) output, offset, scaled_to, scaled_by = nil optkey(args, binding, [:output, tempnam()], [:offset, 0.0], [:scaled_to, false], [:scaled_by, false]) ws = with_sound(:output, output, :scaled_to, scaled_to, :scaled_by, scaled_by, :offset, offset, *args, &body) clm_mix(ws.output) remove_file(ws.output) ws end def scaled_to(scale, &body) with_current_sound(:scaled_to, scale, &body) end def scaled_by(scale, &body) with_current_sound(:scaled_by, scale, &body) end def with_offset(secs, &body) with_current_sound(:offset, secs, &body) end def sound_let(*args, &body) outfile_list = [] arg_list = [] args.each do |sl_args| if proc?(sl_args) or (array?(sl_args) and proc?(sl_args.last)) if proc?(sl_args) ws_body = sl_args ws_args = [] else ws_body = sl_args.pop ws_args = sl_args.dup end ws_args.push(:output, tempnam()) outfile_list.push(with_sound(*ws_args, &ws_body).output) arg_list.push(outfile_list.last) else arg_list.push(sl_args) end end body.call(*arg_list) rescue raise ensure outfile_list.apply(:remove_file) end def with_mix(*args) body_str = args.pop assert_type(string?(body_str), body_str, 0, "a string (body string)") start = 0 if number?(args[-1]) start = args.pop end fname = args.pop assert_type(string?(fname), fname, 0, "a string (filename)") out_file = fname + ".snd" rbm_file = fname + ".rbm" snd_time = :load if File.exist?(out_file) snd_time = File.mtime(out_file) end old_body = "" if File.exist?(rbm_file) old_body = File.open(rbm_file).read end rbm_time = :load if old_body == body_str rbm_time = File.mtime(rbm_file) else File.open(rbm_file, "w") do |f| f << body_str end rbm_file = :load end if snd_time == :load or rbm_time == :load or snd_time < rbm_time if @verbose Snd.message("mix remake %s at %1.3f", out_file, start) end comm = format("# written %s (Snd: %s)\n", Time.now, snd_version) comm += format("[%s, %s]\n", args.to_s.inspect, body_str.inspect) self.with_sound(:output, out_file, :comment, comm, *args) do eval(File.open(rbm_file).read, nil, format("(with_mix_load %s)", rbm_file), 1) end else if @verbose Snd.message("mix %s at %1.3f", out_file, start) end end clm_mix(out_file, :output_frame, seconds2samples(start)) end def with_sound_info(name, start, dur, body = binding) @clm_instruments.store(body, [name, start, dur]) if @info and (not @notehook) Snd.message("%s: start %1.3f, dur %1.3f", name, start, dur) end if @notehook @with_sound_note_hook.call(name, start, dur) end end def run_instrument(start, dur, body) @start_frame = seconds2samples(start + @offset) with_sound_info(get_func_name(3), start, dur, body) end # Handles only the first channel of a reverb file. # body.call(sample, current_sample_index) => vct of @channels' length def run_reverb(&body) name = get_func_name(3) dur = samples2seconds(@ws_reverb.length) + @decay_time with_sound_info("reverb " + name, 0, dur, body) if @verbose Snd.message("%s on %d in and %d out channels", name, @reverb_channels, @channels) end end def run(&body) set_mus_file_buffer_size($clm_file_buffer_size) set_mus_array_print_length($clm_array_print_length) if @clipped == :undefined if (@scaled_by or @scaled_to) and [Mus_bfloat, Mus_lfloat, Mus_bdouble, Mus_ldouble].member?(@sample_type) set_mus_clipping(false) else set_mus_clipping($clm_clipped) end else set_mus_clipping(@clipped) end if defined? set_auto_update_interval set_auto_update_interval(0.0) end before_output frm1 = ws_frample_location init_process_time run_body(&body) after_output stop_process_time old_sync = false if provided? :snd if sound?(snd = find_sound(@output)) old_sync = sync(snd) @out_snd = snd.update else if @header_type == Mus_raw @out_snd = open_raw_sound(@output, @channels, @srate.to_i, @sample_type) else @out_snd = open_sound(@output) end end set_sync(true, @out_snd) end set_statistics frm2 = ws_frample_location if @scaled_to scaled_to_sound(frm1, frm2 - frm1) end if @scaled_by scaled_by_sound(frm1, frm2 - frm1) end if provided? :snd if sound?(snd = find_sound(@output)) if old_sync set_sync(old_sync, snd) end update_time_graph(snd) end end finish_sound if @statistics statistics end 1.upto(@play) do play_it end end protected # INFO [ms] # Mon Nov 15 14:46:13 CET 2010 # # previous (1.?.? ... 1.9.1) # instance_eval do | | body end # # current (1.9.2 since July 2010) # instance_eval do |self| body end # # if BODY: lambda do | | ... end # ArgumentError: wrong number of arguments (1 for 0) # if BODY: Proc.new do | | ... end # okay (Proc ignores arity) def run_body(&body) instance_eval(&body) rescue Interrupt, ScriptError, NameError, StandardError finish_sound show_local_variables case $! when Interrupt, Break # C-g, ws_break Snd.message("with_sound body: %s", $!.message) else raise $! end end def run_reverb_body case @reverb when Proc @reverb.call(*@reverb_data) when String, Symbol snd_func(@reverb, *@reverb_data) end rescue Interrupt, ScriptError, NameError, StandardError finish_sound show_local_variables case $! when Interrupt, Break # C-g, ws_break Snd.message("with_sound body (reverb): %s", $!.message) else raise $! end end def show_local_variables Snd.message() # run_instrument|reverb-proc => [instrument-name, start, dur] # sorted by values[start] @clm_instruments.sort do |a, b| a[1][1] <=> b[1][1] end.each do |proc, vals| Snd.message("=== %s [%1.3f-%1.3f] ===", *vals) each_variables(binding?(proc) ? proc : proc.binding) do |var, val| Snd.message("%s = %s", var, val) end Snd.message() end @clm_instruments.values end def make_reverb_file_name s = string?(@output) ? @output : @output.class.to_s path = File.split(s).first file = File.basename(s, ".*") + ".reverb" unless path == "." file = path + "/" + file end file end def init_process_time tms = process_times @rtime = Time.now @utime = tms.utime @stime = tms.stime end def stop_process_time tms = process_times @rtime = Time.now - @rtime @utime = tms.utime - @utime @stime = tms.stime - @stime end def before_output set_mus_srate(@srate) end def ws_frample_location end def scaled_to_sound(from, to) end def scaled_by_sound(from, to) end def statistics if string?(@ws_output) obj_name = "" else obj_name = " (" + @ws_output.name + ")" end Snd.message("filename: %p%s", @output, obj_name) Snd.message(" chans: %d, srate: %d", @channels, @srate.to_i) if @stat_sample_type and @stat_header_type Snd.message(" format: %s [%s]", mus_sample_type_name(@stat_sample_type), mus_header_type_name(@stat_header_type)) end if @stat_framples > 0 Snd.message(" length: %1.3f (%d frames)", @stat_framples / @srate.to_f, @stat_framples) end Snd.message(" real: %1.3f (utime %1.3f, stime %1.3f)", @rtime, @utime, @stime) if @stat_framples > 1 rt = (@srate.to_f / @stat_framples) Snd.message(" ratio: %1.2f (uratio %1.2f)", @rtime * rt, @utime * rt) end ws_maxamp_statistics unless (comm = @stat_comment).null? Snd.message(" comment: %s", comm) end end def finish_sound if defined? set_auto_update_interval set_auto_update_interval(@old_update_interval) end @reverb and @delete_reverb and (not @continue) and remove_file(@revfile) set_mus_srate(@old_srate) @stat_framples = ws_frample_location end def play_it if provided? :snd # Inside Snd we use a Proc or Method of one arg, a sound INDEX. case @player when Proc @player.call(@out_snd) when Method snd_func(@player, @out_snd) else play(@out_snd, :wait, true) end else # Outside Snd we use a Proc or Method of one arg, a sound FILE NAME. case @player when Proc @player.call(@output) when Method snd_func(@player, @output) else system("sndplay #{@output}") end end end end class Instrument < With_sound # Actually it isn't necessary to define instruments as methods of # class Instrument. def ws_simp(start = 0, dur = 1, freq = 440, amp = 0.5, amp_env = [0, 1, 1, 1]) os = make_sum_of_cosines(:frequency, freq, :cosines, 3) en = make_env(:envelope, amp_env, :scaler, amp, :duration, dur) fs = hz2radians(freq) pv = make_triangle_wave(:frequency, 6.0, :amplitude, 0.0025 * fs) rv = make_rand_interp(:frequency, 8.0, :amplitude, 0.005 * fs) run_instrument(start, dur) do sum_of_cosines(os, triangle_wave(pv) + rand_interp(rv)) * env(en) end end # simple violin, see snd/fm.html def ws_violin(start = 0, dur = 1, freq = 440, amp = 0.5, fm_index = 1, amp_env = [0, 1, 1, 1]) frq_scl = hz2radians(freq) maxdev = frq_scl * fm_index index1 = maxdev * (5.0 / log(freq)) index2 = maxdev * 3.0 * ((8.5 - log(freq)) / (3.0 + freq / 1000.0)) index3 = maxdev * (4.0 / sqrt(freq)) carrier = make_oscil(:frequency, freq) fmosc1 = make_oscil(:frequency, freq) fmosc2 = make_oscil(:frequency, freq * 3.0) fmosc3 = make_oscil(:frequency, freq * 4.0) ampf = make_env(:envelope, amp_env, :scaler, amp, :duration, dur) indf1 = make_env(:envelope, [0, 1, 25, 0.4, 75, 0.6, 100, 0], :scaler, index1, :duration, dur) indf2 = make_env(:envelope, [0, 1, 25, 0.4, 75, 0.6, 100, 0], :scaler, index2, :duration, dur) indf3 = make_env(:envelope, [0, 1, 25, 0.4, 75, 0.6, 100, 0], :scaler, index3, :duration, dur) pervib = make_triangle_wave(:frequency, 0.5, :amplitude, 0.0025 * frq_scl) ranvib = make_rand_interp(:frequency, 16.0, :amplitude, 0.005 * frq_scl) run_instrument(start, dur) do vib = triangle_wave(pervib) + rand_interp(ranvib) env(ampf) * oscil(carrier, vib + env(indf1) * oscil(fmosc1, vib) + env(indf2) * oscil(fmosc2, 3.0 * vib) + env(indf3) * oscil(fmosc3, 4.0 * vib)) end end alias violin ws_violin end # WSChannel2Vct and WSSampler are helper classes used by class # Snd_Instrument. sampler has no possibility to set location # (and direction) which is needed by instrument grani (clm-ins.rb). class WSChannel2Vct # (channel->vct (beg 0) (dur len) (snd #f) (chn #f) (edpos #f)) def initialize(snd = false, chn = false, start = 0, dir = 1) @vct = channel2vct(0, framples(snd, chn), snd, chn, false) @location = ((dir > 0) ? (start - 1) : (start + 1)) @start = start @direction = dir @snd = snd @chn = chn @last_location = @vct.length - 1 end attr_accessor :direction def inspect format("%s.new(%p, %p, %s, %s)", self.class, @snd, @chn, @start, @direction) end def to_s format("#<%s snd: %p, chn: %p, location: %d, direction: %d, vct: %p>", self.class, @snd, @chn, location, @direction, @vct) end def next if @direction > 0 if @location < @last_location @location += 1 @vct[@location] else 0.0 end else if @location > 0 @location -= 1 @vct[@location] else 0.0 end end end def close # not needed end def location if @direction > 0 @location + 1 else @location - 1 end end def location=(v) if @direction > 0 @location = v - 1 else @location = v + 1 end end end class WSSampler # (make-sampler (start-samp 0) (snd #f) (chn #f) (dir 1) (edpos #f)) def initialize(snd = false, chn = false, start = 0, dir = 1) @reader = make_sampler(start, snd, chn, dir, false) @direction = dir @start = start @direction = dir @snd = snd @chn = chn end attr_accessor :direction def inspect format("%s.new(%s, %s, %s, %s)", self.class, @snd.inspect, @chn.inspect, @start, @direction) end def to_s @reader.inspect end def next @reader.call end def close free_sampler(@reader) if sound?(@snd) close_sound_extend(@snd) end end def location sampler_position(@reader) end def location=(v) # sampler_position isn't settable end end class Snd_Instrument < Instrument # place holder for special Snd instruments, see FULLMIX in # clm-ins.rb. def make_ws_reader(file, *args) start, channel, direction = nil optkey(args, binding, [:start, 0], [:channel, 0], [:direction, 1]) if get_args(args, :vct?, false) WSChannel2Vct.new(get_snd(file), channel, start, direction) else WSSampler.new(get_snd(file), channel, start, direction) end end # (read-sample reader) def ws_readin(rd) rd.next end def close_ws_reader(rd) rd.close end def ws_location(rd) rd.location end def set_ws_location(rd, v) rd.location = v.to_i end def ws_increment(rd) rd.direction end def set_ws_increment(rd, v) rd.direction = v.to_i end def ws_srate(file) srate(get_snd(file)).to_f end def ws_channels(file) channels(get_snd(file)) end def ws_duration(file) snd = get_snd(file) framples(snd) / srate(snd).to_f end private def get_snd(file) snd = if integer?(file) integer2sound(file) elsif string?(file) if sound?(s = find_sound(file)) s else open_sound(file) end end if sound?(snd) snd else Snd.snd(snd) end end end class CLM_Instrument < Instrument # place holder for special Snd instruments, see FULLMIX in # clm-ins.rb. # (make-readin (:file) (:channel 0) (:start 0) (:direction 1) def make_ws_reader(file, *args) start, channel, direction = nil optkey(args, binding, [:start, 0], [:channel, 0], [:direction, 1]) make_readin(:file, file, :channel, channel, :start, start, :direction, direction) end # (readin gen) def ws_readin(rd) readin(rd) end def close_ws_reader(rd) mus_close(rd) end def ws_location(rd) mus_location(rd) end def set_ws_location(rd, v) set_mus_location(rd, v) end def ws_increment(rd) mus_increment(rd) end def set_ws_increment(rd, v) set_mus_increment(rd, v) end def ws_srate(file) mus_sound_srate(file) end def ws_channels(file) mus_sound_chans(file) end def ws_duration(file) mus_sound_duration(file) end end class With_Snd < Snd_Instrument def run_instrument(start, dur, *locsig_args, &body) super(start, dur, body) # locsig and Vct as :output and :revout handles only 1 channel. if @channels == 1 and @reverb_channels < 2 run_inst_with_locsig(start, dur, *locsig_args, &body) else run_inst_with_map(start, dur, *locsig_args, &body) end end def run_reverb(&body) super(&body) # run_reverb handles only one reverb channel vo = channel2vct(0, false, @rev_snd, 0, false) vl = vo.length + seconds2samples(@decay_time) vr = Array.new(@channels) do Vct.new(vl, 0.0) end vo.each_with_index do |s, i| fr = body.call(s, i) @channels.times do |chn| vr[chn][i] = fr[chn] end end origin = format("%s(&body", get_func_name) @channels.times do |chn| mix_vct(vr[chn], 0, @out_snd, chn, false, origin) end end add_help(:clm_mix, "clm_mix(infile, *args) :output = false :output_frame = 0 :frames = framples(infile) :input_frame = 0 :scaler = false Example: clm_mix(\"tmp\")") def clm_mix(infile, *args) output, output_frame, frames, input_frame, scaler = nil optkey(args, binding, [:output, false], [:output_frame, 0], [:frames, framples(infile)], [:input_frame, 0], [:scaler, false]) unless sound?(snd = find_sound(infile)) unless snd = open_sound(infile) Snd.raise(:no_such_file, infile, "file name required") end end # to silence "warning: assigned but unused variable - output" output = "not_used" [channels(snd), @channels].min.times do |chn| if scaler and scaler.nonzero? scale_channel(scaler, input_frame, frames, snd, chn) end mix_vct(channel2vct(input_frame, frames, snd, chn), output_frame, snd, chn, false) end snd.revert close_sound_extend(snd) end protected def run_inst_with_locsig(start, dur, *locsig_args, &body) degree, distance, reverb_amount = nil optkey(locsig_args, binding, [:degree, random(90.0)], [:distance, 1.0], [:reverb_amount, 0.05]) vo = Vct.new(seconds2samples(dur), 0.0) vr = @reverb ? Vct.new(seconds2samples(dur), 0.0) : false @locsig = make_locsig(:degree, degree, :distance, distance, :reverb, reverb_amount, :output, vo, :revout, vr, :channels, @channels, :type, @locsig_type) vo.length.times do |i| locsig(@locsig, i, body.call(@start_frame + i)) end origin = format("run_instrument(%s, %s, %s, &body", start, dur, locsig_args.to_s[1..-2]) # get rid of '[' and ']' mix_vct(vo, @start_frame, @out_snd, 0, false, origin) if @reverb mix_vct(vr, @start_frame, @rev_snd, 0, false, origin) end end def run_inst_with_map(start, dur, *locsig_args, &body) origin = format("run_instrument(%s, %s, %s, &body", start, dur, locsig_args.to_s[1..-2]) vo = Vct.new(seconds2samples(dur)) do |i| body.call(@start_frame + i) end @channels.times do |chn| mix_vct(vo, @start_frame, @out_snd, chn, false, origin) end if @reverb ra = get_args(locsig_args, :reverb_amount, 0.05) vr = vo.scale(ra) @reverb_channels.times do |chn| mix_vct(vr, @start_frame, @rev_snd, chn, false, origin) end end end def before_output super snd = rsnd = false sr = mus_srate.to_i snd = find_sound(@output) if sound?(snd = find_sound(@output)) if @continue @srate = set_mus_srate(snd.snd_srate) else snd.snd_header_type = @header_type snd.snd_sample_type = @sample_type snd.snd_srate = sr snd.snd_channels = @channels snd.snd_comment = @comment snd.snd_channels.times do |chn| set_framples(1, snd, chn) end snd.save snd = snd.update end else unless @continue remove_file(@output) end snd = new_sound(@output, @channels, sr, @sample_type, @header_type, @comment) end if @reverb if sound?(rsnd = find_sound(@revfile)) and (not @continue) rsnd.snd_header_type = @header_type rsnd.snd_sample_type = @sample_type rsnd.snd_srate = sr rsnd.snd_channels = @reverb_channels rsnd.snd_channels.times do |chn| set_framples(1, rsnd, chn) end rsnd.save rsnd = rsnd.update else unless @continue remove_file(@revfile) end rsnd = new_sound(@revfile, @reverb_channels, sr, @sample_type, @header_type) end end $output = @ws_output = @out_snd = snd $reverb = @ws_reverb = @rev_snd = rsnd end def after_output @reverb and run_reverb_body @out_snd.save end def ws_frample_location @out_snd.length end def scaled_to_sound(beg, len) scl = @scaled_to / maxamp(@out_snd, true).max @channels.times do |chn| scale_channel(scl, beg, len, @out_snd, chn) end @out_snd.save end def scaled_by_sound(beg, len) @channels.times do |chn| scale_channel(@scaled_by, beg, len, @out_snd, chn) end @out_snd.save end def set_statistics @stat_framples = @out_snd.length @stat_sample_type = @out_snd.snd_sample_type @stat_header_type = @out_snd.snd_header_type @stat_comment = @out_snd.snd_comment @stat_maxamp = @out_snd.snd_maxamp(true) if @reverb @stat_revamp = @rev_snd.snd_maxamp(true) end end def ws_maxamp_statistics Snd.message(" max out: %s%s", @stat_maxamp.to_string, (@scaled_to or @scaled_by) ? " (before scaling)" : "") if @reverb Snd.message(" max rev: %s", @stat_revamp.to_string) end end # with_closed_sound(snd) do |snd_name| ... end # returns new snd index # see clm-ins.rb, run_fullmix def with_closed_sound(snd, &body) snd_name = snd.file_name snd = snd.update close_sound_extend(snd) body.call(snd_name) open_sound(snd_name) end end class With_CLM < CLM_Instrument def run_instrument(start, dur, *locsig_args, &body) super(start, dur, body) degree, distance, reverb_amount = nil optkey(locsig_args, binding, [:degree, random(90.0)], [:distance, 1.0], [:reverb_amount, 0.05]) @locsig = make_locsig(:degree, degree, :distance, distance, :reverb, reverb_amount, :output, @ws_output, :revout, @ws_reverb, :channels, @channels, :type, @locsig_type) @start_frame.upto((@start_frame + seconds2samples(dur)) - 1) do |i| locsig(@locsig, i, body.call(i)) end end def run_reverb(&body) super(&body) (@ws_reverb.length + seconds2samples(@decay_time)).times do |i| frample2file(@ws_output, i, body.call(file2sample(@ws_reverb, i, 0), i)) end end add_help(:clm_mix, "clm_mix(infile, *args) :output = false :output_frame = 0 :frames = mus_sound_framples(infile) :input_frame = 0 :scaler = false Example: clm_mix(\"tmp\")") def clm_mix(infile, *args) output, output_frame, frames, input_frame, scaler = nil optkey(args, binding, [:output, false], [:output_frame, 0], [:frames, mus_sound_framples(infile)], [:input_frame, 0], [:scaler, false]) chans = 0 outgen = mus_output?(@ws_output) unless output if outgen chans = @ws_output.channels output = @ws_output.file_name else Snd.raise(:no_such_sound, @ws_output, "output generator required") end end unless infile = clm_find_sound_file(infile) Snd.raise(:no_such_file, infile, "file name required") end if outgen @ws_output.close end mx = false if chans > 0 and scaler and scaler != 0.0 mx = Vct.new(chans * chans, scaler) end mus_file_mix(output, infile, output_frame, frames, input_frame, mx) if outgen @ws_output = continue_sample2file(output) end end protected def before_output super if @continue @ws_output = continue_sample2file(@output) @srate = set_mus_srate(mus_sound_srate(@output)) if @reverb @ws_reverb = continue_sample2file(@revfile) end if provided?(:snd) and sound?(snd = find_sound(@output)) close_sound_extend(snd) end else remove_file(@output) @ws_output = make_sample2file(@output, @channels, @sample_type, @header_type, @comment) if @reverb remove_file(@revfile) @ws_reverb = make_sample2file(@revfile, @reverb_channels, @sample_type, @header_type) end end $output = @ws_output $reverb = @ws_reverb end def after_output if @reverb mus_output?(@ws_reverb) and @ws_reverb.close old_reverb = @ws_reverb # non-RUN_REVERB...END functions need it here $reverb = @ws_reverb = make_file2sample(@revfile) run_reverb_body mus_input?(@ws_reverb) and @ws_reverb.close $reverb = @ws_reverb = old_reverb end mus_output?(@ws_output) and @ws_output.close end def ws_frample_location with_closed_output do mus_sound_framples(@output) end end def scaled_to_sound(beg, len) if provided? :snd if sound?(@out_snd = find_sound(@output)) @channels.times do |chn| scale_to(@scaled_to, @out_snd, chn) end @out_snd.save end else omax = mus_sound_maxamp(@output) mx = 0.0 1.step(omax.length - 1, 2) do |i| mx = [omax[i].abs, mx].max end if mx.zero? mx = 1.0 end clm_mix(@output, :output_frame, beg, :frames, len, :scaler, @scaled_to / mx) end end def scaled_by_sound(beg, len) if provided? :snd if sound?(@out_snd = find_sound(@output)) @channels.times do |chn| scale_channel(@scaled_by, beg, len, @out_snd, chn) end @out_snd.save end else clm_mix(@output, :output_frame, beg, :frames, len, :scaler, @scaled_by) end end def set_statistics @stat_framples = mus_sound_framples(@output) @stat_sample_type = mus_sound_sample_type(@output) @stat_header_type = mus_sound_header_type(@output) @stat_comment = mus_sound_comment(@output) @stat_maxamp = mus_sound_maxamp(@output) if @reverb @stat_revamp = mus_sound_maxamp(@revfile) end end def ws_maxamp_statistics sr = @srate.to_f ch = "@" @stat_maxamp.each_pair do |s, v| Snd.message("maxamp %s: %1.3f (near %1.3f secs)%s", ch.next!, v, s / sr, (@scaled_to or @scaled_by) ? " (before scaling)" : "") end if @reverb ch = "@" @stat_revamp.each_pair do |s, v| Snd.message("revamp %s: %1.3f (near %1.3f secs)", ch.next!, v, s / sr) end end end def with_closed_output(&body) mus_output?(@ws_output) and @ws_output.close ret = body.call() $output = @ws_output = continue_sample2file(@output) ret end end class With_DAC < Snd_Instrument def initialize(*args, &body) super(:output, "dac", :reverb, false, *args, &body) end def to_s format("#<%s: channels: %d, srate: %d, dac_size: %d>", self.class, @channels, @srate.to_i, @dac_size) end def run_instrument(start, dur, *locsig_args, &body) # dac.run_instrument needs get_func_name(2) here with_sound_info(get_func_name(2), start, dur, body) @locsig = false end def with_current_sound(*args, &body) end def run(&body) before_output set_mus_file_buffer_size($clm_file_buffer_size) init_process_time run_body(&body) play_it stop_process_time if @statistics statistics end end protected def statistics Snd.message("filename: %s", @output) Snd.message(" chans: %d, srate: %d", @channels, @srate.to_i) Snd.message(" real: %1.3f (utime %1.3f, stime %1.3f)", @rtime, @utime, @stime) if @stat_framples > 0 Snd.message(" length: %1.3f (%d frames)", @stat_framples / @srate.to_f, @stat_framples) end end def play_it len = 0 # [body, [name, start, dur]] insts = @clm_instruments.sort do |a, b| a[1][1] <=> b[1][1] end.to_a.map! do |body, args| start = args[1] dur = args[2] beg, ends = times2samples(start, dur) if len < ends len = ends end [beg, ends, body] end oc = mus_clipping() set_mus_clipping(true) od = dac_size() set_dac_size(@dac_size) len += @dac_size len += mus_file_buffer_size() @stat_framples = len s = 0 play(lambda do if s < len sum = 0.0 insts.each do |args| beg, ends, body = args if s.between?(beg, ends) sum += body.call(s) end end s += 1 sum else false end end) set_mus_clipping(oc) set_dac_size(od) set_mus_srate(@old_srate) end end include WS # ws.rb ends here snd-16.1/index.html0000644000076400007640000045274012610307443012344 0ustar bilbil Snd Index
Index
*#readers*eps-left-marginmake-bandpassmus-xcoeffsseconds->samples
eps-sizemake-bandstopmus-ycoeffselect-all
-
ercosmake-bessmus-ycoeffsselect-channel
ercos?make-biquad select-channel-hook
->byte-vector*error-hook*make-birds
N
select-sound
erssbmake-blackman select-sound-hook
A
erssb?make-brown-noisen1cosselected-channel
even-multiplemake-byte-vectorn1cos?selected-data-color
abcoseven-weightmake-channel-drop-sitename-click-hookselected-graph-color
abcos?every-sample?make-colornchoosekcosselected-sound
abortexitmake-combnchoosekcos?selection
absinexit-hookmake-comb-bankncosselection->mix
absin?expand-controlmake-convolvencos2?selection-chans
add-amp-controlsexpand-control-boundsmake-delayncos4?selection-color
add-colormapexpand-control-hopmake-differentiatorncos?selection-context
add-delete-optionexpand-control-jittermake-envnew-soundselection-creates-region
add-directory-to-view-files-listexpand-control-lengthmake-eoddcosnew-sound-dialogselection-framples
add-file-filterexpand-control-rampmake-ercosnew-sound-hookselection-maxamp
add-file-sorterexpand-control?make-erssbnew-widget-hookselection-maxamp-position
add-file-to-view-files-listexplode-sf2make-fft-windownext-sampleselection-member?
add-markexponentially-weighted-moving-averagemake-file->framplenkssbselection-members
add-mark-paneexpsndmake-file->samplenkssb-interpselection-position
add-playerexpsrcmake-filternkssb?selection-rms
add-sound-file-extension make-filtered-combnoddcosselection-srate
add-source-file-extension
F
make-filtered-comb-banknoddcos?selection?
add-to-main-menu make-fir-coeffsnoddsinSelections
add-to-menu*features*make-fir-filternoddsin?set-samples
add-tooltipfeedback fmmake-firmantnoddssbshort-file-name
add-transformfftmake-float-vectornoddssb?show-axes
additive synthesisfft-cancelmake-flocsignoidshow-controls
adjustable-sawtooth-wavefft-editmake-fmssbNoise Reductionshow-disk-space
adjustable-sawtooth-wave?fft-env-editmake-formantnormalize-channelshow-full-duration
adjustable-square-wavefft-env-interpmake-formant-banknormalize-envelopeshow-full-range
adjustable-square-wave?fft-log-frequencymake-frample->filenormalize-partialsshow-grid
adjustable-triangle-wavefft-log-magnitudemake-granulatenormalize-soundshow-indices
adjustable-triangle-wave?fft-smoothermake-graph-datanormalized-mixshow-listener
after-apply-controls-hookfft-squelchmake-green-noisenotchshow-marks
after-edit-hookfft-windowmake-green-noise-interpnotch-channelshow-mix-waveforms
after-graph-hookfft-window-alphamake-hash-tablenotch-selectionshow-selection
after-lisp-graph-hookfft-window-betamake-highpassnotch-soundshow-selection-transform
after-open-hookfft-with-phasesmake-hilbert-transformnotch?show-sonogram-cursor
after-save-as-hookFFTsmake-hooknpcos?show-transform-peaks
after-save-state-hookfile databasemake-iir-filternrcosshow-widget
after-transform-hookfile->arraymake-int-vectornrcos?show-y-zero
all-chansfile->framplemake-iteratornrevsilence-all-mixes
all-passfile->frample?make-izcosnrsinsilence-mixes
all-pass-bankfile->samplemake-j0evencosnrsin?sinc-train
all-pass-bank?file->sample?make-j0j1cosnrssbsinc-train?
all-pass?file-namemake-j2cosnrssb-interpsinc-width
Alsafile-name (generic)make-jjcosnrssb?sine-env-channel
amp-controlfill!make-jncosnrxycossine-ramp
amp-control-boundsfill! (generic)make-jpcosnrxycos?singer
amplitude-modulatefill-polygonmake-jycosnrxysinsmooth-channel
analyse-ladspafill-rectanglemake-k2cosnrxysin?smooth-selection
anoifiltermake-k2sinnsinsmooth-sound
any-env-channelfilter-channelmake-k2ssbnsin?Smoothing
any-randomfilter-control-coeffsmake-k3sinnsincosSMS synthesis
apply-controlsfilter-control-envelopemake-krksinnsincos?snap-mark-to-beat
apply-ladspafilter-control-in-dBmake-locsignssbsnap-marks
aritable?filter-control-in-hzmake-lowpassnssb?snap-mix-to-beat
arityfilter-control-ordermake-mix-samplernxy1cossnd->sample
array->filefilter-control-waveform-colormake-move-soundnxy1cos?snd->sample?
array-interpfilter-control?make-moving-autocorrelationnxy1sinsnd-color
as-one-editfilter-fftmake-moving-averagenxy1sin?snd-error
ask-about-unsaved-editsfilter-selectionmake-moving-fftnxycossnd-error-hook
ask-before-overwritefilter-selection-and-smoothmake-moving-maxnxycos?snd-font
asyfm-Ifilter-soundmake-moving-normnxysinsnd-gcs
asyfm-Jfilter?make-moving-pitchnxysin?snd-help
asyfm?filtered-combmake-moving-scentroid snd-hooks
asymmetric-fmfiltered-comb-bankmake-moving-spectrum
O
*snd-opened-sound*
asymmetric-fm?filtered-comb-bank?make-n1cos snd-print
auto-resizefiltered-comb?make-nchoosekcosobject->stringsnd-spectrum
auto-saveFiltersmake-ncosodd-multiplesnd-tempnam
auto-updatefind-dialogmake-nkssbodd-weightsnd-url
auto-update-intervalfind-markmake-noddcosoffset-channelsnd-urls
autocorrelatefind-mixmake-noddsinoffset-soundsnd-version
autoloadfind-soundmake-noddssbone-polesnd-warning
axis-colorfinfomake-noidone-pole-all-passsnd-warning-hook
axis-infofinish-progress-reportmake-notchone-pole-all-pass?sndwarp
axis-label-fontfir-filtermake-nrcosone-pole?sort!
axis-numbers-fontfir-filter?make-nrsinone-zeroSound placement
firmantmake-nrssbone-zero?sound->amp-env
B
firmant?make-nrxycosopen-file-dialogsound->integer
fit-selection-between-marksmake-nrxysinopen-file-dialog-directorysound-file-extensions
background-gradientflatten-partialsmake-nsinopen-hooksound-file?
bad-header-hookfloat-vectormake-nsincosopen-next-file-in-directorysound-files-in-directory
bagpipefloat-vector*make-nssbopen-raw-soundsound-interp
basic-colorfloat-vector+make-nxy1cosopen-raw-sound-hooksound-loop-info
beats-per-measurefloat-vector->channelmake-nxy1sinopen-soundsound-properties
beats-per-minutefloat-vector->listmake-nxycosopenletsound-property
before-close-hookfloat-vector->stringmake-nxysinopenlet?sound-widgets
before-exit-hookfloat-vector-abs!make-one-poleorientation-hooksound?
before-save-as-hookfloat-vector-add!make-one-pole-all-passoscilsoundfont-info
before-save-state-hookfloat-vector-copymake-one-zerooscil-banksounds
before-transform-hookfloat-vector-equal?make-osciloscil-bank?sounds->segment-data
bes-j0float-vector-fill!make-oscil-bankoscil?spectra
bessfloat-vector-lengthmake-phase-vocoderout-anyspectral interpolation
bess?float-vector-maxmake-pink-noiseout-bankspectral-polynomial
bessel filtersfloat-vector-minmake-pixmapoutaspectro-hop
bigbirdfloat-vector-move!make-playeroutletspectro-x-angle
bignumfloat-vector-multiply!make-polyoid*output*spectro-x-scale
bignum?float-vector-offset!make-polyshapeoutput-comment-hookspectro-y-angle
binary filesfloat-vector-peakmake-polywaveoverlay-rms-envspectro-y-scale
bind-keyfloat-vector-polynomialmake-pulse-trainowletspectro-z-angle
birdfloat-vector-refmake-pulsed-env spectro-z-scale
blackmanfloat-vector-reverse!make-r2k!cos
P
spectrum
blackman4-env-channelfloat-vector-scale!make-r2k2cos spectrum->coeffs
blackman?float-vector-set!make-ramppad-channelspectrum-end
bold-peaks-fontfloat-vector-subseqmake-randpad-marksspectrum-start
breakfloat-vector-subtract!make-rand-interppad-soundspeed-control
brown-noisefloat-vector?make-rcospan-mixspeed-control-bounds
brown-noise?flocsigmake-readinpan-mix-float-vectorspeed-control-style
butterworth filtersflocsig?make-regionpartials->polynomialspeed-control-tones
byte-vectorflute modelmake-region-samplerpartials->wavespot-freq
byte-vector?fm-bellmake-rk!cospausingsquare-wave
fm-drummake-rk!ssbpeak-env-dirsquare-wave?
C
fm-noisemake-rkcospeakssquelch-update
fm-parallel-componentmake-rkoddssbpeaks-fontsquelch-vowels
c-definefm-talkermake-rksinphase-partials->wavesrate
c-g?fm-trumpetmake-rkssbphase-vocodersrate (generic)
c-object?fm-violinmake-round-interpphase-vocoder?src
c-pointerfm-voicemake-rssbPhysical Modelssrc-channel
c-pointer?fmssbmake-rxycospiano modelsrc-duration
call-with-exitfmssb?make-rxyk!cospink-noisesrc-fit-envelope
canterfocus-widgetmake-rxyk!sinpink-noise?src-mixes
cascade->canonicalFOF synthesismake-rxysinpinssrc-selection
catchfofinsmake-sample->fileplace-soundsrc-sound
cellonfor-each-childmake-samplerplaysrc?
chain-dspsfor-each-sound-filemake-sawtooth-waveplay (generic)ssb-am
channel->vctForbidden Planetmake-selectionplay-arrow-sizessb-am?
channel-amp-envsforeground-colormake-sinc-trainplay-between-marksssb-bank
channel-dataforget-regionmake-snd->sampleplay-hookssb-bank-env
channel-envelopeformantmake-sound-boxplay-mixesssb-fm
channel-polynomialformant-bankmake-spencer-filterplay-oftenstart-dac
channel-propertiesformant-bank?make-square-waveplay-region-foreverstart-playing
channel-propertyformant?make-srcplay-sinestart-playing-hook
channel-rmsformatmake-ssb-amplay-sinesstart-playing-selection-hook
channel-styleForthmake-table-lookupplay-syncd-marksstart-progress-report
channel-syncfpmake-table-lookup-with-envplay-until-c-gstatus-report
channel-widgetsfractional-fourier-transformmake-tanhsinplay-with-envsstereo->mono
channelsframple->filemake-triangle-waveplayer-homestereo-flute
channels (generic)frample->file?make-two-poleplayer?stop-player
channels-equal?frample->framplemake-two-zeroplayersstop-playing
channels=?framplesmake-variable-displayPlayingstop-playing-hook
chansframples (generic)make-variable-graphplayingstop-playing-selection-hook
char-positionfree-playermake-vctpluckstretch-envelope
cheby-hkafree-samplermake-wave-trainPluginsstretch-sound-via-dft
chebyshev filtersfreeverbmake-wave-train-with-envpolar->rectangularstring-position
check-mix-tagsFrequency Modulationmap-channelpolynomialsublet
chordalizefullmixmap-sound-filespolynomial operationssuperimpose-ffts
chorusfuncletmaracaspolyoidswap-channels
clean-channel mark->integerpolyoid-envswap-selection-channels
clean-sound
G
mark-click-hookpolyoid?symbol->dynamic-value
clear-listener mark-click-infopolyshapesymbol->value
clip-hookgaussian-distributionmark-colorpolyshape?symbol-access
clippinggc-offmark-contextpolywavesymbol-table
clm-channelgc-onmark-drag-hookpolywave?sync
clm-expsrcGeneratorsmark-explodeposition->xsync (generic)
close-hookgensymmark-homeposition->ysync-everything
close-soundgensym?mark-hookposition-colorsync-max
color->listgl-graph->psmark-loopspower-envsync-style
color-cutoffglSpectrogrammark-namepqwsyncd-marks
color-hookgoertzelmark-name->idpqw-voxsyncd-mixes
color-invertedgoto-listener-endmark-propertiespreferences-dialogsyncup
color-mixesgranimark-propertyprevious-sample
color-orientation-dialogGranular synthesismark-sampleprint-dialog
T
color-scalegranulatemark-syncprint-length
color?granulate?mark-sync-colorprocedure-documentationtable-lookup
colormapgranulated-sound-interpmark-sync-maxprocedure-settertable-lookup?
colormap->integergraphmark-tag-heightprocedure-signaturetanhsin
colormap-namegraph->psmark-tag-widthprocedure-sourcetanhsin?
colormap-refgraph-colormark?profiletap
colormap-sizegraph-cursorMarkingprogress-reporttap?
colormap?graph-datamarkspulse-traintelephone
Colorsgraph-hookmatch-sound-filespulse-train?temp-dir
combgraph-stylemax-envelopepulsed-envtext-focus-color
comb-bankgraphic equalizermax-regionspulsed-env?time-graph-style
comb-bank?graphs-horizontalmax-transform-peaks time-graph-type
comb?green-noisemaxamp
R
time-graph?
combined-data-colorgreen-noise-interpmaxamp (generic) times->samples
commentgreen-noise-interp?maxamp-positionr2k!costiny-font
Common Musicgreen-noise?Maxampsr2k!cos?touch-tone
complexifygrid-densitymenu-widgetsr2k2costrace
compute-uniform-circular-string menus, optionalr2k2cos?Tracking cursors
concatenate-envelopes
H
min-dBradians->degreestracking-cursor-style
constant? mixradians->hztransform->integer
continuation?harmonicizermix->float-vectorramp-channeltransform->vct
continue-frample->fileHartley transformmix->integerrandtransform-dialog
continue-sample->filehash-tablemix-amprand-interptransform-framples
contrast-channelhash-table*mix-amp-envrand-interp?transform-graph-style
contrast-controlhash-table-entriesmix-channelrand?transform-graph-type
contrast-control-amphash-table-refmix-click-hookrandomtransform-graph?
contrast-control-boundshash-table-set!mix-click-infoRandom Numberstransform-normalization
contrast-control?hash-table?mix-click-sets-amprandom-statetransform-sample
contrast-enhancementheader-typemix-colorrandom-state?transform-size
contrast-soundHeaders and sample typesmix-dialog-mixrcostransform-type
Control Panelhello-dentistmix-drag-hookrcos?transform?
controls->channelhelp-dialogmix-file-dialogread-hooktranspose-mixes
convolutionhelp-hookmix-homeread-mix-sampletriangle-wave
convolution reverbhide-widgetmix-lengthread-onlytriangle-wave?
convolvehighlight-colormix-maxampread-region-sampletubebell
convolve-fileshilbert-transformmix-nameread-sampletubular bell
convolve-selection-withhook-functionsmix-name->idread-sample-with-directiontwo-pole
convolve-withhook-membermix-positionreader-condtwo-pole?
convolve?Hooksmix-propertiesreadintwo-tab
copyhtmlmix-propertyreadin?two-zero
copy (generic)html-dirmix-regionrectangular->magnitudestwo-zero?
copy-contexthtml-programmix-release-hookrectangular->polar
copy-samplerhz->radiansmix-sampler?redo
U
Copying mix-selectionregion->integer
correlate
I
mix-soundregion->vctunbind-key
coverlet mix-speedregion-chans*unbound-variable-hook*
cross-fade (amplitude)iir-filtermix-syncregion-framplesunclip-channel
cross-fade (frequency domain)iir-filter?mix-sync-maxregion-graph-styleundo
cross-synthesisinmix-tag-heightregion-homeUndo and Redo
curletin-anymix-tag-widthregion-maxampundo-hook
current-fontinamix-tag-yregion-maxamp-positionunlet
cursorinbmix-vctregion-play-listunselect-all
cursor-colorinfo-dialogmix-waveform-heightregion-positionupdate-graphs
cursor-contextinit-ladspamix?region-rmsupdate-hook
cursor-location-offsetinitial-begmixesregion-sampleupdate-lisp-graph
cursor-positioninitial-durMixingregion-sampler?update-sound
cursor-sizeinitial-graph-hookmono->stereoregion-srateupdate-time-graph
cursor-styleInitialization filemoog-filterregion?update-transform-graph
cursor-update-intervalinletmorally-equal?regionsupon-save-yourself
Cursorsinsert-channelmouse-click-hookRegionsuser interface extensions
cutletinsert-file-dialogmouse-drag-hookremember-sound-state
cyclic-sequencesinsert-regionmouse-enter-graph-hookremove-clicks
V
insert-samplemouse-enter-label-hookremove-from-menu
D
insert-samplesmouse-enter-listener-hookreplace-with-selectionvariable-display
insert-selectionmouse-enter-text-hookreport-mark-namesvariable-graph?
dac-combines-channelsinsert-silencemouse-leave-graph-hookrequirevarlet
dac-sizeinsert-soundmouse-leave-label-hookResamplingvct
data-colorInsertionsmouse-leave-listener-hookreset-all-hooksvct*
data-locationint-vectormouse-leave-text-hookreset-controlsvct+
data-sizeint-vector-refmouse-press-hookreset-listener-cursorvct->channel
db->linearint-vector-set!move-locsigresonvct->list
Debugging (C)int-vector?move-mixesrestore-controlsvct->string
Debugging (instruments)integer->colormapmove-soundReverbvct->vector
Debugging (Scheme)integer->markmove-sound?*reverb*vct-abs!
default-output-chansinteger->mixmove-syncd-marksreverb-control-decayvct-add!
default-output-header-typeinteger->regionmoving-autocorrelationreverb-control-feedbackvct-copy
default-output-sample-typeinteger->soundmoving-autocorrelation?reverb-control-lengthvct-equal?
default-output-srateinteger->transformmoving-averagereverb-control-length-boundsvct-fill!
defgeneratorintegrate-envelopemoving-average?reverb-control-lowpassvct-length
define*invert-filtermoving-fftreverb-control-scalevct-max
define-constantInvocation flagsmoving-fft?reverb-control-scale-boundsvct-min
define-envelopeiteratemoving-lengthreverb-control?vct-move!
define-expansioniterator-at-end?moving-maxreverse!vct-multiply!
define-macroiterator-sequencemoving-max?reverse-by-blocksvct-offset!
define-macro*iterator?moving-normreverse-channelvct-peak
define-selection-via-marksizcosmoving-norm?reverse-envelopevct-ref
defined?izcos?moving-pitchreverse-selectionvct-reverse!
degrees->radians moving-pitch?reverse-soundvct-scale!
delay
J
moving-rmsReversingvct-set!
delay-channel-mixes moving-scentroidrevert-soundvct-subseq
delay-tickj0evencosmoving-scentroid?right-samplevct-subtract!
delay?j0evencos?moving-spectrumring-modulatevct?
delete-colormapj0j1cosmoving-spectrum?rk!cosVcts
delete-file-filterj0j1cos?moving-sumrk!cos?vector->vct
delete-file-sorterj2cosmpgrk!ssbview-files-amp
delete-markj2cos?mus-alsa-buffer-sizerk!ssb?view-files-amp-env
delete-marksJackmus-alsa-buffersrkcosview-files-dialog
delete-samplejc-reverbmus-alsa-capture-devicerkcos?view-files-files
delete-samplesjjcosmus-alsa-devicerkoddssbview-files-select-hook
delete-samples-and-smoothjjcos?mus-alsa-playback-devicerkoddssb?view-files-selected-files
delete-selectionjncosmus-alsa-squelch-warningrksinview-files-sort
delete-selection-and-smoothjncos?mus-array-print-lengthrksin?view-files-speed
delete-transformjpcosmus-bytes-per-samplerkssbview-files-speed-style
Deletionsjpcos?mus-channelrkssb?view-mixes-dialog
describe-hookjust-soundsmus-channelsrmsview-regions-dialog
describe-markjycosmus-chebyshev-tu-sumrms, gain, balance gensview-sound
dhtjycos?mus-clippingrms-envelopevoice physical model
dialog-widgets mus-closerootletvoiced->unvoiced
dilambda
K
mus-copyround-interpvolterra-filter
disable-control-panel mus-dataround-interp?vox
display-bark-fftk2cosmus-describerssb
display-correlationk2cos?mus-error-hookrssb-interp
W
display-dbk2sinmus-error-type->stringrssb?
display-editsk2sin?mus-expand-filenamerubber-soundwave-train
display-energyk2ssbmus-feedbackRubywave-train?
dissolve-fadek2ssb?mus-feedforwardrxycoswavelet-type
dither-channelk3sinmus-fftrxycos?waveshaping voice
dither-soundk3sin?mus-file-buffer-sizerxyk!coswavo-hop
dolphkalman-filter-channelmus-file-clippingrxyk!cos?wavo-trace
dot-productkeymus-file-mixrxyk!sinweighted-moving-average
dot-sizekey-bindingmus-file-namerxyk!sin?widget-position
down-octkey-press-hookmus-float-equal-fudge-factorrxysinwidget-size
draw-axeskrksinmus-frequencyrxysin?widget-text
draw-dotkrksin?mus-generator? Window size and position
draw-dots mus-header-raw-defaults
S
window-height
draw-line
L
mus-header-type->string window-samples
draw-lines mus-header-type-names7 schemewindow-width
draw-mark-hookladspa-descriptormus-hopsamplewindow-x
draw-mix-hookladspa-dirmus-incrementsample->filewindow-y
draw-stringlambda*mus-input?sample->file?with-background-processes
dronelbj-pianomus-interp-typesample-typewith-baffle
drop sitesleft-samplemus-interpolatesampler-at-end?with-file-monitor
drop-hooklength (generic)mus-lengthsampler-homewith-gl
during-open-hooklet->listmus-locationsampler-positionwith-inset-graph
let-refmus-max-mallocsampler?with-interrupts
E
let-set!mus-max-table-sizesamplerswith-let
let?mus-namesampleswith-local-hook
Edit listslinear->dbmus-offsetsamples->secondswith-menu-icons
edit-fragmentlinear-src-channelmus-ordersash-colorwith-mix-tags
edit-header-dialoglint for schememus-oss-set-bufferssave-as-dialog-auto-commentwith-pointer-focus
edit-hooklisp-graph-hookmus-output?save-as-dialog-srcwith-relative-panes
edit-list->functionlisp-graph-stylemus-phasesave-controlswith-smpte-label
edit-positionlisp-graph?mus-rampsave-dirwith-sound
edit-propertieslist->float-vectormus-rand-seedsave-edit-historywith-temporary-selection
edit-propertylist->vctmus-randomsave-envelopeswith-toolbar
edit-treelist-ladspamus-resetsave-hookwith-tooltips
editslistener-click-hookmus-runsave-listenerwith-tracking-cursor
edot-productlistener-colormus-sample-type->stringsave-mark-propertieswith-verbose-cursor
effects-hooklistener-colorizedmus-sample-type-namesave-marks
elliptic filterslistener-fontmus-scalersave-mix
X
Emacs and Sndlistener-promptmus-sound-chanssave-region
envlistener-selectionmus-sound-close-inputsave-region-dialogx->position
env-anylistener-text-colormus-sound-close-outputsave-selectionx-axis-label
env-channellittle-endian?mus-sound-commentsave-selection-dialogx-axis-style
env-channel-with-base*load-hook*mus-sound-data-locationsave-soundx-bounds
env-expt-channel*load-path*mus-sound-datum-sizesave-sound-asx-position-slider
env-interplocate-zeromus-sound-durationsave-sound-dialogx-zoom-slider
env-mixeslocsigmus-sound-forgetsave-statexb-open
env-selectionlocsig-refmus-sound-framplessave-state-filexramp-channel
env-soundlocsig-reverb-refmus-sound-header-typesave-state-hook
env-sound-interplocsig-reverb-set!mus-sound-lengthSaving
Y
env-squared-channellocsig-set!mus-sound-loop-infosavitzky-golay-filter
env?locsig-typemus-sound-mark-infosawtooth-wavey->position
enved-baselocsig?mus-sound-maxampsawtooth-wave?y-axis-label
enved-clip?log-freq-startmus-sound-maxamp-exists?scale-byy-bounds
enved-dialoglpc-coeffsmus-sound-open-inputscale-channely-position-slider
enved-envelopelpc-predictmus-sound-open-outputscale-envelopey-zoom-slider
enved-filter mus-sound-pathscale-mixes
enved-filter-order
M
mus-sound-preloadscale-selection-by
Z
enved-hook mus-sound-prunescale-selection-to
enved-in-dBmacro?mus-sound-readscale-soundz-transform
enved-powermacroexpandmus-sound-reopen-outputscale-tempozecho
enved-stylemain-menumus-sound-report-cachescale-tozero+
enved-targetmain-widgetsmus-sound-sample-typescan-channelzero-pad
enved-wave?make-abcosmus-sound-samplesscanned synthesiszero-phase
enved-waveform-colormake-absinmus-sound-seek-framplescentroidzip-sound
envelope-interpmake-adjustable-sawtooth-wavemus-sound-sratescratchzipper
enveloped-mixmake-adjustable-square-wavemus-sound-type-specifierscript-argzoom-color
Envelopesmake-adjustable-triangle-wavemus-sound-writescript-argszoom-focus-style
eoddcosmake-all-passmus-sound-write-dateScripting
eoddcos?make-all-pass-bankmus-sratesearch-for-click
eps-bottom-marginmake-asyfmmus-widthsearch-procedure
eps-filemake-asymmetric-fmmus-xcoeffSearching
snd-16.1/snd.c0000644000076400007640000011565312541135102011270 0ustar bilbil/* Sound display/edit/etc * * originally intended as a re-implementation of my much-missed dpysnd -- the Foonly/SAIL/E/Mus10/Grnlib sound editor from ca 1983. */ #include "snd.h" snd_state *ss = NULL; static bool ignore_mus_error(int type, char *msg) { Xen result = Xen_false; if (Xen_hook_has_list(ss->mus_error_hook)) result = run_or_hook(ss->mus_error_hook, Xen_list_2(C_int_to_Xen_integer(type), C_string_to_Xen_string(msg)), S_mus_error_hook); return(Xen_is_true(result)); } #ifndef _MSC_VER void top_level_catch(int ignore); #endif static void mus_error_to_snd(int type, char *msg) { if (!ss) { fprintf(stderr, "%s", msg); return; } if (!(ignore_mus_error(type, msg))) { #if HAVE_EXTENSION_LANGUAGE if (msg == NULL) Xen_error(Xen_make_error_type("mus-error"), Xen_list_1(C_string_to_Xen_string((char *)mus_error_type_to_string(type)))); else Xen_error(Xen_make_error_type("mus-error"), Xen_list_1(C_string_to_Xen_string(msg))); #endif snd_error("%s: %s", mus_error_type_to_string(type), msg); #ifndef _MSC_VER ss->jump_ok = true; top_level_catch(1); /* sigh -- try to keep going */ #endif } } static void mus_print_to_snd(char *msg) { if (!ss) { fprintf(stderr, "%s", msg); return; } if (!(ignore_mus_error(MUS_NO_ERROR, msg))) if (msg) { int i, len; listener_append(";"); len = strlen(msg); for (i = 1; i < len - 1; i++) if ((msg[i] == '\n') && (msg[i + 1] == ' ')) msg[i + 1] = ';'; if (msg[0] == '\n') listener_append((char *)(msg + 1)); else listener_append(msg); if (msg[strlen(msg) - 1] != '\n') listener_append("\n"); } } static void initialize_load_path(void) { /* look for SND_PATH env var, add dirs to %load-path or load_path */ char *path; path = getenv("SND_PATH"); if (path) { /* colon-separated list of directory names, pushed on load-path in reverse order (hopefully = search order) */ int i, len, dirs = 1, curdir = 0, start = 0; char **dirnames; len = strlen(path); for (i = 0; i < len; i++) if (path[i] == ':') dirs++; dirnames = (char **)calloc(dirs, sizeof(char *)); for (i = 0; i < len; i++) { if ((path[i] == ':') || (i == len - 1)) { if (i > start) { int j, lim; char *tmp; if (i == (len - 1)) lim = i + 1; else lim = i; tmp = (char *)calloc(lim - start + 1, sizeof(char)); for (j = start; j < lim; j++) tmp[j - start] = path[j]; dirnames[curdir++] = mus_expand_filename(tmp); start = i + 1; free(tmp); } } } for (i = curdir - 1; i >= 0; i--) { Xen_add_to_load_path(dirnames[i]); free(dirnames[i]); } free(dirnames); } } void snd_set_global_defaults(bool need_cleanup) { if (need_cleanup) { if (ss->HTML_Program) {free(ss->HTML_Program); ss->HTML_Program = NULL;} if (ss->HTML_Dir) {free(ss->HTML_Dir); ss->HTML_Dir = NULL;} if (ss->Temp_Dir) {free(ss->Temp_Dir); ss->Temp_Dir = NULL;} if (ss->Save_Dir) {free(ss->Save_Dir); ss->Save_Dir = NULL;} if (ss->Ladspa_Dir) {free(ss->Ladspa_Dir); ss->Ladspa_Dir = NULL;} if (ss->Save_State_File) {free(ss->Save_State_File); ss->Save_State_File = NULL;} if (ss->Eps_File) {free(ss->Eps_File); ss->Eps_File = NULL;} if (ss->Listener_Prompt) {free(ss->Listener_Prompt); ss->Listener_Prompt = NULL;} if (ss->Open_File_Dialog_Directory) {free(ss->Open_File_Dialog_Directory); ss->Open_File_Dialog_Directory = NULL;} /* not sure about the next two... */ if ((cursor_style(ss) == CURSOR_PROC) && (Xen_is_procedure(ss->cursor_proc))) snd_unprotect_at(ss->cursor_proc_loc); if ((zoom_focus_style(ss) == ZOOM_FOCUS_PROC) && (Xen_is_procedure(ss->zoom_focus_proc))) snd_unprotect_at(ss->zoom_focus_proc_loc); } ss->Transform_Size = DEFAULT_TRANSFORM_SIZE; ss->Fft_Window = DEFAULT_FFT_WINDOW; ss->Fft_Window_Alpha = DEFAULT_FFT_WINDOW_ALPHA; ss->Fft_Window_Beta = DEFAULT_FFT_WINDOW_BETA; ss->Transform_Graph_Type = DEFAULT_TRANSFORM_GRAPH_TYPE; ss->Sinc_Width = DEFAULT_SINC_WIDTH; ss->Zero_Pad = DEFAULT_ZERO_PAD; ss->Wavelet_Type = DEFAULT_WAVELET_TYPE; ss->Transform_Type = DEFAULT_TRANSFORM_TYPE; ss->Transform_Normalization = DEFAULT_TRANSFORM_NORMALIZATION; ss->Show_Transform_Peaks = DEFAULT_SHOW_TRANSFORM_PEAKS; ss->Show_Sonogram_Cursor = DEFAULT_SHOW_SONOGRAM_CURSOR; ss->Fft_Log_Magnitude = DEFAULT_FFT_LOG_MAGNITUDE; ss->Fft_Log_Frequency = DEFAULT_FFT_LOG_FREQUENCY; ss->Fft_With_Phases = DEFAULT_FFT_WITH_PHASES; ss->Max_Transform_Peaks = DEFAULT_MAX_TRANSFORM_PEAKS; ss->Log_Freq_Start = DEFAULT_LOG_FREQ_START; ss->Min_dB = DEFAULT_MIN_DB; ss->lin_dB = pow(10.0, DEFAULT_MIN_DB * 0.05); ss->Show_Selection_Transform = DEFAULT_SHOW_SELECTION_TRANSFORM; ss->Default_Output_Chans = DEFAULT_OUTPUT_CHANS; ss->Default_Output_Srate = DEFAULT_OUTPUT_SRATE; ss->Default_Output_Header_Type = DEFAULT_OUTPUT_HEADER_TYPE; ss->Default_Output_Sample_Type = DEFAULT_OUTPUT_SAMPLE_TYPE; ss->Dac_Size = DEFAULT_DAC_SIZE; ss->Dac_Combines_Channels = DEFAULT_DAC_COMBINES_CHANNELS; ss->Auto_Resize = DEFAULT_AUTO_RESIZE; ss->Auto_Update = DEFAULT_AUTO_UPDATE; ss->Auto_Update_Interval = DEFAULT_AUTO_UPDATE_INTERVAL; ss->Ask_Before_Overwrite = DEFAULT_ASK_BEFORE_OVERWRITE; ss->With_Toolbar = DEFAULT_WITH_TOOLBAR; ss->With_Tooltips = DEFAULT_WITH_TOOLTIPS; ss->Remember_Sound_State = DEFAULT_REMEMBER_SOUND_STATE; ss->Ask_About_Unsaved_Edits = DEFAULT_ASK_ABOUT_UNSAVED_EDITS; ss->Save_As_Dialog_Src = DEFAULT_SAVE_AS_DIALOG_SRC; ss->Save_As_Dialog_Auto_Comment = DEFAULT_SAVE_AS_DIALOG_AUTO_COMMENT; ss->Show_Full_Duration = DEFAULT_SHOW_FULL_DURATION; ss->Show_Full_Range = DEFAULT_SHOW_FULL_RANGE; ss->Initial_Beg = DEFAULT_INITIAL_BEG; ss->Initial_Dur = DEFAULT_INITIAL_DUR; ss->With_Background_Processes = DEFAULT_WITH_BACKGROUND_PROCESSES; ss->With_File_Monitor = DEFAULT_WITH_FILE_MONITOR; ss->Selection_Creates_Region = DEFAULT_SELECTION_CREATES_REGION; ss->Channel_Style = DEFAULT_CHANNEL_STYLE; ss->Sound_Style = DEFAULT_SOUND_STYLE; ss->Graphs_Horizontal = DEFAULT_GRAPHS_HORIZONTAL; ss->Graph_Style = DEFAULT_GRAPH_STYLE; ss->Region_Graph_Style = DEFAULT_GRAPH_STYLE; ss->Time_Graph_Type = DEFAULT_TIME_GRAPH_TYPE; ss->X_Axis_Style = DEFAULT_X_AXIS_STYLE; ss->Beats_Per_Minute = DEFAULT_BEATS_PER_MINUTE; ss->Beats_Per_Measure = DEFAULT_BEATS_PER_MEASURE; ss->With_Relative_Panes = DEFAULT_WITH_RELATIVE_PANES; ss->With_GL = DEFAULT_WITH_GL; ss->Dot_Size = DEFAULT_DOT_SIZE; ss->Grid_Density = DEFAULT_GRID_DENSITY; ss->Zoom_Focus_Style = DEFAULT_ZOOM_FOCUS_STYLE; ss->zoom_focus_proc = Xen_undefined; ss->zoom_focus_proc_loc = NOT_A_GC_LOC; ss->Max_Regions = DEFAULT_MAX_REGIONS; ss->Show_Y_Zero = DEFAULT_SHOW_Y_ZERO; ss->Show_Grid = DEFAULT_SHOW_GRID; ss->Show_Axes = DEFAULT_SHOW_AXES; ss->Show_Indices = DEFAULT_SHOW_INDICES; ss->With_Inset_Graph = DEFAULT_WITH_INSET_GRAPH; ss->With_Interrupts = DEFAULT_WITH_INTERRUPTS; ss->With_Menu_Icons = DEFAULT_WITH_MENU_ICONS; ss->With_Smpte_Label = DEFAULT_WITH_SMPTE_LABEL; ss->With_Pointer_Focus = DEFAULT_WITH_POINTER_FOCUS; ss->Play_Arrow_Size = DEFAULT_PLAY_ARROW_SIZE; ss->Sync_Style = DEFAULT_SYNC_STYLE; ss->Listener_Prompt = mus_strdup(DEFAULT_LISTENER_PROMPT); ss->listener_prompt_length = mus_strlen(ss->Listener_Prompt); ss->Clipping = DEFAULT_CLIPPING; ss->Print_Length = DEFAULT_PRINT_LENGTH; ss->View_Files_Sort = DEFAULT_VIEW_FILES_SORT; ss->Just_Sounds = DEFAULT_JUST_SOUNDS; ss->Open_File_Dialog_Directory = NULL; ss->HTML_Dir = mus_strdup(DEFAULT_HTML_DIR); ss->HTML_Program = mus_strdup(DEFAULT_HTML_PROGRAM); ss->Cursor_Size = DEFAULT_CURSOR_SIZE; ss->Cursor_Style = DEFAULT_CURSOR_STYLE; ss->Tracking_Cursor_Style = DEFAULT_TRACKING_CURSOR_STYLE; ss->With_Tracking_Cursor = DEFAULT_WITH_TRACKING_CURSOR; ss->cursor_proc = Xen_undefined; ss->cursor_proc_loc = NOT_A_GC_LOC; ss->With_Verbose_Cursor = DEFAULT_WITH_VERBOSE_CURSOR; ss->Cursor_Update_Interval = DEFAULT_CURSOR_UPDATE_INTERVAL; ss->Cursor_Location_Offset = DEFAULT_CURSOR_LOCATION_OFFSET; ss->Show_Mix_Waveforms = DEFAULT_SHOW_MIX_WAVEFORMS; ss->Mix_Waveform_Height = DEFAULT_MIX_WAVEFORM_HEIGHT; ss->Mix_Tag_Width = DEFAULT_MIX_TAG_WIDTH; ss->Mix_Tag_Height = DEFAULT_MIX_TAG_HEIGHT; ss->With_Mix_Tags = DEFAULT_WITH_MIX_TAGS; ss->Mark_Tag_Width = DEFAULT_MARK_TAG_WIDTH; ss->Mark_Tag_Height = DEFAULT_MARK_TAG_HEIGHT; ss->Show_Marks = DEFAULT_SHOW_MARKS; ss->Color_Map = DEFAULT_COLOR_MAP; ss->Color_Map_Size = DEFAULT_COLOR_MAP_SIZE; ss->Color_Cutoff = DEFAULT_COLOR_CUTOFF; ss->Color_Scale = DEFAULT_COLOR_SCALE; ss->Color_Inverted = DEFAULT_COLOR_INVERTED; ss->Color_Map = DEFAULT_COLOR_MAP; ss->Wavo_Hop = DEFAULT_WAVO_HOP; ss->Wavo_Trace = DEFAULT_WAVO_TRACE; ss->Spectro_Hop = DEFAULT_SPECTRO_HOP; ss->Spectro_X_Scale = DEFAULT_SPECTRO_X_SCALE; ss->Spectro_Y_Scale = DEFAULT_SPECTRO_Y_SCALE; ss->Spectro_Z_Scale = DEFAULT_SPECTRO_Z_SCALE; ss->Spectro_Z_Angle = DEFAULT_SPECTRO_Z_ANGLE; ss->Spectro_X_Angle = DEFAULT_SPECTRO_X_ANGLE; ss->Spectro_Y_Angle = DEFAULT_SPECTRO_Y_ANGLE; ss->Spectrum_End = DEFAULT_SPECTRUM_END; ss->Spectrum_Start = DEFAULT_SPECTRUM_START; ss->Enved_Base = DEFAULT_ENVED_BASE; ss->Enved_Power = DEFAULT_ENVED_POWER; ss->Enved_With_Wave = DEFAULT_ENVED_WITH_WAVE; ss->Enved_Style = DEFAULT_ENVED_STYLE; ss->Enved_Target = DEFAULT_ENVED_TARGET; ss->Enved_Filter_Order = DEFAULT_ENVED_FILTER_ORDER; ss->Eps_Bottom_Margin = DEFAULT_EPS_BOTTOM_MARGIN; ss->Eps_Left_Margin = DEFAULT_EPS_LEFT_MARGIN; ss->Eps_Size = DEFAULT_EPS_SIZE; ss->Expand_Control_Min = DEFAULT_EXPAND_CONTROL_MIN; ss->Expand_Control_Max = DEFAULT_EXPAND_CONTROL_MAX; ss->Amp_Control_Min = DEFAULT_AMP_CONTROL_MIN; ss->Amp_Control_Max = DEFAULT_AMP_CONTROL_MAX; ss->Speed_Control_Min = DEFAULT_SPEED_CONTROL_MIN; ss->Speed_Control_Max = DEFAULT_SPEED_CONTROL_MAX; ss->Contrast_Control_Min = DEFAULT_CONTRAST_CONTROL_MIN; ss->Contrast_Control_Max = DEFAULT_CONTRAST_CONTROL_MAX; ss->Contrast_Control_Amp = DEFAULT_CONTRAST_CONTROL_AMP; ss->Expand_Control_Length = DEFAULT_EXPAND_CONTROL_LENGTH; ss->Expand_Control_Ramp = DEFAULT_EXPAND_CONTROL_RAMP; ss->Expand_Control_Hop = DEFAULT_EXPAND_CONTROL_HOP; ss->Expand_Control_Jitter = DEFAULT_EXPAND_CONTROL_JITTER; ss->Reverb_Control_Feedback = DEFAULT_REVERB_CONTROL_FEEDBACK; ss->Reverb_Control_Lowpass = DEFAULT_REVERB_CONTROL_LOWPASS; ss->Reverb_Control_Scale_Min = DEFAULT_REVERB_CONTROL_SCALE_MIN; ss->Reverb_Control_Scale_Max = DEFAULT_REVERB_CONTROL_SCALE_MAX; ss->Reverb_Control_Decay = DEFAULT_REVERB_CONTROL_DECAY; ss->Speed_Control_Tones = DEFAULT_SPEED_CONTROL_TONES; ss->Speed_Control_Style = DEFAULT_SPEED_CONTROL_STYLE; ss->Reverb_Control_Length_Min = DEFAULT_REVERB_CONTROL_LENGTH_MIN; ss->Reverb_Control_Length_Max = DEFAULT_REVERB_CONTROL_LENGTH_MAX; ss->Filter_Control_Order = DEFAULT_FILTER_CONTROL_ORDER; ss->Filter_Control_In_Db = DEFAULT_FILTER_CONTROL_IN_DB; ss->Filter_Control_In_Hz = DEFAULT_FILTER_CONTROL_IN_HZ; ss->Show_Controls = DEFAULT_SHOW_CONTROLS; if (MUS_DEFAULT_TEMP_DIR != (char *)NULL) ss->Temp_Dir = mus_strdup(MUS_DEFAULT_TEMP_DIR); else ss->Temp_Dir = NULL; if (MUS_DEFAULT_SAVE_DIR != (char *)NULL) ss->Save_Dir = mus_strdup(MUS_DEFAULT_SAVE_DIR); else ss->Save_Dir = NULL; if (DEFAULT_LADSPA_DIR != (char *)NULL) ss->Ladspa_Dir = mus_strdup(DEFAULT_LADSPA_DIR); else ss->Ladspa_Dir = NULL; if (DEFAULT_SAVE_STATE_FILE != (char *)NULL) ss->Save_State_File = mus_strdup(DEFAULT_SAVE_STATE_FILE); else ss->Save_State_File = NULL; if (DEFAULT_PEAK_ENV_DIR != (char *)NULL) ss->Peak_Env_Dir = mus_strdup(DEFAULT_PEAK_ENV_DIR); else ss->Peak_Env_Dir = NULL; if (DEFAULT_EPS_FILE != (char *)NULL) ss->Eps_File = mus_strdup(DEFAULT_EPS_FILE); else ss->Eps_File = NULL; #if HAVE_SCHEME ss->eps_file_symbol = s7_define_variable(s7, "*" S_eps_file "*", s7_make_string(s7, DEFAULT_EPS_FILE)); ss->enved_filter_order_symbol = s7_define_variable(s7, "*" S_enved_filter_order "*", s7_make_integer(s7, DEFAULT_ENVED_FILTER_ORDER)); ss->eps_left_margin_symbol = s7_define_variable(s7, "*" S_eps_left_margin "*", s7_make_real(s7, DEFAULT_EPS_LEFT_MARGIN)); ss->eps_bottom_margin_symbol = s7_define_variable(s7, "*" S_eps_bottom_margin "*", s7_make_real(s7, DEFAULT_EPS_BOTTOM_MARGIN)); ss->eps_size_symbol = s7_define_variable(s7, "*" S_eps_size "*", s7_make_real(s7, DEFAULT_EPS_SIZE)); ss->log_freq_start_symbol = s7_define_variable(s7, "*" S_log_freq_start "*", s7_make_real(s7, DEFAULT_LOG_FREQ_START)); ss->color_map_symbol = s7_define_variable(s7, "*" S_colormap "*", s7_make_integer(s7, DEFAULT_COLOR_MAP)); ss->color_map_size_symbol = s7_define_variable(s7, "*" S_colormap_size "*", s7_make_integer(s7, DEFAULT_COLOR_MAP_SIZE)); ss->mix_waveform_height_symbol = s7_define_variable(s7, "*" S_mix_waveform_height "*", s7_make_integer(s7, DEFAULT_MIX_WAVEFORM_HEIGHT)); ss->sinc_width_symbol = s7_define_variable(s7, "*" S_sinc_width "*", s7_make_integer(s7, DEFAULT_SINC_WIDTH)); ss->region_graph_style_symbol = s7_define_variable(s7, "*" S_region_graph_style "*", s7_make_integer(s7, ss->Region_Graph_Style)); ss->max_regions_symbol = s7_define_variable(s7, "*" S_max_regions "*", s7_make_integer(s7, DEFAULT_MAX_REGIONS)); ss->with_gl_symbol = s7_define_variable(s7, "*" S_with_gl "*", s7_make_boolean(s7, DEFAULT_WITH_GL)); ss->with_relative_panes_symbol = s7_define_variable(s7, "*" S_with_relative_panes "*", s7_make_boolean(s7, DEFAULT_WITH_RELATIVE_PANES)); ss->dac_size_symbol = s7_define_variable(s7, "*" S_dac_size "*", s7_make_integer(s7, DEFAULT_DAC_SIZE)); ss->view_files_sort_symbol = s7_define_variable(s7, "*" S_view_files_sort "*", s7_make_integer(s7, DEFAULT_VIEW_FILES_SORT)); ss->dac_combines_channels_symbol = s7_define_variable(s7, "*" S_dac_combines_channels "*", s7_make_boolean(s7, DEFAULT_DAC_COMBINES_CHANNELS)); ss->show_selection_transform_symbol = s7_define_variable(s7, "*" S_show_selection_transform "*", s7_make_boolean(s7, DEFAULT_SHOW_SELECTION_TRANSFORM)); ss->with_mix_tags_symbol = s7_define_variable(s7, "*" S_with_mix_tags "*", s7_make_boolean(s7, DEFAULT_WITH_MIX_TAGS)); ss->listener_prompt_symbol = s7_define_variable(s7, "*" S_listener_prompt "*", s7_make_string(s7, DEFAULT_LISTENER_PROMPT)); ss->enved_base_symbol = s7_define_variable(s7, "*" S_enved_base "*", s7_make_real(s7, DEFAULT_ENVED_BASE)); ss->enved_power_symbol = s7_define_variable(s7, "*" S_enved_power "*", s7_make_real(s7, DEFAULT_ENVED_POWER)); ss->enved_with_wave_symbol = s7_define_variable(s7, "*" S_enved_with_wave "*", s7_make_boolean(s7, DEFAULT_ENVED_WITH_WAVE)); ss->enved_style_symbol = s7_define_variable(s7, "*" S_enved_style "*", s7_make_integer(s7, DEFAULT_ENVED_STYLE)); ss->graph_cursor_symbol = s7_define_variable(s7, "*" S_graph_cursor "*", s7_make_integer(s7, DEFAULT_GRAPH_CURSOR)); ss->mix_tag_width_symbol = s7_define_variable(s7, "*" S_mix_tag_width "*", s7_make_integer(s7, DEFAULT_MIX_TAG_WIDTH)); ss->mix_tag_height_symbol = s7_define_variable(s7, "*" S_mix_tag_height "*", s7_make_integer(s7, DEFAULT_MIX_TAG_HEIGHT)); ss->mark_tag_height_symbol = s7_define_variable(s7, "*" S_mark_tag_height "*", s7_make_integer(s7, DEFAULT_MARK_TAG_HEIGHT)); ss->mark_tag_width_symbol = s7_define_variable(s7, "*" S_mark_tag_width "*", s7_make_integer(s7, DEFAULT_MARK_TAG_WIDTH)); ss->enved_target_symbol = s7_define_variable(s7, "*" S_enved_target "*", s7_make_integer(s7, DEFAULT_ENVED_TARGET)); ss->cursor_update_interval_symbol = s7_define_variable(s7, "*" S_cursor_update_interval "*", s7_make_real(s7, DEFAULT_CURSOR_UPDATE_INTERVAL)); ss->cursor_location_offset_symbol = s7_define_variable(s7, "*" S_cursor_location_offset "*", s7_make_integer(s7, DEFAULT_CURSOR_LOCATION_OFFSET)); ss->show_controls_symbol = s7_define_variable(s7, "*" S_show_controls "*", s7_make_boolean(s7, DEFAULT_SHOW_CONTROLS)); ss->with_tracking_cursor_symbol = s7_define_variable(s7, "*" S_with_tracking_cursor "*", s7_make_integer(s7, (int)DEFAULT_WITH_TRACKING_CURSOR)); ss->html_dir_symbol = s7_define_variable(s7, "*" S_html_dir "*", s7_make_string(s7, DEFAULT_HTML_DIR)); ss->html_program_symbol = s7_define_variable(s7, "*" S_html_program "*", s7_make_string(s7, DEFAULT_HTML_PROGRAM)); ss->open_file_dialog_directory_symbol = s7_define_variable(s7, "*" S_open_file_dialog_directory "*", s7_make_string(s7, ss->Open_File_Dialog_Directory)); /* snd-file.c */ ss->auto_update_symbol = s7_define_variable(s7, "*" S_auto_update "*", s7_make_boolean(s7, DEFAULT_AUTO_UPDATE)); ss->auto_update_interval_symbol = s7_define_variable(s7, "*" S_auto_update_interval "*", s7_make_real(s7, DEFAULT_AUTO_UPDATE_INTERVAL)); ss->clipping_symbol = s7_define_variable(s7, "*" S_clipping "*", s7_make_boolean(s7, DEFAULT_CLIPPING)); ss->default_output_header_type_symbol = s7_define_variable(s7, "*" S_default_output_header_type "*", s7_make_integer(s7, DEFAULT_OUTPUT_HEADER_TYPE)); ss->default_output_sample_type_symbol = s7_define_variable(s7, "*" S_default_output_sample_type "*", s7_make_integer(s7, DEFAULT_OUTPUT_SAMPLE_TYPE)); ss->default_output_chans_symbol = s7_define_variable(s7, "*" S_default_output_chans "*", s7_make_integer(s7, DEFAULT_OUTPUT_CHANS)); ss->default_output_srate_symbol = s7_define_variable(s7, "*" S_default_output_srate "*", s7_make_integer(s7, DEFAULT_OUTPUT_SRATE)); ss->ask_before_overwrite_symbol = s7_define_variable(s7, "*" S_ask_before_overwrite "*", s7_make_boolean(s7, DEFAULT_ASK_BEFORE_OVERWRITE)); ss->ask_about_unsaved_edits_symbol = s7_define_variable(s7, "*" S_ask_about_unsaved_edits "*", s7_make_boolean(s7, DEFAULT_ASK_ABOUT_UNSAVED_EDITS)); ss->show_full_duration_symbol = s7_define_variable(s7, "*" S_show_full_duration "*", s7_make_boolean(s7, DEFAULT_SHOW_FULL_DURATION)); ss->show_full_range_symbol = s7_define_variable(s7, "*" S_show_full_range "*", s7_make_boolean(s7, DEFAULT_SHOW_FULL_RANGE)); ss->remember_sound_state_symbol = s7_define_variable(s7, "*" S_remember_sound_state "*", s7_make_boolean(s7, DEFAULT_REMEMBER_SOUND_STATE)); ss->save_as_dialog_src_symbol = s7_define_variable(s7, "*" S_save_as_dialog_src "*", s7_make_boolean(s7, DEFAULT_SAVE_AS_DIALOG_SRC)); ss->save_as_dialog_auto_comment_symbol = s7_define_variable(s7, "*" S_save_as_dialog_auto_comment "*", s7_make_boolean(s7, DEFAULT_SAVE_AS_DIALOG_AUTO_COMMENT)); ss->with_toolbar_symbol = s7_define_variable(s7, "*" S_with_toolbar "*", s7_make_boolean(s7, DEFAULT_WITH_TOOLBAR)); ss->with_tooltips_symbol = s7_define_variable(s7, "*" S_with_tooltips "*", s7_make_boolean(s7, DEFAULT_WITH_TOOLTIPS)); ss->with_menu_icons_symbol = s7_define_variable(s7, "*" S_with_menu_icons "*", s7_make_boolean(s7, DEFAULT_WITH_MENU_ICONS)); ss->initial_beg_symbol = s7_define_variable(s7, "*" S_initial_beg "*", s7_make_real(s7, DEFAULT_INITIAL_BEG)); ss->initial_dur_symbol = s7_define_variable(s7, "*" S_initial_dur "*", s7_make_real(s7, DEFAULT_INITIAL_DUR)); /* snd-main.c */ ss->show_indices_symbol = s7_define_variable(s7, "*" S_show_indices "*", s7_make_boolean(s7, DEFAULT_SHOW_INDICES)); ss->just_sounds_symbol = s7_define_variable(s7, "*" S_just_sounds "*", s7_make_boolean(s7, DEFAULT_JUST_SOUNDS)); ss->play_arrow_size_symbol = s7_define_variable(s7, "*" S_play_arrow_size "*", s7_make_integer(s7, DEFAULT_PLAY_ARROW_SIZE)); ss->print_length_symbol = s7_define_variable(s7, "*" S_print_length "*", s7_make_integer(s7, DEFAULT_PRINT_LENGTH)); ss->selection_creates_region_symbol = s7_define_variable(s7, "*" S_selection_creates_region "*", s7_make_boolean(s7, DEFAULT_SELECTION_CREATES_REGION)); ss->save_state_file_symbol = s7_define_variable(s7, "*" S_save_state_file "*", s7_make_string(s7, DEFAULT_SAVE_STATE_FILE)); ss->with_background_processes_symbol = s7_define_variable(s7, "*" S_with_background_processes "*", s7_make_boolean(s7, DEFAULT_WITH_BACKGROUND_PROCESSES)); ss->with_file_monitor_symbol = s7_define_variable(s7, "*" S_with_file_monitor "*", s7_make_boolean(s7, DEFAULT_WITH_FILE_MONITOR)); ss->temp_dir_symbol = s7_define_variable(s7, "*" S_temp_dir "*", s7_make_string(s7, ss->Temp_Dir)); ss->save_dir_symbol = s7_define_variable(s7, "*" S_save_dir "*", s7_make_string(s7, ss->Save_Dir)); ss->ladspa_dir_symbol = s7_define_variable(s7, "*" S_ladspa_dir "*", s7_make_string(s7, DEFAULT_LADSPA_DIR)); ss->peak_env_dir_symbol = s7_define_variable(s7, "*" S_peak_env_dir "*", s7_make_string(s7, DEFAULT_PEAK_ENV_DIR)); ss->axis_label_font_symbol = s7_define_variable(s7, "*" S_axis_label_font "*", s7_make_string(s7, DEFAULT_AXIS_LABEL_FONT)); ss->axis_numbers_font_symbol = s7_define_variable(s7, "*" S_axis_numbers_font "*", s7_make_string(s7, DEFAULT_AXIS_NUMBERS_FONT)); ss->tiny_font_symbol = s7_define_variable(s7, "*" S_tiny_font "*", s7_make_string(s7, DEFAULT_TINY_FONT)); ss->peaks_font_symbol = s7_define_variable(s7, "*" S_peaks_font "*", s7_make_string(s7, DEFAULT_PEAKS_FONT)); ss->bold_peaks_font_symbol = s7_define_variable(s7, "*" S_bold_peaks_font "*", s7_make_string(s7, DEFAULT_BOLD_PEAKS_FONT)); ss->with_inset_graph_symbol = s7_define_variable(s7, "*" S_with_inset_graph "*", s7_make_boolean(s7, DEFAULT_WITH_INSET_GRAPH)); ss->with_pointer_focus_symbol = s7_define_variable(s7, "*" S_with_pointer_focus "*", s7_make_boolean(s7, DEFAULT_WITH_POINTER_FOCUS)); ss->with_smpte_label_symbol = s7_define_variable(s7, "*" S_with_smpte_label "*", s7_make_boolean(s7, DEFAULT_WITH_SMPTE_LABEL)); ss->with_interrupts_symbol = s7_define_variable(s7, "*" S_with_interrupts "*", s7_make_boolean(s7, DEFAULT_WITH_INTERRUPTS)); ss->color_scale_symbol = s7_define_variable(s7, "*" S_color_scale "*", s7_make_real(s7, DEFAULT_COLOR_SCALE)); ss->color_cutoff_symbol = s7_define_variable(s7, "*" S_color_cutoff "*", s7_make_real(s7, DEFAULT_COLOR_CUTOFF)); ss->color_inverted_symbol = s7_define_variable(s7, "*" S_color_inverted "*", s7_make_boolean(s7, DEFAULT_COLOR_INVERTED)); ss->auto_resize_symbol = s7_define_variable(s7, "*" S_auto_resize "*", s7_make_boolean(s7, DEFAULT_AUTO_RESIZE)); #if USE_MOTIF #define DEFAULT_LISTENER_FONT "9x15" #endif #if (!USE_NO_GUI) ss->listener_font_symbol = s7_define_variable(s7, "*" S_listener_font "*", s7_make_string(s7, DEFAULT_LISTENER_FONT)); #else ss->listener_font_symbol = s7_define_variable(s7, "*" S_listener_font "*", s7_make_string(s7, "")); #endif /* snd-snd.c */ ss->channel_style_symbol = s7_define_variable(s7, "*" S_channel_style "*", s7_make_integer(s7, DEFAULT_CHANNEL_STYLE)); ss->filter_control_in_db_symbol = s7_define_variable(s7, "*" S_filter_control_in_dB "*", s7_make_boolean(s7, DEFAULT_FILTER_CONTROL_IN_DB)); ss->filter_control_in_hz_symbol = s7_define_variable(s7, "*" S_filter_control_in_hz "*", s7_make_boolean(s7, DEFAULT_FILTER_CONTROL_IN_HZ)); ss->speed_control_tones_symbol = s7_define_variable(s7, "*" S_speed_control_tones "*", s7_make_integer(s7, DEFAULT_SPEED_CONTROL_TONES)); ss->speed_control_style_symbol = s7_define_variable(s7, "*" S_speed_control_style "*", s7_make_integer(s7, DEFAULT_SPEED_CONTROL_STYLE)); ss->expand_control_length_symbol = s7_define_variable(s7, "*" S_expand_control_length "*", s7_make_real(s7, DEFAULT_EXPAND_CONTROL_LENGTH)); ss->expand_control_ramp_symbol = s7_define_variable(s7, "*" S_expand_control_ramp "*", s7_make_real(s7, DEFAULT_EXPAND_CONTROL_RAMP)); ss->expand_control_hop_symbol = s7_define_variable(s7, "*" S_expand_control_hop "*", s7_make_real(s7, DEFAULT_EXPAND_CONTROL_HOP)); ss->expand_control_jitter_symbol = s7_define_variable(s7, "*" S_expand_control_jitter "*", s7_make_real(s7, DEFAULT_EXPAND_CONTROL_JITTER)); ss->contrast_control_amp_symbol = s7_define_variable(s7, "*" S_contrast_control_amp "*", s7_make_real(s7, DEFAULT_CONTRAST_CONTROL_AMP)); ss->reverb_control_feedback_symbol = s7_define_variable(s7, "*" S_reverb_control_feedback "*", s7_make_real(s7, DEFAULT_REVERB_CONTROL_FEEDBACK)); ss->reverb_control_lowpass_symbol = s7_define_variable(s7, "*" S_reverb_control_lowpass "*", s7_make_real(s7, DEFAULT_REVERB_CONTROL_LOWPASS)); ss->reverb_control_decay_symbol = s7_define_variable(s7, "*" S_reverb_control_decay "*", s7_make_real(s7, DEFAULT_REVERB_CONTROL_DECAY)); ss->filter_control_order_symbol = s7_define_variable(s7, "*" S_filter_control_order "*", s7_make_integer(s7, DEFAULT_FILTER_CONTROL_ORDER)); /* snd-chn.c */ ss->show_transform_peaks_symbol = s7_define_variable(s7, "*" S_show_transform_peaks "*", s7_make_boolean(s7, DEFAULT_SHOW_TRANSFORM_PEAKS)); ss->show_y_zero_symbol = s7_define_variable(s7, "*" S_show_y_zero "*", s7_make_boolean(s7, DEFAULT_SHOW_Y_ZERO)); ss->show_marks_symbol = s7_define_variable(s7, "*" S_show_marks "*", s7_make_boolean(s7, DEFAULT_SHOW_MARKS)); ss->show_grid_symbol = s7_define_variable(s7, "*" S_show_grid "*", s7_make_boolean(s7, DEFAULT_SHOW_GRID)); ss->fft_log_frequency_symbol = s7_define_variable(s7, "*" S_fft_log_frequency "*", s7_make_boolean(s7, DEFAULT_FFT_LOG_FREQUENCY)); ss->fft_log_magnitude_symbol = s7_define_variable(s7, "*" S_fft_log_magnitude "*", s7_make_boolean(s7, DEFAULT_FFT_LOG_MAGNITUDE)); ss->fft_with_phases_symbol = s7_define_variable(s7, "*" S_fft_with_phases "*", s7_make_boolean(s7, DEFAULT_FFT_WITH_PHASES)); ss->sync_style_symbol = s7_define_variable(s7, "*" S_sync_style "*", s7_make_integer(s7, DEFAULT_SYNC_STYLE)); ss->show_axes_symbol = s7_define_variable(s7, "*" S_show_axes "*", s7_make_integer(s7, DEFAULT_SHOW_AXES)); ss->min_db_symbol = s7_define_variable(s7, "*" S_min_dB "*", s7_make_real(s7, DEFAULT_MIN_DB)); ss->cursor_size_symbol = s7_define_variable(s7, "*" S_cursor_size "*", s7_make_integer(s7, DEFAULT_CURSOR_SIZE)); ss->cursor_style_symbol = s7_define_variable(s7, "*" S_cursor_style "*", s7_make_integer(s7, DEFAULT_CURSOR_STYLE)); ss->tracking_cursor_style_symbol = s7_define_variable(s7, "*" S_tracking_cursor_style "*", s7_make_integer(s7, DEFAULT_TRACKING_CURSOR_STYLE)); ss->show_sonogram_cursor_symbol = s7_define_variable(s7, "*" S_show_sonogram_cursor "*", s7_make_boolean(s7, DEFAULT_SHOW_SONOGRAM_CURSOR)); ss->with_verbose_cursor_symbol = s7_define_variable(s7, "*" S_with_verbose_cursor "*", s7_make_boolean(s7, DEFAULT_WITH_VERBOSE_CURSOR)); ss->spectro_x_scale_symbol = s7_define_variable(s7, "*" S_spectro_x_scale "*", s7_make_real(s7, DEFAULT_SPECTRO_X_SCALE)); ss->spectro_y_scale_symbol = s7_define_variable(s7, "*" S_spectro_y_scale "*", s7_make_real(s7, DEFAULT_SPECTRO_Y_SCALE)); ss->spectro_z_scale_symbol = s7_define_variable(s7, "*" S_spectro_z_scale "*", s7_make_real(s7, DEFAULT_SPECTRO_Z_SCALE)); ss->spectro_z_angle_symbol = s7_define_variable(s7, "*" S_spectro_z_angle "*", s7_make_real(s7, DEFAULT_SPECTRO_Z_ANGLE)); ss->spectro_x_angle_symbol = s7_define_variable(s7, "*" S_spectro_x_angle "*", s7_make_real(s7, DEFAULT_SPECTRO_X_ANGLE)); ss->spectro_y_angle_symbol = s7_define_variable(s7, "*" S_spectro_y_angle "*", s7_make_real(s7, DEFAULT_SPECTRO_Y_ANGLE)); ss->spectrum_end_symbol = s7_define_variable(s7, "*" S_spectrum_end "*", s7_make_real(s7, DEFAULT_SPECTRUM_END)); ss->spectrum_start_symbol = s7_define_variable(s7, "*" S_spectrum_start "*", s7_make_real(s7, DEFAULT_SPECTRUM_START)); ss->spectro_hop_symbol = s7_define_variable(s7, "*" S_spectro_hop "*", s7_make_integer(s7, DEFAULT_SPECTRO_HOP)); ss->graphs_horizontal_symbol = s7_define_variable(s7, "*" S_graphs_horizontal "*", s7_make_boolean(s7, DEFAULT_GRAPHS_HORIZONTAL)); ss->max_transform_peaks_symbol = s7_define_variable(s7, "*" S_max_transform_peaks "*", s7_make_integer(s7, DEFAULT_MAX_TRANSFORM_PEAKS)); ss->fft_window_alpha_symbol = s7_define_variable(s7, "*" S_fft_window_alpha "*", s7_make_real(s7, DEFAULT_FFT_WINDOW_ALPHA)); ss->fft_window_beta_symbol = s7_define_variable(s7, "*" S_fft_window_beta "*", s7_make_real(s7, DEFAULT_FFT_WINDOW_BETA)); ss->grid_density_symbol = s7_define_variable(s7, "*" S_grid_density "*", s7_make_real(s7, DEFAULT_GRID_DENSITY)); ss->beats_per_minute_symbol = s7_define_variable(s7, "*" S_beats_per_minute "*", s7_make_real(s7, DEFAULT_BEATS_PER_MINUTE)); ss->show_mix_waveforms_symbol = s7_define_variable(s7, "*" S_show_mix_waveforms "*", s7_make_boolean(s7, DEFAULT_SHOW_MIX_WAVEFORMS)); ss->beats_per_measure_symbol = s7_define_variable(s7, "*" S_beats_per_measure "*", s7_make_integer(s7, DEFAULT_BEATS_PER_MEASURE)); ss->transform_normalization_symbol = s7_define_variable(s7, "*" S_transform_normalization "*", s7_make_integer(s7, DEFAULT_TRANSFORM_NORMALIZATION)); ss->x_axis_style_symbol = s7_define_variable(s7, "*" S_x_axis_style "*", s7_make_integer(s7, DEFAULT_X_AXIS_STYLE)); ss->zoom_focus_style_symbol = s7_define_variable(s7, "*" S_zoom_focus_style "*", s7_make_integer(s7, DEFAULT_ZOOM_FOCUS_STYLE)); ss->graph_style_symbol = s7_define_variable(s7, "*" S_graph_style "*", s7_make_integer(s7, DEFAULT_GRAPH_STYLE)); ss->wavelet_type_symbol = s7_define_variable(s7, "*" S_wavelet_type "*", s7_make_integer(s7, DEFAULT_WAVELET_TYPE)); ss->dot_size_symbol = s7_define_variable(s7, "*" S_dot_size "*", s7_make_integer(s7, DEFAULT_DOT_SIZE)); ss->zero_pad_symbol = s7_define_variable(s7, "*" S_zero_pad "*", s7_make_integer(s7, DEFAULT_ZERO_PAD)); ss->wavo_hop_symbol = s7_define_variable(s7, "*" S_wavo_hop "*", s7_make_integer(s7, DEFAULT_WAVO_HOP)); ss->wavo_trace_symbol = s7_define_variable(s7, "*" S_wavo_trace "*", s7_make_integer(s7, DEFAULT_WAVO_TRACE)); ss->transform_size_symbol = s7_define_variable(s7, "*" S_transform_size "*", s7_make_integer(s7, DEFAULT_TRANSFORM_SIZE)); ss->fft_window_symbol = s7_define_variable(s7, "*" S_fft_window "*", s7_make_integer(s7, DEFAULT_FFT_WINDOW)); ss->transform_graph_type_symbol = s7_define_variable(s7, "*" S_transform_graph_type "*", s7_make_integer(s7, DEFAULT_TRANSFORM_GRAPH_TYPE)); ss->time_graph_type_symbol = s7_define_variable(s7, "*" S_time_graph_type "*", s7_make_integer(s7, DEFAULT_TIME_GRAPH_TYPE)); /* snd-draw.c */ ss->data_color_symbol = s7_define_variable(s7, "*" S_data_color "*", s7_f(s7)); ss->selected_data_color_symbol = s7_define_variable(s7, "*" S_selected_data_color "*", s7_f(s7)); ss->mark_color_symbol = s7_define_variable(s7, "*" S_mark_color "*", s7_f(s7)); ss->graph_color_symbol = s7_define_variable(s7, "*" S_graph_color "*", s7_f(s7)); ss->selected_graph_color_symbol = s7_define_variable(s7, "*" S_selected_graph_color "*", s7_f(s7)); ss->listener_color_symbol = s7_define_variable(s7, "*" S_listener_color "*", s7_f(s7)); ss->listener_text_color_symbol = s7_define_variable(s7, "*" S_listener_text_color "*", s7_f(s7)); ss->basic_color_symbol = s7_define_variable(s7, "*" S_basic_color "*", s7_f(s7)); ss->selection_color_symbol = s7_define_variable(s7, "*" S_selection_color "*", s7_f(s7)); ss->zoom_color_symbol = s7_define_variable(s7, "*" S_zoom_color "*", s7_f(s7)); ss->position_color_symbol = s7_define_variable(s7, "*" S_position_color "*", s7_f(s7)); ss->highlight_color_symbol = s7_define_variable(s7, "*" S_highlight_color "*", s7_f(s7)); ss->enved_waveform_color_symbol = s7_define_variable(s7, "*" S_enved_waveform_color "*", s7_f(s7)); ss->cursor_color_symbol = s7_define_variable(s7, "*" S_cursor_color "*", s7_f(s7)); ss->text_focus_color_symbol = s7_define_variable(s7, "*" S_text_focus_color "*", s7_f(s7)); ss->filter_control_waveform_color_symbol = s7_define_variable(s7, "*" S_filter_control_waveform_color "*", s7_f(s7)); ss->mix_color_symbol = s7_define_variable(s7, "*" S_mix_color "*", s7_f(s7)); ss->sash_color_symbol = s7_define_variable(s7, "*" S_sash_color "*", s7_f(s7)); ss->axis_color_symbol = s7_define_variable(s7, "*" S_axis_color "*", s7_f(s7)); ss->transform_type_symbol = s7_define_variable(s7, "*" S_transform_type "*", s7_f(s7)); /* set in snd-chn.c(!) */ #if USE_GTK ss->listener_colorized_symbol = s7_define_variable(s7, "*listener-colorized*", s7_make_boolean(s7, s7_f(s7))); #endif #endif } #if HAVE_GSL #include #include /* default gsl error handler apparently aborts main program! */ static void snd_gsl_error(const char *reason, const char *file, int line, int gsl_errno) { Xen_error(Xen_make_error_type("gsl-error"), Xen_list_6(C_string_to_Xen_string("GSL: ~A, ~A in ~A line ~A, gsl err: ~A"), C_string_to_Xen_string(gsl_strerror(gsl_errno)), C_string_to_Xen_string(reason), C_string_to_Xen_string(file), C_int_to_Xen_integer(line), C_int_to_Xen_integer(gsl_errno))); } #endif int main(int argc, char **argv) { int i; #if (!_MSC_VER) setlocale(LC_NUMERIC, "C"); /* use decimal point in floats */ #endif #if HAVE_GSL /* if HAVE_GSL and the environment variable GSL_IEEE_MODE exists, use it */ /* GSL_IEEE_MODE=double-precision,mask-underflow,mask-denormalized */ if (getenv("GSL_IEEE_MODE") != NULL) gsl_ieee_env_setup(); gsl_set_error_handler(snd_gsl_error); #endif ss = (snd_state *)calloc(1, sizeof(snd_state)); /* not calloc! */ ss->startup_errors = NULL; #if USE_GTK #if GTK_CHECK_VERSION(3, 0, 0) && (!GLIB_CHECK_VERSION(2,35,0)) g_type_init(); #endif #endif mus_sound_initialize(); /* has to precede version check (mus_audio_moniker needs to be setup in Alsa/Oss) */ xen_initialize(); for (i = 1; i < argc; i++) { if (strcmp(argv[i], "--version") == 0) { fprintf(stdout, "%s", version_info()); snd_exit(0); } else { if (strcmp(argv[i], "--help") == 0) { fprintf(stdout, "%s", "Snd is a sound editor; see http://ccrma.stanford.edu/software/snd/.\n"); fprintf(stdout, "%s", version_info()); snd_exit(0); } } } initialize_sample_type_lists(); snd_set_global_defaults(false); ss->jump_ok = false; ss->file_monitor_ok = false; allocate_regions(max_regions(ss)); ss->init_window_x = DEFAULT_INIT_WINDOW_X; ss->init_window_y = DEFAULT_INIT_WINDOW_Y; ss->init_window_width = DEFAULT_INIT_WINDOW_WIDTH; ss->init_window_height = DEFAULT_INIT_WINDOW_HEIGHT; ss->click_time = 100; init_sound_file_extensions(); ss->max_sounds = 4; /* expands to accommodate any number of files */ ss->sound_sync_max = 0; ss->stopped_explicitly = false; /* C-g sets this flag so that we can interrupt various loops */ ss->checking_explicitly = false; ss->selection_play_stop = false; ss->reloading_updated_file = 0; ss->selected_sound = NO_SELECTION; ss->sounds = (snd_info **)calloc(ss->max_sounds, sizeof(snd_info *)); ss->print_choice = PRINT_SND; ss->graph_hook_active = false; ss->lisp_graph_hook_active = false; ss->exiting = false; ss->deferred_regions = 0; ss->snd_error_data = NULL; ss->snd_error_handler = NULL; ss->snd_warning_data = NULL; ss->snd_warning_handler = NULL; ss->xen_error_data = NULL; ss->xen_error_handler = NULL; ss->update_sound_channel_style = NOT_A_CHANNEL_STYLE; ss->squelch_mark_drag_info = false; #if HAVE_GL && WITH_GL2PS ss->gl_printing = false; #endif g_xen_initialize(); ss->search_proc = Xen_undefined; ss->search_expr = NULL; mus_error_set_handler(mus_error_to_snd); mus_print_set_handler(mus_print_to_snd); initialize_load_path(); /* merge SND_PATH entries into the load-path */ snd_doit(argc, argv); return(0); } void g_init_base(void) { #define H_mus_error_hook S_mus_error_hook " (type message): called upon mus_error. \ If it returns " PROC_TRUE ", Snd ignores the error (it assumes you've handled it via the hook)." ss->mus_error_hook = Xen_define_hook(S_mus_error_hook, "(make-hook 'type 'message)", 2, H_mus_error_hook); } snd-16.1/enved.fs0000644000076400007640000002546612306421671012005 0ustar bilbil\ enved.fs -- enved object type \ Author: Michael Scholz \ Created: Sun Nov 13 13:59:42 CET 2005 \ Changed: Mon Nov 19 06:06:33 CET 2012 \ Commentary: \ This is an example of an Object type written in Forth. \ \ ENVED \ \ enved? ( obj -- f ) \ make-enved ( ary -- en ) \ \ enved-length ( en -- len|-1 ) \ enved-ref ( en index -- point ) \ enved-set! ( en index point -- ) \ enved-index ( en x -- index|-1 ) \ enved-insert! ( en index point -- ) \ enved-delete! ( en index -- ) \ === ENVED OBJECT TYPE === "enved" make-object-type constant fth-enved \ \ ENVED? \ fth-enved make-?obj enved? <'> enved? "( obj -- f ) test if OBJ is an enved\n\ #( 0 1 1 0 ) make-enved enved? => #t\n\ #( 0 1 1 0 ) enved? => #f\n\ Return #t if OBJ is an enved object, otherwise #f." help-set! hide \ Creates setter enved-envelope! and getter enved-envelope@ and \ make-enved-instance for use in make-en. #( "enved-envelope" ) create-instance-struct make-enved-instance : (enved-out-of-bounds) { pos arg name -- ex args } 'out-of-range #( "%s arg %d: %d is out of bounds" name pos arg ) ; : enved-out-of-bounds ( pos arg -- ) postpone get-func-name postpone (enved-out-of-bounds) postpone fth-throw ; immediate : make-en { ary -- en } fth-enved make-enved-instance { en } en ary enved-envelope! en ; : en-inspect { self -- str } self enved-envelope@ { ary } "#<%s[%d]: %s>" #( self object-name ary array-length 2/ ary ) string-format ; : en->string ( self -- str ) enved-envelope@ object->string ; : en-dump ( self -- str ) en->string " make-enved" $+ ; : en->array ( self -- ary ) enved-envelope@ array->array ; : en-copy ( self -- en ) enved-envelope@ array-copy make-en ; : en-length ( self -- len ) enved-envelope@ array-length 2/ ; : en-ref { self index -- point } self index object-range? if index 2* to index #( self enved-envelope@ index array-ref self enved-envelope@ index 1+ array-ref ) else 2 index enved-out-of-bounds then ; : en-set! { self index point -- } self index object-range? if index 2* to index self enved-envelope@ index point 0 array-ref array-set! self enved-envelope@ index 1+ point 1 array-ref array-set! else 2 index enved-out-of-bounds then ; : en-equal? { self obj -- f } self obj = if #t else self enved-envelope@ obj enved-envelope@ object-equal? then ; \ Init object type Enved. <'> en-inspect fth-enved set-object-inspect \ en .inspect <'> en->string fth-enved set-object->string \ en object->string <'> en-dump fth-enved set-object-dump \ en object-dump <'> en->array fth-enved set-object->array \ en object->array <'> en-copy fth-enved set-object-copy \ en object-copy <'> en-ref fth-enved set-object-value-ref \ en idx object-ref => #( x y ) <'> en-set! fth-enved set-object-value-set \ en idx #( x y ) object-set! <'> en-equal? fth-enved set-object-equal-p \ obj1 obj2 object-equal? <'> en-length fth-enved set-object-length \ en object-length => (len/2) <'> en-ref fth-enved 1 set-object-apply \ en idx apply => #( x y ) set-current \ \ MAKE-ENVED \ : make-enved ( ary -- en ) doc" create enved\n\ #( 0 1 1 0 ) make-enved value en\n\ Return new enved object from ARY \ which must be an array of even length." { ary } ary array-length 2 mod 0= ary 1 "an array of even length" assert-type ary make-en ; \ \ ENVED-LENGTH \ : enved-length ( obj -- len|-1 ) doc" return enved length\n\ #( 0 1 1 0 ) make-enved enved-length => 2\n\ #( 0 1 1 0 ) enved-length => -1\n\ If OBJ is an enved object, return its length, otherwise -1." { obj } obj enved? if obj en-length else -1 then ; \ \ ENVED-REF \ : enved-ref ( en index -- point ) doc" return point at INDEX\n\ #( 0 1 1 0 ) make-enved value en\n\ en 0 enved-ref => #( 0 1 )\n\ en 1 enved-ref => #( 1 0 )\n\ Return point at position INDEX. \ Negative index counts from backward. \ Raise OUT-OF-RANGE exception if INDEX is not in EN's range." { en index } en enved? en 1 "an enved" assert-type index 0< if en en-length index + to index then en index en-ref ; \ \ ENVED-SET! \ : enved-set! ( en index point -- ) doc" set point at INDEX\n\ #( 0 1 1 0 ) make-enved value en\n\ en 0 #( 0 0.5 ) enved-set!\n\ en .$ => #( 0 0.5 1 0 )\n\ en 1 #( 1 0.5 ) enved-set!\n\ en .$ => #( 0 0.5 1 0.5 )\n\ Store POINT at position INDEX. \ Negative index counts from backward. \ Raise OUT-OF-RANGE exception if INDEX is not in EN's range." { en index point } en enved? en 1 "an enved" assert-type index 0< if en en-length index + to index then en index point en-set! ; \ \ ENVED-INDEX \ : enved-index ( en x -- index|-1 ) doc" return index of X in EN\n\ #( 1 3 2 3 ) make-enved value en\n\ en 1 enved-index => 0\n\ en 2 enved-index => 1\n\ en 3 enved-index => -1\n\ Return point-index where X is point's x value, or -1 if not found." { en x } en enved? en 1 "an enved" assert-type -1 { idx } en enved-envelope@ { ary } ary array-length 0 ?do ary i array-ref x f= if i 2/ to idx leave then 2 +loop idx ; \ \ ENVED-INSERT! \ : enved-insert! ( en index point -- ) doc" insert POINT at INDEX\n\ #( 1 1 2 2 ) make-enved value en\n\ en 0 #( 0 0 ) enved-insert!\n\ en .$ => #( 0 0 1 1 2 2 )\n\ en 3 #( 3 3 ) enved-insert!\n\ en .$ => #( 0 0 1 1 2 2 3 3 )\n\ Insert POINT at INDEX into EN. \ Negative index counts from backward. \ Raise OUT-OF-RANGE exception if INDEX is not in EN's range." { en index point } en enved? en 1 "an enved" assert-type point array-length 2 = point 3 "a point #( x y )" assert-type index 0< if en en-length index + to index then en index object-range? if index 2* to index en enved-envelope@ index point array-insert! drop else index en en-length = if en enved-envelope@ ( ary ) point 0 array-ref array-push ( ary' ) point 1 array-ref array-push drop else 2 index enved-out-of-bounds then then ; \ \ ENVED-DELETE! \ : enved-delete! ( en index -- ) doc" delete point at INDEX\n\ #( 1 1 2 2 ) make-enved value en\n\ en 1 enved-delete!\n\ en .$ => #( 1 1 )\n\ Delete point at INDEX from EN. \ Negative index counts from backward. \ Raise OUT-OF-RANGE exception if INDEX is not in EN's range." { en index } en enved? en 1 "an enved" assert-type index 0< if en en-length index + to index then en index object-range? if index 2* to index en enved-envelope@ index array-delete! drop en enved-envelope@ index array-delete! drop else 2 index enved-out-of-bounds then ; \ XXX \ For backwards compatibility. : envelope@ { en -- ary } en enved? en 1 "an enved" assert-type en enved-envelope@ ; \ XXX \ For backwards compatibility with arguments swapped. : envelope! { ary en -- } ary array? ary 1 "an array" assert-type en enved? en 2 "an enved" assert-type en ary enved-envelope! ; previous hide : test-display { res req str -- } res req object-equal? unless "\\ %s: res %s, req %s\n" #( str res req ) fth-print then ; : test-catch { xt ex -- tag } xt ex nil fth-catch { tag } stack-reset tag ; set-current : enved-test ( -- ) nil nil nil { en1 en2 tag } \ \ make-enved \ #( 0 1 1 0 ) make-enved to en1 #( 0 1 1 0 ) make-enved to en2 #( 0 1 2 ) <'> make-enved 'wrong-type-arg test-catch to tag tag car 'wrong-type-arg "#( 0 1 2 ) make-enved" test-display \ \ enved? \ en1 enved? #t "en1 enved?" test-display en2 enved? #t "en2 enved?" test-display #( 0 1 1 0 ) enved? #f "#( 0 1 1 0 ) enved?" test-display \ \ enved-length \ en1 enved-length 2 "en1 enved-length" test-display en2 enved-length 2 "en2 enved-length" test-display #( 0 1 1 0 ) enved-length -1 "#( 0 1 1 0 ) enved-length" test-display \ \ enved-ref \ en1 0 enved-ref #( 0 1 ) "en1 0 enved-ref" test-display en1 1 enved-ref #( 1 0 ) "en1 1 enved-ref" test-display en1 2 <'> enved-ref 'out-of-range test-catch to tag tag car 'out-of-range "en1 2 enved-ref" test-display \ \ enved-set! \ #( 0 1 1 0 ) make-enved to en1 en1 0 #( 0 0 ) enved-set! #( 0 0 1 0 ) make-enved to en2 en1 en2 "en1 0 #( 0 0 ) enved-set!" test-display #( 0 1 1 0 ) make-enved to en1 en1 1 #( 1 1 ) enved-set! #( 0 1 1 1 ) make-enved to en2 en1 en2 "en1 1 #( 1 1 ) enved-set!" test-display en1 2 #( 2 0 ) <'> enved-set! 'out-of-range test-catch to tag tag car 'out-of-range "en1 2 enved-set!" test-display \ \ enved-index \ #( 0 1 2 0 ) make-enved to en1 en1 0 enved-index 0 "en1 0 enved-index" test-display en1 2 enved-index 1 "en1 2 enved-index" test-display en1 1 enved-index -1 "en1 1 enved-index" test-display \ \ enved-insert! \ #( 1 1 2 2 ) make-enved to en1 en1 0 #( 0 0 ) enved-insert! #( 0 0 1 1 2 2 ) make-enved to en2 en1 en2 "en1 0 #( 0 0 ) enved-insert!" test-display en1 3 #( 3 3 ) enved-insert! #( 0 0 1 1 2 2 3 3 ) make-enved to en2 en1 en2 "en1 3 #( 3 3 ) enved-insert!" test-display en1 5 #( 5 5 ) <'> enved-insert! 'out-of-range test-catch to tag tag car 'out-of-range "en1 5 #( 5 5 ) enved-insert!" test-display \ \ enved-delete! \ #( 0 0 1 1 2 2 3 3 ) make-enved to en1 en1 0 enved-delete! #( 1 1 2 2 3 3 ) make-enved to en2 en1 en2 "en1 0 enved-delete!" test-display en1 2 enved-delete! #( 1 1 2 2 ) make-enved to en2 en1 en2 "en1 2 enved-delete!" test-display en1 3 <'> enved-delete! 'out-of-range test-catch to tag tag car 'out-of-range "en1 3 enved-delete!" test-display \ \ object-inspect \ #( 0 1 1 0 ) make-enved to en1 en1 object-inspect "#" "object-inspect" test-display \ \ object->string \ en1 object->string "#( 0 1 1 0 )" "object->string" test-display \ \ object-dump \ en1 object-dump "#( 0 1 1 0 ) make-enved" "object-dump" test-display \ \ object->array \ en1 object->array #( 0 1 1 0 ) "object->array" test-display \ \ object-copy \ en1 object-copy en1 "object-copy" test-display \ \ object-ref \ en1 0 object-ref #( 0 1 ) "en1 0 object-ref" test-display en1 1 object-ref #( 1 0 ) "en1 1 object-ref" test-display en1 2 <'> object-ref 'out-of-range test-catch to tag tag car 'out-of-range "en1 2 object-ref" test-display \ \ object-set! \ #( 0 1 1 0 ) make-enved to en1 en1 0 #( 0 0 ) object-set! #( 0 0 1 0 ) make-enved to en2 en1 en2 "en1 0 #( 0 0 ) object-set!" test-display #( 0 1 1 0 ) make-enved to en1 en1 1 #( 1 1 ) object-set! #( 0 1 1 1 ) make-enved to en2 en1 en2 "en1 1 #( 1 1 ) object-set!" test-display en1 2 #( 2 0 ) <'> object-set! 'out-of-range test-catch to tag tag car 'out-of-range "en1 2 object-set!" test-display \ \ object-length \ #( 0 1 1 0 ) make-enved to en1 #( 0 1 1 0 ) make-enved to en2 en1 object-length 2 "en1 object-length" test-display en2 object-length 2 "en2 object-length" test-display \ \ object-equal? \ en1 en2 "object-equal?" test-display \ \ object-apply \ en1 0 object-apply #( 0 1 ) "en1 0 object-apply" test-display en1 1 object-apply #( 1 0 ) "en1 1 object-apply" test-display en1 2 <'> object-apply 'out-of-range test-catch to tag tag car 'out-of-range "en1 2 object-apply" test-display ; previous \ enved.fs ends here snd-16.1/play.rb0000644000076400007640000000620112434353162011627 0ustar bilbil# play.rb -- play.scm -> play.rb # Translator: Michael Scholz # Created: 05/04/22 23:36:39 # Changed: 14/11/14 08:21:06 # playing-related examples # # play_often(n) # play_region_forever(reg) # start_dac(srate, chans) # stop_dac # play_with_amps(snd, *rest) # play_sine(freq, amp) # play_sines(freq_and_amps) # play sound n times -- play_often(3) for example add_help(:play_often, "play_often(n) \ Plays the selected sound N times (interruptible via C-g).") def play_often(n) plays = n - 1 play_once = lambda do |reason| if plays > 0 and reason == 0 plays -= 1 play(selected_sound(), :start, 0, :stop, play_once) end end play(selected_sound(), :start, 0, :stop, play_once) end # bind_key(?p, 0, lambda do |n| play_often([1, n].max) end, false, "play often") # play region over and over until C-g typed add_help(:play_region_forever, "play_region_forever(reg) \ Plays region REG until you interrupt it via C-g.") def play_region_forever(reg) if integer?(reg) reg = integer2region(reg) end play_region_again = lambda do |reason| if reason == 0 play(reg, :wait, false, :stop, play_region_again) end end play(reg, :wait, false, :stop, play_region_again) end # bind_key(?p, 0, # lambda do |n| play_region_forever(Snd.regions[[0, n].max]) end, # false, "play region forever") # play while looping continuously between two movable marks # hold DAC open and play sounds via keyboard add_help(:start_dac, "start_dac(srate=44100, chans=1) \ Starts the DAC running continuously in the background.") def start_dac(sr = 44100, chans = 1) play(false, :srate, sr, :channels, chans) end alias stop_dac stop_playing # play_with_amps -- play channels with individually settable amps add_help(:play_with_amps, "play_with_amps(snd, *amps) \ Plays snd with each channel scaled by the corresponding amp: \ play_with_amps(0, 1.0, 0.5) plays channel 2 of stereo sound at half amplitude.") def play_with_amps(snd, *amps) chns = channels(snd) chns.times do |chn| player = make_player(snd, chn) set_amp_control(amps[chn], player) add_player(player) end start_playing(chns, srate(snd)) end # play_sine and play_sines add_help(:play_sine, "play_sine(freq, amp) \ Plays a 1 second sinewave at freq and amp.") def play_sine(freq, amp) len = 44100 osc = make_oscil(freq) play(lambda do (len -= 1).positive? and (amp * oscil(osc)) end) end add_help(:play_sines, "play_sines(*freq_and_amps) \ Produces a tone given its spectrum: play_sines([[440, 0.4], [660, 0.3]])") def play_sines(*freq_and_amps) len = 44100 num_oscs = freq_and_amps.length frqs = Vct.new(num_oscs) amps = Vct.new(num_oscs) freq_and_amps.each_with_index do |fa, i| frqs[i] = hz2radians(fa[0]) amps[i] = fa[1] end ob = make_oscil_bank(frqs, Vct.new(num_oscs, 0.0), amps) play(lambda do (len -= 1).positive? and oscil_bank(ob) end) end # play_sines([425, 0.05], [450, 0.01], # [470, 0.01], [546, 0.02], # [667, 0.01], [789, 0.034], # [910, 0.032]) # play.rb ends here snd-16.1/jcrev.scm0000644000076400007640000000376712616231602012164 0ustar bilbil(provide 'snd-jcrev.scm) (if (provided? 'snd) (require snd-ws.scm) (require sndlib-ws.scm)) (definstrument (jc-reverb low-pass (volume 1.0) amp-env) "(jc-reverb (low-pass #f) (volume 1.0) (amp-env #f)) -- Chowning reverb" (let ((allpass1 (make-all-pass -0.700 0.700 1051)) (allpass2 (make-all-pass -0.700 0.700 337)) (allpass3 (make-all-pass -0.700 0.700 113)) (comb1 (make-comb 0.742 4799)) (comb2 (make-comb 0.733 4999)) (comb3 (make-comb 0.715 5399)) (comb4 (make-comb 0.697 5801)) (decay-dur *clm-srate*) (chns (channels *output*)) (file-dur (framples *reverb*))) (let ((len (floor (+ decay-dur file-dur))) (filts (if (= chns 1) (vector (make-delay (seconds->samples .013))) (vector (make-delay (seconds->samples .013)) (make-delay (seconds->samples .011))))) (combs (make-comb-bank (vector comb1 comb2 comb3 comb4))) (allpasses (make-all-pass-bank (vector allpass1 allpass2 allpass3)))) (if (or amp-env low-pass) (let ((flt (and low-pass (make-fir-filter 3 (float-vector 0.25 0.5 0.25)))) (envA (make-env :envelope (or amp-env '(0 1 1 1)) :scaler volume :duration (/ len *clm-srate*)))) (if low-pass (do ((i 0 (+ i 1))) ((= i len)) (out-bank filts i (* (env envA) (fir-filter flt (comb-bank combs (all-pass-bank allpasses (ina i *reverb*))))))) (do ((i 0 (+ i 1))) ((= i len)) (out-bank filts i (* (env envA) (comb-bank combs (all-pass-bank allpasses (ina i *reverb*)))))))) (do ((i 0 (+ i 1))) ((= i len)) (out-bank filts i (* volume (comb-bank combs (all-pass-bank allpasses (ina i *reverb*)))))))))) ;;; (with-sound (:reverb jc-reverb) (fm-violin 0 .1 440 .1 :reverb-amount .3)) ;;; (with-sound (:reverb jc-reverb) (outa 0 .1) (outa 0 .5 *reverb*)) ;;; (with-sound (:reverb jc-reverb :reverb-data '((:low-pass #t))) (outa 0 .1) (outa 0 .5 *reverb*)) ;;; (with-sound (:statistics #t :reverb jc-reverb :reverb-data '((:low-pass #t))) (outa 0 .1) (outa 100000 .1) (outa 0 .5 *reverb*) (outa 100000 .5 *reverb*)) snd-16.1/clm2xen.h0000644000076400007640000000366112546544550012074 0ustar bilbil#ifndef CLM2XEN_H #define CLM2XEN_H #include "vct.h" typedef struct mus_xen mus_xen; #define Xen_to_mus_xen(arg) ((mus_xen *)Xen_object_ref(arg)) #define Xen_to_mus_any(obj) mus_xen_gen(Xen_to_mus_xen(obj)) #define MUS_CLM_DEFAULT_TABLE_SIZE 512 #define MUS_CLM_DEFAULT_FREQUENCY 0.0 #ifdef __cplusplus extern "C" { #endif MUS_EXPORT mus_long_t clm_default_table_size_c(void); MUS_EXPORT mus_float_t clm_default_frequency_c(void); MUS_EXPORT mus_any *mus_xen_gen(mus_xen *x); MUS_EXPORT bool mus_is_xen(Xen obj); MUS_EXPORT const char *mus_fft_window_xen_name(mus_fft_window_t i); MUS_EXPORT Xen mus_xen_to_object(mus_xen *gn); MUS_EXPORT Xen mus_xen_to_object_with_vct(mus_xen *gn, Xen v); MUS_EXPORT mus_any *mus_optkey_to_mus_any(Xen key, const char *caller, int n, mus_any *def); MUS_EXPORT int mus_optkey_unscramble(const char *caller, int nkeys, Xen *keys, Xen *args, int *orig); MUS_EXPORT mus_float_t mus_optkey_to_float(Xen key, const char *caller, int n, mus_float_t def); MUS_EXPORT int mus_optkey_to_int(Xen key, const char *caller, int n, int def); MUS_EXPORT bool mus_optkey_to_bool(Xen key, const char *caller, int n, bool def); MUS_EXPORT mus_long_t mus_optkey_to_mus_long_t(Xen key, const char *caller, int n, mus_long_t def); MUS_EXPORT const char *mus_optkey_to_string(Xen key, const char *caller, int n, char *def); MUS_EXPORT Xen mus_optkey_to_procedure(Xen key, const char *caller, int n, Xen def, int required_args, const char *err); MUS_EXPORT mus_xen *mus_any_to_mus_xen(mus_any *ge); MUS_EXPORT mus_xen *mus_any_to_mus_xen_with_vct(mus_any *ge, Xen v); MUS_EXPORT mus_xen *mus_any_to_mus_xen_with_two_vcts(mus_any *ge, Xen v1, Xen v2); MUS_EXPORT Xen g_mus_channels(Xen obj); MUS_EXPORT Xen g_mus_length(Xen gen); MUS_EXPORT Xen g_mus_file_name(Xen gen); MUS_EXPORT Xen g_mus_data(Xen gen); #if HAVE_SCHEME MUS_EXPORT void s7_init_sndlib(s7_scheme *sc); #endif MUS_EXPORT void Init_sndlib(void); #ifdef __cplusplus } #endif #endif snd-16.1/s7.html0000644000076400007640000112540312625174165011571 0ustar bilbil s7
s7

s7 is a Scheme implementation intended as an extension language for other applications, primarily Snd and Common Music. It exists as just two files, s7.c and s7.h, that want only to disappear into someone else's source tree. There are no libraries, no run-time init files, and no configuration scripts. It can be built as a stand-alone interpreter (see below). s7test.scm is a regression test for s7. A tarball is available: ftp://ccrma-ftp.stanford.edu/pub/Lisp/s7.tar.gz.

s7 is the default extension language of Snd and sndlib (http://ccrma.stanford.edu/software/snd/), and Rick Taube's Common Music (commonmusic at sourceforge). There are X, Motif, Gtk, and openGL bindings in libxm in the Snd tarball, or at ftp://ccrma-ftp.stanford.edu/pub/Lisp/libxm.tar.gz. If you're running s7 in a context that has getenv, file-exists?, and system, you can use s7-slib-init.scm to gain easy access to slib. This init file is named "s7.init" in the slib distribution.

Although it is a descendant of tinyScheme, s7 is closest as a Scheme dialect to Guile 1.8. I believe it is compatible with r5rs and r7rs: you can just ignore all the additions discussed in this file. It has continuations, ratios, complex numbers, macros, keywords, hash-tables, multiprecision arithmetic, generalized set!, unicode, and so on. It does not have syntax-rules or any of its friends, and it does not think there is any such thing as an inexact integer.

This file assumes you know about Scheme and all its problems, and want a quick tour of where s7 is different. (Well, it was quick once upon a time). The main difference: if it's in s7, it's a first-class citizen of s7, and that includes macros, environments, and syntactic forms.


I originally used a small font for scholia, but now I have to squint to read that tiny text, so less-than-vital commentaries are shown in the normal font, but indented and on a sort of brownish background.


multiprecision arithmetic

All numeric types, integers, ratios, reals, and complex numbers are supported. The basic integer and real types are defined in s7.h, defaulting to long long int and double. A ratio consists of two integers, a complex number two reals. pi is predefined, as are most-positive-fixnum and most-negative-fixnum. s7 can be built with multiprecision support for all types, using the gmp, mpfr, and mpc libraries (set WITH_GMP to 1 in s7.c). If multiprecision arithmetic is enabled, the following functions are included: bignum, and bignum?, and the variable (*s7* 'bignum-precision). (*s7* 'bignum-precision) defaults to 128; it sets the number of bits each float takes. pi automatically reflects the current (*s7* 'bignum-precision):

> pi
3.141592653589793238462643383279502884195E0
> (*s7* 'bignum-precision)
128
> (set! (*s7* 'bignum-precision) 256)
256
> pi
3.141592653589793238462643383279502884197169399375105820974944592307816406286198E0

bignum? returns #t if its argument is a big number of some type; I use "bignum" for any big number, not just integers. To create a big number, either include enough digits to overflow the default types, or use the bignum function. Its argument is a string representing the desired number:

> (bignum "123456789123456789")
123456789123456789
> (bignum "1.123123123123123123123123123")
1.12312312312312312312312312300000000009E0

In the non-gmp case, if s7 is built using doubles (s7_double in s7.h), the float "epsilon" is around (expt 2 -53), or about 1e-16. In the gmp case, it is around (expt 2 (- (*s7* 'bignum-precision))). So in the default case (precision = 128), using gmp:

> (= 1.0 (+ 1.0 (expt 2.0 -128)))
#t
> (= 1.0 (+ 1.0 (expt 2.0 -127)))
#f

and in the non-gmp case:

> (= 1.0 (+ 1.0 (expt 2 -53)))
#t
> (= 1.0 (+ 1.0 (expt 2 -52)))
#f

In the gmp case, integers and ratios are limited only by the size of memory, but reals are limited by (*s7* 'bignum-precision). This means, for example, that

> (floor 1e56) ; (*s7* 'bignum-precision) is 128
99999999999999999999999999999999999999927942405962072064
> (set! (*s7* 'bignum-precision) 256)
256
> (floor 1e56)
100000000000000000000000000000000000000000000000000000000

The non-gmp case is similar, but it's easy to find the edge cases:

> (floor (+ 0.9999999995 (expt 2.0 23)))
8388609

math functions

s7 includes:

  • sinh, cosh, tanh, asinh, acosh, atanh
  • logior, logxor, logand, lognot, logbit?, ash, integer-length, integer-decode-float
  • random
  • nan?, infinite?

The random function can take any numeric argument, including 0. The following constants are predefined: pi, most-positive-fixnum, most-negative-fixnum. Other math-related differences between s7 and r5rs:

  • rational? and exact mean integer or ratio (i.e. not floating point), inexact means not exact.
  • floor, ceiling, truncate, and round return (exact) integer results.
  • "#" does not stand for an unknown digit.
  • the "@" complex number notation is not supported ("@" is an exponent marker in s7).
  • "+i" is not considered a number; include the real part.
  • modulo, remainder, and quotient take integer, ratio, or real arguments.
  • lcm and gcd can take integer or ratio arguments.
  • log takes an optional second argument, the base.
  • '.' and an exponent can occur in a number in any base.
  • rationalize returns a ratio!
  • case is significant in numbers, as elsewhere: #b0 is 0, but #B0 is an error.
> (exact? 1.0)
#f
> (rational? 1.5)
#f
> (floor 1.4)
1
> (remainder 2.4 1)
0.4
> (modulo 1.4 1.0)
0.4
> (lcm 3/4 1/6)
3/2
> (log 8 2)
3
> (number->string 0.5 2)
"0.1"
> (string->number "0.1" 2)
0.5
> (rationalize 1.5)
3/2
> (complex 1/2 0)
1/2
> (logbit? 6 1) ; argument order, (logbit? int index), follows gmp, not CL
#t

See cload and libgsl.scm for easy access to GSL, and similarly libm.scm for the C math library.

The exponent itself is always in base 10; this follows gmp usage. Scheme normally uses "@" for its useless polar notation, but that means (string->number "1e1" 16) is ambiguous — is the "e" a digit or an exponent marker? In s7, "@" is an exponent marker.

> (string->number "1e9" 2)  ; (expt 2 9)
512.0
> (string->number "1e1" 12) ; "e" is not a digit in base 12
#f
> (string->number "1e1" 16) ; (+ (* 1 16 16) (* 14 16) 1)
481
> (string->number "1.2e1" 3); (* 3 (+ 1 2/3))
5.0

Should s7 predefine the numbers +inf.0, -inf.0, and nan.0? It doesn't currently, but you can get them via log or 1/0 (see below). But what is (/ 1.0 0.0)? s7 gives a "division by zero" error here, and also in (/ 1 0). Guile returns +inf.0 in the first case, which seems reasonable, but a "numerical overflow" error in the second. Slightly weirder is (expt 0.0 0+i). Currently s7 returns 0.0, Guile returns +nan.0+nan.0i, Clisp and sbcl throw an error. Everybody agrees that (expt 0 0) is 1, and Guile thinks that (expt 0.0 0.0) is 1.0. But (expt 0 0.0) and (expt 0.0 0) return different results in Guile (1 and 1.0), both are 0.0 in s7, the first is an error in Clisp, but the second returns 1, and so on — what a mess! This mess was made a lot worse than it needs to be when the IEEE decreed that 0.0 equals -0.0, so we can't tell them apart, but that they produce different results in nearly every use!

scheme@(guile-user)> (= -0.0 0.0)
#t
scheme@(guile-user)> (negative? -0.0)
#f
scheme@(guile-user)> (= (/ 1.0 0.0) (/ 1.0 -0.0))
#f
scheme@(guile-user)>  (< (/ 1.0 -0.0) -1e100 1e100 (/ 1.0 0.0))
#t

How can they be equal? In s7, the sign of -0.0 is ignored, and they really are equal. One other oddity: two floats can satisfy eq? and yet not be eqv?: (eq? nan.0 nan.0) might be #t (it is unspecified), but (eqv? nan.0 nan.0) is #f. The same problem afflicts memq and assq.

The random function takes a range and an optional state, and returns a number between zero and the range, of the same type as the range. It is perfectly reasonable to use a range of 0, in which case random returns 0. random-state creates a new random state from a seed. If no state is passed, random uses some default state initialized from the current time. random-state? returns #t if passed a random state object. s7 ought to have a function named random? that always returns #t.

> (random 0)
0
> (random 1.0)
0.86331198514245
> (random 3/4)
654/1129
> (random 1+i)
0.86300308872748+0.83601002730848i
> (random -1.0)
-0.037691127513267
> (define r0 (random-state 1234))
r0
> (random 100 r0)
94
> (random 100 r0)
19
> (define r1 (random-state 1234))
r1
> (random 100 r1)
94
> (random 100 r1)
19

copy the random-state to save a spot in a random number sequence, or save the random-state as a list via random-state->list, then to restart from that point, apply random-state to that list.

I can't find the right tone for this section; this is the 400-th revision; I wish I were a better writer!

In some Schemes, "rational" means "could possibly be expressed equally well as a ratio: floats are approximations". In s7 it's: "is actually expressed (at the scheme level) as a ratio (or an integer of course)"; otherwise "rational?" is the same as "real?":

(not-s7)> (rational? (sqrt 2))
#t

That 1.0 is represented at the IEEE-float level as a sort of ratio does not mean it has to be a scheme ratio; the two notions are independent.

But that confusion is trivial compared to the completely nutty "inexact integer". As I understand it, "inexact" originally meant "floating point", and "exact" meant integer or ratio of integers. But words have a life of their own. 0.0 somehow became an "inexact" integer (although it can be represented exactly in floating point). +inf.0 must be an integer — its fractional part is explicitly zero! But +nan.0... And then there's:

(not-s7)> (integer? 9007199254740993.1)
#t

When does this matter? I often need to index into a vector, but the index is a float (a "real" in Scheme-speak: its fractional part can be non-zero). In one Scheme:

(not-s7)> (vector-ref #(0) (floor 0.1))
ERROR: Wrong type (expecting exact integer): 0.0   ; [why?  "it's probably a programmer mistake"!]

Not to worry, I'll use inexact->exact:

(not-s7)> (inexact->exact 0.1)
3602879701896397/36028797018963968                  ; [why? "floats are ratios"!]

So I end up using the verbose (floor (inexact->exact ...)) everywhere, and even then I have no guarantee that I'll get a legal vector index. I have never seen any use made of the exact/inexact distinction — just wild flailing to try get around it. I think the whole idea is confused and useless, and leads to verbose and buggy code. If we discard it, we can maintain backwards compatibility via:

(define exact? rational?)
(define (inexact? x) (not (rational? x)))
(define inexact->exact rationalize) ; or floor
(define (exact->inexact x) (* x 1.0))

#i and #e are also useless because you can have any number after, for example, #b:

> #b1.1
1.5
> #b1e2
4.0
> #o17.5+i
15.625+1i

Speaking of #b and friends, what should (string->number "#xffff" 2) return?

more examples
(define (log-n-of n . ints)     ; return the bits on in exactly n of ints
  (let ((len (length ints)))
    (cond ((= len 0) (if (= n 0) -1 0))
	  ((= n 0)   (lognot (apply logior ints)))
	  ((= n len) (apply logand ints))
	  ((> n len) 0)
	  (#t 
	   (do ((1s 0)
		(prev ints)
		(i 0 (+ i 1)))
	       ((= i len) 1s)
	     (let ((cur (ints i)))
	       (if (= i 0)
		   (set! 1s (logior 1s (logand cur (apply log-n-of (- n 1) (cdr ints)))))
		   (let* ((mid (cdr prev))
			  (nxt (if (= i (- len 1)) () (cdr mid))))
		     (set! (cdr prev) nxt)  
		     (set! 1s (logior 1s (logand cur (apply log-n-of (- n 1) ints))))
		     (set! (cdr prev) mid)
		     (set! prev mid)))))))))

define*, lambda*

define* and lambda* are extensions of define and lambda that make it easier to deal with optional, keyword, and rest arguments. The syntax is very simple: every argument to define* has a default value and is automatically available as a keyword argument. The default value is either #f if unspecified, or given in a list whose first member is the argument name. The last argument can be preceded by :rest or a dot to indicate that all other trailing arguments should be packaged as a list under that argument's name. A trailing or rest argument's default value is ().

(define* (hi a (b 32) (c "hi")) (list a b c))

Here the argument "a" defaults to #f, "b" to 32, etc. When the function is called, the argument names are set from the values passed the function, then any unset arguments are bound to their default values, evaluated in left-to-right order. As the current argument list is scanned, any name that occurs as a keyword, :arg for example where the parameter name is arg, sets that argument's new value. Otherwise, as values occur, they are plugged into the actual argument list based on their position, counting a keyword/value pair as one argument. This is called an optional-key list in CLM. So, taking the function above as an example:

> (hi 1) 
(1 32 "hi")
> (hi :b 2 :a 3) 
(3 2 "hi")
> (hi 3 2 1) 
(3 2 1)

See s7test.scm for many examples.

The combination of optional and keyword arguments is viewed with disfavor in the Lisp community, but the problem is in CL's implementation of the idea, not the idea itself. I've used the s7 style since around 1976, and have never found it confusing. The mistake in CL is to require the optional arguments if a keyword argument occurs, and to consider them as distinct from the keyword arguments. So everyone forgets and puts a keyword where CL expects a required-optional argument. CL then does something ridiculous, and the programmer stomps around shouting about keywords, but the fault lies with CL. If s7's way is considered too loose, one way to tighten it might be to insist that once a keyword is used, only keyword argument pairs can follow.

A natural companion of lambda* is named let*. In named let, the implicit function's arguments have initial values, but thereafter, each call requires the full set of arguments. Why not treat the initial values as default values?

> (let* func ((i 1) (j 2)) 
    (+ i j (if (> i 0) (func (- i 1)) 0)))
5
> (letrec ((func (lambda* ((i 1) (j 2)) 
                   (+ i j (if (> i 0) (func (- i 1)) 0)))))
    (func))
5

This is consistent with the lambda* arguments because their defaults are already set in left-to-right order, and as each parameter is set to its default value, the binding is added to the default value expression environment (just as if it were a let*). The let* name itself (the implicit function) is not defined until after the bindings have been evaluated (as in named let).

In CL, keyword default values are handled in the same way:

> (defun foo (&key (a 0) (b (+ a 4)) (c (+ a 7))) (list a b c)) 
FOO 
> (foo :b 2 :a 60) 
(60 2 67) 

In s7, we'd use:

(define* (foo (a 0) (b (+ a 4)) (c (+ a 7))) (list a b c))

To try to catch what I believe are usually mistakes, I added two error checks. One is triggered if you set the same parameter twice in the same call, and the other if an unknown keyword is encountered in the key position. These problems arise in a case such as

(define* (f (a 1) (b 2)) (list a b))

You could do any of the following by accident:

(f 1 :a 2)  ; what is a?
(f :b 1 2)  ; what is b?
(f :c 3)    ; did you really want a to be :c and b to be 3?

In the last case, to pass a keyword deliberately, either include the argument keyword: (f :a :c), or make the default value a keyword: (define* (f (a :c) ...)). To turn off this error check, add :allow-other-keys at the end of the parameter list.

rest arg nits

s7's lambda* arglist handling is not the same as CL's lambda-list. First, you can have more than one :rest parameter:

> ((lambda* (:rest a :rest b) (map + a b)) 1 2 3 4 5) 
'(3 5 7 9)

and second, the rest parameter, if any, takes up an argument slot just like any other argument:

> ((lambda* ((b 3) :rest x (c 1)) (list b c x)) 32)
(32 1 ())
> ((lambda* ((b 3) :rest x (c 1)) (list b c x)) 1 2 3 4 5)
(1 3 (2 3 4 5))

CL would agree with the first case if we used &key for 'c', but would give an error in the second. Of course, the major difference is that s7 keyword arguments don't insist that the key be present. The :rest argument is needed in cases like these because we can't use an expression such as:

> ((lambda* ((a 3) . b c) (list a b c)) 1 2 3 4 5)
error: stray dot?
> ((lambda* (a . (b 1)) b) 1 2) ; the reader turns the arglist into (a b 1)
error: lambda* parameter '1 is a constant

Yet another nit: the :rest argument is not considered a keyword argument, so

> (define* (f :rest a) a)
f
> (f :a 1)
(:a 1)

macros

define-macro, define-macro*, macroexpand, gensym, gensym?, and macro? implement the standard old-time macros.

> (define-macro (trace f)
    `(define ,f 
       (apply lambda 'args 
         `((format #t "(~A ~{~A~^ ~}) -> " ',',f args)
           (let ((val (apply ,,f args))) 
             (format #t "~A~%" val) 
             val)))))
trace
> (trace abs)
abs
> (abs -1.5)
(abs -1.5) -> 1.5
1.5

macroexpand can help debug a macro. I always forget that it wants an expression:

> (define-macro (add-1 arg) `(+ 1 ,arg))
add-1
> (macroexpand (add-1 32))
(+ 1 32)

gensym returns a symbol that is guaranteed to be unused. It takes an optional string argument giving the new symbol name's prefix. gensym? returns #t if its argument is a symbol created by gensym.

(define-macro (pop! sym)
  (let ((v (gensym)))
    `(let ((,v (car ,sym)))
       (set! ,sym (cdr ,sym))
       ,v)))

As in define*, the starred forms give optional and keyword arguments:

> (define-macro* (add-2 a (b 2)) `(+ ,a ,b))
add-2
> (add-2 1 3)
4
> (add-2 1)
3
> (add-2 :b 3 :a 1)
4

A bacro is a macro that expands its body and evaluates the result in the calling environment.

(define setf
  (let ((args (gensym))
        (name (gensym)))
     (apply define-bacro `((,name . ,args)        
			   (unless (null? ,args)
			     (apply set! (car ,args) (cadr ,args) ())
			     (apply setf (cddr ,args)))))))

The setf argument is a gensym (created when setf is defined) so that its name does not shadow any existing variable. Bacros expand in the calling environment, and a normal argument name might shadow something in that environment while the bacro is being expanded. Similarly, if you introduce bindings in the bacro expansion code, you need to keep track of which environment you want things to happen in. Use with-let and gensym liberally. stuff.scm has bacro-shaker which can find inadvertent name collisions, but it is flighty and easily confused. See s7test.scm for many examples of macros including such perennial favorites as loop, dotimes, do*, enum, pushnew, and defstruct. The calling environment itself is (outlet (curlet)) from within a bacro, so

(define-bacro (holler)
  `(format *stderr* "(~S~{ ~S ~S~^~})~%" 
	   (let ((f __func__))
	     (if (pair? f) (car f) f))
	   (map (lambda (slot)
		  (values (symbol->keyword (car slot)) (cdr slot)))		  
		(reverse (map values ,(outlet (curlet)))))))

(define (f1 a b)
  (holler)
  (+ a b))

(f1 2 3) ; prints out "(f1 :a 2 :b 3)" and returns 5

Since a bacro (normally) sheds its define-time environment:

(define call-bac
  (let ((x 2))
    (define-bacro (m a) `(+ ,a ,x))))

> (call-bac 1) 
error: x: unbound variable

A macro here returns 3. But don't be hasty! The bacro can get its define-time environment (its closure) via funclet, so in fact, define-macro is a special case of define-bacro! We can define macros that work in all four ways: the expansion can happen in either the definition or calling environment, as can the evaluation of that expansion. In a bacro, both happen in the calling environment if we take no other action, and in a normal macro (define-macro), the expansion happens in the definition environment, and the evaluation in the calling environment. Here's a brief example of all four:

(let ((x 1) (y 2)) 
  (define-bacro (bac1 a) 
     `(+ ,x y ,a))        ; expand and eval in calling env
  (let ((x 32) (y 64)) 
    (bac1 3)))            ; (with-let (inlet 'x 32 'y 64) (+ 32 y 3))
-> 99                     ;  with-let and inlet refer to environments

(let ((x 1) (y 2))        ; this is like define-macro
  (define-bacro (bac2 a) 
    (with-let (sublet (funclet bac2) :a a)
      `(+ ,x y ,a)))      ; expand in definition env, eval in calling env
  (let ((x 32) (y 64)) 
    (bac2 3)))            ; (with-let (inlet 'x 32 'y 64) (+ 1 y 3))
-> 68

(let ((x 1) (y 2))
  (define-bacro (bac3 a) 
    (let ((e (with-let (sublet (funclet bac3) :a a)
	       `(+ ,x y ,a))))
      `(with-let ,(sublet (funclet bac3) :a a)
	 ,e)))           ; expand and eval in definition env 
  (let ((x 32) (y 64)) 
    (bac3 3)))           ; (with-let (inlet 'x 1 'y 2) (+ 1 y 3))
-> 6

(let ((x 1) (y 2))
  (define-bacro (bac4 a) 
    (let ((e `(+ ,x y ,a)))
      `(with-let ,(sublet (funclet bac4) :a a)
	 ,e)))           ; expand in calling env, eval in definition env
  (let ((x 32) (y 64))     
    (bac4 3)))           ; (with-let (inlet 'x 1 'y 2) (+ 32 y 3))
-> 37

As the setf example shows, a macro is a first-class citizen of s7. You can pass it as a function argument, apply it to a list, return it from a function, call it recursively, and assign it to a variable. You can even set its procedure-setter!

> (define-macro (hi a) `(+ ,a 1))
hi
> (apply hi '(4))
5
> (define (fmac mac) (apply mac '(4)))
fmac
> (fmac hi)
5
> (define (fmac mac) (mac 4))
fmac
> (fmac hi)
5
> (define (make-mac)
    (define-macro (hi a) `(+ ,a 1)))
make-mac
> (let ((x (make-mac)))
    (x 2))
3
> (define-macro (ref v i) `(vector-ref ,v ,i))
ref
> (define-macro (set v i x) `(vector-set! ,v ,i ,x))
set
> (set! (procedure-setter ref) set)
set
> (let ((v (vector 1 2 3))) (set! (ref v 0) 32) v)
#(32 2 3)

To expand all the macros in a piece of code:

(define-macro (fully-macroexpand form)
  (define (expand form)
    (if (pair? form)
	(if (and (symbol? (car form))
		 (macro? (symbol->value (car form))))
	    (expand (apply macroexpand (list form)))
	    (if (and (eq? (car form) 'set!)  ; look for (set! (mac ...) ...) and use mac's procedure-setter
		     (pair? (cdr form))
		     (pair? (cadr form))
		     (macro? (symbol->value (caadr form))))
		(expand (apply (eval (procedure-source (procedure-setter (symbol->value (caadr form))))) 
			       (append (cdadr form) (cddr form))))
		(cons (expand (car form))
		      (expand (cdr form)))))
	form))
  (list 'quote (expand form)))

This does not always handle bacros correctly because their expansion can depend on the run-time state.

backquote details

Backquote (quasiquote) in s7 is almost trivial. Constants are unchanged, symbols are quoted, ",arg" becomes "arg", and ",@arg" becomes "(apply values arg)" — hooray for real multiple values! It's almost as easy to write the actual macro body as the backquoted version of it.

> (define-macro (hi a) `(+ 1 ,a))
hi
> (procedure-source hi)
(lambda (a) ({list} '+ 1 a))

> (define-macro (hi a) `(+ 1 ,@a))
hi
> (procedure-source hi)
(lambda (a) ({list} '+ 1 ({apply_values} a)))

{list} is a special version of list to avoid name collisions and handle a few tricky details (similarly for {apply_values}). There is no unquote-splicing macro in s7; ",@(...)" becomes "(unquote ({apply_values} ...))" at read-time. There shouldn't be any unquote either. In Scheme the reader turns ,x into (unquote x), so:

> (let (,'a) unquote)
a
> (let (, (lambda (x) (+ x 1))) ,,,,'3)
7

comma becomes a sort of symbol macro! I think I'll remove unquote; ,x and ,@x will still work as expected, but there will not be any "unquote" or "unquote-splicing" in the resultant source code. Just to make life difficult:

> (let (' 1) quote)
1

but that translation is so ingrained in lisp that I'm reluctant to change it. The two unquote names, on the other hand, seem unnecessary.

s7 macros are not hygienic. For example,

> (define-macro (mac b) 
    `(let ((a 12)) 
       (+ a ,b)))
mac
> (let ((a 1) (+ *)) (mac a))
144

This returns 144 because '+' has turned into '*', and 'a' is the internal 'a', not the argument 'a'. We get (* 12 12) where we might have expected (+ 12 1). Starting with the '+' problem, as long as the redefinition of '+' is local (that is, it happens after the macro definition), we can unquote the +:

> (define-macro (mac b) 
    `(let ((a 12)) 
       (,+ a ,b))) ; ,+ picks up the definition-time +
mac
> (let ((a 1) (+ *)) (mac a))
24                 ; (+ a a) where a is 12

But the unquote trick won't work if we have previously loaded some file that redefined '+' at the top-level (so at macro definition time, + is *, but we want the built-in +). Although this example is silly, the problem is real in Scheme because Scheme has no reserved words and only one name space.

> (define + *)
+
> (define (add a b) (+ a b))
add
> (add 2 3)
6
> (define (divide a b) (/ a b))
divide
> (divide 2 3)
2/3
> (set! / -) ; a bad idea — this turns off s7's optimizer
-
> (divide 2 3)
-1

Obviously macros are not the problem here. Since we might be loading code written by others, it's sometimes hard to tell what names that code depends on or redefines. We need a way to get the pristine (start-up, built-in) value of '+'. One long-winded way in s7 uses unlet:

> (define + *)
+
> (define (add a b) (with-let (unlet) (+ a b)))
add
> (add 2 3)
5

But this is hard to read, and it's not inconceivable that we might want all three values of a symbol, the start-up value, the definition-time value, and the current value. The latter can be accessed with the bare symbol, the definition-time value with unquote (','), and the start-up value with either unlet or #_<name>. That is, #_+ is a reader macro for (with-let (unlet) +).

> (define-macro (mac b) 
    `(#_let ((a 12)) 
       (#_+ a ,b))) ; #_+ and #_let are start-up values
mac
> (let ((a 1) (+ *)) (mac a))
24                 ; (+ a a) where a is 12 and + is the start-up +

;;; make + generic (there's a similar C-based example below)
> (define (+ . args) 
    (if (null? args) 0 
        (apply (if (number? (car args)) #_+ #_string-append) args)))
+
> (+ 1 2)
3
> (+ "hi" "ho")
"hiho"

#_<name> could be implemented via *#readers*:

(set! *#readers*
  (cons (cons #\_ (lambda (str)
		    (with-let (unlet)
                      (string->symbol (substring str 1)))))
	*#readers*))

So, now we have only the variable capture problem ('a' has been captured in the preceding examples). This is the only thing that the gigantic "hygienic macro" systems actually deal with: a microscopic problem that you'd think, from the hype, was up there with malaria and the national debt. gensym is the standard approach:

> (define-macro (mac b) 
    (let ((var (gensym))) 
      `(#_let ((,var 12))
         (#_+ ,var ,b))))
mac
> (let ((a 1) (+ *)) (mac a))
13

;; or use lambda:
> (define-macro (mac b) 
  `((lambda (b) (let ((a 12)) (#_+ a b))) ,b))
mac
> (let ((a 1) (+ *)) (mac a))
13

But in s7, the simplest approach uses environments. You have complete control over the environment at any point:

(define-macro (mac b)
  `(with-let (inlet 'b ,b)
     (let ((a 12))
       (+ a b))))

> (let ((a 1) (+ *)) (mac a))
13

So s7 does not have syntax-rules because it is not needed.

(define-macro (swap a b) ; assume a and b are symbols
  `(with-let (inlet 'e (curlet) 'tmp ,a)
     (set! (e ',a) (e ',b))
     (set! (e ',b) tmp)))

> (let ((b 1) (tmp 2)) (swap b tmp) (list b tmp))
(2 1)

(define-macro (swap a b) ; here a and b can be any settable expressions
  `(set! ,b (with-let (inlet 'e (curlet) 'tmp ,a) 
	      (with-let e (set! ,a ,b))
	      tmp)))

> (let ((v (vector 1 2))) (swap (v 0) (v 1)) v)
#(2 1)
> (let ((tmp (cons 1 2))) (swap (car tmp) (cdr tmp)) tmp)
(2 . 1)

(set! (procedure-setter swap) (define-macro (set-swap a b c) `(set! ,b ,c)))

> (let ((a 1) (b 2) (c 3) (d 4)) (swap a (swap b (swap c d))) (list a b c d))
(2 3 4 1)

;;; but this is simpler:
(define-macro (rotate! . args)
  `(set! ,(args (- (length args) 1))
         (with-let (inlet 'e (curlet) 'tmp ,(car args))
	   (with-let e 
	     ,@(map (lambda (a b) `(set! ,a ,b)) args (cdr args)))
	   tmp)))

> (let ((a 1) (b 2) (c 3)) (rotate! a b c) (list a b c))
(2 3 1)

If you want the macro's expanded result to be evaluated in its definition environment:

(let ((a 3))
  (define-macro (mac b)
    `(with-let (inlet 'b ,b (funclet mac))
       (+ a b)))       ; definition-time "a", call-time "b"
  (define-macro (mac-1 b)
    `(+ a ,b))         ; call-time "a" and "b"
  (let ((a 32))
    (list (mac 1) 
	  (mac-1 1))))
loopy macros

There is another problem with macros: accidental loops. Take the following example; we're trying to write a macro that defines a function that returns its argument in a list statement.

> (define-macro (hang arg) `(define ,arg `(list (cdr ,,arg))))
hang
> (macroexpand (hang (f a)))
(define #1=(f a) ({list} 'list ({list} 'cdr #1#)))
> (hang (f a))
f
> (procedure-source f)
(lambda #1=(a) ({list} 'list ({list} 'cdr #1#)))
>(f 1)

And now we are hung — we've created a procedure with an infinite loop! This is surprisingly easy to do by accident. Here's one way out:

> (define-macro (hang arg) `(define ,arg `(list ,,@(cdr arg))))
hang
> (macroexpand (hang (f a)))
(define (f a) ({list} 'list a))
> (hang (f a))
f
> (f 1)
(list 1)

Here is Peter Seibel's wonderful once-only macro:

(define-macro (once-only names . body)
  (let ((gensyms (map (lambda (n) (gensym)) names)))
    `(let (,@(map (lambda (g) (list g '(gensym))) gensyms))
       `(let (,,@(map (lambda (g n) (list list g n)) gensyms names))
          ,(let (,@(map list names gensyms))
             ,@body)))))

From the land of sparkling bacros:

(define once-only
  (let ((names (gensym))
	(body (gensym)))
    (apply define-bacro `((,(gensym) ,names . ,body)
      `(let (,@(map (lambda (name) `(,name ,(eval name))) ,names))
	 ,@,body)))))

Sadly, with-let is simpler.

procedure-setter

(procedure-setter proc)
(dilambda proc setter)

Each function (or macro!) can have an associated setter, much like defsetf in CL. As a convenience, there's also a way to associate the two functions under one name: dilambda. The setter is called when the procedure is the target of set! Its last argument is the value passed to set!:

> (procedure-setter cadr)
#f
> (set! (procedure-setter cadr) 
        (lambda (lst val) 
          (set! (car (cdr lst)) val)))
#<lambda (lst val)>
> (procedure-source (procedure-setter cadr))
(lambda (lst val) (set! (car (cdr lst)) val))
> (let ((lst (list 1 2 3))) 
    (set! (cadr lst) 4) 
    lst)
(1 4 3)

In some cases, the setter needs to be a macro:

> (set! (procedure-setter logbit?)
          (define-macro (m var index on) ; here we want to set "var", so we need a macro
	    `(if ,on
	         (set! ,var (logior ,var (ash 1 ,index)))
	         (set! ,var (logand ,var (lognot (ash 1 ,index)))))))
m
> (define (mingle a b)
    (let ((r 0))
      (do ((i 0 (+ i 1)))
          ((= i 31) r)
        (set! (logbit? r (* 2 i)) (logbit? a i))
        (set! (logbit? r (+ (* 2 i) 1)) (logbit? b i)))))
mingle
> (mingle 6 3) ; the INTERCAL mingle operator?
30

Here is a pretty example of dilambda:

(define-macro (c?r path)
  ;; "path" is a list and "X" marks the spot in it that we are trying to access
  ;; (a (b ((c X)))) — anything after the X is ignored, other symbols are just placeholders
  ;; c?r returns a dilambda that gets/sets X

  (define (X-marks-the-spot accessor tree)
    (if (pair? tree)
	(or (X-marks-the-spot (cons 'car accessor) (car tree))
	    (X-marks-the-spot (cons 'cdr accessor) (cdr tree)))
	(and (eq? tree 'X) accessor)))

  (let ((body 'lst))
    (for-each
     (lambda (f)
       (set! body (list f body)))
     (reverse (X-marks-the-spot () path)))

    `(dilambda
      (lambda (lst) 
	,body)
      (lambda (lst val)
	(set! ,body val)))))

> ((c?r (a b (X))) '(1 2 (3 4) 5))
3
> (let ((lst (list 1 2 (list 3 4) 5))) 
   (set! ((c?r (a b (X))) lst) 32)
   lst)
(1 2 (32 4) 5)
> (procedure-source (c?r (a b (X))))
(lambda (lst) (car (car (cdr (cdr lst)))))
> ((c?r (a b . X)) '(1 2 (3 4) 5))
((3 4) 5)
> (let ((lst (list 1 2 (list 3 4) 5))) 
   (set! ((c?r (a b . X)) lst) '(32))
   lst)
(1 2 32)
> (procedure-source (c?r (a b . X)))
(lambda (lst) (cdr (cdr lst)))
> ((c?r (((((a (b (c (d (e X)))))))))) '(((((1 (2 (3 (4 (5 6)))))))))) 
6
> (let ((lst '(((((1 (2 (3 (4 (5 6))))))))))) 
    (set! ((c?r (((((a (b (c (d (e X)))))))))) lst) 32) 
    lst)
(((((1 (2 (3 (4 (5 32)))))))))
> (procedure-source (c?r (((((a (b (c (d (e X)))))))))))
(lambda (lst) (car (cdr (car (cdr (car (cdr (car (cdr (car (cdr (car (car (car (car lst)))))))))))))))

Speaking of INTERCAL, COME-FROM:

(define-macro (define-with-goto-and-come-from name-and-args . body)
  (let ((labels ())
	(gotos ())
	(come-froms ()))

    (define (collect-jumps tree)
      (when (pair? tree)
	(when (pair? (car tree))
	  (case (caar tree)
	    ((label)     (set! labels (cons tree labels)))
	    ((goto)      (set! gotos (cons tree gotos)))
	    ((come-from) (set! come-froms (cons tree come-froms)))
	    (else (collect-jumps (car tree)))))
	(collect-jumps (cdr tree))))

    (collect-jumps body)

    (for-each
     (lambda (goto)
       (let* ((name (cadr (cadar goto)))
	      (label (member name labels (lambda (a b) (eq? a (cadr (cadar b)))))))
	 (if label
	     (set-cdr! goto (car label))
	     (error 'bad-goto "can't find label: ~S" name))))
     gotos)
    
    (for-each
     (lambda (from)
       (let* ((name (cadr (cadar from)))
	      (label (member name labels (lambda (a b) (eq? a (cadr (cadar b)))))))
	 (if label
	     (set-cdr! (car label) from)
	     (error 'bad-come-from "can't find label: ~S" name))))
     come-froms)

    `(define ,name-and-args
       (let ((label (lambda (name) #f))
	     (goto (lambda (name) #f))
	     (come-from (lambda (name) #f)))
	 ,@body))))

applicable objects, generalized set!, generic functions

A procedure with a setter can be viewed as one generalization of set!. Another treats objects as having predefined get and set functions. In s7 lists, strings, vectors, hash-tables, environments, and any cooperating C or Scheme-defined objects are both applicable and settable. newLisp calls this implicit indexing, Kawa has it, Gauche implements it via object-apply, Guile via procedure-with-setter; CL's funcallable instance might be the same idea.

In (vector-ref #(1 2) 0), for example, vector-ref is just a type declaration. But in Scheme, type declarations are unnecessary, so we get exactly the same result from (#(1 2) 0). Similarly, (lst 1) is the same as (list-ref lst 1), and (set! (lst 1) 2) is the same as (list-set! lst 1 2). I like this syntax: the less noise, the better!

Well, maybe applicable strings look weird: ("hi" 1) is #\i, but worse, so is (cond (1 => "hi"))! Even though a string, list, or vector is "applicable", it is not currently considered to be a procedure, so (procedure? "hi") is #f. map and for-each, however, accept anything that apply can handle, so (map #(0 1) '(1 0)) is '(1 0). (On the first call to map in this case, you get the result of (#(0 1) 1) and so on). string->list, vector->list, and let->list are (map values object). Their inverses are (and always have been) equally trivial.

The applicable object syntax makes it easy to write generic functions. For example, s7test.scm has implementations of Common Lisp's sequence functions. length, copy, reverse, fill!, iterate, map and for-each are generic in this sense (map always returns a list).

> (map (lambda (a b) (- a b)) (list 1 2) (vector 3 4))
(5 -3 9)
> (length "hi")
2

Here's a generic FFT:

(define* (cfft! data n (dir 1)) ; (complex data)
  (if (not n) (set! n (length data)))
  (do ((i 0 (+ i 1))
       (j 0))
      ((= i n))
    (if (> j i)
	(let ((temp (data j)))
	  (set! (data j) (data i))
	  (set! (data i) temp)))
    (let ((m (/ n 2)))
      (do () 
	  ((or (< m 2) (< j m)))
	(set! j (- j m))
	(set! m (/ m 2)))
      (set! j (+ j m))))
  (let ((ipow (floor (log n 2)))
	(prev 1))
    (do ((lg 0 (+ lg 1))
	 (mmax 2 (* mmax 2))
	 (pow (/ n 2) (/ pow 2))
	 (theta (complex 0.0 (* pi dir)) (* theta 0.5)))
	((= lg ipow))
      (let ((wpc (exp theta))
	    (wc 1.0))
	(do ((ii 0 (+ ii 1)))
	    ((= ii prev))
	  (do ((jj 0 (+ jj 1))
	       (i ii (+ i mmax))
	       (j (+ ii prev) (+ j mmax)))
	      ((>= jj pow))
	    (let ((tc (* wc (data j))))
	      (set! (data j) (- (data i) tc))
	      (set! (data i) (+ (data i) tc))))
	  (set! wc (* wc wpc)))
	(set! prev mmax))))
  data)

> (cfft! (list 0.0 1+i 0.0 0.0))
(1+1i -1+1i -1-1i 1-1i)
> (cfft! (vector 0.0 1+i 0.0 0.0))
#(1+1i -1+1i -1-1i 1-1i)

And a generic function that copies one sequence's elements into another sequence:

(define (copy-into source dest) ; this is equivalent to (copy source dest)
  (do ((i 0 (+ i 1))) 
      ((= i (min (length source) (length dest))) 
       dest)
    (set! (dest i) (source i))))

but that is already built-in as the two-argument version of the copy function.

There is one place where list-set! and friends are not the same as set!: the former evaluate their first argument, but set! does not (with a quibble; see below):

> (let ((str "hi")) (string-set! (let () str) 1 #\a) str)
"ha"
> (let ((str "hi")) (set! (let () str) 1 #\a) str)
;((let () str) 1 #\a): too many arguments to set!
> (let ((str "hi")) (set! ((let () str) 1) #\a) str)
"ha"
> (let ((str "hi")) (set! (str 1) #\a) str)
"ha"

set! looks at its first argument to decide what to set. If it's a symbol, no problem. If it's a list, set! looks at its car to see if it is some object that has a setter. If the car is itself a list, set! evaluates the internal expression, and tries again. So the second case above is the only one that won't work. And of course:

> (let ((x (list 1 2))) 
    (set! ((((lambda () (list x))) 0) 0) 3) 
    x) 
(3 2)

By my count, around 20 of the Scheme built-in functions are already generic in the sense that they accept arguments of many types (leaving aside the numeric and type checking functions, take for example equal?, display, member, assoc, apply, eval, quasiquote, and values). s7 extends that list with map, for-each, reverse, and length, and adds a few others such as copy, fill!, sort!, object->string, and append. newLisp takes a more radical approach than s7: it extends operators such as '>' to compare strings and lists, as well as numbers. In map and for-each, however, you can mix the argument types, so I'm not as attracted to making '>' generic; you can't, for example, (> "hi" 32.1), or even (> 1 0+i).

The somewhat non-standard generic sequence functions in s7 are:

(sort! sequence less?)
(reverse! sequence) and (reverse sequence)
(fill! sequence value (start 0) end)
(copy obj) and (copy source destination (start 0) end)
(object->string obj)
(length obj)
(append . sequences)
(map func . sequences) and (for-each func . sequences)
(morally-equal? obj1 obj2)

reverse! is an in-place version of reverse. That is, it modifies the sequence passed to it in the process of reversing its contents. If the sequence is a list, remember to use set!: (set! p (reverse! p)). This is somewhat inconsistent with other cases, but historically, lisp programmers have treated the in-place reverse as the fast version, so s7 follows suit.

Leaving aside the weird list case, append returns a sequence of the same type as its first argument.

> (append #(1 2) '(3 4))
#(1 2 3 4)
> (append (float-vector) '(1 2) (byte-vector 3 4))
(float-vector 1.0 2.0 3.0 4.0)

sort! sorts a sequence using the function passed as its second argument:

> (sort! (list 3 4 8 2 0 1 5 9 7 6) <)
(0 1 2 3 4 5 6 7 8 9)

Underlying some of these functions are generic iterators, also built-into s7:

(make-iterator sequence)
(iterator? obj)
(iterate iterator)
(iterator-sequence iterator)
(iterator-at-end? iterator)

make-iterator takes a sequence argument and returns an iterator object that traverses that sequence as it is called. The iterator itself can be treated as a function of no arguments, or (for code clarity) it can be the argument to iterate, which does the same thing. That is (iter) is the same as (iterate iter). The sequence that an iterator is traversing is iterator-sequence.

If the sequence is a hash-table or let, the iterator normally returns a cons of the key and value. There are many cases where this overhead is objectionable, so make-iterator takes a third optional argument, the cons to use (changing its car and cdr directly on each call).

When an iterator reaches the end of its sequence, it returns #<eof>. It used to return nil; I can't decide whether this change is an improvement. If an iterator over a list notices that its list is circular, it returns #<eof>. map and for-each use iterators, so if you pass a circular list to either, it will stop eventually. (An arcane consequence for method writers: specialize make-iterator, not map or for-each).

(define (find-if f sequence)
  (let ((iter (make-iterator sequence)))
    (do ((x (iter) (iter)))
	((or (eof-object? x) (f x))
	 (and (not (eof-object? x)) x)))))

But of course a sequence might contain #<eof>! So to be really safe, use iterator-at-end? instead of eof-object?.

The argument to make-iterator can also be a function or macro. There should be a variable named 'iterator with a non-#f value in the closure's environment:

(define (make-circular-iterator obj)
  (let ((iter (make-iterator obj)))
    (make-iterator 
     (let ((iterator? #t))
       (lambda ()
         (let ((result (iter)))
	   (if (eof-object? result)
	       ((set! iter (make-iterator obj)))
	       result)))))))

The 'iterator? variable is similar to the 'documentation variable used by procedure-documentation. It gives make-iterator some hope of catching inadvertent bogus function arguments that would otherwise cause an infinite loop.

multidimensional vectors

s7 supports vectors with any number of dimensions. It is here, in particular, that generalized set! shines. make-vector's second argument can be a list of dimensions, rather than an integer as in the one dimensional case:

(make-vector (list 2 3 4))
(make-vector '(2 3) 1.0)
(vector-dimensions (make-vector (list 2 3 4))) -> (2 3 4)

The second example includes the optional initial element. (vect i ...) or (vector-ref vect i ...) return the given element, and (set! (vect i ...) value) and (vector-set! vect i ... value) set it. vector-length (or just length) returns the total number of elements. vector-dimensions returns a list of the dimensions.

> (define v (make-vector '(2 3) 1.0))
#2D((1.0 1.0 1.0) (1.0 1.0 1.0))
> (set! (v 0 1) 2.0)
#2D((1.0 2.0 1.0) (1.0 1.0 1.0))
> (v 0 1)
2.0
> (vector-length v)
6

This function initializes each element of a multidimensional vector:

(define (make-array dims . inits)
  (make-shared-vector (apply vector (flatten inits)) dims))

> (make-array '(3 3) '(1 1 1) '(2 2 2) '(3 3 3))
#2D((1 1 1) (2 2 2) (3 3 3))

make-vector also takes an optional fourth argument. If it is #t, and the initial-value is either an integer or a real, make-vector produces a homogenous vector, a vector that can only hold elements of the same type as the initial value (either s7_int or s7_double internally). Homogenous vectors are mostly useful in conjunction with C code. These homogenous vector functions are currently built-in:

(float-vector? obj)
(float-vector . args)
(make-float-vector len (init 0.0))
(float-vector-ref obj . indices)
(float-vector-set! obj indices[...] value)

(int-vector? obj)
(int-vector . args)
(make-int-vector len (init 0))
(int-vector-ref obj . indices)
(int-vector-set! obj indices[...] value)

And also, for completeness:

(byte-vector? obj)
(byte-vector . args)
(make-byte-vector len (init 0))
(->byte-vector str)

but these are really just strings in disguise.

To access a vector's elements with different dimensions than the original had, use (make-shared-vector original-vector new-dimensions (offset 0)):

> (let ((v1 #2d((1 2 3) (4 5 6)))) 
    (let ((v2 (make-shared-vector v1 '(6)))) ; flatten the original
      v2))
#(1 2 3 4 5 6)
> (let ((v1 #(1 2 3 4 5 6))) 
    (let ((v2 (make-shared-vector v1 '(3 2)))) 
      v2))
#2D((1 2) (3 4) (5 6))

matrix multiplication:

(define (matrix-multiply A B)
  ;; assume square matrices and so on for simplicity
  (let* ((size (car (vector-dimensions A)))
	 (C (make-vector (list size size) 0)))
    (do ((i 0 (+ i 1)))
	((= i size) C)
      (do ((j 0 (+ j 1)))
	  ((= j size))
	(let ((sum 0))
	  (do ((k 0 (+ k 1)))
	      ((= k size))
	    (set! sum (+ sum (* (A i k) (B k j)))))
	  (set! (C i j) sum))))))

Conway's game of Life:

(define* (life (width 40) (height 40))
  (let ((state0 (make-vector (list width height) 0))
	(state1 (make-vector (list width height) 0)))

    ;; initialize with some random pattern
    (do ((x 0 (+ x 1)))
	((= x width))
      (do ((y 0 (+ y 1)))
	  ((= y height))
	(set! (state0 x y) (if (< (random 100) 15) 1 0))))

    (do () ()
      ;; show current state (using terminal escape sequences, borrowed from the Rosetta C code)
      (format *stderr* "~C[H" #\escape)           ; ESC H = tab set
      (do ((y 0 (+ y 1)))
	  ((= y height))
	(do ((x 0 (+ x 1)))
	    ((= x width))
	  (if (zero? (state0 x y))
	      (format *stderr* "  ")              ; ESC 07m below = inverse
	      (format *stderr* "~C[07m  ~C[m" #\escape #\escape)))
	(format *stderr* "~C[E" #\escape))        ; ESC E = next line

      ;; get the next state
      (do ((x 1 (+ x 1)))
	  ((= x (- width 1)))
	(do ((y 1 (+ y 1)))
	    ((= y (- height 1)))
	  (let ((n (+ (state0 (- x 1) (- y 1))
		      (state0    x    (- y 1))
		      (state0 (+ x 1) (- y 1))
		      (state0 (- x 1)    y)      
		      (state0 (+ x 1)    y)      
		      (state0 (- x 1) (+ y 1))
		      (state0    x    (+ y 1))
		      (state0 (+ x 1) (+ y 1)))))
	    (set! (state1 x y) 
		  (if (or (= n 3) 
			  (and (= n 2)
			       (not (zero? (state0 x y)))))
		      1 0)))))
      (do ((x 0 (+ x 1)))
	  ((= x width))
	(do ((y 0 (+ y 1)))
	    ((= y height))
	  (set! (state0 x y) (state1 x y)))))))

Multidimensional vector constant syntax is modelled after CL: #nd(...) or #nD(...) signals that the lists specify the elements of an 'n' dimensional vector: #2D((1 2 3) (4 5 6))

> (vector-ref #2D((1 2 3) (4 5 6)) 1 2)
6
> (matrix-multiply #2d((-1 0) (0 -1)) #2d((2 0) (-2 2)))
#2D((-2 0) (2 -2))

If any dimension has 0 length, you get an n-dimensional empty vector. It is not equal to a 1-dimensional empty vector.

> (make-vector '(10 0 3))
#3D()
> (equal? #() #3D())
#f

To save on costly parentheses, and make it easier to write generic multidimensional sequence functions, you can use this same syntax with lists.

> (let ((L '((1 2 3) (4 5 6))))
    (L 1 0))              ; same as (list-ref (list-ref L 1) 0) or ((L 1) 0)
4
> (let ((L '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))))) 
    (set! (L 1 0 2) 32)   ; same as (list-set! (list-ref (list-ref L 1) 0) 2 32) which is unreadable!
    L)
(((1 2 3) (4 5 6)) ((7 8 32) (10 11 12)))

Or with vectors of vectors, of course:

> (let ((V #(#(1 2 3) #(4 5 6)))) 
    (V 1 2))              ; same as (vector-ref (vector-ref V 1) 2) or ((V 1) 2)
6
> (let ((V #2d((1 2 3) (4 5 6))))
    (V 0))
#(1 2 3)

There's one difference between a vector-of-vectors and a multidimensional vector: in the latter case, you can't clobber one of the inner vectors.

> (let ((V #(#(1 2 3) #(4 5 6)))) (set! (V 1) 32) V)
#(#(1 2 3) 32)
> (let ((V #2d((1 2 3) (4 5 6)))) (set! (V 1) 32) V)
;not enough args for vector-set!: (#2D((1 2 3) (4 5 6)) 1 32)

Using lists to display the inner vectors may not be optimal, especially when the elements are also lists:

#2D(((0) (0) ((0))) ((0) 0 ((0))))

The "#()" notation is no better (the elements can be vectors), and I'm not a fan of "[]" parentheses. Perhaps we could use different colors? Or different size parentheses?

#2D(((0) (0) ((0))) ((0) 0 ((0))))
#2D(((0) (0) ((0))) ((0) 0 ((0))))

A similar problem afflicts homogenous vectors. We need some reasonable way to express such a vector even when it has more than one dimension. My first thought was #(...)#, but that makes (let ((b1 0)) (#(1 2)#b1)) ambiguous.

I'm not sure how to handle vector->list and list->vector in the multidimensional case. Currently, vector->list flattens the vector, and list->vector always returns a one dimensional vector, so the two are not inverses.

> (vector->list #2d((1 2) (3 4)))
(1 2 3 4)             ; should this be '((1 2) (3 4)) or '(#(1 2) #(3 4))?
> (list->vector '(#(1 2) #(3 4))) ; what about '((1 2) (3 4))?
#(#(1 2) #(3 4))      

This also affects format and sort!:

> (format #f "~{~A~^ ~}" #2d((1 2) (3 4)))
"1 2 3 4"
> (sort! #2d((1 4) (3 2)) >) 
#2D((4 3) (2 1))

Perhaps make-shared-vector can help:

>(make-shared-vector (list->vector '(1 2 3 4)) '(2 2))
#2D((1 2) (3 4))

Another question: should we accept the multi-index syntax in a case such as:

(let ((v #("abc" "def"))) 
  (v 0 2))

My first thought was that the indices should all refer to the same type of object, so s7 would complain in a mixed case like that. If we can nest any applicable objects and apply the whole thing to an arbitrary list of indices, ambiguities arise:

((lambda (x) x) "hi" 0) 
((lambda (x) (lambda (y) (+ x y))) 1 2)

I think these should complain that the function got too many arguments, but from the implicit indexing point of view, they could be interpreted as:

(string-ref ((lambda (x) x) "hi") 0) ; i.e. (((lambda (x) x) "hi") 0)
(((lambda (x) (lambda (y) (+ x y))) 1) 2)

Add optional and rest arguments, and you can't tell who is supposed to take which arguments. Currently, you can mix types with implicit indices, but a function grabs all remaining indices. Trickier than I expected!

hash-tables

  • (make-hash-table (size 8) eq-func)
  • (hash-table ...)
  • (hash-table* ...)
  • (hash-table? obj)
  • (hash-table-ref ht key)
  • (hash-table-set! ht key value)
  • (hash-table-entries ht)

Each hash-table keeps track of the keys it contains, optimizing the search wherever possible. Any s7 object can be the key or the key's value. If you pass a table size that is not a power of 2, make-hash-table rounds it up to the next power of 2. The table grows as needed. length returns the current size. If a key is not in the table, hash-table-ref returns #f. To remove a key, set its value to #f; to remove all keys, (fill! table #f).

> (let ((ht (make-hash-table)))
    (set! (ht "hi") 123)
    (ht "hi"))
123

hash-table (the function) parallels the functions vector, list, and string. Its arguments are conses containing key/value pairs. The result is a new hash-table with those values preinstalled: (hash-table '("hi" . 32) '("ho" . 1)). After much use, I now think it is more convenient here, as in inlet, to use hash-table*; its arguments are simply the keys and values, without the consing: (hash-table* 'a 1 'b 2). Implicit indexing gives multilevel hashes:

> (let ((h (hash-table* 'a (hash-table* 'b 2 'c 3)))) (h 'a 'b))
2
> (let ((h (hash-table* 'a (hash-table* 'b 2 'c 3)))) (set! (h 'a 'b) 4) (h 'a 'b))
4

Since hash-tables accept the same applicable-object syntax that vectors use, we can treat a hash-table as, for example, a sparse array:

> (define make-sparse-array make-hash-table)
make-sparse-array
> (let ((arr (make-sparse-array)))
   (set! (arr 1032) "1032")
   (set! (arr -23) "-23")
   (list (arr 1032) (arr -23)))
("1032" "-23")

map and for-each accept hash-table arguments. On each iteration, the map or for-each function is passed an entry, '(key . value), in whatever order the entries are encountered in the table.

(define (hash-table->alist table)
  (map values table))

(define (merge-hash-tables . tables) ; probably faster: (define merge-hash-tables append)
  (apply hash-table 
    (apply append 
      (map hash-table->alist tables))))

reverse of a hash-table returns a new table with the keys and values reversed. fill! sets all the values. Two hash-tables are equal if they have the same keys with the same values. This is independent of the table sizes, or the order in which the key/value pairs were added.

The third argument to make-hash-table (eq-func) is slightly complicated. If it is omitted, s7 chooses the hashing equality and mapping functions based on the keys in the hash-table. There are times when you know in advance what equality function you want. If it's one of the built-in s7 equality functions, eq?, eqv?, equal?, morally-equal?, =, string=?, string-ci=?, char=?, or char-ci=?, you can pass that function as the third argument. In any other case, you need to give s7 both the equality function and the mapping function. The latter takes any object and returns the hash-table location for it (an integer). The problem here is that for the arbitrary equality function to work, objects that are equal according to that function have to be mapped to the same hash-table location. There's no way for s7 to intuit what this mapping should be except in the built-in cases. So to specify some arbitrary function, the third argument is a cons: '(equality-checker mapper).

Here's a brief example. In CLM, we have c-objects of type mus-generator (from s7's point of view), and we want to hash them using equal? (which will call the generator-specific equality function). But s7 doesn't realize that the mus-generator type covers 40 or 50 internal types, so as the mapper we pass mus-type: (make-hash-table 64 (cons equal? mus-type)).

If the hash key is a float (a non-rational number), hash-table-ref uses morally-equal?. Otherwise, for example, you could use NaN as a key, but then never be able to access it!

(define-macro (define-memoized name&arg . body)
  (let ((arg (cadr name&arg))
	(memo (gensym "memo")))
    `(define ,(car name&arg)
       (let ((,memo (make-hash-table)))
	 (lambda (,arg)
	   (or (,memo ,arg)                             ; check for saved value
	       (set! (,memo ,arg) (begin ,@body)))))))) ; set! returns the new value

> (define (fib n) 
  (if (< n 2) n (+ (fib (- n 1)) (fib (- n 2)))))
fib
> (define-memoized 
   (memo-fib n) 
     (if (< n 2) n (+ (memo-fib (- n 1)) (memo-fib (- n 2)))))
memo-fib
> (time (fib 34))         ; un-memoized time
1.168                        ;   0.70 on ccrma's i7-3930 machines
> (time (memo-fib 34))    ; memoized time
3.200e-05
> (outlet (funclet memo-fib))
(inlet '{memo}-18 (hash-table 
    '(0 . 0) '(1 . 1) '(2 . 1) '(3 . 2) '(4 . 3) '(5 . 5) 
    '(6 . 8) '(7 . 13) '(8 . 21) '(9 . 34) '(10 . 55) '(11 . 89) 
    '(12 . 144) '(13 . 233) '(14 . 377) '(15 . 610) '(16 . 987) 
    '(17 . 1597) '(18 . 2584) '(19 . 4181) '(20 . 6765) '(21 . 10946) 
    '(22 . 17711) '(23 . 28657) '(24 . 46368) '(25 . 75025) '(26 . 121393) 
    '(27 . 196418) '(28 . 317811) '(29 . 514229) '(30 . 832040) '(31 . 1346269) 
    '(32 . 2178309) '(33 . 3524578) '(34 . 5702887)))

environments

An environment holds symbols and their values. The global environment, for example, holds all the variables that are defined at the top level. Environments are first class (and applicable) objects in s7.

(rootlet)               the top-level (global) environment
(curlet)                the current (innermost) environment
(funclet proc)          the environment at the time when proc was defined
(owlet)                 the environment at the point of the last error
(unlet)                 the current environment, but all built-in functions have their original values

(let-ref env sym)       get value of sym in env, same as (env sym)
(let-set! env sym val)

(inlet . bindings)       make a new environment with the given bindings
(sublet env . bindings)  same as inlet, but the new environment is local to env
(varlet env . bindings)  add new bindings directly to env
(cutlet env . fields)    remove bindings from env

(let? obj)               #t if obj is an environment
(with-let env . body)    evaluate body in the environment env 
(outlet env)             the environment that encloses the environment env (settable)
(let->list env)          return the environment bindings as a list of (symbol . value) cons's

(openlet env)            mark env as open (see below)
(openlet? env)           #t is env is open
(coverlet env)           mark env as closed (undo an earlier openlet)

> (inlet 'a 1 'b 2)
(inlet 'a 1 'b 2)
> (let ((a 1) (b 2)) (curlet))
(inlet 'a 1 'b 2)
> (let ((x (inlet :a 1 :b 2))) (x 'a))
1
> (with-let (inlet 'a 1 'b 2) (+ a b))
3
> (let ((x (inlet :a 1 :b 2))) (set! (x 'a) 4) x)
(inlet 'a 4 'b 2)
> (let ((x (inlet))) (varlet x 'a 1) x)
(inlet 'a 1)
> (let ((a 1)) (let ((b 2)) (outlet (curlet))))
(inlet 'a 1)
> (let ((e (inlet 'a (inlet 'b 1 'c 2)))) (e 'a 'b)) ; in C terms, e->a->b 
1  
> (let ((e (inlet 'a (inlet 'b 1 'c 2)))) (set! (e 'a 'b) 3) (e 'a 'b))
3  

As the names suggest, in s7 an environment is viewed as a disembodied let. Environments are equal if they contain the same symbols with the same values leaving aside shadowing, and taking into account the environment chain up to the rootlet. That is, two environments are equal if any local variable of either has the same value in both.

with-let evaluates its body in the given environment, so (with-let e . body) is equivalent to (eval `(begin ,@body) e), but probably faster. Similarly, (let bindings . body) is equivalent to (eval `(begin ,@body) (apply inlet (flatten bindings))), ignoring the outer (enclosing) environment (the default outer environment of inlet is rootlet). Or better,

(define-macro (with-environs e . body) 
  `(apply let (map (lambda (a) (list (car a) (cdr a))) ,e) '(,@body)))

Or turning it around,

(define-macro (Let vars . body)
  `(with-let (sublet (curlet) 
	       ,@(map (lambda (var)
			(values (symbol->keyword (car var)) (cadr var)))
		      vars))
     ,@body))

(Let ((c 4))
  (Let ((a 2)
        (b (+ c 2)))
  (+ a b c)))

sublet adds bindings (symbols with associated values) to an environment. It does not change the environment passed to it, but just prepends the new bindings, shadowing any old ones, as if you had called "let". To add the bindings directly to the environment, use varlet. Both of these functions accept nil as the 'env' argument as shorthand for (rootlet). Both also accept other environments as well as individual bindings, adding all the argument's bindings to the new environment. inlet is very similar, but normally omits the environment argument. The arguments to sublet and inlet can be passed as symbol/value pairs, as a cons, or using keywords as if in define*. inlet can also be used to copy an environment without accidentally invoking that environment's copy method.

One way to add reader and writer functions to an individual environment slot is:

(define e (inlet 
            'x (let ((local-x 3)) ; x's initial value
		 (dilambda
		   (lambda () local-x)
		   (lambda (val) (set! local-x (max 0 (min val 100))))))))
> ((e 'x))
3
> (set! ((e 'x)) 123)
100

I originally used a bunch of foolishly pompous names for the environment functions. Two are still available for backwards compatibility:

rootlet      global-environment
curlet       current-environment

It is possible in Scheme to redefine built-in functions such as car. To ensure that some code sees the original built-in function definitions, wrap it in (with-let (unlet) ...):

> (let ((caar 123)) 
    (+ caar (with-let (unlet) 
              (caar '((2) 3)))))
125

with-let and unlet are constants, so you can use them in any context without worrying about whether they've been redefined. As mentioned in the macro section, #_<name> is a built-in reader macro for (with-let (unlet) <name>), so for example, #_+ is the built-in + function, no matter what. (unlet) cleans up the current environment whenever it's called, so you can use it to revert the REPL.

I think these functions can implement the notions of libraries, separate namespaces, or modules. Here's one way: first the library writer just writes his library. The normal user simply loads it. The abnormal user worries about everything, so first he loads the library in a local let to make sure no bindings escape to pollute his code, and then he uses unlet to make sure that none of his bindings pollute the library code:

(let ()
  (with-let (unlet)
    (load "any-library.scm" (curlet)) 
    ;; by default load puts stuff in the global environment
    ...))

Now Abnormal User can do what he wants with the library entities. Say he wants to use "lognor" under the name "bitwise-not-or", and all the other functions are of no interest:

(varlet (curlet)
  'bitwise-not-or (with-let (unlet)
                    (load "any-library.scm" (curlet))
                    lognor)) ; lognor is presumably defined in "any-library.scm"

Say he wants to make sure the library is cleanly loaded, but all its top-level bindings are imported into the current environment:

(varlet (curlet)
  (with-let (unlet)
    (let ()
      (load "any-library.scm" (curlet))
      (curlet)))) ; these are the bindings introduced by loading the library

To do the same thing, but prepend "library:" to each name:

(apply varlet (curlet)
  (with-let (unlet)
    (let ()
      (load "any-library.scm" (curlet))
      (map (lambda (binding)
	     (cons (string->symbol 
		    (string-append "library:" (symbol->string (car binding))))
		   (cdr binding)))
	    (curlet)))))

That's all there is to it! Here is the same idea as a macro:

(define-macro (let! init end . body)
  ;; syntax mimics 'do: (let! (vars&values) ((exported-names) result) body)
  ;;   (let! ((a 1)) ((hiho)) (define (hiho x) (+ a x)))
  `(let ,init
     ,@body
     (varlet (outlet (curlet))
       ,@(map (lambda (export)
		`(cons ',export ,export))
	      (car end)))
     ,@(cdr end)))

Well, almost, darn it. If the loaded library file sets (via set!) a global value such as abs, we need to put it back to its original form:

(define (safe-load file)
  (let ((e (with-let (unlet)         ; save the environment before loading
	     (let->list (curlet)))))
    (load file (curlet))
    (let ((new-e (with-let (unlet)   ; get the environment after loading
		   (let->list (curlet)))))
      (for-each                       ; see if any built-in functions were stepped on
       (lambda (sym)
	 (unless (assoc (car sym) e)
	   (format #t "~S clobbered ~A~%" file (car sym))
	   (apply set! (car sym) (list (cdr (assoc (car sym) new-e))))))
       new-e))))

;; say libtest.scm has the line (set! abs odd?)

> (safe-load "libtest.scm")
"libtest.scm" clobbered abs
> (abs -2)
2

s7test.scm has two more versions of this idea: local-let and protected-let. They restore values of both global variables and outlet variables when the let (actually dynamic-wind) exits.

openlet marks its argument, either an environment, a closure, or a c-object as open. I need better terminology here! An open object is one that the built-in s7 functions handle specially. If they encounter one in their argument list, they look in the object for their own name, and call that function if it exists. A bare-bones example:

> (abs (openlet (inlet 'abs (lambda (x) 47))))
47
> (define* (f1 (a 1)) (if (real? a) (abs a) ((a 'f1) a)))
f1
> (f1 :a (openlet (inlet 'f1 (lambda (e) 47))))
47

In CLOS, we'd declare a class and a method, and call make-instance, and then discover that it wouldn't work anyway. Here we have, in effect, an anonymous instance of an anonymous class. A slightly more complex example:

(let ((e1 (openlet 
	   (inlet 
	    'x 3
	    '* (lambda args
		 (if (number? (car args))
		     (apply * (car args) ((cadr args) 'x) (cddr args))
		     (apply * ((car args) 'x) (cdr args))))))))
  (let ((e2 (copy e1)))
    (set! (e2 'x) 4)
    (* 2 e1 e2))) ; (* 2 3 4) => 24

Perhaps these names would be better: openlet -> with-methods, coverlet -> without-methods, and openlet? -> methods?.

define-class

Here is yet another object system. Each class and each instance is an environment. A class might be thought of as a template for instances, but there's actually no difference between them. To make an instance of a class, copy it. To inherit from another class, concatenate the environments. To access (get or set) a field or a method, use the implicit indexing syntax with the field or method name. To evaluate a form in the context of an instance (CL's with-slots), use with-let. To run through all the fields, use map or for-each.

(define-macro* (define-class class-name inherited-classes (slots ()) (methods ()))
  `(let ((outer-env (outlet (curlet)))
	 (new-methods ())
	 (new-slots ()))
     
     (for-each
      (lambda (class)
	;; each class is a set of nested environments, the innermost (first in the list)
	;;   holds the local slots which are copied each time an instance is created,
	;;   the next holds the class slots (global to all instances, not copied);
	;;   these hold the class name and other such info.  The remaining environments
	;;   hold the methods, with the localmost method first.  So in this loop, we
	;;   are gathering the local slots and all the methods of the inherited
	;;   classes, and will splice them together below as a new class.
	
	(set! new-slots (append (let->list class) new-slots))
	(do ((e (outlet (outlet class)) (outlet e)))
	    ((or (not (let? e))
		 (eq? e (rootlet))))
	  (set! new-methods (append (let->list e) new-methods))))
      ,inherited-classes)
     
     (let ((remove-duplicates 
	    (lambda (lst)         ; if multiple local slots with same name, take the localmost
	      (letrec ((rem-dup
			(lambda (lst nlst)
			  (cond ((null? lst) nlst)
				((assq (caar lst) nlst) (rem-dup (cdr lst) nlst))
				(else (rem-dup (cdr lst) (cons (car lst) nlst)))))))
		(reverse (rem-dup lst ()))))))
       (set! new-slots 
	     (remove-duplicates
	      (append (map (lambda (slot)
			     (if (pair? slot)
				 (cons (car slot) (cadr slot))
				 (cons slot #f)))
			   ,slots)                    ; the incoming new slots, #f is the default value
		      new-slots))))                   ; the inherited slots
     
     (set! new-methods 
	   (append (map (lambda (method)
			  (if (pair? method)
			      (cons (car method) (cadr method))
			      (cons method #f)))
			,methods)                     ; the incoming new methods
		   
		   ;; add an object->string method for this class (this is already a generic function).
		   (list (cons 'object->string 
			       (lambda* (obj (use-write #t))
				 (if (eq? use-write :readable)    ; write readably
				     (format #f "(make-~A~{ :~A ~W~^~})" 
					     ',class-name 
					     (map (lambda (slot)
						    (values (car slot) (cdr slot)))
						  obj))
				     (format #f "#<~A: ~{~A~^ ~}>" 
					     ',class-name
					     (map (lambda (slot)
						    (list (car slot) (cdr slot)))
						  obj))))))
		   (reverse! new-methods)))                      ; the inherited methods, shadowed automatically
     
     (let ((new-class (openlet
                       (apply sublet                             ; the local slots
			      (sublet                            ; the global slots
				  (apply inlet                   ; the methods
					 (reverse new-methods))
				'class-name ',class-name         ; class-name slot
				'inherited ,inherited-classes
				'inheritors ())                  ; classes that inherit from this class
			      new-slots))))
       
       (varlet outer-env                  
	 ',class-name new-class                                  ; define the class as class-name in the calling environment
	 
	 ;; define class-name? type check
	 (string->symbol (string-append (symbol->string ',class-name) "?"))
	 (lambda (obj)
	   (and (let? obj)
		(eq? (obj 'class-name) ',class-name))))
       
       (varlet outer-env
	 ;; define the make-instance function for this class.  
	 ;;   Each slot is a keyword argument to the make function.
	 (string->symbol (string-append "make-" (symbol->string ',class-name)))
	 (apply lambda* (map (lambda (slot)
			       (if (pair? slot)
				   (list (car slot) (cdr slot))
				   (list slot #f)))
			     new-slots)
		`((let ((new-obj (copy ,,class-name)))
		    ,@(map (lambda (slot)
			     `(set! (new-obj ',(car slot)) ,(car slot)))
			   new-slots)
		    new-obj))))
       
       ;; save inheritance info for this class for subsequent define-method
       (letrec ((add-inheritor (lambda (class)
				 (for-each add-inheritor (class 'inherited))
				 (if (not (memq new-class (class 'inheritors)))
				     (set! (class 'inheritors) (cons new-class (class 'inheritors)))))))
	 (for-each add-inheritor ,inherited-classes))
       
       ',class-name)))

(define-macro (define-generic name)    ; (define (genfun any) ((any 'genfun) any))
  `(define ,name 
     (lambda args 
       (let ((gf ((car args) ',name))) ; get local definition
	 (if (not (eq? gf ,name))      ; avoid infinite recursion
             (apply gf args)
	     (error "attempt to call generic function wrapper recursively"))))))

(define-macro (define-slot-accessor name slot)
  `(define ,name (dilambda 
		  (lambda (obj) (obj ',slot)) 
		  (lambda (obj val) (set! (obj ',slot) val)))))

(define-macro (define-method name-and-args . body)
  `(let* ((outer-env (outlet (curlet)))
	  (method-name (car ',name-and-args))
	  (method-args (cdr ',name-and-args))
	  (object (caar method-args))
	  (class (symbol->value (cadar method-args)))
	  (old-method (class method-name))
	  (method (apply lambda* method-args ',body)))
     
     ;; define the method as a normal-looking function
     ;;   s7test.scm has define-method-with-next-method that implements call-next-method here
     ;;   it also has make-instance 
     (varlet outer-env
       method-name (apply lambda* method-args 
			  `(((,object ',method-name)
			     ,@(map (lambda (arg)
				      (if (pair? arg) (car arg) arg))
				    method-args)))))
     
     ;; add the method to the class
     (varlet (outlet (outlet class)) method-name method)
     
     ;; if there are inheritors, add it to them as well, but not if they have a shadowing version
     (for-each
      (lambda (inheritor) 
	(if (not (eq? (inheritor method-name) #<undefined>)) ; defined? goes to the global env
	    (if (eq? (inheritor method-name) old-method)
		(set! (inheritor method-name) method))
	    (varlet (outlet (outlet inheritor)) method-name method)))
      (class 'inheritors))
     
     method-name))

(define (all-methods obj method)
  ;; for arbitrary method combinations: this returns a list of all the methods of a given name
  ;;   in obj's class and the classes it inherits from (see example below)
  (let* ((base-method (obj method))
	 (methods (if (procedure? base-method) (list base-method) ())))
    (for-each 
     (lambda (ancestor)
       (let ((next-method (ancestor method)))
	 (if (and (procedure? next-method)
		  (not (memq next-method methods)))
	     (set! methods (cons next-method methods)))))
     (obj 'inherited))
    (reverse methods)))


> (define-class class-1 () 
       '((a 1) (b 2)) 
       (list (list 'add (lambda (obj) 
                          (with-let obj
                            (+ a b))))))
class-1
> (define v (make-class-1 :a 32))
v 
> (v 'a)                         ; to set the 'a slot, (set! (v 'a) 0) 
32
> (object->string v)             ; built-in functions are all generic
"#<class-1: (a 32) (b 2)>"       ;   so this uses the method defined in the class definition
> ((v 'add) v)
34
> (define-generic add)
add
> (add v)                        ; syntactic sugar for ((v 'add) v)
34
> (define-slot-accessor slot-a a) ; more sugar!
slot-a
> (slot-a v)                     ; same as (v 'a), set via (set! (slot-a v) 123)
32
> (map car v)                    ; map and for-each work with environments
(a b)                               ;   map cdr would return '(32 2) in this case
> (define-class class-2 (list class-1)
       '((c 3)) 
       (list (list 'multiply (lambda (obj) 
                               (with-let obj 
                                 (* a b c))))))
class-2
> (define v2 (make-class-2 :a 32))
v2
> v2                            ; will use object->string
"#<class-2: (c 3) (a 32) (b 2)>"
> ((v2 'multiply) v2)
192
> (add v2)                      ; inherited from class-1
34
> (define-method (subtract (obj class-1)) (with-let obj (- a b)))
subtract
> (subtract v2)  ; class-2 inherits from class-1 so it knows about subtract
30
> (define v1 (make-class-1))
v1
> (varlet v1      ; change the add method just in this instance
       'add (lambda (obj) 
              (with-let obj
                (+ 1 a (* 2 b)))))
#<class-1: (a 1) (b 2) (add #<lambda (obj)>)>
> (add v1)
6
> (add v)                       ; other class-1 instances are not affected
34
> (define-class class-3 (list class-2) () 
    (list (list 'multiply (lambda (obj num) 
			    (* num 
			       ((class-2 'multiply) obj) ; method combination 
			       (add obj))))))
class-3
> ((class-3 'multiply) class-3 10)
180                               ; (* 10 (* 1 2 3) (+ 1 2))
> (define v3 (make-class-3))
v3
> (all-methods v3 'multiply)
(#<lambda (obj num)> #<lambda (obj)>)
> (for-each (lambda (p) (format #t "~A~%" (procedure-source p))) (all-methods v3 'multiply))
(lambda (obj num) (* num ((class-2 'multiply) obj) (add obj)))
(lambda (obj) (with-let obj (* a b c)))

with-let (used briefly above) provides an even more striking simplification of syntax than implicit indexing or multidimensional vectors, and it is faster as well! See Snd's generators.scm for many examples.

more examples

Implicit indexing of a local environment does not search the global environment. Since unlet extends the current environment chain, it is considered a local environment:

> ((rootlet) 'abs)
abs
> (let () ((curlet) 'abs))
#<undefined>
> ((unlet) 'abs)
#<undefined>
(define-macro (value->symbol expr)
  `(let ((val ,expr)
	 (e1 (curlet)))
     (call-with-exit
      (lambda (return)
	(do ((e e1 (outlet e))) ()
	  (for-each 
	   (lambda (slot)
	     (if (equal? val (cdr slot))
		 (return (car slot))))
	   e)
	  (if (eq? e (rootlet))
	      (return #f)))))))

> (let ((a 1) (b "hi")) 
    (value->symbol "hi"))
b

openlet alerts the rest of s7 that the environment has methods.

(begin
  (define fvector? #f)
  (define make-fvector #f)
  (let ((type (gensym))
	(->float (lambda (x)
		   (if (real? x)
		       (* x 1.0)
		       (error 'wrong-type-arg "fvector new value is not a real: ~A" x)))))
    (set! make-fvector
	  (lambda* (len (init 0.0)) 
	    (openlet
	     (inlet :v (make-vector len (->float init))
	            :type type
	   	    :length (lambda (f) len)
		    :object->string (lambda (f . args) "#<fvector>")
		    :let-set! (lambda (fv i val) (#_vector-set! (fv 'v) i (->float val)))
		    :let-ref (lambda (fv i) (#_vector-ref (fv 'v) i))))))
    (set! fvector? (lambda (p)
		     (and (let? p)
			  (eq? (p 'type) type))))))
  
> (define fv (make-fvector 32))
fv
> fv
#<fvector>
> (length fv)
32
> (set! (fv 0) 123)
123.0
> (fv 0)
123.0

I can't resist adding at least some of a quaternion implementation (finally "number?" is not the same as "complex?"!):

(define-class quaternion () 
  '((r 0) (i 0) (j 0) (k 0))
  (list (list 'number? (lambda (obj) #t))
	(list 'complex? (lambda (obj) #f))
	(list 'real? (lambda (obj) #f))
	(list 'integer? (lambda (obj) #f))
	(list 'rational? (lambda (obj) #f))

	(list '+ (lambda orig-args
		   (let add ((r ()) (i ()) (j ()) (k ()) (args orig-args))
		     (if (null? args)
			 (make-quaternion 
                           (apply + r) (apply + i) (apply + j) (apply + k)) 
			 (let ((n (car args)))
			   (cond
			    ((real? n)
			     (add (cons n r) i j k (cdr args)))
			    ((complex? n)
			     (add (cons (real-part n) r) (cons (imag-part n) i) j k (cdr args)))
			    ((quaternion? n)
			       (add (cons (n 'r) r) (cons (n 'i) i) 
                                    (cons (n 'j) j) (cons (n 'k) k) 
                                    (cdr args)))
			    ((openlet? n) ; maybe we'll add octonions later!
			     (if (eq? n (car orig-args))
				 (error 'missing-method "+ can't handle these arguments: ~A" args)
				 (apply (n '+) 
                                        (make-quaternion 
                                          (apply + r) (apply + i) (apply + j) (apply + k)) 
                                        (cdr args))))
			    (else (error 'wrong-type-arg "+ argument ~A is not a number" n))))))))
	))

> (let ((q1 (make-quaternion 1.0 1.0 0.0 0.0)))
    (+ 1 q1 2.5+i))
#<quaternion: (r 4.5) (i 2.0) (j 0.0) (k 0.0)>

If an s7 function ignores the type of an argument, as in cons or vector for example, then that argument won't be treated as having any methods.

Since outlet is settable, there are two ways an environment can become circular. One is to include the current environment as the value of one of its variables. The other is: (let () (set! (outlet (curlet)) (curlet))).

If you want to hide an environment's fields from any part of s7 that does not know the field names in advance,

(openlet  ; make it appear to be empty to the rest of s7
  (inlet 'object->string  (lambda args "#<let>")
         'map             (lambda args ())
         'for-each        (lambda args #<unspecified>)
  	 'let->list       (lambda args ())
         'length          (lambda args 0)
	 'copy            (lambda args (inlet))
 	 'open #t
	 'coverlet        (lambda (e) (set! (e 'open) #f) e)
	 'openlet         (lambda (e) (set! (e 'open) #t) e)
	 'openlet?        (lambda (e) (e 'open))
         ;; your secret data here
         ))

(There are still at least two ways to tell that something is fishy).

multiple-values

In s7, multiple values are spliced directly into the caller's argument list.

> (+ (values 1 2 3) 4)
10
> (string-ref ((lambda () (values "abcd" 2))))
#\c
> ((lambda (a b) (+ a b)) ((lambda () (values 1 2))))
3
> (+ (call/cc (lambda (ret) (ret 1 2 3))) 4) ; call/cc has an implicit "values"
10
> ((lambda* ((a 1) (b 2)) (list a b)) (values :a 3))
(3 2)

(define-macro (call-with-values producer consumer) 
  `(,consumer (,producer)))

(define-macro (multiple-value-bind vars expr . body)
  `((lambda ,vars ,@body) ,expr))

(define (curry function . args)
  (if (null? args)
      function
      (lambda more-args
        (if (null? more-args)
            (apply function args)
            (function (apply values args) (apply values more-args))))))

There aren't that many real uses for multiple-values in Scheme. Nearly all can be replaced by a normal list. There are a few cases where multiple-values are handy. First, you can use "values" to return any number of values, including 0, from map's function application:

> (map (lambda (x) (if (odd? x) (values x (* x 20)) (values))) (list 1 2 3))
(1 20 3 60)
> (map values (list 1 2 3) (list 4 5 6))
(1 4 2 5 3 6)

(define (remove-if func lst) 
  (map (lambda (x) (if (func x) (values) x)) lst))

(define (pick-mappings func lst)          
  (map (lambda (x) (or (func x) (values))) lst))

(define (shuffle . args) 
  (apply map values args))

> (shuffle '(1 2 3) #(4 5 6) '(7 8 9))
(1 4 7 2 5 8 3 6 9)

(define (concatenate . args)
  (apply append (map (lambda (arg) (map values arg)) args)))

Second, you can use multiple-values to turn off the short-circuit evaluation of 'or' and 'and'.

> (let ((x 1)) (and (values #f (let () (set! x 3) #f))) x)
3

But 'apply' has the same effect and is easier to read:

(define (and? . args) (apply and args))
(define (every? f . seqs) (apply and (apply map f seqs)))

More often you want to keep the short-circuiting, but add some action as 'and' or 'or' marches through its arguments:

(define-macro (every? function . args)
  `(and ,@(map (lambda (arg) `(,function ,arg)) args)))

(define (map-and proc lst) 
  (or (null? lst) 
      (and (proc (car lst)) 
           (map-and proc (cdr lst)))))

(define-macro (and-let* vars . body)
  `(let () ;; bind vars, if any is #f stop, else evaluate body with those bindings
     (and ,@(map (lambda (var) `(begin (apply define ',var) ,(car var))) vars) 
          (begin ,@body))))

Third, a macro can return multiple values; these are evaluated and spliced, exactly like a normal macro, so you can use (values '(define a 1) '(define b 2)) to splice multiple definitions at the macro invocation point. If an expansion returns (values), nothing is spliced in. This is mostly useful in reader-cond.

> (define-expansion (comment str) (values))
comment
> (+ 1 (comment "one") 2 (comment "two"))
3

At the top-level (in the REPL), since there's nothing to splice into, you simply get your values back:

> (values 1 (list 1 2) (+ 3 4 5))
(values 1 (1 2) 12)

But this printout is just trying to be informative. There is no multiple-values object in s7. You can't (set! x (values 1 2)), for example. The values function tells s7 that its arguments should be handled in a special way, and the multiple-value indication goes away as soon as the arguments are spliced into some caller's arguments.

Internally, s7 uses (apply values ...) to implement unquote splicing (",@") in quasiquote.

Since set! does not evaluate its first argument, and there is no setter for "values", (set! (values x) ...) is not the same as (set! x ...). (string-set! (values string) ...) works because string-set! does evaluate its first argument. ((values + 1 2) (values 3 4) 5) is 15, as anyone would expect.

more on values

In some Schemes, values behaves like CL's prog1:

(not s7)> (let ((x 1)) (cond ((values #f (set! x 2) #t) 3) (#t x)))
2
(not s7)> (if (values #f #t) 1 2)
2

But in s7 we're trying to implement real multiple values (else why have them at all?). There are many ways we could interpret (cond ((values ...))...) and (cond ((values...) => func)), but surely equivalent uses of "cond" and "if" should give the same result. Currently in s7, where a test is in progress, only (values #f) is the same as #f.

> (if (values #f #f) 1 2)            ; (values #f #f) is not #f
1
> (cond ((values #f #f) 1) (#t 2))
1
;;; but if we interpreted this as splicing in the values, we get an inconsistency:
> (cond (#f #f 1) (#t 2))
2
> (if (values #f) 1 2)
2
> (cond ((values #f) 1) (#t 2))
2
> (if (values) 1 2)
1
> (cond ((values) 1) (#t 2))
1
;;; this is consistent with (cond (1) (#t 2))

So "if" and "cond" agree, but it requires that in one case the "values" behavior is slightly weird. (or (values #f #f)) is #f, but that isn't inconsistent because "or" is not testing anything. We might choose to say that (if (values #f #f)...) is an error, but that would be hasty — our troubles have only begun. First, "cond" can omit the expressions that follow the test, unlike "if":

> (cond (3))
3

and even trickier, "cond" can pass the test value to a function:

> (cond (3 => +))
3

The various standards agree that in the "=>" case, the "fed to" function receives one argument, so

(not s7)> (cond ((values 1 2) => +))
1

If we were following the "splice immediately" model, this would be (cond (1 2 => +)) which is an error in some Schemes. So something has to give. My druthers is to make "values" work as consistently as possible, and hope that the one odd corner will not trip anyone. From that point of view, the "one arg" standard looks like a wasted opportunity. s7 handles it this way:

> (+ 1 (cond ((values 2 3))) 4)   ; trailing values are not ignored
10
> (cond ((values 1 2 3) => +))
6

Of course, it is unproblematic that the expression can itself involve multiple values:

> (+ (cond (#t (values 1 2))))
3

Now, what have I missed?

call-with-exit, with-baffle and continuation?

call-with-exit is call/cc without the ability to jump back into the original context, similar to "return" in C. This is cleaner than call/cc, and much faster.

(define-macro (block . body) 
  ;; borrowed loosely from CL — predefine "return" as an escape
  `(call-with-exit (lambda (return) ,@body)))

(define-macro (while test . body)         ; while loop with predefined break and continue
  `(call-with-exit
    (lambda (break) 
      (letrec ((continue (lambda () 
			   (if (let () ,test)
			       (begin 
				 (let () ,@body)
				 (continue))
			       (break)))))
	(continue)))))

(define-macro (switch selector . clauses) ; C-style case (branches fall through unless break called)
  `(call-with-exit
    (lambda (break)
      (case ,selector
	,@(do ((clause clauses (cdr clause))
	       (new-clauses ()))
	      ((null? clause) (reverse new-clauses))
	    (set! new-clauses (cons `(,(caar clause) 
				      ,@(cdar clause)
				      ,@(map (lambda (nc)
					       (apply values (cdr nc))) ; doubly spliced!
					     (if (pair? clause) (cdr clause) ())))
				    new-clauses)))))))

(define (and-for-each func . args)
  ;; apply func to the first member of each arg, stopping if it returns #f
  (call-with-exit
   (lambda (quit)
     (apply for-each (lambda arglist
		       (if (not (apply func arglist))
			   (quit #<unspecified>))) 
	    args))))

(define (find-if f . args)  ; generic position-if is very similar
  (call-with-exit
   (lambda (return) 
     (apply for-each (lambda main-args 
		       (if (apply f main-args) 
			   (apply return main-args)))
	    args))))

> (find-if even? #(1 3 5 2))
2
> (* (find-if > #(1 3 5 2) '(2 2 2 3)))
6

The call-with-exit function's argument (the "continuation") is only valid within the call-with-exit function. In call/cc, you can save it, then call it later to jump back, but if you try that with call-with-exit (from outside the call-with-exit function's body), you'll get an error. This is similar to trying to read from a closed input port.

The other side, so to speak, of call-with-exit, is with-baffle. Both limit the scope of a continuation. Sometimes we need a normal call/cc, but want to make sure it is active only within a given block of code. Normally, if a continuation gets away, there's no telling when it might wreak havoc on us. Scheme code with call/cc becomes unpredictable, undebuggable, and completely unmaintainable. with-baffle blocks all that — no continuation can jump into its body:

(let ((what's-for-breakfast ())
      (bad-dog 'fido))        ; bad-dog wonders what's for breakfast?
  (with-baffle                ; the syntax is (with-baffle . body)         
   (set! what's-for-breakfast
	 (call/cc
	  (lambda (biscuit?)
	    (set! bad-dog biscuit?) ; bad-dog smells a biscuit!
	    (biscuit? 'biscuit!)))))
  (if (eq? what's-for-breakfast 'biscuit!) 
      (bad-dog 'biscuit!))     ; now, outside the baffled block, bad-dog wants that biscuit!
  what's-for-breakfast)        ;   but s7 says "No!": baffled! ("continuation can't jump into with-baffle")

continuation? returns #t if its argument is a continuation, as opposed to a normal procedure. I don't know why Scheme hasn't had this function from the very beginning, but it's needed if you want to write a continuable error handler. Here is a sketch of the situation:

(let ()
  (catch #t
	 (lambda ()
	   (let ((res (call/cc 
                        (lambda (ok) 
			  (error 'cerror "an error" ok)))))
	     (display res) (newline)))
	 (lambda args
	   (if (and (eq? (car args) 'cerror)
		    (continuation? (cadadr args)))
	       (begin
		 (display "continuing...")
		 ((cadadr args) 2)))
	   (display "oops"))))

continuing...2

In a more general case, the error handler is separate from the catch body, and needs a way to distinguish a real continuation from a simple procedure.

(define (continuable-error . args)
  (call/cc 
   (lambda (continue)
     (apply error args))))

(define (continue-from-error)
  (if (continuation? ((owlet) 'continue)) ; might be #<undefined> or a function as in the while macro
      (((owlet) 'continue))
      'bummer))

format, object->string

object->string returns the string representation of its argument. Its optional second argument can be #f (use display), #t (the default, use write), or :readable. In the latter case, object->string tries to produce a string that can be evaluated via eval-string to return an object equal to the original.

> (object->string "hiho")
"\"hiho\""
> (format #f "~S" "hiho")
"\"hiho\""

s7's format function is very close to that in srfi-48.

> (format #f "~A ~D ~F" 'hi 123 3.14)
"hi 123 3.140000"

The format directives (tilde chars) are:

~%        insert newline
~&        insert newline if preceding char was not newline
~~        insert tilde
~\n       (tilde followed by newline): trim white space
~{        begin iteration (take arguments from a list, string, vector, or any other applicable object)
~}        end iteration
~^ ~|     jump out of iteration
~*        ignore the current argument
~C        print character (numeric argument = how many times to print it)
~P        insert 's' if current argument is not 1 or 1.0 (use ~@P for "ies" or "y")
~A        object->string as in display
~S        object->string as in write
~B        number->string in base 2
~O        number->string in base 8
~D        number->string in base 10
~X        number->string in base 16
~E        float to string, (format #f "~E" 100.1) -> "1.001000e+02", (%e in C)
~F        float to string, (format #f "~F" 100.1) -> "100.100000",   (%f in C)
~G        float to string, (format #f "~G" 100.1) -> "100.1",        (%g in C)
~T        insert spaces (padding)
~N        get numeric argument from argument list (similar to V in CL)
~W        object->string with :readable (write readably; s7 is the intended reader)

The eight directives before ~W take the usual numeric arguments to specify field width and precision. These can also be ~N or ~n in which case the numeric argument is read from the list of arguments:

(format #f "~ND" 20 1234) ; => (format "~20D" 1234)
"                1234"

(format #f ...) simply returns the formatted string; (format #t ...) also sends the string to the current-output-port. (format () ...) sends the output to the current-output-port without returning the string (this mimics the other IO routines such as display and newline). Other built-in port choices are *stdout* and *stderr*.

Floats can occur in any base, so:

> #xf.c
15.75

This also affects format. In most Schemes, (format #f "~X" 1.25) is an error. In CL, it is equivalent to using ~A which is perverse. But

> (number->string 1.25 16)
"1.4"

and there's no obvious way to get the same effect from format unless we accept floats in the "~X" case. So in s7,

> (format #f "~X" 21)
"15"
> (format #f "~X" 1.25)
"1.4"
> (format #f "~X" 1.25+i)
"1.4+1.0i"
> (format #f "~X" 21/4)
"15/4"

That is, the output choice matches the argument. A case that came up in the Guile mailing lists is: (format #f "~F" 1/3). s7 currently returns "1/3", but Clisp returns "0.33333334".


The curly bracket directive applies to anything you can map over, not just lists:

> (format #f "~{~C~^ ~}" "hiho")
"h i h o"
> (format #f "~{~{~C~^ ~}~^...~}" (list "hiho" "test"))
"h i h o...t e s t"
> (with-input-from-string (format #f "(~{~C~^ ~})" (format #f "~B" 1367)) read) ; integer->list
(1 0 1 0 1 0 1 0 1 1 1)

Since any sequence can be passed to ~{~}, we need a way to truncate output and represent the rest of the sequence with "...", but ~^ only stops at the end of the sequence. ~| is like ~^ but it also stops after it handles (*s7* 'print-length) elements and prints "...". So, (format #f "~{~A~| ~}" #(0 1 2 3 4)) returns "0 1 2 ..." if (*s7* 'print-length) is 3.

I added object->string to s7 before deciding to include format. format excites a vague disquiet — why do we need this ancient unlispy thing? We can almost replace it with:

(define (objects->string . objects)
  (apply string-append (map (lambda (obj) (object->string obj #f)) objects)))

But how to handle lists (~{...~} in format), or columnized output (~T)? I wonder whether formatted string output still matters outside a REPL. Even in that context, a modern GUI leaves formatting decisions to a text or table widget.

(define-macro (string->objects str . objs)
  `(with-input-from-string ,str
     (lambda ()
       ,@(map (lambda (obj)
		`(set! ,obj (eval (read))))
	      objs))))

hooks

(make-hook . fields)           ; make a new hook
(hook-functions hook)          ; the hook's list of 'body' functions

A hook is a function created by make-hook, and called (normally from C) when something interesting happens. In GUI toolkits hooks are called callback-lists, in CL conditions, in other contexts watchpoints or signals. s7 itself has several hooks: *error-hook*, *unbound-variable-hook*, *missing-close-paren-hook*, and *load-hook*. make-hook is:

(define (make-hook . args)
  (let ((body ()))
    (apply lambda* args
      '(let ((result #<unspecified>))
         (let ((e (curlet)))
	   (for-each (lambda (f) (f e)) body) 
           result))
       ())))

So the result of calling make-hook is a function (the lambda* that is applied to args above) that contains a list of functions, 'body. Each function in that list takes one argument, the hook. Each time the hook itself is called, each of the body functions is called, and the value of 'result is returned. That variable, and each of the hook's arguments are accessible to the hook's internal functions by going through the environment passed to the internal functions. This is a bit circuitous; here's a sketch:

> (define h (make-hook '(a 32) 'b))     ; h is a function: (lambda* ((a 32) b) ...)
h
> (set! (hook-functions h)              ; this sets ((funclet h) 'body)
           (list (lambda (hook) 	; each hook internal function takes one argument, the environment
                   (set! (hook 'result) ; this is the "result" variable above 
                         (format #f "a: ~S, b: ~S" (hook 'a) (hook 'b))))))
(#<lambda (hook)>)
> (h 1 2)                               ; this calls the hook's internal functions (just one in this case)
"a: 1, b: 2"                            ; we set "result" to this string, so it is returned as the hook application result
> (h)
"a: 32, b: #f"

In C, to make a hook:

hook = s7_eval_c_string("(make-hook '(a 32) 'b)");
s7_gc_protect(s7, hook);

And call it:

result = s7_call(s7, hook, s7_list(s7, 2, s7_make_integer(s7, 1), s7_make_integer(s7, 2)));
(define-macro (hook . body)  ; return a new hook with "body" as its body, setting "result"
  `(let ((h (make-hook)))
     (set! (hook-functions h) (list (lambda (h) (set! (h 'result) (begin ,@body)))))
     h))

procedure info

(procedure-source proc)
(procedure-documentation proc)
(procedure-signature proc)
(procedure-setter proc)
(funclet proc)

(arity obj)
(aritable? obj num-args)

procedure-setter returns or sets the set function associated with a procedure (set-car! with car, for example). funclet returns a procedure's environment. procedure-source returns the procedure source (a list).

(define (procedure-arglist f) (cadr (procedure-source f)))

procedure-documentation returns the documentation string associated with a procedure. This used to be the initial string in the function's body (as in CL), but now it is the value of the 'documentation variable, if any, in the procedure's local environment. That is, (define (f a) "doc string" a) is now (define f (let ((documentation "doc string")) (lambda (a) a))). This change gets the string out of the body (where it can slow down evaluation of the function to no purpose), and makes it possible to extend the function information arbitrarily.

arity takes any object and returns either #f if it is not applicable, or a cons containing the minimum and maximum number of arguments acceptable. If the maximum reported is a really big number, that means any number of arguments is ok. aritable? takes two arguments, an object and an integer, and returns #t if the object can be applied to that many arguments.

> (define add-2 (let ((documentation "add-2 adds its 2 args")) (lambda* (a (b 32)) (+ a b))))
add-2
> (procedure-documentation add-2)
"add-2 adds its 2 args"
> (procedure-source add-2)
(lambda* (a (b 32)) (+ a b))
> (arity add-2)
(0 . 2)

procedure-signature is a list describing the argument types and returned value type of the function. The first entry in the list is the return type, and the rest are argument types. #t means any type is possible, and 'values means the function returns multiple values.

> (procedure-signature round)
(integer? real?) ; round takes a real argument, returns an integer
> (procedure-signature vector-ref)
(#t vector? . #1=(integer? . #1#)) ; trailing args are all integers (indices)

If an entry is a list, any of the listed types can occur:

> (procedure-signature char-position)
((boolean? integer?) (char? string?) string? integer?)

which says that the first argument to char-position can be a string or a character, and the return type can be either boolean or an integer. If the function is defined in scheme, its signature is the value of the 'signature variable in its closure:

> (define f1 (let ((documentation "helpful info") 
                   (signature '(boolean? real?))) 
                (lambda (x) 
                  (positive? x))))
f1
> (procedure-documentation f1)
"helpful info"
> (procedure-signature f1)
(boolean? real?)

We could do the same thing using methods:

> (define f1 (let ((procedure-documentation (lambda (f) "helpful info"))
                    (procedure-signature (lambda (f) '(boolean? real?))))
                (openlet
                  (lambda (x) 
                    (positive? x)))))
> (procedure-documentation f1)
"helpful info"
> (procedure-signature f1)
(boolean? real?)

openlet alerts s7 that f1 has methods.


examples

procedure-source returns the actual function source. If you call the function, the optimizer changes the source to suit itself, so if you want to walk over the function body or change it in some way, make a clean copy of the procedure-source first (using, for example, copy-tree in stuff.scm).

(define-bacro (procedure-annotate proc) ; use "bacro" so we can annotate local functions
  (let ((orig (procedure-source proc))) ; this assumes we haven't called "proc" yet

    (define (proc-walk source)
      (if (pair? source)
	  (if (memq (car source) '(let let*))     ; if let or let*, show local variables
	      (if (symbol? (cadr source))         ; named let?
		  ;; (let name vars . body) -> (let name vars print-vars . body)
		  (append 
		   (list (car source)
			 (cadr source)
			 (caddr source)
			 `(format #t "    (let ~A (~{~A~^ ~}) ...)~%" ,(cadr source) (curlet)))
		   (cdddr source))
		  ;; (let(*) vars . body) -> (let vars print-vars . body)
		  (append 
		   (list (car source)
			 (cadr source)
			 `(format #t "    (~A (~{~A~^ ~}) ...)~%" ,(car source) (curlet)))
		   (cddr source)))
	      (cons (proc-walk (car source))
		    (proc-walk (cdr source))))
	  source))
    
    (let* ((new-body (proc-walk orig))
	   (result (gensym))
	   (new-source 
	    `(lambda ,(cadr orig)
	       (let ((,result #<undefined>))
		 (dynamic-wind
		     (lambda ()       ; upon entry, show procedure name and args
		       (format #t "(~A~{ ~A~})~%" 
                               ',proc 
			       (outlet (outlet (curlet)))))
		     (lambda ()
		       (set! ,result (,new-body ,@(cadr orig))))
		     (lambda ()       ; at exit, show result
		       (if (eq? ,result #<undefined>)
			   (format #t "  ~A returns early~%" ',proc)
			   (format #t "  ~A returns ~A~%" ',proc ,result))))))))

      `(define ,proc ,new-source))))

			 
> (define (hi a) (let ((b 12)) (+ b a)))
hi
> (procedure-annotate hi)
#<lambda (a)>
> (let ((x 32)) (+ 1 (hi x)))
45
;; printing: 
(hi (a . 32))
    (let ((b . 12)) ...)
  hi returns 44

But maybe something less invasive is better. Here's a version of let that prints its bindings (this is borrowed from "nuntius" at reddit lisp):

(define-macro (print-let bindings . body)
  (let ((temp-symbol (gensym)))
    `(let ,(map (lambda (var/val)
		  `(,(car var/val) 
		    (let ((,temp-symbol ,(cadr var/val))) 
		      (format #t ";~S: ~S -> ~S~%" 
			      ',(car var/val) 
			      ',(cadr var/val) 
			      ,temp-symbol)
		      ,temp-symbol)))
		bindings)
       ,@body)))

;; or simpler:

(define-macro (print-let bindings . body)
  `(let ,bindings 
     (format #t "~{;~A~%~}" (curlet))
     ,@body))	      

A minor footnote: there are cases in s7 where aritable? can't tell whether a given number of arguments can be applied to an object. For example, ((list 1 (list 2 3)) 0 1) is an error, but ((list 1 (list 2 3)) 1 1) is 3. So (aritable? (list 1 (list 2 3)) 2) depdends on what actual arguments you pass. In these cases, aritable? returns #f.

(define (for-each-subset func args)
  ;; form each subset of args, apply func to the subsets that fit its arity
  (define (subset source dest len)
    (if (null? source)
        (if (aritable? func len)             ; does this subset fit?
	    (apply func dest))
	(begin
	  (subset (cdr source) (cons (car source) dest) (+ len 1))
	  (subset (cdr source) dest len))))
  (subset args () 0))

eval

eval evaluates its argument, a list representing a piece of code. It takes an optional second argument, the environment in which the evaluation should take place. eval-string is similar, but its argument is a string.

> (eval '(+ 1 2))
3
> (eval-string "(+ 1 2)")
3

Leaving aside a few special cases, eval-string could be defined:

(define-macro* (eval-string x e)
  `(eval (with-input-from-string ,x read) (or ,e (curlet))))

eval's environment argument is handy when implementing break and trace:

(define *breaklet* #f)
(define *step-hook* (make-hook 'code 'e))

(define-macro* (trace/break code . break-points)
  (define (caller tree)
    (if (pair? tree)
	(cons 
	 (if (pair? (car tree))
	     (if (and (symbol? (caar tree))
		      (procedure? (symbol->value (caar tree))))
		 (if (member (car tree) break-points)
		     `(__break__ ,(caller (car tree)))
		     `(__call__ ,(caller (car tree))))
		 (caller (car tree)))
	     (car tree))
	 (caller (cdr tree)))
	tree))
  `(call-with-exit (lambda (__top__) ,(caller code))))

(define (go . args)
  (and (let? *breaklet*)
       (apply (*breaklet* 'go) args)))

(define (clear-break)
  (set! *breaklet* #f))

(define-macro (__call__ code)
  `(*step-hook* ',code (curlet)))

(define-macro (__break__ code)
  `(begin
     (call/cc
      (lambda (go)
	(set! *breaklet* (curlet))
	(__top__ (format #f "break at: ~A~%" ',code))))
     ,code))

(set! (hook-functions *step-hook*) 
      (list (lambda (hook)
	      (set! (hook 'result) (eval (hook 'code) (hook 'e))))))

(set! ((funclet *step-hook*) 'end)
      (list (lambda (hook)
	      (define (uncaller tree)
		(if (pair? tree)
		    (cons 
		     (if (and (pair? (car tree))
			      (memq (caar tree) '(__call__ __break__)))
			 (uncaller (cadar tree))
			 (uncaller (car tree)))
		     (uncaller (cdr tree)))
		    tree))
	      (format (current-output-port) ": ~A -> ~A~40T~A~%" 
		      (uncaller (hook 'code)) 
		      (hook 'result)
		      (if (and (not (eq? (hook 'e) (rootlet)))
			       (not (defined? '__top__ (hook 'e))))
			  (map values (hook 'e)) 
			  "")))))

;;; (trace/break (let ((a (+ 3 1)) (b 2)) (if (> (* 2 a) b) 2 3)))
;;; (trace/break (let ((a (+ 3 1)) (b 2)) (if (> (* 2 a) b) 2 3)) (* 2 a))

IO and other OS functions

Besides files, ports can also represent strings and functions. The string port functions are:

(with-output-to-string thunk)         ; open a string port as current-output-port, call thunk, return string
(with-input-from-string string thunk) ; open string as current-input-port, call thunk
(call-with-output-string proc)        ; open a string port, apply proc to it, return string
(call-with-input-string string proc)  ; open string as current-input-port, apply proc to it
(open-output-string)                  ; open a string output port
(get-output-string port clear)        ; return output accumulated in the string output port
(open-input-string string)            ; open a string input port reading string
> (let ((result #f) 
        (p (open-output-string)))
    (format p "this ~A ~C test ~D" "is" #\a 3)
    (set! result (get-output-string p))
    (close-output-port p)
    result)
"this is a test 3"

In get-output-string, if the optional 'clear' argument is #t, the port is cleared (the default in r7rs I think). Other functions:

  • read-byte and write-byte: binary IO.
  • read-line: line-at-a-time reads, optional third argument #t to include the newline.
  • current-error-port, set-current-error-port

The variable (*s7* 'print-length) sets the upper limit on how many elements of a sequence are printed by object->string and format. The end-of-file object is #<eof>. When running s7 behind a GUI, you often want input to come from and output to go to arbitrary widgets. The function ports provide a way to redirect IO in C. See below for an example.

The default IO ports are *stdin*, *stdout*, and *stderr*. *stderr* is useful if you want to make sure output is flushed out immediately. The default output port is *stdout* which buffers output until a newline is seen. In most REPLs, the input port is set up by the REPL, so you need to use *stdin* if you want to read from the terminal instead:

> (read-char)
#<eof>
> (read-char *stdin*)
a          ; here s7 waited for me to type "a" in the terminal
#\a        ; this is the REPL reporting what read-char returned

An environment can be treated as an IO port, providing what Guile calls a "soft port":

(define (call-with-input-vector v proc)
  (let ((i -1))
    (proc (openlet (inlet 'read (lambda (p) (v (set! i (+ i 1)))))))))

Here the IO port is an open environment that redefines the "read" function so that it returns the next element of a vector. See stuff.scm for call-with-output-vector. The "proc" argument above can also be a macro, giving you a kludgey way to get around the dumb "lambda". Here are more useful examples:

(openlet          ; a soft port for format that sends its output to *stderr* and returns the string
  (inlet 'format (lambda (port str . args)
 	           (let ((result (apply format #f str args)))
	             (display result *stderr*)
	             result))))

(define (open-output-log name)
  ;; return a soft output port that does not hold its output file open
  (define (logit name str)
    (let ((p (open-output-file name "a")))
      (display str p)
      (close-output-port p)))
  (openlet 
   (inlet :name name
	  :format (lambda (p str . args) (logit (p 'name) (apply format #f str args)))
	  :write (lambda (obj p)         (logit (p 'name) (object->string obj #t)))
	  :display (lambda (obj p)       (logit (p 'name) (object->string obj #f)))
	  :write-string (lambda (str p)  (logit (p 'name) str))
	  :write-char (lambda (ch p)     (logit (p 'name) (string ch)))
	  :newline (lambda (p)           (logit (p 'name) (string #\newline)))
	  :close-output-port (lambda (p) #f)
	  :flush-output-port (lambda (p) #f))))

binary-io.scm in the Snd package has functions that read and write integers and floats in both endian choices in a variety of sizes.

If the compile time switch WITH_SYSTEM_EXTRAS is 1, several additional OS-related and file-related functions are built-in. This is work in progress; currently this switch adds:

(directory? str)         ; return #t if str is the name of a directory
(file-exists? str)       ; return #t if str names an existing file
(delete-file str)        ; try to delete the file, return 0 is successful, else -1
(getenv var)             ; return the value of an environment variable: (getenv "HOME")
(directory->list dir)    ; return contents of directory as a list of strings (if HAVE_DIRENT_H)
(system command)         ; execute command

But maybe this is not needed; see cload.scm below for a more direct approach.

error handling

(error tag . info)           ; signal an error of type tag with addition information
(catch tag body err)         ; if error of type tag signalled in body (a thunk), call err with tag and info
(throw tag . info)           ; jump to corresponding catch

s7's error handling mimics that of Guile. An error is signalled via the error function, and can be trapped and dealt with via catch.

> (catch 'wrong-number-of-args
    (lambda ()     ; code protected by the catch
      (abs 1 2))
    (lambda args   ; the error handler
      (apply format #t (cadr args))))
"abs: too many arguments: (1 2)"
> (catch 'division-by-zero
    (lambda () (/ 1.0 0.0))
    (lambda args (string->number "inf.0")))
inf.0

(define-macro (catch-all . body)
  `(catch #t (lambda () ,@body) (lambda args args)))

catch has 3 arguments: a tag indicating what error to catch (#t = anything), the code, a thunk, that the catch is protecting, and the function to call if a matching error occurs during the evaluation of the thunk. The error handler takes a rest argument which will hold whatever the error function chooses to pass it. The error function itself takes at least 2 arguments, the error type, a symbol, and the error message. There may also be other arguments describing the error. The default action, in the absence of any catch, is to treat the message as a format control string, apply format to it and the other arguments, and send that info to the current-error-port.

Normally when reading a file, we have to check for #<eof>, but we can let s7 do that:

(define (copy-file infile outfile)
  (call-with-input-file infile
    (lambda (in)
      (call-with-output-file outfile
	(lambda (out)
	  (catch 'wrong-type-arg   ; s7 raises this error if write-char gets #<eof>
	    (lambda () 
	      (do () ()            ; read/write until #<eof>
		(write-char (read-char in) out)))
	    (lambda err 
	      outfile)))))))

catch is not limited to error handling:

(define (map-with-exit func . args)
  ;; map, but if early exit taken, return the accumulated partial result
  ;;   func takes escape thunk, then args
  (let* ((result ())
	 (escape-tag (gensym))
	 (escape (lambda () (throw escape-tag))))
    (catch escape-tag
      (lambda ()
	(let ((len (apply max (map length args))))
	  (do ((ctr 0 (+ ctr 1)))
	      ((= ctr len) (reverse result))      ; return the full result if no throw
	    (let ((val (apply func escape (map (lambda (x) (x ctr)) args))))
	      (set! result (cons val result))))))
      (lambda args
	(reverse result))))) ; if we catch escape-tag, return the partial result

(define (truncate-if func lst)
  (map-with-exit (lambda (escape x) (if (func x) (escape) x)) lst))

> (truncate-if even? #(1 3 5 -1 4 6 7 8))
(1 3 5 -1)

But this is less useful than map (it can't map over a hash-table for example), and is mostly reimplementing built-in code. Perhaps s7 should have an extension of map (and more usefully, for-each) that is patterned after dynamic-wind: (dynamic-for-each init-func main-func end-func . args) where init-func is called with one argument, the length of the shortest sequence argument (for-each and map know this in advance); main-func takes n arguments where n matches the number of sequences passed; and end-func is called even if a jump out of main-func occurs (like dynamic-wind in this regard). In the dynamic-map case, the end-func takes one argument, the current, possibly partial, result list. dynamic-for-each then could easily (but maybe not efficiently) implement generic functions such as ->list, ->vector, and ->string (converting any sequence into a sequence of some other type). map-with-exit would be

(define (map-with-exit func . args) 
  (let ((result ()))
    (call-with-exit
      (lambda (quit)
        (apply dynamic-map #f ; no init-func in this case
               (lambda main-args 
                 (apply func quit main-args)) 
               (lambda (res) 
                 (set! result res))
               args)))
    result))

With all the lambda boilerplate, nested catches are hard to read:

(catch #t
  (lambda ()
    (catch 'division-by-zero
      (lambda ()
	(catch 'wrong-type-arg
	  (lambda () 
	    (abs -1))
	  (lambda args (format #t "got a bad arg~%") -1)))
      (lambda args 0)))
  (lambda args 123))

Perhaps we need a macro:

(define-macro (catch-case clauses . body)
  (let ((base `(lambda () ,@body)))
    (for-each (lambda (clause)
	        (let ((tag (car clause)))
	          (set! base `(lambda () 
			        (catch ',(or (eq? tag 'else) tag)
			          ,base 
			          ,@(cdr clause))))))
	      clauses)
    (caddr base)))

;;; the code above becomes:
(catch-case ((wrong-type-arg   (lambda args (format #t "got a bad arg~%") -1))
	     (division-by-zero (lambda args 0))
	     (else             (lambda args 123)))
  (abs -1))

This is similar to r7rs scheme's "guard", but I don't want a pointless thunk for the body of the catch. Along the same lines:

(define (catch-if test func err)
  (catch #t
    func
    (lambda args
      (if (test (car args))
	  (apply err args)
	  (apply throw args))))) ; if not caught, re-raise the error

(define (catch-member lst func err)
  (catch-if (lambda (tag) (member tag lst)) func err))

(define-macro (catch* clauses . error) 
  ;; try each clause until one evaluates without error, else error:
  ;;    (macroexpand (catch* ((+ 1 2) (- 3 4)) 'error))
  ;;    (catch #t (lambda () (+ 1 2)) (lambda args (catch #t (lambda () (- 3 4)) (lambda args 'error))))
  (define (builder lst)
    (if (null? lst)
	(apply values error)
	`(catch #t (lambda () ,(car lst)) (lambda args ,(builder (cdr lst))))))
  (builder clauses))

When an error is encountered, and when s7 is interrupted via begin_hook, (owlet) returns an environment that contains additional info about that error:

  • error-type: the error type or tag, e.g. 'division-by-zero
  • error-data: the message or information passed by the error function
  • error-code: the code that s7 thinks triggered the error
  • error-line: the line number of that code
  • error-file: the file name of that code

To find a variable's value at the point of the error: ((owlet) var). To list all the local bindings from the error outward:

(do ((e (outlet (owlet)) (outlet e))) 
    ((eq? e (rootlet))) 
  (format #t "~{~A ~}~%" e))

To see the current s7 stack, (stacktrace). You'll probably want to use this in conjunction with *error-hook*. To evaluate the error handler in the environment of the error:

(let ((x 1))
  (catch #t
	 (lambda ()
	   (let ((y 2))
	     (error 'oops)))
	 (lambda args
	   (with-let (sublet (owlet) :args args)    ; add the error handler args
	     (list args x y)))))    ; we have access to 'y'

To limit the maximum size of the stack, set (*s7* 'max-stack-size).

The hook *error-hook* provides a way to specialize error reporting. Its arguments are named 'type and 'data.

(set! (hook-functions *error-hook*) 
      (list (lambda (hook) 
              (apply format *stderr* (hook 'data)) 
              (newline *stderr*))))

There is a break macro defined in Snd (snd-xen.c) which allows you to stop at some point, then evaluate arbitrary expressions in that context.

The s7-built-in catch tags are 'wrong-type-arg, 'syntax-error, 'read-error, 'out-of-memory, 'wrong-number-of-args, 'format-error, 'out-of-range, 'division-by-zero, 'io-error, and 'bignum-error.

autoload

If s7 encounters an unbound variable, it first looks to see if it has any autoload information about it. This info can be declared via autoload, a function of two arguments, the symbol that triggers the autoload, and either a filename or a function. If a filename, s7 loads that file; if a function, it is called with one argument, the current (calling) environment.

(autoload 'channel-distance "dsp.scm") 
;; now if we subsequently call channel-distance but forget to load "dsp.scm" first,
;;   s7 loads "dsp.scm" itself, and uses its definition of channel-distance.
;;   The C-side equivalent is s7_autoload.

;; here is the cload.scm case, loading j0 from the math library if it is called:
(autoload 'j0
	  (lambda (e)
	    (unless (provided? 'cload.scm)
	      (load "cload.scm"))
	    (c-define '(double j0 (double)) "" "math.h")
	    (varlet e 'j0 j0)))

The entity (hash-table or environment probably) that holds the autoload info is named *autoload*. If after checking autoload, the symbol is still unbound, s7 calls *unbound-variable-hook*. The offending symbol is named 'variable in the hook environment. If after running *unbound-variable-hook*, the symbol is still unbound, s7 calls the error handler.

The autoloader knows about s7 environments used as libraries, so, for example, you can (autoload 'j0 "libm.scm"), then use j0 in scheme code. The first time s7 encounters j0, j0 is undefined, so s7 loads libm.scm. That load returns the C math library as the environment *libm*. s7 then automatically looks for j0 in *libm*, and defines it for you. So the result is the same as if you had defined j0 yourself in C code. You can use the r7rs library mechanism here, or with-let, or whatever you want! (In Snd, libc, libm, libdl, and libgdbm are automatically tied into s7 via autoload, so if you call, for example, frexp, libm.scm is loaded, and frexp is exported from the *libm* environment, then the evaluator soldiers on, as if frexp had always been defined in s7).

define-constant, constant?, symbol-access

define-constant defines a constant and constant? returns #t if its argument is a constant. A constant in s7 is really constant: it can't be set or rebound.

> (define-constant var 32)
var
> (set! var 1)
;set!: can't alter immutable object: var
> (let ((var 1)) var)
;can't bind or set an immutable object: var, line 1

This has the possibly surprising side effect that previous uses of the constant name become constants:

(define (func a) (let ((cvar (+ a 1))) cvar))
(define-constant cvar 23)
(func 1)
;can't bind or set an immutable object: cvar

So, obviously, choose unique names for your constants, or don't use define-constant. A function can also be a constant. In some cases, the optimizer can take advantage of this information to speed up function calls.

Constants are very similar to things such as keywords (no set, always return itself as its value), variable trace (informative function upon set or keeping a history of past values), typed variables (restricting a variable's values or doing automatic conversions upon set), and notification upon set (either in Scheme or in C; I wanted this many years ago in Snd). The notification function is especially useful if you have a Scheme variable and want to reflect any change in its value immediately in C (see below). In s7, symbol-access sets this function.

Each environment is a set of symbols and their associated values. symbol-access places a function (or macro) between a symbol and its value in a given environment. The accessor function takes two arguments, the symbol and the new value, and returns the value that is actually set. For example, the function can ensure that a variable is always an integer:

(define e      ; save environment for use below
  (let ((x 3)  ; will always be an integer
	(y 3)  ; will always keep its initial value
	(z 3)) ; will report set!

    (set! (symbol-access 'x) (lambda (s v) (if (integer? v) v x)))
    (set! (symbol-access 'y) (lambda (s v) y))
    (set! (symbol-access 'z) (lambda (s v) (format *stderr* "z ~A -> ~A~%" z v) v))
  
    (set! x 3.3) ; x does not change because 3.3 is not an integer
    (set! y 3.3) ; y does not change
    (set! z 3.3) ; prints "z 3 -> 3.3" 
    (curlet)))

> e
(inlet 'x 3 'y 3 'z 3.3)
>(begin (set! (e 'x) 123) (set! (e 'y) #()) (set! (e 'z) #f))
;; prints "z 3.3 -> #f"
> e
(inlet 'x 123 'y 3 'z #f)
> (define-macro (reflective-let vars . body)
    `(let ,vars
       ,@(map (lambda (vr)
	        `(set! (symbol-access ',(car vr))
		       (lambda (s v)
		         (format *stderr* "~S -> ~S~%" s v)
		         v)))
	      vars)
       ,@body))
reflective-let
> (reflective-let ((a 1)) (set! a 2))
2     ; prints "a -> 2"
>(let ((a 0))
     (set! (symbol-access 'a)
      (let ((history (make-vector 3 0))
	    (position 0))
	(lambda (s v)
	  (set! (history position) v)
	  (set! position (+ position 1))
	  (if (= position 3) (set! position 0))
	  v)))
     (set! a 1)
     (set! a 2)
     ((funclet (symbol-access 'a)) 'history))
#(1 2 0)

Or implement reactive programming:

(let ((a 1)
      (b 2)
      (c 3))
  (set! (symbol-access 'b) (lambda (s v) (set! a (+ v c)) v))
  (set! (symbol-access 'c) (lambda (s v) (set! a (+ b v)) v))
  (set! a (+ b c)) ; a will be updated if b or c is set
  (set! b 4)
  (set! c 5)
  a)               ; a is 9 = (+ 4 5)
reactive-let

stuff.scm has reactive-set!, reactive-vector, reactive-let, reactive-let*, and reactive-lambda*:

> (let ((-a- 1)
        (b 2))
    (reactive-set! -a- (* b 2))
    (set! b 3)
    -a-)
6
> (let ((a 1)) 
    (let ((v (reactive-vector a (+ a 1) 2))) 
      (set! a 4) 
      v))
#(4 5 2)
> (let ((a 1)) 
    (reactive-let ((-b- (+ a 1))) ; if 'a changes, '-b- does too
    (set! a 3)                  ;   so '-b- is now 4
    -b-))
4
> (let ((a 1))
    (reactive-lambda* (s v)
      (format *stderr* "~S -> ~S~%" s v))
    (set! a 3))
"a -> 3"

In the reactive-let example, the macro notices that '-b- depends on 'a, so it sets up a symbol-access on 'a so that (set! a 3) triggers (set! -b- (+ a 1)). I'm using -name- to distinguish the variables that can change value at any time; in the Lisp community, +name+ is often used to mark a constant, so this seems like a natural convention.

Here's the standard example of following the mouse (assuming you're using Snd and glistener):

(let ((*mouse-x* 0) (*mouse-y* 0)
      (x 0) (y 0))

  (reactive-set! x (let ((val (round *mouse-x*))) 
		     (format *stderr* "mouse: ~A ~A~%" x y) 
		     val))
  (reactive-set! y (round *mouse-y*))

  (g_signal_connect (G_OBJECT (listener-text-widget *listener*)) "motion_notify_event" 
		    (lambda (w e d) 
		      (let ((mxy (gdk_event_get_coords (GDK_EVENT e))))
			(set! *mouse-x* (cadr mxy))
			(set! *mouse-y* (caddr mxy))))))

reactive-lambda* is aimed at library consistency. Say we have the following library that wants A to always be half B:

(define (make-library)
  (let ((A 1.0)
	(B 2.0))
    (reactive-lambda* (s v)
      (case s
	((A) (set! B (* 2 v)))
	((B) (set! A (/ v 2)))))
    (define (f1 x) 
      (+ A (* B x)))
    (curlet)))

(with-let (make-library)
  (format *stderr* "(f1 3): ~A~%" (f1 3))
  (set! A 3.0)
  (format *stderr* "A: ~A, B: ~A, (f1 3): ~A~%" A B (f1 3))
  (set! B 4.0)
  (format *stderr* "A: ~A, B: ~A, (f1 3): ~A~%" A B (f1 3)))

reactive-lambda* sets up accessors on the library's top-level variables that call the lambda body if one of the variables is set.

None of these macros does the right thing yet; I'm sort of following my nose.

marvels and curiousities

*load-path* is a list of directories to search when loading a file. *load-hook* is a hook whose functions are called just before a file is loaded. The hook function argument, named 'name, is the filename. While loading, the port-filename and port-line-number of the current-input-port can tell you where you are in the file.

(set! (hook-functions *load-hook*)
       (list (lambda (hook) 
               (format #t "loading ~S...~%" (hook 'name)))))

(set! (hook-functions *load-hook*) 
      (cons (lambda (hook) 
              (format *stderr* "~A~%" 
                (system (string-append "./snd lint.scm -e '(begin (lint \"" (hook 'name) "\") (exit))'") #t)))
            (hook-functions *load-hook*)))

Here's a *load-hook* function that adds the loaded file's directory to the *load-path* variable so that subsequent loads don't need to specify the directory:

(set! (hook-functions *load-hook*)
  (list (lambda (hook)
          (let* ((pos -1)
                 (filename (hook 'name))
	         (len (length filename)))
            (do ((i 0 (+ i 1)))
	        ((= i len))
	      (if (char=? (filename i) #\/)
	          (set! pos i)))
            (if (positive? pos)
	        (let ((directory-name (substring filename 0 pos)))
	          (if (not (member directory-name *load-path*))
		      (set! *load-path* (cons directory-name *load-path*)))))))))

As in Common Lisp, *features* is a list describing what is currently loaded into s7. You can check it with the provided? function, or add something to it with provide. In my version of Snd, at startup *features* is:

> *features*
(snd-16.7 snd15 snd audio snd-s7 snd-gtk gsl alsa gtk2 xg clm6 clm sndlib linux
 dlopen complex-numbers system-extras ratio s7-3.26 s7) 
> (provided? 'gsl)
#t

The other side of provide is require. (require . things) finds each thing (via autoload), and if that thing has not already been loaded, loads the associated file. (require integrate-envelope) loads "env.scm", for example; in this case it is equivalent to simply using integrate-envelope, but if placed at the start of a file, it documents that you're using that function. In the more normal use, (require snd-ws.scm) looks for the file that has (provide 'snd-ws.scm) and if it hasn't already been loaded, loads it ("ws.scm" in this case). The "thing" passed to require is not quoted. To add your own files to this mechanism, add the provided symbol via autoload. Since load can take an environment argument, *features* and its friends follow block structure. So, for example, (let () (require stuff.scm) ...) loads "stuff.scm" into the local environment, not globally.

*features* is an odd variable: it is spread out across the chain of environments, and can hold features in an intermediate environment that aren't in subsequent (nested) values. One simple way this can happen is to load a file in a let, but cause the load to happen at the top level. The provided entities get added to the top-level *features* value, not the current let's value, but they are actually accessible locally. So *features* is a merge of all its currently accessible values, vaguely like call-next-method in CLOS. We can mimic this behavior:

(let ((x '(a)))
  (let ((x '(b)))
    (define (transparent-memq sym var e)
      (let ((val (symbol->value var e)))
	(or (and (pair? val)
		 (memq sym val))
	    (and (not (eq? e (rootlet)))
		 (transparent-memq sym var (outlet e))))))
    (let ((ce (curlet)))
      (list (transparent-memq 'a 'x ce)
	    (transparent-memq 'b 'x ce)
	    (transparent-memq 'c 'x ce)))))

'((a) (b) #f)

Multi-line and in-line comments can be enclosed in #| and |#. (+ #| add |# 1 2).

Leaving aside this case and the booleans, #f and #t, you can specify your own handlers for tokens that start with "#". *#readers* is a list of pairs: (char . func). "char" refers to the first character after the sharp sign (#). "func" is a function of one argument, the string that follows the #-sign up to the next delimiter. "func" is called when #<char> is encountered. If it returns something other than #f, the #-expression is replaced with that value. Scheme has several predefined #-readers for cases such as #b1, #\a, #i123, and so on, but you can override these if you like. If the string passed in is not the complete #-expression, the function can use read-char or read to get the rest. Say we'd like #t<number> to interpret the number in base 12:

(set! *#readers* (cons (cons #\t (lambda (str) (string->number (substring str 1) 12))) *#readers*))

> #tb
11
> #t11.3
13.25

Or have #c(real imag) be read as a complex number:

(set! *#readers* (cons (cons #\c (lambda (str) (apply complex (read)))) *#readers*))

> #c(1 2)
1+2i

I use *#readers* primarily to implement a way to get the current line number and file name, along the lines of C's __LINE__ and __FILE__. port-line-number works if we're reading a file (during load for example), and (owlet) has the same information if an error happens. But during Snd's auto-test sequence, there are many cases that aren't errors, and the file is no longer being loaded, but I need to know where something unexpected happened. So:

(set! *#readers* 
      (cons (cons #\_ (lambda (str)
			(if (string=? str "__line__")
			    (port-line-number)
			    (and (string=? str "__file__")
			         (port-filename)))))
            *#readers*))

Here's a reader macro for read-time evaluation:

(set! *#readers*
  (cons (cons #\. (lambda (str)
		    (and (string=? str ".") (eval (read)))))
	*#readers*))

> '(1 2 #.(* 3 4) 5)
(1 2 12 5)

To return no value from a reader, use (values).

> (set! *#readers* (cons (cons #\; (lambda (str) (if (string=? str ";") (read)) (values))) *#readers*))
((#\; . #<lambda (str)>))
> (+ 1 #;(* 2 3) 4)
5

Here is CL's #+ reader:

(define (sharp-plus str)
  ;; str here is "+", we assume either a symbol or an expression involving symbols follows
  (let ((e (if (string=? str "+")
		(read)                                ; must be #+(...)
		(string->symbol (substring str 1))))  ; #+feature
	(expr (read)))  ; this is the expression following #+
    (if (symbol? e)
        (if (provided? e)
	    expr
	    (values))
	(if (pair? e)
	    (begin      ; evaluate the #+(...) expression as in cond-expand
	      (define (traverse tree)
		(if (pair? tree)                                             
		    (cons (traverse (car tree))                             
			  (if (null? (cdr tree)) () (traverse (cdr tree))))
		    (if (memq tree '(and or not)) tree                 
			(and (symbol? tree) (provided? tree)))))
	      (if (eval (traverse e))
		  expr
		  (values)))
	    (error "strange #+ chooser: ~S~%" e)))))

See also the #n= reader below.

(make-list length (initial-element #f)) returns a list of 'length' elements defaulting to 'initial-element'.

(char-position char-or-string searched-string (start 0))
(string-position substring searched-string (start 0))

char-position and string-position search a string for the occurrence of a character, any of a set of characters, or a string. They return either #f if none is found, or the position within the searched string of the first occurrence. The optional third argument sets where the search starts in the second argument.

If char-position's first argument is a string, it is treated as a set of characters, and char-position looks for the first occurrence of any member of that set. Currently, the strings involved are assumed to be C strings (don't expect embedded nulls to work right in this context).

(call-with-input-file "s7.c" ; report any lines with "static " but no following open paren
  (lambda (file)
    (let loop ((line (read-line file #t)))
      (or (eof-object? line)
	  (let ((pos (string-position "static " line)))
	    (if (and pos
		     (not (char-position #\( (substring line pos))))
 	        (if (> (length line) 80)
		    (begin (display (substring line 0 80)) (newline))
		    (display line))))
	    (loop (read-line file #t)))))))

Keywords exist mainly for define*'s benefit. The keyword functions are: keyword?, make-keyword, symbol->keyword, and keyword->symbol. A keyword is a symbol that starts or ends with a colon. The colon is considered to be a part of the symbol name. A keyword is a constant that evaluates to itself.

(symbol-table)
(symbol->value sym (env (curlet)))
(symbol->dynamic-value sym)
(defined? sym (env (curlet)) ignore-global-env)

defined? returns #t if the symbol is defined in the environment:

(define-macro (defvar name value) 
  `(unless (defined? ',name)
     (define ,name ,value)))

If ignore-global-env is #t, the search is confined to the given environment. symbol->value returns the value (lexically) bound to the symbol, whereas symbol->dynamic-value returns the value dynamically bound to it. A variable can access both of its values:

> (let ((x 32))
  (define (gx) ; return both bindings of 'x
    (list x (symbol->value 'x) (symbol->dynamic-value 'x)))
  (let ((x 100))
    (let ((x 12))
      (values (gx))))) ; this 'values' looks dumb, it is dumb, but see my unconvincing explanantion below.
                       ;   briefly: "dynamic binding" in s7 is not "lexically apparent dynamic binding"
(32 32 12)

symbol-table returns a vector containing the symbols currently in the symbol-table. Here we scan the symbol table looking for any function that doesn't have documentation:

(for-each 
   (lambda (sym)
     (if (defined? sym)
         (let ((val (symbol->value sym)))
           (if (and (procedure? val)
                    (string=? "" (procedure-documentation val)))
               (format *stderr* "~S " sym)))))
  (symbol-table))

Here's a better example, an automatic software tester.

(let ((constants (list #f #t pi () 1 1.5 3/2 1.5+i)))

  (define (autotest func args args-left)
    (catch #t (lambda () (apply func args)) (lambda any #f))
    (if (> args-left 0)
	(for-each
	 (lambda (c)
	   (autotest func (cons c args) (- args-left 1)))
	 constants)))

    (for-each 
      (lambda (sym)
	(if (defined? sym)
	    (let ((val (symbol->value sym)))
              (if (procedure? val)
	          (let ((max-args (cdr (arity val))))
	            (if (or (> max-args 4)
	       	            (memq sym '(exit abort)))
		        (format #t ";skip ~S for now~%" sym)
		        (begin
		          (format #t ";whack on ~S...~%" sym)
		          (autotest val () max-args))))))))
    (symbol-table)))

Equally useful, a profiler:

(define profile 
  (let ((documentation "(profile func) evaluates the function, then reports profiling information. \
The function takes one argument, the environment in which loads and evals should operate."))
    (lambda (expression)
      (define calls (make-vector 1024 (cons 'unused -1)))
      (define call 0)

      (define (profile-1 n)
        (set! (cdr (calls n)) (+ (cdr (calls n)) 1)))
  
      (define (wrap-all)
        (let ((e (inlet)))
          (for-each
            (lambda (sym)
              (if (and (defined? sym)
	               (not (constant? sym)))
	          (let ((val (symbol->value sym)))
	            (if (procedure? val)
	                (let ((new-val (apply lambda 'args `((profile-1 ,call) (apply ,val args)))))
		          (set! (calls call) (cons sym 0))
		          (set! call (+ call 1))
		          (if (>= call (length calls))
			      (set! calls (copy calls (make-vector (* 2 (length calls)) (cons 'unused -1)))))
		          (if (procedure-setter val)
		              (set! (procedure-setter new-val) (procedure-setter val)))
		          (varlet e sym new-val))))))
           (symbol-table))
          e))

      (expression (wrap-all))
      (sort! calls (lambda (a b) (> (cdr a) (cdr b))))
      (do ((i 0 (+ i 1)))
          ((= i call))
        (if (> (cdr (calls i)) 0)
	    (format #t "~S: ~S~%" (car (calls i)) (cdr (calls i))))))))

> (profile (lambda (e) 
             (load "lint.scm" e) 
             (with-let e (lint "dsp.scm"))))
;;; many lines of data print out
more on dynamic values

Why the useless 'values' in our dynamic binding example? The short answer: tail calls. The long winded one goes something like this. symbol->dynamic-value searches the stack to find the latest binding of its argument. But because we want to support tail calls, "let" does not push anything on the stack. If we call a function as the last thing that happens in that let's body, and it tries (internally) to access a dynamic binding, the let that launched the function no longer exists; it might already be garbage collected, and it certainly isn't on the stack. Take our earlier example without the 'values':

(let ((x 32))
  (define (gx) 
    (symbol->dynamic-value 'x))
  (let ((x 100))
    (gx)))

This returns 32 because the (x 100) binding no longer exists anywhere when the gx body is evaluated. So, in s7, the "dynamic binding" of x is the last binding of x that is accessible to s7. This may not be the last binding that we can see in the code text, but I don't see that as an inconsistency. It's not lexical after all. Leaving aside this special case, so to speak, dynamic binding does what you'd expect, even in the context of call/cc. See s7test.scm for the MIT-Scheme test of that interaction.

There is another way to get the call-time value:

(define-macro (elambda args . body)
  `(define-macro (,(gensym) ,@args)
    `((lambda* ,(append ',args `((*env* (curlet)))) 
        ,'(begin ,@body)) 
      ,,@args)))

(define efunc (elambda (x) (+ (*env* 'y) x))) ; add x to the run-time value of y
(let ((y 3)) (efunc 1)) ; returns 4

elambda does not suffer from the symbol->dynamic-value defects mentioned above, but it's probably slower. We have to wrap the function in a macro because lambda*'s argument default values are evaluated in the definition environment, but we want the run-time environment.

(define-macro* (rlambda args . body) ; lambda* but eval arg defaults in run-time env
  (let ((arg-names (map (lambda (arg) (if (pair? arg) (car arg) arg)) args))
	(arg-defaults (map (lambda (arg) (if (pair? arg) `(,(car arg) (eval ,(cadr arg))) arg)) args)))
    `(define-bacro* (,(gensym) ,@arg-defaults)
      `((lambda ,',arg-names ,'(begin ,@body)) ,,@arg-names))))

(let ()
  (define rx (rlambda ((a x)) 
               (if (> a 0) 
                   (let ((x (- x 1))) ;:)
                     (rx))
                   0)))
  (let ((x 3))
    (rx)))

Now putting that idea with the procedure-annotation macro given earlier, and the __func__ business (to get the caller's name), and taking care to handle default arguments correctly, we make a macro that returns an anonymous macro that returns an anonymous function that — where was I?

(define-macro (Display definition) ; (Display (define (f1 x) (+ x 1))) -> an annotated version of f1
  (let ((func (caadr definition))
	(args (cdadr definition)))
    (let ((arg-names (map (lambda (a) (if (symbol? a) a (car a))) args))
	  (body (proc-walk `(begin ,@(cddr definition))))) ; from procedure-annotation above
      `(define ,func
	  (define-macro* (,(gensym) ,@args)
	    (let ((e (gensym))
		  (result (gensym)))
	      `((lambda* ,(append ',arg-names `((,e (curlet)))) ; the calling environment
		  (let ((,result '?))
		    (dynamic-wind
			(lambda ()    ; display the caller, if any, as well as the incoming arguments
			  (format *stderr* "(~A~{~^ ~A~})" ',',func 
				  (map (lambda (slot)
					 (if (gensym? (car slot)) (values) slot))
				       (outlet (outlet (curlet)))))
			  (let ((caller (eval '__func__ ,e)))
			    (if (not (eq? caller #<undefined>))
				(format *stderr* " ;called from ~S" caller))
			    (newline *stderr*)))
			(lambda ()   ; evaluate the original function's body with annotations
			  (set! ,result ,',body))
			(lambda ()   ; display the result (it is returned by the set! above)
			  (format *stderr* "    -> ~S~%" ,result)))))
		,,@arg-names)))))))

stuff.scm has a more mature version of this macro.

help tries to find information about its argument.

> (help 'caadar)
"(caadar lst) returns (car (car (cdr (car lst)))): (caadar '((1 (2 3)))) -> 2"

gc calls the garbage collector. (gc #f) turns off the GC, and (gc #t) turns it on.

(morally-equal? x y)

Say we want to check that two different computations came to the same result, and that result might involve circular structures. Will equal? be our friend?

> (equal? 2 2.0)
#f
> (let ((x +nan.0)) (equal? x x))
#f
> (equal? .1 1/10)
#f    
> (= .1 1/10)
#f
> (= 0.0 0+1e-300i)
#f

No! We need an equality check that ignores epsilonic differences in real and complex numbers, and knows that NaNs are equal for all practical purposes. Leaving aside numbers, closed ports are not equal, yet nothing can be done with them. #() is not equal to #2d(). And two closures are never equal, even if their arguments, environments, and bodies are equal. Since there might be circles, it is not easy to write a replacement for equal? in Scheme. So, in s7, if one thing is basically the same as some other thing, they satisfy the function morally-equal?.

> (morally-equal? 2 2.0)        ; would "equal!?" be a better name?
#t
> (morally-equal? 1/0 1/0)      ; NaN
#t
> (morally-equal? .1 1/10)
#t                              ; floating-point epsilon here is 1.0e-15 or thereabouts
> (morally-equal? 0.0 1e-300)
#t
> (morally-equal? 0.0 1e-14)
#f                              ; its not always #t!
> (morally-equal? (lambda () #f) (lambda () #f))
#t

The *s7* field morally-equal-float-epsilon sets the floating-point fudge factor. I can't decide how bignums should interact with morally-equal?. Currently, if a bignum is involved, either here or in a hash-table, s7 uses equal?. Finally, if either argument is an environment with a 'morally-equal? method, that method is invoked.

define-expansion defines a macro that expands at read-time. It has the same syntax as define-macro, and (in normal use) the same result, but it is much faster because it expands only once. (See define-with-macros in s7test.scm for a way to expand macros in a function body at definition time). Since the reader knows almost nothing about the code it is reading, you need to make sure the expansion name is unique! The reader does know about global variables, so:

(define *debugging* #t)

(define-expansion (assert assertion)
  (if *debugging*          ; or maybe better, (eq? (symbol->value '*debugging*) #t)
      `(unless ,assertion
	 (format *stderr* "~A: ~A failed~%" __func__ ',assertion))
      (values)))

Now the assertion code is only present in the function body (or wherever) if *debugging* is #t; otherwise assert expands into nothing. Leaving aside read-time expansion and splicing, the real difference between define-macro and define-expansion is that the expansion's result is not evaluated. I'm no historian, but I believe that means that define-expansion creates a (gasp!) f*xpr. In fact:

(define-macro (define-f*xpr name-and-args . body)
  `(define ,(car name-and-args)
     (apply define-expansion 
       (append (list (append (list (gensym)) ',(cdr name-and-args))) ',body))))

> (define-f*xpr (mac a) `(+ ,a 1))
mac
> (mac (* 2 3))
(+ (* 2 3) 1)

You can do something similar with a normal macro, or make the indirection explicit:

> (define-macro (fx x) `'(+ 1 ,x)) ; quote result to avoid evaluation
fx
> (let ((a 3)) (fx a))
(+ 1 a)
> (define-expansion (ex x) `(+ 1 ,x))
ex
> (let ((x ex) (a 3)) (x a))       ; avoid read-time splicing
(+ 1 a)
> (let ((a 3)) (ex a))             ; spliced in at read-time
4

As this example shows, the reader knows nothing about the program context, so if it does not see a list whose first element is a expansion name, it does not do anything special. In the (x a) case above, the expansion happens when the code is evaluated, and the expansion result is simply returned, unevaluated.

You can also use macroexpand to cancel the evaluation of a macro's expansion:

(define-macro (rmac . args)
  (if (null? args)
      ()
      (if (null? (cdr args))
	  `(display ',(car args))
	  (append (list 'begin `(display ',(car args)))
		  (list (apply macroexpand (list (append '(rmac) (cdr args)))))))))

> (macroexpand (rmac a b c))
(begin (display 'a) (begin (display 'b) (display 'c)))
> (begin (rmac a b c d) (newline))
abcd

The main built-in expansion is reader-cond. The syntax is based on cond: the car of each clause is evaluated (in the read-time context), and if it is not false, the remainder of that clause is spliced into the code as if you had typed it from the start.

> '(1 2 (reader-cond ((> 1 0) 3) (else 4)) 5 6)
(1 2 3 5 6)
> ((reader-cond ((> 1 0) list 1 2) (else cons)) 5 6)
(1 2 5 6)

*s7* is an environment that gives access to some of s7's internal state:

print-length                  number of elements of a sequence to print
max-string-length             max size arg to make-string and read-string
max-list-length               max size arg to make-list
max-vector-length             max size arg to make-vector and make-hash-table
max-vector-dimensions         make-vector dimensions limit
default-hash-table-length     default size for make-hash-table (8, tables resize as needed)
initial-string-port-length    128, initial size of a string port's buffer

default-rationalize-error     1e-12 (settable)
morally-equal-float-epsilon   1e-15 (settable)
hash-table-float-epsilon      1e-12 (settable, but currently limited to less than 1e-3).
bignum-precision              bits for bignum floats (128)
float-format-precision        digits to print for floats (16)
default-random-state          the default arg for random (settable)

cpu-time                      run time so far
file-names                    currently loaded files (a list)

safety                        0
undefined-identifier-warnings #f 

catches                       a list of the currently active catch tags
exits                         a list of active call-with-exit exit functions
c-types                       a list of c-object type names (from s7_new_type, etc)
input-ports, output-ports, strings, gensyms, vectors, hash-tables, continuations

stack-top                     current stack location
stack-size                    current stack size
max-stack-size                max stack size (settable)
stack                         the current stack entries
stacktrace-defaults           stacktrace formatting info for error handler

symbol-table                  a vector
symbol-table-locked?          #f (if #t, no new symbols can be added to the symbol table)
rootlet-size                  the number of globals

heap-size                     total cells currently available
free-heap-size                the number of currently unused cells
gc-freed                      number of cells freed by the last GC pass
gc-protected-objects          vector of the objects permanently protected from the GC
gc-stats                      #f (#t turns on printout of the GC activity)
memory-usage                  a description of current memory allocations

Use the standard environment syntax to access these fields: (*s7* 'stack-top). stuff.scm has the function *s7*->list that returns most of these fields in a list.

Set (*s7* 'safety) to 2 or higher to turn off optimization.

stacktrace-defaults is a list of four integers and a boolean that tell the error handler how to format stacktrace information. The four integers are: how many frames to display, how many columns are devoted to code display, how many columns are available for a line of data, and where to place comments. The boolean sets whether the entire output should be displayed as a comment. The defaults are '(3 45 80 45 #t).

(c-object? obj)
(c-pointer? obj)
(c-pointer int)

You can wrap up raw C pointers and pass them around in s7 code. The function c-pointer returns a wrapped pointer, and c-pointer? returns #t if passed one. (define NULL (c-pointer 0)). c-object? returns the object's type tag if passed such an object (otherwise #f of course). This tag is also the position of the object's type in the (*s7* 'c-types) list. (*s7* 'c-types) returns a list of the types created by s7_new_type_x and friends.

Some other differences from r5rs:

  • no force or delay (see below).
  • no syntax-rules or any of its friends.
  • no scheme-report-environment, null-environment, or interaction-environment (use curlet).
  • no transcript-on or transcript-off.
  • begin returns the value of the last form; it can contain both definitions and other statements.
  • #<unspecified>, #<eof>, and #<undefined> are first-class objects.
  • for-each and map accept different length arguments; the operation stops when any argument reaches its end.
  • for-each and map accept any applicable object as the first argument, and any sequence or iterator as a trailing argument.
  • letrec*, but without conviction.
  • set! and *-set! return the new value (modulo symbol-access), not #<unspecified>.
  • port-closed?
  • list? means "pair or null", proper-list? is r5rs list?, float? means "real and not rational", sequence? = length.
  • the default IO ports are named *stdin*, *stdout*, and *stderr*.
  • #f as an output port means nothing is output (#f is /dev/null, I guess).
  • member and assoc accept an optional third argument, the comparison function (equal? is the default).
  • case accepts => much like cond (the function argument is the selector).
  • if WITH_SYSTEM_EXTRAS is 1, the following are built-in: directory?, file-exists?, delete-file, system, directory->list, getenv.
  • s7 is case sensitive.
  • when and unless (for r7rs), returning the value of the last form.
  • the "d", "f", "s", and "l" exponent markers are not supported by default (use "e", "E", or "@").
  • quasiquoted vector constants are not supported by default — use reader-cond instead.

In s7 if a built-in function like gcd is referred to in a function body, the optimizer is free to replace it with #_function. That is, (gcd ...) can be changed to (#_gcd ...) at s7's whim, if gcd has its original value at the time the optimizer sees the expression using it. A subsequent (set! gcd +) does not affect this optimized call. I think I could wave my hands and mumble about "aggressive lexical scope" or something, but actually the choice here is that speed trumps that ol' hobgoblin consistency. If you want to change gcd to +, do it before loading code that calls gcd. I think most Schemes handle macros this way: the macro call is replaced by its expansion using its current definition, and a later redefinition does not affect earlier uses.

Here are some changes I'd make to s7 if I didn't care about compatibility with other Schemes:

  • remove the exact/inexact distinction including #i and #e
  • remove call-with-values and its friends
  • remove char-ready?
  • change eof-object? to eof? or just omit it (you can use eq? #<eof>)
  • change make-rectangular to complex, and remove make-polar.
  • remove unquote (the name, not the functionality).
  • remove cond-expand.
  • remove *-ci functions (they are completely useless)

(most of these are removed if you set the compiler flag WITH_PURE_S7), and perhaps:

  • remove even? and odd?, gcd and lcm.
  • remove string-length and vector-length.
  • remove list-ref|set!, string-ref|set!, vector-ref|set!, hash-table-ref|set!, set-car!|cdr!, and set-current-output|input|error-port.
  • change file-exists? to file? (or omit it and assume the use of libc.scm — why reinvent the wheel?).
  • remove all the conversion and copy functions like vector->list and vector-copy (use copy or map).
  • add typeq? and perhaps make null? generic (see stuff.scm).
  • change string->symbol to symbol (what to do with symbol->string in that case?)
  • change with-output-to-* and with-input-from-* to omit the pointless lambda.
  • remove the with-* IO functions (e.g. with-input-from-string), keeping the call-with-* versions (call-with-input-string).
  • remove assq, assv, memq, and memv (these are pointless now that assoc and member can be passed eq? and eqv?).

There are several less-than-ideal names. Perhaps s7 should use *pi*, *most-negative-fixnum*, *most-positive-fixnum* (*fixmost*?) so that all the built-in variables and constants have the same kind of name (or +pi+ to show it is a constant?). Perhaps object->string should be ->string. get-output-string should be current-output-string. write-char behaves like display, not write. provided? should be feature? or *features* should be *provisions*.

The name "cond-expand" is bad — we're not expanding anything, and the macro's point is to make it easy to operate with the *features* list; perhaps "cond-provided"? Not only is cond-expand poorly named, but the whole idea is clumsy. Take libgsl.scm; different versions of the GSL library have different functions. We need to know when we're building the FFI what GSL version we're dealing with. It would be nuts to start pushing and checking dozens of library version symbols when all we actually want is (> version 23.19). (We are also politely trying to ignore the ridiculous little language built into cond-expand; are we not running Scheme?). In place of cond-expand, s7 uses reader-cond, so the read-time decision involves normal evaluation.

Better ideas are always welcome!

Here are the built-in s7 variables:

  • *features* ; a list of symbols
  • *libraries* ; a list of (filename . let) pairs
  • *load-path* ; a list of directories
  • *autoload* ; autoload info (a function internally)
  • *#readers* ; a list of (char . handler) pairs

And the built-in constants:

  • pi
  • *stdin* *stdout* *stderr*
  • *s7*
  • nan.0 -nan.0 inf.0 -inf.0 (what crappy names! nan.0 is an inexact integer that is not a number?)
  • most-positive-fixnum most-negative-fixnum
  • *unbound-variable-hook* *missing-close-paren-hook* *load-hook* *error-hook*

__func__ is the name (or name and location) of the function currently being called, as in C.

Currently WITH_PURE_S7:

  • places 'pure-s7 in *features*
  • omits char-ready, char-ci*, string-ci*
  • omits string-copy, string-fill!, vector-fill!, vector-append
  • omits list->string, list->vector, string->list, vector->list, let->list
  • omits string-length and vector-length
  • omits cond-expand, multiple-values-bind|set!, call-with-values, defmacro(*)
  • omits unquote (the name), and quasiquoted vector constants
  • omits d/f/s/l exponents
  • omits make-polar and make-rectangular (use complex)
  • omits integer-length, exact?, inexact?, exact->inexact, inexact->exact, #i and #e
  • omits set-current-output-port and set-current-input-port
  • omits memq, memv, assq, assv
quotes

Schemes vary in their treatment of (). s7 considers it a constant that evaluates to itself, so you don't need to quote it. (eq? () '()) is #t. This is consistent with, for example, (eq? #f '#f) which is also #t. The standard says "the empty list is a special object of its own type", so surely either choice is acceptable in that regard. One place where the quote matters is in a case statement; the selector is evaluated but the key is not:

> (case '() ((()) 2) (else 1))
2
> (case '() (('()) 2) (else 1)) ; (eqv? '() ''()) is #f
1
;;; which parallels #f (or a number such as 2 etc):
> (case '#f ((#f) 2) (else 1))
2
> (case '#f (('#f) 2) (else 1)) ; (eqv? '#f ''#f) is #f
1

Similarly, vector constants do not have to be quoted. A list constant is quoted to keep it from being evaluated, but #(1 2 3) is as unproblematic as "123" or 123.

These examples bring up another odd corner of scheme: else. In (cond (else 1)) the 'else is evaluated (like any cond test), so its value might be #f; in (case 0 (else 1)) it is not evaluated (like any case key), so it's just a symbol. Since symbol accessors are local in s7, someone can (let ((else #f)) (cond (else 1))) even if we protect the rootlet 'else. Of course, in scheme this kind of trouble is pervasive, so rather than make 'else a constant I think the best path is to use unlet: (let ((else #f)) (cond (#_else 1))). This is 1 (not ()) because the initial value of 'else can't be changed.

mutable constants

How should s7 treat this: (string-set! "hiho" 1 #\z), or (vector-set! #(1 2 3) 1 32), or (list-set! '(1 2 3) 1 32)? Originally, in s7, the first two were errors, and the third was allowed, which doesn't make much sense. Guile and Common Lisp accept all three, but that leads to weird cases where we can reach into a function's body:

> (let ((x (lambda () '(1 2 3)))) (list-set! (x) 1 32) (x))
(1 32 3) ; s7, Guile
> (flet ((x () '(1 2 3))) (setf (nth 1 (x)) 32) (x))
(1 32 3) ; Clisp
> (let ((x (lambda () (list 1 2 3)))) (list-set! (x) 1 32) (x))
(1 2 3)

But it's possible to reach into a function's closure, even when the closed-over thing is a constant:

> (flet ((x () '(1 2 3))) (setf (nth 1 (x)) 32) (x))
(1 32 3)
> (let ((xx (let ((x '(1 2 3))) (lambda () x)))) (list-set! (xx) 1 32) (xx))
(1 32 3)
> (let ((xx (let ((x (list 1 2 3))) (lambda () x)))) (list-set! (xx) 1 32) (xx))
(1 32 3)

And it's possible to reach into a constant list via list-set! (or set-car! of course):

> (let* ((x '(1 2)) (y (list x)) (z (car y))) (list-set! z 1 32) (list x y z))
((1 32) ((1 32)) (1 32))

It would be a programmer's nightmare to have to keep track of which piece of a list is constant, and an implementor's nightmare to copy every list. set! in all its forms is used for its side-effects, so why should we try to put a fence around them? If we flush "immutable constant" because it is a ham-fisted, whack-it-with-a-shovel approach, the only real problem I can see is symbol->string. In CL, this is explicitly an error:

> (setf (elt (symbol-name 'xyz) 1) #\X)
*** - Attempt to modify a read-only string: "XYZ"

And in Guile:

> (string-set! (symbol->string 'symbol->string) 1 #\X)
ERROR: string is read-only: "symbol->string"

So both have a notion of immutable strings. I wonder what other Scheme programmers (not implementors!) want in this situation. Currently, there are no immutable list, string, or vector constants, and symbol->string returns a copy of the string. copy can protect some values. Or combine object->string and string->symbol:

> (let ((x (lambda () (copy "hiho")))) (string-set! (x) 1 #\x) (x))
"hiho"
> (let ((x (string->symbol "hiho"))) (string-set! (symbol->string x) 1 #\x) (symbol->string x))
"hiho"
> (define (immutable obj) (string->symbol (object->string obj :readable)))
immutable
> (define (symbol->object sym) (eval-string (symbol->string sym)))
symbol->object
> (symbol->object (immutable (list 1 2 3)))
(1 2 3)

s7 normally tries to optimize garbage collection by removing some list constants from the heap. If you later set a member of it to something that needs GC protection, nobody in the heap points to it, so it is GC'd. Here is an example:

(define (bad-idea)
  (let ((lst '(1 2 3)))
    (let ((result (list-ref lst 1)))
     (list-set! lst 1 (* 2.0 16.6))
     (gc)
     result)))

Put this is a file, load it into the interpreter, then call (bad-idea) a few times. You can turn off the optimization in question by setting the variable (*s7* 'safety) to 1. (*s7* 'safety) defaults to 0.

circular lists

s7 handles circular lists and vectors and dotted lists with its customary aplomb. You can pass them to memq, or print them, for example; you can even evaluate them. The print syntax is borrowed from CL:

> (let ((lst (list 1 2 3))) 
    (set! (cdr (cdr (cdr lst))) lst) 
    lst)
#1=(1 2 3 . #1#)
> (let* ((x (cons 1 2)) 
         (y (cons 3 x))) 
    (list x y))
(#1=(1 . 2) (3 . #1#))

But should this syntax be readable as well? I'm inclined to say no because then it is part of the language, and it doesn't look like the rest of the language. (I think it's kind of ugly). Perhaps we could implement it via *#readers*:

(define circular-list-reader
  (let ((known-vals #f)
	(top-n -1))
    (lambda (str)

      (define (replace-syms lst)
	;; walk through the new list, replacing our special keywords 
        ;;   with the associated locations

	(define (replace-sym tree getter)
	  (if (keyword? (getter tree))
	      (let ((n (string->number (symbol->string (keyword->symbol (getter tree))))))
		(if (integer? n)
		    (let ((lst (assoc n known-vals)))
		      (if lst
			  (set! (getter tree) (cdr lst))
			  (format *stderr* "#~D# is not defined~%" n)))))))

	(define (walk-tree tree)
	  (if (pair? tree)
	      (begin
		(if (pair? (car tree)) (walk-tree (car tree)) (replace-sym tree car))
		(if (pair? (cdr tree)) (walk-tree (cdr tree)) (replace-sym tree cdr))))
	  tree)

	(walk-tree (cdr lst)))

      ;; str is whatever followed the #, first char is a digit
      (let* ((len (length str))
	     (last-char (str (- len 1))))
	(and (memq last-char '(#\= #\#))             ; is it #n= or #n#?
	    (let ((n (string->number (substring str 0 (- len 1)))))
	      (and (integer? n)
		  (begin
		    (if (not known-vals)            ; save n so we know when we're done
			(begin
			  (set! known-vals ())
			  (set! top-n n))) 

		    (if (char=? last-char #\=)      ; #n=
			(and (char=? (peek-char) #\()
			    (let ((cur-val (assoc n known-vals)))
			      ;; associate the number and the list it points to
			      ;;    if cur-val, perhaps complain? (#n# redefined)
			      (let ((lst (catch #t 
					   read
					   (lambda args             ; a read error
					     (set! known-vals #f)   ;   so clear our state
					     (apply throw args))))) ;   and pass the error on up
				(if (not cur-val)
				    (set! known-vals 
					  (cons (set! cur-val (cons n lst)) known-vals))
				    (set! (cdr cur-val) lst)))
			      
			      (if (= n top-n)            ; replace our special keywords
				  (let ((result (replace-syms cur-val)))
				    (set! known-vals #f) ; '#1=(#+gsl #1#) -> '(:1)!
				    result)
				  (cdr cur-val))))
			                         ; #n=<not a list>?
			;; else it's #n# — set a marker for now since we may not 
			;;   have its associated value yet.  We use a symbol name that 
                        ;;   string->number accepts.
			(symbol->keyword 
                          (symbol (string-append (number->string n) (string #\null) " ")))))))
		                                 ; #n<not an integer>?
	    )))))                                ; #n<something else>?

(do ((i 0 (+ i 1)))
    ((= i 10))
  ;; load up all the #n cases
  (set! *#readers* 
    (cons (cons (integer->char (+ i (char->integer #\0))) circular-list-reader)
          *#readers*)))

> '#1=(1 2 . #1#)
#1=(1 2 . #1#)
> '#1=(1 #2=(2 . #2#) . #1#)
#2=(1 #1=(2 . #1#) . #2#)

And of course, we can treat these as labels:

(let ((ctr 0)) #1=(begin (format #t "~D " ctr) (set! ctr (+ ctr 1)) (if (< ctr 4) #1# (newline))))

which prints "0 1 2 3" and a newline.


Length returns +inf.0 if passed a circular list, and returns a negative number if passed a dotted list. In the dotted case, the absolute value of the length is the list length not counting the final cdr. (define (circular? lst) (infinite? (length lst))).

cyclic-sequences returns a list of the cyclic sequences in its argument, or nil. (define (cyclic? obj) (pair? (cyclic-sequences obj))).

Here's an amusing use of circular lists:

(define (for-each-permutation func vals)
  ;; apply func to every permutation of vals: 
  ;;   (for-each-permutation (lambda args (format #t "~{~A~^ ~}~%" args)) '(1 2 3))
  (define (pinner cur nvals len)
    (if (= len 1)
        (apply func (cons (car nvals) cur))
        (do ((i 0 (+ i 1)))                       ; I suppose a named let would be more Schemish
            ((= i len))
          (let ((start nvals))
            (set! nvals (cdr nvals))
            (let ((cur1 (cons (car nvals) cur)))  ; add (car nvals) to our arg list
              (set! (cdr start) (cdr nvals))      ; splice out that element and 
              (pinner cur1 (cdr start) (- len 1)) ;   pass a smaller circle on down, "wheels within wheels"
              (set! (cdr start) nvals))))))       ; restore original circle
  (let ((len (length vals)))
    (set-cdr! (list-tail vals (- len 1)) vals)    ; make vals into a circle
    (pinner () vals len)
    (set-cdr! (list-tail vals (- len 1)) ())))    ; restore its original shape
unprintable symbols

s7 and Snd use "*" in a variable name, *features* for example, to indicate that the variable is predefined. It may occur unprotected in a macro, for example. The "*" doesn't mean that the variable is special in the CL sense of dynamic scope, but some clear marker is needed for a global variable so that the programmer doesn't accidentally step on it.

Although a variable name's first character is more restricted, currently only #\null, #\newline, #\tab, #\space, #\), #\(, #\", and #\; can't occur within the name. I did not originally include double-quote in this set, so wild stuff like (let ((nam""e 1)) nam""e) would work, but that means that '(1 ."hi") is parsed as a 1 and the symbol ."hi", and (string-set! x"hi") is an error. The first character should not be #\#, #\', #\`, #\,, #\:, or any of those mentioned above, and some characters can't occur by themselves. For example, "." is not a legal variable name, but ".." is. These weird symbols have to be printed sometimes:

> (list 1 (string->symbol (string #\; #\" #\\)) 2)
(1 ;"\ 2)            
> (list 1 (string->symbol (string #\.)) 2)
(1 . 2)

which is a mess. Guile prints the first as (1 #{\;\"\\}# 2). In CL and some Schemes:

[1]> (list 1 (intern (coerce (list #\; #\" #\\) 'string)) 2) ; thanks to Rob Warnock
(1 |;"\\| 2)        
[2]> (equalp 'A '|A|) ; in CL case matters here
T

This is clean, and has the weight of tradition behind it, but I think I'll use "symbol" instead:

> (list 1 (string->symbol (string #\; #\" #\\)) 2)
(1 (symbol ";\"\\") 2)       

This output is readable, and does not eat up perfectly good characters like vertical bar, but it means we can't easily use variable names like "| e t c |". We could allow a name to contain any characters if it starts and ends with "|", but then one vertical bar is trouble.

These symbols are not just an optimization of string comparison:

> (define-macro (hi a) 
  (let ((funny-name (string->symbol ";")))
    `(let ((,funny-name ,a)) (+ 1 ,funny-name))))
hi
> (hi 2)
3
> (macroexpand (hi 2))
(let ((; 2)) (+ 1 ;))    ; for a good time, try (string #\")

> (define-macro (hi a) 
  (let ((funny-name (string->symbol "| e t c |")))
    `(let ((,funny-name ,a)) (+ 1 ,funny-name))))
hi
> (hi 2)
3
> (macroexpand (hi 2))
(let ((| e t c | 2)) (+ 1 | e t c |))
> (let ((funny-name (string->symbol "| e t c |"))) ; now use it as a keyword arg to a function
    (apply define* `((func (,funny-name 32)) (+ ,funny-name 1)))
    ;; (procedure-source func) is (lambda* ((| e t c | 32)) (+ | e t c | 1))
    (apply func (list (symbol->keyword funny-name) 2)))
3

I hope that makes you as happy as it makes me!

The built-in syntactic forms, such as "begin", are almost first-class citizens.

> (let ((progn begin)) 
    (progn 
      (define x 1) 
      (set! x 3) 
      (+ x 4)))
7
> (let ((function lambda)) 
    ((function (a b) (list a b)) 3 4))
(3 4)
> (apply begin '((define x 3) (+ x 2)))
5
> ((lambda (n) (apply n '(((x 1)) (+ x 2)))) let)
3

(define-macro (symbol-set! var val) ; like CL's set
  `(apply set! ,var ',val ()))      ; trailing nil is just to make apply happy — apply*?

(define-macro (progv vars vals . body)
 `(apply (apply lambda ,vars ',body) ,vals))

> (let ((s '(one two)) (v '(1 2))) (progv s v (+ one two)))
3

We can snap together program fragments ("look Ma, no macros!"):

(let* ((x 3) 
       (arg '(x)) 
       (body `((+ ,x x 1)))) 
  ((apply lambda arg body) 12)) ; "legolambda"?

(define (engulph form)
  (let ((body `(let ((L ()))
		 (do ((i 0 (+ i 1)))
		     ((= i 10) (reverse L))
		   (set! L (cons ,form L))))))
    (define function (apply lambda () (list (copy body :readable))))
    (function)))

(let ()
  (define (hi a) (+ a x))
  ((apply let '((x 32)) (list (procedure-source hi))) 12)) ; one function, many closures?

(let ((ctr -1))  ; (enum zero one two) but without using a macro
  (apply begin 
    (map (lambda (symbol) 
           (set! ctr (+ ctr 1)) 
           (list 'define symbol ctr)) ; e.g. '(define zero 0) 
         '(zero one two)))
  (+ zero one two))

But there's a prettier way to implement enum ("transparent-for-each"):

> (define-macro (enum . args)
    `(for-each define ',args (iota (length ',args))))
enum
> (enum a b c) 
#<unspecified>
> b
1

(apply define ...) is similar to CL's set.

> ((apply define-macro '((m a) `(+ 1 ,a))) 3)
4
> ((apply define '((hi a) (+ a 1))) 3)
4

This gives us a way to make anonymous macros, just as lambda returns an anonymous function:

> (define-macro (mu args . body)
  `(apply define-macro '((,(gensym) ,@args) ,@body)))
mu
> ((mu (a) `(+ 1 ,a)) 3)
4
> (define-macro (glambda args) ; returns an anonymous macro that will return a function given a body
    `(define-macro (,(gensym) . body) 
         `(lambda ,',args ,@body)))
glambda
> (let ((gf (glambda (a b))))  ; gf is now ready for any body that involves arguments 'a and 'b
    ((gf (+ a b)) 1 2))        ; apply (lambda (a b) (+ a b)) to '(1 2)
3

catch, dynamic-wind, and many of the other functions that take function arguments in standard Scheme, accept macros in s7.

Apply let is very similar to eval:

> (apply let '((a 2) (b 3)) '((+ a b)))
5
> (eval '(+ a b) (inlet 'a 2 'b 3))
5
> ((apply lambda '(a b) '((+ a b))) 2 3)
5
> (apply let '((a 2) (b 3)) '((list + a b))) ; a -> 2, b -> 3
(+ 2 3)

The redundant-looking double lists are for apply's benefit. We could use a trailing null instead (mimicking apply* in some ancient lisps):

> (apply let '((a 2) (b 3)) '(list + a b) ())
(+ 2 3)

Currently, you can't set! a built-in syntactic keyword to some new value: (set! if 3). I hope this kind of thing is not actually very useful, but let me know if you need it. The issue is purely one of speed.

Speaking of speed... It is widely believed that a Scheme with first class everything can't hope to compete with any "real" Scheme. Humph I say. Take this little example (which is not so misleading that I feel guilty about it):

(define (do-loop n)
  (do ((i 0 (+ i 1)))
      ((= i n))
    (if (zero? (modulo i 1000))
	(display ".")))
  (newline))

(for-each
 (lambda (n) (do-loop n))
 (list 1000 1000000 10000000))

In s7, that takes 0.24 seconds on my home machine. In tinyScheme, from whence we sprang, it takes 85 seconds. In the chicken interpreter, 5.3 seconds, and after compilation (using -O2) of the chicken compiler output, 0.75 seconds. So, s7 is comparable to chicken in speed, even though chicken is compiling to C. I think Guile 2.0.9 takes about 1 second. The equivalent in CL: clisp interpreted 9.3 seconds, compiled 0.85 seconds; sbcl 0.21 seconds.

In s7, there is only one kind of begin statement, and it can contain both definitions and expressions. These are evaluated in the order in which they occur, and in the environment at the point of the evaluation. I think of it as being a little REPL. begin does not introduce a new frame in the current environment, so defines happen in the enclosing environment.

The r7rs compatibility code is in r7rs.scm. I used to include it here, but as r7rs grew, this section got too large. In general, all the conversion routines in r7rs are handled in s7 via generic functions, records are classes, byte-vectors are strings, and so on.

threads

s7 originally had multithreading support, but I removed it in August, 2011. It turned out to be less useful than I hoped, mainly because s7 threads shared the heap and therefore had to coordinate all cell allocations. It was faster and simpler to use multiple processes each running a separate s7 interpreter, rather than one s7 running multiple s7 threads. In CLM, there was also contention for access to the output stream. In GUI-related situations, threads were not useful mainly because the GUI toolkits are not thread safe. Last but not least, the effort to make the non-threaded s7 faster messed up parts of the threaded version. Rather than waste a lot of time fixing this, I chose to flush multithreading. Here's a very simple example of using an s7 interpreter per thread:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include "s7.h"

typedef struct {
  s7_scheme *sc;
  s7_pointer func;
  pthread_t *thread;
} thred;

static void *run_thread(void *obj)
{
  thred *f = (thred *)obj;
  return((void *)s7_call(f->sc, f->func, s7_nil(f->sc)));
}

static thred *make_thread(s7_function func)
{
  thred *f;
  f = (thred *)malloc(sizeof(thred));
  f->sc = s7_init();
  f->func = s7_make_function(f->sc, "a-test", func, 0, 0, false, "a test");
  f->thread = (pthread_t *)malloc(sizeof(pthread_t));
  pthread_create(f->thread, NULL, run_thread, (void *)f);
  return(f);
}

static s7_pointer a_test(s7_scheme *sc, s7_pointer args)
{
  fprintf(stderr, "I am %p\n", sc);
  /* do something time-consuming... */
  return(args);
}

int main(int argc, char **argv)
{
  thred *f1, *f2;
  f1 = make_thread(a_test);
  f2 = make_thread(a_test);

  pthread_join(*(f1->thread), NULL);
  pthread_join(*(f2->thread), NULL);
}

/* build s7 with -DWITH_THREADS, then
 * gcc -o repl repl.c s7.o -g3 -Wl,-export-dynamic -lpthread -lm -I. -ldl 
 */

Unfortunately, there's no way yet to free all the resources s7_init allocates (the heap, stack, etc).

"Life", a poem.

(+(*(+))(*)(+(+)(+)(*)))
(((((lambda () (lambda () (lambda () (lambda () 1))))))))
(+ (((lambda () values)) 1 2 3))
(map apply (list map) (list map) (list (list *)) '((((1 2)) ((3 4 5)))))
(do ((do do do)) (do do do))
(*(*)(*) (+)(+) 1)


FFI examples

s7 exists only to serve as an extension of some other application, so it is primarily a foreign function interface. s7.h has lots of comments about the individual functions. Here I'll collect some complete examples. s7.c depends on the following compile-time flags:

SIZEOF_VOID_P                  8 (default) or 4.
WITH_GMP                       1 if you want multiprecision arithmetic (requires gmp, mpfr, and mpc, default is 0)
HAVE_COMPLEX_NUMBERS           1 if your compiler supports complex numbers
HAVE_COMPLEX_TRIG              1 if your math library has complex versions of the trig functions
DISABLE_DEPRECATED             1 if you want to make sure you're not using any deprecated s7 stuff (default is 0)

WITH_QUASIQUOTE_VECTOR         1 if you want to use the `#(...) junk (defualt is 0)
WITH_IMMUTATBLE_UNQUOTE        1 if you want "unquote" omitted (default is 0)
WITH_EXTRA_EXPONENT_MARKERS    1 if you want "d", "f", "l", and "s" in addition to "e" as exponent markers (default is 0)
                                   if someone defends these exponent markers, ask him to read 1l11+11l1i
WITH_SYSTEM_EXTRAS             1 if you want some additional OS-related functions built-in (default is 0)
WITH_MAIN                      1 if you want s7.c to include a main program section that runs a REPL.
WITH_C_LOADER		       1 if you want to be able to load shared object files with load.

See the comment at the start of s7.c for more information about these switches. s7.h defines the two main number types: s7_int and s7_double. The examples that follow show:

A simple listener

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "s7.h"

int main(int argc, char **argv)
{
  s7_scheme *s7;
  char buffer[512];
  char response[1024];

  s7 = s7_init();                 /* initialize the interpreter */
  while (1)                       /* fire up a read-eval-print loop */
    {
      fprintf(stdout, "\n> ");    /* prompt for input */
      fgets(buffer, 512, stdin);
      if ((buffer[0] != '\n') || 
	  (strlen(buffer) > 1))
	{                         /* evaluate the input and print the result */
	  sprintf(response, "(write %s)", buffer);
	  s7_eval_c_string(s7, response); 
	}
    }
}

/* make mus-config.h (it can be empty), then
 *
 *   gcc -c s7.c -I.
 *   gcc -o repl repl.c s7.o -lm -I. -ldl
 *
 * run it:
 *
 *    repl
 *    > (+ 1 2)
 *    3
 *    > (define (add1 x) (+ 1 x))
 *    add1
 *    > (add1 2)
 *    3
 *    > (exit)
 *
 * for long-term happiness in linux use:
 *   gcc -o repl repl.c s7.o -Wl,-export-dynamic -lm -I. -ldl
 * freebsd:
 *   gcc -o repl repl.c s7.o -Wl,-export-dynamic -lm -I.
 * osx:
 *   gcc -o repl repl.c s7.o -lm -I.
 * openbsd:
 *   gcc -o repl repl.c s7.o -I. -ftrampolines -Wl,-export-dynamic -lm
 */

Since this reads stdin and writes stdout, it can be run as a Scheme subjob of emacs. One (inconvenient) way to do this is to set the emacs variable scheme-program-name to the name of the exectuable created above ("doc7"), then call the emacs function run-scheme: M-x eval-expression in emacs, followed by (setq scheme-program-name "doc7"), then M-x run-scheme, and you're talking to s7 in emacs. Of course, this connection can be customized indefinitely. See, for example, inf-snd.el in the Snd package.

To read stdin while working in a GUI-based program is trickier. In glib/gtk, you can use something like this:

static gboolean read_stdin(GIOChannel *source, GIOCondition condition, gpointer data)
{
  /* here read from g_io_channel_unix_get_fd(source) and call s7_eval_string */
  return(true);
}

/* ... during initialization ... */

GIOChannel *channel;
channel = g_io_channel_unix_new(STDIN_FILENO);  /* watch stdin */
stdin_id = g_io_add_watch_full(channel,         /* and call read_stdin above if input is noticed */
			       G_PRIORITY_DEFAULT, 
			       (GIOCondition)(G_IO_IN | G_IO_HUP | G_IO_ERR), 
			       read_stdin, NULL, NULL);
g_io_channel_unref(channel);
repl with libtecla

Here's a version that uses libtecla for the line editor:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <libtecla.h>
#include "s7.h"

int main(int argc, char **argv)
{
  s7_scheme *s7;
  char *buffer;
  char response[1024];
  GetLine *gl;            /* The tecla line editor */

  gl = new_GetLine(500, 5000);
  s7 = s7_init();  

  while (1) 
    {
      buffer = gl_get_line(gl, "> ", NULL, 0);
      if ((buffer[0] != '\n') || 
	  (strlen(buffer) > 1))
	{                            
	  sprintf(response, "(write %s)", buffer);
	  s7_eval_c_string(s7, response);
	  fprintf(stdout, "\n");
	}
    }
  gl = del_GetLine(gl);
}

/* 
 *   gcc -c s7.c -I. -O2 -g3
 *   gcc -o ex1 ex1.c s7.o -lm -I. -ltecla -ldl
 */

A repl (based on repl.scm) is built into s7. Include the compiler flag -DWITH_MAIN:

in Linux: gcc s7.c -o repl -DWITH_MAIN -I. -O2 -g -ldl -lm -Wl,-export-dynamic
in *BSD:  gcc s7.c -o repl -DWITH_MAIN -I. -O2 -g -lm -Wl,-export-dynamic
in OSX:   gcc s7.c -o repl -DWITH_MAIN -I. -O2 -g -lm
repl in C++

If you prefer C++, here's a C++ version of the listener, extracted from Rick Taube's Common Music package:

#include <iostream>
#include "s7.h"

static s7_pointer main_quit(s7_scheme *sc, s7_pointer args);
static bool is_balanced(std::string str);
static bool is_not_white(std::string str);

int main(int argc, const char* argv[])
{
  s7_scheme* s7 = s7_init();
  s7_pointer val;
  std::string str;

  try 
    {
      while (std::cin)
	{
	  std::cout << "\ns7> ";
	  str = "";
	  while (true)
	    {
	      std::string lin;
	      std::getline(std::cin, lin);
	      str = str + lin + "\n";
	      if (is_balanced(str))
		break;
	    }
	  if (is_not_white(str))
	    {
	      val = s7_eval_c_string(s7, str.c_str());
	      std::cout << s7_object_to_c_string(s7, val);
	    }
	}
    }
  catch(...)
    {
    }
  std::cout << "Bye!\n";
  return 0;
}

static s7_pointer main_quit(s7_scheme *sc, s7_pointer args)
{
  throw 0;
  return(s7_nil(sc));
}

static bool is_balanced(std::string str)
{
  int parens = 0;
  int quotes = 0;
  unsigned i = 0;
  while (i < str.size())
    {
      if (str[i] == ';')
	{
	  for (i = i + 1; i < str.size(); i++)
	    {
	      if (str[i] == '\n')
		break;
	    }
	}
      else if (str[i] == '"')
	{
	  if (i == 0 || str[i - 1] != '\\')
	    {
	      quotes = 1;
	      for (i = i + 1; i < str.size(); i++)
		{
		  if (str[i] == '"' && str[i - 1] != '\\')
		    {
		      quotes = 0;
		      break;
		    }
		}
	      if (quotes)
		return false;
	    }
	}
      else if (str[i] == '(')
	parens++;
      else if (str[i] == ')')
	parens--;
      i++;
    }
  return (parens == 0) && (quotes == 0);
}

static bool is_not_white(std::string str)
{
  for (unsigned i = 0; (i < str.size() && str[i] != ';'); i++)
    if (str[i] != ' ' && str[i] != '\n' && str[i] != '\t')
      return true;
  return false;
}

/* g++ -I. -c repl.cpp
 * g++ -o repl repl.o s7.o -ldl
 */

Common Lisp has something called "evalhook" that makes it possible to insert your own function into the eval loop. In s7, we have a "begin_hook" which sits at the opening of many begin blocks (implicit or explicit). begin_hook is a (C) function; if it sets its bool argument to true, s7 interrupts the current evaluation. Here is a version of the REPL in which begin_hook watches for C-g to interrupt some long computation:

/* terminal-based REPL, 
 *    an expansion of the read-eval-print loop program above.
 * type C-g to interrupt an evaluation.
 */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <termios.h>
#include <signal.h>

#include "s7.h"

static struct termios save_buf, buf;

static void sigcatch(int n)
{
  /* put things back the way they were */
  tcsetattr(fileno(stdin), TCSAFLUSH, &save_buf);
  exit(0);
}

static char buffer[512];
static int type_ahead_point = 0;

static void watch_for_c_g(s7_scheme *sc, bool *all_done)
{
  char c;
  /* watch for C-g without blocking, save other chars as type-ahead */
  tcsetattr(fileno(stdin), TCSAFLUSH, &buf);
  if (read(fileno(stdin), &c, 1) == 1)
    {
      if (c == 7) /* C-g */
	{
	  *all_done = true;
	  type_ahead_point = 0;
	}
      else buffer[type_ahead_point++] = c;
    }
  tcsetattr(fileno(stdin), TCSAFLUSH, &save_buf);
}

int main(int argc, char **argv)
{
  s7_scheme *s7;
  bool use_begin_hook;

  use_begin_hook = (tcgetattr(fileno(stdin), &save_buf) >= 0);
  if (use_begin_hook)
    {
      buf = save_buf;
      buf.c_lflag &= ~ICANON;
      buf.c_cc[VMIN] = 0;
      buf.c_cc[VTIME] = 0;

      signal(SIGINT, sigcatch);
      signal(SIGQUIT, sigcatch);
      signal(SIGTERM, sigcatch);
    }
  s7 = s7_init();  

  if (argc == 2)
    {
      fprintf(stderr, "load %s\n", argv[1]);
      s7_load(s7, argv[1]);
    }
  else
    {
      char response[1024];
      while (1) 
	{
	  fprintf(stdout, "\n> ");
	  fgets((char *)(buffer + type_ahead_point), 512 - type_ahead_point, stdin);
	  type_ahead_point = 0;

	  if ((buffer[0] != '\n') || 
	      (strlen(buffer) > 1))
	    {                            
	      sprintf(response, "(write %s)", buffer);

	      if (use_begin_hook)
		s7_set_begin_hook(s7, watch_for_c_g);
	      s7_eval_c_string(s7, response);
	      if (use_begin_hook)
		s7_set_begin_hook(s7, NULL);
	    }
	}
    }
  if (use_begin_hook)
    tcsetattr(fileno(stdin), TCSAFLUSH, &save_buf);
}

Define a function with arguments and a returned value, and a variable

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "s7.h"

static s7_pointer add1(s7_scheme *sc, s7_pointer args)
{
  /* all added functions have this form, args is a list, 
   *    s7_car(args) is the first arg, etc 
   */
  if (s7_is_integer(s7_car(args)))
    return(s7_make_integer(sc, 1 + s7_integer(s7_car(args))));
  return(s7_wrong_type_arg_error(sc, "add1", 1, s7_car(args), "an integer"));
}

int main(int argc, char **argv)
{
  s7_scheme *s7;
  char buffer[512];
  char response[1024];

  s7 = s7_init();
  
  s7_define_function(s7, "add1", add1, 1, 0, false, "(add1 int) adds 1 to int");
                                      /* add the function "add1" to the interpreter.
                                       *   1, 0, false -> one required arg,
				       *                  no optional args,
				       *                  no "rest" arg
				       */
 s7_define_variable(s7, "my-pi", s7_make_real(s7, 3.14159265));

  while (1)                           /* fire up a "repl" */
    {
      fprintf(stdout, "\n> ");        /* prompt for input */
      fgets(buffer, 512, stdin);
      if ((buffer[0] != '\n') || 
	  (strlen(buffer) > 1))
	{                            
	  sprintf(response, "(write %s)", buffer);
	  s7_eval_c_string(s7, response); /* evaluate input and write the result */
	}
    }
}

/*    doc7
 *    > my-pi
 *    3.14159265
 *    > (+ 1 (add1 1))
 *    3
 *    > (exit)
 */

Call a Scheme-defined function from C, and get/set Scheme variable values in C

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "s7.h"

int main(int argc, char **argv)
{
  s7_scheme *s7;
  s7 = s7_init();

  s7_define_variable(s7, "an-integer", s7_make_integer(s7, 1));
  s7_eval_c_string(s7, "(define (add1 a) (+ a 1))");
  
  fprintf(stderr, "an-integer: %lld\n", 
	  s7_integer(s7_name_to_value(s7, "an-integer")));

  s7_symbol_set_value(s7, s7_make_symbol(s7, "an-integer"), s7_make_integer(s7, 32));

  fprintf(stderr, "now an-integer: %lld\n", 
	  s7_integer(s7_name_to_value(s7, "an-integer")));

  fprintf(stderr, "(add1 2): %lld\n", 
	  s7_integer(s7_call(s7, 
			     s7_name_to_value(s7, "add1"), 
			     s7_cons(s7, s7_make_integer(s7, 2), s7_nil(s7)))));
}

/*
 *    doc7
 *    an-integer: 1
 *    now an-integer: 32
 *    (add1 2): 3
 */

C++ and Juce, from Rick Taube

int main(int argc, const char* argv[]) 
{ 
  initialiseJuce_NonGUI(); 

  s7_scheme *s7 = s7_init(); 
  if (!s7) 
    { 
      std::cout <<  "Can't start S7!\n"; 
      return -1; 
    } 

  s7_pointer val; 
  std::string str; 
  while (true) 
    { 
      std::cout << "\ns7> "; 
      std::getline(std::cin, str); 
      val = s7_eval_c_string(s7, str.c_str()); 
      std::cout << s7_object_to_c_string(s7, val); 
    } 

  free(s7); 
  std::cout << "Bye!\n"; 
  return 0; 
} 

Load sndlib into an s7 repl

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

/* assume we've configured and built sndlib, so it has created a mus-config.h file.
 * also assume we've built s7 with WITH_SYSTEM_EXTRAS set, so we have file-exists? and delete-file
 */

#include "mus-config.h"
#include "s7.h"
#include "xen.h"
#include "clm.h"
#include "clm2xen.h"

/* we need to redirect clm's mus_error calls to s7_error */

static void mus_error_to_s7(int type, char *msg)
{
  s7_error(s7,                               /* s7 is declared in xen.h, defined in xen.c */
	   s7_make_symbol(s7, "mus-error"),
	   s7_cons(s7, s7_make_string(s7, msg), s7_nil(s7)));
}

int main(int argc, char **argv)
{
  char buffer[512];
  char response[1024];

  s7 = s7_init();                     /* initialize the interpreter */
  s7_xen_initialize(s7);              /* initialize the xen stuff (hooks and the xen s7 FFI used by sndlib) */
  Init_sndlib();                      /* initialize sndlib with all the functions linked into s7 */  

  mus_error_set_handler(mus_error_to_s7); /* catch low-level errors and pass them to s7-error */

  while (1)                           /* fire up a "repl" */
    {
      fprintf(stdout, "\n> ");        /* prompt for input */
      fgets(buffer, 512, stdin);

      if ((buffer[0] != '\n') || 
	  (strlen(buffer) > 1))
	{                            
	  sprintf(response, "(write %s)", buffer);
	  s7_eval_c_string(s7, response); /* evaluate input and write the result */
	}
    }
}

/* gcc -o doc7 doc7.c -lm -I. /usr/local/lib/libsndlib.a -lasound -ldl
 *
 *   (load "sndlib-ws.scm")
 *   (with-sound () (outa 10 .1))
 *   (load "v.scm")
 *   (with-sound () (fm-violin 0 .1 440 .1))
 *
 * you might also need -lgsl -lgslcblas -lfftw3
 */

If you built libsndlib.so, it is possible to use it directly in the s7 repl:

repl          ; this is a bare s7 running repl.scm via -DWITH_MAIN=1
loading libc_s7.so
> (load "/home/bil/test/sndlib/libsndlib.so" (inlet 'init_func 's7_init_sndlib))
#t            ; s7_init_sndlib ties all the sndlib functions and variables into s7
> (load "sndlib-ws.scm")
tmpnam
> (set! *clm-player* (lambda (file) (system (format #f "sndplay ~A" file))))
> (load "v.scm")
fm-violin
> (with-sound (:play #t) (fm-violin 0 1 440 .1))
"test.snd"

You can use autoload to load libsndlib when needed:

(define (find-library name)
  (if (or (file-exists? name)
	  (char=? (name 0) #\/))
      name
      (call-with-exit
       (lambda (return)
	 (for-each
	  (lambda (path)
	    (let ((new-name (string-append path "/" name)))
	      (if (file-exists? new-name)
		  (return new-name))))
	  *load-path*)
	 (let ((libs (getenv "LD_LIBRARY_PATH")) ; colon separated directory names
	       (start 0))
	   (do ((colon (char-position #\: libs) (char-position #\: libs start)))
	       ((or (not colon)
		    (let ((new-name (string-append (substring libs start colon) "/" name)))
		      (and (file-exists? new-name)
			   (return new-name)))))
	     (set! start (+ colon 1))))
	 name))))

(autoload 'clm 
  (lambda (e)
    (load (find-library "libsndlib.so") (inlet '(init_func . s7_init_sndlib)))
    (set! *features* (cons 'clm *features*))
    (with-let (rootlet) (define clm #t))
    (load "sndlib-ws.scm")
    (set! *clm-player* (lambda (file) (system (format #f "sndplay ~A" file))))))

and use the repl's vt100 stuff to (for example) post the current begin time as a note list computes:

(define (clm-notehook . args)
  ;; assume second arg is begin time (first is instrument name)
  (when (and (pair? args) 
	     (pair? (cdr args)) 
	     (number? (cadr args)))
    (with-let (sublet (*repl* 'repl-let) :begin-time (cadr args))
      (let ((coords (cursor-coords))
	    (col (floor (/ last-col 2))))
	(let ((str (number->string begin-time)))
	  (format *stderr* "~C[~D;~DH" #\escape prompt-row col)
	  (format *stderr* "~C[K~A"  #\escape (if (> (length str) col) (substring str 0 (- col 1)) str)))
	(format *stderr* "~C[~D;~DH"   #\escape (cdr coords) (car coords))))))

(set! *clm-notehook* clm-notehook)

Add a new Scheme type and a procedure with a setter

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "s7.h"

/* define *listener-prompt* in scheme, add two accessors for C get/set */

static const char *listener_prompt(s7_scheme *sc)
{
  return(s7_string(s7_name_to_value(sc, "*listener-prompt*")));
}

static void set_listener_prompt(s7_scheme *sc, const char *new_prompt)
{
  s7_symbol_set_value(sc, s7_make_symbol(sc, "*listener-prompt*"), s7_make_string(sc, new_prompt));
}

/* now add a new type, a struct named "dax" with two fields, a real "x" and a list "data" */
/*   since the data field is an s7 object, we'll need to mark it to protect it from the GC */

typedef struct {
  s7_double x;
  s7_pointer data;
} dax;

static char *print_dax(s7_scheme *sc, void *val)
{
  char *data_str, *str;
  int data_str_len;
  dax *o = (dax *)val;
  data_str = s7_object_to_c_string(sc, o->data);
  data_str_len = strlen(data_str);
  str = (char *)calloc(data_str_len + 32, sizeof(char));
  snprintf(str, data_str_len + 32, "#<dax %.3f %s>", o->x, data_str);
  free(data_str);
  return(str);
}

static void free_dax(void *val)
{
  if (val) free(val);
}

static bool equal_dax(void *val1, void *val2)
{
  return(val1 == val2);
}

static void mark_dax(void *val)
{
  dax *o = (dax *)val;
  if (o) s7_mark_object(o->data);
}

static int dax_type_tag = 0;

static s7_pointer make_dax(s7_scheme *sc, s7_pointer args)
{
  dax *o;
  o = (dax *)malloc(sizeof(dax));
  o->x = s7_real(s7_car(args));
  if (s7_cdr(args) != s7_nil(sc))
    o->data = s7_cadr(args);
  else o->data = s7_nil(sc);
  return(s7_make_object(sc, dax_type_tag, (void *)o));
}

static s7_pointer is_dax(s7_scheme *sc, s7_pointer args)
{
  return(s7_make_boolean(sc, 
			 s7_is_object(s7_car(args)) &&
			 s7_object_type(s7_car(args)) == dax_type_tag));
}

static s7_pointer dax_x(s7_scheme *sc, s7_pointer args)
{
  dax *o;
  o = (dax *)s7_object_value(s7_car(args));
  return(s7_make_real(sc, o->x));
}

static s7_pointer set_dax_x(s7_scheme *sc, s7_pointer args)
{
  dax *o;
  o = (dax *)s7_object_value(s7_car(args));
  o->x = s7_real(s7_cadr(args));
  return(s7_cadr(args));
}

static s7_pointer dax_data(s7_scheme *sc, s7_pointer args)
{
  dax *o;
  o = (dax *)s7_object_value(s7_car(args));
  return(o->data);
}

static s7_pointer set_dax_data(s7_scheme *sc, s7_pointer args)
{
  dax *o;
  o = (dax *)s7_object_value(s7_car(args));
  o->data = s7_cadr(args);
  return(o->data);
}

int main(int argc, char **argv)
{
  s7_scheme *s7;
  char buffer[512];
  char response[1024];

  s7 = s7_init();
  
  s7_define_variable(s7, "*listener-prompt*", s7_make_string(s7, ">"));

  dax_type_tag = s7_new_type("dax", print_dax, free_dax, equal_dax, mark_dax, NULL, NULL);
  s7_define_function(s7, "make-dax", make_dax, 2, 0, false, "(make-dax x data) makes a new dax");
  s7_define_function(s7, "dax?", is_dax, 1, 0, false, "(dax? anything) returns #t if its argument is a dax object");

  s7_define_variable(s7, "dax-x", 
                     s7_dilambda(s7, "dax-x", dax_x, 1, 0, set_dax_x, 2, 0, "dax x field"));

  s7_define_variable(s7, "dax-data", 
                     s7_dilambda(s7, "dax-data", dax_data, 1, 0, set_dax_data, 2, 0, "dax data field"));

  while (1)
    {
      fprintf(stdout, "\n%s ", listener_prompt(s7));
      fgets(buffer, 512, stdin);
      if ((buffer[0] != '\n') || 
	  (strlen(buffer) > 1))
	{                            
	  sprintf(response, "(write %s)", buffer);
	  s7_eval_c_string(s7, response); /* evaluate input and write the result */
	}
    }
}

/*
 *    > *listener-prompt*
 *    ">"
 *    > (set! *listener-prompt* ":")
 *    ":"
 *    : (define obj (make-dax 1.0 (list 1 2 3)))
 *    obj
 *    : obj
 *    #<dax 1.000 (1 2 3)>
 *    : (dax-x obj)
 *    1.0
 *    : (dax-data obj)
 *    (1 2 3)
 *    : (set! (dax-x obj) 123.0)
 *    123.0
 *    : obj
 *    #<dax 123.000 (1 2 3)>
 *    : (dax? obj)
 *    #t
 *    : (exit)
 */

Redirect output (and input) to a C procedure

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "s7.h"

static void my_print(s7_scheme *sc, unsigned char c, s7_pointer port)
{
  fprintf(stderr, "[%c] ", c);
}

static s7_pointer my_read(s7_scheme *sc, s7_read_t peek, s7_pointer port)
{
  return(s7_make_character(sc, fgetc(stdin)));
}

int main(int argc, char **argv)
{
  s7_scheme *s7;
  char buffer[512];
  char response[1024];

  s7 = s7_init();  

  s7_set_current_output_port(s7, s7_open_output_function(s7, my_print));
  s7_define_variable(s7, "io-port", s7_open_input_function(s7, my_read));

  while (1) 
    {
      fprintf(stdout, "\n> ");
      fgets(buffer, 512, stdin);
      if ((buffer[0] != '\n') || 
	  (strlen(buffer) > 1))
	{                            
	  sprintf(response, "(write %s)", buffer);
	  s7_eval_c_string(s7, response);
	}
    }
}

/* 
 *    > (+ 1 2)
 *    [3]
 *    > (display "hiho")
 *    [h] [i] [h] [o] [#] [<] [u] [n] [s] [p] [e] [c] [i] [f] [i] [e] [d] [>] 
 *    > (define (add1 x) (+ 1 x))
 *    [a] [d] [d] [1] 
 *    > (add1 123)
 *    [1] [2] [4] 
 *    > (read-char io-port)
 *    a                             ; here I typed "a" in the shell
 *    [#] [\] [a] 
 */

Extend a built-in operator ("+" in this case)

There are several ways to do this. In the first example, we save the original function, and replace it with ours, calling the original whenever possible:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "s7.h"

static s7_pointer old_add;           /* the original "+" function for non-string cases */
static s7_pointer old_string_append; /* same, for "string-append" */

static s7_pointer our_add(s7_scheme *sc, s7_pointer args)
{
  /* this will replace the built-in "+" operator, extending it to include strings:
   *   (+ "hi" "ho") -> "hiho" and  (+ 3 4) -> 7
   */
  if ((s7_is_pair(args)) &&
      (s7_is_string(s7_car(args))))
    return(s7_apply_function(sc, old_string_append, args));
  return(s7_apply_function(sc, old_add, args));
}

int main(int argc, char **argv)
{
  s7_scheme *s7;
  char buffer[512];
  char response[1024];
  s7 = s7_init();

  /* get built-in + and string-append */
  old_add = s7_name_to_value(s7, "+");      
  old_string_append = s7_name_to_value(s7, "string-append");

  /* redefine "+" */
  s7_define_function(s7, "+", our_add, 0, 0, true, "(+ ...) adds or appends its arguments");

  while (1)
    {
      fprintf(stdout, "\n> ");
      fgets(buffer, 512, stdin);
      if ((buffer[0] != '\n') || 
	  (strlen(buffer) > 1))
	{                            
	  sprintf(response, "(write %s)", buffer);
	  s7_eval_c_string(s7, response);
	}
    }
}

/*    > (+ 1 2)
 *    3
 *    > (+ "hi" "ho")
 *    "hiho"
 */

In the next example, we use the method (inlet) machinery:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>

#include "s7.h"

static s7_pointer our_abs(s7_scheme *sc, s7_pointer args)
{
  s7_pointer x;
  x = s7_car(args);
  if (!s7_is_number(x))
    {
      s7_pointer method;
      method = s7_method(sc, x, s7_make_symbol(sc, "abs"));
      if (method == s7_undefined(sc))                       /* no method found, so raise an error */
	s7_wrong_type_arg_error(sc, "abs", 1, x, "a real"); 
      return(s7_apply_function(sc, method, args));          /*   else apply the method to the args */
    }
  return(s7_make_real(sc, (s7_double)fabs(s7_number_to_real(sc, x))));
}

int main(int argc, char **argv)
{
  s7_scheme *s7;
  char buffer[512];
  char response[1024];

  s7 = s7_init();
  s7_define_function(s7, "our-abs", our_abs, 1, 0, false, "abs replacement");

  while (1)
    {
      fprintf(stdout, "\n> ");
      fgets(buffer, 512, stdin);
      if ((buffer[0] != '\n') || 
	  (strlen(buffer) > 1))
	{                            
	  sprintf(response, "(write %s)", buffer);
	  s7_eval_c_string(s7, response);
	}
    }
}

/*    > (our-abs -1)
 *    1.0
 *    > (our-abs (openlet (inlet 'value -3.0 'abs (lambda (x) (abs (x 'value))))))
 *    3.0
 */

C-side define* (s7_define_function_star)

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "s7.h"

static s7_pointer plus(s7_scheme *sc, s7_pointer args)
{
  /* (define* (plus (red 32) blue) (+ (* 2 red) blue)) */
  return(s7_make_integer(sc, 2 * s7_integer(s7_car(args)) + s7_integer(s7_cadr(args))));
}

int main(int argc, char **argv)
{
  s7_scheme *s7;
  char buffer[512];
  char response[1024];

  s7 = s7_init();
  s7_define_function_star(s7, "plus", plus, "(red 32) blue", "an example of define* from C");

  while (1)
    {
      fprintf(stdout, "\n> ");
      fgets(buffer, 512, stdin);
      if ((buffer[0] != '\n') || 
	  (strlen(buffer) > 1))
	{                            
	  sprintf(response, "(write %s)", buffer);
	  s7_eval_c_string(s7, response);
	}
    }
}

/* 
 *    > (plus 2 3)
 *    7
 *    > (plus :blue 3)
 *    67
 *    > (plus :blue 1 :red 4)
 *    9
 *    > (plus 2 :blue 3)
 *    7
 *    > (plus :blue 3 :red 1)
 *    5
 */

C-side define-macro (s7_define_macro)

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "s7.h"

static s7_pointer plus(s7_scheme *sc, s7_pointer args)
{
  /* (define-macro (plus a b) `(+ ,a ,b)) */
  s7_pointer a, b;
  a = s7_car(args);
  b = s7_cadr(args);
  return(s7_list(sc, 3, s7_make_symbol(sc, "+"),  a, b));
}

int main(int argc, char **argv)
{
  s7_scheme *s7;
  char buffer[512];
  char response[1024];

  s7 = s7_init();
  s7_define_macro(s7, "plus", plus, 2, 0, false, "plus adds its two arguments");

  while (1)
    {
      fprintf(stdout, "\n> ");
      fgets(buffer, 512, stdin);
      if ((buffer[0] != '\n') || 
	  (strlen(buffer) > 1))
	{                            
	  sprintf(response, "(write %s)", buffer);
	  s7_eval_c_string(s7, response);
	}
    }
}

/* 
 *    > (plus 2 3)
 *    5
 */

define a generic function in C

In scheme, a function becomes generic simply by (apply ((car args) 'func) args). To accomplish the same thing in C, we use s7_method and s7_apply_function:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "s7.h"

static s7_pointer plus(s7_scheme *sc, s7_pointer args)
{
  #define plus_help "(plus obj ...) applies obj's plus method to obj and any trailing arguments."
  s7_pointer obj, method;
  obj = s7_car(args);
  method = s7_method(sc, obj, s7_make_symbol(sc, "plus"));
  if (s7_is_procedure(method))
    return(s7_apply_function(sc, method, args));
  return(s7_f(sc));
}

int main(int argc, char **argv)
{
  s7_scheme *s7;
  s7 = s7_init();
  s7_define_function(s7, "plus", plus, 1, 0, true, plus_help);
  while (1)
    {
      char buffer[512];
      char response[1024];
      fprintf(stdout, "\n> ");
      fgets(buffer, 512, stdin);
      if ((buffer[0] != '\n') || 
	  (strlen(buffer) > 1))
	{                            
	  sprintf(response, "(write %s)", buffer);
	  s7_eval_c_string(s7, response);
	}
    }
}

/* gcc -c s7.c -I.
 * gcc -o ex15 ex15.c s7.o -I. -lm -ldl
 *
 *     > (plus 1 2)
 *     #f
 *     > (define obj (openlet (inlet 'plus (lambda args (apply + 1 (cdr args))))))
 *     obj
 *     > (plus obj 2 3)
 *     6
 */

Signal handling and continuations

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>

#include "s7.h"

static s7_scheme *s7;
struct sigaction new_act, old_act;  
  
static void handle_sigint(int ignored)  
{  
  fprintf(stderr, "interrupted!\n");
  s7_symbol_set_value(s7, s7_make_symbol(s7, "*interrupt*"), s7_make_continuation(s7)); /* save where we were interrupted */
  sigaction(SIGINT, &new_act, NULL);  
  s7_quit(s7);                             /* get out of the eval loop if possible */
}  

static s7_pointer our_sleep(s7_scheme *sc, s7_pointer args)
{
  /* slow down our infinite loop for demo purposes */
  sleep(1);
  return(s7_f(sc));
}

int main(int argc, char **argv)
{
  char buffer[512];
  char response[1024];

  s7 = s7_init();
  s7_define_function(s7, "sleep", our_sleep, 0, 0, false, "(sleep) sleeps");
  s7_define_variable(s7, "*interrupt*", s7_f(s7)); 
  /* Scheme variable *interrupt* holds the continuation at the point of the interrupt */

  sigaction(SIGINT, NULL, &old_act);
  if (old_act.sa_handler != SIG_IGN)
    {
      memset(&new_act, 0, sizeof(new_act));  
      new_act.sa_handler = &handle_sigint;  
      sigaction(SIGINT, &new_act, NULL);  
    }

  while (1)
    {
      fprintf(stderr, "\n> ");
      fgets(buffer, 512, stdin);
      if ((buffer[0] != '\n') || 
	  (strlen(buffer) > 1))
	{                            
	  sprintf(response, "(write %s)", buffer);
	  s7_eval_c_string(s7, response);
	}
    }
}

/*
 *    > (do ((i 0 (+ i 1))) ((= i -1)) (format #t "~D " i) (sleep))
 *      ;;; now type C-C to break out of this loop
 *    0 1 2 ^Cinterrupted!
 *      ;;; call the continuation to continue from where we were interrupted
 *    > (*interrupt*)
 *    3 4 5 ^Cinterrupted!
 *    > *interrupt*
 *    #<continuation>
 *    > (+ 1 2)
 *    3
 */

Multidimensional vector element access

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>

#include "s7.h"

static s7_pointer multivector_ref(s7_scheme *sc, s7_pointer vector, int indices, ...)
{
  /* multivector_ref returns an element of a multidimensional vector */
  int ndims;
  ndims = s7_vector_rank(vector);

  if (ndims == indices)
    {
      va_list ap;
      s7_int index = 0;
      va_start(ap, indices);

      if (ndims == 1)
	{
	  index = va_arg(ap, s7_int);
	  va_end(ap);
	  return(s7_vector_ref(sc, vector, index));
	}
      else
	{
	  int i;
	  s7_pointer *elements;
	  s7_int *offsets, *dimensions;

	  elements = s7_vector_elements(vector);
	  dimensions = s7_vector_dimensions(vector);
	  offsets = s7_vector_offsets(vector);

	  for (i = 0; i < indices; i++)
	    {
	      int ind;
	      ind = va_arg(ap, int);
	      if ((ind < 0) ||
		  (ind >= dimensions[i]))
		{
		  va_end(ap);
		  return(s7_out_of_range_error(sc, 
                                               "multivector_ref", i, 
                                               s7_make_integer(sc, ind), 
                                               "index should be between 0 and the dimension size"));
		}
	      index += (ind * offsets[i]);
	    }
	  va_end(ap);
	  return(elements[index]);
	}
    }
  return(s7_wrong_number_of_args_error(sc, 
                                       "multivector_ref: wrong number of indices: ~A", 
                                       s7_make_integer(sc, indices)));
}

int main(int argc, char **argv)
{
  char buffer[512];
  char response[1024];
  s7_scheme *s7;

  s7 = s7_init(); 
  s7_eval_c_string(s7, "(define vect (make-vector '(2 3 4) 0))");
  s7_eval_c_string(s7, "(set! (vect 1 1 1) 32)");

  fprintf(stdout, "vect[0,0,0]: %s, vect[1,1,1]: %s\n",
	  s7_object_to_c_string(s7, multivector_ref(s7, s7_name_to_value(s7, "vect"), 3, 0, 0, 0)),
	  s7_object_to_c_string(s7, multivector_ref(s7, s7_name_to_value(s7, "vect"), 3, 1, 1, 1)));
}

/* vect[0,0,0]: 0, vect[1,1,1]: 32
 */

Much later... I decided to add s7_vector_ref_n and s7_vector_set_n to s7.

Notification from Scheme that a given Scheme variable has been set

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "s7.h"

static s7_pointer scheme_set_notification(s7_scheme *sc, s7_pointer args)
{
  /* this function is called when the Scheme variable is set! */
  fprintf(stderr, "%s set to %s\n",
	  s7_object_to_c_string(sc, s7_car(args)),
	  s7_object_to_c_string(sc, s7_cadr(args)));
  return(s7_cadr(args));
}

int main(int argc, char **argv)
{
  s7_scheme *s7;
  s7 = s7_init();  

  s7_define_function(s7, "notify-C", scheme_set_notification, 2, 0, false, "called if notified-var is set!");
  s7_define_variable(s7, "notified-var", s7_make_integer(s7, 0));
  s7_symbol_set_access(s7, s7_make_symbol(s7, "notified-var"), s7_name_to_value(s7, "notify-C"));

  if (argc == 2)
    {
      fprintf(stderr, "load %s\n", argv[1]);
      s7_load(s7, argv[1]);
    }
  else
    {
      char buffer[512];
      char response[1024];
      while (1) 
	{
	  fprintf(stdout, "\n> ");
	  fgets(buffer, 512, stdin);
	  
	  if ((buffer[0] != '\n') || 
	      (strlen(buffer) > 1))
	    {                            
	      sprintf(response, "(write %s)", buffer);
	      s7_eval_c_string(s7, response);
	    }
	}
    }
}

/*    > notified-var
 *    0
 *    > (set! notified-var 32)
 *    notified-var set to 32
 *    32
 */

Load C defined stuff into a separate namespace

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "s7.h"

static s7_pointer func1(s7_scheme *sc, s7_pointer args)
{
  return(s7_make_integer(sc, s7_integer(s7_car(args)) + 1));
}

int main(int argc, char **argv)
{
  s7_scheme *s7;
  s7_pointer new_env;

  s7 = s7_init();  

  /* "func1" and "var1" will be placed in an anonymous environment,
   *   accessible from Scheme via the global variable "lib-exports"
   */
  
  new_env = s7_inlet(s7, s7_curlet(s7), s7_nil(s7));
  /* make a private environment for func1 and var1 below (this is our "namespace") */
  s7_gc_protect(s7, new_env);

  s7_define(s7, new_env, 
	    s7_make_symbol(s7, "func1"),
	    s7_make_function(s7, "func1", func1, 1, 0, false, "func1 adds 1 to its argument"));
  
  s7_define(s7, new_env, s7_make_symbol(s7, "var1"), s7_make_integer(s7, 32));
  /* those two symbols are now defined in the new environment */

  /* add "lib-exports" to the global environment */
  s7_define_variable(s7, "lib-exports", s7_let_to_list(s7, new_env));

  if (argc == 2)
    {
      fprintf(stderr, "load %s\n", argv[1]);
      s7_load(s7, argv[1]);
    }
  else
    {
      char buffer[512];
      char response[1024];
      while (1) 
	{
	  fprintf(stdout, "\n> ");
	  fgets(buffer, 512, stdin);
	  
	  if ((buffer[0] != '\n') || 
	      (strlen(buffer) > 1))
	    {                            
	      sprintf(response, "(write %s)", buffer);
	      s7_eval_c_string(s7, response);
	    }
	}
    }
}

/*     > func1
 *     ;func1: unbound variable, line 1
 *     > lib-exports
 *     ((var1 . 32) (func1 . func1))
 *     ;; so lib-exports has the C-defined names and values
 *     ;; we can use these directly:
 *
 *     > (define lib-env (apply sublet (curlet) lib-exports))
 *     lib-env
 *     > (with-let lib-env (func1 var1))
 *     33
 *
 *     ;; or rename them to prepend "lib:"
 *     > (define lib-env (apply sublet 
                                (curlet) 
                                (map (lambda (binding) 
                                       (cons (string->symbol 
                                               (string-append "lib:" (symbol->string (car binding)))) 
                                             (cdr binding))) 
                                     lib-exports)))
 *     lib-env
 *     > (with-let lib-env (lib:func1 lib:var1))
 *     33
 *
 *     ;;; now for convenience, place "func1" in the global environment under the name "func2"
 *     > (define func2 (cdadr lib-exports)) 
 *     func2
 *     > (func2 1)  
 *     2
 */

Handle scheme errors in C

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "s7.h"

static s7_pointer error_handler(s7_scheme *sc, s7_pointer args)
{
  fprintf(stdout, "error: %s\n", s7_string(s7_car(args)));
  return(s7_f(sc));
}

int main(int argc, char **argv)
{
  s7_scheme *s7;
  char buffer[512];
  char response[1024];
  bool with_error_hook = false;

  s7 = s7_init();  
  s7_define_function(s7, "error-handler", error_handler, 1, 0, false, "our error handler");

  if (with_error_hook)
    s7_eval_c_string(s7, "(set! (hook-functions *error-hook*)                    \n\
                            (list (lambda (hook)                                 \n\
                                    (error-handler                               \n\
                                      (apply format #f (hook 'data)))            \n\
                                    (set! (hook 'result) 'our-error))))");
  while (1) 
    {
      fprintf(stdout, "\n> ");
      fgets(buffer, 512, stdin);
	  
      if ((buffer[0] != '\n') || 
	  (strlen(buffer) > 1))
	{                            
	  s7_pointer old_port, result;
	  int gc_loc = -1;
	  const char *errmsg = NULL;

	  /* trap error messages */
	  old_port = s7_set_current_error_port(s7, s7_open_output_string(s7));
	  if (old_port != s7_nil(s7))
	    gc_loc = s7_gc_protect(s7, old_port);

	  /* evaluate the input string */
	  result = s7_eval_c_string(s7, buffer);

	  /* print out the value wrapped in "{}" so we can tell it from other IO paths */
	  fprintf(stdout, "{%s}", s7_object_to_c_string(s7, result));

	  /* look for error messages */
	  errmsg = s7_get_output_string(s7, s7_current_error_port(s7));

	  /* if we got something, wrap it in "[]" */
	  if ((errmsg) && (*errmsg))
	    fprintf(stdout, "[%s]", errmsg); 

	  s7_close_output_port(s7, s7_current_error_port(s7));
	  s7_set_current_error_port(s7, old_port);
	  if (gc_loc != -1)
	    s7_gc_unprotect_at(s7, gc_loc);
	}
    }
}

/* 
 *   gcc -c s7.c -I. -g3
 *   gcc -o ex3 ex3.c s7.o -lm -I. -ldl
 *
 * if with_error_hook is false,
 *
 *   > (+ 1 2)
 *   {3}
 *   > (+ 1 #\c)
 *   {wrong-type-arg}[
 *   ;+ argument 2, #\c, is character but should be a number, line 1
 *   ]
 *
 * so s7 by default prepends ";" to the error message, and appends "\n",
 *   sending that to current-error-port, and the error type ('wrong-type-arg here)
 *   is returned.
 *
 * if with_error_hook is true,
 *
 *   > (+ 1 2)
 *   {3}
 *   > (+ 1 #\c)
 *   error: + argument 2, #\c, is character but should be a number
 *   {our-error}
 *
 * so now the *error-hook* code handles both the error reporting and
 *   the value returned ('our-error in this case).
 */

C and Scheme hooks

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "s7.h"

static s7_pointer my_hook_function(s7_scheme *sc, s7_pointer args)
{
  fprintf(stderr, "a is %s\n", s7_object_to_c_string(sc, s7_symbol_local_value(sc, s7_make_symbol(sc, "a"), s7_car(args))));
  return(s7_car(args));
}

int main(int argc, char **argv)
{
  s7_scheme *s7;
  char buffer[512];
  char response[1024];
  s7_pointer test_hook;

  s7 = s7_init();  

  /* define test_hook in C, test-hook in Scheme, arguments are named a and b */
  test_hook = s7_eval_c_string(s7, "(make-hook 'a 'b)");
  s7_define_constant(s7, "test-hook", test_hook); 

  /* add my_hook_function to the test_hook function list */
  s7_hook_set_functions(s7, test_hook, 
			s7_cons(s7, 
				s7_make_function(s7, "my-hook-function", my_hook_function, 1, 0, false, "my hook-function"), 
				s7_hook_functions(s7, test_hook)));
  while (1) 
    {
      fprintf(stdout, "\n> ");
      fgets(buffer, 512, stdin);
	  
      if ((buffer[0] != '\n') || 
	  (strlen(buffer) > 1))
	{                            
	  sprintf(response, "(write %s)", buffer);
	  s7_eval_c_string(s7, response);
	}
    }
}

/* 
 *    > test-hook
 *    #<lambda (hook)>
 *    > (hook-functions test-hook)
 *    (my-hook-function)
 *    > (test-hook 1 2)
 *    a is 1
 *    #<unspecified>
 */

Load a shared library

We can use dlopen to load a shared library, and dlsym to initialize that library in our main program. The tricky part is to conjure up the right compiler and loader flags. First we define a module that defines a new s7 function, add-1 that we'll tie into s7 explicitly, and another function that we'll try to call by waving a wand.

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "s7.h"

double a_function(double an_arg);
double a_function(double an_arg)
{
  return(an_arg + 1.0);
}

static s7_pointer add_1(s7_scheme *sc, s7_pointer args) 
{
  return(s7_make_integer(sc, s7_integer(s7_car(args)) + 1)); 
}

void init_ex(s7_scheme *sc);
void init_ex(s7_scheme *sc)  /* this needs to be globally accessible (not "static") */
{
  /* tell s7 about add-1, but leave a_function hidden */
  s7_define_function(sc, "add-1", add_1, 1, 0, false, "(add-1 x) adds 1 to x");
}

And here is our main program:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "s7.h"
#include <dlfcn.h>

static void *library = NULL;

static s7_pointer try(s7_scheme *sc, s7_pointer args)
{
  /* try tries to call an arbitrary function in the shared library */
  void *func;
  func = dlsym(library, s7_string(s7_car(args)));
  if (func)
    {
      /* we'll assume double f(double) */
      typedef double (*dl_func)(double arg);
      return(s7_make_real(sc, ((dl_func)func)(s7_real(s7_cadr(args)))));
    }
  return(s7_error(sc, s7_make_symbol(sc, "can't find function"), 
		  s7_list(sc, 2, s7_make_string(sc, "loader error: ~S"), 
			         s7_make_string(sc, dlerror()))));
}

static s7_pointer cload(s7_scheme *sc, s7_pointer args)
{
  /* cload loads a shared library */
  #define CLOAD_HELP "(cload so-file-name) loads the module"
  library = dlopen(s7_string(s7_car(args)), RTLD_LAZY);
  if (library)
    {
      /* call our init func to define add-1 in s7 */
      void *init_func;
      init_func = dlsym(library, s7_string(s7_cadr(args)));
      if (init_func)
	{
	  typedef void *(*dl_func)(s7_scheme *sc);
	  ((dl_func)init_func)(sc);  /* call the initialization function (init_ex above) */
	  return(s7_t(sc));
	}
    }
  return(s7_error(sc, s7_make_symbol(sc, "load-error"), 
		      s7_list(sc, 2, s7_make_string(sc, "loader error: ~S"), 
			             s7_make_string(sc, dlerror()))));
}

int main(int argc, char **argv)
{
  char buffer[512];
  char response[1024];
  s7_scheme *s7;

  s7 = s7_init();  

  s7_define_function(s7, "cload", cload, 2, 0, false, CLOAD_HELP);
  s7_define_function(s7, "try", try, 2, 0, false, 
                         "(try name num) tries to call name in the shared library with the argument num.");

  while (1) 
    {
      fprintf(stdout, "\n> ");
      fgets(buffer, 512, stdin);
	  
      if ((buffer[0] != '\n') || 
	  (strlen(buffer) > 1))
	{                            
	  sprintf(response, "(write %s)", buffer);
	  s7_eval_c_string(s7, response);
	}
    }
}

/* Put the module in the file ex3a.c and the main program in ex3.c, then
 *
 * in Linux:
 *   gcc -c -fPIC ex3a.c
 *   gcc ex3a.o -shared -o ex3a.so
 *   gcc -c s7.c -I. -fPIC -shared
 *   gcc -o ex3 ex3.c s7.o -lm -ldl -I. -Wl,-export-dynamic
 *   # omit -ldl in freeBSD, openBSD might want -ftrampolines
 *
 * in Mac OSX:
 *   gcc -c ex3a.c
 *   gcc ex3a.o -o ex3a.so -dynamic -bundle -undefined suppress -flat_namespace
 *   gcc -c s7.c -I. -dynamic -bundle -undefined suppress -flat_namespace
 *   gcc -o ex3 ex3.c s7.o -lm -ldl -I.
 *
 * and run it:
 *   ex3
 *   > (cload "/home/bil/snd-16/ex3a.so" "init_ex")
 *   #t
 *   > (add-1 2)
 *   3
 *   > (try "a_function" 2.5)
 *   3.5
 */

All of this is just boring boilerplate, so with a little support from s7, we can write a script to do the entire linkage. The s7 side is an extension to "load" that loads a shared object file if its extension is "so", and runs an initialization function whose name is defined in the load environment (the optional second argument to load). An example of the scheme side is cload.scm, included in the s7 tarball. It defines a function that can be called:

(c-define '(double j0 (double)) "m" "math.h")

This links the s7 function m:j0 to the math library function j0. See cload.scm for more details.

Bignums in C

Bignum support depends on gmp, mpfr, and mpc. In this example, we define "add-1" which adds 1 to any kind of number. The s7_big_* functions return the underlying gmp/mpfr/mpc pointer, so we have to copy that into a new number before adding.

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include <gmp.h>
#include <mpfr.h>
#include <mpc.h>

#include "s7.h"

static s7_pointer big_add_1(s7_scheme *sc, s7_pointer args)
{
  /* add 1 to either a normal number or a bignum */
  s7_pointer x;
  x = s7_car(args);
  if (s7_is_bignum(x))
    {
      s7_pointer n;
      if (s7_is_integer(x))
	{
	  mpz_t *big_n;
	  n = s7_make_big_integer(sc, s7_big_integer(x)); /* copy x */
	  big_n = s7_big_integer(n);                      /* get mpz_t pointer of copy */
	  mpz_add_ui(*big_n, *big_n, 1);                  /* add 1 to that */
	  return(n);                                      /* return the new bignum */
	}
      if (s7_is_ratio(x))
	{
	  mpq_t *big_q;
	  mpz_t num, den;
	  n = s7_make_big_ratio(sc, s7_big_ratio(x));
	  big_q = s7_big_ratio(n);
	  mpz_init_set(num, mpq_numref(*big_q));
	  mpz_init_set(den, mpq_denref(*big_q));
	  mpz_add(num, num, den);
	  mpq_set_num(*big_q, num);
	  mpz_clear(num);
	  mpz_clear(den);
	  return(n);
	}
      if (s7_is_real(x))
	{
	  mpfr_t *big_x;
	  n = s7_make_big_real(sc, s7_big_real(x));
	  big_x = s7_big_real(n);
	  mpfr_add_ui(*big_x, *big_x, 1, GMP_RNDN);
	  return(n);
	}
      /* x must be big complex */
      {
	mpc_t *big_z;
	n = s7_make_big_complex(sc, s7_big_complex(x));
	big_z = s7_big_complex(n);
	mpc_add_ui(*big_z, *big_z, 1, MPC_RNDNN);
	return(n);
      }
    }
  else
    {
      if (s7_is_integer(x))
	return(s7_make_integer(sc, 1 + s7_integer(x)));
      if (s7_is_rational(x))
	return(s7_make_ratio(sc, s7_numerator(x) + s7_denominator(x), s7_denominator(x)));
      if (s7_is_real(x))
	return(s7_make_real(sc, 1.0 + s7_real(x)));
      if (s7_is_complex(x))
	return(s7_make_complex(sc, 1.0 + s7_real_part(x), s7_imag_part(x)));
    }
  return(s7_wrong_type_arg_error(sc, "add-1", 0, x, "a number"));
}

int main(int argc, char **argv)
{
  s7_scheme *s7;
  char buffer[512];
  char response[1024];

  s7 = s7_init();  
  s7_define_function(s7, "add-1", big_add_1, 1, 0, false, "(add-1 num) adds 1 to num");

  while (1) 
    {
      fprintf(stdout, "\n> ");
      fgets(buffer, 512, stdin);
      if ((buffer[0] != '\n') || 
	  (strlen(buffer) > 1))
	{                            
	  sprintf(response, "(write %s)", buffer);
	  s7_eval_c_string(s7, response);
	}
    }
}

/* 
 *   gcc -DWITH_GMP=1 -c s7.c -I. -O2 -g3
 *   gcc -DWITH_GMP=1 -o ex2 ex2.c s7.o -I. -O2 -lm -ldl -lgmp -lmpfr -lmpc
 *
 *   ex2
 *   > (add-1 1)   
 *   2
 *   > (add-1 2/3)
 *   5/3
 *   > (add-1 1.4) 
 *   2.4
 *   > (add-1 1.5+i)
 *   2.5+1i
 *   > (add-1 (bignum "3"))
 *   4          ; this is the bignum 4
 *   > (add-1 (bignum "3/4"))
 *   7/4
 *   > (add-1 (bignum "1.4"))
 *   2.399999999999999911182158029987476766109E0
 *   > (add-1 (bignum "1.5+i"))
 *   2.500E0+1.000E0i
 */

glistener.c

glistener.c is a gtk-based repl. It is not specific to s7: Snd uses it as its Forth and Ruby listener as well as for s7. Here's a short example:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>

#include <gtk/gtk.h>

#include "s7.h"
#include "glistener.h"

static s7_scheme *s7;

static gint quit_repl(GtkWidget *w, GdkEvent *event, gpointer context) {exit(0);}

static void evaluator(glistener *g, const char *text)
{
  /* this sends "text" to s7 for evaluation, then displays the result */
  int gc_loc;
  s7_pointer old_port, result;
  const char *errmsg = NULL;
  char *msg = NULL;
  
  old_port = s7_set_current_error_port(s7, s7_open_output_string(s7));
  gc_loc = s7_gc_protect(s7, old_port);
  
  result = s7_eval_c_string(s7, text);
  errmsg = s7_get_output_string(s7, s7_current_error_port(s7));
  if ((errmsg) && (*errmsg))
    {
      msg = (char *)calloc(strlen(errmsg) + 1, sizeof(char));
      strcpy(msg, errmsg);
    }
  
  s7_close_output_port(s7, s7_current_error_port(s7));
  s7_set_current_error_port(s7, old_port);
  s7_gc_unprotect_at(s7, gc_loc);
  
  glistener_append_text(g, "\n");
  if (msg)                      /* some error occurred during evaluation */
    glistener_append_text(g, msg);
  else 
    {                           /* evaluation produced an s7 object which we need to display */
      msg = s7_object_to_c_string(s7, result);
      glistener_append_text(g, msg);
    }
  if (msg) free(msg);
  glistener_append_prompt(g);  /* prompt for more input */
}

static void listener_init(glistener *g, GtkWidget *w)
{
  /* this is the glistener initialization function. "w" above is the new text-view widget,
   *   "g" is the new glistener pointer, passed to any function that wants to talk to this
   *   listener. 
   */
  unsigned char prompt[4] = {0xce, 0xbb, '>', '\0'}; /* lambda as prompt */
  GtkTextBuffer *buffer;

  buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(w));
  glistener_set_font(g, pango_font_description_from_string("Monospace 10"));

  /* our prompt will be a red lambda */
  glistener_set_prompt_tag(g, gtk_text_buffer_create_tag(buffer, "glistener_prompt_tag", 
							 "weight", PANGO_WEIGHT_BOLD, 
							 "foreground", "red",
							 NULL));
  glistener_set_prompt(g, prompt);
}

static const char *helper(glistener *g, const char *text)
{
  /* this function is called whenever the listener thinks help is needed.
   *   Any string it returns is posted in the listener statusbar.
   */
  s7_pointer sym;
  sym = s7_symbol_table_find_name(s7, text);
  if (sym)
    return(s7_help(s7, sym));
  glistener_clear_status(g);
  return(NULL);
}

static void completer(glistener *g, bool (*symbol_func)(const char *symbol_name, void *data), void *data)
{
  /* this function is called when <tab> is typed after a partial symbol name. 
   *   "symbol_func" above should be called on each member of the symbol-table, passing it
   *   the symbol name (as a string) and the data passed as "completer's" third argument.
   *   If symbol_func returns true, it is done, so the loop through the symbol-table can stop.
   */
  s7_for_each_symbol_name(s7, symbol_func, data);
}

int main(int argc, char **argv)
{
  GtkWidget *shell, *frame;
  glistener *g;

  s7 = s7_init();  

  gtk_init(&argc, &argv);
  shell = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  g_signal_connect(G_OBJECT(shell), "delete_event", G_CALLBACK(quit_repl), NULL);

  frame = gtk_frame_new(NULL);
  gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN);
  gtk_widget_show(frame);

  gtk_container_add(GTK_CONTAINER(shell), frame);

  /* make a new listener */
  g = glistener_new(frame, listener_init);
  glistener_set_evaluator(g, evaluator);
  glistener_set_helper(g, helper);
  glistener_set_completer(g, completer);

  gtk_widget_show(shell);
  gdk_window_resize(gtk_widget_get_window(shell), 400, 200);
  gtk_main();
}

/* in gtk-2: gcc gcall.c -o gcall s7.o glistener.o `pkg-config --libs gtk+-2.0 --cflags` -lm -ldl
 * in gtk-3: gcc gcall.c -o gcall s7.o glistener.o `pkg-config --libs gtk+-3.0 --cflags` -lm -ldl
 */
λ> (define λ lambda)
λ
λ> ((λ (a b) (+ a b)) 1 2)
3
λ> 

The five or six functions supplied by the caller (evaluator, helper, completer, checker, colorizer, keyer) all have defaults, so you don't have to supply anything but an evaluator. The default evaluator just prints "?" and prompts for more input. See glistener.h for the full API and an earnest attempt at helpful documentation.

A multi-listener test program is the Snd file tools/gcall.c which is used by tools/gtest.scm for regression testing. One way to name unicode characters is: (define-constant |lambda| #u8(#xce #xbb)). This can be embedded in an ordinary s7 string with any string operation: (string-append |lambda| "ambda") which returns "λambda". (string-length will still return the number of bytes; to get the number of characters in a case like this, use g_utf8_strlen). So, to set the prompt to be a red lambda and the font to be "Nimbus mono 10" from Scheme, assuming we have the usual Scheme-to-C linkages (see snd-glistener.c):

(set! (listener-prompt) (byte-vector #xce #xbb (char->integer #\>) (char->integer #\space)))
(set! (listener-font) "Nimbus mono 10")
(listener-set-prompt-tag *listener* ; ideally this too would be a setter
  (gtk_text_buffer_create_tag 
    (GTK_TEXT_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (listener-text-widget *listener*))))
    "" (list "weight" PANGO_WEIGHT_BOLD "foreground" "red")))

In Snd, all the gtk code is in the *gtk* environment, so we need to use:

(listener-set-prompt-tag *listener*
  (with-let (sublet *gtk* 'textw (listener-text-widget *listener*)) ; use *gtk*
    (gtk_text_buffer_create_tag 
      (GTK_TEXT_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW textw)))
      "" (list "weight" PANGO_WEIGHT_BOLD "foreground" "red"))))

gdb

It is possible to make a mistake while writing C code. I switched from Common Lisp to Scheme a long time ago partly because it was so painful to debug FFI troubles in Common Lisp, and I chose Guile at that time partly because I thought gdb would have native support for it. As far as I know it is still impossible to debug CL FFI troubles, 20 years later! And in gdb Python has muscled Guile aside. Anyway, say you have hit a segfault and find yourself staring at a stackful of opaque pointers. Print statements are your friend, of course, and at the gdb command level, the main one in this context is s7_object_to_c_string. Here are some commands (intended for your .gdbinit file) that can speed up the process. They assume the s7_scheme pointer is named "sc". (These are now included in the gdbinit file in the s7 tarball).

define s7print
print s7_object_to_c_string(sc, $arg0)
end
document s7print
interpret the argument as an s7 value and display it
end
# the current expression is sc->cur_code
# the current environment is sc->envir
# the error environment is sc->owlet
# so for example, to see the current local variables, s7p sc->envir

define s7eval
print s7_object_to_c_string(sc, s7_eval_c_string(sc, $arg0))
end
document s7eval
eval the argument (a string)
end

define s7stack
print s7_object_to_c_string(sc, s7_stacktrace(sc))
end
document s7stack
display the current stack
end

define s7value
print s7_object_to_c_string(sc, s7_name_to_value(sc, $arg0))
end
document s7value
print the value of the variable passed by its print name: s7v "*features*"
end

gdbinit also has s7cell to decode every field of an s7_pointer, and two backtrace decoders: s7bt and s7btfull (heh heh). The bt replacements print the gdb backtrace info, replacing bare pointer numbers with their s7 value, wherever possible:

#1  0x000000000042104e in find_symbol_unchecked (sc=0x97edf0, symbol=vars) at s7.c:6677
        x = (inlet 'f import-lambda-definition-2)
        __FUNCTION__ = "find_symbol_unchecked"
#2  0x00000000006e3424 in eval (sc=0x97edf0, first_op=9) at s7.c:63673
        _x_ = import-lambda-definition-2
        _slot_ = 'form import-lambda-definition-2
        _sym_ = env
        _val_ = import-lambda-definition-2
        args = (vars)
        p = (env)
        func = lint-walk
        e = (inlet 'name import-lambda-definition-2 'form import-lambda-definition-2)
        code = (lint-walk name f vars)
        __FUNCTION__ = "eval"


s7 examples

The s7 tarball includes several scheme files including s7test.scm, lint.scm, cload.scm, write.scm, mockery.scm, and stuff.scm. s7test.scm is a regression test for s7, lint.scm is the s7 equivalent of the ancient C program named lint (modern equivalent: cppcheck), write.scm has a pretty printer, mockery.scm has mock data libraries, cload.scm is a wrapper for the FFI stuff described above, and stuff.scm is just some arbitrary stuff. gdbinit has some gdb commands for s7. repl.scm is a repl.

lint.scm

lint tries to find errors or infelicities in your scheme code. To try it:

(load "lint.scm")
(lint "some-code.scm")

lint tries to reduce false positives, so its default behavior is somewhat laconic. There are several variables at the start of lint.scm to control additional output:

*report-unused-parameters*           ; if #t, report unused function/macro parameters
*report-unused-top-level-functions*  ; if #t, report unused functions
*report-undefined-variables*         ; if #t, report undefined identifiers
*report-shadowed-variables*          ; if #t, report function parameters that are shadowed
*report-minor-stuff*                 ; if #t, report all sorts of other stuff

lint is not smart about functions defined outside the current file, so *report-undefined-variables* sometimes gets confused. *report-minor-stuff* adds output about overly complicated boolean and numerical expressions, dangerous floating point operations, and whatever else it thinks is odd.

Also in lint.scm is html-lint. It reads an HTML file looking for Scheme code. If any is found, it runs s7 and then lint over it, reporting troubles.

cload.scm

cload.scm defines the macro c-define that reduces the overhead involved in (dynamically) linking C entities into s7.

(c-define c-info (prefix "") (headers ()) (cflags "") (ldflags "") output-name)

For example, (c-define '(double j0 (double)) "m" "math.h") links the C math library function j0 into s7 under the name m:j0, passing it a double argument and getting a double result (a real in s7).

prefix is some arbitrary prefix that you want prepended to various names.

headers is a list of headers (as strings) that the c-info relies on, (("math.h") for example).

cflags are any special C compiler flags that are needed ("-I." in particular), and ldflags is the similar case for the loader. output-name is the name of the output C file and associated library. It defaults to "temp-s7-output" followed by a number. In libm.scm, it is set to "libm_s7" to protect it across cload calls. If cload finds an up-to-date output C file and shared library, it simply loads the library, rather than going through all the trouble of writing and compling it.

c-info is a list that describes the C entities that you want to load into s7. It can be either one list describing one entity, or a list of such lists. Each description has the form:

(return-type entity-name-in-C (argument-type...))

where each entry is a symbol, and C names are used throughout. So, in the j0 example above, (double j0 (double)) says we want access to j0, it returns a C double, and it takes one argument, also a C double. s7 tries to figure out what the corresponding s7 type is, but in tricky cases, you should tell it by replacing the bare type name with a list: (C-type underlying-C-type). For example, the Snd function set_graph_style takes an (enum) argument of type graph_style_t. This is actually an int, so we use (graph_style_t int) as the type:

(void set_graph_style ((graph_style_t int)))

If the C entity is a constant, then the descriptor list has just two entries, the C-type and the entity name: (int F_OK) for example. The entity name can also be a list:

((graph_style_t int) (GRAPH_LINES GRAPH_DOTS GRAPH_FILLED GRAPH_DOTS_AND_LINES GRAPH_LOLLIPOPS))

This defines all the names in the list as integers. If the C type has a space ("struct tm*"), use (symbol "struct tm*") to construct the corresponding symbol.

The entity is placed in the current s7 environment under the name (string-append prefix ":" name) where the ":" is omitted if the prefix is null. So in the j0 example, we get in s7 the function m:j0. c-define returns #t if it thinks the load worked, and #f otherwise.

There are times when the only straightforward approach is to write the desired C code directly. To insert C code on the fly, use (in-C "code..."). Two more such cases that come up all the time: C-function for linkage to functions written directly in s7 style using in-C, and C-macro for macros in the C header file that need to be wrapped in #ifdefs. Here are some examples:

;;; various math library functions
(c-define '((double j0 (double)) 
            (double j1 (double)) 
            (double erf (double)) 
            (double erfc (double))
            (double lgamma (double)))
          "m" "math.h")


;;; getenv and setenv
(c-define '(char* getenv (char*)))
(c-define '(int setenv (char* char* int)))


;;; file-exists? and delete-file
(define file-exists? (let () ; define F_OK and access only within this let
                       (c-define '((int F_OK) (int access (char* int))) "" "unistd.h") 
                       (lambda (arg) (= (access arg F_OK) 0))))

(define delete-file (let () 
                      (c-define '(int unlink (char*)) "" "unistd.h") 
                      (lambda (file) (= (unlink file) 0)))) ; 0=success


;;; examples from Snd:
(c-define '(char* version_info ()) "" "snd.h" "-I.")

(c-define '(mus_float_t mus_degrees_to_radians (mus_float_t)) "" "snd.h" "-I.")

(c-define '(snd_info* any_selected_sound ()) "" "snd.h" "-I.")
(c-define '(void select_channel (snd_info* int)) "" "snd.h" "-I.")

(c-define '(((graph_style_t int) (GRAPH_LINES GRAPH_DOTS GRAPH_FILLED GRAPH_DOTS_AND_LINES GRAPH_LOLLIPOPS)) 
            (void set_graph_style ((graph_style_t int)))) 
          "" "snd.h" "-I.")
   

;;; getcwd, strftime
(c-define '(char* getcwd (char* size_t)) "" "unistd.h")

(c-define (list '(void* calloc (size_t size_t))
	        '(void free (void*))
	        '(void time (time_t*)) ; ignore returned value
	        (list (symbol "struct tm*") 'localtime '(time_t*))
                (list 'size_t 'strftime (list 'char* 'size_t 'char* (symbol "struct tm*"))))
          "" "time.h")

> (let ((p (calloc 1 8)) 
        (str (make-string 32)))
    (time p) 
    (strftime str 32 "%a %d-%b-%Y %H:%M %Z" (localtime p))
    (free p) 
    str)
"Sat 11-Aug-2012 08:55 PDT\x00      "


;;; opendir, read_dir, closedir
(c-define '((int closedir (DIR*))
	    (DIR* opendir (char*))
	    (in-C "static char *read_dir(DIR *p)  \
                   {                              \
                     struct dirent *dirp;          \
                     dirp = readdir(p);            \
                     if (!dirp) return(NULL);      \
                     return(dirp->d_name);         \
                   }")
	    (char* read_dir (DIR*)))
  "" '("sys/types.h" "dirent.h"))

(let ((dir (opendir "/home/bil/gtk-snd")))
  (do ((p (read_dir dir) (read_dir dir)))
      ((= (length p) 0))
    (format *stderr* "~A " p))
  (closedir dir))

For the simple cases above, include "-ldl -Wl,-export-dynamic" in the gcc command. So the first FFI example is built (this is in Linux):

gcc -c s7.c -I.
gcc -o ex1 ex1.c s7.o -lm -I. -ldl -Wl,-export-dynamic
ex1
> (load "cload.scm")
c-define-1
> (c-define '(double j0 (double)) "m" "math.h")
#t
> (m:j0 0.5)
0.93846980724081

See also r7rs.scm, libc.scm, libgsl.scm, libm.scm, libdl.scm, and libgdbm.scm. libutf8proc.scm exists, but I have not tested it at all.

(require libc.scm)

(define (copy-file in-file out-file)
  (with-let (sublet *libc* :in-file in-file :out-file out-file)

    ;; the rest of the function body exists in the *libc* environment, with the
    ;;   function parameters in-file and out-file imported, so, for example,
    ;;   (open ...) below calls the libc function open.  

    (let ((infd (open in-file O_RDONLY 0)))
      (if (= infd -1)
	  (error 'io-error "can't find ~S~%" in-file)
	  (let ((outfd (creat out-file #o666)))
	    (if (= outfd -1)
		(begin
		  (close infd)
		  (error 'io-error "can't open ~S~%" out-file))
		(let* ((BUF_SIZE 1024)
                       (buf (malloc BUF_SIZE)))
		  (do ((num (read infd buf BUF_SIZE) (read infd buf BUF_SIZE)))
		      ((or (<= num 0)
			   (not (= (write outfd buf num) num)))))
		  (close outfd)
		  (close infd)
		  (free buf)
		  out-file)))))))

(define (glob->list pattern)
  (with-let (sublet *libc* :pattern pattern)
    (let ((g (glob.make))) 
      (glob pattern 0 g) 
      (let ((res (glob.gl_pathv g))) 
	(globfree g) 
	res))))

;; now (load "*.scm") is (for-each load (glob->list "*.scm")) 
(require libgsl.scm)

(define (eigenvalues M)
  (with-let (sublet *libgsl* :M M)
    (let* ((len (sqrt (length M)))
	   (gm (gsl_matrix_alloc len len))
	   (m (float-vector->gsl_matrix M gm))
	   (evl (gsl_vector_complex_alloc len))
	   (evc (gsl_matrix_complex_alloc len len))
	   (w (gsl_eigen_nonsymmv_alloc len)))
      
      (gsl_eigen_nonsymmv m evl evc w)
      (gsl_eigen_nonsymmv_free w)
      (gsl_eigen_nonsymmv_sort evl evc GSL_EIGEN_SORT_ABS_DESC)
      
      (let ((vals (make-vector len)))
	(do ((i 0 (+ i 1)))
	    ((= i len))
	  (set! (vals i) (gsl_vector_complex_get evl i)))
	(gsl_matrix_free gm)
	(gsl_vector_complex_free evl)
	(gsl_matrix_complex_free evc)
	vals))))

We can use gdbm (or better yet, mdb), the :readable argument to object->string, and the fallback methods in the environments to create name-spaces (lets) with billions of thread-safe local variables, which can be saved and communicated between s7 runs:

(require libgdbm.scm)

(with-let *libgdbm*

  (define *db* 
    (openlet 
     (inlet :file (gdbm_open "test.gdbm" 1024 GDBM_NEWDB #o664 
		    (lambda (str) (format *stderr* "gdbm error: ~S~%" str)))

	    :let-ref-fallback (lambda (obj sym)
				(eval-string (gdbm_fetch (obj 'file) (symbol->string sym))))
	    
	    :let-set!-fallback (lambda (obj sym val)
				 (gdbm_store (obj 'file)
					     (symbol->string sym)
					     (object->string val :readable)
					     GDBM_REPLACE)
				 val)
	    
	    :make-iterator (lambda (obj)
			     (let ((key #f)
				   (length (lambda (obj) (expt 2 20))))
			       (#_make-iterator
                                (let ((iterator? #t))
				  (openlet 
				   (lambda ()
				     (if key
				         (set! key (gdbm_nextkey (obj 'file) (cdr key)))
				         (set! key (gdbm_firstkey (obj 'file))))
				     (if (pair? key)
				         (cons (string->symbol (car key))
					       (eval-string (gdbm_fetch (obj 'file) (car key))))
				         key))))))))))

  (set! (*db* 'str) "123") ; add a variable named 'str with the value "123"
  (set! (*db* 'int) 432)

  (with-let *db* 
    (+ int (length str)))    ; -> 435
  (map values *db*)          ; -> '((str . "123") (int . 432))

  (gdbm_close (*db* 'file)))

repl.scm

repl.scm implements a repl using vt100 codes and libc.scm. It includes symbol and filename completion, a history buffer, paren matching, indentation, multi-line edits, and a debugger window. To move around in the history buffer, use M-p, M-n or M-. (C-p and C-n are used to move the cursor in the current expression). You can change the keymap or the prompt; all the repl functions are accessible through the *repl* environment. One field is 'repl-let which gives you access to all the repl's internal variables and functions. Another is 'top-level-let, normally (sublet (rootlet)), which is the environment in which the repl's evaluation takes place. You can reset the repl back to its starting point with: (set! (*repl* 'top-level-let) (sublet (rootlet))). You can save the current repl state via ((*repl* 'save-repl)), and restore it later via ((*repl* 'restore-repl)). The repl's saved state is in the file save.repl, or the filename can be passed as an argument to save-repl and restore-repl. The special symbol '** holds the last value.

Meta keys are a problem on the Mac. You can use ESC instead, but that requires super-human capacities. I stared at replacement control keys, and nothing seemed right. I don't know how to remap these commands, but it's easy to do: see repl.scm which has a small table of mappings, and try out your own.

To run the repl, either build s7 with the compiler flag -DWITH_MAIN, or conjure up a wrapper:

#include "s7.h"

int main(int argc, char **argv)
{
  s7_scheme *sc;
  sc = s7_init();
  s7_load(sc, "repl.scm");
  s7_eval_c_string(sc, "((*repl* 'run))");
  return(0);
}

/* gcc -o r r.c s7.o -Wl,-export-dynamic -lm -I. -ldl
 */

Besides evaluating s7 expressions, like any repl, you can also type shell commands just as in a shell:

> pwd
/home/bil/cl
> cd ..
/home/bil
> date
Wed 15-Apr-2015 17:32:24 PDT
> **
"Wed 15-Apr-2015 17:32:24 PDT
"

In most cases, these are handled through *unbound-variable-hook*, checked using "command -v", then passed to the underlying shell via the system function. If s7's (as opposed to libc's) system command is accessible, the '** variable holds whatever the command printed.

The prompt is set by the function (*repl* 'prompt). It gets one argument, the current line number, and should set the prompt string and its length.

(set! (*repl* 'prompt) (lambda (num) 
			 (with-let (*repl* 'repl-let)
			   (set! prompt-string "scheme> ") 
			   (set! prompt-length (length prompt-string)))))

or, to use the red lambda example mentioned earlier:

(set! (*repl* 'prompt)
      (lambda (num)
	(with-let (*repl* 'repl-let)
	  (set! prompt-string (bold (red (string #\xce #\xbb #\> #\space))))
	  (set! prompt-length 3)))) ; until we get unicode length calc

The line number provides a quick way to move around in the history buffer. To get a previous line without laboriously typing M-p over and over, simply type the line number (without control or meta bits), then M-.

Here is an example of adding to the keymap:

(set! ((*repl* 'keymap) (integer->char 17)) ; C-q to quit and return to caller
      (lambda (c)
	(set! ((*repl* 'repl-let) 'all-done) #t)))

To access the meta keys (in the keymap), use a string: ((*repl* 'keymap) (string #\escape #\p)); this is Meta-p which normally accesses the history buffer.

You can call the repl from other code, poke around in the current environment (or whatever), then return to the caller:

(load "repl.scm")

(define (drop-into-repl e)
  (let ((C-q (integer->char 17)))              ; we'll use the C-q example above to get out
    (let ((old-C-q ((*repl* 'keymap) C-q))
	  (old-top-level (*repl* 'top-level-let)))
      (dynamic-wind
	  (lambda ()
	    (set! (*repl* 'top-level-let) e)
	    (set! ((*repl* 'keymap) C-q)       
		  (lambda (c)
		    (set! ((*repl* 'repl-let) 'all-done) #t))))
	  (lambda ()
	    ((*repl* 'run)))                   ; run the repl
	  (lambda ()
	    (set! (*repl* 'top-level-let) old-top-level)
	    (set! ((*repl* 'keymap) C-q) old-C-q))))))

(let ((x 32))
  (format *stderr* "x: ~A~%" x)
  (drop-into-repl (curlet))
  (format *stderr* "now x: ~A~%" x))

Now load that code and:

x: 32
> x
32
> (set! x 91)
91
> x
91
> now x: 91  ; here I typed C-q at the prompt

Another possibility:

(set! (hook-functions *error-hook*) 
      (list (lambda (hook) 
              (apply format *stderr* (hook 'data)) 
              (newline *stderr*)
	      (drop-into-repl (owlet)))))

See the end of repl.scm for more examples.

snd-16.1/singer.scm0000644000076400007640000007550612616740310012343 0ustar bilbil;;; Perry Cook's physical model of the vocal tract as described in: ;;; ;;; Cook, Perry R. "Synthesis of the Singing Voice Using a Physically Parameterized Model of the Human Vocal Tract" ;;; Published in the Proceedings of the International Computer Music Conference, Ohio 1989 ;;; and as Stanford University Department of Music Technical Report Stan-M-57, August 1989. ;;; ;;; ---- "Identification of Control Parameters in an Articulatory Vocal Tract Model, with Applications ;;; to the Synthesis of Singing," Ph.D. Thesis, Stanford University Department of Music Technical Report ;;; Stan-M-68, December 1990. ;;; ;;; ---- "SPASM, a Real-time Vocal Tract Physical Model Controller; and Singer, the Companion Software ;;; Synthesis System", Computer Music Journal, vol 17 no 1 Spring 1993. ;;; ;;; This code is a translation of Perry Cook's singer implementation originally in C. ;;; Apparently all Perry's data is aimed at srate=22050. ;;; ;;; translated from CLM singer.ins (provide 'snd-singer.scm) (if (provided? 'snd) (require snd-ws.scm) (require sndlib-ws.scm)) (define two-pi (* 2 pi)) (definstrument (singer beg amp data) ;; data is a list of lists very similar to the sequence of synthesize calls in Perry's original implementation. ;; Each imbedded list has the form: dur shape glot pitch glotamp noiseamps vibramt. ;; See below for examples. (let* ((setup (car data)) (durs (map car data)) (dur (apply + durs)) (begs (let ((bg beg)) (append (list beg) (map (lambda (x) (set! bg (+ bg x))) durs)))) (beg-samps (map seconds->samples begs))) (let ((change-times (let* ((len (length beg-samps)) (nbegs (append beg-samps (list (beg-samps (- len 1)))))) (apply vector nbegs))) (shps (map cadr data)) (glts (map caddr data)) (pfun (let ((init (list 0.0 (* .8 (setup 3))))) (for-each (lambda (b dat) (set! init (append init (list (- b beg)))) (set! init (append init (list (* 1.0 (dat 3)))))) (cdr begs) data) init)) (gfun (let ((init (list 0.0 0.0))) (for-each (lambda (b dat) (set! init (append init (list (- b beg)))) (set! init (append init (list (* 1.0 (dat 4)))))) (cdr begs) data) init)) (nfun (let ((init (list 0.0 (* 1.0 (setup 5))))) (for-each (lambda (b dat) (set! init (append init (list (- b beg)))) (set! init (append init (list (* 1.0 (dat 5)))))) (cdr begs) data) init)) (vfun (let ((init (list 0.0 (* 1.0 (setup 6))))) (for-each (lambda (b dat) (set! init (append init (list (- b beg)))) (set! init (append init (list (* 1.0 (dat 6)))))) (cdr begs) data) init)) (noiseamps (let* ((len (length data)) (v (make-float-vector len 0.0))) (do ((i 0 (+ i 1))) ((= i len)) (set! (v i) (* 1.0 ((data i) 5)))) v)) (tractlength 9)) ;length of vocal tract (let ((frq-env (make-env pfun :duration dur)) (vib-env (make-env vfun :duration dur)) (vib-osc (make-oscil 6.0)) (glot-env (make-env gfun :duration dur)) (noise-env (make-env nfun :duration dur)) (ran-vib (make-rand-interp :frequency 10 :amplitude .02)) (glot-datai (make-float-vector (* 2 (length glts)) 0.0)) (glot-datar (make-float-vector (* 2 (length glts)) 0.0)) (tractlength+8 (+ tractlength 8)) (tractlength+1 (+ tractlength 1)) (tractlength-1 (- tractlength 1)) (tractlength-2 (- tractlength 2)) (noselength 6) (table-size 1000) ; size of glottis wave-table (dpole 0.998) (bg (seconds->samples beg)) (tong-hump-pole 0.998) (tong-tip-pole 0.998)) (let ((shape-data (make-float-vector (* (length shps) tractlength+8) 0.0)) (noselength-1 (- noselength 1)) (noselength-2 (- noselength 2)) (nose-ring-time 1000) ; naso pharynx response decay time (table-size-over-sampling-rate (/ table-size *clm-srate*)) (dgain (- 1.0 dpole)) (tong-hump-gain (- 1.0 tong-hump-pole)) (tong-tip-gain (- 1.0 tong-tip-pole)) (last-sfd -1) (last-gfd -1) (glot-table (make-float-vector (+ 1 table-size) 0.0)) (glot-table2 (make-float-vector (+ 1 table-size) 0.0)) ;; (gn-table (make-float-vector (+ 1 table-size) 0.0)) ;(gn-gain 0.0) ;(gn-out 0.0) ;(gn-del (make-float-vector 4 0.0)) ;; (gn-coeffs (make-float-vector 4 0.0)) ; in Perry's C code, these were set in setGlotNoiseFilter but it was never called! (table-increment 0.0) (glot-refl-gain 0.7) (pitch 400.0) (last-lip-in 0.0) ;for lip reflection/transmission filter (last-lip-out 0.0) (last-lip-refl 0.0) (lip-refl-gain -0.45) (noise-gain 0.0) ;for vocal tract noise generator (noise-input 0.0) (noise-output 0.0) (noisef (make-fir-filter 4 :xcoeffs (make-float-vector 4))) (noisev #f) (noise-pos 0) (fnoiseamp 0.0) (inz1 0.0) (inz2 0.0) ;; nasal tract acoustic tube structure (nose-coeffs (make-float-vector noselength 0.0)) (nose1 (make-float-vector noselength 0.0)) (nose2 (make-float-vector noselength 0.0)) (velum-pos 0.0) (nose-last-minus-refl 0.0) (nose-last-plus-refl 0.0) (nose-last-output 0.0) (nose-filt 0.0) (nose-filt1 0.0) (time-nose-closed 1000) ; this is a hack used to determine if we need to calculate the nasal acoustics ;; vocal tract acoustic tube structure ;; throat radiation low-pass filter (lt1 0.0) (lp (make-one-pole 0.05 (* -0.05 .9995))) (lip-radius 0.0) (s-glot-mix 0.0) (s-noise 0.0) (initial-noise-position 0.0) (formant-shift 1.0) (change-radii #f) (delta 0.0) (new-tract #t) (first-tract #t) (offset -1) (nd (floor (change-times (- (length change-times) 1)))) (next-offset bg) (table-location 0.0) (glotsamp 0.0) (last-tract-plus 0.0) (alpha1 0.0) (alpha2 0.0) (alpha3 0.0) (noseposition 3) (target-radii (make-float-vector tractlength+8 0.0)) (target-temp (make-float-vector tractlength+8 0.0)) (radii-poles (make-float-vector tractlength+8 0.0)) (radii-pole-gains (make-float-vector tractlength+8 0.0)) (radii (make-float-vector tractlength+8 0.0)) ; the radii array contains the vocal tract section radii ; (tractlength-1 of them), then glottal reflection gain ; then lip reflection gain, then noise position, then noise gain, ; then noise pole angle, then noise pole radius, ; then noise pole angle2, then noise pole radius2, then velum opening radius (coeffs (make-float-vector tractlength 0.0)) (dline1 (make-float-vector tractlength 0.0)) (dline2 (make-float-vector tractlength 0.0))) (set! noisev (mus-xcoeffs noisef)) (do ((k 0 (+ k 1)) (i 0 (+ i tractlength+8))) ((= k (length shps))) (let ((shp (cdr (shps k)))) (do ((j i (+ j 1)) (m 0 (+ 1 m))) ((= m (length shp))) (float-vector-set! shape-data j (shp m))))) (do ((k 0 (+ k 1)) (i 0 (+ i 2))) ((= k (length glts))) (let ((glt (glts k))) (set! (glot-datai i) 0.0) (set! (glot-datai (+ i 1)) (car glt)) (set! (glot-datar i) (cadr glt)) (set! (glot-datar (+ i 1)) (caddr glt)))) (set! (nose-coeffs 0) 0.0) (set! (nose-coeffs 1) -0.29) (set! (nose-coeffs 2) -0.22) (set! (nose-coeffs 3) 0.0) (set! (nose-coeffs 4) 0.24) (set! (nose-coeffs 5) 0.3571) (fill! radii 1.0) ;(do ((i 0 (+ i 1))) ((= i 8)) (set! (radii i) 1.0)) (set! (radii 8) 0.7) (set! (radii 9) -0.5) (fill! target-radii 1.0) ;(do ((i 0 (+ i 1))) ((= i 8)) (set! (target-radii i) 1.0)) (set! (target-radii 8) 0.7) (set! (target-radii 9) -0.5) (fill! radii-poles dpole) ;(do ((i 0 (+ i 1))) ((= i tractlength+8)) (set! (radii-poles i) dpole)) (set! (radii-poles 2) tong-hump-pole) (set! (radii-poles 3) tong-hump-pole) (set! (radii-poles 4) tong-hump-pole) (set! (radii-poles 5) tong-tip-pole) (fill! radii-pole-gains dgain) ;(do ((i 0 (+ i 1))) ((= i tractlength+8)) (set! (radii-pole-gains i) dgain)) (set! (radii-pole-gains 2) tong-hump-gain) (set! (radii-pole-gains 3) tong-hump-gain) (set! (radii-pole-gains 4) tong-hump-gain) (set! (radii-pole-gains 5) tong-tip-gain) ;; ---------------- make glot ---------------- (let ((harms (floor (glot-datai 1))) (temp1 0.0) (temp 0.0) (sines (make-float-vector 200 0.0)) (cosines (make-float-vector 200 0.0)) (one-over-two-pi 0.159154943) (two-pi-over-table-size (/ two-pi table-size)) (a (glot-datar 0)) (b (glot-datar 1))) (let ((a2 (* two-pi a)) (b2 (* two-pi b)) (b-a (- b a))) (let ((sa2 (sin a2)) (ca2 (cos a2))) (fill! sines 0.0) (fill! cosines 0.0) (if (not (= b a)) (begin (set! temp (/ one-over-two-pi b-a)) (set! temp1 (- 1.0 ca2)) (set! (sines 1) (* (+ ca2 (* (- sa2 (sin b2)) temp)) temp1 one-over-two-pi)) (set! (cosines 1) (* (+ (- sa2) (* (- ca2 (cos b2)) temp)) temp1 one-over-two-pi)))) (set! (sines 1) (+ (sines 1) (* (+ 0.75 (- ca2) (* (cos (* 2 a2)) 0.25)) one-over-two-pi))) (set! (cosines 1) (+ (cosines 1) (- (* (- sa2 (* (sin (* 2 a2)) 0.25)) one-over-two-pi) (* a 0.5)))) (do ((k 2 (+ k 1)) (ka2 (* 2 a2) (+ ka2 a2)) (ka1 a2 (+ ka1 a2)) (ka3 (* 3 a2) (+ ka3 a2))) ((> k harms)) (if (not (= b a)) (begin (set! temp (/ one-over-two-pi (* b-a k))) (set! (sines k) (* (+ (cos ka2) (* (- (sin ka2) (sin (* k b2))) temp)) (/ temp1 k))) (set! (cosines k) (* (+ (- (sin ka2)) (* (- (cos ka2) (cos (* k b2))) temp)) (/ temp1 k))))) (set! (sines k) (+ (sines k) (/ (- 1.0 (cos ka2)) k) (/ (* (- (cos ka1) 1.0) 0.5) (- k 1)) (/ (* (- (cos ka3) 1.0) 0.5) (+ k 1)))) (set! (sines k) (* (sines k) one-over-two-pi)) (set! (cosines k) (+ (cosines k) (- (/ (sin ka2) k) (/ (* (sin ka1) 0.5) (- k 1)) (/ (* (sin ka3) 0.5) (+ k 1))))) (set! (cosines k) (* (cosines k) one-over-two-pi))) (fill! glot-table 0.0) (do ((j 0 (+ j 1)) (x 0.0 (+ x two-pi-over-table-size))) ((> j table-size)) (do ((k 1 (+ k 1)) (kx x (+ kx x))) ((> k harms)) (float-vector-set! glot-table j (+ (float-vector-ref glot-table j) (* (float-vector-ref cosines k) (cos kx)) (* (float-vector-ref sines k) (sin kx))))))))) (set! s-glot-mix 1.0) (copy glot-table glot-table2) ;; ---------------- end make glot ---------------- (do ((i bg (+ i 1))) ((= i nd)) (if (= i next-offset) (begin ;; time to check for new tract shapes, glottal pulse shapes etc. (set! offset (+ offset 1)) (set! fnoiseamp (noiseamps offset)) (if (= last-sfd -1) (set! last-sfd 0) (let ((new-sfd (+ last-sfd 8 tractlength))) (do ((j last-sfd (+ j 1)) (k new-sfd (+ k 1))) ((= j new-sfd)) (if (> (abs (- (shape-data j) (shape-data k))) .001) (set! new-tract #t))) (set! last-sfd new-sfd))) (if (= last-gfd -1) (set! last-gfd 0) (let ((new-gfd (+ last-gfd 2))) (set! last-gfd new-gfd))) (set! next-offset (floor (change-times (+ offset 1)))) (set! delta (/ 1.0 (- next-offset i))))) (if new-tract (begin (copy shape-data target-radii last-sfd) (if first-tract (copy target-radii radii)) (set! change-radii #f) (set! initial-noise-position (radii tractlength+1)) (do ((j 0 (+ j 1))) ((or (= j tractlength+8) change-radii)) (if (> (abs (- (target-radii j) (radii j))) 0.001) (set! change-radii #t))))) (if (or first-tract change-radii) (begin (if (not new-tract) (begin (float-vector-multiply! radii radii-poles) (copy target-radii target-temp) (float-vector-multiply! target-temp radii-pole-gains) (float-vector-add! radii target-temp) ;; (do ((j 0 (+ j 1))) ((= j tractlength+8)) ;; (float-vector-set! radii j (+ (* (float-vector-ref radii j) (float-vector-ref radii-poles j)) ;; (* (float-vector-ref target-radii j) (float-vector-ref radii-pole-gains j))))) )) ;; set tract shape (let ((tj 1.0) (tk 0.0)) (do ((k 0 (+ k 1)) (j 1 (+ j 1))) ((= j tractlength)) (set! tk tj) (if (zero? (float-vector-ref radii j)) (set! tj 1e-10) (set! tj (* (float-vector-ref radii k) (float-vector-ref radii k)))) (float-vector-set! coeffs j (/ (- tk tj) (+ tk tj))))) (set! glot-refl-gain (radii tractlength-1)) (set! lip-refl-gain (radii tractlength)) (set! noise-pos (floor (radii tractlength+1))) (set! noise-gain (radii (+ tractlength 2))) (let ((temp1 (radii (+ tractlength 3))) (r (radii (+ tractlength 4))) (t2 (radii (+ tractlength 5))) (r2 (radii (+ tractlength 6)))) (let (;; fricative noise generator (set noise angle and radius) (noise-angle (hz->radians temp1)) (noise-angle2 (hz->radians t2)) (noise-radius r) (noise-radius2 r2)) (let ((noise-a (* -2.0 (cos (/ noise-angle formant-shift)) noise-radius)) (noise-b (* noise-radius noise-radius)) (noise-a2 (* -2.0 (cos (/ noise-angle2 formant-shift)) noise-radius2)) (noise-b2 (* noise-radius2 noise-radius2))) (set! (noisev 0) (+ noise-a noise-a2)) (set! (noisev 1) (+ noise-b noise-b2 (* noise-a noise-a2))) (set! (noisev 2) (+ (* noise-a2 noise-b) (* noise-b2 noise-a))) (set! (noisev 3) (* noise-b2 noise-b))))) (set! lip-radius (radii tractlength-2)) (set! velum-pos (radii (+ tractlength 7))) (let ((leftradius (radii (- noseposition 2))) (velumradius velum-pos) (rightradius (radii (- noseposition 1)))) (let ((temp1 0.0) (temp 0.0)) ;; nasal tract (set nasal shape) (set! temp (- rightradius velumradius)) (if (< temp 0.0) (set! temp 0.0)) (set! alpha1 (* leftradius leftradius)) (set! alpha2 (* temp temp)) (set! alpha3 (* velumradius velumradius)) (set! temp1 (/ 2.0 (+ alpha1 alpha2 alpha3))) (set! alpha1 (* alpha1 temp1)) (set! alpha2 (* alpha2 temp1)) (set! alpha3 (* alpha3 temp1)))))) (if new-tract (begin (set! new-tract #f) (set! first-tract #f) (if (or (< s-noise 1.0) (< fnoiseamp 0.0001)) (set! (target-radii tractlength+1) initial-noise-position)))) (set! s-glot-mix (- s-glot-mix delta)) (set! s-noise (env noise-env)) (set! pitch (env frq-env)) (set! table-increment (* pitch (+ 1.0 (* (env vib-env) (oscil vib-osc)) (rand-interp ran-vib)) table-size-over-sampling-rate)) (set! last-lip-out (+ last-lip-in last-tract-plus)) (set! last-lip-refl (* (+ last-lip-in last-tract-plus) lip-refl-gain)) (set! last-lip-in last-tract-plus) ;; next glot tick (set! glotsamp (* (dline2 1) glot-refl-gain)) (if (not (= table-increment 0.0)) (begin (set! table-location (+ table-location table-increment)) (if (>= table-location table-size) (set! table-location (- table-location table-size))) (let ((int-loc (floor table-location))) (let ((table1 (glot-table int-loc))) (set! glotsamp (+ glotsamp (* (env glot-env) (+ table1 (* s-glot-mix (- (glot-table2 int-loc) table1)))))))))) ;; next tract tick (let ((j 0) ;(temp1 0.0) (temp (dline2 2))) (set! lt1 (one-pole lp (+ (dline1 2) temp))) (set! (dline2 1) (+ temp (* (coeffs 1) (- glotsamp temp)))) (set! temp (+ glotsamp (- (dline2 1) temp))) (set! temp (singer-filter 1 noseposition temp dline1 dline2 coeffs)) #| (let ((x 0.0)) (do ((j 2 (+ j 1)) (k 1 (+ k 1))) ((= j noseposition)) (set! x (float-vector-ref dline2 (+ j 1))) (float-vector-set! dline2 j (+ x (* (float-vector-ref coeffs j) (- (float-vector-ref dline1 k) x)))) (set! temp1 temp) (set! temp (+ (float-vector-ref dline1 k) (- (float-vector-ref dline2 j) x))) (float-vector-set! dline1 k temp1))) |# (set! j noseposition) ;added ;;next nasal tick (let ((plussamp (dline1 (- j 1))) (minussamp (dline2 (+ j 1))) (nose-reftemp 0.0)) (if (and (= velum-pos 0.0) (>= time-nose-closed nose-ring-time)) (let ((nose2-1 (float-vector-ref nose2 1))) (set! nose-reftemp (+ (* alpha1 plussamp) (* alpha2 minussamp) (* alpha3 nose2-1))) (set! nose-last-minus-refl (- nose-reftemp plussamp)) (set! nose-last-plus-refl (- nose-reftemp minussamp))) (begin (if (not (= velum-pos 0.0)) (set! time-nose-closed 0) (set! time-nose-closed (+ time-nose-closed 1))) ; added 1 bil 17-Apr-11 but didn't test it ;; nasal tick (let ((nose-reftemp (+ (* alpha1 plussamp) (* alpha2 minussamp) (* alpha3 (nose2 1))))) (let (;(nose-t1 0.0) (nose-temp 0.0) (plus-in (* velum-pos (- nose-reftemp (nose2 1))))) (set! nose-last-minus-refl (- nose-reftemp plussamp)) (set! nose-last-plus-refl (- nose-reftemp minussamp)) (set! nose-reftemp (* (nose-coeffs 1) (- plus-in (nose2 2)))) (set! (nose2 1) (+ (nose2 2) nose-reftemp)) (set! nose-temp (+ plus-in nose-reftemp)) (set! nose-temp (singer-nose-filter noselength-1 nose-temp nose1 nose2 nose-coeffs)) #| (do ((j 2 (+ j 1)) (k 1 (+ k 1))) ((= j noselength-1)) (set! nose-reftemp (* (nose-coeffs j) (- (nose1 k) (nose2 (+ j 1))))) (set! (nose2 j) (+ (nose2 (+ j 1)) nose-reftemp)) (set! nose-t1 nose-temp) (set! nose-temp (+ (nose1 k) nose-reftemp)) (set! (nose1 k) nose-t1)) |# (set! nose-reftemp (* (nose-coeffs noselength-1) (- (nose1 noselength-2) (* nose-last-output 0.25)))) (set! (nose2 noselength-1) (+ (* nose-last-output 0.25) nose-reftemp)) (set! (nose1 noselength-1) (+ (nose1 noselength-2) nose-reftemp)) (set! (nose1 noselength-2) nose-temp) (set! nose-filt1 nose-filt) (set! nose-filt (nose1 noselength-1)) (set! nose-last-output (* (+ nose-filt nose-filt1) 0.5)))))) (set! (dline2 j) nose-last-minus-refl)) (set! (dline1 (- j 1)) temp) (set! temp nose-last-plus-refl) ;; j always starts at 4, goes to 8 so this loop can be unrolled, but doing so doesn't make a big difference (set! temp (singer-filter noseposition tractlength-1 temp dline1 dline2 coeffs)) #| (let ((x 0.0)) (do ((j (+ noseposition 1) (+ j 1)) (k noseposition (+ k 1))) ((= j tractlength-1)) (set! x (float-vector-ref dline2 (+ j 1))) (float-vector-set! dline2 j (+ x (* (float-vector-ref coeffs j) (- (float-vector-ref dline1 k) x)))) (set! temp1 temp) (set! temp (+ (float-vector-ref dline1 k) (- (float-vector-ref dline2 j) x))) (float-vector-set! dline1 k temp1))) |# (set! (dline2 tractlength-1) (+ last-lip-refl (* (coeffs tractlength-1) (- (dline1 tractlength-2) last-lip-refl)))) (set! (dline1 tractlength-1) (+ (dline1 tractlength-2) (- (dline2 tractlength-1) last-lip-refl))) (set! (dline1 tractlength-2) temp) (if (not (= noise-gain 0.0)) (begin (set! noise-input (mus-random 1.0)) ;a guess (set! noise-output (- noise-input inz2 (fir-filter noisef noise-output))) (set! inz2 inz1) (set! inz1 noise-input) (set! (dline1 noise-pos) (+ (dline1 noise-pos) (* noise-output noise-gain s-noise))))) (set! last-tract-plus (* (dline1 tractlength-1) lip-radius))) (outa i (* amp (+ last-lip-out nose-last-output lt1))) )))))) #| (with-sound (:statistics #t) (singer 0 .1 (list (list .4 ehh.shp test.glt 523.0 .8 0.0 .01) (list .6 oo.shp test.glt 523.0 .7 .1 .01)))) (with-sound (:statistics #t) (singer 0 .1 (list (list .05 ehh.shp test.glt 523.0 0.8 0.0 .01) (list .15 ehh.shp test.glt 523.0 0.8 0.0 .01) (list .05 kkk.shp test.glt 523.0 0.0 0.0 .01) (list .05 kkk.shp test.glt 523.0 0.0 0.0 .01) (list .02 kk+.shp test.glt 523.0 0.0 1.0 .01) (list .08 kk+.shp test.glt 523.0 0.0 0.2 .01) (list .05 ooo.shp test.glt 523.0 0.8 0.0 .01) (list .15 ooo.shp test.glt 523.0 0.8 0.0 .01) (list .05 eee.shp test.glt 523.0 0.8 0.0 .01) (list .15 eee.shp test.glt 523.0 0.8 0.0 .01) (list .05 ehh.shp test.glt 523.0 0.8 0.0 .01) (list .15 ehh.shp test.glt 523.0 0.8 0.0 .01) (list .05 mmm.shp test.glt 523.0 0.8 0.0 .01) (list .15 mmm.shp test.glt 523.0 0.8 0.0 .01) (list .10 mmm.shp test.glt 523.0 0.0 0.0 .01) ))) |# (define test.glt (list 10 .65 .65)) (define loud.glt (list 13 .6 .6)) (define soft.glt (list 13 0.65 0.73)) (define wide4.glt (list 18 0.534 0.56)) (define wide5.glt (list 10 0.65 0.65)) (define greekdefault.glt (list 20 0.65 0.672472)) (define lowbass.glt (list 99 0.5 0.17737593)) (define aa.shp (list 8 0.63110816 0.94615144 1.0756062 0.9254686 0.9928594 0.98307705 1.4507878 0.95167005 0.9 -0.4 1.0 0.0 0.0 0.0 0.0 0.0 0.0)) (define hh2.shp (list 8 0.928177 0.61326 0.39779 0.530387 0.679558 0.961326 1.44199 1.09392 0.7 -0.203125 1.0 0.0 554.1667 0.8 2000.0 0.772222 0.0)) (define dhh.shp (list 8 0.828729 1.45856 0.9882353 0.662983 0.9352941 1.2529411 0.40588236 1.1740758 0.7 -0.140625 7.0 0.023333002 3039.613 0.691692 1264.1677 0.404788 0.0)) (define aah.shp (list 8 0.8214024 0.7839217 1.0981537 0.9937591 0.817757 1.1907763 1.3149668 1.0705689 0.7 -0.4 1.0 0.0 0.0 0.0 0.0 0.0 0.0)) (define hhh.shp (list 8 0.928177 0.61326 0.39779 0.530387 0.679558 0.961326 1.44199 1.09392 0.7 -0.203125 1.0 0.046296295 554.1667 0.8 2000.0 0.7722222 0.0)) (define ohh.shp (list 8 1.02762 0.696133 0.39779 0.513812 0.6371682 1.4070797 1.80663 0.5044248 0.7 -0.2 1.0 0.0 1000.0 0.0 0.0 0.0 0.0)) (define ah.shp (list 8 0.7162393 0.6389201 0.8881412 0.6060006 1.293248 1.4140776 1.8503952 0.8622935 0.9 -0.4 1.0 0.0 0.0 0.0 0.0 0.0 0.0)) (define oo.shp (list 8 0.46043858 1.0865723 0.33916336 0.88724023 0.9989101 1.224445 0.39867023 0.506609 0.9 -0.4 1.0 0.0 0.0 0.0 0.0 0.0 0.0)) (define ahh.shp (list 8 0.928177 0.779006 0.629834 0.629834 1.02762 1.65746 1.62431 0.944751 0.7 -0.45 1.0 0.0 0.0 0.0 0.0 0.0 0.0)) (define ee-.shp (list 8 0.928177 1.37569 1.37569 0.679558 0.629834 0.24817872 0.56896555 0.662983 0.7 -0.403125 1.0 0.0 0.0 0.0 0.0 0.0 0.09677419)) (define hoo.shp (list 8 1.32597 1.29282 0.39779 0.530387 1.32597 1.34254 1.78182 0.46408796 0.7 -0.4 1.0 0.031045755 2215.7856 0.82698005 1026.6984 0.96960765 0.0)) (define ooo.shp (list 8 1.32597 1.29282 0.39779 0.530387 1.32597 1.34254 1.78182 0.464088 0.7 -0.4 1.0 0.0 0.0 0.0 0.0 0.0 0.0)) (define ee.shp (list 8 1.02 1.637 1.67 1.558 0.952 0.501 0.681 0.675 0.9 -0.4 1.0 0.0 0.0 0.0 0.0 0.0 0.0)) (define ih.shp (list 8 0.72092783 1.2719809 1.3881364 0.6532612 0.7501422 0.65654784 0.8194081 0.6556785 0.9 -0.4 1.0 0.0 0.0 0.0 0.0 0.0 0.0)) (define ee2.shp (list 8 0.9180887 1.3481673 1.3433423 0.74573994 0.593326 0.5647744 0.6692766 0.7419633 0.7 -0.405254 1.0 0.0 0.0 0.0 0.0 0.0 0.0)) (define ihh.shp (list 8 0.7906788 1.272475 1.4089537 0.68072784 0.62673146 0.7479623 0.7506758 0.7054355 0.9 -0.4 1.0 0.0 0.0 0.0 0.0 0.0 0.0)) (define open.shp (list 8 3.0 3.0 3.0 3.0 3.0 3.0 3.0 3.0 0.7 -0.45 1.0 0.0 0.0 0.0 1.0 0.0 0.0)) (define thh.shp (list 8 0.828729 1.45856 0.9882353 0.662983 0.9352941 1.2529411 0.40588236 1.1740758 0.7 -0.140625 7.0 0.101764 3039.613 0.691692 1264.1677 0.404788 0.0)) (define aw.shp (list 8 1.0525645 0.643587 0.935229 0.4901642 1.0743295 1.1822895 1.4161918 0.82537806 0.9 -0.4 1.0 0.0 0.0 0.0 0.0 0.0 0.0)) (define eee.shp (list 8 0.928177 1.37569 1.37569 0.679558 0.629834 0.646409 0.56896555 0.662983 0.7 -0.403125 1.0 0.0 0.0 0.0 0.0 0.0 0.0)) (define tt+.shp (list 8 0.928177 0.779006 0.629834 0.629834 1.02762 0.18584079 1.62431 0.944751 0.7 -0.45 6.0 0.388889 10514.583 0.854335 1315.2043 0.280428 0.0)) (define aww.shp (list 8 1.02762 0.696133 0.563536 0.513812 0.977901 1.37569 1.80663 0.712707 0.7 -0.2 1.0 0.0 1000.0 0.0 0.0 0.0 0.0)) (define eee2.shp (list 8 0.928177 1.37569 1.37569 0.679558 0.629834 0.646409 0.5117647 0.662983 0.7 -0.203125 7.3688526 0.0 5214.53 0.975806 0.0 0.0 0.0)) (define jjj.shp (list 8 0.928177 0.779006 0.629834 0.629834 1.02762 0.1592921 1.1464338 0.944751 0.7 -0.45 6.0 0.098039 2315.7278 0.7089554 3066.7 0.7983351 0.0)) (define ttt.shp (list 8 0.928177 0.779006 0.629834 0.629834 1.02762 0.0 1.62431 0.944751 0.7 -0.45 6.0 0.388889 10514.583 0.854335 1315.2043 0.280428 0.0)) (define bb2.shp (list 8 1.0 1.0 0.46902645 0.5486725 0.65486723 1.079646 1.3982301 0.0 0.7 -0.2 8.0 0.03 500.0 0.98 0.0 0.0 0.0)) (define eh.shp (list 8 0.7866194 1.1630946 1.2335452 0.93186677 0.94121367 0.7586716 1.3509308 0.8279036 0.9 -0.4 1.0 0.0 0.0 0.0 0.0 0.0 0.0)) (define kk+.shp (list 8 0.8214024 0.7839217 1.0981537 0.1592921 1.061947 1.1907763 1.3149668 1.0705689 0.7 -0.4 4.0 0.4 2000.0 0.93 0.0 0.0 0.0)) (define pipe1.shp (list 8 1.0 1.0 1.0 0.7 0.7 0.7 0.7 0.7 0.0 0.0 1.0 0.0 100.0 0.0 0.0 0.0 0.0)) (define tzz.shp (list 8 0.828729 1.45856 0.9882353 0.662983 0.9352941 1.2529411 0.40588236 1.1740758 0.7 -0.140625 7.0 0.101764 3039.613 0.691692 1264.1677 0.404788 0.0)) (define bbb.shp (list 8 1.0 1.0 0.46902645 0.5486725 0.65486723 1.079646 1.3982301 0.0 0.7 -0.2 8.0 0.03 500.0 0.98 0.0 0.0 0.0)) (define ehh.shp (list 8 0.682 1.554 1.581 1.367 1.315 1.579 0.843 1.476 0.7 -0.24507 1.0 0.0 0.0 0.0 0.0 0.0 0.0)) (define kk2.shp (list 8 0.82140243 0.7839217 1.0981537 0.0 1.061947 1.1907763 1.3149668 1.0705689 0.7 -0.4 5.0 0.01 2000.0 0.93 0.0 0.0 0.0)) (define pp+.shp (list 8 1.0 1.0 0.3362832 0.49557513 0.7079646 1.2389379 1.1327434 0.29203534 0.7 -0.2 8.0 0.040740736 0.0 0.89649165 2082.2144 0.8713607 0.0)) (define uhh.shp (list 8 0.928177 0.61326 0.39779 0.530387 0.679558 0.961326 1.44199 1.09392 0.7 -0.203125 1.0 0.0 0.0 0.0 0.0 0.0 0.0)) (define big.shp (list 8 3.0 3.0 3.0 3.0 3.0 3.0 3.0 3.0 0.0 0.0 1.0 0.0 0.0 0.0 1.0 0.0 0.0)) (define euu.shp (list 8 0.9285748 1.3756071 1.3747121 0.6794088 0.60398144 0.43471563 0.8356653 0.7158814 0.7 -0.403122 1.0 0.0 0.0 0.0 0.0 0.0 0.0)) (define kkk.shp (list 8 0.8214024 0.7839217 1.0981537 0.0 1.061947 1.1907763 1.3149668 1.0705689 0.7 -0.4 4.0 0.09444445 2000.0 0.93 0.0 0.0 0.0)) (define ppp.shp (list 8 1.0 1.0 0.3362832 0.49557513 0.7079646 1.2389379 1.1327434 0.0 0.7 -0.2 8.0 0.05 500.0 0.98 0.0 0.0 0.0)) (define uu.shp (list 8 0.45291674 1.0539645 0.39576897 0.8116293 1.0510263 1.1789232 0.47529656 0.62563825 0.9 -0.4 1.0 0.0 0.0 0.0 0.0 0.0 0.0)) (define fff.shp (list 8 0.93787295 0.70496833 0.8969878 0.60815966 0.9375178 0.7412625 1.1285298 0.2665695 0.7 -0.202603 8.0 0.10341219 8236.909 0.945306 79.28094 0.498648 0.0)) (define ll2.shp (list 8 0.928177 0.779006 0.71772796 0.807417 1.02762 1.65746 0.36206907 0.86510503 0.7 -0.258055 1.0 0.0 0.0 0.0 0.0 0.0 0.20806663)) (define uuu.shp (list 8 0.55 0.943094 1.035 0.434071 1.14681 1.487 0.555 0.656 0.9 -0.4 1.0 0.0 0.0 0.0 0.0 0.0 0.0)) (define lll.shp (list 8 0.928177 0.779006 0.7330638 0.8156748 1.02762 1.65746 0.3620689 0.944751 0.7 -0.103125 1.0 0.0 0.0 0.0 0.0 0.0 0.21774194)) (define rolledr.shp (list 8 0.3365169 0.9244819 1.0542682 0.4485168 1.0597233 0.054845095 0.66896766 0.8336522 0.9 -0.4 1.0 0.0 0.0 0.0 0.0 0.0 0.0)) (define vvv.shp (list 8 0.9400966 0.6775904 0.88759726 0.59890866 0.9485658 0.737778 1.1542239 0.23893797 0.7 -0.2 8.0 0.5 8500.0 0.95 0.0 0.5 0.0)) (define rolledrc.shp (list 8 0.928177 0.779006 0.629834 0.629834 1.02762 0.0 1.62431 0.944751 0.7 -0.45 1.0 0.0 0.0 0.0 0.0 0.0 0.0)) (define mmm.shp (list 8 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.0 0.7 -0.2 1.0 0.0 0.0 0.0 0.0 0.0 0.503268)) (define rolledro.shp (list 8 0.928177 0.779006 0.629834 0.629834 1.02762 0.42477876 1.62431 0.944751 0.7 -0.45 1.0 0.0 0.0 0.0 0.0 0.0 0.0)) (define breath.shp (list 8 0.928177 0.779006 0.629834 0.629834 1.02762 1.65746 1.62431 0.944751 0.7 -0.45 1.0 0.018518519 2588.6013 0.90612125 812.6343 0.9814815 0.0)) (define moo.shp (list 8 1.32597 1.29282 0.39779 0.530387 1.32597 1.34254 1.78182 0.0 0.7 -0.4 1.0 0.0 0.0 0.0 0.0 0.0 0.30645162)) (define rr2.shp (list 8 0.3365169 0.9244819 1.0542682 0.4485168 1.0597233 0.71856207 0.66896766 0.7274576 0.9 -0.4 1.0 0.0 0.0 0.0 0.0 32.000004 0.0)) (define chh.shp (list 8 0.928177 0.779006 0.629834 0.629834 1.02762 0.1592921 1.1464338 0.944751 0.7 -0.45 6.0 0.098039 2315.7278 0.7089554 3066.7 0.7983351 0.0)) (define gg2.shp (list 8 0.8214024 0.4122405 0.40788835 0.0 0.8495575 0.7129002 0.7308959 0.7785335 0.7 -0.4 4.0 0.05 2000.0 0.9 0.0 0.0 0.0)) (define nng.shp (list 8 1.0 1.0 1.0333333 0.0 1.0 0.99999994 0.9568965 1.3189656 0.7 -0.2 1.0 0.0 0.0 0.0 0.0 0.0 1.0)) (define rrr.shp (list 8 0.3365169 0.9244819 1.0542682 0.4485168 1.0597233 0.71856207 0.66896766 0.7274576 0.9 -0.4 1.0 0.0 0.0 0.0 0.0 0.0 0.0)) (define wsp.shp (list 8 0.928177 0.779006 0.629834 0.629834 1.02762 1.65746 1.62431 0.944751 0.7 -0.45 1.0 0.018518519 0.0 0.97 0.0 0.0 0.0)) (define ggg.shp (list 8 0.8214024 0.7839217 1.0981537 0.0 0.8495575 0.7129002 0.7308959 0.7785335 0.7 -0.4 4.0 0.05 2000.0 0.9 0.0 0.0 0.0)) (define nnn.shp (list 8 1.0 1.0 1.0 1.4579439 1.0 0.0 0.9568965 1.3189656 0.7 -0.2 1.0 0.0 0.0 0.0 0.0 0.0 0.503268)) (define sh2.shp (list 8 0.828729 1.45856 0.9882353 0.662983 0.9352941 1.2529411 0.40588236 0.9882353 0.7 -0.140625 7.0 0.0 2451.5984 0.928097 2957.0518 0.883636 0.0)) (define xx2.shp (list 8 0.928177 1.37569 1.37569 0.8495575 0.3451327 0.646409 0.56896555 0.662983 0.7 -0.403125 5.0 0.022222 2102.0833 0.805556 1735.4166 0.759259 0.0)) (define dd2.shp (list 8 0.928177 0.779006 0.629834 0.629834 1.02762 0.0 0.72165513 0.5996184 0.7 -0.45 6.0 0.02 4851.6665 0.953704 2500.0 0.966296 0.0)) (define ggg1.shp (list 8 0.8214024 0.7839217 1.0981537 0.18584079 1.061947 1.1907763 1.3149668 1.0705689 0.7 -0.4 4.0 0.4 2000.0 0.9 0.0 0.0 0.0)) (define noisahh.shp (list 8 0.928177 0.779006 0.629834 0.629834 1.02762 1.65746 1.62431 0.944751 0.7 -0.45 1.0 0.005 0.0 0.787037 3777.0835 0.759259 0.0)) (define shh.shp (list 8 0.828729 1.45856 0.9882353 0.662983 0.9352941 1.2529411 0.40588236 0.9882353 0.7 -0.140625 7.0 0.023333 2451.5984 0.9280972 2957.0518 0.88363576 0.0)) (define xxx.shp (list 8 0.928177 1.37569 1.37569 0.3451327 0.6371682 0.646409 0.56896555 0.662983 0.7 -0.403125 4.0 0.022222219 2102.0833 0.8055556 612.5 0.7592593 0.0)) (define ddd.shp (list 8 0.928177 0.779006 0.629834 0.629834 1.02762 0.0 0.72165513 0.5996184 0.7 -0.45 6.0 0.02 4851.6665 0.953704 2500.0 0.966296 0.0)) (define gxx.shp (list 8 0.928177 1.37569 1.37569 0.3451327 0.6371682 0.646409 0.56896555 0.662983 0.7 -0.403125 4.0 0.022222 2102.0833 0.805556 612.5 0.759259 0.0)) (define none.shp (list 8 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0)) (define sss.shp (list 8 0.928177 1.3588235 1.3588235 0.679558 0.61764705 0.63529414 0.31764707 0.65294117 0.7 -0.103125 7.0 0.105292 1500.0 0.916452 4943.75 0.97222227 0.0)) (define zzz.shp (list 8 0.928177 1.3588235 1.3588235 0.679558 0.61764705 0.63529414 0.31764707 0.65294117 0.7 -0.103125 7.0 0.016 1500.0 0.9257112 4943.75 0.925926 0.0)) snd-16.1/s7.c0000600000076400007640001053527112626144463011046 0ustar bilbil/* s7, a Scheme interpreter * * derived from: * * -------------------------------------------------------------------------------- * T I N Y S C H E M E 1 . 3 9 * Dimitrios Souflis (dsouflis@acm.org) * Based on MiniScheme (original credits follow) * (MINISCM) coded by Atsushi Moriwaki (11/5/1989) * (MINISCM) E-MAIL : moriwaki@kurims.kurims.kyoto-u.ac.jp * (MINISCM) This version has been modified by R.C. Secrist. * (MINISCM) * (MINISCM) Mini-Scheme is now maintained by Akira KIDA. * (MINISCM) * (MINISCM) This is a revised and modified version by Akira KIDA. * (MINISCM) current version is 0.85k4 (15 May 1994) * -------------------------------------------------------------------------------- * * apparently tinyScheme is under the BSD license, so I guess s7 is too. * Here is Snd's verbiage which can apply here: * * The authors hereby grant permission to use, copy, modify, distribute, * and license this software and its documentation for any purpose. No * written agreement, license, or royalty fee is required. Modifications * to this software may be copyrighted by their authors and need not * follow the licensing terms described here. * * followed by the usual all-caps shouting about liability. * * -------------------------------------------------------------------------------- * * s7, Bill Schottstaedt, Aug-08, bil@ccrma.stanford.edu * * Mike Scholz provided the FreeBSD support (complex trig funcs, etc) * Rick Taube, Andrew Burnson, Donny Ward, and Greg Santucci provided the MS Visual C++ support * * Documentation is in s7.h and s7.html. * s7test.scm is a regression test. * glistener.c is a gtk-based listener. * repl.scm is a vt100-based listener. * cload.scm and lib*.scm tie in various C libraries. * lint.scm checks Scheme code for infelicities. * r7rs.scm implements some of r7rs (small). * write.scm currrenly has pretty-print. * mockery.scm has the mock-data definitions. * stuff.scm has some stuff. * * s7.c is organized as follows: * * structs and type flags * constants * GC * stacks * symbols and keywords * environments * continuations * numbers * characters * strings * ports * format * lists * vectors * hash-tables * c-objects * functions * equal? * generic length, copy, reverse, fill!, append * error handlers * sundry leftovers * multiple-values, quasiquote * eval * multiprecision arithmetic * *s7* environment * initialization * repl * * naming conventions: s7_* usually are C accessible (s7.h), g_* are scheme accessible (FFI), * H_* are documentation strings, Q_* are procedure signatures, * *_1 are auxilliary functions, big_* refer to gmp, * scheme "?" corresponds to C "is_", scheme "->" to C "_to_". * * ---------------- compile time switches ---------------- */ #include "mus-config.h" /* * Your config file goes here, or just replace that #include line with the defines you need. * The compile-time switches involve booleans, complex numbers, and multiprecision arithmetic. * Currently we assume we have setjmp.h (used by the error handlers). * * Complex number support which is problematic in C++, Solaris, and netBSD * is on the HAVE_COMPLEX_NUMBERS switch. In OSX or Linux, if you're not using C++, * * #define HAVE_COMPLEX_NUMBERS 1 * #define HAVE_COMPLEX_TRIG 1 * * In C++ I use: * * #define HAVE_COMPLEX_NUMBERS 1 * #define HAVE_COMPLEX_TRIG 0 * * In windows, both are 0. * * Some systems (FreeBSD) have complex.h, but some random subset of the trig funcs, so * HAVE_COMPLEX_NUMBERS means we can find * cimag creal cabs csqrt carg conj * and HAVE_COMPLEX_TRIG means we have * cacos cacosh casin casinh catan catanh ccos ccosh cexp clog cpow csin csinh ctan ctanh * * When HAVE_COMPLEX_NUMBERS is 0, the complex functions are stubs that simply return their * argument -- this will be very confusing for the s7 user because, for example, (sqrt -2) * will return something bogus (it will not signal an error). * * so the incoming (non-s7-specific) compile-time switches are * HAVE_COMPLEX_NUMBERS, HAVE_COMPLEX_TRIG, SIZEOF_VOID_P * if SIZEOF_VOID_P is not defined, we look for __SIZEOF_POINTER__ instead * the default is to assume that we're running on a 64-bit machine. * * To get multiprecision arithmetic, set WITH_GMP to 1. * You'll also need libgmp, libmpfr, and libmpc (version 0.8.0 or later) * In highly numerical contexts, the gmp version of s7 is about 50(!) times slower than the non-gmp version. * * and we use these predefined macros: __cplusplus, _MSC_VER, __GNUC__, __clang__, __ANDROID__ * * if WITH_SYSTEM_EXTRAS is 1 (default is 1 unless _MSC_VER), various OS and file related functions are included. * in openBSD I think you need to include -ftrampolines in CFLAGS. * if you want this file to compile into a stand-alone interpreter, define WITH_MAIN * * -O3 is sometimes slower, sometimes faster * -march=native -fomit-frame-pointer -m64 -funroll-loops gains about .1% * -ffast-math makes a mess of NaNs, and does not appear to be faster * for timing tests, I use: -O2 -DINITIAL_HEAP_SIZE=1024000 -march=native -fomit-frame-pointer -funroll-loops */ /* ---------------- initial sizes ---------------- */ #ifndef INITIAL_HEAP_SIZE #define INITIAL_HEAP_SIZE 128000 /* the heap grows as needed, this is its initial size. * If the initial heap is small, s7 can run in about 2.5 Mbytes of memory. There are (many) cases where a bigger heap is faster. * The heap size must be a multiple of 32. Each object takes about 50 bytes. * * repl runs in 4Mb (18v) (64bit) if heap is 8192 * 11Mb (25v) if 128k heap * snd (no gui) 15Mb (151v) * snd (motif) 12Mb (285v) * snd (gtk) 32Mb (515v!) */ #endif #ifndef SYMBOL_TABLE_SIZE #define SYMBOL_TABLE_SIZE 13567 /* names are hashed into the symbol table (a vector) and collisions are chained as lists. */ #endif #define INITIAL_STACK_SIZE 512 /* the stack grows as needed, each frame takes 4 entries, this is its initial size. * this needs to be big enough to handle the eval_c_string's at startup (ca 100) * In s7test.scm, the maximum stack size is ca 440. In snd-test.scm, it's ca 200. * This number matters only because call/cc copies the stack, which requires filling * the unused portion of the new stack, which requires memcpy of #'s. */ #define INITIAL_PROTECTED_OBJECTS_SIZE 16 /* a vector of objects that are (semi-permanently) protected from the GC, grows as needed */ #define GC_TEMPS_SIZE 256 /* the number of recent objects that are temporarily gc-protected; 8 works for s7test and snd-test. * For the FFI, this sets the lag between a call on s7_cons and the first moment when its result * might be vulnerable to the GC. */ /* ---------------- scheme choices ---------------- */ #ifndef WITH_GMP #define WITH_GMP 0 /* this includes multiprecision arithmetic for all numeric types and functions, using gmp, mpfr, and mpc * WITH_GMP adds the following functions: bignum, bignum?, bignum-precision * using gmp with precision=128 is about 50 times slower than using C doubles and long long ints. */ #endif #if WITH_GMP #define DEFAULT_BIGNUM_PRECISION 128 #endif #ifndef WITH_PURE_S7 #define WITH_PURE_S7 0 #endif #if WITH_PURE_S7 #define WITH_EXTRA_EXPONENT_MARKERS 0 #define WITH_IMMUTABLE_UNQUOTE 1 #define WITH_QUASIQUOTE_VECTOR 0 /* also omitted: *-ci* functions, char-ready?, cond-expand, multiple-values-bind|set!, call-with-values, defmacro(*) * and a lot more (inexact/exact, integer-length, etc) -- see s7.html. */ #endif #ifndef WITH_EXTRA_EXPONENT_MARKERS #define WITH_EXTRA_EXPONENT_MARKERS 0 /* if 1, s7 recognizes "d", "f", "l", and "s" as exponent markers, in addition to "e" (also "D", "F", "L", "S") */ #endif #ifndef WITH_SYSTEM_EXTRAS #define WITH_SYSTEM_EXTRAS (!_MSC_VER) /* this adds several functions that access file info, directories, times, etc * this may be replaced by the cload business below */ #endif #ifndef WITH_IMMUTABLE_UNQUOTE #define WITH_IMMUTABLE_UNQUOTE 0 /* this removes the name "unquote" */ #endif #ifndef WITH_QUASIQUOTE_VECTOR #define WITH_QUASIQUOTE_VECTOR 0 /* this determines whether we include support for quasiquoted vector constants `#(...) */ #endif #ifndef WITH_C_LOADER #define WITH_C_LOADER WITH_GCC /* (load file.so [e]) looks for (e 'init_func) and if found, calls it * as the shared object init function. If WITH_SYSTEM_EXTRAS is 0, the caller * needs to supply system and delete-file so that cload.scm works. */ #endif #define WITH_GCC (defined(__GNUC__) || defined(__clang__)) /* in case mus-config.h forgets these */ #ifdef _MSC_VER #ifndef HAVE_COMPLEX_NUMBERS #define HAVE_COMPLEX_NUMBERS 0 #endif #ifndef HAVE_COMPLEX_TRIG #define HAVE_COMPLEX_TRIG 0 #endif #else #ifndef HAVE_COMPLEX_NUMBERS #define HAVE_COMPLEX_NUMBERS 1 #endif #if __cplusplus #ifndef HAVE_COMPLEX_TRIG #define HAVE_COMPLEX_TRIG 0 #endif #else #ifndef HAVE_COMPLEX_TRIG #define HAVE_COMPLEX_TRIG 1 #endif #endif #endif /* -------------------------------------------------------------------------------- */ #ifndef DEBUGGING #define DEBUGGING 0 #endif #ifndef OP_NAMES #define OP_NAMES 0 #endif #define WITH_ADD_PF 0 #ifndef _MSC_VER #include #include #include #include #include #else /* in Snd these are in mus-config.h */ #ifndef MUS_CONFIG_H_LOADED #define snprintf _snprintf #if _MSC_VER > 1200 #define _CRT_SECURE_NO_DEPRECATE 1 #define _CRT_NONSTDC_NO_DEPRECATE 1 #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1 #endif #endif #include #pragma warning(disable: 4244) #endif #include #include #include #include #include #include #include #include #if __cplusplus #include #else #include #endif #if HAVE_COMPLEX_NUMBERS #if __cplusplus #include #else #include #if defined(__sun) && defined(__SVR4) #undef _Complex_I #define _Complex_I 1.0fi #endif #endif #ifndef CMPLX /* c11 addition? */ #define CMPLX(r, i) ((r) + ((i) * _Complex_I)) #endif #endif #include /* currently longjmps in s7_call, s7_error, g_throw, eval at OP_ERROR_HOOK_QUIT */ #include "s7.h" #ifndef M_PI #define M_PI 3.1415926535897932384626433832795029L #endif #ifndef INFINITY #define INFINITY (-log(0.0)) /* 1.0 / 0.0 is also used, there is sometimes a function, infinity(), MSC apparently uses HUGE_VALF */ #endif #ifndef NAN #define NAN (INFINITY / INFINITY) #endif #define BOLD_TEXT "\033[1m" #define UNBOLD_TEXT "\033[22m" #define WRITE_REAL_PRECISION 16 static int float_format_precision = WRITE_REAL_PRECISION; #if ((!__NetBSD__) && ((_MSC_VER) || (!defined(__STC__)) || (defined(__STDC_VERSION__) && (__STDC_VERSION__ < 199901L)))) #define __func__ __FUNCTION__ #endif #define DISPLAY(Obj) s7_object_to_c_string(sc, Obj) #define DISPLAY_80(Obj) object_to_truncated_string(sc, Obj, 80) #if (((defined(SIZEOF_VOID_P)) && (SIZEOF_VOID_P == 4)) || ((defined(__SIZEOF_POINTER__)) && (__SIZEOF_POINTER__ == 4))) #define opcode_t unsigned int #define PRINT_NAME_PADDING 8 #define PRINT_NAME_SIZE (20 - PRINT_NAME_PADDING - 2) #define ptr_int unsigned int #define INT_FORMAT "%u" #ifndef WITH_OPTIMIZATION #define WITH_OPTIMIZATION 0 /* 32-bit optimized case gets inexplicable NaNs in float-vector ops. * only the rf cases are faulty, so it is possible to set this flag to 1, then make s7_rf_set_function a no-op, * and comment out the 2 syntax_rp cases. * In standard scheme code, this flag does not matter much, but it makes CLM run about 3 times as fast. */ #endif #else #define opcode_t unsigned long long int #define ptr_int unsigned long long int #define INT_FORMAT "%llu" #define PRINT_NAME_PADDING 16 #define PRINT_NAME_SIZE (40 - PRINT_NAME_PADDING - 2) #ifndef WITH_OPTIMIZATION #define WITH_OPTIMIZATION 1 #endif #endif /* types */ #define T_FREE 0 #define T_PAIR 1 #define T_NIL 2 #define T_UNIQUE 3 #define T_UNSPECIFIED 4 #define T_BOOLEAN 5 #define T_CHARACTER 6 #define T_SYMBOL 7 #define T_SYNTAX 8 #define T_INTEGER 9 #define T_RATIO 10 #define T_REAL 11 #define T_COMPLEX 12 #define T_BIG_INTEGER 13 /* these four used only if WITH_GMP -- order matters */ #define T_BIG_RATIO 14 #define T_BIG_REAL 15 #define T_BIG_COMPLEX 16 #define T_STRING 17 #define T_C_OBJECT 18 #define T_VECTOR 19 #define T_INT_VECTOR 20 #define T_FLOAT_VECTOR 21 #define T_CATCH 22 #define T_DYNAMIC_WIND 23 #define T_HASH_TABLE 24 #define T_LET 25 #define T_ITERATOR 26 #define T_STACK 27 #define T_COUNTER 28 #define T_SLOT 29 #define T_C_POINTER 30 #define T_OUTPUT_PORT 31 #define T_INPUT_PORT 32 #define T_BAFFLE 33 #define T_RANDOM_STATE 34 #define T_GOTO 35 #define T_CONTINUATION 36 #define T_CLOSURE 37 #define T_CLOSURE_STAR 38 #define T_C_MACRO 39 #define T_MACRO 40 #define T_MACRO_STAR 41 #define T_BACRO 42 #define T_BACRO_STAR 43 #define T_C_FUNCTION_STAR 44 #define T_C_FUNCTION 45 #define T_C_ANY_ARGS_FUNCTION 46 #define T_C_OPT_ARGS_FUNCTION 47 #define T_C_RST_ARGS_FUNCTION 48 #define NUM_TYPES 49 /* T_STACK, T_SLOT, T_BAFFLE, T_DYNAMIC_WIND, and T_COUNTER are internal * I tried T_CASE_SELECTOR that turned a case statement into an array, but it was slower! */ typedef enum {TOKEN_EOF, TOKEN_LEFT_PAREN, TOKEN_RIGHT_PAREN, TOKEN_DOT, TOKEN_ATOM, TOKEN_QUOTE, TOKEN_DOUBLE_QUOTE, TOKEN_BACK_QUOTE, TOKEN_COMMA, TOKEN_AT_MARK, TOKEN_SHARP_CONST, TOKEN_VECTOR, TOKEN_BYTE_VECTOR} token_t; typedef enum {FILE_PORT, STRING_PORT, FUNCTION_PORT} port_type_t; typedef struct { bool needs_free; FILE *file; char *filename; int filename_length, gc_loc; void *next; s7_pointer (*input_function)(s7_scheme *sc, s7_read_t read_choice, s7_pointer port); void (*output_function)(s7_scheme *sc, unsigned char c, s7_pointer port); /* a version of string ports using a pointer to the current location and a pointer to the end * (rather than an integer for both, indexing from the base string) was not faster. */ s7_pointer orig_str; /* GC protection for string port string */ int (*read_character)(s7_scheme *sc, s7_pointer port); /* function to read a character */ void (*write_character)(s7_scheme *sc, int c, s7_pointer port); /* function to write a character */ void (*write_string)(s7_scheme *sc, const char *str, int len, s7_pointer port); /* function to write a string of known length */ token_t (*read_semicolon)(s7_scheme *sc, s7_pointer port); /* internal skip-to-semicolon reader */ int (*read_white_space)(s7_scheme *sc, s7_pointer port); /* internal skip white space reader */ s7_pointer (*read_name)(s7_scheme *sc, s7_pointer pt); /* internal get-next-name reader */ s7_pointer (*read_sharp)(s7_scheme *sc, s7_pointer pt); /* internal get-next-sharp-constant reader */ s7_pointer (*read_line)(s7_scheme *sc, s7_pointer pt, bool eol_case, bool copied); /* function to read a string up to \n */ void (*display)(s7_scheme *sc, const char *s, s7_pointer pt); } port_t; typedef struct { const char *name; int name_length; unsigned int id; char *doc; s7_pointer generic_ff; s7_pointer signature; s7_pointer (*chooser)(s7_scheme *sc, s7_pointer f, int args, s7_pointer expr); s7_pointer *arg_defaults, *arg_names; s7_pointer call_args; s7_rp_t rp; s7_ip_t ip; s7_pp_t pp, gp; } c_proc_t; typedef struct { /* call/cc */ unsigned int stack_size, op_stack_loc, op_stack_size; int local_key; /* for with-baffle */ } continuation_t; typedef struct vdims_t { unsigned int ndims; bool elements_allocated, dimensions_allocated; /* these are allocated as bytes, not ints, so the struct size is 32 */ s7_int *dims, *offsets; s7_pointer original; } vdims_t; typedef struct { int type; unsigned int outer_type; const char *name; s7_pointer scheme_name; char *(*print)(s7_scheme *sc, void *value); void (*free)(void *value); bool (*equal)(void *val1, void *val2); void (*gc_mark)(void *val); s7_pointer (*ref)(s7_scheme *sc, s7_pointer obj, s7_pointer args); s7_pointer (*set)(s7_scheme *sc, s7_pointer obj, s7_pointer args); s7_pointer (*length)(s7_scheme *sc, s7_pointer obj); s7_pointer (*copy)(s7_scheme *sc, s7_pointer args); s7_pointer (*reverse)(s7_scheme *sc, s7_pointer obj); s7_pointer (*fill)(s7_scheme *sc, s7_pointer args); char *(*print_readably)(s7_scheme *sc, void *value); s7_pointer (*direct_ref)(s7_scheme *sc, s7_pointer obj, s7_int index); s7_pointer (*direct_set)(s7_scheme *sc, s7_pointer obj, s7_int index, s7_pointer val); s7_ip_t ip, set_ip; s7_rp_t rp, set_rp; } c_object_t; typedef struct hash_entry_t { s7_pointer key, value; struct hash_entry_t *next; unsigned int raw_hash; } hash_entry_t; typedef unsigned int (*hash_map_t)(s7_scheme *sc, s7_pointer table, s7_pointer key); /* hash-table object->location mapper */ typedef hash_entry_t *(*hash_check_t)(s7_scheme *sc, s7_pointer table, s7_pointer key); /* hash-table object equality function */ static hash_map_t *default_hash_map; /* cell structure */ typedef struct s7_cell { union { unsigned int flag; unsigned char type_field; unsigned short sflag; } tf; int hloc; union { union { s7_int integer_value; s7_double real_value; struct { char padding[PRINT_NAME_PADDING]; char name[PRINT_NAME_SIZE + 2]; } pval; struct { s7_int numerator; s7_int denominator; } fraction_value; struct { s7_double rl; s7_double im; } complex_value; unsigned long ul_value; /* these two are not used by s7 in any way */ unsigned long long ull_value; #if WITH_GMP mpz_t big_integer; mpq_t big_ratio; mpfr_t big_real; mpc_t big_complex; /* using free_lists here was not faster, and avoiding the extra init/clear too tricky. These make up * no more than ca. 5% of the gmp computation -- it is totally dominated by stuff like __gmpz_mul, * so I can't see much point in optimizing the background noise. In a very numerical context, * gmp slows us down by a factor of 50. */ #endif } number; struct { port_t *port; unsigned char *data; unsigned int size, point; /* these limit the in-core portion of a string-port to 2^31 bytes */ unsigned int line_number, file_number; bool is_closed; port_type_t ptype; } prt; struct{ unsigned char c, up_c; int length; bool alpha_c, digit_c, space_c, upper_c, lower_c; char c_name[12]; } chr; void *c_pointer; int baffle_key; struct { s7_int length; union { s7_pointer *objects; s7_int *ints; s7_double *floats; } elements; vdims_t *dim_info; s7_pointer (*vget)(s7_scheme *sc, s7_pointer vec, s7_int loc); s7_pointer (*vset)(s7_scheme *sc, s7_pointer vec, s7_int loc, s7_pointer val); } vector; struct { s7_int length; s7_pointer *objects; vdims_t *dim_info; int top; } stk; struct { unsigned int mask, entries; hash_entry_t **elements; hash_check_t hash_func; hash_map_t *loc; s7_pointer dproc; } hasher; struct { s7_pointer obj, cur; union { s7_int loc; s7_pointer lcur; } lc; union { s7_int len; s7_pointer slow; hash_entry_t *hcur; } lw; s7_pointer (*next)(s7_scheme *sc, s7_pointer iterator); } iter; struct { c_proc_t *c_proc; /* C functions, macros */ s7_function ff; s7_pointer setter; unsigned int required_args, optional_args, all_args; bool rest_arg; } fnc; struct { /* pairs */ s7_pointer car, cdr, opt1, opt2, opt3; } cons; struct { s7_pointer sym_car, sym_cdr; unsigned long long int hash; const char *fstr; unsigned int op, line; } sym_cons; struct { s7_pointer args, body, env, setter; int arity; } func; struct { unsigned int length; union { bool needs_free; int accessor; } str_ext; char *svalue; unsigned long long int hash; /* string hash-index */ s7_pointer initial_slot; union { char *documentation; s7_pointer ksym; } doc; } string; struct { /* symbols */ s7_pointer name, global_slot, local_slot; long long int id; unsigned int op, tag; } sym; struct { /* syntax */ s7_pointer symbol; int op; short min_args, max_args; s7_rp_t rp; s7_ip_t ip; s7_pp_t pp; } syn; struct { /* slots (bindings) */ s7_pointer sym, val, nxt, pending_value, expr; } slt; struct { /* environments (frames) */ s7_pointer slots, nxt; long long int id; /* id of rootlet is -1 */ union { struct { s7_pointer function; /* __func__ (code) if this is a funclet */ unsigned int line, file; /* __func__ location if it is known */ } efnc; struct { s7_pointer dox1, dox2; /* do loop variables */ } dox; struct { /* (catch #t ...) opts */ s7_pointer result; unsigned int op_stack_loc, goto_loc; } ctall; } edat; } envr; struct { /* these 3 are just place-holders */ s7_pointer unused_slots, unused_nxt; long long int unused_id; /* these two fields are for some special case objects like # */ const char *name; int len; } unq; struct { /* counter (internal) */ s7_pointer result, list, env; /* env = counter_let (curlet after map/for-each frame created) */ unsigned long long int cap; /* sc->capture_let_counter for frame reuse */ } ctr; struct { #if WITH_GMP gmp_randstate_t state; #else unsigned long long int seed, carry; #endif } rng; struct { /* additional object types (C) */ int type; void *value; /* the value the caller associates with the object */ s7_pointer e; /* the method list, if any (openlet) */ s7_pointer (*ref)(s7_scheme *sc, s7_pointer obj, s7_int pos); } c_obj; struct { continuation_t *continuation; s7_pointer stack; s7_pointer *stack_start, *stack_end, *op_stack; } cwcc; struct { /* call-with-exit */ unsigned int goto_loc, op_stack_loc; bool active; } rexit; struct { /* catch */ unsigned int goto_loc, op_stack_loc; s7_pointer tag; s7_pointer handler; } rcatch; /* C++ reserves "catch" I guess */ struct { /* dynamic-wind */ s7_pointer in, out, body; unsigned int state; } winder; } object; #if DEBUGGING int current_alloc_line, previous_alloc_line, current_alloc_type, previous_alloc_type, debugger_bits, gc_line, clear_line, alloc_line, uses; const char *current_alloc_func, *previous_alloc_func, *gc_func, *alloc_func; #endif } s7_cell; typedef struct { s7_pointer *objs; int size, top, ref; bool has_hits; int *refs; } shared_info; typedef struct { int loc, curly_len, ctr; char *curly_str; s7_pointer args, orig_str, curly_arg; s7_pointer port, strport; } format_data; typedef struct gc_obj { s7_pointer p; struct gc_obj *nxt; } gc_obj; typedef struct xf_t { s7_pointer *data, *cur, *end; s7_pointer e; int size; gc_obj *gc_list; struct xf_t *next; } xf_t; static s7_pointer *small_ints, *chars; static s7_pointer real_zero, real_NaN, real_pi, real_one, arity_not_set, max_arity, real_infinity, real_minus_infinity, minus_one, minus_two; struct s7_scheme { opcode_t op; /* making this global is much slower! */ s7_pointer value; s7_pointer args; /* arguments of current function */ s7_pointer code, cur_code; /* current code */ s7_pointer envir; /* curlet */ token_t tok; s7_pointer stack; /* stack is a vector */ unsigned int stack_size; s7_pointer *stack_start, *stack_end, *stack_resize_trigger; s7_pointer *op_stack, *op_stack_now, *op_stack_end; unsigned int op_stack_size, max_stack_size; s7_cell **heap, **free_heap, **free_heap_top, **free_heap_trigger, **previous_free_heap_top; unsigned int heap_size; int gc_freed; /* "int" or "unsigned int" seems safe here: * sizeof(s7_cell) = 48 bytes * so to get more than 2^32 actual objects would require ca 206 GBytes RAM * vectors might be full of the same object (sc->NIL for example), so there * we need ca 38 GBytes RAM (8 bytes per pointer). */ gc_obj *permanent_objects; s7_pointer protected_objects, protected_accessors; /* a vector of gc-protected objects */ unsigned int protected_objects_size, protected_objects_loc, protected_accessors_size, protected_accessors_loc; s7_pointer NIL; /* empty list */ s7_pointer T; /* #t */ s7_pointer F; /* #f */ s7_pointer EOF_OBJECT; /* # */ s7_pointer UNDEFINED; /* # */ s7_pointer UNSPECIFIED; /* # */ s7_pointer NO_VALUE; /* the (values) value */ s7_pointer ELSE; /* else */ s7_pointer GC_NIL; /* a marker for an unoccupied slot in sc->protected_objects (and other similar stuff) */ s7_pointer symbol_table; /* symbol table */ s7_pointer rootlet, shadow_rootlet; /* rootlet */ s7_int rootlet_entries; s7_pointer unlet; /* original bindings of predefined functions */ s7_pointer input_port; /* current-input-port */ s7_pointer input_port_stack; /* input port stack (load and read internally) */ s7_pointer output_port; /* current-output-port */ s7_pointer error_port; /* current-error-port */ s7_pointer owlet; /* owlet */ s7_pointer error_type, error_data, error_code, error_line, error_file; /* owlet slots */ s7_pointer standard_input, standard_output, standard_error; s7_pointer sharp_readers; /* the binding pair for the global *#readers* list */ s7_pointer load_hook; /* *load-hook* hook object */ s7_pointer unbound_variable_hook; /* *unbound-variable-hook* hook object */ s7_pointer missing_close_paren_hook; s7_pointer error_hook; /* *error-hook* hook object */ s7_pointer direct_str; bool gc_off; /* gc_off: if true, the GC won't run */ unsigned int gc_stats; unsigned int gensym_counter, cycle_counter, f_class, add_class, multiply_class, subtract_class, equal_class; int format_column; unsigned long long int capture_let_counter; bool symbol_table_is_locked; long long int let_number; double default_rationalize_error, morally_equal_float_epsilon, hash_table_float_epsilon; s7_int default_hash_table_length, initial_string_port_length, print_length, max_vector_length, max_string_length, max_list_length, max_vector_dimensions; s7_pointer stacktrace_defaults; vdims_t *wrap_only; char *typnam; int typnam_len; char *help_arglist; int print_width; s7_pointer *singletons; #define INITIAL_TMP_STR_SIZE 16 s7_pointer *tmp_strs; #define INITIAL_FILE_NAMES_SIZE 8 s7_pointer *file_names; int file_names_size, file_names_top; #define INITIAL_STRBUF_SIZE 1024 unsigned int strbuf_size; #define TMPBUF_SIZE 1024 char *strbuf, *tmpbuf; char *read_line_buf; unsigned int read_line_buf_size; s7_pointer v, w, x, y, z; /* evaluator local vars */ s7_pointer temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8, temp9, temp10; s7_pointer temp_cell, temp_cell_1, temp_cell_2; s7_pointer d1, d2, d3, d4; s7_pointer T1_1, T2_1, T2_2, T3_1, T3_2, T3_3, Z2_1, Z2_2; s7_pointer A1_1, A2_1, A2_2, A3_1, A3_2, A3_3, A4_1, A4_2, A4_3, A4_4; jmp_buf goto_start; bool longjmp_ok; void (*begin_hook)(s7_scheme *sc, bool *val); int no_values, current_line, s7_call_line, safety; const char *current_file, *s7_call_file, *s7_call_name; shared_info *circle_info; format_data **fdats; int num_fdats; s7_pointer elist_1, elist_2, elist_3, elist_4, elist_5, plist_1, plist_2, plist_3; s7_pointer *strings, *vectors, *input_ports, *output_ports, *continuations, *c_objects, *hash_tables, *gensyms, *setters; unsigned int strings_size, vectors_size, input_ports_size, output_ports_size, continuations_size, c_objects_size, hash_tables_size, gensyms_size, setters_size; unsigned int strings_loc, vectors_loc, input_ports_loc, output_ports_loc, continuations_loc, c_objects_loc, hash_tables_loc, gensyms_loc, setters_loc; unsigned int syms_tag; int ht_iter_tag, baffle_ctr, bignum_precision; s7_pointer default_rng; #if WITH_GMP s7_pointer *bigints, *bigratios, *bigreals, *bignumbers; int bigints_size, bigratios_size, bigreals_size, bignumbers_size; int bigints_loc, bigratios_loc, bigreals_loc, bignumbers_loc; #endif /* these are symbols, primarily for the generic function search */ s7_pointer SUBTRACT, MULTIPLY, ADD, DIVIDE, LT, LEQ, EQ, GT, GEQ, ABS, ACOS, ACOSH; s7_pointer ANGLE, APPEND, APPLY, IS_ARITABLE, ARITY, ASH, ASIN, ASINH, ASSOC, ASSQ, ASSV, ATAN, ATANH; s7_pointer SUBLET, VARLET, UNLET, CUTLET, AUTOLOAD, AUTOLOADER, IS_BOOLEAN, BYTE_VECTOR, IS_BYTE_VECTOR, CAAAAR, CAAADR, CAAAR, CAADAR, CAADDR; s7_pointer CAADR, CAAR, CADAAR, CADADR, CADAR, CADDAR, CADDDR, CADDR, CADR, CALL_CC, CALL_WITH_CURRENT_CONTINUATION, CALL_WITH_EXIT, COVERLET; s7_pointer CALL_WITH_INPUT_FILE, CALL_WITH_INPUT_STRING, CALL_WITH_OUTPUT_FILE, CALL_WITH_OUTPUT_STRING, CAR, CATCH, CDAAAR; s7_pointer CDAADR, CDAAR, CDADAR, CDADDR, CDADR, CDAR, CDDAAR, CDDADR, CDDAR, CDDDAR, CDDDDR, CDDDR, CDDR, CDR, CEILING, CURLET; s7_pointer CHAR_LEQ, CHAR_LT, CHAR_EQ, CHAR_GEQ, CHAR_GT, IS_CHAR, CHAR_POSITION, CHAR_TO_INTEGER, IS_CHAR_ALPHABETIC; s7_pointer CHAR_DOWNCASE, IS_CHAR_LOWER_CASE, IS_CHAR_NUMERIC, CHAR_UPCASE, IS_CHAR_UPPER_CASE; s7_pointer IS_CHAR_WHITESPACE, CLOSE_INPUT_PORT, CLOSE_OUTPUT_PORT, IS_COMPLEX, CONS, IS_CONSTANT, IS_CONTINUATION, COPY, COS, COSH; s7_pointer CURRENT_INPUT_PORT, CURRENT_OUTPUT_PORT, CURRENT_ERROR_PORT, C_POINTER, IS_C_POINTER, IS_C_OBJECT; s7_pointer IS_DEFINED, DENOMINATOR, DISPLAY, DYNAMIC_WIND, IS_LET, INLET, LET_REF, LET_REF_FALLBACK, LET_SET, LET_SET_FALLBACK; s7_pointer IS_EOF_OBJECT, IS_EQ, IS_EQUAL, IS_EQV, ERROR, EVAL, EVAL_STRING, IS_EVEN, IS_EXACT; s7_pointer EXACT_TO_INEXACT, EXP, EXPT, FILL, INT_VECTOR_REF, INT_VECTOR_SET; s7_pointer MAKE_FLOAT_VECTOR, FLOAT_VECTOR, IS_FLOAT_VECTOR, FLOAT_VECTOR_REF, FLOAT_VECTOR_SET, MAKE_INT_VECTOR, INT_VECTOR, IS_INT_VECTOR; s7_pointer FLOOR, FLUSH_OUTPUT_PORT, FORMAT, FOR_EACH, GC, GCD, GENSYM, IS_GENSYM, GET_OUTPUT_STRING, HASH_TABLE, HASH_TABLE_STAR; s7_pointer IS_HASH_TABLE, HASH_TABLE_REF, HASH_TABLE_SET, HASH_TABLE_ENTRIES, HELP, IMAG_PART, IS_INEXACT, INEXACT_TO_EXACT; s7_pointer IS_INFINITE, IS_INPUT_PORT, IS_INTEGER, INTEGER_TO_CHAR, INTEGER_DECODE_FLOAT, IS_KEYWORD, KEYWORD_TO_SYMBOL; s7_pointer LCM, LENGTH, IS_SEQUENCE, IS_ITERATOR, MAKE_ITERATOR, ITERATE, ITERATOR_SEQUENCE, ITERATOR_IS_AT_END; s7_pointer LIST, IS_LIST, LIST_REF, LIST_SET, LIST_TAIL, LOAD, LOG, LOGAND, LOGBIT, LOGIOR, LOGNOT, LOGXOR; s7_pointer IS_MACRO, MAKE_BYTE_VECTOR, MAKE_HASH_TABLE, MAKE_KEYWORD, MAKE_LIST, RANDOM_STATE; s7_pointer MAKE_STRING, MAKE_SHARED_VECTOR, MAKE_VECTOR, MAP, MAX, MEMBER, MEMQ, MEMV, MIN, MODULO, IS_MORALLY_EQUAL, IS_NAN, IS_NEGATIVE, NEWLINE; s7_pointer NOT, IS_NULL, IS_NUMBER, NUMBER_TO_STRING, NUMERATOR, OBJECT_TO_STRING, IS_ODD, OPENLET, IS_OPENLET, OPEN_INPUT_FILE; s7_pointer OPEN_INPUT_STRING, OPEN_OUTPUT_FILE, OUTLET, IS_OUTPUT_PORT, OWLET, IS_PAIR, PAIR_LINE_NUMBER, PEEK_CHAR; s7_pointer IS_PORT_CLOSED, PORT_FILENAME, PORT_LINE_NUMBER, IS_PROPER_LIST; s7_pointer IS_POSITIVE, IS_PROCEDURE, PROCEDURE_DOCUMENTATION, PROCEDURE_SIGNATURE, FUNCLET, PROCEDURE_SOURCE; s7_pointer IS_DILAMBDA, PROVIDE, ROOTLET; s7_pointer IS_PROVIDED, QUOTIENT, RANDOM, IS_RANDOM_STATE, RANDOM_STATE_TO_LIST, RATIONALIZE, IS_RATIONAL, READ, READ_BYTE, READ_CHAR, READ_LINE, IS_REAL; s7_pointer READ_STRING, REAL_PART, REMAINDER, REQUIRE, REVERSE, REVERSEB, ROUND, SET_CAR, SET_CDR, SIN, SINH, SORT, SQRT, STACKTRACE; s7_pointer STRING, STRING_DOWNCASE, STRING_UPCASE, STRING_LEQ, STRING_LT, STRING_EQ; s7_pointer STRING_GEQ, STRING_GT, IS_STRING, STRING_POSITION, STRING_TO_NUMBER, STRING_TO_SYMBOL, STRING_APPEND; s7_pointer STRING_FILL, STRING_REF, STRING_SET, SUBSTRING, SYMBOL; s7_pointer SYMBOL_ACCESS, IS_SYMBOL, SYMBOL_TO_KEYWORD, SYMBOL_TO_STRING, SYMBOL_TO_DYNAMIC_VALUE, SYMBOL_TO_VALUE; s7_pointer TAN, TANH, THROW, TO_BYTE_VECTOR, TRUNCATE, VALUES, VECTOR, VECTOR_APPEND, VECTOR_FILL; s7_pointer IS_VECTOR, VECTOR_DIMENSIONS, VECTOR_REF, VECTOR_SET, WITH_INPUT_FROM_FILE; s7_pointer WITH_INPUT_FROM_STRING, WITH_OUTPUT_TO_FILE, WITH_OUTPUT_TO_STRING, WRITE, WRITE_BYTE, WRITE_CHAR, WRITE_STRING, IS_ZERO; s7_pointer S7_FEATURES, LOAD_PATH, PI, MAGNITUDE, COMPLEX; #if (!WITH_PURE_S7) s7_pointer IS_CHAR_READY, CHAR_CI_LEQ, CHAR_CI_LT, CHAR_CI_EQ, CHAR_CI_GEQ, CHAR_CI_GT, LET_TO_LIST, INTEGER_LENGTH; s7_pointer STRING_CI_LEQ, STRING_CI_LT, STRING_CI_EQ, STRING_CI_GEQ, STRING_CI_GT, STRING_TO_LIST, VECTOR_TO_LIST; s7_pointer STRING_LENGTH, STRING_COPY, LIST_TO_STRING, LIST_TO_VECTOR, VECTOR_LENGTH, MAKE_POLAR, MAKE_RECTANGULAR; #endif #if WITH_GMP s7_pointer BIGNUM, IS_BIGNUM; #endif #if WITH_SYSTEM_EXTRAS s7_pointer IS_DIRECTORY, FILE_EXISTS, DELETE_FILE, GETENV, SYSTEM, DIRECTORY_TO_LIST, FILE_MTIME; #endif /* these are the associated functions, not symbols */ s7_pointer Vector_Set, String_Set, List_Set, Hash_Table_Set, Let_Set; /* Cons (see the setter stuff at the end) */ s7_pointer LAMBDA, LAMBDA_STAR, LET, QUOTE, UNQUOTE, MACROEXPAND, DEFINE_EXPANSION, BAFFLE, WITH_LET, DOCUMENTATION, SIGNATURE; s7_pointer IF, WHEN, UNLESS, BEGIN, COND, CASE, AND, OR, DO, DEFINE, DEFINE_STAR, DEFINE_CONSTANT, WITH_BAFFLE; s7_pointer DEFINE_MACRO, DEFINE_MACRO_STAR, DEFINE_BACRO, DEFINE_BACRO_STAR; s7_pointer LETREC, LETREC_STAR, LET_STAR; s7_pointer SET, QQ_List, QQ_Apply_Values, QQ_Append, Multivector; s7_pointer Apply, Vector; s7_pointer WRONG_TYPE_ARG, wrong_type_arg_info, OUT_OF_RANGE, out_of_range_info; s7_pointer simple_wrong_type_arg_info, simple_out_of_range_info, DIVISION_BY_ZERO, DIVISION_BY_ZERO_ERROR, NO_CATCH, IO_ERROR, INVALID_ESCAPE_FUNCTION; s7_pointer FORMAT_ERROR, WRONG_NUMBER_OF_ARGS, READ_ERROR, STRING_READ_ERROR, SYNTAX_ERROR, TOO_MANY_ARGUMENTS, NOT_ENOUGH_ARGUMENTS; s7_pointer KEY_REST, KEY_ALLOW_OTHER_KEYS, KEY_READABLE, BAFFLED; s7_pointer __FUNC__; s7_pointer Object_Set; /* applicable object set method */ s7_pointer FEED_TO; /* => */ s7_pointer BODY, CLASS_NAME, IS_FLOAT, IS_INTEGER_OR_REAL_AT_END, IS_INTEGER_OR_ANY_AT_END; s7_pointer QUOTE_UNCHECKED, BEGIN_UNCHECKED, CASE_UNCHECKED, SET_UNCHECKED, LAMBDA_UNCHECKED, LET_UNCHECKED, WITH_LET_UNCHECKED, WITH_LET_S; s7_pointer LET_STAR_UNCHECKED, LETREC_UNCHECKED, LETREC_STAR_UNCHECKED, COND_UNCHECKED, COND_SIMPLE, WITH_BAFFLE_UNCHECKED; s7_pointer SET_SYMBOL_C, SET_SYMBOL_S, SET_SYMBOL_Q, SET_SYMBOL_P, SET_SYMBOL_Z, SET_SYMBOL_A; s7_pointer SET_SYMBOL_opSq, SET_SYMBOL_opSSq, SET_SYMBOL_opSSSq, SET_SYMBOL_opCq; s7_pointer SET_NORMAL, SET_PAIR, SET_PAIR_Z, SET_PAIR_A, SET_PAIR_ZA, SET_PAIR_P, SET_PWS, SET_LET_S, SET_LET_ALL_X, SET_PAIR_C, SET_PAIR_C_P; s7_pointer LAMBDA_STAR_UNCHECKED, DO_UNCHECKED, DEFINE_UNCHECKED, DEFINE_FUNCHECKED, DEFINE_STAR_UNCHECKED, DEFINE_CONSTANT_UNCHECKED; s7_pointer CASE_SIMPLE, CASE_SIMPLER, CASE_SIMPLER_1, CASE_SIMPLER_SS, CASE_SIMPLEST, CASE_SIMPLEST_SS; s7_pointer LET_C, LET_S, LET_ALL_C, LET_ALL_S, LET_ALL_X; s7_pointer LET_STAR_ALL_X, LET_opCq, LET_opSSq; s7_pointer LET_NO_VARS, NAMED_LET, NAMED_LET_NO_VARS, NAMED_LET_STAR, LET_STAR2, IF_UNCHECKED, AND_UNCHECKED, AND_P, AND_P2, OR_UNCHECKED, OR_P, OR_P2; s7_pointer IF_P_P_P, IF_P_P, IF_S_P_P, IF_S_P, IF_P_FEED; s7_pointer IF_Z_P, IF_Z_P_P, IF_A_P, IF_A_P_P, IF_ANDP_P, IF_ANDP_P_P, IF_ORP_P, IF_ORP_P_P, IF_CC_P_P; s7_pointer IF_CS_P_P, IF_CC_P, IF_CS_P, IF_AND2_P, IF_AND2_P_P; s7_pointer IF_CSQ_P, IF_CSQ_P_P, IF_CSS_P, IF_CSS_P_P, IF_CSC_P, IF_CSC_P_P; s7_pointer IF_IS_PAIR_P, IF_IS_PAIR_P_P, IF_opSSq_P, IF_opSSq_P_P, IF_S_opCq_P, IF_S_opCq_P_P; s7_pointer IF_IS_SYMBOL_P, IF_IS_SYMBOL_P_P, IF_NOT_S_P, IF_NOT_S_P_P; s7_pointer WHEN_UNCHECKED, UNLESS_UNCHECKED, WHEN_S, UNLESS_S; s7_pointer COND_ALL_X, COND_ALL_X_2, COND_S; s7_pointer INCREMENT_1, DECREMENT_1, SET_CONS, INCREMENT_SS, INCREMENT_SSS, INCREMENT_SZ, INCREMENT_SA, INCREMENT_SAA; s7_pointer LET_opSq, LET_ALL_opSq, LET_opSq_P, LET_ONE, LET_Z; s7_pointer SIMPLE_DO, SAFE_DOTIMES, SAFE_DO, SIMPLE_DO_P, DOTIMES_P, SIMPLE_DO_A, SIMPLE_DO_E; s7_pointer DOX, dox_slot_symbol, else_symbol; s7_pointer *safe_lists, *syn_docs; /* prebuilt evaluator arg lists, syntax doc strings */ s7_pointer autoload_table, libraries; const char ***autoload_names; int *autoload_names_sizes; bool **autoloaded_already; int autoload_names_loc, autoload_names_top; port_t *port_heap; int format_depth; int slash_str_size; char *slash_str; xf_t *cur_rf; xf_t *rf_free_list, *rf_stack; /* s7 env symbols */ s7_pointer stack_top_symbol, symbol_table_is_locked_symbol, heap_size_symbol, gc_freed_symbol, gc_protected_objects_symbol; s7_pointer free_heap_size_symbol, file_names_symbol, symbol_table_symbol, cpu_time_symbol, c_objects_symbol, float_format_precision_symbol; s7_pointer stack_size_symbol, rootlet_size_symbol, c_types_symbol, safety_symbol, max_stack_size_symbol, gc_stats_symbol; s7_pointer strings_symbol, vectors_symbol, input_ports_symbol, output_ports_symbol, continuations_symbol, hash_tables_symbol, gensyms_symbol; s7_pointer catches_symbol, exits_symbol, stack_symbol, default_rationalize_error_symbol, max_string_length_symbol, default_random_state_symbol; s7_pointer max_list_length_symbol, max_vector_length_symbol, max_vector_dimensions_symbol, default_hash_table_length_symbol; s7_pointer hash_table_float_epsilon_symbol, morally_equal_float_epsilon_symbol, initial_string_port_length_symbol, memory_usage_symbol; s7_pointer undefined_identifier_warnings_symbol, print_length_symbol, bignum_precision_symbol, stacktrace_defaults_symbol; bool undefined_identifier_warnings; }; typedef enum {USE_DISPLAY, USE_WRITE, USE_READABLE_WRITE, USE_WRITE_WRONG} use_write_t; #define NUM_SAFE_LISTS 16 #define INITIAL_AUTOLOAD_NAMES_SIZE 4 static s7_pointer prepackaged_type_names[NUM_TYPES]; static bool t_number_p[NUM_TYPES], t_real_p[NUM_TYPES], t_rational_p[NUM_TYPES]; static bool t_simple_p[NUM_TYPES]; static bool t_big_number_p[NUM_TYPES]; static bool t_structure_p[NUM_TYPES]; static bool t_any_macro_p[NUM_TYPES]; static bool t_any_closure_p[NUM_TYPES]; static bool t_has_closure_let[NUM_TYPES]; static bool t_sequence_p[NUM_TYPES]; static bool t_vector_p[NUM_TYPES]; static bool t_applicable_p[NUM_TYPES]; static void init_types(void) { int i; for (i = 0; i < NUM_TYPES; i++) { t_number_p[i] = false; t_real_p[i] = false; t_rational_p[i] = false; t_simple_p[i] = false; t_structure_p[i] = false; t_any_macro_p[i] = false; t_any_closure_p[i] = false; t_has_closure_let[i] = false; t_sequence_p[i] = false; t_vector_p[i] = false; t_applicable_p[i] = false; } t_number_p[T_INTEGER] = true; t_number_p[T_RATIO] = true; t_number_p[T_REAL] = true; t_number_p[T_COMPLEX] = true; t_rational_p[T_INTEGER] = true; t_rational_p[T_RATIO] = true; t_real_p[T_INTEGER] = true; t_real_p[T_RATIO] = true; t_real_p[T_REAL] = true; t_big_number_p[T_BIG_INTEGER] = true; t_big_number_p[T_BIG_RATIO] = true; t_big_number_p[T_BIG_REAL] = true; t_big_number_p[T_BIG_COMPLEX] = true; t_structure_p[T_PAIR] = true; t_structure_p[T_VECTOR] = true; t_structure_p[T_HASH_TABLE] = true; t_structure_p[T_SLOT] = true; t_structure_p[T_LET] = true; t_structure_p[T_ITERATOR] = true; t_sequence_p[T_NIL] = true; t_sequence_p[T_PAIR] = true; t_sequence_p[T_STRING] = true; t_sequence_p[T_VECTOR] = true; t_sequence_p[T_INT_VECTOR] = true; t_sequence_p[T_FLOAT_VECTOR] = true; t_sequence_p[T_HASH_TABLE] = true; t_sequence_p[T_LET] = true; t_sequence_p[T_C_OBJECT] = true; t_vector_p[T_VECTOR] = true; t_vector_p[T_INT_VECTOR] = true; t_vector_p[T_FLOAT_VECTOR] = true; t_applicable_p[T_PAIR] = true; t_applicable_p[T_STRING] = true; t_applicable_p[T_VECTOR] = true; t_applicable_p[T_INT_VECTOR] = true; t_applicable_p[T_FLOAT_VECTOR] = true; t_applicable_p[T_HASH_TABLE] = true; t_applicable_p[T_ITERATOR] = true; t_applicable_p[T_LET] = true; t_applicable_p[T_C_OBJECT] = true; t_applicable_p[T_C_MACRO] = true; t_applicable_p[T_MACRO] = true; t_applicable_p[T_BACRO] = true; t_applicable_p[T_MACRO_STAR] = true; t_applicable_p[T_BACRO_STAR] = true; t_applicable_p[T_SYNTAX] = true; t_applicable_p[T_C_FUNCTION] = true; t_applicable_p[T_C_FUNCTION_STAR] = true; t_applicable_p[T_C_ANY_ARGS_FUNCTION] = true; t_applicable_p[T_C_OPT_ARGS_FUNCTION] = true; t_applicable_p[T_C_RST_ARGS_FUNCTION] = true; t_applicable_p[T_CLOSURE] = true; t_applicable_p[T_CLOSURE_STAR] = true; t_applicable_p[T_GOTO] = true; t_applicable_p[T_CONTINUATION] = true; t_any_macro_p[T_C_MACRO] = true; t_any_macro_p[T_MACRO] = true; t_any_macro_p[T_BACRO] = true; t_any_macro_p[T_MACRO_STAR] = true; t_any_macro_p[T_BACRO_STAR] = true; t_any_closure_p[T_CLOSURE] = true; t_any_closure_p[T_CLOSURE_STAR] = true; t_has_closure_let[T_MACRO] = true; t_has_closure_let[T_BACRO] = true; t_has_closure_let[T_MACRO_STAR] = true; t_has_closure_let[T_BACRO_STAR] = true; t_has_closure_let[T_CLOSURE] = true; t_has_closure_let[T_CLOSURE_STAR] = true; t_simple_p[T_NIL] = true; t_simple_p[T_UNIQUE] = true; t_simple_p[T_BOOLEAN] = true; t_simple_p[T_CHARACTER] = true; t_simple_p[T_SYMBOL] = true; t_simple_p[T_SYNTAX] = true; t_simple_p[T_C_MACRO] = true; t_simple_p[T_C_FUNCTION] = true; t_simple_p[T_C_FUNCTION_STAR] = true; t_simple_p[T_C_ANY_ARGS_FUNCTION] = true; t_simple_p[T_C_OPT_ARGS_FUNCTION] = true; t_simple_p[T_C_RST_ARGS_FUNCTION] = true; /* not completely sure about the next ones */ t_simple_p[T_LET] = true; t_simple_p[T_INPUT_PORT] = true; t_simple_p[T_OUTPUT_PORT] = true; } #define typeflag(p) ((p)->tf.flag) #define typesflag(p) ((p)->tf.sflag) static s7_scheme *hidden_sc = NULL; #if DEBUGGING static bool check_types = true; static const char *check_name(int typ); static s7_pointer check_seti(s7_scheme *sc, s7_pointer x, const char *func, int line); static s7_pointer check_ref(s7_pointer p, int expected_type, const char *func, int line, const char *func1, const char *func2); static s7_pointer check_ref2(s7_pointer p, int expected_type, int other_type, const char *func, int line, const char *func1, const char *func2); static s7_pointer check_ref3(s7_pointer p, const char *func, int line); static s7_pointer check_ref4(s7_pointer p, const char *func, int line); static s7_pointer check_ref5(s7_pointer p, const char *func, int line); static s7_pointer check_ref6(s7_pointer p, const char *func, int line); static s7_pointer check_ref7(s7_pointer p, const char *func, int line); static s7_pointer check_ref8(s7_pointer p, const char *func, int line); static s7_pointer check_ref9(s7_pointer p, const char *func, int line); static s7_pointer check_nref(s7_pointer p, const char *func, int line); static void print_gc_info(s7_pointer obj, int line); static s7_pointer opt1_1(s7_scheme *sc, s7_pointer p, unsigned int role, const char *func, int line); static s7_pointer set_opt1_1(s7_scheme *sc, s7_pointer p, s7_pointer x, unsigned int role, const char *func, int line); static s7_pointer opt2_1(s7_scheme *sc, s7_pointer p, unsigned int role, const char *func, int line); static void set_opt2_1(s7_scheme *sc, s7_pointer p, s7_pointer x, unsigned int role, const char *func, int line); static s7_pointer opt3_1(s7_scheme *sc, s7_pointer p, unsigned int role, const char *func, int line); static void set_opt3_1(s7_scheme *sc, s7_pointer p, s7_pointer x, unsigned int role, const char *func, int line); static unsigned long long int s_hash_1(s7_scheme *sc, s7_pointer p, const char *func, int line); static void set_s_hash_1(s7_scheme *sc, s7_pointer p, unsigned long long int x, const char *func, int line); static const char *s_name_1(s7_scheme *sc, s7_pointer p, const char *func, int line); static void set_s_name_1(s7_scheme *sc, s7_pointer p, const char *str, const char *func, int line); static unsigned int s_line_1(s7_scheme *sc, s7_pointer p, const char *func, int line); static void set_s_line_1(s7_scheme *sc, s7_pointer p, unsigned int x, const char *func, int line); static unsigned int s_len_1(s7_scheme *sc, s7_pointer p, const char *func, int line); static void set_s_len_1(s7_scheme *sc, s7_pointer p, unsigned int x, const char *func, int line); static unsigned int s_op_1(s7_scheme *sc, s7_pointer p, const char *func, int line); static void set_s_op_1(s7_scheme *sc, s7_pointer p, unsigned int x, const char *func, int line); static unsigned int s_syn_op_1(s7_scheme *sc, s7_pointer p, const char *func, int line); static void set_s_syn_op_1(s7_scheme *sc, s7_pointer p, unsigned int x, const char *func, int line); #define unchecked_type(p) ((p)->tf.type_field) #define type(p) ({unsigned char _t_; _t_ = (p)->tf.type_field; if (((check_types) && (_t_ == T_FREE)) || (_t_ >= NUM_TYPES)) print_gc_info(p, __LINE__); _t_;}) #define set_type(p, f) \ do { \ p->previous_alloc_line = p->current_alloc_line; \ p->previous_alloc_func = p->current_alloc_func; \ p->previous_alloc_type = p->current_alloc_type; \ p->current_alloc_line = __LINE__; \ p->current_alloc_func = __func__; \ p->current_alloc_type = f; \ p->uses++; p->clear_line = 0; \ if ((((f) & 0xff) == T_FREE) || (((f) & 0xff) >= NUM_TYPES)) \ fprintf(stderr, "%d: set free %p type to %x\n", __LINE__, p, f); \ else \ { \ if (((typeflag(p) & T_IMMUTABLE) != 0) && ((typeflag(p) != (f)))) \ fprintf(stderr, "%d: set immutable %p type %x to %x\n", __LINE__, p, unchecked_type(p), f); \ } \ typeflag(p) = f; \ } while (0) #define clear_type(p) do {p->clear_line = __LINE__; typeflag(p) = T_FREE;} while (0) /* these check most s7cell field references (and many type bits) for consistency */ #define _TI(P) check_ref(P, T_INTEGER, __func__, __LINE__, NULL, NULL) #define _TR(P) check_ref(P, T_REAL, __func__, __LINE__, NULL, NULL) #define _TF(P) check_ref2(P, T_RATIO, T_INTEGER, __func__, __LINE__, NULL, NULL) #define _TZ(P) check_ref(P, T_COMPLEX, __func__, __LINE__, NULL, NULL) #define _TBgi(P) check_ref(P, T_BIG_INTEGER, __func__, __LINE__, "sweep", NULL) #define _TBgr(P) check_ref(P, T_BIG_REAL, __func__, __LINE__, "sweep", NULL) #define _TBgf(P) check_ref(P, T_BIG_RATIO, __func__, __LINE__, "sweep", NULL) #define _TBgz(P) check_ref(P, T_BIG_COMPLEX, __func__, __LINE__, "sweep", NULL) #define _TChr(P) check_ref(P, T_CHARACTER, __func__, __LINE__, NULL, NULL) #define _TCtr(P) check_ref(P, T_COUNTER, __func__, __LINE__, NULL, NULL) #define _TPtr(P) check_ref(P, T_C_POINTER, __func__, __LINE__, NULL, NULL) #define _TBfl(P) check_ref(P, T_BAFFLE, __func__, __LINE__, NULL, NULL) #define _TGot(P) check_ref(P, T_GOTO, __func__, __LINE__, NULL, NULL) #define _TStk(P) check_ref(P, T_STACK, __func__, __LINE__, NULL, NULL) #define _TLst(P) check_ref(P, T_PAIR, __func__, __LINE__, NULL, NULL) #define _TCat(P) check_ref(P, T_CATCH, __func__, __LINE__, NULL, NULL) #define _TDyn(P) check_ref(P, T_DYNAMIC_WIND, __func__, __LINE__, NULL, NULL) #define _TSlt(P) check_ref(P, T_SLOT, __func__, __LINE__, NULL, NULL) #define _TSlp(P) check_ref2(P, T_SLOT, T_PAIR, __func__, __LINE__, NULL, NULL) #define _TSyn(P) check_ref(P, T_SYNTAX, __func__, __LINE__, NULL, NULL) #define _TMac(P) check_ref(P, T_C_MACRO, __func__, __LINE__, NULL, NULL) #define _TLet(P) check_ref(P, T_LET, __func__, __LINE__, NULL, NULL) #define _TLid(P) check_ref2(P, T_LET, T_NIL, __func__, __LINE__, NULL, NULL) #define _TRan(P) check_ref(P, T_RANDOM_STATE, __func__, __LINE__, NULL, NULL) #define _TCdr(P) check_ref2(P, T_PAIR, T_NIL, __func__, __LINE__, "gc", NULL) #define _TStr(P) check_ref(P, T_STRING, __func__, __LINE__, "sweep", NULL) #define _TObj(P) check_ref(P, T_C_OBJECT, __func__, __LINE__, "free_object", NULL) #define _THsh(P) check_ref(P, T_HASH_TABLE, __func__, __LINE__, "sweep", "free_hash_table") #define _TItr(P) check_ref(P, T_ITERATOR, __func__, __LINE__, "sweep", NULL) #define _TCon(P) check_ref(P, T_CONTINUATION, __func__, __LINE__, "sweep", NULL) #define _TFvc(P) check_ref(P, T_FLOAT_VECTOR, __func__, __LINE__, "sweep", NULL) #define _TIvc(P) check_ref(P, T_INT_VECTOR, __func__, __LINE__, "sweep", NULL) #define _TSym(P) check_ref(P, T_SYMBOL, __func__, __LINE__, "sweep", "remove_gensym_from_symbol_table") #define _TPrt(P) check_ref3(P, __func__, __LINE__) /* input|output_port, or free */ #define _TVec(P) check_ref4(P, __func__, __LINE__) /* any vector or free */ #define _TClo(P) check_ref5(P, __func__, __LINE__) /* has closure let */ #define _TFnc(P) check_ref6(P, __func__, __LINE__) /* any c_function|c_macro */ #define _TNum(P) check_ref7(P, __func__, __LINE__) /* any number (not bignums I think) */ #define _TSeq(P) check_ref8(P, __func__, __LINE__) /* any sequence or structure */ #define _TMet(P) check_ref9(P, __func__, __LINE__) /* anything that might contain a method */ #define _NFre(P) check_nref(P, __func__, __LINE__) /* not free */ #define _TSet(P) check_seti(sc, P, __func__, __LINE__) /* set of immutable value */ #else #define unchecked_type(p) ((p)->tf.type_field) #define type(p) ((p)->tf.type_field) #define set_type(p, f) typeflag(p) = f #define clear_type(p) typeflag(p) = T_FREE #define _TSet(P) P #define _TI(P) P #define _TR(P) P #define _TF(P) P #define _TZ(P) P #define _TBgi(P) P #define _TBgr(P) P #define _TBgf(P) P #define _TBgz(P) P #define _TStr(P) P #define _TSyn(P) P #define _TChr(P) P #define _TObj(P) P #define _TCtr(P) P #define _THsh(P) P #define _TItr(P) P #define _TPtr(P) P #define _TBfl(P) P #define _TGot(P) P #define _TCon(P) P #define _TStk(P) P #define _TPrt(P) P #define _TIvc(P) P #define _TFvc(P) P #define _TVec(P) P #define _TLst(P) P #define _TRan(P) P #define _TDyn(P) P #define _TCat(P) P #define _TClo(P) P #define _TFnc(P) P #define _TSlt(P) P #define _TSlp(P) P #define _TSym(P) P #define _TLet(P) P #define _TLid(P) P #define _TCdr(P) P #define _TNum(P) P #define _TSeq(P) P #define _TMet(P) P #define _TMac(P) P #define _NFre(P) P #endif #define is_number(P) t_number_p[type(P)] #define is_integer(P) (type(P) == T_INTEGER) #define is_real(P) t_real_p[type(P)] #define is_rational(P) t_rational_p[type(P)] #define is_big_number(p) t_big_number_p[type(p)] #define is_t_integer(p) (type(p) == T_INTEGER) #define is_t_ratio(p) (type(p) == T_RATIO) #define is_t_real(p) (type(p) == T_REAL) #define is_t_complex(p) (type(p) == T_COMPLEX) #define is_t_big_integer(p) (type(p) == T_BIG_INTEGER) #define is_t_big_ratio(p) (type(p) == T_BIG_RATIO) #define is_t_big_real(p) (type(p) == T_BIG_REAL) #define is_t_big_complex(p) (type(p) == T_BIG_COMPLEX) #define is_free(p) (type(p) == T_FREE) #define is_free_and_clear(p) (typeflag(p) == T_FREE) #define is_simple(P) t_simple_p[type(P)] #define has_structure(P) t_structure_p[type(P)] #define is_any_macro(P) t_any_macro_p[type(P)] #define is_any_closure(P) t_any_closure_p[type(P)] #define is_procedure_or_macro(P) ((t_any_macro_p[type(P)]) || ((typeflag(P) & T_PROCEDURE) != 0)) #define has_closure_let(P) t_has_closure_let[type(P)] #define is_simple_sequence(P) (t_sequence_p[type(P)]) #define is_sequence(P) ((t_sequence_p[type(P)]) || (has_methods(P))) #define is_applicable(P) (t_applicable_p[type(P)]) /* this misses #() which actually is not applicable to anything, probably "" also, and inapplicable c-objects like random-state */ /* the layout of these bits does matter in several cases -- in particular, don't use the second byte for anything * that might shadow SYNTACTIC_PAIR and OPTIMIZED_PAIR. */ #define TYPE_BITS 8 #define T_KEYWORD (1 << (TYPE_BITS + 0)) #define is_keyword(p) ((typesflag(_NFre(p)) & T_KEYWORD) != 0) /* this bit distinguishes a symbol from a symbol that is also a keyword * this should be ok in the second byte because keywords are constants in s7 (never syntax) */ #define T_SYNTACTIC (1 << (TYPE_BITS + 1)) #define is_syntactic(p) ((typesflag(_NFre(p)) & T_SYNTACTIC) != 0) #define is_syntactic_symbol(p) ((typesflag(_NFre(p)) & (T_SYNTACTIC | 0xff)) == (T_SYMBOL | T_SYNTACTIC)) #define SYNTACTIC_TYPE (unsigned short)(T_SYMBOL | T_DONT_EVAL_ARGS | T_SYNTACTIC) #define SYNTACTIC_PAIR (unsigned short)(T_PAIR | T_SYNTACTIC) /* this marks symbols that represent syntax objects, it should be in the second byte */ #define T_PROCEDURE (1 << (TYPE_BITS + 2)) #define is_procedure(p) ((typesflag(_NFre(p)) & T_PROCEDURE) != 0) /* closure, c_function, applicable object, goto or continuation, should be in second byte */ #define T_OPTIMIZED (1 << (TYPE_BITS + 3)) #define set_optimized(p) typesflag(_TLst(p)) |= T_OPTIMIZED #define clear_optimized(p) typesflag(_TLst(p)) &= (~T_OPTIMIZED) #define OPTIMIZED_PAIR (unsigned short)(T_PAIR | T_OPTIMIZED) #define is_optimized(p) (typesflag(p) == OPTIMIZED_PAIR) /* this is faster than the bit extraction above and the same speed as xor */ /* optimizer flag for an expression that has optimization info, it should be in the second byte */ #define T_SAFE_CLOSURE (1 << (TYPE_BITS + 4)) #define is_safe_closure(p) ((typesflag(_NFre(p)) & T_SAFE_CLOSURE) != 0) #define set_safe_closure(p) typesflag(p) |= T_SAFE_CLOSURE #define clear_safe_closure(p) typesflag(p) &= (~T_SAFE_CLOSURE) /* optimizer flag for a closure body that is completely simple (every expression is safe) * set_safe_closure happens only in optimize_lambda, clear only in procedure_source, bits only here * this has to be separate from T_SAFE_PROCEDURE, and should be in the second byte. * It can be set on either the body (a pair) or the closure itself. */ #define T_DONT_EVAL_ARGS (1 << (TYPE_BITS + 5)) #define dont_eval_args(p) ((typesflag(_NFre(p)) & T_DONT_EVAL_ARGS) != 0) /* this marks things that don't evaluate their arguments */ #define T_EXPANSION (1 << (TYPE_BITS + 6)) #define is_expansion(p) ((typesflag(_NFre(p)) & T_EXPANSION) != 0) #define clear_expansion(p) typesflag(_TSym(p)) &= (~T_EXPANSION) /* this marks the symbol associated with a run-time macro and distinguishes the value from an ordinary macro */ #define T_MULTIPLE_VALUE (1 << (TYPE_BITS + 7)) #define is_multiple_value(p) ((typesflag(_NFre(p)) & T_MULTIPLE_VALUE) != 0) #define set_multiple_value(p) typesflag(_TLst(p)) |= T_MULTIPLE_VALUE #define clear_multiple_value(p) typesflag(_TLst(p)) &= (~T_MULTIPLE_VALUE) #define multiple_value(p) p /* this bit marks a list (from "values") that is waiting for a * chance to be spliced into its caller's argument list. It is normally * on only for a very short time. */ #define T_MATCHED T_MULTIPLE_VALUE #define is_matched_pair(p) ((typesflag(_TLst(p)) & T_MATCHED) != 0) #define set_match_pair(p) typesflag(_TLst(p)) |= T_MATCHED #define clear_match_pair(p) typesflag(_TLst(p)) &= (~T_MATCHED) #define is_matched_symbol(p) ((typesflag(_TSym(p)) & T_MATCHED) != 0) #define set_match_symbol(p) typesflag(_TSym(p)) |= T_MATCHED #define clear_match_symbol(p) typesflag(_TSym(p)) &= (~T_MATCHED) #define T_GLOBAL (1 << (TYPE_BITS + 8)) #define is_global(p) ((typeflag(_TSym(p)) & T_GLOBAL) != 0) #define set_global(p) typeflag(_TSym(p)) |= T_GLOBAL #if 0 /* to find who is stomping on our symbols: */ static char *object_to_truncated_string(s7_scheme *sc, s7_pointer p, int len); static void set_local_1(s7_scheme *sc, s7_pointer symbol, const char *func, int line) { if ((is_global(symbol)) || (is_syntactic(symbol))) fprintf(stderr, "%s[%d]: %s%s%s in %s\n", func, line, BOLD_TEXT, DISPLAY(symbol), UNBOLD_TEXT, DISPLAY_80(sc->cur_code)); typeflag(symbol) = (typeflag(symbol) & ~(T_DONT_EVAL_ARGS | T_GLOBAL | T_SYNTACTIC)); } #define set_local(Symbol) set_local_1(sc, Symbol, __func__, __LINE__) #else #define set_local(p) typeflag(_TSym(p)) &= ~(T_DONT_EVAL_ARGS | T_GLOBAL | T_SYNTACTIC) #endif /* this marks something defined (bound) at the top-level, and never defined locally */ #define T_UNSAFE_DO T_GLOBAL #define is_unsafe_do(p) ((typeflag(_TLst(p)) & T_UNSAFE_DO) != 0) #define set_unsafe_do(p) typeflag(_TLst(p)) |= T_UNSAFE_DO #define is_unsafe_sort(p) is_unsafe_do(p) #define set_unsafe_sort(p) set_unsafe_do(p) /* marks do-loops (and sort functions) that resist optimization */ #define T_COLLECTED (1 << (TYPE_BITS + 9)) #define is_collected(p) ((typeflag(_TSeq(p)) & T_COLLECTED) != 0) #define set_collected(p) typeflag(_TSeq(p)) |= T_COLLECTED /* #define clear_collected(p) typeflag(_TSeq(p)) &= (~T_COLLECTED) */ /* this is a transient flag used by the printer to catch cycles. It affects only objects that have structure. * We can't use a low bit (bit 7 for example), because collect_shared_info inspects the object's type. */ #define T_LINE_NUMBER (1 << (TYPE_BITS + 10)) #define has_line_number(p) ((typeflag(_TLst(p)) & T_LINE_NUMBER) != 0) #define set_has_line_number(p) typeflag(_TLst(p)) |= T_LINE_NUMBER /* pair in question has line/file info added during read, or the environment has function placement info */ #define T_LOADER_PORT T_LINE_NUMBER #define is_loader_port(p) ((typeflag(_TPrt(p)) & T_LOADER_PORT) != 0) #define set_loader_port(p) typeflag(_TPrt(p)) |= T_LOADER_PORT #define clear_loader_port(p) typeflag(_TPrt(p)) &= (~T_LOADER_PORT) /* to block random load-time reads from screwing up the load process, this bit marks a port used by the loader */ #define T_HAS_ACCESSOR T_LINE_NUMBER #define symbol_has_accessor(p) ((typeflag(_TSym(p)) & T_HAS_ACCESSOR) != 0) #define symbol_set_has_accessor(p) typeflag(_TSym(p)) |= T_HAS_ACCESSOR #define slot_has_accessor(p) ((typeflag(_TSlt(p)) & T_HAS_ACCESSOR) != 0) #define slot_set_has_accessor(p) typeflag(_TSlt(p)) |= T_HAS_ACCESSOR /* marks a slot or symbol that has a setter */ #define T_WITH_LET_LET T_LINE_NUMBER #define is_with_let_let(p) ((typeflag(_TLet(p)) & T_WITH_LET_LET) != 0) #define set_with_let_let(p) typeflag(_TLet(p)) |= T_WITH_LET_LET /* marks a let that is the argument to with-let */ #define T_SIMPLE_DEFAULTS T_LINE_NUMBER #define has_simple_defaults(p) ((typeflag(_TFnc(p)) & T_SIMPLE_DEFAULTS) != 0) #define set_simple_defaults(p) typeflag(_TFnc(p)) |= T_SIMPLE_DEFAULTS #define clear_simple_defaults(p) typeflag(_TFnc(p)) &= (~T_SIMPLE_DEFAULTS) /* flag c_func_star arg defaults that need GC protection */ #define T_SHARED (1 << (TYPE_BITS + 11)) #define is_shared(p) ((typeflag(_TSeq(p)) & T_SHARED) != 0) #define set_shared(p) typeflag(_TSeq(p)) |= T_SHARED /* #define clear_shared(p) typeflag(_TSeq(p)) &= (~T_SHARED) */ #define clear_collected_and_shared(p) typeflag(p) &= (~(T_COLLECTED | T_SHARED)) /* this can clear free cells = calloc */ #define T_OVERLAY (1 << (TYPE_BITS + 12)) #define set_overlay(p) typeflag(_TLst(p)) |= T_OVERLAY #define is_overlaid(p) ((typeflag(_TLst(p)) & T_OVERLAY) != 0) /* optimizer flag that marks a cell whose opt_back [ie opt1] points to the previous cell in a list */ #define T_SAFE_PROCEDURE (1 << (TYPE_BITS + 13)) #define is_safe_procedure(p) ((typeflag(_NFre(p)) & T_SAFE_PROCEDURE) != 0) /* applicable objects that do not return or modify their arg list directly (no :rest arg in particular), * and that can't call apply themselves either directly or via s7_call, and that don't mess with the stack. */ #define T_CHECKED (1 << (TYPE_BITS + 14)) #define set_checked(p) typeflag(_TLst(p)) |= T_CHECKED #define is_checked(p) ((typeflag(_TLst(p)) & T_CHECKED) != 0) #define clear_checked(p) typeflag(_TLst(p)) &= (~T_CHECKED) #define set_checked_slot(p) typeflag(_TSlt(p)) |= T_CHECKED #define is_checked_slot(p) ((typeflag(_TSlt(p)) & T_CHECKED) != 0) #define is_not_checked_slot(p) ((typeflag(_TSlt(p)) & T_CHECKED) == 0) #define T_UNSAFE (1 << (TYPE_BITS + 15)) #define set_unsafe(p) typeflag(_TLst(p)) |= T_UNSAFE #define set_unsafely_optimized(p) typeflag(_TLst(p)) |= (T_UNSAFE | T_OPTIMIZED) #define is_unsafe(p) ((typeflag(_TLst(p)) & T_UNSAFE) != 0) #define clear_unsafe(p) typeflag(_TLst(p)) &= (~T_UNSAFE) #define is_safely_optimized(p) ((typeflag(p) & (T_OPTIMIZED | T_UNSAFE)) == T_OPTIMIZED) /* optimizer flag saying "this expression is not completely self-contained. It might involve the stack, etc" */ #define T_CLEAN_SYMBOL T_UNSAFE #define is_clean_symbol(p) ((typeflag(_TSym(p)) & T_CLEAN_SYMBOL) != 0) #define set_clean_symbol(p) typeflag(_TSym(p)) |= T_CLEAN_SYMBOL /* set if we know the symbol name can be printed without quotes (slashification) */ #define T_IMMUTABLE (1 << (TYPE_BITS + 16)) #define is_immutable(p) ((typeflag(_NFre(p)) & T_IMMUTABLE) != 0) #define is_immutable_port(p) ((typeflag(_TPrt(p)) & T_IMMUTABLE) != 0) #define is_immutable_symbol(p) ((typeflag(_TSym(p)) & T_IMMUTABLE) != 0) #define is_immutable_integer(p) ((typeflag(_TI(p)) & T_IMMUTABLE) != 0) #define is_immutable_real(p) ((typeflag(_TR(p)) & T_IMMUTABLE) != 0) #define set_immutable(p) typeflag(_TSym(p)) |= T_IMMUTABLE /* immutable means the value can't be changed via set! or bind -- this is separate from the symbol access stuff * this bit can't be in the second byte -- with-let, for example, is immutable, but we use SYNTACTIC_TYPE to * recognize syntax in do loop optimizations. */ #define T_SETTER (1 << (TYPE_BITS + 17)) #define set_setter(p) typeflag(_TSym(p)) |= T_SETTER #define is_setter(p) ((typeflag(_TSym(p)) & T_SETTER) != 0) /* optimizer flag for a procedure that sets some variable (set-car! for example). */ #define T_ALLOW_OTHER_KEYS T_SETTER #define set_allow_other_keys(p) typeflag(_TLst(p)) |= T_ALLOW_OTHER_KEYS #define allows_other_keys(p) ((typeflag(_TLst(p)) & T_ALLOW_OTHER_KEYS) != 0) /* marks arglist that allows keyword args other than those in the parameter list; can't allow * (define* (f :allow-other-keys)...) because there's only one nil, and besides, it does say "other". */ #define T_MUTABLE (1 << (TYPE_BITS + 18)) #define is_mutable(p) ((typeflag(_TNum(p)) & T_MUTABLE) != 0) /* #define set_mutable(p) typeflag(_TNum(p)) |= T_MUTABLE */ /* used for mutable numbers */ #define T_MARK_SEQ T_MUTABLE #define is_mark_seq(p) ((typeflag(_TItr(p)) & T_MARK_SEQ) != 0) #define set_mark_seq(p) typeflag(_TItr(p)) |= T_MARK_SEQ /* used in iterators for GC mark of sequence */ #define T_BYTE_VECTOR T_MUTABLE #define is_byte_vector(p) ((typeflag(_TStr(p)) & T_BYTE_VECTOR) != 0) #define set_byte_vector(p) typeflag(_TStr(p)) |= T_BYTE_VECTOR /* marks a string that the caller considers a byte_vector */ #define T_STEPPER T_MUTABLE #define is_stepper(p) ((typeflag(_TSlt(p)) & T_STEPPER) != 0) #define set_stepper(p) typeflag(_TSlt(p)) |= T_STEPPER bool s7_is_stepper(s7_pointer p) {return(is_stepper(p));} /* marks a slot that holds a do-loop's step variable (if int, can be numerator=current, denominator=end) */ #define T_SAFE_STEPPER (1 << (TYPE_BITS + 19)) #define is_safe_stepper(p) ((typeflag(_TSlp(p)) & T_SAFE_STEPPER) != 0) #define set_safe_stepper(p) typeflag(_TSlp(p)) |= T_SAFE_STEPPER #define is_unsafe_stepper(p) ((typeflag(_TSlp(p)) & (T_STEPPER | T_SAFE_STEPPER)) == T_STEPPER) /* an experiment */ #define T_PRINT_NAME T_SAFE_STEPPER #define has_print_name(p) ((typeflag(_TNum(p)) & T_PRINT_NAME) != 0) #define set_has_print_name(p) typeflag(_TNum(p)) |= T_PRINT_NAME /* marks numbers that have a saved version of their string representation */ #define T_POSSIBLY_SAFE T_SAFE_STEPPER #define is_possibly_safe(p) ((typeflag(_TFnc(p)) & T_POSSIBLY_SAFE) != 0) #define set_is_possibly_safe(p) typeflag(_TFnc(p)) |= T_POSSIBLY_SAFE /* marks c_functions that are not always unsafe -- this bit didn't work out as intended */ #define T_HAS_SET_FALLBACK T_SAFE_STEPPER #define T_HAS_REF_FALLBACK T_MUTABLE #define has_ref_fallback(p) ((typeflag(_TLid(p)) & T_HAS_REF_FALLBACK) != 0) #define has_set_fallback(p) ((typeflag(_TLid(p)) & T_HAS_SET_FALLBACK) != 0) #define set_has_ref_fallback(p) typeflag(_TLet(p)) |= T_HAS_REF_FALLBACK #define set_has_set_fallback(p) typeflag(_TLet(p)) |= T_HAS_SET_FALLBACK #define set_all_methods(p, e) typeflag(_TLet(p)) |= (typeflag(e) & (T_HAS_METHODS | T_HAS_REF_FALLBACK | T_HAS_SET_FALLBACK)) #define T_COPY_ARGS (1 << (TYPE_BITS + 20)) #define needs_copied_args(p) ((typeflag(_NFre(p)) & T_COPY_ARGS) != 0) /* this marks something that might mess with its argument list, it should not be in the second byte */ #define T_GENSYM (1 << (TYPE_BITS + 21)) #define is_gensym(p) ((typeflag(_TSym(p)) & T_GENSYM) != 0) /* symbol is from gensym (GC-able etc) */ #define T_SIMPLE_ARGS T_GENSYM #define has_simple_args(p) ((typeflag(_TLst(p)) & T_SIMPLE_ARGS) != 0) #define set_simple_args(p) typeflag(_TLst(p)) |= T_SIMPLE_ARGS /* are all lambda* default values simple? */ #define T_LIST_IN_USE T_GENSYM #define list_is_in_use(p) ((typeflag(_TLst(p)) & T_LIST_IN_USE) != 0) #define set_list_in_use(p) typeflag(_TLst(p)) |= T_LIST_IN_USE #define clear_list_in_use(p) typeflag(_TLst(p)) &= (~T_LIST_IN_USE) /* these could all be one permanent list, indexed from inside, and this bit is never actually protecting anything across a call */ #define T_FUNCTION_ENV T_GENSYM #define is_function_env(p) ((typeflag(_TLet(p)) & T_FUNCTION_ENV) != 0) #define set_function_env(p) typeflag(_TLet(p)) |= T_FUNCTION_ENV /* this marks a funclet */ #define T_DOCUMENTED T_GENSYM #define is_documented(p) ((typeflag(_TStr(p)) & T_DOCUMENTED) != 0) #define set_documented(p) typeflag(_TStr(p)) |= T_DOCUMENTED /* this marks a symbol that has documentation (bit is set on name cell) */ #define T_HAS_METHODS (1 << (TYPE_BITS + 22)) #define has_methods(p) ((typeflag(_NFre(p)) & T_HAS_METHODS) != 0) #define set_has_methods(p) typeflag(_TMet(p)) |= T_HAS_METHODS #define clear_has_methods(p) typeflag(_TMet(p)) &= (~T_HAS_METHODS) /* this marks an environment or closure that is "opened" up to generic functions etc * don't reuse this bit if possible */ #define T_GC_MARK 0x80000000 /* (1 << (TYPE_BITS + 23)) but that makes gcc unhappy */ #define is_marked(p) ((typeflag(p) & T_GC_MARK) != 0) #define set_mark(p) typeflag(_NFre(p)) |= T_GC_MARK #define clear_mark(p) typeflag(p) &= (~T_GC_MARK) /* using bit 23 for this makes a big difference in the GC */ static int not_heap = -1; #define heap_location(p) (p)->hloc #define not_in_heap(p) ((_NFre(p))->hloc < 0) #define unheap(p) (p)->hloc = not_heap-- #define is_eof(p) (_NFre(p) == sc->EOF_OBJECT) #define is_true(Sc, p) ((_NFre(p)) != Sc->F) #define is_false(Sc, p) ((_NFre(p)) == Sc->F) #ifdef _MSC_VER #define MS_WINDOWS 1 static s7_pointer make_boolean(s7_scheme *sc, bool val) {if (val) return(sc->T); return(sc->F);} #else #define MS_WINDOWS 0 #define make_boolean(sc, Val) ((Val) ? sc->T : sc->F) #endif #define is_pair(p) (type(p) == T_PAIR) #define is_null(p) ((_NFre(p)) == sc->NIL) #define is_not_null(p) ((_NFre(p)) != sc->NIL) #if (!DEBUGGING) #define opt1(p, r) ((p)->object.cons.opt1) #define set_opt1(p, x, r) (p)->object.cons.opt1 = x #define opt2(p, r) ((p)->object.cons.opt2) #define set_opt2(p, x, r) (p)->object.cons.opt2 = (s7_pointer)(x) #define opt3(p, r) ((p)->object.cons.opt3) #define set_opt3(p, x, r) do {(p)->object.cons.opt3 = x; typeflag(p) &= ~(T_OPTIMIZED | T_LINE_NUMBER);} while (0) #define pair_line(p) (p)->object.sym_cons.line #define pair_set_line(p, X) (p)->object.sym_cons.line = X #define pair_raw_hash(p) (p)->object.sym_cons.hash #define pair_set_raw_hash(p, X) (p)->object.sym_cons.hash = X #define pair_raw_len(p) (p)->object.sym_cons.op #define pair_set_raw_len(p, X) (p)->object.sym_cons.op = X #define pair_raw_name(p) (p)->object.sym_cons.fstr #define pair_set_raw_name(p, X) (p)->object.sym_cons.fstr = X /* opt1 == raw_hash, opt2 == raw_name, opt3 == line+op|len, but hash/name/len only apply to the symbol table so there's no collision */ #else /* these 3 fields (or 8 counting sym_cons) hold most of the varigated optimizer info, so they are used in many conflicting ways. * the bits and funcs here try to track each such use, and report any cross-talk or collisions. * all of this machinery vanishes if debugging is turned off. */ #define S_NAME (1 << 26) #define S_HASH (1 << 27) #define S_OP (1 << 28) #define S_LINE (1 << 29) #define S_LEN (1 << 30) #define S_SYNOP 0x80000000 /* (1 << 31) */ #define E_SET (1 << 0) #define E_FAST (1 << 6) /* fast list in member/assoc circular list check */ #define E_CFUNC (1 << 7) /* c-function */ #define E_CLAUSE (1 << 8) /* case clause */ #define E_BACK (1 << 9) /* back pointer for doubly-linked list */ #define E_LAMBDA (1 << 10) /* lambda(*) */ #define E_SYM (1 << 11) /* symbol */ #define E_PAIR (1 << 12) /* pair */ #define E_CON (1 << 13) /* constant from eval's point of view */ #define E_GOTO (1 << 14) /* call-with-exit exit func */ #define E_VECTOR (1 << 15) /* vector (any kind) */ #define E_ANY (1 << 16) /* anything -- deliberate unchecked case */ #define E_SLOT (1 << 17) /* slot */ #define E_MASK (E_FAST | E_CFUNC | E_CLAUSE | E_BACK | E_LAMBDA | E_SYM | E_PAIR | E_CON | E_GOTO | E_VECTOR | E_ANY | E_SLOT | S_HASH) #define opt1_is_set(p) (((p)->debugger_bits & E_SET) != 0) #define set_opt1_is_set(p) (p)->debugger_bits |= E_SET #define opt1_role_matches(p, Role) (((p)->debugger_bits & E_MASK) == Role) #define set_opt1_role(p, Role) (p)->debugger_bits = (Role | ((p)->debugger_bits & ~E_MASK)) #define opt1(p, Role) opt1_1(hidden_sc, _TLst(p), Role, __func__, __LINE__) #define set_opt1(p, x, Role) set_opt1_1(hidden_sc, _TLst(p), x, Role, __func__, __LINE__) #define F_SET (1 << 1) #define F_C_CALL (1 << 18) /* c_function invocation */ #define F_KEY (1 << 19) /* case key */ #define F_SLOW (1 << 20) /* slow list in member/assoc circular list check */ #define F_SYM (1 << 21) /* symbol */ #define F_PAIR (1 << 22) /* pair */ #define F_CON (1 << 23) /* constant as above */ #define F_CALL (1 << 24) /* c-func */ #define F_LAMBDA (1 << 25) /* lambda form */ #define F_MASK (F_C_CALL | F_KEY | F_SLOW | F_SYM | F_PAIR | F_CON | F_CALL | F_LAMBDA | S_NAME) #define opt2_is_set(p) (((p)->debugger_bits & F_SET) != 0) #define set_opt2_is_set(p) (p)->debugger_bits |= F_SET #define opt2_role_matches(p, Role) (((p)->debugger_bits & F_MASK) == Role) #define set_opt2_role(p, Role) (p)->debugger_bits = (Role | ((p)->debugger_bits & ~F_MASK)) #define opt2(p, Role) opt2_1(hidden_sc, _TLst(p), Role, __func__, __LINE__) #define set_opt2(p, x, Role) set_opt2_1(hidden_sc, _TLst(p), (s7_pointer)x, Role, __func__, __LINE__) /* opt3 collides with optimization and line number stuff (T_LINE_NUMBER, T_OPTIMIZED) */ #define G_SET (1 << 2) #define G_ARGLEN (1 << 3) /* arglist length */ #define G_SYM (1 << 4) /* expression symbol access */ #define G_AND (1 << 5) /* and second clause */ #define G_MASK (G_ARGLEN | G_SYM | G_AND | S_OP | S_LINE | S_LEN | S_SYNOP) #define opt3_is_set(p) (((p)->debugger_bits & G_SET) != 0) #define set_opt3_is_set(p) (p)->debugger_bits |= G_SET #define opt3_role_matches(p, Role) (((p)->debugger_bits & G_MASK) == Role) #define set_opt3_role(p, Role) (p)->debugger_bits = (Role | ((p)->debugger_bits & ~G_MASK)) #define opt3(p, Role) opt3_1(hidden_sc, _TLst(p), Role, __func__, __LINE__) #define set_opt3(p, x, Role) set_opt3_1(hidden_sc, _TLst(p), x, Role, __func__, __LINE__) /* opt1 == s_hash, opt2 == s_fstr, opt3 == s_op|len|line and op==len so they are contradictory (but only op/line|opt3 actually collide) * line|len|op: unsigned int set G_SET and S_* if S_LEN -> not op and vice versa * another collider: pair_syntax_op|optimize_op below. Both need bits: S_SYNOP? */ #define pair_line(p) s_line_1(sc, _TLst(p), __func__, __LINE__) #define pair_set_line(p, X) set_s_line_1(sc, _TLst(p), X, __func__, __LINE__) #define pair_raw_hash(p) s_hash_1(sc, _TLst(p), __func__, __LINE__) #define pair_set_raw_hash(p, X) set_s_hash_1(sc, _TLst(p), X, __func__, __LINE__) #define pair_raw_len(p) s_len_1(sc, _TLst(p), __func__, __LINE__) #define pair_set_raw_len(p, X) set_s_len_1(sc, _TLst(p), X, __func__, __LINE__) #define pair_raw_name(p) s_name_1(sc, _TLst(p), __func__, __LINE__) #define pair_set_raw_name(p, X) set_s_name_1(sc, _TLst(p), X, __func__, __LINE__) #endif #define opt_fast(P) _TCdr(opt1(P, E_FAST)) #define set_opt_fast(P, X) set_opt1(P, _TLst(X), E_FAST) #define opt_back(P) _TLst(opt1(P, E_BACK)) #define set_opt_back(P) set_opt1(cdr(P), _TLst(P), E_BACK) #define has_opt_back(P) (cdr(opt_back(P)) == P ) #define opt_cfunc(P) opt1(P, E_CFUNC) #define set_opt_cfunc(P, X) set_opt1(P, X, E_CFUNC) #define opt_lambda(P) _TClo(opt1(P, E_LAMBDA)) #define set_opt_lambda(P, X) set_opt1(P, X, E_LAMBDA) #define opt_goto(P) _TGot(opt1(P, E_GOTO)) #define set_opt_goto(P, X) set_opt1(P, _TGot(X), E_GOTO) #define opt_vector(P) _TVec(opt1(P, E_VECTOR)) #define set_opt_vector(P, X) set_opt1(P, _TVec(X), E_VECTOR) #define opt_clause(P) opt1(P, E_CLAUSE) #define set_opt_clause(P, X) set_opt1(P, X, E_CLAUSE) #define opt_sym1(P) _TSym(opt1(P, E_SYM)) #define set_opt_sym1(P, X) set_opt1(P, _TSym(X), E_SYM) #define opt_pair1(P) _TCdr(opt1(P, E_PAIR)) #define set_opt_pair1(P, X) set_opt1(P, _TCdr(X), E_PAIR) #define opt_con1(P) opt1(P, E_CON) #define set_opt_con1(P, X) set_opt1(P, X, E_CON) #define opt_any1(P) opt1(P, E_ANY) #define opt_slot1(P) _TSlt(opt1(P, E_SLOT)) #define set_opt_slot1(P, X) set_opt1(P, _TSlt(X), E_SLOT) #define c_callee(f) ((s7_function)opt2(f, F_CALL)) #define c_call(f) ((s7_function)opt2(f, F_CALL)) #define set_c_call(f, X) set_opt2(f, (s7_pointer)X, F_CALL) #define opt_key(P) opt2(P, F_KEY) #define set_opt_key(P, X) set_opt2(P, X, F_KEY) #define opt_slow(P) _TCdr(opt2(P, F_SLOW)) #define set_opt_slow(P, X) set_opt2(P, _TLst(X), F_SLOW) #define opt_sym2(P) _TSym(opt2(P, F_SYM)) #define set_opt_sym2(P, X) set_opt2(P, _TSym(X), F_SYM) #define opt_pair2(P) _TCdr(opt2(P, F_PAIR)) #define set_opt_pair2(P, X) set_opt2(P, _TCdr(X), F_PAIR) #define opt_con2(P) opt2(P, F_CON) #define set_opt_con2(P, X) set_opt2(P, X, F_CON) #define opt_lambda2(P) _TLst(opt2(P, F_LAMBDA)) #define set_opt_lambda2(P, X) set_opt2(P, _TLst(X), F_LAMBDA) #define arglist_length(P) _TI(opt3(cdr(P), G_ARGLEN)) #define set_arglist_length(P, X) set_opt3(cdr(P), _TI(X), G_ARGLEN) #define opt_sym3(P) _TSym(opt3(P, G_SYM)) #define set_opt_sym3(P, X) set_opt3(P, _TSym(X), G_SYM) #define opt_and_2_test(P) _TLst(opt3(P, G_AND)) #define set_opt_and_2_test(P, X) set_opt3(P, _TLst(X), G_AND) #define car(p) (_TCdr(p))->object.cons.car #define cdr(p) (_TCdr(p))->object.cons.cdr #define unchecked_car(p) (_NFre(p))->object.cons.car #define unchecked_cdr(p) (_NFre(p))->object.cons.cdr #define caar(p) car(car(p)) #define cadr(p) car(cdr(p)) #define cdar(p) cdr(car(p)) #define cddr(p) cdr(cdr(p)) #define caaar(p) car(car(car(p))) #define cadar(p) car(cdr(car(p))) #define cdadr(p) cdr(car(cdr(p))) #define caddr(p) car(cdr(cdr(p))) #define caadr(p) car(car(cdr(p))) #define cdaar(p) cdr(car(car(p))) #define cdddr(p) cdr(cdr(cdr(p))) #define cddar(p) cdr(cdr(car(p))) #define caaadr(p) car(car(car(cdr(p)))) #define caadar(p) car(car(cdr(car(p)))) #define cadaar(p) car(cdr(car(car(p)))) #define cadddr(p) car(cdr(cdr(cdr(p)))) #define caaddr(p) car(car(cdr(cdr(p)))) #define cddddr(p) cdr(cdr(cdr(cdr(p)))) #define caddar(p) car(cdr(cdr(car(p)))) #define cdadar(p) cdr(car(cdr(car(p)))) #define cdaddr(p) cdr(car(cdr(cdr(p)))) #define caaaar(p) car(car(car(car(p)))) #define cadadr(p) car(cdr(car(cdr(p)))) #define cdaadr(p) cdr(car(car(cdr(p)))) #define cdaaar(p) cdr(car(car(car(p)))) #define cdddar(p) cdr(cdr(cdr(car(p)))) #define cddadr(p) cdr(cdr(car(cdr(p)))) #define cddaar(p) cdr(cdr(car(car(p)))) #if WITH_GCC /* slightly tricky because cons can be called recursively */ #define cons(Sc, A, B) ({s7_pointer _X_, _A_, _B_; _A_ = A; _B_ = B; new_cell(sc, _X_, T_PAIR | T_SAFE_PROCEDURE); car(_X_) = _A_; cdr(_X_) = _B_; _X_;}) #else #define cons(Sc, A, B) s7_cons(Sc, A, B) #endif #define list_1(Sc, A) cons(Sc, A, sc->NIL) #define list_2(Sc, A, B) cons_unchecked(Sc, A, cons(Sc, B, sc->NIL)) #define list_3(Sc, A, B, C) cons_unchecked(Sc, A, cons_unchecked(Sc, B, cons(Sc, C, sc->NIL))) #define list_4(Sc, A, B, C, D) cons_unchecked(Sc, A, cons_unchecked(Sc, B, cons_unchecked(Sc, C, cons(Sc, D, sc->NIL)))) #define is_string(p) (type(p) == T_STRING) #define string_value(p) (_TStr(p))->object.string.svalue #define string_length(p) (_TStr(p))->object.string.length #define string_hash(p) (_TStr(p))->object.string.hash #define string_needs_free(p) (_TStr(p))->object.string.str_ext.needs_free #define string_temp_true_length(p) (_TStr(p))->object.string.str_ext.accessor #define tmpbuf_malloc(P, Len) do {if ((Len) < TMPBUF_SIZE) P = sc->tmpbuf; else P = (char *)malloc((Len) * sizeof(char));} while (0) #define tmpbuf_calloc(P, Len) do {if ((Len) < TMPBUF_SIZE) {P = sc->tmpbuf; memset((void *)P, 0, Len);} else P = (char *)calloc(Len, sizeof(char));} while (0) #define tmpbuf_free(P, Len) do {if ((Len) >= TMPBUF_SIZE) free(P);} while (0) #define character(p) (_TChr(p))->object.chr.c #define upper_character(p) (_TChr(p))->object.chr.up_c #define is_char_alphabetic(p) (_TChr(p))->object.chr.alpha_c #define is_char_numeric(p) (_TChr(p))->object.chr.digit_c #define is_char_whitespace(p) (_TChr(p))->object.chr.space_c #define is_char_uppercase(p) (_TChr(p))->object.chr.upper_c #define is_char_lowercase(p) (_TChr(p))->object.chr.lower_c #define character_name(p) (_TChr(p))->object.chr.c_name #define character_name_length(p) (_TChr(p))->object.chr.length #if (!DEBUGGING) #define optimize_op(p) (_TLst(p))->object.sym_cons.op #define set_optimize_op(P, Op) optimize_op(P) = Op #else #define optimize_op(p) s_op_1(hidden_sc, _TLst(p), __func__, __LINE__) #define set_optimize_op(p, Op) set_s_op_1(hidden_sc, _TLst(p), Op, __func__, __LINE__) #endif #define optimize_op_match(P, Q) ((is_optimized(P)) && ((optimize_op(P) & 0xfffe) == Q)) #define op_no_hop(P) (optimize_op(P) & 0xfffe) #define clear_hop(P) set_optimize_op(P, op_no_hop(P)) #define clear_optimize_op(P) set_optimize_op(P, 0) #define set_safe_optimize_op(P, Q) do {set_optimized(P); set_optimize_op(P, Q);} while (0) #define set_unsafe_optimize_op(P, Q) do {set_unsafely_optimized(P); set_optimize_op(P, Q);} while (0) #define is_symbol(p) (type(p) == T_SYMBOL) #define symbol_name_cell(p) _TStr((_TSym(p))->object.sym.name) #define set_symbol_name_cell(p, S) (_TSym(p))->object.sym.name = _TStr(S) #define symbol_name(p) string_value(symbol_name_cell(p)) #define symbol_name_length(p) string_length(symbol_name_cell(p)) #define symbol_hmap(p) s7_int_abs(heap_location(p)) #define symbol_global_accessor_index(p) (symbol_name_cell(p))->object.string.str_ext.accessor #define symbol_id(p) (_TSym(p))->object.sym.id #define symbol_set_id(p, X) (_TSym(p))->object.sym.id = X /* we need 64-bits here, since we don't want this thing to wrap around, and frames are created at a great rate * callgrind says this is faster than an unsigned int! */ #define symbol_syntax_op(p) (_TSym(p))->object.sym.op #define global_slot(p) (_TSym(p))->object.sym.global_slot #define initial_slot(p) (symbol_name_cell(p))->object.string.initial_slot #define local_slot(p) (_TSym(p))->object.sym.local_slot #define keyword_symbol(p) (symbol_name_cell(p))->object.string.doc.ksym #define symbol_help(p) (symbol_name_cell(p))->object.string.doc.documentation #define symbol_tag(p) (_TSym(p))->object.sym.tag #define symbol_has_help(p) (is_documented(symbol_name_cell(p))) #define symbol_set_has_help(p) set_documented(symbol_name_cell(p)) #define symbol_set_local(Symbol, Id, Slot) do {local_slot(Symbol) = Slot; symbol_set_id(Symbol, Id);} while (0) /* set slot before id in case Slot is an expression that tries to find the current Symbol slot (using its old Id obviously) */ #define is_slot(p) (type(p) == T_SLOT) #define slot_value(p) _NFre((_TSlt(p))->object.slt.val) #define slot_set_value(p, Val) (_TSlt(p))->object.slt.val = _NFre(Val) #define slot_symbol(p) _TSym((_TSlt(p))->object.slt.sym) #define slot_set_symbol(p, Sym) (_TSlt(p))->object.slt.sym = _TSym(Sym) #define next_slot(p) (_TSlt(p))->object.slt.nxt #define slot_pending_value(p) (_TSlt(p))->object.slt.pending_value #define slot_expression(p) (_TSlt(p))->object.slt.expr #define slot_accessor(p) slot_expression(p) #define is_syntax(p) (type(p) == T_SYNTAX) #define syntax_symbol(p) (_TSyn(p))->object.syn.symbol #define syntax_opcode(p) (_TSyn(p))->object.syn.op #define syntax_min_args(p) (_TSyn(p))->object.syn.min_args #define syntax_max_args(p) (_TSyn(p))->object.syn.max_args #define syntax_documentation(p) sc->syn_docs[syntax_opcode(p)] #define syntax_rp(p) (_TSyn(p))->object.syn.rp #define syntax_ip(p) (_TSyn(p))->object.syn.ip #define syntax_pp(p) (_TSyn(p))->object.syn.pp #if (!DEBUGGING) #define pair_syntax_op(p) (p)->object.sym_cons.op #define pair_set_syntax_op(p, X) (p)->object.sym_cons.op = X #else #define pair_syntax_op(p) s_syn_op_1(hidden_sc, _TLst(p), __func__, __LINE__) #define pair_set_syntax_op(p, Op) set_s_syn_op_1(hidden_sc, _TLst(p), Op, __func__, __LINE__) #endif #define pair_syntax_symbol(P) car(opt_back(P)) static void pair_set_syntax_symbol(s7_pointer p, s7_pointer op) {pair_syntax_symbol(p) = op; pair_set_syntax_op(opt_back(p), symbol_syntax_op(op));} #define ROOTLET_SIZE 512 #define let_id(p) (_TLid(p))->object.envr.id #define is_let(p) (type(p) == T_LET) #define let_slots(p) (_TLet(p))->object.envr.slots #define let_set_slots(p, Slot) (_TLet(p))->object.envr.slots = Slot #define outlet(p) (_TLet(p))->object.envr.nxt #define set_outlet(p, ol) (_TLet(p))->object.envr.nxt = _TLid(ol) #define funclet_function(p) _TSym((_TLet(p))->object.envr.edat.efnc.function) #define funclet_set_function(p, F) (_TLet(p))->object.envr.edat.efnc.function = _TSym(F) #define let_line(p) (_TLet(p))->object.envr.edat.efnc.line #define let_set_line(p, L) (_TLet(p))->object.envr.edat.efnc.line = L #define let_file(p) (_TLet(p))->object.envr.edat.efnc.file #define let_set_file(p, F) (_TLet(p))->object.envr.edat.efnc.file = F #define dox_slot1(p) _TSlt((_TLet(p))->object.envr.edat.dox.dox1) #define dox_set_slot1(p, S) (_TLet(p))->object.envr.edat.dox.dox1 = _TSlt(S) #define dox_slot2(p) _TSlt((_TLet(p))->object.envr.edat.dox.dox2) #define dox_set_slot2(p, S) (_TLet(p))->object.envr.edat.dox.dox2 = _TSlt(S) #define unique_name(p) (p)->object.unq.name #define unique_name_length(p) (p)->object.unq.len #define is_unspecified(p) (type(p) == T_UNSPECIFIED) #define unique_cdr(p) (p)->object.unq.unused_nxt #define vector_length(p) ((p)->object.vector.length) #define vector_element(p, i) ((p)->object.vector.elements.objects[i]) #define vector_elements(p) (p)->object.vector.elements.objects #define vector_getter(p) (_TVec(p))->object.vector.vget #define vector_setter(p) (_TVec(p))->object.vector.vset #define int_vector_element(p, i) ((_TIvc(p))->object.vector.elements.ints[i]) #define int_vector_elements(p) (_TIvc(p))->object.vector.elements.ints #define float_vector_element(p, i) ((_TFvc(p))->object.vector.elements.floats[i]) #define float_vector_elements(p) (_TFvc(p))->object.vector.elements.floats #define is_normal_vector(p) (type(p) == T_VECTOR) #define is_int_vector(p) (type(p) == T_INT_VECTOR) #define is_float_vector(p) (type(p) == T_FLOAT_VECTOR) #define vector_ndims(p) ((_TVec(p))->object.vector.dim_info->ndims) #define vector_dimension(p, i) ((_TVec(p))->object.vector.dim_info->dims[i]) #define vector_dimensions(p) ((_TVec(p))->object.vector.dim_info->dims) #define vector_offset(p, i) ((_TVec(p))->object.vector.dim_info->offsets[i]) #define vector_offsets(p) ((_TVec(p))->object.vector.dim_info->offsets) #define vector_dimension_info(p) ((_TVec(p))->object.vector.dim_info) #define shared_vector(p) ((_TVec(p))->object.vector.dim_info->original) #define vector_rank(p) ((vector_dimension_info(p)) ? vector_ndims(p) : 1) #define vector_has_dimensional_info(p) (vector_dimension_info(p)) #define vector_elements_allocated(p) ((_TVec(p))->object.vector.dim_info->elements_allocated) #define vector_dimensions_allocated(p) ((_TVec(p))->object.vector.dim_info->dimensions_allocated) #define is_hash_table(p) (type(p) == T_HASH_TABLE) #define hash_table_mask(p) (_THsh(p))->object.hasher.mask #define hash_table_element(p, i) ((_THsh(p))->object.hasher.elements[i]) #define hash_table_elements(p) (_THsh(p))->object.hasher.elements #define hash_table_entries(p) (_THsh(p))->object.hasher.entries #define hash_table_checker(p) (_THsh(p))->object.hasher.hash_func #define hash_table_mapper(p) (_THsh(p))->object.hasher.loc #define hash_table_checker_locked(p) (hash_table_mapper(p) != default_hash_map) #define hash_table_procedures(p) (_THsh(p))->object.hasher.dproc #define hash_table_procedures_checker(p) car(hash_table_procedures(p)) #define hash_table_procedures_mapper(p) cdr(hash_table_procedures(p)) #define is_iterator(p) (type(p) == T_ITERATOR) #define iterator_sequence(p) (_TItr(p))->object.iter.obj #define iterator_position(p) (_TItr(p))->object.iter.lc.loc #define iterator_length(p) (_TItr(p))->object.iter.lw.len #define iterator_slow(p) (_TItr(p))->object.iter.lw.slow #define iterator_hash_current(p) (_TItr(p))->object.iter.lw.hcur #define iterator_current(p) (_TItr(p))->object.iter.cur #define iterator_let_current(p) (_TItr(p))->object.iter.lc.lcur #define iterator_let_cons(p) (_TItr(p))->object.iter.cur #define iterator_next(p) (_TItr(p))->object.iter.next #define iterator_is_at_end(p) (iterator_next(p) == iterator_finished) #define ITERATOR_END EOF_OBJECT #define ITERATOR_END_NAME "#" #define is_input_port(p) (type(p) == T_INPUT_PORT) #define is_output_port(p) (type(p) == T_OUTPUT_PORT) #define port_port(p) (_TPrt(p))->object.prt.port #define port_type(p) (_TPrt(p))->object.prt.ptype #define is_string_port(p) (port_type(p) == STRING_PORT) #define is_file_port(p) (port_type(p) == FILE_PORT) #define is_function_port(p) (port_type(p) == FUNCTION_PORT) #define port_line_number(p) (_TPrt(p))->object.prt.line_number #define port_file_number(p) (_TPrt(p))->object.prt.file_number #define port_filename(p) port_port(p)->filename #define port_filename_length(p) port_port(p)->filename_length #define port_file(p) port_port(p)->file #define port_is_closed(p) (_TPrt(p))->object.prt.is_closed #define port_data(p) (_TPrt(p))->object.prt.data #define port_data_size(p) (_TPrt(p))->object.prt.size #define port_position(p) (_TPrt(p))->object.prt.point #define port_needs_free(p) port_port(p)->needs_free #define port_output_function(p) port_port(p)->output_function #define port_input_function(p) port_port(p)->input_function #define port_original_input_string(p) port_port(p)->orig_str #define port_read_character(p) port_port(p)->read_character #define port_read_line(p) port_port(p)->read_line #define port_display(p) port_port(p)->display #define port_write_character(p) port_port(p)->write_character #define port_write_string(p) port_port(p)->write_string #define port_read_semicolon(p) port_port(p)->read_semicolon #define port_read_white_space(p) port_port(p)->read_white_space #define port_read_name(p) port_port(p)->read_name #define port_read_sharp(p) port_port(p)->read_sharp #define port_gc_loc(p) port_port(p)->gc_loc #define is_c_function(f) (type(f) >= T_C_FUNCTION) #define is_c_function_star(f) (type(f) == T_C_FUNCTION_STAR) #define is_any_c_function(f) (type(f) >= T_C_FUNCTION_STAR) #define c_function_data(f) (_TFnc(f))->object.fnc.c_proc #define c_function_call(f) (_TFnc(f))->object.fnc.ff #define c_function_required_args(f) (_TFnc(f))->object.fnc.required_args #define c_function_optional_args(f) (_TFnc(f))->object.fnc.optional_args #define c_function_has_rest_arg(f) (_TFnc(f))->object.fnc.rest_arg #define c_function_all_args(f) (_TFnc(f))->object.fnc.all_args #define c_function_setter(f) (_TFnc(f))->object.fnc.setter #define c_function_name(f) c_function_data(f)->name #define c_function_name_length(f) c_function_data(f)->name_length #define c_function_documentation(f) c_function_data(f)->doc #define c_function_signature(f) c_function_data(f)->signature #define c_function_class(f) c_function_data(f)->id #define c_function_chooser(f) c_function_data(f)->chooser #define c_function_base(f) c_function_data(f)->generic_ff #define c_function_arg_defaults(f) c_function_data(f)->arg_defaults #define c_function_call_args(f) c_function_data(f)->call_args #define c_function_arg_names(f) c_function_data(f)->arg_names #define c_function_rp(f) c_function_data(f)->rp #define c_function_ip(f) c_function_data(f)->ip #define c_function_pp(f) c_function_data(f)->pp #define c_function_gp(f) c_function_data(f)->gp #define set_c_function(f, X) do {set_opt_cfunc(f, X); set_c_call(f, c_function_call(opt_cfunc(f)));} while (0) #define is_c_macro(p) (type(p) == T_C_MACRO) #define c_macro_data(f) (_TMac(f))->object.fnc.c_proc #define c_macro_call(f) (_TMac(f))->object.fnc.ff #define c_macro_name(f) c_macro_data(f)->name #define c_macro_name_length(f) c_macro_data(f)->name_length #define c_macro_required_args(f) (_TMac(f))->object.fnc.required_args #define c_macro_all_args(f) (_TMac(f))->object.fnc.all_args #define c_macro_setter(f) (_TMac(f))->object.fnc.setter #define is_random_state(p) (type(p) == T_RANDOM_STATE) #if WITH_GMP #define random_gmp_state(p) (_TRan(p))->object.rng.state #else #define random_seed(p) (_TRan(p))->object.rng.seed #define random_carry(p) (_TRan(p))->object.rng.carry #endif #define continuation_data(p) (_TCon(p))->object.cwcc.continuation #define continuation_stack(p) (_TCon(p))->object.cwcc.stack #define continuation_stack_end(p) (_TCon(p))->object.cwcc.stack_end #define continuation_stack_start(p) (_TCon(p))->object.cwcc.stack_start #define continuation_stack_size(p) (_TCon(p))->object.cwcc.continuation->stack_size #define continuation_stack_top(p) (continuation_stack_end(p) - continuation_stack_start(p)) #define continuation_op_stack(p) (_TCon(p))->object.cwcc.op_stack #define continuation_op_loc(p) (_TCon(p))->object.cwcc.continuation->op_stack_loc #define continuation_op_size(p) (_TCon(p))->object.cwcc.continuation->op_stack_size #define continuation_key(p) (_TCon(p))->object.cwcc.continuation->local_key #define call_exit_goto_loc(p) (_TGot(p))->object.rexit.goto_loc #define call_exit_op_loc(p) (_TGot(p))->object.rexit.op_stack_loc #define call_exit_active(p) (_TGot(p))->object.rexit.active #define temp_stack_top(p) (_TStk(p))->object.stk.top #define s7_stack_top(Sc) ((Sc)->stack_end - (Sc)->stack_start) #define is_continuation(p) (type(p) == T_CONTINUATION) #define is_goto(p) (type(p) == T_GOTO) #define is_macro(p) (type(p) == T_MACRO) /* #define is_bacro(p) (type(p) == T_BACRO) */ #define is_macro_star(p) (type(p) == T_MACRO_STAR) #define is_bacro_star(p) (type(p) == T_BACRO_STAR) #define is_closure(p) (type(p) == T_CLOSURE) #define is_closure_star(p) (type(p) == T_CLOSURE_STAR) #define closure_args(p) (_TClo(p))->object.func.args #define closure_body(p) (_TClo(p))->object.func.body #define closure_let(p) _TLid((_TClo(p))->object.func.env) #define closure_set_let(p, L) (_TClo(p))->object.func.env = _TLid(L) #define closure_setter(p) (_TClo(p))->object.func.setter #define closure_arity(p) (_TClo(p))->object.func.arity #define CLOSURE_ARITY_NOT_SET 0x40000000 #define MAX_ARITY 0x20000000 #define closure_arity_unknown(p) (closure_arity(p) == CLOSURE_ARITY_NOT_SET) #define is_thunk(Sc, Fnc) ((type(Fnc) >= T_GOTO) && (s7_is_aritable(Sc, Fnc, 0))) #define catch_tag(p) (_TCat(p))->object.rcatch.tag #define catch_goto_loc(p) (_TCat(p))->object.rcatch.goto_loc #define catch_op_loc(p) (_TCat(p))->object.rcatch.op_stack_loc #define catch_handler(p) (_TCat(p))->object.rcatch.handler #define catch_all_goto_loc(p) (_TLet(p))->object.envr.edat.ctall.goto_loc #define catch_all_set_goto_loc(p, L) (_TLet(p))->object.envr.edat.ctall.goto_loc = L #define catch_all_op_loc(p) (_TLet(p))->object.envr.edat.ctall.op_stack_loc #define catch_all_set_op_loc(p, L) (_TLet(p))->object.envr.edat.ctall.op_stack_loc = L #define catch_all_result(p) _NFre((_TLet(p))->object.envr.edat.ctall.result) #define catch_all_set_result(p, R) (_TLet(p))->object.envr.edat.ctall.result = R enum {DWIND_INIT, DWIND_BODY, DWIND_FINISH}; #define dynamic_wind_state(p) (_TDyn(p))->object.winder.state #define dynamic_wind_in(p) (_TDyn(p))->object.winder.in #define dynamic_wind_out(p) (_TDyn(p))->object.winder.out #define dynamic_wind_body(p) (_TDyn(p))->object.winder.body #define is_c_object(p) (type(p) == T_C_OBJECT) #define c_object_value(p) (_TObj(p))->object.c_obj.value #define c_object_type(p) (_TObj(p))->object.c_obj.type #define c_object_let(p) _TLid((_TObj(p))->object.c_obj.e) #define c_object_set_let(p, L) (_TObj(p))->object.c_obj.e = _TLid(L) #define c_object_cref(p) (_TObj(p))->object.c_obj.ref static c_object_t **object_types = NULL; static int object_types_size = 0; static int num_object_types = 0; #define c_object_info(p) object_types[c_object_type(p)] #define c_object_ref(p) c_object_info(p)->ref #define c_object_set(p) c_object_info(p)->set #define c_object_print(p) c_object_info(p)->print #define c_object_print_readably(p) c_object_info(p)->print_readably #define c_object_length(p) c_object_info(p)->length #define c_object_eql(p) c_object_info(p)->equal #define c_object_fill(p) c_object_info(p)->fill #define c_object_copy(p) c_object_info(p)->copy #define c_object_free(p) c_object_info(p)->free #define c_object_mark(p) c_object_info(p)->gc_mark #define c_object_reverse(p) c_object_info(p)->reverse #define c_object_direct_ref(p) c_object_info(p)->direct_ref #define c_object_direct_set(p) c_object_info(p)->direct_set #define c_object_ip(p) c_object_info(p)->ip #define c_object_rp(p) c_object_info(p)->rp #define c_object_set_ip(p) c_object_info(p)->set_ip #define c_object_set_rp(p) c_object_info(p)->set_rp /* #define c_object_outer_type(p) c_object_info(p)->outer_type */ #define raw_pointer(p) (_TPtr(p))->object.c_pointer #define is_counter(p) (type(p) == T_COUNTER) #define counter_result(p) (_TCtr(p))->object.ctr.result #define counter_list(p) (_TCtr(p))->object.ctr.list #define counter_capture(p) (_TCtr(p))->object.ctr.cap #define counter_let(p) _TLid((_TCtr(p))->object.ctr.env) #define counter_set_let(p, L) (_TCtr(p))->object.ctr.env = _TLid(L) #define is_baffle(p) (type(p) == T_BAFFLE) #define baffle_key(p) (_TBfl(p))->object.baffle_key #if __cplusplus && HAVE_COMPLEX_NUMBERS using namespace std; /* the code has to work in C as well as C++, so we can't scatter std:: all over the place */ typedef complex s7_complex; static s7_double Real(complex x) {return(real(x));} /* protect the C++ name */ static s7_double Imag(complex x) {return(imag(x));} #endif #define integer(p) (_TI(p))->object.number.integer_value #define real(p) (_TR(p))->object.number.real_value #define set_real(p, x) real(p) = x #define numerator(p) (_TF(p))->object.number.fraction_value.numerator #define denominator(p) (_TF(p))->object.number.fraction_value.denominator #define fraction(p) (((long double)numerator(p)) / ((long double)denominator(p))) #define inverted_fraction(p) (((long double)denominator(p)) / ((long double)numerator(p))) #define real_part(p) (_TZ(p))->object.number.complex_value.rl #define set_real_part(p, x) real_part(p) = x #define imag_part(p) (_TZ(p))->object.number.complex_value.im #define set_imag_part(p, x) imag_part(p) = x #if HAVE_COMPLEX_NUMBERS #define as_c_complex(p) CMPLX(real_part(p), imag_part(p)) #endif #if WITH_GMP #define big_integer(p) ((_TBgi(p))->object.number.big_integer) #define big_ratio(p) ((_TBgf(p))->object.number.big_ratio) #define big_real(p) ((_TBgr(p))->object.number.big_real) #define big_complex(p) ((_TBgz(p))->object.number.big_complex) #endif #define NUM_SMALL_INTS 2048 #define small_int(Val) small_ints[Val] #define is_small(n) ((n & ~(NUM_SMALL_INTS - 1)) == 0) #define print_name(p) (char *)((_TNum(p))->object.number.pval.name + 1) #define print_name_length(p) (_TNum(p))->object.number.pval.name[0] static void set_print_name(s7_pointer p, const char *name, int len) { if ((len < PRINT_NAME_SIZE) && (!is_mutable(p))) { set_has_print_name(p); print_name_length(p) = (unsigned char)(len & 0xff); memcpy((void *)print_name(p), (void *)name, len); } } #if WITH_GCC #define make_integer(Sc, N) \ ({ s7_int _N_; _N_ = (N); (is_small(_N_) ? small_int(_N_) : ({ s7_pointer _X_; new_cell(Sc, _X_, T_INTEGER); integer(_X_) = _N_; _X_;}) ); }) #define make_real(Sc, X) \ ({ s7_double _N_ = (X); ((_N_ == 0.0) ? real_zero : ({ s7_pointer _X_; new_cell(Sc, _X_, T_REAL); set_real(_X_, _N_); _X_;}) ); }) /* the x == 0.0 check saves more than it costs */ #define make_complex(Sc, R, I) \ ({ s7_double im; im = (I); ((im == 0.0) ? make_real(Sc, R) : ({ s7_pointer _X_; new_cell(Sc, _X_, T_COMPLEX); set_real_part(_X_, R); set_imag_part(_X_, im); _X_;}) ); }) #define real_to_double(Sc, X, Caller) ({ s7_pointer _x_; _x_ = (X); ((type(_x_) == T_REAL) ? real(_x_) : s7_number_to_real_with_caller(sc, _x_, Caller)); }) #define rational_to_double(Sc, X) ({ s7_pointer _x_; _x_ = (X); ((type(_x_) == T_INTEGER) ? (s7_double)integer(_x_) : fraction(_x_)); }) #else #define make_integer(Sc, N) s7_make_integer(Sc, N) #define make_real(Sc, X) s7_make_real(Sc, X) #define make_complex(Sc, R, I) s7_make_complex(Sc, R, I) #define real_to_double(Sc, X, Caller) s7_number_to_real_with_caller(Sc, X, Caller) #define rational_to_double(Sc, X) s7_number_to_real(Sc, X) #endif #define S7_LLONG_MAX 9223372036854775807LL #define S7_LLONG_MIN (-S7_LLONG_MAX - 1LL) #define S7_LONG_MAX 2147483647LL #define S7_LONG_MIN (-S7_LONG_MAX - 1LL) #define S7_SHORT_MAX 32767 #define S7_SHORT_MIN -32768 static s7_int s7_int_max = 0, s7_int_min = 0; /* 9007199254740991LL is where a truncated double starts to skip integers (expt 2 53) = ca 1e16 * :(ceiling (+ 1e16 1)) * 10000000000000000 * :(> 9007199254740993.0 9007199254740992.0) * #f ; in non-gmp 64-bit doubles * * but we can't fix this except in the gmp case because: * :(integer-decode-float (+ (expt 2.0 62) 100)) * (4503599627370496 10 1) * :(integer-decode-float (+ (expt 2.0 62) 500)) * (4503599627370496 10 1) * :(> (+ (expt 2.0 62) 500) (+ (expt 2.0 62) 100)) * #f ; non-gmp again * * i.e. the bits are identical. We can't even detect when it has happened, so should * we just give an error for any floor (or whatever) of an arg>1e16? (sin has a similar problem)? * I think in the non-gmp case I'll throw an error in these cases because the results are * bogus: * :(floor (+ (expt 2.0 62) 512)) * 4611686018427387904 * :(floor (+ (expt 2.0 62) 513)) * 4611686018427388928 * * another case at the edge: (round 9007199254740992.51) -> 9007199254740992 * * This spells trouble for normal arithmetic in this range. If no gmp, * (- (+ (expt 2.0 62) 512) (+ (expt 2.0 62) 513)) = -1024.0 (should be -1.0) * but we don't currently give an error in this case -- not sure what the right thing is. */ /* -------------------------------------------------------------------------------- * local versions of some standard C library functions * timing tests involving these are very hard to interpret -- pervasive inconsistency! */ static int safe_strlen(const char *str) { /* this is safer than strlen, and slightly faster */ char *tmp = (char *)str; if ((!tmp) || (!(*tmp))) return(0); while (*tmp++) {}; return(tmp - str - 1); } static int safe_strlen5(const char *str) { /* safe_strlen but we quit counting if len>5 */ char *tmp = (char *)str; char *end; if ((!tmp) || (!(*tmp))) return(0); end = (char *)(tmp + 6); while ((*tmp++) && (tmp < end)) {}; return(tmp - str - 1); } static char *copy_string_with_length(const char *str, int len) { char *newstr; newstr = (char *)malloc((len + 1) * sizeof(char)); if (len != 0) memcpy((void *)newstr, (void *)str, len + 1); else newstr[0] = 0; return(newstr); } static char *copy_string(const char *str) { return(copy_string_with_length(str, safe_strlen(str))); } static bool local_strcmp(const char *s1, const char *s2) { while (true) { if (*s1 != *s2++) return(false); if (*s1++ == 0) return(true); } return(true); } #define strings_are_equal(Str1, Str2) (local_strcmp(Str1, Str2)) /* this should only be used for internal strings -- scheme strings can have embedded nulls. */ static bool safe_strcmp(const char *s1, const char *s2) { if ((!s1) || (!s2)) return(s1 == s2); return(local_strcmp(s1, s2)); } static bool local_strncmp(const char *s1, const char *s2, unsigned int n) { #if defined(__x86_64__) || defined(__i386__) /* unaligned accesses are safe on i386 hardware, sez everyone */ if (n >= 4) { int *is1, *is2; int n4 = n >> 2; is1 = (int *)s1; is2 = (int *)s2; do {if (*is1++ != *is2++) return(false);} while (--n4 > 0); s1 = (const char *)is1; s2 = (const char *)is2; n &= 3; } #endif while (n > 0) { if (*s1++ != *s2++) return(false); n--; } return(true); } #define strings_are_equal_with_length(Str1, Str2, Len) (local_strncmp(Str1, Str2, Len)) static void memclr(void *s, size_t n) { unsigned char *s2; #if defined(__x86_64__) || defined(__i386__) if (n >= 4) { int *s1 = (int *)s; size_t n4 = n >> 2; do {*s1++ = 0;} while (--n4 > 0); n &= 3; s2 = (unsigned char *)s1; } else s2 = (unsigned char *)s; #else s2 = (unsigned char *)s; #endif while (n > 0) { *s2++ = 0; n--; } } /* ---------------- forward decls ---------------- */ static char *number_to_string_base_10(s7_pointer obj, int width, int precision, char float_choice, int *nlen, use_write_t choice); static bool is_proper_list(s7_scheme *sc, s7_pointer lst); static s7_pointer iterator_finished(s7_scheme *sc, s7_pointer iterator); static bool is_all_x_safe(s7_scheme *sc, s7_pointer p); static void annotate_args(s7_scheme *sc, s7_pointer args, s7_pointer e); static void annotate_arg(s7_scheme *sc, s7_pointer arg, s7_pointer e); static s7_pointer eval(s7_scheme *sc, opcode_t first_op); static s7_pointer division_by_zero_error(s7_scheme *sc, s7_pointer caller, s7_pointer arg); static s7_pointer file_error(s7_scheme *sc, const char *caller, const char *descr, const char *name); static s7_pointer prepackaged_type_name(s7_scheme *sc, s7_pointer x); static void s7_warn(s7_scheme *sc, int len, const char *ctrl, ...); static s7_pointer safe_reverse_in_place(s7_scheme *sc, s7_pointer list); static s7_pointer cons_unchecked(s7_scheme *sc, s7_pointer a, s7_pointer b); static s7_pointer permanent_cons(s7_pointer a, s7_pointer b, unsigned int type); static s7_pointer permanent_list(s7_scheme *sc, int len); static void free_object(s7_pointer a); static s7_pointer make_atom(s7_scheme *sc, char *q, int radix, bool want_symbol, bool with_error); static s7_pointer apply_error(s7_scheme *sc, s7_pointer obj, s7_pointer args); static int remember_file_name(s7_scheme *sc, const char *file); static const char *type_name(s7_scheme *sc, s7_pointer arg, int article); static s7_pointer make_vector_1(s7_scheme *sc, s7_int len, bool filled, unsigned int typ); static s7_pointer make_string_uncopied_with_length(s7_scheme *sc, char *str, int len); static s7_pointer make_string_wrapper_with_length(s7_scheme *sc, const char *str, int len); static s7_pointer make_string_wrapper(s7_scheme *sc, const char *str); static void check_for_substring_temp(s7_scheme *sc, s7_pointer expr); static s7_pointer splice_in_values(s7_scheme *sc, s7_pointer args); static void pop_input_port(s7_scheme *sc); static char *object_to_truncated_string(s7_scheme *sc, s7_pointer p, int len); static token_t token(s7_scheme *sc); static s7_pointer implicit_index(s7_scheme *sc, s7_pointer obj, s7_pointer indices); static bool s7_is_morally_equal(s7_scheme *sc, s7_pointer x, s7_pointer y); static void remove_gensym_from_symbol_table(s7_scheme *sc, s7_pointer sym); static s7_pointer find_symbol_unchecked(s7_scheme *sc, s7_pointer symbol); static s7_pointer unbound_variable(s7_scheme *sc, s7_pointer sym); static s7_pointer optimize_lambda(s7_scheme *sc, bool unstarred_lambda, s7_pointer func, s7_pointer args, s7_pointer body); static bool optimize_expression(s7_scheme *sc, s7_pointer expr, int hop, s7_pointer e); static s7_pointer optimize(s7_scheme *sc, s7_pointer code, int hop, s7_pointer e); static void free_hash_table(s7_pointer table); #if WITH_GMP static s7_int big_integer_to_s7_int(mpz_t n); #else static double next_random(s7_pointer r); #endif #if WITH_GCC #define find_symbol_checked(Sc, Sym) ({s7_pointer _x_; _x_ = find_symbol_unchecked(Sc, Sym); ((_x_) ? _x_ : unbound_variable(Sc, Sym));}) #else #define find_symbol_checked(Sc, Sym) find_symbol_unchecked(Sc, Sym) #endif static s7_pointer find_method(s7_scheme *sc, s7_pointer env, s7_pointer symbol); static s7_pointer find_let(s7_scheme *sc, s7_pointer obj); static bool call_begin_hook(s7_scheme *sc); static s7_pointer default_vector_setter(s7_scheme *sc, s7_pointer vec, s7_int loc, s7_pointer val); static s7_pointer default_vector_getter(s7_scheme *sc, s7_pointer vec, s7_int loc); static s7_pointer simple_wrong_type_arg_error_prepackaged(s7_scheme *sc, s7_pointer caller, s7_pointer arg, s7_pointer typnam, s7_pointer descr); static s7_pointer wrong_type_arg_error_prepackaged(s7_scheme *sc, s7_pointer caller, s7_pointer arg_n, s7_pointer arg, s7_pointer typnam, s7_pointer descr); static s7_pointer out_of_range_error_prepackaged(s7_scheme *sc, s7_pointer caller, s7_pointer arg_n, s7_pointer arg, s7_pointer descr); static s7_pointer simple_out_of_range_error_prepackaged(s7_scheme *sc, s7_pointer caller, s7_pointer arg, s7_pointer descr); /* putting off the type description until s7_error via the sc->GC_NIL marker below makes it possible * for gcc to speed up the functions that call these as tail-calls. 1-2% overall speedup! */ #define simple_wrong_type_argument(Sc, Caller, Arg, Desired_Type) \ simple_wrong_type_arg_error_prepackaged(Sc, symbol_name_cell(Caller), Arg, sc->GC_NIL, prepackaged_type_names[Desired_Type]) #define wrong_type_argument(Sc, Caller, Num, Arg, Desired_Type) \ wrong_type_arg_error_prepackaged(Sc, symbol_name_cell(Caller), make_integer(Sc, Num), Arg, sc->GC_NIL, prepackaged_type_names[Desired_Type]) #define simple_wrong_type_argument_with_type(Sc, Caller, Arg, Type) \ simple_wrong_type_arg_error_prepackaged(Sc, symbol_name_cell(Caller), Arg, sc->GC_NIL, Type) #define wrong_type_argument_with_type(Sc, Caller, Num, Arg, Type) \ wrong_type_arg_error_prepackaged(Sc, symbol_name_cell(Caller), make_integer(Sc, Num), Arg, sc->GC_NIL, Type) #define simple_out_of_range(Sc, Caller, Arg, Description) \ simple_out_of_range_error_prepackaged(Sc, symbol_name_cell(Caller), Arg, Description) #define out_of_range(Sc, Caller, Arg_Num, Arg, Description) \ out_of_range_error_prepackaged(Sc, symbol_name_cell(Caller), Arg_Num, Arg, Description) static s7_pointer CAR_A_LIST, CDR_A_LIST; static s7_pointer CAAR_A_LIST, CADR_A_LIST, CDAR_A_LIST, CDDR_A_LIST; static s7_pointer CAAAR_A_LIST, CAADR_A_LIST, CADAR_A_LIST, CADDR_A_LIST, CDAAR_A_LIST, CDADR_A_LIST, CDDAR_A_LIST, CDDDR_A_LIST; static s7_pointer A_LIST, AN_ASSOCIATION_LIST, AN_OUTPUT_PORT, AN_INPUT_PORT, AN_OPEN_PORT, A_NORMAL_REAL, A_RATIONAL, A_BOOLEAN; static s7_pointer A_NUMBER, A_LET, A_PROCEDURE, A_PROPER_LIST, A_THUNK, SOMETHING_APPLICABLE, A_SYMBOL, A_NON_NEGATIVE_INTEGER; static s7_pointer A_FORMAT_PORT, AN_UNSIGNED_BYTE, A_BINDING, A_NON_CONSTANT_SYMBOL, AN_EQ_FUNC, A_SEQUENCE, ITS_TOO_SMALL, A_NORMAL_PROCEDURE; static s7_pointer ITS_TOO_LARGE, ITS_NEGATIVE, RESULT_IS_TOO_LARGE, ITS_NAN, ITS_INFINITE, TOO_MANY_INDICES, A_VALID_RADIX; static s7_pointer AN_INPUT_STRING_PORT, AN_INPUT_FILE_PORT, AN_OUTPUT_STRING_PORT, AN_OUTPUT_FILE_PORT, A_RANDOM_STATE_OBJECT; #if (!HAVE_COMPLEX_NUMBERS) static s7_pointer NO_COMPLEX_NUMBERS; #endif /* ---------------- evaluator ops ---------------- */ enum {OP_NO_OP, OP_READ_INTERNAL, OP_EVAL, OP_EVAL_ARGS, OP_EVAL_ARGS1, OP_EVAL_ARGS2, OP_EVAL_ARGS3, OP_EVAL_ARGS4, OP_EVAL_ARGS5, OP_APPLY, OP_EVAL_MACRO, OP_LAMBDA, OP_QUOTE, OP_MACROEXPAND, OP_DEFINE, OP_DEFINE1, OP_BEGIN, OP_BEGIN_UNCHECKED, OP_BEGIN1, OP_IF, OP_IF1, OP_WHEN, OP_WHEN1, OP_UNLESS, OP_UNLESS1, OP_SET, OP_SET1, OP_SET2, OP_LET, OP_LET1, OP_LET_STAR, OP_LET_STAR1, OP_LET_STAR2, OP_LETREC, OP_LETREC1, OP_LETREC_STAR, OP_LETREC_STAR1, OP_COND, OP_COND1, OP_COND_SIMPLE, OP_COND1_SIMPLE, OP_AND, OP_AND1, OP_OR, OP_OR1, OP_DEFINE_MACRO, OP_DEFINE_MACRO_STAR, OP_DEFINE_EXPANSION, OP_CASE, OP_CASE1, OP_READ_LIST, OP_READ_NEXT, OP_READ_DOT, OP_READ_QUOTE, OP_READ_QUASIQUOTE, OP_READ_QUASIQUOTE_VECTOR, OP_READ_UNQUOTE, OP_READ_APPLY_VALUES, OP_READ_VECTOR, OP_READ_BYTE_VECTOR, OP_READ_DONE, OP_LOAD_RETURN_IF_EOF, OP_LOAD_CLOSE_AND_POP_IF_EOF, OP_EVAL_STRING, OP_EVAL_DONE, OP_CATCH, OP_DYNAMIC_WIND, OP_DEFINE_CONSTANT, OP_DEFINE_CONSTANT1, OP_DO, OP_DO_END, OP_DO_END1, OP_DO_STEP, OP_DO_STEP2, OP_DO_INIT, OP_DEFINE_STAR, OP_LAMBDA_STAR, OP_LAMBDA_STAR_DEFAULT, OP_ERROR_QUIT, OP_UNWIND_INPUT, OP_UNWIND_OUTPUT, OP_ERROR_HOOK_QUIT, OP_WITH_LET, OP_WITH_LET1, OP_WITH_LET_UNCHECKED, OP_WITH_LET_S, OP_WITH_BAFFLE, OP_WITH_BAFFLE_UNCHECKED, OP_EXPANSION, OP_FOR_EACH, OP_FOR_EACH_1, OP_FOR_EACH_2, OP_FOR_EACH_3, OP_MAP, OP_MAP_1, OP_MAP_GATHER, OP_MAP_GATHER_1, OP_BARRIER, OP_DEACTIVATE_GOTO, OP_DEFINE_BACRO, OP_DEFINE_BACRO_STAR, OP_GET_OUTPUT_STRING, OP_GET_OUTPUT_STRING_1, OP_SORT, OP_SORT1, OP_SORT2, OP_SORT3, OP_SORT_PAIR_END, OP_SORT_VECTOR_END, OP_SORT_STRING_END, OP_EVAL_STRING_1, OP_EVAL_STRING_2, OP_MEMBER_IF, OP_ASSOC_IF, OP_MEMBER_IF1, OP_ASSOC_IF1, OP_QUOTE_UNCHECKED, OP_LAMBDA_UNCHECKED, OP_LET_UNCHECKED, OP_CASE_UNCHECKED, OP_WHEN_UNCHECKED, OP_UNLESS_UNCHECKED, OP_SET_UNCHECKED, OP_SET_SYMBOL_C, OP_SET_SYMBOL_S, OP_SET_SYMBOL_Q, OP_SET_SYMBOL_P, OP_SET_SYMBOL_Z, OP_SET_SYMBOL_A, OP_SET_SYMBOL_opSq, OP_SET_SYMBOL_opCq, OP_SET_SYMBOL_opSSq, OP_SET_SYMBOL_opSSSq, OP_SET_NORMAL, OP_SET_PAIR, OP_SET_PAIR_Z, OP_SET_PAIR_A, OP_SET_PAIR_P, OP_SET_PAIR_ZA, OP_SET_PAIR_P_1, OP_SET_WITH_ACCESSOR, OP_SET_PWS, OP_SET_LET_S, OP_SET_LET_ALL_X, OP_SET_PAIR_C, OP_SET_PAIR_C_P, OP_SET_PAIR_C_P_1, OP_SET_SAFE, OP_INCREMENT_1, OP_DECREMENT_1, OP_SET_CONS, OP_INCREMENT_SS, OP_INCREMENT_SSS, OP_INCREMENT_SZ, OP_INCREMENT_SA, OP_INCREMENT_SAA, OP_LET_STAR_UNCHECKED, OP_LETREC_UNCHECKED, OP_LETREC_STAR_UNCHECKED, OP_COND_UNCHECKED, OP_LAMBDA_STAR_UNCHECKED, OP_DO_UNCHECKED, OP_DEFINE_UNCHECKED, OP_DEFINE_STAR_UNCHECKED, OP_DEFINE_FUNCHECKED, OP_DEFINE_CONSTANT_UNCHECKED, OP_DEFINE_WITH_ACCESSOR, OP_DEFINE_MACRO_WITH_ACCESSOR, OP_LET_NO_VARS, OP_NAMED_LET, OP_NAMED_LET_NO_VARS, OP_NAMED_LET_STAR, OP_LET_C, OP_LET_S, OP_LET_ALL_C, OP_LET_ALL_S, OP_LET_ALL_X, OP_LET_STAR_ALL_X, OP_LET_opCq, OP_LET_opSSq, OP_LET_opSq, OP_LET_ALL_opSq, OP_LET_opSq_P, OP_LET_ONE, OP_LET_ONE_1, OP_LET_Z, OP_LET_Z_1, OP_CASE_SIMPLE, OP_CASE_SIMPLER, OP_CASE_SIMPLER_1, OP_CASE_SIMPLER_SS, OP_CASE_SIMPLEST, OP_CASE_SIMPLEST_SS, OP_IF_UNCHECKED, OP_AND_UNCHECKED, OP_AND_P, OP_AND_P1, OP_AND_P2, OP_OR_UNCHECKED, OP_OR_P, OP_OR_P1, OP_OR_P2, OP_IF_P_FEED, OP_IF_P_FEED_1, OP_WHEN_S, OP_UNLESS_S, OP_IF_S_P, OP_IF_S_P_P, OP_IF_NOT_S_P, OP_IF_NOT_S_P_P, OP_IF_CC_P, OP_IF_CC_P_P, OP_IF_CS_P, OP_IF_CS_P_P, OP_IF_CSQ_P, OP_IF_CSQ_P_P, OP_IF_CSS_P, OP_IF_CSS_P_P, OP_IF_CSC_P, OP_IF_CSC_P_P, OP_IF_IS_PAIR_P, OP_IF_IS_PAIR_P_P, OP_IF_opSSq_P, OP_IF_opSSq_P_P, OP_IF_S_opCq_P, OP_IF_S_opCq_P_P, OP_IF_IS_SYMBOL_P, OP_IF_IS_SYMBOL_P_P, OP_IF_A_P, OP_IF_A_P_P, OP_IF_AND2_P, OP_IF_AND2_P_P, OP_IF_Z_P, OP_IF_Z_P_P, OP_IF_P_P_P, OP_IF_P_P, OP_IF_ANDP_P, OP_IF_ANDP_P_P, OP_IF_ORP_P, OP_IF_ORP_P_P, OP_IF_PPP, OP_IF_PP, OP_CATCH_1, OP_CATCH_2, OP_CATCH_ALL, OP_COND_ALL_X, OP_COND_ALL_X_2, OP_COND_S, OP_SIMPLE_DO, OP_SIMPLE_DO_STEP, OP_SAFE_DOTIMES, OP_SAFE_DOTIMES_STEP, OP_SAFE_DOTIMES_STEP_P, OP_SAFE_DOTIMES_STEP_O, OP_SAFE_DOTIMES_STEP_A, OP_SAFE_DO, OP_SAFE_DO_STEP, OP_SIMPLE_DO_P, OP_SIMPLE_DO_STEP_P, OP_DOX, OP_DOX_STEP, OP_DOX_STEP_P, OP_DOTIMES_P, OP_DOTIMES_STEP_P, OP_SIMPLE_DO_A, OP_SIMPLE_DO_STEP_A, OP_SIMPLE_DO_E, OP_SIMPLE_DO_STEP_E, OP_SAFE_C_P_1, OP_SAFE_C_PP_1, OP_SAFE_C_PP_2, OP_SAFE_C_PP_3, OP_SAFE_C_PP_4, OP_SAFE_C_PP_5, OP_SAFE_C_PP_6, OP_EVAL_ARGS_P_2, OP_EVAL_ARGS_P_2_MV, OP_EVAL_ARGS_P_3, OP_EVAL_ARGS_P_4, OP_EVAL_ARGS_P_3_MV, OP_EVAL_ARGS_P_4_MV, OP_EVAL_ARGS_SSP_1, OP_EVAL_ARGS_SSP_MV, OP_EVAL_MACRO_MV, OP_MACROEXPAND_1, OP_SAFE_C_ZZ_1, OP_SAFE_C_ZZ_2, OP_SAFE_C_ZC_1, OP_SAFE_C_SZ_1, OP_SAFE_C_ZA_1, OP_INCREMENT_SZ_1, OP_SAFE_C_SZ_SZ, OP_SAFE_C_ZAA_1, OP_SAFE_C_AZA_1, OP_SAFE_C_AAZ_1, OP_SAFE_C_SSZ_1, OP_SAFE_C_ZZA_1, OP_SAFE_C_ZZA_2, OP_SAFE_C_ZAZ_1, OP_SAFE_C_ZAZ_2, OP_SAFE_C_AZZ_1, OP_SAFE_C_AZZ_2, OP_SAFE_C_ZZZ_1, OP_SAFE_C_ZZZ_2, OP_SAFE_C_ZZZ_3, OP_SAFE_C_opSq_P_1, OP_SAFE_C_opSq_P_MV, OP_C_P_1, OP_C_P_2, OP_C_SP_1, OP_C_SP_2, OP_CLOSURE_P_1, OP_CLOSURE_P_2, OP_SAFE_CLOSURE_P_1, OP_MAX_DEFINED_1}; #define OP_MAX_DEFINED (OP_MAX_DEFINED_1 + 1) typedef enum{E_C_P, E_C_PP, E_C_CP, E_C_SP, E_C_PC, E_C_PS} combine_op_t; enum {OP_SAFE_C_C, HOP_SAFE_C_C, OP_SAFE_C_S, HOP_SAFE_C_S, OP_SAFE_C_SS, HOP_SAFE_C_SS, OP_SAFE_C_SC, HOP_SAFE_C_SC, OP_SAFE_C_CS, HOP_SAFE_C_CS, OP_SAFE_C_Q, HOP_SAFE_C_Q, OP_SAFE_C_SQ, HOP_SAFE_C_SQ, OP_SAFE_C_QS, HOP_SAFE_C_QS, OP_SAFE_C_QQ, HOP_SAFE_C_QQ, OP_SAFE_C_CQ, HOP_SAFE_C_CQ, OP_SAFE_C_QC, HOP_SAFE_C_QC, OP_SAFE_C_SSS, HOP_SAFE_C_SSS, OP_SAFE_C_SCS, HOP_SAFE_C_SCS, OP_SAFE_C_SSC, HOP_SAFE_C_SSC, OP_SAFE_C_CSS, HOP_SAFE_C_CSS, OP_SAFE_C_SCC, HOP_SAFE_C_SCC, OP_SAFE_C_CSC, HOP_SAFE_C_CSC, OP_SAFE_C_ALL_S, HOP_SAFE_C_ALL_S, OP_SAFE_C_ALL_X, HOP_SAFE_C_ALL_X, OP_SAFE_C_SSA, HOP_SAFE_C_SSA, OP_SAFE_C_SAS, HOP_SAFE_C_SAS, OP_SAFE_C_CSA, HOP_SAFE_C_CSA, OP_SAFE_C_SCA, HOP_SAFE_C_SCA, OP_SAFE_C_CAS, HOP_SAFE_C_CAS, OP_SAFE_C_A, HOP_SAFE_C_A, OP_SAFE_C_AA, HOP_SAFE_C_AA, OP_SAFE_C_AAA, HOP_SAFE_C_AAA, OP_SAFE_C_AAAA, HOP_SAFE_C_AAAA, OP_SAFE_C_SQS, HOP_SAFE_C_SQS, OP_SAFE_C_opAq, HOP_SAFE_C_opAq, OP_SAFE_C_opAAq, HOP_SAFE_C_opAAq, OP_SAFE_C_opAAAq, HOP_SAFE_C_opAAAq, OP_SAFE_C_S_opAq, HOP_SAFE_C_S_opAq, OP_SAFE_C_S_opAAq, HOP_SAFE_C_S_opAAq, OP_SAFE_C_S_opAAAq, HOP_SAFE_C_S_opAAAq, OP_SAFE_C_opCq, HOP_SAFE_C_opCq, OP_SAFE_C_opSq, HOP_SAFE_C_opSq, OP_SAFE_C_opSSq, HOP_SAFE_C_opSSq, OP_SAFE_C_opSCq, HOP_SAFE_C_opSCq, OP_SAFE_C_opSQq, HOP_SAFE_C_opSQq, OP_SAFE_C_opCSq, HOP_SAFE_C_opCSq, OP_SAFE_C_S_opSq, HOP_SAFE_C_S_opSq, OP_SAFE_C_C_opSCq, HOP_SAFE_C_C_opSCq, OP_SAFE_C_S_opSCq, HOP_SAFE_C_S_opSCq, OP_SAFE_C_S_opCSq, HOP_SAFE_C_S_opCSq, OP_SAFE_C_opSq_S, HOP_SAFE_C_opSq_S, OP_SAFE_C_opSq_C, HOP_SAFE_C_opSq_C, OP_SAFE_C_opSq_opSq, HOP_SAFE_C_opSq_opSq, OP_SAFE_C_S_opSSq, HOP_SAFE_C_S_opSSq, OP_SAFE_C_C_opSq, HOP_SAFE_C_C_opSq, OP_SAFE_C_C_opCSq, HOP_SAFE_C_C_opCSq, OP_SAFE_C_opCSq_C, HOP_SAFE_C_opCSq_C, OP_SAFE_C_S_opCq, HOP_SAFE_C_S_opCq, OP_SAFE_C_opSSq_C, HOP_SAFE_C_opSSq_C, OP_SAFE_C_C_opSSq, HOP_SAFE_C_C_opSSq, OP_SAFE_C_C_opCq, HOP_SAFE_C_C_opCq, OP_SAFE_C_opCq_S, HOP_SAFE_C_opCq_S, OP_SAFE_C_opCq_opCq, HOP_SAFE_C_opCq_opCq, OP_SAFE_C_opCq_C, HOP_SAFE_C_opCq_C, OP_SAFE_C_opSCq_opSCq, HOP_SAFE_C_opSCq_opSCq, OP_SAFE_C_opSSq_opSSq, HOP_SAFE_C_opSSq_opSSq, OP_SAFE_C_opSSq_opCq, HOP_SAFE_C_opSSq_opCq, OP_SAFE_C_opSSq_opSq, HOP_SAFE_C_opSSq_opSq, OP_SAFE_C_opSq_opSSq, HOP_SAFE_C_opSq_opSSq, OP_SAFE_C_opSSq_S, HOP_SAFE_C_opSSq_S, OP_SAFE_C_opSCq_S, HOP_SAFE_C_opSCq_S, OP_SAFE_C_opCSq_S, HOP_SAFE_C_opCSq_S, OP_SAFE_C_opSCq_C, HOP_SAFE_C_opSCq_C, OP_SAFE_C_opCq_opSSq, HOP_SAFE_C_opCq_opSSq, OP_SAFE_C_S_op_opSSq_Sq, HOP_SAFE_C_S_op_opSSq_Sq, OP_SAFE_C_S_op_S_opSSqq, HOP_SAFE_C_S_op_S_opSSqq, OP_SAFE_C_op_opSSq_q_C, HOP_SAFE_C_op_opSSq_q_C, OP_SAFE_C_op_opSq_q_C, HOP_SAFE_C_op_opSq_q_C, OP_SAFE_C_op_opSSq_q_S, HOP_SAFE_C_op_opSSq_q_S, OP_SAFE_C_op_opSq_q_S, HOP_SAFE_C_op_opSq_q_S, OP_SAFE_C_S_op_opSSq_opSSqq, HOP_SAFE_C_S_op_opSSq_opSSqq, OP_SAFE_C_op_opSq_q, HOP_SAFE_C_op_opSq_q, OP_SAFE_C_C_op_S_opCqq, HOP_SAFE_C_C_op_S_opCqq, OP_SAFE_C_op_S_opSq_q, HOP_SAFE_C_op_S_opSq_q, OP_SAFE_C_Z, HOP_SAFE_C_Z, OP_SAFE_C_ZZ, HOP_SAFE_C_ZZ, OP_SAFE_C_SZ, HOP_SAFE_C_SZ, OP_SAFE_C_ZS, HOP_SAFE_C_ZS, OP_SAFE_C_CZ, HOP_SAFE_C_CZ, OP_SAFE_C_ZC, HOP_SAFE_C_ZC, OP_SAFE_C_opCq_Z, HOP_SAFE_C_opCq_Z, OP_SAFE_C_S_opSZq, HOP_SAFE_C_S_opSZq, OP_SAFE_C_AZ, HOP_SAFE_C_AZ, OP_SAFE_C_ZA, HOP_SAFE_C_ZA, OP_SAFE_C_ZAA, HOP_SAFE_C_ZAA, OP_SAFE_C_AZA, HOP_SAFE_C_AZA, OP_SAFE_C_AAZ, HOP_SAFE_C_AAZ, OP_SAFE_C_SSZ, HOP_SAFE_C_SSZ, OP_SAFE_C_ZZA, HOP_SAFE_C_ZZA, OP_SAFE_C_ZAZ, HOP_SAFE_C_ZAZ, OP_SAFE_C_AZZ, HOP_SAFE_C_AZZ, OP_SAFE_C_ZZZ, HOP_SAFE_C_ZZZ, OP_THUNK, HOP_THUNK, OP_CLOSURE_S, HOP_CLOSURE_S, OP_CLOSURE_C, HOP_CLOSURE_C, OP_CLOSURE_Q, HOP_CLOSURE_Q, OP_CLOSURE_SS, HOP_CLOSURE_SS, OP_CLOSURE_SC, HOP_CLOSURE_SC, OP_CLOSURE_CS, HOP_CLOSURE_CS, OP_CLOSURE_A, HOP_CLOSURE_A, OP_CLOSURE_AA, HOP_CLOSURE_AA, OP_CLOSURE_ALL_X, HOP_CLOSURE_ALL_X, OP_CLOSURE_ALL_S, HOP_CLOSURE_ALL_S, OP_GLOSURE_A, HOP_GLOSURE_A, OP_GLOSURE_S, HOP_GLOSURE_S, OP_GLOSURE_P, HOP_GLOSURE_P, OP_CLOSURE_STAR_S, HOP_CLOSURE_STAR_S, OP_CLOSURE_STAR_SX, HOP_CLOSURE_STAR_SX, OP_CLOSURE_STAR, HOP_CLOSURE_STAR, OP_CLOSURE_STAR_ALL_X, HOP_CLOSURE_STAR_ALL_X, OP_SAFE_THUNK, HOP_SAFE_THUNK, OP_SAFE_THUNK_E, HOP_SAFE_THUNK_E, OP_SAFE_THUNK_P, HOP_SAFE_THUNK_P, OP_SAFE_CLOSURE_S, HOP_SAFE_CLOSURE_S, OP_SAFE_CLOSURE_C, HOP_SAFE_CLOSURE_C, OP_SAFE_CLOSURE_Q, HOP_SAFE_CLOSURE_Q, OP_SAFE_CLOSURE_SS, HOP_SAFE_CLOSURE_SS, OP_SAFE_CLOSURE_SC, HOP_SAFE_CLOSURE_SC, OP_SAFE_CLOSURE_CS, HOP_SAFE_CLOSURE_CS, OP_SAFE_CLOSURE_A, HOP_SAFE_CLOSURE_A, OP_SAFE_CLOSURE_SA, HOP_SAFE_CLOSURE_SA, OP_SAFE_CLOSURE_S_P, HOP_SAFE_CLOSURE_S_P, OP_SAFE_CLOSURE_SAA, HOP_SAFE_CLOSURE_SAA, OP_SAFE_CLOSURE_ALL_X, HOP_SAFE_CLOSURE_ALL_X, OP_SAFE_CLOSURE_AA, HOP_SAFE_CLOSURE_AA, OP_SAFE_GLOSURE_A, HOP_SAFE_GLOSURE_A, OP_SAFE_GLOSURE_S, HOP_SAFE_GLOSURE_S, OP_SAFE_GLOSURE_S_E, HOP_SAFE_GLOSURE_S_E, OP_SAFE_GLOSURE_P, HOP_SAFE_GLOSURE_P, OP_SAFE_CLOSURE_STAR_S, HOP_SAFE_CLOSURE_STAR_S, OP_SAFE_CLOSURE_STAR_SS, HOP_SAFE_CLOSURE_STAR_SS, OP_SAFE_CLOSURE_STAR_SC, HOP_SAFE_CLOSURE_STAR_SC, OP_SAFE_CLOSURE_STAR_SA, HOP_SAFE_CLOSURE_STAR_SA, OP_SAFE_CLOSURE_STAR_S0, HOP_SAFE_CLOSURE_STAR_S0, OP_SAFE_CLOSURE_STAR, HOP_SAFE_CLOSURE_STAR, OP_SAFE_CLOSURE_STAR_ALL_X, HOP_SAFE_CLOSURE_STAR_ALL_X, /* these can't be embedded, and have to be the last thing called */ OP_APPLY_SS, HOP_APPLY_SS, OP_C_ALL_X, HOP_C_ALL_X, OP_CALL_WITH_EXIT, HOP_CALL_WITH_EXIT, OP_C_CATCH, HOP_C_CATCH, OP_C_CATCH_ALL, HOP_C_CATCH_ALL, OP_C_S_opSq, HOP_C_S_opSq, OP_C_S_opCq, HOP_C_S_opCq, OP_C_SS, HOP_C_SS, OP_C_S, HOP_C_S, OP_READ_S, HOP_READ_S, OP_C_P, HOP_C_P, OP_C_Z, HOP_C_Z, OP_C_SP, HOP_C_SP, OP_C_SZ, HOP_C_SZ, OP_C_A, HOP_C_A, OP_C_SCS, HOP_C_SCS, OP_GOTO, HOP_GOTO, OP_GOTO_C, HOP_GOTO_C, OP_GOTO_S, HOP_GOTO_S, OP_GOTO_A, HOP_GOTO_A, OP_VECTOR_C, HOP_VECTOR_C, OP_VECTOR_S, HOP_VECTOR_S, OP_VECTOR_A, HOP_VECTOR_A, OP_VECTOR_CC, HOP_VECTOR_CC, OP_STRING_C, HOP_STRING_C, OP_STRING_S, HOP_STRING_S, OP_STRING_A, HOP_STRING_A, OP_C_OBJECT, HOP_C_OBJECT, OP_C_OBJECT_C, HOP_C_OBJECT_C, OP_C_OBJECT_S, HOP_C_OBJECT_S, OP_C_OBJECT_A, HOP_C_OBJECT_A, OP_PAIR_C, HOP_PAIR_C, OP_PAIR_S, HOP_PAIR_S, OP_PAIR_A, HOP_PAIR_A, OP_HASH_TABLE_C, HOP_HASH_TABLE_C, OP_HASH_TABLE_S, HOP_HASH_TABLE_S, OP_HASH_TABLE_A, HOP_HASH_TABLE_A, OP_ENVIRONMENT_S, HOP_ENVIRONMENT_S, OP_ENVIRONMENT_Q, HOP_ENVIRONMENT_Q, OP_ENVIRONMENT_A, HOP_ENVIRONMENT_A, OP_ENVIRONMENT_C, HOP_ENVIRONMENT_C, OP_UNKNOWN, HOP_UNKNOWN, OP_UNKNOWN_ALL_S, HOP_UNKNOWN_ALL_S, OP_UNKNOWN_ALL_X, HOP_UNKNOWN_ALL_X, OP_UNKNOWN_G, HOP_UNKNOWN_G, OP_UNKNOWN_GG, HOP_UNKNOWN_GG, OP_UNKNOWN_A, HOP_UNKNOWN_A, OP_UNKNOWN_AA, HOP_UNKNOWN_AA, OP_SAFE_C_PP, HOP_SAFE_C_PP, OP_SAFE_C_opSq_P, HOP_SAFE_C_opSq_P, OP_SAFE_C_SP, HOP_SAFE_C_SP, OP_SAFE_C_CP, HOP_SAFE_C_CP, OP_SAFE_C_QP, HOP_SAFE_C_QP, OP_SAFE_C_AP, HOP_SAFE_C_AP, OP_SAFE_C_PS, HOP_SAFE_C_PS, OP_SAFE_C_PC, HOP_SAFE_C_PC, OP_SAFE_C_PQ, HOP_SAFE_C_PQ, OP_SAFE_C_SSP, HOP_SAFE_C_SSP, OPT_MAX_DEFINED }; #if DEBUGGING || OP_NAMES static const char *op_names[OP_MAX_DEFINED_1] = { "no_op", "read_internal", "eval", "eval_args", "eval_args1", "eval_args2", "eval_args3", "eval_args4", "eval_args5", "apply", "eval_macro", "lambda", "quote", "macroexpand", "define", "define1", "begin", "begin_unchecked", "begin1", "if", "if1", "when", "when1", "unless", "unless1", "set", "set1", "set2", "let", "let1", "let_star", "let_star1", "let_star2", "letrec", "letrec1", "letrec_star", "letrec_star1", "cond", "cond1", "cond_simple", "cond1_simple", "and", "and1", "or", "or1", "define_macro", "define_macro_star", "define_expansion", "case", "case1", "read_list", "read_next", "read_dot", "read_quote", "read_quasiquote", "read_quasiquote_vector", "read_unquote", "read_apply_values", "read_vector", "read_byte_vector", "read_done", "load_return_if_eof", "load_close_and_pop_if_eof", "eval_string", "eval_done", "catch", "dynamic_wind", "define_constant", "define_constant1", "do", "do_end", "do_end1", "do_step", "do_step2", "do_init", "define_star", "lambda_star", "lambda_star_default", "error_quit", "unwind_input", "unwind_output", "error_hook_quit", "with_let", "with_let1", "with_let_unchecked", "with_let_s", "with_baffle", "with_baffle_unchecked", "expansion", "for_each", "for_each_1", "for_each_2", "for_each_3", "map", "map_1", "map_gather", "map_gather_1", "barrier", "deactivate_goto", "define_bacro", "define_bacro_star", "get_output_string", "get_output_string_1", "sort", "sort1", "sort2", "sort3", "sort_pair_end", "sort_vector_end", "sort_string_end", "eval_string_1", "eval_string_2", "member_if", "assoc_if", "member_if1", "assoc_if1", "quote_unchecked", "lambda_unchecked", "let_unchecked", "case_unchecked", "when_unchecked", "unless_unchecked", "set_unchecked", "set_symbol_c", "set_symbol_s", "set_symbol_q", "set_symbol_p", "set_symbol_z", "set_symbol_a", "set_symbol_opsq", "set_symbol_opcq", "set_symbol_opssq", "set_symbol_opsssq", "set_normal", "set_pair", "set_pair_z", "set_pair_a", "set_pair_p", "set_pair_za", "set_pair_p_1", "set_with_accessor", "set_pws", "set_let_s", "set_let_all_x", "set_pair_c", "set_pair_c_p", "set_pair_c_p_1", "set_safe", "increment_1", "decrement_1", "set_cons", "increment_ss", "increment_sss", "increment_sz", "increment_sa", "increment_saa", "let_star_unchecked", "letrec_unchecked", "letrec_star_unchecked", "cond_unchecked", "lambda_star_unchecked", "do_unchecked", "define_unchecked", "define_star_unchecked", "define_funchecked", "define_constant_unchecked", "define_with_accessor", "define_macro_with_accessor", "let_no_vars", "named_let", "named_let_no_vars", "named_let_star", "let_c", "let_s", "let_all_c", "let_all_s", "let_all_x", "let_star_all_x", "let_opcq", "let_opssq", "let_opsq", "let_all_opsq", "let_opsq_p", "let_one", "let_one_1", "let_z", "let_z_1", "case_simple", "case_simpler", "case_simpler_1", "case_simpler_ss", "case_simplest", "case_simplest_ss", "if_unchecked", "and_unchecked", "and_p", "and_p1", "and_p2", "or_unchecked", "or_p", "or_p1", "or_p2", "if_p_feed", "if_p_feed_1", "when_s", "unless_s", "if_s_p", "if_s_p_p", "if_not_s_p", "if_not_s_p_p", "if_cc_p", "if_cc_p_p", "if_cs_p", "if_cs_p_p", "if_csq_p", "if_csq_p_p", "if_css_p", "if_css_p_p", "if_csc_p", "if_csc_p_p", "if_is_pair_p", "if_is_pair_p_p", "if_opssq_p", "if_opssq_p_p", "if_s_opcq_p", "if_s_opcq_p_p", "if_is_symbol_p", "if_is_symbol_p_p", "if_a_p", "if_a_p_p", "if_and2_p", "if_and2_p_p", "if_z_p", "if_z_p_p", "if_p_p_p", "if_p_p", "if_andp_p", "if_andp_p_p", "if_orp_p", "if_orp_p_p", "if_ppp", "if_pp", "catch_1", "catch_2", "catch_all", "cond_all_x", "cond_all_x_2", "cond_s", "simple_do", "simple_do_step", "safe_dotimes", "safe_dotimes_step", "safe_dotimes_step_p", "safe_dotimes_step_o", "safe_dotimes_step_a", "safe_do", "safe_do_step", "simple_do_p", "simple_do_step_p", "dox", "dox_step", "dox_step_p", "dotimes_p", "dotimes_step_p", "simple_do_a", "simple_do_step_a", "simple_do_e", "simple_do_step_e", "safe_c_p_1", "safe_c_pp_1", "safe_c_pp_2", "safe_c_pp_3", "safe_c_pp_4", "safe_c_pp_5", "safe_c_pp_6", "eval_args_p_2", "eval_args_p_2_mv", "eval_args_p_3", "eval_args_p_4", "eval_args_p_3_mv", "eval_args_p_4_mv", "eval_args_ssp_1", "eval_args_ssp_mv", "eval_macro_mv", "macroexpand_1", "safe_c_zz_1", "safe_c_zz_2", "safe_c_zc_1", "safe_c_sz_1", "safe_c_za_1", "increment_sz_1", "safe_c_sz_sz", "safe_c_zaa_1", "safe_c_aza_1", "safe_c_aaz_1", "safe_c_ssz_1", "safe_c_zza_1", "safe_c_zza_2", "safe_c_zaz_1", "safe_c_zaz_2", "safe_c_azz_1", "safe_c_azz_2", "safe_c_zzz_1", "safe_c_zzz_2", "safe_c_zzz_3", "safe_c_opsq_p_1", "safe_c_opsq_p_mv", "c_p_1", "c_p_2", "c_sp_1", "c_sp_2", "closure_p_1", "closure_p_2", "safe_closure_p_1", }; static const char* opt_names[OPT_MAX_DEFINED] = {"safe_c_c", "h_safe_c_c", "safe_c_s", "h_safe_c_s", "safe_c_ss", "h_safe_c_ss", "safe_c_sc", "h_safe_c_sc", "safe_c_cs", "h_safe_c_cs", "safe_c_q", "h_safe_c_q", "safe_c_sq", "h_safe_c_sq", "safe_c_qs", "h_safe_c_qs", "safe_c_qq", "h_safe_c_qq", "safe_c_cq", "h_safe_c_cq", "safe_c_qc", "h_safe_c_qc", "safe_c_sss", "h_safe_c_sss", "safe_c_scs", "h_safe_c_scs", "safe_c_ssc", "h_safe_c_ssc", "safe_c_css", "h_safe_c_css", "safe_c_scc", "h_safe_c_scc", "safe_c_csc", "h_safe_c_csc", "safe_c_all_s", "h_safe_c_all_s", "safe_c_all_x", "h_safe_c_all_x", "safe_c_ssa", "h_safe_c_ssa", "safe_c_sas", "h_safe_c_sas", "safe_c_csa", "h_safe_c_csa", "safe_c_sca", "h_safe_c_sca", "safe_c_cas", "h_safe_c_cas", "safe_c_a", "h_safe_c_a", "safe_c_aa", "h_safe_c_aa", "safe_c_aaa", "h_safe_c_aaa", "safe_c_aaaa", "h_safe_c_aaaa", "safe_c_sqs", "h_safe_c_sqs", "safe_c_opaq", "h_safe_c_opaq", "safe_c_opaaq", "h_safe_c_opaaq", "safe_c_opaaaq", "h_safe_c_opaaaq", "safe_c_s_opaq", "h_safe_c_s_opaq", "safe_c_s_opaaq", "h_safe_c_s_opaaq", "safe_c_s_opaaaq", "h_safe_c_s_opaaaq", "safe_c_opcq", "h_safe_c_opcq", "safe_c_opsq", "h_safe_c_opsq", "safe_c_opssq", "h_safe_c_opssq", "safe_c_opscq", "h_safe_c_opscq", "safe_c_opsqq", "h_safe_c_opsqq", "safe_c_opcsq", "h_safe_c_opcsq", "safe_c_s_opsq", "h_safe_c_s_opsq", "safe_c_c_opscq", "h_safe_c_c_opscq", "safe_c_s_opscq", "h_safe_c_s_opscq", "safe_c_s_opcsq", "h_safe_c_s_opcsq", "safe_c_opsq_s", "h_safe_c_opsq_s", "safe_c_opsq_c", "h_safe_c_opsq_c", "safe_c_opsq_opsq", "h_safe_c_opsq_opsq", "safe_c_s_opssq", "h_safe_c_s_opssq", "safe_c_c_opsq", "h_safe_c_c_opsq", "safe_c_c_opcsq", "h_safe_c_c_opcsq", "safe_c_opcsq_c", "h_safe_c_opcsq_c", "safe_c_s_opcq", "h_safe_c_s_opcq", "safe_c_opssq_c", "h_safe_c_opssq_c", "safe_c_c_opssq", "h_safe_c_c_opssq", "safe_c_c_opcq", "h_safe_c_c_opcq", "safe_c_opcq_s", "h_safe_c_opcq_s", "safe_c_opcq_opcq", "h_safe_c_opcq_opcq", "safe_c_opcq_c", "h_safe_c_opcq_c", "safe_c_opscq_opscq", "h_safe_c_opscq_opscq", "safe_c_opssq_opssq", "h_safe_c_opssq_opssq", "safe_c_opssq_opcq", "h_safe_c_opssq_opcq", "safe_c_opssq_opsq", "h_safe_c_opssq_opsq", "safe_c_opsq_opssq", "h_safe_c_opsq_opssq", "safe_c_opssq_s", "h_safe_c_opssq_s", "safe_c_opscq_s", "h_safe_c_opscq_s", "safe_c_opcsq_s", "h_safe_c_opcsq_s", "safe_c_opscq_c", "h_safe_c_opscq_c", "safe_c_opcq_opssq", "h_safe_c_opcq_opssq", "safe_c_s_op_opssq_sq", "h_safe_c_s_op_opssq_sq", "safe_c_s_op_s_opssqq", "h_safe_c_s_op_s_opssqq", "safe_c_op_opssq_q_c", "h_safe_c_op_opssq_q_c", "safe_c_op_opsq_q_c", "h_safe_c_op_opsq_q_c", "safe_c_op_opssq_q_s", "h_safe_c_op_opssq_q_s", "safe_c_op_opsq_q_s", "h_safe_c_op_opsq_q_s", "safe_c_s_op_opssq_opssqq", "h_safe_c_s_op_opssq_opssqq", "safe_c_op_opsq_q", "h_safe_c_op_opsq_q", "safe_c_c_op_s_opcqq", "h_safe_c_c_op_s_opcqq", "safe_c_op_s_opsq_q", "h_safe_c_op_s_opsq_q", "safe_c_z", "h_safe_c_z", "safe_c_zz", "h_safe_c_zz", "safe_c_sz", "h_safe_c_sz", "safe_c_zs", "h_safe_c_zs", "safe_c_cz", "h_safe_c_cz", "safe_c_zc", "h_safe_c_zc", "safe_c_opcq_z", "h_safe_c_opcq_z", "safe_c_s_opszq", "h_safe_c_s_opszq", "safe_c_az", "h_safe_c_az", "safe_c_za", "h_safe_c_za", "safe_c_zaa", "h_safe_c_zaa", "safe_c_aza", "h_safe_c_aza", "safe_c_aaz", "h_safe_c_aaz", "safe_c_ssz", "h_safe_c_ssz", "safe_c_zza", "h_safe_c_zza", "safe_c_zaz", "h_safe_c_zaz", "safe_c_azz", "h_safe_c_azz", "safe_c_zzz", "h_safe_c_zzz", "thunk", "h_thunk", "closure_s", "h_closure_s", "closure_c", "h_closure_c", "closure_q", "h_closure_q", "closure_ss", "h_closure_ss", "closure_sc", "h_closure_sc", "closure_cs", "h_closure_cs", "closure_a", "h_closure_a", "closure_aa", "h_closure_aa", "closure_all_x", "h_closure_all_x", "closure_all_s", "h_closure_all_s", "glosure_a", "h_glosure_a", "glosure_s", "h_glosure_s", "glosure_p", "h_glosure_p", "closure_star_s", "h_closure_star_s", "closure_star_sx", "h_closure_star_sx", "closure_star", "h_closure_star", "closure_star_all_x", "h_closure_star_all_x", "safe_thunk", "h_safe_thunk", "safe_thunk_e", "h_safe_thunk_e", "safe_thunk_p", "h_safe_thunk_p", "safe_closure_s", "h_safe_closure_s", "safe_closure_c", "h_safe_closure_c", "safe_closure_q", "h_safe_closure_q", "safe_closure_ss", "h_safe_closure_ss", "safe_closure_sc", "h_safe_closure_sc", "safe_closure_cs", "h_safe_closure_cs", "safe_closure_a", "h_safe_closure_a", "safe_closure_sa", "h_safe_closure_sa", "safe_closure_s_p", "h_safe_closure_s_p", "safe_closure_saa", "h_safe_closure_saa", "safe_closure_all_x", "h_safe_closure_all_x", "safe_closure_aa", "h_safe_closure_aa", "safe_glosure_a", "h_safe_glosure_a", "safe_glosure_s", "h_safe_glosure_s", "safe_glosure_s_e", "h_safe_glosure_s_e", "safe_glosure_p", "h_safe_glosure_p", "safe_closure_star_s", "h_safe_closure_star_s", "safe_closure_star_ss", "h_safe_closure_star_ss", "safe_closure_star_sc", "h_safe_closure_star_sc", "safe_closure_star_sa", "h_safe_closure_star_sa", "safe_closure_star_s0", "h_safe_closure_star_s0", "safe_closure_star", "h_safe_closure_star", "safe_closure_star_all_x", "h_safe_closure_star_all_x", "apply_ss", "h_apply_ss", "c_all_x", "h_c_all_x", "call_with_exit", "h_call_with_exit", "c_catch", "h_c_catch", "c_catch_all", "h_c_catch_all", "c_s_opsq", "h_c_s_opsq", "c_s_opcq", "h_c_s_opcq", "c_ss", "h_c_ss", "c_s", "h_c_s", "read_s", "h_read_s", "c_p", "h_c_p", "c_z", "h_c_z", "c_sp", "h_c_sp", "c_sz", "h_c_sz", "c_a", "h_c_a", "c_scs", "h_c_scs", "goto", "h_goto", "goto_c", "h_goto_c", "goto_s", "h_goto_s", "goto_a", "h_goto_a", "vector_c", "h_vector_c", "vector_s", "h_vector_s", "vector_a", "h_vector_a", "vector_cc", "h_vector_cc", "string_c", "h_string_c", "string_s", "h_string_s", "string_a", "h_string_a", "c_object", "h_c_object", "c_object_c", "h_c_object_c", "c_object_s", "h_c_object_s", "c_object_a", "h_c_object_a", "pair_c", "h_pair_c", "pair_s", "h_pair_s", "pair_a", "h_pair_a", "hash_table_c", "h_hash_table_c", "hash_table_s", "h_hash_table_s", "hash_table_a", "h_hash_table_a", "environment_s", "h_environment_s", "environment_q", "h_environment_q", "environment_a", "h_environment_a", "environment_c", "h_environment_c", "unknown", "h_unknown", "unknown_all_s", "h_unknown_all_s", "unknown_all_x", "h_unknown_all_x", "unknown_g", "h_unknown_g", "unknown_gg", "h_unknown_gg", "unknown_a", "h_unknown_a", "unknown_aa", "h_unknown_aa", "safe_c_pp", "h_safe_c_pp", "safe_c_opsq_p", "h_safe_c_opsq_p", "safe_c_sp", "h_safe_c_sp", "safe_c_cp", "h_safe_c_cp", "safe_c_qp", "h_safe_c_qp", "safe_c_ap", "h_safe_c_ap", "safe_c_ps", "h_safe_c_ps", "safe_c_pc", "h_safe_c_pc", "safe_c_pq", "h_safe_c_pq", "safe_c_ssp", "h_safe_c_ssp", }; #endif #define is_safe_c_op(op) (op < OP_THUNK) /* used only in safe_stepper */ #define is_unknown_op(op) ((op >= OP_UNKNOWN) && (op < OP_SAFE_C_PP)) #define is_callable_c_op(op) ((op < OP_THUNK) || (op > OP_UNKNOWN_AA)) /* used only in check_set */ static bool is_h_optimized(s7_pointer p) { return((is_optimized(p)) && ((optimize_op(p) & 1) != 0) && (!is_unknown_op(optimize_op(p)))); } #define is_h_safe_c_c(P) ((is_optimized(P)) && (optimize_op(P) == HOP_SAFE_C_C)) #define is_h_safe_c_s(P) ((is_optimized(P)) && (optimize_op(P) == HOP_SAFE_C_S)) #define is_safe_c_s(P) ((is_optimized(P)) && (op_no_hop(P) == OP_SAFE_C_S)) #define WITH_COUNTS 0 #if WITH_COUNTS #include "profile.h" #endif static int position_of(s7_pointer p, s7_pointer args) { int i; for (i = 1; p != args; i++, args = cdr(args)); return(i); } s7_pointer s7_method(s7_scheme *sc, s7_pointer obj, s7_pointer method) { if (has_methods(obj)) return(find_method(sc, find_let(sc, obj), method)); return(sc->UNDEFINED); } /* if a method is shadowing a built-in like abs, it should expect the same args as abs and * behave the same -- no multiple values etc. */ #define check_method(Sc, Obj, Method, Args) \ { \ s7_pointer func; \ if ((has_methods(Obj)) && ((func = find_method(Sc, find_let(Sc, Obj), Method)) != Sc->UNDEFINED)) \ return(s7_apply_function(Sc, func, Args)); \ } #define check_two_methods(Sc, Obj, Method1, Method2, Args) \ if (has_methods(Obj)) \ { \ s7_pointer func; \ func = find_method(Sc, find_let(Sc, Obj), Method1); \ if ((func == Sc->UNDEFINED) && (Method1 != Method2) && (Method2)) func = find_method(Sc, find_let(Sc, Obj), Method2); \ if (func != Sc->UNDEFINED) return(s7_apply_function(Sc, func, Args)); \ } static s7_pointer check_values(s7_scheme *sc, s7_pointer obj, s7_pointer args) { check_method(sc, obj, sc->VALUES, args); return(sc->GC_NIL); } /* unfortunately, in the simplest cases, where a function (like number?) accepts any argument, * this costs about a factor of 1.5 in speed (we're doing the normal check like s7_is_number, * but then have to check has_methods before returning #f). We can't use the old form until * openlet is seen because the prior code might use #_number? which gets the value * before the switch. These simple functions normally do not dominate timing info, so I'll * go ahead. It's mostly boilerplate: */ #define check_boolean_method(Sc, Checker, Method, Args) \ { \ s7_pointer p; \ p = car(Args); \ if (Checker(p)) return(Sc->T); \ check_method(Sc, p, Method, Args); \ return(Sc->F); \ } #define check_boolean_not_method(Sc, Checker, Method, Args) \ { \ s7_pointer p, func; \ p = find_symbol_checked(Sc, cadar(Args)); \ if (Checker(p)) return(Sc->F); \ if ((has_methods(p)) && ((func = find_method(Sc, find_let(Sc, p), Method)) != Sc->UNDEFINED) && \ (s7_apply_function(Sc, func, list_1(Sc, p)) != Sc->F)) \ return(Sc->F); \ return(Sc->T); \ } #define method_or_bust(Sc, Obj, Method, Args, Type, Num) \ { \ s7_pointer func; \ if ((has_methods(Obj)) && ((func = find_method(Sc, find_let(Sc, Obj), Method)) != Sc->UNDEFINED)) \ return(s7_apply_function(Sc, func, Args)); \ if (Num == 0) return(simple_wrong_type_argument(Sc, Method, Obj, Type)); \ return(wrong_type_argument(Sc, Method, Num, Obj, Type)); \ } #define method_or_bust_with_type(Sc, Obj, Method, Args, Type, Num) \ { \ s7_pointer func; \ if ((has_methods(Obj)) && ((func = find_method(Sc, find_let(Sc, Obj), Method)) != Sc->UNDEFINED)) \ return(s7_apply_function(Sc, func, Args)); \ if (Num == 0) return(simple_wrong_type_argument_with_type(Sc, Method, Obj, Type)); \ return(wrong_type_argument_with_type(Sc, Method, Num, Obj, Type)); \ } #define eval_error_any(Sc, ErrType, ErrMsg, Obj) \ do {static s7_pointer _Err_ = NULL; if (!_Err_) _Err_ = s7_make_permanent_string(ErrMsg); \ return(s7_error(Sc, ErrType, set_elist_2(Sc, _Err_, Obj)));} while (0) #define eval_error(Sc, ErrMsg, Obj) eval_error_any(Sc, Sc->SYNTAX_ERROR, ErrMsg, Obj) #define eval_type_error(Sc, ErrMsg, Obj) eval_error_any(Sc, Sc->WRONG_TYPE_ARG, ErrMsg, Obj) #define eval_range_error(Sc, ErrMsg, Obj) eval_error_any(Sc, Sc->OUT_OF_RANGE, ErrMsg, Obj) #define eval_error_no_return(Sc, ErrType, ErrMsg, Obj) \ do {static s7_pointer _Err_ = NULL; \ if (!_Err_) _Err_ = s7_make_permanent_string(ErrMsg); \ s7_error(Sc, ErrType, set_elist_2(Sc, _Err_, Obj));} while (0) #define eval_error_with_caller(Sc, ErrMsg, Caller, Obj) \ do {static s7_pointer _Err_ = NULL; \ if (!_Err_) _Err_ = s7_make_permanent_string(ErrMsg); \ return(s7_error(Sc, Sc->SYNTAX_ERROR, set_elist_3(Sc, _Err_, Caller, Obj)));} while (0) static s7_pointer set_elist_1(s7_scheme *sc, s7_pointer x1) { car(sc->elist_1) = x1; return(sc->elist_1); } static s7_pointer set_elist_2(s7_scheme *sc, s7_pointer x1, s7_pointer x2) { car(sc->elist_2) = x1; cadr(sc->elist_2) = x2; return(sc->elist_2); } static s7_pointer set_elist_3(s7_scheme *sc, s7_pointer x1, s7_pointer x2, s7_pointer x3) { s7_pointer p; p = sc->elist_3; car(p) = x1; p = cdr(p); car(p) = x2; p = cdr(p); car(p) = x3; return(sc->elist_3); } static s7_pointer set_elist_4(s7_scheme *sc, s7_pointer x1, s7_pointer x2, s7_pointer x3, s7_pointer x4) { s7_pointer p; p = sc->elist_4; car(p) = x1; p = cdr(p); car(p) = x2; p = cdr(p); car(p) = x3; p = cdr(p); car(p) = x4; return(sc->elist_4); } static s7_pointer set_elist_5(s7_scheme *sc, s7_pointer x1, s7_pointer x2, s7_pointer x3, s7_pointer x4, s7_pointer x5) { s7_pointer p; p = sc->elist_5; car(p) = x1; p = cdr(p); car(p) = x2; p = cdr(p); car(p) = x3; p = cdr(p); car(p) = x4; p = cdr(p); car(p) = x5; return(sc->elist_5); } static s7_pointer set_wlist_3(s7_scheme *sc, s7_pointer lst, s7_pointer x1, s7_pointer x2, s7_pointer x3) { s7_pointer p; p = lst; car(p) = x1; p = cdr(p); car(p) = x2; p = cdr(p); car(p) = x3; return(lst); } static s7_pointer set_wlist_4(s7_scheme *sc, s7_pointer lst, s7_pointer x1, s7_pointer x2, s7_pointer x3, s7_pointer x4) { s7_pointer p; p = lst; car(p) = x1; p = cdr(p); car(p) = x2; p = cdr(p); car(p) = x3; p = cdr(p); car(p) = x4; return(lst); } static s7_pointer set_plist_1(s7_scheme *sc, s7_pointer x1) { car(sc->plist_1) = x1; return(sc->plist_1); } static s7_pointer set_plist_2(s7_scheme *sc, s7_pointer x1, s7_pointer x2) { car(sc->plist_2) = x1; cadr(sc->plist_2) = x2; return(sc->plist_2); } static s7_pointer set_plist_3(s7_scheme *sc, s7_pointer x1, s7_pointer x2, s7_pointer x3) { return(set_wlist_3(sc, sc->plist_3, x1, x2, x3)); } /* an experiment */ s7_pointer s7_set_plist_1(s7_scheme *sc, s7_pointer x1) {return(set_plist_1(sc, x1));} /* -------------------------------- constants -------------------------------- */ s7_pointer s7_f(s7_scheme *sc) { return(sc->F); } s7_pointer s7_t(s7_scheme *sc) { return(sc->T); } s7_pointer s7_nil(s7_scheme *sc) { return(sc->NIL); } bool s7_is_null(s7_scheme *sc, s7_pointer p) { return(is_null(p)); } s7_pointer s7_undefined(s7_scheme *sc) { return(sc->UNDEFINED); } s7_pointer s7_unspecified(s7_scheme *sc) { return(sc->UNSPECIFIED); } bool s7_is_unspecified(s7_scheme *sc, s7_pointer val) { return(is_unspecified(val)); } s7_pointer s7_eof_object(s7_scheme *sc) /* returns # -- not equivalent to "eof-object?" */ { return(sc->EOF_OBJECT); } static s7_pointer g_not(s7_scheme *sc, s7_pointer args) { #define H_not "(not obj) returns #t if obj is #f, otherwise #t: (not ()) -> #f" #define Q_not pl_bt return(make_boolean(sc, is_false(sc, car(args)))); } bool s7_boolean(s7_scheme *sc, s7_pointer x) { return(x != sc->F); } bool s7_is_boolean(s7_pointer x) { return(type(x) == T_BOOLEAN); } s7_pointer s7_make_boolean(s7_scheme *sc, bool x) { return(make_boolean(sc, x)); } static s7_pointer g_is_boolean(s7_scheme *sc, s7_pointer args) { #define H_is_boolean "(boolean? obj) returns #t if obj is #f or #t: (boolean? ()) -> #f" #define Q_is_boolean pl_bt check_boolean_method(sc, s7_is_boolean, sc->IS_BOOLEAN, args); } bool s7_is_constant(s7_pointer p) { /* this means "always evaluates to the same thing", sort of, not "evaluates to itself": * (let ((x 'x)) (and (not (constant? x)) (equal? x (eval x)))) * (and (constant? (list + 1)) (not (equal? (list + 1) (eval (list + 1))))) */ return((type(p) != T_SYMBOL) || (is_immutable_symbol(p))); } static s7_pointer g_is_constant(s7_scheme *sc, s7_pointer args) { #define H_is_constant "(constant? obj) returns #t if obj is a constant (unsettable): (constant? pi) -> #t" #define Q_is_constant pl_bt check_boolean_method(sc, s7_is_constant, sc->IS_CONSTANT, args); } /* -------------------------------- GC -------------------------------- */ /* instead of saving the last released location, why not have a free list? * (an int array growable, with a current top and size or whatever) */ #define is_gc_nil(p) ((p) == sc->GC_NIL) unsigned int s7_gc_protect(s7_scheme *sc, s7_pointer x) { unsigned int i, loc, size, new_size; loc = sc->protected_objects_loc++; size = sc->protected_objects_size; if (sc->protected_objects_loc >= size) sc->protected_objects_loc = 0; if (is_gc_nil(vector_element(sc->protected_objects, loc))) { vector_element(sc->protected_objects, loc) = x; return(loc); } for (i = 0; i < size; i++) { if (is_gc_nil(vector_element(sc->protected_objects, i))) { vector_element(sc->protected_objects, i) = x; return(i); } } new_size = 2 * size; vector_elements(sc->protected_objects) = (s7_pointer *)realloc(vector_elements(sc->protected_objects), new_size * sizeof(s7_pointer)); vector_length(sc->protected_objects) = new_size; for (i = size; i < new_size; i++) vector_element(sc->protected_objects, i) = sc->GC_NIL; sc->protected_objects_size = new_size; sc->protected_objects_loc = size; vector_element(sc->protected_objects, size) = x; return(size); } void s7_gc_unprotect(s7_scheme *sc, s7_pointer x) { unsigned int i; for (i = 0; i < sc->protected_objects_size; i++) if (vector_element(sc->protected_objects, i) == x) { vector_element(sc->protected_objects, i) = sc->GC_NIL; sc->protected_objects_loc = i; return; } } void s7_gc_unprotect_at(s7_scheme *sc, unsigned int loc) { if (loc < sc->protected_objects_size) { vector_element(sc->protected_objects, loc) = sc->GC_NIL; sc->protected_objects_loc = loc; } } s7_pointer s7_gc_protected_at(s7_scheme *sc, unsigned int loc) { s7_pointer obj; obj = sc->UNSPECIFIED; if (loc < sc->protected_objects_size) obj = vector_element(sc->protected_objects, loc); if (obj == sc->GC_NIL) return(sc->UNSPECIFIED); return(obj); } #define gc_protected_at(Sc, Loc) vector_element(Sc->protected_objects, Loc) /* #define gc_reprotect(Sc, Loc, Val) vector_element(Sc->protected_objects, Loc) = Val */ static void (*mark_function[NUM_TYPES])(s7_pointer p); #define S7_MARK(Obj) do {s7_pointer _p_; _p_ = Obj; if (!is_marked(_p_)) (*mark_function[unchecked_type(_p_)])(_p_);} while (0) static void mark_symbol(s7_pointer p) { if (is_gensym(p)) set_mark(p); /* don't set the mark bit of a normal symbol! It wrecks the check against SYNTACTIC_TYPE, * slowing everything down by a large amount. */ } static void mark_noop(s7_pointer p) {} /* ports can be alloc'd and freed at a frightening pace, so I think I'll make a special free_list for them. */ static port_t *alloc_port(s7_scheme *sc) { if (sc->port_heap) { port_t *p; p = sc->port_heap; sc->port_heap = (port_t *)(p->next); return(p); } return((port_t *)calloc(1, sizeof(port_t))); } static void free_port(s7_scheme *sc, port_t *p) { p->next = (void *)(sc->port_heap); sc->port_heap = p; } static void close_output_port(s7_scheme *sc, s7_pointer p); static void sweep(s7_scheme *sc) { unsigned int i, j; if (sc->strings_loc > 0) { /* unrolling this loop is not an improvement */ for (i = 0, j = 0; i < sc->strings_loc; i++) { s7_pointer s1; s1 = sc->strings[i]; if (is_free_and_clear(s1)) { if (string_needs_free(s1)) free(string_value(s1)); } else sc->strings[j++] = s1; } sc->strings_loc = j; } if (sc->gensyms_loc > 0) { for (i = 0, j = 0; i < sc->gensyms_loc; i++) { s7_pointer s1; s1 = sc->gensyms[i]; if (is_free_and_clear(s1)) { remove_gensym_from_symbol_table(sc, s1); /* this uses symbol_name_cell data */ free(symbol_name(s1)); if ((is_documented(s1)) && (symbol_help(s1))) { free(symbol_help(s1)); symbol_help(s1) = NULL; } free(symbol_name_cell(s1)); } else sc->gensyms[j++] = s1; } sc->gensyms_loc = j; if (j == 0) mark_function[T_SYMBOL] = mark_noop; } if (sc->c_objects_loc > 0) { for (i = 0, j = 0; i < sc->c_objects_loc; i++) { if (is_free_and_clear(sc->c_objects[i])) free_object(sc->c_objects[i]); else sc->c_objects[j++] = sc->c_objects[i]; } sc->c_objects_loc = j; } if (sc->vectors_loc > 0) { for (i = 0, j = 0; i < sc->vectors_loc; i++) { if (is_free_and_clear(sc->vectors[i])) { s7_pointer a; a = sc->vectors[i]; /* a multidimensional empty vector can have dimension info, wrapped vectors always have dimension info */ if (vector_dimension_info(a)) { if (vector_dimensions_allocated(a)) { free(vector_dimensions(a)); free(vector_offsets(a)); } if (vector_elements_allocated(a)) free(vector_elements(a)); /* I think this will work for any vector (int/float too) */ if (vector_dimension_info(a) != sc->wrap_only) free(vector_dimension_info(a)); } else { if (vector_length(a) != 0) free(vector_elements(a)); } } else sc->vectors[j++] = sc->vectors[i]; /* here (in the else branch) if a vector constant in a global function has been removed from the heap, * not_in_heap(heap_location(v)), and we'll never see it freed, so if there were a lot of these, they might * glom up this loop. Surely not a big deal!? */ } sc->vectors_loc = j; } if (sc->hash_tables_loc > 0) { for (i = 0, j = 0; i < sc->hash_tables_loc; i++) { if (is_free_and_clear(sc->hash_tables[i])) { if (hash_table_mask(sc->hash_tables[i]) > 0) free_hash_table(sc->hash_tables[i]); } else sc->hash_tables[j++] = sc->hash_tables[i]; } sc->hash_tables_loc = j; } if (sc->input_ports_loc > 0) { for (i = 0, j = 0; i < sc->input_ports_loc; i++) { if (is_free_and_clear(sc->input_ports[i])) { s7_pointer a; a = sc->input_ports[i]; if (port_needs_free(a)) { if (port_data(a)) { free(port_data(a)); port_data(a) = NULL; port_data_size(a) = 0; } port_needs_free(a) = false; } if (port_filename(a)) { free(port_filename(a)); port_filename(a) = NULL; } free_port(sc, port_port(a)); } else sc->input_ports[j++] = sc->input_ports[i]; } sc->input_ports_loc = j; } if (sc->output_ports_loc > 0) { for (i = 0, j = 0; i < sc->output_ports_loc; i++) { if (is_free_and_clear(sc->output_ports[i])) { close_output_port(sc, sc->output_ports[i]); /* needed for free filename, etc */ free_port(sc, port_port(sc->output_ports[i])); } else sc->output_ports[j++] = sc->output_ports[i]; } sc->output_ports_loc = j; } if (sc->continuations_loc > 0) { for (i = 0, j = 0; i < sc->continuations_loc; i++) { if (is_free_and_clear(sc->continuations[i])) { s7_pointer c; c = sc->continuations[i]; if (continuation_op_stack(c)) { free(continuation_op_stack(c)); continuation_op_stack(c) = NULL; } free(continuation_data(c)); } else sc->continuations[j++] = sc->continuations[i]; } sc->continuations_loc = j; } #if WITH_GMP if (sc->bigints_loc > 0) { for (i = 0, j = 0; i < sc->bigints_loc; i++) { s7_pointer s1; s1 = sc->bigints[i]; if (is_free_and_clear(s1)) mpz_clear(big_integer(s1)); else sc->bigints[j++] = s1; } sc->bigints_loc = j; } if (sc->bigratios_loc > 0) { for (i = 0, j = 0; i < sc->bigratios_loc; i++) { s7_pointer s1; s1 = sc->bigratios[i]; if (is_free_and_clear(s1)) mpq_clear(big_ratio(s1)); else sc->bigratios[j++] = s1; } sc->bigratios_loc = j; } if (sc->bigreals_loc > 0) { for (i = 0, j = 0; i < sc->bigreals_loc; i++) { s7_pointer s1; s1 = sc->bigreals[i]; if (is_free_and_clear(s1)) mpfr_clear(big_real(s1)); else sc->bigreals[j++] = s1; } sc->bigreals_loc = j; } if (sc->bignumbers_loc > 0) { for (i = 0, j = 0; i < sc->bignumbers_loc; i++) { s7_pointer s1; s1 = sc->bignumbers[i]; if (is_free_and_clear(s1)) mpc_clear(big_complex(s1)); else sc->bignumbers[j++] = s1; } sc->bignumbers_loc = j; } #endif } static void add_string(s7_scheme *sc, s7_pointer p) { if (sc->strings_loc == sc->strings_size) { sc->strings_size *= 2; sc->strings = (s7_pointer *)realloc(sc->strings, sc->strings_size * sizeof(s7_pointer)); } sc->strings[sc->strings_loc++] = p; } #define Add_String(Str) if (sc->strings_loc == sc->strings_size) add_string(sc, Str); else sc->strings[sc->strings_loc++] = Str static void add_gensym(s7_scheme *sc, s7_pointer p) { if (sc->gensyms_loc == sc->gensyms_size) { sc->gensyms_size *= 2; sc->gensyms = (s7_pointer *)realloc(sc->gensyms, sc->gensyms_size * sizeof(s7_pointer)); } sc->gensyms[sc->gensyms_loc++] = p; mark_function[T_SYMBOL] = mark_symbol; } static void add_c_object(s7_scheme *sc, s7_pointer p) { if (sc->c_objects_loc == sc->c_objects_size) { sc->c_objects_size *= 2; sc->c_objects = (s7_pointer *)realloc(sc->c_objects, sc->c_objects_size * sizeof(s7_pointer)); } sc->c_objects[sc->c_objects_loc++] = p; } static void add_hash_table(s7_scheme *sc, s7_pointer p) { if (sc->hash_tables_loc == sc->hash_tables_size) { sc->hash_tables_size *= 2; sc->hash_tables = (s7_pointer *)realloc(sc->hash_tables, sc->hash_tables_size * sizeof(s7_pointer)); } sc->hash_tables[sc->hash_tables_loc++] = p; } static void add_vector(s7_scheme *sc, s7_pointer p) { if (sc->vectors_loc == sc->vectors_size) { sc->vectors_size *= 2; sc->vectors = (s7_pointer *)realloc(sc->vectors, sc->vectors_size * sizeof(s7_pointer)); } sc->vectors[sc->vectors_loc++] = p; } #define Add_Vector(Vec) if (sc->vectors_loc == sc->vectors_size) add_vector(sc, Vec); else sc->vectors[sc->vectors_loc++] = Vec static void add_input_port(s7_scheme *sc, s7_pointer p) { if (sc->input_ports_loc == sc->input_ports_size) { sc->input_ports_size *= 2; sc->input_ports = (s7_pointer *)realloc(sc->input_ports, sc->input_ports_size * sizeof(s7_pointer)); } sc->input_ports[sc->input_ports_loc++] = p; } static void add_output_port(s7_scheme *sc, s7_pointer p) { if (sc->output_ports_loc == sc->output_ports_size) { sc->output_ports_size *= 2; sc->output_ports = (s7_pointer *)realloc(sc->output_ports, sc->output_ports_size * sizeof(s7_pointer)); } sc->output_ports[sc->output_ports_loc++] = p; } static void add_continuation(s7_scheme *sc, s7_pointer p) { if (sc->continuations_loc == sc->continuations_size) { sc->continuations_size *= 2; sc->continuations = (s7_pointer *)realloc(sc->continuations, sc->continuations_size * sizeof(s7_pointer)); } sc->continuations[sc->continuations_loc++] = p; } #if WITH_GMP static void add_bigint(s7_scheme *sc, s7_pointer p) { if (sc->bigints_loc == sc->bigints_size) { sc->bigints_size *= 2; sc->bigints = (s7_pointer *)realloc(sc->bigints, sc->bigints_size * sizeof(s7_pointer)); } sc->bigints[sc->bigints_loc++] = p; } static void add_bigratio(s7_scheme *sc, s7_pointer p) { if (sc->bigratios_loc == sc->bigratios_size) { sc->bigratios_size *= 2; sc->bigratios = (s7_pointer *)realloc(sc->bigratios, sc->bigratios_size * sizeof(s7_pointer)); } sc->bigratios[sc->bigratios_loc++] = p; } static void add_bigreal(s7_scheme *sc, s7_pointer p) { if (sc->bigreals_loc == sc->bigreals_size) { sc->bigreals_size *= 2; sc->bigreals = (s7_pointer *)realloc(sc->bigreals, sc->bigreals_size * sizeof(s7_pointer)); } sc->bigreals[sc->bigreals_loc++] = p; } static void add_bignumber(s7_scheme *sc, s7_pointer p) { if (sc->bignumbers_loc == sc->bignumbers_size) { sc->bignumbers_size *= 2; sc->bignumbers = (s7_pointer *)realloc(sc->bignumbers, sc->bignumbers_size * sizeof(s7_pointer)); } sc->bignumbers[sc->bignumbers_loc++] = p; } #endif #define INIT_GC_CACHE_SIZE 64 static void init_gc_caches(s7_scheme *sc) { sc->strings_size = INIT_GC_CACHE_SIZE * 16; sc->strings_loc = 0; sc->strings = (s7_pointer *)malloc(sc->strings_size * sizeof(s7_pointer)); sc->gensyms_size = INIT_GC_CACHE_SIZE; sc->gensyms_loc = 0; sc->gensyms = (s7_pointer *)malloc(sc->gensyms_size * sizeof(s7_pointer)); sc->vectors_size = INIT_GC_CACHE_SIZE * 8; sc->vectors_loc = 0; sc->vectors = (s7_pointer *)malloc(sc->vectors_size * sizeof(s7_pointer)); sc->hash_tables_size = INIT_GC_CACHE_SIZE; sc->hash_tables_loc = 0; sc->hash_tables = (s7_pointer *)malloc(sc->hash_tables_size * sizeof(s7_pointer)); sc->input_ports_size = INIT_GC_CACHE_SIZE; sc->input_ports_loc = 0; sc->input_ports = (s7_pointer *)malloc(sc->input_ports_size * sizeof(s7_pointer)); sc->output_ports_size = INIT_GC_CACHE_SIZE; sc->output_ports_loc = 0; sc->output_ports = (s7_pointer *)malloc(sc->output_ports_size * sizeof(s7_pointer)); sc->continuations_size = INIT_GC_CACHE_SIZE; sc->continuations_loc = 0; sc->continuations = (s7_pointer *)malloc(sc->continuations_size * sizeof(s7_pointer)); sc->c_objects_size = INIT_GC_CACHE_SIZE; sc->c_objects_loc = 0; sc->c_objects = (s7_pointer *)malloc(sc->c_objects_size * sizeof(s7_pointer)); #if WITH_GMP sc->bigints_size = INIT_GC_CACHE_SIZE; sc->bigints_loc = 0; sc->bigints = (s7_pointer *)malloc(sc->bigints_size * sizeof(s7_pointer)); sc->bigratios_size = INIT_GC_CACHE_SIZE; sc->bigratios_loc = 0; sc->bigratios = (s7_pointer *)malloc(sc->bigratios_size * sizeof(s7_pointer)); sc->bigreals_size = INIT_GC_CACHE_SIZE; sc->bigreals_loc = 0; sc->bigreals = (s7_pointer *)malloc(sc->bigreals_size * sizeof(s7_pointer)); sc->bignumbers_size = INIT_GC_CACHE_SIZE; sc->bignumbers_loc = 0; sc->bignumbers = (s7_pointer *)malloc(sc->bignumbers_size * sizeof(s7_pointer)); #endif /* slightly unrelated... */ sc->setters_size = 4; sc->setters_loc = 0; sc->setters = (s7_pointer *)malloc(sc->c_objects_size * sizeof(s7_pointer)); } static void add_setter(s7_scheme *sc, s7_pointer p, s7_pointer setter) { /* procedure-setters GC-protected. The c_function_setter field can't be used because the built-in functions * are often removed from the heap and never thereafter marked. */ unsigned int i; for (i = 0; i < sc->setters_loc; i++) { s7_pointer x; x = sc->setters[i]; if (car(x) == p) { cdr(x) = setter; return; } } if (sc->setters_loc == sc->setters_size) { sc->setters_size *= 2; sc->setters = (s7_pointer *)realloc(sc->setters, sc->setters_size * sizeof(s7_pointer)); } sc->setters[sc->setters_loc++] = permanent_cons(p, setter, T_PAIR | T_IMMUTABLE); } static void mark_vector_1(s7_pointer p, s7_int top) { s7_pointer *tp, *tend, *tend4; set_mark(p); tp = (s7_pointer *)(vector_elements(p)); if (!tp) return; tend = (s7_pointer *)(tp + top); tend4 = (s7_pointer *)(tend - 4); while (tp <= tend4) { S7_MARK(*tp++); S7_MARK(*tp++); S7_MARK(*tp++); S7_MARK(*tp++); } while (tp < tend) S7_MARK(*tp++); } static void mark_slot(s7_pointer p) { set_mark(p); S7_MARK(slot_value(p)); if (slot_has_accessor(p)) S7_MARK(slot_accessor(p)); if (is_gensym(slot_symbol(p))) /* (let () (apply define (gensym) (list 32)) (gc) (gc) (curlet)) */ set_mark(slot_symbol(p)); } static void mark_let(s7_pointer env) { s7_pointer x; for (x = env; is_let(x) && (!is_marked(x)); x = outlet(x)) { s7_pointer y; set_mark(x); for (y = let_slots(x); is_slot(y); y = next_slot(y)) if (!is_marked(y)) /* slot value might be the enclosing let */ mark_slot(y); } } static void just_mark(s7_pointer p) { set_mark(p); } static void mark_c_proc_star(s7_pointer p) { set_mark(p); if (!has_simple_defaults(p)) { s7_pointer arg; for (arg = c_function_call_args(p); is_pair(arg); arg = cdr(arg)) S7_MARK(car(arg)); } } static void mark_pair(s7_pointer p) { s7_pointer x; set_mark(p); S7_MARK(car(p)); /* if the list is huge, recursion to cdr(p) is problematic when there are strict limits on the stack size * so I'll try something else... (This form is faster according to callgrind). * * in snd-14 or so through 15.3, sc->temp_cell_2|3 were used for trailing args in eval, but that meant * the !is_marked check below (which is intended to catch cyclic lists) caused cells to be missed; * since sc->args could contain permanently marked cells, if these were passed to g_vector, for example, and * make_vector_1 triggered a GC call, we needed to mark both the permanent (always marked) cell and its contents, * and continue through the rest of the list. But adding temp_cell_2|3 to sc->permanent_objects was not enough. * Now I've already forgotten the rest of the story, and it was just an hour ago! -- the upshot is that temp_cell_2|3 * are not now used as arg list members. */ for (x = cdr(p); is_pair(x) && (!is_marked(x)); x = cdr(x)) { set_mark(x); S7_MARK(car(x)); } S7_MARK(x); } static void mark_counter(s7_pointer p) { set_mark(p); S7_MARK(counter_result(p)); S7_MARK(counter_list(p)); S7_MARK(counter_let(p)); } static void mark_closure(s7_pointer p) { set_mark(p); S7_MARK(closure_args(p)); S7_MARK(closure_body(p)); mark_let(closure_let(p)); S7_MARK(closure_setter(p)); } static void mark_stack_1(s7_pointer p, s7_int top) { s7_pointer *tp, *tend; set_mark(p); tp = (s7_pointer *)(vector_elements(p)); if (!tp) return; tend = (s7_pointer *)(tp + top); while (tp < tend) { S7_MARK(*tp++); S7_MARK(*tp++); S7_MARK(*tp++); tp++; } } static void mark_stack(s7_pointer p) { /* we can have a bare stack awaiting a continuation to hold it if the new_cell for the continuation * triggers the GC! But we need a top-of-stack?? */ mark_stack_1(p, temp_stack_top(p)); } static void mark_continuation(s7_pointer p) { unsigned int i; set_mark(p); mark_stack_1(continuation_stack(p), continuation_stack_top(p)); for (i = 0; i < continuation_op_loc(p); i++) S7_MARK(continuation_op_stack(p)[i]); } static void mark_vector(s7_pointer p) { mark_vector_1(p, vector_length(p)); } static void mark_vector_possibly_shared(s7_pointer p) { /* If a subvector (an inner dimension) of a vector is the only remaining reference * to the main vector, we want to make sure the main vector is not GC'd until * the subvector is also GC-able. The shared_vector field either points to the * parent vector, or it is sc->F, so we need to check for a vector parent if * the current is multidimensional (this will include 1-dim slices). We need * to keep the parent case separate (i.e. sc->F means the current is the original) * so that we only free once (or remove_from_heap once). * * If we have a shared-vector of a shared-vector, and the middle and original are not otherwise * in use, we mark the middle one, but (since it itself is not in use anywhere else) * we don't mark the original! So we need to follow the share-vector chain marking every one. */ if ((vector_has_dimensional_info(p)) && (s7_is_vector(shared_vector(p)))) mark_vector_possibly_shared(shared_vector(p)); mark_vector_1(p, vector_length(p)); } static void mark_int_or_float_vector(s7_pointer p) { set_mark(p); } static void mark_int_or_float_vector_possibly_shared(s7_pointer p) { if ((vector_has_dimensional_info(p)) && (s7_is_vector(shared_vector(p)))) mark_int_or_float_vector_possibly_shared(shared_vector(p)); set_mark(p); } static void mark_c_object(s7_pointer p) { set_mark(p); (*(c_object_mark(p)))(c_object_value(p)); } static void mark_catch(s7_pointer p) { set_mark(p); S7_MARK(catch_tag(p)); S7_MARK(catch_handler(p)); } static void mark_dynamic_wind(s7_pointer p) { set_mark(p); S7_MARK(dynamic_wind_in(p)); S7_MARK(dynamic_wind_out(p)); S7_MARK(dynamic_wind_body(p)); } static void mark_hash_table(s7_pointer p) { set_mark(p); S7_MARK(hash_table_procedures(p)); if (hash_table_entries(p) > 0) { unsigned int i, len; hash_entry_t **entries; entries = hash_table_elements(p); len = hash_table_mask(p) + 1; for (i = 0; i < len; i++) { hash_entry_t *xp; for (xp = entries[i++]; xp; xp = xp->next) { S7_MARK(xp->key); S7_MARK(xp->value); } for (xp = entries[i]; xp; xp = xp->next) { S7_MARK(xp->key); S7_MARK(xp->value); } } } } static void mark_iterator(s7_pointer p) { set_mark(p); S7_MARK(iterator_sequence(p)); if (is_mark_seq(p)) S7_MARK(iterator_current(p)); } static void mark_input_port(s7_pointer p) { set_mark(p); set_mark(port_original_input_string(p)); } static void gf_mark(s7_scheme *sc) { gc_obj *p; if (sc->cur_rf) for (p = sc->cur_rf->gc_list; p; p = p->nxt) S7_MARK(p->p); } static void init_mark_functions(void) { mark_function[T_FREE] = mark_noop; mark_function[T_UNIQUE] = mark_noop; mark_function[T_UNSPECIFIED] = mark_noop; mark_function[T_NIL] = mark_noop; mark_function[T_BOOLEAN] = mark_noop; mark_function[T_STRING] = just_mark; mark_function[T_INTEGER] = just_mark; mark_function[T_RATIO] = just_mark; mark_function[T_REAL] = just_mark; mark_function[T_COMPLEX] = just_mark; mark_function[T_BIG_INTEGER] = just_mark; mark_function[T_BIG_RATIO] = just_mark; mark_function[T_BIG_REAL] = just_mark; mark_function[T_BIG_COMPLEX] = just_mark; mark_function[T_SYMBOL] = mark_noop; /* this changes to mark_symbol when gensyms are in the heap */ mark_function[T_PAIR] = mark_pair; mark_function[T_CLOSURE] = mark_closure; mark_function[T_CLOSURE_STAR] = mark_closure; mark_function[T_CONTINUATION] = mark_continuation; mark_function[T_CHARACTER] = mark_noop; mark_function[T_INPUT_PORT] = mark_input_port; mark_function[T_VECTOR] = mark_vector; /* this changes if shared vector created (similarly below) */ mark_function[T_INT_VECTOR] = mark_int_or_float_vector; mark_function[T_FLOAT_VECTOR] = mark_int_or_float_vector; mark_function[T_MACRO] = mark_closure; mark_function[T_BACRO] = mark_closure; mark_function[T_MACRO_STAR] = mark_closure; mark_function[T_BACRO_STAR] = mark_closure; mark_function[T_C_OBJECT] = mark_c_object; mark_function[T_RANDOM_STATE] = just_mark; mark_function[T_GOTO] = just_mark; mark_function[T_OUTPUT_PORT] = just_mark; mark_function[T_CATCH] = mark_catch; mark_function[T_DYNAMIC_WIND] = mark_dynamic_wind; mark_function[T_HASH_TABLE] = mark_hash_table; mark_function[T_ITERATOR] = mark_iterator; mark_function[T_SYNTAX] = mark_noop; mark_function[T_LET] = mark_let; mark_function[T_STACK] = mark_stack; mark_function[T_COUNTER] = mark_counter; mark_function[T_SLOT] = mark_slot; mark_function[T_BAFFLE] = just_mark; mark_function[T_C_MACRO] = just_mark; mark_function[T_C_POINTER] = just_mark; mark_function[T_C_FUNCTION] = just_mark; mark_function[T_C_FUNCTION_STAR] = just_mark; /* changes to mark_c_proc_star if defaults involve an expression */ mark_function[T_C_ANY_ARGS_FUNCTION] = just_mark; mark_function[T_C_OPT_ARGS_FUNCTION] = just_mark; mark_function[T_C_RST_ARGS_FUNCTION] = just_mark; } static void mark_op_stack(s7_scheme *sc) { s7_pointer *p, *tp; tp = sc->op_stack_now; p = sc->op_stack; while (p < tp) S7_MARK(*p++); } static void mark_rootlet(s7_scheme *sc) { s7_pointer ge; s7_pointer *tmp, *top; ge = sc->rootlet; tmp = vector_elements(ge); top = (s7_pointer *)(tmp + sc->rootlet_entries); set_mark(ge); while (tmp < top) S7_MARK(slot_value(*tmp++)); } void s7_mark_object(s7_pointer p) { S7_MARK(p); } static void mark_permanent_objects(s7_scheme *sc) { gc_obj *g; for (g = sc->permanent_objects; g; g = (gc_obj *)(g->nxt)) S7_MARK(g->p); } static void unmark_permanent_objects(s7_scheme *sc) { gc_obj *g; for (g = sc->permanent_objects; g; g = (gc_obj *)(g->nxt)) clear_mark(g->p); } #ifndef _MSC_VER #include #include static struct timeval start_time; static struct timezone z0; #endif #if DEBUGGING static int last_gc_line = 0; static const char *last_gc_func = NULL; #endif #define GC_STATS 1 #define HEAP_STATS 2 #define STACK_STATS 4 #define show_gc_stats(Sc) ((Sc->gc_stats & GC_STATS) != 0) #define show_stack_stats(Sc) ((Sc->gc_stats & STACK_STATS) != 0) #define show_heap_stats(Sc) ((Sc->gc_stats & HEAP_STATS) != 0) static int gc(s7_scheme *sc) { s7_cell **old_free_heap_top; /* mark all live objects (the symbol table is in permanent memory, not the heap) */ #if DEBUGGING #define gc_call(P, Tp) \ p = (*tp++); \ if (is_marked(p)) \ clear_mark(p); \ else \ { \ if (!is_free_and_clear(p)) \ { \ p->debugger_bits = 0; p->gc_line = last_gc_line; p->gc_func = last_gc_func; \ clear_type(p); \ (*fp++) = p;\ }} #else #define gc_call(P, Tp) p = (*tp++); if (is_marked(p)) clear_mark(p); else {if (!is_free_and_clear(p)) {clear_type(p); (*fp++) = p;}} #endif if (show_gc_stats(sc)) { fprintf(stdout, "gc "); #if DEBUGGING fprintf(stdout, "line %s[%d] ", last_gc_func, last_gc_line); #endif #ifndef _MSC_VER /* this is apparently deprecated in favor of clock_gettime -- what compile-time switch to use here? * _POSIX_TIMERS, or perhaps use CLOCK_REALTIME, but clock_gettime requires -lrt -- no thanks. */ gettimeofday(&start_time, &z0); #endif } mark_rootlet(sc); S7_MARK(sc->args); mark_let(sc->envir); #if DEBUGGING check_types = false; #endif mark_let(sc->owlet); #if DEBUGGING check_types = true; #endif S7_MARK(sc->code); S7_MARK(sc->cur_code); mark_stack_1(sc->stack, s7_stack_top(sc)); S7_MARK(sc->v); S7_MARK(sc->w); S7_MARK(sc->x); S7_MARK(sc->y); S7_MARK(sc->z); S7_MARK(sc->value); S7_MARK(sc->temp1); S7_MARK(sc->temp2); S7_MARK(sc->temp3); S7_MARK(sc->temp4); S7_MARK(sc->temp5); S7_MARK(sc->temp6); S7_MARK(sc->temp7); S7_MARK(sc->temp8); S7_MARK(sc->temp9); S7_MARK(sc->temp10); gf_mark(sc); set_mark(sc->input_port); S7_MARK(sc->input_port_stack); set_mark(sc->output_port); set_mark(sc->error_port); S7_MARK(sc->stacktrace_defaults); S7_MARK(sc->autoload_table); S7_MARK(sc->default_rng); mark_pair(sc->temp_cell_1); mark_pair(sc->temp_cell_2); S7_MARK(car(sc->T1_1)); S7_MARK(car(sc->T2_1)); S7_MARK(car(sc->T2_2)); S7_MARK(car(sc->T3_1)); S7_MARK(car(sc->T3_2)); S7_MARK(car(sc->T3_3)); S7_MARK(car(sc->A4_1)); S7_MARK(car(sc->A4_2)); S7_MARK(car(sc->A4_3)); S7_MARK(car(sc->A4_4)); S7_MARK(car(sc->plist_1)); S7_MARK(car(sc->plist_2)); S7_MARK(cadr(sc->plist_2)); S7_MARK(car(sc->plist_3)); S7_MARK(cadr(sc->plist_3)); S7_MARK(caddr(sc->plist_3)); { unsigned int i; s7_pointer p; for (i = 1; i < NUM_SAFE_LISTS; i++) if (list_is_in_use(sc->safe_lists[i])) for (p = sc->safe_lists[i]; is_pair(p); p = cdr(p)) S7_MARK(car(p)); for (i = 0; i < sc->setters_loc; i++) S7_MARK(cdr(sc->setters[i])); } { int i; for (i = 0; i < sc->num_fdats; i++) if (sc->fdats[i]) S7_MARK(sc->fdats[i]->curly_arg); } S7_MARK(sc->protected_objects); S7_MARK(sc->protected_accessors); /* now protect recent allocations using the free_heap cells above the current free_heap_top (if any). * * cells above sc->free_heap_top might be malloc'd garbage (after heap reallocation), so we keep track of * where the last actually freed cells were after the previous GC call. We're trying to * GC protect the previous GC_TEMPS_SIZE allocated pointers so that the caller doesn't have * to gc-protect every temporary cell. * * There's one remaining possible problem. s7_remove_from_heap frees cells outside * the GC and might push free_heap_top beyond its previous_free_heap_top, then * an immediate explicit gc call might not see those temp cells. */ { s7_pointer *tmps, *tmps_top; tmps = sc->free_heap_top; tmps_top = tmps + GC_TEMPS_SIZE; if (tmps_top > sc->previous_free_heap_top) tmps_top = sc->previous_free_heap_top; while (tmps < tmps_top) S7_MARK(*tmps++); } mark_op_stack(sc); mark_permanent_objects(sc); /* free up all unmarked objects */ old_free_heap_top = sc->free_heap_top; { s7_pointer *fp, *tp, *heap_top; fp = sc->free_heap_top; tp = sc->heap; heap_top = (s7_pointer *)(sc->heap + sc->heap_size); while (tp < heap_top) /* != here or ^ makes no difference */ { s7_pointer p; /* from here down is gc_call, but I wanted one case explicit for readability */ p = (*tp++); if (is_marked(p)) /* this order is faster than checking typeflag(p) != T_FREE first */ clear_mark(p); else { if (!is_free_and_clear(p)) /* if T_FREE, it's an already-free object -- the free_heap is usually not empty when we call the GC */ { #if DEBUGGING p->debugger_bits = 0; #endif clear_type(p); /* (this is needed -- otherwise we try to free some objects twice) */ (*fp++) = p; } } /* this looks crazy, but it speeds up the entire GC process by 25%! * going from 16 to 32 saves .2% so it may not matter. */ gc_call(p, tp); gc_call(p, tp); gc_call(p, tp); gc_call(p, tp); gc_call(p, tp); gc_call(p, tp); gc_call(p, tp); gc_call(p, tp); gc_call(p, tp); gc_call(p, tp); gc_call(p, tp); gc_call(p, tp); gc_call(p, tp); gc_call(p, tp); gc_call(p, tp); gc_call(p, tp); gc_call(p, tp); gc_call(p, tp); gc_call(p, tp); gc_call(p, tp); gc_call(p, tp); gc_call(p, tp); gc_call(p, tp); gc_call(p, tp); gc_call(p, tp); gc_call(p, tp); gc_call(p, tp); gc_call(p, tp); gc_call(p, tp); gc_call(p, tp); gc_call(p, tp); } sc->free_heap_top = fp; sweep(sc); } unmark_permanent_objects(sc); sc->gc_freed = (int)(sc->free_heap_top - old_free_heap_top); if (show_gc_stats(sc)) { #ifndef _MSC_VER struct timeval t0; double secs; gettimeofday(&t0, &z0); secs = (t0.tv_sec - start_time.tv_sec) + 0.000001 * (t0.tv_usec - start_time.tv_usec); #if (PRINT_NAME_PADDING == 8) fprintf(stdout, "freed %d/%u (free: %d), time: %f\n", sc->gc_freed, sc->heap_size, sc->free_heap_top - sc->free_heap, secs); #else fprintf(stdout, "freed %d/%u (free: %ld), time: %f\n", sc->gc_freed, sc->heap_size, sc->free_heap_top - sc->free_heap, secs); #endif #else fprintf(stdout, "freed %d/%u\n", sc->gc_freed, sc->heap_size); #endif } /* if (sc->begin_hook) call_begin_hook(sc); */ sc->previous_free_heap_top = sc->free_heap_top; return(sc->gc_freed); /* needed by cell allocator to decide when to increase heap size */ } void s7_gc_stats(s7_scheme *sc, bool on) {sc->gc_stats = (on) ? GC_STATS : 0;} unsigned int s7_heap_size(s7_scheme *sc) {return(sc->heap_size);} int s7_gc_freed(s7_scheme *sc) {return(sc->gc_freed);} #define GC_TRIGGER_SIZE 64 /* new_cell has to include the new cell's type. In the free list, it is 0 (T_FREE). If we remove it here, * but then hit some error before setting the type, the GC sweep thinks it is a free cell already and * does not return it to the free list: a memory leak. */ #if (!DEBUGGING) #define new_cell(Sc, Obj, Type) \ do { \ if (Sc->free_heap_top <= Sc->free_heap_trigger) try_to_call_gc(Sc); \ Obj = (*(--(Sc->free_heap_top))); \ set_type(Obj, Type); \ } while (0) #define new_cell_no_check(Sc, Obj, Type) do {Obj = (*(--(Sc->free_heap_top))); set_type(Obj, Type);} while (0) /* since sc->free_heap_trigger is GC_TRIGGER_SIZE above the free heap base, we don't need * to check it repeatedly after the first such check. */ #else static bool for_any_other_reason(s7_scheme *sc, int line) { #if 0 static int ctr = 0; if ((sc->default_rng) && (!sc->gc_off) && (ctr > GC_TRIGGER_SIZE)) { s7_double x; x = next_random(sc->default_rng); if (x > .995) { ctr = 0; return(true); } } ctr++; #endif return(false); } #define new_cell(Sc, Obj, Type) \ do { \ if ((Sc->free_heap_top <= Sc->free_heap_trigger) || (for_any_other_reason(sc, __LINE__))) {last_gc_line = __LINE__; last_gc_func = __func__; try_to_call_gc(Sc);} \ Obj = (*(--(Sc->free_heap_top))); \ Obj->alloc_line = __LINE__; Obj->alloc_func = __func__; \ set_type(Obj, Type); \ } while (0) #define new_cell_no_check(Sc, Obj, Type) \ do { \ if ((Sc->free_heap_top + 16) < Sc->free_heap_trigger) fprintf(stderr, "[%d: cell %d] ", __LINE__, (int)(sc->free_heap_top - sc->free_heap)); \ Obj = (*(--(Sc->free_heap_top))); \ Obj->alloc_line = __LINE__; Obj->alloc_func = __func__; \ set_type(Obj, Type); \ } while (0) #endif static void resize_heap(s7_scheme *sc) { /* alloc more heap */ unsigned int old_size, old_free, k; s7_cell *cells; s7_pointer p; old_size = sc->heap_size; old_free = sc->free_heap_top - sc->free_heap; if (sc->heap_size < 512000) sc->heap_size *= 2; else sc->heap_size += 512000; sc->heap = (s7_cell **)realloc(sc->heap, sc->heap_size * sizeof(s7_cell *)); if (!(sc->heap)) s7_warn(sc, 256, "heap reallocation failed! tried to get %lu bytes\n", (unsigned long)(sc->heap_size * sizeof(s7_cell *))); sc->free_heap = (s7_cell **)realloc(sc->free_heap, sc->heap_size * sizeof(s7_cell *)); if (!(sc->free_heap)) s7_warn(sc, 256, "free heap reallocation failed! tried to get %lu bytes\n", (unsigned long)(sc->heap_size * sizeof(s7_cell *))); sc->free_heap_trigger = (s7_cell **)(sc->free_heap + GC_TRIGGER_SIZE); sc->free_heap_top = sc->free_heap + old_free; /* incremented below, added old_free 21-Aug-12?!? */ /* optimization suggested by K Matheussen */ cells = (s7_cell *)calloc(sc->heap_size - old_size, sizeof(s7_cell)); for (p = cells, k = old_size; k < sc->heap_size;) { sc->heap[k] = p; heap_location(p) = k++; (*sc->free_heap_top++) = p++; sc->heap[k] = p; heap_location(p) = k++; (*sc->free_heap_top++) = p++; sc->heap[k] = p; heap_location(p) = k++; (*sc->free_heap_top++) = p++; sc->heap[k] = p; heap_location(p) = k++; (*sc->free_heap_top++) = p++; } sc->previous_free_heap_top = sc->free_heap_top; if (show_heap_stats(sc)) fprintf(stderr, "heap grows to %u\n", sc->heap_size); } static void try_to_call_gc(s7_scheme *sc) { /* called only from new_cell and cons */ if (sc->gc_off) { /* we can't just return here! Someone needs a new cell, and once the heap free list is exhausted, segfault */ resize_heap(sc); } else { #if (!DEBUGGING) unsigned int freed_heap; freed_heap = gc(sc); if ((freed_heap < sc->heap_size / 2) && (freed_heap < 1000000)) /* if huge heap */ resize_heap(sc); #else gc(sc); if ((unsigned int)(sc->free_heap_top - sc->free_heap) < sc->heap_size / 2) resize_heap(sc); #endif } } /* originally I tried to mark each temporary value until I was done with it, but * that way madness lies... By delaying GC of _every_ %$^#%@ pointer, I can dispense * with hundreds of individual protections. So the free_heap's last GC_TEMPS_SIZE * allocated pointers are protected during the mark sweep. */ static s7_pointer g_gc(s7_scheme *sc, s7_pointer args) { #define H_gc "(gc (on #t)) runs the garbage collector. If 'on' is supplied, it turns the GC on or off. \ Evaluation produces a surprising amount of garbage, so don't leave the GC off for very long!" #define Q_gc s7_make_signature(sc, 2, sc->T, sc->IS_BOOLEAN) if (is_not_null(args)) { if (!s7_is_boolean(car(args))) method_or_bust(sc, car(args), sc->GC, args, T_BOOLEAN, 0); sc->gc_off = (car(args) == sc->F); if (sc->gc_off) return(sc->F); } gc(sc); return(sc->UNSPECIFIED); } s7_pointer s7_gc_on(s7_scheme *sc, bool on) { sc->gc_off = !on; return(s7_make_boolean(sc, on)); } static int permanent_cells = 0; #if (!WITH_THREADS) static s7_cell *alloc_pointer(void) { #define ALLOC_SIZE 256 static unsigned int alloc_k = ALLOC_SIZE; static s7_cell *alloc_cells = NULL; if (alloc_k == ALLOC_SIZE) /* if either no current block or the block is used up */ { /* make a new block */ permanent_cells += ALLOC_SIZE; alloc_cells = (s7_cell *)calloc(ALLOC_SIZE, sizeof(s7_cell)); alloc_k = 0; } return(&alloc_cells[alloc_k++]); } #else #define alloc_pointer() (s7_cell *)calloc(1, sizeof(s7_cell)) #endif static void add_permanent_object(s7_scheme *sc, s7_pointer obj) { gc_obj *g; g = (gc_obj *)malloc(sizeof(gc_obj)); g->p = obj; g->nxt = sc->permanent_objects; sc->permanent_objects = g; } static void free_cell(s7_scheme *sc, s7_pointer p) { #if DEBUGGING p->debugger_bits = 0; #endif clear_type(p); (*(sc->free_heap_top++)) = p; } static void s7_remove_from_heap(s7_scheme *sc, s7_pointer x) { int loc; s7_pointer p; /* global functions are very rarely redefined, so we can remove the function body from * the heap when it is defined. If redefined, we currently lose the memory held by the * old definition. (It is not trivial to recover this memory because it is allocated * in blocks, not by the pointer, I think, but s7_define is the point to try). * * There is at least one problem with this: if, for example, a function has * a quoted (constant) list, then uses list-set! to change an element of it, * then a GC happens, and the new element is GC'd because no one in the heap * points to it, then we call the function again, and it tries to access * that element. * * (define (bad-idea) * (let ((lst '(1 2 3))) * (let ((result (list-ref lst 1))) * (list-set! lst 1 (* 2.0 16.6)) * (gc) * result))) * * put that in a file, load it (to force removal), than call bad-idea a few times. * so... if (*s7* 'safety) is not 0, remove-from-heap is disabled. */ loc = heap_location(x); if (not_in_heap(x)) return; switch (type(x)) { case T_PAIR: unheap(x); p = alloc_pointer(); sc->heap[loc] = p; (*sc->free_heap_top++) = p; heap_location(p) = loc; #if 0 /* this code fixes the problem above, but at some cost (gc + mark_pair up by about 2% in the worst case (snd-test.scm)) */ if ((car(x) == sc->QUOTE) && (is_pair(cadr(x)))) { add_permanent_object(sc, cdr(x)); } else { s7_remove_from_heap(sc, car(x)); s7_remove_from_heap(sc, cdr(x)); } #else s7_remove_from_heap(sc, car(x)); s7_remove_from_heap(sc, cdr(x)); #endif return; case T_HASH_TABLE: case T_LET: case T_VECTOR: /* not int|float_vector or string because none of their elements are GC-able (so unheap below is ok) * but hash-table and let seem like they need protection? And let does happen via define-class. */ add_permanent_object(sc, x); return; case T_SYNTAX: return; case T_SYMBOL: if (is_gensym(x)) { unsigned int i; sc->heap[loc] = alloc_pointer(); free_cell(sc, sc->heap[loc]); heap_location(sc->heap[loc]) = loc; /* unheap(x); */ heap_location(x) = -heap_location(x); /* if gensym is a hash-table key, then is removed from the heap, we need to be sure the hash-table map to it * continues to be valid. symbol_hmap is abs(heap_location), and the possible overlap with other not-in-heap * ints is not problematic (they'll just hash to the same location). */ for (i = 0; i < sc->gensyms_loc; i++) if (sc->gensyms[i] == x) { unsigned int j; for (j = i + 1; i < sc->gensyms_loc; i++, j++) sc->gensyms[i] = sc->gensyms[j]; sc->gensyms_loc--; if (sc->gensyms_loc == 0) mark_function[T_SYMBOL] = mark_noop; break; } } return; case T_CLOSURE: case T_CLOSURE_STAR: case T_MACRO: case T_MACRO_STAR: case T_BACRO: case T_BACRO_STAR: unheap(x); p = alloc_pointer(); free_cell(sc, p); sc->heap[loc] = p; heap_location(p) = loc; s7_remove_from_heap(sc, closure_args(x)); s7_remove_from_heap(sc, closure_body(x)); return; default: break; } unheap(x); p = alloc_pointer(); free_cell(sc, p); sc->heap[loc] = p; heap_location(p) = loc; } /* -------------------------------- stacks -------------------------------- */ #define OP_STACK_INITIAL_SIZE 32 #if DEBUGGING #define stop_at_error true static void push_op_stack(s7_scheme *sc, s7_pointer op) { (*sc->op_stack_now++) = _NFre(op); if (sc->op_stack_now > (sc->op_stack + sc->op_stack_size)) { fprintf(stderr, "%sop_stack overflow%s\n", BOLD_TEXT, UNBOLD_TEXT); if (stop_at_error) abort(); } } static s7_pointer pop_op_stack(s7_scheme *sc) { s7_pointer op; op = (*(--(sc->op_stack_now))); if (sc->op_stack_now < sc->op_stack) { fprintf(stderr, "%sop_stack underflow%s\n", BOLD_TEXT, UNBOLD_TEXT); if (stop_at_error) abort(); } return(_NFre(op)); } #else #define push_op_stack(Sc, Op) (*Sc->op_stack_now++) = Op #define pop_op_stack(Sc) (*(--(Sc->op_stack_now))) #endif static void initialize_op_stack(s7_scheme *sc) { int i; sc->op_stack = (s7_pointer *)malloc(OP_STACK_INITIAL_SIZE * sizeof(s7_pointer)); sc->op_stack_size = OP_STACK_INITIAL_SIZE; sc->op_stack_now = sc->op_stack; sc->op_stack_end = (s7_pointer *)(sc->op_stack + sc->op_stack_size); for (i = 0; i < OP_STACK_INITIAL_SIZE; i++) sc->op_stack[i] = sc->NIL; } static void resize_op_stack(s7_scheme *sc) { int i, loc, new_size; loc = (int)(sc->op_stack_now - sc->op_stack); new_size = sc->op_stack_size * 2; sc->op_stack = (s7_pointer *)realloc((void *)(sc->op_stack), new_size * sizeof(s7_pointer)); for (i = sc->op_stack_size; i < new_size; i++) sc->op_stack[i] = sc->NIL; sc->op_stack_size = new_size; sc->op_stack_now = (s7_pointer *)(sc->op_stack + loc); sc->op_stack_end = (s7_pointer *)(sc->op_stack + sc->op_stack_size); } #define stack_code(Stack, Loc) vector_element(_TStk(Stack), Loc - 3) #define stack_let(Stack, Loc) vector_element(_TStk(Stack), Loc - 2) #define stack_args(Stack, Loc) vector_element(_TStk(Stack), Loc - 1) #define stack_op(Stack, Loc) ((opcode_t)(vector_element(_TStk(Stack), Loc))) #if DEBUGGING static void pop_stack(s7_scheme *sc) { sc->stack_end -= 4; if (sc->stack_end < sc->stack_start) { fprintf(stderr, "%sstack underflow%s\n", BOLD_TEXT, UNBOLD_TEXT); if (stop_at_error) abort(); } sc->code = sc->stack_end[0]; sc->envir = _TLid(sc->stack_end[1]); sc->args = sc->stack_end[2]; sc->op = (opcode_t)(sc->stack_end[3]); if (sc->op > OP_MAX_DEFINED) { fprintf(stderr, "%sinvalid opcode: " INT_FORMAT "%s\n", BOLD_TEXT, sc->op, UNBOLD_TEXT); if (stop_at_error) abort(); } } static void pop_stack_no_op(s7_scheme *sc) { sc->stack_end -= 4; if (sc->stack_end < sc->stack_start) { fprintf(stderr, "%sstack underflow%s\n", BOLD_TEXT, UNBOLD_TEXT); if (stop_at_error) abort(); } sc->code = sc->stack_end[0]; sc->envir = _TLid(sc->stack_end[1]); sc->args = sc->stack_end[2]; } static void push_stack(s7_scheme *sc, opcode_t op, s7_pointer args, s7_pointer code) { if (sc->stack_end >= sc->stack_start + sc->stack_size) { fprintf(stderr, "%sstack overflow%s\n", BOLD_TEXT, UNBOLD_TEXT); if (stop_at_error) abort(); } if (code) sc->stack_end[0] = code; sc->stack_end[1] = _TLid(sc->envir); if (args) sc->stack_end[2] = args; sc->stack_end[3] = (s7_pointer)op; sc->stack_end += 4; } #define push_stack_no_code(Sc, Op, Args) push_stack(Sc, Op, Args, NULL) #define push_stack_no_args(Sc, Op, Code) push_stack(Sc, Op, NULL, Code) #else /* these macros are faster than the equivalent simple function calls. If the s7_scheme struct is set up to reflect the * stack order [code envir args op], we can use memcpy here: * #define pop_stack(Sc) do {Sc->stack_end -= 4; memcpy((void *)Sc, (void *)(Sc->stack_end), 4 * sizeof(s7_pointer));} while (0) * but it is only slightly faster (.2% at best)! */ #define pop_stack(Sc) \ do { \ Sc->stack_end -= 4; \ Sc->code = Sc->stack_end[0]; \ Sc->envir = Sc->stack_end[1]; \ Sc->args = Sc->stack_end[2]; \ Sc->op = (opcode_t)(Sc->stack_end[3]); \ } while (0) #define pop_stack_no_op(Sc) \ do { \ Sc->stack_end -= 4; \ Sc->code = Sc->stack_end[0]; \ Sc->envir = Sc->stack_end[1]; \ Sc->args = Sc->stack_end[2]; \ } while (0) #define push_stack(Sc, Op, Args, Code) \ do { \ Sc->stack_end[0] = Code; \ Sc->stack_end[1] = Sc->envir; \ Sc->stack_end[2] = Args; \ Sc->stack_end[3] = (s7_pointer)Op; \ Sc->stack_end += 4; \ } while (0) #define push_stack_no_code(Sc, Op, Args) \ do { \ Sc->stack_end[2] = Args; \ Sc->stack_end[3] = (s7_pointer)Op; \ Sc->stack_end += 4; \ } while (0) #define push_stack_no_args(Sc, Op, Code) \ do { \ Sc->stack_end[0] = Code; \ Sc->stack_end[1] = Sc->envir; \ Sc->stack_end[3] = (s7_pointer)Op; \ Sc->stack_end += 4; \ } while (0) #endif /* since we don't GC mark the stack past the stack_top, push_stack_no_args and friends can cause pop_stack to set * sc->code and sc->args to currently free objects. */ #define main_stack_op(Sc) ((opcode_t)(Sc->stack_end[-1])) /* #define main_stack_args(Sc) (Sc->stack_end[-2]) */ /* #define main_stack_let(Sc) (Sc->stack_end[-3]) */ /* #define main_stack_code(Sc) (Sc->stack_end[-4]) */ /* #define pop_main_stack(Sc) Sc->stack_end -= 4 */ /* beware of main_stack_code! If a function has a tail-call, the main_stack_code that form sees * if main_stack_op==op-begin1 can change from call to call -- the begin actually refers * to the caller, which is dependent on where the current function was called, so we can't hard-wire * any optimizations based on that sequence. */ static void stack_reset(s7_scheme *sc) { sc->stack_end = sc->stack_start; push_stack(sc, OP_BARRIER, sc->NIL, sc->NIL); } static void resize_stack(s7_scheme *sc) { unsigned int i, new_size, loc; /* long long ints?? sc->stack_size also is an unsigned int */ loc = s7_stack_top(sc); new_size = sc->stack_size * 2; /* how can we trap infinite recursions? Is a warning in order here? * I think I'll add 'max-stack-size * size currently reaches 8192 in s7test */ if (new_size > sc->max_stack_size) s7_error(sc, s7_make_symbol(sc, "stack-too-big"), set_elist_1(sc, make_string_wrapper(sc, "stack has grown past (*s7* 'max-stack-size)"))); vector_elements(sc->stack) = (s7_pointer *)realloc(vector_elements(sc->stack), new_size * sizeof(s7_pointer)); if (vector_elements(sc->stack) == NULL) s7_error(sc, s7_make_symbol(sc, "stack-too-big"), set_elist_1(sc, make_string_wrapper(sc, "no room to expand stack?"))); for (i = sc->stack_size; i < new_size; i++) vector_element(sc->stack, i) = sc->NIL; vector_length(sc->stack) = new_size; sc->stack_size = new_size; sc->stack_start = vector_elements(sc->stack); sc->stack_end = (s7_pointer *)(sc->stack_start + loc); sc->stack_resize_trigger = (s7_pointer *)(sc->stack_start + sc->stack_size / 2); if (show_stack_stats(sc)) fprintf(stderr, "stack grows to %u\n", new_size); } #define check_stack_size(Sc) \ if (Sc->stack_end >= Sc->stack_resize_trigger) \ { \ if ((Sc->begin_hook) && (call_begin_hook(Sc))) return(Sc->F); \ resize_stack(Sc); \ } /* -------------------------------- symbols -------------------------------- */ static unsigned long long int raw_string_hash(const unsigned char *key, unsigned int len) { unsigned long long int x; unsigned char *cx = (unsigned char *)&x; x = 0; if (len <= 8) memcpy((void *)cx, (void *)key, len); else { unsigned long long int y; unsigned char *cy = (unsigned char *)&y; memcpy((void *)cx, (void *)key, 8); y = 0; len -= 8; memcpy((void *)cy, (void *)(key + 8), (len > 8) ? 8 : len); x |= y; } return(x); } static s7_pointer make_symbol_with_length(s7_scheme *sc, const char *name, unsigned int len); static s7_pointer new_symbol(s7_scheme *sc, const char *name, unsigned int len, unsigned long long int hash, unsigned int location) { s7_pointer x, str, p; unsigned char *base, *val; if (sc->symbol_table_is_locked) return(s7_error(sc, sc->ERROR, sc->NIL)); base = (unsigned char *)malloc(sizeof(s7_cell) * 3 + len + 1); x = (s7_pointer)base; str = (s7_pointer)(base + sizeof(s7_cell)); p = (s7_pointer)(base + 2 * sizeof(s7_cell)); val = (unsigned char *)(base + 3 * sizeof(s7_cell)); memcpy((void *)val, (void *)name, len); val[len] = '\0'; unheap(str); typeflag(str) = T_STRING | T_IMMUTABLE; /* avoid debugging confusion involving set_type (also below) */ string_length(str) = len; string_value(str) = (char *)val; string_hash(str) = hash; string_needs_free(str) = false; unheap(x); typeflag(x) = T_SYMBOL; set_symbol_name_cell(x, str); global_slot(x) = sc->UNDEFINED; /* was sc->NIL; */ initial_slot(x) = sc->UNDEFINED; symbol_set_local(x, 0LL, sc->NIL); symbol_tag(x) = 0; if (symbol_name_length(x) > 1) /* not 0, otherwise : is a keyword */ { if (name[0] == ':') { typeflag(x) |= (T_IMMUTABLE | T_KEYWORD); keyword_symbol(x) = make_symbol_with_length(sc, (char *)(name + 1), len - 1); global_slot(x) = s7_make_slot(sc, sc->NIL, x, x); } else { char c; c = name[symbol_name_length(x) - 1]; if (c == ':') { char *kstr; unsigned int klen; klen = symbol_name_length(x) - 1; /* can't used tmpbuf_* here (or not safely I think) because name is already using tmpbuf */ kstr = (char *)malloc((klen + 1) * sizeof(char)); memcpy((void *)kstr, (void *)name, klen); kstr[klen] = 0; typeflag(x) |= (T_IMMUTABLE | T_KEYWORD); keyword_symbol(x) = make_symbol_with_length(sc, kstr, klen); global_slot(x) = s7_make_slot(sc, sc->NIL, x, x); free(kstr); } } } unheap(p); typeflag(p) = T_PAIR | T_IMMUTABLE; car(p) = x; cdr(p) = vector_element(sc->symbol_table, location); vector_element(sc->symbol_table, location) = p; pair_set_raw_hash(p, hash); pair_set_raw_len(p, len); pair_set_raw_name(p, string_value(str)); return(x); } static s7_pointer make_symbol_with_length(s7_scheme *sc, const char *name, unsigned int len) { s7_pointer x; unsigned long long int hash; unsigned int location; hash = raw_string_hash((const unsigned char *)name, len); location = hash % SYMBOL_TABLE_SIZE; if (len <= 8) { for (x = vector_element(sc->symbol_table, location); is_pair(x); x = cdr(x)) if ((hash == pair_raw_hash(x)) && (len == pair_raw_len(x))) return(car(x)); } else { for (x = vector_element(sc->symbol_table, location); is_pair(x); x = cdr(x)) if ((hash == pair_raw_hash(x)) && (len == pair_raw_len(x)) && (strings_are_equal_with_length(name, pair_raw_name(x), len))) /* length here because name might not be null-terminated */ return(car(x)); } return(new_symbol(sc, name, len, hash, location)); } static s7_pointer make_symbol(s7_scheme *sc, const char *name) { return(make_symbol_with_length(sc, name, safe_strlen(name))); } s7_pointer s7_make_symbol(s7_scheme *sc, const char *name) { if (!name) return(sc->F); return(make_symbol_with_length(sc, name, safe_strlen(name))); } static s7_pointer symbol_table_find_by_name(s7_scheme *sc, const char *name, unsigned long long int hash, unsigned int location) { s7_pointer x; for (x = vector_element(sc->symbol_table, location); is_not_null(x); x = cdr(x)) if ((hash == pair_raw_hash(x)) && (strings_are_equal(name, pair_raw_name(x)))) return(car(x)); return(sc->NIL); } s7_pointer s7_symbol_table_find_name(s7_scheme *sc, const char *name) { unsigned long long int hash; unsigned int location; s7_pointer result; hash = raw_string_hash((const unsigned char *)name, safe_strlen(name)); location = hash % SYMBOL_TABLE_SIZE; result = symbol_table_find_by_name(sc, name, hash, location); if (is_null(result)) return(NULL); return(result); } #define FILLED true #define NOT_FILLED false static s7_pointer g_symbol_table(s7_scheme *sc, s7_pointer args) { #define H_symbol_table "(symbol-table) returns a vector containing the current symbol-table symbols" #define Q_symbol_table s7_make_signature(sc, 1, sc->IS_VECTOR) s7_pointer lst, x; s7_pointer *els; int i, j, syms = 0; /* this can't be optimized by returning the actual symbol-table (a vector of lists), because * gensyms can cause the table's lists and symbols to change at any time. This wreaks havoc * on traversals like for-each. So, symbol-table returns a snap-shot of the table contents * at the time it is called, and we call gc before making the list. I suppose the next step * is to check that we have room, and increase the heap here if necessary! * * (define (for-each-symbol func num) (for-each (lambda (sym) (if (> num 0) (for-each-symbol func (- num 1)) (func sym))) (symbol-table))) * (for-each-symbol (lambda (sym) (gensym) 1)) */ for (i = 0; i < vector_length(sc->symbol_table); i++) for (x = vector_element(sc->symbol_table, i); is_not_null(x); x = cdr(x)) syms++; sc->w = make_vector_1(sc, syms, NOT_FILLED, T_VECTOR); els = vector_elements(sc->w); for (i = 0, j = 0; i < vector_length(sc->symbol_table); i++) for (x = vector_element(sc->symbol_table, i); is_not_null(x); x = cdr(x)) els[j++] = car(x); lst = sc->w; sc->w = sc->NIL; return(lst); } bool s7_for_each_symbol_name(s7_scheme *sc, bool (*symbol_func)(const char *symbol_name, void *data), void *data) { /* this includes the special constants # and so on for simplicity -- are there any others? */ int i; s7_pointer x; for (i = 0; i < vector_length(sc->symbol_table); i++) for (x = vector_element(sc->symbol_table, i); is_not_null(x); x = cdr(x)) if (symbol_func(symbol_name(car(x)), data)) return(true); return((symbol_func("#t", data)) || (symbol_func("#f", data)) || (symbol_func("#", data)) || (symbol_func("#", data)) || (symbol_func("#", data)) || (symbol_func("#true", data)) || (symbol_func("#false", data))); } bool s7_for_each_symbol(s7_scheme *sc, bool (*symbol_func)(const char *symbol_name, s7_pointer value, void *data), void *data) { int i; s7_pointer x; for (i = 0; i < vector_length(sc->symbol_table); i++) for (x = vector_element(sc->symbol_table, i); is_not_null(x); x = cdr(x)) if (symbol_func(symbol_name(car(x)), cdr(x), data)) return(true); return(false); } static void remove_gensym_from_symbol_table(s7_scheme *sc, s7_pointer sym) { /* sym is a free cell at this point (we're called after the GC), but the name_cell is still intact */ s7_pointer x, name; unsigned int location; name = symbol_name_cell(sym); location = string_hash(name) % SYMBOL_TABLE_SIZE; x = vector_element(sc->symbol_table, location); if (car(x) == sym) { vector_element(sc->symbol_table, location) = cdr(x); free(x); } else { s7_pointer y; for (y = x, x = cdr(x); is_pair(x); y = x, x = cdr(x)) { if (car(x) == sym) { cdr(y) = cdr(x); free(x); return; } } #if DEBUGGING fprintf(stderr, "could not remove %s?\n", string_value(name)); #endif } } s7_pointer s7_gensym(s7_scheme *sc, const char *prefix) { char *name; unsigned int len, location; unsigned long long int hash; s7_pointer x; len = safe_strlen(prefix) + 32; tmpbuf_malloc(name, len); /* there's no point in heroic efforts here to avoid name collisions -- the user can screw up no matter what we do */ len = snprintf(name, len, "{%s}-%d", prefix, sc->gensym_counter++); hash = raw_string_hash((const unsigned char *)name, len); location = hash % SYMBOL_TABLE_SIZE; x = new_symbol(sc, name, len, hash, location); /* not T_GENSYM -- might be called from outside */ tmpbuf_free(name, len); return(x); } static bool s7_is_gensym(s7_pointer g) {return((is_symbol(g)) && (is_gensym(g)));} static s7_pointer g_is_gensym(s7_scheme *sc, s7_pointer args) { #define H_is_gensym "(gensym? sym) returns #t if sym is a gensym" #define Q_is_gensym pl_bt check_boolean_method(sc, s7_is_gensym, sc->IS_GENSYM, args); } static char *pos_int_to_str(s7_int num, unsigned int *len, char endc) { #define INT_TO_STR_SIZE 32 static char itos[INT_TO_STR_SIZE]; char *p, *op; p = (char *)(itos + INT_TO_STR_SIZE - 1); op = p; *p-- = '\0'; if (endc != '\0') *p-- = endc; do {*p-- = "0123456789"[num % 10]; num /= 10;} while (num); (*len) = op - p; /* this includes the trailing #\null */ return((char *)(p + 1)); } static s7_pointer g_gensym(s7_scheme *sc, s7_pointer args) { #define H_gensym "(gensym (prefix \"gensym\")) returns a new, unused symbol" #define Q_gensym s7_make_signature(sc, 2, sc->IS_GENSYM, sc->IS_STRING) const char *prefix; char *name, *p; unsigned int len, plen, nlen, location; unsigned long long int hash; s7_pointer x, str, stc; /* get symbol name */ if (is_not_null(args)) { s7_pointer name; name = car(args); if (!is_string(name)) method_or_bust(sc, name, sc->GENSYM, args, T_STRING, 0); prefix = string_value(name); } else prefix = "gensym"; plen = safe_strlen(prefix); len = plen + 32; name = (char *)malloc(len * sizeof(char)); name[0] = '{'; if (plen > 0) memcpy((void *)(name + 1), prefix, plen); name[plen + 1] = '}'; name[plen + 2] = '-'; p = pos_int_to_str(sc->gensym_counter++, &len, '\0'); memcpy((void *)(name + plen + 3), (void *)p, len); nlen = len + plen + 2; hash = raw_string_hash((const unsigned char *)name, nlen); location = hash % SYMBOL_TABLE_SIZE; /* make-string for symbol name */ str = (s7_cell *)malloc(sizeof(s7_cell)); /* was calloc? */ unheap(str); #if DEBUGGING typeflag(str) = 0; #endif set_type(str, T_STRING | T_IMMUTABLE); string_length(str) = nlen; string_value(str) = name; string_needs_free(str) = false; string_hash(str) = hash; /* allocate the symbol in the heap so GC'd when inaccessible */ new_cell(sc, x, T_SYMBOL | T_GENSYM); set_symbol_name_cell(x, str); global_slot(x) = sc->UNDEFINED; initial_slot(x) = sc->UNDEFINED; symbol_set_local(x, 0LL, sc->NIL); /* place new symbol in symbol-table, but using calloc so we can easily free it (remove it from the table) in GC sweep */ stc = (s7_cell *)malloc(sizeof(s7_cell)); /* was calloc? */ #if DEBUGGING typeflag(stc) = 0; #endif unheap(stc); set_type(stc, T_PAIR | T_IMMUTABLE); car(stc) = x; cdr(stc) = vector_element(sc->symbol_table, location); vector_element(sc->symbol_table, location) = stc; pair_set_raw_hash(stc, hash); pair_set_raw_len(stc, string_length(str)); pair_set_raw_name(stc, string_value(str)); add_gensym(sc, x); return(x); } s7_pointer s7_name_to_value(s7_scheme *sc, const char *name) { return(s7_symbol_value(sc, make_symbol(sc, name))); } bool s7_is_symbol(s7_pointer p) { return(is_symbol(p)); } bool s7_is_syntax(s7_pointer p) { return(is_syntax(p)); } static s7_pointer g_is_symbol(s7_scheme *sc, s7_pointer args) { #define H_is_symbol "(symbol? obj) returns #t if obj is a symbol" #define Q_is_symbol pl_bt check_boolean_method(sc, is_symbol, sc->IS_SYMBOL, args); } const char *s7_symbol_name(s7_pointer p) { return(symbol_name(p)); } static s7_pointer g_symbol_to_string(s7_scheme *sc, s7_pointer args) { #define H_symbol_to_string "(symbol->string sym) returns the symbol sym converted to a string" #define Q_symbol_to_string s7_make_signature(sc, 2, sc->IS_STRING, sc->IS_SYMBOL) s7_pointer sym; sym = car(args); if (!is_symbol(sym)) method_or_bust(sc, sym, sc->SYMBOL_TO_STRING, args, T_SYMBOL, 0); /* s7_make_string uses strlen which stops at an embedded null */ return(s7_make_string_with_length(sc, symbol_name(sym), symbol_name_length(sym))); /* return a copy */ } static s7_pointer symbol_to_string_uncopied; static s7_pointer g_symbol_to_string_uncopied(s7_scheme *sc, s7_pointer args) { s7_pointer sym; sym = car(args); if (!is_symbol(sym)) method_or_bust(sc, sym, sc->SYMBOL_TO_STRING, args, T_SYMBOL, 0); return(symbol_name_cell(sym)); } static s7_pointer g_string_to_symbol_1(s7_scheme *sc, s7_pointer str, s7_pointer caller) { if (!is_string(str)) method_or_bust(sc, str, caller, list_1(sc, str), T_STRING, 0); if (string_length(str) == 0) return(simple_wrong_type_argument_with_type(sc, caller, str, make_string_wrapper(sc, "a non-null string"))); /* currently if the string has an embedded null, it marks the end of the new symbol name. */ return(make_symbol_with_length(sc, string_value(str), string_length(str))); } static s7_pointer g_string_to_symbol(s7_scheme *sc, s7_pointer args) { #define H_string_to_symbol "(string->symbol str) returns the string str converted to a symbol" #define Q_string_to_symbol s7_make_signature(sc, 2, sc->IS_SYMBOL, sc->IS_STRING) return(g_string_to_symbol_1(sc, car(args), sc->STRING_TO_SYMBOL)); } static s7_pointer g_symbol(s7_scheme *sc, s7_pointer args) { #define H_symbol "(symbol str) returns the string str converted to a symbol" #define Q_symbol s7_make_signature(sc, 2, sc->IS_SYMBOL, sc->IS_STRING) return(g_string_to_symbol_1(sc, car(args), sc->SYMBOL)); } static s7_pointer add_sym_to_list(s7_scheme *sc, s7_pointer sym) { symbol_tag(sym) = sc->syms_tag; return(sym); } #define clear_syms_in_list(Sc) Sc->syms_tag++ /* -------------------------------- environments -------------------------------- */ #define new_frame(Sc, Old_Env, New_Env) \ do { \ s7_pointer _x_; \ new_cell(Sc, _x_, T_LET); \ let_id(_x_) = ++sc->let_number; \ let_set_slots(_x_, Sc->NIL); \ set_outlet(_x_, Old_Env); \ New_Env = _x_; \ } while (0) static s7_pointer new_frame_in_env(s7_scheme *sc, s7_pointer old_env) { /* return(cons(sc, sc->NIL, old_env)); */ s7_pointer x; new_cell(sc, x, T_LET); let_id(x) = ++sc->let_number; let_set_slots(x, sc->NIL); set_outlet(x, old_env); return(x); } static s7_pointer make_simple_let(s7_scheme *sc) { s7_pointer frame; new_cell(sc, frame, T_LET); let_id(frame) = sc->let_number + 1; let_set_slots(frame, sc->NIL); set_outlet(frame, sc->envir); return(frame); } /* in all these macros, symbol_set_local should follow slot_set_value so that we can evaluate the * slot's value in its old state. */ #define add_slot(Frame, Symbol, Value) \ do { \ s7_pointer _slot_, _sym_, _val_; \ _sym_ = Symbol; _val_ = Value; \ new_cell_no_check(sc, _slot_, T_SLOT);\ slot_set_symbol(_slot_, _sym_); \ slot_set_value(_slot_, _val_); \ symbol_set_local(_sym_, let_id(Frame), _slot_); \ next_slot(_slot_) = let_slots(Frame); \ let_set_slots(Frame, _slot_); \ } while (0) #define add_slot_checked(Frame, Symbol, Value) \ do { \ s7_pointer _slot_, _sym_, _val_; \ _sym_ = Symbol; _val_ = Value; \ new_cell(sc, _slot_, T_SLOT); \ slot_set_symbol(_slot_, _sym_); \ slot_set_value(_slot_, _val_); \ symbol_set_local(_sym_, let_id(Frame), _slot_); \ next_slot(_slot_) = let_slots(Frame); \ let_set_slots(Frame, _slot_); \ } while (0) /* no set_local here -- presumably done earlier in check_* */ #define new_frame_with_slot(Sc, Old_Env, New_Env, Symbol, Value) \ do { \ s7_pointer _x_, _slot_, _sym_, _val_; \ _sym_ = Symbol; _val_ = Value; \ new_cell(Sc, _x_, T_LET); \ let_id(_x_) = ++sc->let_number; \ set_outlet(_x_, Old_Env); \ New_Env = _x_; \ new_cell_no_check(Sc, _slot_, T_SLOT); \ slot_set_symbol(_slot_, _sym_); \ slot_set_value(_slot_, _val_); \ symbol_set_local(_sym_, sc->let_number, _slot_); \ next_slot(_slot_) = sc->NIL; \ let_set_slots(_x_, _slot_); \ } while (0) #define new_frame_with_two_slots(Sc, Old_Env, New_Env, Symbol1, Value1, Symbol2, Value2) \ do { \ s7_pointer _x_, _slot_, _sym1_, _val1_, _sym2_, _val2_; \ _sym1_ = Symbol1; _val1_ = Value1; \ _sym2_ = Symbol2; _val2_ = Value2; \ new_cell(Sc, _x_, T_LET); \ let_id(_x_) = ++sc->let_number; \ set_outlet(_x_, Old_Env); \ New_Env = _x_; \ new_cell_no_check(Sc, _slot_, T_SLOT); \ slot_set_symbol(_slot_, _sym1_); \ slot_set_value(_slot_, _val1_); \ symbol_set_local(_sym1_, sc->let_number, _slot_); \ let_set_slots(_x_, _slot_); \ new_cell_no_check(Sc, _x_, T_SLOT); \ slot_set_symbol(_x_, _sym2_); \ slot_set_value(_x_, _val2_); \ symbol_set_local(_sym2_, sc->let_number, _x_); \ next_slot(_x_) = sc->NIL; \ next_slot(_slot_) = _x_; \ } while (0) static s7_pointer old_frame_in_env(s7_scheme *sc, s7_pointer frame, s7_pointer next_frame) { set_type(frame, T_LET); let_set_slots(frame, sc->NIL); set_outlet(frame, next_frame); let_id(frame) = ++sc->let_number; return(frame); } static s7_pointer old_frame_with_slot(s7_scheme *sc, s7_pointer env, s7_pointer val) { s7_pointer x, sym; unsigned long long int id; id = ++sc->let_number; let_id(env) = id; x = let_slots(env); slot_set_value(x, val); sym = slot_symbol(x); symbol_set_local(sym, id, x); return(env); } static s7_pointer old_frame_with_two_slots(s7_scheme *sc, s7_pointer env, s7_pointer val1, s7_pointer val2) { s7_pointer x, sym; unsigned long long int id; id = ++sc->let_number; let_id(env) = id; x = let_slots(env); slot_set_value(x, val1); sym = slot_symbol(x); symbol_set_local(sym, id, x); x = next_slot(x); slot_set_value(x, val2); sym = slot_symbol(x); symbol_set_local(sym, id, x); return(env); } static s7_pointer old_frame_with_three_slots(s7_scheme *sc, s7_pointer env, s7_pointer val1, s7_pointer val2, s7_pointer val3) { s7_pointer x, sym; unsigned long long int id; id = ++sc->let_number; let_id(env) = id; x = let_slots(env); slot_set_value(x, val1); sym = slot_symbol(x); symbol_set_local(sym, id, x); x = next_slot(x); slot_set_value(x, val2); sym = slot_symbol(x); symbol_set_local(sym, id, x); x = next_slot(x); slot_set_value(x, val3); sym = slot_symbol(x); symbol_set_local(sym, id, x); return(env); } static s7_pointer permanent_slot(s7_pointer symbol, s7_pointer value) { s7_pointer x; x = alloc_pointer(); unheap(x); set_type(x, T_SLOT); slot_set_symbol(x, symbol); slot_set_value(x, value); return(x); } static s7_pointer find_let(s7_scheme *sc, s7_pointer obj) { if (is_let(obj)) return(obj); switch (type(obj)) { case T_LET: return(obj); case T_MACRO: case T_MACRO_STAR: case T_BACRO: case T_BACRO_STAR: case T_CLOSURE: case T_CLOSURE_STAR: return(closure_let(obj)); case T_C_OBJECT: return(c_object_let(obj)); } return(sc->NIL); } static s7_pointer free_let(s7_scheme *sc, s7_pointer e) { s7_pointer p; #if DEBUGGING for (p = let_slots(e); is_slot(p);) { s7_pointer n; n = next_slot(p); /* grab it before we free p, or the type check stuff will complain */ free_cell(sc, p); p = n; } #else for (p = let_slots(e); is_slot(p); p = next_slot(p)) free_cell(sc, p); #endif free_cell(sc, e); return(sc->NIL); } static s7_pointer find_method(s7_scheme *sc, s7_pointer env, s7_pointer symbol) { s7_pointer x; if (symbol_id(symbol) == 0) /* this means the symbol has never been used locally, so how can it be a method? */ return(sc->UNDEFINED); /* I think the symbol_id is in sync with let_id, so the standard search should work */ if (let_id(env) == symbol_id(symbol)) return(slot_value(local_slot(symbol))); for (x = env; symbol_id(symbol) < let_id(x); x = outlet(x)); if (let_id(x) == symbol_id(symbol)) return(slot_value(local_slot(symbol))); for (; is_let(x); x = outlet(x)) { s7_pointer y; for (y = let_slots(x); is_slot(y); y = next_slot(y)) if (slot_symbol(y) == symbol) return(slot_value(y)); } return(sc->UNDEFINED); } static int let_length(s7_scheme *sc, s7_pointer e) { /* used by length, applicable_length, and some length optimizations */ int i; s7_pointer p; if (e == sc->rootlet) return(sc->rootlet_entries); if (has_methods(e)) { s7_pointer length_func; length_func = find_method(sc, e, sc->LENGTH); if (length_func != sc->UNDEFINED) { p = s7_apply_function(sc, length_func, list_1(sc, e)); if (s7_is_integer(p)) return((int)s7_integer(p)); return(-1); /* ?? */ } } for (i = 0, p = let_slots(e); is_slot(p); i++, p = next_slot(p)); return(i); } static s7_pointer make_slot_1(s7_scheme *sc, s7_pointer env, s7_pointer symbol, s7_pointer value) { /* env is not rootlet and is a let */ s7_pointer slot; new_cell(sc, slot, T_SLOT); slot_set_symbol(slot, symbol); slot_set_value(slot, value); next_slot(slot) = let_slots(env); let_set_slots(env, slot); set_local(symbol); /* this is called by varlet so we have to be careful about the resultant let_id * check for greater to ensure shadowing stays in effect, and equal to do updates (set! in effect) */ if (let_id(env) >= symbol_id(symbol)) symbol_set_local(symbol, let_id(env), slot); return(slot); } s7_pointer s7_make_slot(s7_scheme *sc, s7_pointer env, s7_pointer symbol, s7_pointer value) { if ((!is_let(env)) || (env == sc->rootlet)) { s7_pointer ge, slot; if ((sc->safety == 0) && (has_closure_let(value))) { s7_remove_from_heap(sc, closure_args(value)); s7_remove_from_heap(sc, closure_body(value)); } /* first look for existing slot -- this is not always checked before calling s7_make_slot */ if (is_slot(global_slot(symbol))) { slot = global_slot(symbol); slot_set_value(slot, value); return(slot); } ge = sc->rootlet; slot = permanent_slot(symbol, value); vector_element(ge, sc->rootlet_entries++) = slot; if (sc->rootlet_entries >= vector_length(ge)) { int i; vector_length(ge) *= 2; vector_elements(ge) = (s7_pointer *)realloc(vector_elements(ge), vector_length(ge) * sizeof(s7_pointer)); for (i = sc->rootlet_entries; i < vector_length(ge); i++) vector_element(ge, i) = sc->NIL; } global_slot(symbol) = slot; if (symbol_id(symbol) == 0) /* never defined locally? */ { if (initial_slot(symbol) == sc->UNDEFINED) initial_slot(symbol) = permanent_slot(symbol, value); local_slot(symbol) = slot; set_global(symbol); } if (is_gensym(symbol)) s7_remove_from_heap(sc, symbol); return(slot); } return(make_slot_1(sc, env, symbol, value)); /* there are about the same number of frames as local variables -- this * strikes me as surprising, but it holds up across a lot of code. */ } static s7_pointer make_slot(s7_scheme *sc, s7_pointer variable, s7_pointer value) { /* this is for a do-loop optimization -- an unattached slot */ s7_pointer y; new_cell(sc, y, T_SLOT); slot_set_symbol(y, variable); if (!is_symbol(variable)) abort(); slot_set_value(y, value); return(y); } /* -------------------------------- let? -------------------------------- */ bool s7_is_let(s7_pointer e) { return(is_let(e)); } static s7_pointer g_is_let(s7_scheme *sc, s7_pointer args) { #define H_is_let "(let? obj) returns #t if obj is a let (an environment)." #define Q_is_let pl_bt check_boolean_method(sc, is_let, sc->IS_LET, args); } /* -------------------------------- unlet -------------------------------- */ #define UNLET_ENTRIES 400 static void save_unlet(s7_scheme *sc) { /* there are ca 374 predefined functions and whatnot */ int i, k = 0; s7_pointer x; s7_pointer *inits; sc->unlet = (s7_pointer)calloc(1, sizeof(s7_cell)); set_type(sc->unlet, T_VECTOR); vector_length(sc->unlet) = UNLET_ENTRIES; vector_elements(sc->unlet) = (s7_pointer *)malloc(UNLET_ENTRIES * sizeof(s7_pointer)); vector_getter(sc->unlet) = default_vector_getter; vector_setter(sc->unlet) = default_vector_setter; inits = vector_elements(sc->unlet); s7_vector_fill(sc, sc->unlet, sc->NIL); unheap(sc->unlet); for (i = 0; i < vector_length(sc->symbol_table); i++) for (x = vector_element(sc->symbol_table, i); is_not_null(x); x = cdr(x)) { s7_pointer sym; sym = car(x); if (is_slot(initial_slot(sym))) { s7_pointer val; val = slot_value(initial_slot(sym)); if ((is_procedure(val)) || (is_syntax(val))) inits[k++] = initial_slot(sym); /* (let ((begin +)) (with-let (unlet) (begin 1 2))) */ #if DEBUGGING if (k >= UNLET_ENTRIES) fprintf(stderr, "unlet overflow\n"); #endif } } } static s7_pointer g_unlet(s7_scheme *sc, s7_pointer args) { /* add sc->unlet bindings to the current environment */ #define H_unlet "(unlet) establishes the original bindings of all the predefined functions" #define Q_unlet s7_make_signature(sc, 1, sc->IS_LET) /* slightly confusing: * :((unlet) 'abs) * # * :(defined? 'abs (unlet)) * #t * this is because unlet sets up a local environment of unshadowed symbols, * and s7_let_ref below only looks at the local env chain (that is, if env is not * the global env, then the global env is not searched). * * Also (define hi 3) #_hi => 3, (set! hi 4), #_hi -> 3 but (with-let (unlet) hi) -> 4! */ int i; s7_pointer *inits; s7_pointer x; sc->w = new_frame_in_env(sc, sc->envir); inits = vector_elements(sc->unlet); for (i = 0; (i < UNLET_ENTRIES) && (is_slot(inits[i])); i++) { s7_pointer sym; x = slot_value(inits[i]); sym = slot_symbol(inits[i]); if (is_procedure(x)) { if (((!is_global(sym)) && /* it might be shadowed locally */ (s7_symbol_local_value(sc, sym, sc->envir) != slot_value(global_slot(sym)))) || (x != slot_value(global_slot(sym)))) /* it's not shadowed, but has been changed globally */ make_slot_1(sc, sc->w, sym, x); } else { if ((is_syntax(x)) && (local_slot(sym) != sc->NIL)) make_slot_1(sc, sc->w, sym, x); } } /* if (set! + -) then + needs to be overridden, but the local bit isn't set, * so we have to check the actual values in the non-local case. * (define (f x) (with-let (unlet) (+ x 1))) */ x = sc->w; sc->w = sc->NIL; return(x); } /* -------------------------------- openlet? -------------------------------- */ bool s7_is_openlet(s7_pointer e) { return(has_methods(e)); } static s7_pointer g_is_openlet(s7_scheme *sc, s7_pointer args) { #define H_is_openlet "(openlet? obj) returns #t is 'obj' has methods." #define Q_is_openlet pl_bt /* if car(args) is not a let (or possibly have one), should this raise an error? */ check_method(sc, car(args), sc->IS_OPENLET, args); return(make_boolean(sc, has_methods(car(args)))); } /* -------------------------------- openlet -------------------------------- */ s7_pointer s7_openlet(s7_scheme *sc, s7_pointer e) { set_has_methods(e); return(e); } static s7_pointer g_openlet(s7_scheme *sc, s7_pointer args) { #define H_openlet "(openlet e) tells the built-in generic functions that the environment 'e might have an over-riding method." #define Q_openlet pcl_t s7_pointer e; e = car(args); check_method(sc, e, sc->OPENLET, args); if (((is_let(e)) && (e != sc->rootlet)) || (has_closure_let(e)) || ((is_c_object(e)) && (c_object_let(e) != sc->NIL))) { set_has_methods(e); return(e); } return(simple_wrong_type_argument_with_type(sc, sc->OPENLET, e, A_LET)); } /* -------------------------------- coverlet -------------------------------- */ static s7_pointer c_coverlet(s7_scheme *sc, s7_pointer e) { sc->temp3 = e; check_method(sc, e, sc->COVERLET, list_1(sc, e)); if (((is_let(e)) && (e != sc->rootlet)) || (has_closure_let(e)) || ((is_c_object(e)) && (c_object_let(e) != sc->NIL))) { clear_has_methods(e); return(e); } return(simple_wrong_type_argument_with_type(sc, sc->COVERLET, e, A_LET)); } static s7_pointer g_coverlet(s7_scheme *sc, s7_pointer args) { #define H_coverlet "(coverlet e) undoes an earlier openlet." #define Q_coverlet pcl_t return(c_coverlet(sc, car(args))); } /* -------------------------------- varlet -------------------------------- */ static void append_let(s7_scheme *sc, s7_pointer new_e, s7_pointer old_e) { s7_pointer x; if (old_e == sc->rootlet) return; if (new_e != sc->rootlet) { for (x = let_slots(old_e); is_slot(x); x = next_slot(x)) make_slot_1(sc, new_e, slot_symbol(x), slot_value(x)); /* not add_slot here because we might run off the free heap end */ } else { for (x = let_slots(old_e); is_slot(x); x = next_slot(x)) { s7_pointer sym, val; sym = slot_symbol(x); val = slot_value(x); if (is_slot(global_slot(sym))) slot_set_value(global_slot(sym), val); else s7_make_slot(sc, new_e, sym, val); } } } static s7_pointer check_c_obj_env(s7_scheme *sc, s7_pointer old_e, s7_pointer caller) { if (is_c_object(old_e)) old_e = c_object_let(old_e); if (!is_let(old_e)) return(simple_wrong_type_argument_with_type(sc, caller, old_e, A_LET)); return(old_e); } static s7_pointer g_varlet(s7_scheme *sc, s7_pointer args) { #define H_varlet "(varlet env ...) adds its arguments (an environment, a cons: symbol . value, or a pair of arguments, the symbol and its value) \ to the environment env, and returns the environment." #define Q_varlet s7_make_circular_signature(sc, 2, 3, sc->IS_LET, sc->IS_LET, sc->T) s7_pointer x, e, sym, val, p; e = car(args); if (is_null(e)) e = sc->rootlet; else { check_method(sc, e, sc->VARLET, args); if (!is_let(e)) return(wrong_type_argument_with_type(sc, sc->VARLET, 1, e, A_LET)); } for (x = cdr(args); is_pair(x); x = cdr(x)) { p = car(x); switch (type(p)) { case T_SYMBOL: if (is_keyword(p)) sym = keyword_symbol(p); else sym = p; if (!is_pair(cdr(x))) return(wrong_type_argument_with_type(sc, sc->VARLET, position_of(x, args), p, A_BINDING)); x = cdr(x); val = car(x); break; case T_PAIR: sym = car(p); if (!is_symbol(sym)) return(wrong_type_argument_with_type(sc, sc->VARLET, position_of(x, args), p, A_SYMBOL)); val = cdr(p); break; case T_LET: append_let(sc, e, check_c_obj_env(sc, p, sc->VARLET)); continue; default: return(wrong_type_argument_with_type(sc, sc->VARLET, position_of(x, args), p, A_SYMBOL)); } if (is_immutable_symbol(sym)) return(wrong_type_argument_with_type(sc, sc->VARLET, position_of(x, args), sym, A_NON_CONSTANT_SYMBOL)); if (e == sc->rootlet) { if (is_slot(global_slot(sym))) { if (is_syntax(slot_value(global_slot(sym)))) return(wrong_type_argument_with_type(sc, sc->VARLET, position_of(x, args), p, make_string_wrapper(sc, "a non-syntactic keyword"))); /* without this check we can end up turning our code into gibberish: * :(set! quote 1) * ;can't set! quote * :(varlet (rootlet) '(quote . 1)) * :quote * 1 * or worse set quote to a function of one arg that tries to quote something -- infinite loop */ slot_set_value(global_slot(sym), val); } else s7_make_slot(sc, e, sym, val); } else make_slot_1(sc, e, sym, val); /* this used to check for sym already defined, and set its value, but that greatly slows down * the most common use (adding a slot), and makes it hard to shadow explicitly. Don't use * varlet as a substitute for set!/let-set!. */ } return(e); } /* -------------------------------- cutlet -------------------------------- */ static s7_pointer g_cutlet(s7_scheme *sc, s7_pointer args) { #define H_cutlet "(cutlet e symbol ...) removes symbols from the environment e." #define Q_cutlet s7_make_circular_signature(sc, 2, 3, sc->IS_LET, sc->IS_LET, sc->IS_SYMBOL) s7_pointer e, syms; #define THE_UN_ID ++sc->let_number e = car(args); if (is_null(e)) e = sc->rootlet; else { check_method(sc, e, sc->CUTLET, args); if (!is_let(e)) return(wrong_type_argument_with_type(sc, sc->CUTLET, 1, e, A_LET)); } /* besides removing the slot we have to make sure the symbol_id does not match else * let-ref and others will use the old slot! What's the un-id? Perhaps the next one? * (let ((b 1)) (let ((b 2)) (cutlet (curlet) 'b)) b) */ for (syms = cdr(args); is_pair(syms); syms = cdr(syms)) { s7_pointer sym, slot; sym = car(syms); if (!is_symbol(sym)) return(wrong_type_argument_with_type(sc, sc->CUTLET, position_of(syms, args), sym, A_SYMBOL)); if (e == sc->rootlet) { if (is_slot(global_slot(sym))) { symbol_set_id(sym, THE_UN_ID); slot_set_value(global_slot(sym), sc->UNDEFINED); } } else { slot = let_slots(e); if (is_slot(slot)) { if (slot_symbol(slot) == sym) { let_set_slots(e, next_slot(let_slots(e))); symbol_set_id(sym, THE_UN_ID); } else { s7_pointer last_slot; last_slot = slot; for (slot = next_slot(let_slots(e)); is_slot(slot); last_slot = slot, slot = next_slot(slot)) { if (slot_symbol(slot) == sym) { symbol_set_id(sym, THE_UN_ID); next_slot(last_slot) = next_slot(slot); break; } } } } } } return(e); } /* -------------------------------- sublet -------------------------------- */ static s7_pointer sublet_1(s7_scheme *sc, s7_pointer e, s7_pointer bindings, s7_pointer caller) { s7_pointer new_e; if (e == sc->rootlet) new_e = new_frame_in_env(sc, sc->NIL); else new_e = new_frame_in_env(sc, e); set_all_methods(new_e, e); if (!is_null(bindings)) { s7_pointer x; sc->temp3 = new_e; for (x = bindings; is_not_null(x); x = cdr(x)) { s7_pointer p, sym, val; p = car(x); switch (type(p)) { case T_SYMBOL: if (is_keyword(p)) sym = keyword_symbol(p); else sym = p; if (!is_pair(cdr(x))) return(wrong_type_argument_with_type(sc, caller, position_of(x, bindings), p, A_BINDING)); x = cdr(x); val = car(x); break; case T_PAIR: sym = car(p); if (!is_symbol(sym)) return(wrong_type_argument_with_type(sc, caller, position_of(x, bindings), p, A_SYMBOL)); val = cdr(p); break; case T_LET: append_let(sc, new_e, check_c_obj_env(sc, p, caller)); continue; default: return(wrong_type_argument_with_type(sc, caller, position_of(x, bindings), p, A_SYMBOL)); } if (is_immutable_symbol(sym)) return(wrong_type_argument_with_type(sc, caller, position_of(x, bindings), sym, A_NON_CONSTANT_SYMBOL)); /* here we know new_e is a let and is not rootlet */ make_slot_1(sc, new_e, sym, val); if (sym == sc->LET_REF_FALLBACK) set_has_ref_fallback(new_e); else { if (sym == sc->LET_SET_FALLBACK) set_has_set_fallback(new_e); } } sc->temp3 = sc->NIL; } return(new_e); } s7_pointer s7_sublet(s7_scheme *sc, s7_pointer e, s7_pointer bindings) { return(sublet_1(sc, e, bindings, sc->SUBLET)); } static s7_pointer g_sublet(s7_scheme *sc, s7_pointer args) { #define H_sublet "(sublet env ...) adds its \ arguments (each an environment or a cons: symbol . value) to the environment env, and returns the \ new environment." #define Q_sublet s7_make_circular_signature(sc, 2, 3, sc->IS_LET, s7_make_signature(sc, 2, sc->IS_LET, sc->IS_NULL), sc->T) s7_pointer e; e = car(args); if (is_null(e)) e = sc->rootlet; else { check_method(sc, e, sc->SUBLET, args); if (!is_let(e)) return(wrong_type_argument_with_type(sc, sc->SUBLET, 1, e, A_LET)); } return(sublet_1(sc, e, cdr(args), sc->SUBLET)); } /* -------------------------------- inlet -------------------------------- */ s7_pointer s7_inlet(s7_scheme *sc, s7_pointer args) { #define H_inlet "(inlet ...) adds its \ arguments, each an environment, a cons: '(symbol . value), or a keyword/value pair, to a new environment, and returns the \ new environment." #define Q_inlet s7_make_circular_signature(sc, 1, 2, sc->IS_LET, sc->T) return(sublet_1(sc, sc->rootlet, args, sc->INLET)); } #define g_inlet s7_inlet /* -------------------------------- let->list -------------------------------- */ s7_pointer s7_let_to_list(s7_scheme *sc, s7_pointer env) { s7_pointer x; sc->temp3 = sc->w; sc->w = sc->NIL; if (env == sc->rootlet) { unsigned int i, lim2; s7_pointer *entries; entries = vector_elements(env); lim2 = sc->rootlet_entries; if (lim2 & 1) lim2--; for (i = 0; i < lim2; ) { sc->w = cons_unchecked(sc, cons(sc, slot_symbol(entries[i]), slot_value(entries[i])), sc->w); i++; sc->w = cons_unchecked(sc, cons_unchecked(sc, slot_symbol(entries[i]), slot_value(entries[i])), sc->w); i++; } if (lim2 < sc->rootlet_entries) sc->w = cons_unchecked(sc, cons(sc, slot_symbol(entries[i]), slot_value(entries[i])), sc->w); } else { s7_pointer iter, func; /* need to check make-iterator method before dropping into let->list */ if ((has_methods(env)) && ((func = find_method(sc, env, sc->MAKE_ITERATOR)) != sc->UNDEFINED)) iter = s7_apply_function(sc, func, list_1(sc, env)); else iter = sc->NIL; if (is_null(iter)) { for (x = let_slots(env); is_slot(x); x = next_slot(x)) sc->w = cons_unchecked(sc, cons(sc, slot_symbol(x), slot_value(x)), sc->w); } else { /* (begin (load "mockery.scm") (let ((lt ((*mock-pair* 'mock-pair) 1 2 3))) (format *stderr* "~{~A ~}" lt))) */ while (true) { x = s7_iterate(sc, iter); if (iterator_is_at_end(iter)) break; sc->w = cons(sc, x, sc->w); } sc->w = safe_reverse_in_place(sc, sc->w); } } x = sc->w; sc->w = sc->temp3; sc->temp3 = sc->NIL; return(x); } #if (!WITH_PURE_S7) static s7_pointer g_let_to_list(s7_scheme *sc, s7_pointer args) { #define H_let_to_list "(let->list env) returns env's bindings as a list of cons's: '(symbol . value)." #define Q_let_to_list s7_make_signature(sc, 2, sc->IS_PAIR, sc->IS_LET) s7_pointer env; env = car(args); check_method(sc, env, sc->LET_TO_LIST, args); if (!is_let(env)) { if (is_c_object(env)) env = c_object_let(env); if (!is_let(env)) return(simple_wrong_type_argument_with_type(sc, sc->LET_TO_LIST, env, A_LET)); } return(s7_let_to_list(sc, env)); } #endif /* -------------------------------- let-ref -------------------------------- */ static s7_pointer let_ref_1(s7_scheme *sc, s7_pointer env, s7_pointer symbol) { s7_pointer x, y; /* (let ((a 1)) ((curlet) 'a)) * ((rootlet) 'abs) */ if (env == sc->rootlet) { y = global_slot(symbol); if (is_slot(y)) return(slot_value(y)); return(sc->UNDEFINED); } if (let_id(env) == symbol_id(symbol)) return(slot_value(local_slot(symbol))); /* this obviously has to follow the global-env check */ for (x = env; is_let(x); x = outlet(x)) for (y = let_slots(x); is_slot(y); y = next_slot(y)) if (slot_symbol(y) == symbol) return(slot_value(y)); /* now for a horrible kludge. If a let is a mock-hash-table (for example), implicit * indexing of the hash-table collides with the same thing for the let (field names * versus keys), and we can't just try again here because that makes it too easy to * get into infinite recursion. So, 'let-ref-fallback... */ if (has_ref_fallback(env)) check_method(sc, env, sc->LET_REF_FALLBACK, sc->w = list_2(sc, env, symbol)); return(sc->UNDEFINED); } s7_pointer s7_let_ref(s7_scheme *sc, s7_pointer env, s7_pointer symbol) { if (!is_let(env)) return(wrong_type_argument_with_type(sc, sc->LET_REF, 1, env, A_LET)); if (!is_symbol(symbol)) { check_method(sc, env, sc->LET_REF, sc->w = list_2(sc, env, symbol)); if (has_ref_fallback(env)) check_method(sc, env, sc->LET_REF_FALLBACK, sc->w = list_2(sc, env, symbol)); return(wrong_type_argument_with_type(sc, sc->LET_REF, 2, symbol, A_SYMBOL)); } return(let_ref_1(sc, env, symbol)); } static s7_pointer g_let_ref(s7_scheme *sc, s7_pointer args) { #define H_let_ref "(let-ref env sym) returns the value of the symbol sym in the environment env" #define Q_let_ref s7_make_signature(sc, 3, sc->T, sc->IS_LET, sc->IS_SYMBOL) s7_pointer e, s; e = car(args); if (!is_let(e)) return(wrong_type_argument_with_type(sc, sc->LET_REF, 1, e, A_LET)); s = cadr(args); if (!is_symbol(s)) { check_method(sc, e, sc->LET_REF, args); if (has_ref_fallback(e)) check_method(sc, e, sc->LET_REF_FALLBACK, args); return(wrong_type_argument_with_type(sc, sc->LET_REF, 2, s, A_SYMBOL)); } return(let_ref_1(sc, e, s)); } /* -------------------------------- let-set! -------------------------------- */ static s7_pointer call_accessor(s7_scheme *sc, s7_pointer slot, s7_pointer old_value) { s7_pointer func, new_value; new_value = sc->ERROR; func = slot_accessor(slot); if (is_procedure_or_macro(func)) { if (is_c_function(func)) { car(sc->T2_1) = slot_symbol(slot); car(sc->T2_2) = old_value; new_value = c_function_call(func)(sc, sc->T2_1); } else { bool old_off; old_off = sc->gc_off; sc->gc_off = true; new_value = s7_apply_function(sc, func, list_2(sc, slot_symbol(slot), old_value)); sc->gc_off = old_off; } } else return(old_value); if (new_value == sc->ERROR) return(s7_error(sc, sc->ERROR, set_elist_3(sc, make_string_wrapper(sc, "can't set! ~S to ~S"), slot_symbol(slot), old_value))); return(new_value); } static s7_pointer let_set_1(s7_scheme *sc, s7_pointer env, s7_pointer symbol, s7_pointer value) { s7_pointer x, y; if (env == sc->rootlet) { if (is_immutable_symbol(symbol)) /* (let-set! (rootlet) :key #f) */ return(wrong_type_argument_with_type(sc, sc->LET_SET, 2, symbol, A_NON_CONSTANT_SYMBOL)); y = global_slot(symbol); if (is_slot(y)) { if (slot_has_accessor(y)) slot_set_value(y, call_accessor(sc, y, value)); else slot_set_value(y, value); return(slot_value(y)); } return(sc->UNDEFINED); } for (x = env; is_let(x); x = outlet(x)) for (y = let_slots(x); is_slot(y); y = next_slot(y)) if (slot_symbol(y) == symbol) { if (slot_has_accessor(y)) slot_set_value(y, call_accessor(sc, y, value)); else slot_set_value(y, value); return(slot_value(y)); } if (has_set_fallback(env)) check_method(sc, env, sc->LET_SET_FALLBACK, sc->w = list_3(sc, env, symbol, value)); return(sc->UNDEFINED); } s7_pointer s7_let_set(s7_scheme *sc, s7_pointer env, s7_pointer symbol, s7_pointer value) { if (!is_let(env)) return(wrong_type_argument_with_type(sc, sc->LET_SET, 1, env, A_LET)); if (!is_symbol(symbol)) { check_method(sc, env, sc->LET_SET, sc->w = list_3(sc, env, symbol, value)); if (has_set_fallback(env)) check_method(sc, env, sc->LET_SET_FALLBACK, sc->w = list_3(sc, env, symbol, value)); return(wrong_type_argument_with_type(sc, sc->LET_SET, 2, symbol, A_SYMBOL)); } return(let_set_1(sc, env, symbol, value)); } static s7_pointer g_let_set(s7_scheme *sc, s7_pointer args) { /* (let ((a 1)) (set! ((curlet) 'a) 32) a) */ #define H_let_set "(let-set! env sym val) sets the symbol sym's value in the environment env to val" #define Q_let_set s7_make_signature(sc, 4, sc->T, sc->IS_LET, sc->IS_SYMBOL, sc->T) return(s7_let_set(sc, car(args), cadr(args), caddr(args))); } static s7_pointer reverse_slots(s7_scheme *sc, s7_pointer list) { s7_pointer p = list, result, q; result = sc->NIL; while (is_slot(p)) { q = next_slot(p); next_slot(p) = result; result = p; p = q; } return(result); } static s7_pointer let_copy(s7_scheme *sc, s7_pointer env) { if (is_let(env)) { s7_pointer new_e; if (env == sc->rootlet) /* (copy (rootlet)) or (copy (funclet abs)) etc */ return(sc->rootlet); /* we can't make copy handle environments-as-objects specially because the * make-object function in define-class uses copy to make a new object! * So if it is present, we get it here, and then there's almost surely trouble. */ new_e = new_frame_in_env(sc, outlet(env)); set_all_methods(new_e, env); sc->temp3 = new_e; if (is_slot(let_slots(env))) { s7_int id; s7_pointer x, y = NULL; id = let_id(new_e); for (x = let_slots(env); is_slot(x); x = next_slot(x)) { s7_pointer z; new_cell(sc, z, T_SLOT); slot_set_symbol(z, slot_symbol(x)); slot_set_value(z, slot_value(x)); if (symbol_id(slot_symbol(z)) != id) /* keep shadowing intact */ symbol_set_local(slot_symbol(x), id, z); if (is_slot(let_slots(new_e))) next_slot(y) = z; else let_set_slots(new_e, z); next_slot(z) = sc->NIL; /* in case GC runs during this loop */ y = z; } } /* We can't do a (normal) loop here then reverse the slots later because the symbol's local_slot has to * match the unshadowed slot, not the last in the list: * (let ((e1 (inlet 'a 1 'a 2))) (let ((e2 (copy e1))) (list (equal? e1 e2) (equal? (e1 'a) (e2 'a))))) */ sc->temp3 = sc->NIL; return(new_e); } return(sc->NIL); } /* -------------------------------- rootlet -------------------------------- */ static s7_pointer g_rootlet(s7_scheme *sc, s7_pointer ignore) { #define H_rootlet "(rootlet) returns the current top-level definitions (symbol bindings)." #define Q_rootlet s7_make_signature(sc, 1, sc->IS_LET) return(sc->rootlet); } /* as with the symbol-table, this function can lead to disaster -- user could * clobber the environment etc. But we want it to be editable and augmentable, * so I guess I'll leave it alone. (See curlet|funclet as well). */ s7_pointer s7_rootlet(s7_scheme *sc) { return(sc->rootlet); } s7_pointer s7_shadow_rootlet(s7_scheme *sc) { return(sc->shadow_rootlet); } s7_pointer s7_set_shadow_rootlet(s7_scheme *sc, s7_pointer let) { sc->shadow_rootlet = let; return(let); } /* -------------------------------- curlet -------------------------------- */ static s7_pointer g_curlet(s7_scheme *sc, s7_pointer args) { #define H_curlet "(curlet) returns the current definitions (symbol bindings)" #define Q_curlet s7_make_signature(sc, 1, sc->IS_LET) sc->capture_let_counter++; if (is_let(sc->envir)) return(sc->envir); return(sc->rootlet); } s7_pointer s7_curlet(s7_scheme *sc) { sc->capture_let_counter++; return(sc->envir); } s7_pointer s7_set_curlet(s7_scheme *sc, s7_pointer e) { s7_pointer p, old_e; old_e = sc->envir; sc->envir = e; if ((is_let(e)) && (let_id(e) > 0)) /* might be () [id=-1] or rootlet [id=0] etc */ { let_id(e) = ++sc->let_number; for (p = let_slots(e); is_slot(p); p = next_slot(p)) { s7_pointer sym; sym = slot_symbol(p); if (symbol_id(sym) != sc->let_number) symbol_set_local(sym, sc->let_number, p); } } return(old_e); } /* -------------------------------- outlet -------------------------------- */ s7_pointer s7_outlet(s7_scheme *sc, s7_pointer e) { return(outlet(e)); } static s7_pointer g_outlet(s7_scheme *sc, s7_pointer args) { #define H_outlet "(outlet env) is the environment that contains env." #define Q_outlet s7_make_signature(sc, 2, sc->IS_LET, sc->IS_LET) s7_pointer env; env = car(args); if (!is_let(env)) method_or_bust_with_type(sc, env, sc->OUTLET, args, A_LET, 0); if ((env == sc->rootlet) || (is_null(outlet(env)))) return(sc->rootlet); return(outlet(env)); } static s7_pointer g_set_outlet(s7_scheme *sc, s7_pointer args) { /* (let ((a 1)) (let ((b 2)) (set! (outlet (curlet)) (rootlet)) ((curlet) 'a))) */ s7_pointer env, new_outer; env = car(args); if (!is_let(env)) method_or_bust_with_type(sc, env, sc->OUTLET, args, A_LET, 0); new_outer = cadr(args); if (!is_let(new_outer)) return(wrong_type_argument_with_type(sc, sc->OUTLET, 2, new_outer, A_LET)); if (new_outer == sc->rootlet) new_outer = sc->NIL; if (env != sc->rootlet) set_outlet(env, new_outer); return(new_outer); } static s7_pointer find_symbol(s7_scheme *sc, s7_pointer symbol) { s7_pointer x; if (let_id(sc->envir) == symbol_id(symbol)) return(local_slot(symbol)); for (x = sc->envir; symbol_id(symbol) < let_id(x); x = outlet(x)); if (let_id(x) == symbol_id(symbol)) return(local_slot(symbol)); for (; is_let(x); x = outlet(x)) { s7_pointer y; for (y = let_slots(x); is_slot(y); y = next_slot(y)) if (slot_symbol(y) == symbol) return(y); } return(global_slot(symbol)); } static s7_pointer find_symbol_unchecked(s7_scheme *sc, s7_pointer symbol) /* find_symbol_checked includes the unbound_variable call */ { s7_pointer x; if (let_id(sc->envir) == symbol_id(symbol)) return(slot_value(local_slot(symbol))); for (x = sc->envir; symbol_id(symbol) < let_id(x); x = outlet(x)); /* this looks redundant, but every attempt to improve it is much slower! */ if (let_id(x) == symbol_id(symbol)) return(slot_value(local_slot(symbol))); for (; is_let(x); x = outlet(x)) { s7_pointer y; for (y = let_slots(x); is_slot(y); y = next_slot(y)) if (slot_symbol(y) == symbol) return(slot_value(y)); } x = global_slot(symbol); if (is_slot(x)) return(slot_value(x)); #if WITH_GCC return(NULL); #else return(unbound_variable(sc, symbol)); #endif } s7_pointer s7_slot(s7_scheme *sc, s7_pointer symbol) { return(find_symbol(sc, symbol)); } s7_pointer s7_slot_value(s7_pointer slot) { return(slot_value(slot)); } s7_pointer s7_slot_set_value(s7_scheme *sc, s7_pointer slot, s7_pointer value) { slot_set_value(slot, value); return(value); } void s7_slot_set_real_value(s7_scheme *sc, s7_pointer slot, s7_double value) { set_real(slot_value(slot), value); } s7_double s7_slot_real_value(s7_scheme *sc, s7_pointer slot, const char *caller) { return(real_to_double(sc, slot_value(slot), caller)); } s7_int s7_slot_integer_value(s7_pointer slot) { return(integer(slot_value(slot))); } static s7_pointer find_local_symbol(s7_scheme *sc, s7_pointer symbol, s7_pointer e) { if (!is_let(e)) return(global_slot(symbol)); if (symbol_id(symbol) != 0) { s7_pointer y; for (y = let_slots(e); is_slot(y); y = next_slot(y)) if (slot_symbol(y) == symbol) return(y); } return(sc->UNDEFINED); } static s7_pointer s7_local_slot(s7_scheme *sc, s7_pointer symbol) { s7_pointer y; for (y = let_slots(sc->envir); is_slot(y); y = next_slot(y)) if (slot_symbol(y) == symbol) return(y); return(NULL); } s7_pointer s7_symbol_value(s7_scheme *sc, s7_pointer sym) { s7_pointer x; x = find_symbol(sc, sym); if (is_slot(x)) return(slot_value(x)); return(sc->UNDEFINED); } s7_pointer s7_symbol_local_value(s7_scheme *sc, s7_pointer sym, s7_pointer local_env) { if (is_let(local_env)) { s7_pointer x; for (x = local_env; is_let(x); x = outlet(x)) { s7_pointer y; for (y = let_slots(x); is_slot(y); y = next_slot(y)) if (slot_symbol(y) == sym) return(slot_value(y)); } } return(s7_symbol_value(sc, sym)); } /* -------------------------------- symbol->value -------------------------------- */ #define find_global_symbol_checked(Sc, Sym) ((is_global(Sym)) ? slot_value(global_slot(Sym)) : find_symbol_checked(Sc, Sym)) static s7_pointer g_symbol_to_value(s7_scheme *sc, s7_pointer args) { #define H_symbol_to_value "(symbol->value sym (env (curlet))) returns the binding of (the value associated with) the \ symbol sym in the given environment: (let ((x 32)) (symbol->value 'x)) -> 32" #define Q_symbol_to_value s7_make_signature(sc, 3, sc->T, sc->IS_SYMBOL, sc->IS_LET) s7_pointer sym; sym = car(args); if (!is_symbol(sym)) method_or_bust(sc, sym, sc->SYMBOL_TO_VALUE, args, T_SYMBOL, 1); if (is_not_null(cdr(args))) { s7_pointer local_env; local_env = cadr(args); if (local_env == sc->UNLET) return((is_slot(initial_slot(sym))) ? slot_value(initial_slot(sym)) : sc->UNDEFINED); if (!is_let(local_env)) method_or_bust_with_type(sc, local_env, sc->SYMBOL_TO_VALUE, args, A_LET, 2); if (local_env == sc->rootlet) { s7_pointer x; x = global_slot(sym); if (is_slot(x)) return(slot_value(x)); return(sc->UNDEFINED); } return(s7_symbol_local_value(sc, sym, local_env)); } if (is_global(sym)) return(slot_value(global_slot(sym))); return(s7_symbol_value(sc, sym)); } s7_pointer s7_symbol_set_value(s7_scheme *sc, s7_pointer sym, s7_pointer val) { s7_pointer x; /* if immutable should this return an error? */ x = find_symbol(sc, sym); if (is_slot(x)) slot_set_value(x, val); return(val); } /* -------------------------------- symbol->dynamic-value -------------------------------- */ static s7_pointer find_dynamic_value(s7_scheme *sc, s7_pointer x, s7_pointer sym, long long int *id) { for (; symbol_id(sym) < let_id(x); x = outlet(x)); if (let_id(x) == symbol_id(sym)) { (*id) = let_id(x); return(slot_value(local_slot(sym))); } for (; (is_let(x)) && (let_id(x) > (*id)); x = outlet(x)) { s7_pointer y; for (y = let_slots(x); is_slot(y); y = next_slot(y)) if (slot_symbol(y) == sym) { (*id) = let_id(x); return(slot_value(y)); } } return(sc->GC_NIL); } static s7_pointer g_symbol_to_dynamic_value(s7_scheme *sc, s7_pointer args) { #define H_symbol_to_dynamic_value "(symbol->dynamic-value sym) returns the dynamic binding of the symbol sym" #define Q_symbol_to_dynamic_value s7_make_signature(sc, 2, sc->T, sc->IS_SYMBOL) s7_pointer sym, val; long long int top_id; int i; sym = car(args); if (!is_symbol(sym)) method_or_bust(sc, sym, sc->SYMBOL_TO_DYNAMIC_VALUE, args, T_SYMBOL, 1); if (is_global(sym)) return(slot_value(global_slot(sym))); if (let_id(sc->envir) == symbol_id(sym)) return(slot_value(local_slot(sym))); top_id = -1; val = find_dynamic_value(sc, sc->envir, sym, &top_id); if (top_id == symbol_id(sym)) return(val); for (i = s7_stack_top(sc) - 1; i > 0; i -= 4) { s7_pointer cur_val; cur_val = find_dynamic_value(sc, stack_let(sc->stack, i), sym, &top_id); if (cur_val != sc->GC_NIL) val = cur_val; if (top_id == symbol_id(sym)) return(val); } if (val == sc->GC_NIL) return(s7_symbol_value(sc, sym)); return(val); } typedef bool (safe_sym_t)(s7_scheme *sc, s7_pointer sym, s7_pointer e); static s7_function all_x_eval(s7_scheme *sc, s7_pointer arg, s7_pointer e, safe_sym_t *checker); static bool direct_memq(s7_pointer symbol, s7_pointer symbols) { s7_pointer x; for (x = symbols; is_pair(x); x = unchecked_cdr(x)) { if (car(x) == symbol) return(true); x = cdr(x); if (unchecked_car(x) == symbol) return(true); } return(false); } static bool indirect_memq(s7_pointer symbol, s7_pointer symbols) { /* used only below in do_symbol_is_safe */ s7_pointer x; for (x = symbols; is_pair(x); x = cdr(x)) if (caar(x) == symbol) return(true); return(false); } static bool do_symbol_is_safe(s7_scheme *sc, s7_pointer sym, s7_pointer e) { return((is_slot(global_slot(sym))) || (indirect_memq(sym, e)) || (is_slot(find_symbol(sc, sym)))); } static bool let_symbol_is_safe(s7_scheme *sc, s7_pointer sym, s7_pointer e) { return((is_slot(global_slot(sym))) || ((!is_with_let_let(e)) && (is_slot(find_symbol(sc, sym))))); } static bool pair_symbol_is_safe(s7_scheme *sc, s7_pointer sym, s7_pointer e) { return((is_slot(global_slot(sym))) || (direct_memq(sym, e))); } /* make macros and closures */ static s7_pointer make_macro(s7_scheme *sc) { s7_pointer cx, mac; unsigned int typ; if (sc->op == OP_DEFINE_MACRO) typ = T_MACRO | T_DONT_EVAL_ARGS | T_COPY_ARGS; else { if (sc->op == OP_DEFINE_MACRO_STAR) typ = T_MACRO_STAR | T_DONT_EVAL_ARGS | T_COPY_ARGS; else { if (sc->op == OP_DEFINE_BACRO) typ = T_BACRO | T_DONT_EVAL_ARGS | T_COPY_ARGS; else { if (sc->op == OP_DEFINE_BACRO_STAR) typ = T_BACRO_STAR | T_DONT_EVAL_ARGS | T_COPY_ARGS; else { if (sc->op == OP_DEFINE_EXPANSION) typ = T_MACRO | T_EXPANSION | T_DONT_EVAL_ARGS | T_COPY_ARGS; else typ = T_MACRO | T_DONT_EVAL_ARGS | T_COPY_ARGS; } } } } new_cell_no_check(sc, mac, typ); sc->temp6 = mac; closure_args(mac) = cdar(sc->code); closure_body(mac) = cdr(sc->code); closure_setter(mac) = sc->F; closure_set_let(mac, sc->envir); closure_arity(mac) = CLOSURE_ARITY_NOT_SET; sc->capture_let_counter++; sc->code = caar(sc->code); if (sc->op == OP_DEFINE_EXPANSION) set_type(sc->code, T_EXPANSION | T_SYMBOL); /* see comment under READ_TOK */ /* symbol? macro name has already been checked, find name in environment, and define it */ cx = find_local_symbol(sc, sc->code, sc->envir); if (is_slot(cx)) slot_set_value(cx, mac); else s7_make_slot(sc, sc->envir, sc->code, mac); /* was current but we've checked immutable already */ optimize(sc, closure_body(mac), 0, sc->NIL); sc->temp6 = sc->NIL; return(mac); } static s7_pointer make_closure(s7_scheme *sc, s7_pointer args, s7_pointer code, int type) { /* this is called every time a lambda form is evaluated, or during letrec, etc */ s7_pointer x; unsigned int typ; if (is_safe_closure(code)) { if (type == T_CLOSURE) typ = T_CLOSURE | T_PROCEDURE | T_SAFE_CLOSURE | T_COPY_ARGS; else typ = T_CLOSURE_STAR | T_PROCEDURE | T_SAFE_CLOSURE; } else { if (type == T_CLOSURE) typ = T_CLOSURE | T_PROCEDURE | T_COPY_ARGS; else typ = T_CLOSURE_STAR | T_PROCEDURE; } new_cell(sc, x, typ); closure_args(x) = args; closure_body(x) = code; closure_setter(x) = sc->F; if (is_null(args)) closure_arity(x) = 0; else closure_arity(x) = CLOSURE_ARITY_NOT_SET; closure_set_let(x, sc->envir); sc->capture_let_counter++; return(x); } #define make_closure_with_let(Sc, X, Args, Code, Env) \ do { \ unsigned int _T_; \ if (is_safe_closure(Code)) \ _T_ = T_CLOSURE | T_PROCEDURE | T_SAFE_CLOSURE | T_COPY_ARGS; \ else _T_ = T_CLOSURE | T_PROCEDURE | T_COPY_ARGS; \ new_cell(Sc, X, _T_); \ closure_args(X) = Args; \ closure_body(X) = Code; \ closure_setter(X) = sc->F; \ if (is_null(Args)) closure_arity(X) = 0; else closure_arity(X) = CLOSURE_ARITY_NOT_SET; \ closure_set_let(X, Env); \ sc->capture_let_counter++; \ } while (0) #define make_closure_without_capture(Sc, X, Args, Code, Env) \ do { \ unsigned int _T_; \ if (is_safe_closure(Code)) \ _T_ = T_CLOSURE | T_PROCEDURE | T_SAFE_CLOSURE | T_COPY_ARGS; \ else _T_ = T_CLOSURE | T_PROCEDURE | T_COPY_ARGS; \ new_cell(Sc, X, _T_); \ closure_args(X) = Args; \ closure_body(X) = Code; \ closure_setter(X) = sc->F; \ if (is_null(Args)) closure_arity(X) = 0; else closure_arity(X) = CLOSURE_ARITY_NOT_SET; \ closure_set_let(X, Env); \ } while (0) static int closure_length(s7_scheme *sc, s7_pointer e) { /* we can't use let_length(sc, closure_let(e)) because the closure_let(closure) * changes. So the open bit is not always on. Besides, the fallbacks need to be for closures, not environments. */ s7_pointer length_func; length_func = find_method(sc, closure_let(e), sc->LENGTH); if (length_func != sc->UNDEFINED) return((int)s7_integer(s7_apply_function(sc, length_func, list_1(sc, e)))); /* there are cases where this should raise a wrong-type-arg error, but for now... */ return(-1); } #define check_closure_for(Sc, Fnc, Sym) \ if ((has_closure_let(Fnc)) && (is_let(closure_let(Fnc)))) \ { \ s7_pointer val; \ val = find_local_symbol(Sc, Sym, closure_let(Fnc)); \ if ((!is_slot(val)) && (is_let(outlet(closure_let(Fnc))))) \ val = find_local_symbol(Sc, Sym, outlet(closure_let(Fnc))); \ if (is_slot(val)) \ return(slot_value(val)); \ } static s7_pointer copy_tree(s7_scheme *sc, s7_pointer tree) { #if WITH_GCC #define COPY_TREE(P) ({s7_pointer _p; _p = P; cons_unchecked(sc, (is_pair(car(_p))) ? copy_tree(sc, car(_p)) : car(_p), (is_pair(cdr(_p))) ? copy_tree(sc, cdr(_p)) : cdr(_p));}) #else #define COPY_TREE(P) copy_tree(sc, P) #endif return(cons_unchecked(sc, (is_pair(car(tree))) ? COPY_TREE(car(tree)) : car(tree), (is_pair(cdr(tree))) ? COPY_TREE(cdr(tree)) : cdr(tree))); } static void annotate_expansion(s7_pointer p) { if ((is_symbol(car(p))) && (is_pair(cdr(p)))) { set_opt_back(p); set_overlay(cdr(p)); } else { if (is_pair(car(p))) annotate_expansion(car(p)); } for (p = cdr(p); is_pair(p); p = cdr(p)) if (is_pair(car(p))) annotate_expansion(car(p)); } static s7_pointer copy_body(s7_scheme *sc, s7_pointer p) { if (8192 >= (sc->free_heap_top - sc->free_heap)) { gc(sc); while (8192 >= (sc->free_heap_top - sc->free_heap)) resize_heap(sc); } sc->w = copy_tree(sc, p); annotate_expansion(sc->w); p = sc->w; sc->w = sc->NIL; return(p); } static s7_pointer copy_closure(s7_scheme *sc, s7_pointer fnc) { /* copy the source tree annotating (for eventual optimization), return a thing of the same type as fnc */ s7_pointer x, body; body = closure_body(fnc); if (is_pair(body)) body = copy_body(sc, body); new_cell(sc, x, typeflag(fnc)); closure_args(x) = closure_args(fnc); closure_body(x) = body; closure_setter(x) = closure_setter(fnc); closure_arity(x) = closure_arity(fnc); closure_set_let(x, closure_let(fnc)); return(x); } /* -------------------------------- defined? -------------------------------- */ static s7_pointer g_is_defined(s7_scheme *sc, s7_pointer args) { #define H_is_defined "(defined? obj (env (curlet)) ignore-globals) returns #t if obj has a binding (a value) in the environment env" #define Q_is_defined s7_make_signature(sc, 4, sc->IS_BOOLEAN, sc->IS_SYMBOL, sc->IS_LET, sc->IS_BOOLEAN) s7_pointer sym; /* is this correct? * (defined? '_x) #f (symbol->value '_x) # * (define x #) (defined? 'x) #t */ sym = car(args); if (!is_symbol(sym)) method_or_bust(sc, sym, sc->IS_DEFINED, args, T_SYMBOL, 1); if (is_pair(cdr(args))) { s7_pointer e, b, x; e = cadr(args); if (!is_let(e)) return(wrong_type_argument_with_type(sc, sc->IS_DEFINED, 2, e, A_LET)); if (is_pair(cddr(args))) { b = caddr(args); if (!s7_is_boolean(b)) method_or_bust_with_type(sc, b, sc->IS_DEFINED, args, A_BOOLEAN, 3); } else b = sc->F; if (e == sc->rootlet) return(make_boolean(sc, is_slot(global_slot(sym)))); /* new_symbol and gensym initialize global_slot to # */ x = find_local_symbol(sc, sym, e); if (is_slot(x)) return(sc->T); if (b == sc->T) return(sc->F); /* here we can't fall back on find_symbol: * (let ((b 2)) * (let ((e (curlet))) * (let ((a 1)) * (if (defined? 'a e) * (format #t "a: ~A in ~{~A ~}" (symbol->value 'a e) e)))) * "a: 1 in (b . 2)" * * but we also can't just return #f: * (let ((b 2)) * (let ((e (curlet))) * (let ((a 1)) * (format #t "~A: ~A" (defined? 'abs e) (eval '(abs -1) e))))) * "#f: 1" */ return(make_boolean(sc, is_slot(global_slot(sym)))); } else { if (is_global(sym)) return(sc->T); } return(make_boolean(sc, is_slot(find_symbol(sc, sym)))); } bool s7_is_defined(s7_scheme *sc, const char *name) { s7_pointer x; x = s7_symbol_table_find_name(sc, name); if (x) { x = find_symbol(sc, x); return(is_slot(x)); } return(false); } void s7_define(s7_scheme *sc, s7_pointer envir, s7_pointer symbol, s7_pointer value) { s7_pointer x; if ((envir == sc->NIL) || (envir == sc->rootlet)) envir = sc->shadow_rootlet; x = find_local_symbol(sc, symbol, envir); if (is_slot(x)) slot_set_value(x, value); else { s7_make_slot(sc, envir, symbol, value); /* I think this means C code can override "constant" defs */ if ((envir == sc->shadow_rootlet) && (!is_slot(global_slot(symbol)))) { set_global(symbol); /* is_global => global_slot is usable */ global_slot(symbol) = local_slot(symbol); } } } s7_pointer s7_define_variable(s7_scheme *sc, const char *name, s7_pointer value) { s7_pointer sym; sym = make_symbol(sc, name); s7_define(sc, sc->NIL, sym, value); return(sym); } s7_pointer s7_define_variable_with_documentation(s7_scheme *sc, const char *name, s7_pointer value, const char *help) { s7_pointer sym; sym = s7_define_variable(sc, name, value); symbol_set_has_help(sym); symbol_help(sym) = copy_string(help); return(sym); } s7_pointer s7_define_constant(s7_scheme *sc, const char *name, s7_pointer value) { s7_pointer sym; sym = make_symbol(sc, name); s7_define(sc, sc->NIL, sym, value); set_immutable(sym); return(sym); } /* (define (func a) (let ((cvar (+ a 1))) cvar)) (define-constant cvar 23) (func 1) -> ;can't bind an immutable object: cvar * (let ((aaa 1)) (define-constant aaa 32) (set! aaa 3)) -> set!: can't alter immutable object: aaa */ s7_pointer s7_define_constant_with_documentation(s7_scheme *sc, const char *name, s7_pointer value, const char *help) { s7_pointer sym; sym = s7_define_constant(sc, name, value); symbol_set_has_help(sym); symbol_help(sym) = copy_string(help); return(value); } char *s7_symbol_documentation(s7_scheme *sc, s7_pointer sym) { if (is_keyword(sym)) return(NULL); if ((is_symbol(sym)) && (symbol_has_help(sym))) return(symbol_help(sym)); return(NULL); } char *s7_symbol_set_documentation(s7_scheme *sc, s7_pointer sym, const char *new_doc) { if (is_keyword(sym)) return(NULL); if ((is_symbol(sym)) && (symbol_has_help(sym)) && (symbol_help(sym))) free(symbol_help(sym)); symbol_set_has_help(sym); symbol_help(sym) = copy_string(new_doc); return(symbol_help(sym)); } /* -------------------------------- keyword? -------------------------------- */ bool s7_is_keyword(s7_pointer obj) { return(is_keyword(obj)); } static s7_pointer g_is_keyword(s7_scheme *sc, s7_pointer args) { #define H_is_keyword "(keyword? obj) returns #t if obj is a keyword, (keyword? :key) -> #t" #define Q_is_keyword pl_bt check_boolean_method(sc, is_keyword, sc->IS_KEYWORD, args); } /* -------------------------------- make-keyword -------------------------------- */ s7_pointer s7_make_keyword(s7_scheme *sc, const char *key) { s7_pointer sym; char *name; unsigned int slen; slen = safe_strlen(key); tmpbuf_malloc(name, slen + 2); name[0] = ':'; /* prepend ":" */ name[1] = '\0'; memcpy((void *)(name + 1), (void *)key, slen); sym = make_symbol_with_length(sc, name, slen + 1); /* keyword slot etc taken care of here (in new_symbol actually) */ tmpbuf_free(name, slen + 2); return(sym); } static s7_pointer g_make_keyword(s7_scheme *sc, s7_pointer args) { #define H_make_keyword "(make-keyword str) prepends ':' to str and defines that as a keyword" #define Q_make_keyword s7_make_signature(sc, 2, sc->IS_KEYWORD, sc->IS_STRING) if (!is_string(car(args))) method_or_bust(sc, car(args), sc->MAKE_KEYWORD, args, T_STRING, 0); return(s7_make_keyword(sc, string_value(car(args)))); } static s7_pointer c_make_keyword(s7_scheme *sc, s7_pointer x) { if (!is_string(x)) method_or_bust(sc, x, sc->MAKE_KEYWORD, list_1(sc, x), T_STRING, 0); return(s7_make_keyword(sc, string_value(x))); } /* -------------------------------- keyword->symbol -------------------------------- */ static s7_pointer g_keyword_to_symbol(s7_scheme *sc, s7_pointer args) { #define H_keyword_to_symbol "(keyword->symbol key) returns a symbol with the same name as key but no prepended colon" #define Q_keyword_to_symbol s7_make_signature(sc, 2, sc->IS_SYMBOL, sc->IS_KEYWORD) s7_pointer sym; sym = car(args); if (!is_keyword(sym)) method_or_bust_with_type(sc, sym, sc->KEYWORD_TO_SYMBOL, args, make_string_wrapper(sc, "a keyword"), 0); return(keyword_symbol(sym)); } static s7_pointer c_keyword_to_symbol(s7_scheme *sc, s7_pointer sym) { if (!is_keyword(sym)) method_or_bust_with_type(sc, sym, sc->KEYWORD_TO_SYMBOL, list_1(sc, sym), make_string_wrapper(sc, "a keyword"), 0); return(keyword_symbol(sym)); } /* -------------------------------- symbol->keyword -------------------------------- */ static s7_pointer g_symbol_to_keyword(s7_scheme *sc, s7_pointer args) { #define H_symbol_to_keyword "(symbol->keyword sym) returns a keyword with the same name as sym, but with a colon prepended" #define Q_symbol_to_keyword s7_make_signature(sc, 2, sc->IS_KEYWORD, sc->IS_SYMBOL) if (!is_symbol(car(args))) method_or_bust(sc, car(args), sc->SYMBOL_TO_KEYWORD, args, T_SYMBOL, 0); return(s7_make_keyword(sc, symbol_name(car(args)))); } static s7_pointer c_symbol_to_keyword(s7_scheme *sc, s7_pointer sym) { if (!is_symbol(sym)) method_or_bust(sc, sym, sc->SYMBOL_TO_KEYWORD, list_1(sc, sym), T_SYMBOL, 0); return(s7_make_keyword(sc, symbol_name(sym))); } /* ---------------- uninterpreted pointers ---------------- */ bool s7_is_c_pointer(s7_pointer arg) { return(type(arg) == T_C_POINTER); } void *s7_c_pointer(s7_pointer p) { if ((is_number(p)) && (s7_integer(p) == 0)) return(NULL); /* special case where the null pointer has been cons'd up by hand */ if (type(p) != T_C_POINTER) return(NULL); return(raw_pointer(p)); } s7_pointer s7_make_c_pointer(s7_scheme *sc, void *ptr) { s7_pointer x; new_cell(sc, x, T_C_POINTER); raw_pointer(x) = ptr; return(x); } static s7_pointer g_is_c_pointer(s7_scheme *sc, s7_pointer args) { #define H_is_c_pointer "(c-pointer? obj) returns #t if obj is a C pointer being held in s7." #define Q_is_c_pointer pl_bt check_boolean_method(sc, s7_is_c_pointer, sc->IS_C_POINTER, args); } static s7_pointer c_c_pointer(s7_scheme *sc, s7_pointer arg) { ptr_int p; if (!s7_is_integer(arg)) method_or_bust(sc, arg, sc->C_POINTER, list_1(sc, arg), T_INTEGER, 1); p = (ptr_int)s7_integer(arg); /* (c-pointer (bignum "1234")) */ return(s7_make_c_pointer(sc, (void *)p)); } static s7_pointer g_c_pointer(s7_scheme *sc, s7_pointer args) { #define H_c_pointer "(c-pointer int) returns a c-pointer object." #define Q_c_pointer s7_make_signature(sc, 2, sc->IS_C_POINTER, sc->IS_INTEGER) return(c_c_pointer(sc, car(args))); } /* --------------------------------- rf (CLM optimizer) ----------------------------------------------- */ s7_pointer *s7_xf_start(s7_scheme *sc) { sc->cur_rf->cur = sc->cur_rf->data; return(sc->cur_rf->cur); } static void resize_xf(s7_scheme *sc, xf_t *rc) { /* if we're saving pointers into this array (for later fill-in), this realloc * means earlier (backfill) pointers are not valid, so we have to save the position to be * filled, not the pointer to it. */ s7_int loc; loc = rc->cur - rc->data; #if DEBUGGING int i; s7_pointer *old; old = rc->data; rc->data = (s7_pointer *)calloc(rc->size * 2, sizeof(s7_pointer)); for (i = 0; i < rc->size; i++) { rc->data[i] = old[i]; old[i] = NULL; } #else rc->data = (s7_pointer *)realloc(rc->data, rc->size * 2 * sizeof(s7_pointer)); #endif rc->cur = (s7_pointer *)(rc->data + loc); rc->size *= 2; rc->end = (s7_pointer *)(rc->data + rc->size); } #define rc_loc(sc) (ptr_int)(sc->cur_rf->cur - sc->cur_rf->data) #define rc_go(sc, loc) (s7_pointer *)(sc->cur_rf->data + loc) #define xf_init(N) do {rc = sc->cur_rf; if ((rc->cur + N) >= rc->end) resize_xf(sc, rc);} while (0) #define xf_store(Val) do {(*(rc->cur)) = Val; rc->cur++;} while (0) #define xf_save_loc(Loc) do {Loc = rc->cur - rc->data; rc->cur++;} while (0) #define xf_save_loc2(Loc1, Loc2) do {Loc1 = rc->cur - rc->data; Loc2 = Loc1 + 1; rc->cur += 2;} while (0) #define xf_save_loc3(Loc1, Loc2, Loc3) do {Loc1 = rc->cur - rc->data; Loc2 = Loc1 + 1; Loc3 = Loc2 + 1; rc->cur += 3;} while (0) #define xf_store_at(Loc, Val) rc->data[Loc] = Val #define xf_go(loc) rc->cur = (s7_pointer *)(rc->data + loc) /* #define xf_loc() (ptr_int)(rc->cur - rc->data) */ s7_int s7_xf_store(s7_scheme *sc, s7_pointer val) { s7_pointer *cur; xf_t *rc; rc = sc->cur_rf; if (rc->cur == rc->end) resize_xf(sc, rc); cur = rc->cur++; (*cur) = val; return(cur - rc->data); } void s7_xf_store_at(s7_scheme *sc, s7_int index, s7_pointer val) { sc->cur_rf->data[index] = val; } void *s7_xf_new(s7_scheme *sc, s7_pointer e) { xf_t *result; if (sc->rf_free_list) { result = sc->rf_free_list; sc->rf_free_list = sc->rf_free_list->next; } else { result = (xf_t *)malloc(sizeof(xf_t)); result->size = 8; result->data = (s7_pointer *)calloc(result->size, sizeof(s7_pointer)); result->end = (s7_pointer *)(result->data + result->size); } if (sc->cur_rf) { sc->cur_rf->next = sc->rf_stack; sc->rf_stack = sc->cur_rf; } sc->cur_rf = result; result->cur = result->data; result->e = e; /* set only here? */ result->gc_list = NULL; return((void *)result); } static void s7_xf_clear(s7_scheme *sc) { while (sc->cur_rf) {s7_xf_free(sc);} } bool s7_xf_is_stepper(s7_scheme *sc, s7_pointer sym) { s7_pointer e, p; e = sc->cur_rf->e; if (!e) return(false); for (p = let_slots(e); is_slot(p); p = next_slot(p)) if (slot_symbol(p) == sym) return(true); return(false); } static void xf_clear_list(s7_scheme *sc, xf_t *r) { gc_obj *p, *op; for (p = r->gc_list; p; p = op) { op = p->nxt; free(p); } r->gc_list = NULL; } void *s7_xf_detach(s7_scheme *sc) { xf_t *r; r = sc->cur_rf; sc->cur_rf = sc->rf_stack; if (sc->rf_stack) sc->rf_stack = sc->rf_stack->next; return((void *)r); } void s7_xf_attach(s7_scheme *sc, void *ur) { xf_t *r = (xf_t *)ur; r->next = sc->rf_free_list; sc->rf_free_list = r; xf_clear_list(sc, r); } s7_pointer *s7_xf_top(s7_scheme *sc, void *ur) { xf_t *r = (xf_t *)ur; return(r->data); } static s7_pointer xf_push(s7_scheme *sc, s7_pointer obj) { gc_obj *p; p = (gc_obj *)malloc(sizeof(gc_obj)); p->nxt = sc->cur_rf->gc_list; sc->cur_rf->gc_list = p; p->p = obj; return(obj); } #if WITH_ADD_PF static s7_pointer xf_pop(s7_scheme *sc) { if ((sc->cur_rf) && (sc->cur_rf->gc_list)) { s7_pointer p; gc_obj *g; g = sc->cur_rf->gc_list; p = g->p; sc->cur_rf->gc_list = g->nxt; free(g); return(p); } return(NULL); } #endif void s7_xf_free(s7_scheme *sc) { sc->cur_rf->next = sc->rf_free_list; sc->rf_free_list = sc->cur_rf; xf_clear_list(sc, sc->cur_rf); sc->cur_rf = sc->rf_stack; if (sc->rf_stack) sc->rf_stack = sc->rf_stack->next; } static s7_if_t implicit_int_vector_ref(s7_scheme *sc, s7_pointer expr); static s7_rf_t implicit_float_vector_ref(s7_scheme *sc, s7_pointer expr); static s7_pf_t implicit_pf_sequence_ref(s7_scheme *sc, s7_pointer expr); static s7_pf_t implicit_gf_sequence_ref(s7_scheme *sc, s7_pointer expr); #if WITH_OPTIMIZATION static s7_pf_t implicit_pf_sequence_set(s7_scheme *sc, s7_pointer v, s7_pointer ind, s7_pointer val); static s7_pf_t implicit_gf_sequence_set(s7_scheme *sc, s7_pointer v, s7_pointer ind, s7_pointer val); #endif /* set cases are via set_if/set_rf -- but set_gp|pf would need to be restricted to non-symbol settees */ /* need to make sure sequence is not a step var, also set cases */ static s7_rp_t rf_function(s7_pointer f) { switch (type(f)) { case T_C_FUNCTION_STAR: case T_C_FUNCTION: case T_C_ANY_ARGS_FUNCTION: case T_C_OPT_ARGS_FUNCTION: case T_C_RST_ARGS_FUNCTION: return(c_function_rp(f)); case T_FLOAT_VECTOR: return(implicit_float_vector_ref); case T_C_OBJECT: return(c_object_rp(f)); case T_SYNTAX: return(syntax_rp(f)); } return(NULL); } static s7_ip_t if_function(s7_pointer f) { switch (type(f)) { case T_C_FUNCTION_STAR: case T_C_FUNCTION: case T_C_ANY_ARGS_FUNCTION: case T_C_OPT_ARGS_FUNCTION: case T_C_RST_ARGS_FUNCTION: return(c_function_ip(f)); case T_INT_VECTOR: return(implicit_int_vector_ref); case T_C_OBJECT: return(c_object_ip(f)); case T_SYNTAX: return(syntax_ip(f)); } return(NULL); } static s7_pp_t pf_function(s7_pointer f) { switch (type(f)) { case T_C_FUNCTION_STAR: case T_C_FUNCTION: case T_C_ANY_ARGS_FUNCTION: case T_C_OPT_ARGS_FUNCTION: case T_C_RST_ARGS_FUNCTION: return(c_function_pp(f)); case T_PAIR: case T_STRING: case T_VECTOR: case T_HASH_TABLE: case T_LET: return(implicit_pf_sequence_ref); case T_SYNTAX: return(syntax_pp(f)); } return(NULL); } static s7_pp_t gf_function(s7_pointer f) { switch (type(f)) { case T_C_FUNCTION_STAR: case T_C_FUNCTION: case T_C_ANY_ARGS_FUNCTION: case T_C_OPT_ARGS_FUNCTION: case T_C_RST_ARGS_FUNCTION: return(c_function_gp(f)); case T_PAIR: case T_STRING: case T_VECTOR: case T_HASH_TABLE: case T_LET: case T_C_OBJECT: case T_INT_VECTOR: case T_FLOAT_VECTOR: return(implicit_gf_sequence_ref); } return(NULL); } s7_rp_t s7_rf_function(s7_scheme *sc, s7_pointer func) {return(rf_function(func));} s7_ip_t s7_if_function(s7_scheme *sc, s7_pointer func) {return(if_function(func));} s7_pp_t s7_pf_function(s7_scheme *sc, s7_pointer func) {return(pf_function(func));} s7_pp_t s7_gf_function(s7_scheme *sc, s7_pointer func) {return(gf_function(func));} void s7_rf_set_function(s7_pointer f, s7_rp_t rp) { #if WITH_OPTIMIZATION if (!is_c_function(f)) return; c_function_rp(f) = rp; #else return; #endif } void s7_if_set_function(s7_pointer f, s7_ip_t ip) { #if WITH_OPTIMIZATION if (!is_c_function(f)) return; c_function_ip(f) = ip; #else return; #endif } void s7_pf_set_function(s7_pointer f, s7_pp_t pp) { #if WITH_OPTIMIZATION if (!is_c_function(f)) return; c_function_pp(f) = pp; #else return; #endif } void s7_gf_set_function(s7_pointer f, s7_pp_t gp) { #if WITH_OPTIMIZATION if (!is_c_function(f)) return; c_function_gp(f) = gp; #else return; #endif } static s7_rp_t pair_to_rp(s7_scheme *sc, s7_pointer expr) { s7_pointer val_sym, val; val_sym = car(expr); if (!s7_is_symbol(val_sym)) return(NULL); if (s7_local_slot(sc, val_sym)) return(NULL); val = s7_symbol_value(sc, val_sym); return(s7_rf_function(sc, val)); } static s7_ip_t pair_to_ip(s7_scheme *sc, s7_pointer expr) { s7_pointer val_sym, val; val_sym = car(expr); if (!s7_is_symbol(val_sym)) return(NULL); if (s7_local_slot(sc, val_sym)) return(NULL); val = s7_symbol_value(sc, val_sym); return(s7_if_function(sc, val)); } static s7_pp_t pair_to_pp(s7_scheme *sc, s7_pointer expr) { s7_pointer val_sym, val; val_sym = car(expr); if (!s7_is_symbol(val_sym)) return(NULL); if (s7_local_slot(sc, val_sym)) return(NULL); val = s7_symbol_value(sc, val_sym); return(s7_pf_function(sc, val)); } static s7_pp_t pair_to_gp(s7_scheme *sc, s7_pointer expr) { s7_pointer val_sym, val; val_sym = car(expr); if (!s7_is_symbol(val_sym)) return(NULL); if (s7_local_slot(sc, val_sym)) return(NULL); val = s7_symbol_value(sc, val_sym); return(s7_gf_function(sc, val)); } static s7_pf_t xf_opt(s7_scheme *sc, s7_pointer lp) { s7_int loc; s7_pointer f; s7_rp_t rp; s7_ip_t xp; s7_pp_t pp; xf_t *rc; f = find_symbol(sc, car(lp)); if (!is_slot(f)) return(NULL); f = slot_value(f); xf_init(3); xf_save_loc(loc); xp = if_function(f); if (xp) { s7_if_t xf; xf = xp(sc, lp); if (xf) { xf_store_at(loc, (s7_pointer)xf); return((s7_pf_t)xf); } xf_go(loc + 1); } rp = rf_function(f); if (rp) { s7_rf_t rf; rf = rp(sc, lp); if (rf) { xf_store_at(loc, (s7_pointer)rf); return((s7_pf_t)rf); } xf_go(loc + 1); } pp = pf_function(f); if (pp) { s7_pf_t pf; pf = pp(sc, lp); if (pf) { xf_store_at(loc, (s7_pointer)pf); return(pf); } xf_go(loc + 1); } pp = gf_function(f); if (pp) { s7_pf_t pf; pf = pp(sc, lp); if (pf) { xf_store_at(loc, (s7_pointer)pf); return(pf); } } return(NULL); } #if 0 static s7_pointer if_to_pf(s7_scheme *sc, s7_pointer **p) { s7_if_t xf; s7_int x; xf = (s7_if_t)(**p); (*p)++; x = xf(sc, p); return(make_integer(sc, x)); } static s7_pointer rf_to_pf(s7_scheme *sc, s7_pointer **p) { s7_rf_t rf; s7_double x; rf = (s7_rf_t)(**p); (*p)++; x = rf(sc, p); return(make_real(sc, x)); } static s7_pf_t pf_opt(s7_scheme *sc, s7_pointer lp) { s7_int loc, loc1; s7_pointer f; s7_rp_t rp; s7_ip_t xp; s7_pp_t pp; xf_t *rc; f = find_symbol(sc, car(lp)); if (!is_slot(f)) return(NULL); f = slot_value(f); xf_init(3); xf_save_loc(loc); xp = if_function(f); if (xp) { s7_if_t xf; xf_save_loc(loc1); xf = xp(sc, lp); if (xf) { xf_store_at(loc, (s7_pointer)if_to_pf); xf_store_at(loc1, (s7_pointer)xf); return((s7_pf_t)if_to_pf); } xf_go(loc + 1); } rp = rf_function(f); if (rp) { s7_rf_t rf; xf_save_loc(loc1); rf = rp(sc, lp); if (rf) { xf_store_at(loc, (s7_pointer)rf_to_pf); xf_store_at(loc1, (s7_pointer)rf); return((s7_pf_t)rf_to_pf); } xf_go(loc + 1); } pp = pf_function(f); if (pp) { s7_pf_t pf; pf = pp(sc, lp); if (pf) { xf_store_at(loc, (s7_pointer)pf); return(pf); } } return(NULL); } #endif static s7_double rf_c(s7_scheme *sc, s7_pointer **p) { s7_double x; x = s7_number_to_real(sc, **p); (*p)++; return(x); } static s7_double rf_s(s7_scheme *sc, s7_pointer **p) { s7_double x; x = s7_number_to_real(sc, slot_value(**p)); (*p)++; return(x); } static bool arg_to_rf(s7_scheme *sc, s7_pointer a1, s7_int in_loc) { s7_int loc; xf_t *rc; xf_init(2); if (in_loc == -1) xf_save_loc(loc); else loc = in_loc; if (is_pair(a1)) { s7_rp_t rp; s7_rf_t rf; rp = pair_to_rp(sc, a1); if (!rp) return(false); rf = rp(sc, a1); if (!rf) return(false); xf_store_at(loc, (s7_pointer)rf); return(true); } if (is_symbol(a1)) { s7_pointer slot; slot = s7_slot(sc, a1); if ((is_slot(slot)) && (is_real(slot_value(slot)))) { xf_store(slot); xf_store_at(loc, (s7_pointer)rf_s); return(true); } return(false); } if (is_real(a1)) { xf_store(a1); xf_store_at(loc, (s7_pointer)rf_c); return(true); } return(false); } bool s7_arg_to_rf(s7_scheme *sc, s7_pointer a1) { return(arg_to_rf(sc, a1, -1)); } static s7_int if_c(s7_scheme *sc, s7_pointer **p) { s7_pointer i; i = **p; (*p)++; return(integer(i)); } static s7_int if_s(s7_scheme *sc, s7_pointer **p) { s7_pointer x; x = slot_value(**p); (*p)++; if (!is_integer(x)) s7_wrong_type_arg_error(sc, "", 0, x, "an integer"); return(integer(x)); } static bool arg_to_if(s7_scheme *sc, s7_pointer a1, s7_int in_loc) { s7_int loc; xf_t *rc; xf_init(2); if (in_loc == -1) xf_save_loc(loc); else loc = in_loc; if (is_pair(a1)) { s7_ip_t ip; s7_if_t xf; ip = pair_to_ip(sc, a1); if (!ip) return(false); xf = ip(sc, a1); if (!xf) return(false); xf_store_at(loc, (s7_pointer)xf); return(true); } if (is_symbol(a1)) { s7_pointer slot; slot = s7_slot(sc, a1); if ((is_slot(slot)) && (is_integer(slot_value(slot)))) { xf_store(slot); xf_store_at(loc, (s7_pointer)if_s); return(true); } return(false); } if (is_integer(a1)) { xf_store(a1); xf_store_at(loc, (s7_pointer)if_c); return(true); } return(false); } bool s7_arg_to_if(s7_scheme *sc, s7_pointer a1) { return(arg_to_if(sc, a1, -1)); } static s7_pointer pf_c(s7_scheme *sc, s7_pointer **p) { s7_pointer x; x = **p; (*p)++; return(x); } static s7_pointer pf_s(s7_scheme *sc, s7_pointer **p) { s7_pointer x; x = slot_value(**p); (*p)++; return(x); } static bool arg_to_pf(s7_scheme *sc, s7_pointer a1, s7_int in_loc) { s7_int loc; xf_t *rc; xf_init(2); if (in_loc == -1) xf_save_loc(loc); else loc = in_loc; if (is_pair(a1)) { s7_pp_t pp; s7_pf_t pf; pp = pair_to_pp(sc, a1); if (!pp) return(false); pf = pp(sc, a1); if (!pf) return(false); xf_store_at(loc, (s7_pointer)pf); return(true); } if (is_symbol(a1)) { s7_pointer slot; slot = s7_slot(sc, a1); if (is_slot(slot)) { xf_store(slot); xf_store_at(loc, (s7_pointer)pf_s); return(true); } return(false); } xf_store(a1); xf_store_at(loc, (s7_pointer)pf_c); return(true); } bool s7_arg_to_pf(s7_scheme *sc, s7_pointer a1) { return(arg_to_pf(sc, a1, -1)); } static bool arg_to_gf(s7_scheme *sc, s7_pointer a1, s7_int in_loc) { if (is_pair(a1)) { s7_pp_t gp; gp = pair_to_gp(sc, a1); if (gp) { xf_t *rc; s7_pf_t gf; s7_int loc; xf_init(1); if (in_loc == -1) xf_save_loc(loc); else loc = in_loc; gf = gp(sc, a1); if (gf) { xf_store_at(loc, (s7_pointer)gf); return(true); } } } return(false); } bool s7_arg_to_gf(s7_scheme *sc, s7_pointer a1) { return(arg_to_gf(sc, a1, -1)); } static s7_rf_t pair_to_rf(s7_scheme *sc, s7_pointer a1, s7_rf_t x) { if (s7_arg_to_rf(sc, a1)) return(x); return(NULL); } static s7_rf_t pair_to_rf_via_if(s7_scheme *sc, s7_pointer a1, s7_rf_t x) { if (s7_arg_to_if(sc, a1)) return(x); return(NULL); } s7_rf_t s7_rf_1(s7_scheme *sc, s7_pointer expr, s7_rf_t r, s7_rf_t s, s7_rf_t x) { s7_pointer a1; xf_t *rc; if ((is_null(cdr(expr))) || (!is_null(cddr(expr)))) return(NULL); a1 = cadr(expr); xf_init(1); if (is_real(a1)) { xf_store(a1); return(r); } if (is_symbol(a1)) { a1 = s7_slot(sc, a1); if ((!is_slot(a1)) || (is_t_complex(slot_value(a1)))) return(NULL); xf_store(a1); return(s); } if (is_pair(a1)) return(pair_to_rf(sc, a1, x)); return(NULL); } s7_rf_t s7_rf_2(s7_scheme *sc, s7_pointer expr, s7_rf_t rr, s7_rf_t sr, s7_rf_t xr, s7_rf_t rs, s7_rf_t ss, s7_rf_t xs, s7_rf_t rx, s7_rf_t sx, s7_rf_t xx) { s7_pointer a1, a2; xf_t *rc; if ((is_null(cdr(expr))) || (!is_null(cdddr(expr)))) return(NULL); a1 = cadr(expr); a2 = caddr(expr); xf_init(2); if (is_real(a1)) { xf_store(a1); if (is_real(a2)) { xf_store(a2); return(rr); } if (is_symbol(a2)) { a2 = s7_slot(sc, a2); if ((!is_slot(a2)) || (is_t_complex(slot_value(a2)))) return(NULL); xf_store(a2); return(rs); } if (is_pair(a2)) return(pair_to_rf(sc, a2, rx)); return(NULL); } if (is_symbol(a1)) { a1 = s7_slot(sc, a1); if ((!is_slot(a1)) || (is_t_complex(slot_value(a1)))) return(NULL); xf_store(a1); if (is_real(a2)) { xf_store(a2); return(sr); } if (is_symbol(a2)) { a2 = s7_slot(sc, a2); if ((!is_slot(a2)) || (is_t_complex(slot_value(a2)))) return(NULL); xf_store(a2); return(ss); } if (is_pair(a2)) return(pair_to_rf(sc, a2, sx)); return(NULL); } if (is_pair(a1)) { s7_int loc; s7_rp_t rp; s7_rf_t rf; xf_save_loc(loc); rp = pair_to_rp(sc, a1); if (!rp) return(NULL); rf = rp(sc, a1); if (!rf) return(NULL); xf_store_at(loc, (s7_pointer)rf); if (is_real(a2)) { xf_store(a2); return(xr); } if (is_symbol(a2)) { a2 = s7_slot(sc, a2); if ((!is_slot(a2)) || (is_t_complex(slot_value(a2)))) return(NULL); xf_store(a2); return(xs); } if (is_pair(a2)) return(pair_to_rf(sc, a2, xx)); return(NULL); } return(NULL); } #if (!WITH_GMP) typedef struct {s7_rf_t none, r, s, p, rs, rp, ss, sp, pp, rss, rsp, rpp, sss, ssp, spp, ppp;} rf_ops; static rf_ops *add_r_ops, *multiply_r_ops; static s7_rf_t com_rf_2(s7_scheme *sc, s7_pointer expr, rf_ops *a) { /* expr len is assumed to be 3 (2 args) */ s7_pointer a1, a2, p1 = NULL, p2 = NULL, s1 = NULL, s2 = NULL, c1 = NULL, c2 = NULL; xf_t *rc; a1 = cadr(expr); if (is_pair(a1)) p1 = a1; else {if (is_symbol(a1)) s1 = a1; else {if (is_real(a1)) c1 = a1; else return(NULL);}} a2 = caddr(expr); if (is_pair(a2)) p2 = a2; else {if (is_symbol(a2)) s2 = a2; else {if (is_real(a2)) c2 = a2; else return(NULL);}} xf_init(2); if (!c1) {c1 = c2; c2 = NULL;} if (c2) { if ((is_t_real(c1)) || (is_t_real(c2))) { s7_pointer x; s7_double x1, x2; x1 = real_to_double(sc, c1, (a == add_r_ops) ? "+" : "*"); x2 = real_to_double(sc, c2, (a == add_r_ops) ? "+" : "*"); if (a == add_r_ops) x = make_real(sc, x1 + x2); else x = make_real(sc, x1 * x2); if (!is_immutable_real(x)) xf_push(sc, x); xf_store(x); return(a->r); } return(NULL); } if (!s1) {s1 = s2; s2 = NULL;} if (!p1) {p1 = p2; p2 = NULL;} if (s1) { bool s1_real; s1 = s7_slot(sc, s1); if ((!is_slot(s1)) || (is_unsafe_stepper(s1)) || (is_t_complex(slot_value(s1)))) return(NULL); s1_real = (is_t_real(slot_value(s1))); xf_store(s1); if (s2) { s2 = s7_slot(sc, s2); if ((!is_slot(s2)) || (is_unsafe_stepper(s2)) || (is_t_complex(slot_value(s2)))) return(NULL); if ((s1_real) || /* TODO: look at step etc */ (is_t_real(slot_value(s2)))) { xf_store(s2); return(a->ss); } return(NULL); } if (c1) { if ((s1_real) || (is_t_real(c1))) { xf_store(c1); return(a->rs); } return(NULL); } if (s7_arg_to_rf(sc, p1)) return(a->sp); return(NULL); } /* must be p1 here, c1 or p2 */ if (c1) { xf_store(c1); if (s7_arg_to_rf(sc, p1)) return(a->rp); return(NULL); } if ((s7_arg_to_rf(sc, p1)) && (s7_arg_to_rf(sc, p2))) return(a->pp); return(NULL); } static s7_rf_t com_rf_3(s7_scheme *sc, s7_pointer expr, rf_ops *a) { /* expr len is assumed to be 4 (3 args) */ s7_pointer a1, a2, a3, p1 = NULL, p2 = NULL, p3 = NULL, s1 = NULL, s2 = NULL, s3 = NULL, c1 = NULL, c2 = NULL, c3 = NULL; bool s1_real = false; xf_t *rc; a1 = cadr(expr); if (is_pair(a1)) p1 = a1; else {if (is_symbol(a1)) s1 = a1; else {if (is_real(a1)) c1 = a1; else return(NULL);}} a2 = caddr(expr); if (is_pair(a2)) p2 = a2; else {if (is_symbol(a2)) s2 = a2; else {if (is_real(a2)) c2 = a2; else return(NULL);}} a3 = cadddr(expr); if (is_pair(a3)) p3 = a3; else {if (is_symbol(a3)) s3 = a3; else {if (is_real(a3)) c3 = a3; else return(NULL);}} if (!s2) {s2 = s3; s3 = NULL;} if (!s1) {s1 = s2; s2 = s3; s3 = NULL;} xf_init(3); if (s1) { s1 = s7_slot(sc, s1); if ((!is_slot(s1)) || (is_unsafe_stepper(s1)) || (is_t_complex(slot_value(s1)))) return(NULL); s1_real = (is_t_real(slot_value(s1))); xf_store(s1); } if (!p2) {p2 = p3; p3 = NULL;} if (!p1) {p1 = p2; p2 = p3; p3 = NULL;} if (!c2) {c2 = c3; c3 = NULL;} if (!c1) {c1 = c2; c2 = c3; c3 = NULL;} if (c2) { if ((is_t_real(c1)) || (is_t_real(c2)) || ((c3) && (is_t_real(c3)))) { s7_pointer x; s7_double x1, x2, x3; x1 = real_to_double(sc, c1, (a == add_r_ops) ? "+" : "*"); x2 = real_to_double(sc, c2, (a == add_r_ops) ? "+" : "*"); if (c3) x3 = real_to_double(sc, c3, (a == add_r_ops) ? "+" : "*"); else x3 = ((a == add_r_ops) ? 0.0 : 1.0); if (a == add_r_ops) x = make_real(sc, x1 + x2 + x3); else x = make_real(sc, x1 * x2 * x3); if (!is_immutable_real(x)) xf_push(sc, x); xf_store(x); if (c3) return(a->r); if (s1) return(a->rs); if (s7_arg_to_rf(sc, p1)) return(a->rp); } return(NULL); } if (s1) { if (s2) { bool s2_real; s2 = s7_slot(sc, s2); if ((!is_slot(s2)) || (is_unsafe_stepper(s2)) || (is_t_complex(slot_value(s2)))) return(NULL); s2_real = (is_t_real(slot_value(s2))); xf_store(s2); if (s3) { s3 = s7_slot(sc, s3); if ((!is_slot(s3)) || (is_unsafe_stepper(s3)) || (is_t_complex(slot_value(s3)))) return(NULL); if ((s1_real) || (s2_real) || (is_t_real(slot_value(s3)))) { xf_store(s3); return(a->sss); } return(NULL); } if (c1) { if ((s1_real) || (s2_real) || (is_t_real(c1))) { xf_store(c1); return(a->rss); } return(NULL); } if (s7_arg_to_rf(sc, p1)) return(a->ssp); return(NULL); } if (c1) { xf_store(c1); if (s7_arg_to_rf(sc, p1)) return(a->rsp); return(NULL); } if ((s7_arg_to_rf(sc, p1)) && (s7_arg_to_rf(sc, p2))) return(a->spp); return(NULL); } if (c1) { xf_store(c1); if ((s7_arg_to_rf(sc, p1)) && (s7_arg_to_rf(sc, p2))) return(a->rpp); return(NULL); } if ((s7_arg_to_rf(sc, p1)) && (s7_arg_to_rf(sc, p2)) && (s7_arg_to_rf(sc, p3))) return(a->ppp); return(NULL); } typedef struct {s7_if_t none, r, s, p, rs, rp, ss, sp, pp, rss, rsp, rpp, sss, ssp, spp, ppp;} if_ops; static if_ops *add_i_ops, *multiply_i_ops; static s7_if_t com_if_2(s7_scheme *sc, s7_pointer expr, if_ops *a) { /* expr len is assumed to be 3 (2 args) */ s7_pointer a1, a2, p1 = NULL, p2 = NULL, s1 = NULL, s2 = NULL, c1 = NULL, c2 = NULL; xf_t *rc; a1 = cadr(expr); if (is_pair(a1)) p1 = a1; else {if (is_symbol(a1)) s1 = a1; else {if (is_real(a1)) c1 = a1; else return(NULL);}} a2 = caddr(expr); if (is_pair(a2)) p2 = a2; else {if (is_symbol(a2)) s2 = a2; else {if (is_real(a2)) c2 = a2; else return(NULL);}} xf_init(2); if (!c1) {c1 = c2; c2 = NULL;} if ((c1) && (!is_t_integer(c1))) return(NULL); if (c2) { s7_pointer x; if (!(is_t_integer(c2))) return(NULL); if (a == add_i_ops) x = make_integer(sc, integer(c1) + integer(c2)); else x = make_integer(sc, integer(c1) * integer(c2)); if (!is_immutable_integer(x)) xf_push(sc, x); xf_store(x); return(a->r); } if (!s1) {s1 = s2; s2 = NULL;} if (!p1) {p1 = p2; p2 = NULL;} if (s1) { s1 = s7_slot(sc, s1); if ((!is_slot(s1)) || (is_unsafe_stepper(s1)) || (!is_t_integer(slot_value(s1)))) return(NULL); xf_store(s1); if (s2) { s2 = s7_slot(sc, s2); if ((!is_slot(s2)) || (is_unsafe_stepper(s2)) || (!is_t_integer(slot_value(s2)))) return(NULL); xf_store(s2); return(a->ss); } if (c1) { xf_store(c1); return(a->rs); } if (s7_arg_to_if(sc, p1)) return(a->sp); return(NULL); } /* must be p1 here, c1 or p2 */ if (c1) { xf_store(c1); if (s7_arg_to_if(sc, p1)) return(a->rp); return(NULL); } if ((s7_arg_to_if(sc, p1)) && (s7_arg_to_if(sc, p2))) return(a->pp); return(NULL); } static s7_if_t com_if_3(s7_scheme *sc, s7_pointer expr, if_ops *a) { /* expr len is assumed to be 4 (3 args) */ s7_pointer a1, a2, a3, p1 = NULL, p2 = NULL, p3 = NULL, s1 = NULL, s2 = NULL, s3 = NULL, c1 = NULL, c2 = NULL, c3 = NULL; xf_t *rc; a1 = cadr(expr); if (is_pair(a1)) p1 = a1; else {if (is_symbol(a1)) s1 = a1; else {if (is_real(a1)) c1 = a1; else return(NULL);}} a2 = caddr(expr); if (is_pair(a2)) p2 = a2; else {if (is_symbol(a2)) s2 = a2; else {if (is_real(a2)) c2 = a2; else return(NULL);}} a3 = cadddr(expr); if (is_pair(a3)) p3 = a3; else {if (is_symbol(a3)) s3 = a3; else {if (is_real(a3)) c3 = a3; else return(NULL);}} xf_init(3); if (!s2) {s2 = s3; s3 = NULL;} if (!s1) {s1 = s2; s2 = s3; s3 = NULL;} if (s1) { s1 = s7_slot(sc, s1); if ((!is_slot(s1)) || (is_unsafe_stepper(s1)) || (!is_t_integer(slot_value(s1)))) return(NULL); xf_store(s1); } if (!p2) {p2 = p3; p3 = NULL;} if (!p1) {p1 = p2; p2 = p3; p3 = NULL;} if (!c2) {c2 = c3; c3 = NULL;} if (!c1) {c1 = c2; c2 = c3; c3 = NULL;} if (c1) { if (!is_t_integer(c1)) return(NULL); if (c2) { s7_pointer x; if (!is_t_integer(c2)) return(NULL); if ((c3) && (!is_t_integer(c3))) return(NULL); if (a == add_i_ops) x = make_integer(sc, integer(c1) + integer(c2) + ((c3) ? integer(c3) : 0)); else x = make_integer(sc, integer(c1) * integer(c2) * ((c3) ? integer(c3) : 1)); if (!is_immutable_integer(x)) xf_push(sc, x); xf_store(x); if (c3) return(a->r); if (s1) return(a->rs); if (s7_arg_to_if(sc, p1)) return(a->rp); } return(NULL); } if (s1) { if (s2) { s2 = s7_slot(sc, s2); if ((!is_slot(s2)) || (is_unsafe_stepper(s2)) || (!is_t_integer(slot_value(s2)))) return(NULL); xf_store(s2); if (s3) { s3 = s7_slot(sc, s3); if ((!is_slot(s3)) || (is_unsafe_stepper(s3)) || (!is_t_integer(slot_value(s3)))) return(NULL); xf_store(s3); return(a->sss); } if (c1) { xf_store(c1); return(a->rss); } if (s7_arg_to_if(sc, p1)) return(a->ssp); return(NULL); } if (c1) { xf_store(c1); if (s7_arg_to_if(sc, p1)) return(a->rsp); return(NULL); } if ((s7_arg_to_if(sc, p1)) && (s7_arg_to_if(sc, p2))) return(a->spp); return(NULL); } if (c1) { xf_store(c1); if ((s7_arg_to_if(sc, p1)) && (s7_arg_to_if(sc, p2))) return(a->rpp); return(NULL); } if ((s7_arg_to_if(sc, p1)) && (s7_arg_to_if(sc, p2)) && (s7_arg_to_if(sc, p3))) return(a->ppp); return(NULL); } #endif #if WITH_OPTIMIZATION static s7_double set_rf_sr(s7_scheme *sc, s7_pointer **p) { s7_pointer s1, c1; s7_double x; s1 = (**p); (*p)++; c1 = (**p); (*p)++; x = real(c1); slot_set_value(s1, make_real(sc, x)); return(x); } #if 0 static s7_double set_rf_ss(s7_scheme *sc, s7_pointer **p) { s7_pointer s1, s2; s7_double x; s1 = (**p); (*p)++; s2 = (**p); (*p)++; x = real_to_double(sc, slot_value(s2), "set!"); slot_set_value(s1, make_real(sc, x)); return(x); } #endif static s7_double set_rf_sx(s7_scheme *sc, s7_pointer **p) { s7_pointer s1; s7_double x; s7_rf_t r1; s1 = (**p); (*p)++; r1 = (s7_rf_t)(**p); (*p)++; x = r1(sc, p); slot_set_value(s1, make_real(sc, x)); return(x); } static s7_int set_if_sx(s7_scheme *sc, s7_pointer **p) { s7_pointer s1; s7_int x; s7_if_t i1; s1 = (**p); (*p)++; i1 = (s7_if_t)(**p); (*p)++; x = i1(sc, p); slot_set_value(s1, make_integer(sc, x)); return(x); } static s7_rf_t float_vector_set_rf_expanded(s7_scheme *sc, s7_pointer fv, s7_pointer ind_sym, s7_pointer val_expr); static s7_if_t int_vector_set_if_expanded(s7_scheme *sc, s7_pointer iv, s7_pointer ind_sym, s7_pointer val_expr); static s7_rf_t set_rf(s7_scheme *sc, s7_pointer expr) { s7_pointer slot, a1; xf_t *rc; if (is_pair(cdddr(expr))) return(NULL); a1 = cadr(expr); if (!is_symbol(a1)) /* look for implicit index case */ { s7_pointer fv; if ((!is_pair(a1)) || (!is_symbol(car(a1))) || (!is_null(cddr(a1)))) return(NULL); fv = s7_symbol_value(sc, car(a1)); if (is_float_vector(fv)) return(float_vector_set_rf_expanded(sc, fv, cadr(a1), caddr(expr))); if ((is_c_object(fv)) && (c_object_set_rp(fv))) return(c_object_set_rp(fv)(sc, expr)); return(NULL); } /* if sym has real value and new val is real, we're ok */ slot = s7_slot(sc, a1); if (!is_slot(slot)) return(NULL); xf_init(2); if (is_t_real(slot_value(slot))) { s7_pointer a2; xf_store(slot); a2 = caddr(expr); if (is_t_real(a2)) { xf_store(a2); return(set_rf_sr); } #if 0 if (is_symbol(a2)) { s7_pointer a2_slot; a2_slot = s7_slot(sc, a2); if (!is_slot(a2_slot)) return(NULL); if (type(slot_value(a2_slot)) != T_REAL) return(NULL); xf_store(a2_slot); return(set_rf_ss); } #endif if (is_pair(a2)) { s7_rp_t rp; s7_rf_t rf; s7_int loc; xf_save_loc(loc); rp = pair_to_rp(sc, a2); if (!rp) return(NULL); rf = rp(sc, a2); if (!rf) return(NULL); xf_store_at(loc, (s7_pointer)rf); return(set_rf_sx); } } return(NULL); } static s7_if_t set_if(s7_scheme *sc, s7_pointer expr) { s7_pointer slot, a1; if (is_pair(cdddr(expr))) return(NULL); a1 = cadr(expr); if (!is_symbol(a1)) /* look for implicit index case */ { s7_pointer fv; if ((!is_pair(a1)) || (!is_symbol(car(a1))) || (!is_null(cddr(a1)))) return(NULL); fv = s7_symbol_value(sc, car(a1)); if (is_int_vector(fv)) return(int_vector_set_if_expanded(sc, fv, cadr(a1), caddr(expr))); if ((is_c_object(fv)) && (c_object_set_ip(fv))) return(c_object_set_ip(fv)(sc, expr)); return(NULL); } if (!is_symbol(a1)) return(NULL); slot = s7_slot(sc, a1); if (!is_slot(slot)) return(NULL); if (is_t_integer(slot_value(slot))) { s7_pointer a2; xf_t *rc; xf_init(1); xf_store(slot); a2 = caddr(expr); if ((is_pair(a2)) && (s7_arg_to_if(sc, a2))) return(set_if_sx); } return(NULL); } static s7_pf_t set_pf(s7_scheme *sc, s7_pointer expr) { s7_pointer a1; if (is_pair(cdddr(expr))) return(NULL); a1 = cadr(expr); if (is_pair(a1)) /* look for implicit index case */ { s7_pointer v; if ((!is_symbol(car(a1))) || (!is_pair(cdr(a1))) || (!is_null(cddr(a1)))) return(NULL); v = s7_slot(sc, car(a1)); if (!is_slot(v)) return(NULL); switch (type(slot_value(v))) { case T_PAIR: case T_STRING: case T_VECTOR: case T_HASH_TABLE: case T_LET: return(implicit_pf_sequence_set(sc, v, cadr(a1), caddr(expr))); case T_INT_VECTOR: case T_FLOAT_VECTOR: return(implicit_gf_sequence_set(sc, v, cadr(a1), caddr(expr))); } } return(NULL); } #endif typedef s7_pointer (*p0_pf_t)(s7_scheme *sc); static s7_pointer p0_pf_1(s7_scheme *sc, s7_pointer **p, p0_pf_t fnc) { return(fnc(sc)); } static s7_pf_t pf_0(s7_scheme *sc, s7_pointer expr, s7_pf_t fnc) { if (!is_null(cdr(expr))) return(NULL); return(fnc); } #define PF_0(CName, Pfnc) \ static s7_pointer CName ## _pf_0(s7_scheme *sc, s7_pointer **rp) {return(p0_pf_1(sc, rp, Pfnc));} \ static s7_pf_t CName ## _pf(s7_scheme *sc, s7_pointer expr) {return(pf_0(sc, expr, CName ## _pf_0));} PF_0(curlet, s7_curlet) PF_0(rootlet, s7_rootlet) PF_0(current_input_port, s7_current_input_port) PF_0(current_output_port, s7_current_output_port) PF_0(current_error_port, s7_current_error_port) static s7_pointer c_unlet(s7_scheme *sc) {return(g_unlet(sc, sc->NIL));} PF_0(unlet, c_unlet) static s7_pointer c_gc(s7_scheme *sc) {return(g_gc(sc, sc->NIL));} PF_0(gc, c_gc) /* -------- PF_TO_PF -------- */ typedef s7_pointer (*pf_pf_t)(s7_scheme *sc, s7_pointer x); static s7_pointer pf_pf_1(s7_scheme *sc, s7_pointer **p, pf_pf_t fnc) { s7_pf_t f; s7_pointer x; f = (s7_pf_t)(**p); (*p)++; x = f(sc, p); return(fnc(sc, x)); } static s7_pointer pf_pf_s(s7_scheme *sc, s7_pointer **p, pf_pf_t fnc) { s7_pointer x; (*p)++; x = slot_value(**p); (*p)++; return(fnc(sc, x)); } static s7_pf_t pf_1(s7_scheme *sc, s7_pointer expr, s7_pf_t f1, s7_pf_t f2) { if ((is_pair(cdr(expr))) && (is_null(cddr(expr)))) { ptr_int loc; s7_pointer a1; a1 = cadr(expr); loc = rc_loc(sc); if (s7_arg_to_pf(sc, a1)) return((is_symbol(a1)) ? f2 : f1); sc->cur_rf->cur = rc_go(sc, loc); if (s7_arg_to_gf(sc, a1)) return((is_symbol(a1)) ? f2 : f1); } return(NULL); } #define PF_TO_PF(CName, Pfnc) \ static s7_pointer CName ## _pf_p(s7_scheme *sc, s7_pointer **rp) {return(pf_pf_1(sc, rp, Pfnc));} \ static s7_pointer CName ## _pf_s(s7_scheme *sc, s7_pointer **rp) {return(pf_pf_s(sc, rp, Pfnc));} \ static s7_pf_t CName ## _pf(s7_scheme *sc, s7_pointer expr) {return(pf_1(sc, expr, CName ## _pf_p, CName ## _pf_s));} static s7_pointer c_symbol_to_value(s7_scheme *sc, s7_pointer x) {return(g_symbol_to_value(sc, set_plist_1(sc, x)));} PF_TO_PF(symbol_to_value, c_symbol_to_value) static s7_pointer c_symbol_to_string(s7_scheme *sc, s7_pointer p) {return(g_symbol_to_string(sc, set_plist_1(sc, p)));} PF_TO_PF(symbol_to_string, c_symbol_to_string) static s7_pointer c_gensym(s7_scheme *sc, s7_pointer p) {return(g_gensym(sc, set_plist_1(sc, p)));} PF_TO_PF(gensym, c_gensym) static s7_pointer c_not(s7_scheme *sc, s7_pointer x) {return((x == sc->F) ? sc->T : sc->F);} PF_TO_PF(not, c_not) PF_TO_PF(outlet, s7_outlet) PF_TO_PF(openlet, s7_openlet) PF_TO_PF(funclet, s7_funclet) PF_TO_PF(coverlet, c_coverlet) #define bool_with_method(Name, Checker, Method) \ static s7_pointer c_ ## Name (s7_scheme *sc, s7_pointer p) \ { \ s7_pointer func; \ if (Checker(p)) return(sc->T); \ if ((has_methods(p)) && \ ((func = find_method(sc, find_let(sc, p), Method)) != sc->UNDEFINED)) \ return(s7_apply_function(sc, func, list_1(sc, p))); \ return(sc->F); \ } \ PF_TO_PF(Name, c_ ## Name) bool_with_method(is_char, s7_is_character, sc->IS_CHAR) bool_with_method(is_boolean, s7_is_boolean, sc->IS_BOOLEAN) bool_with_method(is_byte_vector, is_byte_vector, sc->IS_BYTE_VECTOR) bool_with_method(is_complex, is_number, sc->IS_COMPLEX) bool_with_method(is_constant, s7_is_constant, sc->IS_CONSTANT) bool_with_method(is_continuation, is_continuation, sc->IS_CONTINUATION) bool_with_method(is_c_pointer, s7_is_c_pointer, sc->IS_C_POINTER) bool_with_method(is_dilambda, s7_is_dilambda, sc->IS_DILAMBDA) bool_with_method(is_eof_object, is_eof, sc->IS_EOF_OBJECT) bool_with_method(is_float_vector, is_float_vector, sc->IS_FLOAT_VECTOR) bool_with_method(is_gensym, is_gensym, sc->IS_GENSYM) bool_with_method(is_hash_table, is_hash_table, sc->IS_HASH_TABLE) bool_with_method(is_input_port, is_input_port, sc->IS_INPUT_PORT) bool_with_method(is_integer, is_integer, sc->IS_INTEGER) bool_with_method(is_int_vector, is_int_vector, sc->IS_INT_VECTOR) bool_with_method(is_iterator, is_iterator, sc->IS_ITERATOR) bool_with_method(is_keyword, is_keyword, sc->IS_KEYWORD) bool_with_method(is_let, is_let, sc->IS_LET) bool_with_method(is_macro, is_macro, sc->IS_MACRO) bool_with_method(is_null, is_null, sc->IS_NULL) bool_with_method(is_number, is_number, sc->IS_NUMBER) bool_with_method(is_openlet, s7_is_openlet, sc->IS_OPENLET) bool_with_method(is_output_port, is_output_port, sc->IS_OUTPUT_PORT) bool_with_method(is_pair, is_pair, sc->IS_PAIR) bool_with_method(is_procedure, is_procedure, sc->IS_PROCEDURE) bool_with_method(is_rational, is_rational, sc->IS_RATIONAL) bool_with_method(is_real, is_real, sc->IS_REAL) bool_with_method(is_string, is_string, sc->IS_STRING) bool_with_method(is_symbol, is_symbol, sc->IS_SYMBOL) bool_with_method(is_vector, s7_is_vector, sc->IS_VECTOR) #define opt_is_list(p) s7_is_list(sc, p) bool_with_method(is_list, opt_is_list, sc->IS_LIST) bool_with_method(iterator_is_at_end, iterator_is_at_end, sc->ITERATOR_IS_AT_END) bool_with_method(is_random_state, is_random_state, sc->IS_RANDOM_STATE) PF_TO_PF(make_keyword, c_make_keyword) PF_TO_PF(keyword_to_symbol, c_keyword_to_symbol) PF_TO_PF(symbol_to_keyword, c_symbol_to_keyword) static s7_pointer c_symbol(s7_scheme *sc, s7_pointer x) {return(g_string_to_symbol_1(sc, x, sc->SYMBOL));} PF_TO_PF(symbol, c_symbol) #if 0 static s7_pointer symbol_pf_p(s7_scheme *sc, s7_pointer **p) { s7_pf_t f; s7_pointer x; f = (s7_pf_t)(**p); (*p)++; x = f(sc, p); return(g_string_to_symbol_1(sc, x, sc->SYMBOL)); } #endif /* an experiment -- we need a temp pointer per func? */ static s7_pointer string_to_symbol_pf_p(s7_scheme *sc, s7_pointer **p) { s7_pf_t f; s7_pointer x; f = (s7_pf_t)(**p); (*p)++; x = f(sc, p); return(g_string_to_symbol_1(sc, x, sc->STRING_TO_SYMBOL)); } static s7_pointer number_to_string_pf_p(s7_scheme *sc, s7_pointer **p); static s7_pointer number_to_string_pf_s(s7_scheme *sc, s7_pointer **p); static s7_pointer number_to_string_pf_temp(s7_scheme *sc, s7_pointer **p); static s7_pointer number_to_string_pf_s_temp(s7_scheme *sc, s7_pointer **p); static s7_pf_t string_to_symbol_pf(s7_scheme *sc, s7_pointer expr) { if ((is_pair(cdr(expr))) && (is_null(cddr(expr)))) { ptr_int loc; loc = rc_loc(sc); if (s7_arg_to_pf(sc, cadr(expr))) return(string_to_symbol_pf_p); sc->cur_rf->cur = rc_go(sc, loc); if (s7_arg_to_gf(sc, cadr(expr))) { if (sc->cur_rf->data[loc] == (s7_pointer)number_to_string_pf_p) sc->cur_rf->data[loc] = (s7_pointer)number_to_string_pf_temp; if (sc->cur_rf->data[loc] == (s7_pointer)number_to_string_pf_s) sc->cur_rf->data[loc] = (s7_pointer)number_to_string_pf_s_temp; return(string_to_symbol_pf_p); } } return(NULL); } #if (!WITH_PURE_S7) PF_TO_PF(let_to_list, s7_let_to_list) #endif /* -------- PF2_TO_PF -------- */ typedef s7_pointer (*pf2_pf_t)(s7_scheme *sc, s7_pointer x, s7_pointer y); static s7_pointer pf2_pf_1(s7_scheme *sc, s7_pointer **p, pf2_pf_t fnc) { s7_pf_t f; s7_pointer x, y; f = (s7_pf_t)(**p); (*p)++; x = f(sc, p); f = (s7_pf_t)(**p); (*p)++; y = f(sc, p); return(fnc(sc, x, y)); } static s7_pointer pf2_pf_sp(s7_scheme *sc, s7_pointer **p, pf2_pf_t fnc) { s7_pf_t f; s7_pointer x, y; x = slot_value(**p); (*p)++; f = (s7_pf_t)(**p); (*p)++; y = f(sc, p); return(fnc(sc, x, y)); } static s7_pointer pf2_pf_ss(s7_scheme *sc, s7_pointer **p, pf2_pf_t fnc) { s7_pointer x, y; x = slot_value(**p); (*p)++; y = slot_value(**p); (*p)++; return(fnc(sc, x, y)); } static s7_pointer pf2_pf_sc(s7_scheme *sc, s7_pointer **p, pf2_pf_t fnc) { s7_pointer x, y; x = slot_value(**p); (*p)++; y = (**p); (*p)++; return(fnc(sc, x, y)); } static s7_pointer pf2_pf_pc(s7_scheme *sc, s7_pointer **p, pf2_pf_t fnc) { s7_pf_t f; s7_pointer x, y; f = (s7_pf_t)(**p); (*p)++; x = f(sc, p); y = (**p); (*p)++; return(fnc(sc, x, y)); } static s7_pf_t pf_2(s7_scheme *sc, s7_pointer expr, s7_pf_t fpp, s7_pf_t fsp, s7_pf_t fss, s7_pf_t fsc, s7_pf_t fpc) { if ((is_pair(cdr(expr))) && (is_pair(cddr(expr))) && (is_null(cdddr(expr)))) { s7_pointer a1, a2; xf_t *rc; xf_init(2); a1 = cadr(expr); a2 = caddr(expr); if (is_symbol(a1)) { a1 = s7_slot(sc, a1); if (!is_slot(a1)) return(NULL); xf_store(a1); if (is_symbol(a2)) { a2 = s7_slot(sc, a2); if (!is_slot(a2)) return(NULL); xf_store(a2); return(fss); } if (is_pair(a2)) { if (!s7_arg_to_pf(sc, a2)) return(NULL); return(fsp); } xf_store(a2); return(fsc); } if (s7_arg_to_pf(sc, a1)) { if ((!is_pair(a2)) && (!is_symbol(a2))) { xf_store(a2); return(fpc); } if (s7_arg_to_pf(sc, a2)) return(fpp); } } return(NULL); } #define PF2_TO_PF(CName, Pfnc) \ static s7_pointer CName ## _pf_p2(s7_scheme *sc, s7_pointer **rp) {return(pf2_pf_1(sc, rp, Pfnc));} \ static s7_pointer CName ## _pf_p2_sp(s7_scheme *sc, s7_pointer **rp) {return(pf2_pf_sp(sc, rp, Pfnc));} \ static s7_pointer CName ## _pf_p2_ss(s7_scheme *sc, s7_pointer **rp) {return(pf2_pf_ss(sc, rp, Pfnc));} \ static s7_pointer CName ## _pf_p2_sc(s7_scheme *sc, s7_pointer **rp) {return(pf2_pf_sc(sc, rp, Pfnc));} \ static s7_pointer CName ## _pf_p2_pc(s7_scheme *sc, s7_pointer **rp) {return(pf2_pf_pc(sc, rp, Pfnc));} \ static s7_pf_t CName ## _pf(s7_scheme *sc, s7_pointer expr) \ { \ return(pf_2(sc, expr, CName ## _pf_p2, CName ## _pf_p2_sp, CName ## _pf_p2_ss, CName ## _pf_p2_sc, CName ## _pf_p2_pc));\ } static s7_pf_t pf_2_x(s7_scheme *sc, s7_pointer expr, bool (*checker)(s7_scheme *sc, s7_pointer obj), s7_pf_t fpp, s7_pf_t fpp_x, s7_pf_t fsp, s7_pf_t fss, s7_pf_t fsc, s7_pf_t fpc, s7_pf_t fpc_x) { if ((is_pair(cdr(expr))) && (is_pair(cddr(expr))) && (is_null(cdddr(expr)))) { s7_pointer a1, a2; xf_t *rc; xf_init(2); a1 = cadr(expr); a2 = caddr(expr); if (is_symbol(a1)) { a1 = s7_slot(sc, a1); if (!is_slot(a1)) return(NULL); xf_store(a1); if (is_symbol(a2)) { a2 = s7_slot(sc, a2); if (!is_slot(a2)) return(NULL); xf_store(a2); return(fss); } if (is_pair(a2)) { if (!s7_arg_to_pf(sc, a2)) return(NULL); return(fsp); } xf_store(a2); return(fsc); } if (s7_arg_to_pf(sc, a1)) { if ((!is_pair(a2)) && (!is_symbol(a2))) { xf_store(a2); if ((checker(sc, a1)) && (checker(sc, a2))) return(fpc_x); return(fpc); } if (s7_arg_to_pf(sc, a2)) { if ((checker(sc, a1)) && (checker(sc, a2))) return(fpp_x); return(fpp); } } } return(NULL); } #define PF2_TO_PF_X(CName, Checker, Pfnc1, Pfnc2) \ static s7_pointer CName ## _pf_p2_pp(s7_scheme *sc, s7_pointer **rp) {return(pf2_pf_1(sc, rp, Pfnc1));} \ static s7_pointer CName ## _pf_p2_ppx(s7_scheme *sc, s7_pointer **rp) {return(pf2_pf_1(sc, rp, Pfnc2));} \ static s7_pointer CName ## _pf_p2_pc(s7_scheme *sc, s7_pointer **rp) {return(pf2_pf_pc(sc, rp, Pfnc1));} \ static s7_pointer CName ## _pf_p2_pcx(s7_scheme *sc, s7_pointer **rp) {return(pf2_pf_pc(sc, rp, Pfnc2));} \ static s7_pointer CName ## _pf_p2_sp(s7_scheme *sc, s7_pointer **rp) {return(pf2_pf_sp(sc, rp, Pfnc1));} \ static s7_pointer CName ## _pf_p2_ss(s7_scheme *sc, s7_pointer **rp) {return(pf2_pf_ss(sc, rp, Pfnc1));} \ static s7_pointer CName ## _pf_p2_sc(s7_scheme *sc, s7_pointer **rp) {return(pf2_pf_sc(sc, rp, Pfnc1));} \ static s7_pf_t CName ## _pf(s7_scheme *sc, s7_pointer expr) \ {\ return(pf_2_x(sc, expr, Checker, \ CName ## _pf_p2_pp, CName ## _pf_p2_ppx, \ CName ## _pf_p2_sp, CName ## _pf_p2_ss, CName ## _pf_p2_sc, \ CName ## _pf_p2_pc, CName ## _pf_p2_pcx)); \ } static s7_pointer c_is_eq(s7_scheme *sc, s7_pointer x, s7_pointer y) {return(make_boolean(sc, x == y));} PF2_TO_PF(is_eq, c_is_eq) static s7_pointer c_is_eqv(s7_scheme *sc, s7_pointer x, s7_pointer y) {return(make_boolean(sc, s7_is_eqv(x, y)));} PF2_TO_PF(is_eqv, c_is_eqv) static s7_pointer c_is_equal(s7_scheme *sc, s7_pointer x, s7_pointer y) {return(make_boolean(sc, s7_is_equal(sc, x, y)));} PF2_TO_PF(is_equal, c_is_equal) static s7_pointer c_is_morally_equal(s7_scheme *sc, s7_pointer x, s7_pointer y) {return(make_boolean(sc, s7_is_morally_equal(sc, x, y)));} PF2_TO_PF(is_morally_equal, c_is_morally_equal) PF2_TO_PF(let_ref, s7_let_ref) static s7_pointer c_cutlet(s7_scheme *sc, s7_pointer x, s7_pointer y) {return(g_cutlet(sc, set_plist_2(sc, x, y)));} PF2_TO_PF(cutlet, c_cutlet) static s7_pointer c_inlet(s7_scheme *sc, s7_pointer x, s7_pointer y) {return(s7_inlet(sc, set_plist_2(sc, x, y)));} PF2_TO_PF(inlet, c_inlet) /* -------- PF3_TO_PF -------- */ typedef s7_pointer (*pf3_pf_t)(s7_scheme *sc, s7_pointer x, s7_pointer y, s7_pointer z); static s7_pointer pf3_pf_1(s7_scheme *sc, s7_pointer **p, pf3_pf_t fnc) { s7_pf_t f; s7_pointer x, y, z; f = (s7_pf_t)(**p); (*p)++; x = f(sc, p); f = (s7_pf_t)(**p); (*p)++; y = f(sc, p); f = (s7_pf_t)(**p); (*p)++; z = f(sc, p); return(fnc(sc, x, y, z)); } static s7_pointer pf3_pf_s(s7_scheme *sc, s7_pointer **p, pf3_pf_t fnc) { s7_pf_t f; s7_pointer x, y, z; x = slot_value(**p); (*p)++; f = (s7_pf_t)(**p); (*p)++; y = f(sc, p); f = (s7_pf_t)(**p); (*p)++; z = f(sc, p); return(fnc(sc, x, y, z)); } static s7_pf_t pf_3(s7_scheme *sc, s7_pointer expr, s7_pf_t fp, s7_pf_t fs) { if ((is_pair(cdr(expr))) && (is_pair(cddr(expr))) && (is_pair(cdddr(expr))) && (is_null(cddddr(expr)))) { s7_pointer a1; a1 = cadr(expr); if (is_symbol(a1)) { s7_pointer slot; slot = s7_slot(sc, a1); if (!is_slot(slot)) return(NULL); s7_xf_store(sc, slot); } else { if (!s7_arg_to_pf(sc, a1)) return(NULL); } if ((s7_arg_to_pf(sc, caddr(expr))) && (s7_arg_to_pf(sc, cadddr(expr)))) return((is_symbol(a1)) ? fs : fp); } return(NULL); } #define PF3_TO_PF(CName, Pfnc) \ static s7_pointer CName ## _pf_p3(s7_scheme *sc, s7_pointer **rp) {return(pf3_pf_1(sc, rp, Pfnc));} \ static s7_pointer CName ## _pf_p3_s(s7_scheme *sc, s7_pointer **rp) {return(pf3_pf_s(sc, rp, Pfnc));} \ static s7_pf_t CName ## _pf(s7_scheme *sc, s7_pointer expr) {return(pf_3(sc, expr, CName ## _pf_p3, CName ## _pf_p3_s));} PF3_TO_PF(let_set, s7_let_set) static s7_pointer c_varlet(s7_scheme *sc, s7_pointer x, s7_pointer y, s7_pointer z) {return(g_varlet(sc, set_plist_3(sc, x, y, z)));} PF3_TO_PF(varlet, c_varlet) PF_TO_PF(c_pointer, c_c_pointer) /* -------- PIF_TO_PF -------- */ typedef s7_pointer (*pif_pf_t)(s7_scheme *sc, s7_pointer x, s7_int y); static s7_pointer pif_pf_1(s7_scheme *sc, s7_pointer **p, pif_pf_t fnc) { s7_pf_t pf; s7_if_t xf; s7_pointer x; s7_int y; pf = (s7_pf_t)(**p); (*p)++; x = pf(sc, p); xf = (s7_if_t)(**p); (*p)++; y = xf(sc, p); return(fnc(sc, x, y)); } static s7_pointer pif_pf_s(s7_scheme *sc, s7_pointer **p, pif_pf_t fnc) { s7_if_t xf; s7_pointer x; s7_int y; x = slot_value(**p); (*p)++; xf = (s7_if_t)(**p); (*p)++; y = xf(sc, p); return(fnc(sc, x, y)); } static s7_pointer pif_pf_pp(s7_scheme *sc, s7_pointer **p, pif_pf_t fnc) { s7_pf_t pf; s7_pointer x, y; pf = (s7_pf_t)(**p); (*p)++; x = pf(sc, p); pf = (s7_pf_t)(**p); (*p)++; y = pf(sc, p); if (!is_integer(y)) return(s7_error(sc, sc->WRONG_TYPE_ARG, set_elist_2(sc, make_string_wrapper(sc, "~A should be an integer"), y))); return(fnc(sc, x, integer(y))); } static s7_pointer pif_pf_sp(s7_scheme *sc, s7_pointer **p, pif_pf_t fnc) { s7_pf_t pf; s7_pointer x, y; x = slot_value(**p); (*p)++; pf = (s7_pf_t)(**p); (*p)++; y = pf(sc, p); if (!is_integer(y)) return(s7_error(sc, sc->WRONG_TYPE_ARG, set_elist_2(sc, make_string_wrapper(sc, "~A should be an integer"), y))); return(fnc(sc, x, integer(y))); } static s7_pf_t pif_1(s7_scheme *sc, s7_pointer expr, s7_pf_t fpi, s7_pf_t fsi, s7_pf_t fpp, s7_pf_t fsp) { if ((is_pair(cdr(expr))) && (is_pair(cddr(expr))) && (is_null(cdddr(expr)))) { s7_pointer a1, a2; ptr_int loc; a1 = cadr(expr); a2 = caddr(expr); if (is_symbol(a1)) { s7_pointer slot; slot = s7_slot(sc, a1); if (!is_slot(slot)) return(NULL); s7_xf_store(sc, slot); } else { if (!s7_arg_to_pf(sc, a1)) return(NULL); } loc = rc_loc(sc); if (s7_arg_to_if(sc, a2)) return((is_symbol(a1)) ? fsi : fpi); sc->cur_rf->cur = rc_go(sc, loc); if (s7_arg_to_pf(sc, a2)) return((is_symbol(a1)) ? fsp : fpp); } return(NULL); } #define PIF_TO_PF(CName, Pfnc) \ static s7_pointer CName ## _pf_pi(s7_scheme *sc, s7_pointer **rp) {return(pif_pf_1(sc, rp, Pfnc));} \ static s7_pointer CName ## _pf_si(s7_scheme *sc, s7_pointer **rp) {return(pif_pf_s(sc, rp, Pfnc));} \ static s7_pointer CName ## _pf_pp(s7_scheme *sc, s7_pointer **rp) {return(pif_pf_pp(sc, rp, Pfnc));} \ static s7_pointer CName ## _pf_sp(s7_scheme *sc, s7_pointer **rp) {return(pif_pf_sp(sc, rp, Pfnc));} \ static s7_pf_t CName ## _pf(s7_scheme *sc, s7_pointer expr) {return(pif_1(sc, expr, CName ## _pf_pi, CName ## _pf_si, CName ## _pf_pp, CName ## _pf_sp));} /* -------- PPIF_TO_PF -------- */ typedef s7_pointer (*ppif_pf_t)(s7_scheme *sc, s7_pointer x, s7_pointer y, s7_int z); static s7_pointer ppif_pf_1(s7_scheme *sc, s7_pointer **p, ppif_pf_t fnc) /* other case is pf2_pf_1, type pf2_pf_t */ { s7_pf_t pf; s7_if_t xf; s7_pointer x, y; s7_int z; pf = (s7_pf_t)(**p); (*p)++; x = pf(sc, p); pf = (s7_pf_t)(**p); (*p)++; y = pf(sc, p); xf = (s7_if_t)(**p); (*p)++; z = xf(sc, p); return(fnc(sc, x, y, z)); } static s7_pf_t ppif_1(s7_scheme *sc, s7_pointer expr, s7_pf_t f1, s7_pf_t f2) { if ((is_pair(cdr(expr))) && (is_pair(cddr(expr)))) { ptr_int loc; if (!s7_arg_to_pf(sc, cadr(expr))) return(NULL); loc = rc_loc(sc); if (!s7_arg_to_pf(sc, caddr(expr))) { sc->cur_rf->cur = rc_go(sc, loc); if (!s7_arg_to_gf(sc, caddr(expr))) return(NULL); } if (is_null(cdddr(expr))) return(f1); if (!is_null(cddddr(expr))) return(NULL); if (s7_arg_to_if(sc, cadddr(expr))) return(f2); } return(NULL); } #define PPIF_TO_PF(CName, Pfnc1, Pfnc2) \ static s7_pointer CName ## _pf_pp(s7_scheme *sc, s7_pointer **rp) {return(pf2_pf_1(sc, rp, Pfnc1));} \ static s7_pointer CName ## _pf_ppi(s7_scheme *sc, s7_pointer **rp) {return(ppif_pf_1(sc, rp, Pfnc2));} \ static s7_pf_t CName ## _pf(s7_scheme *sc, s7_pointer expr) {return(ppif_1(sc, expr, CName ## _pf_pp, CName ## _pf_ppi));} /* -------- PIPF_TO_PF -------- */ typedef s7_pointer (*pipf_pf_t)(s7_scheme *sc, s7_pointer x, s7_int y, s7_pointer z); static s7_pointer pipf_pf_slot(s7_scheme *sc, s7_pointer **p, pipf_pf_t fnc) { s7_pf_t pf; s7_pointer x, z; s7_int y; x = (s7_pointer)(**p); (*p)++; y = s7_integer(slot_value(**p)); (*p)++; pf = (s7_pf_t)(**p); (*p)++; z = pf(sc, p); return(fnc(sc, x, y, z)); } static s7_pointer pipf_pf_s(s7_scheme *sc, s7_pointer **p, pipf_pf_t fnc) { s7_pf_t pf; s7_if_t xf; s7_pointer x, z; s7_int y; x = (s7_pointer)(**p); (*p)++; xf = (s7_if_t)(**p); (*p)++; y = xf(sc, p); pf = (s7_pf_t)(**p); (*p)++; z = pf(sc, p); return(fnc(sc, x, y, z)); } static s7_pointer pipf_pf_seq(s7_scheme *sc, s7_pointer **p, pipf_pf_t fnc) /* used in implicit_sequence_set */ { s7_pf_t pf; s7_if_t xf; s7_pointer x, z; s7_int y; x = slot_value(**p); (*p)++; xf = (s7_if_t)(**p); (*p)++; y = xf(sc, p); pf = (s7_pf_t)(**p); (*p)++; z = pf(sc, p); return(fnc(sc, x, y, z)); } static s7_pointer pipf_pf_a(s7_scheme *sc, s7_pointer **p, pipf_pf_t fnc) { s7_pf_t pf; s7_if_t xf; s7_pointer x, z; s7_int y; pf = (s7_pf_t)(**p); (*p)++; x = pf(sc, p); xf = (s7_if_t)(**p); (*p)++; y = xf(sc, p); pf = (s7_pf_t)(**p); (*p)++; z = pf(sc, p); return(fnc(sc, x, y, z)); } enum {TEST_NO_S, TEST_SS, TEST_SI, TEST_SQ}; /* si = sym ind, ss = sym sym for first two */ typedef int (*pf_i_t)(s7_scheme *sc, s7_pointer x); static s7_pf_t pipf_1(s7_scheme *sc, s7_pointer expr, s7_pf_t f1, s7_pf_t f2, s7_pf_t f3, pf_i_t tester) { if ((is_pair(cdr(expr))) && (is_pair(cddr(expr))) && (is_pair(cdddr(expr))) && (is_null(cddddr(expr)))) { int choice; choice = tester(sc, expr); if ((choice == TEST_SS) || (choice == TEST_SI) || ((choice == TEST_NO_S) && (s7_arg_to_pf(sc, cadr(expr))) && (s7_arg_to_if(sc, caddr(expr))))) { ptr_int loc; loc = rc_loc(sc); if (s7_arg_to_pf(sc, cadddr(expr))) return((choice == TEST_SS) ? f1 : ((choice == TEST_SI) ? f2 : f3)); sc->cur_rf->cur = rc_go(sc, loc); if (s7_arg_to_gf(sc, cadddr(expr))) return((choice == TEST_SS) ? f1 : ((choice == TEST_SI) ? f2 : f3)); } } return(NULL); } #define PIPF_TO_PF(CName, F1, F2, Tester) \ static s7_pointer CName ## _pf_slot(s7_scheme *sc, s7_pointer **rp) {return(pipf_pf_slot(sc, rp, F1));} \ static s7_pointer CName ## _pf_s(s7_scheme *sc, s7_pointer **rp) {return(pipf_pf_s(sc, rp, F1));} \ static s7_pointer CName ## _pf_seq(s7_scheme *sc, s7_pointer **rp) {return(pipf_pf_seq(sc, rp, F1));} \ static s7_pointer CName ## _pf_a(s7_scheme *sc, s7_pointer **rp) {return(pipf_pf_a(sc, rp, F2));} \ static s7_pf_t CName ## _pf(s7_scheme *sc, s7_pointer expr) {return(pipf_1(sc, expr, CName ## _pf_slot, CName ## _pf_s, CName ## _pf_a, Tester));} /* -------- IF_TO_IF -------- */ typedef s7_int (*if_if_t)(s7_scheme *sc, s7_int x); static s7_int if_if_1(s7_scheme *sc, s7_pointer **p, if_if_t fnc) { s7_if_t f; s7_int x; f = (s7_if_t)(**p); (*p)++; x = f(sc, p); return(fnc(sc, x)); } static s7_if_t if_1(s7_scheme *sc, s7_pointer expr, s7_if_t f) { if ((is_pair(cdr(expr))) && (is_null(cddr(expr))) && (s7_arg_to_if(sc, cadr(expr)))) return(f); return(NULL); } #define IF_TO_IF(CName, Ifnc) \ static s7_int CName ## _if_i(s7_scheme *sc, s7_pointer **rp) {return(if_if_1(sc, rp, Ifnc));} \ static s7_if_t CName ## _if(s7_scheme *sc, s7_pointer expr) {return(if_1(sc, expr, CName ## _if_i));} #if (!WITH_GMP) /* -------- IF2_TO_IF -------- */ typedef s7_int (*if2_if_t)(s7_scheme *sc, s7_int x, s7_int y); static s7_int if2_if_1(s7_scheme *sc, s7_pointer **p, if2_if_t fnc) { s7_if_t f; s7_int x, y; f = (s7_if_t)(**p); (*p)++; x = f(sc, p); f = (s7_if_t)(**p); (*p)++; y = f(sc, p); return(fnc(sc, x, y)); } static s7_if_t if_2(s7_scheme *sc, s7_pointer expr, s7_if_t f) { if ((is_pair(cdr(expr))) && (is_pair(cddr(expr))) && (is_null(cdddr(expr))) && (s7_arg_to_if(sc, cadr(expr))) && (s7_arg_to_if(sc, caddr(expr)))) return(f); return(NULL); } #define IF2_TO_IF(CName, Ifnc) \ static s7_int CName ## _if_i2(s7_scheme *sc, s7_pointer **rp) {return(if2_if_1(sc, rp, Ifnc));} \ static s7_if_t CName ## _if(s7_scheme *sc, s7_pointer expr) {return(if_2(sc, expr, CName ## _if_i2));} /* -------- IF_3_TO_IF -------- */ typedef s7_int (*if3_if_t)(s7_scheme *sc, s7_int x, s7_int y, s7_int z); static s7_int if3_if_1(s7_scheme *sc, s7_pointer **p, if3_if_t fnc) { s7_if_t f; s7_int x, y, z; f = (s7_if_t)(**p); (*p)++; x = f(sc, p); f = (s7_if_t)(**p); (*p)++; y = f(sc, p); f = (s7_if_t)(**p); (*p)++; z = f(sc, p); return(fnc(sc, x, y, z)); } static s7_if_t if_3(s7_scheme *sc, s7_pointer expr, s7_if_t f1, s7_if_t f2, s7_if_t f3) { if (!is_pair(cdr(expr))) return(NULL); if (!s7_arg_to_if(sc, cadr(expr))) return(NULL); if (is_null(cddr(expr))) return(f1); if (!s7_arg_to_if(sc, caddr(expr))) return(NULL); if (is_null(cdddr(expr))) return(f2); if (!s7_arg_to_if(sc, cadddr(expr))) return(NULL); if (is_null(cddddr(expr))) return(f3); return(NULL); } #define IF_3_TO_IF(CName, Ifnc1, Ifnc2, Ifnc3) \ static s7_int CName ## _if_i1(s7_scheme *sc, s7_pointer **rp) {return(if_if_1(sc, rp, Ifnc1));} \ static s7_int CName ## _if_i2(s7_scheme *sc, s7_pointer **rp) {return(if2_if_1(sc, rp, Ifnc2));} \ static s7_int CName ## _if_i3(s7_scheme *sc, s7_pointer **rp) {return(if3_if_1(sc, rp, Ifnc3));} \ static s7_if_t CName ## _if(s7_scheme *sc, s7_pointer expr) {return(if_3(sc, expr, CName ## _if_i1, CName ## _if_i2, CName ## _if_i3));} #endif /* gmp */ /* -------- IF_TO_PF -------- */ typedef s7_pointer (*if_pf_t)(s7_scheme *sc, s7_int x); static s7_pointer if_p_1(s7_scheme *sc, s7_pointer **p, if_pf_t fnc) { s7_if_t f; s7_int x; f = (s7_if_t)(**p); (*p)++; x = f(sc, p); return(fnc(sc, x)); } static s7_pf_t if_pf_1(s7_scheme *sc, s7_pointer expr, s7_pf_t f) { if ((is_pair(cdr(expr))) && (is_null(cddr(expr))) && (s7_arg_to_if(sc, cadr(expr)))) return(f); return(NULL); } #define IF_TO_PF(CName, Ifnc) \ static s7_pointer CName ## _pf_i(s7_scheme *sc, s7_pointer **rp) {return(if_p_1(sc, rp, Ifnc));} \ static s7_pf_t CName ## _pf(s7_scheme *sc, s7_pointer expr) {return(if_pf_1(sc, expr, CName ## _pf_i));} /* -------- PF_TO_IF -------- */ typedef s7_int (*pf_if_t)(s7_scheme *sc, s7_pointer x); static s7_int pf_i_1(s7_scheme *sc, s7_pointer **p, pf_if_t fnc) { s7_pf_t f; s7_pointer x; f = (s7_pf_t)(**p); (*p)++; x = f(sc, p); return(fnc(sc, x)); } static s7_if_t pf_if_1(s7_scheme *sc, s7_pointer expr, s7_if_t f) { if ((is_pair(cdr(expr))) && (is_null(cddr(expr))) && (s7_arg_to_pf(sc, cadr(expr)))) return(f); return(NULL); } #define PF_TO_IF(CName, Pfnc) \ static s7_int CName ## _if_p(s7_scheme *sc, s7_pointer **rp) {return(pf_i_1(sc, rp, Pfnc));} \ static s7_if_t CName ## _if(s7_scheme *sc, s7_pointer expr) {return(pf_if_1(sc, expr, CName ## _if_p));} /* -------- PF_TO_RF -------- */ typedef s7_double (*pf_rf_t)(s7_scheme *sc, s7_pointer x); static s7_double pf_r_1(s7_scheme *sc, s7_pointer **p, pf_rf_t fnc) { s7_pf_t f; s7_pointer x; f = (s7_pf_t)(**p); (*p)++; x = f(sc, p); return(fnc(sc, x)); } static s7_rf_t pf_rf_1(s7_scheme *sc, s7_pointer expr, s7_rf_t f) { if ((is_pair(cdr(expr))) && (is_null(cddr(expr))) && (s7_arg_to_rf(sc, cadr(expr)))) return(f); return(NULL); } #define PF_TO_RF(CName, Pfnc) \ static s7_double CName ## _rf_p(s7_scheme *sc, s7_pointer **rp) {return(pf_r_1(sc, rp, Pfnc));} \ static s7_rf_t CName ## _rf(s7_scheme *sc, s7_pointer expr) {return(pf_rf_1(sc, expr, CName ## _rf_p));} #if (!WITH_GMP) /* -------- RF_TO_IF -------- */ typedef s7_int (*rf_if_t)(s7_scheme *sc, s7_double x); static s7_int rf_i_1(s7_scheme *sc, s7_pointer **p, rf_if_t fnc) { s7_rf_t f; s7_double x; f = (s7_rf_t)(**p); (*p)++; x = f(sc, p); return(fnc(sc, x)); } static s7_if_t rf_if_1(s7_scheme *sc, s7_pointer expr, s7_if_t f) { if ((is_pair(cdr(expr))) && (is_null(cddr(expr))) && (s7_arg_to_rf(sc, cadr(expr)))) return(f); return(NULL); } #define RF_TO_IF(CName, Rfnc) \ static s7_int CName ## _if_r(s7_scheme *sc, s7_pointer **rp) {return(rf_i_1(sc, rp, Rfnc));} \ static s7_if_t CName ## _if(s7_scheme *sc, s7_pointer expr) {return(rf_if_1(sc, expr, CName ## _if_r));} #endif /* gmp */ /* -------- RF_TO_PF -------- */ typedef s7_pointer (*rf_pf_t)(s7_scheme *sc, s7_double x); static s7_pointer rf_p_1(s7_scheme *sc, s7_pointer **p, rf_pf_t fnc) { s7_rf_t f; s7_double x; f = (s7_rf_t)(**p); (*p)++; x = f(sc, p); return(fnc(sc, x)); } #if (!WITH_GMP) static s7_pf_t rf_pf_1(s7_scheme *sc, s7_pointer expr, s7_pf_t f) { if ((is_pair(cdr(expr))) && (is_null(cddr(expr))) && (s7_arg_to_rf(sc, cadr(expr)))) return(f); return(NULL); } #define RF_TO_PF(CName, Pfnc) \ static s7_pointer CName ## _pf_r(s7_scheme *sc, s7_pointer **rp) {return(rf_p_1(sc, rp, Pfnc));} \ static s7_pf_t CName ## _pf(s7_scheme *sc, s7_pointer expr) {return(rf_pf_1(sc, expr, CName ## _pf_r));} /* -------- RF_TO_RF -------- */ typedef s7_double (*rf_rf_t)(s7_scheme *sc, s7_double x); static s7_double rf_rf_1(s7_scheme *sc, s7_pointer **p, rf_rf_t fnc) { s7_rf_t f; s7_double x; f = (s7_rf_t)(**p); (*p)++; x = f(sc, p); return(fnc(sc, x)); } static s7_rf_t rf_1(s7_scheme *sc, s7_pointer expr, s7_rf_t f) { if ((is_pair(cdr(expr))) && (is_null(cddr(expr))) && (s7_arg_to_rf(sc, cadr(expr)))) return(f); return(NULL); } #define RF_TO_RF(CName, Rfnc) \ static s7_double CName ## _rf_r(s7_scheme *sc, s7_pointer **rp) {return(rf_rf_1(sc, rp, Rfnc));} \ static s7_rf_t CName ## _rf(s7_scheme *sc, s7_pointer expr) {return(rf_1(sc, expr, CName ## _rf_r));} #define DIRECT_RF_TO_RF(CName) \ static s7_double CName ## _rf_r(s7_scheme *sc, s7_pointer **p) {s7_rf_t f; s7_double x; f = (s7_rf_t)(**p); (*p)++; x = f(sc, p); return(CName(x));} \ static s7_rf_t CName ## _rf(s7_scheme *sc, s7_pointer expr) {if (s7_arg_to_rf(sc, s7_cadr(expr))) return(CName ## _rf_r); return(NULL);} /* -------- RF2_TO_RF -------- */ typedef s7_double (*rf2_rf_t)(s7_scheme *sc, s7_double x, s7_double y); static s7_double rf2_rf_1(s7_scheme *sc, s7_pointer **p, rf2_rf_t fnc) { s7_rf_t f; s7_double x, y; f = (s7_rf_t)(**p); (*p)++; x = f(sc, p); f = (s7_rf_t)(**p); (*p)++; y = f(sc, p); return(fnc(sc, x, y)); } static s7_rf_t rf_2(s7_scheme *sc, s7_pointer expr, s7_rf_t f) { if ((is_pair(cdr(expr))) && (is_null(cddr(expr))) && (s7_arg_to_rf(sc, cadr(expr))) && (s7_arg_to_rf(sc, caddr(expr)))) return(f); return(NULL); } #define RF2_TO_RF(CName, Rfnc) \ static s7_double CName ## _rf_r2(s7_scheme *sc, s7_pointer **rp) {return(rf2_rf_1(sc, rp, Rfnc));} \ static s7_rf_t CName ## _rf(s7_scheme *sc, s7_pointer expr) {return(rf_2(sc, expr, CName ## _rf_r2));} /* -------- RF_3_TO_RF -------- */ typedef s7_double (*rf3_rf_t)(s7_scheme *sc, s7_double x, s7_double y, s7_double z); static s7_double rf3_rf_1(s7_scheme *sc, s7_pointer **p, rf3_rf_t fnc) { s7_rf_t f; s7_double x, y, z; f = (s7_rf_t)(**p); (*p)++; x = f(sc, p); f = (s7_rf_t)(**p); (*p)++; y = f(sc, p); f = (s7_rf_t)(**p); (*p)++; z = f(sc, p); return(fnc(sc, x, y, z)); } static s7_rf_t rf_3(s7_scheme *sc, s7_pointer expr, s7_rf_t f1, s7_rf_t f2, s7_rf_t f3) { if (!is_pair(cdr(expr))) return(NULL); if (!s7_arg_to_rf(sc, cadr(expr))) return(NULL); if (is_null(cddr(expr))) return(f1); if (!s7_arg_to_rf(sc, caddr(expr))) return(NULL); if (is_null(cdddr(expr))) return(f2); if (!s7_arg_to_rf(sc, cadddr(expr))) return(NULL); if (is_null(cddddr(expr))) return(f3); return(NULL); } #define RF_3_TO_RF(CName, Rfnc1, Rfnc2, Rfnc3) \ static s7_double CName ## _rf_r1(s7_scheme *sc, s7_pointer **rp) {return(rf_rf_1(sc, rp, Rfnc1));} \ static s7_double CName ## _rf_r2(s7_scheme *sc, s7_pointer **rp) {return(rf2_rf_1(sc, rp, Rfnc2));} \ static s7_double CName ## _rf_r3(s7_scheme *sc, s7_pointer **rp) {return(rf3_rf_1(sc, rp, Rfnc3));} \ static s7_rf_t CName ## _rf(s7_scheme *sc, s7_pointer expr) {return(rf_3(sc, expr, CName ## _rf_r1, CName ## _rf_r2, CName ## _rf_r3));} /* -------- R_P_F_TO_PF -------- */ static s7_pf_t rpf_pf_1(s7_scheme *sc, s7_pointer expr, s7_pf_t fnc1, s7_pf_t fnc2, s7_pf_t fnc3) { if ((is_pair(cdr(expr))) && (is_null(cddr(expr)))) { ptr_int loc; loc = rc_loc(sc); if (s7_arg_to_rf(sc, cadr(expr))) return(fnc1); sc->cur_rf->cur = rc_go(sc, loc); if (s7_arg_to_pf(sc, cadr(expr))) return(fnc2); sc->cur_rf->cur = rc_go(sc, loc); if (s7_arg_to_gf(sc, cadr(expr))) return(fnc3); } return(NULL); } #define R_P_F_TO_PF(CName, PFnc1, PFnc2, PFnc3) \ static s7_pointer CName ## _pf_r(s7_scheme *sc, s7_pointer **rp) {return(rf_p_1(sc, rp, PFnc1));} \ static s7_pointer CName ## _pf_p(s7_scheme *sc, s7_pointer **rp) {return(pf_pf_1(sc, rp, PFnc2));} \ static s7_pointer CName ## _pf_g(s7_scheme *sc, s7_pointer **rp) {return(pf_pf_1(sc, rp, PFnc3));} \ static s7_pf_t CName ## _pf(s7_scheme *sc, s7_pointer expr) {return(rpf_pf_1(sc, expr, CName ## _pf_r, CName ## _pf_p, CName ## _pf_g));} #endif /* gmp */ /* -------- XF_TO_PF -------- */ static s7_pf_t xf_pf_1(s7_scheme *sc, s7_pointer expr, s7_pf_t f1, s7_pf_t f2, s7_pf_t f3) { if ((is_pair(cdr(expr))) && (is_null(cddr(expr)))) { ptr_int loc; loc = rc_loc(sc); if (s7_arg_to_if(sc, cadr(expr))) return(f1); sc->cur_rf->cur = rc_go(sc, loc); if (s7_arg_to_rf(sc, cadr(expr))) return(f2); sc->cur_rf->cur = rc_go(sc, loc); if (s7_arg_to_pf(sc, cadr(expr))) return(f3); } return(NULL); } #define XF_TO_PF(CName, PFnc1, PFnc2, PFnc3) \ static s7_pointer CName ## _pf_i(s7_scheme *sc, s7_pointer **rp) {return(if_p_1(sc, rp, PFnc1));} \ static s7_pointer CName ## _pf_r(s7_scheme *sc, s7_pointer **rp) {return(rf_p_1(sc, rp, PFnc2));} \ static s7_pointer CName ## _pf_p(s7_scheme *sc, s7_pointer **rp) {return(pf_pf_1(sc, rp, PFnc3));} \ static s7_pf_t CName ## _pf(s7_scheme *sc, s7_pointer expr) {return(xf_pf_1(sc, expr, CName ## _pf_i, CName ## _pf_r, CName ## _pf_p));} /* -------- XF2_TO_PF -------- */ typedef s7_pointer (*if2_pf_t)(s7_scheme *sc, s7_int x, s7_int y); typedef s7_pointer (*rf2_pf_t)(s7_scheme *sc, s7_double x, s7_double y); static s7_pointer if2_pf_1(s7_scheme *sc, s7_pointer **p, if2_pf_t fnc) { s7_if_t f; s7_int x, y; f = (s7_if_t)(**p); (*p)++; x = f(sc, p); f = (s7_if_t)(**p); (*p)++; y = f(sc, p); return(fnc(sc, x, y)); } static s7_pointer rf2_pf_1(s7_scheme *sc, s7_pointer **p, rf2_pf_t fnc) { s7_rf_t f; s7_double x, y; f = (s7_rf_t)(**p); (*p)++; x = f(sc, p); f = (s7_rf_t)(**p); (*p)++; y = f(sc, p); return(fnc(sc, x, y)); } static s7_pointer rf2_pf_sc(s7_scheme *sc, s7_pointer **p, rf2_pf_t fnc) { s7_pointer xp, yp; (*p)++; xp = slot_value(**p); (*p) += 2; yp = (**p); (*p)++; if ((is_t_real(xp)) && (is_t_real(yp))) return(fnc(sc, real(xp), real(yp))); return(fnc(sc, s7_number_to_real(sc, xp), s7_number_to_real(sc, yp))); } static s7_pf_t xf2_pf_1(s7_scheme *sc, s7_pointer expr, s7_pf_t f1, s7_pf_t f2, s7_pf_t f3, s7_pf_t f4, s7_pf_t f5) { if ((is_pair(cdr(expr))) && (is_pair(cddr(expr))) && (is_null(cdddr(expr)))) { ptr_int loc; s7_pointer a1, a2; a1 = cadr(expr); a2 = caddr(expr); if ((is_symbol(a1)) && (is_symbol(a2))) { a1 = s7_slot(sc, a1); if (!is_slot(a1)) return(NULL); s7_xf_store(sc, a1); a2 = s7_slot(sc, a2); if (!is_slot(a2)) return(NULL); s7_xf_store(sc, a2); return(f5); } loc = rc_loc(sc); if ((s7_arg_to_if(sc, a1)) && (s7_arg_to_if(sc, a2))) return(f1); sc->cur_rf->cur = rc_go(sc, loc); if ((s7_arg_to_rf(sc, a1)) && (s7_arg_to_rf(sc, a2))) return(((is_symbol(a1)) && (is_real(a2))) ? f3 : f2); sc->cur_rf->cur = rc_go(sc, loc); if ((s7_arg_to_pf(sc, a1)) && (s7_arg_to_pf(sc, a2))) return(f4); } return(NULL); } #define XF2_TO_PF(CName, PFnc1, PFnc2, PFnc3) \ static s7_pointer CName ## _pf_i2(s7_scheme *sc, s7_pointer **rp) {return(if2_pf_1(sc, rp, PFnc1));} \ static s7_pointer CName ## _pf_r2(s7_scheme *sc, s7_pointer **rp) {return(rf2_pf_1(sc, rp, PFnc2));} \ static s7_pointer CName ## _pf_r2_sc(s7_scheme *sc, s7_pointer **rp) {return(rf2_pf_sc(sc, rp, PFnc2));} \ static s7_pointer CName ## _pf_p2(s7_scheme *sc, s7_pointer **rp) {return(pf2_pf_1(sc, rp, PFnc3));} \ static s7_pointer CName ## _pf_ss(s7_scheme *sc, s7_pointer **rp) {return(pf2_pf_ss(sc, rp, PFnc3));} \ static s7_pf_t CName ## _pf(s7_scheme *sc, s7_pointer expr) \ {\ return(xf2_pf_1(sc, expr, CName ## _pf_i2, CName ## _pf_r2, CName ## _pf_r2_sc, CName ## _pf_p2, CName ## _pf_ss)); \ } #if WITH_OPTIMIZATION static s7_pointer if_pf_xx(s7_scheme *sc, s7_pointer **p) { s7_pf_t test, t; s7_pointer val; ptr_int e1; test = (s7_pf_t)(**p); (*p)++; t = (s7_pf_t)(**p); (*p)++; e1 = (ptr_int)(**p); (*p)++; val = test(sc, p); if (val != sc->F) val = t(sc, p); else val = sc->UNSPECIFIED; (*p) = rc_go(sc, e1); return(val); } static s7_pointer if_pf_not_xx(s7_scheme *sc, s7_pointer **p) { s7_pf_t test, t; s7_pointer val; ptr_int e1; test = (s7_pf_t)(**p); (*p)++; t = (s7_pf_t)(**p); (*p)++; e1 = (ptr_int)(**p); (*p)++; val = test(sc, p); if (val == sc->F) val = t(sc, p); else val = sc->UNSPECIFIED; (*p) = rc_go(sc, e1); return(val); } #if (!WITH_GMP) static s7_pointer equal_p2(s7_scheme *sc, s7_pointer **p); #endif static s7_pointer c_equal_2(s7_scheme *sc, s7_pointer x, s7_pointer y); static s7_pointer if_pf_not_equal_2(s7_scheme *sc, s7_pointer **p) { s7_pf_t t, eq2; s7_pointer val, x, y; ptr_int e1; (*p)++; t = (s7_pf_t)(**p); (*p)++; e1 = (ptr_int)(**p); (*p)++; eq2 = (s7_pf_t)(**p); (*p)++; x = eq2(sc, p); eq2 = (s7_pf_t)(**p); (*p)++; y = eq2(sc, p); if (c_equal_2(sc, x, y) == sc->F) val = t(sc, p); else val = sc->UNSPECIFIED; (*p) = rc_go(sc, e1); return(val); } static s7_pointer if_pf_xxx(s7_scheme *sc, s7_pointer **p) { s7_pointer x; s7_pf_t r1, r2; s7_pf_t pf; s7_pointer val; ptr_int e1, e2; pf = (s7_pf_t)(**p); (*p)++; r1 = (s7_pf_t)(**p); (*p)++; e1 = (ptr_int)(**p); (*p)++; r2 = (s7_pf_t)(**p); (*p)++; e2 = (ptr_int)(**p); (*p)++; val = pf(sc, p); if (val != sc->F) { x = r1(sc, p); (*p) = rc_go(sc, e2); } else { (*p) = rc_go(sc, e1); x = r2(sc, p); } return(x); } static s7_pf_t if_pf(s7_scheme *sc, s7_pointer expr) { s7_pointer test, t, f = NULL; s7_int test_loc, t_loc, f_loc = 0, e1_loc, e2_loc = 0; bool not_case = false; ptr_int loc; xf_t *rc; if ((is_null(cdr(expr))) || (is_null(cddr(expr)))) return(NULL); test = cadr(expr); if ((is_pair(test)) && (car(test) == sc->NOT)) { not_case = true; test = cadr(test); } t = caddr(expr); xf_init(5); xf_save_loc3(test_loc, t_loc, e1_loc); if (is_pair(cdddr(expr))) { f = cadddr(expr); xf_save_loc2(f_loc, e2_loc); } if (!arg_to_pf(sc, test, test_loc)) return(NULL); loc = rc_loc(sc); if (!arg_to_pf(sc, t, t_loc)) { sc->cur_rf->cur = rc_go(sc, loc); if (!arg_to_if(sc, t, t_loc)) return(NULL); } xf_store_at(e1_loc, (s7_pointer)rc_loc(sc)); if (f) { if (!arg_to_pf(sc, f, f_loc)) return(NULL); xf_store_at(e2_loc, (s7_pointer)rc_loc(sc)); } if (!f) { if (not_case) { #if (!WITH_GMP) if ((s7_pointer)equal_p2 == sc->cur_rf->data[test_loc]) return(if_pf_not_equal_2); #endif return(if_pf_not_xx); } return(if_pf_xx); } return(if_pf_xxx); } static s7_double if_rf_xxx(s7_scheme *sc, s7_pointer **p) { s7_double x; s7_rf_t r1, r2; s7_pf_t pf; s7_pointer val; ptr_int e1, e2; pf = (s7_pf_t)(**p); (*p)++; r1 = (s7_rf_t)(**p); (*p)++; r2 = (s7_rf_t)(**p); (*p)++; e1 = (ptr_int)(**p); (*p)++; e2 = (ptr_int)(**p); (*p)++; val = pf(sc, p); if (val != sc->F) { x = r1(sc, p); (*p) = rc_go(sc, e2); } else { (*p) = rc_go(sc, e1); x = r2(sc, p); } return(x); } static s7_rf_t if_rf(s7_scheme *sc, s7_pointer expr) { s7_pointer test, t, f; s7_int test_loc, t_loc, f_loc = 0, e1_loc = 0, e2_loc; xf_t *rc; if ((is_null(cdr(expr))) || (is_null(cddr(expr))) || (is_null(cdddr(expr)))) return(NULL); test = cadr(expr); t = caddr(expr); f = cadddr(expr); xf_init(5); xf_save_loc3(test_loc, t_loc, f_loc); xf_save_loc2(e1_loc, e2_loc); if (!arg_to_pf(sc, test, test_loc)) return(NULL); if (!arg_to_rf(sc, t, t_loc)) return(NULL); xf_store_at(e1_loc, (s7_pointer)rc_loc(sc)); if (!arg_to_rf(sc, f, f_loc)) return(NULL); xf_store_at(e2_loc, (s7_pointer)rc_loc(sc)); return(if_rf_xxx); } static s7_pointer quote_pf_s(s7_scheme *sc, s7_pointer **p) { s7_pointer s; s = **p; (*p)++; return(s); } static s7_pf_t quote_pf(s7_scheme *sc, s7_pointer expr) { if (is_symbol(cadr(expr))) { xf_t *rc; xf_init(1); xf_store(cadr(expr)); return(quote_pf_s); } return(NULL); } static s7_pointer or_pf_xx(s7_scheme *sc, s7_pointer **p) { s7_pf_t pf1, pf2; ptr_int e1; s7_pointer val; pf1 = (s7_pf_t)(**p); (*p)++; pf2 = (s7_pf_t)(**p); (*p)++; e1 = (ptr_int)(**p); (*p)++; val = pf1(sc, p); if (val != sc->F) { (*p) = rc_go(sc, e1); return(val); } return(pf2(sc, p)); } static s7_pf_t or_pf(s7_scheme *sc, s7_pointer expr) { int len; len = s7_list_length(sc, expr); if (len == 3) { int loc1, loc2, eloc; xf_t *rc; xf_init(3); xf_save_loc3(loc1, loc2, eloc); if (!arg_to_pf(sc, cadr(expr), loc1)) return(NULL); if (!arg_to_pf(sc, caddr(expr), loc2)) return(NULL); xf_store_at(eloc, (s7_pointer)rc_loc(sc)); return(or_pf_xx); } return(NULL); } static s7_pointer and_pf_xx(s7_scheme *sc, s7_pointer **p) { s7_pf_t pf1, pf2; ptr_int e1; pf1 = (s7_pf_t)(**p); (*p)++; pf2 = (s7_pf_t)(**p); (*p)++; e1 = (ptr_int)(**p); (*p)++; if (pf1(sc, p) == sc->F) { (*p) = rc_go(sc, e1); return(sc->F); } return(pf2(sc, p)); } static s7_pf_t and_pf(s7_scheme *sc, s7_pointer expr) { int len; len = s7_list_length(sc, expr); if (len == 3) { s7_int loc1, loc2, eloc; xf_t *rc; xf_init(3); xf_save_loc3(loc1, loc2, eloc); if (!arg_to_pf(sc, cadr(expr), loc1)) return(NULL); if (!arg_to_pf(sc, caddr(expr), loc2)) return(NULL); xf_store_at(eloc, (s7_pointer)rc_loc(sc)); return(and_pf_xx); } return(NULL); } #endif /* -------------------------------- continuations and gotos -------------------------------- */ static s7_pointer g_is_continuation(s7_scheme *sc, s7_pointer args) { #define H_is_continuation "(continuation? obj) returns #t if obj is a continuation" #define Q_is_continuation pl_bt check_boolean_method(sc, is_continuation, sc->IS_CONTINUATION, args); /* is this the right thing? It returns #f for call-with-exit ("goto") because * that form of continuation can't continue (via a jump back to its context). * how to recognize the call-with-exit function? "goto" is an internal name. */ } static s7_pointer protected_list_copy(s7_scheme *sc, s7_pointer a) { s7_pointer slow, fast, p; sc->w = cons(sc, car(a), sc->NIL); p = sc->w; slow = fast = cdr(a); while (true) { if (!is_pair(fast)) { if (is_null(fast)) return(sc->w); cdr(p) = fast; return(sc->w); } cdr(p) = cons(sc, car(fast), sc->NIL); p = cdr(p); fast = cdr(fast); if (!is_pair(fast)) { if (is_null(fast)) return(sc->w); cdr(p) = fast; return(sc->w); } /* if unrolled further, it's a lot slower? */ cdr(p) = cons(sc, car(fast), sc->NIL); p = cdr(p); fast = cdr(fast); slow = cdr(slow); if (fast == slow) { /* try to preserve the original cyclic structure */ s7_pointer p1, f1, p2, f2; set_match_pair(a); for (p1 = sc->w, f1 = a; !(is_matched_pair(cdr(f1))); f1 = cdr(f1), p1 = cdr(p1)) set_match_pair(f1); for (p2 = sc->w, f2 = a; cdr(f1) != f2; f2 = cdr(f2), p2 = cdr(p2)) clear_match_pair(f2); for (f1 = f2; is_pair(f1); f1 = cdr(f1), f2 = cdr(f2)) { clear_match_pair(f1); f1 = cdr(f1); clear_match_pair(f1); if (f1 == f2) break; } if (is_null(p1)) cdr(p2) = p2; else cdr(p1) = p2; return(sc->w); } } return(sc->w); } static s7_pointer copy_counter(s7_scheme *sc, s7_pointer obj) { s7_pointer nobj; new_cell(sc, nobj, T_COUNTER); counter_result(nobj) = counter_result(obj); counter_list(nobj) = counter_list(obj); counter_capture(nobj) = counter_capture(obj); counter_set_let(nobj, counter_let(obj)); return(nobj); } static s7_pointer copy_stack(s7_scheme *sc, s7_pointer old_v, int top) { #define CC_INITIAL_STACK_SIZE 256 /* 128 is too small here */ int i, len; s7_pointer new_v; s7_pointer *nv, *ov; /* stacks can grow temporarily, so sc->stack_size grows, but we don't normally need all that * leftover space here, so choose the original stack size if it's smaller. */ len = vector_length(old_v); if (len > CC_INITIAL_STACK_SIZE) { if (top < CC_INITIAL_STACK_SIZE / 4) len = CC_INITIAL_STACK_SIZE; } else { if (len < CC_INITIAL_STACK_SIZE) len = CC_INITIAL_STACK_SIZE; } if ((int)(sc->free_heap_top - sc->free_heap) < (int)(sc->heap_size / 4)) gc(sc); /* this gc call is needed if there are lots of call/cc's -- by pure bad luck * we can end up hitting the end of the gc free list time after time while * in successive copy_stack's below, causing s7 to core up until it runs out of memory. */ new_v = make_vector_1(sc, len, NOT_FILLED, T_VECTOR); set_type(new_v, T_STACK); temp_stack_top(new_v) = top; nv = vector_elements(new_v); ov = vector_elements(old_v); if (len > 0) memcpy((void *)nv, (void *)ov, len * sizeof(s7_pointer)); s7_gc_on(sc, false); #if DEBUGGING check_types = false; #endif for (i = 2; i < top; i += 4) { s7_pointer p; p = ov[i]; /* args */ if (is_pair(p)) /* args need not be a list (it can be a port or #f, etc) */ nv[i] = protected_list_copy(sc, p); /* args (copy is needed -- see s7test.scm) */ /* lst can be dotted or circular here. The circular list only happens in a case like: * (dynamic-wind (lambda () (eq? (let ((lst (cons 1 2))) (set-cdr! lst lst) lst) (call/cc (lambda (k) k)))) (lambda () #f) (lambda () #f)) */ else { if (is_counter(p)) /* these can only occur in this context */ nv[i] = copy_counter(sc, p); } } #if DEBUGGING check_types = true; #endif s7_gc_on(sc, true); return(new_v); } static s7_pointer make_goto(s7_scheme *sc) { s7_pointer x; new_cell(sc, x, T_GOTO | T_PROCEDURE); call_exit_goto_loc(x) = s7_stack_top(sc); call_exit_op_loc(x) = (int)(sc->op_stack_now - sc->op_stack); call_exit_active(x) = true; return(x); } static s7_pointer *copy_op_stack(s7_scheme *sc) { int len; s7_pointer *ops; ops = (s7_pointer *)malloc(sc->op_stack_size * sizeof(s7_pointer)); len = (int)(sc->op_stack_now - sc->op_stack); if (len > 0) memcpy((void *)ops, (void *)(sc->op_stack), len * sizeof(s7_pointer)); return(ops); } /* (with-baffle . body) calls body guaranteeing that there can be no jumps into the * middle of it from outside -- no outer evaluation of a continuation can jump across this * barrier: The flip-side of call-with-exit. * It sets a T_BAFFLE var in a new env, that has a unique key. Call/cc then always * checks the env chain for any such variable, saving the localmost. Apply of a continuation * looks for such a saved variable, if none, go ahead, else check the current env (before the * jump) for that variable. If none, error, else go ahead. This is different from a delimited * continuation which simply delimits the extent of the continuation (why not use lambda?) -- we want to block it * from coming at us from some unknown place. */ static s7_pointer make_baffle(s7_scheme *sc) { s7_pointer x; new_cell(sc, x, T_BAFFLE); baffle_key(x) = sc->baffle_ctr++; return(x); } static bool find_baffle(s7_scheme *sc, int key) { /* search backwards through sc->envir for sc->BAFFLE with key as value */ s7_pointer x, y; for (x = sc->envir; is_let(x); x = outlet(x)) for (y = let_slots(x); is_slot(y); y = next_slot(y)) if ((slot_symbol(y) == sc->BAFFLE) && (baffle_key(slot_value(y)) == key)) return(true); if ((is_slot(global_slot(sc->BAFFLE))) && (is_baffle(slot_value(global_slot(sc->BAFFLE))))) return(baffle_key(slot_value(global_slot(sc->BAFFLE))) == key); return(false); } static int find_any_baffle(s7_scheme *sc) { /* search backwards through sc->envir for any sc->BAFFLE */ if (sc->baffle_ctr > 0) { s7_pointer x, y; for (x = sc->envir; is_let(x); x = outlet(x)) for (y = let_slots(x); is_slot(y); y = next_slot(y)) if (slot_symbol(y) == sc->BAFFLE) return(baffle_key(slot_value(y))); if ((is_slot(global_slot(sc->BAFFLE))) && (is_baffle(slot_value(global_slot(sc->BAFFLE))))) return(baffle_key(slot_value(global_slot(sc->BAFFLE)))); } return(-1); } s7_pointer s7_make_continuation(s7_scheme *sc) { s7_pointer x, stack; int loc; loc = s7_stack_top(sc); stack = copy_stack(sc, sc->stack, loc); sc->temp8 = stack; new_cell(sc, x, T_CONTINUATION | T_PROCEDURE); continuation_data(x) = (continuation_t *)malloc(sizeof(continuation_t)); continuation_stack(x) = stack; continuation_stack_size(x) = vector_length(continuation_stack(x)); /* copy_stack can return a smaller stack than the current one */ continuation_stack_start(x) = vector_elements(continuation_stack(x)); continuation_stack_end(x) = (s7_pointer *)(continuation_stack_start(x) + loc); continuation_op_stack(x) = copy_op_stack(sc); /* no heap allocation here */ continuation_op_loc(x) = (int)(sc->op_stack_now - sc->op_stack); continuation_op_size(x) = sc->op_stack_size; continuation_key(x) = find_any_baffle(sc); add_continuation(sc, x); return(x); } static bool check_for_dynamic_winds(s7_scheme *sc, s7_pointer c) { int i, s_base = 0, c_base = -1; opcode_t op; for (i = s7_stack_top(sc) - 1; i > 0; i -= 4) { op = stack_op(sc->stack, i); switch (op) { case OP_DYNAMIC_WIND: { s7_pointer x; int j; x = stack_code(sc->stack, i); for (j = 3; j < continuation_stack_top(c); j += 4) if ((stack_op(continuation_stack(c), j) == OP_DYNAMIC_WIND) && (x == stack_code(continuation_stack(c), j))) { s_base = i; c_base = j; break; } if (s_base != 0) break; if (dynamic_wind_state(x) == DWIND_BODY) { dynamic_wind_state(x) = DWIND_FINISH; if (dynamic_wind_out(x) != sc->F) { push_stack(sc, OP_EVAL_DONE, sc->args, sc->code); sc->args = sc->NIL; sc->code = dynamic_wind_out(x); eval(sc, OP_APPLY); } } } break; case OP_BARRIER: if (i > continuation_stack_top(c)) /* otherwise it's some unproblematic outer eval-string? */ return(false); /* but what if we've already evaluated a dynamic-wind closer? */ break; case OP_DEACTIVATE_GOTO: /* here we're jumping out of an unrelated call-with-exit block */ if (i > continuation_stack_top(c)) call_exit_active(stack_args(sc->stack, i)) = false; break; default: break; } } for (i = c_base + 4; i < continuation_stack_top(c); i += 4) { op = stack_op(continuation_stack(c), i); if (op == OP_DYNAMIC_WIND) { s7_pointer x; x = stack_code(continuation_stack(c), i); if (dynamic_wind_in(x) != sc->F) { /* this can cause an infinite loop if the call/cc is trying to jump back into * a dynamic-wind init function -- it's even possible to trick with-baffle! * I can't find any fool-proof way to catch this problem. */ push_stack(sc, OP_EVAL_DONE, sc->args, sc->code); sc->args = sc->NIL; sc->code = dynamic_wind_in(x); eval(sc, OP_APPLY); } dynamic_wind_state(x) = DWIND_BODY; } else { if (op == OP_DEACTIVATE_GOTO) call_exit_active(stack_args(continuation_stack(c), i)) = true; } } return(true); } static bool call_with_current_continuation(s7_scheme *sc) { s7_pointer c; c = sc->code; /* check for (baffle ...) blocking the current attempt to continue */ if ((continuation_key(c) >= 0) && (!(find_baffle(sc, continuation_key(c))))) /* should this raise an error? */ return(false); if (!check_for_dynamic_winds(sc, c)) /* if OP_BARRIER on stack deeper than continuation top(?), but can this happen? (it doesn't in s7test) */ return(true); /* we push_stack sc->code before calling an embedded eval above, so sc->code should still be c here, etc */ sc->stack = copy_stack(sc, continuation_stack(c), continuation_stack_top(c)); sc->stack_size = continuation_stack_size(c); sc->stack_start = vector_elements(sc->stack); sc->stack_end = (s7_pointer *)(sc->stack_start + continuation_stack_top(c)); sc->stack_resize_trigger = (s7_pointer *)(sc->stack_start + sc->stack_size / 2); { int i, top; top = continuation_op_loc(c); sc->op_stack_now = (s7_pointer *)(sc->op_stack + top); sc->op_stack_size = continuation_op_size(c); sc->op_stack_end = (s7_pointer *)(sc->op_stack + sc->op_stack_size); for (i = 0; i < top; i++) sc->op_stack[i] = continuation_op_stack(c)[i]; } if (is_null(sc->args)) sc->value = sc->NIL; else { if (is_null(cdr(sc->args))) sc->value = car(sc->args); else sc->value = splice_in_values(sc, sc->args); } return(true); } static void call_with_exit(s7_scheme *sc) { int i, new_stack_top, quit = 0; if (!call_exit_active(sc->code)) { static s7_pointer call_with_exit_error = NULL; if (!call_with_exit_error) call_with_exit_error = s7_make_permanent_string("call-with-exit escape procedure called outside its block"); s7_error(sc, sc->INVALID_ESCAPE_FUNCTION, set_elist_1(sc, call_with_exit_error)); } call_exit_active(sc->code) = false; new_stack_top = call_exit_goto_loc(sc->code); sc->op_stack_now = (s7_pointer *)(sc->op_stack + call_exit_op_loc(sc->code)); /* look for dynamic-wind in the stack section that we are jumping out of */ for (i = s7_stack_top(sc) - 1; i > new_stack_top; i -= 4) { opcode_t op; op = stack_op(sc->stack, i); switch (op) { case OP_DYNAMIC_WIND: { s7_pointer lx; lx = stack_code(sc->stack, i); if (dynamic_wind_state(lx) == DWIND_BODY) { dynamic_wind_state(lx) = DWIND_FINISH; if (dynamic_wind_out(lx) != sc->F) { push_stack(sc, OP_EVAL_DONE, sc->args, sc->code); sc->args = sc->NIL; sc->code = dynamic_wind_out(lx); eval(sc, OP_APPLY); } } } break; case OP_EVAL_STRING_2: s7_close_input_port(sc, sc->input_port); pop_input_port(sc); break; case OP_BARRIER: /* oops -- we almost certainly went too far */ return; case OP_DEACTIVATE_GOTO: /* here we're jumping into an unrelated call-with-exit block */ call_exit_active(stack_args(sc->stack, i)) = false; break; /* call/cc does not close files, but I think call-with-exit should */ case OP_GET_OUTPUT_STRING_1: case OP_UNWIND_OUTPUT: { s7_pointer x; x = stack_code(sc->stack, i); /* "code" = port that we opened */ s7_close_output_port(sc, x); x = stack_args(sc->stack, i); /* "args" = port that we shadowed, if not #f */ if (x != sc->F) sc->output_port = x; } break; case OP_UNWIND_INPUT: s7_close_input_port(sc, stack_code(sc->stack, i)); /* "code" = port that we opened */ sc->input_port = stack_args(sc->stack, i); /* "args" = port that we shadowed */ break; case OP_EVAL_DONE: /* goto called in a method -- put off the inner eval return(s) until we clean up the stack */ quit++; break; default: break; } } sc->stack_end = (s7_pointer *)(sc->stack_start + new_stack_top); /* the return value should have an implicit values call, just as in call/cc */ if (is_null(sc->args)) sc->value = sc->NIL; else { if (is_null(cdr(sc->args))) sc->value = car(sc->args); else sc->value = splice_in_values(sc, sc->args); } if (quit > 0) { if (sc->longjmp_ok) { pop_stack(sc); longjmp(sc->goto_start, 1); } for (i = 0; i < quit; i++) push_stack(sc, OP_EVAL_DONE, sc->NIL, sc->NIL); } } static s7_pointer g_call_cc(s7_scheme *sc, s7_pointer args) { #define H_call_cc "(call-with-current-continuation func) is always a mistake!" #define Q_call_cc s7_make_signature(sc, 2, sc->VALUES, sc->IS_PROCEDURE) /* I think the intent is that sc->VALUES as the proc-sig return type indicates multiple values are possible (otherwise use #t). */ s7_pointer p; p = car(args); /* this is the procedure passed to call/cc */ if (!is_procedure(p)) /* this includes continuations */ { check_two_methods(sc, p, sc->CALL_CC, sc->CALL_WITH_CURRENT_CONTINUATION, args); return(simple_wrong_type_argument_with_type(sc, sc->CALL_CC, p, A_PROCEDURE)); } if (!s7_is_aritable(sc, p, 1)) return(s7_error(sc, sc->WRONG_TYPE_ARG, set_elist_2(sc, make_string_wrapper(sc, "call/cc procedure, ~A, should take one argument"), p))); sc->w = s7_make_continuation(sc); push_stack(sc, OP_APPLY, list_1(sc, sc->w), p); sc->w = sc->NIL; return(sc->NIL); } /* we can't naively optimize call/cc to call-with-exit if the continuation is only * used as a function in the call/cc body because it might (for example) be wrapped * in a lambda form that is being exported. See b-func in s7test for an example. */ static s7_pointer g_call_with_exit(s7_scheme *sc, s7_pointer args) { #define H_call_with_exit "(call-with-exit func) is call/cc without the ability to jump back into a previous computation." #define Q_call_with_exit s7_make_signature(sc, 2, sc->VALUES, sc->IS_PROCEDURE) s7_pointer p, x; /* (call-with-exit (lambda (return) ...)) */ p = car(args); if (!is_procedure(p)) /* this includes continuations */ method_or_bust_with_type(sc, p, sc->CALL_WITH_EXIT, args, A_PROCEDURE, 0); x = make_goto(sc); push_stack(sc, OP_DEACTIVATE_GOTO, x, p); /* this means call-with-exit is not tail-recursive */ push_stack(sc, OP_APPLY, cons_unchecked(sc, x, sc->NIL), p); /* if the lambda body calls the argument as a function, * it is applied to its arguments, apply notices that it is a goto, and... * * (conceptually...) sc->stack_top = call_exit_goto_loc(sc->code); * s_pop(sc, (is_not_null(sc->args)) ? car(sc->args) : sc->NIL); * * which jumps to the point of the goto returning car(args). * * There is one gotcha: we can't jump back in from outside, so if the caller saves the goto * and tries to invoke it outside the call-with-exit block, we have to * make sure it triggers an error. So, if the escape is called, it then * deactivates itself. Otherwise the block returns, we pop to OP_DEACTIVATE_GOTO, * and it finds the goto in sc->args. * Even worse: * (let ((cc #f)) (call-with-exit (lambda (c3) (call/cc (lambda (ret) (set! cc ret))) (c3))) (cc)) * * where we jump back into a call-with-exit body via call/cc, the goto has to be * re-established. * * I think call-with-exit could be based on catch, but it's a simpler notion, * and certainly at the source level it is easier to read. */ return(sc->NIL); } /* -------------------------------- numbers -------------------------------- */ #if WITH_GMP static char *big_number_to_string_with_radix(s7_pointer p, int radix, int width, int *nlen, use_write_t use_write); static bool big_numbers_are_eqv(s7_pointer a, s7_pointer b); static s7_pointer string_to_either_integer(s7_scheme *sc, const char *str, int radix); static s7_pointer string_to_either_ratio(s7_scheme *sc, const char *nstr, const char *dstr, int radix); static s7_pointer string_to_either_real(s7_scheme *sc, const char *str, int radix); static s7_pointer string_to_either_complex(s7_scheme *sc, char *q, char *slash1, char *ex1, bool has_dec_point1, char *plus, char *slash2, char *ex2, bool has_dec_point2, int radix, int has_plus_or_minus); static s7_pointer big_add(s7_scheme *sc, s7_pointer args); static s7_pointer big_subtract(s7_scheme *sc, s7_pointer args); static s7_pointer big_multiply(s7_scheme *sc, s7_pointer args); static s7_pointer big_divide(s7_scheme *sc, s7_pointer args); static s7_pointer big_random(s7_scheme *sc, s7_pointer args); static s7_pointer s7_int_to_big_integer(s7_scheme *sc, s7_int val); static s7_pointer s7_ratio_to_big_ratio(s7_scheme *sc, s7_int num, s7_int den); static s7_pointer s7_number_to_big_real(s7_scheme *sc, s7_pointer p); static s7_pointer promote_number(s7_scheme *sc, int type, s7_pointer x); static s7_pointer big_equal(s7_scheme *sc, s7_pointer args); static s7_pointer big_negate(s7_scheme *sc, s7_pointer args); static s7_pointer big_invert(s7_scheme *sc, s7_pointer args); #if (!WITH_PURE_S7) static s7_pointer big_inexact_to_exact(s7_scheme *sc, s7_pointer args); static s7_pointer big_exact_to_inexact(s7_scheme *sc, s7_pointer args); #endif static s7_pointer mpz_to_big_integer(s7_scheme *sc, mpz_t val); static s7_pointer mpq_to_big_ratio(s7_scheme *sc, mpq_t val); static s7_pointer mpfr_to_big_real(s7_scheme *sc, mpfr_t val); static s7_pointer mpc_to_big_complex(s7_scheme *sc, mpc_t val); #endif #define HAVE_OVERFLOW_CHECKS ((defined(__clang__) && ((__clang_major__ > 3) || (__clang_major__ == 3 && __clang_minor__ >= 4))) || \ (defined(__GNUC__) && __GNUC__ >= 5)) #if (defined(__clang__) && ((__clang_major__ > 3) || (__clang_major__ == 3 && __clang_minor__ >= 4))) #define subtract_overflow(A, B, C) __builtin_ssubll_overflow(A, B, C) #define add_overflow(A, B, C) __builtin_saddll_overflow(A, B, C) #define multiply_overflow(A, B, C) __builtin_smulll_overflow(A, B, C) #define int_subtract_overflow(A, B, C) __builtin_ssub_overflow(A, B, C) #define int_add_overflow(A, B, C) __builtin_sadd_overflow(A, B, C) #define int_multiply_overflow(A, B, C) __builtin_smul_overflow(A, B, C) #else #if (defined(__GNUC__) && __GNUC__ >= 5) #define subtract_overflow(A, B, C) __builtin_sub_overflow(A, B, C) #define add_overflow(A, B, C) __builtin_add_overflow(A, B, C) #define multiply_overflow(A, B, C) __builtin_mul_overflow(A, B, C) #define int_subtract_overflow(A, B, C) __builtin_sub_overflow(A, B, C) #define int_add_overflow(A, B, C) __builtin_add_overflow(A, B, C) #define int_multiply_overflow(A, B, C) __builtin_mul_overflow(A, B, C) #endif #endif #define s7_int_abs(x) ((x) >= 0 ? (x) : -(x)) /* can't use abs even in gcc -- it doesn't work with long long ints! */ #if (!__NetBSD__) #define s7_fabsl(X) fabsl(X) #else static double s7_fabsl(long double x) {if (x < 0.0) return(-x); return(x);} #endif static bool is_NaN(s7_double x) {return(x != x);} /* callgrind says this is faster than isnan, I think (very confusing data...) */ #if defined(__sun) && defined(__SVR4) static bool is_inf(s7_double x) {return((x == x) && (is_NaN(x - x)));} /* there's no isinf in Solaris */ #else #if (!MS_WINDOWS) #if __cplusplus #define is_inf(x) std::isinf(x) #else #define is_inf(x) isinf(x) #endif #else static bool is_inf(s7_double x) {return((x == x) && (is_NaN(x - x)));} /* Another possibility: (x * 0) != 0 */ /* in MS C, we need to provide inverse hyperbolic trig funcs and cbrt */ static double asinh(double x) {return(log(x + sqrt(1.0 + x * x)));} static double acosh(double x) {return(log(x + sqrt(x * x - 1.0)));} /* perhaps less prone to numerical troubles (untested): 2.0 * log(sqrt(0.5 * (x + 1.0)) + sqrt(0.5 * (x - 1.0))) */ static double atanh(double x) {return(log((1.0 + x) / (1.0 - x)) / 2.0);} static double cbrt(double x) {if (x >= 0.0) return(pow(x, 1.0 / 3.0)); return(-pow(-x, 1.0 / 3.0));} #endif /* windows */ #endif /* sun */ /* for g_log, we also need round. this version is from stackoverflow, see also round_per_R5RS below */ double s7_round(double number) {return((number < 0.0) ? ceil(number - 0.5) : floor(number + 0.5));} #if HAVE_COMPLEX_NUMBERS #if __cplusplus #define _Complex_I (complex(0.0, 1.0)) #define creal(x) Real(x) #define cimag(x) Imag(x) #define carg(x) arg(x) #define cabs(x) abs(x) #define csqrt(x) sqrt(x) #define cpow(x, y) pow(x, y) #define clog(x) log(x) #define cexp(x) exp(x) #define csin(x) sin(x) #define ccos(x) cos(x) #define csinh(x) sinh(x) #define ccosh(x) cosh(x) #else typedef double complex s7_complex; #endif #if (!HAVE_COMPLEX_TRIG) #if (__cplusplus) static s7_complex ctan(s7_complex z) {return(csin(z) / ccos(z));} static s7_complex ctanh(s7_complex z) {return(csinh(z) / ccosh(z));} static s7_complex casin(s7_complex z) {return(-_Complex_I * clog(_Complex_I * z + csqrt(1.0 - z * z)));} static s7_complex cacos(s7_complex z) {return(-_Complex_I * clog(z + _Complex_I * csqrt(1.0 - z * z)));} static s7_complex catan(s7_complex z) {return(_Complex_I * clog((_Complex_I + z) / (_Complex_I - z)) / 2.0);} static s7_complex casinh(s7_complex z) {return(clog(z + csqrt(1.0 + z * z)));} static s7_complex cacosh(s7_complex z) {return(clog(z + csqrt(z * z - 1.0)));} static s7_complex catanh(s7_complex z) {return(clog((1.0 + z) / (1.0 - z)) / 2.0);} #else /* still not in FreeBSD! */ static s7_complex clog(s7_complex z) {return(log(fabs(cabs(z))) + carg(z) * _Complex_I);} static s7_complex cpow(s7_complex x, s7_complex y) { s7_double r = cabs(x); s7_double theta = carg(x); s7_double yre = creal(y); s7_double yim = cimag(y); s7_double nr = exp(yre * log(r) - yim * theta); s7_double ntheta = yre * theta + yim * log(r); return(nr * cos(ntheta) + (nr * sin(ntheta)) * _Complex_I); /* make-polar */ } #if (!defined(__FreeBSD__)) || (__FreeBSD__ < 9) /* untested -- this orignally looked at __FreeBSD_version which apparently no longer exists */ static s7_complex cexp(s7_complex z) {return(exp(creal(z)) * cos(cimag(z)) + (exp(creal(z)) * sin(cimag(z))) * _Complex_I);} #endif #if (!defined(__FreeBSD__)) || (__FreeBSD__ < 10) static s7_complex csin(s7_complex z) {return(sin(creal(z)) * cosh(cimag(z)) + (cos(creal(z)) * sinh(cimag(z))) * _Complex_I);} static s7_complex ccos(s7_complex z) {return(cos(creal(z)) * cosh(cimag(z)) + (-sin(creal(z)) * sinh(cimag(z))) * _Complex_I);} static s7_complex csinh(s7_complex z) {return(sinh(creal(z)) * cos(cimag(z)) + (cosh(creal(z)) * sin(cimag(z))) * _Complex_I);} static s7_complex ccosh(s7_complex z) {return(cosh(creal(z)) * cos(cimag(z)) + (sinh(creal(z)) * sin(cimag(z))) * _Complex_I);} static s7_complex ctan(s7_complex z) {return(csin(z) / ccos(z));} static s7_complex ctanh(s7_complex z) {return(csinh(z) / ccosh(z));} static s7_complex casin(s7_complex z) {return(-_Complex_I * clog(_Complex_I * z + csqrt(1.0 - z * z)));} static s7_complex cacos(s7_complex z) {return(-_Complex_I * clog(z + _Complex_I * csqrt(1.0 - z * z)));} static s7_complex catan(s7_complex z) {return(_Complex_I * clog((_Complex_I + z) / (_Complex_I - z)) / 2.0);} static s7_complex catanh(s7_complex z) {return(clog((1.0 + z) / (1.0 - z)) / 2.0);} static s7_complex casinh(s7_complex z) {return(clog(z + csqrt(1.0 + z * z)));} static s7_complex cacosh(s7_complex z) {return(clog(z + csqrt(z * z - 1.0)));} /* perhaps less prone to numerical troubles (untested): 2.0 * clog(csqrt(0.5 * (z + 1.0)) + csqrt(0.5 * (z - 1.0))) */ #endif /* not FreeBSD 10 */ #endif /* not c++ */ #endif /* not HAVE_COMPLEX_TRIG */ #else /* not HAVE_COMPLEX_NUMBERS */ typedef double s7_complex; #define _Complex_I 1 #define creal(x) x #define cimag(x) x #define csin(x) sin(x) #define casin(x) x #define ccos(x) cos(x) #define cacos(x) x #define ctan(x) x #define catan(x) x #define csinh(x) x #define casinh(x) x #define ccosh(x) x #define cacosh(x) x #define ctanh(x) x #define catanh(x) x #define cexp(x) exp(x) #define cpow(x, y) pow(x, y) #define clog(x) log(x) #define csqrt(x) sqrt(x) #define conj(x) x #endif #ifdef __OpenBSD__ /* openbsd's builtin versions of these functions are not usable */ static s7_complex catanh_1(s7_complex z) {return(clog((1.0 + z) / (1.0 - z)) / 2.0);} static s7_complex casinh_1(s7_complex z) {return(clog(z + csqrt(1.0 + z * z)));} static s7_complex cacosh_1(s7_complex z) {return(clog(z + csqrt(z * z - 1.0)));} #endif #ifdef __NetBSD__ static s7_complex catanh_1(s7_complex z) {return(clog((1.0 + z) / (1.0 - z)) / 2.0);} static s7_complex casinh_1(s7_complex z) {return(clog(z + csqrt(1.0 + z * z)));} #endif bool s7_is_number(s7_pointer p) { #if WITH_GMP return((is_number(p)) || (is_big_number(p))); #else return(is_number(p)); #endif } bool s7_is_integer(s7_pointer p) { #if WITH_GMP return((is_t_integer(p)) || (is_t_big_integer(p))); #else return(is_integer(p)); #endif } bool s7_is_real(s7_pointer p) { #if WITH_GMP return((is_real(p)) || (is_t_big_integer(p)) || (is_t_big_ratio(p)) || (is_t_big_real(p))); #else return(is_real(p)); /* in GSL, a NaN or inf is not a real, or perhaps better, finite = not (nan or inf) */ #endif } bool s7_is_rational(s7_pointer p) { #if WITH_GMP return((is_rational(p)) || (is_t_big_integer(p)) || (is_t_big_ratio(p))); #else return(is_rational(p)); #endif } bool s7_is_ratio(s7_pointer p) { #if WITH_GMP return((is_t_ratio(p)) || (is_t_big_ratio(p))); #else return(is_t_ratio(p)); #endif } bool s7_is_complex(s7_pointer p) { #if WITH_GMP return((is_number(p)) || (is_big_number(p))); #else return(is_number(p)); #endif } static s7_int c_gcd(s7_int u, s7_int v) { s7_int a, b; if ((u == s7_int_min) || (v == s7_int_min)) { /* can't take abs of these (below) so do it by hand */ s7_int divisor = 1; if (u == v) return(u); while (((u & 1) == 0) && ((v & 1) == 0)) { u /= 2; v /= 2; divisor *= 2; } return(divisor); } a = s7_int_abs(u); b = s7_int_abs(v); while (b != 0) { s7_int temp; temp = a % b; a = b; b = temp; } if (a < 0) return(-a); return(a); } static bool c_rationalize(s7_double ux, s7_double error, s7_int *numer, s7_int *denom) { /* (define* (rat ux (err 0.0000001)) ;; translated from CL code in Canny, Donald, Ressler, "A Rational Rotation Method for Robust Geometric Algorithms" (let ((x0 (- ux error)) (x1 (+ ux error))) (let ((i (ceiling x0)) (i0 (floor x0)) (i1 (ceiling x1)) (r 0)) (if (>= x1 i) i (do ((p0 i0 (+ p1 (* r p0))) (q0 1 (+ q1 (* r q0))) (p1 i1 p0) (q1 1 q0) (e0 (- i1 x0) e1p) (e1 (- x0 i0) (- e0p (* r e1p))) (e0p (- i1 x1) e1) (e1p (- x1 i0) (- e0 (* r e1)))) ((<= x0 (/ p0 q0) x1) (/ p0 q0)) (set! r (min (floor (/ e0 e1)) (ceiling (/ e0p e1p))))))))) */ double x0, x1; s7_int i, i0, i1, p0, q0, p1, q1; double e0, e1, e0p, e1p; int tries = 0; /* don't use s7_double here; if it is "long double", the loop below will hang */ /* #e1e19 is a killer -- it's bigger than most-positive-fixnum, but if we ceil(ux) below * it turns into most-negative-fixnum. 1e19 is trouble in many places. */ if ((ux > s7_int_max) || (ux < s7_int_min)) { /* can't return false here because that confuses some of the callers! */ if (ux > s7_int_min) (*numer) = s7_int_max; else (*numer) = s7_int_min; (*denom) = 1; return(true); } if (error < 0.0) error = -error; x0 = ux - error; x1 = ux + error; i = (s7_int)ceil(x0); if (error >= 1.0) /* aw good grief! */ { if (x0 < 0) { if (x1 < 0) (*numer) = (s7_int)floor(x1); else (*numer) = 0; } else (*numer) = i; (*denom) = 1; return(true); } if (x1 >= i) { if (i >= 0) (*numer) = i; else (*numer) = (s7_int)floor(x1); (*denom) = 1; return(true); } i0 = (s7_int)floor(x0); i1 = (s7_int)ceil(x1); p0 = i0; q0 = 1; p1 = i1; q1 = 1; e0 = i1 - x0; e1 = x0 - i0; e0p = i1 - x1; e1p = x1 - i0; while (true) { s7_int old_p1, old_q1; double old_e0, old_e1, old_e0p, val, r, r1; val = (double)p0 / (double)q0; if (((x0 <= val) && (val <= x1)) || (e1 == 0) || (e1p == 0) || (tries > 100)) { (*numer) = p0; (*denom) = q0; return(true); } tries++; r = (s7_int)floor(e0 / e1); r1 = (s7_int)ceil(e0p / e1p); if (r1 < r) r = r1; /* do handles all step vars in parallel */ old_p1 = p1; p1 = p0; old_q1 = q1; q1 = q0; old_e0 = e0; e0 = e1p; old_e0p = e0p; e0p = e1; old_e1 = e1; p0 = old_p1 + r * p0; q0 = old_q1 + r * q0; e1 = old_e0p - r * e1p; /* if the error is set too low, we can get e1 = 0 here: (rationalize (/ pi) 1e-17) */ e1p = old_e0 - r * old_e1; } return(false); } s7_pointer s7_rationalize(s7_scheme *sc, s7_double x, s7_double error) { s7_int numer = 0, denom = 1; if (c_rationalize(x, error, &numer, &denom)) return(s7_make_ratio(sc, numer, denom)); return(make_real(sc, x)); } static s7_int number_to_numerator(s7_pointer n) { if (is_t_ratio(n)) return(numerator(n)); return(integer(n)); } static s7_int number_to_denominator(s7_pointer n) { if (is_t_ratio(n)) return(denominator(n)); return(1); } s7_pointer s7_make_integer(s7_scheme *sc, s7_int n) { s7_pointer x; if (is_small(n)) /* ((n >= 0) && (n < NUM_SMALL_INTS)) is slower */ return(small_int(n)); new_cell(sc, x, T_INTEGER); integer(x) = n; return(x); } static s7_pointer make_mutable_integer(s7_scheme *sc, s7_int n) { s7_pointer x; new_cell(sc, x, T_INTEGER | T_MUTABLE); integer(x) = n; return(x); } static s7_pointer make_permanent_integer_unchecked(s7_int i) { s7_pointer p; p = (s7_pointer)calloc(1, sizeof(s7_cell)); typeflag(p) = T_IMMUTABLE | T_INTEGER; unheap(p); integer(p) = i; return(p); } static s7_pointer make_permanent_integer(s7_int i) { if (is_small(i)) return(small_int(i)); if (i == MAX_ARITY) return(max_arity); if (i == CLOSURE_ARITY_NOT_SET) return(arity_not_set); if (i == -1) return(minus_one); if (i == -2) return(minus_two); /* a few -3 */ return(make_permanent_integer_unchecked(i)); } s7_pointer s7_make_real(s7_scheme *sc, s7_double n) { s7_pointer x; /* in snd-test this is called about 40000000 times, primarily test 8/18/22 */ if (n == 0.0) return(real_zero); new_cell(sc, x, T_REAL); set_real(x, n); return(x); } s7_pointer s7_make_mutable_real(s7_scheme *sc, s7_double n) { s7_pointer x; new_cell(sc, x, T_REAL | T_MUTABLE); set_real(x, n); return(x); } static s7_pointer make_permanent_real(s7_double n) { s7_pointer x; int nlen = 0; char *str; x = (s7_pointer)calloc(1, sizeof(s7_cell)); set_type(x, T_IMMUTABLE | T_REAL); unheap(x); set_real(x, n); str = number_to_string_base_10(x, 0, float_format_precision, 'g', &nlen, USE_WRITE); set_print_name(x, str, nlen); return(x); } s7_pointer s7_make_complex(s7_scheme *sc, s7_double a, s7_double b) { s7_pointer x; if (b == 0.0) { new_cell(sc, x, T_REAL); set_real(x, a); } else { new_cell(sc, x, T_COMPLEX); set_real_part(x, a); set_imag_part(x, b); } return(x); } s7_pointer s7_make_ratio(s7_scheme *sc, s7_int a, s7_int b) { s7_pointer x; s7_int divisor; if (b == 0) return(division_by_zero_error(sc, make_string_wrapper(sc, "make-ratio"), set_elist_2(sc, make_integer(sc, a), small_int(0)))); if (a == 0) return(small_int(0)); if (b == 1) return(make_integer(sc, a)); #if (!WITH_GMP) if (b == s7_int_min) { if (a == b) return(small_int(1)); /* we've got a problem... This should not trigger an error during reading -- we might have the * ratio on a switch with-bignums or whatever, so its mere occurrence is just an annoyance. * We'll try to do something... */ if (a & 1) { if (a == 1) return(real_NaN); /* not an error here? we can't get this in the ratio reader, I think, because the denominator is negative */ b = b + 1; /* so (/ -1 most-negative-fixnum) -> 1/9223372036854775807 -- not ideal, but ... */ } else { a /= 2; b /= 2; } } #endif if (b < 0) { a = -a; b = -b; } divisor = c_gcd(a, b); if (divisor != 1) { a /= divisor; b /= divisor; } if (b == 1) return(make_integer(sc, a)); new_cell(sc, x, T_RATIO); numerator(x) = a; denominator(x) = b; return(x); } /* in fc19 as a guest running in virtualbox on OSX, the line a /= divisor can abort with an arithmetic exception (SIGFPE) * if leastfix/mostfix -- apparently this is a bug in virtualbox. */ #define WITH_OVERFLOW_ERROR true #define WITHOUT_OVERFLOW_ERROR false #if (!WITH_PURE_S7) static s7_pointer exact_to_inexact(s7_scheme *sc, s7_pointer x) { /* this is tricky because a big int can mess up when turned into a double: * (truncate (exact->inexact most-positive-fixnum)) -> -9223372036854775808 */ switch (type(x)) { case T_INTEGER: return(make_real(sc, (s7_double)(integer(x)))); case T_RATIO: return(make_real(sc, (s7_double)(fraction(x)))); case T_REAL: case T_COMPLEX: return(x); /* apparently (exact->inexact 1+i) is not an error */ default: method_or_bust_with_type(sc, x, sc->EXACT_TO_INEXACT, list_1(sc, x), A_NUMBER, 0); } } static s7_pointer inexact_to_exact(s7_scheme *sc, s7_pointer x, bool with_error) { switch (type(x)) { case T_INTEGER: case T_RATIO: return(x); case T_REAL: { s7_int numer = 0, denom = 1; s7_double val; val = s7_real(x); if ((is_inf(val)) || (is_NaN(val))) { if (with_error) return(simple_wrong_type_argument_with_type(sc, sc->INEXACT_TO_EXACT, x, A_NORMAL_REAL)); return(sc->NIL); } if ((val > s7_int_max) || (val < s7_int_min)) { if (with_error) return(simple_out_of_range(sc, sc->INEXACT_TO_EXACT, x, ITS_TOO_LARGE)); return(sc->NIL); } if (c_rationalize(val, sc->default_rationalize_error, &numer, &denom)) return(s7_make_ratio(sc, numer, denom)); } default: if (with_error) method_or_bust(sc, x, sc->INEXACT_TO_EXACT, list_1(sc, x), T_REAL, 0); return(sc->NIL); } return(x); } #endif s7_double s7_number_to_real_with_caller(s7_scheme *sc, s7_pointer x, const char *caller) { if (is_t_real(x)) return(real(x)); /* this is nearly always the case in current usage, so by avoiding the "switch" we can go twice as fast */ switch (type(x)) { case T_INTEGER: return((s7_double)integer(x)); case T_RATIO: return((s7_double)numerator(x) / (s7_double)denominator(x)); case T_REAL: return(real(x)); #if WITH_GMP case T_BIG_INTEGER: return((s7_double)big_integer_to_s7_int(big_integer(x))); case T_BIG_RATIO: return((s7_double)((long double)big_integer_to_s7_int(mpq_numref(big_ratio(x))) / (long double)big_integer_to_s7_int(mpq_denref(big_ratio(x))))); case T_BIG_REAL: return((s7_double)mpfr_get_d(big_real(x), GMP_RNDN)); #endif } s7_wrong_type_arg_error(sc, caller, 0, x, "a real number"); return(0.0); } s7_double s7_number_to_real(s7_scheme *sc, s7_pointer x) { return(s7_number_to_real_with_caller(sc, x, "s7_number_to_real")); } s7_int s7_number_to_integer_with_caller(s7_scheme *sc, s7_pointer x, const char *caller) /* currently unused */ { if (type(x) != T_INTEGER) s7_wrong_type_arg_error(sc, caller, 0, x, "an integer"); return(integer(x)); } s7_int s7_number_to_integer(s7_scheme *sc, s7_pointer x) /* currently unused */ { return(s7_number_to_integer_with_caller(sc, x, "s7_number_to_integer")); } s7_int s7_numerator(s7_pointer x) { switch (type(x)) { case T_INTEGER: return(integer(x)); case T_RATIO: return(numerator(x)); #if WITH_GMP case T_BIG_INTEGER: return(big_integer_to_s7_int(big_integer(x))); case T_BIG_RATIO: return(big_integer_to_s7_int(mpq_numref(big_ratio(x)))); #endif } return(0); } s7_int s7_denominator(s7_pointer x) { switch (type(x)) { case T_RATIO: return(denominator(x)); #if WITH_GMP case T_BIG_RATIO: return(big_integer_to_s7_int(mpq_denref(big_ratio(x)))); #endif } return(1); } s7_int s7_integer(s7_pointer p) { #if WITH_GMP if (is_t_big_integer(p)) return(big_integer_to_s7_int(big_integer(p))); #endif return(integer(p)); } s7_double s7_real(s7_pointer p) { #if WITH_GMP if (is_t_big_real(p)) return((s7_double)mpfr_get_d(big_real(p), GMP_RNDN)); #endif return(real(p)); } #if (!WITH_GMP) static s7_complex s7_to_c_complex(s7_pointer p) { #if HAVE_COMPLEX_NUMBERS return(CMPLX(s7_real_part(p), s7_imag_part(p))); #else return(0.0); #endif } static s7_pointer s7_from_c_complex(s7_scheme *sc, s7_complex z) { return(s7_make_complex(sc, creal(z), cimag(z))); } #endif #if ((!WITH_PURE_S7) || (!HAVE_OVERFLOW_CHECKS)) static int integer_length(s7_int a) { static const int bits[256] = {0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8}; #define I_8 256LL #define I_16 65536LL #define I_24 16777216LL #define I_32 4294967296LL #define I_40 1099511627776LL #define I_48 281474976710656LL #define I_56 72057594037927936LL /* a might be most-negative-fixnum! in Clisp: (integer-length -9223372036854775808) -> 63 */ if (a < 0) { if (a == s7_int_min) return(63); a = -a; } if (a < I_8) return(bits[a]); if (a < I_16) return(8 + bits[a >> 8]); if (a < I_24) return(16 + bits[a >> 16]); if (a < I_32) return(24 + bits[a >> 24]); if (a < I_40) return(32 + bits[a >> 32]); if (a < I_48) return(40 + bits[a >> 40]); if (a < I_56) return(48 + bits[a >> 48]); return(56 + bits[a >> 56]); } #endif static int s7_int32_max = 0, s7_int32_min = 0, s7_int_bits = 0, s7_int_digits = 0; /* initialized later */ static int s7_int_digits_by_radix[17]; #if (!WITH_GMP) static s7_pointer s7_negate(s7_scheme *sc, s7_pointer p) /* can't use "negate" because it confuses C++! */ { switch (type(p)) { case T_INTEGER: return(make_integer(sc, -integer(p))); case T_RATIO: return(s7_make_ratio(sc, -numerator(p), denominator(p))); case T_REAL: return(make_real(sc, -real(p))); default: return(s7_make_complex(sc, -real_part(p), -imag_part(p))); } } #endif static s7_pointer s7_invert(s7_scheme *sc, s7_pointer p) /* s7_ to be consistent... */ { switch (type(p)) { case T_INTEGER: return(s7_make_ratio(sc, 1, integer(p))); /* a already checked, not 0 */ case T_RATIO: return(s7_make_ratio(sc, denominator(p), numerator(p))); case T_REAL: return(make_real(sc, 1.0 / real(p))); case T_COMPLEX: { s7_double r2, i2, den; r2 = real_part(p); i2 = imag_part(p); den = (r2 * r2 + i2 * i2); return(s7_make_complex(sc, r2 / den, -i2 / den)); } default: return(wrong_type_argument_with_type(sc, sc->DIVIDE, 1, p, A_NUMBER)); } } static s7_pointer subtract_ratios(s7_scheme *sc, s7_pointer x, s7_pointer y) { s7_int d1, d2, n1, n2; d1 = number_to_denominator(x); n1 = number_to_numerator(x); d2 = number_to_denominator(y); n2 = number_to_numerator(y); if (d1 == d2) /* the easy case -- if overflow here, it matches the int case */ return(s7_make_ratio(sc, n1 - n2, d1)); #if (!WITH_GMP) #if HAVE_OVERFLOW_CHECKS { s7_int n1d2, n2d1, d1d2, dn; if ((multiply_overflow(d1, d2, &d1d2)) || (multiply_overflow(n1, d2, &n1d2)) || (multiply_overflow(n2, d1, &n2d1)) || (subtract_overflow(n1d2, n2d1, &dn))) return(make_real(sc, ((long double)n1 / (long double)d1) - ((long double)n2 / (long double)d2))); return(s7_make_ratio(sc, dn, d1d2)); } #else if ((d1 > s7_int32_max) || (d2 > s7_int32_max) || /* before counting bits, check that overflow is possible */ (n1 > s7_int32_max) || (n2 > s7_int32_max) || (n1 < s7_int32_min) || (n2 < s7_int32_min)) { int d1bits, d2bits; d1bits = integer_length(d1); d2bits = integer_length(d2); if (((d1bits + d2bits) > s7_int_bits) || ((d1bits + integer_length(n2)) > (s7_int_bits - 1)) || ((d2bits + integer_length(n1)) > (s7_int_bits - 1))) return(make_real(sc, ((long double)n1 / (long double)d1) - ((long double)n2 / (long double)d2))); return(s7_make_ratio(sc, n1 * d2 - n2 * d1, d1 * d2)); } #endif #endif return(s7_make_ratio(sc, n1 * d2 - n2 * d1, d1 * d2)); } static bool s7_is_negative(s7_pointer obj) { switch (type(obj)) { case T_INTEGER: return(integer(obj) < 0); case T_RATIO: return(numerator(obj) < 0); #if WITH_GMP case T_BIG_INTEGER: return(mpz_cmp_ui(big_integer(obj), 0) < 0); case T_BIG_RATIO: return(mpq_cmp_ui(big_ratio(obj), 0, 1) < 0); case T_BIG_REAL: return(mpfr_cmp_ui(big_real(obj), 0) < 0); #endif default: return(real(obj) < 0); } } static bool s7_is_positive(s7_pointer x) { switch (type(x)) { case T_INTEGER: return(integer(x) > 0); case T_RATIO: return(numerator(x) > 0); #if WITH_GMP case T_BIG_INTEGER: return(mpz_cmp_ui(big_integer(x), 0) > 0); case T_BIG_RATIO: return(mpq_cmp_ui(big_ratio(x), 0, 1) > 0); case T_BIG_REAL: return(mpfr_cmp_ui(big_real(x), 0) > 0); #endif default: return(real(x) > 0.0); } } static bool s7_is_zero(s7_pointer x) { switch (type(x)) { case T_INTEGER: return(integer(x) == 0); case T_REAL: return(real(x) == 0.0); #if WITH_GMP case T_BIG_INTEGER: return(mpz_cmp_ui(big_integer(x), 0) == 0); case T_BIG_REAL: return(mpfr_zero_p(big_real(x))); #endif default: return(false); /* ratios and complex numbers here are already collapsed into integers and reals */ } } static bool s7_is_one(s7_pointer x) { return(((is_integer(x)) && (integer(x) == 1)) || ((is_t_real(x)) && (real(x) == 1.0))); } /* optimize exponents */ #define MAX_POW 32 static double pepow[17][MAX_POW], mepow[17][MAX_POW]; static void init_pows(void) { int i, j; for (i = 2; i < 17; i++) /* radix between 2 and 16 */ for (j = 0; j < MAX_POW; j++) /* saved exponent between 0 and +/- MAX_POW */ { pepow[i][j] = pow((double)i, (double)j); mepow[i][j] = pow((double)i, (double)(-j)); } } static double ipow(int x, int y) { if ((y < MAX_POW) && (y > (-MAX_POW))) { if (y >= 0) return(pepow[x][y]); return(mepow[x][-y]); } return(pow((double)x, (double)y)); } static int s7_int_to_string(char *p, s7_int n, int radix, int width) { static const char dignum[] = "0123456789abcdef"; int i, len, start, end; bool sign; s7_int pown; if ((radix < 2) || (radix > 16)) return(0); if (n == s7_int_min) /* can't negate this, so do it by hand */ { static const char *mnfs[17] = {"","", "-1000000000000000000000000000000000000000000000000000000000000000", "-2021110011022210012102010021220101220222", "-20000000000000000000000000000000", "-1104332401304422434310311213", "-1540241003031030222122212", "-22341010611245052052301", "-1000000000000000000000", "-67404283172107811828", "-9223372036854775808", "-1728002635214590698", "-41a792678515120368", "-10b269549075433c38", "-4340724c6c71dc7a8", "-160e2ad3246366808", "-8000000000000000"}; len = safe_strlen(mnfs[radix]); if (width > len) { start = width - len - 1; memset((void *)p, (int)' ', start); } else start = 0; for (i = 0; i < len; i++) p[start + i] = mnfs[radix][i]; p[len + start] = '\0'; return(len + start); } sign = (n < 0); if (sign) n = -n; /* the previous version that counted up to n, rather than dividing down below n, as here, * could be confused by large ints on 64 bit machines */ pown = n; for (i = 1; i < 100; i++) { if (pown < radix) break; pown /= (s7_int)radix; } len = i - 1; if (sign) len++; end = 0; if (width > len) /* (format #f "~10B" 123) */ { start = width - len - 1; end += start; memset((void *)p, (int)' ', start); } else { start = 0; end = 0; } if (sign) { p[start] = '-'; end++; } for (i = start + len; i >= end; i--) { p[i] = dignum[n % radix]; n /= radix; } p[len + start + 1] = '\0'; return(len + start + 1); } static char *integer_to_string_base_10_no_width(s7_pointer obj, int *nlen) /* do not free the returned string */ { long long int num; char *p, *op; bool sign; static char int_to_str[INT_TO_STR_SIZE]; if (has_print_name(obj)) { (*nlen) = print_name_length(obj); return((char *)print_name(obj)); } /* (*nlen) = snprintf(int_to_str, INT_TO_STR_SIZE, "%lld", (long long int)integer(obj)); * but that is very slow -- the following code is 6 times faster */ num = (long long int)integer(obj); if (num == s7_int_min) { (*nlen) = 20; return((char *)"-9223372036854775808"); } p = (char *)(int_to_str + INT_TO_STR_SIZE - 1); op = p; *p-- = '\0'; sign = (num < 0); if (sign) num = -num; /* we need a positive index below */ do {*p-- = "0123456789"[num % 10]; num /= 10;} while (num); if (sign) { *p = '-'; (*nlen) = op - p; return(p); } (*nlen) = op - p - 1; return(++p); } #define BASE_10 10 static int num_to_str_size = -1; static char *num_to_str = NULL; static const char *float_format_g = NULL; static char *floatify(char *str, int *nlen) { if ((strchr(str, 'e') == NULL) && (strchr(str, '.') == NULL)) { /* this assumes there is room in str for 2 more chars */ int len; len = *nlen; str[len]='.'; str[len + 1]='0'; str[len + 2]='\0'; (*nlen) = len + 2; } return(str); } static char *number_to_string_base_10(s7_pointer obj, int width, int precision, char float_choice, int *nlen, use_write_t choice) /* don't free result */ { /* the rest of s7 assumes nlen is set to the correct length * a tricky case: (format #f "~f" 1e308) -- tries to print 308 digits! so 256 as default len is too small. * but then even worse: (format #f "~F" 1e308+1e308i)! */ int len; len = 1024; if (width > len) len = 2 * width; if (len > num_to_str_size) { if (!num_to_str) num_to_str = (char *)malloc(len * sizeof(char)); else num_to_str = (char *)realloc(num_to_str, len * sizeof(char)); num_to_str_size = len; } /* bignums can't happen here */ switch (type(obj)) { case T_INTEGER: if (width == 0) return(integer_to_string_base_10_no_width(obj, nlen)); (*nlen) = snprintf(num_to_str, num_to_str_size, "%*lld", width, (long long int)integer(obj)); break; case T_RATIO: len = snprintf(num_to_str, num_to_str_size, "%lld/%lld", (long long int)numerator(obj), (long long int)denominator(obj)); if (width > len) { int spaces; if (width >= num_to_str_size) { num_to_str_size = width + 1; num_to_str = (char *)realloc(num_to_str, num_to_str_size * sizeof(char)); } spaces = width - len; num_to_str[width] = '\0'; memmove((void *)(num_to_str + spaces), (void *)num_to_str, len); memset((void *)num_to_str, (int)' ', spaces); (*nlen) = width; } else (*nlen) = len; break; case T_REAL: { const char *frmt; if (sizeof(double) >= sizeof(s7_double)) frmt = (float_choice == 'g') ? "%*.*g" : ((float_choice == 'f') ? "%*.*f" : "%*.*e"); else frmt = (float_choice == 'g') ? "%*.*Lg" : ((float_choice == 'f') ? "%*.*Lf" : "%*.*Le"); len = snprintf(num_to_str, num_to_str_size - 4, frmt, width, precision, s7_real(obj)); /* -4 for floatify */ (*nlen) = len; floatify(num_to_str, nlen); } break; default: { if ((choice == USE_READABLE_WRITE) && ((is_NaN(real_part(obj))) || (is_NaN(imag_part(obj))) || ((is_inf(real_part(obj))) || (is_inf(imag_part(obj)))))) { char rbuf[128], ibuf[128]; char *rp, *ip; if (is_NaN(real_part(obj))) rp = (char *)"nan.0"; else { if (is_inf(real_part(obj))) { if (real_part(obj) < 0.0) rp = (char *)"-inf.0"; else rp = (char *)"inf.0"; } else { snprintf(rbuf, 128, float_format_g, precision, real_part(obj)); rp = rbuf; } } if (is_NaN(imag_part(obj))) ip = (char *)"nan.0"; else { if (is_inf(imag_part(obj))) { if (imag_part(obj) < 0.0) ip = (char *)"-inf.0"; else ip = (char *)"inf.0"; } else { snprintf(ibuf, 128, float_format_g, precision, imag_part(obj)); ip = ibuf; } } len = snprintf(num_to_str, num_to_str_size, "(complex %s %s)", rp, ip); } else { const char *frmt; if (sizeof(double) >= sizeof(s7_double)) { if (imag_part(obj) >= 0.0) frmt = (float_choice == 'g') ? "%.*g+%.*gi" : ((float_choice == 'f') ? "%.*f+%.*fi" : "%.*e+%.*ei"); else frmt = (float_choice == 'g') ? "%.*g%.*gi" : ((float_choice == 'f') ? "%.*f%.*fi" :"%.*e%.*ei"); /* minus sign comes with the imag_part */ } else { if (imag_part(obj) >= 0.0) frmt = (float_choice == 'g') ? "%.*Lg+%.*Lgi" : ((float_choice == 'f') ? "%.*Lf+%.*Lfi" : "%.*Le+%.*Lei"); else frmt = (float_choice == 'g') ? "%.*Lg%.*Lgi" : ((float_choice == 'f') ? "%.*Lf%.*Lfi" : "%.*Le%.*Lei"); } len = snprintf(num_to_str, num_to_str_size, frmt, precision, real_part(obj), precision, imag_part(obj)); } if (width > len) /* (format #f "~20g" 1+i) */ { int spaces; if (width >= num_to_str_size) { num_to_str_size = width + 1; num_to_str = (char *)realloc(num_to_str, num_to_str_size * sizeof(char)); } spaces = width - len; num_to_str[width] = '\0'; memmove((void *)(num_to_str + spaces), (void *)num_to_str, len); memset((void *)num_to_str, (int)' ', spaces); (*nlen) = width; } else (*nlen) = len; } break; } return(num_to_str); } static char *number_to_string_with_radix(s7_scheme *sc, s7_pointer obj, int radix, int width, int precision, char float_choice, int *nlen) { /* the rest of s7 assumes nlen is set to the correct length */ char *p; int len, str_len; #if WITH_GMP if (s7_is_bignum(obj)) return(big_number_to_string_with_radix(obj, radix, width, nlen, USE_WRITE)); /* this ignores precision because it's way too hard to get the mpfr string to look like * C's output -- we either have to call mpfr_get_str twice (the first time just to * find out what the exponent is and how long the string actually is), or we have * to do messy string manipulations. So (format #f "",3F" pi) ignores the "3" and * prints the full string. */ #endif if (radix == 10) { p = number_to_string_base_10(obj, width, precision, float_choice, nlen, USE_WRITE); return(copy_string_with_length(p, *nlen)); } switch (type(obj)) { case T_INTEGER: p = (char *)malloc((128 + width) * sizeof(char)); *nlen = s7_int_to_string(p, s7_integer(obj), radix, width); return(p); case T_RATIO: { char n[128], d[128]; s7_int_to_string(n, numerator(obj), radix, 0); s7_int_to_string(d, denominator(obj), radix, 0); p = (char *)malloc(256 * sizeof(char)); len = snprintf(p, 256, "%s/%s", n, d); str_len = 256; } break; case T_REAL: { int i; s7_int int_part; s7_double x, frac_part, min_frac, base; bool sign = false; char n[128], d[256]; x = s7_real(obj); if (is_NaN(x)) return(copy_string_with_length("nan.0", *nlen = 5)); if (is_inf(x)) { if (x < 0.0) return(copy_string_with_length("-inf.0", *nlen = 6)); return(copy_string_with_length("inf.0", *nlen = 5)); } if (x < 0.0) { sign = true; x = -x; } if (x > 1.0e18) /* i.e. close to or greater than most-positive-fixnum (9.22e18), so the code below is unlikely to work, (format #f "~X" 1e19) */ { int ep; char *p1; s7_pointer r; len = 0; ep = (int)floor(log(x) / log((double)radix)); r = make_real(sc, x / pow((double)radix, (double)ep)); /* divide it down to one digit, then the fractional part */ p1 = number_to_string_with_radix(sc, r, radix, width, precision, float_choice, &len); p = (char *)malloc((len + 8) * sizeof(char)); (*nlen) = snprintf(p, len + 8, "%s%se%d", (sign) ? "-" : "", p1, ep); free(p1); return(p); } int_part = (s7_int)floor(x); frac_part = x - int_part; s7_int_to_string(n, int_part, radix, 0); min_frac = (s7_double)ipow(radix, -precision); /* doesn't this assume precision < 128/256 and that we can fit in 256 digits (1e308)? */ for (i = 0, base = radix; (i < precision) && (frac_part > min_frac); i++, base *= radix) { s7_int ipart; ipart = (s7_int)(frac_part * base); if (ipart >= radix) /* rounding confusion */ ipart = radix - 1; frac_part -= (ipart / base); if (ipart < 10) d[i] = (char)('0' + ipart); else d[i] = (char)('a' + ipart - 10); } if (i == 0) d[i++] = '0'; d[i] = '\0'; p = (char *)malloc(256 * sizeof(char)); len = snprintf(p, 256, "%s%s.%s", (sign) ? "-" : "", n, d); str_len = 256; } break; default: { char *n, *d; p = (char *)malloc(512 * sizeof(char)); n = number_to_string_with_radix(sc, make_real(sc, real_part(obj)), radix, 0, precision, float_choice, &len); d = number_to_string_with_radix(sc, make_real(sc, imag_part(obj)), radix, 0, precision, float_choice, &len); len = snprintf(p, 512, "%s%s%si", n, (imag_part(obj) < 0.0) ? "" : "+", d); str_len = 512; free(n); free(d); } break; } if (width > len) { int spaces; if (width >= str_len) { str_len = width + 1; p = (char *)realloc(p, str_len * sizeof(char)); } spaces = width - len; p[width] = '\0'; memmove((void *)(p + spaces), (void *)p, len); memset((void *)p, (int)' ', spaces); (*nlen) = width; } else (*nlen) = len; return(p); } char *s7_number_to_string(s7_scheme *sc, s7_pointer obj, int radix) { int nlen = 0; return(number_to_string_with_radix(sc, obj, radix, 0, 20, 'g', &nlen)); /* (log top 10) so we get all the digits in base 10 (??) */ } static void prepare_temporary_string(s7_scheme *sc, int len, int which) { s7_pointer p; p = sc->tmp_strs[which]; if (len > string_temp_true_length(p)) { string_value(p) = (char *)realloc(string_value(p), len * sizeof(char)); string_temp_true_length(p) = len; } } static s7_pointer g_number_to_string_1(s7_scheme *sc, s7_pointer args, bool temporary) { #define H_number_to_string "(number->string num (radix 10)) converts the number num into a string." #define Q_number_to_string s7_make_signature(sc, 3, sc->IS_STRING, sc->IS_NUMBER, sc->IS_INTEGER) s7_int radix = 10; int size, nlen = 0; char *res; s7_pointer x; x = car(args); if (!s7_is_number(x)) method_or_bust_with_type(sc, x, sc->NUMBER_TO_STRING, args, A_NUMBER, 1); if (is_pair(cdr(args))) { s7_pointer y; y = cadr(args); if (s7_is_integer(y)) radix = s7_integer(y); else method_or_bust(sc, y, sc->NUMBER_TO_STRING, args, T_INTEGER, 2); if ((radix < 2) || (radix > 16)) return(out_of_range(sc, sc->NUMBER_TO_STRING, small_int(2), y, A_VALID_RADIX)); } #if WITH_GMP if (s7_is_bignum(x)) { res = big_number_to_string_with_radix(x, radix, 0, &nlen, USE_WRITE); return(make_string_uncopied_with_length(sc, res, nlen)); } #endif size = float_format_precision; if (!is_rational(x)) { /* if size = 20, (number->string .1) gives "0.10000000000000000555", but if it's less than 20, * large numbers (or very small numbers) mess up the less significant digits. */ if (radix == 10) { if (is_real(x)) { s7_double val; val = fabs(s7_real(x)); if ((val > (s7_int32_max / 4)) || (val < 1.0e-6)) size += 4; } else { s7_double rl; rl = fabs(s7_real_part(x)); if ((rl > (s7_int32_max / 4)) || (rl < 1.0e-6)) { s7_double im; im = fabs(s7_imag_part(x)); if ((im > (s7_int32_max / 4)) || (im < 1.0e-6)) size += 4; } } } } if (radix != 10) { res = number_to_string_with_radix(sc, x, radix, 0, size, 'g', &nlen); return(make_string_uncopied_with_length(sc, res, nlen)); } res = number_to_string_base_10(x, 0, size, 'g', &nlen, USE_WRITE); if (temporary) { s7_pointer p; prepare_temporary_string(sc, nlen + 1, 1); p = sc->tmp_strs[1]; string_length(p) = nlen; memcpy((void *)(string_value(p)), (void *)res, nlen); string_value(p)[nlen] = 0; return(p); } return(s7_make_string_with_length(sc, res, nlen)); } static s7_pointer g_number_to_string(s7_scheme *sc, s7_pointer args) { return(g_number_to_string_1(sc, args, false)); } static s7_pointer number_to_string_temp; static s7_pointer g_number_to_string_temp(s7_scheme *sc, s7_pointer args) { return(g_number_to_string_1(sc, args, true)); } static s7_pointer number_to_string_pf_temp(s7_scheme *sc, s7_pointer **p) { s7_pf_t f; s7_pointer x; f = (s7_pf_t)(**p); (*p)++; x = f(sc, p); return(g_number_to_string_1(sc, set_plist_1(sc, x), true)); } static s7_pointer number_to_string_pf_s_temp(s7_scheme *sc, s7_pointer **p) { s7_pointer x; (*p)++; x = slot_value(**p); (*p)++; return(g_number_to_string_1(sc, set_plist_1(sc, x), true)); } static s7_pointer c_number_to_string(s7_scheme *sc, s7_pointer n) {return(g_number_to_string_1(sc, set_plist_1(sc, n), false));} PF_TO_PF(number_to_string, c_number_to_string) #define CTABLE_SIZE 256 static bool *exponent_table, *slashify_table, *char_ok_in_a_name, *white_space, *number_table, *symbol_slashify_table; static int *digits; static void init_ctables(void) { int i; exponent_table = (bool *)calloc(CTABLE_SIZE, sizeof(bool)); slashify_table = (bool *)calloc(CTABLE_SIZE, sizeof(bool)); symbol_slashify_table = (bool *)calloc(CTABLE_SIZE, sizeof(bool)); char_ok_in_a_name = (bool *)calloc(CTABLE_SIZE, sizeof(bool)); white_space = (bool *)calloc(CTABLE_SIZE + 1, sizeof(bool)); white_space++; /* leave white_space[-1] false for white_space[EOF] */ number_table = (bool *)calloc(CTABLE_SIZE, sizeof(bool)); for (i = 1; i < CTABLE_SIZE; i++) char_ok_in_a_name[i] = true; char_ok_in_a_name[0] = false; char_ok_in_a_name[(unsigned char)'('] = false; /* idiotic cast is for C++'s benefit */ char_ok_in_a_name[(unsigned char)')'] = false; char_ok_in_a_name[(unsigned char)';'] = false; char_ok_in_a_name[(unsigned char)'\t'] = false; char_ok_in_a_name[(unsigned char)'\n'] = false; char_ok_in_a_name[(unsigned char)'\r'] = false; char_ok_in_a_name[(unsigned char)' '] = false; char_ok_in_a_name[(unsigned char)'"'] = false; /* what about stuff like vertical tab? or comma? */ for (i = 0; i < CTABLE_SIZE; i++) white_space[i] = false; white_space[(unsigned char)'\t'] = true; white_space[(unsigned char)'\n'] = true; white_space[(unsigned char)'\r'] = true; white_space[(unsigned char)'\f'] = true; white_space[(unsigned char)'\v'] = true; white_space[(unsigned char)' '] = true; white_space[(unsigned char)'\205'] = true; /* 133 */ white_space[(unsigned char)'\240'] = true; /* 160 */ /* surely only 'e' is needed... */ exponent_table[(unsigned char)'e'] = true; exponent_table[(unsigned char)'E'] = true; exponent_table[(unsigned char)'@'] = true; #if WITH_EXTRA_EXPONENT_MARKERS exponent_table[(unsigned char)'s'] = true; exponent_table[(unsigned char)'S'] = true; exponent_table[(unsigned char)'f'] = true; exponent_table[(unsigned char)'F'] = true; exponent_table[(unsigned char)'d'] = true; exponent_table[(unsigned char)'D'] = true; exponent_table[(unsigned char)'l'] = true; exponent_table[(unsigned char)'L'] = true; #endif for (i = 0; i < 32; i++) slashify_table[i] = true; for (i = 127; i < 160; i++) slashify_table[i] = true; slashify_table[(unsigned char)'\\'] = true; slashify_table[(unsigned char)'"'] = true; slashify_table[(unsigned char)'\n'] = false; for (i = 0; i < CTABLE_SIZE; i++) symbol_slashify_table[i] = ((slashify_table[i]) || (!char_ok_in_a_name[i])); digits = (int *)calloc(CTABLE_SIZE, sizeof(int)); for (i = 0; i < CTABLE_SIZE; i++) digits[i] = 256; digits[(unsigned char)'0'] = 0; digits[(unsigned char)'1'] = 1; digits[(unsigned char)'2'] = 2; digits[(unsigned char)'3'] = 3; digits[(unsigned char)'4'] = 4; digits[(unsigned char)'5'] = 5; digits[(unsigned char)'6'] = 6; digits[(unsigned char)'7'] = 7; digits[(unsigned char)'8'] = 8; digits[(unsigned char)'9'] = 9; digits[(unsigned char)'a'] = 10; digits[(unsigned char)'A'] = 10; digits[(unsigned char)'b'] = 11; digits[(unsigned char)'B'] = 11; digits[(unsigned char)'c'] = 12; digits[(unsigned char)'C'] = 12; digits[(unsigned char)'d'] = 13; digits[(unsigned char)'D'] = 13; digits[(unsigned char)'e'] = 14; digits[(unsigned char)'E'] = 14; digits[(unsigned char)'f'] = 15; digits[(unsigned char)'F'] = 15; for (i = 0; i < CTABLE_SIZE; i++) number_table[i] = false; number_table[(unsigned char)'0'] = true; number_table[(unsigned char)'1'] = true; number_table[(unsigned char)'2'] = true; number_table[(unsigned char)'3'] = true; number_table[(unsigned char)'4'] = true; number_table[(unsigned char)'5'] = true; number_table[(unsigned char)'6'] = true; number_table[(unsigned char)'7'] = true; number_table[(unsigned char)'8'] = true; number_table[(unsigned char)'9'] = true; number_table[(unsigned char)'.'] = true; number_table[(unsigned char)'+'] = true; number_table[(unsigned char)'-'] = true; number_table[(unsigned char)'#'] = true; } #define is_white_space(C) white_space[C] /* this is much faster than C's isspace, and does not depend on the current locale. * if c == EOF (-1), it indexes into the empty (0) slot we preallocated below white_space */ static s7_pointer check_sharp_readers(s7_scheme *sc, const char *name) { s7_pointer reader, value, args; bool need_loader_port; value = sc->F; args = sc->F; /* *#reader* is assumed to be an alist of (char . proc) * where each proc takes one argument, the string from just beyond the "#" to the next delimiter. * The procedure can call read-char to read ahead in the current-input-port. * If it returns anything other than #f, that is the value of the sharp expression. * Since #f means "nothing found", it is tricky to handle #F: * (cons #\F (lambda (str) (and (string=? str "F") (list 'not #t)))) * This search happens after #|, #t, and #f (and #nD for multivectors?). #! has a fallback. */ need_loader_port = is_loader_port(sc->input_port); if (need_loader_port) clear_loader_port(sc->input_port); /* normally read* can't read from sc->input_port if it is in use by the loader, * but here we are deliberately making that possible. */ for (reader = slot_value(sc->sharp_readers); is_not_null(reader); reader = cdr(reader)) { if (name[0] == s7_character(caar(reader))) { if (args == sc->F) args = list_1(sc, s7_make_string(sc, name)); /* args is GC protected by s7_apply_function (placed on the stack */ value = s7_apply_function(sc, cdar(reader), args); /* this is much less error-safe than s7_call */ if (value != sc->F) break; } } if (need_loader_port) set_loader_port(sc->input_port); return(value); } static s7_pointer g_sharp_readers_set(s7_scheme *sc, s7_pointer args) { /* new value must be either () or a proper list of conses (char . func) */ if (is_null(cadr(args))) return(cadr(args)); if (is_pair(cadr(args))) { s7_pointer x; for (x = cadr(args); is_pair(x); x = cdr(x)) { if ((!is_pair(car(x))) || (!s7_is_character(caar(x))) || (!s7_is_procedure(cdar(x)))) return(sc->ERROR); } if (is_null(x)) return(cadr(args)); } return(sc->ERROR); } static bool is_abnormal(s7_pointer x) { switch (type(x)) { case T_INTEGER: case T_RATIO: return(false); case T_REAL: return(is_inf(real(x)) || is_NaN(real(x))); case T_COMPLEX: return(((is_inf(s7_real_part(x))) || (is_inf(s7_imag_part(x))) || (is_NaN(s7_real_part(x))) || (is_NaN(s7_imag_part(x))))); #if WITH_GMP case T_BIG_INTEGER: case T_BIG_RATIO: return(false); case T_BIG_REAL: return((is_inf(s7_real_part(x))) || (is_NaN(s7_real_part(x)))); case T_BIG_COMPLEX: return((is_inf(s7_real_part(x))) || (is_inf(s7_imag_part(x))) || (is_NaN(s7_real_part(x))) || (is_NaN(s7_imag_part(x)))); #endif default: return(true); } } #define NESTED_SHARP false #define UNNESTED_SHARP true #define SYMBOL_OK true #define NO_SYMBOLS false static s7_pointer make_sharp_constant(s7_scheme *sc, char *name, bool at_top, int radix, bool with_error) { /* name is the stuff after the '#', return sc->NIL if not a recognized #... entity */ int len; s7_pointer x; if ((name[0] == 't') && ((name[1] == '\0') || (strings_are_equal(name, "true")))) return(sc->T); if ((name[0] == 'f') && ((name[1] == '\0') || (strings_are_equal(name, "false")))) return(sc->F); if (is_not_null(slot_value(sc->sharp_readers))) { x = check_sharp_readers(sc, name); if (x != sc->F) return(x); } len = safe_strlen5(name); /* just count up to 5 */ if (len < 2) return(sc->NIL); switch (name[0]) { /* -------- #< ... > -------- */ case '<': if (strings_are_equal(name, "")) return(sc->UNSPECIFIED); if (strings_are_equal(name, "")) return(sc->UNDEFINED); if (strings_are_equal(name, "")) return(sc->EOF_OBJECT); return(sc->NIL); /* -------- #o #d #x #b -------- */ case 'o': /* #o (octal) */ case 'd': /* #d (decimal) */ case 'x': /* #x (hex) */ case 'b': /* #b (binary) */ { int num_at = 1; #if (!WITH_PURE_S7) bool to_inexact = false, to_exact = false; if (name[1] == '#') { if (!at_top) return(sc->NIL); if ((len > 2) && ((name[2] == 'e') || (name[2] == 'i'))) /* r6rs includes caps here */ { if ((len > 3) && (name[3] == '#')) return(sc->NIL); to_inexact = (name[2] == 'i'); to_exact = (name[2] == 'e'); num_at = 3; } else return(sc->NIL); } #endif /* the #b or whatever overrides any radix passed in earlier */ x = make_atom(sc, (char *)(name + num_at), (name[0] == 'o') ? 8 : ((name[0] == 'x') ? 16 : ((name[0] == 'b') ? 2 : 10)), NO_SYMBOLS, with_error); /* #x#i1 apparently makes sense, so #x1.0 should also be accepted. * here we can get #b#e0/0 or #b#e+1/0 etc. * surely if #e1+i is an error (or #f), and #e#x1+i is an error, * #x#e1+i should also be an error, but #e1+0i is not an error I guess since there actually isn't any imaginary part */ if (is_abnormal(x)) return(sc->NIL); #if (!WITH_PURE_S7) if ((!to_exact) && (!to_inexact)) return(x); if ((s7_imag_part(x) != 0.0) && (to_exact)) /* #x#e1+i */ return(sc->NIL); #if WITH_GMP if (s7_is_bignum(x)) { if (to_exact) return(big_inexact_to_exact(sc, set_plist_1(sc, x))); return(big_exact_to_inexact(sc, set_plist_1(sc, x))); } #endif if (to_exact) return(inexact_to_exact(sc, x, with_error)); return(exact_to_inexact(sc, x)); #else return(x); #endif } break; #if (!WITH_PURE_S7) /* -------- #i -------- */ case 'i': /* #i = ->inexact (see token for table of choices here) */ if (name[1] == '#') { /* there are special cases here: "#e0/0" or "#e#b0/0" -- all infs are complex: * #i1/0=nan.0 but #i1/0+i=inf+1i so e->i is a no-op but i->e is not * * even trickier: a *#reader* like #t could be used as #e#t13.25 so make_sharp_constant * needs to be willing to call the readers even when not at_top (i.e. when NESTED_SHARP). */ if ((name[2] == 'e') || /* #i#e1 -- assume these aren't redefinable? */ (name[2] == 'i')) return(sc->NIL); x = make_sharp_constant(sc, (char *)(name + 2), NESTED_SHARP, radix, with_error); if (s7_is_number(x)) { if (is_abnormal(x)) return(sc->NIL); #if WITH_GMP if (s7_is_bignum(x)) /* (string->number "#b#e-11e+111") */ return(big_exact_to_inexact(sc, set_plist_1(sc, x))); #endif return(exact_to_inexact(sc, x)); } return(sc->NIL); } x = make_atom(sc, (char *)(name + 1), radix, NO_SYMBOLS, with_error); if (!s7_is_number(x)) /* not is_abnormal(x) -- #i0/0 -> nan etc */ return(sc->NIL); #if WITH_GMP if (s7_is_bignum(x)) return(big_exact_to_inexact(sc, set_plist_1(sc, x))); #endif return(exact_to_inexact(sc, x)); /* -------- #e -------- */ case 'e': /* #e = ->exact */ if (name[1] == '#') { if ((name[2] == 'e') || /* #e#e1 */ (name[2] == 'i')) return(sc->NIL); x = make_sharp_constant(sc, (char *)(name + 2), NESTED_SHARP, radix, with_error); if (s7_is_number(x)) { if (is_abnormal(x)) /* (string->number "#e#b0/0") */ return(sc->NIL); if (!s7_is_real(x)) /* (string->number "#e#b1+i") */ return(sc->NIL); #if WITH_GMP return(big_inexact_to_exact(sc, set_plist_1(sc, x))); #endif return(inexact_to_exact(sc, x, with_error)); } return(sc->NIL); } x = make_atom(sc, (char *)(name + 1), radix, NO_SYMBOLS, with_error); #if WITH_GMP /* #e1e310 is a simple case */ if (s7_is_bignum(x)) return(big_inexact_to_exact(sc, set_plist_1(sc, x))); #endif if (is_abnormal(x)) /* (string->number "#e0/0") */ return(sc->NIL); if (!s7_is_real(x)) /* (string->number "#e1+i") */ return(sc->NIL); #if WITH_GMP /* there are non-big floats that are greater than most-positive-fixnum: * :(> .1e20 most-positive-fixnum) -> #t * :(bignum? .1e20) -> #f * so we have to check that, not just is it a bignum. */ return(big_inexact_to_exact(sc, set_plist_1(sc, x))); #endif return(inexact_to_exact(sc, x, with_error)); #endif /* !WITH_PURE_S7 */ /* -------- #_... -------- */ case '_': { s7_pointer sym; sym = make_symbol(sc, (char *)(name + 1)); if (is_slot(initial_slot(sym))) return(slot_value(initial_slot(sym))); return(s7_error(sc, sc->SYNTAX_ERROR, set_elist_2(sc, make_string_wrapper(sc, "#~A is undefined"), make_string_wrapper(sc, name)))); /* return(sc->UNDEFINED); */ } /* -------- #\... -------- */ case '\\': if (name[2] == 0) /* the most common case: #\a */ return(chars[(unsigned char)(name[1])]); /* not unsigned int here! (unsigned int)255 (as a char) returns -1!! */ switch (name[1]) { case 'n': if ((strings_are_equal(name + 1, "null")) || (strings_are_equal(name + 1, "nul"))) return(chars[0]); if (strings_are_equal(name + 1, "newline")) return(chars[(unsigned char)'\n']); break; case 's': if (strings_are_equal(name + 1, "space")) return(chars[(unsigned char)' ']); break; case 'r': if (strings_are_equal(name + 1, "return")) return(chars[(unsigned char)'\r']); break; case 'l': if (strings_are_equal(name + 1, "linefeed")) return(chars[(unsigned char)'\n']); break; case 't': if (strings_are_equal(name + 1, "tab")) return(chars[(unsigned char)'\t']); break; case 'a': /* the next 4 are for r7rs */ if (strings_are_equal(name + 1, "alarm")) return(chars[7]); break; case 'b': if (strings_are_equal(name + 1, "backspace")) return(chars[8]); break; case 'e': if (strings_are_equal(name + 1, "escape")) return(chars[0x1b]); break; case 'd': if (strings_are_equal(name + 1, "delete")) return(chars[0x7f]); break; case 'x': /* #\x is just x, but apparently #\x is int->char? #\x65 -> #\e -- Guile doesn't have this * * r7rs has 2/3/4-byte "characters" of the form #\xcebb but this is not compatible with * make-string, string-length, and so on. We'd either have to have 2-byte chars * so (string-length (make-string 3 #\xcebb)) = 3, or accept 6 here for number of chars. * Then substring and string-set! and so on have to use utf8 encoding throughout or * risk changing the string length unexpectedly. */ { /* sscanf here misses errors like #\x1.4, but make_atom misses #\x6/3, * #\x#b0, #\x#e0.0, #\x-0, #\x#e0e100 etc, so we have to do it at * an even lower level. * another problem: #\xbdca2cbec overflows so lval is -593310740 -> segfault unless caught */ bool happy = true; char *tmp; int lval = 0; tmp = (char *)(name + 2); while ((*tmp) && (happy) && (lval >= 0)) { int dig; dig = digits[(int)(*tmp++)]; if (dig < 16) lval = dig + (lval * 16); else happy = false; } if ((happy) && (lval < 256) && (lval >= 0)) return(chars[lval]); } break; } } return(sc->NIL); } static s7_int string_to_integer(const char *str, int radix, bool *overflow) { bool negative = false; s7_int lval = 0; int dig; char *tmp = (char *)str; char *tmp1; if (str[0] == '+') tmp++; else { if (str[0] == '-') { negative = true; tmp++; } } while (*tmp == '0') {tmp++;}; tmp1 = tmp; if (radix == 10) { while (true) { dig = digits[(unsigned char)(*tmp++)]; if (dig > 9) break; #if HAVE_OVERFLOW_CHECKS if (multiply_overflow(lval, (s7_int)10, &lval)) break; if (add_overflow(lval, (s7_int)dig, &lval)) break; #else lval = dig + (lval * 10); dig = digits[(unsigned char)(*tmp++)]; if (dig > 9) break; lval = dig + (lval * 10); #endif } } else { while (true) { dig = digits[(unsigned char)(*tmp++)]; if (dig >= radix) break; #if HAVE_OVERFLOW_CHECKS if (multiply_overflow(lval, (s7_int)radix, &lval)) break; if (add_overflow(lval, (s7_int)dig, &lval)) break; #else lval = dig + (lval * radix); dig = digits[(unsigned char)(*tmp++)]; if (dig >= radix) break; lval = dig + (lval * radix); #endif } } #if WITH_GMP (*overflow) = ((lval > s7_int32_max) || ((tmp - tmp1) > s7_int_digits_by_radix[radix])); /* this tells the string->number readers to create a bignum. We need to be very * conservative here to catch contexts such as (/ 1/524288 19073486328125) */ #else if ((tmp - tmp1 - 2) > s7_int_digits_by_radix[radix]) { /* I can't decide what to do with these non-gmp overflows. Perhaps NAN in all cases? * overflow: 9223372036854775810 -> -9223372036854775806 -- this is not caught currently */ (*overflow) = true; if (negative) return(s7_int_min); /* or INFINITY? */ return(s7_int_max); /* 0/100000000000000000000000000000000000000000000000000000000000000000000 */ } #endif if (negative) return(-lval); return(lval); } /* 9223372036854775807 9223372036854775807 * -9223372036854775808 -9223372036854775808 * 0000000000000000000000000001.0 1.0 * 1.0000000000000000000000000000 1.0 * 1000000000000000000000000000.0e-40 1.0e-12 * 0.0000000000000000000000000001e40 1.0e12 * 1.0e00000000000000000001 10.0 */ static s7_double string_to_double_with_radix(const char *ur_str, int radix, bool *overflow) { /* strtod follows LANG which is not what we want (only "." is decimal point in Scheme). * To overcome LANG in strtod would require screwing around with setlocale which never works. * So we use our own code -- according to valgrind, this function is much faster than strtod. * * comma as decimal point causes ambiguities: `(+ ,1 2) etc */ int i, sign = 1, frac_len, int_len, dig, max_len, exponent = 0; long long int int_part = 0, frac_part = 0; char *str; char *ipart, *fpart; s7_double dval = 0.0; /* there's an ambiguity in number notation here if we allow "1e1" or "1.e1" in base 16 (or 15) -- is e a digit or an exponent marker? * but 1e+1, for example disambiguates it -- kind of messy! -- the scheme spec says "e" can only occur in base 10. * mpfr says "e" as exponent only in bases <= 10 -- else use '@' which works in any base. This can only cause confusion * in scheme, unfortunately, due to the idiotic scheme polar notation. But we accept "s" and "l" as exponent markers * so, perhaps for radix > 10, the exponent, if any, has to use one of S s L l? Not "l"! And "s" originally meant "short". * * '@' can now be used as the exponent marker (26-Mar-12). * Another slight ambiguity: 1+1/2i is parsed as 1 + 0.5i, not 1+1/(2i), or (1+1)/(2i) or (1+1/2)i etc */ max_len = s7_int_digits_by_radix[radix]; str = (char *)ur_str; if (*str == '+') str++; else { if (*str == '-') { str++; sign = -1; } } while (*str == '0') {str++;}; ipart = str; while (digits[(int)(*str)] < radix) str++; int_len = str - ipart; if (*str == '.') str++; fpart = str; while (digits[(int)(*str)] < radix) str++; frac_len = str - fpart; if ((*str) && (exponent_table[(unsigned char)(*str)])) { int exp_negative = false; str++; if (*str == '+') str++; else { if (*str == '-') { str++; exp_negative = true; } } while ((dig = digits[(int)(*str++)]) < 10) /* exponent itself is always base 10 */ { #if HAVE_OVERFLOW_CHECKS if ((int_multiply_overflow(exponent, 10, &exponent)) || (int_add_overflow(exponent, dig, &exponent))) { exponent = 1000000; /* see below */ break; } #else exponent = dig + (exponent * 10); #endif } #if (!defined(__GNUC__)) || (__GNUC__ < 5) if (exponent < 0) /* we overflowed, so make sure we notice it below (need to check for 0.0e... first) (Brian Damgaard) */ exponent = 1000000; /* see below for examples -- this number needs to be very big but not too big for add */ #endif if (exp_negative) exponent = -exponent; /* 2e12341234123123123123213123123123 -> 0.0 * but exp len is not the decider: 2e00000000000000000000000000000000000000001 -> 20.0 * first zero: 2e123412341231231231231 * then: 2e12341234123123123123123123 -> inf * then: 2e123412341231231231231231231231231231 -> 0.0 * 2e-123412341231231231231 -> inf * but: 0e123412341231231231231231231231231231 */ } #if WITH_GMP /* 9007199254740995.0 */ if (int_len + frac_len >= max_len) { (*overflow) = true; return(0.0); } #endif str = ipart; if ((int_len + exponent) > max_len) { /* 12341234.56789e12 12341234567889999872.0 1.234123456789e+19 * -1234567890123456789.0 -1234567890123456768.0 -1.2345678901235e+18 * 12345678901234567890.0 12345678901234567168.0 1.2345678901235e+19 * 123.456e30 123456000000000012741097792995328.0 1.23456e+32 * 12345678901234567890.0e12 12345678901234569054409354903552.0 1.2345678901235e+31 * 1.234567890123456789012e30 1234567890123456849145940148224.0 1.2345678901235e+30 * 1e20 100000000000000000000.0 1e+20 * 1234567890123456789.0 1234567890123456768.0 1.2345678901235e+18 * 123.456e16 1234560000000000000.0 1.23456e+18 * 98765432101234567890987654321.0e-5 987654321012345728401408.0 9.8765432101235e+23 * 98765432101234567890987654321.0e-10 9876543210123456512.0 9.8765432101235e+18 * 0.00000000000000001234e20 1234.0 * 0.000000000000000000000000001234e30 1234.0 * 0.0000000000000000000000000000000000001234e40 1234.0 * 0.000000000012345678909876543210e15 12345.678909877 * 0e1000 0.0 */ for (i = 0; i < max_len; i++) { dig = digits[(int)(*str++)]; if (dig < radix) int_part = dig + (int_part * radix); else break; } /* if the exponent is huge, check for 0 int_part and frac_part before complaining (0e1000 or 0.0e1000) */ if ((int_part == 0) && (exponent > max_len)) { /* if frac_part is also 0, return 0.0 */ if (frac_len == 0) return(0.0); str = fpart; while ((dig = digits[(int)(*str++)]) < radix) frac_part = dig + (frac_part * radix); if (frac_part == 0) return(0.0); #if WITH_GMP (*overflow) = true; #endif } #if WITH_GMP (*overflow) = ((int_part > 0) || (exponent > 20)); /* .1e310 is a tricky case */ #endif if (int_part != 0) /* 0.<310 zeros here>1e310 for example -- * pow (via ipow) thinks it has to be too big, returns Nan, * then Nan * 0 -> Nan and the NaN propogates */ { if (int_len <= max_len) dval = int_part * ipow(radix, exponent); else dval = int_part * ipow(radix, exponent + int_len - max_len); } else dval = 0.0; /* shift by exponent, but if int_len > max_len then we assumed (see below) int_len - max_len 0's on the left */ /* using int_to_int or table lookups here instead of pow did not make any difference in speed */ if (int_len < max_len) { int k, flen; str = fpart; for (k = 0; (frac_len > 0) && (k < exponent); k += max_len) { if (frac_len > max_len) flen = max_len; else flen = frac_len; frac_len -= max_len; frac_part = 0; for (i = 0; i < flen; i++) frac_part = digits[(int)(*str++)] + (frac_part * radix); if (frac_part != 0) /* same pow->NaN problem as above can occur here */ dval += frac_part * ipow(radix, exponent - flen - k); } } else { /* some of the fraction is in the integer part before the negative exponent shifts it over */ if (int_len > max_len) { int ilen; /* str should be at the last digit we read */ ilen = int_len - max_len; /* we read these above */ if (ilen > max_len) ilen = max_len; for (i = 0; i < ilen; i++) frac_part = digits[(int)(*str++)] + (frac_part * radix); dval += frac_part * ipow(radix, exponent - ilen); } } return(sign * dval); } /* int_len + exponent <= max_len */ if (int_len <= max_len) { int int_exponent; /* a better algorithm (since the inaccuracies are in the radix^exponent portion): * strip off leading zeros and possible sign, * strip off digits beyond max_len, then remove any trailing zeros. * (maybe fiddle with the lowest order digit here for rounding, but I doubt it matters) * read digits until end of number or max_len reached, ignoring the decimal point * get exponent and use it and decimal point location to position the current result integer * this always combines the same integer and the same exponent no matter how the number is expressed. */ int_exponent = exponent; if (int_len > 0) { char *iend; iend = (char *)(str + int_len - 1); while ((*iend == '0') && (iend != str)) {iend--; int_exponent++;} while (str <= iend) int_part = digits[(int)(*str++)] + (int_part * radix); } if (int_exponent != 0) dval = int_part * ipow(radix, int_exponent); else dval = (s7_double)int_part; } else { int len, flen; long long int frpart = 0; /* 98765432101234567890987654321.0e-20 987654321.012346 * 98765432101234567890987654321.0e-29 0.98765432101235 * 98765432101234567890987654321.0e-30 0.098765432101235 * 98765432101234567890987654321.0e-28 9.8765432101235 */ len = int_len + exponent; for (i = 0; i < len; i++) int_part = digits[(int)(*str++)] + (int_part * radix); flen = -exponent; if (flen > max_len) flen = max_len; for (i = 0; i < flen; i++) frpart = digits[(int)(*str++)] + (frpart * radix); if (len <= 0) dval = int_part + frpart * ipow(radix, len - flen); else dval = int_part + frpart * ipow(radix, -flen); } if (frac_len > 0) { str = fpart; if (frac_len <= max_len) { /* splitting out base 10 case saves very little here */ /* this ignores trailing zeros, so that 0.3 equals 0.300 */ char *fend; fend = (char *)(str + frac_len - 1); while ((*fend == '0') && (fend != str)) {fend--; frac_len--;} /* (= .6 0.6000) */ while (str <= fend) frac_part = digits[(int)(*str++)] + (frac_part * radix); dval += frac_part * ipow(radix, exponent - frac_len); /* fprintf(stderr, "frac: %lld, exp: (%d %d) %.20f, val: %.20f\n", frac_part, exponent, frac_len, ipow(radix, exponent - frac_len), dval); * 0.6: frac: 6, exp: 0.10000000000000000555, val: 0.60000000000000008882 * 0.60: frac: 60, exp: 0.01000000000000000021, val: 0.59999999999999997780 * 0.6000: frac: 6000, exp: 0.00010000000000000000, val: 0.59999999999999997780 * :(= 0.6 0.60) * #f * :(= #i3/5 0.6) * #f * so (string->number (number->string num)) == num only if both num's are the same text (or you get lucky) * :(= 0.6 6e-1) ; but not 60e-2 * #t * * to fix the 0.60 case, we need to ignore trailing post-dot zeros. */ } else { if (exponent <= 0) { for (i = 0; i < max_len; i++) frac_part = digits[(int)(*str++)] + (frac_part * radix); dval += frac_part * ipow(radix, exponent - max_len); } else { /* 1.0123456789876543210e1 10.12345678987654373771 * 1.0123456789876543210e10 10123456789.87654304504394531250 * 0.000000010000000000000000e10 100.0 * 0.000000010000000000000000000000000000000000000e10 100.0 * 0.000000012222222222222222222222222222222222222e10 122.22222222222222 * 0.000000012222222222222222222222222222222222222e17 1222222222.222222 */ int_part = 0; for (i = 0; i < exponent; i++) int_part = digits[(int)(*str++)] + (int_part * radix); frac_len -= exponent; if (frac_len > max_len) frac_len = max_len; for (i = 0; i < frac_len; i++) frac_part = digits[(int)(*str++)] + (frac_part * radix); dval += int_part + frac_part * ipow(radix, -frac_len); } } } #if WITH_GMP if ((int_part == 0) && (frac_part == 0)) return(0.0); (*overflow) = ((frac_len - exponent) > max_len); #endif return(sign * dval); } static s7_pointer make_atom(s7_scheme *sc, char *q, int radix, bool want_symbol, bool with_error) { /* make symbol or number from string */ #define IS_DIGIT(Chr, Rad) (digits[(unsigned char)Chr] < Rad) char c, *p; bool has_dec_point1 = false; p = q; c = *p++; /* a number starts with + - . or digit, but so does 1+ for example */ switch (c) { case '#': return(make_sharp_constant(sc, p, UNNESTED_SHARP, radix, with_error)); /* make_sharp_constant expects the '#' to be removed */ case '+': case '-': c = *p++; if (c == '.') { has_dec_point1 = true; c = *p++; } if ((!c) || (!IS_DIGIT(c, radix))) return((want_symbol) ? make_symbol(sc, q) : sc->F); break; case '.': has_dec_point1 = true; c = *p++; if ((!c) || (!IS_DIGIT(c, radix))) return((want_symbol) ? make_symbol(sc, q) : sc->F); break; case '0': /* these two are always digits */ case '1': break; default: if (!IS_DIGIT(c, radix)) return((want_symbol) ? make_symbol(sc, q) : sc->F); break; } /* now it's possibly a number -- the first character(s) could be part of a number in the current radix */ { char *slash1 = NULL, *slash2 = NULL, *plus = NULL, *ex1 = NULL, *ex2 = NULL; bool has_i = false, has_dec_point2 = false; int has_plus_or_minus = 0, current_radix; #if (!WITH_GMP) bool overflow = false; #endif current_radix = radix; /* current_radix is 10 for the exponent portions, but radix for all the rest */ for ( ; (c = *p) != 0; ++p) { /* what about embedded null? (string->number (string #\1 (integer->char 0) #\0)) * currently we stop and return 1, but Guile returns #f */ if (!IS_DIGIT(c, current_radix)) /* moving this inside the switch statement was much slower */ { current_radix = radix; switch (c) { /* -------- decimal point -------- */ case '.': if ((!IS_DIGIT(p[1], current_radix)) && (!IS_DIGIT(p[-1], current_radix))) return((want_symbol) ? make_symbol(sc, q) : sc->F); if (has_plus_or_minus == 0) { if ((has_dec_point1) || (slash1)) return((want_symbol) ? make_symbol(sc, q) : sc->F); has_dec_point1 = true; } else { if ((has_dec_point2) || (slash2)) return((want_symbol) ? make_symbol(sc, q) : sc->F); has_dec_point2 = true; } continue; /* -------- exponent marker -------- */ case 'e': case 'E': #if WITH_EXTRA_EXPONENT_MARKERS case 's': case 'S': case 'd': case 'D': case 'f': case 'F': case 'l': case 'L': #endif if (current_radix > 10) return((want_symbol) ? make_symbol(sc, q) : sc->F); /* see note above */ /* fall through -- if '@' used, radices>10 are ok */ case '@': current_radix = 10; if (((ex1) || (slash1)) && (has_plus_or_minus == 0)) /* ee */ return((want_symbol) ? make_symbol(sc, q) : sc->F); if (((ex2) || (slash2)) && (has_plus_or_minus != 0)) /* 1+1.0ee */ return((want_symbol) ? make_symbol(sc, q) : sc->F); if ((!IS_DIGIT(p[-1], radix)) && /* was current_radix but that's always 10! */ (p[-1] != '.')) return((want_symbol) ? make_symbol(sc, q) : sc->F); if (has_plus_or_minus == 0) { ex1 = p; has_dec_point1 = true; /* decimal point illegal from now on */ } else { ex2 = p; has_dec_point2 = true; } p++; if ((*p == '-') || (*p == '+')) p++; if (IS_DIGIT(*p, current_radix)) continue; break; /* -------- internal + or - -------- */ case '+': case '-': if (has_plus_or_minus != 0) /* already have the separator */ return((want_symbol) ? make_symbol(sc, q) : sc->F); if (c == '+') has_plus_or_minus = 1; else has_plus_or_minus = -1; plus = (char *)(p + 1); continue; /* ratio marker */ case '/': if ((has_plus_or_minus == 0) && ((ex1) || (slash1) || (has_dec_point1))) return((want_symbol) ? make_symbol(sc, q) : sc->F); if ((has_plus_or_minus != 0) && ((ex2) || (slash2) || (has_dec_point2))) return((want_symbol) ? make_symbol(sc, q) : sc->F); if (has_plus_or_minus == 0) slash1 = (char *)(p + 1); else slash2 = (char *)(p + 1); if ((!IS_DIGIT(p[1], current_radix)) || (!IS_DIGIT(p[-1], current_radix))) return((want_symbol) ? make_symbol(sc, q) : sc->F); continue; /* -------- i for the imaginary part -------- */ case 'i': if ((has_plus_or_minus != 0) && (!has_i)) { has_i = true; continue; } break; default: break; } return((want_symbol) ? make_symbol(sc, q) : sc->F); } } if ((has_plus_or_minus != 0) && /* that is, we have an internal + or - */ (!has_i)) /* but no i for the imaginary part */ return((want_symbol) ? make_symbol(sc, q) : sc->F); if (has_i) { #if (!WITH_GMP) s7_double rl = 0.0, im = 0.0; #else char e1 = 0, e2 = 0; #endif s7_pointer result; int len; char ql1, pl1; len = safe_strlen(q); if (q[len - 1] != 'i') return((want_symbol) ? make_symbol(sc, q) : sc->F); /* save original string */ ql1 = q[len - 1]; pl1 = (*(plus - 1)); #if WITH_GMP if (ex1) {e1 = *ex1; (*ex1) = '@';} /* for mpfr */ if (ex2) {e2 = *ex2; (*ex2) = '@';} #endif /* look for cases like 1+i */ if ((q[len - 2] == '+') || (q[len - 2] == '-')) q[len - 1] = '1'; else q[len - 1] = '\0'; /* remove 'i' */ (*((char *)(plus - 1))) = '\0'; /* there is a slight inconsistency here: 1/0 -> nan.0 1/0+0i -> inf.0 (0/1+0i is 0.0) #i1/0+0i -> inf.0 0/0 -> nan.0 0/0+0i -> -nan.0 */ #if (!WITH_GMP) if ((has_dec_point1) || (ex1)) { /* (string->number "1100.1+0.11i" 2) -- need to split into 2 honest reals before passing to non-base-10 str->dbl */ rl = string_to_double_with_radix(q, radix, &overflow); } else { if (slash1) { /* here the overflow could be innocuous if it's in the denominator and the numerator is 0 * 0/100000000000000000000000000000000000000-0i */ s7_int num, den; num = string_to_integer(q, radix, &overflow); den = string_to_integer(slash1, radix, &overflow); if (den == 0) rl = NAN; else { if (num == 0) { rl = 0.0; overflow = false; } else rl = (s7_double)num / (s7_double)den; } } else rl = (s7_double)string_to_integer(q, radix, &overflow); if (overflow) return(real_NaN); } if (rl == -0.0) rl = 0.0; if ((has_dec_point2) || (ex2)) im = string_to_double_with_radix(plus, radix, &overflow); else { if (slash2) { /* same as above: 0-0/100000000000000000000000000000000000000i */ s7_int num, den; num = string_to_integer(plus, radix, &overflow); den = string_to_integer(slash2, radix, &overflow); if (den == 0) im = NAN; else { if (num == 0) { im = 0.0; overflow = false; } else im = (s7_double)num / (s7_double)den; } } else im = (s7_double)string_to_integer(plus, radix, &overflow); if (overflow) return(real_NaN); } if ((has_plus_or_minus == -1) && (im != 0.0)) im = -im; result = s7_make_complex(sc, rl, im); #else result = string_to_either_complex(sc, q, slash1, ex1, has_dec_point1, plus, slash2, ex2, has_dec_point2, radix, has_plus_or_minus); #endif /* restore original string */ q[len - 1] = ql1; (*((char *)(plus - 1))) = pl1; #if WITH_GMP if (ex1) (*ex1) = e1; if (ex2) (*ex2) = e2; #endif return(result); } /* not complex */ if ((has_dec_point1) || (ex1)) { s7_pointer result; if (slash1) /* not complex, so slash and "." is not a number */ return((want_symbol) ? make_symbol(sc, q) : sc->F); #if (!WITH_GMP) result = make_real(sc, string_to_double_with_radix(q, radix, &overflow)); #else { char old_e = 0; if (ex1) { old_e = (*ex1); (*ex1) = '@'; } result = string_to_either_real(sc, q, radix); if (ex1) (*ex1) = old_e; } #endif return(result); } /* not real */ if (slash1) #if (!WITH_GMP) { s7_int n, d; n = string_to_integer(q, radix, &overflow); d = string_to_integer(slash1, radix, &overflow); if ((n == 0) && (d != 0)) /* 0/100000000000000000000000000000000000000 */ return(small_int(0)); if ((d == 0) || (overflow)) return(real_NaN); /* it would be neat to return 1 from 10000000000000000000000000000/10000000000000000000000000000 * but q is the entire number ('/' included) and slash1 is the stuff after the '/', and every * big number comes through here, so there's no clean and safe way to check that q == slash1. */ return(s7_make_ratio(sc, n, d)); } #else return(string_to_either_ratio(sc, q, slash1, radix)); #endif /* integer */ #if (!WITH_GMP) { s7_int x; x = string_to_integer(q, radix, &overflow); if (overflow) return((q[0] == '-') ? real_minus_infinity : real_infinity); return(make_integer(sc, x)); } #else return(string_to_either_integer(sc, q, radix)); #endif } } static s7_pointer s7_string_to_number(s7_scheme *sc, char *str, int radix) { s7_pointer x; x = make_atom(sc, str, radix, NO_SYMBOLS, WITHOUT_OVERFLOW_ERROR); if (s7_is_number(x)) /* only needed because str might start with '#' and not be a number (#t for example) */ return(x); return(sc->F); } static s7_pointer g_string_to_number_1(s7_scheme *sc, s7_pointer args, s7_pointer caller) { #define H_string_to_number "(string->number str (radix 10)) converts str into a number. \ If str does not represent a number, string->number returns #f. If 'str' has an embedded radix, \ the 'radix' it is ignored: (string->number \"#x11\" 2) -> 17 not 3." #define Q_string_to_number s7_make_signature(sc, 3, s7_make_signature(sc, 2, sc->IS_NUMBER, sc->IS_BOOLEAN), sc->IS_STRING, sc->IS_INTEGER) s7_int radix = 0; char *str; if (!is_string(car(args))) method_or_bust(sc, car(args), caller, args, T_STRING, 1); if (is_pair(cdr(args))) { s7_pointer rad, p; rad = cadr(args); if (!s7_is_integer(rad)) { if (!s7_is_integer(p = check_values(sc, rad, cdr(args)))) method_or_bust(sc, rad, caller, args, T_INTEGER, 2); rad = p; } radix = s7_integer(rad); if ((radix < 2) || /* what about negative int as base (Knuth), reals such as phi, and some complex like -1+i */ (radix > 16)) /* the only problem here is printing the number; perhaps put each digit in "()" in base 10: (123)(0)(34) */ return(out_of_range(sc, caller, small_int(2), rad, A_VALID_RADIX)); } else radix = 10; str = (char *)string_value(car(args)); if ((!str) || (!(*str))) return(sc->F); switch (str[0]) { case 'n': if (safe_strcmp(str, "nan.0")) return(real_NaN); break; case 'i': if (safe_strcmp(str, "inf.0")) return(real_infinity); break; case '-': if ((str[1] == 'i') && (safe_strcmp((const char *)(str + 1), "inf.0"))) return(real_minus_infinity); break; case '+': if ((str[1] == 'i') && (safe_strcmp((const char *)(str + 1), "inf.0"))) return(real_infinity); break; } return(s7_string_to_number(sc, str, radix)); } static s7_pointer g_string_to_number(s7_scheme *sc, s7_pointer args) { return(g_string_to_number_1(sc, args, sc->STRING_TO_NUMBER)); } static s7_pointer c_string_to_number(s7_scheme *sc, s7_pointer n) { return(g_string_to_number_1(sc, set_plist_1(sc, n), sc->STRING_TO_NUMBER)); } PF_TO_PF(string_to_number, c_string_to_number) static bool numbers_are_eqv(s7_pointer a, s7_pointer b) { if (type(a) != type(b)) /* (eqv? 1 1.0) -> #f! */ return(false); switch (type(a)) { case T_INTEGER: return((integer(a) == integer(b))); case T_RATIO: return((numerator(a) == numerator(b)) && (denominator(a) == denominator(b))); case T_REAL: if (is_NaN(real(a))) return(false); return(real(a) == real(b)); case T_COMPLEX: if ((is_NaN(real_part(a))) || (is_NaN(imag_part(a)))) return(false); return((real_part(a) == real_part(b)) && (imag_part(a) == imag_part(b))); default: #if WITH_GMP if ((is_big_number(a)) || (is_big_number(b))) /* this can happen if (member bignum ...) -> memv */ return(big_numbers_are_eqv(a, b)); #endif break; } return(false); } static bool is_rational_via_method(s7_scheme *sc, s7_pointer p) { if (s7_is_rational(p)) return(true); if (has_methods(p)) { s7_pointer f; f = find_method(sc, find_let(sc, p), sc->IS_RATIONAL); if (f != sc->UNDEFINED) return(is_true(sc, s7_apply_function(sc, f, cons(sc, p, sc->NIL)))); } return(false); } /* -------------------------------- abs -------------------------------- */ #if (!WITH_GMP) static s7_pointer g_abs(s7_scheme *sc, s7_pointer args) { #define H_abs "(abs x) returns the absolute value of the real number x" #define Q_abs s7_make_signature(sc, 2, sc->IS_REAL, sc->IS_REAL) s7_pointer x; x = car(args); switch (type(x)) { case T_INTEGER: if (integer(x) < 0) { if (integer(x) == s7_int_min) return(make_integer(sc, s7_int_max)); return(make_integer(sc, -integer(x))); } return(x); case T_RATIO: if (numerator(x) < 0) { if (numerator(x) == s7_int_min) return(s7_make_ratio(sc, s7_int_max, denominator(x))); return(s7_make_ratio(sc, -numerator(x), denominator(x))); } return(x); case T_REAL: if (is_NaN(real(x))) /* (abs -nan.0) -> nan.0, not -nan.0 */ return(real_NaN); if (real(x) < 0.0) return(make_real(sc, -real(x))); return(x); default: method_or_bust(sc, x, sc->ABS, args, T_REAL, 0); } } static s7_int c_abs_i(s7_scheme *sc, s7_int arg) {return((arg < 0) ? (-arg) : arg);} IF_TO_IF(abs, c_abs_i) static s7_double c_abs_r(s7_scheme *sc, s7_double arg) {return((arg < 0.0) ? (-arg) : arg);} DIRECT_RF_TO_RF(fabs) /* -------------------------------- magnitude -------------------------------- */ static s7_pointer g_magnitude(s7_scheme *sc, s7_pointer args) { #define H_magnitude "(magnitude z) returns the magnitude of z" #define Q_magnitude s7_make_signature(sc, 2, sc->IS_REAL, sc->IS_NUMBER) s7_pointer x; x = car(args); switch (type(x)) { case T_INTEGER: if (integer(x) == s7_int_min) return(make_integer(sc, s7_int_max)); /* (magnitude -9223372036854775808) -> -9223372036854775808 * same thing happens in abs, lcm and gcd: (gcd -9223372036854775808) -> -9223372036854775808 */ if (integer(x) < 0) return(make_integer(sc, -integer(x))); return(x); case T_RATIO: if (numerator(x) < 0) return(s7_make_ratio(sc, -numerator(x), denominator(x))); return(x); case T_REAL: if (is_NaN(real(x))) /* (magnitude -nan.0) -> nan.0, not -nan.0 */ return(real_NaN); if (real(x) < 0.0) return(make_real(sc, -real(x))); return(x); case T_COMPLEX: return(make_real(sc, hypot(imag_part(x), real_part(x)))); default: method_or_bust_with_type(sc, x, sc->MAGNITUDE, args, A_NUMBER, 0); } } IF_TO_IF(magnitude, c_abs_i) RF_TO_RF(magnitude, c_abs_r) /* -------------------------------- rationalize -------------------------------- */ static s7_pointer g_rationalize(s7_scheme *sc, s7_pointer args) { #define H_rationalize "(rationalize x err) returns the ratio with lowest denominator within err of x" #define Q_rationalize s7_make_signature(sc, 3, sc->IS_RATIONAL, sc->IS_REAL, sc->IS_REAL) s7_double err; s7_pointer x; x = car(args); if (!s7_is_real(x)) method_or_bust(sc, x, sc->RATIONALIZE, args, T_REAL, 1); if (is_not_null(cdr(args))) { s7_pointer ex; ex = cadr(args); if (!s7_is_real(ex)) method_or_bust(sc, ex, sc->RATIONALIZE, args, T_REAL, 2); err = real_to_double(sc, ex, "rationalize"); if (is_NaN(err)) return(out_of_range(sc, sc->RATIONALIZE, small_int(2), cadr(args), ITS_NAN)); if (err < 0.0) err = -err; } else err = sc->default_rationalize_error; switch (type(x)) { case T_INTEGER: { s7_int a, b, pa; if (err < 1.0) return(x); a = s7_integer(x); if (a < 0) pa = -a; else pa = a; if (err >= pa) return(small_int(0)); b = (s7_int)err; pa -= b; if (a < 0) return(make_integer(sc, -pa)); return(make_integer(sc, pa)); } case T_RATIO: if (err == 0.0) return(x); case T_REAL: { s7_double rat; s7_int numer = 0, denom = 1; rat = real_to_double(sc, x, "rationalize"); if ((is_NaN(rat)) || (is_inf(rat))) return(wrong_type_argument_with_type(sc, sc->RATIONALIZE, 1, x, A_NORMAL_REAL)); if (err >= fabs(rat)) return(small_int(0)); if ((rat > 9.2233720368548e+18) || (rat < -9.2233720368548e+18)) return(out_of_range(sc, sc->RATIONALIZE, small_int(1), x, ITS_TOO_LARGE)); if ((fabs(rat) + fabs(err)) < 1.0e-18) err = 1.0e-18; /* (/ 1.0 most-positive-fixnum) is 1.0842021e-19, so if we let err be less than that, * (rationalize 1e-19 1e-20) hangs, but this only affects the initial ceiling, I believe. */ if (fabs(rat) < fabs(err)) return(small_int(0)); if (c_rationalize(rat, err, &numer, &denom)) return(s7_make_ratio(sc, numer, denom)); return(sc->F); } } return(sc->F); /* make compiler happy */ } static s7_pointer c_rats(s7_scheme *sc, s7_pointer x) {return(g_rationalize(sc, set_plist_1(sc, x)));} PF_TO_PF(rationalize, c_rats) /* -------------------------------- angle -------------------------------- */ static s7_pointer g_angle(s7_scheme *sc, s7_pointer args) { #define H_angle "(angle z) returns the angle of z" #define Q_angle s7_make_signature(sc, 2, sc->IS_REAL, sc->IS_NUMBER) s7_pointer x; /* (angle inf+infi) -> 0.78539816339745 ? * I think this should be -pi < ang <= pi */ x = car(args); switch (type(x)) { case T_INTEGER: if (integer(x) < 0) return(real_pi); return(small_int(0)); case T_RATIO: if (numerator(x) < 0) return(real_pi); return(small_int(0)); case T_REAL: if (is_NaN(real(x))) return(x); if (real(x) < 0.0) return(real_pi); return(real_zero); case T_COMPLEX: return(make_real(sc, atan2(imag_part(x), real_part(x)))); default: method_or_bust_with_type(sc, x, sc->ANGLE, args, A_NUMBER, 0); } } /* -------------------------------- make-polar -------------------------------- */ #if (!WITH_PURE_S7) static s7_pointer g_make_polar(s7_scheme *sc, s7_pointer args) { s7_pointer x, y; s7_double ang, mag; #define H_make_polar "(make-polar mag ang) returns a complex number with magnitude mag and angle ang" #define Q_make_polar s7_make_signature(sc, 3, sc->IS_NUMBER, sc->IS_REAL, sc->IS_REAL) x = car(args); y = cadr(args); switch (type(x)) { case T_INTEGER: switch (type(y)) { case T_INTEGER: if (integer(x) == 0) return(x); /* (make-polar 0 1) -> 0 */ if (integer(y) == 0) return(x); /* (make-polar 1 0) -> 1 */ mag = (s7_double)integer(x); ang = (s7_double)integer(y); break; case T_RATIO: if (integer(x) == 0) return(x); mag = (s7_double)integer(x); ang = (s7_double)fraction(y); break; case T_REAL: ang = real(y); if (ang == 0.0) return(x); if (is_NaN(ang)) return(y); if (is_inf(ang)) return(real_NaN); if ((ang == M_PI) || (ang == -M_PI)) return(make_integer(sc, -integer(x))); mag = (s7_double)integer(x); break; default: method_or_bust(sc, y, sc->MAKE_POLAR, args, T_REAL, 2); } break; case T_RATIO: switch (type(y)) { case T_INTEGER: if (integer(y) == 0) return(x); mag = (s7_double)fraction(x); ang = (s7_double)integer(y); break; case T_RATIO: mag = (s7_double)fraction(x); ang = (s7_double)fraction(y); break; case T_REAL: ang = real(y); if (ang == 0.0) return(x); if (is_NaN(ang)) return(y); if (is_inf(ang)) return(real_NaN); if ((ang == M_PI) || (ang == -M_PI)) return(s7_make_ratio(sc, -numerator(x), denominator(x))); mag = (s7_double)fraction(x); break; default: method_or_bust(sc, y, sc->MAKE_POLAR, args, T_REAL, 2); } break; case T_REAL: mag = real(x); switch (type(y)) { case T_INTEGER: if (is_NaN(mag)) return(x); if (integer(y) == 0) return(x); ang = (s7_double)integer(y); break; case T_RATIO: if (is_NaN(mag)) return(x); ang = (s7_double)fraction(y); break; case T_REAL: if (is_NaN(mag)) return(x); ang = real(y); if (ang == 0.0) return(x); if (is_NaN(ang)) return(y); if (is_inf(ang)) return(real_NaN); break; default: method_or_bust(sc, y, sc->MAKE_POLAR, args, T_REAL, 2); } break; default: method_or_bust(sc, x, sc->MAKE_POLAR, args, T_REAL, 1); } return(s7_make_complex(sc, mag * cos(ang), mag * sin(ang))); /* since sin is inaccurate for large arguments, so is make-polar: * (make-polar 1.0 1e40) -> -0.76267273202438+0.64678458842683i, not 8.218988919070239214448025364432557517335E-1-5.696334009536363273080341815735687231337E-1i */ } static s7_pointer c_make_polar_2(s7_scheme *sc, s7_pointer x, s7_pointer y) {return(g_make_polar(sc, set_plist_2(sc, x, y)));} PF2_TO_PF(make_polar, c_make_polar_2) #endif /* -------------------------------- complex -------------------------------- */ static s7_pointer g_complex(s7_scheme *sc, s7_pointer args) { s7_pointer x, y; #define H_complex "(complex x1 x2) returns a complex number with real-part x1 and imaginary-part x2" #define Q_complex s7_make_signature(sc, 3, sc->IS_NUMBER, sc->IS_REAL, sc->IS_REAL) x = car(args); y = cadr(args); switch (type(y)) { case T_INTEGER: switch (type(x)) { case T_INTEGER: if (integer(y) == 0) return(x); return(s7_make_complex(sc, (s7_double)integer(x), (s7_double)integer(y))); case T_RATIO: if (integer(y) == 0) return(x); return(s7_make_complex(sc, (s7_double)fraction(x), (s7_double)integer(y))); case T_REAL: if (integer(y) == 0) return(x); return(s7_make_complex(sc, real(x), (s7_double)integer(y))); default: method_or_bust(sc, x, sc->COMPLEX, args, T_REAL, 1); } case T_RATIO: switch (type(x)) { case T_INTEGER: return(s7_make_complex(sc, (s7_double)integer(x), (s7_double)fraction(y))); case T_RATIO: return(s7_make_complex(sc, (s7_double)fraction(x), (s7_double)fraction(y))); case T_REAL: return(s7_make_complex(sc, real(x), (s7_double)fraction(y))); default: method_or_bust(sc, x, sc->COMPLEX, args, T_REAL, 1); } case T_REAL: switch (type(x)) { case T_INTEGER: if (real(y) == 0.0) return(x); return(s7_make_complex(sc, (s7_double)integer(x), real(y))); case T_RATIO: if (real(y) == 0.0) return(x); return(s7_make_complex(sc, (s7_double)fraction(x), real(y))); case T_REAL: if (real(y) == 0.0) return(x); return(s7_make_complex(sc, real(x), real(y))); default: method_or_bust(sc, x, sc->COMPLEX, args, T_REAL, 1); } default: method_or_bust(sc, (is_let(x)) ? x : y, sc->COMPLEX, args, T_REAL, 2); } } static s7_pointer c_make_complex_2(s7_scheme *sc, s7_pointer x, s7_pointer y) {return(g_complex(sc, set_plist_2(sc, x, y)));} PF2_TO_PF(make_complex, c_make_complex_2) /* -------------------------------- exp -------------------------------- */ static s7_pointer g_exp(s7_scheme *sc, s7_pointer args) { #define H_exp "(exp z) returns e^z, (exp 1) is 2.718281828459" #define Q_exp pcl_n s7_pointer x; x = car(args); switch (type(x)) { case T_INTEGER: if (integer(x) == 0) return(small_int(1)); /* (exp 0) -> 1 */ return(make_real(sc, exp((s7_double)(integer(x))))); case T_RATIO: return(make_real(sc, exp((s7_double)fraction(x)))); case T_REAL: return(make_real(sc, exp(real(x)))); case T_COMPLEX: #if HAVE_COMPLEX_NUMBERS return(s7_from_c_complex(sc, cexp(as_c_complex(x)))); /* this is inaccurate for large arguments: * (exp 0+1e20i) -> -0.66491178990701-0.74692189125949i, not 7.639704044417283004001468027378811228331E-1-6.45251285265780844205811711312523007406E-1i */ #else return(out_of_range(sc, sc->EXP, small_int(1), x, NO_COMPLEX_NUMBERS)); #endif default: method_or_bust_with_type(sc, x, sc->EXP, args, A_NUMBER, 0); } } DIRECT_RF_TO_RF(exp) /* -------------------------------- log -------------------------------- */ #if __cplusplus #define LOG_2 1.4426950408889634074 #else #define LOG_2 1.4426950408889634073599246810018921L /* (/ (log 2.0)) */ #endif static s7_pointer g_log(s7_scheme *sc, s7_pointer args) { #define H_log "(log z1 (z2 e)) returns log(z1) / log(z2) where z2 (the base) defaults to e: (log 8 2) = 3" #define Q_log pcl_n s7_pointer x; x = car(args); if (!s7_is_number(x)) method_or_bust_with_type(sc, x, sc->LOG, args, A_NUMBER, 1); if (is_pair(cdr(args))) { s7_pointer y; y = cadr(args); if (!(s7_is_number(y))) method_or_bust_with_type(sc, y, sc->LOG, args, A_NUMBER, 2); if (y == small_int(2)) { /* (define (2^n? x) (and (not (zero? x)) (zero? (logand x (- x 1))))) */ if (is_integer(x)) { s7_int ix; ix = s7_integer(x); if (ix > 0) { s7_double fx; #if (__ANDROID__) || (MS_WINDOWS) || ((__GNUC__) && ((__GNUC__ < 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ <= 4)))) /* just a guess -- log2 gets a warning in gcc 4.3.2, but not in 4.4.4 */ fx = log((double)ix) / log(2.0); #else fx = log2((double)ix); #endif /* (s7_int)fx rounds (log 8 2) to 2 in FreeBSD! */ #if ((__GNUC__) && ((__GNUC__ < 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ < 4)))) return(make_real(sc, fx)); #else if ((ix & (ix - 1)) == 0) return(make_integer(sc, (s7_int)s7_round(fx))); return(make_real(sc, fx)); #endif } } if ((s7_is_real(x)) && (s7_is_positive(x))) return(make_real(sc, log(real_to_double(sc, x, "log")) * LOG_2)); return(s7_from_c_complex(sc, clog(s7_to_c_complex(x)) * LOG_2)); } if ((x == small_int(1)) && (y == small_int(1))) /* (log 1 1) -> 0 (this is NaN in the bignum case) */ return(small_int(0)); /* (log 1 0) must be 0 since everyone says (expt 0 0) is 1 */ if (s7_is_zero(y)) { if ((y == small_int(0)) && (x == small_int(1))) return(y); return(out_of_range(sc, sc->LOG, small_int(2), y, make_string_wrapper(sc, "can't be 0"))); } if (s7_is_one(y)) /* this used to raise an error, but the bignum case is simpler if we return inf */ { if (s7_is_one(x)) /* but (log 1.0 1.0) -> 0.0 */ return(real_zero); return(real_infinity); /* currently (log 1/0 1) is inf? */ } if ((s7_is_real(x)) && (s7_is_real(y)) && (s7_is_positive(x)) && (s7_is_positive(y))) { if ((s7_is_rational(x)) && (s7_is_rational(y))) { s7_double res; s7_int ires; res = log(rational_to_double(sc, x)) / log(rational_to_double(sc, y)); ires = (s7_int)res; if (res - ires == 0.0) return(make_integer(sc, ires)); /* (log 8 2) -> 3 or (log 1/8 2) -> -3 */ return(make_real(sc, res)); /* perhaps use rationalize here? (log 2 8) -> 1/3 */ } return(make_real(sc, log(real_to_double(sc, x, "log")) / log(real_to_double(sc, y, "log")))); } return(s7_from_c_complex(sc, clog(s7_to_c_complex(x)) / clog(s7_to_c_complex(y)))); } if (s7_is_real(x)) { if (s7_is_positive(x)) return(make_real(sc, log(real_to_double(sc, x, "log")))); return(s7_make_complex(sc, log(-real_to_double(sc, x, "log")), M_PI)); } return(s7_from_c_complex(sc, clog(s7_to_c_complex(x)))); } /* -------------------------------- sin -------------------------------- */ static s7_pointer g_sin(s7_scheme *sc, s7_pointer args) { #define H_sin "(sin z) returns sin(z)" #define Q_sin pcl_n s7_pointer x; x = car(args); switch (type(x)) { case T_REAL: return(make_real(sc, sin(real(x)))); case T_INTEGER: if (integer(x) == 0) return(small_int(0)); /* (sin 0) -> 0 */ return(make_real(sc, sin((s7_double)integer(x)))); case T_RATIO: return(make_real(sc, sin((s7_double)(fraction(x))))); case T_COMPLEX: #if HAVE_COMPLEX_NUMBERS return(s7_from_c_complex(sc, csin(as_c_complex(x)))); #else return(out_of_range(sc, sc->SIN, small_int(1), x, NO_COMPLEX_NUMBERS)); #endif default: method_or_bust_with_type(sc, x, sc->SIN, args, A_NUMBER, 0); } /* sin is totally inaccurate over about 1e18. There's a way to get true results, * but it involves fancy "range reduction" techniques. * This means that lots of things are inaccurate: * (sin (remainder 1e22 (* 2 pi))) * -0.57876806033477 * but it should be -8.522008497671888065747423101326159661908E-1 * --- * (remainder 1e22 (* 2 pi)) -> 1.0057952155665e+22 !! * it should be 5.263007914620499494429139986095833592117E0 */ } DIRECT_RF_TO_RF(sin) /* -------------------------------- cos -------------------------------- */ static s7_pointer g_cos(s7_scheme *sc, s7_pointer args) { #define H_cos "(cos z) returns cos(z)" #define Q_cos pcl_n s7_pointer x; x = car(args); switch (type(x)) { case T_REAL: return(make_real(sc, cos(real(x)))); case T_INTEGER: if (integer(x) == 0) return(small_int(1)); /* (cos 0) -> 1 */ return(make_real(sc, cos((s7_double)integer(x)))); case T_RATIO: return(make_real(sc, cos((s7_double)(fraction(x))))); case T_COMPLEX: #if HAVE_COMPLEX_NUMBERS return(s7_from_c_complex(sc, ccos(as_c_complex(x)))); #else return(out_of_range(sc, sc->COS, small_int(1), x, NO_COMPLEX_NUMBERS)); #endif default: method_or_bust_with_type(sc, x, sc->COS, args, A_NUMBER, 0); } } DIRECT_RF_TO_RF(cos) /* -------------------------------- tan -------------------------------- */ static s7_pointer g_tan(s7_scheme *sc, s7_pointer args) { #define H_tan "(tan z) returns tan(z)" #define Q_tan pcl_n s7_pointer x; x = car(args); switch (type(x)) { case T_REAL: return(make_real(sc, tan(real(x)))); case T_INTEGER: if (integer(x) == 0) return(small_int(0)); /* (tan 0) -> 0 */ return(make_real(sc, tan((s7_double)(integer(x))))); case T_RATIO: return(make_real(sc, tan((s7_double)(fraction(x))))); case T_COMPLEX: #if HAVE_COMPLEX_NUMBERS if (imag_part(x) > 350.0) return(s7_make_complex(sc, 0.0, 1.0)); if (imag_part(x) < -350.0) return(s7_make_complex(sc, 0.0, -1.0)); return(s7_from_c_complex(sc, ctan(as_c_complex(x)))); #else return(out_of_range(sc, sc->TAN, small_int(1), x, NO_COMPLEX_NUMBERS)); #endif default: method_or_bust_with_type(sc, x, sc->TAN, args, A_NUMBER, 0); } } DIRECT_RF_TO_RF(tan) /* -------------------------------- asin -------------------------------- */ static s7_pointer c_asin(s7_scheme *sc, s7_double x) { s7_double absx, recip; s7_complex result; absx = fabs(x); if (absx <= 1.0) return(make_real(sc, asin(x))); /* otherwise use maxima code: */ recip = 1.0 / absx; result = (M_PI / 2.0) - (_Complex_I * clog(absx * (1.0 + (sqrt(1.0 + recip) * csqrt(1.0 - recip))))); if (x < 0.0) return(s7_from_c_complex(sc, -result)); return(s7_from_c_complex(sc, result)); } static s7_pointer g_asin_1(s7_scheme *sc, s7_pointer n) { switch (type(n)) { case T_INTEGER: if (integer(n) == 0) return(small_int(0)); /* (asin 0) -> 0 */ /* in netBSD, (asin 2) returns 0.25383842987008+0.25383842987008i according to Peter Bex */ return(c_asin(sc, (s7_double)integer(n))); case T_RATIO: return(c_asin(sc, (s7_double)numerator(n) / (s7_double)denominator(n))); case T_REAL: return(c_asin(sc, real(n))); case T_COMPLEX: #if HAVE_COMPLEX_NUMBERS /* if either real or imag part is very large, use explicit formula, not casin */ /* this code taken from sbcl's src/code/irrat.lisp */ /* break is around x+70000000i */ if ((fabs(real_part(n)) > 1.0e7) || (fabs(imag_part(n)) > 1.0e7)) { s7_complex sq1mz, sq1pz, z; z = as_c_complex(n); sq1mz = csqrt(1.0 - z); sq1pz = csqrt(1.0 + z); return(s7_make_complex(sc, atan(real_part(n) / creal(sq1mz * sq1pz)), asinh(cimag(sq1pz * conj(sq1mz))))); } return(s7_from_c_complex(sc, casin(as_c_complex(n)))); #else return(out_of_range(sc, sc->ASIN, small_int(1), n, NO_COMPLEX_NUMBERS)); #endif default: method_or_bust_with_type(sc, n, sc->ASIN, list_1(sc, n), A_NUMBER, 0); } } static s7_pointer g_asin(s7_scheme *sc, s7_pointer args) { #define H_asin "(asin z) returns asin(z); (sin (asin x)) = x" #define Q_asin pcl_n return(g_asin_1(sc, car(args))); } R_P_F_TO_PF(asin, c_asin, g_asin_1, g_asin_1) /* g_asin_1 is safe for the gf case because it won't trigger the GC before it is done with its argument */ /* -------------------------------- acos -------------------------------- */ static s7_pointer c_acos(s7_scheme *sc, s7_double x) { s7_double absx, recip; s7_complex result; absx = fabs(x); if (absx <= 1.0) return(make_real(sc, acos(x))); /* else follow maxima again: */ recip = 1.0 / absx; if (x > 0.0) result = _Complex_I * clog(absx * (1.0 + (sqrt(1.0 + recip) * csqrt(1.0 - recip)))); else result = M_PI - _Complex_I * clog(absx * (1.0 + (sqrt(1.0 + recip) * csqrt(1.0 - recip)))); return(s7_from_c_complex(sc, result)); } static s7_pointer g_acos_1(s7_scheme *sc, s7_pointer n) { switch (type(n)) { case T_INTEGER: if (integer(n) == 1) return(small_int(0)); return(c_acos(sc, (s7_double)integer(n))); case T_RATIO: return(c_acos(sc, (s7_double)numerator(n) / (s7_double)denominator(n))); case T_REAL: return(c_acos(sc, real(n))); case T_COMPLEX: #if HAVE_COMPLEX_NUMBERS /* if either real or imag part is very large, use explicit formula, not cacos */ /* this code taken from sbcl's src/code/irrat.lisp */ if ((fabs(real_part(n)) > 1.0e7) || (fabs(imag_part(n)) > 1.0e7)) { s7_complex sq1mz, sq1pz, z; z = as_c_complex(n); sq1mz = csqrt(1.0 - z); sq1pz = csqrt(1.0 + z); return(s7_make_complex(sc, 2.0 * atan(creal(sq1mz) / creal(sq1pz)), asinh(cimag(sq1mz * conj(sq1pz))))); } return(s7_from_c_complex(sc, cacos(s7_to_c_complex(n)))); #else return(out_of_range(sc, sc->ACOS, small_int(1), n, NO_COMPLEX_NUMBERS)); #endif default: method_or_bust_with_type(sc, n, sc->ACOS, list_1(sc, n), A_NUMBER, 0); } } static s7_pointer g_acos(s7_scheme *sc, s7_pointer args) { #define H_acos "(acos z) returns acos(z); (cos (acos 1)) = 1" #define Q_acos pcl_n return(g_acos_1(sc, car(args))); } R_P_F_TO_PF(acos, c_acos, g_acos_1, g_acos_1) /* -------------------------------- atan -------------------------------- */ static s7_double c_atan(s7_scheme *sc, s7_double x, s7_double y) { return(atan2(x, y)); } static s7_pointer g_atan(s7_scheme *sc, s7_pointer args) { #define H_atan "(atan z) returns atan(z), (atan y x) returns atan(y/x)" #define Q_atan s7_make_signature(sc, 3, sc->IS_NUMBER, sc->IS_NUMBER, sc->IS_REAL) /* actually if there are two args, both should be real, but how to express that in the signature? */ s7_pointer x, y; s7_double x1, x2; /* currently (atan inf.0 inf.0) -> 0.78539816339745, and (atan inf.0 -inf.0) -> 2.3561944901923 (etc) */ x = car(args); if (!is_pair(cdr(args))) { switch (type(x)) { case T_INTEGER: if (integer(x) == 0) return(small_int(0)); /* (atan 0) -> 0 */ case T_RATIO: case T_REAL: return(make_real(sc, atan(real_to_double(sc, x, "atan")))); case T_COMPLEX: #if HAVE_COMPLEX_NUMBERS return(s7_from_c_complex(sc, catan(as_c_complex(x)))); #else return(out_of_range(sc, sc->ATAN, small_int(1), x, NO_COMPLEX_NUMBERS)); #endif default: method_or_bust_with_type(sc, x, sc->ATAN, args, A_NUMBER, 0); } } if (!s7_is_real(x)) method_or_bust(sc, x, sc->ATAN, args, T_REAL, 1); y = cadr(args); if (!s7_is_real(y)) method_or_bust(sc, y, sc->ATAN, args, T_REAL, 2); x1 = real_to_double(sc, x, "atan"); x2 = real_to_double(sc, y, "atan"); return(make_real(sc, atan2(x1, x2))); } RF2_TO_RF(atan, c_atan) /* -------------------------------- sinh -------------------------------- */ static s7_pointer g_sinh(s7_scheme *sc, s7_pointer args) { #define H_sinh "(sinh z) returns sinh(z)" #define Q_sinh pcl_n s7_pointer x; x = car(args); switch (type(x)) { case T_INTEGER: if (integer(x) == 0) return(small_int(0)); /* (sinh 0) -> 0 */ case T_REAL: case T_RATIO: return(make_real(sc, sinh(real_to_double(sc, x, "sinh")))); case T_COMPLEX: #if HAVE_COMPLEX_NUMBERS return(s7_from_c_complex(sc, csinh(as_c_complex(x)))); #else return(out_of_range(sc, sc->SINH, small_int(1), x, NO_COMPLEX_NUMBERS)); #endif default: method_or_bust_with_type(sc, x, sc->SINH, args, A_NUMBER, 0); } } DIRECT_RF_TO_RF(sinh) /* -------------------------------- cosh -------------------------------- */ static s7_pointer g_cosh(s7_scheme *sc, s7_pointer args) { #define H_cosh "(cosh z) returns cosh(z)" #define Q_cosh pcl_n s7_pointer x; x = car(args); switch (type(x)) { case T_INTEGER: if (integer(x) == 0) return(small_int(1)); /* (cosh 0) -> 1 */ case T_REAL: case T_RATIO: /* this is not completely correct when optimization kicks in. * :(define (hi) (do ((i 0 (+ i 1))) ((= i 1)) (display (cosh i)))) * hi * :(hi) * 1.0() * :(cosh 0) * 1 */ return(make_real(sc, cosh(real_to_double(sc, x, "cosh")))); case T_COMPLEX: #if HAVE_COMPLEX_NUMBERS return(s7_from_c_complex(sc, ccosh(as_c_complex(x)))); #else return(out_of_range(sc, sc->COSH, small_int(1), x, NO_COMPLEX_NUMBERS)); #endif default: method_or_bust_with_type(sc, x, sc->COSH, args, A_NUMBER, 0); } } DIRECT_RF_TO_RF(cosh) /* -------------------------------- tanh -------------------------------- */ static s7_pointer g_tanh(s7_scheme *sc, s7_pointer args) { #define H_tanh "(tanh z) returns tanh(z)" #define Q_tanh pcl_n s7_pointer x; x = car(args); switch (type(x)) { case T_INTEGER: if (integer(x) == 0) return(small_int(0)); /* (tanh 0) -> 0 */ case T_REAL: case T_RATIO: return(make_real(sc, tanh(real_to_double(sc, x, "tanh")))); case T_COMPLEX: #if HAVE_COMPLEX_NUMBERS if (real_part(x) > 350.0) return(real_one); /* closer than 0.0 which is what ctanh is about to return! */ if (real_part(x) < -350.0) return(make_real(sc, -1.0)); /* closer than ctanh's -0.0 */ return(s7_from_c_complex(sc, ctanh(as_c_complex(x)))); #else return(out_of_range(sc, sc->TANH, small_int(1), x, NO_COMPLEX_NUMBERS)); #endif default: method_or_bust_with_type(sc, x, sc->TANH, args, A_NUMBER, 0); } } DIRECT_RF_TO_RF(tanh) /* -------------------------------- asinh -------------------------------- */ static s7_pointer c_asinh_1(s7_scheme *sc, s7_pointer x) { switch (type(x)) { case T_INTEGER: if (integer(x) == 0) return(small_int(0)); return(make_real(sc, asinh((s7_double)integer(x)))); case T_RATIO: return(make_real(sc, asinh((s7_double)numerator(x) / (s7_double)denominator(x)))); case T_REAL: return(make_real(sc, asinh(real(x)))); case T_COMPLEX: #if HAVE_COMPLEX_NUMBERS #if (defined(__OpenBSD__)) || (defined(__NetBSD__)) return(s7_from_c_complex(sc, casinh_1(as_c_complex(x)))); #else return(s7_from_c_complex(sc, casinh(as_c_complex(x)))); #endif #else return(out_of_range(sc, sc->ASINH, small_int(1), x, NO_COMPLEX_NUMBERS)); #endif default: method_or_bust_with_type(sc, x, sc->ASINH, list_1(sc, x), A_NUMBER, 0); } } static s7_pointer g_asinh(s7_scheme *sc, s7_pointer args) { #define H_asinh "(asinh z) returns asinh(z)" #define Q_asinh pcl_n return(c_asinh_1(sc, car(args))); } static s7_pointer c_asinh(s7_scheme *sc, s7_double x) { return(make_real(sc, asinh(x))); } R_P_F_TO_PF(asinh, c_asinh, c_asinh_1, c_asinh_1) /* -------------------------------- acosh -------------------------------- */ static s7_pointer c_acosh_1(s7_scheme *sc, s7_pointer x) { switch (type(x)) { case T_INTEGER: if (integer(x) == 1) return(small_int(0)); case T_REAL: case T_RATIO: { double x1; x1 = real_to_double(sc, x, "acosh"); if (x1 >= 1.0) return(make_real(sc, acosh(x1))); } case T_COMPLEX: #if HAVE_COMPLEX_NUMBERS #ifdef __OpenBSD__ return(s7_from_c_complex(sc, cacosh_1(s7_to_c_complex(x)))); #else return(s7_from_c_complex(sc, cacosh(s7_to_c_complex(x)))); /* not as_c_complex because x might not be complex */ #endif #else /* since we can fall through to this branch, we need a better error message than "must be a number, not 0.0" */ return(out_of_range(sc, sc->ACOSH, small_int(1), x, NO_COMPLEX_NUMBERS)); #endif default: method_or_bust_with_type(sc, x, sc->ACOSH, list_1(sc, x), A_NUMBER, 0); } } static s7_pointer g_acosh(s7_scheme *sc, s7_pointer args) { #define H_acosh "(acosh z) returns acosh(z)" #define Q_acosh pcl_n return(c_acosh_1(sc, car(args))); } static s7_pointer c_acosh(s7_scheme *sc, s7_double x) { if (x >= 1.0) return(make_real(sc, acosh(x))); return(c_acosh_1(sc, set_plist_1(sc, make_real(sc, x)))); } R_P_F_TO_PF(acosh, c_acosh, c_acosh_1, c_acosh_1) /* -------------------------------- atanh -------------------------------- */ static s7_pointer c_atanh_1(s7_scheme *sc, s7_pointer x) { switch (type(x)) { case T_INTEGER: if (integer(x) == 0) return(small_int(0)); /* (atanh 0) -> 0 */ case T_REAL: case T_RATIO: { double x1; x1 = real_to_double(sc, x, "atanh"); if (fabs(x1) < 1.0) return(make_real(sc, atanh(x1))); } /* if we can't distinguish x from 1.0 even with long doubles, we'll get inf.0: * (atanh 9223372036854775/9223372036854776) -> 18.714973875119 * (atanh 92233720368547758/92233720368547757) -> inf.0 */ case T_COMPLEX: #if HAVE_COMPLEX_NUMBERS #if (defined(__OpenBSD__)) || (defined(__NetBSD__)) return(s7_from_c_complex(sc, catanh_1(s7_to_c_complex(x)))); #else return(s7_from_c_complex(sc, catanh(s7_to_c_complex(x)))); #endif #else return(out_of_range(sc, sc->ATANH, small_int(1), x, NO_COMPLEX_NUMBERS)); #endif default: method_or_bust_with_type(sc, x, sc->ATANH, list_1(sc, x), A_NUMBER, 0); } } static s7_pointer g_atanh(s7_scheme *sc, s7_pointer args) { #define H_atanh "(atanh z) returns atanh(z)" #define Q_atanh pcl_n return(c_atanh_1(sc, car(args))); } static s7_pointer c_atanh(s7_scheme *sc, s7_double x) { if (fabs(x) < 1.0) return(make_real(sc, atanh(x))); return(c_atanh_1(sc, set_plist_1(sc, make_real(sc, x)))); } R_P_F_TO_PF(atanh, c_atanh, c_atanh_1, c_atanh_1) /* -------------------------------- sqrt -------------------------------- */ static s7_pointer g_sqrt(s7_scheme *sc, s7_pointer args) { #define H_sqrt "(sqrt z) returns the square root of z" #define Q_sqrt pcl_n s7_pointer n; s7_double sqx; n = car(args); switch (type(n)) { case T_INTEGER: if (integer(n) >= 0) { s7_int ix; sqx = sqrt((s7_double)integer(n)); ix = (s7_int)sqx; if ((ix * ix) == integer(n)) return(make_integer(sc, ix)); return(make_real(sc, sqx)); /* Mark Weaver notes that * (zero? (- (sqrt 9007199136250226) 94906265.0)) -> #t * but (* 94906265 94906265) -> 9007199136250225 -- oops * at least we return a real here, not an incorrect integer and * (sqrt 9007199136250225) -> 94906265 */ } sqx = (s7_double)integer(n); /* we're trying to protect against (sqrt -9223372036854775808) where we can't negate the integer argument */ return(s7_make_complex(sc, 0.0, sqrt((s7_double)(-sqx)))); case T_RATIO: sqx = (s7_double)fraction(n); if (sqx > 0.0) /* else it's complex, so it can't be a ratio */ { s7_int nm = 0, dn = 1; if (c_rationalize(sqx, 1.0e-16, &nm, &dn)) /* 1e-16 so that (sqrt 1/1099511627776) returns 1/1048576 */ { #if HAVE_OVERFLOW_CHECKS s7_int nm2, dn2; if ((multiply_overflow(nm, nm, &nm2)) || (multiply_overflow(dn, dn, &dn2))) return(make_real(sc, sqrt(sqx))); if ((nm2 == numerator(n)) && (dn2 == denominator(n))) return(s7_make_ratio(sc, nm, dn)); #else if ((nm * nm == numerator(n)) && (dn * dn == denominator(n))) return(s7_make_ratio(sc, nm, dn)); #endif } return(make_real(sc, sqrt(sqx))); } return(s7_make_complex(sc, 0.0, sqrt(-sqx))); case T_REAL: if (is_NaN(real(n))) return(real_NaN); if (real(n) >= 0.0) return(make_real(sc, sqrt(real(n)))); return(s7_make_complex(sc, 0.0, sqrt(-real(n)))); case T_COMPLEX: /* (* inf.0 (sqrt -1)) -> -nan+infi, but (sqrt -inf.0) -> 0+infi */ #if HAVE_COMPLEX_NUMBERS return(s7_from_c_complex(sc, csqrt(as_c_complex(n)))); #else return(out_of_range(sc, sc->SQRT, small_int(1), n, NO_COMPLEX_NUMBERS)); #endif default: method_or_bust_with_type(sc, n, sc->SQRT, args, A_NUMBER, 0); } } /* -------------------------------- expt -------------------------------- */ static s7_int int_to_int(s7_int x, s7_int n) { /* from GSL */ s7_int value = 1; do { if (n & 1) value *= x; n >>= 1; #if HAVE_OVERFLOW_CHECKS if (multiply_overflow(x, x, &x)) break; #else x *= x; #endif } while (n); return(value); } static const long long int nth_roots[63] = { S7_LLONG_MAX, S7_LLONG_MAX, 3037000499LL, 2097151, 55108, 6208, 1448, 511, 234, 127, 78, 52, 38, 28, 22, 18, 15, 13, 11, 9, 8, 7, 7, 6, 6, 5, 5, 5, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}; static const long int_nth_roots[31] = { S7_LONG_MAX, S7_LONG_MAX, 46340, 1290, 215, 73, 35, 21, 14, 10, 8, 7, 5, 5, 4, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}; static bool int_pow_ok(s7_int x, s7_int y) { if (s7_int_bits > 31) return((y < 63) && (nth_roots[y] >= s7_int_abs(x))); return((y < 31) && (int_nth_roots[y] >= s7_int_abs(x))); } static s7_pointer g_expt(s7_scheme *sc, s7_pointer args) { #define H_expt "(expt z1 z2) returns z1^z2" #define Q_expt pcl_n s7_pointer n, pw; n = car(args); if (!s7_is_number(n)) method_or_bust_with_type(sc, n, sc->EXPT, args, A_NUMBER, 1); pw = cadr(args); if (!s7_is_number(pw)) method_or_bust_with_type(sc, pw, sc->EXPT, args, A_NUMBER, 2); /* this provides more than 2 args to expt: * if (is_not_null(cddr(args))) * return(g_expt(sc, list_2(sc, car(args), g_expt(sc, cdr(args))))); * * but it's unusual in scheme to process args in reverse order, and the * syntax by itself is ambiguous (does (expt 2 2 3) = 256 or 64?) */ if (s7_is_zero(n)) { if (s7_is_zero(pw)) { if ((s7_is_integer(n)) && (s7_is_integer(pw))) /* (expt 0 0) -> 1 */ return(small_int(1)); return(real_zero); /* (expt 0.0 0) -> 0.0 */ } if (s7_is_real(pw)) { if (s7_is_negative(pw)) /* (expt 0 -1) */ return(division_by_zero_error(sc, sc->EXPT, args)); /* (Clisp gives divide-by-zero error here, Guile returns inf.0) */ if ((!s7_is_rational(pw)) && /* (expt 0 most-positive-fixnum) */ (is_NaN(s7_real(pw)))) /* (expt 0 +nan.0) */ return(pw); } else { /* (expt 0 a+bi) */ if (real_part(pw) < 0.0) /* (expt 0 -1+i) */ return(division_by_zero_error(sc, sc->EXPT, args)); if ((is_NaN(real_part(pw))) || /* (expt 0 0+1/0i) */ (is_NaN(imag_part(pw)))) return(real_NaN); } if ((s7_is_integer(n)) && (s7_is_integer(pw))) /* pw != 0, (expt 0 2312) */ return(small_int(0)); return(real_zero); /* (expt 0.0 123123) */ } if (s7_is_one(pw)) { if (s7_is_integer(pw)) return(n); if (is_rational(n)) return(make_real(sc, rational_to_double(sc, n))); return(n); } if (is_t_integer(pw)) { s7_int y; y = integer(pw); if (y == 0) { if (is_rational(n)) /* (expt 3 0) */ return(small_int(1)); if ((is_NaN(s7_real_part(n))) || /* (expt 1/0 0) -> NaN */ (is_NaN(s7_imag_part(n)))) /* (expt (complex 0 1/0) 0) -> NaN */ return(n); return(real_one); /* (expt 3.0 0) */ } switch (type(n)) { case T_INTEGER: { s7_int x; x = s7_integer(n); if (x == 1) /* (expt 1 y) */ return(n); if (x == -1) { if (y == s7_int_min) /* (expt -1 most-negative-fixnum) */ return(small_int(1)); if (s7_int_abs(y) & 1) /* (expt -1 odd-int) */ return(n); return(small_int(1)); /* (expt -1 even-int) */ } if (y == s7_int_min) /* (expt x most-negative-fixnum) */ return(small_int(0)); if (x == s7_int_min) /* (expt most-negative-fixnum y) */ return(make_real(sc, pow((double)x, (double)y))); if (int_pow_ok(x, s7_int_abs(y))) { if (y > 0) return(make_integer(sc, int_to_int(x, y))); return(s7_make_ratio(sc, 1, int_to_int(x, -y))); } } break; case T_RATIO: { s7_int nm, dn; nm = numerator(n); dn = denominator(n); if (y == s7_int_min) { if (s7_int_abs(nm) > dn) return(small_int(0)); /* (expt 4/3 most-negative-fixnum) -> 0? */ return(real_infinity); /* (expt 3/4 most-negative-fixnum) -> inf? */ } if ((int_pow_ok(nm, s7_int_abs(y))) && (int_pow_ok(dn, s7_int_abs(y)))) { if (y > 0) return(s7_make_ratio(sc, int_to_int(nm, y), int_to_int(dn, y))); return(s7_make_ratio(sc, int_to_int(dn, -y), int_to_int(nm, -y))); } } break; /* occasionally int^rat can be int but it happens so infrequently it's probably not worth checking * one possibly easy case: (expt 1 1/2) -> 1 (-1?) etc */ case T_REAL: /* (expt -1.0 most-positive-fixnum) should be -1.0 * (expt -1.0 (+ (expt 2 53) 1)) -> -1.0 * (expt -1.0 (- 1 (expt 2 54))) -> -1.0 */ if (real(n) == -1.0) { if (y == s7_int_min) return(real_one); if (s7_int_abs(y) & 1) return(n); return(real_one); } break; case T_COMPLEX: #if HAVE_COMPLEX_NUMBERS if ((s7_real_part(n) == 0.0) && ((s7_imag_part(n) == 1.0) || (s7_imag_part(n) == -1.0))) { bool yp, np; yp = (y > 0); np = (s7_imag_part(n) > 0.0); switch (s7_int_abs(y) % 4) { case 0: return(real_one); case 1: return(s7_make_complex(sc, 0.0, (yp == np) ? 1.0 : -1.0)); case 2: return(make_real(sc, -1.0)); case 3: return(s7_make_complex(sc, 0.0, (yp == np) ? -1.0 : 1.0)); } } #else return(out_of_range(sc, sc->EXPT, small_int(2), n, NO_COMPLEX_NUMBERS)); #endif break; } } if ((s7_is_real(n)) && (s7_is_real(pw))) { s7_double x, y; if ((is_t_ratio(pw)) && (numerator(pw) == 1)) { if (denominator(pw) == 2) return(g_sqrt(sc, args)); if (denominator(pw) == 3) return(make_real(sc, cbrt(real_to_double(sc, n, "expt")))); /* (expt 27 1/3) should be 3, not 3.0... */ /* but: (expt 512/729 1/3) -> 0.88888888888889 */ /* and 4 -> sqrt(sqrt...) etc? */ } x = real_to_double(sc, n, "expt"); y = real_to_double(sc, pw, "expt"); if (is_NaN(x)) return(n); if (is_NaN(y)) return(pw); if (y == 0.0) return(real_one); if (x > 0.0) return(make_real(sc, pow(x, y))); /* tricky cases abound here: (expt -1 1/9223372036854775807) */ } /* (expt 0+i 1e+16) = 0.98156860153485-0.19111012657867i ? * (expt 0+i 1+1/0i) = 0.0 ?? */ return(s7_from_c_complex(sc, cpow(s7_to_c_complex(n), s7_to_c_complex(pw)))); } #if (!WITH_GMP) static s7_pointer c_expt_i(s7_scheme *sc, s7_int x, s7_int y) { if (y == 0) return(small_int(1)); if (y == 1) return(make_integer(sc, x)); return(g_expt(sc, set_plist_2(sc, make_integer(sc, x), make_integer(sc, y)))); } static s7_pointer c_expt_r(s7_scheme *sc, s7_double x, s7_double y) { if (y > 0.0) return(make_real(sc, pow(x, y))); return(g_expt(sc, set_plist_2(sc, make_real(sc, x), make_real(sc, y)))); } static s7_pointer c_expt_2(s7_scheme *sc, s7_pointer x, s7_pointer y) { return(g_expt(sc, set_plist_2(sc, x, y))); } XF2_TO_PF(expt, c_expt_i, c_expt_r, c_expt_2) #endif /* -------------------------------- lcm -------------------------------- */ static s7_pointer g_lcm(s7_scheme *sc, s7_pointer args) { #define H_lcm "(lcm ...) returns the least common multiple of its rational arguments" #define Q_lcm pcl_f s7_int n = 1, d = 0; s7_pointer p; if (!is_pair(args)) return(small_int(1)); if (!is_pair(cdr(args))) { if (!is_rational(car(args))) method_or_bust_with_type(sc, car(args), sc->LCM, args, A_RATIONAL, 1); return(g_abs(sc, args)); } for (p = args; is_pair(p); p = cdr(p)) { s7_pointer x; s7_int b; x = car(p); switch (type(x)) { case T_INTEGER: if (integer(x) == 0) n = 0; else { b = integer(x); if (b < 0) b = -b; n = (n / c_gcd(n, b)) * b; } if (d != 0) d = 1; break; case T_RATIO: b = numerator(x); if (b < 0) b = -b; n = (n / c_gcd(n, b)) * b; if (d == 0) { if (p == args) d = s7_denominator(x); else d = 1; } else d = c_gcd(d, s7_denominator(x)); break; default: method_or_bust_with_type(sc, x, sc->LCM, cons(sc, (d <= 1) ? make_integer(sc, n) : s7_make_ratio(sc, n, d), p), A_RATIONAL, position_of(p, args)); } if (n < 0) return(simple_out_of_range(sc, sc->LCM, args, RESULT_IS_TOO_LARGE)); if (n == 0) { for (p = cdr(p); is_pair(p); p = cdr(p)) if (!is_rational_via_method(sc, car(p))) return(wrong_type_argument_with_type(sc, sc->LCM, position_of(p, args), x, A_RATIONAL)); return(small_int(0)); } } if (d <= 1) return(make_integer(sc, n)); return(s7_make_ratio(sc, n, d)); } static s7_int c_lcm(s7_scheme *sc, s7_int a, s7_int b) { if ((a == 0) || (b == 0)) return(0); if (a < 0) a = -a; if (b < 0) b = -b; return((a / c_gcd(a, b)) * b); } IF2_TO_IF(lcm, c_lcm) /* -------------------------------- gcd -------------------------------- */ static s7_pointer g_gcd(s7_scheme *sc, s7_pointer args) { #define H_gcd "(gcd ...) returns the greatest common divisor of its rational arguments" #define Q_gcd pcl_f s7_int n = 0, d = 1; s7_pointer p; if (!is_pair(args)) return(small_int(0)); if (!is_pair(cdr(args))) { if (!is_rational(car(args))) method_or_bust_with_type(sc, car(args), sc->GCD, args, A_RATIONAL, 1); return(g_abs(sc, args)); } for (p = args; is_pair(p); p = cdr(p)) { s7_pointer x; s7_int b; x = car(p); switch (type(x)) { case T_INTEGER: n = c_gcd(n, integer(x)); break; case T_RATIO: n = c_gcd(n, s7_numerator(x)); b = s7_denominator(x); if (b < 0) b = -b; d = (d / c_gcd(d, b)) * b; if (d < 0) return(simple_out_of_range(sc, sc->GCD, args, RESULT_IS_TOO_LARGE)); break; default: method_or_bust_with_type(sc, x, sc->GCD, cons(sc, (d <= 1) ? make_integer(sc, n) : s7_make_ratio(sc, n, d), p), A_RATIONAL, position_of(p, args)); } if (n < 0) return(simple_out_of_range(sc, sc->GCD, args, RESULT_IS_TOO_LARGE)); } if (d <= 1) return(make_integer(sc, n)); return(s7_make_ratio(sc, n, d)); } static s7_int c_gcd_1(s7_scheme *sc, s7_int a, s7_int b) {return(c_gcd(a, b));} IF2_TO_IF(gcd, c_gcd_1) static s7_pointer s7_truncate(s7_scheme *sc, s7_pointer caller, s7_double xf) /* can't use "truncate" -- it's in unistd.h */ { if ((xf > s7_int_max) || (xf < s7_int_min)) return(simple_out_of_range(sc, caller, make_real(sc, xf), ITS_TOO_LARGE)); if (xf > 0.0) return(make_integer(sc, (s7_int)floor(xf))); return(make_integer(sc, (s7_int)ceil(xf))); } static s7_int c_quo_int(s7_scheme *sc, s7_int x, s7_int y) { if (y == 0) division_by_zero_error(sc, sc->QUOTIENT, set_elist_2(sc, make_integer(sc, x), make_integer(sc, y))); if ((y == -1) && (x == s7_int_min)) /* (quotient most-negative-fixnum -1) */ simple_out_of_range(sc, sc->QUOTIENT, set_elist_2(sc, make_integer(sc, x), make_integer(sc, y)), ITS_TOO_LARGE); return(x / y); } static s7_double c_quo_dbl(s7_scheme *sc, s7_double x, s7_double y) { s7_double xf; if (y == 0.0) division_by_zero_error(sc, sc->QUOTIENT, set_elist_2(sc, make_real(sc, x), make_real(sc, y))); if ((is_inf(y)) || (is_NaN(y))) wrong_type_argument_with_type(sc, sc->QUOTIENT, 2, make_real(sc, y), A_NORMAL_REAL); xf = x / y; if ((xf > s7_int_max) || (xf < s7_int_min)) simple_out_of_range(sc, sc->QUOTIENT, make_real(sc, xf), ITS_TOO_LARGE); if (xf > 0.0) return(floor(xf)); return(ceil(xf)); } static s7_pointer g_quotient(s7_scheme *sc, s7_pointer args) { #define H_quotient "(quotient x1 x2) returns the integer quotient of x1 and x2; (quotient 4 3) = 1" #define Q_quotient pcl_r /* (define (quo x1 x2) (truncate (/ x1 x2))) ; slib */ s7_pointer x, y; s7_int d1, d2, n1, n2; x = car(args); y = cadr(args); switch (type(x)) { case T_INTEGER: switch (type(y)) { case T_INTEGER: return(make_integer(sc, c_quo_int(sc, integer(x), integer(y)))); case T_RATIO: n1 = integer(x); d1 = 1; n2 = numerator(y); d2 = denominator(y); goto RATIO_QUO_RATIO; case T_REAL: if (real(y) == 0.0) return(division_by_zero_error(sc, sc->QUOTIENT, args)); if ((is_inf(real(y))) || (is_NaN(real(y)))) return(wrong_type_argument_with_type(sc, sc->QUOTIENT, 2, y, A_NORMAL_REAL)); return(s7_truncate(sc, sc->QUOTIENT, (s7_double)integer(x) / real(y))); default: method_or_bust(sc, y, sc->QUOTIENT, args, T_REAL, 2); } case T_RATIO: switch (type(y)) { case T_INTEGER: if (integer(y) == 0) return(division_by_zero_error(sc, sc->QUOTIENT, args)); n1 = numerator(x); d1 = denominator(x); n2 = integer(y); d2 = 1; goto RATIO_QUO_RATIO; /* this can lose: * (quotient 1 2305843009213693952/4611686018427387903) -> 2, not 1 * (quotient 21053343141/6701487259 3587785776203/1142027682075) -> 1, not 0 */ case T_RATIO: n1 = numerator(x); d1 = denominator(x); n2 = numerator(y); d2 = denominator(y); RATIO_QUO_RATIO: if (d1 == d2) return(make_integer(sc, n1 / n2)); /* (quotient 3/9223372036854775807 1/9223372036854775807) */ if (n1 == n2) return(make_integer(sc, d2 / d1)); /* (quotient 9223372036854775807/2 9223372036854775807/8) */ #if HAVE_OVERFLOW_CHECKS { s7_int n1d2, n2d1; if ((multiply_overflow(n1, d2, &n1d2)) || (multiply_overflow(n2, d1, &n2d1))) return(s7_truncate(sc, sc->QUOTIENT, ((long double)n1 / (long double)n2) * ((long double)d2 / (long double)d1))); return(make_integer(sc, n1d2 / n2d1)); } #else if ((integer_length(n1) + integer_length(d2) >= s7_int_bits) || (integer_length(n2) + integer_length(d1) >= s7_int_bits)) return(s7_truncate(sc, sc->QUOTIENT, ((long double)n1 / (long double)n2) * ((long double)d2 / (long double)d1))); return(make_integer(sc, (n1 * d2) / (n2 * d1))); #endif case T_REAL: if (real(y) == 0.0) return(division_by_zero_error(sc, sc->QUOTIENT, args)); if ((is_inf(real(y))) || (is_NaN(real(y)))) return(wrong_type_argument_with_type(sc, sc->QUOTIENT, 2, y, A_NORMAL_REAL)); return(s7_truncate(sc, sc->QUOTIENT, (s7_double)fraction(x) / real(y))); default: method_or_bust(sc, y, sc->QUOTIENT, args, T_REAL, 2); } case T_REAL: if ((is_inf(real(x))) || (is_NaN(real(x)))) return(wrong_type_argument_with_type(sc, sc->QUOTIENT, 1, x, A_NORMAL_REAL)); /* if infs allowed we need to return infs/nans, else: * (quotient inf.0 1e-309) -> -9223372036854775808 * (quotient inf.0 inf.0) -> -9223372036854775808 */ switch (type(y)) { case T_INTEGER: if (integer(y) == 0) return(division_by_zero_error(sc, sc->QUOTIENT, args)); return(s7_truncate(sc, sc->QUOTIENT, real(x) / (s7_double)integer(y))); case T_RATIO: return(s7_truncate(sc, sc->QUOTIENT, real(x) / (s7_double)fraction(y))); case T_REAL: return(make_real(sc, c_quo_dbl(sc, real(x), real(y)))); default: method_or_bust(sc, y, sc->QUOTIENT, args, T_REAL, 2); } default: method_or_bust(sc, x, sc->QUOTIENT, args, T_REAL, 2); } } IF2_TO_IF(quotient, c_quo_int) RF2_TO_RF(quotient, c_quo_dbl) static s7_int c_rem_int(s7_scheme *sc, s7_int x, s7_int y) { if (y == 0) division_by_zero_error(sc, sc->REMAINDER, set_elist_2(sc, make_integer(sc, x), make_integer(sc, y))); if ((y == 1) || (y == -1)) /* (remainder most-negative-fixnum -1) will segfault with arithmetic exception */ return(0); return(x % y); } static s7_double c_rem_dbl(s7_scheme *sc, s7_double x, s7_double y) { s7_int quo; s7_double pre_quo; if (y == 0.0) division_by_zero_error(sc, sc->REMAINDER, set_elist_2(sc, make_real(sc, x), make_real(sc, y))); if ((is_inf(y)) || (is_NaN(y))) wrong_type_argument_with_type(sc, sc->REMAINDER, 2, set_elist_1(sc, make_real(sc, y)), A_NORMAL_REAL); pre_quo = x / y; if ((pre_quo > s7_int_max) || (pre_quo < s7_int_min)) simple_out_of_range(sc, sc->REMAINDER, set_elist_2(sc, make_real(sc, x), make_real(sc, y)), ITS_TOO_LARGE); if (pre_quo > 0.0) quo = (s7_int)floor(pre_quo); else quo = (s7_int)ceil(pre_quo); return(x - (y * quo)); } static s7_pointer g_remainder(s7_scheme *sc, s7_pointer args) { #define H_remainder "(remainder x1 x2) returns the remainder of x1/x2; (remainder 10 3) = 1" #define Q_remainder pcl_r /* (define (rem x1 x2) (- x1 (* x2 (quo x1 x2)))) ; slib */ s7_pointer x, y; s7_int quo, d1, d2, n1, n2; s7_double pre_quo; x = car(args); y = cadr(args); switch (type(x)) { case T_INTEGER: switch (type(y)) { case T_INTEGER: return(make_integer(sc, c_rem_int(sc, integer(x), integer(y)))); case T_RATIO: n1 = integer(x); d1 = 1; n2 = numerator(y); d2 = denominator(y); goto RATIO_REM_RATIO; case T_REAL: if (real(y) == 0.0) return(division_by_zero_error(sc, sc->REMAINDER, args)); if ((is_inf(real(y))) || (is_NaN(real(y)))) return(wrong_type_argument_with_type(sc, sc->REMAINDER, 2, y, A_NORMAL_REAL)); pre_quo = (s7_double)integer(x) / real(y); if ((pre_quo > s7_int_max) || (pre_quo < s7_int_min)) return(simple_out_of_range(sc, sc->REMAINDER, args, ITS_TOO_LARGE)); if (pre_quo > 0.0) quo = (s7_int)floor(pre_quo); else quo = (s7_int)ceil(pre_quo); return(make_real(sc, integer(x) - real(y) * quo)); default: method_or_bust(sc, y, sc->REMAINDER, args, T_REAL, 2); } case T_RATIO: switch (type(y)) { case T_INTEGER: n2 = integer(y); if (n2 == 0) return(division_by_zero_error(sc, sc->REMAINDER, args)); n1 = numerator(x); d1 = denominator(x); d2 = 1; goto RATIO_REM_RATIO; case T_RATIO: n1 = numerator(x); d1 = denominator(x); n2 = numerator(y); d2 = denominator(y); RATIO_REM_RATIO: if (d1 == d2) quo = (s7_int)(n1 / n2); else { if (n1 == n2) quo = (s7_int)(d2 / d1); else { #if HAVE_OVERFLOW_CHECKS s7_int n1d2, n2d1; if ((multiply_overflow(n1, d2, &n1d2)) || (multiply_overflow(n2, d1, &n2d1))) { pre_quo = ((long double)n1 / (long double)n2) * ((long double)d2 / (long double)d1); if ((pre_quo > s7_int_max) || (pre_quo < s7_int_min)) return(simple_out_of_range(sc, sc->REMAINDER, args, ITS_TOO_LARGE)); if (pre_quo > 0.0) quo = (s7_int)floor(pre_quo); else quo = (s7_int)ceil(pre_quo); } else quo = n1d2 / n2d1; #else if ((integer_length(n1) + integer_length(d2) >= s7_int_bits) || (integer_length(n2) + integer_length(d1) >= s7_int_bits)) { pre_quo = ((long double)n1 / (long double)n2) * ((long double)d2 / (long double)d1); if ((pre_quo > s7_int_max) || (pre_quo < s7_int_min)) return(simple_out_of_range(sc, sc->REMAINDER, args, ITS_TOO_LARGE)); if (pre_quo > 0.0) quo = (s7_int)floor(pre_quo); else quo = (s7_int)ceil(pre_quo); } else quo = (n1 * d2) / (n2 * d1); #endif } } if (quo == 0) return(x); #if HAVE_OVERFLOW_CHECKS { s7_int dn, nq; if (!multiply_overflow(n2, quo, &nq)) { if ((d1 == d2) && (!subtract_overflow(n1, nq, &dn))) return(s7_make_ratio(sc, dn, d1)); if ((!multiply_overflow(n1, d2, &dn)) && (!multiply_overflow(nq, d1, &nq)) && (!subtract_overflow(dn, nq, &nq)) && (!multiply_overflow(d1, d2, &d1))) return(s7_make_ratio(sc, nq, d1)); } } #else if ((d1 == d2) && ((integer_length(n2) + integer_length(quo)) < s7_int_bits)) return(s7_make_ratio(sc, n1 - n2 * quo, d1)); if ((integer_length(n1) + integer_length(d2) < s7_int_bits) && (integer_length(d1) + integer_length(d2) < s7_int_bits) && (integer_length(n2) + integer_length(d1) + integer_length(quo) < s7_int_bits)) return(s7_make_ratio(sc, n1 * d2 - n2 * d1 * quo, d1 * d2)); #endif return(simple_out_of_range(sc, sc->REMAINDER, args, make_string_wrapper(sc, "intermediate (a/b) is too large"))); case T_REAL: { s7_double frac; if (real(y) == 0.0) return(division_by_zero_error(sc, sc->REMAINDER, args)); if ((is_inf(real(y))) || (is_NaN(real(y)))) return(wrong_type_argument_with_type(sc, sc->REMAINDER, 2, y, A_NORMAL_REAL)); frac = (s7_double)fraction(x); pre_quo = frac / real(y); if ((pre_quo > s7_int_max) || (pre_quo < s7_int_min)) return(simple_out_of_range(sc, sc->REMAINDER, args, ITS_TOO_LARGE)); if (pre_quo > 0.0) quo = (s7_int)floor(pre_quo); else quo = (s7_int)ceil(pre_quo); return(make_real(sc, frac - real(y) * quo)); } default: method_or_bust(sc, y, sc->REMAINDER, args, T_REAL, 2); } case T_REAL: if ((is_inf(real(x))) || (is_NaN(real(x)))) return(wrong_type_argument_with_type(sc, sc->REMAINDER, 1, x, A_NORMAL_REAL)); switch (type(y)) { case T_INTEGER: if (integer(y) == 0) return(division_by_zero_error(sc, sc->REMAINDER, args)); pre_quo = real(x) / (s7_double)integer(y); if ((pre_quo > s7_int_max) || (pre_quo < s7_int_min)) return(simple_out_of_range(sc, sc->REMAINDER, args, ITS_TOO_LARGE)); if (pre_quo > 0.0) quo = (s7_int)floor(pre_quo); else quo = (s7_int)ceil(pre_quo); return(make_real(sc, real(x) - integer(y) * quo)); /* but... (remainder 1e+18 9223372036854775807) -> 1e+18 */ case T_RATIO: { /* bad cases here start around 1e16: (remainder 1e15 3/13) -> 0.0 with loss of digits earlier * would long double help? */ s7_double frac; frac = (s7_double)fraction(y); pre_quo = real(x) / frac; if ((pre_quo > s7_int_max) || (pre_quo < s7_int_min)) return(simple_out_of_range(sc, sc->REMAINDER, args, ITS_TOO_LARGE)); if (pre_quo > 0.0) quo = (s7_int)floor(pre_quo); else quo = (s7_int)ceil(pre_quo); return(make_real(sc, real(x) - frac * quo)); } case T_REAL: return(make_real(sc, c_rem_dbl(sc, real(x), real(y)))); /* see under sin -- this calculation is completely bogus if "a" is large * (quotient 1e22 (* 2 pi)) -> -9223372036854775808 -- should this return arithmetic-overflow? * but it should be 1591549430918953357688, * (remainder 1e22 (* 2 pi)) -> 1.0057952155665e+22 * -- the "remainder" is greater than the original argument! * Clisp gives 0.0 here, as does sbcl * currently s7 throws an error (out-of-range). */ default: method_or_bust(sc, y, sc->REMAINDER, args, T_REAL, 2); } default: method_or_bust(sc, x, sc->REMAINDER, args, T_REAL, 1); } } IF2_TO_IF(remainder, c_rem_int) RF2_TO_RF(remainder, c_rem_dbl) /* -------------------------------- floor -------------------------------- */ #define REAL_TO_INT_LIMIT 9.2233727815085e+18 /* unfortunately, this limit is only a max in a sense: (ceiling 9223372036854770.9) => 9223372036854770 * see s7test for more examples */ static s7_pointer g_floor(s7_scheme *sc, s7_pointer args) { #define H_floor "(floor x) returns the integer closest to x toward -inf" #define Q_floor s7_make_signature(sc, 2, sc->IS_INTEGER, sc->IS_REAL) s7_pointer x; x = car(args); switch (type(x)) { case T_INTEGER: return(x); case T_RATIO: { s7_int val; val = numerator(x) / denominator(x); /* C "/" truncates? -- C spec says "truncation toward 0" */ /* we're avoiding "floor" here because the int->double conversion introduces inaccuracies for big numbers */ if (numerator(x) < 0) /* not "val" because it might be truncated to 0 */ return(make_integer(sc, val - 1)); return(make_integer(sc, val)); } case T_REAL: { s7_double z; z = real(x); if (is_NaN(z)) return(simple_out_of_range(sc, sc->FLOOR, x, ITS_NAN)); if (fabs(z) > REAL_TO_INT_LIMIT) return(simple_out_of_range(sc, sc->FLOOR, x, ITS_TOO_LARGE)); return(make_integer(sc, (s7_int)floor(z))); /* floor here rounds down, whereas a straight int<=real coercion apparently rounds towards 0 */ } case T_COMPLEX: default: method_or_bust(sc, x, sc->FLOOR, args, T_REAL, 0); } } static s7_int c_floor(s7_scheme *sc, s7_double x) {return((s7_int)floor(x));} RF_TO_IF(floor, c_floor) /* -------------------------------- ceiling -------------------------------- */ static s7_pointer g_ceiling(s7_scheme *sc, s7_pointer args) { #define H_ceiling "(ceiling x) returns the integer closest to x toward inf" #define Q_ceiling s7_make_signature(sc, 2, sc->IS_INTEGER, sc->IS_REAL) s7_pointer x; x = car(args); switch (type(x)) { case T_INTEGER: return(x); case T_RATIO: { s7_int val; val = numerator(x) / denominator(x); if (numerator(x) < 0) return(make_integer(sc, val)); return(make_integer(sc, val + 1)); } case T_REAL: { s7_double z; z = real(x); if (is_NaN(z)) return(simple_out_of_range(sc, sc->CEILING, x, ITS_NAN)); if ((is_inf(z)) || (z > REAL_TO_INT_LIMIT) || (z < -REAL_TO_INT_LIMIT)) return(simple_out_of_range(sc, sc->CEILING, x, ITS_TOO_LARGE)); return(make_integer(sc, (s7_int)ceil(real(x)))); } case T_COMPLEX: default: method_or_bust(sc, x, sc->CEILING, args, T_REAL, 0); } } static s7_int c_ceiling(s7_scheme *sc, s7_double x) {return((s7_int)ceil(x));} RF_TO_IF(ceiling, c_ceiling) /* -------------------------------- truncate -------------------------------- */ static s7_pointer g_truncate(s7_scheme *sc, s7_pointer args) { #define H_truncate "(truncate x) returns the integer closest to x toward 0" #define Q_truncate s7_make_signature(sc, 2, sc->IS_INTEGER, sc->IS_REAL) s7_pointer x; x = car(args); switch (type(x)) { case T_INTEGER: return(x); case T_RATIO: return(make_integer(sc, (s7_int)(numerator(x) / denominator(x)))); /* C "/" already truncates */ case T_REAL: { s7_double z; z = real(x); if (is_NaN(z)) return(simple_out_of_range(sc, sc->TRUNCATE, x, ITS_NAN)); if (is_inf(z)) return(simple_out_of_range(sc, sc->TRUNCATE, x, ITS_INFINITE)); return(s7_truncate(sc, sc->TRUNCATE, real(x))); } case T_COMPLEX: default: method_or_bust(sc, x, sc->TRUNCATE, args, T_REAL, 0); } } static s7_int c_trunc(s7_scheme *sc, s7_double x) { if ((x > s7_int_max) || (x < s7_int_min)) simple_out_of_range(sc, sc->TRUNCATE, make_real(sc, x), ITS_TOO_LARGE); if (x > 0.0) return((s7_int)floor(x)); return((s7_int)ceil(x)); } RF_TO_IF(truncate, c_trunc) /* -------------------------------- round -------------------------------- */ static s7_double round_per_R5RS(s7_double x) { s7_double fl, ce, dfl, dce; fl = floor(x); ce = ceil(x); dfl = x - fl; dce = ce - x; if (dfl > dce) return(ce); if (dfl < dce) return(fl); if (fmod(fl, 2.0) == 0.0) return(fl); return(ce); } static s7_pointer g_round(s7_scheme *sc, s7_pointer args) { #define H_round "(round x) returns the integer closest to x" #define Q_round s7_make_signature(sc, 2, sc->IS_INTEGER, sc->IS_REAL) s7_pointer x; x = car(args); switch (type(x)) { case T_INTEGER: return(x); case T_RATIO: { s7_int truncated, remains; long double frac; truncated = numerator(x) / denominator(x); remains = numerator(x) % denominator(x); frac = s7_fabsl((long double)remains / (long double)denominator(x)); if ((frac > 0.5) || ((frac == 0.5) && (truncated % 2 != 0))) { if (numerator(x) < 0) return(make_integer(sc, truncated - 1)); return(make_integer(sc, truncated + 1)); } return(make_integer(sc, truncated)); } case T_REAL: { s7_double z; z = real(x); if (is_NaN(z)) return(simple_out_of_range(sc, sc->ROUND, x, ITS_NAN)); if ((is_inf(z)) || (z > REAL_TO_INT_LIMIT) || (z < -REAL_TO_INT_LIMIT)) return(simple_out_of_range(sc, sc->ROUND, x, ITS_TOO_LARGE)); return(make_integer(sc, (s7_int)round_per_R5RS(z))); } case T_COMPLEX: default: method_or_bust(sc, x, sc->ROUND, args, T_REAL, 0); } } static s7_int c_round(s7_scheme *sc, s7_double x) {return((s7_int)round_per_R5RS(x));} RF_TO_IF(round, c_round) static s7_int c_mod(s7_scheme *sc, s7_int x, s7_int y) { s7_int z; /* if (y == 0) return(x); */ /* else arithmetic exception, but we're checking for this elsewhere */ z = x % y; if (((y < 0) && (z > 0)) || ((y > 0) && (z < 0))) return(z + y); return(z); } static s7_pointer g_modulo(s7_scheme *sc, s7_pointer args) { #define H_modulo "(modulo x1 x2) returns x1 mod x2; (modulo 4 3) = 1. The arguments can be real numbers." #define Q_modulo pcl_r /* (define (mod x1 x2) (- x1 (* x2 (floor (/ x1 x2))))) from slib * (mod x 0) = x according to "Concrete Mathematics" */ s7_pointer x, y; s7_double a, b; s7_int n1, n2, d1, d2; x = car(args); y = cadr(args); switch (type(x)) { case T_INTEGER: switch (type(y)) { case T_INTEGER: if (integer(y) == 0) return(x); if ((integer(y) == 1) || (integer(y) == -1)) return(small_int(0)); /* (modulo most-negative-fixnum -1) will segfault with arithmetic exception */ return(make_integer(sc, c_mod(sc, integer(x), integer(y)))); case T_RATIO: n1 = integer(x); d1 = 1; n2 = numerator(y); d2 = denominator(y); goto RATIO_MOD_RATIO; case T_REAL: b = real(y); if (b == 0.0) return(x); if (is_NaN(b)) return(y); if (is_inf(b)) return(real_NaN); a = (s7_double)integer(x); return(make_real(sc, a - b * (s7_int)floor(a / b))); default: method_or_bust(sc, y, sc->MODULO, args, T_REAL, 2); } case T_RATIO: switch (type(y)) { case T_INTEGER: if (integer(y) == 0) return(x); n1 = numerator(x); d1 = denominator(x); n2 = integer(y); if ((n2 > 0) && (n1 > 0) && (n2 > n1)) return(x); if ((n2 < 0) && (n1 < 0) && (n2 < n1)) return(x); if (n2 == s7_int_min) return(simple_out_of_range(sc, sc->MODULO, y, make_string_wrapper(sc, "intermediate (a/b) is too large"))); /* the problem here is that (modulo 3/2 most-negative-fixnum) * will segfault with signal SIGFPE, Arithmetic exception, so try to trap it. */ d2 = 1; goto RATIO_MOD_RATIO; case T_RATIO: n1 = numerator(x); d1 = denominator(x); n2 = numerator(y); /* can't be 0 */ d2 = denominator(y); if (d1 == d2) return(s7_make_ratio(sc, c_mod(sc, n1, n2), d1)); RATIO_MOD_RATIO: if ((n1 == n2) && (d1 > d2)) return(x); /* signs match so this should be ok */ #if HAVE_OVERFLOW_CHECKS { s7_int n2d1, n1d2, d1d2, fl; if (!multiply_overflow(n2, d1, &n2d1)) { if (n2d1 == 1) return(small_int(0)); if (!multiply_overflow(n1, d2, &n1d2)) { /* can't use "floor" here (int->float ruins everything) */ fl = (s7_int)(n1d2 / n2d1); if (((n1 < 0) && (n2 > 0)) || ((n1 > 0) && (n2 < 0))) fl -= 1; if (fl == 0) return(x); if ((!multiply_overflow(d1, d2, &d1d2)) && (!multiply_overflow(fl, n2d1, &fl)) && (!subtract_overflow(n1d2, fl, &fl))) return(s7_make_ratio(sc, fl, d1d2)); } } } #else if ((integer_length(n1) + integer_length(d2) < s7_int_bits) && (integer_length(n2) + integer_length(d1) < s7_int_bits) && (integer_length(d1) + integer_length(d2) < s7_int_bits)) { s7_int n1d2, n2d1, fl; n1d2 = n1 * d2; n2d1 = n2 * d1; if (n2d1 == 1) return(small_int(0)); /* can't use "floor" here (int->float ruins everything) */ fl = (s7_int)(n1d2 / n2d1); if (((n1 < 0) && (n2 > 0)) || ((n1 > 0) && (n2 < 0))) fl -= 1; if (fl == 0) return(x); if (integer_length(n2d1) + integer_length(fl) < s7_int_bits) return(s7_make_ratio(sc, n1d2 - (n2d1 * fl), d1 * d2)); } #endif /* there are cases here we might want to catch: * (modulo 9223372036 1/9223372036) -> error, not 0? * (modulo 1 1/9223372036854775807) -> error, not 0? */ return(simple_out_of_range(sc, sc->MODULO, x, make_string_wrapper(sc, "intermediate (a/b) is too large"))); case T_REAL: b = real(y); if (b == 0.0) return(x); if (is_NaN(b)) return(y); if (is_inf(b)) return(real_NaN); a = fraction(x); return(make_real(sc, a - b * (s7_int)floor(a / b))); default: method_or_bust(sc, y, sc->MODULO, args, T_REAL, 2); } case T_REAL: a = real(x); switch (type(y)) { case T_INTEGER: if (is_NaN(a)) return(x); if (is_inf(a)) return(real_NaN); if (integer(y) == 0) return(x); b = (s7_double)integer(y); return(make_real(sc, a - b * (s7_int)floor(a / b))); case T_RATIO: if (is_NaN(a)) return(x); if (is_inf(a)) return(real_NaN); b = fraction(y); return(make_real(sc, a - b * (s7_int)floor(a / b))); case T_REAL: if (is_NaN(a)) return(x); if (is_inf(a)) return(real_NaN); b = real(y); if (b == 0.0) return(x); if (is_NaN(b)) return(y); if (is_inf(b)) return(real_NaN); return(make_real(sc, a - b * (s7_int)floor(a / b))); default: method_or_bust(sc, y, sc->MODULO, args, T_REAL, 2); } default: method_or_bust(sc, x, sc->MODULO, args, T_REAL, 1); } } IF2_TO_IF(modulo, c_mod) static s7_double c_mod_r(s7_scheme *sc, s7_double x, s7_double y) {return(x - y * (s7_int)floor(x / y));} RF2_TO_RF(modulo, c_mod_r) static s7_pointer mod_si; static s7_pointer g_mod_si(s7_scheme *sc, s7_pointer args) { s7_pointer x; s7_int y; x = find_symbol_checked(sc, car(args)); y = integer(cadr(args)); if (is_integer(x)) { s7_int z; /* here we know y is positive */ z = integer(x) % y; if (z < 0) return(make_integer(sc, z + y)); return(make_integer(sc, z)); } if (is_t_real(x)) { s7_double a, b; a = real(x); if (is_NaN(a)) return(x); if (is_inf(a)) return(real_NaN); b = (s7_double)y; return(make_real(sc, a - b * (s7_int)floor(a / b))); } if (s7_is_ratio(x)) return(g_modulo(sc, set_plist_2(sc, x, cadr(args)))); method_or_bust(sc, x, sc->MODULO, list_2(sc, x, cadr(args)), T_REAL, 1); } static s7_pointer g_is_zero(s7_scheme *sc, s7_pointer args); static s7_pointer mod_si_is_zero; static s7_pointer g_mod_si_is_zero(s7_scheme *sc, s7_pointer args) { s7_pointer x; s7_int y; /* car is (modulo symbol integer), cadr is 0 or not present (if zero?) */ x = find_symbol_checked(sc, cadar(args)); y = integer(caddar(args)); if (is_integer(x)) return(make_boolean(sc, (integer(x) % y) == 0)); if (is_t_real(x)) return(make_boolean(sc, (fmod(real(x), (s7_double)y) == 0.0))); if (s7_is_ratio(x)) return(sc->F); { s7_pointer func; if ((func = find_method(sc, find_let(sc, x), sc->MODULO)) != sc->UNDEFINED) return(g_is_zero(sc, set_plist_1(sc, s7_apply_function(sc, func, list_2(sc, x, caddar(args)))))); } return(wrong_type_argument(sc, sc->MODULO, 1, x, T_REAL)); } #endif /* !WITH_GMP */ static int reduce_fraction(s7_scheme *sc, s7_int *numer, s7_int *denom) { /* we're assuming in several places that we have a normal s7 rational after returning, * so the denominator needs to be positive. */ s7_int divisor; if (*numer == 0) { *denom = 1; return(T_INTEGER); } if (*denom < 0) { if (*denom == *numer) { *denom = 1; *numer = 1; return(T_INTEGER); } if (*denom == s7_int_min) { if (*numer & 1) return(T_RATIO); *denom /= 2; *numer /= 2; } else { if (*numer == s7_int_min) { if (*denom & 1) return(T_RATIO); *denom /= 2; *numer /= 2; } } *denom = -*denom; *numer = -*numer; } divisor = c_gcd(*numer, *denom); if (divisor != 1) { *numer /= divisor; *denom /= divisor; } if (*denom == 1) return(T_INTEGER); return(T_RATIO); } /* ---------------------------------------- add ---------------------------------------- */ static s7_pointer g_add(s7_scheme *sc, s7_pointer args) { #define H_add "(+ ...) adds its arguments" #define Q_add pcl_n s7_pointer x, p; s7_int num_a, den_a, dn; s7_double rl_a, im_a; #if (!WITH_GMP) if (is_null(args)) return(small_int(0)); #endif x = car(args); p = cdr(args); if (is_null(p)) { if (!is_number(x)) method_or_bust_with_type(sc, x, sc->ADD, args, A_NUMBER, 0); return(x); } switch (type(x)) { case T_INTEGER: num_a = integer(x); ADD_INTEGERS: #if WITH_GMP if ((num_a > s7_int32_max) || (num_a < s7_int32_min)) return(big_add(sc, cons(sc, s7_int_to_big_integer(sc, num_a), p))); #endif x = car(p); p = cdr(p); switch (type(x)) { case T_INTEGER: #if HAVE_OVERFLOW_CHECKS if (add_overflow(num_a, integer(x), &den_a)) { rl_a = (s7_double)num_a + (s7_double)integer(x); if (is_null(p)) return(make_real(sc, rl_a)); goto ADD_REALS; } #else den_a = num_a + integer(x); if (den_a < 0) { if ((num_a > 0) && (integer(x) > 0)) { rl_a = (s7_double)num_a + (s7_double)integer(x); if (is_null(p)) return(make_real(sc, rl_a)); goto ADD_REALS; } } else { if ((num_a < 0) && (integer(x) < 0)) { rl_a = (s7_double)num_a + (s7_double)integer(x); if (is_null(p)) return(make_real(sc, rl_a)); /* this is not ideal! piano.scm has its own noise generator that wants integer * arithmetic to overflow as an integer. Perhaps 'safety==0 would not check * anywhere? */ goto ADD_REALS; } } #endif if (is_null(p)) return(make_integer(sc, den_a)); num_a = den_a; /* (+ 4611686018427387904 4611686018427387904) -> -9223372036854775808 * (+ most-positive-fixnum most-positive-fixnum) -> -2 * (+ most-negative-fixnum most-negative-fixnum) -> 0 * can't check result - arg: (- 0 most-negative-fixnum) -> most-negative-fixnum */ goto ADD_INTEGERS; case T_RATIO: den_a = denominator(x); #if HAVE_OVERFLOW_CHECKS if ((multiply_overflow(den_a, num_a, &dn)) || (add_overflow(dn, numerator(x), &dn))) #else if ((integer_length(num_a) + integer_length(den_a) + integer_length(numerator(x))) < s7_int_bits) dn = numerator(x) + (num_a * den_a); else #endif { if (is_null(p)) { if (num_a == 0) /* (+ 0 1/9223372036854775807) */ return(x); return(make_real(sc, num_a + fraction(x))); } rl_a = (s7_double)num_a + fraction(x); goto ADD_REALS; } if (is_null(p)) return(s7_make_ratio(sc, dn, den_a)); num_a = dn; /* overflow examples: * (+ 100000 1/142857142857140) -> -832205957599110323/28571428571428 * (+ 4611686018427387904 3/4) -> 3/4 * see s7test for more */ goto ADD_RATIOS; case T_REAL: if (is_null(p)) return(make_real(sc, num_a + real(x))); rl_a = (s7_double)num_a + real(x); goto ADD_REALS; case T_COMPLEX: if (is_null(p)) return(s7_make_complex(sc, num_a + real_part(x), imag_part(x))); rl_a = (s7_double)num_a + real_part(x); im_a = imag_part(x); goto ADD_COMPLEX; default: method_or_bust_with_type(sc, x, sc->ADD, cons(sc, s7_make_integer(sc, num_a), cons(sc, x, p)), A_NUMBER, position_of(p, args) - 1); } break; case T_RATIO: num_a = numerator(x); den_a = denominator(x); ADD_RATIOS: #if WITH_GMP if ((num_a > s7_int32_max) || (den_a > s7_int32_max) || (num_a < s7_int32_min)) return(big_add(sc, cons(sc, s7_ratio_to_big_ratio(sc, num_a, den_a), p))); #endif x = car(p); p = cdr(p); switch (type(x)) { case T_INTEGER: #if HAVE_OVERFLOW_CHECKS if ((multiply_overflow(den_a, integer(x), &dn)) || (add_overflow(dn, num_a, &dn))) #else if ((integer_length(integer(x)) + integer_length(den_a) + integer_length(num_a)) < s7_int_bits) dn = num_a + (integer(x) * den_a); else #endif { /* (+ 3/4 4611686018427387904) -> 3/4 * (+ 1/17179869184 1073741824) -> 1/17179869184 * (+ 1/8589934592 1073741824) -> -9223372036854775807/8589934592 */ if (is_null(p)) return(make_real(sc, (s7_double)integer(x) + ((long double)num_a / (long double)den_a))); rl_a = (s7_double)integer(x) + ((long double)num_a / (long double)den_a); goto ADD_REALS; } if (is_null(p)) return(s7_make_ratio(sc, dn, den_a)); num_a = dn; if (reduce_fraction(sc, &num_a, &den_a) == T_INTEGER) goto ADD_INTEGERS; goto ADD_RATIOS; case T_RATIO: { s7_int d1, d2, n1, n2; d1 = den_a; n1 = num_a; d2 = denominator(x); n2 = numerator(x); if (d1 == d2) /* the easy case -- if overflow here, it matches the int case */ { if (is_null(p)) return(s7_make_ratio(sc, n1 + n2, d1)); num_a += n2; /* d1 can't be zero */ } else { #if (!WITH_GMP) #if HAVE_OVERFLOW_CHECKS s7_int n1d2, n2d1; if ((multiply_overflow(d1, d2, &den_a)) || (multiply_overflow(n1, d2, &n1d2)) || (multiply_overflow(n2, d1, &n2d1)) || (add_overflow(n1d2, n2d1, &num_a))) { if (is_null(p)) return(make_real(sc, ((long double)n1 / (long double)d1) + ((long double)n2 / (long double)d2))); rl_a = ((long double)n1 / (long double)d1) + ((long double)n2 / (long double)d2); goto ADD_REALS; } #else if ((d1 > s7_int32_max) || (d2 > s7_int32_max) || /* before counting bits, check that overflow is possible */ (n1 > s7_int32_max) || (n2 > s7_int32_max) || (n1 < s7_int32_min) || (n2 < s7_int32_min)) { int d1bits, d2bits; d1bits = integer_length(d1); d2bits = integer_length(d2); if (((d1bits + d2bits) > s7_int_bits) || ((d1bits + integer_length(n2)) > (s7_int_bits - 1)) || ((d2bits + integer_length(n1)) > (s7_int_bits - 1))) { if (is_null(p)) return(make_real(sc, ((long double)n1 / (long double)d1) + ((long double)n2 / (long double)d2))); rl_a = ((long double)n1 / (long double)d1) + ((long double)n2 / (long double)d2); /* this can lose: * (+ 1 1/9223372036854775807 -1) -> 0.0 not 1/9223372036854775807 */ goto ADD_REALS; } } num_a = n1 * d2 + n2 * d1; den_a = d1 * d2; #endif #else num_a = n1 * d2 + n2 * d1; den_a = d1 * d2; #endif if (is_null(p)) return(s7_make_ratio(sc, num_a, den_a)); } /* (+ 1/100 99/100 (- most-positive-fixnum 2)) should not be converted to real */ if (reduce_fraction(sc, &num_a, &den_a) == T_INTEGER) goto ADD_INTEGERS; goto ADD_RATIOS; } case T_REAL: if (is_null(p)) return(make_real(sc, ((long double)num_a / (long double)den_a) + real(x))); rl_a = ((long double)num_a / (long double)den_a) + real(x); goto ADD_REALS; case T_COMPLEX: if (is_null(p)) return(s7_make_complex(sc, ((long double)num_a / (long double)den_a) + real_part(x), imag_part(x))); rl_a = ((long double)num_a / (long double)den_a) + real_part(x); im_a = imag_part(x); goto ADD_COMPLEX; default: method_or_bust_with_type(sc, x, sc->ADD, cons(sc, s7_make_ratio(sc, num_a, den_a), cons(sc, x, p)), A_NUMBER, position_of(p, args) - 1); } break; case T_REAL: rl_a = real(x); ADD_REALS: x = car(p); p = cdr(p); switch (type(x)) { case T_INTEGER: if (is_null(p)) return(make_real(sc, rl_a + integer(x))); rl_a += (s7_double)integer(x); goto ADD_REALS; case T_RATIO: if (is_null(p)) return(make_real(sc, rl_a + fraction(x))); rl_a += (s7_double)fraction(x); goto ADD_REALS; case T_REAL: if (is_null(p)) return(make_real(sc, rl_a + real(x))); rl_a += real(x); goto ADD_REALS; case T_COMPLEX: if (is_null(p)) return(s7_make_complex(sc, rl_a + real_part(x), imag_part(x))); rl_a += real_part(x); im_a = imag_part(x); goto ADD_COMPLEX; default: method_or_bust_with_type(sc, x, sc->ADD, cons(sc, make_real(sc, rl_a), cons(sc, x, p)), A_NUMBER, position_of(p, args) - 1); } break; case T_COMPLEX: rl_a = real_part(x); im_a = imag_part(x); ADD_COMPLEX: x = car(p); p = cdr(p); switch (type(x)) { case T_INTEGER: if (is_null(p)) return(s7_make_complex(sc, rl_a + integer(x), im_a)); rl_a += (s7_double)integer(x); goto ADD_COMPLEX; case T_RATIO: if (is_null(p)) return(s7_make_complex(sc, rl_a + fraction(x), im_a)); rl_a += (s7_double)fraction(x); goto ADD_COMPLEX; case T_REAL: if (is_null(p)) return(s7_make_complex(sc, rl_a + real(x), im_a)); rl_a += real(x); goto ADD_COMPLEX; case T_COMPLEX: if (is_null(p)) return(s7_make_complex(sc, rl_a + real_part(x), im_a + imag_part(x))); rl_a += real_part(x); im_a += imag_part(x); if (im_a == 0.0) goto ADD_REALS; goto ADD_COMPLEX; default: method_or_bust_with_type(sc, x, sc->ADD, cons(sc, s7_make_complex(sc, rl_a, im_a), cons(sc, x, p)), A_NUMBER, position_of(p, args) - 1); } break; default: method_or_bust_with_type(sc, x, sc->ADD, args, A_NUMBER, 1); } } static s7_pointer add_2, add_1s, add_s1, add_cs1, add_si, add_sf, add_fs; static s7_pointer add_ratios(s7_scheme *sc, s7_pointer x, s7_pointer y) { s7_int d1, d2, n1, n2; d1 = number_to_denominator(x); n1 = number_to_numerator(x); d2 = number_to_denominator(y); n2 = number_to_numerator(y); if (d1 == d2) /* the easy case -- if overflow here, it matches the int case */ return(s7_make_ratio(sc, n1 + n2, d1)); #if HAVE_OVERFLOW_CHECKS { s7_int n1d2, n2d1, d1d2, dn; if ((multiply_overflow(d1, d2, &d1d2)) || (multiply_overflow(n1, d2, &n1d2)) || (multiply_overflow(n2, d1, &n2d1)) || (add_overflow(n1d2, n2d1, &dn))) return(make_real(sc, ((long double)n1 / (long double)d1) + ((long double)n2 / (long double)d2))); return(s7_make_ratio(sc, dn, d1d2)); } #else if ((d1 > s7_int32_max) || (d2 > s7_int32_max) || /* before counting bits, check that overflow is possible */ (n1 > s7_int32_max) || (n2 > s7_int32_max) || (n1 < s7_int32_min) || (n2 < s7_int32_min)) { int d1bits, d2bits; d1bits = integer_length(d1); d2bits = integer_length(d2); if (((d1bits + d2bits) > s7_int_bits) || ((d1bits + integer_length(n2)) > (s7_int_bits - 1)) || ((d2bits + integer_length(n1)) > (s7_int_bits - 1))) return(make_real(sc, ((long double)n1 / (long double)d1) + ((long double)n2 / (long double)d2))); } return(s7_make_ratio(sc, n1 * d2 + n2 * d1, d1 * d2)); #endif } static s7_pointer g_add_2(s7_scheme *sc, s7_pointer args) { s7_pointer x, y; x = car(args); y = cadr(args); if (type(x) == type(y)) { if (is_t_real(x)) return(make_real(sc, real(x) + real(y))); else { switch (type(x)) { #if HAVE_OVERFLOW_CHECKS case T_INTEGER: { s7_int val; if (add_overflow(integer(x), integer(y), &val)) return(make_real(sc, (double)integer(x) + (double)integer(y))); return(make_integer(sc, val)); } #else case T_INTEGER: return(make_integer(sc, integer(x) + integer(y))); #endif case T_RATIO: return(add_ratios(sc, x, y)); case T_REAL: return(make_real(sc, real(x) + real(y))); case T_COMPLEX: return(make_complex(sc, real_part(x) + real_part(y), imag_part(x) + imag_part(y))); default: if (!is_number(x)) method_or_bust_with_type(sc, x, sc->ADD, args, A_NUMBER, 1); method_or_bust_with_type(sc, y, sc->ADD, args, A_NUMBER, 2); } } } switch (type(x)) { case T_INTEGER: switch (type(y)) { case T_INTEGER: return(make_integer(sc, integer(x) + integer(y))); case T_RATIO: return(add_ratios(sc, x, y)); case T_REAL: return(make_real(sc, integer(x) + real(y))); case T_COMPLEX: return(make_complex(sc, integer(x) + real_part(y), imag_part(y))); default: method_or_bust_with_type(sc, y, sc->ADD, args, A_NUMBER, 2); } case T_RATIO: switch (type(y)) { case T_INTEGER: case T_RATIO: return(add_ratios(sc, x, y)); case T_REAL: return(make_real(sc, fraction(x) + real(y))); case T_COMPLEX: return(s7_make_complex(sc, fraction(x) + real_part(y), imag_part(y))); default: method_or_bust_with_type(sc, y, sc->ADD, args, A_NUMBER, 2); } case T_REAL: switch (type(y)) { case T_INTEGER: return(make_real(sc, real(x) + integer(y))); case T_RATIO: return(make_real(sc, real(x) + fraction(y))); case T_REAL: return(make_real(sc, real(x) + real(y))); case T_COMPLEX: return(make_complex(sc, real(x) + real_part(y), imag_part(y))); default: method_or_bust_with_type(sc, y, sc->ADD, args, A_NUMBER, 2); } case T_COMPLEX: switch (type(y)) { case T_INTEGER: return(s7_make_complex(sc, real_part(x) + integer(y), imag_part(x))); case T_RATIO: return(s7_make_complex(sc, real_part(x) + fraction(y), imag_part(x))); case T_REAL: return(s7_make_complex(sc, real_part(x) + real(y), imag_part(x))); case T_COMPLEX: return(make_complex(sc, real_part(x) + real_part(y), imag_part(x) + imag_part(y))); default: method_or_bust_with_type(sc, y, sc->ADD, args, A_NUMBER, 2); } default: method_or_bust_with_type(sc, x, sc->ADD, args, A_NUMBER, 1); } return(x); } static s7_pointer g_add_s1_1(s7_scheme *sc, s7_pointer x, s7_pointer args) { switch (type(x)) { #if HAVE_OVERFLOW_CHECKS case T_INTEGER: { s7_int val; if (add_overflow(integer(x), 1, &val)) return(make_real(sc, (double)integer(x) + 1.0)); return(make_integer(sc, val)); } #else case T_INTEGER: return(make_integer(sc, integer(x) + 1)); #endif case T_RATIO: return(add_ratios(sc, x, small_int(1))); case T_REAL: return(make_real(sc, real(x) + 1.0)); case T_COMPLEX: return(s7_make_complex(sc, real_part(x) + 1.0, imag_part(x))); default: method_or_bust_with_type(sc, x, sc->ADD, cons(sc, x, cdr(args)), A_NUMBER, 1); } return(x); } static s7_pointer g_add_s1(s7_scheme *sc, s7_pointer args) { s7_pointer x; x = car(args); if (is_t_integer(x)) return(make_integer(sc, integer(x) + 1)); return(g_add_s1_1(sc, x, args)); } static s7_pointer c_add_s1(s7_scheme *sc, s7_pointer x) { if (is_t_integer(x)) return(make_integer(sc, integer(x) + 1)); return(g_add_s1_1(sc, x, set_plist_1(sc, x))); } static s7_pointer g_add_cs1(s7_scheme *sc, s7_pointer args) { s7_pointer x; x = find_symbol_checked(sc, car(args)); if (is_integer(x)) return(make_integer(sc, integer(x) + 1)); return(g_add_s1_1(sc, x, args)); } static s7_pointer g_add_1s(s7_scheme *sc, s7_pointer args) { s7_pointer x; x = cadr(args); if (is_integer(x)) return(make_integer(sc, integer(x) + 1)); switch (type(x)) { case T_INTEGER: return(make_integer(sc, integer(x) + 1)); case T_RATIO: return(add_ratios(sc, x, small_int(1))); case T_REAL: return(make_real(sc, real(x) + 1.0)); case T_COMPLEX: return(s7_make_complex(sc, real_part(x) + 1.0, imag_part(x))); default: method_or_bust_with_type(sc, x, sc->ADD, args, A_NUMBER, 2); } return(x); } static s7_pointer g_add_si(s7_scheme *sc, s7_pointer args) { s7_pointer x; s7_int n; x = find_symbol_checked(sc, car(args)); n = integer(cadr(args)); if (is_integer(x)) #if HAVE_OVERFLOW_CHECKS { s7_int val; if (add_overflow(integer(x), n, &val)) return(make_real(sc, (double)integer(x) + (double)n)); return(make_integer(sc, val)); } #else return(make_integer(sc, integer(x) + n)); #endif switch (type(x)) { case T_INTEGER: return(make_integer(sc, integer(x) + n)); case T_RATIO: return(add_ratios(sc, x, cadr(args))); case T_REAL: return(make_real(sc, real(x) + n)); case T_COMPLEX: return(s7_make_complex(sc, real_part(x) + n, imag_part(x))); default: method_or_bust_with_type(sc, x, sc->ADD, list_2(sc, x, cadr(args)), A_NUMBER, 1); } return(x); } static s7_pointer g_add_sf(s7_scheme *sc, s7_pointer args) { s7_pointer x; s7_double n; x = find_symbol_checked(sc, car(args)); n = real(cadr(args)); switch (type(x)) { case T_INTEGER: return(make_real(sc, integer(x) + n)); case T_RATIO: return(make_real(sc, fraction(x) + n)); case T_REAL: return(make_real(sc, real(x) + n)); case T_COMPLEX: return(s7_make_complex(sc, real_part(x) + n, imag_part(x))); default: method_or_bust_with_type(sc, x, sc->ADD, list_2(sc, x, cadr(args)), A_NUMBER, 1); } return(x); } static s7_pointer g_add_fs(s7_scheme *sc, s7_pointer args) { s7_pointer x; s7_double n; x = find_symbol_checked(sc, cadr(args)); n = real(car(args)); switch (type(x)) { case T_INTEGER: return(make_real(sc, integer(x) + n)); case T_RATIO: return(make_real(sc, fraction(x) + n)); case T_REAL: return(make_real(sc, real(x) + n)); case T_COMPLEX: return(s7_make_complex(sc, real_part(x) + n, imag_part(x))); default: method_or_bust_with_type(sc, x, sc->ADD, list_2(sc, x, car(args)), A_NUMBER, 2); } return(x); } static s7_pointer add_f_sf; static s7_pointer g_add_f_sf(s7_scheme *sc, s7_pointer args) { /* (+ x (* s y)) */ s7_pointer vargs, s; s7_double x, y; x = real(car(args)); vargs = cdadr(args); s = find_symbol_checked(sc, car(vargs)); y = real(cadr(vargs)); if (is_t_real(s)) return(make_real(sc, x + (real(s) * y))); switch (type(s)) { case T_INTEGER: return(make_real(sc, x + (integer(s) * y))); case T_RATIO: return(make_real(sc, x + (fraction(s) * y))); case T_REAL: return(make_real(sc, x + real(s) * y)); case T_COMPLEX: return(s7_make_complex(sc, x + (real_part(s) * y), imag_part(s) * y)); default: { s7_pointer func; if ((func = find_method(sc, find_let(sc, s), sc->MULTIPLY)) != sc->UNDEFINED) return(g_add_2(sc, set_plist_2(sc, car(args), s7_apply_function(sc, func, list_2(sc, s, cadr(vargs)))))); return(wrong_type_argument_with_type(sc, sc->MULTIPLY, 1, s, A_NUMBER)); } } return(s); } static s7_pointer add_ss_1ss_1(s7_scheme *sc, s7_pointer s1, s7_pointer s2, s7_pointer s3) { s7_double r1, r2, r3, loc, i1, i2, i3, is1; if ((is_t_real(s1)) && (is_t_real(s2)) && (is_t_real(s3))) return(make_real(sc, (real(s1) * real(s2)) + ((1.0 - real(s1)) * real(s3)))); if ((is_real(s1)) && (is_real(s2)) && (is_real(s3))) { r1 = real_to_double(sc, s1, "*"); r2 = real_to_double(sc, s2, "*"); r3 = real_to_double(sc, s3, "*"); return(make_real(sc, (r1 * r2) + ((1.0 - r1) * r3))); } r1 = s7_real_part(s1); loc = 1.0 - r1; r2 = s7_real_part(s2); r3 = s7_real_part(s3); i1 = s7_imag_part(s1); is1 = -i1; i2 = s7_imag_part(s2); i3 = s7_imag_part(s3); return(s7_make_complex(sc, (r1 * r2 - i1 * i2) + (loc * r3 - is1 * i3), (r1 * i2 + r2 * i1) + (loc * i3 + r3 * is1))); /* (let () * (define (hi a b c) (+ (* a b) (* (- 1.0 a) c))) * (define (hi1 a b c) (+ (* b a) (* c (- 1 a)))) * (define (ho a b c) (list (hi a b c) (hi1 a b c))) * (ho 1.4 2.5+i 3.1)) */ } static s7_pointer add_ss_1ss; static s7_pointer g_add_ss_1ss(s7_scheme *sc, s7_pointer args) { /* (+ (* s1 s2) (* (- 1.0 s1) s3)) */ s7_pointer s1, s2, s3; s1 = find_symbol_checked(sc, cadr(car(args))); s2 = find_symbol_checked(sc, opt_sym1(args)); /* caddr(car(args))) */ s3 = find_symbol_checked(sc, opt_sym2(args)); /* caddr(cadr(args))) */ return(add_ss_1ss_1(sc, s1, s2, s3)); } #if (!WITH_GMP) static s7_double add_rf_xx(s7_scheme *sc, s7_pointer **p) { s7_rf_t r1, r2; s7_double x, y; r1 = (s7_rf_t)(**p); (*p)++; x = r1(sc, p); r2 = (s7_rf_t)(**p); (*p)++; y = r2(sc, p); return(x + y); } static s7_double add_rf_rx(s7_scheme *sc, s7_pointer **p) { s7_pointer s1; s7_rf_t r1; s1 = **p; (*p)++; r1 = (s7_rf_t)(**p); (*p)++; return(r1(sc, p) + real_to_double(sc, s1, "+")); } static s7_double add_rf_sx(s7_scheme *sc, s7_pointer **p) { s7_pointer s1; s7_rf_t r1; s1 = slot_value(**p); (*p)++; r1 = (s7_rf_t)(**p); (*p)++; return(r1(sc, p) + real_to_double(sc, s1, "+")); } static s7_double add_rf_ss(s7_scheme *sc, s7_pointer **p) { s7_pointer s1, s2; s7_double x1; s1 = slot_value(**p); (*p)++; x1 = real_to_double(sc, s1, "+"); s2 = slot_value(**p); (*p)++; return(x1 + real_to_double(sc, s2, "+")); } static s7_double add_rf_rs(s7_scheme *sc, s7_pointer **p) { s7_pointer c1, s1; s7_double x1; s1 = slot_value(**p); (*p)++; c1 = **p; (*p)++; x1 = real_to_double(sc, c1, "+"); return(x1 + real_to_double(sc, s1, "+")); } static s7_double add_rf_xxx(s7_scheme *sc, s7_pointer **p) { s7_rf_t r1, r2, r3; s7_double x, y, z; r1 = (s7_rf_t)(**p); (*p)++; x = r1(sc, p); r2 = (s7_rf_t)(**p); (*p)++; y = r2(sc, p); r3 = (s7_rf_t)(**p); (*p)++; z = r3(sc, p); return(x + y + z); } static s7_double add_rf_rxx(s7_scheme *sc, s7_pointer **p) { s7_pointer c1; s7_rf_t r1, r2; s7_double x, y; c1 = **p; (*p)++; r1 = (s7_rf_t)(**p); (*p)++; x = r1(sc, p); r2 = (s7_rf_t)(**p); (*p)++; y = r2(sc, p); return(x + y + real_to_double(sc, c1, "+")); } static s7_double add_rf_sxx(s7_scheme *sc, s7_pointer **p) { s7_pointer s1; s7_rf_t r1, r2; s7_double x, y; s1 = slot_value(**p); (*p)++; r1 = (s7_rf_t)(**p); (*p)++; x = r1(sc, p); r2 = (s7_rf_t)(**p); (*p)++; y = r2(sc, p); return(x + y + real_to_double(sc, s1, "+")); } static s7_double add_rf_rsx(s7_scheme *sc, s7_pointer **p) { s7_pointer c1, s1; s7_rf_t r1; s7_double x, x1, x2; s1 = slot_value(**p); (*p)++; x2 = real_to_double(sc, s1, "+"); c1 = **p; (*p)++; x1 = real_to_double(sc, c1, "+"); r1 = (s7_rf_t)(**p); (*p)++; x = r1(sc, p); return(x + x1 + x2); } static s7_double add_rf_ssx(s7_scheme *sc, s7_pointer **p) { s7_pointer s1, s2; s7_rf_t r1; s7_double x, x1; s1 = slot_value(**p); (*p)++; x1 = real_to_double(sc, s1, "+"); s2 = slot_value(**p); (*p)++; r1 = (s7_rf_t)(**p); (*p)++; x = r1(sc, p); return(x + x1 + real_to_double(sc, s2, "+")); } static s7_double add_rf_sss(s7_scheme *sc, s7_pointer **p) { s7_pointer s1, s2, s3; s7_double x1, x2; s1 = slot_value(**p); (*p)++; x1 = real_to_double(sc, s1, "+"); s2 = slot_value(**p); (*p)++; x2 = real_to_double(sc, s2, "+"); s3 = slot_value(**p); (*p)++; return(x1 + x2 + real_to_double(sc, s3, "+")); } static s7_double add_rf_rss(s7_scheme *sc, s7_pointer **p) { s7_pointer c1, s1, s2; s7_double x1, x2; s1 = slot_value(**p); (*p)++; x1 = real_to_double(sc, s1, "+"); s2 = slot_value(**p); (*p)++; x2 = real_to_double(sc, s2, "+"); c1 = **p; (*p)++; return(real_to_double(sc, c1, "+") + x1 + x2); } static s7_rf_t add_rf_1(s7_scheme *sc, s7_pointer expr, int len) { if (len == 3) return(com_rf_2(sc, expr, add_r_ops)); if (len == 4) return(com_rf_3(sc, expr, add_r_ops)); if (len > 4) { s7_rf_t rf; ptr_int loc; int first_len; xf_t *rc; first_len = (int)(len / 2); xf_init(2); xf_save_loc(loc); rf = add_rf_1(sc, expr, first_len + 1); if (rf) { int i; s7_pointer p; xf_store_at(loc, (s7_pointer)rf); xf_save_loc(loc); for (i = 0, p = expr; i < first_len; i++, p = cdr(p)); rf = add_rf_1(sc, p, len - first_len); if (rf) { xf_store_at(loc, (s7_pointer)rf); return(add_rf_xx); } else return(NULL); } else return(NULL); } return(NULL); } static s7_rf_t add_rf(s7_scheme *sc, s7_pointer expr) { return(add_rf_1(sc, expr, s7_list_length(sc, expr))); } static s7_int add_if_xx(s7_scheme *sc, s7_pointer **p) { s7_if_t r1, r2; s7_int x, y; r1 = (s7_if_t)(**p); (*p)++; x = r1(sc, p); r2 = (s7_if_t)(**p); (*p)++; y = r2(sc, p); return(x + y); } static s7_int add_if_rx(s7_scheme *sc, s7_pointer **p) { s7_pointer s1; s7_if_t r1; s1 = **p; (*p)++; r1 = (s7_if_t)(**p); (*p)++; return(r1(sc, p) + integer(s1)); } static s7_int add_if_sx(s7_scheme *sc, s7_pointer **p) { s7_pointer s1; s7_if_t r1; s1 = slot_value(**p); (*p)++; r1 = (s7_if_t)(**p); (*p)++; return(r1(sc, p) + integer(s1)); } static s7_int add_if_ss(s7_scheme *sc, s7_pointer **p) { s7_pointer s1, s2; s1 = slot_value(**p); (*p)++; s2 = slot_value(**p); (*p)++; return(integer(s1) + integer(s2)); } static s7_int add_if_rs(s7_scheme *sc, s7_pointer **p) { s7_pointer c1, s1; s1 = slot_value(**p); (*p)++; c1 = **p; (*p)++; return(integer(c1) + integer(s1)); } static s7_int add_if_xxx(s7_scheme *sc, s7_pointer **p) { s7_if_t r1, r2, r3; s7_int x, y, z; r1 = (s7_if_t)(**p); (*p)++; x = r1(sc, p); r2 = (s7_if_t)(**p); (*p)++; y = r2(sc, p); r3 = (s7_if_t)(**p); (*p)++; z = r3(sc, p); return(x + y + z); } static s7_int add_if_rxx(s7_scheme *sc, s7_pointer **p) { s7_pointer c1; s7_if_t r1, r2; s7_int x, y; c1 = **p; (*p)++; r1 = (s7_if_t)(**p); (*p)++; x = r1(sc, p); r2 = (s7_if_t)(**p); (*p)++; y = r2(sc, p); return(x + y + integer(c1)); } static s7_int add_if_sxx(s7_scheme *sc, s7_pointer **p) { s7_pointer s1; s7_if_t r1, r2; s7_int x, y; s1 = slot_value(**p); (*p)++; r1 = (s7_if_t)(**p); (*p)++; x = r1(sc, p); r2 = (s7_if_t)(**p); (*p)++; y = r2(sc, p); return(x + y + integer(s1)); } static s7_int add_if_rsx(s7_scheme *sc, s7_pointer **p) { s7_pointer c1, s1; s7_if_t r1; s7_int x; s1 = slot_value(**p); (*p)++; c1 = **p; (*p)++; r1 = (s7_if_t)(**p); (*p)++; x = r1(sc, p); return(x + integer(c1) + integer(s1)); } static s7_int add_if_ssx(s7_scheme *sc, s7_pointer **p) { s7_pointer s1, s2; s7_if_t r1; s7_int x; s1 = slot_value(**p); (*p)++; s2 = slot_value(**p); (*p)++; r1 = (s7_if_t)(**p); (*p)++; x = r1(sc, p); return(x + integer(s1) + integer(s2)); } static s7_int add_if_sss(s7_scheme *sc, s7_pointer **p) { s7_pointer s1, s2, s3; s1 = slot_value(**p); (*p)++; s2 = slot_value(**p); (*p)++; s3 = slot_value(**p); (*p)++; return(integer(s1) + integer(s2) + integer(s3)); } static s7_int add_if_rss(s7_scheme *sc, s7_pointer **p) { s7_pointer c1, s1, s2; s1 = slot_value(**p); (*p)++; s2 = slot_value(**p); (*p)++; c1 = **p; (*p)++; return(integer(c1) + integer(s1) + integer(s2)); } static s7_if_t add_if_1(s7_scheme *sc, s7_pointer expr, int len) { if (len == 3) return(com_if_2(sc, expr, add_i_ops)); if (len == 4) return(com_if_3(sc, expr, add_i_ops)); if (len > 4) { s7_if_t xf; ptr_int loc; int first_len; xf_t *rc; xf_init(2); xf_save_loc(loc); first_len = (int)(len / 2); xf = add_if_1(sc, expr, first_len + 1); if (xf) { int i; s7_pointer p; xf_store_at(loc, (s7_pointer)xf); xf_save_loc(loc); for (i = 0, p = expr; i < first_len; i++, p = cdr(p)); xf = add_if_1(sc, p, len - first_len); if (xf) { xf_store_at(loc, (s7_pointer)xf); return(add_if_xx); } else return(NULL); } else return(NULL); } return(NULL); } static s7_if_t add_if(s7_scheme *sc, s7_pointer expr) { return(add_if_1(sc, expr, s7_list_length(sc, expr))); } static void init_add_ops(void) { add_r_ops = (rf_ops *)calloc(1, sizeof(rf_ops)); add_r_ops->r = rf_c; add_r_ops->s = rf_s; add_r_ops->rs = add_rf_rs; add_r_ops->rp = add_rf_rx; add_r_ops->sp = add_rf_sx; add_r_ops->ss = add_rf_ss; add_r_ops->pp = add_rf_xx; add_r_ops->rss = add_rf_rss; add_r_ops->rsp = add_rf_rsx; add_r_ops->rpp = add_rf_rxx; add_r_ops->sss = add_rf_sss; add_r_ops->ssp = add_rf_ssx; add_r_ops->spp = add_rf_sxx; add_r_ops->ppp = add_rf_xxx; add_i_ops = (if_ops *)calloc(1, sizeof(if_ops)); add_i_ops->r = if_c; add_i_ops->s = if_s; add_i_ops->rs = add_if_rs; add_i_ops->rp = add_if_rx; add_i_ops->sp = add_if_sx; add_i_ops->ss = add_if_ss; add_i_ops->pp = add_if_xx; add_i_ops->rss = add_if_rss; add_i_ops->rsp = add_if_rsx; add_i_ops->rpp = add_if_rxx; add_i_ops->sss = add_if_sss; add_i_ops->ssp = add_if_ssx; add_i_ops->spp = add_if_sxx; add_i_ops->ppp = add_if_xxx; } #if WITH_ADD_PF static s7_pointer c_add_pf2(s7_scheme *sc, s7_pointer **p) { s7_pf_t pf; s7_pointer x, y; pf = (s7_pf_t)(**p); (*p)++; x = pf(sc, p); xf_push(sc, x); pf = (s7_pf_t)(**p); (*p)++; y = pf(sc, p); x = g_add_2(sc, set_plist_2(sc, x, y)); xf_pop(sc); return(x); } static s7_pf_t add_pf(s7_scheme *sc, s7_pointer expr) { int len; len = s7_list_length(sc, expr); if (len == 3) { if ((s7_arg_to_pf(sc, cadr(expr))) && (s7_arg_to_pf(sc, caddr(expr)))) return(c_add_pf2); } return(NULL); } #endif #endif /* ---------------------------------------- subtract ---------------------------------------- */ static s7_pointer g_subtract(s7_scheme *sc, s7_pointer args) { #define H_subtract "(- x1 ...) subtracts its trailing arguments from the first, or negates the first if only one it is given" #define Q_subtract pcl_n s7_pointer x, p; s7_int num_a, den_a; s7_double rl_a, im_a; x = car(args); p = cdr(args); #if (!WITH_GMP) if (is_null(p)) { if (!is_number(x)) method_or_bust_with_type(sc, x, sc->SUBTRACT, args, A_NUMBER, 0); return(s7_negate(sc, x)); } #endif switch (type(x)) { case T_INTEGER: num_a = integer(x); SUBTRACT_INTEGERS: #if WITH_GMP if ((num_a > s7_int32_max) || (num_a < s7_int32_min)) return(big_subtract(sc, cons(sc, s7_int_to_big_integer(sc, num_a), p))); #endif x = car(p); p = cdr(p); switch (type(x)) { case T_INTEGER: #if HAVE_OVERFLOW_CHECKS if (subtract_overflow(num_a, integer(x), &den_a)) { rl_a = (s7_double)num_a - (s7_double)integer(x); if (is_null(p)) return(make_real(sc, rl_a)); goto SUBTRACT_REALS; } #else den_a = num_a - integer(x); if (den_a < 0) { if ((num_a > 0) && (integer(x) < 0)) { rl_a = (s7_double)num_a - (s7_double)integer(x); if (is_null(p)) return(make_real(sc, rl_a)); goto SUBTRACT_REALS; } /* (- most-positive-fixnum most-negative-fixnum) -> -1 (1.8446744073709551615E19) */ } else { if ((num_a < 0) && (integer(x) > 0)) { rl_a = (s7_double)num_a - (s7_double)integer(x); if (is_null(p)) return(make_real(sc, rl_a)); goto SUBTRACT_REALS; } /* (- most-negative-fixnum most-positive-fixnum) -> 1 (-1.8446744073709551615E19) */ } #endif if (is_null(p)) return(make_integer(sc, den_a)); num_a = den_a; goto SUBTRACT_INTEGERS; case T_RATIO: { s7_int dn; den_a = denominator(x); #if HAVE_OVERFLOW_CHECKS if ((multiply_overflow(num_a, den_a, &dn)) || (subtract_overflow(dn, numerator(x), &dn))) { if (is_null(p)) return(make_real(sc, num_a - fraction(x))); rl_a = (s7_double)num_a - fraction(x); goto SUBTRACT_REALS; } #else if ((integer_length(num_a) + integer_length(den_a) + integer_length(numerator(x))) > s7_int_bits) { if (is_null(p)) return(make_real(sc, num_a - fraction(x))); rl_a = (s7_double)num_a - fraction(x); goto SUBTRACT_REALS; } dn = (num_a * den_a) - numerator(x); #endif if (is_null(p)) return(s7_make_ratio(sc, dn, den_a)); num_a = dn; if (reduce_fraction(sc, &num_a, &den_a) == T_INTEGER) goto SUBTRACT_INTEGERS; goto SUBTRACT_RATIOS; } case T_REAL: if (is_null(p)) return(make_real(sc, num_a - real(x))); rl_a = (s7_double)num_a - real(x); goto SUBTRACT_REALS; case T_COMPLEX: if (is_null(p)) return(s7_make_complex(sc, num_a - real_part(x), -imag_part(x))); rl_a = (s7_double)num_a - real_part(x); im_a = -imag_part(x); goto SUBTRACT_COMPLEX; default: method_or_bust_with_type(sc, x, sc->SUBTRACT, cons(sc, s7_make_integer(sc, num_a), cons(sc, x, p)), A_NUMBER, position_of(p, args) - 1); } break; case T_RATIO: num_a = numerator(x); den_a = denominator(x); SUBTRACT_RATIOS: #if WITH_GMP if ((num_a > s7_int32_max) || (den_a > s7_int32_max) || (num_a < s7_int32_min)) return(big_subtract(sc, cons(sc, s7_ratio_to_big_ratio(sc, num_a, den_a), p))); #endif x = car(p); p = cdr(p); switch (type(x)) { case T_INTEGER: #if HAVE_OVERFLOW_CHECKS { s7_int di; if ((multiply_overflow(den_a, integer(x), &di)) || (subtract_overflow(num_a, di, &di))) { if (is_null(p)) return(make_real(sc, ((long double)num_a / (long double)den_a) - integer(x))); rl_a = ((long double)num_a / (long double)den_a) - integer(x); goto SUBTRACT_REALS; } if (is_null(p)) return(s7_make_ratio(sc, di, den_a)); num_a = di; } #else if ((integer_length(integer(x)) + integer_length(num_a) + integer_length(den_a)) > s7_int_bits) { if (is_null(p)) return(make_real(sc, ((long double)num_a / (long double)den_a) - integer(x))); rl_a = ((long double)num_a / (long double)den_a) - integer(x); goto SUBTRACT_REALS; } if (is_null(p)) return(s7_make_ratio(sc, num_a - (den_a * integer(x)), den_a)); num_a -= (den_a * integer(x)); #endif if (reduce_fraction(sc, &num_a, &den_a) == T_INTEGER) goto SUBTRACT_INTEGERS; goto SUBTRACT_RATIOS; case T_RATIO: { s7_int d1, d2, n1, n2; d1 = den_a; n1 = num_a; d2 = denominator(x); n2 = numerator(x); if (d1 == d2) /* the easy case -- if overflow here, it matches the int case */ { if (is_null(p)) return(s7_make_ratio(sc, n1 - n2, d1)); num_a -= n2; /* d1 can't be zero */ } else { #if (!WITH_GMP) #if HAVE_OVERFLOW_CHECKS s7_int n1d2, n2d1; if ((multiply_overflow(d1, d2, &den_a)) || (multiply_overflow(n1, d2, &n1d2)) || (multiply_overflow(n2, d1, &n2d1)) || (subtract_overflow(n1d2, n2d1, &num_a))) { if (is_null(p)) return(make_real(sc, ((long double)n1 / (long double)d1) - ((long double)n2 / (long double)d2))); rl_a = ((long double)n1 / (long double)d1) - ((long double)n2 / (long double)d2); goto SUBTRACT_REALS; } #else if ((d1 > s7_int32_max) || (d2 > s7_int32_max) || /* before counting bits, check that overflow is possible */ (n1 > s7_int32_max) || (n2 > s7_int32_max) || (n1 < s7_int32_min) || (n2 < s7_int32_min)) { int d1bits, d2bits; d1bits = integer_length(d1); d2bits = integer_length(d2); if (((d1bits + d2bits) > s7_int_bits) || ((d1bits + integer_length(n2)) > (s7_int_bits - 1)) || ((d2bits + integer_length(n1)) > (s7_int_bits - 1))) { if (is_null(p)) return(make_real(sc, ((long double)n1 / (long double)d1) - ((long double)n2 / (long double)d2))); rl_a = ((long double)n1 / (long double)d1) - ((long double)n2 / (long double)d2); goto SUBTRACT_REALS; } } num_a = n1 * d2 - n2 * d1; den_a = d1 * d2; #endif #else num_a = n1 * d2 - n2 * d1; den_a = d1 * d2; #endif if (is_null(p)) return(s7_make_ratio(sc, num_a, den_a)); } if (reduce_fraction(sc, &num_a, &den_a) == T_INTEGER) goto SUBTRACT_INTEGERS; goto SUBTRACT_RATIOS; } case T_REAL: if (is_null(p)) return(make_real(sc, ((long double)num_a / (long double)den_a) - real(x))); rl_a = ((long double)num_a / (long double)den_a) - real(x); goto SUBTRACT_REALS; case T_COMPLEX: if (is_null(p)) return(s7_make_complex(sc, ((long double)num_a / (long double)den_a) - real_part(x), -imag_part(x))); rl_a = ((long double)num_a / (long double)den_a) - real_part(x); im_a = -imag_part(x); goto SUBTRACT_COMPLEX; default: method_or_bust_with_type(sc, x, sc->SUBTRACT, cons(sc, s7_make_ratio(sc, num_a, den_a), cons(sc, x, p)), A_NUMBER, position_of(p, args) - 1); } break; case T_REAL: rl_a = real(x); SUBTRACT_REALS: x = car(p); p = cdr(p); switch (type(x)) { case T_INTEGER: if (is_null(p)) return(make_real(sc, rl_a - integer(x))); rl_a -= (s7_double)integer(x); goto SUBTRACT_REALS; case T_RATIO: if (is_null(p)) return(make_real(sc, rl_a - fraction(x))); rl_a -= (s7_double)fraction(x); goto SUBTRACT_REALS; case T_REAL: if (is_null(p)) return(make_real(sc, rl_a - real(x))); rl_a -= real(x); goto SUBTRACT_REALS; case T_COMPLEX: if (is_null(p)) return(s7_make_complex(sc, rl_a - real_part(x), -imag_part(x))); rl_a -= real_part(x); im_a = -imag_part(x); goto SUBTRACT_COMPLEX; default: method_or_bust_with_type(sc, x, sc->SUBTRACT, cons(sc, make_real(sc, rl_a), cons(sc, x, p)), A_NUMBER, position_of(p, args) - 1); } break; case T_COMPLEX: rl_a = real_part(x); im_a = imag_part(x); SUBTRACT_COMPLEX: x = car(p); p = cdr(p); switch (type(x)) { case T_INTEGER: if (is_null(p)) return(s7_make_complex(sc, rl_a - integer(x), im_a)); rl_a -= (s7_double)integer(x); goto SUBTRACT_COMPLEX; case T_RATIO: if (is_null(p)) return(s7_make_complex(sc, rl_a - fraction(x), im_a)); rl_a -= (s7_double)fraction(x); goto SUBTRACT_COMPLEX; case T_REAL: if (is_null(p)) return(s7_make_complex(sc, rl_a - real(x), im_a)); rl_a -= real(x); goto SUBTRACT_COMPLEX; case T_COMPLEX: if (is_null(p)) return(s7_make_complex(sc, rl_a - real_part(x), im_a - imag_part(x))); rl_a -= real_part(x); im_a -= imag_part(x); if (im_a == 0.0) goto SUBTRACT_REALS; goto SUBTRACT_COMPLEX; default: method_or_bust_with_type(sc, x, sc->SUBTRACT, cons(sc, s7_make_complex(sc, rl_a, im_a), cons(sc, x, p)), A_NUMBER, position_of(p, args) - 1); } break; default: method_or_bust_with_type(sc, x, sc->SUBTRACT, args, A_NUMBER, 1); } } static s7_pointer subtract_1, subtract_s1, subtract_cs1, subtract_2, subtract_csn; static s7_pointer g_subtract_1(s7_scheme *sc, s7_pointer args) { s7_pointer p; p = car(args); switch (type(p)) { case T_INTEGER: if (integer(p) == s7_int_min) #if WITH_GMP return(big_negate(sc, set_plist_1(sc, promote_number(sc, T_BIG_INTEGER, p)))); #else return(make_integer(sc, s7_int_max)); #endif return(make_integer(sc, -integer(p))); case T_RATIO: return(s7_make_ratio(sc, -numerator(p), denominator(p))); case T_REAL: return(make_real(sc, -real(p))); case T_COMPLEX: return(s7_make_complex(sc, -real_part(p), -imag_part(p))); default: method_or_bust_with_type(sc, p, sc->SUBTRACT, args, A_NUMBER, 1); } } static s7_pointer g_subtract_2(s7_scheme *sc, s7_pointer args) { s7_pointer x, y; x = car(args); y = cadr(args); if (type(x) == type(y)) { if (is_t_real(x)) return(make_real(sc, real(x) - real(y))); else { switch (type(x)) { #if HAVE_OVERFLOW_CHECKS case T_INTEGER: { s7_int val; if (subtract_overflow(integer(x), integer(y), &val)) return(make_real(sc, (double)integer(x) - (double)integer(y))); return(make_integer(sc, val)); } #else case T_INTEGER: return(make_integer(sc, integer(x) - integer(y))); #endif case T_RATIO: return(g_subtract(sc, args)); case T_REAL: return(make_real(sc, real(x) - real(y))); case T_COMPLEX: return(make_complex(sc, real_part(x) - real_part(y), imag_part(x) - imag_part(y))); default: if (!is_number(x)) method_or_bust_with_type(sc, x, sc->SUBTRACT, args, A_NUMBER, 1); method_or_bust_with_type(sc, y, sc->SUBTRACT, args, A_NUMBER, 2); } } } switch (type(x)) { case T_INTEGER: switch (type(y)) { case T_INTEGER: return(make_integer(sc, integer(x) - integer(y))); case T_RATIO: return(g_subtract(sc, args)); case T_REAL: return(make_real(sc, integer(x) - real(y))); case T_COMPLEX: return(make_complex(sc, integer(x) - real_part(y), -imag_part(y))); default: method_or_bust_with_type(sc, y, sc->SUBTRACT, args, A_NUMBER, 2); } case T_RATIO: switch (type(y)) { case T_INTEGER: case T_RATIO: return(g_subtract(sc, args)); case T_REAL: return(make_real(sc, fraction(x) - real(y))); case T_COMPLEX: return(s7_make_complex(sc, fraction(x) - real_part(y), -imag_part(y))); default: method_or_bust_with_type(sc, y, sc->SUBTRACT, args, A_NUMBER, 2); } case T_REAL: switch (type(y)) { case T_INTEGER: return(make_real(sc, real(x) - integer(y))); case T_RATIO: return(make_real(sc, real(x) - fraction(y))); case T_REAL: return(make_real(sc, real(x) - real(y))); case T_COMPLEX: return(make_complex(sc, real(x) - real_part(y), -imag_part(y))); default: method_or_bust_with_type(sc, y, sc->SUBTRACT, args, A_NUMBER, 2); } case T_COMPLEX: switch (type(y)) { case T_INTEGER: return(s7_make_complex(sc, real_part(x) - integer(y), imag_part(x))); case T_RATIO: return(s7_make_complex(sc, real_part(x) - fraction(y), imag_part(x))); case T_REAL: return(s7_make_complex(sc, real_part(x) - real(y), imag_part(x))); case T_COMPLEX: return(make_complex(sc, real_part(x) - real_part(y), imag_part(x) - imag_part(y))); default: method_or_bust_with_type(sc, y, sc->SUBTRACT, args, A_NUMBER, 2); } default: method_or_bust_with_type(sc, x, sc->SUBTRACT, args, A_NUMBER, 1); } return(x); } static s7_pointer g_subtract_cs1(s7_scheme *sc, s7_pointer args) { s7_pointer x; x = find_symbol_checked(sc, car(args)); if (is_integer(x)) return(make_integer(sc, integer(x) - 1)); switch (type(x)) { #if HAVE_OVERFLOW_CHECKS case T_INTEGER: { s7_int val; if (subtract_overflow(integer(x), 1, &val)) return(make_real(sc, (double)integer(x) - 1.0)); return(make_integer(sc, val)); } #else case T_INTEGER: return(make_integer(sc, integer(x) - 1)); #endif case T_RATIO: return(subtract_ratios(sc, x, small_int(1))); case T_REAL: return(make_real(sc, real(x) - 1.0)); case T_COMPLEX: return(s7_make_complex(sc, real_part(x) - 1.0, imag_part(x))); default: method_or_bust_with_type(sc, x, sc->SUBTRACT, list_2(sc, x, small_int(1)), A_NUMBER, 1); } return(x); } static s7_pointer g_subtract_s1(s7_scheme *sc, s7_pointer args) { s7_pointer x; x = car(args); /* this one seems to hit reals as often as integers */ switch (type(x)) { #if HAVE_OVERFLOW_CHECKS case T_INTEGER: { s7_int val; if (subtract_overflow(integer(x), 1, &val)) return(make_real(sc, (double)integer(x) - 1.0)); return(make_integer(sc, val)); } #else case T_INTEGER: return(make_integer(sc, integer(x) - 1)); #endif case T_RATIO: return(subtract_ratios(sc, x, small_int(1))); case T_REAL: return(make_real(sc, real(x) - 1.0)); case T_COMPLEX: return(s7_make_complex(sc, real_part(x) - 1.0, imag_part(x))); default: method_or_bust_with_type(sc, x, sc->SUBTRACT, args, A_NUMBER, 1); } return(x); } static s7_pointer g_subtract_csn(s7_scheme *sc, s7_pointer args) { s7_pointer x; s7_int n; x = find_symbol_checked(sc, car(args)); n = s7_integer(cadr(args)); if (is_integer(x)) return(make_integer(sc, integer(x) - n)); switch (type(x)) { #if HAVE_OVERFLOW_CHECKS case T_INTEGER: { s7_int val; if (subtract_overflow(integer(x), n, &val)) return(make_real(sc, (double)integer(x) - (double)n)); return(make_integer(sc, val)); } #else case T_INTEGER: return(make_integer(sc, integer(x) - n)); #endif case T_RATIO: return(subtract_ratios(sc, x, cadr(args))); case T_REAL: return(make_real(sc, real(x) - n)); case T_COMPLEX: return(s7_make_complex(sc, real_part(x) - n, imag_part(x))); default: method_or_bust_with_type(sc, x, sc->SUBTRACT, list_2(sc, x, cadr(args)), A_NUMBER, 1); } return(x); } static s7_pointer subtract_sf; static s7_pointer g_subtract_sf(s7_scheme *sc, s7_pointer args) { s7_pointer x; s7_double n; x = find_symbol_checked(sc, car(args)); n = real(cadr(args)); switch (type(x)) { case T_INTEGER: return(make_real(sc, integer(x) - n)); case T_RATIO: return(make_real(sc, fraction(x) - n)); case T_REAL: return(make_real(sc, real(x) - n)); case T_COMPLEX: return(s7_make_complex(sc, real_part(x) - n, imag_part(x))); default: method_or_bust_with_type(sc, x, sc->SUBTRACT, list_2(sc, x, cadr(args)), A_NUMBER, 1); } return(x); } static s7_pointer subtract_2f; static s7_pointer g_subtract_2f(s7_scheme *sc, s7_pointer args) { s7_pointer x; s7_double n; x = car(args); n = real(cadr(args)); switch (type(x)) { case T_INTEGER: return(make_real(sc, integer(x) - n)); case T_RATIO: return(make_real(sc, fraction(x) - n)); case T_REAL: return(make_real(sc, real(x) - n)); case T_COMPLEX: return(s7_make_complex(sc, real_part(x) - n, imag_part(x))); default: method_or_bust_with_type(sc, x, sc->SUBTRACT, args, A_NUMBER, 1); } return(x); } static s7_pointer subtract_fs; static s7_pointer g_subtract_fs(s7_scheme *sc, s7_pointer args) { s7_pointer x; s7_double n; x = find_symbol_checked(sc, cadr(args)); n = real(car(args)); switch (type(x)) { case T_INTEGER: return(make_real(sc, n - integer(x))); case T_RATIO: return(make_real(sc, n - fraction(x))); case T_REAL: return(make_real(sc, n - real(x))); case T_COMPLEX: return(s7_make_complex(sc, n - real_part(x), -imag_part(x))); default: method_or_bust_with_type(sc, x, sc->SUBTRACT, list_2(sc, car(args), x), A_NUMBER, 2); } return(x); } static s7_pointer subtract_f_sqr; static s7_pointer g_subtract_f_sqr(s7_scheme *sc, s7_pointer args) { s7_pointer x; s7_double y; y = real(car(args)); x = find_symbol_checked(sc, cadr(cadr(args))); if (is_t_real(x)) return(make_real(sc, y - (real(x) * real(x)))); switch (type(x)) { case T_INTEGER: return(make_real(sc, y - (integer(x) * integer(x)))); case T_RATIO: return(make_real(sc, y - (fraction(x) * fraction(x)))); case T_REAL: return(make_real(sc, y - (real(x) * real(x)))); case T_COMPLEX: return(s7_make_complex(sc, y - real_part(x) * real_part(x) + imag_part(x) * imag_part(x), 2.0 * real_part(x) * imag_part(x))); default: /* complicated -- look for * method, if any get (* x x), then go to g_subtract_2 with that and the original y * can't use check_method here because it returns from the caller. */ { s7_pointer func; if ((func = find_method(sc, find_let(sc, x), sc->MULTIPLY)) != sc->UNDEFINED) return(g_subtract_2(sc, set_plist_2(sc, car(args), s7_apply_function(sc, func, list_2(sc, x, x))))); return(wrong_type_argument_with_type(sc, sc->MULTIPLY, 1, x, A_NUMBER)); } } return(x); } #if (!WITH_GMP) /* (define (hi) (- (random 100) 50)) (define (ho) (- (random 1.0) 0.5)) */ static s7_pointer sub_random_ic, sub_random_rc; static s7_pointer g_sub_random_ic(s7_scheme *sc, s7_pointer args) { return(make_integer(sc, ((s7_int)(integer(cadar(args)) * next_random(sc->default_rng))) - integer(cadr(args)))); } static s7_pointer g_sub_random_rc(s7_scheme *sc, s7_pointer args) { return(make_real(sc, real(cadar(args)) * next_random(sc->default_rng) - real(cadr(args)))); } static s7_int negate_if_c(s7_scheme *sc, s7_pointer **p) {s7_pointer x; x = (**p); (*p)++; return(-integer(x));} static s7_int negate_if_s(s7_scheme *sc, s7_pointer **p) {s7_pointer x; x = slot_value(**p); (*p)++; return(-integer(x));} static s7_int negate_if_p(s7_scheme *sc, s7_pointer **p) {s7_if_t f; f = (s7_if_t)(**p); (*p)++; return(f(sc, p));} static s7_int sub_if_cc(s7_scheme *sc, s7_pointer **p) {s7_pointer x, y; x = (**p); (*p)++; y = (**p); (*p)++; return(integer(x) - integer(y));} static s7_int sub_if_cs(s7_scheme *sc, s7_pointer **p) {s7_pointer x, y; x = (**p); (*p)++; y = slot_value(**p); (*p)++; return(integer(x) - integer(y));} static s7_int sub_if_ss(s7_scheme *sc, s7_pointer **p) {s7_pointer x, y; x = slot_value(**p); (*p)++; y = slot_value(**p); (*p)++; return(integer(x) - integer(y));} static s7_int sub_if_sc(s7_scheme *sc, s7_pointer **p) {s7_pointer x, y; x = slot_value(**p); (*p)++; y = (**p); (*p)++; return(integer(x) - integer(y));} static s7_int sub_if_cp(s7_scheme *sc, s7_pointer **p) { s7_if_t xf; s7_pointer x; x = (**p); (*p)++; xf = (s7_if_t)(**p); (*p)++; return(integer(x) - xf(sc, p)); } static s7_int sub_if_pc(s7_scheme *sc, s7_pointer **p) { s7_if_t xf; s7_int x; s7_pointer y; xf = (s7_if_t)(**p); (*p)++; x = xf(sc,p); y = (**p); (*p)++; return(x - integer(y)); } static s7_int sub_if_sp(s7_scheme *sc, s7_pointer **p) { s7_if_t xf; s7_pointer x; x = slot_value(**p); (*p)++; xf = (s7_if_t)(**p); (*p)++; return(integer(x) - xf(sc, p)); } static s7_int sub_if_ps(s7_scheme *sc, s7_pointer **p) { s7_if_t xf; s7_int x; s7_pointer y; xf = (s7_if_t)(**p); (*p)++; x = xf(sc,p); y = slot_value(**p); (*p)++; return(x - integer(y)); } static s7_int sub_if_pp(s7_scheme *sc, s7_pointer **p) { s7_if_t xf; s7_int x, y; xf = (s7_if_t)(**p); (*p)++; x = xf(sc,p); xf = (s7_if_t)(**p); (*p)++; y = xf(sc,p); return(x - y); } static s7_if_t subtract_if(s7_scheme *sc, s7_pointer expr) { s7_pointer a1, a2, slot; xf_t *rc; if (!is_pair(cdr(expr))) return(NULL); xf_init(2); a1 = cadr(expr); if (is_null(cddr(expr))) { if (is_t_integer(a1)) { xf_store(a1); return(negate_if_c); } if (is_symbol(a1)) { s7_pointer s1; s1 = s7_slot(sc, a1); if ((!is_slot(s1)) || (is_unsafe_stepper(s1)) || (!is_t_integer(slot_value(s1)))) return(NULL); xf_store(s1); return(negate_if_s); } if ((is_pair(a1)) && (s7_arg_to_if(sc, a1))) return(negate_if_p); return(NULL); } a2 = caddr(expr); if (is_null(cdddr(expr))) { if (is_t_integer(a1)) { xf_store(a1); if (is_t_integer(a2)) { xf_store(a2); return(sub_if_cc); } if (is_symbol(a2)) { slot = s7_slot(sc, a2); if ((!slot) || (!is_t_integer(slot_value(slot))) || (is_unsafe_stepper(slot))) return(NULL); xf_store(slot); return(sub_if_cs); } if ((is_pair(a2)) && (s7_arg_to_if(sc, a2))) return(sub_if_cp); return(NULL); } if (is_symbol(a1)) { slot = s7_slot(sc, a1); if ((!slot) || (!is_t_integer(slot_value(slot))) || (is_unsafe_stepper(slot))) return(NULL); xf_store(slot); if (is_t_integer(a2)) { xf_store(a2); return(sub_if_sc); } if (is_symbol(a2)) { slot = s7_slot(sc, a2); if ((!slot) || (!is_t_integer(slot_value(slot))) || (is_unsafe_stepper(slot))) return(NULL); xf_store(slot); return(sub_if_ss); } if ((is_pair(a2)) && (s7_arg_to_if(sc, a2))) return(sub_if_sp); return(NULL); } if (is_pair(a1) && (s7_arg_to_if(sc, a1))) { if (is_t_integer(a2)) { xf_store(a2); return(sub_if_pc); } if (is_symbol(a2)) { slot = s7_slot(sc, a2); if ((!slot) || (!is_t_integer(slot_value(slot))) || (is_unsafe_stepper(slot))) return(NULL); xf_store(slot); return(sub_if_ps); } if ((is_pair(a2)) && (s7_arg_to_if(sc, a2))) return(sub_if_pp); } return(NULL); } { s7_if_t xf, res; ptr_int loc; if (is_t_integer(a1)) { xf_store(a1); res = sub_if_cp; } else { if (is_symbol(a1)) { slot = s7_slot(sc, a1); if ((!slot) || (!is_t_integer(slot_value(slot))) || (is_unsafe_stepper(slot))) return(NULL); xf_store(slot); res = sub_if_sp; } else { if ((!is_pair(a1)) || (!s7_arg_to_if(sc, a1))) return(NULL); res = sub_if_pp; } } xf_save_loc(loc); xf = add_if(sc, cdr(expr)); if (xf) { xf_store_at(loc, (s7_pointer)xf); return(res); } } return(NULL); } static s7_double negate_rf_c(s7_scheme *sc, s7_pointer **p) {s7_pointer x; x = (**p); (*p)++; return(-(real_to_double(sc, x, "-")));} static s7_double negate_rf_s(s7_scheme *sc, s7_pointer **p) {s7_pointer x; x = slot_value(**p); (*p)++; return(-(real_to_double(sc, x, "-")));} static s7_double negate_rf_p(s7_scheme *sc, s7_pointer **p) {s7_rf_t f; f = (s7_rf_t)(**p); (*p)++; return(f(sc, p));} static s7_double sub_rf_cc(s7_scheme *sc, s7_pointer **p) { s7_pointer x, y; x = (**p); (*p)++; y = (**p); (*p)++; return(real(x) - real_to_double(sc, y, "-")); } static s7_double sub_rf_cs(s7_scheme *sc, s7_pointer **p) { s7_pointer x, y; x = (**p); (*p)++; y = slot_value(**p); (*p)++; return(real(x) - real_to_double(sc, y, "-")); } static s7_double sub_rf_ss(s7_scheme *sc, s7_pointer **p) { s7_pointer x, y; s7_double x1; x = slot_value(**p); (*p)++; y = slot_value(**p); (*p)++; x1 = real_to_double(sc, x, "-"); return(x1 - real_to_double(sc, y, "-")); } static s7_double sub_rf_sc(s7_scheme *sc, s7_pointer **p) { s7_pointer x, y; x = slot_value(**p); (*p)++; y = (**p); (*p)++; return(real_to_double(sc, x, "-") - real(y)); } static s7_double sub_rf_cp(s7_scheme *sc, s7_pointer **p) { s7_rf_t rf; s7_pointer x; x = (**p); (*p)++; rf = (s7_rf_t)(**p); (*p)++; return(real_to_double(sc, x, "-") - rf(sc, p)); } static s7_double sub_rf_pc(s7_scheme *sc, s7_pointer **p) { s7_rf_t rf; s7_double x; s7_pointer y; rf = (s7_rf_t)(**p); (*p)++; x = rf(sc,p); y = (**p); (*p)++; return(x - real_to_double(sc, y, "-")); } static s7_double sub_rf_sp(s7_scheme *sc, s7_pointer **p) { s7_rf_t rf; s7_pointer x; x = slot_value(**p); (*p)++; rf = (s7_rf_t)(**p); (*p)++; return(real_to_double(sc, x, "-") - rf(sc, p)); } static s7_double sub_rf_ps(s7_scheme *sc, s7_pointer **p) { s7_rf_t rf; s7_double x; s7_pointer y; rf = (s7_rf_t)(**p); (*p)++; x = rf(sc,p); y = slot_value(**p); (*p)++; return(x - real_to_double(sc, y, "-")); } static s7_double sub_rf_pp(s7_scheme *sc, s7_pointer **p) { s7_rf_t rf; s7_double x, y; rf = (s7_rf_t)(**p); (*p)++; x = rf(sc,p); rf = (s7_rf_t)(**p); (*p)++; y = rf(sc,p); return(x - y); } static s7_rf_t subtract_rf(s7_scheme *sc, s7_pointer expr) { s7_pointer a1, a2, slot1, slot2; xf_t *rc; if (!is_pair(cdr(expr))) return(NULL); xf_init(2); a1 = cadr(expr); if (is_null(cddr(expr))) { if (is_t_real(a1)) { xf_store(a1); return(negate_rf_c); } if (is_symbol(a1)) { slot1 = s7_slot(sc, a1); if ((!is_slot(slot1)) || (is_unsafe_stepper(slot1)) || (!(is_real(slot_value(slot1))))) return(NULL); xf_store(slot1); return(negate_rf_s); } if ((is_pair(a1)) && (s7_arg_to_if(sc, a1))) return(negate_rf_p); return(NULL); } a2 = caddr(expr); if (is_null(cdddr(expr))) { if (is_t_real(a1)) { xf_store(a1); if (is_real(a2)) { xf_store(a2); return(sub_rf_cc); } if (is_symbol(a2)) { slot2 = s7_slot(sc, a2); if ((!slot2) || (!is_real(slot_value(slot2))) || (is_unsafe_stepper(slot2))) return(NULL); xf_store(slot2); return(sub_rf_cs); } if ((is_pair(a2)) && (s7_arg_to_if(sc, a2))) return(sub_rf_cp); return(NULL); } if (is_symbol(a1)) { slot1 = s7_slot(sc, a1); if ((!slot1) || (!is_real(slot_value(slot1))) || (is_unsafe_stepper(slot1))) return(NULL); xf_store(slot1); if (is_t_real(a2)) { xf_store(a2); return(sub_rf_sc); } if (is_symbol(a2)) { slot2 = s7_slot(sc, a2); if ((!slot2) || (!is_real(slot_value(slot2))) || (is_unsafe_stepper(slot2))) return(NULL); if ((!is_t_real(slot_value(slot1))) && (!is_t_real(slot_value(slot2)))) return(NULL); xf_store(slot2); return(sub_rf_ss); } if ((is_pair(a2)) && (s7_arg_to_rf(sc, a2))) return(sub_rf_sp); return(NULL); } if (is_pair(a1) && (s7_arg_to_rf(sc, a1))) { if (is_real(a2)) { xf_store(a2); return(sub_rf_pc); } if (is_symbol(a2)) { slot2 = s7_slot(sc, a2); if ((!slot2) || (!is_real(slot_value(slot2))) || (is_unsafe_stepper(slot2))) return(NULL); xf_store(slot2); return(sub_rf_ps); } if ((is_pair(a2)) && (s7_arg_to_rf(sc, a2))) return(sub_rf_pp); } return(NULL); } { s7_rf_t rf, res; ptr_int loc; if (is_real(a1)) { xf_store(a1); res = sub_rf_cp; } else { if (is_symbol(a1)) { slot1 = s7_slot(sc, a1); if ((!slot1) || (!is_t_integer(slot_value(slot1))) || (is_unsafe_stepper(slot1))) return(NULL); xf_store(slot1); res = sub_rf_sp; } else { if ((!is_pair(a1)) || (!s7_arg_to_rf(sc, a1))) return(NULL); res = sub_rf_pp; } } xf_save_loc(loc); rf = add_rf(sc, cdr(expr)); if (rf) { xf_store_at(loc, (s7_pointer)rf); return(res); } } return(NULL); } #if WITH_ADD_PF static s7_pointer c_subtract_pf2(s7_scheme *sc, s7_pointer **p) { s7_pf_t pf; s7_pointer x, y; pf = (s7_pf_t)(**p); (*p)++; x = pf(sc, p); xf_push(sc, x); pf = (s7_pf_t)(**p); (*p)++; y = pf(sc, p); x = g_subtract_2(sc, set_plist_2(sc, x, y)); xf_pop(sc); return(x); } static s7_pf_t subtract_pf(s7_scheme *sc, s7_pointer expr) { int len; len = s7_list_length(sc, expr); if (len == 3) { if ((s7_arg_to_pf(sc, cadr(expr))) && (s7_arg_to_pf(sc, caddr(expr)))) return(c_subtract_pf2); } return(NULL); } #endif #endif /* ---------------------------------------- multiply ---------------------------------------- */ static s7_pointer g_multiply(s7_scheme *sc, s7_pointer args) { #define H_multiply "(* ...) multiplies its arguments" #define Q_multiply pcl_n s7_pointer x, p; s7_int num_a, den_a; s7_double rl_a, im_a; #if (!WITH_GMP) if (is_null(args)) return(small_int(1)); #endif x = car(args); p = cdr(args); if (is_null(p)) { if (!is_number(x)) method_or_bust_with_type(sc, x, sc->MULTIPLY, args, A_NUMBER, 0); return(x); } switch (type(x)) { case T_INTEGER: num_a = integer(x); MULTIPLY_INTEGERS: #if WITH_GMP if ((num_a > s7_int32_max) || (num_a < s7_int32_min)) return(big_multiply(sc, cons(sc, s7_int_to_big_integer(sc, num_a), p))); #endif x = car(p); p = cdr(p); switch (type(x)) { case T_INTEGER: #if WITH_GMP if ((integer(x) > s7_int32_max) || (integer(x) < s7_int32_min)) return(big_multiply(sc, cons(sc, s7_int_to_big_integer(sc, num_a), cons(sc, x, p)))); #endif #if HAVE_OVERFLOW_CHECKS { s7_int dn; if (multiply_overflow(num_a, integer(x), &dn)) { if (is_null(p)) return(make_real(sc, (s7_double)num_a * (s7_double)integer(x))); rl_a = (s7_double)num_a * (s7_double)integer(x); goto MULTIPLY_REALS; } num_a = dn; } #else /* perhaps put all the math-safety stuff on the 'safety switch? * (* 256 17179869184 4194304) -> 0 which is annoying * (* 134217728 137438953472) -> 0 */ if ((integer_length(num_a) + integer_length(integer(x))) >= s7_int_bits) { if (is_null(p)) return(make_real(sc, (s7_double)num_a * (s7_double)integer(x))); rl_a = (s7_double)num_a * (s7_double)integer(x); goto MULTIPLY_REALS; } num_a *= integer(x); #endif if (is_null(p)) return(make_integer(sc, num_a)); goto MULTIPLY_INTEGERS; case T_RATIO: #if HAVE_OVERFLOW_CHECKS { s7_int dn; if (multiply_overflow(numerator(x), num_a, &dn)) { if (is_null(p)) return(make_real(sc, (s7_double)num_a * fraction(x))); rl_a = (s7_double)num_a * fraction(x); goto MULTIPLY_REALS; } num_a = dn; } #else if ((integer_length(num_a) + integer_length(numerator(x))) >= s7_int_bits) { if (is_null(p)) return(make_real(sc, (s7_double)num_a * fraction(x))); rl_a = (s7_double)num_a * fraction(x); goto MULTIPLY_REALS; } num_a *= numerator(x); #endif den_a = denominator(x); if (is_null(p)) return(s7_make_ratio(sc, num_a, den_a)); if (reduce_fraction(sc, &num_a, &den_a) == T_INTEGER) goto MULTIPLY_INTEGERS; goto MULTIPLY_RATIOS; case T_REAL: if (is_null(p)) return(make_real(sc, num_a * real(x))); rl_a = num_a * real(x); goto MULTIPLY_REALS; case T_COMPLEX: if (is_null(p)) return(s7_make_complex(sc, num_a * real_part(x), num_a * imag_part(x))); rl_a = num_a * real_part(x); im_a = num_a * imag_part(x); goto MULTIPLY_COMPLEX; default: method_or_bust_with_type(sc, x, sc->MULTIPLY, cons(sc, s7_make_integer(sc, num_a), cons(sc, x, p)), A_NUMBER, position_of(p, args) - 1); } break; case T_RATIO: num_a = numerator(x); den_a = denominator(x); MULTIPLY_RATIOS: #if WITH_GMP if ((num_a > s7_int32_max) || (den_a > s7_int32_max) || (num_a < s7_int32_min)) return(big_multiply(sc, cons(sc, s7_ratio_to_big_ratio(sc, num_a, den_a), p))); #endif x = car(p); p = cdr(p); switch (type(x)) { case T_INTEGER: /* as in +, this can overflow: * (* 8 -9223372036854775807 8) -> 64 * (* 3/4 -9223372036854775807 8) -> 6 * (* 8 -9223372036854775808 8) -> 0 * (* -1 9223372036854775806 8) -> 16 * (* -9223372036854775808 8 1e+308) -> 0.0 */ #if HAVE_OVERFLOW_CHECKS { s7_int dn; if (multiply_overflow(integer(x), num_a, &dn)) { if (is_null(p)) return(make_real(sc, ((s7_double)integer(x) / (s7_double)den_a) * (s7_double)num_a)); rl_a = ((s7_double)integer(x) / (s7_double)den_a) * (s7_double)num_a; goto MULTIPLY_REALS; } num_a = dn; } #else if ((integer_length(num_a) + integer_length(integer(x))) >= s7_int_bits) { if (is_null(p)) return(make_real(sc, ((s7_double)integer(x) / (s7_double)den_a) * (s7_double)num_a)); rl_a = ((s7_double)integer(x) / (s7_double)den_a) * (s7_double)num_a; goto MULTIPLY_REALS; } num_a *= integer(x); #endif if (is_null(p)) return(s7_make_ratio(sc, num_a, den_a)); if (reduce_fraction(sc, &num_a, &den_a) == T_INTEGER) goto MULTIPLY_INTEGERS; goto MULTIPLY_RATIOS; case T_RATIO: { #if (!WITH_GMP) s7_int d1, n1; #endif s7_int d2, n2; d2 = denominator(x); n2 = numerator(x); #if (!WITH_GMP) d1 = den_a; n1 = num_a; #if HAVE_OVERFLOW_CHECKS if ((multiply_overflow(n1, n2, &num_a)) || (multiply_overflow(d1, d2, &den_a))) { if (is_null(p)) return(make_real(sc, ((long double)n1 / (long double)d1) * ((long double)n2 / (long double)d2))); rl_a = ((long double)n1 / (long double)d1) * ((long double)n2 / (long double)d2); goto MULTIPLY_REALS; } #else if ((d1 > s7_int32_max) || (d2 > s7_int32_max) || /* before counting bits, check that overflow is possible */ (n1 > s7_int32_max) || (n2 > s7_int32_max) || /* (* 1/524288 1/19073486328125) for example */ (n1 < s7_int32_min) || (n2 < s7_int32_min)) { if ((integer_length(d1) + integer_length(d2) > s7_int_bits) || (integer_length(n1) + integer_length(n2) > s7_int_bits)) { if (is_null(p)) return(make_real(sc, ((long double)n1 / (long double)d1) * ((long double)n2 / (long double)d2))); rl_a = ((long double)n1 / (long double)d1) * ((long double)n2 / (long double)d2); goto MULTIPLY_REALS; } } num_a *= n2; den_a *= d2; #endif #else num_a *= n2; den_a *= d2; #endif if (is_null(p)) return(s7_make_ratio(sc, num_a, den_a)); if (reduce_fraction(sc, &num_a, &den_a) == T_INTEGER) goto MULTIPLY_INTEGERS; goto MULTIPLY_RATIOS; } case T_REAL: if (is_null(p)) return(make_real(sc, ((long double)num_a / (long double)den_a) * real(x))); rl_a = ((long double)num_a / (long double)den_a) * real(x); goto MULTIPLY_REALS; case T_COMPLEX: { s7_double frac; frac = ((long double)num_a / (long double)den_a); if (is_null(p)) return(s7_make_complex(sc, frac * real_part(x), frac * imag_part(x))); rl_a = frac * real_part(x); im_a = frac * imag_part(x); goto MULTIPLY_COMPLEX; } default: method_or_bust_with_type(sc, x, sc->MULTIPLY, cons(sc, s7_make_ratio(sc, num_a, den_a), cons(sc, x, p)), A_NUMBER, position_of(p, args) - 1); } break; case T_REAL: rl_a = real(x); MULTIPLY_REALS: x = car(p); p = cdr(p); switch (type(x)) { case T_INTEGER: if (is_null(p)) return(make_real(sc, rl_a * integer(x))); rl_a *= integer(x); goto MULTIPLY_REALS; case T_RATIO: if (is_null(p)) return(make_real(sc, rl_a * fraction(x))); rl_a *= (s7_double)fraction(x); goto MULTIPLY_REALS; case T_REAL: if (is_null(p)) return(make_real(sc, rl_a * real(x))); rl_a *= real(x); goto MULTIPLY_REALS; case T_COMPLEX: if (is_null(p)) return(s7_make_complex(sc, rl_a * real_part(x), rl_a * imag_part(x))); im_a = rl_a * imag_part(x); rl_a *= real_part(x); goto MULTIPLY_COMPLEX; default: method_or_bust_with_type(sc, x, sc->MULTIPLY, cons(sc, make_real(sc, rl_a), cons(sc, x, p)), A_NUMBER, position_of(p, args) - 1); } break; case T_COMPLEX: rl_a = real_part(x); im_a = imag_part(x); MULTIPLY_COMPLEX: x = car(p); p = cdr(p); switch (type(x)) { case T_INTEGER: if (is_null(p)) return(s7_make_complex(sc, rl_a * integer(x), im_a * integer(x))); rl_a *= integer(x); im_a *= integer(x); goto MULTIPLY_COMPLEX; case T_RATIO: { s7_double frac; frac = fraction(x); if (is_null(p)) return(s7_make_complex(sc, rl_a * frac, im_a * frac)); rl_a *= frac; im_a *= frac; goto MULTIPLY_COMPLEX; } case T_REAL: if (is_null(p)) return(s7_make_complex(sc, rl_a * real(x), im_a * real(x))); rl_a *= real(x); im_a *= real(x); goto MULTIPLY_COMPLEX; case T_COMPLEX: { s7_double r1, r2, i1, i2; r1 = rl_a; i1 = im_a; r2 = real_part(x); i2 = imag_part(x); if (is_null(p)) return(s7_make_complex(sc, r1 * r2 - i1 * i2, r1 * i2 + r2 * i1)); rl_a = r1 * r2 - i1 * i2; im_a = r1 * i2 + r2 * i1; if (im_a == 0.0) goto MULTIPLY_REALS; goto MULTIPLY_COMPLEX; } default: method_or_bust_with_type(sc, x, sc->MULTIPLY, cons(sc, s7_make_complex(sc, rl_a, im_a), cons(sc, x, p)), A_NUMBER, position_of(p, args) - 1); } break; default: method_or_bust_with_type(sc, x, sc->MULTIPLY, args, A_NUMBER, 1); } } #if (!WITH_GMP) static s7_pointer multiply_2, multiply_fs, multiply_sf, multiply_is, multiply_si; static s7_pointer g_multiply_2(s7_scheme *sc, s7_pointer args) { s7_pointer x, y; x = car(args); y = cadr(args); if (type(x) == type(y)) { if (is_t_real(x)) return(make_real(sc, real(x) * real(y))); else { switch (type(x)) { #if HAVE_OVERFLOW_CHECKS case T_INTEGER: { s7_int n; if (multiply_overflow(integer(x), integer(y), &n)) return(make_real(sc, ((s7_double)integer(x)) * ((s7_double)integer(y)))); return(make_integer(sc, n)); } #else case T_INTEGER: return(make_integer(sc, integer(x) * integer(y))); #endif case T_RATIO: return(g_multiply(sc, args)); case T_REAL: return(make_real(sc, real(x) * real(y))); case T_COMPLEX: { s7_double r1, r2, i1, i2; r1 = real_part(x); r2 = real_part(y); i1 = imag_part(x); i2 = imag_part(y); return(s7_make_complex(sc, r1 * r2 - i1 * i2, r1 * i2 + r2 * i1)); } default: if (!is_number(x)) method_or_bust_with_type(sc, x, sc->MULTIPLY, args, A_NUMBER, 1); method_or_bust_with_type(sc, y, sc->MULTIPLY, args, A_NUMBER, 2); } } } switch (type(x)) { case T_INTEGER: switch (type(y)) { case T_INTEGER: return(make_integer(sc, integer(x) * integer(y))); case T_RATIO: return(g_multiply(sc, args)); case T_REAL: return(make_real(sc, integer(x) * real(y))); case T_COMPLEX: return(s7_make_complex(sc, integer(x) * real_part(y), integer(x) * imag_part(y))); default: method_or_bust_with_type(sc, y, sc->MULTIPLY, args, A_NUMBER, 2); } case T_RATIO: switch (type(y)) { case T_INTEGER: case T_RATIO: return(g_multiply(sc, args)); case T_REAL: return(make_real(sc, fraction(x) * real(y))); case T_COMPLEX: { s7_double frac; frac = fraction(x); return(s7_make_complex(sc, frac * real_part(y), frac * imag_part(y))); } default: method_or_bust_with_type(sc, y, sc->MULTIPLY, args, A_NUMBER, 2); } case T_REAL: switch (type(y)) { case T_INTEGER: return(make_real(sc, real(x) * integer(y))); case T_RATIO: return(make_real(sc, real(x) * fraction(y))); case T_REAL: return(make_real(sc, real(x) * real(y))); case T_COMPLEX: return(s7_make_complex(sc, real(x) * real_part(y), real(x) * imag_part(y))); default: method_or_bust_with_type(sc, y, sc->MULTIPLY, args, A_NUMBER, 2); } case T_COMPLEX: switch (type(y)) { case T_INTEGER: return(s7_make_complex(sc, real_part(x) * integer(y), imag_part(x) * integer(y))); case T_RATIO: { s7_double frac; frac = fraction(y); return(s7_make_complex(sc, real_part(x) * frac, imag_part(x) * frac)); } case T_REAL: return(s7_make_complex(sc, real_part(x) * real(y), imag_part(x) * real(y))); case T_COMPLEX: { s7_double r1, r2, i1, i2; r1 = real_part(x); r2 = real_part(y); i1 = imag_part(x); i2 = imag_part(y); return(s7_make_complex(sc, r1 * r2 - i1 * i2, r1 * i2 + r2 * i1)); } default: method_or_bust_with_type(sc, y, sc->MULTIPLY, args, A_NUMBER, 2); } default: method_or_bust_with_type(sc, x, sc->MULTIPLY, args, A_NUMBER, 1); } return(x); } /* all of these mess up if overflows occur * (let () (define (f x) (* x 9223372036854775806)) (f -63)) -> -9223372036854775682, but (* -63 9223372036854775806) -> -5.810724383218509e+20 * how to catch this? (affects * - +) */ static s7_pointer g_multiply_si(s7_scheme *sc, s7_pointer args) { s7_pointer x; s7_int n; x = find_symbol_checked(sc, car(args)); n = integer(cadr(args)); switch (type(x)) { #if HAVE_OVERFLOW_CHECKS case T_INTEGER: { s7_int val; if (multiply_overflow(integer(x), n, &val)) return(make_real(sc, (double)integer(x) * (double)n)); return(make_integer(sc, val)); } case T_RATIO: { s7_int val; if (multiply_overflow(numerator(x), n, &val)) return(make_real(sc, fraction(x) * (double)n)); return(s7_make_ratio(sc, val, denominator(x))); } #else case T_INTEGER: return(make_integer(sc, integer(x) * n)); case T_RATIO: return(s7_make_ratio(sc, numerator(x) * n, denominator(x))); #endif case T_REAL: return(make_real(sc, real(x) * n)); case T_COMPLEX: return(s7_make_complex(sc, real_part(x) * n, imag_part(x) * n)); default: method_or_bust_with_type(sc, x, sc->MULTIPLY, list_2(sc, x, cadr(args)), A_NUMBER, 1); } return(x); } static s7_pointer g_multiply_is(s7_scheme *sc, s7_pointer args) { s7_pointer x; s7_int n; x = find_symbol_checked(sc, cadr(args)); n = integer(car(args)); switch (type(x)) { #if HAVE_OVERFLOW_CHECKS case T_INTEGER: { s7_int val; if (multiply_overflow(integer(x), n, &val)) return(make_real(sc, (double)integer(x) * (double)n)); return(make_integer(sc, val)); } case T_RATIO: { s7_int val; if (multiply_overflow(numerator(x), n, &val)) return(make_real(sc, fraction(x) * (double)n)); return(s7_make_ratio(sc, val, denominator(x))); } #else case T_INTEGER: return(make_integer(sc, integer(x) * n)); case T_RATIO: return(s7_make_ratio(sc, numerator(x) * n, denominator(x))); #endif case T_REAL: return(make_real(sc, real(x) * n)); case T_COMPLEX: return(s7_make_complex(sc, real_part(x) * n, imag_part(x) * n)); default: method_or_bust_with_type(sc, x, sc->MULTIPLY, list_2(sc, car(args), x), A_NUMBER, 2); } return(x); } static s7_pointer g_multiply_fs(s7_scheme *sc, s7_pointer args) { s7_pointer x; s7_double scl; scl = real(car(args)); x = find_symbol_checked(sc, cadr(args)); switch (type(x)) { case T_INTEGER: return(make_real(sc, integer(x) * scl)); case T_RATIO: return(make_real(sc, numerator(x) * scl / denominator(x))); case T_REAL: return(make_real(sc, real(x) * scl)); case T_COMPLEX: return(s7_make_complex(sc, real_part(x) * scl, imag_part(x) * scl)); default: method_or_bust_with_type(sc, x, sc->MULTIPLY, list_2(sc, car(args), x), A_NUMBER, 1); } return(x); } static s7_pointer g_multiply_sf(s7_scheme *sc, s7_pointer args) { s7_pointer x; s7_double scl; scl = real(cadr(args)); x = find_symbol_checked(sc, car(args)); switch (type(x)) { case T_INTEGER: return(make_real(sc, integer(x) * scl)); case T_RATIO: return(make_real(sc, numerator(x) * scl / denominator(x))); case T_REAL: return(make_real(sc, real(x) * scl)); case T_COMPLEX: return(s7_make_complex(sc, real_part(x) * scl, imag_part(x) * scl)); default: method_or_bust_with_type(sc, x, sc->MULTIPLY, list_2(sc, x, cadr(args)), A_NUMBER, 2); } return(x); } static s7_pointer sqr_ss; static s7_pointer g_sqr_ss(s7_scheme *sc, s7_pointer args) { s7_pointer x; x = find_symbol_checked(sc, car(args)); switch (type(x)) { #if HAVE_OVERFLOW_CHECKS case T_INTEGER: { s7_int val; if (multiply_overflow(integer(x), integer(x), &val)) return(make_real(sc, (double)integer(x) * (double)integer(x))); return(make_integer(sc, val)); } case T_RATIO: { s7_int num, den; if ((multiply_overflow(numerator(x), numerator(x), &num)) || (multiply_overflow(denominator(x), denominator(x), &den))) return(make_real(sc, fraction(x) * fraction(x))); return(s7_make_ratio(sc, num, den)); } #else case T_INTEGER: return(s7_make_integer(sc, integer(x) * integer(x))); case T_RATIO: return(s7_make_ratio(sc, numerator(x) * numerator(x), denominator(x) * denominator(x))); #endif case T_REAL: return(make_real(sc, real(x) * real(x))); case T_COMPLEX: return(s7_make_complex(sc, real_part(x) * real_part(x) - imag_part(x) * imag_part(x), 2.0 * real_part(x) * imag_part(x))); default: method_or_bust_with_type(sc, x, sc->MULTIPLY, list_2(sc, x, x), A_NUMBER, 1); } return(x); } static s7_pointer mul_1ss; static s7_pointer g_mul_1ss(s7_scheme *sc, s7_pointer args) { /* (* (- 1.0 x) y) */ s7_pointer x, y; x = find_symbol_checked(sc, caddr(car(args))); y = find_symbol_checked(sc, cadr(args)); if ((is_t_real(x)) && (is_t_real(y))) return(make_real(sc, real(y) * (1.0 - real(x)))); if ((is_real(x)) && (is_real(y))) { s7_double x1; x1 = real_to_double(sc, y, "*"); return(make_real(sc, x1 * (1.0 - real_to_double(sc, x, "*")))); } else { s7_double r1, r2, i1, i2; if (!is_number(x)) { s7_pointer func; if ((func = find_method(sc, find_let(sc, x), sc->SUBTRACT)) != sc->UNDEFINED) return(g_multiply_2(sc, set_plist_2(sc, s7_apply_function(sc, func, list_2(sc, real_one, x)), y))); return(wrong_type_argument_with_type(sc, sc->SUBTRACT, 2, x, A_NUMBER)); } if (!is_number(y)) { s7_pointer func; if ((func = find_method(sc, find_let(sc, y), sc->MULTIPLY)) != sc->UNDEFINED) return(s7_apply_function(sc, func, list_2(sc, g_subtract(sc, list_2(sc, real_one, x)), y))); return(wrong_type_argument_with_type(sc, sc->MULTIPLY, 2, y, A_NUMBER)); } r1 = 1.0 - s7_real_part(x); r2 = s7_real_part(y); i1 = -s7_imag_part(x); i2 = s7_imag_part(y); return(s7_make_complex(sc, r1 * r2 - i1 * i2, r1 * i2 + r2 * i1)); } } static s7_pointer multiply_cs_cos; static s7_pointer g_multiply_cs_cos(s7_scheme *sc, s7_pointer args) { /* ([*] -2.0 r (cos x)) */ s7_pointer r, x; r = find_symbol_checked(sc, cadr(args)); x = find_symbol_checked(sc, cadr(caddr(args))); if ((is_t_real(r)) && (is_t_real(x))) return(make_real(sc, real(car(args)) * real(r) * cos(real(x)))); if ((is_real(r)) && (is_real(x))) return(make_real(sc, real(car(args)) * real_to_double(sc, r, "*") * cos(real_to_double(sc, x, "*")))); return(g_multiply(sc, set_plist_3(sc, car(args), r, g_cos(sc, set_plist_1(sc, x))))); } static s7_pointer mul_s_sin_s, mul_s_cos_s; static s7_pointer g_mul_s_sin_s(s7_scheme *sc, s7_pointer args) { /* (* s (sin s)) */ s7_pointer x, y; x = find_symbol_checked(sc, car(args)); y = find_symbol_checked(sc, cadadr(args)); if ((is_real(x)) && (is_real(y))) return(make_real(sc, real_to_double(sc, x, "*") * sin(real_to_double(sc, y, "sin")))); return(g_multiply(sc, set_plist_2(sc, x, g_sin(sc, set_plist_1(sc, y))))); } static s7_pointer g_mul_s_cos_s(s7_scheme *sc, s7_pointer args) { /* (* s (cos s)) */ s7_pointer x, y; x = find_symbol_checked(sc, car(args)); y = find_symbol_checked(sc, cadadr(args)); if ((is_real(x)) && (is_real(y))) return(make_real(sc, real_to_double(sc, x, "*") * cos(real_to_double(sc, y, "cos")))); return(g_multiply(sc, set_plist_2(sc, x, g_cos(sc, set_plist_1(sc, y))))); } static s7_double multiply_rf_xx(s7_scheme *sc, s7_pointer **p) { s7_rf_t r1, r2; s7_double x, y; r1 = (s7_rf_t)(**p); (*p)++; x = r1(sc, p); r2 = (s7_rf_t)(**p); (*p)++; y = r2(sc, p); return(x * y); } static s7_double multiply_rf_rx(s7_scheme *sc, s7_pointer **p) { s7_pointer c1; s7_rf_t r1; s7_double x; c1 = **p; (*p)++; r1 = (s7_rf_t)(**p); (*p)++; x = r1(sc, p); return(x * real_to_double(sc, c1, "*")); } static s7_double multiply_rf_sx(s7_scheme *sc, s7_pointer **p) { s7_pointer s1; s7_rf_t r1; s7_double x; s1 = slot_value(**p); (*p)++; r1 = (s7_rf_t)(**p); (*p)++; x = r1(sc, p); return(x * real_to_double(sc, s1, "*")); } static s7_double multiply_rf_ss(s7_scheme *sc, s7_pointer **p) { s7_pointer s1, s2; s7_double x1; s1 = slot_value(**p); (*p)++; x1 = real_to_double(sc, s1, "*"); s2 = slot_value(**p); (*p)++; return(x1 * real_to_double(sc, s2, "*")); } static s7_double multiply_rf_rs(s7_scheme *sc, s7_pointer **p) { s7_pointer c1, s1; s7_double x1; s1 = slot_value(**p); (*p)++; c1 = **p; (*p)++; x1 = real_to_double(sc, c1, "*"); return(x1 * real_to_double(sc, s1, "*")); } static s7_double multiply_rf_xxx(s7_scheme *sc, s7_pointer **p) { s7_rf_t r1, r2, r3; s7_double x, y, z; r1 = (s7_rf_t)(**p); (*p)++; x = r1(sc, p); r2 = (s7_rf_t)(**p); (*p)++; y = r2(sc, p); r3 = (s7_rf_t)(**p); (*p)++; z = r3(sc, p); return(x * y * z); } static s7_double multiply_rf_rxx(s7_scheme *sc, s7_pointer **p) { s7_pointer c1; s7_rf_t r1, r2; s7_double x, y; c1 = **p; (*p)++; r1 = (s7_rf_t)(**p); (*p)++; x = r1(sc, p); r2 = (s7_rf_t)(**p); (*p)++; y = r2(sc, p); return(x * y * real_to_double(sc, c1, "*")); } static s7_double multiply_rf_sxx(s7_scheme *sc, s7_pointer **p) { s7_pointer s1; s7_rf_t r1, r2; s7_double x, y; s1 = slot_value(**p); (*p)++; r1 = (s7_rf_t)(**p); (*p)++; x = r1(sc, p); r2 = (s7_rf_t)(**p); (*p)++; y = r2(sc, p); return(x * y * real_to_double(sc, s1, "*")); } static s7_double multiply_rf_rsx(s7_scheme *sc, s7_pointer **p) { s7_pointer c1, s1; s7_rf_t r1; s7_double x, x1; s1 = slot_value(**p); (*p)++; c1 = **p; (*p)++; x1 = real_to_double(sc, c1, "*"); r1 = (s7_rf_t)(**p); (*p)++; x = r1(sc, p); return(x * x1 * real_to_double(sc, s1, "*")); } static s7_double multiply_rf_ssx(s7_scheme *sc, s7_pointer **p) { s7_pointer s1, s2; s7_rf_t r1; s7_double x, x1; s1 = slot_value(**p); (*p)++; x1 = real_to_double(sc, s1, "*"); s2 = slot_value(**p); (*p)++; r1 = (s7_rf_t)(**p); (*p)++; x = r1(sc, p); return(x * x1 * real_to_double(sc, s2, "*")); } static s7_double multiply_rf_sss(s7_scheme *sc, s7_pointer **p) { s7_pointer s1, s2, s3; s7_double x1, x2, x3; s1 = slot_value(**p); (*p)++; x1 = real_to_double(sc, s1, "*"); s2 = slot_value(**p); (*p)++; x2 = real_to_double(sc, s2, "*"); s3 = slot_value(**p); (*p)++; x3 = real_to_double(sc, s3, "*"); return(x1 * x2 * x3); } static s7_double multiply_rf_rss(s7_scheme *sc, s7_pointer **p) { s7_pointer c1, s1, s2; s7_double x1, x2, x3; s1 = slot_value(**p); (*p)++; x1 = real_to_double(sc, s1, "*"); s2 = slot_value(**p); (*p)++; x2 = real_to_double(sc, s2, "*"); c1 = **p; (*p)++; x3 = real_to_double(sc, c1, "*"); return(x1 * x2 * x3); } static s7_rf_t multiply_rf_1(s7_scheme *sc, s7_pointer expr, int len) { if (len == 3) return(com_rf_2(sc, expr, multiply_r_ops)); if (len == 4) return(com_rf_3(sc, expr, multiply_r_ops)); if (len > 4) { s7_rf_t rf; ptr_int loc; xf_t *rc; int first_len; xf_init(2); first_len = (int)(len / 2); xf_save_loc(loc); rf = multiply_rf_1(sc, expr, first_len + 1); if (rf) { int i; s7_pointer p; xf_store_at(loc, (s7_pointer)rf); xf_save_loc(loc); for (i = 0, p = expr; i < first_len; i++, p = cdr(p)); rf = multiply_rf_1(sc, p, len - first_len); if (rf) { xf_store_at(loc, (s7_pointer)rf); return(multiply_rf_xx); } else return(NULL); } else return(NULL); } return(NULL); } static s7_rf_t multiply_rf(s7_scheme *sc, s7_pointer expr) { return(multiply_rf_1(sc, expr, s7_list_length(sc, expr))); } static s7_int multiply_if_xx(s7_scheme *sc, s7_pointer **p) { s7_if_t r1, r2; s7_int x, y; r1 = (s7_if_t)(**p); (*p)++; x = r1(sc, p); r2 = (s7_if_t)(**p); (*p)++; y = r2(sc, p); return(x * y); } static s7_int multiply_if_rx(s7_scheme *sc, s7_pointer **p) { s7_pointer c1; s7_if_t r1; s7_int x; c1 = **p; (*p)++; r1 = (s7_if_t)(**p); (*p)++; x = r1(sc, p); return(x * integer(c1)); } static s7_int multiply_if_sx(s7_scheme *sc, s7_pointer **p) { s7_pointer s1; s7_if_t r1; s7_int x; s1 = slot_value(**p); (*p)++; r1 = (s7_if_t)(**p); (*p)++; x = r1(sc, p); return(x * integer(s1)); } static s7_int multiply_if_ss(s7_scheme *sc, s7_pointer **p) { s7_pointer s1, s2; s1 = slot_value(**p); (*p)++; s2 = slot_value(**p); (*p)++; return(integer(s1) * integer(s2)); } static s7_int multiply_if_rs(s7_scheme *sc, s7_pointer **p) { s7_pointer c1, s1; s1 = slot_value(**p); (*p)++; c1 = **p; (*p)++; return(integer(c1) * integer(s1)); } static s7_int multiply_if_xxx(s7_scheme *sc, s7_pointer **p) { s7_if_t r1, r2, r3; s7_int x, y, z; r1 = (s7_if_t)(**p); (*p)++; x = r1(sc, p); r2 = (s7_if_t)(**p); (*p)++; y = r2(sc, p); r3 = (s7_if_t)(**p); (*p)++; z = r3(sc, p); return(x * y * z); } static s7_int multiply_if_rxx(s7_scheme *sc, s7_pointer **p) { s7_pointer c1; s7_if_t r1, r2; s7_int x, y; c1 = **p; (*p)++; r1 = (s7_if_t)(**p); (*p)++; x = r1(sc, p); r2 = (s7_if_t)(**p); (*p)++; y = r2(sc, p); return(x * y * integer(c1)); } static s7_int multiply_if_sxx(s7_scheme *sc, s7_pointer **p) { s7_pointer s1; s7_if_t r1, r2; s7_int x, y; s1 = slot_value(**p); (*p)++; r1 = (s7_if_t)(**p); (*p)++; x = r1(sc, p); r2 = (s7_if_t)(**p); (*p)++; y = r2(sc, p); return(x * y * integer(s1)); } static s7_int multiply_if_rsx(s7_scheme *sc, s7_pointer **p) { s7_pointer c1, s1; s7_if_t r1; s7_int x; s1 = slot_value(**p); (*p)++; c1 = **p; (*p)++; r1 = (s7_if_t)(**p); (*p)++; x = r1(sc, p); return(x * integer(c1) * integer(s1)); } static s7_int multiply_if_ssx(s7_scheme *sc, s7_pointer **p) { s7_pointer s1, s2; s7_if_t r1; s7_int x; s1 = slot_value(**p); (*p)++; s2 = slot_value(**p); (*p)++; r1 = (s7_if_t)(**p); (*p)++; x = r1(sc, p); return(x * integer(s1) * integer(s2)); } static s7_int multiply_if_sss(s7_scheme *sc, s7_pointer **p) { s7_pointer s1, s2, s3; s1 = slot_value(**p); (*p)++; s2 = slot_value(**p); (*p)++; s3 = slot_value(**p); (*p)++; return(integer(s1) * integer(s2) * integer(s3)); } static s7_int multiply_if_rss(s7_scheme *sc, s7_pointer **p) { s7_pointer c1, s1, s2; s1 = slot_value(**p); (*p)++; s2 = slot_value(**p); (*p)++; c1 = **p; (*p)++; return(integer(c1) * integer(s1) * integer(s2)); } static s7_if_t multiply_if_1(s7_scheme *sc, s7_pointer expr, int len) { if (len == 3) return(com_if_2(sc, expr, multiply_i_ops)); if (len == 4) return(com_if_3(sc, expr, multiply_i_ops)); if (len > 4) { s7_if_t xf; xf_t *rc; ptr_int loc; int first_len; xf_init(2); first_len = (int)(len / 2); xf_save_loc(loc); xf = multiply_if_1(sc, expr, first_len + 1); if (xf) { int i; s7_pointer p; xf_store_at(loc, (s7_pointer)xf); xf_save_loc(loc); for (i = 0, p = expr; i < first_len; i++, p = cdr(p)); xf = multiply_if_1(sc, p, len - first_len); if (xf) { xf_store_at(loc, (s7_pointer)xf); return(multiply_if_xx); } else return(NULL); } else return(NULL); } return(NULL); } static s7_if_t multiply_if(s7_scheme *sc, s7_pointer expr) { return(multiply_if_1(sc, expr, s7_list_length(sc, expr))); } static void init_multiply_ops(void) { multiply_r_ops = (rf_ops *)calloc(1, sizeof(rf_ops)); multiply_r_ops->r = rf_c; multiply_r_ops->s = rf_s; multiply_r_ops->rs = multiply_rf_rs; multiply_r_ops->rp = multiply_rf_rx; multiply_r_ops->sp = multiply_rf_sx; multiply_r_ops->ss = multiply_rf_ss; multiply_r_ops->pp = multiply_rf_xx; multiply_r_ops->rss = multiply_rf_rss; multiply_r_ops->rsp = multiply_rf_rsx; multiply_r_ops->rpp = multiply_rf_rxx; multiply_r_ops->sss = multiply_rf_sss; multiply_r_ops->ssp = multiply_rf_ssx; multiply_r_ops->spp = multiply_rf_sxx; multiply_r_ops->ppp = multiply_rf_xxx; multiply_i_ops = (if_ops *)calloc(1, sizeof(if_ops)); multiply_i_ops->r = if_c; multiply_i_ops->s = if_s; multiply_i_ops->rs = multiply_if_rs; multiply_i_ops->rp = multiply_if_rx; multiply_i_ops->sp = multiply_if_sx; multiply_i_ops->ss = multiply_if_ss; multiply_i_ops->pp = multiply_if_xx; multiply_i_ops->rss = multiply_if_rss; multiply_i_ops->rsp = multiply_if_rsx; multiply_i_ops->rpp = multiply_if_rxx; multiply_i_ops->sss = multiply_if_sss; multiply_i_ops->ssp = multiply_if_ssx; multiply_i_ops->spp = multiply_if_sxx; multiply_i_ops->ppp = multiply_if_xxx; } #if WITH_ADD_PF static s7_pointer c_mul_pf2(s7_scheme *sc, s7_pointer **p) { s7_pf_t pf; s7_pointer x, y; pf = (s7_pf_t)(**p); (*p)++; x = pf(sc, p); xf_push(sc, x); pf = (s7_pf_t)(**p); (*p)++; y = pf(sc, p); x = g_multiply_2(sc, set_plist_2(sc, x, y)); xf_pop(sc); return(x); } static s7_pf_t multiply_pf(s7_scheme *sc, s7_pointer expr) { int len; len = s7_list_length(sc, expr); if (len == 3) { if ((s7_arg_to_pf(sc, cadr(expr))) && (s7_arg_to_pf(sc, caddr(expr)))) return(c_mul_pf2); } return(NULL); } #endif #endif /* with-gmp */ /* ---------------------------------------- divide ---------------------------------------- */ static bool is_number_via_method(s7_scheme *sc, s7_pointer p) { if (s7_is_number(p)) return(true); if (has_methods(p)) { s7_pointer f; f = find_method(sc, find_let(sc, p), sc->IS_NUMBER); if (f != sc->UNDEFINED) return(is_true(sc, s7_apply_function(sc, f, cons(sc, p, sc->NIL)))); } return(false); } static s7_pointer g_divide(s7_scheme *sc, s7_pointer args) { #define H_divide "(/ x1 ...) divides its first argument by the rest, or inverts the first if there is only one argument" #define Q_divide pcl_n s7_pointer x, p; s7_int num_a, den_a; s7_double rl_a, im_a; x = car(args); p = cdr(args); if (is_null(p)) { if (!is_number(x)) method_or_bust_with_type(sc, x, sc->DIVIDE, args, A_NUMBER, 0); if (s7_is_zero(x)) return(division_by_zero_error(sc, sc->DIVIDE, args)); return(s7_invert(sc, x)); } switch (type(x)) { case T_INTEGER: num_a = integer(x); if (num_a == 0) { bool return_nan = false, return_real_zero = false; for (; is_pair(p); p = cdr(p)) { s7_pointer n; n = car(p); if (!s7_is_number(n)) { n = check_values(sc, n, p); if (!s7_is_number(n)) return(wrong_type_argument_with_type(sc, sc->DIVIDE, position_of(p, args), n, A_NUMBER)); } if (s7_is_zero(n)) return(division_by_zero_error(sc, sc->DIVIDE, args)); if (type(n) > T_RATIO) { return_real_zero = true; if (is_NaN(s7_real_part(n))) return_nan = true; } } if (return_nan) return(real_NaN); if (return_real_zero) return(real_zero); return(small_int(0)); } DIVIDE_INTEGERS: #if WITH_GMP if ((num_a > s7_int32_max) || (num_a < s7_int32_min)) return(big_divide(sc, cons(sc, s7_int_to_big_integer(sc, num_a), p))); #endif x = car(p); p = cdr(p); switch (type(x)) { case T_INTEGER: if (integer(x) == 0) return(division_by_zero_error(sc, sc->DIVIDE, args)); /* to be consistent, I suppose we should search first for NaNs in the divisor list. * (* 0 0/0) is NaN, so (/ 1 0 0/0) should equal (/ 1 0/0) = NaN. But the whole * thing is ridiculous. */ if (is_null(p)) return(s7_make_ratio(sc, num_a, integer(x))); den_a = integer(x); if (reduce_fraction(sc, &num_a, &den_a) == T_INTEGER) goto DIVIDE_INTEGERS; goto DIVIDE_RATIOS; case T_RATIO: den_a = denominator(x); #if HAVE_OVERFLOW_CHECKS { s7_int dn; if (multiply_overflow(num_a, den_a, &dn)) { if (is_null(p)) return(make_real(sc, num_a * inverted_fraction(x))); rl_a = (s7_double)num_a * inverted_fraction(x); goto DIVIDE_REALS; } num_a = dn; } #else if ((integer_length(num_a) + integer_length(den_a)) > s7_int_bits) { if (is_null(p)) return(make_real(sc, num_a * inverted_fraction(x))); rl_a = (s7_double)num_a * inverted_fraction(x); goto DIVIDE_REALS; } num_a *= den_a; #endif den_a = numerator(x); if (is_null(p)) return(s7_make_ratio(sc, num_a, den_a)); if (reduce_fraction(sc, &num_a, &den_a) == T_INTEGER) goto DIVIDE_INTEGERS; goto DIVIDE_RATIOS; case T_REAL: rl_a = (s7_double)num_a; if (real(x) == 0.0) return(division_by_zero_error(sc, sc->DIVIDE, args)); if (is_null(p)) return(make_real(sc, rl_a / real(x))); rl_a /= real(x); goto DIVIDE_REALS; case T_COMPLEX: { s7_double i2, r2, den; rl_a = (s7_double)num_a; r2 = real_part(x); i2 = imag_part(x); den = 1.0 / (r2 * r2 + i2 * i2); /* we could avoid the squaring (see Knuth II p613 16) * not a big deal: (/ 1.0e308+1.0e308i 2.0e308+2.0e308i) => nan * (gmp case is ok here) */ if (is_null(p)) return(s7_make_complex(sc, rl_a * r2 * den, -(rl_a * i2 * den))); im_a = -rl_a * i2 * den; rl_a *= r2 * den; goto DIVIDE_COMPLEX; } default: method_or_bust_with_type(sc, x, sc->DIVIDE, cons(sc, s7_make_integer(sc, num_a), cons(sc, x, p)), A_NUMBER, position_of(p, args) - 1); } break; case T_RATIO: num_a = numerator(x); den_a = denominator(x); DIVIDE_RATIOS: #if WITH_GMP if ((num_a > s7_int32_max) || (den_a > s7_int32_max) || (num_a < s7_int32_min)) return(big_divide(sc, cons(sc, s7_ratio_to_big_ratio(sc, num_a, den_a), p))); #endif x = car(p); p = cdr(p); switch (type(x)) { case T_INTEGER: if (integer(x) == 0) return(division_by_zero_error(sc, sc->DIVIDE, args)); #if HAVE_OVERFLOW_CHECKS { s7_int dn; if (multiply_overflow(den_a, integer(x), &dn)) { if (is_null(p)) return(make_real(sc, (long double)num_a / ((long double)den_a * (s7_double)integer(x)))); rl_a = (long double)num_a / ((long double)den_a * (s7_double)integer(x)); goto DIVIDE_REALS; } den_a = dn; } #else if ((integer_length(integer(x)) + integer_length(den_a)) > s7_int_bits) { if (is_null(p)) return(make_real(sc, (long double)num_a / ((long double)den_a * (s7_double)integer(x)))); rl_a = (long double)num_a / ((long double)den_a * (s7_double)integer(x)); goto DIVIDE_REALS; } den_a *= integer(x); #endif if (is_null(p)) return(s7_make_ratio(sc, num_a, den_a)); if (reduce_fraction(sc, &num_a, &den_a) == T_INTEGER) goto DIVIDE_INTEGERS; goto DIVIDE_RATIOS; case T_RATIO: { s7_int d1, d2, n1, n2; d1 = den_a; n1 = num_a; d2 = denominator(x); n2 = numerator(x); if (d1 == d2) { if (is_null(p)) return(s7_make_ratio(sc, n1, n2)); den_a = n2; } else { #if (!WITH_GMP) #if HAVE_OVERFLOW_CHECKS if ((multiply_overflow(n1, d2, &n1)) || (multiply_overflow(n2, d1, &d1))) { s7_double r1, r2; r1 = ((long double)num_a / (long double)den_a); r2 = inverted_fraction(x); if (is_null(p)) return(make_real(sc, r1 * r2)); rl_a = r1 * r2; goto DIVIDE_REALS; } num_a = n1; den_a = d1; #else if ((d1 > s7_int32_max) || (d2 > s7_int32_max) || /* before counting bits, check that overflow is possible */ (n1 > s7_int32_max) || (n2 > s7_int32_max) || (n1 < s7_int32_min) || (n2 < s7_int32_min)) { if ((integer_length(d1) + integer_length(n2) > s7_int_bits) || (integer_length(d2) + integer_length(n1) > s7_int_bits)) { s7_double r1, r2; r1 = ((long double)num_a / (long double)den_a); r2 = inverted_fraction(x); if (is_null(p)) return(make_real(sc, r1 * r2)); rl_a = r1 * r2; goto DIVIDE_REALS; } } num_a *= d2; den_a *= n2; #endif #else num_a *= d2; den_a *= n2; #endif if (is_null(p)) return(s7_make_ratio(sc, num_a, den_a)); } if (reduce_fraction(sc, &num_a, &den_a) == T_INTEGER) goto DIVIDE_INTEGERS; goto DIVIDE_RATIOS; } case T_REAL: { s7_double r1; if (real(x) == 0.0) return(division_by_zero_error(sc, sc->DIVIDE, args)); r1 = ((long double)num_a / (long double)den_a); if (is_null(p)) return(make_real(sc, r1 / real(x))); rl_a = r1 / real(x); goto DIVIDE_REALS; } case T_COMPLEX: { s7_double den, i2, r2; rl_a = ((long double)num_a / (long double)den_a); r2 = real_part(x); i2 = imag_part(x); den = 1.0 / (r2 * r2 + i2 * i2); if (is_null(p)) return(s7_make_complex(sc, rl_a * r2 * den, -rl_a * i2 * den)); im_a = -rl_a * i2 * den; rl_a *= r2 * den; goto DIVIDE_COMPLEX; } default: method_or_bust_with_type(sc, x, sc->DIVIDE, cons(sc, s7_make_ratio(sc, num_a, den_a), cons(sc, x, p)), A_NUMBER, position_of(p, args) - 1); } break; case T_REAL: rl_a = real(x); if (rl_a == 0) { bool return_nan = false; for (; is_pair(p); p = cdr(p)) { s7_pointer n; n = car(p); if (!s7_is_number(n)) { n = check_values(sc, n, p); if (!s7_is_number(n)) return(wrong_type_argument_with_type(sc, sc->DIVIDE, position_of(p, args), n, A_NUMBER)); } if (s7_is_zero(n)) return(division_by_zero_error(sc, sc->DIVIDE, args)); if ((is_t_real(n)) && (is_NaN(real(n)))) return_nan = true; } if (return_nan) return(real_NaN); return(real_zero); } DIVIDE_REALS: x = car(p); p = cdr(p); switch (type(x)) { case T_INTEGER: if (integer(x) == 0) return(division_by_zero_error(sc, sc->DIVIDE, args)); if (is_null(p)) return(make_real(sc, rl_a / integer(x))); rl_a /= (s7_double)integer(x); goto DIVIDE_REALS; case T_RATIO: if (is_null(p)) return(make_real(sc, rl_a * inverted_fraction(x))); rl_a *= (s7_double)inverted_fraction(x); goto DIVIDE_REALS; case T_REAL: if (real(x) == 0.0) return(division_by_zero_error(sc, sc->DIVIDE, args)); if (is_null(p)) return(make_real(sc, rl_a / real(x))); rl_a /= real(x); goto DIVIDE_REALS; case T_COMPLEX: { s7_double den, r2, i2; r2 = real_part(x); i2 = imag_part(x); den = 1.0 / (r2 * r2 + i2 * i2); if (is_null(p)) return(s7_make_complex(sc, rl_a * r2 * den, -rl_a * i2 * den)); im_a = -rl_a * i2 * den; rl_a *= r2 * den; goto DIVIDE_COMPLEX; } default: method_or_bust_with_type(sc, x, sc->DIVIDE, cons(sc, make_real(sc, rl_a), cons(sc, x, p)), A_NUMBER, position_of(p, args) - 1); } break; case T_COMPLEX: rl_a = real_part(x); im_a = imag_part(x); DIVIDE_COMPLEX: x = car(p); p = cdr(p); switch (type(x)) { case T_INTEGER: { s7_double r1; if (integer(x) == 0) return(division_by_zero_error(sc, sc->DIVIDE, args)); r1 = 1.0 / (s7_double)integer(x); if (is_null(p)) return(s7_make_complex(sc, rl_a * r1, im_a * r1)); rl_a *= r1; im_a *= r1; goto DIVIDE_COMPLEX; } case T_RATIO: { s7_double frac; frac = inverted_fraction(x); if (is_null(p)) return(s7_make_complex(sc, rl_a * frac, im_a * frac)); rl_a *= frac; im_a *= frac; goto DIVIDE_COMPLEX; } case T_REAL: { s7_double r1; if (real(x) == 0.0) return(division_by_zero_error(sc, sc->DIVIDE, args)); r1 = 1.0 / real(x); if (is_null(p)) return(s7_make_complex(sc, rl_a * r1, im_a * r1)); rl_a *= r1; im_a *= r1; goto DIVIDE_COMPLEX; } case T_COMPLEX: { s7_double r1, r2, i1, i2, den; r1 = rl_a; i1 = im_a; r2 = real_part(x); i2 = imag_part(x); den = 1.0 / (r2 * r2 + i2 * i2); if (is_null(p)) return(s7_make_complex(sc, (r1 * r2 + i1 * i2) * den, (r2 * i1 - r1 * i2) * den)); rl_a = (r1 * r2 + i1 * i2) * den; im_a = (r2 * i1 - r1 * i2) * den; goto DIVIDE_COMPLEX; } default: method_or_bust_with_type(sc, x, sc->DIVIDE, cons(sc, s7_make_complex(sc, rl_a, im_a), cons(sc, x, p)), A_NUMBER, position_of(p, args) - 1); } break; default: method_or_bust_with_type(sc, x, sc->DIVIDE, args, A_NUMBER, 1); } } #if (!WITH_GMP) static s7_pointer invert_1; static s7_pointer g_invert_1(s7_scheme *sc, s7_pointer args) { s7_pointer p; p = car(args); switch (type(p)) { case T_INTEGER: if (integer(p) != 0) return(s7_make_ratio(sc, 1, integer(p))); /* a already checked, not 0 */ return(division_by_zero_error(sc, sc->DIVIDE, args)); case T_RATIO: return(s7_make_ratio(sc, denominator(p), numerator(p))); case T_REAL: if (real(p) != 0.0) return(make_real(sc, 1.0 / real(p))); return(division_by_zero_error(sc, sc->DIVIDE, args)); case T_COMPLEX: { s7_double r2, i2, den; r2 = real_part(p); i2 = imag_part(p); den = (r2 * r2 + i2 * i2); return(s7_make_complex(sc, r2 / den, -i2 / den)); } default: method_or_bust_with_type(sc, p, sc->DIVIDE, args, A_NUMBER, 1); } } static s7_pointer divide_1r; static s7_pointer g_divide_1r(s7_scheme *sc, s7_pointer args) { if (s7_is_real(cadr(args))) { s7_double rl; rl = real_to_double(sc, cadr(args), "/"); if (rl == 0.0) return(division_by_zero_error(sc, sc->DIVIDE, args)); return(make_real(sc, 1.0 / rl)); } return(g_divide(sc, args)); } static s7_double c_dbl_invert(s7_scheme *sc, s7_double x) { if (x == 0.0) division_by_zero_error(sc, sc->DIVIDE, set_elist_1(sc, real_zero)); return(1.0 / x); } static s7_double c_dbl_divide_2(s7_scheme *sc, s7_double x, s7_double y) { if (y == 0.0) division_by_zero_error(sc, sc->DIVIDE, set_elist_2(sc, make_real(sc, x), real_zero)); return(x / y); } static s7_double c_dbl_divide_3(s7_scheme *sc, s7_double x, s7_double y, s7_double z) { s7_double d; d = y * z; if (d == 0.0) division_by_zero_error(sc, sc->DIVIDE, set_elist_3(sc, make_real(sc, x), make_real(sc, y), make_real(sc, z))); return(x / d); } RF_3_TO_RF(divide, c_dbl_invert, c_dbl_divide_2, c_dbl_divide_3) #endif /* ---------------------------------------- max/min ---------------------------------------- */ static bool is_real_via_method_1(s7_scheme *sc, s7_pointer p) { s7_pointer f; f = find_method(sc, find_let(sc, p), sc->IS_REAL); if (f != sc->UNDEFINED) return(is_true(sc, s7_apply_function(sc, f, cons(sc, p, sc->NIL)))); return(false); } #define is_real_via_method(sc, p) ((s7_is_real(p)) || ((has_methods(p)) && (is_real_via_method_1(sc, p)))) static s7_pointer g_max(s7_scheme *sc, s7_pointer args) { #define H_max "(max ...) returns the maximum of its arguments" #define Q_max pcl_r s7_pointer x, y, p; s7_int num_a, num_b, den_a, den_b; x = car(args); p = cdr(args); switch (type(x)) { case T_INTEGER: MAX_INTEGERS: if (is_null(p)) return(x); y = car(p); p = cdr(p); switch (type(y)) { case T_INTEGER: if (integer(x) < integer(y)) x = y; goto MAX_INTEGERS; case T_RATIO: num_a = integer(x); den_a = 1; num_b = numerator(y); den_b = denominator(y); goto RATIO_MAX_RATIO; case T_REAL: if (is_NaN(real(y))) { for (; is_not_null(p); p = cdr(p)) if (!is_real_via_method(sc, car(p))) return(wrong_type_argument(sc, sc->MAX, position_of(p, args), car(p), T_REAL)); return(y); } if (integer(x) < real(y)) { x = y; goto MAX_REALS; } goto MAX_INTEGERS; default: method_or_bust(sc, y, sc->MAX, cons(sc, x, cons(sc, y, p)), T_REAL, position_of(p, args) - 1); } case T_RATIO: MAX_RATIOS: if (is_null(p)) return(x); y = car(p); p = cdr(p); switch (type(y)) { case T_INTEGER: num_a = numerator(x); den_a = denominator(x); num_b = integer(y); den_b = 1; goto RATIO_MAX_RATIO; case T_RATIO: num_a = numerator(x); den_a = denominator(x); num_b = numerator(y); den_b = denominator(y); RATIO_MAX_RATIO: /* there are tricky cases here where long ints outrun doubles: * (max 92233720368547758/9223372036854775807 92233720368547757/9223372036854775807) * which should be 92233720368547758/9223372036854775807) but first the fraction gets reduced * to 13176245766935394/1317624576693539401, so we fall into the double comparison, and * there we should be comparing * 9.999999999999999992410584792601468961145E-3 and * 9.999999999999999883990367544051025548645E-3 * but if using doubles we get * 0.010000000000000000208166817117 and * 0.010000000000000000208166817117 * that is, we can't distinguish these two fractions once they're coerced to doubles. * * Even long doubles fail in innocuous-looking cases: * (min 21053343141/6701487259 3587785776203/1142027682075) -> 3587785776203/1142027682075 * (max 21053343141/6701487259 3587785776203/1142027682075) -> 3587785776203/1142027682075 * * Another consequence: outside gmp, we can't handle cases like * (max 9223372036854776/9223372036854775807 #i9223372036854775/9223372036854775000) * (max #i9223372036854776/9223372036854775807 9223372036854775/9223372036854775000) * I guess if the user is using "inexact" numbers (#i...), he accepts their inexactness. */ if (den_a == den_b) { if (num_a < num_b) x = y; } else { if (num_a == num_b) { if (((num_a >= 0) && (den_a > den_b)) || ((num_a < 0) && (den_a < den_b))) x = y; } else { s7_int vala, valb; vala = num_a / den_a; valb = num_b / den_b; if (!((vala > valb) || ((vala == valb) && (is_t_integer(y))))) { if ((valb > vala) || ((vala == valb) && (is_t_integer(x))) || /* sigh -- both are ratios and the int parts are equal */ (((long double)(num_a % den_a) / (long double)den_a) <= ((long double)(num_b % den_b) / (long double)den_b))) x = y; } } } if (is_t_ratio(x)) goto MAX_RATIOS; goto MAX_INTEGERS; case T_REAL: /* (max 3/4 nan.0) should probably return NaN */ if (is_NaN(real(y))) { for (; is_not_null(p); p = cdr(p)) if (!is_real_via_method(sc, car(p))) return(wrong_type_argument(sc, sc->MAX, position_of(p, args), car(p), T_REAL)); return(y); } if (fraction(x) < real(y)) { x = y; goto MAX_REALS; } goto MAX_RATIOS; default: method_or_bust(sc, y, sc->MAX, cons(sc, x, cons(sc, y, p)), T_REAL, position_of(p, args) - 1); } case T_REAL: if (is_NaN(real(x))) { for (; is_not_null(p); p = cdr(p)) if (!is_real_via_method(sc, car(p))) return(wrong_type_argument(sc, sc->MAX, position_of(p, args), car(p), T_REAL)); return(x); } MAX_REALS: if (is_null(p)) return(x); y = car(p); p = cdr(p); switch (type(y)) { case T_INTEGER: if (real(x) < integer(y)) { x = y; goto MAX_INTEGERS; } goto MAX_REALS; case T_RATIO: if (real(x) < fraction(y)) { x = y; goto MAX_RATIOS; } goto MAX_REALS; case T_REAL: if (is_NaN(real(y))) { for (; is_not_null(p); p = cdr(p)) if (!is_real_via_method(sc, car(p))) return(wrong_type_argument(sc, sc->MAX, position_of(p, args), car(p), T_REAL)); return(y); } if (real(x) < real(y)) x = y; goto MAX_REALS; default: method_or_bust(sc, y, sc->MAX, cons(sc, x, cons(sc, y, p)), T_REAL, position_of(p, args) - 1); } default: method_or_bust(sc, x, sc->MAX, cons(sc, x, p), T_REAL, 1); } } #if (!WITH_GMP) static s7_pointer max_f2; static s7_pointer g_max_f2(s7_scheme *sc, s7_pointer args) { s7_pointer x, y; x = car(args); y = cadr(args); if (is_t_real(y)) return((real(x) >= real(y)) ? x : y); if (is_real(y)) return((real(x) >= real_to_double(sc, y, "max")) ? x : y); method_or_bust(sc, y, sc->MAX, args, T_REAL, 2); } #endif static s7_pointer g_min(s7_scheme *sc, s7_pointer args) { #define H_min "(min ...) returns the minimum of its arguments" #define Q_min pcl_r s7_pointer x, y, p; s7_int num_a, num_b, den_a, den_b; x = car(args); p = cdr(args); switch (type(x)) { case T_INTEGER: MIN_INTEGERS: if (is_null(p)) return(x); y = car(p); p = cdr(p); switch (type(y)) { case T_INTEGER: if (integer(x) > integer(y)) x = y; goto MIN_INTEGERS; case T_RATIO: num_a = integer(x); den_a = 1; num_b = numerator(y); den_b = denominator(y); goto RATIO_MIN_RATIO; case T_REAL: if (is_NaN(real(y))) { for (; is_not_null(p); p = cdr(p)) if (!is_real_via_method(sc, car(p))) return(wrong_type_argument(sc, sc->MIN, position_of(p, args), car(p), T_REAL)); return(y); } if (integer(x) > real(y)) { x = y; goto MIN_REALS; } goto MIN_INTEGERS; default: method_or_bust(sc, y, sc->MIN, cons(sc, x, cons(sc, y, p)), T_REAL, position_of(p, args) - 1); } case T_RATIO: MIN_RATIOS: if (is_null(p)) return(x); y = car(p); p = cdr(p); switch (type(y)) { case T_INTEGER: num_a = numerator(x); den_a = denominator(x); num_b = integer(y); den_b = 1; goto RATIO_MIN_RATIO; case T_RATIO: num_a = numerator(x); den_a = denominator(x); num_b = numerator(y); den_b = denominator(y); RATIO_MIN_RATIO: if (den_a == den_b) { if (num_a > num_b) x = y; } else { if (num_a == num_b) { if (((num_a >= 0) && (den_a < den_b)) || ((num_a < 0) && (den_a > den_b))) x = y; } else { s7_int vala, valb; vala = num_a / den_a; valb = num_b / den_b; if (!((vala < valb) || ((vala == valb) && (is_t_integer(x))))) { if ((valb < vala) || ((vala == valb) && (is_t_integer(y))) || (((long double)(num_a % den_a) / (long double)den_a) >= ((long double)(num_b % den_b) / (long double)den_b))) x = y; } } } if (is_t_ratio(x)) goto MIN_RATIOS; goto MIN_INTEGERS; case T_REAL: /* (min 3/4 nan.0) should probably return NaN */ if (is_NaN(real(y))) { for (; is_not_null(p); p = cdr(p)) if (!is_real_via_method(sc, car(p))) return(wrong_type_argument(sc, sc->MIN, position_of(p, args), car(p), T_REAL)); return(y); } if (fraction(x) > real(y)) { x = y; goto MIN_REALS; } goto MIN_RATIOS; default: method_or_bust(sc, y, sc->MIN, cons(sc, x, cons(sc, y, p)), T_REAL, position_of(p, args) - 1); } case T_REAL: if (is_NaN(real(x))) { for (; is_not_null(p); p = cdr(p)) if (!is_real_via_method(sc, car(p))) return(wrong_type_argument(sc, sc->MIN, position_of(p, args), car(p), T_REAL)); return(x); } MIN_REALS: if (is_null(p)) return(x); y = car(p); p = cdr(p); switch (type(y)) { case T_INTEGER: if (real(x) > integer(y)) { x = y; goto MIN_INTEGERS; } goto MIN_REALS; case T_RATIO: if (real(x) > fraction(y)) { x = y; goto MIN_RATIOS; } goto MIN_REALS; case T_REAL: if (is_NaN(real(y))) { for (; is_not_null(p); p = cdr(p)) if (!is_real_via_method(sc, car(p))) return(wrong_type_argument(sc, sc->MIN, position_of(p, args), car(p), T_REAL)); return(y); } if (real(x) > real(y)) x = y; goto MIN_REALS; default: method_or_bust(sc, y, sc->MIN, cons(sc, x, cons(sc, y, p)), T_REAL, position_of(p, args) - 1); } default: method_or_bust(sc, x, sc->MIN, cons(sc, x, p), T_REAL, 1); } } #if (!WITH_GMP) static s7_pointer min_f2; static s7_pointer g_min_f2(s7_scheme *sc, s7_pointer args) { s7_pointer x, y; x = car(args); y = cadr(args); if (is_t_real(y)) return((real(x) <= real(y)) ? x : y); if (is_real(y)) return((real(x) <= real_to_double(sc, y, "min")) ? x : y); method_or_bust(sc, y, sc->MIN, args, T_REAL, 2); } static s7_int c_max_i1(s7_scheme *sc, s7_int x) {return(x);} static s7_int c_max_i2(s7_scheme *sc, s7_int x, s7_int y) {return((x >= y) ? x : y);} static s7_int c_max_i3(s7_scheme *sc, s7_int x, s7_int y, s7_int z) {return(((x >= y) ? ((x >= z) ? x : z) : ((y >= z) ? y : z)));} IF_3_TO_IF(max, c_max_i1, c_max_i2, c_max_i3) static s7_int c_min_i1(s7_scheme *sc, s7_int x) {return(x);} static s7_int c_min_i2(s7_scheme *sc, s7_int x, s7_int y) {return((x <= y) ? x : y);} static s7_int c_min_i3(s7_scheme *sc, s7_int x, s7_int y, s7_int z) {return(((x <= y) ? ((x <= z) ? x : z) : ((y <= z) ? y : z)));} IF_3_TO_IF(min, c_min_i1, c_min_i2, c_min_i3) static s7_double c_max_r1(s7_scheme *sc, s7_double x) {return(x);} static s7_double c_max_r2(s7_scheme *sc, s7_double x, s7_double y) {return((x >= y) ? x : y);} static s7_double c_max_r3(s7_scheme *sc, s7_double x, s7_double y, s7_double z) {return(((x >= y) ? ((x >= z) ? x : z) : ((y >= z) ? y : z)));} RF_3_TO_RF(max, c_max_r1, c_max_r2, c_max_r3) static s7_double c_min_r1(s7_scheme *sc, s7_double x) {return(x);} static s7_double c_min_r2(s7_scheme *sc, s7_double x, s7_double y) {return((x <= y) ? x : y);} static s7_double c_min_r3(s7_scheme *sc, s7_double x, s7_double y, s7_double z) {return(((x <= y) ? ((x <= z) ? x : z) : ((y <= z) ? y : z)));} RF_3_TO_RF(min, c_min_r1, c_min_r2, c_min_r3) #endif /* ---------------------------------------- = > < >= <= ---------------------------------------- */ static s7_pointer g_equal(s7_scheme *sc, s7_pointer args) { #define H_equal "(= z1 ...) returns #t if all its arguments are equal" #define Q_equal s7_make_circular_signature(sc, 1, 2, sc->IS_BOOLEAN, sc->IS_NUMBER) s7_pointer x, p; s7_int num_a, den_a; s7_double rl_a, im_a; x = car(args); p = cdr(args); switch (type(x)) { case T_INTEGER: num_a = integer(x); while (true) { x = car(p); p = cdr(p); switch (type(x)) { case T_INTEGER: if (num_a != integer(x)) goto NOT_EQUAL; break; case T_RATIO: case T_COMPLEX: goto NOT_EQUAL; case T_REAL: if (num_a != real(x)) goto NOT_EQUAL; break; default: method_or_bust_with_type(sc, x, sc->EQ, cons(sc, make_integer(sc, num_a), cons(sc, x, p)), A_NUMBER, position_of(p, args) - 1); } if (is_null(p)) return(sc->T); } case T_RATIO: num_a = numerator(x); den_a = denominator(x); rl_a = 0.0; while (true) { x = car(p); p = cdr(p); switch (type(x)) { case T_INTEGER: case T_COMPLEX: goto NOT_EQUAL; case T_RATIO: if ((num_a != numerator(x)) || (den_a != denominator(x))) goto NOT_EQUAL; /* hidden cast here */ break; case T_REAL: if (rl_a == 0.0) rl_a = ((long double)num_a) / ((long double)den_a); if (rl_a != real(x)) goto NOT_EQUAL; break; default: method_or_bust_with_type(sc, x, sc->EQ, cons(sc, s7_make_ratio(sc, num_a, den_a), cons(sc, x, p)), A_NUMBER, position_of(p, args) - 1); } if (is_null(p)) return(sc->T); } case T_REAL: rl_a = real(x); while (true) { x = car(p); p = cdr(p); switch (type(x)) { case T_INTEGER: if (rl_a != integer(x)) goto NOT_EQUAL; break; case T_RATIO: if (rl_a != (double)fraction(x)) goto NOT_EQUAL; /* the cast to double is needed because rl_a is s7_double and we want (= ratio real) to be the same as (= real ratio): * (= 1.0 9223372036854775807/9223372036854775806) * (= 9223372036854775807/9223372036854775806 1.0) */ break; case T_REAL: if (rl_a != real(x)) goto NOT_EQUAL; break; case T_COMPLEX: goto NOT_EQUAL; default: method_or_bust_with_type(sc, x, sc->EQ, cons(sc, make_real(sc, rl_a), cons(sc, x, p)), A_NUMBER, position_of(p, args) - 1); } if (is_null(p)) return(sc->T); } case T_COMPLEX: rl_a = real_part(x); im_a = imag_part(x); while (true) { x = car(p); p = cdr(p); switch (type(x)) { case T_INTEGER: case T_RATIO: case T_REAL: goto NOT_EQUAL; break; case T_COMPLEX: if ((rl_a != real_part(x)) || (im_a != imag_part(x))) goto NOT_EQUAL; break; default: method_or_bust_with_type(sc, x, sc->EQ, cons(sc, s7_make_complex(sc, rl_a, im_a), cons(sc, x, p)), A_NUMBER, position_of(p, args) - 1); } if (is_null(p)) return(sc->T); } default: method_or_bust_with_type(sc, x, sc->EQ, args, A_NUMBER, 1); } NOT_EQUAL: for (; is_pair(p); p = cdr(p)) if (!is_number_via_method(sc, car(p))) return(wrong_type_argument_with_type(sc, sc->EQ, position_of(p, args), car(p), A_NUMBER)); return(sc->F); } static s7_pointer equal_s_ic, equal_2; static s7_pointer g_equal_s_ic(s7_scheme *sc, s7_pointer args) { s7_int y; s7_pointer val; val = find_symbol_checked(sc, car(args)); y = s7_integer(cadr(args)); if (is_integer(val)) return(make_boolean(sc, integer(val) == y)); switch (type(val)) { case T_INTEGER: return(make_boolean(sc, integer(val) == y)); case T_RATIO: return(sc->F); case T_REAL: return(make_boolean(sc, real(val) == y)); case T_COMPLEX: return(sc->F); default: method_or_bust_with_type(sc, val, sc->EQ, list_2(sc, val, cadr(args)), A_NUMBER, 1); } return(sc->T); } static s7_int object_length_to_int(s7_scheme *sc, s7_pointer obj); #if (!WITH_GMP) static s7_pointer equal_length_ic; static s7_pointer g_equal_length_ic(s7_scheme *sc, s7_pointer args) { /* avoid make_integer (and telescope opts), we get here with car=length expr, cadr=int */ s7_int ilen; s7_pointer val; val = find_symbol_checked(sc, cadar(args)); ilen = s7_integer(cadr(args)); switch (type(val)) { case T_PAIR: return(make_boolean(sc, s7_list_length(sc, val) == ilen)); case T_NIL: return(make_boolean(sc, ilen == 0)); case T_STRING: return(make_boolean(sc, string_length(val) == ilen)); case T_HASH_TABLE: return(make_boolean(sc, (hash_table_mask(val) + 1) == ilen)); case T_ITERATOR: return(make_boolean(sc, iterator_length(val) == ilen)); case T_C_OBJECT: return(make_boolean(sc, object_length_to_int(sc, val) == ilen)); case T_LET: return(make_boolean(sc, let_length(sc, val) == ilen)); case T_INT_VECTOR: case T_FLOAT_VECTOR: case T_VECTOR: return(make_boolean(sc, vector_length(val) == ilen)); case T_CLOSURE: case T_CLOSURE_STAR: if (has_methods(val)) return(make_boolean(sc, closure_length(sc, val) == ilen)); default: return(simple_wrong_type_argument_with_type(sc, sc->LENGTH, val, A_SEQUENCE)); /* here we already lost because we checked for the length above */ } return(sc->F); } #endif static s7_pointer c_equal_2_1(s7_scheme *sc, s7_pointer x, s7_pointer y) { switch (type(x)) { case T_INTEGER: switch (type(y)) { case T_INTEGER: return(make_boolean(sc, integer(x) == integer(y))); case T_RATIO: return(sc->F); case T_REAL: return(make_boolean(sc, integer(x) == real(y))); case T_COMPLEX: return(sc->F); default: method_or_bust_with_type(sc, y, sc->EQ, list_2(sc, x, y), A_NUMBER, 2); } break; case T_RATIO: switch (type(y)) { case T_INTEGER: return(sc->F); case T_RATIO: return(make_boolean(sc, (numerator(x) == numerator(y)) && (denominator(x) == denominator(y)))); case T_REAL: return(make_boolean(sc, fraction(x) == real(y))); /* this could avoid the divide via numerator == denominator * x */ case T_COMPLEX: return(sc->F); default: method_or_bust_with_type(sc, y, sc->EQ, list_2(sc, x, y), A_NUMBER, 2); } break; case T_REAL: switch (type(y)) { case T_INTEGER: return(make_boolean(sc, real(x) == integer(y))); case T_RATIO: return(make_boolean(sc, real(x) == fraction(y))); case T_REAL: return(make_boolean(sc, real(x) == real(y))); case T_COMPLEX: return(sc->F); default: method_or_bust_with_type(sc, y, sc->EQ, list_2(sc, x, y), A_NUMBER, 2); } break; case T_COMPLEX: switch (type(y)) { case T_INTEGER: case T_RATIO: case T_REAL: return(sc->F); #if (!MS_WINDOWS) case T_COMPLEX: return(make_boolean(sc, (real_part(x) == real_part(y)) && (imag_part(x) == imag_part(y)))); #else case T_COMPLEX: if ((real_part(x) == real_part(y)) && (imag_part(x) == imag_part(y))) return(sc->T); else return(sc->F); #endif default: method_or_bust_with_type(sc, y, sc->EQ, list_2(sc, x, y), A_NUMBER, 2); } break; default: method_or_bust_with_type(sc, x, sc->EQ, list_2(sc, x, y), A_NUMBER, 1); } return(sc->F); } static s7_pointer c_equal_2(s7_scheme *sc, s7_pointer x, s7_pointer y) { #if (!MS_WINDOWS) if (type(x) == type(y)) { if (is_integer(x)) return(make_boolean(sc, integer(x) == integer(y))); switch (type(x)) { case T_INTEGER: return(make_boolean(sc, integer(x) == integer(y))); case T_RATIO: return(make_boolean(sc, (numerator(x) == numerator(y)) && (denominator(x) == denominator(y)))); case T_REAL: return(make_boolean(sc, real(x) == real(y))); case T_COMPLEX: return(make_boolean(sc, (real_part(x) == real_part(y)) && (imag_part(x) == imag_part(y)))); } } #endif return(c_equal_2_1(sc, x, y)); } static s7_pointer g_equal_2(s7_scheme *sc, s7_pointer args) { s7_pointer x, y; x = car(args); y = cadr(args); #if (!MS_WINDOWS) if (type(x) == type(y)) { if (is_integer(x)) return(make_boolean(sc, integer(x) == integer(y))); switch (type(x)) { case T_INTEGER: return(make_boolean(sc, integer(x) == integer(y))); case T_RATIO: return(make_boolean(sc, (numerator(x) == numerator(y)) && (denominator(x) == denominator(y)))); case T_REAL: return(make_boolean(sc, real(x) == real(y))); case T_COMPLEX: return(make_boolean(sc, (real_part(x) == real_part(y)) && (imag_part(x) == imag_part(y)))); } } #endif return(c_equal_2_1(sc, x, y)); } #if (!WITH_GMP) static s7_pointer equal_i2(s7_scheme *sc, s7_pointer **p) { s7_if_t f; s7_int x, y; f = (s7_if_t)(**p); (*p)++; x = f(sc, p); f = (s7_if_t)(**p); (*p)++; y = f(sc, p); return(make_boolean(sc, x == y)); } static s7_pointer equal_i2_ic(s7_scheme *sc, s7_pointer **p) { s7_pointer x, y; (*p)++; x = slot_value(**p); (*p) += 2; y = (**p); (*p)++; if (!is_integer(x)) return(c_equal_2_1(sc, x, y)); return(make_boolean(sc, integer(x) == integer(y))); } static s7_pointer equal_i2_ii(s7_scheme *sc, s7_pointer **p) { s7_pointer x, y; (*p)++; x = slot_value(**p); (*p) += 2; y = slot_value(**p); (*p)++; if (!is_integer(x)) return(c_equal_2_1(sc, x, y)); return(make_boolean(sc, integer(x) == integer(y))); } static s7_pointer equal_r2(s7_scheme *sc, s7_pointer **p) { s7_rf_t f; s7_double x, y; f = (s7_rf_t)(**p); (*p)++; x = f(sc, p); f = (s7_rf_t)(**p); (*p)++; y = f(sc, p); return(make_boolean(sc, x == y)); } static s7_pointer equal_p2(s7_scheme *sc, s7_pointer **p) { s7_pf_t f; s7_pointer x, y; f = (s7_pf_t)(**p); (*p)++; x = f(sc, p); f = (s7_pf_t)(**p); (*p)++; y = f(sc, p); return(c_equal_2(sc, x, y)); } static s7_pf_t equal_pf(s7_scheme *sc, s7_pointer expr) { if ((is_pair(cdr(expr))) && (is_pair(cddr(expr))) && (is_null(cdddr(expr)))) { ptr_int loc; s7_pointer a1, a2; a1 = cadr(expr); a2 = caddr(expr); loc = rc_loc(sc); if ((s7_arg_to_if(sc, cadr(expr))) && (s7_arg_to_if(sc, caddr(expr)))) { if (is_symbol(a1)) { if (is_integer(a2)) return(equal_i2_ic); if (is_symbol(a2)) return(equal_i2_ii); } return(equal_i2); } sc->cur_rf->cur = rc_go(sc, loc); if ((s7_arg_to_rf(sc, cadr(expr))) && (s7_arg_to_rf(sc, caddr(expr)))) return(equal_r2); sc->cur_rf->cur = rc_go(sc, loc); if ((s7_arg_to_pf(sc, cadr(expr))) && (s7_arg_to_pf(sc, caddr(expr)))) return(equal_p2); } return(NULL); } static s7_pointer g_less(s7_scheme *sc, s7_pointer args) { #define H_less "(< x1 ...) returns #t if its arguments are in increasing order" #define Q_less s7_make_circular_signature(sc, 1, 2, sc->IS_BOOLEAN, sc->IS_REAL) s7_pointer x, y, p; x = car(args); p = cdr(args); switch (type(x)) { case T_INTEGER: INTEGER_LESS: y = car(p); p = cdr(p); switch (type(y)) { case T_INTEGER: if (integer(x) >= integer(y)) goto NOT_LESS; if (is_null(p)) return(sc->T); x = y; goto INTEGER_LESS; case T_RATIO: /* no gmp here, but this can overflow: (< 9223372036 1/9223372036), but conversion to real is also problematic */ if ((integer(x) >= 0) && (numerator(y) < 0)) goto NOT_LESS; /* (< 1 -1/2), ratio numerator can't be 0 */ if ((integer(x) <= 0) && (numerator(y) > 0)) /* (< 0 1/2) */ { if (is_null(p)) return(sc->T); x = y; goto RATIO_LESS; } if ((integer(x) < s7_int32_max) && (integer(x) > s7_int32_min) && (denominator(y) < s7_int32_max)) { if ((integer(x) * denominator(y)) >= numerator(y)) goto NOT_LESS; } else { if (integer(x) >= fraction(y)) goto NOT_LESS; } if (is_null(p)) return(sc->T); x = y; goto RATIO_LESS; case T_REAL: if (is_NaN(real(y))) goto NOT_LESS; if (integer(x) >= real(y)) goto NOT_LESS; if (is_null(p)) return(sc->T); x = y; goto REAL_LESS; default: method_or_bust(sc, y, sc->LT, cons(sc, x, cons(sc, y, p)), T_REAL, position_of(p, args) - 1); } case T_RATIO: RATIO_LESS: y = car(p); p = cdr(p); switch (type(y)) { case T_INTEGER: if ((numerator(x) > 0) && (integer(y) <= 0)) goto NOT_LESS; if ((numerator(x) < 0) && (integer(y) >= 0)) { if (is_null(p)) return(sc->T); x = y; goto INTEGER_LESS; } if ((integer(y) < s7_int32_max) && (integer(y) > s7_int32_min) && (denominator(x) < s7_int32_max)) { if (numerator(x) >= (integer(y) * denominator(x))) goto NOT_LESS; } else { if (fraction(x) >= integer(y)) goto NOT_LESS; } if (is_null(p)) return(sc->T); x = y; goto INTEGER_LESS; case T_RATIO: /* conversion to real and >= is not safe here (see comment under g_greater) */ { s7_int d1, d2, n1, n2; d1 = denominator(x); n1 = numerator(x); d2 = denominator(y); n2 = numerator(y); if (d1 == d2) { if (n1 >= n2) goto NOT_LESS; } else { #if HAVE_OVERFLOW_CHECKS if ((multiply_overflow(n1, d2, &n1)) || (multiply_overflow(n2, d1, &n2))) { if (fraction(x) >= fraction(y)) goto NOT_LESS; } else { if (n1 >= n2) goto NOT_LESS; } #else if ((d1 > s7_int32_max) || (d2 > s7_int32_max) || /* before counting bits, check that overflow is possible */ (n1 > s7_int32_max) || (n2 > s7_int32_max) || (n1 < s7_int32_min) || (n2 < s7_int32_min)) { int d1bits, d2bits; d1bits = integer_length(d1); d2bits = integer_length(d2); if (((d1bits + d2bits) > s7_int_bits) || ((d1bits + integer_length(n2)) > (s7_int_bits - 1)) || ((d2bits + integer_length(n1)) > (s7_int_bits - 1))) { if (fraction(x) >= fraction(y)) goto NOT_LESS; /* (< 21053343141/6701487259 3587785776203/1142027682075) -> #f because even long doubles aren't enough here * (= 21053343141/6701487259 3587785776203/1142027682075) is #f because it checks the actual ints and * (> 21053343141/6701487259 3587785776203/1142027682075) is #f just like the < case. * similarly * (min 21053343141/6701487259 3587785776203/1142027682075) -> 3587785776203/1142027682075 * (max 21053343141/6701487259 3587785776203/1142027682075) -> 3587785776203/1142027682075 * * if we print the long double results as integers, both are -3958705157555305931 * so there's not a lot I can do in the non-gmp case. */ } else { if ((n1 * d2) >= (n2 * d1)) goto NOT_LESS; } } else { if ((n1 * d2) >= (n2 * d1)) goto NOT_LESS; } #endif } } if (is_null(p)) return(sc->T); x = y; goto RATIO_LESS; case T_REAL: if (is_NaN(real(y))) goto NOT_LESS; if (fraction(x) >= real(y)) goto NOT_LESS; if (is_null(p)) return(sc->T); x = y; goto REAL_LESS; default: method_or_bust(sc, y, sc->LT, cons(sc, x, cons(sc, y, p)), T_REAL, position_of(p, args) - 1); } case T_REAL: if (is_NaN(real(x))) goto NOT_LESS; REAL_LESS: y = car(p); p = cdr(p); switch (type(y)) { case T_INTEGER: if (real(x) >= integer(y)) goto NOT_LESS; if (is_null(p)) return(sc->T); x = y; goto INTEGER_LESS; case T_RATIO: if (real(x) >= fraction(y)) goto NOT_LESS; if (is_null(p)) return(sc->T); x = y; goto RATIO_LESS; case T_REAL: if (is_NaN(real(y))) goto NOT_LESS; if (real(x) >= real(y)) goto NOT_LESS; if (is_null(p)) return(sc->T); x = y; goto REAL_LESS; default: method_or_bust(sc, y, sc->LT, cons(sc, x, cons(sc, y, p)), T_REAL, position_of(p, args) - 1); } default: method_or_bust(sc, x, sc->LT, args, T_REAL, 1); } NOT_LESS: for (; is_pair(p); p = cdr(p)) if (!is_real_via_method(sc, car(p))) return(wrong_type_argument(sc, sc->LT, position_of(p, args), car(p), T_REAL)); return(sc->F); } static s7_pointer g_less_or_equal(s7_scheme *sc, s7_pointer args) { #define H_less_or_equal "(<= x1 ...) returns #t if its arguments are in increasing order" #define Q_less_or_equal s7_make_circular_signature(sc, 1, 2, sc->IS_BOOLEAN, sc->IS_REAL) s7_pointer x, y, p; x = car(args); p = cdr(args); switch (type(x)) { case T_INTEGER: INTEGER_LEQ: y = car(p); p = cdr(p); switch (type(y)) { case T_INTEGER: if (integer(x) > integer(y)) goto NOT_LEQ; if (is_null(p)) return(sc->T); x = y; goto INTEGER_LEQ; case T_RATIO: /* no gmp here, but this can overflow: (< 9223372036 1/9223372036), but conversion to real is also problematic */ if ((integer(x) >= 0) && (numerator(y) < 0)) goto NOT_LEQ; /* (< 1 -1/2), ratio numerator can't be 0 */ if ((integer(x) <= 0) && (numerator(y) > 0)) /* (< 0 1/2) */ { if (is_null(p)) return(sc->T); x = y; goto RATIO_LEQ; } if ((integer(x) < s7_int32_max) && (integer(x) > s7_int32_min) && (denominator(y) < s7_int32_max)) { if ((integer(x) * denominator(y)) > numerator(y)) goto NOT_LEQ; } else { if (integer(x) > fraction(y)) goto NOT_LEQ; } if (is_null(p)) return(sc->T); x = y; goto RATIO_LEQ; case T_REAL: if (is_NaN(real(y))) goto NOT_LEQ; if (integer(x) > real(y)) goto NOT_LEQ; if (is_null(p)) return(sc->T); x = y; goto REAL_LEQ; default: method_or_bust(sc, y, sc->LEQ, cons(sc, x, cons(sc, y, p)), T_REAL, position_of(p, args) - 1); } case T_RATIO: RATIO_LEQ: y = car(p); p = cdr(p); switch (type(y)) { case T_INTEGER: if ((numerator(x) > 0) && (integer(y) <= 0)) goto NOT_LEQ; if ((numerator(x) < 0) && (integer(y) >= 0)) { if (is_null(p)) return(sc->T); x = y; goto INTEGER_LEQ; } if ((integer(y) < s7_int32_max) && (integer(y) > s7_int32_min) && (denominator(x) < s7_int32_max)) { if (numerator(x) > (integer(y) * denominator(x))) goto NOT_LEQ; } else { if (fraction(x) > integer(y)) goto NOT_LEQ; } if (is_null(p)) return(sc->T); x = y; goto INTEGER_LEQ; case T_RATIO: { s7_int d1, d2, n1, n2; d1 = denominator(x); n1 = numerator(x); d2 = denominator(y); n2 = numerator(y); if (d1 == d2) { if (n1 > n2) goto NOT_LEQ; } else { #if HAVE_OVERFLOW_CHECKS if ((multiply_overflow(n1, d2, &n1)) || (multiply_overflow(n2, d1, &n2))) { if (fraction(x) > fraction(y)) goto NOT_LEQ; } else { if (n1 > n2) goto NOT_LEQ; } #else if ((d1 > s7_int32_max) || (d2 > s7_int32_max) || /* before counting bits, check that overflow is possible */ (n1 > s7_int32_max) || (n2 > s7_int32_max) || (n1 < s7_int32_min) || (n2 < s7_int32_min)) { int d1bits, d2bits; d1bits = integer_length(d1); d2bits = integer_length(d2); if (((d1bits + d2bits) > s7_int_bits) || ((d1bits + integer_length(n2)) > (s7_int_bits - 1)) || ((d2bits + integer_length(n1)) > (s7_int_bits - 1))) { if (fraction(x) > fraction(y)) goto NOT_LEQ; } else { if ((n1 * d2) > (n2 * d1)) goto NOT_LEQ; } } else { if ((n1 * d2) > (n2 * d1)) goto NOT_LEQ; } #endif } } if (is_null(p)) return(sc->T); x = y; goto RATIO_LEQ; case T_REAL: if (is_NaN(real(y))) goto NOT_LEQ; if (fraction(x) > real(y)) goto NOT_LEQ; if (is_null(p)) return(sc->T); x = y; goto REAL_LEQ; default: method_or_bust(sc, y, sc->LEQ, cons(sc, x, cons(sc, y, p)), T_REAL, position_of(p, args) - 1); } case T_REAL: if (is_NaN(real(x))) goto NOT_LEQ; REAL_LEQ: y = car(p); p = cdr(p); switch (type(y)) { case T_INTEGER: if (real(x) > integer(y)) goto NOT_LEQ; if (is_null(p)) return(sc->T); x = y; goto INTEGER_LEQ; case T_RATIO: if (real(x) > fraction(y)) goto NOT_LEQ; if (is_null(p)) return(sc->T); x = y; goto RATIO_LEQ; case T_REAL: if (is_NaN(real(y))) goto NOT_LEQ; if (real(x) > real(y)) goto NOT_LEQ; if (is_null(p)) return(sc->T); x = y; goto REAL_LEQ; default: method_or_bust(sc, y, sc->LEQ, cons(sc, x, cons(sc, y, p)), T_REAL, position_of(p, args) - 1); } default: method_or_bust(sc, x, sc->LEQ, args, T_REAL, 1); } NOT_LEQ: for (; is_pair(p); p = cdr(p)) if (!is_real_via_method(sc, car(p))) return(wrong_type_argument(sc, sc->LEQ, position_of(p, args), car(p), T_REAL)); return(sc->F); } static s7_pointer g_greater(s7_scheme *sc, s7_pointer args) { #define H_greater "(> x1 ...) returns #t if its arguments are in decreasing order" #define Q_greater s7_make_circular_signature(sc, 1, 2, sc->IS_BOOLEAN, sc->IS_REAL) s7_pointer x, y, p; x = car(args); p = cdr(args); switch (type(x)) { case T_INTEGER: INTEGER_GREATER: y = car(p); p = cdr(p); switch (type(y)) { case T_INTEGER: if (integer(x) <= integer(y)) goto NOT_GREATER; if (is_null(p)) return(sc->T); x = y; goto INTEGER_GREATER; case T_RATIO: /* no gmp here, but this can overflow: (< 9223372036 1/9223372036), but conversion to real is also problematic */ if ((integer(x) <= 0) && (numerator(y) > 0)) goto NOT_GREATER; if ((integer(x) >= 0) && (numerator(y) < 0)) { if (is_null(p)) return(sc->T); x = y; goto RATIO_GREATER; } if ((integer(x) < s7_int32_max) && (integer(x) > s7_int32_min) && (denominator(y) < s7_int32_max)) { if ((integer(x) * denominator(y)) <= numerator(y)) goto NOT_GREATER; } else { if (integer(x) <= fraction(y)) goto NOT_GREATER; } if (is_null(p)) return(sc->T); x = y; goto RATIO_GREATER; case T_REAL: if (is_NaN(real(y))) goto NOT_GREATER; if (integer(x) <= real(y)) goto NOT_GREATER; if (is_null(p)) return(sc->T); x = y; goto REAL_GREATER; default: method_or_bust(sc, y, sc->GT, cons(sc, x, cons(sc, y, p)), T_REAL, position_of(p, args) - 1); } case T_RATIO: RATIO_GREATER: y = car(p); p = cdr(p); switch (type(y)) { case T_INTEGER: if ((numerator(x) < 0) && (integer(y) >= 0)) goto NOT_GREATER; if ((numerator(x) > 0) && (integer(y) <= 0)) { if (is_null(p)) return(sc->T); x = y; goto INTEGER_GREATER; } if ((integer(y) < s7_int32_max) && (integer(y) > s7_int32_min) && (denominator(x) < s7_int32_max)) { if (numerator(x) <= (integer(y) * denominator(x))) goto NOT_GREATER; } else { if (fraction(x) <= integer(y)) goto NOT_GREATER; } if (is_null(p)) return(sc->T); x = y; goto INTEGER_GREATER; case T_RATIO: { s7_int d1, d2, n1, n2; d1 = denominator(x); n1 = numerator(x); d2 = denominator(y); n2 = numerator(y); if (d1 == d2) { if (n1 <= n2) goto NOT_GREATER; } else { #if HAVE_OVERFLOW_CHECKS if ((multiply_overflow(n1, d2, &n1)) || (multiply_overflow(n2, d1, &n2))) { if (fraction(x) <= fraction(y)) goto NOT_GREATER; } else { if (n1 <= n2) goto NOT_GREATER; } #else if ((d1 > s7_int32_max) || (d2 > s7_int32_max) || /* before counting bits, check that overflow is possible */ (n1 > s7_int32_max) || (n2 > s7_int32_max) || (n1 < s7_int32_min) || (n2 < s7_int32_min)) { int d1bits, d2bits; d1bits = integer_length(d1); d2bits = integer_length(d2); if (((d1bits + d2bits) > s7_int_bits) || ((d1bits + integer_length(n2)) > (s7_int_bits - 1)) || ((d2bits + integer_length(n1)) > (s7_int_bits - 1))) { if (fraction(x) <= fraction(y)) goto NOT_GREATER; /* (< 21053343141/6701487259 3587785776203/1142027682075) -> #f because even long doubles aren't enough here * (= 21053343141/6701487259 3587785776203/1142027682075) is #f because it checks the actual ints and * (> 21053343141/6701487259 3587785776203/1142027682075) is #f just like the < case. * similarly * (min 21053343141/6701487259 3587785776203/1142027682075) -> 3587785776203/1142027682075 * (max 21053343141/6701487259 3587785776203/1142027682075) -> 3587785776203/1142027682075 * * if we print the long double results as integers, both are -3958705157555305931 * so there's not a lot I can do in the non-gmp case. */ } else { if ((n1 * d2) <= (n2 * d1)) goto NOT_GREATER; } } else { if ((n1 * d2) <= (n2 * d1)) goto NOT_GREATER; } #endif } } if (is_null(p)) return(sc->T); x = y; goto RATIO_GREATER; case T_REAL: if (is_NaN(real(y))) goto NOT_GREATER; if (fraction(x) <= real(y)) goto NOT_GREATER; if (is_null(p)) return(sc->T); x = y; goto REAL_GREATER; default: method_or_bust(sc, y, sc->GT, cons(sc, x, cons(sc, y, p)), T_REAL, position_of(p, args) - 1); } case T_REAL: if (is_NaN(real(x))) goto NOT_GREATER; REAL_GREATER: y = car(p); p = cdr(p); switch (type(y)) { case T_INTEGER: if (real(x) <= integer(y)) goto NOT_GREATER; if (is_null(p)) return(sc->T); x = y; goto INTEGER_GREATER; case T_RATIO: if (real(x) <= fraction(y)) goto NOT_GREATER; if (is_null(p)) return(sc->T); x = y; goto RATIO_GREATER; case T_REAL: if (is_NaN(real(y))) goto NOT_GREATER; if (real(x) <= real(y)) goto NOT_GREATER; if (is_null(p)) return(sc->T); x = y; goto REAL_GREATER; default: method_or_bust(sc, y, sc->GT, cons(sc, x, cons(sc, y, p)), T_REAL, position_of(p, args) - 1); } default: method_or_bust(sc, x, sc->GT, args, T_REAL, 1); } NOT_GREATER: for (; is_pair(p); p = cdr(p)) if (!is_real_via_method(sc, car(p))) return(wrong_type_argument(sc, sc->GT, position_of(p, args), car(p), T_REAL)); return(sc->F); } static s7_pointer g_greater_or_equal(s7_scheme *sc, s7_pointer args) { #define H_greater_or_equal "(>= x1 ...) returns #t if its arguments are in decreasing order" #define Q_greater_or_equal s7_make_circular_signature(sc, 1, 2, sc->IS_BOOLEAN, sc->IS_REAL) /* (>= 1+i 1+i) is an error which seems unfortunate */ s7_pointer x, y, p; x = car(args); p = cdr(args); switch (type(x)) { case T_INTEGER: INTEGER_GEQ: y = car(p); p = cdr(p); switch (type(y)) { case T_INTEGER: if (integer(x) < integer(y)) goto NOT_GEQ; if (is_null(p)) return(sc->T); x = y; goto INTEGER_GEQ; case T_RATIO: /* no gmp here, but this can overflow: (< 9223372036 1/9223372036), but conversion to real is also problematic */ if ((integer(x) <= 0) && (numerator(y) > 0)) goto NOT_GEQ; if ((integer(x) >= 0) && (numerator(y) < 0)) { if (is_null(p)) return(sc->T); x = y; goto RATIO_GEQ; } if ((integer(x) < s7_int32_max) && (integer(x) > s7_int32_min) && (denominator(y) < s7_int32_max)) { if ((integer(x) * denominator(y)) < numerator(y)) goto NOT_GEQ; } else { if (integer(x) < fraction(y)) goto NOT_GEQ; } if (is_null(p)) return(sc->T); x = y; goto RATIO_GEQ; case T_REAL: if (is_NaN(real(y))) goto NOT_GEQ; if (integer(x) < real(y)) goto NOT_GEQ; if (is_null(p)) return(sc->T); x = y; goto REAL_GEQ; default: method_or_bust(sc, y, sc->GEQ, cons(sc, x, cons(sc, y, p)), T_REAL, position_of(p, args) - 1); } case T_RATIO: RATIO_GEQ: y = car(p); p = cdr(p); switch (type(y)) { case T_INTEGER: if ((numerator(x) < 0) && (integer(y) >= 0)) goto NOT_GEQ; if ((numerator(x) > 0) && (integer(y) <= 0)) { if (is_null(p)) return(sc->T); x = y; goto INTEGER_GEQ; } if ((integer(y) < s7_int32_max) && (integer(y) > s7_int32_min) && (denominator(x) < s7_int32_max)) { if (numerator(x) < (integer(y) * denominator(x))) goto NOT_GEQ; } else { if (fraction(x) < integer(y)) goto NOT_GEQ; } if (is_null(p)) return(sc->T); x = y; goto INTEGER_GEQ; case T_RATIO: { s7_int d1, d2, n1, n2; d1 = denominator(x); n1 = numerator(x); d2 = denominator(y); n2 = numerator(y); if (d1 == d2) { if (n1 < n2) goto NOT_GEQ; } else { #if HAVE_OVERFLOW_CHECKS if ((multiply_overflow(n1, d2, &n1)) || (multiply_overflow(n2, d1, &n2))) { if (fraction(x) < fraction(y)) goto NOT_GEQ; } else { if (n1 < n2) goto NOT_GEQ; } #else if ((d1 > s7_int32_max) || (d2 > s7_int32_max) || /* before counting bits, check that overflow is possible */ (n1 > s7_int32_max) || (n2 > s7_int32_max) || (n1 < s7_int32_min) || (n2 < s7_int32_min)) { int d1bits, d2bits; d1bits = integer_length(d1); d2bits = integer_length(d2); if (((d1bits + d2bits) > s7_int_bits) || ((d1bits + integer_length(n2)) > (s7_int_bits - 1)) || ((d2bits + integer_length(n1)) > (s7_int_bits - 1))) { if (fraction(x) < fraction(y)) goto NOT_GEQ; } else { if ((n1 * d2) < (n2 * d1)) goto NOT_GEQ; } } else { if ((n1 * d2) < (n2 * d1)) goto NOT_GEQ; } #endif } } if (is_null(p)) return(sc->T); x = y; goto RATIO_GEQ; case T_REAL: if (is_NaN(real(y))) goto NOT_GEQ; if (fraction(x) < real(y)) goto NOT_GEQ; if (is_null(p)) return(sc->T); x = y; goto REAL_GEQ; default: method_or_bust(sc, y, sc->GEQ, cons(sc, x, cons(sc, y, p)), T_REAL, position_of(p, args) - 1); } case T_REAL: if (is_NaN(real(x))) goto NOT_GEQ; REAL_GEQ: y = car(p); p = cdr(p); switch (type(y)) { case T_INTEGER: if (real(x) < integer(y)) goto NOT_GEQ; if (is_null(p)) return(sc->T); x = y; goto INTEGER_GEQ; case T_RATIO: if (real(x) < fraction(y)) goto NOT_GEQ; if (is_null(p)) return(sc->T); x = y; goto RATIO_GEQ; case T_REAL: if (is_NaN(real(y))) goto NOT_GEQ; if (real(x) < real(y)) goto NOT_GEQ; if (is_null(p)) return(sc->T); x = y; goto REAL_GEQ; default: method_or_bust(sc, y, sc->GEQ, cons(sc, x, cons(sc, y, p)), T_REAL, position_of(p, args) - 1); } default: method_or_bust(sc, x, sc->GEQ, args, T_REAL, 1); } NOT_GEQ: for (; is_pair(p); p = cdr(p)) if (!is_real_via_method(sc, car(p))) return(wrong_type_argument(sc, sc->GEQ, position_of(p, args), car(p), T_REAL)); return(sc->F); } static s7_pointer less_s_ic, less_s0; static s7_pointer g_less_s0(s7_scheme *sc, s7_pointer args) { s7_pointer x; x = car(args); if (is_integer(x)) return(make_boolean(sc, integer(x) < 0)); if (is_real(x)) return(make_boolean(sc, s7_is_negative(x))); method_or_bust(sc, x, sc->LT, args, T_REAL, 1); } static s7_pointer g_less_s_ic(s7_scheme *sc, s7_pointer args) { s7_int y; s7_pointer x; x = car(args); y = integer(cadr(args)); if (is_integer(x)) return(make_boolean(sc, integer(x) < y)); switch (type(x)) { case T_INTEGER: return(make_boolean(sc, integer(x) < y)); case T_RATIO: if ((y >= 0) && (numerator(x) < 0)) return(sc->T); if ((y <= 0) && (numerator(x) > 0)) return(sc->F); if (denominator(x) < s7_int32_max) return(make_boolean(sc, (numerator(x) < (y * denominator(x))))); return(make_boolean(sc, fraction(x) < y)); case T_REAL: return(make_boolean(sc, real(x) < y)); case T_COMPLEX: default: method_or_bust(sc, x, sc->LT, args, T_REAL, 1); } return(sc->T); } static s7_pointer less_length_ic; static s7_pointer g_less_length_ic(s7_scheme *sc, s7_pointer args) { s7_int ilen; s7_pointer val; val = find_symbol_checked(sc, cadar(args)); ilen = s7_integer(cadr(args)); switch (type(val)) { case T_PAIR: return(make_boolean(sc, s7_list_length(sc, val) < ilen)); case T_NIL: return(make_boolean(sc, ilen > 0)); case T_STRING: return(make_boolean(sc, string_length(val) < ilen)); case T_HASH_TABLE: return(make_boolean(sc, hash_table_mask(val) <= ilen)); case T_ITERATOR: return(make_boolean(sc, iterator_length(val) < ilen)); case T_C_OBJECT: return(make_boolean(sc, object_length_to_int(sc, val) < ilen)); case T_LET: return(make_boolean(sc, let_length(sc, val) < ilen)); /* this works because let_length handles the length method itself! */ case T_INT_VECTOR: case T_FLOAT_VECTOR: case T_VECTOR: return(make_boolean(sc, vector_length(val) < ilen)); case T_CLOSURE: case T_CLOSURE_STAR: if (has_methods(val)) return(make_boolean(sc, closure_length(sc, val) < ilen)); default: return(simple_wrong_type_argument_with_type(sc, sc->LENGTH, val, A_SEQUENCE)); /* no check method here because we checked above */ } return(sc->F); } static s7_pointer c_less_2_1(s7_scheme *sc, s7_pointer x, s7_pointer y) { switch (type(x)) { case T_INTEGER: switch (type(y)) { case T_INTEGER: return(make_boolean(sc, integer(x) < integer(y))); case T_RATIO: return(g_less(sc, list_2(sc, x, y))); case T_REAL: if (is_NaN(real(y))) return(sc->F); return(make_boolean(sc, integer(x) < real(y))); default: method_or_bust(sc, y, sc->LT, list_2(sc, x, y), T_REAL, 2); } break; case T_RATIO: return(g_less(sc, list_2(sc, x, y))); case T_REAL: switch (type(y)) { case T_INTEGER: if (is_NaN(real(x))) return(sc->F); return(make_boolean(sc, real(x) < integer(y))); case T_RATIO: if (is_NaN(real(x))) return(sc->F); return(make_boolean(sc, real(x) < fraction(y))); case T_REAL: if (is_NaN(real(x))) return(sc->F); if (is_NaN(real(y))) return(sc->F); return(make_boolean(sc, real(x) < real(y))); default: method_or_bust(sc, y, sc->LT, list_2(sc, x, y), T_REAL, 2); } break; default: method_or_bust(sc, x, sc->LT, list_2(sc, x, y), T_REAL, 1); } return(sc->T); } static s7_pointer c_less_2(s7_scheme *sc, s7_pointer x, s7_pointer y) { #if (!MS_WINDOWS) if (type(x) == type(y)) { switch (type(x)) { case T_INTEGER: return(make_boolean(sc, integer(x) < integer(y))); case T_RATIO: return(make_boolean(sc, fraction(x) < fraction(y))); case T_REAL: return(make_boolean(sc, real(x) < real(y))); } } #endif return(c_less_2_1(sc, x, y)); } static s7_pointer less_2; static s7_pointer g_less_2(s7_scheme *sc, s7_pointer args) { s7_pointer x, y; x = car(args); y = cadr(args); #if (!MS_WINDOWS) if (type(x) == type(y)) { switch (type(x)) { case T_INTEGER: return(make_boolean(sc, integer(x) < integer(y))); case T_RATIO: return(make_boolean(sc, fraction(x) < fraction(y))); case T_REAL: return(make_boolean(sc, real(x) < real(y))); } } #endif return(c_less_2_1(sc, x, y)); } static s7_pointer c_less_i(s7_scheme *sc, s7_int x, s7_int y) {return(make_boolean(sc, x < y));} static s7_pointer c_less_r(s7_scheme *sc, s7_double x, s7_double y) {return(make_boolean(sc, x < y));} XF2_TO_PF(less, c_less_i, c_less_r, c_less_2) static s7_pointer leq_s_ic; static s7_pointer g_leq_s_ic(s7_scheme *sc, s7_pointer args) { s7_int y; s7_pointer x; x = car(args); y = s7_integer(cadr(args)); switch (type(x)) { case T_INTEGER: return(make_boolean(sc, integer(x) <= y)); case T_RATIO: if ((y >= 0) && (numerator(x) <= 0)) return(sc->T); if ((y <= 0) && (numerator(x) > 0)) return(sc->F); if (denominator(x) < s7_int32_max) return(make_boolean(sc, (numerator(x) <= (y * denominator(x))))); return(make_boolean(sc, fraction(x) <= y)); case T_REAL: return(make_boolean(sc, real(x) <= y)); default: method_or_bust(sc, x, sc->LEQ, args, T_REAL, 1); } return(sc->T); } static s7_pointer c_leq_2_1(s7_scheme *sc, s7_pointer x, s7_pointer y) { switch (type(x)) { case T_INTEGER: switch (type(y)) { case T_INTEGER: return(make_boolean(sc, integer(x) <= integer(y))); case T_RATIO: return(g_less_or_equal(sc, list_2(sc, x, y))); case T_REAL: if (is_NaN(real(y))) return(sc->F); return(make_boolean(sc, integer(x) <= real(y))); default: method_or_bust(sc, y, sc->LEQ, list_2(sc, x, y), T_REAL, 2); } break; case T_RATIO: return(g_less_or_equal(sc, list_2(sc, x, y))); case T_REAL: switch (type(y)) { case T_INTEGER: if (is_NaN(real(x))) return(sc->F); return(make_boolean(sc, real(x) <= integer(y))); case T_RATIO: if (is_NaN(real(x))) return(sc->F); return(make_boolean(sc, real(x) <= fraction(y))); case T_REAL: if (is_NaN(real(x))) return(sc->F); if (is_NaN(real(y))) return(sc->F); return(make_boolean(sc, real(x) <= real(y))); default: method_or_bust(sc, y, sc->LEQ, list_2(sc, x, y), T_REAL, 2); } break; default: method_or_bust(sc, x, sc->LEQ, list_2(sc, x, y), T_REAL, 1); } return(sc->T); } static s7_pointer c_leq_2(s7_scheme *sc, s7_pointer x, s7_pointer y) { #if (!MS_WINDOWS) if (type(x) == type(y)) { switch (type(x)) { case T_INTEGER: return(make_boolean(sc, integer(x) <= integer(y))); case T_RATIO: return(make_boolean(sc, fraction(x) <= fraction(y))); case T_REAL: return(make_boolean(sc, real(x) <= real(y))); } } #endif return(c_leq_2_1(sc, x, y)); } static s7_pointer leq_2; static s7_pointer g_leq_2(s7_scheme *sc, s7_pointer args) { s7_pointer x, y; x = car(args); y = cadr(args); #if (!MS_WINDOWS) if (type(x) == type(y)) { switch (type(x)) { case T_INTEGER: return(make_boolean(sc, integer(x) <= integer(y))); case T_RATIO: return(make_boolean(sc, fraction(x) <= fraction(y))); case T_REAL: return(make_boolean(sc, real(x) <= real(y))); } } #endif return(c_leq_2_1(sc, x, y)); } static s7_pointer c_leq_i(s7_scheme *sc, s7_int x, s7_int y) {return(make_boolean(sc, x <= y));} static s7_pointer c_leq_r(s7_scheme *sc, s7_double x, s7_double y) {return(make_boolean(sc, x <= y));} XF2_TO_PF(leq, c_leq_i, c_leq_r, c_leq_2) static s7_pointer greater_s_ic, greater_s_fc; static s7_pointer g_greater_s_ic(s7_scheme *sc, s7_pointer args) { s7_int y; s7_pointer x; x = car(args); y = integer(cadr(args)); switch (type(x)) { case T_INTEGER: return(make_boolean(sc, integer(x) > y)); case T_RATIO: if (denominator(x) < s7_int32_max) /* y has already been checked for range */ return(make_boolean(sc, (numerator(x) > (y * denominator(x))))); return(make_boolean(sc, fraction(x) > y)); case T_REAL: return(make_boolean(sc, real(x) > y)); default: method_or_bust_with_type(sc, x, sc->GT, args, A_NUMBER, 1); } return(sc->T); } static s7_pointer g_greater_s_fc(s7_scheme *sc, s7_pointer args) { s7_double y; s7_pointer x; x = car(args); y = real(cadr(args)); if (is_t_real(x)) return(make_boolean(sc, real(x) > y)); switch (type(x)) { case T_INTEGER: return(make_boolean(sc, integer(x) > y)); case T_RATIO: /* (> 9223372036854775807/9223372036854775806 1.0) */ if (denominator(x) < s7_int32_max) /* y range check was handled in greater_chooser */ return(make_boolean(sc, (numerator(x) > (y * denominator(x))))); return(make_boolean(sc, fraction(x) > y)); case T_REAL: return(make_boolean(sc, real(x) > y)); default: method_or_bust_with_type(sc, x, sc->GT, args, A_NUMBER, 1); } return(sc->T); } static s7_pointer c_greater_2_1(s7_scheme *sc, s7_pointer x, s7_pointer y) { switch (type(x)) { case T_INTEGER: switch (type(y)) { case T_INTEGER: return(make_boolean(sc, integer(x) > integer(y))); case T_RATIO: return(g_greater(sc, list_2(sc, x, y))); case T_REAL: if (is_NaN(real(y))) return(sc->F); return(make_boolean(sc, integer(x) > real(y))); default: method_or_bust(sc, y, sc->GT, list_2(sc, x, y), T_REAL, 2); } break; case T_RATIO: return(g_greater(sc, list_2(sc, x, y))); case T_REAL: switch (type(y)) { case T_INTEGER: if (is_NaN(real(x))) return(sc->F); return(make_boolean(sc, real(x) > integer(y))); case T_RATIO: if (is_NaN(real(x))) return(sc->F); return(make_boolean(sc, real(x) > fraction(y))); case T_REAL: if (is_NaN(real(x))) return(sc->F); if (is_NaN(real(y))) return(sc->F); return(make_boolean(sc, real(x) > real(y))); default: method_or_bust(sc, y, sc->GT, list_2(sc, x, y), T_REAL, 2); } break; default: method_or_bust(sc, x, sc->GT, list_2(sc, x, y), T_REAL, 1); } return(sc->T); } static s7_pointer c_greater_2(s7_scheme *sc, s7_pointer x, s7_pointer y) { #if (!MS_WINDOWS) if (type(x) == type(y)) { switch (type(x)) { case T_INTEGER: return(make_boolean(sc, integer(x) > integer(y))); case T_RATIO: return(make_boolean(sc, fraction(x) > fraction(y))); case T_REAL: return(make_boolean(sc, real(x) > real(y))); } } #endif return(c_greater_2_1(sc, x, y)); } static s7_pointer greater_2; static s7_pointer g_greater_2(s7_scheme *sc, s7_pointer args) { s7_pointer x, y; x = car(args); y = cadr(args); #if (!MS_WINDOWS) if (type(x) == type(y)) { switch (type(x)) { case T_INTEGER: return(make_boolean(sc, integer(x) > integer(y))); case T_RATIO: return(make_boolean(sc, fraction(x) > fraction(y))); case T_REAL: return(make_boolean(sc, real(x) > real(y))); } } #endif return(c_greater_2_1(sc, x, y)); } static s7_pointer c_gt_i(s7_scheme *sc, s7_int x, s7_int y) {return(make_boolean(sc, x > y));} static s7_pointer c_gt_r(s7_scheme *sc, s7_double x, s7_double y) {return(make_boolean(sc, x > y));} XF2_TO_PF(gt, c_gt_i, c_gt_r, c_greater_2) static s7_pointer greater_2_f; static s7_pointer g_greater_2_f(s7_scheme *sc, s7_pointer args) { return(make_boolean(sc, real(car(args)) > real(cadr(args)))); } static s7_pointer c_geq_2_1(s7_scheme *sc, s7_pointer x, s7_pointer y) { switch (type(x)) { case T_INTEGER: switch (type(y)) { case T_INTEGER: return(make_boolean(sc, integer(x) >= integer(y))); case T_RATIO: return(g_greater_or_equal(sc, list_2(sc, x, y))); case T_REAL: if (is_NaN(real(y))) return(sc->F); return(make_boolean(sc, integer(x) >= real(y))); default: method_or_bust(sc, y, sc->GEQ, list_2(sc, x, y), T_REAL, 2); } break; case T_RATIO: return(g_greater_or_equal(sc, list_2(sc, x, y))); case T_REAL: switch (type(y)) { case T_INTEGER: if (is_NaN(real(x))) return(sc->F); return(make_boolean(sc, real(x) >= integer(y))); case T_RATIO: if (is_NaN(real(x))) return(sc->F); return(make_boolean(sc, real(x) >= fraction(y))); case T_REAL: if (is_NaN(real(x))) return(sc->F); if (is_NaN(real(y))) return(sc->F); return(make_boolean(sc, real(x) >= real(y))); default: method_or_bust(sc, y, sc->GEQ, list_2(sc, x, y), T_REAL, 2); } break; default: method_or_bust(sc, x, sc->GEQ, list_2(sc, x, y), T_REAL, 1); } return(sc->T); } static s7_pointer c_geq_2(s7_scheme *sc, s7_pointer x, s7_pointer y) { #if (!MS_WINDOWS) if (type(x) == type(y)) { switch (type(x)) { case T_INTEGER: return(make_boolean(sc, integer(x) >= integer(y))); case T_RATIO: return(make_boolean(sc, fraction(x) >= fraction(y))); case T_REAL: return(make_boolean(sc, real(x) >= real(y))); } } #endif return(c_geq_2_1(sc, x, y)); } #endif static s7_pointer geq_2 = NULL; #if (!WITH_GMP) static s7_pointer g_geq_2(s7_scheme *sc, s7_pointer args) { s7_pointer x, y; x = car(args); y = cadr(args); #if (!MS_WINDOWS) if (type(x) == type(y)) { if (is_integer(x)) return(make_boolean(sc, integer(x) >= integer(y))); switch (type(x)) { case T_INTEGER: return(make_boolean(sc, integer(x) >= integer(y))); case T_RATIO: return(make_boolean(sc, fraction(x) >= fraction(y))); case T_REAL: return(make_boolean(sc, real(x) >= real(y))); } } #endif return(c_geq_2_1(sc, x, y)); } static s7_pointer c_geq_i(s7_scheme *sc, s7_int x, s7_int y) {return(make_boolean(sc, x >= y));} static s7_pointer c_geq_r(s7_scheme *sc, s7_double x, s7_double y) {return(make_boolean(sc, x >= y));} XF2_TO_PF(geq, c_geq_i, c_geq_r, c_geq_2) static s7_pointer geq_s_fc; static s7_pointer g_geq_s_fc(s7_scheme *sc, s7_pointer args) { s7_double y; s7_pointer x; x = car(args); y = real(cadr(args)); if (is_t_real(x)) return(make_boolean(sc, real(x) >= y)); return(g_geq_2(sc, args)); } static s7_pointer geq_length_ic; static s7_pointer g_geq_length_ic(s7_scheme *sc, s7_pointer args) { return(make_boolean(sc, is_false(sc, g_less_length_ic(sc, args)))); } static s7_pointer geq_s_ic; static s7_pointer g_geq_s_ic(s7_scheme *sc, s7_pointer args) { s7_int y; s7_pointer x; x = car(args); y = s7_integer(cadr(args)); switch (type(x)) { case T_INTEGER: return(make_boolean(sc, integer(x) >= y)); case T_RATIO: if ((y >= 0) && (numerator(x) < 0)) return(sc->F); if ((y <= 0) && (numerator(x) >= 0)) return(sc->T); if ((y < s7_int32_max) && (y > s7_int32_min) && (denominator(x) < s7_int32_max)) return(make_boolean(sc, (numerator(x) >= (y * denominator(x))))); return(make_boolean(sc, fraction(x) >= y)); case T_REAL: return(make_boolean(sc, real(x) >= y)); default: method_or_bust(sc, x, sc->GEQ, args, T_REAL, 1); } return(sc->T); } #endif /* end (!WITH_GMP) */ /* ---------------------------------------- real-part imag-part ---------------------------------------- */ s7_double s7_real_part(s7_pointer x) { switch(type(x)) { case T_INTEGER: return((s7_double)integer(x)); case T_RATIO: return(fraction(x)); case T_REAL: return(real(x)); case T_COMPLEX: return(real_part(x)); #if WITH_GMP case T_BIG_INTEGER: return((s7_double)big_integer_to_s7_int(big_integer(x))); case T_BIG_RATIO: return((s7_double)((long double)big_integer_to_s7_int(mpq_numref(big_ratio(x))) / (long double)big_integer_to_s7_int(mpq_denref(big_ratio(x))))); case T_BIG_REAL: return((s7_double)mpfr_get_d(big_real(x), GMP_RNDN)); case T_BIG_COMPLEX: return((s7_double)mpfr_get_d(mpc_realref(big_complex(x)), GMP_RNDN)); #endif } return(0.0); } s7_double s7_imag_part(s7_pointer x) { switch (type(x)) { case T_COMPLEX: return(imag_part(x)); #if WITH_GMP case T_BIG_COMPLEX: return((s7_double)mpfr_get_d(mpc_imagref(big_complex(x)), GMP_RNDN)); #endif } return(0.0); } static s7_pointer g_real_part(s7_scheme *sc, s7_pointer args) { #define H_real_part "(real-part num) returns the real part of num" #define Q_real_part s7_make_signature(sc, 2, sc->IS_REAL, sc->IS_NUMBER) s7_pointer p; p = car(args); switch (type(p)) { case T_INTEGER: case T_RATIO: case T_REAL: return(p); case T_COMPLEX: return(make_real(sc, real_part(p))); #if WITH_GMP case T_BIG_INTEGER: case T_BIG_RATIO: case T_BIG_REAL: return(p); case T_BIG_COMPLEX: { s7_pointer x; new_cell(sc, x, T_BIG_REAL); add_bigreal(sc, x); mpfr_init(big_real(x)); mpc_real(big_real(x), big_complex(p), GMP_RNDN); return(x); } #endif default: method_or_bust_with_type(sc, p, sc->REAL_PART, args, A_NUMBER, 0); } } #if (!WITH_GMP) static s7_double c_real_part(s7_scheme *sc, s7_pointer x) {return(real(g_real_part(sc, set_plist_1(sc, x))));} PF_TO_RF(real_part, c_real_part) #endif static s7_pointer g_imag_part(s7_scheme *sc, s7_pointer args) { #define H_imag_part "(imag-part num) returns the imaginary part of num" #define Q_imag_part s7_make_signature(sc, 2, sc->IS_REAL, sc->IS_NUMBER) s7_pointer p; /* currently (imag-part nan.0) -> 0.0 ? it's true but maybe confusing */ p = car(args); switch (type(p)) { case T_INTEGER: case T_RATIO: return(small_int(0)); case T_REAL: return(real_zero); case T_COMPLEX: return(make_real(sc, imag_part(p))); #if WITH_GMP case T_BIG_INTEGER: case T_BIG_RATIO: return(small_int(0)); case T_BIG_REAL: return(real_zero); case T_BIG_COMPLEX: { s7_pointer x; new_cell(sc, x, T_BIG_REAL); add_bigreal(sc, x); mpfr_init(big_real(x)); mpc_imag(big_real(x), big_complex(p), GMP_RNDN); return(x); } #endif default: method_or_bust_with_type(sc, p, sc->IMAG_PART, args, A_NUMBER, 0); } } #if (!WITH_GMP) static s7_double c_imag_part(s7_scheme *sc, s7_pointer x) {return(real(g_imag_part(sc, set_plist_1(sc, x))));} PF_TO_RF(imag_part, c_imag_part) #endif /* ---------------------------------------- numerator denominator ---------------------------------------- */ static s7_pointer g_numerator(s7_scheme *sc, s7_pointer args) { #define H_numerator "(numerator rat) returns the numerator of the rational number rat" #define Q_numerator s7_make_signature(sc, 2, sc->IS_INTEGER, sc->IS_RATIONAL) s7_pointer x; x = car(args); switch (type(x)) { case T_RATIO: return(make_integer(sc, numerator(x))); case T_INTEGER: return(x); #if WITH_GMP case T_BIG_INTEGER: return(x); case T_BIG_RATIO: return(mpz_to_big_integer(sc, mpq_numref(big_ratio(x)))); #endif default: method_or_bust_with_type(sc, x, sc->NUMERATOR, args, A_RATIONAL, 0); } } #if (!WITH_GMP) static s7_int c_numerator(s7_scheme *sc, s7_pointer x) {return(s7_numerator(x));} PF_TO_IF(numerator, c_numerator) #endif static s7_pointer g_denominator(s7_scheme *sc, s7_pointer args) { #define H_denominator "(denominator rat) returns the denominator of the rational number rat" #define Q_denominator s7_make_signature(sc, 2, sc->IS_INTEGER, sc->IS_RATIONAL) s7_pointer x; x = car(args); switch (type(x)) { case T_RATIO: return(make_integer(sc, denominator(x))); case T_INTEGER: return(small_int(1)); #if WITH_GMP case T_BIG_INTEGER: return(small_int(1)); case T_BIG_RATIO: return(mpz_to_big_integer(sc, mpq_denref(big_ratio(x)))); #endif default: method_or_bust_with_type(sc, x, sc->DENOMINATOR, args, A_RATIONAL, 0); } } #if (!WITH_GMP) static s7_int c_denominator(s7_scheme *sc, s7_pointer x) {return(s7_denominator(x));} PF_TO_IF(denominator, c_denominator) #endif /* ---------------------------------------- nan? infinite? ---------------------------------------- */ static s7_pointer g_is_nan(s7_scheme *sc, s7_pointer args) { #define H_is_nan "(nan? obj) returns #t if obj is a NaN" #define Q_is_nan pl_bn s7_pointer x; x = car(args); switch (type(x)) { case T_INTEGER: case T_RATIO: return(sc->F); case T_REAL: return(make_boolean(sc, is_NaN(real(x)))); case T_COMPLEX: return(make_boolean(sc, (is_NaN(real_part(x))) || (is_NaN(imag_part(x))))); #if WITH_GMP case T_BIG_INTEGER: case T_BIG_RATIO: return(sc->F); case T_BIG_REAL: return(make_boolean(sc, is_NaN(s7_real_part(x)))); case T_BIG_COMPLEX: return(make_boolean(sc, (is_NaN(s7_real_part(x))) || (is_NaN(s7_imag_part(x))))); #endif default: method_or_bust_with_type(sc, x, sc->IS_NAN, list_1(sc, x), A_NUMBER, 0); } } #if (!WITH_GMP) static s7_pointer c_is_nan(s7_scheme *sc, s7_double x) {return((is_NaN(x)) ? sc->T : sc->F);} RF_TO_PF(is_nan, c_is_nan) #endif static s7_pointer g_is_infinite(s7_scheme *sc, s7_pointer args) { #define H_is_infinite "(infinite? obj) returns #t if obj is an infinite real" #define Q_is_infinite pl_bn s7_pointer x; x = car(args); switch (type(x)) { case T_INTEGER: case T_RATIO: return(sc->F); case T_REAL: return(make_boolean(sc, is_inf(real(x)))); case T_COMPLEX: return(make_boolean(sc, (is_inf(real_part(x))) || (is_inf(imag_part(x))))); #if WITH_GMP case T_BIG_INTEGER: case T_BIG_RATIO: return(sc->F); case T_BIG_REAL: return(make_boolean(sc, mpfr_inf_p(big_real(x)) != 0)); case T_BIG_COMPLEX: return(make_boolean(sc, (mpfr_inf_p(big_real(g_real_part(sc, list_1(sc, x)))) != 0) || (mpfr_inf_p(big_real(g_imag_part(sc, list_1(sc, x)))) != 0))); #endif default: method_or_bust_with_type(sc, x, sc->IS_INFINITE, list_1(sc, x), A_NUMBER, 0); } } #if (!WITH_GMP) static s7_pointer c_is_infinite(s7_scheme *sc, s7_double x) {return((is_inf(x)) ? sc->T : sc->F);} RF_TO_PF(is_infinite, c_is_infinite) #endif /* ---------------------------------------- number? complex? integer? rational? real? ---------------------------------------- */ static s7_pointer g_is_number(s7_scheme *sc, s7_pointer args) { #define H_is_number "(number? obj) returns #t if obj is a number" #define Q_is_number pl_bt check_boolean_method(sc, s7_is_number, sc->IS_NUMBER, args); /* we need the s7_* versions here for the GMP case */ } static s7_pointer g_is_integer(s7_scheme *sc, s7_pointer args) { #define H_is_integer "(integer? obj) returns #t if obj is an integer" #define Q_is_integer pl_bt check_boolean_method(sc, s7_is_integer, sc->IS_INTEGER, args); } static s7_pointer g_is_real(s7_scheme *sc, s7_pointer args) { #define H_is_real "(real? obj) returns #t if obj is a real number" #define Q_is_real pl_bt check_boolean_method(sc, s7_is_real, sc->IS_REAL, args); } static s7_pointer g_is_complex(s7_scheme *sc, s7_pointer args) { #define H_is_complex "(complex? obj) returns #t if obj is a number" #define Q_is_complex pl_bt check_boolean_method(sc, s7_is_number, sc->IS_COMPLEX, args); } static s7_pointer g_is_rational(s7_scheme *sc, s7_pointer args) { #define H_is_rational "(rational? obj) returns #t if obj is a rational number (either an integer or a ratio)" #define Q_is_rational pl_bt check_boolean_method(sc, s7_is_rational, sc->IS_RATIONAL, args); /* in the non-gmp case, (rational? 455702434782048082459/86885567283849955830) -> #f, not #t * and similarly for exact? etc. */ } /* ---------------------------------------- even? odd?---------------------------------------- */ static s7_pointer g_is_even(s7_scheme *sc, s7_pointer args) { #define H_is_even "(even? int) returns #t if the integer int is even" #define Q_is_even s7_make_signature(sc, 2, sc->IS_BOOLEAN, sc->IS_INTEGER) s7_pointer p; p = car(args); switch (type(p)) { case T_INTEGER: return(make_boolean(sc, ((integer(p) & 1) == 0))); #if WITH_GMP case T_BIG_INTEGER: return(make_boolean(sc, mpz_even_p(big_integer(p)))); #endif default: method_or_bust(sc, p, sc->IS_EVEN, list_1(sc, p), T_INTEGER, 0); } } #if (!WITH_GMP) static s7_pointer c_is_even(s7_scheme *sc, s7_int arg) {return(((arg & 1) == 0) ? sc->T : sc->F);} IF_TO_PF(is_even, c_is_even) #endif static s7_pointer g_is_odd(s7_scheme *sc, s7_pointer args) { #define H_is_odd "(odd? int) returns #t if the integer int is odd" #define Q_is_odd s7_make_signature(sc, 2, sc->IS_BOOLEAN, sc->IS_INTEGER) s7_pointer p; p = car(args); switch (type(p)) { case T_INTEGER: return(make_boolean(sc, ((integer(p) & 1) == 1))); #if WITH_GMP case T_BIG_INTEGER: return(make_boolean(sc, mpz_odd_p(big_integer(p)))); #endif default: method_or_bust(sc, p, sc->IS_ODD, list_1(sc, p), T_INTEGER, 0); } } #if (!WITH_GMP) static s7_pointer c_is_odd(s7_scheme *sc, s7_int arg) {return(((arg & 1) == 0) ? sc->F : sc->T);} IF_TO_PF(is_odd, c_is_odd) #endif /* ---------------------------------------- zero? ---------------------------------------- */ static s7_pointer c_is_zero(s7_scheme *sc, s7_pointer x) { switch (type(x)) { case T_INTEGER: return(make_boolean(sc, integer(x) == 0)); case T_REAL: return(make_boolean(sc, real(x) == 0.0)); case T_RATIO: case T_COMPLEX: return(sc->F); /* ratios and complex numbers are already collapsed into integers and reals */ #if WITH_GMP case T_BIG_INTEGER: return(make_boolean(sc, mpz_cmp_ui(big_integer(x), 0) == 0)); case T_BIG_REAL: return(make_boolean(sc, mpfr_zero_p(big_real(x)))); case T_BIG_RATIO: case T_BIG_COMPLEX: return(sc->F); #endif default: method_or_bust_with_type(sc, x, sc->IS_ZERO, list_1(sc, x), A_NUMBER, 0); } } static s7_pointer g_is_zero(s7_scheme *sc, s7_pointer args) { #define H_is_zero "(zero? num) returns #t if the number num is zero" #define Q_is_zero pl_bn return(c_is_zero(sc, car(args))); } static s7_pointer c_is_zero_i(s7_scheme *sc, s7_int x) {return(make_boolean(sc, x == 0));} static s7_pointer c_is_zero_r(s7_scheme *sc, s7_double x) {return(make_boolean(sc, x == 0.0));} XF_TO_PF(is_zero, c_is_zero_i, c_is_zero_r, c_is_zero) /* -------------------------------- positive? -------------------------------- */ static s7_pointer c_is_positive(s7_scheme *sc, s7_pointer x) { switch (type(x)) { case T_INTEGER: return(make_boolean(sc, integer(x) > 0)); case T_RATIO: return(make_boolean(sc, numerator(x) > 0)); case T_REAL: return(make_boolean(sc, real(x) > 0.0)); #if WITH_GMP case T_BIG_INTEGER: return(make_boolean(sc, (mpz_cmp_ui(big_integer(x), 0) > 0))); case T_BIG_RATIO: return(make_boolean(sc, (mpq_cmp_ui(big_ratio(x), 0, 1) > 0))); case T_BIG_REAL: return(make_boolean(sc, (mpfr_cmp_ui(big_real(x), 0) > 0))); #endif default: method_or_bust(sc, x, sc->IS_POSITIVE, list_1(sc, x), T_REAL, 0); } } static s7_pointer g_is_positive(s7_scheme *sc, s7_pointer args) { #define H_is_positive "(positive? num) returns #t if the real number num is positive (greater than 0)" #define Q_is_positive s7_make_signature(sc, 2, sc->IS_BOOLEAN, sc->IS_REAL) return(c_is_positive(sc, car(args))); } static s7_pointer c_is_positive_i(s7_scheme *sc, s7_int x) {return(make_boolean(sc, x > 0));} static s7_pointer c_is_positive_r(s7_scheme *sc, s7_double x) {return(make_boolean(sc, x > 0.0));} XF_TO_PF(is_positive, c_is_positive_i, c_is_positive_r, c_is_positive) /* -------------------------------- negative? -------------------------------- */ static s7_pointer c_is_negative(s7_scheme *sc, s7_pointer x) { switch (type(x)) { case T_INTEGER: return(make_boolean(sc, integer(x) < 0)); case T_RATIO: return(make_boolean(sc, numerator(x) < 0)); case T_REAL: return(make_boolean(sc, real(x) < 0.0)); #if WITH_GMP case T_BIG_INTEGER: return(make_boolean(sc, (mpz_cmp_ui(big_integer(x), 0) < 0))); case T_BIG_RATIO: return(make_boolean(sc, (mpq_cmp_ui(big_ratio(x), 0, 1) < 0))); case T_BIG_REAL: return(make_boolean(sc, (mpfr_cmp_ui(big_real(x), 0) < 0))); #endif default: method_or_bust(sc, x, sc->IS_NEGATIVE, list_1(sc, x), T_REAL, 0); } } static s7_pointer g_is_negative(s7_scheme *sc, s7_pointer args) { #define H_is_negative "(negative? num) returns #t if the real number num is negative (less than 0)" #define Q_is_negative s7_make_signature(sc, 2, sc->IS_BOOLEAN, sc->IS_REAL) return(c_is_negative(sc, car(args))); } static s7_pointer c_is_negative_i(s7_scheme *sc, s7_int x) {return(make_boolean(sc, x < 0));} static s7_pointer c_is_negative_r(s7_scheme *sc, s7_double x) {return(make_boolean(sc, x < 0.0));} XF_TO_PF(is_negative, c_is_negative_i, c_is_negative_r, c_is_negative) bool s7_is_ulong(s7_pointer arg) { return(is_integer(arg)); } unsigned long s7_ulong(s7_pointer p) { return((_NFre(p))->object.number.ul_value); } s7_pointer s7_make_ulong(s7_scheme *sc, unsigned long n) { s7_pointer x; new_cell(sc, x, T_INTEGER); x->object.number.ul_value = n; return(x); } bool s7_is_ulong_long(s7_pointer arg) { return(is_integer(arg)); } unsigned long long s7_ulong_long(s7_pointer p) { return((_NFre(p))->object.number.ull_value); } s7_pointer s7_make_ulong_long(s7_scheme *sc, unsigned long long n) { s7_pointer x; new_cell(sc, x, T_INTEGER); x->object.number.ull_value = n; return(x); } #if (!WITH_PURE_S7) #if (!WITH_GMP) /* ---------------------------------------- exact<->inexact exact? inexact? ---------------------------------------- */ static s7_pointer g_exact_to_inexact(s7_scheme *sc, s7_pointer args) { #define H_exact_to_inexact "(exact->inexact num) converts num to an inexact number; (exact->inexact 3/2) = 1.5" #define Q_exact_to_inexact pcl_r return(exact_to_inexact(sc, car(args))); } static s7_pointer g_inexact_to_exact(s7_scheme *sc, s7_pointer args) { #define H_inexact_to_exact "(inexact->exact num) converts num to an exact number; (inexact->exact 1.5) = 3/2" #define Q_inexact_to_exact s7_make_signature(sc, 2, sc->IS_RATIONAL, sc->IS_REAL) return(inexact_to_exact(sc, car(args), WITH_OVERFLOW_ERROR)); } #endif /* (!WITH_GMP) */ static s7_pointer g_is_exact(s7_scheme *sc, s7_pointer args) { #define H_is_exact "(exact? num) returns #t if num is exact (an integer or a ratio)" #define Q_is_exact pl_bn s7_pointer x; x = car(args); switch (type(x)) { case T_INTEGER: case T_RATIO: return(sc->T); case T_REAL: case T_COMPLEX: return(sc->F); #if WITH_GMP case T_BIG_INTEGER: case T_BIG_RATIO: return(sc->T); case T_BIG_REAL: case T_BIG_COMPLEX: return(sc->F); #endif default: method_or_bust_with_type(sc, x, sc->IS_EXACT, args, A_NUMBER, 0); } } static s7_pointer g_is_inexact(s7_scheme *sc, s7_pointer args) { #define H_is_inexact "(inexact? num) returns #t if num is inexact (neither an integer nor a ratio)" #define Q_is_inexact pl_bn s7_pointer x; x = car(args); switch (type(x)) { case T_INTEGER: case T_RATIO: return(sc->F); case T_REAL: case T_COMPLEX: return(sc->T); #if WITH_GMP case T_BIG_INTEGER: case T_BIG_RATIO: return(sc->F); case T_BIG_REAL: case T_BIG_COMPLEX: return(sc->T); #endif default: method_or_bust_with_type(sc, x, sc->IS_INEXACT, args, A_NUMBER, 0); } } /* ---------------------------------------- integer-length, integer-decode-float ---------------------------------------- */ static s7_pointer g_integer_length(s7_scheme *sc, s7_pointer args) { #define H_integer_length "(integer-length arg) returns the number of bits required to represent the integer 'arg': (ceiling (log (abs arg) 2))" #define Q_integer_length pcl_i s7_int x; s7_pointer p; p = car(args); if (!s7_is_integer(p)) method_or_bust(sc, p, sc->INTEGER_LENGTH, args, T_INTEGER, 0); x = s7_integer(p); if (x < 0) return(make_integer(sc, integer_length(-(x + 1)))); return(make_integer(sc, integer_length(x))); } #if (!WITH_GMP) static s7_int c_integer_length(s7_scheme *sc, s7_int arg) {return((arg < 0) ? integer_length(-(arg + 1)) : integer_length(arg));} IF_TO_IF(integer_length, c_integer_length) #endif #endif /* !pure s7 */ static s7_pointer g_integer_decode_float(s7_scheme *sc, s7_pointer args) { #define H_integer_decode_float "(integer-decode-float x) returns a list containing the significand, exponent, and \ sign of 'x' (1 = positive, -1 = negative). (integer-decode-float 0.0): (0 0 1)" #define Q_integer_decode_float s7_make_signature(sc, 2, sc->IS_PAIR, sc->IS_FLOAT) /* no matter what s7_double is, integer-decode-float acts as if x is a C double */ typedef struct decode_float_t { union { long long int ix; double fx; } value; } decode_float_t; decode_float_t num; s7_pointer x; x = car(args); switch (type(x)) { case T_REAL: num.value.fx = (double)real(x); break; #if WITH_GMP case T_BIG_REAL: num.value.fx = (double)real_to_double(sc, x, "integer-decode-float"); break; #endif default: method_or_bust_with_type(sc, x, sc->INTEGER_DECODE_FLOAT, args, make_string_wrapper(sc, "a non-rational real"), 0); } if (num.value.fx == 0.0) return(list_3(sc, small_int(0), small_int(0), small_int(1))); return(list_3(sc, make_integer(sc, (s7_int)((num.value.ix & 0xfffffffffffffLL) | 0x10000000000000LL)), make_integer(sc, (s7_int)(((num.value.ix & 0x7fffffffffffffffLL) >> 52) - 1023 - 52)), make_integer(sc, ((num.value.ix & 0x8000000000000000LL) != 0) ? -1 : 1))); } /* -------------------------------- logior -------------------------------- */ static s7_pointer g_logior(s7_scheme *sc, s7_pointer args) { #define H_logior "(logior int ...) returns the bitwise OR of its integer arguments (the bits that are on in any of the arguments)" #define Q_logior pcl_i s7_int result = 0; s7_pointer x; for (x = args; is_not_null(x); x = cdr(x)) { if (!s7_is_integer(car(x))) method_or_bust(sc, car(x), sc->LOGIOR, cons(sc, make_integer(sc, result), x), T_INTEGER, position_of(x, args)); result |= s7_integer(car(x)); } return(make_integer(sc, result)); } #if (!WITH_GMP) static s7_int c_logior(s7_scheme *sc, s7_int x, s7_int y) {return(x | y);} IF2_TO_IF(logior, c_logior) #endif /* -------------------------------- logxor -------------------------------- */ static s7_pointer g_logxor(s7_scheme *sc, s7_pointer args) { #define H_logxor "(logxor int ...) returns the bitwise XOR of its integer arguments (the bits that are on in an odd number of the arguments)" #define Q_logxor pcl_i s7_int result = 0; s7_pointer x; for (x = args; is_not_null(x); x = cdr(x)) { if (!s7_is_integer(car(x))) method_or_bust(sc, car(x), sc->LOGXOR, cons(sc, make_integer(sc, result), x), T_INTEGER, position_of(x, args)); result ^= s7_integer(car(x)); } return(make_integer(sc, result)); } #if (!WITH_GMP) static s7_int c_logxor(s7_scheme *sc, s7_int x, s7_int y) {return(x ^ y);} IF2_TO_IF(logxor, c_logxor) #endif /* -------------------------------- logand -------------------------------- */ static s7_pointer g_logand(s7_scheme *sc, s7_pointer args) { #define H_logand "(logand int ...) returns the bitwise AND of its integer arguments (the bits that are on in every argument)" #define Q_logand pcl_i s7_int result = -1; s7_pointer x; for (x = args; is_not_null(x); x = cdr(x)) { if (!s7_is_integer(car(x))) method_or_bust(sc, car(x), sc->LOGAND, cons(sc, make_integer(sc, result), x), T_INTEGER, position_of(x, args)); result &= s7_integer(car(x)); } return(make_integer(sc, result)); } #if (!WITH_GMP) static s7_int c_logand(s7_scheme *sc, s7_int x, s7_int y) {return(x & y);} IF2_TO_IF(logand, c_logand) #endif /* -------------------------------- lognot -------------------------------- */ static s7_pointer g_lognot(s7_scheme *sc, s7_pointer args) { #define H_lognot "(lognot num) returns the bitwise negation (the complement, the bits that are not on) in num: (lognot 0) -> -1" #define Q_lognot pcl_i if (!s7_is_integer(car(args))) method_or_bust(sc, car(args), sc->LOGNOT, args, T_INTEGER, 0); return(make_integer(sc, ~s7_integer(car(args)))); } #if (!WITH_GMP) static s7_int c_lognot(s7_scheme *sc, s7_int arg) {return(~arg);} IF_TO_IF(lognot, c_lognot) #endif /* -------------------------------- logbit? -------------------------------- */ /* logbit? CL is (logbitp index int) using 2^index, but that order strikes me as backwards * at least gmp got the arg order right! */ static s7_pointer g_logbit(s7_scheme *sc, s7_pointer args) { #define H_logbit "(logbit? int index) returns #t if the index-th bit is on in int, otherwise #f. The argument \ order here follows gmp, and is the opposite of the CL convention. (logbit? int bit) is the same as (not (zero? (logand int (ash 1 bit))))." #define Q_logbit s7_make_circular_signature(sc, 1, 2, sc->IS_BOOLEAN, sc->IS_INTEGER) s7_pointer x, y; s7_int index; /* index in gmp is mp_bitcnt which is an unsigned long int */ x = car(args); y = cadr(args); if (!s7_is_integer(x)) method_or_bust(sc, x, sc->LOGBIT, args, T_INTEGER, 1); if (!s7_is_integer(y)) method_or_bust(sc, y, sc->LOGBIT, args, T_INTEGER, 2); index = s7_integer(y); if (index < 0) return(out_of_range(sc, sc->LOGBIT, small_int(2), y, ITS_NEGATIVE)); #if WITH_GMP if (is_t_big_integer(x)) return(make_boolean(sc, (mpz_tstbit(big_integer(x), index) != 0))); #endif if (index >= s7_int_bits) /* not sure about the >: (logbit? -1 64) ?? */ return(make_boolean(sc, integer(x) < 0)); /* :(zero? (logand most-positive-fixnum (ash 1 63))) * -> ash argument 2, 63, is out of range (shift is too large) * so logbit? has a wider range than the logand/ash shuffle above. */ /* all these long long ints are necessary, else C turns it into an int, gets confused about signs etc */ return(make_boolean(sc, ((((long long int)(1LL << (long long int)index)) & (long long int)integer(x)) != 0))); } /* -------------------------------- ash -------------------------------- */ static s7_int c_ash(s7_scheme *sc, s7_int arg1, s7_int arg2) { if (arg1 == 0) return(0); if (arg2 >= s7_int_bits) out_of_range(sc, sc->ASH, small_int(2), make_integer(sc, arg2), ITS_TOO_LARGE); if (arg2 < -s7_int_bits) { if (arg1 < 0) /* (ash -31 -100) */ return(-1); return(0); } /* I can't see any point in protecting this: (ash 9223372036854775807 1) -> -2, but anyone using ash must know something about bits */ if (arg2 >= 0) { if (arg1 < 0) { unsigned long long int z; z = (unsigned long long int)arg1; return((s7_int)(z << arg2)); } return(arg1 << arg2); } return(arg1 >> -arg2); } static s7_pointer g_ash(s7_scheme *sc, s7_pointer args) { #define H_ash "(ash i1 i2) returns i1 shifted right or left i2 times, i1 << i2, (ash 1 3) -> 8, (ash 8 -3) -> 1" #define Q_ash pcl_i s7_pointer x, y; x = car(args); if (!s7_is_integer(x)) method_or_bust(sc, x, sc->ASH, args, T_INTEGER, 1); y = cadr(args); if (!s7_is_integer(y)) method_or_bust(sc, y, sc->ASH, args, T_INTEGER, 2); return(make_integer(sc, c_ash(sc, s7_integer(x), s7_integer(y)))); } #if (!WITH_GMP) IF2_TO_IF(ash, c_ash) #endif /* ---------------------------------------- random ---------------------------------------- */ /* random numbers. The simple version used in clm.c is probably adequate, * but here I'll use Marsaglia's MWC algorithm. * (random num) -> a number (0..num), if num == 0 return 0, use global default state * (random num state) -> same but use this state * (random-state seed) -> make a new state * to save the current seed, use copy * to save it across load, random-state->list and list->random-state. * random-state? returns #t if its arg is one of these guys */ #if (!WITH_GMP) s7_pointer s7_random_state(s7_scheme *sc, s7_pointer args) { #define H_random_state "(random-state seed (carry plausible-default)) returns a new random number state initialized with 'seed'. \ Pass this as the second argument to 'random' to get a repeatable random number sequence:\n\ (let ((seed (random-state 1234))) (random 1.0 seed))" #define Q_random_state s7_make_circular_signature(sc, 1, 2, sc->IS_RANDOM_STATE, sc->IS_INTEGER) s7_pointer r1, r2, p; s7_int i1, i2; r1 = car(args); if (!s7_is_integer(r1)) method_or_bust(sc, r1, sc->RANDOM_STATE, args, T_INTEGER, 1); i1 = s7_integer(r1); if (i1 < 0) return(out_of_range(sc, sc->RANDOM_STATE, small_int(1), r1, ITS_NEGATIVE)); if (is_null(cdr(args))) { new_cell(sc, p, T_RANDOM_STATE); random_seed(p) = (unsigned long long int)i1; random_carry(p) = 1675393560; /* should this be dependent on the seed? */ return(p); } r2 = cadr(args); if (!s7_is_integer(r2)) method_or_bust(sc, r2, sc->RANDOM_STATE, args, T_INTEGER, 2); i2 = s7_integer(r2); if (i2 < 0) return(out_of_range(sc, sc->RANDOM_STATE, small_int(2), r2, ITS_NEGATIVE)); new_cell(sc, p, T_RANDOM_STATE); random_seed(p) = (unsigned long long int)i1; random_carry(p) = (unsigned long long int)i2; return(p); } #define g_random_state s7_random_state static s7_pointer c_random_state(s7_scheme *sc, s7_pointer x) {return(s7_random_state(sc, set_plist_1(sc, x)));} PF_TO_PF(random_state, c_random_state) #endif static s7_pointer rng_copy(s7_scheme *sc, s7_pointer args) { #if WITH_GMP return(sc->F); /* I can't find a way to copy a gmp random generator */ #else s7_pointer obj; obj = car(args); if (is_random_state(obj)) { s7_pointer new_r; new_cell(sc, new_r, T_RANDOM_STATE); random_seed(new_r) = random_seed(obj); random_carry(new_r) = random_carry(obj); return(new_r); } return(sc->F); #endif } static s7_pointer g_is_random_state(s7_scheme *sc, s7_pointer args) { #define H_is_random_state "(random-state? obj) returns #t if obj is a random-state object (from random-state)." #define Q_is_random_state pl_bt check_boolean_method(sc, is_random_state, sc->IS_RANDOM_STATE, args); } s7_pointer s7_random_state_to_list(s7_scheme *sc, s7_pointer args) { #define H_random_state_to_list "(random-state->list r) returns the random state object as a list.\ You can later apply random-state to this list to continue a random number sequence from any point." #define Q_random_state_to_list s7_make_signature(sc, 2, sc->IS_PAIR, sc->IS_RANDOM_STATE) #if WITH_GMP if ((is_pair(args)) && (!is_random_state(car(args)))) method_or_bust_with_type(sc, car(args), sc->RANDOM_STATE_TO_LIST, args, A_RANDOM_STATE_OBJECT, 1); return(sc->NIL); #else s7_pointer r; if (is_null(args)) r = sc->default_rng; else { r = car(args); if (!is_random_state(r)) method_or_bust_with_type(sc, r, sc->RANDOM_STATE_TO_LIST, args, A_RANDOM_STATE_OBJECT, 1); } return(list_2(sc, make_integer(sc, random_seed(r)), make_integer(sc, random_carry(r)))); #endif } #define g_random_state_to_list s7_random_state_to_list s7_pointer c_random_state_to_list(s7_scheme *sc, s7_pointer x) {return(s7_random_state_to_list(sc, set_plist_1(sc, x)));} PF_TO_PF(random_state_to_list, c_random_state_to_list) void s7_set_default_random_state(s7_scheme *sc, s7_int seed, s7_int carry) { #if (!WITH_GMP) s7_pointer p; new_cell(sc, p, T_RANDOM_STATE); random_seed(p) = (unsigned long long int)seed; random_carry(p) = (unsigned long long int)carry; sc->default_rng = p; #endif } #if (!WITH_GMP) /* -------------------------------- random -------------------------------- */ static double next_random(s7_pointer r) { /* The multiply-with-carry generator for 32-bit integers: * x(n)=a*x(n-1) + carry mod 2^32 * Choose multiplier a from this list: * 1791398085 1929682203 1683268614 1965537969 1675393560 * 1967773755 1517746329 1447497129 1655692410 1606218150 * 2051013963 1075433238 1557985959 1781943330 1893513180 * 1631296680 2131995753 2083801278 1873196400 1554115554 * ( or any 'a' for which both a*2^32-1 and a*2^31-1 are prime) */ double result; unsigned long long int temp; #define RAN_MULT 2131995753UL temp = random_seed(r) * RAN_MULT + random_carry(r); random_seed(r) = (temp & 0xffffffffUL); random_carry(r) = (temp >> 32); result = (double)((unsigned int)(random_seed(r))) / 4294967295.5; /* divisor was 2^32-1 = 4294967295.0, but somehow this can round up once in a billion tries? * do we want the double just less than 2^32? */ /* (let ((mx 0) (mn 1000)) (do ((i 0 (+ i 1))) ((= i 10000)) (let ((val (random 123))) (set! mx (max mx val)) (set! mn (min mn val)))) (list mn mx)) */ return(result); } s7_double s7_random(s7_scheme *sc, s7_pointer state) { if (!state) return(next_random(sc->default_rng)); return(next_random(state)); } static s7_pointer g_random(s7_scheme *sc, s7_pointer args) { #define H_random "(random num (state #f)) returns a random number between 0 and num (0 if num=0)." #define Q_random s7_make_signature(sc, 3, sc->IS_NUMBER, sc->IS_NUMBER, sc->IS_RANDOM_STATE) s7_pointer r, num; num = car(args); if (!s7_is_number(num)) method_or_bust_with_type(sc, num, sc->RANDOM, args, A_NUMBER, 1); if (is_not_null(cdr(args))) { r = cadr(args); if (!is_random_state(r)) method_or_bust_with_type(sc, r, sc->RANDOM, args, A_RANDOM_STATE_OBJECT, 2); } else r = sc->default_rng; switch (type(num)) { case T_INTEGER: return(make_integer(sc, (s7_int)(integer(num) * next_random(r)))); case T_RATIO: { s7_double x, error; s7_int numer = 0, denom = 1; /* the error here needs to take the size of the fraction into account. Otherwise, if * error is (say) 1e-6 and the fraction is (say) 9000000/9223372036854775807, * c_rationalize will always return 0. But even that isn't foolproof: * (random 1/562949953421312) -> 1/376367230475000 */ x = fraction(num); if ((x < 1.0e-10) && (x > -1.0e-10)) { /* 1e-12 is not tight enough: * (random 1/2251799813685248) -> 1/2250240579436280 * (random -1/4503599627370496) -> -1/4492889778435526 * (random 1/140737488355328) -> 1/140730223985746 * (random -1/35184372088832) -> -1/35183145492420 * (random -1/70368744177664) -> -1/70366866392738 * (random 1/4398046511104) -> 1/4398033095756 * (random 1/137438953472) -> 1/137438941127 */ if (numerator(num) < -10) numer = -(s7_int)(floor(-numerator(num) * next_random(r))); else { if (numerator(num) > 10) numer = (s7_int)floor(numerator(num) * next_random(r)); else { long long int diff; numer = numerator(num); diff = s7_int_max - denominator(num); if (diff < 100) return(s7_make_ratio(sc, numer, denominator(num))); denom = denominator(num) + (s7_int)floor(diff * next_random(r)); return(s7_make_ratio(sc, numer, denom)); } } return(s7_make_ratio(sc, numer, denominator(num))); } if ((x < 1e-6) && (x > -1e-6)) error = 1e-18; else error = 1e-12; c_rationalize(x * next_random(r), error, &numer, &denom); return(s7_make_ratio(sc, numer, denom)); } case T_REAL: return(make_real(sc, real(num) * next_random(r))); case T_COMPLEX: return(s7_make_complex(sc, real_part(num) * next_random(r), imag_part(num) * next_random(r))); } return(sc->F); } static s7_int c_random_i(s7_scheme *sc, s7_int arg) {return((s7_int)(arg * next_random(sc->default_rng)));} /* not round! */ IF_TO_IF(random, c_random_i) static s7_double c_random_r(s7_scheme *sc, s7_double arg) {return(arg * next_random(sc->default_rng));} RF_TO_RF(random, c_random_r) static s7_pointer random_ic, random_rc, random_i; static s7_pointer g_random_ic(s7_scheme *sc, s7_pointer args) { return(make_integer(sc, (s7_int)(integer(car(args)) * next_random(sc->default_rng)))); } static s7_pointer g_random_i(s7_scheme *sc, s7_pointer args) { return(make_integer(sc, (s7_int)(integer(slot_value(global_slot(car(args)))) * next_random(sc->default_rng)))); } static s7_pointer g_random_rc(s7_scheme *sc, s7_pointer args) { return(make_real(sc, real(car(args)) * next_random(sc->default_rng))); } static s7_pointer random_chooser(s7_scheme *sc, s7_pointer f, int args, s7_pointer expr) { if (args == 1) { s7_pointer arg1; arg1 = cadr(expr); if (s7_is_integer(arg1)) { set_optimize_op(expr, HOP_SAFE_C_C); return(random_ic); } if ((is_real(arg1)) && (!is_rational(arg1))) { set_optimize_op(expr, HOP_SAFE_C_C); return(random_rc); } if ((is_symbol(arg1)) && (is_immutable_symbol(arg1)) && (is_global(arg1)) && (is_integer(slot_value(global_slot(arg1))))) { set_optimize_op(expr, HOP_SAFE_C_C); return(random_i); } } return(f); } #endif /* gmp */ /* -------------------------------- characters -------------------------------- */ #define NUM_CHARS 256 static s7_pointer g_char_to_integer(s7_scheme *sc, s7_pointer args) { #define H_char_to_integer "(char->integer c) converts the character c to an integer" #define Q_char_to_integer s7_make_signature(sc, 2, sc->IS_INTEGER, sc->IS_CHAR) if (!s7_is_character(car(args))) method_or_bust(sc, car(args), sc->CHAR_TO_INTEGER, args, T_CHARACTER, 0); return(small_int(character(car(args)))); } #define int_method_or_bust(Sc, Obj, Method, Args, Type, Num) \ { \ s7_pointer func; \ if ((has_methods(Obj)) && ((func = find_method(Sc, find_let(Sc, Obj), Method)) != Sc->UNDEFINED)) \ return(integer(s7_apply_function(Sc, func, Args))); \ if (Num == 0) simple_wrong_type_argument(Sc, Method, Obj, Type); \ wrong_type_argument(Sc, Method, Num, Obj, Type); \ } static s7_int c_char_to_integer(s7_scheme *sc, s7_pointer p) { if (!s7_is_character(p)) int_method_or_bust(sc, p, sc->CHAR_TO_INTEGER, set_plist_1(sc, p), T_CHARACTER, 0); return(character(p)); } PF_TO_IF(char_to_integer, c_char_to_integer) static s7_pointer c_int_to_char(s7_scheme *sc, s7_int ind) { if ((ind < 0) || (ind >= NUM_CHARS)) return(simple_wrong_type_argument_with_type(sc, sc->INTEGER_TO_CHAR, make_integer(sc, ind), make_string_wrapper(sc, "an integer that can represent a character"))); return(s7_make_character(sc, (unsigned char)ind)); } static s7_pointer c_integer_to_char(s7_scheme *sc, s7_pointer x) { s7_int ind; if (!s7_is_integer(x)) method_or_bust(sc, x, sc->INTEGER_TO_CHAR, list_1(sc, x), T_INTEGER, 0); ind = s7_integer(x); if ((ind < 0) || (ind >= NUM_CHARS)) return(simple_wrong_type_argument_with_type(sc, sc->INTEGER_TO_CHAR, x, make_string_wrapper(sc, "an integer that can represent a character"))); return(s7_make_character(sc, (unsigned char)ind)); } static s7_pointer g_integer_to_char(s7_scheme *sc, s7_pointer args) { #define H_integer_to_char "(integer->char i) converts the non-negative integer i to a character" #define Q_integer_to_char s7_make_signature(sc, 2, sc->IS_CHAR, sc->IS_INTEGER) return(c_integer_to_char(sc, car(args))); } IF_TO_PF(integer_to_char, c_int_to_char) static unsigned char uppers[256], lowers[256]; static void init_uppers(void) { int i; for (i = 0; i < 256; i++) { uppers[i] = (unsigned char)toupper(i); lowers[i] = (unsigned char)tolower(i); } } static s7_pointer c_char_upcase(s7_scheme *sc, s7_pointer arg) { if (!s7_is_character(arg)) method_or_bust(sc, arg, sc->CHAR_UPCASE, set_plist_1(sc, arg), T_CHARACTER, 0); return(s7_make_character(sc, upper_character(arg))); } static s7_pointer g_char_upcase(s7_scheme *sc, s7_pointer args) { #define H_char_upcase "(char-upcase c) converts the character c to upper case" #define Q_char_upcase pcl_c if (!s7_is_character(car(args))) method_or_bust(sc, car(args), sc->CHAR_UPCASE, args, T_CHARACTER, 0); return(s7_make_character(sc, upper_character(car(args)))); } PF_TO_PF(char_upcase, c_char_upcase) static s7_pointer c_char_downcase(s7_scheme *sc, s7_pointer arg) { if (!s7_is_character(arg)) method_or_bust(sc, arg, sc->CHAR_DOWNCASE, set_plist_1(sc, arg), T_CHARACTER, 0); return(s7_make_character(sc, lowers[(int)character(arg)])); } static s7_pointer g_char_downcase(s7_scheme *sc, s7_pointer args) { #define H_char_downcase "(char-downcase c) converts the character c to lower case" #define Q_char_downcase pcl_c if (!s7_is_character(car(args))) method_or_bust(sc, car(args), sc->CHAR_DOWNCASE, args, T_CHARACTER, 0); return(s7_make_character(sc, lowers[character(car(args))])); } PF_TO_PF(char_downcase, c_char_downcase) static s7_pointer c_is_char_alphabetic(s7_scheme *sc, s7_pointer arg) { if (!s7_is_character(arg)) method_or_bust(sc, arg, sc->IS_CHAR_ALPHABETIC, set_plist_1(sc, arg), T_CHARACTER, 0); return(make_boolean(sc, is_char_alphabetic(arg))); } static s7_pointer g_is_char_alphabetic(s7_scheme *sc, s7_pointer args) { #define H_is_char_alphabetic "(char-alphabetic? c) returns #t if the character c is alphabetic" #define Q_is_char_alphabetic pl_bc if (!s7_is_character(car(args))) method_or_bust(sc, car(args), sc->IS_CHAR_ALPHABETIC, args, T_CHARACTER, 0); return(make_boolean(sc, is_char_alphabetic(car(args)))); /* isalpha returns #t for (integer->char 226) and others in that range */ } PF_TO_PF(is_char_alphabetic, c_is_char_alphabetic) static s7_pointer c_is_char_numeric(s7_scheme *sc, s7_pointer arg) { if (!s7_is_character(arg)) method_or_bust(sc, arg, sc->IS_CHAR_NUMERIC, set_plist_1(sc, arg), T_CHARACTER, 0); return(make_boolean(sc, is_char_numeric(arg))); } static s7_pointer g_is_char_numeric(s7_scheme *sc, s7_pointer args) { #define H_is_char_numeric "(char-numeric? c) returns #t if the character c is a digit" #define Q_is_char_numeric pl_bc return(c_is_char_numeric(sc, car(args))); } PF_TO_PF(is_char_numeric, c_is_char_numeric) static s7_pointer c_is_char_whitespace(s7_scheme *sc, s7_pointer arg) { if (!s7_is_character(arg)) method_or_bust(sc, arg, sc->IS_CHAR_WHITESPACE, set_plist_1(sc, arg), T_CHARACTER, 0); return(make_boolean(sc, is_char_whitespace(arg))); } static s7_pointer g_is_char_whitespace(s7_scheme *sc, s7_pointer args) { #define H_is_char_whitespace "(char-whitespace? c) returns #t if the character c is non-printing character" #define Q_is_char_whitespace pl_bc return(c_is_char_whitespace(sc, car(args))); } PF_TO_PF(is_char_whitespace, c_is_char_whitespace) static s7_pointer c_is_char_upper_case(s7_scheme *sc, s7_pointer arg) { if (!s7_is_character(arg)) method_or_bust(sc, arg, sc->IS_CHAR_UPPER_CASE, set_plist_1(sc, arg), T_CHARACTER, 0); return(make_boolean(sc, is_char_uppercase(arg))); } static s7_pointer g_is_char_upper_case(s7_scheme *sc, s7_pointer args) { #define H_is_char_upper_case "(char-upper-case? c) returns #t if the character c is in upper case" #define Q_is_char_upper_case pl_bc return(c_is_char_upper_case(sc, car(args))); } PF_TO_PF(is_char_upper_case, c_is_char_upper_case) static s7_pointer c_is_char_lower_case(s7_scheme *sc, s7_pointer arg) { if (!s7_is_character(arg)) method_or_bust(sc, arg, sc->IS_CHAR_LOWER_CASE, set_plist_1(sc, arg), T_CHARACTER, 0); return(make_boolean(sc, is_char_lowercase(arg))); } static s7_pointer g_is_char_lower_case(s7_scheme *sc, s7_pointer args) { #define H_is_char_lower_case "(char-lower-case? c) returns #t if the character c is in lower case" #define Q_is_char_lower_case pl_bc return(c_is_char_lower_case(sc, car(args))); } PF_TO_PF(is_char_lower_case, c_is_char_lower_case) static s7_pointer g_is_char(s7_scheme *sc, s7_pointer args) { #define H_is_char "(char? obj) returns #t if obj is a character" #define Q_is_char pl_bt check_boolean_method(sc, s7_is_character, sc->IS_CHAR, args); } s7_pointer s7_make_character(s7_scheme *sc, unsigned int c) { return(chars[c]); } bool s7_is_character(s7_pointer p) { return(type(p) == T_CHARACTER); } char s7_character(s7_pointer p) { return(character(p)); } static int charcmp(unsigned char c1, unsigned char c2) { return((c1 == c2) ? 0 : (c1 < c2) ? -1 : 1); /* not tolower here -- the single case is apparently supposed to be upper case * this matters in a case like (char-ciIS_CHAR); if (f != sc->UNDEFINED) return(is_true(sc, s7_apply_function(sc, f, cons(sc, p, sc->NIL)))); } return(false); } static s7_pointer g_char_cmp(s7_scheme *sc, s7_pointer args, int val, s7_pointer sym) { s7_pointer x, y; y = car(args); if (!s7_is_character(y)) method_or_bust(sc, y, sym, args, T_CHARACTER, 1); for (x = cdr(args); is_pair(x); x = cdr(x)) { if (!s7_is_character(car(x))) method_or_bust(sc, car(x), sym, cons(sc, y, x), T_CHARACTER, position_of(x, args)); if (charcmp(character(y), character(car(x))) != val) { for (y = cdr(x); is_pair(y); y = cdr(y)) if (!is_character_via_method(sc, car(y))) return(wrong_type_argument(sc, sym, position_of(y, args), car(y), T_CHARACTER)); return(sc->F); } y = car(x); } return(sc->T); } static s7_pointer g_char_cmp_not(s7_scheme *sc, s7_pointer args, int val, s7_pointer sym) { s7_pointer x, y; y = car(args); if (!s7_is_character(y)) method_or_bust(sc, y, sym, args, T_CHARACTER, 1); for (x = cdr(args); is_pair(x); x = cdr(x)) { if (!s7_is_character(car(x))) method_or_bust(sc, car(x), sym, cons(sc, y, x), T_CHARACTER, position_of(x, args)); if (charcmp(character(y), character(car(x))) == val) { for (y = cdr(x); is_pair(y); y = cdr(y)) if (!is_character_via_method(sc, car(y))) return(wrong_type_argument(sc, sym, position_of(y, args), car(y), T_CHARACTER)); return(sc->F); } y = car(x); } return(sc->T); } static s7_pointer g_chars_are_equal(s7_scheme *sc, s7_pointer args) { #define H_chars_are_equal "(char=? char ...) returns #t if all the character arguments are equal" #define Q_chars_are_equal pcl_bc s7_pointer x, y; y = car(args); if (!s7_is_character(y)) method_or_bust(sc, y, sc->CHAR_EQ, args, T_CHARACTER, 1); for (x = cdr(args); is_pair(x); x = cdr(x)) { if (!s7_is_character(car(x))) method_or_bust(sc, car(x), sc->CHAR_EQ, cons(sc, y, x), T_CHARACTER, position_of(x, args)); if (car(x) != y) { for (y = cdr(x); is_pair(y); y = cdr(y)) if (!is_character_via_method(sc, car(y))) return(wrong_type_argument(sc, sc->CHAR_EQ, position_of(y, args), car(y), T_CHARACTER)); return(sc->F); } } return(sc->T); } static s7_pointer g_chars_are_less(s7_scheme *sc, s7_pointer args) { #define H_chars_are_less "(charCHAR_LT)); } static s7_pointer g_chars_are_greater(s7_scheme *sc, s7_pointer args) { #define H_chars_are_greater "(char>? char ...) returns #t if all the character arguments are decreasing" #define Q_chars_are_greater pcl_bc return(g_char_cmp(sc, args, 1, sc->CHAR_GT)); } static s7_pointer g_chars_are_geq(s7_scheme *sc, s7_pointer args) { #define H_chars_are_geq "(char>=? char ...) returns #t if all the character arguments are equal or decreasing" #define Q_chars_are_geq pcl_bc return(g_char_cmp_not(sc, args, -1, sc->CHAR_GEQ)); } static s7_pointer g_chars_are_leq(s7_scheme *sc, s7_pointer args) { #define H_chars_are_leq "(char<=? char ...) returns #t if all the character arguments are equal or increasing" #define Q_chars_are_leq pcl_bc return(g_char_cmp_not(sc, args, 1, sc->CHAR_LEQ)); } static s7_pointer simple_char_eq; static s7_pointer g_simple_char_eq(s7_scheme *sc, s7_pointer args) { return(make_boolean(sc, character(car(args)) == character(cadr(args)))); } static s7_pointer c_char_eq(s7_scheme *sc, s7_pointer x, s7_pointer y) { if (!s7_is_character(x)) method_or_bust(sc, x, sc->CHAR_EQ, list_2(sc, x, y), T_CHARACTER, 1); if (!s7_is_character(y)) method_or_bust(sc, y, sc->CHAR_EQ, list_2(sc, x, y), T_CHARACTER, 2); return(make_boolean(sc, x == y)); } static s7_pointer s7_procedure_signature(s7_scheme *sc, s7_pointer x); static bool char_check(s7_scheme *sc, s7_pointer obj) { if (s7_is_character(obj)) return(true); if ((is_pair(obj)) && (is_symbol(car(obj)))) { s7_pointer sig; sig = s7_procedure_signature(sc, s7_symbol_value(sc, car(obj))); return((sig) && (is_pair(sig)) && (car(sig) == sc->IS_CHAR)); } return(false); } PF2_TO_PF_X(char_eq, char_check, c_char_eq, c_is_eq) static s7_pointer char_equal_s_ic, char_equal_2; static s7_pointer g_char_equal_s_ic(s7_scheme *sc, s7_pointer args) { s7_pointer c; c = find_symbol_checked(sc, car(args)); if (c == cadr(args)) return(sc->T); if (s7_is_character(c)) return(sc->F); method_or_bust(sc, c, sc->CHAR_EQ, list_2(sc, c, cadr(args)), T_CHARACTER, 1); } static s7_pointer g_char_equal_2(s7_scheme *sc, s7_pointer args) { if (!s7_is_character(car(args))) method_or_bust(sc, car(args), sc->CHAR_EQ, args, T_CHARACTER, 1); if (car(args) == cadr(args)) return(sc->T); if (!s7_is_character(cadr(args))) method_or_bust(sc, cadr(args), sc->CHAR_EQ, args, T_CHARACTER, 2); return(sc->F); } static s7_pointer char_less_s_ic, char_less_2; static s7_pointer g_char_less_s_ic(s7_scheme *sc, s7_pointer args) { if (!s7_is_character(car(args))) method_or_bust(sc, car(args), sc->CHAR_LT, args, T_CHARACTER, 1); return(make_boolean(sc, character(car(args)) < character(cadr(args)))); } static s7_pointer g_char_less_2(s7_scheme *sc, s7_pointer args) { if (!s7_is_character(car(args))) method_or_bust(sc, car(args), sc->CHAR_LT, args, T_CHARACTER, 1); if (!s7_is_character(cadr(args))) method_or_bust(sc, cadr(args), sc->CHAR_LT, args, T_CHARACTER, 2); return(make_boolean(sc, character(car(args)) < character(cadr(args)))); } static s7_pointer c_char_lt(s7_scheme *sc, s7_pointer x, s7_pointer y) { if (!s7_is_character(x)) method_or_bust(sc, x, sc->CHAR_LT, list_2(sc, x, y), T_CHARACTER, 1); if (!s7_is_character(y)) method_or_bust(sc, y, sc->CHAR_LT, list_2(sc, x, y), T_CHARACTER, 2); return(make_boolean(sc, character(x) < character(y))); } static s7_pointer c_clt(s7_scheme *sc, s7_pointer x, s7_pointer y) { return(make_boolean(sc, character(x) < character(y))); } PF2_TO_PF_X(char_lt, char_check, c_char_lt, c_clt) static s7_pointer char_greater_s_ic, char_greater_2; static s7_pointer g_char_greater_s_ic(s7_scheme *sc, s7_pointer args) { if (!s7_is_character(car(args))) method_or_bust(sc, car(args), sc->CHAR_GT, args, T_CHARACTER, 1); return(make_boolean(sc, character(car(args)) > character(cadr(args)))); } static s7_pointer g_char_greater_2(s7_scheme *sc, s7_pointer args) { if (!s7_is_character(car(args))) method_or_bust(sc, car(args), sc->CHAR_GT, args, T_CHARACTER, 1); if (!s7_is_character(cadr(args))) method_or_bust(sc, cadr(args), sc->CHAR_GT, args, T_CHARACTER, 2); return(make_boolean(sc, character(car(args)) > character(cadr(args)))); } static s7_pointer c_char_gt(s7_scheme *sc, s7_pointer x, s7_pointer y) { if (!s7_is_character(x)) method_or_bust(sc, x, sc->CHAR_GT, list_2(sc, x, y), T_CHARACTER, 1); if (!s7_is_character(y)) method_or_bust(sc, y, sc->CHAR_GT, list_2(sc, x, y), T_CHARACTER, 2); return(make_boolean(sc, character(x) > character(y))); } static s7_pointer c_cgt(s7_scheme *sc, s7_pointer x, s7_pointer y) { return(make_boolean(sc, character(x) > character(y))); } PF2_TO_PF_X(char_gt, char_check, c_char_gt, c_cgt) static s7_pointer c_char_geq(s7_scheme *sc, s7_pointer x, s7_pointer y) { if (!s7_is_character(x)) method_or_bust(sc, x, sc->CHAR_GEQ, list_2(sc, x, y), T_CHARACTER, 1); if (!s7_is_character(y)) method_or_bust(sc, y, sc->CHAR_GEQ, list_2(sc, x, y), T_CHARACTER, 2); return(make_boolean(sc, character(x) >= character(y))); } PF2_TO_PF(char_geq, c_char_geq) static s7_pointer c_char_leq(s7_scheme *sc, s7_pointer x, s7_pointer y) { if (!s7_is_character(x)) method_or_bust(sc, x, sc->CHAR_LEQ, list_2(sc, x, y), T_CHARACTER, 1); if (!s7_is_character(y)) method_or_bust(sc, y, sc->CHAR_LEQ, list_2(sc, x, y), T_CHARACTER, 2); return(make_boolean(sc, character(x) <= character(y))); } PF2_TO_PF(char_leq, c_char_leq) #if (!WITH_PURE_S7) static s7_pointer g_char_cmp_ci(s7_scheme *sc, s7_pointer args, int val, s7_pointer sym) { s7_pointer x, y; y = car(args); if (!s7_is_character(y)) method_or_bust(sc, y, sym, args, T_CHARACTER, 1); for (x = cdr(args); is_pair(x); x = cdr(x)) { if (!s7_is_character(car(x))) method_or_bust(sc, car(x), sym, cons(sc, y, x), T_CHARACTER, position_of(x, args)); if (charcmp(upper_character(y), upper_character(car(x))) != val) { for (y = cdr(x); is_pair(y); y = cdr(y)) if (!is_character_via_method(sc, car(y))) return(wrong_type_argument(sc, sym, position_of(y, args), car(y), T_CHARACTER)); return(sc->F); } y = car(x); } return(sc->T); } static s7_pointer g_char_cmp_ci_not(s7_scheme *sc, s7_pointer args, int val, s7_pointer sym) { s7_pointer x, y; y = car(args); if (!s7_is_character(y)) method_or_bust(sc, y, sym, args, T_CHARACTER, 1); for (x = cdr(args); is_pair(x); x = cdr(x)) { if (!s7_is_character(car(x))) method_or_bust(sc, car(x), sym, cons(sc, y, x), T_CHARACTER, position_of(x, args)); if (charcmp(upper_character(y), upper_character(car(x))) == val) { for (y = cdr(x); is_pair(y); y = cdr(y)) if (!is_character_via_method(sc, car(y))) return(wrong_type_argument(sc, sym, position_of(y, args), car(y), T_CHARACTER)); return(sc->F); } y = car(x); } return(sc->T); } static s7_pointer g_chars_are_ci_equal(s7_scheme *sc, s7_pointer args) { #define H_chars_are_ci_equal "(char-ci=? char ...) returns #t if all the character arguments are equal, ignoring case" #define Q_chars_are_ci_equal pcl_bc return(g_char_cmp_ci(sc, args, 0, sc->CHAR_CI_EQ)); } static s7_pointer c_char_ci_eq(s7_scheme *sc, s7_pointer x, s7_pointer y) { if (!s7_is_character(x)) method_or_bust(sc, x, sc->CHAR_CI_EQ, list_2(sc, x, y), T_CHARACTER, 1); if (!s7_is_character(y)) method_or_bust(sc, y, sc->CHAR_CI_EQ, list_2(sc, x, y), T_CHARACTER, 2); return(make_boolean(sc, upper_character(x) == upper_character(y))); } PF2_TO_PF(char_ci_eq, c_char_ci_eq) static s7_pointer g_chars_are_ci_less(s7_scheme *sc, s7_pointer args) { #define H_chars_are_ci_less "(char-ciCHAR_CI_LT)); } static s7_pointer c_char_ci_lt(s7_scheme *sc, s7_pointer x, s7_pointer y) { if (!s7_is_character(x)) method_or_bust(sc, x, sc->CHAR_CI_LT, list_2(sc, x, y), T_CHARACTER, 1); if (!s7_is_character(y)) method_or_bust(sc, y, sc->CHAR_CI_LT, list_2(sc, x, y), T_CHARACTER, 2); return(make_boolean(sc, upper_character(x) < upper_character(y))); } PF2_TO_PF(char_ci_lt, c_char_ci_lt) static s7_pointer g_chars_are_ci_greater(s7_scheme *sc, s7_pointer args) { #define H_chars_are_ci_greater "(char-ci>? char ...) returns #t if all the character arguments are decreasing, ignoring case" #define Q_chars_are_ci_greater pcl_bc return(g_char_cmp_ci(sc, args, 1, sc->CHAR_CI_GT)); } static s7_pointer c_char_ci_gt(s7_scheme *sc, s7_pointer x, s7_pointer y) { if (!s7_is_character(x)) method_or_bust(sc, x, sc->CHAR_CI_GT, list_2(sc, x, y), T_CHARACTER, 1); if (!s7_is_character(y)) method_or_bust(sc, y, sc->CHAR_CI_GT, list_2(sc, x, y), T_CHARACTER, 2); return(make_boolean(sc, upper_character(x) > upper_character(y))); } PF2_TO_PF(char_ci_gt, c_char_ci_gt) static s7_pointer g_chars_are_ci_geq(s7_scheme *sc, s7_pointer args) { #define H_chars_are_ci_geq "(char-ci>=? char ...) returns #t if all the character arguments are equal or decreasing, ignoring case" #define Q_chars_are_ci_geq pcl_bc return(g_char_cmp_ci_not(sc, args, -1, sc->CHAR_CI_GEQ)); } static s7_pointer c_char_ci_geq(s7_scheme *sc, s7_pointer x, s7_pointer y) { if (!s7_is_character(x)) method_or_bust(sc, x, sc->CHAR_CI_GEQ, list_2(sc, x, y), T_CHARACTER, 1); if (!s7_is_character(y)) method_or_bust(sc, y, sc->CHAR_CI_GEQ, list_2(sc, x, y), T_CHARACTER, 2); return(make_boolean(sc, upper_character(x) >= upper_character(y))); } PF2_TO_PF(char_ci_geq, c_char_ci_geq) static s7_pointer g_chars_are_ci_leq(s7_scheme *sc, s7_pointer args) { #define H_chars_are_ci_leq "(char-ci<=? char ...) returns #t if all the character arguments are equal or increasing, ignoring case" #define Q_chars_are_ci_leq pcl_bc return(g_char_cmp_ci_not(sc, args, 1, sc->CHAR_CI_LEQ)); } static s7_pointer c_char_ci_leq(s7_scheme *sc, s7_pointer x, s7_pointer y) { if (!s7_is_character(x)) method_or_bust(sc, x, sc->CHAR_CI_LEQ, list_2(sc, x, y), T_CHARACTER, 1); if (!s7_is_character(y)) method_or_bust(sc, y, sc->CHAR_CI_LEQ, list_2(sc, x, y), T_CHARACTER, 2); return(make_boolean(sc, upper_character(x) <= upper_character(y))); } PF2_TO_PF(char_ci_leq, c_char_ci_leq) #endif /* not pure s7 */ static s7_pointer g_char_position(s7_scheme *sc, s7_pointer args) { #define H_char_position "(char-position char-or-str str (start 0)) returns the position of the first occurrence of char in str, or #f" #define Q_char_position s7_make_signature(sc, 4, s7_make_signature(sc, 2, sc->IS_INTEGER, sc->IS_BOOLEAN), s7_make_signature(sc, 2, sc->IS_CHAR, sc->IS_STRING), sc->IS_STRING, sc->IS_INTEGER) const char *porig, *p, *pset; s7_int start, pos, len; /* not "int" because start arg might be most-negative-fixnum */ s7_pointer arg1, arg2; arg1 = car(args); if ((!s7_is_character(arg1)) && (!is_string(arg1))) method_or_bust(sc, arg1, sc->CHAR_POSITION, args, T_CHARACTER, 1); arg2 = cadr(args); if (!is_string(arg2)) method_or_bust(sc, arg2, sc->CHAR_POSITION, args, T_STRING, 2); porig = string_value(arg2); len = string_length(arg2); if (is_pair(cddr(args))) { s7_pointer arg3; arg3 = caddr(args); if (!s7_is_integer(arg3)) { s7_pointer p; if (!s7_is_integer(p = check_values(sc, arg3, cddr(args)))) method_or_bust(sc, arg3, sc->CHAR_POSITION, args, T_INTEGER, 3); arg3 = p; } start = s7_integer(arg3); if (start < 0) return(wrong_type_argument_with_type(sc, sc->CHAR_POSITION, 3, arg3, A_NON_NEGATIVE_INTEGER)); } else start = 0; if (start >= len) return(sc->F); if (s7_is_character(arg1)) { char c; c = character(arg1); p = strchr((const char *)(porig + start), (int)c); /* use strchrnul in Gnu C to catch embedded null case */ if (p) return(make_integer(sc, p - porig)); return(sc->F); } if (string_length(arg1) == 0) return(sc->F); pset = string_value(arg1); pos = strcspn((const char *)(porig + start), (const char *)pset); if ((pos + start) < len) return(make_integer(sc, pos + start)); /* but if the string has an embedded null, we can get erroneous results here -- * perhaps check for null at pos+start? What about a searched-for string that * also has embedded nulls? * * The embedded nulls are for byte-vector usages, where presumably you're not talking * about chars and strings, so I think I'll ignore these cases. In unicode, you'd * want to use unicode-aware searchers, so that also is irrelevant. */ return(sc->F); } static s7_pointer c_char_position_ppi(s7_scheme *sc, s7_pointer x, s7_pointer y, s7_int z) {return(g_char_position(sc, set_plist_3(sc, x, y, make_integer(sc, z))));} static s7_pointer c_char_position_pp(s7_scheme *sc, s7_pointer x, s7_pointer y) {return(g_char_position(sc, set_plist_2(sc, x, y)));} PPIF_TO_PF(char_position, c_char_position_pp, c_char_position_ppi) static s7_pointer char_position_csi; static s7_pointer g_char_position_csi(s7_scheme *sc, s7_pointer args) { /* assume char arg1, no end */ const char *porig, *p; char c; s7_pointer arg2; s7_int start, len; c = character(car(args)); arg2 = cadr(args); if (!is_string(arg2)) return(g_char_position(sc, args)); len = string_length(arg2); /* can't return #f here if len==0 -- need start error check first */ porig = string_value(arg2); if (is_pair(cddr(args))) { s7_pointer arg3; arg3 = caddr(args); if (!s7_is_integer(arg3)) return(g_char_position(sc, args)); start = s7_integer(arg3); if (start < 0) return(wrong_type_argument_with_type(sc, sc->CHAR_POSITION, 3, arg3, A_NON_NEGATIVE_INTEGER)); if (start >= len) return(sc->F); } else start = 0; if (len == 0) return(sc->F); p = strchr((const char *)(porig + start), (int)c); if (p) return(make_integer(sc, p - porig)); return(sc->F); } static s7_pointer g_string_position(s7_scheme *sc, s7_pointer args) { #define H_string_position "(string-position str1 str2 (start 0)) returns the starting position of str1 in str2 or #f" #define Q_string_position s7_make_signature(sc, 4, s7_make_signature(sc, 2, sc->IS_INTEGER, sc->IS_BOOLEAN), sc->IS_STRING, sc->IS_STRING, sc->IS_INTEGER) const char *s1, *s2, *p2; s7_int start = 0; s7_pointer s1p, s2p; s1p = car(args); if (!is_string(s1p)) method_or_bust(sc, s1p, sc->STRING_POSITION, args, T_STRING, 1); s2p = cadr(args); if (!is_string(s2p)) method_or_bust(sc, s2p, sc->STRING_POSITION, args, T_STRING, 2); if (is_pair(cddr(args))) { s7_pointer arg3; arg3 = caddr(args); if (!s7_is_integer(arg3)) { s7_pointer p; if (!s7_is_integer(p = check_values(sc, arg3, cddr(args)))) method_or_bust(sc, arg3, sc->STRING_POSITION, args, T_INTEGER, 3); arg3 = p; } start = s7_integer(arg3); if (start < 0) return(wrong_type_argument_with_type(sc, sc->STRING_POSITION, 3, arg3, A_NON_NEGATIVE_INTEGER)); } if (string_length(s1p) == 0) return(sc->F); s1 = string_value(s1p); s2 = string_value(s2p); if (start >= string_length(s2p)) return(sc->F); p2 = strstr((const char *)(s2 + start), s1); if (!p2) return(sc->F); return(make_integer(sc, p2 - s2)); } static s7_pointer c_string_position_ppi(s7_scheme *sc, s7_pointer x, s7_pointer y, s7_int z) {return(g_string_position(sc, set_plist_3(sc, x, y, make_integer(sc, z))));} static s7_pointer c_string_position_pp(s7_scheme *sc, s7_pointer x, s7_pointer y) {return(g_string_position(sc, set_plist_2(sc, x, y)));} PPIF_TO_PF(string_position, c_string_position_pp, c_string_position_ppi) /* -------------------------------- strings -------------------------------- */ s7_pointer s7_make_string_with_length(s7_scheme *sc, const char *str, int len) { s7_pointer x; new_cell(sc, x, T_STRING | T_SAFE_PROCEDURE); string_value(x) = (char *)malloc((len + 1) * sizeof(char)); if (len != 0) /* memcpy can segfault if string_value(x) is NULL */ memcpy((void *)string_value(x), (void *)str, len); string_value(x)[len] = 0; string_length(x) = len; string_hash(x) = 0; string_needs_free(x) = true; Add_String(x); return(x); } static s7_pointer make_string_uncopied_with_length(s7_scheme *sc, char *str, int len) { s7_pointer x; new_cell(sc, x, T_STRING | T_SAFE_PROCEDURE); string_value(x) = str; string_length(x) = len; string_hash(x) = 0; string_needs_free(x) = true; add_string(sc, x); return(x); } static s7_pointer make_string_wrapper_with_length(s7_scheme *sc, const char *str, int len) { s7_pointer x; new_cell(sc, x, T_STRING | T_IMMUTABLE | T_SAFE_PROCEDURE); string_value(x) = (char *)str; string_length(x) = len; string_hash(x) = 0; string_needs_free(x) = false; return(x); } static s7_pointer make_string_wrapper(s7_scheme *sc, const char *str) { return(make_string_wrapper_with_length(sc, str, safe_strlen(str))); } static s7_pointer make_empty_string(s7_scheme *sc, int len, char fill) { s7_pointer x; new_cell(sc, x, T_STRING); string_value(x) = (char *)malloc((len + 1) * sizeof(char)); if (fill != 0) memset((void *)(string_value(x)), fill, len); string_value(x)[len] = 0; string_hash(x) = 0; string_length(x) = len; string_needs_free(x) = true; add_string(sc, x); return(x); } s7_pointer s7_make_string(s7_scheme *sc, const char *str) { if (str) return(s7_make_string_with_length(sc, str, safe_strlen(str))); return(make_empty_string(sc, 0, 0)); } static char *make_permanent_string(const char *str) { char *x; int len; len = safe_strlen(str); x = (char *)malloc((len + 1) * sizeof(char)); memcpy((void *)x, (void *)str, len); x[len] = 0; return(x); } s7_pointer s7_make_permanent_string(const char *str) { /* for the symbol table which is never GC'd */ s7_pointer x; x = alloc_pointer(); unheap(x); set_type(x, T_STRING | T_IMMUTABLE); if (str) { unsigned int len; len = safe_strlen(str); string_length(x) = len; string_value(x) = (char *)malloc((len + 1) * sizeof(char)); memcpy((void *)string_value(x), (void *)str, len); string_value(x)[len] = 0; } else { string_value(x) = NULL; string_length(x) = 0; } string_hash(x) = 0; string_needs_free(x) = false; return(x); } static s7_pointer make_temporary_string(s7_scheme *sc, const char *str, int len) { s7_pointer p; p = sc->tmp_strs[0]; prepare_temporary_string(sc, len + 1, 0); string_length(p) = len; if (len > 0) memmove((void *)(string_value(p)), (void *)str, len); /* not memcpy because str might be a temp string (i.e. sc->tmp_str_chars -> itself) */ string_value(p)[len] = 0; return(p); } bool s7_is_string(s7_pointer p) { return(is_string(p)); } const char *s7_string(s7_pointer p) { return(string_value(p)); } static s7_pointer g_is_string(s7_scheme *sc, s7_pointer args) { #define H_is_string "(string? obj) returns #t if obj is a string" #define Q_is_string pl_bt check_boolean_method(sc, is_string, sc->IS_STRING, args); } /* -------------------------------- make-string -------------------------------- */ static s7_pointer g_make_string(s7_scheme *sc, s7_pointer args) { #define H_make_string "(make-string len (val #\\space)) makes a string of length len filled with the character val (default: space)" #define Q_make_string s7_make_signature(sc, 3, sc->IS_STRING, sc->IS_INTEGER, sc->IS_CHAR) s7_pointer n; s7_int len; char fill = ' '; n = car(args); if (!s7_is_integer(n)) { check_two_methods(sc, n, sc->MAKE_STRING, sc->MAKE_BYTE_VECTOR, args); return(wrong_type_argument(sc, sc->MAKE_STRING, 1, n, T_INTEGER)); } len = s7_integer(n); if ((len < 0) || (len > sc->max_string_length)) return(out_of_range(sc, sc->MAKE_STRING, small_int(1), n, (len < 0) ? ITS_NEGATIVE : ITS_TOO_LARGE)); if (is_not_null(cdr(args))) { if (!s7_is_character(cadr(args))) method_or_bust(sc, cadr(args), sc->MAKE_STRING, args, T_CHARACTER, 2); fill = s7_character(cadr(args)); } n = make_empty_string(sc, (int)len, fill); if (fill == '\0') memset((void *)string_value(n), 0, (int)len); return(n); } static s7_pointer c_make_string(s7_scheme *sc, s7_int len) {return(make_empty_string(sc, (int)len, ' '));} IF_TO_PF(make_string, c_make_string) #if (!WITH_PURE_S7) static s7_pointer g_string_length(s7_scheme *sc, s7_pointer args) { #define H_string_length "(string-length str) returns the length of the string str" #define Q_string_length s7_make_signature(sc, 2, sc->IS_INTEGER, sc->IS_STRING) s7_pointer p; p = car(args); if (!is_string(p)) method_or_bust(sc, p, sc->STRING_LENGTH, args, T_STRING, 0); return(make_integer(sc, string_length(p))); } static s7_int c_string_length(s7_scheme *sc, s7_pointer p) { if (!is_string(p)) int_method_or_bust(sc, p, sc->STRING_LENGTH, set_plist_1(sc, p), T_STRING, 0); return(string_length(p)); } PF_TO_IF(string_length, c_string_length) #endif /* -------------------------------- string-up|downcase -------------------------------- */ static s7_pointer c_string_downcase(s7_scheme *sc, s7_pointer p) { s7_pointer newstr; int i, len; unsigned char *nstr, *ostr; sc->temp3 = p; if (!is_string(p)) method_or_bust(sc, p, sc->STRING_DOWNCASE, list_1(sc, p), T_STRING, 0); len = string_length(p); newstr = make_empty_string(sc, len, 0); ostr = (unsigned char *)string_value(p); nstr = (unsigned char *)string_value(newstr); for (i = 0; i < len; i++) nstr[i] = lowers[(int)ostr[i]]; return(newstr); } static s7_pointer g_string_downcase(s7_scheme *sc, s7_pointer args) { #define H_string_downcase "(string-downcase str) returns the lower case version of str." #define Q_string_downcase pcl_s return(c_string_downcase(sc, car(args))); } PF_TO_PF(string_downcase, c_string_downcase) static s7_pointer c_string_upcase(s7_scheme *sc, s7_pointer p) { s7_pointer newstr; int i, len; unsigned char *nstr, *ostr; sc->temp3 = p; if (!is_string(p)) method_or_bust(sc, p, sc->STRING_UPCASE, list_1(sc, p), T_STRING, 0); len = string_length(p); newstr = make_empty_string(sc, len, 0); ostr = (unsigned char *)string_value(p); nstr = (unsigned char *)string_value(newstr); for (i = 0; i < len; i++) nstr[i] = uppers[(int)ostr[i]]; return(newstr); } static s7_pointer g_string_upcase(s7_scheme *sc, s7_pointer args) { #define H_string_upcase "(string-upcase str) returns the upper case version of str." #define Q_string_upcase pcl_s return(c_string_upcase(sc, car(args))); } PF_TO_PF(string_upcase, c_string_upcase) unsigned int s7_string_length(s7_pointer str) { return(string_length(str)); } /* -------------------------------- string-ref -------------------------------- */ static s7_pointer string_ref_1(s7_scheme *sc, s7_pointer strng, s7_pointer index) { char *str; s7_int ind; if (!s7_is_integer(index)) { s7_pointer p; if (!s7_is_integer(p = check_values(sc, index, cons(sc, index, sc->NIL)))) method_or_bust(sc, index, sc->STRING_REF, list_2(sc, strng, index), T_INTEGER, 2); index = p; } ind = s7_integer(index); if (ind < 0) return(wrong_type_argument_with_type(sc, sc->STRING_REF, 2, index, A_NON_NEGATIVE_INTEGER)); if (ind >= string_length(strng)) return(out_of_range(sc, sc->STRING_REF, small_int(2), index, ITS_TOO_LARGE)); str = string_value(strng); return(s7_make_character(sc, ((unsigned char *)str)[ind])); } static s7_pointer g_string_ref(s7_scheme *sc, s7_pointer args) { s7_pointer strng, index, p; char *str; s7_int ind; #define H_string_ref "(string-ref str index) returns the character at the index-th element of the string str" #define Q_string_ref s7_make_signature(sc, 3, sc->IS_CHAR, sc->IS_STRING, sc->IS_INTEGER) strng = car(args); if (!is_string(strng)) method_or_bust(sc, strng, sc->STRING_REF, args, T_STRING, 1); index = cadr(args); if (!s7_is_integer(index)) { if (!s7_is_integer(p = check_values(sc, index, cdr(args)))) method_or_bust(sc, index, sc->STRING_REF, args, T_INTEGER, 2); index = p; } ind = s7_integer(index); if (ind < 0) return(wrong_type_argument_with_type(sc, sc->STRING_REF, 2, index, A_NON_NEGATIVE_INTEGER)); if (ind >= string_length(strng)) return(out_of_range(sc, sc->STRING_REF, small_int(2), index, ITS_TOO_LARGE)); str = string_value(strng); return(s7_make_character(sc, ((unsigned char *)str)[ind])); } static s7_pointer c_string_ref(s7_scheme *sc, s7_pointer str, s7_int ind) { if (!is_string(str)) method_or_bust(sc, str, sc->STRING_REF, list_2(sc, str, make_integer(sc, ind)), T_STRING, 1); if (ind < 0) return(wrong_type_argument_with_type(sc, sc->STRING_REF, 2, make_integer(sc, ind), A_NON_NEGATIVE_INTEGER)); if (ind >= string_length(str)) return(out_of_range(sc, sc->STRING_REF, small_int(2), make_integer(sc, ind), ITS_TOO_LARGE)); return(s7_make_character(sc, ((unsigned char *)string_value(str))[ind])); } PIF_TO_PF(string_ref, c_string_ref) /* -------------------------------- string-set! -------------------------------- */ static s7_pointer g_string_set(s7_scheme *sc, s7_pointer args) { #define H_string_set "(string-set! str index chr) sets the index-th element of the string str to the character chr" #define Q_string_set s7_make_signature(sc, 4, sc->IS_CHAR, sc->IS_STRING, sc->IS_INTEGER, sc->IS_CHAR) s7_pointer x, c, index; char *str; s7_int ind; x = car(args); if (!is_string(x)) method_or_bust(sc, x, sc->STRING_SET, args, T_STRING, 1); index = cadr(args); if (!s7_is_integer(index)) { s7_pointer p; if (!s7_is_integer(p = check_values(sc, index, cdr(args)))) method_or_bust(sc, index, sc->STRING_SET, args, T_INTEGER, 2); index = p; } ind = s7_integer(index); if (ind < 0) return(wrong_type_argument_with_type(sc, sc->STRING_SET, 2, index, A_NON_NEGATIVE_INTEGER)); if (ind >= string_length(x)) return(out_of_range(sc, sc->STRING_SET, small_int(2), index, ITS_TOO_LARGE)); str = string_value(_TSet(x)); c = caddr(args); if (!s7_is_character(c)) { if ((is_byte_vector(x)) && (s7_is_integer(c))) { s7_int ic; /* not int here! */ ic = s7_integer(c); if ((ic < 0) || (ic > 255)) return(wrong_type_argument_with_type(sc, sc->STRING_SET, 3, c, AN_UNSIGNED_BYTE)); str[ind] = (char)ic; return(c); } method_or_bust(sc, c, sc->STRING_SET, list_3(sc, x, index, c), T_CHARACTER, 3); } str[ind] = (char)s7_character(c); return(c); } static int c_string_tester(s7_scheme *sc, s7_pointer expr) { s7_pointer a1; a1 = cadr(expr); if (is_symbol(a1)) { s7_pointer table; table = s7_slot(sc, a1); if ((is_slot(table)) && ((is_immutable_symbol(a1)) || (!is_stepper(table))) && (is_string(slot_value(table)))) { s7_pointer a2; s7_xf_store(sc, slot_value(table)); a2 = caddr(expr); if (is_symbol(a2)) { s7_pointer slot; slot = s7_slot(sc, a2); if ((is_slot(slot)) && (is_integer(slot_value(slot)))) { s7_xf_store(sc, slot); return(TEST_SS); } } else { if (s7_arg_to_if(sc, a1)) return(TEST_SI); } return(TEST_SQ); } } return(TEST_NO_S); } static s7_pointer c_string_set_s(s7_scheme *sc, s7_pointer vec, s7_int index, s7_pointer val) { if (!s7_is_character(val)) method_or_bust(sc, val, sc->STRING_SET, list_3(sc, vec, make_integer(sc, index), val), T_CHARACTER, 3); if ((index < 0) || (index >= string_length(vec))) return(out_of_range(sc, sc->STRING_SET, small_int(2), make_integer(sc, index), (index < 0) ? ITS_NEGATIVE : ITS_TOO_LARGE)); string_value(vec)[index] = (char)character(val); return(val); } static s7_pointer c_string_set(s7_scheme *sc, s7_pointer vec, s7_int index, s7_pointer val) { if (!s7_is_string(vec)) method_or_bust(sc, vec, sc->STRING_SET, set_plist_3(sc, vec, make_integer(sc, index), val), T_STRING, 1); return(c_string_set_s(sc, vec, index, val)); } PIPF_TO_PF(string_set, c_string_set_s, c_string_set, c_string_tester) /* -------------------------------- string-append -------------------------------- */ static s7_pointer g_string_append_1(s7_scheme *sc, s7_pointer args, bool use_temp) { int len = 0; s7_pointer x, newstr; char *pos; if (is_null(args)) return(s7_make_string_with_length(sc, "", 0)); /* get length for new string */ for (x = args; is_not_null(x); x = cdr(x)) { s7_pointer p; p = car(x); if (!is_string(p)) { /* look for string-append and if found, cobble up a plausible intermediate call */ if (has_methods(p)) { s7_pointer func; func = find_method(sc, find_let(sc, p), sc->STRING_APPEND); if (func != sc->UNDEFINED) { s7_pointer y; if (len == 0) return(s7_apply_function(sc, func, args)); newstr = make_empty_string(sc, len, 0); for (pos = string_value(newstr), y = args; y != x; pos += string_length(car(y)), y = cdr(y)) memcpy(pos, string_value(car(y)), string_length(car(y))); return(s7_apply_function(sc, func, cons(sc, newstr, x))); } } return(wrong_type_argument(sc, sc->STRING_APPEND, position_of(x, args), p, T_STRING)); } len += string_length(p); } if (use_temp) { newstr = sc->tmp_strs[0]; prepare_temporary_string(sc, len + 1, 0); string_length(newstr) = len; string_value(newstr)[len] = 0; } else { /* store the contents of the argument strings into the new string */ newstr = make_empty_string(sc, len, 0); } for (pos = string_value(newstr), x = args; is_not_null(x); pos += string_length(car(x)), x = cdr(x)) memcpy(pos, string_value(car(x)), string_length(car(x))); if (is_byte_vector(car(args))) set_byte_vector(newstr); return(newstr); } static s7_pointer g_string_append(s7_scheme *sc, s7_pointer args) { #define H_string_append "(string-append str1 ...) appends all its string arguments into one string" #define Q_string_append pcl_s return(g_string_append_1(sc, args, false)); } static s7_pointer string_append_to_temp; static s7_pointer g_string_append_to_temp(s7_scheme *sc, s7_pointer args) { return(g_string_append_1(sc, args, true)); } #if (!WITH_PURE_S7) static s7_pointer g_string_copy(s7_scheme *sc, s7_pointer args) { #define H_string_copy "(string-copy str) returns a copy of its string argument" #define Q_string_copy pcl_s s7_pointer p; p = car(args); if (!is_string(p)) method_or_bust(sc, p, sc->STRING_COPY, args, T_STRING, 1); return(s7_make_string_with_length(sc, string_value(p), string_length(p))); } #endif /* -------------------------------- substring -------------------------------- */ static s7_pointer start_and_end(s7_scheme *sc, s7_pointer caller, s7_pointer fallback, s7_pointer start_and_end_args, s7_pointer args, int position, s7_int *start, s7_int *end) { /* we assume that *start=0 and *end=length, that end is "exclusive" * return true if the start/end points are not changed. */ s7_pointer pstart, pend, p; s7_int index; #if DEBUGGING if (is_null(start_and_end_args)) { fprintf(stderr, "start_and_end args is null\n"); return(sc->GC_NIL); } #endif pstart = car(start_and_end_args); if (!s7_is_integer(pstart)) { if (!s7_is_integer(p = check_values(sc, pstart, start_and_end_args))) { check_two_methods(sc, pstart, caller, fallback, args); return(wrong_type_argument(sc, caller, position, pstart, T_INTEGER)); } else pstart = p; } index = s7_integer(pstart); if ((index < 0) || (index > *end)) /* *end == length here */ return(out_of_range(sc, caller, small_int(position), pstart, (index < 0) ? ITS_NEGATIVE : ITS_TOO_LARGE)); *start = index; if (is_null(cdr(start_and_end_args))) return(sc->GC_NIL); pend = cadr(start_and_end_args); if (!s7_is_integer(pend)) { if (!s7_is_integer(p = check_values(sc, pend, cdr(start_and_end_args)))) { check_two_methods(sc, pend, caller, fallback, (position == 2) ? list_3(sc, car(args), pstart, pend) : list_4(sc, car(args), cadr(args), pstart, pend)); return(wrong_type_argument(sc, caller, position + 1, pend, T_INTEGER)); } else pend = p; } index = s7_integer(pend); if ((index < *start) || (index > *end)) return(out_of_range(sc, caller, small_int(position + 1), pend, (index < *start) ? ITS_TOO_SMALL : ITS_TOO_LARGE)); *end = index; return(sc->GC_NIL); } static s7_pointer g_substring(s7_scheme *sc, s7_pointer args) { #define H_substring "(substring str start (end (length str))) returns the portion of the string str between start and \ end: (substring \"01234\" 1 2) -> \"1\"" #define Q_substring s7_make_circular_signature(sc, 2, 3, sc->IS_STRING, sc->IS_STRING, sc->IS_INTEGER) s7_pointer x, str; s7_int start = 0, end; int len; char *s; str = car(args); if (!is_string(str)) method_or_bust(sc, str, sc->SUBSTRING, args, T_STRING, 1); end = string_length(str); if (!is_null(cdr(args))) { x = start_and_end(sc, sc->SUBSTRING, NULL, cdr(args), args, 2, &start, &end); if (x != sc->GC_NIL) return(x); } s = string_value(str); len = (int)(end - start); x = s7_make_string_with_length(sc, (char *)(s + start), len); string_value(x)[len] = 0; return(x); } static s7_pointer substring_to_temp; static s7_pointer g_substring_to_temp(s7_scheme *sc, s7_pointer args) { s7_pointer str; s7_int start = 0, end; str = car(args); if (!is_string(str)) method_or_bust(sc, str, sc->SUBSTRING, args, T_STRING, 1); end = string_length(str); if (!is_null(cdr(args))) { s7_pointer x; x = start_and_end(sc, sc->SUBSTRING, NULL, cdr(args), args, 2, &start, &end); if (x != sc->GC_NIL) return(x); } return(make_temporary_string(sc, (const char *)(string_value(str) + start), (int)(end - start))); } /* -------------------------------- object->string -------------------------------- */ static use_write_t write_choice(s7_scheme *sc, s7_pointer arg) { if (arg == sc->F) return(USE_DISPLAY); if (arg == sc->T) return(USE_WRITE); if (arg == sc->KEY_READABLE) return(USE_READABLE_WRITE); return(USE_WRITE_WRONG); } #define DONT_USE_DISPLAY(Choice) ((Choice == USE_DISPLAY) ? USE_WRITE : Choice) static char *s7_object_to_c_string_1(s7_scheme *sc, s7_pointer obj, use_write_t use_write, int *nlen); static s7_pointer g_object_to_string(s7_scheme *sc, s7_pointer args) { #define H_object_to_string "(object->string obj (write #t)) returns a string representation of obj." #define Q_object_to_string s7_make_signature(sc, 3, sc->IS_STRING, sc->T, s7_make_signature(sc, 2, sc->IS_BOOLEAN, sc->IS_KEYWORD)) use_write_t choice; char *str; s7_pointer obj; int len = 0; if (is_not_null(cdr(args))) { choice = write_choice(sc, cadr(args)); if (choice == USE_WRITE_WRONG) method_or_bust(sc, cadr(args), sc->OBJECT_TO_STRING, args, T_BOOLEAN, 2); } else choice = USE_WRITE; /* can't use s7_object_to_string here anymore because it assumes use_write arg is a boolean */ obj = car(args); check_method(sc, obj, sc->OBJECT_TO_STRING, args); str = s7_object_to_c_string_1(sc, obj, choice, &len); if (str) return(make_string_uncopied_with_length(sc, str, len)); return(s7_make_string_with_length(sc, "", 0)); } static s7_pointer c_object_to_string(s7_scheme *sc, s7_pointer x) {return(g_object_to_string(sc, set_plist_1(sc, x)));} PF_TO_PF(object_to_string, c_object_to_string) /* -------------------------------- string comparisons -------------------------------- */ static int scheme_strcmp(s7_pointer s1, s7_pointer s2) { /* tricky here because str[i] must be treated as unsigned * (stringchar #xf0)) (string (integer->char #x70))) * also null or lack thereof does not say anything about the string end * so we have to go by its length. */ int i, len, len1, len2; char *str1, *str2; len1 = string_length(s1); len2 = string_length(s2); if (len1 > len2) len = len2; else len = len1; str1 = string_value(s1); str2 = string_value(s2); for (i = 0; i < len; i++) if ((unsigned char)(str1[i]) < (unsigned char )(str2[i])) return(-1); else { if ((unsigned char)(str1[i]) > (unsigned char)(str2[i])) return(1); } if (len1 < len2) return(-1); if (len1 > len2) return(1); return(0); } static bool is_string_via_method(s7_scheme *sc, s7_pointer p) { if (s7_is_string(p)) return(true); if (has_methods(p)) { s7_pointer f; f = find_method(sc, find_let(sc, p), sc->IS_STRING); if (f != sc->UNDEFINED) return(is_true(sc, s7_apply_function(sc, f, cons(sc, p, sc->NIL)))); } return(false); } static s7_pointer g_string_cmp(s7_scheme *sc, s7_pointer args, int val, s7_pointer sym) { s7_pointer x, y; y = car(args); if (!is_string(y)) method_or_bust(sc, y, sym, args, T_STRING, 1); for (x = cdr(args); is_not_null(x); x = cdr(x)) { if (!is_string(car(x))) method_or_bust(sc, car(x), sym, cons(sc, y, x), T_STRING, position_of(x, args)); if (scheme_strcmp(y, car(x)) != val) { for (y = cdr(x); is_pair(y); y = cdr(y)) if (!is_string_via_method(sc, car(y))) return(wrong_type_argument(sc, sym, position_of(y, args), car(y), T_STRING)); return(sc->F); } y = car(x); } return(sc->T); } static s7_pointer g_string_cmp_not(s7_scheme *sc, s7_pointer args, int val, s7_pointer sym) { s7_pointer x, y; y = car(args); if (!is_string(y)) method_or_bust(sc, y, sym, args, T_STRING, 1); for (x = cdr(args); is_not_null(x); x = cdr(x)) { if (!is_string(car(x))) method_or_bust(sc, car(x), sym, cons(sc, y, x), T_STRING, position_of(x, args)); if (scheme_strcmp(y, car(x)) == val) { for (y = cdr(x); is_pair(y); y = cdr(y)) if (!is_string_via_method(sc, car(y))) return(wrong_type_argument(sc, sym, position_of(y, args), car(y), T_STRING)); return(sc->F); } y = car(x); } return(sc->T); } static bool scheme_strings_are_equal(s7_pointer x, s7_pointer y) { return((string_length(x) == string_length(y)) && (strings_are_equal_with_length(string_value(x), string_value(y), string_length(x)))); } static s7_pointer g_strings_are_equal(s7_scheme *sc, s7_pointer args) { #define H_strings_are_equal "(string=? str ...) returns #t if all the string arguments are equal" #define Q_strings_are_equal pcl_bs /* C-based check stops at null, but we can have embedded nulls. * (let ((s1 "1234") (s2 "1245")) (string-set! s1 1 #\null) (string-set! s2 1 #\null) (string=? s1 s2)) */ s7_pointer x, y; bool happy = true; y = car(args); if (!is_string(y)) method_or_bust(sc, y, sc->STRING_EQ, args, T_STRING, 1); for (x = cdr(args); is_pair(x); x = cdr(x)) { s7_pointer p; p = car(x); if (y != p) { if (!is_string(p)) method_or_bust(sc, p, sc->STRING_EQ, cons(sc, y, x), T_STRING, position_of(x, args)); if (happy) happy = scheme_strings_are_equal(p, y); } } if (!happy) return(sc->F); return(sc->T); } static s7_pointer c_string_eq(s7_scheme *sc, s7_pointer x, s7_pointer y) { if (!is_string(x)) method_or_bust(sc, x, sc->STRING_EQ, list_2(sc, x, y), T_STRING, 1); if (!is_string(y)) method_or_bust(sc, y, sc->STRING_EQ, list_2(sc, x, y), T_STRING, 2); return(make_boolean(sc, ((string_length(x) == string_length(y)) && (strings_are_equal_with_length(string_value(x), string_value(y), string_length(x)))))); } PF2_TO_PF(string_eq, c_string_eq) static s7_pointer g_strings_are_less(s7_scheme *sc, s7_pointer args) { #define H_strings_are_less "(stringSTRING_LT)); } static s7_pointer c_string_lt(s7_scheme *sc, s7_pointer x, s7_pointer y) { if (!is_string(x)) method_or_bust(sc, x, sc->STRING_LT, list_2(sc, x, y), T_STRING, 1); if (!is_string(y)) method_or_bust(sc, y, sc->STRING_LT, list_2(sc, x, y), T_STRING, 2); return(make_boolean(sc, scheme_strcmp(x, y) == -1)); } PF2_TO_PF(string_lt, c_string_lt) static s7_pointer g_strings_are_greater(s7_scheme *sc, s7_pointer args) { #define H_strings_are_greater "(string>? str ...) returns #t if all the string arguments are decreasing" #define Q_strings_are_greater pcl_bs return(g_string_cmp(sc, args, 1, sc->STRING_GT)); } static s7_pointer c_string_gt(s7_scheme *sc, s7_pointer x, s7_pointer y) { if (!is_string(x)) method_or_bust(sc, x, sc->STRING_GT, list_2(sc, x, y), T_STRING, 1); if (!is_string(y)) method_or_bust(sc, y, sc->STRING_GT, list_2(sc, x, y), T_STRING, 2); return(make_boolean(sc, scheme_strcmp(x, y) == 1)); } PF2_TO_PF(string_gt, c_string_gt) static s7_pointer g_strings_are_geq(s7_scheme *sc, s7_pointer args) { #define H_strings_are_geq "(string>=? str ...) returns #t if all the string arguments are equal or decreasing" #define Q_strings_are_geq pcl_bs return(g_string_cmp_not(sc, args, -1, sc->STRING_GEQ)); } static s7_pointer c_string_geq(s7_scheme *sc, s7_pointer x, s7_pointer y) { if (!is_string(x)) method_or_bust(sc, x, sc->STRING_GEQ, list_2(sc, x, y), T_STRING, 1); if (!is_string(y)) method_or_bust(sc, y, sc->STRING_GEQ, list_2(sc, x, y), T_STRING, 2); return(make_boolean(sc, scheme_strcmp(x, y) != -1)); } PF2_TO_PF(string_geq, c_string_geq) static s7_pointer g_strings_are_leq(s7_scheme *sc, s7_pointer args) { #define H_strings_are_leq "(string<=? str ...) returns #t if all the string arguments are equal or increasing" #define Q_strings_are_leq pcl_bs return(g_string_cmp_not(sc, args, 1, sc->STRING_LEQ)); } static s7_pointer c_string_leq(s7_scheme *sc, s7_pointer x, s7_pointer y) { if (!is_string(x)) method_or_bust(sc, x, sc->STRING_LEQ, list_2(sc, x, y), T_STRING, 1); if (!is_string(y)) method_or_bust(sc, y, sc->STRING_LEQ, list_2(sc, x, y), T_STRING, 2); return(make_boolean(sc, scheme_strcmp(x, y) != 1)); } PF2_TO_PF(string_leq, c_string_leq) static s7_pointer string_equal_s_ic, string_equal_2; static s7_pointer g_string_equal_s_ic(s7_scheme *sc, s7_pointer args) { if (!is_string(car(args))) method_or_bust(sc, car(args), sc->STRING_EQ, args, T_STRING, 1); return(make_boolean(sc, scheme_strings_are_equal(car(args), cadr(args)))); } static s7_pointer g_string_equal_2(s7_scheme *sc, s7_pointer args) { if (!is_string(car(args))) method_or_bust(sc, car(args), sc->STRING_EQ, args, T_STRING, 1); if (!is_string(cadr(args))) method_or_bust(sc, cadr(args), sc->STRING_EQ, args, T_STRING, 2); return(make_boolean(sc, scheme_strings_are_equal(car(args), cadr(args)))); } static s7_pointer string_less_2; static s7_pointer g_string_less_2(s7_scheme *sc, s7_pointer args) { if (!is_string(car(args))) method_or_bust(sc, car(args), sc->STRING_LT, args, T_STRING, 1); if (!is_string(cadr(args))) method_or_bust(sc, cadr(args), sc->STRING_LT, args, T_STRING, 2); return(make_boolean(sc, scheme_strcmp(car(args), cadr(args)) == -1)); } static s7_pointer string_greater_2; static s7_pointer g_string_greater_2(s7_scheme *sc, s7_pointer args) { if (!is_string(car(args))) method_or_bust(sc, car(args), sc->STRING_GT, args, T_STRING, 1); if (!is_string(cadr(args))) method_or_bust(sc, cadr(args), sc->STRING_GT, args, T_STRING, 2); return(make_boolean(sc, scheme_strcmp(car(args), cadr(args)) == 1)); } #if (!WITH_PURE_S7) static int scheme_strcasecmp(s7_pointer s1, s7_pointer s2) { /* same as scheme_strcmp -- watch out for unwanted sign! and lack of trailing null (length sets string end). */ int i, len, len1, len2; unsigned char *str1, *str2; len1 = string_length(s1); len2 = string_length(s2); if (len1 > len2) len = len2; else len = len1; str1 = (unsigned char *)string_value(s1); str2 = (unsigned char *)string_value(s2); for (i = 0; i < len; i++) if (uppers[(int)str1[i]] < uppers[(int)str2[i]]) return(-1); else { if (uppers[(int)str1[i]] > uppers[(int)str2[i]]) return(1); } if (len1 < len2) return(-1); if (len1 > len2) return(1); return(0); } static bool scheme_strequal_ci(s7_pointer s1, s7_pointer s2) { /* same as scheme_strcmp -- watch out for unwanted sign! */ int i, len, len2; unsigned char *str1, *str2; len = string_length(s1); len2 = string_length(s2); if (len != len2) return(false); str1 = (unsigned char *)string_value(s1); str2 = (unsigned char *)string_value(s2); for (i = 0; i < len; i++) if (uppers[(int)str1[i]] != uppers[(int)str2[i]]) return(false); return(true); } static s7_pointer g_string_ci_cmp(s7_scheme *sc, s7_pointer args, int val, s7_pointer sym) { s7_pointer x, y; y = car(args); if (!is_string(y)) method_or_bust(sc, y, sym, args, T_STRING, 1); for (x = cdr(args); is_not_null(x); x = cdr(x)) { if (!is_string(car(x))) method_or_bust(sc, car(x), sym, cons(sc, y, x), T_STRING, position_of(x, args)); if (val == 0) { if (!scheme_strequal_ci(y, car(x))) { for (y = cdr(x); is_pair(y); y = cdr(y)) if (!is_string_via_method(sc, car(y))) return(wrong_type_argument(sc, sym, position_of(y, args), car(y), T_STRING)); return(sc->F); } } else { if (scheme_strcasecmp(y, car(x)) != val) { for (y = cdr(x); is_pair(y); y = cdr(y)) if (!is_string_via_method(sc, car(y))) return(wrong_type_argument(sc, sym, position_of(y, args), car(y), T_STRING)); return(sc->F); } } y = car(x); } return(sc->T); } static s7_pointer g_string_ci_cmp_not(s7_scheme *sc, s7_pointer args, int val, s7_pointer sym) { s7_pointer x, y; y = car(args); if (!is_string(y)) method_or_bust(sc, y, sym, args, T_STRING, 1); for (x = cdr(args); is_not_null(x); x = cdr(x)) { if (!is_string(car(x))) method_or_bust(sc, car(x), sym, cons(sc, y, x), T_STRING, position_of(x, args)); if (scheme_strcasecmp(y, car(x)) == val) { for (y = cdr(x); is_pair(y); y = cdr(y)) if (!is_string_via_method(sc, car(y))) return(wrong_type_argument(sc, sym, position_of(y, args), car(y), T_STRING)); return(sc->F); } y = car(x); } return(sc->T); } static s7_pointer g_strings_are_ci_equal(s7_scheme *sc, s7_pointer args) { #define H_strings_are_ci_equal "(string-ci=? str ...) returns #t if all the string arguments are equal, ignoring case" #define Q_strings_are_ci_equal pcl_bs return(g_string_ci_cmp(sc, args, 0, sc->STRING_CI_EQ)); } static s7_pointer c_string_ci_eq(s7_scheme *sc, s7_pointer x, s7_pointer y) { if (!is_string(x)) method_or_bust(sc, x, sc->STRING_CI_EQ, list_2(sc, x, y), T_STRING, 1); if (!is_string(y)) method_or_bust(sc, y, sc->STRING_CI_EQ, list_2(sc, x, y), T_STRING, 2); return(make_boolean(sc, scheme_strcasecmp(x, y) == 0)); } PF2_TO_PF(string_ci_eq, c_string_ci_eq) static s7_pointer g_strings_are_ci_less(s7_scheme *sc, s7_pointer args) { #define H_strings_are_ci_less "(string-ciSTRING_CI_LT)); } static s7_pointer c_string_ci_lt(s7_scheme *sc, s7_pointer x, s7_pointer y) { if (!is_string(x)) method_or_bust(sc, x, sc->STRING_CI_LT, list_2(sc, x, y), T_STRING, 1); if (!is_string(y)) method_or_bust(sc, y, sc->STRING_CI_LT, list_2(sc, x, y), T_STRING, 2); return(make_boolean(sc, scheme_strcasecmp(x, y) == -1)); } PF2_TO_PF(string_ci_lt, c_string_ci_lt) static s7_pointer g_strings_are_ci_greater(s7_scheme *sc, s7_pointer args) { #define H_strings_are_ci_greater "(string-ci>? str ...) returns #t if all the string arguments are decreasing, ignoring case" #define Q_strings_are_ci_greater pcl_bs return(g_string_ci_cmp(sc, args, 1, sc->STRING_CI_GT)); } static s7_pointer c_string_ci_gt(s7_scheme *sc, s7_pointer x, s7_pointer y) { if (!is_string(x)) method_or_bust(sc, x, sc->STRING_CI_GT, list_2(sc, x, y), T_STRING, 1); if (!is_string(y)) method_or_bust(sc, y, sc->STRING_CI_GT, list_2(sc, x, y), T_STRING, 2); return(make_boolean(sc, scheme_strcasecmp(x, y) == 1)); } PF2_TO_PF(string_ci_gt, c_string_ci_gt) static s7_pointer g_strings_are_ci_geq(s7_scheme *sc, s7_pointer args) { #define H_strings_are_ci_geq "(string-ci>=? str ...) returns #t if all the string arguments are equal or decreasing, ignoring case" #define Q_strings_are_ci_geq pcl_bs return(g_string_ci_cmp_not(sc, args, -1, sc->STRING_CI_GEQ)); } static s7_pointer c_string_ci_geq(s7_scheme *sc, s7_pointer x, s7_pointer y) { if (!is_string(x)) method_or_bust(sc, x, sc->STRING_CI_GEQ, list_2(sc, x, y), T_STRING, 1); if (!is_string(y)) method_or_bust(sc, y, sc->STRING_CI_GEQ, list_2(sc, x, y), T_STRING, 2); return(make_boolean(sc, scheme_strcasecmp(x, y) != -1)); } PF2_TO_PF(string_ci_geq, c_string_ci_geq) static s7_pointer g_strings_are_ci_leq(s7_scheme *sc, s7_pointer args) { #define H_strings_are_ci_leq "(string-ci<=? str ...) returns #t if all the string arguments are equal or increasing, ignoring case" #define Q_strings_are_ci_leq pcl_bs return(g_string_ci_cmp_not(sc, args, 1, sc->STRING_CI_LEQ)); } static s7_pointer c_string_ci_leq(s7_scheme *sc, s7_pointer x, s7_pointer y) { if (!is_string(x)) method_or_bust(sc, x, sc->STRING_CI_LEQ, list_2(sc, x, y), T_STRING, 1); if (!is_string(y)) method_or_bust(sc, y, sc->STRING_CI_LEQ, list_2(sc, x, y), T_STRING, 2); return(make_boolean(sc, scheme_strcasecmp(x, y) != 1)); } PF2_TO_PF(string_ci_leq, c_string_ci_leq) #endif /* pure s7 */ static s7_pointer g_string_fill(s7_scheme *sc, s7_pointer args) { #define H_string_fill "(string-fill! str chr start end) fills the string str with the character chr" #define Q_string_fill s7_make_circular_signature(sc, 3, 4, s7_make_signature(sc, 2, sc->IS_CHAR, sc->IS_INTEGER), sc->IS_STRING, sc->IS_CHAR, sc->IS_INTEGER) s7_pointer x, chr; s7_int start = 0, end, byte = 0; x = car(args); if (!is_string(x)) method_or_bust(sc, x, sc->STRING_FILL, args, T_STRING, 1); /* not two methods here */ chr = cadr(args); if (!is_byte_vector(x)) { if (!s7_is_character(chr)) { check_two_methods(sc, chr, sc->STRING_FILL, sc->FILL, args); return(wrong_type_argument(sc, sc->STRING_FILL, 2, chr, T_CHARACTER)); } } else { if (!is_integer(chr)) { check_two_methods(sc, chr, sc->STRING_FILL, sc->FILL, args); return(wrong_type_argument(sc, sc->FILL, 2, chr, T_INTEGER)); } byte = integer(chr); if ((byte < 0) || (byte > 255)) return(simple_wrong_type_argument_with_type(sc, sc->STRING_FILL, chr, AN_UNSIGNED_BYTE)); } end = string_length(x); if (!is_null(cddr(args))) { s7_pointer p; p = start_and_end(sc, sc->STRING_FILL, sc->FILL, cddr(args), args, 3, &start, &end); if (p != sc->GC_NIL) return(p); if (start == end) return(chr); } if (end == 0) return(chr); if (!is_byte_vector(x)) memset((void *)(string_value(x) + start), (int)character(chr), end - start); else memset((void *)(string_value(x) + start), (int)byte, end - start); return(chr); } #if (!WITH_PURE_S7) static s7_pointer c_string_fill(s7_scheme *sc, s7_pointer x, s7_pointer y) {return(g_string_fill(sc, set_plist_2(sc, x, y)));} PF2_TO_PF(string_fill, c_string_fill) #endif static s7_pointer g_string_1(s7_scheme *sc, s7_pointer args, s7_pointer sym) { int i, len; s7_pointer x, newstr; char *str; /* get length for new string and check arg types */ for (len = 0, x = args; is_not_null(x); len++, x = cdr(x)) { s7_pointer p; p = car(x); if (!s7_is_character(p)) { if (has_methods(p)) { s7_pointer func; func = find_method(sc, find_let(sc, p), sym); if (func != sc->UNDEFINED) { s7_pointer y; if (len == 0) return(s7_apply_function(sc, func, args)); newstr = make_empty_string(sc, len, 0); str = string_value(newstr); for (i = 0, y = args; y != x; i++, y = cdr(y)) str[i] = character(car(y)); return(g_string_append(sc, set_plist_2(sc, newstr, s7_apply_function(sc, func, x)))); } } return(wrong_type_argument(sc, sym, len + 1, car(x), T_CHARACTER)); } } newstr = make_empty_string(sc, len, 0); str = string_value(newstr); for (i = 0, x = args; is_not_null(x); i++, x = cdr(x)) str[i] = character(car(x)); return(newstr); } static s7_pointer g_string(s7_scheme *sc, s7_pointer args) { #define H_string "(string chr...) appends all its character arguments into one string" #define Q_string s7_make_circular_signature(sc, 1, 2, sc->IS_STRING, sc->IS_CHAR) if (is_null(args)) /* (string) but not (string ()) */ return(s7_make_string_with_length(sc, "", 0)); return(g_string_1(sc, args, sc->STRING)); } #if (!WITH_PURE_S7) static s7_pointer g_list_to_string(s7_scheme *sc, s7_pointer args) { #define H_list_to_string "(list->string lst) appends all the list's characters into one string; (apply string lst)" #define Q_list_to_string s7_make_signature(sc, 2, sc->IS_STRING, sc->IS_PROPER_LIST) if (is_null(car(args))) return(s7_make_string_with_length(sc, "", 0)); if (!is_proper_list(sc, car(args))) method_or_bust_with_type(sc, car(args), sc->LIST_TO_STRING, args, make_string_wrapper(sc, "a (proper, non-circular) list of characters"), 0); return(g_string_1(sc, car(args), sc->LIST_TO_STRING)); } #endif static s7_pointer s7_string_to_list(s7_scheme *sc, const char *str, int len) { int i; s7_pointer result; if (len == 0) return(sc->NIL); if (len >= (sc->free_heap_top - sc->free_heap)) { gc(sc); while (len >= (sc->free_heap_top - sc->free_heap)) resize_heap(sc); } sc->v = sc->NIL; for (i = len - 1; i >= 0; i--) sc->v = cons_unchecked(sc, s7_make_character(sc, ((unsigned char)str[i])), sc->v); result = sc->v; sc->v = sc->NIL; return(result); } #if (!WITH_PURE_S7) static s7_pointer g_string_to_list(s7_scheme *sc, s7_pointer args) { #define H_string_to_list "(string->list str start end) returns the elements of the string str in a list; (map values str)" #define Q_string_to_list s7_make_circular_signature(sc, 2, 3, sc->IS_LIST, sc->IS_STRING, sc->IS_INTEGER) s7_int i, start = 0, end; s7_pointer p, str; str = car(args); if (!is_string(str)) method_or_bust(sc, str, sc->STRING_TO_LIST, args, T_STRING, 0); end = string_length(str); if (!is_null(cdr(args))) { p = start_and_end(sc, sc->STRING_TO_LIST, NULL, cdr(args), args, 2, &start, &end); if (p != sc->GC_NIL) return(p); if (start == end) return(sc->NIL); } else { if (end == 0) return(sc->NIL); } if ((start == 0) && (end == string_length(str))) return(s7_string_to_list(sc, string_value(str), string_length(str))); sc->w = sc->NIL; for (i = end - 1; i >= start; i--) sc->w = cons(sc, s7_make_character(sc, ((unsigned char)string_value(str)[i])), sc->w); p = sc->w; sc->w = sc->NIL; return(p); } static s7_pointer c_string_to_list(s7_scheme *sc, s7_pointer x) {return(g_string_to_list(sc, set_plist_1(sc, x)));} PF_TO_PF(string_to_list, c_string_to_list) #endif /* -------------------------------- byte_vectors -------------------------------- * * these are just strings with the T_BYTE_VECTOR bit set. */ static bool s7_is_byte_vector(s7_pointer b) {return((is_string(b)) && (is_byte_vector(b)));} static s7_pointer g_is_byte_vector(s7_scheme *sc, s7_pointer args) { #define H_is_byte_vector "(byte-vector? obj) returns #t if obj is a byte-vector" #define Q_is_byte_vector pl_bt check_boolean_method(sc, s7_is_byte_vector, sc->IS_BYTE_VECTOR, args); } static s7_pointer g_to_byte_vector(s7_scheme *sc, s7_pointer args) { #define H_to_byte_vector "(->byte-vector obj) turns a string into a byte-vector." #define Q_to_byte_vector s7_make_signature(sc, 2, sc->IS_BYTE_VECTOR, sc->IS_STRING) s7_pointer str; str = car(args); if (is_integer(str)) str = s7_make_string_with_length(sc, (const char *)(&(integer(str))), sizeof(s7_int)); else { if (!is_string(str)) method_or_bust(sc, str, sc->TO_BYTE_VECTOR, set_plist_1(sc, str), T_STRING, 1); } set_byte_vector(str); return(str); } static s7_pointer c_to_byte_vector(s7_scheme *sc, s7_pointer str) {return(g_to_byte_vector(sc, set_plist_1(sc, str)));} PF_TO_PF(to_byte_vector, c_to_byte_vector) static s7_pointer g_make_byte_vector(s7_scheme *sc, s7_pointer args) { #define H_make_byte_vector "(make-byte-vector len (byte 0)) makes a byte-vector of length len filled with byte." #define Q_make_byte_vector s7_make_circular_signature(sc, 1, 2, sc->IS_BYTE_VECTOR, sc->IS_INTEGER) s7_pointer str; if (is_null(cdr(args))) { str = g_make_string(sc, args); if (is_string(str)) memclr((void *)(string_value(str)), string_length(str)); } else { s7_pointer len, byte; s7_int b; len = car(args); if (!is_integer(len)) method_or_bust(sc, len, sc->MAKE_BYTE_VECTOR, args, T_INTEGER, 1); byte = cadr(args); if (!s7_is_integer(byte)) method_or_bust(sc, byte, sc->MAKE_BYTE_VECTOR, args, T_INTEGER, 2); b = s7_integer(byte); if ((b < 0) || (b > 255)) return(simple_wrong_type_argument_with_type(sc, sc->MAKE_BYTE_VECTOR, byte, AN_UNSIGNED_BYTE)); str = g_make_string(sc, set_plist_2(sc, len, chars[b])); } set_byte_vector(str); return(str); } static s7_pointer g_byte_vector(s7_scheme *sc, s7_pointer args) { #define H_byte_vector "(byte-vector ...) returns a byte-vector whose elements are the arguments" #define Q_byte_vector s7_make_circular_signature(sc, 1, 2, sc->IS_BYTE_VECTOR, sc->IS_INTEGER) s7_int i, len; s7_pointer vec, x; char *str; len = s7_list_length(sc, args); vec = make_empty_string(sc, len, 0); str = string_value(vec); for (i = 0, x = args; is_pair(x); i++, x = cdr(x)) { s7_pointer byte; s7_int b; byte = car(x); if (!s7_is_integer(byte)) { if (has_methods(byte)) { s7_pointer func; func = find_method(sc, find_let(sc, byte), sc->BYTE_VECTOR); if (func != sc->UNDEFINED) { if (i == 0) return(s7_apply_function(sc, func, args)); string_length(vec) = i; vec = g_string_append(sc, set_plist_2(sc, vec, s7_apply_function(sc, func, x))); set_byte_vector(vec); return(vec); } } return(wrong_type_argument(sc, sc->BYTE_VECTOR, i + 1, byte, T_INTEGER)); } b = s7_integer(byte); if ((b < 0) || (b > 255)) return(simple_wrong_type_argument_with_type(sc, sc->BYTE_VECTOR, byte, AN_UNSIGNED_BYTE)); str[i] = (unsigned char)b; } set_byte_vector(vec); return(vec); } static s7_pointer byte_vector_to_list(s7_scheme *sc, const char *str, int len) { int i; s7_pointer p; if (len == 0) return(sc->NIL); sc->w = sc->NIL; for (i = len - 1; i >= 0; i--) sc->w = cons(sc, small_int((unsigned int)((unsigned char)(str[i]))), sc->w); /* extra cast is not redundant! */ p = sc->w; sc->w = sc->NIL; return(p); } /* -------------------------------- ports -------------------------------- * * originally nil served as stdin and friends, but that made it impossible to catch an error * like (read-line (current-output-port)) when the latter was stdout. So we now have * the built-in constant ports *stdin*, *stdout*, and *stderr*. Some way is needed to * refer to these directly so that (read-line *stdin*) for example can insist on reading * from the terminal, or whatever stdin is. */ static s7_pointer g_is_port_closed(s7_scheme *sc, s7_pointer args) { #define H_is_port_closed "(port-closed? p) returns #t if the port p is closed." #define Q_is_port_closed pl_bt s7_pointer x; x = car(args); if ((is_input_port(x)) || (is_output_port(x))) return(make_boolean(sc, port_is_closed(x))); method_or_bust_with_type(sc, x, sc->IS_PORT_CLOSED, args, make_string_wrapper(sc, "a port"), 0); } static s7_pointer c_port_line_number(s7_scheme *sc, s7_pointer x) { if ((!(is_input_port(x))) || (port_is_closed(x))) method_or_bust_with_type(sc, x, sc->PORT_LINE_NUMBER, list_1(sc, x), AN_INPUT_PORT, 0); return(make_integer(sc, port_line_number(x))); } static s7_pointer g_port_line_number(s7_scheme *sc, s7_pointer args) { #define H_port_line_number "(port-line-number input-file-port) returns the current read line number of port" #define Q_port_line_number s7_make_signature(sc, 2, sc->IS_INTEGER, sc->IS_INPUT_PORT) if (is_null(args)) return(c_port_line_number(sc, sc->input_port)); return(c_port_line_number(sc, car(args))); } PF_TO_PF(port_line_number, c_port_line_number) int s7_port_line_number(s7_pointer p) { if (is_input_port(p)) return(port_line_number(p)); return(0); } const char *s7_port_filename(s7_pointer x) { if (((is_input_port(x)) || (is_output_port(x))) && (!port_is_closed(x))) return(port_filename(x)); return(NULL); } static s7_pointer c_port_filename(s7_scheme *sc, s7_pointer x) { if (((is_input_port(x)) || (is_output_port(x))) && (!port_is_closed(x))) { if (port_filename(x)) return(make_string_wrapper_with_length(sc, port_filename(x), port_filename_length(x))); return(s7_make_string_with_length(sc, "", 0)); /* otherwise (eval-string (port-filename)) and (string->symbol (port-filename)) segfault */ } method_or_bust_with_type(sc, x, sc->PORT_FILENAME, list_1(sc, x), AN_OPEN_PORT, 0); } static s7_pointer g_port_filename(s7_scheme *sc, s7_pointer args) { #define H_port_filename "(port-filename file-port) returns the filename associated with port" #define Q_port_filename s7_make_signature(sc, 2, sc->IS_STRING, sc->T) if (is_null(args)) return(c_port_filename(sc, sc->input_port)); return(c_port_filename(sc, car(args))); } PF_TO_PF(port_filename, c_port_filename) bool s7_is_input_port(s7_scheme *sc, s7_pointer p) { return(is_input_port(p)); } static s7_pointer g_is_input_port(s7_scheme *sc, s7_pointer args) { #define H_is_input_port "(input-port? p) returns #t if p is an input port" #define Q_is_input_port pl_bt check_boolean_method(sc, is_input_port, sc->IS_INPUT_PORT, args); } bool s7_is_output_port(s7_scheme *sc, s7_pointer p) { return(is_output_port(p)); } static s7_pointer g_is_output_port(s7_scheme *sc, s7_pointer args) { #define H_is_output_port "(output-port? p) returns #t if p is an output port" #define Q_is_output_port pl_bt check_boolean_method(sc, is_output_port, sc->IS_OUTPUT_PORT, args); } s7_pointer s7_current_input_port(s7_scheme *sc) { return(sc->input_port); } static s7_pointer g_current_input_port(s7_scheme *sc, s7_pointer args) { #define H_current_input_port "(current-input-port) returns the current input port" #define Q_current_input_port s7_make_signature(sc, 1, sc->IS_INPUT_PORT) return(sc->input_port); } #if (!WITH_PURE_S7) static s7_pointer g_set_current_input_port(s7_scheme *sc, s7_pointer args) { #define H_set_current_input_port "(set-current-input-port port) sets the current-input port to port and returns the previous value of the input port" #define Q_set_current_input_port s7_make_signature(sc, 2, sc->IS_INPUT_PORT, sc->IS_INPUT_PORT) s7_pointer old_port, port; old_port = sc->input_port; port = car(args); if ((is_input_port(port)) && (!port_is_closed(port))) sc->input_port = port; else { check_method(sc, port, s7_make_symbol(sc, "set-current-input-port"), args); return(s7_wrong_type_arg_error(sc, "set-current-input-port", 0, port, "an open input port")); } return(old_port); } #endif s7_pointer s7_set_current_input_port(s7_scheme *sc, s7_pointer port) { s7_pointer old_port; old_port = sc->input_port; sc->input_port = port; return(old_port); } s7_pointer s7_current_output_port(s7_scheme *sc) { return(sc->output_port); } s7_pointer s7_set_current_output_port(s7_scheme *sc, s7_pointer port) { s7_pointer old_port; old_port = sc->output_port; sc->output_port = port; return(old_port); } static s7_pointer g_current_output_port(s7_scheme *sc, s7_pointer args) { #define H_current_output_port "(current-output-port) returns the current output port" #define Q_current_output_port s7_make_signature(sc, 1, sc->IS_OUTPUT_PORT) return(sc->output_port); } #if (!WITH_PURE_S7) static s7_pointer g_set_current_output_port(s7_scheme *sc, s7_pointer args) { #define H_set_current_output_port "(set-current-output-port port) sets the current-output port to port and returns the previous value of the output port" #define Q_set_current_output_port s7_make_signature(sc, 2, sc->IS_OUTPUT_PORT, sc->IS_OUTPUT_PORT) s7_pointer old_port, port; old_port = sc->output_port; port = car(args); if (((is_output_port(port)) && (!port_is_closed(port))) || (port == sc->F)) sc->output_port = port; else { check_method(sc, port, s7_make_symbol(sc, "set-current-output-port"), args); return(s7_wrong_type_arg_error(sc, "set-current-output-port", 0, port, "an open output port")); } return(old_port); } #endif s7_pointer s7_current_error_port(s7_scheme *sc) { return(sc->error_port); } s7_pointer s7_set_current_error_port(s7_scheme *sc, s7_pointer port) { s7_pointer old_port; old_port = sc->error_port; sc->error_port = port; return(old_port); } static s7_pointer g_current_error_port(s7_scheme *sc, s7_pointer args) { #define H_current_error_port "(current-error-port) returns the current error port" #define Q_current_error_port s7_make_signature(sc, 1, sc->IS_OUTPUT_PORT) return(sc->error_port); } static s7_pointer g_set_current_error_port(s7_scheme *sc, s7_pointer args) { #define H_set_current_error_port "(set-current-error-port port) sets the current-error port to port and returns the previous value of the error port" #define Q_set_current_error_port s7_make_signature(sc, 2, sc->IS_OUTPUT_PORT, sc->IS_OUTPUT_PORT) s7_pointer old_port, port; old_port = sc->error_port; port = car(args); if (((is_output_port(port)) && (!port_is_closed(port))) || (port == sc->F)) sc->error_port = port; else { check_method(sc, port, s7_make_symbol(sc, "set-current-error-port"), args); return(s7_wrong_type_arg_error(sc, "set-current-error-port", 0, port, "an open output port")); } return(old_port); } #if (!WITH_PURE_S7) static s7_pointer g_is_char_ready(s7_scheme *sc, s7_pointer args) { #define H_is_char_ready "(char-ready? (port (current-input-port))) returns #t if a character is ready for input on the given port" #define Q_is_char_ready s7_make_signature(sc, 2, sc->IS_BOOLEAN, sc->IS_INPUT_PORT) if (is_not_null(args)) { s7_pointer pt = car(args); if (!is_input_port(pt)) method_or_bust_with_type(sc, pt, sc->IS_CHAR_READY, args, AN_INPUT_PORT, 0); if (port_is_closed(pt)) return(simple_wrong_type_argument_with_type(sc, sc->IS_CHAR_READY, pt, AN_OPEN_PORT)); if (is_function_port(pt)) return((*(port_input_function(pt)))(sc, S7_IS_CHAR_READY, pt)); return(make_boolean(sc, is_string_port(pt))); } return(make_boolean(sc, (is_input_port(sc->input_port)) && (is_string_port(sc->input_port)))); } #endif static s7_pointer g_is_eof_object(s7_scheme *sc, s7_pointer args) { #define H_is_eof_object "(eof-object? val) returns #t if val is the end-of-file object" #define Q_is_eof_object pl_bt check_boolean_method(sc, is_eof, sc->IS_EOF_OBJECT, args); } static int closed_port_read_char(s7_scheme *sc, s7_pointer port); static s7_pointer closed_port_read_line(s7_scheme *sc, s7_pointer port, bool with_eol, bool copied); static void closed_port_write_char(s7_scheme *sc, int c, s7_pointer port); static void closed_port_write_string(s7_scheme *sc, const char *str, int len, s7_pointer port); static void closed_port_display(s7_scheme *sc, const char *s, s7_pointer port); void s7_close_input_port(s7_scheme *sc, s7_pointer p) { #if DEBUGGING if (!is_input_port(p)) fprintf(stderr, "s7_close_input_port: %s\n", DISPLAY(p)); #endif if ((is_immutable_port(p)) || ((is_input_port(p)) && (port_is_closed(p)))) return; if (port_filename(p)) { free(port_filename(p)); port_filename(p) = NULL; } if (is_file_port(p)) { if (port_file(p)) { fclose(port_file(p)); port_file(p) = NULL; } } else { if ((is_string_port(p)) && (port_gc_loc(p) != -1)) s7_gc_unprotect_at(sc, port_gc_loc(p)); } if (port_needs_free(p)) { if (port_data(p)) { free(port_data(p)); port_data(p) = NULL; port_data_size(p) = 0; } port_needs_free(p) = false; } port_read_character(p) = closed_port_read_char; port_read_line(p) = closed_port_read_line; port_write_character(p) = closed_port_write_char; port_write_string(p) = closed_port_write_string; port_display(p) = closed_port_display; port_is_closed(p) = true; } static s7_pointer c_close_input_port(s7_scheme *sc, s7_pointer pt) { if (!is_input_port(pt)) method_or_bust_with_type(sc, pt, sc->CLOSE_INPUT_PORT, set_plist_1(sc, pt), AN_INPUT_PORT, 0); if (!is_immutable_port(pt)) s7_close_input_port(sc, pt); return(sc->UNSPECIFIED); } static s7_pointer g_close_input_port(s7_scheme *sc, s7_pointer args) { #define H_close_input_port "(close-input-port port) closes the port" #define Q_close_input_port s7_make_signature(sc, 2, sc->T, sc->IS_INPUT_PORT) return(c_close_input_port(sc, car(args))); } PF_TO_PF(close_input_port, c_close_input_port) void s7_flush_output_port(s7_scheme *sc, s7_pointer p) { if ((!is_output_port(p)) || (!is_file_port(p)) || (port_is_closed(p)) || (p == sc->F)) return; if (port_file(p)) { if (port_position(p) > 0) { if (fwrite((void *)(port_data(p)), 1, port_position(p), port_file(p)) != port_position(p)) s7_warn(sc, 64, "fwrite trouble in flush-output-port\n"); port_position(p) = 0; } fflush(port_file(p)); } } static s7_pointer g_flush_output_port(s7_scheme *sc, s7_pointer args) { #define H_flush_output_port "(flush-output-port port) flushes the port" #define Q_flush_output_port s7_make_signature(sc, 2, sc->T, sc->IS_OUTPUT_PORT) s7_pointer pt; if (is_null(args)) pt = sc->output_port; else pt = car(args); if (!is_output_port(pt)) { if (pt == sc->F) return(pt); method_or_bust_with_type(sc, pt, sc->FLUSH_OUTPUT_PORT, args, AN_OUTPUT_PORT, 0); } s7_flush_output_port(sc, pt); return(pt); } static s7_pointer c_flush_output_port(s7_scheme *sc) {return(g_flush_output_port(sc, sc->NIL));} PF_0(flush_output_port, c_flush_output_port) static void close_output_port(s7_scheme *sc, s7_pointer p) { if (is_file_port(p)) { if (port_filename(p)) /* only a file (output) port has a filename */ { free(port_filename(p)); port_filename(p) = NULL; port_filename_length(p) = 0; } if (port_file(p)) { if (port_position(p) > 0) { if (fwrite((void *)(port_data(p)), 1, port_position(p), port_file(p)) != port_position(p)) s7_warn(sc, 64, "fwrite trouble in close-output-port\n"); port_position(p) = 0; } free(port_data(p)); fflush(port_file(p)); fclose(port_file(p)); port_file(p) = NULL; } } else { if ((is_string_port(p)) && (port_data(p))) { free(port_data(p)); port_data(p) = NULL; port_data_size(p) = 0; port_needs_free(p) = false; } } port_read_character(p) = closed_port_read_char; port_read_line(p) = closed_port_read_line; port_write_character(p) = closed_port_write_char; port_write_string(p) = closed_port_write_string; port_display(p) = closed_port_display; port_is_closed(p) = true; } void s7_close_output_port(s7_scheme *sc, s7_pointer p) { if ((is_immutable_port(p)) || ((is_output_port(p)) && (port_is_closed(p))) || (p == sc->F)) return; close_output_port(sc, p); } static s7_pointer c_close_output_port(s7_scheme *sc, s7_pointer pt) { if (!is_output_port(pt)) { if (pt == sc->F) return(sc->UNSPECIFIED); method_or_bust_with_type(sc, pt, sc->CLOSE_OUTPUT_PORT, set_plist_1(sc, pt), AN_OUTPUT_PORT, 0); } if (!(is_immutable_port(pt))) s7_close_output_port(sc, pt); return(sc->UNSPECIFIED); } static s7_pointer g_close_output_port(s7_scheme *sc, s7_pointer args) { #define H_close_output_port "(close-output-port port) closes the port" #define Q_close_output_port s7_make_signature(sc, 2, sc->T, sc->IS_OUTPUT_PORT) return(c_close_output_port(sc, car(args))); } PF_TO_PF(close_output_port, c_close_output_port) /* -------- read character functions -------- */ static int file_read_char(s7_scheme *sc, s7_pointer port) { return(fgetc(port_file(port))); } static int function_read_char(s7_scheme *sc, s7_pointer port) { return(character((*(port_input_function(port)))(sc, S7_READ_CHAR, port))); } static int string_read_char(s7_scheme *sc, s7_pointer port) { if (port_data_size(port) <= port_position(port)) /* port_string_length is 0 if no port string */ return(EOF); return((unsigned char)port_data(port)[port_position(port)++]); } static int output_read_char(s7_scheme *sc, s7_pointer port) { simple_wrong_type_argument_with_type(sc, sc->READ_CHAR, port, AN_INPUT_PORT); return(0); } static int closed_port_read_char(s7_scheme *sc, s7_pointer port) { simple_wrong_type_argument_with_type(sc, sc->READ_CHAR, port, AN_OPEN_PORT); return(0); } /* -------- read line functions -------- */ static s7_pointer output_read_line(s7_scheme *sc, s7_pointer port, bool with_eol, bool copied) { return(simple_wrong_type_argument_with_type(sc, sc->READ_LINE, port, AN_INPUT_PORT)); } static s7_pointer closed_port_read_line(s7_scheme *sc, s7_pointer port, bool with_eol, bool copied) { return(simple_wrong_type_argument_with_type(sc, sc->READ_LINE, port, AN_OPEN_PORT)); } static s7_pointer function_read_line(s7_scheme *sc, s7_pointer port, bool with_eol, bool copied) { return((*(port_input_function(port)))(sc, S7_READ_LINE, port)); } static s7_pointer stdin_read_line(s7_scheme *sc, s7_pointer port, bool with_eol, bool copied) { if (sc->read_line_buf == NULL) { sc->read_line_buf_size = 1024; sc->read_line_buf = (char *)malloc(sc->read_line_buf_size * sizeof(char)); } if (fgets(sc->read_line_buf, sc->read_line_buf_size, stdin) != NULL) return(s7_make_string(sc, sc->read_line_buf)); /* fgets adds the trailing '\0' */ return(s7_make_string_with_length(sc, NULL, 0)); } static s7_pointer file_read_line(s7_scheme *sc, s7_pointer port, bool with_eol, bool copied) { char *buf; int read_size, previous_size = 0; if (sc->read_line_buf == NULL) { sc->read_line_buf_size = 1024; sc->read_line_buf = (char *)malloc(sc->read_line_buf_size * sizeof(char)); } buf = sc->read_line_buf; read_size = sc->read_line_buf_size; while (true) { char *p, *rtn; size_t len; p = fgets(buf, read_size, port_file(port)); if (!p) return(sc->EOF_OBJECT); rtn = strchr(buf, (int)'\n'); if (rtn) { port_line_number(port)++; return(s7_make_string_with_length(sc, sc->read_line_buf, (with_eol) ? (previous_size + rtn - p + 1) : (previous_size + rtn - p))); } /* if no newline, then either at eof or need bigger buffer */ len = strlen(sc->read_line_buf); if ((len + 1) < sc->read_line_buf_size) return(s7_make_string_with_length(sc, sc->read_line_buf, len)); previous_size = sc->read_line_buf_size; sc->read_line_buf_size *= 2; sc->read_line_buf = (char *)realloc(sc->read_line_buf, sc->read_line_buf_size * sizeof(char)); read_size = previous_size; previous_size -= 1; buf = (char *)(sc->read_line_buf + previous_size); } return(sc->EOF_OBJECT); } static s7_pointer string_read_line(s7_scheme *sc, s7_pointer port, bool with_eol, bool copied) { unsigned int i, port_start; unsigned char *port_str, *cur, *start; port_start = port_position(port); port_str = port_data(port); start = (unsigned char *)(port_str + port_start); cur = (unsigned char *)strchr((const char *)start, (int)'\n'); /* this can run off the end making valgrind unhappy, but I think it's innocuous */ if (cur) { port_line_number(port)++; i = cur - port_str; port_position(port) = i + 1; if (copied) return(s7_make_string_with_length(sc, (const char *)start, ((with_eol) ? i + 1 : i) - port_start)); return(make_string_wrapper_with_length(sc, (char *)start, ((with_eol) ? i + 1 : i) - port_start)); } i = port_data_size(port); port_position(port) = i; if (i <= port_start) /* the < part can happen -- if not caught we try to create a string of length -1 -> segfault */ return(sc->EOF_OBJECT); if (copied) return(s7_make_string_with_length(sc, (const char *)start, i - port_start)); return(make_string_wrapper_with_length(sc, (char *)start, i - port_start)); } /* -------- write character functions -------- */ static void resize_port_data(s7_pointer pt, int new_size) { int loc; loc = port_data_size(pt); port_data_size(pt) = new_size; port_data(pt) = (unsigned char *)realloc(port_data(pt), new_size * sizeof(unsigned char)); memclr((void *)(port_data(pt) + loc), new_size - loc); } static void string_write_char(s7_scheme *sc, int c, s7_pointer pt) { if (port_position(pt) >= port_data_size(pt)) resize_port_data(pt, port_data_size(pt) * 2); port_data(pt)[port_position(pt)++] = c; } static void stdout_write_char(s7_scheme *sc, int c, s7_pointer port) { fputc(c, stdout); } static void stderr_write_char(s7_scheme *sc, int c, s7_pointer port) { fputc(c, stderr); } static void function_write_char(s7_scheme *sc, int c, s7_pointer port) { (*(port_output_function(port)))(sc, c, port); } #define PORT_DATA_SIZE 256 static void file_write_char(s7_scheme *sc, int c, s7_pointer port) { if (port_position(port) == PORT_DATA_SIZE) { if (fwrite((void *)(port_data(port)), 1, PORT_DATA_SIZE, port_file(port)) != PORT_DATA_SIZE) s7_warn(sc, 64, "fwrite trouble during write-char\n"); port_position(port) = 0; } port_data(port)[port_position(port)++] = (unsigned char)c; } static void input_write_char(s7_scheme *sc, int c, s7_pointer port) { simple_wrong_type_argument_with_type(sc, sc->WRITE_CHAR, port, AN_OUTPUT_PORT); } static void closed_port_write_char(s7_scheme *sc, int c, s7_pointer port) { simple_wrong_type_argument_with_type(sc, sc->WRITE_CHAR, port, AN_OPEN_PORT); } /* -------- write string functions -------- */ static void input_write_string(s7_scheme *sc, const char *str, int len, s7_pointer port) { simple_wrong_type_argument_with_type(sc, sc->WRITE, port, AN_OUTPUT_PORT); } static void closed_port_write_string(s7_scheme *sc, const char *str, int len, s7_pointer port) { simple_wrong_type_argument_with_type(sc, sc->WRITE, port, AN_OPEN_PORT); } static void input_display(s7_scheme *sc, const char *s, s7_pointer port) { simple_wrong_type_argument_with_type(sc, sc->WRITE, port, AN_OUTPUT_PORT); } static void closed_port_display(s7_scheme *sc, const char *s, s7_pointer port) { simple_wrong_type_argument_with_type(sc, sc->WRITE, port, AN_OPEN_PORT); } static void stdout_write_string(s7_scheme *sc, const char *str, int len, s7_pointer port) { if (str[len] == '\0') fputs(str, stdout); else { int i; for (i = 0; i < len; i++) fputc(str[i], stdout); } } static void stderr_write_string(s7_scheme *sc, const char *str, int len, s7_pointer port) { if (str[len] == '\0') fputs(str, stderr); else { int i; for (i = 0; i < len; i++) fputc(str[i], stderr); } } static void string_write_string(s7_scheme *sc, const char *str, int len, s7_pointer pt) { int new_len; /* len is known to be non-zero */ new_len = port_position(pt) + len; if (new_len >= (int)port_data_size(pt)) resize_port_data(pt, new_len * 2); memcpy((void *)(port_data(pt) + port_position(pt)), (void *)str, len); /* memcpy is much faster than the equivalent while loop */ port_position(pt) = new_len; } static s7_pointer write_string_chooser(s7_scheme *sc, s7_pointer f, int args, s7_pointer expr) { check_for_substring_temp(sc, expr); return(f); } static void file_display(s7_scheme *sc, const char *s, s7_pointer port) { if (s) { if (port_position(port) > 0) { if (fwrite((void *)(port_data(port)), 1, port_position(port), port_file(port)) != port_position(port)) s7_warn(sc, 64, "fwrite trouble in display\n"); port_position(port) = 0; } if (fputs(s, port_file(port)) == EOF) s7_warn(sc, 64, "write to %s: %s\n", port_filename(port), strerror(errno)); } } static void file_write_string(s7_scheme *sc, const char *str, int len, s7_pointer pt) { int new_len; new_len = port_position(pt) + len; if (new_len >= PORT_DATA_SIZE) { if (port_position(pt) > 0) { if (fwrite((void *)(port_data(pt)), 1, port_position(pt), port_file(pt)) != port_position(pt)) s7_warn(sc, 64, "fwrite trouble in write-string\n"); port_position(pt) = 0; } if (fwrite((void *)str, 1, len, port_file(pt)) != (size_t)len) s7_warn(sc, 64, "fwrite trouble in write-string\n"); } else { memcpy((void *)(port_data(pt) + port_position(pt)), (void *)str, len); port_position(pt) = new_len; } } static void string_display(s7_scheme *sc, const char *s, s7_pointer port) { if (s) string_write_string(sc, s, safe_strlen(s), port); } static void function_display(s7_scheme *sc, const char *s, s7_pointer port) { if (s) { for (; *s; s++) (*(port_output_function(port)))(sc, *s, port); } } static void function_write_string(s7_scheme *sc, const char *str, int len, s7_pointer pt) { int i; for (i = 0; i < len; i++) (*(port_output_function(pt)))(sc, str[i], pt); } static void stdout_display(s7_scheme *sc, const char *s, s7_pointer port) { if (s) fputs(s, stdout); } static void stderr_display(s7_scheme *sc, const char *s, s7_pointer port) { if (s) fputs(s, stderr); } static s7_pointer g_write_string(s7_scheme *sc, s7_pointer args) { #define H_write_string "(write-string str port start end) writes str to port." #define Q_write_string s7_make_circular_signature(sc, 3, 4, sc->IS_STRING, sc->IS_STRING, sc->IS_OUTPUT_PORT, sc->IS_INTEGER) s7_pointer str, port; s7_int start = 0, end; str = car(args); if (!is_string(str)) method_or_bust(sc, str, sc->WRITE_STRING, args, T_STRING, 1); end = string_length(str); if (!is_null(cdr(args))) { s7_pointer inds; port = cadr(args); inds = cddr(args); if (!is_null(inds)) { s7_pointer p; p = start_and_end(sc, sc->WRITE_STRING, NULL, inds, args, 3, &start, &end); if (p != sc->GC_NIL) return(p); } } else port = sc->output_port; if (!is_output_port(port)) { if (port == sc->F) { s7_pointer x; int len; if ((start == 0) && (end == string_length(str))) return(str); len = (int)(end - start); x = s7_make_string_with_length(sc, (char *)(string_value(str) + start), len); string_value(x)[len] = 0; return(x); } method_or_bust_with_type(sc, port, sc->WRITE_STRING, args, AN_OUTPUT_PORT, 2); } if (start == 0) port_write_string(port)(sc, string_value(str), end, port); else port_write_string(port)(sc, (char *)(string_value(str) + start), (end - start), port); return(str); } static s7_pointer c_write_string(s7_scheme *sc, s7_pointer x) {return(g_write_string(sc, set_plist_1(sc, x)));} PF_TO_PF(write_string, c_write_string) /* -------- skip to newline readers -------- */ static token_t file_read_semicolon(s7_scheme *sc, s7_pointer pt) { int c; do (c = fgetc(port_file(pt))); while ((c != '\n') && (c != EOF)); port_line_number(pt)++; if (c == EOF) return(TOKEN_EOF); return(token(sc)); } static token_t string_read_semicolon(s7_scheme *sc, s7_pointer pt) { const char *orig_str, *str; str = (const char *)(port_data(pt) + port_position(pt)); orig_str = strchr(str, (int)'\n'); if (!orig_str) { port_position(pt) = port_data_size(pt); return(TOKEN_EOF); } port_position(pt) += (orig_str - str + 1); /* + 1 because strchr leaves orig_str pointing at the newline */ port_line_number(pt)++; return(token(sc)); } /* -------- white space readers -------- */ static int file_read_white_space(s7_scheme *sc, s7_pointer port) { int c; while (is_white_space(c = fgetc(port_file(port)))) if (c == '\n') port_line_number(port)++; return(c); } static int terminated_string_read_white_space(s7_scheme *sc, s7_pointer pt) { const unsigned char *str; unsigned char c; /* here we know we have null termination and white_space[#\null] is false. */ str = (const unsigned char *)(port_data(pt) + port_position(pt)); while (white_space[c = *str++]) /* (let ((ÿa 1)) ÿa) -- 255 is not -1 = EOF */ if (c == '\n') port_line_number(pt)++; if (c) port_position(pt) = str - port_data(pt); else port_position(pt) = port_data_size(pt); return((int)c); } /* name (alphanumeric token) readers */ static void resize_strbuf(s7_scheme *sc, unsigned int needed_size) { unsigned int i, old_size; old_size = sc->strbuf_size; while (sc->strbuf_size <= needed_size) sc->strbuf_size *= 2; sc->strbuf = (char *)realloc(sc->strbuf, sc->strbuf_size * sizeof(char)); for (i = old_size; i < sc->strbuf_size; i++) sc->strbuf[i] = '\0'; } static s7_pointer file_read_name_or_sharp(s7_scheme *sc, s7_pointer pt, bool atom_case) { int c; unsigned int i = 1; /* sc->strbuf[0] has the first char of the string we're reading */ do { c = fgetc(port_file(pt)); /* might return EOF */ if (c == '\n') port_line_number(pt)++; sc->strbuf[i++] = c; if (i >= sc->strbuf_size) resize_strbuf(sc, i); } while ((c != EOF) && (char_ok_in_a_name[c])); if ((i == 2) && (sc->strbuf[0] == '\\')) sc->strbuf[2] = '\0'; else { if (c != EOF) { if (c == '\n') port_line_number(pt)--; ungetc(c, port_file(pt)); } sc->strbuf[i - 1] = '\0'; } if (atom_case) return(make_atom(sc, sc->strbuf, BASE_10, SYMBOL_OK, WITH_OVERFLOW_ERROR)); return(make_sharp_constant(sc, sc->strbuf, UNNESTED_SHARP, BASE_10, WITH_OVERFLOW_ERROR)); } static s7_pointer file_read_name(s7_scheme *sc, s7_pointer pt) { return(file_read_name_or_sharp(sc, pt, true)); } static s7_pointer file_read_sharp(s7_scheme *sc, s7_pointer pt) { return(file_read_name_or_sharp(sc, pt, false)); } static s7_pointer string_read_name_no_free(s7_scheme *sc, s7_pointer pt) { /* sc->strbuf[0] has the first char of the string we're reading */ unsigned int k; char *str, *orig_str; str = (char *)(port_data(pt) + port_position(pt)); if (!char_ok_in_a_name[(unsigned char)*str]) { s7_pointer result; result = sc->singletons[(unsigned char)(sc->strbuf[0])]; if (!result) { sc->strbuf[1] = '\0'; result = make_symbol_with_length(sc, sc->strbuf, 1); sc->singletons[(unsigned char)(sc->strbuf[0])] = result; } return(result); } orig_str = (char *)(str - 1); str++; while (char_ok_in_a_name[(unsigned char)(*str)]) {str++;} k = str - orig_str; if (*str != 0) port_position(pt) += (k - 1); else port_position(pt) = port_data_size(pt); /* this is equivalent to: * str = strpbrk(str, "(); \"\t\r\n"); * if (!str) * { * k = strlen(orig_str); * str = (char *)(orig_str + k); * } * else k = str - orig_str; * but slightly faster. */ if (!number_table[(unsigned char)(*orig_str)]) return(make_symbol_with_length(sc, orig_str, k)); /* eval_c_string string is a constant so we can't set and unset the token's end char */ if ((k + 1) >= sc->strbuf_size) resize_strbuf(sc, k + 1); memcpy((void *)(sc->strbuf), (void *)orig_str, k); sc->strbuf[k] = '\0'; return(make_atom(sc, sc->strbuf, BASE_10, SYMBOL_OK, WITH_OVERFLOW_ERROR)); } static s7_pointer string_read_sharp(s7_scheme *sc, s7_pointer pt) { /* sc->strbuf[0] has the first char of the string we're reading. * since a *#readers* function might want to get further input, we can't mess with the input even when it is otherwise safe */ unsigned int k; char *orig_str, *str; str = (char *)(port_data(pt) + port_position(pt)); if (!char_ok_in_a_name[(unsigned char)*str]) { if (sc->strbuf[0] == 'f') return(sc->F); if (sc->strbuf[0] == 't') return(sc->T); if (sc->strbuf[0] == '\\') { /* must be from #\( and friends -- a character that happens to be not ok-in-a-name */ sc->strbuf[1] = str[0]; sc->strbuf[2] = '\0'; port_position(pt)++; } else sc->strbuf[1] = '\0'; return(make_sharp_constant(sc, sc->strbuf, UNNESTED_SHARP, BASE_10, WITH_OVERFLOW_ERROR)); } orig_str = (char *)(str - 1); str++; while (char_ok_in_a_name[(unsigned char)(*str)]) {str++;} k = str - orig_str; if (*str != 0) port_position(pt) += (k - 1); else port_position(pt) += k; if ((k + 1) >= sc->strbuf_size) resize_strbuf(sc, k + 1); memcpy((void *)(sc->strbuf), (void *)orig_str, k); sc->strbuf[k] = '\0'; return(make_sharp_constant(sc, sc->strbuf, UNNESTED_SHARP, BASE_10, WITH_OVERFLOW_ERROR)); } static s7_pointer string_read_name(s7_scheme *sc, s7_pointer pt) { /* port_string was allocated (and read from a file) so we can mess with it directly */ s7_pointer result; unsigned int k; char *orig_str, *str; char endc; str = (char *)(port_data(pt) + port_position(pt)); if (!char_ok_in_a_name[(unsigned char)*str]) { s7_pointer result; result = sc->singletons[(unsigned char)(sc->strbuf[0])]; if (!result) { sc->strbuf[1] = '\0'; result = make_symbol_with_length(sc, sc->strbuf, 1); sc->singletons[(unsigned char)(sc->strbuf[0])] = result; } return(result); } orig_str = (char *)(str - 1); str++; while (char_ok_in_a_name[(unsigned char)(*str)]) {str++;} k = str - orig_str; if (*str != 0) port_position(pt) += (k - 1); else port_position(pt) = port_data_size(pt); if (!number_table[(unsigned char)(*orig_str)]) return(make_symbol_with_length(sc, orig_str, k)); endc = (*str); (*str) = '\0'; result = make_atom(sc, orig_str, BASE_10, SYMBOL_OK, WITH_OVERFLOW_ERROR); (*str) = endc; return(result); } static s7_pointer read_file(s7_scheme *sc, FILE *fp, const char *name, long max_size, const char *caller) { s7_pointer port; #ifndef _MSC_VER long size; #endif int port_loc; new_cell(sc, port, T_INPUT_PORT); port_loc = s7_gc_protect(sc, port); port_port(port) = alloc_port(sc); port_is_closed(port) = false; port_original_input_string(port) = sc->NIL; port_write_character(port) = input_write_char; port_write_string(port) = input_write_string; /* if we're constantly opening files, and each open saves the file name in permanent * memory, we gradually core-up. */ port_filename_length(port) = safe_strlen(name); port_filename(port) = copy_string_with_length(name, port_filename_length(port)); port_line_number(port) = 1; /* first line is numbered 1 */ add_input_port(sc, port); #ifndef _MSC_VER /* this doesn't work in MS C */ fseek(fp, 0, SEEK_END); size = ftell(fp); rewind(fp); /* pseudo files (under /proc for example) have size=0, but we can read them, so don't assume a 0 length file is empty */ if ((size > 0) && /* if (size != 0) we get (open-input-file "/dev/tty") -> (open "/dev/tty") read 0 bytes of an expected -1? */ ((max_size < 0) || (size < max_size))) { size_t bytes; unsigned char *content; content = (unsigned char *)malloc((size + 2) * sizeof(unsigned char)); bytes = fread(content, sizeof(unsigned char), size, fp); if (bytes != (size_t)size) { char tmp[256]; int len; len = snprintf(tmp, 256, "(%s \"%s\") read %ld bytes of an expected %ld?", caller, name, (long)bytes, size); port_write_string(sc->output_port)(sc, tmp, len, sc->output_port); size = bytes; } content[size] = '\0'; content[size + 1] = '\0'; fclose(fp); port_type(port) = STRING_PORT; port_data(port) = content; port_data_size(port) = size; port_position(port) = 0; port_needs_free(port) = true; port_gc_loc(port) = -1; port_read_character(port) = string_read_char; port_read_line(port) = string_read_line; port_display(port) = input_display; port_read_semicolon(port) = string_read_semicolon; port_read_white_space(port) = terminated_string_read_white_space; port_read_name(port) = string_read_name; port_read_sharp(port) = string_read_sharp; } else { port_file(port) = fp; port_type(port) = FILE_PORT; port_needs_free(port) = false; port_read_character(port) = file_read_char; port_read_line(port) = file_read_line; port_display(port) = input_display; port_read_semicolon(port) = file_read_semicolon; port_read_white_space(port) = file_read_white_space; port_read_name(port) = file_read_name; port_read_sharp(port) = file_read_sharp; /* was string_read_sharp?? */ } #else /* _stat64 is no better than the fseek/ftell route, and * GetFileSizeEx and friends requires Windows.h which makes hash of everything else. * fread until done takes too long on big files, so use a file port */ port_file(port) = fp; port_type(port) = FILE_PORT; port_needs_free(port) = false; port_read_character(port) = file_read_char; port_read_line(port) = file_read_line; port_display(port) = input_display; port_read_semicolon(port) = file_read_semicolon; port_read_white_space(port) = file_read_white_space; port_read_name(port) = file_read_name; port_read_sharp(port) = file_read_sharp; #endif s7_gc_unprotect_at(sc, port_loc); return(port); } static s7_pointer make_input_file(s7_scheme *sc, const char *name, FILE *fp) { #define MAX_SIZE_FOR_STRING_PORT 5000000 return(read_file(sc, fp, name, MAX_SIZE_FOR_STRING_PORT, "open")); } #if (!MS_WINDOWS) #include #endif static bool is_directory(const char *filename) { #if (!MS_WINDOWS) #ifdef S_ISDIR struct stat statbuf; return((stat(filename, &statbuf) >= 0) && (S_ISDIR(statbuf.st_mode))); #endif #endif return(false); } static s7_pointer open_input_file_1(s7_scheme *sc, const char *name, const char *mode, const char *caller) { FILE *fp; /* see if we can open this file before allocating a port */ if (is_directory(name)) return(file_error(sc, caller, "is a directory", name)); errno = 0; fp = fopen(name, mode); if (!fp) { #if (!MS_WINDOWS) if (errno == EINVAL) return(file_error(sc, caller, "invalid mode", mode)); #if WITH_GCC /* catch one special case, "~/..." */ if ((name[0] == '~') && (name[1] == '/')) { char *home; home = getenv("HOME"); if (home) { char *filename; int len; len = safe_strlen(name) + safe_strlen(home) + 1; tmpbuf_malloc(filename, len); snprintf(filename, len, "%s%s", home, (char *)(name + 1)); fp = fopen(filename, "r"); tmpbuf_free(filename, len); if (fp) return(make_input_file(sc, name, fp)); } } #endif #endif return(file_error(sc, caller, strerror(errno), name)); } return(make_input_file(sc, name, fp)); } s7_pointer s7_open_input_file(s7_scheme *sc, const char *name, const char *mode) { return(open_input_file_1(sc, name, mode, "open-input-file")); } static s7_pointer g_open_input_file(s7_scheme *sc, s7_pointer args) { #define H_open_input_file "(open-input-file filename (mode \"r\")) opens filename for reading" #define Q_open_input_file s7_make_signature(sc, 3, sc->IS_INPUT_PORT, sc->IS_STRING, sc->IS_STRING) s7_pointer name = car(args); if (!is_string(name)) method_or_bust(sc, name, sc->OPEN_INPUT_FILE, args, T_STRING, 1); /* what if the file name is a byte-vector? currently we accept it */ if (is_pair(cdr(args))) { s7_pointer mode; mode = cadr(args); if (!is_string(mode)) method_or_bust_with_type(sc, mode, sc->OPEN_INPUT_FILE, args, make_string_wrapper(sc, "a string (a mode such as \"r\")"), 2); /* since scheme allows embedded nulls, dumb stuff is accepted here: (open-input-file file "a\x00b") -- should this be an error? */ return(open_input_file_1(sc, string_value(name), string_value(mode), "open-input-file")); } return(open_input_file_1(sc, string_value(name), "r", "open-input-file")); } static void make_standard_ports(s7_scheme *sc) { s7_pointer x; /* standard output */ x = alloc_pointer(); unheap(x); set_type(x, T_OUTPUT_PORT | T_IMMUTABLE); port_port(x) = (port_t *)calloc(1, sizeof(port_t)); port_type(x) = FILE_PORT; port_data(x) = NULL; port_is_closed(x) = false; port_filename_length(x) = 8; port_filename(x) = copy_string_with_length("*stdout*", 8); port_file_number(x) = remember_file_name(sc, port_filename(x)); /* these numbers need to be correct for the evaluator (__FUNC__ data) */ port_line_number(x) = 0; port_file(x) = stdout; port_needs_free(x) = false; port_read_character(x) = output_read_char; port_read_line(x) = output_read_line; port_display(x) = stdout_display; port_write_character(x) = stdout_write_char; port_write_string(x) = stdout_write_string; sc->standard_output = x; /* standard error */ x = alloc_pointer(); unheap(x); set_type(x, T_OUTPUT_PORT | T_IMMUTABLE); port_port(x) = (port_t *)calloc(1, sizeof(port_t)); port_type(x) = FILE_PORT; port_data(x) = NULL; port_is_closed(x) = false; port_filename_length(x) = 8; port_filename(x) = copy_string_with_length("*stderr*", 8); port_file_number(x) = remember_file_name(sc, port_filename(x)); port_line_number(x) = 0; port_file(x) = stderr; port_needs_free(x) = false; port_read_character(x) = output_read_char; port_read_line(x) = output_read_line; port_display(x) = stderr_display; port_write_character(x) = stderr_write_char; port_write_string(x) = stderr_write_string; sc->standard_error = x; /* standard input */ x = alloc_pointer(); unheap(x); set_type(x, T_INPUT_PORT | T_IMMUTABLE); port_port(x) = (port_t *)calloc(1, sizeof(port_t)); port_type(x) = FILE_PORT; port_is_closed(x) = false; port_original_input_string(x) = sc->NIL; port_filename_length(x) = 7; port_filename(x) = copy_string_with_length("*stdin*", 7); port_file_number(x) = remember_file_name(sc, port_filename(x)); port_line_number(x) = 0; port_file(x) = stdin; port_needs_free(x) = false; port_read_character(x) = file_read_char; port_read_line(x) = stdin_read_line; port_display(x) = input_display; port_read_semicolon(x) = file_read_semicolon; port_read_white_space(x) = file_read_white_space; port_read_name(x) = file_read_name; port_read_sharp(x) = file_read_sharp; port_write_character(x) = input_write_char; port_write_string(x) = input_write_string; sc->standard_input = x; s7_define_constant(sc, "*stdin*", sc->standard_input); s7_define_constant(sc, "*stdout*", sc->standard_output); s7_define_constant(sc, "*stderr*", sc->standard_error); sc->input_port = sc->standard_input; sc->output_port = sc->standard_output; sc->error_port = sc->standard_error; sc->current_file = NULL; sc->current_line = -1; } s7_pointer s7_open_output_file(s7_scheme *sc, const char *name, const char *mode) { FILE *fp; s7_pointer x; /* see if we can open this file before allocating a port */ errno = 0; fp = fopen(name, mode); if (!fp) { #if (!MS_WINDOWS) if (errno == EINVAL) return(file_error(sc, "open-output-file", "invalid mode", mode)); #endif return(file_error(sc, "open-output-file", strerror(errno), name)); } new_cell(sc, x, T_OUTPUT_PORT); port_port(x) = alloc_port(sc); port_type(x) = FILE_PORT; port_is_closed(x) = false; port_filename_length(x) = safe_strlen(name); port_filename(x) = copy_string_with_length(name, port_filename_length(x)); port_line_number(x) = 1; port_file(x) = fp; port_needs_free(x) = false; port_read_character(x) = output_read_char; port_read_line(x) = output_read_line; port_display(x) = file_display; port_write_character(x) = file_write_char; port_write_string(x) = file_write_string; port_position(x) = 0; port_data_size(x) = PORT_DATA_SIZE; port_data(x) = (unsigned char *)malloc(PORT_DATA_SIZE); /* was +8? */ add_output_port(sc, x); return(x); } static s7_pointer g_open_output_file(s7_scheme *sc, s7_pointer args) { #define H_open_output_file "(open-output-file filename (mode \"w\")) opens filename for writing" #define Q_open_output_file s7_make_signature(sc, 3, sc->IS_OUTPUT_PORT, sc->IS_STRING, sc->IS_STRING) s7_pointer name = car(args); if (!is_string(name)) method_or_bust(sc, name, sc->OPEN_OUTPUT_FILE, args, T_STRING, 1); if (is_pair(cdr(args))) { if (!is_string(cadr(args))) method_or_bust_with_type(sc, cadr(args), sc->OPEN_OUTPUT_FILE, args, make_string_wrapper(sc, "a string (a mode such as \"w\")"), 2); return(s7_open_output_file(sc, string_value(name), string_value(cadr(args)))); } return(s7_open_output_file(sc, string_value(name), "w")); } static s7_pointer open_input_string(s7_scheme *sc, const char *input_string, int len) { s7_pointer x; new_cell(sc, x, T_INPUT_PORT); port_port(x) = alloc_port(sc); port_type(x) = STRING_PORT; port_is_closed(x) = false; port_original_input_string(x) = sc->NIL; port_data(x) = (unsigned char *)input_string; port_data_size(x) = len; port_position(x) = 0; port_filename_length(x) = 0; port_filename(x) = NULL; port_file_number(x) = 0; /* unsigned int */ port_line_number(x) = 0; port_needs_free(x) = false; port_gc_loc(x) = -1; port_read_character(x) = string_read_char; port_read_line(x) = string_read_line; port_display(x) = input_display; port_read_semicolon(x) = string_read_semicolon; #if DEBUGGING if (input_string[len] != '\0') fprintf(stderr, "read_white_space string is not terminated: %s", input_string); #endif port_read_white_space(x) = terminated_string_read_white_space; port_read_name(x) = string_read_name_no_free; port_read_sharp(x) = string_read_sharp; port_write_character(x) = input_write_char; port_write_string(x) = input_write_string; add_input_port(sc, x); return(x); } static s7_pointer open_and_protect_input_string(s7_scheme *sc, s7_pointer str) { s7_pointer p; p = open_input_string(sc, string_value(str), string_length(str)); port_gc_loc(p) = s7_gc_protect(sc, str); return(p); } s7_pointer s7_open_input_string(s7_scheme *sc, const char *input_string) { return(open_input_string(sc, input_string, safe_strlen(input_string))); } static s7_pointer g_open_input_string(s7_scheme *sc, s7_pointer args) { #define H_open_input_string "(open-input-string str) opens an input port reading str" #define Q_open_input_string s7_make_signature(sc, 2, sc->IS_INPUT_PORT, sc->IS_STRING) s7_pointer input_string, port; input_string = car(args); if (!is_string(input_string)) method_or_bust(sc, input_string, sc->OPEN_INPUT_STRING, args, T_STRING, 0); port = open_and_protect_input_string(sc, input_string); return(port); } #define FORMAT_PORT_LENGTH 128 /* the large majority (> 99% in my tests) of the output strings have less than 128 chars when the port is finally closed * 256 is slightly slower (the calloc time below dominates the realloc time in string_write_string) * 64 is much slower (realloc dominates) */ static s7_pointer open_output_string(s7_scheme *sc, int len) { s7_pointer x; new_cell(sc, x, T_OUTPUT_PORT); port_port(x) = alloc_port(sc); port_type(x) = STRING_PORT; port_is_closed(x) = false; port_data_size(x) = len; port_data(x) = (unsigned char *)malloc(len * sizeof(unsigned char)); /* was +8? */ port_data(x)[0] = '\0'; /* in case s7_get_output_string before any output */ port_position(x) = 0; port_needs_free(x) = true; port_read_character(x) = output_read_char; port_read_line(x) = output_read_line; port_display(x) = string_display; port_write_character(x) = string_write_char; port_write_string(x) = string_write_string; add_output_port(sc, x); return(x); } s7_pointer s7_open_output_string(s7_scheme *sc) { return(open_output_string(sc, sc->initial_string_port_length)); } static s7_pointer g_open_output_string(s7_scheme *sc, s7_pointer args) { #define H_open_output_string "(open-output-string) opens an output string port" #define Q_open_output_string s7_make_signature(sc, 1, sc->IS_OUTPUT_PORT) return(s7_open_output_string(sc)); } const char *s7_get_output_string(s7_scheme *sc, s7_pointer p) { port_data(p)[port_position(p)] = '\0'; return((const char *)port_data(p)); } static s7_pointer g_get_output_string(s7_scheme *sc, s7_pointer args) { #define H_get_output_string "(get-output-string port clear-port) returns the output accumulated in port. \ If the optional 'clear-port' is #t, the current string is flushed." #define Q_get_output_string s7_make_signature(sc, 3, sc->IS_STRING, sc->IS_OUTPUT_PORT, sc->IS_BOOLEAN) s7_pointer p, result; bool clear_port = false; if (is_pair(cdr(args))) { p = cadr(args); if (!s7_is_boolean(p)) return(wrong_type_argument(sc, sc->GET_OUTPUT_STRING, 2, p, T_BOOLEAN)); clear_port = (p == sc->T); } p = car(args); if ((!is_output_port(p)) || (!is_string_port(p))) { if (p == sc->F) return(make_empty_string(sc, 0, 0)); method_or_bust_with_type(sc, p, sc->GET_OUTPUT_STRING, args, make_string_wrapper(sc, "an output string port"), 0); } if (port_is_closed(p)) return(simple_wrong_type_argument_with_type(sc, sc->GET_OUTPUT_STRING, p, make_string_wrapper(sc, "an active (open) string port"))); result = s7_make_string_with_length(sc, (const char *)port_data(p), port_position(p)); if (clear_port) { port_position(p) = 0; port_data(p)[0] = '\0'; } return(result); } s7_pointer s7_open_input_function(s7_scheme *sc, s7_pointer (*function)(s7_scheme *sc, s7_read_t read_choice, s7_pointer port)) { s7_pointer x; new_cell(sc, x, T_INPUT_PORT); port_port(x) = alloc_port(sc); port_type(x) = FUNCTION_PORT; port_is_closed(x) = false; port_original_input_string(x) = sc->NIL; port_needs_free(x) = false; port_input_function(x) = function; port_read_character(x) = function_read_char; port_read_line(x) = function_read_line; port_display(x) = input_display; port_write_character(x) = input_write_char; port_write_string(x) = input_write_string; add_input_port(sc, x); return(x); } s7_pointer s7_open_output_function(s7_scheme *sc, void (*function)(s7_scheme *sc, unsigned char c, s7_pointer port)) { s7_pointer x; new_cell(sc, x, T_OUTPUT_PORT); port_port(x) = alloc_port(sc); port_type(x) = FUNCTION_PORT; port_data(x) = NULL; port_is_closed(x) = false; port_needs_free(x) = false; port_output_function(x) = function; port_read_character(x) = output_read_char; port_read_line(x) = output_read_line; port_display(x) = function_display; port_write_character(x) = function_write_char; port_write_string(x) = function_write_string; add_output_port(sc, x); return(x); } static void push_input_port(s7_scheme *sc, s7_pointer new_port) { sc->temp6 = sc->input_port; sc->input_port = new_port; sc->input_port_stack = cons(sc, sc->temp6, sc->input_port_stack); sc->temp6 = sc->NIL; } static void pop_input_port(s7_scheme *sc) { if (is_pair(sc->input_port_stack)) { s7_pointer nxt; sc->input_port = car(sc->input_port_stack); nxt = cdr(sc->input_port_stack); /* is this safe? */ free_cell(sc, sc->input_port_stack); sc->input_port_stack = nxt; } else sc->input_port = sc->standard_input; } static int inchar(s7_pointer pt) { int c; if (is_file_port(pt)) c = fgetc(port_file(pt)); /* not unsigned char! -- could be EOF */ else { if (port_data_size(pt) <= port_position(pt)) return(EOF); c = (unsigned char)port_data(pt)[port_position(pt)++]; } if (c == '\n') port_line_number(pt)++; return(c); } static void backchar(char c, s7_pointer pt) { if (c == '\n') port_line_number(pt)--; if (is_file_port(pt)) ungetc(c, port_file(pt)); else { if (port_position(pt) > 0) port_position(pt)--; } } int s7_read_char(s7_scheme *sc, s7_pointer port) { /* needs to be int return value so EOF=-1, but not 255 */ return(port_read_character(port)(sc, port)); } int s7_peek_char(s7_scheme *sc, s7_pointer port) { int c; /* needs to be an int so EOF=-1, but not 255 */ c = port_read_character(port)(sc, port); if (c != EOF) backchar(c, port); return(c); } void s7_write_char(s7_scheme *sc, int c, s7_pointer pt) { if (pt != sc->F) port_write_character(pt)(sc, c, pt); } static s7_pointer input_port_if_not_loading(s7_scheme *sc) { s7_pointer port; port = sc->input_port; if (is_loader_port(port)) /* this flag is turned off by the reader macros, so we aren't in that context */ { int c; c = port_read_white_space(port)(sc, port); if (c > 0) /* we can get either EOF or NULL at the end */ { backchar(c, port); return(NULL); } return(sc->standard_input); } return(port); } static s7_pointer g_read_char(s7_scheme *sc, s7_pointer args) { #define H_read_char "(read-char (port (current-input-port))) returns the next character in the input port" #define Q_read_char s7_make_signature(sc, 2, s7_make_signature(sc, 2, sc->IS_CHAR, sc->IS_EOF_OBJECT), sc->IS_INPUT_PORT) s7_pointer port; if (is_not_null(args)) port = car(args); else { port = input_port_if_not_loading(sc); if (!port) return(sc->EOF_OBJECT); } if (!is_input_port(port)) method_or_bust_with_type(sc, port, sc->READ_CHAR, args, AN_INPUT_PORT, 0); return(chars[port_read_character(port)(sc, port)]); } static s7_pointer read_char_0, read_char_1; static s7_pointer g_read_char_0(s7_scheme *sc, s7_pointer args) { s7_pointer port; port = input_port_if_not_loading(sc); if (port) return(chars[port_read_character(port)(sc, port)]); return(sc->EOF_OBJECT); } static s7_pointer g_read_char_1(s7_scheme *sc, s7_pointer args) { s7_pointer port; port = car(args); if (!is_input_port(port)) method_or_bust_with_type(sc, port, sc->READ_CHAR, args, AN_INPUT_PORT, 0); return(chars[port_read_character(port)(sc, port)]); } static s7_pointer c_read_char(s7_scheme *sc) { int c; s7_pointer port; port = input_port_if_not_loading(sc); if (!port) return(sc->EOF_OBJECT); c = port_read_character(port)(sc, port); if (c == EOF) return(sc->EOF_OBJECT); return(chars[c]); } PF_0(read_char, c_read_char) static s7_pointer read_char_chooser(s7_scheme *sc, s7_pointer f, int args, s7_pointer expr) { if (args == 0) return(read_char_0); if (args == 1) return(read_char_1); return(f); } static s7_pointer g_write_char(s7_scheme *sc, s7_pointer args) { #define H_write_char "(write-char char (port (current-output-port))) writes char to the output port" #define Q_write_char s7_make_signature(sc, 3, sc->IS_CHAR, sc->IS_CHAR, sc->IS_OUTPUT_PORT) s7_pointer port, chr; chr = car(args); if (!s7_is_character(chr)) method_or_bust(sc, chr, sc->WRITE_CHAR, args, T_CHARACTER, 1); if (is_pair(cdr(args))) port = cadr(args); else port = sc->output_port; if (port == sc->F) return(chr); if (!is_output_port(port)) method_or_bust_with_type(sc, port, sc->WRITE_CHAR, args, AN_OUTPUT_PORT, 2); port_write_character(port)(sc, s7_character(chr), port); return(chr); } static s7_pointer c_write_char(s7_scheme *sc, s7_pointer chr) { if (!s7_is_character(chr)) method_or_bust(sc, chr, sc->WRITE_CHAR, set_plist_1(sc, chr), T_CHARACTER, 1); if (sc->output_port == sc->F) return(chr); port_write_character(sc->output_port)(sc, s7_character(chr), sc->output_port); return(chr); } static s7_pointer write_char_1; static s7_pointer g_write_char_1(s7_scheme *sc, s7_pointer args) {return(c_write_char(sc, car(args)));} PF_TO_PF(write_char, c_write_char) static s7_pointer write_char_chooser(s7_scheme *sc, s7_pointer f, int args, s7_pointer expr) { if (args == 1) return(write_char_1); return(f); } /* (with-output-to-string (lambda () (write-char #\space))) -> " " * (with-output-to-string (lambda () (write #\space))) -> "#\\space" * (with-output-to-string (lambda () (display #\space))) -> " " * is this correct? It's what Guile does. write-char is actually display-char. */ static s7_pointer g_peek_char(s7_scheme *sc, s7_pointer args) { #define H_peek_char "(peek-char (port (current-input-port))) returns the next character in the input port, but does not remove it from the input stream" #define Q_peek_char s7_make_signature(sc, 2, s7_make_signature(sc, 2, sc->IS_CHAR, sc->IS_EOF_OBJECT), sc->IS_INPUT_PORT) s7_pointer port; if (is_not_null(args)) port = car(args); else port = sc->input_port; if (!is_input_port(port)) method_or_bust_with_type(sc, port, sc->PEEK_CHAR, args, AN_INPUT_PORT, 0); if (port_is_closed(port)) return(simple_wrong_type_argument_with_type(sc, sc->PEEK_CHAR, port, AN_OPEN_PORT)); if (is_function_port(port)) return((*(port_input_function(port)))(sc, S7_PEEK_CHAR, port)); return(chars[s7_peek_char(sc, port)]); } static s7_pointer c_peek_char(s7_scheme *sc) {return(chars[s7_peek_char(sc, sc->input_port)]);} PF_0(peek_char, c_peek_char) static s7_pointer g_read_byte(s7_scheme *sc, s7_pointer args) { #define H_read_byte "(read-byte (port (current-input-port))): reads a byte from the input port" #define Q_read_byte s7_make_signature(sc, 2, s7_make_signature(sc, 2, sc->IS_INTEGER, sc->IS_EOF_OBJECT), sc->IS_INPUT_PORT) s7_pointer port; int c; if (is_not_null(args)) port = car(args); else { port = input_port_if_not_loading(sc); if (!port) return(sc->EOF_OBJECT); } if (!is_input_port(port)) method_or_bust_with_type(sc, port, sc->READ_BYTE, args, AN_INPUT_PORT, 0); c = port_read_character(port)(sc, port); if (c == EOF) return(sc->EOF_OBJECT); return(small_int(c)); } static s7_pointer c_read_byte(s7_scheme *sc) { int c; s7_pointer port; port = input_port_if_not_loading(sc); if (!port) return(sc->EOF_OBJECT); c = port_read_character(port)(sc, port); if (c == EOF) return(sc->EOF_OBJECT); return(small_int(c)); } PF_0(read_byte, c_read_byte) static s7_pointer g_write_byte(s7_scheme *sc, s7_pointer args) { #define H_write_byte "(write-byte byte (port (current-output-port))): writes byte to the output port" #define Q_write_byte s7_make_signature(sc, 3, sc->IS_INTEGER, sc->IS_INTEGER, sc->IS_OUTPUT_PORT) s7_pointer port, b; s7_int val; b = car(args); if (!s7_is_integer(b)) method_or_bust(sc, car(args), sc->WRITE_BYTE, args, T_INTEGER, 1); val = s7_integer(b); if ((val < 0) || (val > 255)) /* need to check this before port==#f, else (write-byte most-positive-fixnum #f) is not an error */ return(wrong_type_argument_with_type(sc, sc->WRITE_BYTE, 1, b, AN_UNSIGNED_BYTE)); if (is_pair(cdr(args))) port = cadr(args); else port = sc->output_port; if (!is_output_port(port)) { if (port == sc->F) return(car(args)); method_or_bust_with_type(sc, port, sc->WRITE_BYTE, args, AN_OUTPUT_PORT, 0); } s7_write_char(sc, (int)(s7_integer(b)), port); return(b); } static s7_int c_write_byte(s7_scheme *sc, s7_int x) { if ((x < 0) || (x > 255)) wrong_type_argument_with_type(sc, sc->WRITE_BYTE, 1, make_integer(sc, x), AN_UNSIGNED_BYTE); s7_write_char(sc, (int)x, sc->output_port); return(x); } IF_TO_IF(write_byte, c_write_byte) static s7_pointer g_read_line(s7_scheme *sc, s7_pointer args) { #define H_read_line "(read-line port (with-eol #f)) returns the next line from port, or #.\ If 'with-eol' is not #f, read-line includes the trailing end-of-line character." #define Q_read_line s7_make_signature(sc, 3, s7_make_signature(sc, 2, sc->IS_STRING, sc->IS_EOF_OBJECT), sc->IS_INPUT_PORT, sc->IS_BOOLEAN) s7_pointer port; bool with_eol = false; if (is_not_null(args)) { port = car(args); if (!is_input_port(port)) method_or_bust_with_type(sc, port, sc->READ_LINE, args, AN_INPUT_PORT, 1); if (is_not_null(cdr(args))) with_eol = (cadr(args) != sc->F); } else { port = input_port_if_not_loading(sc); if (!port) return(sc->EOF_OBJECT); } return(port_read_line(port)(sc, port, with_eol, true)); } static s7_pointer c_read_line(s7_scheme *sc) {return(g_read_line(sc, sc->NIL));} PF_0(read_line, c_read_line) static s7_pointer read_line_uncopied; static s7_pointer g_read_line_uncopied(s7_scheme *sc, s7_pointer args) { s7_pointer port; bool with_eol = false; port = car(args); if (!is_input_port(port)) return(g_read_line(sc, args)); if (is_not_null(cdr(args))) with_eol = (cadr(args) != sc->F); return(port_read_line(port)(sc, port, with_eol, false)); } static s7_pointer c_read_string(s7_scheme *sc, s7_int chars, s7_pointer port) { s7_pointer s; s7_int i; unsigned char *str; if (chars < 0) return(wrong_type_argument_with_type(sc, sc->READ_STRING, 1, make_integer(sc, chars), A_NON_NEGATIVE_INTEGER)); if (chars > sc->max_string_length) return(out_of_range(sc, sc->READ_STRING, small_int(1), make_integer(sc, chars), ITS_TOO_LARGE)); if (!port) return(sc->EOF_OBJECT); if (!is_input_port(port)) method_or_bust_with_type(sc, port, sc->READ_STRING, list_2(sc, make_integer(sc, chars), port), AN_INPUT_PORT, 2); if (chars == 0) return(make_empty_string(sc, 0, 0)); s = make_empty_string(sc, chars, 0); str = (unsigned char *)string_value(s); for (i = 0; i < chars; i++) { int c; c = port_read_character(port)(sc, port); if (c == EOF) { if (i == 0) return(sc->EOF_OBJECT); string_length(s) = i; return(s); } str[i] = (unsigned char)c; } return(s); } static s7_pointer g_read_string(s7_scheme *sc, s7_pointer args) { #define H_read_string "(read-string k port) reads k characters from port into a new string and returns it." #define Q_read_string s7_make_signature(sc, 3, s7_make_signature(sc, 2, sc->IS_STRING, sc->IS_EOF_OBJECT), sc->IS_INTEGER, sc->IS_INPUT_PORT) s7_pointer k, port; k = car(args); if (!s7_is_integer(k)) method_or_bust(sc, k, sc->READ_STRING, args, T_INTEGER, 1); if (!is_null(cdr(args))) port = cadr(args); else port = input_port_if_not_loading(sc); /* port checked (for NULL) in c_read_string */ return(c_read_string(sc, s7_integer(k), port)); } static s7_pointer c_read_string_1(s7_scheme *sc, s7_int chars) {return(c_read_string(sc, chars, input_port_if_not_loading(sc)));} IF_TO_PF(read_string, c_read_string_1) s7_pointer s7_read(s7_scheme *sc, s7_pointer port) { if (is_input_port(port)) { bool old_longjmp; s7_pointer old_envir; old_envir = sc->envir; sc->envir = sc->NIL; if (sc->longjmp_ok) { push_input_port(sc, port); push_stack(sc, OP_BARRIER, port, sc->NIL); push_stack(sc, OP_EVAL_DONE, sc->args, sc->code); eval(sc, OP_READ_INTERNAL); pop_input_port(sc); sc->envir = old_envir; return(sc->value); } stack_reset(sc); push_stack(sc, OP_EVAL_DONE, old_envir, sc->NIL); /* GC protect envir */ push_input_port(sc, port); old_longjmp = sc->longjmp_ok; if (!sc->longjmp_ok) { sc->longjmp_ok = true; if (setjmp(sc->goto_start) != 0) eval(sc, sc->op); else eval(sc, OP_READ_INTERNAL); } sc->longjmp_ok = old_longjmp; pop_input_port(sc); sc->envir = old_envir; return(sc->value); } return(simple_wrong_type_argument_with_type(sc, sc->READ, port, AN_INPUT_PORT)); } static s7_pointer g_read(s7_scheme *sc, s7_pointer args) { /* would it be useful to add an environment arg here? (just set sc->envir at the end?) * except for expansions, nothing is evaluated at read time, unless... * say we set up a dot reader: * (set! *#readers* (cons (cons #\. (lambda (str) (if (string=? str ".") (eval (read)) #f))) *#readers*)) * then * (call-with-input-string "(+ 1 #.(+ 1 hiho))" (lambda (p) (read p))) * evaluates hiho in the rootlet, but how to pass the env to the inner eval or read? * (eval, eval-string and load already have an env arg) */ #define H_read "(read (port (current-input-port))) returns the next object in the input port, or # at the end" #define Q_read s7_make_signature(sc, 2, sc->T, sc->IS_INPUT_PORT) s7_pointer port; if (is_not_null(args)) port = car(args); else { port = input_port_if_not_loading(sc); if (!port) return(sc->EOF_OBJECT); } if (!is_input_port(port)) method_or_bust_with_type(sc, port, sc->READ, args, AN_INPUT_PORT, 0); if (is_function_port(port)) return((*(port_input_function(port)))(sc, S7_READ, port)); if ((is_string_port(port)) && (port_data_size(port) <= port_position(port))) return(sc->EOF_OBJECT); push_input_port(sc, port); push_stack(sc, OP_READ_DONE, sc->NIL, sc->NIL); /* this stops the internal read process so we only get one form */ push_stack(sc, OP_READ_INTERNAL, sc->NIL, sc->NIL); return(port); } static s7_pointer c_read(s7_scheme *sc) {return(g_read(sc, sc->NIL));} PF_0(read, c_read) /* -------------------------------- load -------------------------------- */ static FILE *search_load_path(s7_scheme *sc, const char *name) { int i, len; s7_pointer lst; lst = s7_load_path(sc); len = s7_list_length(sc, lst); for (i = 0; i < len; i++) { const char *new_dir; new_dir = string_value(s7_list_ref(sc, lst, i)); if (new_dir) { FILE *fp; snprintf(sc->tmpbuf, TMPBUF_SIZE, "%s/%s", new_dir, name); fp = fopen(sc->tmpbuf, "r"); if (fp) return(fp); } } return(NULL); } static s7_pointer s7_load_1(s7_scheme *sc, const char *filename, s7_pointer e) { s7_pointer port; FILE *fp; char *new_filename = NULL; fp = fopen(filename, "r"); if (!fp) { fp = search_load_path(sc, filename); if (fp) new_filename = copy_string(sc->tmpbuf); /* (require libc.scm) for example needs the directory for cload in some cases */ } if (!fp) return(file_error(sc, "load", "can't open", filename)); if (is_pair(s7_hook_functions(sc, sc->load_hook))) s7_call(sc, sc->load_hook, list_1(sc, sc->temp4 = s7_make_string(sc, filename))); port = read_file(sc, fp, (new_filename) ? (const char *)new_filename : filename, -1, "load"); /* -1 means always read its contents into a local string */ port_file_number(port) = remember_file_name(sc, filename); if (new_filename) free(new_filename); set_loader_port(port); push_input_port(sc, port); /* it's possible to call this recursively (s7_load is Xen_load_file which can be invoked via s7_call) * but in that case, we actually want it to behave like g_load and continue the evaluation upon completion */ sc->envir = e; push_stack(sc, OP_LOAD_RETURN_IF_EOF, port, sc->code); if (!sc->longjmp_ok) { bool old_longjmp; old_longjmp = sc->longjmp_ok; if (!sc->longjmp_ok) { sc->longjmp_ok = true; if (setjmp(sc->goto_start) != 0) eval(sc, sc->op); else eval(sc, OP_READ_INTERNAL); } sc->longjmp_ok = old_longjmp; } else eval(sc, OP_READ_INTERNAL); pop_input_port(sc); if (is_input_port(port)) s7_close_input_port(sc, port); return(sc->value); } s7_pointer s7_load(s7_scheme *sc, const char *filename) { return(s7_load_1(sc, filename, sc->NIL)); } #if WITH_C_LOADER #include static char *full_filename(const char *filename) { int len; char *pwd, *rtn; pwd = getcwd(NULL, 0); /* docs say this means it will return a new string of the right size */ len = safe_strlen(pwd) + safe_strlen(filename) + 8; rtn = (char *)malloc(len * sizeof(char)); if (pwd) { snprintf(rtn, len, "%s/%s", pwd, filename); free(pwd); } else snprintf(rtn, len, "%s", filename); return(rtn); } #endif static s7_pointer g_load(s7_scheme *sc, s7_pointer args) { #define H_load "(load file (env (rootlet))) loads the scheme file 'file'. The 'env' argument \ defaults to the rootlet. To load into the current environment instead, pass (curlet)." #define Q_load s7_make_signature(sc, 3, sc->VALUES, sc->IS_STRING, sc->IS_LET) FILE *fp = NULL; s7_pointer name, port; const char *fname; name = car(args); if (!is_string(name)) method_or_bust(sc, name, sc->LOAD, args, T_STRING, 1); if (is_not_null(cdr(args))) { s7_pointer e; e = cadr(args); if (!is_let(e)) return(wrong_type_argument_with_type(sc, sc->LOAD, 2, e, A_LET)); if (e == sc->rootlet) sc->envir = sc->NIL; else sc->envir = e; } else sc->envir = sc->NIL; fname = string_value(name); if ((!fname) || (!(*fname))) /* fopen("", "r") returns a file pointer?? */ return(s7_error(sc, sc->OUT_OF_RANGE, set_elist_2(sc, make_string_wrapper(sc, "load's first argument, ~S, should be a filename"), name))); if (is_directory(fname)) return(s7_error(sc, sc->WRONG_TYPE_ARG, set_elist_2(sc, make_string_wrapper(sc, "load argument, ~S, is a directory"), name))); #if WITH_C_LOADER /* if fname ends in .so, try loading it as a c shared object * (load "/home/bil/cl/m_j0.so" (inlet (cons 'init_func 'init_m_j0))) */ { int fname_len; fname_len = safe_strlen(fname); if ((fname_len > 3) && (is_pair(cdr(args))) && (local_strcmp((const char *)(fname + (fname_len - 3)), ".so"))) { s7_pointer init; init = let_ref_1(sc, sc->envir, s7_make_symbol(sc, "init_func")); if (is_symbol(init)) { void *library; char *pwd_name = NULL; if (fname[0] != '/') pwd_name = full_filename(fname); /* this is necessary, at least in Linux -- we can't blithely dlopen whatever is passed to us */ library = dlopen((pwd_name) ? pwd_name : fname, RTLD_NOW); if (library) { const char *init_name = NULL; void *init_func; init_name = symbol_name(init); init_func = dlsym(library, init_name); if (init_func) { typedef void *(*dl_func)(s7_scheme *sc); ((dl_func)init_func)(sc); if (pwd_name) free(pwd_name); return(sc->T); } else { s7_warn(sc, 512, "loaded %s, but can't find %s (%s)?\n", fname, init_name, dlerror()); dlclose(library); } } else s7_warn(sc, 512, "load %s failed: %s\n", (pwd_name) ? pwd_name : fname, dlerror()); if (pwd_name) free(pwd_name); } else s7_warn(sc, 512, "can't load %s: no init function\n", fname); return(sc->F); } } #endif fp = fopen(fname, "r"); #if WITH_GCC if (!fp) { /* catch one special case, "~/..." since it causes 99.9% of the "can't load ..." errors */ if ((fname[0] == '~') && (fname[1] == '/')) { char *home; home = getenv("HOME"); if (home) { char *filename; int len; len = safe_strlen(fname) + safe_strlen(home) + 1; tmpbuf_malloc(filename, len); snprintf(filename, len, "%s%s", home, (char *)(fname + 1)); fp = fopen(filename, "r"); tmpbuf_free(filename, len); } } } #endif if (!fp) { fp = search_load_path(sc, fname); if (!fp) return(file_error(sc, "load", "can't open", fname)); } port = read_file(sc, fp, fname, -1, "load"); port_file_number(port) = remember_file_name(sc, fname); set_loader_port(port); push_input_port(sc, port); push_stack(sc, OP_LOAD_CLOSE_AND_POP_IF_EOF, sc->NIL, sc->NIL); /* was pushing args and code, but I don't think they're used later */ push_stack(sc, OP_READ_INTERNAL, sc->NIL, sc->NIL); /* now we've opened and moved to the file to be loaded, and set up the stack to return * to where we were. Call *load-hook* if it is a procedure. */ if (is_not_null(s7_hook_functions(sc, sc->load_hook))) s7_apply_function(sc, sc->load_hook, list_1(sc, sc->temp4 = s7_make_string(sc, fname))); return(sc->UNSPECIFIED); } s7_pointer s7_load_path(s7_scheme *sc) { return(s7_symbol_value(sc, sc->LOAD_PATH)); } s7_pointer s7_add_to_load_path(s7_scheme *sc, const char *dir) { s7_symbol_set_value(sc, sc->LOAD_PATH, cons(sc, s7_make_string(sc, dir), s7_symbol_value(sc, sc->LOAD_PATH))); return(s7_symbol_value(sc, sc->LOAD_PATH)); } static s7_pointer g_load_path_set(s7_scheme *sc, s7_pointer args) { /* new value must be either () or a proper list of strings */ if (is_null(cadr(args))) return(cadr(args)); if (is_pair(cadr(args))) { s7_pointer x; for (x = cadr(args); is_pair(x); x = cdr(x)) if (!is_string(car(x))) return(sc->ERROR); if (is_null(x)) return(cadr(args)); } return(sc->ERROR); } /* ---------------- autoload ---------------- */ void s7_autoload_set_names(s7_scheme *sc, const char **names, int size) { /* the idea here is that by sticking to string constants we can handle 90% of the work at compile-time, * with less start-up memory. Then eventually we'll add C libraries a la xg (gtk) as environments * and every name in that library will come as an import once dlopen has picked up the library. * So, hopefully, we can pre-declare as many names as we want from as many libraries as we want, * without a bloated mess of a run-time image. And new libraries are easy to accommodate -- * add the names to be auto-exported to this list with the name of the scheme file that cloads * the library and exports the given name. So, we'll need a separate such file for each library? * * the environment variable could use the library base name in *: *libm* or *libgtk* * (*libm* 'j0) * why not just predeclare these libraries? The caller could import what he wants via require. * So the autoloader need only know which libraries, but this doesn't fit the current use of gtk in xg * In fact, we only need to see *libm* -> libm.so etc, but we still need the arg/return types of each function, etc * And libgtk is enormous -- seems too bad to tie-in everything via the FFI when we need less than 1% of it. * Perhaps each module as an environment within the main one: ((*libgtk* *gtkwidget*) 'gtk_widget_new)? * But that requires inside knowlege of the library, and changes without notice. * * Also we need to decide how to handle name collisions (by order of autoload lib setup) * And (lastly?) how to handle different library versions? * * * so autoload known libs here in s7 so we're indepentdent of snd * (currently these are included in make-index.scm[line 575] -> snd-xref.c) * for each module, include an env in the lib env (*libgtk* 'gtkwidget.h) or whatever that has the names in that header * in autoload below, don't sort! -- just build a list of autoload tables and check each in order at autoload time (we want startup to be fast) * for versions, include wrapper macro at end of each c-define choice * in the xg case, there's no savings in delaying the defines * */ if (sc->autoload_names == NULL) { sc->autoload_names = (const char ***)calloc(INITIAL_AUTOLOAD_NAMES_SIZE, sizeof(const char **)); sc->autoload_names_sizes = (int *)calloc(INITIAL_AUTOLOAD_NAMES_SIZE, sizeof(int)); sc->autoloaded_already = (bool **)calloc(INITIAL_AUTOLOAD_NAMES_SIZE, sizeof(bool *)); sc->autoload_names_top = INITIAL_AUTOLOAD_NAMES_SIZE; sc->autoload_names_loc = 0; } else { if (sc->autoload_names_loc >= sc->autoload_names_top) { int i; sc->autoload_names_top *= 2; sc->autoload_names = (const char ***)realloc(sc->autoload_names, sc->autoload_names_top * sizeof(const char **)); sc->autoload_names_sizes = (int *)realloc(sc->autoload_names_sizes, sc->autoload_names_top * sizeof(int)); sc->autoloaded_already = (bool **)realloc(sc->autoloaded_already, sc->autoload_names_top * sizeof(bool *)); for (i = sc->autoload_names_loc; i < sc->autoload_names_top; i++) { sc->autoload_names[i] = NULL; sc->autoload_names_sizes[i] = 0; sc->autoloaded_already[i] = NULL; } } } sc->autoload_names[sc->autoload_names_loc] = names; sc->autoload_names_sizes[sc->autoload_names_loc] = size; sc->autoloaded_already[sc->autoload_names_loc] = (bool *)calloc(size, sizeof(bool)); sc->autoload_names_loc++; } static const char *find_autoload_name(s7_scheme *sc, s7_pointer symbol, bool *already_loaded, bool loading) { int l = 0, pos = -1, lib, libs; const char *name, *this_name; name = symbol_name(symbol); libs = sc->autoload_names_loc; for (lib = 0; lib < libs; lib++) { const char **names; int u; u = sc->autoload_names_sizes[lib] - 1; names = sc->autoload_names[lib]; while (true) { int comp; if (u < l) break; pos = (l + u) / 2; this_name = names[pos * 2]; comp = strcmp(this_name, name); if (comp == 0) { *already_loaded = sc->autoloaded_already[lib][pos]; if (loading) sc->autoloaded_already[lib][pos] = true; return(names[pos * 2 + 1]); /* file name given func name */ } if (comp < 0) l = pos + 1; else u = pos - 1; } } return(NULL); } s7_pointer s7_autoload(s7_scheme *sc, s7_pointer symbol, s7_pointer file_or_function) { /* add '(symbol . file) to s7's autoload table */ if (is_null(sc->autoload_table)) sc->autoload_table = s7_make_hash_table(sc, sc->default_hash_table_length); s7_hash_table_set(sc, sc->autoload_table, symbol, file_or_function); return(file_or_function); } static s7_pointer g_autoload(s7_scheme *sc, s7_pointer args) { #define H_autoload "(autoload symbol file-or-function) adds the symbol to its table of autoloadable symbols. \ If that symbol is encountered as an unbound variable, s7 either loads the file (following *load-path*), or calls \ the function. The function takes one argument, the calling environment. Presumably the symbol is defined \ in the file, or by the function." #define Q_autoload s7_make_signature(sc, 3, sc->T, sc->IS_SYMBOL, sc->T) s7_pointer sym, value; sym = car(args); if (is_string(sym)) { if (string_length(sym) == 0) /* (autoload "" ...) */ return(s7_wrong_type_arg_error(sc, "autoload", 1, sym, "a symbol-name or a symbol")); sym = make_symbol_with_length(sc, string_value(sym), string_length(sym)); } if (!is_symbol(sym)) { check_method(sc, sym, sc->AUTOLOAD, args); return(s7_wrong_type_arg_error(sc, "autoload", 1, sym, "a string (symbol-name) or a symbol")); } if (is_keyword(sym)) return(s7_wrong_type_arg_error(sc, "autoload", 1, sym, "a normal symbol (a keyword is never unbound)")); value = cadr(args); if (is_string(value)) return(s7_autoload(sc, sym, value)); if (((is_closure(value)) || (is_closure_star(value))) && (s7_is_aritable(sc, value, 1))) return(s7_autoload(sc, sym, value)); check_method(sc, value, sc->AUTOLOAD, args); return(s7_wrong_type_arg_error(sc, "autoload", 2, value, "a string (file-name) or a thunk")); } static s7_pointer g_autoloader(s7_scheme *sc, s7_pointer args) { #define H_autoloader "(*autoload* sym) returns the autoload info for the symbol sym, or #f." #define Q_autoloader s7_make_signature(sc, 2, sc->T, sc->IS_SYMBOL) s7_pointer sym; sym = car(args); if (!is_symbol(sym)) { check_method(sc, sym, sc->AUTOLOADER, args); return(s7_wrong_type_arg_error(sc, "*autoload*", 1, sym, "a symbol")); } if (sc->autoload_names) { const char *file; bool loaded = false; file = find_autoload_name(sc, sym, &loaded, false); if (file) return(s7_make_string(sc, file)); } if (is_hash_table(sc->autoload_table)) return(s7_hash_table_ref(sc, sc->autoload_table, sym)); return(sc->F); } static s7_pointer g_require(s7_scheme *sc, s7_pointer args) { #define H_require "(require . symbols) loads each file associated with each symbol if it has not been loaded already.\ The symbols refer to the argument to \"provide\"." #define Q_require s7_make_circular_signature(sc, 1, 2, sc->T, sc->IS_SYMBOL) s7_pointer p; sc->temp5 = cons(sc, args, sc->temp5); for (p = args; is_pair(p); p = cdr(p)) { if (is_symbol(car(p))) { if (!is_slot(find_symbol(sc, car(p)))) { s7_pointer f; f = g_autoloader(sc, p); if (is_string(f)) s7_load_1(sc, string_value(f), sc->envir); else { sc->temp5 = sc->NIL; return(s7_error(sc, make_symbol(sc, "autoload-error"), set_elist_2(sc, make_string_wrapper(sc, "require: no autoload info for ~S"), car(p)))); } } } else { sc->temp5 = sc->NIL; if ((is_pair(car(p))) && (caar(p) == sc->QUOTE)) return(s7_error(sc, sc->WRONG_TYPE_ARG, set_elist_2(sc, make_string_wrapper(sc, "require: don't quote ~S"), car(p)))); return(s7_error(sc, sc->WRONG_TYPE_ARG, set_elist_2(sc, make_string_wrapper(sc, "require: ~S is not a symbol"), car(p)))); } } sc->temp5 = cdr(sc->temp5); return(sc->T); } /* -------------------------------- eval-string -------------------------------- */ static s7_pointer eval_string_1(s7_scheme *sc, const char *str) { s7_pointer port; port = s7_open_input_string(sc, str); push_input_port(sc, port); push_stack(sc, OP_BARRIER, port, sc->NIL); /* we're being called directly from C here, not as part of a scheme program. * Use this op to protect the port, I guess. */ push_stack(sc, OP_EVAL_STRING, sc->args, sc->code); /* eval-string is not tail-recursive because it pushes markers in eval to catch * multiple statements in one eval-string call. */ eval(sc, OP_READ_INTERNAL); pop_input_port(sc); s7_close_input_port(sc, port); if (is_multiple_value(sc->value)) /* (+ 1 (eval-string "(values 2 3)")) */ sc->value = splice_in_values(sc, multiple_value(sc->value)); return(sc->value); } s7_pointer s7_eval_c_string_with_environment(s7_scheme *sc, const char *str, s7_pointer e) { bool old_longjmp; s7_pointer port, old_envir; /* this can be called recursively via s7_call */ sc->v = sc->envir; /* old envir needs GC protection even given the push_stack below */ old_envir = sc->envir; sc->envir = e; if (sc->longjmp_ok) { s7_pointer result; result = eval_string_1(sc, str); sc->envir = old_envir; return(result); } stack_reset(sc); push_stack(sc, OP_EVAL_STRING, old_envir, sc->NIL); /* GC protect envir */ port = s7_open_input_string(sc, str); push_input_port(sc, port); old_longjmp = sc->longjmp_ok; if (!sc->longjmp_ok) { sc->longjmp_ok = true; if (setjmp(sc->goto_start) != 0) eval(sc, sc->op); else eval(sc, OP_READ_INTERNAL); } sc->longjmp_ok = old_longjmp; pop_input_port(sc); s7_close_input_port(sc, port); sc->envir = old_envir; return(sc->value); } s7_pointer s7_eval_c_string(s7_scheme *sc, const char *str) { return(s7_eval_c_string_with_environment(sc, str, sc->NIL)); } static s7_pointer g_eval_string(s7_scheme *sc, s7_pointer args) { #define H_eval_string "(eval-string str (env (curlet))) returns the result of evaluating the string str as Scheme code" #define Q_eval_string s7_make_signature(sc, 3, sc->VALUES, sc->IS_STRING, sc->IS_LET) s7_pointer port, str; str = car(args); if (!is_string(str)) method_or_bust(sc, str, sc->EVAL_STRING, args, T_STRING, 1); if (is_not_null(cdr(args))) { s7_pointer e; e = cadr(args); if (!is_let(e)) return(wrong_type_argument_with_type(sc, sc->EVAL_STRING, 2, e, A_LET)); if (e == sc->rootlet) sc->envir = sc->NIL; else sc->envir = e; } port = open_and_protect_input_string(sc, str); push_input_port(sc, port); sc->temp3 = sc->args; push_stack(sc, OP_EVAL_STRING_1, args, sc->code); push_stack(sc, OP_READ_INTERNAL, sc->NIL, sc->NIL); return(sc->F); } static s7_pointer eval_string_chooser(s7_scheme *sc, s7_pointer f, int args, s7_pointer expr) { check_for_substring_temp(sc, expr); return(f); } static s7_pointer call_with_input(s7_scheme *sc, s7_pointer port, s7_pointer args) { s7_pointer p; p = cadr(args); port_original_input_string(port) = car(args); push_stack(sc, OP_UNWIND_INPUT, sc->input_port, port); push_stack(sc, OP_APPLY, list_1(sc, port), p); return(sc->F); } /* -------------------------------- call-with-input-string -------------------------------- */ static s7_pointer g_call_with_input_string(s7_scheme *sc, s7_pointer args) { s7_pointer str, proc; #define H_call_with_input_string "(call-with-input-string str proc) opens a string port for str and applies proc to it" #define Q_call_with_input_string pl_sf /* (call-with-input-string "44" (lambda (p) (+ 1 (read p)))) -> 45 */ str = car(args); if (!is_string(str)) method_or_bust(sc, str, sc->CALL_WITH_INPUT_STRING, args, T_STRING, 1); proc = cadr(args); if (is_let(proc)) check_method(sc, proc, sc->CALL_WITH_INPUT_STRING, args); if (!s7_is_aritable(sc, proc, 1)) return(wrong_type_argument_with_type(sc, sc->CALL_WITH_INPUT_STRING, 2, proc, make_string_wrapper(sc, "a procedure of one argument (the port)"))); if ((is_continuation(proc)) || (is_goto(proc))) return(wrong_type_argument_with_type(sc, sc->CALL_WITH_INPUT_STRING, 2, proc, A_NORMAL_PROCEDURE)); return(call_with_input(sc, open_and_protect_input_string(sc, str), args)); } static s7_pointer c_call_with_input_string(s7_scheme *sc, s7_pointer x, s7_pointer y) {return(g_call_with_input_string(sc, set_plist_2(sc, x, y)));} PF2_TO_PF(call_with_input_string, c_call_with_input_string) /* -------------------------------- call-with-input-file -------------------------------- */ static s7_pointer g_call_with_input_file(s7_scheme *sc, s7_pointer args) { #define H_call_with_input_file "(call-with-input-file filename proc) opens filename and calls proc with the input port as its argument" #define Q_call_with_input_file pl_sf s7_pointer str, proc; str = car(args); if (!is_string(str)) method_or_bust(sc, str, sc->CALL_WITH_INPUT_FILE, args, T_STRING, 1); proc = cadr(args); if (!s7_is_aritable(sc, proc, 1)) return(wrong_type_argument_with_type(sc, sc->CALL_WITH_INPUT_FILE, 2, proc, make_string_wrapper(sc, "a procedure of one argument (the port)"))); if ((is_continuation(proc)) || (is_goto(proc))) return(wrong_type_argument_with_type(sc, sc->CALL_WITH_INPUT_FILE, 2, proc, A_NORMAL_PROCEDURE)); return(call_with_input(sc, open_input_file_1(sc, string_value(str), "r", "call-with-input-file"), args)); } static s7_pointer c_call_with_input_file(s7_scheme *sc, s7_pointer x, s7_pointer y) {return(g_call_with_input_file(sc, set_plist_2(sc, x, y)));} PF2_TO_PF(call_with_input_file, c_call_with_input_file) static s7_pointer with_input(s7_scheme *sc, s7_pointer port, s7_pointer args) { s7_pointer old_input_port, p; old_input_port = sc->input_port; sc->input_port = port; port_original_input_string(port) = car(args); push_stack(sc, OP_UNWIND_INPUT, old_input_port, port); p = cadr(args); push_stack(sc, OP_APPLY, sc->NIL, p); return(sc->F); } /* -------------------------------- with-input-from-string -------------------------------- */ static s7_pointer g_with_input_from_string(s7_scheme *sc, s7_pointer args) { #define H_with_input_from_string "(with-input-from-string str thunk) opens str as the temporary current-input-port and calls thunk" #define Q_with_input_from_string pl_sf s7_pointer str; str = car(args); if (!is_string(str)) method_or_bust(sc, str, sc->WITH_INPUT_FROM_STRING, args, T_STRING, 1); if (!is_thunk(sc, cadr(args))) method_or_bust_with_type(sc, cadr(args), sc->WITH_INPUT_FROM_STRING, args, A_THUNK, 2); /* since the arguments are evaluated before we get here, we can get some confusing situations: * (with-input-from-string "#x2.1" (read)) * (read) -> whatever it can get from the current input port! * ";with-input-from-string argument 2, #, is untyped but should be a thunk" */ return(with_input(sc, open_and_protect_input_string(sc, str), args)); } static s7_pointer c_with_input_from_string(s7_scheme *sc, s7_pointer x) {return(g_with_input_from_string(sc, set_plist_1(sc, x)));} PF_TO_PF(with_input_from_string, c_with_input_from_string) /* -------------------------------- with-input-from-file -------------------------------- */ static s7_pointer g_with_input_from_file(s7_scheme *sc, s7_pointer args) { #define H_with_input_from_file "(with-input-from-file filename thunk) opens filename as the temporary current-input-port and calls thunk" #define Q_with_input_from_file pl_sf if (!is_string(car(args))) method_or_bust(sc, car(args), sc->WITH_INPUT_FROM_FILE, args, T_STRING, 1); if (!is_thunk(sc, cadr(args))) method_or_bust_with_type(sc, cadr(args), sc->WITH_INPUT_FROM_FILE, args, A_THUNK, 2); return(with_input(sc, open_input_file_1(sc, string_value(car(args)), "r", "with-input-from-file"), args)); } static s7_pointer c_with_input_from_file(s7_scheme *sc, s7_pointer x) {return(g_with_input_from_file(sc, set_plist_1(sc, x)));} PF_TO_PF(with_input_from_file, c_with_input_from_file) /* -------------------------------- iterators -------------------------------- */ static s7_pointer g_is_iterator(s7_scheme *sc, s7_pointer args) { #define H_is_iterator "(iterator? obj) returns #t if obj is an iterator." #define Q_is_iterator pl_bt s7_pointer x; x = car(args); if (is_iterator(x)) return(sc->T); check_closure_for(sc, x, sc->IS_ITERATOR); check_boolean_method(sc, is_iterator, sc->IS_ITERATOR, args); return(sc->F); } static s7_pointer iterator_copy(s7_scheme *sc, s7_pointer p) { /* fields are obj cur [loc|lcur] [len|slow|hcur] next */ s7_pointer iter; new_cell(sc, iter, T_ITERATOR | T_SAFE_PROCEDURE); iterator_sequence(iter) = iterator_sequence(p); /* obj */ iterator_position(iter) = iterator_position(p); /* loc|lcur (loc is s7_int) */ iterator_length(iter) = iterator_length(p); /* len|slow|hcur (len is s7_int) */ iterator_current(iter) = iterator_current(p); /* cur */ iterator_next(iter) = iterator_next(p); /* next */ return(iter); } static s7_pointer iterator_finished(s7_scheme *sc, s7_pointer iterator) { return(sc->ITERATOR_END); } static s7_pointer let_iterate(s7_scheme *sc, s7_pointer iterator) { s7_pointer slot; slot = iterator_let_current(iterator); if (is_slot(slot)) { iterator_let_current(iterator) = next_slot(slot); if (iterator_let_cons(iterator)) { s7_pointer p; p = iterator_let_cons(iterator); car(p) = slot_symbol(slot); cdr(p) = slot_value(slot); return(p); } return(cons(sc, slot_symbol(slot), slot_value(slot))); } iterator_next(iterator) = iterator_finished; return(sc->ITERATOR_END); } static s7_pointer rootlet_iterate(s7_scheme *sc, s7_pointer iterator) { s7_pointer slot; slot = iterator_current(iterator); if (is_slot(slot)) { if (iterator_position(iterator) < sc->rootlet_entries) { iterator_position(iterator)++; iterator_current(iterator) = vector_element(sc->rootlet, iterator_position(iterator)); } else iterator_current(iterator) = sc->NIL; return(cons(sc, slot_symbol(slot), slot_value(slot))); } iterator_next(iterator) = iterator_finished; return(sc->ITERATOR_END); } static s7_pointer hash_table_iterate(s7_scheme *sc, s7_pointer iterator) { s7_pointer table; int loc, len; hash_entry_t **elements; hash_entry_t *lst; lst = iterator_hash_current(iterator); if (lst) { iterator_hash_current(iterator) = lst->next; if (iterator_current(iterator)) { s7_pointer p; p = iterator_current(iterator); car(p) = lst->key; cdr(p) = lst->value; return(p); } return(cons(sc, lst->key, lst->value)); } table = iterator_sequence(iterator); /* using iterator_length and hash_table_entries here was slightly slower */ len = hash_table_mask(table) + 1; elements = hash_table_elements(table); for (loc = iterator_position(iterator) + 1; loc < len; loc++) { hash_entry_t *x; x = elements[loc]; if (x) { iterator_position(iterator) = loc; iterator_hash_current(iterator) = x->next; if (iterator_current(iterator)) { s7_pointer p; p = iterator_current(iterator); car(p) = x->key; cdr(p) = x->value; return(p); } return(cons(sc, x->key, x->value)); } } iterator_next(iterator) = iterator_finished; return(sc->ITERATOR_END); } static s7_pointer string_iterate(s7_scheme *sc, s7_pointer obj) { if (iterator_position(obj) < iterator_length(obj)) return(s7_make_character(sc, (unsigned char)(string_value(iterator_sequence(obj))[iterator_position(obj)++]))); iterator_next(obj) = iterator_finished; return(sc->ITERATOR_END); } static s7_pointer byte_vector_iterate(s7_scheme *sc, s7_pointer obj) { if (iterator_position(obj) < iterator_length(obj)) return(small_int((unsigned char)(string_value(iterator_sequence(obj))[iterator_position(obj)++]))); iterator_next(obj) = iterator_finished; return(sc->ITERATOR_END); } static s7_pointer float_vector_iterate(s7_scheme *sc, s7_pointer obj) { if (iterator_position(obj) < iterator_length(obj)) return(make_real(sc, float_vector_element(iterator_sequence(obj), iterator_position(obj)++))); iterator_next(obj) = iterator_finished; return(sc->ITERATOR_END); } static s7_pointer int_vector_iterate(s7_scheme *sc, s7_pointer obj) { if (iterator_position(obj) < iterator_length(obj)) return(make_integer(sc, int_vector_element(iterator_sequence(obj), iterator_position(obj)++))); iterator_next(obj) = iterator_finished; return(sc->ITERATOR_END); } static s7_pointer vector_iterate(s7_scheme *sc, s7_pointer obj) { if (iterator_position(obj) < iterator_length(obj)) return(vector_element(iterator_sequence(obj), iterator_position(obj)++)); iterator_next(obj) = iterator_finished; return(sc->ITERATOR_END); } static s7_pointer closure_iterate(s7_scheme *sc, s7_pointer obj) { s7_pointer result; result = s7_apply_function(sc, iterator_sequence(obj), sc->NIL); if (result == sc->ITERATOR_END) iterator_next(obj) = iterator_finished; return(result); } static s7_pointer c_object_direct_iterate(s7_scheme *sc, s7_pointer obj) { if (iterator_position(obj) < iterator_length(obj)) { s7_pointer result, p; p = iterator_sequence(obj); result = c_object_cref(p)(sc, p, iterator_position(obj)); iterator_position(obj)++; if (result == sc->ITERATOR_END) iterator_next(obj) = iterator_finished; return(result); } iterator_next(obj) = iterator_finished; return(sc->ITERATOR_END); } static s7_pointer c_object_iterate(s7_scheme *sc, s7_pointer obj) { if (iterator_position(obj) < iterator_length(obj)) { s7_pointer result, p, cur; p = iterator_sequence(obj); cur = iterator_current(obj); car(sc->Z2_1) = sc->x; car(sc->Z2_2) = sc->z; /* is this necessary? */ car(cur) = make_integer(sc, iterator_position(obj)); result = (*(c_object_ref(p)))(sc, p, cur); sc->x = car(sc->Z2_1); sc->z = car(sc->Z2_2); iterator_position(obj)++; if (result == sc->ITERATOR_END) iterator_next(obj) = iterator_finished; return(result); } iterator_next(obj) = iterator_finished; return(sc->ITERATOR_END); } static s7_pointer pair_iterate_1(s7_scheme *sc, s7_pointer obj); static s7_pointer pair_iterate(s7_scheme *sc, s7_pointer obj) { if (is_pair(iterator_current(obj))) { s7_pointer result; result = car(iterator_current(obj)); iterator_current(obj) = cdr(iterator_current(obj)); if (iterator_current(obj) == iterator_slow(obj)) { iterator_next(obj) = iterator_finished; return(result); } iterator_next(obj) = pair_iterate_1; return(result); } iterator_next(obj) = iterator_finished; return(sc->ITERATOR_END); } static s7_pointer pair_iterate_1(s7_scheme *sc, s7_pointer obj) { if (is_pair(iterator_current(obj))) { s7_pointer result; result = car(iterator_current(obj)); iterator_current(obj) = cdr(iterator_current(obj)); if (iterator_current(obj) == iterator_slow(obj)) { iterator_next(obj) = iterator_finished; return(result); } iterator_slow(obj) = cdr(iterator_slow(obj)); iterator_next(obj) = pair_iterate; return(result); } iterator_next(obj) = iterator_finished; return(sc->ITERATOR_END); } static s7_pointer iterator_method(s7_scheme *sc, s7_pointer e) { s7_pointer func; if ((has_methods(e)) && ((func = find_method(sc, find_let(sc, e), sc->MAKE_ITERATOR)) != sc->UNDEFINED)) { s7_pointer it; it = s7_apply_function(sc, func, list_1(sc, e)); if (!is_iterator(it)) return(s7_error(sc, sc->ERROR, set_elist_2(sc, make_string_wrapper(sc, "make-iterator method must return an interator: ~S"), it))); return(it); } return(NULL); } s7_pointer s7_make_iterator(s7_scheme *sc, s7_pointer e) { s7_pointer iter; new_cell(sc, iter, T_ITERATOR | T_SAFE_PROCEDURE); iterator_sequence(iter) = e; iterator_position(iter) = 0; switch (type(e)) { case T_LET: if (e == sc->rootlet) { iterator_current(iter) = vector_element(e, 0); /* unfortunately tricky -- let_iterate uses different fields */ iterator_next(iter) = rootlet_iterate; } else { s7_pointer f; sc->temp6 = iter; f = iterator_method(sc, e); sc->temp6 = sc->NIL; if (f) {free_cell(sc, iter); return(f);} iterator_let_current(iter) = let_slots(e); iterator_next(iter) = let_iterate; iterator_let_cons(iter) = NULL; } break; case T_HASH_TABLE: iterator_hash_current(iter) = NULL; iterator_current(iter) = NULL; iterator_position(iter) = -1; iterator_next(iter) = hash_table_iterate; break; case T_STRING: iterator_length(iter) = string_length(e); if (is_byte_vector(e)) iterator_next(iter) = byte_vector_iterate; else iterator_next(iter) = string_iterate; break; case T_VECTOR: iterator_length(iter) = vector_length(e); iterator_next(iter) = vector_iterate; break; case T_INT_VECTOR: iterator_length(iter) = vector_length(e); iterator_next(iter) = int_vector_iterate; break; case T_FLOAT_VECTOR: iterator_length(iter) = vector_length(e); iterator_next(iter) = float_vector_iterate; break; case T_PAIR: iterator_current(iter) = e; iterator_next(iter) = pair_iterate; iterator_slow(iter) = e; break; case T_MACRO: case T_MACRO_STAR: case T_BACRO: case T_BACRO_STAR: case T_CLOSURE: case T_CLOSURE_STAR: { s7_pointer p; p = cons(sc, e, sc->NIL); if (g_is_iterator(sc, p) != sc->F) { car(p) = small_int(0); iterator_current(iter) = p; set_mark_seq(iter); iterator_next(iter) = closure_iterate; if (has_methods(e)) iterator_length(iter) = closure_length(sc, e); else iterator_length(iter) = s7_int_max; } else { free_cell(sc, iter); return(simple_wrong_type_argument_with_type(sc, sc->MAKE_ITERATOR, e, make_string_wrapper(sc, "a closure/macro with an 'iterator local that is not #f"))); } } break; case T_C_OBJECT: iterator_length(iter) = object_length_to_int(sc, e); if (c_object_direct_ref(e)) { iterator_next(iter) = c_object_direct_iterate; c_object_cref(e) = c_object_direct_ref(e); } else { s7_pointer f; sc->temp6 = iter; f = iterator_method(sc, e); sc->temp6 = sc->NIL; if (f) {free_cell(sc, iter); return(f);} iterator_current(iter) = cons(sc, small_int(0), sc->NIL); set_mark_seq(iter); iterator_next(iter) = c_object_iterate; } break; default: return(simple_wrong_type_argument_with_type(sc, sc->MAKE_ITERATOR, e, A_SEQUENCE)); } return(iter); } static s7_pointer g_make_iterator(s7_scheme *sc, s7_pointer args) { #define H_make_iterator "(make-iterator sequence) returns an iterator object that \ returns the next value in the sequence each time it is called. When it reaches the end, it returns " ITERATOR_END_NAME "." #define Q_make_iterator s7_make_signature(sc, 3, sc->IS_ITERATOR, sc->IS_SEQUENCE, sc->IS_PAIR) s7_pointer seq; seq = car(args); if (is_pair(cdr(args))) { if (is_pair(cadr(args))) { if (is_hash_table(seq)) { s7_pointer iter; iter = s7_make_iterator(sc, seq); iterator_current(iter) = cadr(args); set_mark_seq(iter); return(iter); } if ((is_let(seq)) && (seq != sc->rootlet)) { s7_pointer iter; iter = s7_make_iterator(sc, seq); iterator_let_cons(iter) = cadr(args); set_mark_seq(iter); return(iter); } } else return(simple_wrong_type_argument(sc, sc->MAKE_ITERATOR, cadr(args), T_PAIR)); } return(s7_make_iterator(sc, seq)); } PF_TO_PF(make_iterator, s7_make_iterator) static s7_pointer c_iterate(s7_scheme *sc, s7_pointer iter) { if (!is_iterator(iter)) method_or_bust(sc, iter, sc->ITERATE, list_1(sc, iter), T_ITERATOR, 0); return((iterator_next(iter))(sc, iter)); } static s7_pointer g_iterate(s7_scheme *sc, s7_pointer args) { #define H_iterate "(iterate obj) returns the next element from the iterator obj, or " ITERATOR_END_NAME "." #define Q_iterate s7_make_signature(sc, 2, sc->T, sc->IS_ITERATOR) s7_pointer iter; iter = car(args); if (!is_iterator(iter)) method_or_bust(sc, iter, sc->ITERATE, args, T_ITERATOR, 0); return((iterator_next(iter))(sc, iter)); } static s7_pointer iterate_pf_p(s7_scheme *sc, s7_pointer **p) { s7_pf_t f; s7_pointer x; f = (s7_pf_t)(**p); (*p)++; x = f(sc, p); return(c_iterate(sc, x)); } static s7_pointer iterate_pf_s(s7_scheme *sc, s7_pointer **p) { pf_pf_t f; s7_pointer x; x = (s7_pointer)(**p); (*p)++; f = (pf_pf_t)(**p); (*p)++; return(f(sc, x)); } static s7_pf_t iterate_gf(s7_scheme *sc, s7_pointer expr) { if ((is_pair(cdr(expr))) && (is_null(cddr(expr)))) { s7_pointer a1, obj; a1 = cadr(expr); if ((is_symbol(a1)) && (!s7_xf_is_stepper(sc, a1)) && (is_iterator(obj = s7_symbol_value(sc, a1)))) { s7_xf_store(sc, obj); s7_xf_store(sc, (s7_pointer)iterator_next(obj)); return(iterate_pf_s); } if (s7_arg_to_pf(sc, a1)) return(iterate_pf_p); } return(NULL); } static s7_pf_t iterate_pf(s7_scheme *sc, s7_pointer expr) { if ((is_pair(cdr(expr))) && (is_null(cddr(expr)))) { s7_pointer a1, obj; a1 = cadr(expr); if ((is_symbol(a1)) && (!s7_xf_is_stepper(sc, a1)) && (is_iterator(obj = s7_symbol_value(sc, a1)))) { s7_pointer seq; seq = iterator_sequence(obj); if ((type(seq) == T_VECTOR) || (is_string(seq)) || (is_pair(seq))) { s7_xf_store(sc, obj); s7_xf_store(sc, (s7_pointer)iterator_next(obj)); return(iterate_pf_s); } } } return(NULL); } s7_pointer s7_iterate(s7_scheme *sc, s7_pointer obj) { return((iterator_next(obj))(sc, obj)); } bool s7_is_iterator(s7_pointer obj) { return(is_iterator(obj)); } bool s7_iterator_is_at_end(s7_pointer obj) { return(iterator_is_at_end(obj)); } static s7_pointer g_iterator_sequence(s7_scheme *sc, s7_pointer args) { #define H_iterator_sequence "(iterator-sequence iterator) returns the sequence that iterator is traversing." #define Q_iterator_sequence s7_make_signature(sc, 2, sc->IS_SEQUENCE, sc->IS_ITERATOR) s7_pointer iter; iter = car(args); if (!is_iterator(iter)) return(simple_wrong_type_argument(sc, sc->ITERATOR_SEQUENCE, iter, T_ITERATOR)); return(iterator_sequence(iter)); } static s7_pointer c_iterator_sequence(s7_scheme *sc, s7_pointer iter) { if (!is_iterator(iter)) return(simple_wrong_type_argument(sc, sc->ITERATOR_SEQUENCE, iter, T_ITERATOR)); return(iterator_sequence(iter)); } PF_TO_PF(iterator_sequence, c_iterator_sequence) static s7_pointer g_iterator_is_at_end(s7_scheme *sc, s7_pointer args) { #define H_iterator_is_at_end "(iterator-at-end? iter) returns #t if the iterator has reached the end of its sequence." #define Q_iterator_is_at_end s7_make_signature(sc, 2, sc->IS_BOOLEAN, sc->IS_ITERATOR) s7_pointer iter; iter = car(args); if (!is_iterator(iter)) return(simple_wrong_type_argument(sc, sc->ITERATOR_IS_AT_END, iter, T_ITERATOR)); return(make_boolean(sc, iterator_is_at_end(iter))); } /* -------------------------------------------------------------------------------- */ #define INITIAL_SHARED_INFO_SIZE 8 static int shared_ref(shared_info *ci, s7_pointer p) { /* from print after collecting refs, not called by equality check */ int i; s7_pointer *objs; if (!is_collected(p)) return(0); objs = ci->objs; for (i = 0; i < ci->top; i++) if (objs[i] == p) { int val; val = ci->refs[i]; if (val > 0) ci->refs[i] = -ci->refs[i]; return(val); } return(0); } static int peek_shared_ref(shared_info *ci, s7_pointer p) { /* returns 0 if not found, otherwise the ref value for p */ int i; s7_pointer *objs; objs = ci->objs; if (!is_collected(p)) return(0); for (i = 0; i < ci->top; i++) if (objs[i] == p) return(ci->refs[i]); return(0); } static void enlarge_shared_info(shared_info *ci) { int i; ci->size *= 2; ci->objs = (s7_pointer *)realloc(ci->objs, ci->size * sizeof(s7_pointer)); ci->refs = (int *)realloc(ci->refs, ci->size * sizeof(int)); for (i = ci->top; i < ci->size; i++) { ci->refs[i] = 0; ci->objs[i] = NULL; } } static void add_equal_ref(shared_info *ci, s7_pointer x, s7_pointer y) { /* assume neither x nor y is in the table, and that they should share a ref value, * called only in equality check, not printer. */ if ((ci->top + 2) >= ci->size) enlarge_shared_info(ci); set_collected(x); set_collected(y); ci->ref++; ci->objs[ci->top] = x; ci->refs[ci->top++] = ci->ref; ci->objs[ci->top] = y; ci->refs[ci->top++] = ci->ref; } static void add_shared_ref(shared_info *ci, s7_pointer x, int ref_x) { /* called only in equality check, not printer */ if (ci->top == ci->size) enlarge_shared_info(ci); set_collected(x); ci->objs[ci->top] = x; ci->refs[ci->top++] = ref_x; } static shared_info *collect_shared_info(s7_scheme *sc, shared_info *ci, s7_pointer top, bool stop_at_print_length, bool *cyclic); static hash_entry_t *hash_equal(s7_scheme *sc, s7_pointer table, s7_pointer key); static void collect_vector_info(s7_scheme *sc, shared_info *ci, s7_pointer top, bool stop_at_print_length, bool *cyclic) { s7_int i, plen; if (stop_at_print_length) { plen = sc->print_length; if (plen > vector_length(top)) plen = vector_length(top); } else plen = vector_length(top); for (i = 0; i < plen; i++) if (has_structure(vector_element(top, i))) collect_shared_info(sc, ci, vector_element(top, i), stop_at_print_length, cyclic); } static shared_info *collect_shared_info(s7_scheme *sc, shared_info *ci, s7_pointer top, bool stop_at_print_length, bool *cyclic) { /* look for top in current list. * * As we collect objects (guaranteed to have structure) we set the collected bit. If we ever * encounter an object with that bit on, we've seen it before so we have a possible cycle. * Once the collection pass is done, we run through our list, and clear all these bits. */ if (is_shared(top)) return(ci); if (is_collected(top)) { s7_pointer *p, *objs_end; int i; *cyclic = true; objs_end = (s7_pointer *)(ci->objs + ci->top); for (p = ci->objs; p < objs_end; p++) if ((*p) == top) { i = (int)(p - ci->objs); if (ci->refs[i] == 0) { ci->has_hits = true; ci->refs[i] = ++ci->ref; /* if found, set the ref number */ } break; } } else { /* top not seen before -- add it to the list */ bool top_cyclic = false; set_collected(top); if (ci->top == ci->size) enlarge_shared_info(ci); ci->objs[ci->top++] = top; /* now search the rest of this structure */ switch (type(top)) { case T_PAIR: if (has_structure(car(top))) collect_shared_info(sc, ci, car(top), stop_at_print_length, &top_cyclic); if (has_structure(cdr(top))) collect_shared_info(sc, ci, cdr(top), stop_at_print_length, &top_cyclic); break; case T_VECTOR: collect_vector_info(sc, ci, top, stop_at_print_length, &top_cyclic); break; case T_ITERATOR: collect_shared_info(sc, ci, iterator_sequence(top), stop_at_print_length, &top_cyclic); break; case T_HASH_TABLE: if (hash_table_entries(top) > 0) { unsigned int i, len; hash_entry_t **entries; bool keys_safe; keys_safe = ((hash_table_checker(top) != hash_equal) && (!hash_table_checker_locked(top))); entries = hash_table_elements(top); len = hash_table_mask(top) + 1; for (i = 0; i < len; i++) { hash_entry_t *p; for (p = entries[i]; p; p = p->next) { if ((!keys_safe) && (has_structure(p->key))) collect_shared_info(sc, ci, p->key, stop_at_print_length, &top_cyclic); if (has_structure(p->value)) collect_shared_info(sc, ci, p->value, stop_at_print_length, &top_cyclic); } } } break; case T_SLOT: if (has_structure(slot_value(top))) collect_shared_info(sc, ci, slot_value(top), stop_at_print_length, &top_cyclic); break; case T_LET: if (top == sc->rootlet) collect_vector_info(sc, ci, top, stop_at_print_length, &top_cyclic); else { s7_pointer p; for (p = let_slots(top); is_slot(p); p = next_slot(p)) if (has_structure(slot_value(p))) collect_shared_info(sc, ci, slot_value(p), stop_at_print_length, &top_cyclic); } break; } if (!top_cyclic) set_shared(top); else *cyclic = true; } return(ci); } static shared_info *new_shared_info(s7_scheme *sc) { shared_info *ci; if (sc->circle_info == NULL) { ci = (shared_info *)calloc(1, sizeof(shared_info)); ci->size = INITIAL_SHARED_INFO_SIZE; ci->objs = (s7_pointer *)malloc(ci->size * sizeof(s7_pointer)); ci->refs = (int *)calloc(ci->size, sizeof(int)); /* finder expects 0 = unseen previously */ sc->circle_info = ci; } else { int i; ci = sc->circle_info; memclr((void *)(ci->refs), ci->top * sizeof(int)); for (i = 0; i < ci->top; i++) clear_collected_and_shared(ci->objs[i]); } ci->top = 0; ci->ref = 0; ci->has_hits = false; return(ci); } static shared_info *make_shared_info(s7_scheme *sc, s7_pointer top, bool stop_at_print_length) { /* for the printer */ shared_info *ci; int i, refs; s7_pointer *ci_objs; int *ci_refs; bool no_problem = true, cyclic = false; /* check for simple cases first */ if (is_pair(top)) { if (s7_list_length(sc, top) != 0) /* it is not circular at the top level (following cdr), so we can check each car(x) */ { s7_pointer x; for (x = top; is_pair(x); x = cdr(x)) if (has_structure(car(x))) { /* it can help a little in some cases to scan vectors here (and slots): * if no element has structure, it's ok (maybe also hash_table_entries == 0) */ no_problem = false; break; } if ((no_problem) && (!is_null(x)) && (has_structure(x))) no_problem = false; if (no_problem) return(NULL); } } else { if (s7_is_vector(top)) { if (type(top) != T_VECTOR) return(NULL); for (i = 0; i < vector_length(top); i++) if (has_structure(vector_element(top, i))) { no_problem = false; break; } if (no_problem) return(NULL); } } ci = new_shared_info(sc); /* collect all pointers associated with top */ collect_shared_info(sc, ci, top, stop_at_print_length, &cyclic); for (i = 0; i < ci->top; i++) { s7_pointer p; p = ci->objs[i]; clear_collected_and_shared(p); } if (!cyclic) return(NULL); if (!(ci->has_hits)) return(NULL); ci_objs = ci->objs; ci_refs = ci->refs; /* find if any were referenced twice (once for just being there, so twice=shared) * we know there's at least one such reference because has_hits is true. */ for (i = 0, refs = 0; i < ci->top; i++) if (ci_refs[i] > 0) { set_collected(ci_objs[i]); if (i == refs) refs++; else { ci_objs[refs] = ci_objs[i]; ci_refs[refs++] = ci_refs[i]; ci_refs[i] = 0; ci_objs[i] = NULL; } } ci->top = refs; return(ci); } /* -------------------------------- cyclic-sequences -------------------------------- */ static s7_pointer cyclic_sequences(s7_scheme *sc, s7_pointer obj, bool return_list) { if (has_structure(obj)) { shared_info *ci; ci = make_shared_info(sc, obj, false); /* false=don't stop at print length (vectors etc) */ if (ci) { if (return_list) { int i; s7_pointer lst; sc->w = sc->NIL; for (i = 0; i < ci->top; i++) sc->w = cons(sc, ci->objs[i], sc->w); lst = sc->w; sc->w = sc->NIL; return(lst); } else return(sc->T); } } return(sc->NIL); } static s7_pointer g_cyclic_sequences(s7_scheme *sc, s7_pointer args) { #define H_cyclic_sequences "(cyclic-sequences obj) returns a list of elements that are cyclic." #define Q_cyclic_sequences s7_make_signature(sc, 2, sc->IS_LIST, sc->T) return(cyclic_sequences(sc, car(args), true)); } static int circular_list_entries(s7_pointer lst) { int i; s7_pointer x; for (i = 1, x = cdr(lst); ; i++, x = cdr(x)) { int j; s7_pointer y; for (y = lst, j = 0; j < i; y = cdr(y), j++) if (x == y) return(i); } } static void object_to_port_with_circle_check(s7_scheme *sc, s7_pointer vr, s7_pointer port, use_write_t use_write, shared_info *ci); static void object_to_port(s7_scheme *sc, s7_pointer obj, s7_pointer port, use_write_t use_write, shared_info *ci); static s7_pointer object_out(s7_scheme *sc, s7_pointer obj, s7_pointer strport, use_write_t choice); static char *multivector_indices_to_string(s7_scheme *sc, s7_int index, s7_pointer vect, char *str, int cur_dim) { s7_int size, ind; char buf[64]; size = vector_dimension(vect, cur_dim); ind = index % size; if (cur_dim > 0) multivector_indices_to_string(sc, (index - ind) / size, vect, str, cur_dim - 1); snprintf(buf, 64, " %lld", ind); #ifdef __OpenBSD__ strlcat(str, buf, 128); /* 128=length of str */ #else strcat(str, buf); #endif return(str); } static int multivector_to_port(s7_scheme *sc, s7_pointer vec, s7_pointer port, int out_len, int flat_ref, int dimension, int dimensions, bool *last, use_write_t use_write, shared_info *ci) { int i; if (use_write != USE_READABLE_WRITE) { if (*last) port_write_string(port)(sc, " (", 2, port); else port_write_character(port)(sc, '(', port); (*last) = false; } for (i = 0; i < vector_dimension(vec, dimension); i++) { if (dimension == (dimensions - 1)) { if (flat_ref < out_len) { if (use_write == USE_READABLE_WRITE) { int plen; char buf[128]; char *indices; /* need to translate flat_ref into a set of indices */ tmpbuf_calloc(indices, 128); plen = snprintf(buf, 128, "(set! ({v}%s) ", multivector_indices_to_string(sc, flat_ref, vec, indices, dimension)); port_write_string(port)(sc, buf, plen, port); tmpbuf_free(indices, 128); } object_to_port_with_circle_check(sc, vector_element(vec, flat_ref), port, DONT_USE_DISPLAY(use_write), ci); if (use_write == USE_READABLE_WRITE) port_write_string(port)(sc, ") ", 2, port); flat_ref++; } else { port_write_string(port)(sc, "...)", 4, port); return(flat_ref); } if ((use_write != USE_READABLE_WRITE) && (i < (vector_dimension(vec, dimension) - 1))) port_write_character(port)(sc, ' ', port); } else { if (flat_ref < out_len) flat_ref = multivector_to_port(sc, vec, port, out_len, flat_ref, dimension + 1, dimensions, last, DONT_USE_DISPLAY(use_write), ci); else { port_write_string(port)(sc, "...)", 4, port); return(flat_ref); } } } if (use_write != USE_READABLE_WRITE) port_write_character(port)(sc, ')', port); (*last) = true; return(flat_ref); } static void vector_to_port(s7_scheme *sc, s7_pointer vect, s7_pointer port, use_write_t use_write, shared_info *ci) { s7_int i, len; int plen; bool too_long = false; char buf[128]; len = vector_length(vect); if (len == 0) { if (vector_rank(vect) > 1) { plen = snprintf(buf, 32, "#%uD()", vector_ndims(vect)); port_write_string(port)(sc, buf, plen, port); } else port_write_string(port)(sc, "#()", 3, port); return; } if (use_write != USE_READABLE_WRITE) { plen = sc->print_length; if (plen <= 0) { if (vector_rank(vect) > 1) { plen = snprintf(buf, 32, "#%uD(...)", vector_ndims(vect)); port_write_string(port)(sc, buf, plen, port); } else port_write_string(port)(sc, "#(...)", 6, port); return; } if (len > plen) { too_long = true; len = plen; } } if (use_write == USE_READABLE_WRITE) { if ((ci) && (peek_shared_ref(ci, vect) != 0)) { port_write_string(port)(sc, "(let (({v} (make-vector ", 24, port); if (vector_rank(vect) > 1) { unsigned int dim; port_write_string(port)(sc, "'(", 2, port); for (dim = 0; dim < vector_ndims(vect); dim++) { plen = snprintf(buf, 128, "%lld ", vector_dimension(vect, dim)); port_write_string(port)(sc, buf, plen, port); } port_write_string(port)(sc, ")))) ", 5, port); } else { plen = snprintf(buf, 128, "%lld))) ", vector_length(vect)); port_write_string(port)(sc, buf, plen, port); } if (shared_ref(ci, vect) < 0) { plen = snprintf(buf, 128, "(set! {%d} {v}) ", -shared_ref(ci, vect)); port_write_string(port)(sc, buf, plen, port); } if (vector_rank(vect) > 1) { bool last = false; multivector_to_port(sc, vect, port, len, 0, 0, vector_ndims(vect), &last, use_write, ci); } else { for (i = 0; i < len; i++) { port_write_string(port)(sc, "(set! ({v} ", 11, port); plen = snprintf(buf, 128, "%lld) ", i); port_write_string(port)(sc, buf, plen, port); object_to_port_with_circle_check(sc, vector_element(vect, i), port, use_write, ci); port_write_string(port)(sc, ") ", 2, port); } } port_write_string(port)(sc, "{v})", 4, port); } else /* simple readable case */ { if (vector_rank(vect) > 1) port_write_string(port)(sc, "(make-shared-vector (vector", 27, port); else port_write_string(port)(sc, "(vector", 7, port); for (i = 0; i < len; i++) { port_write_character(port)(sc, ' ', port); object_to_port_with_circle_check(sc, vector_element(vect, i), port, use_write, ci); } port_write_character(port)(sc, ')', port); if (vector_rank(vect) > 1) { unsigned int dim; port_write_string(port)(sc, " '(", 3, port); for (dim = 0; dim < vector_ndims(vect) - 1; dim++) { plen = snprintf(buf, 128, "%lld ", vector_dimension(vect, dim)); port_write_string(port)(sc, buf, plen, port); } plen = snprintf(buf, 128, "%lld", vector_dimension(vect, dim)); port_write_string(port)(sc, buf, plen, port); port_write_string(port)(sc, "))", 2, port); } } } else { if (vector_rank(vect) > 1) { bool last = false; if (vector_ndims(vect) > 1) { plen = snprintf(buf, 32, "#%uD", vector_ndims(vect)); port_write_string(port)(sc, buf, plen, port); } else port_write_character(port)(sc, '#', port); multivector_to_port(sc, vect, port, len, 0, 0, vector_ndims(vect), &last, use_write, ci); } else { port_write_string(port)(sc, "#(", 2, port); for (i = 0; i < len - 1; i++) { object_to_port_with_circle_check(sc, vector_element(vect, i), port, DONT_USE_DISPLAY(use_write), ci); port_write_character(port)(sc, ' ', port); } object_to_port_with_circle_check(sc, vector_element(vect, i), port, DONT_USE_DISPLAY(use_write), ci); if (too_long) port_write_string(port)(sc, " ...)", 5, port); else port_write_character(port)(sc, ')', port); } } } static bool string_needs_slashification(const char *str, int len) { /* we have to go by len (str len) not *s==0 because s7 strings can have embedded nulls */ unsigned char *p, *pend; pend = (unsigned char *)(str + len); for (p = (unsigned char *)str; p < pend; p++) if (slashify_table[*p]) return(true); return(false); } #define IN_QUOTES true #define NOT_IN_QUOTES false static char *slashify_string(s7_scheme *sc, const char *p, int len, bool quoted, int *nlen) /* do not free result */ { int j = 0, cur_size, size; char *s; unsigned char *pcur, *pend; pend = (unsigned char *)(p + len); size = len + 256; if (size > sc->slash_str_size) { if (sc->slash_str) free(sc->slash_str); sc->slash_str_size = size; sc->slash_str = (char *)malloc(size); } else size = sc->slash_str_size; cur_size = size - 2; /* memset((void *)sc->slash_str, 0, size); */ s = sc->slash_str; if (quoted) s[j++] = '"'; /* what about the trailing nulls? Guile writes them out (as does s7 currently) * but that is not ideal. I'd like to use ~S for error messages, so that * strings are clearly identified via the double-quotes, but this way of * writing them is ugly: * * :(let ((str (make-string 8 #\null))) (set! (str 0) #\a) str) * "a\x00\x00\x00\x00\x00\x00\x00" * * but it would be misleading to omit them because: * * :(let ((str (make-string 8 #\null))) (set! (str 0) #\a) (string-append str "bc")) * "a\x00\x00\x00\x00\x00\x00\x00bc" */ for (pcur = (unsigned char *)p; pcur < pend; pcur++) { if (slashify_table[*pcur]) { s[j++] = '\\'; switch (*pcur) { case '"': s[j++] = '"'; break; case '\\': s[j++] = '\\'; break; default: /* this is the "\x01" stuff */ { unsigned int n; static char dignum[] = "0123456789abcdef"; s[j++] = 'x'; n = (unsigned int)(*pcur); if (n < 16) s[j++] = '0'; else s[j++] = dignum[(n / 16) % 16]; s[j++] = dignum[n % 16]; } break; } } else s[j++] = *pcur; if (j >= cur_size) /* even with 256 extra, we can overflow (for example, inordinately many tabs in ALSA output) */ { /* int k; */ size *= 2; sc->slash_str = (char *)realloc(sc->slash_str, size * sizeof(char)); sc->slash_str_size = size; cur_size = size - 2; s = sc->slash_str; /* for (k = j; k < size; k++) s[k] = 0; */ } } if (quoted) s[j++] = '"'; s[j] = '\0'; (*nlen) = j; return(s); } static void output_port_to_port(s7_scheme *sc, s7_pointer obj, s7_pointer port, use_write_t use_write) { if ((obj == sc->standard_output) || (obj == sc->standard_error)) port_write_string(port)(sc, port_filename(obj), port_filename_length(obj), port); else { int nlen; if (use_write == USE_READABLE_WRITE) { if (port_is_closed(obj)) port_write_string(port)(sc, "(let ((p (open-output-string))) (close-output-port p) p)", 56, port); else { char *str; if (is_string_port(obj)) { port_write_string(port)(sc, "(let ((p (open-output-string)))", 31, port); if (port_position(obj) > 0) { port_write_string(port)(sc, " (display ", 10, port); str = slashify_string(sc, (const char *)port_data(obj), port_position(obj), IN_QUOTES, &nlen); port_write_string(port)(sc, str, nlen, port); port_write_string(port)(sc, " p)", 3, port); } port_write_string(port)(sc, " p)", 3, port); } else { str = (char *)malloc(256 * sizeof(char)); nlen = snprintf(str, 256, "(open-output-file \"%s\" \"a\")", port_filename(obj)); port_write_string(port)(sc, str, nlen, port); free(str); } } } else { if (is_string_port(obj)) port_write_string(port)(sc, "", 10, port); else port_write_character(port)(sc, '>', port); } } } static void input_port_to_port(s7_scheme *sc, s7_pointer obj, s7_pointer port, use_write_t use_write) { if (obj == sc->standard_input) port_write_string(port)(sc, port_filename(obj), port_filename_length(obj), port); else { int nlen = 0; if (use_write == USE_READABLE_WRITE) { if (port_is_closed(obj)) port_write_string(port)(sc, "(call-with-input-string \"\" (lambda (p) p))", 42, port); else { if (is_function_port(obj)) port_write_string(port)(sc, "#", 22, port); else { char *str; if (is_file_port(obj)) { str = (char *)malloc(256 * sizeof(char)); nlen = snprintf(str, 256, "(open-input-file \"%s\")", port_filename(obj)); port_write_string(port)(sc, str, nlen, port); free(str); } else { /* if the string is large, slashify_string is a problem. Usually this is actually * a file port where the contents were read in one (up to 5MB) gulp, so the * readable version could be: open file, read-char to the current port_position. * s7_port_filename(port) has the char* name if any. */ int data_len; data_len = port_data_size(obj) - port_position(obj); if (data_len > 100) { const char *filename; filename = (const char *)s7_port_filename(obj); if (filename) { #define DO_STR_LEN 1024 char *do_str; int len; do_str = (char *)malloc(DO_STR_LEN * sizeof(char)); if (port_position(obj) > 0) { len = snprintf(do_str, DO_STR_LEN, "(let ((port (open-input-file \"%s\")))", filename); port_write_string(port)(sc, do_str, len, port); len = snprintf(do_str, DO_STR_LEN, " (do ((i 0 (+ i 1)) (c (read-char port) (read-char port))) ((= i %d) port)))", port_position(obj) - 1); } else len = snprintf(do_str, DO_STR_LEN, "(open-input-file \"%s\")", filename); port_write_string(port)(sc, do_str, len, port); free(do_str); return; } } port_write_string(port)(sc, "(open-input-string ", 19, port); /* not port_write_string here because there might be embedded double-quotes */ str = slashify_string(sc, (const char *)(port_data(obj) + port_position(obj)), port_data_size(obj) - port_position(obj), IN_QUOTES, &nlen); port_write_string(port)(sc, str, nlen, port); port_write_character(port)(sc, ')', port); } } } } else { if (is_string_port(obj)) port_write_string(port)(sc, "", 10, port); else port_write_character(port)(sc, '>', port); } } } static bool symbol_needs_slashification(s7_pointer obj) { unsigned char *p, *pend; const char *str; int len; str = symbol_name(obj); if (str[0] == '#') return(true); len = symbol_name_length(obj); pend = (unsigned char *)(str + len); for (p = (unsigned char *)str; p < pend; p++) if (symbol_slashify_table[*p]) return(true); set_clean_symbol(obj); return(false); } static void symbol_to_port(s7_scheme *sc, s7_pointer obj, s7_pointer port, use_write_t use_write) { /* I think this is the only place we print a symbol's name * but in the readable case, what about (symbol "1;3")? it actually seems ok! */ if ((!is_clean_symbol(obj)) && (symbol_needs_slashification(obj))) { int nlen = 0; char *str, *symstr; str = slashify_string(sc, symbol_name(obj), symbol_name_length(obj), NOT_IN_QUOTES, &nlen); nlen += 16; tmpbuf_malloc(symstr, nlen); nlen = snprintf(symstr, nlen, "(symbol \"%s\")", str); port_write_string(port)(sc, symstr, nlen, port); tmpbuf_free(symstr, nlen); } else { if ((use_write == USE_READABLE_WRITE) && (!is_keyword(obj))) port_write_character(port)(sc, '\'', port); if (is_string_port(port)) { int new_len; new_len = port_position(port) + symbol_name_length(obj); if (new_len >= (int)port_data_size(port)) resize_port_data(port, new_len * 2); memcpy((void *)(port_data(port) + port_position(port)), (void *)symbol_name(obj), symbol_name_length(obj)); port_position(port) = new_len; } else port_write_string(port)(sc, symbol_name(obj), symbol_name_length(obj), port); } } static void string_to_port(s7_scheme *sc, s7_pointer obj, s7_pointer port, use_write_t use_write) { if (string_length(obj) > 0) { /* this used to check for length > 1<<24 -- is that still necessary? * since string_length is a scheme length, not C, this write can embed nulls from C's point of view */ if (use_write == USE_DISPLAY) port_write_string(port)(sc, string_value(obj), string_length(obj), port); else { if (!string_needs_slashification(string_value(obj), string_length(obj))) { port_write_character(port)(sc, '"', port); port_write_string(port)(sc, string_value(obj), string_length(obj), port); port_write_character(port)(sc, '"', port); } else { char *str; int nlen = 0; str = slashify_string(sc, string_value(obj), string_length(obj), IN_QUOTES, &nlen); port_write_string(port)(sc, str, nlen, port); } } } else { if (use_write != USE_DISPLAY) port_write_string(port)(sc, "\"\"", 2, port); } } static void byte_vector_to_port(s7_scheme *sc, s7_pointer vect, s7_pointer port, use_write_t use_write) { s7_int i, len; int plen; bool too_long = false; len = string_length(vect); if (use_write == USE_READABLE_WRITE) plen = len; else plen = sc->print_length; if (len == 0) port_write_string(port)(sc, "#u8()", 5, port); else { if (plen <= 0) port_write_string(port)(sc, "#u8(...)", 8, port); else { unsigned int nlen; char *p; if (len > plen) { too_long = true; len = plen; } port_write_string(port)(sc, "#u8(", 4, port); for (i = 0; i < len - 1; i++) { p = pos_int_to_str((int)((unsigned char)string_value(vect)[i]), &nlen, ' '); port_write_string(port)(sc, p, nlen - 1, port); } p = pos_int_to_str((int)((unsigned char)string_value(vect)[i]), &nlen, (too_long) ? '\0' : ')'); port_write_string(port)(sc, p, nlen - 1, port); if (too_long) port_write_string(port)(sc, " ...)", 5, port); } } } static void int_or_float_vector_to_port(s7_scheme *sc, s7_pointer vect, s7_pointer port, use_write_t use_write) { s7_int i, len; int plen; bool too_long = false; len = vector_length(vect); if (use_write == USE_READABLE_WRITE) plen = len; else plen = sc->print_length; if (len == 0) port_write_string(port)(sc, "#()", 3, port); else { if (plen <= 0) port_write_string(port)(sc, "#(...)", 6, port); else { char buf[128]; if (len > plen) { too_long = true; len = plen; } if (is_int_vector(vect)) { if (vector_rank(vect) > 1) port_write_string(port)(sc, "(make-shared-vector (int-vector", 31, port); else port_write_string(port)(sc, "(int-vector", 11, port); if (!is_string_port(port)) { for (i = 0; i < len; i++) { plen = snprintf(buf, 128, " %lld", int_vector_element(vect, i)); port_write_string(port)(sc, buf, plen, port); } } else { /* an experiment */ int new_len, next_len; unsigned char *dbuf; new_len = port_position(port); next_len = port_data_size(port) - 128; dbuf = port_data(port); for (i = 0; i < len; i++) { if (new_len >= next_len) { resize_port_data(port, port_data_size(port) * 2); next_len = port_data_size(port) - 128; dbuf = port_data(port); } plen = snprintf((char *)(dbuf + new_len), 128, " %lld", int_vector_element(vect, i)); new_len += plen; } port_position(port) = new_len; } } else { if (vector_rank(vect) > 1) port_write_string(port)(sc, "(make-shared-vector (float-vector", 33, port); else port_write_string(port)(sc, "(float-vector", 13, port); for (i = 0; i < len; i++) { port_write_character(port)(sc, ' ', port); plen = snprintf(buf, 124, float_format_g, float_format_precision, float_vector_element(vect, i)); /* 124 so floatify has room */ floatify(buf, &plen); port_write_string(port)(sc, buf, plen, port); } } if (too_long) port_write_string(port)(sc, " ...)", 5, port); else port_write_character(port)(sc, ')', port); if (vector_rank(vect) > 1) { unsigned int dim; port_write_string(port)(sc, " '(", 3, port); for (dim = 0; dim < vector_ndims(vect) - 1; dim++) { plen = snprintf(buf, 128, "%lld ", vector_dimension(vect, dim)); port_write_string(port)(sc, buf, plen, port); } plen = snprintf(buf, 128, "%lld", vector_dimension(vect, dim)); port_write_string(port)(sc, buf, plen, port); port_write_string(port)(sc, "))", 2, port); } } } } static void list_to_port(s7_scheme *sc, s7_pointer lst, s7_pointer port, use_write_t use_write, shared_info *ci) { /* we need list_to_starboard... */ s7_pointer x; int i, len, true_len; true_len = s7_list_length(sc, lst); if (true_len < 0) /* a dotted list -- handle cars, then final cdr */ len = (-true_len + 1); else { if (true_len == 0) /* either () or a circular list */ { if (is_not_null(lst)) len = circular_list_entries(lst); else { port_write_string(port)(sc, "()", 2, port); return; } } else len = true_len; } if (((car(lst) == sc->QUOTE) || (car(lst) == sc->QUOTE_UNCHECKED)) && /* this can happen (see lint.scm) */ (true_len == 2)) { /* len == 1 is important, otherwise (list 'quote 1 2) -> '1 2 which looks weird * or (object->string (apply . `''1)) -> "'quote 1" * so (quote x) = 'x but (quote x y z) should be left alone (if evaluated, it's an error) */ port_write_character(port)(sc, '\'', port); object_to_port_with_circle_check(sc, cadr(lst), port, USE_WRITE, ci); return; } else port_write_character(port)(sc, '(', port); if (is_multiple_value(lst)) port_write_string(port)(sc, "values ", 7, port); if (use_write == USE_READABLE_WRITE) { if (ci) { int plen; char buf[128]; port_write_string(port)(sc, "let (({lst} (make-list ", 23, port); plen = snprintf(buf, 128, "%d))) ", len); port_write_string(port)(sc, buf, plen, port); if ((shared_ref(ci, lst) < 0)) { plen = snprintf(buf, 128, "(set! {%d} {lst}) ", -shared_ref(ci, lst)); port_write_string(port)(sc, buf, plen, port); } port_write_string(port)(sc, "(let (({x} {lst})) ", 19, port); for (i = 0, x = lst; (i < len) && (is_pair(x)); i++, x = cdr(x)) { port_write_string(port)(sc, "(set-car! {x} ", 14, port); object_to_port_with_circle_check(sc, car(x), port, use_write, ci); port_write_string(port)(sc, ") ", 2, port); if (i < len - 1) port_write_string(port)(sc, "(set! {x} (cdr {x})) ", 21, port); } if (!is_null(x)) { port_write_string(port)(sc, "(set-cdr! {x} ", 14, port); object_to_port_with_circle_check(sc, x, port, use_write, ci); port_write_string(port)(sc, ") ", 2, port); } port_write_string(port)(sc, ") {lst})", 8, port); } else { /* the easier cases: no circles or shared refs to patch up */ if (true_len > 0) { port_write_string(port)(sc, "list", 4, port); for (x = lst; is_pair(x); x = cdr(x)) { port_write_character(port)(sc, ' ', port); object_to_port_with_circle_check(sc, car(x), port, use_write, ci); } port_write_character(port)(sc, ')', port); } else { port_write_string(port)(sc, "cons ", 5, port); object_to_port_with_circle_check(sc, car(lst), port, use_write, ci); for (x = cdr(lst); is_pair(x); x = cdr(x)) { port_write_character(port)(sc, ' ', port); port_write_string(port)(sc, "(cons ", 6, port); object_to_port_with_circle_check(sc, car(x), port, use_write, ci); } port_write_character(port)(sc, ' ', port); object_to_port_with_circle_check(sc, x, port, use_write, ci); for (i = 1; i < len; i++) port_write_character(port)(sc, ')', port); } } } else { if (ci) { for (x = lst, i = 0; (is_pair(x)) && (i < len) && ((!ci) || (i == 0) || (peek_shared_ref(ci, x) == 0)); i++, x = cdr(x)) { object_to_port_with_circle_check(sc, car(x), port, DONT_USE_DISPLAY(use_write), ci); if (i < (len - 1)) port_write_character(port)(sc, ' ', port); } if (is_not_null(x)) { if ((true_len == 0) && (i == len)) port_write_string(port)(sc, " . ", 3, port); else port_write_string(port)(sc, ". ", 2, port); object_to_port_with_circle_check(sc, x, port, DONT_USE_DISPLAY(use_write), ci); } port_write_character(port)(sc, ')', port); } else { for (x = lst, i = 0; (is_pair(x)) && (i < len); i++, x = cdr(x)) { object_to_port(sc, car(x), port, DONT_USE_DISPLAY(use_write), ci); if (i < (len - 1)) port_write_character(port)(sc, ' ', port); } if (is_not_null(x)) { port_write_string(port)(sc, ". ", 2, port); object_to_port(sc, x, port, DONT_USE_DISPLAY(use_write), ci); } port_write_character(port)(sc, ')', port); } } } static void hash_table_to_port(s7_scheme *sc, s7_pointer hash, s7_pointer port, use_write_t use_write, shared_info *ci) { int i, len, gc_iter; bool too_long = false; s7_pointer iterator, p; /* if hash is a member of ci, just print its number * (let ((ht (hash-table '(a . 1)))) (hash-table-set! ht 'b ht)) * * since equal? does not care about the hash-table lengths, we can ignore that complication in the :readable case */ len = hash_table_entries(hash); if (len == 0) { port_write_string(port)(sc, "(hash-table)", 12, port); return; } if (use_write != USE_READABLE_WRITE) { s7_int plen; plen = sc->print_length; if (plen <= 0) { port_write_string(port)(sc, "(hash-table ...)", 16, port); return; } if (len > plen) { too_long = true; len = plen; } } iterator = s7_make_iterator(sc, hash); gc_iter = s7_gc_protect(sc, iterator); p = cons(sc, sc->F, sc->F); iterator_current(iterator) = p; set_mark_seq(iterator); if ((use_write == USE_READABLE_WRITE) && (ci) && (peek_shared_ref(ci, hash) != 0)) { port_write_string(port)(sc, "(let (({ht} (make-hash-table)))", 31, port); if (shared_ref(ci, hash) < 0) { int plen; char buf[64]; plen = snprintf(buf, 64, "(set! {%d} {ht}) ", -shared_ref(ci, hash)); port_write_string(port)(sc, buf, plen, port); } for (i = 0; i < len; i++) { s7_pointer key_val, key, val; key_val = hash_table_iterate(sc, iterator); key = car(key_val); val = cdr(key_val); port_write_string(port)(sc, " (set! ({ht} ", 13, port); if (key == hash) port_write_string(port)(sc, "{ht}", 4, port); else object_to_port_with_circle_check(sc, key, port, USE_READABLE_WRITE, ci); port_write_string(port)(sc, ") ", 2, port); if (val == hash) port_write_string(port)(sc, "{ht}", 4, port); else object_to_port_with_circle_check(sc, val, port, USE_READABLE_WRITE, ci); port_write_character(port)(sc, ')', port); } port_write_string(port)(sc, " {ht})", 6, port); } else { port_write_string(port)(sc, "(hash-table", 11, port); for (i = 0; i < len; i++) { s7_pointer key_val; if (use_write == USE_READABLE_WRITE) port_write_character(port)(sc, ' ', port); else port_write_string(port)(sc, " '", 2, port); key_val = hash_table_iterate(sc, iterator); object_to_port_with_circle_check(sc, key_val, port, DONT_USE_DISPLAY(use_write), ci); } if (too_long) port_write_string(port)(sc, " ...)", 5, port); else port_write_character(port)(sc, ')', port); } s7_gc_unprotect_at(sc, gc_iter); } static void slot_to_port_1(s7_scheme *sc, s7_pointer x, s7_pointer port, use_write_t use_write, shared_info *ci) { if (is_slot(x)) { slot_to_port_1(sc, next_slot(x), port, use_write, ci); port_write_character(port)(sc, ' ', port); object_to_port_with_circle_check(sc, x, port, use_write, ci); } } static void let_to_port(s7_scheme *sc, s7_pointer obj, s7_pointer port, use_write_t use_write, shared_info *ci) { /* if outer env points to (say) method list, the object needs to specialize object->string itself */ if (has_methods(obj)) { s7_pointer print_func; print_func = find_method(sc, obj, sc->OBJECT_TO_STRING); if (print_func != sc->UNDEFINED) { s7_pointer p; /* what needs to be protected here? for one, the function might not return a string! */ clear_has_methods(obj); if (use_write == USE_WRITE) p = s7_apply_function(sc, print_func, list_1(sc, obj)); else p = s7_apply_function(sc, print_func, list_2(sc, obj, (use_write == USE_DISPLAY) ? sc->F : sc->KEY_READABLE)); set_has_methods(obj); if ((is_string(p)) && (string_length(p) > 0)) port_write_string(port)(sc, string_value(p), string_length(p), port); return; } } if (obj == sc->rootlet) port_write_string(port)(sc, "(rootlet)", 9, port); else { /* circles can happen here: * (let () (let ((b (curlet))) (curlet))) * #> * or (let ((b #f)) (set! b (curlet)) (curlet)) * #1=# */ if ((use_write == USE_READABLE_WRITE) && (ci) && (peek_shared_ref(ci, obj) != 0)) { s7_pointer x; port_write_string(port)(sc, "(let (({e} (inlet))) ", 21, port); if ((ci) && (shared_ref(ci, obj) < 0)) { int plen; char buf[64]; plen = snprintf(buf, 64, "(set! {%d} {e}) ", -shared_ref(ci, obj)); port_write_string(port)(sc, buf, plen, port); } port_write_string(port)(sc, "(apply varlet {e} (reverse (list ", 33, port); for (x = let_slots(obj); is_slot(x); x = next_slot(x)) { port_write_string(port)(sc, "(cons ", 6, port); symbol_to_port(sc, slot_symbol(x), port, use_write); port_write_character(port)(sc, ' ', port); object_to_port_with_circle_check(sc, slot_value(x), port, use_write, ci); port_write_character(port)(sc, ')', port); } port_write_string(port)(sc, "))) {e})", 8, port); } else { port_write_string(port)(sc, "(inlet", 6, port); slot_to_port_1(sc, let_slots(obj), port, use_write, ci); port_write_character(port)(sc, ')', port); } } } static void write_macro_readably(s7_scheme *sc, s7_pointer obj, s7_pointer port) { s7_pointer arglist, body, expr; body = closure_body(obj); arglist = closure_args(obj); port_write_string(port)(sc, "(define-", 8, port); port_write_string(port)(sc, ((is_macro(obj)) || (is_macro_star(obj))) ? "macro" : "bacro", 5, port); if ((is_macro_star(obj)) || (is_bacro_star(obj))) port_write_character(port)(sc, '*', port); port_write_string(port)(sc, " (_m_", 5, port); if (is_symbol(arglist)) { port_write_string(port)(sc, " . ", 3, port); port_write_string(port)(sc, symbol_name(arglist), symbol_name_length(arglist), port); } else { if (is_pair(arglist)) { for (expr = arglist; is_pair(expr); expr = cdr(expr)) { port_write_character(port)(sc, ' ', port); object_to_port(sc, car(expr), port, USE_WRITE, NULL); } if (!is_null(expr)) { port_write_string(port)(sc, " . ", 3, port); object_to_port(sc, expr, port, USE_WRITE, NULL); } } } port_write_string(port)(sc, ") ", 2, port); for (expr = body; is_pair(expr); expr = cdr(expr)) object_to_port(sc, car(expr), port, USE_WRITE, NULL); port_write_character(port)(sc, ')', port); } static s7_pointer match_symbol(s7_scheme *sc, s7_pointer symbol, s7_pointer e) { s7_pointer y, le; for (le = e; is_let(le) && (le != sc->rootlet); le = outlet(le)) for (y = let_slots(le); is_slot(y); y = next_slot(y)) if (slot_symbol(y) == symbol) return(y); return(NULL); } static bool slot_memq(s7_pointer symbol, s7_pointer symbols) { s7_pointer x; for (x = symbols; is_pair(x); x = cdr(x)) if (slot_symbol(car(x)) == symbol) return(true); return(false); } static bool arg_memq(s7_pointer symbol, s7_pointer args) { s7_pointer x; for (x = args; is_pair(x); x = cdr(x)) if ((car(x) == symbol) || ((is_pair(car(x))) && (caar(x) == symbol))) return(true); return(false); } static void collect_locals(s7_scheme *sc, s7_pointer body, s7_pointer e, s7_pointer args, int gc_loc) { if (is_pair(body)) { collect_locals(sc, car(body), e, args, gc_loc); collect_locals(sc, cdr(body), e, args, gc_loc); } else { if ((is_symbol(body)) && (!arg_memq(body, args)) && (!slot_memq(body, gc_protected_at(sc, gc_loc)))) { s7_pointer slot; slot = match_symbol(sc, body, e); if (slot) gc_protected_at(sc, gc_loc) = cons(sc, slot, gc_protected_at(sc, gc_loc)); } } } static s7_pointer find_closure(s7_scheme *sc, s7_pointer closure, s7_pointer cur_env) { s7_pointer e, y; for (e = cur_env; is_let(e); e = outlet(e)) { if ((is_function_env(e)) && (is_global(funclet_function(e))) && /* (define (f1) (lambda () 1)) shouldn't say the returned closure is named f1 */ (slot_value(global_slot(funclet_function(e))) == closure)) return(funclet_function(e)); for (y = let_slots(e); is_slot(y); y = next_slot(y)) if (slot_value(y) == closure) return(slot_symbol(y)); } return(sc->NIL); } static void write_closure_name(s7_scheme *sc, s7_pointer closure, s7_pointer port) { s7_pointer x; x = find_closure(sc, closure, closure_let(closure)); /* this can be confusing! In some cases, the function is in its environment, and in other very similar-looking cases it isn't: * (let ((a (lambda () 1))) a) * # * (letrec ((a (lambda () 1))) a) * a * (let () (define (a) 1) a) * a */ if (is_symbol(x)) /* after find_closure */ { port_write_string(port)(sc, symbol_name(x), symbol_name_length(x), port); return; } /* names like # and # are useless -- try to be a bit more informative */ switch (type(closure)) { case T_CLOSURE: port_write_string(port)(sc, "#", 3, port); else { s7_pointer args; args = closure_args(closure); if (is_symbol(args)) { port_write_string(port)(sc, symbol_name(args), symbol_name_length(args), port); port_write_character(port)(sc, '>', port); /* (lambda a a) -> # */ } else { port_write_character(port)(sc, '(', port); x = car(args); if (is_pair(x)) x = car(x); port_write_string(port)(sc, symbol_name(x), symbol_name_length(x), port); if (!is_null(cdr(args))) { s7_pointer y; port_write_character(port)(sc, ' ', port); if (is_pair(cdr(args))) { y = cadr(args); if (is_pair(y)) y = car(y); else { if (y == sc->KEY_REST) { port_write_string(port)(sc, ":rest ", 6, port); args = cdr(args); y = cadr(args); if (is_pair(y)) y = car(y); } } } else { port_write_string(port)(sc, ". ", 2, port); y = cdr(args); } port_write_string(port)(sc, symbol_name(y), symbol_name_length(y), port); if ((is_pair(cdr(args))) && (!is_null(cddr(args)))) port_write_string(port)(sc, " ...", 4, port); } port_write_string(port)(sc, ")>", 2, port); } } } static s7_pointer closure_name(s7_scheme *sc, s7_pointer closure) { /* this is used by the error handlers to get the current function name */ s7_pointer x; x = find_closure(sc, closure, sc->envir); if (is_symbol(x)) return(x); if (is_pair(sc->cur_code)) return(sc->cur_code); return(closure); /* desperation -- the parameter list (caar here) will cause endless confusion in OP_APPLY errors! */ } static void write_closure_readably_1(s7_scheme *sc, s7_pointer obj, s7_pointer arglist, s7_pointer body, s7_pointer port) { s7_int old_print_length; s7_pointer p; if (type(obj) == T_CLOSURE_STAR) port_write_string(port)(sc, "(lambda* ", 9, port); else port_write_string(port)(sc, "(lambda ", 8, port); if ((is_pair(arglist)) && (allows_other_keys(arglist))) { sc->temp9 = s7_append(sc, arglist, cons(sc, sc->KEY_ALLOW_OTHER_KEYS, sc->NIL)); object_out(sc, sc->temp9, port, USE_WRITE); sc->temp9 = sc->NIL; } else object_out(sc, arglist, port, USE_WRITE); /* here we just want the straight output (a b) not (list 'a 'b) */ old_print_length = sc->print_length; sc->print_length = 1048576; for (p = body; is_pair(p); p = cdr(p)) { port_write_character(port)(sc, ' ', port); object_out(sc, car(p), port, USE_WRITE); } port_write_character(port)(sc, ')', port); sc->print_length = old_print_length; } static void write_closure_readably(s7_scheme *sc, s7_pointer obj, s7_pointer port) { s7_pointer body, arglist, pe, local_slots, setter = NULL; int gc_loc; body = closure_body(obj); arglist = closure_args(obj); pe = closure_let(obj); /* perhaps check for documentation? */ gc_loc = s7_gc_protect(sc, sc->NIL); collect_locals(sc, body, pe, arglist, gc_loc); /* collect locals used only here */ if (s7_is_dilambda(obj)) { setter = closure_setter(obj); if ((!(has_closure_let(setter))) || (closure_let(setter) != pe)) setter = NULL; } if (setter) collect_locals(sc, closure_body(setter), pe, closure_args(setter), gc_loc); local_slots = gc_protected_at(sc, gc_loc); if (!is_null(local_slots)) { s7_pointer x; port_write_string(port)(sc, "(let (", 6, port); for (x = local_slots; is_pair(x); x = cdr(x)) { s7_pointer slot; slot = car(x); port_write_character(port)(sc, '(', port); port_write_string(port)(sc, symbol_name(slot_symbol(slot)), symbol_name_length(slot_symbol(slot)), port); port_write_character(port)(sc, ' ', port); object_out(sc, slot_value(slot), port, USE_WRITE); if (is_null(cdr(x))) port_write_character(port)(sc, ')', port); else port_write_string(port)(sc, ") ", 2, port); } port_write_string(port)(sc, ") ", 2, port); } if (setter) port_write_string(port)(sc, "(dilambda ", 10, port); write_closure_readably_1(sc, obj, arglist, body, port); if (setter) { port_write_character(port)(sc, ' ', port); write_closure_readably_1(sc, setter, closure_args(setter), closure_body(setter), port); port_write_character(port)(sc, ')', port); } if (!is_null(local_slots)) port_write_character(port)(sc, ')', port); s7_gc_unprotect_at(sc, gc_loc); } #if TRAP_SEGFAULT #include static sigjmp_buf senv; /* global here is not a problem -- it is used only to protect s7_is_valid */ static volatile sig_atomic_t can_jump = 0; static void segv(int ignored) {if (can_jump) siglongjmp(senv, 1);} #endif bool s7_is_valid(s7_scheme *sc, s7_pointer arg) { bool result = false; if (!arg) return(false); #if TRAP_SEGFAULT if (sigsetjmp(senv, 1) == 0) { void (*old_segv)(int sig); can_jump = 1; old_segv = signal(SIGSEGV, segv); #endif result = ((!is_free(arg)) && (type(arg) < NUM_TYPES) && (arg->hloc >= not_heap) && ((arg->hloc < 0) || ((arg->hloc < (int)sc->heap_size) && (sc->heap[arg->hloc] == arg)))); #if TRAP_SEGFAULT signal(SIGSEGV, old_segv); } else result = false; can_jump = 0; #endif return(result); } enum {NO_ARTICLE, INDEFINITE_ARTICLE}; static char *describe_type_bits(s7_scheme *sc, s7_pointer obj) { unsigned int full_typ; unsigned char typ; char *buf; buf = (char *)malloc(512 * sizeof(char)); typ = unchecked_type(obj); full_typ = typeflag(obj); /* if debugging all of these bits are being watched, so we need some ugly subterfuges */ snprintf(buf, 512, "type: %d (%s), flags: #x%x%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", typ, type_name(sc, obj, NO_ARTICLE), full_typ, ((full_typ & T_PROCEDURE) != 0) ? " procedure" : "", ((full_typ & T_GC_MARK) != 0) ? " gc-marked" : "", ((full_typ & T_IMMUTABLE) != 0) ? " immutable" : "", ((full_typ & T_EXPANSION) != 0) ? " expansion" : "", ((full_typ & T_MULTIPLE_VALUE) != 0) ? " values or matched" : "", ((full_typ & T_KEYWORD) != 0) ? " keyword" : "", ((full_typ & T_DONT_EVAL_ARGS) != 0) ? " dont-eval-args" : "", ((full_typ & T_SYNTACTIC) != 0) ? " syntactic" : "", ((full_typ & T_OVERLAY) != 0) ? " overlay" : "", ((full_typ & T_CHECKED) != 0) ? " checked" : "", ((full_typ & T_UNSAFE) != 0) ? ((is_symbol(obj)) ? " clean" : " unsafe") : "", ((full_typ & T_OPTIMIZED) != 0) ? " optimized" : "", ((full_typ & T_SAFE_CLOSURE) != 0) ? " safe-closure" : "", ((full_typ & T_SAFE_PROCEDURE) != 0) ? " safe-procedure" : "", ((full_typ & T_SETTER) != 0) ? " setter" : "", ((full_typ & T_COPY_ARGS) != 0) ? " copy-args" : "", ((full_typ & T_COLLECTED) != 0) ? " collected" : "", ((full_typ & T_SHARED) != 0) ? " shared" : "", ((full_typ & T_HAS_METHODS) != 0) ? " has-methods" : "", ((full_typ & T_GLOBAL) != 0) ? ((is_pair(obj)) ? " unsafe-do" : " global") : "", ((full_typ & T_SAFE_STEPPER) != 0) ? ((is_let(obj)) ? " let-set!-fallback" : ((is_slot(obj)) ? " safe-stepper" : " print-name")) : "", ((full_typ & T_LINE_NUMBER) != 0) ? ((is_pair(obj)) ? " line number" : ((is_input_port(obj)) ? " loader-port" : ((is_let(obj)) ? " with-let" : " has accessor"))) : "", ((full_typ & T_MUTABLE) != 0) ? ((is_string(obj)) ? " byte-vector" : ((is_let(obj)) ? " let-ref-fallback" : ((is_iterator(obj)) ? " mark-seq" : ((is_slot(obj)) ? " stepper" : " mutable")))) : "", ((full_typ & T_GENSYM) != 0) ? ((is_let(obj)) ? " function-env" : ((is_unspecified(obj)) ? " no-value" : ((is_pair(obj)) ? " list-in-use" : ((is_closure_star(obj)) ? " simple-args" : ((is_string(obj)) ? " documented" : " gensym"))))) : ""); return(buf); } #if DEBUGGING static const char *check_name(int typ) { if ((typ >= 0) && (typ < NUM_TYPES)) { s7_pointer p; p = prepackaged_type_names[typ]; if (is_string(p)) return(string_value(p)); switch (typ) { case T_C_OBJECT: return("a c-object"); case T_INPUT_PORT: return("an input port"); case T_OUTPUT_PORT: return("an output port"); } } return("unknown type!"); } static s7_pointer check_seti(s7_scheme *sc, s7_pointer x, const char *func, int line) { if (is_immutable(x)) { fprintf(stderr, "%s%s[%d]: set! immutable %s: %s%s\n", BOLD_TEXT, func, line, type_name(sc, x, NO_ARTICLE), DISPLAY(x), UNBOLD_TEXT); if (stop_at_error) abort(); } return(x); } static s7_pointer check_ref(s7_pointer p, int expected_type, const char *func, int line, const char *func1, const char *func2) { int typ; typ = unchecked_type(p); if (typ != expected_type) { if ((!func1) || (typ != T_FREE)) { fprintf(stderr, "%s%s[%d]: not %s, but %s (%d)%s\n", BOLD_TEXT, func, line, check_name(expected_type), check_name(typ), typ, UNBOLD_TEXT); if (stop_at_error) abort(); } else { if ((strcmp(func, func1) != 0) && ((!func2) || (strcmp(func, func2) != 0))) { fprintf(stderr, "%s%s[%d]: free cell, not %s%s\n", BOLD_TEXT, func, line, check_name(expected_type), UNBOLD_TEXT); if (stop_at_error) abort(); } } } return(p); } static s7_pointer check_ref2(s7_pointer p, int expected_type, int other_type, const char *func, int line, const char *func1, const char *func2) { int typ; typ = unchecked_type(p); if ((typ != expected_type) && (typ != other_type)) return(check_ref(p, expected_type, func, line, func1, func2)); return(p); } static s7_pointer check_ref3(s7_pointer p, const char *func, int line) { int typ; typ = unchecked_type(p); if ((typ != T_INPUT_PORT) && (typ != T_OUTPUT_PORT) && (typ != T_FREE)) { fprintf(stderr, "%s%s[%d]: not a port, but %s (%d)%s\n", BOLD_TEXT, func, line, check_name(typ), typ, UNBOLD_TEXT); if (stop_at_error) abort(); } return(p); } static s7_pointer check_ref4(s7_pointer p, const char *func, int line) { int typ; typ = unchecked_type(p); if ((typ != T_VECTOR) && (typ != T_FLOAT_VECTOR) && (typ != T_INT_VECTOR) && (typ != T_FREE)) { fprintf(stderr, "%s%s[%d]: not a vector, but %s (%d)%s\n", BOLD_TEXT, func, line, check_name(typ), typ, UNBOLD_TEXT); if (stop_at_error) abort(); } return(p); } static s7_pointer check_ref5(s7_pointer p, const char *func, int line) { int typ; typ = unchecked_type(p); if (!t_has_closure_let[typ]) { fprintf(stderr, "%s%s[%d]: not a closure, but %s (%d)%s\n", BOLD_TEXT, func, line, check_name(typ), typ, UNBOLD_TEXT); if (stop_at_error) abort(); } return(p); } static s7_pointer check_ref6(s7_pointer p, const char *func, int line) { int typ; typ = unchecked_type(p); if ((typ < T_C_FUNCTION_STAR) && (typ != T_C_MACRO)) { fprintf(stderr, "%s%s[%d]: not a c function, but %s (%d)%s\n", BOLD_TEXT, func, line, check_name(typ), typ, UNBOLD_TEXT); if (stop_at_error) abort(); } return(p); } static s7_pointer check_ref7(s7_pointer p, const char *func, int line) { if ((!func) || (strcmp(func, "decribe_type_bits") != 0)) { int typ; typ = unchecked_type(p); if ((typ < T_INTEGER) || (typ > T_COMPLEX)) { fprintf(stderr, "%s%s[%d]: not a number, but %s (%d)%s\n", BOLD_TEXT, func, line, check_name(typ), typ, UNBOLD_TEXT); if (stop_at_error) abort(); } } return(p); } static s7_pointer check_ref8(s7_pointer p, const char *func, int line) { int typ; typ = unchecked_type(p); if ((!t_sequence_p[typ]) && (!t_structure_p[typ])) { fprintf(stderr, "%s%s[%d]: not a sequence, but %s (%d)%s\n", BOLD_TEXT, func, line, check_name(typ), typ, UNBOLD_TEXT); if (stop_at_error) abort(); } return(p); } static s7_pointer check_ref9(s7_pointer p, const char *func, int line) { int typ; typ = unchecked_type(p); if ((typ != T_LET) && (typ != T_C_OBJECT) && (!is_any_closure(p)) && (!is_any_macro(p))) { fprintf(stderr, "%s%s[%d]: not a possible method holder, but %s (%d)%s\n", BOLD_TEXT, func, line, check_name(typ), typ, UNBOLD_TEXT); if (stop_at_error) abort(); } return(p); } static s7_pointer check_nref(s7_pointer p, const char *func, int line) { int typ; typ = unchecked_type(p); if (typ == T_FREE) { fprintf(stderr, "%s%s[%d]: attempt to use cleared type%s\n", BOLD_TEXT, func, line, UNBOLD_TEXT); if (stop_at_error) abort(); } return(p); } static void print_gc_info(s7_pointer obj, int line) { fprintf(stderr, "%s%p is free (line %d), current: %s[%d], previous: %s[%d], gc call: %s[%d], clear: %d, alloc: %s[%d]%s\n", BOLD_TEXT, obj, line, obj->current_alloc_func, obj->current_alloc_line, obj->previous_alloc_func, obj->previous_alloc_line, obj->gc_func, obj->gc_line, obj->clear_line, obj->alloc_func, obj->alloc_line, UNBOLD_TEXT); abort(); } static void show_opt1_bits(s7_scheme *sc, s7_pointer p, const char *func, int line) { fprintf(stderr, "%sopt1 %s[%d]: %p->%p %x%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", BOLD_TEXT, func, line, p, p->object.cons.opt1, p->debugger_bits, ((p->debugger_bits & E_SET) != 0) ? " e-set" : "", ((p->debugger_bits & E_FAST) != 0) ? " fast" : "", ((p->debugger_bits & E_CFUNC) != 0) ? " cfunc" : "", ((p->debugger_bits & E_CLAUSE) != 0) ? " clause" : "", ((p->debugger_bits & E_BACK) != 0) ? " back" : "", ((p->debugger_bits & E_LAMBDA) != 0) ? " lambda" : "", ((p->debugger_bits & E_SYM) != 0) ? " sym" : "", ((p->debugger_bits & E_PAIR) != 0) ? " pair" : "", ((p->debugger_bits & E_CON) != 0) ? " con" : "", ((p->debugger_bits & E_GOTO) != 0) ? " goto" : "", ((p->debugger_bits & E_VECTOR) != 0) ? " vector" : "", ((p->debugger_bits & E_ANY) != 0) ? " any" : "", ((p->debugger_bits & E_SLOT) != 0) ? " slot" : "", ((p->debugger_bits & S_HASH) != 0) ? " raw-hash" : "", UNBOLD_TEXT); } static s7_pointer opt1_1(s7_scheme *sc, s7_pointer p, unsigned int role, const char *func, int line) { if ((!opt1_is_set(p)) || ((!opt1_role_matches(p, role)) && (role != E_ANY))) { show_opt1_bits(sc, p, func, line); if (stop_at_error) abort(); } return(p->object.cons.opt1); } static s7_pointer set_opt1_1(s7_scheme *sc, s7_pointer p, s7_pointer x, unsigned int role, const char *func, int line) { p->object.cons.opt1 = x; set_opt1_role(p, role); set_opt1_is_set(p); return(x); } static unsigned long long int s_hash_1(s7_scheme *sc, s7_pointer p, const char *func, int line) { if ((!opt1_is_set(p)) || (!opt1_role_matches(p, S_HASH))) { show_opt1_bits(sc, p, func, line); if (stop_at_error) abort(); } return(p->object.sym_cons.hash); } static void set_s_hash_1(s7_scheme *sc, s7_pointer p, unsigned long long int x, const char *func, int line) { p->object.sym_cons.hash = x; set_opt1_role(p, S_HASH); set_opt1_is_set(p); } static void show_opt2_bits(s7_scheme *sc, s7_pointer p, const char *func, int line) { fprintf(stderr, "%s%s[%d]: opt2: %p->%p %x%s%s%s%s%s%s%s%s%s%s%s\n", BOLD_TEXT, func, line, p, p->object.cons.opt2, p->debugger_bits, ((p->debugger_bits & F_SET) != 0) ? " f-set" : "", ((p->debugger_bits & F_C_CALL) != 0) ? " c-call" : "", ((p->debugger_bits & F_KEY) != 0) ? " key" : "", ((p->debugger_bits & F_SLOW) != 0) ? " slow" : "", ((p->debugger_bits & F_SYM) != 0) ? " sym" : "", ((p->debugger_bits & F_PAIR) != 0) ? " pair" : "", ((p->debugger_bits & F_CON) != 0) ? " con" : "", ((p->debugger_bits & F_CALL) != 0) ? " call" : "", ((p->debugger_bits & F_LAMBDA) != 0) ? " lambda" : "", ((p->debugger_bits & S_NAME) != 0) ? " raw-name" : "", UNBOLD_TEXT); } static s7_pointer opt2_1(s7_scheme *sc, s7_pointer p, unsigned int role, const char *func, int line) { if ((!opt2_is_set(p)) || (!opt2_role_matches(p, role))) { show_opt2_bits(sc, p, func, line); if (stop_at_error) abort(); } return(p->object.cons.opt2); } static void set_opt2_1(s7_scheme *sc, s7_pointer p, s7_pointer x, unsigned int role, const char *func, int line) { p->object.cons.opt2 = x; set_opt2_role(p, role); set_opt2_is_set(p); } static const char *s_name_1(s7_scheme *sc, s7_pointer p, const char *func, int line) { if ((!opt2_is_set(p)) || (!opt2_role_matches(p, S_NAME))) { show_opt2_bits(sc, p, func, line); if (stop_at_error) abort(); } return(p->object.sym_cons.fstr); } static void set_s_name_1(s7_scheme *sc, s7_pointer p, const char *str, const char *func, int line) { p->object.sym_cons.fstr = str; set_opt2_role(p, S_NAME); set_opt2_is_set(p); } static void show_opt3_bits(s7_scheme *sc, s7_pointer p, const char *func, int line) { fprintf(stderr, "%s%s[%d]: opt3: %x%s%s%s%s%s%s%s%s%s\n", BOLD_TEXT, func, line, p->debugger_bits, ((p->debugger_bits & G_SET) != 0) ? " g-set" : "", ((p->debugger_bits & G_ARGLEN) != 0) ? " arglen" : "", ((p->debugger_bits & G_SYM) != 0) ? " sym" : "", ((p->debugger_bits & G_AND) != 0) ? " and" : "", ((p->debugger_bits & S_LINE) != 0) ? " line" : "", ((p->debugger_bits & S_LEN) != 0) ? " len" : "", ((p->debugger_bits & S_OP) != 0) ? " op" : "", ((p->debugger_bits & S_SYNOP) != 0) ? " syn-op" : "", UNBOLD_TEXT); } static s7_pointer opt3_1(s7_scheme *sc, s7_pointer p, unsigned int role, const char *func, int line) { if ((!opt3_is_set(p)) || (!opt3_role_matches(p, role))) { show_opt3_bits(sc, p, func, line); if (stop_at_error) abort(); } return(p->object.cons.opt3); } static void set_opt3_1(s7_scheme *sc, s7_pointer p, s7_pointer x, unsigned int role, const char *func, int line) { typeflag(p) &= ~(T_OPTIMIZED | T_LINE_NUMBER); p->object.cons.opt3 = x; set_opt3_is_set(p); set_opt3_role(p, role); } /* S_LINE */ static unsigned int s_line_1(s7_scheme *sc, s7_pointer p, const char *func, int line) { if ((!opt3_is_set(p)) || ((p->debugger_bits & S_LINE) == 0) || (!has_line_number(p))) { show_opt3_bits(sc, p, func, line); if (stop_at_error) abort(); } return(p->object.sym_cons.line); } static void set_s_line_1(s7_scheme *sc, s7_pointer p, unsigned int x, const char *func, int line) { p->object.sym_cons.line = x; (p)->debugger_bits = (S_LINE | (p->debugger_bits & ~S_LEN)); /* turn on line, cancel len */ set_opt3_is_set(p); } /* S_LEN (collides with S_LINE) */ static unsigned int s_len_1(s7_scheme *sc, s7_pointer p, const char *func, int line) { if ((!opt3_is_set(p)) || ((p->debugger_bits & S_LEN) == 0) || (has_line_number(p))) { show_opt3_bits(sc, p, func, line); if (stop_at_error) abort(); } return(p->object.sym_cons.line); } static void set_s_len_1(s7_scheme *sc, s7_pointer p, unsigned int x, const char *func, int line) { typeflag(p) &= ~(T_LINE_NUMBER); p->object.sym_cons.line = x; (p)->debugger_bits = (S_LEN | (p->debugger_bits & ~(S_LINE))); set_opt3_is_set(p); } /* S_OP */ static unsigned int s_op_1(s7_scheme *sc, s7_pointer p, const char *func, int line) { if ((!opt3_is_set(p)) || ((p->debugger_bits & S_OP) == 0)) { show_opt3_bits(sc, p, func, line); if (stop_at_error) abort(); } return(p->object.sym_cons.op); } static void set_s_op_1(s7_scheme *sc, s7_pointer p, unsigned int x, const char *func, int line) { p->object.sym_cons.op = x; (p)->debugger_bits = (S_OP | (p->debugger_bits & ~(S_SYNOP))); set_opt3_is_set(p); } /* S_SYNOP (collides with S_OP) */ static unsigned int s_syn_op_1(s7_scheme *sc, s7_pointer p, const char *func, int line) { if ((!opt3_is_set(p)) || ((p->debugger_bits & S_SYNOP) == 0)) { show_opt3_bits(sc, p, func, line); if (stop_at_error) abort(); } return(p->object.sym_cons.op); } static void set_s_syn_op_1(s7_scheme *sc, s7_pointer p, unsigned int x, const char *func, int line) { p->object.sym_cons.op = x; (p)->debugger_bits = (S_SYNOP | (p->debugger_bits & ~(S_OP))); set_opt3_is_set(p); } static void print_debugging_state(s7_scheme *sc, s7_pointer obj, s7_pointer port) { /* show current state, current allocated state, and previous allocated state. */ char *current_bits, *allocated_bits, *previous_bits, *str; int save_typeflag, len, nlen; const char *excl_name; if (is_free(obj)) excl_name = "free cell!"; else excl_name = "unknown object!"; current_bits = describe_type_bits(sc, obj); save_typeflag = typeflag(obj); typeflag(obj) = obj->current_alloc_type; allocated_bits = describe_type_bits(sc, obj); typeflag(obj) = obj->previous_alloc_type; previous_bits = describe_type_bits(sc, obj); typeflag(obj) = save_typeflag; len = safe_strlen(excl_name) + safe_strlen(current_bits) + safe_strlen(allocated_bits) + safe_strlen(previous_bits) + safe_strlen(obj->previous_alloc_func) + safe_strlen(obj->current_alloc_func) + 512; tmpbuf_malloc(str, len); nlen = snprintf(str, len, "\n<%s %s,\n current: %s[%d] %s,\n previous: %s[%d] %s\n hloc: %d (%d uses), free: %s[%d], clear: %d, alloc: %s[%d]>", excl_name, current_bits, obj->current_alloc_func, obj->current_alloc_line, allocated_bits, obj->previous_alloc_func, obj->previous_alloc_line, previous_bits, heap_location(obj), obj->uses, obj->gc_func, obj->gc_line, obj->clear_line, obj->alloc_func, obj->alloc_line); free(current_bits); free(allocated_bits); free(previous_bits); if (is_null(port)) fprintf(stderr, "%p: %s\n", obj, str); else port_write_string(port)(sc, str, nlen, port); tmpbuf_free(str, len); } #endif static void iterator_to_port(s7_scheme *sc, s7_pointer obj, s7_pointer port, use_write_t use_write, shared_info *ci) { if (use_write == USE_READABLE_WRITE) { if (iterator_is_at_end(obj)) port_write_string(port)(sc, "(make-iterator #())", 19, port); else { s7_pointer seq; seq = iterator_sequence(obj); if ((is_string(seq)) && (!is_byte_vector(seq))) { port_write_string(port)(sc, "(make-iterator \"", 16, port); port_write_string(port)(sc, (char *)(string_value(seq) + iterator_position(obj)), string_length(seq) - iterator_position(obj), port); port_write_string(port)(sc, "\")", 2, port); } else { if (iterator_position(obj) > 0) port_write_string(port)(sc, "(let ((iter (make-iterator ", 27, port); else port_write_string(port)(sc, "(make-iterator ", 15, port); object_to_port_with_circle_check(sc, iterator_sequence(obj), port, use_write, ci); if (iterator_position(obj) > 0) { int nlen; char *str; str = (char *)malloc(128 * sizeof(char)); nlen = snprintf(str, 128, "))) (do ((i 0 (+ i 1))) ((= i %lld) iter) (iterate iter)))", iterator_position(obj)); port_write_string(port)(sc, str, nlen, port); free(str); } else port_write_character(port)(sc, ')', port); } } } else { const char *str; str = type_name(sc, iterator_sequence(obj), NO_ARTICLE); port_write_string(port)(sc, "#', port); } } static void baffle_to_port(s7_scheme *sc, s7_pointer obj, s7_pointer port) { int nlen; char buf[64]; nlen = snprintf(buf, 64, "#", baffle_key(obj)); port_write_string(port)(sc, buf, nlen, port); } static void c_pointer_to_port(s7_scheme *sc, s7_pointer obj, s7_pointer port, use_write_t use_write) { int nlen; char buf[64]; if (use_write == USE_READABLE_WRITE) nlen = snprintf(buf, 64, "(c-pointer " INT_FORMAT ")", (ptr_int)raw_pointer(obj)); else nlen = snprintf(buf, 64, "#", raw_pointer(obj)); port_write_string(port)(sc, buf, nlen, port); } static void rng_to_port(s7_scheme *sc, s7_pointer obj, s7_pointer port, use_write_t use_write) { int nlen; char buf[128]; #if WITH_GMP if (use_write == USE_READABLE_WRITE) nlen = snprintf(buf, 128, "#"); else nlen = snprintf(buf, 128, "#", obj); #else if (use_write == USE_READABLE_WRITE) nlen = snprintf(buf, 128, "(random-state %llu %llu)", random_seed(obj), random_carry(obj)); else nlen = snprintf(buf, 128, "#", random_seed(obj), random_carry(obj)); #endif port_write_string(port)(sc, buf, nlen, port); } static void object_to_port(s7_scheme *sc, s7_pointer obj, s7_pointer port, use_write_t use_write, shared_info *ci) { int nlen; char *str; switch (type(obj)) { case T_FLOAT_VECTOR: case T_INT_VECTOR: int_or_float_vector_to_port(sc, obj, port, use_write); break; case T_VECTOR: vector_to_port(sc, obj, port, use_write, ci); break; case T_PAIR: list_to_port(sc, obj, port, use_write, ci); break; case T_HASH_TABLE: hash_table_to_port(sc, obj, port, use_write, ci); break; case T_ITERATOR: iterator_to_port(sc, obj, port, use_write, ci); break; case T_LET: let_to_port(sc, obj, port, use_write, ci); break; case T_UNIQUE: /* if file has # it causes read to return # -> end of read! what is readable version? */ if ((use_write == USE_READABLE_WRITE) && (obj == sc->EOF_OBJECT)) port_write_string(port)(sc, "(begin #)", 14, port); else port_write_string(port)(sc, unique_name(obj), unique_name_length(obj), port); break; case T_BOOLEAN: case T_NIL: case T_UNSPECIFIED: port_write_string(port)(sc, unique_name(obj), unique_name_length(obj), port); break; case T_INPUT_PORT: input_port_to_port(sc, obj, port, use_write); break; case T_OUTPUT_PORT: output_port_to_port(sc, obj, port, use_write); break; case T_COUNTER: port_write_string(port)(sc, "#", 10, port); break; case T_BAFFLE: baffle_to_port(sc, obj, port); break; case T_INTEGER: if (has_print_name(obj)) port_write_string(port)(sc, print_name(obj), print_name_length(obj), port); else { nlen = 0; str = integer_to_string_base_10_no_width(obj, &nlen); if (nlen > 0) { set_print_name(obj, str, nlen); port_write_string(port)(sc, str, nlen, port); } else port_display(port)(sc, str, port); } break; case T_REAL: case T_RATIO: case T_COMPLEX: if (has_print_name(obj)) port_write_string(port)(sc, print_name(obj), print_name_length(obj), port); else { nlen = 0; str = number_to_string_base_10(obj, 0, float_format_precision, 'g', &nlen, use_write); /* was 14 */ set_print_name(obj, str, nlen); port_write_string(port)(sc, str, nlen, port); } break; #if WITH_GMP case T_BIG_INTEGER: case T_BIG_RATIO: case T_BIG_REAL: case T_BIG_COMPLEX: nlen = 0; str = big_number_to_string_with_radix(obj, BASE_10, 0, &nlen, use_write); port_write_string(port)(sc, str, nlen, port); free(str); break; #endif case T_SYMBOL: symbol_to_port(sc, obj, port, use_write); break; case T_SYNTAX: port_display(port)(sc, symbol_name(syntax_symbol(obj)), port); break; case T_STRING: if (is_byte_vector(obj)) byte_vector_to_port(sc, obj, port, use_write); else string_to_port(sc, obj, port, use_write); break; case T_CHARACTER: if (use_write == USE_DISPLAY) port_write_character(port)(sc, character(obj), port); else port_write_string(port)(sc, character_name(obj), character_name_length(obj), port); break; case T_CLOSURE: case T_CLOSURE_STAR: if (has_methods(obj)) { /* look for object->string method else fallback on ordinary case. * can't use recursion on closure_let here because then the fallback name is #. */ s7_pointer print_func; print_func = find_method(sc, closure_let(obj), sc->OBJECT_TO_STRING); if (print_func != sc->UNDEFINED) { s7_pointer p; p = s7_apply_function(sc, print_func, list_1(sc, obj)); if (string_length(p) > 0) port_write_string(port)(sc, string_value(p), string_length(p), port); break; } } if (use_write == USE_READABLE_WRITE) write_closure_readably(sc, obj, port); else write_closure_name(sc, obj, port); break; case T_MACRO: case T_MACRO_STAR: case T_BACRO: case T_BACRO_STAR: if (use_write == USE_READABLE_WRITE) write_macro_readably(sc, obj, port); else write_closure_name(sc, obj, port); break; case T_C_OPT_ARGS_FUNCTION: case T_C_RST_ARGS_FUNCTION: case T_C_ANY_ARGS_FUNCTION: case T_C_FUNCTION: case T_C_FUNCTION_STAR: port_write_string(port)(sc, c_function_name(obj), c_function_name_length(obj), port); break; case T_C_MACRO: port_write_string(port)(sc, c_macro_name(obj), c_macro_name_length(obj), port); break; case T_C_POINTER: c_pointer_to_port(sc, obj, port, use_write); break; case T_RANDOM_STATE: rng_to_port(sc, obj, port, use_write); break; case T_CONTINUATION: if (use_write == USE_READABLE_WRITE) port_write_string(port)(sc, "continuation", 12, port); else port_write_string(port)(sc, "#", 15, port); break; case T_GOTO: if (use_write == USE_READABLE_WRITE) port_write_string(port)(sc, "goto", 4, port); else port_write_string(port)(sc, "#", 7, port); break; case T_CATCH: port_write_string(port)(sc, "#", 8, port); break; case T_DYNAMIC_WIND: /* this can happen because (*s7* 'stack) can involve dynamic-wind markers */ port_write_string(port)(sc, "#", 15, port); break; case T_C_OBJECT: if (use_write == USE_READABLE_WRITE) str = ((*(c_object_print_readably(obj)))(sc, c_object_value(obj))); else str = ((*(c_object_print(obj)))(sc, c_object_value(obj))); port_display(port)(sc, str, port); free(str); break; case T_SLOT: if (use_write != USE_READABLE_WRITE) port_write_character(port)(sc, '\'', port); symbol_to_port(sc, slot_symbol(obj), port, use_write); port_write_character(port)(sc, ' ', port); object_to_port_with_circle_check(sc, slot_value(obj), port, use_write, ci); break; default: #if DEBUGGING print_debugging_state(sc, obj, port); #else { char *str, *tmp; int len; tmp = describe_type_bits(sc, obj); len = 32 + safe_strlen(tmp); tmpbuf_malloc(str, len); if (is_free(obj)) nlen = snprintf(str, len, "", tmp); else nlen = snprintf(str, len, "", tmp); free(tmp); port_write_string(port)(sc, str, nlen, port); tmpbuf_free(str, len); } #endif break; } } static void object_to_port_with_circle_check(s7_scheme *sc, s7_pointer vr, s7_pointer port, use_write_t use_write, shared_info *ci) { if ((ci) && (has_structure(vr))) { int ref; ref = shared_ref(ci, vr); if (ref != 0) { char buf[32]; int nlen; char *p; unsigned int len; if (ref > 0) { if (use_write == USE_READABLE_WRITE) { nlen = snprintf(buf, 32, "(set! {%d} ", ref); port_write_string(port)(sc, buf, nlen, port); object_to_port(sc, vr, port, USE_READABLE_WRITE, ci); port_write_character(port)(sc, ')', port); } else { p = pos_int_to_str((s7_int)ref, &len, '='); *--p = '#'; port_write_string(port)(sc, p, len, port); object_to_port(sc, vr, port, DONT_USE_DISPLAY(use_write), ci); } } else { if (use_write == USE_READABLE_WRITE) { nlen = snprintf(buf, 32, "{%d}", -ref); port_write_string(port)(sc, buf, nlen, port); } else { p = pos_int_to_str((s7_int)(-ref), &len, '#'); *--p = '#'; port_write_string(port)(sc, p, len, port); } } return; } } object_to_port(sc, vr, port, use_write, ci); } static void setup_shared_reads(s7_scheme *sc, s7_pointer port, shared_info *ci) { int i; char buf[64]; port_write_string(port)(sc, "(let (", 6, port); for (i = 1; i <= ci->top; i++) { int len; len = snprintf(buf, 64, "({%d} #f)", i); port_write_string(port)(sc, buf, len, port); } port_write_string(port)(sc, ") ", 2, port); } static void finish_shared_reads(s7_scheme *sc, s7_pointer port, shared_info *ci) { port_write_character(port)(sc, ')', port); } static s7_pointer object_out(s7_scheme *sc, s7_pointer obj, s7_pointer strport, use_write_t choice) { if ((has_structure(obj)) && (obj != sc->rootlet)) { shared_info *ci; ci = make_shared_info(sc, obj, choice != USE_READABLE_WRITE); if (ci) { if (choice == USE_READABLE_WRITE) { setup_shared_reads(sc, strport, ci); object_to_port_with_circle_check(sc, obj, strport, choice, ci); finish_shared_reads(sc, strport, ci); } else object_to_port_with_circle_check(sc, obj, strport, choice, ci); return(obj); } } object_to_port(sc, obj, strport, choice, NULL); return(obj); } static s7_pointer format_ports = NULL; static s7_pointer open_format_port(s7_scheme *sc) { s7_pointer x; int len; if (format_ports) { x = format_ports; format_ports = (s7_pointer)(port_port(x)->next); port_position(x) = 0; port_data(x)[0] = '\0'; return(x); } len = FORMAT_PORT_LENGTH; x = alloc_pointer(); set_type(x, T_OUTPUT_PORT); port_port(x) = (port_t *)calloc(1, sizeof(port_t)); port_type(x) = STRING_PORT; port_is_closed(x) = false; port_data_size(x) = len; port_data(x) = (unsigned char *)malloc(len * sizeof(unsigned char)); /* was +8 */ port_data(x)[0] = '\0'; port_position(x) = 0; port_needs_free(x) = false; port_read_character(x) = output_read_char; port_read_line(x) = output_read_line; port_display(x) = string_display; port_write_character(x) = string_write_char; port_write_string(x) = string_write_string; return(x); } static void close_format_port(s7_scheme *sc, s7_pointer port) { port_port(port)->next = (void *)format_ports; format_ports = port; } static char *s7_object_to_c_string_1(s7_scheme *sc, s7_pointer obj, use_write_t use_write, int *nlen) { char *str; s7_pointer strport; strport = open_format_port(sc); object_out(sc, obj, strport, use_write); if (nlen) (*nlen) = port_position(strport); str = (char *)malloc((port_position(strport) + 1) * sizeof(char)); memcpy((void *)str, (void *)port_data(strport), port_position(strport)); str[port_position(strport)] = '\0'; close_format_port(sc, strport); return(str); } char *s7_object_to_c_string(s7_scheme *sc, s7_pointer obj) { return(s7_object_to_c_string_1(sc, obj, USE_WRITE, NULL)); } s7_pointer s7_object_to_string(s7_scheme *sc, s7_pointer obj, bool use_write) /* unavoidable backwards compatibility rigidity here */ { char *str; int len = 0; str = s7_object_to_c_string_1(sc, obj, (use_write) ? USE_WRITE : USE_DISPLAY, &len); if (str) return(make_string_uncopied_with_length(sc, str, len)); return(s7_make_string_with_length(sc, "", 0)); } /* -------------------------------- newline -------------------------------- */ void s7_newline(s7_scheme *sc, s7_pointer port) { s7_write_char(sc, '\n', port); } static s7_pointer g_newline(s7_scheme *sc, s7_pointer args) { #define H_newline "(newline (port (current-output-port))) writes a carriage return to the port" #define Q_newline s7_make_signature(sc, 2, sc->T, sc->IS_OUTPUT_PORT) s7_pointer port; if (is_not_null(args)) port = car(args); else port = sc->output_port; if (!is_output_port(port)) { if (port == sc->F) return(sc->UNSPECIFIED); method_or_bust_with_type(sc, port, sc->NEWLINE, args, AN_OUTPUT_PORT, 0); } s7_newline(sc, port); return(sc->UNSPECIFIED); } static s7_pointer c_newline(s7_scheme *sc) {s7_newline(sc, sc->output_port); return(sc->UNSPECIFIED);} PF_0(newline, c_newline) /* -------------------------------- write -------------------------------- */ void s7_write(s7_scheme *sc, s7_pointer obj, s7_pointer port) { if (port != sc->F) { if (port_is_closed(port)) s7_wrong_type_arg_error(sc, "write", 2, port, "an open output port"); object_out(sc, obj, port, USE_WRITE); } } static s7_pointer g_write(s7_scheme *sc, s7_pointer args) { #define H_write "(write obj (port (current-output-port))) writes (object->string obj) to the output port" #define Q_write s7_make_signature(sc, 3, sc->T, sc->T, sc->IS_OUTPUT_PORT) s7_pointer port; if (is_pair(cdr(args))) port = cadr(args); else port = sc->output_port; if (!is_output_port(port)) { if (port == sc->F) return(car(args)); method_or_bust_with_type(sc, port, sc->WRITE, args, AN_OUTPUT_PORT, 2); } if (port_is_closed(port)) return(s7_wrong_type_arg_error(sc, "write", 2, port, "an open output port")); return(object_out(sc, car(args), port, USE_WRITE)); } static s7_pointer c_write_i(s7_scheme *sc, s7_int x) {return(g_write(sc, set_plist_1(sc, make_integer(sc, x))));} static s7_pointer c_write_r(s7_scheme *sc, s7_double x) {return(g_write(sc, set_plist_1(sc, make_real(sc, x))));} static s7_pointer c_write_p(s7_scheme *sc, s7_pointer x) {return(g_write(sc, set_plist_1(sc, x)));} XF_TO_PF(write, c_write_i, c_write_r, c_write_p) /* -------------------------------- display -------------------------------- */ void s7_display(s7_scheme *sc, s7_pointer obj, s7_pointer port) { if (port != sc->F) { if (port_is_closed(port)) s7_wrong_type_arg_error(sc, "display", 2, port, "an open output port"); object_out(sc, obj, port, USE_DISPLAY); } } static s7_pointer g_display(s7_scheme *sc, s7_pointer args) { #define H_display "(display obj (port (current-output-port))) prints obj" #define Q_display s7_make_signature(sc, 3, sc->T, sc->T, sc->IS_OUTPUT_PORT) s7_pointer port; if (is_pair(cdr(args))) port = cadr(args); else port = sc->output_port; if (!is_output_port(port)) { if (port == sc->F) return(car(args)); method_or_bust_with_type(sc, port, sc->DISPLAY, args, AN_OUTPUT_PORT, 2); } if (port_is_closed(port)) return(s7_wrong_type_arg_error(sc, "display", 2, port, "an open output port")); return(object_out(sc, car(args), port, USE_DISPLAY)); } static s7_pointer c_display(s7_scheme *sc, s7_pointer x) {return(g_display(sc, set_plist_1(sc, x)));} PF_TO_PF(display, c_display) /* -------------------------------- call-with-output-string -------------------------------- */ static s7_pointer g_call_with_output_string(s7_scheme *sc, s7_pointer args) { #define H_call_with_output_string "(call-with-output-string proc) opens a string port applies proc to it, then returns the collected output" #define Q_call_with_output_string s7_make_signature(sc, 2, sc->IS_STRING, sc->IS_PROCEDURE) s7_pointer port, proc; proc = car(args); if (is_let(proc)) check_method(sc, proc, sc->CALL_WITH_OUTPUT_STRING, args); if (!s7_is_aritable(sc, proc, 1)) method_or_bust_with_type(sc, proc, sc->CALL_WITH_OUTPUT_STRING, args, make_string_wrapper(sc, "a procedure of one argument (the port)"), 1); if ((is_continuation(proc)) || (is_goto(proc))) return(wrong_type_argument_with_type(sc, sc->CALL_WITH_OUTPUT_STRING, 1, proc, A_NORMAL_PROCEDURE)); port = s7_open_output_string(sc); push_stack(sc, OP_GET_OUTPUT_STRING_1, sc->F, port); push_stack(sc, OP_APPLY, list_1(sc, port), proc); return(sc->F); } static s7_pointer c_call_with_output_string(s7_scheme *sc, s7_pointer x) {return(g_call_with_output_string(sc, set_plist_1(sc, x)));} PF_TO_PF(call_with_output_string, c_call_with_output_string) /* -------------------------------- call-with-output-file -------------------------------- */ static s7_pointer g_call_with_output_file(s7_scheme *sc, s7_pointer args) { #define H_call_with_output_file "(call-with-output-file filename proc) opens filename and calls proc with the output port as its argument" #define Q_call_with_output_file pl_sf s7_pointer port, file, proc; file = car(args); if (!is_string(file)) method_or_bust(sc, file, sc->CALL_WITH_OUTPUT_FILE, args, T_STRING, 1); proc = cadr(args); if (!s7_is_aritable(sc, proc, 1)) method_or_bust_with_type(sc, proc, sc->CALL_WITH_OUTPUT_FILE, args, make_string_wrapper(sc, "a procedure of one argument (the port)"), 2); if ((is_continuation(proc)) || is_goto(proc)) return(wrong_type_argument_with_type(sc, sc->CALL_WITH_OUTPUT_FILE, 2, proc, A_NORMAL_PROCEDURE)); port = s7_open_output_file(sc, string_value(file), "w"); push_stack(sc, OP_UNWIND_OUTPUT, sc->F, port); push_stack(sc, OP_APPLY, list_1(sc, port), proc); return(sc->F); } static s7_pointer c_call_with_output_file(s7_scheme *sc, s7_pointer x) {return(g_call_with_output_file(sc, set_plist_1(sc, x)));} PF_TO_PF(call_with_output_file, c_call_with_output_file) /* -------------------------------- with-output-to-string -------------------------------- */ static s7_pointer g_with_output_to_string(s7_scheme *sc, s7_pointer args) { #define H_with_output_to_string "(with-output-to-string thunk) opens a string as a temporary current-output-port, calls thunk, then returns the collected output" #define Q_with_output_to_string s7_make_signature(sc, 2, sc->IS_STRING, sc->IS_PROCEDURE) s7_pointer old_output_port, p; p = car(args); if (!is_thunk(sc, p)) method_or_bust_with_type(sc, p, sc->WITH_OUTPUT_TO_STRING, args, A_THUNK, 1); old_output_port = sc->output_port; sc->output_port = s7_open_output_string(sc); push_stack(sc, OP_GET_OUTPUT_STRING_1, old_output_port, sc->output_port); push_stack(sc, OP_APPLY, sc->NIL, p); return(sc->F); } static s7_pointer c_with_output_to_string(s7_scheme *sc, s7_pointer x) {return(g_with_output_to_string(sc, set_plist_1(sc, x)));} PF_TO_PF(with_output_to_string, c_with_output_to_string) /* (let () (define-macro (mac) (write "123")) (with-output-to-string mac)) * (string-ref (with-output-to-string (lambda () (write "1234") (values (get-output-string) 1)))) */ /* -------------------------------- with-output-to-file -------------------------------- */ static s7_pointer g_with_output_to_file(s7_scheme *sc, s7_pointer args) { #define H_with_output_to_file "(with-output-to-file filename thunk) opens filename as the temporary current-output-port and calls thunk" #define Q_with_output_to_file pl_sf s7_pointer old_output_port, file, proc; file = car(args); if (!is_string(file)) method_or_bust(sc, file, sc->WITH_OUTPUT_TO_FILE, args, T_STRING, 1); proc = cadr(args); if (!is_thunk(sc, proc)) method_or_bust_with_type(sc, proc, sc->WITH_OUTPUT_TO_FILE, args, A_THUNK, 2); old_output_port = sc->output_port; sc->output_port = s7_open_output_file(sc, string_value(file), "w"); push_stack(sc, OP_UNWIND_OUTPUT, old_output_port, sc->output_port); push_stack(sc, OP_APPLY, sc->NIL, proc); return(sc->F); } static s7_pointer c_with_output_to_file(s7_scheme *sc, s7_pointer x) {return(g_with_output_to_file(sc, set_plist_1(sc, x)));} PF_TO_PF(with_output_to_file, c_with_output_to_file) /* -------------------------------- format -------------------------------- */ static s7_pointer format_error_1(s7_scheme *sc, s7_pointer msg, const char *str, s7_pointer args, format_data *fdat) { s7_pointer x = NULL, ctrl_str; static s7_pointer format_string_1 = NULL, format_string_2, format_string_3, format_string_4; if (!format_string_1) { format_string_1 = s7_make_permanent_string("format: ~S ~{~S~^ ~}: ~A"); format_string_2 = s7_make_permanent_string("format: ~S: ~A"); format_string_3 = s7_make_permanent_string("format: ~S ~{~S~^ ~}~&~NT^: ~A"); format_string_4 = s7_make_permanent_string("format: ~S~&~NT^: ~A"); } if (fdat->orig_str) ctrl_str = fdat->orig_str; else ctrl_str = make_string_wrapper(sc, str); if (fdat->loc == 0) { if (is_pair(args)) x = set_elist_4(sc, format_string_1, ctrl_str, args, msg); else x = set_elist_3(sc, format_string_2, ctrl_str, msg); } else { if (is_pair(args)) x = set_elist_5(sc, format_string_3, ctrl_str, args, make_integer(sc, fdat->loc + 20), msg); else x = set_elist_4(sc, format_string_4, ctrl_str, make_integer(sc, fdat->loc + 20), msg); } if (fdat->port) { close_format_port(sc, fdat->port); fdat->port = NULL; } return(s7_error(sc, sc->FORMAT_ERROR, x)); } #define format_error(Sc, Msg, Str, Args, Fdat) \ do {static s7_pointer _Err_ = NULL; if (!_Err_) _Err_ = s7_make_permanent_string(Msg); return(format_error_1(Sc, _Err_, Str, Args, Fdat));} while (0) #define just_format_error(Sc, Msg, Str, Args, Fdat) \ do {static s7_pointer _Err_ = NULL; if (!_Err_) _Err_ = s7_make_permanent_string(Msg); format_error_1(Sc, _Err_, Str, Args, Fdat);} while (0) static void format_append_char(s7_scheme *sc, format_data *fdat, char c, s7_pointer port) { port_write_character(port)(sc, c, port); sc->format_column++; /* if c is #\null, is this the right thing to do? * We used to return "1 2 3 4" because ~C was first turned into a string (empty in this case) * (format #f "1 2~C3 4" #\null) * "1 2" * Clisp does this: * (format nil "1 2~C3 4" (int-char 0)) * "1 23 4" * whereas sbcl says int-char is undefined, and * Guile returns "1 2\x003 4" */ } static void format_append_newline(s7_scheme *sc, format_data *fdat, s7_pointer port) { port_write_character(port)(sc, '\n', port); sc->format_column = 0; } static void format_append_string(s7_scheme *sc, format_data *fdat, const char *str, int len, s7_pointer port) { port_write_string(port)(sc, str, len, port); fdat->loc += len; sc->format_column += len; } static void format_append_chars(s7_scheme *sc, format_data *fdat, char pad, int chars, s7_pointer port) { int j; if (chars > 0) { if (chars < TMPBUF_SIZE) { for (j = 0; j < chars; j++) sc->tmpbuf[j] = pad; sc->tmpbuf[chars] = '\0'; format_append_string(sc, fdat, sc->tmpbuf, chars, port); } else { for (j = 0; j < chars; j++) format_append_char(sc, fdat, pad, port); } } } static int format_read_integer(s7_scheme *sc, int *cur_i, int str_len, const char *str, s7_pointer args, format_data *fdat) { /* we know that str[*cur_i] is a digit */ int i, lval = 0; for (i = *cur_i; i < str_len - 1; i++) { int dig; dig = digits[(unsigned char)str[i]]; if (dig < 10) { #if HAVE_OVERFLOW_CHECKS if ((int_multiply_overflow(lval, 10, &lval)) || (int_add_overflow(lval, dig, &lval))) break; #else lval = dig + (lval * 10); #endif } else break; } if (i >= str_len) just_format_error(sc, "numeric argument, but no directive!", str, args, fdat); *cur_i = i; return(lval); } static void format_number(s7_scheme *sc, format_data *fdat, int radix, int width, int precision, char float_choice, char pad, s7_pointer port) { char *tmp; int nlen = 0; if (width < 0) width = 0; /* precision choice depends on float_choice if it's -1 */ if (precision < 0) { if ((float_choice == 'e') || (float_choice == 'f') || (float_choice == 'g')) precision = 6; else { /* in the "int" cases, precision depends on the arg type */ switch (type(car(fdat->args))) { case T_INTEGER: case T_RATIO: precision = 0; break; default: precision = 6; break; } } } /* should (format #f "~F" 1/3) return "1/3"?? in CL it's "0.33333334" */ tmp = number_to_string_with_radix(sc, car(fdat->args), radix, width, precision, float_choice, &nlen); if (pad != ' ') { char *padtmp; padtmp = tmp; while (*padtmp == ' ') (*(padtmp++)) = pad; } format_append_string(sc, fdat, tmp, nlen, port); free(tmp); fdat->args = cdr(fdat->args); fdat->ctr++; } static int format_nesting(const char *str, char opener, char closer, int start, int end) /* start=i, end=str_len-1 */ { int k, nesting = 1; for (k = start + 2; k < end; k++) if (str[k] == '~') { if (str[k + 1] == closer) { nesting--; if (nesting == 0) return(k - start - 1); } else { if (str[k + 1] == opener) nesting++; } } return(-1); } static bool format_method(s7_scheme *sc, const char *str, format_data *fdat, s7_pointer port) { s7_pointer obj, func; obj = car(fdat->args); if ((has_methods(obj)) && ((func = find_method(sc, find_let(sc, obj), sc->FORMAT)) != sc->UNDEFINED)) { s7_pointer ctrl_str; if (fdat->orig_str) ctrl_str = fdat->orig_str; else ctrl_str = make_string_wrapper(sc, str); obj = s7_apply_function(sc, func, cons(sc, ctrl_str, fdat->args)); if (is_string(obj)) { format_append_string(sc, fdat, string_value(obj), string_length(obj), port); fdat->args = cdr(fdat->args); fdat->ctr++; return(true); } } return(false); } static int format_numeric_arg(s7_scheme *sc, const char *str, int str_len, format_data *fdat, s7_pointer args, int *i) { #define MAX_FORMAT_WIDTH 10000 int width; if ((str[*i] == 'n') || (str[*i] == 'N')) { *i = *i + 1; if (is_null(fdat->args)) /* (format #f "~nT") */ just_format_error(sc, "~~N: missing argument", str, args, fdat); if (!s7_is_integer(car(fdat->args))) just_format_error(sc, "~~N: integer argument required", str, args, fdat); width = (int)s7_integer(car(fdat->args)); fdat->args = cdr(fdat->args); /* I don't think fdat->ctr should be incremented here -- it's for *vector-print-length* etc */ } else width = format_read_integer(sc, i, str_len, str, args, fdat); if ((width < 0) || /* maybe overflow somewhere? */ (width > MAX_FORMAT_WIDTH)) just_format_error(sc, "width argument too big", str, args, fdat); return(width); } #if WITH_GMP static bool s7_is_one_or_big_one(s7_pointer p); #else #define s7_is_one_or_big_one(Num) s7_is_one(Num) #endif static s7_pointer object_to_list(s7_scheme *sc, s7_pointer obj); static s7_pointer format_to_port_1(s7_scheme *sc, s7_pointer port, const char *str, s7_pointer args, s7_pointer *next_arg, bool with_result, bool columnized, int len, s7_pointer orig_str) { int i, str_len; format_data *fdat; s7_pointer deferred_port; if ((!with_result) && (port == sc->F)) return(sc->F); if (len <= 0) { str_len = safe_strlen(str); if (str_len == 0) { if (is_not_null(args)) { static s7_pointer null_err = NULL; if (!null_err) null_err = s7_make_permanent_string("format control string is null, but there are arguments: ~S"); return(s7_error(sc, sc->FORMAT_ERROR, set_elist_2(sc, null_err, args))); } if (with_result) return(make_string_wrapper_with_length(sc, "", 0)); return(sc->F); } } else str_len = len; sc->format_depth++; if (sc->format_depth >= sc->num_fdats) { int k, new_num_fdats; new_num_fdats = sc->format_depth * 2; sc->fdats = (format_data **)realloc(sc->fdats, sizeof(format_data *) * new_num_fdats); for (k = sc->num_fdats; k < new_num_fdats; k++) sc->fdats[k] = NULL; sc->num_fdats = new_num_fdats; } fdat = sc->fdats[sc->format_depth]; if (!fdat) { fdat = (format_data *)malloc(sizeof(format_data)); sc->fdats[sc->format_depth] = fdat; fdat->curly_len = 0; fdat->curly_str = NULL; fdat->ctr = 0; } else { if (fdat->port) close_format_port(sc, fdat->port); if (fdat->strport) close_format_port(sc, fdat->strport); } fdat->port = NULL; fdat->strport = NULL; fdat->loc = 0; fdat->args = args; fdat->orig_str = orig_str; fdat->curly_arg = sc->NIL; /* choose whether to write to a temporary string port, or simply use the in-coming port * if with_result, returned string is wanted. * if port is sc->F, no non-string result is wanted. * if port is not boolean, it better be a port. * if we are about to goto START in eval, and main_stack_op(Sc) == OP_BEGIN1, no return string is wanted -- yow, this is not true */ if (with_result) { deferred_port = port; port = open_format_port(sc); fdat->port = port; } else deferred_port = sc->F; for (i = 0; i < str_len - 1; i++) { if ((unsigned char)(str[i]) == (unsigned char)'~') /* what does MS C want? */ { use_write_t use_write; switch (str[i + 1]) { case '%': /* -------- newline -------- */ /* sbcl apparently accepts numeric args here (including 0) */ if ((port_data(port)) && (port_position(port) < port_data_size(port))) { port_data(port)[port_position(port)++] = '\n'; /* which is actually a bad idea, but as a desperate stopgap, I simply padded * the string port string with 8 chars that are not in the length. */ sc->format_column = 0; } else format_append_newline(sc, fdat, port); i++; break; case '&': /* -------- conditional newline -------- */ if (sc->format_column > 0) format_append_newline(sc, fdat, port); i++; break; case '~': /* -------- tilde -------- */ format_append_char(sc, fdat, '~', port); i++; break; case '\n': /* -------- trim white-space -------- */ for (i = i + 2; i args)) /* (format #f "~*~A") */ format_error(sc, "can't skip argument!", str, args, fdat); fdat->args = cdr(fdat->args); break; case '|': /* -------- exit if args nil or ctr > *vector-print-length* -------- */ if ((is_pair(fdat->args)) && (fdat->ctr >= sc->print_length)) { format_append_string(sc, fdat, " ...", 4, port); fdat->args = sc->NIL; } /* fall through */ case '^': /* -------- exit -------- */ if (is_null(fdat->args)) { i = str_len; goto ALL_DONE; } i++; break; case '@': /* -------- plural, 'y' or 'ies' -------- */ i += 2; if ((str[i] != 'P') && (str[i] != 'p')) format_error(sc, "unknown '@' directive", str, args, fdat); if (!s7_is_real(car(fdat->args))) /* CL accepts non numbers here */ format_error(sc, "'@P' directive argument is not a real number", str, args, fdat); if (!s7_is_one_or_big_one(car(fdat->args))) format_append_string(sc, fdat, "ies", 3, port); else format_append_char(sc, fdat, 'y', port); fdat->args = cdr(fdat->args); break; case 'P': case 'p': /* -------- plural in 's' -------- */ if (!s7_is_real(car(fdat->args))) format_error(sc, "'P' directive argument is not a real number", str, args, fdat); if (!s7_is_one_or_big_one(car(fdat->args))) format_append_char(sc, fdat, 's', port); i++; fdat->args = cdr(fdat->args); break; case '{': /* -------- iteration -------- */ { int curly_len; if (is_null(fdat->args)) format_error(sc, "missing argument", str, args, fdat); curly_len = format_nesting(str, '{', '}', i, str_len - 1); if (curly_len == -1) format_error(sc, "'{' directive, but no matching '}'", str, args, fdat); if (curly_len == 1) format_error(sc, "~{~}' doesn't consume any arguments!", str, args, fdat); /* what about cons's here? I can't see any way in CL either to specify the car or cdr of a cons within the format string * (cons 1 2) is applicable: ((cons 1 2) 0) -> 1 * also there can be applicable objects that won't work in the map context (arg not integer etc) */ if (is_not_null(car(fdat->args))) /* (format #f "~{~A ~}" ()) -> "" */ { s7_pointer curly_arg; curly_arg = object_to_list(sc, car(fdat->args)); /* if a pair, this simply returns the original */ if (is_not_null(curly_arg)) /* (format #f "~{~A ~}" #()) -> "" */ { char *curly_str = NULL; /* this is the local (nested) format control string */ s7_pointer orig_arg; if (!is_proper_list(sc, curly_arg)) format_error(sc, "'{' directive argument should be a proper list or something we can turn into a list", str, args, fdat); fdat->curly_arg = curly_arg; if (curly_arg != car(fdat->args)) orig_arg = curly_arg; else orig_arg = sc->NIL; if (curly_len > fdat->curly_len) { if (fdat->curly_str) free (fdat->curly_str); fdat->curly_len = curly_len; fdat->curly_str = (char *)malloc(curly_len * sizeof(char)); } curly_str = fdat->curly_str; memcpy((void *)curly_str, (void *)(str + i + 2), curly_len - 1); curly_str[curly_len - 1] = '\0'; if ((sc->format_depth < sc->num_fdats - 1) && (sc->fdats[sc->format_depth + 1])) sc->fdats[sc->format_depth + 1]->ctr = 0; /* it's not easy to use an iterator here instead of a list (so object->list isn't needed above), * because the curly brackets may enclose multiple arguments -- we would need to use * iterators throughout this function. */ while (is_not_null(curly_arg)) { s7_pointer new_arg = sc->NIL; format_to_port_1(sc, port, curly_str, curly_arg, &new_arg, false, columnized, curly_len - 1, NULL); if (curly_arg == new_arg) { fdat->curly_arg = sc->NIL; format_error(sc, "'{...}' doesn't consume any arguments!", str, args, fdat); } curly_arg = new_arg; } fdat->curly_arg = sc->NIL; while (is_pair(orig_arg)) { s7_pointer p; p = orig_arg; orig_arg = cdr(orig_arg); free_cell(sc, p); /* if car(fdar->args) is a hash-table, we could also free_cell(car(p)), but not in any other case */ } } } i += (curly_len + 2); /* jump past the ending '}' too */ fdat->args = cdr(fdat->args); fdat->ctr++; } break; case '}': format_error(sc, "unmatched '}'", str, args, fdat); case 'W': case 'w': use_write = USE_READABLE_WRITE; goto OBJSTR; case 'S': case 's': use_write = USE_WRITE; goto OBJSTR; case 'A': case 'a': use_write = USE_DISPLAY; OBJSTR: /* object->string */ { s7_pointer obj, strport; if (is_null(fdat->args)) format_error(sc, "missing argument", str, args, fdat); i++; obj = car(fdat->args); /* for the column check, we need to know the length of the object->string output */ if (columnized) { strport = open_format_port(sc); fdat->strport = strport; } else strport = port; object_out(sc, obj, strport, use_write); if (columnized) { if (port_position(strport) >= port_data_size(strport)) resize_port_data(strport, port_data_size(strport) * 2); port_data(strport)[port_position(strport)] = '\0'; if (port_position(strport) > 0) format_append_string(sc, fdat, (const char *)port_data(strport), port_position(strport), port); close_format_port(sc, strport); fdat->strport = NULL; } fdat->args = cdr(fdat->args); fdat->ctr++; } break; /* -------- numeric args -------- */ case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case ',': case 'N': case 'n': case 'B': case 'b': case 'D': case 'd': case 'E': case 'e': case 'F': case 'f': case 'G': case 'g': case 'O': case 'o': case 'X': case 'x': case 'T': case 't': case 'C': case 'c': { int width = -1, precision = -1; char pad = ' '; i++; /* str[i] == '~' */ if ((isdigit((int)(str[i]))) || (str[i] == 'N') || (str[i] == 'n')) /* this is faster than the equivalent strchr */ width = format_numeric_arg(sc, str, str_len, fdat, args, &i); if (str[i] == ',') { i++; /* is (format #f "~12,12D" 1) an error? The precision has no use here. */ if ((isdigit((int)(str[i]))) || (str[i] == 'N') || (str[i] == 'n')) precision = format_numeric_arg(sc, str, str_len, fdat, args, &i); else { if (str[i] == '\'') /* (format #f "~12,'xD" 1) -> "xxxxxxxxxxx1" */ { pad = str[i + 1]; i += 2; if (i >= str_len) /* (format #f "~,'") */ format_error(sc, "incomplete numeric argument", str, args, fdat); } /* is (let ((str "~12,'xD")) (set! (str 5) #\null) (format #f str 1)) an error? */ } } switch (str[i]) { /* -------- pad to column -------- * are columns numbered from 1 or 0? there seems to be disagreement about this directive * does "space over to" mean including? */ case 'T': case 't': if (width == -1) width = 0; if (precision == -1) precision = 0; if ((width > 0) || (precision > 0)) /* (format #f "a~8Tb") */ { /* (length (substring (format #f "~%~10T.") 1)) == (length (format #f "~10T.")) * (length (substring (format #f "~%-~10T.~%") 1)) == (length (format #f "-~10T.~%")) */ if (precision > 0) { int mult; mult = (int)(ceil((s7_double)(sc->format_column + 1 - width) / (s7_double)precision)); /* CLtL2 ("least positive int") */ if (mult < 1) mult = 1; width += (precision * mult); } format_append_chars(sc, fdat, pad, width - sc->format_column - 1, port); } break; case 'C': case 'c': { s7_pointer obj; if (is_null(fdat->args)) format_error(sc, "~~C: missing argument", str, args, fdat); /* the "~~" here and below protects against "~C" being treated as a directive */ /* i++; */ obj = car(fdat->args); if (!s7_is_character(obj)) { if (!format_method(sc, str, fdat, port)) format_error(sc, "'C' directive requires a character argument", str, args, fdat); } else { /* here use_write is false, so we just add the char, not its name */ if (width == -1) format_append_char(sc, fdat, character(obj), port); else format_append_chars(sc, fdat, character(obj), width, port); fdat->args = cdr(fdat->args); fdat->ctr++; } } break; /* -------- numbers -------- */ case 'F': case 'f': if (is_null(fdat->args)) format_error(sc, "~~F: missing argument", str, args, fdat); if (!(s7_is_number(car(fdat->args)))) { if (!format_method(sc, str, fdat, port)) format_error(sc, "~~F: numeric argument required", str, args, fdat); } else format_number(sc, fdat, 10, width, precision, 'f', pad, port); break; case 'G': case 'g': if (is_null(fdat->args)) format_error(sc, "~~G: missing argument", str, args, fdat); if (!(s7_is_number(car(fdat->args)))) { if (!format_method(sc, str, fdat, port)) format_error(sc, "~~G: numeric argument required", str, args, fdat); } else format_number(sc, fdat, 10, width, precision, 'g', pad, port); break; case 'E': case 'e': if (is_null(fdat->args)) format_error(sc, "~~E: missing argument", str, args, fdat); if (!(s7_is_number(car(fdat->args)))) { if (!format_method(sc, str, fdat, port)) format_error(sc, "~~E: numeric argument required", str, args, fdat); } else format_number(sc, fdat, 10, width, precision, 'e', pad, port); break; /* how to handle non-integer arguments in the next 4 cases? clisp just returns * the argument: (format nil "~X" 1.25) -> "1.25" which is perverse (ClTl2 p 581: * "if arg is not an integer, it is printed in ~A format and decimal base")!! * I think I'll use the type of the number to choose the output format. */ case 'D': case 'd': if (is_null(fdat->args)) format_error(sc, "~~D: missing argument", str, args, fdat); if (!(s7_is_number(car(fdat->args)))) { /* (let () (require mockery.scm) (format #f "~D" ((*mock-number* 'mock-number) 123))) * port here is a string-port, str has the width/precision data if the caller wants it, * args is the current arg. But format_number handles fdat->args and so on, so * I think I'll pass the format method the current control string (str), the * current object (car(fdat->args)), and the arglist (args), and assume it will * return a (scheme) string. */ if (!format_method(sc, str, fdat, port)) format_error(sc, "~~D: numeric argument required", str, args, fdat); } else format_number(sc, fdat, 10, width, precision, 'd', pad, port); break; case 'O': case 'o': if (is_null(fdat->args)) format_error(sc, "~~O: missing argument", str, args, fdat); if (!(s7_is_number(car(fdat->args)))) { if (!format_method(sc, str, fdat, port)) format_error(sc, "~~O: numeric argument required", str, args, fdat); } else format_number(sc, fdat, 8, width, precision, 'o', pad, port); break; case 'X': case 'x': if (is_null(fdat->args)) format_error(sc, "~~X: missing argument", str, args, fdat); if (!(s7_is_number(car(fdat->args)))) { if (!format_method(sc, str, fdat, port)) format_error(sc, "~~X: numeric argument required", str, args, fdat); } else format_number(sc, fdat, 16, width, precision, 'x', pad, port); break; case 'B': case 'b': if (is_null(fdat->args)) format_error(sc, "~~B: missing argument", str, args, fdat); if (!(s7_is_number(car(fdat->args)))) { if (!format_method(sc, str, fdat, port)) format_error(sc, "~~B: numeric argument required", str, args, fdat); } else format_number(sc, fdat, 2, width, precision, 'b', pad, port); break; default: if (width > 0) format_error(sc, "unused numeric argument", str, args, fdat); format_error(sc, "unimplemented format directive", str, args, fdat); } } break; default: format_error(sc, "unimplemented format directive", str, args, fdat); } } else /* str[i] is not #\~ */ { int j, new_len; const char *p; p = (char *)strchr((const char *)(str + i + 1), (int)'~'); if (!p) j = str_len; else j = (int)(p - str); new_len = j - i; if ((port_data(port)) && ((port_position(port) + new_len) < port_data_size(port))) { memcpy((void *)(port_data(port) + port_position(port)), (void *)(str + i), new_len); port_position(port) += new_len; } else port_write_string(port)(sc, (char *)(str + i), new_len, port); fdat->loc += new_len; sc->format_column += new_len; i = j - 1; } } ALL_DONE: if (next_arg) (*next_arg) = fdat->args; else { if (is_not_null(fdat->args)) format_error(sc, "too many arguments", str, args, fdat); } if (i < str_len) { if (str[i] == '~') format_error(sc, "control string ends in tilde", str, args, fdat); format_append_char(sc, fdat, str[i], port); } sc->format_depth--; if (with_result) { s7_pointer result; if ((is_output_port(deferred_port)) && (port_position(port) > 0)) { port_data(port)[port_position(port)] = '\0'; port_write_string(deferred_port)(sc, (const char *)port_data(port), port_position(port), deferred_port); } result = s7_make_string_with_length(sc, (char *)port_data(port), port_position(port)); close_format_port(sc, port); fdat->port = NULL; return(result); } return(sc->F); } static bool is_columnizing(const char *str) { /* look for ~t ~,T ~,t */ char *p; for (p = (char *)str; (*p);) if (*p++ == '~') /* this is faster than strchr */ { char c; c = *p++; if ((c == 't') || (c == 'T')) return(true); if (!c) return(false); if ((c == ',') || ((c >= '0') && (c <= '9')) || (c == 'n') || (c == 'N')) { while (((c >= '0') && (c <= '9')) || (c == 'n') || (c == 'N')) c = *p++; if ((c == 't') || (c == 'T')) return(true); if (!c) return(false); /* ~,1 for example */ if (c == ',') { c = *p++; while (((c >= '0') && (c <= '9')) || (c == 'n') || (c == 'N')) c = *p++; if ((c == 't') || (c == 'T')) return(true); if (!c) return(false); } } } return(false); } static s7_pointer format_to_port(s7_scheme *sc, s7_pointer port, const char *str, s7_pointer args, s7_pointer *next_arg, bool with_result, int len) { return(format_to_port_1(sc, port, str, args, next_arg, with_result, true /* is_columnizing(str) */, len, NULL)); /* is_columnizing on every call is much slower than ignoring the issue */ } static s7_pointer g_format_1(s7_scheme *sc, s7_pointer args) { s7_pointer pt, str; sc->format_column = 0; pt = car(args); if (is_string(pt)) return(format_to_port_1(sc, sc->F, string_value(pt), cdr(args), NULL, true, true, string_length(pt), pt)); if (is_null(pt)) pt = sc->output_port; /* () -> (current-output-port) */ if (!((s7_is_boolean(pt)) || /* #f or #t */ ((is_output_port(pt)) && /* (current-output-port) or call-with-open-file arg, etc */ (!port_is_closed(pt))))) method_or_bust_with_type(sc, pt, sc->FORMAT, args, AN_OUTPUT_PORT, 1); str = cadr(args); if (!is_string(str)) method_or_bust(sc, str, sc->FORMAT, args, T_STRING, 2); return(format_to_port_1(sc, (pt == sc->T) ? sc->output_port : pt, string_value(str), cddr(args), NULL, !is_output_port(pt), true, string_length(str), str)); } static s7_pointer g_format(s7_scheme *sc, s7_pointer args) { #define H_format "(format out str . args) substitutes args into str sending the result to out. Most of \ s7's format directives are taken from CL: ~% = newline, ~& = newline if the preceding output character was \ no a newline, ~~ = ~, ~ trims white space, ~* skips an argument, ~^ exits {} iteration if the arg list is exhausted, \ ~nT spaces over to column n, ~A prints a representation of any object, ~S is the same, but puts strings in double quotes, \ ~C prints a character, numbers are handled by ~F, ~E, ~G, ~B, ~O, ~D, and ~X with preceding numbers giving \ spacing (and spacing character) and precision. ~{ starts an embedded format directive which is ended by ~}: \n\ \n\ >(format #f \"dashed: ~{~A~^-~}\" '(1 2 3))\n\ \"dashed: 1-2-3\"\n\ \n\ ~P inserts \"s\" if the current it is not 1 or 1.0 (use ~@P for \"ies\" or \"y\").\n\ ~B is number->string in base 2, ~O in base 8, ~D base 10, ~X base 16,\n\ ~E: (format #f \"~E\" 100.1) -> \"1.001000e+02\" (%e in C)\n\ ~F: (format #f \"~F\" 100.1) -> \"100.100000\" (%f in C)\n\ ~G: (format #f \"~G\" 100.1) -> \"100.1\" (%g in C)\n\ \n\ If the 'out' it is not an output port, the resultant string is returned. If it \ is #t, the string is also sent to the current-output-port." #define Q_format s7_make_circular_signature(sc, 1, 2, s7_make_signature(sc, 2, sc->IS_STRING, sc->IS_BOOLEAN), sc->T) return(g_format_1(sc, args)); } const char *s7_format(s7_scheme *sc, s7_pointer args) { s7_pointer result; result = g_format_1(sc, args); if (is_string(result)) return(string_value(result)); return(NULL); } /* -------------------------------- system extras -------------------------------- */ #if WITH_SYSTEM_EXTRAS #include static s7_pointer g_is_directory(s7_scheme *sc, s7_pointer args) { #define H_is_directory "(directory? str) returns #t if str is the name of a directory" #define Q_is_directory s7_make_signature(sc, 2, sc->IS_BOOLEAN, sc->IS_STRING) s7_pointer name; name = car(args); if (!is_string(name)) method_or_bust(sc, name, sc->IS_DIRECTORY, args, T_STRING, 0); return(s7_make_boolean(sc, is_directory(string_value(name)))); } static bool file_probe(const char *arg) { #if (!MS_WINDOWS) return(access(arg, F_OK) == 0); #else int fd; fd = open(arg, O_RDONLY, 0); if (fd == -1) return(false); close(fd); return(true); #endif } static s7_pointer g_file_exists(s7_scheme *sc, s7_pointer args) { #define H_file_exists "(file-exists? filename) returns #t if the file exists" #define Q_file_exists s7_make_signature(sc, 2, sc->IS_BOOLEAN, sc->IS_STRING) s7_pointer name; name = car(args); if (!is_string(name)) method_or_bust(sc, name, sc->FILE_EXISTS, args, T_STRING, 0); return(s7_make_boolean(sc, file_probe(string_value(name)))); } static s7_pointer g_delete_file(s7_scheme *sc, s7_pointer args) { #define H_delete_file "(delete-file filename) deletes the file filename." #define Q_delete_file s7_make_signature(sc, 2, sc->IS_INTEGER, sc->IS_STRING) s7_pointer name; name = car(args); if (!is_string(name)) method_or_bust(sc, name, sc->DELETE_FILE, args, T_STRING, 0); return(make_integer(sc, unlink(string_value(name)))); } static s7_pointer g_getenv(s7_scheme *sc, s7_pointer args) { #define H_getenv "(getenv var) returns the value of an environment variable." #define Q_getenv pcl_s s7_pointer name; name = car(args); if (!is_string(name)) method_or_bust(sc, name, sc->GETENV, args, T_STRING, 0); return(s7_make_string(sc, getenv(string_value(name)))); } static s7_pointer g_system(s7_scheme *sc, s7_pointer args) { #define H_system "(system command) executes the command. If the optional second it is #t, \ system captures the output as a string and returns it." #define Q_system s7_make_signature(sc, 3, sc->T, sc->IS_STRING, sc->IS_BOOLEAN) s7_pointer name; name = car(args); if (!is_string(name)) method_or_bust(sc, name, sc->SYSTEM, args, T_STRING, 0); if ((is_pair(cdr(args))) && (cadr(args) == sc->T)) { #define BUF_SIZE 256 char buf[BUF_SIZE]; char *str = NULL; int cur_len = 0, full_len = 0; FILE *fd; s7_pointer res; fd = popen(string_value(name), "r"); while (fgets(buf, BUF_SIZE, fd)) { int buf_len; buf_len = safe_strlen(buf); if (cur_len + buf_len >= full_len) { full_len += BUF_SIZE * 2; if (str) str = (char *)realloc(str, full_len * sizeof(char)); else str = (char *)malloc(full_len * sizeof(char)); } memcpy((void *)(str + cur_len), (void *)buf, buf_len); cur_len += buf_len; } pclose(fd); res = s7_make_string_with_length(sc, str, cur_len); if (str) free(str); return(res); } return(make_integer(sc, system(string_value(name)))); } #ifndef _MSC_VER #include static s7_pointer c_directory_to_list(s7_scheme *sc, s7_pointer name) { DIR *dpos; s7_pointer result; if (!is_string(name)) method_or_bust(sc, name, sc->DIRECTORY_TO_LIST, list_1(sc, name), T_STRING, 0); sc->w = sc->NIL; if ((dpos = opendir(string_value(name))) != NULL) { struct dirent *dirp; while ((dirp = readdir(dpos)) != NULL) sc->w = cons(sc, s7_make_string(sc, dirp->d_name), sc->w); closedir(dpos); } result = sc->w; sc->w = sc->NIL; return(result); } static s7_pointer g_directory_to_list(s7_scheme *sc, s7_pointer args) { #define H_directory_to_list "(directory->list directory) returns the contents of the directory as a list of strings (filenames)." #define Q_directory_to_list s7_make_signature(sc, 2, sc->IS_PAIR, sc->IS_STRING) return(c_directory_to_list(sc, car(args))); } PF_TO_PF(directory_to_list, c_directory_to_list) static s7_pointer g_file_mtime(s7_scheme *sc, s7_pointer args) { #define H_file_mtime "(file-mtime file): return the write date of file" #define Q_file_mtime s7_make_signature(sc, 2, sc->IS_INTEGER, sc->IS_STRING) struct stat statbuf; int err; s7_pointer name; name = car(args); if (!is_string(name)) method_or_bust(sc, name, sc->FILE_MTIME, args, T_STRING, 0); err = stat(string_value(name), &statbuf); if (err < 0) return(file_error(sc, "file-mtime", strerror(errno), string_value(name))); return(s7_make_integer(sc, (s7_int)(statbuf.st_mtime))); } #endif #endif /* -------------------------------- lists -------------------------------- */ s7_pointer s7_cons(s7_scheme *sc, s7_pointer a, s7_pointer b) { s7_pointer x; new_cell(sc, x, T_PAIR | T_SAFE_PROCEDURE); car(x) = a; cdr(x) = b; return(x); } static s7_pointer cons_unchecked(s7_scheme *sc, s7_pointer a, s7_pointer b) { /* apparently slightly faster as a function? */ s7_pointer x; new_cell_no_check(sc, x, T_PAIR | T_SAFE_PROCEDURE); car(x) = a; cdr(x) = b; return(x); } static s7_pointer permanent_cons(s7_pointer a, s7_pointer b, unsigned int type) { /* for the symbol table which is never GC'd (and its contents aren't marked) */ s7_pointer x; x = alloc_pointer(); set_type(x, type); unheap(x); car(x) = a; cdr(x) = b; return(x); } static s7_pointer permanent_list(s7_scheme *sc, int len) { int j; s7_pointer p; p = sc->NIL; for (j = 0; j < len; j++) p = permanent_cons(sc->NIL, p, T_PAIR | T_IMMUTABLE); return(p); } #if DEBUGGING static int sigs = 0, sig_pairs = 0; #endif s7_pointer s7_make_signature(s7_scheme *sc, int len, ...) { va_list ap; s7_pointer p, res; #if DEBUGGING sigs++; sig_pairs += len; #endif res = permanent_list(sc, len); va_start(ap, len); for (p = res; is_pair(p); p = cdr(p)) { car(p) = va_arg(ap, s7_pointer); #if DEBUGGING if (!car(p)) { fprintf(stderr, "missed type check in procedure-signature\n"); abort(); } #endif } va_end(ap); return((s7_pointer)res); } s7_pointer s7_make_circular_signature(s7_scheme *sc, int cycle_point, int len, ...) { va_list ap; int i; s7_pointer p, res, back = NULL, end = NULL; #if DEBUGGING sigs++; sig_pairs += len; #endif res = permanent_list(sc, len); va_start(ap, len); for (p = res, i = 0; is_pair(p); p = cdr(p), i++) { car(p) = va_arg(ap, s7_pointer); if (i == cycle_point) back = p; if (i == (len - 1)) end = p; #if DEBUGGING if (!car(p)) { fprintf(stderr, "missed type check in (circular) procedure-signature\n"); abort(); } #endif } va_end(ap); cdr(end) = back; return((s7_pointer)res); } bool s7_is_pair(s7_pointer p) { return(is_pair(p)); } s7_pointer s7_car(s7_pointer p) {return(car(p));} s7_pointer s7_cdr(s7_pointer p) {return(cdr(p));} s7_pointer s7_cadr(s7_pointer p) {return(cadr(p));} s7_pointer s7_cddr(s7_pointer p) {return(cddr(p));} s7_pointer s7_cdar(s7_pointer p) {return(cdar(p));} s7_pointer s7_caar(s7_pointer p) {return(caar(p));} s7_pointer s7_caadr(s7_pointer p) {return(caadr(p));} s7_pointer s7_caddr(s7_pointer p) {return(caddr(p));} s7_pointer s7_cadar(s7_pointer p) {return(cadar(p));} s7_pointer s7_caaar(s7_pointer p) {return(caaar(p));} s7_pointer s7_cdadr(s7_pointer p) {return(cdadr(p));} s7_pointer s7_cdddr(s7_pointer p) {return(cdddr(p));} s7_pointer s7_cddar(s7_pointer p) {return(cddar(p));} s7_pointer s7_cdaar(s7_pointer p) {return(cdaar(p));} s7_pointer s7_caaadr(s7_pointer p) {return(caaadr(p));} s7_pointer s7_caaddr(s7_pointer p) {return(caaddr(p));} s7_pointer s7_caadar(s7_pointer p) {return(caadar(p));} s7_pointer s7_caaaar(s7_pointer p) {return(caaaar(p));} s7_pointer s7_cadadr(s7_pointer p) {return(cadadr(p));} s7_pointer s7_cadddr(s7_pointer p) {return(cadddr(p));} s7_pointer s7_caddar(s7_pointer p) {return(caddar(p));} s7_pointer s7_cadaar(s7_pointer p) {return(cadaar(p));} s7_pointer s7_cdaadr(s7_pointer p) {return(cdaadr(p));} s7_pointer s7_cdaddr(s7_pointer p) {return(cdaddr(p));} s7_pointer s7_cdadar(s7_pointer p) {return(cdadar(p));} s7_pointer s7_cdaaar(s7_pointer p) {return(cdaaar(p));} s7_pointer s7_cddadr(s7_pointer p) {return(cddadr(p));} s7_pointer s7_cddddr(s7_pointer p) {return(cddddr(p));} s7_pointer s7_cdddar(s7_pointer p) {return(cdddar(p));} s7_pointer s7_cddaar(s7_pointer p) {return(cddaar(p));} s7_pointer s7_set_car(s7_pointer p, s7_pointer q) { car(p) = q; return(p); } s7_pointer s7_set_cdr(s7_pointer p, s7_pointer q) { cdr(p) = q; return(p); } /* -------------------------------------------------------------------------------- */ s7_pointer s7_apply_1(s7_scheme *sc, s7_pointer args, s7_pointer (*f1)(s7_pointer a1)) { /* not currently used */ return(f1(car(args))); } s7_pointer s7_apply_2(s7_scheme *sc, s7_pointer args, s7_pointer (*f2)(s7_pointer a1, s7_pointer a2)) { return(f2(car(args), cadr(args))); } s7_pointer s7_apply_3(s7_scheme *sc, s7_pointer args, s7_pointer (*f3)(s7_pointer a1, s7_pointer a2, s7_pointer a3)) { s7_pointer a1; a1 = car(args); args = cdr(args); return(f3(a1, car(args), cadr(args))); } s7_pointer s7_apply_4(s7_scheme *sc, s7_pointer args, s7_pointer (*f4)(s7_pointer a1, s7_pointer a2, s7_pointer a3, s7_pointer a4)) { s7_pointer a1, a2; a1 = car(args); a2 = cadr(args); args = cddr(args); return(f4(a1, a2, car(args), cadr(args))); } s7_pointer s7_apply_5(s7_scheme *sc, s7_pointer args, s7_pointer (*f5)(s7_pointer a1, s7_pointer a2, s7_pointer a3, s7_pointer a4, s7_pointer a5)) { s7_pointer a1, a2, a3, a4; a1 = car(args); a2 = cadr(args); args = cddr(args); a3 = car(args); a4 = cadr(args); args = cddr(args); return(f5(a1, a2, a3, a4, car(args))); } s7_pointer s7_apply_6(s7_scheme *sc, s7_pointer args, s7_pointer (*f6)(s7_pointer a1, s7_pointer a2, s7_pointer a3, s7_pointer a4, s7_pointer a5, s7_pointer a6)) { s7_pointer a1, a2, a3, a4; a1 = car(args); a2 = cadr(args); args = cddr(args); a3 = car(args); a4 = cadr(args); args = cddr(args); return(f6(a1, a2, a3, a4, car(args), cadr(args))); } s7_pointer s7_apply_7(s7_scheme *sc, s7_pointer args, s7_pointer (*f7)(s7_pointer a1, s7_pointer a2, s7_pointer a3, s7_pointer a4, s7_pointer a5, s7_pointer a6, s7_pointer a7)) { s7_pointer a1, a2, a3, a4, a5, a6; a1 = car(args); a2 = cadr(args); args = cddr(args); a3 = car(args); a4 = cadr(args); args = cddr(args); a5 = car(args); a6 = cadr(args); args = cddr(args); return(f7(a1, a2, a3, a4, a5, a6, car(args))); } s7_pointer s7_apply_8(s7_scheme *sc, s7_pointer args, s7_pointer (*f8)(s7_pointer a1, s7_pointer a2, s7_pointer a3, s7_pointer a4, s7_pointer a5, s7_pointer a6, s7_pointer a7, s7_pointer a8)) { s7_pointer a1, a2, a3, a4, a5, a6; a1 = car(args); a2 = cadr(args); args = cddr(args); a3 = car(args); a4 = cadr(args); args = cddr(args); a5 = car(args); a6 = cadr(args); args = cddr(args); return(f8(a1, a2, a3, a4, a5, a6, car(args), cadr(args))); } s7_pointer s7_apply_9(s7_scheme *sc, s7_pointer args, s7_pointer (*f9)(s7_pointer a1, s7_pointer a2, s7_pointer a3, s7_pointer a4, s7_pointer a5, s7_pointer a6, s7_pointer a7, s7_pointer a8, s7_pointer a9)) { s7_pointer a1, a2, a3, a4, a5, a6; a1 = car(args); a2 = cadr(args); args = cddr(args); a3 = car(args); a4 = cadr(args); args = cddr(args); a5 = car(args); a6 = cadr(args); args = cddr(args); return(f9(a1, a2, a3, a4, a5, a6, car(args), cadr(args), caddr(args))); } s7_pointer s7_apply_n_1(s7_scheme *sc, s7_pointer args, s7_pointer (*f1)(s7_pointer a1)) { if (is_pair(args)) return(f1(car(args))); return(f1(sc->UNDEFINED)); } s7_pointer s7_apply_n_2(s7_scheme *sc, s7_pointer args, s7_pointer (*f2)(s7_pointer a1, s7_pointer a2)) { if (is_pair(args)) { if (is_pair(cdr(args))) return(f2(car(args), cadr(args))); return(f2(car(args), sc->UNDEFINED)); } return(f2(sc->UNDEFINED, sc->UNDEFINED)); } s7_pointer s7_apply_n_3(s7_scheme *sc, s7_pointer args, s7_pointer (*f3)(s7_pointer a1, s7_pointer a2, s7_pointer a3)) { if (is_pair(args)) { s7_pointer a1; a1 = car(args); args = cdr(args); if (is_pair(args)) { s7_pointer a2; a2 = car(args); if (is_pair(cdr(args))) return(f3(a1, a2, cadr(args))); return(f3(a1, a2, sc->UNDEFINED)); } return(f3(a1, sc->UNDEFINED, sc->UNDEFINED)); } return(f3(sc->UNDEFINED, sc->UNDEFINED, sc->UNDEFINED)); } s7_pointer s7_apply_n_4(s7_scheme *sc, s7_pointer args, s7_pointer (*f4)(s7_pointer a1, s7_pointer a2, s7_pointer a3, s7_pointer a4)) { if (is_pair(args)) { s7_pointer a1; a1 = car(args); args = cdr(args); if (is_pair(args)) { s7_pointer a2; a2 = car(args); args = cdr(args); if (is_pair(args)) { s7_pointer a3; a3 = car(args); if (is_pair(cdr(args))) return(f4(a1, a2, a3, cadr(args))); return(f4(a1, a2, a3, sc->UNDEFINED)); } return(f4(a1, a2, sc->UNDEFINED, sc->UNDEFINED)); } return(f4(a1, sc->UNDEFINED, sc->UNDEFINED, sc->UNDEFINED)); } return(f4(sc->UNDEFINED, sc->UNDEFINED, sc->UNDEFINED, sc->UNDEFINED)); } s7_pointer s7_apply_n_5(s7_scheme *sc, s7_pointer args, s7_pointer (*f5)(s7_pointer a1, s7_pointer a2, s7_pointer a3, s7_pointer a4, s7_pointer a5)) { if (is_pair(args)) { s7_pointer a1; a1 = car(args); args = cdr(args); if (is_pair(args)) { s7_pointer a2; a2 = car(args); args = cdr(args); if (is_pair(args)) { s7_pointer a3; a3 = car(args); args = cdr(args); if (is_pair(args)) { s7_pointer a4; a4 = car(args); if (is_pair(cdr(args))) return(f5(a1, a2, a3, a4, cadr(args))); return(f5(a1, a2, a3, a4, sc->UNDEFINED)); } return(f5(a1, a2, a3, sc->UNDEFINED, sc->UNDEFINED)); } return(f5(a1, a2, sc->UNDEFINED, sc->UNDEFINED, sc->UNDEFINED)); } return(f5(a1, sc->UNDEFINED, sc->UNDEFINED, sc->UNDEFINED, sc->UNDEFINED)); } return(f5(sc->UNDEFINED, sc->UNDEFINED, sc->UNDEFINED, sc->UNDEFINED, sc->UNDEFINED)); } s7_pointer s7_apply_n_6(s7_scheme *sc, s7_pointer args, s7_pointer (*f6)(s7_pointer a1, s7_pointer a2, s7_pointer a3, s7_pointer a4, s7_pointer a5, s7_pointer a6)) { s7_pointer a1, a2, a3, a4, a5, a6; a1 = sc->UNDEFINED; a2 = sc->UNDEFINED; a3 = sc->UNDEFINED; a4 = sc->UNDEFINED; a5 = sc->UNDEFINED; a6 = sc->UNDEFINED; if (is_pair(args)) { a1 = car(args); args = cdr(args); if (is_pair(args)) { a2 = car(args); args = cdr(args); if (is_pair(args)) { a3 = car(args); args = cdr(args); if (is_pair(args)) { a4 = car(args); args = cdr(args); if (is_pair(args)) { a5 = car(args); if (is_pair(cdr(args))) a6 = cadr(args); }}}}} return(f6(a1, a2, a3, a4, a5, a6)); } s7_pointer s7_apply_n_7(s7_scheme *sc, s7_pointer args, s7_pointer (*f7)(s7_pointer a1, s7_pointer a2, s7_pointer a3, s7_pointer a4, s7_pointer a5, s7_pointer a6, s7_pointer a7)) { s7_pointer a1, a2, a3, a4, a5, a6, a7; a1 = sc->UNDEFINED; a2 = sc->UNDEFINED; a3 = sc->UNDEFINED; a4 = sc->UNDEFINED; a5 = sc->UNDEFINED; a6 = sc->UNDEFINED, a7 = sc->UNDEFINED; if (is_pair(args)) { a1 = car(args); args = cdr(args); if (is_pair(args)) { a2 = car(args); args = cdr(args); if (is_pair(args)) { a3 = car(args); args = cdr(args); if (is_pair(args)) { a4 = car(args); args = cdr(args); if (is_pair(args)) { a5 = car(args); args = cdr(args); if (is_pair(args)) { a6 = car(args); if (is_pair(cdr(args))) a7 = cadr(args); }}}}}} return(f7(a1, a2, a3, a4, a5, a6, a7)); } s7_pointer s7_apply_n_8(s7_scheme *sc, s7_pointer args, s7_pointer (*f8)(s7_pointer a1, s7_pointer a2, s7_pointer a3, s7_pointer a4, s7_pointer a5, s7_pointer a6, s7_pointer a7, s7_pointer a8)) { s7_pointer a1, a2, a3, a4, a5, a6, a7, a8; a1 = sc->UNDEFINED; a2 = sc->UNDEFINED; a3 = sc->UNDEFINED; a4 = sc->UNDEFINED; a5 = sc->UNDEFINED; a6 = sc->UNDEFINED, a7 = sc->UNDEFINED; a8 = sc->UNDEFINED; if (is_pair(args)) { a1 = car(args); args = cdr(args); if (is_pair(args)) { a2 = car(args); args = cdr(args); if (is_pair(args)) { a3 = car(args); args = cdr(args); if (is_pair(args)) { a4 = car(args); args = cdr(args); if (is_pair(args)) { a5 = car(args); args = cdr(args); if (is_pair(args)) { a6 = car(args); args = cdr(args); if (is_pair(args)) { a7 = car(args); if (is_pair(cdr(args))) a8 = cadr(args); }}}}}}} return(f8(a1, a2, a3, a4, a5, a6, a7, a8)); } s7_pointer s7_apply_n_9(s7_scheme *sc, s7_pointer args, s7_pointer (*f9)(s7_pointer a1, s7_pointer a2, s7_pointer a3, s7_pointer a4, s7_pointer a5, s7_pointer a6, s7_pointer a7, s7_pointer a8, s7_pointer a9)) { s7_pointer a1, a2, a3, a4, a5, a6, a7, a8, a9; a1 = sc->UNDEFINED; a2 = sc->UNDEFINED; a3 = sc->UNDEFINED; a4 = sc->UNDEFINED; a5 = sc->UNDEFINED; a6 = sc->UNDEFINED, a7 = sc->UNDEFINED; a8 = sc->UNDEFINED; a9 = sc->UNDEFINED; if (is_pair(args)) { a1 = car(args); args = cdr(args); if (is_pair(args)) { a2 = car(args); args = cdr(args); if (is_pair(args)) { a3 = car(args); args = cdr(args); if (is_pair(args)) { a4 = car(args); args = cdr(args); if (is_pair(args)) { a5 = car(args); args = cdr(args); if (is_pair(args)) { a6 = car(args); args = cdr(args); if (is_pair(args)) { a7 = car(args); args = cdr(args); if (is_pair(args)) { a8 = car(args); if (is_pair(cdr(args))) a9 = cadr(args); }}}}}}}} return(f9(a1, a2, a3, a4, a5, a6, a7, a8, a9)); } /* -------------------------------------------------------------------------------- */ s7_pointer s7_list_ref(s7_scheme *sc, s7_pointer lst, int num) { int i; s7_pointer x; for (x = lst, i = 0; (i < num) && (is_pair(x)); i++, x = cdr(x)) {} if ((i == num) && (is_pair(x))) return(car(x)); return(sc->NIL); } s7_pointer s7_list_set(s7_scheme *sc, s7_pointer lst, int num, s7_pointer val) { int i; s7_pointer x; for (x = lst, i = 0; (i < num) && (is_pair(x)); i++, x = cdr(x)) {} if ((i == num) && (is_pair(x))) car(x) = val; return(val); } s7_pointer s7_member(s7_scheme *sc, s7_pointer sym, s7_pointer lst) { s7_pointer x; for (x = lst; is_pair(x); x = cdr(x)) if (s7_is_equal(sc, sym, car(x))) return(x); return(sc->F); } static bool symbol_is_in_arg_list(s7_pointer sym, s7_pointer lst) { s7_pointer x; for (x = lst; is_pair(x); x = cdr(x)) if ((sym == car(x)) || ((is_pair(car(x))) && (sym == caar(x)))) return(true); return(sym == x); } s7_pointer s7_assoc(s7_scheme *sc, s7_pointer sym, s7_pointer lst) { s7_pointer x, y; if (!is_pair(lst)) return(sc->F); x = lst; y = lst; while (true) { if ((is_pair(car(x))) && (s7_is_equal(sc, sym, caar(x)))) return(car(x)); x = cdr(x); if (!is_pair(x)) return(sc->F); if ((is_pair(car(x))) && (s7_is_equal(sc, sym, caar(x)))) return(car(x)); x = cdr(x); if (!is_pair(x)) return(sc->F); y = cdr(y); if (x == y) return(sc->F); } return(sc->F); } s7_pointer s7_reverse(s7_scheme *sc, s7_pointer a) { /* reverse list -- produce new list (other code assumes this function does not return the original!) */ s7_pointer x, p; if (is_null(a)) return(a); if (!is_pair(cdr(a))) { if (is_not_null(cdr(a))) return(cons(sc, cdr(a), car(a))); return(cons(sc, car(a), sc->NIL)); /* don't return 'a' itself */ } sc->w = list_1(sc, car(a)); for (x = cdr(a), p = a; is_pair(x); x = cdr(x), p = cdr(p)) { sc->w = cons(sc, car(x), sc->w); if (is_pair(cdr(x))) { x = cdr(x); sc->w = cons(sc, car(x), sc->w); } if (x == p) /* this can take awhile to notice there's a cycle, but what does the caller expect? */ break; } if (is_not_null(x)) p = cons(sc, x, sc->w); /* ?? this means that (reverse '(1 2 . 3)) returns '(3 2 1) -- we used to return () here */ else p = sc->w; sc->w = sc->NIL; return(p); } /* s7_reverse sometimes tacks extra nodes on the end of a reversed circular list (it detects the cycle too late) * (let ((lst (list 0))) (set! (cdr lst) lst) (reverse lst)) -> (#1=(0 . #1#) 0 0 0) */ static s7_pointer reverse_in_place(s7_scheme *sc, s7_pointer term, s7_pointer list) { s7_pointer p = list, result = term, q; while (is_not_null(p)) { q = cdr(p); if ((!is_pair(q)) && (is_not_null(q))) return(sc->NIL); /* improper list? */ cdr(p) = result; result = p; p = q; } return(result); } static s7_pointer reverse_in_place_unchecked(s7_scheme *sc, s7_pointer term, s7_pointer list) { s7_pointer p = list, result = term, q; while (is_not_null(p)) { q = cdr(p); cdr(p) = result; result = p; p = q; if (is_null(p)) break; q = cdr(p); cdr(p) = result; result = p; p = q; } return(result); } static s7_pointer safe_reverse_in_place(s7_scheme *sc, s7_pointer list) /* "safe" here means we guarantee this list is unproblematic */ { s7_pointer p = list, result, q; result = sc->NIL; while (is_not_null(p)) { q = cdr(p); /* also if (is_null(list)) || (is_null(cdr(list))) return(list) */ cdr(p) = result; result = p; p = q; /* unroll the loop for speed */ if (is_null(p)) break; q = cdr(p); cdr(p) = result; result = p; p = q; if (is_null(p)) break; q = cdr(p); cdr(p) = result; result = p; p = q; if (is_null(p)) break; q = cdr(p); cdr(p) = result; result = p; p = q; } return(result); } /* is this correct? (let ((x (list 1 2))) (eq? x (append () x))) -> #t */ s7_pointer s7_append(s7_scheme *sc, s7_pointer a, s7_pointer b) { s7_pointer p, tp, np; if (is_null(a)) return(b); tp = cons(sc, car(a), sc->NIL); sc->y = tp; for (p = cdr(a), np = tp; is_pair(p); p = cdr(p), np = cdr(np)) cdr(np) = cons(sc, car(p), sc->NIL); cdr(np) = b; sc->y = sc->NIL; return(tp); } static s7_pointer copy_list(s7_scheme *sc, s7_pointer lst) { s7_pointer p, tp, np; if (!is_pair(lst)) return(sc->NIL); tp = cons(sc, car(lst), sc->NIL); sc->y = tp; for (p = cdr(lst), np = tp; is_pair(p); p = cdr(p), np = cdr(np)) cdr(np) = cons(sc, car(p), sc->NIL); sc->y = sc->NIL; return(tp); } static s7_pointer copy_list_with_arglist_error(s7_scheme *sc, s7_pointer lst) { s7_pointer p, tp, np; if (is_null(lst)) return(sc->NIL); if (!is_pair(lst)) s7_error(sc, sc->SYNTAX_ERROR, set_elist_2(sc, make_string_wrapper(sc, "stray dot?: ~S"), lst)); tp = cons(sc, car(lst), sc->NIL); sc->y = tp; for (p = cdr(lst), np = tp; is_pair(p); p = cdr(p), np = cdr(np)) cdr(np) = cons(sc, car(p), sc->NIL); sc->y = sc->NIL; if (!is_null(p)) s7_error(sc, sc->SYNTAX_ERROR, set_elist_2(sc, make_string_wrapper(sc, "improper list of arguments: ~S"), lst)); return(tp); } static s7_pointer revappend(s7_scheme *sc, s7_pointer a, s7_pointer b) { /* (map (lambda (x) (if (odd? x) (apply values '(1 2 3)) (values))) (list 1 2 3 4)) * is a bad case -- we have to copy the incoming list. */ s7_pointer p = b, q; if (is_not_null(a)) { a = copy_list(sc, a); while (is_not_null(a)) { q = cdr(a); cdr(a) = p; p = a; a = q; } } return(p); } static int safe_list_length(s7_scheme *sc, s7_pointer a) { /* assume that "a" is a proper list */ int i = 0; s7_pointer b; for (b = a; is_pair(b); i++, b = cdr(b)) {}; return(i); } int s7_list_length(s7_scheme *sc, s7_pointer a) { /* returns -len if list is dotted, 0 if it's (directly) circular */ int i; s7_pointer slow, fast; slow = fast = a; for (i = 0; ; i += 2) { if (!is_pair(fast)) { if (is_null(fast)) return(i); return(-i); } fast = cdr(fast); if (!is_pair(fast)) { if (is_null(fast)) return(i + 1); return(-i - 1); } /* if unrolled further, it's a lot slower? */ fast = cdr(fast); slow = cdr(slow); if (fast == slow) return(0); } return(0); } /* -------------------------------- null? pair? -------------------------------- */ static s7_pointer g_is_null(s7_scheme *sc, s7_pointer args) { #define H_is_null "(null? obj) returns #t if obj is the empty list" #define Q_is_null pl_bt check_boolean_method(sc, is_null, sc->IS_NULL, args); /* as a generic this could be: has_structure and length == 0 */ } static s7_pointer g_is_pair(s7_scheme *sc, s7_pointer args) { #define H_is_pair "(pair? obj) returns #t if obj is a pair (a non-empty list)" #define Q_is_pair pl_bt check_boolean_method(sc, is_pair, sc->IS_PAIR, args); } /* -------------------------------- list? proper-list? -------------------------------- */ bool s7_is_list(s7_scheme *sc, s7_pointer p) { return((is_pair(p)) || (is_null(p))); } static bool is_proper_list(s7_scheme *sc, s7_pointer lst) { s7_pointer slow, fast; fast = lst; slow = lst; while (true) { if (!is_pair(fast)) return(is_null(fast)); /* else it's an improper list */ fast = cdr(fast); if (!is_pair(fast)) return(is_null(fast)); fast = cdr(fast); if (!is_pair(fast)) return(is_null(fast)); fast = cdr(fast); slow = cdr(slow); if (fast == slow) return(false); } return(true); } static s7_pointer g_is_list(s7_scheme *sc, s7_pointer args) { #define H_is_list "(list? obj) returns #t if obj is a pair or null" #define Q_is_list pl_bt #define is_a_list(p) s7_is_list(sc, p) check_boolean_method(sc, is_a_list, sc->IS_LIST, args); } /* -------------------------------- make-list -------------------------------- */ static s7_pointer make_list(s7_scheme *sc, int len, s7_pointer init) { switch (len) { case 0: return(sc->NIL); case 1: return(cons(sc, init, sc->NIL)); case 2: return(cons_unchecked(sc, init, cons(sc, init, sc->NIL))); case 3: return(cons_unchecked(sc, init, cons_unchecked(sc, init, cons(sc, init, sc->NIL)))); case 4: return(cons_unchecked(sc, init, cons_unchecked(sc, init, cons_unchecked(sc, init, cons(sc, init, sc->NIL))))); case 5: return(cons_unchecked(sc, init, cons_unchecked(sc, init, cons_unchecked(sc, init, cons_unchecked(sc, init, cons(sc, init, sc->NIL)))))); case 6: return(cons_unchecked(sc, init, cons_unchecked(sc, init, cons_unchecked(sc, init, cons_unchecked(sc, init, cons_unchecked(sc, init, cons(sc, init, sc->NIL))))))); case 7: return(cons_unchecked(sc, init, cons_unchecked(sc, init, cons_unchecked(sc, init, cons_unchecked(sc, init, cons_unchecked(sc, init, cons_unchecked(sc, init, cons(sc, init, sc->NIL)))))))); default: { s7_pointer result; int i; if (len >= (sc->free_heap_top - sc->free_heap)) { gc(sc); while (len >= (sc->free_heap_top - sc->free_heap)) resize_heap(sc); } sc->v = sc->NIL; for (i = 0; i < len; i++) sc->v = cons_unchecked(sc, init, sc->v); result = sc->v; sc->v = sc->NIL; return(result); } } return(sc->NIL); /* never happens, I hope */ } static s7_pointer g_make_list(s7_scheme *sc, s7_pointer args) { #define H_make_list "(make-list length (initial-element #f)) returns a list of 'length' elements whose value is 'initial-element'." #define Q_make_list s7_make_signature(sc, 3, sc->IS_LIST, sc->IS_INTEGER, sc->T) s7_pointer init; s7_int len; if (!s7_is_integer(car(args))) method_or_bust(sc, car(args), sc->MAKE_LIST, args, T_INTEGER, 1); len = s7_integer(car(args)); /* needs to be s7_int here so that (make-list most-negative-fixnum) is handled correctly */ if (len < 0) return(out_of_range(sc, sc->MAKE_LIST, small_int(1), car(args), ITS_NEGATIVE)); if (len == 0) return(sc->NIL); /* what about (make-list 0 123)? */ if (len > sc->max_list_length) return(out_of_range(sc, sc->MAKE_LIST, small_int(1), car(args), ITS_TOO_LARGE)); if (is_pair(cdr(args))) init = cadr(args); else init = sc->F; return(make_list(sc, (int)len, init)); } static s7_pointer c_make_list(s7_scheme *sc, s7_int len) {return(make_list(sc, (int)len, sc->F));} IF_TO_PF(make_list, c_make_list) /* -------------------------------- list-ref -------------------------------- */ static s7_pointer list_ref_ic; static s7_pointer g_list_ref_ic(s7_scheme *sc, s7_pointer args) { s7_int i, index; s7_pointer lst, p; lst = car(args); if (!is_pair(lst)) method_or_bust(sc, lst, sc->LIST_REF, args, T_PAIR, 1); index = s7_integer(cadr(args)); for (i = 0, p = lst; (i < index) && is_pair(p); i++, p = cdr(p)) {} if (!is_pair(p)) { if (is_null(p)) return(out_of_range(sc, sc->LIST_REF, small_int(2), cadr(args), ITS_TOO_LARGE)); return(wrong_type_argument_with_type(sc, sc->LIST_REF, 1, lst, A_PROPER_LIST)); } return(car(p)); } static s7_pointer list_ref_1(s7_scheme *sc, s7_pointer lst, s7_pointer ind) { s7_int i, index; s7_pointer p; if (!s7_is_integer(ind)) { if (!s7_is_integer(p = check_values(sc, ind, cons(sc, ind, sc->NIL)))) method_or_bust(sc, ind, sc->LIST_REF, list_2(sc, lst, ind), T_INTEGER, 2); ind = p; } index = s7_integer(ind); if ((index < 0) || (index > sc->max_list_length)) return(out_of_range(sc, sc->LIST_REF, small_int(2), ind, (index < 0) ? ITS_NEGATIVE : ITS_TOO_LARGE)); for (i = 0, p = lst; (i < index) && is_pair(p); i++, p = cdr(p)) {} if (!is_pair(p)) { if (is_null(p)) return(out_of_range(sc, sc->LIST_REF, small_int(2), ind, ITS_TOO_LARGE)); return(wrong_type_argument_with_type(sc, sc->LIST_REF, 1, lst, A_PROPER_LIST)); } return(car(p)); } static s7_pointer g_list_ref(s7_scheme *sc, s7_pointer args) { #define H_list_ref "(list-ref lst i ...) returns the i-th element (0-based) of the list" #define Q_list_ref s7_make_circular_signature(sc, 2, 3, sc->T, sc->IS_PAIR, sc->IS_INTEGER) /* (let ((L '((1 2 3) (4 5 6)))) (list-ref L 1 2)) (define (lref L . args) (if (null? (cdr args)) (list-ref L (car args)) (apply lref (list-ref L (car args)) (cdr args)))) */ s7_pointer lst, inds; lst = car(args); if (!is_pair(lst)) method_or_bust(sc, lst, sc->LIST_REF, args, T_PAIR, 1); inds = cdr(args); while (true) { lst = list_ref_1(sc, lst, car(inds)); if (is_null(cdr(inds))) return(lst); inds = cdr(inds); if (!is_pair(lst)) /* trying to avoid a cons here at the cost of one extra type check */ return(implicit_index(sc, lst, inds)); } } static s7_pointer c_list_ref(s7_scheme *sc, s7_pointer x, s7_int index) { int i; s7_pointer p; if (!s7_is_pair(x)) method_or_bust(sc, x, sc->LIST_REF, list_2(sc, x, make_integer(sc, index)), T_PAIR, 1); if (index < 0) return(out_of_range(sc, sc->LIST_REF, small_int(2), make_integer(sc, index), ITS_NEGATIVE)); for (i = 0, p = x; (i < index) && is_pair(p); i++, p = cdr(p)) {} if (!is_pair(p)) { if (is_null(p)) return(out_of_range(sc, sc->LIST_REF, small_int(2), make_integer(sc, index), ITS_TOO_LARGE)); return(wrong_type_argument_with_type(sc, sc->LIST_REF, 1, x, A_PROPER_LIST)); } return(car(p)); } PIF_TO_PF(list_ref, c_list_ref) /* -------------------------------- list-set! -------------------------------- */ static s7_pointer g_list_set_1(s7_scheme *sc, s7_pointer lst, s7_pointer args, int arg_num) { #define H_list_set "(list-set! lst i ... val) sets the i-th element (0-based) of the list to val" #define Q_list_set s7_make_circular_signature(sc, 2, 3, sc->T, sc->IS_PAIR, sc->T) int i; s7_int index; s7_pointer p, ind; /* (let ((L '((1 2 3) (4 5 6)))) (list-set! L 1 2 32) L) */ if (!is_pair(lst)) method_or_bust(sc, lst, sc->LIST_SET, cons(sc, lst, args), T_PAIR, 1); ind = car(args); if (!s7_is_integer(ind)) { if (!s7_is_integer(p = check_values(sc, ind, args))) method_or_bust(sc, ind, sc->LIST_SET, cons(sc, lst, args), T_INTEGER, arg_num); ind = p; } index = s7_integer(ind); if ((index < 0) || (index > sc->max_list_length)) return(out_of_range(sc, sc->LIST_SET, small_int(arg_num), ind, (index < 0) ? ITS_NEGATIVE : ITS_TOO_LARGE)); for (i = 0, p = _TSet(lst); (i < index) && is_pair(p); i++, p = cdr(p)) {} if (!is_pair(p)) { if (is_null(p)) return(out_of_range(sc, sc->LIST_SET, small_int(arg_num), ind, ITS_TOO_LARGE)); return(wrong_type_argument_with_type(sc, sc->LIST_SET, 1, lst, A_PROPER_LIST)); } if (is_null(cddr(args))) car(p) = cadr(args); else return(g_list_set_1(sc, car(p), cdr(args), arg_num + 1)); return(cadr(args)); } static s7_pointer g_list_set(s7_scheme *sc, s7_pointer args) { return(g_list_set_1(sc, car(args), cdr(args), 2)); } static int c_list_tester(s7_scheme *sc, s7_pointer expr) { s7_pointer a1; a1 = cadr(expr); if (is_symbol(a1)) { s7_pointer table; table = s7_slot(sc, a1); if ((is_slot(table)) && ((is_immutable_symbol(a1)) || (!is_stepper(table))) && (is_pair(slot_value(table)))) { s7_xf_store(sc, slot_value(table)); a1 = caddr(expr); if (is_symbol(a1)) { s7_pointer slot; slot = s7_slot(sc, a1); if ((is_slot(slot)) && (is_integer(slot_value(slot)))) { s7_xf_store(sc, slot); return(TEST_SS); } } else { if (s7_arg_to_if(sc, a1)) return(TEST_SI); } return(TEST_SQ); } } return(TEST_NO_S); } static s7_pointer c_list_set_s(s7_scheme *sc, s7_pointer lst, s7_int index, s7_pointer val) { s7_int i; s7_pointer p; if ((index < 0) || (index > sc->max_list_length)) return(out_of_range(sc, sc->LIST_SET, small_int(2), make_integer(sc, index), (index < 0) ? ITS_NEGATIVE : ITS_TOO_LARGE)); for (i = 0, p = lst; (i < index) && is_pair(p); i++, p = cdr(p)) {} if (!is_pair(p)) { if (is_null(p)) return(out_of_range(sc, sc->LIST_SET, small_int(2), make_integer(sc, index), ITS_TOO_LARGE)); return(wrong_type_argument_with_type(sc, sc->LIST_SET, 1, lst, A_PROPER_LIST)); } car(p) = val; return(val); } static s7_pointer c_list_set(s7_scheme *sc, s7_pointer vec, s7_int index, s7_pointer val) { if (!s7_is_pair(vec)) method_or_bust(sc, vec, sc->LIST_SET, set_plist_3(sc, vec, make_integer(sc, index), val), T_PAIR, 1); return(c_list_set_s(sc, vec, index, val)); } PIPF_TO_PF(list_set, c_list_set_s, c_list_set, c_list_tester) static s7_pointer list_set_ic; static s7_pointer g_list_set_ic(s7_scheme *sc, s7_pointer args) { s7_pointer lst; lst = car(args); if (!is_pair(lst)) method_or_bust(sc, lst, sc->LIST_SET, args, T_PAIR, 1); return(c_list_set_s(sc, lst, s7_integer(cadr(args)), caddr(args))); } /* -------------------------------- list-tail -------------------------------- */ static s7_pointer c_list_tail(s7_scheme *sc, s7_pointer lst, s7_int index) { s7_int i; s7_pointer p; if (!s7_is_list(sc, lst)) method_or_bust_with_type(sc, lst, sc->LIST_TAIL, list_2(sc, lst, make_integer(sc, index)), A_LIST, 1); if ((index < 0) || (index > sc->max_list_length)) return(out_of_range(sc, sc->LIST_TAIL, small_int(2), make_integer(sc, index), (index < 0) ? ITS_NEGATIVE : ITS_TOO_LARGE)); for (i = 0, p = lst; (i < index) && (is_pair(p)); i++, p = cdr(p)) {} if (i < index) return(out_of_range(sc, sc->LIST_TAIL, small_int(2), make_integer(sc, index), ITS_TOO_LARGE)); return(p); } static s7_pointer g_list_tail(s7_scheme *sc, s7_pointer args) { #define H_list_tail "(list-tail lst i) returns the list from the i-th element on" #define Q_list_tail s7_make_signature(sc, 3, sc->IS_LIST, sc->IS_PAIR, sc->IS_INTEGER) s7_pointer p; p = cadr(args); if (!s7_is_integer(p)) { s7_pointer p1; if (!s7_is_integer(p1 = check_values(sc, p, cdr(args)))) method_or_bust(sc, p, sc->LIST_TAIL, args, T_INTEGER, 2); p = p1; } return(c_list_tail(sc, car(args), s7_integer(p))); } PIF_TO_PF(list_tail, c_list_tail) /* -------------------------------- cons -------------------------------- */ static s7_pointer g_cons(s7_scheme *sc, s7_pointer args) { /* n-ary cons could be the equivalent of CL's list*? */ /* it would be neater to have a single cons cell able to contain (directly) any number of elements */ /* (set! (cadr (cons 1 2 3)) 4) -> (1 4 . 3) */ #define H_cons "(cons a b) returns a pair containing a and b" #define Q_cons s7_make_signature(sc, 3, sc->IS_PAIR, sc->T, sc->T) /* cdr(args) = cadr(args); * this is not safe -- it changes a variable's value directly: * (let ((lst (list 1 2))) (list (apply cons lst) lst)) -> '((1 . 2) (1 . 2)) */ s7_pointer x; new_cell(sc, x, T_PAIR | T_SAFE_PROCEDURE); car(x) = car(args); cdr(x) = cadr(args); return(x); } PF2_TO_PF(cons, s7_cons) static void init_car_a_list(void) { CAR_A_LIST = s7_make_permanent_string("a list whose car is also a list"); CDR_A_LIST = s7_make_permanent_string("a list whose cdr is also a list"); CAAR_A_LIST = s7_make_permanent_string("a list whose caar is also a list"); CADR_A_LIST = s7_make_permanent_string("a list whose cadr is also a list"); CDAR_A_LIST = s7_make_permanent_string("a list whose cdar is also a list"); CDDR_A_LIST = s7_make_permanent_string("a list whose cddr is also a list"); CAAAR_A_LIST = s7_make_permanent_string("a list whose caaar is also a list"); CAADR_A_LIST = s7_make_permanent_string("a list whose caadr is also a list"); CADAR_A_LIST = s7_make_permanent_string("a list whose cadar is also a list"); CADDR_A_LIST = s7_make_permanent_string("a list whose caddr is also a list"); CDAAR_A_LIST = s7_make_permanent_string("a list whose cdaar is also a list"); CDADR_A_LIST = s7_make_permanent_string("a list whose cdadr is also a list"); CDDAR_A_LIST = s7_make_permanent_string("a list whose cddar is also a list"); CDDDR_A_LIST = s7_make_permanent_string("a list whose cdddr is also a list"); A_LIST = s7_make_permanent_string("a list"); AN_EQ_FUNC = s7_make_permanent_string("a procedure that can take 2 arguments"); AN_ASSOCIATION_LIST = s7_make_permanent_string("an association list"); A_NORMAL_REAL = s7_make_permanent_string("a normal real"); A_RATIONAL = s7_make_permanent_string("an integer or a ratio"); A_NUMBER = s7_make_permanent_string("a number"); A_PROCEDURE = s7_make_permanent_string("a procedure"); A_NORMAL_PROCEDURE = s7_make_permanent_string("a normal procedure (not a continuation)"); A_LET = s7_make_permanent_string("a let (environment)"); A_PROPER_LIST = s7_make_permanent_string("a proper list"); A_BOOLEAN = s7_make_permanent_string("a boolean"); AN_INPUT_PORT = s7_make_permanent_string("an input port"); AN_OPEN_PORT = s7_make_permanent_string("an open port"); AN_OUTPUT_PORT = s7_make_permanent_string("an output port"); AN_INPUT_STRING_PORT = s7_make_permanent_string("an input string port"); AN_INPUT_FILE_PORT = s7_make_permanent_string("an input file port"); AN_OUTPUT_STRING_PORT = s7_make_permanent_string("an output string port"); AN_OUTPUT_FILE_PORT = s7_make_permanent_string("an output file port"); A_THUNK = s7_make_permanent_string("a thunk"); A_SYMBOL = s7_make_permanent_string("a symbol"); A_NON_NEGATIVE_INTEGER = s7_make_permanent_string("a non-negative integer"); AN_UNSIGNED_BYTE = s7_make_permanent_string("an unsigned byte"); SOMETHING_APPLICABLE = s7_make_permanent_string("a procedure or something applicable"); A_RANDOM_STATE_OBJECT = s7_make_permanent_string("a random-state object"); A_FORMAT_PORT = s7_make_permanent_string("#f, #t, or an open output port"); A_BINDING = s7_make_permanent_string("a pair whose car is a symbol: '(symbol . value)"); A_NON_CONSTANT_SYMBOL = s7_make_permanent_string("a non-constant symbol"); A_SEQUENCE = s7_make_permanent_string("a sequence"); A_VALID_RADIX = s7_make_permanent_string("should be between 2 and 16"); RESULT_IS_TOO_LARGE = s7_make_permanent_string("result is too large"); ITS_TOO_LARGE = s7_make_permanent_string("it is too large"); ITS_TOO_SMALL = s7_make_permanent_string("it is less than the start position"); ITS_NEGATIVE = s7_make_permanent_string("it is negative"); ITS_NAN = s7_make_permanent_string("NaN usually indicates a numerical error"); ITS_INFINITE = s7_make_permanent_string("it is infinite"); TOO_MANY_INDICES = s7_make_permanent_string("too many indices"); #if (!HAVE_COMPLEX_NUMBERS) NO_COMPLEX_NUMBERS = s7_make_permanent_string("this version of s7 does not support complex numbers"); #endif } /* -------- car -------- */ static s7_pointer g_car_1(s7_scheme *sc, s7_pointer lst) { if (!is_pair(lst)) method_or_bust(sc, lst, sc->CAR, set_plist_1(sc, lst), T_PAIR, 0); return(car(lst)); } static s7_pointer g_car(s7_scheme *sc, s7_pointer args) { #define H_car "(car pair) returns the first element of the pair" #define Q_car pl_p s7_pointer lst; lst = car(args); if (!is_pair(lst)) method_or_bust(sc, lst, sc->CAR, args, T_PAIR, 0); return(car(lst)); } PF_TO_PF(car, g_car_1) static s7_pointer g_set_car(s7_scheme *sc, s7_pointer args) { #define H_set_car "(set-car! pair val) sets the pair's first element to val" #define Q_set_car s7_make_signature(sc, 3, sc->T, sc->IS_PAIR, sc->T) s7_pointer p; p = car(args); if (!is_pair(p)) method_or_bust(sc, p, sc->SET_CAR, args, T_PAIR, 1); car(p) = cadr(args); return(car(p)); } static s7_pointer c_set_car(s7_scheme *sc, s7_pointer x, s7_pointer y) { if (!is_pair(x)) method_or_bust(sc, x, sc->SET_CAR, set_plist_2(sc, x, y), T_PAIR, 1); car(x) = y; return(y); } PF2_TO_PF(set_car, c_set_car) /* -------- cdr -------- */ static s7_pointer g_cdr_1(s7_scheme *sc, s7_pointer lst) { if (!is_pair(lst)) method_or_bust(sc, lst, sc->CDR, set_plist_1(sc, lst), T_PAIR, 0); return(cdr(lst)); } static s7_pointer g_cdr(s7_scheme *sc, s7_pointer args) { #define H_cdr "(cdr pair) returns the second element of the pair" #define Q_cdr pl_p s7_pointer lst; lst = car(args); if (!is_pair(lst)) method_or_bust(sc, lst, sc->CDR, args, T_PAIR, 0); return(cdr(lst)); } PF_TO_PF(cdr, g_cdr_1) static s7_pointer g_set_cdr(s7_scheme *sc, s7_pointer args) { #define H_set_cdr "(set-cdr! pair val) sets the pair's second element to val" #define Q_set_cdr s7_make_signature(sc, 3, sc->T, sc->IS_PAIR, sc->T) s7_pointer p; p = car(args); if (!is_pair(p)) method_or_bust(sc, p, sc->SET_CDR, args, T_PAIR, 1); cdr(p) = cadr(args); return(cdr(p)); } static s7_pointer c_set_cdr(s7_scheme *sc, s7_pointer x, s7_pointer y) { if (!is_pair(x)) method_or_bust(sc, x, sc->SET_CDR, set_plist_2(sc, x, y), T_PAIR, 1); cdr(x) = y; return(y); } PF2_TO_PF(set_cdr, c_set_cdr) /* -------- caar --------*/ static s7_pointer g_caar_1(s7_scheme *sc, s7_pointer lst) { if (!is_pair(lst)) method_or_bust(sc, lst, sc->CAAR, set_plist_1(sc, lst), T_PAIR, 0); if (!is_pair(car(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CAAR, lst, CAR_A_LIST)); /* it makes no difference in timing to move lst here or below (i.e. lst=car(lst) then return(car(lst)) and so on) */ return(caar(lst)); } static s7_pointer g_caar(s7_scheme *sc, s7_pointer args) { #define H_caar "(caar lst) returns (car (car lst)): (caar '((1 2))) -> 1" #define Q_caar pl_p s7_pointer lst; lst = car(args); if (!is_pair(lst)) method_or_bust(sc, lst, sc->CAAR, args, T_PAIR, 0); if (!is_pair(car(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CAAR, lst, CAR_A_LIST)); /* it makes no difference in timing to move lst here or below (i.e. lst=car(lst) then return(car(lst)) and so on) */ return(caar(lst)); } PF_TO_PF(caar, g_caar_1) /* -------- cadr --------*/ static s7_pointer g_cadr_1(s7_scheme *sc, s7_pointer lst) { if (!is_pair(lst)) method_or_bust(sc, lst, sc->CADR, set_plist_1(sc, lst), T_PAIR, 0); if (!is_pair(cdr(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CADR, lst, CDR_A_LIST)); return(cadr(lst)); } static s7_pointer g_cadr(s7_scheme *sc, s7_pointer args) { #define H_cadr "(cadr lst) returns (car (cdr lst)): (cadr '(1 2 3)) -> 2" #define Q_cadr pl_p s7_pointer lst; lst = car(args); if (!is_pair(lst)) method_or_bust(sc, lst, sc->CADR, args, T_PAIR, 0); if (!is_pair(cdr(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CADR, lst, CDR_A_LIST)); return(cadr(lst)); } PF_TO_PF(cadr, g_cadr_1) /* -------- cdar -------- */ static s7_pointer g_cdar_1(s7_scheme *sc, s7_pointer lst) { if (!is_pair(lst)) method_or_bust(sc, lst, sc->CDAR, set_plist_1(sc, lst), T_PAIR, 0); if (!is_pair(car(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CDAR, lst, CAR_A_LIST)); return(cdar(lst)); } static s7_pointer g_cdar(s7_scheme *sc, s7_pointer args) { #define H_cdar "(cdar lst) returns (cdr (car lst)): (cdar '((1 2 3))) -> '(2 3)" #define Q_cdar pl_p s7_pointer lst; lst = car(args); if (!is_pair(lst)) method_or_bust(sc, lst, sc->CDAR, args, T_PAIR, 0); if (!is_pair(car(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CDAR, lst, CAR_A_LIST)); return(cdar(lst)); } PF_TO_PF(cdar, g_cdar_1) /* -------- cddr -------- */ static s7_pointer g_cddr_1(s7_scheme *sc, s7_pointer lst) { if (!is_pair(lst)) method_or_bust(sc, lst, sc->CDDR, set_plist_1(sc, lst), T_PAIR, 0); if (!is_pair(cdr(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CDDR, lst, CDR_A_LIST)); return(cddr(lst)); } static s7_pointer g_cddr(s7_scheme *sc, s7_pointer args) { #define H_cddr "(cddr lst) returns (cdr (cdr lst)): (cddr '(1 2 3 4)) -> '(3 4)" #define Q_cddr pl_p s7_pointer lst; lst = car(args); if (!is_pair(lst)) method_or_bust(sc, lst, sc->CDDR, args, T_PAIR, 0); if (!is_pair(cdr(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CDDR, lst, CDR_A_LIST)); return(cddr(lst)); } PF_TO_PF(cddr, g_cddr_1) /* -------- caaar -------- */ static s7_pointer g_caaar_1(s7_scheme *sc, s7_pointer lst) { if (!is_pair(lst)) method_or_bust(sc, lst, sc->CAAAR, set_plist_1(sc, lst), T_PAIR, 0); if (!is_pair(car(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CAAAR, lst, CAR_A_LIST)); if (!is_pair(car(car(lst)))) return(simple_wrong_type_argument_with_type(sc, sc->CAAAR, lst, CAAR_A_LIST)); return(caaar(lst)); } static s7_pointer g_caaar(s7_scheme *sc, s7_pointer args) { #define H_caaar "(caaar lst) returns (car (car (car lst))): (caaar '(((1 2)))) -> 1" #define Q_caaar pl_p return(g_caaar_1(sc, car(args))); } PF_TO_PF(caaar, g_caaar_1) /* -------- caadr -------- */ static s7_pointer g_caadr_1(s7_scheme *sc, s7_pointer lst) { if (!is_pair(lst)) method_or_bust(sc, lst, sc->CAADR, set_plist_1(sc, lst), T_PAIR, 0); if (!is_pair(cdr(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CAADR, lst, CDR_A_LIST)); if (!is_pair(car(cdr(lst)))) return(simple_wrong_type_argument_with_type(sc, sc->CAADR, lst, CADR_A_LIST)); return(caadr(lst)); } static s7_pointer g_caadr(s7_scheme *sc, s7_pointer args) { #define H_caadr "(caadr lst) returns (car (car (cdr lst))): (caadr '(1 (2 3))) -> 2" #define Q_caadr pl_p return(g_caadr_1(sc, car(args))); } PF_TO_PF(caadr, g_caadr_1) /* -------- cadar -------- */ static s7_pointer g_cadar_1(s7_scheme *sc, s7_pointer lst) { if (!is_pair(lst)) method_or_bust(sc, lst, sc->CADAR, set_plist_1(sc, lst), T_PAIR, 0); if (!is_pair(car(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CADAR, lst, CAR_A_LIST)); if (!is_pair(cdr(car(lst)))) return(simple_wrong_type_argument_with_type(sc, sc->CADAR, lst, CDAR_A_LIST)); return(cadar(lst)); } static s7_pointer g_cadar(s7_scheme *sc, s7_pointer args) { #define H_cadar "(cadar lst) returns (car (cdr (car lst))): (cadar '((1 2 3))) -> 2" #define Q_cadar pl_p return(g_cadar_1(sc, car(args))); } PF_TO_PF(cadar, g_cadar_1) /* -------- cdaar -------- */ static s7_pointer g_cdaar_1(s7_scheme *sc, s7_pointer lst) { if (!is_pair(lst)) method_or_bust(sc, lst, sc->CDAAR, set_plist_1(sc, lst), T_PAIR, 0); if (!is_pair(car(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CDAAR, lst, CAR_A_LIST)); if (!is_pair(car(car(lst)))) return(simple_wrong_type_argument_with_type(sc, sc->CDAAR, lst, CAAR_A_LIST)); return(cdaar(lst)); } static s7_pointer g_cdaar(s7_scheme *sc, s7_pointer args) { #define H_cdaar "(cdaar lst) returns (cdr (car (car lst))): (cdaar '(((1 2 3)))) -> '(2 3)" #define Q_cdaar pl_p return(g_cdaar_1(sc, car(args))); } PF_TO_PF(cdaar, g_cdaar_1) /* -------- caddr -------- */ static s7_pointer g_caddr_1(s7_scheme *sc, s7_pointer lst) { if (!is_pair(lst)) method_or_bust(sc, lst, sc->CADDR, set_plist_1(sc, lst), T_PAIR, 0); if (!is_pair(cdr(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CADDR, lst, CDR_A_LIST)); if (!is_pair(cdr(cdr(lst)))) return(simple_wrong_type_argument_with_type(sc, sc->CADDR, lst, CDDR_A_LIST)); return(caddr(lst)); } static s7_pointer g_caddr(s7_scheme *sc, s7_pointer args) { #define H_caddr "(caddr lst) returns (car (cdr (cdr lst))): (caddr '(1 2 3 4)) -> 3" #define Q_caddr pl_p return(g_caddr_1(sc, car(args))); } PF_TO_PF(caddr, g_caddr_1) /* -------- cdddr -------- */ static s7_pointer g_cdddr_1(s7_scheme *sc, s7_pointer lst) { if (!is_pair(lst)) method_or_bust(sc, lst, sc->CDDDR, set_plist_1(sc, lst), T_PAIR, 0); if (!is_pair(cdr(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CDDDR, lst, CDR_A_LIST)); if (!is_pair(cdr(cdr(lst)))) return(simple_wrong_type_argument_with_type(sc, sc->CDDDR, lst, CDDR_A_LIST)); return(cdddr(lst)); } static s7_pointer g_cdddr(s7_scheme *sc, s7_pointer args) { #define H_cdddr "(cdddr lst) returns (cdr (cdr (cdr lst))): (cdddr '(1 2 3 4)) -> '(4)" #define Q_cdddr pl_p return(g_cdddr_1(sc, car(args))); } PF_TO_PF(cdddr, g_cdddr_1) /* -------- cdadr -------- */ static s7_pointer g_cdadr_1(s7_scheme *sc, s7_pointer lst) { if (!is_pair(lst)) method_or_bust(sc, lst, sc->CDADR, set_plist_1(sc, lst), T_PAIR, 0); if (!is_pair(cdr(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CDADR, lst, CDR_A_LIST)); if (!is_pair(car(cdr(lst)))) return(simple_wrong_type_argument_with_type(sc, sc->CDADR, lst, CADR_A_LIST)); return(cdadr(lst)); } static s7_pointer g_cdadr(s7_scheme *sc, s7_pointer args) { #define H_cdadr "(cdadr lst) returns (cdr (car (cdr lst))): (cdadr '(1 (2 3 4))) -> '(3 4)" #define Q_cdadr pl_p return(g_cdadr_1(sc, car(args))); } PF_TO_PF(cdadr, g_cdadr_1) /* -------- cddar -------- */ static s7_pointer g_cddar_1(s7_scheme *sc, s7_pointer lst) { if (!is_pair(lst)) method_or_bust(sc, lst, sc->CDDAR, set_plist_1(sc, lst), T_PAIR, 0); if (!is_pair(car(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CDDAR, lst, CAR_A_LIST)); if (!is_pair(cdr(car(lst)))) return(simple_wrong_type_argument_with_type(sc, sc->CDDAR, lst, CDAR_A_LIST)); return(cddar(lst)); } static s7_pointer g_cddar(s7_scheme *sc, s7_pointer args) { #define H_cddar "(cddar lst) returns (cdr (cdr (car lst))): (cddar '((1 2 3 4))) -> '(3 4)" #define Q_cddar pl_p return(g_cddar_1(sc, car(args))); } PF_TO_PF(cddar, g_cddar_1) /* -------- caaaar -------- */ static s7_pointer g_caaaar_1(s7_scheme *sc, s7_pointer lst) { if (!is_pair(lst)) method_or_bust(sc, lst, sc->CAAAAR, set_plist_1(sc, lst), T_PAIR, 0); if (!is_pair(car(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CAAAAR, lst, CAR_A_LIST)); if (!is_pair(caar(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CAAAAR, lst, CAAR_A_LIST)); if (!is_pair(caaar(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CAAAAR, lst, CAAAR_A_LIST)); return(caaaar(lst)); } static s7_pointer g_caaaar(s7_scheme *sc, s7_pointer args) { #define H_caaaar "(caaaar lst) returns (car (car (car (car lst)))): (caaaar '((((1 2))))) -> 1" #define Q_caaaar pl_p return(g_caaaar_1(sc, car(args))); } PF_TO_PF(caaaar, g_caaaar_1) /* -------- caaadr -------- */ static s7_pointer g_caaadr_1(s7_scheme *sc, s7_pointer lst) { if (!is_pair(lst)) method_or_bust(sc, lst, sc->CAAADR, set_plist_1(sc, lst), T_PAIR, 0); if (!is_pair(cdr(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CAAADR, lst, CDR_A_LIST)); if (!is_pair(cadr(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CAAADR, lst, CADR_A_LIST)); if (!is_pair(caadr(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CAAADR, lst, CAADR_A_LIST)); return(caaadr(lst)); } static s7_pointer g_caaadr(s7_scheme *sc, s7_pointer args) { #define H_caaadr "(caaadr lst) returns (car (car (car (cdr lst)))): (caaadr '(1 ((2 3)))) -> 2" #define Q_caaadr pl_p return(g_caaadr_1(sc, car(args))); } PF_TO_PF(caaadr, g_caaadr_1) /* -------- caadar -------- */ static s7_pointer g_caadar_1(s7_scheme *sc, s7_pointer lst) { if (!is_pair(lst)) method_or_bust(sc, lst, sc->CAADAR, set_plist_1(sc, lst), T_PAIR, 0); if (!is_pair(car(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CAADAR, lst, CAR_A_LIST)); if (!is_pair(cdar(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CAADAR, lst, CDAR_A_LIST)); if (!is_pair(cadar(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CAADAR, lst, CADAR_A_LIST)); return(caadar(lst)); } static s7_pointer g_caadar(s7_scheme *sc, s7_pointer args) { #define H_caadar "(caadar lst) returns (car (car (cdr (car lst)))): (caadar '((1 (2 3)))) -> 2" #define Q_caadar pl_p return(g_caadar_1(sc, car(args))); } PF_TO_PF(caadar, g_caadar_1) /* -------- cadaar -------- */ static s7_pointer g_cadaar_1(s7_scheme *sc, s7_pointer lst) { if (!is_pair(lst)) method_or_bust(sc, lst, sc->CADAAR, set_plist_1(sc, lst), T_PAIR, 0); if (!is_pair(car(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CADAAR, lst, CAR_A_LIST)); if (!is_pair(caar(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CADAAR, lst, CAAR_A_LIST)); if (!is_pair(cdaar(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CADAAR, lst, CDAAR_A_LIST)); return(cadaar(lst)); } static s7_pointer g_cadaar(s7_scheme *sc, s7_pointer args) { #define H_cadaar "(cadaar lst) returns (car (cdr (car (car lst)))): (cadaar '(((1 2 3)))) -> 2" #define Q_cadaar pl_p return(g_cadaar_1(sc, car(args))); } PF_TO_PF(cadaar, g_cadaar_1) /* -------- caaddr -------- */ static s7_pointer g_caaddr_1(s7_scheme *sc, s7_pointer lst) { if (!is_pair(lst)) method_or_bust(sc, lst, sc->CAADDR, set_plist_1(sc, lst), T_PAIR, 0); if (!is_pair(cdr(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CAADDR, lst, CDR_A_LIST)); if (!is_pair(cddr(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CAADDR, lst, CDDR_A_LIST)); if (!is_pair(caddr(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CAADDR, lst, CADDR_A_LIST)); return(caaddr(lst)); } static s7_pointer g_caaddr(s7_scheme *sc, s7_pointer args) { #define H_caaddr "(caaddr lst) returns (car (car (cdr (cdr lst)))): (caaddr '(1 2 (3 4))) -> 3" #define Q_caaddr pl_p return(g_caaddr_1(sc, car(args))); } PF_TO_PF(caaddr, g_caaddr_1) /* -------- cadddr -------- */ static s7_pointer g_cadddr_1(s7_scheme *sc, s7_pointer lst) { if (!is_pair(lst)) method_or_bust(sc, lst, sc->CADDDR, set_plist_1(sc, lst), T_PAIR, 0); if (!is_pair(cdr(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CADDDR, lst, CDR_A_LIST)); if (!is_pair(cddr(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CADDDR, lst, CDDR_A_LIST)); if (!is_pair(cdddr(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CADDDR, lst, CDDDR_A_LIST)); return(cadddr(lst)); } static s7_pointer g_cadddr(s7_scheme *sc, s7_pointer args) { #define H_cadddr "(cadddr lst) returns (car (cdr (cdr (cdr lst)))): (cadddr '(1 2 3 4 5)) -> 4" #define Q_cadddr pl_p return(g_cadddr_1(sc, car(args))); } PF_TO_PF(cadddr, g_cadddr_1) /* -------- cadadr -------- */ static s7_pointer g_cadadr_1(s7_scheme *sc, s7_pointer lst) { if (!is_pair(lst)) method_or_bust(sc, lst, sc->CADADR, set_plist_1(sc, lst), T_PAIR, 0); if (!is_pair(cdr(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CADADR, lst, CDR_A_LIST)); if (!is_pair(cadr(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CADADR, lst, CADR_A_LIST)); if (!is_pair(cdadr(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CADADR, lst, CDADR_A_LIST)); return(cadadr(lst)); } static s7_pointer g_cadadr(s7_scheme *sc, s7_pointer args) { #define H_cadadr "(cadadr lst) returns (car (cdr (car (cdr lst)))): (cadadr '(1 (2 3 4))) -> 3" #define Q_cadadr pl_p return(g_cadadr_1(sc, car(args))); } PF_TO_PF(cadadr, g_cadadr_1) /* -------- caddar -------- */ static s7_pointer g_caddar_1(s7_scheme *sc, s7_pointer lst) { if (!is_pair(lst)) method_or_bust(sc, lst, sc->CADDAR, set_plist_1(sc, lst), T_PAIR, 0); if (!is_pair(car(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CADDAR, lst, CAR_A_LIST)); if (!is_pair(cdar(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CADDAR, lst, CDAR_A_LIST)); if (!is_pair(cddar(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CADDAR, lst, CDDAR_A_LIST)); return(caddar(lst)); } static s7_pointer g_caddar(s7_scheme *sc, s7_pointer args) { #define H_caddar "(caddar lst) returns (car (cdr (cdr (car lst)))): (caddar '((1 2 3 4))) -> 3" #define Q_caddar pl_p return(g_caddar_1(sc, car(args))); } PF_TO_PF(caddar, g_caddar_1) /* -------- cdaaar -------- */ static s7_pointer g_cdaaar_1(s7_scheme *sc, s7_pointer lst) { if (!is_pair(lst)) method_or_bust(sc, lst, sc->CDAAAR, set_plist_1(sc, lst), T_PAIR, 0); if (!is_pair(car(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CDAAAR, lst, CAR_A_LIST)); if (!is_pair(caar(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CDAAAR, lst, CAAR_A_LIST)); if (!is_pair(caaar(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CDAAAR, lst, CAAAR_A_LIST)); return(cdaaar(lst)); } static s7_pointer g_cdaaar(s7_scheme *sc, s7_pointer args) { #define H_cdaaar "(cdaaar lst) returns (cdr (car (car (car lst)))): (cdaaar '((((1 2 3))))) -> '(2 3)" #define Q_cdaaar pl_p return(g_cdaaar_1(sc, car(args))); } PF_TO_PF(cdaaar, g_cdaaar_1) /* -------- cdaadr -------- */ static s7_pointer g_cdaadr_1(s7_scheme *sc, s7_pointer lst) { if (!is_pair(lst)) method_or_bust(sc, lst, sc->CDAADR, set_plist_1(sc, lst), T_PAIR, 0); if (!is_pair(cdr(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CDAADR, lst, CDR_A_LIST)); if (!is_pair(cadr(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CDAADR, lst, CADR_A_LIST)); if (!is_pair(caadr(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CDAADR, lst, CAADR_A_LIST)); return(cdaadr(lst)); } static s7_pointer g_cdaadr(s7_scheme *sc, s7_pointer args) { #define H_cdaadr "(cdaadr lst) returns (cdr (car (car (cdr lst)))): (cdaadr '(1 ((2 3 4)))) -> '(3 4)" #define Q_cdaadr pl_p return(g_cdaadr_1(sc, car(args))); } PF_TO_PF(cdaadr, g_cdaadr_1) /* -------- cdadar -------- */ static s7_pointer g_cdadar_1(s7_scheme *sc, s7_pointer lst) { if (!is_pair(lst)) method_or_bust(sc, lst, sc->CDADAR, set_plist_1(sc, lst), T_PAIR, 0); if (!is_pair(car(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CDADAR, lst, CAR_A_LIST)); if (!is_pair(cdar(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CDADAR, lst, CDAR_A_LIST)); if (!is_pair(cadar(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CDADAR, lst, CADAR_A_LIST)); return(cdadar(lst)); } static s7_pointer g_cdadar(s7_scheme *sc, s7_pointer args) { #define H_cdadar "(cdadar lst) returns (cdr (car (cdr (car lst)))): (cdadar '((1 (2 3 4)))) -> '(3 4)" #define Q_cdadar pl_p return(g_cdadar_1(sc, car(args))); } PF_TO_PF(cdadar, g_cdadar_1) /* -------- cddaar -------- */ static s7_pointer g_cddaar_1(s7_scheme *sc, s7_pointer lst) { if (!is_pair(lst)) method_or_bust(sc, lst, sc->CDDAAR, set_plist_1(sc, lst), T_PAIR, 0); if (!is_pair(car(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CDDAAR, lst, CAR_A_LIST)); if (!is_pair(caar(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CDDAAR, lst, CAAR_A_LIST)); if (!is_pair(cdaar(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CDDAAR, lst, CDAAR_A_LIST)); return(cddaar(lst)); } static s7_pointer g_cddaar(s7_scheme *sc, s7_pointer args) { #define H_cddaar "(cddaar lst) returns (cdr (cdr (car (car lst)))): (cddaar '(((1 2 3 4)))) -> '(3 4)" #define Q_cddaar pl_p return(g_cddaar_1(sc, car(args))); } PF_TO_PF(cddaar, g_cddaar_1) /* -------- cdaddr -------- */ static s7_pointer g_cdaddr_1(s7_scheme *sc, s7_pointer lst) { if (!is_pair(lst)) method_or_bust(sc, lst, sc->CDADDR, set_plist_1(sc, lst), T_PAIR, 0); if (!is_pair(cdr(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CDADDR, lst, CDR_A_LIST)); if (!is_pair(cddr(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CDADDR, lst, CDDR_A_LIST)); if (!is_pair(caddr(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CDADDR, lst, CADDR_A_LIST)); return(cdaddr(lst)); } static s7_pointer g_cdaddr(s7_scheme *sc, s7_pointer args) { #define H_cdaddr "(cdaddr lst) returns (cdr (car (cdr (cdr lst)))): (cdaddr '(1 2 (3 4 5))) -> '(4 5)" #define Q_cdaddr pl_p return(g_cdaddr_1(sc, car(args))); } PF_TO_PF(cdaddr, g_cdaddr_1) /* -------- cddddr -------- */ static s7_pointer g_cddddr_1(s7_scheme *sc, s7_pointer lst) { if (!is_pair(lst)) method_or_bust(sc, lst, sc->CDDDDR, set_plist_1(sc, lst), T_PAIR, 0); if (!is_pair(cdr(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CDDDDR, lst, CDR_A_LIST)); if (!is_pair(cddr(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CDDDDR, lst, CDDR_A_LIST)); if (!is_pair(cdddr(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CDDDDR, lst, CDDDR_A_LIST)); return(cddddr(lst)); } static s7_pointer g_cddddr(s7_scheme *sc, s7_pointer args) { #define H_cddddr "(cddddr lst) returns (cdr (cdr (cdr (cdr lst)))): (cddddr '(1 2 3 4 5)) -> '(5)" #define Q_cddddr pl_p return(g_cddddr_1(sc, car(args))); } PF_TO_PF(cddddr, g_cddddr_1) /* -------- cddadr -------- */ static s7_pointer g_cddadr_1(s7_scheme *sc, s7_pointer lst) { if (!is_pair(lst)) method_or_bust(sc, lst, sc->CDDADR, set_plist_1(sc, lst), T_PAIR, 0); if (!is_pair(cdr(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CDDADR, lst, CDR_A_LIST)); if (!is_pair(cadr(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CDDADR, lst, CADR_A_LIST)); if (!is_pair(cdadr(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CDDADR, lst, CDADR_A_LIST)); return(cddadr(lst)); } static s7_pointer g_cddadr(s7_scheme *sc, s7_pointer args) { #define H_cddadr "(cddadr lst) returns (cdr (cdr (car (cdr lst)))): (cddadr '(1 (2 3 4 5))) -> '(4 5)" #define Q_cddadr pl_p return(g_cddadr_1(sc, car(args))); } PF_TO_PF(cddadr, g_cddadr_1) /* -------- cdddar -------- */ static s7_pointer g_cdddar_1(s7_scheme *sc, s7_pointer lst) { if (!is_pair(lst)) method_or_bust(sc, lst, sc->CDDDAR, set_plist_1(sc, lst), T_PAIR, 0); if (!is_pair(car(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CDDDAR, lst, CAR_A_LIST)); if (!is_pair(cdar(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CDDDAR, lst, CDAR_A_LIST)); if (!is_pair(cddar(lst))) return(simple_wrong_type_argument_with_type(sc, sc->CDDDAR, lst, CDDAR_A_LIST)); return(cdddar(lst)); } static s7_pointer g_cdddar(s7_scheme *sc, s7_pointer args) { #define H_cdddar "(cdddar lst) returns (cdr (cdr (cdr (car lst)))): (cdddar '((1 2 3 4 5))) -> '(4 5)" #define Q_cdddar pl_p return(g_cdddar_1(sc, car(args))); } PF_TO_PF(cdddar, g_cdddar_1) s7_pointer s7_assq(s7_scheme *sc, s7_pointer obj, s7_pointer x) { s7_pointer y; y = x; while (true) { /* we can blithely take the car of anything, since we're not treating it as an object, * then if we get a bogus match, the following check that caar made sense ought to catch it. * * if car(#) = # (initialization time), then cdr(nil)->unspec * and subsequent caar(unspc)->unspec so we could forgo half the is_pair checks below. * This breaks if "x" is a dotted list -- the last cdr is not nil, so we lose. */ if ((obj == unchecked_car(car(x))) && (is_pair(car(x)))) return(car(x)); x = cdr(x); if (!is_pair(x)) return(sc->F); if ((obj == unchecked_car(car(x))) && (is_pair(car(x)))) return(car(x)); x = cdr(x); if (!is_pair(x)) return(sc->F); if ((obj == unchecked_car(car(x))) && (is_pair(car(x)))) return(car(x)); x = cdr(x); if (!is_pair(x)) return(sc->F); if ((obj == unchecked_car(car(x))) && (is_pair(car(x)))) return(car(x)); x = cdr(x); if (!is_pair(x)) return(sc->F); if ((obj == unchecked_car(car(x))) && (is_pair(car(x)))) return(car(x)); x = cdr(x); if (!is_pair(x)) return(sc->F); if ((obj == unchecked_car(car(x))) && (is_pair(car(x)))) return(car(x)); x = cdr(x); if (!is_pair(x)) return(sc->F); y = cdr(y); if (x == y) return(sc->F); } return(sc->F); /* not reached */ } #if (!WITH_PURE_S7) static s7_pointer c_assq(s7_scheme *sc, s7_pointer x, s7_pointer y) { if (!is_pair(y)) { if (is_null(y)) return(sc->F); method_or_bust_with_type(sc, y, sc->ASSQ, list_2(sc, x, y), AN_ASSOCIATION_LIST, 2); } /* we don't check for (pair? (car x)) here (or in assv) so we get some inconsistency with assoc: * (assq #f '(#f 2 . 3)) -> #f * (assoc #f '(#f 2 . 3)) -> 'error */ return(s7_assq(sc, x, y)); } static s7_pointer g_assq(s7_scheme *sc, s7_pointer args) { #define H_assq "(assq obj alist) returns the key-value pair associated (via eq?) with the key obj in the association list alist" #define Q_assq s7_make_signature(sc, 3, s7_make_signature(sc, 2, sc->IS_PAIR, sc->IS_BOOLEAN), sc->T, sc->IS_LIST) return(c_assq(sc, car(args), cadr(args))); } PF2_TO_PF(assq, c_assq) #endif static s7_pointer c_assv(s7_scheme *sc, s7_pointer x, s7_pointer y) { s7_pointer z; if (!is_pair(y)) { if (is_null(y)) return(sc->F); method_or_bust_with_type(sc, y, sc->ASSV, list_2(sc, x, y), AN_ASSOCIATION_LIST, 2); } if (is_simple(x)) return(s7_assq(sc, x, y)); z = y; while (true) { /* here we can't play the assq == game because s7_is_eqv thinks it's getting a legit s7 object */ if ((is_pair(car(y))) && (s7_is_eqv(x, caar(y)))) return(car(y)); y = cdr(y); if (!is_pair(y)) return(sc->F); if ((is_pair(car(y))) && (s7_is_eqv(x, caar(y)))) return(car(y)); y = cdr(y); if (!is_pair(y)) return(sc->F); z = cdr(z); if (z == y) return(sc->F); } return(sc->F); /* not reached */ } static s7_pointer g_assv(s7_scheme *sc, s7_pointer args) /* g_assv is called by g_assoc below */ { #define H_assv "(assv obj alist) returns the key-value pair associated (via eqv?) with the key obj in the association list alist" #define Q_assv Q_assq return(c_assv(sc, car(args), cadr(args))); } #if (!WITH_PURE_S7) PF2_TO_PF(assv, c_assv) #endif static s7_pointer all_x_c_ss(s7_scheme *sc, s7_pointer arg); static s7_pointer all_x_c_uu(s7_scheme *sc, s7_pointer arg); static s7_pointer g_is_eq(s7_scheme *sc, s7_pointer args); static s7_pointer g_is_eqv(s7_scheme *sc, s7_pointer args); static s7_pointer g_assoc(s7_scheme *sc, s7_pointer args) { #define H_assoc "(assoc obj alist (func #f)) returns the key-value pair associated (via equal?) with the key obj in the association list alist.\ If 'func' is a function of 2 arguments, it is used for the comparison instead of 'equal?" #define Q_assoc s7_make_signature(sc, 4, s7_make_signature(sc, 2, sc->IS_PAIR, sc->IS_BOOLEAN), sc->T, sc->IS_LIST, sc->IS_PROCEDURE) s7_pointer x, y, obj, eq_func = NULL; x = cadr(args); if (!is_null(x)) { if (!is_pair(x)) method_or_bust_with_type(sc, x, sc->ASSOC, args, AN_ASSOCIATION_LIST, 2); if ((is_pair(x)) && (!is_pair(car(x)))) return(wrong_type_argument_with_type(sc, sc->ASSOC, 2, x, AN_ASSOCIATION_LIST)); /* we're assuming caar below so it better exist */ } if (is_not_null(cddr(args))) { /* check third arg before second (trailing arg error check) */ eq_func = caddr(args); if (type(eq_func) < T_GOTO) method_or_bust_with_type(sc, eq_func, sc->ASSOC, args, A_PROCEDURE, 0); if (!s7_is_aritable(sc, eq_func, 2)) return(wrong_type_argument_with_type(sc, sc->ASSOC, 3, eq_func, AN_EQ_FUNC)); } if (is_null(x)) return(sc->F); if (eq_func) { /* now maybe there's a simple case */ if (s7_list_length(sc, x) > 0) { if ((is_safe_procedure(eq_func)) && (is_c_function(eq_func))) { s7_function func; func = c_function_call(eq_func); if (func == g_is_eq) return(s7_assq(sc, car(args), x)); if (func == g_is_eqv) return(g_assv(sc, args)); car(sc->T2_1) = car(args); for (; is_pair(x); x = cdr(x)) { if (is_pair(car(x))) { car(sc->T2_2) = caar(x); if (is_true(sc, func(sc, sc->T2_1))) return(car(x)); /* I wonder if the assoc equality function should get the cons, not just caar? */ } else return(wrong_type_argument_with_type(sc, sc->ASSOC, 2, cadr(args), AN_ASSOCIATION_LIST)); } return(sc->F); } /* lg auto? */ if ((is_closure(eq_func)) && (is_pair(closure_args(eq_func))) && (is_pair(cdr(closure_args(eq_func))))) /* not dotted arg list */ { s7_pointer body; body = closure_body(eq_func); if ((is_optimized(car(body))) && (is_null(cdr(body))) && (is_all_x_safe(sc, car(body)))) { s7_function func; s7_pointer b; new_frame_with_two_slots(sc, sc->envir, sc->envir, car(closure_args(eq_func)), car(args), cadr(closure_args(eq_func)), sc->F); func = all_x_eval(sc, car(body), sc->envir, let_symbol_is_safe); /* safe since local */ b = next_slot(let_slots(sc->envir)); for (; is_pair(x); x = cdr(x)) { slot_set_value(b, caar(x)); if (is_true(sc, func(sc, car(body)))) return(car(x)); } return(sc->F); } } } /* sc->value = sc->F; */ y = cons(sc, args, sc->NIL); set_opt_fast(y, x); set_opt_slow(y, x); push_stack(sc, OP_ASSOC_IF, y, eq_func); push_stack(sc, OP_APPLY, list_2(sc, car(args), caar(x)), eq_func); return(sc->UNSPECIFIED); } x = cadr(args); obj = car(args); if (is_simple(obj)) return(s7_assq(sc, obj, x)); y = x; if (is_string(obj)) { s7_pointer val; while (true) { if (is_pair(car(x))) { val = caar(x); if ((val == obj) || ((is_string(val)) && (scheme_strings_are_equal(obj, val)))) return(car(x)); } x = cdr(x); if (!is_pair(x)) return(sc->F); if (is_pair(car(x))) { val = caar(x); if ((val == obj) || ((is_string(val)) && (scheme_strings_are_equal(obj, val)))) return(car(x)); } x = cdr(x); if (!is_pair(x)) return(sc->F); y = cdr(y); if (x == y) return(sc->F); } return(sc->F); } while (true) { if ((is_pair(car(x))) && (s7_is_equal(sc, obj, caar(x)))) return(car(x)); x = cdr(x); if (!is_pair(x)) return(sc->F); if ((is_pair(car(x))) && (s7_is_equal(sc, obj, caar(x)))) return(car(x)); x = cdr(x); if (!is_pair(x)) return(sc->F); y = cdr(y); if (x == y) return(sc->F); } return(sc->F); /* not reached */ } static s7_pointer c_assoc(s7_scheme *sc, s7_pointer x, s7_pointer y) {return(g_assoc(sc, set_plist_2(sc, x, y)));} PF2_TO_PF(assoc, c_assoc) /* ---------------- member, memv, memq ---------------- */ s7_pointer s7_memq(s7_scheme *sc, s7_pointer obj, s7_pointer x) { s7_pointer y; y = x; while (true) { if (obj == car(x)) return(x); x = cdr(x); if (!is_pair(x)) return(sc->F); if (obj == car(x)) return(x); x = cdr(x); if (!is_pair(x)) return(sc->F); if (obj == car(x)) return(x); x = cdr(x); if (!is_pair(x)) return(sc->F); if (obj == car(x)) return(x); x = cdr(x); if (!is_pair(x)) return(sc->F); y = cdr(y); if (x == y) return(sc->F); } return(sc->F); } #if (!WITH_PURE_S7) static s7_pointer c_memq(s7_scheme *sc, s7_pointer x, s7_pointer y) { if (!is_pair(y)) { if (is_null(y)) return(sc->F); method_or_bust_with_type(sc, y, sc->MEMQ, list_2(sc, x, y), A_LIST, 2); } return(s7_memq(sc, x, y)); } static s7_pointer g_memq(s7_scheme *sc, s7_pointer args) { #define H_memq "(memq obj list) looks for obj in list and returns the list from that point if it is found, otherwise #f. memq uses eq?" #define Q_memq pl_tp return(c_memq(sc, car(args), cadr(args))); } PF2_TO_PF(memq, c_memq) #endif /* I think (memq 'c '(a b . c)) should return #f because otherwise * (memq () ...) would return the () at the end. */ /* if memq's list is a quoted list, it won't be changing, so we can tell ahead of time that it is * a proper list, and what its length is. */ static s7_pointer memq_3, memq_4, memq_any; static s7_pointer g_memq_3(s7_scheme *sc, s7_pointer args) { s7_pointer x, obj; x = cadr(args); obj = car(args); while (true) { if (obj == car(x)) return(x); x = cdr(x); if (obj == car(x)) return(x); x = cdr(x); if (obj == car(x)) return(x); x = cdr(x); if (!is_pair(x)) return(sc->F); } return(sc->F); } static s7_pointer g_memq_4(s7_scheme *sc, s7_pointer args) { s7_pointer x, obj; x = cadr(args); obj = car(args); while (true) { if (obj == car(x)) return(x); x = cdr(x); if (obj == car(x)) return(x); x = cdr(x); if (obj == car(x)) return(x); x = cdr(x); if (obj == car(x)) return(x); x = cdr(x); if (!is_pair(x)) return(sc->F); } return(sc->F); } static s7_pointer g_memq_any(s7_scheme *sc, s7_pointer args) { /* no circular list check needed in this case */ s7_pointer x, obj; x = cadr(args); obj = car(args); while (true) { if (obj == car(x)) return(x); x = cdr(x); if (!is_pair(x)) return(sc->F); /* every other pair check could be omitted */ if (obj == car(x)) return(x); x = cdr(x); if (!is_pair(x)) return(sc->F); if (obj == car(x)) return(x); x = cdr(x); if (!is_pair(x)) return(sc->F); if (obj == car(x)) return(x); x = cdr(x); if (!is_pair(x)) return(sc->F); } return(sc->F); } static s7_pointer memq_car; static s7_pointer g_memq_car(s7_scheme *sc, s7_pointer args) { s7_pointer x, obj; obj = find_symbol_checked(sc, cadar(args)); if (!is_pair(obj)) { s7_pointer func; if ((has_methods(obj)) && ((func = find_method(sc, find_let(sc, obj), sc->CAR)) != sc->UNDEFINED)) obj = s7_apply_function(sc, func, list_1(sc, obj)); if (!is_pair(obj)) return(simple_wrong_type_argument(sc, sc->CAR, obj, T_PAIR)); } obj = car(obj); x = cadr(cadr(args)); while (true) { if (obj == car(x)) return(x); x = cdr(x); if (!is_pair(x)) return(sc->F); if (obj == car(x)) return(x); x = cdr(x); if (!is_pair(x)) return(sc->F); } return(sc->F); } static s7_pointer memq_chooser(s7_scheme *sc, s7_pointer f, int args, s7_pointer expr) { if ((is_pair(caddr(expr))) && (car(caddr(expr)) == sc->QUOTE) && (is_pair(cadr(caddr(expr))))) { int len; if ((is_h_safe_c_s(cadr(expr))) && (c_callee(cadr(expr)) == g_car)) { set_optimize_op(expr, HOP_SAFE_C_C); return(memq_car); } len = s7_list_length(sc, cadr(caddr(expr))); if (len > 0) { if ((len % 4) == 0) return(memq_4); if ((len % 3) == 0) return(memq_3); return(memq_any); } } return(f); } static s7_pointer memv_number(s7_scheme *sc, s7_pointer obj, s7_pointer x) { s7_pointer y; y = x; while (true) { if ((s7_is_number(car(x))) && (numbers_are_eqv(obj, car(x)))) return(x); x = cdr(x); if (!is_pair(x)) return(sc->F); if ((s7_is_number(car(x))) && (numbers_are_eqv(obj, car(x)))) return(x); x = cdr(x); if (!is_pair(x)) return(sc->F); if ((s7_is_number(car(x))) && (numbers_are_eqv(obj, car(x)))) return(x); x = cdr(x); if (!is_pair(x)) return(sc->F); if ((s7_is_number(car(x))) && (numbers_are_eqv(obj, car(x)))) return(x); x = cdr(x); if (!is_pair(x)) return(sc->F); y = cdr(y); if (x == y) return(sc->F); } return(sc->F); } static s7_pointer c_memv(s7_scheme *sc, s7_pointer x, s7_pointer y) { s7_pointer z; if (!is_pair(y)) { if (is_null(y)) return(sc->F); method_or_bust_with_type(sc, y, sc->MEMV, list_2(sc, x, y), A_LIST, 2); } if (is_simple(x)) return(s7_memq(sc, x, y)); if (s7_is_number(x)) return(memv_number(sc, x, y)); z = y; while (true) { if (s7_is_eqv(x, car(y))) return(y); y = cdr(y); if (!is_pair(y)) return(sc->F); if (s7_is_eqv(x, car(y))) return(y); y = cdr(y); if (!is_pair(y)) return(sc->F); z = cdr(z); if (z == y) return(sc->F); } return(sc->F); /* not reached */ } static s7_pointer g_memv(s7_scheme *sc, s7_pointer args) { #define H_memv "(memv obj list) looks for obj in list and returns the list from that point if it is found, otherwise #f. memv uses eqv?" #define Q_memv pl_tp return(c_memv(sc, car(args), cadr(args))); } #if (!WITH_PURE_S7) PF2_TO_PF(memv, c_memv) #endif static s7_pointer member(s7_scheme *sc, s7_pointer obj, s7_pointer x) { s7_pointer y; y = x; if (is_string(obj)) { while (true) { if ((obj == car(x)) || ((is_string(car(x))) && (scheme_strings_are_equal(obj, car(x))))) return(x); x = cdr(x); if (!is_pair(x)) return(sc->F); if ((obj == car(x)) || ((is_string(car(x))) && (scheme_strings_are_equal(obj, car(x))))) return(x); x = cdr(x); if (!is_pair(x)) return(sc->F); y = cdr(y); if (x == y) return(sc->F); } return(sc->F); } while (true) { if (s7_is_equal(sc, obj, car(x))) return(x); x = cdr(x); if (!is_pair(x)) return(sc->F); if (s7_is_equal(sc, obj, car(x))) return(x); x = cdr(x); if (!is_pair(x)) return(sc->F); if (s7_is_equal(sc, obj, car(x))) return(x); x = cdr(x); if (!is_pair(x)) return(sc->F); if (s7_is_equal(sc, obj, car(x))) return(x); x = cdr(x); if (!is_pair(x)) return(sc->F); y = cdr(y); if (x == y) return(sc->F); } return(sc->F); /* not reached */ } static s7_pointer g_member(s7_scheme *sc, s7_pointer args) { #define H_member "(member obj list (func #f)) looks for obj in list and returns the list from that point if it is found, otherwise #f. \ member uses equal? If 'func' is a function of 2 arguments, it is used for the comparison instead of 'equal?" #define Q_member s7_make_signature(sc, 4, sc->T, sc->T, sc->IS_LIST, sc->IS_PROCEDURE) /* this could be extended to accept sequences: * (member #\a "123123abnfc" char=?) -> "abnfc" * (member "abc" "123abc321" string=?) -> "abc321" but there's the string length complication * (member 1 #(0 1 2) =) -> #(1 2) etc but what would it do for a hash-table? * the third arg can be weird: (member #f (list #t) cons) -> (#t) -- cons returns '(#f . #t) which is true, so we get '(#t) * should this be an error: (member '(1 2 3) () '(1 . 2)) -- the third arg is bogus, but the second is nil * * here as in assoc, sort, and make-hash-table we accept macros, but I can't think of a good reason to do so. */ s7_pointer x, y, obj, eq_func = NULL; x = cadr(args); if ((!is_pair(x)) && (!is_null(x))) method_or_bust_with_type(sc, x, sc->MEMBER, args, A_LIST, 2); if (is_not_null(cddr(args))) { /* check third arg before second (trailing arg error check) */ eq_func = caddr(args); if (type(eq_func) < T_GOTO) method_or_bust_with_type(sc, eq_func, sc->MEMBER, args, A_PROCEDURE, 3); if (!s7_is_aritable(sc, eq_func, 2)) return(wrong_type_argument_with_type(sc, sc->MEMBER, 3, eq_func, AN_EQ_FUNC)); } if (is_null(x)) return(sc->F); if (eq_func) { /* now maybe there's a simple case */ if (s7_list_length(sc, x) > 0) { if ((is_safe_procedure(eq_func)) && (is_c_function(eq_func))) { s7_function func; func = c_function_call(eq_func); if (func == g_is_eq) return(s7_memq(sc, car(args), x)); if (func == g_is_eqv) return(g_memv(sc, args)); car(sc->T2_1) = car(args); for (; is_pair(x); x = cdr(x)) { car(sc->T2_2) = car(x); if (is_true(sc, func(sc, sc->T2_1))) return(x); } return(sc->F); } if ((is_closure(eq_func)) && (is_pair(closure_args(eq_func))) && (is_pair(cdr(closure_args(eq_func))))) /* not dotted arg list */ { s7_pointer body; body = closure_body(eq_func); if ((is_optimized(car(body))) && (is_null(cdr(body))) && (is_all_x_safe(sc, car(body)))) { s7_function func; func = all_x_eval(sc, car(body), closure_args(eq_func), pair_symbol_is_safe); /* tmap, lg falls through*/ if (((func == all_x_c_ss) || (func == all_x_c_uu)) && (cadar(body) == car(closure_args(eq_func))) && (caddar(body) == cadr(closure_args(eq_func)))) { car(sc->T2_1) = car(args); func = c_callee(car(body)); for (; is_pair(x); x = cdr(x)) { car(sc->T2_2) = car(x); if (is_true(sc, func(sc, sc->T2_1))) return(x); } } else { s7_pointer b; new_frame_with_two_slots(sc, sc->envir, sc->envir, car(closure_args(eq_func)), car(args), cadr(closure_args(eq_func)), sc->F); b = next_slot(let_slots(sc->envir)); for (; is_pair(x); x = cdr(x)) { slot_set_value(b, car(x)); if (is_true(sc, func(sc, car(body)))) return(x); } } return(sc->F); } } } y = cons(sc, args, sc->NIL); /* this could probably be handled with a counter cell (cdr here is unused) */ set_opt_fast(y, x); set_opt_slow(y, x); push_stack(sc, OP_MEMBER_IF, y, eq_func); car(sc->T2_1) = car(args); car(sc->T2_2) = car(x); push_stack(sc, OP_APPLY, sc->T2_1, eq_func); return(sc->UNSPECIFIED); } obj = car(args); if (is_simple(obj)) return(s7_memq(sc, obj, x)); /* the only things that aren't simply == here are c_object, string, number, vector, hash-table, pair, and c_pointer * but all the other cases are unlikely. */ if (s7_is_number(obj)) return(memv_number(sc, obj, x)); return(member(sc, obj, x)); } static s7_pointer c_member(s7_scheme *sc, s7_pointer x, s7_pointer y) {return(g_member(sc, set_plist_2(sc, x, y)));} PF2_TO_PF(member, c_member) static s7_pointer member_sq; static s7_pointer g_member_sq(s7_scheme *sc, s7_pointer args) { s7_pointer obj, lst; lst = cadr(cadr(args)); obj = find_symbol_checked(sc, car(args)); if (is_simple(obj)) return(s7_memq(sc, obj, lst)); if (s7_is_number(obj)) return(memv_number(sc, obj, lst)); return(member(sc, obj, lst)); } static s7_pointer member_num_s; static s7_pointer g_member_num_s(s7_scheme *sc, s7_pointer args) { s7_pointer lst; lst = find_symbol_checked(sc, cadr(args)); if (!is_pair(lst)) { if (is_null(lst)) return(sc->F); method_or_bust_with_type(sc, lst, sc->MEMBER, list_2(sc, car(args), lst), A_LIST, 2); } return(memv_number(sc, car(args), lst)); } static s7_pointer member_ss; static s7_pointer g_member_ss(s7_scheme *sc, s7_pointer args) { s7_pointer obj, x; obj = find_symbol_checked(sc, car(args)); x = find_symbol_checked(sc, cadr(args)); if (!is_pair(x)) { if (is_null(x)) return(sc->F); method_or_bust_with_type(sc, x, sc->MEMBER, list_2(sc, obj, x), A_LIST, 2); } if (is_simple(obj)) return(s7_memq(sc, obj, x)); if (s7_is_number(obj)) return(memv_number(sc, obj, x)); return(member(sc, obj, x)); } static s7_pointer member_chooser(s7_scheme *sc, s7_pointer f, int args, s7_pointer expr) { if (args == 2) { if (is_symbol(caddr(expr))) { if (s7_is_number(cadr(expr))) { set_optimize_op(expr, HOP_SAFE_C_C); return(member_num_s); /* (member 4 lst) */ } if (is_symbol(cadr(expr))) { set_optimize_op(expr, HOP_SAFE_C_C); return(member_ss); /* (member obj lst) */ } } else { if ((is_symbol(cadr(expr))) && (is_pair(caddr(expr))) && (car(caddr(expr)) == sc->QUOTE) && (is_pair(cadr(caddr(expr))))) { set_optimize_op(expr, HOP_SAFE_C_C); return(member_sq); /* (member q '(quote lambda case)) */ } } } if ((args == 3) && (is_symbol(cadddr(expr))) && (cadddr(expr) == sc->IS_EQ)) return(memq_chooser(sc, f, 2, expr)); return(f); } static bool is_memq(s7_pointer sym, s7_pointer lst) { s7_pointer x; for (x = lst; is_pair(x); x = cdr(x)) if (sym == car(x)) return(true); return(false); } static s7_pointer c_is_provided(s7_scheme *sc, s7_pointer sym) { s7_pointer topf, x; if (!is_symbol(sym)) method_or_bust(sc, sym, sc->IS_PROVIDED, list_1(sc, sym), T_SYMBOL, 0); /* here the *features* list is spread out (or can be anyway) along the curlet chain, * so we need to travel back all the way to the top level checking each *features* list in turn. * Since *features* grows via cons (newest first), we can stop the scan if we hit the shared * top-level at least. */ topf = slot_value(global_slot(sc->S7_FEATURES)); if (is_memq(sym, topf)) return(sc->T); if (is_global(sc->S7_FEATURES)) return(sc->F); for (x = sc->envir; symbol_id(sc->S7_FEATURES) < let_id(x); x = outlet(x)); for (; is_let(x); x = outlet(x)) { s7_pointer y; for (y = let_slots(x); is_slot(y); y = next_slot(y)) if (slot_symbol(y) == sc->S7_FEATURES) { if ((slot_value(y) != topf) && (is_memq(sym, slot_value(y)))) return(sc->T); } } return(sc->F); } static s7_pointer g_is_provided(s7_scheme *sc, s7_pointer args) { #define H_is_provided "(provided? symbol) returns #t if symbol is a member of the *features* list" #define Q_is_provided s7_make_signature(sc, 2, sc->IS_BOOLEAN, sc->IS_SYMBOL) return(c_is_provided(sc, car(args))); } bool s7_is_provided(s7_scheme *sc, const char *feature) { return(is_memq(s7_make_symbol(sc, feature), s7_symbol_value(sc, sc->S7_FEATURES))); /* this goes from local outward */ } PF_TO_PF(is_provided, c_is_provided) static s7_pointer c_provide(s7_scheme *sc, s7_pointer sym) { /* this has to be relative to the curlet: (load file env) * the things loaded are only present in env, and go away with it, so should not be in the global *features* list */ s7_pointer p, lst; if (!is_symbol(sym)) method_or_bust(sc, sym, sc->PROVIDE, list_1(sc, sym), T_SYMBOL, 0); p = find_local_symbol(sc, sc->S7_FEATURES, sc->envir); /* if sc->envir is nil, this returns the global slot, else local slot */ lst = slot_value(find_symbol(sc, sc->S7_FEATURES)); /* in either case, we want the current *feartures* list */ if (p == sc->UNDEFINED) make_slot_1(sc, sc->envir, sc->S7_FEATURES, cons(sc, sym, lst)); else { if (!is_memq(sym, lst)) slot_set_value(p, cons(sc, sym, lst)); } if (!is_slot(find_symbol(sc, sym))) /* *features* name might be the same as an existing function */ s7_define(sc, sc->envir, sym, sym); return(sym); } static s7_pointer g_provide(s7_scheme *sc, s7_pointer args) { #define H_provide "(provide symbol) adds symbol to the *features* list" #define Q_provide s7_make_signature(sc, 2, sc->IS_SYMBOL, sc->IS_SYMBOL) return(c_provide(sc, car(args))); } void s7_provide(s7_scheme *sc, const char *feature) { c_provide(sc, s7_make_symbol(sc, feature)); } PF_TO_PF(provide, c_provide) static s7_pointer g_features_set(s7_scheme *sc, s7_pointer args) { /* symbol_access for set/let of *features* which can only be changed via provide */ if (s7_is_list(sc, cadr(args))) return(cadr(args)); return(sc->ERROR); } static s7_pointer g_list(s7_scheme *sc, s7_pointer args) { #define H_list "(list ...) returns its arguments in a list" #define Q_list s7_make_circular_signature(sc, 1, 2, sc->IS_PAIR, sc->T) return(copy_list(sc, args)); } static s7_pointer c_list_1(s7_scheme *sc, s7_pointer x) {return(cons(sc, x, sc->NIL));} PF_TO_PF(list, c_list_1) static s7_pointer list_0, list_1, list_2; static s7_pointer g_list_0(s7_scheme *sc, s7_pointer args) { return(sc->NIL); } static s7_pointer g_list_1(s7_scheme *sc, s7_pointer args) { return(cons(sc, car(args), sc->NIL)); } static s7_pointer g_list_2(s7_scheme *sc, s7_pointer args) { return(cons_unchecked(sc, car(args), cons(sc, cadr(args), sc->NIL))); } static s7_pointer list_chooser(s7_scheme *sc, s7_pointer f, int args, s7_pointer expr) { switch (args) { case 0: return(list_0); case 1: return(list_1); case 2: return(list_2); } return(f); } s7_pointer s7_list(s7_scheme *sc, int num_values, ...) { int i; va_list ap; s7_pointer p; if (num_values == 0) return(sc->NIL); sc->w = sc->NIL; va_start(ap, num_values); for (i = 0; i < num_values; i++) sc->w = cons(sc, va_arg(ap, s7_pointer), sc->w); va_end(ap); p = sc->w; sc->w = sc->NIL; return(safe_reverse_in_place(sc, p)); } static s7_int sequence_length(s7_scheme *sc, s7_pointer lst); static s7_pointer g_list_append(s7_scheme *sc, s7_pointer args) { s7_pointer y, tp, np = NULL, pp; /* we know here that args is a pair and cdr(args) is a pair */ tp = sc->NIL; for (y = args; is_pair(y); y = cdr(y)) /* arglist so not dotted */ { s7_pointer p; p = car(y); check_method(sc, p, sc->APPEND, (is_null(tp)) ? args : cons(sc, tp, y)); if (is_null(cdr(y))) { if (is_null(tp)) return(p); if ((s7_is_list(sc, p)) || (!is_sequence(p))) cdr(np) = p; else { s7_int len; len = sequence_length(sc, p); if (len > 0) cdr(np) = s7_copy(sc, set_plist_2(sc, p, make_list(sc, len, sc->F))); else { if (len < 0) cdr(np) = p; } } sc->y = sc->NIL; return(tp); } if (!is_sequence(p)) return(wrong_type_argument_with_type(sc, sc->APPEND, position_of(y, args), p, A_SEQUENCE)); if (!is_null(p)) { if (is_pair(p)) { if (!is_proper_list(sc, p)) { sc->y = sc->NIL; return(wrong_type_argument_with_type(sc, sc->APPEND, position_of(y, args), p, A_PROPER_LIST)); } /* is this error correct? * (append '(3) '(1 . 2)) -> '(3 1 . 2) ; (old) guile also returns this * but (append '(1 . 2) '(3)) -> this error */ if (is_null(tp)) { tp = cons(sc, car(p), sc->NIL); np = tp; sc->y = tp; /* GC protect? */ pp = cdr(p); } else pp = p; for (; is_pair(pp); pp = cdr(pp), np = cdr(np)) cdr(np) = cons(sc, car(pp), sc->NIL); } else { s7_int len; len = sequence_length(sc, p); if (len > 0) { if (is_null(tp)) { tp = s7_copy(sc, set_plist_2(sc, p, make_list(sc, len, sc->F))); np = tp; sc->y = tp; } else cdr(np) = s7_copy(sc, set_plist_2(sc, p, make_list(sc, len, sc->F))); for (; is_pair(cdr(np)); np = cdr(np)); } else { if (len < 0) return(wrong_type_argument_with_type(sc, sc->APPEND, position_of(y, args), p, A_SEQUENCE)); } } } } return(tp); } static s7_pointer append_in_place(s7_scheme *sc, s7_pointer a, s7_pointer b) { /* tack b onto the end of a without copying either -- 'a' is changed! */ s7_pointer p; if (is_null(a)) return(b); p = a; while (is_not_null(cdr(p))) p = cdr(p); cdr(p) = b; return(a); } /* -------------------------------- vectors -------------------------------- */ bool s7_is_vector(s7_pointer p) { return(t_vector_p[type(p)]); } bool s7_is_float_vector(s7_pointer p) { return(type(p) == T_FLOAT_VECTOR); } bool s7_is_int_vector(s7_pointer p) { return(type(p) == T_INT_VECTOR); } static s7_pointer default_vector_setter(s7_scheme *sc, s7_pointer vec, s7_int loc, s7_pointer val) { vector_element(vec, loc) = val; return(val); } static s7_pointer default_vector_getter(s7_scheme *sc, s7_pointer vec, s7_int loc) { return(vector_element(vec, loc)); } static s7_pointer int_vector_setter(s7_scheme *sc, s7_pointer vec, s7_int loc, s7_pointer val) { if (!s7_is_integer(val)) s7_wrong_type_arg_error(sc, "int_vector_set!", 3, val, "an integer"); int_vector_element(vec, loc) = s7_integer(val); return(val); } static s7_pointer int_vector_getter(s7_scheme *sc, s7_pointer vec, s7_int loc) { return(make_integer(sc, int_vector_element(vec, loc))); } static s7_pointer float_vector_setter(s7_scheme *sc, s7_pointer vec, s7_int loc, s7_pointer val) { float_vector_element(vec, loc) = real_to_double(sc, val, "float-vector-set!"); return(val); } static s7_pointer float_vector_getter(s7_scheme *sc, s7_pointer vec, s7_int loc) { return(make_real(sc, float_vector_element(vec, loc))); } static s7_pointer make_vector_1(s7_scheme *sc, s7_int len, bool filled, unsigned int typ) { s7_pointer x; if (len < 0) return(wrong_type_argument_with_type(sc, sc->MAKE_VECTOR, 1, make_integer(sc, len), A_NON_NEGATIVE_INTEGER)); if (len > sc->max_vector_length) return(out_of_range(sc, sc->MAKE_VECTOR, small_int(1), make_integer(sc, len), ITS_TOO_LARGE)); /* this has to follow the error checks! (else garbage in free_heap temps portion confuses GC when "vector" is finalized) */ new_cell(sc, x, typ | T_SAFE_PROCEDURE); /* (v 0) as vector-ref is safe */ vector_length(x) = 0; vector_elements(x) = NULL; vector_dimension_info(x) = NULL; if (len > 0) { vector_length(x) = len; if (typ == T_VECTOR) { vector_elements(x) = (s7_pointer *)malloc(len * sizeof(s7_pointer)); if (!vector_elements(x)) return(s7_error(sc, make_symbol(sc, "out-of-memory"), set_elist_1(sc, make_string_wrapper(sc, "make-vector allocation failed!")))); vector_getter(x) = default_vector_getter; vector_setter(x) = default_vector_setter; if (filled) s7_vector_fill(sc, x, sc->NIL); /* make_hash_table assumes nil as the default value */ } else { if (typ == T_FLOAT_VECTOR) { if (filled) float_vector_elements(x) = (s7_double *)calloc(len, sizeof(s7_double)); else float_vector_elements(x) = (s7_double *)malloc(len * sizeof(s7_double)); if (!float_vector_elements(x)) return(s7_error(sc, make_symbol(sc, "out-of-memory"), set_elist_1(sc, make_string_wrapper(sc, "make-float-vector allocation failed!")))); vector_getter(x) = float_vector_getter; vector_setter(x) = float_vector_setter; } else { if (filled) int_vector_elements(x) = (s7_int *)calloc(len, sizeof(s7_int)); else int_vector_elements(x) = (s7_int *)malloc(len * sizeof(s7_int)); if (!int_vector_elements(x)) return(s7_error(sc, make_symbol(sc, "out-of-memory"), set_elist_1(sc, make_string_wrapper(sc, "make-int-vector allocation failed!")))); vector_getter(x) = int_vector_getter; vector_setter(x) = int_vector_setter; } } } Add_Vector(x); return(x); } s7_pointer s7_make_vector(s7_scheme *sc, s7_int len) { return(make_vector_1(sc, len, FILLED, T_VECTOR)); } static vdims_t *make_wrap_only(s7_scheme *sc) { vdims_t *v; v = (vdims_t *)malloc(sizeof(vdims_t)); v->original = sc->F; v->elements_allocated = false; v->ndims = 1; v->dimensions_allocated = false; v->dims = NULL; v->offsets = NULL; return(v); } #define make_vdims(Sc, Alloc, Dims, Info) ((((Dims) == 1) && (!(Alloc))) ? sc->wrap_only : make_vdims_1(Sc, Alloc, Dims, Info)) static vdims_t *make_vdims_1(s7_scheme *sc, bool elements_allocated, int dims, s7_int *dim_info) { vdims_t *v; v = (vdims_t *)malloc(sizeof(vdims_t)); v->original = sc->F; v->elements_allocated = elements_allocated; v->ndims = dims; if (dims > 1) { int i; s7_int offset = 1; v->dimensions_allocated = true; v->dims = (s7_int *)malloc(v->ndims * sizeof(s7_int)); v->offsets = (s7_int *)malloc(v->ndims * sizeof(s7_int)); for (i = 0; i < dims; i++) v->dims[i] = dim_info[i]; for (i = v->ndims - 1; i >= 0; i--) { v->offsets[i] = offset; offset *= v->dims[i]; } } else { v->dimensions_allocated = false; v->dims = NULL; v->offsets = NULL; } return(v); } s7_pointer s7_make_int_vector(s7_scheme *sc, s7_int len, int dims, s7_int *dim_info) { s7_pointer p; p = make_vector_1(sc, len, FILLED, T_INT_VECTOR); if (dim_info) vector_dimension_info(p) = make_vdims(sc, true, dims, dim_info); return(p); } s7_pointer s7_make_float_vector(s7_scheme *sc, s7_int len, int dims, s7_int *dim_info) { s7_pointer p; p = make_vector_1(sc, len, FILLED, T_FLOAT_VECTOR); if (dim_info) vector_dimension_info(p) = make_vdims(sc, true, dims, dim_info); return(p); } s7_pointer s7_make_float_vector_wrapper(s7_scheme *sc, s7_int len, s7_double *data, int dims, s7_int *dim_info, bool free_data) { /* this wraps up a C-allocated/freed double array as an s7 vector. */ s7_pointer x; new_cell(sc, x, T_FLOAT_VECTOR | T_SAFE_PROCEDURE); float_vector_elements(x) = data; vector_getter(x) = float_vector_getter; vector_setter(x) = float_vector_setter; vector_length(x) = len; if (!dim_info) { if (!free_data) /* here we need the dim info to tell the GC to leave the data alone */ { s7_int di[1]; di[0] = len; vector_dimension_info(x) = make_vdims(sc, free_data, 1, di); } else vector_dimension_info(x) = NULL; } else vector_dimension_info(x) = make_vdims(sc, free_data, dims, dim_info); Add_Vector(x); return(x); } s7_int s7_vector_length(s7_pointer vec) { return(vector_length(vec)); } s7_int s7_print_length(s7_scheme *sc) {return(sc->print_length);} s7_int s7_set_print_length(s7_scheme *sc, s7_int new_len) { s7_int old_len; old_len = sc->print_length; sc->print_length = new_len; return(old_len); } #if (!WITH_GMP) void s7_vector_fill(s7_scheme *sc, s7_pointer vec, s7_pointer obj) #else static void vector_fill(s7_scheme *sc, s7_pointer vec, s7_pointer obj) #endif { s7_int len, i, left; len = vector_length(vec); if (len == 0) return; left = len - 8; i = 0; switch (type(vec)) { case T_FLOAT_VECTOR: if (!s7_is_real(obj)) s7_wrong_type_arg_error(sc, "(float) vector-fill!", 2, obj, "a real"); else { s7_double x; x = real_to_double(sc, obj, "vector-fill!"); if (x == 0.0) memclr((void *)float_vector_elements(vec), len * sizeof(s7_double)); else { s7_double *orig; orig = float_vector_elements(vec); while (i <= left) { orig[i++] = x; orig[i++] = x; orig[i++] = x; orig[i++] = x; orig[i++] = x; orig[i++] = x; orig[i++] = x; orig[i++] = x; } for (; i < len; i++) orig[i] = x; } } break; case T_INT_VECTOR: if (!s7_is_integer(obj)) /* possibly a bignum */ s7_wrong_type_arg_error(sc, "(int) vector-fill!", 2, obj, "an integer"); else { s7_int k; k = s7_integer(obj); if (k == 0) memclr((void *)int_vector_elements(vec), len * sizeof(s7_int)); else { s7_int* orig; orig = int_vector_elements(vec); while (i <= left) { orig[i++] = k; orig[i++] = k; orig[i++] = k; orig[i++] = k; orig[i++] = k; orig[i++] = k; orig[i++] = k; orig[i++] = k; } for (; i < len; i++) orig[i] = k; } } break; default: { s7_pointer *orig; orig = vector_elements(vec); while (i <= left) { orig[i++] = obj; orig[i++] = obj; orig[i++] = obj; orig[i++] = obj; orig[i++] = obj; orig[i++] = obj; orig[i++] = obj; orig[i++] = obj; } for (; i < len; i++) orig[i] = obj; } } } static s7_pointer g_vector_fill(s7_scheme *sc, s7_pointer args) { #define H_vector_fill "(vector-fill! v val start end) sets all elements of the vector v between start and end to val" #define Q_vector_fill s7_make_circular_signature(sc, 3, 4, sc->T, sc->IS_VECTOR, sc->T, sc->IS_INTEGER) s7_pointer x, fill; s7_int start = 0, end; x = car(args); if (!s7_is_vector(x)) { check_method(sc, x, sc->VECTOR_FILL, args); /* not two_methods (and fill!) here else we get stuff like: * (let ((e (openlet (inlet 'fill! (lambda (obj val) (string-fill! (obj 'value) val)) 'value "01234")))) (vector-fill! e #\a) (e 'value)) -> "aaaaa" */ return(wrong_type_argument(sc, sc->VECTOR_FILL, 1, x, T_VECTOR)); } fill = cadr(args); if (is_float_vector(x)) { if (!s7_is_real(fill)) /* possibly a bignum */ { check_two_methods(sc, fill, sc->VECTOR_FILL, sc->FILL, args); s7_wrong_type_arg_error(sc, "(float) vector-fill!", 2, fill, "a real"); } } else { if (is_int_vector(x)) { if (!s7_is_integer(fill)) { check_two_methods(sc, fill, sc->VECTOR_FILL, sc->FILL, args); s7_wrong_type_arg_error(sc, "(int) vector-fill!", 2, fill, "an integer"); } } } end = vector_length(x); if (!is_null(cddr(args))) { s7_pointer p; p = start_and_end(sc, sc->VECTOR_FILL, sc->FILL, cddr(args), args, 3, &start, &end); if (p != sc->GC_NIL) return(p); if (start == end) return(fill); } if (end == 0) return(fill); if ((start == 0) && (end == vector_length(x))) s7_vector_fill(sc, x, fill); else { s7_int i; if (is_normal_vector(x)) { for (i = start; i < end; i++) vector_element(x, i) = fill; } else { if (is_int_vector(x)) { s7_int k; k = s7_integer(fill); if (k == 0) memclr((void *)(int_vector_elements(x) + start), (end - start) * sizeof(s7_int)); else { for (i = start; i < end; i++) int_vector_element(x, i) = k; } } else { if (is_float_vector(x)) { s7_double y; y = real_to_double(sc, fill, "vector-fill!"); if (y == 0.0) memclr((void *)(float_vector_elements(x) + start), (end - start) * sizeof(s7_double)); else { s7_double *orig; s7_int left; orig = float_vector_elements(x); left = end - 8; i = start; while (i <= left) { orig[i++] = y; orig[i++] = y; orig[i++] = y; orig[i++] = y; orig[i++] = y; orig[i++] = y; orig[i++] = y; orig[i++] = y; } for (; i < end; i++) orig[i] = y; } } } } } return(fill); } #if (!WITH_PURE_S7) static s7_pointer c_vector_fill(s7_scheme *sc, s7_pointer x, s7_pointer y) {return(g_vector_fill(sc, set_plist_2(sc, x, y)));} PF2_TO_PF(vector_fill, c_vector_fill) #endif s7_pointer s7_vector_ref(s7_scheme *sc, s7_pointer vec, s7_int index) { if (index >= vector_length(vec)) return(out_of_range(sc, sc->VECTOR_REF, small_int(2), make_integer(sc, index), ITS_TOO_LARGE)); return(vector_getter(vec)(sc, vec, index)); } s7_pointer s7_vector_set(s7_scheme *sc, s7_pointer vec, s7_int index, s7_pointer a) { if (index >= vector_length(vec)) return(out_of_range(sc, sc->VECTOR_SET, small_int(2), make_integer(sc, index), ITS_TOO_LARGE)); vector_setter(vec)(sc, vec, index, a); return(a); } s7_pointer *s7_vector_elements(s7_pointer vec) { return(vector_elements(vec)); } s7_int *s7_int_vector_elements(s7_pointer vec) { return(int_vector_elements(vec)); } s7_double *s7_float_vector_elements(s7_pointer vec) { return(float_vector_elements(vec)); } s7_int *s7_vector_dimensions(s7_pointer vec) { s7_int *dims; if (vector_dimension_info(vec)) return(vector_dimensions(vec)); dims = (s7_int *)malloc(sizeof(s7_int)); dims[0] = vector_length(vec); return(dims); } s7_int *s7_vector_offsets(s7_pointer vec) { s7_int *offs; if (vector_dimension_info(vec)) return(vector_offsets(vec)); offs = (s7_int *)malloc(sizeof(s7_int)); offs[0] = 1; return(offs); } #if (!WITH_PURE_S7) static s7_pointer vector_append(s7_scheme *sc, s7_pointer args, int typ); static s7_pointer g_vector_append(s7_scheme *sc, s7_pointer args) { /* returns a one-dimensional vector. To handle multidimensional vectors, we'd need to * ensure all the dimensional data matches (rank, size of each dimension except the last etc), * which is too much trouble. */ #define H_vector_append "(vector-append . vectors) returns a new (1-dimensional) vector containing the elements of its vector arguments." #define Q_vector_append pcl_v s7_pointer p; int i; if (is_null(args)) return(make_vector_1(sc, 0, NOT_FILLED, T_VECTOR)); for (i = 0, p = args; is_pair(p); p = cdr(p), i++) { s7_pointer x; x = car(p); if (!s7_is_vector(x)) { if (has_methods(x)) { s7_pointer func; func = find_method(sc, find_let(sc, x), sc->VECTOR_APPEND); if (func != sc->UNDEFINED) { int k; s7_pointer v, y; if (i == 0) return(s7_apply_function(sc, func, args)); /* we have to copy the arglist here */ sc->temp9 = make_list(sc, i, sc->F); for (k = 0, y = args, v = sc->temp9; k < i; k++, y = cdr(y), v = cdr(v)) car(v) = car(y); v = g_vector_append(sc, sc->temp9); y = s7_apply_function(sc, func, cons(sc, v, p)); sc->temp9 = sc->NIL; return(y); } } return(wrong_type_argument(sc, sc->VECTOR_APPEND, i, x, T_VECTOR)); } } return(vector_append(sc, args, type(car(args)))); } #endif s7_pointer s7_vector_ref_n(s7_scheme *sc, s7_pointer vector, int indices, ...) { /* from s7.html */ int ndims; ndims = s7_vector_rank(vector); if (ndims == indices) { va_list ap; s7_int index = 0; va_start(ap, indices); if (ndims == 1) { index = va_arg(ap, s7_int); va_end(ap); return(s7_vector_ref(sc, vector, index)); } else { int i; s7_int *offsets, *dimensions; dimensions = s7_vector_dimensions(vector); offsets = s7_vector_offsets(vector); for (i = 0; i < indices; i++) { int ind; ind = va_arg(ap, int); if ((ind < 0) || (ind >= dimensions[i])) { va_end(ap); return(out_of_range(sc, sc->VECTOR_REF, small_int(i), make_integer(sc, ind), (ind < 0) ? ITS_NEGATIVE : ITS_TOO_LARGE)); } index += (ind * offsets[i]); } va_end(ap); return(vector_getter(vector)(sc, vector, index)); } } return(s7_wrong_number_of_args_error(sc, "s7_vector_ref_n: wrong number of indices: ~A", s7_make_integer(sc, indices))); } s7_pointer s7_vector_set_n(s7_scheme *sc, s7_pointer vector, s7_pointer value, int indices, ...) { int ndims; ndims = s7_vector_rank(vector); if (ndims == indices) { va_list ap; s7_int index = 0; va_start(ap, indices); if (ndims == 1) { index = va_arg(ap, s7_int); va_end(ap); s7_vector_set(sc, vector, index, value); return(value); } else { int i; s7_int *offsets, *dimensions; dimensions = s7_vector_dimensions(vector); offsets = s7_vector_offsets(vector); for (i = 0; i < indices; i++) { int ind; ind = va_arg(ap, int); if ((ind < 0) || (ind >= dimensions[i])) { va_end(ap); return(s7_out_of_range_error(sc, "s7_vector_set_n", i, s7_make_integer(sc, ind), "should be a valid index")); } index += (ind * offsets[i]); } va_end(ap); vector_setter(vector)(sc, vector, index, value); return(value); } } return(s7_wrong_number_of_args_error(sc, "s7_vector_set_n: wrong number of indices: ~A", s7_make_integer(sc, indices))); } s7_pointer s7_vector_to_list(s7_scheme *sc, s7_pointer vect) { s7_int i, len; s7_pointer result; len = vector_length(vect); if (len == 0) return(sc->NIL); if (len >= (sc->free_heap_top - sc->free_heap)) { gc(sc); while (len >= (sc->free_heap_top - sc->free_heap)) resize_heap(sc); } sc->v = sc->NIL; for (i = len - 1; i >= 0; i--) sc->v = cons_unchecked(sc, vector_getter(vect)(sc, vect, i), sc->v); result = sc->v; sc->v = sc->NIL; return(result); } #if (!WITH_PURE_S7) static s7_pointer c_vector_to_list(s7_scheme *sc, s7_pointer vec) { sc->temp3 = vec; if (!s7_is_vector(vec)) method_or_bust(sc, vec, sc->VECTOR_TO_LIST, list_1(sc, vec), T_VECTOR, 0); return(s7_vector_to_list(sc, vec)); } static s7_pointer g_vector_to_list(s7_scheme *sc, s7_pointer args) { s7_int i, start = 0, end; s7_pointer p, vec; #define H_vector_to_list "(vector->list v start end) returns the elements of the vector v as a list; (map values v)" #define Q_vector_to_list s7_make_circular_signature(sc, 2, 3, sc->IS_LIST, sc->IS_VECTOR, sc->IS_INTEGER) vec = car(args); if (!s7_is_vector(vec)) method_or_bust(sc, vec, sc->VECTOR_TO_LIST, args, T_VECTOR, 0); end = vector_length(vec); if (!is_null(cdr(args))) { p = start_and_end(sc, sc->VECTOR_TO_LIST, NULL, cdr(args), args, 2, &start, &end); if (p != sc->GC_NIL) return(p); if (start == end) return(sc->NIL); } if ((start == 0) && (end == vector_length(vec))) return(s7_vector_to_list(sc, vec)); sc->w = sc->NIL; for (i = end - 1; i >= start; i--) sc->w = cons(sc, vector_getter(vec)(sc, vec, i), sc->w); p = sc->w; sc->w = sc->NIL; return(p); } PF_TO_PF(vector_to_list, c_vector_to_list) #endif s7_pointer s7_make_and_fill_vector(s7_scheme *sc, s7_int len, s7_pointer fill) { s7_pointer vect; vect = make_vector_1(sc, len, NOT_FILLED, T_VECTOR); s7_vector_fill(sc, vect, fill); return(vect); } static s7_pointer g_vector(s7_scheme *sc, s7_pointer args) { #define H_vector "(vector ...) returns a vector whose elements are the arguments" #define Q_vector s7_make_circular_signature(sc, 1, 2, sc->IS_VECTOR, sc->T) s7_int len; s7_pointer vec; len = s7_list_length(sc, args); vec = make_vector_1(sc, len, NOT_FILLED, T_VECTOR); if (len > 0) { s7_int i; s7_pointer x; for (x = args, i = 0; is_pair(x); x = cdr(x), i++) vector_element(vec, i) = car(x); } return(vec); } static s7_pointer c_vector_1(s7_scheme *sc, s7_pointer x) {return(g_vector(sc, set_plist_1(sc, x)));} PF_TO_PF(vector, c_vector_1) static s7_pointer g_is_float_vector(s7_scheme *sc, s7_pointer args) { #define H_is_float_vector "(float-vector? obj) returns #t if obj is an homogenous float vector" #define Q_is_float_vector pl_bt check_boolean_method(sc, s7_is_float_vector, sc->IS_FLOAT_VECTOR, args); } static s7_pointer g_float_vector(s7_scheme *sc, s7_pointer args) { #define H_float_vector "(float-vector ...) returns an homogenous float vector whose elements are the arguments" #define Q_float_vector s7_make_circular_signature(sc, 1, 2, sc->IS_FLOAT_VECTOR, sc->IS_REAL) s7_int len; s7_pointer vec; len = s7_list_length(sc, args); vec = make_vector_1(sc, len, NOT_FILLED, T_FLOAT_VECTOR); /* dangerous: assumes real_to_double won't trigger GC even if bignums */ if (len > 0) { s7_int i; s7_pointer x; for (x = args, i = 0; is_pair(x); x = cdr(x), i++) { if (s7_is_real(car(x))) /* bignum is ok here */ float_vector_element(vec, i) = real_to_double(sc, car(x), "float-vector"); else return(simple_wrong_type_argument(sc, sc->FLOAT_VECTOR, car(x), T_REAL)); } } return(vec); } static s7_pointer c_float_vector_1(s7_scheme *sc, s7_pointer x) {return(g_float_vector(sc, set_plist_1(sc, x)));} PF_TO_PF(float_vector, c_float_vector_1) static s7_pointer g_is_int_vector(s7_scheme *sc, s7_pointer args) { #define H_is_int_vector "(int-vector? obj) returns #t if obj is an homogenous int vector" #define Q_is_int_vector pl_bt check_boolean_method(sc, is_int_vector, sc->IS_INT_VECTOR, args); } static s7_pointer g_int_vector(s7_scheme *sc, s7_pointer args) { #define H_int_vector "(int-vector ...) returns an homogenous int vector whose elements are the arguments" #define Q_int_vector s7_make_circular_signature(sc, 1, 2, sc->IS_INT_VECTOR, sc->IS_INTEGER) s7_int len; s7_pointer vec; len = s7_list_length(sc, args); vec = make_vector_1(sc, len, NOT_FILLED, T_INT_VECTOR); if (len > 0) { s7_int i; s7_pointer x; for (x = args, i = 0; is_pair(x); x = cdr(x), i++) { if (is_integer(car(x))) int_vector_element(vec, i) = integer(car(x)); else return(simple_wrong_type_argument(sc, sc->INT_VECTOR, car(x), T_INTEGER)); } } return(vec); } static s7_pointer c_int_vector_1(s7_scheme *sc, s7_pointer x) {return(g_int_vector(sc, set_plist_1(sc, x)));} PF_TO_PF(int_vector, c_int_vector_1) #if (!WITH_PURE_S7) static s7_pointer c_list_to_vector(s7_scheme *sc, s7_pointer p) { sc->temp3 = p; if (is_null(p)) return(s7_make_vector(sc, 0)); if (!is_proper_list(sc, p)) method_or_bust_with_type(sc, p, sc->LIST_TO_VECTOR, list_1(sc, p), A_PROPER_LIST, 0); return(g_vector(sc, p)); } static s7_pointer g_list_to_vector(s7_scheme *sc, s7_pointer args) { #define H_list_to_vector "(list->vector lst) returns a vector containing the elements of lst; (apply vector lst)" #define Q_list_to_vector s7_make_signature(sc, 2, sc->IS_VECTOR, sc->IS_PROPER_LIST) return(c_list_to_vector(sc, car(args))); } PF_TO_PF(list_to_vector, c_list_to_vector) static s7_pointer g_vector_length(s7_scheme *sc, s7_pointer args) { s7_pointer vec; #define H_vector_length "(vector-length v) returns the length of vector v" #define Q_vector_length s7_make_signature(sc, 2, sc->IS_INTEGER, sc->IS_VECTOR) vec = car(args); if (!s7_is_vector(vec)) method_or_bust(sc, vec, sc->VECTOR_LENGTH, args, T_VECTOR, 0); return(make_integer(sc, vector_length(vec))); } static s7_int c_vector_length(s7_scheme *sc, s7_pointer vec) { if (!s7_is_vector(vec)) int_method_or_bust(sc, vec, sc->VECTOR_LENGTH, set_plist_1(sc, vec), T_VECTOR, 0); return(vector_length(vec)); } PF_TO_IF(vector_length, c_vector_length) #endif static s7_pointer make_shared_vector(s7_scheme *sc, s7_pointer vect, int skip_dims, s7_int index) { s7_pointer x; vdims_t *v; /* (let ((v #2d((1 2) (3 4)))) (v 1)) * (let ((v (make-vector '(2 3 4) 0))) (v 1 2)) * (let ((v #3d(((0 1 2 3) (4 5 6 7) (8 9 10 11)) ((12 13 14 15) (16 17 18 19) (20 21 22 23))))) (v 0 1)) */ new_cell(sc, x, typeflag(vect) | T_SAFE_PROCEDURE); vector_length(x) = 0; vector_elements(x) = NULL; vector_getter(x) = vector_getter(vect); vector_setter(x) = vector_setter(vect); v = (vdims_t *)malloc(sizeof(vdims_t)); v->ndims = vector_ndims(vect) - skip_dims; v->dims = (s7_int *)(vector_dimensions(vect) + skip_dims); v->offsets = (s7_int *)(vector_offsets(vect) + skip_dims); v->original = vect; /* shared_vector */ if (type(vect) == T_VECTOR) mark_function[T_VECTOR] = mark_vector_possibly_shared; else mark_function[type(vect)] = mark_int_or_float_vector_possibly_shared; v->elements_allocated = false; v->dimensions_allocated = false; vector_dimension_info(x) = v; if (skip_dims > 0) vector_length(x) = vector_offset(vect, skip_dims - 1); else vector_length(x) = vector_length(vect); if (is_int_vector(vect)) int_vector_elements(x) = (s7_int *)(int_vector_elements(vect) + index); else { if (is_float_vector(vect)) float_vector_elements(x) = (s7_double *)(float_vector_elements(vect) + index); else vector_elements(x) = (s7_pointer *)(vector_elements(vect) + index); } add_vector(sc, x); return(x); } static s7_pointer g_make_shared_vector(s7_scheme *sc, s7_pointer args) { #define H_make_shared_vector "(make-shared-vector original-vector new-dimensions (offset 0)) returns \ a vector that points to the same elements as the original-vector but with different dimensional info." #define Q_make_shared_vector s7_make_signature(sc, 4, sc->IS_VECTOR, sc->IS_VECTOR, s7_make_signature(sc, 2, sc->IS_PAIR, sc->IS_INTEGER), sc->IS_INTEGER) /* (let ((v1 #2d((1 2 3) (4 5 6)))) (let ((v2 (make-shared-vector v1 '(6)))) v2)) -> #(1 2 3 4 5 6) * (let ((v1 #(1 2 3 4 5 6))) (let ((v2 (make-shared-vector v1 '(3 2)))) v2)) -> #2D((1 2) (3 4) (5 6)) * this is most useful in generic functions -- they can still use (v n) as the accessor. */ s7_pointer orig, dims, y, x; vdims_t *v; int i; s7_int new_len = 1, orig_len, offset = 0; orig = car(args); if (!s7_is_vector(orig)) method_or_bust(sc, orig, sc->MAKE_SHARED_VECTOR, args, T_VECTOR, 1); orig_len = vector_length(orig); if (!is_null(cddr(args))) { s7_pointer off; off = caddr(args); if (s7_is_integer(off)) { offset = s7_integer(off); if ((offset < 0) || (offset >= orig_len)) /* we need this if, for example, offset == 9223372036854775807 */ return(out_of_range(sc, sc->MAKE_SHARED_VECTOR, small_int(3), off, (offset < 0) ? ITS_NEGATIVE : ITS_TOO_LARGE)); } else method_or_bust(sc, off, sc->MAKE_SHARED_VECTOR, args, T_INTEGER, 3); } dims = cadr(args); if (is_integer(dims)) { if ((s7_integer(dims) < 0) || (s7_integer(dims) >= orig_len)) return(out_of_range(sc, sc->MAKE_SHARED_VECTOR, small_int(2), dims, (s7_integer(dims) < 0) ? ITS_NEGATIVE : ITS_TOO_LARGE)); dims = list_1(sc, dims); } else { if ((is_null(dims)) || (!is_proper_list(sc, dims))) method_or_bust(sc, dims, sc->MAKE_SHARED_VECTOR, args, T_PAIR, 2); for (y = dims; is_pair(y); y = cdr(y)) if ((!s7_is_integer(car(y))) || /* (make-shared-vector v '((1 2) (3 4))) */ (s7_integer(car(y)) > orig_len) || (s7_integer(car(y)) < 0)) return(s7_error(sc, sc->WRONG_TYPE_ARG, set_elist_1(sc, make_string_wrapper(sc, "a list of integers that fits the original vector")))); } v = (vdims_t *)malloc(sizeof(vdims_t)); v->ndims = safe_list_length(sc, dims); v->dims = (s7_int *)malloc(v->ndims * sizeof(s7_int)); v->offsets = (s7_int *)malloc(v->ndims * sizeof(s7_int)); v->dimensions_allocated = true; v->elements_allocated = false; v->original = orig; /* shared_vector */ if (type(orig) == T_VECTOR) mark_function[T_VECTOR] = mark_vector_possibly_shared; else mark_function[type(orig)] = mark_int_or_float_vector_possibly_shared; for (i = 0, y = dims; is_pair(y); i++, y = cdr(y)) v->dims[i] = s7_integer(car(y)); for (i = v->ndims - 1; i >= 0; i--) { v->offsets[i] = new_len; new_len *= v->dims[i]; } if ((new_len < 0) || ((new_len + offset) > vector_length(orig))) { free(v->dims); free(v->offsets); free(v); return(out_of_range(sc, sc->MAKE_SHARED_VECTOR, small_int(2), dims, make_string_wrapper(sc, "a shared vector has to fit in the original vector"))); } new_cell(sc, x, typeflag(orig) | T_SAFE_PROCEDURE); vector_dimension_info(x) = v; vector_length(x) = new_len; /* might be less than original length */ vector_getter(x) = vector_getter(orig); vector_setter(x) = vector_setter(orig); if (is_int_vector(orig)) int_vector_elements(x) = (s7_int *)(int_vector_elements(orig) + offset); else { if (is_float_vector(orig)) float_vector_elements(x) = (s7_double *)(float_vector_elements(orig) + offset); else vector_elements(x) = (s7_pointer *)(vector_elements(orig) + offset); } add_vector(sc, x); return(x); } static s7_pointer c_make_shared_vector_ppi(s7_scheme *sc, s7_pointer x, s7_pointer y, s7_int z) { return(g_make_shared_vector(sc, set_plist_3(sc, x, y, make_integer(sc, z)))); } static s7_pointer c_make_shared_vector_pp(s7_scheme *sc, s7_pointer x, s7_pointer y) { return(g_make_shared_vector(sc, set_plist_2(sc, x, y))); } PPIF_TO_PF(make_shared_vector, c_make_shared_vector_pp, c_make_shared_vector_ppi) static s7_pointer make_vector_wrapper(s7_scheme *sc, s7_int size, s7_pointer *elements) { s7_pointer x; new_cell(sc, x, T_VECTOR | T_SAFE_PROCEDURE); vector_length(x) = size; vector_elements(x) = elements; vector_getter(x) = default_vector_getter; vector_setter(x) = default_vector_setter; vector_dimension_info(x) = NULL; /* don't add_vector -- no need for sweep to see this */ return(x); } static s7_pointer make_subvector(s7_scheme *sc, s7_pointer v) { s7_pointer x; new_cell(sc, x, type(v)); vector_length(x) = vector_length(v); if (is_normal_vector(v)) vector_elements(x) = vector_elements(v); else { if (is_float_vector(v)) float_vector_elements(x) = float_vector_elements(v); else int_vector_elements(x) = int_vector_elements(v); } vector_getter(x) = vector_getter(v); vector_setter(x) = vector_setter(v); vector_dimension_info(x) = NULL; return(x); } static s7_pointer vector_ref_1(s7_scheme *sc, s7_pointer vect, s7_pointer indices) { s7_int index = 0; if (vector_length(vect) == 0) return(out_of_range(sc, sc->VECTOR_REF, small_int(1), vect, ITS_TOO_LARGE)); if (vector_rank(vect) > 1) { unsigned int i; s7_pointer x; for (x = indices, i = 0; (is_not_null(x)) && (i < vector_ndims(vect)); x = cdr(x), i++) { s7_int n; s7_pointer p, p1; p = car(x); if (!s7_is_integer(p)) { if (!s7_is_integer(p1 = check_values(sc, p, x))) method_or_bust(sc, p, sc->VECTOR_REF, cons(sc, vect, indices), T_INTEGER, i + 2); p = p1; } n = s7_integer(p); if ((n < 0) || (n >= vector_dimension(vect, i))) return(out_of_range(sc, sc->VECTOR_REF, make_integer(sc, i + 2), p, (n < 0) ? ITS_NEGATIVE : ITS_TOO_LARGE)); index += n * vector_offset(vect, i); } if (is_not_null(x)) { if (type(vect) != T_VECTOR) return(out_of_range(sc, sc->VECTOR_REF, small_int(2), indices, TOO_MANY_INDICES)); return(implicit_index(sc, vector_element(vect, index), x)); } /* if not enough indices, return a shared vector covering whatever is left */ if (i < vector_ndims(vect)) return(make_shared_vector(sc, vect, i, index)); } else { s7_pointer p, p1; /* (let ((hi (make-vector 3 0.0)) (sum 0.0)) (do ((i 0 (+ i 1))) ((= i 3)) (set! sum (+ sum (hi i)))) sum) */ p = car(indices); if (!s7_is_integer(p)) { if (!s7_is_integer(p1 = check_values(sc, p, indices))) method_or_bust(sc, p, sc->VECTOR_REF, cons(sc, vect, indices), T_INTEGER, 2); p = p1; } index = s7_integer(p); if ((index < 0) || (index >= vector_length(vect))) return(out_of_range(sc, sc->VECTOR_REF, small_int(2), p, (index < 0) ? ITS_NEGATIVE : ITS_TOO_LARGE)); if (is_not_null(cdr(indices))) /* (let ((L #(#(1 2 3) #(4 5 6)))) (vector-ref L 1 2)) */ { if (type(vect) != T_VECTOR) return(out_of_range(sc, sc->VECTOR_REF, small_int(2), indices, TOO_MANY_INDICES)); return(implicit_index(sc, vector_element(vect, index), cdr(indices))); } } return((vector_getter(vect))(sc, vect, index)); } static s7_pointer g_vector_ref(s7_scheme *sc, s7_pointer args) { #define H_vector_ref "(vector-ref v ... i) returns the i-th element of vector v." #define Q_vector_ref s7_make_circular_signature(sc, 2, 3, sc->T, sc->IS_VECTOR, sc->IS_INTEGER) s7_pointer vec; vec = car(args); if (!s7_is_vector(vec)) method_or_bust(sc, vec, sc->VECTOR_REF, args, T_VECTOR, 1); return(vector_ref_1(sc, vec, cdr(args))); } static s7_pointer g_vector_ref_ic_n(s7_scheme *sc, s7_pointer args, s7_int index) { s7_pointer vec; vec = find_symbol_checked(sc, car(args)); if (!s7_is_vector(vec)) method_or_bust(sc, vec, sc->VECTOR_REF, list_2(sc, vec, cadr(args)), T_VECTOR, 1); if (index >= vector_length(vec)) return(out_of_range(sc, sc->VECTOR_REF, small_int(2), cadr(args), ITS_TOO_LARGE)); if (vector_rank(vec) > 1) { if (index >= vector_dimension(vec, 0)) return(out_of_range(sc, sc->VECTOR_REF, small_int(2), cadr(args), ITS_TOO_LARGE)); return(make_shared_vector(sc, vec, 1, index * vector_offset(vec, 0))); } return(vector_getter(vec)(sc,vec, index)); } /* (vector-ref fv i) -> allocates real, so it's not a pf case */ static s7_pointer vector_ref_pf_slot(s7_scheme *sc, s7_pointer **p) { s7_pointer x, y; x = (**p); (*p)++; y = slot_value(**p); (*p)++; return(vector_elements(x)[s7_integer(y)]); } static s7_pointer vector_ref_pf_s(s7_scheme *sc, s7_pointer **p) { s7_if_t xf; s7_pointer x; s7_int y; x = (**p); (*p)++; xf = (s7_if_t)(**p); (*p)++; y = xf(sc, p); return(vector_elements(x)[y]); } static s7_pointer vector_ref_pf_i(s7_scheme *sc, s7_pointer **p) { s7_if_t xf; s7_pointer x; s7_int y; x = slot_value(**p); (*p)++; xf = (s7_if_t)(**p); (*p)++; y = xf(sc, p); return(vector_elements(x)[y]); } static int c_vector_tester(s7_scheme *sc, s7_pointer expr) { s7_pointer a1; a1 = cadr(expr); if (is_symbol(a1)) { s7_pointer table; table = s7_slot(sc, a1); if ((is_slot(table)) && ((is_immutable_symbol(a1)) || (!is_stepper(table)))) { table = slot_value(table); if ((type(table) == T_VECTOR) && (vector_rank(table) == 1)) { s7_pointer a2; s7_xf_store(sc, table); a2 = caddr(expr); if (is_symbol(a2)) { s7_pointer slot; slot = s7_slot(sc, a2); if ((is_slot(slot)) && (is_integer(slot_value(slot)))) { s7_xf_store(sc, slot); return(TEST_SS); } } else { if (s7_arg_to_if(sc, a2)) return(TEST_SI); } return(TEST_SQ); } } } return(TEST_NO_S); } static s7_pf_t vector_ref_pf(s7_scheme *sc, s7_pointer expr) { if ((is_pair(cdr(expr))) && (is_pair(cddr(expr))) && (is_null(cdddr(expr)))) { int choice; choice = (c_vector_tester(sc, expr)); if (choice == TEST_SS) return(vector_ref_pf_slot); if (choice == TEST_SI) return(vector_ref_pf_s); } return(NULL); } static s7_pointer vector_ref_ic; static s7_pointer g_vector_ref_ic(s7_scheme *sc, s7_pointer args) {return(g_vector_ref_ic_n(sc, args, s7_integer(cadr(args))));} static s7_pointer vector_ref_ic_0; static s7_pointer g_vector_ref_ic_0(s7_scheme *sc, s7_pointer args) {return(g_vector_ref_ic_n(sc, args, 0));} static s7_pointer vector_ref_ic_1; static s7_pointer g_vector_ref_ic_1(s7_scheme *sc, s7_pointer args) {return(g_vector_ref_ic_n(sc, args, 1));} static s7_pointer vector_ref_ic_2; static s7_pointer g_vector_ref_ic_2(s7_scheme *sc, s7_pointer args) {return(g_vector_ref_ic_n(sc, args, 2));} static s7_pointer vector_ref_ic_3; static s7_pointer g_vector_ref_ic_3(s7_scheme *sc, s7_pointer args) {return(g_vector_ref_ic_n(sc, args, 3));} static s7_pointer vector_ref_gs; static s7_pointer g_vector_ref_gs(s7_scheme *sc, s7_pointer args) { /* global vector ref: (vector-ref global_vector i) */ s7_pointer x, vec; s7_int index; vec = find_global_symbol_checked(sc, car(args)); x = find_symbol_checked(sc, cadr(args)); if (!s7_is_vector(vec)) method_or_bust(sc, vec, sc->VECTOR_REF, list_2(sc, vec, x), T_VECTOR, 1); if (!s7_is_integer(x)) method_or_bust(sc, x, sc->VECTOR_REF, list_2(sc, vec, x), T_INTEGER, 2); index = s7_integer(x); if ((index < 0) || (index >= vector_length(vec))) return(out_of_range(sc, sc->VECTOR_REF, small_int(2), cadr(args), (index < 0) ? ITS_NEGATIVE : ITS_TOO_LARGE)); if (vector_rank(vec) > 1) { if (index >= vector_dimension(vec, 0)) return(out_of_range(sc, sc->VECTOR_REF, small_int(2), cadr(args), ITS_TOO_LARGE)); return(make_shared_vector(sc, vec, 1, index * vector_offset(vec, 0))); } return(vector_getter(vec)(sc, vec, index)); } static s7_pointer vector_ref_add1; static s7_pointer g_vector_ref_add1(s7_scheme *sc, s7_pointer args) { /* (vector-ref v (+ s 1)) I think */ s7_pointer vec, x; s7_int index; vec = find_symbol_checked(sc, car(args)); x = find_symbol_checked(sc, cadr(cadr(args))); if (!s7_is_integer(x)) method_or_bust(sc, x, sc->VECTOR_REF, list_2(sc, vec, x), T_INTEGER, 2); index = s7_integer(x) + 1; if (!s7_is_vector(vec)) method_or_bust(sc, vec, sc->VECTOR_REF, list_2(sc, vec, s7_make_integer(sc, index)), T_VECTOR, 1); if ((index < 0) || (index >= vector_length(vec))) return(out_of_range(sc, sc->VECTOR_REF, small_int(2), cadr(args), (index < 0) ? ITS_NEGATIVE : ITS_TOO_LARGE)); if (vector_rank(vec) > 1) { if (index >= vector_dimension(vec, 0)) return(out_of_range(sc, sc->VECTOR_REF, small_int(2), cadr(args), ITS_TOO_LARGE)); return(make_shared_vector(sc, vec, 1, index * vector_offset(vec, 0))); } return(vector_getter(vec)(sc, vec, index)); } static s7_pointer vector_ref_2, constant_vector_ref_gs; static s7_pointer g_constant_vector_ref_gs(s7_scheme *sc, s7_pointer args) { s7_pointer x, vec; s7_int index; vec = opt_vector(args); x = find_symbol_checked(sc, cadr(args)); if (!s7_is_integer(x)) return(g_vector_ref_gs(sc, args)); index = s7_integer(x); if ((index < 0) || (index >= vector_length(vec))) return(out_of_range(sc, sc->VECTOR_REF, small_int(2), cadr(args), (index < 0) ? ITS_NEGATIVE : ITS_TOO_LARGE)); return(vector_element(vec, index)); } static s7_pointer g_vector_ref_2(s7_scheme *sc, s7_pointer args) { s7_pointer vec, ind; s7_int index; vec = car(args); if (!s7_is_vector(vec)) method_or_bust(sc, vec, sc->VECTOR_REF, args, T_VECTOR, 1); /* should be ok because we go to g_vector_ref below */ if (vector_rank(vec) > 1) return(g_vector_ref(sc, args)); ind = cadr(args); if (!s7_is_integer(ind)) method_or_bust(sc, ind, sc->VECTOR_REF, args, T_INTEGER, 2); index = s7_integer(ind); if ((index < 0) || (index >= vector_length(vec))) return(out_of_range(sc, sc->VECTOR_REF, small_int(2), ind, (index < 0) ? ITS_NEGATIVE : ITS_TOO_LARGE)); return(vector_getter(vec)(sc, vec, index)); } static s7_pointer g_vector_set(s7_scheme *sc, s7_pointer args) { #define H_vector_set "(vector-set! v i ... value) sets the i-th element of vector v to value." #define Q_vector_set s7_make_circular_signature(sc, 3, 4, sc->T, sc->IS_VECTOR, sc->IS_INTEGER, sc->IS_INTEGER_OR_ANY_AT_END) s7_pointer vec, val; s7_int index; vec = car(args); if (!s7_is_vector(vec)) method_or_bust(sc, vec, sc->VECTOR_SET, args, T_VECTOR, 1); if (vector_length(_TSet(vec)) == 0) return(out_of_range(sc, sc->VECTOR_SET, small_int(1), vec, ITS_TOO_LARGE)); if (vector_rank(vec) > 1) { unsigned int i; s7_pointer x; index = 0; for (x = cdr(args), i = 0; (is_not_null(cdr(x))) && (i < vector_ndims(vec)); x = cdr(x), i++) { s7_int n; s7_pointer p, p1; p = car(x); if (!s7_is_integer(p)) { if (!s7_is_integer(p1 = check_values(sc, p, x))) method_or_bust(sc, p, sc->VECTOR_SET, args, T_INTEGER, i + 2); p = p1; } n = s7_integer(p); if ((n < 0) || (n >= vector_dimension(vec, i))) return(out_of_range(sc, sc->VECTOR_SET, make_integer(sc, i + 2), p, (n < 0) ? ITS_NEGATIVE : ITS_TOO_LARGE)); index += n * vector_offset(vec, i); } if (is_not_null(cdr(x))) return(s7_wrong_number_of_args_error(sc, "too many args for vector-set!: ~S", args)); if (i != vector_ndims(vec)) return(s7_wrong_number_of_args_error(sc, "not enough args for vector-set!: ~S", args)); val = car(x); } else { s7_pointer p, p1; p = cadr(args); if (!s7_is_integer(p)) { if (!s7_is_integer(p1 = check_values(sc, p, cdr(args)))) method_or_bust(sc, p, sc->VECTOR_SET, args, T_INTEGER, 2); p = p1; } index = s7_integer(p); if ((index < 0) || (index >= vector_length(vec))) return(out_of_range(sc, sc->VECTOR_SET, small_int(2), p, (index < 0) ? ITS_NEGATIVE : ITS_TOO_LARGE)); if (is_not_null(cdddr(args))) { car(sc->temp_cell_2) = vector_getter(vec)(sc, vec, index); cdr(sc->temp_cell_2) = cddr(args); return(g_vector_set(sc, sc->temp_cell_2)); } val = caddr(args); } vector_setter(vec)(sc, vec, index, val); return(val); } static s7_pointer vector_set_ic; static s7_pointer g_vector_set_ic(s7_scheme *sc, s7_pointer args) { /* (vector-set! vec 0 x) */ s7_pointer vec, val; s7_int index; vec = find_symbol_checked(sc, car(args)); if (!s7_is_vector(vec)) method_or_bust(sc, vec, sc->VECTOR_SET, list_3(sc, vec, cadr(args), find_symbol_checked(sc, caddr(args))), T_VECTOR, 1); /* the list_3 happens only if we find the method */ if (vector_rank(vec) > 1) return(g_vector_set(sc, set_plist_3(sc, vec, cadr(args), find_symbol_checked(sc, caddr(args))))); index = s7_integer(cadr(args)); if (index >= vector_length(vec)) return(out_of_range(sc, sc->VECTOR_SET, small_int(2), cadr(args), ITS_TOO_LARGE)); val = find_symbol_checked(sc, caddr(args)); vector_setter(vec)(sc, vec, index, val); return(val); } static s7_pointer vector_set_vref; static s7_pointer g_vector_set_vref(s7_scheme *sc, s7_pointer args) { /* (vector-set! vec i (vector-ref vec j)) -- checked that the vector is the same */ s7_pointer vec, val1, val2; s7_int index1, index2; vec = find_symbol_checked(sc, car(args)); val1 = find_symbol_checked(sc, cadr(args)); val2 = find_symbol_checked(sc, caddr(caddr(args))); if ((!s7_is_vector(vec)) || (vector_rank(vec) > 1) || (!s7_is_integer(val1)) || (!s7_is_integer(val2))) return(g_vector_set(sc, set_plist_3(sc, vec, val1, g_vector_ref(sc, set_plist_2(sc, vec, val2))))); index1 = s7_integer(val1); if (index1 >= vector_length(vec)) return(out_of_range(sc, sc->VECTOR_SET, small_int(2), val1, ITS_TOO_LARGE)); index2 = s7_integer(val2); if (index2 >= vector_length(vec)) return(out_of_range(sc, sc->VECTOR_REF, small_int(2), val2, ITS_TOO_LARGE)); vector_setter(vec)(sc, vec, index1, val1 = vector_getter(vec)(sc, vec, index2)); return(val1); } static s7_pointer vector_set_vector_ref; static s7_pointer g_vector_set_vector_ref(s7_scheme *sc, s7_pointer args) { /* (vector-set! data i|j (+|- (vector-ref data i) tc)) */ s7_pointer vec, val, val2, tc, arg3; s7_int index1, index2; vec = find_symbol_checked(sc, car(args)); val = find_symbol_checked(sc, cadr(args)); arg3 = caddr(args); tc = find_symbol_checked(sc, caddr(arg3)); val2 = caddr(cadr(arg3)); if ((!s7_is_vector(vec)) || (vector_rank(vec) > 1) || (!s7_is_integer(val))) return(g_vector_set(sc, set_plist_3(sc, vec, val, c_call(arg3)(sc, list_2(sc, g_vector_ref(sc, set_plist_2(sc, vec, find_symbol_checked(sc, val2))), tc))))); index1 = s7_integer(val); if (index1 >= vector_length(vec)) return(out_of_range(sc, sc->VECTOR_SET, small_int(2), val, ITS_TOO_LARGE)); if (val2 != cadr(args)) { val2 = find_symbol_checked(sc, val2); if (!s7_is_integer(val2)) { s7_pointer p; if (!s7_is_integer(p = check_values(sc, val2, list_1(sc, val2)))) return(wrong_type_argument(sc, sc->VECTOR_REF, 2, val2, T_INTEGER)); else val2 = p; } index2 = s7_integer(val2); if (index2 >= vector_length(vec)) return(out_of_range(sc, sc->VECTOR_REF, small_int(2), val, ITS_TOO_LARGE)); } else index2 = index1; car(sc->Z2_1) = vector_getter(vec)(sc, vec, index2); car(sc->Z2_2) = tc; vector_setter(vec)(sc, vec, index1, tc = c_call(arg3)(sc, sc->Z2_1)); return(tc); } static s7_pointer c_vector_set_3(s7_scheme *sc, s7_pointer vec, s7_int index, s7_pointer val) { /* (vector-set! vec ind val) where are all predigested */ if (!s7_is_vector(vec)) method_or_bust(sc, vec, sc->VECTOR_SET, list_3(sc, vec, make_integer(sc, index), val), T_VECTOR, 1); if (vector_rank(vec) > 1) return(g_vector_set(sc, list_3(sc, vec, make_integer(sc, index), val))); if ((index < 0) || (index >= vector_length(vec))) return(out_of_range(sc, sc->VECTOR_SET, small_int(2), make_integer(sc, index), (index < 0) ? ITS_NEGATIVE : ITS_TOO_LARGE)); vector_setter(vec)(sc, vec, index, val); return(val); } static s7_pointer c_vector_set_s(s7_scheme *sc, s7_pointer vec, s7_int index, s7_pointer val) { /* (vector-set! vec ind val) where are all predigested, vector is prechecked */ if ((index < 0) || (index >= vector_length(vec))) return(out_of_range(sc, sc->VECTOR_SET, small_int(2), make_integer(sc, index), (index < 0) ? ITS_NEGATIVE : ITS_TOO_LARGE)); vector_elements(vec)[index] = val; return(val); } static s7_pointer vector_set_3; static s7_pointer g_vector_set_3(s7_scheme *sc, s7_pointer args) { s7_pointer ind; ind = cadr(args); if (!s7_is_integer(ind)) { s7_pointer p; if (!s7_is_integer(p = check_values(sc, ind, cdr(args)))) return(wrong_type_argument(sc, sc->VECTOR_SET, 2, ind, T_INTEGER)); else ind = p; } return(c_vector_set_3(sc, car(args), s7_integer(ind), caddr(args))); } PIPF_TO_PF(vector_set, c_vector_set_s, c_vector_set_3, c_vector_tester) static s7_pointer g_make_vector(s7_scheme *sc, s7_pointer args) { #define H_make_vector "(make-vector len (value #f) (homogenous #f)) returns a vector of len elements initialized to value. \ To create a multidimensional vector, put the dimension bounds in a list (this is to avoid ambiguities such as \ (make-vector 1 2) where it's not clear whether the '2' is an initial value or a dimension size). (make-vector '(2 3) 1.0) \ returns a 2 dimensional vector of 6 total elements, all initialized to 1.0. If homogenous is #t, and value is either an integer \ or a real, the vector can only hold numbers of that type (s7_int or s7_double)." #define Q_make_vector s7_make_signature(sc, 4, sc->IS_VECTOR, s7_make_signature(sc, 2, sc->IS_INTEGER, sc->IS_PAIR), sc->T, sc->IS_BOOLEAN) s7_int len; s7_pointer x, fill, vec; int result_type = T_VECTOR; fill = sc->UNSPECIFIED; x = car(args); if (s7_is_integer(x)) { len = s7_integer(x); if (len < 0) return(wrong_type_argument_with_type(sc, sc->MAKE_VECTOR, 1, x, A_NON_NEGATIVE_INTEGER)); } else { if (!(is_pair(x))) method_or_bust_with_type(sc, x, sc->MAKE_VECTOR, args, make_string_wrapper(sc, "an integer or a list of integers"), 1); if (!s7_is_integer(car(x))) return(wrong_type_argument_with_type(sc, sc->MAKE_VECTOR, 1, car(x), make_string_wrapper(sc, "each dimension should be an integer"))); if (is_null(cdr(x))) len = s7_integer(car(x)); else { int dims; s7_pointer y; dims = s7_list_length(sc, x); if (dims <= 0) /* 0 if circular, negative if dotted */ return(wrong_type_argument_with_type(sc, sc->MAKE_VECTOR, 1, x, A_PROPER_LIST)); if (dims > sc->max_vector_dimensions) return(out_of_range(sc, sc->MAKE_VECTOR, small_int(1), x, ITS_TOO_LARGE)); for (len = 1, y = x; is_not_null(y); y = cdr(y)) { if (!s7_is_integer(car(y))) return(wrong_type_argument(sc, sc->MAKE_VECTOR, position_of(y, x), car(y), T_INTEGER)); len *= s7_integer(car(y)); if (len < 0) return(wrong_type_argument_with_type(sc, sc->MAKE_VECTOR, position_of(y, x), car(y), A_NON_NEGATIVE_INTEGER)); } } } if (is_not_null(cdr(args))) { fill = cadr(args); if (is_not_null(cddr(args))) { if (caddr(args) == sc->T) { /* here bignums can cause confusion, so use is_integer not s7_is_integer etc */ if (is_integer(fill)) result_type = T_INT_VECTOR; else { if (s7_is_real(fill)) /* might be gmp with big_real by accident (? see above) */ result_type = T_FLOAT_VECTOR; else method_or_bust_with_type(sc, fill, sc->MAKE_VECTOR, args, make_string_wrapper(sc, "an integer or a real since 'homogenous' is #t"), 2); } } else { if (caddr(args) != sc->F) method_or_bust_with_type(sc, caddr(args), sc->MAKE_VECTOR, args, A_BOOLEAN, 3); } } } vec = make_vector_1(sc, len, NOT_FILLED, result_type); if (len > 0) s7_vector_fill(sc, vec, fill); if ((is_pair(x)) && (is_pair(cdr(x)))) { int i; s7_int offset = 1; s7_pointer y; vdims_t *v; v = (vdims_t *)malloc(sizeof(vdims_t)); v->ndims = safe_list_length(sc, x); v->dims = (s7_int *)malloc(v->ndims * sizeof(s7_int)); v->offsets = (s7_int *)malloc(v->ndims * sizeof(s7_int)); v->original = sc->F; v->dimensions_allocated = true; v->elements_allocated = (len > 0); for (i = 0, y = x; is_not_null(y); i++, y = cdr(y)) v->dims[i] = s7_integer(car(y)); for (i = v->ndims - 1; i >= 0; i--) { v->offsets[i] = offset; offset *= v->dims[i]; } vector_dimension_info(vec) = v; } return(vec); } IF_TO_PF(make_vector, s7_make_vector) static s7_pointer g_make_float_vector(s7_scheme *sc, s7_pointer args) { #define H_make_float_vector "(make-float-vector len (init 0.0)) returns a float-vector." #define Q_make_float_vector s7_make_signature(sc, 3, sc->IS_FLOAT_VECTOR, s7_make_signature(sc, 2, sc->IS_INTEGER, sc->IS_PAIR), sc->IS_REAL) s7_int len; s7_pointer x, p; s7_double *arr; p = car(args); if ((is_pair(cdr(args))) || (!is_integer(p))) { s7_pointer init; if (is_pair(cdr(args))) { init = cadr(args); if (!s7_is_real(init)) method_or_bust(sc, init, sc->MAKE_FLOAT_VECTOR, args, T_REAL, 2); #if WITH_GMP if (s7_is_bignum(init)) return(g_make_vector(sc, set_plist_3(sc, p, make_real(sc, real_to_double(sc, init, "make-float-vector")), sc->T))); #endif if (is_rational(init)) return(g_make_vector(sc, set_plist_3(sc, p, make_real(sc, rational_to_double(sc, init)), sc->T))); } else init = real_zero; return(g_make_vector(sc, set_plist_3(sc, p, init, sc->T))); } len = s7_integer(p); if (len < 0) return(wrong_type_argument_with_type(sc, sc->MAKE_FLOAT_VECTOR, 1, p, A_NON_NEGATIVE_INTEGER)); if (len > sc->max_vector_length) return(out_of_range(sc, sc->MAKE_FLOAT_VECTOR, small_int(1), p, ITS_TOO_LARGE)); if (len > 0) arr = (s7_double *)calloc(len, sizeof(s7_double)); else arr = NULL; new_cell(sc, x, T_FLOAT_VECTOR | T_SAFE_PROCEDURE); vector_length(x) = len; float_vector_elements(x) = arr; vector_dimension_info(x) = NULL; vector_getter(x) = float_vector_getter; vector_setter(x) = float_vector_setter; add_vector(sc, x); return(x); } static s7_pointer c_make_float_vector(s7_scheme *sc, s7_int len) {return(s7_make_float_vector(sc, len, 1, NULL));} IF_TO_PF(make_float_vector, c_make_float_vector) static s7_pointer g_make_int_vector(s7_scheme *sc, s7_pointer args) { #define H_make_int_vector "(make-int-vector len (init 0.0)) returns an int-vector." #define Q_make_int_vector s7_make_signature(sc, 3, sc->IS_INT_VECTOR, s7_make_signature(sc, 2, sc->IS_INTEGER, sc->IS_PAIR), sc->IS_INTEGER) s7_int len; s7_pointer x, p; s7_int *arr; p = car(args); if ((is_pair(cdr(args))) || (!is_integer(p))) { s7_pointer init; if (is_pair(cdr(args))) { init = cadr(args); if (!is_integer(init)) method_or_bust(sc, init, sc->MAKE_INT_VECTOR, args, T_INTEGER, 2); } else init = small_int(0); return(g_make_vector(sc, set_plist_3(sc, p, init, sc->T))); } len = s7_integer(p); if (len < 0) return(wrong_type_argument_with_type(sc, sc->MAKE_INT_VECTOR, 1, p, A_NON_NEGATIVE_INTEGER)); if (len > sc->max_vector_length) return(out_of_range(sc, sc->MAKE_INT_VECTOR, small_int(1), p, ITS_TOO_LARGE)); if (len > 0) arr = (s7_int *)calloc(len, sizeof(s7_int)); else arr = NULL; new_cell(sc, x, T_INT_VECTOR | T_SAFE_PROCEDURE); vector_length(x) = len; int_vector_elements(x) = arr; vector_dimension_info(x) = NULL; vector_getter(x) = int_vector_getter; vector_setter(x) = int_vector_setter; add_vector(sc, x); return(x); } static s7_pointer c_make_int_vector(s7_scheme *sc, s7_int len) {return(s7_make_int_vector(sc, len, 1, NULL));} IF_TO_PF(make_int_vector, c_make_int_vector) static s7_pointer g_is_vector(s7_scheme *sc, s7_pointer args) { #define H_is_vector "(vector? obj) returns #t if obj is a vector" #define Q_is_vector pl_bt check_boolean_method(sc, s7_is_vector, sc->IS_VECTOR, args); } int s7_vector_rank(s7_pointer vect) { return(vector_rank(vect)); } static s7_pointer g_vector_dimensions(s7_scheme *sc, s7_pointer args) { #define H_vector_dimensions "(vector-dimensions vect) returns a list of vect's dimensions. In srfi-63 terms:\n\ (define array-dimensions vector-dimensions)\n\ (define (array-rank v) (length (vector-dimensions v)))" #define Q_vector_dimensions s7_make_signature(sc, 2, sc->IS_PAIR, sc->IS_VECTOR) s7_pointer x; x = car(args); if (!s7_is_vector(x)) method_or_bust(sc, x, sc->VECTOR_DIMENSIONS, args, T_VECTOR, 0); if (vector_rank(x) > 1) { int i; sc->w = sc->NIL; for (i = vector_ndims(x) - 1; i >= 0; i--) sc->w = cons(sc, make_integer(sc, vector_dimension(x, i)), sc->w); x = sc->w; sc->w = sc->NIL; return(x); } return(list_1(sc, make_integer(sc, vector_length(x)))); } static s7_pointer c_vector_dimensions(s7_scheme *sc, s7_pointer x) {return(g_vector_dimensions(sc, set_plist_1(sc, x)));} PF_TO_PF(vector_dimensions, c_vector_dimensions) #define MULTIVECTOR_TOO_MANY_ELEMENTS -1 #define MULTIVECTOR_NOT_ENOUGH_ELEMENTS -2 static int traverse_vector_data(s7_scheme *sc, s7_pointer vec, int flat_ref, int dimension, int dimensions, int *sizes, s7_pointer lst) { /* we're filling vec, we're currently looking for element (flat-wise) flat_ref, * we're at ref in dimension of dimensions, where sizes gives the bounds, and lst is our data * #3D(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12))) */ int i; s7_pointer x; for (i = 0, x = lst; i < sizes[dimension]; i++, x = cdr(x)) { if (!is_pair(x)) return(MULTIVECTOR_NOT_ENOUGH_ELEMENTS); if (dimension == (dimensions - 1)) vector_setter(vec)(sc, vec, flat_ref++, car(x)); else { flat_ref = traverse_vector_data(sc, vec, flat_ref, dimension + 1, dimensions, sizes, car(x)); if (flat_ref < 0) return(flat_ref); } } if (is_not_null(x)) return(MULTIVECTOR_TOO_MANY_ELEMENTS); return(flat_ref); } static s7_pointer s7_multivector_error(s7_scheme *sc, const char *message, s7_pointer data) { return(s7_error(sc, sc->READ_ERROR, set_elist_3(sc, make_string_wrapper(sc, "reading constant vector, ~A: ~A"), make_string_wrapper(sc, message), data))); } static s7_pointer g_multivector(s7_scheme *sc, s7_int dims, s7_pointer data) { /* get the dimension bounds from data, make the new vector, fill it from data * * dims needs to be s7_int so we can at least give correct error messages. * also should we let an empty vector have any number of dimensions? currently ndims is an int. */ s7_pointer vec, x; int i, vec_loc, err; int *sizes; /* (#2d((1 2 3) (4 5 6)) 0 0) -> 1 * (#2d((1 2 3) (4 5 6)) 0 1) -> 2 * (#2d((1 2 3) (4 5 6)) 1 1) -> 5 * (#3D(((1 2) (3 4)) ((5 6) (7 8))) 0 0 0) -> 1 * (#3D(((1 2) (3 4)) ((5 6) (7 8))) 1 1 0) -> 7 * #3D(((1 2) (3 4)) ((5 6) (7))) -> error, #3D(((1 2) (3 4)) ((5 6) (7 8 9))), #3D(((1 2) (3 4)) (5 (7 8 9))) etc * * but a special case: #nD() is an n-dimensional empty vector */ if (dims <= 0) /* #0d(...) #2147483649D() [if dims is int this is negative] */ return(s7_out_of_range_error(sc, "#nD(...) dimensions", 1, make_integer(sc, dims), "must be 1 or more")); if (dims > sc->max_vector_dimensions) return(s7_out_of_range_error(sc, "#nD(...) dimensions", 1, make_integer(sc, dims), "must be < 512")); /* sc->max_vector_dimensions=512 currently */ sc->w = sc->NIL; if (is_null(data)) /* dims are already 0 (calloc above) */ return(g_make_vector(sc, set_plist_1(sc, make_list(sc, dims, small_int(0))))); sizes = (int *)calloc(dims, sizeof(int)); for (x = data, i = 0; i < dims; i++) { sizes[i] = safe_list_length(sc, x); sc->w = cons(sc, make_integer(sc, sizes[i]), sc->w); x = car(x); if ((i < (dims - 1)) && (!is_pair(x))) { free(sizes); return(s7_multivector_error(sc, "we need a list that fully specifies the vector's elements", data)); } } vec = g_make_vector(sc, set_plist_1(sc, sc->w = safe_reverse_in_place(sc, sc->w))); vec_loc = s7_gc_protect(sc, vec); sc->w = sc->NIL; /* now fill the vector checking that all the lists match */ err = traverse_vector_data(sc, vec, 0, 0, dims, sizes, data); free(sizes); s7_gc_unprotect_at(sc, vec_loc); if (err < 0) return(s7_multivector_error(sc, (err == MULTIVECTOR_TOO_MANY_ELEMENTS) ? "found too many elements" : "not enough elements found", data)); return(vec); } static s7_pointer g_qq_multivector(s7_scheme *sc, s7_pointer args) { /* `#2d((1 2) ,(list 3 4)) */ #define H_qq_multivector "quasiquote internal support for multidimensional vector constants" #define Q_qq_multivector s7_make_signature(sc, 2, sc->IS_VECTOR, sc->T) return(g_multivector(sc, s7_integer(car(args)), cdr(args))); } s7_pointer s7_vector_copy(s7_scheme *sc, s7_pointer old_vect) { s7_int len; s7_pointer new_vect; len = vector_length(old_vect); if (is_float_vector(old_vect)) { if (vector_rank(old_vect) > 1) new_vect = g_make_vector(sc, set_plist_3(sc, g_vector_dimensions(sc, set_plist_1(sc, old_vect)), real_zero, sc->T)); else new_vect = make_vector_1(sc, len, NOT_FILLED, T_FLOAT_VECTOR); if (len > 0) memcpy((void *)(float_vector_elements(new_vect)), (void *)(float_vector_elements(old_vect)), len * sizeof(s7_double)); } else { if (is_int_vector(old_vect)) { if (vector_rank(old_vect) > 1) new_vect = g_make_vector(sc, set_plist_3(sc, g_vector_dimensions(sc, set_plist_1(sc, old_vect)), small_int(0), sc->T)); else new_vect = make_vector_1(sc, len, NOT_FILLED, T_INT_VECTOR); if (len > 0) memcpy((void *)(int_vector_elements(new_vect)), (void *)(int_vector_elements(old_vect)), len * sizeof(s7_int)); } else { if (vector_rank(old_vect) > 1) new_vect = g_make_vector(sc, set_plist_1(sc, g_vector_dimensions(sc, list_1(sc, old_vect)))); else new_vect = make_vector_1(sc, len, NOT_FILLED, T_VECTOR); /* here and in vector-fill! we have a problem with bignums -- should new bignums be allocated? (copy_list also) */ if (len > 0) memcpy((void *)(vector_elements(new_vect)), (void *)(vector_elements(old_vect)), len * sizeof(s7_pointer)); } } return(new_vect); } static s7_pointer univect_ref(s7_scheme *sc, s7_pointer args, bool flt) { s7_pointer v, caller; s7_int ind; int typ; caller = (flt) ? sc->FLOAT_VECTOR_REF : sc->INT_VECTOR_REF; typ = (flt) ? T_FLOAT_VECTOR : T_INT_VECTOR; v = car(args); if (type(v) != typ) method_or_bust(sc, v, caller, args, typ, 1); if (vector_rank(v) == 1) { s7_pointer index; index = cadr(args); if (!s7_is_integer(index)) { s7_pointer p; if (!s7_is_integer(p = check_values(sc, index, cdr(args)))) return(wrong_type_argument(sc, caller, 2, index, T_INTEGER)); else index = p; } ind = s7_integer(index); if ((ind < 0) || (ind >= vector_length(v))) return(simple_out_of_range(sc, caller, index, (ind < 0) ? ITS_NEGATIVE : ITS_TOO_LARGE)); if (!is_null(cddr(args))) return(out_of_range(sc, caller, small_int(2), cdr(args), TOO_MANY_INDICES)); } else { unsigned int i; s7_pointer x; ind = 0; for (x = cdr(args), i = 0; (is_not_null(x)) && (i < vector_ndims(v)); x = cdr(x), i++) { s7_int n; if (!s7_is_integer(car(x))) { s7_pointer p; if (!s7_is_integer(p = check_values(sc, car(x), x))) return(wrong_type_argument(sc, caller, i + 2, car(x), T_INTEGER)); n = s7_integer(p); } else n = s7_integer(car(x)); if ((n < 0) || (n >= vector_dimension(v, i))) return(out_of_range(sc, caller, make_integer(sc, i + 2), car(x), (n < 0) ? ITS_NEGATIVE : ITS_TOO_LARGE)); ind += n * vector_offset(v, i); } if (is_not_null(x)) return(out_of_range(sc, caller, small_int(2), cdr(args), TOO_MANY_INDICES)); /* if not enough indices, return a shared vector covering whatever is left */ if (i < vector_ndims(v)) return(make_shared_vector(sc, v, i, ind)); } if (flt) return(make_real(sc, float_vector_element(v, ind))); return(make_integer(sc, int_vector_element(v, ind))); } static s7_pointer univect_set(s7_scheme *sc, s7_pointer args, bool flt) { s7_pointer vec, val, caller; s7_int index; int typ; caller = (flt) ? sc->FLOAT_VECTOR_SET : sc->INT_VECTOR_SET; typ = (flt) ? T_FLOAT_VECTOR : T_INT_VECTOR; vec = car(args); if (type(vec) != typ) method_or_bust(sc, vec, caller, args, typ, 1); if (vector_rank(vec) > 1) { unsigned int i; s7_pointer x; index = 0; for (x = cdr(args), i = 0; (is_not_null(cdr(x))) && (i < vector_ndims(vec)); x = cdr(x), i++) { s7_int n; if (!s7_is_integer(car(x))) { s7_pointer p; if (!s7_is_integer(p = check_values(sc, car(x), x))) method_or_bust(sc, car(x), caller, args, T_INTEGER, i + 2); n = s7_integer(p); } else n = s7_integer(car(x)); if ((n < 0) || (n >= vector_dimension(vec, i))) return(out_of_range(sc, caller, make_integer(sc, i + 2), car(x), (n < 0) ? ITS_NEGATIVE : ITS_TOO_LARGE)); index += n * vector_offset(vec, i); } if (is_not_null(cdr(x))) return(s7_wrong_number_of_args_error(sc, "too many args: ~S", args)); if (i != vector_ndims(vec)) return(s7_wrong_number_of_args_error(sc, "not enough args: ~S", args)); val = car(x); } else { if (!s7_is_integer(cadr(args))) { s7_pointer p; if (!s7_is_integer(p = check_values(sc, cadr(args), cdr(args)))) method_or_bust(sc, cadr(args), caller, args, T_INTEGER, 2); index = s7_integer(p); } else index = s7_integer(cadr(args)); if ((index < 0) || (index >= vector_length(vec))) return(out_of_range(sc, caller, small_int(2), cadr(args), (index < 0) ? ITS_NEGATIVE : ITS_TOO_LARGE)); if (is_not_null(cdddr(args))) return(s7_wrong_number_of_args_error(sc, "too many args: ~S", args)); val = caddr(args); } if (flt) { if (!s7_is_real(val)) method_or_bust(sc, val, caller, args, T_REAL, 3); float_vector_element(vec, index) = real_to_double(sc, val, "float-vector-set!"); /* currently this accepts a complex value and assigns real_part(val) to the float-vector -- maybe an error instead? */ } else { if (!s7_is_integer(val)) method_or_bust(sc, val, caller, args, T_INTEGER, 3); int_vector_element(vec, index) = s7_integer(val); } return(val); } static s7_pointer g_float_vector_ref(s7_scheme *sc, s7_pointer args) { #define H_float_vector_ref "(float-vector-ref v ...) returns an element of the float-vector v." #define Q_float_vector_ref s7_make_circular_signature(sc, 2, 3, sc->IS_FLOAT, sc->IS_FLOAT_VECTOR, sc->IS_INTEGER) return(univect_ref(sc, args, true)); } static s7_pointer g_float_vector_set(s7_scheme *sc, s7_pointer args) { #define H_float_vector_set "(float-vector-set! v i ... value) sets the i-th element of the float-vector v to value." #define Q_float_vector_set s7_make_circular_signature(sc, 3, 4, sc->IS_REAL, sc->IS_FLOAT_VECTOR, sc->IS_INTEGER, sc->IS_INTEGER_OR_REAL_AT_END) return(univect_set(sc, args, true)); } static s7_pointer g_int_vector_ref(s7_scheme *sc, s7_pointer args) { #define H_int_vector_ref "(int-vector-ref v ...) returns an element of the int-vector v." #define Q_int_vector_ref s7_make_circular_signature(sc, 2, 3, sc->IS_INTEGER, sc->IS_INT_VECTOR, sc->IS_INTEGER) return(univect_ref(sc, args, false)); } static s7_pointer g_int_vector_set(s7_scheme *sc, s7_pointer args) { #define H_int_vector_set "(int-vector-set! v i ... value) sets the i-th element of the int-vector v to value." #define Q_int_vector_set s7_make_circular_signature(sc, 2, 3, sc->IS_INTEGER, sc->IS_INT_VECTOR, sc->IS_INTEGER) return(univect_set(sc, args, false)); } /* int-vector-ref|set optimizers */ static s7_int int_vector_ref_if_a(s7_scheme *sc, s7_pointer **p) { s7_if_t xf; s7_pointer x; s7_int y; x = (**p); (*p)++; if (!is_int_vector(x)) wrong_type_argument(sc, sc->INT_VECTOR_REF, 1, x, T_INT_VECTOR); xf = (s7_if_t)(**p); (*p)++; y = xf(sc, p); if ((y < 0) || (y >= vector_length(x))) out_of_range(sc, sc->INT_VECTOR_REF, small_int(2), make_integer(sc, y), (y < 0) ? ITS_NEGATIVE : ITS_TOO_LARGE); return(int_vector_elements(x)[y]); } static s7_if_t int_vector_ref_if_expanded(s7_scheme *sc, s7_pointer iv, s7_pointer ind_expr) { s7_xf_store(sc, iv); if (s7_arg_to_if(sc, ind_expr)) return(int_vector_ref_if_a); return(NULL); } static s7_if_t int_vector_ref_if(s7_scheme *sc, s7_pointer expr) { if ((is_pair(cdr(expr))) && (is_pair(cddr(expr))) && (is_null(cdddr(expr)))) { s7_pointer iv; iv = cadr(expr); if (!is_symbol(iv)) return(NULL); iv = s7_slot(sc, iv); if (!is_slot(iv)) return(NULL); if (!is_int_vector(slot_value(iv))) return(NULL); return(int_vector_ref_if_expanded(sc, slot_value(iv), caddr(expr))); } return(NULL); } static s7_if_t implicit_int_vector_ref(s7_scheme *sc, s7_pointer expr) { if ((is_null(cdr(expr))) || (!is_null(cddr(expr)))) return(NULL); return(int_vector_ref_if_expanded(sc, s7_symbol_value(sc, car(expr)), cadr(expr))); } static s7_int int_vector_set_if_a(s7_scheme *sc, s7_pointer **p) { s7_if_t xf; s7_pointer x; s7_int y, z; x = (**p); (*p)++; if (!is_int_vector(x)) wrong_type_argument(sc, sc->INT_VECTOR_SET, 1, x, T_INT_VECTOR); xf = (s7_if_t)(**p); (*p)++; y = xf(sc, p); if ((y < 0) || (y >= vector_length(x))) out_of_range(sc, sc->INT_VECTOR_SET, small_int(2), make_integer(sc, y), (y < 0) ? ITS_NEGATIVE : ITS_TOO_LARGE); xf = (s7_if_t)(**p); (*p)++; z = xf(sc, p); int_vector_elements(x)[y] = z; return(z); } static s7_if_t int_vector_set_if_expanded(s7_scheme *sc, s7_pointer iv, s7_pointer ind_sym, s7_pointer val_expr) { s7_xf_store(sc, iv); if ((s7_arg_to_if(sc, ind_sym)) && (s7_arg_to_if(sc, val_expr))) return(int_vector_set_if_a); return(NULL); } static s7_if_t int_vector_set_if(s7_scheme *sc, s7_pointer expr) { if ((is_pair(cdr(expr))) && (is_pair(cddr(expr))) && (is_pair(cdddr(expr))) && (is_null(cddddr(expr)))) { s7_pointer iv; iv = cadr(expr); if (!is_symbol(iv)) return(NULL); iv = s7_slot(sc, iv); if (!is_slot(iv)) return(NULL); if (!is_int_vector(slot_value(iv))) return(NULL); return(int_vector_set_if_expanded(sc, slot_value(iv), caddr(expr), cadddr(expr))); } return(NULL); } /* float-vector-ref|set optimizers */ static s7_double fv_set_rf_checked(s7_scheme *sc, s7_pointer **p) { s7_pointer fv, ind; s7_double val; s7_int index; s7_rf_t rf; fv = **p; (*p)++; ind = slot_value(**p); (*p)++; if (!is_integer(ind)) wrong_type_argument(sc, sc->FLOAT_VECTOR_SET, 2, ind, T_INTEGER); index = integer(ind); if ((index < 0) || (index >= vector_length(fv))) out_of_range(sc, sc->FLOAT_VECTOR_SET, small_int(2), ind, (index < 0) ? ITS_NEGATIVE : ITS_TOO_LARGE); rf = (s7_rf_t)(**p); (*p)++; val = rf(sc, p); float_vector_element(fv, index) = val; return(val); } static s7_double fv_set_rf_r(s7_scheme *sc, s7_pointer **p) { s7_pointer fv, ind, x; s7_double val; s7_int index; fv = **p; (*p)++; ind = slot_value(**p); (*p)++; if (!is_integer(ind)) wrong_type_argument(sc, sc->FLOAT_VECTOR_SET, 2, ind, T_INTEGER); index = integer(ind); if ((index < 0) || (index >= vector_length(fv))) out_of_range(sc, sc->FLOAT_VECTOR_SET, small_int(2), ind, (index < 0) ? ITS_NEGATIVE : ITS_TOO_LARGE); x = **p; (*p)++; val = real_to_double(sc, x, "float-vector-set!"); float_vector_element(fv, index) = val; return(val); } static s7_double fv_set_rf_s(s7_scheme *sc, s7_pointer **p) { s7_pointer fv, ind, x; s7_double val; s7_int index; fv = **p; (*p)++; ind = slot_value(**p); (*p)++; if (!is_integer(ind)) wrong_type_argument(sc, sc->FLOAT_VECTOR_SET, 2, ind, T_INTEGER); index = integer(ind); if ((index < 0) || (index >= vector_length(fv))) out_of_range(sc, sc->FLOAT_VECTOR_SET, small_int(2), ind, (index < 0) ? ITS_NEGATIVE : ITS_TOO_LARGE); x = slot_value(**p); (*p)++; val = real_to_double(sc, x, "float-vector-set!"); float_vector_element(fv, index) = val; return(val); } static s7_double fv_set_rf_six(s7_scheme *sc, s7_pointer **p) { s7_pointer fv, ind; s7_double val; s7_int index; s7_rf_t rf; fv = **p; (*p)++; ind = **p; (*p)++; index = integer(ind); rf = (s7_rf_t)(**p); (*p)++; val = rf(sc, p); float_vector_element(fv, index) = val; return(val); } static s7_double fv_set_rf_if(s7_scheme *sc, s7_pointer **p) { s7_pointer fv; s7_double val; s7_int index; s7_rf_t rf; s7_if_t xf; fv = **p; (*p)++; xf = (s7_if_t)(**p); (*p)++; index = xf(sc, p); if ((index < 0) || (index >= vector_length(fv))) out_of_range(sc, sc->FLOAT_VECTOR_SET, small_int(2), make_integer(sc, index), (index < 0) ? ITS_NEGATIVE : ITS_TOO_LARGE); rf = (s7_rf_t)(**p); (*p)++; val = rf(sc, p); float_vector_element(fv, index) = val; return(val); } static s7_rf_t float_vector_set_rf_expanded(s7_scheme *sc, s7_pointer fv, s7_pointer ind_sym, s7_pointer val_expr) { xf_t *rc; xf_init(3); xf_store(fv); if (is_symbol(ind_sym)) { s7_pointer ind, ind_slot; ind_slot = s7_slot(sc, ind_sym); if (!is_slot(ind_slot)) return(NULL); ind = slot_value(ind_slot); if (!is_integer(ind)) return(NULL); if (numerator(ind) < 0) return(NULL); xf_store(ind_slot); if (is_real(val_expr)) { xf_store(val_expr); return(fv_set_rf_r); } if (is_symbol(val_expr)) { s7_pointer slot, val; slot = s7_slot(sc, val_expr); if (!is_slot(slot)) return(NULL); val = slot_value(slot); if (!is_real(val)) return(NULL); xf_store(slot); return(fv_set_rf_s); } if (!is_pair(val_expr)) return(NULL); return(pair_to_rf(sc, val_expr, fv_set_rf_checked)); } if (is_pair(ind_sym)) { s7_ip_t ip; s7_if_t xf; s7_int loc; if (!is_pair(val_expr)) return(NULL); xf_save_loc(loc); ip = pair_to_ip(sc, ind_sym); if (!ip) return(NULL); xf = ip(sc, ind_sym); if (!xf) return(NULL); xf_store_at(loc, (s7_pointer)xf); return(pair_to_rf(sc, val_expr, fv_set_rf_if)); } if ((is_integer(ind_sym)) && (is_pair(val_expr))) { s7_int index; index = integer(ind_sym); if ((index < 0) || (index >= vector_length(fv))) return(NULL); xf_store(ind_sym); return(pair_to_rf(sc, val_expr, fv_set_rf_six)); } return(NULL); } static s7_rf_t float_vector_set_rf(s7_scheme *sc, s7_pointer expr) { s7_pointer fv; fv = cadr(expr); if (!is_symbol(fv)) return(NULL); fv = s7_slot(sc, fv); if (!is_slot(fv)) return(NULL); if (!is_float_vector(slot_value(fv))) return(NULL); return(float_vector_set_rf_expanded(sc, slot_value(fv), caddr(expr), cadddr(expr))); } static s7_double fv_ref_rf_ss(s7_scheme *sc, s7_pointer **p) { s7_pointer s1, s2; s7_int ind; s1 = slot_value(**p); (*p)++; s2 = slot_value(**p); (*p)++; ind = s7_integer(s2); if ((ind < 0) || (ind >= vector_length(s1))) out_of_range(sc, sc->FLOAT_VECTOR_REF, small_int(2), s2, (ind < 0) ? ITS_NEGATIVE : ITS_TOO_LARGE); return(float_vector_elements(s1)[ind]); } static s7_double fv_ref_rf_si(s7_scheme *sc, s7_pointer **p) { s7_pointer s1, s2; s7_int ind; s1 = slot_value(**p); (*p)++; s2 = (**p); (*p)++; ind = s7_integer(s2); if ((ind < 0) || (ind >= vector_length(s1))) out_of_range(sc, sc->FLOAT_VECTOR_REF, small_int(2), s2, (ind < 0) ? ITS_NEGATIVE : ITS_TOO_LARGE); return(float_vector_elements(s1)[ind]); } static s7_double fv_ref_rf_sx(s7_scheme *sc, s7_pointer **p) { s7_pointer s1; s7_if_t i1; s7_int ind; s1 = slot_value(**p); (*p)++; i1 = (s7_if_t)(**p); (*p)++; ind = i1(sc, p); if ((ind < 0) || (ind >= vector_length(s1))) out_of_range(sc, sc->FLOAT_VECTOR_REF, small_int(2), make_integer(sc, ind), (ind < 0) ? ITS_NEGATIVE : ITS_TOO_LARGE); return(float_vector_elements(s1)[ind]); } static s7_double fv_ref_rf_pf(s7_scheme *sc, s7_pointer **p) { s7_pointer s1; s7_pf_t fv; s7_if_t i1; s7_int ind; fv = (s7_pf_t)(**p); (*p)++; s1 = fv(sc, p); if (!is_float_vector(s1)) wrong_type_argument(sc, sc->FLOAT_VECTOR_REF, 1, s1, T_FLOAT_VECTOR); i1 = (s7_if_t)(**p); (*p)++; ind = i1(sc, p); if ((ind < 0) || (ind >= vector_length(s1))) out_of_range(sc, sc->FLOAT_VECTOR_REF, small_int(2), make_integer(sc, ind), (ind < 0) ? ITS_NEGATIVE : ITS_TOO_LARGE); return(float_vector_elements(s1)[ind]); } static s7_rf_t float_vector_ref_rf_expanded(s7_scheme *sc, s7_pointer a1, s7_pointer a2) { if ((is_symbol(a1)) && (is_float_vector(s7_symbol_value(sc, a1)))) { xf_t *rc; xf_init(2); xf_store(s7_slot(sc, a1)); if (is_integer(a2)) { xf_store(a2); return(fv_ref_rf_si); } if (is_symbol(a2)) { a2 = s7_slot(sc, a2); if ((!is_slot(a2)) || (is_t_complex(slot_value(a2)))) return(NULL); xf_store(a2); return(fv_ref_rf_ss); } if (is_pair(a2)) return(pair_to_rf_via_if(sc, a2, fv_ref_rf_sx)); } if ((is_pair(a1)) && (s7_arg_to_pf(sc, a1)) && (s7_arg_to_if(sc, a2))) return(fv_ref_rf_pf); return(NULL); } static s7_rf_t float_vector_ref_rf(s7_scheme *sc, s7_pointer expr) { if ((is_null(cdr(expr))) || (is_null(cddr(expr))) || (!is_null(cdddr(expr)))) return(NULL); return(float_vector_ref_rf_expanded(sc, cadr(expr), caddr(expr))); } static s7_rf_t implicit_float_vector_ref(s7_scheme *sc, s7_pointer expr) { if ((is_null(cdr(expr))) || (!is_null(cddr(expr)))) return(NULL); return(float_vector_ref_rf_expanded(sc, car(expr), cadr(expr))); } static s7_pointer hash_table_ref_pf_i(s7_scheme *sc, s7_pointer **p); static s7_pointer hash_table_set_pf_sxx(s7_scheme *sc, s7_pointer **p); static s7_pf_t implicit_pf_sequence_ref(s7_scheme *sc, s7_pointer expr) { s7_pointer seq, ind; if ((is_null(cdr(expr))) || (!is_null(cddr(expr)))) return(NULL); seq = car(expr); ind = cadr(expr); if (!is_symbol(seq)) return(NULL); seq = s7_slot(sc, seq); if (!is_slot(seq)) return(NULL); s7_xf_store(sc, seq); switch (type(slot_value(seq))) { case T_STRING: if (s7_arg_to_if(sc, ind)) return(string_ref_pf_si); break; case T_PAIR: if (s7_arg_to_if(sc, ind)) return(list_ref_pf_si); break; case T_VECTOR: if (s7_arg_to_if(sc, ind)) return(vector_ref_pf_i); /* TODO: these vref funcs don't check bounds */ break; case T_HASH_TABLE: if (s7_arg_to_pf(sc, ind)) return(hash_table_ref_pf_i); break; case T_LET: if (s7_arg_to_pf(sc, ind)) return(let_ref_pf_p2_sp); break; } return(NULL); } static s7_pf_t implicit_gf_sequence_ref(s7_scheme *sc, s7_pointer expr) { /* only difference from pf case: int|float-vectors return s7_pointer values */ return(implicit_pf_sequence_ref(sc, expr)); } #if WITH_OPTIMIZATION static s7_pf_t implicit_pf_sequence_set(s7_scheme *sc, s7_pointer seq, s7_pointer ind, s7_pointer val) { /* seq is the slot */ s7_xf_store(sc, seq); switch (type(slot_value(seq))) { case T_STRING: if ((s7_arg_to_if(sc, ind)) && (s7_arg_to_pf(sc, val))) return(string_set_pf_seq); break; case T_PAIR: if ((s7_arg_to_if(sc, ind)) && (s7_arg_to_pf(sc, val))) return(list_set_pf_seq); break; case T_VECTOR: if ((s7_arg_to_if(sc, ind)) && (s7_arg_to_pf(sc, val))) return(vector_set_pf_seq); break; case T_HASH_TABLE: if ((s7_arg_to_pf(sc, ind)) && (s7_arg_to_pf(sc, val))) return(hash_table_set_pf_sxx); break; case T_LET: if ((s7_arg_to_pf(sc, ind)) && (s7_arg_to_pf(sc, val))) return(let_set_pf_p3_s); break; } return(NULL); } static s7_pf_t implicit_gf_sequence_set(s7_scheme *sc, s7_pointer v, s7_pointer ind, s7_pointer val) { return(implicit_pf_sequence_set(sc, v, ind, val)); } #endif /* -------------------------------------------------------------------------------- */ static bool c_function_is_ok(s7_scheme *sc, s7_pointer x) { /* macro version of this (below) is much slower! */ s7_pointer p; p = car(x); if (is_global(p)) p = slot_value(global_slot(p)); else p = find_symbol_unchecked(sc, p); /* this is nearly always global and p == opt_cfunc(x) */ return((p == opt_any1(x)) || ((is_any_c_function(p)) && (opt_cfunc(x)) && (c_function_class(p) == c_function_class(opt_cfunc(x))))); } #if 0 #define c_function_is_ok(Sc, X) \ ({ s7_pointer _X_, _p_; _X_ = X; _p_ = find_global_symbol_checked(Sc, car(_X_)); \ ((_p_ == opt_cfunc(_X_)) || ((is_any_c_function(_p_)) && (c_function_class(_p_) == c_function_class(opt_cfunc(_X_))))); }) #endif static bool arglist_has_rest(s7_scheme *sc, s7_pointer args) { s7_pointer p; for (p = args; is_pair(p); p = cdr(p)) if (car(p) == sc->KEY_REST) return(true); return(false); } static bool arglist_has_keyword(s7_pointer args) { s7_pointer p; for (p = args; is_pair(p); p = cdr(p)) if (is_keyword(car(p))) return(true); return(false); } /* -------- sort! -------- */ #if (!WITH_GMP) static int dbl_less(const void *f1, const void *f2) { if ((*((s7_double *)f1)) < (*((s7_double *)f2))) return(-1); if ((*((s7_double *)f1)) > (*((s7_double *)f2))) return(1); return(0); } static int int_less(const void *f1, const void *f2) { if ((*((s7_int *)f1)) < (*((s7_int *)f2))) return(-1); if ((*((s7_int *)f1)) > (*((s7_int *)f2))) return(1); return(0); } static int dbl_greater(const void *f1, const void *f2) {return(-dbl_less(f1, f2));} static int int_greater(const void *f1, const void *f2) {return(-int_less(f1, f2));} static int byte_less(const void *f1, const void *f2) { if ((*((unsigned char *)f1)) < (*((unsigned char *)f2))) return(-1); if ((*((unsigned char *)f1)) > (*((unsigned char *)f2))) return(1); return(0); } static int byte_greater(const void *f1, const void *f2) {return(-byte_less(f1, f2));} static int dbl_less_2(const void *f1, const void *f2) { s7_pointer p1, p2; p1 = (*((s7_pointer *)f1)); p2 = (*((s7_pointer *)f2)); if (real(p1) < real(p2)) return(-1); if (real(p1) > real(p2)) return(1); return(0); } static int int_less_2(const void *f1, const void *f2) { s7_pointer p1, p2; p1 = (*((s7_pointer *)f1)); p2 = (*((s7_pointer *)f2)); if (integer(p1) < integer(p2)) return(-1); if (integer(p1) > integer(p2)) return(1); return(0); } static int dbl_greater_2(const void *f1, const void *f2) {return(-dbl_less_2(f1, f2));} static int int_greater_2(const void *f1, const void *f2) {return(-int_less_2(f1, f2));} #endif static s7_scheme *compare_sc; static s7_function compare_func; static s7_pointer compare_args, compare_begin, compare_v1, compare_v2; static opcode_t compare_op; static s7_pf_t compare_pf; static int vector_compare(const void *v1, const void *v2) { car(compare_args) = (*(s7_pointer *)v1); cadr(compare_args) = (*(s7_pointer *)v2); return(((*(compare_func))(compare_sc, compare_args) != compare_sc->F) ? -1 : 1); } static int pf_compare(const void *v1, const void *v2) { s7_pointer *top; s7_pointer **rp; slot_set_value(compare_v1, (*(s7_pointer *)v1)); slot_set_value(compare_v2, (*(s7_pointer *)v2)); top = compare_sc->cur_rf->data; rp = ⊤ (*rp)++; if (is_true(compare_sc, compare_pf(compare_sc, rp))) return(-1); return(1); } static int closure_compare(const void *v1, const void *v2) { slot_set_value(compare_v1, (*(s7_pointer *)v1)); slot_set_value(compare_v2, (*(s7_pointer *)v2)); push_stack(compare_sc, OP_EVAL_DONE, compare_sc->args, compare_sc->code); compare_sc->code = compare_args; /* this should be ok because we checked in advance that it is a safe closure (no sort! for example) */ eval(compare_sc, compare_op); return((compare_sc->value != compare_sc->F) ? -1 : 1); } static int closure_compare_begin(const void *v1, const void *v2) { slot_set_value(compare_v1, (*(s7_pointer *)v1)); slot_set_value(compare_v2, (*(s7_pointer *)v2)); push_stack(compare_sc, OP_EVAL_DONE, compare_sc->args, compare_sc->code); push_stack_no_args(compare_sc, OP_BEGIN1, compare_begin); compare_sc->code = compare_args; eval(compare_sc, compare_op); return((compare_sc->value != compare_sc->F) ? -1 : 1); } static s7_pointer g_sort(s7_scheme *sc, s7_pointer args) { #define H_sort "(sort! sequence less?) sorts a sequence using the function 'less?' to compare elements." #define Q_sort s7_make_signature(sc, 3, sc->T, sc->IS_SEQUENCE, sc->IS_PROCEDURE) s7_pointer data, lessp, lx; s7_int len = 0, n, k; int (*sort_func)(const void *v1, const void *v2); s7_pointer *elements; int gc_loc = -1; /* both the intermediate vector (if any) and the current args pointer need GC protection, * but it is a real bother to unprotect args at every return statement, so I'll use temp3 */ sc->temp3 = args; /* this is needed! */ data = car(args); if (is_null(data)) { /* (apply sort! () #f) should be an error I think */ lessp = cadr(args); if (type(lessp) < T_GOTO) method_or_bust_with_type(sc, lessp, sc->SORT, args, A_PROCEDURE, 2); if (!s7_is_aritable(sc, lessp, 2)) return(wrong_type_argument_with_type(sc, sc->SORT, 2, lessp, AN_EQ_FUNC)); return(sc->NIL); } lessp = cadr(args); if (type(lessp) < T_GOTO) method_or_bust_with_type(sc, lessp, sc->SORT, args, A_PROCEDURE, 2); if (!s7_is_aritable(sc, lessp, 2)) return(wrong_type_argument_with_type(sc, sc->SORT, 2, lessp, AN_EQ_FUNC)); if ((is_continuation(lessp)) || is_goto(lessp)) return(wrong_type_argument_with_type(sc, sc->SORT, 2, lessp, A_NORMAL_PROCEDURE)); sort_func = vector_compare; compare_func = NULL; compare_args = sc->T2_1; compare_sc = sc; if ((is_safe_procedure(lessp)) && /* (sort! a <) */ (is_c_function(lessp))) { s7_pointer sig; sig = c_function_signature(lessp); if ((sig) && (is_pair(sig)) && (car(sig) != sc->IS_BOOLEAN)) return(wrong_type_argument_with_type(sc, sc->SORT, 2, lessp, make_string_wrapper(sc, "sort! function should return a boolean"))); compare_func = c_function_call(lessp); } else { if (is_closure(lessp)) { s7_pointer expr, largs; expr = car(closure_body(lessp)); largs = closure_args(lessp); if ((is_null(cdr(closure_body(lessp)))) && (is_optimized(expr))) { /* since (sort seq (lambda (a b) ...)) can't return a "safe closure" (the hop bit is off in * optimize in this case, for some arcane reason), the optimized expression won't be hop_safe, * but that is irrelevant at this point -- if c_function_is_ok, we're good to go. */ if ((is_pair(largs)) && (!arglist_has_rest(sc, largs)) && (((optimize_op(expr) & 1) != 0) || (c_function_is_ok(sc, expr)))) { int orig_data; orig_data = optimize_op(expr); set_optimize_op(expr, optimize_op(expr) | 1); if ((optimize_op(expr) == HOP_SAFE_C_SS) && (car(largs) == cadr(expr)) && (cadr(largs) == caddr(expr))) { lessp = find_symbol_unchecked(sc, car(expr)); compare_func = c_function_call(lessp); } else { if (!is_unsafe_sort(expr)) { new_frame_with_two_slots(sc, closure_let(lessp), sc->envir, car(largs), sc->F, cadr(largs), sc->F); set_stepper(let_slots(sc->envir)); set_stepper(next_slot(let_slots(sc->envir))); s7_xf_new(sc, sc->envir); compare_pf = xf_opt(sc, expr); if (compare_pf) { sort_func = pf_compare; compare_func = g_sort; /* whatever...(just a flag) */ compare_v1 = let_slots(sc->envir); compare_v2 = next_slot(let_slots(sc->envir)); } else { set_unsafe_sort(expr); s7_xf_free(sc); } } } set_optimize_op(expr, orig_data); } } if ((!compare_func) && (is_pair(largs)) && /* closure args not a symbol, etc */ (is_safe_closure(lessp))) /* no embedded sort! or call/cc, etc */ { new_frame_with_two_slots(sc, closure_let(lessp), sc->envir, car(largs), sc->F, cadr(largs), sc->F); compare_func = (s7_function)lessp; /* not used -- just a flag */ compare_args = car(closure_body(lessp)); compare_begin = cdr(closure_body(lessp)); if (is_null(compare_begin)) sort_func = closure_compare; else sort_func = closure_compare_begin; if (typesflag(compare_args) == SYNTACTIC_PAIR) { compare_op = (opcode_t)pair_syntax_op(compare_args); compare_args = cdr(compare_args); } else compare_op = OP_EVAL; compare_v1 = let_slots(sc->envir); compare_v2 = next_slot(let_slots(sc->envir)); } } } #if (!WITH_GMP) if (compare_func == g_less) compare_func = g_less_2; else { if (compare_func == g_greater) compare_func = g_greater_2; } #endif switch (type(data)) { case T_PAIR: len = s7_list_length(sc, data); /* 0 here == infinite */ if (len <= 0) { if (sort_func == pf_compare) s7_xf_free(sc); return(s7_error(sc, sc->WRONG_TYPE_ARG, set_elist_2(sc, make_string_wrapper(sc, "sort! argument 1 should be a proper list: ~S"), data))); } if (len < 2) { if (sort_func == pf_compare) s7_xf_free(sc); return(data); } if (compare_func) { int i; s7_pointer vec, p; vec = g_vector(sc, data); gc_loc = s7_gc_protect(sc, vec); elements = s7_vector_elements(vec); sc->v = vec; qsort((void *)elements, len, sizeof(s7_pointer), sort_func); for (p = data, i = 0; i < len; i++, p = cdr(p)) car(p) = elements[i]; s7_gc_unprotect_at(sc, gc_loc); if (sort_func == pf_compare) s7_xf_free(sc); return(data); } push_stack(sc, OP_SORT_PAIR_END, cons(sc, data, lessp), sc->code); /* save and gc protect the original list and func */ car(args) = g_vector(sc, data); break; case T_STRING: { /* byte-vectors here also, so this isn't completely silly */ int i; s7_pointer vec; unsigned char *chrs; len = string_length(data); if (len < 2) { if (sort_func == pf_compare) s7_xf_free(sc); return(data); } #if (!WITH_GMP) if (is_c_function(lessp)) { if (((!is_byte_vector(data)) && (compare_func == g_chars_are_less)) || ((is_byte_vector(data)) && (compare_func == g_less_2))) { qsort((void *)vector_elements(data), len, sizeof(unsigned char), byte_less); return(data); } if (((!is_byte_vector(data)) && (compare_func == g_chars_are_greater)) || ((is_byte_vector(data)) && (compare_func == g_greater_2))) { qsort((void *)vector_elements(data), len, sizeof(unsigned char), byte_greater); return(data); } } #endif vec = make_vector_1(sc, len, NOT_FILLED, T_VECTOR); gc_loc = s7_gc_protect(sc, vec); elements = s7_vector_elements(vec); chrs = (unsigned char *)string_value(data); if (is_byte_vector(data)) { for (i = 0; i < len; i++) elements[i] = small_int(chrs[i]); } else { for (i = 0; i < len; i++) elements[i] = chars[chrs[i]]; } if (compare_func) { sc->v = vec; qsort((void *)elements, len, sizeof(s7_pointer), sort_func); if (is_byte_vector(data)) { for (i = 0; i < len; i++) chrs[i] = (char)integer(elements[i]); } else { for (i = 0; i < len; i++) chrs[i] = character(elements[i]); } s7_gc_unprotect_at(sc, gc_loc); if (sort_func == pf_compare) s7_xf_free(sc); return(data); } push_stack(sc, OP_SORT_STRING_END, cons(sc, data, lessp), sc->code); car(args) = vec; s7_gc_unprotect_at(sc, gc_loc); } break; case T_INT_VECTOR: case T_FLOAT_VECTOR: { int i; s7_pointer vec; len = vector_length(data); if (len < 2) { if (sort_func == pf_compare) s7_xf_free(sc); return(data); } #if (!WITH_GMP) if (is_c_function(lessp)) { if (compare_func == g_less_2) { if (type(data) == T_FLOAT_VECTOR) qsort((void *)vector_elements(data), len, sizeof(s7_double), dbl_less); else qsort((void *)vector_elements(data), len, sizeof(s7_int), int_less); return(data); } if (compare_func == g_greater_2) { if (type(data) == T_FLOAT_VECTOR) qsort((void *)vector_elements(data), len, sizeof(s7_double), dbl_greater); else qsort((void *)vector_elements(data), len, sizeof(s7_int), int_greater); return(data); } } #endif /* currently we have to make the ordinary vector here even if not compare_func * because the sorter uses vector_element to access sort args (see SORT_DATA in eval). * This is probably better than passing down getter/setter (fewer allocations). * get/set macro in eval is SORT_DATA(k) then s7_vector_to_list if pair at start (sort_*_end) */ vec = make_vector_1(sc, len, FILLED, T_VECTOR); /* we need this vector prefilled because vector_getter below makes reals/int, causing possible GC * at any time during that loop, and the GC mark process expects the vector to have an s7_pointer * at every element. */ gc_loc = s7_gc_protect(sc, vec); elements = s7_vector_elements(vec); for (i = 0; i < len; i++) elements[i] = vector_getter(data)(sc, data, i); if (compare_func) { sc->v = vec; qsort((void *)elements, len, sizeof(s7_pointer), sort_func); for (i = 0; i < len; i++) vector_setter(data)(sc, data, i, elements[i]); s7_gc_unprotect_at(sc, gc_loc); if (sort_func == pf_compare) s7_xf_free(sc); return(data); } push_stack(sc, OP_SORT_VECTOR_END, cons(sc, data, lessp), sc->code); /* save and gc protect the original homogenous vector and func */ car(args) = vec; s7_gc_unprotect_at(sc, gc_loc); } break; case T_VECTOR: len = vector_length(data); if (len < 2) { if (sort_func == pf_compare) s7_xf_free(sc); return(data); } if (compare_func) { /* here if, for example, compare_func == stringSORT, args, A_SEQUENCE, 1); } if (sort_func == pf_compare) s7_xf_free(sc); n = len - 1; k = ((int)(n / 2)) + 1; lx = s7_make_vector(sc, (sc->safety == 0) ? 4 : 6); gc_loc = s7_gc_protect(sc, lx); sc->v = lx; vector_element(lx, 0) = make_mutable_integer(sc, n); vector_element(lx, 1) = make_mutable_integer(sc, k); vector_element(lx, 2) = make_mutable_integer(sc, 0); vector_element(lx, 3) = make_mutable_integer(sc, 0); if (sc->safety != 0) { vector_element(lx, 4) = make_mutable_integer(sc, 0); vector_element(lx, 5) = make_integer(sc, n * n); } push_stack(sc, OP_SORT, args, lx); s7_gc_unprotect_at(sc, gc_loc); return(sc->F); /* if the comparison function waffles, sort! can hang: (sort! '(1 2 3) (lambda (a b) (= a b))) * set 'safety to 1 to add a check for this loop, but the "safe" procedures are direct, so unchecked. */ } static s7_pointer c_sort_p(s7_scheme *sc, s7_pointer x, s7_pointer y) {return(g_sort(sc, set_plist_2(sc, x, y)));} PF2_TO_PF(sort, c_sort_p) /* these are for the eval sort -- sort a vector, then if necessary put that data into the original sequence */ static s7_pointer vector_into_list(s7_pointer vect, s7_pointer lst) { s7_pointer p; s7_pointer *elements; int i, len; elements = s7_vector_elements(vect); len = vector_length(vect); for (i = 0, p = lst; i < len; i++, p = cdr(p)) car(p) = elements[i]; return(lst); } static s7_pointer vector_into_fi_vector(s7_pointer source, s7_pointer dest) { s7_pointer *elements; int i, len; elements = s7_vector_elements(source); len = vector_length(source); if (is_float_vector(dest)) { s7_double *flts; flts = float_vector_elements(dest); for (i = 0; i < len; i++) flts[i] = real(elements[i]); } else { s7_int *ints; ints = int_vector_elements(dest); for (i = 0; i < len; i++) ints[i] = integer(elements[i]); } return(dest); } static s7_pointer vector_into_string(s7_pointer vect, s7_pointer dest) { s7_pointer *elements; int i, len; unsigned char *str; elements = s7_vector_elements(vect); len = vector_length(vect); str = (unsigned char *)string_value(dest); if (is_byte_vector(dest)) { for (i = 0; i < len; i++) str[i] = (unsigned char)integer(elements[i]); } else { for (i = 0; i < len; i++) str[i] = character(elements[i]); } return(dest); } /* -------- hash tables -------- */ static hash_entry_t *hash_free_list = NULL; static void free_hash_table(s7_pointer table) { hash_entry_t **entries; entries = hash_table_elements(table); if (hash_table_entries(table) > 0) { unsigned int i, len; len = hash_table_mask(table) + 1; for (i = 0; i < len; i++) { hash_entry_t *p, *n; for (p = entries[i++]; p; p = n) { n = p->next; p->next = hash_free_list; hash_free_list = p; } for (p = entries[i]; p; p = n) { n = p->next; p->next = hash_free_list; hash_free_list = p; } } } free(entries); } static hash_entry_t *make_hash_entry(s7_pointer key, s7_pointer value, unsigned int raw_hash) { hash_entry_t *p; if (hash_free_list) { p = hash_free_list; hash_free_list = p->next; } else p = (hash_entry_t *)malloc(sizeof(hash_entry_t)); p->key = key; p->value = value; p->raw_hash = raw_hash; return(p); } /* -------------------------------- hash-table? -------------------------------- */ bool s7_is_hash_table(s7_pointer p) { return(is_hash_table(p)); } static s7_pointer g_is_hash_table(s7_scheme *sc, s7_pointer args) { #define H_is_hash_table "(hash-table? obj) returns #t if obj is a hash-table" #define Q_is_hash_table pl_bt check_boolean_method(sc, is_hash_table, sc->IS_HASH_TABLE, args); } /* -------------------------------- hash-table-entries -------------------------------- */ static s7_pointer g_hash_table_entries(s7_scheme *sc, s7_pointer args) { #define H_hash_table_entries "(hash-table-entries obj) returns the number of entries in the hash-table obj" #define Q_hash_table_entries s7_make_signature(sc, 2, sc->IS_INTEGER, sc->IS_HASH_TABLE) if (!is_hash_table(car(args))) method_or_bust(sc, car(args), sc->HASH_TABLE_ENTRIES, args, T_HASH_TABLE, 0); return(make_integer(sc, hash_table_entries(car(args)))); } static s7_int c_hash_table_entries(s7_scheme *sc, s7_pointer p) { if (!is_hash_table(p)) int_method_or_bust(sc, p, sc->HASH_TABLE_ENTRIES, set_plist_1(sc, p), T_HASH_TABLE, 0); return(hash_table_entries(p)); } PF_TO_IF(hash_table_entries, c_hash_table_entries) /* ---------------- mappers ---------------- */ static unsigned int hash_float_location(s7_double x) { int loc; #if defined(__clang__) if ((is_inf(x)) || (is_NaN(x))) return(0); #endif x = fabs(x); if (x < 100.0) loc = 1000.0 * x; /* this means hash_table_float_epsilon only works if it is less than about .001 */ else loc = x; if (loc < 0) return(0); return(loc); } /* built in hash loc tables for eq? eqv? equal? morally-equal? = string=? string-ci=? char=? char-ci=? (default=equal?) */ #define hash_loc(Sc, Table, Key) (*(hash_table_mapper(Table)[type(Key)]))(Sc, Table, Key) static hash_map_t *eq_hash_map, *eqv_hash_map, *string_eq_hash_map, *number_eq_hash_map, *char_eq_hash_map, *closure_hash_map; static hash_map_t *morally_equal_hash_map, *c_function_hash_map; #if (!WITH_PURE_S7) static hash_map_t *string_ci_eq_hash_map, *char_ci_eq_hash_map; #endif static unsigned int hash_map_nil(s7_scheme *sc, s7_pointer table, s7_pointer key) {return(type(key));} static unsigned int hash_map_int(s7_scheme *sc, s7_pointer table, s7_pointer key) {return((unsigned int)(s7_int_abs(integer(key))));} static unsigned int hash_map_char(s7_scheme *sc, s7_pointer table, s7_pointer key) {return(character(key));} static unsigned int hash_map_ratio(s7_scheme *sc, s7_pointer table, s7_pointer key) {return((unsigned int)denominator(key));} /* overflow possible as elsewhere */ static unsigned int hash_map_complex(s7_scheme *sc, s7_pointer table, s7_pointer key) {return(hash_float_location(real_part(key)));} static unsigned int hash_map_symbol(s7_scheme *sc, s7_pointer table, s7_pointer key) {return(symbol_hmap(key));} static unsigned int hash_map_syntax(s7_scheme *sc, s7_pointer table, s7_pointer key) {return(symbol_hmap(syntax_symbol(key)));} #if WITH_GMP static unsigned int hash_map_big_int(s7_scheme *sc, s7_pointer table, s7_pointer key) { return((unsigned int)(big_integer_to_s7_int(big_integer(key)))); } static unsigned int hash_map_big_ratio(s7_scheme *sc, s7_pointer table, s7_pointer key) { return((unsigned int)(big_integer_to_s7_int(mpq_denref(big_ratio(key))))); } static unsigned int hash_map_big_real(s7_scheme *sc, s7_pointer table, s7_pointer key) { return((unsigned int)mpfr_get_d(big_real(key), GMP_RNDN)); } static unsigned int hash_map_big_complex(s7_scheme *sc, s7_pointer table, s7_pointer key) { return((unsigned int)mpfr_get_d(mpc_realref(big_complex(key)), GMP_RNDN)); } #endif static unsigned int hash_map_string(s7_scheme *sc, s7_pointer table, s7_pointer key) { if (string_hash(key) == 0) string_hash(key) = raw_string_hash((const unsigned char *)string_value(key), string_length(key)); return(string_hash(key)); } #if (!WITH_PURE_S7) static unsigned int hash_map_ci_char(s7_scheme *sc, s7_pointer table, s7_pointer key) {return(upper_character(key));} static unsigned int hash_map_ci_string(s7_scheme *sc, s7_pointer table, s7_pointer key) { int len; len = string_length(key); if (len == 0) return(0); return(len + (uppers[(int)(string_value(key)[0])] << 4)); } #endif static unsigned int hash_map_real(s7_scheme *sc, s7_pointer table, s7_pointer key) { return(hash_float_location(real(key))); /* currently 1e300 goes to most-negative-fixnum! -> 0 after logand size, I hope * * we need round, not floor for the location calculation in the real/complex cases else * 1-eps doesn't match 1.0, but 1+eps does. And what if round(val) is too big for int? * lrint is complex and requires special compiler flags to get any speed (-fno-math-errno). * all we need is (int)(val+0.5) -- all the other stuff is pointless in this context */ } static unsigned int hash_map_real_eq(s7_scheme *sc, s7_pointer table, s7_pointer x) { if (real(x) < 0.0) return((unsigned int)(s7_round(-real(x)))); return((unsigned int)s7_round(real(x))); } static unsigned int hash_map_ratio_eq(s7_scheme *sc, s7_pointer table, s7_pointer y) { s7_double x; x = fraction(y); if (x < 0.0) return((unsigned int)s7_round(-x)); return((unsigned int)s7_round(x)); } static unsigned int hash_map_hash_table(s7_scheme *sc, s7_pointer table, s7_pointer key) { /* hash-tables are equal if key/values match independent of table size and entry order. * if not using morally-equal?, hash_table_checker|mapper must also be the same. * Keys are supposed to be constant while keys, so a hash-table shouldn't be a key of itself. */ return(hash_table_entries(key)); } static unsigned int hash_map_int_vector(s7_scheme *sc, s7_pointer table, s7_pointer key) { if (vector_length(key) == 0) return(0); if (vector_length(key) == 1) return((unsigned int)(s7_int_abs(int_vector_element(key, 0)))); return((unsigned int)(vector_length(key) + s7_int_abs(int_vector_element(key, 0)) + s7_int_abs(int_vector_element(key, 1)))); } static unsigned int hash_map_float_vector(s7_scheme *sc, s7_pointer table, s7_pointer key) { if (vector_length(key) == 0) return(0); if (vector_length(key) == 1) return(hash_float_location(float_vector_element(key, 0))); return((unsigned int)(vector_length(key) + hash_float_location(float_vector_element(key, 0)) + hash_float_location(float_vector_element(key, 1)))); } static unsigned int hash_map_vector(s7_scheme *sc, s7_pointer table, s7_pointer key) { if ((vector_length(key) == 0) || (is_sequence(vector_element(key, 0)))) return(vector_length(key)); if ((vector_length(key) == 1) || (is_sequence(vector_element(key, 1)))) return(hash_loc(sc, table, vector_element(key, 0))); return(vector_length(key) + hash_loc(sc, table, vector_element(key, 0)) + hash_loc(sc, table, vector_element(key, 1))); } static unsigned int hash_map_eq(s7_scheme *sc, s7_pointer table, s7_pointer key) { int x; x = heap_location(key); if (x < 0) return(-x); return(x); } static unsigned int hash_map_closure(s7_scheme *sc, s7_pointer table, s7_pointer key) { s7_pointer f, old_e, args, body; f = hash_table_procedures_mapper(table); old_e = sc->envir; args = closure_args(f); body = closure_body(f); new_frame_with_slot(sc, closure_let(f), sc->envir, (is_symbol(car(args))) ? car(args) : caar(args), key); push_stack(sc, OP_EVAL_DONE, sc->args, sc->code); if (is_pair(cdr(body))) push_stack_no_args(sc, OP_BEGIN1, cdr(body)); sc->code = car(body); eval(sc, OP_EVAL); sc->envir = old_e; return(integer(sc->value)); } static unsigned int hash_map_c_function(s7_scheme *sc, s7_pointer table, s7_pointer key) { s7_function f; f = c_function_call(hash_table_procedures_mapper(table)); car(sc->T1_1) = key; return(integer(f(sc, sc->T1_1))); } static unsigned int hash_map_let(s7_scheme *sc, s7_pointer table, s7_pointer key) { /* lets are equal if same symbol/value pairs, independent of order, taking into account shadowing * (length (inlet 'a 1 'a 2)) = 2 * but this counts as just one entry from equal?'s point of view, so if more than one entry, we have a problem. * (equal? (inlet 'a 1) (inlet 'a 3 'a 2 'a 1)) = #t * also currently equal? follows outlet, but that is ridiculous here, so in this case hash equal? * is not the same as equal? Surely anyone using lets as keys wants eq? */ s7_pointer slot; int slots; if ((key == sc->rootlet) || (!is_slot(let_slots(key)))) return(0); slot = let_slots(key); if (!is_slot(next_slot(slot))) { if (is_sequence(slot_value(slot))) /* avoid loop if cycles */ return(symbol_hmap(slot_symbol(slot))); return(symbol_hmap(slot_symbol(slot)) + hash_loc(sc, table, slot_value(slot))); } slots = 0; for (; is_slot(slot); slot = next_slot(slot)) if (!is_matched_symbol(slot_symbol(slot))) { set_match_symbol(slot_symbol(slot)); slots++; } for (slot = let_slots(key); is_slot(slot); slot = next_slot(slot)) clear_match_symbol(slot_symbol(slot)); if (slots == 1) { slot = let_slots(key); if (is_sequence(slot_value(slot))) /* avoid loop if cycles */ return(symbol_hmap(slot_symbol(slot))); return(symbol_hmap(slot_symbol(slot)) + hash_loc(sc, table, slot_value(slot))); } return(slots); } static unsigned int hash_map_pair(s7_scheme *sc, s7_pointer table, s7_pointer key) { /* len+loc(car) is not horrible, but it means (for example) every list '(set! ...) is hashed to the same location, * so at least we need to take cadr into account if possible. Better would combine the list_length(max 5 == safe_strlen5?) call * with stats like symbols/pairs/constants at top level, then use those to spread it out over all the locs. */ s7_pointer p1; unsigned int loc = 0; if (!is_sequence(car(key))) loc = hash_loc(sc, table, car(key)) + 1; p1 = cdr(key); if ((is_pair(p1)) && (!is_sequence(car(p1)))) loc += hash_loc(sc, table, car(p1)) + 1; return(loc); } /* ---------------- checkers ---------------- */ static hash_entry_t *hash_empty(s7_scheme *sc, s7_pointer table, s7_pointer key) { return(NULL); } static hash_entry_t *hash_int(s7_scheme *sc, s7_pointer table, s7_pointer key) { if (is_integer(key)) { s7_int keyval; hash_entry_t *x; unsigned int loc, hash_len; hash_len = hash_table_mask(table); keyval = integer(key); if (keyval < 0) loc = (unsigned int)((-keyval) & hash_len); else loc = (unsigned int)(keyval & hash_len); /* I think this assumes hash_map_int is using s7_int_abs (and high order bits are ignored) */ for (x = hash_table_element(table, loc); x; x = x->next) if (integer(x->key) == keyval) return(x); } return(NULL); } static hash_entry_t *hash_string(s7_scheme *sc, s7_pointer table, s7_pointer key) { if (is_string(key)) { hash_entry_t *x; unsigned int hash_len, key_len; unsigned long long int hash; const char *key_str; key_len = string_length(key); key_str = string_value(key); hash_len = hash_table_mask(table); if (string_hash(key) == 0) string_hash(key) = raw_string_hash((const unsigned char *)string_value(key), string_length(key)); hash = string_hash(key); if (key_len <= 8) { for (x = hash_table_element(table, hash & hash_len); x; x = x->next) if ((hash == string_hash(x->key)) && (key_len == string_length(x->key))) return(x); } else { for (x = hash_table_element(table, hash & hash_len); x; x = x->next) if ((hash == string_hash(x->key)) && (key_len == string_length(x->key)) && /* these are scheme strings, so we can't assume 0=end of string */ (strings_are_equal_with_length(key_str, string_value(x->key), key_len))) return(x); } } return(NULL); } #if (!WITH_PURE_S7) static hash_entry_t *hash_ci_string(s7_scheme *sc, s7_pointer table, s7_pointer key) { if (is_string(key)) { hash_entry_t *x; unsigned int hash, hash_len; hash_len = hash_table_mask(table); hash = hash_map_ci_string(sc, table, key); for (x = hash_table_element(table, hash & hash_len); x; x = x->next) if (scheme_strequal_ci(key, x->key)) return(x); } return(NULL); } static hash_entry_t *hash_ci_char(s7_scheme *sc, s7_pointer table, s7_pointer key) { if (s7_is_character(key)) { hash_entry_t *x; unsigned int hash_len, loc; hash_len = hash_table_mask(table); loc = hash_loc(sc, table, key) & hash_len; for (x = hash_table_element(table, loc); x; x = x->next) if (upper_character(key) == upper_character(x->key)) return(x); } return(NULL); } #endif static hash_entry_t *hash_float_1(s7_scheme *sc, s7_pointer table, unsigned int loc, s7_double keyval) { hash_entry_t *x; bool look_for_nan; look_for_nan = is_NaN(keyval); for (x = hash_table_element(table, loc); x; x = x->next) { if (is_t_real(x->key)) /* we're possibly called from hash_equal, so keys might not be T_REAL */ { s7_double val; val = real(x->key); if (look_for_nan) { if (is_NaN(val)) return(x); } else { if ((val == keyval) || /* inf case */ (fabs(val - keyval) < sc->hash_table_float_epsilon)) return(x); } } } return(NULL); } static hash_entry_t *hash_float(s7_scheme *sc, s7_pointer table, s7_pointer key) { /* give the equality check some room. also inf == inf and nan == nan */ if (type(key) == T_REAL) { s7_double keyval; unsigned int hash_len, loc; hash_len = hash_table_mask(table); keyval = real(key); loc = hash_float_location(keyval) & hash_len; return(hash_float_1(sc, table, loc, keyval)); } return(NULL); } static hash_entry_t *hash_complex_1(s7_scheme *sc, s7_pointer table, unsigned int loc, s7_pointer key) { hash_entry_t *x; for (x = hash_table_element(table, loc); x; x = x->next) if ((is_t_complex(x->key)) && (s7_is_morally_equal(sc, x->key, key))) return(x); return(NULL); } static hash_entry_t *hash_equal_real(s7_scheme *sc, s7_pointer table, s7_pointer key) { return(hash_float_1(sc, table, hash_loc(sc, table, key) & hash_table_mask(table), real(key))); } static hash_entry_t *hash_equal_complex(s7_scheme *sc, s7_pointer table, s7_pointer key) { return(hash_complex_1(sc, table, hash_loc(sc, table, key) & hash_table_mask(table), key)); } static hash_entry_t *hash_equal_syntax(s7_scheme *sc, s7_pointer table, s7_pointer key) { hash_entry_t *x; unsigned int loc; loc = hash_loc(sc, table, key) & hash_table_mask(table); for (x = hash_table_element(table, loc); x; x = x->next) if ((is_syntax(x->key)) && (syntax_symbol(x->key) == syntax_symbol(key))) /* the opcodes might differ, but the symbols should not */ return(x); return(NULL); } static hash_entry_t *hash_equal_eq(s7_scheme *sc, s7_pointer table, s7_pointer key) { hash_entry_t *x; unsigned int loc; loc = hash_loc(sc, table, key) & hash_table_mask(table); for (x = hash_table_element(table, loc); x; x = x->next) if (x->key == key) return(x); return(NULL); } static hash_entry_t *hash_equal_any(s7_scheme *sc, s7_pointer table, s7_pointer key) { hash_entry_t *x; unsigned int loc; loc = hash_loc(sc, table, key) & hash_table_mask(table); /* we can get into an infinite loop here, but it requires 2 hash tables that are members of each other * and key is one of them, so I changed the equality check above to use eq? -- not sure this is right. */ /* hope for an easy case... */ for (x = hash_table_element(table, loc); x; x = x->next) if (x->key == key) return(x); for (x = hash_table_element(table, loc); x; x = x->next) if (s7_is_equal(sc, x->key, key)) return(x); return(NULL); } static hash_entry_t *(*default_hash_checks[NUM_TYPES])(s7_scheme *sc, s7_pointer table, s7_pointer key); static hash_entry_t *(*equal_hash_checks[NUM_TYPES])(s7_scheme *sc, s7_pointer table, s7_pointer key); static hash_entry_t *(*morally_equal_hash_checks[NUM_TYPES])(s7_scheme *sc, s7_pointer table, s7_pointer key); static hash_entry_t *hash_equal(s7_scheme *sc, s7_pointer table, s7_pointer key) { return((*(equal_hash_checks[type(key)]))(sc, table, key)); } static hash_entry_t *hash_morally_equal(s7_scheme *sc, s7_pointer table, s7_pointer key) { hash_entry_t *x; unsigned int loc; loc = hash_loc(sc, table, key) & hash_table_mask(table); for (x = hash_table_element(table, loc); x; x = x->next) if (x->key == key) return(x); for (x = hash_table_element(table, loc); x; x = x->next) if (s7_is_morally_equal(sc, x->key, key)) return(x); return(NULL); } static hash_entry_t *hash_c_function(s7_scheme *sc, s7_pointer table, s7_pointer key) { hash_entry_t *x; unsigned int hash_len, loc; s7_function f; f = c_function_call(hash_table_procedures_checker(table)); hash_len = hash_table_mask(table); loc = hash_loc(sc, table, key) & hash_len; car(sc->T2_1) = key; for (x = hash_table_element(table, loc); x; x = x->next) { car(sc->T2_2) = x->key; if (is_true(sc, f(sc, sc->T2_1))) return(x); } return(NULL); } static hash_entry_t *hash_eq(s7_scheme *sc, s7_pointer table, s7_pointer key) { /* explicit eq? as hash equality func or (for example) symbols as keys */ hash_entry_t *x; unsigned int hash_len, loc; hash_len = hash_table_mask(table); loc = hash_loc(sc, table, key) & hash_len; for (x = hash_table_element(table, loc); x; x = x->next) if (key == x->key) return(x); return(NULL); } static hash_entry_t *hash_eqv(s7_scheme *sc, s7_pointer table, s7_pointer key) { hash_entry_t *x; unsigned int hash_len, loc; hash_len = hash_table_mask(table); loc = hash_loc(sc, table, key) & hash_len; for (x = hash_table_element(table, loc); x; x = x->next) if (s7_is_eqv(key, x->key)) return(x); return(NULL); } static hash_entry_t *hash_number(s7_scheme *sc, s7_pointer table, s7_pointer key) { if (is_number(key)) { hash_entry_t *x; unsigned int hash_len, loc; hash_len = hash_table_mask(table); loc = hash_loc(sc, table, key) & hash_len; #if (!WITH_GMP) for (x = hash_table_element(table, loc); x; x = x->next) if ((is_number(x->key)) && (is_true(sc, c_equal_2_1(sc, key, x->key)))) return(x); #else for (x = hash_table_element(table, loc); x; x = x->next) if ((is_number(x->key)) && (is_true(sc, big_equal(sc, set_plist_2(sc, key, x->key))))) return(x); #endif } return(NULL); } static hash_entry_t *hash_symbol(s7_scheme *sc, s7_pointer table, s7_pointer key) { if (is_symbol(key)) { hash_entry_t *x; for (x = hash_table_element(table, symbol_hmap(key) & hash_table_mask(table)); x; x = x->next) if (key == x->key) return(x); } return(NULL); } static hash_entry_t *hash_char(s7_scheme *sc, s7_pointer table, s7_pointer key) { if (s7_is_character(key)) return(hash_eq(sc, table, key)); return(NULL); } static hash_entry_t *hash_closure(s7_scheme *sc, s7_pointer table, s7_pointer key) { hash_entry_t *x; unsigned int hash_len, loc; s7_pointer f, args, body, old_e; f = hash_table_procedures_checker(table); hash_len = hash_table_mask(table); loc = hash_loc(sc, table, key) & hash_len; old_e = sc->envir; args = closure_args(f); /* in lambda* case, car/cadr(args) can be lists */ body = closure_body(f); new_frame_with_two_slots(sc, closure_let(f), sc->envir, (is_symbol(car(args))) ? car(args) : caar(args), key, (is_symbol(cadr(args))) ? cadr(args) : caadr(args), sc->F); for (x = hash_table_element(table, loc); x; x = x->next) { slot_set_value(next_slot(let_slots(sc->envir)), x->key); push_stack(sc, OP_EVAL_DONE, sc->args, sc->code); if (is_pair(cdr(body))) push_stack_no_args(sc, OP_BEGIN1, cdr(body)); sc->code = car(body); eval(sc, OP_EVAL); if (is_true(sc, sc->value)) { sc->envir = old_e; return(x); } } sc->envir = old_e; return(NULL); } static s7_pointer remove_from_hash_table(s7_scheme *sc, s7_pointer table, s7_pointer key, hash_entry_t *p) { hash_entry_t *x; unsigned int hash_len, loc; hash_len = hash_table_mask(table); #if DEBUGGING if (p->raw_hash != hash_loc(sc, table, key)) fprintf(stderr, "%s[%d]: %s raw: %u, loc: %u\n", __func__, __LINE__, DISPLAY(key), p->raw_hash, hash_loc(sc, table, key)); #endif loc = p->raw_hash & hash_len; x = hash_table_element(table, loc); if (x == p) hash_table_element(table, loc) = x->next; else { hash_entry_t *y; for (y = x, x = x->next; x; y = x, x = x->next) if (x == p) { y->next = x->next; break; } #if DEBUGGING if (!x) fprintf(stderr, "lost %s!\n", DISPLAY(key)); #endif } hash_table_entries(table)--; if ((hash_table_entries(table) == 0) && (!hash_table_checker_locked(table))) hash_table_checker(table) = hash_empty; x->next = hash_free_list; hash_free_list = x; return(sc->F); } /* -------------------------------- make-hash-table -------------------------------- */ s7_pointer s7_make_hash_table(s7_scheme *sc, s7_int size) { s7_pointer table; hash_entry_t **els; /* size is rounded up to the next power of 2 */ if ((size & (size + 1)) != 0) /* already 2^n - 1 ? */ { size--; size |= (size >> 1); size |= (size >> 2); size |= (size >> 4); size |= (size >> 8); size |= (size >> 16); if (s7_int_bits > 31) /* this is either 31 or 63 */ size |= (size >> 32); } size++; els = (hash_entry_t **)calloc(size, sizeof(hash_entry_t *)); if (!els) return(s7_error(sc, make_symbol(sc, "out-of-memory"), set_elist_1(sc, make_string_wrapper(sc, "make-hash-table allocation failed!")))); new_cell(sc, table, T_HASH_TABLE | T_SAFE_PROCEDURE); hash_table_mask(table) = size - 1; hash_table_elements(table) = els; hash_table_checker(table) = hash_empty; hash_table_mapper(table) = default_hash_map; hash_table_entries(table) = 0; hash_table_procedures(table) = sc->F; add_hash_table(sc, table); return(table); } static s7_pointer g_is_equal(s7_scheme *sc, s7_pointer args); static s7_pointer g_is_morally_equal(s7_scheme *sc, s7_pointer args); static s7_pointer g_make_hash_table(s7_scheme *sc, s7_pointer args) { #define H_make_hash_table "(make-hash-table (size 511) eq-func) returns a new hash table" #define Q_make_hash_table s7_make_signature(sc, 3, sc->IS_HASH_TABLE, sc->IS_INTEGER, sc->IS_PAIR) s7_int size; size = sc->default_hash_table_length; if (is_not_null(args)) { s7_pointer p; p = car(args); if (!s7_is_integer(p)) { s7_pointer p1; if (!s7_is_integer(p1 = check_values(sc, p, args))) method_or_bust(sc, p, sc->MAKE_HASH_TABLE, args, T_INTEGER, 1); p = p1; } size = s7_integer(p); if (size <= 0) /* we need s7_int here to catch (make-hash-table most-negative-fixnum) etc */ return(simple_out_of_range(sc, sc->MAKE_HASH_TABLE, p, make_string_wrapper(sc, "should be a positive integer"))); if (size > sc->max_vector_length) return(simple_out_of_range(sc, sc->MAKE_HASH_TABLE, p, ITS_TOO_LARGE)); if (is_not_null(cdr(args))) { s7_pointer ht, proc; proc = cadr(args); if (is_c_function(proc)) { if (!s7_is_aritable(sc, proc, 2)) return(wrong_type_argument_with_type(sc, sc->MAKE_HASH_TABLE, 3, proc, AN_EQ_FUNC)); ht = s7_make_hash_table(sc, size); if (c_function_call(proc) == g_is_equal) return(ht); if (c_function_call(proc) == g_is_eq) { hash_table_checker(ht) = hash_eq; hash_table_mapper(ht) = eq_hash_map; } else { if (c_function_call(proc) == g_strings_are_equal) { hash_table_checker(ht) = hash_string; hash_table_mapper(ht) = string_eq_hash_map; } else { #if (!WITH_PURE_S7) if (c_function_call(proc) == g_strings_are_ci_equal) { hash_table_checker(ht) = hash_ci_string; hash_table_mapper(ht) = string_ci_eq_hash_map; } else { if (c_function_call(proc) == g_chars_are_ci_equal) { hash_table_checker(ht) = hash_ci_char; hash_table_mapper(ht) = char_ci_eq_hash_map; } else { #endif if (c_function_call(proc) == g_chars_are_equal) { hash_table_checker(ht) = hash_char; hash_table_mapper(ht) = char_eq_hash_map; } else { #if (!WITH_GMP) if (c_function_call(proc) == g_equal) #else if ((c_function_call(proc) == g_equal) || (c_function_call(proc) == big_equal)) #endif { hash_table_checker(ht) = hash_number; hash_table_mapper(ht) = number_eq_hash_map; } else { if (c_function_call(proc) == g_is_eqv) { hash_table_checker(ht) = hash_eqv; hash_table_mapper(ht) = eqv_hash_map; } else { if (c_function_call(proc) == g_is_morally_equal) { hash_table_checker(ht) = hash_morally_equal; hash_table_mapper(ht) = morally_equal_hash_map; } else return(wrong_type_argument_with_type(sc, sc->MAKE_HASH_TABLE, 3, proc, make_string_wrapper(sc, "a hash function"))); }}}}} #if (!WITH_PURE_S7) }} #endif return(ht); } /* proc not c_function */ else { if (is_pair(proc)) { s7_pointer checker, mapper; checker = car(proc); mapper = cdr(proc); if (((is_any_c_function(checker)) || (is_any_closure(checker))) && ((is_any_c_function(mapper)) || (is_any_closure(mapper))) && (s7_is_aritable(sc, checker, 2)) && (s7_is_aritable(sc, mapper, 1))) { s7_pointer sig; ht = s7_make_hash_table(sc, size); if (is_any_c_function(checker)) { sig = c_function_signature(checker); if ((sig) && (is_pair(sig)) && (car(sig) != sc->IS_BOOLEAN)) return(wrong_type_argument_with_type(sc, sc->MAKE_HASH_TABLE, 3, proc, make_string_wrapper(sc, "equality function should return a boolean"))); hash_table_checker(ht) = hash_c_function; } else hash_table_checker(ht) = hash_closure; if (is_any_c_function(mapper)) { sig = c_function_signature(mapper); if ((sig) && (is_pair(sig)) && (car(sig) != sc->IS_INTEGER)) return(wrong_type_argument_with_type(sc, sc->MAKE_HASH_TABLE, 3, proc, make_string_wrapper(sc, "mapping function should return an integer"))); hash_table_mapper(ht) = c_function_hash_map; } else hash_table_mapper(ht) = closure_hash_map; hash_table_procedures(ht) = proc; return(ht); } } return(wrong_type_argument_with_type(sc, sc->MAKE_HASH_TABLE, 3, proc, make_string_wrapper(sc, "a cons of two functions"))); } } } return(s7_make_hash_table(sc, size)); } void init_hash_maps(void) { int i; default_hash_map = (hash_map_t *)malloc(NUM_TYPES * sizeof(hash_map_t)); eq_hash_map = (hash_map_t *)malloc(NUM_TYPES * sizeof(hash_map_t)); eqv_hash_map = (hash_map_t *)malloc(NUM_TYPES * sizeof(hash_map_t)); string_eq_hash_map = (hash_map_t *)malloc(NUM_TYPES * sizeof(hash_map_t)); number_eq_hash_map = (hash_map_t *)malloc(NUM_TYPES * sizeof(hash_map_t)); char_eq_hash_map = (hash_map_t *)malloc(NUM_TYPES * sizeof(hash_map_t)); #if (!WITH_PURE_S7) string_ci_eq_hash_map = (hash_map_t *)malloc(NUM_TYPES * sizeof(hash_map_t)); char_ci_eq_hash_map = (hash_map_t *)malloc(NUM_TYPES * sizeof(hash_map_t)); #endif closure_hash_map = (hash_map_t *)malloc(NUM_TYPES * sizeof(hash_map_t)); c_function_hash_map = (hash_map_t *)malloc(NUM_TYPES * sizeof(hash_map_t)); morally_equal_hash_map = (hash_map_t *)malloc(NUM_TYPES * sizeof(hash_map_t)); for (i = 0; i < NUM_TYPES; i++) { default_hash_map[i] = hash_map_nil; string_eq_hash_map[i] = hash_map_nil; char_eq_hash_map[i] = hash_map_nil; #if (!WITH_PURE_S7) string_ci_eq_hash_map[i] = hash_map_nil; char_ci_eq_hash_map[i] = hash_map_nil; #endif number_eq_hash_map[i] = hash_map_nil; closure_hash_map[i] = hash_map_closure; c_function_hash_map[i] = hash_map_c_function; eq_hash_map[i] = hash_map_eq; eqv_hash_map[i] = hash_map_eq; equal_hash_checks[i] = hash_equal_any; morally_equal_hash_checks[i] = hash_equal_any; default_hash_checks[i] = hash_equal; } default_hash_map[T_INTEGER] = hash_map_int; default_hash_map[T_RATIO] = hash_map_ratio; default_hash_map[T_REAL] = hash_map_real; default_hash_map[T_COMPLEX] = hash_map_complex; default_hash_map[T_CHARACTER] = hash_map_char; default_hash_map[T_SYMBOL] = hash_map_symbol; default_hash_map[T_SYNTAX] = hash_map_syntax; default_hash_map[T_STRING] = hash_map_string; default_hash_map[T_HASH_TABLE] = hash_map_hash_table; default_hash_map[T_VECTOR] = hash_map_vector; default_hash_map[T_INT_VECTOR] = hash_map_int_vector; default_hash_map[T_FLOAT_VECTOR] = hash_map_float_vector; default_hash_map[T_LET] = hash_map_let; default_hash_map[T_PAIR] = hash_map_pair; #if WITH_GMP default_hash_map[T_BIG_INTEGER] = hash_map_big_int; default_hash_map[T_BIG_RATIO] = hash_map_big_ratio; default_hash_map[T_BIG_REAL] = hash_map_big_real; default_hash_map[T_BIG_COMPLEX] = hash_map_big_complex; #endif for (i = 0; i < NUM_TYPES; i++) morally_equal_hash_map[i] = default_hash_map[i]; string_eq_hash_map[T_STRING] = hash_map_string; char_eq_hash_map[T_CHARACTER] = hash_map_char; #if (!WITH_PURE_S7) string_ci_eq_hash_map[T_STRING] = hash_map_ci_string; char_ci_eq_hash_map[T_CHARACTER] = hash_map_ci_char; #endif number_eq_hash_map[T_INTEGER] = hash_map_int; number_eq_hash_map[T_RATIO] = hash_map_ratio_eq; number_eq_hash_map[T_REAL] = hash_map_real_eq; number_eq_hash_map[T_COMPLEX] = hash_map_complex; #if (WITH_GMP) number_eq_hash_map[T_BIG_INTEGER] = hash_map_big_int; number_eq_hash_map[T_BIG_RATIO] = hash_map_big_ratio; number_eq_hash_map[T_BIG_REAL] = hash_map_big_real; number_eq_hash_map[T_BIG_COMPLEX] = hash_map_big_complex; #endif eqv_hash_map[T_INTEGER] = hash_map_int; eqv_hash_map[T_RATIO] = hash_map_ratio_eq; eqv_hash_map[T_REAL] = hash_map_real_eq; eqv_hash_map[T_COMPLEX] = hash_map_complex; morally_equal_hash_map[T_INTEGER] = hash_map_int; morally_equal_hash_map[T_RATIO] = hash_map_ratio_eq; morally_equal_hash_map[T_REAL] = hash_map_real_eq; morally_equal_hash_map[T_COMPLEX] = hash_map_complex; equal_hash_checks[T_REAL] = hash_equal_real; equal_hash_checks[T_COMPLEX] = hash_equal_complex; equal_hash_checks[T_SYNTAX] = hash_equal_syntax; equal_hash_checks[T_SYMBOL] = hash_equal_eq; equal_hash_checks[T_CHARACTER] = hash_equal_eq; default_hash_checks[T_STRING] = hash_string; default_hash_checks[T_INTEGER] = hash_int; default_hash_checks[T_REAL] = hash_float; default_hash_checks[T_SYMBOL] = hash_symbol; default_hash_checks[T_CHARACTER] = hash_char; } static unsigned int resize_hash_table(s7_scheme *sc, s7_pointer table) { /* resize the table */ unsigned int hash_len, loc; int i, old_size, new_size; hash_entry_t **new_els, **old_els; old_size = hash_table_mask(table) + 1; new_size = old_size * 4; hash_len = new_size - 1; new_els = (hash_entry_t **)calloc(new_size, sizeof(hash_entry_t *)); old_els = hash_table_elements(table); for (i = 0; i < old_size; i++) { hash_entry_t *x, *n; for (x = old_els[i]; x; x = n) { n = x->next; loc = x->raw_hash & hash_len; x->next = new_els[loc]; new_els[loc] = x; } } hash_table_elements(table) = new_els; free(old_els); hash_table_mask(table) = new_size - 1; return(hash_len); } /* -------------------------------- hash-table-ref -------------------------------- */ s7_pointer s7_hash_table_ref(s7_scheme *sc, s7_pointer table, s7_pointer key) { hash_entry_t *x; x = (*hash_table_checker(table))(sc, table, key); if (x) return(x->value); return(sc->F); } static s7_pointer g_hash_table_ref(s7_scheme *sc, s7_pointer args) { #define H_hash_table_ref "(hash-table-ref table key) returns the value associated with key in the hash table" #define Q_hash_table_ref s7_make_signature(sc, 3, sc->T, sc->IS_HASH_TABLE, sc->T) s7_pointer table; table = car(args); if (!is_hash_table(table)) method_or_bust(sc, table, sc->HASH_TABLE_REF, args, T_HASH_TABLE, 1); /* (define (href H . args) (if (null? (cdr args)) (hash-table-ref H (car args)) (apply href (hash-table-ref H (car args)) (cdr args)))) */ if (is_null(cddr(args))) return(s7_hash_table_ref(sc, table, cadr(args))); return(implicit_index(sc, s7_hash_table_ref(sc, table, cadr(args)), cddr(args))); } static s7_pointer hash_table_ref_2; static s7_pointer g_hash_table_ref_2(s7_scheme *sc, s7_pointer args) { s7_pointer table; hash_entry_t *x; table = car(args); if (!is_hash_table(table)) method_or_bust(sc, table, sc->HASH_TABLE_REF, args, T_HASH_TABLE, 1); x = (*hash_table_checker(table))(sc, table, cadr(args)); if (x) return(x->value); return(sc->F); } static s7_pointer hash_table_ref_ss; static s7_pointer g_hash_table_ref_ss(s7_scheme *sc, s7_pointer args) { s7_pointer table; hash_entry_t *x; table = find_symbol_checked(sc, car(args)); if (!is_hash_table(table)) method_or_bust(sc, table, sc->HASH_TABLE_REF, list_2(sc, table, find_symbol_checked(sc, cadr(args))), T_HASH_TABLE, 1); x = (*hash_table_checker(table))(sc, table, find_symbol_checked(sc, cadr(args))); if (x) return(x->value); return(sc->F); } static s7_pointer hash_table_ref_car; static s7_pointer g_hash_table_ref_car(s7_scheme *sc, s7_pointer args) { s7_pointer y, table; hash_entry_t *x; table = find_symbol_checked(sc, car(args)); if (!is_hash_table(table)) method_or_bust(sc, table, sc->HASH_TABLE_REF, list_2(sc, table, car(find_symbol_checked(sc, cadadr(args)))), T_HASH_TABLE, 1); y = find_symbol_checked(sc, cadadr(args)); if (!is_pair(y)) return(simple_wrong_type_argument(sc, sc->CAR, y, T_PAIR)); x = (*hash_table_checker(table))(sc, table, car(y)); if (x) return(x->value); return(sc->F); } static s7_pointer hash_table_ref_pf_a(s7_scheme *sc, s7_pointer **p) { s7_pf_t f; s7_pointer x, y; f = (s7_pf_t)(**p); (*p)++; x = f(sc, p); f = (s7_pf_t)(**p); (*p)++; y = f(sc, p); return(s7_hash_table_ref(sc, x, y)); } static s7_pointer hash_table_ref_pf_i(s7_scheme *sc, s7_pointer **p) /* i=implicit I think */ { s7_pf_t f; s7_pointer x, y; x = slot_value(**p); (*p)++; f = (s7_pf_t)(**p); (*p)++; y = f(sc, p); return(s7_hash_table_ref(sc, x, y)); } static s7_pointer hash_table_ref_pf_s(s7_scheme *sc, s7_pointer **p) { s7_pf_t f; s7_pointer x, y; hash_entry_t *h; x = (**p); (*p)++; f = (s7_pf_t)(**p); (*p)++; y = f(sc, p); h = (*hash_table_checker(x))(sc, x, y); if (h) return(h->value); return(sc->F); } static s7_pointer hash_table_ref_pf_ps(s7_scheme *sc, s7_pointer **p) { s7_pointer x, y; x = (**p); (*p) += 2; y = slot_value(**p); (*p)++; return(s7_hash_table_ref(sc, x, y)); } static s7_pointer hash_table_ref_pf_r(s7_scheme *sc, s7_pointer **p) { s7_rf_t f; s7_pointer x; s7_double y; int hash_len; hash_entry_t *h; x = (**p); (*p)++; f = (s7_rf_t)(**p); (*p)++; y = f(sc, p); hash_len = hash_table_mask(x); h = hash_float_1(sc, x, hash_float_location(y) & hash_len, y); if (h) return(h->value); return(sc->F); } static s7_pf_t hash_table_ref_pf(s7_scheme *sc, s7_pointer expr) { if ((is_pair(cdr(expr))) && (is_pair(cddr(expr))) && (is_null(cdddr(expr)))) { s7_pointer a1; a1 = cadr(expr); if (is_symbol(a1)) { s7_pointer table; table = s7_slot(sc, a1); if ((is_slot(table)) && (!is_stepper(table)) && (is_hash_table(slot_value(table)))) { ptr_int loc; s7_pointer a2; a2 = caddr(expr); s7_xf_store(sc, slot_value(table)); loc = rc_loc(sc); if (s7_arg_to_pf(sc, a2)) return((is_symbol(a2)) ? hash_table_ref_pf_ps : hash_table_ref_pf_s); sc->cur_rf->cur = rc_go(sc, loc); if (s7_arg_to_gf(sc, a2)) return((is_symbol(a2)) ? hash_table_ref_pf_ps : hash_table_ref_pf_s); sc->cur_rf->cur = rc_go(sc, loc); if (s7_arg_to_rf(sc, a2)) return(hash_table_ref_pf_r); return(NULL); } } if ((s7_arg_to_pf(sc, cadr(expr))) && (s7_arg_to_pf(sc, caddr(expr)))) return(hash_table_ref_pf_a); } return(NULL); } /* -------------------------------- hash-table-set! -------------------------------- */ static void hash_table_set_function(s7_pointer table, int typ) { if ((hash_table_checker(table) != hash_equal) && (hash_table_checker(table) != default_hash_checks[typ])) { if (hash_table_checker(table) == hash_empty) hash_table_checker(table) = default_hash_checks[typ]; else hash_table_checker(table) = hash_equal; } } s7_pointer s7_hash_table_set(s7_scheme *sc, s7_pointer table, s7_pointer key, s7_pointer value) { hash_entry_t *x; x = (*hash_table_checker(table))(sc, table, key); if (x) { if (value == sc->F) return(remove_from_hash_table(sc, table, key, x)); x->value = value; } else { unsigned int hash_len, raw_hash, loc; hash_entry_t *p; if (value == sc->F) return(sc->F); if (!hash_table_checker_locked(table)) hash_table_set_function(table, type(key)); hash_len = hash_table_mask(table); if (hash_table_entries(table) > hash_len) hash_len = resize_hash_table(sc, table); raw_hash = hash_loc(sc, table, key); if (!hash_free_list) { int i; hash_free_list = (hash_entry_t *)malloc(16 * sizeof(hash_entry_t)); for (p = hash_free_list, i = 0; i < 15; i++) {p->next = p + 1; p++;} p->next = NULL; } p = hash_free_list; hash_free_list = p->next; p->key = key; p->value = value; p->raw_hash = raw_hash; loc = raw_hash & hash_len; p->next = hash_table_element(table, loc); hash_table_element(table, loc) = p; hash_table_entries(table)++; } return(value); } static s7_pointer hash_table_set_pf_sxs(s7_scheme *sc, s7_pointer **p) { s7_pointer key, table, value; s7_pf_t pf; table = slot_value(**p); (*p)++; pf = (s7_pf_t)(**p); (*p)++; key = pf(sc, p); value = slot_value(**p); (*p)++; return(s7_hash_table_set(sc, table, key, value)); } static s7_pointer hash_table_set_pf_sxx(s7_scheme *sc, s7_pointer **p) { s7_pointer key, table, value; s7_pf_t pf; table = slot_value(**p); (*p)++; pf = (s7_pf_t)(**p); (*p)++; key = pf(sc, p); pf = (s7_pf_t)(**p); (*p)++; value = pf(sc, p); return(s7_hash_table_set(sc, table, key, value)); } static s7_pointer hash_table_set_pf_sss(s7_scheme *sc, s7_pointer **p) { s7_pointer key, table, value; table = slot_value(**p); (*p)++; key = slot_value(**p); (*p)++; value = slot_value(**p); (*p)++; return(s7_hash_table_set(sc, table, key, value)); } static s7_pointer hash_table_set_pf_ssx(s7_scheme *sc, s7_pointer **p) { s7_pf_t pf; s7_pointer key, table, value; table = slot_value(**p); (*p)++; key = slot_value(**p); (*p)++; pf = (s7_pf_t)(**p); (*p)++; value = pf(sc, p); return(s7_hash_table_set(sc, table, key, value)); } static s7_pf_t hash_table_set_pf(s7_scheme *sc, s7_pointer expr) { if ((is_pair(cdr(expr))) && (is_pair(cddr(expr))) && (is_pair(cdddr(expr))) && (is_null(cddddr(expr)))) { s7_pointer a1, a2, a3; a1 = cadr(expr); a2 = caddr(expr); a3 = cadddr(expr); if (is_symbol(a1)) { xf_t *rc; a1 = s7_slot(sc, a1); if ((!is_slot(a1)) || (!is_hash_table(slot_value(a1))) || (is_stepper(a1))) return(NULL); xf_init(3); xf_store(a1); if (is_symbol(a2)) { a2 = s7_slot(sc, a2); if (!is_slot(a2)) return(NULL); xf_store(a2); } else { ptr_int loc; loc = rc_loc(sc); if (!s7_arg_to_pf(sc, a2)) { sc->cur_rf->cur = rc_go(sc, loc); if (!s7_arg_to_gf(sc, a2)) return(NULL); } } if (is_symbol(a3)) { a3 = s7_slot(sc, a3); if (!is_slot(a3)) return(NULL); xf_store(a3); return((is_slot(a2)) ? hash_table_set_pf_sss : hash_table_set_pf_sxs); } else { ptr_int loc; loc = rc_loc(sc); if (!s7_arg_to_pf(sc, a3)) { sc->cur_rf->cur = rc_go(sc, loc); if (!s7_arg_to_gf(sc, a3)) return(NULL); } return((is_slot(a2)) ? hash_table_set_pf_ssx : hash_table_set_pf_sxx); } } } return(NULL); } static s7_pointer g_hash_table_set(s7_scheme *sc, s7_pointer args) { #define H_hash_table_set "(hash-table-set! table key value) sets the value associated with key in the hash table to value" #define Q_hash_table_set s7_make_signature(sc, 4, sc->T, sc->IS_HASH_TABLE, sc->T, sc->T) s7_pointer table; table = car(args); if (!is_hash_table(table)) method_or_bust(sc, table, sc->HASH_TABLE_SET, args,T_HASH_TABLE, 1); return(s7_hash_table_set(sc, table, cadr(args), caddr(args))); } /* -------------------------------- hash-table -------------------------------- */ static s7_pointer g_hash_table(s7_scheme *sc, s7_pointer args) { #define H_hash_table "(hash-table ...) returns a hash-table containing the cons's passed as its arguments. \ That is, (hash-table '(\"hi\" . 3) (\"ho\" . 32)) returns a new hash-table with the two key/value pairs preinstalled." #define Q_hash_table s7_make_circular_signature(sc, 1, 2, sc->IS_HASH_TABLE, sc->IS_LIST) int len; s7_pointer x, ht; /* this accepts repeated keys: (hash-table '(a . 1) '(a . 1)) */ for (len = 0, x = args; is_pair(x); x = cdr(x), len++) if ((!is_pair(car(x))) && (!is_null(car(x)))) return(wrong_type_argument(sc, sc->HASH_TABLE, position_of(x, args), car(x), T_PAIR)); ht = s7_make_hash_table(sc, (len > sc->default_hash_table_length) ? len : sc->default_hash_table_length); if (len > 0) { int ht_loc; ht_loc = s7_gc_protect(sc, ht); /* hash_table_set can cons, so we need to protect this */ for (x = args; is_pair(x); x = cdr(x)) if (is_pair(car(x))) s7_hash_table_set(sc, ht, caar(x), cdar(x)); s7_gc_unprotect_at(sc, ht_loc); } return(ht); } /* -------------------------------- hash-table* -------------------------------- */ static s7_pointer g_hash_table_star(s7_scheme *sc, s7_pointer args) { #define H_hash_table_star "(hash-table* ...) returns a hash-table containing the symbol/value pairs passed as its arguments. \ That is, (hash-table* 'a 1 'b 2) returns a new hash-table with the two key/value pairs preinstalled." #define Q_hash_table_star s7_make_circular_signature(sc, 1, 2, sc->IS_HASH_TABLE, sc->T) int len; s7_pointer ht; len = safe_list_length(sc, args); if (len & 1) return(s7_error(sc, sc->WRONG_NUMBER_OF_ARGS, set_elist_2(sc, make_string_wrapper(sc, "hash-table* got an odd number of arguments: ~S"), args))); len /= 2; ht = s7_make_hash_table(sc, (len > sc->default_hash_table_length) ? len : sc->default_hash_table_length); if (len > 0) { int ht_loc; s7_pointer x, y; ht_loc = s7_gc_protect(sc, ht); /* hash_table_set can cons, so we need to protect this */ for (x = args, y = cdr(args); is_pair(y); x = cddr(x), y = cddr(y)) s7_hash_table_set(sc, ht, car(x), car(y)); s7_gc_unprotect_at(sc, ht_loc); } return(ht); } static s7_pointer hash_table_copy(s7_scheme *sc, s7_pointer old_hash, s7_pointer new_hash, unsigned int start, unsigned int end) { unsigned int i, old_len, new_len, count = 0; hash_entry_t **old_lists, **new_lists; hash_entry_t *x, *p; old_len = hash_table_mask(old_hash) + 1; new_len = hash_table_mask(new_hash); old_lists = hash_table_elements(old_hash); new_lists = hash_table_elements(new_hash); if (hash_table_entries(new_hash) == 0) { hash_table_checker(new_hash) = hash_table_checker(old_hash); for (i = 0; i < old_len; i++) for (x = old_lists[i]; x; x = x->next) { if (count >= end) { hash_table_entries(new_hash) = end - start; return(new_hash); } if (count >= start) { unsigned int loc; loc = x->raw_hash & new_len; p = make_hash_entry(x->key, x->value, x->raw_hash); p->next = new_lists[loc]; new_lists[loc] = p; } count++; } hash_table_entries(new_hash) = count - start; return(new_hash); } /* this can't be optimized much because we have to look for key matches */ for (i = 0; i < old_len; i++) for (x = old_lists[i]; x; x = x->next) { if (count >= end) return(new_hash); if (count >= start) { hash_entry_t *y; y = (*hash_table_checker(new_hash))(sc, new_hash, x->key); if (y) y->value = x->value; else { unsigned int loc; loc = x->raw_hash & new_len; p = make_hash_entry(x->key, x->value, x->raw_hash); p->next = new_lists[loc]; new_lists[loc] = p; hash_table_entries(new_hash)++; if (!hash_table_checker_locked(new_hash)) hash_table_set_function(new_hash, type(x->key)); } } count++; } return(new_hash); } s7_pointer hash_table_fill(s7_scheme *sc, s7_pointer args) { s7_pointer val, table; table = car(args); val = cadr(args); if (hash_table_entries(table) > 0) { int len; hash_entry_t **entries; entries = hash_table_elements(table); len = hash_table_mask(table) + 1; /* hash-table-ref returns #f if it can't find a key, so val == #f here means empty the table */ if (val == sc->F) { hash_entry_t **hp, **hn; hash_entry_t *p; hp = entries; hn = (hash_entry_t **)(hp + len); for (; hp < hn; hp++) { if (*hp) { p = *hp; while (p->next) p = p->next; p->next = hash_free_list; hash_free_list = *hp; } hp++; if (*hp) { p = *hp; while (p->next) p = p->next; p->next = hash_free_list; hash_free_list = *hp; } } memset(entries, 0, len * sizeof(hash_entry_t *)); if (!hash_table_checker_locked(table)) hash_table_checker(table) = hash_empty; hash_table_entries(table) = 0; } else { int i; hash_entry_t *x; for (i = 0; i < len; i++) for (x = entries[i]; x; x = x->next) x->value = val; /* keys haven't changed, so no need to mess with hash_table_checker */ } } return(val); } static s7_pointer hash_table_reverse(s7_scheme *sc, s7_pointer old_hash) { int i, len; s7_pointer new_hash; hash_entry_t **old_lists; int gc_loc; len = hash_table_mask(old_hash) + 1; new_hash = s7_make_hash_table(sc, len); gc_loc = s7_gc_protect(sc, new_hash); /* I don't think the original hash functions can make any sense in general, so ignore them */ old_lists = hash_table_elements(old_hash); for (i = 0; i < len; i++) { hash_entry_t *x; for (x = old_lists[i]; x; x = x->next) s7_hash_table_set(sc, new_hash, x->value, x->key); } s7_gc_unprotect_at(sc, gc_loc); return(new_hash); } /* -------------------------------- functions -------------------------------- */ bool s7_is_function(s7_pointer p) { return(is_c_function(p)); } static s7_pointer fallback_chooser(s7_scheme *sc, s7_pointer f, int args, s7_pointer expr) { return(f); } static void s7_function_set_class(s7_pointer f, s7_pointer base_f) { c_function_class(f) = c_function_class(base_f); c_function_base(f) = base_f; } static int c_functions = 0; s7_pointer s7_make_function(s7_scheme *sc, const char *name, s7_function f, int required_args, int optional_args, bool rest_arg, const char *doc) { c_proc_t *ptr; unsigned int ftype = T_C_FUNCTION; s7_pointer x; x = alloc_pointer(); unheap(x); ptr = (c_proc_t *)malloc(sizeof(c_proc_t)); c_functions++; if (required_args == 0) { if (rest_arg) ftype = T_C_ANY_ARGS_FUNCTION; else { if (optional_args != 0) ftype = T_C_OPT_ARGS_FUNCTION; /* a thunk needs to check for no args passed */ } } else { if (rest_arg) ftype = T_C_RST_ARGS_FUNCTION; } set_type(x, ftype | T_PROCEDURE); c_function_data(x) = ptr; c_function_call(x) = f; c_function_base(x) = x; c_function_setter(x) = sc->F; c_function_name(x) = name; /* (procedure-name proc) => (format #f "~A" proc) */ c_function_name_length(x) = safe_strlen(name); if (doc) c_function_documentation(x) = make_permanent_string(doc); else c_function_documentation(x) = NULL; c_function_signature(x) = sc->F; c_function_required_args(x) = required_args; c_function_optional_args(x) = optional_args; c_function_has_rest_arg(x) = rest_arg; if (rest_arg) c_function_all_args(x) = MAX_ARITY; else c_function_all_args(x) = required_args + optional_args; c_function_class(x) = ++sc->f_class; c_function_chooser(x) = fallback_chooser; c_function_rp(x) = NULL; c_function_ip(x) = NULL; c_function_pp(x) = NULL; c_function_gp(x) = NULL; return(x); } s7_pointer s7_make_safe_function(s7_scheme *sc, const char *name, s7_function f, int required_args, int optional_args, bool rest_arg, const char *doc) { s7_pointer p; p = s7_make_function(sc, name, f, required_args, optional_args, rest_arg, doc); typeflag(p) |= T_SAFE_PROCEDURE; /* not set_type(p, type(p) ...) because that accidentally clears the T_PROCEDURE bit */ return(p); } s7_pointer s7_make_typed_function(s7_scheme *sc, const char *name, s7_function f, int required_args, int optional_args, bool rest_arg, const char *doc, s7_pointer signature) { s7_pointer func; func = s7_make_function(sc, name, f, required_args, optional_args, rest_arg, doc); typeflag(func) |= T_SAFE_PROCEDURE; if (signature) c_function_signature(func) = signature; return(func); } bool s7_is_procedure(s7_pointer x) { return(is_procedure(x)); /* this returns "is applicable" so it is true for applicable c_objects, macros, etc */ } static s7_pointer g_is_procedure(s7_scheme *sc, s7_pointer args) { #define H_is_procedure "(procedure? obj) returns #t if obj is a procedure" #define Q_is_procedure pl_bt s7_pointer x; int typ; x = car(args); if ((!is_procedure(x)) || (is_c_object(x))) { check_method(sc, x, sc->IS_PROCEDURE, args); return(sc->F); } typ = type(x); /* make_object sets the T_PROCEDURE bit if the object has an apply function, * but we currently return (procedure? "hi") -> #f, so we can't simply use * is_procedure. * * Unfortunately much C code depends on s7_is_procedure treating applicable * objects and macros as procedures. We can use arity = applicable? */ return(make_boolean(sc, (typ == T_CLOSURE) || (typ == T_CLOSURE_STAR) || (typ >= T_C_FUNCTION_STAR) || (typ == T_GOTO) || (typ == T_CONTINUATION))); } static void s7_function_set_setter(s7_scheme *sc, const char *getter, const char *setter) { /* this is internal, used only with c_function setters, so we don't need to worry about the GC mark choice */ c_function_setter(s7_name_to_value(sc, getter)) = s7_name_to_value(sc, setter); } s7_pointer s7_closure_body(s7_scheme *sc, s7_pointer p) { if (has_closure_let(p)) return(closure_body(p)); return(sc->NIL); } s7_pointer s7_closure_let(s7_scheme *sc, s7_pointer p) { if (has_closure_let(p)) return(closure_let(p)); return(sc->NIL); } s7_pointer s7_closure_args(s7_scheme *sc, s7_pointer p) { if (has_closure_let(p)) return(closure_args(p)); return(sc->NIL); } static s7_pointer c_procedure_source(s7_scheme *sc, s7_pointer p) { /* make it look like a scheme-level lambda */ if (is_symbol(p)) { p = s7_symbol_value(sc, p); if (p == sc->UNDEFINED) return(s7_error(sc, sc->WRONG_TYPE_ARG, set_elist_2(sc, make_string_wrapper(sc, "procedure-source arg, '~S, is unbound"), p))); } if ((is_c_function(p)) || (is_c_macro(p))) return(sc->NIL); check_method(sc, p, sc->PROCEDURE_SOURCE, list_1(sc, p)); if (has_closure_let(p)) { s7_pointer body; body = closure_body(p); if (is_safe_closure(body)) clear_safe_closure(body); return(append_in_place(sc, list_2(sc, ((is_closure_star(p)) || (is_macro_star(p)) || (is_bacro_star(p))) ? sc->LAMBDA_STAR : sc->LAMBDA, closure_args(p)), body)); } if (!is_procedure(p)) return(simple_wrong_type_argument_with_type(sc, sc->PROCEDURE_SOURCE, p, make_string_wrapper(sc, "a procedure or a macro"))); return(sc->NIL); } static s7_pointer g_procedure_source(s7_scheme *sc, s7_pointer args) { #define H_procedure_source "(procedure-source func) tries to return the definition of func" #define Q_procedure_source s7_make_signature(sc, 2, sc->IS_LIST, sc->IS_PROCEDURE) return(c_procedure_source(sc, car(args))); } PF_TO_PF(procedure_source, c_procedure_source) s7_pointer s7_funclet(s7_scheme *sc, s7_pointer p) { if (has_closure_let(p)) return(closure_let(p)); return(sc->rootlet); } static s7_pointer g_funclet(s7_scheme *sc, s7_pointer args) { s7_pointer p, e; #define H_funclet "(funclet func) tries to return an object's environment" #define Q_funclet s7_make_signature(sc, 2, sc->IS_LET, sc->IS_PROCEDURE) /* this procedure gives direct access to a function's closure -- see s7test.scm * for some wild examples. At least it provides a not-too-kludgey way for several functions * to share a closure. */ p = car(args); if (is_symbol(p)) { p = s7_symbol_value(sc, p); if (p == sc->UNDEFINED) return(s7_error(sc, sc->WRONG_TYPE_ARG, set_elist_2(sc, make_string_wrapper(sc, "funclet arg, '~S, is unbound"), car(args)))); /* not p here */ } check_method(sc, p, sc->FUNCLET, args); if (!is_procedure_or_macro(p)) return(simple_wrong_type_argument_with_type(sc, sc->FUNCLET, p, make_string_wrapper(sc, "a procedure or a macro"))); e = find_let(sc, p); if ((is_null(e)) && (!is_c_object(p))) return(sc->rootlet); return(e); } s7_pointer s7_define_function(s7_scheme *sc, const char *name, s7_function fnc, int required_args, int optional_args, bool rest_arg, const char *doc) { s7_pointer func, sym; func = s7_make_function(sc, name, fnc, required_args, optional_args, rest_arg, doc); sym = make_symbol(sc, name); s7_define(sc, sc->NIL, sym, func); return(sym); } s7_pointer s7_define_safe_function(s7_scheme *sc, const char *name, s7_function fnc, int required_args, int optional_args, bool rest_arg, const char *doc) { /* returns (string->symbol name), not the c_proc_t func */ s7_pointer func, sym; func = s7_make_safe_function(sc, name, fnc, required_args, optional_args, rest_arg, doc); sym = make_symbol(sc, name); s7_define(sc, sc->NIL, sym, func); return(sym); } s7_pointer s7_define_typed_function(s7_scheme *sc, const char *name, s7_function fnc, int required_args, int optional_args, bool rest_arg, const char *doc, s7_pointer signature) { /* returns (string->symbol name), not the c_proc_t func */ s7_pointer func, sym; func = s7_make_typed_function(sc, name, fnc, required_args, optional_args, rest_arg, doc, signature); sym = make_symbol(sc, name); s7_define(sc, sc->NIL, sym, func); return(sym); } static s7_pointer s7_define_unsafe_typed_function(s7_scheme *sc, const char *name, s7_function fnc, int required_args, int optional_args, bool rest_arg, const char *doc, s7_pointer signature) { /* returns (string->symbol name), not the c_proc_t func */ s7_pointer func, sym; func = s7_make_function(sc, name, fnc, required_args, optional_args, rest_arg, doc); if (signature) c_function_signature(func) = signature; sym = make_symbol(sc, name); s7_define(sc, sc->NIL, sym, func); return(sym); } s7_pointer s7_define_macro(s7_scheme *sc, const char *name, s7_function fnc, int required_args, int optional_args, bool rest_arg, const char *doc) { s7_pointer func, sym; func = s7_make_function(sc, name, fnc, required_args, optional_args, rest_arg, doc); set_type(func, T_C_MACRO | T_DONT_EVAL_ARGS); /* this used to include T_PROCEDURE */ sym = make_symbol(sc, name); s7_define(sc, sc->NIL, sym, func); return(sym); } bool s7_is_macro(s7_scheme *sc, s7_pointer x) { return(is_any_macro(x)); } static s7_pointer g_is_macro(s7_scheme *sc, s7_pointer args) { #define H_is_macro "(macro? arg) returns #t if 'arg' is a macro or a bacro" #define Q_is_macro pl_bt check_boolean_method(sc, is_any_macro, sc->IS_MACRO, args); } static void define_function_star_1(s7_scheme *sc, const char *name, s7_function fnc, const char *arglist, const char *doc, bool safe) { s7_pointer func, sym, local_args, p; char *internal_arglist; int i, len, n_args, gc_loc; s7_pointer *names, *defaults; len = safe_strlen(arglist) + 8; tmpbuf_malloc(internal_arglist, len); snprintf(internal_arglist, len, "'(%s)", arglist); local_args = s7_eval_c_string(sc, internal_arglist); gc_loc = s7_gc_protect(sc, local_args); tmpbuf_free(internal_arglist, len); n_args = safe_list_length(sc, local_args); /* currently rest arg not supported, and we don't notice :key :allow-other-keys etc */ func = s7_make_function(sc, name, fnc, 0, n_args, false, doc); if (safe) set_type(func, T_C_FUNCTION_STAR | T_PROCEDURE | T_SAFE_PROCEDURE); else set_type(func, T_C_FUNCTION_STAR | T_PROCEDURE); c_function_call_args(func) = make_list(sc, n_args, sc->F); s7_remove_from_heap(sc, c_function_call_args(func)); sym = make_symbol(sc, name); s7_define(sc, sc->NIL, sym, func); names = (s7_pointer *)malloc(n_args * sizeof(s7_pointer)); c_function_arg_names(func) = names; defaults = (s7_pointer *)malloc(n_args * sizeof(s7_pointer)); c_function_arg_defaults(func) = defaults; set_simple_defaults(func); for (p = local_args, i = 0; i < n_args; p = cdr(p), i++) { s7_pointer arg; arg = car(p); if (is_pair(arg)) { names[i] = s7_make_keyword(sc, symbol_name(car(arg))); defaults[i] = cadr(arg); s7_remove_from_heap(sc, cadr(arg)); if ((is_symbol(defaults[i])) || (is_pair(defaults[i]))) { clear_simple_defaults(func); mark_function[T_C_FUNCTION_STAR] = mark_c_proc_star; } } else { names[i] = s7_make_keyword(sc, symbol_name(arg)); defaults[i] = sc->F; } } s7_gc_unprotect_at(sc, gc_loc); } void s7_define_function_star(s7_scheme *sc, const char *name, s7_function fnc, const char *arglist, const char *doc) { define_function_star_1(sc, name, fnc, arglist, doc, false); } void s7_define_safe_function_star(s7_scheme *sc, const char *name, s7_function fnc, const char *arglist, const char *doc) { define_function_star_1(sc, name, fnc, arglist, doc, true); } s7_pointer set_c_function_call_args(s7_scheme *sc) { int i, j, n_args; s7_pointer arg, par, call_args, func; s7_pointer *df; func = sc->code; n_args = c_function_all_args(func); call_args = c_function_call_args(func); df = c_function_arg_defaults(func); for (i = 0, par = call_args; is_pair(par); i++, par = cdr(par)) { clear_checked(par); car(par) = df[i]; } df = c_function_arg_names(func); for (i = 0, arg = sc->args, par = call_args; (i < n_args) && (is_pair(arg)); i++, arg = cdr(arg), par = cdr(par)) { if (!is_keyword(car(arg))) { if (is_checked(par)) return(s7_error(sc, sc->WRONG_TYPE_ARG, set_elist_3(sc, make_string_wrapper(sc, "parameter set twice, ~S in ~S"), car(par), sc->args))); set_checked(par); car(par) = car(arg); } else { s7_pointer p; for (j = 0, p = call_args; j < n_args; j++, p = cdr(p)) if (df[j] == car(arg)) break; if (j == n_args) return(s7_error(sc, sc->WRONG_TYPE_ARG, set_elist_2(sc, make_string_wrapper(sc, "~A: not a parameter name?"), car(arg)))); if (is_checked(p)) return(s7_error(sc, sc->WRONG_TYPE_ARG, set_elist_3(sc, make_string_wrapper(sc, "parameter set twice, ~S in ~S"), car(p), sc->args))); set_checked(p); arg = cdr(arg); car(p) = car(arg); } } if (!is_null(arg)) return(s7_error(sc, sc->WRONG_NUMBER_OF_ARGS, set_elist_3(sc, sc->TOO_MANY_ARGUMENTS, func, sc->args))); if (!has_simple_defaults(func)) for (i = 0, par = call_args; i < n_args; i++, par = cdr(par)) if (!is_checked(par)) { if (is_symbol(car(par))) car(par) = find_symbol_checked(sc, car(par)); else { if (is_pair(car(par))) car(par) = s7_eval_form(sc, car(par), sc->NIL); } } return(call_args); } /* -------------------------------- procedure-documentation -------------------------------- */ static s7_pointer get_doc(s7_scheme *sc, s7_pointer x) { check_closure_for(sc, x, sc->DOCUMENTATION); return(NULL); } const char *s7_procedure_documentation(s7_scheme *sc, s7_pointer x) { s7_pointer val; if (is_symbol(x)) { if ((symbol_has_help(x)) && (is_global(x))) return(symbol_help(x)); x = s7_symbol_value(sc, x); /* this is needed by Snd */ } if ((is_any_c_function(x)) || (is_c_macro(x))) return((char *)c_function_documentation(x)); val = get_doc(sc, x); if ((val) && (is_string(val))) return(string_value(val)); return(NULL); } static s7_pointer c_procedure_documentation(s7_scheme *sc, s7_pointer p) { if (is_symbol(p)) { if ((symbol_has_help(p)) && (is_global(p))) return(s7_make_string(sc, symbol_help(p))); p = s7_symbol_value(sc, p); } check_method(sc, p, sc->PROCEDURE_DOCUMENTATION, list_1(sc, p)); if ((!is_procedure(p)) && (!s7_is_macro(sc, p))) return(simple_wrong_type_argument_with_type(sc, sc->PROCEDURE_DOCUMENTATION, p, A_PROCEDURE)); return(s7_make_string(sc, s7_procedure_documentation(sc, p))); } static s7_pointer g_procedure_documentation(s7_scheme *sc, s7_pointer args) { #define H_procedure_documentation "(procedure-documentation func) returns func's documentation string" #define Q_procedure_documentation s7_make_signature(sc, 2, sc->IS_STRING, sc->IS_PROCEDURE) return(c_procedure_documentation(sc, car(args))); } PF_TO_PF(procedure_documentation, c_procedure_documentation) /* -------------------------------- help -------------------------------- */ const char *s7_help(s7_scheme *sc, s7_pointer obj) { if (is_syntax(obj)) return(string_value(syntax_documentation(obj))); if (is_symbol(obj)) { /* here look for name */ if (s7_symbol_documentation(sc, obj)) return(s7_symbol_documentation(sc, obj)); obj = s7_symbol_value(sc, obj); } if (is_procedure_or_macro(obj)) return(s7_procedure_documentation(sc, obj)); /* if is string, apropos? (can scan symbol table) */ return(NULL); } static s7_pointer g_help(s7_scheme *sc, s7_pointer args) { #define H_help "(help obj) returns obj's documentation" #define Q_help s7_make_signature(sc, 2, s7_make_signature(sc, 2, sc->IS_STRING, sc->IS_BOOLEAN), sc->T) const char *doc; check_method(sc, car(args), sc->HELP, args); doc = s7_help(sc, car(args)); if (!doc) return(sc->F); return(s7_make_string(sc, doc)); } static s7_pointer c_help(s7_scheme *sc, s7_pointer x) {return(g_help(sc, set_plist_1(sc, x)));} PF_TO_PF(help, c_help) /* -------------------------------- procedure-signature -------------------------------- */ static s7_pointer get_signature(s7_scheme *sc, s7_pointer x) { check_closure_for(sc, x, sc->SIGNATURE); return(sc->F); } static s7_pointer s7_procedure_signature(s7_scheme *sc, s7_pointer x) { if ((is_any_c_function(x)) || (is_c_macro(x))) return((s7_pointer)c_function_signature(x)); return(get_signature(sc, x)); } static s7_pointer c_procedure_signature(s7_scheme *sc, s7_pointer p) { if (is_symbol(p)) { p = s7_symbol_value(sc, p); if (p == sc->UNDEFINED) return(sc->F); } check_method(sc, p, sc->PROCEDURE_SIGNATURE, list_1(sc, p)); if (!is_procedure(p)) return(sc->F); return(s7_procedure_signature(sc, p)); } static s7_pointer g_procedure_signature(s7_scheme *sc, s7_pointer args) { #define H_procedure_signature "(procedure-signature func) returns func's signature" #define Q_procedure_signature s7_make_signature(sc, 2, s7_make_signature(sc, 2, sc->IS_PAIR, sc->IS_BOOLEAN), sc->T) return(c_procedure_signature(sc, car(args))); } PF_TO_PF(procedure_signature, c_procedure_signature) /* -------------------------------- new types (c_objects) -------------------------------- */ static void fallback_free(void *value) {} static void fallback_mark(void *value) {} static char *fallback_print(s7_scheme *sc, void *val) { return(copy_string("#")); } static char *fallback_print_readably(s7_scheme *sc, void *val) { return(copy_string("#")); } static bool fallback_equal(void *val1, void *val2) { return(val1 == val2); } static s7_pointer fallback_ref(s7_scheme *sc, s7_pointer obj, s7_pointer args) { return(apply_error(sc, obj, args)); } static s7_pointer fallback_set(s7_scheme *sc, s7_pointer obj, s7_pointer args) { eval_error(sc, "attempt to set ~S?", obj); } static s7_pointer fallback_length(s7_scheme *sc, s7_pointer obj) { return(sc->F); } bool s7_is_object(s7_pointer p) { return(is_c_object(p)); } static s7_pointer g_is_c_object(s7_scheme *sc, s7_pointer args) { #define H_is_c_object "(c-object? obj) returns the object's type tag if obj is a C object, otherwise #f" #define Q_is_c_object pl_bt s7_pointer p; p = car(args); if (is_c_object(p)) return(make_integer(sc, c_object_type(p))); /* this is the object_types table index = tag */ check_method(sc, p, sc->IS_C_OBJECT, args); return(sc->F); /* <1> (*s7* 'c-types) ("") <2> (c-object? (random-state 123)) 0 */ } static s7_pointer g_internal_object_set(s7_scheme *sc, s7_pointer args) { return((*(c_object_set(car(args))))(sc, car(args), cdr(args))); } int s7_new_type(const char *name, char *(*print)(s7_scheme *sc, void *value), void (*gc_free)(void *value), bool (*equal)(void *val1, void *val2), void (*gc_mark)(void *val), s7_pointer (*ref)(s7_scheme *sc, s7_pointer obj, s7_pointer args), s7_pointer (*set)(s7_scheme *sc, s7_pointer obj, s7_pointer args)) { int tag; tag = num_object_types++; if (tag >= object_types_size) { if (object_types_size == 0) { object_types_size = 8; object_types = (c_object_t **)calloc(object_types_size, sizeof(c_object_t *)); } else { object_types_size = tag + 8; object_types = (c_object_t **)realloc((void *)object_types, object_types_size * sizeof(c_object_t *)); } } object_types[tag] = (c_object_t *)calloc(1, sizeof(c_object_t)); object_types[tag]->type = tag; object_types[tag]->name = copy_string(name); object_types[tag]->scheme_name = s7_make_permanent_string(name); object_types[tag]->free = (gc_free) ? gc_free : fallback_free; object_types[tag]->print = (print) ? print : fallback_print; object_types[tag]->equal = (equal) ? equal : fallback_equal; object_types[tag]->gc_mark = (gc_mark) ? gc_mark : fallback_mark; object_types[tag]->ref = (ref) ? ref : fallback_ref; object_types[tag]->set = (set) ? set : fallback_set; if (object_types[tag]->ref != fallback_ref) object_types[tag]->outer_type = (T_C_OBJECT | T_PROCEDURE | T_SAFE_PROCEDURE); else object_types[tag]->outer_type = T_C_OBJECT; object_types[tag]->length = fallback_length; object_types[tag]->copy = NULL; object_types[tag]->reverse = NULL; object_types[tag]->fill = NULL; object_types[tag]->print_readably = fallback_print_readably; object_types[tag]->ip = NULL; object_types[tag]->rp = NULL; object_types[tag]->set_ip = NULL; object_types[tag]->set_rp = NULL; return(tag); } int s7_new_type_x(s7_scheme *sc, const char *name, char *(*print)(s7_scheme *sc, void *value), void (*free)(void *value), bool (*equal)(void *val1, void *val2), void (*gc_mark)(void *val), s7_pointer (*apply)(s7_scheme *sc, s7_pointer obj, s7_pointer args), s7_pointer (*set)(s7_scheme *sc, s7_pointer obj, s7_pointer args), s7_pointer (*length)(s7_scheme *sc, s7_pointer obj), s7_pointer (*copy)(s7_scheme *sc, s7_pointer args), s7_pointer (*reverse)(s7_scheme *sc, s7_pointer args), s7_pointer (*fill)(s7_scheme *sc, s7_pointer args)) { int tag; tag = s7_new_type(name, print, free, equal, gc_mark, apply, set); if (length) object_types[tag]->length = length; else object_types[tag]->length = fallback_length; object_types[tag]->copy = copy; object_types[tag]->reverse = reverse; object_types[tag]->fill = fill; return(tag); } static void free_object(s7_pointer a) { (*(c_object_free(a)))(c_object_value(a)); } static bool objects_are_equal(s7_scheme *sc, s7_pointer a, s7_pointer b) { return((c_object_type(a) == c_object_type(b)) && ((*(c_object_eql(a)))(c_object_value(a), c_object_value(b)))); } void *s7_object_value(s7_pointer obj) { return(c_object_value(obj)); } void *s7_object_value_checked(s7_pointer obj, int type) { if ((is_c_object(obj)) && (c_object_type(obj) == type)) return(c_object_value(obj)); return(NULL); } void s7_set_object_print_readably(int type, char *(*printer)(s7_scheme *sc, void *val)) { object_types[type]->print_readably = printer; } int s7_object_type(s7_pointer obj) { if (is_c_object(obj)) return(c_object_type(obj)); return(-1); } s7_pointer s7_make_object(s7_scheme *sc, int type, void *value) { s7_pointer x; new_cell(sc, x, object_types[type]->outer_type); /* c_object_info(x) = &(object_types[type]); */ /* that won't work because object_types can move when it is realloc'd and the old stuff is freed by realloc * and since we're checking (for example) ref_2 existence as not null, we can't use a table of c_object_t's! */ c_object_type(x) = type; c_object_value(x) = value; c_object_set_let(x, sc->NIL); add_c_object(sc, x); return(x); } s7_pointer s7_object_let(s7_pointer obj) { return(c_object_let(obj)); } s7_pointer s7_object_set_let(s7_pointer obj, s7_pointer e) { c_object_set_let(obj, e); return(e); } void s7_object_type_set_xf(int tag, s7_ip_t ip, s7_ip_t set_ip, s7_rp_t rp, s7_rp_t set_rp) { object_types[tag]->ip = ip; object_types[tag]->rp = rp; object_types[tag]->set_ip = set_ip; object_types[tag]->set_rp = set_rp; } void s7_object_type_set_direct(int tag, s7_pointer (*dref)(s7_scheme *sc, s7_pointer obj, s7_int index), s7_pointer (*dset)(s7_scheme *sc, s7_pointer obj, s7_int index, s7_pointer val)) { object_types[tag]->direct_ref = dref; object_types[tag]->direct_set = dset; } static s7_pointer object_length(s7_scheme *sc, s7_pointer obj) { if (c_object_length(obj)) return((*(c_object_length(obj)))(sc, obj)); eval_error(sc, "attempt to get length of ~S?", obj); } static s7_int object_length_to_int(s7_scheme *sc, s7_pointer obj) { if (c_object_length(obj)) { s7_pointer res; res = (*(c_object_length(obj)))(sc, obj); if (s7_is_integer(res)) return(s7_integer(res)); } return(-1); } static s7_pointer object_copy(s7_scheme *sc, s7_pointer args) { s7_pointer obj; obj = car(args); check_method(sc, obj, sc->COPY, args); if (c_object_copy(obj)) return((*(c_object_copy(obj)))(sc, args)); eval_error(sc, "attempt to copy ~S?", obj); } /* -------- dilambda -------- */ s7_pointer s7_dilambda(s7_scheme *sc, const char *name, s7_pointer (*getter)(s7_scheme *sc, s7_pointer args), int get_req_args, int get_opt_args, s7_pointer (*setter)(s7_scheme *sc, s7_pointer args), int set_req_args, int set_opt_args, const char *documentation) { s7_pointer get_func, set_func; char *internal_set_name; int len; len = 16 + safe_strlen(name); internal_set_name = (char *)malloc(len * sizeof(char)); snprintf(internal_set_name, len, "[set-%s]", name); get_func = s7_make_safe_function(sc, name, getter, get_req_args, get_opt_args, false, documentation); s7_define(sc, sc->NIL, make_symbol(sc, name), get_func); set_func = s7_make_function(sc, internal_set_name, setter, set_req_args, set_opt_args, false, documentation); c_function_setter(get_func) = set_func; return(get_func); } s7_pointer s7_typed_dilambda(s7_scheme *sc, const char *name, s7_pointer (*getter)(s7_scheme *sc, s7_pointer args), int get_req_args, int get_opt_args, s7_pointer (*setter)(s7_scheme *sc, s7_pointer args), int set_req_args, int set_opt_args, const char *documentation, s7_pointer get_sig, s7_pointer set_sig) { s7_pointer get_func, set_func; get_func = s7_dilambda(sc, name, getter, get_req_args, get_opt_args, setter, set_req_args, set_opt_args, documentation); set_func = c_function_setter(get_func); if (get_sig) c_function_signature(get_func) = get_sig; if (set_sig) c_function_signature(set_func) = set_sig; return(get_func); } bool s7_is_dilambda(s7_pointer obj) { return(((is_c_function(obj)) && (is_c_function(c_function_setter(obj)))) || ((is_any_closure(obj)) && (is_procedure(closure_setter(obj))))); } static s7_pointer g_is_dilambda(s7_scheme *sc, s7_pointer args) { #define H_is_dilambda "(dilambda? obj) returns #t if obj is a procedure with setter." #define Q_is_dilambda pl_bt check_boolean_method(sc, s7_is_dilambda, sc->IS_DILAMBDA, args); } s7_pointer s7_procedure_setter(s7_scheme *sc, s7_pointer obj) { if (is_c_function(obj)) return(c_function_setter(obj)); return(closure_setter(obj)); } static s7_pointer g_procedure_setter(s7_scheme *sc, s7_pointer args) { #define H_procedure_setter "(procedure-setter obj) returns the setter associated with obj, or #f" #define Q_procedure_setter s7_make_signature(sc, 2, sc->T, sc->IS_PROCEDURE) s7_pointer p; p = car(args); switch (type(p)) { case T_MACRO: case T_MACRO_STAR: case T_BACRO: case T_BACRO_STAR: case T_CLOSURE: case T_CLOSURE_STAR: return(closure_setter(p)); case T_C_FUNCTION: case T_C_FUNCTION_STAR: case T_C_ANY_ARGS_FUNCTION: case T_C_OPT_ARGS_FUNCTION: case T_C_RST_ARGS_FUNCTION: return(c_function_setter(p)); case T_C_MACRO: return(c_macro_setter(p)); case T_GOTO: case T_CONTINUATION: return(sc->F); case T_LET: case T_C_OBJECT: check_method(sc, p, s7_make_symbol(sc, "procedure-setter"), args); break; case T_ITERATOR: if (is_any_closure(iterator_sequence(p))) return(closure_setter(iterator_sequence(p))); return(sc->F); } return(s7_wrong_type_arg_error(sc, "procedure-setter", 0, p, "a procedure or a reasonable facsimile thereof")); } static s7_pointer g_procedure_set_setter(s7_scheme *sc, s7_pointer args) { s7_pointer p, setter; p = car(args); if (!is_procedure_or_macro(p)) return(s7_wrong_type_arg_error(sc, "set! procedure-setter procedure", 1, p, "a procedure")); setter = cadr(args); if ((setter != sc->F) && (!is_procedure_or_macro(setter))) return(s7_wrong_type_arg_error(sc, "set! procedure-setter setter", 2, setter, "a procedure or #f")); /* should we check that p != setter? * :(set! (procedure-setter <) <) * < * :(set! (< 3 2) 3) * #f * :(set! (< 1) 2) * #t * can this make sense? */ switch (type(p)) { case T_MACRO: case T_MACRO_STAR: case T_BACRO: case T_BACRO_STAR: case T_CLOSURE: case T_CLOSURE_STAR: closure_setter(p) = setter; break; case T_C_FUNCTION: case T_C_ANY_ARGS_FUNCTION: case T_C_OPT_ARGS_FUNCTION: case T_C_RST_ARGS_FUNCTION: c_function_setter(p) = setter; if (is_any_closure(setter)) add_setter(sc, p, setter); break; case T_C_FUNCTION_STAR: c_function_setter(p) = setter; if (is_any_closure(setter)) add_setter(sc, p, setter); break; case T_C_MACRO: if (is_any_closure(setter)) add_setter(sc, p, setter); c_macro_setter(p) = setter; break; case T_GOTO: return(s7_wrong_type_arg_error(sc, "set! procedure-setter", 1, p, "a normal procedure (not a call-with-exit exit procedure)")); case T_CONTINUATION: return(s7_wrong_type_arg_error(sc, "set! procedure-setter", 1, p, "a normal procedure")); } return(setter); } void s7_define_function_with_setter(s7_scheme *sc, const char *name, s7_function get_fnc, s7_function set_fnc, int req_args, int opt_args, const char *doc) { s7_dilambda(sc, name, get_fnc, req_args, opt_args, set_fnc, req_args + 1, opt_args, doc); } /* -------------------------------- arity -------------------------------- */ static s7_pointer closure_arity_to_cons(s7_scheme *sc, s7_pointer x, s7_pointer x_args) { /* x_args is unprocessed -- it is exactly the list as used in the closure[*] definition */ int len; if (is_symbol(x_args)) /* any number of args is ok */ return(s7_cons(sc, small_int(0), max_arity)); if (closure_arity_unknown(x)) closure_arity(x) = s7_list_length(sc, x_args); len = closure_arity(x); if (len < 0) /* dotted list => rest arg, (length '(a b . c)) is -2 */ return(s7_cons(sc, s7_make_integer(sc, -len), max_arity)); return(s7_cons(sc, s7_make_integer(sc, len), s7_make_integer(sc, len))); } static void closure_star_arity_1(s7_scheme *sc, s7_pointer x, s7_pointer args) { if (closure_arity_unknown(x)) { if (is_null(args)) closure_arity(x) = 0; else { if (allows_other_keys(args)) closure_arity(x) = -1; else { s7_pointer p; int i; for (i = 0, p = args; is_pair(p); p = cdr(p)) { s7_pointer arg; arg = car(p); if (arg == sc->KEY_REST) break; i++; } if (is_null(p)) closure_arity(x) = i; else closure_arity(x) = -1; /* see below */ } } } } static s7_pointer closure_star_arity_to_cons(s7_scheme *sc, s7_pointer x, s7_pointer x_args) { if (is_symbol(x_args)) return(s7_cons(sc, small_int(0), max_arity)); closure_star_arity_1(sc, x, x_args); if (closure_arity(x) == -1) return(s7_cons(sc, small_int(0), max_arity)); return(s7_cons(sc, small_int(0), s7_make_integer(sc, closure_arity(x)))); } static int closure_arity_to_int(s7_scheme *sc, s7_pointer x) { /* not lambda* here */ if (closure_arity_unknown(x)) { int i; s7_pointer b; for (i = 0, b = closure_args(x); is_pair(b); i++, b = cdr(b)) {}; if (is_null(b)) closure_arity(x) = i; else { if (i == 0) return(-1); closure_arity(x) = -i; } } return(closure_arity(x)); } static int closure_star_arity_to_int(s7_scheme *sc, s7_pointer x) { /* not lambda here */ closure_star_arity_1(sc, x, closure_args(x)); return(closure_arity(x)); } s7_pointer s7_arity(s7_scheme *sc, s7_pointer x) { switch (type(x)) { case T_C_OPT_ARGS_FUNCTION: case T_C_RST_ARGS_FUNCTION: case T_C_FUNCTION: return(s7_cons(sc, s7_make_integer(sc, c_function_required_args(x)), s7_make_integer(sc, c_function_all_args(x)))); case T_C_ANY_ARGS_FUNCTION: case T_C_FUNCTION_STAR: return(s7_cons(sc, small_int(0), s7_make_integer(sc, c_function_all_args(x)))); /* should this be *2? */ case T_MACRO: case T_BACRO: case T_CLOSURE: return(closure_arity_to_cons(sc, x, closure_args(x))); case T_MACRO_STAR: case T_BACRO_STAR: case T_CLOSURE_STAR: return(closure_star_arity_to_cons(sc, x, closure_args(x))); case T_C_MACRO: return(s7_cons(sc, s7_make_integer(sc, c_macro_required_args(x)), s7_make_integer(sc, c_macro_all_args(x)))); case T_GOTO: case T_CONTINUATION: return(s7_cons(sc, small_int(0), max_arity)); case T_STRING: if (string_length(x) == 0) return(sc->F); case T_LET: /* check_method(sc, x, sc->ARITY, args); */ return(s7_cons(sc, small_int(1), small_int(1))); case T_C_OBJECT: /* check_method(sc, x, sc->ARITY, args); */ if (is_procedure(x)) return(s7_cons(sc, small_int(0), max_arity)); return(sc->F); case T_INT_VECTOR: case T_FLOAT_VECTOR: case T_VECTOR: if (vector_length(x) == 0) return(sc->F); case T_PAIR: case T_HASH_TABLE: return(s7_cons(sc, small_int(1), max_arity)); case T_ITERATOR: return(s7_cons(sc, small_int(0), small_int(0))); case T_SYNTAX: return(s7_cons(sc, small_int(syntax_min_args(x)), (syntax_max_args(x) == -1) ? max_arity : small_int(syntax_max_args(x)))); } return(sc->F); } static s7_pointer g_arity(s7_scheme *sc, s7_pointer args) { #define H_arity "(arity obj) the min and max acceptable args for obj if it is applicable, otherwise #f." #define Q_arity pcl_t /* check_method(sc, p, sc->ARITY, args); */ return(s7_arity(sc, car(args))); } PF_TO_PF(arity, s7_arity) static bool closure_is_aritable(s7_scheme *sc, s7_pointer x, s7_pointer x_args, int args) { /* x_args is unprocessed -- it is exactly the list as used in the closure definition */ int len; if (args == 0) return(!is_pair(x_args)); if (is_symbol(x_args)) /* any number of args is ok */ return(true); len = closure_arity(x); if (len == CLOSURE_ARITY_NOT_SET) { len = s7_list_length(sc, x_args); closure_arity(x) = len; } if (len < 0) /* dotted list => rest arg, (length '(a b . c)) is -2 */ return((-len) <= args); /* so we have enough to take care of the required args */ return(args == len); /* in a normal lambda list, there are no other possibilities */ } static bool closure_star_is_aritable(s7_scheme *sc, s7_pointer x, s7_pointer x_args, int args) { if (is_symbol(x_args)) return(true); closure_star_arity_1(sc, x, x_args); return((closure_arity(x) == -1) || (args <= closure_arity(x))); } bool s7_is_aritable(s7_scheme *sc, s7_pointer x, int args) { switch (type(x)) { case T_C_OPT_ARGS_FUNCTION: case T_C_RST_ARGS_FUNCTION: case T_C_FUNCTION: return(((int)c_function_required_args(x) <= args) && ((int)c_function_all_args(x) >= args)); case T_C_ANY_ARGS_FUNCTION: case T_C_FUNCTION_STAR: return((int)c_function_all_args(x) >= args); case T_MACRO: case T_BACRO: case T_CLOSURE: return(closure_is_aritable(sc, x, closure_args(x), args)); case T_MACRO_STAR: case T_BACRO_STAR: case T_CLOSURE_STAR: return(closure_star_is_aritable(sc, x, closure_args(x), args)); case T_C_MACRO: return(((int)c_macro_required_args(x) <= args) && ((int)c_macro_all_args(x) >= args)); case T_GOTO: case T_CONTINUATION: return(true); case T_STRING: return((args == 1) && (string_length(x) > 0)); /* ("" 0) -> error */ case T_C_OBJECT: /* check_method(sc, x, sc->IS_ARITABLE, list_2(sc, x, s7_make_integer(sc, args))); -- see below */ return(is_procedure(x)); /* i.e. is_applicable */ case T_INT_VECTOR: case T_FLOAT_VECTOR: case T_VECTOR: return((args > 0) && (vector_length(x) > 0) && /* (#() 0) -> error */ ((unsigned int)args <= vector_rank(x))); case T_LET: /* check_method(sc, x, sc->IS_ARITABLE, list_2(sc, x, s7_make_integer(sc, args))); */ /* this slows us down a lot */ case T_HASH_TABLE: case T_PAIR: return(args == 1); case T_ITERATOR: return(args == 0); case T_SYNTAX: return((args >= syntax_min_args(x)) && ((args <= syntax_max_args(x)) || (syntax_max_args(x) == -1))); } return(false); } static s7_pointer g_is_aritable(s7_scheme *sc, s7_pointer args) { #define H_is_aritable "(aritable? obj num-args) returns #t if 'obj can be applied to 'num-args arguments." #define Q_is_aritable s7_make_signature(sc, 3, sc->IS_BOOLEAN, sc->T, sc->IS_INTEGER) s7_pointer n; s7_int num; n = cadr(args); if (!s7_is_integer(n)) /* remember gmp case! */ method_or_bust(sc, n, sc->IS_ARITABLE, args, T_INTEGER, 2); num = s7_integer(n); if (num < 0) return(out_of_range(sc, sc->IS_ARITABLE, small_int(2), n, ITS_NEGATIVE)); if (num > MAX_ARITY) num = MAX_ARITY; return(make_boolean(sc, s7_is_aritable(sc, car(args), (int)num))); } static s7_pointer c_is_aritable(s7_scheme *sc, s7_pointer x, s7_int y) {return(make_boolean(sc, s7_is_aritable(sc, x, y)));} PIF_TO_PF(is_aritable, c_is_aritable) static s7_pointer is_aritable_ic; static s7_pointer g_is_aritable_ic(s7_scheme *sc, s7_pointer args) { return(make_boolean(sc, s7_is_aritable(sc, car(args), (int)integer(cadr(args))))); } static s7_pointer is_aritable_chooser(s7_scheme *sc, s7_pointer f, int args, s7_pointer expr) { if (args == 2) { s7_pointer arg2; arg2 = caddr(expr); if ((s7_is_integer(arg2)) && (s7_integer(arg2) < MAX_ARITY) && (s7_integer(arg2) >= 0)) return(is_aritable_ic); } return(f); } /* -------- sequence? -------- */ static s7_pointer g_is_sequence(s7_scheme *sc, s7_pointer args) { #define H_is_sequence "(sequence? obj) returns #t if obj is a sequence (vector, string, pair, etc)" #define Q_is_sequence pl_bt check_boolean_method(sc, is_simple_sequence, sc->IS_SEQUENCE, args); } /* -------------------------------- symbol-access ------------------------------------------------ */ static unsigned int protect_accessor(s7_scheme *sc, s7_pointer acc) { unsigned int loc; if (sc->protected_accessors_size == sc->protected_accessors_loc) { int i, new_size, size; size = sc->protected_accessors_size; new_size = 2 * size; vector_elements(sc->protected_accessors) = (s7_pointer *)realloc(vector_elements(sc->protected_accessors), new_size * sizeof(s7_pointer)); vector_length(sc->protected_accessors) = new_size; for (i = size; i < new_size; i++) vector_element(sc->protected_accessors, i) = sc->GC_NIL; sc->protected_accessors_size = new_size; } loc = sc->protected_accessors_loc++; vector_element(sc->protected_accessors, loc) = acc; return(loc); } s7_pointer s7_symbol_access(s7_scheme *sc, s7_pointer sym) { /* these refer to the rootlet */ if ((is_slot(global_slot(sym))) && (slot_has_accessor(global_slot(sym)))) return(s7_gc_protected_at(sc, symbol_global_accessor_index(sym))); return(sc->F); } s7_pointer s7_symbol_set_access(s7_scheme *sc, s7_pointer symbol, s7_pointer func) { if (slot_has_accessor(global_slot(symbol))) { unsigned int index; index = symbol_global_accessor_index(symbol); if (is_immutable(vector_element(sc->protected_accessors, index))) return(func); vector_element(sc->protected_accessors, index) = func; } else { if (func != sc->F) { slot_set_has_accessor(global_slot(symbol)); symbol_set_has_accessor(symbol); symbol_global_accessor_index(symbol) = protect_accessor(sc, func); } } slot_accessor(global_slot(symbol)) = func; return(func); } /* (let () (define xxx 23) (define (hix) (set! xxx 24)) (hix) (set! (symbol-access 'xxx) (lambda (sym val) (format *stderr* "val: ~A~%" val) val)) (hix)) * so set symbol-access before use! */ static s7_pointer g_symbol_access(s7_scheme *sc, s7_pointer args) { #define H_symbol_access "(symbol-access sym (env (curlet))) is the function called when the symbol is set!." #define Q_symbol_access s7_make_signature(sc, 3, sc->T, sc->IS_SYMBOL, sc->IS_LET) s7_pointer sym, p, e; sym = car(args); if (!is_symbol(sym)) method_or_bust(sc, sym, sc->SYMBOL_ACCESS, args, T_SYMBOL, 0); if (is_keyword(sym)) return(sc->F); if (is_pair(cdr(args))) { e = cadr(args); if (!is_let(e)) return(wrong_type_argument(sc, sc->SYMBOL_ACCESS, 2, e, T_LET)); } else e = sc->envir; if ((e == sc->rootlet) || (e == sc->NIL)) return(s7_symbol_access(sc, sym)); if (is_null(cdr(args))) p = find_symbol(sc, sym); else p = find_local_symbol(sc, sym, e); if ((is_slot(p)) && (slot_has_accessor(p))) return(slot_accessor(p)); return(sc->F); } static s7_pointer g_symbol_set_access(s7_scheme *sc, s7_pointer args) { s7_pointer sym, func, e, p; /* perhaps: check func */ sym = car(args); if (!is_symbol(sym)) /* no check method because no method name? */ return(s7_wrong_type_arg_error(sc, "set! symbol-access", 1, sym, "a symbol")); if (is_keyword(sym)) return(s7_wrong_type_arg_error(sc, "set! symbol-access", 1, sym, "a normal symbol (a keyword can't be set)")); /* (set! (symbol-access sym) f) or (set! (symbol-access sym env) f) */ if (is_pair(cddr(args))) { e = cadr(args); if (!is_let(e)) return(s7_wrong_type_arg_error(sc, "set! symbol-access", 2, e, "a let")); func = caddr(args); } else { e = sc->envir; func = cadr(args); } if ((!is_procedure_or_macro(func)) && (func != sc->F)) return(s7_wrong_type_arg_error(sc, "set! symbol-access", 3, func, "a function or #f")); if ((e == sc->rootlet) || (e == sc->NIL)) { if (!is_slot(global_slot(sym))) return(sc->F); return(s7_symbol_set_access(sc, sym, func)); } if (is_null(cddr(args))) p = find_symbol(sc, sym); else p = find_local_symbol(sc, sym, e); if (is_slot(p)) { slot_accessor(p) = func; if (func != sc->F) { slot_set_has_accessor(p); symbol_set_has_accessor(sym); } return(func); } return(sc->F); } static s7_pointer bind_accessed_symbol(s7_scheme *sc, opcode_t op, s7_pointer symbol, s7_pointer new_value) { /* this refers to (define (sym ...)) and friends -- define cases * see call_accessor for the set! cases */ s7_pointer func; func = g_symbol_access(sc, set_plist_2(sc, symbol, sc->envir)); if (is_procedure_or_macro(func)) { if (is_c_function(func)) { s7_pointer old_value; old_value = new_value; car(sc->T2_1) = symbol; car(sc->T2_2) = new_value; new_value = c_function_call(func)(sc, sc->T2_1); if (new_value == sc->ERROR) return(s7_error(sc, sc->ERROR, set_elist_3(sc, make_string_wrapper(sc, "can't bind ~S to ~S"), symbol, old_value))); } else { sc->args = list_2(sc, symbol, new_value); push_stack(sc, op, sc->args, sc->code); sc->code = func; return(sc->NO_VALUE); /* this means the accessor in set! needs to goto APPLY to get the new value */ } } return(new_value); } /* -------------------------------- hooks -------------------------------- */ s7_pointer s7_hook_functions(s7_scheme *sc, s7_pointer hook) { return(s7_symbol_local_value(sc, sc->BODY, closure_let(hook))); } s7_pointer s7_hook_set_functions(s7_scheme *sc, s7_pointer hook, s7_pointer functions) { if (s7_is_list(sc, functions)) s7_let_set(sc, closure_let(hook), sc->BODY, functions); return(functions); } /* -------------------------------- eq etc -------------------------------- */ bool s7_is_eq(s7_pointer obj1, s7_pointer obj2) { return(obj1 == obj2); /* so floats and NaNs might be eq? but not eqv? */ } static s7_pointer g_is_eq(s7_scheme *sc, s7_pointer args) { #define H_is_eq "(eq? obj1 obj2) returns #t if obj1 is eq to (the same object as) obj2" #define Q_is_eq pcl_bt return(make_boolean(sc, ((car(args) == cadr(args)) || ((is_unspecified(car(args))) && (is_unspecified(cadr(args))))))); /* (eq? (apply apply apply values '(())) #) should return #t */ } bool s7_is_eqv(s7_pointer a, s7_pointer b) { if ((a == b) && (!is_number(a))) return(true); #if WITH_GMP if ((is_big_number(a)) || (is_big_number(b))) return(big_numbers_are_eqv(a, b)); #endif if (type(a) != type(b)) return(false); if (is_string(a)) return(string_value(a) == string_value(b)); if (s7_is_number(a)) return(numbers_are_eqv(a, b)); if (is_unspecified(a)) /* types are the same so we know b is also unspecified */ return(true); return(false); } static s7_pointer g_is_eqv(s7_scheme *sc, s7_pointer args) { #define H_is_eqv "(eqv? obj1 obj2) returns #t if obj1 is equivalent to obj2" #define Q_is_eqv pcl_bt return(make_boolean(sc, s7_is_eqv(car(args), cadr(args)))); } static bool floats_are_morally_equal(s7_scheme *sc, s7_double x, s7_double y) { if (x == y) return(true); if ((is_NaN(x)) || (is_NaN(y))) return((is_NaN(x)) && (is_NaN(y))); return(fabs(x - y) <= sc->morally_equal_float_epsilon); } static bool eq_equal(s7_scheme *sc, s7_pointer x, s7_pointer y, shared_info *ci, bool morally) { return(x == y); } static bool symbol_equal(s7_scheme *sc, s7_pointer x, s7_pointer y, shared_info *ci, bool morally) { if (x == y) return(true); if (!is_symbol(y)) return(false); /* (morally-equal? ''(1) '(1)) */ if (!morally) return(false); return((is_slot(global_slot(x))) && /* the optimizer can replace the original symbol with its own */ (is_syntax(slot_value(global_slot(x)))) && (is_slot(global_slot(y))) && (is_syntax(slot_value(global_slot(y)))) && (syntax_symbol(slot_value(global_slot(x))) == syntax_symbol(slot_value(global_slot(y))))); } static bool unspecified_equal(s7_scheme *sc, s7_pointer x, s7_pointer y, shared_info *ci, bool morally) { return(is_unspecified(y)); } static bool c_pointer_equal(s7_scheme *sc, s7_pointer x, s7_pointer y, shared_info *ci, bool morally) { return((s7_is_c_pointer(y)) && (raw_pointer(x) == raw_pointer(y))); } static bool string_equal(s7_scheme *sc, s7_pointer x, s7_pointer y, shared_info *ci, bool morally) { return((is_string(y)) && (scheme_strings_are_equal(x, y))); } static bool syntax_equal(s7_scheme *sc, s7_pointer x, s7_pointer y, shared_info *ci, bool morally) { return((is_syntax(y)) && (syntax_symbol(x) == syntax_symbol(y))); } static bool c_object_equal(s7_scheme *sc, s7_pointer x, s7_pointer y, shared_info *ci, bool morally) { return((is_c_object(y)) && (objects_are_equal(sc, x, y))); } static bool port_equal(s7_scheme *sc, s7_pointer x, s7_pointer y, shared_info *ci, bool morally) { if (x == y) return(true); if ((!morally) || (type(x) != type(y)) || (port_type(x) != port_type(y))) return(false); if ((port_is_closed(x)) && (port_is_closed(y))) return(true); return((is_string_port(x)) && (port_position(x) == port_position(y)) && (port_data_size(x) == port_data_size(y)) && (local_strncmp((const char *)port_data(x), (const char *)port_data(y), (is_input_port(x)) ? port_data_size(x) : port_position(x)))); } static int equal_ref(s7_scheme *sc, s7_pointer x, s7_pointer y, shared_info *ci) { /* here we know x and y are pointers to the same type of structure */ int ref_x, ref_y; ref_x = peek_shared_ref(ci, x); ref_y = peek_shared_ref(ci, y); if ((ref_x != 0) && (ref_y != 0)) return((ref_x == ref_y) ? 1 : 0); /* try to harmonize the new guy -- there can be more than one structure equal to the current one */ if (ref_x != 0) add_shared_ref(ci, y, ref_x); else { if (ref_y != 0) add_shared_ref(ci, x, ref_y); else add_equal_ref(ci, x, y); } return(-1); } static bool s7_is_equal_1(s7_scheme *sc, s7_pointer x, s7_pointer y, shared_info *ci, bool morally); static bool hash_table_equal(s7_scheme *sc, s7_pointer x, s7_pointer y, shared_info *ci, bool morally) { hash_entry_t **lists; int i, len; shared_info *nci = ci; if (x == y) return(true); if (!is_hash_table(y)) { if ((morally) && (has_methods(y))) { s7_pointer equal_func; equal_func = find_method(sc, find_let(sc, y), sc->IS_MORALLY_EQUAL); if (equal_func != sc->UNDEFINED) return(s7_boolean(sc, s7_apply_function(sc, equal_func, list_2(sc, y, x)))); } return(false); } if (ci) { i = equal_ref(sc, x, y, ci); if (i == 0) return(false); if (i == 1) return(true); } if (hash_table_entries(x) != hash_table_entries(y)) return(false); if (hash_table_entries(x) == 0) return(true); if ((!morally) && ((hash_table_checker_locked(x)) || (hash_table_checker_locked(y)))) { if (hash_table_checker(x) != hash_table_checker(y)) return(false); if (hash_table_mapper(x) != hash_table_mapper(y)) return(false); } len = hash_table_mask(x) + 1; lists = hash_table_elements(x); if (!nci) nci = new_shared_info(sc); for (i = 0; i < len; i++) { hash_entry_t *p; for (p = lists[i]; p; p = p->next) { hash_entry_t *y_val; y_val = (*hash_table_checker(y))(sc, y, p->key); if ((!y_val) || (!s7_is_equal_1(sc, p->value, y_val->value, nci, morally))) return(false); } } /* if we get here, every key/value in x has a corresponding key/value in y, and the number of entries match, * so surely the tables are equal?? */ return(true); } static bool slots_match(s7_scheme *sc, s7_pointer px, s7_pointer y, bool morally, shared_info *nci) { s7_pointer ey, py; for (ey = y; (is_let(ey)) && (ey != sc->rootlet); ey = outlet(ey)) for (py = let_slots(ey); is_slot(py); py = next_slot(py)) if (slot_symbol(px) == slot_symbol(py)) /* we know something will match */ return(s7_is_equal_1(sc, slot_value(px), slot_value(py), nci, morally)); return(false); } static bool let_equal(s7_scheme *sc, s7_pointer x, s7_pointer y, shared_info *ci, bool morally) { /* x == y if all unshadowed vars match, leaving aside the rootlet, so that for any local variable, * we get the same value in either x or y. */ s7_pointer ex, ey, px, py; shared_info *nci = ci; int x_len, y_len; if (x == y) return(true); if (morally) { s7_pointer equal_func; if (has_methods(x)) { equal_func = find_method(sc, find_let(sc, x), sc->IS_MORALLY_EQUAL); if (equal_func != sc->UNDEFINED) return(s7_boolean(sc, s7_apply_function(sc, equal_func, list_2(sc, x, y)))); } if (has_methods(y)) { equal_func = find_method(sc, find_let(sc, y), sc->IS_MORALLY_EQUAL); if (equal_func != sc->UNDEFINED) return(s7_boolean(sc, s7_apply_function(sc, equal_func, list_2(sc, y, x)))); } } if (!is_let(y)) return(false); if ((x == sc->rootlet) || (y == sc->rootlet)) return(false); if (ci) { int i; i = equal_ref(sc, x, y, ci); if (i == 0) return(false); if (i == 1) return(true); } clear_syms_in_list(sc); for (x_len = 0, ex = x; (is_let(ex)) && (ex != sc->rootlet); ex = outlet(ex)) for (px = let_slots(ex); is_slot(px); px = next_slot(px)) if (symbol_tag(slot_symbol(px)) != sc->syms_tag) { add_sym_to_list(sc, slot_symbol(px)); x_len++; } for (ey = y; (is_let(ey)) && (ey != sc->rootlet); ey = outlet(ey)) for (py = let_slots(ey); is_slot(py); py = next_slot(py)) if (symbol_tag(slot_symbol(py)) != sc->syms_tag) /* symbol in y, not in x */ return(false); for (y_len = 0, ey = y; (is_let(ey)) && (ey != sc->rootlet); ey = outlet(ey)) for (py = let_slots(ey); is_slot(py); py = next_slot(py)) if (symbol_tag(slot_symbol(py)) != 0) { y_len ++; symbol_tag(slot_symbol(py)) = 0; } if (x_len != y_len) /* symbol in x, not in y */ return(false); if (!nci) nci = new_shared_info(sc); for (ex = x; (is_let(ex)) && (ex != sc->rootlet); ex = outlet(ex)) for (px = let_slots(ex); is_slot(px); px = next_slot(px)) if (symbol_tag(slot_symbol(px)) == 0) /* unshadowed */ { symbol_tag(slot_symbol(px)) = sc->syms_tag; /* values don't match */ if (!slots_match(sc, px, y, morally, nci)) return(false); } return(true); } static bool closure_equal(s7_scheme *sc, s7_pointer x, s7_pointer y, shared_info *ci, bool morally) { if (x == y) return(true); if (type(x) != type(y)) return(false); if ((has_methods(x)) && (has_methods(y))) { s7_pointer equal_func; equal_func = find_method(sc, closure_let(x), (morally) ? sc->IS_MORALLY_EQUAL : sc->IS_EQUAL); if (equal_func != sc->UNDEFINED) return(s7_boolean(sc, s7_apply_function(sc, equal_func, list_2(sc, x, y)))); } /* not sure about this -- we can't simply check let_equal(closure_let(x), closure_let(y)) * because locally defined constant functions on the second pass find the outer let. */ return((morally) && (s7_is_equal_1(sc, closure_args(x), closure_args(y), ci, morally)) && (s7_is_equal_1(sc, closure_body(x), closure_body(y), ci, morally))); } static bool pair_equal(s7_scheme *sc, s7_pointer x, s7_pointer y, shared_info *ci, bool morally) { int i; s7_pointer px, py; shared_info *nci = ci; if (x == y) return(true); if (!is_pair(y)) { if ((morally) && (has_methods(y))) { s7_pointer equal_func; equal_func = find_method(sc, find_let(sc, y), sc->IS_MORALLY_EQUAL); if (equal_func != sc->UNDEFINED) return(s7_boolean(sc, s7_apply_function(sc, equal_func, list_2(sc, y, x)))); } return(false); } if (ci) { i = equal_ref(sc, x, y, ci); if (i == 0) return(false); if (i == 1) return(true); } else nci = new_shared_info(sc); if (!s7_is_equal_1(sc, car(x), car(y), nci, morally)) return(false); for (px = cdr(x), py = cdr(y); (is_pair(px)) && (is_pair(py)); px = cdr(px), py = cdr(py)) { if (!s7_is_equal_1(sc, car(px), car(py), nci, morally)) return(false); i = equal_ref(sc, px, py, nci); if (i == 0) return(false); if (i == 1) return(true); } return(s7_is_equal_1(sc, px, py, nci, morally)); } static bool vector_rank_match(s7_scheme *sc, s7_pointer x, s7_pointer y) { int x_dims, y_dims; if (vector_has_dimensional_info(x)) x_dims = vector_ndims(x); else x_dims = 1; if (vector_has_dimensional_info(y)) y_dims = vector_ndims(y); else y_dims = 1; if (x_dims != y_dims) return(false); if (x_dims > 1) { int j; for (j = 0; j < x_dims; j++) if (vector_dimension(x, j) != vector_dimension(y, j)) return(false); } return(true); } static bool vector_equal(s7_scheme *sc, s7_pointer x, s7_pointer y, shared_info *ci, bool morally) { s7_int i, len; shared_info *nci = ci; if (x == y) return(true); if (!s7_is_vector(y)) { if ((morally) && (has_methods(y))) { s7_pointer equal_func; equal_func = find_method(sc, find_let(sc, y), sc->IS_MORALLY_EQUAL); if (equal_func != sc->UNDEFINED) return(s7_boolean(sc, s7_apply_function(sc, equal_func, list_2(sc, y, x)))); } return(false); } len = vector_length(x); if (len != vector_length(y)) return(false); if (len == 0) { if (morally) return(true); if (!vector_rank_match(sc, x, y)) return(false); return(true); } if (!vector_rank_match(sc, x, y)) return(false); if (type(x) != type(y)) { if (!morally) return(false); /* (morally-equal? (make-int-vector 3 0) (make-vector 3 0)) -> #t * (morally-equal? (make-float-vector 3 1.0) (vector 1 1 1)) -> #t */ for (i = 0; i < len; i++) if (!s7_is_equal_1(sc, vector_getter(x)(sc, x, i), vector_getter(y)(sc, y, i), NULL, true)) /* this could be greatly optimized */ return(false); return(true); } if (is_float_vector(x)) { if (!morally) { for (i = 0; i < len; i++) { s7_double z; z = float_vector_element(x, i); if ((is_NaN(z)) || (z != float_vector_element(y, i))) return(false); } return(true); } else { s7_double *arr1, *arr2; s7_double fudge; arr1 = float_vector_elements(x); arr2 = float_vector_elements(y); fudge = sc->morally_equal_float_epsilon; if (fudge == 0.0) { for (i = 0; i < len; i++) if ((arr1[i] != arr2[i]) && ((!is_NaN(arr1[i])) || (!is_NaN(arr2[i])))) return(false); } else { for (i = 0; i < len; i++) { s7_double diff; diff = fabs(arr1[i] - arr2[i]); if (diff > fudge) return(false); if ((is_NaN(diff)) && ((!is_NaN(arr1[i])) || (!is_NaN(arr2[i])))) return(false); } } return(true); } } if (is_int_vector(x)) { for (i = 0; i < len; i++) if (int_vector_element(x, i) != int_vector_element(y, i)) return(false); return(true); } if (ci) { i = equal_ref(sc, x, y, ci); if (i == 0) return(false); if (i == 1) return(true); } else nci = new_shared_info(sc); for (i = 0; i < len; i++) if (!(s7_is_equal_1(sc, vector_element(x, i), vector_element(y, i), nci, morally))) return(false); return(true); } static bool iterator_equal(s7_scheme *sc, s7_pointer x, s7_pointer y, shared_info *ci, bool morally) { if (x == y) return(true); if (!is_iterator(y)) return(false); switch (type(iterator_sequence(x))) { case T_STRING: return((is_string(iterator_sequence(y))) && (iterator_position(x) == iterator_position(y)) && (string_equal(sc, iterator_sequence(x), iterator_sequence(y), ci, morally))); case T_VECTOR: case T_INT_VECTOR: case T_FLOAT_VECTOR: return((s7_is_vector(iterator_sequence(y))) && (iterator_position(x) == iterator_position(y)) && (vector_equal(sc, iterator_sequence(x), iterator_sequence(y), ci, morally))); case T_PAIR: return((iterator_sequence(x) == iterator_sequence(y)) && (iterator_next(x) == iterator_next(y)) && /* even if seqs are equal, one might be at end */ (iterator_current(x) == iterator_current(y))); /* current pointer into the sequence */ case T_HASH_TABLE: return((iterator_sequence(x) == iterator_sequence(y)) && (iterator_next(x) == iterator_next(y)) && (iterator_current(x) == iterator_current(y)) && (iterator_hash_current(x) == iterator_hash_current(y)) && (iterator_position(x) == iterator_position(y))); default: break; } return(false); } static bool bignum_equal(s7_scheme *sc, s7_pointer x, s7_pointer y, shared_info *ci, bool morally) { if (!s7_is_number(y)) return(false); #if WITH_GMP if (!morally) return(big_numbers_are_eqv(x, y)); return(big_equal(sc, set_plist_2(sc, x, y)) != sc->F); #else return(false); #endif } static bool integer_equal(s7_scheme *sc, s7_pointer x, s7_pointer y, shared_info *ci, bool morally) { #if WITH_GMP if (is_big_number(y)) { if (!morally) return(big_numbers_are_eqv(x, y)); return(big_equal(sc, set_plist_2(sc, x, y)) != sc->F); } #endif if (is_integer(y)) return(integer(x) == integer(y)); if ((!morally) || (!is_number(y))) return(false); if (is_t_real(y)) return((!is_NaN(real(y))) && (fabs(integer(x) - real(y)) <= sc->morally_equal_float_epsilon)); if (is_t_ratio(y)) return(s7_fabsl(integer(x) - fraction(y)) <= sc->morally_equal_float_epsilon); return((!is_NaN(real_part(y))) && (!is_NaN(imag_part(y))) && (fabs(integer(x) - real_part(y)) <= sc->morally_equal_float_epsilon) && (fabs(imag_part(y)) <= sc->morally_equal_float_epsilon)); } /* apparently ratio_equal is predefined in g++ -- name collision on mac */ static bool fraction_equal(s7_scheme *sc, s7_pointer x, s7_pointer y, shared_info *ci, bool morally) { #if WITH_GMP if (is_big_number(y)) { if (!morally) return(big_numbers_are_eqv(x, y)); return(big_equal(sc, set_plist_2(sc, x, y)) != sc->F); } #endif if (!morally) return((s7_is_ratio(y)) && (numerator(x) == numerator(y)) && (denominator(x) == denominator(y))); if (is_t_ratio(y)) return(s7_fabsl(fraction(x) - fraction(y)) <= sc->morally_equal_float_epsilon); if (is_t_real(y)) return(floats_are_morally_equal(sc, fraction(x), real(y))); if (is_integer(y)) return(s7_fabsl(fraction(x) - integer(y)) <= sc->morally_equal_float_epsilon); if (is_t_complex(y)) return((!is_NaN(real_part(y))) && (!is_NaN(imag_part(y))) && (s7_fabsl(fraction(x) - real_part(y)) <= sc->morally_equal_float_epsilon) && (fabs(imag_part(y)) <= sc->morally_equal_float_epsilon)); return(false); } static bool real_equal(s7_scheme *sc, s7_pointer x, s7_pointer y, shared_info *ci, bool morally) { #if WITH_GMP if (is_big_number(y)) { if (!morally) return(big_numbers_are_eqv(x, y)); return(big_equal(sc, set_plist_2(sc, x, y)) != sc->F); } #endif if (!morally) return((is_t_real(y)) && (real(x) == real(y))); if (!is_number(y)) return(false); if (is_t_real(y)) return(floats_are_morally_equal(sc, real(x), real(y))); if (is_integer(y)) return((!is_NaN(real(x))) && (fabs(real(x) - integer(y)) <= sc->morally_equal_float_epsilon)); if (is_t_ratio(y)) return(floats_are_morally_equal(sc, real(x), fraction(y))); if (is_NaN(real(x))) return((is_NaN(real_part(y))) && (fabs(imag_part(y)) <= sc->morally_equal_float_epsilon)); return((!is_NaN(real(x))) && (!is_NaN(real_part(y))) && (!is_NaN(imag_part(y))) && ((real(x) == real_part(y)) || (fabs(real(x) - real_part(y)) <= sc->morally_equal_float_epsilon)) && (fabs(imag_part(y)) <= sc->morally_equal_float_epsilon)); } static bool complex_equal(s7_scheme *sc, s7_pointer x, s7_pointer y, shared_info *ci, bool morally) { #if WITH_GMP if (is_big_number(y)) { if (!morally) return(big_numbers_are_eqv(x, y)); return(big_equal(sc, set_plist_2(sc, x, y)) != sc->F); } #endif if (!morally) return((is_t_complex(y)) && (!is_NaN(real_part(x))) && (!is_NaN(imag_part(x))) && (real_part(x) == real_part(y)) && (imag_part(x) == imag_part(y))); if (!is_number(y)) return(false); if (is_integer(y)) return((!is_NaN(real_part(x))) && (!is_NaN(imag_part(x))) && (fabs(real_part(x) - integer(y)) <= sc->morally_equal_float_epsilon) && (fabs(imag_part(x)) <= sc->morally_equal_float_epsilon)); if (s7_is_ratio(y)) return((!is_NaN(real_part(x))) && (!is_NaN(imag_part(x))) && (s7_fabsl(real_part(x) - fraction(y)) <= sc->morally_equal_float_epsilon) && (fabs(imag_part(x)) <= sc->morally_equal_float_epsilon)); if (is_real(y)) { if (is_NaN(imag_part(x))) return(false); if (is_NaN(real(y))) return((is_NaN(real_part(x))) && (fabs(imag_part(x)) <= sc->morally_equal_float_epsilon)); return(((real_part(x) == real(y)) || (fabs(real_part(x) - real(y)) <= sc->morally_equal_float_epsilon)) && (fabs(imag_part(x)) <= sc->morally_equal_float_epsilon)); } /* should (morally-equal? nan.0 (complex nan.0 nan.0)) be #t (it's #f above)? */ if (is_NaN(real_part(x))) return((is_NaN(real_part(y))) && (((is_NaN(imag_part(x))) && (is_NaN(imag_part(y)))) || (imag_part(x) == imag_part(y)) || (fabs(imag_part(x) - imag_part(y)) <= sc->morally_equal_float_epsilon))); if (is_NaN(imag_part(x))) return((is_NaN(imag_part(y))) && ((real_part(x) == real_part(y)) || (fabs(real_part(x) - real_part(y)) <= sc->morally_equal_float_epsilon))); if ((is_NaN(real_part(y))) || (is_NaN(imag_part(y)))) return(false); return(((real_part(x) == real_part(y)) || (fabs(real_part(x) - real_part(y)) <= sc->morally_equal_float_epsilon)) && ((imag_part(x) == imag_part(y)) || (fabs(imag_part(x) - imag_part(y)) <= sc->morally_equal_float_epsilon))); } static bool rng_equal(s7_scheme *sc, s7_pointer x, s7_pointer y, shared_info *ci, bool morally) { #if WITH_GMP return(x == y); #else return((x == y) || ((is_random_state(y)) && (random_seed(x) == random_seed(y)) && (random_carry(x) == random_carry(y)))); #endif } static bool (*equals[NUM_TYPES])(s7_scheme *sc, s7_pointer x, s7_pointer y, shared_info *ci, bool morally); static void init_equals(void) { int i; for (i = 0; i < NUM_TYPES; i++) equals[i] = eq_equal; equals[T_SYMBOL] = symbol_equal; equals[T_C_POINTER] = c_pointer_equal; equals[T_UNSPECIFIED] = unspecified_equal; equals[T_STRING] = string_equal; equals[T_SYNTAX] = syntax_equal; equals[T_C_OBJECT] = c_object_equal; equals[T_RANDOM_STATE] = rng_equal; equals[T_ITERATOR] = iterator_equal; equals[T_INPUT_PORT] = port_equal; equals[T_OUTPUT_PORT] = port_equal; equals[T_MACRO] = closure_equal; equals[T_MACRO_STAR] = closure_equal; equals[T_BACRO] = closure_equal; equals[T_BACRO_STAR] = closure_equal; equals[T_CLOSURE] = closure_equal; equals[T_CLOSURE_STAR] = closure_equal; equals[T_HASH_TABLE] = hash_table_equal; equals[T_LET] = let_equal; equals[T_PAIR] = pair_equal; equals[T_VECTOR] = vector_equal; equals[T_INT_VECTOR] = vector_equal; equals[T_FLOAT_VECTOR] = vector_equal; equals[T_INTEGER] = integer_equal; equals[T_RATIO] = fraction_equal; equals[T_REAL] = real_equal; equals[T_COMPLEX] = complex_equal; equals[T_BIG_INTEGER] = bignum_equal; equals[T_BIG_RATIO] = bignum_equal; equals[T_BIG_REAL] = bignum_equal; equals[T_BIG_COMPLEX] = bignum_equal; } static bool s7_is_equal_1(s7_scheme *sc, s7_pointer x, s7_pointer y, shared_info *ci, bool morally) { return((*(equals[type(x)]))(sc, x, y, ci, morally)); } bool s7_is_equal(s7_scheme *sc, s7_pointer x, s7_pointer y) { return(s7_is_equal_1(sc, x, y, NULL, false)); } bool s7_is_morally_equal(s7_scheme *sc, s7_pointer x, s7_pointer y) { return(s7_is_equal_1(sc, x, y, NULL, true)); } static s7_pointer g_is_equal(s7_scheme *sc, s7_pointer args) { #define H_is_equal "(equal? obj1 obj2) returns #t if obj1 is equal to obj2" #define Q_is_equal pcl_bt return(make_boolean(sc, s7_is_equal(sc, car(args), cadr(args)))); } static s7_pointer g_is_morally_equal(s7_scheme *sc, s7_pointer args) { #define H_is_morally_equal "(morally-equal? obj1 obj2) returns #t if obj1 is close enough to obj2." #define Q_is_morally_equal pcl_bt return(make_boolean(sc, s7_is_morally_equal(sc, car(args), cadr(args)))); } /* ---------------------------------------- length, copy, fill ---------------------------------------- */ static s7_pointer s7_length(s7_scheme *sc, s7_pointer lst) { switch (type(lst)) { case T_PAIR: { int len; len = s7_list_length(sc, lst); /* len < 0 -> dotted and (abs len) is length not counting the final cdr * len == 0, circular so length is infinite */ if (len == 0) return(real_infinity); return(make_integer(sc, len)); } case T_NIL: return(small_int(0)); case T_INT_VECTOR: case T_FLOAT_VECTOR: case T_VECTOR: return(make_integer(sc, vector_length(lst))); case T_STRING: return(make_integer(sc, string_length(lst))); case T_ITERATOR: return(make_integer(sc, iterator_length(lst))); /* in several cases, this is incorrect */ case T_HASH_TABLE: return(make_integer(sc, hash_table_mask(lst) + 1)); case T_C_OBJECT: check_method(sc, lst, sc->LENGTH, list_1(sc, lst)); return(object_length(sc, lst)); case T_LET: check_method(sc, lst, sc->LENGTH, list_1(sc, lst)); return(make_integer(sc, let_length(sc, lst))); case T_CLOSURE: case T_CLOSURE_STAR: if (has_methods(lst)) return(make_integer(sc, closure_length(sc, lst))); return(sc->F); case T_INPUT_PORT: if (is_string_port(lst)) return(make_integer(sc, port_data_size(lst))); return(sc->F); default: return(sc->F); } return(sc->F); } static s7_pointer g_length(s7_scheme *sc, s7_pointer args) { #define H_length "(length obj) returns the length of obj, which can be a list, vector, string, or hash-table. \ The length of a dotted list does not include the final cdr, and is returned as a negative number. A circular \ list has infinite length. Length of anything else returns #f." #define Q_length pcl_t return(s7_length(sc, car(args))); } /* what about (length file)? input port, read_file gets the file length, so perhaps save it * but we're actually looking at the port, so its length is what remains to be read? (if input port) */ PF_TO_PF(length, s7_length) /* -------------------------------- copy -------------------------------- */ static s7_pointer copy_to_string_error = NULL, copy_to_byte_vector_error = NULL; static void set_string_error_source(s7_scheme *sc, s7_pointer source) { if (!copy_to_string_error) copy_to_string_error = s7_make_permanent_string("copy ~A to string, ~S is not a character"); if (!copy_to_byte_vector_error) copy_to_byte_vector_error = s7_make_permanent_string("copy ~A to byte-vector, ~S is not a byte"); cadr(sc->elist_3) = prepackaged_type_name(sc, source); } static s7_pointer string_setter(s7_scheme *sc, s7_pointer str, s7_int loc, s7_pointer val) { if (s7_is_character(val)) { string_value(str)[loc] = s7_character(val); return(val); } /* (copy #(3) "123"): wrong type arg because not a char, but it's very confusing to report * error: copy argument 3, 3, is an integer but should be a character * perhaps better, copy #(3) to string, 3 is not a character */ #if DEBUGGING if (!copy_to_string_error) {fprintf(stderr, "string_error not set\n"); abort();} #endif car(sc->elist_3) = copy_to_string_error; caddr(sc->elist_3) = val; return(s7_error(sc, sc->WRONG_TYPE_ARG, sc->elist_3)); } static s7_pointer byte_vector_setter(s7_scheme *sc, s7_pointer str, s7_int loc, s7_pointer val) { if (s7_is_integer(val)) { s7_int byte; byte = s7_integer(val); if ((byte >= 0) && (byte < 256)) string_value(str)[loc] = (unsigned char)byte; else return(simple_wrong_type_argument_with_type(sc, sc->COPY, val, AN_UNSIGNED_BYTE)); return(val); } #if DEBUGGING if (!copy_to_byte_vector_error) {fprintf(stderr, "byte_vector_error not set\n"); abort();} #endif car(sc->elist_3) = copy_to_byte_vector_error; caddr(sc->elist_3) = val; return(s7_error(sc, sc->WRONG_TYPE_ARG, sc->elist_3)); } static s7_pointer string_getter(s7_scheme *sc, s7_pointer str, s7_int loc) { return(s7_make_character(sc, (unsigned char)(string_value(str)[loc]))); /* cast needed else (copy (string (integer->char 255))...) is trouble */ } static s7_pointer byte_vector_getter(s7_scheme *sc, s7_pointer str, s7_int loc) { return(make_integer(sc, (unsigned char)(string_value(str)[loc]))); } static s7_pointer c_object_setter(s7_scheme *sc, s7_pointer obj, s7_int loc, s7_pointer val) { car(sc->T2_1) = make_integer(sc, loc); car(sc->T2_2) = val; return((*(c_object_set(obj)))(sc, obj, sc->T2_1)); } static s7_pointer c_object_getter(s7_scheme *sc, s7_pointer obj, s7_int loc) { car(sc->T1_1) = make_integer(sc, loc); return((*(c_object_ref(obj)))(sc, obj, sc->T1_1)); } static s7_pointer let_setter(s7_scheme *sc, s7_pointer e, s7_int loc, s7_pointer val) { /* loc is irrelevant here * val has to be of the form (cons symbol value) * if symbol is already in e, its value is changed, otherwise a new slot is added to e */ static s7_pointer ls_err = NULL; s7_pointer sym; if (!is_pair(val)) { if (!ls_err) ls_err = s7_make_permanent_string("(cons symbol value)"); return(wrong_type_argument_with_type(sc, sc->COPY, 3, e, ls_err)); } sym = car(val); if (!is_symbol(sym)) { if (!ls_err) ls_err = s7_make_permanent_string("(cons symbol value)"); return(wrong_type_argument_with_type(sc, sc->COPY, 3, e, ls_err)); } if ((symbol_id(sym) < let_id(e)) || (s7_let_set(sc, e, sym, cdr(val)) != cdr(val))) make_slot_1(sc, e, sym, cdr(val)); return(val); } static s7_pointer hash_table_setter(s7_scheme *sc, s7_pointer e, s7_int loc, s7_pointer val) { /* loc is irrelevant here * val has to be of the form (cons key value) * if key is already in e, its value is changed, otherwise a new slot is added to e */ if (!is_pair(val)) return(wrong_type_argument_with_type(sc, sc->COPY, 1, e, A_LIST)); return(s7_hash_table_set(sc, e, car(val), cdr(val))); } s7_pointer s7_copy(s7_scheme *sc, s7_pointer args) { #define H_copy "(copy obj) returns a copy of obj, (copy src dest) copies src into dest, (copy src dest start end) copies src from start to end." #define Q_copy s7_make_circular_signature(sc, 3, 4, sc->T, sc->IS_SEQUENCE, sc->IS_SEQUENCE, sc->IS_INTEGER) s7_pointer source, dest; s7_int i, j, dest_len, start, end, source_len; s7_pointer (*set)(s7_scheme *sc, s7_pointer obj, s7_int loc, s7_pointer val) = NULL; s7_pointer (*get)(s7_scheme *sc, s7_pointer obj, s7_int loc) = NULL; bool have_indices; source = car(args); if (is_null(cdr(args))) /* (copy obj) */ { switch (type(source)) { case T_STRING: { s7_pointer ns; ns = s7_make_string_with_length(sc, string_value(source), string_length(source)); if (is_byte_vector(source)) set_byte_vector(ns); return(ns); } case T_C_OBJECT: return(object_copy(sc, args)); case T_RANDOM_STATE: return(rng_copy(sc, args)); case T_HASH_TABLE: /* this has to copy nearly everything */ { int gc_loc; s7_pointer new_hash; new_hash = s7_make_hash_table(sc, hash_table_mask(source) + 1); gc_loc = s7_gc_protect(sc, new_hash); hash_table_checker(new_hash) = hash_table_checker(source); hash_table_mapper(new_hash) = hash_table_mapper(source); hash_table_procedures(new_hash) = hash_table_procedures(source); hash_table_copy(sc, source, new_hash, 0, hash_table_entries(source)); s7_gc_unprotect_at(sc, gc_loc); return(new_hash); } case T_ITERATOR: return(iterator_copy(sc, source)); case T_LET: check_method(sc, source, sc->COPY, args); return(let_copy(sc, source)); /* this copies only the local env and points to outer envs */ case T_CLOSURE: case T_CLOSURE_STAR: case T_MACRO: case T_MACRO_STAR: case T_BACRO: case T_BACRO_STAR: check_method(sc, source, sc->COPY, args); return(copy_closure(sc, source)); case T_INT_VECTOR: case T_FLOAT_VECTOR: case T_VECTOR: return(s7_vector_copy(sc, source)); /* "shallow" copy */ case T_PAIR: /* top level only, as in the other cases, last arg checks for circles */ return(protected_list_copy(sc, source)); case T_INTEGER: new_cell(sc, dest, T_INTEGER); integer(dest) = integer(source); return(dest); case T_RATIO: new_cell(sc, dest, T_RATIO); numerator(dest) = numerator(source); denominator(dest) = denominator(source); return(dest); case T_REAL: new_cell(sc, dest, T_REAL); set_real(dest, real(source)); return(dest); case T_COMPLEX: new_cell(sc, dest, T_COMPLEX); set_real_part(dest, real_part(source)); set_imag_part(dest, imag_part(source)); return(dest); #if WITH_GMP case T_BIG_INTEGER: return(mpz_to_big_integer(sc, big_integer(source))); case T_BIG_RATIO: return(mpq_to_big_ratio(sc, big_ratio(source))); case T_BIG_REAL: return(mpfr_to_big_real(sc, big_real(source))); case T_BIG_COMPLEX: return(mpc_to_big_complex(sc, big_complex(source))); #endif case T_C_POINTER: return(s7_make_c_pointer(sc, s7_c_pointer(source))); } return(source); } have_indices = (is_pair(cddr(args))); dest = cadr(args); if ((source == dest) && (!have_indices)) return(dest); switch (type(source)) { case T_PAIR: if (dest == sc->KEY_READABLE) /* a kludge, but I can't think of anything less stupid */ return(copy_body(sc, source)); end = s7_list_length(sc, source); if (end == 0) end = circular_list_entries(source); else { if (end < 0) end = -end; } break; case T_INT_VECTOR: case T_FLOAT_VECTOR: case T_VECTOR: get = vector_getter(source); end = vector_length(source); break; case T_STRING: if (is_byte_vector(source)) get = byte_vector_getter; else get = string_getter; end = string_length(source); break; case T_HASH_TABLE: end = hash_table_entries(source); break; case T_C_OBJECT: check_method(sc, source, sc->COPY, args); { s7_pointer x; x = object_copy(sc, args); if (x == dest) return(dest); /* if object_copy can't handle args for some reason, it should return #f (not dest), and we'll soldier on... */ } get = c_object_direct_ref(source); if (!get) get = c_object_getter; end = object_length_to_int(sc, source); break; case T_LET: check_method(sc, source, sc->COPY, args); if (source == sc->rootlet) return(wrong_type_argument_with_type(sc, sc->COPY, 1, source, make_string_wrapper(sc, "a sequence other than the rootlet"))); end = let_length(sc, source); break; case T_NIL: end = 0; if (is_sequence(dest)) break; default: return(wrong_type_argument_with_type(sc, sc->COPY, 1, source, A_SEQUENCE)); /* copy doesn't have to duplicate fill!, so (copy 1 #(...)) need not be supported */ } start = 0; if (have_indices) { s7_pointer p; p = start_and_end(sc, sc->COPY, NULL, cddr(args), args, 3, &start, &end); if (p != sc->GC_NIL) return(p); } if ((start == 0) && (source == dest)) return(dest); source_len = end - start; switch (type(dest)) { case T_PAIR: dest_len = s7_list_length(sc, dest); if (dest_len == 0) dest_len = circular_list_entries(dest); else { if (dest_len < 0) dest_len = -dest_len; } break; case T_INT_VECTOR: case T_FLOAT_VECTOR: case T_VECTOR: set = vector_setter(dest); dest_len = vector_length(dest); break; case T_STRING: if (is_byte_vector(dest)) set = byte_vector_setter; else set = string_setter; dest_len = string_length(dest); break; case T_HASH_TABLE: set = hash_table_setter; dest_len = source_len; break; case T_C_OBJECT: set = c_object_direct_set(dest); if (!set) set = c_object_setter; dest_len = object_length_to_int(sc, dest); break; case T_LET: if (dest == sc->rootlet) return(wrong_type_argument_with_type(sc, sc->COPY, 2, dest, make_string_wrapper(sc, "a sequence other than the rootlet"))); set = let_setter; dest_len = source_len; /* grows via set, so dest_len isn't relevant */ break; case T_NIL: return(sc->NIL); default: return(wrong_type_argument_with_type(sc, sc->COPY, 2, dest, A_SEQUENCE)); } if ((source_len == 0) || (dest_len == 0)) return(dest); /* end is source_len if not set explicitly */ if (dest_len < source_len) { end = dest_len + start; source_len = dest_len; } if ((source != dest) && (type(source) == type(dest))) { switch (type(source)) { case T_PAIR: { s7_pointer ps, pd; ps = source; for (i = 0; i < start; i++) ps = cdr(ps); for (pd = dest; (i < end) && is_pair(ps) && is_pair(pd); i++, ps = cdr(ps), pd = cdr(pd)) car(pd) = car(ps); return(dest); } case T_VECTOR: memcpy((void *)(vector_elements(dest)), (void *)((vector_elements(source)) + start), source_len * sizeof(s7_pointer)); return(dest); case T_INT_VECTOR: memcpy((void *)(int_vector_elements(dest)), (void *)((int_vector_elements(source)) + start), source_len * sizeof(s7_int)); return(dest); case T_FLOAT_VECTOR: memcpy((void *)(float_vector_elements(dest)), (void *)((float_vector_elements(source)) + start), source_len * sizeof(s7_double)); return(dest); case T_STRING: /* this is 4 cases (string/byte-vector) */ memcpy((void *)string_value(dest), (void *)((string_value(source)) + start), source_len * sizeof(char)); return(dest); case T_C_OBJECT: { s7_pointer mi, mj; int gc_loc1, gc_loc2; s7_pointer (*ref)(s7_scheme *sc, s7_pointer obj, s7_pointer args); s7_pointer (*set)(s7_scheme *sc, s7_pointer obj, s7_pointer args); mi = make_mutable_integer(sc, start); mj = make_mutable_integer(sc, end); gc_loc1 = s7_gc_protect(sc, mi); gc_loc2 = s7_gc_protect(sc, mj); ref = c_object_ref(source); set = c_object_set(dest); for (i = start, j = 0; i < end; i++, j++) { integer(mi) = i; integer(mj) = j; car(sc->T1_1) = mi; car(sc->T2_2) = ref(sc, source, sc->T1_1); car(sc->T2_1) = mj; set(sc, dest, sc->T2_1); } s7_gc_unprotect_at(sc, gc_loc1); s7_gc_unprotect_at(sc, gc_loc2); return(dest); } case T_LET: break; case T_HASH_TABLE: { s7_pointer p; p = hash_table_copy(sc, source, dest, start, end); if ((hash_table_checker(source) != hash_table_checker(dest)) && (!hash_table_checker_locked(dest))) { if (hash_table_checker(dest) == hash_empty) hash_table_checker(dest) = hash_table_checker(source); else hash_table_checker(dest) = hash_equal; } return(p); } break; default: return(dest); } } switch (type(source)) { case T_PAIR: { s7_pointer p; p = source; if (start > 0) for (i = 0; i < start; i++) p = cdr(p); /* dest won't be a pair here -- the pair->pair case was caught above */ if (is_string(dest)) set_string_error_source(sc, source); for (i = start, j = 0; i < end; i++, j++, p = cdr(p)) set(sc, dest, j, car(p)); return(dest); } case T_LET: /* implicit index can give n-way reality check (ht growth by new entries) * if shadowed entries are they unshadowed by reversal? */ { /* source and dest can't be rootlet (checked above) */ s7_pointer slot; slot = let_slots(source); for (i = 0; i < start; i++) slot = next_slot(slot); if (is_pair(dest)) { s7_pointer p; for (i = start, p = dest; i < end; i++, p = cdr(p), slot = next_slot(slot)) car(p) = cons(sc, slot_symbol(slot), slot_value(slot)); } else { if (is_let(dest)) { for (i = start; i < end; i++, slot = next_slot(slot)) make_slot_1(sc, dest, slot_symbol(slot), slot_value(slot)); } else { if (is_hash_table(dest)) { for (i = start; i < end; i++, slot = next_slot(slot)) s7_hash_table_set(sc, dest, slot_symbol(slot), slot_value(slot)); } else { for (i = start, j = 0; i < end; i++, j++, slot = next_slot(slot)) set(sc, dest, j, cons(sc, slot_symbol(slot), slot_value(slot))); } } } return(dest); } case T_HASH_TABLE: { int loc, skip; hash_entry_t **elements; hash_entry_t *x = NULL; elements = hash_table_elements(source); loc = -1; skip = start; while (skip > 0) { while (!x) x = elements[++loc]; skip--; x = x->next; } if (is_pair(dest)) { s7_pointer p; for (i = start, p = dest; i < end; i++, p = cdr(p)) { while (!x) x = elements[++loc]; car(p) = cons(sc, x->key, x->value); x = x->next; } } else { if (is_let(dest)) { for (i = start; i < end; i++) { while (!x) x = elements[++loc]; make_slot_1(sc, dest, x->key, x->value); x = x->next; } } else { for (i = start, j = 0; i < end; i++, j++) { while (!x) x = elements[++loc]; set(sc, dest, j, cons(sc, x->key, x->value)); x = x->next; } } } return(dest); } case T_FLOAT_VECTOR: if (is_int_vector(dest)) { for (i = start, j = 0; i < end; i++, j++) int_vector_element(dest, j) = (s7_int)(float_vector_element(source, i)); return(dest); } break; case T_INT_VECTOR: if (is_float_vector(dest)) { for (i = start, j = 0; i < end; i++, j++) float_vector_element(dest, j) = (s7_double)(int_vector_element(source, i)); return(dest); } if (is_string(dest)) /* includes byte-vector, as below */ { for (i = start, j = 0; i < end; i++, j++) string_value(dest)[j] = (unsigned char)int_vector_element(source, i); return(dest); } break; case T_STRING: if (is_normal_vector(dest)) { if (is_byte_vector(source)) { for (i = start, j = 0; i < end; i++, j++) vector_element(dest, j) = make_integer(sc, (s7_int)((unsigned char)string_value(source)[i])); } else { for (i = start, j = 0; i < end; i++, j++) vector_element(dest, j) = s7_make_character(sc, (unsigned char)string_value(source)[i]); } return(dest); } if (is_int_vector(dest)) { for (i = start, j = 0; i < end; i++, j++) int_vector_element(dest, j) = (s7_int)((unsigned char)(string_value(source)[i])); return(dest); } if (is_float_vector(dest)) { for (i = start, j = 0; i < end; i++, j++) float_vector_element(dest, j) = (s7_double)((unsigned char)(string_value(source)[i])); return(dest); } } if (is_pair(dest)) { s7_pointer p; for (i = start, p = dest; i < end; i++, p = cdr(p)) car(p) = get(sc, source, i); } else { /* if source == dest here, we're moving data backwards, so this is safe in either case */ if (is_string(dest)) set_string_error_source(sc, source); for (i = start, j = 0; i < end; i++, j++) set(sc, dest, j, get(sc, source, i)); } /* some choices probably should raise an error, but don't: * (copy (make-hash-table) "1") ; nothing to copy (empty hash table), so no error */ return(dest); } #define g_copy s7_copy static s7_pointer c_copy(s7_scheme *sc, s7_pointer x) {return(s7_copy(sc, set_plist_1(sc, x)));} PF_TO_PF(copy, c_copy) /* -------------------------------- reverse -------------------------------- */ static s7_pointer g_reverse(s7_scheme *sc, s7_pointer args) { #define H_reverse "(reverse lst) returns a list with the elements of lst in reverse order. reverse \ also accepts a string or vector argument." #define Q_reverse s7_make_signature(sc, 2, sc->IS_SEQUENCE, sc->IS_SEQUENCE) s7_pointer p, np; p = car(args); sc->temp3 = p; np = sc->NIL; switch (type(p)) { case T_NIL: return(sc->NIL); case T_PAIR: return(s7_reverse(sc, p)); case T_STRING: { char *source, *dest, *end; int len; len = string_length(p); source = string_value(p); end = (char *)(source + len); dest = (char *)malloc((len + 1) * sizeof(char)); dest[len] = 0; np = make_string_uncopied_with_length(sc, dest, len); dest += len; while (source < end) *(--dest) = *source++; if (is_byte_vector(p)) set_byte_vector(np); } break; case T_INT_VECTOR: { s7_int *source, *dest, *end; s7_int len; len = vector_length(p); if (vector_rank(p) > 1) np = g_make_vector(sc, set_plist_3(sc, g_vector_dimensions(sc, set_plist_1(sc, p)), small_int(0), sc->T)); else np = make_vector_1(sc, len, NOT_FILLED, T_INT_VECTOR); source = int_vector_elements(p); end = (s7_int *)(source + len); dest = (s7_int *)(int_vector_elements(np) + len); while (source < end) *(--dest) = *source++; } break; case T_FLOAT_VECTOR: { s7_double *source, *dest, *end; s7_int len; len = vector_length(p); if (vector_rank(p) > 1) np = g_make_vector(sc, set_plist_3(sc, g_vector_dimensions(sc, set_plist_1(sc, p)), real_zero, sc->T)); else np = make_vector_1(sc, len, NOT_FILLED, T_FLOAT_VECTOR); source = float_vector_elements(p); end = (s7_double *)(source + len); dest = (s7_double *)(float_vector_elements(np) + len); while (source < end) *(--dest) = *source++; } break; case T_VECTOR: { s7_pointer *source, *dest, *end; s7_int len; len = vector_length(p); if (vector_rank(p) > 1) np = g_make_vector(sc, set_plist_1(sc, g_vector_dimensions(sc, list_1(sc, p)))); else np = make_vector_1(sc, len, NOT_FILLED, T_VECTOR); source = vector_elements(p); end = (s7_pointer *)(source + len); dest = (s7_pointer *)(vector_elements(np) + len); while (source < end) *(--dest) = *source++; } break; case T_HASH_TABLE: return(hash_table_reverse(sc, p)); case T_C_OBJECT: check_method(sc, p, sc->REVERSE, args); if (c_object_reverse(p)) return((*(c_object_reverse(p)))(sc, args)); eval_error(sc, "attempt to reverse ~S?", p); default: method_or_bust_with_type(sc, p, sc->REVERSE, args, A_SEQUENCE, 0); } return(np); } static s7_pointer c_reverse(s7_scheme *sc, s7_pointer x) {return(g_reverse(sc, set_plist_1(sc, x)));} PF_TO_PF(reverse, c_reverse) static s7_pointer c_reverse_in_place(s7_scheme *sc, s7_pointer p) { switch (type(p)) { case T_NIL: return(sc->NIL); case T_PAIR: { s7_pointer np; np = reverse_in_place(sc, sc->NIL, p); if (is_null(np)) return(simple_wrong_type_argument_with_type(sc, sc->REVERSEB, p, A_PROPER_LIST)); return(np); } break; /* (reverse! p) is supposed to change p directly and lisp programmers expect reverse! to be fast * so in a sense this is different from the other cases: it assumes (set! p (reverse! p)) * To make (reverse! p) direct: * for (l = p, r = cdr(p); is_pair(r); l = r, r = cdr(r)) opt1(r) = l; * if (!is_null(r)) return(simple_wrong_type_argument_with_type(sc, sc->REVERSEB, p, A_PROPER_LIST)); * for (r = l, l = p; l != r; l = cdr(l)) {t = car(l); car(l) = car(r); car(r) = t; if (cdr(l) != r) r = opt1(r);} */ case T_STRING: { int len; char *s1, *s2; len = string_length(p); if (len < 2) return(p); s1 = string_value(p); s2 = (char *)(s1 + len - 1); while (s1 < s2) {char c; c = *s1; *s1++ = *s2; *s2-- = c;} } break; case T_INT_VECTOR: { s7_int len; s7_int *s1, *s2; len = vector_length(p); if (len < 2) return(p); s1 = int_vector_elements(p); s2 = (s7_int *)(s1 + len - 1); while (s1 < s2) {s7_int c; c = *s1; *s1++ = *s2; *s2-- = c;} } break; case T_FLOAT_VECTOR: { s7_int len; s7_double *s1, *s2; len = vector_length(p); if (len < 2) return(p); s1 = float_vector_elements(p); s2 = (s7_double *)(s1 + len - 1); while (s1 < s2) {s7_double c; c = *s1; *s1++ = *s2; *s2-- = c;} } break; case T_VECTOR: { s7_int len; s7_pointer *s1, *s2; len = vector_length(p); if (len < 2) return(p); s1 = vector_elements(p); s2 = (s7_pointer *)(s1 + len - 1); while (s1 < s2) {s7_pointer c; c = *s1; *s1++ = *s2; *s2-- = c;} } break; default: if ((is_simple_sequence(p)) && (!has_methods(p))) return(simple_wrong_type_argument_with_type(sc, sc->REVERSEB, p, make_string_wrapper(sc, "a vector, string, or list"))); method_or_bust_with_type(sc, p, sc->REVERSEB, list_1(sc, p), A_SEQUENCE, 0); } return(p); } static s7_pointer g_reverse_in_place(s7_scheme *sc, s7_pointer args) { #define H_reverse_in_place "(reverse! lst) reverses lst in place" #define Q_reverse_in_place s7_make_signature(sc, 2, sc->IS_SEQUENCE, sc->IS_SEQUENCE) return(c_reverse_in_place(sc, car(args))); } PF_TO_PF(reverse_in_place, c_reverse_in_place) /* -------------------------------- fill! -------------------------------- */ static s7_pointer list_fill(s7_scheme *sc, s7_pointer args) { /* ambiguous ("tree-fill"?) but if it's like vector-fill, we just stomp on the top level */ s7_pointer x, y, obj, val; s7_int i, start = 0, end, len; obj = car(args); len = s7_list_length(sc, obj); end = len; if (end < 0) end = -end; else {if (end == 0) end = 123123123;} val = cadr(args); if (!is_null(cddr(args))) { s7_pointer p; p = start_and_end(sc, sc->FILL, sc->FILL, cddr(args), args, 3, &start, &end); if (p != sc->GC_NIL) return(p); if (start == end) return(val); } if (len > 0) { s7_int i; s7_pointer p; if (end < len) len = end; for (i = 0, p = obj; i < start; p = cdr(p), i++); for (; i < len; p = cdr(p), i++) car(p) = val; return(val); } for (x = obj, y = obj, i = 0; ;i++) { if ((end > 0) && (i >= end)) return(val); if (i >= start) car(x) = val; if (!is_pair(cdr(x))) { if (!is_null(cdr(x))) cdr(x) = val; return(val); } x = cdr(x); if ((i & 1) != 0) y = cdr(y); if (x == y) return(val); } return(val); } s7_pointer s7_fill(s7_scheme *sc, s7_pointer args) { #define H_fill "(fill! obj val (start 0) end) fills obj with val" #define Q_fill s7_make_circular_signature(sc, 3, 4, sc->T, sc->IS_SEQUENCE, sc->T, sc->IS_INTEGER) s7_pointer p; p = car(args); switch (type(p)) { case T_STRING: return(g_string_fill(sc, args)); /* redundant type check here and below */ case T_INT_VECTOR: case T_FLOAT_VECTOR: case T_VECTOR: return(g_vector_fill(sc, args)); case T_PAIR: return(list_fill(sc, args)); case T_NIL: return(cadr(args)); /* this parallels the empty vector case */ case T_HASH_TABLE: return(hash_table_fill(sc, args)); case T_C_OBJECT: check_method(sc, p, sc->FILL, args); if (c_object_fill(p)) return((*(c_object_fill(p)))(sc, args)); eval_error(sc, "attempt to fill ~S?", p); default: check_method(sc, p, sc->FILL, args); } return(wrong_type_argument_with_type(sc, sc->FILL, 1, p, A_SEQUENCE)); /* (fill! 1 0) */ } #define g_fill s7_fill /* perhaps (fill iterator obj) could fill the underlying sequence (if any) -- not let/closure * similarly for length, reverse etc */ static s7_pointer c_fill(s7_scheme *sc, s7_pointer x, s7_pointer y) {return(s7_fill(sc, set_plist_2(sc, x, y)));} PF2_TO_PF(fill, c_fill) /* -------------------------------- append -------------------------------- */ static s7_int sequence_length(s7_scheme *sc, s7_pointer lst) { switch (type(lst)) { case T_PAIR: { int len; len = s7_list_length(sc, lst); if (len == 0) return(-1); return(len); } case T_NIL: return(0); case T_INT_VECTOR: case T_FLOAT_VECTOR: case T_VECTOR: return(vector_length(lst)); case T_STRING: return(string_length(lst)); case T_HASH_TABLE: return(hash_table_entries(lst)); case T_LET: return(let_length(sc, lst)); case T_C_OBJECT: { s7_pointer x; x = object_length(sc, lst); if (s7_is_integer(x)) return(s7_integer(x)); } } return(-1); } static s7_int total_sequence_length(s7_scheme *sc, s7_pointer args, s7_pointer caller, int typ) { s7_pointer p; int i; s7_int len = 0; for (i = 0, p = args; is_pair(p); p = cdr(p), i++) { s7_pointer seq; s7_int n; seq = car(p); n = sequence_length(sc, seq); if ((n > 0) && (typ != T_FREE) && ((type(seq) == T_HASH_TABLE) || (type(seq) == T_LET))) { wrong_type_argument(sc, sc->APPEND, i, seq, typ); return(0); } if (n < 0) { wrong_type_argument_with_type(sc, sc->APPEND, i, seq, (is_pair(seq)) ? A_PROPER_LIST : A_SEQUENCE); return(0); } len += n; } return(len); } static s7_pointer vector_append(s7_scheme *sc, s7_pointer args, int typ) { s7_pointer new_vec; s7_int len; len = total_sequence_length(sc, args, sc->VECTOR_APPEND, (typ == T_VECTOR) ? T_FREE : ((typ == T_FLOAT_VECTOR) ? T_REAL : T_INTEGER)); new_vec = make_vector_1(sc, len, (typ == T_VECTOR) ? FILLED : NOT_FILLED, typ); /* might hit GC in loop below so we can't use NOT_FILLED here */ if (len > 0) { s7_pointer p, sv; int i; sc->temp9 = new_vec; /* s7_copy below can call s7_error so s7_gc_protect here is tricky -- use a preset position perhaps? */ sv = make_subvector(sc, new_vec); sc->temp10 = sv; for (i = 0, p = args; is_pair(p); p = cdr(p)) { s7_int n; s7_pointer x; x = car(p); n = sequence_length(sc, x); if (n > 0) { vector_length(sv) = n; s7_copy(sc, set_plist_2(sc, x, sv)); vector_length(sv) = 0; /* so GC doesn't march off the end */ i += n; if (typ == T_VECTOR) vector_elements(sv) = (s7_pointer *)(vector_elements(new_vec) + i); else { if (typ == T_FLOAT_VECTOR) float_vector_elements(sv) = (s7_double *)(float_vector_elements(new_vec) + i); else int_vector_elements(sv) = (s7_int *)(int_vector_elements(new_vec) + i); } } } set_plist_2(sc, sc->NIL, sc->NIL); sc->temp9 = sc->NIL; sc->temp10 = sc->NIL; vector_length(sv) = 0; } return(new_vec); } static s7_pointer string_append(s7_scheme *sc, s7_pointer args) { s7_pointer new_str; s7_int len; len = total_sequence_length(sc, args, sc->STRING_APPEND, (is_byte_vector(car(args))) ? T_INTEGER : T_CHARACTER); new_str = make_empty_string(sc, len, 0); if (is_byte_vector(car(args))) set_byte_vector(new_str); if (len > 0) { s7_pointer p, sv; int i; sc->temp9 = new_str; sv = make_string_wrapper_with_length(sc, (const char *)string_value(new_str), len); if (is_byte_vector(new_str)) set_byte_vector(sv); sc->temp10 = sv; for (i = 0, p = args; is_pair(p); p = cdr(p)) { s7_pointer x; s7_int n; x = car(p); n = sequence_length(sc, x); if (n > 0) { string_length(sv) = n; s7_copy(sc, set_plist_2(sc, x, sv)); i += n; string_value(sv) = (char *)(string_value(new_str) + i); } } set_plist_2(sc, sc->NIL, sc->NIL); sc->temp9 = sc->NIL; sc->temp10 = sc->NIL; string_length(sv) = 0; } return(new_str); } static s7_pointer hash_table_append(s7_scheme *sc, s7_pointer args) { s7_pointer new_hash, p; new_hash = s7_make_hash_table(sc, sc->default_hash_table_length); for (p = args; is_pair(p); p = cdr(p)) s7_copy(sc, set_plist_2(sc, car(p), new_hash)); set_plist_2(sc, sc->NIL, sc->NIL); return(new_hash); } static s7_pointer let_append(s7_scheme *sc, s7_pointer args) { s7_pointer new_let, p, e; e = car(args); check_method(sc, e, sc->APPEND, args); new_let = new_frame_in_env(sc, sc->NIL); for (p = args; is_pair(p); p = cdr(p)) s7_copy(sc, set_plist_2(sc, car(p), new_let)); set_plist_2(sc, sc->NIL, sc->NIL); return(new_let); } static s7_pointer g_append(s7_scheme *sc, s7_pointer args) { #define H_append "(append ...) returns its argument sequences appended into one sequence" #define Q_append s7_make_circular_signature(sc, 0, 1, sc->T) s7_pointer a1; if (is_null(args)) return(sc->NIL); /* (append) -> () */ a1 = car(args); /* first arg determines result type unless all args but last are empty (sigh) */ if (is_null(cdr(args))) return(a1); /* (append ) -> */ switch (type(a1)) { case T_NIL: case T_PAIR: return(g_list_append(sc, args)); /* only list case accepts any trailing arg because dotted lists are special */ case T_VECTOR: case T_INT_VECTOR: case T_FLOAT_VECTOR: return(vector_append(sc, args, type(a1))); case T_STRING: return(string_append(sc, args)); case T_HASH_TABLE: return(hash_table_append(sc, args)); case T_LET: return(let_append(sc, args)); default: check_method(sc, a1, sc->APPEND, args); } return(wrong_type_argument_with_type(sc, sc->APPEND, 1, a1, A_SEQUENCE)); /* (append 1 0) */ } static s7_pointer object_to_list(s7_scheme *sc, s7_pointer obj) { /* used only in format_to_port_1 and (map values ...) */ switch (type(obj)) { case T_INT_VECTOR: case T_FLOAT_VECTOR: case T_VECTOR: return(s7_vector_to_list(sc, obj)); case T_STRING: if (is_byte_vector(obj)) return(byte_vector_to_list(sc, string_value(obj), string_length(obj))); return(s7_string_to_list(sc, string_value(obj), string_length(obj))); case T_HASH_TABLE: if (hash_table_entries(obj) > 0) { s7_pointer x, iterator; iterator = s7_make_iterator(sc, obj); sc->temp8 = iterator; sc->w = sc->NIL; while (true) { x = s7_iterate(sc, iterator); if (iterator_is_at_end(iterator)) break; sc->w = cons(sc, x, sc->w); } x = sc->w; sc->w = sc->NIL; sc->temp8 = sc->NIL; return(x); } return(sc->NIL); case T_LET: #if (!WITH_PURE_S7) check_method(sc, obj, sc->LET_TO_LIST, list_1(sc, obj)); #endif return(s7_let_to_list(sc, obj)); case T_ITERATOR: { s7_pointer result, p = NULL; int results = 0; result = sc->NIL; while (true) { s7_pointer val; val = s7_iterate(sc, obj); if ((val == sc->ITERATOR_END) && (iterator_is_at_end(obj))) { sc->temp8 = sc->NIL; return(result); } if (sc->safety > 0) { results++; if (results > 10000) { fprintf(stderr, "iterator in object->list is creating a very long list!\n"); results = S7_LONG_MIN; } } if (val != sc->NO_VALUE) { if (is_null(result)) { if (is_multiple_value(val)) { result = multiple_value(val); clear_multiple_value(val); for (p = result; is_pair(cdr(p)); p = cdr(p)); } else { result = cons(sc, val, sc->NIL); p = result; } sc->temp8 = result; } else { if (is_multiple_value(val)) { cdr(p) = multiple_value(val); clear_multiple_value(val); for (; is_pair(cdr(p)); p = cdr(p)); } else { cdr(p) = cons(sc, val, sc->NIL); p = cdr(p); } } } } } case T_C_OBJECT: { long int i, len; /* the "long" matters on 64-bit machines */ s7_pointer x, z, result; int gc_z = -1; x = object_length(sc, obj); if (s7_is_integer(x)) len = s7_integer(x); else return(sc->F); if (len < 0) return(sc->F); if (len == 0) return(sc->NIL); result = make_list(sc, len, sc->NIL); sc->temp8 = result; z = list_1(sc, sc->F); gc_z = s7_gc_protect(sc, z); car(sc->Z2_1) = sc->x; car(sc->Z2_2) = sc->z; for (i = 0, x = result; i < len; i++, x = cdr(x)) { car(z) = make_integer(sc, i); car(x) = (*(c_object_ref(obj)))(sc, obj, z); } sc->x = car(sc->Z2_1); sc->z = car(sc->Z2_2); s7_gc_unprotect_at(sc, gc_z); sc->temp8 = sc->NIL; return(result); } } return(obj); } /* ---------------- stacktrace ---------------- */ static s7_pointer stacktrace_find_caller(s7_scheme *sc, s7_pointer e) { if ((is_let(e)) && (e != sc->rootlet)) { if (is_function_env(e)) return(funclet_function(e)); return(stacktrace_find_caller(sc, outlet(e))); } return(sc->F); } static bool stacktrace_find_let(s7_scheme *sc, int loc, s7_pointer e) { return((loc > 0) && ((stack_let(sc->stack, loc) == e) || (stacktrace_find_let(sc, loc - 4, e)))); } static int stacktrace_find_error_hook_quit(s7_scheme *sc) { int i; for (i = s7_stack_top(sc) - 1; i >= 3; i -= 4) if (stack_op(sc->stack, i) == OP_ERROR_HOOK_QUIT) return(i); return(-1); } static bool stacktrace_in_error_handler(s7_scheme *sc, int loc) { return((outlet(sc->owlet) == sc->envir) || (stacktrace_find_let(sc, loc * 4, outlet(sc->owlet))) || (stacktrace_find_error_hook_quit(sc) > 0)); } static bool stacktrace_error_hook_function(s7_scheme *sc, s7_pointer sym) { if (is_symbol(sym)) { s7_pointer f; f = s7_symbol_value(sc, sym); return((is_procedure(f)) && (is_procedure(sc->error_hook)) && (is_pair(s7_hook_functions(sc, sc->error_hook))) && (direct_memq(f, s7_hook_functions(sc, sc->error_hook)))); } return(false); } static char *stacktrace_walker(s7_scheme *sc, s7_pointer code, s7_pointer e, char *notes, int gc_syms, int code_cols, int total_cols, int notes_start_col, bool as_comment) { s7_pointer syms; syms = gc_protected_at(sc, gc_syms); if (is_symbol(code)) { if ((!direct_memq(code, syms)) && (!is_slot(global_slot(code)))) { s7_pointer val; syms = cons(sc, code, syms); gc_protected_at(sc, gc_syms) = syms; val = s7_symbol_local_value(sc, code, e); if ((val) && (val != sc->UNDEFINED) && (!is_any_macro(val))) { int typ; typ = type(val); if (typ < T_GOTO) { char *objstr, *str; const char *spaces; int objlen, new_note_len, notes_max, cur_line_len = 0, spaces_len; bool new_notes_line = false; spaces = " "; spaces_len = strlen(spaces); if (notes_start_col < 0) notes_start_col = 50; notes_max = total_cols - notes_start_col; objstr = s7_object_to_c_string(sc, val); objlen = strlen(objstr); if (objlen > notes_max) { objstr[notes_max - 4] = '.'; objstr[notes_max - 3] = '.'; objstr[notes_max - 2] = '.'; objstr[notes_max - 1] = '\0'; objlen = notes_max; } new_note_len = symbol_name_length(code) + 3 + objlen; /* we want to append this much info to the notes, but does it need a new line? */ if (notes_start_col < code_cols) new_notes_line = true; else { if (notes) { char *last_newline; last_newline = strrchr(notes, (int)'\n'); /* returns ptr to end if none = nil if not found? */ if (last_newline) cur_line_len = strlen(notes) - strlen(last_newline); else cur_line_len = strlen(notes); new_notes_line = ((cur_line_len + new_note_len) > notes_max); } } if (new_notes_line) { new_note_len += (4 + notes_start_col + ((notes) ? strlen(notes) : 0)); str = (char *)malloc(new_note_len * sizeof(char)); snprintf(str, new_note_len, "%s\n%s%s%s%s: %s", (notes) ? notes : "", (as_comment) ? "; " : "", (spaces_len >= notes_start_col) ? (char *)(spaces + spaces_len - notes_start_col) : "", (as_comment) ? "" : " ; ", symbol_name(code), objstr); } else { new_note_len += ((notes) ? strlen(notes) : 0) + 4; str = (char *)malloc(new_note_len * sizeof(char)); snprintf(str, new_note_len, "%s%s%s: %s", (notes) ? notes : "", (notes) ? ", " : " ; ", symbol_name(code), objstr); } free(objstr); if (notes) free(notes); return(str); } } } return(notes); } if (is_pair(code)) { notes = stacktrace_walker(sc, car(code), e, notes, gc_syms, code_cols, total_cols, notes_start_col, as_comment); return(stacktrace_walker(sc, cdr(code), e, notes, gc_syms, code_cols, total_cols, notes_start_col, as_comment)); } return(notes); } static char *stacktrace_add_func(s7_scheme *sc, s7_pointer f, s7_pointer code, char *errstr, char *notes, int code_max, bool as_comment) { int newlen, errlen; char *newstr, *str; errlen = strlen(errstr); if ((is_symbol(f)) && (f != car(code))) { newlen = symbol_name_length(f) + errlen + 10; newstr = (char *)malloc(newlen * sizeof(char)); errlen = snprintf(newstr, newlen, "%s: %s", symbol_name(f), errstr); } else { newlen = errlen + 8; newstr = (char *)malloc(newlen * sizeof(char)); if ((errlen > 2) && (errstr[2] == '(')) errlen = snprintf(newstr, newlen, " %s", errstr); else errlen = snprintf(newstr, newlen, "%s", errstr); } newlen = code_max + 8 + ((notes) ? strlen(notes) : 0); str = (char *)malloc(newlen * sizeof(char)); if (errlen >= code_max) { newstr[code_max - 4] = '.'; newstr[code_max - 3] = '.'; newstr[code_max - 2] = '.'; newstr[code_max - 1] = '\0'; snprintf(str, newlen, "%s%s%s\n", (as_comment) ? "; " : "", newstr, (notes) ? notes : ""); } else { /* send out newstr, pad with spaces to code_max, then notes */ int len; len = snprintf(str, newlen, "%s%s", (as_comment) ? "; " : "", newstr); if (notes) { int i; for (i = len; i < code_max - 1; i++) str[i] = ' '; str[i] = '\0'; #ifdef __OpenBSD__ strlcat(str, notes, newlen); strlcat(str, "\n", newlen); #else strcat(str, notes); strcat(str, "\n"); #endif } } free(newstr); return(str); } static char *stacktrace_1(s7_scheme *sc, int frames_max, int code_cols, int total_cols, int notes_start_col, bool as_comment) { char *str; int loc, top, frames = 0, gc_syms; gc_syms = s7_gc_protect(sc, sc->NIL); str = NULL; top = (sc->stack_end - sc->stack_start) / 4; /* (*s7* 'stack_top), not s7_stack_top! */ if (stacktrace_in_error_handler(sc, top)) { s7_pointer err_code; err_code = slot_value(sc->error_code); if (is_pair(err_code)) { char *errstr, *notes = NULL; s7_pointer cur_env, f; errstr = s7_object_to_c_string(sc, err_code); cur_env = outlet(sc->owlet); f = stacktrace_find_caller(sc, cur_env); /* this is a symbol */ if ((is_let(cur_env)) && (cur_env != sc->rootlet)) notes = stacktrace_walker(sc, err_code, cur_env, NULL, gc_syms, code_cols, total_cols, notes_start_col, as_comment); str = stacktrace_add_func(sc, f, err_code, errstr, notes, code_cols, as_comment); free(errstr); } /* now if OP_ERROR_HOOK_QUIT is in the stack, jump past it! */ loc = stacktrace_find_error_hook_quit(sc); if (loc > 0) top = (loc + 1) / 4; } for (loc = top - 1; loc > 0; loc--) { s7_pointer code; int true_loc; true_loc = (int)(loc + 1) * 4 - 1; code = stack_code(sc->stack, true_loc); if (is_pair(code)) { char *codestr; codestr = s7_object_to_c_string(sc, code); if (codestr) { if ((!local_strcmp(codestr, "(result)")) && (!local_strcmp(codestr, "(#f)")) && (strstr(codestr, "(stacktrace)") == NULL) && (strstr(codestr, "(stacktrace ") == NULL)) { s7_pointer e, f; e = stack_let(sc->stack, true_loc); f = stacktrace_find_caller(sc, e); if (!stacktrace_error_hook_function(sc, f)) { char *notes = NULL, *newstr; int newlen; frames++; if (frames > frames_max) { free(codestr); s7_gc_unprotect_at(sc, gc_syms); return(str); } if ((is_let(e)) && (e != sc->rootlet)) notes = stacktrace_walker(sc, code, e, NULL, gc_syms, code_cols, total_cols, notes_start_col, as_comment); newstr = stacktrace_add_func(sc, f, code, codestr, notes, code_cols, as_comment); free(codestr); if (notes) free(notes); newlen = strlen(newstr) + 1 + ((str) ? strlen(str) : 0); codestr = (char *)malloc(newlen * sizeof(char)); snprintf(codestr, newlen, "%s%s", (str) ? str : "", newstr); if (str) free(str); free(newstr); str = codestr; codestr = NULL; } else free(codestr); } else free(codestr); } } } s7_gc_unprotect_at(sc, gc_syms); return(str); } s7_pointer s7_stacktrace(s7_scheme *sc) { char *str; str = stacktrace_1(sc, 30, 45, 80, 45, false); return(make_string_uncopied_with_length(sc, str, safe_strlen(str))); } static s7_pointer g_stacktrace(s7_scheme *sc, s7_pointer args) { #define H_stacktrace "(stacktrace (max-frames 30) (code-cols 50) (total-cols 80) (note-col 50) as-comment) returns \ a stacktrace as a string. Each line has two portions, the code being evaluated and a note giving \ the value of local variables in that code. The first argument sets how many lines are displayed. \ The next three arguments set the length and layout of those lines. 'as-comment' if #t causes each \ line to be preceded by a semicolon." #define Q_stacktrace s7_make_signature(sc, 6, sc->IS_STRING, sc->IS_INTEGER, sc->IS_INTEGER, sc->IS_INTEGER, sc->IS_INTEGER, sc->IS_BOOLEAN) s7_int max_frames = 30, code_cols = 50, total_cols = 80, notes_start_col = 50; bool as_comment = false; char *str; if (!is_null(args)) { if (s7_is_integer(car(args))) { max_frames = s7_integer(car(args)); if ((max_frames <= 0) || (max_frames > s7_int32_max)) max_frames = 30; args = cdr(args); if (!is_null(args)) { if (s7_is_integer(car(args))) { code_cols = s7_integer(car(args)); if ((code_cols <= 8) || (code_cols > s7_int32_max)) code_cols = 50; args = cdr(args); if (!is_null(args)) { if (s7_is_integer(car(args))) { total_cols = s7_integer(car(args)); if ((total_cols <= code_cols) || (total_cols > s7_int32_max)) total_cols = 80; args = cdr(args); if (!is_null(args)) { if (s7_is_integer(car(args))) { notes_start_col = s7_integer(car(args)); if ((notes_start_col <= 0) || (notes_start_col > s7_int32_max)) notes_start_col = 50; args = cdr(args); if (!is_null(args)) { if (s7_is_boolean(car(args))) as_comment = s7_boolean(sc, car(args)); else return(wrong_type_argument(sc, sc->STACKTRACE, 5, car(args), T_BOOLEAN)); } } else return(wrong_type_argument(sc, sc->STACKTRACE, 4, car(args), T_INTEGER)); } } else return(wrong_type_argument(sc, sc->STACKTRACE, 3, car(args), T_INTEGER)); } } else return(wrong_type_argument(sc, sc->STACKTRACE, 2, car(args), T_INTEGER)); } } else method_or_bust(sc, car(args), sc->STACKTRACE, args, T_INTEGER, 1); } str = stacktrace_1(sc, (int)max_frames, (int)code_cols, (int)total_cols, (int)notes_start_col, as_comment); return(make_string_uncopied_with_length(sc, str, safe_strlen(str))); } /* -------- error handlers -------- */ static const char *make_type_name(s7_scheme *sc, const char *name, int article) { int i, slen, len; slen = safe_strlen(name); len = slen + 8; if (len > sc->typnam_len) { if (sc->typnam) free(sc->typnam); sc->typnam = (char *)malloc(len * sizeof(char)); sc->typnam_len = len; } if (article == INDEFINITE_ARTICLE) { i = 1; sc->typnam[0] = 'a'; if ((name[0] == 'a') || (name[0] == 'e') || (name[0] == 'i') || (name[0] == 'o') || (name[0] == 'u')) sc->typnam[i++] = 'n'; sc->typnam[i++] = ' '; } else i = 0; memcpy((void *)(sc->typnam + i), (void *)name, slen); sc->typnam[i + slen] = '\0'; return(sc->typnam); } static const char *type_name_from_type(s7_scheme *sc, int typ, int article) { static const char *frees[2] = {"free cell", "a free cell"}; static const char *nils[2] = {"nil", "nil"}; static const char *uniques[2] = {"untyped", "untyped"}; static const char *booleans[2] = {"boolean", "boolean"}; static const char *strings[2] = {"string", "a string"}; static const char *symbols[2] = {"symbol", "a symbol"}; static const char *syntaxes[2] = {"syntax", "syntactic"}; static const char *pairs[2] = {"pair", "a pair"}; static const char *gotos[2] = {"goto", "a goto (from call-with-exit)"}; static const char *continuations[2] = {"continuation", "a continuation"}; static const char *c_functions[2] = {"c-function", "a c-function"}; static const char *macros[2] = {"macro", "a macro"}; static const char *c_macros[2] = {"c-macro", "a c-macro"}; static const char *bacros[2] = {"bacro", "a bacro"}; static const char *vectors[2] = {"vector", "a vector"}; static const char *int_vectors[2] = {"int-vector", "an int-vector"}; static const char *float_vectors[2] = {"float-vector", "a float-vector"}; static const char *c_pointers[2] = {"C pointer", "a raw C pointer"}; static const char *counters[2] = {"internal counter", "an internal counter"}; static const char *baffles[2] = {"baffle", "a baffle"}; static const char *slots[2] = {"slot", "a slot (variable binding)"}; static const char *characters[2] = {"character", "a character"}; static const char *catches[2] = {"catch", "a catch"}; static const char *dynamic_winds[2] = {"dynamic-wind", "a dynamic-wind"}; static const char *hash_tables[2] = {"hash-table", "a hash-table"}; static const char *iterators[2] = {"iterator", "an iterator"}; static const char *environments[2] = {"environment", "an environment"}; static const char *integers[2] = {"integer", "an integer"}; static const char *big_integers[2] = {"big integer", "a big integer"}; static const char *ratios[2] = {"ratio", "a ratio"}; static const char *big_ratios[2] = {"big ratio", "a big ratio"}; static const char *reals[2] = {"real", "a real"}; static const char *big_reals[2] = {"big real", "a big real"}; static const char *complexes[2] = {"complex number", "a complex number"}; static const char *big_complexes[2] = {"big complex number", "a big complex number"}; static const char *functions[2] = {"function", "a function"}; static const char *function_stars[2] = {"function*", "a function*"}; static const char *rngs[2] = {"random-state", "a random-state"}; switch (typ) { case T_FREE: return(frees[article]); case T_NIL: return(nils[article]); case T_UNIQUE: return(uniques[article]); case T_UNSPECIFIED: return(uniques[article]); case T_BOOLEAN: return(booleans[article]); case T_STRING: return(strings[article]); case T_SYMBOL: return(symbols[article]); case T_SYNTAX: return(syntaxes[article]); case T_PAIR: return(pairs[article]); case T_GOTO: return(gotos[article]); case T_CONTINUATION: return(continuations[article]); case T_C_OPT_ARGS_FUNCTION: case T_C_RST_ARGS_FUNCTION: case T_C_ANY_ARGS_FUNCTION: case T_C_FUNCTION_STAR: case T_C_FUNCTION: return(c_functions[article]); case T_CLOSURE: return(functions[article]); case T_CLOSURE_STAR: return(function_stars[article]); case T_C_MACRO: return(c_macros[article]); case T_C_POINTER: return(c_pointers[article]); case T_CHARACTER: return(characters[article]); case T_VECTOR: return(vectors[article]); case T_INT_VECTOR: return(int_vectors[article]); case T_FLOAT_VECTOR: return(float_vectors[article]); case T_MACRO_STAR: case T_MACRO: return(macros[article]); case T_BACRO_STAR: case T_BACRO: return(bacros[article]); case T_CATCH: return(catches[article]); /* are these 2 possible? */ case T_DYNAMIC_WIND: return(dynamic_winds[article]); case T_HASH_TABLE: return(hash_tables[article]); case T_ITERATOR: return(iterators[article]); case T_LET: return(environments[article]); case T_COUNTER: return(counters[article]); case T_BAFFLE: return(baffles[article]); case T_RANDOM_STATE: return(rngs[article]); case T_SLOT: return(slots[article]); case T_INTEGER: return(integers[article]); case T_RATIO: return(ratios[article]); case T_REAL: return(reals[article]); case T_COMPLEX: return(complexes[article]); case T_BIG_INTEGER: return(big_integers[article]); case T_BIG_RATIO: return(big_ratios[article]); case T_BIG_REAL: return(big_reals[article]); case T_BIG_COMPLEX: return(big_complexes[article]); } return(NULL); } static const char *type_name(s7_scheme *sc, s7_pointer arg, int article) { switch (unchecked_type(arg)) { case T_C_OBJECT: return(make_type_name(sc, object_types[c_object_type(arg)]->name, article)); case T_INPUT_PORT: return(make_type_name(sc, (is_file_port(arg)) ? "input file port" : ((is_string_port(arg)) ? "input string port" : "input port"), article)); case T_OUTPUT_PORT: return(make_type_name(sc, (is_file_port(arg)) ? "output file port" : ((is_string_port(arg)) ? "output string port" : "output port"), article)); case T_LET: if (has_methods(arg)) { s7_pointer class_name; class_name = find_method(sc, arg, sc->CLASS_NAME); if (is_symbol(class_name)) return(make_type_name(sc, symbol_name(class_name), article)); } default: { const char *str; str = type_name_from_type(sc, unchecked_type(arg), article); if (str) return(str); } } return("messed up object"); } static s7_pointer prepackaged_type_name(s7_scheme *sc, s7_pointer x) { s7_pointer p; if (has_methods(x)) { p = find_method(sc, find_let(sc, x), sc->CLASS_NAME); if (is_symbol(p)) return(symbol_name_cell(p)); } p = prepackaged_type_names[type(x)]; if (is_string(p)) return(p); switch (type(x)) { case T_C_OBJECT: return(object_types[c_object_type(x)]->scheme_name); case T_INPUT_PORT: return((is_file_port(x)) ? AN_INPUT_FILE_PORT : ((is_string_port(x)) ? AN_INPUT_STRING_PORT : AN_INPUT_PORT)); case T_OUTPUT_PORT: return((is_file_port(x)) ? AN_OUTPUT_FILE_PORT : ((is_string_port(x)) ? AN_OUTPUT_STRING_PORT : AN_OUTPUT_PORT)); } return(make_string_wrapper(sc, "unknown type!")); } static s7_pointer type_name_string(s7_scheme *sc, s7_pointer arg) { if (type(arg) < NUM_TYPES) { s7_pointer p; p = prepackaged_type_names[type(arg)]; /* these use INDEFINITE_ARTICLE */ if (is_string(p)) return(p); } return(make_string_wrapper(sc, type_name(sc, arg, INDEFINITE_ARTICLE))); } static s7_pointer wrong_type_arg_error_prepackaged(s7_scheme *sc, s7_pointer caller, s7_pointer arg_n, s7_pointer arg, s7_pointer typnam, s7_pointer descr) { s7_pointer p; p = cdr(sc->wrong_type_arg_info); /* info list is '(format_string caller arg_n arg type_name descr) */ car(p) = caller; p = cdr(p); car(p) = arg_n; p = cdr(p); car(p) = arg; p = cdr(p); car(p) = (typnam == sc->GC_NIL) ? prepackaged_type_name(sc, arg) : typnam; p = cdr(p); car(p) = descr; return(s7_error(sc, sc->WRONG_TYPE_ARG, sc->wrong_type_arg_info)); } static s7_pointer simple_wrong_type_arg_error_prepackaged(s7_scheme *sc, s7_pointer caller, s7_pointer arg, s7_pointer typnam, s7_pointer descr) { set_wlist_4(sc, cdr(sc->simple_wrong_type_arg_info), caller, arg, (typnam == sc->GC_NIL) ? prepackaged_type_name(sc, arg) : typnam, descr); return(s7_error(sc, sc->WRONG_TYPE_ARG, sc->simple_wrong_type_arg_info)); } s7_pointer s7_wrong_type_arg_error(s7_scheme *sc, const char *caller, int arg_n, s7_pointer arg, const char *descr) { /* info list is '(format_string caller arg_n arg type_name descr) */ if (arg_n < 0) arg_n = 0; if (arg_n > 0) return(wrong_type_arg_error_prepackaged(sc, make_string_wrapper(sc, caller), make_integer(sc, arg_n), arg, type_name_string(sc, arg), make_string_wrapper(sc, descr))); return(simple_wrong_type_arg_error_prepackaged(sc, make_string_wrapper(sc, caller), arg, type_name_string(sc, arg), make_string_wrapper(sc, descr))); } static s7_pointer out_of_range_error_prepackaged(s7_scheme *sc, s7_pointer caller, s7_pointer arg_n, s7_pointer arg, s7_pointer descr) { /* info list is '(format_string caller arg_n arg descr) */ set_wlist_4(sc, cdr(sc->out_of_range_info), caller, arg_n, arg, descr); return(s7_error(sc, sc->OUT_OF_RANGE, sc->out_of_range_info)); } static s7_pointer simple_out_of_range_error_prepackaged(s7_scheme *sc, s7_pointer caller, s7_pointer arg, s7_pointer descr) { set_wlist_3(sc, cdr(sc->simple_out_of_range_info), caller, arg, descr); return(s7_error(sc, sc->OUT_OF_RANGE, sc->simple_out_of_range_info)); } s7_pointer s7_out_of_range_error(s7_scheme *sc, const char *caller, int arg_n, s7_pointer arg, const char *descr) { /* info list is '(format_string caller arg_n arg descr) */ if (arg_n < 0) arg_n = 0; if (arg_n > 0) return(out_of_range_error_prepackaged(sc, make_string_wrapper(sc, caller), make_integer(sc, arg_n), arg, make_string_wrapper(sc, descr))); return(simple_out_of_range_error_prepackaged(sc, make_string_wrapper(sc, caller), arg, make_string_wrapper(sc, descr))); } s7_pointer s7_wrong_number_of_args_error(s7_scheme *sc, const char *caller, s7_pointer args) { return(s7_error(sc, sc->WRONG_NUMBER_OF_ARGS, set_elist_2(sc, make_string_wrapper(sc, caller), args))); /* "caller" includes the format directives */ } static s7_pointer division_by_zero_error(s7_scheme *sc, s7_pointer caller, s7_pointer arg) { return(s7_error(sc, sc->DIVISION_BY_ZERO, set_elist_3(sc, sc->DIVISION_BY_ZERO_ERROR, caller, arg))); } static s7_pointer file_error(s7_scheme *sc, const char *caller, const char *descr, const char *name) { return(s7_error(sc, sc->IO_ERROR, set_elist_4(sc, make_string_wrapper(sc, "~A: ~A ~S"), make_string_wrapper(sc, caller), make_string_wrapper(sc, descr), make_string_wrapper(sc, name)))); } static s7_pointer closure_or_f(s7_scheme *sc, s7_pointer p) { s7_pointer body; if (!is_closure(p)) return(p); body = closure_body(p); if (is_pair(cdr(body))) return(p); if (!is_pair(car(body))) return(sc->F); if (caar(body) == sc->QUOTE) return(sc->F); return(p); } static s7_pointer g_dynamic_wind(s7_scheme *sc, s7_pointer args) { #define H_dynamic_wind "(dynamic-wind init body finish) calls init, then body, then finish, \ each a function of no arguments, guaranteeing that finish is called even if body is exited" #define Q_dynamic_wind s7_make_circular_signature(sc, 1, 2, sc->VALUES, sc->IS_PROCEDURE) s7_pointer p; if (!is_thunk(sc, car(args))) method_or_bust_with_type(sc, car(args), sc->DYNAMIC_WIND, args, A_THUNK, 1); if (!is_thunk(sc, cadr(args))) method_or_bust_with_type(sc, cadr(args), sc->DYNAMIC_WIND, args, A_THUNK, 2); if (!is_thunk(sc, caddr(args))) method_or_bust_with_type(sc, caddr(args), sc->DYNAMIC_WIND, args, A_THUNK, 3); /* this won't work: (let ((final (lambda (a b c) (list a b c)))) (dynamic-wind (lambda () #f) (lambda () (set! final (lambda () (display "in final")))) final)) * but why not? 'final' is a thunk by the time it is evaluated. * catch (the error handler) is similar. * * It can't work here because we set up the dynamic_wind_out slot below and * even if the thunk check was removed, we'd still be trying to apply the original function. */ new_cell(sc, p, T_DYNAMIC_WIND); /* don't mark car/cdr, don't copy */ dynamic_wind_in(p) = closure_or_f(sc, car(args)); dynamic_wind_body(p) = cadr(args); dynamic_wind_out(p) = closure_or_f(sc, caddr(args)); /* since we don't care about the in and out results, and they are thunks, if the body is not a pair, * or is a quoted thing, we just ignore that function. */ push_stack(sc, OP_DYNAMIC_WIND, sc->NIL, p); /* args will be the saved result, code = s7_dynwind_t obj */ if (dynamic_wind_in(p) != sc->F) { dynamic_wind_state(p) = DWIND_INIT; push_stack(sc, OP_APPLY, sc->NIL, dynamic_wind_in(p)); } else { dynamic_wind_state(p) = DWIND_BODY; push_stack(sc, OP_APPLY, sc->NIL, dynamic_wind_body(p)); } return(sc->F); } s7_pointer s7_dynamic_wind(s7_scheme *sc, s7_pointer init, s7_pointer body, s7_pointer finish) { /* this is essentially s7_call with a dynamic-wind wrapper around "body" */ s7_pointer p; bool old_longjmp; jmp_buf old_goto_start; sc->temp1 = ((init == sc->F) ? finish : init); sc->temp2 = body; old_longjmp = sc->longjmp_ok; memcpy((void *)old_goto_start, (void *)(sc->goto_start), sizeof(jmp_buf)); sc->longjmp_ok = true; if (setjmp(sc->goto_start) != 0) /* returning from s7_error catch handler */ { sc->longjmp_ok = old_longjmp; memcpy((void *)(sc->goto_start), (void *)old_goto_start, sizeof(jmp_buf)); if ((sc->op == OP_ERROR_QUIT) && (sc->longjmp_ok)) longjmp(sc->goto_start, 1); eval(sc, sc->op); return(sc->value); } push_stack(sc, OP_EVAL_DONE, sc->args, sc->code); sc->args = sc->NIL; new_cell(sc, p, T_DYNAMIC_WIND); dynamic_wind_in(p) = init; dynamic_wind_body(p) = body; dynamic_wind_out(p) = finish; push_stack(sc, OP_DYNAMIC_WIND, sc->NIL, p); if (init != sc->F) { dynamic_wind_state(p) = DWIND_INIT; sc->code = init; } else { dynamic_wind_state(p) = DWIND_BODY; sc->code = body; } eval(sc, OP_APPLY); sc->longjmp_ok = old_longjmp; memcpy((void *)(sc->goto_start), (void *)old_goto_start, sizeof(jmp_buf)); return(sc->value); } static s7_pointer g_catch(s7_scheme *sc, s7_pointer args) { #define H_catch "(catch tag thunk handler) evaluates thunk; if an error occurs that matches the tag (#t matches all), the handler is called" #define Q_catch s7_make_circular_signature(sc, 2, 3, sc->VALUES, sc->T, sc->IS_PROCEDURE) s7_pointer p, proc, err; /* Guile sets up the catch before looking for arg errors: * (catch #t log (lambda args "hiho")) -> "hiho" * which is consistent in that (catch #t (lambda () (log))...) should probably be the same as (catch #t log ...) */ proc = cadr(args); err = caddr(args); /* if (is_let(err)) check_method(sc, err, sc->CATCH, args); */ /* causes exit from s7! */ new_cell(sc, p, T_CATCH); catch_tag(p) = car(args); catch_goto_loc(p) = s7_stack_top(sc); catch_op_loc(p) = (int)(sc->op_stack_now - sc->op_stack); catch_handler(p) = err; if (is_any_macro(err)) push_stack(sc, OP_CATCH_2, args, p); else push_stack(sc, OP_CATCH, args, p); /* args ignored but maybe safer for GC? */ /* not sure about these error checks -- they can be omitted */ if (!is_thunk(sc, proc)) return(wrong_type_argument_with_type(sc, sc->CATCH, 2, proc, A_THUNK)); if (!is_applicable(err)) return(wrong_type_argument_with_type(sc, sc->CATCH, 3, err, SOMETHING_APPLICABLE)); /* should we check here for (aritable? err 2)? -- right now: * (catch #t (lambda () 1) "hiho") -> 1 * currently this is checked only if the error handler is called */ if (is_closure(proc)) /* not also lambda* here because we need to handle the arg defaults */ { sc->code = closure_body(proc); new_frame(sc, closure_let(proc), sc->envir); push_stack(sc, OP_BEGIN_UNCHECKED, sc->args, sc->code); } else push_stack(sc, OP_APPLY, sc->NIL, proc); return(sc->F); } /* s7_catch(sc, tag, body, error): return(g_catch(sc, list(sc, 3, tag, body, error))) */ /* error reporting info -- save filename and line number */ #define remember_location(Line, File) (((File) << 20) | (Line)) #define remembered_line_number(Line) ((Line) & 0xfffff) #define remembered_file_name(Line) ((((Line) >> 20) <= sc->file_names_top) ? sc->file_names[Line >> 20] : sc->F) /* this gives room for 4000 files each of 1000000 lines */ static int remember_file_name(s7_scheme *sc, const char *file) { int i; for (i = 0; i <= sc->file_names_top; i++) if (safe_strcmp(file, string_value(sc->file_names[i]))) return(i); sc->file_names_top++; if (sc->file_names_top >= sc->file_names_size) { int old_size = 0; if (sc->file_names_size == 0) { sc->file_names_size = INITIAL_FILE_NAMES_SIZE; sc->file_names = (s7_pointer *)calloc(sc->file_names_size, sizeof(s7_pointer)); } else { old_size = sc->file_names_size; sc->file_names_size *= 2; sc->file_names = (s7_pointer *)realloc(sc->file_names, sc->file_names_size * sizeof(s7_pointer)); } for (i = old_size; i < sc->file_names_size; i++) sc->file_names[i] = sc->F; } sc->file_names[sc->file_names_top] = s7_make_permanent_string(file); return(sc->file_names_top); } static s7_pointer init_owlet(s7_scheme *sc) { s7_pointer e; e = new_frame_in_env(sc, sc->rootlet); sc->temp3 = e; sc->error_type = make_slot_1(sc, e, make_symbol(sc, "error-type"), sc->F); /* the error type or tag ('division-by-zero) */ sc->error_data = make_slot_1(sc, e, make_symbol(sc, "error-data"), sc->F); /* the message or information passed by the error function */ sc->error_code = make_slot_1(sc, e, make_symbol(sc, "error-code"), sc->F); /* the code that s7 thinks triggered the error */ sc->error_line = make_slot_1(sc, e, make_symbol(sc, "error-line"), sc->F); /* the line number of that code */ sc->error_file = make_slot_1(sc, e, make_symbol(sc, "error-file"), sc->F); /* the file name of that code */ return(e); } static s7_pointer g_owlet(s7_scheme *sc, s7_pointer args) { #define H_owlet "(owlet) returns the environment at the point of the last error. \ It has the additional local variables: error-type, error-data, error-code, error-line, and error-file." #define Q_owlet s7_make_signature(sc, 1, sc->IS_LET) /* if owlet is not copied, (define e (owlet)), e changes as owlet does! */ s7_pointer e, x; int gc_loc; e = let_copy(sc, sc->owlet); gc_loc = s7_gc_protect(sc, e); /* also make sure the pairs are copied: should be error-data and error-code */ for (x = let_slots(e); is_slot(x); x = next_slot(x)) if (is_pair(slot_value(x))) slot_set_value(x, protected_list_copy(sc, slot_value(x))); s7_gc_unprotect_at(sc, gc_loc); return(e); } static s7_pointer c_owlet(s7_scheme *sc) {return(g_owlet(sc, sc->NIL));} PF_0(owlet, c_owlet) static s7_pointer active_catches(s7_scheme *sc) { int i; s7_pointer x, lst; lst = sc->NIL; for (i = s7_stack_top(sc) - 1; i >= 3; i -= 4) switch (stack_op(sc->stack, i)) { case OP_CATCH_ALL: lst = cons(sc, sc->T, lst); break; case OP_CATCH_2: case OP_CATCH_1: case OP_CATCH: x = stack_code(sc->stack, i); lst = cons(sc, catch_tag(x), lst); break; } return(reverse_in_place_unchecked(sc, sc->NIL, lst)); } static s7_pointer active_exits(s7_scheme *sc) { /* (call-with-exit (lambda (exiter) (*s7* 'exits))) */ int i; s7_pointer lst; lst = sc->NIL; for (i = s7_stack_top(sc) - 1; i >= 3; i -= 4) if (stack_op(sc->stack, i) == OP_DEACTIVATE_GOTO) { s7_pointer func, jump; func = stack_code(sc->stack, i); /* presumably this has the goto name */ jump = stack_args(sc->stack, i); /* call this to jump */ if (is_any_closure(func)) lst = cons(sc, cons(sc, car(closure_args(func)), jump), lst); else { if ((is_pair(func)) && (car(func) == sc->CALL_WITH_EXIT)) lst = cons(sc, cons(sc, car(cadr(cadr(func))), jump), lst); /* (call-with-exit (lambda (three) ...)) */ else lst = cons(sc, cons(sc, sc->UNSPECIFIED, jump), lst); } sc->w = lst; } return(reverse_in_place_unchecked(sc, sc->NIL, lst)); } static s7_pointer stack_entries(s7_scheme *sc) { int i; s7_pointer lst; lst = sc->NIL; for (i = s7_stack_top(sc) - 1; i >= 3; i -= 4) { s7_pointer func, args, e; opcode_t op; func = stack_code(sc->stack, i); args = stack_args(sc->stack, i); e = stack_let(sc->stack, i); op = stack_op(sc->stack, i); if ((s7_is_valid(sc, func)) && (s7_is_valid(sc, args)) && (s7_is_valid(sc, e)) && (op < OP_MAX_DEFINED)) { lst = cons(sc, list_4(sc, func, args, e, make_integer(sc, op)), lst); sc->w = lst; } } return(reverse_in_place_unchecked(sc, sc->NIL, lst)); } /* catch handlers */ typedef bool (*catch_function)(s7_scheme *sc, int i, s7_pointer type, s7_pointer info, bool *reset_hook); static catch_function catchers[OP_MAX_DEFINED + 1]; static bool catch_all_function(s7_scheme *sc, int i, s7_pointer type, s7_pointer info, bool *reset_hook) { s7_pointer catcher; catcher = stack_let(sc->stack, i); sc->op_stack_now = (s7_pointer *)(sc->op_stack + catch_all_op_loc(catcher)); sc->stack_end = (s7_pointer *)(sc->stack_start + catch_all_goto_loc(catcher)); pop_stack(sc); sc->value = catch_all_result(catcher); return(true); } static bool catch_2_function(s7_scheme *sc, int i, s7_pointer type, s7_pointer info, bool *reset_hook) { /* this is the macro-error-handler case from g_catch * (let () (define-macro (m . args) (apply (car args) (cadr args))) (catch #t (lambda () (error abs -1)) m)) */ s7_pointer x; x = stack_code(sc->stack, i); if ((catch_tag(x) == sc->T) || (catch_tag(x) == type) || (type == sc->T)) { int loc; loc = catch_goto_loc(x); sc->op_stack_now = (s7_pointer *)(sc->op_stack + catch_op_loc(x)); sc->stack_end = (s7_pointer *)(sc->stack_start + loc); sc->code = catch_handler(x); car(sc->T2_1) = type; car(sc->T2_2) = info; sc->args = sc->T2_1; /* copied in op_apply? */ sc->op = OP_APPLY; return(true); } return(false); } static bool catch_1_function(s7_scheme *sc, int i, s7_pointer type, s7_pointer info, bool *reset_hook) { s7_pointer x; x = stack_code(sc->stack, i); if ((catch_tag(x) == sc->T) || (catch_tag(x) == type) || (type == sc->T)) { int loc; opcode_t op; s7_pointer catcher, error_func, body; op = stack_op(sc->stack, i); sc->temp4 = stack_let(sc->stack, i); /* GC protect this, since we're moving the stack top below */ catcher = x; loc = catch_goto_loc(catcher); sc->op_stack_now = (s7_pointer *)(sc->op_stack + catch_op_loc(catcher)); sc->stack_end = (s7_pointer *)(sc->stack_start + loc); error_func = catch_handler(catcher); /* very often the error handler just returns either a constant ('error or #f), or * the args passed to it, so there's no need to laboriously make a closure, * and apply it -- just set sc->value to the closure body (or the args) and * return. * * so first examine closure_body(error_func) * if it is a constant, or quoted symbol, return that, * if it is the args symbol, return (list type info) */ /* if OP_CATCH_1, we deferred making the error handler until it is actually needed */ if (op == OP_CATCH_1) body = cdr(error_func); else { if (is_closure(error_func)) body = closure_body(error_func); else body = NULL; } if ((body) && (is_null(cdr(body)))) { s7_pointer y = NULL; body = car(body); if (is_pair(body)) { if (car(body) == sc->QUOTE) y = cadr(body); else { if ((car(body) == sc->CAR) && (is_pair(error_func)) && (cadr(body) == car(error_func))) y = type; } } else { if (is_symbol(body)) { if ((is_pair(error_func)) && (body == car(error_func))) y = list_2(sc, type, info); } else y = body; } if (y) { pop_stack(sc); sc->value = y; sc->temp4 = sc->NIL; return(true); } } if (op == OP_CATCH_1) { s7_pointer y = NULL; make_closure_without_capture(sc, y, car(error_func), cdr(error_func), sc->temp4); sc->code = y; } else sc->code = error_func; sc->temp4 = sc->NIL; /* if user (i.e. yers truly!) copies/pastes the preceding lambda () into the * error handler portion of the catch, he gets the inexplicable message: * ;(): too many arguments: (a1 ()) * when this apply tries to call the handler. So, we need a special case * error check here! */ if (!s7_is_aritable(sc, sc->code, 2)) { s7_wrong_number_of_args_error(sc, "catch error handler should accept 2 args: ~S", sc->code); return(false); } /* since make_closure_with_let sets needs_copied_args and we're going to OP_APPLY, * we don't need a new list here. */ car(sc->T2_1) = type; car(sc->T2_2) = info; sc->args = sc->T2_1; sc->op = OP_APPLY; /* explicit eval needed if s7_call called into scheme where a caught error occurred (ex6 in exs7.c) * but putting it here (via eval(sc, OP_APPLY)) means the C stack is not cleared correctly in non-s7-call cases, * so defer it until s7_call */ return(true); } return(false); } static bool catch_dw_function(s7_scheme *sc, int i, s7_pointer type, s7_pointer info, bool *reset_hook) { s7_pointer x; x = stack_code(sc->stack, i); if (dynamic_wind_state(x) == DWIND_BODY) { dynamic_wind_state(x) = DWIND_FINISH; /* make sure an uncaught error in the exit thunk doesn't cause us to loop */ if (dynamic_wind_out(x) != sc->F) { push_stack(sc, OP_EVAL_DONE, sc->args, sc->code); sc->code = dynamic_wind_out(x); sc->args = sc->NIL; eval(sc, OP_APPLY); /* I guess this means no call/cc out of the exit thunk in an error-catching context */ } } return(false); } static bool catch_out_function(s7_scheme *sc, int i, s7_pointer type, s7_pointer info, bool *reset_hook) { s7_pointer x; x = stack_code(sc->stack, i); /* "code" = port that we opened */ s7_close_output_port(sc, x); x = stack_args(sc->stack, i); /* "args" = port that we shadowed, if not #f */ if (x != sc->F) sc->output_port = x; return(false); } static bool catch_in_function(s7_scheme *sc, int i, s7_pointer type, s7_pointer info, bool *reset_hook) { s7_close_input_port(sc, stack_code(sc->stack, i)); /* "code" = port that we opened */ sc->input_port = stack_args(sc->stack, i); /* "args" = port that we shadowed */ return(false); } static bool catch_read_function(s7_scheme *sc, int i, s7_pointer type, s7_pointer info, bool *reset_hook) { pop_input_port(sc); return(false); } static bool catch_eval_function(s7_scheme *sc, int i, s7_pointer type, s7_pointer info, bool *reset_hook) { s7_close_input_port(sc, sc->input_port); pop_input_port(sc); return(false); } static bool catch_barrier_function(s7_scheme *sc, int i, s7_pointer type, s7_pointer info, bool *reset_hook) { if (is_input_port(stack_args(sc->stack, i))) /* (eval-string "'(1 .)") */ { if (sc->input_port == stack_args(sc->stack, i)) pop_input_port(sc); s7_close_input_port(sc, stack_args(sc->stack, i)); } return(false); } static bool catch_hook_function(s7_scheme *sc, int i, s7_pointer type, s7_pointer info, bool *reset_hook) { sc->error_hook = stack_code(sc->stack, i); /* apparently there was an error during *error-hook* evaluation, but Rick wants the hook re-established anyway */ (*reset_hook) = true; /* avoid infinite loop -- don't try to (re-)evaluate (buggy) *error-hook*! */ return(false); } static bool catch_goto_function(s7_scheme *sc, int i, s7_pointer type, s7_pointer info, bool *reset_hook) { call_exit_active(stack_args(sc->stack, i)) = false; return(false); } static void init_catchers(void) { int i; for (i = 0; i <= OP_MAX_DEFINED; i++) catchers[i] = NULL; catchers[OP_CATCH_ALL] = catch_all_function; catchers[OP_CATCH_2] = catch_2_function; catchers[OP_CATCH_1] = catch_1_function; catchers[OP_CATCH] = catch_1_function; catchers[OP_DYNAMIC_WIND] = catch_dw_function; catchers[OP_GET_OUTPUT_STRING_1] = catch_out_function; catchers[OP_UNWIND_OUTPUT] = catch_out_function; catchers[OP_UNWIND_INPUT] = catch_in_function; catchers[OP_READ_DONE] = catch_read_function; /* perhaps an error during (read) */ catchers[OP_EVAL_STRING_1] = catch_eval_function; /* perhaps an error happened before we could push the OP_EVAL_STRING_2 */ catchers[OP_EVAL_STRING_2] = catch_eval_function; catchers[OP_BARRIER] = catch_barrier_function; catchers[OP_DEACTIVATE_GOTO] = catch_goto_function; catchers[OP_ERROR_HOOK_QUIT] = catch_hook_function; } static s7_pointer g_throw(s7_scheme *sc, s7_pointer args) { #define H_throw "(throw tag . info) is like (error ...) but it does not affect the owlet. \ It looks for an existing catch with a matching tag, and jumps to it if found. Otherwise it raises an error." #define Q_throw pcl_t bool ignored_flag = false; int i; s7_pointer type, info; type = car(args); info = cdr(args); /* look for a catcher */ for (i = s7_stack_top(sc) - 1; i >= 3; i -= 4) { catch_function catcher; catcher = catchers[stack_op(sc->stack, i)]; if ((catcher) && (catcher(sc, i, type, info, &ignored_flag))) { if (sc->longjmp_ok) longjmp(sc->goto_start, 1); return(sc->value); } } if (is_let(car(args))) check_method(sc, car(args), sc->THROW, args); return(s7_error(sc, make_symbol(sc, "uncaught-throw"), args)); } static void s7_warn(s7_scheme *sc, int len, const char *ctrl, ...) { va_list ap; char *str; str = (char *)malloc(len * sizeof(char)); va_start(ap, ctrl); len = vsnprintf(str, len, ctrl, ap); va_end(ap); if (port_is_closed(sc->error_port)) sc->error_port = sc->standard_error; s7_display(sc, make_string_uncopied_with_length(sc, str, len), sc->error_port); } s7_pointer s7_error(s7_scheme *sc, s7_pointer type, s7_pointer info) { static int last_line = -1; bool reset_error_hook = false; s7_pointer cur_code; /* type is a symbol normally, and info is compatible with format: (apply format #f info) -- * car(info) is the control string, cdr(info) its args * type/range errors have cadr(info)=caller, caddr(info)=offending arg number * null info can mean symbol table is locked so make-symbol uses s7_error to get out * * set up (owlet), look for a catch that matches 'type', if found * call its error-handler, else if *error-hook* is bound, call it, * else send out the error info ourselves. */ sc->no_values = 0; sc->format_depth = -1; sc->gc_off = false; /* this is in case we were triggered from the sort function -- clumsy! */ s7_xf_clear(sc); slot_set_value(sc->error_type, type); slot_set_value(sc->error_data, info); #if DEBUGGING if (!is_let(sc->owlet)) fprintf(stderr, "owlet clobbered!\n"); #endif if ((unchecked_type(sc->envir) != T_LET) && (sc->envir != sc->NIL)) sc->envir = sc->NIL; /* in reader, the envir frame is mostly ignored so it can be (and usually is) garbage */ set_outlet(sc->owlet, sc->envir); cur_code = sc->cur_code; slot_set_value(sc->error_code, cur_code); if (has_line_number(cur_code)) { int line; line = pair_line(cur_code); if (line != last_line) { last_line = line; if (line > 0) { slot_set_value(sc->error_line, make_integer(sc, remembered_line_number(line))); slot_set_value(sc->error_file, remembered_file_name(line)); } else { slot_set_value(sc->error_line, sc->F); slot_set_value(sc->error_file, sc->F); } } } else { slot_set_value(sc->error_line, sc->F); slot_set_value(sc->error_file, sc->F); } { /* look for a catcher */ int i; /* top is 1 past actual top, top - 1 is op, if op = OP_CATCH, top - 4 is the cell containing the catch struct */ for (i = s7_stack_top(sc) - 1; i >= 3; i -= 4) { catch_function catcher; catcher = catchers[stack_op(sc->stack, i)]; if ((catcher) && (catcher(sc, i, type, info, &reset_error_hook))) { if (sc->longjmp_ok) longjmp(sc->goto_start, 1); return(type); /* throw returns sc->value here? */ } } } /* error not caught */ /* (set! *error-hook* (list (lambda (hook) (apply format #t (hook 'args))))) */ if ((!reset_error_hook) && (is_procedure(sc->error_hook)) && (is_pair(s7_hook_functions(sc, sc->error_hook)))) { s7_pointer error_hook_func; /* (set! (hook-functions *error-hook*) (list (lambda (h) (format *stderr* "got error ~A~%" (h 'args))))) */ error_hook_func = sc->error_hook; sc->error_hook = sc->F; /* if the *error-hook* functions trigger an error, we had better not have *error-hook* still set! */ push_stack(sc, OP_ERROR_HOOK_QUIT, sc->NIL, error_hook_func); /* restore *error-hook* upon successful (or any!) evaluation */ sc->args = list_2(sc, type, info); sc->code = error_hook_func; /* if we drop into the longjmp below, the hook functions are not called! * OP_ERROR_HOOK_QUIT performs the longjmp, so it should be safe to go to eval. */ eval(sc, OP_APPLY); } else { if (port_is_closed(sc->error_port)) sc->error_port = sc->standard_error; /* if info is not a list, send object->string to current error port, * else assume car(info) is a format control string, and cdr(info) are its args * * if at all possible, get some indication of where we are! */ if ((!s7_is_list(sc, info)) || (!is_string(car(info)))) format_to_port(sc, sc->error_port, "\n;~S ~S", set_plist_2(sc, type, info), NULL, false, 7); else { const char *carstr; int i, len; bool use_format = false; /* it's possible that the error string is just a string -- not intended for format */ carstr = string_value(car(info)); len = string_length(car(info)); for (i = 0; i < len; i++) if (carstr[i] == '~') { use_format = true; break; } if (use_format) { char *errstr; int str_len; len += 8; tmpbuf_malloc(errstr, len); str_len = snprintf(errstr, len, "\n;%s", string_value(car(info))); format_to_port(sc, sc->error_port, errstr, cdr(info), NULL, false, str_len); tmpbuf_free(errstr, len); } else format_to_port(sc, sc->error_port, "\n;~S ~S", set_plist_2(sc, type, info), NULL, false, 7); } /* now display location at end */ if ((is_input_port(sc->input_port)) && (port_file(sc->input_port) != stdin) && (!port_is_closed(sc->input_port))) { const char *filename = NULL; int line; filename = port_filename(sc->input_port); line = port_line_number(sc->input_port); if (filename) format_to_port(sc, sc->error_port, "\n; ~A[~D]", set_plist_2(sc, make_string_wrapper(sc, filename), make_integer(sc, line)), NULL, false, 10); else { if ((line > 0) && (slot_value(sc->error_line) != sc->F)) format_to_port(sc, sc->error_port, "\n; line ~D", set_plist_1(sc, make_integer(sc, line)), NULL, false, 11); else { if (is_pair(sc->input_port_stack)) { s7_pointer p; p = car(sc->input_port_stack); if ((is_input_port(p)) && (port_file(p) != stdin) && (!port_is_closed(p))) { filename = port_filename(p); line = port_line_number(p); if (filename) format_to_port(sc, sc->error_port, "\n; ~A[~D]", set_plist_2(sc, make_string_wrapper(sc, filename), make_integer(sc, line)), NULL, false, 10); } } } } } else { const char *call_name; call_name = sc->s7_call_name; /* sc->s7_call_name = NULL; */ if (call_name) { sc->s7_call_name = NULL; if ((sc->s7_call_file != NULL) && (sc->s7_call_line >= 0)) { format_to_port(sc, sc->error_port, "\n; ~A ~A[~D]", set_plist_3(sc, make_string_wrapper(sc, call_name), make_string_wrapper(sc, sc->s7_call_file), make_integer(sc, sc->s7_call_line)), NULL, false, 13); } } } s7_newline(sc, sc->error_port); if (is_string(slot_value(sc->error_file))) { format_to_port(sc, sc->error_port, "; ~S, line ~D", set_plist_2(sc, slot_value(sc->error_file), slot_value(sc->error_line)), NULL, false, 16); s7_newline(sc, sc->error_port); } /* look for __func__ in the error environment etc */ if (sc->error_port != sc->F) { char *errstr; errstr = stacktrace_1(sc, s7_integer(car(sc->stacktrace_defaults)), s7_integer(cadr(sc->stacktrace_defaults)), s7_integer(caddr(sc->stacktrace_defaults)), s7_integer(cadddr(sc->stacktrace_defaults)), s7_boolean(sc, s7_list_ref(sc, sc->stacktrace_defaults, 4))); if (errstr) { port_write_string(sc->error_port)(sc, ";\n", 2, sc->error_port); port_write_string(sc->error_port)(sc, errstr, strlen(errstr), sc->error_port); free(errstr); port_write_character(sc->error_port)(sc, '\n', sc->error_port); } } else { if (is_pair(slot_value(sc->error_code))) { format_to_port(sc, sc->error_port, "; ~S", set_plist_1(sc, slot_value(sc->error_code)), NULL, false, 7); s7_newline(sc, sc->error_port); } } /* if (is_continuation(type)) * go into repl here with access to continuation? Or expect *error-handler* to deal with it? */ sc->value = type; stack_reset(sc); sc->op = OP_ERROR_QUIT; } if (sc->longjmp_ok) longjmp(sc->goto_start, 1); return(type); } static s7_pointer apply_error(s7_scheme *sc, s7_pointer obj, s7_pointer args) { /* the operator type is needed here else the error message is confusing: * (apply '+ (list 1 2))) -> ;attempt to apply + to (1 2)? */ static s7_pointer errstr = NULL; if (is_null(obj)) return(s7_error(sc, sc->SYNTAX_ERROR, set_elist_2(sc, make_string_wrapper_with_length(sc, "attempt to apply nil to ~S?", 27), args))); if (!errstr) errstr = s7_make_permanent_string("attempt to apply ~A ~S to ~S?"); return(s7_error(sc, sc->SYNTAX_ERROR, set_elist_4(sc, errstr, type_name_string(sc, obj), obj, args))); } static s7_pointer read_error_1(s7_scheme *sc, const char *errmsg, bool string_error) { /* reader errors happen before the evaluator gets involved, so forms such as: * (catch #t (lambda () (car '( . ))) (lambda arg 'error)) * do not catch the error if we simply signal an error when we encounter it. */ char *msg; int len; s7_pointer pt; pt = sc->input_port; if (!string_error) { /* make an heroic effort to find where we slid off the tracks */ if (is_string_port(sc->input_port)) { #define QUOTE_SIZE 40 unsigned int i, j, start = 0, end, slen; char *recent_input = NULL; /* we can run off the end in cases like (eval-string "(. . ,.)") or (eval-string " (@ . ,.)") */ if (port_position(pt) >= port_data_size(pt)) port_position(pt) = port_data_size(pt) - 1; /* start at current position and look back a few chars */ for (i = port_position(pt), j = 0; (i > 0) && (j < QUOTE_SIZE); i--, j++) if ((port_data(pt)[i] == '\0') || (port_data(pt)[i] == '\n') || (port_data(pt)[i] == '\r')) break; start = i; /* start at current position and look ahead a few chars */ for (i = port_position(pt), j = 0; (i < port_data_size(pt)) && (j < QUOTE_SIZE); i++, j++) if ((port_data(pt)[i] == '\0') || (port_data(pt)[i] == '\n') || (port_data(pt)[i] == '\r')) break; end = i; slen = end - start; /* hopefully this is more or less the current line where the read error happened */ if (slen > 0) { recent_input = (char *)calloc((slen + 9), sizeof(char)); for (i = 0; i < (slen + 8); i++) recent_input[i] = '.'; recent_input[3] = ' '; recent_input[slen + 4] = ' '; for (i = 0; i < slen; i++) recent_input[i + 4] = port_data(pt)[start + i]; } if ((port_line_number(pt) > 0) && (port_filename(pt))) { len = safe_strlen(recent_input) + safe_strlen(errmsg) + port_filename_length(pt) + safe_strlen(sc->current_file) + 64; msg = (char *)malloc(len * sizeof(char)); len = snprintf(msg, len, "%s: %s %s[%u], last top-level form at: %s[%d]", errmsg, (recent_input) ? recent_input : "", port_filename(pt), port_line_number(pt), sc->current_file, sc->current_line); } else { len = safe_strlen(recent_input) + safe_strlen(errmsg) + safe_strlen(sc->current_file) + 64; msg = (char *)malloc(len * sizeof(char)); if ((sc->current_file) && (sc->current_line >= 0)) len = snprintf(msg, len, "%s: %s, last top-level form at %s[%d]", errmsg, (recent_input) ? recent_input : "", sc->current_file, sc->current_line); else len = snprintf(msg, len, "%s: %s", errmsg, (recent_input) ? recent_input : ""); } if (recent_input) free(recent_input); return(s7_error(sc, sc->READ_ERROR, set_elist_1(sc, make_string_uncopied_with_length(sc, msg, len)))); } } if ((port_line_number(pt) > 0) && (port_filename(pt))) { len = safe_strlen(errmsg) + port_filename_length(pt) + safe_strlen(sc->current_file) + 128; msg = (char *)malloc(len * sizeof(char)); if (string_error) len = snprintf(msg, len, "%s %s[%u],\n; possible culprit: \"%s...\"\n; last top-level form at %s[%d]", errmsg, port_filename(pt), port_line_number(pt), sc->strbuf, sc->current_file, sc->current_line); else len = snprintf(msg, len, "%s %s[%u], last top-level form at %s[%d]", errmsg, port_filename(pt), port_line_number(pt), sc->current_file, sc->current_line); return(s7_error(sc, sc->READ_ERROR, set_elist_1(sc, make_string_uncopied_with_length(sc, msg, len)))); } return(s7_error(sc, (string_error) ? sc->STRING_READ_ERROR : sc->READ_ERROR, set_elist_1(sc, make_string_wrapper(sc, (char *)errmsg)))); } static s7_pointer read_error(s7_scheme *sc, const char *errmsg) { return(read_error_1(sc, errmsg, false)); } static s7_pointer string_read_error(s7_scheme *sc, const char *errmsg) { return(read_error_1(sc, errmsg, true)); } static s7_pointer g_error(s7_scheme *sc, s7_pointer args) { #define H_error "(error type ...) signals an error. The 'type' can be used with catch to trap \ particular errors. If the error is not caught, s7 treats the second argument as a format control string, \ and applies it to the rest of the arguments." #define Q_error pcl_t if (is_not_null(args)) { if (is_string(car(args))) /* CL-style error? -- use tag = 'no-catch */ { s7_error(sc, sc->NO_CATCH, args); /* this can have trailing args (implicit format) */ return(sc->UNSPECIFIED); } return(s7_error(sc, car(args), cdr(args))); } return(s7_error(sc, sc->NIL, sc->NIL)); } static char *truncate_string(char *form, int len, use_write_t use_write, int *form_len) { unsigned char *f; f = (unsigned char *)form; if (use_write != USE_DISPLAY) { /* I guess we need to protect the outer double quotes in this case */ int i; for (i = len - 5; i >= (len / 2); i--) if (is_white_space((int)f[i])) { form[i] = '.'; form[i + 1] = '.'; form[i + 2] = '.'; form[i + 3] = '"'; form[i + 4] = '\0'; (*form_len) = i + 4; return(form); } i = len - 5; if (i > 0) { form[i] = '.'; form[i + 1] = '.'; form[i + 2] = '.'; form[i + 3] = '"'; form[i + 4] = '\0'; } else { if (len >= 2) { form[len - 1] = '"'; form[len] = '\0'; } } } else { int i; for (i = len - 4; i >= (len / 2); i--) if (is_white_space((int)f[i])) { form[i] = '.'; form[i + 1] = '.'; form[i + 2] = '.'; form[i + 3] = '\0'; (*form_len) = i + 3; return(form); } i = len - 4; if (i >= 0) { form[i] = '.'; form[i + 1] = '.'; form[i + 2] = '.'; form[i + 3] = '\0'; } else form[len] = '\0'; } return(form); } static char *object_to_truncated_string(s7_scheme *sc, s7_pointer p, int len) { char *s; int s_len; s = s7_object_to_c_string(sc, p); s_len = safe_strlen(s); if (s_len > len) return(truncate_string(s, len, USE_DISPLAY, &s_len)); return(s); } static char *missing_close_paren_syntax_check(s7_scheme *sc, s7_pointer lst) { s7_pointer p, old_hook; int old_hook_loc; char *msg = NULL; /* this can get into an infinite loop if unbound variable hook gets involved so... */ old_hook = s7_hook_functions(sc, sc->unbound_variable_hook); old_hook_loc = s7_gc_protect(sc, old_hook); s7_hook_set_functions(sc, sc->unbound_variable_hook, sc->NIL); for (p = lst; is_pair(p); p = cdr(p)) { if (is_pair(car(p))) { s7_pointer sym; sym = caar(p); if (is_symbol(sym)) { int len; len = s7_list_length(sc, car(p)); if (((sym == make_symbol_with_length(sc, "if", 2)) && (len > 4)) || /* some care is needed -- we can't risk autoloading the very same file we're complaining about! */ ((is_slot(global_slot(sym))) && (s7_is_procedure(slot_value(global_slot(sym)))) && (!s7_is_aritable(sc, slot_value(global_slot(sym)), len))) || ((sym == make_symbol_with_length(sc, "define", 6)) && (is_pair(cdr(p))) && (is_symbol(cadr(p))) && (len > 3))) { int msg_len, form_len; char *form; /* it's very tricky to try to see other errors here, especially because 'case' * can have syntax names in its key lists. Even this may get fooled, but * I'm hoping that more often than not, it will help track down the missing * close paren. */ form = object_to_truncated_string(sc, car(p), 80); form_len = safe_strlen(form); msg_len = form_len + 128; msg = (char *)malloc(msg_len * sizeof(char)); snprintf(msg, msg_len, "; this looks bogus: %s", form); free(form); s7_hook_set_functions(sc, sc->unbound_variable_hook, old_hook); s7_gc_unprotect_at(sc, old_hook_loc); return(msg); } } msg = missing_close_paren_syntax_check(sc, car(p)); if (msg) { s7_hook_set_functions(sc, sc->unbound_variable_hook, old_hook); s7_gc_unprotect_at(sc, old_hook_loc); return(msg); } } } s7_hook_set_functions(sc, sc->unbound_variable_hook, old_hook); s7_gc_unprotect_at(sc, old_hook_loc); return(NULL); } static s7_pointer missing_close_paren_error(s7_scheme *sc) { int len; char *msg, *syntax_msg = NULL; s7_pointer pt; if ((unchecked_type(sc->envir) != T_LET) && (sc->envir != sc->NIL)) sc->envir = sc->NIL; /* check *missing-close-paren-hook* */ if (!is_null(sc->missing_close_paren_hook)) { s7_pointer result; result = s7_call(sc, sc->missing_close_paren_hook, sc->NIL); if (result != sc->UNSPECIFIED) return(g_throw(sc, list_1(sc, result))); } pt = sc->input_port; /* it's hard to give a good idea here of where the missing paren is because we've already * popped off all the stacked info, following ')' until eof. * but the current incoming program code is in sc->args, reversed at its top level, * so it's worth looking for some problem involving too many clauses (if) or arguments, etc. * another gotcha: since we're in the reader, we can't depend on sc->envir! * this can be a hard bug to track down in a large program, so s7 really has to make an effort to help. */ if (is_pair(sc->args)) { s7_pointer lx; lx = s7_reverse(sc, sc->args); syntax_msg = missing_close_paren_syntax_check(sc, lx); /* if syntax_msg is null, we didn't find the problem, so perhaps show it indented? */ } if ((port_line_number(pt) > 0) && (port_filename(pt))) { len = port_filename_length(pt) + safe_strlen(sc->current_file) + safe_strlen(syntax_msg) + 128; msg = (char *)malloc(len * sizeof(char)); if (syntax_msg) { len = snprintf(msg, len, "missing close paren, %s[%u], last top-level form at %s[%d]\n%s", port_filename(pt), port_line_number(pt), sc->current_file, sc->current_line, syntax_msg); free(syntax_msg); } else len = snprintf(msg, len, "missing close paren, %s[%u], last top-level form at %s[%d]", port_filename(pt), port_line_number(pt), sc->current_file, sc->current_line); return(s7_error(sc, sc->READ_ERROR, set_elist_1(sc, make_string_uncopied_with_length(sc, msg, len)))); } if (syntax_msg) { len = safe_strlen(syntax_msg) + 128; msg = (char *)malloc(len * sizeof(char)); len = snprintf(msg, len, "missing close paren\n%s\n", syntax_msg); free(syntax_msg); return(s7_error(sc, sc->READ_ERROR, set_elist_1(sc, make_string_uncopied_with_length(sc, msg, len)))); } return(s7_error(sc, sc->READ_ERROR, set_elist_1(sc, make_string_wrapper(sc, "missing close paren")))); } static void improper_arglist_error(s7_scheme *sc) { /* sc->code is the last (dotted) arg, sc->args is the arglist reversed not including sc->code * the original was `(,@(reverse args) . ,code) essentially */ if (sc->args == sc->NIL) /* (abs . 1) */ s7_error(sc, sc->SYNTAX_ERROR, set_elist_1(sc, make_string_wrapper(sc, "function call is a dotted list?"))); else s7_error(sc, sc->SYNTAX_ERROR, set_elist_2(sc, make_string_wrapper(sc, "improper list of arguments: ~S"), append_in_place(sc, sc->args = safe_reverse_in_place(sc, sc->args), sc->code))); } /* -------------------------------- leftovers -------------------------------- */ void (*s7_begin_hook(s7_scheme *sc))(s7_scheme *sc, bool *val) { return(sc->begin_hook); } void s7_set_begin_hook(s7_scheme *sc, void (*hook)(s7_scheme *sc, bool *val)) { sc->begin_hook = hook; } static bool call_begin_hook(s7_scheme *sc) { bool result = false; /* originally begin_hook was bool (*hook)(s7_scheme *sc): the value was returned directly, * rather than going through a *bool arg (&result below). That works in gcc (Linux/OSX), * but does not work in MS Visual C++. In the latter, the compiler apparently completely * eliminates any local, returning (for example) a thread-relative stack-allocated value * directly, but then by the time we get here, that variable has vanished, and we get * garbage. We had to thwart the optimization by adding if ((flag) && (!flag)) fprintf(...); * So, in the new form (26-Jun-13), the value is passed directly into an s7 variable * that I hope can't be optimized out of existence. */ opcode_t op; op = sc->op; push_stack(sc, OP_BARRIER, sc->args, sc->code); sc->begin_hook(sc, &result); if (result) { /* set (owlet) in case we were interrupted and need to see why something was hung */ slot_set_value(sc->error_type, sc->F); slot_set_value(sc->error_data, sc->value); /* was sc->F but we now clobber this below */ slot_set_value(sc->error_code, sc->cur_code); slot_set_value(sc->error_line, sc->F); slot_set_value(sc->error_file, sc->F); set_outlet(sc->owlet, sc->envir); sc->value = s7_make_symbol(sc, "begin-hook-interrupt"); /* otherwise the evaluator returns whatever random thing is in sc->value (normally #) * which makes debugging unnecessarily difficult. */ s7_quit(sc); /* don't call gc here -- perhaps at restart somehow? */ return(true); } pop_stack_no_op(sc); sc->op = op; /* for better error handling. otherwise we get "barrier" as the offending function name in eval_error */ return(false); } static s7_pointer apply_list_star(s7_scheme *sc, s7_pointer d) { s7_pointer p, q; /* we check this ahead of time: if (is_null(cdr(d))) return(car(d)); */ p = cons(sc, car(d), cdr(d)); q = p; while (is_not_null(cdr(cdr(p)))) { d = cons(sc, car(p), cdr(p)); p = cdr(p); } cdr(p) = car(cdr(p)); return(q); } static s7_pointer apply_list_error(s7_scheme *sc, s7_pointer lst) { return(s7_error(sc, sc->WRONG_TYPE_ARG, set_elist_2(sc, make_string_wrapper(sc, "apply's last argument should be a proper list: ~S"), lst))); } static s7_pointer g_apply(s7_scheme *sc, s7_pointer args) { #define H_apply "(apply func ...) applies func to the rest of the arguments" #define Q_apply s7_make_circular_signature(sc, 2, 3, sc->VALUES, sc->IS_PROCEDURE, sc->T) /* can apply always be replaced with apply values? * (apply + '(1 2 3)) is the same as (+ (apply values '(1 2 3))) * not if apply* in disguise, I think: * (apply + 1 2 ()) -> 3 * (apply + 1 2 (apply values ())) -> error */ sc->code = car(args); if (is_null(cdr(args))) sc->args = sc->NIL; else { if (is_safe_procedure(sc->code)) { s7_pointer p, q; for (q = args, p = cdr(args); is_not_null(cdr(p)); q = p, p = cdr(p)); /* the last arg is supposed to be a list, it will be spliced onto the end of the previous arg list (if any) below */ if (!is_proper_list(sc, car(p))) /* (apply + #f) etc */ return(apply_list_error(sc, args)); cdr(q) = car(p); /* this would work: if (is_c_function(sc->code)) return(c_function_call(sc->code)(sc, cdr(args))); * but it omits the arg number check */ push_stack(sc, OP_APPLY, cdr(args), sc->code); return(sc->NIL); } else { /* here we have to copy the arg list */ if (is_null(cddr(args))) sc->args = cadr(args); else sc->args = apply_list_star(sc, cdr(args)); if (!is_proper_list(sc, sc->args)) /* (apply + #f) etc */ return(apply_list_error(sc, args)); } } push_stack(sc, OP_APPLY, sc->args, sc->code); return(sc->NIL); } s7_pointer s7_apply_function(s7_scheme *sc, s7_pointer fnc, s7_pointer args) { if (is_c_function(fnc)) return(c_function_call(fnc)(sc, args)); push_stack(sc, OP_EVAL_DONE, sc->args, sc->code); sc->args = args; sc->code = fnc; eval(sc, OP_APPLY); /* we're limited in choices here -- the caller might be (say) car(sc->T1_1) = c_call(...) where the c_call * happens to fallback on a method -- we can't just push OP_APPLY and drop back into the evaluator normally. */ return(sc->value); } s7_pointer s7_eval(s7_scheme *sc, s7_pointer code, s7_pointer e) { push_stack(sc, OP_EVAL_DONE, sc->args, sc->code); sc->code = code; if ((e != sc->rootlet) && (is_let(e))) sc->envir = e; else sc->envir = sc->NIL; /* can't check is_let(e) because sc->rootlet sets its type to t_env! */ eval(sc, OP_BEGIN); return(sc->value); } s7_pointer s7_eval_form(s7_scheme *sc, s7_pointer form, s7_pointer e) { push_stack(sc, OP_EVAL_DONE, sc->args, sc->code); sc->code = form; if ((e != sc->rootlet) && (is_let(e))) sc->envir = e; else sc->envir = sc->NIL; eval(sc, OP_EVAL); return(sc->value); } static s7_pointer g_eval(s7_scheme *sc, s7_pointer args) { #define H_eval "(eval code (env (curlet))) evaluates code in the environment env. 'env' \ defaults to the curlet; to evaluate something in the top-level environment instead, \ pass (rootlet):\n\ \n\ (define x 32) \n\ (let ((x 3))\n\ (eval 'x (rootlet)))\n\ \n\ returns 32" #define Q_eval s7_make_signature(sc, 3, sc->VALUES, sc->IS_LIST, sc->IS_LET) if (is_not_null(cdr(args))) { s7_pointer e; e = cadr(args); if (!is_let(e)) return(wrong_type_argument_with_type(sc, sc->EVAL, 2, e, A_LET)); if (e == sc->rootlet) sc->envir = sc->NIL; else sc->envir = e; } sc->code = car(args); if (s7_stack_top(sc) < 12) push_stack(sc, OP_BARRIER, sc->NIL, sc->NIL); push_stack(sc, OP_EVAL, sc->args, sc->code); return(sc->NIL); } s7_pointer s7_call(s7_scheme *sc, s7_pointer func, s7_pointer args) { bool old_longjmp; jmp_buf old_goto_start; /* this can be called while we are in the eval loop (within eval_c_string for instance), * and if we reset the stack, the previously running evaluation steps off the end * of the stack == segfault. */ if (is_c_function(func)) return(c_function_call(func)(sc, args)); /* no check for wrong-number-of-args -- is that reasonable? */ sc->temp1 = func; /* this is just GC protection */ sc->temp2 = args; old_longjmp = sc->longjmp_ok; memcpy((void *)old_goto_start, (void *)(sc->goto_start), sizeof(jmp_buf)); /* if an error occurs during s7_call, and it is caught, catch (above) wants to longjmp * to its caller to complete the error handler evaluation so that the C stack is * cleaned up -- this means we have to have the longjmp location set here, but * we could get here from anywhere, so we need to save and restore the incoming * longjmp location. */ sc->longjmp_ok = true; if (setjmp(sc->goto_start) != 0) /* returning from s7_error catch handler */ { sc->longjmp_ok = old_longjmp; memcpy((void *)(sc->goto_start), (void *)old_goto_start, sizeof(jmp_buf)); if ((sc->op == OP_ERROR_QUIT) && (sc->longjmp_ok)) longjmp(sc->goto_start, 1); /* this is trying to clear the C stack back to some clean state */ eval(sc, sc->op); /* sc->op can be OP_APPLY if s7_call raised an error that was caught (via catch) -- we're about to go to the error handler */ return(sc->value); } push_stack(sc, OP_EVAL_DONE, sc->args, sc->code); /* this saves the current evaluation and will eventually finish this (possibly) nested call */ sc->args = args; sc->code = func; /* besides a closure, "func" can also be an object (T_C_OBJECT) -- in Snd, a generator for example */ eval(sc, OP_APPLY); sc->longjmp_ok = old_longjmp; memcpy((void *)(sc->goto_start), (void *)old_goto_start, sizeof(jmp_buf)); return(sc->value); } s7_pointer s7_call_with_location(s7_scheme *sc, s7_pointer func, s7_pointer args, const char *caller, const char *file, int line) { s7_pointer result; if (caller) { sc->s7_call_name = caller; sc->s7_call_file = file; sc->s7_call_line = line; } result = s7_call(sc, func, args); if (caller) { sc->s7_call_name = NULL; sc->s7_call_file = NULL; sc->s7_call_line = -1; } return(result); } static s7_pointer implicit_index(s7_scheme *sc, s7_pointer obj, s7_pointer indices) { /* (let ((lst '("12" "34"))) (lst 0 1)) -> #\2 * (let ((lst (list #(1 2) #(3 4)))) (lst 0 1)) -> 2 * * this can get tricky: * ((list (lambda (a) (+ a 1)) (lambda (b) (* b 2))) 1 2) -> 4 * but what if func takes rest/optional args, etc? * ((list (lambda args (car args))) 0 "hi" 0) * should this return #\h or "hi"?? * currently it is "hi" which is consistent with * ((lambda args (car args)) "hi" 0) * but... * ((lambda (arg) arg) "hi" 0) * is currently an error (too many arguments) * it should be (((lambda (arg) arg) "hi") 0) -> #\h * * this applies to non-homogenous cases, so float|int-vectors don't get here */ switch (type(obj)) { case T_VECTOR: /* (#(#(1 2) #(3 4)) 1 1) -> 4 */ return(vector_ref_1(sc, obj, indices)); case T_STRING: /* (#("12" "34") 0 1) -> #\2 */ if (is_null(cdr(indices))) { if (is_byte_vector(obj)) /* ((vector (byte-vector 1)) 0 0) */ return(small_int((unsigned int)(character(string_ref_1(sc, obj, car(indices)))))); return(string_ref_1(sc, obj, car(indices))); } return(s7_error(sc, sc->WRONG_NUMBER_OF_ARGS, set_elist_3(sc, sc->TOO_MANY_ARGUMENTS, obj, indices))); case T_PAIR: /* (#((1 2) (3 4)) 1 0) -> 3, (#((1 (2 3))) 0 1 0) -> 2 */ obj = list_ref_1(sc, obj, car(indices)); if (is_pair(cdr(indices))) return(implicit_index(sc, obj, cdr(indices))); return(obj); case T_HASH_TABLE: /* ((vector (hash-table '(a . 1) '(b . 2))) 0 'a) -> 1 */ obj = s7_hash_table_ref(sc, obj, car(indices)); if (is_pair(cdr(indices))) return(implicit_index(sc, obj, cdr(indices))); return(obj); case T_C_OBJECT: return((*(c_object_ref(obj)))(sc, obj, indices)); case T_LET: obj = s7_let_ref(sc, obj, car(indices)); if (is_pair(cdr(indices))) return(implicit_index(sc, obj, cdr(indices))); return(obj); default: /* (#(a b c) 0 1) -> error, but ((list (lambda (x) x)) 0 "hi") -> "hi" */ return(g_apply(sc, list_2(sc, obj, indices))); } } /* -------------------------------- s7-version -------------------------------- */ static s7_pointer g_s7_version(s7_scheme *sc, s7_pointer args) { #define H_s7_version "(s7-version) returns some string describing the current s7" #define Q_s7_version pcl_s #if WITH_COUNTS report_counts(sc); #endif return(s7_make_string(sc, "s7 " S7_VERSION ", " S7_DATE)); } void s7_quit(s7_scheme *sc) { sc->longjmp_ok = false; pop_input_port(sc); stack_reset(sc); push_stack(sc, OP_EVAL_DONE, sc->NIL, sc->NIL); } /* -------------------------------- exit -------------------------------- */ static s7_pointer g_emergency_exit(s7_scheme *sc, s7_pointer args) { #define H_emergency_exit "(emergency-exit obj) exits s7 immediately" #define Q_emergency_exit pcl_t s7_pointer obj; #ifndef EXIT_SUCCESS #define EXIT_SUCCESS 0 #define EXIT_FAILURE 1 #endif if (is_null(args)) _exit(EXIT_SUCCESS); /* r7rs spec says use _exit here */ obj = car(args); if (obj == sc->F) _exit(EXIT_FAILURE); if ((obj == sc->T) || (!s7_is_integer(obj))) _exit(EXIT_SUCCESS); _exit((int)s7_integer(obj)); return(sc->F); } static s7_pointer g_exit(s7_scheme *sc, s7_pointer args) { #define H_exit "(exit obj) exits s7" #define Q_exit pcl_t s7_quit(sc); return(g_emergency_exit(sc, args)); } #if DEBUGGING static s7_pointer g_abort(s7_scheme *sc, s7_pointer args) {abort();} #endif static s7_function all_x_function[OPT_MAX_DEFINED]; #define is_all_x_op(Op) (all_x_function[Op] != NULL) static bool is_all_x_safe(s7_scheme *sc, s7_pointer p) { return((!is_pair(p)) || ((car(p) == sc->QUOTE) && (is_pair(cdr(p)))) || /* (if #t (quote . -1)) */ ((is_optimized(p)) && (is_all_x_op(optimize_op(p))))); } static int all_x_count(s7_pointer x) { int count = 0; s7_pointer p; for (p = cdr(x); is_pair(p); p = cdr(p)) if ((is_optimized(car(p))) && (is_all_x_op(optimize_op(car(p))))) count++; return(count); } /* arg here is the full expression */ static s7_pointer all_x_else(s7_scheme *sc, s7_pointer arg) {return(sc->T);} /* used in cond_all_x */ static s7_pointer all_x_c(s7_scheme *sc, s7_pointer arg) {return(arg);} static s7_pointer all_x_q(s7_scheme *sc, s7_pointer arg) {return(cadr(arg));} static s7_pointer all_x_s(s7_scheme *sc, s7_pointer arg) {return(find_symbol_checked(sc, arg));} static s7_pointer all_x_u(s7_scheme *sc, s7_pointer arg) {return(find_symbol_unchecked(sc, arg));} static s7_pointer all_x_k(s7_scheme *sc, s7_pointer arg) {return(arg);} static s7_pointer all_x_c_c(s7_scheme *sc, s7_pointer arg) {return(c_call(arg)(sc, cdr(arg)));} static s7_pointer all_x_c_add1(s7_scheme *sc, s7_pointer arg) { s7_pointer x; x = find_symbol_unchecked(sc, cadr(arg)); if (is_integer(x)) return(make_integer(sc, integer(x) + 1)); return(g_add_s1_1(sc, x, arg)); } static s7_pointer all_x_c_addi(s7_scheme *sc, s7_pointer arg) { s7_pointer x; x = find_symbol_unchecked(sc, cadr(arg)); if (is_integer(x)) return(make_integer(sc, integer(x) + integer(caddr(arg)))); return(g_add_2(sc, set_plist_2(sc, x, caddr(arg)))); } static s7_pointer all_x_c_char_eq(s7_scheme *sc, s7_pointer arg) { s7_pointer c; c = find_symbol_unchecked(sc, cadr(arg)); if (c == caddr(arg)) return(sc->T); if (s7_is_character(c)) return(sc->F); method_or_bust(sc, c, sc->CHAR_EQ, set_plist_2(sc, c, caddr(arg)), T_CHARACTER, 1); } static s7_pointer all_x_c_q(s7_scheme *sc, s7_pointer arg) { car(sc->T1_1) = cadr(cadr(arg)); return(c_call(arg)(sc, sc->T1_1)); } static s7_pointer all_x_c_s(s7_scheme *sc, s7_pointer arg) { car(sc->T1_1) = find_symbol_checked(sc, cadr(arg)); return(c_call(arg)(sc, sc->T1_1)); } static s7_pointer all_x_c_u(s7_scheme *sc, s7_pointer arg) { car(sc->T1_1) = find_symbol_unchecked(sc, cadr(arg)); return(c_call(arg)(sc, sc->T1_1)); } static s7_pointer all_x_cdr_s(s7_scheme *sc, s7_pointer arg) { s7_pointer val; val = find_symbol_checked(sc, cadr(arg)); return((is_pair(val)) ? cdr(val) : g_cdr(sc, set_plist_1(sc, val))); } static s7_pointer all_x_cdr_u(s7_scheme *sc, s7_pointer arg) { s7_pointer val; val = find_symbol_unchecked(sc, cadr(arg)); return((is_pair(val)) ? cdr(val) : g_cdr(sc, set_plist_1(sc, val))); } static s7_pointer all_x_car_s(s7_scheme *sc, s7_pointer arg) { s7_pointer val; val = find_symbol_checked(sc, cadr(arg)); return((is_pair(val)) ? car(val) : g_car(sc, set_plist_1(sc, val))); } static s7_pointer all_x_null_s(s7_scheme *sc, s7_pointer arg) { return(make_boolean(sc, is_null(find_symbol_checked(sc, cadr(arg))))); } static s7_pointer all_x_c_sc(s7_scheme *sc, s7_pointer arg) { car(sc->T2_1) = find_symbol_checked(sc, cadr(arg)); car(sc->T2_2) = caddr(arg); return(c_call(arg)(sc, sc->T2_1)); } static s7_pointer all_x_c_uc(s7_scheme *sc, s7_pointer arg) { car(sc->T2_1) = find_symbol_unchecked(sc, cadr(arg)); car(sc->T2_2) = caddr(arg); return(c_call(arg)(sc, sc->T2_1)); } static s7_pointer all_x_c_cs(s7_scheme *sc, s7_pointer arg) { car(sc->T2_2) = find_symbol_checked(sc, caddr(arg)); car(sc->T2_1) = cadr(arg); return(c_call(arg)(sc, sc->T2_1)); } static s7_pointer all_x_c_ss(s7_scheme *sc, s7_pointer arg) { car(sc->T2_1) = find_symbol_checked(sc, cadr(arg)); car(sc->T2_2) = find_symbol_checked(sc, caddr(arg)); return(c_call(arg)(sc, sc->T2_1)); } static s7_pointer all_x_c_uu(s7_scheme *sc, s7_pointer arg) { car(sc->T2_1) = find_symbol_unchecked(sc, cadr(arg)); car(sc->T2_2) = find_symbol_unchecked(sc, caddr(arg)); return(c_call(arg)(sc, sc->T2_1)); } static s7_pointer all_x_c_sss(s7_scheme *sc, s7_pointer arg) { car(sc->T3_1) = find_symbol_checked(sc, cadr(arg)); car(sc->T3_2) = find_symbol_checked(sc, caddr(arg)); car(sc->T3_3) = find_symbol_checked(sc, cadddr(arg)); return(c_call(arg)(sc, sc->T3_1)); } static s7_pointer all_x_c_uuu(s7_scheme *sc, s7_pointer arg) { car(sc->T3_1) = find_symbol_unchecked(sc, cadr(arg)); car(sc->T3_2) = find_symbol_unchecked(sc, caddr(arg)); car(sc->T3_3) = find_symbol_unchecked(sc, cadddr(arg)); return(c_call(arg)(sc, sc->T3_1)); } static s7_pointer all_x_c_scs(s7_scheme *sc, s7_pointer arg) { car(sc->T3_1) = find_symbol_checked(sc, cadr(arg)); car(sc->T3_3) = find_symbol_checked(sc, cadddr(arg)); car(sc->T3_2) = caddr(arg); return(c_call(arg)(sc, sc->T3_1)); } static s7_pointer all_x_c_css(s7_scheme *sc, s7_pointer arg) { car(sc->T3_2) = find_symbol_checked(sc, caddr(arg)); car(sc->T3_3) = find_symbol_checked(sc, cadddr(arg)); car(sc->T3_1) = cadr(arg); return(c_call(arg)(sc, sc->T3_1)); } static s7_pointer all_x_c_csc(s7_scheme *sc, s7_pointer arg) { car(sc->T3_2) = find_symbol_checked(sc, caddr(arg)); car(sc->T3_1) = cadr(arg); car(sc->T3_3) = cadddr(arg); return(c_call(arg)(sc, sc->T3_1)); } static s7_pointer all_x_c_ssc(s7_scheme *sc, s7_pointer arg) { car(sc->T3_1) = find_symbol_checked(sc, cadr(arg)); car(sc->T3_2) = find_symbol_checked(sc, caddr(arg)); car(sc->T3_3) = cadddr(arg); return(c_call(arg)(sc, sc->T3_1)); } static s7_pointer all_x_c_sq(s7_scheme *sc, s7_pointer arg) { car(sc->T2_1) = find_symbol_checked(sc, cadr(arg)); car(sc->T2_2) = cadr(caddr(arg)); return(c_call(arg)(sc, sc->T2_1)); } static s7_pointer all_x_c_opcq(s7_scheme *sc, s7_pointer arg) { s7_pointer largs; largs = cadr(arg); car(sc->T1_1) = c_call(largs)(sc, cdr(largs)); return(c_call(arg)(sc, sc->T1_1)); } static s7_pointer all_x_c_s_opcq(s7_scheme *sc, s7_pointer arg) { s7_pointer largs; largs = caddr(arg); car(sc->T2_2) = c_call(largs)(sc, cdr(largs)); car(sc->T2_1) = find_symbol_checked(sc, cadr(arg)); return(c_call(arg)(sc, sc->T2_1)); } static s7_pointer all_x_c_c_opcq(s7_scheme *sc, s7_pointer arg) { s7_pointer largs; largs = caddr(arg); car(sc->T2_2) = c_call(largs)(sc, cdr(largs)); car(sc->T2_1) = cadr(arg); return(c_call(arg)(sc, sc->T2_1)); } static s7_pointer all_x_c_opcq_s(s7_scheme *sc, s7_pointer arg) { s7_pointer largs; largs = cadr(arg); car(sc->T2_1) = c_call(largs)(sc, cdr(largs)); car(sc->T2_2) = find_symbol_checked(sc, caddr(arg)); return(c_call(arg)(sc, sc->T2_1)); } static s7_pointer all_x_c_opcq_c(s7_scheme *sc, s7_pointer arg) { s7_pointer largs; largs = cadr(arg); car(sc->T2_1) = c_call(largs)(sc, cdr(largs)); car(sc->T2_2) = caddr(arg); return(c_call(arg)(sc, sc->T2_1)); } static s7_pointer all_x_c_opcq_opcq(s7_scheme *sc, s7_pointer arg) { s7_pointer largs; largs = cadr(arg); car(sc->T2_1) = c_call(largs)(sc, cdr(largs)); largs = caddr(arg); car(sc->T2_2) = c_call(largs)(sc, cdr(largs)); return(c_call(arg)(sc, sc->T2_1)); } static s7_pointer all_x_c_opsq(s7_scheme *sc, s7_pointer arg) { s7_pointer largs; largs = cadr(arg); car(sc->T1_1) = find_symbol_checked(sc, cadr(largs)); car(sc->T1_1) = c_call(largs)(sc, sc->T1_1); return(c_call(arg)(sc, sc->T1_1)); } static s7_pointer all_x_c_not_opsq(s7_scheme *sc, s7_pointer arg) { s7_pointer largs; largs = cadr(arg); car(sc->T1_1) = find_symbol_checked(sc, cadr(largs)); if (c_call(largs)(sc, sc->T1_1) == sc->F) return(sc->T); return(sc->F); } static s7_pointer all_x_c_opuq(s7_scheme *sc, s7_pointer arg) { s7_pointer largs; largs = cadr(arg); car(sc->T1_1) = find_symbol_unchecked(sc, cadr(largs)); car(sc->T1_1) = c_call(largs)(sc, sc->T1_1); return(c_call(arg)(sc, sc->T1_1)); } static s7_pointer all_x_c_not_opuq(s7_scheme *sc, s7_pointer arg) { s7_pointer largs; largs = cadr(arg); car(sc->T1_1) = find_symbol_unchecked(sc, cadr(largs)); if (c_call(largs)(sc, sc->T1_1) == sc->F) return(sc->T); return(sc->F); } static s7_pointer all_x_c_opssq(s7_scheme *sc, s7_pointer arg) { s7_pointer largs; largs = cadr(arg); car(sc->T2_1) = find_symbol_checked(sc, cadr(largs)); car(sc->T2_2) = find_symbol_checked(sc, caddr(largs)); car(sc->T1_1) = c_call(largs)(sc, sc->T2_1); return(c_call(arg)(sc, sc->T1_1)); } static s7_pointer all_x_c_opuuq(s7_scheme *sc, s7_pointer arg) { s7_pointer largs; largs = cadr(arg); car(sc->T2_1) = find_symbol_unchecked(sc, cadr(largs)); car(sc->T2_2) = find_symbol_unchecked(sc, caddr(largs)); car(sc->T1_1) = c_call(largs)(sc, sc->T2_1); return(c_call(arg)(sc, sc->T1_1)); } static s7_pointer all_x_c_opscq(s7_scheme *sc, s7_pointer arg) { s7_pointer largs; largs = cadr(arg); car(sc->T2_1) = find_symbol_checked(sc, cadr(largs)); car(sc->T2_2) = caddr(largs); car(sc->T1_1) = c_call(largs)(sc, sc->T2_1); return(c_call(arg)(sc, sc->T1_1)); } static s7_pointer all_x_c_opsqq(s7_scheme *sc, s7_pointer arg) { s7_pointer largs; largs = cadr(arg); car(sc->T2_1) = find_symbol_checked(sc, cadr(largs)); car(sc->T2_2) = cadr(caddr(largs)); car(sc->T1_1) = c_call(largs)(sc, sc->T2_1); return(c_call(arg)(sc, sc->T1_1)); } static s7_pointer all_x_c_opssq_s(s7_scheme *sc, s7_pointer arg) { s7_pointer largs; largs = cadr(arg); car(sc->T2_1) = find_symbol_checked(sc, cadr(largs)); car(sc->T2_2) = find_symbol_checked(sc, caddr(largs)); car(sc->T2_1) = c_call(largs)(sc, sc->T2_1); car(sc->T2_2) = find_symbol_checked(sc, caddr(arg)); return(c_call(arg)(sc, sc->T2_1)); } static s7_pointer all_x_c_opuuq_u(s7_scheme *sc, s7_pointer arg) { s7_pointer largs; largs = cadr(arg); car(sc->T2_1) = find_symbol_unchecked(sc, cadr(largs)); car(sc->T2_2) = find_symbol_unchecked(sc, caddr(largs)); car(sc->T2_1) = c_call(largs)(sc, sc->T2_1); car(sc->T2_2) = find_symbol_unchecked(sc, caddr(arg)); return(c_call(arg)(sc, sc->T2_1)); } static s7_pointer all_x_c_opssq_c(s7_scheme *sc, s7_pointer arg) { s7_pointer largs; largs = cadr(arg); car(sc->T2_1) = find_symbol_checked(sc, cadr(largs)); car(sc->T2_2) = find_symbol_checked(sc, caddr(largs)); car(sc->T2_1) = c_call(largs)(sc, sc->T2_1); car(sc->T2_2) = caddr(arg); return(c_call(arg)(sc, sc->T2_1)); } static s7_pointer all_x_c_opsq_s(s7_scheme *sc, s7_pointer arg) { s7_pointer largs; largs = cadr(arg); car(sc->T1_1) = find_symbol_checked(sc, cadr(largs)); car(sc->T2_1) = c_call(largs)(sc, sc->T1_1); car(sc->T2_2) = find_symbol_checked(sc, caddr(arg)); return(c_call(arg)(sc, sc->T2_1)); } static s7_pointer all_x_c_opuq_u(s7_scheme *sc, s7_pointer arg) { s7_pointer largs; largs = cadr(arg); car(sc->T1_1) = find_symbol_unchecked(sc, cadr(largs)); car(sc->T2_1) = c_call(largs)(sc, sc->T1_1); car(sc->T2_2) = find_symbol_unchecked(sc, caddr(arg)); return(c_call(arg)(sc, sc->T2_1)); } static s7_pointer all_x_c_opsq_c(s7_scheme *sc, s7_pointer arg) { s7_pointer largs; largs = cadr(arg); car(sc->T1_1) = find_symbol_checked(sc, cadr(largs)); car(sc->T2_1) = c_call(largs)(sc, sc->T1_1); car(sc->T2_2) = caddr(arg); return(c_call(arg)(sc, sc->T2_1)); } static s7_pointer all_x_c_s_opssq(s7_scheme *sc, s7_pointer arg) { s7_pointer largs; largs = caddr(arg); car(sc->T2_1) = find_symbol_checked(sc, cadr(largs)); car(sc->T2_2) = find_symbol_checked(sc, caddr(largs)); car(sc->T2_2) = c_call(largs)(sc, sc->T2_1); car(sc->T2_1) = find_symbol_checked(sc, cadr(arg)); return(c_call(arg)(sc, sc->T2_1)); } static s7_pointer all_x_c_u_opuuq(s7_scheme *sc, s7_pointer arg) { s7_pointer largs; largs = caddr(arg); car(sc->T2_1) = find_symbol_unchecked(sc, cadr(largs)); car(sc->T2_2) = find_symbol_unchecked(sc, caddr(largs)); car(sc->T2_2) = c_call(largs)(sc, sc->T2_1); car(sc->T2_1) = find_symbol_unchecked(sc, cadr(arg)); return(c_call(arg)(sc, sc->T2_1)); } static s7_pointer all_x_c_s_opsq(s7_scheme *sc, s7_pointer arg) { s7_pointer largs; largs = caddr(arg); car(sc->T1_1) = find_symbol_checked(sc, cadr(largs)); car(sc->T2_2) = c_call(largs)(sc, sc->T1_1); car(sc->T2_1) = find_symbol_checked(sc, cadr(arg)); return(c_call(arg)(sc, sc->T2_1)); } static s7_pointer all_x_c_u_opuq(s7_scheme *sc, s7_pointer arg) { s7_pointer largs; largs = caddr(arg); car(sc->T1_1) = find_symbol_unchecked(sc, cadr(largs)); car(sc->T2_2) = c_call(largs)(sc, sc->T1_1); car(sc->T2_1) = find_symbol_unchecked(sc, cadr(arg)); return(c_call(arg)(sc, sc->T2_1)); } static s7_pointer all_x_c_c_opsq(s7_scheme *sc, s7_pointer arg) { s7_pointer largs; largs = caddr(arg); car(sc->T1_1) = find_symbol_checked(sc, cadr(largs)); car(sc->T2_2) = c_call(largs)(sc, sc->T1_1); car(sc->T2_1) = cadr(arg); return(c_call(arg)(sc, sc->T2_1)); } static s7_pointer all_x_c_opsq_opsq(s7_scheme *sc, s7_pointer arg) { s7_pointer largs; largs = cdr(arg); car(sc->T1_1) = find_symbol_checked(sc, cadr(car(largs))); sc->temp3 = c_call(car(largs))(sc, sc->T1_1); largs = cadr(largs); car(sc->T1_1) = find_symbol_checked(sc, cadr(largs)); car(sc->T2_2) = c_call(largs)(sc, sc->T1_1); car(sc->T2_1) = sc->temp3; sc->temp3 = sc->NIL; return(c_call(arg)(sc, sc->T2_1)); } static s7_pointer all_x_c_opuq_opuq(s7_scheme *sc, s7_pointer arg) { s7_pointer largs; largs = cdr(arg); car(sc->T1_1) = find_symbol_unchecked(sc, cadr(car(largs))); sc->temp3 = c_call(car(largs))(sc, sc->T1_1); largs = cadr(largs); car(sc->T1_1) = find_symbol_unchecked(sc, cadr(largs)); car(sc->T2_2) = c_call(largs)(sc, sc->T1_1); car(sc->T2_1) = sc->temp3; sc->temp3 = sc->NIL; return(c_call(arg)(sc, sc->T2_1)); } static s7_pointer all_x_c_opssq_opssq(s7_scheme *sc, s7_pointer arg) { s7_pointer largs; largs = cdr(arg); car(sc->T2_1) = find_symbol_checked(sc, cadr(car(largs))); car(sc->T2_2) = find_symbol_checked(sc, caddr(car(largs))); sc->temp3 = c_call(car(largs))(sc, sc->T2_1); largs = cadr(largs); car(sc->T2_1) = find_symbol_checked(sc, cadr(largs)); car(sc->T2_2) = find_symbol_checked(sc, caddr(largs)); car(sc->T2_2) = c_call(largs)(sc, sc->T2_1); car(sc->T2_1) = sc->temp3; sc->temp3 = sc->NIL; return(c_call(arg)(sc, sc->T2_1)); } static s7_pointer all_x_c_opuuq_opuuq(s7_scheme *sc, s7_pointer arg) { s7_pointer largs; largs = cdr(arg); car(sc->T2_1) = find_symbol_unchecked(sc, cadr(car(largs))); car(sc->T2_2) = find_symbol_unchecked(sc, caddr(car(largs))); sc->temp3 = c_call(car(largs))(sc, sc->T2_1); largs = cadr(largs); car(sc->T2_1) = find_symbol_unchecked(sc, cadr(largs)); car(sc->T2_2) = find_symbol_unchecked(sc, caddr(largs)); car(sc->T2_2) = c_call(largs)(sc, sc->T2_1); car(sc->T2_1) = sc->temp3; sc->temp3 = sc->NIL; return(c_call(arg)(sc, sc->T2_1)); } static s7_pointer all_x_c_op_opssq_q_c(s7_scheme *sc, s7_pointer code) { s7_pointer arg; arg = cadr(cadr(code)); car(sc->T2_1) = find_symbol_checked(sc, cadr(arg)); car(sc->T2_2) = find_symbol_checked(sc, caddr(arg)); car(sc->T1_1) = c_call(arg)(sc, sc->T2_1); car(sc->T2_1) = c_call(cadr(code))(sc, sc->T1_1); car(sc->T2_2) = caddr(code); return(c_call(code)(sc, sc->T2_1)); } static s7_pointer all_x_c_a(s7_scheme *sc, s7_pointer arg) { car(sc->T1_1) = c_call(cdr(arg))(sc, cadr(arg)); return(c_call(arg)(sc, sc->T1_1)); } static s7_pointer all_x_c_ssa(s7_scheme *sc, s7_pointer arg) { sc->temp3 = c_call(cdddr(arg))(sc, cadddr(arg)); car(sc->T3_1) = find_symbol_checked(sc, cadr(arg)); car(sc->T3_2) = find_symbol_checked(sc, caddr(arg)); car(sc->T3_3) = sc->temp3; sc->temp3 = sc->NIL; return(c_call(arg)(sc, sc->T3_1)); } static s7_pointer all_x_c_sas(s7_scheme *sc, s7_pointer arg) { sc->temp3 = c_call(cddr(arg))(sc, caddr(arg)); car(sc->T3_1) = find_symbol_checked(sc, cadr(arg)); car(sc->T3_3) = find_symbol_checked(sc, cadddr(arg)); car(sc->T3_2) = sc->temp3; sc->temp3 = sc->NIL; return(c_call(arg)(sc, sc->T3_1)); } static s7_pointer all_x_c_sca(s7_scheme *sc, s7_pointer arg) { sc->temp3 = c_call(cdddr(arg))(sc, cadddr(arg)); car(sc->T3_1) = find_symbol_checked(sc, cadr(arg)); car(sc->T3_2) = caddr(arg); car(sc->T3_3) = sc->temp3; sc->temp3 = sc->NIL; return(c_call(arg)(sc, sc->T3_1)); } static s7_pointer all_x_c_csa(s7_scheme *sc, s7_pointer arg) { sc->temp3 = c_call(cdddr(arg))(sc, cadddr(arg)); car(sc->T3_1) = cadr(arg); car(sc->T3_2) = find_symbol_checked(sc, caddr(arg)); car(sc->T3_3) = sc->temp3; sc->temp3 = sc->NIL; return(c_call(arg)(sc, sc->T3_1)); } static s7_pointer all_x_c_cas(s7_scheme *sc, s7_pointer arg) { sc->temp3 = c_call(cddr(arg))(sc, caddr(arg)); car(sc->T3_1) = cadr(arg); car(sc->T3_3) = find_symbol_checked(sc, cadddr(arg)); car(sc->T3_2) = sc->temp3; sc->temp3 = sc->NIL; return(c_call(arg)(sc, sc->T3_1)); } static void all_x_function_init(void) { int i; for (i = 0; i < OPT_MAX_DEFINED; i++) all_x_function[i] = NULL; all_x_function[HOP_SAFE_C_C] = all_x_c_c; all_x_function[HOP_SAFE_C_Q] = all_x_c_q; all_x_function[HOP_SAFE_C_A] = all_x_c_a; all_x_function[HOP_SAFE_C_S] = all_x_c_s; all_x_function[HOP_SAFE_C_opCq] = all_x_c_opcq; all_x_function[HOP_SAFE_C_opSq] = all_x_c_opsq; all_x_function[HOP_SAFE_C_opSSq] = all_x_c_opssq; all_x_function[HOP_SAFE_C_opSCq] = all_x_c_opscq; all_x_function[HOP_SAFE_C_opSQq] = all_x_c_opsqq; all_x_function[HOP_SAFE_C_SC] = all_x_c_sc; all_x_function[HOP_SAFE_C_CS] = all_x_c_cs; all_x_function[HOP_SAFE_C_SQ] = all_x_c_sq; all_x_function[HOP_SAFE_C_SS] = all_x_c_ss; all_x_function[HOP_SAFE_C_opSq_S] = all_x_c_opsq_s; all_x_function[HOP_SAFE_C_opSq_C] = all_x_c_opsq_c; all_x_function[HOP_SAFE_C_S_opSq] = all_x_c_s_opsq; all_x_function[HOP_SAFE_C_S_opCq] = all_x_c_s_opcq; all_x_function[HOP_SAFE_C_opCq_S] = all_x_c_opcq_s; all_x_function[HOP_SAFE_C_opCq_C] = all_x_c_opcq_c; all_x_function[HOP_SAFE_C_C_opSq] = all_x_c_c_opsq; all_x_function[HOP_SAFE_C_C_opCq] = all_x_c_c_opcq; all_x_function[HOP_SAFE_C_opSSq_C] = all_x_c_opssq_c; all_x_function[HOP_SAFE_C_opSSq_S] = all_x_c_opssq_s; all_x_function[HOP_SAFE_C_S_opSSq] = all_x_c_s_opssq; all_x_function[HOP_SAFE_C_opSq_opSq] = all_x_c_opsq_opsq; all_x_function[HOP_SAFE_C_opCq_opCq] = all_x_c_opcq_opcq; all_x_function[HOP_SAFE_C_opSSq_opSSq] = all_x_c_opssq_opssq; all_x_function[HOP_SAFE_C_op_opSSq_q_C] = all_x_c_op_opssq_q_c; all_x_function[HOP_SAFE_C_CSA] = all_x_c_csa; all_x_function[HOP_SAFE_C_CAS] = all_x_c_cas; all_x_function[HOP_SAFE_C_SCA] = all_x_c_sca; all_x_function[HOP_SAFE_C_SAS] = all_x_c_sas; all_x_function[HOP_SAFE_C_SSA] = all_x_c_ssa; all_x_function[HOP_SAFE_C_SSC] = all_x_c_ssc; all_x_function[HOP_SAFE_C_SSS] = all_x_c_sss; all_x_function[HOP_SAFE_C_SCS] = all_x_c_scs; all_x_function[HOP_SAFE_C_CSS] = all_x_c_css; all_x_function[HOP_SAFE_C_CSC] = all_x_c_csc; } static s7_function all_x_eval(s7_scheme *sc, s7_pointer arg, s7_pointer e, safe_sym_t *checker) { if (is_pair(arg)) { if (is_optimized(arg)) { switch (optimize_op(arg)) { case HOP_SAFE_C_C: if ((c_call(arg) == g_add_cs1) && (checker(sc, cadr(arg), e))) return(all_x_c_add1); if ((c_call(arg) == g_add_si) && (checker(sc, cadr(arg), e))) return(all_x_c_addi); if ((c_call(arg) == g_char_equal_s_ic) && (checker(sc, cadr(arg), e))) return(all_x_c_char_eq); return(all_x_c_c); case HOP_SAFE_C_S: if (car(arg) == sc->CDR) { if (checker(sc, cadr(arg), e)) return(all_x_cdr_u); return(all_x_cdr_s); } if (car(arg) == sc->CAR) return(all_x_car_s); if (car(arg) == sc->IS_NULL) return(all_x_null_s); if (checker(sc, cadr(arg), e)) /* all we want here is assurance it's not going to be unbound */ return(all_x_c_u); return(all_x_c_s); case HOP_SAFE_C_SS: if ((checker(sc, cadr(arg), e)) && (checker(sc, caddr(arg), e))) return(all_x_c_uu); return(all_x_c_ss); case HOP_SAFE_C_SSS: if ((checker(sc, cadr(arg), e)) && (checker(sc, caddr(arg), e)) && (checker(sc, cadddr(arg), e))) return(all_x_c_uuu); return(all_x_c_sss); case HOP_SAFE_C_SC: if (checker(sc, cadr(arg), e)) return(all_x_c_uc); return(all_x_c_sc); case HOP_SAFE_C_opSq: if (checker(sc, cadr(cadr(arg)), e)) { if (car(arg) == sc->NOT) return(all_x_c_not_opuq); return(all_x_c_opuq); } if (car(arg) == sc->NOT) return(all_x_c_not_opsq); return(all_x_c_opsq); case HOP_SAFE_C_opSq_opSq: if ((checker(sc, cadr(cadr(arg)), e)) && (checker(sc, cadr(caddr(arg)), e))) return(all_x_c_opuq_opuq); return(all_x_c_opsq_opsq); case HOP_SAFE_C_opSSq_opSSq: if ((checker(sc, cadr(cadr(arg)), e)) && (checker(sc, caddr(cadr(arg)), e)) && (checker(sc, cadr(caddr(arg)), e)) && (checker(sc, caddr(caddr(arg)), e))) return(all_x_c_opuuq_opuuq); return(all_x_c_opssq_opssq); case HOP_SAFE_C_opSSq: if ((checker(sc, cadr(cadr(arg)), e)) && (checker(sc, caddr(cadr(arg)), e))) return(all_x_c_opuuq); return(all_x_c_opssq); case HOP_SAFE_C_opSSq_S: if ((checker(sc, cadr(cadr(arg)), e)) && (checker(sc, caddr(cadr(arg)), e)) && (checker(sc, caddr(arg), e))) return(all_x_c_opuuq_u); return(all_x_c_opssq_s); case HOP_SAFE_C_S_opSq: if ((checker(sc, cadr(arg), e)) && (checker(sc, cadr(caddr(arg)), e))) return(all_x_c_u_opuq); return(all_x_c_s_opsq); case HOP_SAFE_C_S_opSSq: if ((checker(sc, cadr(arg), e)) && (checker(sc, cadr(caddr(arg)), e)) && (checker(sc, caddr(caddr(arg)), e))) return(all_x_c_u_opuuq); return(all_x_c_s_opssq); case HOP_SAFE_C_opSq_S: if ((checker(sc, cadr(cadr(arg)), e)) && (checker(sc, caddr(arg), e))) return(all_x_c_opuq_u); return(all_x_c_opsq_s); default: /* if (!all_x_function[optimize_op(arg)]) fprintf(stderr, "%s: %s\n", opt_names[optimize_op(arg)], DISPLAY(arg)); */ return(all_x_function[optimize_op(arg)]); } } if (car(arg) == sc->QUOTE) return(all_x_q); return(NULL); } if (is_symbol(arg)) { if (is_keyword(arg)) return(all_x_k); if (checker(sc, arg, e)) return(all_x_u); return(all_x_s); } return(all_x_c); } static s7_function cond_all_x_eval(s7_scheme *sc, s7_pointer arg, s7_pointer e) { if (arg == sc->ELSE) return(all_x_else); return(all_x_eval(sc, arg, e, let_symbol_is_safe)); } /* ---------------------------------------- for-each ---------------------------------------- */ static s7_pointer make_counter(s7_scheme *sc, s7_pointer iter) { s7_pointer x; new_cell(sc, x, T_COUNTER); counter_result(x) = sc->NIL; counter_list(x) = iter; /* iterator */ counter_capture(x) = 0; /* will be capture_let_counter */ counter_set_let(x, sc->NIL); /* will be the saved env */ return(x); } static s7_pointer g_for_each(s7_scheme *sc, s7_pointer args) { #define H_for_each "(for-each proc object . objects) applies proc to each element of the objects traversed in parallel. \ Each object can be a list, string, vector, hash-table, or any other sequence." #define Q_for_each s7_make_circular_signature(sc, 2, 3, sc->T, sc->IS_PROCEDURE, sc->LENGTH) s7_pointer p, f; int len; bool got_nil = false; /* fprintf(stderr, "for-each: %s\n", DISPLAY(args)); */ /* try the normal case first */ f = car(args); /* the function */ p = cadr(args); if ((is_null(cddr(args))) && (is_pair(p)) && (is_closure(f)) && /* not lambda* that might get confused about arg names */ (closure_arity_to_int(sc, f) == 1) && /* not a rest arg: not is_pair: (lambda (x . args) arg) */ (!is_immutable_symbol(car(closure_args(f))))) { s7_pointer c; c = make_counter(sc, p); counter_result(c) = p; push_stack(sc, OP_FOR_EACH_2, c, f); return(sc->UNSPECIFIED); } if (!is_applicable(f)) method_or_bust_with_type(sc, f, sc->FOR_EACH, args, SOMETHING_APPLICABLE, 1); for (len = 0, p = cdr(args); is_not_null(p); p = cdr(p), len++) { if ((!is_sequence(car(p))) && (!is_iterator(car(p)))) return(simple_wrong_type_argument_with_type(sc, sc->FOR_EACH, car(p), A_SEQUENCE)); if (is_null(car(p))) got_nil = true; } if (!s7_is_aritable(sc, f, len)) { static s7_pointer for_each_args_error = NULL; if (!for_each_args_error) for_each_args_error = s7_make_permanent_string("for-each ~A: ~A args?"); return(s7_error(sc, sc->WRONG_NUMBER_OF_ARGS, set_elist_3(sc, for_each_args_error, f, small_int(len)))); } if (got_nil) return(sc->UNSPECIFIED); sc->temp3 = args; sc->z = sc->NIL; /* don't use sc->args here -- it needs GC protection until we get the iterators */ for (p = cdr(args); is_not_null(p); p = cdr(p)) { s7_pointer iter; iter = car(p); if (!is_iterator(car(p))) iter = s7_make_iterator(sc, iter); sc->z = cons(sc, iter, sc->z); } sc->temp3 = sc->NIL; sc->x = make_list(sc, len, sc->NIL); sc->z = safe_reverse_in_place(sc, sc->z); sc->z = cons(sc, sc->z, sc->x); /* if function is safe c func, do the for-each locally */ if ((is_safe_procedure(f)) && (is_c_function(f))) { s7_function func; s7_pointer iters; func = c_function_call(f); push_stack(sc, OP_NO_OP, sc->args, sc->z); /* temporary GC protection */ if (len == 1) { s7_pointer x, y; x = caar(sc->z); y = cdr(sc->z); sc->z = sc->NIL; while (true) { car(y) = s7_iterate(sc, x); if (iterator_is_at_end(x)) { pop_stack(sc); return(sc->UNSPECIFIED); } func(sc, y); } } iters = sc->z; sc->z = sc->NIL; while (true) { s7_pointer x, y; for (x = car(iters), y = cdr(iters); is_pair(x); x = cdr(x), y = cdr(y)) { car(y) = s7_iterate(sc, car(x)); if (iterator_is_at_end(car(x))) { pop_stack(sc); return(sc->UNSPECIFIED); } } func(sc, cdr(iters)); } } /* if closure call is straightforward, use OP_FOR_EACH_1 */ if ((len == 1) && (is_closure(f)) && /* not lambda* that might get confused about arg names */ (closure_arity_to_int(sc, f) == 1) && /* not a rest arg: not is_pair: (lambda (x . args) arg) */ (!is_immutable_symbol(car(closure_args(f))))) { s7_pointer body, expr; body = closure_body(f); expr = car(body); if ((is_null(cdr(body))) && (is_optimized(expr)) && (is_all_x_op(optimize_op(expr)))) { s7_function func; s7_pointer slot, iter; iter = caar(sc->z); sc->z = sc->NIL; push_stack(sc, OP_NO_OP, iter, f); /* temporary GC protection?? */ sc->envir = new_frame_in_env(sc, sc->envir); slot = make_slot_1(sc, sc->envir, car(closure_args(f)), sc->F); func = all_x_eval(sc, expr, sc->envir, let_symbol_is_safe); if (func == all_x_c_c) { func = c_callee(expr); expr = cdr(expr); } while (true) { slot_set_value(slot, s7_iterate(sc, iter)); if (iterator_is_at_end(iter)) { pop_stack(sc); return(sc->UNSPECIFIED); } func(sc, expr); } } push_stack(sc, OP_FOR_EACH_1, make_counter(sc, caar(sc->z)), f); sc->z = sc->NIL; return(sc->UNSPECIFIED); } push_stack(sc, OP_FOR_EACH, sc->z, f); sc->z = sc->NIL; return(sc->UNSPECIFIED); } /* ---------------------------------------- map ---------------------------------------- */ static s7_pointer g_map(s7_scheme *sc, s7_pointer args) { #define H_map "(map proc object . objects) applies proc to a list made up of the next element of each of its arguments, returning \ a list of the results. Its arguments can be lists, vectors, strings, hash-tables, or any applicable objects." #define Q_map s7_make_circular_signature(sc, 2, 3, sc->IS_LIST, sc->IS_PROCEDURE, sc->LENGTH) s7_pointer p, f; int len; bool got_nil = false; f = car(args); /* the function */ if (!is_applicable(f)) method_or_bust_with_type(sc, f, sc->MAP, args, SOMETHING_APPLICABLE, 1); for (len = 0, p = cdr(args); is_not_null(p); p = cdr(p), len++) { if ((!is_sequence(car(p))) && (!is_iterator(car(p)))) return(simple_wrong_type_argument_with_type(sc, sc->MAP, car(p), A_SEQUENCE)); if (is_null(car(p))) got_nil = true; } if ((!is_pair(f)) && (!s7_is_aritable(sc, f, len))) { static s7_pointer map_args_error = NULL; if (!map_args_error) map_args_error = s7_make_permanent_string("map ~A: ~A args?"); return(s7_error(sc, sc->WRONG_NUMBER_OF_ARGS, set_elist_3(sc, map_args_error, f, small_int(len)))); } if (got_nil) return(sc->NIL); if ((f == slot_value(global_slot(sc->VALUES))) && (is_null(cddr(args))) && (!has_methods(cadr(args)))) { p = object_to_list(sc, cadr(args)); if (p != cadr(args)) return(p); } sc->temp3 = args; sc->z = sc->NIL; /* don't use sc->args here -- it needs GC protection until we get the iterators */ for (p = cdr(args); is_not_null(p); p = cdr(p)) { s7_pointer iter; iter = car(p); if (!is_iterator(car(p))) iter = s7_make_iterator(sc, iter); sc->z = cons(sc, iter, sc->z); } sc->z = safe_reverse_in_place(sc, sc->z); sc->temp3 = sc->NIL; /* if function is safe c func, do the map locally */ if ((is_safe_procedure(f)) && (is_c_function(f))) { s7_function func; s7_pointer val, val1, old_args, iter_list; val1 = cons(sc, sc->z, make_list(sc, len, sc->NIL)); iter_list = sc->z; sc->z = sc->NIL; old_args = sc->args; func = c_function_call(f); push_stack(sc, OP_NO_OP, iter_list, val = cons(sc, sc->NIL, sc->code)); /* temporary GC protection */ while (true) { s7_pointer x, y, z; for (x = iter_list, y = cdr(val1); is_pair(x); x = cdr(x), y = cdr(y)) { car(y) = s7_iterate(sc, car(x)); if (iterator_is_at_end(car(x))) { pop_stack(sc); sc->args = old_args; return(safe_reverse_in_place(sc, car(val))); } } z = func(sc, cdr(val1)); /* can this contain multiple-values? */ if (z != sc->NO_VALUE) car(val) = cons(sc, z, car(val)); } } /* if closure call is straightforward, use OP_MAP_1 */ if ((len == 1) && (is_closure(f)) && /* not lambda* that might get confused about arg names */ (closure_arity_to_int(sc, f) == 1) && /* not a rest arg: not is_pair: (lambda (x . args) arg) */ (!is_immutable_symbol(car(closure_args(f))))) { s7_pointer body, expr; body = closure_body(f); expr = car(body); if ((is_null(cdr(body))) && (is_optimized(expr)) && (is_all_x_op(optimize_op(expr)))) { s7_function func; s7_pointer slot, iter, val, z; iter = car(sc->z); sc->z = sc->NIL; push_stack(sc, OP_NO_OP, sc->args, val = cons(sc, sc->NIL, f)); sc->envir = new_frame_in_env(sc, sc->envir); slot = make_slot_1(sc, sc->envir, car(closure_args(f)), sc->F); func = all_x_eval(sc, expr, sc->envir, let_symbol_is_safe); if (func == all_x_c_c) { func = c_callee(expr); expr = cdr(expr); } while (true) { slot_set_value(slot, s7_iterate(sc, iter)); if (iterator_is_at_end(iter)) { pop_stack(sc); return(safe_reverse_in_place(sc, car(val))); } z = func(sc, expr); if (z != sc->NO_VALUE) car(val) = cons(sc, z, car(val)); } } push_stack(sc, OP_MAP_1, make_counter(sc, car(sc->z)), f); sc->z = sc->NIL; return(sc->NIL); } push_stack(sc, OP_MAP, make_counter(sc, sc->z), f); sc->z = sc->NIL; return(sc->NIL); } /* -------------------------------- multiple-values -------------------------------- */ static s7_pointer splice_in_values(s7_scheme *sc, s7_pointer args) { int top; s7_pointer x; top = s7_stack_top(sc) - 1; /* stack_end - stack_start: if this is negative, we're in big trouble */ switch (stack_op(sc->stack, top)) { /* the normal case -- splice values into caller's args */ case OP_EVAL_ARGS1: case OP_EVAL_ARGS2: case OP_EVAL_ARGS3: case OP_EVAL_ARGS4: /* code = args yet to eval in order, args = evalled args reversed * * it's not safe to simply reverse args and tack the current stacked args onto its (new) end, * setting stacked args to cdr of reversed-args and returning car because the list (args) * can be some variable's value in a macro expansion via ,@ and reversing it in place * (all this to avoid consing), clobbers the variable's value. */ for (x = args; is_not_null(cdr(x)); x = cdr(x)) stack_args(sc->stack, top) = cons(sc, car(x), stack_args(sc->stack, top)); return(car(x)); /* in the next set, the main evaluator branches blithely assume no multiple-values, * and if it happens anyway, we vector to a different branch here */ case OP_SAFE_C_opSq_P_1: vector_element(sc->stack, top) = (s7_pointer)OP_SAFE_C_opSq_P_MV; return(args); case OP_SAFE_C_SSZ_1: case OP_EVAL_ARGS_SSP_1: vector_element(sc->stack, top) = (s7_pointer)OP_EVAL_ARGS_SSP_MV; return(args); case OP_SAFE_C_SZ_1: case OP_EVAL_ARGS_P_2: vector_element(sc->stack, top) = (s7_pointer)OP_EVAL_ARGS_P_2_MV; return(args); case OP_EVAL_ARGS_P_3: vector_element(sc->stack, top) = (s7_pointer)OP_EVAL_ARGS_P_3_MV; return(args); case OP_SAFE_C_ZC_1: case OP_EVAL_ARGS_P_4: vector_element(sc->stack, top) = (s7_pointer)OP_EVAL_ARGS_P_4_MV; return(args); case OP_C_P_1: vector_element(sc->stack, top) = (s7_pointer)OP_C_P_2; return(args); case OP_SAFE_CLOSURE_P_1: case OP_CLOSURE_P_1: vector_element(sc->stack, top) = (s7_pointer)OP_CLOSURE_P_2; return(args); case OP_C_SP_1: vector_element(sc->stack, top) = (s7_pointer)OP_C_SP_2; return(args); case OP_SAFE_C_PP_1: vector_element(sc->stack, top) = (s7_pointer)OP_SAFE_C_PP_3; return(args); case OP_SAFE_C_PP_2: vector_element(sc->stack, top) = (s7_pointer)OP_SAFE_C_PP_4; return(args); case OP_SAFE_C_PP_5: vector_element(sc->stack, top) = (s7_pointer)OP_SAFE_C_PP_6; return(args); case OP_EVAL_ARGS5: /* code = previous arg saved, args = ante-previous args reversed * we'll take value->code->args and reverse in args5 * if one value, return it, else * put code onto args, splice as above until there are 2 left * set code to first and value to last */ if (is_null(args)) return(sc->UNSPECIFIED); if (is_null(cdr(args))) return(car(args)); stack_args(sc->stack, top) = cons(sc, stack_code(sc->stack, top), stack_args(sc->stack, top)); for (x = args; is_not_null(cddr(x)); x = cdr(x)) stack_args(sc->stack, top) = cons(sc, car(x), stack_args(sc->stack, top)); stack_code(sc->stack, top) = car(x); return(cadr(x)); /* look for errors here rather than glomming up the set! and let code */ case OP_SET_SAFE: case OP_SET1: /* (set! var (values 1 2 3)) */ set_multiple_value(args); eval_error(sc, "can't set! some variable to ~S", args); case OP_SET_PAIR_P_1: case OP_SET_PAIR_C_P_1: set_multiple_value(args); eval_error(sc, "too many values to set! ~S", args); case OP_LET1: /* (let ((var (values 1 2 3))) ...) */ case OP_LET_ONE_1: case OP_LET_Z_1: set_multiple_value(args); eval_error_with_caller(sc, "~A: can't bind some variable to ~S", sc->LET, args); /* "some variable" is ugly, but the actual name is tricky to find at this point -- * it's in main_stack_args, but finding the right one is a mess. It's isn't sc->code. */ case OP_LET_STAR1: set_multiple_value(args); eval_error_with_caller(sc, "~A: can't bind some variable to ~S", sc->LET_STAR, args); case OP_LETREC1: case OP_LETREC_STAR1: set_multiple_value(args); eval_error_with_caller(sc, "~A: can't bind some variable to ~S", (sc->op == OP_LETREC1) ? sc->LETREC : sc->LETREC_STAR, args); /* handle 'and' and 'or' specially */ case OP_AND1: for (x = args; is_not_null(cdr(x)); x = cdr(x)) if (car(x) == sc->F) return(sc->F); return(car(x)); case OP_OR1: for (x = args; is_not_null(cdr(x)); x = cdr(x)) if (car(x) != sc->F) return(car(x)); return(car(x)); case OP_BARRIER: pop_stack(sc); return(splice_in_values(sc, args)); case OP_BEGIN1: /* here we have a values call with nothing to splice into. So flush it... * otherwise the multiple-values bit gets set in some innocent list and never unset: * :(let ((x '((1 2)))) (eval `(apply apply values x)) x) * ((values 1 2)) * other cases: (+ 1 (begin (values 5 6) (values 2 3)) 4) -> 10 -- the (5 6) is dropped * (let () (values 1 2 3) 4) but (+ (let () (values 1 2))) -> 3 */ return(args); case OP_CATCH: case OP_CATCH_1: case OP_CATCH_2: /* (+ (catch #t (lambda () (values 3 4)) (lambda args args))) */ pop_stack(sc); return(splice_in_values(sc, args)); case OP_EXPANSION: /* we get here if a reader-macro (define-expansion) returned multiple values. * these need to be read in order into the current reader lists (we'll assume OP_READ_LIST is next in the stack. * and that it will be expecting the next arg entry in sc->value). */ pop_stack(sc); top -= 4; for (x = args; is_not_null(cdr(x)); x = cdr(x)) stack_args(sc->stack, top) = cons(sc, car(x), stack_args(sc->stack, top)); return(car(x)); /* sc->value from OP_READ_LIST point of view */ default: break; } /* let it meander back up the call chain until someone knows where to splice it */ set_multiple_value(args); return(args); } s7_pointer s7_values(s7_scheme *sc, s7_pointer args) { #define H_values "(values obj ...) splices its arguments into whatever list holds it (its 'continuation')" #define Q_values s7_make_circular_signature(sc, 1, 2, sc->VALUES, sc->T) if (is_null(args)) /* ((lambda () (let ((x 1)) (set! x (boolean? (values)))))) */ return(sc->NO_VALUE); /* this was sc->NIL until 16-Jun-10, * nil is consistent with the implied values call in call/cc (if no args, the continuation function returns ()) * hmmm... * Guile complains ("too few values returned to continuation") in the call/cc case, and * (equal? (if #f #f) (* (values))) complains "Zero values returned to single-valued continuation" * so perhaps call/cc should also return # -- I don't know what is best. * * a note in the scheme bboard: * This would work in s7: * (define (print-concat . args) * (if (or (null? args) ; (print-concat) * (eq? (car args) (values))) ; (print-concat arg1 ...) * (newline) * (begin * (display (car args)) * (print-concat (apply values (cdr args)))))) * but it's a bit ugly. I think (values) should be the same as * (apply values ()). It's currently #, mainly for * historical reasons (a lot of the code s7 is used with * assumes that behavior). If (values) simply vanished, * then code like (abs -1 (values)) is not an error. */ if (is_null(cdr(args))) return(car(args)); return(splice_in_values(sc, args)); } #define g_values s7_values /* -------------------------------- quasiquote -------------------------------- */ static s7_pointer g_qq_list(s7_scheme *sc, s7_pointer args) { #define H_qq_list "({list} ...) returns its arguments in a list (internal to quasiquote)" #define Q_qq_list pcl_t s7_pointer x, y, px; if (sc->no_values == 0) return(args); for (x = args; is_pair(x); x = cdr(x)) if (car(x) == sc->NO_VALUE) break; if (is_null(x)) return(args); /* this is not maximally efficient, but it's not important: * we've hit the rare special case where ({apply_values} ())) needs to be ignored * in the splicing process (i.e. the arglist acts as if the thing never happened) */ px = sc->NIL; for (x = args, y = args; is_pair(y); y = cdr(y)) if (car(y) != sc->NO_VALUE) { car(x) = car(y); px = x; x = cdr(x); } if ((is_not_null(y)) && (y != sc->NO_VALUE)) cdr(x) = cdr(y); else { sc->no_values--; if (is_null(px)) return(sc->NIL); cdr(px) = sc->NIL; } return(args); } static s7_pointer g_apply_values(s7_scheme *sc, s7_pointer args) { #define H_apply_values "({apply_values} var) applies values to var. This is an internal function." #define Q_apply_values pcl_t s7_pointer x; if (is_null(args)) { sc->no_values++; return(sc->NO_VALUE); } if (is_null(cdr(args))) x = car(args); else x = apply_list_star(sc, args); if (!is_proper_list(sc, x)) return(apply_list_error(sc, args)); if (is_null(x)) { sc->no_values++; return(sc->NO_VALUE); } return(g_values(sc, x)); } /* (apply values ...) replaces (unquote_splicing ...) * * (define-macro (hi a) `(+ 1 ,a) == (list '+ 1 a) * (define-macro (hi a) ``(+ 1 ,,a) == (list list '+ 1 (list quote a))) * * (define-macro (hi a) `(+ 1 ,@a) == (list '+ 1 (apply values a)) * (define-macro (hi a) ``(+ 1 ,,@a) == (list list '+ 1 (apply values a)) * * this is not the same as CL's quasiquote; for example: * [1]> (let ((a 1) (b 2)) `(,a ,@b)) * (1 . 2) * in s7 this is an error. * * also in CL the target of ,@ can apparently be a circular list */ static bool is_simple_code(s7_scheme *sc, s7_pointer form) { s7_pointer tmp; for (tmp = form; is_pair(tmp); tmp = cdr(tmp)) if (is_pair(car(tmp))) { if ((tmp == car(tmp)) || /* try to protect against #1=(#1) -- do we actually need cyclic_sequences here? */ (!is_simple_code(sc, car(tmp)))) return(false); } else { if ((car(tmp) == sc->UNQUOTE) || ((is_null(car(tmp))) && (is_null(cdr(tmp))))) return(false); } return(is_null(tmp)); } static s7_pointer g_quasiquote_1(s7_scheme *sc, s7_pointer form) { #define H_quasiquote "(quasiquote arg) is the same as `arg. If arg is a list, it can contain \ comma (\"unquote\") and comma-atsign (\"apply values\") to pre-evaluate portions of the list. \ unquoted expressions are evaluated and plugged into the list, apply-values evaluates the expression \ and splices the resultant list into the outer list. `(1 ,(+ 1 1) ,@(list 3 4)) -> (1 2 3 4)." #define Q_quasiquote pcl_t if (!is_pair(form)) { if (!is_symbol(form)) { /* things that evaluate to themselves don't need to be quoted. */ return(form); } return(list_2(sc, sc->QUOTE, form)); } if (car(form) == sc->UNQUOTE) { if (is_not_null(cddr(form))) eval_error(sc, "unquote: too many arguments, ~S", form); return(cadr(form)); } /* it's a list, so return the list with each element handled as above. * we try to support dotted lists which makes the code much messier. */ /* if no element of the list is a list or unquote, just return the original quoted */ if (is_simple_code(sc, form)) return(list_2(sc, sc->QUOTE, form)); { int len, i, loc; s7_pointer orig, bq, old_scw; bool dotted = false; len = s7_list_length(sc, form); if (len == 0) { /* a circular form, apparently */ return(list_2(sc, sc->QUOTE, form)); } if (len < 0) { len = -len; dotted = true; } old_scw = sc->w; loc = s7_gc_protect(sc, old_scw); sc->w = sc->NIL; for (i = 0; i <= len; i++) sc->w = cons(sc, sc->NIL, sc->w); car(sc->w) = sc->QQ_List; if (!dotted) { for (orig = form, bq = cdr(sc->w), i = 0; i < len; i++, orig = cdr(orig), bq = cdr(bq)) { if ((is_pair(cdr(orig))) && /* this was is_pair(orig) which seems to be always the case */ (cadr(orig) == sc->UNQUOTE)) { /* `(1 . ,(+ 1 1)) -> '(1 unquote (+ 1 1)) -> '(1 . 2) * `(1 . ,@'((2 3))) -> (1 unquote ({apply_values} '((2 3)))) -> ({append} ({list} 1) ({apply_values} '((2 3)))) -> '(1 2 3) * this used to be `(1 . ,@('(2 3))). * This now becomes (1 unquote ({apply_values} ('(2 3)))) -> ({append} ({list} 1) ({apply_values} ('(2 3)))) -> error * `(1 . (,@'(2 3))) works in both cases, and `(1 . (,(+ 1 1))) */ car(bq) = g_quasiquote_1(sc, car(orig)); cdr(bq) = sc->NIL; sc->w = list_3(sc, sc->QQ_Append, sc->w, caddr(orig)); break; } else car(bq) = g_quasiquote_1(sc, car(orig)); } } else { /* `(1 2 . 3) */ len--; for (orig = form, bq = cdr(sc->w), i = 0; i < len; i++, orig = cdr(orig), bq = cdr(bq)) car(bq) = g_quasiquote_1(sc, car(orig)); car(bq) = g_quasiquote_1(sc, car(orig)); sc->w = list_3(sc, sc->QQ_Append, sc->w, g_quasiquote_1(sc, cdr(orig))); /* quasiquote might quote a symbol in cdr(orig), so it's not completely pointless */ } bq = sc->w; sc->w = old_scw; s7_gc_unprotect_at(sc, loc); return(bq); } } static s7_pointer g_quasiquote(s7_scheme *sc, s7_pointer args) { /* this is for explicit quasiquote support, not the backquote stuff in macros */ return(g_quasiquote_1(sc, car(args))); } /* ---------------- reader funcs for eval ---------------- */ static void back_up_stack(s7_scheme *sc) { opcode_t top_op; top_op = stack_op(sc->stack, s7_stack_top(sc) - 1); if (top_op == OP_READ_DOT) { pop_stack(sc); top_op = stack_op(sc->stack, s7_stack_top(sc) - 1); } if ((top_op == OP_READ_VECTOR) || (top_op == OP_READ_BYTE_VECTOR)) { pop_stack(sc); top_op = stack_op(sc->stack, s7_stack_top(sc) - 1); } if (top_op == OP_READ_QUOTE) pop_stack(sc); } static token_t read_sharp(s7_scheme *sc, s7_pointer pt) { int c; /* inchar can return EOF, so it can't be used directly as an index into the digits array */ c = inchar(pt); switch (c) { case EOF: s7_error(sc, sc->READ_ERROR, set_elist_1(sc, make_string_wrapper(sc, "unexpected '#' at end of input"))); break; case '(': sc->w = small_int(1); return(TOKEN_VECTOR); case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { /* here we can get an overflow: #1231231231231232131D() * and we can't shrug it off: * :#2147483649123D() * ;#nD(...) dimensions argument 1, -2147483647, is out of range (must be 1 or more) * but * :#2147483649123D() * creates a vector with 512 dimensions! * ndims in the vector struct is an unsigned int, so we'll complain if it goes over short max for now */ s7_int dims; int d, loc = 0; sc->strbuf[loc++] = c; dims = digits[c]; while (true) { s7_int dig; d = inchar(pt); if (d == EOF) s7_error(sc, sc->READ_ERROR, set_elist_1(sc, make_string_wrapper(sc, "unexpected end of input while reading #n..."))); dig = digits[d]; if (dig >= 10) break; dims = dig + (dims * 10); if ((dims <= 0) || (dims > S7_SHORT_MAX)) s7_error(sc, sc->READ_ERROR, set_elist_2(sc, make_string_wrapper(sc, "overflow while reading #nD: ~A"), make_integer(sc, dims))); sc->strbuf[loc++] = d; } sc->strbuf[loc++] = d; if ((d == 'D') || (d == 'd')) { d = inchar(pt); if (d == EOF) s7_error(sc, sc->READ_ERROR, set_elist_1(sc, make_string_wrapper(sc, "unexpected end of input while reading #nD..."))); sc->strbuf[loc++] = d; if (d == '(') { sc->w = make_integer(sc, dims); return(TOKEN_VECTOR); } } /* try to back out */ for (d = loc - 1; d > 0; d--) backchar(sc->strbuf[d], pt); } break; case 'u': { int d; d = inchar(pt); if (d == EOF) s7_error(sc, sc->READ_ERROR, set_elist_1(sc, make_string_wrapper(sc, "unexpected end of input while reading #u..."))); if (d == '8') { d = inchar(pt); if (d == EOF) s7_error(sc, sc->READ_ERROR, set_elist_1(sc, make_string_wrapper(sc, "unexpected end of input while reading #u8..."))); if (d == '(') return(TOKEN_BYTE_VECTOR); backchar(d, pt); backchar('8', pt); } else backchar(d, pt); } break; case ':': /* turn #: into : -- this is for compatibility with Guile, #:optional in particular. * I just noticed that Rick is using this -- I'll just leave it alone. * but that means : readers need to handle this case specially. * I don't think #! is special anymore -- maybe remove that code? */ sc->strbuf[0] = ':'; return(TOKEN_ATOM); /* block comments in #! ... !# */ /* this is needed when an input file is treated as a script: #!/home/bil/cl/snd !# (format #t "a test~%") (exit) * but very often the closing !# is omitted which is too bad */ case '!': { char last_char; s7_pointer reader; /* make it possible to override #! handling */ for (reader = slot_value(sc->sharp_readers); is_pair(reader); reader = cdr(reader)) if (s7_character(caar(reader)) == '!') { sc->strbuf[0] = c; return(TOKEN_SHARP_CONST); /* next stage notices any errors */ } /* not #! as block comment (for Guile I guess) */ last_char = ' '; while ((c = inchar(pt)) != EOF) { if ((c == '#') && (last_char == '!')) break; last_char = c; } if (c == EOF) s7_error(sc, sc->READ_ERROR, set_elist_1(sc, make_string_wrapper(sc, "unexpected end of input while reading #!"))); return(token(sc)); } /* block comments in #| ... |# * since we ignore everything until the |#, internal semicolon comments are ignored, * meaning that ;|# is as effective as |# */ case '|': { if (is_file_port(pt)) { char last_char; last_char = ' '; while (true) { c = fgetc(port_file(pt)); if (c == EOF) s7_error(sc, sc->READ_ERROR, set_elist_1(sc, make_string_wrapper(sc, "unexpected end of input while reading #|"))); if ((c == '#') && (last_char == '|')) break; last_char = c; if (c == '\n') port_line_number(pt)++; } return(token(sc)); } else { const char *str, *orig_str, *p, *pend; orig_str = (const char *)(port_data(pt) + port_position(pt)); pend = (const char *)(port_data(pt) + port_data_size(pt)); str = orig_str; while (true) { p = strchr(str, (int)'|'); if ((!p) || (p >= pend)) { port_position(pt) = port_data_size(pt); s7_error(sc, sc->READ_ERROR, set_elist_1(sc, make_string_wrapper(sc, "unexpected end of input while reading #|"))); } if (p[1] == '#') break; str = (const char *)(p + 1); } port_position(pt) += (p - orig_str + 2); /* now count newline inside the comment */ str = (const char *)orig_str; pend = p; while (true) { p = strchr(str, (int)'\n'); if ((p) && (p < pend)) { port_line_number(pt)++; str = (char *)(p + 1); } else break; } return(token(sc)); } } } sc->strbuf[0] = c; return(TOKEN_SHARP_CONST); /* next stage notices any errors */ } static token_t read_comma(s7_scheme *sc, s7_pointer pt) { int c; /* here we probably should check for symbol names that start with "@": :(define-macro (hi @foo) `(+ ,@foo 1)) hi :(hi 2) ;foo: unbound variable but :(define-macro (hi .foo) `(+ ,.foo 1)) hi :(hi 2) 3 and ambiguous: :(define-macro (hi @foo . foo) `(list ,@foo)) what about , @foo -- is the space significant? We accept ,@ foo. */ if ((c = inchar(pt)) == '@') return(TOKEN_AT_MARK); if (c == EOF) { sc->strbuf[0] = ','; /* was '@' which doesn't make any sense */ return(TOKEN_COMMA); /* was TOKEN_ATOM, which also doesn't seem sensible */ } backchar(c, pt); return(TOKEN_COMMA); } static token_t read_dot(s7_scheme *sc, s7_pointer pt) { int c; c = inchar(pt); if (c != EOF) { backchar(c, pt); if ((!char_ok_in_a_name[c]) && (c != 0)) return(TOKEN_DOT); } else { sc->strbuf[0] = '.'; return(TOKEN_DOT); } sc->strbuf[0] = '.'; return(TOKEN_ATOM); /* i.e. something that can start with a dot like a number */ } static token_t token(s7_scheme *sc) { int c; c = port_read_white_space(sc->input_port)(sc, sc->input_port); switch (c) { case '(': return(TOKEN_LEFT_PAREN); case ')': return(TOKEN_RIGHT_PAREN); case '.': return(read_dot(sc, sc->input_port)); case '\'': return(TOKEN_QUOTE); case ';': return(port_read_semicolon(sc->input_port)(sc, sc->input_port)); case '"': return(TOKEN_DOUBLE_QUOTE); case '`': return(TOKEN_BACK_QUOTE); case ',': return(read_comma(sc, sc->input_port)); case '#': return(read_sharp(sc, sc->input_port)); case '\0': case EOF: return(TOKEN_EOF); default: sc->strbuf[0] = c; /* every TOKEN_ATOM return goes to port_read_name, so we save a backchar/inchar shuffle by starting the read here */ return(TOKEN_ATOM); } } #define NOT_AN_X_CHAR -1 static int read_x_char(s7_pointer pt) { /* possible "\xnn" char (write creates these things, so we have to read them) * but we could have crazy input like "\x -- with no trailing double quote */ int d1, c; c = inchar(pt); if (c == EOF) return(NOT_AN_X_CHAR); d1 = digits[c]; if (d1 < 16) { int d2; c = inchar(pt); if (c == EOF) return(NOT_AN_X_CHAR); d2 = digits[c]; if (d2 < 16) return(16 * d1 + d2); /* following char can be anything, including a number -- we ignore it */ /* apparently one digit is also ok */ backchar(c, pt); return(d1); } return(NOT_AN_X_CHAR); } static s7_pointer read_string_constant(s7_scheme *sc, s7_pointer pt) { /* sc->F => error * no check needed here for bad input port and so on */ unsigned int i = 0; if (is_string_port(pt)) { /* try the most common case first */ char *s, *start, *end; start = (char *)(port_data(pt) + port_position(pt)); if (*start == '"') { port_position(pt)++; return(make_empty_string(sc, 0, 0)); } end = (char *)(port_data(pt) + port_data_size(pt)); s = strpbrk(start, "\"\n\\"); if ((!s) || (s >= end)) /* can this read a huge string constant from a file? */ { if (start == end) sc->strbuf[0] = '\0'; else memcpy((void *)(sc->strbuf), (void *)start, (end - start > 8) ? 8 : (end - start)); sc->strbuf[8] = '\0'; return(sc->F); } if (*s == '"') { int len; len = s - start; port_position(pt) += (len + 1); return(s7_make_string_with_length(sc, start, len)); } for (; s < end; s++) { if (*s == '"') /* switch here no faster */ { int len; len = s - start; port_position(pt) += (len + 1); return(s7_make_string_with_length(sc, start, len)); } else { if (*s == '\\') { /* all kinds of special cases here (resultant string is not the current string), so drop to loop below (setting "i") */ unsigned int len; len = (unsigned int)(s - start); if (len > 0) { if (len >= sc->strbuf_size) resize_strbuf(sc, len); /* for (i = 0; i < len; i++) sc->strbuf[i] = port_data(pt)[port_position(pt)++]; */ memcpy((void *)(sc->strbuf), (void *)(port_data(pt) + port_position(pt)), len); port_position(pt) += len; } i = len; break; } else { if (*s == '\n') port_line_number(pt)++; } } } } while (true) { /* splitting this check out and duplicating the loop was slower?!? */ int c; c = port_read_character(pt)(sc, pt); switch (c) { case '\n': port_line_number(pt)++; sc->strbuf[i++] = c; break; case EOF: sc->strbuf[(i > 8) ? 8 : i] = '\0'; return(sc->F); case '"': return(s7_make_string_with_length(sc, sc->strbuf, i)); case '\\': c = inchar(pt); if (c == EOF) { sc->strbuf[(i > 8) ? 8 : i] = '\0'; return(sc->F); } if ((c == '\\') || (c == '"') || (c == '|')) sc->strbuf[i++] = c; else { if (c == 'n') sc->strbuf[i++] = '\n'; else { if (c == 't') /* this is for compatibility with other Schemes */ sc->strbuf[i++] = '\t'; else { if (c == 'x') { c = read_x_char(pt); if (c == NOT_AN_X_CHAR) return(sc->T); sc->strbuf[i++] = (unsigned char)c; } else { /* if (!is_white_space(c)) */ /* changed 8-Apr-12 */ if ((c != '\n') && (c != '\r')) return(sc->T); /* #f here would give confusing error message "end of input", so return #t=bad backslash. * this is not optimal. It's easy to forget that backslash needs to be backslashed. * * the white_space business half-implements Scheme's \...... or \...... * feature -- the characters after \ are flushed if they're all white space and include a newline. * (string->number "1\ 2") is 12?? Too bizarre. */ } } } } break; default: sc->strbuf[i++] = c; break; } if (i >= sc->strbuf_size) resize_strbuf(sc, i); } } static s7_pointer read_expression(s7_scheme *sc) { while (true) { int c; switch (sc->tok) { case TOKEN_EOF: return(sc->EOF_OBJECT); case TOKEN_BYTE_VECTOR: push_stack_no_code(sc, OP_READ_BYTE_VECTOR, sc->NIL); sc->tok = TOKEN_LEFT_PAREN; break; case TOKEN_VECTOR: /* already read #( -- TOKEN_VECTOR is triggered by #( */ push_stack_no_code(sc, OP_READ_VECTOR, sc->w); /* sc->w is the dimensions */ /* fall through */ case TOKEN_LEFT_PAREN: sc->tok = token(sc); if (sc->tok == TOKEN_RIGHT_PAREN) return(sc->NIL); if (sc->tok == TOKEN_DOT) { back_up_stack(sc); do {c = inchar(sc->input_port);} while ((c != ')') && (c != EOF)); return(read_error(sc, "stray dot after '('?")); /* (car '( . )) */ } if (sc->tok == TOKEN_EOF) return(missing_close_paren_error(sc)); push_stack_no_code(sc, OP_READ_LIST, sc->NIL); /* here we need to clear args, but code is ignored */ check_stack_size(sc); break; case TOKEN_QUOTE: push_stack_no_code(sc, OP_READ_QUOTE, sc->NIL); sc->tok = token(sc); break; case TOKEN_BACK_QUOTE: sc->tok = token(sc); #if WITH_QUASIQUOTE_VECTOR if (sc->tok == TOKEN_VECTOR) { push_stack_no_code(sc, OP_READ_QUASIQUOTE_VECTOR, sc->w); sc->tok = TOKEN_LEFT_PAREN; } else #endif push_stack_no_code(sc, OP_READ_QUASIQUOTE, sc->NIL); break; case TOKEN_COMMA: push_stack_no_code(sc, OP_READ_UNQUOTE, sc->NIL); sc->tok = token(sc); break; case TOKEN_AT_MARK: push_stack_no_code(sc, OP_READ_APPLY_VALUES, sc->NIL); sc->tok = token(sc); break; case TOKEN_ATOM: return(port_read_name(sc->input_port)(sc, sc->input_port)); /* If reading list (from lparen), this will finally get us to op_read_list */ case TOKEN_DOUBLE_QUOTE: sc->value = read_string_constant(sc, sc->input_port); if (sc->value == sc->F) /* can happen if input code ends in the middle of a string */ return(string_read_error(sc, "end of input encountered while in a string")); if (sc->value == sc->T) return(read_error(sc, "unknown backslash usage -- perhaps you meant two backslashes?")); return(sc->value); case TOKEN_SHARP_CONST: sc->value = port_read_sharp(sc->input_port)(sc, sc->input_port); /* here we need the following character and form * strbuf[0] == '#', false above = # case, not an atom */ if (is_null(sc->value)) { return(read_error(sc, "undefined # expression")); /* a read error here seems draconian -- this unknown constant doesn't otherwise get in our way * but how to alert the caller to the problem without stopping the read? */ } return(sc->value); case TOKEN_DOT: /* (catch #t (lambda () (+ 1 . . )) (lambda args 'hiho)) */ back_up_stack(sc); do {c = inchar(sc->input_port);} while ((c != ')') && (c != EOF)); return(read_error(sc, "stray dot in list?")); /* (+ 1 . . ) */ case TOKEN_RIGHT_PAREN: /* (catch #t (lambda () '(1 2 . )) (lambda args 'hiho)) */ back_up_stack(sc); return(read_error(sc, "unexpected close paren")); /* (+ 1 2)) or (+ 1 . ) */ } } /* we never get here */ return(sc->NIL); } /* ---------------- *unbound-variable-hook* ---------------- */ static s7_pointer loaded_library(s7_scheme *sc, const char *file) { s7_pointer p; for (p = slot_value(sc->libraries); is_pair(p); p = cdr(p)) if (local_strcmp(file, string_value(caar(p)))) return(cdar(p)); return(sc->NIL); } static s7_pointer find_closure_let(s7_scheme *sc, s7_pointer cur_env) { s7_pointer e; for (e = cur_env; is_let(e); e = outlet(e)) if (is_function_env(e)) return(e); return(sc->NIL); } static s7_pointer unbound_variable(s7_scheme *sc, s7_pointer sym) { /* this always occurs in a context where we're trying to find anything, so I'll move a couple of those checks here */ if (has_ref_fallback(sc->envir)) /* an experiment -- see s7test (with-let *db* (+ int (length str))) */ check_method(sc, sc->envir, sc->LET_REF_FALLBACK, sc->w = list_2(sc, sc->envir, sym)); /* but if the thing we want to hit this fallback happens to exist at a higher level, oops... */ if (sym == sc->UNQUOTE) eval_error(sc, "unquote (',') occurred outside quasiquote: ~S", sc->cur_code); if (sym == sc->__FUNC__) /* __func__ is a sort of symbol macro */ { s7_pointer env; env = find_closure_let(sc, sc->envir); if (is_let(env)) { /* for C-defined things like hooks and dilambda, let_file and let_line are 0 */ if ((let_file(env) > 0) && (let_file(env) < (s7_int)sc->file_names_top) && /* let_file(env) might be > int */ (let_line(env) > 0)) return(list_3(sc, funclet_function(env), sc->file_names[let_file(env)], make_integer(sc, let_line(env)))); return(funclet_function(env)); } return(sc->UNDEFINED); } if (safe_strcmp(symbol_name(sym), "|#")) return(read_error(sc, "unmatched |#")); /* check *autoload*, autoload_names, then *unbound-variable-hook* */ if ((sc->autoload_names) || (is_hash_table(sc->autoload_table)) || (is_not_null(s7_hook_functions(sc, sc->unbound_variable_hook)))) { s7_pointer result, cur_code, value, code, args, cur_env, x, z; /* sc->args and sc->code are pushed on the stack by s7_call, then * restored by eval, so they are normally protected, but sc->value and sc->cur_code are * not protected (yet). We need sc->cur_code so that the possible eventual error * call can tell where the error occurred, and we need sc->value because it might * be awaiting addition to sc->args in e.g. OP_EVAL_ARGS5, and then be clobbered * by the hook function. (+ 1 asdf) will end up evaluating (+ asdf asdf) if sc->value * is not protected. We also need to save/restore sc->envir in case s7_load is called. */ args = sc->args; code = sc->code; value = sc->value; cur_code = sc->cur_code; cur_env = sc->envir; result = sc->UNDEFINED; x = sc->x; z = sc->z; sc->temp7 = s7_list(sc, 6, code, args, value, cur_code, x, z); if (!is_pair(cur_code)) { /* isolated typo perhaps -- no pair to hold the position info, so make one. * sc->cur_code is GC-protected, so this should be safe. */ cur_code = cons(sc, sym, sc->NIL); /* the error will say "(sym)" which is not too misleading */ pair_set_line(cur_code, remember_location(port_line_number(sc->input_port), port_file_number(sc->input_port))); set_has_line_number(cur_code); } /* check sc->autoload_names */ if (sc->autoload_names) { const char *file; bool loaded = false; file = find_autoload_name(sc, sym, &loaded, true); if ((file) && (!loaded)) { s7_pointer e; /* if we've already loaded this file, we can get the library (e) from a table [(file lib) ...] * here it was possible to get caught in a loop: * change file, reload, unbound var seen, check autoload, it says "load file"... (where file does not get added to *libraries*) * so the "loaded" arg tries to catch such cases */ e = loaded_library(sc, file); if (!is_let(e)) e = s7_load(sc, file); result = s7_symbol_value(sc, sym); /* calls find_symbol, does not trigger unbound_variable search */ if ((result == sc->UNDEFINED) && (is_let(e))) { result = s7_let_ref(sc, e, sym); /* I think to be consistent we should add '(sym . result) to the global env */ if (result != sc->UNDEFINED) s7_define(sc, sc->NIL, sym, result); } } } if (result == sc->UNDEFINED) { /* check the *autoload* hash table */ if (is_hash_table(sc->autoload_table)) { s7_pointer val; /* it was possible to get in a loop here: missing paren in x.scm, checks last symbol, sees * autoload sym -> x.scm, loads x.scm, missing paren... */ val = s7_hash_table_ref(sc, sc->autoload_table, sym); if (is_string(val)) /* val should be a filename. *load-path* is searched if necessary. */ s7_load(sc, string_value(val)); else { if (is_closure(val)) /* val should be a function of one argument, the current (calling) environment */ s7_call(sc, val, s7_cons(sc, sc->envir, sc->NIL)); } result = s7_symbol_value(sc, sym); /* calls find_symbol, does not trigger unbound_variable search */ } /* check *unbound-variable-hook* */ if ((result == sc->UNDEFINED) && (is_not_null(sc->unbound_variable_hook))) { /* (let () (set! (hook-functions *unbound-variable-hook*) (list (lambda (v) _asdf_))) _asdf_) */ s7_pointer old_hook; old_hook = sc->unbound_variable_hook; car(sc->Z2_1) = old_hook; sc->unbound_variable_hook = sc->error_hook; /* avoid the infinite loop mentioned above */ result = s7_call(sc, old_hook, list_1(sc, sym)); /* not s7_apply_function */ sc->unbound_variable_hook = old_hook; } } sc->value = _NFre(value); sc->cur_code = cur_code; sc->args = args; sc->code = code; sc->envir = cur_env; sc->x = x; sc->z = z; sc->temp7 = sc->NIL; if ((result != sc->UNDEFINED) && (result != sc->UNSPECIFIED)) return(result); } eval_error(sc, "~A: unbound variable", sym); } static s7_pointer assign_syntax(s7_scheme *sc, const char *name, opcode_t op, s7_pointer min_args, s7_pointer max_args, const char *doc) { s7_pointer x, syn; unsigned long long int hash; unsigned int loc; hash = raw_string_hash((const unsigned char *)name, safe_strlen(name)); loc = hash % SYMBOL_TABLE_SIZE; x = new_symbol(sc, name, safe_strlen(name), hash, loc); syn = alloc_pointer(); unheap(syn); set_type(syn, T_SYNTAX | T_SYNTACTIC | T_DONT_EVAL_ARGS); syntax_opcode(syn) = op; syntax_symbol(syn) = x; syntax_min_args(syn) = integer(min_args); syntax_max_args(syn) = ((max_args == max_arity) ? -1 : integer(max_args)); syntax_documentation(syn) = s7_make_permanent_string(doc); syntax_rp(syn) = NULL; syntax_ip(syn) = NULL; syntax_pp(syn) = NULL; global_slot(x) = permanent_slot(x, syn); initial_slot(x) = permanent_slot(x, syn); typeflag(x) = SYNTACTIC_TYPE; symbol_set_local(x, 0LL, sc->NIL); symbol_syntax_op(x) = op; return(x); } static s7_pointer assign_internal_syntax(s7_scheme *sc, const char *name, opcode_t op) { s7_pointer x, str, syn; s7_pointer symbol, old_syn; symbol = s7_make_symbol(sc, name); old_syn = slot_value(global_slot(symbol)); str = s7_make_permanent_string(name); x = alloc_pointer(); unheap(x); set_type(x, T_SYMBOL); set_symbol_name_cell(x, str); symbol_set_local(x, 0LL, sc->NIL); symbol_syntax_op(x) = op; syn = alloc_pointer(); heap_location(syn) = heap_location(old_syn); set_type(syn, T_SYNTAX | T_SYNTACTIC | T_DONT_EVAL_ARGS); syntax_opcode(syn) = op; syntax_symbol(syn) = symbol; syntax_min_args(syn) = syntax_min_args(old_syn); syntax_max_args(syn) = syntax_max_args(old_syn); syntax_documentation(syn) = syntax_documentation(old_syn); syntax_rp(syn) = syntax_rp(old_syn); syntax_ip(syn) = syntax_ip(old_syn); syntax_pp(syn) = syntax_pp(old_syn); global_slot(x) = permanent_slot(x, syn); initial_slot(x) = permanent_slot(x, syn); typeflag(x) = SYNTACTIC_TYPE; return(x); } static s7_int c_pair_line_number(s7_scheme *sc, s7_pointer p) { if (!is_pair(p)) int_method_or_bust(sc, p, sc->PAIR_LINE_NUMBER, set_plist_1(sc, p), T_PAIR, 0); if (has_line_number(p)) { unsigned int x; x = pair_line(p); return(remembered_line_number(x)); } return(0); } static s7_pointer g_pair_line_number(s7_scheme *sc, s7_pointer args) { #define H_pair_line_number "(pair-line-number pair) returns the line number at which it read 'pair'" #define Q_pair_line_number s7_make_signature(sc, 2, sc->IS_INTEGER, sc->IS_PAIR) return(make_integer(sc, c_pair_line_number(sc, car(args)))); } PF_TO_IF(pair_line_number, c_pair_line_number) static s7_pointer lambda_star_argument_set_value(s7_scheme *sc, s7_pointer sym, s7_pointer val) { s7_pointer x; for (x = let_slots(sc->envir) /* presumably the arglist */; is_slot(x); x = next_slot(x)) if (slot_symbol(x) == sym) { /* x is our binding (symbol . value) */ if (is_not_checked_slot(x)) set_checked_slot(x); /* this is a special use of this bit, I think */ else return(s7_error(sc, sc->WRONG_TYPE_ARG, set_elist_4(sc, make_string_wrapper(sc, "~A: parameter set twice, ~S in ~S"), closure_name(sc, sc->code), sym, sc->args))); slot_set_value(x, val); return(val); } return(sc->NO_VALUE); } static s7_pointer lambda_star_set_args(s7_scheme *sc) { /* sc->code is a closure: ((args body) envir) * (define* (hi a (b 1)) (+ a b)) * (procedure-source hi) -> (lambda* (a (b 1)) (+ a b)) * * so rather than spinning through the args binding names to values in the * procedure's new environment (as in the usual closure case above), * we scan the current args, and match against the * template in the car of the closure, binding as we go. * * for each actual arg, if it's not a keyword that matches a member of the * template, bind it to its current (place-wise) arg, else bind it to * that arg. If it's the symbol :key or :optional, just go on. * If it's :rest bind the next arg to the trailing args at this point. * All args can be accessed by their name as a keyword. * In other words (define* (hi (a 1)) ...) is the same as (define* (hi :key (a 1)) ...) etc. * * all args are optional, any arg with no default value defaults to #f. * but the rest arg should default to (). * I later decided to add two warnings: if a parameter is set twice and if * an unknown keyword is seen in a keyword position and there is no rest arg. * * :key and :optional are just noise words, so these have already been spliced out of the arg list */ bool allow_other_keys; s7_pointer lx, cx, zx; /* get the current args, re-setting args that have explicit values */ cx = closure_args(sc->code); allow_other_keys = ((is_pair(cx)) && (allows_other_keys(cx))); lx = sc->args; zx = sc->NIL; while ((is_pair(cx)) && (is_pair(lx))) { if (car(cx) == sc->KEY_REST) /* the rest arg */ { /* next arg is bound to trailing args from this point as a list */ zx = sc->KEY_REST; cx = cdr(cx); if (is_pair(car(cx))) lambda_star_argument_set_value(sc, caar(cx), lx); else lambda_star_argument_set_value(sc, car(cx), lx); lx = cdr(lx); cx = cdr(cx); } else { /* mock-symbols introduce an ambiguity here; if the object's value is a keyword, is that * intended to be used as an argument name or value? */ s7_pointer car_lx; car_lx = car(lx); if (has_methods(car_lx)) car_lx = check_values(sc, car_lx, lx); if ((is_pair(cdr(lx))) && (is_keyword(car_lx))) { /* char *name; */ /* found a keyword, check the lambda args via the corresponding symbol */ s7_pointer sym; sym = keyword_symbol(car_lx); if (lambda_star_argument_set_value(sc, sym, car(cdr(lx))) == sc->NO_VALUE) { /* if default value is a key, go ahead and use this value. * (define* (f (a :b)) a) (f :c) * this has become much trickier than I anticipated... */ if (allow_other_keys) { /* in CL: (defun hi (&key (a 1) &allow-other-keys) a) (hi :b :a :a 3) -> 3 * in s7: (define* (hi (a 1) :allow-other-keys) a) (hi :b :a :a 3) -> 3 */ lx = cddr(lx); continue; } else { if ((is_pair(car(cx))) && (is_keyword(cadar(cx)))) { /* cx is the closure args list, not the copy of it in the curlet */ s7_pointer x; x = find_symbol(sc, caar(cx)); if (is_slot(x)) { if (is_not_checked_slot(x)) { set_checked_slot(x); slot_set_value(x, car(lx)); } else { /* this case is not caught yet: ((lambda* (a :optional b :allow-other-keys ) a) :b 1 :c :a :a ) */ return(s7_error(sc, sc->WRONG_TYPE_ARG, set_elist_4(sc, make_string_wrapper(sc, "~A: parameter set twice, ~S in ~S"), closure_name(sc, sc->code), lx, sc->args))); } } else { return(s7_error(sc, sc->WRONG_TYPE_ARG, set_elist_4(sc, make_string_wrapper(sc, "~A: unknown key: ~S in ~S"), closure_name(sc, sc->code), lx, sc->args))); } /* (define* (f a (b :c)) b) (f :b 1 :d) */ } else { return(s7_error(sc, sc->WRONG_TYPE_ARG, set_elist_4(sc, make_string_wrapper(sc, "~A: unknown key: ~S in ~S"), closure_name(sc, sc->code), lx, sc->args))); } } } lx = cdr(lx); if (is_pair(lx)) lx = cdr(lx); } else /* not a key/value pair */ { /* this is always a positional (i.e. direct) change, but the closure_args are in the * definition order whereas currently the environment slots are in reverse order. */ if (is_pair(car(cx))) lambda_star_argument_set_value(sc, caar(cx), car(lx)); else lambda_star_argument_set_value(sc, car(cx), car(lx)); lx = cdr(lx); } cx = cdr(cx); } } /* (let () (define* (hi (a 1) :allow-other-keys) a) (hi :a 2 32)) */ /* (let () (define* (f (a :b)) a) (list (f) (f 1) (f :c) (f :a :c) (f :a 1) (f))) */ /* check for trailing args with no :rest arg */ if (is_not_null(lx)) { if ((is_not_null(cx)) || (zx == sc->KEY_REST)) { if (is_symbol(cx)) make_slot_1(sc, sc->envir, cx, lx); } else { if (!allow_other_keys) /* ((lambda* (a) a) :a 1 2) */ return(s7_error(sc, sc->WRONG_NUMBER_OF_ARGS, set_elist_3(sc, sc->TOO_MANY_ARGUMENTS, closure_name(sc, sc->code), sc->args))); else { /* check trailing args for repeated keys or keys with no values or values with no keys */ while (is_pair(lx)) { if ((!is_keyword(car(lx))) || /* ((lambda* (a :allow-other-keys) a) :a 1 :b 2 3) */ (!is_pair(cdr(lx)))) /* ((lambda* (a :allow-other-keys) a) :a 1 :b) */ return(s7_error(sc, sc->WRONG_TYPE_ARG, set_elist_3(sc, make_string_wrapper(sc, "~A: not a key/value pair: ~S"), closure_name(sc, sc->code), lx))); /* errors not caught? * ((lambda* (a :allow-other-keys) a) :a 1 :a 2) * ((lambda* (:allow-other-keys ) #f) :b :a :a :b) * ((lambda* (:key b :allow-other-keys ) b) 1 :b 2) */ lx = cddr(lx); } } } } return(sc->NIL); } static s7_pointer is_pair_car, is_pair_cdr, is_pair_cadr; static s7_pointer g_is_pair_car(s7_scheme *sc, s7_pointer args) { s7_pointer val; val = find_symbol_checked(sc, cadar(args)); if (!is_pair(val)) /* (define (tst) (let ((a 123)) (pair? (car a)))) */ return(g_is_pair(sc, list_1(sc, g_car(sc, set_plist_1(sc, val))))); return(make_boolean(sc, is_pair(car(val)))); } static s7_pointer g_is_pair_cdr(s7_scheme *sc, s7_pointer args) { s7_pointer val; val = find_symbol_checked(sc, cadar(args)); if (!is_pair(val)) return(g_is_pair(sc, list_1(sc, g_cdr(sc, set_plist_1(sc, val))))); return(make_boolean(sc, is_pair(cdr(val)))); } static s7_pointer g_is_pair_cadr(s7_scheme *sc, s7_pointer args) { s7_pointer val; val = find_symbol_checked(sc, cadar(args)); if (!is_pair(val)) return(g_is_pair(sc, list_1(sc, g_cadr(sc, set_plist_1(sc, val))))); return(make_boolean(sc, is_pair(cadr(val)))); } static s7_pointer is_pair_chooser(s7_scheme *sc, s7_pointer f, int args, s7_pointer expr) { if ((is_optimized(cadr(expr))) && (optimize_op(cadr(expr)) == HOP_SAFE_C_S)) { s7_function g; g = c_callee(cadr(expr)); if (g == g_car) { set_optimize_op(expr, HOP_SAFE_C_C); return(is_pair_car); } if (g == g_cdr) { set_optimize_op(expr, HOP_SAFE_C_C); return(is_pair_cdr); } if (g == g_cadr) { set_optimize_op(expr, HOP_SAFE_C_C); return(is_pair_cadr); } } return(f); } static s7_pointer is_null_cdr; static s7_pointer g_is_null_cdr(s7_scheme *sc, s7_pointer args) { s7_pointer val; val = find_symbol_checked(sc, cadar(args)); if (!is_pair(val)) return(g_is_null(sc, list_1(sc, g_cdr(sc, set_plist_1(sc, val))))); return(make_boolean(sc, is_null(cdr(val)))); } static s7_pointer is_null_chooser(s7_scheme *sc, s7_pointer f, int args, s7_pointer expr) { if (is_h_safe_c_s(cadr(expr))) { s7_function g; g = c_callee(cadr(expr)); if (g == g_cdr) { set_optimize_op(expr, HOP_SAFE_C_C); return(is_null_cdr); } } return(f); } static s7_pointer format_allg, format_allg_no_column, format_just_newline; static s7_pointer g_format_allg(s7_scheme *sc, s7_pointer args) { return(g_format_1(sc, args)); } static s7_pointer g_format_just_newline(s7_scheme *sc, s7_pointer args) { s7_pointer pt, str; pt = car(args); str = cadr(args); if (pt == sc->F) return(s7_make_string_with_length(sc, string_value(str), string_length(str))); if (pt == sc->T) { if (sc->output_port != sc->F) port_write_string(sc->output_port)(sc, string_value(str), string_length(str), sc->output_port); return(s7_make_string_with_length(sc, string_value(str), string_length(str))); } if ((!is_output_port(pt)) || (port_is_closed(pt))) method_or_bust_with_type(sc, pt, sc->FORMAT, args, A_FORMAT_PORT, 1); port_write_string(pt)(sc, string_value(str), string_length(str), pt); return(sc->F); } static s7_pointer g_format_allg_no_column(s7_scheme *sc, s7_pointer args) { s7_pointer pt, str; pt = car(args); if (is_null(pt)) pt = sc->output_port; if (!((s7_is_boolean(pt)) || ((is_output_port(pt)) && /* (current-output-port) or call-with-open-file arg, etc */ (!port_is_closed(pt))))) method_or_bust_with_type(sc, pt, sc->FORMAT, args, A_FORMAT_PORT, 1); str = cadr(args); sc->format_column = 0; return(format_to_port_1(sc, (pt == sc->T) ? sc->output_port : pt, string_value(str), cddr(args), NULL, !is_output_port(pt), /* i.e. is boolean port so we're returning a string */ false, /* we checked in advance that it is not columnized */ string_length(str), str)); } static s7_pointer format_chooser(s7_scheme *sc, s7_pointer f, int args, s7_pointer expr) { s7_pointer port, str_arg; port = cadr(expr); str_arg = caddr(expr); if ((args > 1) && (!is_string(port)) && (is_string(str_arg))) { if (args == 2) { int len; char *orig; const char *p; orig = string_value(str_arg); p = strchr((const char *)orig, (int)'~'); if (!p) { if (s7_is_boolean(port)) set_optimize_op(expr, HOP_SAFE_C_C); return(format_just_newline); /* "just_newline" actually just outputs the control string -- see fixup below */ } len = string_length(str_arg); if ((len > 1) && (orig[len - 1] == '%') && ((p - orig) == len - 2)) { orig[len - 2] = '\n'; orig[len - 1] = '\0'; string_length(str_arg) = len - 1; if (s7_is_boolean(port)) set_optimize_op(expr, HOP_SAFE_C_C); return(format_just_newline); } } /* this used to worry about optimized expr and particular cases -- why? I can't find a broken case */ if (!is_columnizing(string_value(str_arg))) return(format_allg_no_column); return(format_allg); } return(f); } static s7_pointer is_eq_car, is_eq_car_q, is_eq_caar_q; static s7_pointer g_is_eq_car(s7_scheme *sc, s7_pointer args) { s7_pointer lst, val; lst = find_symbol_checked(sc, cadar(args)); val = find_symbol_checked(sc, cadr(args)); if (!is_pair(lst)) return(g_is_eq(sc, set_plist_2(sc, g_car(sc, list_1(sc, lst)), val))); return(make_boolean(sc, car(lst) == val)); } static s7_pointer g_is_eq_car_q(s7_scheme *sc, s7_pointer args) { s7_pointer lst; lst = find_symbol_checked(sc, cadar(args)); if (!is_pair(lst)) return(g_is_eq(sc, set_plist_2(sc, g_car(sc, set_plist_1(sc, lst)), cadr(cadr(args))))); return(make_boolean(sc, car(lst) == cadr(cadr(args)))); } static s7_pointer g_is_eq_caar_q(s7_scheme *sc, s7_pointer args) { s7_pointer lst; lst = find_symbol_checked(sc, cadar(args)); if (!is_pair(lst)) return(g_is_eq(sc, set_plist_2(sc, g_caar(sc, set_plist_1(sc, lst)), cadr(cadr(args))))); return(make_boolean(sc, caar(lst) == cadr(cadr(args)))); } static s7_pointer is_eq_chooser(s7_scheme *sc, s7_pointer f, int args, s7_pointer expr) { if (is_h_safe_c_s(cadr(expr))) { if ((is_symbol(caddr(expr))) && (c_callee(cadr(expr)) == g_car)) { set_optimize_op(expr, HOP_SAFE_C_C); return(is_eq_car); } if ((is_pair(caddr(expr))) && (caaddr(expr) == sc->QUOTE)) { if (c_callee(cadr(expr)) == g_car) { set_optimize_op(expr, HOP_SAFE_C_C); return(is_eq_car_q); } if (c_callee(cadr(expr)) == g_caar) { set_optimize_op(expr, HOP_SAFE_C_C); return(is_eq_caar_q); } } } return(f); } /* also not-chooser for all the ? procs, ss case for not equal? etc */ static s7_pointer not_is_pair, not_is_symbol, not_is_null, not_is_list, not_is_number; static s7_pointer not_is_char, not_is_string, not_is_zero, not_is_eq_sq, not_is_eq_ss; static s7_pointer g_not_is_pair(s7_scheme *sc, s7_pointer args) {check_boolean_not_method(sc, is_pair, sc->IS_PAIR, args);} static s7_pointer g_not_is_null(s7_scheme *sc, s7_pointer args) {check_boolean_not_method(sc, is_null, sc->IS_NULL, args);} static s7_pointer g_not_is_symbol(s7_scheme *sc, s7_pointer args) {check_boolean_not_method(sc, is_symbol, sc->IS_SYMBOL, args);} static s7_pointer g_not_is_number(s7_scheme *sc, s7_pointer args) {check_boolean_not_method(sc, s7_is_number, sc->IS_NUMBER, args);} static s7_pointer g_not_is_char(s7_scheme *sc, s7_pointer args) {check_boolean_not_method(sc, s7_is_character, sc->IS_CHAR, args);} static s7_pointer g_not_is_string(s7_scheme *sc, s7_pointer args) {check_boolean_not_method(sc, is_string, sc->IS_STRING, args);} static s7_pointer g_not_is_zero(s7_scheme *sc, s7_pointer args) {check_boolean_not_method(sc, s7_is_zero, sc->IS_ZERO, args);} static s7_pointer g_not_is_list(s7_scheme *sc, s7_pointer args) {check_boolean_not_method(sc, opt_is_list, sc->IS_LIST, args);} /* eq? does not check for methods */ static s7_pointer g_not_is_eq_sq(s7_scheme *sc, s7_pointer args) { return(make_boolean(sc, find_symbol_checked(sc, cadr(car(args))) != cadr(caddr(car(args))))); } static s7_pointer g_not_is_eq_ss(s7_scheme *sc, s7_pointer args) { return(make_boolean(sc, find_symbol_checked(sc, cadr(car(args))) != find_symbol_checked(sc, caddr(car(args))))); } /* here the method finder is in either car or cdr */ static s7_pointer not_is_pair_car; static s7_pointer g_not_is_pair_car(s7_scheme *sc, s7_pointer args) { s7_pointer val; val = find_symbol_checked(sc, cadr(cadar(args))); if (!is_pair(val)) return(g_not(sc, list_1(sc, g_is_pair(sc, list_1(sc, g_car(sc, set_plist_1(sc, val))))))); return(make_boolean(sc, !is_pair(car(val)))); } static s7_pointer not_c_c; static s7_pointer g_not_c_c(s7_scheme *sc, s7_pointer args) { /* args: ( (null? l) ) */ return(make_boolean(sc, is_false(sc, c_call(car(args))(sc, cdar(args))))); } static s7_pointer not_chooser(s7_scheme *sc, s7_pointer g, int args, s7_pointer expr) { if (is_optimized(cadr(expr))) /* cadr(expr) might be a symbol, for example; is_optimized includes is_pair */ { if (optimize_op(cadr(expr)) == HOP_SAFE_C_S) { s7_function f; f = c_callee(cadr(expr)); if (f == g_is_pair) { set_optimize_op(expr, HOP_SAFE_C_C); return(not_is_pair); } if (f == g_is_null) { set_optimize_op(expr, HOP_SAFE_C_C); return(not_is_null); } if (f == g_is_symbol) { set_optimize_op(expr, HOP_SAFE_C_C); return(not_is_symbol); } if (f == g_is_list) { set_optimize_op(expr, HOP_SAFE_C_C); return(not_is_list); } /* g_is_number is c_function_call(slot_value(global_slot(sc->IS_NUMBER))) * so if this is changed (via openlet??) the latter is perhaps better?? * but user might have (#_number? e), so we can't change later and catch this. */ if ((f == g_is_number) || (f == g_is_complex)) { set_optimize_op(expr, HOP_SAFE_C_C); return(not_is_number); } if (f == g_is_zero) { set_optimize_op(expr, HOP_SAFE_C_C); return(not_is_zero); } if (f == g_is_char) { set_optimize_op(expr, HOP_SAFE_C_C); return(not_is_char); } if (f == g_is_string) { set_optimize_op(expr, HOP_SAFE_C_C); return(not_is_string); } } if ((optimize_op(cadr(expr)) == HOP_SAFE_C_SQ) && (c_callee(cadr(expr)) == g_is_eq)) { set_optimize_op(expr, HOP_SAFE_C_C); return(not_is_eq_sq); } if (optimize_op(cadr(expr)) == HOP_SAFE_C_SS) { if (c_callee(cadr(expr)) == g_is_eq) { set_optimize_op(expr, HOP_SAFE_C_C); return(not_is_eq_ss); } } if (optimize_op(cadr(expr)) == HOP_SAFE_C_C) { set_optimize_op(expr, HOP_SAFE_C_C); if (c_callee(cadr(expr)) == g_is_pair_car) return(not_is_pair_car); return(not_c_c); } } return(g); } static s7_pointer vector_ref_chooser(s7_scheme *sc, s7_pointer f, int args, s7_pointer expr) { if (args == 2) { s7_pointer arg1, arg2; arg1 = cadr(expr); arg2 = caddr(expr); if (is_symbol(arg1)) { if ((s7_is_integer(arg2)) && (s7_integer(arg2) >= 0)) { set_optimize_op(expr, HOP_SAFE_C_C); switch (s7_integer(arg2)) /* (might be big int) */ { case 0: return(vector_ref_ic_0); case 1: return(vector_ref_ic_1); case 2: return(vector_ref_ic_2); case 3: return(vector_ref_ic_3); default: return(vector_ref_ic); } } if (is_global(arg1)) { if (is_symbol(arg2)) { set_optimize_op(expr, HOP_SAFE_C_C); if (is_immutable_symbol(arg1)) { s7_pointer vect; vect = slot_value(global_slot(arg1)); if ((is_normal_vector(vect)) && (vector_rank(vect) == 1)) { set_opt_vector(cdr(expr), vect); return(constant_vector_ref_gs); } } return(vector_ref_gs); } } if ((is_pair(arg2)) && (is_safely_optimized(arg2)) && (c_callee(arg2) == g_add_cs1)) { set_optimize_op(expr, HOP_SAFE_C_C); return(vector_ref_add1); } } /* vector_ref_sub1 was not worth the code, and few other easily optimized expressions happen here */ return(vector_ref_2); } return(f); } static s7_pointer vector_set_chooser(s7_scheme *sc, s7_pointer f, int args, s7_pointer expr) { if (args == 3) { s7_pointer arg1, arg2, arg3; arg1 = cadr(expr); arg2 = caddr(expr); arg3 = cadddr(expr); if (is_symbol(arg1)) { if ((s7_is_integer(arg2)) && (s7_integer(arg2) >= 0) && (is_symbol(arg3))) { set_optimize_op(expr, HOP_SAFE_C_C); return(vector_set_ic); } if (is_symbol(arg2)) { if ((is_pair(arg3)) && (is_safely_optimized(arg3))) { if ((c_callee(arg3) == g_vector_ref_2) && (arg1 == cadr(arg3)) && (is_symbol(caddr(arg3)))) { set_optimize_op(expr, HOP_SAFE_C_C); return(vector_set_vref); } if (((c_callee(arg3) == g_add_2) || (c_callee(arg3) == g_subtract_2)) && (is_symbol(caddr(arg3))) && (is_optimized(cadr(arg3))) && (c_callee(cadr(arg3)) == g_vector_ref_2) && (cadr(cadr(arg3)) == arg1)) { set_optimize_op(expr, HOP_SAFE_C_C); return(vector_set_vector_ref); } } } } return(vector_set_3); } return(f); } static s7_pointer list_set_chooser(s7_scheme *sc, s7_pointer f, int args, s7_pointer expr) { if ((args == 3) && (s7_is_integer(caddr(expr))) && (s7_integer(caddr(expr)) >= 0) && (s7_integer(caddr(expr)) < sc->max_list_length)) return(list_set_ic); return(f); } static s7_pointer list_ref_chooser(s7_scheme *sc, s7_pointer f, int args, s7_pointer expr) { if ((args == 2) && (s7_is_integer(caddr(expr))) && (s7_integer(caddr(expr)) >= 0) && (s7_integer(caddr(expr)) < sc->max_list_length)) return(list_ref_ic); return(f); } static s7_pointer hash_table_ref_chooser(s7_scheme *sc, s7_pointer f, int args, s7_pointer expr) { if (args == 2) { if ((is_symbol(cadr(expr))) && (is_symbol(caddr(expr)))) { set_optimize_op(expr, HOP_SAFE_C_C); return(hash_table_ref_ss); } if ((is_symbol(cadr(expr))) && (is_h_safe_c_s(caddr(expr))) && (c_callee(caddr(expr)) == g_car)) { set_optimize_op(expr, HOP_SAFE_C_C); return(hash_table_ref_car); } return(hash_table_ref_2); } return(f); } #if (!WITH_GMP) static s7_pointer modulo_chooser(s7_scheme *sc, s7_pointer f, int args, s7_pointer expr) { if ((args == 2) && (is_symbol(cadr(expr))) && (is_integer(caddr(expr))) && (integer(caddr(expr)) > 1)) { set_optimize_op(expr, HOP_SAFE_C_C); return(mod_si); } return(f); } #endif static s7_pointer add_chooser(s7_scheme *sc, s7_pointer f, int args, s7_pointer expr) { /* (+ s f) (+ (* s s) s) (+ s s) (+ s (* s s)) */ #if (!WITH_GMP) if (args == 2) { s7_pointer arg1, arg2; arg1 = cadr(expr); arg2 = caddr(expr); if (arg1 == small_int(1)) return(add_1s); if (arg2 == small_int(1)) { if (is_symbol(arg1)) { set_optimize_op(expr, HOP_SAFE_C_C); return(add_cs1); } return(add_s1); } #if HAVE_OVERFLOW_CHECKS if (s7_is_integer(arg2)) #else if ((s7_is_integer(arg2)) && (integer_length(integer(arg2)) < 31)) #endif { if (is_symbol(arg1)) { set_optimize_op(expr, HOP_SAFE_C_C); return(add_si); } } if ((is_t_real(arg2)) && (is_symbol(arg1))) { set_optimize_op(expr, HOP_SAFE_C_C); return(add_sf); } if (is_t_real(arg1)) { if (is_symbol(arg2)) { set_optimize_op(expr, HOP_SAFE_C_C); return(add_fs); } if ((is_h_safe_c_c(arg2)) && (c_callee(arg2) == g_multiply_sf)) { set_optimize_op(expr, HOP_SAFE_C_C); return(add_f_sf); } } if ((is_optimized(arg1)) && (is_optimized(arg2))) { if ((optimize_op(arg1) == HOP_SAFE_C_SS) && (optimize_op(arg2) == HOP_SAFE_C_C) && (c_callee(arg1) == g_multiply_2) && (c_callee(arg2) == g_mul_1ss) && (cadr(arg1) == caddr(cadr(arg2)))) { set_optimize_op(expr, HOP_SAFE_C_C); set_opt_sym1(cdr(expr), caddr(arg1)); set_opt_sym2(cdr(expr), caddr(arg2)); return(add_ss_1ss); } } return(add_2); } #endif return(f); } static s7_pointer multiply_chooser(s7_scheme *sc, s7_pointer f, int args, s7_pointer expr) { #if (!WITH_GMP) if (args == 2) { s7_pointer arg1, arg2; arg1 = cadr(expr); arg2 = caddr(expr); if (is_symbol(arg1)) { #if HAVE_OVERFLOW_CHECKS if (s7_is_integer(arg2)) #else if ((s7_is_integer(arg2)) && (integer_length(integer(arg2)) < 31)) #endif { set_optimize_op(expr, HOP_SAFE_C_C); return(multiply_si); } if (arg1 == arg2) { set_optimize_op(expr, HOP_SAFE_C_C); return(sqr_ss); } if (is_t_real(arg2)) { set_optimize_op(expr, HOP_SAFE_C_C); return(multiply_sf); } } if (is_symbol(arg2)) { #if HAVE_OVERFLOW_CHECKS if (s7_is_integer(arg1)) #else if ((s7_is_integer(arg1)) && (integer_length(integer(arg1)) < 31)) #endif { set_optimize_op(expr, HOP_SAFE_C_C); return(multiply_is); } if (is_t_real(arg1)) { set_optimize_op(expr, HOP_SAFE_C_C); return(multiply_fs); } } if ((is_pair(arg1)) && (is_symbol(arg2)) && (car(arg1) == sc->SUBTRACT) && (is_t_real(cadr(arg1))) && (real(cadr(arg1)) == 1.0) && (is_symbol(caddr(arg1))) && (is_null(cdddr(arg1)))) { set_optimize_op(expr, HOP_SAFE_C_C); return(mul_1ss); } if ((is_symbol(arg1)) && (is_optimized(arg2)) && ((car(arg2) == sc->SIN) || (car(arg2) == sc->COS)) && (is_symbol(cadr(arg2)))) { set_optimize_op(expr, HOP_SAFE_C_C); clear_unsafe(expr); if (car(arg2) == sc->SIN) return(mul_s_sin_s); return(mul_s_cos_s); } return(multiply_2); } if (args == 3) { s7_pointer arg1, arg2, arg3; arg1 = cadr(expr); arg2 = caddr(expr); arg3 = cadddr(expr); if ((is_t_real(arg1)) && (is_symbol(arg2)) && (is_pair(arg3)) && (car(arg3) == sc->COS) && (is_symbol(cadr(arg3)))) { set_optimize_op(expr, HOP_SAFE_C_C); return(multiply_cs_cos); } } #endif return(f); } static s7_pointer subtract_chooser(s7_scheme *sc, s7_pointer f, int args, s7_pointer expr) { #if (!WITH_GMP) if (args == 1) return(subtract_1); if (args == 2) { s7_pointer arg1, arg2; arg1 = cadr(expr); arg2 = caddr(expr); if (arg2 == small_int(1)) { if (is_symbol(arg1)) { set_optimize_op(expr, HOP_SAFE_C_C); return(subtract_cs1); } return(subtract_s1); } if (is_t_real(arg2)) { if (is_symbol(arg1)) { set_optimize_op(expr, HOP_SAFE_C_C); return(subtract_sf); } if ((is_pair(arg1)) && (is_safely_optimized(arg1))) { if (c_callee(arg1) == g_random_rc) { set_optimize_op(expr, HOP_SAFE_C_C); return(sub_random_rc); } } } if (is_t_real(arg1)) { if (is_symbol(arg2)) { set_optimize_op(expr, HOP_SAFE_C_C); return(subtract_fs); } if ((is_h_safe_c_c(arg2)) && (c_callee(arg2) == g_sqr_ss)) { set_optimize_op(expr, HOP_SAFE_C_C); return(subtract_f_sqr); } } if (s7_is_integer(arg2)) { if (is_symbol(arg1)) { set_optimize_op(expr, HOP_SAFE_C_C); return(subtract_csn); } if ((is_safely_optimized(arg1)) && (c_callee(arg1) == g_random_ic)) { set_optimize_op(expr, HOP_SAFE_C_C); return(sub_random_ic); } } if (is_t_real(arg2)) return(subtract_2f); return(subtract_2); } #endif return(f); } static s7_pointer divide_chooser(s7_scheme *sc, s7_pointer f, int args, s7_pointer expr) { #if (!WITH_GMP) if (args == 1) return(invert_1); if (args == 2) { s7_pointer arg1; arg1 = cadr(expr); if ((is_t_real(arg1)) && (real(arg1) == 1.0)) return(divide_1r); } #endif return(f); } #if (!WITH_GMP) static s7_pointer max_chooser(s7_scheme *sc, s7_pointer f, int args, s7_pointer expr) { if ((args == 2) && (is_t_real(cadr(expr))) && (!is_NaN(real(cadr(expr))))) return(max_f2); return(f); } static s7_pointer min_chooser(s7_scheme *sc, s7_pointer f, int args, s7_pointer expr) { if ((args == 2) && (is_t_real(cadr(expr))) && (!is_NaN(real(cadr(expr))))) return(min_f2); return(f); } static s7_pointer is_zero_chooser(s7_scheme *sc, s7_pointer f, int args, s7_pointer expr) { if ((args == 1) && (is_safely_optimized(cadr(expr))) && (optimize_op(cadr(expr)) == HOP_SAFE_C_C) && (c_callee(cadr(expr)) == g_mod_si)) { set_optimize_op(expr, HOP_SAFE_C_C); return(mod_si_is_zero); } return(f); } static s7_pointer equal_chooser(s7_scheme *sc, s7_pointer ur_f, int args, s7_pointer expr) { if (args == 2) { s7_pointer arg1, arg2; arg1 = cadr(expr); arg2 = caddr(expr); if (s7_is_integer(arg2)) { if (is_safely_optimized(arg1)) { s7_function f; f = c_callee(arg1); if (f == g_length) { if (optimize_op(arg1) == HOP_SAFE_C_S) { set_optimize_op(expr, HOP_SAFE_C_C); return(equal_length_ic); } } if ((f == g_mod_si) && (integer(arg2) == 0)) { set_optimize_op(expr, HOP_SAFE_C_C); return(mod_si_is_zero); } } if (is_symbol(arg1)) { set_optimize_op(expr, HOP_SAFE_C_C); return(equal_s_ic); } } return(equal_2); } return(ur_f); } static s7_pointer less_chooser(s7_scheme *sc, s7_pointer f, int args, s7_pointer expr) { if (args == 2) { s7_pointer arg2; arg2 = caddr(expr); if (is_integer(arg2)) { if (is_h_safe_c_s(cadr(expr))) { s7_function f; f = c_callee(cadr(expr)); if (f == g_length) { set_optimize_op(expr, HOP_SAFE_C_C); return(less_length_ic); } } if (integer(arg2) == 0) return(less_s0); if ((integer(arg2) < s7_int32_max) && (integer(arg2) > s7_int32_min)) return(less_s_ic); } return(less_2); } return(f); } static s7_pointer leq_chooser(s7_scheme *sc, s7_pointer f, int args, s7_pointer expr) { if (args == 2) { s7_pointer arg2; arg2 = caddr(expr); if ((is_integer(arg2)) && (integer(arg2) < s7_int32_max) && (integer(arg2) > s7_int32_min)) return(leq_s_ic); return(leq_2); } return(f); } static s7_pointer greater_chooser(s7_scheme *sc, s7_pointer f, int args, s7_pointer expr) { if (args == 2) { s7_pointer arg2; arg2 = caddr(expr); if ((is_integer(arg2)) && (integer(arg2) < s7_int32_max) && (integer(arg2) > s7_int32_min)) return(greater_s_ic); if ((is_t_real(arg2)) && (real(arg2) < s7_int32_max) && (real(arg2) > s7_int32_min)) return(greater_s_fc); return(greater_2); } return(f); } static s7_pointer geq_chooser(s7_scheme *sc, s7_pointer f, int args, s7_pointer expr) { if (args == 2) { s7_pointer arg2; arg2 = caddr(expr); if (is_integer(arg2)) { if (is_h_safe_c_s(cadr(expr))) { s7_function f; f = c_callee(cadr(expr)); if (f == g_length) { set_optimize_op(expr, HOP_SAFE_C_C); return(geq_length_ic); } } if ((integer(arg2) < s7_int32_max) && (integer(arg2) > s7_int32_min)) return(geq_s_ic); } if ((is_t_real(arg2)) && (real(arg2) < s7_int32_max) && (real(arg2) > s7_int32_min)) return(geq_s_fc); return(geq_2); } return(f); } #endif /* end (!WITH_GMP) */ static bool returns_char(s7_scheme *sc, s7_pointer arg) { /* also if arg is immutable symbol + value is char */ if (s7_is_character(arg)) return(true); if ((is_h_optimized(arg)) && (is_c_function(opt_cfunc(arg)))) { s7_pointer sig; sig = c_function_signature(opt_cfunc(arg)); return((sig) && (is_pair(sig)) && (car(sig) == sc->IS_CHAR)); } return(false); } static s7_pointer char_equal_chooser(s7_scheme *sc, s7_pointer f, int args, s7_pointer expr) { if (args == 2) { s7_pointer arg1, arg2; arg1 = cadr(expr); arg2 = caddr(expr); if ((returns_char(sc, arg1)) && (returns_char(sc, arg2))) return(simple_char_eq); if ((is_symbol(arg1)) && (s7_is_character(arg2))) { set_optimize_op(expr, HOP_SAFE_C_C); return(char_equal_s_ic); } return(char_equal_2); } return(f); } static s7_pointer char_less_chooser(s7_scheme *sc, s7_pointer f, int args, s7_pointer expr) { if (args == 2) { if (s7_is_character(caddr(expr))) return(char_less_s_ic); return(char_less_2); } return(f); } static s7_pointer char_greater_chooser(s7_scheme *sc, s7_pointer f, int args, s7_pointer expr) { if (args == 2) { if (s7_is_character(caddr(expr))) return(char_greater_s_ic); return(char_greater_2); } return(f); } static void check_for_substring_temp(s7_scheme *sc, s7_pointer expr) { s7_pointer p, np = NULL, ap = NULL, sp = NULL, arg; int pairs = 0; /* a bit tricky -- accept temp only if there's just one inner expression and it calls substring */ for (p = cdr(expr); is_pair(p); p = cdr(p)) { arg = car(p); if (is_pair(arg)) { pairs++; if ((is_symbol(car(arg))) && (is_safely_optimized(arg))) { if (c_callee(arg) == g_substring) np = arg; else { if (c_callee(arg) == g_number_to_string) sp = arg; else { if (c_callee(arg) == g_string_append) ap = arg; else { if (c_callee(arg) == g_symbol_to_string) set_c_function(arg, symbol_to_string_uncopied); else { if ((c_callee(arg) == g_read_line) && (is_pair(cdr(arg)))) set_c_function(arg, read_line_uncopied); }}}}}}} if (pairs == 1) { if (np) set_c_function(np, substring_to_temp); else { if (sp) set_c_function(sp, number_to_string_temp); else { if (ap) { for (p = ap; is_pair(p); p = cdr(p)) { /* make sure there are no embedded uses of the temp string */ arg = car(p); if ((is_pair(arg)) && (is_safely_optimized(arg))) { if (c_callee(arg) == g_substring_to_temp) set_c_function(arg, slot_value(global_slot(sc->SUBSTRING))); else { if (c_callee(arg) == g_string_append_to_temp) set_c_function(arg, slot_value(global_slot(sc->STRING_APPEND))); } } } set_c_function(ap, string_append_to_temp); } } } } } static s7_pointer char_position_chooser(s7_scheme *sc, s7_pointer f, int args, s7_pointer expr) { if (((args == 2) || (args == 3)) && (s7_is_character(cadr(expr)))) return(char_position_csi); return(f); } static s7_pointer string_equal_chooser(s7_scheme *sc, s7_pointer f, int args, s7_pointer expr) { check_for_substring_temp(sc, expr); if (args == 2) { if (is_string(caddr(expr))) return(string_equal_s_ic); return(string_equal_2); } return(f); } static s7_pointer string_less_chooser(s7_scheme *sc, s7_pointer f, int args, s7_pointer expr) { check_for_substring_temp(sc, expr); if (args == 2) return(string_less_2); return(f); } static s7_pointer string_greater_chooser(s7_scheme *sc, s7_pointer f, int args, s7_pointer expr) { check_for_substring_temp(sc, expr); if (args == 2) return(string_greater_2); return(f); } static s7_pointer string_to_symbol_chooser(s7_scheme *sc, s7_pointer f, int args, s7_pointer expr) { check_for_substring_temp(sc, expr); return(f); } static s7_pointer string_ref_chooser(s7_scheme *sc, s7_pointer f, int args, s7_pointer expr) { check_for_substring_temp(sc, expr); return(f); } static s7_pointer string_set_chooser(s7_scheme *sc, s7_pointer f, int args, s7_pointer expr) { return(f); } static s7_pointer string_append_chooser(s7_scheme *sc, s7_pointer f, int args, s7_pointer expr) { check_for_substring_temp(sc, expr); return(f); } static s7_pointer or_direct; static s7_pointer g_or_direct(s7_scheme *sc, s7_pointer args) { s7_pointer p; for (p = args; is_pair(p); p = cdr(p)) { s7_pointer x; x = car(p); if (is_symbol(x)) x = find_symbol_checked(sc, x); if (is_true(sc, x)) return(x); } return(sc->F); } static s7_pointer and_direct; static s7_pointer g_and_direct(s7_scheme *sc, s7_pointer args) { s7_pointer p, x; x = sc->T; for (p = args; is_pair(p); p = cdr(p)) { x = car(p); if (is_symbol(x)) x = find_symbol_checked(sc, x); if (is_false(sc, x)) return(x); } return(x); } static s7_pointer if_direct; static s7_pointer g_if_direct(s7_scheme *sc, s7_pointer args) { s7_pointer p; p = car(args); if (is_symbol(p)) p = find_symbol_checked(sc, p); if (is_true(sc, p)) p = cadr(args); else { if (!is_null(cddr(args))) p = caddr(args); else return(sc->UNSPECIFIED); } if (is_symbol(p)) return(find_symbol_checked(sc, p)); return(p); } static s7_pointer or_all_x, or_all_x_2, or_all_x_2s; static s7_pointer g_or_all_x(s7_scheme *sc, s7_pointer args) { s7_pointer p; for (p = args; is_pair(p); p = cdr(p)) { s7_pointer x; x = c_call(p)(sc, car(p)); if (is_true(sc, x)) return(x); } return(sc->F); } static s7_pointer g_or_all_x_2(s7_scheme *sc, s7_pointer args) { s7_pointer p; p = c_call(args)(sc, car(args)); if (p != sc->F) return(p); p = cdr(args); return(c_call(p)(sc, car(p))); } static s7_pointer g_or_all_x_2s(s7_scheme *sc, s7_pointer args) { s7_pointer p; p = car(args); car(sc->T1_1) = find_symbol_unchecked(sc, cadr(p)); p = c_call(p)(sc, sc->T1_1); if (p != sc->F) return(p); p = cadr(args); car(sc->T1_1) = find_symbol_unchecked(sc, cadr(p)); return(c_call(p)(sc, sc->T1_1)); } static s7_pointer and_all_x, and_all_x_2; static s7_pointer g_and_all_x(s7_scheme *sc, s7_pointer args) { s7_pointer p, x = sc->T; for (p = args; is_pair(p); p = cdr(p)) { x = c_call(p)(sc, car(p)); if (is_false(sc, x)) return(x); } return(x); } static s7_pointer g_and_all_x_2(s7_scheme *sc, s7_pointer args) { s7_pointer p; p = c_call(args)(sc, car(args)); if (p == sc->F) return(p); p = cdr(args); return(c_call(p)(sc, car(p))); } static s7_pointer if_all_x1; static s7_pointer g_if_all_x1(s7_scheme *sc, s7_pointer args) { s7_pointer p; if (is_true(sc, c_call(args)(sc, car(args)))) p = cdr(args); else return(sc->UNSPECIFIED); return(c_call(p)(sc, car(p))); } static s7_pointer if_all_x2; static s7_pointer g_if_all_x2(s7_scheme *sc, s7_pointer args) { s7_pointer p; if (is_true(sc, c_call(args)(sc, car(args)))) p = cdr(args); else p = cddr(args); return(c_call(p)(sc, car(p))); } static s7_pointer if_all_not_x1; static s7_pointer g_if_all_not_x1(s7_scheme *sc, s7_pointer args) { s7_pointer p; if (is_false(sc, c_call(args)(sc, cadar(args)))) p = cdr(args); else return(sc->UNSPECIFIED); return(c_call(p)(sc, car(p))); } static s7_pointer if_all_not_x2; static s7_pointer g_if_all_not_x2(s7_scheme *sc, s7_pointer args) { s7_pointer p; if (is_false(sc, c_call(args)(sc, cadar(args)))) p = cdr(args); else p = cddr(args); return(c_call(p)(sc, car(p))); } static s7_pointer if_all_x_qq; static s7_pointer g_if_all_x_qq(s7_scheme *sc, s7_pointer args) { if (is_true(sc, c_call(args)(sc, car(args)))) return(cadr(cadr(args))); return(cadr(caddr(args))); } static s7_pointer if_all_x_qa; static s7_pointer g_if_all_x_qa(s7_scheme *sc, s7_pointer args) { if (is_true(sc, c_call(args)(sc, car(args)))) return(cadr(cadr(args))); return(c_call(cddr(args))(sc, caddr(args))); } static s7_pointer or_s_direct; static s7_pointer g_or_s_direct(s7_scheme *sc, s7_pointer args) { s7_pointer p; car(sc->T1_1) = find_symbol_checked(sc, cadar(args)); for (p = args; is_pair(p); p = cdr(p)) { s7_pointer x; x = c_call(car(p))(sc, sc->T1_1); if (is_true(sc, x)) return(x); } return(sc->F); } static s7_pointer and_s_direct; static s7_pointer g_and_s_direct(s7_scheme *sc, s7_pointer args) { s7_pointer p, x = sc->T; car(sc->T1_1) = find_symbol_checked(sc, cadar(args)); for (p = args; is_pair(p); p = cdr(p)) { x = c_call(car(p))(sc, sc->T1_1); if (is_false(sc, x)) return(x); } return(x); } static s7_pointer if_s_direct; static s7_pointer g_if_s_direct(s7_scheme *sc, s7_pointer args) { s7_pointer p; car(sc->T1_1) = find_symbol_checked(sc, cadar(args)); if (is_true(sc, c_call(car(args))(sc, sc->T1_1))) p = cdr(args); else { p = cddr(args); if (is_null(p)) return(sc->UNSPECIFIED); } return(c_call(car(p))(sc, sc->T1_1)); } static s7_pointer make_function_with_class(s7_scheme *sc, s7_pointer cls, const char *name, s7_function f, int required_args, int optional_args, bool rest_arg, const char *doc) { s7_pointer uf; /* the "safe_function" business here doesn't matter -- this is after the optimizer decides what is safe */ uf = s7_make_safe_function(sc, name, f, required_args, optional_args, rest_arg, doc); s7_function_set_class(uf, cls); return(uf); } static s7_pointer set_function_chooser(s7_scheme *sc, s7_pointer sym, s7_pointer (*chooser)(s7_scheme *sc, s7_pointer f, int args, s7_pointer expr)) { s7_pointer f; f = slot_value(global_slot(sym)); #ifndef WITHOUT_CHOOSERS c_function_chooser(f) = chooser; #endif return(f); } static void init_choosers(s7_scheme *sc) { s7_pointer f; #if (!WITH_GMP) s7_if_set_function(slot_value(global_slot(sc->MODULO)), modulo_if); s7_rf_set_function(slot_value(global_slot(sc->MODULO)), modulo_rf); s7_rf_set_function(slot_value(global_slot(sc->REMAINDER)), remainder_rf); s7_if_set_function(slot_value(global_slot(sc->REMAINDER)), remainder_if); s7_rf_set_function(slot_value(global_slot(sc->QUOTIENT)), quotient_rf); s7_if_set_function(slot_value(global_slot(sc->QUOTIENT)), quotient_if); s7_if_set_function(slot_value(global_slot(sc->NUMERATOR)), numerator_if); s7_if_set_function(slot_value(global_slot(sc->DENOMINATOR)), denominator_if); s7_rf_set_function(slot_value(global_slot(sc->REAL_PART)), real_part_rf); s7_rf_set_function(slot_value(global_slot(sc->IMAG_PART)), imag_part_rf); s7_gf_set_function(slot_value(global_slot(sc->RATIONALIZE)), rationalize_pf); s7_if_set_function(slot_value(global_slot(sc->CEILING)), ceiling_if); s7_if_set_function(slot_value(global_slot(sc->TRUNCATE)), truncate_if); s7_if_set_function(slot_value(global_slot(sc->ROUND)), round_if); s7_if_set_function(slot_value(global_slot(sc->FLOOR)), floor_if); s7_if_set_function(slot_value(global_slot(sc->LOGIOR)), logior_if); s7_if_set_function(slot_value(global_slot(sc->LOGAND)), logand_if); s7_if_set_function(slot_value(global_slot(sc->LOGXOR)), logxor_if); s7_if_set_function(slot_value(global_slot(sc->LOGNOT)), lognot_if); s7_if_set_function(slot_value(global_slot(sc->ASH)), ash_if); s7_if_set_function(slot_value(global_slot(sc->GCD)), gcd_if); s7_if_set_function(slot_value(global_slot(sc->LCM)), lcm_if); s7_rf_set_function(slot_value(global_slot(sc->MAX)), max_rf); s7_if_set_function(slot_value(global_slot(sc->MAX)), max_if); s7_rf_set_function(slot_value(global_slot(sc->MIN)), min_rf); s7_if_set_function(slot_value(global_slot(sc->MIN)), min_if); s7_rf_set_function(slot_value(global_slot(sc->DIVIDE)), divide_rf); s7_if_set_function(slot_value(global_slot(sc->MULTIPLY)), multiply_if); s7_rf_set_function(slot_value(global_slot(sc->MULTIPLY)), multiply_rf); s7_rf_set_function(slot_value(global_slot(sc->ADD)), add_rf); s7_if_set_function(slot_value(global_slot(sc->ADD)), add_if); s7_rf_set_function(slot_value(global_slot(sc->SUBTRACT)), subtract_rf); s7_if_set_function(slot_value(global_slot(sc->SUBTRACT)), subtract_if); #if WITH_ADD_PF s7_gf_set_function(slot_value(global_slot(sc->MULTIPLY)), multiply_pf); s7_gf_set_function(slot_value(global_slot(sc->ADD)), add_pf); s7_gf_set_function(slot_value(global_slot(sc->SUBTRACT)), subtract_pf); #endif s7_rf_set_function(slot_value(global_slot(sc->SIN)), sin_rf); s7_rf_set_function(slot_value(global_slot(sc->COS)), cos_rf); s7_rf_set_function(slot_value(global_slot(sc->TAN)), tan_rf); s7_rf_set_function(slot_value(global_slot(sc->SINH)), sinh_rf); s7_rf_set_function(slot_value(global_slot(sc->COSH)), cosh_rf); s7_rf_set_function(slot_value(global_slot(sc->TANH)), tanh_rf); s7_rf_set_function(slot_value(global_slot(sc->ATAN)), atan_rf); s7_rf_set_function(slot_value(global_slot(sc->EXP)), exp_rf); s7_gf_set_function(slot_value(global_slot(sc->ASIN)), asin_pf); s7_gf_set_function(slot_value(global_slot(sc->ACOS)), acos_pf); s7_gf_set_function(slot_value(global_slot(sc->ASINH)), asinh_pf); s7_gf_set_function(slot_value(global_slot(sc->ACOSH)), acosh_pf); s7_gf_set_function(slot_value(global_slot(sc->ATANH)), atanh_pf); s7_rf_set_function(slot_value(global_slot(sc->RANDOM)), random_rf); s7_if_set_function(slot_value(global_slot(sc->RANDOM)), random_if); s7_gf_set_function(slot_value(global_slot(sc->EXPT)), expt_pf); s7_gf_set_function(slot_value(global_slot(sc->NUMBER_TO_STRING)), number_to_string_pf); s7_gf_set_function(slot_value(global_slot(sc->STRING_TO_NUMBER)), string_to_number_pf); s7_rf_set_function(slot_value(global_slot(sc->ABS)), fabs_rf); s7_if_set_function(slot_value(global_slot(sc->ABS)), abs_if); #if (!WITH_PURE_S7) s7_gf_set_function(slot_value(global_slot(sc->MAKE_RECTANGULAR)), make_complex_pf); s7_gf_set_function(slot_value(global_slot(sc->MAKE_POLAR)), make_polar_pf); #endif s7_rf_set_function(slot_value(global_slot(sc->MAGNITUDE)), magnitude_rf); s7_if_set_function(slot_value(global_slot(sc->MAGNITUDE)), magnitude_if); s7_gf_set_function(slot_value(global_slot(sc->COMPLEX)), make_complex_pf); /* actually complex */ s7_pf_set_function(slot_value(global_slot(sc->EQ)), equal_pf); s7_pf_set_function(slot_value(global_slot(sc->LT)), less_pf); s7_pf_set_function(slot_value(global_slot(sc->LEQ)), leq_pf); s7_pf_set_function(slot_value(global_slot(sc->GEQ)), geq_pf); s7_pf_set_function(slot_value(global_slot(sc->GT)), gt_pf); #endif /* !gmp */ s7_if_set_function(slot_value(global_slot(sc->PAIR_LINE_NUMBER)), pair_line_number_if); s7_if_set_function(slot_value(global_slot(sc->HASH_TABLE_ENTRIES)), hash_table_entries_if); #if (!WITH_PURE_S7) #if (!WITH_GMP) s7_if_set_function(slot_value(global_slot(sc->INTEGER_LENGTH)), integer_length_if); #endif s7_if_set_function(slot_value(global_slot(sc->VECTOR_LENGTH)), vector_length_if); s7_if_set_function(slot_value(global_slot(sc->STRING_LENGTH)), string_length_if); s7_pf_set_function(slot_value(global_slot(sc->STRING_FILL)), string_fill_pf); s7_pf_set_function(slot_value(global_slot(sc->VECTOR_FILL)), vector_fill_pf); #endif s7_pf_set_function(slot_value(global_slot(sc->LENGTH)), length_pf); s7_pf_set_function(slot_value(global_slot(sc->FILL)), fill_pf); s7_gf_set_function(slot_value(global_slot(sc->COPY)), copy_pf); s7_gf_set_function(slot_value(global_slot(sc->REVERSE)), reverse_pf); s7_pf_set_function(slot_value(global_slot(sc->NOT)), not_pf); s7_if_set_function(slot_value(global_slot(sc->CHAR_TO_INTEGER)), char_to_integer_if); s7_pf_set_function(slot_value(global_slot(sc->CHAR_EQ)), char_eq_pf); s7_pf_set_function(slot_value(global_slot(sc->CHAR_GT)), char_gt_pf); s7_pf_set_function(slot_value(global_slot(sc->CHAR_GEQ)), char_geq_pf); s7_pf_set_function(slot_value(global_slot(sc->CHAR_LT)), char_lt_pf); s7_pf_set_function(slot_value(global_slot(sc->CHAR_LEQ)), char_leq_pf); s7_pf_set_function(slot_value(global_slot(sc->STRING_EQ)), string_eq_pf); s7_pf_set_function(slot_value(global_slot(sc->STRING_LT)), string_lt_pf); s7_pf_set_function(slot_value(global_slot(sc->STRING_LEQ)), string_leq_pf); s7_pf_set_function(slot_value(global_slot(sc->STRING_GT)), string_gt_pf); s7_pf_set_function(slot_value(global_slot(sc->STRING_GEQ)), string_geq_pf); s7_gf_set_function(slot_value(global_slot(sc->STRING_UPCASE)), string_upcase_pf); s7_gf_set_function(slot_value(global_slot(sc->STRING_DOWNCASE)), string_downcase_pf); s7_gf_set_function(slot_value(global_slot(sc->CHAR_POSITION)), char_position_pf); s7_gf_set_function(slot_value(global_slot(sc->STRING_POSITION)), string_position_pf); #if (!WITH_PURE_S7) s7_pf_set_function(slot_value(global_slot(sc->CHAR_CI_EQ)), char_ci_eq_pf); s7_pf_set_function(slot_value(global_slot(sc->CHAR_CI_GT)), char_ci_gt_pf); s7_pf_set_function(slot_value(global_slot(sc->CHAR_CI_GEQ)), char_ci_geq_pf); s7_pf_set_function(slot_value(global_slot(sc->CHAR_CI_LT)), char_ci_lt_pf); s7_pf_set_function(slot_value(global_slot(sc->CHAR_CI_LEQ)), char_ci_leq_pf); s7_pf_set_function(slot_value(global_slot(sc->STRING_CI_EQ)), string_ci_eq_pf); s7_pf_set_function(slot_value(global_slot(sc->STRING_CI_LT)), string_ci_lt_pf); s7_pf_set_function(slot_value(global_slot(sc->STRING_CI_LEQ)), string_ci_leq_pf); s7_pf_set_function(slot_value(global_slot(sc->STRING_CI_GT)), string_ci_gt_pf); s7_pf_set_function(slot_value(global_slot(sc->STRING_CI_GEQ)), string_ci_geq_pf); #endif #if (!WITH_GMP) s7_pf_set_function(slot_value(global_slot(sc->IS_EVEN)), is_even_pf); s7_pf_set_function(slot_value(global_slot(sc->IS_ODD)), is_odd_pf); s7_pf_set_function(slot_value(global_slot(sc->IS_NAN)), is_nan_pf); s7_pf_set_function(slot_value(global_slot(sc->IS_INFINITE)), is_infinite_pf); #endif s7_pf_set_function(slot_value(global_slot(sc->IS_ZERO)), is_zero_pf); s7_pf_set_function(slot_value(global_slot(sc->IS_POSITIVE)), is_positive_pf); s7_pf_set_function(slot_value(global_slot(sc->IS_NEGATIVE)), is_negative_pf); s7_pf_set_function(slot_value(global_slot(sc->HASH_TABLE_REF)), hash_table_ref_pf); s7_pf_set_function(slot_value(global_slot(sc->HASH_TABLE_SET)), hash_table_set_pf); s7_pf_set_function(slot_value(global_slot(sc->VECTOR_REF)), vector_ref_pf); s7_pf_set_function(slot_value(global_slot(sc->VECTOR_SET)), vector_set_pf); s7_pf_set_function(slot_value(global_slot(sc->STRING_REF)), string_ref_pf); s7_pf_set_function(slot_value(global_slot(sc->STRING_SET)), string_set_pf); s7_pf_set_function(slot_value(global_slot(sc->LIST_REF)), list_ref_pf); s7_pf_set_function(slot_value(global_slot(sc->LIST_SET)), list_set_pf); s7_pf_set_function(slot_value(global_slot(sc->LET_REF)), let_ref_pf); s7_pf_set_function(slot_value(global_slot(sc->LET_SET)), let_set_pf); s7_pf_set_function(slot_value(global_slot(sc->TO_BYTE_VECTOR)), to_byte_vector_pf); s7_rf_set_function(slot_value(global_slot(sc->FLOAT_VECTOR_REF)), float_vector_ref_rf); s7_rf_set_function(slot_value(global_slot(sc->FLOAT_VECTOR_SET)), float_vector_set_rf); s7_if_set_function(slot_value(global_slot(sc->INT_VECTOR_REF)), int_vector_ref_if); s7_if_set_function(slot_value(global_slot(sc->INT_VECTOR_SET)), int_vector_set_if); s7_pf_set_function(slot_value(global_slot(sc->CAAAAR)), caaaar_pf); s7_pf_set_function(slot_value(global_slot(sc->CAAADR)), caaadr_pf); s7_pf_set_function(slot_value(global_slot(sc->CAAAR)), caaar_pf); s7_pf_set_function(slot_value(global_slot(sc->CAADAR)), caadar_pf); s7_pf_set_function(slot_value(global_slot(sc->CAADDR)), caaddr_pf); s7_pf_set_function(slot_value(global_slot(sc->CAADR)), caadr_pf); s7_pf_set_function(slot_value(global_slot(sc->CAAR)), caar_pf); s7_pf_set_function(slot_value(global_slot(sc->CADAAR)), cadaar_pf); s7_pf_set_function(slot_value(global_slot(sc->CADADR)), cadadr_pf); s7_pf_set_function(slot_value(global_slot(sc->CADAR)), cadar_pf); s7_pf_set_function(slot_value(global_slot(sc->CADDAR)), caddar_pf); s7_pf_set_function(slot_value(global_slot(sc->CADDDR)), cadddr_pf); s7_pf_set_function(slot_value(global_slot(sc->CADDR)), caddr_pf); s7_pf_set_function(slot_value(global_slot(sc->CADR)), cadr_pf); s7_pf_set_function(slot_value(global_slot(sc->CAR)), car_pf); s7_pf_set_function(slot_value(global_slot(sc->CDAAAR)), cdaaar_pf); s7_pf_set_function(slot_value(global_slot(sc->CDAADR)), cdaadr_pf); s7_pf_set_function(slot_value(global_slot(sc->CDAAR)), cdaar_pf); s7_pf_set_function(slot_value(global_slot(sc->CDADAR)), cdadar_pf); s7_pf_set_function(slot_value(global_slot(sc->CDADDR)), cdaddr_pf); s7_pf_set_function(slot_value(global_slot(sc->CDADR)), cdadr_pf); s7_pf_set_function(slot_value(global_slot(sc->CDAR)), cdar_pf); s7_pf_set_function(slot_value(global_slot(sc->CDDAAR)), cddaar_pf); s7_pf_set_function(slot_value(global_slot(sc->CDDADR)), cddadr_pf); s7_pf_set_function(slot_value(global_slot(sc->CDDAR)), cddar_pf); s7_pf_set_function(slot_value(global_slot(sc->CDDDAR)), cdddar_pf); s7_pf_set_function(slot_value(global_slot(sc->CDDDDR)), cddddr_pf); s7_pf_set_function(slot_value(global_slot(sc->CDDDR)), cdddr_pf); s7_pf_set_function(slot_value(global_slot(sc->CDDR)), cddr_pf); s7_pf_set_function(slot_value(global_slot(sc->CDR)), cdr_pf); s7_pf_set_function(slot_value(global_slot(sc->SET_CAR)), set_car_pf); s7_pf_set_function(slot_value(global_slot(sc->SET_CDR)), set_cdr_pf); s7_pf_set_function(slot_value(global_slot(sc->LIST_TAIL)), list_tail_pf); s7_pf_set_function(slot_value(global_slot(sc->ASSOC)), assoc_pf); s7_pf_set_function(slot_value(global_slot(sc->MEMBER)), member_pf); s7_gf_set_function(slot_value(global_slot(sc->CONS)), cons_pf); s7_gf_set_function(slot_value(global_slot(sc->LIST)), list_pf); s7_gf_set_function(slot_value(global_slot(sc->INT_VECTOR)), int_vector_pf); s7_gf_set_function(slot_value(global_slot(sc->FLOAT_VECTOR)), float_vector_pf); s7_gf_set_function(slot_value(global_slot(sc->VECTOR)), vector_pf); s7_gf_set_function(slot_value(global_slot(sc->C_POINTER)), c_pointer_pf); s7_gf_set_function(slot_value(global_slot(sc->VECTOR_DIMENSIONS)), vector_dimensions_pf); s7_gf_set_function(slot_value(global_slot(sc->MAKE_SHARED_VECTOR)), make_shared_vector_pf); s7_gf_set_function(slot_value(global_slot(sc->MAKE_VECTOR)), make_vector_pf); s7_gf_set_function(slot_value(global_slot(sc->MAKE_FLOAT_VECTOR)), make_float_vector_pf); s7_gf_set_function(slot_value(global_slot(sc->MAKE_INT_VECTOR)), make_int_vector_pf); s7_gf_set_function(slot_value(global_slot(sc->MAKE_LIST)), make_list_pf); s7_gf_set_function(slot_value(global_slot(sc->MAKE_STRING)), make_string_pf); #if (!WITH_PURE_S7) s7_pf_set_function(slot_value(global_slot(sc->MEMQ)), memq_pf); s7_pf_set_function(slot_value(global_slot(sc->MEMV)), memv_pf); s7_pf_set_function(slot_value(global_slot(sc->ASSQ)), assq_pf); s7_pf_set_function(slot_value(global_slot(sc->ASSV)), assv_pf); s7_gf_set_function(slot_value(global_slot(sc->LIST_TO_VECTOR)), list_to_vector_pf); s7_gf_set_function(slot_value(global_slot(sc->VECTOR_TO_LIST)), vector_to_list_pf); s7_gf_set_function(slot_value(global_slot(sc->STRING_TO_LIST)), string_to_list_pf); s7_gf_set_function(slot_value(global_slot(sc->LET_TO_LIST)), let_to_list_pf); #endif s7_gf_set_function(slot_value(global_slot(sc->RANDOM_STATE_TO_LIST)), random_state_to_list_pf); s7_pf_set_function(slot_value(global_slot(sc->IS_ARITABLE)), is_aritable_pf); s7_pf_set_function(slot_value(global_slot(sc->IS_BOOLEAN)), is_boolean_pf); s7_pf_set_function(slot_value(global_slot(sc->IS_BYTE_VECTOR)), is_byte_vector_pf); s7_pf_set_function(slot_value(global_slot(sc->IS_CHAR)), is_char_pf); s7_pf_set_function(slot_value(global_slot(sc->IS_COMPLEX)), is_complex_pf); s7_pf_set_function(slot_value(global_slot(sc->IS_CONSTANT)), is_constant_pf); s7_pf_set_function(slot_value(global_slot(sc->IS_CONTINUATION)), is_continuation_pf); s7_pf_set_function(slot_value(global_slot(sc->IS_C_POINTER)), is_c_pointer_pf); s7_pf_set_function(slot_value(global_slot(sc->IS_DILAMBDA)), is_dilambda_pf); s7_pf_set_function(slot_value(global_slot(sc->IS_EOF_OBJECT)), is_eof_object_pf); s7_pf_set_function(slot_value(global_slot(sc->IS_FLOAT_VECTOR)), is_float_vector_pf); s7_pf_set_function(slot_value(global_slot(sc->IS_GENSYM)), is_gensym_pf); s7_pf_set_function(slot_value(global_slot(sc->IS_HASH_TABLE)), is_hash_table_pf); s7_pf_set_function(slot_value(global_slot(sc->IS_INPUT_PORT)), is_input_port_pf); s7_pf_set_function(slot_value(global_slot(sc->IS_INTEGER)), is_integer_pf); s7_pf_set_function(slot_value(global_slot(sc->IS_INT_VECTOR)), is_int_vector_pf); s7_pf_set_function(slot_value(global_slot(sc->IS_KEYWORD)), is_keyword_pf); s7_pf_set_function(slot_value(global_slot(sc->IS_LET)), is_let_pf); s7_pf_set_function(slot_value(global_slot(sc->IS_LIST)), is_list_pf); s7_pf_set_function(slot_value(global_slot(sc->IS_MACRO)), is_macro_pf); s7_pf_set_function(slot_value(global_slot(sc->IS_NULL)), is_null_pf); s7_pf_set_function(slot_value(global_slot(sc->IS_NUMBER)), is_number_pf); s7_pf_set_function(slot_value(global_slot(sc->IS_OUTPUT_PORT)), is_output_port_pf); s7_pf_set_function(slot_value(global_slot(sc->IS_PAIR)), is_pair_pf); s7_pf_set_function(slot_value(global_slot(sc->IS_PROCEDURE)), is_procedure_pf); s7_pf_set_function(slot_value(global_slot(sc->IS_PROVIDED)), is_provided_pf); s7_pf_set_function(slot_value(global_slot(sc->IS_RANDOM_STATE)), is_random_state_pf); s7_pf_set_function(slot_value(global_slot(sc->IS_RATIONAL)), is_rational_pf); s7_pf_set_function(slot_value(global_slot(sc->IS_REAL)), is_real_pf); s7_pf_set_function(slot_value(global_slot(sc->IS_STRING)), is_string_pf); s7_pf_set_function(slot_value(global_slot(sc->IS_SYMBOL)), is_symbol_pf); s7_pf_set_function(slot_value(global_slot(sc->IS_VECTOR)), is_vector_pf); s7_pf_set_function(slot_value(global_slot(sc->IS_ITERATOR)), is_iterator_pf); s7_pf_set_function(slot_value(global_slot(sc->ITERATOR_IS_AT_END)), iterator_is_at_end_pf); s7_pf_set_function(slot_value(global_slot(sc->ITERATOR_SEQUENCE)), iterator_sequence_pf); s7_pf_set_function(slot_value(global_slot(sc->ITERATE)), iterate_pf); s7_gf_set_function(slot_value(global_slot(sc->ITERATE)), iterate_gf); s7_gf_set_function(slot_value(global_slot(sc->MAKE_ITERATOR)), make_iterator_pf); #if (!WITH_GMP) s7_gf_set_function(slot_value(global_slot(sc->RANDOM_STATE)), random_state_pf); #endif s7_pf_set_function(slot_value(global_slot(sc->REVERSEB)), reverse_in_place_pf); s7_gf_set_function(slot_value(global_slot(sc->SORT)), sort_pf); s7_pf_set_function(slot_value(global_slot(sc->PROVIDE)), provide_pf); s7_pf_set_function(slot_value(global_slot(sc->SYMBOL)), symbol_pf); s7_pf_set_function(slot_value(global_slot(sc->STRING_TO_SYMBOL)), string_to_symbol_pf); s7_gf_set_function(slot_value(global_slot(sc->SYMBOL_TO_STRING)), symbol_to_string_pf); s7_pf_set_function(slot_value(global_slot(sc->MAKE_KEYWORD)), make_keyword_pf); s7_pf_set_function(slot_value(global_slot(sc->KEYWORD_TO_SYMBOL)), keyword_to_symbol_pf); s7_pf_set_function(slot_value(global_slot(sc->SYMBOL_TO_KEYWORD)), symbol_to_keyword_pf); s7_pf_set_function(slot_value(global_slot(sc->SYMBOL_TO_VALUE)), symbol_to_value_pf); s7_gf_set_function(slot_value(global_slot(sc->GENSYM)), gensym_pf); s7_gf_set_function(slot_value(global_slot(sc->ARITY)), arity_pf); s7_pf_set_function(slot_value(global_slot(sc->IS_OPENLET)), is_openlet_pf); s7_pf_set_function(slot_value(global_slot(sc->CURLET)), curlet_pf); s7_pf_set_function(slot_value(global_slot(sc->OWLET)), owlet_pf); s7_pf_set_function(slot_value(global_slot(sc->ROOTLET)), rootlet_pf); s7_pf_set_function(slot_value(global_slot(sc->OUTLET)), outlet_pf); s7_pf_set_function(slot_value(global_slot(sc->OPENLET)), openlet_pf); s7_pf_set_function(slot_value(global_slot(sc->COVERLET)), coverlet_pf); s7_pf_set_function(slot_value(global_slot(sc->FUNCLET)), funclet_pf); s7_pf_set_function(slot_value(global_slot(sc->CUTLET)), cutlet_pf); s7_pf_set_function(slot_value(global_slot(sc->VARLET)), varlet_pf); s7_pf_set_function(slot_value(global_slot(sc->UNLET)), unlet_pf); s7_gf_set_function(slot_value(global_slot(sc->INLET)), inlet_pf); s7_pf_set_function(slot_value(global_slot(sc->GC)), gc_pf); s7_gf_set_function(slot_value(global_slot(sc->HELP)), help_pf); s7_gf_set_function(slot_value(global_slot(sc->PROCEDURE_SOURCE)), procedure_source_pf); s7_gf_set_function(slot_value(global_slot(sc->PROCEDURE_DOCUMENTATION)), procedure_documentation_pf); s7_gf_set_function(slot_value(global_slot(sc->PROCEDURE_SIGNATURE)), procedure_signature_pf); s7_pf_set_function(slot_value(global_slot(sc->IS_CHAR_ALPHABETIC)), is_char_alphabetic_pf); s7_pf_set_function(slot_value(global_slot(sc->IS_CHAR_LOWER_CASE)), is_char_lower_case_pf); s7_pf_set_function(slot_value(global_slot(sc->IS_CHAR_NUMERIC)), is_char_numeric_pf); s7_pf_set_function(slot_value(global_slot(sc->IS_CHAR_UPPER_CASE)), is_char_upper_case_pf); s7_pf_set_function(slot_value(global_slot(sc->IS_CHAR_WHITESPACE)), is_char_whitespace_pf); s7_pf_set_function(slot_value(global_slot(sc->CHAR_UPCASE)), char_upcase_pf); s7_pf_set_function(slot_value(global_slot(sc->CHAR_DOWNCASE)), char_downcase_pf); s7_pf_set_function(slot_value(global_slot(sc->INTEGER_TO_CHAR)), integer_to_char_pf); s7_pf_set_function(slot_value(global_slot(sc->CURRENT_INPUT_PORT)), current_input_port_pf); s7_pf_set_function(slot_value(global_slot(sc->CURRENT_OUTPUT_PORT)), current_output_port_pf); s7_pf_set_function(slot_value(global_slot(sc->CURRENT_ERROR_PORT)), current_error_port_pf); s7_pf_set_function(slot_value(global_slot(sc->CLOSE_INPUT_PORT)), close_input_port_pf); s7_pf_set_function(slot_value(global_slot(sc->CLOSE_OUTPUT_PORT)), close_output_port_pf); s7_pf_set_function(slot_value(global_slot(sc->FLUSH_OUTPUT_PORT)), flush_output_port_pf); s7_gf_set_function(slot_value(global_slot(sc->PORT_FILENAME)), port_filename_pf); s7_gf_set_function(slot_value(global_slot(sc->PORT_LINE_NUMBER)), port_line_number_pf); s7_pf_set_function(slot_value(global_slot(sc->WITH_INPUT_FROM_FILE)), with_input_from_file_pf); s7_pf_set_function(slot_value(global_slot(sc->WITH_INPUT_FROM_STRING)), with_input_from_string_pf); s7_gf_set_function(slot_value(global_slot(sc->WITH_OUTPUT_TO_STRING)), with_output_to_string_pf); s7_pf_set_function(slot_value(global_slot(sc->WITH_OUTPUT_TO_FILE)), with_output_to_file_pf); s7_gf_set_function(slot_value(global_slot(sc->CALL_WITH_OUTPUT_STRING)), call_with_output_string_pf); s7_pf_set_function(slot_value(global_slot(sc->CALL_WITH_OUTPUT_FILE)), call_with_output_file_pf); s7_pf_set_function(slot_value(global_slot(sc->CALL_WITH_INPUT_STRING)), call_with_input_string_pf); s7_pf_set_function(slot_value(global_slot(sc->CALL_WITH_INPUT_FILE)), call_with_input_file_pf); #if WITH_SYSTEM_EXTRAS s7_gf_set_function(slot_value(global_slot(sc->DIRECTORY_TO_LIST)), directory_to_list_pf); #endif s7_if_set_function(slot_value(global_slot(sc->WRITE_BYTE)), write_byte_if); s7_pf_set_function(slot_value(global_slot(sc->WRITE_CHAR)), write_char_pf); s7_pf_set_function(slot_value(global_slot(sc->READ_BYTE)), read_byte_pf); s7_pf_set_function(slot_value(global_slot(sc->READ_CHAR)), read_char_pf); s7_pf_set_function(slot_value(global_slot(sc->PEEK_CHAR)), peek_char_pf); s7_pf_set_function(slot_value(global_slot(sc->NEWLINE)), newline_pf); s7_pf_set_function(slot_value(global_slot(sc->WRITE)), write_pf); s7_pf_set_function(slot_value(global_slot(sc->WRITE_STRING)), write_string_pf); s7_gf_set_function(slot_value(global_slot(sc->READ_STRING)), read_string_pf); s7_pf_set_function(slot_value(global_slot(sc->DISPLAY)), display_pf); s7_gf_set_function(slot_value(global_slot(sc->READ)), read_pf); s7_gf_set_function(slot_value(global_slot(sc->READ_LINE)), read_line_pf); s7_gf_set_function(slot_value(global_slot(sc->OBJECT_TO_STRING)), object_to_string_pf); s7_pf_set_function(slot_value(global_slot(sc->IS_EQ)), is_eq_pf); s7_pf_set_function(slot_value(global_slot(sc->IS_EQV)), is_eqv_pf); s7_pf_set_function(slot_value(global_slot(sc->IS_EQUAL)), is_equal_pf); s7_pf_set_function(slot_value(global_slot(sc->IS_MORALLY_EQUAL)), is_morally_equal_pf); /* + */ f = set_function_chooser(sc, sc->ADD, add_chooser); sc->add_class = c_function_class(f); add_2 = make_function_with_class(sc, f, "+", g_add_2, 2, 0, false, "+ opt"); add_1s = make_function_with_class(sc, f, "+", g_add_1s, 2, 0, false, "+ opt"); add_s1 = make_function_with_class(sc, f, "+", g_add_s1, 2, 0, false, "+ opt"); add_cs1 = make_function_with_class(sc, f, "+", g_add_cs1, 2, 0, false, "+ opt"); add_si = make_function_with_class(sc, f, "+", g_add_si, 2, 0, false, "+ opt"); add_sf = make_function_with_class(sc, f, "+", g_add_sf, 2, 0, false, "+ opt"); add_fs = make_function_with_class(sc, f, "+", g_add_fs, 2, 0, false, "+ opt"); add_ss_1ss = make_function_with_class(sc, f, "+", g_add_ss_1ss, 2, 0, false, "+ opt"); add_f_sf = make_function_with_class(sc, f, "+", g_add_f_sf, 2, 0, false, "+ opt"); /* - */ f = set_function_chooser(sc, sc->SUBTRACT, subtract_chooser); sc->subtract_class = c_function_class(f); subtract_1 = make_function_with_class(sc, f, "-", g_subtract_1, 1, 0, false, "- opt"); subtract_2 = make_function_with_class(sc, f, "-", g_subtract_2, 2, 0, false, "- opt"); subtract_s1 = make_function_with_class(sc, f, "-", g_subtract_s1, 2, 0, false, "- opt"); subtract_cs1 = make_function_with_class(sc, f, "-", g_subtract_cs1, 2, 0, false, "- opt"); subtract_csn = make_function_with_class(sc, f, "-", g_subtract_csn, 2, 0, false, "- opt"); subtract_sf = make_function_with_class(sc, f, "-", g_subtract_sf, 2, 0, false, "- opt"); subtract_2f = make_function_with_class(sc, f, "-", g_subtract_2f, 2, 0, false, "- opt"); subtract_fs = make_function_with_class(sc, f, "-", g_subtract_fs, 2, 0, false, "- opt"); subtract_f_sqr = make_function_with_class(sc, f, "-", g_subtract_f_sqr, 2, 0, false, "- opt"); #if (!WITH_GMP) sub_random_ic = make_function_with_class(sc, f, "random", g_sub_random_ic, 2, 0, false, "- opt"); sub_random_rc = make_function_with_class(sc, f, "random", g_sub_random_rc, 2, 0, false, "- opt"); #endif /* * */ f = set_function_chooser(sc, sc->MULTIPLY, multiply_chooser); sc->multiply_class = c_function_class(f); #if (!WITH_GMP) multiply_2 = make_function_with_class(sc, f, "*", g_multiply_2, 2, 0, false, "* opt"); multiply_is = make_function_with_class(sc, f, "*", g_multiply_is, 2, 0, false, "* opt"); multiply_si = make_function_with_class(sc, f, "*", g_multiply_si, 2, 0, false, "* opt"); multiply_fs = make_function_with_class(sc, f, "*", g_multiply_fs, 2, 0, false, "* opt"); multiply_sf = make_function_with_class(sc, f, "*", g_multiply_sf, 2, 0, false, "* opt"); sqr_ss = make_function_with_class(sc, f, "*", g_sqr_ss, 2, 0, false, "* opt"); mul_1ss = make_function_with_class(sc, f, "*", g_mul_1ss, 2, 0, false, "* opt"); multiply_cs_cos = make_function_with_class(sc, f, "*", g_multiply_cs_cos, 3, 0, false, "* opt"); mul_s_sin_s = make_function_with_class(sc, f, "*", g_mul_s_sin_s, 2, 0, false, "* opt"); mul_s_cos_s = make_function_with_class(sc, f, "*", g_mul_s_cos_s, 2, 0, false, "* opt"); #endif /* / */ f = set_function_chooser(sc, sc->DIVIDE, divide_chooser); #if (!WITH_GMP) invert_1 = make_function_with_class(sc, f, "/", g_invert_1, 1, 0, false, "/ opt"); divide_1r = make_function_with_class(sc, f, "/", g_divide_1r, 2, 0, false, "/ opt"); /* modulo */ f = set_function_chooser(sc, sc->MODULO, modulo_chooser); mod_si = make_function_with_class(sc, f, "modulo", g_mod_si, 2, 0, false, "modulo opt"); /* max */ f = set_function_chooser(sc, sc->MAX, max_chooser); max_f2 = make_function_with_class(sc, f, "max", g_max_f2, 2, 0, false, "max opt"); /* min */ f = set_function_chooser(sc, sc->MIN, min_chooser); min_f2 = make_function_with_class(sc, f, "min", g_min_f2, 2, 0, false, "min opt"); /* zero? */ set_function_chooser(sc, sc->IS_ZERO, is_zero_chooser); /* = */ f = set_function_chooser(sc, sc->EQ, equal_chooser); sc->equal_class = c_function_class(f); equal_s_ic = make_function_with_class(sc, f, "=", g_equal_s_ic, 2, 0, false, "= opt"); equal_length_ic = make_function_with_class(sc, f, "=", g_equal_length_ic, 2, 0, false, "= opt"); equal_2 = make_function_with_class(sc, f, "=", g_equal_2, 2, 0, false, "= opt"); mod_si_is_zero = make_function_with_class(sc, f, "=", g_mod_si_is_zero, 2, 0, false, "= opt"); /* < */ f = set_function_chooser(sc, sc->LT, less_chooser); less_s_ic = make_function_with_class(sc, f, "<", g_less_s_ic, 2, 0, false, "< opt"); less_s0 = make_function_with_class(sc, f, "<", g_less_s0, 2, 0, false, "< opt"); less_2 = make_function_with_class(sc, f, "<", g_less_2, 2, 0, false, "< opt"); less_length_ic = make_function_with_class(sc, f, "<", g_less_length_ic, 2, 0, false, "< opt"); /* > */ f = set_function_chooser(sc, sc->GT, greater_chooser); greater_s_ic = make_function_with_class(sc, f, ">", g_greater_s_ic, 2, 0, false, "> opt"); greater_s_fc = make_function_with_class(sc, f, ">", g_greater_s_fc, 2, 0, false, "> opt"); greater_2 = make_function_with_class(sc, f, ">", g_greater_2, 2, 0, false, "> opt"); greater_2_f = make_function_with_class(sc, f, ">", g_greater_2_f, 2, 0, false, "> opt"); /* <= */ f = set_function_chooser(sc, sc->LEQ, leq_chooser); leq_s_ic = make_function_with_class(sc, f, "<=", g_leq_s_ic, 2, 0, false, "<= opt"); leq_2 = make_function_with_class(sc, f, "<=", g_leq_2, 2, 0, false, "<= opt"); /* >= */ f = set_function_chooser(sc, sc->GEQ, geq_chooser); geq_s_ic = make_function_with_class(sc, f, ">=", g_geq_s_ic, 2, 0, false, ">= opt"); geq_s_fc = make_function_with_class(sc, f, ">=", g_geq_s_fc, 2, 0, false, ">= opt"); geq_2 = make_function_with_class(sc, f, ">=", g_geq_2, 2, 0, false, ">= opt"); geq_length_ic = make_function_with_class(sc, f, ">=", g_geq_length_ic, 2, 0, false, ">= opt"); /* random */ f = set_function_chooser(sc, sc->RANDOM, random_chooser); random_i = make_function_with_class(sc, f, "random", g_random_i, 1, 0, false, "random opt"); random_ic = make_function_with_class(sc, f, "random", g_random_ic, 1, 0, false, "random opt"); random_rc = make_function_with_class(sc, f, "random", g_random_rc, 1, 0, false, "random opt"); #endif /* list */ f = set_function_chooser(sc, sc->LIST, list_chooser); list_0 = make_function_with_class(sc, f, "list", g_list_0, 0, 0, false, "list opt"); list_1 = make_function_with_class(sc, f, "list", g_list_1, 1, 0, false, "list opt"); list_2 = make_function_with_class(sc, f, "list", g_list_2, 2, 0, false, "list opt"); /* aritable? */ f = set_function_chooser(sc, sc->IS_ARITABLE, is_aritable_chooser); is_aritable_ic = make_function_with_class(sc, f, "aritable?", g_is_aritable_ic, 2, 0, false, "aritable? opt"); /* char=? */ f = set_function_chooser(sc, sc->CHAR_EQ, char_equal_chooser); simple_char_eq = make_function_with_class(sc, f, "char=?", g_simple_char_eq, 2, 0, false, "char=? opt"); char_equal_s_ic = make_function_with_class(sc, f, "char=?", g_char_equal_s_ic, 2, 0, false, "char=? opt"); char_equal_2 = make_function_with_class(sc, f, "char=?", g_char_equal_2, 2, 0, false, "char=? opt"); /* char>? */ f = set_function_chooser(sc, sc->CHAR_GT, char_greater_chooser); char_greater_s_ic = make_function_with_class(sc, f, "char>?", g_char_greater_s_ic, 2, 0, false, "char>? opt"); char_greater_2 = make_function_with_class(sc, f, "char>?", g_char_greater_2, 2, 0, false, "char>? opt"); /* charCHAR_LT, char_less_chooser); char_less_s_ic = make_function_with_class(sc, f, "charCHAR_POSITION, char_position_chooser); char_position_csi = make_function_with_class(sc, f, "char-position", g_char_position_csi, 2, 1, false, "char-position opt"); /* string->symbol */ set_function_chooser(sc, sc->STRING_TO_SYMBOL, string_to_symbol_chooser); /* string=? */ f = set_function_chooser(sc, sc->STRING_EQ, string_equal_chooser); string_equal_s_ic = make_function_with_class(sc, f, "string=?", g_string_equal_s_ic, 2, 0, false, "string=? opt"); string_equal_2 = make_function_with_class(sc, f, "string=?", g_string_equal_2, 2, 0, false, "string=? opt"); /* substring */ substring_to_temp = s7_make_function(sc, "substring", g_substring_to_temp, 2, 1, false, "substring opt"); s7_function_set_class(substring_to_temp, slot_value(global_slot(sc->SUBSTRING))); /* number->string */ number_to_string_temp = s7_make_function(sc, "number->string", g_number_to_string_temp, 1, 1, false, "number->string opt"); s7_function_set_class(number_to_string_temp, slot_value(global_slot(sc->NUMBER_TO_STRING))); /* string>? */ f = set_function_chooser(sc, sc->STRING_GT, string_greater_chooser); string_greater_2 = make_function_with_class(sc, f, "string>?", g_string_greater_2, 2, 0, false, "string>? opt"); /* stringSTRING_LT, string_less_chooser); string_less_2 = make_function_with_class(sc, f, "stringSTRING_REF, string_ref_chooser); /* string-set! */ set_function_chooser(sc, sc->STRING_SET, string_set_chooser); /* string-append */ f = set_function_chooser(sc, sc->STRING_APPEND, string_append_chooser); string_append_to_temp = make_function_with_class(sc, f, "string-append", g_string_append_to_temp, 0, 0, true, "string-append opt"); /* symbol->string */ f = slot_value(global_slot(sc->SYMBOL_TO_STRING)); symbol_to_string_uncopied = s7_make_function(sc, "symbol->string", g_symbol_to_string_uncopied, 1, 0, false, "symbol->string opt"); s7_function_set_class(symbol_to_string_uncopied, f); /* vector-ref */ f = set_function_chooser(sc, sc->VECTOR_REF, vector_ref_chooser); vector_ref_ic = make_function_with_class(sc, f, "vector-ref", g_vector_ref_ic, 2, 0, false, "vector-ref opt"); vector_ref_ic_0 = make_function_with_class(sc, f, "vector-ref", g_vector_ref_ic_0, 1, 0, false, "vector-ref opt"); vector_ref_ic_1 = make_function_with_class(sc, f, "vector-ref", g_vector_ref_ic_1, 1, 0, false, "vector-ref opt"); vector_ref_ic_2 = make_function_with_class(sc, f, "vector-ref", g_vector_ref_ic_2, 1, 0, false, "vector-ref opt"); vector_ref_ic_3 = make_function_with_class(sc, f, "vector-ref", g_vector_ref_ic_3, 1, 0, false, "vector-ref opt"); vector_ref_add1 = make_function_with_class(sc, f, "vector-ref", g_vector_ref_add1, 2, 0, false, "vector-ref opt"); vector_ref_2 = make_function_with_class(sc, f, "vector-ref", g_vector_ref_2, 2, 0, false, "vector-ref opt"); vector_ref_gs = make_function_with_class(sc, f, "vector-ref", g_vector_ref_gs, 2, 0, false, "vector-ref opt"); constant_vector_ref_gs = make_function_with_class(sc, f, "vector-ref", g_constant_vector_ref_gs, 2, 0, false, "vector-ref opt"); /* vector-set! */ f = set_function_chooser(sc, sc->VECTOR_SET, vector_set_chooser); vector_set_ic = make_function_with_class(sc, f, "vector-set!", g_vector_set_ic, 3, 0, false, "vector-set! opt"); vector_set_vref = make_function_with_class(sc, f, "vector-set!", g_vector_set_vref, 3, 0, false, "vector-set! opt"); vector_set_vector_ref = make_function_with_class(sc, f, "vector-set!", g_vector_set_vector_ref, 3, 0, false, "vector-set! opt"); vector_set_3 = make_function_with_class(sc, f, "vector-set!", g_vector_set_3, 3, 0, false, "vector-set! opt"); /* list-ref */ f = set_function_chooser(sc, sc->LIST_REF, list_ref_chooser); list_ref_ic = make_function_with_class(sc, f, "list-ref", g_list_ref_ic, 2, 0, false, "list-ref opt"); /* list-set! */ f = set_function_chooser(sc, sc->LIST_SET, list_set_chooser); list_set_ic = make_function_with_class(sc, f, "list-set!", g_list_set_ic, 3, 0, false, "list-set! opt"); /* hash-table-ref */ f = set_function_chooser(sc, sc->HASH_TABLE_REF, hash_table_ref_chooser); hash_table_ref_2 = make_function_with_class(sc, f, "hash-table-ref", g_hash_table_ref_2, 2, 0, false, "hash-table-ref opt"); hash_table_ref_ss = make_function_with_class(sc, f, "hash-table-ref", g_hash_table_ref_ss, 2, 0, false, "hash-table-ref opt"); hash_table_ref_car = make_function_with_class(sc, f, "hash-table-ref", g_hash_table_ref_car, 2, 0, false, "hash-table-ref opt"); /* format */ f = set_function_chooser(sc, sc->FORMAT, format_chooser); format_allg = make_function_with_class(sc, f, "format", g_format_allg, 1, 0, true, "format opt"); format_allg_no_column = make_function_with_class(sc, f, "format", g_format_allg_no_column, 1, 0, true, "format opt"); format_just_newline = make_function_with_class(sc, f, "format", g_format_just_newline, 2, 0, false, "format opt"); /* not */ f = set_function_chooser(sc, sc->NOT, not_chooser); not_is_pair = make_function_with_class(sc, f, "not", g_not_is_pair, 1, 0, false, "not opt"); not_is_null = make_function_with_class(sc, f, "not", g_not_is_null, 1, 0, false, "not opt"); not_is_list = make_function_with_class(sc, f, "not", g_not_is_list, 1, 0, false, "not opt"); not_is_symbol = make_function_with_class(sc, f, "not", g_not_is_symbol, 1, 0, false, "not opt"); not_is_number = make_function_with_class(sc, f, "not", g_not_is_number, 1, 0, false, "not opt"); not_is_zero = make_function_with_class(sc, f, "not", g_not_is_zero, 1, 0, false, "not opt"); not_is_string = make_function_with_class(sc, f, "not", g_not_is_string, 1, 0, false, "not opt"); not_is_char = make_function_with_class(sc, f, "not", g_not_is_char, 1, 0, false, "not opt"); not_is_eq_ss = make_function_with_class(sc, f, "not", g_not_is_eq_ss, 1, 0, false, "not opt"); not_is_eq_sq = make_function_with_class(sc, f, "not", g_not_is_eq_sq, 1, 0, false, "not opt"); not_is_pair_car = make_function_with_class(sc, f, "not", g_not_is_pair_car, 1, 0, false, "not opt"); not_c_c = make_function_with_class(sc, f, "not", g_not_c_c, 1, 0, false, "not opt"); /* pair? */ f = set_function_chooser(sc, sc->IS_PAIR, is_pair_chooser); is_pair_car = make_function_with_class(sc, f, "pair?", g_is_pair_car, 1, 0, false, "pair? opt"); is_pair_cdr = make_function_with_class(sc, f, "pair?", g_is_pair_cdr, 1, 0, false, "pair? opt"); is_pair_cadr = make_function_with_class(sc, f, "pair?", g_is_pair_cadr, 1, 0, false, "pair? opt"); /* null? */ f = set_function_chooser(sc, sc->IS_NULL, is_null_chooser); is_null_cdr = make_function_with_class(sc, f, "null?", g_is_null_cdr, 1, 0, false, "null? opt"); /* eq? */ f = set_function_chooser(sc, sc->IS_EQ, is_eq_chooser); is_eq_car = make_function_with_class(sc, f, "eq?", g_is_eq_car, 2, 0, false, "eq? opt"); is_eq_car_q = make_function_with_class(sc, f, "eq?", g_is_eq_car_q, 2, 0, false, "eq? opt"); is_eq_caar_q = make_function_with_class(sc, f, "eq?", g_is_eq_caar_q, 2, 0, false, "eq? opt"); /* member */ f = set_function_chooser(sc, sc->MEMBER, member_chooser); member_ss = make_function_with_class(sc, f, "member", g_member_ss, 2, 0, false, "member opt"); member_sq = make_function_with_class(sc, f, "member", g_member_sq, 2, 0, false, "member opt"); member_num_s = make_function_with_class(sc, f, "member", g_member_num_s, 2, 0, false, "member opt"); /* memq */ #if (!WITH_PURE_S7) f = set_function_chooser(sc, sc->MEMQ, memq_chooser); /* is pure-s7, use member here */ #endif memq_3 = make_function_with_class(sc, f, "memq", g_memq_3, 2, 0, false, "memq opt"); memq_4 = make_function_with_class(sc, f, "memq", g_memq_4, 2, 0, false, "memq opt"); memq_any = make_function_with_class(sc, f, "memq", g_memq_any, 2, 0, false, "memq opt"); memq_car = make_function_with_class(sc, f, "memq", g_memq_car, 2, 0, false, "memq opt"); /* read-char */ f = set_function_chooser(sc, sc->READ_CHAR, read_char_chooser); read_char_0 = make_function_with_class(sc, f, "read-char", g_read_char_0, 0, 0, false, "read-char opt"); read_char_1 = make_function_with_class(sc, f, "read-char", g_read_char_1, 1, 0, false, "read-char opt"); /* write-char */ f = set_function_chooser(sc, sc->WRITE_CHAR, write_char_chooser); write_char_1 = make_function_with_class(sc, f, "write-char", g_write_char_1, 1, 0, false, "write-char opt"); /* read-line */ read_line_uncopied = s7_make_function(sc, "read-line", g_read_line_uncopied, 1, 1, false, "read-line opt"); s7_function_set_class(read_line_uncopied, slot_value(global_slot(sc->READ_LINE))); /* write-string */ set_function_chooser(sc, sc->WRITE_STRING, write_string_chooser); /* eval-string */ set_function_chooser(sc, sc->EVAL_STRING, eval_string_chooser); /* or and if simple cases */ or_direct = s7_make_function(sc, "or", g_or_direct, 0, 0, true, "or opt"); and_direct = s7_make_function(sc, "and", g_and_direct, 0, 0, true, "and opt"); if_direct = s7_make_function(sc, "if", g_if_direct, 2, 1, false, "if opt"); or_all_x = s7_make_function(sc, "or", g_or_all_x, 0, 0, true, "or opt"); or_all_x_2 = s7_make_function(sc, "or", g_or_all_x_2, 2, 0, false, "or opt"); or_all_x_2s = s7_make_function(sc, "or", g_or_all_x_2s, 2, 0, false, "or opt"); and_all_x = s7_make_function(sc, "and", g_and_all_x, 0, 0, true, "and opt"); and_all_x_2 = s7_make_function(sc, "and", g_and_all_x_2, 2, 0, false, "and opt"); if_all_x1 = s7_make_function(sc, "if", g_if_all_x1, 2, 0, false, "if opt"); if_all_x2 = s7_make_function(sc, "if", g_if_all_x2, 3, 0, false, "if opt"); if_all_not_x1 = s7_make_function(sc, "if", g_if_all_not_x1, 2, 0, false, "if opt"); if_all_not_x2 = s7_make_function(sc, "if", g_if_all_not_x2, 3, 0, false, "if opt"); if_all_x_qq = s7_make_function(sc, "if", g_if_all_x_qq, 3, 0, false, "if opt"); if_all_x_qa = s7_make_function(sc, "if", g_if_all_x_qa, 3, 0, false, "if opt"); or_s_direct = s7_make_function(sc, "or", g_or_s_direct, 0, 0, true, "or opt"); and_s_direct = s7_make_function(sc, "and", g_and_s_direct, 0, 0, true, "and opt"); if_s_direct = s7_make_function(sc, "if", g_if_s_direct, 2, 1, false, "if opt"); } static s7_pointer collect_collisions(s7_scheme *sc, s7_pointer lst, s7_pointer e) { /* collect local variable names from let/do (pre-error-check) */ s7_pointer p; sc->w = e; for (p = lst; is_pair(p); p = cdr(p)) if ((is_pair(car(p))) && (is_symbol(caar(p)))) sc->w = cons(sc, add_sym_to_list(sc, caar(p)), sc->w); return(sc->w); } static s7_pointer collect_collisions_star(s7_scheme *sc, s7_pointer lst, s7_pointer e) { /* collect local variable names from lambda arglists (pre-error-check) */ s7_pointer p; sc->w = e; for (p = lst; is_pair(p); p = cdr(p)) { s7_pointer car_p; car_p = car(p); if (is_pair(car_p)) car_p = car(car_p); if ((is_symbol(car_p)) && (!is_keyword(car_p))) sc->w = cons(sc, add_sym_to_list(sc, car_p), sc->w); } return(sc->w); } #define choose_c_function(Sc, Expr, Func, Args) set_c_function(Expr, c_function_chooser(Func)(Sc, Func, Args, Expr)) static bool optimize_thunk(s7_scheme *sc, s7_pointer expr, s7_pointer func, int hop) { /* fprintf(stderr, "expr: %s, hop: %d\n", DISPLAY(expr), hop); */ if (is_immutable_symbol(car(expr))) hop = 1; if (is_closure(func)) { if (is_null(closure_args(func))) /* no rest arg funny business */ { if (is_safe_closure(func)) { s7_pointer body; body = closure_body(func); set_unsafe_optimize_op(expr, hop + OP_SAFE_THUNK); if (is_null(cdr(body))) { if (is_optimized(car(body))) set_unsafe_optimize_op(expr, hop + OP_SAFE_THUNK_E); else { if ((is_pair(car(body))) && (is_syntactic(caar(body)))) { set_optimize_op(expr, hop + OP_SAFE_THUNK_P); if (typesflag(car(body)) != SYNTACTIC_PAIR) { pair_set_syntax_op(car(body), symbol_syntax_op(caar(body))); set_type(car(body), SYNTACTIC_PAIR); } } } } } else set_unsafe_optimize_op(expr, hop + OP_THUNK); set_opt_lambda(expr, func); } return(false); /* false because currently the C_PP stuff assumes safe procedure calls */ } if (is_c_function(func)) { if (c_function_required_args(func) != 0) return(false); if ((is_safe_procedure(func)) || (c_function_call(func) == g_list) || /* (list) is safe */ (c_function_call(func) == g_values)) /* (values) is safe */ { set_safe_optimize_op(expr, hop + OP_SAFE_C_C); choose_c_function(sc, expr, func, 0); return(true); } return(false); } if (is_closure_star(func)) { if ((is_proper_list(sc, closure_args(func))) && (has_simple_args(closure_body(func)))) { set_unsafe_optimize_op(expr, hop + ((is_safe_closure(func)) ? OP_SAFE_CLOSURE_STAR : OP_CLOSURE_STAR)); set_opt_lambda(expr, func); } } return(false); } static int combine_ops(s7_scheme *sc, combine_op_t op1, s7_pointer e1, s7_pointer e2) { int op2; op2 = op_no_hop(e2); /* e_c_pp case (1) is slightly different from the others: e2 is not a part of e1 */ switch (op1) { case E_C_P: switch (op2) { case OP_SAFE_C_C: return(OP_SAFE_C_opCq); /* this includes the multi-arg C_C cases */ case OP_SAFE_C_S: return(OP_SAFE_C_opSq); case OP_SAFE_C_SS: return(OP_SAFE_C_opSSq); case OP_SAFE_C_SQ: return(OP_SAFE_C_opSQq); case OP_SAFE_C_SC: return(OP_SAFE_C_opSCq); case OP_SAFE_C_CS: return(OP_SAFE_C_opCSq); case OP_SAFE_C_opSq: return(OP_SAFE_C_op_opSq_q); case OP_SAFE_C_S_opSq: return(OP_SAFE_C_op_S_opSq_q); case OP_SAFE_C_A: return(OP_SAFE_C_opAq); case OP_SAFE_C_AA: return(OP_SAFE_C_opAAq); case OP_SAFE_C_AAA: return(OP_SAFE_C_opAAAq); } return(OP_SAFE_C_Z); /* this splits out to A in optimize_func_one_arg */ case E_C_SP: switch (op2) { case OP_SAFE_C_S: set_opt_sym1(cdr(e1), cadr(e2)); return(OP_SAFE_C_S_opSq); case OP_SAFE_C_C: set_opt_pair1(cdr(e1), cdr(e2)); return(OP_SAFE_C_S_opCq); case OP_SAFE_C_SC: set_opt_sym1(cdr(e1), cadr(e2)); set_opt_con2(cdr(e1), caddr(e2)); return(OP_SAFE_C_S_opSCq); case OP_SAFE_C_CS: /* (* a (- 1 b)), e1 is the full expr, e2 is (- 1 b) */ set_opt_con1(cdr(e1), cadr(e2)); set_opt_sym2(cdr(e1), caddr(e2)); return(OP_SAFE_C_S_opCSq); case OP_SAFE_C_SS: /* (* a (- b c)) */ set_opt_sym1(cdr(e1), cadr(e2)); set_opt_sym2(cdr(e1), caddr(e2)); return(OP_SAFE_C_S_opSSq); case OP_SAFE_C_opSSq_S: return(OP_SAFE_C_S_op_opSSq_Sq); case OP_SAFE_C_S_opSSq: return(OP_SAFE_C_S_op_S_opSSqq); case OP_SAFE_C_opSSq_opSSq: return(OP_SAFE_C_S_op_opSSq_opSSqq); case OP_SAFE_C_SZ: return(OP_SAFE_C_S_opSZq); case OP_SAFE_C_A: return(OP_SAFE_C_S_opAq); case OP_SAFE_C_AA: return(OP_SAFE_C_S_opAAq); case OP_SAFE_C_CSA: case OP_SAFE_C_CAS: case OP_SAFE_C_SCA: case OP_SAFE_C_SAS: case OP_SAFE_C_SSA: case OP_SAFE_C_AAA: return(OP_SAFE_C_S_opAAAq); } /* fprintf(stderr, "%s: %s\n", opt_names[op2], DISPLAY(e1)); */ return(OP_SAFE_C_SZ); case E_C_PS: switch (op2) { case OP_SAFE_C_C: return(OP_SAFE_C_opCq_S); case OP_SAFE_C_S: return(OP_SAFE_C_opSq_S); case OP_SAFE_C_CS: return(OP_SAFE_C_opCSq_S); case OP_SAFE_C_SC: return(OP_SAFE_C_opSCq_S); case OP_SAFE_C_SS: return(OP_SAFE_C_opSSq_S); case OP_SAFE_C_opSq: return(OP_SAFE_C_op_opSq_q_S); case OP_SAFE_C_opSSq: return(OP_SAFE_C_op_opSSq_q_S); } return(OP_SAFE_C_ZS); case E_C_PC: switch (op2) { case OP_SAFE_C_C: return(OP_SAFE_C_opCq_C); case OP_SAFE_C_S: return(OP_SAFE_C_opSq_C); case OP_SAFE_C_CS: return(OP_SAFE_C_opCSq_C); case OP_SAFE_C_SS: return(OP_SAFE_C_opSSq_C); case OP_SAFE_C_SC: return(OP_SAFE_C_opSCq_C); case OP_SAFE_C_opSq: return(OP_SAFE_C_op_opSq_q_C); case OP_SAFE_C_opSSq: return(OP_SAFE_C_op_opSSq_q_C); } return(OP_SAFE_C_ZC); case E_C_CP: switch (op2) { case OP_SAFE_C_C: set_opt_pair1(cdr(e1), cdr(e2)); return(OP_SAFE_C_C_opCq); case OP_SAFE_C_S: set_opt_sym1(cdr(e1), cadr(e2)); return(OP_SAFE_C_C_opSq); case OP_SAFE_C_CS: set_opt_con1(cdr(e1), cadr(e2)); set_opt_sym2(cdr(e1), caddr(e2)); return(OP_SAFE_C_C_opCSq); case OP_SAFE_C_SC: set_opt_sym1(cdr(e1), cadr(e2)); set_opt_con2(cdr(e1), caddr(e2)); return(OP_SAFE_C_C_opSCq); case OP_SAFE_C_SS: set_opt_sym1(cdr(e1), cadr(e2)); set_opt_sym2(cdr(e1), caddr(e2)); return(OP_SAFE_C_C_opSSq); case OP_SAFE_C_S_opCq: return(OP_SAFE_C_C_op_S_opCqq); } return(OP_SAFE_C_CZ); case E_C_PP: switch (op2) { case OP_SAFE_C_S: if (optimize_op_match(e1, OP_SAFE_C_S)) return(OP_SAFE_C_opSq_opSq); if (optimize_op_match(e1, OP_SAFE_C_SS)) return(OP_SAFE_C_opSSq_opSq); break; case OP_SAFE_C_C: if (optimize_op_match(e1, OP_SAFE_C_C)) return(OP_SAFE_C_opCq_opCq); if (optimize_op_match(e1, OP_SAFE_C_SS)) return(OP_SAFE_C_opSSq_opCq); break; case OP_SAFE_C_SC: if (optimize_op_match(e1, OP_SAFE_C_SC)) return(OP_SAFE_C_opSCq_opSCq); break; case OP_SAFE_C_SS: if (optimize_op_match(e1, OP_SAFE_C_C)) return(OP_SAFE_C_opCq_opSSq); if (optimize_op_match(e1, OP_SAFE_C_SS)) return(OP_SAFE_C_opSSq_opSSq); if (optimize_op_match(e1, OP_SAFE_C_S)) return(OP_SAFE_C_opSq_opSSq); break; } return(OP_SAFE_C_ZZ); default: break; } return(OP_NO_OP); } static void annotate_args(s7_scheme *sc, s7_pointer args, s7_pointer e) { s7_pointer p; for (p = args; is_pair(p); p = cdr(p)) set_c_call(p, all_x_eval(sc, car(p), e, (s7_is_list(sc, e)) ? pair_symbol_is_safe : let_symbol_is_safe)); } static void annotate_arg(s7_scheme *sc, s7_pointer arg, s7_pointer e) { /* if sc->envir is sc->NIL, we're at the top-level, but the global_slot check should suffice for that */ set_c_call(arg, all_x_eval(sc, car(arg), e, (s7_is_list(sc, e)) ? pair_symbol_is_safe : let_symbol_is_safe)); } static void opt_generator(s7_scheme *sc, s7_pointer func, s7_pointer expr, int hop) { /* this is an optimization aimed at generators. So we might as well go all out... */ if (is_global(car(expr))) /* not a function argument for example */ { s7_pointer body; body = closure_body(func); if ((s7_list_length(sc, body) == 2) && (caar(body) == sc->LET_SET) && (is_optimized(car(body))) && (optimize_op(car(body)) == HOP_SAFE_C_SQS) && (caadr(body) == sc->WITH_LET) && (is_symbol(cadr(cadr(body))))) { s7_pointer args; args = closure_args(func); if ((cadr(cadr(body)) == car(args)) && (is_pair(cdr(args))) && (is_pair(cadr(args))) && (cadddr(car(body)) == caadr(closure_args(func)))) { if (is_global(car(expr))) hop = 1; /* it's my party... */ set_optimize_op(expr, hop + OP_SAFE_CLOSURE_STAR_S0); set_opt_sym1(cdr(expr), cadr(caddar(body))); set_opt_pair2(cdr(expr), cddadr(body)); } } } } static bool is_lambda(s7_scheme *sc, s7_pointer sym) { return((sym == sc->LAMBDA) && (symbol_id(sym) == 0)); /* symbol_id==0 means it has never been rebound (T_GLOBAL might not be set for initial stuff) */ } static bool optimize_func_one_arg(s7_scheme *sc, s7_pointer expr, s7_pointer func, int hop, int pairs, int symbols, int quotes, int bad_pairs, s7_pointer e) { s7_pointer arg1; /* very often, expr is already optimized */ arg1 = cadr(expr); if ((pairs == 0) && (is_immutable_symbol(car(expr)))) hop = 1; if (((is_c_function(func)) && (c_function_required_args(func) <= 1) && (c_function_all_args(func) >= 1)) || ((is_c_function_star(func)) && (c_function_all_args(func) == 1))) /* surely no need to check key here? */ { bool func_is_safe; func_is_safe = is_safe_procedure(func); if (pairs == 0) { if (func_is_safe) /* safe c function */ { set_safe_optimize_op(expr, hop + ((symbols == 0) ? OP_SAFE_C_C : OP_SAFE_C_S)); /* we can't simply check is_global here to forego symbol value lookup later because we aren't * tracking local vars, so the global bit may be on right now, but won't be when * this code is evaluated. But memq(sym, e) would catch such cases. * I think it has already been checked for func, so we only need to look for arg1. * But global symbols are rare, and I don't see a huge savings in the lookup time -- * in callgrind it's about 7/lookup in both cases. */ choose_c_function(sc, expr, func, 1); return(true); } else /* c function is not safe */ { set_unsafely_optimized(expr); if (symbols == 0) { set_optimize_op(expr, hop + OP_C_A); annotate_arg(sc, cdr(expr), e); set_arglist_length(expr, small_int(1)); } else { if (c_function_call(func) == g_read) set_optimize_op(expr, hop + OP_READ_S); else set_optimize_op(expr, hop + OP_C_S); } choose_c_function(sc, expr, func, 1); return(false); } } else /* pairs == 1 */ { if (bad_pairs == 0) { if (func_is_safe) { int op; op = combine_ops(sc, E_C_P, expr, arg1); set_safe_optimize_op(expr, hop + op); /* fallback is Z */ if (!hop) { clear_hop(arg1); } else { if ((op == OP_SAFE_C_Z) && (is_all_x_op(optimize_op(arg1)))) { /* this is confusing! this is much faster than safe_c_z, but * the parallel let_z|a case seems to claim that z is faster. */ set_optimize_op(expr, hop + OP_SAFE_C_A); annotate_arg(sc, cdr(expr), e); } } choose_c_function(sc, expr, func, 1); return(true); } if (is_all_x_op(optimize_op(arg1))) { set_unsafe_optimize_op(expr, hop + OP_C_A); annotate_arg(sc, cdr(expr), e); set_arglist_length(expr, small_int(1)); choose_c_function(sc, expr, func, 1); return(false); } } else /* bad_pairs == 1 */ { if (quotes == 1) { if (func_is_safe) { set_safe_optimize_op(expr, hop + OP_SAFE_C_Q); choose_c_function(sc, expr, func, 1); return(true); } set_unsafe_optimize_op(expr, hop + OP_C_A); annotate_arg(sc, cdr(expr), e); set_arglist_length(expr, small_int(1)); choose_c_function(sc, expr, func, 1); return(false); } else /* quotes == 0 */ { if (!func_is_safe) { s7_pointer lambda_expr; lambda_expr = arg1; if ((is_pair(lambda_expr)) && (is_lambda(sc, car(lambda_expr))) && /* check for stuff like (define (f) (eval (lambda 2))) */ (is_pair(cdr(lambda_expr))) && (is_pair(cddr(lambda_expr)))) { if ((c_function_call(func) == g_call_with_exit) && (is_pair(cadr(lambda_expr))) && (is_null(cdadr(lambda_expr)))) { set_unsafe_optimize_op(expr, hop + OP_CALL_WITH_EXIT); choose_c_function(sc, expr, func, 1); set_opt_pair2(expr, cdr(lambda_expr)); return(false); } } } set_unsafe_optimize_op(expr, hop + ((is_h_optimized(arg1)) ? OP_C_Z : OP_C_P)); choose_c_function(sc, expr, func, 1); return(false); } } } if (!func_is_safe) { set_unsafe_optimize_op(expr, hop + ((is_h_optimized(arg1)) ? OP_C_Z : OP_C_P)); choose_c_function(sc, expr, func, 1); return(false); } return(is_optimized(expr)); } if (is_closure(func)) { bool safe_case, global_case; s7_pointer body; if (closure_arity_to_int(sc, func) != 1) return(false); /* this is checking for dotted arglists: boolean=? for example. To optimize these calls, we need op_closure cases that * bind the dotted name to the remaining args as a list. This does not happen enough to be worth the trouble. */ safe_case = is_safe_closure(func); global_case = is_global(car(expr)); body = closure_body(func); if (pairs == 0) { if (is_symbol(arg1)) { if (safe_case) { set_optimize_op(expr, hop + ((global_case) ? OP_SAFE_GLOSURE_S : OP_SAFE_CLOSURE_S)); if (is_null(cdr(body))) { if ((global_case) && (is_optimized(car(body)))) set_optimize_op(expr, hop + OP_SAFE_GLOSURE_S_E); else { if ((is_pair(car(body))) && (is_syntactic(caar(body)))) { set_optimize_op(expr, hop + OP_SAFE_CLOSURE_S_P); if (typesflag(car(body)) != SYNTACTIC_PAIR) { pair_set_syntax_op(car(body), symbol_syntax_op(caar(body))); set_type(car(body), SYNTACTIC_PAIR); } } } } } else set_optimize_op(expr, hop + ((global_case) ? OP_GLOSURE_S : OP_CLOSURE_S)); set_opt_sym2(expr, arg1); } else { set_optimize_op(expr, hop + ((safe_case) ? OP_SAFE_CLOSURE_C : OP_CLOSURE_C)); set_opt_con2(expr, arg1); } set_opt_lambda(expr, func); set_unsafely_optimized(expr); return(false); } else /* pairs == 1 */ { if (bad_pairs == 0) { if ((is_optimized(arg1)) && (is_all_x_op(optimize_op(arg1)))) { set_unsafely_optimized(expr); annotate_arg(sc, cdr(expr), e); set_arglist_length(expr, small_int(1)); if (safe_case) set_optimize_op(expr, hop + ((global_case) ? OP_SAFE_GLOSURE_A : OP_SAFE_CLOSURE_A)); else set_optimize_op(expr, hop + ((global_case) ? OP_GLOSURE_A : OP_CLOSURE_A)); set_opt_lambda(expr, func); return(false); } } else /* bad_pairs == 1 */ { if (quotes == 1) { set_unsafe_optimize_op(expr, hop + ((safe_case) ? OP_SAFE_CLOSURE_Q : OP_CLOSURE_Q)); set_opt_lambda(expr, func); return(false); } } if ((quotes == 0) && (global_case)) { set_unsafe_optimize_op(expr, hop + ((safe_case) ? OP_SAFE_GLOSURE_P : OP_GLOSURE_P)); set_opt_lambda(expr, func); return(false); } } if (pairs == (quotes + all_x_count(expr))) { set_unsafe_optimize_op(expr, hop + ((safe_case ? OP_SAFE_CLOSURE_A : OP_CLOSURE_A))); annotate_arg(sc, cdr(expr), e); set_opt_lambda(expr, func); set_arglist_length(expr, small_int(1)); return(false); } return(is_optimized(expr)); } if (is_closure_star(func)) { bool safe_case; if ((!has_simple_args(closure_body(func))) || (is_null(closure_args(func)))) return(false); safe_case = is_safe_closure(func); if ((pairs == 0) && (symbols == 1)) { set_unsafely_optimized(expr); if (safe_case) { set_optimize_op(expr, hop + OP_SAFE_CLOSURE_STAR_S); if (closure_star_arity_to_int(sc, func) == 2) { s7_pointer defarg2; defarg2 = cadr(closure_args(func)); if ((is_pair(defarg2)) && (s7_is_zero(cadr(defarg2)))) opt_generator(sc, func, expr, hop); } } else set_optimize_op(expr, hop + OP_CLOSURE_STAR_S); set_opt_lambda(expr, func); set_opt_sym2(expr, arg1); return(false); } if ((!arglist_has_rest(sc, closure_args(func))) && (pairs == (quotes + all_x_count(expr)))) { set_unsafe_optimize_op(expr, hop + ((safe_case) ? OP_SAFE_CLOSURE_STAR_ALL_X : OP_CLOSURE_STAR_ALL_X)); annotate_arg(sc, cdr(expr), e); set_opt_lambda(expr, func); set_arglist_length(expr, small_int(1)); return(false); } return(is_optimized(expr)); } if ((pairs == 0) && (s7_is_vector(func))) { set_safe_optimize_op(expr, hop + ((symbols == 1) ? OP_VECTOR_S : OP_VECTOR_C)); set_opt_vector(expr, func); return(true); } /* unknown_* is set later */ return(is_optimized(expr)); } static bool rdirect_memq(s7_scheme *sc, s7_pointer symbol, s7_pointer symbols) { s7_pointer x; for (x = symbols; is_pair(x); x = cdr(x)) { if (car(x) == symbol) return(true); x = cdr(x); if (car(x) == symbol) /* car(nil)=unspec, cdr(unspec)=unspec! This only works for lists known to be undotted and non-circular */ return(true); } return(false); } static s7_pointer find_uncomplicated_symbol(s7_scheme *sc, s7_pointer symbol, s7_pointer e) { s7_pointer x; long long int id; if ((symbol_tag(symbol) == sc->syms_tag) && (rdirect_memq(sc, symbol, e))) /* it's probably a local variable reference */ return(sc->NIL); if (is_global(symbol)) return(global_slot(symbol)); id = symbol_id(symbol); for (x = sc->envir; id < let_id(x); x = outlet(x)); for (; is_let(x); x = outlet(x)) { s7_pointer y; if (let_id(x) == id) return(local_slot(symbol)); for (y = let_slots(x); is_slot(y); y = next_slot(y)) if (slot_symbol(y) == symbol) return(y); } return(global_slot(symbol)); /* it's no longer global perhaps (local definition now inaccessible) */ } static bool unsafe_is_safe(s7_scheme *sc, s7_pointer func, s7_pointer arg1, s7_pointer arg2, s7_pointer arg3, s7_pointer e) { s7_pointer f = NULL; /* arg3 if member|assoc */ if (!arg3) return(true); f = arg3; if (!is_symbol(f)) return(false); f = find_uncomplicated_symbol(sc, f, e); /* form_is_safe -- how to catch local c-funcs here? */ if (is_slot(f)) { f = slot_value(f); return((is_c_function(f)) && (is_safe_procedure(f))); } return(false); } static bool optimize_func_two_args(s7_scheme *sc, s7_pointer expr, s7_pointer func, int hop, int pairs, int symbols, int quotes, int bad_pairs, s7_pointer e) { s7_pointer arg1, arg2; arg1 = cadr(expr); arg2 = caddr(expr); if ((pairs == 0) && (is_immutable_symbol(car(expr)))) hop = 1; if ((is_c_function(func) && (c_function_required_args(func) <= 2) && (c_function_all_args(func) >= 2)) || ((is_c_function_star(func)) && (c_function_all_args(func) == 2) && (!is_keyword(arg1)))) { /* this is a mess */ bool func_is_safe; func_is_safe = is_safe_procedure(func); if (pairs == 0) { if ((func_is_safe) || ((is_possibly_safe(func)) && (unsafe_is_safe(sc, func, arg1, arg2, NULL, e)))) { /* another case here: set-car! and set-cdr! are safe if symbols==1 and arg1 is the symbol (i.e. arg2 is a constant) */ if (symbols == 0) set_optimize_op(expr, hop + OP_SAFE_C_C); else { if (symbols == 2) set_optimize_op(expr, hop + OP_SAFE_C_SS); /* these two symbols are almost never the same, (sqrt (+ (* x x) (* y y))) */ else set_optimize_op(expr, hop + ((is_symbol(arg1)) ? OP_SAFE_C_SC : OP_SAFE_C_CS)); } set_optimized(expr); choose_c_function(sc, expr, func, 2); return(true); } set_unsafely_optimized(expr); if (symbols == 2) { if (c_function_call(func) == g_apply) { set_optimize_op(expr, hop + OP_APPLY_SS); set_opt_cfunc(expr, func); set_opt_sym2(expr, arg2); } else { set_optimize_op(expr, hop + OP_C_SS); choose_c_function(sc, expr, func, 2); } } else { set_optimize_op(expr, hop + OP_C_ALL_X); annotate_args(sc, cdr(expr), e); set_arglist_length(expr, small_int(2)); choose_c_function(sc, expr, func, 2); if (is_safe_procedure(opt_cfunc(expr))) { clear_unsafe(expr); set_optimized(expr); /* symbols can be 0..2 here, no pairs */ if (symbols == 1) { if (is_symbol(arg1)) set_optimize_op(expr, hop + OP_SAFE_C_SC); else set_optimize_op(expr, hop + OP_SAFE_C_CS); } else { if (symbols == 2) set_optimize_op(expr, hop + OP_SAFE_C_SS); else set_optimize_op(expr, hop + OP_SAFE_C_C); } return(true); } } return(false); } /* pairs != 0 */ if ((bad_pairs == 0) && (pairs == 2)) { if ((func_is_safe) || ((is_possibly_safe(func)) && (unsafe_is_safe(sc, func, arg1, arg2, NULL, e)))) { int op; op = combine_ops(sc, E_C_PP, arg1, arg2); set_safe_optimize_op(expr, hop + op); /* fallback here is ZZ */ if (!hop) { clear_hop(arg1); clear_hop(arg2); } else { if (op == OP_SAFE_C_ZZ) { if (is_all_x_safe(sc, arg1)) { if (is_all_x_safe(sc, arg2)) { set_optimize_op(expr, hop + OP_SAFE_C_AA); annotate_args(sc, cdr(expr), e); set_arglist_length(expr, small_int(2)); } else { if (optimize_op(arg1) == HOP_SAFE_C_C) set_optimize_op(expr, hop + OP_SAFE_C_opCq_Z); else { set_optimize_op(expr, hop + OP_SAFE_C_AZ); annotate_arg(sc, cdr(expr), e); set_arglist_length(expr, small_int(2)); } } } else { if (is_all_x_safe(sc, arg2)) { set_optimize_op(expr, hop + OP_SAFE_C_ZA); annotate_arg(sc, cddr(expr), e); set_arglist_length(expr, small_int(2)); } } } } choose_c_function(sc, expr, func, 2); /* this might change the op to safe_c_c, so it has to be last */ return(true); } } if ((bad_pairs == 0) && (pairs == 1)) { if ((func_is_safe) || ((is_possibly_safe(func)) && (unsafe_is_safe(sc, func, arg1, arg2, NULL, e)))) { combine_op_t orig_op; int op; if (is_pair(arg1)) { if (is_symbol(arg2)) orig_op = E_C_PS; else orig_op = E_C_PC; op = combine_ops(sc, orig_op, expr, arg1); if (!hop) clear_hop(arg1); } else { if (is_symbol(arg1)) orig_op = E_C_SP; else orig_op = E_C_CP; op = combine_ops(sc, orig_op, expr, arg2); if (!hop) clear_hop(arg2); } set_safe_optimize_op(expr, hop + op); choose_c_function(sc, expr, func, 2); return(true); } if (symbols == 1) { if (is_symbol(arg1)) { if (is_safe_c_s(arg2)) { set_unsafe_optimize_op(expr, hop + OP_C_S_opSq); set_opt_sym1(cdr(expr), cadr(arg2)); choose_c_function(sc, expr, func, 2); return(false); } if (optimize_op_match(arg2, OP_SAFE_C_C)) { set_unsafe_optimize_op(expr, hop + OP_C_S_opCq); set_opt_pair1(cdr(expr), cdr(arg2)); choose_c_function(sc, expr, func, 2); return(false); } } } } if ((bad_pairs == 1) && (quotes == 1)) { if ((func_is_safe) || ((is_possibly_safe(func)) && (unsafe_is_safe(sc, func, arg1, arg2, NULL, e)))) { if (symbols == 1) { set_optimized(expr); if (is_symbol(arg1)) set_optimize_op(expr, hop + OP_SAFE_C_SQ); else set_optimize_op(expr, hop + OP_SAFE_C_QS); choose_c_function(sc, expr, func, 2); return(true); } else { if (pairs == 1) { /* Q must be 1, symbols = 0, pairs = 1 (the quote), so this must be CQ or QC? */ set_optimized(expr); if (is_pair(arg1)) set_optimize_op(expr, hop + OP_SAFE_C_QC); else set_optimize_op(expr, hop + OP_SAFE_C_CQ); choose_c_function(sc, expr, func, 2); return(true); } } } else { if (pairs == 1) { set_unsafe_optimize_op(expr, hop + OP_C_ALL_X); annotate_args(sc, cdr(expr), e); set_arglist_length(expr, small_int(2)); choose_c_function(sc, expr, func, 2); return(false); } } } if (quotes == 2) { if ((func_is_safe) || ((is_possibly_safe(func)) && (unsafe_is_safe(sc, func, arg1, arg2, NULL, e)))) { set_safe_optimize_op(expr, hop + OP_SAFE_C_QQ); choose_c_function(sc, expr, func, 2); return(true); } set_unsafe_optimize_op(expr, hop + OP_C_ALL_X); annotate_args(sc, cdr(expr), e); set_arglist_length(expr, small_int(2)); choose_c_function(sc, expr, func, 2); return(false); } if ((pairs == 1) && (quotes == 0) && ((func_is_safe) || ((is_possibly_safe(func)) && (unsafe_is_safe(sc, func, arg1, arg2, NULL, e))))) { if (symbols == 1) { set_optimized(expr); if (is_symbol(arg1)) { if ((bad_pairs == 0) || (is_h_optimized(arg2))) /* bad_pair && h_optimized happens a lot */ { set_optimize_op(expr, hop + OP_SAFE_C_SZ); choose_c_function(sc, expr, func, 2); /* if hop is on, is it the case that opt1 is unused? where besides c_function_is_ok is it referenced? * some like add_ss_1ss use opt1(cdr(...)) which is safe here I think because cadr is a symbol * it's used in the choosers to detect e.g. temp funcs */ return(true); } set_unsafe(expr); set_optimize_op(expr, hop + OP_SAFE_C_SP); choose_c_function(sc, expr, func, 2); return(false); } /* arg2 is a symbol */ if ((bad_pairs == 0) || (is_h_optimized(arg1))) { set_optimize_op(expr, hop + OP_SAFE_C_ZS); choose_c_function(sc, expr, func, 2); return(true); } /* unknowns get here: (* amp (amps 0)) * also list: (make-polywave pitch (list 1 0.93 2 0.07)) * and (* vol (granulate gen)) */ set_unsafe(expr); set_optimize_op(expr, hop + OP_SAFE_C_PS); choose_c_function(sc, expr, func, 2); return(false); } if (symbols == 0) { set_optimized(expr); if (is_pair(arg1)) { if ((bad_pairs == 0) || (is_h_optimized(arg2))) { set_optimize_op(expr, hop + OP_SAFE_C_ZC); choose_c_function(sc, expr, func, 2); return(true); } else { set_unsafe(expr); set_optimize_op(expr, hop + OP_SAFE_C_PC); choose_c_function(sc, expr, func, 2); return(false); } } else { if ((bad_pairs == 0) || (is_h_optimized(arg1))) { set_optimize_op(expr, hop + OP_SAFE_C_CZ); choose_c_function(sc, expr, func, 2); return(true); } else { set_unsafe(expr); set_optimize_op(expr, hop + OP_SAFE_C_CP); choose_c_function(sc, expr, func, 2); return(false); } } } } if ((pairs == 2) && ((func_is_safe) || ((is_possibly_safe(func)) && (unsafe_is_safe(sc, func, arg1, arg2, NULL, e))))) { if ((bad_pairs == 1) && (is_safe_c_s(arg1))) { /* unsafe func here won't work unless we check that later and make the new arg list (for {list} etc) * (and it has to be the last pair else the unknown_g stuff can mess up) */ set_unsafe_optimize_op(expr, hop + OP_SAFE_C_opSq_P); choose_c_function(sc, expr, func, 2); return(false); } else { if (quotes == 0) { set_unsafely_optimized(expr); if (is_all_x_safe(sc, arg1)) { set_optimize_op(expr, hop + ((is_h_optimized(arg2)) ? OP_SAFE_C_AZ : OP_SAFE_C_AP)); annotate_arg(sc, cdr(expr), e); } else set_optimize_op(expr, hop + OP_SAFE_C_PP); choose_c_function(sc, expr, func, 2); return(false); } else { if (quotes == 1) { if (car(arg1) == sc->QUOTE) set_optimize_op(expr, hop + OP_SAFE_C_QP); else set_optimize_op(expr, hop + OP_SAFE_C_PQ); set_unsafely_optimized(expr); choose_c_function(sc, expr, func, 2); return(false); } } } } if (func_is_safe) { if (pairs == (quotes + all_x_count(expr))) { set_safe_optimize_op(expr, hop + OP_SAFE_C_AA); annotate_args(sc, cdr(expr), e); set_arglist_length(expr, small_int(2)); choose_c_function(sc, expr, func, 2); return(true); } } if ((pairs == 1) && (symbols == 1) && (quotes == 0) && (!func_is_safe) && (is_symbol(arg1))) { set_unsafe_optimize_op(expr, hop + ((is_h_optimized(arg2)) ? OP_C_SZ : OP_C_SP)); choose_c_function(sc, expr, func, 2); return(false); } return(is_optimized(expr)); } if (is_closure(func)) { if (closure_arity_to_int(sc, func) != 2) return(false); if ((pairs == 0) && (symbols >= 1)) { set_unsafely_optimized(expr); if (symbols == 2) { set_optimize_op(expr, hop + ((is_safe_closure(func)) ? OP_SAFE_CLOSURE_SS : OP_CLOSURE_SS)); set_opt_sym2(expr, arg2); } else { if (is_symbol(arg1)) { set_optimize_op(expr, hop + ((is_safe_closure(func) ? OP_SAFE_CLOSURE_SC : OP_CLOSURE_SC))); set_opt_con2(expr, arg2); } else { set_optimize_op(expr, hop + ((is_safe_closure(func) ? OP_SAFE_CLOSURE_CS : OP_CLOSURE_CS))); set_opt_sym2(expr, arg2); } } set_opt_lambda(expr, func); return(false); } if ((!arglist_has_rest(sc, closure_args(func))) && (pairs == (quotes + all_x_count(expr)))) { set_unsafely_optimized(expr); if (is_safe_closure(func)) { if (is_symbol(arg1)) set_optimize_op(expr, hop + OP_SAFE_CLOSURE_SA); else set_optimize_op(expr, hop + OP_SAFE_CLOSURE_AA); } else set_optimize_op(expr, hop + OP_CLOSURE_AA); annotate_args(sc, cdr(expr), e); set_opt_lambda(expr, func); set_arglist_length(expr, small_int(2)); return(false); } return(is_optimized(expr)); } if (is_closure_star(func)) { if (((!has_simple_args(closure_body(func))) || (closure_star_arity_to_int(sc, func) < 2) || (arglist_has_keyword(cdr(expr))))) return(false); if ((pairs == 0) && (symbols >= 1) && (is_symbol(arg1))) { set_unsafely_optimized(expr); if (symbols == 2) { set_optimize_op(expr, hop + ((is_safe_closure(func)) ? OP_SAFE_CLOSURE_STAR_SS : OP_CLOSURE_STAR_SX)); set_opt_sym2(expr, arg2); } else { if (is_safe_closure(func)) { set_optimize_op(expr, hop + OP_SAFE_CLOSURE_STAR_SC); set_opt_con2(expr, arg2); if (arg2 == real_zero) opt_generator(sc, func, expr, hop); } else set_optimize_op(expr, hop + OP_CLOSURE_STAR_SX); } set_opt_lambda(expr, func); return(false); } if ((!arglist_has_rest(sc, closure_args(func))) && (pairs == (quotes + all_x_count(expr)))) { set_unsafely_optimized(expr); if (is_safe_closure(func)) { if ((is_symbol(arg1)) && (closure_star_arity_to_int(sc, func) == 2)) set_optimize_op(expr, hop + OP_SAFE_CLOSURE_STAR_SA); else set_optimize_op(expr, hop + OP_SAFE_CLOSURE_STAR_ALL_X); } else set_optimize_op(expr, hop + OP_CLOSURE_STAR_ALL_X); annotate_args(sc, cdr(expr), e); set_opt_lambda(expr, func); set_arglist_length(expr, small_int(2)); return(false); } } return(is_optimized(expr)); } static bool optimize_func_three_args(s7_scheme *sc, s7_pointer expr, s7_pointer func, int hop, int pairs, int symbols, int quotes, int bad_pairs, s7_pointer e) { s7_pointer arg1, arg2, arg3; arg1 = cadr(expr); arg2 = caddr(expr); arg3 = cadddr(expr); if ((pairs == 0) && (is_immutable_symbol(car(expr)))) hop = 1; if ((is_c_function(func) && (c_function_required_args(func) <= 3) && (c_function_all_args(func) >= 3)) || ((is_c_function_star(func)) && (c_function_all_args(func) == 3) && (!is_keyword(arg1)) && (!is_keyword(arg2)))) { if ((is_safe_procedure(func)) || ((is_possibly_safe(func)) && (unsafe_is_safe(sc, func, arg1, arg2, arg3, e)))) { if (pairs == 0) { set_optimized(expr); if (symbols == 0) set_optimize_op(expr, hop + OP_SAFE_C_C); else { if (symbols == 3) { set_optimize_op(expr, hop + OP_SAFE_C_SSS); set_opt_sym1(cdr(expr), arg2); set_opt_sym2(cdr(expr), arg3); } else { if (symbols == 2) { if (!is_symbol(arg1)) { set_optimize_op(expr, hop + OP_SAFE_C_CSS); set_opt_sym1(cdr(expr), arg2); set_opt_sym2(cdr(expr), arg3); } else { if (!is_symbol(arg3)) { set_opt_con2(cdr(expr), arg3); if (is_keyword(arg2)) { set_opt_con1(cdr(expr), arg2); set_optimize_op(expr, hop + OP_SAFE_C_SCC); } else { set_opt_sym1(cdr(expr), arg2); set_optimize_op(expr, hop + OP_SAFE_C_SSC); } } else { set_opt_con1(cdr(expr), arg2); set_opt_sym2(cdr(expr), arg3); set_optimize_op(expr, hop + OP_SAFE_C_SCS); } } } else { if (is_symbol(arg1)) { set_opt_con1(cdr(expr), arg2); set_opt_con2(cdr(expr), arg3); set_optimize_op(expr, hop + OP_SAFE_C_SCC); } else { if (is_symbol(arg2)) { set_opt_sym1(cdr(expr), arg2); set_opt_con2(cdr(expr), arg3); set_optimize_op(expr, hop + OP_SAFE_C_CSC); } else { set_optimize_op(expr, hop + OP_SAFE_C_AAA); /* fallback on all_x_c and s here -- a kludge */ annotate_args(sc, cdr(expr), e); set_arglist_length(expr, small_int(3)); } } } } } choose_c_function(sc, expr, func, 3); return(true); } /* pairs != 0 */ if (pairs == quotes + all_x_count(expr)) { set_optimized(expr); if ((symbols == 2) && (quotes == 1)) { if ((is_symbol(arg1)) && (is_symbol(arg3))) { set_opt_con1(cdr(expr), cadr(arg2)); set_opt_sym2(cdr(expr), arg3); set_optimize_op(expr, hop + OP_SAFE_C_SQS); choose_c_function(sc, expr, func, 3); return(true); } } annotate_args(sc, cdr(expr), e); set_arglist_length(expr, small_int(3)); set_optimize_op(expr, hop + OP_SAFE_C_AAA); if (pairs == 1) { if (symbols == 1) { if (is_pair(arg3)) { if (is_symbol(arg2)) set_optimize_op(expr, hop + OP_SAFE_C_CSA); else set_optimize_op(expr, hop + OP_SAFE_C_SCA); } else { if ((is_pair(arg2)) && (is_symbol(arg3))) set_optimize_op(expr, hop + OP_SAFE_C_CAS); } } else { if ((symbols == 2) && (is_symbol(arg1))) set_optimize_op(expr, hop + ((is_symbol(arg2)) ? OP_SAFE_C_SSA : OP_SAFE_C_SAS)); } } choose_c_function(sc, expr, func, 3); return(true); } if (bad_pairs == 0) { if ((symbols == 2) && (is_symbol(arg1)) && (is_symbol(arg2))) { set_optimize_op(expr, hop + OP_SAFE_C_SSZ); } else { /* use either X or Z in all 8 choices */ if ((!is_pair(arg1)) || (is_all_x_op(optimize_op(arg1)))) { annotate_arg(sc, cdr(expr), e); if ((!is_pair(arg2)) || (is_all_x_op(optimize_op(arg2)))) { set_optimize_op(expr, hop + OP_SAFE_C_AAZ); /* here last can't be A because we checked for that above */ annotate_arg(sc, cddr(expr), e); } else { if ((!is_pair(arg3)) || (is_all_x_op(optimize_op(arg3)))) { set_optimize_op(expr, hop + OP_SAFE_C_AZA); annotate_arg(sc, cdddr(expr), e); } else set_optimize_op(expr, hop + OP_SAFE_C_AZZ); } } else { if ((!is_pair(arg2)) || (is_all_x_op(optimize_op(arg2)))) { annotate_arg(sc, cddr(expr), e); if ((!is_pair(arg3)) || (is_all_x_op(optimize_op(arg3)))) { set_optimize_op(expr, hop + OP_SAFE_C_ZAA); annotate_arg(sc, cdddr(expr), e); } else set_optimize_op(expr, hop + OP_SAFE_C_ZAZ); } else { if ((!is_pair(arg3)) || (is_all_x_op(optimize_op(arg3)))) { set_optimize_op(expr, hop + OP_SAFE_C_ZZA); annotate_arg(sc, cdddr(expr), e); } else set_optimize_op(expr, hop + OP_SAFE_C_ZZZ); } } } set_optimized(expr); choose_c_function(sc, expr, func, 3); set_arglist_length(expr, small_int(3)); return(true); } /* aap is not better than ssp, sap also saves very little */ if ((pairs == 1) && (bad_pairs == 1) && (symbols == 2) && (is_pair(arg3))) { set_unsafe_optimize_op(expr, hop + ((is_h_optimized(arg3)) ? OP_SAFE_C_SSZ : OP_SAFE_C_SSP)); choose_c_function(sc, expr, func, 3); return(false); } } else /* func is not safe */ { if (pairs == quotes + all_x_count(expr)) { set_optimized(expr); if ((symbols == 2) && (pairs == 0) && (is_symbol(arg1)) && (is_symbol(arg3))) set_optimize_op(expr, hop + OP_C_SCS); else { annotate_args(sc, cdr(expr), e); set_arglist_length(expr, small_int(3)); set_optimize_op(expr, hop + OP_C_ALL_X); } choose_c_function(sc, expr, func, 3); if (optimize_op(expr) != HOP_SAFE_C_C) /* did chooser fix it up? */ { set_unsafe(expr); return(false); } return(true); } /* (define (hi) (catch #t (lambda () 1) (lambda args 2))) * first arg list must be (), second a symbol */ if (c_function_call(func) == g_catch) { if (((bad_pairs == 2) && (!is_pair(arg1))) || ((bad_pairs == 3) && (car(arg1) == sc->QUOTE))) { s7_pointer body_lambda, error_lambda; body_lambda = arg2; error_lambda = arg3; if ((is_pair(body_lambda)) && (is_lambda(sc, car(body_lambda))) && (is_pair(error_lambda)) && (is_lambda(sc, car(error_lambda))) && (is_null(cadr(body_lambda))) && (is_not_null(cddr(body_lambda))) && (is_symbol(cadr(error_lambda))) && (!is_immutable_symbol(cadr(error_lambda))) && (is_not_null(cddr(error_lambda)))) { s7_pointer error_result; error_result = caddr(error_lambda); set_unsafely_optimized(expr); if ((arg1 == sc->T) && (is_null(cdddr(error_lambda))) && (!is_symbol(error_result)) && ((!is_pair(error_result)) || (car(error_result) == sc->QUOTE))) { set_optimize_op(expr, hop + OP_C_CATCH_ALL); set_c_function(expr, func); if (is_pair(error_result)) set_opt_con2(expr, cadr(error_result)); else set_opt_con2(expr, error_result); set_opt_pair1(cdr(expr), cddr(body_lambda)); } else { set_optimize_op(expr, hop + OP_C_CATCH); choose_c_function(sc, expr, func, 3); } return(false); } } } } return(is_optimized(expr)); } /* not c func */ if(is_closure(func)) { if (closure_arity_to_int(sc, func) != 3) return(false); if ((symbols == 3) && (!is_safe_closure(func))) { set_unsafely_optimized(expr); set_opt_lambda(expr, func); set_arglist_length(expr, small_int(3)); set_optimize_op(expr, hop + OP_CLOSURE_ALL_S); return(false); } if (pairs == quotes + all_x_count(expr)) { if (is_safe_closure(func)) { if (is_symbol(arg1)) set_optimize_op(expr, hop + OP_SAFE_CLOSURE_SAA); else set_optimize_op(expr, hop + OP_SAFE_CLOSURE_ALL_X); } else set_optimize_op(expr, hop + OP_CLOSURE_ALL_X); set_unsafely_optimized(expr); annotate_args(sc, cdr(expr), e); set_opt_lambda(expr, func); set_arglist_length(expr, small_int(3)); return(false); } } if (is_closure_star(func)) { if ((!has_simple_args(closure_body(func))) || (closure_star_arity_to_int(sc, func) < 3) || (arglist_has_keyword(cdr(expr))) || (arglist_has_rest(sc, closure_args(func)))) /* is this redundant? */ return(false); if (pairs == quotes + all_x_count(expr)) { set_unsafe_optimize_op(expr, hop + ((is_safe_closure(func) ? OP_SAFE_CLOSURE_STAR_ALL_X : OP_CLOSURE_STAR_ALL_X))); annotate_args(sc, cdr(expr), e); set_opt_lambda(expr, func); set_arglist_length(expr, small_int(3)); return(false); } } if (bad_pairs > quotes) return(false); return(is_optimized(expr)); } static bool optimize_func_many_args(s7_scheme *sc, s7_pointer expr, s7_pointer func, int hop, int args, int pairs, int symbols, int quotes, int bad_pairs, s7_pointer e) { bool func_is_closure; if (bad_pairs > quotes) return(false); if ((pairs == 0) && (is_immutable_symbol(car(expr)))) hop = 1; if ((is_c_function(func)) && (c_function_required_args(func) <= (unsigned int)args) && (c_function_all_args(func) >= (unsigned int)args)) { if (is_safe_procedure(func)) { if (pairs == 0) { if (symbols == 0) { set_safe_optimize_op(expr, hop + OP_SAFE_C_C); choose_c_function(sc, expr, func, args); return(true); } if ((symbols == args) && (args < GC_TRIGGER_SIZE)) { set_safe_optimize_op(expr, hop + OP_SAFE_C_ALL_S); set_arglist_length(expr, make_permanent_integer(args)); choose_c_function(sc, expr, func, args); return(true); } } if ((args < GC_TRIGGER_SIZE) && (pairs == (quotes + all_x_count(expr)))) { set_optimized(expr); if (args == 4) set_optimize_op(expr, hop + OP_SAFE_C_AAAA); else set_optimize_op(expr, hop + OP_SAFE_C_ALL_X); annotate_args(sc, cdr(expr), e); set_arglist_length(expr, make_permanent_integer(args)); choose_c_function(sc, expr, func, args); return(true); } } else /* c_func is not safe */ { if ((args < GC_TRIGGER_SIZE) && (pairs == (quotes + all_x_count(expr)))) { set_unsafe_optimize_op(expr, hop + OP_C_ALL_X); annotate_args(sc, cdr(expr), e); set_arglist_length(expr, make_permanent_integer(args)); choose_c_function(sc, expr, func, args); return(false); } } return(is_optimized(expr)); } func_is_closure = is_closure(func); if (func_is_closure) { if (closure_arity_to_int(sc, func) != args) return(false); if ((pairs == 0) && ((symbols == args) || (symbols == 0)) && (args < GC_TRIGGER_SIZE)) { bool safe_case; safe_case = is_safe_closure(func); set_unsafe_optimize_op(expr, hop + ((safe_case) ? OP_SAFE_CLOSURE_ALL_X : OP_CLOSURE_ALL_X)); annotate_args(sc, cdr(expr), e); set_arglist_length(expr, make_permanent_integer(args)); set_opt_lambda(expr, func); if ((!safe_case) && (symbols == args)) set_optimize_op(expr, hop + OP_CLOSURE_ALL_S); return(false); } } if ((is_closure_star(func)) && ((!has_simple_args(closure_body(func))) || (closure_star_arity_to_int(sc, func) < args) || (arglist_has_keyword(cdr(expr))))) return(false); if (args < GC_TRIGGER_SIZE) { if (((func_is_closure) || (is_closure_star(func))) && (!arglist_has_rest(sc, closure_args(func))) && (pairs == (quotes + all_x_count(expr)))) { set_unsafely_optimized(expr); if (func_is_closure) set_optimize_op(expr, hop + ((is_safe_closure(func)) ? OP_SAFE_CLOSURE_ALL_X : OP_CLOSURE_ALL_X)); else set_optimize_op(expr, hop + ((is_safe_closure(func)) ? OP_SAFE_CLOSURE_STAR_ALL_X : OP_CLOSURE_STAR_ALL_X)); annotate_args(sc, cdr(expr), e); set_arglist_length(expr, make_permanent_integer(args)); set_opt_lambda(expr, func); return(false); } } return(is_optimized(expr)); } static bool optimize_syntax(s7_scheme *sc, s7_pointer expr, s7_pointer func, int hop, s7_pointer e) { opcode_t op; s7_pointer p; if (!is_pair(cdr(expr))) /* cddr(expr) might be null if, for example, (begin (let ...)) */ return(false); op = (opcode_t)syntax_opcode(func); sc->w = e; switch (op) { case OP_QUOTE: case OP_MACROEXPAND: return(false); case OP_LET: case OP_LET_STAR: if (is_symbol(cadr(expr))) e = collect_collisions(sc, caddr(expr), cons(sc, add_sym_to_list(sc, cadr(expr)), e)); else e = collect_collisions(sc, cadr(expr), e); break; case OP_LETREC: case OP_LETREC_STAR: e = collect_collisions(sc, cadr(expr), e); break; case OP_DEFINE_MACRO: case OP_DEFINE_MACRO_STAR: case OP_DEFINE_BACRO: case OP_DEFINE_BACRO_STAR: case OP_DEFINE_CONSTANT: case OP_DEFINE_EXPANSION: case OP_DEFINE: case OP_DEFINE_STAR: if (is_pair(cadr(expr))) { s7_pointer name_args; name_args = cadr(expr); if (is_symbol(car(name_args))) e = cons(sc, add_sym_to_list(sc, car(name_args)), e); if (is_symbol(cdr(name_args))) e = cons(sc, add_sym_to_list(sc, cdr(name_args)), e); else e = collect_collisions_star(sc, cdr(name_args), e); /* fprintf(stderr, "%s -> e: %s\n", DISPLAY(expr), DISPLAY(e)); */ } break; case OP_LAMBDA: case OP_LAMBDA_STAR: if (is_symbol(cadr(expr))) /* (lambda args ...) */ e = cons(sc, add_sym_to_list(sc, cadr(expr)), e); else e = collect_collisions_star(sc, cadr(expr), e); break; case OP_SET: if (is_symbol(cadr(expr))) e = cons(sc, add_sym_to_list(sc, cadr(expr)), e); break; case OP_DO: e = collect_collisions(sc, cadr(expr), e); break; case OP_WITH_LET: if (sc->safety != 0) hop = 0; e = sc->NIL; /* we can't trust anything here, so hop ought to be off. For example, * (define (hi) * (let ((e (sublet (curlet) * (cons 'abs (lambda (a) (- a 1)))))) * (with-let e (abs -1)))) * returns 1 if hop is 1, but -2 outside the function body. */ break; default: break; } if (is_pair(e)) sc->w = e; /* fprintf(stderr, "%s -> e: %s\n", DISPLAY(expr), DISPLAY(e)); */ for (p = cdr(expr); is_pair(p); p = cdr(p)) if ((is_pair(car(p))) && (!is_checked(car(p)))) /* ((typeflag & (0xff | T_CHECKED)) == T_PAIR) is not faster */ optimize_expression(sc, car(p), hop, e); if ((hop == 1) && (symbol_id(car(expr)) == 0)) { if ((op == OP_IF) || (op == OP_OR) || (op == OP_AND)) { bool happy = true; for (p = cdr(expr); (happy) && (is_pair(p)); p = cdr(p)) happy = is_all_x_safe(sc, car(p)); if ((happy) && (is_null(p))) /* catch the syntax error later: (or #f . 2) etc */ { int args, symbols = 0, pairs = 0, rest = 0; s7_pointer sym = NULL; bool c_s_is_ok = true; for (args = 0, p = cdr(expr); is_pair(p); p = cdr(p), args++) { if (is_symbol(car(p))) symbols++; else { if (!is_pair(car(p))) rest++; else { pairs++; if ((c_s_is_ok) && ((!is_h_safe_c_s(car(p))) || ((sym) && (sym != cadar(p))))) c_s_is_ok = false; else sym = cadar(p); } } } if ((op == OP_IF) && ((args < 2) || (args > 3))) /* syntax error */ return(false); set_safe_optimize_op(expr, hop + OP_SAFE_C_C); if (pairs == 0) { if (op == OP_OR) set_c_function(expr, or_direct); else { if (op == OP_AND) set_c_function(expr, and_direct); else set_c_function(expr, if_direct); } return(true); } if ((pairs == args) && (c_s_is_ok)) { if (op == OP_OR) set_c_function(expr, or_s_direct); else { if (op == OP_AND) set_c_function(expr, and_s_direct); else set_c_function(expr, if_s_direct); } return(true); } for (p = cdr(expr); is_pair(p); p = cdr(p)) set_c_call(p, all_x_eval(sc, car(p), e, pair_symbol_is_safe)); if (op == OP_OR) { if (s7_list_length(sc, cdr(expr)) == 2) { set_c_function(expr, or_all_x_2); if ((c_call(cdr(expr)) == all_x_c_u) && (c_call(cddr(expr)) == all_x_c_u)) set_c_function(expr, or_all_x_2s); } else set_c_function(expr, or_all_x); } else { if (op == OP_AND) { if (s7_list_length(sc, cdr(expr)) == 2) set_c_function(expr, and_all_x_2); else set_c_function(expr, and_all_x); } else { s7_pointer test, b1, b2; test = cdr(expr); b1 = cdr(test); b2 = cdr(b1); if ((c_call(b1) == all_x_q) && (is_pair(b2))) { if (c_call(b2) == all_x_q) set_c_function(expr, if_all_x_qq); else set_c_function(expr, if_all_x_qa); } else { if ((is_pair(car(test))) && (caar(test) == sc->NOT)) { set_c_call(test, all_x_eval(sc, cadar(test), e, pair_symbol_is_safe)); if (is_null(b2)) set_c_function(expr, if_all_not_x1); else set_c_function(expr, if_all_not_x2); } else { if (is_null(b2)) set_c_function(expr, if_all_x1); else set_c_function(expr, if_all_x2); } } } } return(true); } /* else we could check other if cases here (test is often all_x_safe) */ } } return(false); } static bool optimize_expression(s7_scheme *sc, s7_pointer expr, int hop, s7_pointer e) { s7_pointer car_expr; /* fprintf(stderr, "opt %d %s %s\n", hop, DISPLAY(expr), DISPLAY(e)); */ /* if (is_checked(expr)) return(true); */ set_checked(expr); car_expr = car(expr); if (is_symbol(car_expr)) { s7_pointer func; if (is_syntactic(car_expr)) return(optimize_syntax(sc, expr, slot_value(global_slot(car_expr)), hop, e)); if (car_expr == sc->QUOTE) return(false); func = find_uncomplicated_symbol(sc, car_expr, e); if (is_slot(func)) { func = slot_value(func); if (is_syntactic(func)) return(optimize_syntax(sc, expr, func, hop, e)); /* we miss implicit indexing here because at this time, the data are not set */ if ((is_procedure(func)) || (is_c_function(func)) || (is_safe_procedure(func))) /* built-in applicable objects like vectors */ { int pairs = 0, symbols = 0, args = 0, bad_pairs = 0, quotes = 0, orig_hop; s7_pointer p; orig_hop = hop; if ((is_any_closure(func)) || /* can't depend on opt1 here because it might not be global, or might be redefined locally */ ((!is_global(car_expr)) && ((!is_slot(global_slot(car_expr))) || (slot_value(global_slot(car_expr)) != func)))) { /* (let () (define (f2 a) (+ a 1)) (define (f1 a) (f2 a)) (define (f2 a) (- a)) (f1 12)) * (let () (define (f2 a) (+ a 1)) (define (f1 a) (f2 a)) (define (f2 a) (- a 1)) (f1 12)) * and similar define* cases */ hop = 0; /* this is very tricky! See s7test for some cases. Basically, we need to protect a recursive call * of the current function being optimized from being confused with some previous definition * of the same name. But method lists have global names so the global bit is off even though the * thing is actually a safe global. But no closure can be considered safe in the hop sense -- * even a global function might be redefined at anuy time, and previous uses of it in other functions * need to reflect its new value. * So, closures are always checked, but built-in functions are used as if never redefined until that redefinition. * costs: index 6/1380, t502: 2/12900, bench: 43/4134, snd-test: 22/37200 * Syntax handling is already impure in s7, so the special handling of built-in functions doesn't * offend me much. Consider each a sort of reader macro until someone redefines it -- previous * uses may not be affected because they might have been optimized away -- the result depends on the * current optimizer. * Another case (from K Matheussen): * (define (call-func func arg1 arg2) (define (call) (func arg1 arg2)) (call)) (call-func + 1 2.5) (call-func - 5 2) * when we get here originally "func" is +, hop=1, but just checking for !is_global(car_expr) is * not good enough -- if we load mockery.scm, nothing is global! */ } /* but if we make a recursive call on a func, we've obviously already looked up that function, and * if it has not been shadowed, then we don't need to check it -- so the hop bit should be on * for that one case. */ for (p = cdr(expr); is_pair(p); p = cdr(p), args++) /* check the args (the calling expression) */ { s7_pointer car_p; car_p = car(p); if (is_symbol(car_p)) symbols++; else { if (is_pair(car_p)) { pairs++; if (!is_checked(car_p)) { if (!optimize_expression(sc, car_p, orig_hop, e)) { bad_pairs++; if ((car(car_p) == sc->QUOTE) && (is_pair(cdr(car_p))) && (is_null(cddr(car_p)))) quotes++; } } else { if ((!is_optimized(car_p)) || (is_unsafe(car_p))) { bad_pairs++; if ((car(car_p) == sc->QUOTE) && (is_pair(cdr(car_p))) && (is_null(cddr(car_p)))) quotes++; } } } } } if (is_null(p)) /* if not null, dotted list of args? */ { switch (args) { case 0: return(optimize_thunk(sc, expr, func, hop)); case 1: return(optimize_func_one_arg(sc, expr, func, hop, pairs, symbols, quotes, bad_pairs, e)); case 2: return(optimize_func_two_args(sc, expr, func, hop, pairs, symbols, quotes, bad_pairs, e)); case 3: return(optimize_func_three_args(sc, expr, func, hop, pairs, symbols, quotes, bad_pairs, e)); default: return(optimize_func_many_args(sc, expr, func, hop, args, pairs, symbols, quotes, bad_pairs, e)); } } return(false); } } else { if ((sc->undefined_identifier_warnings) && (func == sc->UNDEFINED) && /* car_expr is not in e or global */ (symbol_tag(car_expr) == 0)) /* and we haven't looked it up earlier */ { s7_pointer p; p = sc->input_port; if ((is_input_port(p)) && (port_file(p) != stdin) && (!port_is_closed(p)) && (port_filename(p))) s7_warn(sc, 1024, "%s might be undefined (%s %u)\n", DISPLAY(car_expr), port_filename(p), port_line_number(p)); else s7_warn(sc, 1024, "; %s might be undefined\n", DISPLAY(car_expr)); symbol_tag(car_expr) = 1; /* one warning is enough */ } /* we need local definitions and func args in e? also check is_symbol case below */ } /* car_expr is a symbol but it's not a known procedure or a "safe" case = vector etc */ { /* else maybe it's something like a let variable binding: (sqrtfreq (sqrt frequency)) */ s7_pointer p; int len = 0, pairs = 0, symbols = 0, quotes = 0; for (p = cdr(expr); is_pair(p); p = cdr(p), len++) { s7_pointer car_p; car_p = car(p); if (is_pair(car_p)) { pairs++; if ((hop != 0) && (car(car_p) == sc->QUOTE)) quotes++; if (!is_checked(car_p)) optimize_expression(sc, car_p, hop, e); } else { if (is_symbol(car_p)) symbols++; } } if ((is_null(p)) && /* (+ 1 . 2) */ (!is_optimized(expr))) { /* len=0 case is almost entirely arglists */ set_opt_con1(expr, sc->GC_NIL); if (pairs == 0) { if (len == 0) { /* hoping to catch object application here, as in readers in Snd */ set_unsafe_optimize_op(expr, OP_UNKNOWN); return(false); } if (len == 1) { if (car_expr != sc->QUOTE) /* !! quote can be redefined locally, unsetting the T_SYNTACTIC flag -- can this happen elsewhere? */ { set_unsafe_optimize_op(expr, OP_UNKNOWN_G); /* hooboy -- we get here in let bindings... * to save access to the caller, we'd need to pass it as an arg to optimize_expression */ } return(false); } if (len == 2) { set_unsafely_optimized(expr); if (symbols == 2) set_optimize_op(expr, OP_UNKNOWN_GG); else { if (symbols == 0) set_optimize_op(expr, OP_UNKNOWN_GG); else { if (is_symbol(cadr(expr))) set_optimize_op(expr, OP_UNKNOWN_GG); else set_optimize_op(expr, OP_UNKNOWN_GG); } } return(false); } if ((len >= 3) && (len == symbols)) { set_unsafe_optimize_op(expr, OP_UNKNOWN_ALL_S); set_arglist_length(expr, make_permanent_integer(len)); return(false); } } else /* pairs != 0 */ { s7_pointer arg1; arg1 = cadr(expr); if (pairs == 1) { if (len == 1) { if (quotes == 1) { set_unsafe_optimize_op(expr, OP_UNKNOWN_A); return(false); } if (is_all_x_safe(sc, arg1)) { set_arglist_length(expr, small_int(1)); set_unsafe_optimize_op(expr, OP_UNKNOWN_A); return(false); } } else { if (len == 2) { if ((is_all_x_safe(sc, arg1)) && (is_all_x_safe(sc, caddr(expr)))) { set_arglist_length(expr, small_int(2)); set_unsafe_optimize_op(expr, OP_UNKNOWN_AA); return(false); } } } } if ((len == 2) && (is_all_x_safe(sc, arg1)) && (is_all_x_safe(sc, caddr(expr)))) { set_arglist_length(expr, small_int(2)); set_unsafe_optimize_op(expr, OP_UNKNOWN_AA); return(false); } if ((pairs == (quotes + all_x_count(expr))) && (len < GC_TRIGGER_SIZE)) { set_unsafe_optimize_op(expr, (len == 1) ? OP_UNKNOWN_A : OP_UNKNOWN_ALL_X); set_arglist_length(expr, make_permanent_integer(len)); return(false); } } } } } else { /* car(expr) is not a symbol, but there might be interesting stuff here */ /* (define (hi a) (case 1 ((1) (if (> a 2) a 2)))) */ s7_pointer p; for (p = expr; is_pair(p); p = cdr(p)) { if ((is_pair(car(p))) && (!is_checked(car(p)))) optimize_expression(sc, car(p), hop, e); } } return(false); } static s7_pointer optimize(s7_scheme *sc, s7_pointer code, int hop, s7_pointer e) { s7_pointer x; if (sc->safety > 1) return(NULL); /* fprintf(stderr, "optimize %s %d %s\n", DISPLAY_80(code), hop, DISPLAY(e)); */ for (x = code; (is_pair(x)) && (!is_checked(x)); x = cdr(x)) { set_checked(x); if ((is_pair(car(x))) && (!is_checked(car(x)))) optimize_expression(sc, car(x), hop, e); } if ((!is_null(x)) && (!is_pair(x))) eval_error(sc, "stray dot in function body: ~S", code); return(NULL); } #if WITH_GCC #define indirect_c_function_is_ok(Sc, X) ({s7_pointer _X_; _X_ = X; (((optimize_op(_X_) & 0x1) != 0) || (c_function_is_ok(Sc, _X_)));}) #define indirect_cq_function_is_ok(Sc, X) ({s7_pointer _X_; _X_ = X; ((!is_optimized(_X_)) || ((optimize_op(_X_) & 0x1) != 0) || (c_function_is_ok(Sc, _X_)));}) #else #define indirect_c_function_is_ok(Sc, X) (((optimize_op(X) & 0x1) != 0) || (c_function_is_ok(Sc, X))) #define indirect_cq_function_is_ok(Sc, X) ((!is_optimized(X)) || ((optimize_op(X) & 0x1) != 0) || (c_function_is_ok(Sc, X))) #endif static bool body_is_safe(s7_scheme *sc, s7_pointer func, s7_pointer body, bool at_end); static bool form_is_safe(s7_scheme *sc, s7_pointer func, s7_pointer x, bool at_end) { /* called only from body_is_safe and itself */ s7_pointer expr; sc->cycle_counter++; if ((!is_proper_list(sc, x)) || (sc->cycle_counter > 5000)) return(false); expr = car(x); if (is_syntactic_symbol(expr)) { switch (symbol_syntax_op(expr)) { case OP_OR: case OP_AND: case OP_BEGIN: case OP_WITH_BAFFLE: if (!body_is_safe(sc, func, cdr(x), at_end)) return(false); break; case OP_MACROEXPAND: return(false); case OP_QUOTE: break; /* in the name binders, we first have to check that "func" actually is the same thing as the caller's func */ case OP_LET: case OP_LET_STAR: if (is_symbol(cadr(x))) return(false); case OP_LETREC: case OP_LETREC_STAR: if (is_pair(cadr(x))) { s7_pointer vars; for (vars = cadr(x); is_pair(vars); vars = cdr(vars)) { s7_pointer let_var; let_var = car(vars); if ((!is_pair(let_var)) || (!is_pair(cdr(let_var)))) return(false); if (car(let_var) == func) return(false); /* it's shadowed */ if ((is_pair(cadr(let_var))) && (!form_is_safe(sc, func, cadr(let_var), false))) return(false); } } if (!body_is_safe(sc, func, cddr(x), at_end)) return(false); break; case OP_IF: if (!is_pair(cdr(x))) return(false); /* (if) ! */ if (!((!is_pair(cadr(x))) || (form_is_safe(sc, func, cadr(x), false)))) return(false); if (!((!is_pair(caddr(x))) || (form_is_safe(sc, func, caddr(x), at_end)))) return(false); if (!((!is_pair(cdddr(x))) || (!is_pair(cadddr(x))) || (form_is_safe(sc, func, cadddr(x), at_end)))) return(false); break; case OP_WHEN: case OP_UNLESS: if (!is_pair(cdr(x))) return(false); /* (when) */ if (!((!is_pair(cadr(x))) || (form_is_safe(sc, func, cadr(x), false)))) return(false); if (!body_is_safe(sc, func, cddr(x), at_end)) return(false); break; case OP_COND: { s7_pointer p; for (p = cdr(x); is_pair(p); p = cdr(p)) { s7_pointer ex; ex = car(p); if (is_pair(ex)) /* ?? */ { if ((is_pair(car(ex))) && (!form_is_safe(sc, func, car(ex), false))) return(false); if ((is_pair(cdr(ex))) && (!body_is_safe(sc, func, cdr(ex), at_end))) return(false); } } if (is_not_null(p)) return(false); } break; case OP_CASE: { s7_pointer p; if ((is_pair(cadr(x))) && (!form_is_safe(sc, func, cadr(x), false))) return(false); for (p = cddr(x); is_pair(p); p = cdr(p)) if ((is_pair(car(p))) && (!body_is_safe(sc, func, cdar(p), at_end))) return(false); } break; case OP_DO: /* (do (...) (...) ...) */ if (!is_pair(cddr(x))) return(false); if (!body_is_safe(sc, func, cdddr(x), false)) return(false); if (is_pair(cadr(x))) { s7_pointer vars; for (vars = cadr(x); is_pair(vars); vars = cdr(vars)) { s7_pointer do_var; do_var = car(vars); if (!is_pair(do_var)) return(false); if ((car(do_var) == func) || (!is_pair(cdr(do_var)))) /* (do ((a . 1) (b . 2)) ...) */ return(false); if ((is_pair(cadr(do_var))) && (!form_is_safe(sc, func, cadr(do_var), false))) return(false); if ((is_pair(cddr(do_var))) && (is_pair(caddr(do_var))) && (!form_is_safe(sc, func, caddr(do_var), false))) return(false); } } if ((is_pair(caddr(x))) && (!body_is_safe(sc, func, caddr(x), at_end))) return(false); break; case OP_SET: /* if we set func, we have to make sure we abandon the tail call scan: * (let () (define (hi a) (let ((v (vector 1 2 3))) (set! hi v) (hi a))) (hi 1)) */ if (!is_pair(cdr(x))) return(false); /* (set!) ! */ if (cadr(x) == func) return(false); /* car(x) is set!, cadr(x) is settee or obj, caddr(x) is val */ if (is_symbol(caddr(x))) return(false); /* ?? because it might be a local function that has captured local state? */ if (((!is_pair(caddr(x))) || (form_is_safe(sc, func, caddr(x), false))) && ((is_symbol(cadr(x))) || ((is_pair(cadr(x))) && (form_is_safe(sc, func, cadr(x), false))))) return(true); return(false); case OP_WITH_LET: if (is_pair(cadr(x))) return(false); if (!body_is_safe(sc, sc->F, cddr(x), at_end)) return(false); break; /* op_define and friends are not safe: (define (a) (define b 3)...) tries to put b in the current env, * but in a safe func, that's a constant. See s7test L 1865 for an example. */ default: /* try to catch weird cases like: * (let () (define (hi1 a) (define (hi1 b) (+ b 1)) (hi1 a)) (hi1 1)) * (let () (define (hi1 a) (define (ho1 b) b) (define (hi1 b) (+ b 1)) (hi1 a)) (hi1 1)) */ return(false); } } else /* car(x) is not syntactic ?? */ { if ((!is_optimized(x)) || (is_unsafe(x))) { if (expr == func) /* try to catch tail call */ { s7_pointer p; for (p = cdr(x); is_pair(p); p = cdr(p)) if ((is_pair(car(p))) && (((!is_optimized(car(p))) && (caar(p) != sc->QUOTE)) || (is_unsafe(car(p))) || (caar(p) == func))) /* func called as arg, so not tail call */ return(false); if ((at_end) && (is_null(p))) /* tail call, so safe */ return(true); return(false); } if (is_symbol(expr)) { if (is_global(expr)) { s7_pointer f; f = find_symbol_checked(sc, expr); if (((is_c_function(f)) && ((is_safe_procedure(f)) || ((is_possibly_safe(f)) && (is_pair(cdr(x))) && (is_pair(cddr(x))) && (unsafe_is_safe(sc, f, cadr(x), caddr(x), (is_pair(cdddr(x))) ? cadddr(x) : NULL, sc->NIL))))) || ((is_closure(f)) && (is_safe_closure(f)))) { s7_pointer p; for (p = cdr(x); is_pair(p); p = cdr(p)) if ((is_pair(car(p))) && ((!is_optimized(car(p))) || (is_unsafe(car(p))))) { if ((caar(p) != func) || (!is_null(cdr(p)))) return(false); } if (!is_null(p)) return(false); } } else { s7_pointer f; f = find_symbol(sc, expr); if (is_slot(f)) { if ((is_syntax(slot_value(f))) || (is_any_macro(slot_value(f)))) return(false); if ((is_closure(slot_value(f))) && (is_safe_closure(slot_value(f)))) { s7_pointer p; /* the calling function is safe, but what about its arguments? */ for (p = cdr(x); is_pair(p); p = cdr(p)) if ((is_pair(car(p))) && (caar(p) == func)) /* this would be a recursive call on func that is not in tail-call position */ return(false); return(true); } } } } return(false); } } return(true); } static bool body_is_safe(s7_scheme *sc, s7_pointer func, s7_pointer body, bool at_end) { /* called in optimize_lambda and above */ s7_pointer p; for (p = body; is_pair(p); p = cdr(p)) if ((is_pair(car(p))) && (!form_is_safe(sc, func, car(p), (at_end) && (is_null(cdr(p)))))) return(false); return(is_null(p)); } /* ---------------------------------------- error checks ---------------------------------------- */ #define goto_START 0 #define goto_BEGIN1 1 #define fall_through 2 #define goto_DO_END_CLAUSES 3 #define goto_SAFE_DO_END_CLAUSES 4 #define goto_OPT_EVAL 5 #define goto_START_WITHOUT_POP_STACK 6 #define goto_EVAL 7 #define goto_APPLY 8 #define goto_EVAL_ARGS 9 #define goto_DO_UNCHECKED 10 static s7_pointer check_lambda_args(s7_scheme *sc, s7_pointer args, int *arity) { s7_pointer x; int i; if ((!is_pair(args)) && (!is_null(args))) { if (s7_is_constant(args)) /* (lambda :a ...) */ eval_error(sc, "lambda parameter '~S is a constant", args); /* not ~A here, (lambda #\null do) for example */ /* we currently accept (lambda i i . i) (lambda quote i) (lambda : : . #()) (lambda : 1 . "") * at this level, but when the lambda form is evaluated, it will trigger an error. */ if (is_symbol(args)) set_local(args); if (arity) (*arity) = -1; return(sc->F); } for (i = 0, x = args; is_pair(x); i++, x = cdr(x)) { s7_pointer car_x; car_x = car(x); if (s7_is_constant(car_x)) /* (lambda (pi) pi), constant here means not a symbol */ { if (is_pair(car_x)) /* (lambda ((:hi . "hi") . "hi") 1) */ eval_error(sc, "lambda parameter '~S is a pair (perhaps you want define* or lambda*?)", car_x); eval_error(sc, "lambda parameter '~S is a constant", car_x); } if (symbol_is_in_arg_list(car_x, cdr(x))) /* (lambda (a a) ...) or (lambda (a . a) ...) */ eval_error(sc, "lambda parameter '~S is used twice in the parameter list", car_x); set_local(car_x); } if (is_not_null(x)) { if (s7_is_constant(x)) /* (lambda (a . 0.0) a) or (lambda (a . :b) a) */ eval_error(sc, "lambda :rest parameter '~S is a constant", x); i = -i - 1; } if (arity) (*arity) = i; return(sc->F); } static s7_pointer check_lambda_star_args(s7_scheme *sc, s7_pointer args, int *arity) { s7_pointer top, v, w; int i; if (!s7_is_list(sc, args)) { if (s7_is_constant(args)) /* (lambda* :a ...) */ eval_error(sc, "lambda* parameter '~S is a constant", args); if (is_symbol(args)) set_local(args); if (arity) (*arity) = -1; return(args); } top = args; v = args; for (i = 0, w = args; is_pair(w); i++, v = w, w = cdr(w)) { s7_pointer car_w; car_w = car(w); if (is_pair(car_w)) { if (s7_is_constant(car(car_w))) /* (lambda* ((:a 1)) ...) */ eval_error(sc, "lambda* parameter '~A is a constant", car(car_w)); if (symbol_is_in_arg_list(caar(w), cdr(w))) /* (lambda* ((a 1) a) ...) */ eval_error(sc, "lambda* parameter '~A is used twice in the argument list", car(car_w)); if (!is_pair(cdr(car_w))) /* (lambda* ((a . 0.0)) a) */ { if (is_null(cdr(car_w))) /* (lambda* ((a)) ...) */ eval_error(sc, "lambda* parameter default value missing? '~A", car_w); eval_error(sc, "lambda* parameter is a dotted pair? '~A", car_w); } else { if ((is_pair(cadr(car_w))) && /* (lambda* ((a (quote . -1))) ...) */ (s7_list_length(sc, cadr(car_w)) < 0)) eval_error(sc, "lambda* parameter default value is improper? ~A", car_w); } if (is_not_null(cddr(car_w))) /* (lambda* ((a 0.0 'hi)) a) */ eval_error(sc, "lambda* parameter has multiple default values? '~A", car_w); set_local(car(car_w)); } else { if (car_w != sc->KEY_REST) { if (s7_is_constant(car_w)) { if (car_w == sc->KEY_ALLOW_OTHER_KEYS) { if (is_not_null(cdr(w))) /* (lambda* (:allow-other-keys x) x) */ eval_error(sc, ":allow-other-keys should be the last parameter: ~A", args); if (w == top) eval_error(sc, ":allow-other-keys can't be the only parameter: ~A", args); set_allow_other_keys(top); cdr(v) = sc->NIL; } else /* (lambda* (pi) ...) */ eval_error(sc, "lambda* parameter '~A is a constant", car_w); } if (symbol_is_in_arg_list(car_w, cdr(w))) /* (lambda* (a a) ...) or (lambda* (a . a) ...) */ eval_error(sc, "lambda* parameter '~A is used twice in the argument list", car_w); if (!is_keyword(car_w)) set_local(car_w); } else { if (!is_pair(cdr(w))) /* (lambda* (:rest) ...) */ eval_error(sc, "lambda* :rest parameter missing? ~A", w); if (!is_symbol(cadr(w))) /* (lambda* (:rest (a 1)) ...) */ { if (!is_pair(cadr(w))) /* (lambda* (:rest 1) ...) */ eval_error(sc, "lambda* :rest parameter is not a symbol? ~A", w); eval_error(sc, "lambda* :rest parameter can't have a default value. ~A", w); } else { if (is_immutable_symbol(cadr(w))) return(s7_error(sc, sc->WRONG_TYPE_ARG, set_elist_2(sc, make_string_wrapper(sc, "can't bind an immutable object: ~S"), w))); } set_local(cadr(w)); } } } if (is_not_null(w)) { if (s7_is_constant(w)) /* (lambda* (a . 0.0) a) or (lambda* (a . :b) a) */ eval_error(sc, "lambda* :rest parameter '~A is a constant", w); if (is_symbol(w)) set_local(w); i = -1; } if (arity) (*arity) = i; return(top); } static void check_lambda(s7_scheme *sc) { /* code is a lambda form minus the "lambda": ((a b) (+ a b)) */ /* this includes unevaluated symbols (direct symbol table refs) in macro arg list */ s7_pointer code, body; code = sc->code; if (!is_pair(code)) /* (lambda) or (lambda . 1) */ eval_error_no_return(sc, sc->SYNTAX_ERROR, "lambda: no args? ~A", sc->cur_code); body = cdr(code); if (!is_pair(body)) /* (lambda #f) */ eval_error_no_return(sc, sc->SYNTAX_ERROR, "lambda: no body? ~A", code); /* in many cases, this is a no-op -- we already checked at define */ check_lambda_args(sc, car(code), NULL); clear_syms_in_list(sc); /* look for (define f (let (...) (lambda ...))) and treat as equivalent to (define (f ...)...) * It's actually safe to ignore main_stack_op, but s7test has some dubious tests that this * check gets around -- need to decide about these cases! */ if ((sc->safety != 0) || (main_stack_op(sc) != OP_DEFINE1)) optimize(sc, body, 0, sc->NIL); else optimize_lambda(sc, true, sc->GC_NIL, car(code), body); /* why was lambda the func? */ if ((is_overlaid(code)) && (has_opt_back(code))) pair_set_syntax_symbol(code, sc->LAMBDA_UNCHECKED); } static void check_lambda_star(s7_scheme *sc) { if ((!is_pair(sc->code)) || (!is_pair(cdr(sc->code)))) /* (lambda*) or (lambda* #f) */ eval_error_no_return(sc, sc->SYNTAX_ERROR, "lambda*: no args or no body? ~A", sc->code); car(sc->code) = check_lambda_star_args(sc, car(sc->code), NULL); clear_syms_in_list(sc); if ((sc->safety != 0) || (main_stack_op(sc) != OP_DEFINE1)) optimize(sc, cdr(sc->code), 0, sc->NIL); else optimize_lambda(sc, false, sc->GC_NIL, car(sc->code), cdr(sc->code)); if ((is_overlaid(sc->code)) && (has_opt_back(sc->code))) pair_set_syntax_symbol(sc->code, sc->LAMBDA_STAR_UNCHECKED); } static s7_pointer check_when(s7_scheme *sc) { if (!is_pair(sc->code)) /* (when) or (when . 1) */ eval_error(sc, "when has no expression or body: ~A", sc->code); if (!is_pair(cdr(sc->code))) /* (when 1) or (when 1 . 1) */ eval_error(sc, "when has no body?: ~A", sc->code); if ((is_overlaid(sc->code)) && (has_opt_back(sc->code))) { pair_set_syntax_symbol(sc->code, sc->WHEN_UNCHECKED); if (is_symbol(car(sc->code))) pair_set_syntax_symbol(sc->code, sc->WHEN_S); } return(sc->code); } static s7_pointer check_unless(s7_scheme *sc) { if (!is_pair(sc->code)) /* (unless) or (unless . 1) */ eval_error(sc, "unless has no expression or body: ~A", sc->code); if (!is_pair(cdr(sc->code))) /* (unless 1) or (unless 1 . 1) */ eval_error(sc, "unless has no body?: ~A", sc->code); if ((is_overlaid(sc->code)) && (has_opt_back(sc->code))) { pair_set_syntax_symbol(sc->code, sc->UNLESS_UNCHECKED); if (is_symbol(car(sc->code))) pair_set_syntax_symbol(sc->code, sc->UNLESS_S); } return(sc->code); } /* (apply unless (list values :key #f)) */ static s7_pointer check_case(s7_scheme *sc) { bool keys_simple = true, have_else = false, has_feed_to = false, keys_single = true, bodies_simple = true, bodies_simplest = true; s7_pointer x; if (!is_pair(sc->code)) /* (case) or (case . 1) */ eval_error(sc, "case has no selector: ~A", sc->code); if (!is_pair(cdr(sc->code))) /* (case 1) or (case 1 . 1) */ eval_error(sc, "case has no clauses?: ~A", sc->code); if (!is_pair(cadr(sc->code))) /* (case 1 1) */ eval_error(sc, "case clause is not a list? ~A", sc->code); for (x = cdr(sc->code); is_not_null(x); x = cdr(x)) { s7_pointer y; if ((!is_pair(x)) || /* (case 1 ((2) 1) . 1) */ (!is_pair(car(x)))) eval_error(sc, "case clause ~A messed up", x); if (!is_pair(cdar(x))) /* (case 1 ((1))) */ eval_error(sc, "case clause result missing: ~A", car(x)); if ((bodies_simple) && (!is_null(cddar(x)))) { bodies_simple = false; bodies_simplest = false; } if (bodies_simplest) { if ((is_pair(cadar(x))) && (caadar(x) != sc->QUOTE)) { if (is_pair(caar(x))) bodies_simplest = false; else { if ((caar(x) != sc->ELSE) && (caar(x) != sc->else_symbol) && ((!is_symbol(caar(x))) || (s7_symbol_value(sc, caar(x)) != sc->ELSE))) bodies_simplest = false; } } } y = caar(x); if (!is_pair(y)) { if ((y != sc->ELSE) && (y != sc->else_symbol) && /* (case 1 (2 1)) */ ((!is_symbol(y)) || (s7_symbol_value(sc, y) != sc->ELSE))) /* "proper list" below because: (case 1 (() 2) ... */ eval_error(sc, "case clause key list ~A is not a proper list or 'else'", y); if (is_not_null(cdr(x))) /* (case 1 (else 1) ((2) 1)) */ eval_error(sc, "case 'else' clause, ~A, is not the last clause", x); have_else = true; } else { /* what about (case 1 ((1) #t) ((1) #f)) [this is ok by guile] * (case 1 ((1) #t) ()) * (case 1 ((2 2 2) 1)): guile says # * but we do support: (let ((otherwise else)) (case 0 ((1) 2) (otherwise 3))) -> 3! * is that consistent? * (let ((else #f)) (case 0 ((1) 2) (else 3))) -> 3 * (case 0 ((1) 2) (else (let ((else 3)) else))) -> 3 * the selector (sc->value) is evaluated, but the search key is not * (case '2 ((2) 3) (else 1)) -> 3 * (case '2 (('2) 3) (else 1)) -> 1 * another approach: make else a value, not a symbol, like #, evaluates to itself * or set it to be immutable, but I guess I'll say "use #_else" for now. */ if (!is_simple(car(y))) keys_simple = false; if (!is_null(cdr(y))) keys_single = false; for (y = cdr(y); is_not_null(y); y = cdr(y)) { if (!is_pair(y)) /* (case () ((1 . 2) . hi) . hi) */ eval_error(sc, "case key list is improper? ~A", x); if (!is_simple(car(y))) keys_simple = false; } } y = car(x); if ((cadr(y) == sc->FEED_TO) && (s7_symbol_value(sc, sc->FEED_TO) == sc->UNDEFINED)) { has_feed_to = true; if (!is_pair(cddr(y))) /* (case 1 (else =>)) */ eval_error(sc, "case: '=>' target missing? ~A", y); if (is_pair(cdddr(y))) /* (case 1 (else => + - *)) */ eval_error(sc, "case: '=>' has too many targets: ~A", y); } } if ((is_overlaid(sc->code)) && (has_opt_back(sc->code))) { for (x = cdr(sc->code); is_not_null(x); x = cdr(x)) { set_opt_key(x, caar(x)); if (is_pair(opt_key(x))) set_opt_clause(x, cadar(x)); } pair_set_syntax_symbol(sc->code, sc->CASE_UNCHECKED); if ((!has_feed_to) && (keys_simple)) { if (have_else) /* don't combine ifs ! */ { if (is_symbol(car(sc->code))) pair_set_syntax_symbol(sc->code, sc->CASE_SIMPLE); } else { if (keys_single) { if ((bodies_simple) && (is_symbol(car(sc->code)))) pair_set_syntax_symbol(sc->code, sc->CASE_SIMPLEST); else { if ((is_optimized(car(sc->code))) && (optimize_op(car(sc->code)) == HOP_SAFE_C_SS)) pair_set_syntax_symbol(sc->code, sc->CASE_SIMPLEST_SS); } for (x = cdr(sc->code); is_not_null(x); x = cdr(x)) set_opt_key(x, caaar(x)); } else { if (bodies_simple) { if (is_symbol(car(sc->code))) pair_set_syntax_symbol(sc->code, sc->CASE_SIMPLER_1); else { if ((is_optimized(car(sc->code))) && (optimize_op(car(sc->code)) == HOP_SAFE_C_SS)) pair_set_syntax_symbol(sc->code, sc->CASE_SIMPLER_SS); } } else { if (is_symbol(car(sc->code))) pair_set_syntax_symbol(sc->code, sc->CASE_SIMPLER); } } } } } return(sc->code); } static s7_pointer check_let_one_var(s7_scheme *sc, s7_pointer start) { s7_pointer binding; pair_set_syntax_symbol(sc->code, sc->LET_ONE); binding = car(start); if (is_pair(cadr(binding))) { if (is_h_optimized(cadr(binding))) { if (is_null(cddr(sc->code))) /* one statement body */ { set_opt_sym2(cdr(sc->code), car(binding)); set_opt_pair2(sc->code, cadr(binding)); pair_set_syntax_symbol(sc->code, sc->LET_Z); if ((is_h_safe_c_s(cadr(binding))) && (is_pair(cadr(sc->code)))) /* one body expr is a pair */ { pair_set_syntax_symbol(sc->code, sc->LET_opSq_P); set_opt_sym2(sc->code, cadr(cadr(binding))); if ((!is_optimized(cadr(sc->code))) && (is_syntactic_symbol(caadr(sc->code)))) { /* the is_optimized check here and in other parallel cases protects against cases like: * (define (hi) (let ((e #f)) (let ((val (not e))) (if (boolean? val) val e)))) (hi) * where the "(if...)" part is optimized as safe_c_s before we get here. If we simply * pair_set_syntax_op(cadr(sc->code)) as below, the optimization bit is on, but the * apparent optimize_op (op) is now safe_c_qq! So eval ejects it and it is handled by the * explicit ("trailers") code. */ pair_set_syntax_op(cadr(sc->code), symbol_syntax_op(caadr(sc->code))); } return(sc->code); } } if (is_h_safe_c_s(cadr(binding))) { pair_set_syntax_symbol(sc->code, sc->LET_opSq); set_opt_sym2(sc->code, cadr(cadr(binding))); return(sc->code); } /* opt1 here is opt_back */ set_opt_pair2(sc->code, cadr(binding)); if (optimize_op(cadr(binding)) == HOP_SAFE_C_SS) { pair_set_syntax_symbol(sc->code, sc->LET_opSSq); set_opt_sym3(sc->code, caddr(cadr(binding))); } else { if (optimize_op(cadr(binding)) == HOP_SAFE_C_C) { set_opt_sym3(sc->code, car(binding)); pair_set_syntax_symbol(sc->code, sc->LET_opCq); } /* let_all_x here is slightly slower than fallback let_z */ } } } else { s7_pointer p; p = cadaar(sc->code); /* sc->code is of the form '(((x y))...) */ set_opt_sym3(sc->code, caaar(sc->code)); if (is_symbol(p)) { set_opt_sym2(sc->code, p); pair_set_syntax_symbol(sc->code, sc->LET_S); } else { set_opt_con2(sc->code, p); pair_set_syntax_symbol(sc->code, sc->LET_C); } } return(sc->code); } static s7_pointer check_let(s7_scheme *sc) { s7_pointer x, start; bool named_let; int vars; if (!is_pair(sc->code)) /* (let . 1) */ { if (is_null(sc->code)) /* (let) */ eval_error(sc, "let has no variables or body: ~A", sc->code); eval_error(sc, "let form is an improper list? ~A", sc->code); } if (!is_pair(cdr(sc->code))) /* (let () ) */ eval_error(sc, "let has no body: ~A", sc->code); if ((!s7_is_list(sc, car(sc->code))) && /* (let 1 ...) */ (!is_symbol(car(sc->code)))) eval_error(sc, "let variable list is messed up or missing: ~A", sc->code); /* we accept these (other schemes complain, but I can't see why -- a no-op is the user's business!): * (let () (define (hi) (+ 1 2))) * (let () (begin (define x 3))) * (let () 3 (begin (define x 3))) * (let () (define x 3)) * (let () (if #t (define (x) 3))) * * similar cases: * (case 0 ((0) (define (x) 3) (x))) * (cond (0 (define (x) 3) (x))) * (and (define (x) x) 1) * (begin (define (x y) y) (x (define (x y) y))) * (if (define (x) 1) 2 3) * (do () ((define (x) 1) (define (y) 2))) * * but we can get some humorous results: * (let ((x (lambda () 3))) (if (define (x) 4) (x) 0)) -> 4 */ named_let = (is_symbol(car(sc->code))); if (named_let) { if (!s7_is_list(sc, cadr(sc->code))) /* (let hi #t) */ eval_error(sc, "let variable list is messed up: ~A", sc->code); if (is_null(cddr(sc->code))) /* (let hi () ) */ eval_error(sc, "named let has no body: ~A", sc->code); if (is_immutable_symbol(car(sc->code))) return(s7_error(sc, sc->WRONG_TYPE_ARG, set_elist_2(sc, make_string_wrapper(sc, "can't bind an immutable object: ~S"), sc->code))); set_local(car(sc->code)); start = cadr(sc->code); } else start = car(sc->code); clear_syms_in_list(sc); for (vars = 0, x = start; is_pair(x); vars++, x = cdr(x)) { s7_pointer y, carx; carx = car(x); if ((!is_pair(carx)) || (is_null(cdr(carx)))) /* (let ((x)) ...) or (let ((x 1) . (y 2)) ...) */ eval_error(sc, "let variable declaration, but no value?: ~A", x); if (!(is_pair(cdr(carx)))) /* (let ((x . 1))...) */ eval_error(sc, "let variable declaration is not a proper list?: ~A", x); if (is_not_null(cddr(carx))) /* (let ((x 1 2 3)) ...) */ eval_error(sc, "let variable declaration has more than one value?: ~A", x); /* currently if the extra value involves a read error, we get a kind of panicky-looking message: * (let ((x . 2 . 3)) x) * ;let variable declaration has more than one value?: (x error error "stray dot?: ... ((x . 2 . 3)) x) ..") */ y = car(carx); if (!(is_symbol(y))) eval_error(sc, "bad variable ~S in let", carx); if (is_immutable_symbol(y)) return(s7_error(sc, sc->WRONG_TYPE_ARG, set_elist_2(sc, make_string_wrapper(sc, "can't bind an immutable object: ~S"), x))); /* check for name collisions -- not sure this is required by Scheme */ if (symbol_tag(y) == sc->syms_tag) eval_error(sc, "duplicate identifier in let: ~A", y); add_sym_to_list(sc, y); set_local(y); } /* we accept (let ((:hi 1)) :hi) * (let ('1) quote) [guile accepts this] */ if (is_not_null(x)) /* (let* ((a 1) . b) a) */ eval_error(sc, "let var list improper?: ~A", sc->code); if ((is_overlaid(sc->code)) && (has_opt_back(sc->code))) { if (named_let) { s7_pointer ex; if (is_null(start)) pair_set_syntax_symbol(sc->code, sc->NAMED_LET_NO_VARS); else pair_set_syntax_symbol(sc->code, sc->NAMED_LET); /* this is (let name ...) so the initial values need to be removed from the closure arg list */ sc->args = sc->NIL; /* sc->args is set to nil in named_let below */ for (ex = start; is_pair(ex); ex = cdr(ex)) sc->args = cons(sc, caar(ex), sc->args); optimize_lambda(sc, true, car(sc->code), sc->args = safe_reverse_in_place(sc, sc->args), cddr(sc->code)); /* apparently these guys are almost never safe */ return(sc->code); } if (is_null(start)) pair_set_syntax_symbol(sc->code, sc->LET_NO_VARS); else { pair_set_syntax_symbol(sc->code, sc->LET_UNCHECKED); if (is_null(cdr(start))) /* one binding */ check_let_one_var(sc, start); else { if (vars < GC_TRIGGER_SIZE) { s7_pointer p, op; op = sc->NIL; for (p = start; is_pair(p); p = cdr(p)) { s7_pointer x; x = car(p); if (is_pair(cadr(x))) { if (car(cadr(x)) == sc->QUOTE) op = sc->LET_ALL_X; else { if (is_h_safe_c_s(cadr(x))) { if ((op == sc->NIL) || (op == sc->LET_ALL_opSq)) op = sc->LET_ALL_opSq; else op = sc->LET_ALL_X; } else { if (is_all_x_safe(sc, cadr(x))) op = sc->LET_ALL_X; else { op = sc->LET_UNCHECKED; break; } } } } else { if (is_symbol(cadr(x))) { if ((op == sc->NIL) || (op == sc->LET_ALL_S)) op = sc->LET_ALL_S; else op = sc->LET_ALL_X; } else { if ((op == sc->NIL) || (op == sc->LET_ALL_C)) op = sc->LET_ALL_C; else op = sc->LET_ALL_X; } } } pair_set_syntax_symbol(sc->code, op); } else pair_set_syntax_symbol(sc->code, sc->LET_UNCHECKED); } } if (pair_syntax_symbol(sc->code) == sc->LET_ALL_X) { s7_pointer p; for (p = start; is_pair(p); p = cdr(p)) set_c_call(cdar(p), all_x_eval(sc, cadar(p), sc->envir, let_symbol_is_safe)); } } return(sc->code); } static s7_pointer check_let_star(s7_scheme *sc) { s7_pointer y; bool named_let; if (!is_pair(sc->code)) /* (let* . 1) */ eval_error(sc, "let* variable list is messed up: ~A", sc->code); if (!is_pair(cdr(sc->code))) /* (let*) */ eval_error(sc, "let* variable list is messed up: ~A", sc->code); named_let = (is_symbol(car(sc->code))); if (named_let) { if (!s7_is_list(sc, cadr(sc->code))) /* (let* hi #t) */ eval_error(sc, "let* variable list is messed up: ~A", sc->code); if (is_null(cddr(sc->code))) /* (let* hi () ) */ eval_error(sc, "named let* has no body: ~A", sc->code); if (is_immutable_symbol(car(sc->code))) return(s7_error(sc, sc->WRONG_TYPE_ARG, set_elist_2(sc, make_string_wrapper(sc, "can't bind an immutable object: ~S"), sc->code))); set_local(car(sc->code)); if ((!is_null(cadr(sc->code))) && ((!is_pair(cadr(sc->code))) || /* (let* hi x ... ) */ (!is_pair(caadr(sc->code))) || /* (let* hi (x) ...) */ (!is_pair(cdaadr(sc->code))))) /* (let* hi ((x . 1)) ...) */ eval_error(sc, "named let* variable declaration value is missing: ~A", sc->code); } else { if ((!is_null(car(sc->code))) && ((!is_pair(car(sc->code))) || /* (let* x ... ) */ (!is_pair(caar(sc->code))) || /* (let* (x) ...) */ (!is_pair(cdaar(sc->code))))) /* (let* ((x . 1)) ...) */ eval_error(sc, "let* variable declaration value is missing: ~A", sc->code); } for (y = ((named_let) ? cadr(sc->code) : car(sc->code)); is_pair(y); y = cdr(y)) { s7_pointer x, z; x = car(y); if (!(is_symbol(car(x)))) /* (let* ((3 1)) 1) */ eval_error(sc, "bad variable ~S in let*", x); z = car(x); if (is_immutable_symbol(z)) return(s7_error(sc, sc->WRONG_TYPE_ARG, set_elist_2(sc, make_string_wrapper(sc, "can't bind an immutable object: ~S"), x))); if (!is_pair(x)) /* (let* ((x)) ...) */ eval_error(sc, "let* variable declaration, but no value?: ~A", x); if (!(is_pair(cdr(x)))) /* (let* ((x . 1))...) */ eval_error(sc, "let* variable declaration is not a proper list?: ~A", x); if (is_not_null(cddr(x))) /* (let* ((x 1 2 3)) ...) */ eval_error(sc, "let* variable declaration has more than one value?: ~A", x); x = cdr(y); if (is_pair(x)) { if (!is_pair(car(x))) /* (let* ((x -1) 2) 3) */ eval_error(sc, "let* variable/binding is ~S?", car(x)); if (!is_pair(cdar(x))) /* (let* ((a 1) (b . 2)) ...) */ eval_error(sc, "let* variable list is messed up? ~A", x); } else { if (is_not_null(x)) /* (let* ((a 1) . b) a) */ eval_error(sc, "let* var list improper?: ~A", x); } /* currently (let* ((a 1) (a (+ a 1))) a) is 2, not an error! */ set_local(z); } if ((is_overlaid(sc->code)) && (has_opt_back(sc->code))) { if (named_let) { if (is_null(cadr(sc->code))) pair_set_syntax_symbol(sc->code, sc->NAMED_LET_NO_VARS); else { pair_set_syntax_symbol(sc->code, sc->NAMED_LET_STAR); set_opt_con2(sc->code, cadr(car(cadr(sc->code)))); } return(sc->code); } pair_set_syntax_symbol(sc->code, sc->LET_STAR_UNCHECKED); if (is_null(car(sc->code))) pair_set_syntax_symbol(sc->code, sc->LET_NO_VARS); /* (let* () ...) */ else { if (is_null(cdar(sc->code))) check_let_one_var(sc, car(sc->code)); /* (let* ((var...))...) -> (let ((var...))...) */ else /* more than one entry */ { s7_pointer p, op; op = sc->LET_STAR_ALL_X; set_opt_con2(sc->code, cadaar(sc->code)); for (p = car(sc->code); is_pair(p); p = cdr(p)) { s7_pointer x; x = car(p); if (is_pair(cadr(x))) { if ((!is_all_x_safe(sc, cadr(x))) && (car(cadr(x)) != sc->QUOTE)) { op = sc->LET_STAR2; break; } } } pair_set_syntax_symbol(sc->code, op); } } if ((pair_syntax_symbol(sc->code) == sc->LET_ALL_X) || (pair_syntax_symbol(sc->code) == sc->LET_STAR_ALL_X)) { s7_pointer p; for (p = car(sc->code); is_pair(p); p = cdr(p)) set_c_call(cdar(p), all_x_eval(sc, cadar(p), sc->envir, let_symbol_is_safe)); } } return(sc->code); } static s7_pointer check_letrec(s7_scheme *sc, bool letrec) { s7_pointer x, caller; caller = (letrec) ? sc->LETREC : sc->LETREC_STAR; if ((!is_pair(sc->code)) || /* (letrec . 1) */ (!is_pair(cdr(sc->code))) || /* (letrec) */ (!s7_is_list(sc, car(sc->code)))) /* (letrec 1 ...) */ eval_error_with_caller(sc, "~A: variable list is messed up: ~A", caller, sc->code); clear_syms_in_list(sc); for (x = car(sc->code); is_not_null(x); x = cdr(x)) { s7_pointer y, carx; if (!is_pair(x)) /* (letrec ((a 1) . 2) ...) */ eval_error_with_caller(sc, "~A: improper list of variables? ~A", caller, sc->code); carx = car(x); if ((!is_pair(carx)) || /* (letrec (1 2) #t) */ (!(is_symbol(car(carx))))) eval_error_with_caller(sc, "~A: bad variable ~S", caller, carx); y = car(carx); if (is_immutable_symbol(y)) return(s7_error(sc, sc->WRONG_TYPE_ARG, set_elist_2(sc, make_string_wrapper(sc, "can't bind an immutable object: ~S"), x))); if (!is_pair(cdr(carx))) /* (letrec ((x . 1))...) */ { if (is_null(cdr(carx))) /* (letrec ((x)) x) -- perhaps this is legal? */ eval_error_with_caller(sc, "~A: variable declaration has no value?: ~A", caller, carx); eval_error_with_caller(sc, "~A: variable declaration is not a proper list?: ~A", caller, carx); } if (is_not_null(cddr(carx))) /* (letrec ((x 1 2 3)) ...) */ eval_error_with_caller(sc, "~A: variable declaration has more than one value?: ~A", caller, carx); /* check for name collisions -- this is needed in letrec* else which of the two legit values * does our "rec" refer to, so to speak. */ if (symbol_tag(y) == sc->syms_tag) eval_error_with_caller(sc, "~A: duplicate identifier: ~A", caller, y); add_sym_to_list(sc, y); set_local(y); } if ((is_overlaid(sc->code)) && (has_opt_back(sc->code))) pair_set_syntax_symbol(sc->code, (letrec) ? sc->LETREC_UNCHECKED : sc->LETREC_STAR_UNCHECKED); return(sc->code); } static s7_pointer check_quote(s7_scheme *sc) { if (!is_pair(sc->code)) /* (quote . -1) */ { if (is_null(sc->code)) eval_error(sc, "quote: not enough arguments: ~A", sc->code); eval_error(sc, "quote: stray dot?: ~A", sc->code); } if (is_not_null(cdr(sc->code))) /* (quote . (1 2)) or (quote 1 1) */ eval_error(sc, "quote: too many arguments ~A", sc->code); #if 0 if ((is_overlaid(sc->code)) && (has_opt_back(sc->code))) { pair_set_syntax_symbol(sc->code, sc->QUOTE_UNCHECKED); } #endif return(sc->code); } static s7_pointer check_and(s7_scheme *sc) { s7_pointer p; bool all_pairs; if (is_null(sc->code)) return(sc->code); all_pairs = is_pair(sc->code); for (p = sc->code; is_pair(p); p = cdr(p)) { if (!is_pair(car(p))) all_pairs = false; } if (is_not_null(p)) /* (and . 1) (and #t . 1) */ eval_error(sc, "and: stray dot?: ~A", sc->code); if ((is_overlaid(sc->code)) && (has_opt_back(sc->code))) { if (all_pairs) { for (p = sc->code; is_pair(p); p = cdr(p)) set_c_call(p, all_x_eval(sc, car(p), sc->envir, let_symbol_is_safe)); /* c_callee can be nil! */ if ((c_callee(sc->code)) && (is_pair(cdr(sc->code))) && (is_null(cddr(sc->code)))) pair_set_syntax_symbol(sc->code, sc->AND_P2); else pair_set_syntax_symbol(sc->code, sc->AND_P); } else pair_set_syntax_symbol(sc->code, sc->AND_UNCHECKED); } return(sc->code); } static s7_pointer check_or(s7_scheme *sc) { s7_pointer p; bool all_pairs; if (is_null(sc->code)) return(sc->code); all_pairs = is_pair(sc->code); for (p = sc->code; is_pair(p); p = cdr(p)) { if (!is_pair(car(p))) all_pairs = false; } if (is_not_null(p)) eval_error(sc, "or: stray dot?: ~A", sc->code); if ((is_overlaid(sc->code)) && (has_opt_back(sc->code))) { if (all_pairs) { s7_pointer ep; for (ep = sc->code; is_pair(ep); ep = cdr(ep)) set_c_call(ep, all_x_eval(sc, car(ep), sc->envir, let_symbol_is_safe)); if ((c_callee(sc->code)) && (is_pair(cdr(sc->code))) && (is_null(cddr(sc->code)))) pair_set_syntax_symbol(sc->code, sc->OR_P2); else pair_set_syntax_symbol(sc->code, sc->OR_P); } else pair_set_syntax_symbol(sc->code, sc->OR_UNCHECKED); } return(sc->code); } static s7_pointer check_if(s7_scheme *sc) { s7_pointer cdr_code; if (!is_pair(sc->code)) /* (if) or (if . 1) */ eval_error(sc, "(if): if needs at least 2 expressions: ~A", sc->code); cdr_code = cdr(sc->code); if (!is_pair(cdr_code)) /* (if 1) */ eval_error(sc, "(if ~A): if needs another clause", car(sc->code)); if (is_pair(cdr(cdr_code))) { if (is_not_null(cddr(cdr_code))) /* (if 1 2 3 4) */ eval_error(sc, "too many clauses for if: ~A", sc->code); } else { if (is_not_null(cdr(cdr_code))) /* (if 1 2 . 3) */ eval_error(sc, "if: ~A has improper list?", sc->code); } if ((is_overlaid(sc->code)) && (has_opt_back(sc->code))) { s7_pointer test; bool one_branch; pair_set_syntax_symbol(sc->code, sc->IF_UNCHECKED); one_branch = (is_null(cdr(cdr_code))); test = car(sc->code); if (is_pair(test)) { if (is_h_optimized(test)) { if (optimize_op(test) == HOP_SAFE_C_C) { if (c_callee(test) == g_and_all_x_2) { pair_set_syntax_symbol(sc->code, (one_branch) ? sc->IF_AND2_P : sc->IF_AND2_P_P); set_opt_and_2_test(sc->code, cddr(test)); } else pair_set_syntax_symbol(sc->code, (one_branch) ? sc->IF_CC_P : sc->IF_CC_P_P); set_opt_pair2(sc->code, cdr(test)); } else { if (is_h_safe_c_s(test)) { /* these miss methods? */ if (car(test) == sc->IS_PAIR) pair_set_syntax_symbol(sc->code, (one_branch) ? sc->IF_IS_PAIR_P : sc->IF_IS_PAIR_P_P); else { if (car(test) == sc->IS_SYMBOL) pair_set_syntax_symbol(sc->code, (one_branch) ? sc->IF_IS_SYMBOL_P : sc->IF_IS_SYMBOL_P_P); else { if (car(test) == sc->NOT) pair_set_syntax_symbol(sc->code, (one_branch) ? sc->IF_NOT_S_P : sc->IF_NOT_S_P_P); else pair_set_syntax_symbol(sc->code, (one_branch) ? sc->IF_CS_P : sc->IF_CS_P_P); } } set_opt_sym2(sc->code, cadr(test)); } else { if (optimize_op(test) == HOP_SAFE_C_SQ) { pair_set_syntax_symbol(sc->code, (one_branch) ? sc->IF_CSQ_P : sc->IF_CSQ_P_P); set_opt_con2(sc->code, cadr(caddr(test))); set_opt_sym3(sc->code, cadr(test)); } else { if (optimize_op(test) == HOP_SAFE_C_SS) { pair_set_syntax_symbol(sc->code, (one_branch) ? sc->IF_CSS_P : sc->IF_CSS_P_P); set_opt_sym2(sc->code, caddr(test)); set_opt_sym3(sc->code, cadr(test)); } else { if (optimize_op(test) == HOP_SAFE_C_SC) { pair_set_syntax_symbol(sc->code, (one_branch) ? sc->IF_CSC_P : sc->IF_CSC_P_P); set_opt_con2(sc->code, caddr(test)); set_opt_sym3(sc->code, cadr(test)); } else { if (optimize_op(test) == HOP_SAFE_C_S_opCq) { pair_set_syntax_symbol(sc->code, (one_branch) ? sc->IF_S_opCq_P : sc->IF_S_opCq_P_P); set_opt_pair2(sc->code, caddr(test)); set_opt_sym3(sc->code, cadr(test)); } else { if (optimize_op(test) == HOP_SAFE_C_opSSq) { pair_set_syntax_symbol(sc->code, (one_branch) ? sc->IF_opSSq_P : sc->IF_opSSq_P_P); set_opt_pair2(sc->code, cadar(sc->code)); set_opt_sym3(sc->code, caddr(opt_pair2(sc->code))); } else { if (is_all_x_safe(sc, test)) { pair_set_syntax_symbol(sc->code, (one_branch) ? sc->IF_A_P : sc->IF_A_P_P); set_c_call(sc->code, all_x_eval(sc, test, sc->envir, let_symbol_is_safe)); } else { pair_set_syntax_symbol(sc->code, (one_branch) ? sc->IF_Z_P : sc->IF_Z_P_P); set_opt_con2(sc->code, cadr(sc->code)); } } } } } } } } } else { pair_set_syntax_symbol(sc->code, (one_branch) ? sc->IF_P_P : sc->IF_P_P_P); if (is_syntactic_symbol(car(test))) { pair_set_syntax_op(test, symbol_syntax_op(car(test))); if ((symbol_syntax_op(car(test)) == OP_AND) || (symbol_syntax_op(car(test)) == OP_OR)) { opcode_t new_op; s7_pointer old_code; old_code = sc->code; sc->code = cdr(test); if (symbol_syntax_op(car(test)) == OP_AND) check_and(sc); else check_or(sc); new_op = symbol_syntax_op(car(test)); sc->code = old_code; if ((new_op == OP_AND_P) || (new_op == OP_AND_P2)) pair_set_syntax_symbol(sc->code, (one_branch) ? sc->IF_ANDP_P : sc->IF_ANDP_P_P); else { if ((new_op == OP_OR_P) || (new_op == OP_OR_P2)) pair_set_syntax_symbol(sc->code, (one_branch) ? sc->IF_ORP_P : sc->IF_ORP_P_P); } } } } } else /* test is symbol or constant, but constant here is nutty */ { if (is_symbol(test)) pair_set_syntax_symbol(sc->code, (one_branch) ? sc->IF_S_P : sc->IF_S_P_P); } } return(sc->code); } static s7_pointer optimize_lambda(s7_scheme *sc, bool unstarred_lambda, s7_pointer func, s7_pointer args, s7_pointer body) { int len; /* fprintf(stderr, "opt %s %s\n", DISPLAY(args), DISPLAY(body)); */ len = s7_list_length(sc, body); if (len < 0) /* (define (hi) 1 . 2) */ eval_error_with_caller(sc, "~A: function body messed up, ~A", (unstarred_lambda) ? sc->LAMBDA : sc->LAMBDA_STAR, sc->code); if (len > 0) /* i.e. not circular */ { s7_pointer lst; clear_syms_in_list(sc); if (is_symbol(func)) lst = list_1(sc, add_sym_to_list(sc, func)); else lst = sc->NIL; optimize(sc, body, 1, collect_collisions_star(sc, args, lst)); /* if the body is safe, we can optimize the calling sequence */ if ((is_proper_list(sc, args)) && (!arglist_has_rest(sc, args))) { if (!unstarred_lambda) { s7_pointer p; bool happy = true; /* check default vals -- if none is an expression or symbol, set simple args */ for (p = args; is_pair(p); p = cdr(p)) { s7_pointer arg; arg = car(p); if ((is_pair(arg)) && /* has default value */ ((is_symbol(cadr(arg))) || /* if default value might involve eval in any way, it isn't simple */ ((is_pair(cadr(arg))) && /* pair as default only ok if it is (quote ...) */ (car(cadr(arg)) != sc->QUOTE)))) { happy = false; break; } } if (happy) set_simple_args(body); } sc->cycle_counter = 0; if (((unstarred_lambda) || (has_simple_args(body))) && (body_is_safe(sc, func, body, true))) { /* there is one problem with closure* here -- we can't trust anything that has fancy (non-constant) default argument values. */ set_safe_closure(body); /* this bit is set on the function itself in make_closure and friends */ } } } return(NULL); } static s7_pointer check_define(s7_scheme *sc) { s7_pointer func, caller; bool starred; int arity = CLOSURE_ARITY_NOT_SET; starred = (sc->op == OP_DEFINE_STAR); if (starred) { caller = sc->DEFINE_STAR; sc->op = OP_DEFINE_STAR_UNCHECKED; } else { if (sc->op == OP_DEFINE) caller = sc->DEFINE; else caller = sc->DEFINE_CONSTANT; } if (!is_pair(sc->code)) eval_error_with_caller(sc, "~A: nothing to define? ~A", caller, sc->code); /* (define) */ if (!is_pair(cdr(sc->code))) { if (is_null(cdr(sc->code))) eval_error_with_caller(sc, "~A: no value? ~A", caller, sc->code); /* (define var) */ eval_error_with_caller(sc, "~A: bad form? ~A", caller, sc->code); /* (define var . 1) */ } if (!is_pair(car(sc->code))) { if (is_not_null(cddr(sc->code))) /* (define var 1 . 2) */ eval_error_with_caller(sc, "~A: more than 1 value? ~A", caller, sc->code); /* (define var 1 2) */ if (starred) eval_error(sc, "define* is restricted to functions: (define* ~{~S~^ ~})", sc->code); func = car(sc->code); if (!is_symbol(func)) /* (define 3 a) */ eval_error_with_caller(sc, "~A: define a non-symbol? ~S", caller, func); if (is_keyword(func)) /* (define :hi 1) */ eval_error_with_caller(sc, "~A ~A: keywords are constants", caller, func); if (is_syntactic(func)) /* (define and a) */ { if (sc->safety > 0) s7_warn(sc, 128, "%s: syntactic keywords tend to behave badly if redefined", DISPLAY(func)); set_local(func); } if ((is_pair(cadr(sc->code))) && /* look for (define sym (lambda ...)) and treat it like (define (sym ...)...) */ ((caadr(sc->code) == sc->LAMBDA) || (caadr(sc->code) == sc->LAMBDA_STAR)) && (symbol_id(caadr(sc->code)) == 0)) /* not is_global here because that bit might not be set for initial symbols (why not? -- redef as method etc) */ optimize_lambda(sc, caadr(sc->code) == sc->LAMBDA, func, cadr(cadr(sc->code)), cddr(cadr(sc->code))); } else { func = caar(sc->code); if (!is_symbol(func)) /* (define (3 a) a) */ eval_error_with_caller(sc, "~A: define a non-symbol? ~S", caller, func); if (is_syntactic(func)) /* (define (and a) a) */ { if (sc->safety > 0) s7_warn(sc, 128, "%s: syntactic keywords tend to behave badly if redefined", DISPLAY(func)); set_local(func); } if (starred) cdar(sc->code) = check_lambda_star_args(sc, cdar(sc->code), &arity); else check_lambda_args(sc, cdar(sc->code), &arity); optimize_lambda(sc, !starred, func, cdar(sc->code), cdr(sc->code)); } if ((is_overlaid(sc->code)) && (has_opt_back(sc->code))) { if (sc->op == OP_DEFINE) { if ((is_pair(car(sc->code))) && (!symbol_has_accessor(func)) && (!is_immutable_symbol(func))) pair_set_syntax_symbol(sc->code, sc->DEFINE_FUNCHECKED); else pair_set_syntax_symbol(sc->code, sc->DEFINE_UNCHECKED); } else { if (starred) pair_set_syntax_symbol(sc->code, sc->DEFINE_STAR_UNCHECKED); else pair_set_syntax_symbol(sc->code, sc->DEFINE_CONSTANT_UNCHECKED); } } return(sc->code); } static int define_unchecked_ex(s7_scheme *sc) { if (sc->op == OP_DEFINE_STAR_UNCHECKED) { s7_pointer x; unsigned int typ; if (is_safe_closure(cdr(sc->code))) typ = T_CLOSURE_STAR | T_PROCEDURE | T_SAFE_CLOSURE; else typ = T_CLOSURE_STAR | T_PROCEDURE; new_cell(sc, x, typ); closure_args(x) = cdar(sc->code); closure_body(x) = cdr(sc->code); closure_set_let(x, sc->envir); closure_arity(x) = CLOSURE_ARITY_NOT_SET; closure_setter(x) = sc->F; sc->capture_let_counter++; sc->value = x; sc->code = caar(sc->code); return(fall_through); } if (!is_pair(car(sc->code))) { s7_pointer x; x = car(sc->code); sc->code = cadr(sc->code); if (is_pair(sc->code)) { push_stack(sc, OP_DEFINE1, sc->NIL, x); return(goto_EVAL); } if (is_symbol(sc->code)) sc->value = find_global_symbol_checked(sc, sc->code); else sc->value = sc->code; sc->code = x; } else { s7_pointer x; /* a closure. If we called this same code earlier (a local define), the only thing * that is new here is the environment -- we can't blithely save the closure object * in opt2 somewhere, and pick it up the next time around (since call/cc might take * us back to the previous case). We also can't re-use opt2(sc->code) because opt2 * is not cleared in the gc. */ make_closure_with_let(sc, x, cdar(sc->code), cdr(sc->code), sc->envir); sc->value = _NFre(x); sc->code = caar(sc->code); } return(fall_through); } static void define_funchecked(s7_scheme *sc) { s7_pointer new_func, new_env, code; code = sc->code; sc->value = caar(code); new_cell(sc, new_func, T_CLOSURE | T_PROCEDURE | T_COPY_ARGS); closure_args(new_func) = cdar(code); closure_body(new_func) = cdr(code); closure_setter(new_func) = sc->F; closure_arity(new_func) = CLOSURE_ARITY_NOT_SET; sc->capture_let_counter++; if (is_safe_closure(cdr(code))) { s7_pointer arg; set_safe_closure(new_func); new_cell_no_check(sc, new_env, T_LET | T_FUNCTION_ENV); let_id(new_env) = ++sc->let_number; let_set_slots(new_env, sc->NIL); set_outlet(new_env, sc->envir); closure_set_let(new_func, new_env); funclet_set_function(new_env, sc->value); for (arg = closure_args(new_func); is_pair(arg); arg = cdr(arg)) make_slot_1(sc, new_env, car(arg), sc->NIL); let_set_slots(new_env, reverse_slots(sc, let_slots(new_env))); } else closure_set_let(new_func, sc->envir); /* unsafe closures created by other functions do not support __func__ */ add_slot(sc->envir, sc->value, new_func); set_local(sc->value); sc->value = new_func; } static int lambda_star_default(s7_scheme *sc) { while (true) { s7_pointer z; z = sc->args; if (is_slot(z)) { if (slot_value(z) == sc->UNDEFINED) { if (is_closure_star(sc->code)) { s7_pointer val; val = slot_expression(z); if (is_symbol(val)) { slot_set_value(z, find_symbol_checked(sc, val)); if (slot_value(z) == sc->UNDEFINED) eval_error_no_return(sc, sc->SYNTAX_ERROR, "lambda* defaults: ~A is unbound", slot_symbol(z)); /* but #f is default if no expr, so there's some inconsistency here */ } else { if (is_pair(val)) { if (car(val) == sc->QUOTE) { if ((!is_pair(cdr(val))) || /* (lambda* ((a (quote))) a) or (lambda* ((a (quote 1 1))) a) etc */ (is_pair(cddr(val)))) eval_error_no_return(sc, sc->SYNTAX_ERROR, "lambda* default: ~A is messed up", val); slot_set_value(z, cadr(val)); } else { push_stack(sc, OP_LAMBDA_STAR_DEFAULT, sc->args, sc->code); sc->code = val; return(goto_EVAL); } } else slot_set_value(z, val); } } else slot_set_value(z, slot_expression(z)); } sc->args = slot_pending_value(z); } else break; } return(fall_through); } #if 0 static void unsafe_closure_2(s7_scheme *sc, s7_pointer arg1, s7_pointer arg2) { s7_pointer code, args; if (sc->stack_end >= sc->stack_resize_trigger) resize_stack(sc); /* not check_stack_size because it tries to return sc->F */ code = opt_lambda(sc->code); args = closure_args(code); new_frame_with_two_slots(sc, closure_let(code), sc->envir, car(args), arg1, cadr(args), arg2); sc->code = closure_body(code); } #else #define unsafe_closure_2(Sc, Arg1, Arg2) \ { \ s7_pointer Code, Args, A1, A2; A1 = Arg1; A2 = Arg2; \ if (Sc->stack_end >= Sc->stack_resize_trigger) resize_stack(Sc); \ Code = opt_lambda(Sc->code); \ Args = closure_args(Code); \ new_frame_with_two_slots(Sc, closure_let(Code), Sc->envir, car(Args), A1, cadr(Args), A2); \ Sc->code = closure_body(Code); \ } #endif static void unsafe_closure_star(s7_scheme *sc) { s7_pointer x, z, e; unsigned long long int id; new_frame(sc, closure_let(sc->code), sc->envir); e = sc->envir; id = let_id(e); for (x = closure_args(sc->code), z = sc->args; is_pair(x); x = cdr(x)) { s7_pointer sym, args, val; if (is_pair(car(x))) sym = caar(x); else sym = car(x); val = car(z); args = cdr(z); set_type(z, T_SLOT); slot_set_symbol(z, sym); symbol_set_local(sym, id, z); slot_set_value(z, val); next_slot(z) = let_slots(e); let_set_slots(e, z); z = args; } sc->code = closure_body(sc->code); } static void fill_closure_star(s7_scheme *sc, s7_pointer p) { for (; is_pair(p); p = cdr(p)) { s7_pointer defval; if (is_pair(car(p))) { defval = cadar(p); if (is_pair(defval)) sc->args = cons(sc, cadr(defval), sc->args); else sc->args = cons(sc, defval, sc->args); } else sc->args = cons(sc, sc->F, sc->args); } sc->args = safe_reverse_in_place(sc, sc->args); sc->code = opt_lambda(sc->code); } static void fill_safe_closure_star(s7_scheme *sc, s7_pointer x, s7_pointer p) { for (; is_pair(p); p = cdr(p), x = next_slot(x)) { s7_pointer defval; if (is_pair(car(p))) { defval = cadar(p); if (is_pair(defval)) slot_set_value(x, cadr(defval)); else slot_set_value(x, defval); } else slot_set_value(x, sc->F); symbol_set_local(slot_symbol(x), let_id(sc->envir), x); } sc->code = closure_body(opt_lambda(sc->code)); } static s7_pointer check_define_macro(s7_scheme *sc, opcode_t op) { s7_pointer x, y, caller; caller = sc->DEFINE_MACRO; switch (op) { case OP_DEFINE_MACRO: caller = sc->DEFINE_MACRO; break; case OP_DEFINE_MACRO_STAR: caller = sc->DEFINE_MACRO_STAR; break; case OP_DEFINE_BACRO: caller = sc->DEFINE_BACRO; break; case OP_DEFINE_BACRO_STAR: caller = sc->DEFINE_BACRO_STAR; break; case OP_DEFINE_EXPANSION: caller = sc->DEFINE_EXPANSION; break; } if (!is_pair(sc->code)) /* (define-macro . 1) */ eval_error_with_caller(sc, "~A name missing (stray dot?): ~A", caller, sc->code); if (!is_pair(car(sc->code))) /* (define-macro a ...) */ return(wrong_type_argument_with_type(sc, caller, 1, car(sc->code), make_string_wrapper(sc, "a list: (name ...)"))); /* not car(opt_back(sc->code)) to get the caller (e.g. 'define-bacro) because opt_back might not be set: (apply define-macro '(1)) */ x = caar(sc->code); if (!is_symbol(x)) eval_error_with_caller(sc, "~A: ~S is not a symbol?", caller, x); if (dont_eval_args(x)) /* (define-macro (quote a) quote) */ { if (sc->safety > 0) s7_warn(sc, 128, "%s: syntactic keywords tend to behave badly if redefined", DISPLAY(x)); set_local(x); } if (is_immutable_symbol(x)) eval_error_with_caller(sc, "~A: ~S is immutable", caller, x); if (!is_pair(cdr(sc->code))) /* (define-macro (...)) */ eval_error_with_caller(sc, "~A ~A, but no body?", caller, x); y = cdar(sc->code); /* the arglist */ if ((!s7_is_list(sc, y)) && (!is_symbol(y))) return(s7_error(sc, sc->SYNTAX_ERROR, /* (define-macro (mac . 1) ...) */ set_elist_3(sc, make_string_wrapper(sc, "macro ~A argument list is ~S?"), x, y))); for ( ; is_pair(y); y = cdr(y)) if ((!is_symbol(car(y))) && ((sc->op == OP_DEFINE_MACRO) || (sc->op == OP_DEFINE_BACRO) || (sc->op == OP_DEFINE_EXPANSION))) return(s7_error(sc, sc->SYNTAX_ERROR, /* (define-macro (mac 1) ...) */ set_elist_3(sc, make_string_wrapper(sc, "define-macro ~A argument name is not a symbol: ~S"), x, y))); if ((sc->op == OP_DEFINE_MACRO_STAR) || (sc->op == OP_DEFINE_BACRO_STAR)) cdar(sc->code) = check_lambda_star_args(sc, cdar(sc->code), NULL); else check_lambda_args(sc, cdar(sc->code), NULL); return(sc->code); } static int expansion_ex(s7_scheme *sc) { int loc; s7_pointer caller; /* read-time macro expansion: * (define-macro (hi a) (format #t "hi...") `(+ ,a 1)) * (define (ho b) (+ 1 (hi b))) * here sc->value is: (ho b), (hi b), (+ 1 (hi b)), (define (ho b) (+ 1 (hi b))) * but... first we can't tell for sure at this point that "hi" really is a macro * (letrec ((hi ... (hi...))) will be confused about the second hi, * or (call/cc (lambda (hi) (hi 1))) etc. * second, figuring out that we're quoted is not easy -- we have to march all the * way to the bottom of the stack looking for op_read_quote or op_read_vector * #(((hi)) 2) or '(((hi))) * or op_read_list with args not equal (quote) or (macroexapand) * '(hi 3) or (macroexpand (hi 3) or (quote (hi 3)) * and those are only the problems I noticed! * * The hardest of these problems involve shadowing, so Rick asked for "define-expansion" * which is like define-macro, but the programmer guarantees that the macro * name will not be shadowed. * * to make expansion recognition fast here, define-expansion sets the T_EXPANSION * bit in the symbol as well as the value: * set_type(sc->code, T_EXPANSION | T_SYMBOL) * but this can lead to confusion because the expansion name is now globally identified as an expansion. * (let () (define-expansion (ex1 a) `(+ ,a 1)) (display (ex1 3))) * (define (ex1 b) (* b 2)) (display (ex1 3)) * since this happens at the top level, the first line is evaluated, ex1 becomes an expansion. * but the reader has no idea about lets and whatnot, so in the second line, ex1 is still an expansion * to the reader, so ir sees (define (+ b 1) ...) -- error! To support tail-calls, there's no * way in eval to see the let close, so we can't clear the expansion flag when the let is done. * But we don't want define-expansion to mimic define-constant (via T_IMMUTABLE) because programs * like lint need to cancel reader-cond (for example). So, we allow an expansion to be redefined, * and check here that the expander symbol still refers to an expansion. * * but in (define (ex1 b) b), the reader doesn't know we're in a define call (or it would be * a bother to notice), so to redefine an expansion, first (set! ex1 #f) or (define ex1 #f), * then (define (ex1 b) b). * * This is a mess! Maybe we should insist that expansions are always global. */ loc = s7_stack_top(sc) - 1; if (is_pair(stack_args(sc->stack, loc))) caller = car(stack_args(sc->stack, loc)); /* this can be garbage */ else caller = sc->F; if ((loc >= 3) && (stack_op(sc->stack, loc) != OP_READ_QUOTE) && /* '(hi 1) for example */ (stack_op(sc->stack, loc) != OP_READ_VECTOR) && /* #(reader-cond) for example */ (caller != sc->QUOTE) && /* (quote (hi 1)) */ (caller != sc->MACROEXPAND) && /* (macroexpand (hi 1)) */ (caller != sc->DEFINE_EXPANSION)) /* (define-expansion ...) being reloaded/redefined */ { s7_pointer symbol, slot; /* we're playing fast and loose with sc->envir in the reader, so here we need a disaster check */ #if DEBUGGING if (unchecked_type(sc->envir) != T_LET) sc->envir = sc->NIL; #else if (!is_let(sc->envir)) sc->envir = sc->NIL; #endif symbol = car(sc->value); if ((symbol_id(symbol) == 0) || (sc->envir == sc->NIL)) slot = global_slot(symbol); else slot = find_symbol(sc, symbol); if (is_slot(slot)) sc->code = slot_value(slot); else sc->code = sc->UNDEFINED; if (!is_expansion(sc->code)) clear_expansion(symbol); else { sc->args = copy_list(sc, cdr(sc->value)); return(goto_APPLY); } } return(fall_through); } static s7_pointer check_with_let(s7_scheme *sc) { if (!is_pair(sc->code)) /* (with-let . "hi") */ eval_error(sc, "with-let takes an environment argument: ~A", sc->code); if (!is_pair(cdr(sc->code))) /* (with-let e) -> an error? */ eval_error(sc, "with-let body is messed up: ~A", sc->code); if ((!is_pair(cddr(sc->code))) && (!is_null(cddr(sc->code)))) eval_error(sc, "with-let body has stray dot? ~A", sc->code); if ((is_overlaid(sc->code)) && (has_opt_back(sc->code))) { pair_set_syntax_symbol(sc->code, sc->WITH_LET_UNCHECKED); if ((is_symbol(car(sc->code))) && (is_pair(cadr(sc->code)))) pair_set_syntax_symbol(sc->code, sc->WITH_LET_S); } return(sc->code); } static s7_pointer check_cond(s7_scheme *sc) { bool has_feed_to = false; s7_pointer x; if (!is_pair(sc->code)) /* (cond) or (cond . 1) */ eval_error(sc, "cond, but no body: ~A", sc->code); for (x = sc->code; is_pair(x); x = cdr(x)) { if (!is_pair(car(x))) /* (cond 1) or (cond (#t 1) 3) */ eval_error(sc, "every clause in cond must be a list: ~A", car(x)); else { s7_pointer y; y = car(x); if ((!is_pair(cdr(y))) && (!is_null(cdr(y)))) /* (cond (1 . 2)) */ eval_error(sc, "cond: stray dot? ~A", sc->code); if ((cadr(y) == sc->FEED_TO) && (s7_symbol_value(sc, sc->FEED_TO) == sc->UNDEFINED)) { has_feed_to = true; if (!is_pair(cddr(y))) /* (cond (#t =>)) or (cond (#t => . 1)) */ eval_error(sc, "cond: '=>' target missing? ~A", x); if (is_pair(cdddr(y))) /* (cond (1 => + abs)) */ eval_error(sc, "cond: '=>' has too many targets: ~A", x); } /* currently we accept: * (cond (1 2) (=> . =>)) and all variants thereof, e.g. (cond (1 2) (=> 1 . 2) (1 2)) or * (cond (1) (=>)) but Guile accepts this? * (cond (1) (1 =>)) * amusing (correct) case: (cond (1 => "hi")) -> #\i */ } } if (is_not_null(x)) /* (cond ((1 2)) . 1) */ eval_error(sc, "cond: stray dot? ~A", sc->code); if ((is_overlaid(sc->code)) && (has_opt_back(sc->code))) { if (has_feed_to) { pair_set_syntax_symbol(sc->code, sc->COND_UNCHECKED); if (is_null(cdr(sc->code))) { s7_pointer expr, f; expr = car(sc->code); f = caddr(expr); if ((is_pair(f)) && (car(f) == sc->LAMBDA) && (is_null(cdr(cddr(f))))) { s7_pointer arg; arg = cadr(f); if ((is_pair(arg)) && (is_null(cdr(arg))) && (is_symbol(car(arg)))) { /* (define (hi) (cond (#t => (lambda (s) s)))) */ set_opt_lambda2(sc->code, caddar(sc->code)); /* (lambda ...) above */ pair_set_syntax_symbol(sc->code, sc->IF_P_FEED); } } } } else { s7_pointer p, sym = NULL; bool xopt = true, c_s_is_ok = true; pair_set_syntax_symbol(sc->code, sc->COND_SIMPLE); for (p = sc->code; xopt && (is_pair(p)); p = cdr(p)) { xopt = is_all_x_safe(sc, caar(p)); if ((c_s_is_ok) && (caar(p) != sc->T) && (caar(p) != sc->ELSE)) { if ((!is_pair(caar(p))) || (!is_h_safe_c_s(caar(p))) || ((sym) && (sym != cadaar(p)))) c_s_is_ok = false; else sym = cadaar(p); } } if (c_s_is_ok) pair_set_syntax_symbol(sc->code, sc->COND_S); else { if (xopt) { int i; pair_set_syntax_symbol(sc->code, sc->COND_ALL_X); for (i = 0, p = sc->code; is_pair(p); i++, p = cdr(p)) set_c_call(car(p), cond_all_x_eval(sc, caar(p), sc->envir)); /* handle 'else' specially here */ if (i == 2) pair_set_syntax_symbol(sc->code, sc->COND_ALL_X_2); } } } } return(sc->code); } static s7_pointer check_set(s7_scheme *sc) { if (!is_pair(sc->code)) { if (is_null(sc->code)) /* (set!) */ eval_error(sc, "set!: not enough arguments: ~A", sc->code); eval_error(sc, "set!: stray dot? ~A", sc->code); /* (set! . 1) */ } if (!is_pair(cdr(sc->code))) { if (is_null(cdr(sc->code))) /* (set! var) */ eval_error(sc, "set!: not enough arguments: ~A", sc->code); eval_error(sc, "set!: stray dot? ~A", sc->code); /* (set! var . 1) */ } if (is_not_null(cddr(sc->code))) /* (set! var 1 2) */ eval_error(sc, "~A: too many arguments to set!", sc->code); /* cadr (the value) has not yet been evaluated */ if (is_immutable(car(sc->code))) /* (set! pi 3) */ eval_error(sc, "set!: can't alter immutable object: ~S", car(sc->code)); if (is_pair(car(sc->code))) { if (is_pair(caar(sc->code))) { if (!s7_is_list(sc, cdar(sc->code))) /* (set! ('(1 2) . 0) 1) */ eval_error(sc, "improper list of args to set!: ~A", sc->code); } if (!is_proper_list(sc, car(sc->code))) /* (set! ("hi" . 1) #\a) or (set! (#(1 2) . 1) 0) */ eval_error(sc, "set! target is an improper list: (set! ~A ...)", car(sc->code)); } else { if (!is_symbol(car(sc->code))) /* (set! 12345 1) */ eval_error(sc, "set! can't change ~S", car(sc->code)); } if ((is_overlaid(sc->code)) && (has_opt_back(sc->code))) { if (is_pair(car(sc->code))) { /* here we have (set! (...) ...) */ s7_pointer inner, value; inner = car(sc->code); value = cadr(sc->code); pair_set_syntax_symbol(sc->code, sc->SET_UNCHECKED); if (is_symbol(car(inner))) { if ((is_null(cdr(inner))) && (!is_pair(value)) && (is_global(car(inner))) && (is_c_function(slot_value(global_slot(car(inner))))) && (c_function_required_args(slot_value(global_slot(car(inner)))) == 0)) pair_set_syntax_symbol(sc->code, sc->SET_PWS); else { if ((is_pair(cdr(inner))) && (!is_pair(cddr(inner)))) /* we check cddr(sc->code) above */ { if (!is_pair(cadr(inner))) { /* (set! (f s) ...) */ if (!is_pair(value)) pair_set_syntax_symbol(sc->code, sc->SET_PAIR); else { pair_set_syntax_symbol(sc->code, sc->SET_PAIR_P); /* splice_in_values protects us here from values */ if (is_h_optimized(value)) /* this excludes h_unknown_g etc */ { pair_set_syntax_symbol(sc->code, sc->SET_PAIR_Z); if (is_all_x_safe(sc, value)) { s7_pointer obj; annotate_arg(sc, cdr(sc->code), sc->envir); pair_set_syntax_symbol(sc->code, sc->SET_PAIR_ZA); obj = find_symbol_checked(sc, car(inner)); if ((is_c_function(obj)) && (is_c_function(c_function_setter(obj)))) { pair_set_syntax_symbol(sc->code, sc->SET_PAIR_A); } } } } } else { if ((car(cadr(inner)) == sc->QUOTE) && (is_symbol(car(inner))) && ((is_symbol(value)) || (is_all_x_safe(sc, value)))) { if (is_symbol(value)) pair_set_syntax_symbol(sc->code, sc->SET_LET_S); else { pair_set_syntax_symbol(sc->code, sc->SET_LET_ALL_X); set_c_call(cdr(sc->code), all_x_eval(sc, value, sc->envir, let_symbol_is_safe)); } } else { if (is_h_safe_c_c(cadr(inner))) { if (!is_pair(value)) pair_set_syntax_symbol(sc->code, sc->SET_PAIR_C); else { /* splice_in_values protects us here from values */ pair_set_syntax_symbol(sc->code, sc->SET_PAIR_C_P); } } } } } } } } else pair_set_syntax_symbol(sc->code, sc->SET_NORMAL); if (is_symbol(car(sc->code))) { s7_pointer settee, value; settee = car(sc->code); value = cadr(sc->code); if ((!symbol_has_accessor(settee)) && (!is_syntactic(settee))) { if (is_symbol(value)) pair_set_syntax_symbol(sc->code, sc->SET_SYMBOL_S); else { if (!is_pair(value)) pair_set_syntax_symbol(sc->code, sc->SET_SYMBOL_C); else { if (car(value) == sc->QUOTE) pair_set_syntax_symbol(sc->code, sc->SET_SYMBOL_Q); else { /* if cadr(cadr) == car, or cdr(cadr) not null and cadr(cadr) == car, and cddr(cadr) == null, * it's (set! ( val)) or ( val ) or ( ) * in the set code, we get the slot as usual, then in case 1 above, * car(sc->T2_1) = slot_value(slot), car(sc->T2_2) = increment, call , set slot_value(slot) * * this can be done in all combined cases where a symbol is repeated (do in particular) */ /* (define (hi) (let ((x 1)) (set! x (+ x 1)))) * but the value might be values: * (let () (define (hi) (let ((x 0)) (set! x (values 1 2)) x)) (catch #t hi (lambda a a)) (hi)) * which is caught in splice_in_values */ pair_set_syntax_symbol(sc->code, sc->SET_SYMBOL_P); if (is_h_safe_c_s(value)) { pair_set_syntax_symbol(sc->code, sc->SET_SYMBOL_opSq); set_opt_sym2(sc->code, cadr(value)); } else { if (is_h_optimized(value)) { pair_set_syntax_symbol(sc->code, sc->SET_SYMBOL_Z); if (optimize_op(value) == HOP_SAFE_C_C) { pair_set_syntax_symbol(sc->code, sc->SET_SYMBOL_opCq); /* opt1 here points back? */ set_opt_pair2(sc->code, cdr(value)); } else { /* most of these special cases probably don't matter */ if (optimize_op(value) == HOP_SAFE_C_SS) { if (settee == cadr(value)) pair_set_syntax_symbol(sc->code, sc->INCREMENT_SS); else pair_set_syntax_symbol(sc->code, sc->SET_SYMBOL_opSSq); set_opt_pair2(sc->code, cdr(value)); } else { if (optimize_op(value) == HOP_SAFE_C_SSS) { if ((settee == cadr(value)) && (car(value) == sc->ADD)) pair_set_syntax_symbol(sc->code, sc->INCREMENT_SSS); else pair_set_syntax_symbol(sc->code, sc->SET_SYMBOL_opSSSq); set_opt_pair2(sc->code, cdr(value)); } else { if (is_all_x_safe(sc, value)) /* value = cadr(sc->code) */ { pair_set_syntax_symbol(sc->code, sc->SET_SYMBOL_A); annotate_arg(sc, cdr(sc->code), sc->envir); } if (is_callable_c_op(optimize_op(value))) { if ((settee == cadr(value)) && (!is_null(cddr(value)))) { if (is_null(cdddr(value))) { if (is_all_x_safe(sc, caddr(value))) { /* this appears to give a slight savings over the SZ case */ pair_set_syntax_symbol(sc->code, sc->INCREMENT_SA); annotate_arg(sc, cddr(value), sc->envir); /* this sets c_callee(arg) */ set_opt_pair2(sc->code, cddr(value)); } else { if (is_optimized(caddr(value))) { pair_set_syntax_symbol(sc->code, sc->INCREMENT_SZ); set_opt_pair2(sc->code, caddr(value)); } } } else { if ((is_null(cddddr(value))) && (is_all_x_safe(sc, caddr(value))) && (is_all_x_safe(sc, cadddr(value)))) { pair_set_syntax_symbol(sc->code, sc->INCREMENT_SAA); annotate_arg(sc, cddr(value), sc->envir); annotate_arg(sc, cdddr(value), sc->envir); set_opt_pair2(sc->code, cddr(value)); } } } } } } } } } if ((is_h_optimized(value)) && (!is_unsafe(value)) && (is_not_null(cdr(value)))) /* (set! x (y)) */ { if (is_not_null(cddr(value))) { if ((caddr(value) == small_int(1)) && (cadr(value) == settee)) { if ((opt_cfunc(value) == add_s1) || (opt_cfunc(value) == add_cs1)) pair_set_syntax_symbol(sc->code, sc->INCREMENT_1); else { if ((opt_cfunc(value) == subtract_s1) || (opt_cfunc(value) == subtract_cs1)) pair_set_syntax_symbol(sc->code, sc->DECREMENT_1); } } else { if ((cadr(value) == small_int(1)) && (caddr(value) == settee) && (opt_cfunc(value) == add_1s)) pair_set_syntax_symbol(sc->code, sc->INCREMENT_1); else { if ((settee == caddr(value)) && (is_symbol(cadr(value))) && (caadr(sc->code) == sc->CONS)) { pair_set_syntax_symbol(sc->code, sc->SET_CONS); set_opt_sym2(sc->code, cadr(value)); } } } } } } } } } } } return(sc->code); } static bool set_pair_p_3(s7_scheme *sc, s7_pointer obj, s7_pointer arg, s7_pointer value) { if (is_slot(obj)) obj = slot_value(obj); else eval_error(sc, "no generalized set for ~A", caar(sc->code)); switch (type(obj)) { case T_C_OBJECT: car(sc->T2_1) = arg; car(sc->T2_2) = value; sc->value = (*(c_object_set(obj)))(sc, obj, sc->T2_1); break; /* some of these are wasteful -- we know the object type! (list hash-table) */ case T_INT_VECTOR: case T_FLOAT_VECTOR: case T_VECTOR: #if WITH_GMP car(sc->T3_1) = obj; car(sc->T3_2) = arg; car(sc->T3_3) = value; sc->value = g_vector_set(sc, sc->T3_1); #else if (vector_rank(obj) > 1) { car(sc->T3_1) = obj; car(sc->T3_2) = arg; car(sc->T3_3) = value; sc->value = g_vector_set(sc, sc->T3_1); } else { s7_int index; if (!is_integer(arg)) eval_type_error(sc, "vector-set!: index must be an integer: ~S", sc->code); index = integer(arg); if (index < 0) eval_range_error(sc, "vector-set!: index must not be negative: ~S", sc->code); if (index >= vector_length(obj)) eval_range_error(sc, "vector-set!: index must be less than vector length: ~S", sc->code); vector_setter(obj)(sc, obj, index, value); sc->value = _NFre(value); } #endif break; case T_STRING: #if WITH_GMP car(sc->T3_1) = obj; car(sc->T3_2) = arg; car(sc->T3_3) = value; sc->value = g_string_set(sc, sc->T3_1); #else { s7_int index; if (!is_integer(arg)) eval_type_error(sc, "string-set!: index must be an integer: ~S", sc->code); index = integer(arg); if (index < 0) eval_range_error(sc, "string-set!: index must not be negative: ~S", sc->code); if (index >= string_length(obj)) eval_range_error(sc, "string-set!: index must be less than string length: ~S", sc->code); if (s7_is_character(value)) { string_value(obj)[index] = (char)s7_character(value); sc->value = _NFre(value); } else { if ((is_byte_vector(obj)) && (s7_is_integer(value))) { int ic; ic = s7_integer(value); if ((ic < 0) || (ic > 255)) eval_type_error(sc, "string-set!: value must be a character: ~S", sc->code); string_value(obj)[index] = (char)ic; sc->value = _NFre(value); } else eval_type_error(sc, "string-set!: value must be a character: ~S", sc->code); } } #endif break; case T_PAIR: car(sc->T3_1) = obj; car(sc->T3_2) = arg; car(sc->T3_3) = value; sc->value = g_list_set(sc, sc->T3_1); break; case T_HASH_TABLE: sc->value = s7_hash_table_set(sc, obj, arg, value); break; case T_LET: sc->value = s7_let_set(sc, obj, arg, value); break; case T_C_OPT_ARGS_FUNCTION: case T_C_RST_ARGS_FUNCTION: case T_C_ANY_ARGS_FUNCTION: /* (let ((lst (list 1 2))) (set! (list-ref lst 1) 2) lst) */ case T_C_FUNCTION: case T_C_FUNCTION_STAR: /* obj here is a c_function, but its setter could be a closure and vice versa below */ if (is_procedure_or_macro(c_function_setter(obj))) { if (is_c_function(c_function_setter(obj))) { car(sc->T2_1) = arg; car(sc->T2_2) = value; sc->value = c_function_call(c_function_setter(obj))(sc, sc->T2_1); } else { sc->code = c_function_setter(obj); if (needs_copied_args(sc->code)) sc->args = list_2(sc, arg, value); else sc->args = set_plist_2(sc, arg, value); return(true); /* goto APPLY; */ } } else eval_error(sc, "no generalized set for ~A", obj); break; case T_MACRO: case T_MACRO_STAR: case T_BACRO: case T_BACRO_STAR: case T_CLOSURE: case T_CLOSURE_STAR: if (is_procedure_or_macro(closure_setter(obj))) { if (is_c_function(closure_setter(obj))) { car(sc->T2_1) = arg; car(sc->T2_2) = value; sc->value = c_function_call(closure_setter(obj))(sc, sc->T2_1); } else { sc->code = closure_setter(obj); if (needs_copied_args(sc->code)) sc->args = list_2(sc, arg, value); else sc->args = set_plist_2(sc, arg, value); return(true); /* goto APPLY; */ } } else eval_error(sc, "no generalized set for ~A", obj); break; default: /* (set! (1 2) 3) */ eval_error(sc, "no generalized set for ~A", obj); } return(false); } static bool safe_stepper(s7_scheme *sc, s7_pointer expr, s7_pointer vars) { /* for now, just look for stepper as last element of any list * any embedded set is handled by do-is-safe, so we don't need to descend into the depths */ s7_pointer p; if (direct_memq(cadr(expr), vars)) return(false); for (p = cdr(expr); is_pair(cdr(p)); p = cdr(p)); if (is_pair(p)) { if ((is_optimized(p)) && ((optimize_op(p) & 1) != 0) && (is_safe_c_op(optimize_op(p)))) return(true); if (direct_memq(car(p), vars)) return(false); } else { if (direct_memq(p, vars)) return(false); } return(true); } static int set_pair_ex(s7_scheme *sc) { s7_pointer caar_code, cx; caar_code = caar(sc->code); if (is_pair(caar_code)) { push_stack(sc, OP_SET2, cdar(sc->code), cdr(sc->code)); sc->code = caar_code; return(goto_EVAL); } if (is_symbol(caar_code)) { /* this was cx = s7_symbol_value(sc, caar_code) but the function call overhead is noticeable */ cx = find_symbol(sc, caar_code); if (is_slot(cx)) cx = slot_value(cx); else eval_error_no_return(sc, sc->SYNTAX_ERROR, "no generalized set for ~A", caar_code); } else cx = caar_code; /* code here is the accessor and the value without the "set!": ((window-width) 800) */ /* (set! (hi 0) (* 2 3)) -> ((hi 0) (* 2 3)) */ /* for these kinds of objects, some Schemes restrict set! * (list-set! '(1 2 3) 1 32) is accepted but does it make sense? * (set-car! '(1 . 2) 32) * (string-set! "hiho" 1 #\z) * (vector-set! #(1 2 3) 1 32) * (let ((x (lambda () "hiho"))) (string-set! (x) 1 #\a)) * (let ((x (lambda () #(1 2 3)))) (vector-set! (x) 1 32)) * (let ((str "hiho")) (string-set! str 1 #\x) str) * (let ((v #(1 2 3))) (vector-set! v 1 32) v) * (let ((x (lambda () "hiho"))) (string-set! (x) 1 #\x) (x)) * * It seems weird that we can reach into both the function body, and its closure: * (let ((xx (let ((x '(1 2 3))) (lambda () x)))) (list-set! (xx) 1 32) (xx)) -> '(1 32 3) * * (let* ((x '(1 2)) (y (list x)) (z (car y))) (list-set! z 1 32) (list x y z)) * ((1 32) ((1 32)) (1 32)) * * (string-set! (symbol->string 'symbol->string) 1 #\X) -> error currently also in Guile "string is read-only" * (setf (elt (symbol-name 'xyz) 1) #\X) -> error in CL "read-only string" */ /* for gmp case, indices need to be decoded via s7_integer, not just integer */ switch (type(cx)) { case T_C_OBJECT: { s7_pointer settee, index, val; if (is_null(cdr(sc->code))) s7_wrong_number_of_args_error(sc, "no value for object-set!: ~S", sc->code); if (!is_null(cddr(sc->code))) s7_wrong_number_of_args_error(sc, "too many values for object-set!: ~S", sc->code); settee = car(sc->code); if ((is_null(cdr(settee))) || (!is_null(cddr(settee)))) { /* no-index or multi-index case -- use slow version. * TODO: ambiguity here -- is (set! (obj a b) v) actually (set! ((obj a) b) v)? * perhaps look at setter? c-object-set takes 1 arg -- is this a bug? */ push_op_stack(sc, sc->Object_Set); if (is_null(cdr(settee))) { push_stack(sc, OP_EVAL_ARGS1, list_1(sc, cx), cddr(sc->code)); sc->code = cadr(sc->code); } else { push_stack(sc, OP_EVAL_ARGS1, list_1(sc, cx), s7_append(sc, cddr(settee), cdr(sc->code))); sc->code = cadr(settee); } return(goto_EVAL); } index = cadr(settee); if (!is_pair(index)) { if (is_symbol(index)) index = find_symbol_checked(sc, index); val = cadr(sc->code); if (!is_pair(val)) { if (is_symbol(val)) val = find_symbol_checked(sc, val); car(sc->T2_1) = index; car(sc->T2_2) = val; sc->value = (*(c_object_set(cx)))(sc, cx, sc->T2_1); return(goto_START); } push_op_stack(sc, sc->Object_Set); sc->args = list_2(sc, index, cx); sc->code = cdr(sc->code); return(goto_EVAL_ARGS); } else { push_stack(sc, OP_EVAL_ARGS1, list_1(sc, cx), cdr(sc->code)); push_op_stack(sc, sc->Object_Set); sc->code = cadr(settee); } return(goto_EVAL); } break; case T_INT_VECTOR: case T_FLOAT_VECTOR: case T_VECTOR: { /* cx is the vector, sc->code is expr without the set! */ /* args have not been evaluated! */ s7_pointer settee, index, val; if (is_null(cdr(sc->code))) s7_wrong_number_of_args_error(sc, "no value for vector-set!: ~S", sc->code); if (!is_null(cddr(sc->code))) s7_wrong_number_of_args_error(sc, "too many values for vector-set!: ~S", sc->code); settee = car(sc->code); if (is_null(cdr(settee))) s7_wrong_number_of_args_error(sc, "no index for vector-set!: ~S", sc->code); if ((!is_null(cddr(settee))) && (type(cx) == T_VECTOR)) { push_stack(sc, OP_SET2, cddr(settee), cdr(sc->code)); sc->code = list_2(sc, car(settee), cadr(settee)); return(goto_EVAL); } if ((!is_null(cddr(settee))) || (vector_rank(cx) > 1)) { /* multi-index case -- use slow version */ push_op_stack(sc, sc->Vector_Set); push_stack(sc, OP_EVAL_ARGS1, list_1(sc, cx), s7_append(sc, cddr(settee), cdr(sc->code))); sc->code = cadr(settee); return(goto_EVAL); } index = cadr(settee); if (!is_pair(index)) { s7_int ind; if (is_symbol(index)) index = find_symbol_checked(sc, index); if (!s7_is_integer(index)) eval_error_no_return(sc, sc->WRONG_TYPE_ARG, "vector-set!: index must be an integer: ~S", sc->code); ind = s7_integer(index); if ((ind < 0) || (ind >= vector_length(cx))) out_of_range(sc, sc->VECTOR_SET, small_int(2), index, (ind < 0) ? ITS_NEGATIVE : ITS_TOO_LARGE); val = cadr(sc->code); if (!is_pair(val)) { if (is_symbol(val)) val = find_symbol_checked(sc, val); vector_setter(cx)(sc, cx, ind, val); sc->value = _NFre(val); return(goto_START); } push_op_stack(sc, sc->Vector_Set); sc->args = list_2(sc, index, cx); sc->code = cdr(sc->code); return(goto_EVAL_ARGS); } else { /* here the index calc might be trivial -- (+ i 1) or (- j 1) but this branch hardly ever happens */ push_stack(sc, OP_EVAL_ARGS1, list_1(sc, cx), cdr(sc->code)); push_op_stack(sc, sc->Vector_Set); sc->code = cadr(settee); } } break; case T_STRING: { /* sc->code = cons(sc, sc->String_Set, s7_append(sc, car(sc->code), cdr(sc->code))); * * here only one index makes sense, and it is required, so * (set! ("str") #\a), (set! ("str" . 1) #\a) and (set! ("str" 1 2) #\a) * are all errors (but see below!). */ s7_pointer settee, index, val; if (is_null(cdr(sc->code))) s7_wrong_number_of_args_error(sc, "no value for string-set!: ~S", sc->code); if (!is_null(cddr(sc->code))) s7_wrong_number_of_args_error(sc, "too many values for string-set!: ~S", sc->code); settee = car(sc->code); if (is_null(cdr(settee))) /* there's an index: (set! (str i) #\a), code is ((str 0) #\1) */ s7_wrong_number_of_args_error(sc, "no index for string-set!: ~S", sc->code); if (!is_null(cddr(settee))) s7_wrong_number_of_args_error(sc, "too many indices for string-set!: ~S", sc->code); /* if there's one index (the standard case), and it is not a pair, and there's one value (also standard) * and it is not a pair, let's optimize this thing! * cx is what we're setting, cadar is the index, cadr is the new value */ index = cadr(settee); if (!is_pair(index)) { s7_int ind; if (is_symbol(index)) index = find_symbol_checked(sc, index); if (!s7_is_integer(index)) eval_error_no_return(sc, sc->WRONG_TYPE_ARG, "string-set!: index must be an integer: ~S", sc->code); ind = s7_integer(index); if ((ind < 0) || (ind >= string_length(cx))) out_of_range(sc, sc->STRING_SET, small_int(2), index, (ind < 0) ? ITS_NEGATIVE : ITS_TOO_LARGE); val = cadr(sc->code); if (!is_pair(val)) { if (is_symbol(val)) val = find_symbol_checked(sc, val); if (s7_is_character(val)) { string_value(cx)[ind] = character(val); sc->value = val; return(goto_START); } else { if ((is_byte_vector(cx)) && (s7_is_integer(val))) { int ic; ic = s7_integer(val); if ((ic < 0) || (ic > 255)) eval_error_no_return(sc, sc->WRONG_TYPE_ARG, "string-set!: value must be a character: ~S", sc->code); string_value(cx)[ind] = (char)ic; sc->value = val; return(goto_START); } } eval_error_no_return(sc, sc->WRONG_TYPE_ARG, "string-set!: value must be a character: ~S", sc->code); } push_op_stack(sc, sc->String_Set); sc->args = list_2(sc, index, cx); sc->code = cdr(sc->code); return(goto_EVAL_ARGS); } else { push_stack(sc, OP_EVAL_ARGS1, list_1(sc, cx), cdr(sc->code)); push_op_stack(sc, sc->String_Set); sc->code = cadar(sc->code); } } break; case T_PAIR: /* code: ((lst 1) 32) from (let ((lst '(1 2 3))) (set! (lst 1) 32)) */ { s7_pointer settee, index, val; if (is_null(cdr(sc->code))) s7_wrong_number_of_args_error(sc, "no value for list-set!: ~S", sc->code); if (!is_null(cddr(sc->code))) s7_wrong_number_of_args_error(sc, "too many values for list-set!: ~S", sc->code); settee = car(sc->code); if (is_null(cdr(settee))) s7_wrong_number_of_args_error(sc, "no index for list-set!: ~S", sc->code); if (!is_null(cddr(settee))) { /* split (set! (a b c...) v) into (set! ((a b) c ...) v), eval (a b), return * (let ((L (list (list 1 2)))) (set! (L 0 0) 3) L) */ push_stack(sc, OP_SET2, cddr(settee), cdr(sc->code)); sc->code = list_2(sc, car(settee), cadr(settee)); return(goto_EVAL); } index = cadr(settee); val = cadr(sc->code); if ((is_pair(index)) || (is_pair(val))) { push_op_stack(sc, sc->List_Set); push_stack(sc, OP_EVAL_ARGS1, list_1(sc, cx), s7_append(sc, cddr(settee), cdr(sc->code))); sc->code = index; return(goto_EVAL); } if (is_symbol(index)) index = find_symbol_checked(sc, index); if (is_symbol(val)) val = find_symbol_checked(sc, val); car(sc->T2_1) = index; car(sc->T2_2) = val; sc->value = g_list_set_1(sc, cx, sc->T2_1, 2); return(goto_START); } break; case T_HASH_TABLE: { s7_pointer settee, key; if (is_null(cdr(sc->code))) s7_wrong_number_of_args_error(sc, "no value for hash-table-set!: ~S", sc->code); if (!is_null(cddr(sc->code))) s7_wrong_number_of_args_error(sc, "too many values for hash-table-set!: ~S", sc->code); settee = car(sc->code); if (is_null(cdr(settee))) s7_wrong_number_of_args_error(sc, "no key for hash-table-set!: ~S", sc->code); if (!is_null(cddr(settee))) { push_stack(sc, OP_SET2, cddr(settee), cdr(sc->code)); sc->code = list_2(sc, car(settee), cadr(settee)); return(goto_EVAL); } key = cadr(settee); if (!is_pair(key)) { s7_pointer val; if (is_symbol(key)) key = find_symbol_checked(sc, key); val = cadr(sc->code); if (!is_pair(val)) { if (is_symbol(val)) val = find_symbol_checked(sc, val); sc->value = s7_hash_table_set(sc, cx, key, val); return(goto_START); } push_op_stack(sc, sc->Hash_Table_Set); sc->args = list_2(sc, key, cx); sc->code = cdr(sc->code); return(goto_EVAL_ARGS); } else { push_stack(sc, OP_EVAL_ARGS1, list_1(sc, cx), cdr(sc->code)); push_op_stack(sc, sc->Hash_Table_Set); sc->code = cadar(sc->code); } } break; case T_LET: /* sc->code = cons(sc, sc->Let_Set, s7_append(sc, car(sc->code), cdr(sc->code))); */ { s7_pointer settee, key; /* code: ((gen 'input) input) from (set! (gen 'input) input) */ if (is_null(cdr(sc->code))) s7_wrong_number_of_args_error(sc, "no value for let-set!: ~S", sc->code); if (!is_null(cddr(sc->code))) s7_wrong_number_of_args_error(sc, "too many values for let-set!: ~S", sc->code); settee = car(sc->code); if (is_null(cdr(settee))) s7_wrong_number_of_args_error(sc, "no identifier for let-set!: ~S", sc->code); if (!is_null(cddr(settee))) { push_stack(sc, OP_SET2, cddr(settee), cdr(sc->code)); sc->code = list_2(sc, car(settee), cadr(settee)); return(goto_EVAL); } key = cadr(settee); if ((is_pair(key)) && (car(key) == sc->QUOTE)) { s7_pointer val; key = cadr(key); val = cadr(sc->code); if (!is_pair(val)) { if (is_symbol(val)) val = find_symbol_checked(sc, val); sc->value = s7_let_set(sc, cx, key, val); return(goto_START); } push_op_stack(sc, sc->Let_Set); sc->args = list_2(sc, key, cx); sc->code = cdr(sc->code); return(goto_EVAL_ARGS); } else { push_stack(sc, OP_EVAL_ARGS1, list_1(sc, cx), cdr(sc->code)); push_op_stack(sc, sc->Let_Set); sc->code = cadar(sc->code); } } break; case T_C_MACRO: case T_C_OPT_ARGS_FUNCTION: case T_C_RST_ARGS_FUNCTION: case T_C_ANY_ARGS_FUNCTION: /* (let ((lst (list 1 2))) (set! (list-ref lst 0) 2) lst) */ case T_C_FUNCTION: case T_C_FUNCTION_STAR: /* perhaps it has a setter */ if (is_procedure(c_function_setter(cx))) { /* sc->code = cons(sc, c_function_setter(cx), s7_append(sc, cdar(sc->code), cdr(sc->code))); */ if (is_pair(cdar(sc->code))) { if ((is_symbol(cadr(sc->code))) && (is_symbol(cadar(sc->code)))) { if (is_null(cddar(sc->code))) { car(sc->T2_1) = find_symbol_checked(sc, cadar(sc->code)); car(sc->T2_2) = find_symbol_checked(sc, cadr(sc->code)); sc->args = sc->T2_1; sc->code = c_function_setter(cx); return(goto_APPLY); /* check arg num etc */ } if ((is_symbol(caddar(sc->code))) && (is_null(cdddar(sc->code)))) { car(sc->T3_1) = find_symbol_checked(sc, cadar(sc->code)); car(sc->T3_2) = find_symbol_checked(sc, caddar(sc->code)); car(sc->T3_3) = find_symbol_checked(sc, cadr(sc->code)); sc->args = sc->T3_1; sc->code = c_function_setter(cx); return(goto_APPLY); /* check arg num etc */ } } push_op_stack(sc, c_function_setter(cx)); push_stack(sc, OP_EVAL_ARGS1, sc->NIL, s7_append(sc, cddar(sc->code), cdr(sc->code))); sc->code = cadar(sc->code); } else { if ((is_null(cddr(sc->code))) && (!is_pair(cadr(sc->code)))) { if (is_symbol(cadr(sc->code))) car(sc->T1_1) = find_symbol_checked(sc, cadr(sc->code)); else car(sc->T1_1) = cadr(sc->code); sc->args = sc->T1_1; sc->code = c_function_setter(cx); return(goto_APPLY); /* check arg num etc */ } push_op_stack(sc, c_function_setter(cx)); push_stack(sc, OP_EVAL_ARGS1, sc->NIL, cddr(sc->code)); sc->code = cadr(sc->code); } } else { if (is_any_macro(c_function_setter(cx))) { if (is_null(cdar(sc->code))) sc->args = copy_list(sc, cdr(sc->code)); else sc->args = s7_append(sc, cdar(sc->code), copy_list(sc, cdr(sc->code))); /* append copies except for its last arg, but for macros, we have to copy everything, hence the extra copy_list */ sc->code = c_function_setter(cx); return(goto_APPLY); } else eval_error_no_return(sc, sc->SYNTAX_ERROR, "no generalized set for ~A", caar_code); } break; case T_MACRO: case T_MACRO_STAR: case T_BACRO: case T_BACRO_STAR: case T_CLOSURE: case T_CLOSURE_STAR: { s7_pointer setter; setter = closure_setter(cx); if (is_procedure(setter)) /* appears to be caar_code */ { /* (set! (o g) ...), here cx = o, sc->code = ((o g) ...) */ push_op_stack(sc, setter); if (is_null(cdar(sc->code))) { push_stack(sc, OP_EVAL_ARGS1, sc->NIL, cddr(sc->code)); sc->code = cadr(sc->code); } else { if (is_null(cddar(sc->code))) push_stack(sc, OP_EVAL_ARGS1, sc->NIL, cdr(sc->code)); else push_stack(sc, OP_EVAL_ARGS1, sc->NIL, s7_append(sc, cddar(sc->code), cdr(sc->code))); sc->code = cadar(sc->code); } } else { if (is_any_macro(setter)) { if (is_null(cdar(sc->code))) sc->args = copy_list(sc, cdr(sc->code)); else sc->args = s7_append(sc, cdar(sc->code), copy_list(sc, cdr(sc->code))); sc->code = setter; return(goto_APPLY); } else eval_error_no_return(sc, sc->SYNTAX_ERROR, "no generalized set for ~A", caar_code); } } break; case T_ITERATOR: /* not sure this makes sense */ { s7_pointer setter; setter = iterator_sequence(cx); if ((is_any_closure(setter)) || (is_any_macro(setter))) setter = closure_setter(iterator_sequence(cx)); else setter = sc->F; if (is_procedure(setter)) { push_op_stack(sc, setter); push_stack(sc, OP_EVAL_ARGS1, sc->NIL, sc->NIL); sc->code = cadr(sc->code); /* the (as yet unevaluated) value, incoming code was ((obj) val) */ } else { if (is_any_macro(setter)) { sc->args = list_1(sc, cadr(sc->code)); sc->code = setter; return(goto_APPLY); } else eval_error_no_return(sc, sc->SYNTAX_ERROR, "no generalized set for ~A", caar_code); } } break; default: /* (set! (1 2) 3) */ eval_error_no_return(sc, sc->SYNTAX_ERROR, "no generalized set for ~A", caar_code); } return(goto_EVAL); } static bool tree_match(s7_scheme *sc, s7_pointer tree) { if (is_symbol(tree)) return(is_matched_symbol(tree)); if (is_pair(tree)) return((tree_match(sc, car(tree))) || (tree_match(sc, cdr(tree)))); return(false); } static bool do_is_safe(s7_scheme *sc, s7_pointer body, s7_pointer steppers, s7_pointer var_list, bool *has_set) { /* here any (unsafe?) closure or jumping-op (call/cc) or shadowed variable is trouble */ s7_pointer p; for (p = body; is_pair(p); p = cdr(p)) { s7_pointer expr; expr = car(p); if (is_pair(expr)) { s7_pointer x; x = car(expr); if (is_symbol(x)) { if (is_syntactic(x)) { opcode_t op; s7_pointer func, vars; func = slot_value(global_slot(x)); op = (opcode_t)syntax_opcode(func); switch (op) { case OP_MACROEXPAND: return(false); case OP_QUOTE: break; case OP_LET: case OP_LET_STAR: if (is_symbol(cadr(expr))) return(false); case OP_LETREC: case OP_LETREC_STAR: case OP_DO: for (vars = cadr(expr); is_pair(vars); vars = cdr(vars)) { s7_pointer var; var = caar(vars); if ((direct_memq(var, var_list)) || (direct_memq(var, steppers))) return(false); var_list = cons(sc, var, var_list); sc->x = var_list; if ((is_pair(cdar(vars))) && (!do_is_safe(sc, cdar(vars), steppers, var_list, has_set))) { sc->x = sc->NIL; return(false); } sc->x = sc->NIL; } if (op == OP_DO) { /* set_unsafe_do(cdr(expr)); */ if (!do_is_safe(sc, (op == OP_DO) ? cdddr(expr) : cddr(expr), steppers, var_list, has_set)) return(false); } else { if (!do_is_safe(sc, cddr(expr), steppers, var_list, has_set)) return(false); } break; case OP_SET: { s7_pointer settee; settee = cadr(expr); if (!is_symbol(settee)) /* (set! (...) ...) which is tricky due to setter functions/macros */ { s7_pointer setv; if ((!is_pair(settee)) || (!is_symbol(car(settee)))) return(false); setv = find_symbol_unchecked(sc, car(settee)); if (!((setv) && ((is_sequence(setv)) || ((is_c_function(setv)) && (is_safe_procedure(c_function_setter(setv))))))) return(false); (*has_set) = true; } else { if ((is_pair(cadr(sc->code))) && (is_pair(caadr(sc->code)))) { bool res; set_match_symbol(settee); res = tree_match(sc, caadr(sc->code)); /* (set! end ...) in some fashion */ clear_match_symbol(settee); if (res) return(false); } if (!direct_memq(cadr(expr), var_list)) /* is some non-local variable being set? */ (*has_set) = true; } if (!do_is_safe(sc, cddr(expr), steppers, var_list, has_set)) return(false); if (!safe_stepper(sc, expr, steppers)) /* is step var's value used as the stored value by set!? */ return(false); } break; case OP_IF: case OP_WHEN: case OP_UNLESS: case OP_COND: case OP_CASE: case OP_AND: case OP_OR: case OP_BEGIN: if (!do_is_safe(sc, cdr(expr), steppers, var_list, has_set)) return(false); break; case OP_WITH_LET: return(true); default: return(false); } } else { if ((!is_optimized(expr)) || (is_unsafe(expr)) || (!do_is_safe(sc, cdr(expr), steppers, var_list, has_set))) /* this is unreasonably retrictive because optimize_expression returns "unsafe" * even when everything is safe -- it's merely saying it could not find a * special optimization case for the expression. */ return(false); else { if (is_setter(x)) /* "setter" includes stuff like cons and vector -- x is a symbol */ { /* (hash-table-set! ht i 0) -- caddr is being saved, so this is not safe * similarly (vector-set! v 0 i) etc */ if (!direct_memq(cadr(expr), var_list)) /* non-local is being changed */ { if ((direct_memq(cadr(expr), steppers)) || /* stepper is being set? */ (!is_pair(cddr(expr))) || (!is_pair(cdddr(expr))) || (is_pair(cddddr(expr))) || ((x == sc->HASH_TABLE_SET) && (is_symbol(caddr(expr))) && (direct_memq(caddr(expr), steppers))) || ((is_symbol(cadddr(expr))) && (direct_memq(cadddr(expr), steppers))) || (is_pair(cadddr(expr)))) (*has_set) = true; } if (!do_is_safe(sc, cddr(expr), steppers, var_list, has_set)) return(false); if (!safe_stepper(sc, expr, steppers)) return(false); } } } } else { return(false); /* car(expr) ("x") is not a symbol: ((mus-data loc) chan) for example * but that's actually safe since it's just in effect vector-ref * there are several examples in dlocsig: ((group-speakers group) i) etc */ } } } return(true); } static bool preserves_type(s7_scheme *sc, unsigned int x) { return((x == sc->add_class) || (x == sc->subtract_class) || (x == sc->multiply_class)); } static s7_pointer check_do(s7_scheme *sc) { s7_pointer x; /* fprintf(stderr, "check_do: %s\n", DISPLAY(sc->code)); */ if ((!is_pair(sc->code)) || /* (do . 1) */ ((!is_pair(car(sc->code))) && /* (do 123) */ (is_not_null(car(sc->code))))) /* (do () ...) is ok */ eval_error(sc, "do: var list is not a list: ~S", sc->code); if (!is_pair(cdr(sc->code))) /* (do () . 1) */ eval_error(sc, "do body is messed up: ~A", sc->code); if ((!is_pair(cadr(sc->code))) && /* (do ((i 0)) 123) */ (is_not_null(cadr(sc->code)))) /* no end-test? */ eval_error(sc, "do: end-test and end-value list is not a list: ~A", sc->code); if (is_pair(car(sc->code))) { for (x = car(sc->code); is_pair(x); x = cdr(x)) { if (!(is_pair(car(x)))) /* (do (4) (= 3)) */ eval_error(sc, "do: variable name missing? ~A", sc->code); if (!is_symbol(caar(x))) /* (do ((3 2)) ()) */ eval_error(sc, "do step variable: ~S is not a symbol?", x); if (is_immutable_symbol(caar(x))) /* (do ((pi 3 (+ pi 1))) ((= pi 4)) pi) */ eval_error(sc, "do step variable: ~S is immutable", x); if (is_pair(cdar(x))) { if ((!is_pair(cddar(x))) && (is_not_null(cddar(x)))) /* (do ((i 0 . 1)) ...) */ eval_error(sc, "do: step variable info is an improper list?: ~A", sc->code); if ((is_pair(cddar(x))) && (is_not_null(cdr(cddar(x))))) /* (do ((i 0 1 (+ i 1))) ...) */ eval_error(sc, "do: step variable info has extra stuff after the increment: ~A", sc->code); } else eval_error(sc, "do: step variable has no initial value: ~A", x); set_local(caar(x)); /* (do ((i)) ...) */ } if (is_not_null(x)) /* (do ((i 0 i) . 1) ((= i 1))) */ eval_error(sc, "do: list of variables is improper: ~A", sc->code); } if (is_pair(cadr(sc->code))) { for (x = cadr(sc->code); is_pair(x); x = cdr(x)); if (is_not_null(x)) eval_error(sc, "stray dot in do end section? ~A", sc->code); } for (x = cddr(sc->code); is_pair(x); x = cdr(x)); if (is_not_null(x)) eval_error(sc, "stray dot in do body? ~A", sc->code); if ((is_overlaid(sc->code)) && (has_opt_back(sc->code))) { s7_pointer vars, end, body; bool one_line; vars = car(sc->code); end = cadr(sc->code); body = cddr(sc->code); one_line = ((safe_list_length(sc, body) == 1) && (is_pair(car(body)))); pair_set_syntax_symbol(sc->code, sc->DO_UNCHECKED); /* (define (hi) (do ((i 0 (+ i 1))) ((= i 3)) (display i)) (newline)) */ /* (define (hi) (do ((i 1.5 (+ i 1))) ((= i 2.5)) (display i) (newline))) * in OP_SAFE_DOTIMES, for example, if init value is not an integer, it goes to OP_SIMPLE_DO * remaining optimizable cases: we can step by 1 and use = for end, and yet simple_do(_p) calls the functions * geq happens as often as =, and -1 as step * also cdr as step to is_null as end * also what about no do-var cases? (do () ...) * * also do body is optimized expr: vector_set_3 via hop_safe_c_sss for example or (vset v i (vref w i)) */ if ((is_pair(end)) && (is_pair(car(end))) && (is_pair(vars)) && (is_null(cdr(vars))) && (is_pair(body))) { /* loop has one step variable, and normal-looking end test */ vars = car(vars); if ((safe_list_length(sc, vars) == 3) && ((!is_pair(cadr(vars))) || (is_h_safe_c_c(cadr(vars))))) { s7_pointer step_expr; step_expr = caddr(vars); if ((is_optimized(step_expr)) && (((optimize_op(step_expr) == HOP_SAFE_C_SC) && (car(vars) == cadr(step_expr))) || ((optimize_op(step_expr) == HOP_SAFE_C_C) && (car(vars) == cadr(step_expr)) && ((opt_cfunc(step_expr) == add_cs1) || (opt_cfunc(step_expr) == subtract_cs1))) || ((optimize_op(step_expr) == HOP_SAFE_C_CS) && (car(vars) == caddr(step_expr))))) { /* step var is (var const|symbol (op var const)|(op const var)) */ end = car(end); if ((is_optimized(end)) && (car(vars) == cadr(end)) && (cadr(end) != caddr(end)) && ((opt_any1(end) == equal_s_ic) || (optimize_op(end) == HOP_SAFE_C_SS) || (optimize_op(end) == HOP_SAFE_C_SC))) { /* end var is (op var const|symbol) using same var as step * so at least we can use SIMPLE_DO */ bool has_set = false; if (opt_cfunc(step_expr) == add_cs1) { set_c_function(step_expr, add_s1); set_optimize_op(step_expr, HOP_SAFE_C_SC); } if (opt_cfunc(step_expr) == subtract_cs1) { set_c_function(step_expr, subtract_s1); set_optimize_op(step_expr, HOP_SAFE_C_SC); } if (opt_cfunc(end) == equal_s_ic) { set_c_function(end, equal_2); set_optimize_op(end, HOP_SAFE_C_SC); } if ((opt_cfunc(step_expr) == add_s1) && (opt_cfunc(end) == equal_2) && (s7_is_integer(caddr(step_expr))) && (s7_integer(caddr(step_expr)) == 1)) { pair_set_syntax_symbol(sc->code, sc->SIMPLE_DO_A); if ((one_line) && (is_optimized(car(body)))) pair_set_syntax_symbol(sc->code, sc->SIMPLE_DO_E); } else pair_set_syntax_symbol(sc->code, sc->SIMPLE_DO); if ((one_line) && ((!is_optimized(car(body))) || (op_no_hop(car(body)) != OP_SAFE_C_C)) && (is_syntactic_symbol(caar(body)))) { pair_set_syntax_op(car(body), symbol_syntax_op(caar(body))); pair_set_syntax_symbol(sc->code, sc->SIMPLE_DO_P); set_opt_pair2(sc->code, caddr(caar(sc->code))); if ((s7_is_integer(caddr(step_expr))) && (s7_integer(caddr(step_expr)) == 1) && (c_function_class(opt_cfunc(step_expr)) == sc->add_class) && /* we check above that (car(vars) == cadr(step_expr)) * and that (car(vars) == cadr(end)) */ ((c_function_class(opt_cfunc(end)) == sc->equal_class) || (opt_cfunc(end) == geq_2))) pair_set_syntax_symbol(sc->code, sc->DOTIMES_P); } if (do_is_safe(sc, body, sc->w = list_1(sc, car(vars)), sc->NIL, &has_set)) { /* now look for the very common dotimes case */ if ((((s7_is_integer(caddr(step_expr))) && (s7_integer(caddr(step_expr)) == 1)) || ((s7_is_integer(cadr(step_expr))) && (s7_integer(cadr(step_expr)) == 1))) && (c_function_class(opt_cfunc(step_expr)) == sc->add_class) && ((c_function_class(opt_cfunc(end)) == sc->equal_class) || (opt_cfunc(end) == geq_2)) ) { /* we're stepping by +1 and going to = * the final integer check has to wait until run time (symbol value dependent) */ pair_set_syntax_symbol(sc->code, sc->SAFE_DO); if ((!has_set) && (c_function_class(opt_cfunc(end)) == sc->equal_class)) pair_set_syntax_symbol(sc->code, sc->SAFE_DOTIMES); } } return(sc->NIL); } } } } /* we get here if there is more than one local var or anything "non-simple" about the rest */ /* (define (hi) (do ((i 0 (+ i 1))) ((= i 3)) (display i)) (newline)) * (define (hi) (do ((i 0 (+ i 1)) (j 1 (+ j 1))) ((= i 3)) (display j))(newline)) */ vars = car(sc->code); end = cadr(sc->code); /* check end expression first */ if ((is_pair(car(end))) && (caar(end) != sc->QUOTE) && (is_optimized(car(end))) && (is_all_x_safe(sc, car(end)))) set_c_call(cdr(sc->code), all_x_eval(sc, car(end), sc->envir, let_symbol_is_safe)); else return(sc->code); /* vars can be nil (no steppers) */ if (is_pair(vars)) { s7_pointer p; for (p = vars; is_pair(p); p = cdr(p)) { s7_pointer var; var = car(p); if ((!is_all_x_safe(sc, cadr(var))) || ((is_pair(cddr(var))) && (!is_all_x_safe(sc, caddr(var))))) { s7_pointer q; for (q = vars; q != p; q = cdr(q)) clear_match_symbol(caar(q)); return(sc->code); } set_match_symbol(car(var)); } /* we want to use the pending_value slot for other purposes, so make sure * the current val is not referred to in any trailing step exprs. The inits * are ok because at init-time, the new frame is not connected. * another tricky case: current var might be used in previous step expr(!) */ for (p = vars; is_pair(p); p = cdr(p)) { s7_pointer var, val; var = car(p); val = cddr(var); if (is_pair(val)) { var = car(var); clear_match_symbol(var); /* ignore current var */ if (tree_match(sc, car(val))) { s7_pointer q; for (q = vars; is_pair(q); q = cdr(q)) clear_match_symbol(caar(q)); return(sc->code); } set_match_symbol(var); } } for (p = vars; is_pair(p); p = cdr(p)) clear_match_symbol(caar(p)); } /* end and steps look ok! */ pair_set_syntax_symbol(sc->code, sc->DOX); set_opt_pair2(sc->code, car(end)); /* end expr */ /* each step expr is safe so not an explicit set! * the symbol_is_safe check in all_x_eval needs to see the do envir, not the caller's * but that means the is_all_x_safe check above also needs to use the local env? */ if (is_pair(vars)) { s7_pointer p; for (p = vars; is_pair(p); p = cdr(p)) { s7_pointer var; var = car(p); if (is_pair(cdr(var))) set_c_call(cdr(var), all_x_eval(sc, cadr(var), sc->envir, let_symbol_is_safe)); /* init val */ if (is_pair(cddr(var))) { s7_pointer step_expr; step_expr = caddr(var); set_c_call(cddr(var), all_x_eval(sc, step_expr, vars, do_symbol_is_safe)); /* sets opt2(cddr(var)), not opt1 */ if ((is_pair(step_expr)) && (car(step_expr) != sc->QUOTE) && /* opt_cfunc(==opt1) might not be set in this case (sigh) */ (preserves_type(sc, c_function_class(opt_cfunc(step_expr))))) set_safe_stepper(cddr(var)); } } } /* there are only a couple of cases in snd-test where a multi-statement do body is completely all-x-able */ return(sc->NIL); } return(sc->code); } static bool dox_pf_ok(s7_scheme *sc, s7_pointer code, s7_pointer scc, s7_function endf, bool all_pairs) { s7_pointer p, endp; int body_len, i; s7_pf_t pf; endp = caadr(scc); body_len = s7_list_length(sc, code); s7_xf_new(sc, sc->envir); for (i = 0, p = code; is_pair(p); i++, p = cdr(p)) if ((!is_symbol(caar(p))) || (!xf_opt(sc, car(p)))) break; if ((is_null(p)) && (pf = xf_opt(sc, endp))) { s7_pointer slots; s7_pointer *top; slots = let_slots(sc->envir); top = sc->cur_rf->data; if ((all_pairs) && (body_len == 1)) { s7_rf_t rf; rf = (s7_rf_t)(*top); top++; while (true) { s7_pointer slot; s7_pointer *temp; s7_pointer **rp; temp = top; rp = &temp; rf(sc, rp); for (slot = slots; is_slot(slot); slot = next_slot(slot)) if (is_pair(slot_expression(slot))) slot_pending_value(slot) = c_call(slot_expression(slot))(sc, car(slot_expression(slot))); for (slot = slots; is_slot(slot); slot = next_slot(slot)) if (is_pair(slot_expression(slot))) slot_set_value(slot, slot_pending_value(slot)); (*rp)++; if (is_true(sc, pf(sc, rp))) { s7_xf_free(sc); sc->code = cdadr(scc); return(true); } } } else { while (true) { s7_pointer slot; s7_pointer *temp; s7_pointer **rp; temp = top; rp = &temp; for (i = 0; i < body_len; i++) { s7_rf_t rf; rf = (s7_rf_t)(**rp); (*rp)++; rf(sc, rp); } for (slot = slots; is_slot(slot); slot = next_slot(slot)) if (is_pair(slot_expression(slot))) slot_pending_value(slot) = c_call(slot_expression(slot))(sc, car(slot_expression(slot))); for (slot = slots; is_slot(slot); slot = next_slot(slot)) if (is_pair(slot_expression(slot))) slot_set_value(slot, slot_pending_value(slot)); (*rp)++; if (is_true(sc, pf(sc, rp))) { s7_xf_free(sc); sc->code = cdadr(scc); return(true); } } } } s7_xf_free(sc); return(false); } static int dox_ex(s7_scheme *sc) { /* any number of steppers using dox exprs, end also dox, body and end result arbitrary. * since all these exprs are local, we don't need to jump until the body */ long long int id; s7_pointer frame, vars, slot, code; s7_function endf; bool all_pairs = true; /* fprintf(stderr, "%s: %s\n", __func__, DISPLAY(sc->code)); */ new_frame(sc, sc->envir, frame); /* new frame is not tied into the symbol lookup process yet */ for (vars = car(sc->code); is_pair(vars); vars = cdr(vars)) { s7_pointer expr, val; expr = cadar(vars); if (is_pair(expr)) { if (car(expr) == sc->QUOTE) val = cadr(expr); else val = c_call(cdar(vars))(sc, expr); } else { if (is_symbol(expr)) val = find_symbol_checked(sc, expr); else val = expr; } new_cell_no_check(sc, slot, T_SLOT); slot_set_symbol(slot, caar(vars)); slot_set_value(slot, val); set_stepper(slot); slot_expression(slot) = cddar(vars); if (is_pair(slot_expression(slot))) { if (is_safe_stepper(slot_expression(slot))) { s7_pointer step_expr; step_expr = car(slot_expression(slot)); if ((is_pair(cddr(step_expr))) && (type(val) == type(caddr(step_expr)))) set_safe_stepper(slot); } } else all_pairs = false; next_slot(slot) = let_slots(frame); let_set_slots(frame, slot); } sc->envir = frame; id = let_id(frame); for (slot = let_slots(frame); is_slot(slot); slot = next_slot(slot)) symbol_set_local(slot_symbol(slot), id, slot); if (is_true(sc, c_call(cdr(sc->code))(sc, opt_pair2(sc->code)))) { /* if no end result exprs, we return nil, but others probably # * (let ((x (do ((i 0 (+ i 1))) (#t)))) x) -> () */ sc->code = cdadr(sc->code); return(goto_DO_END_CLAUSES); } code = cddr(sc->code); endf = c_callee(cdr(sc->code)); if (is_null(code)) /* no body? */ { s7_pointer endp, slots, scc; scc = sc->code; endp = opt_pair2(sc->code); if (endf == all_x_c_c) { endf = c_callee(endp); endp = cdr(endp); } slots = let_slots(sc->envir); if (!is_slot(slots)) { while (!is_true(sc, endf(sc, endp))); sc->code = cdadr(scc); return(goto_DO_END_CLAUSES); } if ((is_null(next_slot(slots))) && (is_pair(slot_expression(slots)))) { s7_function f; s7_pointer a; f = c_callee(slot_expression(slots)); a = car(slot_expression(slots)); if (f == all_x_c_c) { f = c_callee(a); a = cdr(a); } while (true) /* thash titer */ { slot_set_value(slots, f(sc, a)); if (is_true(sc, endf(sc, endp))) { sc->code = cdadr(scc); return(goto_DO_END_CLAUSES); } } } else { while (true) { s7_pointer slt; for (slt = slots; is_slot(slt); slt = next_slot(slt)) if (is_pair(slot_expression(slt))) slot_set_value(slt, c_call(slot_expression(slt))(sc, car(slot_expression(slt)))); if (is_true(sc, endf(sc, endp))) { sc->code = cdadr(scc); return(goto_DO_END_CLAUSES); } } } } if ((!is_unsafe_do(sc->code)) && (dox_pf_ok(sc, code, sc->code, endf, all_pairs))) return(goto_DO_END_CLAUSES); /* fprintf(stderr, "dox: %s\n", DISPLAY(code)); */ set_unsafe_do(sc->code); if ((is_null(cdr(code))) && /* one expr */ (is_pair(car(code)))) { code = car(code); if ((typesflag(code) == SYNTACTIC_PAIR) || (typesflag(car(code)) == SYNTACTIC_TYPE)) { push_stack_no_args(sc, OP_DOX_STEP_P, sc->code); if (typesflag(code) == SYNTACTIC_PAIR) sc->op = (opcode_t)pair_syntax_op(code); else { sc->op = (opcode_t)symbol_syntax_op(car(code)); pair_set_syntax_op(code, sc->op); set_type(code, SYNTACTIC_PAIR); } sc->code = cdr(code); return(goto_START_WITHOUT_POP_STACK); } } return(fall_through); } static int simple_do_ex(s7_scheme *sc, s7_pointer code) { s7_pointer body, step_expr, step_var, ctr, end; s7_function stepf, endf; s7_pf_t rf; /* fprintf(stderr, "%s: %s\n", __func__, DISPLAY(sc->code)); */ body = car(opt_pair2(code)); if (!is_symbol(car(body))) return(fall_through); step_expr = caddr(caar(code)); stepf = c_callee(step_expr); endf = c_callee(caadr(code)); ctr = dox_slot1(sc->envir); end = dox_slot2(sc->envir); step_var = caddr(step_expr); #if (!WITH_GMP) set_stepper(ctr); if (((stepf == g_subtract_s1) && (endf == g_less_s0)) || ((stepf == g_add_s1) && (endf == g_equal_2))) /* add_s1 means (+ sym 1) */ set_safe_stepper(ctr); #endif s7_xf_new(sc, sc->envir); rf = xf_opt(sc, body); if (rf) { s7_pointer *top; /* fprintf(stderr, "ex: %s\n", DISPLAY(code)); */ top = sc->cur_rf->data; top++; #if (!WITH_GMP) if ((stepf == g_add_s1) && (endf == g_equal_2)) { while (true) { s7_pointer *temp; temp = top; rf(sc, &temp); slot_set_value(ctr, c_add_s1(sc, slot_value(ctr))); if (is_true(sc, c_equal_2(sc, slot_value(ctr), slot_value(end)))) { s7_xf_free(sc); sc->code = cdr(cadr(code)); return(goto_DO_END_CLAUSES); } } } #endif while (true) { s7_pointer *temp; temp = top; rf(sc, &temp); car(sc->T2_1) = slot_value(ctr); car(sc->T2_2) = step_var; slot_set_value(ctr, stepf(sc, sc->T2_1)); car(sc->T2_1) = slot_value(ctr); car(sc->T2_2) = slot_value(end); if (is_true(sc, endf(sc, sc->T2_1))) { s7_xf_free(sc); sc->code = cdr(cadr(code)); return(goto_DO_END_CLAUSES); } } } s7_xf_free(sc); return(fall_through); } static bool pf_ok(s7_scheme *sc, s7_pointer code, s7_pointer scc, bool safe_step) { s7_pointer p; int body_len, i; if (safe_step) set_safe_stepper(sc->args); else set_safe_stepper(dox_slot1(sc->envir)); body_len = s7_list_length(sc, code); s7_xf_new(sc, sc->envir); for (i = 0, p = code; is_pair(p); i++, p = cdr(p)) if (!xf_opt(sc, car(p))) break; if (is_null(p)) { s7_pointer stepper; s7_pointer *top; s7_int end; stepper = slot_value(sc->args); end = denominator(stepper); top = sc->cur_rf->data; if (safe_step) { if (body_len == 1) { s7_int end4; s7_rf_t rf; rf = (s7_rf_t)(*top); top++; end4 = end - 4; for (; numerator(stepper) < end4; numerator(stepper)++) { s7_pointer *rp; rp = top; rf(sc, &rp); numerator(stepper)++; rp = top; rf(sc, &rp); numerator(stepper)++; rp = top; rf(sc, &rp); numerator(stepper)++; rp = top; rf(sc, &rp); } for (; numerator(stepper) < end; numerator(stepper)++) { s7_pointer *rp; rp = top; rf(sc, &rp); } } else { for (; numerator(stepper) < end; numerator(stepper)++) { s7_pointer *temp; s7_pointer **rp; temp = top; rp = &temp; for (i = 0; i < body_len; i++) { s7_rf_t rf; rf = (s7_rf_t)(**rp); (*rp)++; rf(sc, rp); } } } } else { /* can't re-use the stepper value directly */ s7_pointer step_slot, end_slot; s7_int step; step_slot = dox_slot1(sc->envir); end_slot = dox_slot2(sc->envir); if (body_len == 1) { s7_rf_t rf; rf = (s7_rf_t)(*top); top++; while (true) { s7_pointer *rp; rp = top; rf(sc, &rp); step = s7_integer(slot_value(step_slot)) + 1; slot_set_value(step_slot, make_integer(sc, step)); if (step == s7_integer(slot_value(end_slot))) break; } } else { while (true) { s7_pointer *temp; s7_pointer **rp; temp = top; rp = &temp; for (i = 0; i < body_len; i++) { s7_rf_t rf; rf = (s7_rf_t)(**rp); (*rp)++; rf(sc, rp); } step = s7_integer(slot_value(step_slot)) + 1; slot_set_value(step_slot, make_integer(sc, step)); if (step == s7_integer(slot_value(end_slot))) break; } } } s7_xf_free(sc); sc->code = cdadr(scc); return(true); } s7_xf_free(sc); return(false); } static int let_pf_ok(s7_scheme *sc, s7_pointer step_slot, s7_pointer scc, bool safe_case) { s7_pointer let_body, p = NULL, let_vars, let_code; bool let_star; int body_len; s7_rf_t varf = NULL; s7_pointer old_e, stepper; int var_len; /* fprintf(stderr, "%lld %lld %s %d\n", numerator(step_slot), denominator(step_slot), DISPLAY(scc), safe_case); */ let_code = caddr(scc); let_body = cddr(let_code); body_len = s7_list_length(sc, let_body); let_star = (symbol_syntax_op(car(let_code)) == OP_LET_STAR); let_vars = cadr(let_code); set_safe_stepper(step_slot); stepper = slot_value(step_slot); old_e = sc->envir; sc->envir = new_frame_in_env(sc, sc->envir); s7_xf_new(sc, old_e); for (var_len = 0, p = let_vars; (is_pair(p)) && (is_pair(cadar(p))); var_len++, p = cdr(p)) { s7_int var_loc; s7_pointer expr, fcar, car_ex; s7_rp_t varp; var_loc = s7_xf_store(sc, NULL); expr = cadar(p); car_ex = car(expr); /* fcar = find_symbol_checked(sc, car(expr)); */ if (!is_symbol(car_ex)) break; fcar = find_symbol(sc, car_ex); if (!is_slot(fcar)) break; fcar = slot_value(fcar); varp = rf_function(fcar); if (!varp) break; varf = varp(sc, expr); if (!varf) break; s7_xf_store_at(sc, var_loc, (s7_pointer)varf); if (let_star) make_slot_1(sc, sc->envir, caar(p), s7_make_mutable_real(sc, 1.5)); } if (is_null(p)) { int i; s7_pf_t bodyf = NULL; if (!let_star) for (p = let_vars; is_pair(p); p = cdr(p)) make_slot_1(sc, sc->envir, caar(p), s7_make_mutable_real(sc, 1.5)); for (i = 0, p = let_body; is_pair(p); i++, p = cdr(p)) { bodyf = xf_opt(sc, car(p)); if (!bodyf) break; } if (is_null(p)) { s7_pointer *top; s7_int end; if (safe_case) { end = denominator(stepper); top = sc->cur_rf->data; if ((var_len == 1) && (body_len == 1)) /* very common special case */ { s7_pointer rl; s7_int end3; s7_pointer **rp; s7_pointer *temp; end3 = end - 3; rl = slot_value(let_slots(sc->envir)); top++; for (; numerator(stepper) < end3; numerator(stepper)++) { temp = top; rp = &temp; set_real(rl, varf(sc, rp)); (*rp)++; bodyf(sc, rp); numerator(stepper)++; temp = top; rp = &temp; set_real(rl, varf(sc, rp)); (*rp)++; bodyf(sc, rp); numerator(stepper)++; temp = top; rp = &temp; set_real(rl, varf(sc, rp)); (*rp)++; bodyf(sc, rp); } for (; numerator(stepper) < end; numerator(stepper)++) { temp = top; rp = &temp; set_real(rl, varf(sc, rp)); (*rp)++; bodyf(sc, rp); } } else { let_set_slots(sc->envir, reverse_slots(sc, let_slots(sc->envir))); for (; numerator(stepper) < end; numerator(stepper)++) { s7_pointer **rp; s7_pointer *temp; temp = top; rp = &temp; for (p = let_slots(sc->envir); is_slot(p); p = next_slot(p)) { s7_rf_t r1; r1 = (s7_rf_t)(**rp); (*rp)++; set_real(slot_value(p), r1(sc, rp)); } for (i = 0; i < body_len; i++) { s7_pf_t pf; pf = (s7_pf_t)(**rp); (*rp)++; pf(sc, rp); } } } } else { end = denominator(stepper); top = sc->cur_rf->data; if ((var_len == 1) && (body_len == 1)) /* very common special case */ { s7_pointer rl; s7_int k; rl = slot_value(let_slots(sc->envir)); top++; for (k = numerator(stepper); k < end; k++) { s7_pointer **rp; s7_pointer *temp; slot_set_value(step_slot, make_integer(sc, k)); temp = top; rp = &temp; set_real(rl, varf(sc, rp)); (*rp)++; bodyf(sc, rp); } } else { s7_int k; let_set_slots(sc->envir, reverse_slots(sc, let_slots(sc->envir))); for (k = numerator(stepper); k < end; k++) { s7_pointer **rp; s7_pointer *temp; slot_set_value(step_slot, make_integer(sc, k)); temp = top; rp = &temp; for (p = let_slots(sc->envir); is_slot(p); p = next_slot(p)) { s7_rf_t r1; r1 = (s7_rf_t)(**rp); (*rp)++; set_real(slot_value(p), r1(sc, rp)); } for (i = 0; i < body_len; i++) { s7_pf_t pf; pf = (s7_pf_t)(**rp); (*rp)++; pf(sc, rp); } } } } s7_xf_free(sc); sc->code = cdr(cadr(scc)); return(goto_SAFE_DO_END_CLAUSES); } } sc->envir = old_e; s7_xf_free(sc); return(fall_through); } static int safe_dotimes_ex(s7_scheme *sc) { s7_pointer init_val; /* fprintf(stderr, "%s: %s\n", __func__, DISPLAY(sc->code)); */ init_val = cadr(caar(sc->code)); if (is_symbol(init_val)) init_val = find_symbol_checked(sc, init_val); else { if (is_pair(init_val)) init_val = c_call(init_val)(sc, cdr(init_val)); } if (s7_is_integer(init_val)) { s7_pointer end_expr, end_val, code; code = sc->code; end_expr = caadr(code); end_val = caddr(end_expr); if (is_symbol(end_val)) end_val = find_symbol_checked(sc, end_val); if (s7_is_integer(end_val)) { sc->code = cddr(code); sc->envir = new_frame_in_env(sc, sc->envir); sc->args = make_slot_1(sc, sc->envir, caaar(code), make_mutable_integer(sc, s7_integer(init_val))); denominator(slot_value(sc->args)) = s7_integer(end_val); set_stepper(sc->args); /* (define (hi) (do ((i 1 (+ 1 i))) ((= i 1) i))) -- we need the frame even if the loop is not evaluated */ if ((is_null(sc->code)) || ((!is_pair(car(sc->code))) && (is_null(cdr(sc->code))))) { numerator(slot_value(sc->args)) = s7_integer(end_val); sc->code = cdr(cadr(code)); return(goto_SAFE_DO_END_CLAUSES); } if (s7_integer(init_val) == s7_integer(end_val)) { sc->code = cdr(cadr(code)); return(goto_SAFE_DO_END_CLAUSES); } if ((is_null(cdr(sc->code))) && (is_pair(car(sc->code)))) { sc->code = car(sc->code); set_opt_pair2(code, sc->code); /* is_pair above */ if ((typesflag(sc->code) == SYNTACTIC_PAIR) || (typesflag(car(sc->code)) == SYNTACTIC_TYPE)) { if (!is_unsafe_do(code)) { if ((symbol_syntax_op(car(sc->code)) == OP_LET) || (symbol_syntax_op(car(sc->code)) == OP_LET_STAR)) { if (let_pf_ok(sc, sc->args, code, true) == goto_SAFE_DO_END_CLAUSES) return(goto_SAFE_DO_END_CLAUSES); } else { if (pf_ok(sc, cddr(code), code, true)) return(goto_SAFE_DO_END_CLAUSES); } set_unsafe_do(code); } push_stack(sc, OP_SAFE_DOTIMES_STEP_P, sc->args, code); if (typesflag(sc->code) == SYNTACTIC_PAIR) sc->op = (opcode_t)pair_syntax_op(sc->code); else { sc->op = (opcode_t)symbol_syntax_op(car(sc->code)); pair_set_syntax_op(sc->code, sc->op); set_type(sc->code, SYNTACTIC_PAIR); } sc->code = cdr(sc->code); return(goto_START_WITHOUT_POP_STACK); } else /* car not syntactic? */ { if ((!is_unsafe_do(code)) && (pf_ok(sc, cddr(code), code, true))) return(goto_SAFE_DO_END_CLAUSES); set_unsafe_do(code); #if DEBUGGING if (!is_optimized(sc->code)) fprintf(stderr, "%s[%d]: not opt: %s\n", __func__, __LINE__, DISPLAY(sc->code)); #endif if (is_optimized(sc->code)) /* think this is not needed -- can we get here otherwise? */ { push_stack(sc, OP_SAFE_DOTIMES_STEP_O, sc->args, code); return(goto_OPT_EVAL); } } /* impossible? but make sure in any case we're set up for begin */ sc->code = cddr(code); } /* multi-line body */ if ((!is_unsafe_do(code)) && (pf_ok(sc, sc->code, code, true))) return(goto_SAFE_DO_END_CLAUSES); set_unsafe_do(code); set_opt_pair2(code, sc->code); push_stack(sc, OP_SAFE_DOTIMES_STEP, sc->args, code); return(goto_BEGIN1); } } return(fall_through); } static int safe_do_ex(s7_scheme *sc) { /* body is safe, step = +1, end is =, but stepper and end might be set (or at least indirectly exported) in the body: * (let ((lst ())) (do ((i 0 (+ i 1))) ((= i 10)) (let ((j (min i 100))) (set! lst (cons j lst)))) lst) * however, we're very restrictive about this in check_do and do_is_safe; even this is considered trouble: * (let ((x 0)) (do ((i i (+ i 1))) ((= i 7)) (set! x (+ x i))) x) * but end might not be an integer -- need to catch this earlier. */ s7_pointer end, init_val, end_val, code; /* fprintf(stderr, "%s: %s\n", __func__, DISPLAY(sc->code)); */ code = sc->code; init_val = cadaar(code); if (is_symbol(init_val)) init_val = find_symbol_checked(sc, init_val); else { if (is_pair(init_val)) init_val = c_call(init_val)(sc, cdr(init_val)); } end = caddr(car(cadr(code))); if (is_symbol(end)) end_val = find_symbol_checked(sc, end); else end_val = end; if ((!s7_is_integer(init_val)) || (!s7_is_integer(end_val))) { pair_set_syntax_symbol(sc->code, sc->DO_UNCHECKED); return(goto_DO_UNCHECKED); } /* (let ((sum 0)) (define (hi) (do ((i 10 (+ i 1))) ((= i 10) i) (set! sum (+ sum i)))) (hi)) */ sc->envir = new_frame_in_env(sc, sc->envir); dox_set_slot1(sc->envir, make_slot_1(sc, sc->envir, caaar(code), init_val)); /* define the step var -- might be needed in the end clauses */ if ((s7_integer(init_val) == s7_integer(end_val)) || ((s7_integer(init_val) > s7_integer(end_val)) && (opt_cfunc(car(cadr(code))) == geq_2))) { sc->code = cdr(cadr(code)); return(goto_SAFE_DO_END_CLAUSES); } if (is_symbol(end)) sc->args = find_symbol(sc, end); else sc->args = make_slot(sc, sc->dox_slot_symbol, end); /* here and elsewhere sc->args is used for GC protection */ dox_set_slot2(sc->envir, sc->args); if ((!is_unsafe_do(sc->code)) && ((!is_optimized(caadr(code))) || (opt_cfunc(caadr(code)) != geq_2))) { set_stepper(dox_slot1(sc->envir)); if (pf_ok(sc, cddr(sc->code), sc->code, false)) return(goto_SAFE_DO_END_CLAUSES); set_unsafe_do(sc->code); } sc->code = cddr(code); if (is_unsafe_do(sc->code)) /* we've seen this loop before and it's not optimizable */ { set_opt_pair2(code, sc->code); push_stack(sc, OP_SAFE_DO_STEP, sc->args, code); return(goto_BEGIN1); } set_unsafe_do(sc->code); set_opt_pair2(code, sc->code); push_stack(sc, OP_SAFE_DO_STEP, sc->args, code); return(goto_BEGIN1); } static int dotimes_p_ex(s7_scheme *sc) { s7_pointer init, end, code, init_val, end_val; /* (do ... (set! args ...)) -- one line, syntactic */ /* if (!is_unsafe_do(sc->code)) fprintf(stderr, "%s: %s\n", __func__, DISPLAY(sc->code)); */ code = sc->code; init = cadaar(code); if (is_symbol(init)) init_val = find_symbol_checked(sc, init); else { if (is_pair(init)) init_val = c_call(init)(sc, cdr(init)); else init_val = init; } sc->value = init_val; set_opt_pair2(code, caadr(code)); end = caddr(opt_pair2(code)); if (is_symbol(end)) sc->args = find_symbol(sc, end); else sc->args = make_slot(sc, sc->dox_slot_symbol, end); end_val = slot_value(sc->args); if ((!s7_is_integer(init_val)) || (!s7_is_integer(end_val))) { pair_set_syntax_symbol(sc->code, sc->DO_UNCHECKED); return(goto_DO_UNCHECKED); } sc->envir = new_frame_in_env(sc, sc->envir); dox_set_slot1(sc->envir, make_slot_1(sc, sc->envir, caaar(code), init_val)); dox_set_slot2(sc->envir, sc->args); car(sc->T2_1) = slot_value(dox_slot1(sc->envir)); car(sc->T2_2) = slot_value(dox_slot2(sc->envir)); if (is_true(sc, c_call(caadr(code))(sc, sc->T2_1))) { sc->code = cdadr(code); return(goto_DO_END_CLAUSES); } if ((!is_unsafe_do(code)) && (opt_cfunc(caadr(code)) != geq_2)) { s7_pointer old_args, old_init, body; body = caddr(code); old_args = sc->args; old_init = slot_value(dox_slot1(sc->envir)); sc->args = dox_slot1(sc->envir); slot_set_value(sc->args, make_mutable_integer(sc, integer(slot_value(dox_slot1(sc->envir))))); denominator(slot_value(sc->args)) = integer(slot_value(dox_slot2(sc->envir))); set_stepper(sc->args); if (((typesflag(body) == SYNTACTIC_PAIR) || (typesflag(car(body)) == SYNTACTIC_TYPE)) && ((symbol_syntax_op(car(body)) == OP_LET) || (symbol_syntax_op(car(body)) == OP_LET_STAR))) { if (let_pf_ok(sc, sc->args, code, false) == goto_SAFE_DO_END_CLAUSES) return(goto_DO_END_CLAUSES); } else { if (pf_ok(sc, cddr(code), code, false)) return(goto_DO_END_CLAUSES); } slot_set_value(sc->args, old_init); sc->args = old_args; set_unsafe_do(code); } push_stack(sc, OP_DOTIMES_STEP_P, sc->args, code); sc->code = caddr(code); return(goto_EVAL); } static int do_init_ex(s7_scheme *sc) { s7_pointer x, y, z; while (true) { sc->args = cons(sc, sc->value, sc->args); /* code will be last element (first after reverse) */ if (is_pair(sc->code)) { /* here sc->code is a list like: ((i 0 (+ i 1)) ...) so cadar gets the init value. */ s7_pointer init; init = cadar(sc->code); if (is_pair(init)) { push_stack(sc, OP_DO_INIT, sc->args, cdr(sc->code)); sc->code = init; return(goto_EVAL); } if (is_symbol(init)) sc->value = find_symbol_checked(sc, init); else sc->value = init; sc->code = cdr(sc->code); } else break; } /* all the initial values are now in the args list */ sc->args = safe_reverse_in_place(sc, sc->args); sc->code = car(sc->args); /* saved at the start */ z = sc->args; sc->args = cdr(sc->args); /* init values */ /* sc->envir = new_frame_in_env(sc, sc->envir); */ /* sc->args was cons'd above, so it should be safe to reuse it as the new frame */ sc->envir = old_frame_in_env(sc, z, sc->envir); /* run through sc->code and sc->args adding '( caar(car(code)) . car(args) ) to sc->envir, * also reuse the value cells as the new frame slots. */ sc->value = sc->NIL; y = sc->args; for (x = car(sc->code); is_not_null(y); x = cdr(x)) { s7_pointer sym, args, val; sym = caar(x); val = car(y); args = cdr(y); set_type(y, T_SLOT); slot_set_symbol(y, sym); slot_set_value(y, val); next_slot(y) = let_slots(sc->envir); let_set_slots(sc->envir, y); symbol_set_local(sym, let_id(sc->envir), y); if (is_not_null(cddar(x))) /* else no incr expr, so ignore it henceforth */ { s7_pointer p; p = cons(sc, caddar(x), val); set_opt_slot1(p, y); /* val is just a place-holder -- this is where we store the new value */ sc->value = cons_unchecked(sc, p, sc->value); } y = args; } sc->args = cons(sc, sc->value = safe_reverse_in_place(sc, sc->value), cadr(sc->code)); sc->code = cddr(sc->code); /* here args is a list of 2 or 3 lists, first is (list (list (var . binding) incr-expr init-value) ...), second is end-expr, third can be result expr * so for (do ((i 0 (+ i 1))) ((= i 3) (+ i 1)) ...) args is ((((i . 0) (+ i 1) 0 #f)) (= i 3) (+ i 1)) */ return(fall_through); } #if (!WITH_GCC) #define closure_is_ok(Sc, Code, Type, Args) (find_symbol_unchecked(Sc, car(Code)) == opt_lambda(Code)) #define closure_star_is_ok(Sc, Code, Type, Args) (find_symbol_unchecked(Sc, car(Code)) == opt_lambda(Code)) #else /* it is almost never the case that we already have the value and can see it in the current environment directly, * but once found, the value usually matches the current (opt_lambda(code)) * * (_val_) is needed below because car(code) might be undefined (with-let can cause this confusion), * and find_symbol_unchecked returns NULL in that case. */ #if 1 /* unlike the c_function_is_ok case, the macro form here is faster?? callgrind and time agree on this. * opt_lambda(_code_) here can (legitimately) be a free cell or almost anything. */ #define closure_is_ok(Sc, Code, Type, Args) \ ({ s7_pointer _code_, _val_; _code_ = Code; _val_ = find_symbol_unchecked(Sc, car(_code_)); \ ((_val_ == opt_any1(_code_)) || \ ((_val_) && (typesflag(_val_) == (unsigned short)Type) && \ ((closure_arity(_val_) == Args) || (closure_arity_to_int(Sc, _val_) == Args)) && \ (set_opt_lambda(_code_, _val_)))); }) #else static bool closure_is_ok(s7_scheme *sc, s7_pointer code, unsigned short type, int args) { s7_pointer f; f = find_symbol_unchecked(sc, car(code)); return ((f == opt_lambda(code)) || ((f) && (typesflag(f) == type) && ((closure_arity(f) == args) || (closure_arity_to_int(sc, f) == args)) && (set_opt_lambda(code, f)))); } #endif #define closure_star_is_ok(Sc, Code, Type, Args) \ ({ s7_pointer _val_; _val_ = find_symbol_unchecked(Sc, car(Code)); \ ((_val_ == opt_any1(Code)) || \ ((_val_) && (typesflag(_val_) == (unsigned short)Type) && \ ((closure_arity(_val_) >= Args) || (closure_star_arity_to_int(Sc, _val_) >= Args)) && \ (set_opt_lambda(Code, _val_)))); }) #endif #define MATCH_UNSAFE_CLOSURE (T_CLOSURE | T_PROCEDURE) #define MATCH_SAFE_CLOSURE (T_CLOSURE | T_PROCEDURE | T_SAFE_CLOSURE) #define MATCH_UNSAFE_CLOSURE_STAR (T_CLOSURE_STAR | T_PROCEDURE) #define MATCH_SAFE_CLOSURE_STAR (T_CLOSURE_STAR | T_PROCEDURE | T_SAFE_CLOSURE) /* since T_HAS_METHODS is on if there might be methods, this can protect us from that case */ /* unknown ops */ static int fixup_unknown_op(s7_scheme *sc, s7_pointer code, s7_pointer func, int op) { /* sc arg used if debugging */ set_optimize_op(code, op); set_opt_lambda(code, func); /* opt_lambda works here because it is the only checked case, but ideally we'd split out all the cases via switch (op) */ return(goto_OPT_EVAL); } static int unknown_ex(s7_scheme *sc, s7_pointer f) { s7_pointer code; code = sc->code; switch (type(f)) { case T_C_OBJECT: if (s7_is_aritable(sc, f, 0)) return(fixup_unknown_op(sc, code, f, OP_C_OBJECT)); break; case T_GOTO: return(fixup_unknown_op(sc, code, f, OP_GOTO)); case T_CLOSURE: if ((!has_methods(f)) && (is_null(closure_args(f)))) { int hop; hop = (is_immutable_symbol(car(code))) ? 1 : 0; if (is_safe_closure(f)) { s7_pointer body; body = closure_body(f); set_optimize_op(code, hop + OP_SAFE_THUNK); if (is_null(cdr(body))) { if (is_optimized(car(body))) set_optimize_op(code, hop + OP_SAFE_THUNK_E); else { if ((is_pair(car(body))) && (is_syntactic_symbol(caar(body)))) { set_optimize_op(code, hop + OP_SAFE_THUNK_P); if (typesflag(car(body)) != SYNTACTIC_PAIR) { pair_set_syntax_op(car(body), symbol_syntax_op(caar(body))); set_type(car(body), SYNTACTIC_PAIR); } } } } set_opt_lambda(code, f); return(goto_OPT_EVAL); } return(fixup_unknown_op(sc, code, f, hop + OP_THUNK)); } /* we can't ignore the recheck here (i.e. set the hop bit) because the closure, even if a global can be set later: * (begin (define *x* #f) (define (test) (display (*x*))) (define (setx n) (set! *x* (lambda () n))) (setx 1) (test) (setx 2) (test)) * this is a case where the name matters (we need a pristine global), so it's easily missed. */ break; case T_CLOSURE_STAR: if ((!has_methods(f)) && (has_simple_args(closure_body(f)))) return(fixup_unknown_op(sc, code, f, ((is_immutable_symbol(car(code))) ? 1 : 0) + ((is_safe_closure(f)) ? OP_SAFE_CLOSURE_STAR : OP_CLOSURE_STAR))); break; default: break; } return(fall_through); } static int unknown_g_ex(s7_scheme *sc, s7_pointer f) { s7_pointer code; bool sym_case; int hop; code = sc->code; hop = (is_immutable_symbol(car(code))) ? 1 : 0; sym_case = is_symbol(cadr(code)); switch (type(f)) { case T_C_FUNCTION: case T_C_FUNCTION_STAR: case T_C_ANY_ARGS_FUNCTION: case T_C_OPT_ARGS_FUNCTION: case T_C_RST_ARGS_FUNCTION: if (s7_is_aritable(sc, f, 1)) { if (sym_case) { set_optimize_op(code, hop + ((is_safe_procedure(f)) ? OP_SAFE_C_S : OP_C_S)); set_c_function(code, f); return(goto_OPT_EVAL); } else { if (is_safe_procedure(f)) { set_optimize_op(code, hop + OP_SAFE_C_C); set_c_function(code, f); return(goto_OPT_EVAL); } } } break; case T_CLOSURE: if ((!has_methods(f)) && (closure_arity_to_int(sc, f) == 1)) { if (sym_case) { set_opt_sym2(code, cadr(code)); if (is_safe_closure(f)) { s7_pointer body; set_optimize_op(code, hop + ((is_global(car(code))) ? OP_SAFE_GLOSURE_S : OP_SAFE_CLOSURE_S)); body = closure_body(f); if (is_null(cdr(body))) { if ((is_optimized(car(body))) && (is_global(car(code)))) set_optimize_op(code, hop + OP_SAFE_GLOSURE_S_E); else { if ((is_pair(car(body))) && (is_syntactic_symbol(caar(body)))) { set_optimize_op(code, hop + OP_SAFE_CLOSURE_S_P); if (typesflag(car(body)) != SYNTACTIC_PAIR) { pair_set_syntax_op(car(body), symbol_syntax_op(caar(body))); set_type(car(body), SYNTACTIC_PAIR); } } } } } else set_optimize_op(code, hop + ((is_global(car(code))) ? OP_GLOSURE_S : OP_CLOSURE_S)); } else { set_optimize_op(code, hop + ((is_safe_closure(f)) ? OP_SAFE_CLOSURE_C : OP_CLOSURE_C)); set_opt_con2(code, cadr(code)); } set_opt_lambda(code, f); return(goto_OPT_EVAL); } break; case T_CLOSURE_STAR: if ((sym_case) && (!has_methods(f)) && (has_simple_args(closure_body(f))) && (!is_null(closure_args(f)))) { set_opt_sym2(code, cadr(code)); return(fixup_unknown_op(sc, code, f, hop + ((is_safe_closure(f)) ? OP_SAFE_CLOSURE_STAR_S : OP_CLOSURE_STAR_S))); } break; case T_INT_VECTOR: case T_FLOAT_VECTOR: case T_VECTOR: if ((sym_case) || (is_integer(cadr(code)))) /* (v 4/3) */ return(fixup_unknown_op(sc, code, f, (sym_case) ? OP_VECTOR_S : OP_VECTOR_C)); break; case T_STRING: return(fixup_unknown_op(sc, code, f, (sym_case) ? OP_STRING_S : OP_STRING_C)); case T_PAIR: return(fixup_unknown_op(sc, code, f, (sym_case) ? OP_PAIR_S : OP_PAIR_C)); case T_C_OBJECT: if (s7_is_aritable(sc, f, 1)) return(fixup_unknown_op(sc, code, f, (sym_case) ? OP_C_OBJECT_S : OP_C_OBJECT_C)); break; case T_LET: return(fixup_unknown_op(sc, code, f, (sym_case) ? OP_ENVIRONMENT_S : OP_ENVIRONMENT_C)); case T_HASH_TABLE: return(fixup_unknown_op(sc, code, f, (sym_case) ? OP_HASH_TABLE_S : OP_HASH_TABLE_C)); case T_GOTO: return(fixup_unknown_op(sc, code, f, (sym_case) ? OP_GOTO_S : OP_GOTO_C)); default: break; } return(fall_through); } static int unknown_gg_ex(s7_scheme *sc, s7_pointer f) { if (s7_is_aritable(sc, f, 2)) { bool s1, s2; int hop; s7_pointer code; code = sc->code; hop = (is_immutable_symbol(car(code))) ? 1 : 0; s1 = is_symbol(cadr(code)); s2 = is_symbol(caddr(code)); switch (type(f)) { case T_CLOSURE: if (has_methods(f)) break; if (closure_arity_to_int(sc, f) == 2) { if (s1) { if (is_safe_closure(f)) set_optimize_op(code, hop + ((s2) ? OP_SAFE_CLOSURE_SS : OP_SAFE_CLOSURE_SC)); else set_optimize_op(code, hop + ((s2) ? OP_CLOSURE_SS : OP_CLOSURE_SC)); } else { if (!s2) break; set_optimize_op(code, hop + ((is_safe_closure(f)) ? OP_SAFE_CLOSURE_CS : OP_CLOSURE_CS)); } if (s2) set_opt_sym2(code, caddr(code)); else set_opt_con2(code, caddr(code)); set_opt_lambda(code, f); return(goto_OPT_EVAL); } break; case T_CLOSURE_STAR: /* the closure* opts assume args are not keywords, but we can check that! */ if ((s1) && (!has_methods(f))) { if (s2) { if ((!is_keyword(cadr(code))) && (!is_keyword(caddr(code))) && (has_simple_args(closure_body(f))) && (closure_star_arity_to_int(sc, f) >= 2)) { set_opt_sym2(code, caddr(code)); return(fixup_unknown_op(sc, code, f, hop + ((is_safe_closure(f)) ? OP_SAFE_CLOSURE_STAR_SS : OP_CLOSURE_STAR_SX))); } } else { set_opt_con2(code, caddr(code)); if ((!is_keyword(cadr(code))) && (has_simple_args(closure_body(f))) && (closure_star_arity_to_int(sc, f) >= 2)) return(fixup_unknown_op(sc, code, f, hop + ((is_safe_closure(f)) ? OP_SAFE_CLOSURE_STAR_SC : OP_CLOSURE_STAR_SX))); } } break; case T_C_FUNCTION: case T_C_FUNCTION_STAR: case T_C_ANY_ARGS_FUNCTION: case T_C_OPT_ARGS_FUNCTION: case T_C_RST_ARGS_FUNCTION: if (is_safe_procedure(f)) { if (s1) set_optimize_op(code, hop + ((s2) ? OP_SAFE_C_SS : OP_SAFE_C_SC)); else set_optimize_op(code, hop + ((s2) ? OP_SAFE_C_CS : OP_SAFE_C_C)); } else { set_optimize_op(code, hop + OP_C_ALL_X); annotate_args(sc, cdr(code), sc->envir); } set_arglist_length(code, small_int(2)); set_c_function(code, f); return(goto_OPT_EVAL); case T_INT_VECTOR: case T_FLOAT_VECTOR: case T_VECTOR: if ((is_integer(cadr(code))) && /* !s1 obviously) */ (s7_integer(cadr(code)) >= 0) && (is_integer(caddr(code))) && (s7_integer(caddr(code)) >= 0)) return(fixup_unknown_op(sc, code, f, OP_VECTOR_CC)); break; default: break; } } return(fall_through); } static int unknown_all_s_ex(s7_scheme *sc, s7_pointer f) { s7_pointer code; int num_args; code = sc->code; num_args = integer(arglist_length(code)); if (s7_is_aritable(sc, f, num_args)) { int hop; hop = (is_immutable_symbol(car(code))) ? 1 : 0; switch (type(f)) { case T_CLOSURE: if ((!has_methods(f)) && (closure_arity_to_int(sc, f) == num_args)) { annotate_args(sc, cdr(code), sc->envir); return(fixup_unknown_op(sc, code, f, hop + ((is_safe_closure(f)) ? OP_SAFE_CLOSURE_ALL_X : OP_CLOSURE_ALL_S))); } break; case T_C_FUNCTION: case T_C_FUNCTION_STAR: case T_C_ANY_ARGS_FUNCTION: case T_C_OPT_ARGS_FUNCTION: case T_C_RST_ARGS_FUNCTION: if (is_safe_procedure(f)) set_optimize_op(code, hop + OP_SAFE_C_ALL_S); else { set_optimize_op(code, hop + OP_C_ALL_X); annotate_args(sc, cdr(code), sc->envir); } set_c_function(code, f); return(goto_OPT_EVAL); default: break; } } return(fall_through); } static int unknown_a_ex(s7_scheme *sc, s7_pointer f) { if (s7_is_aritable(sc, f, 1)) { s7_pointer code; code = sc->code; set_arglist_length(code, small_int(1)); annotate_args(sc, cdr(code), sc->envir); switch (type(f)) { case T_INT_VECTOR: case T_FLOAT_VECTOR: case T_VECTOR: return(fixup_unknown_op(sc, code, f, OP_VECTOR_A)); case T_C_FUNCTION: case T_C_FUNCTION_STAR: case T_C_ANY_ARGS_FUNCTION: case T_C_OPT_ARGS_FUNCTION: case T_C_RST_ARGS_FUNCTION: if ((is_safe_procedure(f)) && (is_optimized(cadr(code)))) { int op; op = combine_ops(sc, E_C_P, code, cadr(code)); set_optimize_op(code, op); if ((op == OP_SAFE_C_Z) && (is_all_x_op(optimize_op(cadr(code))))) set_optimize_op(code, OP_SAFE_C_A); set_c_function(code, f); return(goto_OPT_EVAL); } if ((is_pair(cadr(code))) && (caadr(code) == sc->QUOTE)) set_optimize_op(code, (is_safe_procedure(f)) ? OP_SAFE_C_Q : OP_C_A); else set_optimize_op(code, (is_safe_procedure(f)) ? OP_SAFE_C_A : OP_C_A); set_c_function(code, f); return(goto_OPT_EVAL); case T_CLOSURE: if ((!has_methods(f)) && (closure_arity_to_int(sc, f) == 1)) { if ((is_pair(cadr(code))) && (caadr(code) == sc->QUOTE)) return(fixup_unknown_op(sc, code, f, (is_safe_closure(f)) ? OP_SAFE_CLOSURE_Q : OP_CLOSURE_Q)); if (is_safe_closure(f)) set_optimize_op(code, (is_global(car(code))) ? OP_SAFE_GLOSURE_A : OP_SAFE_CLOSURE_A); else set_optimize_op(code, (is_global(car(code))) ? OP_GLOSURE_A : OP_CLOSURE_A); set_opt_lambda(code, f); return(goto_OPT_EVAL); } break; case T_CLOSURE_STAR: if ((!has_methods(f)) && (has_simple_args(closure_body(f))) && (closure_star_arity_to_int(sc, f) >= 1) && (!arglist_has_keyword(cdr(code)))) return(fixup_unknown_op(sc, code, f, (is_safe_closure(f)) ? OP_SAFE_CLOSURE_STAR_ALL_X : OP_CLOSURE_STAR_ALL_X)); break; case T_STRING: return(fixup_unknown_op(sc, code, f, OP_STRING_A)); case T_PAIR: return(fixup_unknown_op(sc, code, f, OP_PAIR_A)); case T_C_OBJECT: return(fixup_unknown_op(sc, code, f, OP_C_OBJECT_A)); case T_LET: return(fixup_unknown_op(sc, code, f, ((is_pair(cadr(code))) && (caadr(code) == sc->QUOTE)) ? OP_ENVIRONMENT_Q : OP_ENVIRONMENT_A)); case T_HASH_TABLE: return(fixup_unknown_op(sc, code, f, OP_HASH_TABLE_A)); case T_GOTO: return(fixup_unknown_op(sc, code, f, OP_GOTO_A)); default: break; } } return(fall_through); } static int unknown_aa_ex(s7_scheme *sc, s7_pointer f) { if (s7_is_aritable(sc, f, 2)) { s7_pointer code; code = sc->code; set_arglist_length(code, small_int(2)); annotate_args(sc, cdr(code), sc->envir); switch (type(f)) { case T_CLOSURE: if ((!has_methods(f)) && (closure_arity_to_int(sc, f) == 2)) { set_optimize_op(code, (is_safe_closure(f)) ? OP_SAFE_CLOSURE_AA : OP_CLOSURE_AA); set_opt_lambda(code, f); return(goto_OPT_EVAL); } break; case T_CLOSURE_STAR: if ((!has_methods(f)) && (has_simple_args(closure_body(f))) && (closure_star_arity_to_int(sc, f) >= 2) && (!arglist_has_keyword(cdr(code)))) return(fixup_unknown_op(sc, code, f, (is_safe_closure(f)) ? OP_SAFE_CLOSURE_STAR_ALL_X : OP_CLOSURE_STAR_ALL_X)); break; case T_C_FUNCTION: case T_C_FUNCTION_STAR: case T_C_ANY_ARGS_FUNCTION: case T_C_OPT_ARGS_FUNCTION: case T_C_RST_ARGS_FUNCTION: set_optimize_op(code, (is_safe_procedure(f)) ? OP_SAFE_C_AA : OP_C_ALL_X); set_c_function(code, f); return(goto_OPT_EVAL); default: break; } } return(fall_through); } static int unknown_all_x_ex(s7_scheme *sc, s7_pointer f) { s7_pointer code; int num_args; code = sc->code; num_args = integer(arglist_length(code)); if (s7_is_aritable(sc, f, num_args)) { switch (type(f)) { case T_CLOSURE: if ((!has_methods(f)) && (closure_arity_to_int(sc, f) == num_args)) { annotate_args(sc, cdr(code), sc->envir); if (is_safe_closure(f)) { if ((is_symbol(cadr(code))) && (num_args == 3)) set_optimize_op(code, OP_SAFE_CLOSURE_SAA); else set_optimize_op(code, OP_SAFE_CLOSURE_ALL_X); } else set_optimize_op(code, OP_CLOSURE_ALL_X); set_opt_lambda(code, f); return(goto_OPT_EVAL); } break; case T_CLOSURE_STAR: if ((!has_methods(f)) && (has_simple_args(closure_body(f))) && (closure_star_arity_to_int(sc, f) >= num_args) && (!arglist_has_keyword(cdr(code)))) { annotate_args(sc, cdr(code), sc->envir); return(fixup_unknown_op(sc, code, f, (is_safe_closure(f)) ? OP_SAFE_CLOSURE_STAR_ALL_X : OP_CLOSURE_STAR_ALL_X)); } break; case T_C_FUNCTION: case T_C_FUNCTION_STAR: case T_C_ANY_ARGS_FUNCTION: case T_C_OPT_ARGS_FUNCTION: case T_C_RST_ARGS_FUNCTION: set_optimize_op(code, (is_safe_procedure(f)) ? OP_SAFE_C_ALL_X : OP_C_ALL_X); annotate_args(sc, cdr(code), sc->envir); set_c_function(code, f); return(goto_OPT_EVAL); default: break; } } return(fall_through); } static void unwind_output_ex(s7_scheme *sc) { bool is_file; is_file = is_file_port(sc->code); if ((is_output_port(sc->code)) && (!port_is_closed(sc->code))) s7_close_output_port(sc, sc->code); /* may call fflush */ if ((is_output_port(sc->args)) && (!port_is_closed(sc->args))) sc->output_port = sc->args; if ((is_file) && (is_multiple_value(sc->value))) sc->value = splice_in_values(sc, multiple_value(sc->value)); } static void unwind_input_ex(s7_scheme *sc) { if ((is_input_port(sc->code)) && (!port_is_closed(sc->code))) s7_close_input_port(sc, sc->code); if ((is_input_port(sc->args)) && (!port_is_closed(sc->args))) sc->input_port = sc->args; if (is_multiple_value(sc->value)) sc->value = splice_in_values(sc, multiple_value(sc->value)); } static int dynamic_wind_ex(s7_scheme *sc) { if (dynamic_wind_state(sc->code) == DWIND_INIT) { dynamic_wind_state(sc->code) = DWIND_BODY; push_stack(sc, OP_DYNAMIC_WIND, sc->NIL, sc->code); sc->code = dynamic_wind_body(sc->code); sc->args = sc->NIL; return(goto_APPLY); } else { if (dynamic_wind_state(sc->code) == DWIND_BODY) { dynamic_wind_state(sc->code) = DWIND_FINISH; if (dynamic_wind_out(sc->code) != sc->F) { push_stack(sc, OP_DYNAMIC_WIND, sc->value, sc->code); sc->code = dynamic_wind_out(sc->code); sc->args = sc->NIL; return(goto_APPLY); } else { if (is_multiple_value(sc->value)) sc->value = splice_in_values(sc, multiple_value(sc->value)); return(goto_START); } } if (is_multiple_value(sc->args)) /* (+ 1 (dynamic-wind (lambda () #f) (lambda () (values 2 3 4)) (lambda () #f)) 5) */ sc->value = splice_in_values(sc, multiple_value(sc->args)); else sc->value = sc->args; /* value saved above */ } return(goto_START); } static int read_s_ex(s7_scheme *sc) { /* another lint opt */ s7_pointer port, code; code = sc->code; port = find_symbol_checked(sc, cadr(code)); if (!is_input_port(port)) /* was also not stdin */ { sc->value = g_read(sc, list_1(sc, port)); return(goto_START); } /* I guess this port_is_closed check is needed because we're going down a level below */ if (port_is_closed(port)) simple_wrong_type_argument_with_type(sc, sc->READ, port, AN_OPEN_PORT); if (is_function_port(port)) sc->value = (*(port_input_function(port)))(sc, S7_READ, port); else { if ((is_string_port(port)) && (port_data_size(port) <= port_position(port))) sc->value = sc->EOF_OBJECT; else { push_input_port(sc, port); push_stack(sc, OP_READ_DONE, sc->NIL, sc->NIL); /* this stops the internal read process so we only get one form */ sc->tok = token(sc); switch (sc->tok) { case TOKEN_EOF: return(goto_START); case TOKEN_RIGHT_PAREN: read_error(sc, "unexpected close paren"); case TOKEN_COMMA: read_error(sc, "unexpected comma"); default: sc->value = read_expression(sc); sc->current_line = port_line_number(sc->input_port); /* this info is used to track down missing close parens */ sc->current_file = port_filename(sc->input_port); } } } /* equally read-done and read-list here */ return(goto_START); } static void eval_string_ex(s7_scheme *sc) { /* read and evaluate string expression(s?) * assume caller (C via g_eval_c_string) is dealing with the string port */ /* (eval-string (string-append "(list 1 2 3)" (string #\newline) (string #\newline))) * needs to be sure to get rid of the trailing white space before checking for EOF * else it tries to eval twice and gets "attempt to apply 1?, line 2" */ if ((sc->tok != TOKEN_EOF) && (port_position(sc->input_port) < port_data_size(sc->input_port))) /* ran past end somehow? */ { unsigned char c; while (white_space[c = port_data(sc->input_port)[port_position(sc->input_port)++]]) if (c == '\n') port_line_number(sc->input_port)++; if (c != 0) { backchar(c, sc->input_port); push_stack(sc, OP_EVAL_STRING, sc->NIL, sc->value); push_stack(sc, OP_READ_INTERNAL, sc->NIL, sc->NIL); } else push_stack(sc, OP_EVAL_DONE, sc->NIL, sc->value); } else push_stack(sc, OP_EVAL_DONE, sc->NIL, sc->value); sc->code = sc->value; } static void eval_string_1_ex(s7_scheme *sc) { if ((sc->tok != TOKEN_EOF) && (port_position(sc->input_port) < port_data_size(sc->input_port))) /* ran past end somehow? */ { unsigned char c; while (white_space[c = port_data(sc->input_port)[port_position(sc->input_port)++]]) if (c == '\n') port_line_number(sc->input_port)++; if (c != 0) { backchar(c, sc->input_port); push_stack(sc, OP_EVAL_STRING_1, sc->NIL, sc->value); push_stack(sc, OP_READ_INTERNAL, sc->NIL, sc->NIL); } else push_stack(sc, OP_EVAL_STRING_2, sc->NIL, sc->NIL); } else push_stack(sc, OP_EVAL_STRING_2, sc->NIL, sc->NIL); sc->code = sc->value; } static int string_c_ex(s7_scheme *sc) { s7_int index; s7_pointer s, code; code = sc->code; s = find_symbol_checked(sc, car(code)); if ((!is_string(s)) || (!is_integer(cadr(code)))) return(fall_through); index = s7_integer(cadr(code)); if ((index < string_length(s)) && (index >= 0)) { if (is_byte_vector(s)) sc->value = small_int((unsigned char)string_value(s)[index]); else sc->value = s7_make_character(sc, ((unsigned char *)string_value(s))[index]); return(goto_START); } sc->value = string_ref_1(sc, s, cadr(code)); return(goto_START); } static int string_a_ex(s7_scheme *sc) { s7_int index; s7_pointer s, x, code; code = sc->code; s = find_symbol_checked(sc, car(code)); x = c_call(cdr(code))(sc, cadr(code)); if ((!is_string(s)) || (!s7_is_integer(x))) return(fall_through); index = s7_integer(x); if ((index < string_length(s)) && (index >= 0)) { if (is_byte_vector(s)) sc->value = small_int((unsigned char)string_value(s)[index]); else sc->value = s7_make_character(sc, ((unsigned char *)string_value(s))[index]); return(goto_START); } sc->value = string_ref_1(sc, s, x); return(goto_START); } static int string_s_ex(s7_scheme *sc) { s7_int index; s7_pointer s, ind, code; code = sc->code; s = find_symbol_checked(sc, car(code)); ind = find_symbol_checked(sc, cadr(code)); if ((!is_string(s)) || (!s7_is_integer(ind))) return(fall_through); index = s7_integer(ind); if ((index < string_length(s)) && (index >= 0)) { if (is_byte_vector(s)) sc->value = small_int((unsigned char)string_value(s)[index]); else sc->value = s7_make_character(sc, ((unsigned char *)string_value(s))[index]); return(goto_START); } sc->value = string_ref_1(sc, s, ind); return(goto_START); } static int vector_c_ex(s7_scheme *sc) { /* this is the implicit indexing case (vector-ref is a normal safe op) * (define (hi) (let ((v (vector 1 2 3))) (v 0))) * this starts as unknown_g in optimize_expression -> vector_c * but it still reports itself as unsafe, so there are higher levels possible */ s7_pointer v, code; code = sc->code; v = find_symbol_checked(sc, car(code)); if ((!s7_is_vector(v)) || (!s7_is_integer(cadr(code)))) /* (v 4/3) */ return(fall_through); if (vector_rank(v) == 1) { s7_int index; index = s7_integer(cadr(code)); if ((index < vector_length(v)) && (index >= 0)) { sc->value = vector_getter(v)(sc, v, index); return(goto_START); } } sc->value = vector_ref_1(sc, v, cdr(code)); return(goto_START); } static int vector_cc_ex(s7_scheme *sc) { s7_pointer v, code; code = sc->code; v = find_symbol_checked(sc, car(code)); if (!s7_is_vector(v)) /* we've checked that the args are non-negative ints */ return(fall_through); if (vector_rank(v) == 2) { s7_int index; index = s7_integer(cadr(code)) * vector_offset(v, 0) + s7_integer(caddr(code)); if (index < vector_length(v)) { sc->value = vector_getter(v)(sc, v, index); return(goto_START); } } sc->value = vector_ref_1(sc, v, cdr(code)); return(goto_START); } static int vector_s_ex(s7_scheme *sc) { s7_pointer v, ind, code; code = sc->code; v = find_symbol_checked(sc, car(code)); ind = find_symbol_checked(sc, cadr(code)); if ((!s7_is_vector(v)) || (!s7_is_integer(ind))) return(fall_through); if (vector_rank(v) == 1) { s7_int index; index = s7_integer(ind); if ((index < vector_length(v)) && (index >= 0)) { sc->value = vector_getter(v)(sc, v, index); return(goto_START); } } sc->value = vector_ref_1(sc, v, cons(sc, ind, sc->NIL)); return(goto_START); } static int vector_a_ex(s7_scheme *sc) { s7_pointer v, x, code; code = sc->code; v = find_symbol_checked(sc, car(code)); if (!s7_is_vector(v)) return(fall_through); x = c_call(cdr(code))(sc, cadr(code)); if (s7_is_integer(x)) { if (vector_rank(v) == 1) { s7_int index; index = s7_integer(x); if ((index < vector_length(v)) && (index >= 0)) { sc->value = vector_getter(v)(sc, v, index); return(goto_START); } } } sc->value = vector_ref_1(sc, v, cons(sc, x, sc->NIL)); return(goto_START); } #if WITH_QUASIQUOTE_VECTOR static void read_quasiquote_vector_ex(s7_scheme *sc) { /* this works only if the quasiquoted list elements can be evaluated in the read-time environment. * `#(1 ,@(list 1 2) 4) -> (apply vector ({list} 1 ({apply_values} (list 1 2)) 4)) -> #(1 1 2 4) * * Originally, I used: * sc->value = list_3(sc, sc->Apply, sc->Vector, g_quasiquote_1(sc, sc->value)); * goto START; * which means that #(...) makes a vector at read time, but `#(...) is just like (vector ...). * :(let ((f1 (lambda () (let ((x 32)) #(x 0)))) * (f2 (lambda () (let ((x 32)) `#(,x 0))))) * (eq? (f1) (f1))) * #t * :(let ((f1 (lambda () (let ((x 32)) #(x 0)))) * (f2 (lambda () (let ((x 32)) `#(,x 0))))) * (eq? (f2) (f2))) * #f * The tricky part in s7 is that we might have quasiquoted multidimensional vectors */ if (sc->args == small_int(1)) sc->code = list_3(sc, sc->Apply, sc->Vector, g_quasiquote_1(sc, sc->value)); /* qq result will be evaluated (might include {list} etc) */ else sc->code = list_4(sc, sc->Apply, sc->Multivector, sc->args, g_quasiquote_1(sc, sc->value)); } #endif static void increment_1_ex(s7_scheme *sc) { /* ([set!] ctr (+ ctr 1)) */ s7_pointer val, y; y = find_symbol(sc, car(sc->code)); if (!is_slot(y)) eval_error_no_return(sc, sc->WRONG_TYPE_ARG, "set! ~A: unbound variable", car(sc->code)); val = slot_value(y); switch (type(val)) { case T_INTEGER: sc->value = make_integer(sc, integer(val) + 1); /* this can't be optimized to treat y's value as a mutable integer */ break; case T_RATIO: new_cell(sc, sc->value, T_RATIO); numerator(sc->value) = numerator(val) + denominator(val); denominator(sc->value) = denominator(val); break; case T_REAL: sc->value = make_real(sc, real(val) + 1.0); break; case T_COMPLEX: new_cell(sc, sc->value, T_COMPLEX); set_real_part(sc->value, real_part(val) + 1.0); set_imag_part(sc->value, imag_part(val)); break; default: sc->value = g_add(sc, set_plist_2(sc, val, small_int(1))); break; } slot_set_value(y, sc->value); } static void decrement_1_ex(s7_scheme *sc) { /* ([set!] ctr (- ctr 1)) */ s7_pointer val, y; y = find_symbol(sc, car(sc->code)); if (!is_slot(y)) eval_error_no_return(sc, sc->WRONG_TYPE_ARG, "set! ~A: unbound variable", car(sc->code)); val = slot_value(y); switch (type(val)) { case T_INTEGER: sc->value = make_integer(sc, integer(val) - 1); break; case T_RATIO: new_cell(sc, sc->value, T_RATIO); numerator(sc->value) = numerator(val) - denominator(val); denominator(sc->value) = denominator(val); break; case T_REAL: sc->value = make_real(sc, real(val) - 1.0); break; case T_COMPLEX: new_cell(sc, sc->value, T_COMPLEX); set_real_part(sc->value, real_part(val) - 1.0); set_imag_part(sc->value, imag_part(val)); break; default: sc->value = g_subtract(sc, set_plist_2(sc, val, small_int(1))); break; } slot_set_value(y, sc->value); } static void set_pws_ex(s7_scheme *sc) { /* ([set!] (save-dir) "/home/bil/zap/snd") */ s7_pointer obj; obj = caar(sc->code); if (is_symbol(obj)) { obj = find_symbol(sc, obj); if (is_slot(obj)) obj = slot_value(obj); else eval_error_no_return(sc, sc->SYNTAX_ERROR, "no generalized set for ~A", caar(sc->code)); } if ((is_c_function(obj)) && (is_procedure(c_function_setter(obj)))) { s7_pointer value; value = cadr(sc->code); if (is_symbol(value)) value = find_symbol_checked(sc, value); car(sc->T1_1) = value; sc->value = c_function_call(c_function_setter(obj))(sc, sc->T1_1); } else eval_error_no_return(sc, sc->SYNTAX_ERROR, "no generalized set for ~A", obj); } /* -------------------------------- apply functions -------------------------------- */ static void apply_c_function(s7_scheme *sc) /* -------- C-based function -------- */ { unsigned int len; len = safe_list_length(sc, sc->args); if (len < c_function_required_args(sc->code)) s7_error(sc, sc->WRONG_NUMBER_OF_ARGS, set_elist_3(sc, sc->NOT_ENOUGH_ARGUMENTS, sc->code, sc->args)); if (c_function_all_args(sc->code) < len) s7_error(sc, sc->WRONG_NUMBER_OF_ARGS, set_elist_3(sc, sc->TOO_MANY_ARGUMENTS, sc->code, sc->args)); sc->value = c_function_call(sc->code)(sc, sc->args); } static void apply_c_opt_args_function(s7_scheme *sc) /* -------- C-based function that has n optional arguments -------- */ { unsigned int len; len = safe_list_length(sc, sc->args); if (c_function_all_args(sc->code) < len) s7_error(sc, sc->WRONG_NUMBER_OF_ARGS, set_elist_3(sc, sc->TOO_MANY_ARGUMENTS, sc->code, sc->args)); sc->value = c_function_call(sc->code)(sc, sc->args); } static void apply_c_rst_args_function(s7_scheme *sc) /* -------- C-based function that has n required args, then any others -------- */ { unsigned int len; len = safe_list_length(sc, sc->args); if (len < c_function_required_args(sc->code)) s7_error(sc, sc->WRONG_NUMBER_OF_ARGS, set_elist_3(sc, sc->NOT_ENOUGH_ARGUMENTS, sc->code, sc->args)); sc->value = c_function_call(sc->code)(sc, sc->args); /* sc->code here need not match sc->code before the function call (map for example) */ } static void apply_c_any_args_function(s7_scheme *sc) /* -------- C-based function that can take any number of arguments -------- */ { sc->value = c_function_call(sc->code)(sc, sc->args); } static void apply_c_function_star(s7_scheme *sc) /* -------- C-based function with defaults (lambda*) -------- */ { sc->value = c_function_call(sc->code)(sc, set_c_function_call_args(sc)); } static void apply_c_macro(s7_scheme *sc) /* -------- C-based macro -------- */ { int len; len = s7_list_length(sc, sc->args); if (len < (int)c_macro_required_args(sc->code)) s7_error(sc, sc->WRONG_NUMBER_OF_ARGS, set_elist_3(sc, sc->NOT_ENOUGH_ARGUMENTS, sc->code, sc->args)); if ((int)c_macro_all_args(sc->code) < len) s7_error(sc, sc->WRONG_NUMBER_OF_ARGS, set_elist_3(sc, sc->TOO_MANY_ARGUMENTS, sc->code, sc->args)); sc->code = c_macro_call(sc->code)(sc, sc->args); if (is_multiple_value(sc->code)) /* can this happen? s7_values splices before returning, and `(values ...) is handled later */ { push_stack(sc, OP_EVAL_MACRO_MV, sc->NIL, cdr(sc->code)); sc->code = car(sc->code); } } static void apply_syntax(s7_scheme *sc) /* -------- syntactic keyword as applicable object -------- */ { /* current reader-cond macro uses this via (map quote ...) */ int len; /* ((apply lambda '((x) (+ x 1))) 4) */ if (is_pair(sc->args)) { len = s7_list_length(sc, sc->args); if (len == 0) eval_error_no_return(sc, sc->SYNTAX_ERROR, "attempt to evaluate a circular list: ~A", sc->args); } else len = 0; if (len < syntax_min_args(sc->code)) s7_error(sc, sc->WRONG_NUMBER_OF_ARGS, set_elist_3(sc, sc->NOT_ENOUGH_ARGUMENTS, sc->code, sc->args)); if ((syntax_max_args(sc->code) < len) && (syntax_max_args(sc->code) != -1)) s7_error(sc, sc->WRONG_NUMBER_OF_ARGS, set_elist_3(sc, sc->TOO_MANY_ARGUMENTS, sc->code, sc->args)); sc->op = (opcode_t)syntax_opcode(sc->code); /* (apply begin '((define x 3) (+ x 2))) */ /* I used to have elaborate checks here for embedded circular lists, but now i think that is the caller's problem */ sc->code = sc->args; } static void apply_vector(s7_scheme *sc) /* -------- vector as applicable object -------- */ { /* sc->code is the vector, sc->args is the list of indices */ if (is_null(sc->args)) /* (#2d((1 2) (3 4))) */ s7_wrong_number_of_args_error(sc, "not enough args for vector-ref: ~A", sc->args); if ((is_null(cdr(sc->args))) && (s7_is_integer(car(sc->args))) && (vector_rank(sc->code) == 1)) { s7_int index; index = s7_integer(car(sc->args)); if ((index >= 0) && (index < vector_length(sc->code))) sc->value = vector_getter(sc->code)(sc, sc->code, index); else out_of_range(sc, sc->VECTOR_REF, small_int(2), car(sc->args), (index < 0) ? ITS_NEGATIVE : ITS_TOO_LARGE); } else sc->value = vector_ref_1(sc, sc->code, sc->args); } static void apply_string(s7_scheme *sc) /* -------- string as applicable object -------- */ { if (is_null(cdr(sc->args))) { if (s7_is_integer(car(sc->args))) { s7_int index; /* not int: ("abs" most-negative-fixnum) */ index = s7_integer(car(sc->args)); if ((index >= 0) && (index < string_length(sc->code))) { if (is_byte_vector(sc->code)) sc->value = small_int((unsigned char)(string_value(sc->code))[index]); else sc->value = s7_make_character(sc, ((unsigned char *)string_value(sc->code))[index]); return; } } sc->value = string_ref_1(sc, sc->code, car(sc->args)); return; } s7_error(sc, sc->WRONG_NUMBER_OF_ARGS, set_elist_3(sc, (is_null(sc->args)) ? sc->NOT_ENOUGH_ARGUMENTS : sc->TOO_MANY_ARGUMENTS, sc->code, sc->args)); } static int apply_pair(s7_scheme *sc) /* -------- list as applicable object -------- */ { if (is_multiple_value(sc->code)) /* ((values 1 2 3) 0) */ { /* car of values can be anything, so conjure up a new expression, and apply again */ sc->x = multiple_value(sc->code); /* ((values + 1 2) 3) */ sc->code = car(sc->x); sc->args = s7_append(sc, cdr(sc->x), sc->args); sc->x = sc->NIL; return(goto_APPLY); } if (is_null(sc->args)) s7_wrong_number_of_args_error(sc, "not enough args for list-ref (via list as applicable object): ~A", sc->args); sc->value = list_ref_1(sc, sc->code, car(sc->args)); /* (L 1) */ if (!is_null(cdr(sc->args))) sc->value = implicit_index(sc, sc->value, cdr(sc->args)); /* (L 1 2) */ return(goto_START); } static void apply_hash_table(s7_scheme *sc) /* -------- hash-table as applicable object -------- */ { if (is_null(sc->args)) s7_wrong_number_of_args_error(sc, "not enough args for hash-table-ref (via hash table as applicable object): ~A", sc->args); sc->value = s7_hash_table_ref(sc, sc->code, car(sc->args)); if (!is_null(cdr(sc->args))) sc->value = implicit_index(sc, sc->value, cdr(sc->args)); } static void apply_let(s7_scheme *sc) /* -------- environment as applicable object -------- */ { if (is_null(sc->args)) sc->value = s7_let_ref(sc, sc->code, sc->F); /* why #f and not ()? both are ok in s7test */ else sc->value = s7_let_ref(sc, sc->code, car(sc->args)); if (is_pair(cdr(sc->args))) sc->value = implicit_index(sc, sc->value, cdr(sc->args)); /* (let ((v #(1 2 3))) (let ((e (curlet))) ((e 'v) 1))) -> 2 * so (let ((v #(1 2 3))) (let ((e (curlet))) (e 'v 1))) -> 2 */ } static void apply_iterator(s7_scheme *sc) /* -------- iterator as applicable object -------- */ { if (!is_null(sc->args)) s7_wrong_number_of_args_error(sc, "too many args for iterator: ~A", sc->args); sc->value = s7_iterate(sc, sc->code); } static void apply_lambda(s7_scheme *sc) /* -------- normal function (lambda), or macro -------- */ { /* load up the current args into the ((args) (lambda)) layout [via the current environment] */ /* not often safe closure here, and very confusing if so to get identity macro args handled correctly */ s7_pointer x, z, e; unsigned long long int id; e = sc->envir; id = let_id(e); for (x = closure_args(sc->code), z = sc->args; is_pair(x); x = cdr(x)) { s7_pointer sym, args, val; /* reuse the value cells as the new frame slots */ if (is_null(z)) s7_error(sc, sc->WRONG_NUMBER_OF_ARGS, set_elist_3(sc, sc->NOT_ENOUGH_ARGUMENTS, closure_name(sc, sc->code), sc->cur_code)); /* now that args are being reused as slots, the error message can't use sc->args, * so fallback on sc->cur_code in this section. * But that can be #f, and closure_name can be confusing in this context, so we need a better error message! */ sym = car(x); val = car(z); args = cdr(z); set_type(z, T_SLOT); slot_set_symbol(z, sym); symbol_set_local(sym, id, z); slot_set_value(z, val); next_slot(z) = let_slots(e); let_set_slots(e, z); z = args; } if (is_null(x)) { if (is_not_null(z)) s7_error(sc, sc->WRONG_NUMBER_OF_ARGS, set_elist_3(sc, sc->TOO_MANY_ARGUMENTS, closure_name(sc, sc->code), sc->cur_code)); } else { sc->temp6 = z; /* the rest arg */ make_slot_1(sc, sc->envir, x, z); sc->temp6 = sc->NIL; } sc->code = closure_body(sc->code); } static int apply_lambda_star(s7_scheme *sc) /* -------- define* (lambda*) -------- */ { /* to check for and fixup unset args from defaults, we need to traverse the slots in left-to-right order * but they are stored backwards in the environment, so use pending_value as a back-pointer. * We have to build the environment before calling lambda_star_set_args because keywords can * cause any arg to be set at any point in the arg list. * * the frame-making step below could be precalculated, but where to store it? */ s7_pointer z, top, nxt; top = NULL; nxt = NULL; for (z = closure_args(sc->code); is_pair(z); z = cdr(z)) { s7_pointer car_z; car_z = car(z); if (is_pair(car_z)) /* arg has a default value of some sort */ { s7_pointer val; val = cadr(car_z); if ((!is_pair(val)) && (!is_symbol(val))) make_slot_1(sc, sc->envir, car(car_z), val); else { s7_pointer y; add_slot(sc->envir, car(car_z), sc->UNDEFINED); y = let_slots(sc->envir); slot_expression(y) = cadr(car_z); slot_pending_value(y) = sc->NIL; if (!top) { top = y; nxt = top; } else { slot_pending_value(nxt) = y; nxt = y; } } } else { if (!is_keyword(car_z)) make_slot_1(sc, sc->envir, car_z, sc->F); else { if (car_z == sc->KEY_REST) { make_slot_1(sc, sc->envir, cadr(z), sc->NIL); z = cdr(z); } } } } if (is_symbol(z)) make_slot_1(sc, sc->envir, z, sc->NIL); lambda_star_set_args(sc); /* load up current arg vals */ if (top) { /* get default values, which may involve evaluation */ push_stack(sc, OP_LAMBDA_STAR_DEFAULT, sc->args, sc->code); /* op is just a placeholder (don't use OP_BARRIER here) */ sc->args = top; if (lambda_star_default(sc) == goto_EVAL) return(goto_EVAL); pop_stack_no_op(sc); /* get original args and code back */ } sc->code = closure_body(sc->code); return(goto_BEGIN1); } static void apply_continuation(s7_scheme *sc) /* -------- continuation ("call/cc") -------- */ { if (!call_with_current_continuation(sc)) { static s7_pointer cc_err = NULL; if (!cc_err) cc_err = s7_make_permanent_string("continuation can't jump into with-baffle"); s7_error(sc, sc->BAFFLED, set_elist_1(sc, cc_err)); } } static void apply_c_object(s7_scheme *sc) /* -------- applicable (new-type) object -------- */ { sc->value = (*(c_object_ref(sc->code)))(sc, sc->code, sc->args); } /* -------------------------------------------------------------------------------- */ static int define1_ex(s7_scheme *sc) { /* sc->code is the symbol being defined, sc->value is its value * if sc->value is a closure, car is of the form ((args...) body...) * so the doc string if any is (cadr (car value)) * and the arg list gives the number of optional args up to the dot */ /* it's not possible to expand and replace macros at this point without evaluating * the body. Just as examples, say we have a macro "mac", * (define (hi) (call/cc (lambda (mac) (mac 1)))) * (define (hi) (quote (mac 1))) or macroexpand etc * (define (hi mac) (mac 1)) assuming mac here is a function passed as an arg, * etc... */ /* the immutable constant check needs to wait until we have the actual new value because * we want to ignore the rebinding (not raise an error) if it is the existing value. * This happens when we reload a file that calls define-constant. */ if (is_immutable(sc->code)) /* (define pi 3) or (define (pi a) a) */ { s7_pointer x; if (!is_symbol(sc->code)) /* (define "pi" 3) ? */ eval_error_no_return(sc, sc->SYNTAX_ERROR, "define: ~S is immutable", sc->code); x = global_slot(sc->code); if ((!is_slot(x)) || (type(sc->value) != unchecked_type(slot_value(x))) || (!s7_is_morally_equal(sc, sc->value, slot_value(x)))) /* if value is unchanged, just ignore this (re)definition */ eval_error_no_return(sc, sc->SYNTAX_ERROR, "define: ~S is immutable", sc->code); /* can't use s7_is_equal because value might be NaN, etc */ } if (symbol_has_accessor(sc->code)) { s7_pointer x; x = find_symbol(sc, sc->code); if ((is_slot(x)) && (slot_has_accessor(x))) { sc->value = bind_accessed_symbol(sc, OP_DEFINE_WITH_ACCESSOR, sc->code, sc->value); if (sc->value == sc->NO_VALUE) return(goto_APPLY); /* if all goes well, OP_DEFINE_WITH_ACCESSOR will jump to DEFINE2 */ } } return(fall_through); } static void define2_ex(s7_scheme *sc) { if (is_any_closure(sc->value)) { s7_pointer new_func, new_env; new_func = sc->value; /* we can get here from let: (define (outer a) (let () (define (inner b) (+ a b)) (inner a))) * but the port info is not relevant here, so restrict the __func__ list making to top-level * cases (via sc->envir == sc->NIL). */ new_cell_no_check(sc, new_env, T_LET | T_FUNCTION_ENV); let_id(new_env) = ++sc->let_number; set_outlet(new_env, closure_let(new_func)); closure_set_let(new_func, new_env); let_set_slots(new_env, sc->NIL); funclet_set_function(new_env, sc->code); if ((!is_let(sc->envir)) && (port_filename(sc->input_port)) && (port_file(sc->input_port) != stdin)) { /* unbound_variable will be called if __func__ is encountered, and will return this info as if __func__ had some meaning */ let_set_file(new_env, port_file_number(sc->input_port)); let_set_line(new_env, port_line_number(sc->input_port)); } else { let_set_file(new_env, 0); let_set_line(new_env, 0); } /* this should happen only if the closure* default values do not refer in any way to * the enclosing environment (else we can accidentally shadow something that happens * to share an argument name that is being used as a default value -- kinda dumb!). * I think I'll check this before setting the safe_closure bit. */ if (is_safe_closure(new_func)) { int i; s7_pointer arg; for (i = 0, arg = closure_args(new_func); is_pair(arg); i++, arg = cdr(arg)) { if (is_pair(car(arg))) make_slot_1(sc, new_env, caar(arg), sc->NIL); else make_slot_1(sc, new_env, car(arg), sc->NIL); } let_set_slots(new_env, reverse_slots(sc, let_slots(new_env))); } /* add the newly defined thing to the current environment */ if (is_let(sc->envir)) { add_slot(sc->envir, sc->code, new_func); set_local(sc->code); /* so funchecked is always local already -- perhaps reset below? */ } else s7_make_slot(sc, sc->envir, sc->code, new_func); sc->value = new_func; /* 25-Jul-14 so define returns the value not the name */ } else { s7_pointer lx; /* add the newly defined thing to the current environment */ lx = find_local_symbol(sc, sc->code, sc->envir); if (is_slot(lx)) slot_set_value(lx, sc->value); else s7_make_slot(sc, sc->envir, sc->code, sc->value); } } /* ---------------------------------------- */ static void clear_all_optimizations(s7_scheme *sc, s7_pointer p) { /* I believe that we would not have been optimized to begin with if the tree were circular, * and this tree is supposed to be a function call + args -- a circular list here is a bug. */ if (is_pair(p)) { if (is_optimized(p)) { clear_optimized(p); clear_optimize_op(p); set_opt_con1(p, sc->NIL); set_opt_con2(p, sc->NIL); } clear_all_optimizations(sc, cdr(p)); clear_all_optimizations(sc, car(p)); } } static bool a_is_ok(s7_scheme *sc, s7_pointer p) { /* "A" here need not be a function call or "p" a pair (all_x_c etc) */ if (is_pair(p)) { if ((is_optimized(p)) && (!c_function_is_ok(sc, p))) return(false); if (car(p) != sc->QUOTE) return((a_is_ok(sc, car(p))) && (a_is_ok(sc, cdr(p)))); } return(true); } #define c_function_is_ok_cadr(Sc, P) ((c_function_is_ok(Sc, P)) && (c_function_is_ok(Sc, cadr(P)))) #define c_function_is_ok_caddr(Sc, P) ((c_function_is_ok(Sc, P)) && (c_function_is_ok(Sc, caddr(P)))) #define c_function_is_ok_cadr_caddr(Sc, P) ((c_function_is_ok(Sc, P)) && (c_function_is_ok(Sc, cadr(P))) && (c_function_is_ok(Sc, caddr(P)))) #define a_is_ok_cadr(Sc, P) ((c_function_is_ok(Sc, P)) && (a_is_ok(Sc, cadr(P)))) #define a_is_ok_caddr(Sc, P) ((c_function_is_ok(Sc, P)) && (a_is_ok(Sc, caddr(P)))) #define a_is_ok_cadddr(Sc, P) ((c_function_is_ok(Sc, P)) && (a_is_ok(Sc, cadddr(P)))) /* -------------------------------- eval -------------------------------- */ #if WITH_GCC #undef new_cell #if (!DEBUGGING) #define new_cell(Sc, Obj, Type) \ do { \ if (Sc->free_heap_top <= Sc->free_heap_trigger) {try_to_call_gc(Sc); if ((Sc->begin_hook) && (call_begin_hook(Sc))) return(Sc->F);} \ Obj = (*(--(Sc->free_heap_top))); \ set_type(Obj, Type); \ } while (0) #else #define new_cell(Sc, Obj, Type) \ do { \ if ((Sc->free_heap_top <= Sc->free_heap_trigger) || (for_any_other_reason(sc, __LINE__))) {last_gc_line = __LINE__; last_gc_func = __func__; try_to_call_gc(Sc); if ((Sc->begin_hook) && (call_begin_hook(Sc))) return(Sc->F);} \ Obj = (*(--(Sc->free_heap_top))); \ Obj->alloc_line = __LINE__; Obj->alloc_func = __func__; \ set_type(Obj, Type); \ } while (0) #endif #endif #if WITH_GMP #define global_add big_add #else #define global_add g_add #endif static s7_pointer check_for_cyclic_code(s7_scheme *sc, s7_pointer code) { if (cyclic_sequences(sc, code, false) == sc->T) eval_error(sc, "attempt to evaluate a circular list: ~A", code); resize_stack(sc); return(sc->F); } static s7_pointer eval(s7_scheme *sc, opcode_t first_op) { sc->op = first_op; /* this procedure can be entered recursively (via s7_call for example), so it's no place for a setjmp * I don't think the recursion can hurt our continuations because s7_call is coming from hooks and * callbacks that are implicit in our stack. */ goto START_WITHOUT_POP_STACK; /* this ugly two-step is faster than other ways of writing this code */ while (true) { START: pop_stack(sc); /* syntax_opcode can be optimize_op, the field can be set at read time, we could * probably combine the optimized and normal case statements, jump here if eval (eval_pair, opt_eval), * and thereby save the is_syntactic and is_pair check in op_eval, op_begin would explicitly jump back here, no op_eval, * current trailers would be outside? and where would eval args go? Huge change, might save 1% if lucky. * see end of file -- I think this is too pessimistic and given rearrangement of the s7_cell layout, * can be done without an increase in size. * * about half the cases don't care about args or op, but it's not simple to distribute the sc->args * setting throughout this switch statement. Lots of branches fall through to the next and there * are many internal goto's to branches, so the code becomes a mess. sc->op is even worse because * we use it in several cases for error information or choice of next op, etc. */ START_WITHOUT_POP_STACK: /* fprintf(stderr, "%s (%d)\n", op_names[sc->op], (int)(sc->op)); */ switch (sc->op) { case OP_NO_OP: break; case OP_READ_INTERNAL: /* if we're loading a file, and in the file we evaluate something like: * (let () * (set-current-input-port (open-input-file "tmp2.r5rs")) * (close-input-port (current-input-port))) * ... (with no reset of input port to its original value) * the load process tries to read the loaded string, but the sc->input_port is now closed, * and the original is inaccessible! So we get a segfault in token. We don't want to put * a port_is_closed check there because token only rarely is in this danger. I think this * is the only place where we can be about to call token, and someone has screwed up our port. * * We can't call read_error here because it assumes the input string is ok! */ if (port_is_closed(sc->input_port)) return(s7_error(sc, sc->READ_ERROR, set_elist_1(sc, make_string_wrapper(sc, "our input port got clobbered!")))); sc->tok = token(sc); switch (sc->tok) { case TOKEN_EOF: { /* (eval-string "'a ; b") gets here with 'a -> a, so we need to squelch the pending eval. * another approach would read-ahead in eval_string_1_ex, but this seems less messy. */ int top; top = s7_stack_top(sc) - 1; if (stack_op(sc->stack, top) == OP_EVAL_STRING_1) vector_element(sc->stack, top) = (s7_pointer)OP_EVAL_STRING_2; } break; case TOKEN_RIGHT_PAREN: read_error(sc, "unexpected close paren"); case TOKEN_COMMA: read_error(sc, "unexpected comma"); default: sc->value = read_expression(sc); sc->current_line = port_line_number(sc->input_port); /* this info is used to track down missing close parens */ sc->current_file = port_filename(sc->input_port); break; } break; /* (read p) from scheme * "p" becomes current input port for eval's duration, then pops back before returning value into calling expr */ case OP_READ_DONE: pop_input_port(sc); if (sc->tok == TOKEN_EOF) sc->value = sc->EOF_OBJECT; sc->current_file = NULL; /* this is for error handling */ break; /* load("file"); from C (g_load) -- assume caller will clean up * read and evaluate exprs until EOF that matches (stack reflects nesting) */ case OP_LOAD_RETURN_IF_EOF: /* loop here until eof (via push stack below) */ if (sc->tok != TOKEN_EOF) { push_stack(sc, OP_LOAD_RETURN_IF_EOF, sc->NIL, sc->NIL); push_stack(sc, OP_READ_INTERNAL, sc->NIL, sc->NIL); sc->code = sc->value; goto EVAL; /* we read an expression, now evaluate it, and return to read the next */ } sc->current_file = NULL; return(sc->F); /* (load "file") in scheme * read and evaluate all exprs, then upon EOF, close current and pop input port stack */ case OP_LOAD_CLOSE_AND_POP_IF_EOF: if (sc->tok != TOKEN_EOF) { push_stack(sc, OP_LOAD_CLOSE_AND_POP_IF_EOF, sc->NIL, sc->NIL); /* was push args, code */ if ((!is_string_port(sc->input_port)) || (port_position(sc->input_port) < port_data_size(sc->input_port))) { push_stack(sc, OP_READ_INTERNAL, sc->NIL, sc->NIL); } else sc->tok = TOKEN_EOF; sc->code = sc->value; goto EVAL; /* we read an expression, now evaluate it, and return to read the next */ } s7_close_input_port(sc, sc->input_port); pop_input_port(sc); sc->current_file = NULL; if (is_multiple_value(sc->value)) /* (load "file") where "file" is (values 1 2 3) */ sc->value = splice_in_values(sc, multiple_value(sc->value)); break; case OP_EVAL_STRING: eval_string_ex(sc); goto EVAL; case OP_EVAL_STRING_2: s7_close_input_port(sc, sc->input_port); pop_input_port(sc); if (is_multiple_value(sc->value)) sc->value = splice_in_values(sc, multiple_value(sc->value)); break; case OP_EVAL_STRING_1: eval_string_1_ex(sc); goto EVAL; /* -------------------- sort! (heapsort, done directly so that call/cc in the sort function will work correctly) -------------------- */ #define SORT_N integer(vector_element(sc->code, 0)) #define SORT_K integer(vector_element(sc->code, 1)) #define SORT_J integer(vector_element(sc->code, 2)) #define SORT_K1 integer(vector_element(sc->code, 3)) #define SORT_CALLS integer(vector_element(sc->code, 4)) #define SORT_STOP integer(vector_element(sc->code, 5)) #define SORT_DATA(K) vector_element(car(sc->args), K) #define SORT_LESSP cadr(sc->args) HEAPSORT: { s7_int n, j, k; s7_pointer lx; n = SORT_N; k = SORT_K1; if ((n == k) || (k > ((s7_int)(n / 2)))) /* k == n == 0 is the first case */ goto START; if (sc->safety != 0) { SORT_CALLS++; if (SORT_CALLS > SORT_STOP) eval_range_error(sc, "sort! is caught in an infinite loop, comparison: ~S", SORT_LESSP); } j = 2 * k; SORT_J = j; if (j < n) { push_stack(sc, OP_SORT1, sc->args, sc->code); lx = SORT_LESSP; /* cadr of sc->args */ if (needs_copied_args(lx)) sc->args = list_2(sc, SORT_DATA(j), SORT_DATA(j + 1)); else { car(sc->T2_1) = SORT_DATA(j); car(sc->T2_2) = SORT_DATA(j + 1); sc->args = sc->T2_1; } sc->code = lx; goto APPLY; } else sc->value = sc->F; } case OP_SORT1: { s7_int j, k; s7_pointer lx; k = SORT_K1; j = SORT_J; if (is_true(sc, sc->value)) { j = j + 1; SORT_J = j; } push_stack(sc, OP_SORT2, sc->args, sc->code); lx = SORT_LESSP; if (needs_copied_args(lx)) sc->args = list_2(sc, SORT_DATA(k), SORT_DATA(j)); else { car(sc->T2_1) = SORT_DATA(k); car(sc->T2_2) = SORT_DATA(j); sc->args = sc->T2_1; } sc->code = lx; goto APPLY; } case OP_SORT2: { s7_int j, k; k = SORT_K1; j = SORT_J; if (is_true(sc, sc->value)) { s7_pointer lx; lx = SORT_DATA(j); SORT_DATA(j) = SORT_DATA(k); SORT_DATA(k) = lx; } else goto START; SORT_K1 = SORT_J; goto HEAPSORT; } case OP_SORT: /* coming in sc->args is sort args (data less?), sc->code = '(n k 0) * here we call the inner loop until k <= 0 [the local k! -- this is tricky because scheme passes args by value] */ { s7_int k; k = SORT_K; if (k > 0) { SORT_K = k - 1; SORT_K1 = k - 1; push_stack(sc, OP_SORT, sc->args, sc->code); goto HEAPSORT; } /* else fall through */ } case OP_SORT3: { s7_int n; s7_pointer lx; n = SORT_N; if (n <= 0) { sc->value = car(sc->args); goto START; } lx = SORT_DATA(0); SORT_DATA(0) = SORT_DATA(n); SORT_DATA(n) = lx; SORT_N = n - 1; SORT_K1 = 0; push_stack(sc, OP_SORT3, sc->args, sc->code); goto HEAPSORT; } case OP_SORT_PAIR_END: /* sc->value is the sort vector which needs to be copied into the original list */ sc->value = vector_into_list(sc->value, car(sc->args)); break; case OP_SORT_VECTOR_END: /* sc->value is the sort (s7_pointer) vector which needs to be copied into the original (double/int) vector */ sc->value = vector_into_fi_vector(sc->value, car(sc->args)); break; case OP_SORT_STRING_END: sc->value = vector_into_string(sc->value, car(sc->args)); break; /* batcher networks: * ((0 2) (0 1) (1 2)) * ((0 2) (1 3) (0 1) (2 3) (1 2)) * etc -- see batcher in s7test.scm (from Doug Hoyte) * but since it has to be done here by hand, it turns into too much code, 3 is: * < l0 l2 ? * no goto L1 * < l0 l1 ? * no return 1 0 2 * < l1 l2? * yes return 0 1 2 (direct) * no return 0 2 1 * L1: * < l0 l1 ? * yes return 2 0 1 * < l1 l2 ? * yes return 1 2 0 * no return 2 1 0 * since each "<" op above goes to OP_APPLY, we have ca 5 labels, and ca 25-50 lines */ /* -------------------------------- MAP -------------------------------- */ case OP_MAP_GATHER_1: if (sc->value != sc->NO_VALUE) { if (is_multiple_value(sc->value)) counter_result(sc->args) = revappend(sc, multiple_value(sc->value), counter_result(sc->args)); else counter_result(sc->args) = cons(sc, sc->value, counter_result(sc->args)); } case OP_MAP_1: { s7_pointer x, args, code, p; code = sc->code; args = sc->args; p = counter_list(args); x = s7_iterate(sc, p); if (iterator_is_at_end(p)) { sc->value = safe_reverse_in_place(sc, counter_result(args)); goto START; } push_stack(sc, OP_MAP_GATHER_1, args, code); if (counter_capture(args) != sc->capture_let_counter) { new_frame_with_slot(sc, closure_let(code), sc->envir, car(closure_args(code)), x); counter_set_let(args, sc->envir); counter_capture(args) = sc->capture_let_counter; } else sc->envir = old_frame_with_slot(sc, counter_let(args), x); sc->code = closure_body(code); goto BEGIN1; } case OP_MAP_GATHER: if (sc->value != sc->NO_VALUE) /* (map (lambda (x) (values)) (list 1)) */ { if (is_multiple_value(sc->value)) /* (map (lambda (x) (if (odd? x) (values x (* x 20)) (values))) (list 1 2 3 4)) */ counter_result(sc->args) = revappend(sc, multiple_value(sc->value), counter_result(sc->args)); /* not append_in_place here because sc->value has the multiple-values bit set */ else counter_result(sc->args) = cons(sc, sc->value, counter_result(sc->args)); } case OP_MAP: { s7_pointer y, iterators; iterators = counter_list(sc->args); sc->x = sc->NIL; /* can't use preset args list here (as in for-each): (map list '(a b c)) */ for (y = iterators; is_pair(y); y = cdr(y)) { s7_pointer x; x = s7_iterate(sc, car(y)); if (iterator_is_at_end(car(y))) { sc->value = safe_reverse_in_place(sc, counter_result(sc->args)); /* here and below it is not safe to pre-release sc->args (the counter) */ goto START; } sc->x = cons(sc, x, sc->x); } sc->x = safe_reverse_in_place(sc, sc->x); push_stack(sc, OP_MAP_GATHER, sc->args, sc->code); sc->args = sc->x; sc->x = sc->NIL; if (needs_copied_args(sc->code)) sc->args = copy_list(sc, sc->args); goto APPLY; } /* -------------------------------- FOR-EACH -------------------------------- */ case OP_FOR_EACH: { s7_pointer x, y, iterators, saved_args; iterators = car(sc->args); saved_args = cdr(sc->args); for (x = saved_args, y = iterators; is_pair(x); x = cdr(x), y = cdr(y)) { car(x) = s7_iterate(sc, car(y)); if (iterator_is_at_end(car(y))) { sc->value = sc->UNSPECIFIED; goto START; } } push_stack(sc, OP_FOR_EACH, sc->args, sc->code); sc->args = saved_args; if (needs_copied_args(sc->code)) sc->args = copy_list(sc, sc->args); goto APPLY; } /* for-each et al remake the local frame, but that's only needed if the local env is exported, * and that can only happen through make-closure in various guises and curlet. * owlet captures, but it would require a deliberate error to use it in this context. * c_objects call object_set_let but that requires a prior curlet or sublet. So we have * sc->capture_let_counter that is incremented every time an environment is captured, then * here we save that ctr, call body, on rerun check ctr, if it has not changed we are safe and can reuse frame. */ case OP_FOR_EACH_1: { s7_pointer code, counter, p, arg; counter = sc->args; p = counter_list(counter); arg = s7_iterate(sc, p); if (iterator_is_at_end(p)) { sc->value = sc->UNSPECIFIED; goto START; } code = sc->code; if (counter_capture(counter) != sc->capture_let_counter) { new_frame_with_slot(sc, closure_let(code), sc->envir, car(closure_args(code)), arg); counter_set_let(counter, sc->envir); counter_capture(counter) = sc->capture_let_counter; } else sc->envir = old_frame_with_slot(sc, counter_let(counter), arg); push_stack(sc, OP_FOR_EACH_1, counter, code); sc->code = closure_body(code); goto BEGIN1; } case OP_FOR_EACH_3: case OP_FOR_EACH_2: { s7_pointer code, c, lst, arg; c = sc->args; /* the counter */ lst = counter_list(c); if (!is_pair(lst)) /* '(1 2 . 3) as arg? */ { sc->value = sc->UNSPECIFIED; goto START; } code = sc->code; arg = car(lst); counter_list(c) = cdr(lst); if (sc->op == OP_FOR_EACH_3) { counter_result(c) = cdr(counter_result(c)); if (counter_result(c) == counter_list(c)) { sc->value = sc->UNSPECIFIED; goto START; } push_stack(sc, OP_FOR_EACH_2, c, code); } else push_stack(sc, OP_FOR_EACH_3, c, code); if (counter_capture(c) != sc->capture_let_counter) { new_frame_with_slot(sc, closure_let(code), sc->envir, car(closure_args(code)), arg); counter_set_let(c, sc->envir); counter_capture(c) = sc->capture_let_counter; } else sc->envir = old_frame_with_slot(sc, counter_let(c), arg); sc->code = closure_body(code); goto BEGIN1; } /* -------------------------------- MEMBER -------------------------------- */ case OP_MEMBER_IF: case OP_MEMBER_IF1: /* code=func, args = (list original args) with opt_fast->position in cadr (the list), value = result of comparison */ if (sc->value != sc->F) /* previous comparison was not #f -- return list */ { sc->value = opt_fast(sc->args); goto START; } if (!is_pair(cdr(opt_fast(sc->args)))) /* no more args -- return #f */ { sc->value = sc->F; goto START; } set_opt_fast(sc->args, cdr(opt_fast(sc->args))); /* cdr down arg list */ if (sc->op == OP_MEMBER_IF1) { /* circular list check */ if (opt_fast(sc->args) == opt_slow(sc->args)) { sc->value = sc->F; goto START; } set_opt_slow(sc->args, cdr(opt_slow(sc->args))); /* cdr down the slow list (check for circular list) */ push_stack(sc, OP_MEMBER_IF, sc->args, sc->code); } else push_stack(sc, OP_MEMBER_IF1, sc->args, sc->code); if (needs_copied_args(sc->code)) sc->args = list_2(sc, caar(sc->args), car(opt_fast(sc->args))); else sc->args = set_plist_2(sc, caar(sc->args), car(opt_fast(sc->args))); goto APPLY; /* -------------------------------- ASSOC -------------------------------- */ case OP_ASSOC_IF: case OP_ASSOC_IF1: /* code=func, args=(list args) with f/opt_fast=list, value=result of comparison * (assoc 3 '((1 . a) (2 . b) (3 . c) (4 . d)) =) */ if (sc->value != sc->F) /* previous comparison was not #f -- return (car list) */ { sc->value = car(opt_fast(sc->args)); goto START; } if (!is_pair(cdr(opt_fast(sc->args)))) /* (assoc 3 '((1 . 2) . 3) =) or nil */ { sc->value = sc->F; goto START; } set_opt_fast(sc->args, cdr(opt_fast(sc->args))); /* cdr down arg list */ if (sc->op == OP_ASSOC_IF1) { /* circular list check */ if (opt_fast(sc->args) == opt_slow(sc->args)) { sc->value = sc->F; goto START; } set_opt_slow(sc->args, cdr(opt_slow(sc->args))); /* cdr down the slow list */ push_stack(sc, OP_ASSOC_IF, sc->args, sc->code); } else push_stack(sc, OP_ASSOC_IF1, sc->args, sc->code); if (!is_pair(car(opt_fast(sc->args)))) /* (assoc 1 '((2 . 2) 3) =) -- we access caaadr below */ eval_type_error(sc, "assoc: second arg is not an alist: ~S", sc->args); /* not sure about this -- we could simply skip the entry both here and in g_assoc * (assoc 1 '((2 . 2) 3)) -> #f * (assoc 1 '((2 . 2) 3) =) -> error currently */ if (needs_copied_args(sc->code)) sc->args = list_2(sc, caar(sc->args), caar(opt_fast(sc->args))); else sc->args = set_plist_2(sc, caar(sc->args), caar(opt_fast(sc->args))); goto APPLY; /* -------------------------------- DO -------------------------------- */ SAFE_DOTIMES: case OP_SAFE_DOTIMES: { int choice; choice = safe_dotimes_ex(sc); if (choice == goto_SAFE_DO_END_CLAUSES) goto SAFE_DO_END_CLAUSES; if (choice == goto_BEGIN1) goto BEGIN1; if (choice == goto_OPT_EVAL) goto OPT_EVAL; if (choice == goto_START_WITHOUT_POP_STACK) goto START_WITHOUT_POP_STACK; pair_set_syntax_symbol(sc->code, sc->SIMPLE_DO); goto SIMPLE_DO; } case OP_SAFE_DOTIMES_STEP_P: { s7_pointer arg; arg = slot_value(sc->args); numerator(arg)++; if (numerator(arg) == denominator(arg)) { sc->code = cdr(cadr(sc->code)); goto DO_END_CLAUSES; } push_stack(sc, OP_SAFE_DOTIMES_STEP_P, sc->args, sc->code); sc->code = opt_pair2(sc->code); sc->op = (opcode_t)pair_syntax_op(sc->code); sc->code = cdr(sc->code); goto START_WITHOUT_POP_STACK; } case OP_SAFE_DOTIMES_STEP_O: { s7_pointer arg; arg = slot_value(sc->args); numerator(arg)++; if (numerator(arg) == denominator(arg)) { sc->code = cdr(cadr(sc->code)); goto DO_END_CLAUSES; } push_stack(sc, OP_SAFE_DOTIMES_STEP_O, sc->args, sc->code); sc->code = opt_pair2(sc->code); goto OPT_EVAL; } case OP_SAFE_DOTIMES_STEP_A: { s7_pointer arg; /* no calls?? */ arg = slot_value(sc->args); car(sc->T2_1) = arg; car(sc->T2_2) = sc->value; c_call(opt_pair2(sc->code))(sc, sc->T2_1); numerator(arg)++; if (numerator(arg) == denominator(arg)) { sc->code = cdr(cadr(sc->code)); goto DO_END_CLAUSES; } push_stack(sc, OP_SAFE_DOTIMES_STEP_A, sc->args, sc->code); sc->code = caddr(opt_pair2(sc->code)); goto OPT_EVAL; } case OP_SAFE_DOTIMES_STEP: { s7_pointer arg; arg = slot_value(sc->args); numerator(arg)++; if (numerator(arg) == denominator(arg)) { sc->code = cdr(cadr(sc->code)); goto DO_END_CLAUSES; } push_stack(sc, OP_SAFE_DOTIMES_STEP, sc->args, sc->code); arg = opt_pair2(sc->code); /* here we know the body has more than one form */ push_stack_no_args(sc, OP_BEGIN1, cdr(arg)); sc->code = car(arg); goto EVAL; } SAFE_DO: case OP_SAFE_DO: { int choice; choice = safe_do_ex(sc); if (choice == goto_SAFE_DO_END_CLAUSES) goto SAFE_DO_END_CLAUSES; if (choice == goto_EVAL) goto EVAL; if (choice == goto_DO_UNCHECKED) goto DO_UNCHECKED; goto BEGIN1; } case OP_SAFE_DO_STEP: { s7_int step, end; s7_pointer args, code, slot; args = sc->envir; code = sc->code; slot = dox_slot1(args); step = s7_integer(slot_value(slot)) + 1; slot_set_value(slot, make_integer(sc, step)); end = s7_integer(slot_value(dox_slot2(args))); if ((step == end) || ((step > end) && (opt_cfunc(caadr(code)) == geq_2))) { sc->code = cdadr(code); goto DO_END_CLAUSES; } push_stack(sc, OP_SAFE_DO_STEP, sc->args, code); sc->code = opt_pair2(code); goto BEGIN1; } SIMPLE_DO_P: case OP_SIMPLE_DO_P: sc->op = OP_SIMPLE_DO_P; goto SIMPLE_DO; SIMPLE_DO_E: case OP_SIMPLE_DO_E: sc->op = OP_SIMPLE_DO_E; goto SIMPLE_DO; SIMPLE_DO_A: case OP_SIMPLE_DO_A: sc->op = OP_SIMPLE_DO_A; SIMPLE_DO: case OP_SIMPLE_DO: { /* body might not be safe in this case, but the step and end exprs are easy * "not safe" merely means we hit something that the optimizer can't specialize like (+ (* (abs (- ...)))) */ s7_pointer init, end, code; code = sc->code; sc->envir = new_frame_in_env(sc, sc->envir); init = cadaar(code); if (is_symbol(init)) sc->value = find_symbol_checked(sc, init); else { if (is_pair(init)) sc->value = c_call(init)(sc, cdr(init)); else sc->value = init; } dox_set_slot1(sc->envir, make_slot_1(sc, sc->envir, caaar(code), sc->value)); end = caddr(caadr(code)); if (is_symbol(end)) sc->args = find_symbol(sc, end); else { s7_pointer slot; new_cell_no_check(sc, slot, T_SLOT); slot_set_symbol(slot, sc->dox_slot_symbol); slot_set_value(slot, end); sc->args = slot; } dox_set_slot2(sc->envir, sc->args); car(sc->T2_1) = slot_value(dox_slot1(sc->envir)); car(sc->T2_2) = slot_value(dox_slot2(sc->envir)); if (is_true(sc, c_call(caadr(code))(sc, sc->T2_1))) { sc->code = cdadr(code); goto DO_END_CLAUSES; } if (sc->op == OP_SIMPLE_DO_P) { push_stack(sc, OP_SIMPLE_DO_STEP_P, sc->args, code); sc->code = caddr(code); goto EVAL; } set_opt_pair2(code, cddr(code)); if ((is_null(cdr(opt_pair2(code)))) && (is_pair(car(opt_pair2(code)))) && (is_symbol(cadr(caddr(caar(code)))))) /* caar=(i 0 (+ i 1)), caddr=(+ i 1), so this is apparently checking that the stepf is reasonable? */ { int choice; choice = simple_do_ex(sc, code); if (choice == goto_START) goto START; if (choice == goto_BEGIN1) goto BEGIN1; if (choice == goto_DO_END_CLAUSES) goto DO_END_CLAUSES; } if (sc->op == OP_SIMPLE_DO_E) push_stack(sc, OP_SIMPLE_DO_STEP_E, sc->args, code); else { if (sc->op == OP_SIMPLE_DO_A) push_stack(sc, OP_SIMPLE_DO_STEP_A, sc->args, code); else push_stack(sc, OP_SIMPLE_DO_STEP, sc->args, code); } sc->code = opt_pair2(code); goto BEGIN1; } case OP_SIMPLE_DO_STEP_P: case OP_SIMPLE_DO_STEP: { s7_pointer step, ctr, end, code; ctr = dox_slot1(sc->envir); end = dox_slot2(sc->envir); code = sc->code; step = caddr(caar(code)); if (is_symbol(cadr(step))) { car(sc->T2_1) = slot_value(ctr); car(sc->T2_2) = caddr(step); } else { car(sc->T2_2) = slot_value(ctr); car(sc->T2_1) = cadr(step); } slot_set_value(ctr, c_call(step)(sc, sc->T2_1)); car(sc->T2_1) = slot_value(ctr); car(sc->T2_2) = slot_value(end); if (is_true(sc, c_call(caadr(code))(sc, sc->T2_1))) { sc->code = cdr(cadr(code)); goto DO_END_CLAUSES; } push_stack(sc, sc->op, sc->args, code); if (sc->op == OP_SIMPLE_DO_STEP_P) { code = caddr(code); sc->cur_code = code; sc->op = (opcode_t)pair_syntax_op(code); sc->code = cdr(code); goto START_WITHOUT_POP_STACK; } sc->code = opt_pair2(code); goto BEGIN1; } case OP_SIMPLE_DO_STEP_E: case OP_SIMPLE_DO_STEP_A: { /* (((i 0 (+ i 1))) ((= i 1000)) (set! mx (max mx (abs (f1 signal)))) (set! signal 0.0)) * (((i 0 (+ i 1))) ((= i 20)) (outa i (sine-env e))) * we checked in check_do that the step expr is s+1 */ s7_pointer val, ctr, end, code; s7_int index; code = sc->code; ctr = dox_slot1(sc->envir); val = slot_value(ctr); end = slot_value(dox_slot2(sc->envir)); if (is_integer(val)) { slot_set_value(ctr, make_integer(sc, index = integer(val) + 1)); if (is_integer(end)) { if (index == integer(end)) { sc->code = cdr(cadr(code)); goto DO_END_CLAUSES; } } else { car(sc->T2_1) = slot_value(ctr); car(sc->T2_2) = end; if (is_true(sc, g_equal_2(sc, sc->T2_1))) { sc->code = cdr(cadr(code)); goto DO_END_CLAUSES; } } } else { car(sc->T1_1) = val; /* add_s1 ignores cadr(args) */ slot_set_value(ctr, g_add_s1(sc, sc->T1_1)); car(sc->T2_1) = slot_value(ctr); car(sc->T2_2) = end; if (is_true(sc, g_equal_2(sc, sc->T2_1))) { sc->code = cdr(cadr(code)); goto DO_END_CLAUSES; } } push_stack(sc, sc->op, sc->args, code); if (sc->op == OP_SIMPLE_DO_STEP_E) { sc->code = car(opt_pair2(code)); goto OPT_EVAL; } sc->code = opt_pair2(code); goto BEGIN1; } DOTIMES_P: case OP_DOTIMES_P: { int choice; choice = dotimes_p_ex(sc); if (choice == goto_DO_END_CLAUSES) goto DO_END_CLAUSES; if (choice == goto_DO_UNCHECKED) goto DO_UNCHECKED; goto EVAL; } case OP_DOTIMES_STEP_P: { s7_pointer ctr, now, end, code, end_test; code = sc->code; ctr = dox_slot1(sc->envir); now = slot_value(ctr); end = slot_value(dox_slot2(sc->envir)); end_test = opt_pair2(code); if (is_integer(now)) { slot_set_value(ctr, make_integer(sc, integer(now) + 1)); now = slot_value(ctr); if (is_integer(end)) { if ((integer(now) == integer(end)) || ((integer(now) > integer(end)) && (opt_cfunc(end_test) == geq_2))) { sc->code = cdadr(code); goto DO_END_CLAUSES; } } else { car(sc->T2_1) = now; car(sc->T2_2) = end; if (is_true(sc, c_call(end_test)(sc, sc->T2_1))) { sc->code = cdadr(code); goto DO_END_CLAUSES; } } } else { car(sc->T1_1) = now; slot_set_value(ctr, g_add_s1(sc, sc->T1_1)); /* (define (hi) (let ((x 0.0) (y 1.0)) (do ((i y (+ i 1))) ((= i 6)) (do ((i i (+ i 1))) ((>= i 7)) (set! x (+ x i)))) x)) */ car(sc->T2_1) = slot_value(ctr); car(sc->T2_2) = end; if (is_true(sc, c_call(end_test)(sc, sc->T2_1))) { sc->code = cdadr(code); goto DO_END_CLAUSES; } } push_stack(sc, OP_DOTIMES_STEP_P, sc->args, code); code = caddr(code); sc->cur_code = code; sc->op = (opcode_t)pair_syntax_op(code); sc->code = cdr(code); goto START_WITHOUT_POP_STACK; } DOX: case OP_DOX: { int choice; choice = dox_ex(sc); if (choice == goto_DO_END_CLAUSES) goto DO_END_CLAUSES; if (choice == goto_START) goto START; if (choice == goto_BEGIN1) goto BEGIN1; if (choice == goto_START_WITHOUT_POP_STACK) goto START_WITHOUT_POP_STACK; push_stack_no_args(sc, OP_DOX_STEP, sc->code); sc->code = cddr(sc->code); goto BEGIN1; } case OP_DOX_STEP: { s7_pointer slot; for (slot = let_slots(sc->envir); is_slot(slot); slot = next_slot(slot)) if (is_pair(slot_expression(slot))) slot_set_value(slot, c_call(slot_expression(slot))(sc, car(slot_expression(slot)))); if (is_true(sc, c_call(cdr(sc->code))(sc, opt_pair2(sc->code)))) { sc->code = cdadr(sc->code); goto DO_END_CLAUSES; } push_stack_no_args(sc, OP_DOX_STEP, sc->code); sc->code = cddr(sc->code); goto BEGIN1; } case OP_DOX_STEP_P: { s7_pointer slot; for (slot = let_slots(sc->envir); is_slot(slot); slot = next_slot(slot)) if (is_pair(slot_expression(slot))) slot_set_value(slot, c_call(slot_expression(slot))(sc, car(slot_expression(slot)))); if (is_true(sc, c_call(cdr(sc->code))(sc, opt_pair2(sc->code)))) { sc->code = cdadr(sc->code); goto DO_END_CLAUSES; } push_stack_no_args(sc, OP_DOX_STEP_P, sc->code); sc->code = caddr(sc->code); sc->op = (opcode_t)pair_syntax_op(sc->code); sc->code = cdr(sc->code); goto START_WITHOUT_POP_STACK; } /* we could use slot_pending_value, slot_expression, not this extra list, but the list seems simpler. */ #define DO_VAR_SLOT(P) opt_slot1(P) #define DO_VAR_NEW_VALUE(P) cdr(P) #define DO_VAR_STEP_EXPR(P) car(P) DO_STEP: case OP_DO_STEP: /* increment all vars, return to endtest * these are also updated in parallel at the end, so we gather all the incremented values first * * here we know car(sc->args) is not null, args is the list of steppable vars, * any unstepped vars in the do var section are not in this list, so * (do ((i 0 (+ i 1)) (j 2)) ...) * arrives here with sc->args: * '(((+ i 1) . 0)) */ push_stack(sc, OP_DO_END, sc->args, sc->code); sc->args = car(sc->args); /* the var data lists */ sc->code = sc->args; /* save the top of the list */ DO_STEP1: /* on each iteration, each arg incr expr is evaluated and the value placed in caddr while we cdr down args * finally args is nil... */ if (is_null(sc->args)) { s7_pointer x; for (x = sc->code; is_not_null(x); x = cdr(x)) slot_set_value(DO_VAR_SLOT(car(x)), DO_VAR_NEW_VALUE(car(x))); /* some schemes rebind here, rather than reset, but that is expensive, * and only matters once in a blue moon (closure over enclosed lambda referring to a do var) * and the caller can easily mimic the correct behavior in that case by adding a let or using a named let, * making the rebinding explicit. * * Hmmm... I'll leave this alone, but there are other less cut-and-dried cases: * (let ((j (lambda () 0)) * (k 0)) * (do ((i (j) (j)) * (j (lambda () 1) (lambda () (+ i 1)))) ; bind here hits different "i" than set! * ((= i 3) k) * (set! k (+ k i)))) * is it 6 or 3? * * if we had a way to tell that there were no lambdas in the do expression, would that * guarantee that set was ok? Here's a bad case: * (let ((f #f)) * (do ((i 0 (+ i 1))) * ((= i 3)) * (let () ; so that the define is ok * (define (x) i) * (if (= i 1) (set! f x)))) * (f)) * s7 says 3, guile says 1. * * I wonder if what they're actually talking about is a kind of shared value problem. If we * set the value directly (not the cdr(binding) but, for example, integer(cdr(binding))), then * every previous reference gets changed as a side-effect. In the current code, we're "binding" * the value in the sense that on each step, a new value is assigned to the step variable. * In the "direct" case, (let ((v #(0 0 0))) (do ((i 0 (+ i 1))) ((= i 3) v) (set! (v i) i)) * would return #(3 3 3). * * if sc->capture_let_counter changes, would it be sufficient to simply make a new slot? * I think not; the closure retains the current env chain, not the slots, so we need a new env. */ sc->value = sc->NIL; pop_stack_no_op(sc); goto DO_END; } push_stack(sc, OP_DO_STEP2, sc->args, sc->code); /* here sc->args is a list like (((i . 0) (+ i 1) 0) ...) * so sc->code becomes (+ i 1) in this case */ sc->code = DO_VAR_STEP_EXPR(car(sc->args)); goto EVAL; case OP_DO_STEP2: DO_VAR_NEW_VALUE(car(sc->args)) = sc->value; /* save current value */ sc->args = cdr(sc->args); /* go to next step var */ goto DO_STEP1; case OP_DO: /* sc->code is the stuff after "do" */ if (is_null(check_do(sc))) { s7_pointer op; op = car(opt_back(sc->code)); if (op == sc->DOX) goto DOX; if (op == sc->SAFE_DOTIMES) goto SAFE_DOTIMES; if (op == sc->DOTIMES_P) goto DOTIMES_P; if (op == sc->SAFE_DO) goto SAFE_DO; if (op == sc->SIMPLE_DO_A) goto SIMPLE_DO_A; if (op == sc->SIMPLE_DO_E) goto SIMPLE_DO_E; if (op == sc->SIMPLE_DO) goto SIMPLE_DO; goto SIMPLE_DO_P; } DO_UNCHECKED: case OP_DO_UNCHECKED: if (is_null(car(sc->code))) /* (do () ...) -- (let ((i 0)) (do () ((= i 1)) (set! i 1))) */ { sc->envir = new_frame_in_env(sc, sc->envir); sc->args = cons_unchecked(sc, sc->NIL, cadr(sc->code)); sc->code = cddr(sc->code); goto DO_END; } /* eval each init value, then set up the new frame (like let, not let*) */ sc->args = sc->NIL; /* the evaluated var-data */ sc->value = sc->code; /* protect it */ sc->code = car(sc->code); /* the vars */ case OP_DO_INIT: if (do_init_ex(sc) == goto_EVAL) goto EVAL; /* fall through */ DO_END: case OP_DO_END: /* here vars have been init'd or incr'd * args = (list var-data end-expr return-expr-if-any) * if (do ((i 0 (+ i 1))) ((= i 3) 10)), args: (vars (= i 3) 10) * if (do ((i 0 (+ i 1))) ((= i 3))), args: (vars (= i 3)) and result expr is () == (begin) * if (do ((i 0 (+ i 1))) (#t 10 12)), args: (vars #t 10 12), result: ([begin] 10 12) -> 12 * if (call-with-exit (lambda (r) (do () () (r)))), args: '(()) * code = body */ if (is_not_null(cdr(sc->args))) { push_stack(sc, OP_DO_END1, sc->args, sc->code); sc->code = cadr(sc->args); /* evaluate the end expr */ goto EVAL; } else { /* (do ((...)) () ...) -- no endtest */ if (is_pair(sc->code)) { if (is_null(car(sc->args))) push_stack(sc, OP_DO_END, sc->args, sc->code); else push_stack(sc, OP_DO_STEP, sc->args, sc->code); goto BEGIN1; } else { /* no body? */ if (is_null(car(sc->args))) goto DO_END; goto DO_STEP; } } case OP_DO_END1: /* sc->value is the result of end-test evaluation */ if (is_true(sc, sc->value)) { /* we're done -- deal with result exprs * if there isn't an end test, there also isn't a result (they're in the same list) */ sc->code = cddr(sc->args); /* result expr (a list -- implicit begin) */ free_cell(sc, sc->args); sc->args = sc->NIL; if (is_null(sc->code)) { sc->value = sc->NIL; goto START; } } else { /* evaluate the body and step vars, etc */ if (is_null(car(sc->args))) push_stack(sc, OP_DO_END, sc->args, sc->code); else push_stack(sc, OP_DO_STEP, sc->args, sc->code); /* sc->code is ready to go */ } goto BEGIN1; SAFE_DO_END_CLAUSES: if (is_null(sc->code)) { /* sc->args = sc->NIL; */ sc->envir = free_let(sc, sc->envir); sc->value = sc->NIL; goto START; } goto DO_END_CODE; DO_END_CLAUSES: if (is_null(sc->code)) { sc->value = sc->NIL; goto START; } DO_END_CODE: if (is_pair(cdr(sc->code))) { push_stack_no_args(sc, OP_BEGIN1, cdr(sc->code)); sc->code = car(sc->code); goto EVAL; } sc->code = car(sc->code); if (is_pair(sc->code)) goto EVAL; if (is_symbol(sc->code)) sc->value = find_symbol_checked(sc, sc->code); else sc->value = sc->code; goto START; /* -------------------------------- BEGIN -------------------------------- */ case OP_BEGIN: if (!is_proper_list(sc, sc->code)) /* proper list includes nil, I think */ eval_error(sc, "unexpected dot? ~A", sc->code); if ((!is_null(sc->code)) && /* so check for it here */ (!is_null(cdr(sc->code))) && (is_overlaid(sc->code)) && (has_opt_back(sc->code))) pair_set_syntax_symbol(sc->code, sc->BEGIN_UNCHECKED); case OP_BEGIN_UNCHECKED: /* if ((sc->begin_hook) && (call_begin_hook(sc))) return(sc->F); */ if (is_null(sc->code)) /* (begin) -> () */ { sc->value = sc->NIL; goto START; } case OP_BEGIN1: if ((sc->begin_hook) && (call_begin_hook(sc))) return(sc->F); BEGIN1: #if DEBUGGING if (!s7_is_list(sc, sc->code)) abort(); #endif if (is_pair(cdr(sc->code))) /* sc->code can be nil here, but cdr(nil)-># */ push_stack_no_args(sc, OP_BEGIN1, cdr(sc->code)); sc->code = car(sc->code); /* goto EVAL; */ EVAL: case OP_EVAL: /* main part of evaluation * at this point, it's sc->code we care about; sc->args is not relevant. */ /* fprintf(stderr, " eval: %s %d %d\n", DISPLAY_80(sc->code), (typesflag(sc->code) == SYNTACTIC_PAIR), (is_optimized(sc->code))); */ if (typesflag(sc->code) == SYNTACTIC_PAIR) /* xor is not faster here */ { sc->cur_code = sc->code; /* in case an error occurs, this helps tell us where we are */ sc->op = (opcode_t)pair_syntax_op(sc->code); sc->code = cdr(sc->code); goto START_WITHOUT_POP_STACK; /* it is only slightly faster to use labels as values (computed gotos) here */ } if (is_optimized(sc->code)) { s7_pointer code; /* fprintf(stderr, " %s\n", opt_names[optimize_op(sc->code)]); */ OPT_EVAL: code = sc->code; sc->cur_code = code; switch (optimize_op(code)) { /* -------------------------------------------------------------------------------- */ case OP_SAFE_C_C: if (!c_function_is_ok(sc, code)) break; case HOP_SAFE_C_C: sc->value = c_call(code)(sc, cdr(code)); /* this includes all safe calls where all args are constants */ goto START; case OP_SAFE_C_Q: if (!c_function_is_ok(sc, code)) break; case HOP_SAFE_C_Q: car(sc->T1_1) = cadr(cadr(code)); sc->value = c_call(code)(sc, sc->T1_1); goto START; case OP_SAFE_C_S: if (!c_function_is_ok(sc, code)) break; case HOP_SAFE_C_S: car(sc->T1_1) = find_symbol_checked(sc, cadr(code)); sc->value = c_call(code)(sc, sc->T1_1); goto START; case OP_SAFE_C_SS: if (!c_function_is_ok(sc, code)) break; case HOP_SAFE_C_SS: { s7_pointer val, args; args = cdr(code); val = find_symbol_checked(sc, car(args)); car(sc->T2_2) = find_symbol_checked(sc, cadr(args)); car(sc->T2_1) = val; sc->value = c_call(code)(sc, sc->T2_1); goto START; } case OP_SAFE_C_ALL_S: if (!c_function_is_ok(sc, code)) break; case HOP_SAFE_C_ALL_S: { int num_args; s7_pointer args, p; num_args = integer(arglist_length(code)); if ((num_args != 0) && (num_args < NUM_SAFE_LISTS) && (!list_is_in_use(sc->safe_lists[num_args]))) { sc->args = sc->safe_lists[num_args]; set_list_in_use(sc->args); } else sc->args = make_list(sc, num_args, sc->NIL); for (args = cdr(code), p = sc->args; is_pair(args); args = cdr(args), p = cdr(p)) car(p) = find_symbol_checked(sc, car(args)); clear_list_in_use(sc->args); sc->value = c_call(code)(sc, sc->args); goto START; } case OP_SAFE_C_SC: if (!c_function_is_ok(sc, code)) break; case HOP_SAFE_C_SC: { s7_pointer args; args = cdr(code); car(sc->T2_1) = find_symbol_checked(sc, car(args)); car(sc->T2_2) = cadr(args); sc->value = c_call(code)(sc, sc->T2_1); goto START; } case OP_SAFE_C_CS: if (!c_function_is_ok(sc, code)) break; case HOP_SAFE_C_CS: { s7_pointer args; args = cdr(code); car(sc->T2_2) = find_symbol_checked(sc, cadr(args)); car(sc->T2_1) = car(args); sc->value = c_call(code)(sc, sc->T2_1); goto START; } case OP_SAFE_C_SQ: if (!c_function_is_ok(sc, code)) break; case HOP_SAFE_C_SQ: { s7_pointer args; args = cdr(code); car(sc->T2_1) = find_symbol_checked(sc, car(args)); car(sc->T2_2) = cadr(cadr(args)); sc->value = c_call(code)(sc, sc->T2_1); goto START; } case OP_SAFE_C_QS: if (!c_function_is_ok(sc, code)) break; case HOP_SAFE_C_QS: { s7_pointer args; args = cdr(code); car(sc->T2_2) = find_symbol_checked(sc, cadr(args)); car(sc->T2_1) = cadr(car(args)); sc->value = c_call(code)(sc, sc->T2_1); goto START; } case OP_SAFE_C_QQ: if (!c_function_is_ok(sc, code)) break; case HOP_SAFE_C_QQ: { s7_pointer args; args = cdr(code); car(sc->T2_1) = cadr(car(args)); car(sc->T2_2) = cadr(cadr(args)); sc->value = c_call(code)(sc, sc->T2_1); goto START; } case OP_SAFE_C_CQ: if (!c_function_is_ok(sc, code)) break; case HOP_SAFE_C_CQ: { s7_pointer args; args = cdr(code); car(sc->T2_1) = car(args); car(sc->T2_2) = cadr(cadr(args)); sc->value = c_call(code)(sc, sc->T2_1); goto START; } case OP_SAFE_C_QC: if (!c_function_is_ok(sc, code)) break; case HOP_SAFE_C_QC: { s7_pointer args; args = cdr(code); car(sc->T2_1) = cadr(car(args)); car(sc->T2_2) = cadr(args); sc->value = c_call(code)(sc, sc->T2_1); goto START; } case OP_SAFE_C_Z: if (!c_function_is_ok(sc, code)) break; /* I think a_is_ok of cadr here and below is redundant -- they'll be checked when Z is * because we cleared the hop bit after combine_ops. */ case HOP_SAFE_C_Z: check_stack_size(sc); push_stack(sc, OP_SAFE_C_P_1, sc->NIL, code); sc->code = cadr(code); goto OPT_EVAL; case OP_SAFE_C_CZ: if (!c_function_is_ok(sc, code)) break; case HOP_SAFE_C_CZ: check_stack_size(sc); /* it's possible in a case like this to overflow the stack -- s7test has a deeply * nested expression involving (+ c (+ c (+ ... ))) all opt'd as safe_c_cz -- if we're close * to the stack end at the start, it runs off the end. Normally the stack increase in * the reader protects us, but a call/cc can replace the original stack with a much smaller one. * How to minimize the cost of this check? */ push_stack(sc, OP_SAFE_C_SZ_1, cadr(code), code); sc->code = caddr(code); goto OPT_EVAL; case OP_SAFE_C_ZC: if (!c_function_is_ok(sc, code)) break; case HOP_SAFE_C_ZC: check_stack_size(sc); push_stack(sc, OP_SAFE_C_ZC_1, caddr(code), code); /* need ZC_1 here in case multiple values encountered */ sc->code = cadr(code); goto OPT_EVAL; case OP_SAFE_C_SZ: if (!c_function_is_ok(sc, code)) break; case HOP_SAFE_C_SZ: check_stack_size(sc); push_stack(sc, OP_SAFE_C_SZ_1, find_symbol_checked(sc, cadr(code)), code); sc->code = caddr(code); /* splitting out the all_x cases here and elsewhere saves nothing */ goto OPT_EVAL; case OP_SAFE_C_ZS: if (!c_function_is_ok(sc, code)) break; case HOP_SAFE_C_ZS: check_stack_size(sc); push_stack(sc, OP_EVAL_ARGS_P_3, sc->NIL, code); sc->code = cadr(code); goto OPT_EVAL; case OP_SAFE_C_opAq: if (!a_is_ok_cadr(sc, code)) break; case HOP_SAFE_C_opAq: { s7_pointer arg; arg = cadr(code); car(sc->A1_1) = c_call(cdr(arg))(sc, cadr(arg)); car(sc->T1_1) = c_call(arg)(sc, sc->A1_1); sc->value = c_call(code)(sc, sc->T1_1); goto START; } case OP_SAFE_C_opAAq: if (!a_is_ok_cadr(sc, code)) break; case HOP_SAFE_C_opAAq: { s7_pointer arg; arg = cadr(code); car(sc->A2_1) = c_call(cdr(arg))(sc, cadr(arg)); car(sc->A2_2) = c_call(cddr(arg))(sc, caddr(arg)); car(sc->T1_1) = c_call(arg)(sc, sc->A2_1); sc->value = c_call(code)(sc, sc->T1_1); goto START; } case OP_SAFE_C_opAAAq: if (!a_is_ok_cadr(sc, code)) break; case HOP_SAFE_C_opAAAq: { s7_pointer arg; arg = cadr(code); car(sc->A3_1) = c_call(cdr(arg))(sc, cadr(arg)); car(sc->A3_2) = c_call(cddr(arg))(sc, caddr(arg)); car(sc->A3_3) = c_call(cdddr(arg))(sc, cadddr(arg)); car(sc->T1_1) = c_call(arg)(sc, sc->A3_1); sc->value = c_call(code)(sc, sc->T1_1); goto START; } case OP_SAFE_C_S_opAq: if (!a_is_ok_caddr(sc, code)) break; case HOP_SAFE_C_S_opAq: { s7_pointer arg; arg = caddr(code); car(sc->A1_1) = c_call(cdr(arg))(sc, cadr(arg)); car(sc->T2_2) = c_call(arg)(sc, sc->A1_1); car(sc->T2_1) = find_symbol_checked(sc, cadr(code)); sc->value = c_call(code)(sc, sc->T2_1); goto START; } case OP_SAFE_C_S_opAAq: if (!a_is_ok_caddr(sc, code)) break; case HOP_SAFE_C_S_opAAq: { s7_pointer arg; arg = caddr(code); car(sc->A2_1) = c_call(cdr(arg))(sc, cadr(arg)); car(sc->A2_2) = c_call(cddr(arg))(sc, caddr(arg)); car(sc->T2_2) = c_call(arg)(sc, sc->A2_1); car(sc->T2_1) = find_symbol_checked(sc, cadr(code)); sc->value = c_call(code)(sc, sc->T2_1); goto START; } case OP_SAFE_C_S_opAAAq: if (!a_is_ok_caddr(sc, code)) break; case HOP_SAFE_C_S_opAAAq: { s7_pointer arg, p; p = caddr(code); arg = cdr(p); car(sc->A3_1) = c_call(arg)(sc, car(arg)); arg = cdr(arg); car(sc->A3_2) = c_call(arg)(sc, car(arg)); arg = cdr(arg); car(sc->A3_3) = c_call(arg)(sc, car(arg)); car(sc->T2_2) = c_call(p)(sc, sc->A3_1); car(sc->T2_1) = find_symbol_checked(sc, cadr(code)); sc->value = c_call(code)(sc, sc->T2_1); goto START; } case OP_SAFE_C_S_opSZq: if (!a_is_ok_caddr(sc, code)) break; case HOP_SAFE_C_S_opSZq: push_stack(sc, OP_SAFE_C_SZ_SZ, find_symbol_checked(sc, cadr(caddr(code))), code); sc->code = caddr(caddr(code)); goto OPT_EVAL; case OP_SAFE_C_AZ: if (!a_is_ok(sc, code)) break; case HOP_SAFE_C_AZ: push_stack(sc, OP_SAFE_C_SZ_1, c_call(cdr(code))(sc, cadr(code)), code); sc->code = caddr(code); goto OPT_EVAL; /* s: h_safe_c_s_op_s_opssqq: 204308 */ case OP_SAFE_C_ZA: if (!a_is_ok(sc, code)) break; case HOP_SAFE_C_ZA: /* here we can't use ZS order because we sometimes assume left->right arg evaluation (binary-io.scm for example) */ push_stack(sc, OP_SAFE_C_ZA_1, sc->NIL, code); sc->code = cadr(code); goto OPT_EVAL; case OP_SAFE_C_ZZ: if (!c_function_is_ok(sc, code)) break; case HOP_SAFE_C_ZZ: /* most of the component Z's here are very complex: * 264600: (+ (* even-amp (oscil (vector-ref evens k) (+ even-freq val))) (* odd-amp... */ push_stack(sc, OP_SAFE_C_ZZ_1, sc->NIL, code); sc->code = cadr(code); goto OPT_EVAL; case OP_SAFE_C_opCq_Z: if (!a_is_ok(sc, code)) break; case HOP_SAFE_C_opCq_Z: push_stack(sc, OP_SAFE_C_ZZ_2, c_call(cadr(code))(sc, cdr(cadr(code))), code); sc->code = caddr(code); goto OPT_EVAL; case OP_SAFE_C_ZAA: if (!a_is_ok(sc, code)) break; case HOP_SAFE_C_ZAA: push_stack(sc, OP_SAFE_C_ZAA_1, sc->NIL, code); sc->code = cadr(code); goto OPT_EVAL; case OP_SAFE_C_AZA: if (!a_is_ok(sc, code)) break; case HOP_SAFE_C_AZA: push_stack(sc, OP_SAFE_C_AZA_1, c_call(cdr(code))(sc, cadr(code)), code); sc->code = caddr(code); goto OPT_EVAL; case OP_SAFE_C_SSZ: if (!c_function_is_ok(sc, code)) break; case HOP_SAFE_C_SSZ: push_stack(sc, OP_SAFE_C_SSZ_1, find_symbol_checked(sc, cadr(code)), code); sc->code = cadddr(code); goto OPT_EVAL; case OP_SAFE_C_AAZ: if (!a_is_ok(sc, code)) break; case HOP_SAFE_C_AAZ: push_op_stack(sc, c_call(cdr(code))(sc, cadr(code))); push_stack(sc, OP_SAFE_C_AAZ_1, c_call(cddr(code))(sc, caddr(code)), code); sc->code = cadddr(code); goto OPT_EVAL; case OP_SAFE_C_ZZA: if (!a_is_ok(sc, code)) break; case HOP_SAFE_C_ZZA: push_stack(sc, OP_SAFE_C_ZZA_1, sc->NIL, code); sc->code = cadr(code); goto OPT_EVAL; case OP_SAFE_C_ZAZ: if (!a_is_ok(sc, code)) break; case HOP_SAFE_C_ZAZ: push_stack(sc, OP_SAFE_C_ZAZ_1, sc->NIL, code); sc->code = cadr(code); goto OPT_EVAL; case OP_SAFE_C_AZZ: if (!a_is_ok(sc, code)) break; case HOP_SAFE_C_AZZ: push_stack(sc, OP_SAFE_C_AZZ_1, c_call(cdr(code))(sc, cadr(code)), code); sc->code = caddr(code); goto OPT_EVAL; case OP_SAFE_C_ZZZ: if (!c_function_is_ok(sc, code)) break; case HOP_SAFE_C_ZZZ: push_stack(sc, OP_SAFE_C_ZZZ_1, sc->NIL, code); sc->code = cadr(code); goto OPT_EVAL; case OP_SAFE_C_A: if (!a_is_ok_cadr(sc, code)) break; case HOP_SAFE_C_A: car(sc->A1_1) = c_call(cdr(code))(sc, cadr(code)); sc->value = c_call(code)(sc, sc->A1_1); goto START; case OP_SAFE_C_AA: if (!a_is_ok(sc, code)) break; case HOP_SAFE_C_AA: car(sc->A2_1) = c_call(cdr(code))(sc, cadr(code)); car(sc->A2_2) = c_call(cddr(code))(sc, caddr(code)); sc->value = c_call(code)(sc, sc->A2_1); goto START; case OP_SAFE_C_AAA: if (!a_is_ok(sc, code)) break; case HOP_SAFE_C_AAA: { s7_pointer arg; arg = cdr(code); car(sc->A3_1) = c_call(arg)(sc, car(arg)); arg = cdr(arg); car(sc->A3_2) = c_call(arg)(sc, car(arg)); arg = cdr(arg); car(sc->A3_3) = c_call(arg)(sc, car(arg)); sc->value = c_call(code)(sc, sc->A3_1); goto START; } case OP_SAFE_C_SSA: if (!a_is_ok_cadddr(sc, code)) break; case HOP_SAFE_C_SSA: { s7_pointer arg; arg = cdr(code); car(sc->A3_1) = find_symbol_checked(sc, car(arg)); arg = cdr(arg); car(sc->A3_2) = find_symbol_checked(sc, car(arg)); arg = cdr(arg); car(sc->A3_3) = c_call(arg)(sc, car(arg)); sc->value = c_call(code)(sc, sc->A3_1); goto START; } case OP_SAFE_C_SAS: if (!a_is_ok_caddr(sc, code)) break; case HOP_SAFE_C_SAS: { s7_pointer arg; arg = cdr(code); car(sc->A3_1) = find_symbol_checked(sc, car(arg)); arg = cdr(arg); car(sc->A3_2) = c_call(arg)(sc, car(arg)); arg = cdr(arg); car(sc->A3_3) = find_symbol_checked(sc, car(arg)); sc->value = c_call(code)(sc, sc->A3_1); goto START; } case OP_SAFE_C_CSA: if (!a_is_ok_cadddr(sc, code)) break; case HOP_SAFE_C_CSA: { s7_pointer arg; arg = cdr(code); car(sc->A3_1) = car(arg); arg = cdr(arg); car(sc->A3_2) = find_symbol_checked(sc, car(arg)); arg = cdr(arg); car(sc->A3_3) = c_call(arg)(sc, car(arg)); sc->value = c_call(code)(sc, sc->A3_1); goto START; } case OP_SAFE_C_SCA: if (!a_is_ok_cadddr(sc, code)) break; case HOP_SAFE_C_SCA: { s7_pointer arg; arg = cdr(code); car(sc->A3_1) = find_symbol_checked(sc, car(arg)); arg = cdr(arg); car(sc->A3_2) = car(arg); arg = cdr(arg); car(sc->A3_3) = c_call(arg)(sc, car(arg)); sc->value = c_call(code)(sc, sc->A3_1); goto START; } case OP_SAFE_C_CAS: if (!a_is_ok_caddr(sc, code)) break; case HOP_SAFE_C_CAS: { s7_pointer arg; arg = cdr(code); car(sc->A3_1) = car(arg); arg = cdr(arg); car(sc->A3_2) = c_call(arg)(sc, car(arg)); car(sc->A3_3) = find_symbol_checked(sc, cadr(arg)); sc->value = c_call(code)(sc, sc->A3_1); goto START; } case OP_SAFE_C_AAAA: if (!a_is_ok(sc, code)) break; case HOP_SAFE_C_AAAA: { s7_pointer arg; arg = cdr(code); car(sc->A4_1) = c_call(arg)(sc, car(arg)); arg = cdr(arg); car(sc->A4_2) = c_call(arg)(sc, car(arg)); arg = cdr(arg); car(sc->A4_3) = c_call(arg)(sc, car(arg)); arg = cdr(arg); car(sc->A4_4) = c_call(arg)(sc, car(arg)); sc->value = c_call(code)(sc, sc->A4_1); goto START; } case OP_SAFE_C_ALL_X: if (!a_is_ok(sc, code)) break; case HOP_SAFE_C_ALL_X: { int num_args; s7_pointer args, p; num_args = integer(arglist_length(code)); if ((num_args != 0) && (num_args < NUM_SAFE_LISTS) && (!list_is_in_use(sc->safe_lists[num_args]))) { sc->args = sc->safe_lists[num_args]; set_list_in_use(sc->args); } else sc->args = make_list(sc, num_args, sc->NIL); for (args = cdr(code), p = sc->args; is_pair(args); args = cdr(args), p = cdr(p)) car(p) = c_call(args)(sc, car(args)); clear_list_in_use(sc->args); sc->value = c_call(code)(sc, sc->args); /* we can't release a temp here: * (define (hi) (vector 14800 14020 (oscil os) (* 1/3 14800) 14800 (* 1/2 14800))) (hi) where os returns non-zero: * #(14800 14020 14800/3 14800 7400) */ goto START; } case OP_SAFE_C_SQS: if (!c_function_is_ok(sc, code)) break; case HOP_SAFE_C_SQS: { /* (let-set! gen 'fm fm); many of these are handled in safe_closure_star_s0 */ s7_pointer val1, args; args = cdr(code); val1 = find_symbol_checked(sc, car(args)); car(sc->T3_3) = find_symbol_checked(sc, opt_sym2(args)); car(sc->T3_2) = opt_con1(args); car(sc->T3_1) = val1; sc->value = c_call(code)(sc, sc->T3_1); goto START; } case OP_SAFE_C_SCS: if (!c_function_is_ok(sc, code)) break; case HOP_SAFE_C_SCS: { /* (define (hi) (let ((x 32) (lst '(0 1))) (list-set! lst 0 x) x)) */ s7_pointer val1, args; args = cdr(code); val1 = find_symbol_checked(sc, car(args)); car(sc->T3_3) = find_symbol_checked(sc, opt_sym2(args)); car(sc->T3_2) = opt_con1(args); car(sc->T3_1) = val1; sc->value = c_call(code)(sc, sc->T3_1); goto START; } case OP_SAFE_C_SSC: if (!c_function_is_ok(sc, code)) break; case HOP_SAFE_C_SSC: { /* (define (hi) (let ((v #(0 1 2)) (i 0)) (vector-set! v i 1) v)) */ s7_pointer val1, args; args = cdr(code); val1 = find_symbol_checked(sc, car(args)); car(sc->T3_2) = find_symbol_checked(sc, opt_sym1(args)); car(sc->T3_3) = opt_con2(args); car(sc->T3_1) = val1; sc->value = c_call(code)(sc, sc->T3_1); goto START; } case OP_SAFE_C_SCC: if (!c_function_is_ok(sc, code)) break; case HOP_SAFE_C_SCC: { /* (make-env E :length 100) */ s7_pointer args; args = cdr(code); car(sc->T3_1) = find_symbol_checked(sc, car(args)); car(sc->T3_2) = opt_con1(args); car(sc->T3_3) = opt_con2(args); sc->value = c_call(code)(sc, sc->T3_1); goto START; } case OP_SAFE_C_CSC: if (!c_function_is_ok(sc, code)) break; case HOP_SAFE_C_CSC: { s7_pointer args; args = cdr(code); car(sc->T3_2) = find_symbol_checked(sc, opt_sym1(args)); car(sc->T3_1) = car(args); car(sc->T3_3) = opt_con2(args); sc->value = c_call(code)(sc, sc->T3_1); goto START; } case OP_SAFE_C_CSS: if (!c_function_is_ok(sc, code)) break; case HOP_SAFE_C_CSS: { s7_pointer val1, args; args = cdr(code); val1 = find_symbol_checked(sc, opt_sym2(args)); car(sc->T3_2) = find_symbol_checked(sc, opt_sym1(args)); car(sc->T3_3) = val1; car(sc->T3_1) = car(args); sc->value = c_call(code)(sc, sc->T3_1); goto START; } case OP_SAFE_C_SSS: if (!c_function_is_ok(sc, code)) break; case HOP_SAFE_C_SSS: { s7_pointer val1, val2, args; args = cdr(code); val1 = find_symbol_checked(sc, car(args)); val2 = find_symbol_checked(sc, opt_sym1(args)); car(sc->T3_3) = find_symbol_checked(sc, opt_sym2(args)); car(sc->T3_1) = val1; car(sc->T3_2) = val2; sc->value = c_call(code)(sc, sc->T3_1); goto START; } case OP_SAFE_C_opCq: if (!c_function_is_ok_cadr(sc, code)) break; case HOP_SAFE_C_opCq: car(sc->T1_1) = c_call(car(cdr(code)))(sc, cdar(cdr(code))); /* OP_SAFE_C_C can involve any number of ops */ sc->value = c_call(code)(sc, sc->T1_1); goto START; case OP_SAFE_C_opSq: if (!c_function_is_ok_cadr(sc, code)) break; case HOP_SAFE_C_opSq: { s7_pointer args; args = cadr(code); car(sc->T1_1) = find_symbol_checked(sc, cadr(args)); car(sc->T1_1) = c_call(args)(sc, sc->T1_1); sc->value = c_call(code)(sc, sc->T1_1); goto START; } case OP_SAFE_C_op_opSq_q: if ((!c_function_is_ok(sc, code)) || (!c_function_is_ok(sc, cadr(code))) || (!c_function_is_ok(sc, cadr(cadr(code))))) break; case HOP_SAFE_C_op_opSq_q: { s7_pointer outer, args; outer = cadr(code); args = cadr(outer); car(sc->T1_1) = find_symbol_checked(sc, cadr(args)); car(sc->T1_1) = c_call(args)(sc, sc->T1_1); car(sc->T1_1) = c_call(outer)(sc, sc->T1_1); sc->value = c_call(code)(sc, sc->T1_1); goto START; } case OP_SAFE_C_op_S_opSq_q: if ((!c_function_is_ok(sc, code)) || (!c_function_is_ok(sc, cadr(code))) || (!c_function_is_ok(sc, caddr(cadr(code))))) break; case HOP_SAFE_C_op_S_opSq_q: { /* (exp (* r (cos x))) */ s7_pointer outer, args; outer = cadr(code); args = caddr(outer); car(sc->T1_1) = find_symbol_checked(sc, cadr(args)); car(sc->T2_2) = c_call(args)(sc, sc->T1_1); car(sc->T2_1) = find_symbol_checked(sc, cadr(outer)); car(sc->T1_1) = c_call(outer)(sc, sc->T2_1); sc->value = c_call(code)(sc, sc->T1_1); goto START; } case OP_SAFE_C_PS: if (!c_function_is_ok(sc, code)) break; case HOP_SAFE_C_PS: push_stack(sc, OP_EVAL_ARGS_P_3, sc->NIL, code); /* gotta wait in this case */ sc->code = cadr(code); goto EVAL; case OP_SAFE_C_PC: if (!c_function_is_ok(sc, code)) break; case HOP_SAFE_C_PC: push_stack(sc, OP_EVAL_ARGS_P_4, caddr(code), code); sc->code = cadr(code); goto EVAL; case OP_SAFE_C_PQ: if (!c_function_is_ok(sc, code)) break; case HOP_SAFE_C_PQ: push_stack(sc, OP_EVAL_ARGS_P_4, cadr(caddr(code)), code); /* was P_5, but that's the same as P_4 */ sc->code = cadr(code); goto EVAL; case OP_SAFE_C_SP: if (!c_function_is_ok(sc, code)) break; case HOP_SAFE_C_SP: push_stack(sc, OP_EVAL_ARGS_P_2, find_symbol_checked(sc, cadr(code)), code); sc->code = caddr(code); goto EVAL; case OP_SAFE_C_AP: if ((!c_function_is_ok(sc, code)) || (!a_is_ok(sc, cadr(code)))) break; case HOP_SAFE_C_AP: push_stack(sc, OP_EVAL_ARGS_P_2, c_call(cdr(code))(sc, cadr(code)), code); sc->code = caddr(code); goto EVAL; case OP_SAFE_C_CP: if (!c_function_is_ok(sc, code)) break; case HOP_SAFE_C_CP: push_stack(sc, OP_EVAL_ARGS_P_2, cadr(code), code); sc->code = caddr(code); goto EVAL; case OP_SAFE_C_QP: if (!c_function_is_ok(sc, code)) break; case HOP_SAFE_C_QP: push_stack(sc, OP_EVAL_ARGS_P_2, cadr(cadr(code)), code); sc->code = caddr(code); goto EVAL; case OP_SAFE_C_PP: if (!c_function_is_ok(sc, code)) break; case HOP_SAFE_C_PP: push_stack(sc, OP_SAFE_C_PP_1, sc->NIL, code); sc->code = cadr(code); goto EVAL; case OP_SAFE_C_SSP: if (!c_function_is_ok(sc, code)) break; case HOP_SAFE_C_SSP: push_stack(sc, OP_EVAL_ARGS_SSP_1, sc->NIL, code); sc->code = cadddr(code); goto EVAL; case OP_SAFE_C_opSSq: if (!c_function_is_ok_cadr(sc, code)) break; case HOP_SAFE_C_opSSq: { s7_pointer args, val1; args = cadr(code); val1 = find_symbol_checked(sc, cadr(args)); car(sc->T2_2) = find_symbol_checked(sc, caddr(args)); car(sc->T2_1) = val1; car(sc->T1_1) = c_call(args)(sc, sc->T2_1); sc->value = c_call(code)(sc, sc->T1_1); goto START; } case OP_SAFE_C_opSCq: if (!c_function_is_ok_cadr(sc, code)) break; case HOP_SAFE_C_opSCq: { s7_pointer args; args = cadr(code); car(sc->T2_1) = find_symbol_checked(sc, cadr(args)); car(sc->T2_2) = caddr(args); car(sc->T1_1) = c_call(args)(sc, sc->T2_1); sc->value = c_call(code)(sc, sc->T1_1); goto START; } case OP_SAFE_C_opCSq: if (!c_function_is_ok_cadr(sc, code)) break; case HOP_SAFE_C_opCSq: { s7_pointer args; args = cadr(code); car(sc->T2_2) = find_symbol_checked(sc, caddr(args)); car(sc->T2_1) = cadr(args); car(sc->T1_1) = c_call(args)(sc, sc->T2_1); sc->value = c_call(code)(sc, sc->T1_1); goto START; } case OP_SAFE_C_opSQq: if (!c_function_is_ok_cadr(sc, code)) break; case HOP_SAFE_C_opSQq: { s7_pointer args; args = cadr(code); car(sc->T2_1) = find_symbol_checked(sc, cadr(args)); car(sc->T2_2) = cadr(caddr(args)); car(sc->T1_1) = c_call(args)(sc, sc->T2_1); sc->value = c_call(code)(sc, sc->T1_1); goto START; } case OP_SAFE_C_S_opSq: if (!c_function_is_ok_caddr(sc, code)) break; case HOP_SAFE_C_S_opSq: { s7_pointer args, val; args = cdr(code); val = find_symbol_checked(sc, car(args)); car(sc->T1_1) = find_symbol_checked(sc, opt_sym1(args)); car(sc->T2_2) = c_call(cadr(args))(sc, sc->T1_1); car(sc->T2_1) = val; sc->value = c_call(code)(sc, sc->T2_1); goto START; } case OP_SAFE_C_S_opCq: if (!c_function_is_ok_caddr(sc, code))break; case HOP_SAFE_C_S_opCq: { s7_pointer args, val; args = cdr(code); val = find_symbol_checked(sc, car(args)); car(sc->T2_2) = c_call(cadr(args))(sc, opt_pair1(args)); /* any number of constants here */ car(sc->T2_1) = val; sc->value = c_call(code)(sc, sc->T2_1); goto START; } case OP_SAFE_C_C_opSq: if (!c_function_is_ok_caddr(sc, code)) break; case HOP_SAFE_C_C_opSq: { s7_pointer args; args = cdr(code); car(sc->T1_1) = find_symbol_checked(sc, opt_sym1(args)); car(sc->T2_2) = c_call(cadr(args))(sc, sc->T1_1); car(sc->T2_1) = car(args); sc->value = c_call(code)(sc, sc->T2_1); goto START; } case OP_SAFE_C_C_opCq: if (!c_function_is_ok_caddr(sc, code)) break; case HOP_SAFE_C_C_opCq: { s7_pointer args; args = cdr(code); car(sc->T2_2) = c_call(cadr(args))(sc, opt_pair1(args)); /* any # of args */ car(sc->T2_1) = car(args); sc->value = c_call(code)(sc, sc->T2_1); goto START; } case OP_SAFE_C_C_opCSq: if (!c_function_is_ok_caddr(sc, code)) break; case HOP_SAFE_C_C_opCSq: { s7_pointer args; args = cdr(code); car(sc->T2_2) = find_symbol_checked(sc, opt_sym2(args)); car(sc->T2_1) = opt_con1(args); car(sc->T2_2) = c_call(cadr(args))(sc, sc->T2_1); car(sc->T2_1) = car(args); sc->value = c_call(code)(sc, sc->T2_1); goto START; } case OP_SAFE_C_C_opSSq: if (!c_function_is_ok_caddr(sc, code)) break; case HOP_SAFE_C_C_opSSq: { s7_pointer args, val; args = cdr(code); val = find_symbol_checked(sc, opt_sym1(args)); car(sc->T2_2) = find_symbol_checked(sc, opt_sym2(args)); car(sc->T2_1) = val; car(sc->T2_2) = c_call(cadr(args))(sc, sc->T2_1); car(sc->T2_1) = car(args); sc->value = c_call(code)(sc, sc->T2_1); goto START; } case OP_SAFE_C_opCSq_C: if (!c_function_is_ok_cadr(sc, code)) break; case HOP_SAFE_C_opCSq_C: { s7_pointer args; args = cdr(code); car(sc->T2_2) = find_symbol_checked(sc, caddr(car(args))); car(sc->T2_1) = cadr(car(args)); car(sc->T2_1) = c_call(car(args))(sc, sc->T2_1); car(sc->T2_2) = cadr(args); sc->value = c_call(code)(sc, sc->T2_1); goto START; } case OP_SAFE_C_opSSq_C: if (!c_function_is_ok_cadr(sc, code)) break; case HOP_SAFE_C_opSSq_C: { s7_pointer args, val; args = cdr(code); val = find_symbol_checked(sc, cadr(car(args))); car(sc->T2_2) = find_symbol_checked(sc, caddr(car(args))); car(sc->T2_1) = val; car(sc->T2_1) = c_call(car(args))(sc, sc->T2_1); car(sc->T2_2) = cadr(args); sc->value = c_call(code)(sc, sc->T2_1); goto START; } case OP_SAFE_C_opSSq_S: if (!c_function_is_ok_cadr(sc, code)) break; case HOP_SAFE_C_opSSq_S: { s7_pointer args, val, val1; args = cdr(code); val = find_symbol_checked(sc, cadr(car(args))); val1 = find_symbol_checked(sc, cadr(args)); car(sc->T2_2) = find_symbol_checked(sc, caddr(car(args))); car(sc->T2_1) = val; car(sc->T2_1) = c_call(car(args))(sc, sc->T2_1); car(sc->T2_2) = val1; sc->value = c_call(code)(sc, sc->T2_1); goto START; } case OP_SAFE_C_op_opSSq_q_C: if ((!c_function_is_ok(sc, code)) || (!c_function_is_ok(sc, cadr(code))) || (!c_function_is_ok(sc, cadr(cadr(code))))) break; case HOP_SAFE_C_op_opSSq_q_C: { /* code: (> (magnitude (- old new)) 0.001) */ s7_pointer arg; arg = cadr(cadr(code)); car(sc->T2_1) = find_symbol_checked(sc, cadr(arg)); car(sc->T2_2) = find_symbol_checked(sc, caddr(arg)); car(sc->T1_1) = c_call(arg)(sc, sc->T2_1); car(sc->T2_1) = c_call(cadr(code))(sc, sc->T1_1); car(sc->T2_2) = caddr(code); sc->value = c_call(code)(sc, sc->T2_1); goto START; } case OP_SAFE_C_op_opSSq_q_S: if ((!c_function_is_ok(sc, code)) || (!c_function_is_ok(sc, cadr(code))) || (!c_function_is_ok(sc, cadr(cadr(code))))) break; case HOP_SAFE_C_op_opSSq_q_S: { /* code: (> (magnitude (- old new)) s) */ s7_pointer arg; arg = cadr(cadr(code)); car(sc->T2_1) = find_symbol_checked(sc, cadr(arg)); car(sc->T2_2) = find_symbol_checked(sc, caddr(arg)); car(sc->T1_1) = c_call(arg)(sc, sc->T2_1); car(sc->T2_1) = c_call(cadr(code))(sc, sc->T1_1); car(sc->T2_2) = find_symbol_checked(sc, caddr(code)); sc->value = c_call(code)(sc, sc->T2_1); goto START; } case OP_SAFE_C_op_opSq_q_C: if ((!c_function_is_ok(sc, code)) || (!c_function_is_ok(sc, cadr(code))) || (!c_function_is_ok(sc, cadr(cadr(code))))) break; case HOP_SAFE_C_op_opSq_q_C: { s7_pointer arg; arg = cadr(cadr(code)); car(sc->T1_1) = find_symbol_checked(sc, cadr(arg)); car(sc->T1_1) = c_call(arg)(sc, sc->T1_1); car(sc->T2_1) = c_call(cadr(code))(sc, sc->T1_1); car(sc->T2_2) = caddr(code); sc->value = c_call(code)(sc, sc->T2_1); goto START; } case OP_SAFE_C_op_opSq_q_S: if ((!c_function_is_ok(sc, code)) || (!c_function_is_ok(sc, cadr(code))) || (!c_function_is_ok(sc, cadr(cadr(code))))) break; case HOP_SAFE_C_op_opSq_q_S: { s7_pointer arg; arg = cadr(cadr(code)); car(sc->T1_1) = find_symbol_checked(sc, cadr(arg)); car(sc->T1_1) = c_call(arg)(sc, sc->T1_1); car(sc->T2_1) = c_call(cadr(code))(sc, sc->T1_1); car(sc->T2_2) = find_symbol_checked(sc, caddr(code)); sc->value = c_call(code)(sc, sc->T2_1); goto START; } case OP_SAFE_C_S_op_opSSq_Sq: if ((!c_function_is_ok(sc, code)) || (!c_function_is_ok(sc, caddr(code))) || (!c_function_is_ok(sc, cadr(caddr(code))))) break; case HOP_SAFE_C_S_op_opSSq_Sq: { /* (let () (define (hi a b c d) (+ a (* (- b c) d))) (define (ho) (hi 1 2 3 4)) (ho)) * or actually... (oscil fmosc1 (+ (* fm1-rat vib) fuzz)) * and that is then packaged as opCq...: (* (env indf1) (oscil fmosc1 (+ (* fm1-rat vib) fuzz))) * and that is then (+ ...) * but now this is handled in clm2xen.c */ s7_pointer args, val, val1; args = caddr(code); /* (* (- b c) d) */ val1 = cadr(args); val = find_symbol_checked(sc, cadr(val1)); /* b */ car(sc->T2_2) = find_symbol_checked(sc, caddr(val1)); /* c */ car(sc->T2_1) = val; val = find_symbol_checked(sc, caddr(args)); /* d */ car(sc->T2_1) = c_call(val1)(sc, sc->T2_1); /* (- b c) */ car(sc->T2_2) = val; car(sc->T2_2) = c_call(args)(sc, sc->T2_1); /* (* ...) */ car(sc->T2_1) = find_symbol_checked(sc, cadr(code)); /* a */ sc->value = c_call(code)(sc, sc->T2_1); /* (+ ...) */ goto START; } case OP_SAFE_C_S_op_S_opSSqq: if ((!c_function_is_ok(sc, code)) || (!c_function_is_ok(sc, caddr(code))) || (!c_function_is_ok(sc, caddr(caddr(code))))) break; case HOP_SAFE_C_S_op_S_opSSqq: { /* (let () (define (hi a b c d) (+ a (* d (- b c)))) (define (ho) (hi 1 2 3 4)) (ho)) */ s7_pointer args, val, val1; args = caddr(code); /* (* d (- b c)) */ val1 = caddr(args); val = find_symbol_checked(sc, cadr(val1)); /* b */ car(sc->T2_2) = find_symbol_checked(sc, caddr(val1)); /* c */ car(sc->T2_1) = val; val = find_symbol_checked(sc, cadr(args)); /* d */ car(sc->T2_2) = c_call(val1)(sc, sc->T2_1); /* (- b c) */ car(sc->T2_1) = val; car(sc->T2_2) = c_call(args)(sc, sc->T2_1); /* (* ...) */ car(sc->T2_1) = find_symbol_checked(sc, cadr(code)); /* a */ sc->value = c_call(code)(sc, sc->T2_1); /* (+ ...) */ goto START; } case OP_SAFE_C_S_op_opSSq_opSSqq: if (!a_is_ok(sc, code)) break; case HOP_SAFE_C_S_op_opSSq_opSSqq: { /* (* s (f3 (f1 a b) (f2 c d))) */ s7_pointer args, f1, op1, op2; args = caddr(code); op1 = cadr(args); op2 = caddr(args); car(sc->T2_1) = find_symbol_checked(sc, cadr(op1)); car(sc->T2_2) = find_symbol_checked(sc, caddr(op1)); f1 = c_call(op1)(sc, sc->T2_1); car(sc->T2_1) = find_symbol_checked(sc, cadr(op2)); car(sc->T2_2) = find_symbol_checked(sc, caddr(op2)); car(sc->T2_2) = c_call(op2)(sc, sc->T2_1); car(sc->T2_1) = f1; car(sc->T2_2) = c_call(args)(sc, sc->T2_1); car(sc->T2_1) = find_symbol_checked(sc, cadr(code)); sc->value = c_call(code)(sc, sc->T2_1); goto START; } case OP_SAFE_C_opSCq_S: if (!c_function_is_ok_cadr(sc, code)) break; case HOP_SAFE_C_opSCq_S: { s7_pointer args, val1; args = cdr(code); val1 = find_symbol_checked(sc, cadr(args)); car(sc->T2_1) = find_symbol_checked(sc, cadr(car(args))); car(sc->T2_2) = caddr(car(args)); car(sc->T2_1) = c_call(car(args))(sc, sc->T2_1); car(sc->T2_2) = val1; sc->value = c_call(code)(sc, sc->T2_1); goto START; } case OP_SAFE_C_opSCq_C: if (!c_function_is_ok_cadr(sc, code)) break; case HOP_SAFE_C_opSCq_C: { s7_pointer args; args = cdr(code); car(sc->T2_1) = find_symbol_checked(sc, cadr(car(args))); car(sc->T2_2) = caddr(car(args)); car(sc->T2_1) = c_call(car(args))(sc, sc->T2_1); car(sc->T2_2) = cadr(args); sc->value = c_call(code)(sc, sc->T2_1); goto START; } case OP_SAFE_C_opCSq_S: if (!c_function_is_ok_cadr(sc, code)) break; case HOP_SAFE_C_opCSq_S: { s7_pointer args, val1; args = cdr(code); val1 = find_symbol_checked(sc, cadr(args)); car(sc->T2_2) = find_symbol_checked(sc, caddr(car(args))); car(sc->T2_1) = cadr(car(args)); car(sc->T2_1) = c_call(car(args))(sc, sc->T2_1); car(sc->T2_2) = val1; sc->value = c_call(code)(sc, sc->T2_1); goto START; } case OP_SAFE_C_S_opSCq: if (!c_function_is_ok_caddr(sc, code)) break; case HOP_SAFE_C_S_opSCq: { s7_pointer val1, args; args = cdr(code); val1 = find_symbol_checked(sc, car(args)); car(sc->T2_1) = find_symbol_checked(sc, opt_sym1(args)); car(sc->T2_2) = opt_con2(args); car(sc->T2_2) = c_call(cadr(args))(sc, sc->T2_1); car(sc->T2_1) = val1; sc->value = c_call(code)(sc, sc->T2_1); goto START; } case OP_SAFE_C_C_opSCq: if (!c_function_is_ok_caddr(sc, code)) break; case HOP_SAFE_C_C_opSCq: { s7_pointer args; args = cdr(code); car(sc->T2_1) = find_symbol_checked(sc, opt_sym1(args)); car(sc->T2_2) = opt_con2(args); car(sc->T2_2) = c_call(cadr(args))(sc, sc->T2_1); car(sc->T2_1) = car(args); sc->value = c_call(code)(sc, sc->T2_1); goto START; } case OP_SAFE_C_S_opSSq: if (!c_function_is_ok_caddr(sc, code)) break; case HOP_SAFE_C_S_opSSq: { /* (* a (- b c)) */ s7_pointer val1, val2, args; args = cdr(code); val1 = find_symbol_checked(sc, car(args)); val2 = find_symbol_checked(sc, opt_sym1(args)); car(sc->T2_2) = find_symbol_checked(sc, opt_sym2(args)); car(sc->T2_1) = val2; car(sc->T2_2) = c_call(cadr(args))(sc, sc->T2_1); car(sc->T2_1) = val1; sc->value = c_call(code)(sc, sc->T2_1); goto START; } case OP_SAFE_C_S_opCSq: if (!c_function_is_ok_caddr(sc, code)) break; case HOP_SAFE_C_S_opCSq: { /* (* a (- 1 b)) or (logand a (ash 1 b)) */ s7_pointer val1, args; args = cdr(code); val1 = find_symbol_checked(sc, car(args)); /* a */ car(sc->T2_2) = find_symbol_checked(sc, opt_sym2(args)); /* b */ car(sc->T2_1) = opt_con1(args); /* 1 */ car(sc->T2_2) = c_call(cadr(args))(sc, sc->T2_1); /* (- 1 b) */ car(sc->T2_1) = val1; sc->value = c_call(code)(sc, sc->T2_1); goto START; } case OP_SAFE_C_opSq_S: if (!c_function_is_ok_cadr(sc, code)) break; case HOP_SAFE_C_opSq_S: { s7_pointer args; args = cdr(code); car(sc->T1_1) = find_symbol_checked(sc, cadr(car(args))); sc->temp3 = c_call(car(args))(sc, sc->T1_1); car(sc->T2_2) = find_symbol_checked(sc, cadr(args)); car(sc->T2_1) = sc->temp3; sc->temp3 = sc->NIL; sc->value = c_call(code)(sc, sc->T2_1); goto START; } case OP_SAFE_C_opSq_P: if (!c_function_is_ok_cadr(sc, code)) break; case HOP_SAFE_C_opSq_P: { s7_pointer args; args = cadr(code); car(sc->T1_1) = find_symbol_checked(sc, cadr(args)); push_stack(sc, OP_SAFE_C_opSq_P_1, c_call(args)(sc, sc->T1_1), sc->code); sc->code = caddr(code); goto EVAL; } case OP_SAFE_C_opCq_S: if (!c_function_is_ok_cadr(sc, code)) break; case HOP_SAFE_C_opCq_S: { s7_pointer args, val; args = cdr(code); val = find_symbol_checked(sc, cadr(args)); car(sc->T2_1) = c_call(car(args))(sc, cdr(car(args))); car(sc->T2_2) = val; sc->value = c_call(code)(sc, sc->T2_1); goto START; } case OP_SAFE_C_opCq_C: if (!c_function_is_ok_cadr(sc, code)) break; case HOP_SAFE_C_opCq_C: { s7_pointer args; args = cdr(code); car(sc->T2_1) = c_call(car(args))(sc, cdr(car(args))); car(sc->T2_2) = cadr(args); /* the second C stands for 1 arg? */ sc->value = c_call(code)(sc, sc->T2_1); goto START; } case OP_SAFE_C_opSq_C: if (!c_function_is_ok_cadr(sc, code)) break; case HOP_SAFE_C_opSq_C: { s7_pointer args; args = cdr(code); car(sc->T1_1) = find_symbol_checked(sc, cadr(car(args))); car(sc->T2_1) = c_call(car(args))(sc, sc->T1_1); car(sc->T2_2) = cadr(args); sc->value = c_call(code)(sc, sc->T2_1); goto START; } case OP_SAFE_C_C_op_S_opCqq: if (!a_is_ok(sc, code)) break; case HOP_SAFE_C_C_op_S_opCqq: { /* (define (hi a) (< 1.0 (+ a (* a 2)))) */ s7_pointer args, arg1, arg2; args = cdr(code); /* C_op_S_opCqq */ arg1 = cadr(args); /* op_S_opCqq */ arg2 = caddr(arg1); /* opCq */ car(sc->T2_2) = c_call(arg2)(sc, cdr(arg2)); car(sc->T2_1) = find_symbol_checked(sc, cadr(arg1)); car(sc->T2_2) = c_call(arg1)(sc, sc->T2_1); car(sc->T2_1) = car(args); sc->value = c_call(code)(sc, sc->T2_1); goto START; } case OP_SAFE_C_opSq_opSq: if (!c_function_is_ok_cadr_caddr(sc, code)) break; case HOP_SAFE_C_opSq_opSq: { s7_pointer args; args = cdr(code); car(sc->T1_1) = find_symbol_checked(sc, cadr(car(args))); sc->temp3 = c_call(car(args))(sc, sc->T1_1); args = cadr(args); car(sc->T1_1) = find_symbol_checked(sc, cadr(args)); car(sc->T2_2) = c_call(args)(sc, sc->T1_1); car(sc->T2_1) = sc->temp3; sc->temp3 = sc->NIL; sc->value = c_call(code)(sc, sc->T2_1); goto START; } case OP_SAFE_C_opCq_opCq: if (!c_function_is_ok_cadr_caddr(sc, code)) break; case HOP_SAFE_C_opCq_opCq: { s7_pointer args; args = cdr(code); car(sc->T2_1) = c_call(car(args))(sc, cdr(car(args))); car(sc->T2_2) = c_call(cadr(args))(sc, cdr(cadr(args))); sc->value = c_call(code)(sc, sc->T2_1); goto START; } case OP_SAFE_C_opCq_opSSq: if (!c_function_is_ok_cadr_caddr(sc, code)) break; case HOP_SAFE_C_opCq_opSSq: { s7_pointer args, val; /* code: (/ (+ bn 1) (+ bn an)) */ args = cdr(code); val = c_call(car(args))(sc, cdr(car(args))); args = cdr(args); car(sc->T2_1) = find_symbol_checked(sc, cadar(args)); car(sc->T2_2) = find_symbol_checked(sc, caddar(args)); car(sc->T2_2) = c_call(car(args))(sc, sc->T2_1); car(sc->T2_1) = val; sc->value = c_call(code)(sc, sc->T2_1); goto START; } case OP_SAFE_C_opSCq_opSCq: if (!c_function_is_ok_cadr_caddr(sc, code)) break; case HOP_SAFE_C_opSCq_opSCq: { s7_pointer args, val2; args = cdr(code); val2 = find_symbol_checked(sc, cadr(cadr(args))); car(sc->T2_1) = find_symbol_checked(sc, cadr(car(args))); car(sc->T2_2) = caddr(car(args)); sc->temp3 = c_call(car(args))(sc, sc->T2_1); car(sc->T2_1) = val2; car(sc->T2_2) = caddr(cadr(args)); car(sc->T2_2) = c_call(cadr(args))(sc, sc->T2_1); car(sc->T2_1) = sc->temp3; sc->temp3 = sc->NIL; sc->value = c_call(code)(sc, sc->T2_1); goto START; } case OP_SAFE_C_opSSq_opSSq: if (!c_function_is_ok_cadr_caddr(sc, code)) break; case HOP_SAFE_C_opSSq_opSSq: { s7_pointer args, val3, val4; args = cdr(code); val3 = find_symbol_checked(sc, caddr(car(args))); val4 = find_symbol_checked(sc, caddr(cadr(args))); car(sc->T2_1) = find_symbol_checked(sc, cadr(car(args))); car(sc->T2_2) = val3; sc->temp3 = c_call(car(args))(sc, sc->T2_1); car(sc->T2_1) = find_symbol_checked(sc, cadr(cadr(args))); car(sc->T2_2) = val4; car(sc->T2_2) = c_call(cadr(args))(sc, sc->T2_1); car(sc->T2_1) = sc->temp3; sc->temp3 = sc->NIL; sc->value = c_call(code)(sc, sc->T2_1); goto START; } case OP_SAFE_C_opSSq_opSq: if (!c_function_is_ok_cadr_caddr(sc, code)) break; case HOP_SAFE_C_opSSq_opSq: { s7_pointer args, val3; args = cdr(code); val3 = find_symbol_checked(sc, caddr(car(args))); car(sc->T2_1) = find_symbol_checked(sc, cadr(car(args))); car(sc->T2_2) = val3; val3 = c_call(car(args))(sc, sc->T2_1); car(sc->T1_1) = find_symbol_checked(sc, cadr(cadr(args))); car(sc->T2_2) = c_call(cadr(args))(sc, sc->T1_1); car(sc->T2_1) = val3; sc->value = c_call(code)(sc, sc->T2_1); goto START; } case OP_SAFE_C_opSq_opSSq: if (!c_function_is_ok_cadr_caddr(sc, code)) break; case HOP_SAFE_C_opSq_opSSq: { s7_pointer args, val3; args = cdr(code); car(sc->T1_1) = find_symbol_checked(sc, cadr(car(args))); val3 = c_call(car(args))(sc, sc->T1_1); car(sc->T2_2) = find_symbol_checked(sc, caddr(cadr(args))); car(sc->T2_1) = find_symbol_checked(sc, cadr(cadr(args))); car(sc->T2_2) = c_call(cadr(args))(sc, sc->T2_1); car(sc->T2_1) = val3; sc->value = c_call(code)(sc, sc->T2_1); goto START; } case OP_SAFE_C_opSSq_opCq: if (!c_function_is_ok_cadr_caddr(sc, code)) break; case HOP_SAFE_C_opSSq_opCq: { s7_pointer arg1, arg2, val3; arg1 = cadr(code); arg2 = caddr(code); val3 = find_symbol_checked(sc, caddr(arg1)); car(sc->T2_1) = find_symbol_checked(sc, cadr(arg1)); car(sc->T2_2) = val3; car(sc->T2_1) = c_call(arg1)(sc, sc->T2_1); car(sc->T2_2) = c_call(arg2)(sc, cdr(arg2)); sc->value = c_call(code)(sc, sc->T2_1); goto START; } /* -------------------------------------------------------------------------------- */ case OP_C_S: if (!c_function_is_ok(sc, code)) break; case HOP_C_S: sc->args = list_1(sc, find_symbol_checked(sc, cadr(code))); sc->value = c_call(code)(sc, sc->args); goto START; case OP_READ_S: if (!c_function_is_ok(sc, code)) break; case HOP_READ_S: read_s_ex(sc); goto START; case OP_C_A: if (!a_is_ok_cadr(sc, code)) break; case HOP_C_A: sc->args = list_1(sc, c_call(cdr(code))(sc, cadr(code))); sc->value = c_call(code)(sc, sc->args); goto START; case OP_C_Z: if (!c_function_is_ok(sc, code)) break; case HOP_C_Z: push_stack(sc, OP_C_P_1, sc->NIL, code); sc->code = cadr(code); goto OPT_EVAL; case OP_C_P: if (!c_function_is_ok(sc, code)) break; case HOP_C_P: push_stack(sc, OP_C_P_1, sc->NIL, code); sc->code = cadr(code); goto EVAL; case OP_C_SS: if (!c_function_is_ok(sc, code)) break; case HOP_C_SS: sc->args = list_2(sc, find_symbol_checked(sc, cadr(code)), find_symbol_checked(sc, caddr(code))); sc->value = c_call(code)(sc, sc->args); goto START; case OP_C_SZ: if (!c_function_is_ok(sc, code)) break; case HOP_C_SZ: push_stack(sc, OP_C_SP_1, find_symbol_checked(sc, cadr(code)), code); sc->code = caddr(code); goto OPT_EVAL; case OP_C_SP: if (!c_function_is_ok(sc, code)) break; case HOP_C_SP: push_stack(sc, OP_C_SP_1, find_symbol_checked(sc, cadr(code)), code); sc->code = caddr(code); goto EVAL; case OP_APPLY_SS: if (!c_function_is_ok(sc, code)) break; case HOP_APPLY_SS: sc->code = find_symbol_checked(sc, cadr(code)); /* global search here was slower */ sc->args = find_symbol_checked(sc, opt_sym2(code)); if (!is_proper_list(sc, sc->args)) /* (apply + #f) etc */ return(apply_list_error(sc, sc->args)); if (needs_copied_args(sc->code)) sc->args = copy_list(sc, sc->args); goto APPLY; case OP_C_S_opSq: if ((!c_function_is_ok(sc, code)) || (!indirect_c_function_is_ok(sc, caddr(code)))) break; case HOP_C_S_opSq: { s7_pointer args, val; args = cdr(code); val = find_symbol_checked(sc, car(args)); car(sc->T1_1) = find_symbol_checked(sc, opt_sym1(args)); sc->args = list_2(sc, val, c_call(cadr(args))(sc, sc->T1_1)); sc->value = c_call(code)(sc, sc->args); goto START; } case OP_C_S_opCq: if ((!c_function_is_ok(sc, code)) || (!indirect_c_function_is_ok(sc, caddr(code)))) break; case HOP_C_S_opCq: { s7_pointer args, val; args = cdr(code); sc->temp3 = find_symbol_checked(sc, car(args)); val = c_call(cadr(args))(sc, opt_pair1(args)); sc->args = list_2(sc, sc->temp3, val); sc->temp3 = sc->NIL; sc->value = c_call(code)(sc, sc->args); goto START; } case OP_C_SCS: if (!c_function_is_ok(sc, code)) break; case HOP_C_SCS: { s7_pointer a1, a2; a1 = cdr(code); a2 = cdr(a1); sc->args = list_3(sc, find_symbol_checked(sc, car(a1)), car(a2), find_symbol_checked(sc, cadr(a2))); /* was unchecked? */ sc->value = c_call(code)(sc, sc->args); goto START; } case OP_C_ALL_X: if (!c_function_is_ok(sc, code)) break; case HOP_C_ALL_X: { /* (set-cdr! lst ()) */ s7_pointer args, p; sc->args = make_list(sc, integer(arglist_length(code)), sc->NIL); for (args = cdr(code), p = sc->args; is_pair(args); args = cdr(args), p = cdr(p)) car(p) = c_call(args)(sc, car(args)); sc->value = c_call(code)(sc, sc->args); goto START; } case OP_CALL_WITH_EXIT: if (!c_function_is_ok(sc, code)) break; check_lambda_args(sc, cadr(cadr(code)), NULL); case HOP_CALL_WITH_EXIT: { s7_pointer go, args; args = opt_pair2(code); go = make_goto(sc); push_stack(sc, OP_DEACTIVATE_GOTO, go, code); /* code arg is ignored, but perhaps this is safer in GC? */ new_frame_with_slot(sc, sc->envir, sc->envir, caar(args), go); sc->code = cdr(args); goto BEGIN1; } case OP_C_CATCH: if (!c_function_is_ok(sc, code)) break; check_lambda_args(sc, cadr(cadddr(code)), NULL); case HOP_C_CATCH: { /* (catch #t (lambda () (set! ("hi") #\a)) (lambda args args)) * code is (catch #t (lambda () ....) (lambda args ....)) */ s7_pointer p, f, args, tag; args = cddr(code); /* defer making the error lambda */ /* z = cdadr(args); make_closure_with_let(sc, y, car(z), cdr(z), sc->envir); */ /* check catch tag */ f = cadr(code); if (!is_pair(f)) /* (catch #t ...) or (catch sym ...) */ { if (is_symbol(f)) tag = find_symbol_checked(sc, f); else tag = f; } else tag = cadr(f); /* (catch 'sym ...) */ new_cell(sc, p, T_CATCH); /* the catch object sitting on the stack */ catch_tag(p) = tag; catch_goto_loc(p) = s7_stack_top(sc); catch_op_loc(p) = (int)(sc->op_stack_now - sc->op_stack); catch_handler(p) = cdadr(args); /* not yet a closure... */ push_stack(sc, OP_CATCH_1, code, p); /* code ignored here, except by GC */ new_frame(sc, sc->envir, sc->envir); sc->code = cddar(args); goto BEGIN1; } case OP_C_CATCH_ALL: if (!c_function_is_ok(sc, code)) break; case HOP_C_CATCH_ALL: { /* (catch #t (lambda () ...) (lambda args #f) */ s7_pointer p; new_frame(sc, sc->envir, sc->envir); /* catch_all needs 3 pieces of info: the goto/op locs and the result * the locs are unsigned ints, so this fits in the new frame's dox1/2 fields. */ p = sc->envir; catch_all_set_goto_loc(p, s7_stack_top(sc)); catch_all_set_op_loc(p, (int)(sc->op_stack_now - sc->op_stack)); catch_all_set_result(p, opt_con2(code)); push_stack_no_args(sc, OP_CATCH_ALL, code); sc->code = opt_pair1(cdr(code)); /* the body of the first lambda */ goto BEGIN1; /* removed one_liner check here -- rare */ } /* -------------------------------------------------------------------------------- */ case OP_THUNK: if (!closure_is_ok(sc, code, MATCH_UNSAFE_CLOSURE, 0)) {set_optimize_op(code, OP_UNKNOWN); goto OPT_EVAL;} case HOP_THUNK: check_stack_size(sc); /* this recursion check is consistent with the other unsafe closure calls, but we're probably in big trouble: * (letrec ((a (lambda () (cons 1 (b)))) (b (lambda () (a)))) (b)) * unfortunately the alternative is a segfault when we wander off the end of the stack. * * It seems that we could use the hop bit here (since it is always off) to choose between BEGIN1 and OPT_EVAL or EVAL, * but the EVAL choice gains nothing in time, and the OPT_EVAL choice is too tricky -- it is a two-level optimization, * so if the inner (car(closure_body)) gets unopt'd for some reason, the outer HOP_THUNK never finds * out, and peculiar things start to happen. (Also, is_h_optimized would need to be smarter). */ new_frame(sc, closure_let(opt_lambda(code)), sc->envir); sc->code = closure_body(opt_lambda(code)); goto BEGIN1; case OP_SAFE_THUNK: if (!closure_is_ok(sc, code, MATCH_SAFE_CLOSURE, 0)) {set_optimize_op(code, OP_UNKNOWN); goto OPT_EVAL;} case HOP_SAFE_THUNK: /* no frame needed */ /* (let ((x 1)) (let () (define (f) x) (let ((x 0)) (define (g) (set! x 32) (f)) (g)))) */ sc->envir = closure_let(opt_lambda(code)); sc->code = closure_body(opt_lambda(code)); goto BEGIN1; case OP_SAFE_THUNK_E: if (find_symbol_unchecked(sc, car(code)) != opt_any1(code)) {set_optimize_op(code, OP_UNKNOWN); goto OPT_EVAL;} case HOP_SAFE_THUNK_E: sc->envir = closure_let(opt_lambda(code)); sc->code = car(closure_body(opt_lambda(code))); goto OPT_EVAL; case OP_SAFE_THUNK_P: if (find_symbol_unchecked(sc, car(code)) != opt_any1(code)) {set_optimize_op(code, OP_UNKNOWN); goto OPT_EVAL;} case HOP_SAFE_THUNK_P: sc->envir = closure_let(opt_lambda(code)); sc->code = car(closure_body(opt_lambda(code))); sc->op = (opcode_t)pair_syntax_op(sc->code); sc->code = cdr(sc->code); goto START_WITHOUT_POP_STACK; case OP_SAFE_CLOSURE_S: if (!closure_is_ok(sc, code, MATCH_SAFE_CLOSURE, 1)) {set_optimize_op(code, OP_UNKNOWN_G); goto OPT_EVAL;} case HOP_SAFE_CLOSURE_S: /* since a tail call is safe, we can't change the current env's let_id until * after we do the lookup -- it might be the current func's arg, and we're * about to call the same func. */ sc->envir = old_frame_with_slot(sc, closure_let(opt_lambda(code)), find_symbol_checked(sc, opt_sym2(code))); sc->code = closure_body(opt_lambda(code)); goto BEGIN1; case OP_SAFE_CLOSURE_S_P: if (find_symbol_unchecked(sc, car(code)) != opt_any1(code)) {set_optimize_op(code, OP_UNKNOWN_G); goto OPT_EVAL;} case HOP_SAFE_CLOSURE_S_P: sc->envir = old_frame_with_slot(sc, closure_let(opt_lambda(code)), find_symbol_checked(sc, opt_sym2(code))); sc->code = car(closure_body(opt_lambda(code))); sc->op = (opcode_t)pair_syntax_op(sc->code); sc->code = cdr(sc->code); goto START_WITHOUT_POP_STACK; case OP_SAFE_GLOSURE_S: if ((symbol_id(car(code)) != 0) ||(opt_any1(code) != slot_value(global_slot(car(code))))) {set_optimize_op(code, OP_UNKNOWN_G); goto OPT_EVAL;} case HOP_SAFE_GLOSURE_S: sc->envir = old_frame_with_slot(sc, closure_let(opt_lambda(code)), find_symbol_checked(sc, opt_sym2(code))); sc->code = closure_body(opt_lambda(code)); goto BEGIN1; case OP_SAFE_GLOSURE_S_E: if ((symbol_id(car(code)) != 0) || (opt_any1(code) != slot_value(global_slot(car(code))))) {set_optimize_op(code, OP_UNKNOWN_G); goto OPT_EVAL;} case HOP_SAFE_GLOSURE_S_E: sc->envir = old_frame_with_slot(sc, closure_let(opt_lambda(code)), find_symbol_checked(sc, opt_sym2(code))); sc->code = car(closure_body(opt_lambda(code))); goto OPT_EVAL; case OP_SAFE_CLOSURE_C: if (!closure_is_ok(sc, code, MATCH_SAFE_CLOSURE, 1)) {set_optimize_op(code, OP_UNKNOWN_G); goto OPT_EVAL;} case HOP_SAFE_CLOSURE_C: sc->envir = old_frame_with_slot(sc, closure_let(opt_lambda(code)), cadr(code)); sc->code = closure_body(opt_lambda(code)); goto BEGIN1; case OP_SAFE_CLOSURE_Q: if (!closure_is_ok(sc, code, MATCH_SAFE_CLOSURE, 1)) {set_optimize_op(code, OP_UNKNOWN_A); goto OPT_EVAL;} case HOP_SAFE_CLOSURE_Q: sc->envir = old_frame_with_slot(sc, closure_let(opt_lambda(code)), cadr(cadr(code))); sc->code = closure_body(opt_lambda(code)); goto BEGIN1; case OP_SAFE_GLOSURE_P: if ((symbol_id(car(code)) != 0) || (opt_any1(code) != slot_value(global_slot(car(code))))) break; case HOP_SAFE_GLOSURE_P: push_stack(sc, OP_SAFE_CLOSURE_P_1, sc->NIL, code); sc->code = cadr(code); goto EVAL; case OP_SAFE_CLOSURE_A: if (!closure_is_ok(sc, code, MATCH_SAFE_CLOSURE, 1)) {set_optimize_op(code, OP_UNKNOWN_A); goto OPT_EVAL;} if (!indirect_c_function_is_ok(sc, cadr(code))) break; case HOP_SAFE_CLOSURE_A: sc->envir = old_frame_with_slot(sc, closure_let(opt_lambda(code)), c_call(cdr(code))(sc, cadr(code))); sc->code = closure_body(opt_lambda(code)); goto BEGIN1; case OP_SAFE_GLOSURE_A: if ((symbol_id(car(code)) != 0) || (opt_any1(code) != slot_value(global_slot(car(code))))) {set_optimize_op(code, OP_UNKNOWN_A); goto OPT_EVAL;} if (!indirect_c_function_is_ok(sc, cadr(code))) break; case HOP_SAFE_GLOSURE_A: sc->envir = old_frame_with_slot(sc, closure_let(opt_lambda(code)), c_call(cdr(code))(sc, cadr(code))); sc->code = closure_body(opt_lambda(code)); goto BEGIN1; case OP_SAFE_CLOSURE_SS: if (!closure_is_ok(sc, code, MATCH_SAFE_CLOSURE, 2)) {set_optimize_op(code, OP_UNKNOWN_GG); goto OPT_EVAL;} case HOP_SAFE_CLOSURE_SS: sc->envir = old_frame_with_two_slots(sc, closure_let(opt_lambda(code)), find_symbol_checked(sc, cadr(code)), find_symbol_checked(sc, opt_sym2(code))); sc->code = closure_body(opt_lambda(code)); goto BEGIN1; case OP_SAFE_CLOSURE_SC: if (!closure_is_ok(sc, code, MATCH_SAFE_CLOSURE, 2)) {set_optimize_op(code, OP_UNKNOWN_GG); goto OPT_EVAL;} case HOP_SAFE_CLOSURE_SC: sc->envir = old_frame_with_two_slots(sc, closure_let(opt_lambda(code)), find_symbol_checked(sc, cadr(code)), opt_con2(code)); sc->code = closure_body(opt_lambda(code)); goto BEGIN1; case OP_SAFE_CLOSURE_CS: if (!closure_is_ok(sc, code, MATCH_SAFE_CLOSURE, 2)) {set_optimize_op(code, OP_UNKNOWN_GG); goto OPT_EVAL;} case HOP_SAFE_CLOSURE_CS: sc->envir = old_frame_with_two_slots(sc, closure_let(opt_lambda(code)), cadr(code), find_symbol_checked(sc, opt_sym2(code))); sc->code = closure_body(opt_lambda(code)); goto BEGIN1; case OP_SAFE_CLOSURE_SA: if (!closure_is_ok(sc, code, MATCH_SAFE_CLOSURE, 2)) {set_optimize_op(code, OP_UNKNOWN_AA); goto OPT_EVAL;} case HOP_SAFE_CLOSURE_SA: { s7_pointer args; args = cddr(code); args = c_call(args)(sc, car(args)); sc->envir = old_frame_with_two_slots(sc, closure_let(opt_lambda(code)), find_symbol_checked(sc, cadr(code)), args); sc->code = closure_body(opt_lambda(code)); goto BEGIN1; } case OP_SAFE_CLOSURE_AA: if (!closure_is_ok(sc, code, MATCH_SAFE_CLOSURE, 2)) {set_optimize_op(code, OP_UNKNOWN_AA); goto OPT_EVAL;} case HOP_SAFE_CLOSURE_AA: { s7_pointer args, y, z; args = cdr(code); y = c_call(args)(sc, car(args)); args = cdr(args); z = c_call(args)(sc, car(args)); sc->envir = old_frame_with_two_slots(sc, closure_let(opt_lambda(code)), y, z); sc->code = closure_body(opt_lambda(code)); goto BEGIN1; } case OP_SAFE_CLOSURE_SAA: if (!closure_is_ok(sc, code, MATCH_SAFE_CLOSURE, 3)) break; case HOP_SAFE_CLOSURE_SAA: { s7_pointer args, y, z; args = cddr(code); y = c_call(args)(sc, car(args)); args = cdr(args); z = c_call(args)(sc, car(args)); sc->envir = old_frame_with_three_slots(sc, closure_let(opt_lambda(code)), find_symbol_checked(sc, cadr(code)), y, z); sc->code = closure_body(opt_lambda(code)); goto BEGIN1; } case OP_SAFE_CLOSURE_ALL_X: if (!closure_is_ok(sc, code, MATCH_SAFE_CLOSURE, integer(arglist_length(code)))) break; case HOP_SAFE_CLOSURE_ALL_X: { s7_pointer args, p, env, x, z; int num_args; unsigned long long int id; num_args = integer(arglist_length(code)); if ((num_args != 0) && (num_args < NUM_SAFE_LISTS) && (!list_is_in_use(sc->safe_lists[num_args]))) { sc->args = sc->safe_lists[num_args]; set_list_in_use(sc->args); } else sc->args = make_list(sc, num_args, sc->NIL); for (args = cdr(code), p = sc->args; is_pair(args); args = cdr(args), p = cdr(p)) car(p) = c_call(args)(sc, car(args)); clear_list_in_use(sc->args); sc->code = opt_lambda(code); id = ++sc->let_number; env = closure_let(sc->code); let_id(env) = id; for (x = let_slots(env), z = sc->args; is_slot(x); x = next_slot(x), z = cdr(z)) { slot_set_value(x, car(z)); symbol_set_local(slot_symbol(x), id, x); } sc->envir = env; sc->code = closure_body(sc->code); if (is_pair(cdr(sc->code))) { push_stack_no_args(sc, OP_BEGIN1, cdr(sc->code)); sc->code = car(sc->code); } else { sc->code = car(sc->code); if (is_optimized(sc->code)) goto OPT_EVAL; } goto EVAL; } /* -------------------------------------------------------------------------------- */ case OP_SAFE_CLOSURE_STAR_SS: if (!closure_star_is_ok(sc, code, MATCH_SAFE_CLOSURE_STAR, 2)) {set_optimize_op(code, OP_UNKNOWN_GG); goto OPT_EVAL;} case HOP_SAFE_CLOSURE_STAR_SS: { s7_pointer x, val1, val2; /* the finders have to operate in the current environment, so we can't change sc->envir until later */ val1 = find_symbol_checked(sc, cadr(code)); val2 = find_symbol_checked(sc, opt_sym2(code)); /* caddr */ sc->envir = old_frame_with_slot(sc, closure_let(opt_lambda(code)), val1); x = next_slot(let_slots(closure_let(opt_lambda(code)))); slot_set_value(x, val2); symbol_set_local(slot_symbol(x), let_id(sc->envir), x); fill_safe_closure_star(sc, next_slot(x), cddr(closure_args(opt_lambda(code)))); goto BEGIN1; } case OP_SAFE_CLOSURE_STAR_SC: if (!closure_star_is_ok(sc, code, MATCH_SAFE_CLOSURE_STAR, 2)) {set_optimize_op(code, OP_UNKNOWN_GG); goto OPT_EVAL;} case HOP_SAFE_CLOSURE_STAR_SC: { s7_pointer x; sc->envir = old_frame_with_slot(sc, closure_let(opt_lambda(code)), find_symbol_checked(sc, cadr(code))); x = next_slot(let_slots(closure_let(opt_lambda(code)))); slot_set_value(x, caddr(code)); symbol_set_local(slot_symbol(x), let_id(sc->envir), x); fill_safe_closure_star(sc, next_slot(x), cddr(closure_args(opt_lambda(code)))); goto BEGIN1; } case OP_SAFE_CLOSURE_STAR_SA: if (!closure_star_is_ok(sc, code, MATCH_SAFE_CLOSURE_STAR, 2)) break; case HOP_SAFE_CLOSURE_STAR_SA: { s7_pointer arg; /* the second arg needs to be evaluated before we set sc->envir. * we checked at optimize time that this closure takes only 2 args. */ arg = cddr(code); arg = c_call(arg)(sc, car(arg)); sc->envir = old_frame_with_two_slots(sc, closure_let(opt_lambda(code)), find_symbol_checked(sc, cadr(code)), arg); sc->code = closure_body(opt_lambda(code)); goto BEGIN1; } case OP_SAFE_CLOSURE_STAR_ALL_X: if (!closure_star_is_ok(sc, code, MATCH_SAFE_CLOSURE_STAR, integer(arglist_length(code)))) break; case HOP_SAFE_CLOSURE_STAR_ALL_X: { s7_pointer args, p, orig_args, e; /* (let () (define* (hi (a 1)) (+ a 1)) (define (ho) (hi (* 2 3))) (ho)) * (do ((i 0 (+ i 1))) ((= i 11)) (envelope-interp (/ i 21) '(0 0 100 1))) */ e = closure_let(opt_lambda(code)); for (args = cdr(code), p = let_slots(e), orig_args = closure_args(opt_lambda(code)); is_pair(args); args = cdr(args), orig_args = cdr(orig_args), p = next_slot(p)) slot_pending_value(p) = c_call(args)(sc, car(args)); /* we're out of caller's args, so fill rest of environment slots from the defaults */ for (; is_slot(p); p = next_slot(p), orig_args = cdr(orig_args)) { s7_pointer defval; if (is_pair(car(orig_args))) { defval = cadar(orig_args); if (is_pair(defval)) slot_pending_value(p) = cadr(defval); else slot_pending_value(p) = defval; } else slot_pending_value(p) = sc->F; } /* we have to put off the actual environment update in case this is a tail recursive call */ let_id(e) = ++sc->let_number; for (p = let_slots(e); is_slot(p); p = next_slot(p)) { slot_set_value(p, slot_pending_value(p)); symbol_set_local(slot_symbol(p), let_id(e), p); } sc->envir = e; sc->code = closure_body(opt_lambda(code)); goto BEGIN1; } case OP_SAFE_CLOSURE_STAR: if (!closure_star_is_ok(sc, code, MATCH_SAFE_CLOSURE_STAR, 0)) {set_optimize_op(code, OP_UNKNOWN); goto OPT_EVAL;} case HOP_SAFE_CLOSURE_STAR: /* (let () (define* (hi (a 100)) (random a)) (define (ho) (hi)) (ho)) */ sc->envir = closure_let(opt_lambda(code)); let_id(sc->envir) = ++sc->let_number; fill_safe_closure_star(sc, let_slots(closure_let(opt_lambda(code))), closure_args(opt_lambda(code))); goto BEGIN1; case OP_SAFE_CLOSURE_STAR_S0: if (find_symbol_unchecked(sc, car(code)) != opt_any1(code)) {set_optimize_op(code, OP_UNKNOWN_G); goto OPT_EVAL;} case HOP_SAFE_CLOSURE_STAR_S0: /* here we know we have (let-set! arg1 'name arg2) (with-env arg1 ...) as the safe closure body. * since no errors can come from the first, there's no need for the procedure env. * so do the set and with-env by hand, leaving with the env body. */ { s7_pointer e; e = find_symbol_checked(sc, cadr(code)); /* S of S0 above */ if (e == sc->rootlet) sc->envir = sc->NIL; else { if (!is_let(e)) eval_type_error(sc, "with-let takes an environment argument: ~A", e); sc->envir = e; set_with_let_let(e); } if (e != sc->rootlet) { s7_pointer p; let_id(e) = ++sc->let_number; for (p = let_slots(e); is_slot(p); p = next_slot(p)) { s7_pointer sym; sym = slot_symbol(p); symbol_set_local(sym, sc->let_number, p); } slot_set_value(local_slot(opt_sym1(cdr(code))), real_zero); /* "arg2" above */ } sc->code = opt_pair2(cdr(code)); goto BEGIN1; } case OP_SAFE_CLOSURE_STAR_S: if (!closure_star_is_ok(sc, code, MATCH_SAFE_CLOSURE_STAR, 1)) {set_optimize_op(code, OP_UNKNOWN_G); goto OPT_EVAL;} case HOP_SAFE_CLOSURE_STAR_S: sc->envir = old_frame_with_slot(sc, closure_let(opt_lambda(code)), find_symbol_checked(sc, opt_sym2(code))); /* that sets the first arg to the passed symbol value; now set default values, if any */ fill_safe_closure_star(sc, next_slot(let_slots(closure_let(opt_lambda(code)))), cdr(closure_args(opt_lambda(code)))); goto BEGIN1; /* -------------------------------------------------------------------------------- */ case OP_GOTO: set_opt_goto(code, find_symbol_checked(sc, car(code))); if (!is_goto(opt_goto(code))) {set_optimize_op(code, OP_UNKNOWN); goto OPT_EVAL;} case HOP_GOTO: sc->args = sc->NIL; sc->code = opt_goto(code); call_with_exit(sc); goto START; case OP_GOTO_C: /* call-with-exit repeat use internally is very rare, so let's just look it up */ set_opt_goto(code, find_symbol_checked(sc, car(code))); if (!is_goto(opt_goto(code))) { set_optimize_op(code, OP_UNKNOWN_G); goto OPT_EVAL; } case HOP_GOTO_C: /* (return #t) -- recognized via OP_UNKNOWN_G, opt_goto(code) is the function [parallels OP_CLOSURE_C] */ sc->args = cdr(code); sc->code = opt_goto(code); call_with_exit(sc); goto START; case OP_GOTO_S: set_opt_goto(code, find_symbol_checked(sc, car(code))); if (!is_goto(opt_goto(code))) {set_optimize_op(code, OP_UNKNOWN_G); goto OPT_EVAL;} case HOP_GOTO_S: sc->args = list_1(sc, find_symbol_checked(sc, cadr(code))); /* I think this needs listification because call_with_exit might call dynamic unwinders etc. */ sc->code = opt_goto(code); call_with_exit(sc); goto START; case OP_GOTO_A: set_opt_goto(code, find_symbol_checked(sc, car(code))); if (!is_goto(opt_goto(code))) {set_optimize_op(code, OP_UNKNOWN_A); goto OPT_EVAL;} case HOP_GOTO_A: sc->args = list_1(sc, c_call(cdr(code))(sc, cadr(code))); sc->code = opt_goto(code); call_with_exit(sc); goto START; /* for T_CONTINUATION, set sc->args to list_1(sc, ...) as in goto (and code?), then call_with_current_continuation */ case OP_CLOSURE_C: if (!closure_is_ok(sc, code, MATCH_UNSAFE_CLOSURE, 1)) {set_optimize_op(code, OP_UNKNOWN_G); goto OPT_EVAL;} case HOP_CLOSURE_C: check_stack_size(sc); code = opt_lambda(code); new_frame_with_slot(sc, closure_let(code), sc->envir, car(closure_args(code)), cadr(sc->code)); sc->code = closure_body(code); goto BEGIN1; case OP_CLOSURE_Q: if (!closure_is_ok(sc, code, MATCH_UNSAFE_CLOSURE, 1)) {set_optimize_op(code, OP_UNKNOWN_A); goto OPT_EVAL;} case HOP_CLOSURE_Q: check_stack_size(sc); code = opt_lambda(code); new_frame_with_slot(sc, closure_let(code), sc->envir, car(closure_args(code)), cadr(cadr(sc->code))); sc->code = closure_body(code); goto BEGIN1; case OP_CLOSURE_A: if (!closure_is_ok(sc, code, MATCH_UNSAFE_CLOSURE, 1)) {set_optimize_op(code, OP_UNKNOWN_A); goto OPT_EVAL;} if (!indirect_c_function_is_ok(sc, cadr(code))) break; case HOP_CLOSURE_A: sc->value = c_call(cdr(code))(sc, cadr(code)); check_stack_size(sc); code = opt_lambda(code); new_frame_with_slot(sc, closure_let(code), sc->envir, car(closure_args(code)), sc->value); sc->code = closure_body(code); goto BEGIN1; case OP_GLOSURE_A: if ((symbol_id(car(code)) != 0) || (opt_lambda(code) != slot_value(global_slot(car(code))))) {set_optimize_op(code, OP_UNKNOWN_A); goto OPT_EVAL;} if (!indirect_c_function_is_ok(sc, cadr(code))) break; case HOP_GLOSURE_A: sc->value = c_call(cdr(code))(sc, cadr(code)); check_stack_size(sc); code = opt_lambda(code); new_frame_with_slot(sc, closure_let(code), sc->envir, car(closure_args(code)), sc->value); sc->code = closure_body(code); goto BEGIN1; case OP_GLOSURE_P: if ((symbol_id(car(code)) != 0) || (opt_lambda(code) != slot_value(global_slot(car(code))))) break; case HOP_GLOSURE_P: push_stack(sc, OP_CLOSURE_P_1, sc->NIL, code); sc->code = cadr(code); goto EVAL; case OP_GLOSURE_S: if ((symbol_id(car(code)) != 0) || (opt_any1(code) != slot_value(global_slot(car(code))))) {set_optimize_op(code, OP_UNKNOWN_G); goto OPT_EVAL;} case HOP_GLOSURE_S: sc->value = find_symbol_checked(sc, opt_sym2(code)); check_stack_size(sc); code = opt_lambda(code); new_frame_with_slot(sc, closure_let(code), sc->envir, car(closure_args(code)), sc->value); sc->code = closure_body(code); goto BEGIN1; case OP_CLOSURE_S: if (!closure_is_ok(sc, code, MATCH_UNSAFE_CLOSURE, 1)) {set_optimize_op(code, OP_UNKNOWN_G); goto OPT_EVAL;} case HOP_CLOSURE_S: sc->value = find_symbol_checked(sc, opt_sym2(code)); check_stack_size(sc); code = opt_lambda(code); new_frame_with_slot(sc, closure_let(code), sc->envir, car(closure_args(code)), sc->value); sc->code = closure_body(code); goto BEGIN1; case OP_CLOSURE_SS: if (!closure_is_ok(sc, code, MATCH_UNSAFE_CLOSURE, 2)) {set_optimize_op(code, OP_UNKNOWN_GG); goto OPT_EVAL;} case HOP_CLOSURE_SS: /* only called if one of these symbols has an accessor */ unsafe_closure_2(sc, find_symbol_checked(sc, cadr(code)), find_symbol_checked(sc, opt_sym2(code))); goto BEGIN1; case OP_CLOSURE_SC: if (!closure_is_ok(sc, code, MATCH_UNSAFE_CLOSURE, 2)) {set_optimize_op(code, OP_UNKNOWN_GG); goto OPT_EVAL;} case HOP_CLOSURE_SC: unsafe_closure_2(sc, find_symbol_checked(sc, cadr(code)), opt_con2(code)); goto BEGIN1; case OP_CLOSURE_CS: if (!closure_is_ok(sc, code, MATCH_UNSAFE_CLOSURE, 2)) {set_optimize_op(code, OP_UNKNOWN_GG); goto OPT_EVAL;} case HOP_CLOSURE_CS: unsafe_closure_2(sc, cadr(code), find_symbol_checked(sc, opt_sym2(code))); goto BEGIN1; case OP_CLOSURE_AA: if (!closure_is_ok(sc, code, MATCH_UNSAFE_CLOSURE, 2)) {set_optimize_op(code, OP_UNKNOWN_AA); goto OPT_EVAL;} if ((is_optimized(cadr(code))) && (!indirect_c_function_is_ok(sc, cadr(code)))) break; if ((is_optimized(caddr(code))) && (!indirect_c_function_is_ok(sc, caddr(code)))) break; case HOP_CLOSURE_AA: { s7_pointer args; args = cdr(code); sc->temp2 = c_call(args)(sc, car(args)); unsafe_closure_2(sc, sc->temp2, c_call(cdr(args))(sc, cadr(args))); goto BEGIN1; } case OP_CLOSURE_ALL_S: if (!closure_is_ok(sc, code, MATCH_UNSAFE_CLOSURE, integer(arglist_length(code)))) {set_optimize_op(code, OP_UNKNOWN_ALL_S); goto OPT_EVAL;} case HOP_CLOSURE_ALL_S: { s7_pointer args, p, func, e; /* in this case, we have just lambda (not lambda*), and no dotted arglist, * and no accessed symbols in the arglist, and we know the arglist matches the parameter list. */ check_stack_size(sc); func = opt_lambda(code); /* we need to get the slot names from the current function, but the values from the calling environment */ new_frame(sc, closure_let(func), e); sc->z = e; for (p = closure_args(func), args = cdr(code); is_pair(p); p = cdr(p), args = cdr(args)) add_slot(e, car(p), find_symbol_checked(sc, car(args))); sc->envir = e; sc->z = sc->NIL; sc->code = closure_body(func); goto BEGIN1; } case OP_CLOSURE_ALL_X: check_stack_size(sc); if (!closure_is_ok(sc, code, MATCH_UNSAFE_CLOSURE, integer(arglist_length(code)))) {set_optimize_op(code, OP_UNKNOWN_ALL_X); goto OPT_EVAL;} case HOP_CLOSURE_ALL_X: { s7_pointer args, p, func, e; func = opt_lambda(code); new_frame(sc, closure_let(func), e); sc->z = e; for (p = closure_args(func), args = cdr(code); is_pair(p); p = cdr(p), args = cdr(args)) { s7_pointer val; val = c_call(args)(sc, car(args)); add_slot_checked(e, car(p), val); /* can't use add_slot here -- all_x_c_* hit trigger? */ } sc->envir = e; sc->z = sc->NIL; sc->code = closure_body(func); goto BEGIN1; } /* -------------------------------------------------------------------------------- */ case OP_CLOSURE_STAR_ALL_X: if (!closure_star_is_ok(sc, code, MATCH_UNSAFE_CLOSURE_STAR, integer(arglist_length(code)))) { set_optimize_op(code, OP_UNKNOWN_ALL_X); goto OPT_EVAL; } case HOP_CLOSURE_STAR_ALL_X: { /* here also, all the args are simple */ /* (let () (define* (hi (a 1)) (list a)) (define (ho) (hi (* 2 3))) (ho)) */ s7_pointer args, p, func, new_args; func = opt_lambda(code); sc->args = make_list(sc, closure_star_arity_to_int(sc, func), sc->NIL); new_args = sc->args; for (p = closure_args(func), args = cdr(code); is_pair(args); p = cdr(p), args = cdr(args), new_args = cdr(new_args)) car(new_args) = c_call(args)(sc, car(args)); for (; is_pair(p); p = cdr(p), new_args = cdr(new_args)) { s7_pointer defval; if (is_pair(car(p))) { defval = cadar(p); if (is_pair(defval)) car(new_args) = cadr(defval); else car(new_args) = defval; } else car(new_args) = sc->F; } sc->code = opt_lambda(code); unsafe_closure_star(sc); goto BEGIN1; } case OP_CLOSURE_STAR_SX: if (!closure_star_is_ok(sc, code, MATCH_UNSAFE_CLOSURE_STAR, 2)) {set_optimize_op(code, OP_UNKNOWN_GG); goto OPT_EVAL;} case HOP_CLOSURE_STAR_SX: { s7_pointer val1, val2, args; args = cddr(closure_args(opt_lambda(code))); val1 = find_symbol_checked(sc, cadr(code)); val2 = caddr(code); if (is_symbol(val2)) val2 = find_symbol_checked(sc, val2); if (is_null(args)) { car(sc->T2_1) = val1; car(sc->T2_2) = val2; code = opt_lambda(sc->code); args = closure_args(code); new_frame_with_two_slots(sc, closure_let(code), sc->envir, (is_pair(car(args))) ? caar(args) : car(args), car(sc->T2_1), (is_pair(cadr(args))) ? caadr(args) : cadr(args), car(sc->T2_2)); sc->code = closure_body(code); } else { sc->args = list_2(sc, val2, val1); fill_closure_star(sc, args); unsafe_closure_star(sc); } goto BEGIN1; } case OP_CLOSURE_STAR: if (!closure_star_is_ok(sc, code, MATCH_UNSAFE_CLOSURE_STAR, 0)) {set_optimize_op(code, OP_UNKNOWN); goto OPT_EVAL;} case HOP_CLOSURE_STAR: /* (let () (define* (hi (a 1)) (list a)) (define (ho) (hi)) (ho)) */ sc->args = sc->NIL; fill_closure_star(sc, closure_args(opt_lambda(code))); unsafe_closure_star(sc); goto BEGIN1; case OP_CLOSURE_STAR_S: if (!closure_star_is_ok(sc, code, MATCH_UNSAFE_CLOSURE_STAR, 1)) {set_optimize_op(code, OP_UNKNOWN_G); goto OPT_EVAL;} case HOP_CLOSURE_STAR_S: sc->args = list_1(sc, find_symbol_checked(sc, opt_sym2(code))); fill_closure_star(sc, cdr(closure_args(opt_lambda(code)))); unsafe_closure_star(sc); goto BEGIN1; /* -------------------------------------------------------------------------------- */ case OP_UNKNOWN: case HOP_UNKNOWN: if (unknown_ex(sc, find_symbol_checked(sc, car(code))) == goto_OPT_EVAL) goto OPT_EVAL; break; case OP_UNKNOWN_G: case HOP_UNKNOWN_G: if (unknown_g_ex(sc, find_symbol_checked(sc, car(code))) == goto_OPT_EVAL) goto OPT_EVAL; break; case OP_UNKNOWN_GG: case HOP_UNKNOWN_GG: if (unknown_gg_ex(sc, find_symbol_checked(sc, car(code))) == goto_OPT_EVAL) goto OPT_EVAL; break; case OP_UNKNOWN_ALL_S: case HOP_UNKNOWN_ALL_S: if (unknown_all_s_ex(sc, find_symbol_checked(sc, car(code))) == goto_OPT_EVAL) goto OPT_EVAL; break; case OP_UNKNOWN_A: case HOP_UNKNOWN_A: if (unknown_a_ex(sc, find_symbol_checked(sc, car(code))) == goto_OPT_EVAL) goto OPT_EVAL; break; case OP_UNKNOWN_AA: case HOP_UNKNOWN_AA: if (unknown_aa_ex(sc, find_symbol_checked(sc, car(code))) == goto_OPT_EVAL) goto OPT_EVAL; break; case OP_UNKNOWN_ALL_X: case HOP_UNKNOWN_ALL_X: if (unknown_all_x_ex(sc, find_symbol_checked(sc, car(code))) == goto_OPT_EVAL) goto OPT_EVAL; break; /* -------------------------------------------------------------------------------- */ case OP_VECTOR_C: case HOP_VECTOR_C: if (vector_c_ex(sc) == goto_START) goto START; break; case OP_VECTOR_CC: case HOP_VECTOR_CC: if (vector_cc_ex(sc) == goto_START) goto START; break; case OP_VECTOR_A: if (!indirect_cq_function_is_ok(sc, cadr(code))) break; case HOP_VECTOR_A: if (vector_a_ex(sc) == goto_START) goto START; break; case OP_VECTOR_S: case HOP_VECTOR_S: if (vector_s_ex(sc) == goto_START) goto START; break; case OP_STRING_C: case HOP_STRING_C: if (string_c_ex(sc) == goto_START) goto START; break; case OP_STRING_A: if (!indirect_cq_function_is_ok(sc, cadr(code))) break; case HOP_STRING_A: if (string_a_ex(sc) == goto_START) goto START; break; case OP_STRING_S: case HOP_STRING_S: if (string_s_ex(sc) == goto_START) goto START; break; case OP_HASH_TABLE_C: case HOP_HASH_TABLE_C: { s7_pointer s; s = find_symbol_checked(sc, car(code)); if (!is_hash_table(s)) break; sc->value = s7_hash_table_ref(sc, s, cadr(code)); goto START; } case OP_HASH_TABLE_S: case HOP_HASH_TABLE_S: { s7_pointer s; s = find_symbol_checked(sc, car(code)); if (!is_hash_table(s)) break; sc->value = s7_hash_table_ref(sc, s, find_symbol_checked(sc, cadr(code))); goto START; } case OP_HASH_TABLE_A: if (!indirect_cq_function_is_ok(sc, cadr(code))) break; case HOP_HASH_TABLE_A: { s7_pointer s; s = find_symbol_checked(sc, car(code)); if (!is_hash_table(s)) break; sc->value = s7_hash_table_ref(sc, s, c_call(cdr(code))(sc, cadr(code))); goto START; } case OP_ENVIRONMENT_C: case HOP_ENVIRONMENT_C: { s7_pointer s; s = find_symbol_checked(sc, car(code)); if (!is_let(s)) break; sc->value = s7_let_ref(sc, s, cadr(code)); goto START; } case OP_ENVIRONMENT_S: case HOP_ENVIRONMENT_S: { s7_pointer s; s = find_symbol_checked(sc, car(code)); if (!is_let(s)) break; sc->value = s7_let_ref(sc, s, find_symbol_checked(sc, cadr(code))); goto START; } case OP_ENVIRONMENT_Q: case HOP_ENVIRONMENT_Q: { s7_pointer s, sym; s = find_symbol_checked(sc, car(code)); if (!is_let(s)) break; sym = cadr(cadr(code)); if (is_symbol(sym)) sc->value = let_ref_1(sc, s, sym); else return(wrong_type_argument_with_type(sc, sc->LET_REF, 2, sym, A_SYMBOL)); /* (e '(1)) */ goto START; } case OP_ENVIRONMENT_A: if (!indirect_cq_function_is_ok(sc, cadr(code))) break; case HOP_ENVIRONMENT_A: { s7_pointer s, sym; s = find_symbol_checked(sc, car(code)); if (!is_let(s)) break; sym = c_call(cdr(code))(sc, cadr(code)); if (is_symbol(sym)) sc->value = let_ref_1(sc, s, sym); else return(wrong_type_argument_with_type(sc, sc->LET_REF, 2, sym, A_SYMBOL)); /* (e expr) where expr->#f */ goto START; } case OP_PAIR_C: case HOP_PAIR_C: { s7_pointer s; s = find_symbol_checked(sc, car(code)); if (!is_pair(s)) break; /* this used to check is_integer(cadr(code)) but surely an error is correct if s is a pair? */ sc->value = list_ref_1(sc, s, cadr(code)); goto START; } case OP_PAIR_A: if (!indirect_cq_function_is_ok(sc, cadr(code))) break; case HOP_PAIR_A: { s7_pointer s, x; s = find_symbol_checked(sc, car(code)); if (!is_pair(s)) break; x = c_call(cdr(code))(sc, cadr(code)); sc->value = list_ref_1(sc, s, x); goto START; } case OP_PAIR_S: case HOP_PAIR_S: { s7_pointer s, ind; s = find_symbol_checked(sc, car(code)); if (!is_pair(s)) break; ind = find_symbol_checked(sc, cadr(code)); sc->value = list_ref_1(sc, s, ind); goto START; } case OP_C_OBJECT: case HOP_C_OBJECT: { s7_pointer c; c = find_symbol_checked(sc, car(code)); if (!is_c_object(c)) break; sc->value = (*(c_object_ref(c)))(sc, c, sc->NIL); goto START; } case OP_C_OBJECT_C: case HOP_C_OBJECT_C: { s7_pointer c; c = find_symbol_checked(sc, car(code)); if (!is_c_object(c)) break; sc->value = (*(c_object_ref(c)))(sc, c, cdr(code)); goto START; } case OP_C_OBJECT_A: if (!indirect_cq_function_is_ok(sc, cadr(code))) break; case HOP_C_OBJECT_A: { s7_pointer c; c = find_symbol_checked(sc, car(code)); if (!is_c_object(c)) break; car(sc->T1_1) = c_call(cdr(code))(sc, cadr(code)); sc->value = (*(c_object_ref(c)))(sc, c, sc->T1_1); goto START; } case OP_C_OBJECT_S: case HOP_C_OBJECT_S: { s7_pointer c; c = find_symbol_checked(sc, car(code)); if (!is_c_object(c)) break; car(sc->T1_1) = find_symbol_checked(sc, cadr(code)); sc->value = (*(c_object_ref(c)))(sc, c, sc->T1_1); goto START; } default: fprintf(stderr, "bad op in opt_eval: op %u, is_opt: %d, %s\n", optimize_op(code), is_optimized(code), DISPLAY_80(code)); break; } /* else cancel all the optimization info -- someone stepped on our symbol */ /* there is a problem with this -- if the caller still insists on goto OPT_EVAL, for example, * we get here over and over. (let ((x (list (car y))))...) where list is redefined away. */ clear_all_optimizations(sc, code); /* and fall into the normal evaluator */ } /* fprintf(stderr, "trail: %s\n", DISPLAY(sc->code)); */ { s7_pointer code, carc; code = sc->code; if (is_pair(code)) { sc->cur_code = code; carc = car(code); if (typesflag(carc) == SYNTACTIC_TYPE) { set_type(code, SYNTACTIC_PAIR); car(code) = syntax_symbol(slot_value(initial_slot(carc))); /* clear possible optimization confusion */ sc->op = (opcode_t)symbol_syntax_op(car(code)); pair_set_syntax_op(code, sc->op); sc->code = cdr(code); goto START_WITHOUT_POP_STACK; } /* -------------------------------------------------------------------------------- */ /* trailers */ if (is_symbol(carc)) { /* car is a symbol, sc->code a list */ sc->value = find_global_symbol_checked(sc, carc); sc->code = cdr(code); /* drop into eval args */ } else { /* very uncommon case: car is either itself a pair or some non-symbol */ if (is_pair(carc)) { /* evaluate the inner list but that list can be circular: carc: #1=(#1# #1#)! * and the cycle can be well-hidden -- #1=((#1 2) . 2) and other such stuff */ if (sc->stack_end >= sc->stack_resize_trigger) check_for_cyclic_code(sc, code); push_stack(sc, OP_EVAL_ARGS, sc->NIL, cdr(code)); if (typesflag(car(carc)) == SYNTACTIC_TYPE) /* was checking for is_syntactic here but that can be confused by successive optimizer passes: * (define (hi) (((lambda () list)) 1 2 3)) etc */ { if ((car(carc) == sc->QUOTE) && /* ('and #f) */ ((!is_pair(cdr(carc))) || /* ((quote . #\h) (2 . #\i)) ! */ (is_syntactic(cadr(carc))))) return(apply_error(sc, (is_pair(cdr(carc))) ? cadr(carc) : carc, cdr(code))); sc->op = (opcode_t)symbol_syntax_op(car(carc)); sc->code = cdr(carc); goto START_WITHOUT_POP_STACK; } push_stack(sc, OP_EVAL_ARGS, sc->NIL, cdr(carc)); sc->code = car(carc); goto EVAL; } else { /* car must be the function to be applied */ sc->value = _NFre(carc); sc->code = cdr(code); /* drop into OP_EVAL_ARGS */ } } } else /* sc->code is not a pair */ { if (is_symbol(code)) { sc->value = find_symbol_checked(sc, code); pop_stack(sc); if (sc->op != OP_EVAL_ARGS) goto START_WITHOUT_POP_STACK; /* drop into OP_EVAL_ARGS */ } else { /* sc->code is not a pair or a symbol */ sc->value = _NFre(code); goto START; } } /* sc->value is car=something applicable * sc->code = rest of expression * sc->args is nil (set by the drop-through cases above -- perhaps clearer to bring that down?) */ } case OP_EVAL_ARGS: if (dont_eval_args(sc->value)) { if (is_any_macro(sc->value)) { /* macro expansion */ sc->args = copy_list_with_arglist_error(sc, sc->code); sc->code = sc->value; goto APPLY; /* not UNSAFE_CLOSURE because it might be a bacro */ } /* (define progn begin) (progn (display "hi") (+ 1 23)) */ if (!is_syntax(sc->value)) eval_error(sc, "attempt to evaluate: ~A?", sc->code); sc->op = (opcode_t)syntax_opcode(sc->value); goto START_WITHOUT_POP_STACK; } /* sc->value is the func * we don't have to delay lookup of the func because arg evaluation order is not specified, so * (let ((func +)) (func (let () (set! func -) 3) 2)) * can return 5. */ /* if (is_null(sc->code)) {sc->code = sc->value; goto APPLY;} * this is hit very rarely so it costs more than it saves */ push_op_stack(sc, sc->value); if (sc->op_stack_now >= sc->op_stack_end) resize_op_stack(sc); sc->args = sc->NIL; goto EVAL_ARGS; /* moving eval_args up here (to avoid this goto) was slightly slower, probably by chance. */ case OP_EVAL_ARGS5: /* sc->value is the last arg, sc->code is the previous */ { s7_pointer x, y; new_cell(sc, x, T_PAIR); new_cell_no_check(sc, y, T_PAIR); car(x) = sc->code; cdr(x) = sc->args; car(y) = sc->value; cdr(y) = x; sc->args = safe_reverse_in_place(sc, y); sc->code = pop_op_stack(sc); goto APPLY; } case OP_EVAL_ARGS2: /* sc->value is the last arg, [so if is_null(cdr(sc->code) and current is pair, push args2] */ { s7_pointer x; sc->code = pop_op_stack(sc); new_cell(sc, x, T_PAIR); car(x) = sc->value; cdr(x) = sc->args; if (!is_null(sc->args)) sc->args = safe_reverse_in_place(sc, x); else sc->args = x; goto APPLY; } /* tricky cases here all involve values (i.e. multiple-values) */ case OP_EVAL_ARGS_P_2: /* from HOP_SAFE_C_SP||CP|QP, handled like P_1 case above * primarily involves generators: (outa i (nrcos gen)) etc */ car(sc->T2_1) = sc->args; car(sc->T2_2) = sc->value; sc->value = c_call(sc->code)(sc, sc->T2_1); break; case OP_EVAL_ARGS_P_2_MV: sc->args = cons(sc, sc->args, sc->value); sc->code = c_function_base(opt_cfunc(sc->code)); goto APPLY; case OP_EVAL_ARGS_SSP_1: /* from HOP_SAFE_C_SSP */ car(sc->T3_3) = sc->value; car(sc->T3_1) = find_symbol_checked(sc, cadr(sc->code)); car(sc->T3_2) = find_symbol_checked(sc, caddr(sc->code)); sc->value = c_call(sc->code)(sc, sc->T3_1); break; case OP_EVAL_ARGS_SSP_MV: sc->args = cons(sc, find_symbol_checked(sc, cadr(sc->code)), cons(sc, find_symbol_checked(sc, caddr(sc->code)), sc->value)); sc->code = c_function_base(opt_cfunc(sc->code)); goto APPLY; case OP_EVAL_ARGS_P_3: car(sc->T2_2) = find_symbol_checked(sc, caddr(sc->code)); /* we have to wait because we say the evaluation order is always left to right * and the first arg's evaluation might change the value of the second arg. */ car(sc->T2_1) = sc->value; sc->value = c_call(sc->code)(sc, sc->T2_1); break; case OP_EVAL_ARGS_P_3_MV: /* (define (hi a) (+ (values 1 2) a)) * (define (hi a) (log (values 1 2) a)) */ sc->w = sc->value; sc->args = cons(sc, find_symbol_checked(sc, caddr(sc->code)), sc->w); sc->code = c_function_base(opt_cfunc(sc->code)); goto APPLY; case OP_EVAL_ARGS_P_4: car(sc->T2_1) = sc->value; car(sc->T2_2) = sc->args; sc->value = c_call(sc->code)(sc, sc->T2_1); break; case OP_EVAL_ARGS_P_4_MV: /* same as P_2_MV) */ sc->args = cons(sc, sc->args, sc->value); sc->code = c_function_base(opt_cfunc(sc->code)); goto APPLY; /* (define (hi) (log (values 1 2) 3)) ? */ case OP_SAFE_C_ZC_1: car(sc->T2_1) = sc->value; car(sc->T2_2) = sc->args; sc->value = c_call(sc->code)(sc, sc->T2_1); break; case OP_SAFE_C_SZ_1: car(sc->T2_1) = sc->args; car(sc->T2_2) = sc->value; sc->value = c_call(sc->code)(sc, sc->T2_1); break; case OP_SAFE_C_SZ_SZ: /* S_opSZq actually, in (nominal second, only actual) SZ, S=args, Z=value, * SZ from the SP combiner for SZ */ car(sc->T2_1) = sc->args; car(sc->T2_2) = sc->value; car(sc->T2_2) = c_call(caddr(sc->code))(sc, sc->T2_1); car(sc->T2_1) = find_symbol_checked(sc, cadr(sc->code)); sc->value = c_call(sc->code)(sc, sc->T2_1); break; case OP_SAFE_C_ZA_1: car(sc->T2_2) = c_call(cddr(sc->code))(sc, caddr(sc->code)); car(sc->T2_1) = sc->value; sc->value = c_call(sc->code)(sc, sc->T2_1); break; case OP_SAFE_C_ZZ_1: push_stack(sc, OP_SAFE_C_ZZ_2, sc->value, sc->code); sc->code = caddr(sc->code); goto OPT_EVAL; case OP_SAFE_C_ZZ_2: car(sc->T2_1) = sc->args; car(sc->T2_2) = sc->value; sc->value = c_call(sc->code)(sc, sc->T2_1); break; case OP_SAFE_C_ZAA_1: car(sc->A3_1) = sc->value; car(sc->A3_2) = c_call(cddr(sc->code))(sc, caddr(sc->code)); car(sc->A3_3) = c_call(cdddr(sc->code))(sc, cadddr(sc->code)); sc->value = c_call(sc->code)(sc, sc->A3_1); break; case OP_SAFE_C_AZA_1: car(sc->T3_3) = c_call(cdddr(sc->code))(sc, cadddr(sc->code)); car(sc->T3_2) = sc->value; car(sc->T3_1) = sc->args; sc->value = c_call(sc->code)(sc, sc->T3_1); break; case OP_SAFE_C_SSZ_1: car(sc->T3_1) = sc->args; car(sc->T3_3) = sc->value; car(sc->T3_2) = find_symbol_checked(sc, caddr(sc->code)); sc->value = c_call(sc->code)(sc, sc->T3_1); break; case OP_SAFE_C_AAZ_1: car(sc->T3_1) = pop_op_stack(sc); car(sc->T3_2) = sc->args; car(sc->T3_3) = sc->value; sc->value = c_call(sc->code)(sc, sc->T3_1); break; case OP_SAFE_C_ZZA_1: push_op_stack(sc, sc->value); push_stack(sc, OP_SAFE_C_ZZA_2, sc->args, sc->code); sc->code = caddr(sc->code); goto OPT_EVAL; case OP_SAFE_C_ZZA_2: car(sc->A3_1) = pop_op_stack(sc); car(sc->A3_2) = sc->value; car(sc->A3_3) = c_call(cdddr(sc->code))(sc, cadddr(sc->code)); sc->value = c_call(sc->code)(sc, sc->A3_1); break; case OP_SAFE_C_ZAZ_1: push_op_stack(sc, sc->value); push_stack(sc, OP_SAFE_C_ZAZ_2, c_call(cddr(sc->code))(sc, caddr(sc->code)), sc->code); sc->code = cadddr(sc->code); goto OPT_EVAL; case OP_SAFE_C_ZAZ_2: car(sc->T3_1) = pop_op_stack(sc); car(sc->T3_2) = sc->args; car(sc->T3_3) = sc->value; sc->value = c_call(sc->code)(sc, sc->T3_1); break; case OP_SAFE_C_AZZ_1: push_op_stack(sc, sc->value); push_stack(sc, OP_SAFE_C_AZZ_2, sc->args, sc->code); sc->code = cadddr(sc->code); goto OPT_EVAL; case OP_SAFE_C_AZZ_2: car(sc->T3_1) = sc->args; car(sc->T3_2) = pop_op_stack(sc); car(sc->T3_3) = sc->value; sc->value = c_call(sc->code)(sc, sc->T3_1); break; case OP_SAFE_C_ZZZ_1: push_stack(sc, OP_SAFE_C_ZZZ_2, sc->value, sc->code); sc->code = caddr(sc->code); goto OPT_EVAL; case OP_SAFE_C_ZZZ_2: push_op_stack(sc, sc->value); push_stack(sc, OP_SAFE_C_ZZZ_3, sc->args, sc->code); sc->code = cadddr(sc->code); goto OPT_EVAL; case OP_SAFE_C_ZZZ_3: car(sc->T3_1) = sc->args; car(sc->T3_2) = pop_op_stack(sc); car(sc->T3_3) = sc->value; sc->value = c_call(sc->code)(sc, sc->T3_1); break; case OP_SAFE_C_opSq_P_1: /* this is the no-multiple-values case */ car(sc->T2_1) = sc->args; car(sc->T2_2) = sc->value; sc->value = c_call(sc->code)(sc, sc->T2_1); break; case OP_SAFE_C_opSq_P_MV: /* here we need an argnum check since values could have appended any number of args */ sc->args = cons(sc, sc->args, sc->value); /* can values return an improper or circular list? I don't think so: * (values 1 . 2) -> improper arg list error (same with apply values) * * currently (values) does not simply erase itself: * :(let () (define (arg2 a) (let ((b 1)) (set! b (+ a b)) (values))) (define (hi c) (expt (abs c) (arg2 2))) (hi 2)) * ;expt power, argument 2, #, is an untyped but should be a number * :(s7-version (values)) * ;s7-version: too many arguments: (#) * :(exp (values) 0.0) * ;exp: too many arguments: (# 0.0) * * map is explicitly a special case, and surely it is more confusing to have (values) scattered at random. * also this is consistent with the unoptimized version */ sc->code = c_function_base(opt_cfunc(sc->code)); goto APPLY; /* (define (hi a) (+ (abs a) (values 1 2 3))) */ case OP_EVAL_ARGS3: /* sc->value is the next-to-last arg, and we know the last arg is not a list (so values can't mess us up!) */ { s7_pointer x, y, val; val = sc->code; if (is_symbol(val)) val = find_symbol_checked(sc, val); new_cell(sc, x, T_PAIR); new_cell_no_check(sc, y, T_PAIR); car(x) = sc->value; cdr(x) = sc->args; car(y) = val; cdr(y) = x; sc->args = safe_reverse_in_place(sc, y); sc->code = pop_op_stack(sc); goto APPLY; } case OP_EVAL_ARGS4: /* sc->code is a pair, and either cdr(sc->code) is not null or car(sc->code) is a pair * * (#f #f) (env #f) etc. args is very often nil here, so we're looking at 3 simple args * or even just 2 in some cases: (+ req opt) with value 2 and args () */ { s7_pointer x; new_cell(sc, x, T_PAIR); car(x) = sc->value; cdr(x) = sc->args; sc->args = x; /* all the others reverse -- why not this case? -- reverse is at end? (below) */ goto EVAL_ARGS_PAIR; } case OP_EVAL_ARGS1: { s7_pointer x; new_cell(sc, x, T_PAIR); car(x) = sc->value; cdr(x) = sc->args; sc->args = x; } EVAL_ARGS: /* first time, value = op, args = nil, code is args */ if (is_pair(sc->code)) /* evaluate current arg -- must check for pair here, not sc->NIL (improper list as args) */ { s7_pointer car_code; EVAL_ARGS_PAIR: car_code = car(sc->code); /* switch statement here is much slower for some reason */ if (is_pair(car_code)) { if (sc->stack_end >= sc->stack_resize_trigger) check_for_cyclic_code(sc, sc->code); /* all 3 of these push_stacks can result in stack overflow, see above 64065 */ if (is_null(cdr(sc->code))) push_stack(sc, OP_EVAL_ARGS2, sc->args, sc->NIL); else { if (!is_pair(cdr(sc->code))) /* (= 0 '(1 . 2) . 3) */ improper_arglist_error(sc); if ((is_null(cddr(sc->code))) && (!is_pair(cadr(sc->code)))) push_stack(sc, OP_EVAL_ARGS3, sc->args, cadr(sc->code)); else push_stack(sc, OP_EVAL_ARGS4, sc->args, cdr(sc->code)); } sc->code = car_code; if (is_optimized(sc->code)) goto OPT_EVAL; goto EVAL; } /* car(sc->code) is not a pair */ if (is_pair(cdr(sc->code))) { sc->code = cdr(sc->code); if (is_symbol(car_code)) sc->value = find_symbol_checked(sc, car_code); else sc->value = _NFre(car_code); /* sc->value is the current arg's value, sc->code is pointing to the next */ /* cdr(sc->code) may not be a pair or nil here! * (eq? #f . 1) -> sc->code is 1 */ if (is_null(cdr(sc->code))) { s7_pointer x, y, val; /* we're at the last arg, sc->value is the previous one, not yet saved in the args list */ car_code = car(sc->code); if (is_pair(car_code)) { if (sc->stack_end >= sc->stack_resize_trigger) check_for_cyclic_code(sc, sc->code); push_stack(sc, OP_EVAL_ARGS5, sc->args, sc->value); sc->code = car_code; goto EVAL; } /* get the last arg */ if (is_symbol(car_code)) val = find_symbol_checked(sc, car_code); else val = car_code; sc->temp4 = val; /* get the current arg, which is not a list */ sc->code = pop_op_stack(sc); new_cell(sc, x, T_PAIR); new_cell_no_check(sc, y, T_PAIR); car(x) = sc->value; cdr(x) = sc->args; car(y) = val; cdr(y) = x; sc->args = safe_reverse_in_place(sc, y); /* drop into APPLY */ } else { /* here we know sc->code is a pair, cdr(sc->code) is not null * sc->value is the previous arg's value */ s7_pointer x; new_cell(sc, x, T_PAIR); car(x) = sc->value; cdr(x) = sc->args; sc->args = x; goto EVAL_ARGS_PAIR; } } else { /* here we've reached the last arg (sc->code == nil), it is not a pair */ s7_pointer x, val; if (!is_null(cdr(sc->code))) improper_arglist_error(sc); sc->code = pop_op_stack(sc); if (is_symbol(car_code)) val = find_symbol_checked(sc, car_code); /* this has to precede the set_type below */ else val = car_code; sc->temp4 = val; new_cell(sc, x, T_PAIR); car(x) = val; cdr(x) = sc->args; if (!is_null(sc->args)) sc->args = safe_reverse_in_place(sc, x); else sc->args = x; /* drop into APPLY */ } } else /* got all args -- go to apply */ { if (is_not_null(sc->code)) improper_arglist_error(sc); else { sc->code = pop_op_stack(sc); sc->args = safe_reverse_in_place(sc, sc->args); /* we could omit the arg reversal in many cases, but lots of code assumes the args are in order; * adding a bit for this in the type field saves some time in s7test (many + and * tests), but costs * about the same time in other cases, so it's not a clear win. */ } } /* turning this into a call on an array of functions was not a complete disaster, but tauto.scm was ~1.5% slower. * the array-index overhead is the same as the current switch statement's, but there was also the boolean+jump overhead, * and the function-local overhead currently otherwise 0 (I assume because the compiler can simply plug it in here). */ APPLY: /* fprintf(stderr, "apply %s to %s\n", DISPLAY(sc->code), DISPLAY(sc->args)); */ switch (type(sc->code)) { case T_C_FUNCTION: apply_c_function(sc); goto START; case T_C_ANY_ARGS_FUNCTION: apply_c_any_args_function(sc); goto START; case T_C_FUNCTION_STAR: apply_c_function_star(sc); goto START; case T_C_OPT_ARGS_FUNCTION: apply_c_opt_args_function(sc); goto START; case T_C_RST_ARGS_FUNCTION: apply_c_rst_args_function(sc); goto START; case T_C_MACRO: apply_c_macro(sc); goto EVAL; case T_CONTINUATION: apply_continuation(sc); goto START; case T_GOTO: call_with_exit(sc); goto START; case T_C_OBJECT: apply_c_object(sc); goto START; case T_INT_VECTOR: case T_FLOAT_VECTOR: case T_VECTOR: apply_vector(sc); goto START; case T_STRING: apply_string(sc); goto START; case T_HASH_TABLE: apply_hash_table(sc); goto START; case T_ITERATOR: apply_iterator(sc); goto START; case T_LET: apply_let(sc); goto START; case T_SYNTAX: apply_syntax(sc); goto START_WITHOUT_POP_STACK; case T_PAIR: if (apply_pair(sc) == goto_APPLY) goto APPLY; goto START; case T_MACRO: if (is_expansion(sc->code)) push_stack(sc, OP_EXPANSION, sc->NIL, sc->NIL); else push_stack(sc, OP_EVAL_MACRO, sc->NIL, sc->NIL); new_frame(sc, closure_let(sc->code), sc->envir); apply_lambda(sc); goto BEGIN1; case T_BACRO: push_stack(sc, OP_EVAL_MACRO, sc->NIL, sc->NIL); new_frame(sc, sc->envir, sc->envir); /* like let* -- we'll be adding macro args, so might as well sequester things here */ apply_lambda(sc); goto BEGIN1; case T_CLOSURE: check_stack_size(sc); new_frame(sc, closure_let(sc->code), sc->envir); apply_lambda(sc); goto BEGIN1; case T_MACRO_STAR: push_stack(sc, OP_EVAL_MACRO, sc->NIL, sc->NIL); new_frame(sc, closure_let(sc->code), sc->envir); if (apply_lambda_star(sc) == goto_EVAL) goto EVAL; goto BEGIN1; case T_BACRO_STAR: push_stack(sc, OP_EVAL_MACRO, sc->NIL, sc->NIL); new_frame(sc, sc->envir, sc->envir); if (apply_lambda_star(sc) == goto_EVAL) goto EVAL; goto BEGIN1; case T_CLOSURE_STAR: check_stack_size(sc); sc->envir = new_frame_in_env(sc, closure_let(sc->code)); if (apply_lambda_star(sc) == goto_EVAL) goto EVAL; goto BEGIN1; default: return(apply_error(sc, sc->code, sc->args)); } case OP_APPLY: /* apply 'code' to 'args' */ if (needs_copied_args(sc->code)) sc->args = copy_list(sc, sc->args); goto APPLY; /* (let ((lst '((1 2)))) (define (identity x) x) (cons (apply identity lst) lst)) */ case OP_LAMBDA_STAR_DEFAULT: /* sc->args is the current closure arg list position, sc->value is the default expression's value */ slot_set_value(sc->args, sc->value); sc->args = slot_pending_value(sc->args); if (lambda_star_default(sc) == goto_EVAL) goto EVAL; pop_stack_no_op(sc); sc->code = closure_body(sc->code); goto BEGIN1; case OP_MACROEXPAND_1: sc->args = cdar(sc->code); sc->code = sc->value; goto MACROEXPAND; case OP_MACROEXPAND: /* mimic APPLY above, but don't push OP_EVAL_MACRO or OP_EXPANSION * (define-macro (mac a) `(+ ,a 1)) (macroexpand (mac 3)), sc->code: ((mac 3)) */ if ((!is_pair(sc->code)) || (!is_pair(car(sc->code)))) eval_error(sc, "macroexpand argument is not a macro call: ~A", sc->code); if (!is_null(cdr(sc->code))) eval_error(sc, "macroexpand: too many arguments: ~A", sc->code); if (is_pair(caar(sc->code))) /* (macroexpand ((symbol->value 'mac) (+ 1 2))) */ { push_stack(sc, OP_MACROEXPAND_1, sc->NIL, sc->code); sc->code = caar(sc->code); goto EVAL; } sc->args = cdar(sc->code); if (!is_symbol(caar(sc->code))) eval_error(sc, "macroexpand argument is not a macro call: ~A", sc->code); sc->code = find_symbol_checked(sc, caar(sc->code)); MACROEXPAND: switch (type(sc->code)) { case T_MACRO: new_frame(sc, closure_let(sc->code), sc->envir); apply_lambda(sc); goto BEGIN1; case T_BACRO: new_frame(sc, sc->envir, sc->envir); apply_lambda(sc); goto BEGIN1; case T_MACRO_STAR: new_frame(sc, closure_let(sc->code), sc->envir); if (apply_lambda_star(sc) == goto_EVAL) goto EVAL; goto BEGIN1; case T_BACRO_STAR: new_frame(sc, sc->envir, sc->envir); if (apply_lambda_star(sc) == goto_EVAL) goto EVAL; goto BEGIN1; case T_C_MACRO: sc->value = c_macro_call(sc->code)(sc, sc->args); goto START; } eval_error(sc, "macroexpand argument is not a macro call: ~A", sc->args); case OP_QUOTE: case OP_QUOTE_UNCHECKED: /* I think a quoted list in another list can be applied to a function, come here and * be changed to unchecked, set-cdr! or something clobbers the argument so we get * here on the next time around with the equivalent of (quote . 0) so unchecked * quote needs more thought. */ check_quote(sc); sc->value = car(sc->code); break; case OP_DEFINE_FUNCHECKED: define_funchecked(sc); break; case OP_DEFINE_CONSTANT1: sc->code = car(sc->code); if (is_pair(sc->code)) sc->code = car(sc->code); /* (define-constant (ex3 a)...) */ if (is_symbol(sc->code)) set_immutable(sc->code); break; case OP_DEFINE_CONSTANT: if ((!is_pair(sc->code)) || (!is_pair(cdr(sc->code)))) /* (define-constant) */ eval_error(sc, "define-constant: not enough arguments: ~S", sc->code); if ((is_symbol(car(sc->code))) && /* (define-constant abs abs): "abs will not be touched" */ (car(sc->code) == cadr(sc->code)) && (symbol_id(car(sc->code)) == 0) && /* else (let iter ... (define-constant iter iter) ...) -> segfault on later calls */ (is_null(cddr(sc->code)))) { set_immutable(car(sc->code)); sc->value = find_symbol_checked(sc, car(sc->code)); goto START; } push_stack(sc, OP_DEFINE_CONSTANT1, sc->NIL, sc->code); case OP_DEFINE_STAR: case OP_DEFINE: check_define(sc); case OP_DEFINE_CONSTANT_UNCHECKED: case OP_DEFINE_STAR_UNCHECKED: case OP_DEFINE_UNCHECKED: if (define_unchecked_ex(sc) == goto_EVAL) goto EVAL; case OP_DEFINE1: if (define1_ex(sc) == goto_APPLY) goto APPLY; case OP_DEFINE_WITH_ACCESSOR: define2_ex(sc); break; /* -------------------------------- SET! -------------------------------- */ case OP_SET_PAIR_P: /* ([set!] (car a) (cadr a)) */ /* here the pair can't generate multiple values, or if it does, it's an error (caught below) * splice_in_values will notice the OP_SET_PAIR_P_1 and complain. * (let () (define (hi) (let ((str "123")) (set! (str 0) (values #\a)) str)) (hi) (hi)) is "a23" * (let () (define (hi) (let ((str "123")) (set! (str 0) (values #\a #\b)) str)) (hi) (hi)) is an error from the first call (caught elsewhere) * (let () (define (hi) (let ((str "123")) (set! (str 0) (values #\a #\b)) str)) (catch #t hi (lambda a a)) (hi)) is an error from the second call */ push_stack_no_args(sc, OP_SET_PAIR_P_1, sc->code); sc->code = cadr(sc->code); goto EVAL; case OP_SET_PAIR_Z: push_stack_no_args(sc, OP_SET_PAIR_P_1, sc->code); sc->code = cadr(sc->code); goto OPT_EVAL; case OP_SET_PAIR_A: { s7_pointer obj, val; obj = find_symbol_checked(sc, caar(sc->code)); val = c_call(cdr(sc->code))(sc, cadr(sc->code)); /* this call can step on sc->Tx_x */ car(sc->T2_1) = cadar(sc->code); /* might be a constant: (set! (mus-sound-srate "oboe.snd") 12345) */ if (is_symbol(car(sc->T2_1))) car(sc->T2_1) = find_symbol_checked(sc, cadar(sc->code)); car(sc->T2_2) = val; sc->value = c_function_call(c_function_setter(obj))(sc, sc->T2_1); } break; case OP_SET_PAIR_C_P: /* ([set!] (name (+ i 1)) (if (eq? (car a) 'car) #\a #\d)) */ push_stack_no_args(sc, OP_SET_PAIR_C_P_1, sc->code); sc->code = cadr(sc->code); goto EVAL; case OP_SET_PAIR_C_P_1: /* code: ((name (+ i 1)) ...) for example, so cadar is the c_c expr and its args are cdr(cadar) */ sc->temp8 = sc->value; if (set_pair_p_3(sc, find_symbol(sc, caar(sc->code)), c_call(cadar(sc->code))(sc, cdadar(sc->code)), sc->temp8)) goto APPLY; break; case OP_SET_PAIR_C: /* ([set!] (name (+ len 1)) #\r) */ { s7_pointer value; value = cadr(sc->code); if (is_symbol(value)) value = find_symbol_checked(sc, value); if (set_pair_p_3(sc, find_symbol(sc, caar(sc->code)), c_call(cadar(sc->code))(sc, cdadar(sc->code)), value)) goto APPLY; } break; case OP_SET_LET_S: /* (set! (*s7* 'print-length) i) */ if (set_pair_p_3(sc, find_symbol(sc, caar(sc->code)), cadr(cadar(sc->code)), find_symbol_checked(sc, cadr(sc->code)))) goto APPLY; break; case OP_SET_LET_ALL_X: /* (set! (hook 'result) 123) or (set! (H 'c) 32) */ if (set_pair_p_3(sc, find_symbol(sc, caar(sc->code)), cadr(cadar(sc->code)), c_call(cdr(sc->code))(sc, cadr(sc->code)))) goto APPLY; break; case OP_SET_PAIR_ZA: /* unknown setter pair, but value is easy */ sc->value = c_call(cdr(sc->code))(sc, cadr(sc->code)); /* fall through */ case OP_SET_PAIR_P_1: { /* car(sc->code) is a pair, caar(code) is the object with a setter, it has one (safe) argument, and one safe value to set * (set! (str i) #\a) in a function (both inner things need to be symbols (or the second can be a quoted symbol) to get here) * the inner list is a proper list, with no embedded list at car. */ s7_pointer arg, value; value = sc->value; arg = cadar(sc->code); if (is_symbol(arg)) arg = find_symbol_checked(sc, arg); else { if (is_pair(arg)) arg = cadr(arg); /* can only be (quote ...) in this case */ } if (set_pair_p_3(sc, find_symbol(sc, caar(sc->code)), arg, value)) goto APPLY; } break; case OP_SET_PAIR: { /* ([set!] (procedure-setter g) s) or ([set!] (str 0) #\a) */ s7_pointer obj, arg, value; value = cadr(sc->code); if (is_symbol(value)) value = find_symbol_checked(sc, value); arg = cadar(sc->code); if (is_symbol(arg)) arg = find_symbol_checked(sc, arg); else { if (is_pair(arg)) arg = cadr(arg); /* can only be (quote ...) in this case */ } obj = caar(sc->code); if (is_symbol(obj)) obj = find_symbol(sc, obj); if (set_pair_p_3(sc, obj, arg, value)) goto APPLY; } break; /* this is (set! (getter) val) where getter is a global c_function (a built-in pws) and val is not a pair */ case OP_SET_PWS: /* (set! (mus-clipping) #f) */ set_pws_ex(sc); break; case OP_INCREMENT_1: increment_1_ex(sc); break; case OP_DECREMENT_1: decrement_1_ex(sc); break; #define SET_CASE(Op, Code) \ case Op: \ { \ s7_pointer lx; \ lx = find_symbol(sc, _TSet(car(sc->code))); \ if (!is_slot(lx)) eval_type_error(sc, "set! ~A: unbound variable", sc->code); \ Code; \ sc->value = slot_value(lx); \ goto START; \ } SET_CASE(OP_SET_SYMBOL_C, slot_set_value(lx, cadr(sc->code))) SET_CASE(OP_SET_SYMBOL_Q, slot_set_value(lx, cadr(cadr(sc->code)))) SET_CASE(OP_SET_SYMBOL_A, slot_set_value(lx, c_call(cdr(sc->code))(sc, cadr(sc->code)))) SET_CASE(OP_SET_SYMBOL_S, slot_set_value(lx, find_symbol_checked(sc, cadr(sc->code)))) SET_CASE(OP_SET_CONS, slot_set_value(lx, cons(sc, find_symbol_checked(sc, opt_sym2(sc->code)), slot_value(lx)))) /* ([set!] bindings (cons v bindings)) */ SET_CASE(OP_SET_SYMBOL_opCq, slot_set_value(lx, c_call(cadr(sc->code))(sc, opt_pair2(sc->code)))) /* here we know the symbols do not have accessors, at least at optimization time */ SET_CASE(OP_SET_SYMBOL_opSq, do { \ car(sc->T1_1) = find_symbol_checked(sc, opt_sym2(sc->code)); \ slot_set_value(lx, c_call(cadr(sc->code))(sc, sc->T1_1)); \ } while (0)) SET_CASE(OP_SET_SYMBOL_opSSq, do { \ car(sc->T2_1) = find_symbol_checked(sc, car(opt_pair2(sc->code))); \ car(sc->T2_2) = find_symbol_checked(sc, cadr(opt_pair2(sc->code))); \ slot_set_value(lx, c_call(cadr(sc->code))(sc, sc->T2_1)); \ } while (0)) SET_CASE(OP_SET_SYMBOL_opSSSq, do { \ car(sc->T3_1) = find_symbol_checked(sc, car(opt_pair2(sc->code))); \ car(sc->T3_2) = find_symbol_checked(sc, opt_sym1(opt_pair2(sc->code))); \ car(sc->T3_3) = find_symbol_checked(sc, opt_sym2(opt_pair2(sc->code))); \ slot_set_value(lx, c_call(cadr(sc->code))(sc, sc->T3_1)); \ } while (0)) SET_CASE(OP_INCREMENT_SS, /* ([set!] x (+ x i)) */ do { \ car(sc->T2_1) = slot_value(lx); \ car(sc->T2_2) = find_symbol_checked(sc, cadr(opt_pair2(sc->code))); \ slot_set_value(lx, c_call(cadr(sc->code))(sc, sc->T2_1)); \ } while (0)) SET_CASE(OP_INCREMENT_SSS, /* ([set!] x (+ x y z)) -- nearly always involves reals */ do { \ s7_pointer x1; s7_pointer x2; s7_pointer x3; \ x1 = slot_value(lx); \ x2 = find_symbol_checked(sc, opt_sym1(opt_pair2(sc->code))); \ x3 = find_symbol_checked(sc, opt_sym2(opt_pair2(sc->code))); \ if ((is_t_real(x1)) && (is_t_real(x2)) && (is_t_real(x3))) \ slot_set_value(lx, make_real(sc, real(x1) + real(x2) + real(x3))); \ else { \ car(sc->T3_1) = x1; car(sc->T3_2) = x2; car(sc->T3_3) = x3; \ slot_set_value(lx, global_add(sc, sc->T3_1)); \ } \ } while (0)) SET_CASE(OP_INCREMENT_SA, do { \ s7_pointer arg; \ arg = opt_pair2(sc->code); \ car(sc->T2_2) = c_call(arg)(sc, car(arg)); \ car(sc->T2_1) = slot_value(lx); \ slot_set_value(lx, c_call(cadr(sc->code))(sc, sc->T2_1)); \ } while (0)) SET_CASE(OP_INCREMENT_SAA, /* (set! sum (+ sum (expt k i) (expt (- k) i))) -- oops */ do { \ s7_pointer arg; \ arg = opt_pair2(sc->code); /* cddr(value) */ \ car(sc->A3_3) = c_call(cdr(arg))(sc, cadr(arg)); \ car(sc->A3_2) = c_call(arg)(sc, car(arg)); \ car(sc->A3_1) = slot_value(lx); \ slot_set_value(lx, c_call(cadr(sc->code))(sc, sc->A3_1)); \ } while (0)) case OP_SET_SAFE: { s7_pointer lx; lx = find_symbol(sc, _TSet(sc->code)); /* SET_CASE above looks for car(sc->code) */ if (!is_slot(lx)) eval_type_error(sc, "set! ~A: unbound variable", sc->code); slot_set_value(lx, sc->value); sc->value = slot_value(lx); } break; case OP_SET_SYMBOL_P: /* ([set!] f (lambda () 1)) */ push_stack_no_args(sc, OP_SET_SAFE, car(sc->code)); sc->code = cadr(sc->code); goto EVAL; case OP_SET_SYMBOL_Z: /* ([set!] sum (+ sum n)) */ push_stack_no_args(sc, OP_SET_SAFE, car(sc->code)); sc->code = cadr(sc->code); goto OPT_EVAL; case OP_INCREMENT_SZ: { s7_pointer sym; sym = find_symbol(sc, car(sc->code)); if (is_slot(sym)) { push_stack(sc, OP_INCREMENT_SZ_1, sym, sc->code); sc->code = opt_pair2(sc->code); /* caddr(cadr(sc->code)); */ goto OPT_EVAL; } eval_type_error(sc, "set! ~A: unbound variable", sc->code); } case OP_INCREMENT_SZ_1: car(sc->T2_1) = slot_value(sc->args); car(sc->T2_2) = sc->value; sc->value = c_call(cadr(sc->code))(sc, sc->T2_1); slot_set_value(sc->args, sc->value); break; case OP_SET2: if (is_pair(sc->value)) { /* (let ((L '((1 2 3)))) (set! ((L 0) 1) 32) L) * (let ((L '(((1 2 3))))) (set! ((L 0) 0 1) 32) L) * any deeper nesting was handled already by the first eval * set! looks at its first argument, if it's a symbol, it sets the associated value, * if it's a list, it looks at the car of that list to decide which setter to call, * if it's a list of lists, it passes the embedded lists to eval, then looks at the * car of the result. This means that we can do crazy things like: * (let ((x '(1)) (y '(2))) (set! ((if #t x y) 0) 32) x) * * the other args need to be evaluated (but not the list as if it were code): * (let ((L '((1 2 3))) (index 1)) (set! ((L 0) index) 32) L) */ if (!is_proper_list(sc, sc->args)) /* (set! ('(1 2) 1 . 2) 1) */ eval_error(sc, "set! target arguments are an improper list: ~A", sc->args); /* in all of these cases, we might need to GC protect the temporary lists */ if (is_multiple_value(sc->value)) sc->code = cons(sc, sc->SET, s7_append(sc, multiple_value(sc->value), s7_append(sc, sc->args, sc->code))); /* drop into OP_SET */ else { if (sc->args != sc->NIL) { push_op_stack(sc, sc->List_Set); push_stack(sc, OP_EVAL_ARGS1, list_1(sc, sc->value), s7_append(sc, cdr(sc->args), sc->code)); sc->code = car(sc->args); } else eval_error(sc, "list set!: not enough arguments: ~S", sc->code); goto EVAL; } } else { if (s7_is_vector(sc->value)) { /* (let ((L #(#(1 2 3) #(4 5 6)))) (set! ((L 1) 0) 32) L) * bad case when args is nil: (let ((L #(#(1 2 3) #(4 5 6)))) (set! ((L 1)) 32) L) */ if (sc->args != sc->NIL) { push_op_stack(sc, sc->Vector_Set); push_stack(sc, OP_EVAL_ARGS1, list_1(sc, sc->value), s7_append(sc, cdr(sc->args), sc->code)); sc->code = car(sc->args); } else eval_error(sc, "vector set!: not enough arguments: ~S", sc->code); goto EVAL; } sc->code = cons_unchecked(sc, cons(sc, sc->value, sc->args), sc->code); } /* fall through */ case OP_SET: /* entry for set! */ check_set(sc); case OP_SET_UNCHECKED: if (is_pair(car(sc->code))) /* has accessor */ { int choice; choice = set_pair_ex(sc); if (choice == goto_EVAL) goto EVAL; if (choice == goto_START) goto START; if (choice == goto_APPLY) goto APPLY; goto EVAL_ARGS; } /* fall through */ case OP_SET_NORMAL: { s7_pointer x; x = cadr(sc->code); if (is_pair(x)) { push_stack_no_args(sc, OP_SET1, car(sc->code)); sc->code = x; goto EVAL; } if (is_symbol(x)) sc->value = find_symbol_checked(sc, x); else sc->value = _NFre(x); sc->code = car(sc->code); } case OP_SET1: { s7_pointer lx; /* if unbound variable hook here, we need the binding, not the current value */ lx = find_symbol(sc, _TSet(sc->code)); if (is_slot(lx)) { if (slot_has_accessor(lx)) { s7_pointer func; func = slot_accessor(lx); if (is_procedure_or_macro(func)) { if (is_c_function(func)) { car(sc->T2_1) = sc->code; car(sc->T2_2) = sc->value; sc->value = c_function_call(func)(sc, sc->T2_1); if (sc->value == sc->ERROR) /* backwards compatibility... */ return(s7_error(sc, sc->ERROR, set_elist_3(sc, make_string_wrapper(sc, "can't set ~S to ~S"), car(sc->T2_1), car(sc->T2_2)))); } else { sc->args = list_2(sc, sc->code, sc->value); push_stack(sc, OP_SET_WITH_ACCESSOR, sc->args, lx); /* op, args, code */ sc->code = func; goto APPLY; } } } else { if (is_syntax(slot_value(lx))) eval_error(sc, "can't set! ~A", sc->code); } slot_set_value(lx, sc->value); goto START; } eval_type_error(sc, "set! ~A: unbound variable", sc->code); } case OP_SET_WITH_ACCESSOR: if (sc->value == sc->ERROR) /* backwards compatibility... */ return(s7_error(sc, sc->ERROR, set_elist_2(sc, make_string_wrapper(sc, "can't set ~S"), sc->args))); slot_set_value(sc->code, sc->value); break; /* -------------------------------- IF -------------------------------- */ case OP_IF: check_if(sc); case OP_IF_UNCHECKED: push_stack_no_args(sc, OP_IF1, cdr(sc->code)); sc->code = car(sc->code); goto EVAL; case OP_IF1: if (is_true(sc, sc->value)) sc->code = car(sc->code); else sc->code = cadr(sc->code); /* even pre-optimization, (if #f #f) ==> # because car(sc->NIL) = sc->UNSPECIFIED */ if (is_pair(sc->code)) goto EVAL; if (is_symbol(sc->code)) sc->value = find_symbol_checked(sc, sc->code); else sc->value = sc->code; break; #define IF_CASE(Op, Code) \ case Op ## _P: Code {sc->code = cadr(sc->code); goto EVAL;} else {sc->value = sc->UNSPECIFIED; goto START;} \ case Op ## _P_P: Code {sc->code = cadr(sc->code); goto EVAL;} else {sc->code = caddr(sc->code); goto EVAL;} IF_CASE(OP_IF_S, if (is_true(sc, find_symbol_checked(sc, car(sc->code))))) IF_CASE(OP_IF_NOT_S, if (is_false(sc, find_symbol_checked(sc, opt_sym2(sc->code))))) IF_CASE(OP_IF_A, if (is_true(sc, c_call(sc->code)(sc, car(sc->code))))) IF_CASE(OP_IF_CC, if (is_true(sc, c_call(car(sc->code))(sc, opt_pair2(sc->code))))) IF_CASE(OP_IF_IS_PAIR, if (is_pair(find_symbol_checked(sc, opt_sym2(sc->code))))) IF_CASE(OP_IF_IS_SYMBOL, if (is_symbol(find_symbol_checked(sc, opt_sym2(sc->code))))) IF_CASE(OP_IF_CS, car(sc->T1_1) = find_symbol_checked(sc, opt_sym2(sc->code)); \ if (is_true(sc, c_call(car(sc->code))(sc, sc->T1_1)))) IF_CASE(OP_IF_CSQ, car(sc->T2_1) = find_symbol_checked(sc, opt_sym3(sc->code)); \ car(sc->T2_2) = opt_con2(sc->code); \ if (is_true(sc, c_call(car(sc->code))(sc, sc->T2_1)))) IF_CASE(OP_IF_CSS, car(sc->T2_1) = find_symbol_checked(sc, opt_sym3(sc->code)); \ car(sc->T2_2) = find_symbol_checked(sc, opt_sym2(sc->code)); if (is_true(sc, c_call(car(sc->code))(sc, sc->T2_1)))) IF_CASE(OP_IF_CSC, car(sc->T2_1) = find_symbol_checked(sc, opt_sym3(sc->code)); \ car(sc->T2_2) = opt_con2(sc->code); \ if (is_true(sc, c_call(car(sc->code))(sc, sc->T2_1)))) IF_CASE(OP_IF_S_opCq, car(sc->T2_2) = c_call(opt_pair2(sc->code))(sc, cdr(opt_pair2(sc->code))); \ car(sc->T2_1) = find_symbol_checked(sc, opt_sym3(sc->code)); \ if (is_true(sc, c_call(car(sc->code))(sc, sc->T2_1)))) IF_CASE(OP_IF_opSSq, {s7_pointer args; s7_pointer val1; \ args = opt_pair2(sc->code); \ val1 = find_symbol_checked(sc, cadr(args)); \ car(sc->T2_2) = find_symbol_checked(sc, opt_sym3(sc->code)); \ car(sc->T2_1) = val1; \ car(sc->T1_1) = c_call(args)(sc, sc->T2_1);} \ if (is_true(sc, c_call(car(sc->code))(sc, sc->T1_1)))) IF_CASE(OP_IF_AND2, if ((is_true(sc, c_call(opt_pair2(sc->code))(sc, car(opt_pair2(sc->code))))) && \ (is_true(sc, c_call(opt_and_2_test(sc->code))(sc, car(opt_and_2_test(sc->code))))))) case OP_IF_P_P: push_stack_no_args(sc, OP_IF_PP, cadr(sc->code)); sc->code = car(sc->code); goto EVAL; case OP_IF_P_P_P: push_stack_no_args(sc, OP_IF_PPP, cdr(sc->code)); sc->code = car(sc->code); goto EVAL; case OP_IF_Z_P: push_stack_no_args(sc, OP_IF_PP, opt_con2(sc->code)); sc->code = car(sc->code); goto OPT_EVAL; case OP_IF_Z_P_P: push_stack_no_args(sc, OP_IF_PPP, cdr(sc->code)); sc->code = car(sc->code); goto OPT_EVAL; case OP_IF_ANDP_P: push_stack_no_args(sc, OP_IF_PP, cadr(sc->code)); sc->code = cdar(sc->code); goto AND_P; case OP_IF_ANDP_P_P: push_stack_no_args(sc, OP_IF_PPP, cdr(sc->code)); sc->code = cdar(sc->code); goto AND_P; case OP_IF_ORP_P: push_stack_no_args(sc, OP_IF_PP, cadr(sc->code)); sc->code = cdar(sc->code); goto OR_P; case OP_IF_ORP_P_P: push_stack_no_args(sc, OP_IF_PPP, cdr(sc->code)); sc->code = cdar(sc->code); goto OR_P; case OP_IF_PPP: if (is_true(sc, sc->value)) sc->code = car(sc->code); else sc->code = cadr(sc->code); goto EVAL; case OP_IF_PP: if (is_true(sc, sc->value)) goto EVAL; sc->value = sc->UNSPECIFIED; break; case OP_IF_P_FEED: /* actually cond right now: (cond (expr => p)) where p is (lambda (s) ...) -- see check_cond */ push_stack_no_args(sc, OP_IF_P_FEED_1, sc->code); sc->code = caar(sc->code); goto EVAL; case OP_IF_P_FEED_1: if (is_true(sc, sc->value)) { if (is_multiple_value(sc->value)) sc->code = cons(sc, opt_lambda2(sc->code), multiple_value(sc->value)); else { new_frame_with_slot(sc, sc->envir, sc->envir, caadr(opt_lambda2(sc->code)), sc->value); sc->code = caddr(opt_lambda2(sc->code)); } goto EVAL; } sc->value = sc->NIL; /* since it's actually cond -- perhaps push as sc->args above */ break; case OP_WHEN: check_when(sc); case OP_WHEN_UNCHECKED: push_stack_no_args(sc, OP_WHEN1, cdr(sc->code)); sc->code = car(sc->code); goto EVAL; case OP_WHEN1: if (is_true(sc, sc->value)) goto BEGIN1; sc->value = sc->UNSPECIFIED; break; case OP_WHEN_S: if (is_true(sc, find_symbol_checked(sc, car(sc->code)))) { sc->code = cdr(sc->code); goto BEGIN1; } sc->value = sc->UNSPECIFIED; break; case OP_UNLESS: check_unless(sc); case OP_UNLESS_UNCHECKED: push_stack_no_args(sc, OP_UNLESS1, cdr(sc->code)); sc->code = car(sc->code); goto EVAL; case OP_UNLESS1: if (is_false(sc, sc->value)) goto BEGIN1; sc->value = sc->UNSPECIFIED; break; case OP_UNLESS_S: if (is_false(sc, find_symbol_checked(sc, car(sc->code)))) { sc->code = cdr(sc->code); goto BEGIN1; } sc->value = sc->UNSPECIFIED; break; case OP_SAFE_C_P_1: car(sc->T1_1) = sc->value; sc->value = c_call(sc->code)(sc, sc->T1_1); break; case OP_SAFE_C_PP_1: /* unless multiple values from last call (first arg), sc->args == sc->NIL because we pushed that. * we get here only from OP_SAFE_C_PP. * * currently splice_in_values changes the operator so if we get here, sc->value is the result of the first arg * * safe_c_pp -> 1, but if mv, -> 3 * 1: -> 2, if mv -> 4 * 2: done (both normal) * 3: -> 5, but if mv, -> 6 * 4: done (1 normal, 2 mv) * 5: done (1 mv, 2 normal) * 6: done (both mv) * * I think safe_c_ppp would require 18 branches (or maybe just collect the args and concatenate at the end?) */ push_stack(sc, OP_SAFE_C_PP_2, sc->value, sc->code); /* mv -> 3 */ sc->code = caddr(sc->code); if (is_optimized(sc->code)) goto OPT_EVAL; goto EVAL; case OP_SAFE_C_PP_2: /* we get here only if neither arg returned multiple values, so sc->args is the first value, and sc->value the second */ car(sc->T2_1) = sc->args; car(sc->T2_2) = sc->value; sc->value = c_call(sc->code)(sc, sc->T2_1); break; case OP_SAFE_C_PP_3: /* we get here if the first arg returned multiple values */ push_stack(sc, OP_SAFE_C_PP_5, sc->value, sc->code); sc->code = caddr(sc->code); if (is_optimized(sc->code)) goto OPT_EVAL; goto EVAL; case OP_SAFE_C_PP_4: /* we get here if the first arg result was normal, but the second had multiple values */ sc->args = cons(sc, sc->args, sc->value); sc->code = c_function_base(opt_cfunc(sc->code)); goto APPLY; case OP_SAFE_C_PP_5: /* 1 mv, 2, normal */ sc->args = s7_append(sc, sc->args, list_1(sc, sc->value)); sc->code = c_function_base(opt_cfunc(sc->code)); goto APPLY; case OP_SAFE_C_PP_6: /* both mv */ sc->args = s7_append(sc, sc->args, sc->value); /* * c_call(sc->code) here is g_add_2, but we have any number of args from a values call * the original (unoptimized) function is (hopefully) c_function_base(opt_cfunc(sc->code))? * (let () (define (ho a) (+ a 2)) (define (hi) (+ (ho 1) (ho 2))) (hi)) -> 7 * (let () (define (ho a) (+ a 2)) (define (hi) (+ (ho 1) (values 3 4))) (hi)) -> 10 * (let () (define (ho a) (+ a 2)) (define (hi) (+ (values 3 4) (ho 1))) (hi)) -> 10 * (let () (define (hi) (+ (values 1 2) (values 3 4))) (hi)) -> 10 */ sc->code = c_function_base(opt_cfunc(sc->code)); goto APPLY; case OP_C_P_1: sc->value = c_call(sc->code)(sc, list_1(sc, sc->value)); break; case OP_C_P_2: /* op_c_p_1 -> mv case: (define (hi) (format (values #f "~A ~D" 1 2))) */ sc->code = c_function_base(opt_cfunc(sc->code)); /* see comment above */ sc->args = copy_list(sc, sc->value); goto APPLY; case OP_SAFE_CLOSURE_P_1: sc->envir = old_frame_with_slot(sc, closure_let(opt_lambda(sc->code)), sc->value); sc->code = closure_body(opt_lambda(sc->code)); goto BEGIN1; case OP_CLOSURE_P_1: /* sc->value is presumably the argument value */ check_stack_size(sc); sc->code = opt_lambda(sc->code); new_frame_with_slot(sc, closure_let(sc->code), sc->envir, car(closure_args(sc->code)), sc->value); sc->code = closure_body(sc->code); goto BEGIN1; case OP_CLOSURE_P_2: /* here we got multiple values */ sc->code = opt_lambda(sc->code); sc->args = copy_list(sc, sc->value); goto APPLY; case OP_C_SP_1: sc->value = c_call(sc->code)(sc, list_2(sc, sc->args, sc->value)); break; case OP_C_SP_2: /* op_c_sp_1 -> mv case: (map + (values '(1 2 3) #(1 2 3))) */ sc->code = c_function_base(opt_cfunc(sc->code)); sc->args = cons(sc, sc->args, copy_list(sc, sc->value)); goto APPLY; /* -------------------------------- LET -------------------------------- */ case OP_LET_NO_VARS: new_frame(sc, sc->envir, sc->envir); sc->code = cdr(sc->code); /* ignore the () */ goto BEGIN1; case OP_NAMED_LET_NO_VARS: new_frame(sc, sc->envir, sc->envir); sc->args = make_closure(sc, sc->NIL, cddr(sc->code), T_CLOSURE); /* sc->args is a temp here */ make_slot_1(sc, sc->envir, car(sc->code), sc->args); sc->code = cddr(sc->code); goto BEGIN1; case OP_LET_C: /* one var, init is constant, incoming sc->code is '(((var val))...)! */ new_frame_with_slot(sc, sc->envir, sc->envir, opt_sym3(sc->code), opt_con2(sc->code)); sc->code = cdr(sc->code); goto BEGIN1; case OP_LET_S: /* one var, init is symbol, incoming sc->code is '(((var sym))...) */ sc->value = find_symbol_checked(sc, opt_sym2(sc->code)); new_frame_with_slot(sc, sc->envir, sc->envir, opt_sym3(sc->code), sc->value); sc->code = cdr(sc->code); goto BEGIN1; case OP_LET_opSq: { s7_pointer binding; binding = caar(sc->code); car(sc->T1_1) = find_symbol_checked(sc, opt_sym2(sc->code)); sc->value = c_call(cadr(binding))(sc, sc->T1_1); new_frame_with_slot(sc, sc->envir, sc->envir, car(binding), sc->value); push_stack_no_args(sc, OP_BEGIN1, cddr(sc->code)); sc->code = cadr(sc->code); goto EVAL; } case OP_LET_opSq_P: { s7_pointer binding; binding = caar(sc->code); car(sc->T1_1) = find_symbol_checked(sc, opt_sym2(sc->code)); sc->value = c_call(cadr(binding))(sc, sc->T1_1); new_frame_with_slot(sc, sc->envir, sc->envir, car(binding), sc->value); sc->code = cadr(sc->code); goto EVAL; } case OP_LET_opCq: /* one var, init is safe_c_c */ sc->value = c_call(opt_pair2(sc->code))(sc, cdr(opt_pair2(sc->code))); new_frame_with_slot(sc, sc->envir, sc->envir, opt_sym3(sc->code), sc->value); sc->code = cdr(sc->code); goto BEGIN1; case OP_LET_opSSq: /* one var, init is safe_c_ss */ { s7_pointer largs, in_val; largs = opt_pair2(sc->code); /* cadr(caar(sc->code)); */ in_val = find_symbol_checked(sc, cadr(largs)); car(sc->T2_2) = find_symbol_checked(sc, opt_sym3(sc->code)); /* caddr(largs)); */ car(sc->T2_1) = in_val; sc->value = c_call(largs)(sc, sc->T2_1); new_frame_with_slot(sc, sc->envir, sc->envir, caaar(sc->code), sc->value); sc->code = cdr(sc->code); goto BEGIN1; } case OP_LET_Z: push_stack(sc, OP_LET_Z_1, opt_sym2(cdr(sc->code)), cadr(sc->code)); sc->code = opt_pair2(sc->code); goto OPT_EVAL; case OP_LET_Z_1: new_frame_with_slot(sc, sc->envir, sc->envir, sc->args, sc->value); goto EVAL; case OP_LET_ONE: /* one var */ { s7_pointer p; p = caar(sc->code); sc->value = cadr(p); if (is_pair(sc->value)) { push_stack(sc, OP_LET_ONE_1, car(p), cdr(sc->code)); /* args code */ sc->code = sc->value; goto EVAL; } if (is_symbol(sc->value)) sc->value = find_symbol_checked(sc, sc->value); sc->code = cdr(sc->code); sc->args = car(p); /* drop through */ } case OP_LET_ONE_1: new_frame_with_slot(sc, sc->envir, sc->envir, sc->args, sc->value); goto BEGIN1; case OP_LET_ALL_C: { s7_pointer p; new_frame(sc, sc->envir, sc->envir); for (p = car(sc->code); is_pair(p); p = cdr(p)) add_slot(sc->envir, caar(p), cadar(p)); sc->code = cdr(sc->code); goto BEGIN1; } case OP_LET_ALL_S: /* n vars, all inits are symbols. We need to GC-protect the new frame-list as it is being * created without tying the new frame into sc->envir until the end. */ { s7_pointer p, frame; frame = make_simple_let(sc); sc->args = frame; for (p = car(sc->code); is_pair(p); p = cdr(p)) add_slot(frame, caar(p), find_symbol_checked(sc, cadar(p))); sc->let_number++; sc->envir = frame; sc->code = cdr(sc->code); goto BEGIN1; } case OP_LET_ALL_opSq: { s7_pointer p, frame; frame = make_simple_let(sc); sc->args = frame; for (p = car(sc->code); is_pair(p); p = cdr(p)) { s7_pointer cp; cp = cadar(p); car(sc->T1_1) = find_symbol_checked(sc, cadr(cp)); add_slot(frame, caar(p), c_call(cp)(sc, sc->T1_1)); } sc->let_number++; sc->envir = frame; sc->code = cdr(sc->code); goto BEGIN1; } /* it is possible to save the frame+slots in a copied symbol+syntax pair, then reuse them * on every call here, but the savings in GC+allocation+setup is less than the cost in * marking the saved stuff past its actual life! (If the code is removed from the heap, * the frame has to be saved on the permanent_objects list). */ case OP_LET_ALL_X: { s7_pointer p, frame; frame = make_simple_let(sc); sc->args = frame; for (p = car(sc->code); is_pair(p); p = cdr(p)) { s7_pointer arg; arg = cdar(p); arg = c_call(arg)(sc, car(arg)); add_slot(frame, caar(p), arg); } sc->let_number++; sc->envir = frame; sc->code = cdr(sc->code); goto BEGIN1; } case OP_NAMED_LET: sc->args = sc->NIL; sc->value = sc->code; sc->code = cadr(sc->code); goto LET1; case OP_LET_UNCHECKED: /* not named, but has vars */ { s7_pointer x; new_cell(sc, x, T_PAIR); car(x) = sc->code; cdr(x) = sc->NIL; sc->args = x; sc->code = car(sc->code); goto LET1A; } case OP_LET: /* sc->code is everything after the let: (let ((a 1)) a) so sc->code is (((a 1)) a) */ /* car can be either a list or a symbol ("named let") */ { bool named_let; check_let(sc); sc->args = sc->NIL; sc->value = sc->code; named_let = is_symbol(car(sc->code)); sc->code = (named_let) ? cadr(sc->code) : car(sc->code); if (is_null(sc->code)) /* (let [name] () ...): no bindings, so skip that step */ { sc->code = sc->value; new_frame(sc, sc->envir, sc->envir); if (named_let) { sc->x = make_closure(sc, sc->NIL, cddr(sc->code), T_CLOSURE); /* args = () in new closure, see NAMED_LET_NO_VARS above */ /* if this is a safe closure, we can build its env in advance and name it (a thunk in this case) */ set_function_env(closure_let(sc->x)); funclet_set_function(closure_let(sc->x), car(sc->code)); make_slot_1(sc, sc->envir, car(sc->code), sc->x); sc->code = cddr(sc->code); sc->x = sc->NIL; } else sc->code = cdr(sc->code); goto BEGIN1; } } LET1: case OP_LET1: { s7_pointer x, y; new_cell(sc, x, T_PAIR); car(x) = sc->value; /* the first time (now handled above), this saves the entire let body across the evaluations -- we pick it up later */ cdr(x) = sc->args; sc->args = x; if (is_pair(sc->code)) { LET1A: x = cadar(sc->code); if (is_pair(x)) { push_stack(sc, OP_LET1, sc->args, cdr(sc->code)); sc->code = x; if (is_optimized(x)) goto OPT_EVAL; goto EVAL; /* this push_stack/goto can't be optimized away via a local optimize_op case statement * because any c_call can trigger an embedded call on the evaluator (for example, * open-sound involves both hooks, and s7_load if the corresponding .scm code exists), * so we have to protect sc->code and sc->args via the stack. (I subsequently added * some protection here, but debugging this is hard, and the gain is not huge). */ } if (is_symbol(x)) sc->value = find_symbol_checked(sc, x); else sc->value = _NFre(x); sc->code = cdr(sc->code); goto LET1; } x = safe_reverse_in_place(sc, sc->args); sc->code = car(x); /* restore the original form */ y = cdr(x); /* use sc->args as the new frame */ sc->y = y; sc->envir = old_frame_in_env(sc, x, sc->envir); { bool named_let; named_let = is_symbol(car(sc->code)); if (named_let) { /* we need to check the current environment for ridiculous cases like * (let hiho ((hiho 4)) hiho) -- I guess hiho is 4 */ s7_pointer let_name; let_name = car(sc->code); sc->envir = new_frame_in_env(sc, sc->envir); sc->w = sc->NIL; for (x = cadr(sc->code); is_pair(x); x = cdr(x)) sc->w = cons(sc, caar(x), sc->w); sc->x = make_closure(sc, sc->w = safe_reverse_in_place(sc, sc->w), cddr(sc->code), T_CLOSURE); sc->w = sc->NIL; if (is_safe_closure(sc->x)) { s7_pointer arg, new_env; new_env = new_frame_in_env(sc, sc->envir); closure_set_let(sc->x, new_env); for (arg = closure_args(sc->x); is_pair(arg); arg = cdr(arg)) make_slot_1(sc, new_env, car(arg), sc->NIL); let_set_slots(new_env, reverse_slots(sc, let_slots(new_env))); } make_slot_1(sc, sc->envir, let_name, sc->x); sc->x = sc->NIL; sc->envir = new_frame_in_env(sc, sc->envir); for (x = cadr(sc->code); is_not_null(y); x = cdr(x)) { s7_pointer sym, args, val; /* reuse the value cells as the new frame slots */ sym = caar(x); if (sym == let_name) let_name = sc->NIL; val = car(y); args = cdr(y); set_type(y, T_SLOT); slot_set_symbol(y, sym); slot_set_value(y, val); next_slot(y) = let_slots(sc->envir); let_set_slots(sc->envir, y); symbol_set_local(sym, let_id(sc->envir), y); y = args; } sc->code = cddr(sc->code); } else { s7_pointer e; unsigned long long int id; e = sc->envir; id = let_id(e); for (x = car(sc->code); is_not_null(y); x = cdr(x)) { s7_pointer sym, args, val; /* reuse the value cells as the new frame slots */ sym = caar(x); val = car(y); args = cdr(y); set_type(y, T_SLOT); slot_set_symbol(y, sym); symbol_set_local(sym, id, y); slot_set_value(y, val); next_slot(y) = let_slots(e); let_set_slots(e, y); y = args; } sc->code = cdr(sc->code); } } sc->y = sc->NIL; goto BEGIN1; } /* -------------------------------- LET* -------------------------------- */ case OP_LET_STAR_ALL_X: { s7_pointer p; for (p = car(sc->code); is_pair(p); p = cdr(p)) { s7_pointer arg; arg = cdar(p); arg = c_call(arg)(sc, car(arg)); new_frame_with_slot(sc, sc->envir, sc->envir, caar(p), arg); } sc->code = cdr(sc->code); goto BEGIN1; } case OP_NAMED_LET_STAR: push_stack(sc, OP_LET_STAR1, sc->code, cadr(sc->code)); sc->code = opt_con2(sc->code); goto EVAL; case OP_LET_STAR2: push_stack(sc, OP_LET_STAR1, sc->code, car(sc->code)); sc->code = opt_con2(sc->code); goto EVAL; case OP_LET_STAR: check_let_star(sc); case OP_LET_STAR_UNCHECKED: if (is_symbol(car(sc->code))) { s7_pointer cx; cx = car(sc->code); sc->value = cdr(sc->code); if (is_null(car(sc->value))) { sc->envir = new_frame_in_env(sc, sc->envir); sc->code = cdr(sc->value); make_slot_1(sc, sc->envir, cx, make_closure(sc, sc->NIL, sc->code, T_CLOSURE_STAR)); goto BEGIN1; } } else { if (is_null(car(sc->code))) { sc->envir = new_frame_in_env(sc, sc->envir); sc->code = cdr(sc->code); goto BEGIN1; } } if (is_symbol(car(sc->code))) { push_stack(sc, OP_LET_STAR1, sc->code, cadr(sc->code)); sc->code = cadr(caadr(sc->code)); } else { push_stack(sc, OP_LET_STAR1, sc->code, car(sc->code)); /* args is the let body, saved for later, code is the list of vars+initial-values */ sc->code = cadr(caar(sc->code)); /* caar(code) = first var/val pair, we've checked that all these guys are legit, so cadr of that is the value */ } goto EVAL; case OP_LET_STAR1: /* let* -- calculate parameters */ /* we can't skip (or reuse) this new frame -- we have to imitate a nested let, otherwise * (let ((f1 (lambda (arg) (+ arg 1)))) * (let* ((x 32) * (f1 (lambda (arg) (f1 (+ x arg))))) * (f1 1))) * will hang. (much later -- this worries me... Could we defer making the slot?) */ while (true) { new_frame_with_slot(sc, sc->envir, sc->envir, caar(sc->code), sc->value); sc->code = cdr(sc->code); if (is_pair(sc->code)) { s7_pointer x; x = cadar(sc->code); if (is_pair(x)) { push_stack(sc, OP_LET_STAR1, sc->args, sc->code); sc->code = x; if (is_optimized(x)) goto OPT_EVAL; goto EVAL; } if (is_symbol(x)) sc->value = find_symbol_checked(sc, x); else sc->value = _NFre(x); } else break; } sc->code = sc->args; /* original sc->code set in push_stack above */ if (is_symbol(car(sc->code))) { /* now we need to declare the new function */ make_slot_1(sc, sc->envir, car(sc->code), make_closure(sc, cadr(sc->code), cddr(sc->code), T_CLOSURE_STAR)); sc->code = cddr(sc->code); } else sc->code = cdr(sc->code); goto BEGIN1; /* -------------------------------- LETREC -------------------------------- */ case OP_LETREC: check_letrec(sc, true); case OP_LETREC_UNCHECKED: /* get all local vars and set to # * get parallel list of values * eval each member of values list with env still full of #'s * assign each value to its variable * eval body * * which means that (letrec ((x x)) x) is not an error! * but this assumes the environment is not changed by evaluating the exprs? * (letrec ((a (define b 1))) b) -- if let, the define takes place in the calling env, not the current env * I think I need to check here that slot_pending_value is set (using the is_checked bit below). */ sc->envir = new_frame_in_env(sc, sc->envir); if (is_pair(car(sc->code))) { s7_pointer x; for (x = car(sc->code); is_not_null(x); x = cdr(x)) { s7_pointer slot; slot = make_slot_1(sc, sc->envir, caar(x), sc->UNDEFINED); slot_pending_value(slot) = sc->UNDEFINED; slot_expression(slot) = cadar(x); set_checked_slot(slot); } sc->args = let_slots(sc->envir); push_stack(sc, OP_LETREC1, sc->args, sc->code); sc->code = slot_expression(sc->args); goto EVAL; } sc->code = cdr(sc->code); goto BEGIN1; case OP_LETREC1: slot_pending_value(sc->args) = sc->value; sc->args = next_slot(sc->args); if (is_slot(sc->args)) { push_stack(sc, OP_LETREC1, sc->args, sc->code); sc->code = slot_expression(sc->args); goto EVAL; } else { s7_pointer slot; for (slot = let_slots(sc->envir); is_slot(slot); slot = next_slot(slot)) if (is_checked_slot(slot)) slot_set_value(slot, slot_pending_value(slot)); sc->code = cdr(sc->code); goto BEGIN1; } /* -------------------------------- LETREC* -------------------------------- */ case OP_LETREC_STAR: check_letrec(sc, false); case OP_LETREC_STAR_UNCHECKED: /* get all local vars and set to # * eval each member of values list and assign immediately, as in let* * eval body */ sc->envir = new_frame_in_env(sc, sc->envir); if (is_pair(car(sc->code))) { s7_pointer x, p, q; for (x = car(sc->code); is_not_null(x); x = cdr(x)) { s7_pointer slot; slot = make_slot_1(sc, sc->envir, caar(x), sc->UNDEFINED); slot_expression(slot) = cadar(x); } /* these are reversed, and for letrec*, they need to be in order, so... (reverse_in_place on the slot list) */ p = let_slots(sc->envir); x = sc->NIL; while (is_slot(p)) { q = next_slot(p); next_slot(p) = x; x = p; p = q; } let_set_slots(sc->envir, x); sc->args = let_slots(sc->envir); push_stack(sc, OP_LETREC_STAR1, sc->args, sc->code); sc->code = slot_expression(sc->args); goto EVAL; } sc->code = cdr(sc->code); goto BEGIN1; case OP_LETREC_STAR1: { s7_pointer slot; slot = sc->args; slot_set_value(slot, sc->value); slot = next_slot(slot); if (is_slot(slot)) { push_stack(sc, OP_LETREC_STAR1, slot, sc->code); sc->code = slot_expression(slot); goto EVAL; } else { sc->code = cdr(sc->code); goto BEGIN1; } } /* -------------------------------- COND -------------------------------- */ case OP_COND: check_cond(sc); case OP_COND_UNCHECKED: push_stack(sc, OP_COND1, sc->NIL, sc->code); sc->code = caar(sc->code); goto EVAL; case OP_COND1: if (is_true(sc, sc->value)) { sc->code = cdar(sc->code); if (is_null(sc->code)) { if (is_multiple_value(sc->value)) /* (+ 1 (cond ((values 2 3)))) */ sc->value = splice_in_values(sc, multiple_value(sc->value)); /* no result clause, so return test, (cond (#t)) -> #t, (cond ((+ 1 2))) -> 3 */ goto START; } if (is_pair(sc->code)) { if ((car(sc->code) == sc->FEED_TO) && (s7_symbol_value(sc, sc->FEED_TO) == sc->UNDEFINED)) { if (is_multiple_value(sc->value)) /* (cond ((values 1 2) => +)) */ sc->code = cons(sc, cadr(sc->code), multiple_value(sc->value)); else sc->code = list_2(sc, cadr(sc->code), list_2(sc, sc->QUOTE, sc->value)); goto EVAL; } goto BEGIN1; } eval_error(sc, "cond: unexpected dot? ~A", sc->code); /* (cond (#t . 1)) etc */ } sc->code = cdr(sc->code); if (is_null(sc->code)) { sc->value = sc->NIL; goto START; } push_stack_no_args(sc, OP_COND1, sc->code); sc->code = caar(sc->code); goto EVAL; case OP_COND_SIMPLE: push_stack_no_args(sc, OP_COND1_SIMPLE, sc->code); sc->code = caar(sc->code); goto EVAL; case OP_COND1_SIMPLE: while (true) { if (is_true(sc, sc->value)) { sc->code = cdar(sc->code); if (is_null(sc->code)) { if (is_multiple_value(sc->value)) sc->value = splice_in_values(sc, multiple_value(sc->value)); goto START; } goto BEGIN1; } sc->code = cdr(sc->code); if (is_null(sc->code)) { sc->value = sc->NIL; goto START; } if (is_pair(caar(sc->code))) { push_stack_no_args(sc, OP_COND1_SIMPLE, sc->code); sc->code = caar(sc->code); goto EVAL; } sc->value = caar(sc->code); if (is_symbol(sc->value)) sc->value = find_symbol_checked(sc, sc->value); } case OP_COND_S: { s7_pointer val = NULL, p; if (is_pair(caar(sc->code))) val = find_symbol_checked(sc, cadaar(sc->code)); for (p = sc->code; is_pair(p); p = cdr(p)) { s7_pointer ap; ap = caar(p); if (is_pair(ap)) { car(sc->T1_1) = val; sc->value = c_call(ap)(sc, sc->T1_1); } else sc->value = sc->T; if (is_true(sc, sc->value)) { sc->code = cdar(p); if (is_null(sc->code)) { if (is_multiple_value(sc->value)) sc->value = splice_in_values(sc, multiple_value(sc->value)); goto START; } goto BEGIN1; } } sc->value = sc->NIL; } break; case OP_COND_ALL_X_2: { s7_pointer p; p = sc->code; sc->value = c_call(car(p))(sc, caar(p)); if (!is_true(sc, sc->value)) { p = cdr(p); sc->value = c_call(car(p))(sc, caar(p)); if (!is_true(sc, sc->value)) { sc->value = sc->NIL; goto START; } } sc->code = cdar(p); if (is_null(sc->code)) { if (is_multiple_value(sc->value)) sc->value = splice_in_values(sc, multiple_value(sc->value)); goto START; } goto BEGIN1; } case OP_COND_ALL_X: { s7_pointer p; for (p = sc->code; is_pair(p); p = cdr(p)) { sc->value = c_call(car(p))(sc, caar(p)); if (is_true(sc, sc->value)) { sc->code = cdar(p); if (is_null(sc->code)) { if (is_multiple_value(sc->value)) sc->value = splice_in_values(sc, multiple_value(sc->value)); goto START; } goto BEGIN1; } } sc->value = sc->NIL; } break; /* -------------------------------- AND -------------------------------- */ case OP_AND: check_and(sc); if (is_null(sc->code)) { sc->value = sc->T; goto START; } goto AND1; case OP_AND1: if ((is_false(sc, sc->value)) || (is_null(sc->code))) goto START; AND1: case OP_AND_UNCHECKED: { s7_pointer p; p = car(sc->code); if (!is_pair(p)) { if (is_symbol(p)) sc->value = find_global_symbol_checked(sc, p); else sc->value = p; if ((is_false(sc, sc->value)) || (is_null(cdr(sc->code)))) goto START; sc->code = cdr(sc->code); goto AND1; } if (is_not_null(cdr(sc->code))) push_stack_no_args(sc, OP_AND1, cdr(sc->code)); sc->code = p; if (is_optimized(p)) goto OPT_EVAL; goto EVAL; } case OP_AND_P1: if ((is_false(sc, sc->value)) || (is_null(sc->code))) goto START; /* fall through */ AND_P: case OP_AND_P: if (c_callee(sc->code)) /* all c_callee's are set via all_x_eval which can return nil */ { sc->value = c_call(sc->code)(sc, car(sc->code)); if (is_false(sc, sc->value)) goto START; sc->code = cdr(sc->code); if (is_null(sc->code)) goto START; goto AND_P; } else { if (is_not_null(cdr(sc->code))) push_stack_no_args(sc, OP_AND_P1, cdr(sc->code)); sc->code = car(sc->code); goto EVAL; } case OP_AND_P2: /* we know c_callee is set on sc->code, and there are only two branches */ sc->value = c_call(sc->code)(sc, car(sc->code)); if (is_false(sc, sc->value)) goto START; sc->code = cadr(sc->code); goto EVAL; /* -------------------------------- OR -------------------------------- */ case OP_OR: check_or(sc); if (is_null(sc->code)) { sc->value = sc->F; goto START; } goto OR1; case OP_OR1: if ((is_true(sc, sc->value)) || (is_null(sc->code))) goto START; OR1: case OP_OR_UNCHECKED: if (!is_pair(car(sc->code))) { sc->value = car(sc->code); if (is_symbol(sc->value)) sc->value = find_symbol_checked(sc, sc->value); if ((is_true(sc, sc->value)) || (is_null(cdr(sc->code)))) goto START; sc->code = cdr(sc->code); goto OR1; } if (is_not_null(cdr(sc->code))) push_stack_no_args(sc, OP_OR1, cdr(sc->code)); sc->code = car(sc->code); goto EVAL; case OP_OR_P1: if ((is_true(sc, sc->value)) || (is_null(sc->code))) goto START; /* fall through */ OR_P: case OP_OR_P: if (c_callee(sc->code)) { sc->value = c_call(sc->code)(sc, car(sc->code)); if (is_true(sc, sc->value)) goto START; sc->code = cdr(sc->code); if (is_null(sc->code)) goto START; goto OR_P; } else { if (is_not_null(cdr(sc->code))) push_stack_no_args(sc, OP_OR_P1, cdr(sc->code)); sc->code = car(sc->code); goto EVAL; } case OP_OR_P2: /* we know c_callee is set on sc->code, and there are only two branches */ sc->value = c_call(sc->code)(sc, car(sc->code)); if (is_true(sc, sc->value)) goto START; sc->code = cadr(sc->code); goto EVAL; /* by going direct without a push_stack on the last one we get tail calls, * but if the last arg (also in "and" above) is "values", there is a slight * inconsistency: the values are returned and spliced into the caller if trailing, but * are spliced into the "or" if not trailing, so * * (+ 10 (or (values 1 2) #f)) * 11 * (+ 10 (or #f (values 1 2))) * 13 * (+ 10 (or (or #f (values 1 2)) #f)) * 11 * * The tail recursion is more important. This behavior matches that of "begin" -- if the * values statement is last, it splices into the next outer arglist. */ /* -------------------------------- macro evaluation -------------------------------- */ case OP_EVAL_MACRO: /* after (scheme-side) macroexpansion, evaluate the resulting expression */ /* * (define-macro (hi a) `(+ ,a 1)) * (hi 2) * here with value: (+ 2 1) */ if (is_multiple_value(sc->value)) { /* a normal macro's result is evaluated (below) and its value replaces the macro invocation, * so if a macro returns multiple values, evaluate each one, then replace the macro * invocation with (apply values evaluated-results-in-a-list). We need to save the * new list of results, and where we are in the macro's output list, so code=macro output, * args=new list. If it returns (values), should we use #? I think that * happens now without generating a multiple_value object: * (define-macro (hi) (values)) (hi) -> # * * (define-macro (ho) (values '(+ 1 2) '(* 3 4))) (+ 1 (ho) 3) -> 19 * (define-macro (ha) (values '(define a 1) '(define b 2))) (let () (ha) (+ a b)) -> 3 */ push_stack(sc, OP_EVAL_MACRO_MV, sc->NIL, cdr(sc->value)); sc->code = car(sc->value); } else sc->code = sc->value; goto EVAL; case OP_EVAL_MACRO_MV: if (is_null(sc->code)) /* end of values list */ { sc->value = splice_in_values(sc, multiple_value(safe_reverse_in_place(sc, cons(sc, sc->value, sc->args)))); goto START; } push_stack(sc, OP_EVAL_MACRO_MV, cons(sc, sc->value, sc->args), cdr(sc->code)); sc->code = car(sc->code); goto EVAL; case OP_EXPANSION: /* after the expander has finished, if a list was returned, we need to add some annotations. * if the expander returned (values), the list-in-progress vanishes! (This mimics map and *#readers*). */ if (sc->value == sc->NO_VALUE) sc->stack_end[-1] = (s7_pointer)OP_READ_NEXT; else { if (is_pair(sc->value)) annotate_expansion(sc->value); } break; case OP_DEFINE_MACRO_WITH_ACCESSOR: if (sc->value == sc->ERROR) /* backwards compatibility... */ return(s7_error(sc, sc->ERROR, set_elist_3(sc, make_string_wrapper(sc, "can't define-macro ~S to ~S"), car(sc->args), cadr(sc->args)))); sc->code = sc->value; if ((!is_pair(sc->code)) || (!is_pair(car(sc->code))) || (!is_symbol(caar(sc->code)))) eval_error(sc, "define-macro: ~S does not look like a macro?", sc->code); sc->value = make_macro(sc); break; case OP_DEFINE_BACRO: case OP_DEFINE_BACRO_STAR: case OP_DEFINE_EXPANSION: case OP_DEFINE_MACRO: case OP_DEFINE_MACRO_STAR: check_define_macro(sc, sc->op); if (symbol_has_accessor(caar(sc->code))) { s7_pointer x; x = find_symbol(sc, caar(sc->code)); if ((is_slot(x)) && (slot_has_accessor(x))) { sc->value = bind_accessed_symbol(sc, OP_DEFINE_MACRO_WITH_ACCESSOR, caar(sc->code), sc->code); if (sc->value == sc->NO_VALUE) goto APPLY; sc->code = sc->value; } } sc->value = make_macro(sc); break; case OP_LAMBDA: check_lambda(sc); case OP_LAMBDA_UNCHECKED: make_closure_with_let(sc, sc->value, car(sc->code), cdr(sc->code), sc->envir); break; case OP_LAMBDA_STAR: check_lambda_star(sc); case OP_LAMBDA_STAR_UNCHECKED: sc->value = make_closure(sc, car(sc->code), cdr(sc->code), T_CLOSURE_STAR); break; /* -------------------------------- CASE -------------------------------- */ case OP_CASE: /* case, car(sc->code) is the selector */ check_case(sc); case OP_CASE_UNCHECKED: { s7_pointer carc; carc = car(sc->code); if (!is_pair(carc)) { if (is_symbol(carc)) sc->value = find_symbol_checked(sc, carc); else sc->value = carc; sc->code = cdr(sc->code); /* fall through */ } else { push_stack_no_args(sc, OP_CASE1, cdr(sc->code)); sc->code = carc; goto EVAL; } } case OP_CASE1: { s7_pointer x, y; if (is_simple(sc->value)) { for (x = sc->code; is_pair(x); x = cdr(x)) { y = caar(x); if (!is_pair(y)) goto ELSE_CASE; do { if (car(y) == sc->value) goto ELSE_CASE; y = cdr(y); } while (is_pair(y)); } } else { for (x = sc->code; is_pair(x); x = cdr(x)) { y = caar(x); if (!is_pair(y)) goto ELSE_CASE; for (; is_pair(y); y = cdr(y)) if (s7_is_eqv(car(y), sc->value)) goto ELSE_CASE; } } /* x is the entire matching clause, (case 2 ((2) 3)), x: (((2) 3)) */ ELSE_CASE: if (is_not_null(x)) { sc->code = cdar(x); /* check for => */ if ((car(sc->code) == sc->FEED_TO) && (s7_symbol_value(sc, sc->FEED_TO) == sc->UNDEFINED)) { sc->code = list_2(sc, cadr(sc->code), list_2(sc, sc->QUOTE, sc->value)); goto EVAL; } goto BEGIN1; } /* no match found */ sc->value = sc->UNSPECIFIED; /* this was sc->NIL but the spec says case value is unspecified if no clauses match */ } break; case OP_CASE_SIMPLE: /* assume symbol as selector, all keys are simple, and no => */ { s7_pointer x, y, selector; selector = find_symbol_checked(sc, car(sc->code)); for (x = cdr(sc->code); is_pair(x); x = cdr(x)) { y = opt_key(x); if (!is_pair(y)) /* else? */ { sc->code = cdar(x); goto BEGIN1; } do { if (car(y) == selector) { sc->code = cdar(x); goto BEGIN1; } y = cdr(y); } while (is_pair(y)); } sc->value = sc->UNSPECIFIED; } break; case OP_CASE_SIMPLER: /* assume symbol as selector, all keys are simple, and no => and no else */ { s7_pointer x, y, selector; selector = find_symbol_checked(sc, car(sc->code)); for (x = cdr(sc->code); is_pair(x); x = cdr(x)) { y = opt_key(x); do { if (car(y) == selector) { sc->code = cdar(x); goto BEGIN1; } y = cdr(y); } while (is_pair(y)); } sc->value = sc->UNSPECIFIED; } break; case OP_CASE_SIMPLER_1: /* assume symbol as selector, all keys are simple, and no => and no else, bodies are 1 liners */ { s7_pointer x, y, selector; selector = find_symbol_checked(sc, car(sc->code)); for (x = cdr(sc->code); is_pair(x); x = cdr(x)) { y = opt_key(x); do { if (car(y) == selector) { sc->code = opt_clause(x); /* cadar(x); */ goto EVAL; } y = cdr(y); } while (is_pair(y)); } sc->value = sc->UNSPECIFIED; } break; case OP_CASE_SIMPLER_SS: /* assume hop_safe_ss as selector, all keys are simple, and no => and no else, bodies are 1 liners */ { s7_pointer x, y, selector, args; args = cdar(sc->code); x = find_symbol_checked(sc, car(args)); car(sc->T2_2) = find_symbol_checked(sc, cadr(args)); car(sc->T2_1) = x; selector = c_call(car(sc->code))(sc, sc->T2_1); for (x = cdr(sc->code); is_pair(x); x = cdr(x)) { y = opt_key(x); do { if (car(y) == selector) { sc->code = opt_clause(x); /* cadar(x); */ goto EVAL; } y = cdr(y); } while (is_pair(y)); } sc->value = sc->UNSPECIFIED; } break; case OP_CASE_SIMPLEST_SS: { s7_pointer x, selector, args; args = cdar(sc->code); x = find_symbol_checked(sc, car(args)); car(sc->T2_2) = find_symbol_checked(sc, cadr(args)); car(sc->T2_1) = x; selector = c_call(car(sc->code))(sc, sc->T2_1); for (x = cdr(sc->code); is_pair(x); x = cdr(x)) if (opt_key(x) == selector) { sc->code = cdar(x); goto BEGIN1; } sc->value = sc->UNSPECIFIED; } break; case OP_CASE_SIMPLEST: /* assume symbol as selector, all keys are simple and singletons, and no => and no else, bodies are 1 liners */ { s7_pointer x, selector; selector = find_symbol_checked(sc, car(sc->code)); for (x = cdr(sc->code); is_pair(x); x = cdr(x)) if (opt_key(x) == selector) { sc->code = opt_clause(x); /* cadar(x); */ goto EVAL; } sc->value = sc->UNSPECIFIED; } break; case OP_ERROR_QUIT: case OP_EVAL_DONE: /* this is the "time to quit" operator */ return(sc->F); break; case OP_BARRIER: case OP_CATCH_ALL: case OP_CATCH: case OP_CATCH_1: case OP_CATCH_2: break; case OP_DEACTIVATE_GOTO: call_exit_active(sc->args) = false; /* as we leave the call-with-exit body, deactivate the exiter */ break; case OP_ERROR_HOOK_QUIT: sc->error_hook = sc->code; /* restore old value */ /* now mimic the end of the normal error handler. Since this error hook evaluation can happen * in an arbitrary s7_call nesting, we can't just return from the current evaluation -- * we have to jump to the original (top-level) call. Otherwise '# or whatever * is simply treated as the (non-error) return value, and the higher level evaluations * get confused. */ stack_reset(sc); sc->op = OP_ERROR_QUIT; if (sc->longjmp_ok) longjmp(sc->goto_start, 1); return(sc->value); /* not executed I hope */ case OP_GET_OUTPUT_STRING: /* from get-output-string -- return a new string */ sc->value = s7_make_string_with_length(sc, (const char *)port_data(sc->code), port_position(sc->code)); break; case OP_GET_OUTPUT_STRING_1: /* from call-with-output-string and with-output-to-string -- return the port string directly */ if ((!is_output_port(sc->code)) || (port_is_closed(sc->code))) simple_wrong_type_argument_with_type(sc, sc->WITH_OUTPUT_TO_STRING, sc->code, make_string_wrapper(sc, "an open string output port")); if (port_position(sc->code) >= port_data_size(sc->code)) resize_port_data(sc->code, port_position(sc->code) + 1); /* need room for the trailing #\null */ sc->value = make_string_uncopied_with_length(sc, (char *)port_data(sc->code), port_position(sc->code)); string_value(sc->value)[port_position(sc->code)] = 0; port_data(sc->code) = NULL; port_data_size(sc->code) = 0; port_needs_free(sc->code) = false; /* fall through */ case OP_UNWIND_OUTPUT: unwind_output_ex(sc); break; case OP_UNWIND_INPUT: unwind_input_ex(sc); break; case OP_DYNAMIC_WIND: if (dynamic_wind_ex(sc) == goto_APPLY) goto APPLY; break; /* -------------------------------- with-let -------------------------------- * * the extra set! to pull in args, or fixup the outlet is annoying, but * but with-let is hard to do right -- what if env is chained as in class/objects? * also, currently a mock-let is an error -- perhaps add the method checks? * but unless 'values, that would require a 'with-let method (it's not a function) */ case OP_WITH_LET_S: { s7_pointer e; e = find_symbol_checked(sc, car(sc->code)); if (e == sc->rootlet) sc->envir = sc->NIL; else { s7_pointer p; if (!is_let(e)) eval_type_error(sc, "with-let takes an environment argument: ~A", e); set_with_let_let(e); let_id(e) = ++sc->let_number; sc->envir = e; /* if the let in question has 10,000 names (e.g. *gtk*) this loop (which can't be avoided currently) * will be noticeable in a few cases. So, instead of saying (with-let *gtk* ...) use something * equivalent to (with-let (sublet *gtk*) ...) which is cleaner anyway. (In my timing tests, even * when pounding on this one block, the loop only amounts to 1% of the time. Normally it's * negligible). */ for (p = let_slots(e); is_slot(p); p = next_slot(p)) { s7_pointer sym; sym = slot_symbol(p); if (symbol_id(sym) != sc->let_number) symbol_set_local(sym, sc->let_number, p); } } sc->code = cdr(sc->code); goto BEGIN1; } case OP_WITH_LET: check_with_let(sc); case OP_WITH_LET_UNCHECKED: sc->value = car(sc->code); if (!is_pair(sc->value)) { if (is_symbol(sc->value)) sc->value = find_symbol_checked(sc, sc->value); sc->code = cdr(sc->code); if (!is_pair(sc->code)) { if (!is_let(sc->value)) /* (with-let e abs) */ eval_type_error(sc, "with-let takes an environment argument: ~A", sc->value); if (is_symbol(sc->code)) sc->value = s7_symbol_local_value(sc, sc->code, sc->value); else sc->value = sc->code; goto START; } /* else fall through */ } else { push_stack(sc, OP_WITH_LET1, sc->NIL, cdr(sc->code)); sc->code = sc->value; /* eval env arg */ goto EVAL; } case OP_WITH_LET1: { s7_pointer e; e = sc->value; if (!is_let(e)) /* (with-let . "hi") */ eval_type_error(sc, "with-let takes an environment argument: ~A", e); if (e == sc->rootlet) sc->envir = sc->NIL; /* (with-let (rootlet) ...) */ else { s7_pointer p; set_with_let_let(e); let_id(e) = ++sc->let_number; sc->envir = e; for (p = let_slots(e); is_slot(p); p = next_slot(p)) { s7_pointer sym; sym = slot_symbol(p); if (symbol_id(sym) != sc->let_number) symbol_set_local(sym, sc->let_number, p); } } goto BEGIN1; } case OP_WITH_BAFFLE: if (!is_proper_list(sc, sc->code)) eval_error(sc, "with-baffle: unexpected dot? ~A", sc->code); if ((!is_null(sc->code)) && (is_overlaid(sc->code)) && (has_opt_back(sc->code))) pair_set_syntax_symbol(sc->code, sc->WITH_BAFFLE_UNCHECKED); case OP_WITH_BAFFLE_UNCHECKED: if (is_null(sc->code)) { sc->value = sc->NIL; goto START; } new_frame(sc, sc->envir, sc->envir); make_slot_1(sc, sc->envir, sc->BAFFLE, make_baffle(sc)); goto BEGIN1; /* -------------------------------- the reader -------------------------------- */ POP_READ_LIST: /* push-stack OP_READ_LIST is always no_code and sc->op is always OP_READ_LIST (and not used), sc->envir is apparently not needed here */ sc->stack_end -= 4; sc->args = sc->stack_end[2]; READ_LIST: case OP_READ_LIST: /* sc->args is sc->NIL at first */ { s7_pointer x; new_cell(sc, x, T_PAIR); car(x) = sc->value; cdr(x) = sc->args; sc->args = x; } case OP_READ_NEXT: /* this is 75% of the token calls, so expanding it saves lots of time */ { int c; s7_pointer pt; pt = sc->input_port; c = port_read_white_space(pt)(sc, pt); READ_C: switch (c) { case '(': c = port_read_white_space(pt)(sc, pt); /* sc->tok = token(sc) */ switch (c) { case '(': sc->tok = TOKEN_LEFT_PAREN; break; case ')': sc->value = sc->NIL; goto READ_LIST; /* was tok = TOKEN_RIGHT_PAREN */ case '.': sc->tok = read_dot(sc, pt); break; case '\'': sc->tok = TOKEN_QUOTE; break; case ';': sc->tok = port_read_semicolon(pt)(sc, pt); break; case '"': sc->tok = TOKEN_DOUBLE_QUOTE; break; case '`': sc->tok = TOKEN_BACK_QUOTE; break; case ',': sc->tok = read_comma(sc, pt); break; case '#': sc->tok = read_sharp(sc, pt); break; case '\0': case EOF: sc->tok = TOKEN_EOF; break; default: { s7_pointer x; sc->strbuf[0] = c; push_stack_no_code(sc, OP_READ_LIST, sc->args); check_stack_size(sc); sc->value = port_read_name(pt)(sc, pt); new_cell(sc, x, T_PAIR); car(x) = sc->value; cdr(x) = sc->NIL; sc->args = x; /* if (port_position(pt) >= port_data_size(pt)) return(missing_close_paren_error(sc)); */ c = port_read_white_space(pt)(sc, pt); goto READ_C; } } if (sc->tok == TOKEN_ATOM) { s7_pointer x; push_stack_no_code(sc, OP_READ_LIST, sc->args); check_stack_size(sc); sc->value = port_read_name(pt)(sc, pt); new_cell(sc, x, T_PAIR); car(x) = sc->value; cdr(x) = sc->NIL; sc->args = x; /* if (port_position(pt) >= port_data_size(pt)) return(missing_close_paren_error(sc)); */ c = port_read_white_space(pt)(sc, pt); goto READ_C; } if (sc->tok == TOKEN_RIGHT_PAREN) { sc->value = sc->NIL; goto READ_LIST; } if (sc->tok == TOKEN_DOT) { do {c = inchar(pt);} while ((c != ')') && (c != EOF)); return(read_error(sc, "stray dot after '('?")); /* (car '( . )) */ } if (sc->tok == TOKEN_EOF) return(missing_close_paren_error(sc)); push_stack_no_code(sc, OP_READ_LIST, sc->args); push_stack_no_code(sc, OP_READ_LIST, sc->NIL); check_stack_size(sc); sc->value = read_expression(sc); if (main_stack_op(sc) == OP_READ_LIST) goto POP_READ_LIST; goto START; case ')': sc->tok = TOKEN_RIGHT_PAREN; break; case '.': sc->tok = read_dot(sc, pt); /* dot or atom */ break; case '\'': sc->tok = TOKEN_QUOTE; push_stack_no_code(sc, OP_READ_LIST, sc->args); sc->value = read_expression(sc); goto START; case ';': sc->tok = port_read_semicolon(pt)(sc, pt); break; case '"': sc->tok = TOKEN_DOUBLE_QUOTE; sc->value = read_string_constant(sc, pt); if (sc->value == sc->F) /* can happen if input code ends in the middle of a string */ return(string_read_error(sc, "end of input encountered while in a string")); if (sc->value == sc->T) return(read_error(sc, "unknown backslash usage -- perhaps you meant two backslashes?")); goto READ_LIST; case '`': sc->tok = TOKEN_BACK_QUOTE; push_stack_no_code(sc, OP_READ_LIST, sc->args); sc->value = read_expression(sc); if (main_stack_op(sc) == OP_READ_LIST) goto POP_READ_LIST; goto START; /* read_unquote */ case ',': sc->tok = read_comma(sc, pt); /* at_mark or comma */ push_stack_no_code(sc, OP_READ_LIST, sc->args); sc->value = read_expression(sc); goto START; /* read_unquote */ case '#': sc->tok = read_sharp(sc, pt); break; case '\0': case EOF: return(missing_close_paren_error(sc)); default: sc->strbuf[0] = c; sc->value = port_read_name(pt)(sc, pt); /* if (port_position(pt) >= port_data_size(pt)) return(missing_close_paren_error(sc)); */ goto READ_LIST; } } READ_TOK: switch (sc->tok) { case TOKEN_RIGHT_PAREN: /* sc->args can't be null here */ sc->value = safe_reverse_in_place(sc, sc->args); if (is_symbol(car(sc->value))) { pair_set_line(sc->value, remember_location(port_line_number(sc->input_port), port_file_number(sc->input_port))); set_has_line_number(sc->value); /* sc->input_port above can't be nil(?) -- it falls back on stdin now */ if ((is_expansion(car(sc->value))) && (expansion_ex(sc) == goto_APPLY)) goto APPLY; if (is_pair(cdr(sc->value))) { set_opt_back(sc->value); set_overlay(cdr(sc->value)); } } break; case TOKEN_EOF: /* can't happen, I believe */ return(missing_close_paren_error(sc)); case TOKEN_ATOM: sc->value = port_read_name(sc->input_port)(sc, sc->input_port); /* if (port_position(sc->input_port) >= port_data_size(sc->input_port)) return(missing_close_paren_error(sc)); */ goto READ_LIST; case TOKEN_SHARP_CONST: sc->value = port_read_sharp(sc->input_port)(sc, sc->input_port); if (is_null(sc->value)) return(read_error(sc, "undefined # expression")); if (sc->value == sc->NO_VALUE) { /* (set! *#readers* (cons (cons #\; (lambda (s) (read) (values))) *#readers*)) * (+ 1 #;(* 2 3) 4) * so we need to get the next token, act on it without any assumptions about read list */ sc->tok = token(sc); goto READ_TOK; } goto READ_LIST; case TOKEN_DOUBLE_QUOTE: sc->value = read_string_constant(sc, sc->input_port); if (sc->value == sc->F) /* can happen if input code ends in the middle of a string */ return(string_read_error(sc, "end of input encountered while in a string")); if (sc->value == sc->T) return(read_error(sc, "unknown backslash usage -- perhaps you meant two backslashes?")); goto READ_LIST; case TOKEN_DOT: push_stack_no_code(sc, OP_READ_DOT, sc->args); sc->tok = token(sc); sc->value = read_expression(sc); break; default: /* by far the main case here is TOKEN_LEFT_PAREN, but it doesn't save anything to move it to this level */ push_stack_no_code(sc, OP_READ_LIST, sc->args); sc->value = read_expression(sc); /* check for op_read_list here and explicit pop_stack are slower */ break; } if (main_stack_op(sc) == OP_READ_LIST) goto POP_READ_LIST; break; case OP_READ_DOT: if (token(sc) != TOKEN_RIGHT_PAREN) { back_up_stack(sc); read_error(sc, "stray dot?"); /* (+ 1 . 2 3) or (list . ) */ } /* args = previously read stuff, value = thing just after the dot and before the ')': * (list 1 2 . 3) * value: 3, args: (2 1 list) * '(1 . 2) * value: 2, args: (1) * * but we also get here in a lambda arg list: * (lambda (a b . c) #f) * value: c, args: (b a) * * so we have to leave any error checks until later, I guess * -- in eval_args1, if we end with non-pair-not-nil then * something is fishy */ sc->value = reverse_in_place(sc, sc->value, sc->args); if (main_stack_op(sc) == OP_READ_LIST) goto POP_READ_LIST; break; case OP_READ_QUOTE: /* can't check for sc->value = sc->NIL here because we want ''() to be different from '() */ sc->value = list_2(sc, sc->QUOTE, sc->value); set_opt_back(sc->value); set_overlay(cdr(sc->value)); if (main_stack_op(sc) == OP_READ_LIST) goto POP_READ_LIST; break; case OP_READ_QUASIQUOTE: /* this was pushed when the backquote was seen, then eventually we popped back to it */ sc->value = g_quasiquote_1(sc, sc->value); /* doing quasiquote at read time means there are minor inconsistencies in * various combinations or quote/' and quasiquote/`. A quoted ` will expand * but quoted quasiquote will not (` can't be redefined, but quasiquote can). * see s7test.scm for examples. */ if (main_stack_op(sc) == OP_READ_LIST) goto POP_READ_LIST; break; case OP_READ_VECTOR: if (!is_proper_list(sc, sc->value)) /* #(1 . 2) */ return(read_error(sc, "vector constant data is not a proper list")); if (sc->args == small_int(1)) /* sc->args was sc->w earlier from read_sharp */ sc->value = g_vector(sc, sc->value); else sc->value = g_multivector(sc, s7_integer(sc->args), sc->value); if (main_stack_op(sc) == OP_READ_LIST) goto POP_READ_LIST; break; case OP_READ_BYTE_VECTOR: if (!is_proper_list(sc, sc->value)) /* #u8(1 . 2) */ return(read_error(sc, "byte-vector constant data is not a proper list")); sc->value = g_byte_vector(sc, sc->value); if (main_stack_op(sc) == OP_READ_LIST) goto POP_READ_LIST; break; #if WITH_QUASIQUOTE_VECTOR case OP_READ_QUASIQUOTE_VECTOR: read_quasiquote_vector_ex(sc); goto EVAL; #endif case OP_READ_UNQUOTE: /* here if sc->value is a constant, the unquote is pointless (what about ,pi?) */ if ((is_pair(sc->value)) || (is_symbol(sc->value))) sc->value = list_2(sc, sc->UNQUOTE, sc->value); if (main_stack_op(sc) == OP_READ_LIST) goto POP_READ_LIST; break; case OP_READ_APPLY_VALUES: if (is_symbol(sc->value)) { s7_pointer lst; lst = list_2(sc, sc->QQ_Apply_Values, sc->value); set_unsafe_optimize_op(lst, HOP_C_S); set_c_function(lst, sc->QQ_Apply_Values); sc->value = list_2(sc, sc->UNQUOTE, lst); } else sc->value = list_2(sc, sc->UNQUOTE, list_2(sc, sc->QQ_Apply_Values, sc->value)); if (main_stack_op(sc) == OP_READ_LIST) goto POP_READ_LIST; break; default: fprintf(stderr, "unknown operator: %d in %s\n", (int)(sc->op), DISPLAY(sc->cur_code)); #if DEBUGGING abort(); #endif return(sc->F); } } return(sc->F); } #if WITH_GCC #undef new_cell #if (!DEBUGGING) #define new_cell(Sc, Obj, Type) \ do { \ if (Sc->free_heap_top <= Sc->free_heap_trigger) try_to_call_gc(Sc); \ Obj = (*(--(Sc->free_heap_top))); \ set_type(Obj, Type); \ } while (0) #else #define new_cell(Sc, Obj, Type) \ do { \ if ((Sc->free_heap_top <= Sc->free_heap_trigger) || (for_any_other_reason(sc, __LINE__))) {last_gc_line = __LINE__; last_gc_func = __func__; try_to_call_gc(Sc);} \ Obj = (*(--(Sc->free_heap_top))); \ Obj->alloc_line = __LINE__; Obj->alloc_func = __func__; \ set_type(Obj, Type); \ } while (0) #endif #endif /* needed in s7_gmp_init and s7_init, initialized in s7_init before we get to gmp */ static s7_pointer pl_bt, pl_p, pl_bc, pcl_bc, pcl_bs, pl_bn, pl_sf, pcl_bt, pcl_i, pcl_t, pcl_r, pcl_n, pcl_s, pcl_v, pcl_f, pcl_c; #if (!WITH_PURE_S7) static s7_pointer pl_tp; #endif /* -------------------------------- multiprecision arithmetic -------------------------------- */ #if WITH_GMP static mp_prec_t mpc_precision = DEFAULT_BIGNUM_PRECISION; /* global for libs */ static mp_prec_t mpc_set_default_precision(mp_prec_t prec) {mpc_precision = prec; return(prec);} #define mpc_init(Z) mpc_init2(Z, mpc_precision) static void mpc_init_set(mpc_ptr z, mpc_ptr y, mpc_rnd_t rnd) { mpc_init(z); mpc_set(z, y, rnd); } mpfr_t *s7_big_real(s7_pointer x) {return(&big_real(x));} mpz_t *s7_big_integer(s7_pointer x) {return(&big_integer(x));} mpq_t *s7_big_ratio(s7_pointer x) {return(&big_ratio(x));} mpc_t *s7_big_complex(s7_pointer x) {return(&big_complex(x));} static char *mpfr_to_string(mpfr_t val, int radix) { char *str, *tmp, *str1; mp_exp_t expptr; int i, len, ep; if (mpfr_zero_p(val)) return(copy_string("0.0")); if (mpfr_nan_p(val)) return(copy_string("nan.0")); if (mpfr_inf_p(val)) { if (mpfr_signbit(val) == 0) return(copy_string("inf.0")); return(copy_string("-inf.0")); } str1 = mpfr_get_str(NULL, &expptr, radix, 0, val, GMP_RNDN); /* 0 -> full precision, but it's too hard to make this look like C formatted output. * :(format #f "~,3F" pi) * "3.141592653589793238462643383279502884195E0" * :(format #f "~,3F" 1.1234567890123) ; not a bignum * "1.123" * :(format #f "~,3F" 1.12345678901234) ; a bignum * "1.123456789012339999999999999999999999999E0" * but we don't know the exponent or the string length until after we call mpfr_get_str. */ str = str1; ep = (int)expptr; len = safe_strlen(str); /* remove trailing 0's */ for (i = len - 1; i > 3; i--) if (str[i] != '0') break; if (i < len - 1) str[i + 1] = '\0'; len += 64; tmp = (char *)malloc(len * sizeof(char)); if (str[0] == '-') snprintf(tmp, len, "-%c.%s%c%d", str[1], (char *)(str + 2), (radix <= 10) ? 'E' : '@', ep - 1); else snprintf(tmp, len, "%c.%s%c%d", str[0], (char *)(str + 1), (radix <= 10) ? 'E' : '@', ep - 1); mpfr_free_str(str1); return(tmp); } static char *mpc_to_string(mpc_t val, int radix, use_write_t use_write) { char *rl, *im, *tmp; int len; mpfr_t a, b; mpfr_init(a); mpc_real(a, val, GMP_RNDN); rl = mpfr_to_string(a, radix); mpfr_init(b); mpc_imag(b, val, GMP_RNDN); im = mpfr_to_string(b, radix); len = safe_strlen(rl) + safe_strlen(im) + 128; tmp = (char *)malloc(len * sizeof(char)); if (use_write == USE_READABLE_WRITE) snprintf(tmp, len, "(complex %s %s)", rl, im); else snprintf(tmp, len, "%s%s%si", rl, (im[0] == '-') ? "" : "+", im); free(rl); free(im); return(tmp); } static char *big_number_to_string_with_radix(s7_pointer p, int radix, int width, int *nlen, use_write_t use_write) { char *str = NULL; switch (type(p)) { case T_BIG_INTEGER: str = mpz_get_str(NULL, radix, big_integer(p)); break; case T_BIG_RATIO: str = mpq_get_str(NULL, radix, big_ratio(p)); break; case T_BIG_REAL: str = mpfr_to_string(big_real(p), radix); break; default: str = mpc_to_string(big_complex(p), radix, use_write); break; } if (width > 0) { int len; len = safe_strlen(str); if (width > len) { int spaces; str = (char *)realloc(str, (width + 1) * sizeof(char)); spaces = width - len; str[width] = '\0'; memmove((void *)(str + spaces), (void *)str, len); memset((void *)str, (int)' ', spaces); (*nlen) = width; } else (*nlen) = len; } else (*nlen) = safe_strlen(str); return(str); } static bool s7_is_one_or_big_one(s7_pointer p) { bool result = false; if (!is_big_number(p)) return(s7_is_one(p)); if (is_t_big_integer(p)) { mpz_t n; mpz_init_set_si(n, 1); result = (mpz_cmp(n, big_integer(p)) == 0); mpz_clear(n); } else { if (is_t_big_real(p)) { mpfr_t n; mpfr_init_set_d(n, 1.0, GMP_RNDN); result = (mpfr_cmp(n, big_real(p)) == 0); mpfr_clear(n); } } return(result); } static s7_pointer string_to_big_integer(s7_scheme *sc, const char *str, int radix) { s7_pointer x; new_cell(sc, x, T_BIG_INTEGER); add_bigint(sc, x); mpz_init_set_str(big_integer(x), (str[0] == '+') ? (const char *)(str + 1) : str, radix); return(x); } static s7_pointer mpz_to_big_integer(s7_scheme *sc, mpz_t val) { s7_pointer x; new_cell(sc, x, T_BIG_INTEGER); add_bigint(sc, x); mpz_init_set(big_integer(x), val); return(x); } s7_pointer s7_make_big_integer(s7_scheme *sc, mpz_t *val) { return(mpz_to_big_integer(sc, *val)); } static s7_pointer string_to_big_ratio(s7_scheme *sc, const char *str, int radix) { s7_pointer x; mpq_t n; mpq_init(n); mpq_set_str(n, str, radix); mpq_canonicalize(n); if (mpz_cmp_ui(mpq_denref(n), 1) == 0) x = mpz_to_big_integer(sc, mpq_numref(n)); else { new_cell(sc, x, T_BIG_RATIO); add_bigratio(sc, x); mpq_init(big_ratio(x)); mpq_set_num(big_ratio(x), mpq_numref(n)); mpq_set_den(big_ratio(x), mpq_denref(n)); } mpq_clear(n); return(x); } static s7_pointer mpq_to_big_ratio(s7_scheme *sc, mpq_t val) { s7_pointer x; new_cell(sc, x, T_BIG_RATIO); add_bigratio(sc, x); mpq_init(big_ratio(x)); mpq_set_num(big_ratio(x), mpq_numref(val)); mpq_set_den(big_ratio(x), mpq_denref(val)); return(x); } s7_pointer s7_make_big_ratio(s7_scheme *sc, mpq_t *val) { return(mpq_to_big_ratio(sc, *val)); } static s7_pointer mpz_to_big_ratio(s7_scheme *sc, mpz_t val) { s7_pointer x; new_cell(sc, x, T_BIG_RATIO); add_bigratio(sc, x); mpq_init(big_ratio(x)); mpq_set_num(big_ratio(x), val); return(x); } static s7_pointer make_big_integer_or_ratio(s7_scheme *sc, s7_pointer z) { if (mpz_cmp_ui(mpq_denref(big_ratio(z)), 1) == 0) return(mpz_to_big_integer(sc, mpq_numref(big_ratio(z)))); return(z); } static s7_pointer string_to_big_real(s7_scheme *sc, const char *str, int radix) { s7_pointer x; new_cell(sc, x, T_BIG_REAL); add_bigreal(sc, x); mpfr_init_set_str(big_real(x), str, radix, GMP_RNDN); return(x); } static void mpz_init_set_s7_int(mpz_t n, s7_int uval); static s7_pointer s7_number_to_big_real(s7_scheme *sc, s7_pointer p) { s7_pointer x; new_cell(sc, x, T_BIG_REAL); add_bigreal(sc, x); switch (type(p)) { case T_INTEGER: if (sizeof(s7_int) == sizeof(long int)) mpfr_init_set_si(big_real(x), integer(p), GMP_RNDN); else mpfr_init_set_ld(big_real(x), (long double)integer(p), GMP_RNDN); break; case T_RATIO: /* here we can't use fraction(number(p)) even though that uses long double division because * there are lots of long long int ratios that will still look the same. * We have to do the actual bignum divide by hand. */ { mpq_t rat; mpz_t n1, d1; mpz_init_set_s7_int(n1, numerator(p)); mpz_init_set_s7_int(d1, denominator(p)); mpq_init(rat); mpq_set_num(rat, n1); mpq_set_den(rat, d1); mpq_canonicalize(rat); mpfr_init_set_q(big_real(x), rat, GMP_RNDN); mpz_clear(n1); mpz_clear(d1); mpq_clear(rat); } break; default: mpfr_init_set_d(big_real(x), s7_real(p), GMP_RNDN); break; } return(x); } static s7_pointer mpz_to_big_real(s7_scheme *sc, mpz_t val) { s7_pointer x; new_cell(sc, x, T_BIG_REAL); add_bigreal(sc, x); mpfr_init_set_z(big_real(x), val, GMP_RNDN); return(x); } static s7_pointer mpq_to_big_real(s7_scheme *sc, mpq_t val) { s7_pointer x; new_cell(sc, x, T_BIG_REAL); add_bigreal(sc, x); mpfr_init_set_q(big_real(x), val, GMP_RNDN); return(x); } static s7_pointer mpfr_to_big_real(s7_scheme *sc, mpfr_t val) { s7_pointer x; new_cell(sc, x, T_BIG_REAL); add_bigreal(sc, x); mpfr_init_set(big_real(x), val, GMP_RNDN); return(x); } s7_pointer s7_make_big_real(s7_scheme *sc, mpfr_t *val) { return(mpfr_to_big_real(sc, *val)); } static s7_pointer big_pi(s7_scheme *sc) { s7_pointer x; new_cell(sc, x, T_BIG_REAL); add_bigreal(sc, x); mpfr_init(big_real(x)); mpfr_const_pi(big_real(x), GMP_RNDN); return(x); } static s7_pointer s7_number_to_big_complex(s7_scheme *sc, s7_pointer p) { s7_pointer x; new_cell(sc, x, T_BIG_COMPLEX); add_bignumber(sc, x); mpc_init(big_complex(x)); switch (type(p)) { case T_INTEGER: if (sizeof(s7_int) == sizeof(long int)) mpc_set_si(big_complex(x), integer(p), MPC_RNDNN); else mpc_set_d(big_complex(x), (double)integer(p), MPC_RNDNN); break; case T_RATIO: /* can't use fraction here */ { mpfr_t temp; mpq_t rat; mpz_t n1, d1; mpz_init_set_s7_int(n1, numerator(p)); mpz_init_set_s7_int(d1, denominator(p)); mpq_init(rat); mpq_set_num(rat, n1); mpq_set_den(rat, d1); mpq_canonicalize(rat); mpfr_init_set_q(temp, rat, GMP_RNDN); mpc_set_fr(big_complex(x), temp, MPC_RNDNN); mpz_clear(n1); mpz_clear(d1); mpq_clear(rat); mpfr_clear(temp); } break; case T_REAL: mpc_set_d(big_complex(x), s7_real(p), MPC_RNDNN); break; default: mpc_set_d_d(big_complex(x), real_part(p), imag_part(p), MPC_RNDNN); break; } return(x); } static s7_pointer make_big_real_or_complex(s7_scheme *sc, s7_pointer z) { double ipart; ipart = mpfr_get_d(mpc_imagref(big_complex(z)), GMP_RNDN); /* not mpfr_cmp_ui to 0 here because that misleads us when imag_part is NaN or inf */ if (ipart == 0.0) return(mpfr_to_big_real(sc, mpc_realref(big_complex(z)))); return(z); } static s7_pointer mpz_to_big_complex(s7_scheme *sc, mpz_t val) { mpfr_t temp; s7_pointer x; new_cell(sc, x, T_BIG_COMPLEX); add_bignumber(sc, x); mpc_init(big_complex(x)); mpfr_init_set_z(temp, val, GMP_RNDN); mpc_set_fr(big_complex(x), temp, MPC_RNDNN); mpfr_clear(temp); return(x); } static s7_pointer mpq_to_big_complex(s7_scheme *sc, mpq_t val) { mpfr_t temp; s7_pointer x; new_cell(sc, x, T_BIG_COMPLEX); add_bignumber(sc, x); mpc_init(big_complex(x)); mpfr_init_set_q(temp, val, GMP_RNDN); mpc_set_fr(big_complex(x), temp, MPC_RNDNN); mpfr_clear(temp); return(x); } static s7_pointer mpfr_to_big_complex(s7_scheme *sc, mpfr_t val) { s7_pointer x; new_cell(sc, x, T_BIG_COMPLEX); add_bignumber(sc, x); mpc_init(big_complex(x)); mpc_set_fr(big_complex(x), val, MPC_RNDNN); return(x); } static s7_pointer mpc_to_big_complex(s7_scheme *sc, mpc_t val) { s7_pointer x; new_cell(sc, x, T_BIG_COMPLEX); add_bignumber(sc, x); mpc_init(big_complex(x)); mpc_set(big_complex(x), val, MPC_RNDNN); return(x); } s7_pointer s7_make_big_complex(s7_scheme *sc, mpc_t *val) { return(mpc_to_big_complex(sc, *val)); } static s7_pointer make_big_complex(s7_scheme *sc, mpfr_t rl, mpfr_t im) { /* there is no mpc_get_str equivalent, so we need to split up str, * use make_big_real to get the 2 halves, then mpc_init, then * mpc_set_fr_fr. */ s7_pointer x; new_cell(sc, x, T_BIG_COMPLEX); add_bignumber(sc, x); mpc_init(big_complex(x)); mpc_set_fr_fr(big_complex(x), rl ,im, MPC_RNDNN); return(x); } /* gmp.h mpz_init_set_si the "si" part is "signed long int", so in 64-bit machines, s7_int already fits (if it's long long int). * I guess we can catch the 4-byte long int (since no configure script) by noticing that sizeof(s7_int) == sizeof(long int)? */ static void mpz_init_set_s7_int(mpz_t n, s7_int uval) { if (sizeof(s7_int) == sizeof(long int)) mpz_init_set_si(n, uval); else { /* long long int to gmp mpz_t */ bool need_sign; long long int val; val = (long long int)uval; /* handle one special case (sigh) */ if (val == s7_int_min) mpz_init_set_str(n, "-9223372036854775808", 10); else { need_sign = (val < 0); if (need_sign) val = -val; mpz_init_set_si(n, val >> 32); mpz_mul_2exp(n, n, 32); mpz_add_ui(n, n, (unsigned int)(val & 0xffffffff)); if (need_sign) mpz_neg(n, n); } } } static s7_pointer s7_int_to_big_integer(s7_scheme *sc, s7_int val) { s7_pointer x; new_cell(sc, x, T_BIG_INTEGER); add_bigint(sc, x); mpz_init_set_s7_int(big_integer(x), val); return(x); } static s7_int big_integer_to_s7_int(mpz_t n) { long long int high, low; mpz_t x; bool need_sign = false; if (mpz_fits_slong_p(n)) return(mpz_get_si(n)); if ((hidden_sc->safety > 0) && (sizeof(s7_int) == sizeof(long int))) { char *str; str = mpz_get_str(NULL, 10, n); s7_warn(hidden_sc, 256, "can't convert %s to s7_int\n", str); free(str); } mpz_init_set(x, n); if (mpz_cmp_ui(x, 0) < 0) { need_sign = true; mpz_neg(x, x); } low = mpz_get_ui(x); if (low == s7_int_min) return(s7_int_min); mpz_fdiv_q_2exp(x, x, 32); high = mpz_get_ui(x); mpz_clear(x); if (need_sign) return(-(low + (high << 32))); return(low + (high << 32)); } static mpq_t *s7_ints_to_mpq(s7_int num, s7_int den) { /* den here always comes from denominator(x) so it is not negative */ mpq_t *n; n = (mpq_t *)malloc(sizeof(mpq_t)); mpq_init(*n); if (sizeof(s7_int) == sizeof(long int)) mpq_set_si(*n, num, den); else { mpz_t n1, d1; mpz_init_set_s7_int(n1, num); mpz_init_set_s7_int(d1, den); mpq_set_num(*n, n1); mpq_set_den(*n, d1); mpq_canonicalize(*n); mpz_clear(n1); mpz_clear(d1); } return(n); } static mpfr_t *s7_double_to_mpfr(s7_double val) { mpfr_t *n; n = (mpfr_t *)malloc(sizeof(mpfr_t)); mpfr_init_set_d(*n, val, GMP_RNDN); return(n); } static mpc_t *s7_doubles_to_mpc(s7_double rl, s7_double im) { mpc_t *n; n = (mpc_t *)malloc(sizeof(mpc_t)); mpc_init(*n); mpc_set_d_d(*n, rl, im, MPC_RNDNN); return(n); } static s7_pointer s7_ratio_to_big_ratio(s7_scheme *sc, s7_int num, s7_int den) { /* den here always comes from denominator(x) or some positive constant so it is not negative */ s7_pointer x; new_cell(sc, x, T_BIG_RATIO); add_bigratio(sc, x); mpq_init(big_ratio(x)); if (sizeof(s7_int) == sizeof(long int)) mpq_set_si(big_ratio(x), num, den); else { mpz_t n1, d1; mpz_init_set_s7_int(n1, num); mpz_init_set_s7_int(d1, den); mpq_set_num(big_ratio(x), n1); mpq_set_den(big_ratio(x), d1); mpq_canonicalize(big_ratio(x)); mpz_clear(n1); mpz_clear(d1); } return(x); } static bool big_numbers_are_eqv(s7_pointer a, s7_pointer b) { bool result; /* either or both can be big here, but not neither */ if (s7_is_integer(a)) { mpz_t a1, b1; if (!(s7_is_integer(b))) return(false); if ((is_big_number(a)) && (is_big_number(b))) return(mpz_cmp(big_integer(a), big_integer(b)) == 0); if (is_big_number(a)) mpz_init_set(a1, big_integer(a)); else mpz_init_set_s7_int(a1, s7_integer(a)); if (is_big_number(b)) mpz_init_set(b1, big_integer(b)); else mpz_init_set_s7_int(b1, s7_integer(b)); result = (mpz_cmp(a1, b1) == 0); mpz_clear(a1); mpz_clear(b1); return(result); } if (s7_is_ratio(a)) { mpq_t *a1, *b1; if (!s7_is_ratio(b)) return(false); if ((is_big_number(a)) && (is_big_number(b))) return(mpq_cmp(big_ratio(a), big_ratio(b)) == 0); if (is_big_number(a)) a1 = &big_ratio(a); else a1 = s7_ints_to_mpq(numerator(a), denominator(a)); if (is_big_number(b)) b1 = &big_ratio(b); else b1 = s7_ints_to_mpq(numerator(b), denominator(b)); result = (mpq_cmp(*a1, *b1) == 0); if (!is_big_number(a)) { mpq_clear(*a1); free(a1); } if (!is_big_number(b)) { mpq_clear(*b1); free(b1); } return(result); } if (s7_is_real(a)) { mpfr_t *a1, *b1; /* s7_is_real is not finicky enough here -- (eqv? 1.0 1) should return #f */ if (is_big_number(b)) { if (type(b) != T_BIG_REAL) return(false); } else { if (type(b) != T_REAL) return(false); } if ((is_big_number(a)) && (is_big_number(b))) return(mpfr_equal_p(big_real(a), big_real(b))); if (is_big_number(a)) a1 = &big_real(a); else a1 = s7_double_to_mpfr(s7_real(a)); if (is_big_number(b)) b1 = &big_real(b); else b1 = s7_double_to_mpfr(s7_real(b)); result = (mpfr_cmp(*a1, *b1) == 0); if (!is_big_number(a)) { mpfr_clear(*a1); free(a1); } if (!is_big_number(b)) { mpfr_clear(*b1); free(b1); } return(result); } if (s7_is_complex(a)) { mpc_t *a1, *b1; /* s7_is_complex is not finicky enough here */ if ((type(b) != T_BIG_COMPLEX) && (type(b) != T_COMPLEX)) return(false); /* (eqv? (bignum "1+i") 1+1i) */ if ((is_big_number(a)) && (is_big_number(b))) return(mpc_cmp(big_complex(a), big_complex(b)) == 0); if (is_big_number(a)) a1 = &big_complex(a); else a1 = s7_doubles_to_mpc(real_part(a), imag_part(a)); if (is_big_number(b)) b1 = &big_complex(b); else b1 = s7_doubles_to_mpc(real_part(b), imag_part(b)); result = (mpc_cmp(*a1, *b1) == 0); if (!is_big_number(a)) { mpc_clear(*a1); free(a1); } if (!is_big_number(b)) { mpc_clear(*b1); free(b1); } return(result); } return(false); } static s7_pointer string_to_either_integer(s7_scheme *sc, const char *str, int radix) { s7_int val; bool overflow = false; val = string_to_integer(str, radix, &overflow); if (!overflow) return(make_integer(sc, val)); return(string_to_big_integer(sc, str, radix)); } static s7_pointer string_to_either_ratio(s7_scheme *sc, const char *nstr, const char *dstr, int radix) { s7_int n, d; bool overflow = false; /* gmp segfaults if passed a bignum/0 so this needs to check first that * the denominator is not 0 before letting gmp screw up. Also, if the * first character is '+', gmp returns 0! */ d = string_to_integer(dstr, radix, &overflow); if (!overflow) { if (d == 0) return(real_NaN); n = string_to_integer(nstr, radix, &overflow); if (!overflow) return(s7_make_ratio(sc, n, d)); } if (nstr[0] == '+') return(string_to_big_ratio(sc, (const char *)(nstr + 1), radix)); return(string_to_big_ratio(sc, nstr, radix)); } static s7_pointer string_to_either_real(s7_scheme *sc, const char *str, int radix) { bool overflow = false; s7_double val; val = string_to_double_with_radix((char *)str, radix, &overflow); if (!overflow) return(make_real(sc, val)); return(string_to_big_real(sc, str, radix)); } static s7_pointer string_to_either_complex_1(s7_scheme *sc, char *q, char *slash1, char *ex1, bool has_dec_point1, int radix, s7_double *d_rl) { bool overflow = false; /* there's a real problem here -- we don't want to promote s7_double .1 to a bignum because * its low order digits are garbage, causing (rationalize .1 0) to return 3602879701896397/36028797018963968 * no matter what the bignum-precision. But we can't just fallback on gmp's reader because (for example) * it reads 1/2+i or 1+0/0i as 1.0. Also format gets screwed up. And string->number signals an error * where it should return #f. I wonder what to do. */ if ((has_dec_point1) || (ex1)) { (*d_rl) = string_to_double_with_radix(q, radix, &overflow); if (overflow) return(string_to_big_real(sc, q, radix)); } else { if (slash1) { s7_int n, d; /* q can include the slash and denominator */ n = string_to_integer(q, radix, &overflow); if (overflow) return(string_to_big_ratio(sc, q, radix)); else { d = string_to_integer(slash1, radix, &overflow); if (!overflow) (*d_rl) = (s7_double)n / (s7_double)d; else return(string_to_big_ratio(sc, q, radix)); } } else { s7_int val; val = string_to_integer(q, radix, &overflow); if (overflow) return(string_to_big_integer(sc, q, radix)); (*d_rl) = (s7_double)val; } } if ((*d_rl) == -0.0) (*d_rl) = 0.0; return(NULL); } static s7_pointer string_to_either_complex(s7_scheme *sc, char *q, char *slash1, char *ex1, bool has_dec_point1, char *plus, char *slash2, char *ex2, bool has_dec_point2, int radix, int has_plus_or_minus) { /* this can be just about anything involving 2 real/ratio/int portions, +/- in between and 'i' at the end */ double d_rl = 0.0, d_im = 0.0; s7_pointer p_rl = NULL, p_im = NULL, result; mpfr_t m_rl, m_im; p_rl = string_to_either_complex_1(sc, q, slash1, ex1, has_dec_point1, radix, &d_rl); p_im = string_to_either_complex_1(sc, plus, slash2, ex2, has_dec_point2, radix, &d_im); if (d_im == 0.0) { /* 1.0+0.0000000000000000000000000000i */ if ((!p_im) || (s7_is_zero(p_im))) { if (!p_rl) return(make_real(sc, d_rl)); return(p_rl); } } if ((!p_rl) && (!p_im)) return(s7_make_complex(sc, d_rl, (has_plus_or_minus == -1) ? (-d_im) : d_im)); if (p_rl) mpfr_init_set(m_rl, big_real(promote_number(sc, T_BIG_REAL, p_rl)), GMP_RNDN); else mpfr_init_set_d(m_rl, d_rl, GMP_RNDN); if (p_im) mpfr_init_set(m_im, big_real(promote_number(sc, T_BIG_REAL, p_im)), GMP_RNDN); else mpfr_init_set_d(m_im, d_im, GMP_RNDN); if (has_plus_or_minus == -1) mpfr_neg(m_im, m_im, GMP_RNDN); result = make_big_complex(sc, m_rl, m_im); mpfr_clear(m_rl); mpfr_clear(m_im); return(result); } static int big_type_to_result_type(int cur_type, int next_type) { if ((cur_type == T_BIG_COMPLEX) || (cur_type == T_COMPLEX) || (next_type == T_BIG_COMPLEX)) return(T_BIG_COMPLEX); if ((cur_type == T_BIG_REAL) || (cur_type == T_REAL) || (next_type == T_BIG_REAL)) return(T_BIG_REAL); if ((cur_type == T_BIG_RATIO) || (cur_type == T_RATIO) || (next_type == T_BIG_RATIO)) return(T_BIG_RATIO); return(T_BIG_INTEGER); } static int normal_type_to_result_type(int cur_type, int next_type) { if (cur_type > T_COMPLEX) next_type += 4; if (cur_type > next_type) return(cur_type); return(next_type); } static s7_pointer promote_number_1(s7_scheme *sc, int type, s7_pointer x, bool copy) { /* x can be any number -- need to convert it to the current result type */ switch (type) { case T_BIG_INTEGER: if (is_big_number(x)) { if (copy) return(mpz_to_big_integer(sc, big_integer(x))); return(x); /* can only be T_BIG_INTEGER here */ } return(s7_int_to_big_integer(sc, s7_integer(x))); /* can only be integer here */ case T_BIG_RATIO: if (is_big_number(x)) { if (is_t_big_ratio(x)) { if (copy) return(mpq_to_big_ratio(sc, big_ratio(x))); return(x); } return(mpz_to_big_ratio(sc, big_integer(x))); } if (is_t_integer(x)) return(s7_ratio_to_big_ratio(sc, integer(x), 1)); return(s7_ratio_to_big_ratio(sc, numerator(x), denominator(x))); case T_BIG_REAL: if (is_big_number(x)) { if (is_t_big_real(x)) { if (copy) return(mpfr_to_big_real(sc, big_real(x))); return(x); } if (is_t_big_ratio(x)) return(mpq_to_big_real(sc, big_ratio(x))); return(mpz_to_big_real(sc, big_integer(x))); } return(s7_number_to_big_real(sc, x)); default: if (is_big_number(x)) { if (is_t_big_complex(x)) { if (copy) return(mpc_to_big_complex(sc, big_complex(x))); return(x); } if (is_t_big_real(x)) return(mpfr_to_big_complex(sc, big_real(x))); if (is_t_big_ratio(x)) return(mpq_to_big_complex(sc, big_ratio(x))); return(mpz_to_big_complex(sc, big_integer(x))); } return(s7_number_to_big_complex(sc, x)); } return(sc->NIL); } static s7_pointer promote_number(s7_scheme *sc, int type, s7_pointer x) { return(promote_number_1(sc, type, x, false)); } static s7_pointer to_big(s7_scheme *sc, s7_pointer x) { if (is_big_number(x)) return(x); switch (type(x)) { case T_INTEGER: return(s7_int_to_big_integer(sc, integer(x))); case T_RATIO: return(s7_ratio_to_big_ratio(sc, numerator(x), denominator(x))); case T_REAL: return(s7_number_to_big_real(sc, x)); default: return(s7_number_to_big_complex(sc, x)); } } static s7_pointer copy_and_promote_number(s7_scheme *sc, int type, s7_pointer x) { return(promote_number_1(sc, type, x, true)); } void s7_vector_fill(s7_scheme *sc, s7_pointer vec, s7_pointer obj) { /* if the same bignum object is assigned to each element, different vector elements * are actually the same -- we need to make a copy of obj for each one */ if ((is_normal_vector(vec)) && (is_big_number(obj))) { int gc_loc; s7_int i, len; s7_pointer *tp; len = vector_length(vec); tp = (s7_pointer *)(vector_elements(vec)); /* we'll be calling new_cell below, hence the GC, so make sure the elements are markable, * and the vector itself is GC protected (we can be called within make-vector). */ gc_loc = s7_gc_protect(sc, vec); vector_fill(sc, vec, sc->NIL); switch (type(obj)) { case T_BIG_INTEGER: for (i = 0; i < len; i++) tp[i] = mpz_to_big_integer(sc, big_integer(obj)); break; case T_BIG_RATIO: for (i = 0; i < len; i++) tp[i] = mpq_to_big_ratio(sc, big_ratio(obj)); break; case T_BIG_REAL: for (i = 0; i < len; i++) tp[i] = mpfr_to_big_real(sc, big_real(obj)); break; default: for (i = 0; i < len; i++) tp[i] = mpc_to_big_complex(sc, big_complex(obj)); break; } s7_gc_unprotect_at(sc, gc_loc); } else vector_fill(sc, vec, obj); } static s7_pointer big_bignum(s7_scheme *sc, s7_pointer args) { #define H_bignum "(bignum val (radix 10)) returns a multiprecision version of the string 'val'" #define Q_bignum s7_make_signature(sc, 3, sc->IS_BIGNUM, sc->IS_NUMBER, sc->IS_INTEGER) s7_pointer p; p = g_string_to_number_1(sc, args, sc->BIGNUM); if (is_false(sc, p)) /* (bignum "1/3.0") */ s7_error(sc, make_symbol(sc, "bignum-error"), set_elist_2(sc, make_string_wrapper(sc, "bignum argument does not represent a number: ~S"), car(args))); switch (type(p)) { case T_INTEGER: return(promote_number(sc, T_BIG_INTEGER, p)); case T_RATIO: return(promote_number(sc, T_BIG_RATIO, p)); /* we can't use promote_number here because it propogates C-double inaccuracies * (rationalize (bignum "0.1") 0) should return 1/10 not 3602879701896397/36028797018963968 */ case T_REAL: if (is_NaN(real(p))) return(p); return(string_to_big_real(sc, string_value(car(args)), (is_pair(cdr(args))) ? s7_integer(cadr(args)) : 10)); case T_COMPLEX: return(promote_number(sc, T_BIG_COMPLEX, p)); default: return(p); } } bool s7_is_bignum(s7_pointer obj) { return(is_big_number(obj)); } static s7_pointer big_is_bignum(s7_scheme *sc, s7_pointer args) { #define H_is_bignum "(bignum? obj) returns #t if obj is a multiprecision number." #define Q_is_bignum pl_bt return(s7_make_boolean(sc, is_big_number(car(args)))); } #define get_result_type(Sc, Type, P) \ ((is_number(P)) ? normal_type_to_result_type(Type, type(p)) : ((is_big_number(P)) ? big_type_to_result_type(Type, type(p)) : result_type_via_method(Sc, Type, P))) static int result_type_via_method(s7_scheme *sc, int result_type, s7_pointer p) { s7_pointer f; if (!has_methods(p)) return(-1); f = find_method(sc, find_let(sc, p), sc->IS_INTEGER); if ((f != sc->UNDEFINED) && (is_true(sc, s7_apply_function(sc, f, cons(sc, p, sc->NIL))))) return(big_type_to_result_type(result_type, T_BIG_INTEGER)); f = find_method(sc, find_let(sc, p), sc->IS_RATIONAL); if ((f != sc->UNDEFINED) && (is_true(sc, s7_apply_function(sc, f, cons(sc, p, sc->NIL))))) return(big_type_to_result_type(result_type, T_BIG_RATIO)); f = find_method(sc, find_let(sc, p), sc->IS_REAL); if ((f != sc->UNDEFINED) && (is_true(sc, s7_apply_function(sc, f, cons(sc, p, sc->NIL))))) return(big_type_to_result_type(result_type, T_BIG_REAL)); /* might be a number, but not complex (quaternion) */ f = find_method(sc, find_let(sc, p), sc->IS_COMPLEX); if ((f != sc->UNDEFINED) && (is_true(sc, s7_apply_function(sc, f, cons(sc, p, sc->NIL))))) return(big_type_to_result_type(result_type, T_BIG_COMPLEX)); return(-1); } static s7_pointer big_add(s7_scheme *sc, s7_pointer args) { int result_type = T_INTEGER; s7_pointer x, result; if (is_null(args)) return(small_int(0)); if ((is_null(cdr(args))) && (s7_is_number(car(args)))) return(car(args)); for (x = args; is_not_null(x); x = cdr(x)) { s7_pointer p; p = car(x); result_type = get_result_type(sc, result_type, p); if (result_type < 0) return(g_add(sc, args)); } if (result_type < T_BIG_INTEGER) return(g_add(sc, args)); if (!s7_is_number(car(args))) check_method(sc, car(args), sc->ADD, args); result = copy_and_promote_number(sc, result_type, car(args)); for (x = cdr(args); is_not_null(x); x = cdr(x)) { s7_pointer arg; if (!s7_is_number(car(x))) check_method(sc, car(x), sc->ADD, cons(sc, result, x)); arg = promote_number(sc, result_type, car(x)); switch (result_type) { case T_BIG_INTEGER: mpz_add(big_integer(result), big_integer(result), big_integer(arg)); break; case T_BIG_RATIO: mpq_add(big_ratio(result), big_ratio(result), big_ratio(arg)); break; case T_BIG_REAL: mpfr_add(big_real(result), big_real(result), big_real(arg), GMP_RNDN); break; case T_BIG_COMPLEX: mpc_add(big_complex(result), big_complex(result), big_complex(arg), MPC_RNDNN); break; } } switch (result_type) { case T_BIG_RATIO: return(make_big_integer_or_ratio(sc, result)); case T_BIG_COMPLEX: return(make_big_real_or_complex(sc, result)); } return(result); } static s7_pointer big_negate(s7_scheme *sc, s7_pointer args) { /* assume cdr(args) is nil and we're called from subtract, so check for big num else call g_subtract */ s7_pointer p, x; p = car(args); switch (type(p)) { case T_BIG_INTEGER: x = mpz_to_big_integer(sc, big_integer(p)); mpz_neg(big_integer(x), big_integer(x)); return(x); case T_BIG_RATIO: x = mpq_to_big_ratio(sc, big_ratio(p)); mpq_neg(big_ratio(x), big_ratio(x)); return(x); case T_BIG_REAL: x = mpfr_to_big_real(sc, big_real(p)); mpfr_neg(big_real(x), big_real(x), GMP_RNDN); return(x); case T_BIG_COMPLEX: x = mpc_to_big_complex(sc, big_complex(p)); mpc_neg(big_complex(x), big_complex(x), MPC_RNDNN); return(x); case T_INTEGER: if (integer(p) == s7_int_min) { x = s7_int_to_big_integer(sc, integer(p)); mpz_neg(big_integer(x), big_integer(x)); return(x); } return(make_integer(sc, -integer(p))); case T_RATIO: return(s7_make_ratio(sc, -numerator(p), denominator(p))); case T_REAL: return(make_real(sc, -real(p))); default: return(s7_make_complex(sc, -real_part(p), -imag_part(p))); } } static s7_pointer big_subtract(s7_scheme *sc, s7_pointer args) { int result_type = T_INTEGER; s7_pointer x, result; if (!s7_is_number(car(args))) method_or_bust_with_type(sc, car(args), sc->SUBTRACT, args, A_NUMBER, 1); if (is_null(cdr(args))) return(big_negate(sc, args)); for (x = args; is_not_null(x); x = cdr(x)) { s7_pointer p; p = car(x); result_type = get_result_type(sc, result_type, p); if (result_type < 0) return(g_subtract(sc, args)); } if (result_type < T_BIG_INTEGER) return(g_subtract(sc, args)); if (!s7_is_number(car(args))) check_method(sc, car(args), sc->SUBTRACT, args); result = copy_and_promote_number(sc, result_type, car(args)); for (x = cdr(args); is_not_null(x); x = cdr(x)) { s7_pointer arg; if (!s7_is_number(car(x))) check_method(sc, car(x), sc->SUBTRACT, cons(sc, result, x)); arg = promote_number(sc, result_type, car(x)); switch (result_type) { case T_BIG_INTEGER: mpz_sub(big_integer(result), big_integer(result), big_integer(arg)); break; case T_BIG_RATIO: mpq_sub(big_ratio(result), big_ratio(result), big_ratio(arg)); break; case T_BIG_REAL: mpfr_sub(big_real(result), big_real(result), big_real(arg), GMP_RNDN); break; case T_BIG_COMPLEX: mpc_sub(big_complex(result), big_complex(result), big_complex(arg), MPC_RNDNN); break; } } switch (result_type) { case T_BIG_RATIO: return(make_big_integer_or_ratio(sc, result)); case T_BIG_COMPLEX: return(make_big_real_or_complex(sc, result)); } return(result); } static s7_pointer big_multiply(s7_scheme *sc, s7_pointer args) { int result_type = T_INTEGER; s7_pointer x, result; if (is_null(args)) return(small_int(1)); if ((is_null(cdr(args))) && (s7_is_number(car(args)))) return(car(args)); for (x = args; is_not_null(x); x = cdr(x)) { s7_pointer p; p = car(x); result_type = get_result_type(sc, result_type, p); if (result_type < 0) return(g_multiply(sc, args)); } if (result_type < T_BIG_INTEGER) return(g_multiply(sc, args)); if (!s7_is_number(car(args))) check_method(sc, car(args), sc->MULTIPLY, args); result = copy_and_promote_number(sc, result_type, car(args)); for (x = cdr(args); is_not_null(x); x = cdr(x)) { s7_pointer arg; if (!s7_is_number(car(x))) check_method(sc, car(x), sc->MULTIPLY, cons(sc, result, x)); arg = promote_number(sc, result_type, car(x)); switch (result_type) { case T_BIG_INTEGER: mpz_mul(big_integer(result), big_integer(result), big_integer(arg)); break; case T_BIG_RATIO: mpq_mul(big_ratio(result), big_ratio(result), big_ratio(arg)); break; case T_BIG_REAL: mpfr_mul(big_real(result), big_real(result), big_real(arg), GMP_RNDN); break; case T_BIG_COMPLEX: mpc_mul(big_complex(result), big_complex(result), big_complex(arg), MPC_RNDNN); break; } } switch (result_type) { case T_BIG_RATIO: return(make_big_integer_or_ratio(sc, result)); case T_BIG_COMPLEX: return(make_big_real_or_complex(sc, result)); } return(result); } static s7_pointer big_invert(s7_scheme *sc, s7_pointer args) { /* assume cdr(args) is nil and we're called from divide, so check for big num else call g_divide */ s7_pointer p, x; p = car(args); if (s7_is_zero(p)) return(division_by_zero_error(sc, sc->DIVIDE, p)); switch (type(p)) { case T_INTEGER: if (integer(p) == s7_int_min) { mpz_t n1, d1; new_cell(sc, x, T_BIG_RATIO); add_bigratio(sc, x); mpz_init_set_s7_int(n1, 1); mpz_init_set_s7_int(d1, s7_int_min); mpq_set_num(big_ratio(x), n1); mpq_set_den(big_ratio(x), d1); mpq_canonicalize(big_ratio(x)); mpz_clear(n1); mpz_clear(d1); return(x); } return(s7_make_ratio(sc, 1, integer(p))); /* a already checked, not 0 */ case T_RATIO: return(s7_make_ratio(sc, denominator(p), numerator(p))); case T_REAL: return(make_real(sc, 1.0 / real(p))); case T_COMPLEX: { s7_double r2, i2, den; r2 = real_part(p); i2 = imag_part(p); den = (r2 * r2 + i2 * i2); return(s7_make_complex(sc, r2 / den, -i2 / den)); } case T_BIG_INTEGER: /* p might be 1 or -1 */ { mpz_t n; mpz_init_set_si(n, 1); if (mpz_cmp(n, big_integer(p)) == 0) { mpz_clear(n); return(small_int(1)); } mpz_set_si(n, -1); if (mpz_cmp(n, big_integer(p)) == 0) { mpz_clear(n); return(minus_one); } new_cell(sc, x, T_BIG_RATIO); add_bigratio(sc, x); mpq_init(big_ratio(x)); mpz_set_ui(n, 1); mpq_set_num(big_ratio(x), n); mpz_clear(n); mpq_set_den(big_ratio(x), big_integer(p)); mpq_canonicalize(big_ratio(x)); return(x); } case T_BIG_RATIO: { mpz_t n; mpz_init_set_si(n, 1); if (mpz_cmp(n, mpq_numref(big_ratio(p))) == 0) { mpz_clear(n); return(mpz_to_big_integer(sc, mpq_denref(big_ratio(p)))); } mpz_set_si(n, -1); if (mpz_cmp(n, mpq_numref(big_ratio(p))) == 0) { mpz_clear(n); x = mpz_to_big_integer(sc, mpq_denref(big_ratio(p))); mpz_neg(big_integer(x), big_integer(x)); return(x); } mpz_clear(n); new_cell(sc, x, T_BIG_RATIO); add_bigratio(sc, x); mpq_init(big_ratio(x)); mpq_set_num(big_ratio(x), mpq_denref(big_ratio(p))); mpq_set_den(big_ratio(x), mpq_numref(big_ratio(p))); mpq_canonicalize(big_ratio(x)); return(x); } case T_BIG_REAL: x = mpfr_to_big_real(sc, big_real(p)); mpfr_ui_div(big_real(x), 1, big_real(x), GMP_RNDN); return(x); default: x = mpc_to_big_complex(sc, big_complex(p)); mpc_ui_div(big_complex(x), 1, big_complex(x), MPC_RNDNN); return(x); } } static s7_pointer big_divide(s7_scheme *sc, s7_pointer args) { int result_type = T_INTEGER; s7_pointer x, divisor, result; if (!s7_is_number(car(args))) method_or_bust_with_type(sc, car(args), sc->DIVIDE, args, A_NUMBER, 1); if (is_null(cdr(args))) return(big_invert(sc, args)); for (x = args; is_not_null(x); x = cdr(x)) { s7_pointer p; p = car(x); /* if divisor is 0, gmp throws an exception and halts s7! * I don't think we can trap gmp errors, and the abort is built into the library code. */ result_type = get_result_type(sc, result_type, p); if (result_type < 0) return(g_divide(sc, args)); if ((x != args) && (s7_is_zero(p))) return(division_by_zero_error(sc, sc->DIVIDE, args)); } if (result_type < T_BIG_INTEGER) return(g_divide(sc, args)); if (!s7_is_number(car(args))) check_method(sc, car(args), sc->DIVIDE, args); if (!s7_is_number(cadr(args))) check_method(sc, cadr(args), sc->DIVIDE, args); divisor = copy_and_promote_number(sc, result_type, cadr(args)); for (x = cddr(args); is_not_null(x); x = cdr(x)) { s7_pointer arg; if (!s7_is_number(car(x))) { s7_pointer func; if ((has_methods(car(x))) && ((func = find_method(sc, find_let(sc, car(x)), sc->MULTIPLY)) != sc->UNDEFINED)) { divisor = s7_apply_function(sc, func, cons(sc, divisor, x)); break; } } arg = promote_number(sc, result_type, car(x)); switch (result_type) { case T_BIG_INTEGER: mpz_mul(big_integer(divisor), big_integer(divisor), big_integer(arg)); break; case T_BIG_RATIO: mpq_mul(big_ratio(divisor), big_ratio(divisor), big_ratio(arg)); break; case T_BIG_REAL: mpfr_mul(big_real(divisor), big_real(divisor), big_real(arg), GMP_RNDN); break; case T_BIG_COMPLEX: mpc_mul(big_complex(divisor), big_complex(divisor), big_complex(arg), MPC_RNDNN); break; } } if (s7_is_zero(divisor)) return(division_by_zero_error(sc, sc->DIVIDE, args)); /* it's possible for the divisor to be the wrong type here (if complex multiply -> real for example */ divisor = promote_number_1(sc, result_type, divisor, false); result = copy_and_promote_number(sc, result_type, car(args)); switch (result_type) { case T_BIG_INTEGER: { new_cell(sc, x, T_BIG_RATIO); add_bigratio(sc, x); mpq_init(big_ratio(x)); mpq_set_num(big_ratio(x), big_integer(result)); mpq_set_den(big_ratio(x), big_integer(divisor)); mpq_canonicalize(big_ratio(x)); if (mpz_cmp_ui(mpq_denref(big_ratio(x)), 1) == 0) return(mpz_to_big_integer(sc, mpq_numref(big_ratio(x)))); return(x); } case T_BIG_RATIO: mpq_div(big_ratio(result), big_ratio(result), big_ratio(divisor)); return(make_big_integer_or_ratio(sc, result)); case T_BIG_REAL: mpfr_div(big_real(result), big_real(result), big_real(divisor), GMP_RNDN); break; case T_BIG_COMPLEX: mpc_div(big_complex(result), big_complex(result), big_complex(divisor), MPC_RNDNN); return(make_big_real_or_complex(sc, result)); } return(result); } static s7_pointer big_abs(s7_scheme *sc, s7_pointer args) { #define H_abs "(abs x) returns the absolute value of the real number x" #define Q_abs s7_make_signature(sc, 2, sc->IS_REAL, sc->IS_REAL) s7_pointer p, x; p = car(args); switch (type(p)) { case T_INTEGER: if (integer(p) < 0) { if (integer(p) == s7_int_min) { x = s7_int_to_big_integer(sc, integer(p)); mpz_neg(big_integer(x), big_integer(x)); return(x); } return(make_integer(sc, -integer(p))); } return(p); case T_RATIO: if (numerator(p) < 0) return(s7_make_ratio(sc, -numerator(p), denominator(p))); return(p); case T_REAL: if (real(p) < 0.0) return(make_real(sc, -real(p))); return(p); case T_BIG_INTEGER: x = mpz_to_big_integer(sc, big_integer(p)); mpz_abs(big_integer(x), big_integer(x)); return(x); case T_BIG_RATIO: x = mpq_to_big_ratio(sc, big_ratio(p)); mpq_abs(big_ratio(x), big_ratio(x)); return(x); case T_BIG_REAL: x = mpfr_to_big_real(sc, big_real(p)); mpfr_abs(big_real(x), big_real(x), GMP_RNDN); return(x); default: method_or_bust(sc, p, sc->ABS, args, T_REAL, 0); } } static s7_pointer big_magnitude(s7_scheme *sc, s7_pointer args) { #define H_magnitude "(magnitude z) returns the magnitude of z" #define Q_magnitude s7_make_signature(sc, 2, sc->IS_REAL, sc->IS_NUMBER) s7_pointer p; p = car(args); if (!s7_is_number(p)) method_or_bust_with_type(sc, p, sc->MAGNITUDE, args, A_NUMBER, 0); if (is_t_big_complex(p)) { mpfr_t n; mpfr_init(n); mpc_abs(n, big_complex(p), GMP_RNDN); p = mpfr_to_big_real(sc, n); mpfr_clear(n); return(p); } if (is_t_complex(p)) return(make_real(sc, hypot(imag_part(p), real_part(p)))); return(big_abs(sc, args)); } static s7_pointer big_angle(s7_scheme *sc, s7_pointer args) { #define H_angle "(angle z) returns the angle of z" #define Q_angle s7_make_signature(sc, 2, sc->IS_REAL, sc->IS_NUMBER) s7_pointer p; p = car(args); switch (type(p)) { case T_INTEGER: if (integer(p) < 0) return(real_pi); return(small_int(0)); case T_RATIO: if (numerator(p) < 0) return(real_pi); return(small_int(0)); case T_REAL: if (is_NaN(real(p))) return(p); if (real(p) < 0.0) return(real_pi); return(real_zero); case T_COMPLEX: return(make_real(sc, atan2(imag_part(p), real_part(p)))); case T_BIG_INTEGER: if (mpz_cmp_ui(big_integer(p), 0) >= 0) return(small_int(0)); return(big_pi(sc)); case T_BIG_RATIO: if (mpq_cmp_ui(big_ratio(p), 0, 1) >= 0) return(small_int(0)); return(big_pi(sc)); case T_BIG_REAL: { double x; x = mpfr_get_d(big_real(p), GMP_RNDN); /* mpfr_get_d returns inf or -inf if the arg is too large for a double */ if (is_NaN(x)) return(p); if (x >= 0.0) return(real_zero); return(big_pi(sc)); } case T_BIG_COMPLEX: { s7_pointer x; new_cell(sc, x, T_BIG_REAL); add_bigreal(sc, x); mpfr_init(big_real(x)); mpc_arg(big_real(x), big_complex(p), GMP_RNDN); return(x); } default: method_or_bust_with_type(sc, p, sc->ANGLE, args, A_NUMBER, 0); } } static s7_pointer c_big_complex(s7_scheme *sc, s7_pointer args) { #define H_complex "(complex x1 x2) returns a complex number with real-part x1 and imaginary-part x2" #define Q_complex s7_make_signature(sc, 3, sc->IS_NUMBER, sc->IS_REAL, sc->IS_REAL) s7_pointer p0, p1, p; mpfr_t rl, im; double x; p0 = car(args); if (!s7_is_real(p0)) method_or_bust(sc, p0, sc->COMPLEX, args, T_REAL, 1); p1 = cadr(args); if (!s7_is_real(p1)) method_or_bust(sc, p1, sc->COMPLEX, args, T_REAL, 2); if ((!is_big_number(p1)) && (real_to_double(sc, p1, "complex") == 0.0)) /* imag-part is not bignum and is 0.0 */ return(p0); mpfr_init_set(im, big_real(promote_number(sc, T_BIG_REAL, p1)), GMP_RNDN); x = mpfr_get_d(im, GMP_RNDN); if (x == 0.0) /* imag-part is bignum 0.0 */ { mpfr_clear(im); return(p0); } mpfr_init_set(rl, big_real(promote_number(sc, T_BIG_REAL, p0)), GMP_RNDN); new_cell(sc, p, T_BIG_COMPLEX); add_bignumber(sc, p); mpc_init(big_complex(p)); mpc_set_fr_fr(big_complex(p), rl, im, MPC_RNDNN); mpfr_clear(rl); mpfr_clear(im); return(p); } /* (make-polar 0 (real-part (log 0))) = 0? or nan? */ #if (!WITH_PURE_S7) static s7_pointer big_make_polar(s7_scheme *sc, s7_pointer args) { #define H_make_polar "(make-polar mag ang) returns a complex number with magnitude mag and angle ang" #define Q_make_polar s7_make_signature(sc, 3, sc->IS_NUMBER, sc->IS_REAL, sc->IS_REAL) s7_pointer p0, p1, p; mpfr_t ang, mag, rl, im; double x, y; p0 = car(args); if (!s7_is_real(p0)) method_or_bust(sc, p0, sc->MAKE_POLAR, args, T_REAL, 1); p1 = cadr(args); if (!s7_is_real(p1)) method_or_bust(sc, p1, sc->MAKE_POLAR, args, T_REAL, 2); mpfr_init_set(ang, big_real(promote_number(sc, T_BIG_REAL, p1)), GMP_RNDN); y = mpfr_get_d(ang, GMP_RNDN); if (is_NaN(y)) { mpfr_clear(ang); return(real_NaN); } mpfr_init_set(mag, big_real(promote_number(sc, T_BIG_REAL, p0)), GMP_RNDN); x = mpfr_get_d(mag, GMP_RNDN); if (is_NaN(x)) { mpfr_clear(ang); mpfr_clear(mag); return(real_NaN); } if ((x == 0.0) || (y == 0.0)) { mpfr_clear(ang); mpfr_clear(mag); return(p0); } mpfr_init_set(im, ang, GMP_RNDN); mpfr_sin(im, im, GMP_RNDN); mpfr_mul(im, im, mag, GMP_RNDN); x = mpfr_get_d(im, GMP_RNDN); if (x == 0.0) { mpfr_clear(im); mpfr_clear(ang); mpfr_clear(mag); return(p0); } mpfr_init_set(rl, ang, GMP_RNDN); mpfr_cos(rl, rl, GMP_RNDN); mpfr_mul(rl, rl, mag, GMP_RNDN); new_cell(sc, p, T_BIG_COMPLEX); add_bignumber(sc, p); mpc_init(big_complex(p)); mpc_set_fr_fr(big_complex(p), rl, im, MPC_RNDNN); mpfr_clear(rl); mpfr_clear(im); mpfr_clear(ang); mpfr_clear(mag); return(p); } #endif static s7_pointer big_log(s7_scheme *sc, s7_pointer args) { #define H_log "(log z1 (z2 e)) returns log(z1) / log(z2) where z2 (the base) defaults to e: (log 8 2) = 3" #define Q_log pcl_n /* either arg can be big, second is optional */ s7_pointer p0, p1 = NULL, p; p0 = car(args); if (!s7_is_number(p0)) method_or_bust_with_type(sc, p0, sc->LOG, args, A_NUMBER, 1); if (is_not_null(cdr(args))) { p1 = cadr(args); if (!s7_is_number(p1)) method_or_bust_with_type(sc, p1, sc->LOG, args, A_NUMBER, 2); } if ((s7_is_real(p0)) && ((!p1) || (s7_is_real(p1)))) { double x, y = 0.0; p0 = promote_number(sc, T_BIG_REAL, p0); x = mpfr_get_d(big_real(p0), GMP_RNDN); if (is_NaN(x)) return(real_NaN); if (p1) { p1 = promote_number(sc, T_BIG_REAL, p1); y = mpfr_get_d(big_real(p1), GMP_RNDN); /* we can't check y here for 1.0 (check for 0.0 apparently is ok): * :(log 100.0 (+ 1.0 (bignum "1e-16"))) * ;log base, argument 2, 1.000000000000000100000000000000000000002E0, is out of range (can't be 0.0 or 1.0) * :(= 1.0 (+ 1.0 (bignum "1e-16"))) * #f */ if (is_NaN(y)) return(real_NaN); if (y == 0.0) return(out_of_range(sc, sc->LOG, small_int(2), p1, make_string_wrapper(sc, "argument can't be 0.0"))); } if (x == 0.0) return(s7_make_complex(sc, -INFINITY, M_PI)); if ((x > 0.0) && (y >= 0.0)) { mpfr_t n, base; mpfr_init_set(n, big_real(p0), GMP_RNDN); mpfr_log(n, n, GMP_RNDN); if (!p1) { /* presumably log is safe with regard to real-part overflow giving a bogus int? */ if ((s7_is_rational(car(args))) && (mpfr_integer_p(n) != 0)) { new_cell(sc, p, T_BIG_INTEGER); add_bigint(sc, p); mpz_init(big_integer(p)); mpfr_get_z(big_integer(p), n, GMP_RNDN); } else p = mpfr_to_big_real(sc, n); mpfr_clear(n); return(p); } mpfr_init_set(base, big_real(p1), GMP_RNDN); mpfr_log(base, base, GMP_RNDN); mpfr_div(n, n, base, GMP_RNDN); mpfr_clear(base); if ((s7_is_rational(car(args))) && (s7_is_rational(cadr(args))) && (mpfr_integer_p(n) != 0)) { new_cell(sc, p, T_BIG_INTEGER); add_bigint(sc, p); mpz_init(big_integer(p)); mpfr_get_z(big_integer(p), n, GMP_RNDN); } else p = mpfr_to_big_real(sc, n); mpfr_clear(n); return(p); } } p0 = promote_number(sc, T_BIG_COMPLEX, p0); if (p1) p1 = promote_number(sc, T_BIG_COMPLEX, p1); { mpc_t n, base; double x; mpc_init(n); mpc_set(n, big_complex(p0), MPC_RNDNN); mpc_log(n, n, MPC_RNDNN); if (!p1) { p = mpc_to_big_complex(sc, n); mpc_clear(n); return(p); } mpc_init(base); mpc_set(base, big_complex(p1), MPC_RNDNN); mpc_log(base, base, MPC_RNDNN); mpc_div(n, n, base, MPC_RNDNN); mpc_clear(base); x = mpfr_get_d(mpc_imagref(n), GMP_RNDN); if (x == 0.0) p = mpfr_to_big_real(sc, mpc_realref(n)); else p = mpc_to_big_complex(sc, n); mpc_clear(n); return(p); } } static s7_pointer big_sqrt(s7_scheme *sc, s7_pointer args) { /* real >= 0 -> real, else complex */ #define H_sqrt "(sqrt z) returns the square root of z" #define Q_sqrt pcl_n s7_pointer p; p = car(args); if (!s7_is_number(p)) method_or_bust_with_type(sc, p, sc->SQRT, args, A_NUMBER, 0); p = to_big(sc, p); /* if big integer, try to return int if perfect square */ if (is_t_big_integer(p)) { if (mpz_cmp_ui(big_integer(p), 0) < 0) p = promote_number(sc, T_BIG_COMPLEX, p); else { mpz_t n, rem; mpz_init(rem); mpz_init_set(n, big_integer(p)); mpz_sqrtrem(n, rem, n); if (mpz_cmp_ui(rem, 0) == 0) { p = mpz_to_big_integer(sc, n); mpz_clear(n); mpz_clear(rem); return(p); } mpz_clear(n); mpz_clear(rem); p = promote_number(sc, T_BIG_REAL, p); } } /* if big ratio, check both num and den for squares */ if (is_t_big_ratio(p)) { if (mpq_cmp_ui(big_ratio(p), 0, 1) < 0) p = promote_number(sc, T_BIG_COMPLEX, p); else { mpz_t n1, rem; mpz_init(rem); mpz_init_set(n1, mpq_numref(big_ratio(p))); mpz_sqrtrem(n1, rem, n1); if (mpz_cmp_ui(rem, 0) == 0) { mpz_t d1; mpz_init_set(d1, mpq_denref(big_ratio(p))); mpz_sqrtrem(d1, rem, d1); if (mpz_cmp_ui(rem, 0) == 0) { mpq_t n; mpq_init(n); mpq_set_num(n, n1); mpq_set_den(n, d1); mpq_canonicalize(n); p = mpq_to_big_ratio(sc, n); mpz_clear(n1); mpz_clear(d1); mpz_clear(rem); mpq_clear(n); return(p); } mpz_clear(d1); } mpz_clear(n1); mpz_clear(rem); p = promote_number(sc, T_BIG_REAL, p); } } /* if real and not negative, use mpfr_sqrt */ if (is_t_big_real(p)) { if (mpfr_cmp_ui(big_real(p), 0) < 0) p = promote_number(sc, T_BIG_COMPLEX, p); else { mpfr_t n; mpfr_init_set(n, big_real(p), GMP_RNDN); mpfr_sqrt(n, n, GMP_RNDN); p = mpfr_to_big_real(sc, n); mpfr_clear(n); return(p); } } /* p is a big number, so it must be complex at this point */ { mpc_t n; mpc_init(n); mpc_set(n, big_complex(p), MPC_RNDNN); mpc_sqrt(n, n, MPC_RNDNN); p = mpc_to_big_complex(sc, n); mpc_clear(n); return(p); } } /* (define (diff f a) (magnitude (- (f a) (f (bignum (number->string a)))))) * (sin 1e15+1e15i) hangs in mpc 0.8.2, but appears to be fixed in the current svn sources */ enum {TRIG_NO_CHECK, TRIG_TAN_CHECK, TRIG_TANH_CHECK}; static s7_pointer big_trig(s7_scheme *sc, s7_pointer args, int (*mpfr_trig)(mpfr_ptr, mpfr_srcptr, mpfr_rnd_t), int (*mpc_trig)(mpc_ptr, mpc_srcptr, mpc_rnd_t), int tan_case, s7_pointer sym) /* these declarations mimic the mpfr.h and mpc.h declarations. It seems to me that * they ought to be: * int (*mpfr_trig)(mpfr_t rop, mpfr_t op, mp_rnd_t rnd), * void (*mpc_trig)(mpc_t rop, mpc_t op, mpc_rnd_t rnd)) */ { s7_pointer p; p = car(args); /* I think here we should always promote to bignum (otherwise, for example, (exp 800) -> inf) */ if (!s7_is_number(p)) method_or_bust_with_type(sc, p, sym, args, A_NUMBER, 0); if (s7_is_real(p)) { mpfr_t n; mpfr_init_set(n, big_real(promote_number(sc, T_BIG_REAL, p)), GMP_RNDN); mpfr_trig(n, n, GMP_RNDN); /* it's confusing to check for ints here via mpfr_integer_p because it * is dependent on the precision! (exp 617/5) returns an integer if * precision is 128, but a float if 512. */ p = mpfr_to_big_real(sc, n); mpfr_clear(n); return(p); } if (!is_big_number(p)) p = promote_number(sc, T_BIG_COMPLEX, p); if (tan_case == TRIG_TAN_CHECK) { if ((MPC_INEX_IM(mpc_cmp_si_si(big_complex(p), 1, 350))) > 0) return(s7_make_complex(sc, 0.0, 1.0)); if ((MPC_INEX_IM(mpc_cmp_si_si(big_complex(p), 1, -350))) < 0) return(s7_make_complex(sc, 0.0, -1.0)); } if (tan_case == TRIG_TANH_CHECK) { if ((MPC_INEX_RE(mpc_cmp_si_si(big_complex(p), 350, 1))) > 0) return(real_one); if ((MPC_INEX_RE(mpc_cmp_si_si(big_complex(p), -350, 1))) < 0) return(make_real(sc, -1.0)); } { mpc_t n; double ix; mpc_init(n); mpc_trig(n, big_complex(p), MPC_RNDNN); /* (sin (bignum "1e15+1e15i")) causes mpc to hang (e9 is ok, but e10 hangs) * (sin (bignum "0+1e10i")) -> 0+inf (sin (bignum "1+1e10i")) hangs * * before comparing imag-part to 0, we need to look for NaN and inf, else: * (sinh 0+0/0i) -> 0.0 * (sinh (log 0.0)) -> inf.0 */ ix = mpfr_get_d(mpc_imagref(n), GMP_RNDN); if (ix == 0.0) { mpfr_t z; mpfr_init_set(z, mpc_realref(n), GMP_RNDN); p = mpfr_to_big_real(sc, z); mpfr_clear(z); } else p = mpc_to_big_complex(sc, n); mpc_clear(n); return(p); } } static s7_pointer big_sin(s7_scheme *sc, s7_pointer args) { #define H_sin "(sin z) returns sin(z)" #define Q_sin pcl_n return(big_trig(sc, args, mpfr_sin, mpc_sin, TRIG_NO_CHECK, sc->SIN)); } static s7_pointer big_cos(s7_scheme *sc, s7_pointer args) { #define H_cos "(cos z) returns cos(z)" #define Q_cos pcl_n return(big_trig(sc, args, mpfr_cos, mpc_cos, TRIG_NO_CHECK, sc->COS)); } s7_pointer s7_cos(s7_scheme *sc, s7_pointer x) { return(big_cos(sc, cons(sc, x, sc->NIL))); } static s7_pointer big_tan(s7_scheme *sc, s7_pointer args) { #define H_tan "(tan z) returns tan(z)" #define Q_tan pcl_n return(big_trig(sc, args, mpfr_tan, mpc_tan, TRIG_TAN_CHECK, sc->TAN)); } static s7_pointer big_sinh(s7_scheme *sc, s7_pointer args) { #define H_sinh "(sinh z) returns sinh(z)" #define Q_sinh pcl_n /* currently (sinh 0+0/0i) -> 0.0? */ return(big_trig(sc, args, mpfr_sinh, mpc_sinh, TRIG_NO_CHECK, sc->SINH)); } static s7_pointer big_cosh(s7_scheme *sc, s7_pointer args) { #define H_cosh "(cosh z) returns cosh(z)" #define Q_cosh pcl_n return(big_trig(sc, args, mpfr_cosh, mpc_cosh, TRIG_NO_CHECK, sc->COSH)); } static s7_pointer big_tanh(s7_scheme *sc, s7_pointer args) { #define H_tanh "(tanh z) returns tanh(z)" #define Q_tanh pcl_n return(big_trig(sc, args, mpfr_tanh, mpc_tanh, TRIG_TANH_CHECK, sc->TANH)); } static s7_pointer big_exp(s7_scheme *sc, s7_pointer args) { #define H_exp "(exp z) returns e^z, (exp 1) is 2.718281828459" #define Q_exp pcl_n return(big_trig(sc, args, mpfr_exp, mpc_exp, TRIG_NO_CHECK, sc->EXP)); } static s7_pointer big_expt(s7_scheme *sc, s7_pointer args) { #define H_expt "(expt z1 z2) returns z1^z2" #define Q_expt pcl_n s7_pointer x, y, p; /* see comment under g_expt * if (is_not_null(cddr(args))) * return(big_expt(sc, set_plist_2(sc, car(args), big_expt(sc, cdr(args))))); */ x = car(args); if (!s7_is_number(x)) method_or_bust_with_type(sc, x, sc->EXPT, args, A_NUMBER, 1); y = cadr(args); if (!s7_is_number(y)) method_or_bust_with_type(sc, y, sc->EXPT, args, A_NUMBER, 2); if (s7_is_zero(x)) { if ((s7_is_integer(x)) && (s7_is_integer(y)) && (s7_is_zero(y))) return(small_int(1)); if (s7_is_real(y)) { if (s7_is_negative(y)) return(division_by_zero_error(sc, sc->EXPT, args)); } else { if (s7_is_negative(g_real_part(sc, cdr(args)))) return(division_by_zero_error(sc, sc->EXPT, args)); } if ((s7_is_rational(x)) && (s7_is_rational(y))) return(small_int(0)); return(real_zero); } if (s7_is_integer(y)) { s7_int yval; yval = s7_integer(y); if (yval == 0) { if (s7_is_rational(x)) return(small_int(1)); return(real_one); } if (yval == 1) return(x); if (!is_big_number(x)) { if ((s7_is_one(x)) || (s7_is_zero(x))) return(x); } if ((yval < s7_int32_max) && (yval > s7_int32_min)) { /* from here yval can fit in an unsigned int * (protect against gmp exception if for example (expt 1/9223372036854775807 -9223372036854775807) */ if (s7_is_integer(x)) { mpz_t n; mpq_t r; x = promote_number(sc, T_BIG_INTEGER, x); mpz_init_set(n, big_integer(x)); if (yval >= 0) { mpz_pow_ui(n, n, (unsigned int)yval); p = mpz_to_big_integer(sc, n); mpz_clear(n); return(p); } mpz_pow_ui(n, n, (unsigned int)(-yval)); mpq_init(r); mpq_set_z(r, n); mpq_inv(r, r); if (mpz_cmp_ui(mpq_denref(r), 1) == 0) { mpz_t z; mpz_init_set(z, mpq_numref(r)); mpq_clear(r); mpz_clear(n); p = mpz_to_big_integer(sc, z); mpz_clear(z); return(p); } mpz_clear(n); p = mpq_to_big_ratio(sc, r); mpq_clear(r); return(p); } if (s7_is_ratio(x)) /* here y is an integer */ { mpz_t n, d; mpq_t r; x = promote_number(sc, T_BIG_RATIO, x); mpz_init_set(n, mpq_numref(big_ratio(x))); mpz_init_set(d, mpq_denref(big_ratio(x))); mpq_init(r); if (yval >= 0) { mpz_pow_ui(n, n, (unsigned int)yval); mpz_pow_ui(d, d, (unsigned int)yval); mpq_set_num(r, n); mpq_set_den(r, d); } else { yval = -yval; mpz_pow_ui(n, n, (unsigned int)yval); mpz_pow_ui(d, d, (unsigned int)yval); mpq_set_num(r, d); mpq_set_den(r, n); mpq_canonicalize(r); } mpz_clear(n); mpz_clear(d); if (mpz_cmp_ui(mpq_denref(r), 1) == 0) { mpz_t z; mpz_init_set(z, mpq_numref(r)); mpq_clear(r); p = mpz_to_big_integer(sc, z); mpz_clear(z); return(p); } p = mpq_to_big_ratio(sc, r); mpq_clear(r); return(p); } if (s7_is_real(x)) { mpfr_t z; x = promote_number(sc, T_BIG_REAL, x); mpfr_init_set(z, big_real(x), GMP_RNDN); mpfr_pow_si(z, z, yval, GMP_RNDN); p = mpfr_to_big_real(sc, z); mpfr_clear(z); return(p); } } } if ((is_t_ratio(y)) && /* not s7_is_ratio which accepts bignums */ (numerator(y) == 1)) { if (denominator(y) == 2) return(big_sqrt(sc, args)); if ((s7_is_real(x)) && (denominator(y) == 3)) { mpfr_t z; mpfr_init_set(z, big_real(promote_number(sc, T_BIG_REAL, x)), GMP_RNDN); mpfr_cbrt(z, z, GMP_RNDN); p = mpfr_to_big_real(sc, z); mpfr_clear(z); return(p); } } if ((s7_is_real(x)) && (s7_is_real(y)) && (s7_is_positive(x))) { mpfr_t z; mpfr_init_set(z, big_real(promote_number(sc, T_BIG_REAL, x)), GMP_RNDN); mpfr_pow(z, z, big_real(promote_number(sc, T_BIG_REAL, y)), GMP_RNDN); p = mpfr_to_big_real(sc, z); mpfr_clear(z); return(p); } { mpc_t cy; mpc_t z; x = promote_number(sc, T_BIG_COMPLEX, x); y = promote_number(sc, T_BIG_COMPLEX, y); mpc_init(z); mpc_set(z, big_complex(x), MPC_RNDNN); if (mpc_cmp_si_si(z, 0, 0) == 0) { mpc_clear(z); return(small_int(0)); } if (mpc_cmp_si_si(z, 1, 0) == 0) { mpc_clear(z); return(small_int(1)); } mpc_init(cy); mpc_set(cy, big_complex(y), MPC_RNDNN); mpc_pow(z, z, cy, MPC_RNDNN); mpc_clear(cy); if (mpfr_cmp_ui(mpc_imagref(z), 0) == 0) { mpfr_t n; if ((s7_is_rational(car(args))) && (s7_is_rational(cadr(args))) && (mpfr_integer_p(mpc_realref(z)) != 0)) { /* mpfr_integer_p can be confused: (expt 2718/1000 (bignum "617/5")) returns an int if precision=128, float if 512 */ /* so first make sure we're within (say) 31 bits */ mpfr_t zi; mpfr_init_set_ui(zi, s7_int32_max, GMP_RNDN); if (mpfr_cmpabs(mpc_realref(z), zi) < 0) { mpz_t k; mpz_init(k); mpfr_get_z(k, mpc_realref(z), GMP_RNDN); mpc_clear(z); mpfr_clear(zi); p = mpz_to_big_integer(sc, k); mpz_clear(k); return(p); } mpfr_clear(zi); } mpfr_init_set(n, mpc_realref(z), GMP_RNDN); mpc_clear(z); p = mpfr_to_big_real(sc, n); mpfr_clear(n); return(p); } p = mpc_to_big_complex(sc, z); mpc_clear(z); return(p); } } static s7_pointer big_asinh(s7_scheme *sc, s7_pointer args) { #define H_asinh "(asinh z) returns asinh(z)" #define Q_asinh pcl_n s7_pointer p; p = car(args); if (!s7_is_number(p)) method_or_bust_with_type(sc, p, sc->ASINH, args, A_NUMBER, 0); if (s7_is_real(p)) { mpfr_t n; p = promote_number(sc, T_BIG_REAL, p); mpfr_init_set(n, big_real(p), GMP_RNDN); mpfr_asinh(n, n, GMP_RNDN); p = mpfr_to_big_real(sc, n); mpfr_clear(n); return(p); } { mpc_t n; p = promote_number(sc, T_BIG_COMPLEX, p); mpc_init(n); mpc_set(n, big_complex(p), MPC_RNDNN); mpc_asinh(n, n, MPC_RNDNN); p = mpc_to_big_complex(sc, n); mpc_clear(n); return(p); } } static s7_pointer big_acosh(s7_scheme *sc, s7_pointer args) { #define H_acosh "(acosh z) returns acosh(z)" #define Q_acosh pcl_n s7_pointer p; double x; mpc_t n; p = car(args); if (!s7_is_number(p)) method_or_bust_with_type(sc, p, sc->ACOSH, args, A_NUMBER, 0); p = promote_number(sc, T_BIG_COMPLEX, p); mpc_init(n); mpc_set(n, big_complex(p), MPC_RNDNN); mpc_acosh(n, n, MPC_RNDNN); x = mpfr_get_d(mpc_imagref(n), GMP_RNDN); if (x == 0.0) p = mpfr_to_big_real(sc, mpc_realref(n)); else p = mpc_to_big_complex(sc, n); mpc_clear(n); return(p); } static s7_pointer big_atanh(s7_scheme *sc, s7_pointer args) { #define H_atanh "(atanh z) returns atanh(z)" #define Q_atanh pcl_n s7_pointer p; p = car(args); if (!s7_is_number(p)) method_or_bust_with_type(sc, p, sc->ATANH, args, A_NUMBER, 0); if (s7_is_real(p)) { bool ok; mpfr_t temp; p = promote_number(sc, T_BIG_REAL, p); mpfr_init_set_ui(temp, 1, GMP_RNDN); ok = (mpfr_cmpabs(big_real(p), temp) < 0); mpfr_clear(temp); if (ok) { mpfr_t n; mpfr_init_set(n, big_real(p), GMP_RNDN); mpfr_atanh(n, n, GMP_RNDN); p = mpfr_to_big_real(sc, n); mpfr_clear(n); return(p); } } { mpc_t n; p = promote_number(sc, T_BIG_COMPLEX, p); mpc_init(n); mpc_set(n, big_complex(p), MPC_RNDNN); mpc_atanh(n, n, MPC_RNDNN); p = mpc_to_big_complex(sc, n); mpc_clear(n); return(p); } } static s7_pointer big_atan(s7_scheme *sc, s7_pointer args) { #define H_atan "(atan z) returns atan(z), (atan y x) returns atan(y/x)" #define Q_atan s7_make_signature(sc, 3, sc->IS_NUMBER, sc->IS_NUMBER, sc->IS_REAL) s7_pointer p0, p1 = NULL, p; p0 = car(args); if (!s7_is_number(p0)) method_or_bust_with_type(sc, p0, sc->ATAN, args, A_NUMBER, 0); if (is_not_null(cdr(args))) { p1 = cadr(args); if (!s7_is_real(p1)) method_or_bust(sc, p1, sc->ATAN, args, T_REAL, 2); if (!s7_is_real(p0)) return(wrong_type_argument(sc, sc->ATAN, 1, p0, T_REAL)); p1 = promote_number(sc, T_BIG_REAL, p1); } if (s7_is_real(p0)) { mpfr_t n; p0 = promote_number(sc, T_BIG_REAL, p0); mpfr_init_set(n, big_real(p0), GMP_RNDN); if (!p1) mpfr_atan(n, n, GMP_RNDN); else mpfr_atan2(n, n, big_real(p1), GMP_RNDN); p = mpfr_to_big_real(sc, n); mpfr_clear(n); return(p); } { mpc_t n; p0 = promote_number(sc, T_BIG_COMPLEX, p0); mpc_init_set(n, big_complex(p0), MPC_RNDNN); mpc_atan(n, n, MPC_RNDNN); p = mpc_to_big_complex(sc, n); mpc_clear(n); return(p); } } static s7_pointer big_acos(s7_scheme *sc, s7_pointer args) { #define H_acos "(acos z) returns acos(z); (cos (acos 1)) = 1" #define Q_acos pcl_n s7_pointer p; p = car(args); if (!s7_is_number(p)) method_or_bust_with_type(sc, p, sc->ACOS, args, A_NUMBER, 0); if (s7_is_real(p)) { bool ok; mpfr_t temp; mpfr_t n; p = promote_number(sc, T_BIG_REAL, p); mpfr_init_set(n, big_real(p), GMP_RNDN); mpfr_init_set_ui(temp, 1, GMP_RNDN); ok = (mpfr_cmpabs(n, temp) <= 0); mpfr_clear(temp); if (ok) { mpfr_acos(n, n, GMP_RNDN); p = mpfr_to_big_real(sc, n); mpfr_clear(n); return(p); } mpfr_clear(n); } { mpc_t n; p = promote_number(sc, T_BIG_COMPLEX, p); mpc_init_set(n, big_complex(p), MPC_RNDNN); mpc_acos(n, n, MPC_RNDNN); p = mpc_to_big_complex(sc, n); mpc_clear(n); return(p); } } static s7_pointer big_asin(s7_scheme *sc, s7_pointer args) { #define H_asin "(asin z) returns asin(z); (sin (asin 1)) = 1" #define Q_asin pcl_n s7_pointer p; p = car(args); if (!s7_is_number(p)) method_or_bust_with_type(sc, p, sc->ASIN, args, A_NUMBER, 0); if (s7_is_real(p)) { bool ok; mpfr_t temp; mpfr_t n; p = promote_number(sc, T_BIG_REAL, p); mpfr_init_set(n, big_real(p), GMP_RNDN); mpfr_init_set_ui(temp, 1, GMP_RNDN); ok = (mpfr_cmpabs(n, temp) <= 0); mpfr_clear(temp); if (ok) { mpfr_asin(n, n, GMP_RNDN); p = mpfr_to_big_real(sc, n); mpfr_clear(n); return(p); } mpfr_clear(n); } { mpc_t n; p = promote_number(sc, T_BIG_COMPLEX, p); mpc_init_set(n, big_complex(p), MPC_RNDNN); mpc_asin(n, n, MPC_RNDNN); p = mpc_to_big_complex(sc, n); mpc_clear(n); return(p); } } static s7_pointer big_lognot(s7_scheme *sc, s7_pointer args) { if (is_t_big_integer(car(args))) { s7_pointer p; mpz_t n; mpz_init(n); mpz_com(n, big_integer(car(args))); p = mpz_to_big_integer(sc, n); mpz_clear(n); return(p); } return(g_lognot(sc, args)); } #if (!WITH_PURE_S7) static s7_pointer big_integer_length(s7_scheme *sc, s7_pointer args) { if (is_t_big_integer(car(args))) { s7_pointer result; mpfr_t n; mpfr_init_set_z(n, big_integer(car(args)), GMP_RNDN); if (mpfr_cmp_ui(n, 0) < 0) mpfr_neg(n, n, GMP_RNDN); else mpfr_add_ui(n, n, 1, GMP_RNDN); mpfr_log2(n, n, GMP_RNDU); result = make_integer(sc, mpfr_get_si(n, GMP_RNDU)); mpfr_clear(n); return(result); } return(g_integer_length(sc, args)); } #endif static s7_pointer big_ash(s7_scheme *sc, s7_pointer args) { s7_pointer p0, p1; p0 = car(args); p1 = cadr(args); /* here, as in expt, there are cases like (ash 1 63) which need to be handled as bignums * so there's no way to tell when it's safe to drop into g_ash instead. */ if ((s7_is_integer(p0)) && /* this includes bignum ints... */ (s7_is_integer(p1))) { mpz_t n; s7_int shift; s7_pointer p; bool p0_is_big; int p0_compared_to_zero = 0; p0_is_big = is_big_number(p0); if (p0_is_big) p0_compared_to_zero = mpz_cmp_ui(big_integer(p0), 0); else { if (s7_integer(p0) > 0) p0_compared_to_zero = 1; else { if (s7_integer(p0) < 0) p0_compared_to_zero = -1; else p0_compared_to_zero = 0; } } if (p0_compared_to_zero == 0) return(small_int(0)); if (is_big_number(p1)) { if (!mpz_fits_sint_p(big_integer(p1))) { if (mpz_cmp_ui(big_integer(p1), 0) > 0) return(out_of_range(sc, sc->ASH, small_int(2), p1, ITS_TOO_LARGE)); /* here if p0 is negative, we need to return -1 */ if (p0_compared_to_zero == 1) return(small_int(0)); return(minus_one); } shift = mpz_get_si(big_integer(p1)); } else { shift = s7_integer(p1); if (shift < s7_int32_min) { if (p0_compared_to_zero == 1) return(small_int(0)); return(minus_one); } } mpz_init_set(n, big_integer(promote_number(sc, T_BIG_INTEGER, p0))); if (shift > 0) /* left */ mpz_mul_2exp(n, n, shift); else { if (shift < 0) /* right */ mpz_fdiv_q_2exp(n, n, (unsigned int)(-shift)); } p = mpz_to_big_integer(sc, n); mpz_clear(n); return(p); } return(g_ash(sc, args)); } static bool is_integer_via_method(s7_scheme *sc, s7_pointer p) { if (s7_is_integer(p)) return(true); if (has_methods(p)) { s7_pointer f; f = find_method(sc, find_let(sc, p), sc->IS_INTEGER); if (f != sc->UNDEFINED) return(is_true(sc, s7_apply_function(sc, f, cons(sc, p, sc->NIL)))); } return(false); } static s7_pointer big_bits(s7_scheme *sc, s7_pointer args, s7_pointer sym, int start, s7_function g_bits, void (*mpz_bits)(mpz_ptr, mpz_srcptr, mpz_srcptr)) { s7_pointer x, lst; bool use_bigs = false; for (x = args; is_not_null(x); x = cdr(x)) { if (!is_integer_via_method(sc, car(x))) return(wrong_type_argument(sc, sym, position_of(x, args), car(x), T_INTEGER)); if (!use_bigs) use_bigs = (type(car(x)) != T_INTEGER); } if (use_bigs) { mpz_t n; mpz_init_set_si(n, 0); if (start == -1) mpz_sub_ui(n, n, 1); for (x = args; is_not_null(x); x = cdr(x)) { s7_pointer i; i = car(x); switch (type(i)) { case T_BIG_INTEGER: mpz_bits(n, n, big_integer(i)); break; case T_INTEGER: mpz_bits(n, n, big_integer(s7_int_to_big_integer(sc, integer(i)))); break; default: /* we know it's an integer of some sort, but what about the method */ lst = cons(sc, mpz_to_big_integer(sc, n), x); mpz_clear(n); method_or_bust(sc, i, sym, lst, T_INTEGER, position_of(x, args)); } } x = mpz_to_big_integer(sc, n); mpz_clear(n); return(x); } return(g_bits(sc, args)); } static s7_pointer big_logand(s7_scheme *sc, s7_pointer args) { if (is_null(args)) return(minus_one); return(big_bits(sc, args, sc->LOGAND, -1, g_logand, mpz_and)); } static s7_pointer big_logior(s7_scheme *sc, s7_pointer args) { if (is_null(args)) return(small_int(0)); return(big_bits(sc, args, sc->LOGIOR, 0, g_logior, mpz_ior)); } static s7_pointer big_logxor(s7_scheme *sc, s7_pointer args) { if (is_null(args)) return(small_int(0)); return(big_bits(sc, args, sc->LOGXOR, 0, g_logxor, mpz_xor)); } static s7_pointer big_rationalize(s7_scheme *sc, s7_pointer args) { #define H_rationalize "(rationalize x err) returns the ratio with lowest denominator within err of x" #define Q_rationalize s7_make_signature(sc, 3, sc->IS_RATIONAL, sc->IS_REAL, sc->IS_REAL) /* currently (rationalize 1/0 1e18) -> 0 * remember to pad with many trailing zeros: * * : (rationalize 0.1 0) * 3602879701896397/36028797018963968 * :(rationalize 0.1000000000000000 0) * 1/10 * * perhaps gmp number reader used if gmp -- could this be the trailing zeros problem? (why is the non-gmp case ok?) * also the bignum function is faking it. * (rationalize (real-part (bignum "0.1+i")) 0) -> 3602879701896397/36028797018963968 * * a confusing case: * > (rationalize 5925563891587147521650777143.74135805596e05) * should be 148139097289678688041269428593533951399/250000 * but that requires more than 128 bits of bignum-precision. */ s7_pointer p0, p1 = NULL, p; mpfr_t error, ux, x0, x1; mpz_t i, i0, i1; double xx; p0 = car(args); if (!s7_is_real(p0)) method_or_bust(sc, p0, sc->RATIONALIZE, args, T_REAL, 1); /* p0 can be exact, but we still have to check it for simplification */ if (is_not_null(cdr(args))) { double err_x; p1 = cadr(args); if (!s7_is_real(p1)) /* (rationalize (expt 2 60) -) */ method_or_bust(sc, p1, sc->RATIONALIZE, args, T_REAL, 2); if (is_big_number(p1)) mpfr_init_set(error, big_real(promote_number(sc, T_BIG_REAL, p1)), GMP_RNDN); else mpfr_init_set_d(error, real_to_double(sc, p1, "rationalize"), GMP_RNDN); err_x = mpfr_get_d(error, GMP_RNDN); if (is_NaN(err_x)) { mpfr_clear(error); return(out_of_range(sc, sc->RATIONALIZE, small_int(2), cadr(args), ITS_NAN)); } if (mpfr_inf_p(error) != 0) { mpfr_clear(error); return(small_int(0)); } mpfr_abs(error, error, GMP_RNDN); } else mpfr_init_set_d(error, sc->default_rationalize_error, GMP_RNDN); if (is_big_number(p0)) mpfr_init_set(ux, big_real(promote_number(sc, T_BIG_REAL, p0)), GMP_RNDN); else mpfr_init_set_d(ux, real_to_double(sc, p0, "rationalize"), GMP_RNDN); xx = mpfr_get_d(ux, GMP_RNDN); if (is_NaN(xx)) { mpfr_clear(ux); mpfr_clear(error); return(out_of_range(sc, sc->RATIONALIZE, small_int(1), car(args), ITS_NAN)); } if (mpfr_inf_p(ux) != 0) { mpfr_clear(ux); mpfr_clear(error); return(out_of_range(sc, sc->RATIONALIZE, small_int(1), car(args), ITS_INFINITE)); } mpfr_init_set(x0, ux, GMP_RNDN); /* x0 = ux - error */ mpfr_sub(x0, x0, error, GMP_RNDN); mpfr_init_set(x1, ux, GMP_RNDN); /* x1 = ux + error */ mpfr_add(x1, x1, error, GMP_RNDN); mpz_init(i); mpfr_get_z(i, x0, GMP_RNDU); /* i = ceil(x0) */ if (mpfr_cmp_ui(error, 1) >= 0) /* if (error >= 1.0) */ { mpz_t n; if (mpfr_cmp_ui(x0, 0) < 0) /* if (x0 < 0) */ { if (mpfr_cmp_ui(x1, 0) < 0) /* if (x1 < 0) */ { mpz_init(n); mpfr_get_z(n, x1, GMP_RNDD); /* num = floor(x1) */ } else mpz_init_set_ui(n, 0); /* else num = 0 */ } else mpz_init_set(n, i); /* else num = i */ mpz_clear(i); mpfr_clear(ux); mpfr_clear(x0); mpfr_clear(x1); mpfr_clear(error); p = mpz_to_big_integer(sc, n); mpz_clear(n); return(p); } if (mpfr_cmp_z(x1, i) >= 0) /* if (x1 >= i) */ { mpz_t n; if (mpz_cmp_ui(i, 0) >= 0) /* if (i >= 0) */ mpz_init_set(n, i); /* num = i */ else { mpz_init(n); mpfr_get_z(n, x1, GMP_RNDD); /* else num = floor(x1) */ } mpz_clear(i); mpfr_clear(ux); mpfr_clear(x0); mpfr_clear(x1); mpfr_clear(error); p = mpz_to_big_integer(sc, n); mpz_clear(n); return(p); } { mpz_t p0, q0, r, r1, p1, q1, old_p1, old_q1; mpfr_t val, e0, e1, e0p, e1p, old_e0, old_e1, old_e0p; mpz_init(i0); mpz_init(i1); mpfr_get_z(i0, x0, GMP_RNDD); /* i0 = floor(x0) */ mpfr_get_z(i1, x1, GMP_RNDU); /* i1 = ceil(x1) */ mpz_init_set(p0, i0); /* p0 = i0 */ mpz_init_set_ui(q0, 1); /* q0 = 1 */ mpz_init_set(p1, i1); /* p1 = i1 */ mpz_init_set_ui(q1, 1); /* q1 = 1 */ mpfr_init(e0); mpfr_init(e1); mpfr_init(e0p); mpfr_init(e1p); mpfr_sub_z(e0, x0, i1, GMP_RNDN); /* e0 = i1 - x0 */ mpfr_neg(e0, e0, GMP_RNDN); mpfr_sub_z(e1, x0, i0, GMP_RNDN); /* e1 = x0 - i0 */ mpfr_sub_z(e0p, x1, i1, GMP_RNDN); /* e0p = i1 - x1 */ mpfr_neg(e0p, e0p, GMP_RNDN); mpfr_sub_z(e1p, x1, i0, GMP_RNDN); /* e1p = x1 - i0 */ mpfr_init(val); mpfr_init(old_e0); mpfr_init(old_e1); mpfr_init(old_e0p); mpz_init(r); mpz_init(r1); mpz_init(old_p1); mpz_init(old_q1); while (true) { mpfr_set_z(val, p0, GMP_RNDN); mpfr_div_z(val, val, q0, GMP_RNDN); /* val = p0/q0 */ if (((mpfr_cmp(x0, val) <= 0) && /* if ((x0 <= val) && (val <= x1)) */ (mpfr_cmp(val, x1) <= 0)) || (mpfr_cmp_ui(e1, 0) == 0) || (mpfr_cmp_ui(e1p, 0) == 0)) /* these last 2 are probably not needed -- they protect against running out of bits in the non-gmp case above */ { mpq_t q; mpq_init(q); mpq_set_num(q, p0); /* return(p0/q0) */ mpq_set_den(q, q0); mpz_clear(i); mpz_clear(i0); mpz_clear(i1); mpfr_clear(ux); mpfr_clear(x0); mpfr_clear(x1); mpfr_clear(error); mpz_clear(p0); mpz_clear(q0); mpz_clear(r); mpz_clear(r1); mpz_clear(p1); mpz_clear(q1); mpz_clear(old_p1); mpz_clear(old_q1); mpfr_clear(val); mpfr_clear(e0); mpfr_clear(e1); mpfr_clear(e0p); mpfr_clear(e1p); mpfr_clear(old_e0); mpfr_clear(old_e1); mpfr_clear(old_e0p); p = mpq_to_big_ratio(sc, q); mpq_clear(q); return(p); } mpfr_div(val, e0, e1, GMP_RNDN); mpfr_get_z(r, val, GMP_RNDD); /* r = floor(e0/e1) */ mpfr_div(val, e0p, e1p, GMP_RNDN); mpfr_get_z(r1, val, GMP_RNDU); /* r1 = ceil(e0p/e1p) */ if (mpz_cmp(r1, r) < 0) /* if (r1 < r) */ mpz_set(r, r1); /* r = r1 */ mpz_set(old_p1, p1); /* old_p1 = p1 */ mpz_set(p1, p0); /* p1 = p0 */ mpz_set(old_q1, q1); /* old_q1 = q1 */ mpz_set(q1, q0); /* q1 = q0 */ mpfr_set(old_e0, e0, GMP_RNDN); /* old_e0 = e0 */ mpfr_set(e0, e1p, GMP_RNDN); /* e0 = e1p */ mpfr_set(old_e0p, e0p, GMP_RNDN); /* old_e0p = e0p */ mpfr_set(e0p, e1, GMP_RNDN); /* e0p = e1 */ mpfr_set(old_e1, e1, GMP_RNDN); /* old_e1 = e1 */ mpz_mul(p0, p0, r); /* p0 = old_p1 + r * p0 */ mpz_add(p0, p0, old_p1); mpz_mul(q0, q0, r); /* q0 = old_q1 + r * q0 */ mpz_add(q0, q0, old_q1); mpfr_mul_z(e1, e1p, r, GMP_RNDN); /* e1 = old_e0p - r * e1p */ mpfr_sub(e1, old_e0p, e1, GMP_RNDN); mpfr_mul_z(e1p, old_e1, r, GMP_RNDN); /* e1p = old_e0 - r * old_e1 */ mpfr_sub(e1p, old_e0, e1p, GMP_RNDN); } } } #if (!WITH_PURE_S7) static s7_pointer big_exact_to_inexact(s7_scheme *sc, s7_pointer args) { #define H_exact_to_inexact "(exact->inexact num) converts num to an inexact number; (exact->inexact 3/2) = 1.5" #define Q_exact_to_inexact pcl_r s7_pointer p; p = car(args); if (!s7_is_number(p)) /* apparently (exact->inexact 1+i) is not an error */ method_or_bust_with_type(sc, p, sc->EXACT_TO_INEXACT, args, A_NUMBER, 0); if (!s7_is_rational(p)) return(p); return(promote_number(sc, T_BIG_REAL, to_big(sc, p))); } static s7_pointer big_inexact_to_exact(s7_scheme *sc, s7_pointer args) { #define H_inexact_to_exact "(inexact->exact num) converts num to an exact number; (inexact->exact 1.5) = 3/2" #define Q_inexact_to_exact s7_make_signature(sc, 2, sc->IS_RATIONAL, sc->IS_REAL) s7_pointer p; p = car(args); if (s7_is_rational(p)) return(p); if (!s7_is_real(p)) method_or_bust(sc, p, sc->INEXACT_TO_EXACT, args, T_REAL, 0); return(big_rationalize(sc, args)); } #endif static s7_pointer big_convert_to_int(s7_scheme *sc, s7_pointer args, s7_pointer sym, void (*div_func)(mpz_ptr, mpz_srcptr, mpz_srcptr), mp_rnd_t mode) { /* we can't go to the normal (non-gmp) functions here */ s7_pointer p; mpz_t n; p = car(args); if (!s7_is_real(p)) method_or_bust(sc, p, sym, args, T_REAL, 0); if (s7_is_integer(p)) return(p); p = to_big(sc, p); if (is_t_big_ratio(p)) { /* apparently we have to do the divide by hand */ mpz_t d; mpz_init_set(n, mpq_numref(big_ratio(p))); mpz_init_set(d, mpq_denref(big_ratio(p))); div_func(n, n, d); mpz_clear(d); } else { if ((g_is_nan(sc, args) == sc->T) || (g_is_infinite(sc, args)) == sc->T) return(simple_out_of_range(sc, sym, p, (g_is_nan(sc, args) == sc->T) ? ITS_NAN : ITS_INFINITE)); mpz_init(n); mpfr_get_z(n, big_real(p), mode); } p = mpz_to_big_integer(sc, n); mpz_clear(n); return(p); } static s7_pointer big_floor(s7_scheme *sc, s7_pointer args) { #define H_floor "(floor x) returns the integer closest to x toward -inf" #define Q_floor s7_make_signature(sc, 2, sc->IS_INTEGER, sc->IS_REAL) return(big_convert_to_int(sc, args, sc->FLOOR, mpz_fdiv_q, GMP_RNDD)); } static s7_pointer big_ceiling(s7_scheme *sc, s7_pointer args) { #define H_ceiling "(ceiling x) returns the integer closest to x toward inf" #define Q_ceiling s7_make_signature(sc, 2, sc->IS_INTEGER, sc->IS_REAL) return(big_convert_to_int(sc, args, sc->CEILING, mpz_cdiv_q, GMP_RNDU)); } static s7_pointer big_truncate(s7_scheme *sc, s7_pointer args) { #define H_truncate "(truncate x) returns the integer closest to x toward 0" #define Q_truncate s7_make_signature(sc, 2, sc->IS_INTEGER, sc->IS_REAL) return(big_convert_to_int(sc, args, sc->TRUNCATE, mpz_tdiv_q, GMP_RNDZ)); } static s7_pointer big_round(s7_scheme *sc, s7_pointer args) { #define H_round "(round x) returns the integer closest to x" #define Q_round s7_make_signature(sc, 2, sc->IS_INTEGER, sc->IS_REAL) s7_pointer p; mpz_t n; p = car(args); if (!s7_is_real(p)) method_or_bust(sc, p, sc->ROUND, args, T_REAL, 0); if (s7_is_integer(p)) return(p); p = to_big(sc, p); if (is_t_big_integer(p)) return(p); if (is_t_big_ratio(p)) { int rnd; mpz_t rm; mpz_init_set(n, mpq_numref(big_ratio(p))); mpz_init(rm); mpz_fdiv_qr(n, rm, n, mpq_denref(big_ratio(p))); mpz_mul_ui(rm, rm, 2); rnd = mpz_cmpabs(rm, mpq_denref(big_ratio(p))); mpz_fdiv_q(rm, rm, mpq_denref(big_ratio(p))); if (rnd > 0) mpz_add(n, n, rm); else { if (rnd == 0) { if (mpz_odd_p(n)) mpz_add_ui(n, n, 1); } } mpz_clear(rm); p = mpz_to_big_integer(sc, n); mpz_clear(n); return(p); } if ((g_is_nan(sc, args) == sc->T) || (g_is_infinite(sc, args)) == sc->T) return(simple_out_of_range(sc, sc->ROUND, p, (g_is_nan(sc, args) == sc->T) ? ITS_NAN : ITS_INFINITE)); { int cmp_res; mpz_t fl, ce; mpfr_t x, dfl, dce; mpfr_init_set(x, big_real(p), GMP_RNDN); mpz_init(fl); mpfr_get_z(fl, x, GMP_RNDD); /* fl = floor(x) */ mpz_init(ce); mpfr_get_z(ce, x, GMP_RNDU); /* ce = ceil(x) */ mpfr_init(dfl); mpfr_sub_z(dfl, x, fl, GMP_RNDN); /* dfl = x - fl */ mpfr_init(dce); mpfr_sub_z(dce, x, ce, GMP_RNDN); /* dce = -(ce - x) */ mpfr_neg(dce, dce, GMP_RNDN); /* and reversed */ cmp_res = mpfr_cmp(dfl, dce); if (cmp_res > 0) /* if (dfl > dce) return(ce) */ mpz_init_set(n, ce); else { if (cmp_res < 0) /* if (dfl < dce) return(fl) */ mpz_init_set(n, fl); else { if (mpz_even_p(fl)) mpz_init_set(n, fl); /* if (mod(fl, 2) == 0) return(fl) */ else mpz_init_set(n, ce); /* else return(ce) */ } } mpz_clear(fl); mpz_clear(ce); mpfr_clear(dfl); mpfr_clear(dce); mpfr_clear(x); p = mpz_to_big_integer(sc, n); mpz_clear(n); return(p); } } static s7_pointer big_quotient(s7_scheme *sc, s7_pointer args) { #define H_quotient "(quotient x1 x2) returns the integer quotient of x1 and x2; (quotient 4 3) = 1" #define Q_quotient pcl_r s7_pointer x, y, p; x = car(args); y = cadr(args); if (!s7_is_real(x)) method_or_bust(sc, x, sc->QUOTIENT, args, T_REAL, 1); if (!s7_is_real(y)) method_or_bust(sc, y, sc->QUOTIENT, args, T_REAL, 2); if ((s7_is_integer(x)) && (s7_is_integer(y))) { mpz_t n; x = to_big(sc, x); y = to_big(sc, y); if (s7_is_zero(y)) return(division_by_zero_error(sc, sc->QUOTIENT, args)); mpz_init_set(n, big_integer(x)); mpz_tdiv_q(n, n, big_integer(y)); p = mpz_to_big_integer(sc, n); mpz_clear(n); return(p); } return(big_truncate(sc, set_plist_1(sc, big_divide(sc, args)))); } static s7_pointer big_remainder(s7_scheme *sc, s7_pointer args) { #define H_remainder "(remainder x1 x2) returns the integer remainder of x1 and x2; (remainder 10 3) = 1" #define Q_remainder pcl_r s7_pointer x, y, p; x = car(args); y = cadr(args); if (!s7_is_real(x)) method_or_bust(sc, x, sc->REMAINDER, args, T_REAL, 1); if (!s7_is_real(y)) method_or_bust(sc, y, sc->REMAINDER, args, T_REAL, 2); if ((s7_is_integer(x)) && (s7_is_integer(y))) { mpz_t n; x = to_big(sc, x); y = to_big(sc, y); if (s7_is_zero(y)) return(division_by_zero_error(sc, sc->REMAINDER, args)); mpz_init_set(n, big_integer(x)); mpz_tdiv_r(n, n, big_integer(y)); p = mpz_to_big_integer(sc, n); mpz_clear(n); return(p); } return(big_subtract(sc, list_2(sc, x, big_multiply(sc, set_plist_2(sc, y, big_quotient(sc, args)))))); } static s7_pointer big_modulo(s7_scheme *sc, s7_pointer args) { #define H_modulo "(modulo x1 x2) returns x1 mod x2; (modulo 4 3) = 1. The arguments can be real numbers." #define Q_modulo pcl_r s7_pointer a, b, p; a = car(args); if (!s7_is_real(a)) method_or_bust(sc, a, sc->MODULO, args, T_REAL, 1); b = cadr(args); if (!s7_is_real(b)) method_or_bust(sc, b, sc->MODULO, args, T_REAL, 2); a = to_big(sc, a); b = to_big(sc, b); if ((s7_is_integer(a)) && (s7_is_integer(b))) { s7_pointer x, y; int cy, cz; mpz_t n; y = promote_number(sc, T_BIG_INTEGER, b); if (mpz_cmp_ui(big_integer(y), 0) == 0) return(a); x = promote_number(sc, T_BIG_INTEGER, a); /* mpz_mod is too tricky here */ mpz_init_set(n, big_integer(x)); mpz_fdiv_r(n, n, big_integer(y)); cy = mpz_cmp_ui(big_integer(y), 0); cz = mpz_cmp_ui(n, 0); if (((cy < 0) && (cz > 0)) || ((cy > 0) && (cz < 0))) mpz_add(n, n, big_integer(y)); p = mpz_to_big_integer(sc, n); mpz_clear(n); return(p); } return(big_subtract(sc, list_2(sc, a, big_multiply(sc, list_2(sc, b, big_floor(sc, set_plist_1(sc, big_divide(sc, set_plist_2(sc, a, b))))))))); } static int big_real_scan_args(s7_scheme *sc, s7_pointer args) { int i, result_type = T_INTEGER; s7_pointer arg; for (i = 1, arg = args; is_not_null(arg); i++, arg = cdr(arg)) { s7_pointer p; p = car(arg); if (!is_real_via_method(sc, p)) return(-i); result_type = get_result_type(sc, result_type, p); } return(result_type); } static s7_pointer big_max(s7_scheme *sc, s7_pointer args) { int result_type; s7_pointer x, result, arg; result_type = big_real_scan_args(sc, args); if (result_type < 0) return(wrong_type_argument(sc, sc->MAX, -result_type, s7_list_ref(sc, args, -1 - result_type), T_REAL)); if (result_type < T_BIG_INTEGER) return(g_max(sc, args)); if (!s7_is_number(car(args))) check_method(sc, car(args), sc->MAX, args); result = promote_number(sc, result_type, car(args)); for (x = cdr(args); is_not_null(x); x = cdr(x)) { if (!s7_is_number(car(x))) check_method(sc, car(x), sc->MAX, cons(sc, result, x)); arg = promote_number(sc, result_type, car(x)); switch (result_type) { case T_BIG_INTEGER: if (mpz_cmp(big_integer(result), big_integer(arg)) < 0) result = arg; break; case T_BIG_RATIO: if (mpq_cmp(big_ratio(result), big_ratio(arg)) < 0) result = arg; break; case T_BIG_REAL: if (mpfr_cmp(big_real(result), big_real(arg)) < 0) result = arg; break; } } if (result_type == T_BIG_RATIO) /* maybe actual result was an int */ { if (mpz_cmp_ui(mpq_denref(big_ratio(result)), 1) == 0) { mpz_t n; s7_pointer p; mpz_init_set(n, mpq_numref(big_ratio(result))); p = mpz_to_big_integer(sc, n); mpz_clear(n); return(p); } } return(result); } static s7_pointer big_min(s7_scheme *sc, s7_pointer args) { int result_type; s7_pointer x, result, arg; result_type = big_real_scan_args(sc, args); if (result_type < 0) return(wrong_type_argument(sc, sc->MIN, -result_type, s7_list_ref(sc, args, -1 - result_type), T_REAL)); if (result_type < T_BIG_INTEGER) return(g_min(sc, args)); if (!s7_is_number(car(args))) check_method(sc, car(args), sc->MIN, args); result = promote_number(sc, result_type, car(args)); for (x = cdr(args); is_not_null(x); x = cdr(x)) { if (!s7_is_number(car(x))) check_method(sc, car(x), sc->MIN, cons(sc, result, x)); arg = promote_number(sc, result_type, car(x)); switch (result_type) { case T_BIG_INTEGER: if (mpz_cmp(big_integer(result), big_integer(arg)) > 0) result = arg; break; case T_BIG_RATIO: if (mpq_cmp(big_ratio(result), big_ratio(arg)) > 0) result = arg; break; case T_BIG_REAL: if (mpfr_cmp(big_real(result), big_real(arg)) > 0) result = arg; break; } } if (result_type == T_BIG_RATIO) /* maybe actual result was an int */ { if (mpz_cmp_ui(mpq_denref(big_ratio(result)), 1) == 0) { mpz_t n; s7_pointer p; mpz_init_set(n, mpq_numref(big_ratio(result))); p = mpz_to_big_integer(sc, n); mpz_clear(n); return(p); } } return(result); } static s7_pointer big_less(s7_scheme *sc, s7_pointer args) { #define H_less "(< x1 ...) returns #t if its arguments are in increasing order" #define Q_less s7_make_circular_signature(sc, 1, 2, sc->IS_BOOLEAN, sc->IS_REAL) int result_type; s7_pointer x, previous, current; result_type = big_real_scan_args(sc, args); if (result_type < 0) return(wrong_type_argument(sc, sc->LT, -result_type, s7_list_ref(sc, args, -1 - result_type), T_REAL)); /* don't try to use g_less here */ if (result_type < T_BIG_INTEGER) result_type += 4; if (!s7_is_number(car(args))) check_method(sc, car(args), sc->LT, args); previous = promote_number(sc, result_type, car(args)); for (x = cdr(args); is_not_null(x); x = cdr(x)) { if (!s7_is_number(car(x))) check_method(sc, car(x), sc->LT, cons(sc, previous, x)); current = promote_number(sc, result_type, car(x)); switch (result_type) { case T_BIG_INTEGER: if (mpz_cmp(big_integer(previous), big_integer(current)) >= 0) return(sc->F); break; case T_BIG_RATIO: if (mpq_cmp(big_ratio(previous), big_ratio(current)) >= 0) return(sc->F); break; case T_BIG_REAL: if (mpfr_cmp(big_real(previous), big_real(current)) >= 0) return(sc->F); break; } previous = current; } return(sc->T); } static s7_pointer big_less_or_equal(s7_scheme *sc, s7_pointer args) { #define H_less_or_equal "(<= x1 ...) returns #t if its arguments are in increasing order" #define Q_less_or_equal s7_make_circular_signature(sc, 1, 2, sc->IS_BOOLEAN, sc->IS_REAL) int result_type; s7_pointer x, previous, current; result_type = big_real_scan_args(sc, args); if (result_type < 0) return(wrong_type_argument(sc, sc->LEQ, -result_type, s7_list_ref(sc, args, -1 - result_type), T_REAL)); if (result_type < T_BIG_INTEGER) result_type += 4; if (!s7_is_number(car(args))) check_method(sc, car(args), sc->LEQ, args); previous = promote_number(sc, result_type, car(args)); for (x = cdr(args); is_not_null(x); x = cdr(x)) { if (!s7_is_number(car(x))) check_method(sc, car(x), sc->LEQ, cons(sc, previous, x)); current = promote_number(sc, result_type, car(x)); switch (result_type) { case T_BIG_INTEGER: if (mpz_cmp(big_integer(previous), big_integer(current)) > 0) return(sc->F); break; case T_BIG_RATIO: if (mpq_cmp(big_ratio(previous), big_ratio(current)) > 0) return(sc->F); break; case T_BIG_REAL: if (mpfr_cmp(big_real(previous), big_real(current)) > 0) return(sc->F); break; } previous = current; } return(sc->T); } static s7_pointer big_greater(s7_scheme *sc, s7_pointer args) { #define H_greater "(> x1 ...) returns #t if its arguments are in decreasing order" #define Q_greater s7_make_circular_signature(sc, 1, 2, sc->IS_BOOLEAN, sc->IS_REAL) int result_type; s7_pointer x, previous, current; result_type = big_real_scan_args(sc, args); if (result_type < 0) return(wrong_type_argument(sc, sc->GT, -result_type, s7_list_ref(sc, args, -1 - result_type), T_REAL)); if (result_type < T_BIG_INTEGER) result_type += 4; if (!s7_is_number(car(args))) check_method(sc, car(args), sc->GT, args); previous = promote_number(sc, result_type, car(args)); for (x = cdr(args); is_not_null(x); x = cdr(x)) { if (!s7_is_number(car(x))) check_method(sc, car(x), sc->GT, cons(sc, previous, x)); current = promote_number(sc, result_type, car(x)); switch (result_type) { case T_BIG_INTEGER: if (mpz_cmp(big_integer(previous), big_integer(current)) <= 0) return(sc->F); break; case T_BIG_RATIO: if (mpq_cmp(big_ratio(previous), big_ratio(current)) <= 0) return(sc->F); break; case T_BIG_REAL: if (mpfr_cmp(big_real(previous), big_real(current)) <= 0) return(sc->F); break; } previous = current; } return(sc->T); } static s7_pointer big_greater_or_equal(s7_scheme *sc, s7_pointer args) { #define H_greater_or_equal "(>= x1 ...) returns #t if its arguments are in decreasing order" #define Q_greater_or_equal s7_make_circular_signature(sc, 1, 2, sc->IS_BOOLEAN, sc->IS_REAL) int result_type; s7_pointer x, previous, current; result_type = big_real_scan_args(sc, args); if (result_type < 0) return(wrong_type_argument(sc, sc->GEQ, -result_type, s7_list_ref(sc, args, -1 - result_type), T_REAL)); if (result_type < T_BIG_INTEGER) result_type += 4; if (!s7_is_number(car(args))) check_method(sc, car(args), sc->GEQ, args); previous = promote_number(sc, result_type, car(args)); for (x = cdr(args); is_not_null(x); x = cdr(x)) { if (!s7_is_number(car(x))) check_method(sc, car(x), sc->GEQ, cons(sc, previous, x)); current = promote_number(sc, result_type, car(x)); switch (result_type) { case T_BIG_INTEGER: if (mpz_cmp(big_integer(previous), big_integer(current)) < 0) return(sc->F); break; case T_BIG_RATIO: if (mpq_cmp(big_ratio(previous), big_ratio(current)) < 0) return(sc->F); break; case T_BIG_REAL: if (mpfr_cmp(big_real(previous), big_real(current)) < 0) return(sc->F); break; } previous = current; } return(sc->T); } static s7_pointer big_equal(s7_scheme *sc, s7_pointer args) { #define Q_equal s7_make_circular_signature(sc, 1, 2, sc->IS_BOOLEAN, sc->IS_NUMBER) /* this is morally-equal? for bignums, the other case goes through big_numbers_are_eqv */ int result_type = T_INTEGER; s7_pointer x, y, result; bool got_nan = false; for (x = args; is_not_null(x); x = cdr(x)) { s7_pointer p; p = car(x); if (!s7_is_number(p)) { check_method(sc, car(args), sc->EQ, x); return(wrong_type_argument_with_type(sc, sc->EQ, position_of(x, args), p, A_NUMBER)); } result_type = get_result_type(sc, result_type, p); if (!got_nan) got_nan = (((is_t_real(p)) && (is_NaN(real(p)))) || /* (= (bignum "3") 1/0) */ ((is_t_complex(p)) && ((is_NaN(real_part(p))) || (is_NaN(imag_part(p)))))); } if (got_nan) return(sc->F); /* put this off until here so that non-numbers anywhere in the arg list will raise an error */ if (result_type < T_BIG_INTEGER) return(g_equal(sc, args)); result = promote_number(sc, result_type, car(args)); for (y = cdr(args); is_not_null(y); y = cdr(y)) { s7_pointer arg; arg = promote_number(sc, result_type, car(y)); switch (result_type) { case T_BIG_INTEGER: if (mpz_cmp(big_integer(result), big_integer(arg)) != 0) return(sc->F); break; case T_BIG_RATIO: if (mpq_cmp(big_ratio(result), big_ratio(arg)) != 0) return(sc->F); break; case T_BIG_REAL: { mpfr_t *a1; a1 = s7_double_to_mpfr(sc->morally_equal_float_epsilon); if (mpfr_cmp(big_real(big_abs(sc, set_plist_1(sc, big_subtract(sc, set_plist_2(sc, result, arg))))), *a1) > 0) return(sc->F); } break; case T_BIG_COMPLEX: { mpfr_t *a1; a1 = s7_double_to_mpfr(sc->morally_equal_float_epsilon); if (mpfr_cmp(big_real(big_magnitude(sc, set_plist_1(sc, big_subtract(sc, set_plist_2(sc, result, arg))))), *a1) > 0) return(sc->F); } break; } } return(sc->T); } static s7_pointer big_gcd(s7_scheme *sc, s7_pointer args) { #define H_gcd "(gcd ...) returns the greatest common divisor of its rational arguments" #define Q_gcd pcl_f bool rats = false; s7_pointer x, lst; for (x = args; is_not_null(x); x = cdr(x)) { if (!is_rational_via_method(sc, car(x))) return(wrong_type_argument_with_type(sc, sc->GCD, position_of(x, args), car(x), A_RATIONAL)); if (!rats) rats = (!is_integer_via_method(sc, car(x))); } if (is_null(cdr(args))) /* (gcd -2305843009213693951/4611686018427387903) */ return(big_abs(sc, args)); if (!rats) { mpz_t n; mpz_init(n); for (x = args; is_not_null(x); x = cdr(x)) { if (!s7_is_number(car(x))) { lst = cons(sc, mpz_to_big_integer(sc, n), x); mpz_clear(n); method_or_bust(sc, car(x), sc->GCD, lst, T_INTEGER, position_of(x, args)); } mpz_gcd(n, n, big_integer(promote_number(sc, T_BIG_INTEGER, car(x)))); if (mpz_cmp_ui(n, 1) == 0) { mpz_clear(n); return(small_int(1)); } } x = mpz_to_big_integer(sc, n); mpz_clear(n); return(x); } { s7_pointer rat; mpq_t q; mpz_t n, d; if (!s7_is_number(car(args))) check_method(sc, car(args), sc->GCD, args); rat = promote_number(sc, T_BIG_RATIO, car(args)); mpz_init_set(n, mpq_numref(big_ratio(rat))); mpz_init_set(d, mpq_denref(big_ratio(rat))); for (x = cdr(args); is_not_null(x); x = cdr(x)) { if (!s7_is_number(car(x))) { mpq_init(q); mpq_set_num(q, n); mpq_set_den(q, d); lst = cons(sc, mpq_to_big_ratio(sc, q), x); mpz_clear(n); mpz_clear(d); mpq_clear(q); method_or_bust_with_type(sc, car(x), sc->GCD, lst, A_RATIONAL, position_of(x, args)); } rat = promote_number(sc, T_BIG_RATIO, car(x)); mpz_gcd(n, n, mpq_numref(big_ratio(rat))); mpz_lcm(d, d, mpq_denref(big_ratio(rat))); } if (mpz_cmp_ui(d, 1) == 0) { rat = mpz_to_big_integer(sc, n); mpz_clear(n); mpz_clear(d); return(rat); } mpq_init(q); mpq_set_num(q, n); mpq_set_den(q, d); mpz_clear(n); mpz_clear(d); x = mpq_to_big_ratio(sc, q); mpq_clear(q); return(x); } } static s7_pointer big_lcm(s7_scheme *sc, s7_pointer args) { #define H_lcm "(lcm ...) returns the least common multiple of its rational arguments" #define Q_lcm pcl_f s7_pointer x, lst; bool rats = false; for (x = args; is_not_null(x); x = cdr(x)) { if (!is_rational_via_method(sc, car(x))) return(wrong_type_argument_with_type(sc, sc->LCM, position_of(x, args), car(x), A_RATIONAL)); if (!rats) rats = (!is_integer_via_method(sc, car(x))); } if (is_null(cdr(args))) /* (lcm -2305843009213693951/4611686018427387903) */ return(big_abs(sc, args)); if (!rats) { mpz_t n; mpz_init(n); mpz_set_ui(n, 1); for (x = args; is_not_null(x); x = cdr(x)) { if (!s7_is_number(car(x))) { lst = cons(sc, mpz_to_big_integer(sc, n), x); mpz_clear(n); method_or_bust(sc, car(x), sc->LCM, lst, T_INTEGER, position_of(x, args)); } mpz_lcm(n, n, big_integer(promote_number(sc, T_BIG_INTEGER, car(x)))); if (mpz_cmp_ui(n, 0) == 0) { mpz_clear(n); return(small_int(0)); } } x = mpz_to_big_integer(sc, n); mpz_clear(n); return(x); } { s7_pointer rat; mpq_t q; mpz_t n, d; if (!s7_is_number(car(args))) check_method(sc, car(args), sc->LCM, args); rat = promote_number(sc, T_BIG_RATIO, car(args)); mpz_init_set(n, mpq_numref(big_ratio(rat))); if (mpz_cmp_ui(n, 0) == 0) { mpz_clear(n); return(small_int(0)); } mpz_init_set(d, mpq_denref(big_ratio(rat))); for (x = cdr(args); is_not_null(x); x = cdr(x)) { if (!s7_is_number(car(x))) { mpq_init(q); mpq_set_num(q, n); mpq_set_den(q, d); lst = cons(sc, mpq_to_big_ratio(sc, q), x); mpz_clear(n); mpz_clear(d); mpq_clear(q); method_or_bust_with_type(sc, car(x), sc->LCM, lst, A_RATIONAL, position_of(x, args)); } rat = promote_number(sc, T_BIG_RATIO, car(x)); mpz_lcm(n, n, mpq_numref(big_ratio(rat))); if (mpz_cmp_ui(n, 0) == 0) { mpz_clear(n); mpz_clear(d); return(small_int(0)); } mpz_gcd(d, d, mpq_denref(big_ratio(rat))); } if (mpz_cmp_ui(d, 1) == 0) { rat = mpz_to_big_integer(sc, n); mpz_clear(n); mpz_clear(d); return(rat); } mpq_init(q); mpq_set_num(q, n); mpq_set_den(q, d); mpz_clear(n); mpz_clear(d); x = mpq_to_big_ratio(sc, q); mpq_clear(q); return(x); } } static s7_pointer set_bignum_precision(s7_scheme *sc, int precision) { mp_prec_t bits; if (precision <= 1) /* (set! (*s7* 'bignum-precision) 1) causes mpfr to segfault! (also 0 and -1) */ return(s7_out_of_range_error(sc, "set! (*s7* 'bignum-precision)", 0, make_integer(sc, precision), "has to be greater than 1")); bits = (mp_prec_t)precision; mpfr_set_default_prec(bits); mpc_set_default_precision(bits); s7_symbol_set_value(sc, sc->PI, big_pi(sc)); return(sc->F); } static s7_pointer big_random_state(s7_scheme *sc, s7_pointer args) { #define H_random_state "(random-state seed) returns a new random number state initialized with 'seed'. \ Pass this as the second argument to 'random' to get a repeatable random number sequence:\n\ (let ((seed (random-state 1234))) (random 1.0 seed))" #define Q_random_state s7_make_circular_signature(sc, 1, 2, sc->IS_RANDOM_STATE, sc->IS_INTEGER) s7_pointer r, seed; seed = car(args); if (!s7_is_integer(seed)) method_or_bust(sc, seed, sc->RANDOM_STATE, args, T_INTEGER, 0); if (type(seed) != T_BIG_INTEGER) seed = promote_number(sc, T_BIG_INTEGER, seed); new_cell(sc, r, T_RANDOM_STATE); gmp_randinit_default(random_gmp_state(r)); gmp_randseed(random_gmp_state(r), big_integer(seed)); return(r); } static s7_pointer big_random(s7_scheme *sc, s7_pointer args) { #define H_random "(random num (state #f)) returns a random number between 0 and num (0 if num=0)." #define Q_random s7_make_signature(sc, 3, sc->IS_NUMBER, sc->IS_NUMBER, sc->IS_RANDOM_STATE) s7_pointer num, state, x; num = car(args); if (!s7_is_number(num)) method_or_bust_with_type(sc, num, sc->RANDOM, args, A_NUMBER, 1); state = sc->default_rng; if (is_not_null(cdr(args))) { state = cadr(args); if (!is_random_state(state)) return(wrong_type_argument_with_type(sc, sc->RANDOM, 2, state, A_RANDOM_STATE_OBJECT)); } if (s7_is_zero(num)) return(num); if (!is_big_number(num)) { switch (type(num)) { case T_INTEGER: num = promote_number(sc, T_BIG_INTEGER, num); break; case T_RATIO: num = promote_number(sc, T_BIG_RATIO, num); break; case T_REAL: num = promote_number(sc, T_BIG_REAL, num); break; default: num = promote_number(sc, T_BIG_COMPLEX, num); break; } } switch (type(num)) { case T_BIG_INTEGER: { mpz_t n; mpz_init(n); mpz_urandomm(n, random_gmp_state(state), big_integer(num)); /* this does not work if num is a negative number -- you get positive results. * so check num for sign, and negate result if necessary. */ if (mpz_cmp_ui(big_integer(num), 0) < 0) mpz_neg(n, n); x = mpz_to_big_integer(sc, n); mpz_clear(n); return(x); } case T_BIG_RATIO: { mpfr_t n, e; mpfr_t rat; mpfr_init_set_ui(n, 1, GMP_RNDN); mpfr_urandomb(n, random_gmp_state(state)); mpfr_init_set_q(rat, big_ratio(num), GMP_RNDN); mpfr_mul(n, n, rat, GMP_RNDN); mpfr_init_set_str(e, "0.0000001", 10, GMP_RNDN); mpfr_mul(e, e, rat, GMP_RNDN); mpfr_clear(rat); /* as in g_random, small ratios are a problem because the error term (sc->default_rationalize_error = 1e-12 here) * clobbers everything to 0. */ x = big_rationalize(sc, set_plist_2(sc, mpfr_to_big_real(sc, n), mpfr_to_big_real(sc, e))); mpfr_clear(n); mpfr_clear(e); return(x); } case T_BIG_REAL: { mpfr_t n; mpfr_init_set_ui(n, 1, GMP_RNDN); mpfr_urandomb(n, random_gmp_state(state)); mpfr_mul(n, n, big_real(num), GMP_RNDN); x = mpfr_to_big_real(sc, n); mpfr_clear(n); return(x); } case T_BIG_COMPLEX: { mpc_t n; mpc_init(n); mpc_urandom(n, random_gmp_state(state)); mpfr_mul(mpc_realref(n), mpc_realref(n), mpc_realref(big_complex(num)), GMP_RNDN); mpfr_mul(mpc_imagref(n), mpc_imagref(n), mpc_imagref(big_complex(num)), GMP_RNDN); x = mpc_to_big_complex(sc, n); mpc_clear(n); return(x); } } return(sc->F); /* make the compiler happy */ } s7_double s7_random(s7_scheme *sc, s7_pointer state) { s7_pointer p; p = big_random(sc, set_plist_1(sc, (state) ? state : sc->default_rng)); return((s7_double)mpfr_get_d(big_real(p), GMP_RNDN)); } static void s7_gmp_init(s7_scheme *sc) { #define big_defun(Scheme_Name, C_Name, Req, Opt, Rst) s7_define_typed_function(sc, Scheme_Name, big_ ## C_Name, Req, Opt, Rst, H_ ## C_Name, Q_ ## C_Name) #define c_big_defun(Scheme_Name, C_Name, Req, Opt, Rst) s7_define_typed_function(sc, Scheme_Name, c_big_ ## C_Name, Req, Opt, Rst, H_ ## C_Name, Q_ ## C_Name) sc->ADD = big_defun("+", add, 0, 0, true); sc->SUBTRACT = big_defun("-", subtract, 1, 0, true); sc->MULTIPLY = big_defun("*", multiply, 0, 0, true); sc->DIVIDE = big_defun("/", divide, 1, 0, true); sc->MAX = big_defun("max", max, 1, 0, true); sc->MIN = big_defun("min", min, 1, 0, true); sc->LT = big_defun("<", less, 2, 0, true); sc->LEQ = big_defun("<=", less_or_equal, 2, 0, true); sc->GT = big_defun(">", greater, 2, 0, true); sc->GEQ = big_defun(">=", greater_or_equal, 2, 0, true); sc->EQ = big_defun("=", equal, 2, 0, true); sc->RATIONALIZE = big_defun("rationalize", rationalize, 1, 1, false); #if (!WITH_PURE_S7) sc->EXACT_TO_INEXACT = big_defun("exact->inexact", exact_to_inexact, 1, 0, false); sc->INEXACT_TO_EXACT = big_defun("inexact->exact", inexact_to_exact, 1, 0, false); sc->INTEGER_LENGTH = big_defun("integer-length", integer_length, 1, 0, false); sc->MAKE_RECTANGULAR = c_big_defun("make-rectangular", complex, 2, 0, false); sc->MAKE_POLAR = big_defun("make-polar", make_polar, 2, 0, false); #endif sc->FLOOR = big_defun("floor", floor, 1, 0, false); sc->CEILING = big_defun("ceiling", ceiling, 1, 0, false); sc->TRUNCATE = big_defun("truncate", truncate, 1, 0, false); sc->ROUND = big_defun("round", round, 1, 0, false); sc->QUOTIENT = big_defun("quotient", quotient, 2, 0, false); sc->REMAINDER = big_defun("remainder", remainder, 2, 0, false); sc->MODULO = big_defun("modulo", modulo, 2, 0, false); sc->GCD = big_defun("gcd", gcd, 0, 0, true); sc->LCM = big_defun("lcm", lcm, 0, 0, true); sc->COMPLEX = c_big_defun("complex", complex, 2, 0, false); sc->MAGNITUDE = big_defun("magnitude", magnitude, 1, 0, false); sc->ANGLE = big_defun("angle", angle, 1, 0, false); sc->ABS = big_defun("abs", abs, 1, 0, false); sc->LOGNOT = big_defun("lognot", lognot, 1, 0, false); sc->LOGIOR = big_defun("logior", logior, 0, 0, true); sc->LOGXOR = big_defun("logxor", logxor, 0, 0, true); sc->LOGAND = big_defun("logand", logand, 0, 0, true); sc->ASH = big_defun("ash", ash, 2, 0, false); sc->EXP = big_defun("exp", exp, 1, 0, false); sc->EXPT = big_defun("expt", expt, 2, 0, false); sc->LOG = big_defun("log", log, 1, 1, false); sc->SQRT = big_defun("sqrt", sqrt, 1, 0, false); sc->SIN = big_defun("sin", sin, 1, 0, false); sc->COS = big_defun("cos", cos, 1, 0, false); sc->TAN = big_defun("tan", tan, 1, 0, false); sc->ASIN = big_defun("asin", asin, 1, 0, false); sc->ACOS = big_defun("acos", acos, 1, 0, false); sc->ATAN = big_defun("atan", atan, 1, 1, false); sc->SINH = big_defun("sinh", sinh, 1, 0, false); sc->COSH = big_defun("cosh", cosh, 1, 0, false); sc->TANH = big_defun("tanh", tanh, 1, 0, false); sc->ASINH = big_defun("asinh", asinh, 1, 0, false); sc->ACOSH = big_defun("acosh", acosh, 1, 0, false); sc->ATANH = big_defun("atanh", atanh, 1, 0, false); sc->RANDOM = big_defun("random", random, 1, 1, false); sc->RANDOM_STATE = big_defun("random-state", random_state, 1, 1, false); sc->IS_BIGNUM = big_defun("bignum?", is_bignum, 1, 0, false); /* needed by Q_bignum below */ sc->BIGNUM = big_defun("bignum", bignum, 1, 1, false); sc->bignum_precision = DEFAULT_BIGNUM_PRECISION; mpfr_set_default_prec((mp_prec_t)DEFAULT_BIGNUM_PRECISION); mpc_set_default_precision((mp_prec_t)DEFAULT_BIGNUM_PRECISION); s7_symbol_set_value(sc, sc->PI, big_pi(sc)); /* if these fixnum limits were read as strings, they'd be bignums in the gmp case, * so for consistency make the symbolic versions bignums as well. */ s7_symbol_set_value(sc, make_symbol(sc, "most-positive-fixnum"), s7_int_to_big_integer(sc, s7_integer(s7_name_to_value(sc, "most-positive-fixnum")))); s7_symbol_set_value(sc, make_symbol(sc, "most-negative-fixnum"), s7_int_to_big_integer(sc, s7_integer(s7_name_to_value(sc, "most-negative-fixnum")))); s7_provide(sc, "gmp"); } #endif /* WITH_GMP */ /* -------------------------------- *s7* environment -------------------------------- */ static void init_s7_let(s7_scheme *sc) { sc->stack_top_symbol = s7_make_symbol(sc, "stack-top"); sc->stack_size_symbol = s7_make_symbol(sc, "stack-size"); sc->stacktrace_defaults_symbol = s7_make_symbol(sc, "stacktrace-defaults"); sc->symbol_table_is_locked_symbol = s7_make_symbol(sc, "symbol-table-locked?"); sc->heap_size_symbol = s7_make_symbol(sc, "heap-size"); sc->free_heap_size_symbol = s7_make_symbol(sc, "free-heap-size"); sc->gc_freed_symbol = s7_make_symbol(sc, "gc-freed"); sc->gc_protected_objects_symbol = s7_make_symbol(sc, "gc-protected-objects"); set_immutable(sc->gc_protected_objects_symbol); sc->input_ports_symbol = s7_make_symbol(sc, "input-ports"); sc->output_ports_symbol = s7_make_symbol(sc, "output-ports"); sc->strings_symbol = s7_make_symbol(sc, "strings"); sc->gensyms_symbol = s7_make_symbol(sc, "gensyms"); sc->vectors_symbol = s7_make_symbol(sc, "vectors"); sc->hash_tables_symbol = s7_make_symbol(sc, "hash-tables"); sc->continuations_symbol = s7_make_symbol(sc, "continuations"); sc->c_objects_symbol = s7_make_symbol(sc, "c-objects"); sc->file_names_symbol = s7_make_symbol(sc, "file-names"); sc->symbol_table_symbol = s7_make_symbol(sc, "symbol-table"); sc->rootlet_size_symbol = s7_make_symbol(sc, "rootlet-size"); sc->c_types_symbol = s7_make_symbol(sc, "c-types"); sc->safety_symbol = s7_make_symbol(sc, "safety"); sc->undefined_identifier_warnings_symbol = s7_make_symbol(sc, "undefined-identifier-warnings"); sc->gc_stats_symbol = s7_make_symbol(sc, "gc-stats"); sc->max_stack_size_symbol = s7_make_symbol(sc, "max-stack-size"); sc->cpu_time_symbol = s7_make_symbol(sc, "cpu-time"); sc->catches_symbol = s7_make_symbol(sc, "catches"); sc->exits_symbol = s7_make_symbol(sc, "exits"); sc->stack_symbol = s7_make_symbol(sc, "stack"); sc->max_string_length_symbol = s7_make_symbol(sc, "max-string-length"); sc->max_list_length_symbol = s7_make_symbol(sc, "max-list-length"); sc->max_vector_length_symbol = s7_make_symbol(sc, "max-vector-length"); sc->max_vector_dimensions_symbol = s7_make_symbol(sc, "max-vector-dimensions"); sc->default_hash_table_length_symbol = s7_make_symbol(sc, "default-hash-table-length"); sc->initial_string_port_length_symbol = s7_make_symbol(sc, "initial-string-port-length"); sc->default_rationalize_error_symbol = s7_make_symbol(sc, "default-rationalize-error"); sc->default_random_state_symbol = s7_make_symbol(sc, "default-random-state"); sc->morally_equal_float_epsilon_symbol = s7_make_symbol(sc, "morally-equal-float-epsilon"); sc->hash_table_float_epsilon_symbol = s7_make_symbol(sc, "hash-table-float-epsilon"); sc->print_length_symbol = s7_make_symbol(sc, "print-length"); sc->bignum_precision_symbol = s7_make_symbol(sc, "bignum-precision"); sc->memory_usage_symbol = s7_make_symbol(sc, "memory-usage"); sc->float_format_precision_symbol = s7_make_symbol(sc, "float-format-precision"); } #ifdef __linux__ #include #endif static s7_pointer describe_memory_usage(s7_scheme *sc) { /* heap, permanent, stack?, doc strings, sigs, c_func structs (and ports etc), vcts, mx_alloc, output bufs, * sinc_tables, c-objects, rc_data, strbuf/tmpbuf[reallocs], autoload tables, hash_entrys, symbol_table, * small_ints? */ int i, syms = 0, len; s7_pointer x; #ifdef __linux__ struct rusage info; getrusage(RUSAGE_SELF, &info); fprintf(stderr, "process size: %lld\n", (s7_int)(info.ru_maxrss * 1024)); #endif fprintf(stderr, "heap: %u (%lld bytes)", sc->heap_size, (s7_int)(sc->heap_size * (sizeof(s7_pointer) + sizeof(s7_cell)))); { unsigned int k; int ts[NUM_TYPES]; for (i = 0; i < NUM_TYPES; i++) ts[i] = 0; for (k = 0; k < sc->heap_size; k++) ts[unchecked_type(sc->heap[k])]++; for (i = 0; i < NUM_TYPES; i++) { if ((i % 10) == 0) fprintf(stderr, "\n "); fprintf(stderr, " %d", ts[i]); } fprintf(stderr, "\n"); } fprintf(stderr, "permanent cells: %d (%lld bytes)\n", permanent_cells, (s7_int)(permanent_cells * sizeof(s7_cell))); for (i = 0; i < vector_length(sc->symbol_table); i++) for (x = vector_element(sc->symbol_table, i); is_not_null(x); x = cdr(x)) syms++; fprintf(stderr, "symbol table: %d (%d symbols, %lld bytes)\n", SYMBOL_TABLE_SIZE, syms, (s7_int)(SYMBOL_TABLE_SIZE * sizeof(s7_pointer) + syms * 3 * sizeof(s7_cell))); fprintf(stderr, "stack: %u (%lld bytes)\n", sc->stack_size, (s7_int)(sc->stack_size * sizeof(s7_pointer))); fprintf(stderr, "c_functions: %d (%d bytes)\n", c_functions, (int)(c_functions * sizeof(c_proc_t))); len = 0; for (i = 0; i < (int)(sc->strings_loc); i++) len += string_length(sc->strings[i]); fprintf(stderr, "strings: %u, %d bytes\n", sc->strings_loc, len); /* also doc strings, permanent strings, etc */ { int hs; hash_entry_t *p; for (hs = 0, p = hash_free_list; p; p = (hash_entry_t *)(p->next), hs++); len = 0; for (i = 0; i < (int)(sc->hash_tables_loc); i++) len += (hash_table_mask(sc->hash_tables[i]) + 1); fprintf(stderr, "hash tables: %d (%d %d), ", (int)(sc->hash_tables_loc), len, hs); } { int fs; port_t *p; for (fs = 0, p = sc->port_heap; p; p = (port_t *)(p->next), fs++); fprintf(stderr, "vectors: %u, input: %u, output: %u, free port: %d\ncontinuations: %u, c_objects: %u, gensyms: %u, setters: %u\n", sc->vectors_loc, sc->input_ports_loc, sc->output_ports_loc, fs, sc->continuations_loc, sc->c_objects_loc, sc->gensyms_loc, sc->setters_loc); } return(sc->F); } static s7_pointer g_s7_let_ref_fallback(s7_scheme *sc, s7_pointer args) { s7_pointer sym; sym = cadr(args); if (!is_symbol(sym)) return(simple_wrong_type_argument(sc, sc->LET_REF, sym, T_SYMBOL)); if (sym == sc->print_length_symbol) /* print-length */ return(s7_make_integer(sc, sc->print_length)); if (sym == sc->stack_top_symbol) /* stack-top = #frames active (4 stack entries per frame) */ return(s7_make_integer(sc, (sc->stack_end - sc->stack_start) / 4)); if (sym == sc->stack_size_symbol) /* stack-size (max so far) */ return(s7_make_integer(sc, sc->stack_size)); if (sym == sc->max_stack_size_symbol) /* max-stack-size */ return(s7_make_integer(sc, sc->max_stack_size)); if (sym == sc->stacktrace_defaults_symbol) /* stacktrace-defaults (used to be *stacktrace*) */ return(sc->stacktrace_defaults); if (sym == sc->symbol_table_is_locked_symbol) /* symbol-table-locked? */ return(make_boolean(sc, sc->symbol_table_is_locked)); if (sym == sc->symbol_table_symbol) /* symbol-table (the raw vector) */ return(sc->symbol_table); if (sym == sc->rootlet_size_symbol) /* rootlet-size */ return(s7_make_integer(sc, sc->rootlet_entries)); if (sym == sc->safety_symbol) /* safety */ return(s7_make_integer(sc, sc->safety)); if (sym == sc->undefined_identifier_warnings_symbol) /* undefined-identifier-warnings */ return(s7_make_boolean(sc, sc->undefined_identifier_warnings)); if (sym == sc->cpu_time_symbol) /* cpu-time */ return(s7_make_real(sc, (double)clock() / (double)CLOCKS_PER_SEC)); if (sym == sc->catches_symbol) /* catches */ return(active_catches(sc)); if (sym == sc->exits_symbol) /* exits */ return(active_exits(sc)); if (sym == sc->stack_symbol) /* stack */ return(stack_entries(sc)); if (sym == sc->heap_size_symbol) /* heap-size */ return(s7_make_integer(sc, sc->heap_size)); if (sym == sc->free_heap_size_symbol) /* free-heap-size (number of unused cells in the heap) */ return(s7_make_integer(sc, sc->free_heap_top - sc->free_heap)); if (sym == sc->gc_freed_symbol) /* gc-freed = # cells freed during last GC sweep */ return(s7_make_integer(sc, sc->gc_freed)); if (sym == sc->gc_protected_objects_symbol) /* gc-protected-objects */ return(sc->protected_objects); if (sym == sc->gc_stats_symbol) /* gc-stats */ return(make_integer(sc, sc->gc_stats)); if (sym == sc->default_rationalize_error_symbol) /* default-rationalize-error */ return(make_real(sc, sc->default_rationalize_error)); if (sym == sc->default_random_state_symbol) /* default-random-state */ return(sc->default_rng); if (sym == sc->max_list_length_symbol) /* max-list-length (as arg to make-list) */ return(s7_make_integer(sc, sc->max_list_length)); if (sym == sc->max_vector_length_symbol) /* max-vector-length (as arg to make-vector and make-hash-table) */ return(s7_make_integer(sc, sc->max_vector_length)); if (sym == sc->max_vector_dimensions_symbol) /* max-vector-dimensions (make-vector) */ return(s7_make_integer(sc, sc->max_vector_dimensions)); if (sym == sc->max_string_length_symbol) /* max-string-length (as arg to make-string and read-string) */ return(s7_make_integer(sc, sc->max_string_length)); if (sym == sc->default_hash_table_length_symbol) /* default size for make-hash-table */ return(s7_make_integer(sc, sc->default_hash_table_length)); if (sym == sc->morally_equal_float_epsilon_symbol) /* morally-equal-float-epsilon */ return(s7_make_real(sc, sc->morally_equal_float_epsilon)); if (sym == sc->hash_table_float_epsilon_symbol) /* hash-table-float-epsilon */ return(s7_make_real(sc, sc->hash_table_float_epsilon)); if (sym == sc->initial_string_port_length_symbol) /* initial-string-port-length */ return(s7_make_integer(sc, sc->initial_string_port_length)); if (sym == sc->input_ports_symbol) /* input-ports */ return(make_vector_wrapper(sc, sc->input_ports_loc, sc->input_ports)); if (sym == sc->output_ports_symbol) /* output-ports */ return(make_vector_wrapper(sc, sc->output_ports_loc, sc->output_ports)); if (sym == sc->strings_symbol) /* strings */ return(make_vector_wrapper(sc, sc->strings_loc, sc->strings)); if (sym == sc->gensyms_symbol) /* gensyms */ return(make_vector_wrapper(sc, sc->gensyms_loc, sc->gensyms)); if (sym == sc->vectors_symbol) /* vectors */ return(make_vector_wrapper(sc, sc->vectors_loc, sc->vectors)); if (sym == sc->hash_tables_symbol) /* hash-tables */ return(make_vector_wrapper(sc, sc->hash_tables_loc, sc->hash_tables)); if (sym == sc->continuations_symbol) /* continuations */ return(make_vector_wrapper(sc, sc->continuations_loc, sc->continuations)); if (sym == sc->c_objects_symbol) /* c-objects */ return(make_vector_wrapper(sc, sc->c_objects_loc, sc->c_objects)); if (sym == sc->file_names_symbol) /* file-names (loaded files) */ return(make_vector_wrapper(sc, sc->file_names_top, sc->file_names)); if (sym == sc->c_types_symbol) /* c-types */ { s7_pointer res; int i; sc->w = sc->NIL; for (i = 0; i < num_object_types; i++) /* c-object type (tag) is i */ sc->w = cons(sc, object_types[i]->scheme_name, sc->w); res = safe_reverse_in_place(sc, sc->w); /* so car(types) has tag 0 */ sc->w = sc->NIL; return(res); } if (sym == sc->bignum_precision_symbol) /* bignum-precision */ return(s7_make_integer(sc, sc->bignum_precision)); if (sym == sc->float_format_precision_symbol) /* float-format-precision */ return(s7_make_integer(sc, float_format_precision)); if (sym == sc->memory_usage_symbol) /* memory-usage */ return(describe_memory_usage(sc)); /* sc->unlet is a scheme vector of slots -- not very useful at the scheme level */ return(sc->UNDEFINED); } static s7_pointer g_s7_let_set_fallback(s7_scheme *sc, s7_pointer args) { s7_pointer sym, val; sym = cadr(args); if (!is_symbol(sym)) return(simple_wrong_type_argument(sc, sc->LET_SET, sym, T_SYMBOL)); val = caddr(args); if ((sym == sc->print_length_symbol) || (sym == sc->max_vector_length_symbol) || (sym == sc->max_vector_dimensions_symbol) || (sym == sc->max_list_length_symbol) || (sym == sc->max_string_length_symbol)) { if (s7_is_integer(val)) { s7_int iv; iv = s7_integer(val); /* might be bignum if gmp */ if (iv < 0) return(simple_out_of_range(sc, sym, val, make_string_wrapper(sc, "should be a positive integer"))); if (sym == sc->print_length_symbol) sc->print_length = iv; else { if (sym == sc->max_vector_length_symbol) sc->max_vector_length = iv; else { if (sym == sc->max_vector_dimensions_symbol) sc->max_vector_dimensions = iv; else { if (sym == sc->max_list_length_symbol) sc->max_list_length = iv; else sc->max_string_length = iv; } } } return(val); } return(simple_wrong_type_argument(sc, sym, val, T_INTEGER)); } if (sym == sc->gc_stats_symbol) { if (s7_is_boolean(val)) {sc->gc_stats = ((val == sc->T) ? GC_STATS : 0); return(val);} if (s7_is_integer(val)) {sc->gc_stats = s7_integer(val); return(val);} return(simple_wrong_type_argument(sc, sym, val, T_BOOLEAN)); } if (sym == sc->symbol_table_is_locked_symbol) { if (s7_is_boolean(val)) {sc->symbol_table_is_locked = (val == sc->T); return(val);} return(simple_wrong_type_argument(sc, sym, val, T_BOOLEAN)); } if (sym == sc->max_stack_size_symbol) { if (s7_is_integer(val)) { s7_int size; size = s7_integer(val); if (size >= INITIAL_STACK_SIZE) { sc->max_stack_size = (unsigned int)size; return(val); } return(simple_out_of_range(sc, sym, val, make_string_wrapper(sc, "should be greater than the initial stack size (512)"))); } return(simple_wrong_type_argument(sc, sym, val, T_INTEGER)); } if (sym == sc->safety_symbol) { if (s7_is_integer(val)) {sc->safety = s7_integer(val); return(val);} return(simple_wrong_type_argument(sc, sym, val, T_INTEGER)); } if (sym == sc->undefined_identifier_warnings_symbol) { if (s7_is_boolean(val)) {sc->undefined_identifier_warnings = s7_boolean(sc, val); return(val);} return(simple_wrong_type_argument(sc, sym, val, T_BOOLEAN)); } if (sym == sc->default_hash_table_length_symbol) { if (s7_is_integer(val)) {sc->default_hash_table_length = s7_integer(val); return(val);} return(simple_wrong_type_argument(sc, sym, val, T_INTEGER)); } if (sym == sc->initial_string_port_length_symbol) { if (s7_is_integer(val)) {sc->initial_string_port_length = s7_integer(val); return(val);} return(simple_wrong_type_argument(sc, sym, val, T_INTEGER)); } if (sym == sc->morally_equal_float_epsilon_symbol) { if (s7_is_real(val)) {sc->morally_equal_float_epsilon = s7_real(val); return(val);} return(simple_wrong_type_argument(sc, sym, val, T_REAL)); } if (sym == sc->hash_table_float_epsilon_symbol) { if (s7_is_real(val)) {sc->hash_table_float_epsilon = s7_real(val); return(val);} return(simple_wrong_type_argument(sc, sym, val, T_REAL)); } if (sym == sc->float_format_precision_symbol) { if (s7_is_integer(val)) {float_format_precision = s7_integer(val); return(val);} return(simple_wrong_type_argument(sc, sym, val, T_INTEGER)); } if (sym == sc->default_rationalize_error_symbol) { if (s7_is_real(val)) {sc->default_rationalize_error = real_to_double(sc, val, "set! default-rationalize-error"); return(val);} return(simple_wrong_type_argument(sc, sym, val, T_REAL)); } if (sym == sc->default_random_state_symbol) { if (is_random_state(val)) { #if (!WITH_GMP) random_seed(sc->default_rng) = random_seed(val); random_carry(sc->default_rng) = random_carry(val); #endif return(val); } return(wrong_type_argument_with_type(sc, sym, 1, val, A_RANDOM_STATE_OBJECT)); } if (sym == sc->stacktrace_defaults_symbol) { if (!is_pair(val)) return(simple_wrong_type_argument(sc, sym, val, T_PAIR)); if (s7_list_length(sc, val) != 5) return(simple_wrong_type_argument_with_type(sc, sym, val, make_string_wrapper(sc, "a list with 5 entries"))); if (!is_integer(car(val))) return(wrong_type_argument_with_type(sc, sym, 1, car(val), make_string_wrapper(sc, "an integer (stack frames)"))); if (!is_integer(cadr(val))) return(wrong_type_argument_with_type(sc, sym, 2, cadr(val), make_string_wrapper(sc, "an integer (cols-for-data)"))); if (!is_integer(caddr(val))) return(wrong_type_argument_with_type(sc, sym, 3, caddr(val), make_string_wrapper(sc, "an integer (line length)"))); if (!is_integer(cadddr(val))) return(wrong_type_argument_with_type(sc, sym, 4, cadddr(val), make_string_wrapper(sc, "an integer (comment position)"))); if (!s7_is_boolean(s7_list_ref(sc,val, 4))) return(wrong_type_argument_with_type(sc, sym, 5, s7_list_ref(sc, val, 4), make_string_wrapper(sc, "a boolean (treat-data-as-comment)"))); sc->stacktrace_defaults = copy_list(sc, val); return(val); } if (sym == sc->bignum_precision_symbol) { if (s7_is_integer(val)) { sc->bignum_precision = s7_integer(val); #if WITH_GMP set_bignum_precision(sc, sc->bignum_precision); #endif return(val); } return(simple_wrong_type_argument(sc, sym, val, T_INTEGER)); } if ((sym == sc->cpu_time_symbol) || (sym == sc->heap_size_symbol) || (sym == sc->free_heap_size_symbol) || (sym == sc->gc_freed_symbol) || (sym == sc->gc_protected_objects_symbol) || (sym == sc->file_names_symbol) || (sym == sc->c_types_symbol) || (sym == sc->catches_symbol) || (sym == sc->exits_symbol) || (sym == sc->rootlet_size_symbol) || (sym == sc->stack_top_symbol) || (sym == sc->stack_size_symbol)) return(s7_error(sc, sc->ERROR, set_elist_2(sc, make_string_wrapper(sc, "can't set (*s7* '~S)"), sym))); return(sc->UNDEFINED); } /* some procedure-signature support functions */ static s7_pointer g_is_float(s7_scheme *sc, s7_pointer args) { #define H_is_float "(float? x) returns #t is x is real and not rational." #define Q_is_float pl_bt s7_pointer p; p = car(args); return(make_boolean(sc, ((is_real(p)) && (!is_rational(p))))); } static s7_pointer g_is_proper_list(s7_scheme *sc, s7_pointer args) { #define H_is_proper_list "(proper-list? x) returns #t is x is a list that is not circular or dotted." #define Q_is_proper_list pl_bt s7_pointer p; p = car(args); return(make_boolean(sc, is_proper_list(sc, p))); } /* how to handle this? */ static s7_pointer g_is_integer_or_real_at_end(s7_scheme *sc, s7_pointer args) {return(sc->T);} static s7_pointer g_is_integer_or_any_at_end(s7_scheme *sc, s7_pointer args) {return(sc->T);} #ifndef _MSC_VER /* gdb stacktrace decoding */ static bool is_decodable(s7_scheme *sc, s7_pointer p) { int i; s7_pointer x; s7_pointer *tp, *heap_top; if ((void *)p == (void *)sc) return(false); /* check basic constants */ if ((p == sc->NIL) || (p == sc->T) || (p == sc->F) || (p == sc->EOF_OBJECT) || (p == sc->ELSE) || (p == sc->rootlet) || (p == sc->UNDEFINED) || (p == sc->UNSPECIFIED) || (p == sc->NO_VALUE) || (p == sc->GC_NIL) || (p == sc->T1_1) || (p == sc->T2_1) || (p == sc->T3_1) || (p == sc->A1_1) || (p == sc->A2_1) || (p == sc->A3_1) || (p == sc->A4_1)) return(true); /* check symbol-table */ for (i = 0; i < vector_length(sc->symbol_table); i++) for (x = vector_element(sc->symbol_table, i); is_not_null(x); x = cdr(x)) { s7_pointer sym; sym = car(x); if ((sym == p) || ((is_global(sym)) && (is_slot(global_slot(sym))) && (p == slot_value(global_slot(sym))))) return(true); } for (i = 0; i < NUM_CHARS; i++) if (p == chars[i]) return(true); for (i = 0; i <= NUM_SMALL_INTS; i++) if (p == small_ints[i]) return(true); /* also real_one and friends, sc->safe_lists, tmp_strs? p|elist? */ /* check the heap */ tp = sc->heap; heap_top = (s7_pointer *)(sc->heap + sc->heap_size); while (tp < heap_top) if (p == (*tp++)) return(true); return(false); } char *s7_decode_bt(void) { FILE *fp; fp = fopen("gdb.txt", "r"); if (fp) { long i, size; size_t bytes; bool in_quotes = false; unsigned char *bt; s7_scheme *sc; sc = hidden_sc; fseek(fp, 0, SEEK_END); size = ftell(fp); rewind(fp); bt = (unsigned char *)malloc((size + 1) * sizeof(unsigned char)); bytes = fread(bt, sizeof(unsigned char), size, fp); if (bytes != (size_t)size) { fclose(fp); free(bt); return((char *)" oops "); } bt[size] = '\0'; fclose(fp); for (i = 0; i < size; i++) { fputc(bt[i], stdout); if ((bt[i] == '"') && ((i == 0) || (bt[i - 1] != '\\'))) in_quotes = (!in_quotes); else { if ((!in_quotes) && (i < size - 8)) { if ((bt[i] == '=') && (((bt[i + 1] == '0') && (bt[i + 2] == 'x')) || ((bt[i + 1] == ' ') && (bt[i + 2] == '0') && (bt[i + 3] == 'x')))) { void *vp; int vals; vals = sscanf((const char *)(bt + i + 1), "%p", &vp); if (vals == 1) { int k; for (k = i + ((bt[i + 2] == 'x') ? 3 : 4); (k < size) && (IS_DIGIT(bt[k], 16)); k++); if ((bt[k] != ' ') || (bt[k + 1] != '"')) { s7_pointer p; p = (s7_pointer)vp; if ((is_decodable(sc, p)) && (!is_free(p))) { if (bt[i + 1] == ' ') fputc(' ', stdout); i = k - 1; if (s7_is_valid(sc, p)) { char *str; str = s7_object_to_c_string(sc, p); fprintf(stdout, "%s%s%s", BOLD_TEXT, str, UNBOLD_TEXT); free(str); } else { if (is_free(p)) fprintf(stderr, "%p: %sfree cell%s", p, BOLD_TEXT, UNBOLD_TEXT); else fprintf(stderr, "%p: %sunprintable?%s", p, BOLD_TEXT, UNBOLD_TEXT); } } } } } } } } free(bt); } return((char *)""); } #endif /* -------------------------------- initialization -------------------------------- */ static s7_pointer make_unique_object(const char* name, unsigned int typ) { s7_pointer p; p = alloc_pointer(); set_type(p, typ | T_IMMUTABLE); unique_name_length(p) = safe_strlen(name); unique_name(p) = copy_string_with_length(name, unique_name_length(p)); unheap(p); return(p); } s7_scheme *s7_init(void) { int i; s7_scheme *sc; s7_pointer sym; static bool already_inited = false; #ifndef _MSC_VER setlocale(LC_NUMERIC, "C"); /* use decimal point in floats */ #endif if (!already_inited) { init_types(); init_ctables(); init_mark_functions(); init_equals(); init_hash_maps(); init_pows(); #if (!WITH_GMP) init_add_ops(); init_multiply_ops(); #endif init_uppers(); all_x_function_init(); init_catchers(); /* sizeof(__float128) == sizeof(long double) so how to distinguish them for printf (L vs Q)? */ /* if (sizeof(s7_double) >= 16) float_format_g = "%.*Qg"; */ /* __float128 */ if (sizeof(s7_double) > 8) float_format_g = "%.*Lg"; /* long double (80-bit precision?) */ else float_format_g = "%.*g"; /* float and double */ } sc = (s7_scheme *)calloc(1, sizeof(s7_scheme)); /* malloc is not recommended here */ hidden_sc = sc; /* for gdb/debugging */ sc->gc_off = true; /* sc->args and so on are not set yet, so a gc during init -> segfault */ sc->gc_stats = 0; init_gc_caches(sc); sc->longjmp_ok = false; sc->symbol_table_is_locked = false; if (sizeof(s7_int) == 4) sc->max_vector_length = (1 << 24); else sc->max_vector_length = (1LL << 32); sc->max_string_length = 1073741824; sc->max_list_length = 1073741824; sc->max_vector_dimensions = 512; sc->strbuf_size = INITIAL_STRBUF_SIZE; sc->strbuf = (char *)calloc(sc->strbuf_size, sizeof(char)); sc->tmpbuf = (char *)calloc(TMPBUF_SIZE, sizeof(char)); sc->print_width = sc->max_string_length; sc->initial_string_port_length = 128; sc->format_depth = -1; sc->slash_str_size = 0; sc->slash_str = NULL; sc->singletons = (s7_pointer *)calloc(256, sizeof(s7_pointer)); sc->read_line_buf = NULL; sc->read_line_buf_size = 0; sc->cur_rf = NULL; sc->rf_free_list = NULL; sc->rf_stack = NULL; sc->NIL = make_unique_object("()", T_NIL); sc->GC_NIL = make_unique_object("#", T_UNIQUE); sc->T = make_unique_object("#t", T_BOOLEAN); sc->F = make_unique_object("#f", T_BOOLEAN); sc->EOF_OBJECT = make_unique_object("#", T_UNIQUE); sc->UNDEFINED = make_unique_object("#", T_UNIQUE); sc->ELSE = make_unique_object("else", T_UNIQUE); /* "else" is added to the rootlet below -- can't do it here because the symbol table and environment don't exist yet. */ sc->UNSPECIFIED = make_unique_object("#", T_UNSPECIFIED); sc->NO_VALUE = make_unique_object("#", T_UNSPECIFIED); car(sc->NIL) = cdr(sc->NIL) = sc->UNSPECIFIED; /* this is mixing two different s7_cell structs, cons and envr, but luckily * envr has two initial s7_pointer fields, equivalent to car and cdr, so * let_id which is the same as opt1 is unaffected. To get the names * built-in, I'll append unique_name and unique_name_length fields to * the envr struct. */ let_id(sc->NIL) = -1; unique_cdr(sc->UNSPECIFIED) = sc->UNSPECIFIED; unique_cdr(sc->UNDEFINED) = sc->UNDEFINED; /* this way find_symbol of an undefined symbol returns # not # */ sc->temp_cell_1 = permanent_cons(sc->NIL, sc->NIL, T_PAIR | T_IMMUTABLE); sc->temp_cell = permanent_cons(sc->temp_cell_1, sc->NIL, T_PAIR | T_IMMUTABLE); sc->temp_cell_2 = permanent_cons(sc->NIL, sc->NIL, T_PAIR | T_IMMUTABLE); sc->T1_1 = permanent_cons(sc->NIL, sc->NIL, T_PAIR | T_IMMUTABLE); sc->T2_2 = permanent_cons(sc->NIL, sc->NIL, T_PAIR | T_IMMUTABLE); sc->T2_1 = permanent_cons(sc->NIL, sc->T2_2, T_PAIR | T_IMMUTABLE); sc->Z2_2 = permanent_cons(sc->NIL, sc->NIL, T_PAIR | T_IMMUTABLE); sc->Z2_1 = permanent_cons(sc->NIL, sc->Z2_2, T_PAIR | T_IMMUTABLE); sc->T3_3 = permanent_cons(sc->NIL, sc->NIL, T_PAIR | T_IMMUTABLE); sc->T3_2 = permanent_cons(sc->NIL, sc->T3_3, T_PAIR | T_IMMUTABLE); sc->T3_1 = permanent_cons(sc->NIL, sc->T3_2, T_PAIR | T_IMMUTABLE); sc->A4_4 = permanent_cons(sc->NIL, sc->NIL, T_PAIR | T_IMMUTABLE); sc->A4_3 = permanent_cons(sc->NIL, sc->A4_4, T_PAIR | T_IMMUTABLE); sc->A4_2 = permanent_cons(sc->NIL, sc->A4_3, T_PAIR | T_IMMUTABLE); sc->A4_1 = permanent_cons(sc->NIL, sc->A4_2, T_PAIR | T_IMMUTABLE); sc->A1_1 = sc->A4_4; sc->A2_1 = sc->A4_3; sc->A2_2 = sc->A4_4; sc->A3_1 = sc->A4_2; sc->A3_2 = sc->A4_3; sc->A3_3 = sc->A4_4; sc->safe_lists = (s7_pointer *)calloc(NUM_SAFE_LISTS, sizeof(s7_pointer)); for (i = 1; i < NUM_SAFE_LISTS; i++) sc->safe_lists[i] = permanent_list(sc, i); sc->input_port_stack = sc->NIL; sc->code = sc->NIL; sc->cur_code = sc->F; sc->args = sc->NIL; sc->value = sc->NIL; sc->v = sc->NIL; sc->w = sc->NIL; sc->x = sc->NIL; sc->y = sc->NIL; sc->z = sc->NIL; sc->temp1 = sc->NIL; sc->temp2 = sc->NIL; sc->temp3 = sc->NIL; sc->temp4 = sc->NIL; sc->temp5 = sc->NIL; sc->temp6 = sc->NIL; sc->temp7 = sc->NIL; sc->temp8 = sc->NIL; sc->temp9 = sc->NIL; sc->temp10 = sc->NIL; sc->begin_hook = NULL; sc->autoload_table = sc->NIL; sc->autoload_names = NULL; sc->autoload_names_sizes = NULL; sc->autoloaded_already = NULL; sc->autoload_names_loc = 0; sc->port_heap = NULL; sc->permanent_objects = NULL; sc->heap_size = INITIAL_HEAP_SIZE; if ((sc->heap_size % 32) != 0) sc->heap_size = 32 * (int)ceil((double)(sc->heap_size) / 32.0); sc->heap = (s7_pointer *)malloc(sc->heap_size * sizeof(s7_pointer)); sc->free_heap = (s7_cell **)malloc(sc->heap_size * sizeof(s7_cell *)); sc->free_heap_top = (s7_cell **)(sc->free_heap + INITIAL_HEAP_SIZE); sc->free_heap_trigger = (s7_cell **)(sc->free_heap + GC_TRIGGER_SIZE); sc->previous_free_heap_top = sc->free_heap_top; { s7_cell *cells; cells = (s7_cell *)calloc(INITIAL_HEAP_SIZE, sizeof(s7_cell)); for (i = 0; i < INITIAL_HEAP_SIZE; i++) { sc->heap[i] = &cells[i]; sc->free_heap[i] = sc->heap[i]; heap_location(sc->heap[i]) = i; i++; sc->heap[i] = &cells[i]; sc->free_heap[i] = sc->heap[i]; heap_location(sc->heap[i]) = i; } } /* this has to precede s7_make_* allocations */ sc->protected_objects_size = INITIAL_PROTECTED_OBJECTS_SIZE; sc->protected_objects_loc = 0; sc->protected_objects = s7_make_vector(sc, INITIAL_PROTECTED_OBJECTS_SIZE); sc->protected_accessors_size = INITIAL_PROTECTED_OBJECTS_SIZE; sc->protected_accessors_loc = 0; sc->protected_accessors = s7_make_vector(sc, INITIAL_PROTECTED_OBJECTS_SIZE); for (i = 0; i < INITIAL_PROTECTED_OBJECTS_SIZE; i++) { vector_element(sc->protected_objects, i) = sc->GC_NIL; vector_element(sc->protected_accessors, i) = sc->GC_NIL; } sc->stack = s7_make_vector(sc, INITIAL_STACK_SIZE); sc->stack_start = vector_elements(sc->stack); sc->stack_end = sc->stack_start; sc->stack_size = INITIAL_STACK_SIZE; sc->stack_resize_trigger = (s7_pointer *)(sc->stack_start + sc->stack_size / 2); set_type(sc->stack, T_STACK); sc->max_stack_size = (1 << 30); initialize_op_stack(sc); /* keep the symbol table out of the heap */ sc->symbol_table = (s7_pointer)calloc(1, sizeof(s7_cell)); set_type(sc->symbol_table, T_VECTOR); vector_length(sc->symbol_table) = SYMBOL_TABLE_SIZE; vector_elements(sc->symbol_table) = (s7_pointer *)malloc(SYMBOL_TABLE_SIZE * sizeof(s7_pointer)); vector_getter(sc->symbol_table) = default_vector_getter; vector_setter(sc->symbol_table) = default_vector_setter; s7_vector_fill(sc, sc->symbol_table, sc->NIL); unheap(sc->symbol_table); sc->tmp_strs = (s7_pointer *)malloc(2 * sizeof(s7_pointer)); for (i = 0; i < 2; i++) { s7_pointer p; p = alloc_pointer(); sc->tmp_strs[i] = p; unheap(p); set_type(p, T_STRING | T_SAFE_PROCEDURE); string_hash(p) = 0; string_needs_free(p) = false; string_length(p) = 0; string_value(p) = (char *)malloc(INITIAL_TMP_STR_SIZE * sizeof(char)); string_temp_true_length(p) = INITIAL_TMP_STR_SIZE; } sc->typnam = NULL; sc->typnam_len = 0; sc->help_arglist = NULL; sc->default_rationalize_error = 1.0e-12; sc->hash_table_float_epsilon = 1.0e-12; sc->morally_equal_float_epsilon = 1.0e-15; sc->default_hash_table_length = 8; sc->gensym_counter = 0; sc->capture_let_counter = 0; sc->f_class = 0; sc->add_class = 0; sc->equal_class = 0; sc->let_number = 0; sc->format_column = 0; sc->file_names = NULL; sc->file_names_size = 0; sc->file_names_top = -1; sc->no_values = 0; sc->s7_call_line = 0; sc->s7_call_file = NULL; sc->s7_call_name = NULL; sc->safety = 0; sc->print_length = 8; sc->baffle_ctr = 0; sc->syms_tag = 0; sc->CLASS_NAME = make_symbol(sc, "class-name"); sc->circle_info = NULL; sc->fdats = (format_data **)calloc(8, sizeof(format_data *)); sc->num_fdats = 8; sc->plist_1 = permanent_list(sc, 1); sc->plist_2 = permanent_list(sc, 2); sc->plist_3 = permanent_list(sc, 3); sc->elist_1 = permanent_list(sc, 1); sc->elist_2 = permanent_list(sc, 2); sc->elist_3 = permanent_list(sc, 3); sc->elist_4 = permanent_list(sc, 4); sc->elist_5 = permanent_list(sc, 5); sc->direct_str = s7_make_permanent_string(NULL); sc->undefined_identifier_warnings = false; sc->wrap_only = make_wrap_only(sc); sc->dox_slot_symbol = s7_make_symbol(sc, "(dox_slot)"); sc->rootlet = s7_make_vector(sc, ROOTLET_SIZE); set_type(sc->rootlet, T_LET); sc->rootlet_entries = 0; for (i = 0; i < ROOTLET_SIZE; i++) vector_element(sc->rootlet, i) = sc->NIL; sc->envir = sc->NIL; sc->shadow_rootlet = sc->NIL; if (!already_inited) { /* keep the small_ints out of the heap */ small_ints = (s7_pointer *)malloc((NUM_SMALL_INTS + 1) * sizeof(s7_pointer)); { s7_cell *cells; cells = (s7_cell *)calloc((NUM_SMALL_INTS + 1), sizeof(s7_cell)); for (i = 0; i <= NUM_SMALL_INTS; i++) { s7_pointer p; small_ints[i] = &cells[i]; p = small_ints[i]; typeflag(p) = T_IMMUTABLE | T_INTEGER; unheap(p); integer(p) = i; } } real_zero = make_permanent_real(0.0); real_one = make_permanent_real(1.0); real_NaN = make_permanent_real(NAN); real_infinity = make_permanent_real(INFINITY); real_minus_infinity = make_permanent_real(-INFINITY); real_pi = make_permanent_real(3.1415926535897932384626433832795029L); /* M_PI is not good enough for s7_double = long double */ arity_not_set = make_permanent_integer_unchecked(CLOSURE_ARITY_NOT_SET); max_arity = make_permanent_integer_unchecked(MAX_ARITY); minus_one = make_permanent_integer_unchecked(-1); minus_two = make_permanent_integer_unchecked(-2); /* prebuilt null string is tricky mainly because it overlaps #u8() */ /* keep the characters out of the heap */ chars = (s7_pointer *)malloc((NUM_CHARS + 1) * sizeof(s7_pointer)); chars[0] = sc->EOF_OBJECT; chars++; /* now chars[EOF] == chars[-1] == sc->EOF_OBJECT */ { s7_cell *cells; cells = (s7_cell *)calloc(NUM_CHARS, sizeof(s7_cell)); for (i = 0; i < NUM_CHARS; i++) { s7_pointer cp; unsigned char c; c = (unsigned char)i; cp = &cells[i]; typeflag(cp) = T_IMMUTABLE | T_CHARACTER; unheap(cp); character(cp) = c; upper_character(cp) = (unsigned char)toupper(i); is_char_alphabetic(cp) = (bool)isalpha(i); is_char_numeric(cp) = (bool)isdigit(i); is_char_whitespace(cp) = white_space[i]; is_char_uppercase(cp) = (((bool)isupper(i)) || ((i >= 192) && (i < 208))); is_char_lowercase(cp) = (bool)islower(i); chars[i] = cp; #define make_character_name(C, S) strncat((char *)(&(character_name(C))), S, character_name_length(C) = strlen(S)) switch (c) { case ' ': make_character_name(cp, "#\\space"); break; case '\n': make_character_name(cp, "#\\newline"); break; case '\r': make_character_name(cp, "#\\return"); break; case '\t': make_character_name(cp, "#\\tab"); break; case '\0': make_character_name(cp, "#\\null"); break; case (char)0x1b: make_character_name(cp, "#\\escape"); break; case (char)0x7f: make_character_name(cp, "#\\delete"); break; case (char)7: make_character_name(cp, "#\\alarm"); break; case (char)8: make_character_name(cp, "#\\backspace"); break; default: { #define P_SIZE 12 int len; if ((c < 32) || (c >= 127)) len = snprintf((char *)(&(character_name(cp))), P_SIZE, "#\\x%x", c); else len = snprintf((char *)(&(character_name(cp))), P_SIZE, "#\\%c", c); character_name_length(cp) = len; break; } } } } } #if WITH_COUNTS init_hashes(sc); #endif make_standard_ports(sc); sc->syn_docs = (s7_pointer *)calloc(OP_MAX_DEFINED, sizeof(s7_pointer)); #define QUOTE_HELP "(quote obj) returns obj unevaluated. 'obj is an abbreviation for (quote obj)." #define IF_HELP "(if expr true-stuff optional-false-stuff) evaluates expr, then if it is true, evaluates true-stuff; otherwise, \ if optional-false-stuff exists, it is evaluated." #define WHEN_HELP "(when expr ...) evaluates expr, and if it is true, evaluates each form in its body, returning the value of the last" #define UNLESS_HELP "(unless expr ...) evaluates expr, and if it is false, evaluates each form in its body, returning the value of the last" #define BEGIN_HELP "(begin ...) evaluates each form in its body, returning the value of the last one" #define SET_HELP "(set! variable value) sets the value of variable to value." #define LET_HELP "(let ((var val)...) ...) binds each variable to its initial value, then evaluates its body,\ returning the value of the last form. The let variables are local to it, and \ are not available for use until all have been initialized." #define LET_STAR_HELP "(let* ((var val)...) ...) binds each variable to its initial value, then evaluates its body, \ returning the value of the last form. The let* variables are local to it, and are available immediately." #define LETREC_HELP "(letrec ((var (lambda ...)))...) is like let, but var can refer to itself in its value \ (i.e. you can define local recursive functions)" #define LETREC_STAR_HELP "(letrec* ((var val))...) is like letrec, but successive bindings are handled as in let*" #define COND_HELP "(cond (expr clause...)...) is like if..then. Each expr is evaluated in order, and if one is not #f, \ the associated clauses are evaluated, whereupon cond returns." #define AND_HELP "(and expr expr ...) evaluates each of its arguments in order, quitting (and returning #f) \ as soon as one of them returns #f. If all are non-#f, it returns the last value." #define OR_HELP "(or expr expr ...) evaluates each of its argments in order, quitting as soon as one of them is not #f. \ If all are #f, or returns #f." #define CASE_HELP "(case val ((key...) clause...)...) looks for val in the various lists of keys, and if a \ match is found (via eqv?), the associated clauses are evaluated, and case returns." #define DO_HELP "(do (vars...) (loop control and return value) ...) is a do-loop." #define LAMBDA_HELP "(lambda args ...) returns a function." #define LAMBDA_STAR_HELP "(lambda* args ...) returns a function; the args list can have default values, \ the parameters themselves can be accessed via keywords." #define DEFINE_HELP "(define var val) assigns val to the variable (symbol) var. (define (func args) ...) is \ shorthand for (define func (lambda args ...))" #define DEFINE_STAR_HELP "(define* (func args) ...) defines a function with optional/keyword arguments." #define DEFINE_CONSTANT_HELP "(define-constant var val) defines var to be a constant (it can't be set or bound), with the value val." #define DEFINE_MACRO_HELP "(define-macro (mac args) ...) defines mac to be a macro." #define DEFINE_MACRO_STAR_HELP "(define-macro* (mac args) ...) defines mac to be a macro with optional/keyword arguments." #define DEFINE_EXPANSION_HELP "(define-expansion (mac args) ...) defines mac to be a read-time macro." #define DEFINE_BACRO_HELP "(define-bacro (mac args) ...) defines mac to be a bacro." #define DEFINE_BACRO_STAR_HELP "(define-bacro* (mac args) ...) defines mac to be a bacro with optional/keyword arguments." #define WITH_BAFFLE_HELP "(with-baffle ...) evaluates its body in a context that is safe from outside interference." #define MACROEXPAND_HELP "(macroexpand macro-call) returns the result of the expansion phase of evaluating the macro call." #define WITH_LET_HELP "(with-let env ...) evaluates its body in the environment env." sc->QUOTE = assign_syntax(sc, "quote", OP_QUOTE, small_int(1), small_int(1), QUOTE_HELP); sc->IF = assign_syntax(sc, "if", OP_IF, small_int(2), small_int(3), IF_HELP); sc->WHEN = assign_syntax(sc, "when", OP_WHEN, small_int(2), max_arity, WHEN_HELP); sc->UNLESS = assign_syntax(sc, "unless", OP_UNLESS, small_int(2), max_arity, UNLESS_HELP); sc->BEGIN = assign_syntax(sc, "begin", OP_BEGIN, small_int(0), max_arity, BEGIN_HELP); sc->SET = assign_syntax(sc, "set!", OP_SET, small_int(2), small_int(2), SET_HELP); sc->LET = assign_syntax(sc, "let", OP_LET, small_int(2), max_arity, LET_HELP); sc->LET_STAR = assign_syntax(sc, "let*", OP_LET_STAR, small_int(2), max_arity, LET_STAR_HELP); sc->LETREC = assign_syntax(sc, "letrec", OP_LETREC, small_int(2), max_arity, LETREC_HELP); sc->LETREC_STAR = assign_syntax(sc, "letrec*", OP_LETREC_STAR, small_int(2), max_arity, LETREC_STAR_HELP); sc->COND = assign_syntax(sc, "cond", OP_COND, small_int(1), max_arity, COND_HELP); sc->AND = assign_syntax(sc, "and", OP_AND, small_int(0), max_arity, AND_HELP); sc->OR = assign_syntax(sc, "or", OP_OR, small_int(0), max_arity, OR_HELP); sc->CASE = assign_syntax(sc, "case", OP_CASE, small_int(2), max_arity, CASE_HELP); sc->DO = assign_syntax(sc, "do", OP_DO, small_int(2), max_arity, DO_HELP); /* 2 because body can be null */ sc->LAMBDA = assign_syntax(sc, "lambda", OP_LAMBDA, small_int(2), max_arity, LAMBDA_HELP); sc->LAMBDA_STAR = assign_syntax(sc, "lambda*", OP_LAMBDA_STAR, small_int(2), max_arity, LAMBDA_STAR_HELP); sc->DEFINE = assign_syntax(sc, "define", OP_DEFINE, small_int(2), max_arity, DEFINE_HELP); sc->DEFINE_STAR = assign_syntax(sc, "define*", OP_DEFINE_STAR, small_int(2), max_arity, DEFINE_STAR_HELP); sc->DEFINE_CONSTANT = assign_syntax(sc, "define-constant", OP_DEFINE_CONSTANT, small_int(2), max_arity, DEFINE_CONSTANT_HELP); sc->DEFINE_MACRO = assign_syntax(sc, "define-macro", OP_DEFINE_MACRO, small_int(2), max_arity, DEFINE_MACRO_HELP); sc->DEFINE_MACRO_STAR = assign_syntax(sc, "define-macro*", OP_DEFINE_MACRO_STAR, small_int(2), max_arity, DEFINE_MACRO_STAR_HELP); sc->DEFINE_EXPANSION = assign_syntax(sc, "define-expansion",OP_DEFINE_EXPANSION, small_int(2), max_arity, DEFINE_EXPANSION_HELP); sc->DEFINE_BACRO = assign_syntax(sc, "define-bacro", OP_DEFINE_BACRO, small_int(2), max_arity, DEFINE_BACRO_HELP); sc->DEFINE_BACRO_STAR = assign_syntax(sc, "define-bacro*", OP_DEFINE_BACRO_STAR, small_int(2), max_arity, DEFINE_BACRO_STAR_HELP); sc->WITH_BAFFLE = assign_syntax(sc, "with-baffle", OP_WITH_BAFFLE, small_int(1), max_arity, WITH_BAFFLE_HELP); sc->MACROEXPAND = assign_syntax(sc, "macroexpand", OP_MACROEXPAND, small_int(1), small_int(1), MACROEXPAND_HELP); sc->WITH_LET = assign_syntax(sc, "with-let", OP_WITH_LET, small_int(1), max_arity, WITH_LET_HELP); set_immutable(sc->WITH_LET); #if WITH_OPTIMIZATION syntax_rp(slot_value(global_slot(sc->SET))) = set_rf; syntax_ip(slot_value(global_slot(sc->SET))) = set_if; syntax_pp(slot_value(global_slot(sc->SET))) = set_pf; syntax_rp(slot_value(global_slot(sc->IF))) = if_rf; syntax_pp(slot_value(global_slot(sc->IF))) = if_pf; syntax_pp(slot_value(global_slot(sc->OR))) = or_pf; syntax_pp(slot_value(global_slot(sc->AND))) = and_pf; syntax_pp(slot_value(global_slot(sc->QUOTE))) = quote_pf; #endif sc->QUOTE_UNCHECKED = assign_internal_syntax(sc, "quote", OP_QUOTE_UNCHECKED); sc->BEGIN_UNCHECKED = assign_internal_syntax(sc, "begin", OP_BEGIN_UNCHECKED); sc->WITH_BAFFLE_UNCHECKED = assign_internal_syntax(sc, "with-baffle", OP_WITH_BAFFLE_UNCHECKED); sc->LET_UNCHECKED = assign_internal_syntax(sc, "let", OP_LET_UNCHECKED); sc->LET_STAR_UNCHECKED = assign_internal_syntax(sc, "let*", OP_LET_STAR_UNCHECKED); sc->LETREC_UNCHECKED = assign_internal_syntax(sc, "letrec", OP_LETREC_UNCHECKED); sc->LETREC_STAR_UNCHECKED = assign_internal_syntax(sc, "letrec*", OP_LETREC_STAR_UNCHECKED); sc->LET_NO_VARS = assign_internal_syntax(sc, "let", OP_LET_NO_VARS); sc->LET_C = assign_internal_syntax(sc, "let", OP_LET_C); sc->LET_S = assign_internal_syntax(sc, "let", OP_LET_S); sc->LET_ALL_C = assign_internal_syntax(sc, "let", OP_LET_ALL_C); sc->LET_ALL_S = assign_internal_syntax(sc, "let", OP_LET_ALL_S); sc->LET_ALL_X = assign_internal_syntax(sc, "let", OP_LET_ALL_X); sc->LET_STAR_ALL_X = assign_internal_syntax(sc, "let*", OP_LET_STAR_ALL_X); sc->LET_opCq = assign_internal_syntax(sc, "let", OP_LET_opCq); sc->LET_opSSq = assign_internal_syntax(sc, "let", OP_LET_opSSq); sc->LET_opSq = assign_internal_syntax(sc, "let", OP_LET_opSq); sc->LET_opSq_P = assign_internal_syntax(sc, "let", OP_LET_opSq_P); sc->LET_ONE = assign_internal_syntax(sc, "let", OP_LET_ONE); sc->LET_Z = assign_internal_syntax(sc, "let", OP_LET_Z); sc->LET_ALL_opSq = assign_internal_syntax(sc, "let", OP_LET_ALL_opSq); sc->NAMED_LET_NO_VARS = assign_internal_syntax(sc, "let", OP_NAMED_LET_NO_VARS); sc->NAMED_LET = assign_internal_syntax(sc, "let", OP_NAMED_LET); sc->NAMED_LET_STAR = assign_internal_syntax(sc, "let*", OP_NAMED_LET_STAR); sc->LET_STAR2 = assign_internal_syntax(sc, "let*", OP_LET_STAR2); sc->WITH_LET_UNCHECKED = assign_internal_syntax(sc, "with-let", OP_WITH_LET_UNCHECKED); sc->WITH_LET_S = assign_internal_syntax(sc, "with-let", OP_WITH_LET_S); sc->CASE_UNCHECKED = assign_internal_syntax(sc, "case", OP_CASE_UNCHECKED); sc->CASE_SIMPLE = assign_internal_syntax(sc, "case", OP_CASE_SIMPLE); sc->CASE_SIMPLER = assign_internal_syntax(sc, "case", OP_CASE_SIMPLER); sc->CASE_SIMPLER_1 = assign_internal_syntax(sc, "case", OP_CASE_SIMPLER_1); sc->CASE_SIMPLER_SS = assign_internal_syntax(sc, "case", OP_CASE_SIMPLER_SS); sc->CASE_SIMPLEST = assign_internal_syntax(sc, "case", OP_CASE_SIMPLEST); sc->CASE_SIMPLEST_SS = assign_internal_syntax(sc, "case", OP_CASE_SIMPLEST_SS); sc->COND_UNCHECKED = assign_internal_syntax(sc, "cond", OP_COND_UNCHECKED); sc->COND_SIMPLE = assign_internal_syntax(sc, "cond", OP_COND_SIMPLE); sc->DO_UNCHECKED = assign_internal_syntax(sc, "do", OP_DO_UNCHECKED); sc->LAMBDA_UNCHECKED = assign_internal_syntax(sc, "lambda", OP_LAMBDA_UNCHECKED); sc->LAMBDA_STAR_UNCHECKED = assign_internal_syntax(sc, "lambda*", OP_LAMBDA_STAR_UNCHECKED); sc->DEFINE_UNCHECKED = assign_internal_syntax(sc, "define", OP_DEFINE_UNCHECKED); sc->DEFINE_FUNCHECKED = assign_internal_syntax(sc, "define", OP_DEFINE_FUNCHECKED); sc->DEFINE_STAR_UNCHECKED = assign_internal_syntax(sc, "define*", OP_DEFINE_STAR_UNCHECKED); sc->DEFINE_CONSTANT_UNCHECKED = assign_internal_syntax(sc, "define-constant", OP_DEFINE_CONSTANT_UNCHECKED); sc->SET_UNCHECKED = assign_internal_syntax(sc, "set!", OP_SET_UNCHECKED); sc->SET_SYMBOL_C = assign_internal_syntax(sc, "set!", OP_SET_SYMBOL_C); sc->SET_SYMBOL_S = assign_internal_syntax(sc, "set!", OP_SET_SYMBOL_S); sc->SET_SYMBOL_Q = assign_internal_syntax(sc, "set!", OP_SET_SYMBOL_Q); sc->SET_SYMBOL_opSq = assign_internal_syntax(sc, "set!", OP_SET_SYMBOL_opSq); sc->SET_SYMBOL_opSSq = assign_internal_syntax(sc, "set!", OP_SET_SYMBOL_opSSq); sc->SET_SYMBOL_opSSSq = assign_internal_syntax(sc, "set!", OP_SET_SYMBOL_opSSSq); sc->SET_SYMBOL_opCq = assign_internal_syntax(sc, "set!", OP_SET_SYMBOL_opCq); sc->SET_SYMBOL_P = assign_internal_syntax(sc, "set!", OP_SET_SYMBOL_P); sc->SET_SYMBOL_Z = assign_internal_syntax(sc, "set!", OP_SET_SYMBOL_Z); sc->SET_SYMBOL_A = assign_internal_syntax(sc, "set!", OP_SET_SYMBOL_A); sc->SET_NORMAL = assign_internal_syntax(sc, "set!", OP_SET_NORMAL); sc->SET_PWS = assign_internal_syntax(sc, "set!", OP_SET_PWS); sc->SET_PAIR = assign_internal_syntax(sc, "set!", OP_SET_PAIR); sc->SET_PAIR_P = assign_internal_syntax(sc, "set!", OP_SET_PAIR_P); sc->SET_PAIR_Z = assign_internal_syntax(sc, "set!", OP_SET_PAIR_Z); sc->SET_PAIR_A = assign_internal_syntax(sc, "set!", OP_SET_PAIR_A); sc->SET_PAIR_ZA = assign_internal_syntax(sc, "set!", OP_SET_PAIR_ZA); sc->SET_LET_S = assign_internal_syntax(sc, "set!", OP_SET_LET_S); sc->SET_LET_ALL_X = assign_internal_syntax(sc, "set!", OP_SET_LET_ALL_X); sc->SET_PAIR_C = assign_internal_syntax(sc, "set!", OP_SET_PAIR_C); sc->SET_PAIR_C_P = assign_internal_syntax(sc, "set!", OP_SET_PAIR_C_P); sc->INCREMENT_1 = assign_internal_syntax(sc, "set!", OP_INCREMENT_1); sc->INCREMENT_SS = assign_internal_syntax(sc, "set!", OP_INCREMENT_SS); sc->INCREMENT_SSS = assign_internal_syntax(sc, "set!", OP_INCREMENT_SSS); sc->INCREMENT_SZ = assign_internal_syntax(sc, "set!", OP_INCREMENT_SZ); sc->INCREMENT_SA = assign_internal_syntax(sc, "set!", OP_INCREMENT_SA); sc->INCREMENT_SAA = assign_internal_syntax(sc, "set!", OP_INCREMENT_SAA); sc->DECREMENT_1 = assign_internal_syntax(sc, "set!", OP_DECREMENT_1); sc->SET_CONS = assign_internal_syntax(sc, "set!", OP_SET_CONS); sc->AND_UNCHECKED = assign_internal_syntax(sc, "and", OP_AND_UNCHECKED); sc->AND_P = assign_internal_syntax(sc, "and", OP_AND_P); sc->AND_P2 = assign_internal_syntax(sc, "and", OP_AND_P2); sc->OR_UNCHECKED = assign_internal_syntax(sc, "or", OP_OR_UNCHECKED); sc->OR_P = assign_internal_syntax(sc, "or", OP_OR_P); sc->OR_P2 = assign_internal_syntax(sc, "or", OP_OR_P2); sc->IF_UNCHECKED = assign_internal_syntax(sc, "if", OP_IF_UNCHECKED); sc->IF_P_P = assign_internal_syntax(sc, "if", OP_IF_P_P); sc->IF_P_P_P = assign_internal_syntax(sc, "if", OP_IF_P_P_P); sc->IF_ANDP_P = assign_internal_syntax(sc, "if", OP_IF_ANDP_P); sc->IF_ANDP_P_P = assign_internal_syntax(sc, "if", OP_IF_ANDP_P_P); sc->IF_ORP_P = assign_internal_syntax(sc, "if", OP_IF_ORP_P); sc->IF_ORP_P_P = assign_internal_syntax(sc, "if", OP_IF_ORP_P_P); sc->IF_S_P = assign_internal_syntax(sc, "if", OP_IF_S_P); sc->IF_S_P_P = assign_internal_syntax(sc, "if", OP_IF_S_P_P); sc->IF_P_FEED = assign_internal_syntax(sc, "cond", OP_IF_P_FEED); sc->COND_ALL_X = assign_internal_syntax(sc, "cond", OP_COND_ALL_X); sc->COND_ALL_X_2 = assign_internal_syntax(sc, "cond", OP_COND_ALL_X_2); sc->COND_S = assign_internal_syntax(sc, "cond", OP_COND_S); sc->IF_Z_P = assign_internal_syntax(sc, "if", OP_IF_Z_P); sc->IF_Z_P_P = assign_internal_syntax(sc, "if", OP_IF_Z_P_P); sc->IF_A_P = assign_internal_syntax(sc, "if", OP_IF_A_P); sc->IF_A_P_P = assign_internal_syntax(sc, "if", OP_IF_A_P_P); sc->IF_CC_P = assign_internal_syntax(sc, "if", OP_IF_CC_P); sc->IF_CC_P_P = assign_internal_syntax(sc, "if", OP_IF_CC_P_P); sc->IF_CS_P = assign_internal_syntax(sc, "if", OP_IF_CS_P); sc->IF_CS_P_P = assign_internal_syntax(sc, "if", OP_IF_CS_P_P); sc->IF_CSQ_P = assign_internal_syntax(sc, "if", OP_IF_CSQ_P); sc->IF_CSQ_P_P = assign_internal_syntax(sc, "if", OP_IF_CSQ_P_P); sc->IF_CSS_P = assign_internal_syntax(sc, "if", OP_IF_CSS_P); sc->IF_CSS_P_P = assign_internal_syntax(sc, "if", OP_IF_CSS_P_P); sc->IF_CSC_P = assign_internal_syntax(sc, "if", OP_IF_CSC_P); sc->IF_CSC_P_P = assign_internal_syntax(sc, "if", OP_IF_CSC_P_P); sc->IF_S_opCq_P = assign_internal_syntax(sc, "if", OP_IF_S_opCq_P); sc->IF_S_opCq_P_P = assign_internal_syntax(sc, "if", OP_IF_S_opCq_P_P); sc->IF_opSSq_P = assign_internal_syntax(sc, "if", OP_IF_opSSq_P); sc->IF_opSSq_P_P = assign_internal_syntax(sc, "if", OP_IF_opSSq_P_P); sc->IF_IS_PAIR_P = assign_internal_syntax(sc, "if", OP_IF_IS_PAIR_P); sc->IF_IS_PAIR_P_P = assign_internal_syntax(sc, "if", OP_IF_IS_PAIR_P_P); sc->IF_IS_SYMBOL_P = assign_internal_syntax(sc, "if", OP_IF_IS_SYMBOL_P); sc->IF_IS_SYMBOL_P_P = assign_internal_syntax(sc, "if", OP_IF_IS_SYMBOL_P_P); sc->IF_NOT_S_P = assign_internal_syntax(sc, "if", OP_IF_NOT_S_P); sc->IF_NOT_S_P_P = assign_internal_syntax(sc, "if", OP_IF_NOT_S_P_P); sc->IF_AND2_P = assign_internal_syntax(sc, "if", OP_IF_AND2_P); sc->IF_AND2_P_P = assign_internal_syntax(sc, "if", OP_IF_AND2_P_P); sc->WHEN_S = assign_internal_syntax(sc, "when", OP_WHEN_S); sc->UNLESS_S = assign_internal_syntax(sc, "unless", OP_UNLESS_S); sc->WHEN_UNCHECKED = assign_internal_syntax(sc, "when", OP_WHEN_UNCHECKED); sc->UNLESS_UNCHECKED = assign_internal_syntax(sc, "unless", OP_UNLESS_UNCHECKED); sc->DOTIMES_P = assign_internal_syntax(sc, "do", OP_DOTIMES_P); sc->SIMPLE_DO = assign_internal_syntax(sc, "do", OP_SIMPLE_DO); sc->SIMPLE_DO_P = assign_internal_syntax(sc, "do", OP_SIMPLE_DO_P); sc->SIMPLE_DO_A = assign_internal_syntax(sc, "do", OP_SIMPLE_DO_A); sc->SIMPLE_DO_E = assign_internal_syntax(sc, "do", OP_SIMPLE_DO_E); sc->SAFE_DOTIMES = assign_internal_syntax(sc, "do", OP_SAFE_DOTIMES); sc->SAFE_DO = assign_internal_syntax(sc, "do", OP_SAFE_DO); sc->DOX = assign_internal_syntax(sc, "do", OP_DOX); sc->DOCUMENTATION = make_symbol(sc, "documentation"); sc->SIGNATURE = make_symbol(sc, "signature"); #if WITH_IMMUTABLE_UNQUOTE /* this code solves the various unquote redefinition troubles * if "," -> "(unquote...)" in the reader, (let (, (lambda (x) (+ x 1))) ,,,,1) -> 5 * in s7, this requires a quote: (let (, (lambda (x) (+ x 1))) ,,,,'1) */ sc->UNQUOTE = make_symbol(sc, ","); set_immutable(sc->UNQUOTE); #else sc->UNQUOTE = make_symbol(sc, "unquote"); #endif sc->FEED_TO = make_symbol(sc, "=>"); sc->BAFFLE = make_symbol(sc, "(baffle)"); sc->BODY = make_symbol(sc, "body"); sc->ERROR = make_symbol(sc, "error"); sc->READ_ERROR = make_symbol(sc, "read-error"); sc->STRING_READ_ERROR = make_symbol(sc, "string-read-error"); sc->SYNTAX_ERROR = make_symbol(sc, "syntax-error"); sc->WRONG_TYPE_ARG = make_symbol(sc, "wrong-type-arg"); sc->WRONG_NUMBER_OF_ARGS = make_symbol(sc, "wrong-number-of-args"); sc->FORMAT_ERROR = make_symbol(sc, "format-error"); sc->OUT_OF_RANGE = make_symbol(sc, "out-of-range"); sc->NO_CATCH = make_symbol(sc, "no-catch"); sc->IO_ERROR = make_symbol(sc, "io-error"); sc->INVALID_ESCAPE_FUNCTION = make_symbol(sc, "invalid-escape-function"); sc->BAFFLED = make_symbol(sc, "baffled!"); sc->KEY_ALLOW_OTHER_KEYS = s7_make_keyword(sc, "allow-other-keys"); sc->KEY_REST = s7_make_keyword(sc, "rest"); sc->KEY_READABLE = s7_make_keyword(sc, "readable"); sc->__FUNC__ = make_symbol(sc, "__func__"); s7_make_slot(sc, sc->NIL, sc->else_symbol = make_symbol(sc, "else"), sc->ELSE); sc->owlet = init_owlet(sc); sc->wrong_type_arg_info = permanent_list(sc, 6); car(sc->wrong_type_arg_info) = s7_make_permanent_string("~A argument ~D, ~S, is ~A but should be ~A"); sc->simple_wrong_type_arg_info = permanent_list(sc, 5); car(sc->simple_wrong_type_arg_info) = s7_make_permanent_string("~A argument, ~S, is ~A but should be ~A"); sc->out_of_range_info = permanent_list(sc, 5); car(sc->out_of_range_info) = s7_make_permanent_string("~A argument ~D, ~S, is out of range (~A)"); sc->simple_out_of_range_info = permanent_list(sc, 4); car(sc->simple_out_of_range_info) = s7_make_permanent_string("~A argument, ~S, is out of range (~A)"); sc->TOO_MANY_ARGUMENTS = s7_make_permanent_string("~A: too many arguments: ~A"); sc->NOT_ENOUGH_ARGUMENTS = s7_make_permanent_string("~A: not enough arguments: ~A"); sc->DIVISION_BY_ZERO_ERROR = s7_make_permanent_string("~A: division by zero, ~S"); sc->DIVISION_BY_ZERO = make_symbol(sc, "division-by-zero"); if (!already_inited) init_car_a_list(); for (i = 0; i < NUM_TYPES; i++) { const char *str; str = type_name_from_type(sc, i, INDEFINITE_ARTICLE); if (str) prepackaged_type_names[i] = s7_make_permanent_string(str); else prepackaged_type_names[i] = sc->F; } /* unset built-ins: T_STACK (can't happen), T_C_OBJECT (want actual name), T_INPUT|OUTPUT_PORT (want string|file|etc included) */ sc->gc_off = false; #define defun(Scheme_Name, C_Name, Req, Opt, Rst) s7_define_typed_function(sc, Scheme_Name, g_ ## C_Name, Req, Opt, Rst, H_ ## C_Name, Q_ ## C_Name) #define unsafe_defun(Scheme_Name, C_Name, Req, Opt, Rst) s7_define_unsafe_typed_function(sc, Scheme_Name, g_ ## C_Name, Req, Opt, Rst, H_ ## C_Name, Q_ ## C_Name) /* we need the sc->IS_* symbols first for the procedure signature lists */ sc->IS_BOOLEAN = make_symbol(sc, "boolean?"); pl_bt = s7_make_signature(sc, 2, sc->IS_BOOLEAN, sc->T); sc->IS_SYMBOL = defun("symbol?", is_symbol, 1, 0, false); sc->IS_GENSYM = defun("gensym?", is_gensym, 1, 0, false); sc->IS_KEYWORD = defun("keyword?", is_keyword, 1, 0, false); sc->IS_LET = defun("let?", is_let, 1, 0, false); sc->IS_OPENLET = defun("openlet?", is_openlet, 1, 0, false); sc->IS_ITERATOR = defun("iterator?", is_iterator, 1, 0, false); sc->IS_CONSTANT = defun("constant?", is_constant, 1, 0, false); sc->IS_MACRO = defun("macro?", is_macro, 1, 0, false); sc->IS_C_POINTER = defun("c-pointer?", is_c_pointer, 1, 0, false); sc->IS_C_OBJECT = defun("c-object?", is_c_object, 1, 0, false); sc->IS_INPUT_PORT = defun("input-port?", is_input_port, 1, 0, false); sc->IS_OUTPUT_PORT = defun("output-port?", is_output_port, 1, 0, false); sc->IS_EOF_OBJECT = defun("eof-object?", is_eof_object, 1, 0, false); sc->IS_INTEGER = defun("integer?", is_integer, 1, 0, false); sc->IS_NUMBER = defun("number?", is_number, 1, 0, false); sc->IS_REAL = defun("real?", is_real, 1, 0, false); sc->IS_COMPLEX = defun("complex?", is_complex, 1, 0, false); sc->IS_RATIONAL = defun("rational?", is_rational, 1, 0, false); sc->IS_RANDOM_STATE = defun("random-state?", is_random_state, 1, 0, false); sc->IS_CHAR = defun("char?", is_char, 1, 0, false); sc->IS_STRING = defun("string?", is_string, 1, 0, false); sc->IS_LIST = defun("list?", is_list, 1, 0, false); sc->IS_PAIR = defun("pair?", is_pair, 1, 0, false); sc->IS_VECTOR = defun("vector?", is_vector, 1, 0, false); sc->IS_FLOAT_VECTOR = defun("float-vector?", is_float_vector, 1, 0, false); sc->IS_INT_VECTOR = defun("int-vector?", is_int_vector, 1, 0, false); sc->IS_BYTE_VECTOR = defun("byte-vector?", is_byte_vector, 1, 0, false); sc->IS_HASH_TABLE = defun("hash-table?", is_hash_table, 1, 0, false); sc->IS_CONTINUATION = defun("continuation?", is_continuation, 1, 0, false); sc->IS_PROCEDURE = defun("procedure?", is_procedure, 1, 0, false); sc->IS_DILAMBDA = defun("dilambda?", is_dilambda, 1, 0, false); /* set above */ defun("boolean?", is_boolean, 1, 0, false); sc->IS_FLOAT = defun("float?", is_float, 1, 0, false); sc->IS_PROPER_LIST = defun("proper-list?", is_proper_list, 1, 0, false); sc->IS_SEQUENCE = defun("sequence?", is_sequence, 1, 0, false); sc->IS_NULL = defun("null?", is_null, 1, 0, false); sc->IS_INTEGER_OR_REAL_AT_END = s7_define_function(sc, "integer:real?", g_is_integer_or_real_at_end, 1, 0, false, "internal signature helper"); sc->IS_INTEGER_OR_ANY_AT_END = s7_define_function(sc, "integer:any?", g_is_integer_or_any_at_end, 1, 0, false, "internal signature helper"); pl_p = s7_make_signature(sc, 2, sc->T, sc->IS_PAIR); #if (!WITH_PURE_S7) pl_tp = s7_make_signature(sc, 3, sc->T, sc->T, sc->IS_PAIR); #endif pl_bc = s7_make_signature(sc, 2, sc->IS_BOOLEAN, sc->IS_CHAR); pl_bn = s7_make_signature(sc, 2, sc->IS_BOOLEAN, sc->IS_NUMBER); pl_sf = s7_make_signature(sc, 3, sc->T, sc->IS_STRING, sc->IS_PROCEDURE); pcl_bt = s7_make_circular_signature(sc, 1, 2, sc->IS_BOOLEAN, sc->T); pcl_bc = s7_make_circular_signature(sc, 1, 2, sc->IS_BOOLEAN, sc->IS_CHAR); pcl_bs = s7_make_circular_signature(sc, 1, 2, sc->IS_BOOLEAN, sc->IS_STRING); pcl_i = s7_make_circular_signature(sc, 0, 1, sc->IS_INTEGER); pcl_t = s7_make_circular_signature(sc, 0, 1, sc->T); pcl_r = s7_make_circular_signature(sc, 0, 1, sc->IS_REAL); pcl_f = s7_make_circular_signature(sc, 0, 1, sc->IS_RATIONAL); pcl_n = s7_make_circular_signature(sc, 0, 1, sc->IS_NUMBER); pcl_s = s7_make_circular_signature(sc, 0, 1, sc->IS_STRING); pcl_v = s7_make_circular_signature(sc, 0, 1, sc->IS_VECTOR); pcl_c = s7_make_circular_signature(sc, 0, 1, sc->IS_CHAR); sc->VALUES = make_symbol(sc, "values"); sc->GENSYM = defun("gensym", gensym, 0, 1, false); defun("symbol-table", symbol_table, 0, 0, false); sc->SYMBOL_TO_STRING = defun("symbol->string", symbol_to_string, 1, 0, false); sc->STRING_TO_SYMBOL = defun("string->symbol", string_to_symbol, 1, 0, false); sc->SYMBOL = defun("symbol", symbol, 1, 0, false); sc->SYMBOL_TO_VALUE = defun("symbol->value", symbol_to_value, 1, 1, false); sc->SYMBOL_TO_DYNAMIC_VALUE = defun("symbol->dynamic-value", symbol_to_dynamic_value, 1, 0, false); s7_typed_dilambda(sc, "symbol-access", g_symbol_access, 1, 1, g_symbol_set_access, 2, 1, H_symbol_access, Q_symbol_access, NULL); sc->SYMBOL_ACCESS = make_symbol(sc, "symbol-access"); sc->MAKE_KEYWORD = defun("make-keyword", make_keyword, 1, 0, false); sc->SYMBOL_TO_KEYWORD = defun("symbol->keyword", symbol_to_keyword, 1, 0, false); sc->KEYWORD_TO_SYMBOL = defun("keyword->symbol", keyword_to_symbol, 1, 0, false); sc->OUTLET = defun("outlet", outlet, 1, 0, false); sc->ROOTLET = defun("rootlet", rootlet, 0, 0, false); sc->CURLET = defun("curlet", curlet, 0, 0, false); sc->UNLET = defun("unlet", unlet, 0, 0, false); set_immutable(sc->UNLET); sc->SUBLET = defun("sublet", sublet, 1, 0, true); sc->VARLET = unsafe_defun("varlet", varlet, 1, 0, true); sc->CUTLET = unsafe_defun("cutlet", cutlet, 1, 0, true); sc->INLET = defun("inlet", inlet, 0, 0, true); sc->OWLET = defun("owlet", owlet, 0, 0, false); sc->COVERLET = defun("coverlet", coverlet, 1, 0, false); sc->OPENLET = defun("openlet", openlet, 1, 0, false); sc->LET_REF = defun("let-ref", let_ref, 2, 0, false); sc->LET_SET = defun("let-set!", let_set, 3, 0, false); sc->LET_REF_FALLBACK = make_symbol(sc, "let-ref-fallback"); sc->LET_SET_FALLBACK = make_symbol(sc, "let-set!-fallback"); sc->MAKE_ITERATOR = defun("make-iterator", make_iterator, 1, 1, false); sc->ITERATE = defun("iterate", iterate, 1, 0, false); sc->ITERATOR_SEQUENCE = defun("iterator-sequence", iterator_sequence, 1, 0, false); sc->ITERATOR_IS_AT_END = defun("iterator-at-end?", iterator_is_at_end, 1, 0, false); sc->IS_PROVIDED = defun("provided?", is_provided, 1, 0, false); sc->PROVIDE = defun("provide", provide, 1, 0, false); sc->IS_DEFINED = defun("defined?", is_defined, 1, 2, false); sc->C_POINTER = defun("c-pointer", c_pointer, 1, 0, false); sc->PORT_LINE_NUMBER = defun("port-line-number", port_line_number, 0, 1, false); sc->PORT_FILENAME = defun("port-filename", port_filename, 0, 1, false); sc->PAIR_LINE_NUMBER = defun("pair-line-number", pair_line_number, 1, 0, false); sc->IS_PORT_CLOSED = defun("port-closed?", is_port_closed, 1, 0, false); sc->CURRENT_INPUT_PORT = defun("current-input-port", current_input_port, 0, 0, false); sc->CURRENT_OUTPUT_PORT = defun("current-output-port", current_output_port, 0, 0, false); sc->CURRENT_ERROR_PORT = defun("current-error-port", current_error_port, 0, 0, false); defun("set-current-error-port", set_current_error_port, 1, 0, false); #if (!WITH_PURE_S7) sc->LET_TO_LIST = defun("let->list", let_to_list, 1, 0, false); defun("set-current-input-port", set_current_input_port, 1, 0, false); defun("set-current-output-port", set_current_output_port, 1, 0, false); sc->IS_CHAR_READY = defun("char-ready?", is_char_ready, 0, 1, false); /* the least-used scheme function */ #endif sc->CLOSE_INPUT_PORT = defun("close-input-port", close_input_port, 1, 0, false); sc->CLOSE_OUTPUT_PORT = defun("close-output-port", close_output_port, 1, 0, false); sc->FLUSH_OUTPUT_PORT = defun("flush-output-port", flush_output_port, 0, 1, false); sc->OPEN_INPUT_FILE = defun("open-input-file", open_input_file, 1, 1, false); sc->OPEN_OUTPUT_FILE = defun("open-output-file", open_output_file, 1, 1, false); sc->OPEN_INPUT_STRING = defun("open-input-string", open_input_string, 1, 0, false); defun("open-output-string", open_output_string, 0, 0, false); sc->GET_OUTPUT_STRING = defun("get-output-string", get_output_string, 1, 1, false); sc->NEWLINE = defun("newline", newline, 0, 1, false); sc->WRITE = defun("write", write, 1, 1, false); sc->DISPLAY = defun("display", display, 1, 1, false); sc->READ_CHAR = defun("read-char", read_char, 0, 1, false); sc->PEEK_CHAR = defun("peek-char", peek_char, 0, 1, false); sc->WRITE_CHAR = defun("write-char", write_char, 1, 1, false); sc->WRITE_STRING = defun("write-string", write_string, 1, 3, false); sc->READ_BYTE = defun("read-byte", read_byte, 0, 1, false); sc->WRITE_BYTE = defun("write-byte", write_byte, 1, 1, false); sc->READ_LINE = defun("read-line", read_line, 0, 2, false); sc->READ_STRING = defun("read-string", read_string, 1, 1, false); sc->READ = unsafe_defun("read", read, 0, 1, false); /* read can't be safe because it messes with the stack, expecting to be all by itself in the call sequence (not embedded in OP_SAFE_C_opSq for example) */ sc->CALL_WITH_INPUT_STRING = unsafe_defun("call-with-input-string", call_with_input_string, 2, 0, false); sc->CALL_WITH_INPUT_FILE = unsafe_defun("call-with-input-file", call_with_input_file, 2, 0, false); sc->WITH_INPUT_FROM_STRING = unsafe_defun("with-input-from-string", with_input_from_string, 2, 0, false); sc->WITH_INPUT_FROM_FILE = unsafe_defun("with-input-from-file", with_input_from_file, 2, 0, false); sc->CALL_WITH_OUTPUT_STRING = unsafe_defun("call-with-output-string", call_with_output_string, 1, 0, false); sc->CALL_WITH_OUTPUT_FILE = unsafe_defun("call-with-output-file", call_with_output_file, 2, 0, false); sc->WITH_OUTPUT_TO_STRING = unsafe_defun("with-output-to-string", with_output_to_string, 1, 0, false); sc->WITH_OUTPUT_TO_FILE = unsafe_defun("with-output-to-file", with_output_to_file, 2, 0, false); #if WITH_SYSTEM_EXTRAS sc->IS_DIRECTORY = defun("directory?", is_directory, 1, 0, false); sc->FILE_EXISTS = defun("file-exists?", file_exists, 1, 0, false); sc->DELETE_FILE = defun("delete-file", delete_file, 1, 0, false); sc->GETENV = defun("getenv", getenv, 1, 0, false); sc->SYSTEM = defun("system", system, 1, 1, false); #ifndef _MSC_VER sc->DIRECTORY_TO_LIST = defun("directory->list", directory_to_list, 1, 0, false); sc->FILE_MTIME = defun("file-mtime", file_mtime, 1, 0, false); #endif #endif sc->REAL_PART = defun("real-part", real_part, 1, 0, false); sc->IMAG_PART = defun("imag-part", imag_part, 1, 0, false); sc->NUMERATOR = defun("numerator", numerator, 1, 0, false); sc->DENOMINATOR = defun("denominator", denominator, 1, 0, false); sc->IS_EVEN = defun("even?", is_even, 1, 0, false); sc->IS_ODD = defun("odd?", is_odd, 1, 0, false); sc->IS_ZERO = defun("zero?", is_zero, 1, 0, false); sc->IS_POSITIVE = defun("positive?", is_positive, 1, 0, false); sc->IS_NEGATIVE = defun("negative?", is_negative, 1, 0, false); sc->IS_INFINITE = defun("infinite?", is_infinite, 1, 0, false); sc->IS_NAN = defun("nan?", is_nan, 1, 0, false); #if (!WITH_GMP) sc->COMPLEX = defun("complex", complex, 2, 0, false); sc->MAGNITUDE = defun("magnitude", magnitude, 1, 0, false); sc->ANGLE = defun("angle", angle, 1, 0, false); sc->RATIONALIZE = defun("rationalize", rationalize, 1, 1, false); sc->ABS = defun("abs", abs, 1, 0, false); sc->EXP = defun("exp", exp, 1, 0, false); sc->LOG = defun("log", log, 1, 1, false); sc->SIN = defun("sin", sin, 1, 0, false); sc->COS = defun("cos", cos, 1, 0, false); sc->TAN = defun("tan", tan, 1, 0, false); sc->ASIN = defun("asin", asin, 1, 0, false); sc->ACOS = defun("acos", acos, 1, 0, false); sc->ATAN = defun("atan", atan, 1, 1, false); sc->SINH = defun("sinh", sinh, 1, 0, false); sc->COSH = defun("cosh", cosh, 1, 0, false); sc->TANH = defun("tanh", tanh, 1, 0, false); sc->ASINH = defun("asinh", asinh, 1, 0, false); sc->ACOSH = defun("acosh", acosh, 1, 0, false); sc->ATANH = defun("atanh", atanh, 1, 0, false); sc->SQRT = defun("sqrt", sqrt, 1, 0, false); sc->EXPT = defun("expt", expt, 2, 0, false); sc->FLOOR = defun("floor", floor, 1, 0, false); sc->CEILING = defun("ceiling", ceiling, 1, 0, false); sc->TRUNCATE = defun("truncate", truncate, 1, 0, false); sc->ROUND = defun("round", round, 1, 0, false); sc->LCM = defun("lcm", lcm, 0, 0, true); sc->GCD = defun("gcd", gcd, 0, 0, true); sc->ADD = defun("+", add, 0, 0, true); sc->SUBTRACT = defun("-", subtract, 1, 0, true); sc->MULTIPLY = defun("*", multiply, 0, 0, true); sc->DIVIDE = defun("/", divide, 1, 0, true); sc->MAX = defun("max", max, 1, 0, true); sc->MIN = defun("min", min, 1, 0, true); sc->QUOTIENT = defun("quotient", quotient, 2, 0, false); sc->REMAINDER = defun("remainder", remainder, 2, 0, false); sc->MODULO = defun("modulo", modulo, 2, 0, false); sc->EQ = defun("=", equal, 2, 0, true); sc->LT = defun("<", less, 2, 0, true); sc->GT = defun(">", greater, 2, 0, true); sc->LEQ = defun("<=", less_or_equal, 2, 0, true); sc->GEQ = defun(">=", greater_or_equal, 2, 0, true); sc->LOGIOR = defun("logior", logior, 0, 0, true); sc->LOGXOR = defun("logxor", logxor, 0, 0, true); sc->LOGAND = defun("logand", logand, 0, 0, true); sc->LOGNOT = defun("lognot", lognot, 1, 0, false); sc->ASH = defun("ash", ash, 2, 0, false); sc->RANDOM_STATE = defun("random-state", random_state, 1, 1, false); sc->RANDOM = defun("random", random, 1, 1, false); #if (!WITH_PURE_S7) sc->INEXACT_TO_EXACT = defun("inexact->exact", inexact_to_exact, 1, 0, false); sc->EXACT_TO_INEXACT = defun("exact->inexact", exact_to_inexact, 1, 0, false); sc->INTEGER_LENGTH = defun("integer-length", integer_length, 1, 0, false); sc->MAKE_POLAR = defun("make-polar", make_polar, 2, 0, false); sc->MAKE_RECTANGULAR = defun("make-rectangular", complex, 2, 0, false); #endif #endif /* !gmp */ sc->LOGBIT = defun("logbit?", logbit, 2, 0, false); sc->INTEGER_DECODE_FLOAT = defun("integer-decode-float", integer_decode_float, 1, 0, false); #if (!WITH_PURE_S7) sc->IS_EXACT = defun("exact?", is_exact, 1, 0, false); sc->IS_INEXACT = defun("inexact?", is_inexact, 1, 0, false); #endif sc->RANDOM_STATE_TO_LIST = defun("random-state->list", random_state_to_list, 0, 1, false); sc->NUMBER_TO_STRING = defun("number->string", number_to_string, 1, 1, false); sc->STRING_TO_NUMBER = defun("string->number", string_to_number, 1, 1, false); sc->CHAR_UPCASE = defun("char-upcase", char_upcase, 1, 0, false); sc->CHAR_DOWNCASE = defun("char-downcase", char_downcase, 1, 0, false); sc->CHAR_TO_INTEGER = defun("char->integer", char_to_integer, 1, 0, false); sc->INTEGER_TO_CHAR = defun("integer->char", integer_to_char, 1, 0, false); sc->IS_CHAR_UPPER_CASE = defun("char-upper-case?", is_char_upper_case, 1, 0, false); sc->IS_CHAR_LOWER_CASE = defun("char-lower-case?", is_char_lower_case, 1, 0, false); sc->IS_CHAR_ALPHABETIC = defun("char-alphabetic?", is_char_alphabetic, 1, 0, false); sc->IS_CHAR_NUMERIC = defun("char-numeric?", is_char_numeric, 1, 0, false); sc->IS_CHAR_WHITESPACE = defun("char-whitespace?", is_char_whitespace, 1, 0, false); sc->CHAR_EQ = defun("char=?", chars_are_equal, 2, 0, true); sc->CHAR_LT = defun("charCHAR_GT = defun("char>?", chars_are_greater, 2, 0, true); sc->CHAR_LEQ = defun("char<=?", chars_are_leq, 2, 0, true); sc->CHAR_GEQ = defun("char>=?", chars_are_geq, 2, 0, true); sc->CHAR_POSITION = defun("char-position", char_position, 2, 1, false); sc->STRING_POSITION = defun("string-position", string_position, 2, 1, false); sc->MAKE_STRING = defun("make-string", make_string, 1, 1, false); sc->STRING_REF = defun("string-ref", string_ref, 2, 0, false); sc->STRING_SET = defun("string-set!", string_set, 3, 0, false); sc->STRING_EQ = defun("string=?", strings_are_equal, 2, 0, true); sc->STRING_LT = defun("stringSTRING_GT = defun("string>?", strings_are_greater, 2, 0, true); sc->STRING_LEQ = defun("string<=?", strings_are_leq, 2, 0, true); sc->STRING_GEQ = defun("string>=?", strings_are_geq, 2, 0, true); #if (!WITH_PURE_S7) sc->CHAR_CI_EQ = defun("char-ci=?", chars_are_ci_equal, 2, 0, true); sc->CHAR_CI_LT = defun("char-ciCHAR_CI_GT = defun("char-ci>?", chars_are_ci_greater, 2, 0, true); sc->CHAR_CI_LEQ = defun("char-ci<=?", chars_are_ci_leq, 2, 0, true); sc->CHAR_CI_GEQ = defun("char-ci>=?", chars_are_ci_geq, 2, 0, true); sc->STRING_CI_EQ = defun("string-ci=?", strings_are_ci_equal, 2, 0, true); sc->STRING_CI_LT = defun("string-ciSTRING_CI_GT = defun("string-ci>?", strings_are_ci_greater, 2, 0, true); sc->STRING_CI_LEQ = defun("string-ci<=?", strings_are_ci_leq, 2, 0, true); sc->STRING_CI_GEQ = defun("string-ci>=?", strings_are_ci_geq, 2, 0, true); sc->STRING_COPY = defun("string-copy", string_copy, 1, 0, false); sc->STRING_FILL = defun("string-fill!", string_fill, 2, 2, false); sc->LIST_TO_STRING = defun("list->string", list_to_string, 1, 0, false); sc->STRING_LENGTH = defun("string-length", string_length, 1, 0, false); sc->STRING_TO_LIST = defun("string->list", string_to_list, 1, 2, false); #endif sc->STRING_DOWNCASE = defun("string-downcase", string_downcase, 1, 0, false); sc->STRING_UPCASE = defun("string-upcase", string_upcase, 1, 0, false); sc->STRING_APPEND = defun("string-append", string_append, 0, 0, true); sc->SUBSTRING = defun("substring", substring, 2, 1, false); sc->STRING = defun("string", string, 0, 0, true); sc->OBJECT_TO_STRING = defun("object->string", object_to_string, 1, 1, false); sc->FORMAT = defun("format", format, 1, 0, true); /* this was unsafe, but was that due to the (ill-advised) use of temp_call_2 in the arg lists? */ sc->CONS = defun("cons", cons, 2, 0, false); sc->CAR = defun("car", car, 1, 0, false); sc->CDR = defun("cdr", cdr, 1, 0, false); sc->SET_CAR = defun("set-car!", set_car, 2, 0, false); sc->SET_CDR = unsafe_defun("set-cdr!", set_cdr, 2, 0, false); sc->CAAR = defun("caar", caar, 1, 0, false); sc->CADR = defun("cadr", cadr, 1, 0, false); sc->CDAR = defun("cdar", cdar, 1, 0, false); sc->CDDR = defun("cddr", cddr, 1, 0, false); sc->CAAAR = defun("caaar", caaar, 1, 0, false); sc->CAADR = defun("caadr", caadr, 1, 0, false); sc->CADAR = defun("cadar", cadar, 1, 0, false); sc->CDAAR = defun("cdaar", cdaar, 1, 0, false); sc->CADDR = defun("caddr", caddr, 1, 0, false); sc->CDDDR = defun("cdddr", cdddr, 1, 0, false); sc->CDADR = defun("cdadr", cdadr, 1, 0, false); sc->CDDAR = defun("cddar", cddar, 1, 0, false); sc->CAAAAR = defun("caaaar", caaaar, 1, 0, false); sc->CAAADR = defun("caaadr", caaadr, 1, 0, false); sc->CAADAR = defun("caadar", caadar, 1, 0, false); sc->CADAAR = defun("cadaar", cadaar, 1, 0, false); sc->CAADDR = defun("caaddr", caaddr, 1, 0, false); sc->CADDDR = defun("cadddr", cadddr, 1, 0, false); sc->CADADR = defun("cadadr", cadadr, 1, 0, false); sc->CADDAR = defun("caddar", caddar, 1, 0, false); sc->CDAAAR = defun("cdaaar", cdaaar, 1, 0, false); sc->CDAADR = defun("cdaadr", cdaadr, 1, 0, false); sc->CDADAR = defun("cdadar", cdadar, 1, 0, false); sc->CDDAAR = defun("cddaar", cddaar, 1, 0, false); sc->CDADDR = defun("cdaddr", cdaddr, 1, 0, false); sc->CDDDDR = defun("cddddr", cddddr, 1, 0, false); sc->CDDADR = defun("cddadr", cddadr, 1, 0, false); sc->CDDDAR = defun("cdddar", cdddar, 1, 0, false); sc->ASSOC = unsafe_defun("assoc", assoc, 2, 1, false); set_is_possibly_safe(slot_value(global_slot(sc->ASSOC))); sc->MEMBER = unsafe_defun("member", member, 2, 1, false); set_is_possibly_safe(slot_value(global_slot(sc->MEMBER))); sc->LIST = defun("list", list, 0, 0, true); sc->LIST_REF = defun("list-ref", list_ref, 2, 0, true); sc->LIST_SET = defun("list-set!", list_set, 3, 0, true); sc->LIST_TAIL = defun("list-tail", list_tail, 2, 0, false); sc->MAKE_LIST = defun("make-list", make_list, 1, 1, false); sc->LENGTH = defun("length", length, 1, 0, false); sc->COPY = defun("copy", copy, 1, 3, false); sc->FILL = defun("fill!", fill, 2, 2, false); sc->REVERSE = defun("reverse", reverse, 1, 0, false); sc->REVERSEB = defun("reverse!", reverse_in_place, 1, 0, false); sc->SORT = unsafe_defun("sort!", sort, 2, 0, false); sc->APPEND = defun("append", append, 0, 0, true); #if (!WITH_PURE_S7) sc->ASSQ = defun("assq", assq, 2, 0, false); sc->ASSV = defun("assv", assv, 2, 0, false); sc->MEMQ = defun("memq", memq, 2, 0, false); sc->MEMV = defun("memv", memv, 2, 0, false); sc->VECTOR_APPEND = defun("vector-append", vector_append, 0, 0, true); sc->LIST_TO_VECTOR = defun("list->vector", list_to_vector, 1, 0, false); sc->VECTOR_FILL = defun("vector-fill!", vector_fill, 2, 2, false); sc->VECTOR_LENGTH = defun("vector-length", vector_length, 1, 0, false); sc->VECTOR_TO_LIST = defun("vector->list", vector_to_list, 1, 2, false); #else sc->VECTOR_APPEND = sc->APPEND; sc->VECTOR_FILL = sc->FILL; sc->STRING_FILL = sc->FILL; #endif sc->VECTOR_REF = defun("vector-ref", vector_ref, 2, 0, true); sc->VECTOR_SET = defun("vector-set!", vector_set, 3, 0, true); sc->VECTOR_DIMENSIONS = defun("vector-dimensions", vector_dimensions, 1, 0, false); sc->MAKE_VECTOR = defun("make-vector", make_vector, 1, 2, false); sc->MAKE_SHARED_VECTOR = defun("make-shared-vector", make_shared_vector, 2, 1, false); sc->VECTOR = defun("vector", vector, 0, 0, true); set_setter(sc->VECTOR); /* like cons, I guess */ sc->Vector = slot_value(global_slot(sc->VECTOR)); sc->FLOAT_VECTOR = defun("float-vector", float_vector, 0, 0, true); sc->MAKE_FLOAT_VECTOR = defun("make-float-vector", make_float_vector, 1, 1, false); sc->FLOAT_VECTOR_SET = defun("float-vector-set!", float_vector_set, 3, 0, true); sc->FLOAT_VECTOR_REF = defun("float-vector-ref", float_vector_ref, 2, 0, true); sc->INT_VECTOR = defun("int-vector", int_vector, 0, 0, true); sc->MAKE_INT_VECTOR = defun("make-int-vector", make_int_vector, 1, 1, false); sc->INT_VECTOR_SET = defun("int-vector-set!", int_vector_set, 3, 0, true); sc->INT_VECTOR_REF = defun("int-vector-ref", int_vector_ref, 2, 0, true); sc->TO_BYTE_VECTOR = defun("->byte-vector", to_byte_vector, 1, 0, false); sc->BYTE_VECTOR = defun("byte-vector", byte_vector, 0, 0, true); sc->MAKE_BYTE_VECTOR = defun("make-byte-vector", make_byte_vector, 1, 1, false); sc->HASH_TABLE = defun("hash-table", hash_table, 0, 0, true); sc->HASH_TABLE_STAR = defun("hash-table*", hash_table_star, 0, 0, true); sc->MAKE_HASH_TABLE = defun("make-hash-table", make_hash_table, 0, 2, false); sc->HASH_TABLE_REF = defun("hash-table-ref", hash_table_ref, 2, 0, true); sc->HASH_TABLE_SET = defun("hash-table-set!", hash_table_set, 3, 0, false); sc->HASH_TABLE_ENTRIES = defun("hash-table-entries", hash_table_entries, 1, 0, false); defun("cyclic-sequences", cyclic_sequences, 1, 0, false); sc->CALL_CC = unsafe_defun("call/cc", call_cc, 1, 0, false); sc->CALL_WITH_CURRENT_CONTINUATION = unsafe_defun("call-with-current-continuation", call_cc, 1, 0, false); sc->CALL_WITH_EXIT = unsafe_defun("call-with-exit", call_with_exit, 1, 0, false); sc->LOAD = unsafe_defun("load", load, 1, 1, false); sc->AUTOLOAD = unsafe_defun("autoload", autoload, 2, 0, false); sc->EVAL = unsafe_defun("eval", eval, 1, 1, false); sc->EVAL_STRING = unsafe_defun("eval-string", eval_string, 1, 1, false); sc->APPLY = unsafe_defun("apply", apply, 1, 0, true); sc->Apply = slot_value(global_slot(sc->APPLY)); set_type(sc->Apply, type(sc->Apply) | T_COPY_ARGS | T_PROCEDURE); /* (let ((x '((1 2) 3 4))) (catch #t (lambda () (apply apply apply x)) (lambda args 'error)) x) should not mess up x! */ sc->FOR_EACH = unsafe_defun("for-each", for_each, 2, 0, true); sc->MAP = unsafe_defun("map", map, 2, 0, true); sc->DYNAMIC_WIND = unsafe_defun("dynamic-wind", dynamic_wind, 3, 0, false); /* sc->VALUES = */ unsafe_defun("values", values, 0, 0, true); sc->CATCH = unsafe_defun("catch", catch, 3, 0, false); sc->THROW = unsafe_defun("throw", throw, 1, 0, true); sc->ERROR = unsafe_defun("error", error, 0, 0, true); /* it's faster to leave error/throw unsafe than to set needs_copied_args and use s7_define_safe_function because copy_list overwhelms any other savings */ sc->STACKTRACE = defun("stacktrace", stacktrace, 0, 5, false); { /* these are internal for quasiquote's use */ s7_pointer sym; sym = unsafe_defun("{apply_values}", apply_values, 0, 0, true); set_immutable(sym); sc->QQ_Apply_Values = slot_value(global_slot(sym)); sym = unsafe_defun("{append}", append, 0, 0, true); set_immutable(sym); sc->QQ_Append = slot_value(global_slot(sym)); sym = unsafe_defun("{multivector}", qq_multivector, 1, 0, true); set_immutable(sym); sc->Multivector = slot_value(global_slot(sym)); sym = unsafe_defun("{list}", qq_list, 0, 0, true); set_immutable(sym); sc->QQ_List = slot_value(global_slot(sym)); set_type(sc->QQ_List, T_C_RST_ARGS_FUNCTION | T_PROCEDURE | T_COPY_ARGS); } sc->PROCEDURE_DOCUMENTATION = defun("procedure-documentation", procedure_documentation, 1, 0, false); sc->PROCEDURE_SIGNATURE = defun("procedure-signature", procedure_signature, 1, 0, false); sc->HELP = defun("help", help, 1, 0, false); sc->PROCEDURE_SOURCE = defun("procedure-source", procedure_source, 1, 0, false); sc->FUNCLET = defun("funclet", funclet, 1, 0, false); s7_typed_dilambda(sc, "procedure-setter", g_procedure_setter, 1, 0, g_procedure_set_setter, 2, 0, H_procedure_setter, Q_procedure_setter, NULL); sc->ARITY = defun("arity", arity, 1, 0, false); sc->IS_ARITABLE = defun("aritable?", is_aritable, 2, 0, false); sc->NOT = defun("not", not, 1, 0, false); sc->IS_EQ = defun("eq?", is_eq, 2, 0, false); sc->IS_EQV = defun("eqv?", is_eqv, 2, 0, false); sc->IS_EQUAL = defun("equal?", is_equal, 2, 0, false); sc->IS_MORALLY_EQUAL = defun("morally-equal?", is_morally_equal, 2, 0, false); sc->GC = defun("gc", gc, 0, 1, false); defun("s7-version", s7_version, 0, 0, false); defun("emergency-exit", emergency_exit, 0, 1, false); defun("exit", exit, 0, 1, false); #if DEBUGGING s7_define_function(sc, "abort", g_abort, 0, 0, false, "drop into gdb I hope"); #endif sym = s7_define_function(sc, "(c-object set)", g_internal_object_set, 1, 0, true, "internal object setter redirection"); sc->Object_Set = slot_value(global_slot(sym)); /* -------- *features* -------- */ sc->S7_FEATURES = s7_define_variable(sc, "*features*", sc->NIL); s7_symbol_set_access(sc, sc->S7_FEATURES, s7_make_function(sc, "(set *features*)", g_features_set, 2, 0, false, "*features* accessor")); /* -------- *load-path* -------- */ sc->LOAD_PATH = s7_define_variable_with_documentation(sc, "*load-path*", sc->NIL, "*load-path* is a list of directories (strings) that the load function searches if it is passed an incomplete file name"); s7_symbol_set_access(sc, sc->LOAD_PATH, s7_make_function(sc, "(set *load-path*)", g_load_path_set, 2, 0, false, "*load-path* accessor")); /* -------- *autoload* -------- * this pretends to be a hash-table or environment, but it's actually a function */ sc->AUTOLOADER = s7_define_function(sc, "*autoload*", g_autoloader, 1, 0, false, H_autoloader); sym = s7_define_variable(sc, "*libraries*", sc->NIL); sc->libraries = global_slot(sym); s7_autoload(sc, make_symbol(sc, "cload.scm"), s7_make_permanent_string("cload.scm")); s7_autoload(sc, make_symbol(sc, "lint.scm"), s7_make_permanent_string("lint.scm")); s7_autoload(sc, make_symbol(sc, "stuff.scm"), s7_make_permanent_string("stuff.scm")); s7_autoload(sc, make_symbol(sc, "mockery.scm"), s7_make_permanent_string("mockery.scm")); s7_autoload(sc, make_symbol(sc, "write.scm"), s7_make_permanent_string("write.scm")); s7_autoload(sc, make_symbol(sc, "repl.scm"), s7_make_permanent_string("repl.scm")); s7_autoload(sc, make_symbol(sc, "r7rs.scm"), s7_make_permanent_string("r7rs.scm")); s7_autoload(sc, make_symbol(sc, "libc.scm"), s7_make_permanent_string("libc.scm")); s7_autoload(sc, make_symbol(sc, "libm.scm"), s7_make_permanent_string("libm.scm")); s7_autoload(sc, make_symbol(sc, "libdl.scm"), s7_make_permanent_string("libdl.scm")); s7_autoload(sc, make_symbol(sc, "libgsl.scm"), s7_make_permanent_string("libgsl.scm")); s7_autoload(sc, make_symbol(sc, "libgdbm.scm"), s7_make_permanent_string("libgdbm.scm")); s7_autoload(sc, make_symbol(sc, "libutf8proc.scm"), s7_make_permanent_string("libutf8proc.scm")); sc->REQUIRE = s7_define_macro(sc, "require", g_require, 0, 0, true, H_require); sc->stacktrace_defaults = s7_list(sc, 5, small_int(3), small_int(45), small_int(80), small_int(45), sc->T); /* -------- *#readers* -------- */ sym = s7_define_variable(sc, "*#readers*", sc->NIL); sc->sharp_readers = global_slot(sym); s7_symbol_set_access(sc, sym, s7_make_function(sc, "(set *#readers*)", g_sharp_readers_set, 2, 0, false, "*#readers* accessor")); /* sigh... I don't like these! */ s7_define_constant(sc, "nan.0", real_NaN); s7_define_constant(sc, "-nan.0", real_NaN); s7_define_constant(sc, "inf.0", real_infinity); s7_define_constant(sc, "-inf.0", real_minus_infinity); /* *features* */ s7_provide(sc, "s7"); s7_provide(sc, "s7-" S7_VERSION); s7_provide(sc, "ratio"); #if WITH_PURE_S7 s7_provide(sc, "pure-s7"); #endif #if WITH_EXTRA_EXPONENT_MARKERS s7_provide(sc, "dfls-exponents"); #endif #if WITH_SYSTEM_EXTRAS s7_provide(sc, "system-extras"); #endif #if WITH_IMMUTABLE_UNQUOTE s7_provide(sc, "immutable-unquote"); #endif #if DEBUGGING s7_provide(sc, "debugging"); #endif #if HAVE_COMPLEX_NUMBERS s7_provide(sc, "complex-numbers"); #endif #if WITH_C_LOADER s7_provide(sc, "dlopen"); #endif #ifdef __APPLE__ s7_provide(sc, "osx"); #endif #ifdef __linux__ s7_provide(sc, "linux"); #endif #ifdef __OpenBSD__ s7_provide(sc, "openbsd"); #endif #ifdef __NetBSD__ s7_provide(sc, "netbsd"); #endif #ifdef __FreeBSD__ s7_provide(sc, "freebsd"); #endif #if MS_WINDOWS s7_provide(sc, "windows"); #endif #ifdef __bfin__ s7_provide(sc, "blackfin"); #endif #ifdef __ANDROID__ s7_provide(sc, "android"); #endif #ifdef __CYGWIN__ s7_provide(sc, "cygwin"); #endif #ifdef __hpux s7_provide(sc, "hpux"); #endif #if defined(__sun) && defined(__SVR4) s7_provide(sc, "solaris"); #endif sc->Vector_Set = slot_value(global_slot(sc->VECTOR_SET)); set_setter(sc->VECTOR_SET); /* not float-vector-set! here */ sc->List_Set = slot_value(global_slot(sc->LIST_SET)); set_setter(sc->LIST_SET); sc->Hash_Table_Set = slot_value(global_slot(sc->HASH_TABLE_SET)); set_setter(sc->HASH_TABLE_SET); sc->Let_Set = slot_value(global_slot(sc->LET_SET)); set_setter(sc->LET_SET); set_setter(sc->CONS); /* (this blocks an over-eager do loop optimization -- see do-test-15 in s7test) */ sc->String_Set = slot_value(global_slot(sc->STRING_SET)); set_setter(sc->STRING_SET); set_setter(sc->SET_CAR); set_setter(sc->SET_CDR); #if (!WITH_PURE_S7) set_setter(s7_make_symbol(sc, "set-current-input-port")); set_setter(s7_make_symbol(sc, "set-current-output-port")); s7_function_set_setter(sc, "current-input-port", "set-current-input-port"); s7_function_set_setter(sc, "current-output-port", "set-current-output-port"); #endif set_setter(s7_make_symbol(sc, "set-current-error-port")); s7_function_set_setter(sc, "current-error-port", "set-current-error-port"); /* despite the similar names, current-error-port is different from the other two, and a setter is needed * in scheme because error and warn send output to it by default. It is not a "dynamic variable" unlike * the other two. In the input/output cases, setting the port can only cause confusion. * current-error-port should simply be an s7 variable with a name like *error-port* and an accessor to * ensure its new value, if any, is an output port. */ s7_function_set_setter(sc, "car", "set-car!"); s7_function_set_setter(sc, "cdr", "set-cdr!"); s7_function_set_setter(sc, "hash-table-ref", "hash-table-set!"); s7_function_set_setter(sc, "vector-ref", "vector-set!"); s7_function_set_setter(sc, "float-vector-ref", "float-vector-set!"); s7_function_set_setter(sc, "int-vector-ref", "int-vector-set!"); s7_function_set_setter(sc, "list-ref", "list-set!"); s7_function_set_setter(sc, "let-ref", "let-set!"); s7_function_set_setter(sc, "string-ref", "string-set!"); c_function_setter(slot_value(global_slot(sc->OUTLET))) = s7_make_function(sc, "(set! outlet)", g_set_outlet, 2, 0, false, "outlet setter"); { int i, top; #if WITH_GMP #define S7_LOG_LLONG_MAX 36.736800 #define S7_LOG_LONG_MAX 16.6355322 #else /* actually not safe = (log (- (expt 2 63) 1)) and (log (- (expt 2 31) 1)) * (using 63 and 31 bits) */ #define S7_LOG_LLONG_MAX 43.668274 #define S7_LOG_LONG_MAX 21.487562 #endif top = sizeof(s7_int); s7_int32_max = (top == 8) ? S7_LONG_MAX : S7_SHORT_MAX; s7_int32_min = (top == 8) ? S7_LONG_MIN : S7_SHORT_MIN; s7_int_bits = (top == 8) ? 63 : 31; s7_int_digits = (top == 8) ? 18 : 8; s7_int_max = (top == 8) ? S7_LLONG_MAX : S7_LONG_MAX; s7_int_min = (top == 8) ? S7_LLONG_MIN : S7_LONG_MIN; s7_int_digits_by_radix[0] = 0; s7_int_digits_by_radix[1] = 0; for (i = 2; i < 17; i++) s7_int_digits_by_radix[i] = (int)(floor(((top == 8) ? S7_LOG_LLONG_MAX : S7_LOG_LONG_MAX) / log((double)i))); s7_define_constant(sc, "most-positive-fixnum", make_permanent_integer_unchecked((top == 8) ? s7_int_max : ((top == 4) ? S7_LONG_MAX : S7_SHORT_MAX))); s7_define_constant(sc, "most-negative-fixnum", make_permanent_integer_unchecked((top == 8) ? s7_int_min : ((top == 4) ? S7_LONG_MIN : S7_SHORT_MIN))); if (top == 4) sc->default_rationalize_error = 1.0e-6; s7_define_constant(sc, "pi", real_pi); sc->PI = s7_make_symbol(sc, "pi"); { s7_pointer p; new_cell(sc, p, T_RANDOM_STATE); #if WITH_GMP { mpz_t seed; mpz_init_set_ui(seed, (unsigned int)time(NULL)); gmp_randinit_default(random_gmp_state(p)); gmp_randseed(random_gmp_state(p), seed); mpz_clear(seed); } #else random_seed(p) = (unsigned long long int)time(NULL); random_carry(p) = 1675393560; #endif sc->default_rng = p; } for (i = 0; i < 10; i++) sc->singletons[(unsigned char)'0' + i] = small_int(i); sc->singletons[(unsigned char)'+'] = sc->ADD; sc->singletons[(unsigned char)'-'] = sc->SUBTRACT; sc->singletons[(unsigned char)'*'] = sc->MULTIPLY; sc->singletons[(unsigned char)'/'] = sc->DIVIDE; sc->singletons[(unsigned char)'<'] = sc->LT; sc->singletons[(unsigned char)'>'] = sc->GT; sc->singletons[(unsigned char)'='] = sc->EQ; } #if WITH_GMP s7_gmp_init(sc); #endif init_choosers(sc); s7_define_macro(sc, "quasiquote", g_quasiquote, 1, 0, false, H_quasiquote); s7_eval_c_string(sc, "(define (dilambda g s) \n\ (if (or (not (arity g)) (not (arity s))) \n\ (error 'wrong-type-arg \"dilambda takes 2 procedures: ~A ~A\" g s) \n\ (set! (procedure-setter g) s)) \n\ g)"); #if (!WITH_PURE_S7) s7_eval_c_string(sc, "(define hash-table-size length)"); /* backwards compatibility */ s7_eval_c_string(sc, "(define-macro (defmacro name args . body) `(define-macro ,(cons name args) ,@body))"); s7_eval_c_string(sc, "(define-macro (defmacro* name args . body) `(define-macro* ,(cons name args) ,@body))"); s7_eval_c_string(sc, "(define-macro (call-with-values producer consumer) `(,consumer (,producer)))"); /* (call-with-values (lambda () (values 1 2 3)) +) */ s7_eval_c_string(sc, "(define-macro (multiple-value-bind vars expression . body) \n\ (if (or (symbol? vars) (negative? (length vars))) \n\ `((lambda ,vars ,@body) ,expression) \n\ `((lambda* (,@vars . ,(gensym)) ,@body) ,expression)))"); /* (multiple-value-bind (a b) (values 1 2) (+ a b)), named "receive" in srfi-8 which strikes me as perverse */ s7_eval_c_string(sc, "(define-macro (multiple-value-set! vars expr . body) \n\ (if (pair? vars) \n\ (let ((local-vars (map (lambda (n) (gensym)) vars))) \n\ `((lambda* (,@local-vars . ,(gensym)) \n\ ,@(map (lambda (n ln) `(set! ,n ,ln)) vars local-vars) \n\ ,@body) \n\ ,expr)) \n\ (if (and (null? vars) (null? expr)) \n\ `(begin ,@body) \n\ (error \"multiple-value-set! vars/exprs messed up\"))))"); s7_eval_c_string(sc, "(define-macro (cond-expand . clauses) \n\ (letrec ((traverse (lambda (tree) \n\ (if (pair? tree) \n\ (cons (traverse (car tree)) \n\ (if (null? (cdr tree)) () (traverse (cdr tree)))) \n\ (if (member tree '(and or not else) eq?) tree \n\ (and (symbol? tree) (provided? tree))))))) \n\ `(cond ,@(map (lambda (clause) \n\ (cons (traverse (car clause)) \n\ (if (null? (cdr clause)) '(#f) (cdr clause)))) \n\ clauses))))"); #endif s7_eval_c_string(sc, "(define-expansion (reader-cond . clauses) \n\ (call-with-exit \n\ (lambda (return) \n\ (for-each \n\ (lambda (clause) \n\ (let ((val (eval (car clause)))) \n\ (if val \n\ (if (null? (cdr clause)) (return val) \n\ (if (null? (cddr clause)) (return (cadr clause)) \n\ (return (apply values (map quote (cdr clause))))))))) \n\ clauses) \n\ (values))))"); s7_eval_c_string(sc, "(define (make-hook . args) \n\ (let ((body ())) \n\ (apply lambda* args \n\ '(let ((result #)) \n\ (let ((e (curlet))) \n\ (for-each (lambda (f) (f e)) body) \n\ result)) \n\ ())))"); s7_eval_c_string(sc, "(define hook-functions \n\ (dilambda \n\ (lambda (hook) \n\ ((funclet hook) 'body)) \n\ (lambda (hook lst) \n\ (if (or (null? lst) \n\ (and (pair? lst) \n\ (apply and (map (lambda (f) \n\ (and (procedure? f) \n\ (aritable? f 1))) \n\ lst)))) \n\ (set! ((funclet hook) 'body) lst) \n\ (error 'wrong-type-arg \"hook-functions must be a list of functions, each accepting one argument: ~S\" lst)))))"); /* -------- *unbound-variable-hook* -------- */ sc->unbound_variable_hook = s7_eval_c_string(sc, "(make-hook 'variable)"); s7_define_constant_with_documentation(sc, "*unbound-variable-hook*", sc->unbound_variable_hook, "*unbound-variable-hook* functions are called when an unbound variable is encountered, passed (hook 'variable)."); /* -------- *missing-close-paren-hook* -------- */ sc->missing_close_paren_hook = s7_eval_c_string(sc, "(make-hook)"); s7_define_constant_with_documentation(sc, "*missing-close-paren-hook*", sc->missing_close_paren_hook, "*missing-close-paren-hook* functions are called when the reader thinks a close paren is missing"); /* -------- *load-hook* -------- */ sc->load_hook = s7_eval_c_string(sc, "(make-hook 'name)"); s7_define_constant_with_documentation(sc, "*load-hook*", sc->load_hook, "*load-hook* functions are invoked by load, passing the to-be-loaded filename as (hook 'name)"); /* -------- *error-hook* -------- */ sc->error_hook = s7_eval_c_string(sc, "(make-hook 'type 'data)"); s7_define_constant_with_documentation(sc, "*error-hook*", sc->error_hook, "*error-hook* functions are called in the error handler, passed (hook 'type) and (hook 'data)."); s7_define_constant(sc, "*s7*", s7_openlet(sc, s7_inlet(sc, s7_list(sc, 2, s7_cons(sc, sc->LET_REF_FALLBACK, s7_make_function(sc, "s7-let-ref", g_s7_let_ref_fallback, 2, 0, false, "*s7* reader")), s7_cons(sc, sc->LET_SET_FALLBACK, s7_make_function(sc, "s7-let-set", g_s7_let_set_fallback, 3, 0, false, "*s7* writer")))))); #if (!DISABLE_DEPRECATED) s7_eval_c_string(sc, "(define global-environment rootlet) \n\ (define current-environment curlet) \n\ (define make-procedure-with-setter dilambda) \n\ (define procedure-with-setter? dilambda?)\n\ (define make-random-state random-state) \n\ (define make-complex complex) \n\ (define (procedure-arity obj) (let ((c (arity obj))) (list (car c) (- (cdr c) (car c)) (> (cdr c) 100000))))"); #endif /* fprintf(stderr, "size: %d, max op: %d, opt: %d\n", (int)sizeof(s7_cell), OP_MAX_DEFINED, OPT_MAX_DEFINED); */ /* 64 bit machine: size: 48 [size 72 if gmp], op: 321, opt: 400 */ if (sizeof(void *) > sizeof(s7_int)) fprintf(stderr, "s7_int is too small: it has %d bytes, but void* has %d\n", (int)sizeof(s7_int), (int)sizeof(void *)); save_unlet(sc); #if WITH_COUNTS clear_counts(); #endif init_s7_let(sc); /* set up *s7* */ already_inited = true; return(sc); } /* -------------------------------- repl -------------------------------- */ #ifndef USE_SND #define USE_SND 0 #endif #ifndef WITH_MAIN #define WITH_MAIN 0 #endif #if (WITH_MAIN && (!USE_SND)) int main(int argc, char **argv) { s7_scheme *sc; sc = s7_init(); if (argc == 2) { fprintf(stderr, "load %s\n", argv[1]); s7_load(sc, argv[1]); } else { #ifndef _MSC_VER s7_load(sc, "repl.scm"); /* this is libc dependent */ s7_eval_c_string(sc, "((*repl* 'run))"); #else while (1) /* a minimal repl -- taken from s7.html */ { char buffer[512]; char response[1024]; fprintf(stdout, "\n> "); fgets(buffer, 512, stdin); if ((buffer[0] != '\n') || (strlen(buffer) > 1)) { sprintf(response, "(write %s)", buffer); s7_eval_c_string(sc, response); } } #endif } return(0); } /* in Linux: gcc s7.c -o repl -DWITH_MAIN -I. -g3 -ldl -lm -Wl,-export-dynamic * in *BSD: gcc s7.c -o repl -DWITH_MAIN -I. -g3 -lm -Wl,-export-dynamic * in OSX: gcc s7.c -o repl -DWITH_MAIN -I. -g3 -lm * (clang also needs LDFLAGS="-Wl,-export-dynamic" in Linux) */ #endif /* ---------------------------------------------------- * * 12 | 13 | 14 | 15 | 16.0 16.1 * * s7test 1721 | 1358 | 995 | 1194 | 1122 1117 * index 44.3 | 3291 | 1725 | 1276 | 1156 1158 * teq | | | 6612 | 2380 2376 * tauto 265 | 89 | 9 | 8.4 | 2638 2643 * tcopy | | | 13.6 | 3204 3203 * bench 42.7 | 8752 | 4220 | 3506 | 3230 3229 * tform | | | 6816 | 3627 3589 * tmap | | | 9.3 | 4176 4177 * titer | | | 7503 | 5218 5219 * thash | | | 50.7 | 8491 8484 * lg | | | | 20.7 * | | | | * tgen | 71 | 70.6 | 38.0 | 12.0 11.7 * tall 90 | 43 | 14.5 | 12.7 | 15.0 15.0 * calls 359 | 275 | 54 | 34.7 | 37.1 37.0 * * ---------------------------------------------------- * * mockery.scm needs documentation (and stuff.scm: doc cyclic-seq+stuff under circular lists) * cyclic-seq in stuff.scm, but current code is really clumsy * gtk gl: I can't see how to switch gl in and out as in the motif version -- I guess I need both gl_area and drawing_area * the old mus-audio-* code needs to use play or something, especially bess* -- what about soundio * snd namespaces from etc mark: (inlet :type 'mark :name "" :home :sample 0 :sync #f) with name/sync/sample settable * doc c_object_rf stuff? or how cload ties things into rf/sig * libutf8proc.scm doc/examples? cload gtk/sndlib * remove the #t=all sounds business! = (map f (sounds)) * gf cases (rf/if also): substring [inlet list vector float-vector int-vector] hash-table(*) sublet string format vector-append string-append append * clm make-* sig should include the actual gen: oscil->(float? oscil? real?), also make->actual not #t in a circle * make-oscil -> '(oscil? real? real) * make-env -> '(env? sequence? real? real? real? real? integer? integer?) [seq here is actually pair? or float-vector?] * * how to get at read-error cause in catch? port-data=string, port-position=int, port_data_size=int last-open-paren (sc->current_line) * port-data port-position, length=remaining (unread) chars, copy->string gets that data, so no need for new funcs * also port-filename|line-number could use let syntax, then maybe add position|data etc -- mock let like *s7* * gc troubles with the string wrapper. Another such case: iterator. But how to handle default port as in (port-line-number)? * * append: 44522: what if method not first arg? use 'values: check_values? * (append "asd" ((*mock-string* 'mock-string) "hi")): error: append argument 1, "hi", is mock-string but should be a character * s7 44522 -- method check is unfinished -- should look for append and make arglists, not length * (append "asd" ((*mock-char* 'mock-char) #\g)): error: append argument 1, #\g, is mock-char but should be a sequence * also arg num is incorrect -- always off by 1? * append in string case uses string_append, not g_string_append! * * lint: simple type->bool outside if et al?? [if car sig boolean? simplify] * closure sig from body (and side-effects), expand args in code for internal lint? * if closure depends only on arg (no free var, no funcs other than built-ins) and has no side-effects, and gets constant arg, eval? * define* lambda* key-opt-key ordering and recognition -- split out arity/type/side-effect/self-contained (are globals in the var list?) * first step done, now make-var -> sublet/inlet, handle the todo's in lint.scm, t330 lambda case * also are defines in begin exported? also when etc. * for class let: arity, procedure?, macro?, object->string, for var: sig and side decisions, macro tests * can we match cc/exit args to the caller? error-args to the catcher? * :rest with default * macros that cause definitions are ignored (this also affects variable usage stats) and cload'ed identifiers are missed * variable not used can be confused (prepend-spaces and display-let in stuff.scm) * catch func arg checks (thunk, any args) * code that can be make-list|string or vector|string etc * morally-equal? for vector equality * do we catch (not (when...))? it's not necessarily a mistake. * letrec -> let (as in index.scm) [if none of letrec vars (including current) occurs in any of the bindings, use let] * can letrec* -> let* if there are no forward refs? ->letrec if no cross dependencies? * can the reverse be recognized (i.e. no occurrence of name in outer env, use in let before decl)? * kw passed to define? non-hygienic macro problem (these should be obvious from the calling args and current env) * * static s7_int abs_if_i(s7_scheme *sc, s7_pointer **p){s7_if_t f; s7_int x; f = (s7_if_t)(**p); (*p)++; x = f(sc, p); return(abs(x));} * in libc_s7.c -- this should use llabs or cast the argument, or do abs by hand. * (define (f f) (define* (f (f f)) f) (f)) (f 0): error: lambda* defaults: f is unbound?? * (define* (f2 a :rest b) (list a b)), (f2 1 :a 1) is not an error? at least in lint point out that here :a does not set a * (define (f1 f1) f1) is also ok? */ snd-16.1/snd-axis.c0000644000076400007640000017157312601500373012240 0ustar bilbil#include "snd.h" bool is_x_axis_style(int n) { switch (n) { case X_AXIS_IN_SECONDS: case X_AXIS_IN_SAMPLES: case X_AXIS_AS_PERCENTAGE: case X_AXIS_IN_BEATS: case X_AXIS_IN_MEASURES: case X_AXIS_AS_CLOCK: return(true); break; } return(false); } bool shows_axes(int n) { switch (n) { case SHOW_NO_AXES: case SHOW_ALL_AXES: case SHOW_X_AXIS: case SHOW_ALL_AXES_UNLABELLED: case SHOW_X_AXIS_UNLABELLED: case SHOW_BARE_X_AXIS: return(true); break; } return(false); } typedef struct tick_descriptor { double hi, lo; int max_ticks; double flo, fhi, mlo, mhi, step, tenstep; int tens; int maj_tick_len, min_tick_len, min_label_width, max_label_width; char *min_label, *max_label; mus_float_t grid_scale; } tick_descriptor; static tick_descriptor *free_tick_descriptor(tick_descriptor *td) { if (td) { if (td->min_label) {free(td->min_label); td->min_label = NULL;} if (td->max_label) {free(td->max_label); td->max_label = NULL;} free(td); } return(NULL); } static tick_descriptor *describe_ticks(tick_descriptor *gd_td, double lo, double hi, int max_ticks, mus_float_t grid_scale) { /* given absolute (unchangeable) axis bounds lo and hi, and maximum number of ticks to use, find a "pretty" tick placement */ /* much of the work here involves floating point rounding problems. We assume the tick labeller will round as well */ tick_descriptor *td; int ten, hib, lob, offset = 0; double flog10, plog10; double frac, ften, hilo_diff, eten, flt_ten; double inside, mfdiv, mten, mften; int mticks, mdiv; if (!gd_td) td = (tick_descriptor *)calloc(1, sizeof(tick_descriptor)); else { td = gd_td; if ((td->hi == hi) && (td->lo == lo) && (td->max_ticks == max_ticks) && ((fabs(td->grid_scale - grid_scale)) < .01)) return(td); } td->hi = hi; td->lo = lo; td->grid_scale = grid_scale; hilo_diff = hi - lo; if (hilo_diff < .001) { offset = (int)hi; hi -= offset; lo -= offset; } td->max_ticks = max_ticks; flt_ten = log10(hilo_diff); ten = (int)floor(flt_ten); frac = flt_ten - ten; if (frac > .9999) ten++; eten = pow(10, ten); hib = (int)floor(hi / eten); lob = (int)ceil(lo / eten); /* it's possible to wrap-around here and get negative numbers (so we keep the offset separate above) */ if (lob != hib) { td->mlo = (double)(lob * eten); td->mhi = (double)(hib * eten); } else { double flt_ften; /* try next lower power of ten */ ften = eten * .1; flt_ften = (hi / ften); hib = (int)floor(flt_ften); frac = flt_ften - hib; if (frac > .9999) hib++; lob = (int)ceil(lo / ften); td->mlo = (double)(lob * ften); td->mhi = (double)(hib * ften); } inside = (td->mhi - td->mlo) / hilo_diff; mticks = (int)floor(inside * max_ticks); if (mticks <= 1) mdiv = 1; else if (mticks < 3) mdiv = mticks; else if (mticks == 3) mdiv = 2; else if (mticks < 6) mdiv = mticks; else if (mticks < 10) mdiv = 5; else mdiv = (int)(10 * floor(mticks / 10)); mfdiv = (td->mhi - td->mlo) / mdiv; flog10 = floor(log10(mfdiv)); plog10 = pow(10, flog10); td->tens = (int)fabs(flog10); mten = grid_scale * (double)(floor(4.0 * (.00001 + (mfdiv / plog10)))) / 4.0; if (mten < 1.0) mten = 1.0; if ((mten == 1.0) || (mten == 2.0) || (mten == 2.5) || (mten == 5.0)) ften = mten; else if (mten < 2.0) ften = 2.0; else if (mten < 2.5) ften = 2.5; else if (mten < 5.0) ften = 5.0; else ften = 10.0; td->tenstep = ften; mften = ften * plog10; td->step = mften; flt_ten = lo / mften; lob = (int)ceil(flt_ten); frac = lob - flt_ten; if (frac > .9999) lob--; td->flo = lob * mften; flt_ten = (hi / mften); hib = (int)floor(flt_ten); frac = flt_ten - hib; if (frac > .9999) hib++; td->fhi = hib * mften; if (hilo_diff < .001) { td->mlo += offset; td->mhi += offset; td->flo += offset; td->fhi += offset; } return(td); } static bool first_beat(chan_info *cp, double val) { int measure, beat; double beat_frac; beat = (int)val; beat_frac = val - beat; measure = (int)(beat / cp->beats_per_measure); beat = beat - measure * cp->beats_per_measure; return((beat == 0) && (beat_frac < .001)); } static char *measure_number(int bpm, double val) { /* split out the measure number, change to beat count (1-based), add fraction, if any */ /* "val" is in terms of beats */ char *buf; int measure, beat; double beat_frac; beat = (int)val; beat_frac = val - beat; measure = (int)(beat / bpm); beat = beat - measure * bpm; buf = (char *)calloc(64, sizeof(char)); if (beat_frac > .001) { char *frac_buf, *tmp; /* according to the C spec, there's no way to get %f to omit the leading "0" */ frac_buf = (char *)calloc(32, sizeof(char)); snprintf(frac_buf, 32, "%.3f", beat_frac); if (frac_buf[0] == '0') tmp = (frac_buf + 1); /* omit the leading "0" */ else tmp = frac_buf; snprintf(buf, 64, "%d(%d)%s", 1 + measure, 1 + beat, tmp); free(frac_buf); } else snprintf(buf, 64, "%d(%d)", 1 + measure, 1 + beat); return(buf); } static char *clock_number(double loc, int tens) { /* DD:HH:MM:SS.ddd */ #define CLOCK_BUFFER_SIZE 64 int day, hour, minute, second; double frac_second; char *buf; second = (int)loc; frac_second = loc - second; minute = (int)floor(second / 60); hour = (int)floor(minute / 60); day = (int)floor(hour / 24); second %= 60; minute %= 60; hour %= 24; buf = (char *)calloc(CLOCK_BUFFER_SIZE, sizeof(char)); if (day > 0) snprintf(buf, CLOCK_BUFFER_SIZE, "%02d:%02d:%02d:%02d.%0*d", day, hour, minute, second, tens, (int)(frac_second * pow(10.0, tens))); else { if (hour > 0) snprintf(buf, CLOCK_BUFFER_SIZE, "%02d:%02d:%02d.%0*d", hour, minute, second, tens, (int)(frac_second * pow(10.0, tens))); else { if (minute > 0) snprintf(buf, CLOCK_BUFFER_SIZE, "%02d:%02d.%0*d", minute, second, tens, (int)(frac_second * pow(10.0, tens))); else { if (second > 0) snprintf(buf, CLOCK_BUFFER_SIZE, "%d.%0*d", second, tens, (int)(frac_second * pow(10.0, tens))); else snprintf(buf, CLOCK_BUFFER_SIZE, "0.%0*d", tens, (int)(frac_second * pow(10.0, tens))); } } } return(buf); } static char *location_to_string(double loc, int style, int bpm, int tens) { if (style == X_AXIS_IN_SAMPLES) tens = 0; else { if (tens == 0) tens = 1; /* in x axis we usually want the ".0" */ } switch (style) { case X_AXIS_AS_CLOCK: return(clock_number(loc, tens)); break; case X_AXIS_IN_MEASURES: return(measure_number(bpm, loc)); break; default: return(prettyf(loc, tens)); break; } return(prettyf(loc, tens)); } char *x_axis_location_to_string(chan_info *cp, double loc) { if (cp) { axis_info *ap; ap = cp->axis; /* time graph */ if (ap) { tick_descriptor *tdx; tdx = ap->x_ticks; if (tdx) return(location_to_string(loc, cp->x_axis_style, cp->beats_per_measure, tdx->tens)); } } return(prettyf(loc, 2)); } axis_info *free_axis_info(axis_info *ap) { if (!ap) return(NULL); if (ap->x_ticks) ap->x_ticks = free_tick_descriptor(ap->x_ticks); if (ap->y_ticks) ap->y_ticks = free_tick_descriptor(ap->y_ticks); /* leave ap->ax alone -- it actually belongs to cp */ if (ap->xlabel) { free(ap->xlabel); ap->xlabel = NULL; } if (ap->default_xlabel) { free(ap->default_xlabel); ap->default_xlabel = NULL; } if (ap->ylabel) { free(ap->ylabel); ap->ylabel = NULL; } free(ap); return(NULL); } int grf_x(double val, axis_info *ap) { if (val >= ap->x1) return(ap->x_axis_x1); if (val <= ap->x0) return(ap->x_axis_x0); return((int)(ap->x_base + val * ap->x_scale)); } int grf_y(mus_float_t val, axis_info *ap) { if (val >= ap->y1) return(ap->y_axis_y1); if (val <= ap->y0) return(ap->y_axis_y0); return((int)(ap->y_base + val * ap->y_scale)); } void init_axis_scales(axis_info *ap) { if ((ap->x_axis_x0 == ap->x_axis_x1) || (ap->x0 == ap->x1)) ap->x_scale = 0.0; else ap->x_scale = ((double)(ap->x_axis_x1 - ap->x_axis_x0)) / ((double)(ap->x1 - ap->x0)); ap->x_base = (double)(ap->x_axis_x0 - ap->x0 * ap->x_scale); if ((ap->y_axis_y0 == ap->y_axis_y1) || (ap->y0 == ap->y1)) ap->y_scale = 0.0; else ap->y_scale = (mus_float_t)(ap->y_axis_y1 - ap->y_axis_y0) / (ap->y1 - ap->y0); ap->y_base = (mus_float_t)(ap->y_axis_y0 - ap->y0 * ap->y_scale); } static int tick_grf_x(double val, axis_info *ap, x_axis_style_t style, int srate) { int res = 0; switch (style) { case X_AXIS_AS_CLOCK: case X_AXIS_IN_SECONDS: default: res = (int)(ap->x_base + val * ap->x_scale); break; case X_AXIS_IN_BEATS: case X_AXIS_IN_MEASURES: if (ap->cp) res = (int)(ap->x_base + val * ap->x_scale * 60.0 / ap->cp->beats_per_minute); else res = (int)(ap->x_base + val * ap->x_scale); break; case X_AXIS_IN_SAMPLES: res = (int)(ap->x_axis_x0 + (val - ap->x0 * srate) * ap->x_scale / srate); break; case X_AXIS_AS_PERCENTAGE: res = (int)(ap->x_axis_x0 + (val - ap->x0 / ap->xmax) * ap->x_scale * ap->xmax); break; } if (res >= -32768) { if (res < 32768) return(res); return(32767); } return(-32768); } #if HAVE_GL #if WITH_GL2PS void gl2ps_text(const char *msg); #endif static bool gl_fonts_activated = false; static int label_base, number_base; static void activate_gl_fonts(void) { #if USE_MOTIF if (!gl_fonts_activated) { XFontStruct *label, *number; label = (XFontStruct *)(AXIS_LABEL_FONT(ss)); number = (XFontStruct *)(AXIS_NUMBERS_FONT(ss)); label_base = glGenLists(128); number_base = glGenLists(128); glXUseXFont(label->fid, 32, 96, label_base + 32); glXUseXFont(number->fid, 32, 96, number_base + 32); gl_fonts_activated = true; } #else if (!gl_fonts_activated) { label_base = glGenLists(128); number_base = glGenLists(128); gl_fonts_activated = true; } #endif } void reload_label_font(void) { #if USE_MOTIF if (gl_fonts_activated) { XFontStruct *label; glDeleteLists(label_base, 128); label_base = glGenLists(128); label = (XFontStruct *)(AXIS_LABEL_FONT(ss)); glXUseXFont(label->fid, 32, 96, label_base + 32); } #else if (gl_fonts_activated) { glDeleteLists(label_base, 128); label_base = glGenLists(128); /* gdk_gl_font_use_pango_font(AXIS_LABEL_FONT(ss), 32, 96, label_base + 32); */ } #endif } void reload_number_font(void) { #if USE_MOTIF if (gl_fonts_activated) { XFontStruct *number; glDeleteLists(number_base, 128); number_base = glGenLists(128); number = (XFontStruct *)(AXIS_NUMBERS_FONT(ss)); glXUseXFont(number->fid, 32, 96, number_base + 32); } #else if (gl_fonts_activated) { glDeleteLists(number_base, 128); number_base = glGenLists(128); /* gdk_gl_font_use_pango_font(AXIS_NUMBERS_FONT(ss), 32, 96, number_base + 32); */ } #endif } #endif static void draw_horizontal_grid_line(int y, axis_info *ap, graphics_context *ax) { color_t old_color; old_color = get_foreground_color(ax); if (ap->cp->selected) set_foreground_color(ax, ss->selected_grid_color); else set_foreground_color(ax, ss->grid_color); draw_line(ax, ap->y_axis_x0, y, ap->x_axis_x1, y); set_foreground_color(ax, old_color); } static void draw_vertical_grid_line(int x, axis_info *ap, graphics_context *ax) { color_t old_color; old_color = get_foreground_color(ax); if (ap->cp->selected) set_foreground_color(ax, ss->selected_grid_color); else set_foreground_color(ax, ss->grid_color); draw_line(ax, x, ap->x_axis_y0, x, ap->y_axis_y1); set_foreground_color(ax, old_color); } static void draw_x_number(const char *label, int x, int y, int hgt, axis_info *ap, graphics_context *ax, printing_t printing) { /* from motif point of view, gtk is down by font height (ascent) in pixels */ if (x < 0) x = 0; /* if no y axis and no labels, this sometimes is pushed left too far */ #if USE_MOTIF y = y + hgt + 1; #else y = y + 4; #endif draw_string(ax, x, y, label, mus_strlen(label)); if (printing) ps_draw_string(ap, x, y, label); } static void draw_y_number(const char *label, int x, int y, int hgt, axis_info *ap, graphics_context *ax, printing_t printing) { /* from motif point of view, gtk is down by font height (ascent) in pixels */ #if USE_MOTIF y = y + (int)(hgt / 2); #else y = y - (int)(hgt / 2); #endif draw_string(ax, x, y, label, mus_strlen(label)); if (printing) ps_draw_string(ap, x, y, label); } static void draw_label(const char *label, int x, int y, int yoff, axis_info *ap, graphics_context *ax, printing_t printing) { /* from motif point of view, gtk is down by font height (ascent) in pixels */ #if USE_GTK y -= yoff; #endif draw_string(ax, x - 10, y, label, mus_strlen(label)); if (printing) ps_draw_string(ap, x - 10, y, label); } static void draw_vertical_tick(int x, int y0, int y1, axis_info *ap, graphics_context *ax, printing_t printing, bool include_grid) { draw_line(ax, x, y1, x, y0); if (printing) ps_draw_line(ap, x, y1, x, y0); if (include_grid) draw_vertical_grid_line(x, ap, ax); } static void draw_horizontal_tick(int x0, int x1, int y, axis_info *ap, graphics_context *ax, printing_t printing, bool include_grid) { draw_line(ax, x0, y, x1, y); if (printing) ps_draw_line(ap, x0, y, x1, y); if (include_grid) draw_horizontal_grid_line(y, ap, ax); } static void draw_log_tick_label(const char *label, int logx, int y, int hgt, int x_label_width, int right_border_width, axis_info *ap, graphics_context *ax, printing_t printing, bool use_tiny_font) { /* is there room for a label? */ /* the main label is at ap->x_label_x to that plus x_label_width */ int lx0, lx1, tx0, tx1, label_width; lx0 = ap->x_label_x; lx1 = lx0 + x_label_width; label_width = number_width(label, use_tiny_font); tx0 = (int)(logx - .45 * label_width); if ((tx0 + label_width) > ap->x_axis_x1) tx0 = (int)(logx - label_width + .75 * right_border_width); tx1 = tx0 + label_width; if ((lx0 > tx1) || (lx1 < tx0)) draw_x_number(label, tx0, y, hgt, ap, ax, printing); } static void use_tiny(graphics_context *ax, printing_t printing) { #if USE_MOTIF ax->current_font = ((XFontStruct *)(TINY_FONT(ss)))->fid; XSetFont(ax->dp, ax->gc, ((XFontStruct *)(TINY_FONT(ss)))->fid); #else #if USE_GTK ax->current_font = TINY_FONT(ss); #endif #endif if (printing) ps_set_tiny_numbers_font(); } void set_numbers_font(graphics_context *ax, printing_t printing, bool use_tiny_font) { if (use_tiny_font) use_tiny(ax, printing); else { #if USE_MOTIF ax->current_font = ((XFontStruct *)(AXIS_NUMBERS_FONT(ss)))->fid; XSetFont(ax->dp, ax->gc, ((XFontStruct *)(AXIS_NUMBERS_FONT(ss)))->fid); #else #if USE_GTK ax->current_font = AXIS_NUMBERS_FONT(ss); #endif #endif if (printing) ps_set_number_font(); } } static void set_labels_font(graphics_context *ax, printing_t printing, bool use_tiny_font) { if (use_tiny_font) use_tiny(ax, printing); else { #if USE_MOTIF ax->current_font = ((XFontStruct *)(AXIS_LABEL_FONT(ss)))->fid; XSetFont(ax->dp, ax->gc, ((XFontStruct *)(AXIS_LABEL_FONT(ss)))->fid); #else #if USE_GTK ax->current_font = AXIS_LABEL_FONT(ss); #endif #endif if (printing) ps_set_label_font(); } } void make_axes_1(axis_info *ap, x_axis_style_t x_style, int srate, show_axes_t axes, printing_t printing, with_x_axis_t show_x_axis, with_grid_t with_grid, log_axis_t log_axes, mus_float_t grid_scale) { int width, height; int axis_thickness, left_border_width, bottom_border_width, top_border_width, right_border_width, inner_border_width; int major_tick_length, minor_tick_length, x_tick_spacing, y_tick_spacing; bool include_x_label, include_x_ticks, include_x_tick_labels, include_y_ticks, include_y_tick_labels, include_grid; bool y_axis_linear = true, x_axis_linear = true, use_tiny_font = false; int x_label_width, x_label_height, x_number_height; int num_ticks; tick_descriptor *tdx = NULL, *tdy = NULL; int curx, cury; graphics_context *ax; #if HAVE_GL mus_float_t xthick, ythick, xmajorlen, xminorlen, ymajorlen, yminorlen; #endif ax = ap->ax; width = ap->width; height = ap->height; ap->graph_active = ((width > 4) || (height > 10)); include_grid = ((ap->cp) && (with_grid)); if ((axes == SHOW_NO_AXES) || (width < 40) || (height < 40) || (ap->xmax == 0.0)) { /* leave it set up for bare graph */ if (height > 100) { ap->y_axis_y0 = ap->y_offset + height - 20; ap->y_axis_y1 = ap->y_offset + 10; } else { ap->y_axis_y0 = ap->y_offset + (int)(0.8 * height); ap->y_axis_y1 = ap->y_offset + (int)(0.1 * height); } if (width > 100) { ap->x_axis_x1 = ap->graph_x0 + width - 10; ap->x_axis_x0 = ap->graph_x0 + 20; } else { ap->x_axis_x1 = ap->graph_x0 + (int)(0.9 * width); ap->x_axis_x0 = ap->graph_x0 + (int)(0.2 * width); } init_axis_scales(ap); return; } left_border_width = 10; #if USE_MOTIF bottom_border_width = 10; #else bottom_border_width = 8; #endif top_border_width = 10; right_border_width = 14; inner_border_width = 5; x_tick_spacing = 20; if (width < 250) x_tick_spacing = 10 + (width / 25); y_tick_spacing = 20; if (height < 250) y_tick_spacing = 10 + (height / 25); if ((height < 100) || (width < 100)) { major_tick_length = 4; minor_tick_length = 2; } else { major_tick_length = 9; minor_tick_length = 5; } axis_thickness = 2; #if HAVE_GL xthick = (mus_float_t)(2 * axis_thickness) / (mus_float_t)height; ythick = (mus_float_t)(2 * axis_thickness) / (mus_float_t)width; xmajorlen = (mus_float_t)(2 * major_tick_length) / (mus_float_t)height; xminorlen = (mus_float_t)(2 * minor_tick_length) / (mus_float_t)height; ymajorlen = (mus_float_t)(2 * major_tick_length) / (mus_float_t)width; yminorlen = (mus_float_t)(2 * minor_tick_length) / (mus_float_t)width; #endif if (show_x_axis) { if (axes == SHOW_BARE_X_AXIS) { include_x_label = false; include_x_tick_labels = false; include_x_ticks = false; } else { if ((axes == SHOW_X_AXIS_UNLABELLED) || (axes == SHOW_ALL_AXES_UNLABELLED)) include_x_label = false; else include_x_label = ((ap->xlabel) && ((height > 100) && (width > 100))); include_x_tick_labels = ((height > 60) && (width > 100)); include_x_ticks = ((height > 40) && (width > 40)); } } else { include_x_label = false; include_x_tick_labels = false; include_x_ticks = false; } if (log_axes == WITH_LOG_X_AXIS) x_axis_linear = false; if ((axes != SHOW_X_AXIS) && (axes != SHOW_X_AXIS_UNLABELLED)) { include_y_tick_labels = ((width > 100) && (height > 60)); include_y_ticks = ((width > 100) && (height > 40)); } else { include_y_tick_labels = false; include_y_ticks = false; } if (log_axes == WITH_LOG_Y_AXIS) y_axis_linear = false; curx = left_border_width; cury = height - bottom_border_width; use_tiny_font = ((width < 250) || (height < 140)); x_number_height = number_height((use_tiny_font) ? TINY_FONT(ss) : AXIS_NUMBERS_FONT(ss)); x_label_height = 0; x_label_width = 0; if (include_x_label) { x_label_width = label_width(ap->xlabel, use_tiny_font); if ((x_label_width + curx + right_border_width) > width) { include_x_label = false; x_label_width = 0; x_label_height = 0; } else x_label_height = label_height(use_tiny_font); } else { if (include_x_ticks) x_label_height = label_height(use_tiny_font); /* bare x axis case handled later */ } if (y_axis_linear) { if (include_y_ticks) { /* figure out how long the longest tick label will be and make room for it */ /* values go from ap->y0 to ap->y1 */ /* basic tick spacing is tick_spacing pixels */ num_ticks = cury / y_tick_spacing; /* ticks start and stop at 10-based locations (i.e. sloppy axis bounds) */ /* so, given the current min..max, find the pretty min..max for ticks */ if (ap->y1 <= ap->y0) { if (ap->y0 != 0.0) ap->y1 = ap->y0 * 1.25; else ap->y1 = 1.0; } tdy = describe_ticks(ap->y_ticks, ap->y0, ap->y1, num_ticks, grid_scale); ap->y_ticks = tdy; if (include_y_tick_labels) { int tick_label_width; if (tdy->min_label) { free(tdy->min_label); tdy->min_label = NULL; } tdy->min_label = prettyf(tdy->mlo, tdy->tens); tdy->min_label_width = number_width(tdy->min_label, use_tiny_font); if (tdy->max_label) { free(tdy->max_label); tdy->max_label = NULL; } tdy->max_label = prettyf(tdy->mhi, tdy->tens); tdy->max_label_width = number_width(tdy->max_label, use_tiny_font); tick_label_width = tdy->min_label_width; if (tick_label_width < tdy->max_label_width) tick_label_width = tdy->max_label_width; if (((curx + tick_label_width) > (int)(.61 * width)) || ((4 * x_number_height) > height)) include_y_tick_labels = false; else curx += tick_label_width; } curx += major_tick_length; tdy->maj_tick_len = major_tick_length; tdy->min_tick_len = minor_tick_length; ap->y_axis_y1 = top_border_width; } else ap->y_axis_y1 = 0; } else { /* log case */ if (include_y_tick_labels) curx += number_width("10000", use_tiny_font); curx += major_tick_length; ap->y_axis_y1 = include_y_ticks ? top_border_width : 0; } ap->x_axis_x1 = width - right_border_width; ap->x_axis_x0 = curx; if (ap->x1 <= ap->x0) { if (ap->x0 != 0.0) ap->x1 = ap->x0 * 1.25; else ap->x1 = .1; } if ((x_axis_linear) && (include_x_ticks)) { num_ticks = (ap->x_axis_x1 - curx) / x_tick_spacing; switch (x_style) { case X_AXIS_AS_CLOCK: case X_AXIS_IN_SECONDS: default: tdx = describe_ticks(ap->x_ticks, ap->x0, ap->x1, num_ticks, grid_scale); break; case X_AXIS_IN_SAMPLES: tdx = describe_ticks(ap->x_ticks, ap->x0 * srate, ap->x1 * srate, num_ticks, grid_scale); break; case X_AXIS_IN_BEATS: case X_AXIS_IN_MEASURES: if (ap->cp) /* cp==null probably can't happen -- ap->cp is null (only?) if we're called from the envelope editor */ { mus_float_t beats_per_second; beats_per_second = ap->cp->beats_per_minute / 60.0; tdx = describe_ticks(ap->x_ticks, ap->x0 * beats_per_second, ap->x1 * beats_per_second, num_ticks, grid_scale); /* here we are getting the intra-beat settings, if x-axis-in-measures */ } else tdx = describe_ticks(ap->x_ticks, ap->x0, ap->x1, num_ticks, grid_scale); break; /* measure-positions or some such list could use marks */ case X_AXIS_AS_PERCENTAGE: tdx = describe_ticks(ap->x_ticks, ap->x0 / ap->xmax, ap->x1 / ap->xmax, num_ticks, grid_scale); break; } ap->x_ticks = tdx; if (include_x_tick_labels) { int tick_label_width; if (tdx->min_label) { free(tdx->min_label); tdx->min_label = NULL; } tdx->min_label = location_to_string(tdx->mlo, x_style, (ap->cp) ? (ap->cp->beats_per_measure) : 1, tdx->tens); tdx->min_label_width = number_width(tdx->min_label, use_tiny_font); if (tdx->max_label) { free(tdx->max_label); tdx->max_label = NULL; } tdx->max_label = location_to_string(tdx->mhi, x_style, (ap->cp) ? (ap->cp->beats_per_measure) : 1, tdx->tens); tdx->max_label_width = number_width(tdx->max_label, use_tiny_font); tick_label_width = tdx->min_label_width; if (tick_label_width < tdx->max_label_width) tick_label_width = tdx->max_label_width; if ((curx + 2 * tick_label_width) > (int)(.61 * width)) include_x_tick_labels = false; } tdx->maj_tick_len = major_tick_length; tdx->min_tick_len = minor_tick_length; } if ((include_x_label) || (include_x_tick_labels)) { ap->x_label_y = cury; ap->x_label_x = (curx + width - x_label_width) / 2; cury -= (x_label_height + inner_border_width); } else { if (axes == SHOW_BARE_X_AXIS) cury -= (label_height(false) + inner_border_width); } ap->y_axis_y0 = cury; ap->y_axis_x0 = curx; ap->y_axis_x0 += ap->graph_x0; ap->x_axis_x0 += ap->graph_x0; ap->x_axis_x1 += ap->graph_x0; ap->x_label_x += ap->graph_x0; ap->x_axis_y0 = cury; /* now if y_offset is in use, apply global shift in y direction */ ap->x_axis_y0 += ap->y_offset; ap->y_axis_y0 += ap->y_offset; ap->y_axis_y1 += ap->y_offset; ap->x_label_y += ap->y_offset; init_axis_scales(ap); if ((printing) && (ap->cp) && ((ap->cp->chan == 0) || (ap->cp->sound->channel_style != CHANNELS_SUPERIMPOSED))) ps_bg(ap, ax); #if HAVE_GL if (ap->use_gl) activate_gl_fonts(); ap->used_gl = ap->use_gl; #endif /* x axis label */ if (include_x_label) { set_labels_font(ax, printing, use_tiny_font); #if HAVE_GL if (ap->use_gl) { mus_float_t yl; yl = -0.5 - xthick - ((mus_float_t)(4 * major_tick_length + x_label_height) / (mus_float_t)height); glColor3f(0.0, 0.0, 0.0); glRasterPos3f(-0.1, 0.0, yl); glListBase(label_base); #if WITH_GL2PS if (ss->gl_printing) gl2ps_text(ap->xlabel); #endif glCallLists(mus_strlen(ap->xlabel), GL_UNSIGNED_BYTE, (GLubyte *)(ap->xlabel)); } else #endif { draw_label(ap->xlabel, ap->x_label_x, ap->x_label_y + inner_border_width, x_label_height, ap, ax, printing); } } /* x axis */ if (show_x_axis) { #if HAVE_GL if (ap->use_gl) { glBegin(GL_POLYGON); glColor3f(0.0, 0.0, 0.0); glVertex3f(-0.501 - ythick, 0.0, -0.501 - xthick); glVertex3f(0.50, 0.0, -0.501 - xthick); glVertex3f(0.50, 0.0, -0.501); glVertex3f(-0.501 - ythick, 0.0, -0.501); glEnd(); } else #endif { fill_rectangle(ax, ap->x_axis_x0, ap->x_axis_y0, (unsigned int)(ap->x_axis_x1 - ap->x_axis_x0), axis_thickness); } } /* y axis */ if ((axes != SHOW_X_AXIS) && (axes != SHOW_X_AXIS_UNLABELLED)) { #if HAVE_GL if (ap->use_gl) { glBegin(GL_POLYGON); glColor3f(0.0, 0.0, 0.0); glVertex3f(-0.501 - ythick, 0.0, -0.501 - xthick); glVertex3f(-0.501, 0.0, -0.501 - xthick); glVertex3f(-0.501, 0.0, 0.50); glVertex3f(-0.501 - ythick, 0.0, 0.50); glEnd(); /* draw rotated text here doesn't look very good -- the code in Mesa/progs/xdemos/xrotfontdemo.c uses * Mesa/progs/xdemos/xuserotfont.c which first sets up a bitmap very much like rotate_text in snd-xutils.c * then code much like the x axis label drawer above. */ } else #endif { #if (!USE_NO_GUI) if ((ap->cp) && (ap->ylabel) && (include_y_tick_labels)) { int y_label_width = 0; y_label_width = label_width(ap->ylabel, use_tiny_font); if ((ap->y_axis_y0 - ap->y_axis_y1) > (y_label_width + 20)) draw_rotated_axis_label(ap->cp, ax, ap->ylabel, (tdy) ? #if USE_GTK (ap->y_axis_x0 - tdy->maj_tick_len - tdy->min_label_width - inner_border_width - 10) : #else (ap->y_axis_x0 - tdy->maj_tick_len - tdy->min_label_width - inner_border_width) : #endif (ap->y_axis_x0 - inner_border_width - 30), /* tdy might be null if not y_axis_linear (sonogram + log-freq + y axis label) */ (int)((ap->y_axis_y0 + ap->y_axis_y1 - y_label_width) * 0.5) - 8); } #endif fill_rectangle(ax, ap->y_axis_x0, ap->y_axis_y1, axis_thickness, (unsigned int)(ap->y_axis_y0 - ap->y_axis_y1)); } } if (printing) { if (show_x_axis) ps_fill_rectangle(ap, ap->x_axis_x0, ap->x_axis_y0, ap->x_axis_x1 - ap->x_axis_x0, axis_thickness); if ((axes != SHOW_X_AXIS) && (axes != SHOW_X_AXIS_UNLABELLED)) ps_fill_rectangle(ap, ap->y_axis_x0, ap->y_axis_y1, axis_thickness, ap->y_axis_y0 - ap->y_axis_y1); } /* linear axis ticks/labels */ if ((include_y_tick_labels) || (include_x_tick_labels)) set_numbers_font(ax, printing, use_tiny_font); if ((y_axis_linear) && (include_y_tick_labels)) { #if HAVE_GL if (ap->use_gl) { mus_float_t xl; xl = -0.5 - ythick - ((mus_float_t)(3 * tdy->maj_tick_len + tdy->min_label_width + inner_border_width) / (mus_float_t)width); glRasterPos3f(xl, 0.0, (tdy->mlo - ap->y0) / (ap->y1 - ap->y0) - 0.51); glListBase(number_base); #if WITH_GL2PS if (ss->gl_printing) gl2ps_text(tdy->min_label); #endif glCallLists(mus_strlen(tdy->min_label), GL_UNSIGNED_BYTE, (GLubyte *)(tdy->min_label)); xl = -0.5 - ythick - ((mus_float_t)(3 * tdy->maj_tick_len + tdy->max_label_width + inner_border_width) / (mus_float_t)width); glRasterPos3f(xl, 0.0, (tdy->mhi - ap->y0) / (ap->y1 - ap->y0) - 0.51); glListBase(number_base); #if WITH_GL2PS if (ss->gl_printing) gl2ps_text(tdy->max_label); #endif glCallLists(mus_strlen(tdy->max_label), GL_UNSIGNED_BYTE, (GLubyte *)(tdy->max_label)); } else #endif { /* y axis numbers */ draw_y_number(tdy->min_label, ap->y_axis_x0 - tdy->maj_tick_len - tdy->min_label_width - inner_border_width, grf_y(tdy->mlo, ap), x_number_height, ap, ax, printing); draw_y_number(tdy->max_label, ap->y_axis_x0 - tdy->maj_tick_len - tdy->max_label_width - inner_border_width, grf_y(tdy->mhi, ap), x_number_height, ap, ax, printing); } } if ((x_axis_linear) && (include_x_tick_labels)) { int lx0, lx1, tx0, tx1; /* the label is at ap->x_label_x to that plus x_label_width */ /* the number label widths are tdx->max|min_label_width */ lx0 = ap->x_label_x; lx1 = lx0 + x_label_width; tx0 = (int)(tick_grf_x(tdx->mlo, ap, x_style, srate) - .45 * tdx->min_label_width); tx1 = tx0 + tdx->min_label_width; if ((lx0 > tx1) || (lx1 < tx0)) { #if HAVE_GL if (ap->use_gl) { mus_float_t yl; yl = -0.5 - xthick - ((mus_float_t)(3 * major_tick_length + x_number_height + inner_border_width) / (mus_float_t)height); glRasterPos3f((tdx->mlo - ap->x0) / (ap->x1 - ap->x0) - 0.53, 0.0, yl); glListBase(number_base); #if WITH_GL2PS if (ss->gl_printing) gl2ps_text(tdx->min_label); #endif glCallLists(mus_strlen(tdx->min_label), GL_UNSIGNED_BYTE, (GLubyte *)(tdx->min_label)); } else #endif { /* x axis min label */ draw_x_number(tdx->min_label, tx0, ap->x_axis_y0 + major_tick_length, x_number_height, ap, ax, printing); } } tx0 = (int)(tick_grf_x(tdx->mhi, ap, x_style, srate) - (.45 * tdx->max_label_width)); /* try centered label first */ if ((int)(tx0 + tdx->max_label_width) > ap->x_axis_x1) tx0 = (int)(tick_grf_x(tdx->mhi, ap, x_style, srate) - tdx->max_label_width + .75 * right_border_width); tx1 = tx0 + tdx->max_label_width; if ((lx0 > tx1) || (lx1 < tx0)) { #if HAVE_GL if (ap->use_gl) { mus_float_t yl; yl = -0.5 - xthick - ((mus_float_t)(3 * major_tick_length + x_number_height + inner_border_width) / (mus_float_t)height); glRasterPos3f((tdx->mhi - ap->x0) / (ap->x1 - ap->x0) - 0.53, 0.0, yl); glListBase(number_base); #if WITH_GL2PS if (ss->gl_printing) gl2ps_text(tdx->max_label); #endif glCallLists(mus_strlen(tdx->max_label), GL_UNSIGNED_BYTE, (GLubyte *)(tdx->max_label)); } else #endif { /* x axis max label */ draw_x_number(tdx->max_label, tx0, ap->x_axis_y0 + major_tick_length, x_number_height, ap, ax, printing); } } } if ((y_axis_linear) && (include_y_ticks)) { double fy, tens; int ty, x0, majx, minx, x; /* start ticks at flo, go to fhi by step, major ticks at mlo mhi and intervals of tenstep surrounding */ x0 = ap->y_axis_x0; majx = x0 - tdy->maj_tick_len; minx = x0 - tdy->min_tick_len; fy = tdy->mlo; ty = grf_y(fy, ap); #if HAVE_GL if (ap->use_gl) { mus_float_t ypos; ypos = (fy - ap->y0) / (ap->y1 - ap->y0) - 0.5; glBegin(GL_LINES); glVertex3f(-0.50 - ymajorlen, 0.0, ypos); glVertex3f(-0.501, 0.0, ypos); glEnd(); } else #endif { draw_horizontal_tick(majx, x0, ty, ap, ax, printing, include_grid); } tens = 0.0; fy -= tdy->step; while (fy >= tdy->flo) { tens += tdy->tenstep; if (tens == 10.0) { tens = 0.0; x = majx; } else x = minx; ty = grf_y(fy, ap); #if HAVE_GL if (ap->use_gl) { mus_float_t ypos; ypos = (fy - ap->y0) / (ap->y1 - ap->y0) - 0.5; glBegin(GL_LINES); glVertex3f(-0.50 - ((x == majx) ? ymajorlen : yminorlen), 0.0, ypos); glVertex3f(-0.501, 0.0, ypos); glEnd(); } else #endif { draw_horizontal_tick(x, x0, ty, ap, ax, printing, include_grid); } fy -= tdy->step; } tens = 0.0; fy = tdy->mlo; fy += tdy->step; while (fy <= tdy->fhi) { tens += tdy->tenstep; if (tens == 10.0) { tens = 0.0; x = majx; } else x = minx; ty = grf_y(fy, ap); #if HAVE_GL if (ap->use_gl) { mus_float_t ypos; ypos = (fy - ap->y0) / (ap->y1 - ap->y0) - 0.5; glBegin(GL_LINES); glVertex3f(-0.50 - ((x == majx) ? ymajorlen : yminorlen), 0.0, ypos); glVertex3f(-0.501, 0.0, ypos); glEnd(); } else #endif { draw_horizontal_tick(x, x0, ty, ap, ax, printing, include_grid); } fy += tdy->step; } } if ((x_axis_linear) && (include_x_ticks)) { bool major_tick_is_less_than_measure = false; double fx, tens; int tx, y0, majy, miny, y; y0 = ap->x_axis_y0; majy = y0 + tdx->maj_tick_len; miny = y0 + tdx->min_tick_len; /* start at leftmost major tick and work toward y axis */ fx = tdx->mlo; tx = tick_grf_x(fx, ap, x_style, srate); if ((ap->cp) && (x_style == X_AXIS_IN_MEASURES) && ((tdx->tenstep * tdx->step) <= ((60.0 * ap->cp->beats_per_measure) / (mus_float_t)(ap->cp->beats_per_minute)))) major_tick_is_less_than_measure = true; #if HAVE_GL if (ap->use_gl) { mus_float_t xpos; xpos = (fx - ap->x0) / (ap->x1 - ap->x0) - 0.5; glBegin(GL_LINES); glVertex3f(xpos, 0.0, -0.50 - xmajorlen); glVertex3f(xpos, 0.0, -0.501); glEnd(); } else #endif { if ((major_tick_is_less_than_measure) && (first_beat(ap->cp, fx))) draw_vertical_tick(tx, y0 - major_tick_length, majy + minor_tick_length, ap, ax, printing, include_grid); else draw_vertical_tick(tx, y0, majy, ap, ax, printing, include_grid); } tens = 0.0; fx -= tdx->step; while (fx >= tdx->flo) { tens += tdx->tenstep; if (tens == 10.0) { tens = 0.0; y = majy; } else y = miny; tx = tick_grf_x(fx, ap, x_style, srate); #if HAVE_GL if (ap->use_gl) { mus_float_t xpos; xpos = (fx - ap->x0) / (ap->x1 - ap->x0) - 0.5; glBegin(GL_LINES); glVertex3f(xpos, 0.0, -0.50 - ((y == majy) ? xmajorlen : xminorlen)); glVertex3f(xpos, 0.0, -0.501); glEnd(); } else #endif { if ((major_tick_is_less_than_measure) && (first_beat(ap->cp, fx))) draw_vertical_tick(tx, y0 - major_tick_length, y + minor_tick_length, ap, ax, printing, include_grid); else draw_vertical_tick(tx, y0, y, ap, ax, printing, include_grid); } fx -= tdx->step; } tens = 0.0; fx = tdx->mlo; /* now start at leftmost major tick and work towards right end */ fx += tdx->step; while (fx <= tdx->fhi) { tens += tdx->tenstep; if (tens == 10.0) { tens = 0.0; y = majy; } else y = miny; tx = tick_grf_x(fx, ap, x_style, srate); #if HAVE_GL if (ap->use_gl) { mus_float_t xpos; xpos = (fx - ap->x0) / (ap->x1 - ap->x0) - 0.5; glBegin(GL_LINES); glVertex3f(xpos, 0.0, -0.50 - ((y == majy) ? xmajorlen : xminorlen)); glVertex3f(xpos, 0.0, -0.501); glEnd(); } else #endif { if ((major_tick_is_less_than_measure) && (first_beat(ap->cp, fx))) draw_vertical_tick(tx, y0 - major_tick_length, y + minor_tick_length, ap, ax, printing, include_grid); else draw_vertical_tick(tx, y0, y, ap, ax, printing, include_grid); } fx += tdx->step; } } /* All linear axis stuff has been taken care of. Check for log axes (assume fft context, not spectrogram so no GL) */ /* x axis overall label has already gone out */ if ((!x_axis_linear) && (show_x_axis) && (include_x_ticks)) { double min_freq, max_freq; mus_float_t minlx = 0.0, maxlx, fap_range, log_range, lscale = 1.0, curlx; int logx; int y0, majy, miny, i; const char *label = NULL; mus_float_t freq = 0.0, freq10 = 0.0; /* get min (log-freq or spectrum-start), max, add major ticks and brief labels, then if room add log-style minor ticks (100's, 1000's) */ y0 = ap->x_axis_y0; majy = y0 + major_tick_length; miny = y0 + minor_tick_length; min_freq = ap->x0; max_freq = ap->x1; if (include_x_tick_labels) set_numbers_font(ax, printing, use_tiny_font); fap_range = max_freq - min_freq; if (min_freq > 1.0) minlx = log(min_freq); else minlx = 0.0; maxlx = log(max_freq); log_range = (maxlx - minlx); lscale = fap_range / log_range; for (i = 0; i < 3; i++) { switch (i) { case 0: label = "100"; freq = 100.0; break; case 1: label = "1000"; freq = 1000.0; break; case 2: label = "10000"; freq = 10000.0; break; } if ((min_freq <= freq) && (max_freq >= freq)) { /* draw major tick at freq */ freq10 = freq / 10.0; logx = grf_x(min_freq + lscale * (log(freq) - minlx), ap); draw_vertical_tick(logx, y0, majy, ap, ax, printing, include_grid); draw_log_tick_label(label, logx, ap->x_axis_y0 + major_tick_length, x_number_height, x_label_width, right_border_width, ap, ax, printing, use_tiny_font); if (width > 200) { curlx = snd_round(min_freq / freq10) * freq10; for (; curlx < freq; curlx += freq10) { logx = grf_x(min_freq + lscale * (log(curlx) - minlx), ap); draw_vertical_tick(logx, y0, miny, ap, ax, printing, include_grid); } } } } } if ((!y_axis_linear) && (axes != SHOW_X_AXIS) && (axes != SHOW_X_AXIS_UNLABELLED) && (include_y_ticks)) { double min_freq, max_freq; mus_float_t minlx = 0.0, maxlx, fap_range, log_range, lscale = 1.0, curly; int logy; int x0, majx, minx, i; const char *label = NULL; mus_float_t freq = 0.0, freq10 = 0.0; /* get min (log-freq or spectrum-start), max, add major ticks and brief labels, then if room add log-style minor ticks (100's, 1000's) */ x0 = ap->y_axis_x0; majx = x0 - major_tick_length; minx = x0 - minor_tick_length; min_freq = ap->y0; max_freq = ap->y1; if (include_y_tick_labels) set_numbers_font(ax, printing, use_tiny_font); fap_range = max_freq - min_freq; if (min_freq > 1.0) minlx = log(min_freq); else minlx = 0.0; maxlx = log(max_freq); log_range = (maxlx - minlx); lscale = fap_range / log_range; for (i = 0; i < 3; i++) { switch (i) { case 0: label = "100"; freq = 100.0; break; case 1: label = "1000"; freq = 1000.0; break; case 2: label = "10000"; freq = 10000.0; break; } if ((min_freq <= freq) && (max_freq >= freq)) { /* draw major tick at freq */ freq10 = freq / 10.0; logy = grf_y(min_freq + lscale * (log(freq) - minlx), ap); draw_horizontal_tick(majx, x0, logy, ap, ax, printing, include_grid); if (include_y_tick_labels) { int label_width; label_width = number_width(label, use_tiny_font); /* y axis number */ draw_y_number(label, ap->y_axis_x0 - major_tick_length - label_width - inner_border_width, logy, x_number_height, ap, ax, printing); } if (height > 200) { curly = snd_round(min_freq / freq10) * freq10; for (; curly < freq; curly += freq10) { logy = grf_y(min_freq + lscale * (log(curly) - minlx), ap); draw_horizontal_tick(minx, x0, logy, ap, ax, printing, include_grid); } } } } } } axis_info *make_axis_info (chan_info *cp, double xmin, double xmax, mus_float_t ymin, mus_float_t ymax, const char *xlabel, double x0, double x1, mus_float_t y0, mus_float_t y1, axis_info *old_ap) { axis_info *ap; if (old_ap) ap = old_ap; else { ap = (axis_info *)calloc(1, sizeof(axis_info)); ap->cp = cp; } ap->xmin = xmin; ap->xmax = xmax; if (ap->xmin == ap->xmax) ap->xmax += .001; ap->ymin = ymin; ap->ymax = ymax; if ((xlabel) && (!(mus_strcmp(xlabel, ap->xlabel)))) { /* this apparently should leave the default_xlabel and ylabels alone */ if (ap->xlabel) free(ap->xlabel); ap->xlabel = mus_strdup(xlabel); } ap->x0 = x0; ap->x1 = x1; if (ap->x0 == ap->x1) ap->x1 += .001; if (ap->x1 > ap->xmax) ap->x1 = ap->xmax; ap->y0 = y0; ap->y1 = y1; ap->y_offset = 0; ap->y_ambit = ap->ymax - ap->ymin; ap->x_ambit = ap->xmax - ap->xmin; return(ap); } #if (!USE_NO_GUI) static axis_info *get_ap(chan_info *cp, axis_info_t ap_id, const char *caller) { #define AXIS_INFO_ID_OK(Id) (Id <= (int)LISP_AXIS_INFO) if (AXIS_INFO_ID_OK(ap_id)) switch (ap_id) { case TIME_AXIS_INFO: return(cp->axis); break; case TRANSFORM_AXIS_INFO: if (cp->fft) return(cp->fft->axis); break; case LISP_AXIS_INFO: if (cp->lisp_info) return(lisp_info_axis(cp)); break; } Xen_error(Xen_make_error_type("no-such-axis"), Xen_list_6(((!(cp->squelch_update)) || (!(AXIS_INFO_ID_OK(ap_id)))) ? C_string_to_Xen_string("~A: no such axis: ~A of sound ~A (~A), chan: ~A (axis should be " S_time_graph ", " S_lisp_graph ", or " S_transform_graph ")") : C_string_to_Xen_string("~A: no such axis: ~A of sound ~A (~A), chan: ~A does not exist, probably because output is squelched"), C_string_to_Xen_string(caller), C_int_to_Xen_integer((int)(ap_id)), C_int_to_Xen_sound(cp->sound->index), C_string_to_Xen_string(cp->sound->short_filename), C_int_to_Xen_integer(cp->chan))); return(NULL); } #define TO_C_AXIS_INFO(Snd, Chn, Ap, Caller) get_ap(get_cp(Snd, Chn, Caller), (Xen_is_integer(Ap)) ? (axis_info_t)Xen_integer_to_C_int(Ap) : TIME_AXIS_INFO, Caller) static Xen g_x_to_position(Xen val, Xen snd, Xen chn, Xen ap) { #define H_x_to_position "(" S_x_to_position " val :optional snd chn (ax " S_time_graph ")): x pixel loc of val" Xen_check_type(Xen_is_number(val), val, 1, S_x_to_position, "a number"); Snd_assert_channel(S_x_to_position, snd, chn, 2); Xen_check_type(Xen_is_integer_or_unbound(ap), ap, 4, S_x_to_position, S_time_graph ", " S_transform_graph ", or " S_lisp_graph); return(C_int_to_Xen_integer(grf_x(Xen_real_to_C_double(val), TO_C_AXIS_INFO(snd, chn, ap, S_x_to_position)))); } static Xen g_y_to_position(Xen val, Xen snd, Xen chn, Xen ap) { #define H_y_to_position "(" S_y_to_position " val :optional snd chn (ax " S_time_graph ")): y pixel loc of val" Xen_check_type(Xen_is_number(val), val, 1, S_y_to_position, "a number"); Snd_assert_channel(S_y_to_position, snd, chn, 2); Xen_check_type(Xen_is_integer_or_unbound(ap), ap, 4, S_y_to_position, S_time_graph ", " S_transform_graph ", or " S_lisp_graph); return(C_int_to_Xen_integer(grf_y(Xen_real_to_C_double(val), TO_C_AXIS_INFO(snd, chn, ap, S_y_to_position)))); } static Xen g_position_to_x(Xen val, Xen snd, Xen chn, Xen ap) { #define H_position_to_x "(" S_position_to_x " val :optional snd chn (ax " S_time_graph ")): x axis value corresponding to pixel val" Xen_check_type(Xen_is_integer(val), val, 1, S_position_to_x, "an integer"); Snd_assert_channel(S_position_to_x, snd, chn, 2); Xen_check_type(Xen_is_integer_or_unbound(ap), ap, 4, S_position_to_x, S_time_graph ", " S_transform_graph ", or " S_lisp_graph); return(C_double_to_Xen_real(ungrf_x(TO_C_AXIS_INFO(snd, chn, ap, S_position_to_x), Xen_integer_to_C_int(val)))); } static Xen g_position_to_y(Xen val, Xen snd, Xen chn, Xen ap) { #define H_position_to_y "(" S_position_to_y " val :optional snd chn (ax " S_time_graph ")): y axis value corresponding to pixel val" Xen_check_type(Xen_is_integer(val), val, 1, S_position_to_y, "an integer"); Snd_assert_channel(S_position_to_y, snd, chn, 2); Xen_check_type(Xen_is_integer_or_unbound(ap), ap, 4, S_position_to_y, S_time_graph ", " S_transform_graph ", or " S_lisp_graph); return(C_double_to_Xen_real(ungrf_y(TO_C_AXIS_INFO(snd, chn, ap, S_position_to_y), Xen_integer_to_C_int(val)))); } static Xen g_axis_info(Xen snd, Xen chn, Xen ap_id) { #define H_axis_info "(" S_axis_info " :optional snd chn (ax " S_time_graph ")): info about axis: (list losamp hisamp \ x0 y0 x1 y1 xmin ymin xmax ymax pix_x0 pix_y0 pix_x1 pix_y1 y_offset xscale yscale xlabel ylabel new-peaks)" axis_info *ap; Snd_assert_channel(S_axis_info, snd, chn, 1); Xen_check_type(Xen_is_integer_or_unbound(ap_id), ap_id, 3, S_axis_info, S_time_graph ", " S_transform_graph ", or " S_lisp_graph); ap = TO_C_AXIS_INFO(snd, chn, ap_id, S_axis_info); if (ap == NULL) return(Xen_empty_list); return(Xen_cons(C_llong_to_Xen_llong(ap->losamp), Xen_cons(C_llong_to_Xen_llong(ap->hisamp), Xen_cons(C_double_to_Xen_real(ap->x0), Xen_cons(C_double_to_Xen_real(ap->y0), Xen_cons(C_double_to_Xen_real(ap->x1), Xen_cons(C_double_to_Xen_real(ap->y1), Xen_cons(C_double_to_Xen_real(ap->xmin), Xen_cons(C_double_to_Xen_real(ap->ymin), Xen_cons(C_double_to_Xen_real(ap->xmax), Xen_cons(C_double_to_Xen_real(ap->ymax), Xen_cons(C_int_to_Xen_integer(ap->x_axis_x0), Xen_cons(C_int_to_Xen_integer(ap->y_axis_y0), Xen_cons(C_int_to_Xen_integer(ap->x_axis_x1), Xen_cons(C_int_to_Xen_integer(ap->y_axis_y1), Xen_cons(C_int_to_Xen_integer(ap->y_offset), Xen_cons(C_double_to_Xen_real(ap->x_scale), Xen_cons(C_double_to_Xen_real(ap->y_scale), Xen_cons((ap->xlabel) ? C_string_to_Xen_string(ap->xlabel) : Xen_false, Xen_cons((ap->ylabel) ? C_string_to_Xen_string(ap->ylabel) : Xen_false, Xen_cons((ap->cp) ? C_bool_to_Xen_boolean(ap->cp->new_peaks) : Xen_false, Xen_empty_list))))))))))))))))))))); } #if USE_MOTIF #define Xen_unwrap_snd_gc(Value) Xen_unwrap_C_pointer(Xen_cadr(Value)) #define Xen_is_GC(Value) (Xen_is_list(Value) && (Xen_list_length(Value) >= 2) && \ (Xen_is_symbol(Xen_car(Value))) && \ (strcmp("GC", Xen_symbol_to_C_string(Xen_car(Value))) == 0)) #else #if USE_GTK #define Xen_unwrap_snd_gc(Value) (gc_t *)(Xen_unwrap_C_pointer(Xen_cadr(Value))) #define Xen_is_GC(Value) (Xen_is_list(Value) && (Xen_list_length(Value) >= 2) && \ (Xen_is_symbol(Xen_car(Value))) && \ (strcmp("gc_t_", Xen_symbol_to_C_string(Xen_car(Value))) == 0)) #else #define Xen_unwrap_snd_gc(Value) 0 #define Xen_is_GC(Value) 0 #endif #endif static Xen g_draw_axes(Xen args) { #define H_draw_axes "(" S_draw_axes " wid gc label (x0 0.0) (x1 1.0) (y0 -1.0) (y1 1.0) (style " S_x_axis_in_seconds ") (axes " S_show_all_axes ")): \ draws axes in the widget 'wid', using the graphics context 'gc', with the x-axis label 'label' \ going from x0 to x1 (floats) along the x axis, y0 to y1 along the y axis, with " S_x_axis_style " \ 'style' (" S_x_axis_in_seconds " etc); the axes are actually displayed if 'axes' is " S_show_all_axes ". \ Returns actual (pixel) axis bounds -- a list (x0 y0 x1 y1)." #if USE_MOTIF Widget w; GC gc; #endif #if USE_GTK GtkWidget *w; gc_t *gc; #endif Xen val, xwid, xgc, label_ref; double x0 = 0.0, x1 = 1.0; mus_float_t y0 = -1.0, y1 = 1.0; x_axis_style_t x_style = X_AXIS_IN_SECONDS; show_axes_t axes = SHOW_ALL_AXES; graphics_context *ax; axis_info *ap; int len; len = Xen_list_length(args); #if (!USE_GTK) Xen_check_type((len >= 3) && (len < 10), args, 1, S_draw_axes, "3 required and 6 optional args"); #else Xen_check_type((len >= 3) && (len < 11), args, 1, S_draw_axes, "3 required and 7 optional args"); #endif xwid = Xen_list_ref(args, 0); Xen_check_type(Xen_is_widget(xwid), xwid, 1, S_draw_axes, "widget"); xgc = Xen_list_ref(args, 1); Xen_check_type(Xen_is_GC(xgc), xgc, 2, S_draw_axes, "snd-gc"); #if USE_MOTIF w = (Widget)(Xen_unwrap_widget(xwid)); gc = (GC)(Xen_unwrap_snd_gc(xgc)); #endif #if USE_GTK w = (GtkWidget *)(Xen_unwrap_widget(xwid)); gc = (gc_t *)(Xen_unwrap_snd_gc(xgc)); #endif label_ref = Xen_list_ref(args, 2); Xen_check_type(Xen_is_string(label_ref) || Xen_is_false(label_ref), label_ref, 3, S_draw_axes, "a string"); if (len > 3) { Xen xx0; xx0 = Xen_list_ref(args, 3); Xen_check_type(Xen_is_number(xx0), xx0, 4, S_draw_axes, "a number"); x0 = Xen_real_to_C_double(xx0); if (len > 4) { Xen xx1; xx1 = Xen_list_ref(args, 4); Xen_check_type(Xen_is_number(xx1), xx1, 5, S_draw_axes, "a number"); x1 = Xen_real_to_C_double(xx1); if (len > 5) { Xen xy0; xy0 = Xen_list_ref(args, 5); Xen_check_type(Xen_is_number(xy0), xy0, 6, S_draw_axes, "a number"); y0 = Xen_real_to_C_double(xy0); if (len > 6) { Xen xy1; xy1 = Xen_list_ref(args, 6); Xen_check_type(Xen_is_number(xy1), xy1, 7, S_draw_axes, "a number"); y1 = Xen_real_to_C_double(xy1); if (len > 7) { Xen xstyle; int tmp; xstyle = Xen_list_ref(args, 7); Xen_check_type(Xen_is_integer(xstyle), xstyle, 8, S_draw_axes, "axis style"); tmp = Xen_integer_to_C_int(xstyle); if (!(is_x_axis_style(tmp))) Xen_out_of_range_error(S_draw_axes, 7, xstyle, "axis style"); x_style = (x_axis_style_t)tmp; if (len > 8) { Xen xaxes; xaxes = Xen_list_ref(args, 8); Xen_check_type(Xen_is_integer(xaxes), xaxes, 9, S_draw_axes, S_show_axes " choice"); tmp = Xen_integer_to_C_int(xaxes); if (!(shows_axes(tmp))) Xen_out_of_range_error(S_draw_axes, 8, xaxes, S_show_axes " choice"); axes = (show_axes_t)Xen_integer_to_C_int(xaxes); #if USE_GTK if (len > 9) ss->cr = (cairo_t *)Xen_unwrap_C_pointer(Xen_cadr(Xen_list_ref(args, 9))); #endif }}}}}} ap = (axis_info *)calloc(1, sizeof(axis_info)); ax = (graphics_context *)calloc(1, sizeof(graphics_context)); ap->ax = ax; #if USE_MOTIF ax->dp = XtDisplay(w); ax->wn = XtWindow(w); #endif #if USE_GTK ax->wn = WIDGET_TO_WINDOW(w); ax->w = w; if (!ss->cr) Xen_error(Xen_make_error_type("no-cairo-t"), Xen_list_1(C_string_to_Xen_string(S_draw_axes ": in Gtk, the trailing cairo_t argument is not optional"))); #endif ap->xmin = x0; ap->xmax = x1; ap->ymin = y0; ap->ymax = y1; ap->y_ambit = y1 - y0; ap->x_ambit = x1 - x0; if (Xen_is_string(label_ref)) ap->xlabel = mus_strdup(Xen_string_to_C_string(label_ref)); ap->x0 = x0; ap->x1 = x1; ap->y0 = y0; ap->y1 = y1; ap->width = widget_width(w); ap->window_width = ap->width; ap->y_offset = 0; ap->height = widget_height(w); ap->graph_x0 = 0; clear_window(ax); ax->gc = gc; make_axes_1(ap, x_style, 1, axes, NOT_PRINTING, WITH_X_AXIS, NO_GRID, WITH_LINEAR_AXES, grid_density(ss)); val = Xen_cons(C_int_to_Xen_integer(ap->x_axis_x0), Xen_cons(C_int_to_Xen_integer(ap->y_axis_y0), Xen_cons(C_int_to_Xen_integer(ap->x_axis_x1), Xen_cons(C_int_to_Xen_integer(ap->y_axis_y1), Xen_empty_list)))); free_axis_info(ap); return(val); } static Xen g_x_axis_label(Xen snd, Xen chn, Xen ax) { #define H_x_axis_label "(" S_x_axis_label " :optional snd chn (ax " S_time_graph ")): current x axis label" axis_info *ap; Snd_assert_channel(S_x_axis_label, snd, chn, 1); Xen_check_type(Xen_is_integer_or_unbound(ax), ax, 3, S_x_axis_label, S_time_graph ", " S_transform_graph ", or " S_lisp_graph); ap = TO_C_AXIS_INFO(snd, chn, ax, S_x_axis_label); return(C_string_to_Xen_string(ap->xlabel)); } static Xen g_set_x_axis_label(Xen label, Xen snd, Xen chn, Xen ax) { axis_info *ap; Snd_assert_channel(S_set S_x_axis_label, snd, chn, 2); Xen_check_type(Xen_is_string(label) || Xen_is_false(label), label, 1, S_set S_x_axis_label, "a string"); Xen_check_type(Xen_is_integer_or_unbound(ax), ax, 4, S_set S_x_axis_label, S_time_graph ", " S_transform_graph ", or " S_lisp_graph); ap = TO_C_AXIS_INFO(snd, chn, ax, S_x_axis_label); if (ap->xlabel) free(ap->xlabel); if (ap->default_xlabel) free(ap->default_xlabel); if (Xen_is_false(label)) { ap->xlabel = NULL; ap->default_xlabel = NULL; } else { ap->xlabel = mus_strdup(Xen_string_to_C_string(label)); if ((Xen_is_integer(ax)) && (Xen_integer_to_C_int(ax) == (int)TRANSFORM_AXIS_INFO)) set_fft_info_xlabel(ap->cp, ap->xlabel); ap->default_xlabel = mus_strdup(ap->xlabel); } update_graph(ap->cp); return(label); } with_four_setter_args(g_set_x_axis_label_reversed, g_set_x_axis_label) static Xen g_y_axis_label(Xen snd, Xen chn, Xen ax) { #define H_y_axis_label "(" S_y_axis_label " :optional snd chn (ax " S_time_graph ")): current y axis label" axis_info *ap; Snd_assert_channel(S_y_axis_label, snd, chn, 1); Xen_check_type(Xen_is_integer_or_unbound(ax), ax, 3, S_y_axis_label, S_time_graph ", " S_transform_graph ", or " S_lisp_graph); ap = TO_C_AXIS_INFO(snd, chn, ax, S_y_axis_label); return(C_string_to_Xen_string(ap->ylabel)); } static Xen g_set_y_axis_label(Xen label, Xen snd, Xen chn, Xen ax) { axis_info *ap; Snd_assert_channel(S_set S_y_axis_label, snd, chn, 2); Xen_check_type(Xen_is_string(label) || Xen_is_false(label), label, 1, S_set S_y_axis_label, "a string"); Xen_check_type(Xen_is_integer_or_unbound(ax), ax, 4, S_set S_y_axis_label, S_time_graph ", " S_transform_graph ", or " S_lisp_graph); ap = TO_C_AXIS_INFO(snd, chn, ax, S_y_axis_label); if (ap->ylabel) free(ap->ylabel); if (Xen_is_false(label)) ap->ylabel = NULL; else ap->ylabel = mus_strdup(Xen_string_to_C_string(label)); update_graph(ap->cp); return(label); } with_four_setter_args(g_set_y_axis_label_reversed, g_set_y_axis_label) static Xen g_x_bounds(Xen snd, Xen chn, Xen ax) { #define H_x_bounds "(" S_x_bounds " :optional snd chn axis): a list (x0 x1) giving the current x axis bounds of snd channel chn" axis_info *ap; Snd_assert_channel(S_x_bounds, snd, chn, 1); Xen_check_type(Xen_is_integer_or_unbound(ax), ax, 4, S_x_bounds, S_time_graph ", " S_transform_graph ", or " S_lisp_graph); ap = TO_C_AXIS_INFO(snd, chn, ax, S_x_bounds); return(Xen_list_2(C_double_to_Xen_real(ap->x0), C_double_to_Xen_real(ap->x1))); /* wavogram settings depend on context -- no easy way to map back to user's notion of bounds */ } static Xen g_set_x_bounds(Xen bounds, Xen snd, Xen chn, Xen ax) { chan_info *cp; axis_info *ap; mus_float_t x0 = 0.0, x1 = 0.0; Snd_assert_channel(S_set S_x_bounds, snd, chn, 2); Xen_check_type(Xen_is_number(bounds) || (Xen_is_list(bounds) && (Xen_list_length(bounds) == 2)), bounds, 1, S_set S_x_bounds, "a list: (x0 x1) or a number"); Xen_check_type(Xen_is_integer_or_unbound(ax), ax, 4, S_set S_x_bounds, S_time_graph ", " S_transform_graph ", or " S_lisp_graph); ap = TO_C_AXIS_INFO(snd, chn, ax, S_set S_x_bounds); cp = get_cp(snd, chn, S_set S_x_bounds); if (!cp) return(Xen_false); if (Xen_is_number(bounds)) { x0 = 0.0; x1 = Xen_real_to_C_double(bounds); } else { x0 = Xen_real_to_C_double(Xen_car(bounds)); x1 = Xen_real_to_C_double(Xen_cadr(bounds)); if (x1 < x0) Xen_out_of_range_error(S_set S_x_bounds, 1, bounds, "x1 < x0?"); } if (ap == cp->axis) { if (cp->time_graph_type == GRAPH_ONCE) { snd_info *sp; set_x_axis_x0x1(cp, x0, x1); sp = cp->sound; if (sp->nchans > 1) { if ((!Xen_is_bound(chn)) && (cp->sound->channel_style == CHANNELS_COMBINED)) { int i; for (i = 0; i < sp->nchans; i++) if (i != cp->chan) set_x_axis_x0x1(sp->chans[i], x0, x1); /* y-bounds are already tied together in the channels-combined case */ } } } } else { ap->x0 = x0; ap->x1 = x1; } return(bounds); } with_four_setter_args(g_set_x_bounds_reversed, g_set_x_bounds) static Xen g_y_bounds(Xen snd, Xen chn, Xen ax) { #define H_y_bounds "(" S_y_bounds " :optional snd chn axis): a list (y0 y1) giving the current y axis bounds of snd channel chn" axis_info *ap; Snd_assert_channel(S_y_bounds, snd, chn, 1); Xen_check_type(Xen_is_integer_or_unbound(ax), ax, 4, S_y_bounds, S_time_graph ", " S_transform_graph ", or " S_lisp_graph); ap = TO_C_AXIS_INFO(snd, chn, ax, S_y_bounds); return(Xen_list_2(C_double_to_Xen_real(ap->y0), C_double_to_Xen_real(ap->y1))); } static Xen g_set_y_bounds(Xen bounds, Xen snd, Xen chn, Xen ax) { chan_info *cp; axis_info *ap; mus_float_t low = 0.0, hi = 0.0; Xen y0 = Xen_undefined, y1 = Xen_undefined; Snd_assert_channel(S_set S_y_bounds, snd, chn, 2); Xen_check_type((Xen_is_number(bounds)) || (Xen_is_list(bounds)), bounds, 1, S_set S_y_bounds, "a list or a number"); Xen_check_type(Xen_is_integer_or_unbound(ax), ax, 4, S_set S_y_bounds, S_time_graph ", " S_transform_graph ", or " S_lisp_graph); ap = TO_C_AXIS_INFO(snd, chn, ax, S_set S_y_bounds); cp = get_cp(snd, chn, S_set S_y_bounds); if (!cp) return(Xen_false); if (Xen_is_number(bounds)) { hi = Xen_real_to_C_double(bounds); low = -hi; } else { int len; len = Xen_list_length(bounds); if (len > 0) { y0 = Xen_car(bounds); if (len > 1) y1 = Xen_cadr(bounds); } if (Xen_is_number(y0)) { low = Xen_real_to_C_double(y0); if (Xen_is_number(y1)) hi = Xen_real_to_C_double(y1); else { if (low < 0.0) hi = -low; else { hi = low; low = -low; } } } else { if (ap == cp->axis) { /* if no bounds given, use maxamp */ hi = channel_maxamp(cp, AT_CURRENT_EDIT_POSITION); if (hi < 0.0) hi = -hi; if (hi == 0.0) hi = .001; low = -hi; } } } if (hi > low) { ap->ymin = low; ap->ymax = hi; ap->y_ambit = (ap->ymax - ap->ymin); ap->y0 = low; ap->y1 = hi; ap->zy = 1.0; ap->sy = 0.0; if (ap == cp->axis) { resize_sy_and_zy(cp); apply_y_axis_change(cp); } } return(bounds); } with_four_setter_args(g_set_y_bounds_reversed, g_set_y_bounds) Xen_wrap_4_optional_args(g_x_to_position_w, g_x_to_position) Xen_wrap_4_optional_args(g_y_to_position_w, g_y_to_position) Xen_wrap_4_optional_args(g_position_to_x_w, g_position_to_x) Xen_wrap_4_optional_args(g_position_to_y_w, g_position_to_y) Xen_wrap_3_optional_args(g_axis_info_w, g_axis_info) #if (!USE_NO_GUI) Xen_wrap_any_args(g_draw_axes_w, g_draw_axes) #endif Xen_wrap_3_optional_args(g_x_axis_label_w, g_x_axis_label) Xen_wrap_3_optional_args(g_y_axis_label_w, g_y_axis_label) Xen_wrap_3_optional_args(g_x_bounds_w, g_x_bounds) Xen_wrap_3_optional_args(g_y_bounds_w, g_y_bounds) #if HAVE_SCHEME #define g_set_x_axis_label_w g_set_x_axis_label_reversed #define g_set_y_axis_label_w g_set_y_axis_label_reversed #define g_set_x_bounds_w g_set_x_bounds_reversed #define g_set_y_bounds_w g_set_y_bounds_reversed #else Xen_wrap_4_optional_args(g_set_x_axis_label_w, g_set_x_axis_label) Xen_wrap_4_optional_args(g_set_y_axis_label_w, g_set_y_axis_label) Xen_wrap_4_optional_args(g_set_x_bounds_w, g_set_x_bounds) Xen_wrap_4_optional_args(g_set_y_bounds_w, g_set_y_bounds) #endif void g_init_axis(void) { Xen_define_safe_procedure(S_x_to_position, g_x_to_position_w, 1, 3, 0, H_x_to_position); Xen_define_safe_procedure(S_y_to_position, g_y_to_position_w, 1, 3, 0, H_y_to_position); Xen_define_safe_procedure(S_position_to_x, g_position_to_x_w, 1, 3, 0, H_position_to_x); Xen_define_safe_procedure(S_position_to_y, g_position_to_y_w, 1, 3, 0, H_position_to_y); Xen_define_safe_procedure(S_axis_info, g_axis_info_w, 0, 3, 0, H_axis_info); Xen_define_safe_procedure(S_draw_axes, g_draw_axes_w, 0, 0, 1, H_draw_axes); Xen_define_dilambda(S_x_axis_label, g_x_axis_label_w, H_x_axis_label, S_set S_x_axis_label, g_set_x_axis_label_w, 0, 3, 1, 3); Xen_define_dilambda(S_y_axis_label, g_y_axis_label_w, H_y_axis_label, S_set S_y_axis_label, g_set_y_axis_label_w, 0, 3, 1, 3); Xen_define_dilambda(S_x_bounds, g_x_bounds_w, H_x_bounds, S_set S_x_bounds, g_set_x_bounds_w, 0, 3, 1, 3); Xen_define_dilambda(S_y_bounds, g_y_bounds_w, H_y_bounds, S_set S_y_bounds, g_set_y_bounds_w, 0, 3, 1, 3); Xen_define_constant(S_time_graph, TIME_AXIS_INFO, "time domain graph axis info"); Xen_define_constant(S_transform_graph, TRANSFORM_AXIS_INFO, "frequency domain graph axis info"); Xen_define_constant(S_lisp_graph, LISP_AXIS_INFO, "lisp graph axis info"); } #endif /* end no gui (covers entire xen section) */ /* (if something is moved here, remember to add stubs to snd-nogui.c) */ snd-16.1/index.rb0000644000076400007640000000251712306421672011777 0ustar bilbil# Snd documentation index (generated by index.cl) # html :play or html "play" ==> the whole string must match # html(/^play$/) ==> regexp search def html(str) url = if str.kind_of?(Regexp) # x --> ["play", "extsnd.html#sndplay"] pair = snd_urls().detect do |x| str.match(x[0]) end if pair.kind_of?(Array) pair[1] else false end else # String or Symbol snd_url(str.to_s) end if url and (not url.empty?) goto_html(url) else snd_print "no url for #{str}?" false end end def help(str) snd_help(str) or snd_help(html(str)) end def goto_html(url) dir = [Dir.pwd, html_dir(), "/usr/doc/snd-11", "/usr/share/doc/snd-11", "/usr/local/share/doc/snd-11", "/usr/doc/snd-10", "/usr/share/doc/snd-10", "/usr/local/share/doc/snd-10", "/usr/doc/snd-8"].detect do |d| if d.kind_of?(String) if File.exist?(d + "/" + "snd.html") d end end end if dir case html_program() when "netscape", "mozilla" send_mozilla(dir + "/" + url) else system(format("%s file:%s/%s &", html_program(), dir, url)) end else snd_print "snd.html not found; set_html_dir(path) to appropriate path!" end url end snd-16.1/snd-dac.c0000644000076400007640000031645612616725517012043 0ustar bilbil#include "snd.h" #include "clm2xen.h" /* * each channel currently being played has an associated dac_info struct * all active dac_info structs are held in a play_list * channels can come and go as a play is in progress */ /* -------------------------------- per-channel control-panel state -------------------------------- */ typedef struct { mus_any *gen; struct dac_info *dp; bool speeding; mus_float_t sr; } spd_info; typedef enum {DAC_NOTHING, DAC_CHANNEL, DAC_REGION, DAC_MIX, DAC_XEN} dac_source_t; typedef struct dac_info { dac_source_t type; mus_float_t cur_index; mus_float_t cur_amp; mus_float_t cur_srate; mus_float_t cur_exp; mus_float_t cur_rev; /* rev scaler -- len is set at initialization */ mus_float_t contrast_amp; bool expanding, reverbing, filtering; /* these need lots of preparation, so they're noticed only at the start */ int audio_chan; /* where channel's output is going (wrap-around if not enough audio output channels) */ int slot; mus_float_t *a; /* filter coeffs */ int a_size; /* user can change filter order while playing (sigh...) */ snd_fd *chn_fd; /* sampler, null if DAC_Xen */ spd_info *spd; mus_any *flt; int region, mix_id; /* to reset region-browser play button upon completion */ bool selection; mus_any *src; snd_info *sp; /* needed to see button callback changes etc */ chan_info *cp; bool never_sped; int expand_ring_framples; mus_long_t end; Xen stop_procedure; int stop_procedure_gc_loc; Xen func; int func_gc_loc, direction; mus_float_t (*dac_sample)(struct dac_info *dp); } dac_info; #define AMP_CONTROL(sp, dp) ((dp->cp->amp_control) ? (dp->cp->amp_control[0]) : sp->amp_control) /* an experiment */ static mus_float_t dac_read_sample(struct dac_info *dp) { return(read_sample(dp->chn_fd)); } static mus_float_t dac_no_sample(struct dac_info *dp) { return(0.0); } static mus_float_t dac_xen_sample(struct dac_info *dp) { Xen result; result = Xen_unprotected_call_with_no_args(dp->func); if (Xen_is_false(result)) { dp->end = 0; return(0.0); } return(Xen_real_to_C_double(result)); } /* -------- filter -------- */ static mus_any *make_flt(dac_info *dp, int order, mus_float_t *env) { if (order <= 0) return(NULL); dp->a_size = order; dp->a = (mus_float_t *)calloc(order, sizeof(mus_float_t)); if (env) mus_make_fir_coeffs(order, env, dp->a); return(mus_make_fir_filter(order, dp->a, NULL)); } /* -------- sample-rate conversion -------- */ static mus_float_t dac_src_input_as_needed(void *arg, int direction) { dac_info *dp = (dac_info *)arg; if ((direction != dp->direction) && (dp->chn_fd)) { read_sample_change_direction(dp->chn_fd, (direction == 1) ? READ_FORWARD : READ_BACKWARD); dp->direction = direction; } return((*(dp->dac_sample))(dp)); } static mus_float_t speed(dac_info *dp, mus_float_t sr) { if (dp->never_sped) return((*(dp->dac_sample))(dp)); if (dp->src == NULL) dp->src = mus_make_src(&dac_src_input_as_needed, sr, sinc_width(ss), (void *)dp); mus_set_increment(dp->src, sr); return(mus_src(dp->src, 0.0, &dac_src_input_as_needed)); } /* -------- granular synthesis -------- */ static mus_float_t expand_input_as_needed(void *arg, int dir) { spd_info *spd = (spd_info *)arg; dac_info *dp; dp = spd->dp; if (spd->speeding) return(speed(dp, spd->sr)); else return((*(dp->dac_sample))(dp)); } static int max_expand_control_len(snd_info *sp) { if (sp->expand_control_length > .5) return(0); return((int)(snd_srate(sp) * .5)); } static void *make_expand(snd_info *sp, mus_float_t initial_ex, dac_info *dp) { spd_info *spd; spd = (spd_info *)calloc(1, sizeof(spd_info)); spd->gen = mus_make_granulate(&expand_input_as_needed, initial_ex, sp->expand_control_length, .6, /* expand scaler, not currently settable -- dac_set_expand_scaler below */ sp->expand_control_hop, sp->expand_control_ramp, sp->expand_control_jitter, max_expand_control_len(sp), NULL, (void *)spd); spd->dp = dp; spd->speeding = false; spd->sr = 0.0; return(spd); } static void free_expand(void *ur_spd) { spd_info *spd = (spd_info *)ur_spd; if (ur_spd) { mus_free(spd->gen); free(spd); } } static mus_float_t expand(dac_info *dp, mus_float_t sr, mus_float_t ex) { /* from mixer.sai, used in "Leviathan", 1986 */ bool speeding; snd_info *sp; spd_info *spd; sp = dp->sp; speeding = ((sp->speed_control_direction != 1) || (!(snd_feq(sp->speed_control, 1.0))) || (!(snd_feq(dp->cur_srate, 1.0)))); spd = dp->spd; spd->speeding = speeding; spd->sr = sr; return(mus_granulate(spd->gen, &expand_input_as_needed)); } /* -------- reverb -------- */ /* to implement run-time reverb-length, we would need to save the individual delay lens, both nominal and actual (given srate); set up the combs/allpasses to make room for 5.0 as reverb_control_length, then at each call, check current reverb len (how?), and if not original, recalculate how many samples each delay needs to be expanded by and so on -- more complexity than it's worth! */ static int prime(int num) { if (num == 2) return(1); if ((num % 2) == 1) { int lim, i; lim = (int)(sqrt(num)); for (i = 3; i < lim; i += 2) if ((num % i) == 0) return(0); return(1); } return(0); } static int get_prime(int num) { int i; if ((num % 2) == 1) i = num; else i = num + 1; while (!(prime(i))) i += 2; return(i); } typedef struct { int num_combs; mus_any **combs; int num_allpasses; mus_any **allpasses; mus_any *onep; } rev_info; static rev_info *global_rev = NULL; static void nrev(rev_info *r, mus_float_t *rins, mus_float_t *routs, int chans) { mus_float_t rout, rin = 0.0; int i; for (i = 0; i < chans; i++) rin += rins[i]; rout = mus_all_pass_unmodulated_noz(r->allpasses[3], mus_one_pole(r->onep, mus_all_pass_unmodulated_noz(r->allpasses[2], mus_all_pass_unmodulated_noz(r->allpasses[1], mus_all_pass_unmodulated_noz(r->allpasses[0], mus_comb_unmodulated_noz(r->combs[0], rin) + mus_comb_unmodulated_noz(r->combs[1], rin) + mus_comb_unmodulated_noz(r->combs[2], rin) + mus_comb_unmodulated_noz(r->combs[3], rin) + mus_comb_unmodulated_noz(r->combs[4], rin) + mus_comb_unmodulated_noz(r->combs[5], rin)))))); for (i = 0; i < chans; i++) routs[i] = mus_all_pass_unmodulated_noz(r->allpasses[i + 4], rout); } static mus_float_t *r_ins, *r_outs; static int reverb_chans = 0; static void reverb(rev_info *r, mus_float_t **rins, mus_float_t **outs, int ind) { int i, chans; chans = reverb_chans; for (i = 0; i < chans; i++) { r_ins[i] = rins[i][ind]; r_outs[i] = 0.0; } nrev(r, r_ins, r_outs, chans); for (i = 0; i < chans; i++) outs[i][ind] += (r_outs[i]); } static void free_reverb(void) { rev_info *r; r = global_rev; if (r) { int i; if (r->combs) { for (i = 0; i < r->num_combs; i++) if (r->combs[i]) mus_free(r->combs[i]); free(r->combs); } if (r->onep) mus_free(r->onep); if (r->allpasses) { for (i = 0; i < r->num_allpasses; i++) if (r->allpasses[i]) mus_free(r->allpasses[i]); free(r->allpasses); } free(r); } global_rev = NULL; } static mus_float_t *comb_factors = NULL; static rev_info *make_nrev(snd_info *sp, int chans) { /* Mike McNabb's nrev from Mus10 days (ca. 1978) */ #define BASE_DLY_LEN 14 static int base_dly_len[BASE_DLY_LEN] = {1433, 1601, 1867, 2053, 2251, 2399, 347, 113, 37, 59, 43, 37, 29, 19}; static int dly_len[BASE_DLY_LEN]; #define NREV_COMBS 6 static mus_float_t nrev_comb_factors[NREV_COMBS] = {0.822, 0.802, 0.773, 0.753, 0.753, 0.733}; mus_float_t srscale; int i, j, len; rev_info *r; if (sp == NULL) return(NULL); srscale = sp->reverb_control_length * snd_srate(sp) / 25641.0; for (i = 0; i < BASE_DLY_LEN; i++) dly_len[i] = get_prime((int)(srscale * base_dly_len[i])); r = (rev_info *)calloc(1, sizeof(rev_info)); r->num_combs = NREV_COMBS; r->combs = (mus_any **)calloc(r->num_combs, sizeof(mus_any *)); r->num_allpasses = 4 + chans; r->allpasses = (mus_any **)calloc(r->num_allpasses, sizeof(mus_any *)); if (comb_factors) free(comb_factors); comb_factors = (mus_float_t *)calloc(r->num_combs, sizeof(mus_float_t)); for (i = 0; i < r->num_combs; i++) { comb_factors[i] = nrev_comb_factors[i]; r->combs[i] = mus_make_comb(comb_factors[i] * sp->reverb_control_feedback, dly_len[i], NULL, dly_len[i], MUS_INTERP_LINEAR); } r->onep = mus_make_one_pole(sp->reverb_control_lowpass, sp->reverb_control_lowpass - 1.0); for (i = 0, j = r->num_combs; i < 4; i++, j++) r->allpasses[i] = mus_make_all_pass(-0.700, 0.700, dly_len[j], NULL, dly_len[j], MUS_INTERP_LINEAR); for (i = 0, j = 10; i < chans; i++) { if (j < BASE_DLY_LEN) len = dly_len[j]; else len = get_prime((int)(40 + mus_random(20.0))); r->allpasses[i + 4] = mus_make_all_pass(-0.700, 0.700, len, NULL, len, MUS_INTERP_LINEAR); } return(r); } static void make_reverb(snd_info *sp, int chans) { reverb_chans = chans; global_rev = make_nrev(sp, chans); } static void set_reverb_filter_coeff(mus_float_t newval) { if (global_rev) { mus_set_xcoeff(global_rev->onep, 0, newval); mus_set_ycoeff(global_rev->onep, 1, 1.0 - newval); } } static void set_reverb_comb_factors(mus_float_t val) { int j; if (global_rev) for (j = 0; j < global_rev->num_combs; j++) mus_set_scaler(global_rev->combs[j], comb_factors[j] * val); } /* -------- contrast-enhancement -------- */ static mus_float_t contrast (dac_info *dp, mus_float_t amp, mus_float_t index, mus_float_t inval) { return(amp * mus_contrast_enhancement(dp->contrast_amp * inval, index)); } static mus_error_handler_t *old_error_handler; static bool got_local_error = false; static void local_mus_error(int type, char *msg) { got_local_error = true; snd_error_without_format(msg); } mus_float_t *sample_linear_env(env *e, int order) { /* used only for filter coeffs (env here is the frequency response curve) */ mus_any *ge; int ordp; mus_float_t *data = NULL; mus_float_t last_x, step; last_x = e->data[(e->pts - 1) * 2]; step = 2 * last_x / ((mus_float_t)order - 1); ordp = e->pts; if (ordp < order) ordp = order; got_local_error = false; old_error_handler = mus_error_set_handler(local_mus_error); ge = mus_make_env(e->data, e->pts, 1.0, 0.0, e->base, 0.0, 1000 * ordp, NULL); mus_error_set_handler(old_error_handler); if (!got_local_error) { int i, j; mus_float_t x; data = (mus_float_t *)malloc(order * sizeof(mus_float_t)); for (i = 0, x = 0.0; i < order / 2; i++, x += step) data[i] = mus_env_interp(x, ge); for (j = order / 2 - 1, i = order / 2; (i < order) && (j >= 0); i++, j--) data[i] = data[j]; mus_free(ge); } return(data); } static void free_dac_info(dac_info *dp, play_stop_t reason) { bool looping; looping = (dp->stop_procedure == Xen_true); if (dp->stop_procedure_gc_loc != NOT_A_GC_LOC) { Xen_call_with_1_arg(dp->stop_procedure, C_int_to_Xen_integer((int)reason), "play stop procedure"); snd_unprotect_at(dp->stop_procedure_gc_loc); dp->stop_procedure = Xen_false; dp->stop_procedure_gc_loc = NOT_A_GC_LOC; } if (dp->func_gc_loc != NOT_A_GC_LOC) { snd_unprotect_at(dp->func_gc_loc); dp->func = Xen_false; dp->func_gc_loc = NOT_A_GC_LOC; } if (dp->a) {free(dp->a); dp->a = NULL; dp->a_size = 0;} dp->chn_fd = free_snd_fd(dp->chn_fd); if (dp->spd) free_expand(dp->spd); if (dp->src) mus_free(dp->src); if (dp->flt) mus_free(dp->flt); dp->sp = NULL; dp->cp = NULL; dp->type = DAC_NOTHING; free(dp); if ((looping) && (reason == PLAY_COMPLETE)) loop_play_selection(); } static int dac_max_sounds = 0; static dac_info **play_list = NULL; #define INITIAL_MAX_SOUNDS 16 static int play_list_members = 0; static int max_active_slot = -1; /* -------------------------------- special control panel variables -------------------------------- */ typedef enum {DAC_EXPAND, DAC_EXPAND_RAMP, DAC_EXPAND_LENGTH, DAC_EXPAND_HOP, DAC_EXPAND_SCALER, DAC_CONTRAST_AMP, DAC_REVERB_FEEDBACK, DAC_REVERB_LOWPASS} dac_field_t; static void dac_set_field(snd_info *sp, mus_float_t newval, dac_field_t field) { /* if sp == NULL, sets globally */ if (play_list) { if (field == DAC_REVERB_LOWPASS) { if (global_rev) set_reverb_filter_coeff(newval); } else { if (field == DAC_REVERB_FEEDBACK) { if (global_rev) set_reverb_comb_factors(newval); } else { int i; for (i = 0; i <= max_active_slot; i++) { dac_info *dp; dp = play_list[i]; if ((dp) && ((sp == NULL) || (sp == dp->sp))) { int val; switch (field) { case DAC_EXPAND: if (dp->spd) mus_set_increment(dp->spd->gen, newval); break; case DAC_EXPAND_LENGTH: /* segment length */ if (dp->spd) { val = (int)(snd_srate(sp) * newval); mus_set_length(dp->spd->gen, val); mus_set_ramp(dp->spd->gen, (int)(val * sp->expand_control_ramp)); } break; case DAC_EXPAND_RAMP: if (dp->spd) { val = (int)(newval * sp->expand_control_length * snd_srate(sp)); mus_set_ramp(dp->spd->gen, val); } break; case DAC_EXPAND_HOP: /* output hop */ if (dp->spd) { val = (int)(snd_srate(sp) * newval); mus_set_hop(dp->spd->gen, val); mus_set_increment(dp->spd->gen, sp->expand_control); } break; case DAC_EXPAND_SCALER: if (dp->spd) mus_set_scaler(dp->spd->gen, newval); break; case DAC_CONTRAST_AMP: dp->contrast_amp = newval; break; default: break; } } } } } } } void dac_set_expand(snd_info *sp, mus_float_t newval) {dac_set_field(sp, newval, DAC_EXPAND);} void dac_set_expand_length(snd_info *sp, mus_float_t newval) {dac_set_field(sp, newval, DAC_EXPAND_LENGTH);} void dac_set_expand_ramp(snd_info *sp, mus_float_t newval) {dac_set_field(sp, newval, DAC_EXPAND_RAMP);} void dac_set_expand_hop(snd_info *sp, mus_float_t newval) {dac_set_field(sp, newval, DAC_EXPAND_HOP);} /* static void dac_set_expand_scaler(snd_info *sp, mus_float_t newval) {dac_set_field(sp, newval, DAC_EXPAND_SCALER);} */ /* not currently accessible */ void dac_set_contrast_amp(snd_info *sp, mus_float_t newval) {dac_set_field(sp, newval, DAC_CONTRAST_AMP);} void dac_set_reverb_feedback(snd_info *sp, mus_float_t newval) {dac_set_field(sp, newval, DAC_REVERB_FEEDBACK);} void dac_set_reverb_lowpass(snd_info *sp, mus_float_t newval) {dac_set_field(sp, newval, DAC_REVERB_LOWPASS);} /* -------------------------------- stop playing (remove from play-list) -------------------------------- */ typedef struct { int srate; /* output srate */ int channels; /* total output channels currently active */ int framples; /* samples per channel per output block */ int devices; /* output devices active */ int *chans_per_device; /* channels sent to each active device */ mus_sample_t out_samp_type; /* output sample type */ int slice; /* background process state (i.e. starting, running, quitting) */ mus_long_t reverb_ring_framples; /* how long the reverb rings after the end (if reverb, of course) */ } dac_state; static dac_state *snd_dacp = NULL; static void free_dac_state(void) { if (snd_dacp) { if (snd_dacp->chans_per_device) free(snd_dacp->chans_per_device); free(snd_dacp); snd_dacp = NULL; } } static bool dac_running = false; static Xen play_hook; static Xen start_playing_hook; static Xen stop_playing_hook; static Xen stop_playing_selection_hook; static Xen start_playing_selection_hook; #define MAX_DEVICES 8 static int dev_fd[MAX_DEVICES] = {-1, -1, -1, -1, -1, -1, -1, -1}; void cleanup_dac(void) { /* called only from snd_exit_cleanly in snd-main.c */ int i; if (dac_running) for (i = 0; i < MAX_DEVICES; i++) if (dev_fd[i] != -1) { mus_audio_close(dev_fd[i]); dev_fd[i] = -1; } for (i = 0; i < MAX_DEVICES; i++) dev_fd[i] = -1; dac_running = false; } static bool something_is_playing(void) { int i; if (play_list) for (i = 0; i < dac_max_sounds; i++) if (play_list[i]) return(true); return(false); } static void reflect_play_stop(snd_info *sp) { #if (!USE_NO_GUI) set_control_panel_play_button(sp); #endif set_open_file_play_button(false); #if (!USE_NO_GUI) view_files_unplay(); #endif if (!something_is_playing()) ss->tracking = false; } static void free_player_sound(snd_info *sp); typedef enum {WITHOUT_TOGGLE, WITH_TOGGLE} dac_toggle_t; static void stop_playing_with_toggle(dac_info *dp, dac_toggle_t toggle, with_hook_t with_hook, play_stop_t reason) { snd_info *sp = NULL; bool sp_stopping = false; if ((dp == NULL) || (play_list == NULL)) return; sp = dp->sp; if ((sp) && (sp->inuse != SOUND_IDLE)) { if (sp->playing > 0) sp->playing--; if (sp->playing == 0) sp_stopping = true; if ((sp_stopping) && (ss->tracking) && (sp->inuse == SOUND_NORMAL) && (sp->index >= 0)) { int i; for (i = 0; i < sp->nchans; i++) { chan_info *cp; cp = sp->chans[i]; if ((cp == dp->cp) || (sp->sync != 0)) /* don't move the cursor in a channel that isn't playing */ { if (with_tracking_cursor(ss) == TRACK_AND_STAY) { if (dp->cur_srate > 0.0) { mus_long_t samp; samp = current_location(dp->chn_fd) + ((snd_dacp) ? snd_dacp->framples : 0); if (dp->selection) { if (samp > selection_end(cp)) samp = selection_end(cp); } else { if (samp > current_samples(cp)) samp = current_samples(cp); } cursor_sample(cp) = samp - 1; } cp->original_left_sample = cursor_sample(cp) - (cp->original_window_size / 2); if (cp->original_left_sample < 0) cp->original_left_sample = 0; } else cursor_sample(cp) = cp->original_cursor; cursor_moveto_with_window(cp, cursor_sample(cp), cp->original_left_sample, cp->original_window_size); update_graph(cp); } } } /* if ctrl-click play, c-t, c-q -> this flag is still set from aborted previous play, so clear at c-t (or c-g) */ } else sp = NULL; /* don't free it as a player below */ play_list[dp->slot] = NULL; play_list_members--; if (toggle == WITH_TOGGLE) { switch (dp->type) { case DAC_CHANNEL: if ((sp) && (sp->playing <= 0)) reflect_play_stop(sp); break; case DAC_REGION: if (dp->region != INVALID_REGION) reflect_play_region_stop(dp->region); break; case DAC_MIX: if (dp->mix_id != INVALID_MIX_ID) reflect_mix_play_stop(); case DAC_XEN: break; case DAC_NOTHING: break; } } if (dp->slot == max_active_slot) max_active_slot--; if (with_hook == WITH_HOOK) { if (dp->type == DAC_CHANNEL) { if (dp->selection) { reflect_play_selection_stop(); if (Xen_hook_has_list(stop_playing_selection_hook)) run_hook(stop_playing_selection_hook, Xen_empty_list, S_stop_playing_selection_hook); } else { if ((sp_stopping) && (Xen_hook_has_list(stop_playing_hook))) run_hook(stop_playing_hook, Xen_list_1(C_int_to_Xen_sound(sp->index)), S_stop_playing_hook); } } } if ((sp) && (is_player_sound(sp))) { int k; bool free_ok = true; dp->sp = NULL; /* free_player_sound frees it */ for (k = dp->slot + 1; k < dac_max_sounds; k++) { dac_info *ndp; ndp = play_list[k]; if ((ndp) && (ndp->sp) && (ndp->sp == sp)) { free_ok = false; break; } } if (free_ok) free_player_sound(sp); sp = NULL; } free_dac_info(dp, reason); /* this will call the stop-function, if any */ if ((sp) && (sp_stopping) && (sp->delete_me)) { #if USE_MOTIF || USE_GTK if (sp->delete_me != (void *)1) clear_deleted_snd_info(sp->delete_me); /* for various file dialog play buttons */ #endif completely_free_snd_info(sp); /* dummy snd_info struct for (play "filename") in snd-xen.c */ } } static void stop_playing(dac_info *dp, with_hook_t with_hook, play_stop_t reason) { stop_playing_with_toggle(dp, WITH_TOGGLE, with_hook, reason); } static idle_func_t dac_in_background(any_pointer_t ptr); static idle_func_t dac_work_proc = 0; /* needed in gtk to force process to stop */ static void stop_playing_sound_with_toggle(snd_info *sp, dac_toggle_t toggle, with_hook_t with_hook, play_stop_t reason) { /* this needs to scan all current play_list members and remove any that are referring * to sp, even indirectly (as through the current selection) */ /* if reason = PLAY_STOP_CALLED, PLAY_C_T, or PLAY_C_G, we need to slam the output volumes to 0.0 (so the * draining output is not played), then once we're sure output has stopped, put them back where they were. * But, this action is sound-driver (OS) specific -- perhaps just hit MUS_AUDIO_AMP and hope? * How to tell that on-card buffers are finally empty? Wait 1 or 2 seconds? * * an added annoyance -- to get current amps, we have to make separate read call for each chan! */ if ((sp) && (play_list)) { int i; dac_info *dp; for (i = 0; i < dac_max_sounds; i++) if ((play_list[i]) && (sp == (play_list[i]->sp))) { dp = play_list[i]; play_list[i] = NULL; stop_playing_with_toggle(dp, toggle, with_hook, reason); } if ((play_list_members > 0) && (with_hook == WITH_HOOK)) { /* see comment below */ for (i = 0; i < dac_max_sounds; i++) if ((play_list[i]) && (sp == (play_list[i]->sp))) { dp = play_list[i]; play_list[i] = NULL; stop_playing_with_toggle(dp, toggle, WITHOUT_HOOK, reason); /* do it again but with hook disabled */ } } } } void stop_playing_sound(snd_info *sp, play_stop_t reason) { stop_playing_sound_with_toggle(sp, WITH_TOGGLE, WITH_HOOK, reason); } void stop_playing_sound_without_hook(snd_info *sp, play_stop_t reason) { stop_playing_sound_with_toggle(sp, WITH_TOGGLE, WITHOUT_HOOK, reason); } void stop_playing_sound_no_toggle(snd_info *sp, play_stop_t reason) { stop_playing_sound_with_toggle(sp, WITHOUT_TOGGLE, WITH_HOOK, reason); } static void stop_playing_all_sounds_1(with_hook_t with_hook, play_stop_t reason) { if (play_list) { int i; dac_info *dp; for (i = 0; i < dac_max_sounds; i++) { dp = play_list[i]; play_list[i] = NULL; stop_playing(dp, with_hook, reason); /* this can call stop_playing_hook which can make a new play_list member where the old one used to be! */ } if ((play_list_members > 0) && (with_hook == WITH_HOOK)) { /* stop-playing-hook must have started a new player, but in this case, * the rest of Snd assumes the dac has stopped no matter what. So, * we make a second pass with the hooks disabled. */ for (i = 0; i < dac_max_sounds; i++) { dp = play_list[i]; play_list[i] = NULL; stop_playing(dp, WITHOUT_HOOK, reason); } } } if (snd_dacp) { snd_dacp->slice = 2; dac_in_background(NULL); /* try to force completion (work proc might not be called above) */ } } void stop_playing_all_sounds(play_stop_t reason) { stop_playing_all_sounds_1(WITH_HOOK, reason); } static void stop_playing_all_sounds_without_hook(play_stop_t reason) { stop_playing_all_sounds_1(WITHOUT_HOOK, reason); } void stop_playing_region(int n, play_stop_t reason) { if (play_list) { int i; dac_info *dp; for (i = 0; i < dac_max_sounds; i++) if ((play_list[i]) && (play_list[i]->type == DAC_REGION) && (play_list[i]->region == n)) { dp = play_list[i]; play_list[i] = NULL; stop_playing(dp, WITHOUT_HOOK, reason); } } } /* -------------------------------- play (add to play-list) -------------------------------- */ static int find_slot_to_play(void) { int i, old_size; if (play_list == NULL) { dac_max_sounds = INITIAL_MAX_SOUNDS; play_list = (dac_info **)calloc(dac_max_sounds, sizeof(dac_info *)); } for (i = 0; i < dac_max_sounds; i++) if (!play_list[i]) return(i); old_size = dac_max_sounds; dac_max_sounds += INITIAL_MAX_SOUNDS; play_list = (dac_info **)realloc(play_list, dac_max_sounds * sizeof(dac_info *)); for (i = old_size; i < dac_max_sounds; i++) play_list[i] = NULL; return(old_size); } static dac_info *make_dac_info(int slot, chan_info *cp, snd_info *sp, snd_fd *fd, mus_long_t end, int out_chan, dac_source_t type, Xen func) { dac_info *dp; dp = (dac_info *)calloc(1, sizeof(dac_info)); /* only place dac_info is created */ dp->stop_procedure = Xen_false; dp->stop_procedure_gc_loc = NOT_A_GC_LOC; dp->region = INVALID_REGION; dp->mix_id = INVALID_MIX_ID; dp->direction = 1; dp->type = type; /* dac needs to know how to get input before calling mus_make_src below */ if (type == DAC_NOTHING) dp->dac_sample = dac_no_sample; else { if (type == DAC_XEN) { dp->dac_sample = dac_xen_sample; dp->func = func; dp->func_gc_loc = snd_protect(func); } else { dp->dac_sample = dac_read_sample; dp->func = Xen_false; dp->func_gc_loc = NOT_A_GC_LOC; } } dp->a = NULL; dp->a_size = 0; dp->audio_chan = out_chan; dp->never_sped = true; dp->chn_fd = fd; dp->sp = sp; dp->cp = cp; /* next block may get input */ if (sp) { dp->expanding = sp->expand_control_on; dp->filtering = ((sp->filter_control_on) && (sp->filter_control_order > 0)); dp->reverbing = sp->reverb_control_on; dp->contrast_amp = sp->contrast_control_amp; if ((!(snd_feq(sp->speed_control, 1.0))) || (sp->speed_control_direction == -1)) { dp->src = mus_make_src(&dac_src_input_as_needed, sp->speed_control, sinc_width(ss), (void *)dp); dp->direction = sp->speed_control_direction; } if (dp->expanding) { dp->spd = (spd_info *)make_expand(sp, sp->expand_control, dp); dp->expand_ring_framples = (int)(snd_srate(sp) * sp->expand_control * sp->expand_control_length * 2); } if (dp->filtering) { sp->filter_control_changed = false; if (!(sp->filter_control_envelope)) dp->filtering = false; else { mus_float_t *data = NULL; data = sample_linear_env(sp->filter_control_envelope, sp->filter_control_order); if (data) { dp->flt = make_flt(dp, sp->filter_control_order, data); free(data); } else dp->filtering = false; } } } play_list_members++; dp->end = end; play_list[slot] = dp; dp->slot = slot; if (max_active_slot < slot) max_active_slot = slot; if (sp) { dp->cur_srate = sp->speed_control * sp->speed_control_direction; if (!(snd_feq(dp->cur_srate, 1.0))) dp->never_sped = false; dp->cur_amp = AMP_CONTROL(sp, dp); dp->cur_index = sp->contrast_control; dp->cur_exp = sp->expand_control; dp->cur_rev = sp->reverb_control_scale; } return(dp); } static void start_dac(int srate, int channels, play_process_t background, mus_float_t decay) { int i; /* look for channel folding cases etc */ /* channels = how many output audio chans we have; dac_combines_channels sets whether to wrap or muffle chans outside this limit */ if (with_tracking_cursor(ss) != DONT_TRACK) ss->tracking = true; for (i = 0; i <= max_active_slot; i++) { dac_info *dp; dp = play_list[i]; if ((dp) && (dac_running)) /* dac_running also if apply */ { /* in the "normal" (non-apply) case the reverb allocation is deferred until we're sure about the number of output channels */ if ((dp->reverbing) && (dp->sp) && (global_rev == NULL)) make_reverb(dp->sp, channels); if (snd_dacp) { if (dp->audio_chan >= snd_dacp->channels) /* if dac_running, the number of channels has already been set and won't change */ { if (dac_combines_channels(ss)) dp->audio_chan %= snd_dacp->channels; else stop_playing(dp, WITHOUT_HOOK, PLAY_NO_CHANNEL); } } } } /* any number of sounds can be piling into the dac buffers with new ones added at any time * (this is the play_list -- an array of dac_info pointers, each one a separate channel rendition) */ if (!dac_running) { if (snd_dacp) free_dac_state(); snd_dacp = (dac_state *)calloc(1, sizeof(dac_state)); snd_dacp->slice = 0; snd_dacp->srate = srate; snd_dacp->out_samp_type = MUS_AUDIO_COMPATIBLE_SAMPLE_TYPE; if (snd_dacp->srate <= 0) snd_dacp->srate = 44100; snd_dacp->channels = channels; if (dac_size(ss) > 0) snd_dacp->framples = dac_size(ss); else snd_dacp->framples = 256; snd_dacp->devices = 1; /* just a first guess */ snd_dacp->reverb_ring_framples = (mus_long_t)(srate * decay); if (background == IN_BACKGROUND) dac_work_proc = BACKGROUND_ADD(dac_in_background, NULL); else { /* here we want to play as an atomic (not background) action */ while (dac_in_background(NULL) == BACKGROUND_CONTINUE) check_for_event(); /* need to be able to C-g out of this */ } } } /* pos = to_c_edit_position(cp, edpos, caller, arg_pos); */ static dac_info *add_channel_to_play_list(chan_info *cp, snd_info *sp, mus_long_t start, mus_long_t end, int pos, int out_chan) { /* if not sp, control panel is ignored */ int slot; read_direction_t direction = READ_FORWARD; mus_long_t beg = 0; snd_fd *sf; if (pos == AT_CURRENT_EDIT_POSITION) pos = cp->edit_ctr; if (sp) { if (sp->speed_control_direction == 1) { if (start >= cp->edits[pos]->samples) return(NULL); direction = READ_FORWARD; beg = start; } else { direction = READ_BACKWARD; if (start < end) { mus_long_t tmp; tmp = start; start = end; end = tmp; } if ((start == 0) || (start >= cp->edits[pos]->samples)) /* don't be pedantic about the start point */ beg = cp->edits[pos]->samples - 1; else beg = start; if ((end == 0) || (end >= (cp->edits[pos]->samples))) end = NO_END_SPECIFIED; } } slot = find_slot_to_play(); if (slot == -1) return(NULL); sf = init_sample_read_any(beg, cp, direction, pos); if (sf) { if (sp) { sp->playing++; if (((with_tracking_cursor(ss) != DONT_TRACK) || (ss->tracking)) && (!(is_player_sound(sp)))) { cp->original_cursor = cursor_sample(cp); if (cp->axis) { cp->original_left_sample = cp->axis->losamp; cp->original_window_size = cp->axis->hisamp - cp->axis->losamp; } cp->cursor_on = true; cursor_moveto_without_verbosity(cp, start); #if USE_MOTIF if (cp->chan_widgets) update_graph(cp); #endif } } return(make_dac_info(slot, cp, sp, sf, end, out_chan, DAC_CHANNEL, Xen_false)); } return(NULL); } static dac_info *add_region_channel_to_play_list(int region, int chan, mus_long_t beg, mus_long_t end, int out_chan) { int slot; snd_fd *fd; slot = find_slot_to_play(); if (slot == -1) return(NULL); fd = init_region_read(beg, region, chan, READ_FORWARD); if (fd) { dac_info *dp; dp = make_dac_info(slot, fd->cp, NULL, fd, end, out_chan, DAC_REGION, Xen_false); if (dp) dp->region = region; return(dp); } return(NULL); } void play_region_1(int region, play_process_t background, Xen stop_proc) { /* just plays region (not current selection) -- no control panel etc */ int chans, i; dac_info *dp = NULL, *rtn_dp = NULL; if ((background == NOT_IN_BACKGROUND) && (play_list_members > 0)) return; if (!(region_ok(region))) return; chans = region_chans(region); if (chans == 0) return; for (i = 0; i < chans; i++) { dp = add_region_channel_to_play_list(region, i, 0, NO_END_SPECIFIED, i); /* i = out chan */ if (dp) { if (rtn_dp == NULL) rtn_dp = dp; } } if (rtn_dp) { rtn_dp->stop_procedure = stop_proc; if (Xen_is_procedure(stop_proc)) rtn_dp->stop_procedure_gc_loc = snd_protect(stop_proc); start_dac(region_srate(region), chans, background, DEFAULT_REVERB_CONTROL_DECAY); } } void play_region(int region, play_process_t background) { play_region_1(region, background, Xen_false); } bool add_mix_to_play_list(mix_state *ms, chan_info *cp, mus_long_t beg_within_mix, bool start_playing) { int slot; slot = find_slot_to_play(); if (slot != -1) { snd_fd *fd; fd = make_virtual_mix_reader(cp, beg_within_mix, ms->len - beg_within_mix, ms->index, 1.0, READ_FORWARD); if (fd) { dac_info *dp; dp = make_dac_info(slot, cp, NULL, fd, NO_END_SPECIFIED, 0, DAC_MIX, Xen_false); if (dp) { dp->mix_id = ms->index; /* any valid mix id will do */ if (start_playing) start_dac(snd_srate(cp->sound), 1, NOT_IN_BACKGROUND, DEFAULT_REVERB_CONTROL_DECAY); return(true); } } else free_snd_fd(fd); } return(false); } /* (play (let ((osc (make-oscil 440.0)) (samp 0)) (lambda () (if (> samp 20000) #f (begin (set! samp (1+ samp)) (* .5 (oscil osc))))))) ; you can use explicit control panel accessors */ static bool add_zeros_to_play_list(int srate, int chans) { int slot; slot = find_slot_to_play(); if (slot != -1) { dac_info *dp; dp = make_dac_info(slot, NULL, NULL, NULL, NO_END_SPECIFIED, 0, DAC_NOTHING, Xen_false); if (dp) { start_dac(srate, chans, IN_BACKGROUND, DEFAULT_REVERB_CONTROL_DECAY); return(true); } } return(false); } static bool add_xen_to_play_list(Xen func) { int slot; slot = find_slot_to_play(); if (slot != -1) { dac_info *dp; dp = make_dac_info(slot, NULL, NULL, NULL, NO_END_SPECIFIED, 0, DAC_XEN, func); if (dp) { #if USE_NO_GUI start_dac((int)mus_srate(), 1, NOT_IN_BACKGROUND, DEFAULT_REVERB_CONTROL_DECAY); #else start_dac((int)mus_srate(), 1, IN_BACKGROUND, DEFAULT_REVERB_CONTROL_DECAY); #endif /* ^ output channels */ return(true); } } return(false); } static bool call_start_playing_hook(snd_info *sp) { if ((Xen_hook_has_list(start_playing_hook)) && (Xen_is_true(run_or_hook(start_playing_hook, Xen_list_1(C_int_to_Xen_sound(sp->index)), /* this can be 123456 (TEMP_SOUND_INDEX in snd-file.c) -- View:Files dialog play button */ S_start_playing_hook)))) { reflect_play_stop(sp); /* turns off buttons */ if (sp->delete_me) completely_free_snd_info(sp); /* dummy snd_info struct for (play "filename") in snd-xen.c */ return(true); } return(false); } static bool call_start_playing_selection_hook(void) { return((Xen_hook_has_list(start_playing_selection_hook)) && (Xen_is_true(run_or_hook(start_playing_selection_hook, Xen_empty_list, S_start_playing_selection_hook)))); } static dac_info *play_channel_1(chan_info *cp, mus_long_t start, mus_long_t end, play_process_t background, int pos, Xen stop_proc, int out_chan) { /* just plays one channel (ignores possible sync), includes start-hook */ snd_info *sp = NULL; dac_info *dp = NULL; sp = cp->sound; if (sp->inuse == SOUND_IDLE) return(NULL); if (call_start_playing_hook(sp)) return(NULL); dp = add_channel_to_play_list(cp, sp, start, end, pos, out_chan); if (dp) { dp->stop_procedure = stop_proc; if (Xen_is_procedure(stop_proc)) dp->stop_procedure_gc_loc = snd_protect(stop_proc); set_play_button(sp, true); start_dac(snd_srate(sp), 1, background, sp->reverb_control_decay); } return(dp); } void play_channel(chan_info *cp, mus_long_t start, mus_long_t end) { play_channel_1(cp, start, end, IN_BACKGROUND, AT_CURRENT_EDIT_POSITION, Xen_false, cp->chan); } static dac_info *play_sound_1(snd_info *sp, mus_long_t start, mus_long_t end, play_process_t background, Xen edpos, Xen stop_proc, const char *caller, int arg_pos) { /* just plays one sound (ignores possible sync) */ int i; dac_info *dp = NULL, *rtn_dp = NULL; if ((background == NOT_IN_BACKGROUND) && (play_list_members > 0)) return(NULL); if (sp->inuse == SOUND_IDLE) return(NULL); if (call_start_playing_hook(sp)) return(NULL); for (i = 0; i < sp->nchans; i++) { int pos; pos = to_c_edit_position(sp->chans[i], edpos, caller, arg_pos); dp = add_channel_to_play_list(sp->chans[i], sp, start, end, pos, i); /* i = out chan */ if ((dp) && (rtn_dp == NULL)) rtn_dp = dp; } if (rtn_dp) { rtn_dp->stop_procedure = stop_proc; if (Xen_is_procedure(stop_proc)) rtn_dp->stop_procedure_gc_loc = snd_protect(stop_proc); set_play_button(sp, true); start_dac(snd_srate(sp), sp->nchans, background, sp->reverb_control_decay); } return(rtn_dp); } void play_sound(snd_info *sp, mus_long_t start, mus_long_t end) { play_sound_1(sp, start, end, IN_BACKGROUND, C_int_to_Xen_integer(AT_CURRENT_EDIT_POSITION), Xen_false, NULL, 0); } static dac_info *play_channels_1(chan_info **cps, int chans, mus_long_t *starts, mus_long_t *ur_ends, play_process_t background, Xen edpos, bool selection, Xen stop_proc, const char *caller, int arg_pos) { /* ends can be NULL */ int i; snd_info *sp = NULL; dac_info *dp = NULL, *rtn_dp = NULL; mus_long_t *ends; if ((background == NOT_IN_BACKGROUND) && (play_list_members > 0)) return(NULL); if (chans <= 0) return(NULL); if (!selection) { if (call_start_playing_hook(cps[0]->sound)) return(NULL); } else { if (call_start_playing_selection_hook()) return(NULL); } if (ur_ends) ends = ur_ends; else { ends = (mus_long_t *)calloc(chans, sizeof(mus_long_t)); for (i = 0; i < chans; i++) ends[i] = NO_END_SPECIFIED; } sp = cps[0]->sound; for (i = 0; i < chans; i++) { int pos; pos = to_c_edit_position(cps[i], edpos, caller, arg_pos); dp = add_channel_to_play_list(cps[i], sp, starts[i], ends[i], pos, i); if (dp) { if (rtn_dp == NULL) rtn_dp = dp; if (selection) dp->selection = true; } } if (ur_ends == NULL) free(ends); if ((sp) && (rtn_dp)) { rtn_dp->stop_procedure = stop_proc; if (Xen_is_procedure(stop_proc)) rtn_dp->stop_procedure_gc_loc = snd_protect(stop_proc); set_play_button(sp, true); start_dac(snd_srate(sp), chans, background, sp->reverb_control_decay); } return(rtn_dp); } void play_channels(chan_info **cps, int chans, mus_long_t *starts, mus_long_t *ur_ends, play_process_t background, Xen edpos, bool selection, const char *caller, int arg_pos) { play_channels_1(cps, chans, starts, ur_ends, background, edpos, selection, Xen_false, caller, arg_pos); } void play_channel_with_sync(chan_info *cp, mus_long_t start, mus_long_t end) { snd_info *sp; sync_info *si; mus_long_t *ends = NULL; int i; sp = cp->sound; if ((sp->sync == 0) || (is_player_sound(sp))) { play_channel(cp, start, end); return; } si = snd_sync(sp->sync); if (end != NO_END_SPECIFIED) { ends = (mus_long_t *)calloc(si->chans, sizeof(mus_long_t)); for (i = 0; i < si->chans; i++) ends[i] = end; } for (i = 0; i < si->chans; i++) si->begs[i] = start; play_channels_1(si->cps, si->chans, si->begs, ends, IN_BACKGROUND, C_int_to_Xen_integer(AT_CURRENT_EDIT_POSITION), false, Xen_false, NULL, 0); si = free_sync_info(si); if (ends) free(ends); } static dac_info *play_selection_1(play_process_t background, Xen stop_proc) { /* just plays the current selection */ dac_info *dp = NULL; if (selection_is_active()) { sync_info *si = NULL; si = selection_sync(); if (si) { int i; mus_long_t *ends; ends = (mus_long_t *)calloc(si->chans, sizeof(mus_long_t)); for (i = 0; i < si->chans; i++) ends[i] = si->begs[i] + selection_len(); dp = play_channels_1(si->cps, si->chans, si->begs, ends, background, C_int_to_Xen_integer(AT_CURRENT_EDIT_POSITION), true, stop_proc, NULL, 0); si = free_sync_info(si); /* does not free samplers */ free(ends); } } return(dp); } void play_selection(play_process_t background) { play_selection_1(background, Xen_false); } void loop_play_selection(void) { play_selection_1(IN_BACKGROUND, Xen_true); } /* -------------------------------- process samples and write to DAC -------------------------------- */ #define NO_CHANGE 0 #define JUST_AMP 1 #define JUST_SPEED 2 #define ALL_CHANGES 3 static int choose_dac_op(dac_info *dp, snd_info *sp) { if (!sp) return(NO_CHANGE); if ((dp->expanding) || (dp->filtering) || (dp->reverbing) || (sp->contrast_control_on)) return(ALL_CHANGES); else { if ((sp->speed_control_direction != 1) || (!(snd_feq(sp->speed_control, 1.0))) || (!(snd_feq(dp->cur_srate, 1.0)))) return(JUST_SPEED); else { if ((AMP_CONTROL(sp, dp) == dp->cur_amp) && (snd_feq(AMP_CONTROL(sp, dp), 1.0))) return(NO_CHANGE); else return(JUST_AMP); } } } static int cursor_time; /* can't move cursor on each dac buffer -- causes clicks */ static bool dac_pausing = false; void toggle_dac_pausing(void) {dac_pausing = (!dac_pausing); play_button_pause(dac_pausing);} /* only below and snd-kbd.c */ bool play_in_progress(void) {return(play_list_members > 0);} static unsigned char **audio_bytes = NULL; static int audio_bytes_size = 0; static int audio_bytes_devices = 0; static mus_float_t **dac_buffers = NULL; static int dac_buffer_size = 0; static int dac_buffer_chans = 0; /* chans allocated */ static mus_float_t **rev_ins; #define WRITE_TO_DAC 1 #define WRITE_TO_FILE 0 static int fill_dac_buffers(int write_ok) { /* return value used only by Apply */ int i; bool cursor_change = false; int framples; mus_float_t *revin; dac_info *dp; snd_info *sp; mus_float_t *buf; #if (HAVE_OSS || HAVE_ALSA) mus_float_t **dev_bufs; #endif framples = snd_dacp->framples; /* clear buffers */ for (i = 0; i < snd_dacp->channels; i++) memset(dac_buffers[i], 0, framples * sizeof(mus_float_t)); if (global_rev) for (i = 0; i < snd_dacp->channels; i++) memset(rev_ins[i], 0, framples * sizeof(mus_float_t)); if (dac_pausing) cursor_change = false; else { if (Xen_hook_has_list(play_hook)) run_hook(play_hook, Xen_list_1(C_int_to_Xen_integer(framples)), S_play_hook); cursor_time += framples; cursor_change = (cursor_time >= (int)(snd_dacp->srate * cursor_update_interval(ss))); /* the check for hooks and so on has to be separate from the fill loop to keep everything synchronized across stop-function replay requests etc */ /* first check for disasters (user closed sound while playing it or running Apply!) */ for (i = 0; i <= max_active_slot; i++) { dp = play_list[i]; if (dp) { sp = dp->sp; /* can be nil if region playing */ if ((sp) && ((sp->inuse == SOUND_IDLE) || (sp->playing == 0))) stop_playing(dp, WITHOUT_HOOK, PLAY_CLOSE); } } /* now read currently active chans and update locations -- don't call any hooks or stop-functions! */ for (i = 0; i <= max_active_slot; i++) { dp = play_list[i]; if (dp) { int j; mus_float_t amp, incr, sr, sincr, ind, indincr, rev, revincr, fval; if (dp->audio_chan >= snd_dacp->channels) /* this can happen if we're playing 1 chan, try to add 2 chans */ { if (dac_combines_channels(ss)) dp->audio_chan %= snd_dacp->channels; else continue; } /* check for moving cursor */ sp = dp->sp; /* can be nil if region playing */ if ((sp) && (ss->tracking) && (cursor_change) && (dp->chn_fd) && (!(dp->chn_fd->at_eof)) && #if (!USE_NO_GUI) (dp->cp->chan_widgets) && /* nil if play_file */ #endif (dp->chn_fd->cb)) { mus_long_t loc; bool old_just_zero; old_just_zero = dp->cp->just_zero; dp->cp->just_zero = true; loc = current_location(dp->chn_fd); loc -= (int)(cursor_location_offset(ss) * dp->cur_srate); /* should work in either direction */ cursor_moveto_without_verbosity(dp->cp, loc); dp->cp->just_zero = old_just_zero; } /* add a buffer's worth from the current source into dp->audio_chan */ buf = dac_buffers[dp->audio_chan]; if (buf == NULL) continue; revin = rev_ins[dp->audio_chan]; switch (choose_dac_op(dp, sp)) { case NO_CHANGE: /* simplest case -- no changes at all */ for (j = 0; j < framples; j++) buf[j] += (mus_float_t)((*(dp->dac_sample))(dp)); break; case JUST_AMP: /* AMP_CONTROL(sp, dp) is current UI value, dp->cur_amp is current local value */ amp = dp->cur_amp; incr = (AMP_CONTROL(sp, dp) - amp) / (mus_float_t)(framples); for (j = 0; j < framples; j++, amp += incr) buf[j] += (mus_float_t)(amp * (*(dp->dac_sample))(dp)); dp->cur_amp = amp; break; case JUST_SPEED: /* includes amp changes */ /* sp->speed_control is current UI value, dp->cur_srate is current local value */ dp->never_sped = false; amp = dp->cur_amp; incr = (AMP_CONTROL(sp, dp) - amp) / (mus_float_t)(framples); sr = dp->cur_srate; sincr = (sp->speed_control * sp->speed_control_direction - sr) / (mus_float_t)(framples); if ((sr != 0.0) || (sincr != 0.0)) { if (dp->src) { if ((amp == 1.0) && (incr == 0.0) && (sincr == 0.0)) { mus_set_increment(dp->src, sr); mus_src_to_buffer(dp->src, &dac_src_input_as_needed, buf, framples); } else { for (j = 0; j < framples; j++, amp += incr, sr += sincr) { mus_set_increment(dp->src, sr); buf[j] += (amp * mus_src(dp->src, 0.0, &dac_src_input_as_needed)); } } } else { for (j = 0; j < framples; j++, amp += incr, sr += sincr) buf[j] += (amp * speed(dp, sr)); } } dp->cur_srate = sr; dp->cur_amp = amp; break; case ALL_CHANGES: amp = dp->cur_amp; incr = (AMP_CONTROL(sp, dp) - amp) / (mus_float_t)(framples); sr = dp->cur_srate; sincr = (sp->speed_control * sp->speed_control_direction - sr) / (mus_float_t)(framples); if ((sincr != 0.0) || (!(snd_feq(sr, 1.0)))) dp->never_sped = false; ind = dp->cur_index; indincr = (sp->contrast_control - ind) / (mus_float_t)(framples); rev = dp->cur_rev; revincr = (sp->reverb_control_scale - rev) / (mus_float_t)(framples); if ((dp->filtering) && (sp->filter_control_changed)) { mus_float_t *data = NULL; data = sample_linear_env(sp->filter_control_envelope, sp->filter_control_order); if (data) { /* check all chans in sp before clearing filter_order_changed flag */ int j; for (j = i; j <= max_active_slot; j++) { dac_info *ndp; ndp = play_list[j]; if ((ndp) && (ndp->sp == sp) && (ndp->filtering)) { if (sp->filter_control_order > ndp->a_size) /* need more room in dp->a == flt->xcoeffs and flt->state */ { free(ndp->a); ndp->a_size = sp->filter_control_order; ndp->a = (mus_float_t *)calloc(ndp->a_size, sizeof(mus_float_t)); } mus_make_fir_coeffs(sp->filter_control_order, data, ndp->a); /* fill dp->a with new coeffs */ mus_filter_set_xcoeffs(ndp->flt, ndp->a); /* tell gen about them */ if (mus_filter_set_order(ndp->flt, sp->filter_control_order) < 0) /* fixup gen's order (and internal state array) */ snd_warning("trouble in filter (order not changed?)"); } } free(data); } sp->filter_control_changed = false; } if (dp->expanding) { mus_float_t ex, exincr; ex = dp->cur_exp; exincr = (sp->expand_control - ex) / (mus_float_t)(framples); for (j = 0; j < framples; j++, amp += incr, sr += sincr, ind += indincr, ex += exincr, rev += revincr) { fval = expand(dp, sr, ex); if (sp->contrast_control_on) fval = contrast(dp, amp, ind, fval); else fval *= amp; if (dp->filtering) fval = mus_fir_filter(dp->flt, fval); if (dp->reverbing) revin[j] += fval * rev; buf[j] += fval; } dp->cur_exp = ex; } else { if (dp->filtering) { for (j = 0; j < framples; j++, amp += incr, sr += sincr, ind += indincr, rev += revincr) { fval = speed(dp, sr); if (sp->contrast_control_on) fval = contrast(dp, amp, ind, fval); else fval *= amp; fval = mus_fir_filter(dp->flt, fval); if (dp->reverbing) revin[j] += fval * rev; buf[j] += fval; } } else { if (sp->contrast_control_on) { for (j = 0; j < framples; j++, amp += incr, sr += sincr, ind += indincr, rev += revincr) { fval = contrast(dp, amp, ind, speed(dp, sr)); if (dp->reverbing) revin[j] += fval * rev; buf[j] += fval; } } else { if (dp->never_sped) { for (j = 0; j < framples; j++, amp += incr, rev += revincr) { fval = amp * (*(dp->dac_sample))(dp); revin[j] += fval * rev; buf[j] += fval; } } else { for (j = 0; j < framples; j++, amp += incr, sr += sincr, rev += revincr) { fval = amp * speed(dp, sr); revin[j] += fval * rev; buf[j] += fval; } } } } } dp->cur_srate = sr; dp->cur_amp = amp; dp->cur_rev = rev; dp->cur_index = ind; break; } if ((dp->end != NO_END_SPECIFIED) && (dp->end != 0)) { if ((dp->chn_fd->cb == NULL) || ((dp->sp->speed_control_direction > 0) && ((dp->chn_fd->at_eof) || (dp->end <= current_location(dp->chn_fd)))) || ((dp->sp->speed_control_direction < 0) && (dp->end > current_location(dp->chn_fd)))) dp->end = 0; } } } /* fill-case loop through max_active_slot */ if (global_rev) for (i = 0; i < framples; i++) reverb(global_rev, rev_ins, dac_buffers, i); /* now hooks, stop-function etc */ for (i = 0; i <= max_active_slot; i++) { dp = play_list[i]; if (dp) { /* check for EOF or specified end point */ if (write_ok == WRITE_TO_DAC) /* not Apply */ { if (dp->end == 0) stop_playing(dp, WITH_HOOK, PLAY_COMPLETE); else { if ((dp->chn_fd) && (dp->chn_fd->at_eof)) { if (!(dp->expanding)) stop_playing(dp, WITH_HOOK, PLAY_COMPLETE); else { dp->expand_ring_framples -= framples; if (dp->expand_ring_framples <= 0) stop_playing(dp, WITH_HOOK, PLAY_COMPLETE); } } } } else /* Apply, always sets the end point explicitly */ { if (dp->end == 0) { stop_playing_all_sounds_without_hook(PLAY_COMPLETE); play_list_members = 0; max_active_slot = -1; } } } } /* stop-case loop through max_active_slot */ if ((global_rev) && (snd_dacp) && (play_list_members == 0)) { snd_dacp->reverb_ring_framples -= framples; if (snd_dacp->reverb_ring_framples <= 0) free_reverb(); } } /* now parcel these buffers out to the available devices */ if (snd_dacp) { #if (HAVE_OSS || HAVE_ALSA) if (write_ok == WRITE_TO_DAC) { dev_bufs = dac_buffers; for (i = 0; i < snd_dacp->devices; i++) if (dev_fd[i] != -1) { mus_file_write_buffer(snd_dacp->out_samp_type, 0, framples - 1, snd_dacp->chans_per_device[i], dev_bufs, (char *)(audio_bytes[i]), clipping(ss)); dev_bufs += snd_dacp->chans_per_device[i]; } for (i = 0; i < snd_dacp->devices; i++) if (dev_fd[i] != -1) { int bytes; bytes = snd_dacp->chans_per_device[i] * framples * mus_bytes_per_sample(snd_dacp->out_samp_type); mus_audio_write(dev_fd[i], (char *)(audio_bytes[i]), bytes); } } #else if (write_ok == WRITE_TO_DAC) { int bytes; mus_file_write_buffer(snd_dacp->out_samp_type, 0, framples - 1, snd_dacp->channels, dac_buffers, (char *)(audio_bytes[0]), clipping(ss)); bytes = snd_dacp->channels * framples * mus_bytes_per_sample(snd_dacp->out_samp_type); mus_audio_write(dev_fd[0], (char *)(audio_bytes[0]), bytes); } #endif } if (cursor_change) cursor_time = 0; return(framples); } /* -------------------------------- specialize mus_print -------------------------------- */ static mus_print_handler_t *old_dac_printer = NULL; static char *last_print = NULL; static void dac_mus_print(char *msg) { if (last_print) free(last_print); last_print = mus_strdup(msg); (*old_dac_printer)(msg); } static void set_dac_print(void) { if (last_print) free(last_print); last_print = NULL; if (old_dac_printer != dac_mus_print) old_dac_printer = mus_print_set_handler(dac_mus_print); } static void unset_dac_print(void) { mus_print_set_handler(old_dac_printer); } #if WITH_AUDIO static const char *describe_dac(void) { /* this is only called in dac_error and only then upon a failed mus_audio_open_output */ int players = 0, i; dac_info *ptr = NULL; for (i = 0; i < dac_max_sounds; i++) if (play_list[i]) { ptr = play_list[i]; players++; } if ((players == 1) && (ptr->sp)) return((const char *)(ptr->sp->short_filename)); return(""); } #endif static void dac_error(void) { stop_playing_all_sounds_without_hook(PLAY_ERROR); #if WITH_AUDIO snd_error("can't play %s: %s", describe_dac(), (last_print) ? last_print : "reason not known"); #endif } /* -------------------------------- initialize DAC -------------------------------- */ static void make_dac_buffers(void) { /* make the per-channel buffers and audio output buffers */ int bytes, i; if ((dac_buffers == NULL) || (dac_buffer_chans < snd_dacp->channels) || (dac_buffer_size < snd_dacp->framples)) { if (dac_buffers) { for (i = 0; i < dac_buffer_chans; i++) free(dac_buffers[i]); free(dac_buffers); } if (rev_ins) { for (i = 0; i < dac_buffer_chans; i++) free(rev_ins[i]); free(rev_ins); } dac_buffers = (mus_float_t **)calloc(snd_dacp->channels, sizeof(mus_float_t *)); rev_ins = (mus_float_t **)calloc(snd_dacp->channels, sizeof(mus_float_t *)); for (i = 0; i < snd_dacp->channels; i++) { dac_buffers[i] = (mus_float_t *)calloc(snd_dacp->framples, sizeof(mus_float_t)); rev_ins[i] = (mus_float_t *)calloc(snd_dacp->framples, sizeof(mus_float_t)); } dac_buffer_chans = snd_dacp->channels; dac_buffer_size = snd_dacp->framples; if (r_outs) free(r_outs); if (r_ins) free(r_ins); r_outs = (mus_float_t *)calloc(snd_dacp->channels, sizeof(mus_float_t)); r_ins = (mus_float_t *)calloc(snd_dacp->channels, sizeof(mus_float_t)); } bytes = snd_dacp->channels * dac_buffer_size * mus_bytes_per_sample(snd_dacp->out_samp_type); if ((audio_bytes_size < bytes) || (audio_bytes_devices < snd_dacp->devices)) { if (audio_bytes) { for (i = 0; i < audio_bytes_devices; i++) free(audio_bytes[i]); free(audio_bytes); } audio_bytes = (unsigned char **)calloc(snd_dacp->devices, sizeof(unsigned char *)); for (i = 0; i < snd_dacp->devices; i++) audio_bytes[i] = (unsigned char *)calloc(bytes, sizeof(unsigned char)); audio_bytes_size = bytes; audio_bytes_devices = snd_dacp->devices; } } static void stop_audio_output(void); #if (HAVE_ALSA || HAVE_OSS) /* Controls behavior of device selection logic below. No amount of logic * can make everybody happy all the time. The [i]logic below cannot always * produce the desired result but deleting it altogether will break the * systems that currently rely on it. Not wise without an external api * in place designed to select whatever the user _really_ wants. Till * then set this to "1" to always send to the first device. */ static int feed_first_device = 0; #define ALSA_MAX_DEVICES 64 static int alsa_devices[ALSA_MAX_DEVICES]; static int alsa_available_chans[ALSA_MAX_DEVICES]; static int alsa_max_chans[ALSA_MAX_DEVICES]; static int alsa_min_chans[ALSA_MAX_DEVICES]; static int alsa_max_chans_value = 0; static int alsa_max_chans_dev = 0; static bool audio_devices_scanned = false; static int alsa_devices_available = 0; void mus_audio_alsa_channel_info(int dev, int *info); void mus_audio_alsa_device_list(int sys, int size, int *val); int mus_audio_alsa_device_direction(int dev); static void scan_audio_devices(void) { int cards, card, devs, dev, d; int index = 0; int direction; int val[ALSA_MAX_DEVICES]; if (!audio_devices_scanned) { audio_devices_scanned = true; /* At this time * we always select the widest device if the requested channels fit into it. * Otherwise we try to combine devices, if all fails we modify snd settings * so that channel folding takes place. This is inefficient but works for now. */ cards = 1; index = 0; /* scan all cards and build a list of available output devices */ for (card = 0; card < cards; card++) { mus_audio_alsa_device_list(MUS_AUDIO_PACK_SYSTEM(card), ALSA_MAX_DEVICES, val); devs = val[0]; /* scan all devices in the card */ for (d = 0; d < devs; d++) { dev = val[d + 1]; direction = mus_audio_alsa_device_direction(MUS_AUDIO_PACK_SYSTEM(card) | dev); if (direction == 0) { /* remember output device */ alsa_devices[index++] = MUS_AUDIO_PACK_SYSTEM(card) | dev; if (index >= ALSA_MAX_DEVICES) goto NO_MORE_DEVICES; } } } NO_MORE_DEVICES: /* get channel availability for all devices */ for (d = 0; d < index; d++) { int chan_info[4]; alsa_available_chans[d] = 0; alsa_min_chans[d] = 0; alsa_max_chans[d] = 0; mus_audio_alsa_channel_info(alsa_devices[d], chan_info); alsa_available_chans[d] = chan_info[0]; alsa_min_chans[d] = chan_info[1]; alsa_max_chans[d] = chan_info[2]; if (alsa_max_chans[d] > alsa_max_chans_value) { /* remember widest device */ alsa_max_chans_value = alsa_max_chans[d]; alsa_max_chans_dev = d; } } } alsa_devices_available = index; } int mus_audio_alsa_samples_per_channel(int dev); static bool start_audio_output_1(void) { int i; /* -------------------- ALSA not OSS -------------------- */ if (mus_audio_api() == MUS_ALSA_API) { static int out_dev[ALSA_MAX_DEVICES]; int d, alloc_chans, alloc_devs; scan_audio_devices(); /* allocate devices for playback */ alloc_chans = 0; alloc_devs = 0; for (d = 0; d < ALSA_MAX_DEVICES; d++) out_dev[d] = -1; for (d = 0; d < MAX_DEVICES; d++) dev_fd[d] = -1; if (feed_first_device == 0) { /* see if widest device can accommodate all channels */ if (alsa_max_chans_value >= snd_dacp->channels) { out_dev[alloc_devs++] = alsa_max_chans_dev; alloc_chans += alsa_max_chans_value; } if (alloc_devs == 0) { /* try to use several devices */ int prev_samp_type = -1; for (d = 0; d < alsa_devices_available; d++) { int this_samp_type; this_samp_type = mus_audio_compatible_sample_type(alsa_devices[d]); if (prev_samp_type == -1) { prev_samp_type = this_samp_type; } /* samp_type for all selected devices should match */ if (this_samp_type == prev_samp_type) { out_dev[alloc_devs++] = d; alloc_chans += alsa_available_chans[d]; if (alloc_devs >= ALSA_MAX_DEVICES) break; } } if ((alloc_devs != 0) && (alloc_chans < snd_dacp->channels)) { /* not enough available channels, give up */ for (d = 0; d < ALSA_MAX_DEVICES; d++) out_dev[d] = -1; alloc_devs = 0; alloc_chans = 0; } if (alloc_devs == 0) { /* fold all channels into the first device */ out_dev[alloc_devs++] = 0; alloc_chans += alsa_available_chans[0]; } } } else { /* first device on first card is the one */ out_dev[alloc_devs++] = 0; alloc_chans += alsa_available_chans[0]; } snd_dacp->out_samp_type = mus_audio_compatible_sample_type(alsa_devices[out_dev[0]]); if (alloc_devs < 2) { /* see if we have a minimum sized frample to fill * FIXME: could this happen in more than one device? */ int c; c = alsa_min_chans[out_dev[0]]; if (c > snd_dacp->channels) { snd_dacp->channels = c; } } /* see if we have to fold channels */ if (alloc_chans < snd_dacp->channels) { if (dac_combines_channels(ss)) snd_warning("folding %d chans into %d ", snd_dacp->channels, alloc_chans); snd_dacp->channels = alloc_chans; } { int samples_per_channel; /* read the number of samples per channel the device wants buffered */ samples_per_channel = mus_audio_alsa_samples_per_channel(alsa_devices[out_dev[0]]); snd_dacp->framples = samples_per_channel; /* set_dac_size(snd_dacp->framples * mus_bytes_per_sample(snd_dacp->out_samp_type)); */ set_dac_size(samples_per_channel); /* bil 24-Mar-13 */ } /* open all allocated devices */ for (d = 0; d < alloc_devs; d++) { int channels; channels = alsa_available_chans[out_dev[d]]; if (alloc_chans <= alsa_available_chans[out_dev[d]]) { if (snd_dacp->channels < alsa_min_chans[out_dev[d]]) { channels = alsa_min_chans[out_dev[d]]; } else { channels = snd_dacp->channels; } } /* FIXME: assumes devices are same size... */ set_dac_print(); dev_fd[d] = mus_audio_open_output(alsa_devices[out_dev[d]], snd_dacp->srate, channels, snd_dacp->out_samp_type, snd_dacp->framples * channels * mus_bytes_per_sample(snd_dacp->out_samp_type)); unset_dac_print(); if (dev_fd[d] == -1) { /* could not open a device, close all others and quit playback */ int i; for (i = 0; i < d; i++) { mus_audio_close(alsa_devices[out_dev[i]]); } dac_error(); dac_running = false; if (global_rev) free_reverb(); max_active_slot = -1; return(false); } } snd_dacp->devices = alloc_devs; /* for now assume all are same number of chans */ snd_dacp->chans_per_device = (int *)calloc(snd_dacp->devices, sizeof(int)); for (i = 0; i < snd_dacp->devices; i++) snd_dacp->chans_per_device[i] = snd_dacp->channels / snd_dacp->devices; make_dac_buffers(); } else { /* -------------------- OSS not ALSA -------------------- */ /* api == MUS_OSS_API -- MUS_JACK_API should not intrude here because we're in HAVE_ALSA || HAVE_OSS */ int oss_available_chans = 2; if (snd_dacp->channels > 2) oss_available_chans = mus_audio_device_channels(MUS_AUDIO_DEFAULT); for (i = 0; i < MAX_DEVICES; i++) dev_fd[i] = -1; /* see if we can play 16 bit output */ snd_dacp->out_samp_type = mus_audio_compatible_sample_type(MUS_AUDIO_DEFAULT); /* removed PPC stuff here 30-Apr-12 */ if ((oss_available_chans < snd_dacp->channels) && (oss_available_chans > 0)) { if (dac_combines_channels(ss)) snd_warning("folding %d chans into %d ", snd_dacp->channels, oss_available_chans); snd_dacp->channels = oss_available_chans; } set_dac_print(); if (dev_fd[0] == MUS_ERROR) dev_fd[0] = mus_audio_open_output(MUS_AUDIO_DEFAULT, snd_dacp->srate, snd_dacp->channels, snd_dacp->out_samp_type, dac_size(ss)); unset_dac_print(); if (dev_fd[0] == MUS_ERROR) { dac_error(); stop_audio_output(); return(false); } snd_dacp->devices = (dev_fd[1] != -1) ? 2 : 1; snd_dacp->chans_per_device = (int *)calloc(snd_dacp->devices, sizeof(int)); for (i = 0; i < snd_dacp->devices; i++) snd_dacp->chans_per_device[i] = snd_dacp->channels / snd_dacp->devices; make_dac_buffers(); } return(true); } #else /* not ALSA or OSS */ static bool start_audio_output_1(void) { int i; int available_chans = 2; if (snd_dacp->channels > 2) available_chans = mus_audio_device_channels(MUS_AUDIO_DEFAULT); if (available_chans <= 0) { snd_warning("no available channels??"); return(false); } if (available_chans < snd_dacp->channels) { if (dac_combines_channels(ss)) snd_warning("folding %d chans into %d ", snd_dacp->channels, available_chans); snd_dacp->channels = available_chans; } for (i = 0; i < MAX_DEVICES; i++) dev_fd[i] = -1; snd_dacp->out_samp_type = mus_audio_device_sample_type(MUS_AUDIO_DEFAULT); set_dac_print(); if (dev_fd[0] == MUS_ERROR) dev_fd[0] = mus_audio_open_output(MUS_AUDIO_DEFAULT, snd_dacp->srate, snd_dacp->channels, snd_dacp->out_samp_type, dac_size(ss)); unset_dac_print(); if (dev_fd[0] == MUS_ERROR) { dac_error(); stop_audio_output(); return(false); } snd_dacp->devices = 1; snd_dacp->chans_per_device = (int *)calloc(snd_dacp->devices, sizeof(int)); for (i = 0; i < snd_dacp->devices; i++) snd_dacp->chans_per_device[i] = available_chans / snd_dacp->devices; make_dac_buffers(); return(true); } #endif static bool start_audio_output(void) { /* at this point the desired output srate and chans are set in dacp (via start_dac) */ dac_info *dp; cursor_time = 0; if (start_audio_output_1()) /* number of channels may be less than requested initially */ { int i; for (i = 0; i <= max_active_slot; i++) { dp = play_list[i]; if (dp) { /* deferred reverb allocation since start_audio_output_1 may force more chans open */ if ((dp->reverbing) && (dp->sp) && (global_rev == NULL)) make_reverb(dp->sp, snd_dacp->channels); if (dp->audio_chan >= snd_dacp->channels) { if (dac_combines_channels(ss)) dp->audio_chan %= snd_dacp->channels; else stop_playing(dp, WITHOUT_HOOK, PLAY_NO_CHANNEL); } } } dac_running = true; fill_dac_buffers(WRITE_TO_DAC); if (!snd_dacp) return(false); return(true); } return(false); } static void stop_audio_output(void) { int i; for (i = 0; i < MAX_DEVICES; i++) if (dev_fd[i] != -1) { mus_audio_close(dev_fd[i]); dev_fd[i] = -1; } dac_running = false; dac_pausing = false; if (global_rev) free_reverb(); max_active_slot = -1; } static idle_func_t dac_in_background(any_pointer_t ptr) { /* slice 0: try to open audio output devices and get ready to send samples * 1: loop sending data until the play_list is empty or some error (C-g) happens * 2: try to close all active outputs and remove background procedure */ if (snd_dacp == NULL) return(BACKGROUND_QUIT); switch (snd_dacp->slice) { case 0: if (start_audio_output()) { if (snd_dacp == NULL) return(BACKGROUND_QUIT); snd_dacp->slice = 1; return(BACKGROUND_CONTINUE); } else { free_dac_state(); return(BACKGROUND_QUIT); } break; case 1: fill_dac_buffers(WRITE_TO_DAC); if (snd_dacp == NULL) return(BACKGROUND_QUIT); /* dac-hook called stop-playing or something equally perverse */ if ((global_rev == NULL) && (play_list_members == 0)) snd_dacp->slice = 2; return(BACKGROUND_CONTINUE); break; case 2: stop_audio_output(); free_dac_state(); #if USE_GTK /* in gtk: * (play) * (apply-controls) ; while playing * -> segfault and many other weird problems * This bug appears to be in gtk -- if a background function returns false, it is not supposed to be called * again. But for some reason gtk continues to call dac_in_background after I return false. I haven't * tracked this down in the glib sources (glib/gmain.c) -- I suspect that they're "destroying" the "source" * (in their jargon) before checking whether to remove the function from the poll list. Or possibly, * I'm destroying it somewhere -- in any case, I'll stop the thing by hand. */ if (dac_work_proc) { BACKGROUND_REMOVE(dac_work_proc); dac_work_proc = 0; } #endif return(BACKGROUND_QUIT); break; } return(BACKGROUND_QUIT); } /* ---------------- support for Apply button (snd-apply.c) ---------------- */ void initialize_apply(snd_info *sp, int chans, mus_long_t beg, mus_long_t dur) { int curchan = 0; stop_playing_all_sounds_without_hook(PLAY_APPLY); /* see note above about gtk and work procs */ if (snd_dacp) /* may not have been able to complete despite slice=2 in stop all */ { snd_dacp->slice = 2; dac_in_background(NULL); /* so try to force completion */ } if (chans <= 0) return; max_active_slot = -1; play_list_members = 0; dac_running = true; /* this keeps start_dac from actually starting the dac */ if (snd_dacp) free_dac_state(); snd_dacp = (dac_state *)calloc(1, sizeof(dac_state)); snd_dacp->slice = 0; snd_dacp->srate = snd_srate(sp); snd_dacp->out_samp_type = MUS_AUDIO_COMPATIBLE_SAMPLE_TYPE; if (snd_dacp->srate <= 0) snd_dacp->srate = 44100; snd_dacp->channels = chans; snd_dacp->framples = 8192; snd_dacp->devices = 1; snd_dacp->chans_per_device = (int *)calloc(1, sizeof(int)); snd_dacp->chans_per_device[0] = chans; snd_dacp->reverb_ring_framples = (mus_long_t)(snd_dacp->srate * sp->reverb_control_decay); make_dac_buffers(); switch (ss->apply_choice) { case APPLY_TO_SOUND: play_sound(sp, beg, beg + dur); break; case APPLY_TO_SELECTION: play_selection(IN_BACKGROUND); break; case APPLY_TO_CHANNEL: if (sp->selected_channel != NO_SELECTION) curchan = sp->selected_channel; play_channel(sp->chans[curchan], beg, beg + dur); break; } } void finalize_apply(snd_info *sp) { /* if no reverb, these need to be cleaned up */ stop_playing_all_sounds_without_hook(PLAY_APPLY); max_active_slot = -1; play_list_members = 0; sp->playing = 0; dac_running = false; if (snd_dacp) free_dac_state(); if (global_rev) free_reverb(); } int run_apply(int ofd) { int len, chans; if (!(snd_dacp)) return(-1); chans = snd_dacp->channels; /* snd_dacp might be freed by fill_dac_buffers */ len = fill_dac_buffers(WRITE_TO_FILE); mus_file_write(ofd, 0, len - 1, chans, dac_buffers); return(len); } /* -------- players -------- */ static snd_info **players = NULL; static int *player_chans = NULL; static int players_size = 0; static int new_player_index(void) { int i, old_size; if (players_size == 0) { players_size = 8; players = (snd_info **)calloc(players_size, sizeof(snd_info *)); player_chans = (int *)calloc(players_size, sizeof(int)); return(-1); } for (i = 1; i < players_size; i++) if (players[i] == NULL) return(-i); old_size = players_size; players_size += 8; players = (snd_info **)realloc(players, players_size * sizeof(snd_info *)); player_chans = (int *)realloc(player_chans, players_size * sizeof(int)); for (i = old_size; i < players_size; i++) { players[i] = NULL; player_chans[i] = 0; } return(-old_size); } #define PLAYER(Sp) -(Sp->index) static int make_player(snd_info *sp, chan_info *cp) { /* store sp so we can access it via find_sound (get_sp) later */ players[PLAYER(sp)] = sp; player_chans[PLAYER(sp)] = cp->chan; return(-sp->index); } static void free_player_sound(snd_info *sp) { if (players) { players[PLAYER(sp)] = NULL; player_chans[PLAYER(sp)] = 0; } free(sp->filename); sp->filename = NULL; free(sp->chans); sp->chans = NULL; if (sp->filter_control_envelope) sp->filter_control_envelope = free_env(sp->filter_control_envelope); sp->inuse = SOUND_IDLE; free(sp); } void clear_players(void) { /* called only in free_snd_info, snd-data.c -- make sure currently closing sound is not playing (via a user-created player) */ int i; for (i = 0; i < players_size; i++) { int j; snd_info *sp; sp = players[i]; if (sp) for (j = 0; j < sp->nchans; j++) if ((sp->chans[j] == NULL) || (sp->chans[j]->active < CHANNEL_HAS_EDIT_LIST) || (sp->chans[j]->sound == NULL)) { int k; for (k = 0; k <= max_active_slot; k++) { dac_info *dp; dp = play_list[k]; if ((dp) && (sp == dp->sp)) { play_list[k] = NULL; play_list_members--; free_dac_info(dp, PLAY_CLOSE); /* calls stop-function, if any. used in snd-data.c in free_snd_info */ } } if (is_player_sound(sp)) free_player_sound(sp); break; } } } /* ---------------------------------------- player objects ---------------------------------------- */ typedef struct { int n; } xen_player; #define Xen_to_xen_player(arg) ((xen_player *)Xen_object_ref(arg)) static int xen_player_to_int(Xen n) { xen_player *mx; mx = Xen_to_xen_player(n); return(mx->n); } #define Xen_player_to_C_int(Player) xen_player_to_int(Player) snd_info *get_player_sound(Xen obj) { return(players[xen_player_to_int(obj)]); } static Xen_object_type_t xen_player_tag; bool xen_is_player(Xen obj) { return(Xen_c_object_is_type(obj, xen_player_tag)); } static void xen_player_free(xen_player *v) {if (v) free(v);} Xen_wrap_free(xen_player, free_xen_player, xen_player_free) static char *xen_player_to_string(xen_player *v) { #define PLAYER_PRINT_BUFFER_SIZE 64 char *buf; if (v == NULL) return(NULL); buf = (char *)calloc(PLAYER_PRINT_BUFFER_SIZE, sizeof(char)); snprintf(buf, PLAYER_PRINT_BUFFER_SIZE, "#", v->n); return(buf); } Xen_wrap_print(xen_player, print_xen_player, xen_player_to_string) #if HAVE_FORTH || HAVE_RUBY static Xen g_xen_player_to_string(Xen obj) { char *vstr; Xen result; #define S_xen_player_to_string "player->string" Xen_check_type(xen_is_player(obj), obj, 1, S_xen_player_to_string, "a player"); vstr = xen_player_to_string(Xen_to_xen_player(obj)); result = C_string_to_Xen_string(vstr); free(vstr); return(result); } #endif #if (!HAVE_SCHEME) static bool xen_player_equalp(xen_player *v1, xen_player *v2) { return((v1 == v2) || (v1->n == v2->n)); } static Xen equalp_xen_player(Xen obj1, Xen obj2) { if ((!(xen_is_player(obj1))) || (!(xen_is_player(obj2)))) return(Xen_false); return(C_bool_to_Xen_boolean(xen_player_equalp(Xen_to_xen_player(obj1), Xen_to_xen_player(obj2)))); } #endif static xen_player *xen_player_make(int n) { xen_player *new_v; new_v = (xen_player *)malloc(sizeof(xen_player)); new_v->n = n; return(new_v); } static Xen new_xen_player(int n) { xen_player *mx; if (n < 0) return(Xen_false); mx = xen_player_make(n); return(Xen_make_object(xen_player_tag, mx, 0, free_xen_player)); } #define C_int_to_Xen_player(val) new_xen_player(val) #if HAVE_SCHEME static bool s7_xen_player_equalp(void *obj1, void *obj2) { return((obj1 == obj2) || (((xen_player *)obj1)->n == ((xen_player *)obj2)->n)); } static Xen s7_xen_player_length(s7_scheme *sc, Xen player) { chan_info *cp; int index; index = Xen_player_to_C_int(player); cp = players[index]->chans[player_chans[index]]; return(C_llong_to_Xen_llong(current_samples(cp))); } #endif static void init_xen_player(void) { #if HAVE_SCHEME xen_player_tag = s7_new_type_x(s7, "", print_xen_player, free_xen_player, s7_xen_player_equalp, NULL, NULL, NULL, s7_xen_player_length, NULL, NULL, NULL); #else #if HAVE_RUBY xen_player_tag = Xen_make_object_type("XenPlayer", sizeof(xen_player)); #else xen_player_tag = Xen_make_object_type("Player", sizeof(xen_player)); #endif #endif #if HAVE_FORTH fth_set_object_inspect(xen_player_tag, print_xen_player); fth_set_object_dump(xen_player_tag, g_xen_player_to_string); fth_set_object_equal(xen_player_tag, equalp_xen_player); fth_set_object_free(xen_player_tag, free_xen_player); #endif #if HAVE_RUBY rb_define_method(xen_player_tag, "to_s", Xen_procedure_cast print_xen_player, 0); rb_define_method(xen_player_tag, "eql?", Xen_procedure_cast equalp_xen_player, 1); rb_define_method(xen_player_tag, "==", Xen_procedure_cast equalp_xen_player, 1); rb_define_method(xen_player_tag, "to_str", Xen_procedure_cast g_xen_player_to_string, 0); #endif } /* -------------------------------------------------------------------------------- */ static Xen play_file(const char *play_name, mus_long_t start, mus_long_t end, int in_channel, int out_channel, play_process_t background, Xen stop_func) { snd_info *sp; if (!(mus_file_probe(play_name))) return(snd_no_such_file_error(S_play, C_string_to_Xen_string(play_name))); if (!(mus_is_header_type(mus_sound_header_type(play_name)))) Xen_error(BAD_HEADER, Xen_list_3(C_string_to_Xen_string(S_play ": ~S has unknown header: ~A"), C_string_to_Xen_string(play_name), C_string_to_Xen_string(mus_header_type_name(mus_header_type())))); if (!(mus_is_sample_type(mus_sound_sample_type(play_name)))) Xen_error(Xen_make_error_type("bad-sample-type"), Xen_list_3(C_string_to_Xen_string(S_play ": ~S has unknown sample type: ~A"), C_string_to_Xen_string(play_name), C_string_to_Xen_string(mus_header_original_sample_type_name(mus_sound_original_sample_type(play_name), mus_sound_header_type(play_name))))); sp = make_sound_readable(play_name, false); sp->short_filename = filename_without_directory(play_name); sp->filename = NULL; sp->delete_me = (void *)1; if (in_channel != -1) play_channel_1(sp->chans[in_channel], start, end, background, 0, stop_func, (out_channel < 0) ? 0 : out_channel); else play_sound_1(sp, start, end, background, Xen_integer_zero, stop_func, S_play, -1); return(Xen_false); } static Xen kw_start, kw_end, kw_channel, kw_wait, kw_edit_position, kw_stop, kw_out_channel, kw_with_sync, kw_srate, kw_channels; static void init_play_keywords(void) { kw_start = Xen_make_keyword("start"); kw_end = Xen_make_keyword("end"); kw_wait = Xen_make_keyword("wait"); kw_channel = Xen_make_keyword("channel"); kw_out_channel = Xen_make_keyword("out-channel"); kw_edit_position = Xen_make_keyword("edit-position"); kw_stop = Xen_make_keyword("stop"); kw_with_sync = Xen_make_keyword("with-sync"); kw_srate = Xen_make_keyword("srate"); kw_channels = Xen_make_keyword("channels"); } static Xen g_play(Xen arglist) { #if HAVE_SCHEME #define play_example "(play \"oboe.snd\")" #endif #if HAVE_RUBY #define play_example "play(\"oboe.snd\")" #endif #if HAVE_FORTH #define play_example "\"oboe.snd\" play" #endif #define H_play "(" S_play " object :start :end :channel :edit-position :out-channel :with-sync :wait :stop): \ play the object from start to end. If channel is not given, play all channels. If with-sync, play all objects sync'd \ to the current object. If wait, wait for the play process to finish before going on. If out-channel, send the samples \ to that DAC channel. If edit-position, play that member of the edit list, otherwise play the current state of the object. \ If stop, call that function when the play process finishes. \ If object is a string, it is assumed to be a file name: \n " play_example "\n." Xen object = Xen_undefined; mus_long_t start = 0, end = NO_END_SPECIFIED; int channel = -1, out_channel = -1, srate = 44100, channels = 2, edpos_argpos = 0, channel_argpos = 0; bool with_sync = false, wait = false; Xen stop_func = Xen_false, edit_position = Xen_false, channel_arg = Xen_false; play_process_t background; snd_info *sp; if (!Xen_is_null(arglist)) { #define NARGS 10 Xen args[NARGS * 2]; Xen keys[NARGS]; int orig_arg[NARGS] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; int vals, i, arglist_len; if (!Xen_is_keyword(Xen_car(arglist))) { object = Xen_car(arglist); arglist = Xen_cdr(arglist); } keys[0] = kw_start; keys[1] = kw_end; keys[2] = kw_channel; keys[3] = kw_edit_position; keys[4] = kw_out_channel; keys[5] = kw_with_sync; keys[6] = kw_wait; keys[7] = kw_stop; keys[8] = kw_srate; keys[9] = kw_channels; for (i = 0; i < NARGS * 2; i++) args[i] = Xen_undefined; arglist_len = Xen_list_length(arglist); if (arglist_len > NARGS) Xen_out_of_range_error(S_play, 0, arglist, "too many arguments"); for (i = 0; i < arglist_len; i++) args[i] = Xen_list_ref(arglist, i); vals = mus_optkey_unscramble(S_play, NARGS, keys, args, orig_arg); if (vals > 0) { start = mus_optkey_to_mus_long_t(keys[0], S_play, orig_arg[0], start); if (start < 0) Xen_out_of_range_error(S_play, orig_arg[0], keys[0], "start is negative?"); end = mus_optkey_to_mus_long_t(keys[1], S_play, orig_arg[1], end); if (end < -1) Xen_out_of_range_error(S_play, orig_arg[1], keys[1], "end is negative?"); channel = mus_optkey_to_int(keys[2], S_play, orig_arg[2], channel); channel_argpos = orig_arg[2]; channel_arg = keys[2]; if (!(Xen_is_keyword(keys[3]))) { edit_position = keys[3]; edpos_argpos = orig_arg[3]; } out_channel = mus_optkey_to_int(keys[4], S_play, orig_arg[4], out_channel); with_sync = mus_optkey_to_bool(keys[5], S_play, orig_arg[5], with_sync); wait = mus_optkey_to_bool(keys[6], S_play, orig_arg[6], wait); stop_func = mus_optkey_to_procedure(keys[7], S_play, orig_arg[7], stop_func, 1, "play stop function takes 1 argument"); srate = mus_optkey_to_int(keys[8], S_play, orig_arg[8], srate); if (srate <= 0) Xen_out_of_range_error(S_play, orig_arg[8], keys[8], "srate <= 0?"); channels = mus_optkey_to_int(keys[9], S_play, orig_arg[9], channels); if (channels <= 0) Xen_out_of_range_error(S_play, orig_arg[9], keys[9], "channels <= 0?"); } } #if USE_NO_GUI background = NOT_IN_BACKGROUND; #else if (wait) background = NOT_IN_BACKGROUND; else background = IN_BACKGROUND; /* confusing! wait=#f means don't wait for the play to complete => IN_BACKGROUND */ #endif /* unspecified object means the current sound, all chans, all samps, with sync, without wait, current edpos */ if (!Xen_is_bound(object)) { sp = any_selected_sound(); if (sp) play_sound_1(sp, start, end, background, C_int_to_Xen_integer(AT_CURRENT_EDIT_POSITION), Xen_false, NULL, 0); return(Xen_false); } /* #f object means start sending out zeros */ if (Xen_is_false(object)) return(C_bool_to_Xen_boolean(add_zeros_to_play_list(srate, channels))); /* procedure object means add that function to the play list */ if (Xen_is_procedure(object)) return(C_bool_to_Xen_boolean(add_xen_to_play_list(object))); /* mix object */ if (xen_is_mix(object)) return(g_play_mix(object, start)); /* selection object */ if (xen_is_selection(object)) { if (selection_is_active()) play_selection_1(background, stop_func); return(object); } /* region object */ if (xen_is_region(object)) return(g_play_region(object, background, stop_func)); /* string object = filename */ if (Xen_is_string(object)) { char *name; name = mus_expand_filename(Xen_string_to_C_string(object)); play_file((const char *)name, start, end, channel, out_channel, background, stop_func); free(name); return(object); } /* otherwise object is either a player or a sound */ if (xen_is_player(object)) sp = get_player_sound(object); else sp = get_sp(object); if (sp == NULL) return(snd_no_such_sound_error(S_play, object)); if ((with_sync) && (sp->sync != 0) && (!(is_player_sound(sp)))) { sync_info *si; mus_long_t *ends = NULL; int i; si = snd_sync(sp->sync); if (end != NO_END_SPECIFIED) { ends = (mus_long_t *)calloc(si->chans, sizeof(mus_long_t)); for (i = 0; i < si->chans; i++) ends[i] = end; } for (i = 0; i < si->chans; i++) si->begs[i] = start; play_channels_1(si->cps, si->chans, si->begs, ends, background, edit_position, false, stop_func, S_play, edpos_argpos); si = free_sync_info(si); if (ends) free(ends); return(Xen_false); } if (channel == -1) play_sound_1(sp, start, end, background, edit_position, stop_func, S_play, edpos_argpos); else { if ((channel < sp->nchans) && (channel >= 0)) { int pos; chan_info *cp; cp = sp->chans[channel]; if (out_channel < 0) out_channel = channel; pos = to_c_edit_position(cp, edit_position, S_play, edpos_argpos); play_channel_1(cp, start, end, background, pos, stop_func, out_channel); } else Xen_out_of_range_error(S_play, channel_argpos, channel_arg, "channel does not exist?"); } return(object); } Xen no_such_player_error(const char *caller, Xen player) { Xen_error(Xen_make_error_type("no-such-player"), Xen_list_3(C_string_to_Xen_string("~A: no such player, ~A"), C_string_to_Xen_string(caller), player)); return(Xen_false); } static Xen g_stop_playing(Xen snd) { #define H_stop_playing "(" S_stop_playing " :optional snd): stop play (DAC output) in progress" snd_info *sp = NULL; Xen_check_type(Xen_is_integer(snd) || xen_is_sound(snd) || !Xen_is_bound(snd) || xen_is_player(snd), snd, 1, S_stop_playing, "a sound or player"); if (Xen_is_integer(snd) || xen_is_sound(snd)) { sp = get_sp(snd); if (!sp) return(snd_no_such_sound_error(S_stop_playing, snd)); } else { if (xen_is_player(snd)) { sp = get_player_sound(snd); if (!sp) return(no_such_player_error(S_stop_playing, snd)); } } if (sp) stop_playing_sound(sp, PLAY_STOP_CALLED); else stop_playing_all_sounds(PLAY_STOP_CALLED); return(Xen_false); } /* add-player make-player stop-player start-playing */ static Xen g_make_player(Xen snd, Xen chn) { #define H_make_player "(" S_make_player " :optional snd chn): \ make a new player associated with snd's channel chn. \ A player is a sort of wrapper for a channel of a sound; it supports \ all the control panel functions. Once created, you can set these \ fields, then call " S_add_player " to add this channel to the list of \ channels either being played (if a play is in progress) or about \ to be played (via " S_start_playing ")." snd_info *true_sp, *new_sp; chan_info *cp; Snd_assert_channel(S_make_player, snd, chn, 1); true_sp = get_sp(snd); if (true_sp == NULL) return(snd_no_such_sound_error(S_make_player, snd)); cp = get_cp(snd, chn, S_make_player); new_sp = make_snd_info(NULL, "make_player:wrapper", true_sp->hdr, new_player_index(), FILE_READ_ONLY); new_sp->chans[cp->chan] = cp; return(C_int_to_Xen_player(make_player(new_sp, cp))); } static Xen g_player_home(Xen player) { #define H_player_home "(" S_player_home " player): a list of the sound index and channel number associated with player" int index; Xen_check_type(xen_is_player(player), player, 1, S_player_home, "a player"); index = Xen_player_to_C_int(player); if ((index > 0) && (index < players_size) && (players[index]) && (players[index]->chans) && (player_chans[index] < players[index]->nchans)) { chan_info *cp; cp = players[index]->chans[player_chans[index]]; /* trying to get back to the original sound index (not the player index) */ if ((cp->sound) && (cp->sound->active)) return(Xen_list_2(C_int_to_Xen_sound(cp->sound->index), C_int_to_Xen_integer(cp->chan))); return(Xen_false); /* can this happen? */ } return(no_such_player_error(S_player_home, player)); } static Xen g_add_player(Xen player, Xen start, Xen end, Xen edpos, Xen stop_proc, Xen out_chan) { #define H_add_player "(" S_add_player " player :optional (start 0) (end len) (pos -1) stop-proc (out-chan player-chan)): \ adds a player to the play list; the play begins when " S_start_playing " is called. \ The start, end, and edit-position of the portion played can be specified. 'out-chan' is \ the audio hardware output channel to use to play this channel. It defaults to the \ channel number in the sound that contains the channel being played." snd_info *sp = NULL; int index, pos; chan_info *cp; dac_info *dp = NULL; int i, ochan = -1; Xen_check_type(xen_is_player(player), player, 1, S_add_player, "a player"); Xen_check_type(Xen_is_integer_or_unbound(start), start, 2, S_add_player, "an integer"); Xen_check_type(Xen_is_integer_or_unbound(end), end, 3, S_add_player, "an integer"); Xen_check_type(((Xen_is_procedure(stop_proc)) && (procedure_arity_ok(stop_proc, 1))) || (!Xen_is_bound(stop_proc)) || (Xen_is_false(stop_proc)), stop_proc, 5, S_add_player, "a procedure of 1 arg"); Xen_check_type(Xen_is_integer_or_unbound(out_chan), out_chan, 6, S_add_player, "an integer"); index = Xen_player_to_C_int(player); if ((index > 0) && (index < players_size)) sp = players[index]; if (!sp) return(no_such_player_error(S_add_player, player)); if (play_list) for (i = 0; i < dac_max_sounds; i++) if ((play_list[i]) && (sp == (play_list[i]->sp))) Xen_error(Xen_make_error_type("arg-error"), Xen_list_2(C_string_to_Xen_string(S_add_player ": player ~A is already in the play list"), player)); cp = sp->chans[player_chans[index]]; pos = to_c_edit_position(cp, edpos, S_add_player, 4); if (Xen_is_integer(out_chan)) ochan = Xen_integer_to_C_int(out_chan); if (ochan < 0) ochan = cp->chan; dp = add_channel_to_play_list(cp, sp, /* this is not cp->sound! */ beg_to_sample(start, S_add_player), (Xen_is_llong(end)) ? Xen_llong_to_C_llong(end) : NO_END_SPECIFIED, pos, ochan); if (dp == NULL) return(Xen_false); dp->stop_procedure = stop_proc; if (Xen_is_procedure(stop_proc)) dp->stop_procedure_gc_loc = snd_protect(stop_proc); return(player); } static Xen g_start_playing(Xen Chans, Xen Srate, Xen In_Background) { #define H_start_playing "(" S_start_playing " :optional (chans 1) (srate 44100) (in-background " PROC_TRUE ")): \ If a play-list is waiting, start it." int chans = 1, srate = 44100; bool back; Xen_check_type(Xen_is_integer_or_unbound(Chans), Chans, 1, S_start_playing, "an integer"); Xen_check_type(Xen_is_integer_or_unbound(Srate), Srate, 2, S_start_playing, "an integer"); Xen_check_type(Xen_is_boolean_or_unbound(In_Background), In_Background, 3, S_start_playing, "a boolean"); if (Xen_is_integer(Chans)) chans = Xen_integer_to_C_int(Chans); if ((chans <= 0) || (chans > 256)) Xen_out_of_range_error(S_start_playing, 1, Chans, "chans <= 0 or > 256?"); if (Xen_is_integer(Srate)) srate = Xen_integer_to_C_int(Srate); if (srate <= 0) Xen_out_of_range_error(S_start_playing, 2, Srate, "srate <= 0?"); back = Xen_boolean_to_C_bool(In_Background); start_dac(srate, chans, (back) ? IN_BACKGROUND : NOT_IN_BACKGROUND, DEFAULT_REVERB_CONTROL_DECAY); return(Xen_false); } static Xen g_stop_player(Xen player) { #define H_stop_player "(" S_stop_player " player): stop player and remove its associated sound from the current DAC playlist" snd_info *sp = NULL; Xen_check_type(xen_is_player(player), player, 1, S_stop_player, "a player"); sp = get_player_sound(player); if (sp) stop_playing_sound(sp, PLAY_STOP_CALLED); return(player); } static Xen g_free_player(Xen player) { #define H_free_player "(" S_free_player " player): free all resources associated with 'player' and remove it from the current DAC playlist" snd_info *sp = NULL; Xen_check_type(xen_is_player(player), player, 1, S_free_player, "a player"); sp = get_player_sound(player); if (sp) free_player_sound(sp); return(Xen_false); } /* also the dac filler needs to run on empty buffers in this case? */ static Xen g_is_player(Xen obj) { #define H_is_player "(" S_is_player " obj): is 'obj' an active player" if (xen_is_player(obj)) { int index; index = Xen_player_to_C_int(obj); return(C_bool_to_Xen_boolean((index > 0) && (index < players_size) && (players[index]))); } return(Xen_false); } /* player-position? -- need quick way from index to dp to its sampler, then C_llong_to_Xen_llong(current_location(fd)) */ static Xen g_players(void) { #define H_players "(" S_players ") -> list of currently active players." Xen lst = Xen_empty_list; int i; for (i = 0; i < players_size; i++) if (players[i]) lst = Xen_cons(C_int_to_Xen_player(i), lst); return(lst); } static Xen g_dac_size(void) {return(C_int_to_Xen_integer(dac_size(ss)));} static Xen g_set_dac_size(Xen val) { #define H_dac_size "(" S_dac_size "): the current DAC buffer size in framples (256)" int len; Xen_check_type(Xen_is_integer(val), val, 1, S_set S_dac_size, "an integer"); len = Xen_integer_to_C_int(val); if (len > 0) set_dac_size(len); /* macro in snd-0.h */ return(C_int_to_Xen_integer(dac_size(ss))); } static Xen g_dac_combines_channels(void) {return(C_bool_to_Xen_boolean(dac_combines_channels(ss)));} static Xen g_set_dac_combines_channels(Xen val) { #define H_dac_combines_channels "(" S_dac_combines_channels "): " PROC_TRUE " if extra channels are to be mixed into available ones during playing. \ That is, if the sound to be played has 4 channels, but the DAC can only handle 2, if this \ variable is " PROC_TRUE ", the extra channels are mixed into the available ones; otherwise they are ignored." Xen_check_type(Xen_is_boolean(val), val, 1, S_set S_dac_combines_channels, "a boolean"); set_dac_combines_channels(Xen_boolean_to_C_bool(val)); return(C_bool_to_Xen_boolean(dac_combines_channels(ss))); } static Xen g_playing(void) { #define H_playing "(" S_playing "): " PROC_TRUE " if sound output is in progress. If players are waiting to start, \ setting this to " PROC_TRUE " starts them; setting it to " PROC_FALSE " stops output." return(C_bool_to_Xen_boolean(something_is_playing())); } static Xen g_set_playing(Xen on) { bool starting = false; Xen_check_type(Xen_is_boolean(on), on, 1, S_set S_playing, "a boolean"); starting = Xen_boolean_to_C_bool(on); if (starting) start_dac((int)mus_srate(), 1, IN_BACKGROUND, DEFAULT_REVERB_CONTROL_DECAY); /* how to get plausible srate chans here? */ else stop_playing_all_sounds(PLAY_STOP_CALLED); return(on); } static Xen g_pausing(void) { #define H_pausing "(" S_pausing "): " PROC_TRUE " if sound output is currently pausing (this can be set)." return(C_bool_to_Xen_boolean(dac_pausing)); } static Xen g_set_pausing(Xen pause) { Xen_check_type(Xen_is_boolean(pause), pause, 1, S_set S_pausing, "a boolean"); dac_pausing = Xen_boolean_to_C_bool(pause); play_button_pause(dac_pausing); return(pause); } static Xen g_cursor_update_interval(void) {return(C_double_to_Xen_real(cursor_update_interval(ss)));} static Xen g_set_cursor_update_interval(Xen val) { mus_float_t ctime; #define H_cursor_update_interval "(" S_cursor_update_interval "): time (seconds) between cursor updates if " S_with_tracking_cursor "." Xen_check_type(Xen_is_number(val), val, 1, S_set S_cursor_update_interval, "a number"); ctime = Xen_real_to_C_double(val); if ((ctime < 0.0) || (ctime > (24 * 3600))) Xen_out_of_range_error(S_set S_cursor_update_interval, 1, val, "invalid time"); set_cursor_update_interval(ctime); return(C_double_to_Xen_real(cursor_update_interval(ss))); } static Xen g_cursor_location_offset(void) {return(C_int_to_Xen_integer(cursor_location_offset(ss)));} static Xen g_set_cursor_location_offset(Xen val) { int ctime; #define H_cursor_location_offset "(" S_cursor_location_offset "): samples added to cursor location if cursor displayed during play." Xen_check_type(Xen_is_integer(val), val, 1, S_set S_cursor_location_offset, "an integer"); ctime = Xen_integer_to_C_int(val); set_cursor_location_offset(ctime); return(C_int_to_Xen_integer(cursor_location_offset(ss))); } static Xen g_with_tracking_cursor(void) { #define H_with_tracking_cursor "(" S_with_tracking_cursor "): " PROC_TRUE " if cursor always moves along in waveform display as sound is played" if (with_tracking_cursor(ss) == DONT_TRACK) return(Xen_false); if (with_tracking_cursor(ss) == TRACK_AND_RETURN) return(Xen_true); return(Xen_make_keyword("track-and-stay")); } static Xen g_set_with_tracking_cursor(Xen on) { if (Xen_is_boolean(on)) /* for backwards compatibility */ { set_with_tracking_cursor(ss, (Xen_boolean_to_C_bool(on)) ? TRACK_AND_RETURN : DONT_TRACK); return(on); } if (Xen_is_integer(on)) { int val; val = Xen_integer_to_C_int(on); if (val == 2) set_with_tracking_cursor(ss, TRACK_AND_STAY); else set_with_tracking_cursor(ss, ((val == 1) ? TRACK_AND_RETURN : DONT_TRACK)); return(C_int_to_Xen_integer((int)with_tracking_cursor(ss))); } if (Xen_is_keyword(on)) { if (Xen_keyword_is_eq(on, Xen_make_keyword("track-and-return"))) { set_with_tracking_cursor(ss, TRACK_AND_RETURN); return(on); } if (Xen_keyword_is_eq(on, Xen_make_keyword("track-and-stay"))) { set_with_tracking_cursor(ss, TRACK_AND_STAY); return(on); } if (Xen_keyword_is_eq(on, Xen_make_keyword("dont-track"))) { set_with_tracking_cursor(ss, DONT_TRACK); return(on); } } Xen_check_type(false, on, 1, S_set S_with_tracking_cursor, ":dont-track, :track-and-return, or :track-and-stay"); return(on); } Xen_wrap_no_args(g_with_tracking_cursor_w, g_with_tracking_cursor) Xen_wrap_1_arg(g_set_with_tracking_cursor_w, g_set_with_tracking_cursor) Xen_wrap_any_args(g_play_w, g_play) Xen_wrap_1_optional_arg(g_stop_playing_w, g_stop_playing) Xen_wrap_2_optional_args(g_make_player_w, g_make_player) Xen_wrap_6_optional_args(g_add_player_w, g_add_player) Xen_wrap_1_arg(g_player_home_w, g_player_home) Xen_wrap_3_optional_args(g_start_playing_w, g_start_playing) Xen_wrap_1_arg(g_stop_player_w, g_stop_player) Xen_wrap_1_arg(g_free_player_w, g_free_player) Xen_wrap_no_args(g_players_w, g_players) Xen_wrap_1_arg(g_is_player_w, g_is_player) Xen_wrap_no_args(g_dac_size_w, g_dac_size) Xen_wrap_1_arg(g_set_dac_size_w, g_set_dac_size) Xen_wrap_no_args(g_dac_combines_channels_w, g_dac_combines_channels) Xen_wrap_1_arg(g_set_dac_combines_channels_w, g_set_dac_combines_channels) Xen_wrap_no_args(g_playing_w, g_playing) Xen_wrap_1_arg(g_set_playing_w, g_set_playing) Xen_wrap_no_args(g_pausing_w, g_pausing) Xen_wrap_1_arg(g_set_pausing_w, g_set_pausing) Xen_wrap_no_args(g_cursor_update_interval_w, g_cursor_update_interval) Xen_wrap_1_arg(g_set_cursor_update_interval_w, g_set_cursor_update_interval) Xen_wrap_no_args(g_cursor_location_offset_w, g_cursor_location_offset) Xen_wrap_1_arg(g_set_cursor_location_offset_w, g_set_cursor_location_offset) #if HAVE_SCHEME static s7_pointer acc_cursor_location_offset(s7_scheme *sc, s7_pointer args) {return(g_set_cursor_location_offset(s7_cadr(args)));} static s7_pointer acc_cursor_update_interval(s7_scheme *sc, s7_pointer args) {return(g_set_cursor_update_interval(s7_cadr(args)));} static s7_pointer acc_dac_combines_channels(s7_scheme *sc, s7_pointer args) {return(g_set_dac_combines_channels(s7_cadr(args)));} static s7_pointer acc_dac_size(s7_scheme *sc, s7_pointer args) {return(g_set_dac_size(s7_cadr(args)));} static s7_pointer acc_with_tracking_cursor(s7_scheme *sc, s7_pointer args) {return(g_set_with_tracking_cursor(s7_cadr(args)));} #endif void g_init_dac(void) { init_xen_player(); init_play_keywords(); Xen_define_procedure(S_play, g_play_w, 0, 0, 1, H_play); Xen_define_procedure(S_stop_playing, g_stop_playing_w, 0, 1, 0, H_stop_playing); Xen_define_dilambda(S_pausing, g_pausing_w, H_pausing, S_set S_pausing, g_set_pausing_w, 0, 0, 1, 0); Xen_define_dilambda(S_playing, g_playing_w, H_playing, S_set S_playing, g_set_playing_w, 0, 0, 1, 0); Xen_define_procedure(S_make_player, g_make_player_w, 0, 2, 0, H_make_player); Xen_define_procedure(S_add_player, g_add_player_w, 1, 5, 0, H_add_player); Xen_define_safe_procedure(S_player_home, g_player_home_w, 1, 0, 0, H_player_home); Xen_define_procedure(S_start_playing, g_start_playing_w, 0, 3, 0, H_start_playing); Xen_define_procedure(S_stop_player, g_stop_player_w, 1, 0, 0, H_stop_player); Xen_define_procedure(S_free_player, g_free_player_w, 1, 0, 0, H_free_player); Xen_define_safe_procedure(S_players, g_players_w, 0, 0, 0, H_players); Xen_define_safe_procedure(S_is_player, g_is_player_w, 1, 0, 0, H_is_player); Xen_define_dilambda(S_with_tracking_cursor, g_with_tracking_cursor_w, H_with_tracking_cursor, S_set S_with_tracking_cursor, g_set_with_tracking_cursor_w, 0, 0, 1, 0); Xen_define_dilambda(S_dac_size, g_dac_size_w, H_dac_size, S_set S_dac_size, g_set_dac_size_w, 0, 0, 1, 0); Xen_define_dilambda(S_dac_combines_channels, g_dac_combines_channels_w, H_dac_combines_channels, S_set S_dac_combines_channels, g_set_dac_combines_channels_w, 0, 0, 1, 0); Xen_define_dilambda(S_cursor_update_interval, g_cursor_update_interval_w, H_cursor_update_interval, S_set S_cursor_update_interval, g_set_cursor_update_interval_w, 0, 0, 1, 0); Xen_define_dilambda(S_cursor_location_offset, g_cursor_location_offset_w, H_cursor_location_offset, S_set S_cursor_location_offset, g_set_cursor_location_offset_w, 0, 0, 1, 0); #define H_stop_playing_hook S_stop_playing_hook " (snd): called when a sound finishes playing." #define H_play_hook S_play_hook " (size): called each time a buffer is sent to the DAC." #define H_start_playing_hook S_start_playing_hook " (snd): called when a play request is triggered. \ If it returns " PROC_TRUE ", the sound is not played." #define H_stop_playing_selection_hook S_stop_playing_selection_hook " (): called when the selection stops playing" #define H_start_playing_selection_hook S_start_playing_selection_hook " (): called when the selection starts playing" stop_playing_hook = Xen_define_hook(S_stop_playing_hook, "(make-hook 'snd)", 1, H_stop_playing_hook); start_playing_hook = Xen_define_hook(S_start_playing_hook, "(make-hook 'snd)", 1, H_start_playing_hook); play_hook = Xen_define_hook(S_play_hook, "(make-hook 'size)", 1, H_play_hook); stop_playing_selection_hook = Xen_define_hook(S_stop_playing_selection_hook, "(make-hook)", 0, H_stop_playing_selection_hook); start_playing_selection_hook = Xen_define_hook(S_start_playing_selection_hook, "(make-hook)", 0, H_start_playing_selection_hook); #if HAVE_SCHEME s7_symbol_set_access(s7, ss->cursor_location_offset_symbol, s7_make_function(s7, "[acc-" S_cursor_location_offset "]", acc_cursor_location_offset, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->cursor_update_interval_symbol, s7_make_function(s7, "[acc-" S_cursor_update_interval "]", acc_cursor_update_interval, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->dac_combines_channels_symbol, s7_make_function(s7, "[acc-" S_dac_combines_channels "]", acc_dac_combines_channels, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->dac_size_symbol, s7_make_function(s7, "[acc-" S_dac_size "]", acc_dac_size, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->with_tracking_cursor_symbol, s7_make_function(s7, "[acc-" S_with_tracking_cursor "]", acc_with_tracking_cursor, 2, 0, false, "accessor")); s7_symbol_set_documentation(s7, ss->cursor_location_offset_symbol, "*cursor-location-offset*: samples added to cursor location if cursor displayed during play."); s7_symbol_set_documentation(s7, ss->cursor_update_interval_symbol, "*cursor-update-interval*: time (seconds) between cursor updates if with-tracking-cursor."); s7_symbol_set_documentation(s7, ss->dac_combines_channels_symbol, "*dac-combines-channels*: #t if extra channels are to be mixed into available ones during playing."); s7_symbol_set_documentation(s7, ss->dac_size_symbol, "*dac-size*: the current DAC buffer size in framples (256)"); s7_symbol_set_documentation(s7, ss->with_tracking_cursor_symbol, "*with-tracking-cursor*: #t if cursor always moves along in waveform display as sound is played"); #endif } snd-16.1/maxf.rb0000644000076400007640000001635012306421672011623 0ustar bilbil# maxf.rb -- CLM -> Snd/Ruby translation of maxf.ins # Translator/Author: Michael Scholz # Created: Mon Mar 24 11:24:23 CET 2003 # Changed: Thu Oct 15 00:16:58 CEST 2009 # It follows the original header of Juan Reyes. # ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; # ;; # ;; maxf.ins # ;; This is Max Mathews (mvm) new filter (2002) # ;; High-Q, 2-Integrator, filter with # ;; Two Poles, and one Zero at the Origin # ;; # ;; It synthesizes equal-tempered frequencies # ;; integer & just scales out of a wide-band input # ;; signal. # ;; Based on Max's code (filter.cpp) # ;; # ;; This heuristic might be called Modal Synthesis. # ;; But as well it can also be additive synthesis in # ;; which a resonator is initialized to generate the # ;; exponentially decaying sinusoids at the desired # ;; phase. # ;; # ;; This implementation written by Juan Reyes with dsp # ;; assistance from JOS. # ;; This version Oct-30, 2002 # ;; # ;; Change gain(att) of input file if clipping # ;; # ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; require "ws" CLM = Struct.new("CLM", :yy1, :yy2, :zz1, :zz2, :pp1, :pp2, :pp3, :out) add_help(:maxfilter, "maxfilter(file, start, *args) :att = 1.0 :numf = 1 :freqfactor = 1.0 :amplitude = 1.0 :amp-env = [0, 1, 100, 1] :degree = kernel_rand(90.0) :distance = 1.0 :reverb_amount = 0.2 This is Max Mathews (mvm) new filter (2002) High-Q, 2-Integrator, filter with Two Poles, and one Zero at the Origin It synthesizes equal-tempered frequencies integer & just scales out of a wide-band input signal. Based on Max's code (filter.cpp) This heuristic might be called Modal Synthesis. But as well it can also be additive synthesis in which a resonator is initialized to generate the exponentially decaying sinusoids at the desired phase. :att = 1 in-file attenuation :numf = 1 1 filter :numf = 4 4 filters :numf = 9 9 filters :numf = 12 12 filters :numf = 13 13 filters") def maxfilter(file, start = 0, *args) att, numf, freqfactor, amplitude, amp_env, degree, distance, reverb_amount = nil optkey(args, binding, [:att, 1.0], [:numf, 1], [:freqfactor, 1.0], [:amplitude, 1.0], [:amp_env, [0, 1, 100, 1]], [:degree, kernel_rand(90.0)], [:distance, 1.0], [:reverb_amount, 0.2]) rda, snd = make_general_reader(file, :channel, 0) formfil = CLM.new(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) dur = duration(file) ampf = make_env(:envelope, amp_env, :scaler, amplitude, :duration, dur) state_0 = make_array( 1) do make_array(3, 0.0) end state_1 = make_array(12) do make_array(3, 0.0) end state_2 = make_array( 9) do make_array(3, 0.0) end state_3 = make_array(13) do make_array(3, 0.0) end state_4 = make_array( 4) do make_array(3, 0.0) end state_5 = make_array( 2) do make_array(3, 0.0) end case numf when 1 Snd.display "State 0 (default): One filter" state_0[0] = 7.54e-002, 2000.0 * freqfactor, 2.0 when 2 Snd.display "State 5: Two filters" state_5[0] = 7.54e-003, 200.0 * freqfactor, 4.0 state_5[1] = 7.54e-004, 800.0 * freqfactor, 1.0 when 4 Snd.display "State 4: Four filters" state_4[0] = 7.54e-002, 1000.0 * freqfactor, 0.5 state_4[1] = 3.225e-002, 400.0 * freqfactor, 3.0 state_4[2] = 1.14e-002, 800.0 * freqfactor, 2.8 state_4[3] = 7.54e-002, 1600.0 * freqfactor, 1.0 when 9 Snd.display "State 2: Streached overtone string 9 filters" state_2[0] = 1.07e-002, 100.0, 2.5 state_2[1] = 1.07e-002, 202.0, 0.75 state_2[2] = 1.07e-002, 305.0, 0.5 state_2[3] = 7.077e-003, 408.0, 0.4 state_2[4] = 1.07e-002, 501.0, 0.3 state_2[5] = 1.07e-002, 612.0, 0.25 state_2[6] = 1.07e-003, 715.0, 0.25 state_2[7] = 1.07e-002, 817.0, 0.2 state_2[8] = 1.07e-002, 920.0, 0.18 when 12 Snd.display "State 1: Risset bell long 12 filters" state_1[0] = 5.025e-002, 224.0, 3.7 state_1[1] = 5.025e-002, 225.0, 3.3 state_1[2] = 5.025e-002, 368.0, 2.8 state_1[3] = 5.025e-002, 369.0, 2.4 state_1[4] = 1.047e-002, 476.0, 1.9 state_1[5] = 5.025e-002, 680.0, 1.7 state_1[6] = 5.025e-002, 800.0, 1.5 state_1[7] = 4.05e-002, 1096.0, 1.1 state_1[8] = 4.05e-002, 1099.0, 0.9 state_1[9] = 4.05e-002, 1200.0, 0.6 state_1[10] = 3.78e-002, 1504.0, 0.4 state_1[11] = 4.05e-002, 1628.0, 0.3 when 13 Snd.display "State 3: Open major chord with repeated octave 12 filters" state_3[0] = 5.025e-002, 100.0, 2.0 state_3[1] = 5.025e-002, 251.0, 2.0 state_3[2] = 5.025e-002, 299.0, 2.0 state_3[3] = 5.025e-002, 401.0, 2.0 state_3[4] = 5.025e-002, 199.0, 2.0 state_3[5] = 5.025e-002, 501.0, 2.0 state_3[6] = 5.025e-002, 599.0, 2.0 state_3[7] = 5.025e-002, 801.0, 2.0 state_3[8] = 5.025e-002, 201.0, 2.0 state_3[9] = 5.025e-002, 749.0, 2.0 state_3[10] = 5.025e-002, 900.0, 2.0 state_3[11] = 5.025e-004, 1205.0, 2.0 state_3[12] = 5.025e-004, 1205.0, 2.0 else Snd.display "Please leave default or enter [1] [2] [4] [9] [12] [13]" numf = 1 end mvmfilt = lambda do |b, sample| b[:yy2] = (b[:pp1] * b[:yy1] + b[:pp2] * b[:zz1]) - b[:pp3] * sample b[:zz2] = b[:zz1] - b[:pp2] * b[:yy2] b[:zz1] = b[:zz2] b[:yy1] = b[:yy2] b[:out] = b[:yy1] end set_coeffs = lambda do |b, ary| famp, ffreq, fdecay = ary tper = 1.0 / @srate centerfreq = (2.0 * PI * ffreq) / @srate maxdecay = (2.0 * tper) / (centerfreq * centerfreq) mindecay = tper / centerfreq fdecay = if fdecay >= maxdecay maxdecay else fdecay.to_f end fdecay = mindecay if fdecay <= mindecay b[:pp1] = 1.0 - 2.0 / (fdecay * @srate) b[:pp2] = (2.0 * PI * ffreq) / @srate b[:pp3] = b[:pp2] * famp end run_instrument(start, dur, :degree, degree, :distance, distance, :reverb_amount, reverb_amount) do outval_a = att * general_readin(rda) add_fl = 0.0 numf.times do |j| case numf when 1 set_coeffs.call(formfil, state_0[j]) when 2 set_coeffs.call(formfil, state_5[j]) when 4 set_coeffs.call(formfil, state_4[j]) when 9 set_coeffs.call(formfil, state_2[j]) when 12 set_coeffs.call(formfil, state_1[j]) when 13 set_coeffs.call(formfil, state_3[j]) end filsig = mvmfilt.call(formfil, outval_a) add_fl += filsig end env(ampf) * add_fl end close_general_reader(snd, rda) end =begin ifile = "dog.snd" ofile = "rmax_dog.snd" stats = [1, 2, 4, 9, 12, 13] with_sound(:play, 1, :statistics, true, :channels, 4, :output, ofile, :reverb, :jc_reverb, :comment, format("maxfilter test, filters %s, source %s", stats.inspect, ifile)) do stats.each_with_index do |val, i| maxfilter(ifile, i, :numf, val) end end with_sound(:srate, 22050) do maxfilter("dog.snd", 0) end with_sound(:srate, 44100) do maxfilter("dog.snd", 0, :numf, 12) end with_sound(:srate, 44100) do maxfilter("dog.snd", 0, :numf, 13, :att, 0.75) end with_sound(:srate, 44100) do maxfilter("dog.snd", 0, :numf, 2, :att, 0.25, :freqfactor, 0.5) end =end # maxf.rb ends here snd-16.1/music5-examples0000644000076400007640000000425012306421672013303 0ustar bilbilThis is a set of music5 examples taken from Max Mathews' "The Technology of Computer Music". To use them, copy each separate example into a separate file, then pass that to pass1. The output is a raw (headerless) sound file. If you're using Snd, use this hook to make the translation automatic: (add-hook! open-raw-sound-hook (lambda (file choices) (list 1 20000 mus-lfloat))) -------------------------------------------------------------------------------- INS 0 1 ; OSC P5 P6 B2 F2 P30 ; OUT B2 B1 ; END ; GEN 0 1 2 0 0 .999 50 .999 205 -.999 306 -.999 461 0 511 ; NOT 0 1 .50 125 8.45 ; NOT .75 1 .17 250 8.45 ; NOT 1.00 2 .50 500 8.46 ; NOT 1.75 1 .17 1000 8.93 ; NOT 2.00 1 .95 2000 10.04 ; NOT 3.00 1 .95 1000 8.45 ; NOT 4.00 1 .50 500 8.93 ; NOT 4.75 1 .17 500 8.93 ; NOT 5.00 1 .50 700 8.93 ; NOT 5.75 1 .17 1000 13.39 ; NOT 6.00 1 1.95 2000 12.65 ; TER 8.00 ; -------------------------------------------------------------------------------- INS 0 1 ; OSC P5 P6 B2 F1 P30 ; OSC B2 P7 B2 F2 P29 ; OUT B2 B1 ; END ; GEN 0 1 1 0 0 .99 20 .99 491 0 511 ; GEN 0 1 2 0 0 .99 50 .99 205 -.99 306 -.99 461 0 511 ; NOT 0 1 2 1000 .0128 6.70 ; NOT 2 1 1 1000 .0256 8.44 ; TER 3 ; -------------------------------------------------------------------------------- INS 0 2 ; OSC P5 P6 B2 F1 P30 ; OSC P8 P9 B3 F3 P29 ; AD2 P7 B3 B3 ; OSC B2 B3 B2 F2 P28 ; OUT B2 B1 ; END ; GEN 0 1 1 0 0 .99 20 .99 491 0 511 ; GEN 0 1 2 0 0 .99 50 .99 205 -.99 306 -.99 461 0 511 ; GEN 0 2 3 1 1 ; NOT 0 2 2 1000 .0128 6.70 .067 .205 ; NOT 2 2 1 1000 .0256 8.44 .084 .205 ; TER 3 ; -------------------------------------------------------------------------------- INS 0 3 ; OSC P5 P7 B2 F3 P30 ; OSC P6 P7 B3 F4 P29 ; AD2 B2 B3 B2 ; OSC B2 P8 B2 F2 V1 ; OUT B2 B1 ; END ; GEN 0 1 3 .999 0 0 511 ; GEN 0 1 4 0 0 .999 511 ; GEN 0 1 2 0 0 .99 50 .99 205 -.99 306 -.99 461 0 511 ; COM NOT 0 3 2 0 2000 .0128 6.70 ; COM NOT 2 3 1 2000 0 .0256 6.70 ; COM round off errors? ; COM we need a slower read rate to get ends to match: ; NOT 0 3 2 0 2000 .01277 6.70 ; NOT 2 3 1 2000 0 .02555 6.70 ; TER 3 ; -------------------------------------------------------------------------------- snd-16.1/clm-ins.fs0000644000076400007640000041423612327441227012245 0ustar bilbil\ clm-ins.fs -- clm-ins.scm|rb -> clm-ins.fs \ Translator/Author: Michael Scholz \ Created: 06/02/03 10:36:51 \ Changed: 14/04/28 03:52:17 \ \ @(#)clm-ins.fs 1.49 4/28/14 \ jc-reverb ( keyword-args -- ) \ violin ( start dur freq amp keyword-args -- ) \ fm-violin ( start dur freq amp keyword-args -- ) \ \ clm-ins.scm|rb instruments \ \ pluck ( start dur freq amp :optional weighting lossfact -- ) \ vox ( start dur freq amp ampfun freqfun freqscl ... -- ) \ fofins ( start dur freq amp vib f0 a0 f1 a1 f2 a2 :optional ae ve -- ) \ fm-trumpet ( start dur keyword-args -- ) \ pqw-vox ( start dur freq spacing-freq amp ampfun freqfun ... -- ) \ stereo-flute ( start dur freq flow keyword-args -- ) \ fm-bell ( start dur freq amp :optional amp-env index-env index -- ) \ fm-insect ( start dur freq amp amp-env ... -- ) \ fm-drum ( start dur freq amp index :optional high degr dist rev-amt -- ) \ gong ( start dur freq amp -- ) \ attract ( start dur amp c -- ) \ pqw ( start dur sfreq cfreq amp ampfun indexfun parts -- ) \ tubebell ( start dur freq amp :optional base --) \ wurley ( start dur freq amp -- ) \ rhodey ( start dur freq amp :optional base -- ) \ hammondoid ( start dur freq amp -- ) \ metal ( start dur freq amp -- ) \ drone ( start dur freq amp ampfun synth ampat ampdc ... -- ) \ canter ( start dur pitch amp ampfun ranfun skewfun ... -- ) \ nrev ( keyword-args -- ) \ reson ( start dur pitch amp indxfun skewfun ... -- ) \ cellon ( start dur pitch0 amp ampfun betafun ... -- ) \ jl-reverb ( keyword-args -- ) \ gran-synth ( start dur freq grain-dur interval amp -- ) \ touch-tone ( numbers keyword-args -- ) \ spectra ( start dur freq amp :optional ... -- ) \ two-tab ( start dur freq amp :optional ... -- ) \ lbj-piano ( start dur freq amp -- ) \ resflt ( start dur driver ... -- ) \ scratch-ins ( start file src-ratio turntable -- ) \ pins ( file start dur keyword-args -- ) \ zc ( start dur freq amp len1 len2 feedback -- ) \ zn ( start dur freq amp len1 len2 feedforward -- ) \ za ( start dur freq amp len1 len2 fb ffw -- ) \ clm-expsrc ( start dur in-file exp-ratio src-ratio amp :optional ... -- ) \ exp-snd ( file start dur amp :optional ... -- ) \ expfil ( start dur hopsecs rampsecs steadysecs file1 file2 -- ) \ graph-eq ( file start dur keyword-args -- ) \ anoi ( fname start dur :optional fftsize amp-scaler R -- ) \ fullmix ( in-file :optional ... -- ) \ bes-fm ( start dur freq amp ratio index -- ) require clm require env \ Prevent name clash with possibly loaded sndins.so. \ sndins.so instruments can be called with fm-violin-ins etc. [ifdef] fm-violin <'> fm-violin alias fm-violin-ins <'> fm-violin-ins <'> fm-violin help-ref help-set! [then] [ifdef] jc-reverb <'> jc-reverb alias jc-reverb-ins <'> jc-reverb-ins <'> jc-reverb help-ref help-set! [then] [ifdef] nrev <'> nrev alias nrev-ins <'> nrev-ins <'> nrev help-ref help-set! [then] \ General input function for src, granulate etc. : readin-cb { gen -- prc; dir self -- val } 1 proc-create ( prc ) gen , does> { dir self -- val } self @ ( gen ) readin ; : reverb-dur ( rev -- dur ) mus-length samples->seconds *clm-decay-time* f+ ; \ clm/jcrev.ins instrument: jc-reverb-fs <{ :key volume 1.0 delay1 0.013 delay2 0.011 delay3 0.015 delay4 0.017 low-pass #f doubled #f amp-env #f -- }> doc" The Chowning reverb.\n\ 0 1 440 0.2 <'> fm-violin :reverb <'> jc-reverb with-sound\n\ 0 1 440 0.2 <'> fm-violin\n\ :reverb-data #( :low-pass #t ) :reverb <'> jc-reverb :channels 2 with-sound." *output* channels { chans } *reverb* channels { rev-chans } *reverb* reverb-dur { dur } *verbose* if get-func-name rev-chans chans reverb-info then :feedback -0.7 :feedforward 0.7 :size 1051 make-all-pass { allpass1 } :feedback -0.7 :feedforward 0.7 :size 337 make-all-pass { allpass2 } :feedback -0.7 :feedforward 0.7 :size 113 make-all-pass { allpass3 } :scaler 0.742 :size 4799 make-comb { comb1 } :scaler 0.733 :size 4999 make-comb { comb2 } :scaler 0.715 :size 5399 make-comb { comb3 } :scaler 0.697 :size 5801 make-comb { comb4 } chans 1 > { chan2 } chans 4 = { chan4 } :size delay1 seconds->samples make-delay { outdel1 } chan2 if :size delay2 seconds->samples make-delay else #f then { outdel2 } doubled chan4 || if :size delay3 seconds->samples make-delay else #f then { outdel3 } chan4 doubled chan2 && || if :size delay4 seconds->samples make-delay else #f then { outdel4 } amp-env if :envelope amp-env :scaler volume :duration dur make-env else #f then { env-a } doubled chan4 && if "jc-reverb is not set up for doubled reverb in quad" error then 0.0 0.0 { comb-sum comb-sum-1 } 0.0 dur run 0.0 rev-chans 0 ?do j i *reverb* in-any f+ loop { in-val } allpass3 allpass2 allpass1 in-val 0.0 all-pass 0.0 all-pass 0.0 all-pass { allpass-sum } comb-sum-1 { comb-sum-2 } comb-sum to comb-sum-1 comb1 allpass-sum 0.0 comb comb2 allpass-sum 0.0 comb f+ comb3 allpass-sum 0.0 comb f+ comb4 allpass-sum 0.0 comb f+ to comb-sum low-pass if comb-sum comb-sum-2 f+ 0.25 f* comb-sum-1 f2/ f+ else comb-sum then { all-sums } outdel1 all-sums 0.0 delay { del-a } doubled if outdel3 all-sums 0.0 delay del-a f+ to del-a then env-a ?dup-if env to volume then i del-a volume f* *output* outa drop chan2 if outdel2 all-sums 0.0 delay { del-b } doubled if outdel4 all-sums 0.0 delay del-b f+ to del-b then i del-b volume f* *output* outb drop then chan4 if i outdel3 all-sums 0.0 delay volume f* *output* outc drop i outdel4 all-sums 0.0 delay volume f* *output* outd drop then loop ;instrument <'> jc-reverb-fs alias jc-reverb <'> jc-reverb <'> jc-reverb-fs help-ref help-set! \ snd/fm.html instrument: violin <{ start dur freq amp :key fm-index 1.0 amp-env #( 0 0 25 1 75 1 100 0 ) index-env #( 0 1 25 0.4 75 0.6 100 0 ) degree 0.0 distance 1.0 reverb-amount 0.01 -- }> doc" Violin example from snd/fm.html.\n\ 0 3 440 0.5 :fm-index 0.5 <'> violin with-sound" freq hz->radians { frq-scl } frq-scl fm-index f* { maxdev } 5.0 freq flog f/ maxdev f* { index1 } 8.5 freq flog f- 3.0 freq 1000.0 f/ f+ f/ maxdev 3.0 f* f* { index2 } 4.0 freq fsqrt f/ maxdev f* { index3 } :frequency freq make-oscil { carrier } :frequency freq make-oscil { fmosc1 } :frequency freq 3.0 f* make-oscil { fmosc2 } :frequency freq 4.0 f* make-oscil { fmosc3 } :envelope amp-env :scaler amp :duration dur make-env { ampf } :envelope index-env :scaler index1 :duration dur make-env { indf1 } :envelope index-env :scaler index2 :duration dur make-env { indf2 } :envelope index-env :scaler index3 :duration dur make-env { indf3 } :frequency 5.0 :amplitude 0.0025 frq-scl f* make-triangle-wave { pervib } :frequency 16.0 :amplitude 0.005 frq-scl f* make-rand-interp { ranvib } start dur #{ :degree degree :distance distance :reverb reverb-amount } run-instrument pervib 0.0 triangle-wave ranvib 0.0 rand-interp f+ { vib } carrier vib fmosc1 vib 0.0 oscil indf1 env f* f+ fmosc2 3.0 vib f* 0.0 oscil indf2 env f* f+ fmosc3 4.0 vib f* 0.0 oscil indf3 env f* f+ 0.0 oscil ampf env f* end-run ;instrument : violin-test <{ :optional start 0.0 dur 1.0 -- }> start now! now@ dur 440 0.5 violin dur 0.2 f+ step ; \ === FM-Violin (clm/v.ins, snd/v.scm|rb) === instrument: fm-violin-fs <{ start dur freq amp :key fm-index 1.0 amp-env #( 0 0 25 1 75 1 100 0 ) periodic-vibrato-rate 5.0 periodic-vibrato-amplitude 0.0025 random-vibrato-rate 16.0 random-vibrato-amplitude 0.005 noise-freq 1000.0 noise-amount 0.0 ind-noise-freq 10.0 ind-noise-amount 0.0 amp-noise-freq 20.0 amp-noise-amount 0.0 gliss-env #( 0 0 100 0 ) glissando-amount 0.0 fm1-env #( 0 1 25 0.4 75 0.6 100 0 ) fm2-env #( 0 1 25 0.4 75 0.6 100 0 ) fm3-env #( 0 1 25 0.4 75 0.6 100 0 ) fm1-rat 1.0 fm2-rat 3.0 fm3-rat 4.0 fm1-index #f fm2-index #f fm3-index #f base 1.0 degree 0.0 distance 1.0 reverb-amount 0.01 index-type 'violin -- }> doc" FM-Violin from clm/v.ins|snd/v.scm|rb.\n\ 0 3 440 0.5 :fm-index 0.5 <'> fm-violin with-sound." freq fabs 1.0 f<= if "freq = %s? reset to 440.0" #( freq ) fth-warning 440.0 to freq then freq hz->radians { frq-scl } fm-index f0<> { modulate } frq-scl fm-index f* { maxdev } index-type 'violin = { vln } freq flog { logfreq } freq fsqrt { sqrtfreq } fm1-index unless maxdev vln if 5.0 else 7.5 then logfreq f/ f* pi fmin to fm1-index then fm2-index unless maxdev 3.0 f* vln if 8.5 logfreq f- 3.0 freq 0.001 f* f+ f/ else 15.0 sqrtfreq f/ then f* pi fmin to fm2-index then fm3-index unless maxdev vln if 4.0 else 8.0 then sqrtfreq f/ f* pi fmin to fm3-index then noise-amount f0= fm1-env fm2-env equal? && fm1-env fm3-env equal? && fm1-rat fm1-rat floor f- f0= && fm2-rat fm1-rat floor f- f0= && fm2-rat fm2-rat floor f- f0= && fm3-rat fm1-rat floor f- f0= && fm3-rat fm3-rat floor f- f0= && { easy-case } easy-case modulate && 1.0 && fm1-index || { norm } :frequency freq make-oscil { carrier } :envelope amp-env :scaler amp :duration dur :base base make-env { ampf } #f #f #f { fmosc1 fmosc2 fmosc3 } #f #f #f { indf1 indf2 indf3 } modulate if easy-case if :frequency freq fm1-rat f* :coeffs #( fm1-rat f>s fm1-index fm2-rat fm1-rat f/ fround->s fm2-index fm3-rat fm1-rat f/ fround->s fm3-index ) 1 partials->polynomial make-polyshape else :frequency freq fm1-rat f* make-oscil then to fmosc1 easy-case unless :frequency freq fm2-rat f* make-oscil to fmosc2 :frequency freq fm3-rat f* make-oscil to fmosc3 :envelope fm1-env :scaler norm :duration dur make-env to indf1 :envelope fm2-env :scaler fm2-index :duration dur make-env to indf2 :envelope fm3-env :scaler fm3-index :duration dur make-env to indf3 then then :envelope gliss-env :scaler glissando-amount frq-scl f* :duration dur make-env { frqf } :frequency periodic-vibrato-rate :amplitude periodic-vibrato-amplitude frq-scl f* make-triangle-wave { pervib } :frequency random-vibrato-rate :amplitude random-vibrato-amplitude frq-scl f* make-rand-interp { ranvib } #f #f #f { fm-noi ind-noi amp-noi } noise-amount f0<> if :frequency noise-freq :amplitude noise-amount pi f* make-rand to fm-noi then ind-noise-freq f0<> ind-noise-amount f0<> && if :frequency ind-noise-freq :amplitude ind-noise-amount make-rand-interp to ind-noi then amp-noise-freq f0<> amp-noise-amount f0<> && if :frequency amp-noise-freq :amplitude amp-noise-amount make-rand-interp to amp-noi then 0.0 0.0 1.0 1.0 { vib fuzz ind-fuzz amp-fuzz } modulate if easy-case if start dur #{ :degree degree :distance distance :reverb reverb-amount } run-instrument fm-noi if fm-noi 0.0 rand to fuzz then frqf env pervib 0.0 triangle-wave f+ ranvib 0.0 rand-interp f+ to vib ind-noi if ind-noi 0.0 rand-interp 1.0 f+ to ind-fuzz then amp-noi if amp-noi 0.0 rand-interp 1.0 f+ to amp-fuzz then carrier ( gen ) fmosc1 1.0 vib polyshape ind-fuzz f* vib f+ ( fm ) 0.0 ( pm ) oscil ampf env f* amp-fuzz f* end-run else start dur #{ :degree degree :distance distance :reverb reverb-amount } run-instrument fm-noi if fm-noi 0.0 rand to fuzz then frqf env pervib 0.0 triangle-wave f+ ranvib 0.0 rand-interp f+ to vib ind-noi if ind-noi 0.0 rand-interp 1.0 f+ to ind-fuzz then amp-noi if amp-noi 0.0 rand-interp 1.0 f+ to amp-fuzz then carrier ( gen ) fmosc1 fm1-rat vib f* fuzz f+ 0.0 oscil indf1 env f* fmosc2 fm2-rat vib f* fuzz f+ 0.0 oscil indf2 env f* f+ fmosc3 fm3-rat vib f* fuzz f+ 0.0 oscil indf3 env f* f+ ind-fuzz f* vib f+ ( fm ) 0.0 ( pm ) oscil ampf env f* amp-fuzz f* end-run then else start dur #{ :degree degree :distance distance :reverb reverb-amount } run-instrument fm-noi if fm-noi 0.0 rand to fuzz then frqf env pervib 0.0 triangle-wave f+ ranvib 0.0 rand-interp f+ to vib ind-noi if ind-noi 0.0 rand-interp 1.0 f+ to ind-fuzz then amp-noi if amp-noi 0.0 rand-interp 1.0 f+ to amp-fuzz then carrier vib 0.0 oscil ampf env f* amp-fuzz f* end-run then ; <'> fm-violin-fs alias fm-violin <'> fm-violin <'> fm-violin-fs help-ref help-set! : fm-violin-test <{ :optional start 0.0 dur 1.0 -- }> start now! now@ dur 440 0.5 fm-violin dur 0.2 f+ step ; \ === CLM-INS.(RB|SCM) === \ (with original comments from clm-ins.scm) hide : get-optimum-c { s o p -- t c } o 1/f s o fsin f* 1.0 s f- s o fcos f* f+ fatan2 f* { pa } p pa f- f>s { tmp_int } tmp_int unless 1 to tmp_int then p pa f- tmp_int f- { pc } begin pc 0.1 f< while tmp_int 1 - to tmp_int pc 1.0 f+ to pc repeat tmp_int ( t ) o fsin o pc f* fsin f- o o pc f* f+ fsin f/ ( c ) ; : tune-it { f s1 -- s c t } mus-srate f f/ { p } s1 f0= if 0.5 else s1 then { s } f hz->radians { o } s o p get-optimum-c { t1 c1 } 1.0 s f- o p get-optimum-c { t2 c2 } s 0.5 f<> c1 fabs c2 fabs f< && if 1.0 s f- c1 t1 else s c2 t2 then ; set-current \ PLUCK \ \ The Karplus-Strong algorithm as extended by David Jaffe and Julius \ Smith -- see Jaffe and Smith, "Extensions of the Karplus-Strong \ Plucked-String Algorithm" CMJ vol 7 no 2 Summer 1983, reprinted in \ "The Music Machine". translated from CLM's pluck.ins instrument: pluck <{ start dur freq amp :optional weighting 0.5 lossfact 0.9 -- }> doc" Implement the Jaffe-Smith plucked string physical model. \ WEIGHTING is the ratio of the once-delayed to the twice-delayed samples. \ It defaults to 0.5 = shortest decay. \ Anything other than 0.5 = longer decay. \ Must be between 0 and less than 1.0. \ LOSSFACT can be used to shorten decays. \ Most useful values are between 0.8 and 1.0.\n\ 0 1 330 0.3 0.95 0.95 <'> pluck with-sound" freq weighting tune-it { wt0 c dlen } lossfact f0= if 1.0 else 1.0 lossfact fmin then { lf } wt0 f0= if 0.5 else 1.0 wt0 fmin then { wt } lf 1.0 wt f- f* lf wt f* make-one-zero { allp } c 1.0 make-one-zero { feedb } dlen 0.0 make-vct map 1.0 2.0 mus-random f- end-map { tab } start dur #{ :degree 90.0 random } run-instrument tab cycle-ref { val } tab i dlen mod 1.0 c f- feedb allp val one-zero one-zero f* vct-set! drop amp val f* end-run ;instrument previous : pluck-test <{ :optional start 0.0 dur 1.0 -- }> start now! now@ dur 330 0.3 0.95 0.95 pluck dur 0.2 f+ step ; \ formant center frequencies for a male speaker (vox and pqw-vox) #{ :I: #( 390.0 1990.0 2550.0 ) :UH: #( 520.0 1190.0 2390.0 ) :U: #( 440.0 1020.0 2240.0 ) :W: #( 300.0 610.0 2200.0 ) :Y: #( 300.0 2200.0 3065.0 ) :L: #( 300.0 1300.0 3000.0 ) :D: #( 300.0 1700.0 2600.0 ) :N: #( 280.0 1700.0 2600.0 ) :T: #( 200.0 1700.0 2600.0 ) :TH: #( 200.0 1400.0 2200.0 ) :V: #( 175.0 1100.0 2400.0 ) :ZH: #( 175.0 1800.0 2000.0 ) :E: #( 530.0 1840.0 2480.0 ) :A: #( 730.0 1090.0 2440.0 ) :OO: #( 300.0 870.0 2240.0 ) :LL: #( 380.0 880.0 2575.0 ) :EE: #( 260.0 3500.0 3800.0 ) :I2: #( 350.0 2300.0 3340.0 ) :G: #( 250.0 1350.0 2000.0 ) :NG: #( 280.0 2300.0 2750.0 ) :K: #( 350.0 1350.0 2000.0 ) :S: #( 200.0 1300.0 2500.0 ) :THE: #( 200.0 1600.0 2200.0 ) :ZZ: #( 900.0 2400.0 3800.0 ) :AE: #( 660.0 1720.0 2410.0 ) :OW: #( 570.0 840.0 2410.0 ) :ER: #( 490.0 1350.0 1690.0 ) :R: #( 420.0 1300.0 1600.0 ) :LH: #( 280.0 1450.0 1600.0 ) :B: #( 200.0 800.0 1750.0 ) :M: #( 280.0 900.0 2200.0 ) :P: #( 300.0 800.0 1750.0 ) :F: #( 175.0 900.0 4400.0 ) :SH: #( 200.0 1800.0 2000.0 ) :Z: #( 200.0 1300.0 2500.0 ) :VV: #( 565.0 1045.0 2400.0 ) } value clm-ins-formants \ MLBVOI \ \ translation from MUS10 of Marc LeBrun's waveshaping voice instrument \ (using FM here) this version translated (and simplified slightly) \ from CLM's mlbvoi.ins instrument: vox <{ start dur freq amp ampfun freqfun freqscl voxfun index :optional vibscl 0.1 -- }> voxfun length { size } size make-array { f1 } size make-array { f2 } size make-array { f3 } size 1- 0 ?do clm-ins-formants voxfun i 1+ object-ref hash-ref { phon } voxfun i object-ref { n } f1 i n array-set! phon 0 array-ref f1 i 1+ rot array-set! f2 i n array-set! phon 1 array-ref f2 i 1+ rot array-set! f3 i n array-set! phon 2 array-ref f3 i 1+ rot array-set! 2 +loop :frequency 0.0 make-oscil { car-os } 6 make-array map :frequency 0.0 make-oscil end-map { ofs } :envelope ampfun :scaler amp :duration dur make-env { ampf } :envelope f1 :duration dur make-env { frmf1 } :envelope f2 :duration dur make-env { frmf2 } :envelope f3 :duration dur make-env { frmf3 } :envelope freqfun :duration dur :scaler freqscl freq f* :offset freq make-env { freqf } :frequency 6.0 :amplitude freq vibscl f* make-triangle-wave { per-vib } :frequency 20.0 :amplitude freq 0.01 f* make-rand-interp { ran-vib } 6 0.0 make-vct { freqs } 6 0.0 make-vct { amps } start dur #{ :degree 90.0 random } run-instrument freqf env per-vib 0.0 triangle-wave f+ ran-vib 0.0 rand-interp f+ { frq } frmf1 env { frm } frm frq f/ { frm0 } frm0 floor dup f>s { frm-fint frm-int } frm-int 2 mod unless freqs 0 frm-fint frq f* hz->radians vct-set! drop freqs 1 frm-fint 1.0 f+ frq f* hz->radians vct-set! drop amps 1 frm0 frm-fint f- vct-set! drop amps 0 1.0 amps 1 vct-ref f- vct-set! drop else freqs 1 frm-fint frq f* hz->radians vct-set! drop freqs 0 frm-fint 1.0 f+ frq f* hz->radians vct-set! drop amps 0 frm0 frm-fint f- vct-set! drop amps 1 1.0 amps 0 vct-ref f- vct-set! drop then frmf2 env to frm frm frq f/ to frm0 frm0 floor to frm-fint frm-fint f>s to frm-int frm-int 2 mod unless freqs 2 frm-fint frq f* hz->radians vct-set! drop freqs 3 frm-fint 1.0 f+ frq f* hz->radians vct-set! drop amps 3 frm0 frm-fint f- vct-set! drop amps 2 1.0 amps 3 vct-ref f- vct-set! drop else freqs 3 frm-fint frq f* hz->radians vct-set! drop freqs 2 frm-fint 1.0 f+ frq f* hz->radians vct-set! drop amps 2 frm0 frm-fint f- vct-set! drop amps 3 1.0 amps 2 vct-ref f- vct-set! drop then frmf3 env to frm frm frq f/ to frm0 frm0 floor to frm-fint frm-fint f>s to frm-int frm-int 2 mod unless freqs 4 frm-fint frq f* hz->radians vct-set! drop freqs 5 frm-fint 1.0 f+ frq f* hz->radians vct-set! drop amps 5 frm0 frm-fint f- vct-set! drop amps 4 1.0 amps 5 vct-ref f- vct-set! drop else freqs 5 frm-fint frq f* hz->radians vct-set! drop freqs 4 frm-fint 1.0 f+ frq f* hz->radians vct-set! drop amps 4 frm0 frm-fint f- vct-set! drop amps 5 1.0 amps 4 vct-ref f- vct-set! drop then car-os frq hz->radians 0.0 oscil index f* { caros } ofs 0 array-ref caros 0.2 f* freqs 0 vct-ref f+ 0.0 oscil amps 0 vct-ref f* ofs 1 array-ref caros 0.2 f* freqs 1 vct-ref f+ 0.0 oscil amps 1 vct-ref f* f+ 0.80 f* ofs 2 array-ref caros 0.5 f* freqs 2 vct-ref f+ 0.0 oscil amps 2 vct-ref f* ofs 3 array-ref caros 0.5 f* freqs 3 vct-ref f+ 0.0 oscil amps 3 vct-ref f* f+ 0.15 f* f+ ofs 4 array-ref caros freqs 4 vct-ref f+ 0.0 oscil amps 4 vct-ref f* ofs 5 array-ref caros freqs 5 vct-ref f+ 0.0 oscil amps 5 vct-ref f* f+ 0.05 f* f+ ampf env f* end-run ;instrument : vox-test <{ :optional start 0.0 dur 1.0 -- }> start now! #( 0 0 25 1 75 1 100 0 ) { amp-env } #( 0 0 5 0.5 10 0 100 1 ) { frq-env } #( 0 :E: 25 :AE: 35 :ER: 65 :ER: 75 :I: 100 :UH: ) { examp1 } #( 0 :I: 5 :OW: 10 :I: 50 :AE: 100 :OO: ) { examp2 } now@ dur 170 0.4 amp-env frq-env 0.1 examp1 0.05 0.1 vox dur 0.2 f+ step now@ dur 300 0.4 amp-env frq-env 0.1 examp2 0.02 0.1 vox dur 0.2 f+ step now@ 5.0 600 0.4 amp-env frq-env 0.1 examp2 0.01 0.1 vox 5.0 0.2 f+ step ; \ FOF example \ \ snd/sndclm.html, section wave-train instrument: fofins <{ start dur freq amp vib f0 a0 f1 a1 f2 a2 :optional ae #( 0 0 25 1 75 1 100 0 ) ve #( 0 1 100 1 ) -- }> doc" Produce FOF synthesis.\n\ 0 1 270 0.2 0.001 730 0.6 1090 0.3 2440 0.1 <'> fofins with-sound." :envelope ae :scaler amp :duration dur make-env { ampf } :frequency 6.0 make-oscil { vibr } :envelope ve :scaler vib :duration dur make-env { vibenv } f0 hz->radians { frq0 } f1 hz->radians { frq1 } f2 hz->radians { frq2 } mus-srate 22050.0 f= if 100 else 200 then { foflen } two-pi foflen f/ { win-freq } foflen 0.0 make-vct map a0 i frq0 f* fsin f* a1 i frq1 f* fsin f* f+ a2 i frq2 f* fsin f* f+ f2/ 1.0 i win-freq f* fcos f- f* end-map { foftab } :frequency freq :wave foftab make-wave-train { wt0 } start dur #{ :degree 90.0 random } run-instrument ampf env wt0 vibenv env vibr 0.0 0.0 oscil f* wave-train f* end-run ;instrument : fofins-test <{ :optional start 0.0 dur 1.0 -- }> start now! now@ dur 270 0.2 0.001 730 0.6 1090 0.3 2440 0.1 fofins dur 0.2 f+ step ; \ FM TRUMPET \ \ Dexter Morrill's FM-trumpet: from CMJ feb 77 p51 instrument: fm-trumpet <{ start dur :key frq1 250 frq2 1500 amp1 0.5 amp2 0.1 ampatt1 0.03 ampdec1 0.35 ampatt2 0.03 ampdec2 0.3 modfrq1 250 modind11 0 modind12 2.66 modfrq2 250 modind21 0 modind22 1.8 rvibamp 0.007 rvibfrq 125 vibamp 0.007 vibfrq 7 vibatt 0.6 vibdec 0.2 frqskw 0.03 frqatt 0.06 ampenv1 #( 0 0 25 1 75 0.9 100 0 ) ampenv2 #( 0 0 25 1 75 0.9 100 0 ) indenv1 #( 0 0 25 1 75 0.9 100 0 ) indenv2 #( 0 0 25 1 75 0.9 100 0 ) -- }> doc" 0 2 <'> fm-trumpet with-sound." :envelope #( 0 1 25 0.1 75 0 100 0 ) 25.0 vibatt dur f/ 100.0 f* 45.0 fmin 75.0 1.0 vibdec dur f/ f- 100.0 f* 55.0 fmax stretch-envelope :scaler vibamp :duration dur make-env { per-vib-f } :frequency rvibfrq :amplitude rvibamp make-rand-interp { ran-vib } :frequency vibfrq make-oscil { per-vib } 1.0 0.01 dur f/ f- 100.0 f* 75.0 fmax { dec-01 } :envelope #( 0 0 25 1 75 1 100 0 ) 25.0 frqatt dur f/ 100.0 f* 25.0 fmin 75.0 dec-01 stretch-envelope :scaler frqskw :duration dur make-env { frq-f } ampatt1 dur f/ 100.0 f* 25.0 fmin { ampattpt1 } 1.0 ampdec1 dur f/ f- 100.0 f* 75.0 fmax { ampdecpt1 } ampatt2 dur f/ 100.0 f* 25.0 fmin { ampattpt2 } 1.0 ampdec2 dur f/ f- 100.0 f* 75.0 fmax { ampdecpt2 } :envelope indenv1 25.0 ampattpt1 75.0 dec-01 stretch-envelope :scaler modfrq1 modind12 modind11 f- f* :duration dur make-env { mod1-f } :frequency 0.0 make-oscil { mod1 } :frequency 0.0 make-oscil { car1 } :envelope ampenv1 25 ampattpt1 75 ampdecpt1 stretch-envelope :scaler amp1 :duration dur make-env { car1-f } :envelope indenv2 25 ampattpt2 75 dec-01 stretch-envelope :scaler modfrq2 modind22 modind21 f- f* :duration dur make-env { mod2-f } :frequency 0.0 make-oscil { mod2 } :frequency 0.0 make-oscil { car2 } :envelope ampenv2 25.0 ampattpt2 75.0 ampdecpt2 stretch-envelope :scaler amp2 :duration dur make-env { car2-f } start dur #{ :degree 90.0 random } run-instrument ran-vib 0.0 rand-interp 1.0 f+ 1.0 per-vib-f env per-vib 0.0 0.0 oscil f* f+ f* 1.0 frq-f env f+ f* hz->radians { frq-change } car1 mod1 modfrq1 frq-change f* 0.0 oscil mod1-f env f* frq1 f+ frq-change f* 0.0 oscil car1-f env f* car2 mod2 modfrq2 frq-change f* 0.0 oscil mod2-f env f* frq2 f+ frq-change f* 0.0 oscil car2-f env f* f+ end-run ;instrument : fm-trumpet-test <{ :optional start 0.0 dur 1.0 -- }> start now! now@ dur fm-trumpet dur 0.2 f+ step ; #( "pqw-sin-evens" "pqw-sin-odds" "pqw-cos-evens" "pqw-cos-odds" "pqw-cos-coeffs" "pqw-sin-coeffs" "pqw-frmfs" "pqw-amps" ) create-struct make-pqw-vox-struct \ PQWVOX \ \ translation of CLM pqwvox.ins (itself translated from MUS10 of MLB's \ waveshaping voice instrument (using phase quadrature waveshaping)) instrument: pqw-vox <{ start dur freq spacing-freq amp ampfun freqfun freqscl phonemes formant-amps formant-shapes -- }> :frequency 0.0 make-oscil { car-sin } :frequency 0.0 :initial-phase half-pi make-oscil { car-cos } :envelope ampfun :scaler amp :duration dur make-env { ampf } :envelope freqfun :scaler freqscl freq f* :duration dur :offset freq make-env { freqf } :frequency 6.0 :amplitude freq 0.1 f* make-triangle-wave { per-vib } :frequency 20.0 :amplitude freq 0.05 f* make-rand-interp { ran-vib } phonemes length { plen } plen make-array { phone1 } plen make-array { phone2 } plen make-array { phone3 } plen 1- 0 ?do phonemes i object-ref { ph } phone1 i ph array-set! phone2 i ph array-set! phone3 i ph array-set! clm-ins-formants phonemes i 1+ object-ref hash-ref { ary } phone1 i 1+ ary 0 object-ref array-set! phone2 i 1+ ary 1 object-ref array-set! phone3 i 1+ ary 2 object-ref array-set! 2 +loop #( phone1 phone2 phone3 ) { phones } nil 0 { pv shape } formant-amps map make-pqw-vox-struct to pv pv :frequency 0.0 :initial-phase 0.0 make-oscil pqw-sin-evens! pv :frequency 0.0 :initial-phase 0.0 make-oscil pqw-sin-odds! pv :frequency 0.0 :initial-phase half-pi make-oscil pqw-cos-evens! pv :frequency 0.0 :initial-phase half-pi make-oscil pqw-cos-odds! formant-shapes i object-ref normalize-partials to shape pv shape mus-chebyshev-first-kind partials->polynomial pqw-cos-coeffs! pv shape mus-chebyshev-second-kind partials->polynomial pqw-sin-coeffs! :envelope phones i array-ref :duration dur make-env pv swap pqw-frmfs! pv formant-amps i object-ref pqw-amps! pv end-map { values } 4 0.0 make-vct { vals } spacing-freq freq f/ { frq-ratio } start dur #{ :degree 90.0 random } run-instrument freqf env per-vib 0.0 triangle-wave f+ ran-vib 0.0 rand-interp f+ { frq } frq frq-ratio f* hz->radians { frqscl } car-sin frqscl 0.0 oscil { carsin } car-cos frqscl 0.0 oscil { carcos } 0.0 ( sum ) values each to pv pv pqw-frmfs@ env frq f/ { frm0 } frm0 floor { frm-fint } frm-fint f>s 2 mod unless vals 0 frm-fint frq f* hz->radians vct-set! drop ( even-freq ) vals 1 frm-fint 1.0 f+ frq f* hz->radians vct-set! drop ( odd-freq ) vals 3 frm0 frm-fint f- vct-set! drop ( odd-amp ) vals 2 1.0 vals 3 vct-ref f- vct-set! drop ( even-amp ) else vals 1 frm-fint frq f* hz->radians vct-set! drop ( odd-freq ) vals 0 frm-fint 1.0 f+ frq f* hz->radians vct-set! drop ( even-freq ) vals 2 frm0 frm-fint f- vct-set! drop ( even-amp ) vals 3 1.0 vals 2 vct-ref f- vct-set! drop ( odd-amp ) then pv pqw-cos-coeffs@ carcos polynomial { fax } pv pqw-sin-coeffs@ carcos polynomial carsin f* { yfax } pv pqw-sin-evens@ vals 0 vct-ref 0.0 oscil yfax f* pv pqw-cos-evens@ vals 0 vct-ref 0.0 oscil fax f* f- vals 2 vct-ref f* pv pqw-sin-odds@ vals 1 vct-ref 0.0 oscil yfax f* pv pqw-cos-odds@ vals 1 vct-ref 0.0 oscil fax f* f- vals 3 vct-ref f* f+ pv pqw-amps@ f* f+ end-each ( sum ) ampf env f* end-run ;instrument : pqw-vox-test <{ :optional start 0.0 dur 1.0 -- }> start now! #( 0 0 50 1 100 0 ) { ampfun } #( 0 0 100 0 ) { freqfun } #( 0 0 100 1 ) { freqramp } #( #( 1 1 2 0.5 ) #( 1 0.5 2 0.5 3 1 ) #( 1 1 4 0.5 ) ) { sh1 } #( #( 1 1 2 0.5 ) #( 1 1 2 0.5 3 0.2 4 0.1 ) #( 1 1 3 0.1 4 0.5 ) ) { sh2 } #( #( 1 1 2 0.5 ) #( 1 1 4 0.1 ) #( 1 1 2 0.1 4 0.05 ) ) { sh3 } #( #( 1 1 2 0.5 3 0.1 4 0.01 ) #( 1 1 4 0.1 ) #( 1 1 2 0.1 4 0.05 ) ) { sh4 } #( 0.8 0.15 0.05 ) { amps } now@ dur 300 300 0.5 ampfun freqfun 0.00 #( 0 :L: 100 :L: ) #( 0.33 0.33 0.33 ) sh1 pqw-vox dur 0.2 f+ step now@ dur 200 200 0.5 ampfun freqramp 0.10 #( 0 :UH: 100 :ER: ) amps sh2 pqw-vox dur 0.2 f+ step now@ dur 100 314 0.5 ampfun freqramp 0.10 #( 0 :UH: 100 :ER: ) amps sh2 pqw-vox dur 0.2 f+ step now@ dur 200 314 0.5 ampfun freqramp 0.01 #( 0 :UH: 100 :ER: ) amps sh3 pqw-vox dur 0.2 f+ step now@ dur 100 414 0.5 ampfun freqramp 0.01 #( 0 :OW: 50 :E: 100 :ER: ) amps sh4 pqw-vox dur 0.2 f+ step ; \ STEREO-FLUTE instrument: stereo-flute <{ start dur freq flow :key flow-envelope #( 0 1 100 1 ) decay 0.01 noise 0.0356 embouchure-size 0.5 fbk-scl1 0.5 fbk-scl2 0.55 out-scl 1.0 a0 0.7 b1 -0.3 vib-rate 5.0 vib-amount 0.03 ran-rate 5.0 ran-amount 0.03 -- }> doc" A physical model of a flute.\n\ 0 1 440 0.55 :flow-envelope #( 0 0 1 1 2 1 3 0 ) <'> stereo-flute with-sound." :envelope flow-envelope :scaler flow :duration dur decay f- make-env { flowf } :frequency vib-rate make-oscil { p-vib } :frequency ran-rate make-rand-interp { ran-vib } :frequency mus-srate f2/ :amplitude 1.0 make-rand { breath } mus-srate freq f/ fround->s { periodic-samples } embouchure-size periodic-samples f* fround->s make-delay { emb } periodic-samples make-delay { bore } a0 b1 make-one-pole { rlf } 0.0 0.0 0.0 0.0 { emb-sig delay-sig out-sig prev-out-sig } 0.0 0.0 0.0 { cur-exit cur-diff cur-flow } 0.0 0.0 { dc-blocked prev-dc-blocked } start dur #{ :degree 90.0 random } run-instrument bore out-sig 0.0 delay to delay-sig emb cur-diff 0.0 delay to emb-sig p-vib 0.0 0.0 oscil vib-amount f* ran-vib 0.0 rand-interp ran-amount f* f+ flowf env f+ to cur-flow breath 0.0 rand cur-flow f* noise f* cur-flow f+ fbk-scl1 delay-sig f* f+ to cur-diff emb-sig emb-sig emb-sig f* emb-sig f* f- to cur-exit rlf fbk-scl2 delay-sig f* cur-exit f+ one-pole to out-sig \ ;; NB the DC blocker is not in the cicuit. \ ;; It is applied to the out-sig but the result is \ ;; not fed back into the system. out-sig prev-out-sig f- 0.995 prev-dc-blocked f* f+ to dc-blocked out-sig to prev-out-sig dc-blocked to prev-dc-blocked out-scl dc-blocked f* end-run ;instrument : flute-test <{ :optional start 0.0 dur 1.0 -- }> start now! now@ dur 440 0.55 :flow-envelope #( 0 0 1 1 2 1 3 0 ) stereo-flute dur 0.2 f+ step ; \ FM-BELL instrument: fm-bell <{ start dur freq amp :optional amp-env #( 0 0 0.1 1 10 0.6 25 0.3 50 0.15 90 0.1 100 0 ) index-env #( 0 1 2 1.1 25 0.75 75 0.5 100 0.2 ) index 1.0 -- }> freq 32.0 f* hz->radians { fm-ind1 } 8.0 freq 50.0 f/ f- 4.0 f* hz->radians { fm-ind2 } 1.4 freq 250.0 f/ f- 0.705 f* fm-ind2 f* { fm-ind3 } 20.0 freq 20.0 f/ f- 32.0 f* hz->radians { fm-ind4 } :frequency freq f2* make-oscil { mod1 } :frequency freq 1.41 f* make-oscil { mod2 } :frequency freq 2.82 f* make-oscil { mod3 } :frequency freq 2.4 f* make-oscil { mod4 } :frequency freq make-oscil { car1 } :frequency freq make-oscil { car2 } :frequency freq 2.4 f* make-oscil { car3 } :envelope amp-env :scaler amp :duration dur make-env { ampf } :envelope index-env :scaler index :duration dur make-env { indf } 0.0 { fmenv } start dur #{ :degree 90.0 random } run-instrument indf env to fmenv car1 fmenv fm-ind1 f* mod1 0.0 0.0 oscil f* ( fm ) 0.0 ( pm ) oscil car2 mod2 0.0 0.0 oscil fm-ind2 f* mod3 0.0 0.0 oscil fm-ind3 f* f+ fmenv f* ( fm ) 0.0 ( pm ) oscil 0.15 f* f+ ( car1 + car2 ) car3 mod4 0.0 0.0 oscil fmenv fm-ind4 f* f* ( fm ) 0.0 ( pm ) oscil 0.15 f* f+ ( car12 + car3 ) ampf env f* ( car123 * ampf ) end-run ;instrument : fm-bell-test <{ :optional start 0.0 dur 1.0 -- }> start now! now@ dur 440.0 0.5 fm-bell dur 0.2 f+ step ; \ FM-INSECT \ clm/insect.ins instrument: fm-insect <{ start dur freq amp amp-env mod-freq mod-skew mod-freq-env mod-index mod-index-env fm-index fm-ratio -- }> :frequency freq make-oscil { carrier } :frequency mod-freq make-oscil { fm1-osc } :frequency fm-ratio freq f* make-oscil { fm2-osc } :envelope amp-env :scaler amp :duration dur make-env { ampf } :envelope mod-index-env :scaler mod-index hz->radians :duration dur make-env { indf } :envelope mod-freq-env :scaler mod-skew hz->radians :duration dur make-env { modfrqf } fm-index fm-ratio f* freq f* hz->radians { fm2-amp } 0.0 0.0 { garble-in garble-out } start dur #{ :degree 90.0 random } run-instrument fm1-osc modfrqf env 0.0 oscil indf env f* to garble-in fm2-osc garble-in 0.0 oscil fm2-amp f* to garble-out carrier garble-out garble-in f+ 0.0 oscil ampf env f* end-run ;instrument : fm-insect-test <{ :optional start 0.0 dur 1.0 -- }> start now! #( 0 0 40 1 95 1 100 0.5 ) { locust } #( 0 1 25 0.7 75 0.78 100 1 ) { bug-hi } #( 0 0 25 1 75 0.7 100 0 ) { amp } now@ 0.000 f+ 1.699 4142.627 0.015 amp 60 -16.707 locust 500.866 bug-hi 0.346 0.5 fm-insect now@ 0.195 f+ 0.233 4126.284 0.030 amp 60 -12.142 locust 649.490 bug-hi 0.407 0.5 fm-insect now@ 0.217 f+ 2.057 3930.258 0.045 amp 60 -3.011 locust 562.087 bug-hi 0.591 0.5 fm-insect now@ 2.100 f+ 1.500 900.627 0.060 amp 40 -16.707 locust 300.866 bug-hi 0.346 0.5 fm-insect now@ 3.000 f+ 1.500 900.627 0.060 amp 40 -16.707 locust 300.866 bug-hi 0.046 0.5 fm-insect now@ 3.450 f+ 1.500 900.627 0.090 amp 40 -16.707 locust 300.866 bug-hi 0.006 0.5 fm-insect now@ 3.950 f+ 1.500 900.627 0.120 amp 40 -10.707 locust 300.866 bug-hi 0.346 0.5 fm-insect now@ 4.300 f+ 1.500 900.627 0.090 amp 40 -20.707 locust 300.866 bug-hi 0.246 0.5 fm-insect 6.0 step ; \ FM-DRUM \ \ Jan Mattox's fm drum: instrument: fm-drum <{ start dur freq amp index :optional high #f degr 0.0 dist 1.0 rev-amt 0.01 -- }> high if 3.414 8.525 else 1.414 3.515 then { casrat fmrat } :envelope #( 0 0 25 0 75 1 100 1 ) :scaler high if 66.0 hz->radians else 0 then :duration dur make-env { glsf } #( 0 0 3 0.05 5 0.2 7 0.8 8 0.95 10 1.0 12 0.95 20 0.3 30 0.1 100 0 ) { ampfun } high if 0.01 else 0.015 then 100.0 f* dur f/ { atdrpt } :envelope ampfun 10.0 atdrpt 15.0 100.0 dur 0.2 f- dur f/ 100.0 f* f- atdrpt 1.0 f+ fmax stretch-envelope :scaler amp :duration dur make-env { ampf } #( 0 0 5 0.014 10 0.033 15 0.061 20 0.099 25 0.153 30 0.228 35 0.332 40 0.477 45 0.681 50 0.964 55 0.681 60 0.478 65 0.332 70 0.228 75 0.153 80 0.099 85 0.061 90 0.033 95 0.0141 100 0 ) { indxfun } 100.0 dur 0.1 f- dur f/ 100.0 f* f- { indxpt } indxfun 50.0 atdrpt 65.0 indxpt stretch-envelope { divindxf } :envelope divindxf :duration dur :scaler fmrat freq f* index f* hz->radians pi fmin make-env { indxf } :envelope divindxf :duration dur :scaler casrat freq f* index f* hz->radians pi fmin make-env { mindxf } :envelope ampfun 10.0 atdrpt 90.0 100.0 dur 0.05 f- dur f/ 100.0 f* f- atdrpt 1.0 f+ fmax stretch-envelope :duration dur :scaler 7000.0 hz->radians pi fmin make-env { devf } :frequency 7000.0 :amplitude 1 make-rand { rn } :frequency freq make-oscil { car } :frequency freq fmrat f* make-oscil { fmosc } :frequency freq casrat f* make-oscil { cc } 0.0 { gls } start dur #{ :degree degr :distance dist :reverb rev-amt } run-instrument glsf env to gls cc ( gen ) devf env rn 0.0 rand f* gls casrat f* f+ ( fm ) 0.0 ( pm ) oscil mindxf env f* gls fmrat f* f+ ( fm ) fmosc ( gen ) swap 0.0 ( pm ) oscil indxf env f* gls f+ ( fm ) car ( gen ) swap 0.0 ( pm ) oscil ampf env f* end-run ;instrument : fm-drum-test <{ :optional start 0.0 dur 1.0 -- }> start now! now@ dur 55 0.3 5 fm-drum dur 0.2 f+ step now@ dur 66 0.3 4 #t fm-drum dur 0.2 f+ step ; \ FM-GONG \ \ Paul Weineke's gong. instrument: gong <{ start dur freq amp :key degree 0.0 distance 1.0 reverb-amount 0.005 -- }> 0.01 1.160 freq f* f* hz->radians { indx01 } 0.30 1.160 freq f* f* hz->radians { indx11 } 0.01 3.140 freq f* f* hz->radians { indx02 } 0.38 3.140 freq f* f* hz->radians { indx12 } 0.01 1.005 freq f* f* hz->radians { indx03 } 0.50 1.005 freq f* f* hz->radians { indx13 } 5 { atpt } 100 0.002 dur f/ f* { atdur } #( 0 0 3 1 15 0.5 27 0.25 50 0.1 100 0 ) { expf } #( 0 0 15 0.3 30 1.0 75 0.5 100 0 ) { rise } #( 0 0 75 1.0 98 1.0 100 0 ) { fmup } #( 0 0 2 1.0 100 0 ) { fmdwn } :envelope expf atpt atdur 0 0 stretch-envelope :scaler amp :duration dur make-env { ampfun } :envelope fmup :scaler indx11 indx01 f- :duration dur :offset indx01 make-env { indxfun1 } :envelope fmdwn :scaler indx12 indx02 f- :duration dur :offset indx02 make-env { indxfun2 } :envelope rise :scaler indx13 indx03 f- :duration dur :offset indx03 make-env { indxfun3 } :frequency freq make-oscil { car } :frequency freq 1.160 f* make-oscil { mod1 } :frequency freq 3.140 f* make-oscil { mod2 } :frequency freq 1.005 f* make-oscil { mod3 } start dur #{ :degree degree :distance distance :reverb reverb-amount } run-instrument car mod3 0.0 0.0 oscil indxfun3 env f* mod2 0.0 0.0 oscil indxfun2 env f* f+ mod1 0.0 0.0 oscil indxfun1 env f* f+ 0.0 oscil ampfun env f* end-run ;instrument : gong-test <{ :optional start 0.0 dur 1.0 -- }> start now! now@ dur 261.61 0.6 gong dur 0.2 f+ step ; \ ATTRACT \ \ by James McCartney, from CMJ vol 21 no 3 p 6 instrument: attract <{ start dur amp c -- }> 0.2 0.2 { a b } 0.04 { dt } amp f2/ c f/ { scale } -1.0 { x } 0.0 0.0 0.0 { x1 y z } start dur #{ :degree 90.0 random } run-instrument x y z f+ dt f* f- to x1 a y f* x f+ dt f* y f+ to y x z f* b f+ c z f* f- dt f* z f+ to z x1 to x scale x f* end-run ;instrument : attract-test <{ :optional start 0.0 dur 1.0 -- }> start now! now@ dur 0.5 2.0 attract dur 0.2 f+ step ; \ PQW \ \ phase-quadrature waveshaping used to create asymmetric (i.e. single \ side-band) spectra. The basic idea here is a variant of sin x sin y \ - cos x cos y = cos (x + y) \ \ clm/pqw.ins instrument: pqw <{ start dur sfreq cfreq amp ampfun indexfun parts :key degree 0.0 distance 1.0 reverb-amount 0.005 -- }> parts normalize-partials { nparts } :frequency sfreq :initial-phase half-pi make-oscil { sp-cos } :frequency sfreq make-oscil { sp-sin } :frequency cfreq :initial-phase half-pi make-oscil { c-cos } :frequency cfreq make-oscil { c-sin } nparts mus-chebyshev-second-kind partials->polynomial { sin-coeffs } nparts mus-chebyshev-first-kind partials->polynomial { cos-coeffs } :envelope ampfun :scaler amp :duration dur make-env { amp-env } :envelope indexfun :duration dur make-env { ind-env } 0.0 0.0 0.0 0.0 { vib ax fax yfax } cfreq sfreq f/ { r } :frequency 5.0 :amplitude 0.005 sfreq f* hz->radians make-triangle-wave { tr } :frequency 12.0 :amplitude 0.005 sfreq f* hz->radians make-rand-interp { rn } start dur #{ :degree degree :distance distance :reverb reverb-amount } run-instrument tr 0.0 triangle-wave rn 0.0 rand-interp f+ to vib 1.0 ind-env env fmin sp-cos vib 0.0 oscil f* to ax cos-coeffs ax polynomial to fax sp-sin vib 0.0 oscil sin-coeffs ax polynomial f* to yfax c-sin vib r f* 0.0 oscil yfax f* c-cos vib r f* 0.0 oscil fax f* f- amp-env env f* end-run ;instrument : pqw-test <{ :optional start 0.0 dur 1.0 -- }> start now! now@ dur 200 1000 0.2 #( 0 0 25 1 100 0 ) #( 0 1 100 0 ) #( 2 0.1 3 0.3 6 0.5 ) pqw dur 0.2 f+ step ; \ taken from Perry Cook's stkv1.tar.Z (Synthesis Toolkit), but I was \ in a bit of a hurry and may not have made slavishly accurate \ translations. Please let me (bil@ccrma.stanford.edu) know of any \ serious (non-envelope) errors. \ \ from Perry Cook's TubeBell.cpp instrument: tubebell <{ start dur freq amp :optional base 32.0 -- }> :frequency freq 0.995 f* make-oscil { osc0 } :frequency freq 0.995 1.414 f* f* make-oscil { osc1 } :frequency freq 1.005 f* make-oscil { osc2 } :frequency freq 1.414 f* make-oscil { osc3 } :envelope #( 0 0 0.005 1 dur 0.006 fmax 0 ) :base base :duration dur make-env { ampenv1 } :envelope #( 0 0 0.001 1 dur 0.002 fmax 0 ) :base base f2* :duration dur make-env { ampenv2 } :frequency 2.0 make-oscil { ampmod } amp f2/ { g0 } g0 0.707 f* { g1 } start dur #{ :degree 90.0 random } run-instrument ampmod 0.0 0.0 oscil 0.007 f* 0.993 f+ ( amp ) osc0 osc1 0.0 0.0 oscil 0.203 f* 0.0 oscil ampenv1 env f* g1 f* osc2 osc3 0.0 0.0 oscil 0.144 f* 0.0 oscil ampenv2 env f* g0 f* f+ ( osc0 + osc2 ) f* ( amp * osc0+2 ) end-run ;instrument : tubebell-test <{ :optional start 0.0 dur 1.0 -- }> start now! now@ dur 440 0.2 32 tubebell dur 0.2 f+ step ; \ from Perry Cook's Wurley.cpp instrument: wurley <{ start dur freq amp -- }> :frequency freq make-oscil { osc0 } :frequency freq 4 f* make-oscil { osc1 } :frequency 510 make-oscil { osc2 } :frequency 510 make-oscil { osc3 } :frequency 8 make-oscil { ampmod } :envelope #( 0 0 1 1 9 1 10 0 ) :duration dur make-env { ampenv } :envelope #( 0 0 0.001 1 0.15 0 dur 0.16 fmax 0 ) :duration dur make-env { indenv } :envelope #( 0 0 0.001 1 0.25 0 dur 0.26 fmax 0 ) :duration dur make-env { resenv } amp f2/ { g0 } g0 0.307 f* { g1 } start dur #{ :degree 90.0 random } run-instrument ampenv env ( amp ) ampmod 0.0 0.0 oscil 0.007 f* 1.0 f+ f* ( ampmod * amp ) osc0 osc1 0.0 0.0 oscil 0.307 f* 0.0 oscil g0 f* osc2 osc3 0.0 0.0 oscil indenv env f* 0.117 f* 0.0 oscil g1 f* resenv env f* f+ ( osc0 + osc2 ) f* ( amp * osc0+2 ) end-run ;instrument : wurley-test <{ :optional start 0.0 dur 1.0 -- }> start now! now@ dur 440 0.2 wurley dur 0.2 f+ step ; \ from Perry Cook's Rhodey.cpp instrument: rhodey <{ start dur freq amp :optional base 0.5 -- }> :frequency freq make-oscil { osc0 } :frequency freq make-oscil { osc1 } :frequency freq make-oscil { osc2 } :frequency freq make-oscil { osc3 } :envelope #( 0 0 0.005 1 dur 0.006 fmax 0 ) :base base :duration dur make-env { ampenv1 } :envelope #( 0 0 0.001 1 dur 0.002 fmax 0 ) :base base 1.5 f* :duration dur make-env { ampenv2 } :envelope #( 0 0 0.001 1 0.25 0 ) :base base 4 f* :duration dur make-env { ampenv3 } amp f2/ { g0 } start dur #{ :degree 90.0 random } run-instrument osc0 osc1 0.0 0.0 oscil 0.535 f* 0.0 oscil ampenv1 env f* g0 f* osc2 osc3 0.0 0.0 oscil 0.109 f* ampenv3 env f* 0.0 oscil ampenv2 env f* g0 f* f+ ( osc0 + osc2 ) end-run ;instrument : rhodey-test <{ :optional start 0.0 dur 1.0 -- }> start now! now@ dur 440 0.2 0.5 rhodey dur 0.2 f+ step ; \ from Perry Cook's BeeThree.cpp instrument: hammondoid <{ start dur freq amp -- }> :frequency freq 0.999 f* make-oscil { osc0 } :frequency freq 1.997 f* make-oscil { osc1 } :frequency freq 3.006 f* make-oscil { osc2 } :frequency freq 6.009 f* make-oscil { osc3 } :envelope #( 0 0 0.005 1 dur 0.006 fmax 0.008 f- 1 dur 0 ) :duration dur make-env { ampenv1 } :envelope #( 0 0 0.005 1 dur 0.006 fmax 0 ) :duration dur make-env { ampenv2 } amp f2/ { g0 } 0.1875 amp f* { amp0.1875 } 0.375 amp f* { amp0.375 } start dur #{ :degree 90.0 random } run-instrument osc0 0.0 0.0 oscil amp0.1875 f* osc1 0.0 0.0 oscil amp0.1875 f* f+ ( osc0 + osc1 ) osc2 0.0 0.0 oscil g0 f* f+ ( osc0+1 + osc2 ) ampenv1 env f* ( osc0+1+2 * amp1 ) osc3 0.0 0.0 oscil amp0.375 f* ampenv2 env f* ( osc3 * amp2 ) f+ ( osc0+1+2*amp1 + osc3*amp2 ) end-run ;instrument : hammondoid-test <{ :optional start 0.0 dur 1.0 -- }> start now! now@ dur 440 0.2 hammondoid dur 0.2 f+ step ; \ from Perry Cook's HeavyMtl.cpp instrument: metal <{ start dur freq amp -- }> :frequency freq make-oscil { osc0 } :frequency freq 4 f* 0.999 f* make-oscil { osc1 } :frequency freq 3 f* 1.001 f* make-oscil { osc2 } :frequency freq 0.5 f* 1.002 f* make-oscil { osc3 } :envelope #( 0 0 0.001 1 dur 0.002 fmax 0.002 f- 1 dur 0 ) :duration dur make-env { ampenv0 } :envelope #( 0 0 0.001 1 dur 0.002 fmax 0.011 f- 1 dur 0 ) :duration dur make-env { ampenv1 } :envelope #( 0 0 0.010 1 dur 0.020 fmax 0.015 f- 1 dur 0 ) :duration dur make-env { ampenv2 } :envelope #( 0 0 0.030 1 dur 0.040 fmax 0.040 f- 1 dur 0 ) :duration dur make-env { ampenv3 } 0.615 amp f* { amp0.615 } start dur #{ :degree 90.0 random } run-instrument osc0 osc1 osc2 0.0 0.0 oscil ampenv2 env f* 0.574 f* ( fm1 ) 0.0 ( pm1 ) oscil ampenv1 env f* 0.202 f* ( osc1 ) osc3 0.0 0.0 oscil ampenv3 env f* 0.116 f* ( osc3 ) f+ ( fm0 = osc1 + osc3 ) 0.0 ( pm0 ) oscil ampenv0 env f* amp0.615 f* ( osc0 ) end-run ;instrument : metal-test <{ :optional start 0.0 dur 1.0 -- }> start now! now@ dur 440 0.2 metal dur 0.2 f+ step ; \ DRONE instrument: drone <{ start dur freq amp ampfun synth ampat ampdc rvibamt rvibfreq -- }> :frequency freq :wave synth #f #f partials->wave make-table-lookup { s } :envelope ampfun 25.0 ampat dur f/ 100.0 f* 75.0 100.0 ampdc dur f/ 100.0 f* f- stretch-envelope :scaler amp 0.25 f* :duration dur make-env { ampenv } :frequency rvibfreq :amplitude rvibamt freq f* hz->radians make-rand { ranvib } start dur #{ :degree 90.0 random } run-instrument s ranvib 0.0 rand fabs table-lookup ampenv env f* end-run ;instrument \ CANTER instrument: canter <{ start dur pitch amp ampfun ranfun skewfun skewpc ranpc ranfreq indexfun atdr dcdr ampfun1 indfun1 fmtfun1 ampfun2 indfun2 fmtfun2 ampfun3 indfun3 fmtfun3 ampfun4 indfun4 fmtfun4 -- }> pitch 400.0 f/ flog 910.0 400.0 f/ flog f/ 100.0 f* floor { k } 100.0 atdr dur f/ f* { atpt } 100.0 100.0 dcdr dur f/ f* f- { dcpt } k fmtfun1 1.0 envelope-interp { lfmt1 } 0.5 lfmt1 pitch f/ f+ floor { harm1 } k indfun1 1.0 envelope-interp pitch f* hz->radians { dev11 } dev11 f2/ { dev01 } k ampfun1 1.0 envelope-interp amp f* 1.0 harm1 lfmt1 pitch f/ f- fabs f- f* { lamp1 } k fmtfun2 1.0 envelope-interp { lfmt2 } 0.5 lfmt2 pitch f/ f+ floor { harm2 } k indfun2 1.0 envelope-interp pitch f* hz->radians { dev12 } dev12 f2/ { dev02 } k ampfun2 1.0 envelope-interp amp f* 1.0 harm2 lfmt2 pitch f/ f- fabs f- f* { lamp2 } k fmtfun3 1.0 envelope-interp { lfmt3 } 0.5 lfmt3 pitch f/ f+ floor { harm3 } k indfun3 1.0 envelope-interp pitch f* hz->radians { dev13 } dev13 f2/ { dev03 } k ampfun3 1.0 envelope-interp amp f* 1.0 harm3 lfmt3 pitch f/ f- fabs f- f* { lamp3 } k fmtfun4 1.0 envelope-interp { lfmt4 } 0.5 lfmt4 pitch f/ f+ floor { harm4 } k indfun4 1.0 envelope-interp pitch f* hz->radians { dev14 } dev14 f2/ { dev04 } k ampfun4 1.0 envelope-interp amp f* 1.0 harm4 lfmt4 pitch f/ f- fabs f- f* { lamp4 } :envelope ampfun 25.0 atpt 75.0 dcpt stretch-envelope :duration dur make-env { tampfun } :envelope skewfun 25.0 atpt 75.0 dcpt stretch-envelope :duration dur :scaler pitch skewpc f* hz->radians make-env { tskwfun } :envelope ranfun 25.0 atpt 75.0 dcpt stretch-envelope :duration dur make-env { tranfun } :envelope indexfun 25.0 atpt 75.0 dcpt stretch-envelope :duration dur make-env { tidxfun } :frequency pitch make-oscil { modgen } :frequency pitch harm1 f* make-oscil { gen1 } :frequency pitch harm2 f* make-oscil { gen2 } :frequency pitch harm3 f* make-oscil { gen3 } :frequency pitch harm4 f* make-oscil { gen4 } :frequency ranfreq :amplitude ranpc pitch f* hz->radians make-rand { ranvib } 0.0 0.0 0.0 0.0 { frqval modval ampval indval } start dur #{ :degree 90.0 random } run-instrument tskwfun env tranfun env ranvib 0.0 rand f* f+ to frqval modgen frqval 0.0 oscil to modval tampfun env to ampval tidxfun env to indval gen1 indval dev11 f* dev01 f+ modval f* frqval f+ harm1 f* 0.0 oscil lamp1 ampval f* f* gen2 indval dev12 f* dev02 f+ modval f* frqval f+ harm2 f* 0.0 oscil lamp2 ampval f* f* f+ ( gen1 + gen2 ) gen3 indval dev13 f* dev03 f+ modval f* frqval f+ harm3 f* 0.0 oscil lamp3 ampval f* f* f+ ( gen1+2 + gen3 ) gen4 indval dev14 f* dev04 f+ modval f* frqval f+ harm4 f* 0.0 oscil lamp4 ampval f* f* f+ ( gen1+2+3 + gen4 ) end-run ;instrument : drone/canter-test <{ :optional start 0.0 dur 1.0 -- }> start now! #( 0 1200 100 1000 ) { fmt1 } #( 0 2250 100 1800 ) { fmt2 } #( 0 4500 100 4500 ) { fmt3 } #( 0 6750 100 8100 ) { fmt4 } #( 0 0.67 100 0.70 ) { amp1 } #( 0 0.95 100 0.95 ) { amp2 } #( 0 0.28 100 0.33 ) { amp3 } #( 0 0.14 100 0.15 ) { amp4 } #( 0 0.75 100 0.65 ) { ind1 } #( 0 0.75 100 0.75 ) { ind2 } #( 0 1 100 1 ) { ind3 } #( 0 1 100 1 ) { ind4 } #( 0 0 100 0 ) { skwf } #( 0 0 25 1 75 1 100 0 ) { ampf } #( 0 0.5 100 0.5 ) { ranf } #( 0 1 100 1 ) { index } #( 0 0 5 1 95 1 100 0 ) { solid } #( 0.5 0.06 1 0.62 1.5 0.07 2 0.6 2.5 0.08 3 0.56 4 0.24 5 0.98 6 0.53 7 0.16 8 0.33 9 0.62 10 0.12 12 0.14 14 0.86 16 0.12 23 0.14 24 0.17 ) { bassdr2 } #( 0.3 0.04 1 0.81 2 0.27 3 0.2 4 0.21 5 0.18 6 0.35 7 0.03 8 0.07 9 0.02 10 0.025 11 0.035 ) { tenordr } now@ 4 115.0 0.125 solid bassdr2 0.1 0.5 0.01 10 drone now@ 4 229.0 0.125 solid tenordr 0.1 0.5 0.01 11 drone now@ 4 229.5 0.125 solid tenordr 0.1 0.5 0.01 09 drone now@ 2.100 918.000 0.175 ampf ranf skwf 0.050 0.01 10 index 0.005 0.005 amp1 ind1 fmt1 amp2 ind2 fmt2 amp3 ind3 fmt3 amp4 ind4 fmt4 canter now@ 2.100 f+ 0.300 688.500 0.175 ampf ranf skwf 0.050 0.01 10 index 0.005 0.005 amp1 ind1 fmt1 amp2 ind2 fmt2 amp3 ind3 fmt3 amp4 ind4 fmt4 canter now@ 2.400 f+ 0.040 826.200 0.175 ampf ranf skwf 0.050 0.01 10 index 0.005 0.005 amp1 ind1 fmt1 amp2 ind2 fmt2 amp3 ind3 fmt3 amp4 ind4 fmt4 canter now@ 2.440 f+ 0.560 459.000 0.175 ampf ranf skwf 0.050 0.01 10 index 0.005 0.005 amp1 ind1 fmt1 amp2 ind2 fmt2 amp3 ind3 fmt3 amp4 ind4 fmt4 canter now@ 3.000 f+ 0.040 408.000 0.175 ampf ranf skwf 0.050 0.01 10 index 0.005 0.005 amp1 ind1 fmt1 amp2 ind2 fmt2 amp3 ind3 fmt3 amp4 ind4 fmt4 canter now@ 3.040 f+ 0.040 619.650 0.175 ampf ranf skwf 0.050 0.01 10 index 0.005 0.005 amp1 ind1 fmt1 amp2 ind2 fmt2 amp3 ind3 fmt3 amp4 ind4 fmt4 canter now@ 3.080 f+ 0.040 408.000 0.175 ampf ranf skwf 0.050 0.01 10 index 0.005 0.005 amp1 ind1 fmt1 amp2 ind2 fmt2 amp3 ind3 fmt3 amp4 ind4 fmt4 canter now@ 3.120 f+ 0.040 688.500 0.175 ampf ranf skwf 0.050 0.01 10 index 0.005 0.005 amp1 ind1 fmt1 amp2 ind2 fmt2 amp3 ind3 fmt3 amp4 ind4 fmt4 canter now@ 3.160 f+ 0.290 459.000 0.175 ampf ranf skwf 0.050 0.01 10 index 0.005 0.005 amp1 ind1 fmt1 amp2 ind2 fmt2 amp3 ind3 fmt3 amp4 ind4 fmt4 canter now@ 3.450 f+ 0.150 516.375 0.175 ampf ranf skwf 0.050 0.01 10 index 0.005 0.005 amp1 ind1 fmt1 amp2 ind2 fmt2 amp3 ind3 fmt3 amp4 ind4 fmt4 canter now@ 3.600 f+ 0.040 826.200 0.175 ampf ranf skwf 0.050 0.01 10 index 0.005 0.005 amp1 ind1 fmt1 amp2 ind2 fmt2 amp3 ind3 fmt3 amp4 ind4 fmt4 canter now@ 3.640 f+ 0.040 573.750 0.175 ampf ranf skwf 0.050 0.01 10 index 0.005 0.005 amp1 ind1 fmt1 amp2 ind2 fmt2 amp3 ind3 fmt3 amp4 ind4 fmt4 canter now@ 3.680 f+ 0.040 619.650 0.175 ampf ranf skwf 0.050 0.01 10 index 0.005 0.005 amp1 ind1 fmt1 amp2 ind2 fmt2 amp3 ind3 fmt3 amp4 ind4 fmt4 canter now@ 3.720 f+ 0.180 573.750 0.175 ampf ranf skwf 0.050 0.01 10 index 0.005 0.005 amp1 ind1 fmt1 amp2 ind2 fmt2 amp3 ind3 fmt3 amp4 ind4 fmt4 canter now@ 3.900 f+ 0.040 688.500 0.175 ampf ranf skwf 0.050 0.01 10 index 0.005 0.005 amp1 ind1 fmt1 amp2 ind2 fmt2 amp3 ind3 fmt3 amp4 ind4 fmt4 canter now@ 3.940 f+ 0.260 459.000 0.175 ampf ranf skwf 0.050 0.01 10 index 0.005 0.005 amp1 ind1 fmt1 amp2 ind2 fmt2 amp3 ind3 fmt3 amp4 ind4 fmt4 canter 4.4 step ; \ NREV (the most popular Samson box reverb) \ \ REVERB-FACTOR controls the length of the decay -- it should not \ exceed (/ 1.0 .823), LP-COEFF controls the strength of the low pass \ filter inserted in the feedback loop, VOLUME can be used to boost the \ reverb output. \ \ clm/nrev.ins instrument: nrev-fs <{ :key reverb-factor 1.09 lp-coeff 0.7 lp-out-coeff 0.85 output-scale 1.0 volume 1.0 amp-env #( 0 1 1 1 ) -- }> doc" NREV (the most popular Samson box reverb).\n\ <'> fm-violin-test :reverb <'> nrev with-sound." *output* channels { chans } *reverb* channels { rev-chans } *reverb* reverb-dur { dur } *verbose* if get-func-name rev-chans chans reverb-info then mus-srate 25641.0 f/ { sr } #( 1433 1601 1867 2053 2251 2399 347 113 37 59 43 37 29 19 ) map sr *key* f* f>s dup 2 mod unless 1+ then ( val ) begin ( val ) dup prime? false? while 2 + repeat ( val ) end-map { dly-len } :scaler 0.822 reverb-factor f* :size dly-len 0 array-ref make-comb { comb0 } :scaler 0.802 reverb-factor f* :size dly-len 1 array-ref make-comb { comb1 } :scaler 0.773 reverb-factor f* :size dly-len 2 array-ref make-comb { comb2 } :scaler 0.753 reverb-factor f* :size dly-len 3 array-ref make-comb { comb3 } :scaler 0.753 reverb-factor f* :size dly-len 4 array-ref make-comb { comb4 } :scaler 0.733 reverb-factor f* :size dly-len 5 array-ref make-comb { comb5 } :feedback -0.7 :feedforward 0.7 :size dly-len 6 array-ref make-all-pass { allp0 } :feedback -0.7 :feedforward 0.7 :size dly-len 7 array-ref make-all-pass { allp1 } :feedback -0.7 :feedforward 0.7 :size dly-len 8 array-ref make-all-pass { allp2 } :feedback -0.7 :feedforward 0.7 :size dly-len 9 array-ref make-all-pass { allp3 } :feedback -0.7 :feedforward 0.7 :size dly-len 10 array-ref make-all-pass { allp4 } :feedback -0.7 :feedforward 0.7 :size dly-len 11 array-ref make-all-pass { allp5 } :feedback -0.7 :feedforward 0.7 :size dly-len 12 array-ref make-all-pass { allp6 } :feedback -0.7 :feedforward 0.7 :size dly-len 13 array-ref make-all-pass { allp7 } lp-coeff lp-coeff 1.0 f- make-one-pole { low } lp-out-coeff lp-coeff 1.0 f- make-one-pole { low-a } lp-out-coeff lp-coeff 1.0 f- make-one-pole { low-b } lp-out-coeff lp-coeff 1.0 f- make-one-pole { low-c } lp-out-coeff lp-coeff 1.0 f- make-one-pole { low-d } :envelope amp-env :scaler output-scale :duration dur make-env { ampf } 0.0 dur run 0.0 ( rev ) rev-chans 0 ?do j i *reverb* in-any f+ loop volume f* ampf env f* { rev } 0.0 ( outrev ) comb0 rev 0.0 comb f+ comb1 rev 0.0 comb f+ comb2 rev 0.0 comb f+ comb3 rev 0.0 comb f+ comb4 rev 0.0 comb f+ comb5 rev 0.0 comb f+ { outrev } allp2 allp1 allp0 outrev 0.0 all-pass 0.0 all-pass 0.0 all-pass to outrev allp3 low outrev one-pole 0.0 all-pass to outrev low-a allp4 outrev 0.0 all-pass one-pole output-scale f* { sample-a } low-b allp5 outrev 0.0 all-pass one-pole output-scale f* { sample-b } low-c allp6 outrev 0.0 all-pass one-pole output-scale f* { sample-c } low-d allp7 outrev 0.0 all-pass one-pole output-scale f* { sample-d } chans 2 = if i sample-a sample-d f+ f2/ *output* outa drop else i sample-a *output* outa drop then chans 2 = chans 4 = || if chans 2 = if i sample-b sample-c f+ f2/ *output* outb drop else i sample-b *output* outb drop then then chans 4 = if i sample-c *output* outc drop i sample-d *output* outd drop then loop ;instrument <'> nrev-fs alias nrev <'> nrev <'> nrev-fs help-ref help-set! #( "reson-carriers" "reson-ampfs" "reson-indfs" "reson-c-rats" ) create-struct make-reson-struct \ RESON instrument: reson <{ start dur pitch amp indxfun skewfun pcskew skewat skewdc vibfreq vibpc ranvibfreq ranvibpc data -- }> :frequency pitch make-oscil { mod } :envelope skewfun 25.0 skewat dur f/ 100.0 f* 75.0 100.0 skewdc dur f/ 100.0 f* f- stretch-envelope :scaler pcskew pitch f* hz->radians :duration dur make-env { frqf } :frequency vibfreq :amplitude vibpc pitch f* hz->radians make-triangle-wave { pervib } :frequency ranvibfreq :amplitude ranvibpc pitch f* hz->radians make-rand-interp { ranvib } 0.0 ( sum ) data each ( lst-val ) 2 object-ref f+ ( sum += ... ) end-each { totalamp } nil { rs } data object->array map! *key* { frmdat } frmdat 0 object-ref { ampf } frmdat 1 object-ref { freq } frmdat 2 object-ref { rfamp } frmdat 3 object-ref dur f/ 100.0 f* { ampat } 100.0 frmdat 4 object-ref dur f/ 100.0 f* f- { ampdc } frmdat 5 object-ref freq f* hz->radians { dev0 } frmdat 6 object-ref freq f* hz->radians { dev1 } frmdat 7 object-ref dur f/ 100.0 f* { indxat } 100.0 frmdat 8 object-ref dur f/ 100.0 f* f- { indxdc } freq pitch f/ fround->s { harm } 1.0 harm freq pitch f/ f- fabs f- { rsamp } pitch harm f* { cfq } ampat f0= if 25.0 to ampat then ampdc f0= if 75.0 to ampdc then indxat f0= if 25.0 to indxat then indxdc f0= if 75.0 to indxdc then make-reson-struct to rs :envelope indxfun 25.0 indxat 75.0 indxdc stretch-envelope :scaler dev1 dev0 f- :offset dev0 :duration dur make-env rs swap reson-indfs! :envelope ampf 25.0 ampat 75.0 ampdc stretch-envelope :scaler rsamp amp rfamp totalamp f/ f* f* :duration dur make-env rs swap reson-ampfs! rs harm reson-c-rats! rs :frequency cfq :initial-phase 0.0 make-oscil reson-carriers! rs end-map { values } start dur #{ :degree 90.0 random } run-instrument pervib 0.0 triangle-wave ranvib 0.0 rand-interp f+ frqf env f+ { vib } mod vib 0.0 oscil { modsig } 0.0 ( val ) values each { rs } rs reson-ampfs@ env ( amp ) rs reson-carriers@ ( car-os ) rs reson-c-rats@ vib f* rs reson-indfs@ env modsig f* f+ ( car-fm ) 0.0 ( car-pm ) oscil f* ( car-os * amp ) f+ ( val += ... ) end-each ( val ) end-run ;instrument : reson-test <{ :optional start 0.0 dur 1.0 -- }> start now! #( #( #( 0 0 100 1 ) 1200 0.5 0.1 0.1 0 1.0 0.1 0.1 ) #( #( 0 1 100 0 ) 2400 0.5 0.1 0.1 0 1.0 0.1 0.1 ) ) { data } now@ dur 440 0.5 #( 0 0 100 1 ) #( 0 0 100 1 ) 0.1 0.1 0.1 5 0.01 5 0.01 data reson dur 0.2 f+ step ; \ STK's feedback-fm instrument named CelloN in Sambox-land instrument: cellon <{ start dur pitch0 amp ampfun betafun beta0 beta1 betaat betadc ampat ampdc pitch1 glissfun glissat glissdc pvibfreq pvibpc pvibfun pvibat pvibdc rvibfreq rvibpc rvibfun -- }> pitch1 f0= if pitch0 else pitch1 then { pit1 } :frequency pitch0 make-oscil { carr } 0.5 -0.5 make-one-zero { low } :frequency pitch0 make-oscil { fmosc } :frequency pvibfreq :amplitude 1.0 make-triangle-wave { pvib } :frequency rvibfreq :amplitude 1.0 make-rand-interp { rvib } ampat f0> if ampat dur f/ 100.0 f* else 25.0 then { ampap } ampdc f0> if 1.0 ampdc dur f/ f- 100.0 f* else 75.0 then { ampdp } glissat f0> if glissat dur f/ 100.0 f* else 25.0 then { glsap } glissdc f0> if 1.0 glissdc dur f/ f- 100.0 f* else 75.0 then { glsdp } betaat f0> if betaat dur f/ 100.0 f* else 25.0 then { betap } betadc f0> if 1.0 betadc dur f/ f- 100.0 f* else 75.0 then { betdp } pvibat f0> if pvibat dur f/ 100.0 f* else 25.0 then { pvbap } pvibdc f0> if 1.0 pvibdc dur f/ f- 100.0 f* else 75.0 then { pvbdp } :envelope pvibfun 25.0 pvbap 75.0 pvbdp stretch-envelope :scaler pvibpc pitch0 f* hz->radians :duration dur make-env { pvibenv } :envelope rvibfun :scaler rvibpc pitch0 f* hz->radians :duration dur make-env { rvibenv } :envelope glissfun 25.0 glsap 75.0 glsdp stretch-envelope :scaler pit1 pitch0 f- hz->radians :duration dur make-env { glisenv } :envelope ampfun 25.0 ampap 75.0 ampdp stretch-envelope :scaler amp :duration dur make-env { amplenv } :envelope betafun 25.0 betap 75.0 betdp stretch-envelope :scaler beta1 beta0 f- :offset beta0 :duration dur make-env { betaenv } 0.0 { fm } start dur #{ :degree 90.0 random } run-instrument pvibenv env pvib 0.0 triangle-wave f* rvibenv env rvib 0.0 rand-interp f* f+ glisenv env f+ { vib } low betaenv env fmosc vib fm f+ 0.0 oscil f* one-zero to fm amplenv env carr vib fm f+ 0.0 oscil f* end-run ;instrument : cellon-test <{ :optional start 0.0 dur 1.0 -- }> start now! now@ dur 220 0.5 #( 0 0 25 1 75 1 100 0 ) \ ampfun #( 0 0 25 1 75 1 100 0 ) \ betafun 0.75 1 0 0 0 0 220 #( 0 0 25 1 75 1 100 0 ) \ glissfun 0 0 0 0 #( 0 0 100 0 ) \ pvibfun 0 0 0 0 #( 0 0 100 0 ) \ rvibfun cellon dur 0.2 f+ step ; \ JL-REVERB instrument: jl-reverb <{ -- }> *output* channels { chans } *reverb* channels { rev-chans } *reverb* reverb-dur { dur } *verbose* if get-func-name rev-chans chans reverb-info then :feedback -0.7 :feedforward 0.7 :size 2111 make-all-pass { allpass1 } :feedback -0.7 :feedforward 0.7 :size 673 make-all-pass { allpass2 } :feedback -0.7 :feedforward 0.7 :size 223 make-all-pass { allpass3 } :scaler 0.742 :size 9601 make-comb { comb1 } :scaler 0.733 :size 10007 make-comb { comb2 } :scaler 0.715 :size 10799 make-comb { comb3 } :scaler 0.697 :size 11597 make-comb { comb4 } :size 0.013 seconds->samples make-delay { outdel1 } chans 1 > if :size 0.011 seconds->samples make-delay else #f then { outdel2 } chans 2 > if :size 0.015 seconds->samples make-delay else #f then { outdel3 } chans 3 > if :size 0.017 seconds->samples make-delay else #f then { outdel4 } 0.0 { allpass-sum } 0.0 { all-sums } 0.0 dur run 0.0 ( sum ) rev-chans 0 ?do j i *reverb* in-any f+ ( sum += ... ) loop { in-val } allpass3 allpass2 allpass1 in-val 0.0 all-pass 0.0 all-pass 0.0 all-pass to allpass-sum comb1 allpass-sum 0.0 comb comb2 allpass-sum 0.0 comb f+ comb3 allpass-sum 0.0 comb f+ comb4 allpass-sum 0.0 comb f+ to all-sums i outdel1 all-sums 0.0 delay *output* outa drop outdel2 if i outdel2 all-sums 0.0 delay *output* outb drop then outdel3 if i outdel3 all-sums 0.0 delay *output* outc drop then outdel4 if i outdel4 all-sums 0.0 delay *output* outd drop then loop ;instrument \ GRAN-SYNTH instrument: gran-synth <{ start dur freq grain-dur interval amp -- }> :envelope #( 0 0 25 1 75 1 100 0 ) :duration grain-dur make-env { grain-env } :frequency freq make-oscil { carrier } grain-dur interval fmax mus-srate f* fceil f>s { grain-size } :frequency interval 1/f :size grain-size make-wave-train { grains } grains mus-data map! grain-env env carrier 0.0 0.0 oscil f* end-map drop start dur #{ :degree 90.0 random } run-instrument grains 0.0 wave-train amp f* end-run ;instrument : gran-synth-test <{ :optional start 0.0 dur 1.0 -- }> start now! now@ dur 100 0.0189 0.02 0.4 gran-synth dur 0.2 f+ step ; \ TOUCH-TONE \ \ clm/ugex.ins instrument: touch-tone <{ numbers :key start 0.0 -- }> doc" (See clm/ugex.ins) NUMBERS is an array with phone numbers.\n\ #( 4 8 3 4 6 2 1 ) <'> touch-tone with-sound." #( 0 697 697 697 770 770 770 852 852 852 941 941 941 ) { tt1 } #( 0 1209 1336 1477 1209 1336 1477 1209 1336 1477 1209 1336 1477 ) { tt2 } numbers each ( numb ) dup 0= if drop 11 then { idx } :frequency tt1 idx array-ref make-oscil { frq1 } :frequency tt2 idx array-ref make-oscil { frq2 } i 0.3 f* start f+ 0.2 #{ :degree 90.0 random } run-instrument frq1 0.0 0.0 oscil frq2 0.0 0.0 oscil f+ 0.25 f* end-run end-each ;instrument : touch-tone-test <{ :optional start 0.0 dur 1.0 -- }> start now! #( 4 8 3 4 6 2 1 ) :start now@ touch-tone dur 7 ( digits ) f* 0.2 f+ step ; \ SPECTRA instrument: spectra <{ start dur freq amp :optional parts #( 1 1 2 0.5 ) ampenv #( 0 0 50 1 100 0 ) vibamp 0.005 vibfrq 5.0 degr 0.0 dist 1.0 rev-amt 0.005 -- }> :frequency freq :wave parts #f #f partials->wave make-table-lookup { s } :envelope ampenv :scaler amp :duration dur make-env { ampf } freq hz->radians vibamp f* { vamp } :frequency vibfrq :amplitude vamp make-triangle-wave { pervib } :frequency vibfrq 1.0 f+ :amplitude vamp make-rand-interp { ranvib } start dur #{ :degree degr :distance dist :reverb rev-amt } run-instrument s pervib 0.0 triangle-wave ranvib 0.0 rand-interp f+ table-lookup ampf env f* end-run ;instrument : spectra-test <{ :optional start 0.0 dur 1.0 -- }> start now! #( 1.00 0.1132 2.00 0.0252 3.00 0.0292 4.01 0.0136 5.03 0.0045 6.06 0.0022 7.11 0.0101 8.17 0.0004 9.23 0.0010 10.33 0.0012 11.44 0.0013 12.58 0.0011 13.75 0.0002 14.93 0.0005 16.14 0.0002 ) { p-a4 } now@ dur 440 2.0 p-a4 #( 0 0 1 1 5 0.9 12 0.5 25 0.25 100 0 ) spectra dur 0.2 f+ step ; \ TWO-TAB \ \ interpolate between two waveforms (this could be extended to \ implement all the various wavetable-based synthesis techniques). instrument: two-tab <{ start dur freq amp :optional part1 #( 1.0 1.0 2.0 0.5 ) part2 #( 1.0 0.0 3.0 1.0 ) ampenv #( 0 0 50 1 100 0 ) interpenv #( 0 1 100 0 ) vibamp 0.005 vibfrq 5.0 degr 0.0 dist 1.0 rev-amt 0.005 -- }> :frequency freq :wave part1 #f #f partials->wave make-table-lookup { s1 } :frequency freq :wave part2 #f #f partials->wave make-table-lookup { s2 } :envelope ampenv :scaler amp :duration dur make-env { ampf } :envelope interpenv :duration dur make-env { interpf } freq hz->radians vibamp f* { vamp } :frequency vibfrq :amplitude vamp make-triangle-wave { pervib } :frequency vibfrq 1.0 f+ :amplitude vamp make-rand-interp { ranvib } start dur #{ :degree degr :distance dist :reverb rev-amt } run-instrument pervib 0.0 triangle-wave ranvib 0.0 rand-interp f+ { vib } interpf env { intrp } s1 vib table-lookup intrp f* s2 vib table-lookup 1.0 intrp f- f* f+ ( s1 + s2 ) ampf env f* end-run ;instrument : two-tab-test <{ :optional start 0.0 dur 1.0 -- }> start now! now@ dur 440 0.5 two-tab dur 0.2 f+ step ; \ LBJ-PIANO #( #( 1.97 0.0326 2.99 0.0086 3.95 0.0163 4.97 0.0178 5.98 0.0177 6.95 0.0315 8.02 0.0001 8.94 0.0076 9.96 0.0134 10.99 0.0284 11.98 0.0229 13.02 0.0229 13.89 0.0010 15.06 0.0090 16.00 0.0003 17.08 0.0078 18.16 0.0064 19.18 0.0129 20.21 0.0085 21.27 0.0225 22.32 0.0061 23.41 0.0102 24.48 0.0005 25.56 0.0016 26.64 0.0018 27.70 0.0113 28.80 0.0111 29.91 0.0158 31.06 0.0093 32.17 0.0017 33.32 0.0002 34.42 0.0018 35.59 0.0027 36.74 0.0055 37.90 0.0037 39.06 0.0064 40.25 0.0033 41.47 0.0014 42.53 0.0004 43.89 0.0010 45.12 0.0039 46.33 0.0039 47.64 0.0009 48.88 0.0016 50.13 0.0006 51.37 0.0010 52.70 0.0002 54.00 0.0004 55.30 0.0008 56.60 0.0025 57.96 0.0010 59.30 0.0012 60.67 0.0011 61.99 0.0003 62.86 0.0001 64.36 0.0005 64.86 0.0001 66.26 0.0004 67.70 0.0006 68.94 0.0002 70.10 0.0001 70.58 0.0002 72.01 0.0007 73.53 0.0006 75.00 0.0002 77.03 0.0005 78.00 0.0002 79.57 0.0006 81.16 0.0005 82.70 0.0005 84.22 0.0003 85.41 0.0002 87.46 0.0001 90.30 0.0001 94.02 0.0001 95.26 0.0002 109.39 0.0003 ) #( 1.98 0.0194 2.99 0.0210 3.97 0.0276 4.96 0.0297 5.96 0.0158 6.99 0.0207 8.01 0.0009 9.00 0.0101 10.00 0.0297 11.01 0.0289 12.02 0.0211 13.04 0.0127 14.07 0.0061 15.08 0.0174 16.13 0.0009 17.12 0.0093 18.16 0.0117 19.21 0.0122 20.29 0.0108 21.30 0.0077 22.38 0.0132 23.46 0.0073 24.14 0.0002 25.58 0.0026 26.69 0.0035 27.77 0.0053 28.88 0.0024 30.08 0.0027 31.13 0.0075 32.24 0.0027 33.36 0.0004 34.42 0.0004 35.64 0.0019 36.78 0.0037 38.10 0.0009 39.11 0.0027 40.32 0.0010 41.51 0.0013 42.66 0.0019 43.87 0.0007 45.13 0.0017 46.35 0.0019 47.65 0.0021 48.89 0.0014 50.18 0.0023 51.42 0.0015 52.73 0.0002 54.00 0.0005 55.34 0.0006 56.60 0.0010 57.96 0.0016 58.86 0.0005 59.30 0.0004 60.75 0.0005 62.22 0.0003 63.55 0.0005 64.82 0.0003 66.24 0.0003 67.63 0.0011 69.09 0.0007 70.52 0.0004 72.00 0.0005 73.50 0.0008 74.95 0.0003 77.13 0.0013 78.02 0.0002 79.48 0.0004 82.59 0.0004 84.10 0.0003 ) #( 2.00 0.0313 2.99 0.0109 4.00 0.0215 5.00 0.0242 5.98 0.0355 7.01 0.0132 8.01 0.0009 9.01 0.0071 10.00 0.0258 11.03 0.0221 12.02 0.0056 13.06 0.0196 14.05 0.0160 15.11 0.0107 16.11 0.0003 17.14 0.0111 18.21 0.0085 19.23 0.0010 20.28 0.0048 21.31 0.0128 22.36 0.0051 23.41 0.0041 24.05 0.0006 25.54 0.0019 26.62 0.0028 27.72 0.0034 28.82 0.0062 29.89 0.0039 30.98 0.0058 32.08 0.0011 33.21 0.0002 34.37 0.0008 35.46 0.0018 36.62 0.0036 37.77 0.0018 38.92 0.0042 40.07 0.0037 41.23 0.0011 42.67 0.0003 43.65 0.0018 44.68 0.0025 45.99 0.0044 47.21 0.0051 48.40 0.0044 49.67 0.0005 50.88 0.0019 52.15 0.0003 53.42 0.0008 54.69 0.0010 55.98 0.0005 57.26 0.0013 58.53 0.0027 59.83 0.0011 61.21 0.0027 62.54 0.0003 63.78 0.0003 65.20 0.0001 66.60 0.0006 67.98 0.0008 69.37 0.0019 70.73 0.0007 72.14 0.0004 73.62 0.0002 74.40 0.0003 76.52 0.0006 77.97 0.0002 79.49 0.0004 80.77 0.0003 81.00 0.0001 82.47 0.0005 83.97 0.0001 87.27 0.0002 ) #( 2.00 0.0257 2.99 0.0142 3.97 0.0202 4.95 0.0148 5.95 0.0420 6.95 0.0037 7.94 0.0004 8.94 0.0172 9.95 0.0191 10.96 0.0115 11.97 0.0059 12.98 0.0140 14.00 0.0178 15.03 0.0121 16.09 0.0002 17.07 0.0066 18.08 0.0033 19.15 0.0022 20.18 0.0057 21.22 0.0077 22.29 0.0037 23.33 0.0066 24.97 0.0002 25.49 0.0019 26.55 0.0042 27.61 0.0043 28.73 0.0038 29.81 0.0084 30.91 0.0040 32.03 0.0025 33.14 0.0005 34.26 0.0003 35.38 0.0019 36.56 0.0037 37.68 0.0049 38.86 0.0036 40.11 0.0011 41.28 0.0008 42.50 0.0004 43.60 0.0002 44.74 0.0022 45.99 0.0050 47.20 0.0009 48.40 0.0036 49.68 0.0004 50.92 0.0009 52.17 0.0005 53.46 0.0007 54.76 0.0006 56.06 0.0005 57.34 0.0011 58.67 0.0005 59.95 0.0015 61.37 0.0008 62.72 0.0004 65.42 0.0009 66.96 0.0003 68.18 0.0003 69.78 0.0003 71.21 0.0004 72.45 0.0002 74.22 0.0003 75.44 0.0001 76.53 0.0003 78.31 0.0004 79.83 0.0003 80.16 0.0001 81.33 0.0003 82.44 0.0001 83.17 0.0002 84.81 0.0003 85.97 0.0003 89.08 0.0001 90.70 0.0002 92.30 0.0002 95.59 0.0002 97.22 0.0003 98.86 0.0001 108.37 0.0001 125.54 0.0001 ) #( 1.99 0.0650 3.03 0.0040 4.03 0.0059 5.02 0.0090 5.97 0.0227 6.98 0.0050 8.04 0.0020 9.00 0.0082 9.96 0.0078 11.01 0.0056 12.01 0.0095 13.02 0.0050 14.04 0.0093 15.08 0.0064 16.14 0.0017 17.06 0.0020 18.10 0.0025 19.14 0.0023 20.18 0.0015 21.24 0.0032 22.29 0.0029 23.32 0.0014 24.37 0.0005 25.43 0.0030 26.50 0.0022 27.60 0.0027 28.64 0.0024 29.76 0.0035 30.81 0.0136 31.96 0.0025 33.02 0.0003 34.13 0.0005 35.25 0.0007 36.40 0.0014 37.51 0.0020 38.64 0.0012 39.80 0.0019 40.97 0.0004 42.09 0.0003 43.24 0.0003 44.48 0.0002 45.65 0.0024 46.86 0.0005 48.07 0.0013 49.27 0.0008 50.49 0.0006 52.95 0.0001 54.23 0.0005 55.45 0.0004 56.73 0.0001 58.03 0.0003 59.29 0.0002 60.59 0.0003 62.04 0.0002 65.89 0.0002 67.23 0.0002 68.61 0.0002 69.97 0.0004 71.36 0.0005 85.42 0.0001 ) #( 1.98 0.0256 2.96 0.0158 3.95 0.0310 4.94 0.0411 5.95 0.0238 6.94 0.0152 7.93 0.0011 8.95 0.0185 9.92 0.0166 10.93 0.0306 11.94 0.0258 12.96 0.0202 13.97 0.0403 14.95 0.0228 15.93 0.0005 17.01 0.0072 18.02 0.0034 19.06 0.0028 20.08 0.0124 21.13 0.0137 22.16 0.0102 23.19 0.0058 23.90 0.0013 25.30 0.0039 26.36 0.0039 27.41 0.0025 28.47 0.0071 29.64 0.0031 30.60 0.0027 31.71 0.0021 32.84 0.0003 33.82 0.0002 35.07 0.0019 36.09 0.0054 37.20 0.0038 38.33 0.0024 39.47 0.0055 40.55 0.0016 41.77 0.0006 42.95 0.0002 43.27 0.0018 44.03 0.0006 45.25 0.0019 46.36 0.0033 47.50 0.0024 48.87 0.0012 50.03 0.0016 51.09 0.0004 53.52 0.0017 54.74 0.0012 56.17 0.0003 57.40 0.0011 58.42 0.0020 59.70 0.0007 61.29 0.0008 62.56 0.0003 63.48 0.0002 64.83 0.0002 66.12 0.0012 67.46 0.0017 68.81 0.0003 69.13 0.0003 70.53 0.0002 71.84 0.0001 73.28 0.0002 75.52 0.0010 76.96 0.0005 77.93 0.0003 78.32 0.0003 79.73 0.0003 81.69 0.0002 82.52 0.0001 84.01 0.0001 84.61 0.0002 86.88 0.0001 88.36 0.0002 89.85 0.0002 91.35 0.0003 92.86 0.0002 93.40 0.0001 105.28 0.0002 106.22 0.0002 107.45 0.0001 108.70 0.0003 122.08 0.0002 ) #( 1.97 0.0264 2.97 0.0211 3.98 0.0234 4.98 0.0307 5.96 0.0085 6.94 0.0140 7.93 0.0005 8.96 0.0112 9.96 0.0209 10.98 0.0194 11.98 0.0154 12.99 0.0274 13.99 0.0127 15.01 0.0101 15.99 0.0002 17.04 0.0011 18.08 0.0032 19.14 0.0028 20.12 0.0054 21.20 0.0053 22.13 0.0028 23.22 0.0030 24.32 0.0006 25.24 0.0004 26.43 0.0028 27.53 0.0048 28.52 0.0039 29.54 0.0047 30.73 0.0044 31.82 0.0007 32.94 0.0008 34.04 0.0012 35.13 0.0018 36.29 0.0007 37.35 0.0075 38.51 0.0045 39.66 0.0014 40.90 0.0004 41.90 0.0002 43.08 0.0002 44.24 0.0017 45.36 0.0013 46.68 0.0020 47.79 0.0015 48.98 0.0010 50.21 0.0012 51.34 0.0001 53.82 0.0003 55.09 0.0004 56.23 0.0005 57.53 0.0004 58.79 0.0005 59.30 0.0002 60.03 0.0002 61.40 0.0003 62.84 0.0001 66.64 0.0001 67.97 0.0001 69.33 0.0001 70.68 0.0001 73.57 0.0002 75.76 0.0002 76.45 0.0001 79.27 0.0001 80.44 0.0002 81.87 0.0002 ) #( 2.00 0.0311 2.99 0.0086 3.99 0.0266 4.97 0.0123 5.98 0.0235 6.97 0.0161 7.97 0.0008 8.96 0.0088 9.96 0.0621 10.99 0.0080 11.99 0.0034 12.99 0.0300 14.03 0.0228 15.04 0.0105 16.03 0.0004 17.06 0.0036 18.09 0.0094 18.95 0.0009 20.17 0.0071 21.21 0.0161 22.25 0.0106 23.28 0.0104 24.33 0.0008 25.38 0.0030 26.46 0.0035 27.50 0.0026 28.59 0.0028 29.66 0.0128 30.75 0.0139 31.81 0.0038 32.93 0.0006 34.04 0.0004 35.16 0.0005 36.25 0.0023 37.35 0.0012 38.46 0.0021 39.59 0.0035 40.71 0.0006 41.86 0.0007 42.42 0.0001 43.46 0.0003 44.17 0.0032 45.29 0.0013 46.57 0.0004 47.72 0.0011 48.79 0.0005 50.11 0.0005 51.29 0.0003 52.47 0.0002 53.68 0.0004 55.02 0.0005 56.18 0.0003 57.41 0.0003 58.75 0.0007 59.33 0.0009 60.00 0.0004 61.34 0.0001 64.97 0.0003 65.20 0.0002 66.48 0.0002 67.83 0.0002 68.90 0.0003 70.25 0.0003 71.59 0.0002 73.68 0.0001 75.92 0.0001 77.08 0.0002 78.45 0.0002 81.56 0.0002 82.99 0.0001 88.39 0.0001 ) #( 0.97 0.0059 1.98 0.0212 2.99 0.0153 3.99 0.0227 4.96 0.0215 5.97 0.0153 6.98 0.0085 7.98 0.0007 8.97 0.0179 9.98 0.0512 10.98 0.0322 12.00 0.0098 13.02 0.0186 14.00 0.0099 15.05 0.0109 15.88 0.0011 17.07 0.0076 18.11 0.0071 19.12 0.0045 20.16 0.0038 21.23 0.0213 22.27 0.0332 23.34 0.0082 24.34 0.0014 25.42 0.0024 26.47 0.0012 27.54 0.0014 28.60 0.0024 29.72 0.0026 30.10 0.0008 31.91 0.0021 32.13 0.0011 33.02 0.0007 34.09 0.0014 35.17 0.0007 36.27 0.0024 37.39 0.0029 38.58 0.0014 39.65 0.0017 40.95 0.0012 41.97 0.0004 42.43 0.0002 43.49 0.0001 44.31 0.0012 45.42 0.0031 46.62 0.0017 47.82 0.0013 49.14 0.0013 50.18 0.0010 51.54 0.0003 53.90 0.0006 55.06 0.0010 56.31 0.0003 57.63 0.0001 59.02 0.0003 60.09 0.0004 60.35 0.0004 61.62 0.0009 63.97 0.0001 65.19 0.0001 65.54 0.0002 66.92 0.0002 67.94 0.0002 69.17 0.0003 69.60 0.0004 70.88 0.0002 72.24 0.0002 76.12 0.0001 78.94 0.0001 81.75 0.0001 82.06 0.0001 83.53 0.0001 90.29 0.0002 91.75 0.0001 92.09 0.0002 93.28 0.0001 97.07 0.0001 ) #( 1.98 0.0159 2.98 0.1008 3.98 0.0365 4.98 0.0133 5.97 0.0101 6.97 0.0115 7.97 0.0007 8.99 0.0349 10.01 0.0342 11.01 0.0236 12.00 0.0041 13.02 0.0114 14.05 0.0137 15.06 0.0100 16.05 0.0007 17.04 0.0009 18.12 0.0077 19.15 0.0023 20.12 0.0017 21.24 0.0113 22.26 0.0126 23.30 0.0093 24.36 0.0007 25.43 0.0007 26.47 0.0009 27.55 0.0013 28.59 0.0025 29.61 0.0010 30.77 0.0021 31.86 0.0023 32.96 0.0003 34.03 0.0007 35.06 0.0005 36.20 0.0006 37.34 0.0006 38.36 0.0009 39.60 0.0016 40.69 0.0005 41.77 0.0002 42.92 0.0002 44.02 0.0003 45.24 0.0006 46.33 0.0004 47.50 0.0007 48.71 0.0007 49.87 0.0002 51.27 0.0002 53.42 0.0003 55.88 0.0003 57.10 0.0004 58.34 0.0002 59.86 0.0003 61.13 0.0003 67.18 0.0001 68.50 0.0001 71.17 0.0001 83.91 0.0001 90.55 0.0001 ) #( 0.98 0.0099 2.00 0.0181 2.99 0.0353 3.98 0.0285 4.97 0.0514 5.96 0.0402 6.96 0.0015 7.98 0.0012 8.98 0.0175 9.98 0.0264 10.98 0.0392 11.98 0.0236 13.00 0.0153 14.04 0.0049 15.00 0.0089 16.01 0.0001 17.03 0.0106 18.03 0.0028 19.05 0.0024 20.08 0.0040 21.11 0.0103 22.12 0.0104 23.20 0.0017 24.19 0.0008 25.20 0.0007 26.24 0.0011 27.36 0.0009 27.97 0.0030 29.40 0.0044 30.37 0.0019 31.59 0.0017 32.65 0.0008 33.59 0.0005 34.79 0.0009 35.75 0.0027 36.88 0.0035 37.93 0.0039 39.00 0.0031 40.08 0.0025 41.16 0.0010 43.25 0.0004 44.52 0.0012 45.62 0.0023 45.85 0.0012 47.00 0.0006 47.87 0.0008 48.99 0.0003 50.48 0.0003 51.62 0.0001 52.43 0.0001 53.56 0.0002 54.76 0.0002 56.04 0.0002 56.68 0.0006 57.10 0.0003 58.28 0.0005 59.47 0.0003 59.96 0.0002 60.67 0.0001 63.08 0.0002 64.29 0.0002 66.72 0.0001 67.97 0.0001 68.65 0.0001 70.43 0.0001 79.38 0.0001 80.39 0.0001 82.39 0.0001 ) #( 1.00 0.0765 1.99 0.0151 2.99 0.0500 3.99 0.0197 5.00 0.0260 6.00 0.0145 6.98 0.0128 7.97 0.0004 8.98 0.0158 9.99 0.0265 11.02 0.0290 12.02 0.0053 13.03 0.0242 14.03 0.0103 15.06 0.0054 16.04 0.0006 17.08 0.0008 18.10 0.0058 19.16 0.0011 20.16 0.0055 21.18 0.0040 22.20 0.0019 23.22 0.0014 24.05 0.0005 25.31 0.0019 26.38 0.0018 27.44 0.0022 28.45 0.0024 29.57 0.0073 30.58 0.0032 31.66 0.0071 32.73 0.0015 33.85 0.0005 34.96 0.0003 36.00 0.0020 37.11 0.0018 38.18 0.0055 39.23 0.0006 40.33 0.0004 41.52 0.0003 43.41 0.0028 45.05 0.0003 45.99 0.0002 47.07 0.0003 48.52 0.0002 49.48 0.0003 50.63 0.0003 51.81 0.0002 54.05 0.0002 55.24 0.0001 56.62 0.0001 57.81 0.0004 59.16 0.0013 60.23 0.0003 66.44 0.0001 68.99 0.0004 75.49 0.0001 87.56 0.0004 ) #( 0.98 0.0629 1.99 0.0232 2.98 0.0217 4.00 0.0396 4.98 0.0171 5.97 0.0098 6.99 0.0167 7.99 0.0003 8.98 0.0192 9.98 0.0266 10.99 0.0256 12.01 0.0061 13.02 0.0135 14.02 0.0062 15.05 0.0158 16.06 0.0018 17.08 0.0101 18.09 0.0053 19.11 0.0074 20.13 0.0020 21.17 0.0052 22.22 0.0077 23.24 0.0035 24.00 0.0009 25.32 0.0016 26.40 0.0022 27.43 0.0005 28.55 0.0026 29.60 0.0026 30.65 0.0010 31.67 0.0019 32.77 0.0008 33.81 0.0003 34.91 0.0003 36.01 0.0005 37.11 0.0010 38.20 0.0014 39.29 0.0039 40.43 0.0012 41.50 0.0006 43.38 0.0017 43.75 0.0002 44.94 0.0005 46.13 0.0002 47.11 0.0003 48.28 0.0005 48.42 0.0005 49.44 0.0003 50.76 0.0004 51.93 0.0002 54.15 0.0003 55.31 0.0005 55.50 0.0003 56.98 0.0003 57.90 0.0004 60.33 0.0002 61.39 0.0001 61.59 0.0001 65.09 0.0002 66.34 0.0001 68.85 0.0001 70.42 0.0002 71.72 0.0001 73.05 0.0003 79.65 0.0001 85.28 0.0002 93.52 0.0001 ) #( 1.02 0.0185 1.99 0.0525 2.98 0.0613 3.99 0.0415 4.98 0.0109 5.97 0.0248 6.99 0.0102 7.98 0.0005 8.98 0.0124 9.99 0.0103 10.99 0.0124 12.00 0.0016 13.01 0.0029 14.03 0.0211 15.04 0.0128 16.07 0.0021 17.09 0.0009 18.09 0.0043 19.14 0.0022 20.13 0.0016 21.20 0.0045 22.21 0.0088 23.26 0.0046 24.29 0.0013 25.35 0.0009 26.39 0.0028 27.49 0.0009 28.51 0.0006 29.58 0.0012 30.70 0.0010 31.74 0.0019 32.75 0.0002 33.85 0.0001 34.95 0.0005 36.02 0.0003 37.16 0.0009 38.25 0.0018 39.35 0.0008 40.54 0.0004 41.61 0.0002 43.40 0.0004 43.74 0.0003 45.05 0.0001 46.11 0.0003 47.40 0.0002 48.36 0.0004 49.55 0.0004 50.72 0.0002 52.00 0.0001 55.58 0.0002 57.02 0.0001 57.98 0.0002 59.13 0.0003 61.56 0.0001 66.56 0.0001 87.65 0.0002 ) #( 1.00 0.0473 1.99 0.0506 2.99 0.0982 3.99 0.0654 5.00 0.0196 5.99 0.0094 6.99 0.0118 7.93 0.0001 8.99 0.0057 10.01 0.0285 11.01 0.0142 12.03 0.0032 13.03 0.0056 14.06 0.0064 15.06 0.0059 16.11 0.0005 17.09 0.0033 18.14 0.0027 19.15 0.0014 20.17 0.0010 21.21 0.0059 22.26 0.0043 23.31 0.0031 24.31 0.0018 25.33 0.0009 26.41 0.0005 27.47 0.0015 28.53 0.0015 29.58 0.0041 30.65 0.0025 31.73 0.0011 32.83 0.0010 34.98 0.0003 36.07 0.0009 37.23 0.0001 38.26 0.0020 39.41 0.0014 40.53 0.0005 41.40 0.0003 42.80 0.0002 43.48 0.0028 43.93 0.0001 45.03 0.0003 46.18 0.0007 47.41 0.0001 48.57 0.0002 49.67 0.0001 50.83 0.0002 54.39 0.0001 55.58 0.0002 57.97 0.0005 58.11 0.0002 59.21 0.0001 60.42 0.0002 61.66 0.0001 ) #( 1.00 0.0503 2.00 0.0963 2.99 0.1304 3.99 0.0218 4.98 0.0041 5.98 0.0292 6.98 0.0482 7.99 0.0005 8.99 0.0280 10.00 0.0237 11.00 0.0152 12.02 0.0036 12.95 0.0022 14.06 0.0111 15.07 0.0196 16.08 0.0016 17.11 0.0044 18.13 0.0073 19.17 0.0055 20.19 0.0028 21.20 0.0012 22.27 0.0068 23.30 0.0036 24.35 0.0012 25.35 0.0002 26.46 0.0005 27.47 0.0005 28.59 0.0009 29.65 0.0021 30.70 0.0020 31.78 0.0012 32.89 0.0010 35.06 0.0005 36.16 0.0008 37.27 0.0010 38.36 0.0010 39.47 0.0014 40.58 0.0004 41.43 0.0007 41.82 0.0003 43.48 0.0008 44.53 0.0001 45.25 0.0003 46.43 0.0002 47.46 0.0002 48.76 0.0005 49.95 0.0004 50.96 0.0002 51.12 0.0002 52.33 0.0001 54.75 0.0001 55.75 0.0002 56.90 0.0002 58.17 0.0002 59.40 0.0004 60.62 0.0002 65.65 0.0001 66.91 0.0002 69.91 0.0001 71.25 0.0002 ) #( 1.00 0.1243 1.98 0.1611 3.00 0.0698 3.98 0.0390 5.00 0.0138 5.99 0.0154 7.01 0.0287 8.01 0.0014 9.01 0.0049 10.00 0.0144 11.01 0.0055 12.05 0.0052 13.01 0.0011 14.05 0.0118 15.07 0.0154 16.12 0.0028 17.14 0.0061 18.25 0.0007 19.22 0.0020 20.24 0.0011 21.27 0.0029 22.30 0.0046 23.34 0.0049 24.35 0.0004 25.45 0.0003 26.47 0.0007 27.59 0.0008 28.16 0.0009 29.12 0.0002 29.81 0.0006 30.81 0.0009 31.95 0.0004 33.00 0.0011 34.12 0.0005 35.18 0.0003 36.30 0.0008 37.38 0.0003 38.55 0.0003 39.64 0.0006 40.77 0.0007 41.52 0.0006 41.89 0.0006 43.04 0.0011 43.60 0.0009 44.31 0.0002 45.68 0.0002 46.56 0.0003 47.60 0.0001 48.83 0.0006 50.01 0.0003 51.27 0.0003 56.04 0.0005 57.21 0.0003 58.56 0.0004 59.83 0.0003 61.05 0.0001 62.20 0.0001 67.37 0.0002 76.53 0.0001 ) #( 0.99 0.0222 1.99 0.0678 2.99 0.0683 4.00 0.0191 5.00 0.0119 6.01 0.0232 6.98 0.0336 7.99 0.0082 9.01 0.0201 10.01 0.0189 11.01 0.0041 12.01 0.0053 13.05 0.0154 14.04 0.0159 15.06 0.0092 16.11 0.0038 17.12 0.0014 18.15 0.0091 19.16 0.0006 20.30 0.0012 21.25 0.0061 22.28 0.0099 23.34 0.0028 24.38 0.0012 25.43 0.0016 26.49 0.0048 27.55 0.0025 28.62 0.0015 29.71 0.0032 30.78 0.0077 31.88 0.0011 32.97 0.0007 34.08 0.0006 35.16 0.0008 36.28 0.0004 37.41 0.0006 38.54 0.0005 39.62 0.0002 40.80 0.0003 41.93 0.0001 43.06 0.0002 44.21 0.0003 45.38 0.0002 46.54 0.0007 47.78 0.0003 48.95 0.0004 50.10 0.0003 51.37 0.0002 53.79 0.0003 56.20 0.0001 58.71 0.0002 66.47 0.0003 ) #( 1.01 0.0241 1.99 0.1011 2.98 0.0938 3.98 0.0081 4.99 0.0062 5.99 0.0291 6.99 0.0676 7.59 0.0004 8.98 0.0127 9.99 0.0112 10.99 0.0142 12.00 0.0029 13.02 0.0071 14.02 0.0184 15.03 0.0064 16.07 0.0010 17.09 0.0011 18.11 0.0010 19.15 0.0060 20.19 0.0019 21.24 0.0025 22.29 0.0013 23.31 0.0050 25.41 0.0030 26.50 0.0018 27.53 0.0006 28.63 0.0012 29.66 0.0013 30.77 0.0020 31.84 0.0006 34.04 0.0001 35.14 0.0001 36.32 0.0004 37.41 0.0007 38.53 0.0007 39.67 0.0009 40.85 0.0003 45.49 0.0002 46.65 0.0001 47.81 0.0004 49.01 0.0002 53.91 0.0002 55.14 0.0002 57.69 0.0002 ) #( 1.00 0.0326 2.00 0.1066 2.99 0.1015 4.00 0.0210 4.97 0.0170 5.99 0.0813 6.98 0.0820 7.96 0.0011 8.99 0.0248 10.03 0.0107 11.01 0.0126 12.01 0.0027 13.01 0.0233 14.04 0.0151 15.05 0.0071 16.04 0.0002 17.10 0.0061 18.12 0.0059 19.15 0.0087 20.23 0.0005 21.25 0.0040 22.30 0.0032 23.35 0.0004 24.40 0.0001 25.45 0.0030 26.54 0.0022 27.60 0.0003 28.70 0.0009 29.80 0.0029 30.85 0.0006 31.97 0.0006 34.19 0.0004 35.30 0.0003 36.43 0.0007 37.56 0.0005 38.68 0.0019 39.88 0.0013 41.00 0.0003 43.35 0.0003 44.51 0.0002 45.68 0.0006 46.93 0.0010 48.11 0.0006 49.29 0.0003 55.58 0.0002 ) #( 0.98 0.0113 1.99 0.0967 3.00 0.0719 3.98 0.0345 4.98 0.0121 6.00 0.0621 7.00 0.0137 7.98 0.0006 9.01 0.0314 10.01 0.0171 11.02 0.0060 12.03 0.0024 13.05 0.0077 14.07 0.0040 15.12 0.0032 16.13 0.0004 17.15 0.0011 18.20 0.0028 19.18 0.0003 20.26 0.0003 21.31 0.0025 22.35 0.0021 23.39 0.0005 25.55 0.0002 26.62 0.0014 27.70 0.0003 28.78 0.0005 29.90 0.0030 31.01 0.0011 32.12 0.0005 34.31 0.0001 35.50 0.0002 36.62 0.0002 37.76 0.0005 38.85 0.0002 40.09 0.0004 43.60 0.0001 44.73 0.0002 46.02 0.0002 47.25 0.0004 48.44 0.0004 ) #( 0.99 0.0156 1.98 0.0846 2.98 0.0178 3.98 0.0367 4.98 0.0448 5.98 0.0113 6.99 0.0189 8.00 0.0011 9.01 0.0247 10.02 0.0089 11.01 0.0184 12.03 0.0105 13.00 0.0039 14.07 0.0116 15.09 0.0078 16.13 0.0008 17.14 0.0064 18.19 0.0029 19.22 0.0028 20.25 0.0017 21.32 0.0043 22.37 0.0055 23.42 0.0034 24.48 0.0004 25.54 0.0002 26.61 0.0017 27.70 0.0011 28.80 0.0002 29.89 0.0019 30.97 0.0028 32.09 0.0007 34.30 0.0002 35.44 0.0003 36.55 0.0001 37.69 0.0004 38.93 0.0002 40.05 0.0005 41.20 0.0005 42.37 0.0002 43.54 0.0003 44.73 0.0001 45.95 0.0002 47.16 0.0001 48.43 0.0005 49.65 0.0004 55.90 0.0002 59.81 0.0004 ) #( 1.01 0.0280 2.00 0.0708 2.99 0.0182 3.99 0.0248 4.98 0.0245 5.98 0.0279 6.98 0.0437 7.99 0.0065 8.99 0.0299 10.00 0.0073 10.99 0.0011 12.03 0.0122 13.03 0.0028 14.08 0.0044 15.11 0.0097 16.15 0.0010 17.17 0.0025 18.19 0.0017 19.24 0.0008 20.28 0.0040 21.32 0.0024 22.38 0.0008 23.46 0.0032 24.52 0.0010 25.59 0.0008 26.68 0.0009 27.76 0.0012 28.88 0.0003 29.95 0.0005 31.05 0.0017 32.14 0.0002 33.29 0.0003 37.88 0.0002 39.03 0.0002 40.19 0.0004 41.37 0.0003 43.74 0.0002 46.20 0.0001 48.68 0.0001 49.93 0.0001 51.19 0.0002 ) #( 1.00 0.0225 1.99 0.0921 2.98 0.0933 3.99 0.0365 4.99 0.0100 5.98 0.0213 6.98 0.0049 7.98 0.0041 8.98 0.0090 9.99 0.0068 11.01 0.0040 12.03 0.0086 13.02 0.0015 14.04 0.0071 15.09 0.0082 16.14 0.0011 17.15 0.0014 18.18 0.0010 19.26 0.0013 20.26 0.0005 21.33 0.0006 22.36 0.0011 23.46 0.0016 24.52 0.0004 25.59 0.0002 26.70 0.0006 27.78 0.0007 28.87 0.0002 30.03 0.0008 31.14 0.0010 32.24 0.0006 33.37 0.0002 35.67 0.0003 37.99 0.0004 39.17 0.0004 40.35 0.0005 41.53 0.0001 46.42 0.0001 ) #( 1.00 0.0465 1.99 0.0976 2.98 0.0678 4.00 0.0727 4.99 0.0305 5.98 0.0210 6.98 0.0227 8.00 0.0085 9.01 0.0183 10.02 0.0258 11.05 0.0003 12.06 0.0061 13.05 0.0021 14.10 0.0089 15.12 0.0077 16.16 0.0016 17.21 0.0061 18.23 0.0011 19.29 0.0031 20.36 0.0031 21.41 0.0007 22.48 0.0013 23.55 0.0020 24.64 0.0004 25.74 0.0005 26.81 0.0006 27.95 0.0006 29.03 0.0001 30.22 0.0010 31.30 0.0004 32.48 0.0001 33.60 0.0002 38.30 0.0003 ) #( 1.00 0.0674 1.99 0.0841 2.98 0.0920 3.99 0.0328 4.99 0.0368 5.98 0.0206 6.99 0.0246 8.01 0.0048 9.01 0.0218 10.03 0.0155 11.05 0.0048 12.06 0.0077 13.00 0.0020 14.10 0.0083 15.15 0.0084 16.18 0.0015 17.22 0.0039 18.27 0.0032 19.34 0.0026 20.40 0.0012 21.47 0.0009 22.54 0.0008 23.62 0.0016 24.71 0.0005 25.82 0.0004 26.91 0.0002 28.03 0.0008 29.17 0.0002 30.32 0.0028 31.45 0.0004 32.61 0.0005 33.77 0.0001 36.14 0.0003 37.32 0.0002 38.54 0.0005 39.75 0.0002 42.23 0.0002 48.65 0.0001 ) #( 1.01 0.0423 1.99 0.0240 2.98 0.0517 4.00 0.0493 5.00 0.0324 6.00 0.0094 6.99 0.0449 7.99 0.0050 9.00 0.0197 10.03 0.0132 11.03 0.0009 12.07 0.0017 13.08 0.0023 14.12 0.0094 15.16 0.0071 16.21 0.0020 17.25 0.0005 18.30 0.0027 19.04 0.0004 20.43 0.0022 21.51 0.0002 22.59 0.0006 23.72 0.0018 24.80 0.0002 25.88 0.0002 27.03 0.0002 28.09 0.0006 29.31 0.0002 30.46 0.0004 31.61 0.0007 32.78 0.0005 33.95 0.0001 36.34 0.0002 37.56 0.0001 38.80 0.0001 40.02 0.0001 44.14 0.0001 ) #( 1.00 0.0669 1.99 0.0909 2.99 0.0410 3.98 0.0292 4.98 0.0259 5.98 0.0148 6.98 0.0319 7.99 0.0076 9.01 0.0056 10.02 0.0206 11.04 0.0032 12.05 0.0085 13.08 0.0040 14.12 0.0037 15.16 0.0030 16.20 0.0013 17.24 0.0021 18.30 0.0010 19.36 0.0015 20.44 0.0013 21.50 0.0009 22.60 0.0015 23.69 0.0014 24.80 0.0006 25.87 0.0002 27.02 0.0006 28.12 0.0002 29.28 0.0003 30.43 0.0002 31.59 0.0007 32.79 0.0001 35.14 0.0001 37.57 0.0001 40.03 0.0002 41.28 0.0004 44.10 0.0001 ) #( 0.99 0.0421 1.99 0.1541 2.98 0.0596 3.98 0.0309 4.98 0.0301 5.99 0.0103 7.00 0.0240 8.01 0.0073 9.01 0.0222 10.04 0.0140 11.05 0.0033 12.08 0.0045 13.13 0.0009 14.13 0.0015 15.21 0.0026 16.24 0.0003 17.30 0.0004 18.35 0.0010 19.39 0.0003 20.50 0.0015 21.57 0.0003 22.68 0.0011 23.80 0.0005 24.90 0.0008 26.02 0.0002 27.16 0.0001 28.30 0.0006 29.48 0.0002 31.81 0.0005 33.00 0.0003 34.21 0.0001 37.89 0.0001 ) #( 0.99 0.0389 2.00 0.2095 3.00 0.0835 3.99 0.0289 5.00 0.0578 5.99 0.0363 7.01 0.0387 8.01 0.0056 9.04 0.0173 10.05 0.0175 11.08 0.0053 12.10 0.0056 13.15 0.0064 14.19 0.0036 15.22 0.0019 16.29 0.0010 17.36 0.0017 18.43 0.0018 19.51 0.0004 20.60 0.0011 21.70 0.0003 22.82 0.0003 23.95 0.0001 25.05 0.0004 26.17 0.0001 28.50 0.0003 29.68 0.0001 32.07 0.0003 33.28 0.0004 34.52 0.0001 ) #( 1.00 0.1238 1.99 0.2270 3.00 0.0102 3.99 0.0181 4.98 0.0415 6.00 0.0165 7.01 0.0314 8.02 0.0148 9.04 0.0203 10.05 0.0088 11.07 0.0062 12.11 0.0070 13.14 0.0054 14.19 0.0028 15.24 0.0044 16.30 0.0029 17.38 0.0009 18.45 0.0026 19.56 0.0003 20.65 0.0025 21.74 0.0014 22.87 0.0013 23.99 0.0007 25.15 0.0002 27.46 0.0004 28.39 0.0006 28.65 0.0004 29.85 0.0001 31.05 0.0002 32.27 0.0003 33.52 0.0002 34.76 0.0003 ) #( 1.00 0.1054 2.00 0.2598 2.99 0.0369 3.98 0.0523 4.99 0.0020 5.99 0.0051 7.00 0.0268 8.01 0.0027 9.04 0.0029 10.05 0.0081 11.08 0.0047 12.12 0.0051 13.16 0.0091 14.19 0.0015 15.27 0.0030 16.34 0.0017 17.42 0.0006 18.51 0.0003 19.61 0.0007 20.72 0.0003 21.84 0.0001 22.99 0.0010 24.13 0.0001 28.44 0.0001 30.09 0.0001 ) #( 0.99 0.0919 2.00 0.0418 2.99 0.0498 3.99 0.0135 4.99 0.0026 6.00 0.0155 7.01 0.0340 8.02 0.0033 9.04 0.0218 10.08 0.0084 11.11 0.0057 12.15 0.0051 13.21 0.0043 14.25 0.0015 15.31 0.0023 16.40 0.0008 17.48 0.0004 18.59 0.0016 19.71 0.0010 20.84 0.0018 21.98 0.0002 23.11 0.0013 24.26 0.0003 26.67 0.0002 29.12 0.0002 30.37 0.0002 31.62 0.0003 32.92 0.0001 ) #( 0.99 0.1174 1.99 0.1126 2.99 0.0370 3.99 0.0159 5.01 0.0472 6.01 0.0091 7.03 0.0211 8.05 0.0015 9.07 0.0098 10.11 0.0038 11.15 0.0042 12.20 0.0018 13.24 0.0041 14.32 0.0033 15.41 0.0052 16.49 0.0001 17.61 0.0004 18.71 0.0004 19.84 0.0004 20.99 0.0002 22.14 0.0006 23.31 0.0006 24.50 0.0004 25.70 0.0002 28.09 0.0002 28.66 0.0002 32.00 0.0001 ) #( 1.00 0.1085 2.00 0.1400 2.99 0.0173 3.99 0.0229 5.00 0.0272 6.02 0.0077 7.03 0.0069 8.04 0.0017 9.08 0.0045 10.10 0.0030 11.15 0.0040 12.20 0.0007 13.25 0.0019 14.32 0.0008 15.42 0.0024 16.50 0.0002 17.59 0.0005 18.71 0.0003 19.83 0.0002 20.98 0.0005 23.29 0.0008 ) #( 1.00 0.0985 2.00 0.1440 2.99 0.0364 3.99 0.0425 5.00 0.0190 6.01 0.0089 7.03 0.0278 8.04 0.0006 9.07 0.0083 10.10 0.0021 11.14 0.0050 12.18 0.0005 13.26 0.0036 14.33 0.0005 15.41 0.0026 17.62 0.0004 18.75 0.0004 19.89 0.0003 21.04 0.0012 22.21 0.0002 23.38 0.0004 27.04 0.0001 ) #( 0.99 0.1273 2.00 0.1311 2.99 0.0120 4.00 0.0099 5.00 0.0235 6.02 0.0068 7.03 0.0162 8.06 0.0009 9.08 0.0083 10.12 0.0014 11.17 0.0050 12.24 0.0010 13.29 0.0013 14.39 0.0022 15.48 0.0011 16.59 0.0002 17.70 0.0003 18.84 0.0010 20.00 0.0003 21.17 0.0003 23.56 0.0004 28.79 0.0003 ) #( 1.00 0.1018 2.00 0.1486 3.00 0.0165 4.00 0.0186 5.01 0.0194 6.02 0.0045 7.04 0.0083 8.06 0.0012 9.10 0.0066 10.15 0.0009 11.19 0.0008 12.26 0.0011 13.34 0.0028 14.45 0.0006 15.53 0.0009 16.66 0.0002 17.79 0.0006 18.94 0.0005 20.11 0.0003 21.29 0.0005 22.49 0.0003 23.73 0.0005 26.22 0.0001 27.52 0.0001 28.88 0.0002 ) #( 1.00 0.1889 1.99 0.1822 3.00 0.0363 4.00 0.0047 5.01 0.0202 6.03 0.0053 7.05 0.0114 8.01 0.0002 9.13 0.0048 10.17 0.0010 11.23 0.0033 12.30 0.0010 13.38 0.0006 14.50 0.0002 15.62 0.0010 20.27 0.0001 21.47 0.0001 ) #( 1.00 0.0522 1.99 0.0763 2.99 0.0404 4.00 0.0139 5.01 0.0185 6.01 0.0021 7.06 0.0045 8.09 0.0002 9.11 0.0003 10.17 0.0006 11.25 0.0004 12.32 0.0005 13.40 0.0003 14.53 0.0003 15.65 0.0007 16.80 0.0001 17.95 0.0002 19.14 0.0006 20.34 0.0002 21.56 0.0003 ) #( 0.99 0.1821 1.99 0.0773 3.00 0.0125 4.01 0.0065 5.01 0.0202 6.03 0.0071 7.05 0.0090 8.08 0.0006 9.13 0.0008 10.18 0.0013 11.25 0.0010 12.33 0.0012 13.42 0.0006 14.54 0.0005 15.65 0.0004 17.97 0.0002 19.15 0.0001 ) #( 1.00 0.1868 2.00 0.0951 3.00 0.0147 4.01 0.0134 5.02 0.0184 6.04 0.0132 7.06 0.0011 8.11 0.0008 9.15 0.0010 10.22 0.0012 11.30 0.0011 12.40 0.0003 13.11 0.0004 13.49 0.0002 14.62 0.0003 15.77 0.0001 ) #( 1.00 0.1933 2.00 0.0714 3.00 0.0373 4.00 0.0108 5.02 0.0094 6.02 0.0010 7.07 0.0022 8.11 0.0002 9.16 0.0065 10.23 0.0015 11.31 0.0023 12.40 0.0003 13.53 0.0014 14.66 0.0002 15.81 0.0011 18.20 0.0002 19.41 0.0001 ) #( 0.99 0.2113 1.99 0.0877 3.00 0.0492 4.01 0.0094 5.02 0.0144 6.04 0.0103 7.07 0.0117 8.12 0.0006 9.19 0.0019 10.25 0.0007 11.35 0.0017 12.45 0.0010 13.58 0.0003 14.74 0.0003 15.91 0.0003 19.57 0.0002 ) #( 0.99 0.2455 1.99 0.0161 3.00 0.0215 4.01 0.0036 5.03 0.0049 6.04 0.0012 7.09 0.0036 8.14 0.0011 9.21 0.0009 10.30 0.0001 11.40 0.0012 12.50 0.0001 13.66 0.0005 14.84 0.0001 ) #( 1.00 0.1132 2.00 0.0252 3.00 0.0292 4.01 0.0136 5.03 0.0045 6.06 0.0022 7.11 0.0101 8.17 0.0004 9.23 0.0010 10.33 0.0012 11.44 0.0013 12.58 0.0011 13.75 0.0002 14.93 0.0005 16.14 0.0002 ) #( 1.00 0.1655 2.00 0.0445 3.00 0.0120 4.00 0.0038 5.02 0.0015 6.07 0.0038 7.11 0.0003 8.19 0.0002 9.25 0.0010 10.36 0.0011 11.48 0.0005 12.63 0.0002 13.79 0.0003 16.24 0.0002 ) #( 0.99 0.3637 1.99 0.0259 3.01 0.0038 4.01 0.0057 5.03 0.0040 6.07 0.0067 7.12 0.0014 8.19 0.0004 9.27 0.0003 10.38 0.0002 12.67 0.0001 ) #( 1.00 0.1193 2.00 0.0230 3.00 0.0104 4.01 0.0084 5.04 0.0047 6.08 0.0035 7.13 0.0041 8.20 0.0002 9.29 0.0005 10.40 0.0005 11.53 0.0003 12.70 0.0002 13.91 0.0002 ) #( 1.00 0.0752 2.00 0.0497 3.00 0.0074 4.02 0.0076 5.05 0.0053 6.09 0.0043 7.15 0.0024 8.22 0.0001 9.32 0.0006 10.45 0.0002 11.58 0.0001 12.78 0.0001 15.22 0.0001 ) #( 1.00 0.2388 2.00 0.0629 3.01 0.0159 4.04 0.0063 5.07 0.0051 6.12 0.0045 7.19 0.0026 8.29 0.0015 9.43 0.0001 11.75 0.0002 ) #( 1.00 0.1919 2.01 0.0116 3.01 0.0031 4.03 0.0090 5.07 0.0061 6.13 0.0036 7.19 0.0013 8.30 0.0016 9.13 0.0001 10.59 0.0002 11.78 0.0002 ) #( 1.00 0.1296 2.00 0.0135 3.01 0.0041 4.04 0.0045 5.09 0.0028 6.14 0.0046 7.23 0.0007 8.32 0.0007 9.50 0.0001 ) #( 1.00 0.0692 2.00 0.0209 3.02 0.0025 4.05 0.0030 5.09 0.0047 6.17 0.0022 7.25 0.0015 8.36 0.0015 9.53 0.0010 10.69 0.0001 13.40 0.0001 ) #( 1.00 0.1715 2.00 0.0142 3.01 0.0024 4.03 0.0015 5.07 0.0017 6.13 0.0018 7.22 0.0009 8.33 0.0014 9.51 0.0007 10.69 0.0002 ) #( 1.00 0.1555 2.01 0.0148 3.02 0.0007 4.06 0.0006 5.10 0.0005 6.16 0.0008 7.26 0.0009 8.39 0.0008 9.58 0.0002 ) #( 1.00 0.1357 2.00 0.0116 3.02 0.0026 4.04 0.0009 5.09 0.0004 6.17 0.0005 7.27 0.0002 8.40 0.0001 ) #( 1.00 0.2185 2.01 0.0087 3.03 0.0018 4.06 0.0025 5.11 0.0020 6.20 0.0012 7.32 0.0005 8.46 0.0001 9.66 0.0003 ) #( 1.00 0.2735 2.00 0.0038 3.02 0.0008 4.06 0.0012 5.12 0.0008 6.22 0.0011 7.35 0.0003 8.50 0.0002 ) #( 1.00 0.1441 1.99 0.0062 3.01 0.0023 4.05 0.0011 5.11 0.0012 6.20 0.0003 7.33 0.0004 8.50 0.0001 ) #( 1.00 0.0726 2.01 0.0293 3.03 0.0022 5.14 0.0005 6.26 0.0011 7.41 0.0002 8.63 0.0002 ) #( 1.00 0.0516 2.00 0.0104 3.02 0.0029 5.15 0.0002 6.27 0.0001 ) #( 1.00 0.0329 2.00 0.0033 3.03 0.0013 4.10 0.0005 5.19 0.0004 6.32 0.0002 ) #( 1.00 0.0179 1.99 0.0012 3.04 0.0005 4.10 0.0017 5.20 0.0005 6.35 0.0001 ) #( 1.00 0.0334 2.01 0.0033 3.04 0.0011 4.13 0.0003 5.22 0.0003 ) #( 0.99 0.0161 2.01 0.0100 3.04 0.0020 4.13 0.0003 ) #( 1.00 0.0475 1.99 0.0045 3.03 0.0035 4.12 0.0011 ) #( 1.00 0.0593 2.00 0.0014 4.17 0.0002 ) #( 1.00 0.0249 2.01 0.0016 ) #( 1.00 0.0242 2.00 0.0038 4.19 0.0002 ) #( 1.00 0.0170 2.02 0.0030 ) #( 1.00 0.0381 2.00 0.0017 3.09 0.0002 ) #( 1.00 0.0141 2.03 0.0005 3.11 0.0003 4.26 0.0001 ) #( 1.00 0.0122 2.03 0.0024 ) #( 1.00 0.0107 2.07 0.0007 3.12 0.0004 ) #( 1.00 0.0250 2.02 0.0026 3.15 0.0002 ) #( 1.01 0.0092 ) #( 1.01 0.0102 2.09 0.0005 ) #( 1.00 0.0080 2.00 0.0005 3.19 0.0001 ) #( 1.01 0.0298 2.01 0.0005 ) ) constant piano-spectra 0.04 value *clm-piano-attack-duration* 0.2 value *clm-piano-realease-duration* -10 value *clm-db-drop-per-second* \ This thing sounds pretty good down low, below middle c or so. \ Unfortunately, there are some tens of partials down there and we're \ using exponential envelopes. You're going to wait for a long long \ time just to hear a single low note. The high notes sound pretty \ rotten--they just don't sparkle; I have a feeling that this is due \ to the low amplitude of the original data, and the lack of \ mechanical noise. \ \ The only thing you can do to alter the sound of a piano note is to \ set the pfreq parameter. Pfreq is used to look up the partials. By \ default, it's set to the requested frequency. Setting it to a \ neighboring freq is useful when you're repeating notes. Note that \ there's no nyquist detection; a high freq with a low pfreq, will \ give you fold over (hmmm...maybe I can get those high notes to \ sparkle after all). instrument: lbj-piano <{ start dur freq amp :key degree 45.0 distance 1.0 reverb-amount 0.0 -- }> 12.0 freq 32.703 f/ flog 2.0 flog f/ f* f>s { idx } piano-spectra idx array-ref normalize-partials { parts } dur *clm-piano-attack-duration* *clm-piano-realease-duration* f+ f+ to dur dur *clm-piano-realease-duration* f- { env1dur } env1dur mus-srate f* fround->s { env1samples } #( 0.0 0.0 *clm-piano-attack-duration* 100.0 f* env1dur f/ 4.0 f/ 1.0 *clm-piano-attack-duration* 100.0 f* env1dur f/ 1.0 100.0 *clm-db-drop-per-second* env1dur f* db->linear ) { ampfun1 } :envelope ampfun1 :scaler amp :duration env1dur :base 10000.0 make-env { ampenv1 } :envelope #( 0 1 100 0 ) :scaler amp ampfun1 -1 array-ref f* :duration env1dur :base 1.0 make-env { ampenv2 } parts length 2/ 0.0 make-vct { alist } parts length 2/ make-array map! alist i parts i 2* 1+ vct-ref vct-set! drop :frequency parts i 2* vct-ref freq f* make-oscil end-map { oscils } start dur #{ :degree degree :distance distance :reverb reverb-amount } run-instrument 0.0 ( sum ) oscils each ( os ) 0.0 0.0 oscil alist i vct-ref f* f+ ( sum += ... ) end-each ( sum ) i env1samples > if ampenv2 else ampenv1 then env f* end-run ;instrument : lbj-piano-test <{ :optional start 0.0 dur 1.0 -- }> start now! now@ dur 440 0.5 lbj-piano dur 0.24 f+ 0.2 f+ step ; \ RESFLT \ clm/resflt.ins instrument: resflt <{ start dur driver ranfreq noiamp noifun cosamp cosfreq1 cosfreq0 cosnum ampcosfun freqcosfun freq1 r1 g1 freq2 r2 g2 freq3 r3 g3 :key degree 0.0 distance 1.0 reverb-amount 0.005 -- }> doc" From clm/resflt.ins\n\ 0 1 #f 0 0 #f 0.1 200 230 10 '( 0 0 50 1 100 0 ) '( 0 0 100 1 )\n\ 500 0.995 0.1 1000 0.995 0.1 2000 0.995 0.1 :degree\n\ 90.0 random <'> resflt with-sound\n\ 0 1 #t 10000 0.01 '( 0 0 50 1 100 0 ) 0 0 0 0 #f #f\n\ 500 0.995 0.1 1000 0.995 0.1 2000 0.995 0.1 :degree\n\ 90.0 random <'> resflt with-sound." :radius r1 :frequency freq1 make-two-pole { f1 } :radius r2 :frequency freq2 make-two-pole { f2 } :radius r3 :frequency freq3 make-two-pole { f3 } driver if :envelope noifun :scaler noiamp :duration dur make-env { ampf } :frequency ranfreq make-rand { gen } start dur #{ :degree degree :distance distance :reverb reverb-amount } run-instrument gen 0.0 rand ampf env f* { input } f1 input g1 f* two-pole f2 input g2 f* two-pole f+ f3 input g3 f* two-pole f+ end-run else :envelope freqcosfun :scaler cosfreq1 cosfreq0 f- hz->radians :duration dur make-env { frqf } :envelope ampcosfun :scaler cosamp :duration dur make-env { ampf } :frequency cosfreq0 :n cosnum make-ncos { gen } start dur #{ :degree degree :distance distance :reverb reverb-amount } run-instrument gen frqf env ncos ampf env f* { input } f1 input g1 f* two-pole f2 input g2 f* two-pole f+ f3 input g3 f* two-pole f+ end-run then ;instrument : resflt-test <{ :optional start 0.0 dur 1.0 -- }> start now! now@ dur #f \ start dur driver 0 0 #f 0.1 \ ranfreq noiamp noifun cosamp 200 230 10 \ cosfreq1 cosfreq0 cosnum '( 0 0 50 1 100 0 ) \ ampcosfun '( 0 0 100 1 ) \ freqcosfun 500 0.995 0.1 1000 0.995 0.1 2000 0.995 0.1 :degree 90.0 random resflt dur 0.2 f+ step now@ dur #t \ start dur driver 10000 0.01 \ ranfreq noiamp '( 0 0 50 1 100 0 ) \ noifun 0 0 0 0 \ cosamp cosfreq1 cosfreq0 cosnum #f #f \ ampcosfun freqcosfun 500 0.995 0.1 1000 0.995 0.1 2000 0.995 0.1 :degree 90.0 random resflt dur 0.2 f+ step ; hide : scratch-input-cb { rd samp -- prc ; dir self -- r } 1 proc-create ( prc ) samp , rd , does> { dir self -- r } self @ { samp } self cell+ @ { rd } rd samp 0 file->sample \ (file->sample rd samp 0) dir self +! \ samp += dir ; set-current \ SCRATCH-INS instrument: scratch-ins <{ start file src-ratio turntable -- }> file find-file to file file unless 'file-not-found #( "%s: can't find %S" get-func-name file ) fth-throw then file mus-sound-duration { dur } file make-readin { f } turntable 0 object-ref seconds->samples { cur-samp } turntable 1 object-ref seconds->samples { turn-samp } :input f cur-samp scratch-input-cb :srate src-ratio make-src { rd } src-ratio f0> { forwards } forwards turn-samp cur-samp < && if rd src-ratio fnegate set-mus-increment drop then 1 { turn-i } 0 { turning } 0.0 0.0 { last-val1 last-val2 } start dur #{ :degree 90.0 random } run-instrument turn-i turntable length >= ?leave rd 0.0 undef src { val } turning unless forwards cur-samp turn-samp >= && if 1 else forwards false? cur-samp turn-samp <= && if -1 else turning then then to turning else last-val2 last-val1 f<= last-val1 val f>= && last-val2 last-val1 f>= last-val1 val f<= && || if turn-i 1+ to turn-i turn-i turntable length < if turntable turn-i object-ref seconds->samples to turn-samp forwards not to forwards rd rd mus-increment fnegate set-mus-increment drop then 0 to turning then then last-val1 to last-val2 val to last-val1 val end-run f mus-close drop ;instrument previous : scratch-test <{ :optional start 0.0 dur 1.0 -- }> start now! start "fyow.snd" dur 1.5 fmin #( 0 0.5 0.25 1 ) scratch-ins "fyow.snd" find-file mus-sound-duration 0.2 f+ step ; \ PINS \ \ spectral modeling (SMS) instrument: pins <{ start dur file amp :key transposition 1.0 time-scaler 1.0 fftsize 256 highest-bin 128 max-peaks 16 attack #f -- }> doc" start dur \"fyow.snd\" 1.0 :time-scaler 2.0 pins." file find-file to file file unless 'file-not-found #( "%s: can't find %S" get-func-name file ) fth-throw then file mus-sound-duration { fdur } dur time-scaler f/ { sdur } sdur fdur f> if 'forth-error #( "%s is %.3f secs long, \ but we'll need %.3f secs of data for this note" file fdur sdur ) fth-throw then file make-readin { fil } fftsize make-vct { fdr } fftsize make-vct { fdi } blackman2-window fftsize 0.0 0.0 make-fft-window { win } fftsize make-vct { fftamps } max-peaks 2* { max-oscils } max-oscils make-vct { current-peak-freqs } max-oscils make-vct { last-peak-freqs } max-oscils make-vct { current-peak-amps } max-oscils make-vct { last-peak-amps } max-peaks make-vct { peak-amps } max-peaks make-vct { peak-freqs } max-oscils make-array map! :frequency 0.0 make-oscil end-map { resynth-oscils } max-oscils make-vct { ampls } max-oscils make-vct { rates } max-oscils make-vct { freqs } max-oscils make-vct { sweeps } fftsize 4.0 f/ fround->s { hop } time-scaler hop f* fround->s { outhop } outhop 1/f { ifreq } ifreq hz->radians { ihifreq } mus-srate fftsize f/ { fft-mag } max-oscils { cur-oscils } attack if attack else 0 then { ramped } attack { splice-attack } attack if attack else 1 then { attack-size } 0.0 { ramp-ind } attack-size make-vct { ramped-attack } outhop { trigger } win fftsize 0.42323 f* 1/f vct-scale! drop 0 { filptr } start dur #{ :degree 90.0 random } run-instrument splice-attack if attack-size 1/f { ramp } fil filptr 0 file->sample amp f* ( outval ) filptr 1+ to filptr filptr attack-size > if 1 { mult } ramped-attack map! fil filptr i + 0 file->sample mult f* mult ramp f- to mult end-map drop #f to splice-attack then ( outval ) else trigger outhop >= if 0 { peaks } 0 to trigger fdr map! fil filptr i + 0 file->sample win i vct-ref f* end-map drop filptr fdr vct-length + to filptr fdi 0.0 vct-fill! drop filptr fftsize hop - - to filptr fdr fdi fftsize 1 mus-fft drop highest-bin 0 ?do fftamps i fdr i vct-ref dup f* fdi i vct-ref dup f* f+ fsqrt f2* vct-set! drop loop current-peak-freqs each { fv } current-peak-amps i vct-ref { av } last-peak-freqs i fv vct-set! drop last-peak-amps i av vct-set! drop current-peak-amps i 0.0 vct-set! drop end-each peak-amps 0.0 vct-fill! drop fftamps 0 vct-ref { ra } 0.0 0.0 { la ca } highest-bin 0 ?do ca to la ra to ca fftamps i vct-ref to ra ca 0.001 f> ca ra f> && ca la f> && if la flog10 ra flog10 f- f2/ la flog10 -2.0 ca flog10 f* f+ ra flog10 f+ f/ { offset } 10.0 ca flog10 0.25 la flog10 ra flog10 f- f* offset f* f- f** { amp-1 } fft-mag i offset -1.0 f+ f+ f* { freq } peaks max-peaks = if 0 { minp } peak-amps 0 vct-ref { minpeak } max-peaks 1 ?do peak-amps i vct-ref minpeak f< if i to minp peak-amps i vct-ref to minpeak then loop amp-1 minpeak f> if peak-freqs minp freq vct-set! drop peak-amps minp amp-1 vct-set! drop then else peak-freqs peaks freq vct-set! drop peak-amps peaks amp-1 vct-set! drop peaks 1+ to peaks then then loop peaks 0 ?do 0 { maxp } peak-amps 0 vct-ref ( maxpk ) max-peaks 1 ?do peak-amps i vct-ref over f> if i to maxp drop ( maxpk ) peak-amps i vct-ref ( maxpk ) then loop ( maxpk ) f0> if -1 { closestp } 10 { closestamp } peak-freqs maxp vct-ref { cur-freq } cur-freq 1/f { icf } max-peaks 0 ?do last-peak-amps i vct-ref f0> if icf last-peak-freqs i vct-ref cur-freq f- fabs f* { closeness } closeness closestamp f< if closeness to closestamp i to closestp then then loop closestamp 0.1 f< if current-peak-amps closestp peak-amps maxp vct-ref vct-set! drop peak-amps maxp 0.0 vct-set! drop current-peak-freqs closestp cur-freq vct-set! drop then then loop max-peaks 0 ?do peak-amps i vct-ref f0> if -1 { new-place } max-oscils 0 ?do last-peak-amps i vct-ref f0= current-peak-amps i vct-ref f0= && if i to new-place leave then loop current-peak-amps new-place peak-amps i vct-ref vct-set! drop peak-amps i 0.0 vct-set! drop current-peak-freqs new-place peak-freqs i vct-ref vct-set! drop last-peak-freqs new-place peak-freqs i vct-ref vct-set! drop resynth-oscils new-place array-ref ( gen ) transposition peak-freqs i vct-ref f* ( val ) set-mus-frequency drop then loop 0 to cur-oscils max-oscils 0 ?do rates i current-peak-amps i vct-ref last-peak-amps i vct-ref f- ifreq f* vct-set! drop current-peak-amps i vct-ref f0<> last-peak-amps i vct-ref f0<> || if i to cur-oscils then sweeps i current-peak-freqs i vct-ref last-peak-freqs i vct-ref f- transposition f* ihifreq f* vct-set! drop loop cur-oscils 1+ to cur-oscils then trigger 1+ to trigger ramped 0= if 0.0 ( sum ) else ramped-attack ramp-ind vct-ref ( sum ) ramp-ind 1+ to ramp-ind ramp-ind ramped = if 0 to ramp-ind then then ( sum ) cur-oscils 0 ?do ampls i vct-ref f0<> rates i vct-ref f0<> || if resynth-oscils i array-ref freqs i vct-ref 0.0 oscil ampls i vct-ref f* f+ ( sum += ... ) ampls i rates i vct-ref object-set+! freqs i sweeps i vct-ref object-set+! then loop amp ( sum ) f* then end-run ;instrument : pins-test <{ :optional start 0.0 dur 1.0 -- }> start now! now@ dur "fyow.snd" 1.0 :time-scaler 2.0 pins dur 0.2 f+ step ; \ ZC instrument: zc <{ start dur freq amp len1 len2 feedback -- }> :frequency freq make-pulse-train { s } :size len1 :scaler feedback :max-size len1 len2 max 1+ make-comb { d0 } :envelope #( 0 0 1 1 ) :scaler len2 len1 f- :duration dur make-env { zenv } start dur #{ :degree 90.0 random } run-instrument d0 s 0.0 pulse-train amp f* zenv env comb end-run ;instrument : zc-test <{ :optional start 0.0 dur 1.0 -- }> start now! now@ dur 100 0.4 20 100 0.95 zc dur 0.2 f+ step now@ dur 100 0.4 100 20 0.95 zc dur 0.2 f+ step ; \ ZN \ \ notches are spaced at srate/len, feedforward sets depth thereof so \ sweep of len from 20 to 100 sweeps the notches down from 1000 Hz to \ ca 200 Hz so we hear our downward glissando beneath the pulses. instrument: zn <{ start dur freq amp len1 len2 feedforward -- }> :frequency freq make-pulse-train { s } :size len1 :scaler feedforward :max-size len1 len2 max 1+ make-notch { d0 } :envelope #( 0 0 1 1 ) :scaler len2 len1 f- :duration dur make-env { zenv } start dur #{ :degree 90.0 random } run-instrument d0 s 0.0 pulse-train amp f* zenv env notch end-run ;instrument : zn-test <{ :optional start 0.0 dur 1.0 -- }> start now! now@ dur 100 0.5 20 100 0.95 zn dur 0.2 f+ step now@ dur 100 0.5 100 20 0.95 zn dur 0.2 f+ step ; \ ZA instrument: za <{ start dur freq amp len1 len2 fb ffw -- }> :frequency freq make-pulse-train { s } :size len1 :feedback fb :feedforward ffw :max-size len1 len2 max 1+ make-all-pass { d0 } :envelope #( 0 0 1 1 ) :scaler len2 len1 f- :duration dur make-env { zenv } start dur #{ :degree 90.0 random } run-instrument d0 s 0.0 pulse-train amp f* zenv env all-pass end-run ;instrument : za-test <{ :optional start 0.0 dur 1.0 -- }> start now! now@ dur 100 0.3 20 100 0.95 0.95 za dur 0.2 f+ step now@ dur 100 0.3 100 20 0.95 0.95 za dur 0.2 f+ step ; hide : clm-src-cb { gen -- prc; dir self -- r } 1 proc-create ( prc ) gen , does> { dir self -- r } self @ ( gen ) #f #f granulate ; set-current \ CLM-EXPSRC instrument: clm-expsrc <{ start dur in-file exp-ratio src-ratio amp :optional rev #f start-in-file 0 -- }> in-file find-file to in-file in-file unless 'file-not-found #( "%s: can't find %S" get-func-name in-file ) fth-throw then start-in-file in-file mus-sound-srate f* fround->s { stf } :file in-file :channel 0 :start stf make-readin { fdA } :input fdA readin-cb :expansion exp-ratio make-granulate { exA } :input exA clm-src-cb :srate src-ratio make-src { srcA } in-file channels 2 = *output* channels 2 = && { two-chans } *reverb* rev && { revit } two-chans if :file in-file :channel 1 :start stf make-readin { fdB } :input fdB readin-cb :expansion exp-ratio make-granulate { exB } :input exB clm-src-cb :srate src-ratio make-src { srcB } revit if rev f2/ to rev start dur run srcA 0.0 undef src amp f* { valA } srcB 0.0 undef src amp f* { valB } i valA *output* outa drop i valB *output* outb drop i valA valB f+ rev f* *reverb* outa drop loop else start dur run i srcA 0.0 undef src amp f* *output* outa drop i srcB 0.0 undef src amp f* *output* outb drop loop then else revit if start dur run srcA 0.0 undef src amp f* { valA } i valA *output* outa drop i valA rev f* *reverb* outa drop loop else start dur run i srcA 0.0 undef src amp f* *output* outa drop loop then then ;instrument previous : clm-expsrc-test <{ :optional start 0.0 dur 1.0 -- }> start now! now@ dur "oboe.snd" 2.0 1.0 1.0 clm-expsrc dur 0.2 f+ step ; \ EXP-SND instrument: exp-snd <{ file start dur amp :optional exp-amt 1.0 ramp 0.4 seglen 0.15 sr 1.0 hop 0.05 ampenv #f -- }> doc" \n\ \\ ;; granulate with envelopes on the expansion amount,\n\ \\ ;; segment envelope shape, segment length, hop length,\n\ \\ ;; and input file resampling rate\n\ \"fyow.snd\" 0 3 1 #( 0 1 1 3 ) 0.4 0.15\n\ #( 0 2 1 0.5 ) 0.05 <'> exp-snd with-sound\n\ \"oboe.snd\" 0 3 1 #( 0 1 1 3 ) 0.4 0.15\n\ #( 0 2 1 0.5 ) 0.2 <'> exp-snd with-sound." file find-file to file file unless 'file-not-found #( "%s: can't find %S" get-func-name file ) fth-throw then file 0 make-readin { f0 } :envelope exp-amt array? if exp-amt else #( 0 exp-amt 1 exp-amt ) then :duration dur make-env { expenv } :envelope seglen array? if seglen else #( 0 seglen 1 seglen ) then :duration dur make-env { lenenv } seglen if seglen array? if seglen max-envelope else seglen then else 0.15 then { max-seg-len } seglen if seglen array? if seglen 1 array-ref else seglen then else 0.15 then { initial-seg-len } max-seg-len 0.15 f> if 0.6 0.15 f* max-seg-len f/ else 0.6 then { scaler-amp } :envelope sr array? if sr else #( 0 sr 1 sr ) then :duration dur make-env { srenv } ramp array? if ramp else #( 0 ramp 1 ramp ) then { rampdata } :envelope rampdata :duration dur make-env { rampenv } ramp if ramp array? if ramp 1 array-ref else ramp then else 0.4 then { initial-ramp-time } :envelope hop array? if hop else #( 0 hop 1 hop ) then :duration dur make-env { hopenv } hop if hop array? if hop max-envelope else hop then else 0.05 then { max-out-hop } hop if hop array? if hop 1 array-ref else hop then else 0.05 then { initial-out-hop } exp-amt if exp-amt array? if exp-amt min-envelope else exp-amt then else 1.0 then { min-exp-amt } exp-amt if exp-amt array? if exp-amt 1 array-ref else exp-amt then else 1.0 then { initial-exp-amt } max-out-hop min-exp-amt f/ { max-in-hop } :envelope ampenv #( 0 0 0.5 1 1 0 ) || :scaler amp :duration dur make-env { ampe } :input f0 readin-cb :expansion initial-exp-amt :max-size max-out-hop max-in-hop fmax max-seg-len f+ mus-srate f* fceil f>s :ramp initial-ramp-time :hop initial-out-hop :length initial-seg-len :scaler scaler-amp make-granulate { ex-a } ampe env { vol } ex-a granulate vol f* { val-a0 } ex-a granulate vol f* { val-a1 } rampdata min-envelope f0<= rampdata max-envelope 0.5 f>= || if 'forth-error #( "ramp arg to expand must always \ be between 0.0 and 0.5, %.3f -- %.3f" rampdata min-envelope rampdata max-envelope ) fth-throw then 0.0 0.0 { ex-samp next-samp } 0.0 0.0 0.0 0.0 0.0 { expa segl resa rmpl hp } 0 0 { sl rl } start dur #{ :degree 90.0 random } run-instrument expenv env to expa lenenv env to segl srenv env to resa rampenv env to rmpl hopenv env to hp segl mus-srate f* floor dup f>s to sl ( fsl ) rmpl f* floor f>s to rl ampe env to vol ex-a sl set-mus-length drop ex-a rl set-mus-ramp drop ex-a hp set-mus-frequency drop ex-a expa set-mus-increment drop resa next-samp f+ to next-samp next-samp ex-samp 1.0 f+ f> if next-samp ex-samp f- fround->s 0 ?do val-a1 to val-a0 ex-a granulate vol f* to val-a1 1.0 ex-samp f+ to ex-samp loop then next-samp ex-samp f= if val-a0 else next-samp ex-samp f- val-a1 val-a0 f- f* val-a0 f+ then end-run ;instrument : exp-snd-test <{ :optional start 0.0 dur 1.0 -- }> start now! "fyow.snd" now@ dur 1.0 #( 0 1 1 3 ) 0.4 0.15 #( 0 2 1 0.5 ) 0.05 exp-snd dur 0.2 f+ step "oboe.snd" now@ dur 1.0 #( 0 1 1 3 ) 0.4 0.15 #( 0 2 1 0.5 ) 0.2 exp-snd dur 0.2 f+ step ; #( "exp-rampval" "exp-rampinc" "exp-loc" "exp-segctr" "exp-whichseg" "exp-ramplen" "exp-steadylen" "exp-trigger" ) create-struct make-expfil-struct \ EXPFIL instrument: expfil <{ start dur hopsecs rampsecs steadysecs file1 file2 -- }> file1 find-file to file1 file1 unless 'file-not-found #( "%s: can't find %S" get-func-name file1 ) fth-throw then file2 find-file to file2 file2 unless 'file-not-found #( "%s: can't find %S" get-func-name file2 ) fth-throw then rampsecs seconds->samples { ramplen } make-expfil-struct { grn1 } make-expfil-struct { grn2 } grn1 0.0 exp-rampval! grn2 0.0 exp-rampval! grn1 ramplen 1/f exp-rampinc! grn2 ramplen 1/f exp-rampinc! grn1 0 exp-loc! grn2 0 exp-loc! grn1 0 exp-segctr! grn2 0 exp-segctr! grn1 0 exp-whichseg! grn2 0 exp-whichseg! grn1 ramplen exp-ramplen! grn2 ramplen exp-ramplen! grn1 steadysecs seconds->samples exp-steadylen! grn2 steadysecs seconds->samples exp-steadylen! grn1 0 exp-trigger! grn2 0 exp-trigger! hopsecs seconds->samples { hop } start seconds->samples { out1 } hop out1 + { out2 } file1 0 make-readin { fil1 } file2 0 make-readin { fil2 } 0.0 { inval } start dur #{ :degree 90.0 random } run-instrument 0.0 ( val ) i out1 = if fil1 grn1 exp-loc@ 0 file->sample to inval grn1 grn1 exp-loc@ 1+ exp-loc! grn1 exp-whichseg@ case 0 of grn1 exp-rampval@ inval f* to inval grn1 grn1 exp-rampinc@ grn1 exp-rampval@ f+ exp-rampval! grn1 grn1 exp-segctr@ 1+ exp-segctr! grn1 exp-segctr@ grn1 exp-ramplen@ = if grn1 0 exp-segctr! grn1 grn1 exp-whichseg@ 1+ exp-whichseg! then endof 1 of grn1 grn1 exp-segctr@ 1+ exp-segctr! grn1 exp-segctr@ grn1 exp-steadylen@ = if grn1 0 exp-segctr! grn1 grn1 exp-whichseg@ 1+ exp-whichseg! then endof \ default grn1 exp-rampval@ inval f* to inval grn1 grn1 exp-segctr@ 1+ exp-segctr! grn1 grn1 exp-rampinc@ fnegate grn1 exp-rampval@ f+ exp-rampval! grn1 exp-segctr@ grn1 exp-ramplen@ = if grn1 0 exp-segctr! grn1 1 exp-trigger! grn1 0 exp-whichseg! grn1 0.0 exp-rampval! then endcase inval f+ ( val ) out1 1+ to out1 grn1 exp-trigger@ 1 = if grn1 0 exp-trigger! hop out1 + to out1 then then i out2 = if fil2 grn2 exp-loc@ 0 file->sample { inval } grn2 grn2 exp-loc@ 1+ exp-loc! grn2 exp-whichseg@ case 0 of grn2 exp-rampval@ inval f* to inval grn2 grn2 exp-rampinc@ grn1 exp-rampval@ f+ exp-rampval! grn2 grn2 exp-segctr@ 1+ exp-segctr! grn2 exp-segctr@ grn2 exp-ramplen@ = if grn2 0 exp-segctr! grn2 grn2 exp-whichseg@ 1+ exp-whichseg! then endof 1 of grn2 grn2 exp-segctr@ 1+ exp-segctr! grn2 exp-segctr@ grn2 exp-steadylen@ = if grn2 0 exp-segctr! grn2 grn2 exp-whichseg@ 1+ exp-whichseg! then endof \ default grn2 exp-rampval@ inval f* to inval grn2 grn2 exp-segctr@ 1+ exp-segctr! grn2 grn2 exp-rampinc@ fnegate grn2 exp-rampval@ f+ exp-rampval! grn2 exp-segctr@ grn2 exp-ramplen@ = if grn2 0 exp-segctr! grn2 1 exp-trigger! grn2 0 exp-whichseg! grn2 0.0 exp-rampval! then endcase inval f+ ( val ) out2 1+ to out2 grn2 exp-trigger@ 1 = if grn2 0 exp-trigger! hop out2 + to out2 then then end-run ;instrument : expfil-test <{ :optional start 0.0 dur 1.0 -- }> start now! now@ dur 0.2 0.01 0.1 "oboe.snd" "fyow.snd" expfil dur 0.2 f+ step ; \ GRAPH-EQ \ \ From: Marco Trevisani \ \ This should work like a Graphic Equalizer.... \ Very easy to use. Just some note: \ \ "amp" & "amp-env" apply an enveloppe to the final result of the \ filtering. \ \ "dur" as ""standard"" in my instruments, when dur = 0 it will take the \ length of the sndfile input, otherwise the duration in seconds. \ \ "gain-freq-list" is a list of gains and frequencies to \ filter --in this order gain and frequencies--. There is no limit to \ the size of the list. Gain can be a number or an \ envelope. Unfortunatelly in this version they cant alternate, one \ should chose, all envelopes or all numbers i.e.: \ case 1 -> #( .1 440.0 .3 1500.0 .2 330.0 ...etc) or \ case 2 -> #((0 .1 1 .5) 440.0 (0 1 1 .01) 1500 (0 .3 1 .5) 330.0 ...etc) \ #( .1 440.0 (0 1 1 .01) 1500 ..etc) <<< again, this is not allowed .. \ \ "offset-gain" This apply to all the gains if case 1. It adds or \ subtracts an offset to all the gains in the list. This number can be \ positive or negative. In case the result is a negative number --let's \ say offset = -.4 and, like in case 1, the first gain is .1, the result \ would be -.3 -- the instrument will pass a gain equal to 0. \ \ "filt-gain-scale" & "filt-gain-base" will apply to the elements of the \ envelopes if we are in case 2, gains are envelopes. instrument: graph-eq <{ file start dur :key file-start 0.0 amplitude 1.0 amp-env #( 0 1 0.8 1 1 0 ) amp-base 1.0 offset-gain 0.0 gain-freq-list #( #( 0 1 1 0 ) 440 #( 0 0 1 1 ) 660 ) filt-gain-scale 1.0 filt-gain-base 1.0 a1 0.99 -- }> doc" \"oboe.snd\" 0 2 graph-eq." file find-file to file file unless 'file-not-found #( "%s: can't find %S" get-func-name file ) fth-throw then :file file :start file mus-sound-srate file-start f* fround->s make-readin { rd } :envelope amp-env :scaler amplitude :duration dur :base amp-base make-env { ampf } gain-freq-list length 2/ { len } len make-array { gainl } len make-array { freql } 0 { idx } gain-freq-list length 1- 0 ?do gainl idx gain-freq-list i array-ref array-set! freql idx gain-freq-list i 1+ array-ref array-set! idx 1+ to idx 2 +loop gainl 0 array-ref array? dup { if-list-in-gain } if len make-array map! :envelope gainl i array-ref :scaler filt-gain-scale :duration dur :base filt-gain-base make-env end-map else #f then { env-size } freql map :frequency *key* :radius a1 make-formant end-map { frm-size } len 1.0 make-vct { gains } gainl each { gval } freql i array-ref { fval } if-list-in-gain if :envelope gval :scaler filt-gain-scale :duration dur :base filt-gain-base make-env env-size i rot ( en ) array-set! frm-size i :frequency fval :radius a1 make-formant array-set! else frm-size i :frequency fval :radius a1 make-formant array-set! gains i offset-gain gval f+ f0< if 0.0 else offset-gain gval f+ then vct-set! drop then end-each 1.0 a1 f- { 1-a1 } start dur #{ :degree 90.0 random } run-instrument rd readin { inval } 0.0 ( outval ) env-size each { en } if-list-in-gain if gains i en env 1-a1 f* vct-set! drop then frm-size i array-ref ( fmt ) inval undef formant gains i vct-ref f* ( fmt * gain ) f+ ( outval += ... ) end-each ampf env f* ( outval ) end-run rd mus-close drop ;instrument : graph-eq-test <{ :optional start 0.0 dur 1.0 -- }> start now! "oboe.snd" now@ dur :amplitude 50.0 graph-eq dur 0.2 f+ step ; \ ANOI \ \ a kind of noise reduction -- on-going average spectrum is squelched \ to some extent obviously aimed at intermittent signal in background \ noise \ this is based on Perry Cook's Scrubber.m \ \ clm/anoi.ins instrument: anoi <{ fname start dur :optional fftsize 128 amp-scaler 1.0 R two-pi -- }> fftsize 2/ { freq-inc } fftsize 0.0 make-vct { fdr } fftsize 0.0 make-vct { fdi } freq-inc 1.0 make-vct { spectr } freq-inc 1.0 make-vct { scales } freq-inc 0.0 make-vct { diffs } blackman2-window fftsize undef undef make-fft-window { win } amp-scaler 4.0 f* mus-srate f/ { incr } fname find-file to fname fname unless 'file-not-found #( "%s: can't find %S" get-func-name fname ) fth-throw then fname make-file->sample { fil } fftsize s>f to fftsize fftsize fnegate { -fftsize } 1.0 R fftsize f/ f- { radius } mus-srate fftsize f/ { bin } freq-inc make-array map! :frequency i bin f* :radius radius make-formant end-map { fs } 0 { samp } 0.0 { inval } nil { fmt } 0.0 { curscl } 0.0 { fd } 0.0 { amp } start dur #{ :degree 90.0 random } run-instrument fil samp 0 file->sample to inval samp 1+ to samp fdr inval cycle-set! amp amp-scaler f< if incr amp f+ to amp then fdr cycle-start@ 0= if fdr fdi win 1 spectrum drop diffs map! fdr i vct-ref to fd spectr i spectr i vct-ref 0.9 f* fd 0.1 f* f+ vct-set! ( sp ) fd f>= if scales i vct-ref -fftsize f/ else fd spectr i vct-ref f- fd f/ scales i vct-ref f- fftsize f/ then ( diff ) end-map drop then 0.0 ( outval ) fs each to fmt scales i vct-ref to curscl fmt inval undef formant curscl f* f+ ( outval += ... ) scales i diffs i vct-ref curscl f+ vct-set! drop end-each ( outval ) amp f* end-run ;instrument : anoi-test <{ :optional start 0.0 dur 1.0 -- }> start now! "fyow.snd" now@ dur 128 2.0 anoi dur 0.2 f+ step ; \ Date: Fri, 25 Sep 1998 09:56:41 +0300 \ From: Matti Koskinen \ To: linux-audio-dev@ginette.musique.umontreal.ca \ Subject: [linux-audio-dev] Announce: alpha version of denoising \ [...] \ I wrote a simple denoiser called anoi after it's parent \ clm-instrument anoi.ins. \ \ anoi tries to remove white noise like tape hiss from wav- \ files. Removing of noise succeeds ok, but depending of the \ original sound, some distortion can be audible. \ \ If someone is interested, http://www.sci.fi/~mjkoskin \ contains tarred and gzipped file. \ \ Now only monophonic wav-files can be denoised, but adding \ others isn't too difficult. \ \ -matti \ mjkoskin@sci.fi \ \ FIXME fullmix \ needs some more work \ instrument: fullmix <{ in-file :optional start 0.0 dur #f inbeg 0.0 matrix #f sr #f rev-amount #f -- }> ; : fullmix-test <{ :optional start 0.0 dur 1.0 -- }> ; 0 [if] hide : set-fullmix-matrix { outn mx inp outp in-chans out-chans dur -- envs } #f { envs } outn number? if mx inp outp outn mixer-set! drop else outn env? outn array? || if in-chans make-array map! out-chans make-array end-map to envs envs inp array-ref outp outn env? if outn else :envelope outn :duration dur make-env then array-set! else 'forth-error #( "fullmix: unknown element in matrix: %S" outn ) fth-throw then then envs ; set-current \ FULLMIX instrument: fullmix <{ in-file :optional start 0.0 dur #f inbeg 0.0 matrix #f sr #f rev-amount #f -- }> doc" \"pistol.snd\" 0 1 fullmix\n\ :envelope #( 0 0 1 1 ) :duration 2 :scaler 0.5 make-env value en \"oboe.snd\" 0 2 0 #( #( 0.8 en ) ) 2.0 <'> fullmix with-sound." in-file find-file to in-file in-file unless 'file-not-found #( "%s: can't find %S" get-func-name in-file ) fth-throw then dur number? unless in-file mus-sound-duration inbeg f- sr if sr fabs else 1.0 then f/ to dur then in-file channels { in-chans } *output* channels { out-chans } inbeg in-file mus-sound-srate f* fround->s { inloc } matrix if in-chans out-chans max make-mixer else in-chans out-chans max 1.0 make-scalar-mixer then { mx } #f { rev-mx } *reverb* rev-amount f0> && if in-chans make-mixer to rev-mx in-chans 0 ?do rev-mx i 0 rev-amount mixer-set! drop loop then #f { envs } #f { inlist } matrix if matrix object-length 0> if in-chans 0 ?do matrix i object-ref to inlist out-chans 0 ?do inlist i object-ref ( outn ) mx j i in-chans out-chans dur set-fullmix-matrix to envs loop loop else in-chans 0 ?do i out-chans < if mx i i matrix mixer-set! drop then loop then then sr unless \ ws-info ( start dur local-vars -- start dur ) \ \ This is normally done in RUN or RUN-INSTRUMENT, but here \ we haven't one of them. \ start dur local-variables ws-info ( start dur ) ( start ) seconds->samples { st } ( dur ) seconds->samples { samps } *output* in-file undef make-file->frame st samps inloc mx envs mus-file-mix drop rev-mx if *reverb* 1 make-frame st samps inloc rev-mx #f mus-file-mix drop then else in-chans make-frame { inframe } out-chans make-frame { outframe } in-chans make-array map! :file in-file :channel i :start inloc make-readin { rd } :input rd readin-cb :srate sr make-src end-map { srcs } envs if start dur run envs each ( mat ) each { en } env? if mx j ( inp ) i ( outp ) en env mixer-set! drop then end-each end-each in-chans 0 ?do inframe i srcs i array-ref 0.0 undef src frame-set! drop loop *output* i inframe mx outframe frame->frame frame->file drop rev-mx if *reverb* i inframe rev-mx outframe frame->frame frame->file drop then loop else start dur run in-chans 0 ?do inframe i srcs i array-ref 0.0 undef src frame-set! drop loop *output* i inframe mx outframe frame->frame frame->file drop rev-mx if *reverb* i inframe rev-mx outframe frame->frame frame->file drop then loop then then ;instrument previous : fullmix-test <{ :optional start 0.0 dur 1.0 -- }> start now! :envelope #( 0 0 1 1 ) :duration dur :scaler 0.5 make-env { en } "pistol.snd" now@ dur fullmix dur 0.2 f+ step "oboe.snd" now@ dur 0 #( #( 0.1 en ) ) fullmix dur 0.2 f+ step ; [then] 'snd provided? [if] \ ;;; bes-fm -- can also use bes-j0 here as in earlier versions instrument: bes-fm <{ start dur freq amp ratio index -- }> 0.0 0.0 { car-ph mod-ph } freq hz->radians { car-incr } ratio car-incr f* { mod-incr } :envelope #( 0 0 25 1 75 1 100 0 ) :scaler amp :duration dur make-env { ampenv } start dur #{ :degree 90.0 random } run-instrument ampenv env car-ph bes-j1 f* ( result ) mod-ph bes-j1 index f* car-incr f+ car-ph f+ to car-ph mod-incr mod-ph f+ to mod-ph end-run ;instrument : bes-fm-test <{ :optional start 0.0 dur 1.0 -- }> start now! now@ dur 440.0 10.0 1.0 4.0 bes-fm dur 0.2 f+ step ; include dsp [else] : bes-fm-test <{ :optional start 0.0 dur 1.0 -- }> ; \ --- Hilbert transform (from dsp.fs) : make-hilbert-transform <{ :optional len 30 -- gen }> doc" Make Hilbert transform filter." len 2* 1+ { arrlen } arrlen 0.0 make-vct { arr } len even? if len else len 1+ then { lim } lim len negate ?do i len + { kk } i pi f* { denom } 1.0 denom fcos f- { num } num f0<> i 0<> || if arr kk num denom f/ denom len f/ fcos 0.46 f* 0.54 f+ f* vct-set! drop then loop :order arrlen :xcoeffs arr make-fir-filter ; <'> fir-filter alias hilbert-transform <'> fir-filter? alias hilbert-transform? <'> hilbert-transform <'> fir-filter help-ref help-set! <'> hilbert-transform? <'> fir-filter? help-ref help-set! [then] \ SSB-FM \ ;;; this might be better named "quasi-ssb-fm" -- cancellations are not \ ;;; perfect #( "sbfm-am0" "sbfm-am1" "sbfm-car0" "sbfm-car1" "sbfm-mod0" "sbfm-mod1" ) create-struct make-ssb-fm-struct : make-ssb-fm ( freq -- sbfm ) { freq } make-ssb-fm-struct { sbfm } freq 0.0 make-oscil sbfm swap sbfm-am0! freq half-pi make-oscil sbfm swap sbfm-am1! 0.0 0.0 make-oscil sbfm swap sbfm-car0! 0.0 half-pi make-oscil sbfm swap sbfm-car1! 40 make-hilbert-transform sbfm swap sbfm-mod0! 40 make-delay sbfm swap sbfm-mod1! sbfm ; : ssb-fm ( gen modsig -- val ) { gen modsig } gen sbfm-am0@ 0.0 0.0 oscil gen sbfm-car0@ gen sbfm-mod0@ modsig hilbert-transform 0.0 oscil f* gen sbfm-am1@ 0.0 0.0 oscil gen sbfm-car1@ gen sbfm-mod1@ modsig 0.0 delay 0.0 oscil f* f+ ; \ ;;; if all we want are asymmetric fm-generated spectra, we can just \ ;;; add 2 fm oscil pairs: #( "fm2-os1" "fm2-os2" "fm2-os3" "fm2-os4" ) create-struct make-fm2-struct : make-fm2 ( f1 f2 f3 f4 p1 p2 p3 p4 -- fm2 ) { f1 f2 f3 f4 p1 p2 p3 p4 } make-fm2-struct { fm2 } f1 p1 make-oscil fm2 swap fm2-os1! f2 p2 make-oscil fm2 swap fm2-os2! f3 p3 make-oscil fm2 swap fm2-os3! f4 p4 make-oscil fm2 swap fm2-os4! fm2 ; : fm2 ( gen index -- val ) { gen index } gen fm2-os1@ gen fm2-os2@ 0.0 0.0 oscil index f* 0.0 oscil gen fm2-os3@ gen fm2-os4@ 0.0 0.0 oscil index f* 0.0 oscil f+ 0.25 f* ; \ ;;; rms gain balance \ ;;; This is a translation of the rmsgain code provided by Fabio Furlanete. hide #( "rmsg-c1" "rmsg-c2" "rmsg-q" "rmsg-r" "rmsg-avg" "rmsg-avgc" ) create-struct make-rmsgain-struct set-current : make-rmsgain <{ :optional hp 10.0 -- gen }> doc" Make RMS gain generator." 2.0 two-pi mus-srate f/ hp f* fcos f- { b } b b b f* 1.0 f- fsqrt f- { c2 } 1.0 c2 f- { c1 } make-rmsgain-struct { rmsg } rmsg c1 rmsg-c1! rmsg c2 rmsg-c2! rmsg 0.0 rmsg-q! rmsg 0.0 rmsg-r! rmsg 0.0 rmsg-avg! rmsg 0 rmsg-avgc! rmsg ; : rmsgain-rms ( gen sig -- val ) doc" Run RMS gain generator." { gen sig } gen rmsg-c1@ sig f* sig f* gen rmsg-c2@ gen rmsg-q@ f* f+ gen over rmsg-q! ( val ) fsqrt ; : rmsgain-gain ( gen sig rmsval -- val ) doc" Return current RMS gain." { gen sig rmsval } gen rmsg-c1@ sig f* sig f* gen rmsg-c2@ gen rmsg-r@ f* f+ gen over rmsg-r! ( val ) f0= if rmsval else rmsval gen rmsg-r@ fsqrt f/ then { this-gain } gen gen rmsg-avg@ this-gain f+ rmsg-avg! gen gen rmsg-avgc@ 1+ rmsg-avgc! sig this-gain f* ; : rmsgain-balance ( gen sig comp -- val ) doc" Scale signal based on a RMS gain." { gen sig comp } gen sig gen comp rmsgain-rms rmsgain-gain ; : rmsgain-gain-avg ( gen -- val ) doc" Is part of the RMS gain stuff." { gen } gen rmsg-avg@ gen rmsg-avgc@ f/ ; <'> rmsg-avg@ alias rmsgain-avg ( gen -- val ) <'> rmsg-avgc@ alias rmsgain-avgc ( gen -- val ) previous : clm-ins-test <{ :optional start 0.0 dur 1.0 }> start now! now@ dur violin-test now@ dur fm-violin-test now@ dur pluck-test now@ dur vox-test now@ dur fofins-test now@ dur fm-trumpet-test now@ dur pqw-vox-test now@ dur flute-test now@ dur fm-bell-test now@ dur fm-insect-test now@ dur fm-drum-test now@ dur gong-test now@ dur attract-test now@ dur pqw-test now@ dur tubebell-test now@ dur wurley-test now@ dur rhodey-test now@ dur hammondoid-test now@ dur metal-test now@ dur drone/canter-test now@ dur reson-test now@ dur cellon-test now@ dur gran-synth-test now@ dur touch-tone-test now@ dur spectra-test now@ dur two-tab-test now@ dur lbj-piano-test now@ dur resflt-test now@ dur scratch-test now@ dur pins-test now@ dur zc-test now@ dur zn-test now@ dur za-test now@ dur clm-expsrc-test now@ dur exp-snd-test now@ dur expfil-test now@ dur graph-eq-test now@ dur anoi-test now@ dur fullmix-test now@ dur bes-fm-test ; \ clm-ins.fs ends here snd-16.1/COPYING0000644000076400007640000000217712306421672011400 0ustar bilbilSnd is a sound editor written by Bill Schottstaedt (bil@ccrma.stanford.edu). Except where otherwise noted, it is Copyright 1996-2013 Bill Schottstaedt. The authors hereby grant permission to use, copy, modify, distribute, and license this software and its documentation for any purpose. No written agreement, license, or royalty fee is required. Modifications to this software may be copyrighted by their authors and need not follow the licensing terms described here. IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. snd-16.1/headers.c0000644000076400007640000075156112623170515012133 0ustar bilbil/* readers/writers for various sound file headers * * Currently supported read/write (in standard sample types): * NeXT/Sun/DEC/AFsp * AIFF/AIFC * RIFF (microsoft wave) * RF64 (EBU) * IRCAM (old style) * NIST-sphere * CAFF * no header * * Currently supported read-only (in selected sample types): * 8SVX (IFF), EBICSF, INRS, ESPS, SPPACK, ADC (OGI), AVR, VOC, CSL, snack "SMP", PVF, * Sound Tools, Turtle Beach SMP, SoundFont 2.0, Sound Designer I, PSION alaw, MAUD, * Gravis Ultrasound, Comdisco SPW, Goldwave sample, OMF, quicktime, sox, * Sonic Foundry (w64), SBStudio II, Delusion digital, Digiplayer ST3, Farandole Composer WaveSample, * Ultratracker WaveSample, Sample Dump exchange, Yamaha SY85 and SY99 (buggy), Yamaha TX16W, * Covox v8, AVI, Kurzweil 2000, Paris Ensoniq, Impulse tracker, Korg, Akai type 4, Maui, * * for a few of these I'm still trying to get documentation -- best sources of info are: * ftp.cwi.nl:pub/audio (info files) * the AFsp sources http://www.TSP.ECE.McGill.CA/MMSP/Documents/AudioFormats/index.html * the SOX sources * svr-ftp.eng.cam.ac.uk:/comp.speech/tools * http://www.wotsit.org * CAFF: http://developer.apple.com/documentation/MusicAudio/Reference/CAFSpec/ * and afconvert can be found in /Developer/Examples/CoreAudio/Services/AudioFileTools/ * RIFF: Microsoft Multimedia Programmer's Reference Manual at ftp.microsoft.com:/SoftLib/MSLFILES/MDRK.EXE * AVI: http://www.rahul.net/jfm/avi.html * EBU RF64: http://www.ebu.ch/CMSimages/en/tec_doc_t3306_tcm6-42570.pdf * Sound Designer: "Developer Documentation" from Digidesign * * test cases (sample files): ccrma-ftp.stanford.edu:/pub/Lisp/sf.tar.gz */ #include "mus-config.h" #if USE_SND #include "snd.h" #endif #include #include #include #include #include #ifndef _MSC_VER #include #else #include #pragma warning(disable: 4244) #endif #include "_sndlib.h" #include "sndlib-strings.h" /* can't use LONG_MAX here because we want a 4-byte max even on 64-bit machines */ #define BIGGEST_4_BYTE_SIGNED_INT 2147483647L #define BIGGEST_4_BYTE_UNSIGNED_INT 4294967295UL static const unsigned char I_DSND[4] = {'.','s','n','d'}; /* NeXT/Sun/Dec/SGI/AFsp first word */ static const unsigned char I_FORM[4] = {'F','O','R','M'}; /* AIFF first word */ static const unsigned char I_AIFF[4] = {'A','I','F','F'}; /* AIFF second word */ static const unsigned char I_AIFC[4] = {'A','I','F','C'}; /* ditto but might be compressed data */ static const unsigned char I_COMM[4] = {'C','O','M','M'}; static const unsigned char I_COMT[4] = {'C','O','M','T'}; static const unsigned char I_INFO[4] = {'I','N','F','O'}; static const unsigned char I_INST[4] = {'I','N','S','T'}; static const unsigned char I_MARK[4] = {'M','A','R','K'}; static const unsigned char I_SSND[4] = {'S','S','N','D'}; static const unsigned char I_NONE[4] = {'N','O','N','E'}; static const unsigned char I_ULAW[4] = {'U','L','A','W'}; /* AIFC compression types that we can handle */ static const unsigned char I_ulaw[4] = {'u','l','a','w'}; /* or maybe it's lowercase (Apple) ... */ static const unsigned char I_raw_[4] = {'r','a','w',' '}; /* AIFC offset binary OS 8.5 (others are 'MAC3' 'MAC6' 'cdx4' 'cdx2' 'str4') */ static const unsigned char I_sowt[4] = {'s','o','w','t'}; /* AIFC 16-bit little endian -- used by Mac when extracting CD tracks */ static const unsigned char I_fl32[4] = {'f','l','3','2'}; /* AIFC 32-bit float */ static const unsigned char I_fl64[4] = {'f','l','6','4'}; /* AIFC 64-bit float */ static const unsigned char I_alaw[4] = {'a','l','a','w'}; /* apple */ static const unsigned char I_APPL[4] = {'A','P','P','L'}; static const unsigned char I_MUS_[4] = {'C','L','M',' '}; /* I hereby claim this AIFF chunk name */ static const unsigned char I_RIFF[4] = {'R','I','F','F'}; /* RIFF first word */ static const unsigned char I_RIFX[4] = {'R','I','F','X'}; /* RIFX first word (big-endian RIFF file) */ static const unsigned char I_WAVE[4] = {'W','A','V','E'}; static const unsigned char I_fmt_[4] = {'f','m','t',' '}; static const unsigned char I_data[4] = {'d','a','t','a'}; static const unsigned char I_fact[4] = {'f','a','c','t'}; /* used by compressed RIFF files */ static const unsigned char I_clm_[4] = {'c','l','m',' '}; static const unsigned char I_NIST[4] = {'N','I','S','T'}; /* first word of NIST SPHERE files */ static const unsigned char I_VOC0[4] = {'C','r','e','a'}; /* Actual text is "Creative Voice File" */ static const unsigned char I_SOUN[4] = {'S','O','U','N'}; /* Sound Tools first word="SOUND" -- not unique as SMP files start with "SOUND SAMPLE" */ static const unsigned char I_ANNO[4] = {'A','N','N','O'}; static const unsigned char I_NAME[4] = {'N','A','M','E'}; static const unsigned char I_AVR_[4] = {'2','B','I','T'}; /* first word of AVR files */ static const unsigned char I_SPIB[4] = {'%','/','/','\n'}; /* first word of IEEE spib text sound files */ static const unsigned char I_S___[4] = {'%','-','-','-'}; /* first word of other IEEE spib text sound files */ static const unsigned char I_ALaw[4] = {'A','L','a','w'}; /* first word of PSION alaw files */ static const unsigned char I_MThd[4] = {'M','T','h','d'}; /* sigh -- the M word */ static const unsigned char I_DECN[4] = {'.','s','d','\0'}; /* first word of DEC files (?) */ static const unsigned char I_LIST[4] = {'L','I','S','T'}; static const unsigned char I_GF1P[4] = {'G','F','1','P'}; /* first word of Gravis Ultrsound patch files */ static const unsigned char I_DSIG[4] = {'$','S','I','G'}; /* first word of Comdisco SPW file */ static const unsigned char I_GOLD[4] = {'G','O','L','D'}; /* first word Goldwave(?) sample file */ static const unsigned char I_SRFS[4] = {'S','R','F','S'}; /* first word Sonic Resource Foundry file(?) */ static const unsigned char I_Diam[4] = {'D','i','a','m'}; /* first word DiamondWare file */ static const unsigned char I_CSRE[4] = {'C','S','R','E'}; /* adf first word -- second starts with "40" */ static const unsigned char I_SND_[4] = {'S','N','D',' '}; /* SBStudio II */ static const unsigned char I_DDSF[4] = {'D','D','S','F'}; /* Delusion Digital Sound File */ static const unsigned char I_FSMt[4] = {'F','S','M',(unsigned char)'\376'}; /* Farandole Composer WaveSample */ static const unsigned char I_UWFD[4] = {'U','W','F','D'}; /* Ultratracker Wavesample */ static const unsigned char I_LM89[4] = {'L','M','8','9'}; /* Yamaha TX-16 */ static const unsigned char I_SY80[4] = {'S','Y','8','0'}; /* Yamaha SY-99 */ static const unsigned char I_SY85[4] = {'S','Y','8','5'}; /* Yamaha SY-85 */ static const unsigned char I_SCRS[4] = {'S','C','R','S'}; /* Digiplayer ST3 */ static const unsigned char I_covox[4] = {(unsigned char)'\377','\125',(unsigned char)'\377',(unsigned char)'\252'}; static const unsigned char I_PRAM[4] = {'P','R','A','M'}; /* Kurzweil 2000 */ static const unsigned char I__PAF[4] = {' ','p','a','f'}; /* Paris Ensoniq */ static const unsigned char I_FAP_[4] = {'f','a','p',' '}; /* Paris Ensoniq */ static const unsigned char I_file[4] = {'f','i','l','e'}; /* snack "SMP" */ static const unsigned char I_PVF1[4] = {'P','V','F','1'}; /* portable voice format (mgetty) */ static const unsigned char I_PVF2[4] = {'P','V','F','2'}; static const unsigned char I_riff[4] = {'r','i','f','f'}; /* SoundForge */ static const unsigned char I_TWIN[4] = {'T','W','I','N'}; /* TwinVQ */ static const unsigned char I_IMPS[4] = {'I','M','P','S'}; /* Impulse Tracker */ static const unsigned char I_SMP1[4] = {'S','M','P','1'}; /* Korg */ static const unsigned char I_Maui[4] = {'M','a','u','i'}; /* Turtle Beach */ static const unsigned char I_SDIF[4] = {'S','D','I','F'}; /* IRCAM sdif */ #if G7XX static const unsigned char I_NVF_[4] = {'N','V','F',' '}; /* Nomad II Creative NVF */ #endif static const unsigned char I_ajkg[4] = {'a','j','k','g'}; /* shorten */ static const unsigned char I_RF64[4] = {'R','F','6','4'}; /* EBU RF64 */ static const unsigned char I_ds64[4] = {'d','s','6','4'}; /* EBU RF64 */ static const unsigned char I_caff[4] = {'c','a','f','f'}; /* Apple CAFF */ static const unsigned char I_desc[4] = {'d','e','s','c'}; /* Apple CAFF */ static const unsigned char I_lpcm[4] = {'l','p','c','m'}; /* Apple CAFF */ static const unsigned char I_dSoX[4] = {'.','S','o','X'}; /* Sox intermediate (little-endian?) */ static const unsigned char I_XoSd[4] = {'X','o','S','.'}; /* Sox intermediate */ #define HDRBUFSIZ 256 static unsigned char *hdrbuf; #define INITIAL_READ_SIZE 256 /* AIFF files can have any number of ANNO chunks, so we'll grab at least 4 of them */ #define AUX_COMMENTS 4 static mus_long_t *aux_comment_start = NULL, *aux_comment_end = NULL; #define LOOPS 2 static int *loop_modes = NULL, *loop_starts = NULL, *loop_ends = NULL; static int markers = 0; static int *marker_ids = NULL, *marker_positions = NULL; static bool hdrbuf_is_inited = false; /* for CLM */ void mus_reset_headers_c(void) { hdrbuf_is_inited = false; markers = 0; } int mus_header_initialize(void) { if (!hdrbuf_is_inited) { hdrbuf_is_inited = true; hdrbuf = (unsigned char *)calloc(HDRBUFSIZ, sizeof(unsigned char)); aux_comment_start = (mus_long_t *)calloc(AUX_COMMENTS, sizeof(mus_long_t)); aux_comment_end = (mus_long_t *)calloc(AUX_COMMENTS, sizeof(mus_long_t)); loop_modes = (int *)calloc(LOOPS, sizeof(int)); loop_starts = (int *)calloc(LOOPS, sizeof(int)); loop_ends = (int *)calloc(LOOPS, sizeof(int)); if ((hdrbuf == NULL) || (aux_comment_start == NULL) || (aux_comment_end == NULL) || (loop_modes == NULL) || (loop_starts == NULL) || (loop_ends == NULL)) return(mus_error(MUS_MEMORY_ALLOCATION_FAILED, "mus_header_initialize: buffer allocation failed")); } return(MUS_NO_ERROR); } #define I_IRCAM_VAX 0x0001a364 #define I_IRCAM_SUN 0x0002a364 #define I_IRCAM_MIPS 0x0003a364 #define I_IRCAM_NEXT 0x0004a364 static mus_long_t data_location = 0; static int srate = 0, chans = 0, original_sample_type = 0; static mus_sample_t sample_type = MUS_UNKNOWN_SAMPLE; static mus_header_t header_type = MUS_UNKNOWN_HEADER; static int type_specifier = 0, bits_per_sample = 0, block_align = 0, fact_samples = 0; static mus_long_t comment_start = 0, comment_end = 0; static mus_long_t true_file_length = 0, data_size = 0; static int base_detune = 0, base_note = 0; static bool little_endian = false; mus_long_t mus_header_samples(void) {return(data_size);} mus_long_t mus_header_data_location(void) {return(data_location);} int mus_header_chans(void) {return(chans);} int mus_header_srate(void) {return(srate);} mus_header_t mus_header_type(void) {return(header_type);} mus_sample_t mus_header_sample_type(void) {return(sample_type);} mus_long_t mus_header_comment_start(void) {return(comment_start);} mus_long_t mus_header_comment_end(void) {return(comment_end);} mus_long_t mus_header_aux_comment_start(int n) {if (aux_comment_start) return(aux_comment_start[n]); else return(-1);} mus_long_t mus_header_aux_comment_end(int n) {if (aux_comment_end) return(aux_comment_end[n]); else return(-1);} int mus_header_type_specifier(void) {return(type_specifier);} int mus_header_bits_per_sample(void) {return(bits_per_sample);} int mus_header_fact_samples(void) {return(fact_samples);} int mus_header_block_align(void) {return(block_align);} mus_long_t mus_header_true_length(void) {return(true_file_length);} int mus_header_original_sample_type(void) {return(original_sample_type);} int mus_header_loop_mode(int which) {if (loop_modes) return(loop_modes[which]); else return(-1);} int mus_header_loop_start(int which) {if (loop_starts) return(loop_starts[which]); else return(-1);} int mus_header_loop_end(int which) {if (loop_ends) return(loop_ends[which]); else return(-1);} int mus_header_mark_position(int id) {int i; for (i = 0; i < markers; i++) {if (marker_ids[i] == id) return(marker_positions[i]);} return(-1);} int mus_header_base_detune(void) {return(base_detune);} int mus_header_base_note(void) {return(base_note);} int mus_header_mark_info(int **m_ids, int **m_positions) { (*m_ids) = marker_ids; (*m_positions) = marker_positions; return(markers); } int mus_bytes_per_sample(mus_sample_t samp_type) { switch (samp_type) { case MUS_BYTE: return(1); break; case MUS_BSHORT: return(2); break; case MUS_UBYTE: return(1); break; case MUS_MULAW: return(1); break; case MUS_ALAW: return(1); break; case MUS_BINT: return(4); break; case MUS_BFLOAT: return(4); break; case MUS_BFLOAT_UNSCALED: return(4); break; case MUS_B24INT: return(3); break; case MUS_BDOUBLE: return(8); break; case MUS_BDOUBLE_UNSCALED: return(8); break; case MUS_LSHORT: return(2); break; case MUS_LINT: return(4); break; case MUS_LFLOAT: return(4); break; case MUS_LDOUBLE: return(8); break; case MUS_LFLOAT_UNSCALED: return(4); break; case MUS_LDOUBLE_UNSCALED: return(8); break; case MUS_L24INT: return(3); break; case MUS_UBSHORT: return(2); break; case MUS_ULSHORT: return(2); break; case MUS_BINTN: return(4); break; case MUS_LINTN: return(4); break; default: return(1); break; /* we divide by this number, so 0 is not safe */ } } mus_long_t mus_samples_to_bytes (mus_sample_t samp_type, mus_long_t size) { return(size * (mus_bytes_per_sample(samp_type))); } mus_long_t mus_bytes_to_samples (mus_sample_t samp_type, mus_long_t size) { return((mus_long_t)(size / (mus_bytes_per_sample(samp_type)))); } static bool equal_big_or_little_endian(const unsigned char *n1, const unsigned int n2) { return((mus_char_to_ubint(n1) == n2) || (mus_char_to_ulint(n1) == n2)); } static short big_or_little_endian_short(const unsigned char *n, bool little) { if (little) return(mus_char_to_lshort(n)); return(mus_char_to_bshort(n)); } static int big_or_little_endian_int(const unsigned char *n, bool little) { if (little) return(mus_char_to_lint(n)); return(mus_char_to_bint(n)); } static unsigned int big_or_little_endian_uint(const unsigned char *n, bool little) { if (little) return(mus_char_to_ulint(n)); return(mus_char_to_ubint(n)); } static float big_or_little_endian_float(const unsigned char *n, bool little) { if (little) return(mus_char_to_lfloat(n)); return(mus_char_to_bfloat(n)); } static bool match_four_chars(const unsigned char *head, const unsigned char *match) { return((head[0] == match[0]) && (head[1] == match[1]) && (head[2] == match[2]) && (head[3] == match[3])); } static void write_four_chars(unsigned char *head, const unsigned char *match) { head[0] = match[0]; head[1] = match[1]; head[2] = match[2]; head[3] = match[3]; } const char *mus_header_type_name(mus_header_t type) { switch (type) { case MUS_NEXT: return("Sun/Next"); break; case MUS_AIFC: return("AIFC"); break; case MUS_RIFF: return("RIFF"); break; case MUS_BICSF: return("BICSF"); break; case MUS_NIST: return("NIST"); break; case MUS_INRS: return("INRS"); break; case MUS_ESPS: return("ESPS"); break; case MUS_SVX: return("SVX8"); break; case MUS_VOC: return("VOC"); break; case MUS_SNDT: return("SNDT"); break; case MUS_SOX: return("Sox"); break; case MUS_RAW: return("raw (no header)"); break; case MUS_SMP: return("SMP"); break; case MUS_AVR: return("AVR"); break; case MUS_IRCAM: return("IRCAM"); break; case MUS_SD1: return("Sound Designer 1"); break; case MUS_SPPACK: return("SPPACK"); break; case MUS_MUS10: return("Mus10"); break; case MUS_HCOM: return("HCOM"); break; case MUS_PSION: return("PSION"); break; case MUS_MAUD: return("MAUD"); break; case MUS_IEEE: return("IEEE text"); break; case MUS_MATLAB: return("Matlab"); break; case MUS_ADC: return("ADC/OGI"); break; case MUS_MIDI: return("MIDI"); break; case MUS_SOUNDFONT: return("SoundFont"); break; case MUS_GRAVIS: return("Gravis Ultrasound patch"); break; case MUS_COMDISCO: return("Comdisco SPW signal"); break; case MUS_GOLDWAVE: return("Goldwave sample"); break; case MUS_SRFS: return("SRFS"); break; case MUS_MIDI_SAMPLE_DUMP: return("MIDI sample dump"); break; case MUS_DIAMONDWARE: return("DiamondWare"); break; case MUS_ADF: return("CSRE adf"); break; case MUS_SBSTUDIOII: return("SBStudioII"); break; case MUS_DELUSION: return("Delusion"); break; case MUS_FARANDOLE: return("Farandole"); break; case MUS_SAMPLE_DUMP: return("Sample dump"); break; case MUS_ULTRATRACKER: return("Ultratracker"); break; case MUS_YAMAHA_TX16W: return("TX-16W"); break; case MUS_YAMAHA_SY85: return("Sy-85"); break; case MUS_YAMAHA_SY99: return("Sy-99"); break; case MUS_KURZWEIL_2000: return("Kurzweil 2000"); break; case MUS_KORG: return("Korg"); break; case MUS_MAUI: return("Turtle Beach"); break; case MUS_IMPULSETRACKER: return("Impulse Tracker"); break; case MUS_AKAI4: return("AKAI 4"); break; case MUS_DIGIPLAYER: return("Digiplayer ST3"); break; case MUS_COVOX: return("Covox V8"); break; case MUS_AVI: return("AVI"); break; case MUS_OMF: return("OMF"); break; case MUS_QUICKTIME: return("Quicktime"); break; case MUS_ASF: return("asf"); break; case MUS_AIFF: return("AIFF"); break; case MUS_PAF: return("Ensoniq Paris"); break; case MUS_CSL: return("CSL"); break; case MUS_FILE_SAMP: return("snack SMP"); break; case MUS_PVF: return("Portable Voice Format"); break; case MUS_SOUNDFORGE: return("SoundForge"); break; case MUS_TWINVQ: return("TwinVQ"); break; case MUS_SDIF: return("IRCAM sdif"); break; #if G7XX case MUS_NVF: return("Creative NVF"); break; #endif case MUS_OGG: return("Ogg Vorbis"); break; case MUS_FLAC: return("Flac"); break; case MUS_SPEEX: return("Speex"); break; case MUS_MPEG: return("mpeg"); break; case MUS_SHORTEN: return("shorten"); break; case MUS_TTA: return("tta"); break; case MUS_WAVPACK: return("wavpack"); break; case MUS_RF64: return("rf64"); break; case MUS_CAFF: return("caff"); break; default: return("unknown"); break; } } const char *mus_sample_type_name(mus_sample_t samp_type) { switch (samp_type) { case MUS_BSHORT: return("big endian short (16 bits)"); break; case MUS_MULAW: return("mulaw (8 bits)"); break; case MUS_BYTE: return("signed byte (8 bits)"); break; case MUS_BFLOAT: return("big endian float (32 bits)"); break; case MUS_BFLOAT_UNSCALED: return("big endian float (32 bits, unscaled)"); break; case MUS_BINT: return("big endian int (32 bits)"); break; case MUS_ALAW: return("alaw (8 bits)"); break; case MUS_UBYTE: return("unsigned byte (8 bits)"); break; case MUS_B24INT: return("big endian int (24 bits)"); break; case MUS_BDOUBLE: return("big endian double (64 bits)"); break; case MUS_BDOUBLE_UNSCALED: return("big endian double (64 bits, unscaled)"); break; case MUS_LSHORT: return("little endian short (16 bits)"); break; case MUS_LINT: return("little endian int (32 bits)"); break; case MUS_LFLOAT: return("little endian float (32 bits)"); break; case MUS_LDOUBLE: return("little endian double (64 bits)"); break; case MUS_LFLOAT_UNSCALED: return("little endian float (32 bits, unscaled)"); break; case MUS_LDOUBLE_UNSCALED: return("little endian double (64 bits, unscaled)"); break; case MUS_UBSHORT: return("unsigned big endian short (16 bits)"); break; case MUS_ULSHORT: return("unsigned little endian short (16 bits)"); break; case MUS_L24INT: return("little endian int (24 bits)"); break; case MUS_BINTN: return("normalized big endian int (32 bits)"); break; case MUS_LINTN: return("normalized little endian int (32 bits)"); break; default: return("unknown"); break; } } const char *mus_sample_type_short_name(mus_sample_t samp_type) { switch (samp_type) { case MUS_BSHORT: return("short int"); break; case MUS_MULAW: return("mulaw"); break; case MUS_BYTE: return("signed byte"); break; case MUS_BFLOAT: return("float"); break; case MUS_BFLOAT_UNSCALED: return("float unscaled)"); break; case MUS_BINT: return("int"); break; case MUS_ALAW: return("alaw"); break; case MUS_UBYTE: return("unsigned byte"); break; case MUS_B24INT: return("24-bit int"); break; case MUS_BDOUBLE: return("double"); break; case MUS_BDOUBLE_UNSCALED: return("double unscaled"); break; case MUS_LSHORT: return("short int"); break; case MUS_LINT: return("int"); break; case MUS_LFLOAT: return("float"); break; case MUS_LDOUBLE: return("double"); break; case MUS_LFLOAT_UNSCALED: return("float unscaled"); break; case MUS_LDOUBLE_UNSCALED: return("double unscaled"); break; case MUS_UBSHORT: return("unsigned short"); break; case MUS_ULSHORT: return("unsigned short"); break; case MUS_L24INT: return("24-bit int"); break; case MUS_BINTN: return("normalized int"); break; case MUS_LINTN: return("normalized int"); break; default: return("unknown"); break; } } #if HAVE_RUBY #define TO_LANG(Str) (const char *)xen_scheme_constant_to_ruby(Str) #else #define TO_LANG(Str) Str #endif const char *mus_header_type_to_string(mus_header_t type) { switch (type) { case MUS_NEXT: return(TO_LANG(S_mus_next)); case MUS_AIFF: return(TO_LANG(S_mus_aiff)); case MUS_AIFC: return(TO_LANG(S_mus_aifc)); case MUS_RIFF: return(TO_LANG(S_mus_riff)); case MUS_NIST: return(TO_LANG(S_mus_nist)); case MUS_IRCAM: return(TO_LANG(S_mus_ircam)); case MUS_RAW: return(TO_LANG(S_mus_raw)); case MUS_BICSF: return(TO_LANG(S_mus_bicsf)); case MUS_VOC: return(TO_LANG(S_mus_voc)); case MUS_SVX: return(TO_LANG(S_mus_svx)); case MUS_SOUNDFONT: return(TO_LANG(S_mus_soundfont)); case MUS_RF64: return(TO_LANG(S_mus_rf64)); case MUS_CAFF: return(TO_LANG(S_mus_caff)); default: break; } return(NULL); } const char *mus_sample_type_to_string(mus_sample_t samp_type) { switch (samp_type) { case MUS_BSHORT: return(TO_LANG(S_mus_bshort)); case MUS_LSHORT: return(TO_LANG(S_mus_lshort)); case MUS_MULAW: return(TO_LANG(S_mus_mulaw)); case MUS_ALAW: return(TO_LANG(S_mus_alaw)); case MUS_BYTE: return(TO_LANG(S_mus_byte)); case MUS_UBYTE: return(TO_LANG(S_mus_ubyte)); case MUS_BFLOAT: return(TO_LANG(S_mus_bfloat)); case MUS_LFLOAT: return(TO_LANG(S_mus_lfloat)); case MUS_BINT: return(TO_LANG(S_mus_bint)); case MUS_LINT: return(TO_LANG(S_mus_lint)); case MUS_BINTN: return(TO_LANG(S_mus_bintn)); case MUS_LINTN: return(TO_LANG(S_mus_lintn)); case MUS_B24INT: return(TO_LANG(S_mus_b24int)); case MUS_L24INT: return(TO_LANG(S_mus_l24int)); case MUS_BDOUBLE: return(TO_LANG(S_mus_bdouble)); case MUS_LDOUBLE: return(TO_LANG(S_mus_ldouble)); case MUS_UBSHORT: return(TO_LANG(S_mus_ubshort)); case MUS_ULSHORT: return(TO_LANG(S_mus_ulshort)); case MUS_BDOUBLE_UNSCALED: return(TO_LANG(S_mus_bdouble_unscaled)); case MUS_LDOUBLE_UNSCALED: return(TO_LANG(S_mus_ldouble_unscaled)); case MUS_BFLOAT_UNSCALED: return(TO_LANG(S_mus_bfloat_unscaled)); case MUS_LFLOAT_UNSCALED: return(TO_LANG(S_mus_lfloat_unscaled)); default: break; } return(NULL); } static const char *any_sample_type_name(mus_sample_t sndlib_samp_type) { if (mus_is_sample_type(sndlib_samp_type)) return(mus_sample_type_name(sndlib_samp_type)); else return(mus_header_original_sample_type_name(mus_header_original_sample_type(), mus_header_type())); } #define SEEK_FILE_LENGTH(File) lseek(File, 0L, SEEK_END) static int read_bicsf_header(const char *filename, int fd); /* ------------------------------------ NeXT (or Sun) -------------------------------- * * 0: ".snd" * 4: data_location (bytes) (not necessarily word aligned on Sun) * 8: data_size (bytes) -- sometimes incorrect ("advisory") * 12: sample type indicator -- see below * 16: srate (int) * 20: chans * 24: comment start * * in an AFsp file, the first 4 bytes of the comment are "AFsp", * for bicsf, the integer at 28 is 107364 or 107415 * * on NeXTStep, always big-endian. ".snd"==0x2e736e64 on big-endian machines. * * formats are: * 0 unspecified, 1 mulaw_8, 2 linear_8, 3 linear_16, 4 linear_24, 5 linear_32, 6 float, * 7 double, 8 indirect, 9 nested, 10 dsp_core, 11 dsp_data_8, 12 dsp_data_16, 13 dsp_data_24, * 14 dsp_data_32, 16 display, 17 mulaw_squelch, 18 emphasized, 19 compressed, 20 compressed_emphasized * 21 dsp_commands, 22 dsp_commands_samples, 23 adpcm_g721, 24 adpcm_g722, 25 adpcm_g723, * 26 adpcm_g723_5, 27 alaw_8, 28 aes, 29 delat_mulaw_8 * internal Snd(lib)-only formats: * 30: mus_lint, 31: mus_lfloat, * 32: mus_bintn, 33: mus_lintn, * 34: mus_ldouble and others... (added by me for Snd internal use) */ /* according to the file /usr/share/magic, the DECN versions were little endian */ static int read_next_header(const char *filename, int fd) { int maybe_bicsf, err = MUS_NO_ERROR, i; type_specifier = mus_char_to_uninterpreted_int((unsigned char *)hdrbuf); data_location = mus_char_to_ubint((unsigned char *)(hdrbuf + 4)); if (data_location < 24) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data location: %lld?", filename, data_location)); data_size = mus_char_to_ubint((unsigned char *)(hdrbuf + 8)); /* changed to unsigned 11-Nov-06 */ /* can be bogus -- fixup if possible */ true_file_length = SEEK_FILE_LENGTH(fd); if ((data_size <= 24) || (data_size > true_file_length)) data_size = (true_file_length - data_location); else { if (true_file_length > (mus_long_t)0x80000000) /* (1 << 31)) */ data_size = true_file_length - data_location; /* assume size field overflowed 32 bits */ } original_sample_type = mus_char_to_bint((unsigned char *)(hdrbuf + 12)); switch (original_sample_type) { case 1: sample_type = MUS_MULAW; break; case 2: sample_type = MUS_BYTE; break; /* some sound files assume MUS_UBYTE here! (NAS from 1994 X11R6 contrib) */ case 3: sample_type = MUS_BSHORT; break; case 4: sample_type = MUS_B24INT; break; case 5: sample_type = MUS_BINT; break; case 6: sample_type = MUS_BFLOAT; break; case 7: sample_type = MUS_BDOUBLE; break; case 18: sample_type = MUS_BSHORT; break; /* "emphasized": Xavier Serra's de-emphasis filter: y(n) = x(n) + .9 y(n-1) */ case 27: sample_type = MUS_ALAW; break; case 30: sample_type = MUS_LINT; break; /* from here on, for Snd's internal benefit -- these are probably not used elsewhere */ case 31: sample_type = MUS_LFLOAT; break; case 32: sample_type = MUS_BINTN; break; case 33: sample_type = MUS_LINTN; break; case 34: sample_type = MUS_LDOUBLE; break; case 35: sample_type = MUS_ULSHORT; break; case 36: sample_type = MUS_UBSHORT; break; case 37: sample_type = MUS_LFLOAT_UNSCALED; break; case 38: sample_type = MUS_BFLOAT_UNSCALED; break; case 39: sample_type = MUS_LDOUBLE_UNSCALED; break; case 40: sample_type = MUS_BDOUBLE_UNSCALED; break; case 41: sample_type = MUS_LSHORT; break; case 42: sample_type = MUS_L24INT; break; case 43: sample_type = MUS_UBYTE; break; default: sample_type = MUS_UNKNOWN_SAMPLE; break; } srate = mus_char_to_bint((unsigned char *)(hdrbuf + 16)); chans = mus_char_to_bint((unsigned char *)(hdrbuf + 20)); comment_start = 0; comment_end = 0; for (i = 24; i < data_location - 1; i++) if (hdrbuf[i] == '\0') break; else { if (hdrbuf[i] != ' ') { comment_start = i; comment_end = data_location - 1; break; } } if (comment_end < comment_start) comment_end = comment_start; maybe_bicsf = mus_char_to_bint((unsigned char *)(hdrbuf + 28)); if (maybe_bicsf == 107364) err = read_bicsf_header(filename, fd); data_size = mus_bytes_to_samples(sample_type, data_size); return(err); } static int sndlib_format_to_next(mus_sample_t samp_type) { switch (samp_type) { case MUS_MULAW: return(1); break; case MUS_BYTE: return(2); break; case MUS_BSHORT: return(3); break; case MUS_B24INT: return(4); break; case MUS_BINT: return(5); break; case MUS_BFLOAT: return(6); break; case MUS_BDOUBLE: return(7); break; case MUS_ALAW: return(27); break; case MUS_LINT: return(30); break; /* see above */ case MUS_LFLOAT: return(31); break; case MUS_BINTN: return(32); break; case MUS_LINTN: return(33); break; case MUS_LDOUBLE: return(34); break; case MUS_ULSHORT: return(35); break; case MUS_UBSHORT: return(36); break; case MUS_LFLOAT_UNSCALED: return(37); break; case MUS_BFLOAT_UNSCALED: return(38); break; case MUS_LDOUBLE_UNSCALED: return(39); break; case MUS_BDOUBLE_UNSCALED: return(40); break; case MUS_LSHORT: return(41); break; case MUS_L24INT: return(42); break; case MUS_UBYTE: return(43); break; default: return(mus_error(MUS_UNSUPPORTED_SAMPLE_TYPE, "Next header: can't write sample type: %d (%s)", samp_type, any_sample_type_name(samp_type))); break; } } static int header_write(int fd, unsigned char *buf, int chars) { if (chars > 0) { long long int bytes; bytes = (long long int)write(fd, buf, chars); if (bytes != chars) { char *errstr = NULL; errstr = STRERROR(errno); return(mus_error(MUS_WRITE_ERROR, "header_write: wrote %lld of %d bytes, %s", bytes, chars, (errstr) ? errstr : "unknown error?")); } } return(MUS_NO_ERROR); } static int header_read(int fd, unsigned char *buf, int chars) { if (chars > 0) { long long int bytes; bytes = (long long int)read(fd, buf, chars); if (bytes != chars) { char *errstr = NULL; errstr = STRERROR(errno); return(mus_error(MUS_READ_ERROR, "header_read: read %lld of %d bytes, %s", bytes, chars, (errstr) ? errstr : "unknown error?")); } } return(MUS_NO_ERROR); } static void write_next_comment(int fd, const char *comment, int len, int loc) { if (len > 0) header_write(fd, (unsigned char *)comment, len); len = loc - (len + 24); if (len > 0) { unsigned char *combuf; combuf = (unsigned char *)calloc(len, sizeof(unsigned char)); header_write(fd, combuf, len); free(combuf); } } static int mus_header_write_next_header(int fd, int wsrate, int wchans, int loc, int siz, mus_sample_t samp_type, const char *comment, int len) { int i, j; write_four_chars((unsigned char *)hdrbuf, I_DSND); /* ".snd" */ i = len / 4; j = 24 + (4 * (i + 1)); if (loc < j) loc = j; mus_bint_to_char((unsigned char *)(hdrbuf + 4), loc); mus_bint_to_char((unsigned char *)(hdrbuf + 8), siz); mus_bint_to_char((unsigned char *)(hdrbuf + 12), sndlib_format_to_next(samp_type)); mus_bint_to_char((unsigned char *)(hdrbuf + 16), wsrate); mus_bint_to_char((unsigned char *)(hdrbuf + 20), wchans); header_write(fd, hdrbuf, 24); write_next_comment(fd, comment, len, loc); data_location = loc; return(MUS_NO_ERROR); } /* ------------------------------------ AIFF ------------------------------------ * * 0: "FORM" * 4: size (bytes) * 8: "AIFF" or "AIFC" -- the latter includes compressed formats (list extended for 8.5 Sound.h) * * Thereafter the file is organized into "chunks", each chunk being * a 4-byte identifer followed by an int (4-bytes) giving the chunk size * not including the 8-byte header. AIFF data is signed. If the chunk * size is odd, an extra (unaccounted-for) null byte is added at the end. * * The chunks we want are "COMM", "SSND", and "APPL". * * COMM: 0: chans * 2: framples * 6: bits per sample * 8: srate as 80-bit IEEE float * then if AIFC (not AIFF), 4 bytes giving compression id ("NONE"=not compressed) * followed by Pascal string giving long name of compression type * * SSND: 0: data location (offset within SSND chunk) * * Other chunks include: ANNO: a comment, INST: loop control, MARK: marker, MIDI: midi, * COMT: comment (max 65536 chars), NAME: sound name, AUTH: author's name * (c), AESD: recording data, APPL: application specific stuff * "MARK" size short-#marks {marks} -- latter are short-ID long-position pstring-name. * "INST" size chars[baseNote detune lowNote highNote lowVelocity HighVelocity] short-gain loops[sustain release] * loop: short-playMode marker-begin marker-end (signed?) shorts) * playMode: 0 no loop, 1 forward loop, 2 forward/backward loop * chars are MIDI data (detune is in cents) * "MIDI" size MIDI-data... * "AESD" size AES Channel Status Data (24 bytes as specified by AES) * see "AES: Guidelines for the use of the AES3 interface" * byte 0: bit 0: 0 = consumer, 1 = pro * bit 1: 0 = audio, 1 = non-audio * bits 2:4: emphasis: 0:none, 4:none, 6:CD, 7:CCITT J17 * bits 6:7: srate: 00 = 48KHz, 01 = 48, 10 = 44.1, 11 = 32 * byte 1: bits 0:3: chans: 2:mono, else stereo * byte 2 for word size stuff (always ends up 16-bit): bits 3-5 = sample length where 4 = 16-bit * byte 3: multi-channels modes, 4: AES sync ref, 5:unused, 6-9:ASCII source ID, 10-13:ASCII destination ID * byte 14-17:local sample addr, 18-21:time of day addr, then CRC checks * "APPL" size signature data * "COMT" size short-#comments {comments} -- the latter are long-time marker short-text-length char-text * time is in seconds since 1-Jan-1904 * "NAME"/"AUTH"/"(c) "/"ANNO" size char-name * "FVER" size(4) AIFC-format-version -- currently always 0xA2805140 * "SAXL" -- a desperate kludge to get around Apple's own compression schemes! * * always big-endian * There was also (briefly) an AIFS file, now deprecated. */ /* ieee-80 conversions -- design by committee! */ /* this code taken from CSound sources -- apparently originally written by Malcolm Slaney at Apple */ #define ULPOW2TO31 ((unsigned int)0x80000000) #define DPOW2TO31 ((double)2147483648.0) /* 2^31 */ static double myUlongToDouble(unsigned int ul) { double val; if (ul & ULPOW2TO31) val = DPOW2TO31 + (ul & (~ULPOW2TO31)); else val = ul; return val; } static unsigned int myDoubleToUlong(double val) { unsigned int ul; if (val < DPOW2TO31) ul = (unsigned int)val; else ul = ULPOW2TO31 | (unsigned int)(val-DPOW2TO31); return ul; } static double ieee_80_to_double(unsigned char *p) { unsigned char sign; short lexp = 0; unsigned int mant1 = 0; unsigned int mant0 = 0; lexp = *p++; lexp <<= 8; lexp |= *p++; sign = (lexp & 0x8000) ? 1 : 0; lexp &= 0x7FFF; mant1 = *p++; mant1 <<= 8; mant1 |= *p++; mant1 <<= 8; mant1 |= *p++; mant1 <<= 8; mant1 |= *p++; mant0 = *p++; mant0 <<= 8; mant0 |= *p++; mant0 <<= 8; mant0 |= *p++; mant0 <<= 8; mant0 |= *p++; if (mant1 == 0 && mant0 == 0 && lexp == 0 && sign == 0) return 0.0; else { double val; val = myUlongToDouble(mant0) * pow(2.0, -63.0); val += myUlongToDouble(mant1) * pow(2.0, -31.0); val *= pow(2.0, ((double) lexp) - 16383.0); return sign ? -val : val; } } static void double_to_ieee_80(double val, unsigned char *p) { short lexp = 0; unsigned char sign = 0; unsigned int mant1 = 0; unsigned int mant0 = 0; if (val < 0.0) { sign = 1; val = -val; } if (val != 0.0) /* val identically zero -> all elements zero */ { lexp = (short)(log(val) / log(2.0) + 16383.0); val *= pow(2.0, 31.0 + 16383.0 - (double)lexp); mant1 = myDoubleToUlong(val); val -= myUlongToDouble(mant1); val *= pow(2.0, 32.0); mant0 = myDoubleToUlong(val); } *p++ = ((sign << 7) | (lexp >> 8)); *p++ = 0xFF & lexp; *p++ = 0xFF & (mant1 >> 24); *p++ = 0xFF & (mant1 >> 16); *p++ = 0xFF & (mant1 >> 8); *p++ = 0xFF & (mant1); *p++ = 0xFF & (mant0 >> 24); *p++ = 0xFF & (mant0 >> 16); *p++ = 0xFF & (mant0 >> 8); *p++ = 0xFF & (mant0); } static mus_long_t update_form_size, update_framples_location, update_ssnd_location, update_rf64_location; static long long int seek_and_read(int fd, unsigned char *buf, mus_long_t offset, int nbytes) { if (offset < 0) return(-1); lseek(fd, offset, SEEK_SET); return(read(fd, buf, nbytes)); } static int read_aiff_marker(int m, unsigned char *buf) { int psize; marker_ids[m] = mus_char_to_bshort((unsigned char *)buf); marker_positions[m] = mus_char_to_bint((unsigned char *)(buf + 2)); psize = (int)buf[6] + 1; if (psize & 1) psize++; return(psize+6); } static void read_aif_mark_chunk(int fd, unsigned char *buf, mus_long_t offset) { int num_marks, m, moff, msize; /* unsigned short #marks, each mark: id pos name (pstring damn it) */ num_marks = mus_char_to_ubshort((unsigned char *)(buf + 8)); if (num_marks > markers) { if (markers > 0) { if (marker_ids) free(marker_ids); if (marker_positions) free(marker_positions); } markers = num_marks; marker_ids = (int *)calloc(markers, sizeof(int)); marker_positions = (int *)calloc(markers, sizeof(int)); } moff = 10; for (m = 0; m < num_marks; m++) { if (seek_and_read(fd, (unsigned char *)buf, offset + moff, 8) > 0) { msize = read_aiff_marker(m, (unsigned char *)buf); moff += msize; } } } static void read_aif_inst_chunk(unsigned char *buf) { base_note = buf[8]; base_detune = buf[9]; loop_modes[0] = mus_char_to_bshort((unsigned char *)(buf + 16)); loop_starts[0] = mus_char_to_bshort((unsigned char *)(buf + 18)); loop_ends[0] = mus_char_to_bshort((unsigned char *)(buf + 20)); loop_modes[1] = mus_char_to_bshort((unsigned char *)(buf + 22)); loop_starts[1] = mus_char_to_bshort((unsigned char *)(buf + 24)); loop_ends[1] = mus_char_to_bshort((unsigned char *)(buf + 26)); /* these are mark numbers */ } static void read_aif_aux_comment(unsigned char *buf, mus_long_t offset, int chunksize) { int i, j = 0; for (i = 0; i < AUX_COMMENTS; i++) if (aux_comment_start[i] == 0) { j = i; break; } if (j >= AUX_COMMENTS) { mus_print("read_aiff_header: ran out of auxiliary comment space"); j = 0; } aux_comment_start[j] = offset + 8; if (match_four_chars((unsigned char *)buf, I_COMT)) aux_comment_start[j] += 8; /* skip time stamp and markerId (not ID, I assume!) */ aux_comment_end[j] = offset + 7 + chunksize; } static void read_aif_appl_chunk(unsigned char *buf, mus_long_t offset, int chunksize) { static const unsigned char I_SU7M[4] = {'S','U','7','M'}; static const unsigned char I_SU7R[4] = {'S','U','7','R'}; if (match_four_chars((unsigned char *)(buf + 8), I_MUS_)) { /* my chunk has an arbitrary length comment (a lisp program evaluated in the CLM package) * to handle mix et al. Can't use the built-in chunk for this because the comment length might * be greater than 65536 chars. Need to remember to pad to even length here. */ comment_start = offset + 12; comment_end = comment_start + chunksize - 5; } else { if ((match_four_chars((unsigned char *)(buf + 8), I_SU7M)) || (match_four_chars((unsigned char *)(buf + 8), I_SU7R))) { mus_print("this is an SU700 ssp file?"); data_location = 512; chans = 1; /* actually SU7M and SU7R point to 2 chan data as separate chunks */ } } } static int read_aiff_header(const char *filename, int fd, int overall_offset) { /* we know we have checked for FORM xxxx AIFF|AIFC when we arrive here */ /* as far as I can tell, the COMM block has the header data we seek, and the SSND block has the sound data */ int chunkloc, i, ssnd_bytes = 0; bool happy = true, got_comm = false; mus_long_t offset = 0; type_specifier = mus_char_to_uninterpreted_int((unsigned char *)(hdrbuf + 8 + overall_offset)); update_ssnd_location = 0; chunkloc = 12 + overall_offset; for (i = 0; i < AUX_COMMENTS; i++) aux_comment_start[i] = 0; sample_type = MUS_BSHORT; srate = 0; chans = 0; markers = 0; if (marker_ids) free(marker_ids); if (marker_positions) free(marker_positions); marker_ids = NULL; marker_positions = NULL; true_file_length = SEEK_FILE_LENGTH(fd); update_form_size = mus_char_to_ubint((unsigned char *)(hdrbuf + 4 + overall_offset)); /* should be file-size - 8 unless there are multiple forms */ while (happy) { int chunksize; offset += chunkloc; if (seek_and_read(fd, (unsigned char *)hdrbuf, offset, 32) <= 0) { if ((got_comm) && (data_location > 0)) { mus_print("%s, aiff header: chunks confused at %lld; will try to continue", filename, offset); break; } return(mus_error(MUS_HEADER_READ_FAILED, "%s, aiff header: chunks confused at %lld" , filename, offset)); } chunksize = mus_char_to_bint((unsigned char *)(hdrbuf + 4)); if ((chunksize == 0) && /* can be empty data chunk */ (hdrbuf[0] == 0) && (hdrbuf[1] == 0) && (hdrbuf[2] == 0) && (hdrbuf[3] == 0)) break; if (chunksize < 0) break; /* fprintf(stderr, "chunk: %c%c%c%c for %d\n", hdrbuf[0], hdrbuf[1], hdrbuf[2], hdrbuf[3], chunksize); */ if (match_four_chars((unsigned char *)hdrbuf, I_COMM)) { int framples; got_comm = true; chans = mus_char_to_bshort((unsigned char *)(hdrbuf + 8)); framples = mus_char_to_ubint((unsigned char *)(hdrbuf + 10)); /* was bint 27-Jul-01 */ update_framples_location = 10 + offset; original_sample_type = mus_char_to_bshort((unsigned char *)(hdrbuf + 14)); if ((original_sample_type % 8) != 0) { /* weird sizes are legal -- * these samples are left-justified (and zero padded on the right), so * we can handle any bit size by rounding up to the nearest byte. */ original_sample_type = 8 * (1 + (original_sample_type >> 3)); } if (original_sample_type == 8) sample_type = MUS_BYTE; else if (original_sample_type == 16) sample_type = MUS_BSHORT; else if (original_sample_type == 24) sample_type = MUS_B24INT; else if (original_sample_type == 32) sample_type = MUS_BINT; else if (original_sample_type == 64) sample_type = MUS_BDOUBLE; else return(mus_error(MUS_HEADER_READ_FAILED, "%s: bits per sample: %d?", filename, mus_char_to_bshort((unsigned char *)(hdrbuf + 14)))); srate = (int)ieee_80_to_double((unsigned char *)(hdrbuf + 16)); /* if AIFC, compression type over-rides (possibly bogus) original_sample_type */ if (type_specifier == mus_char_to_uninterpreted_int((unsigned const char *)I_AIFC)) { static const unsigned char I_twos[4] = {'t','w','o','s'}; /* AIFC big endian? */ /* some aifc files assume the compression field is a new and very weird chunk!! -- surely a bug? */ /* AIFF spec says COMM size is always 18, but this is amended in the newer AIFC spec */ if (chunksize == 18) chunksize += (5 + ((int)hdrbuf[30])); /* 5 = chunk header length in this case */ if ((!(match_four_chars((unsigned char *)(hdrbuf + 26), I_NONE))) && (!(match_four_chars((unsigned char *)(hdrbuf + 26), I_twos)))) { static const unsigned char I_ALAW[4] = {'A','L','A','W'}; original_sample_type = mus_char_to_uninterpreted_int((unsigned char *)(hdrbuf + 26)); if ((match_four_chars((unsigned char *)(hdrbuf + 26), I_ALAW)) || (match_four_chars((unsigned char *)(hdrbuf + 26), I_alaw))) sample_type = MUS_ALAW; else { if ((match_four_chars((unsigned char *)(hdrbuf + 26), I_ULAW)) || (match_four_chars((unsigned char *)(hdrbuf + 26), I_ulaw))) sample_type = MUS_MULAW; else { static const unsigned char I_ni23[4] = {'n','i','2','3'}; if ((match_four_chars((unsigned char *)(hdrbuf + 26), I_sowt)) || (match_four_chars((unsigned char *)(hdrbuf + 26), I_ni23))) { /* Sound.h sez sowt is just 16-bit format */ if (sample_type == MUS_BSHORT) sample_type = MUS_LSHORT; else if (sample_type == MUS_B24INT) sample_type = MUS_L24INT; else if (sample_type == MUS_BINT) sample_type = MUS_LINT; } else { if (match_four_chars((unsigned char *)(hdrbuf + 26), I_raw_)) { if (sample_type == MUS_BYTE) sample_type = MUS_UBYTE; else if (sample_type == MUS_BSHORT) sample_type = MUS_UBSHORT; } else { unsigned char I_FL32[4] = {'F','L','3','2'}; /* 32-bit float (apparently used by CSound and SoundHack) */ if ((match_four_chars((unsigned char *)(hdrbuf + 26), I_fl32)) || (match_four_chars((unsigned char *)(hdrbuf + 26), I_FL32))) sample_type = MUS_BFLOAT; else { if (match_four_chars((unsigned char *)(hdrbuf + 26), I_fl64)) sample_type = MUS_BDOUBLE; else { static const unsigned char I_ima4[4] = {'i','m','a','4'}; /* AIFC IMA adpcm apparently */ if (match_four_chars((unsigned char *)(hdrbuf + 26), I_ima4)) { block_align = 34; original_sample_type = MUS_AIFF_IMA_ADPCM; } else { static const unsigned char I_in32[4] = {'i','n','3','2'}; if (match_four_chars((unsigned char *)(hdrbuf + 26), I_in32)) sample_type = MUS_BINT; else { static const unsigned char I_in24[4] = {'i','n','2','4'}; if (match_four_chars((unsigned char *)(hdrbuf + 26), I_in24)) sample_type = MUS_B24INT; else { /* others from Sound.h: 0x6D730002, -- Microsoft ADPCM - ACM code 2 0x6D730011, -- DVI/Intel IMA ADPCM - ACM code 17 'MAC3' -- MACE 3:1 'MAC6' -- MACE 6:1 'cdx4' -- CD/XA 4:1 'cdx2' -- CD/XA 2:1 'dvca' -- DV Audio 'QDMC' -- QDesign music 'QDM2' -- QDesign2 music 'Qclp' -- QUALCOMM PureVoice 0x6D730055 -- MPEG Layer 3, CBR only (pre QT4.1) '.mp3' -- MPEG Layer 3, CBR & VBR (QT4.1 and later) openquicktime and ffmpeg have decoders for some of these; all too complex for my taste on a Mac, we could apparently pick up decoders from coreaudio */ sample_type = MUS_UNKNOWN_SAMPLE; } } } } } } } } } } } data_size = (framples * mus_bytes_per_sample(sample_type) * chans); } else { if (match_four_chars((unsigned char *)hdrbuf, I_SSND)) { if (data_location != 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: two SSND chunks found", filename)); update_ssnd_location = offset + 4; data_location = mus_char_to_bint((unsigned char *)(hdrbuf + 8)) + offset + 16; /* Baroque! */ /* offset is where the hdrbuf is positioned in the file, the sound data offset itself is at loc+8 and the */ /* 0-based location of the sound data is at the end of the chunk = 16 (8 = header+4 = offset+4 = blocksize) */ /* the next int can be the block size if the data is block-aligned */ /* only one SSND per AIFF is allowed */ if (chunksize == 0) break; /* this may happen while pre-reading an in-progress output file for updating */ ssnd_bytes = offset + chunksize - data_location + 8; } else { static const unsigned char I_AUTH[4] = {'A','U','T','H'}; if ((match_four_chars((unsigned char *)hdrbuf, I_ANNO)) || (match_four_chars((unsigned char *)hdrbuf, I_COMT)) || (match_four_chars((unsigned char *)hdrbuf, I_NAME)) || (match_four_chars((unsigned char *)hdrbuf, I_AUTH))) read_aif_aux_comment(hdrbuf, offset, chunksize); else { if (match_four_chars((unsigned char *)hdrbuf, I_APPL)) read_aif_appl_chunk(hdrbuf, offset, chunksize); else { if (match_four_chars((unsigned char *)hdrbuf, I_INST)) read_aif_inst_chunk(hdrbuf); else { if (match_four_chars((unsigned char *)hdrbuf, I_MARK)) read_aif_mark_chunk(fd, hdrbuf, offset); } } } } } chunkloc = (8 + chunksize); if (chunksize & 1) chunkloc++; /* extra null appended to odd-length chunks */ if ((offset + chunkloc) >= update_form_size) happy = false; } if (!got_comm) return(mus_error(MUS_HEADER_READ_FAILED, "%s: no COMM chunk", filename)); if (data_location == 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: no SSND (data) chunk", filename)); if (data_size > true_file_length) { data_size = true_file_length - data_location; if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %lld?", filename, data_size)); } if ((data_size > ssnd_bytes) && (sample_type != MUS_UNKNOWN_SAMPLE)) data_size = ssnd_bytes; data_size = mus_bytes_to_samples(sample_type, data_size); return(MUS_NO_ERROR); } static int sndlib_format_to_aiff_bits(mus_sample_t samp_type) { switch (samp_type) { case MUS_BSHORT: case MUS_LSHORT: case MUS_UBSHORT: case MUS_ULSHORT: return(16); break; case MUS_B24INT: case MUS_L24INT: return(24); break; case MUS_BINT: case MUS_LINT: case MUS_BFLOAT: case MUS_LFLOAT: return(32); break; case MUS_BDOUBLE: case MUS_LDOUBLE: return(64); break; case MUS_BYTE: case MUS_UBYTE: case MUS_MULAW: case MUS_ALAW: return(8); break; default: return(mus_error(MUS_UNSUPPORTED_SAMPLE_TYPE, "aiff header: can't write sample type: %d (%s)", samp_type, any_sample_type_name(samp_type))); break; } } static const char *sndlib_format_to_aifc_name(mus_sample_t samp_type) { switch (samp_type) { case MUS_BSHORT: case MUS_B24INT: case MUS_BINT: case MUS_BYTE: return((const char *)I_NONE); break; /* use in24 and in32? */ case MUS_LSHORT: case MUS_L24INT: case MUS_LINT: return((const char *)I_sowt); break; /* should this use ni23? */ case MUS_BFLOAT: return((const char *)I_fl32); break; case MUS_BDOUBLE: return((const char *)I_fl64); break; case MUS_UBYTE: case MUS_UBSHORT: return((const char *)I_raw_); break; case MUS_MULAW: return((const char *)I_ulaw); break; case MUS_ALAW: return((const char *)I_alaw); break; default: return((const char *)I_NONE); break; } } static int write_aif_header(int fd, int wsrate, int wchans, int siz, mus_sample_t samp_type, const char *comment, int len, bool aifc_header) { /* we write the simplest possible AIFC header: AIFC | COMM | APPL-MUS_ if needed | SSND eof. */ /* the assumption being that we're going to be appending sound data once the header is out */ /* INST and MARK chunks added Jul-95 for various programs that expect them (MixView). */ /* set aifc_header to false to get old-style AIFF header */ int i, j, lenhdr = 0, lenloop, curend = 0, extra = 0; lenloop = 38; if ((loop_modes[0] != 0) || (loop_modes[1] != 0)) lenloop = 42 + 28; if (len != 0) { lenhdr = 12; if ((len % 4) != 0) extra = (4 - (len % 4)); } write_four_chars((unsigned char *)hdrbuf, I_FORM); if (aifc_header) mus_bint_to_char((unsigned char *)(hdrbuf + 4), len + 30 + 16 + lenloop + siz + lenhdr + extra + 12 + 10); else mus_bint_to_char((unsigned char *)(hdrbuf + 4), len + 30 + 16 + lenloop + siz + lenhdr + extra); /* * comment length + 4 for AIFF 18+8 for I_COMM info + 16 for I_SSND info + 38 for INST and MARK + * siz for data + 12 for comment header if any + padding == total size - 8 (i.e. FORM header). * INST+MARK (38) added 3-Jul-95 for Notam software compatibility */ if (aifc_header) { static const unsigned char I_FVER[4] = {'F','V','E','R'}; write_four_chars((unsigned char *)(hdrbuf + 8), I_AIFC); header_write(fd, hdrbuf, 12); curend = 12; write_four_chars((unsigned char *)hdrbuf, I_FVER); mus_bint_to_char((unsigned char *)(hdrbuf + 4), 4); mus_bint_to_char((unsigned char *)(hdrbuf + 8), 0xA2805140); } else write_four_chars((unsigned char *)(hdrbuf + 8), I_AIFF); write_four_chars((unsigned char *)(hdrbuf + 12), I_COMM); if (aifc_header) mus_bint_to_char((unsigned char *)(hdrbuf + 16), 18 + 10); else mus_bint_to_char((unsigned char *)(hdrbuf + 16), 18); mus_bshort_to_char((unsigned char *)(hdrbuf + 20), (short)wchans); if (wchans > 0) mus_bint_to_char((unsigned char *)(hdrbuf + 22), siz / (wchans * mus_bytes_per_sample(samp_type))); mus_bshort_to_char((unsigned char *)(hdrbuf + 26), sndlib_format_to_aiff_bits(samp_type)); double_to_ieee_80((double)wsrate, (unsigned char *)(hdrbuf + 28)); if (aifc_header) { char *str; str = (char *)sndlib_format_to_aifc_name(samp_type); write_four_chars((unsigned char *)(hdrbuf + 38), (const unsigned char *)str); (*(unsigned char *)(hdrbuf + 42)) = 4; /* final pad null not accounted-for */ write_four_chars((unsigned char *)(hdrbuf + 43), (const unsigned char *)str); (*(unsigned char *)(hdrbuf + 47)) = 0; i = 48; } else i = 38; if (len != 0) { if (aifc_header) { write_four_chars((unsigned char *)(hdrbuf + 48), I_APPL); mus_bint_to_char((unsigned char *)(hdrbuf + 52), len + 4 + extra); write_four_chars((unsigned char *)(hdrbuf + 56), I_MUS_); i = 60; } else { write_four_chars((unsigned char *)(hdrbuf + 38), I_APPL); mus_bint_to_char((unsigned char *)(hdrbuf + 42), len + 4 + extra); write_four_chars((unsigned char *)(hdrbuf + 46), I_MUS_); i = 50; } for (j = 0; j < len; j++) { if (i == HDRBUFSIZ) { curend += HDRBUFSIZ; header_write(fd, hdrbuf, HDRBUFSIZ); i = 0; } hdrbuf[i] = comment[j]; i++; } if (extra != 0) { if ((i + extra) > HDRBUFSIZ) { curend += i; header_write(fd, hdrbuf, i); i = 0; } for (j = 0; j < extra; j++) { hdrbuf[i] = 0; i++; } } } curend += i; header_write(fd, hdrbuf, i); if ((loop_modes[0] == 0) && (loop_modes[1] == 0)) { write_four_chars((unsigned char *)hdrbuf, I_MARK); /* SoundHack includes a blank MARK chunk for some reason */ mus_bint_to_char((unsigned char *)(hdrbuf + 4), 2); mus_bshort_to_char((unsigned char *)(hdrbuf + 8), 0); write_four_chars((unsigned char *)(hdrbuf + 10), I_INST); mus_bint_to_char((unsigned char *)(hdrbuf + 14), 20); mus_bint_to_char((unsigned char *)(hdrbuf + 18), 0x3c00007f); /* base-note = middle C, detune = 0, lownote = 0, highnote = 0x7f */ mus_bint_to_char((unsigned char *)(hdrbuf + 22), 0x017f0000); /* lowvelocity = 1, highvelocity = 0x7f, gain = 0 */ mus_bint_to_char((unsigned char *)(hdrbuf + 26), 0); /* no loops */ mus_bint_to_char((unsigned char *)(hdrbuf + 30), 0); mus_bint_to_char((unsigned char *)(hdrbuf + 34), 0); header_write(fd, hdrbuf, 38); curend += 38; } else { write_four_chars((unsigned char *)hdrbuf, I_MARK); mus_bint_to_char((unsigned char *)(hdrbuf + 4), 8 * 4 + 2); /* 2 for mark#, then 2:id + 4:pos + 2:pstr */ /* loop_info: 0..3 are markers positions (ids 1..4) */ mus_bshort_to_char((unsigned char *)(hdrbuf + 8), 4); for (j = 0; j < 4; j++) { mus_bshort_to_char((unsigned char *)(hdrbuf + 10 + 8 * j), j + 1); switch (j) { case 0: mus_bint_to_char((unsigned char *)(hdrbuf + 10 + 8 * j + 2), loop_starts[0]); break; case 1: mus_bint_to_char((unsigned char *)(hdrbuf + 10 + 8 * j + 2), loop_ends[0]); break; case 2: mus_bint_to_char((unsigned char *)(hdrbuf + 10 + 8 * j + 2), loop_starts[1]); break; case 3: mus_bint_to_char((unsigned char *)(hdrbuf + 10 + 8 * j + 2), loop_ends[1]); break; } mus_bshort_to_char((unsigned char *)(hdrbuf + 10 + 8 * j + 6), 0); } header_write(fd, hdrbuf, 42); curend += 42; write_four_chars((unsigned char *)hdrbuf, I_INST); mus_bint_to_char((unsigned char *)(hdrbuf + 4), 20); mus_bint_to_char((unsigned char *)(hdrbuf + 8), 0x3c00007f); mus_bint_to_char((unsigned char *)(hdrbuf + 12), 0x017f0000); hdrbuf[8] = (unsigned char)(base_note); hdrbuf[9] = (unsigned char)(base_detune); mus_bshort_to_char((unsigned char *)(hdrbuf + 16), loop_modes[0]); mus_bshort_to_char((unsigned char *)(hdrbuf + 18), 1); mus_bshort_to_char((unsigned char *)(hdrbuf + 20), 2); mus_bshort_to_char((unsigned char *)(hdrbuf + 22), loop_modes[1]); mus_bshort_to_char((unsigned char *)(hdrbuf + 24), 3); mus_bshort_to_char((unsigned char *)(hdrbuf + 26), 4); header_write(fd, hdrbuf, 28); curend += 28; } write_four_chars((unsigned char *)(hdrbuf), I_SSND); mus_bint_to_char((unsigned char *)(hdrbuf + 4), siz + 8); mus_bint_to_char((unsigned char *)(hdrbuf + 8), 0); /* "offset" */ mus_bint_to_char((unsigned char *)(hdrbuf + 12), 0); /* "blocksize " */ header_write(fd, hdrbuf, 16); data_location = 16 + curend; return(MUS_NO_ERROR); } char *mus_header_aiff_aux_comment(const char *name, mus_long_t *starts, mus_long_t *ends) { /* AIFC: look for aux comments (ANNO chunks) */ char *sc = NULL; if ((starts) && (starts[0] != 0)) { mus_long_t full_len; int fd, i; fd = mus_file_open_read(name); if (fd == -1) return(NULL); full_len = 0; for (i = 0; i < AUX_COMMENTS; i++) if ((starts[i] > 0) && (starts[i] < ends[i])) full_len += (ends[i] - starts[i] + 3); if (full_len > 0) { mus_long_t sc_len; sc = (char *)calloc(full_len, sizeof(char)); sc_len = 0; for (i = 0; i < AUX_COMMENTS; i++) { mus_long_t start, end; start = starts[i]; end = ends[i]; if ((start > 0) && (start < end)) { int j; mus_long_t len; len = end - start + 1; lseek(fd, start, SEEK_SET); header_read(fd, (unsigned char *)(sc + sc_len), len); for (j = 0; j < len; j++) if (sc[j + sc_len] == 0) sc[j + sc_len] = ' '; sc_len += len; sc[sc_len++] = '\n'; } } } CLOSE(fd, name); } return(sc); } /* ------------------------------------ CAFF ------------------------------------ * * this is a new format from Apple ("Core Audio File Format") described at * http://developer.apple.com/documentation/MusicAudio/Reference/CAFSpec * * all chunks as in AIFC but size is signed 64-bit int * * 0: 'caff' * 4: 1 ("version") * 6: 0 ("flags") * 8: 'desc' (required to be in this position) * 12: sizeof apple's CAFAudioFormat struct -- (32) * 20: srate (float64) * 28: format (int32) * 32: format flags * 36: bytes per "packet" * 40: framples per packet * 44: channels per frample * 48: bits per channel * audio data is in 'data' chunk */ static int read_caff_header(int fd) { mus_long_t chunksize = 8, offset = 0; bool happy = false; int err = MUS_NO_ERROR; #define data_is_float (1L << 0) #define data_is_big_endian (1L << 1) /* misleading name -- flag is 1 if data is little endian */ sample_type = MUS_UNKNOWN_SAMPLE; srate = 0; chans = 0; data_size = 0; true_file_length = SEEK_FILE_LENGTH(fd); while (!happy) { offset += chunksize; if (offset >= true_file_length) break; if (seek_and_read(fd, (unsigned char *)hdrbuf, offset, 64) <= 0) break; chunksize = mus_char_to_blong((unsigned char *)(hdrbuf + 4)); if (chunksize < 0) break; /* 'desc' is always the first chunk, but easier to handle in the loop */ if (match_four_chars((unsigned char *)hdrbuf, I_desc)) { int format_flags, channels_per_frample, bits_per_channel; srate = (int)mus_char_to_bdouble((unsigned char *)(hdrbuf + 12)); format_flags = mus_char_to_ubint((unsigned char *)(hdrbuf + 24)); /* bytes_per_packet = mus_char_to_ubint((unsigned char *)(hdrbuf + 28)); */ /* framples_per_packet = mus_char_to_ubint((unsigned char *)(hdrbuf + 32)); */ channels_per_frample = mus_char_to_ubint((unsigned char *)(hdrbuf + 36)); bits_per_channel = mus_char_to_ubint((unsigned char *)(hdrbuf + 40)); chans = channels_per_frample; /* format id can be 'lpcm' 'alaw' 'ulaw' and a bunch of others we ignore */ original_sample_type = mus_char_to_bint((unsigned char *)(hdrbuf + 20)); if (match_four_chars((unsigned char *)(hdrbuf + 20), I_lpcm)) { if (format_flags & data_is_float) { if (!(format_flags & data_is_big_endian)) { if (bits_per_channel == 32) sample_type = MUS_BFLOAT; else { if (bits_per_channel == 64) sample_type = MUS_BDOUBLE; else err = MUS_UNSUPPORTED_SAMPLE_TYPE; } } else { if (bits_per_channel == 32) sample_type = MUS_LFLOAT; else { if (bits_per_channel == 64) sample_type = MUS_LDOUBLE; else err = MUS_UNSUPPORTED_SAMPLE_TYPE; } } } else { if (!(format_flags & data_is_big_endian)) { if (bits_per_channel == 32) sample_type = MUS_BINTN; else { if (bits_per_channel == 24) sample_type = MUS_B24INT; else { if (bits_per_channel == 16) sample_type = MUS_BSHORT; else { if (bits_per_channel == 8) sample_type = MUS_BYTE; else err = MUS_UNSUPPORTED_SAMPLE_TYPE; } } } } else { if (bits_per_channel == 32) sample_type = MUS_LINTN; else { if (bits_per_channel == 24) sample_type = MUS_L24INT; else { if (bits_per_channel == 16) sample_type = MUS_LSHORT; else { if (bits_per_channel == 8) sample_type = MUS_BYTE; else err = MUS_UNSUPPORTED_SAMPLE_TYPE; } } } } } } else { if (match_four_chars((unsigned char *)(hdrbuf + 20), I_alaw)) { sample_type = MUS_ALAW; } else { if (match_four_chars((unsigned char *)(hdrbuf + 20), I_ulaw)) { sample_type = MUS_MULAW; } else err = MUS_UNSUPPORTED_SAMPLE_TYPE; } } } else { if (match_four_chars((unsigned char *)hdrbuf, I_data)) { happy = true; data_location = offset + 16; /* skip the 4 bytes for "edit count" */ update_framples_location = offset + 4; /* here chunksize can be -1! */ if (chunksize > 0) data_size = chunksize; else data_size = true_file_length - data_location; } /* else edct or something for comment? */ } chunksize += 12; } if (err == MUS_NO_ERROR) data_size = mus_bytes_to_samples(sample_type, data_size); return(err); } static int write_caff_header(int fd, int wsrate, int wchans, mus_long_t wsize, mus_sample_t samp_type) { int format_flags = 0, bytes_per_packet = 0, framples_per_packet = 1, bits_per_channel = 0; switch (samp_type) { case MUS_ALAW: bytes_per_packet = 1; bits_per_channel = 8; break; case MUS_MULAW: bytes_per_packet = 1; bits_per_channel = 8; break; default: if ((samp_type == MUS_LFLOAT) || (samp_type == MUS_LDOUBLE) || (samp_type == MUS_BFLOAT) || (samp_type == MUS_BDOUBLE)) format_flags = 1; if ((samp_type == MUS_LFLOAT) || (samp_type == MUS_LDOUBLE) || (samp_type == MUS_LINTN) || (samp_type == MUS_L24INT) || (samp_type == MUS_LSHORT)) format_flags |= 2; switch (samp_type) { case MUS_BYTE: bytes_per_packet = 1; bits_per_channel = 8; break; case MUS_LSHORT: case MUS_BSHORT: bytes_per_packet = 2; bits_per_channel = 16; break; case MUS_L24INT: case MUS_B24INT: bytes_per_packet = 3; bits_per_channel = 24; break; case MUS_LFLOAT: case MUS_BFLOAT: case MUS_BINTN: case MUS_LINTN: bytes_per_packet = 4; bits_per_channel = 32; break; case MUS_LDOUBLE: case MUS_BDOUBLE: bytes_per_packet = 8; bits_per_channel = 64; break; default: break; } break; } bytes_per_packet *= wchans; write_four_chars((unsigned char *)hdrbuf, I_caff); mus_bshort_to_char((unsigned char *)(hdrbuf + 4), 1); mus_bshort_to_char((unsigned char *)(hdrbuf + 6), 0); write_four_chars((unsigned char *)(hdrbuf + 8), I_desc); mus_blong_to_char((unsigned char *)(hdrbuf + 12), 32); mus_bdouble_to_char((unsigned char *)(hdrbuf + 20), (double)wsrate); switch (samp_type) { case MUS_ALAW: write_four_chars((unsigned char *)(hdrbuf + 28), I_alaw); break; case MUS_MULAW: write_four_chars((unsigned char *)(hdrbuf + 28), I_ulaw); break; default: write_four_chars((unsigned char *)(hdrbuf + 28), I_lpcm); break; } mus_bint_to_char((unsigned char *)(hdrbuf + 32), format_flags); mus_bint_to_char((unsigned char *)(hdrbuf + 36), bytes_per_packet); mus_bint_to_char((unsigned char *)(hdrbuf + 40), framples_per_packet); mus_bint_to_char((unsigned char *)(hdrbuf + 44), wchans); mus_bint_to_char((unsigned char *)(hdrbuf + 48), bits_per_channel); write_four_chars((unsigned char *)(hdrbuf + 52), I_data); mus_blong_to_char((unsigned char *)(hdrbuf + 56), wsize); update_framples_location = 56; mus_bint_to_char((unsigned char *)(hdrbuf + 64), 0); data_location = 68; header_write(fd, hdrbuf, 68); return(MUS_NO_ERROR); } /* ------------------------------------ RIFF (wave) ------------------------------------ * * see ftp.microsoft.com:/SoftLib/MSLFILES/MDRK.EXE (also MMSYSTEM.H and MMREG.H) * ftp://ftp.isi.edu/in-notes/rfc2361.txt * * 0: "RIFF" (little-endian) or "RIFX" (big-endian) * 4: size * 8: "WAVE" ("RMID" = midi data, others are AVI, CPPO, ACON, DLS? etc) * AVI chunk can include audio data * * rest very similar to AIFF (odd-sized chunks are padded) * * fmt 0: format code (see below) * 2: chans * 4: srate (long) * 8: average rate "for buffer estimation" * 12: alignment "block size" * 14: data size (bits per sample) (PCM only) * 16: count (bytes) of extra info in the header (i.e. trailing info added to this basic header) * 20: samples per block (short) in dvi_adpcm * * formats are: 0: unknown, 1: PCM, 2: ADPCM, 3: IEEE float, 4: VSELP, 5: IBM_CVSD, 6: alaw, 7: mulaw * 0x10: OKI_ADPCM, 0x11: DVI_ADPCM, 0x12: MediaSpace_ADPCM, * 0x13: Sierra_ADPCM, 0x14: G723_ADPCM, 0x15: DIGISTD, 0x16: DIGIFIX, 0x17: Dialogic ADPCM, * 0x18: Mediavision ADPCM, 0x19: HP cu codec, * 0x20: Yamaha_ADPCM, 0x21: SONARC, 0x22: DSPGroup_TrueSpeech * 0x23: EchoSC1, 0x24: AudioFile_AF36, 0x25: APTX, 0x26: AudioFile_AF10 * 0x27: prosody 1612, 0x28: lrc, * 0x30: Dolby_Ac2, 0x31: GSM610, 0x32: MSN audio codec, 0x33: Antext_ADPCM, 0x34: Control_res_vqlpc, * 0x35: DIGIREAL, 0x36: DIGIADPCM, 0x37: Control_res_cr10, 0x38: NMS_VBXADPCM, 0x39:Roland rdac, * 0x3a: echo sc3, 0x3b: Rockwell adpcm, 0x3c: Rockwell digitalk codec, 0x3d: Xebec, * 0x40: G721_ADPCM, 0x41: G728 CELP, 0x42: MS G723, 0x50: MPEG, * 0x52: RT24, 0x53: PAC, 0x55: Mpeg layer 3, 0x59: Lucent G723, 0x60: Cirrus, * 0x61: ESS Tech pcm, 0x62: voxware (obsolete), 0x63: canopus atrac, * 0x64: G726, 0x65: G722, 0x66: DSAT, 0x67: DSAT display, * 0x69: voxware (obsolete), 0x70: voxware ac8 (obsolete), 0x71: voxware ac10 (obsolete), * 0x72: voxware ac16 (obsolete), 0x73: voxware ac20 (obsolete), 0x74: voxware rt24, * 0x75: voxware rt29, 0x76: voxware rt29hw (obsolete), 0x77: voxware vr12 (obsolete), * 0x78: voxware vr18 (obsolete), 0x79: voxware tq40 (obsolete), * 0x80: softsound, 0x81: voxware tq60 (obsolete), 0x82: MS RT24, 0x83: G729A, * 0x84: MVI_MVI2, 0x85: DF G726, 0x86: DF GSM610, 0x88: isaudio, 0x89: onlive, * 0x91: sbc24, 0x92: dolby ac3 spdif, 0x97: zyxel adpcm, 0x98: philips lpcbb, * 0x99: packed, 0x100: rhetorex adpcm, * 0x101: Irat, 0x102: IBM_alaw?, 0x103: IBM_ADPCM?, * 0x111: vivo G723, 0x112: vivo siren, 0x123: digital g273 * 0x200: Creative_ADPCM, 0x202: Creative fastspeech 8, 0x203: Creative fastspeech 10, * 0x220: quarterdeck, 0x300: FM_TOWNS_SND, 0x400: BTV digital, 0x680: VME vmpcm, * 0x1000: OLIGSM, 0x1001: OLIADPCM, 0x1002: OLICELP, 0x1003: OLISBC, 0x1004: OLIOPR * 0x1100: LH codec, 0x1400: Norris, 0x1401: isaudio, 0x1500: Soundspace musicompression, 0x2000: DVM * (see http://www.microsoft.com/asf/resources/draft-ietf-fleischman-codec-subtree-00.txt) * and new: 0xFFFE: wave_format_extensible: bits/sample, mapping, 16 byte guid, 1st 2 bytes are code as above * * RIFF and LIST chunks have nested chunks. Registered chunk names include: * LIST with subchunks, one of which can be: * INFO itself containing: * IARL: archival location, IART: artist, ICMS: commissioned, ICMT: comment, ICOP: copyright, ICRD: creation date, * ICRP: uh...cropped, IDIM: dimensions, IDPI: dpi, IENG: engineer, IGNR: genre, IKEY: keywords, ILGT: lightness, * IMED: medium, INAM: name, IPLT: palette, IPRD: product, ISBJ: subject, ISFT: software, ISHP: sharpness, * ISRC: source, ISRF: source form, ITCH: technician, ISMP: SMPTE time code, IDIT: digitization time * * data chunk has the samples * other (currently ignored) chunks are wavl = waveform data, fact, cues of some sort, slnt = silence, * plst = playlist, adtl = associated data list, labl = cue label, note = cue comments, * ltxt = text associated with data segment (cue), file, DISP = displayable object, * JUNK = EBU placeholder -- see below, PAD = padding, etc * fact chunk generally has number of samples (used in compressed files) * bext chunk has comments -- perhaps add these to the info/list list? I need an example! -- is the chunk id "bext"? */ static mus_sample_t wave_to_sndlib_format(int osf, int bps, bool little) { switch (osf) { case 1: switch (bps) { case 8: return(MUS_UBYTE); break; case 16: if (little) return(MUS_LSHORT); else return(MUS_BSHORT); break; case 32: if (little) return(MUS_LINT); else return(MUS_BINT); break; case 24: if (little) return(MUS_L24INT); else return(MUS_B24INT); break; default: return(MUS_UBYTE); break; } break; case 3: if (little) { if (bps == 64) return(MUS_LDOUBLE); else return(MUS_LFLOAT); } else { if (bps == 64) return(MUS_BDOUBLE); else return(MUS_BFLOAT); } break; case 6: if (bps == 8) return(MUS_ALAW); break; case 7: if (bps == 8) return(MUS_MULAW); break; /* IBM mulaw follows G711 specs like other versions (this info direct from IBM) */ case 0x101: return(MUS_MULAW); break; case 0x102: return(MUS_ALAW); break; } return(MUS_UNKNOWN_SAMPLE); } static void read_riff_fmt_chunk(unsigned char *hbuf, bool little) { /* fmt chunk (also used in RF64 below) * * 8: short format code --1 = PCM for example * 10: short chans --1 * 12: long rate --48000 (0xbb80) * 16: long ave rate --65655 (0x10077) * 20: short align --2 * 22: short data size (bits) --16 * 24: bytes of extra * ... some extra data dependent on format * * R I F F # # # # W A V E f m t sp * 5249 4646 f851 0500 5741 5645 666d 7420 * e40f 0000 0100 0100 80bb 0000 0077 0100 * 0200 1000 0000 0000 0000 0000 0000 0000 * * #x000551f8 = 348664 = size in bytes - 8 * #x00000fe4 = 4068 [fmt_ chunk size?] */ original_sample_type = big_or_little_endian_short((unsigned char *)(hbuf + 8), little); chans = big_or_little_endian_short((unsigned char *)(hbuf + 10), little); srate = big_or_little_endian_int((unsigned char *)(hbuf + 12), little); block_align = big_or_little_endian_short((unsigned char *)(hbuf + 20), little); bits_per_sample = big_or_little_endian_short((unsigned char *)(hbuf + 22), little); if (original_sample_type == -2) /* 0xFFFE = "extensible" : short size=22, short bits, long chanmap, short format */ original_sample_type = big_or_little_endian_short((unsigned char *)(hbuf + 24 + 8), little); sample_type = wave_to_sndlib_format(original_sample_type, bits_per_sample, little); } static int write_riff_fmt_chunk(int fd, unsigned char *hbuf, mus_sample_t samp_type, int wsrate, int wchans) { int err = MUS_NO_ERROR; write_four_chars((unsigned char *)hbuf, I_fmt_); mus_lint_to_char((unsigned char *)(hbuf + 4), 16); switch (samp_type) { case MUS_MULAW: mus_lshort_to_char((unsigned char *)(hbuf + 8), 7); mus_lshort_to_char((unsigned char *)(hbuf + 22), 8); break; case MUS_ALAW: mus_lshort_to_char((unsigned char *)(hbuf + 8), 6); mus_lshort_to_char((unsigned char *)(hbuf + 22), 8); break; case MUS_UBYTE: mus_lshort_to_char((unsigned char *)(hbuf + 8), 1); mus_lshort_to_char((unsigned char *)(hbuf + 22), 8); break; case MUS_LSHORT: mus_lshort_to_char((unsigned char *)(hbuf + 8), 1); mus_lshort_to_char((unsigned char *)(hbuf + 22), 16); break; case MUS_L24INT: mus_lshort_to_char((unsigned char *)(hbuf + 8), 1); mus_lshort_to_char((unsigned char *)(hbuf + 22), 24); break; case MUS_LINT: mus_lshort_to_char((unsigned char *)(hbuf + 8), 1); mus_lshort_to_char((unsigned char *)(hbuf + 22), 32); break; case MUS_LFLOAT: mus_lshort_to_char((unsigned char *)(hbuf + 8), 3); mus_lshort_to_char((unsigned char *)(hbuf + 22), 32); break; case MUS_LDOUBLE: mus_lshort_to_char((unsigned char *)(hbuf + 8), 3); mus_lshort_to_char((unsigned char *)(hbuf + 22), 64); break; default: /* don't call mus_error directly -- we need to close the file first in mus_header_write */ err = MUS_UNSUPPORTED_SAMPLE_TYPE; break; } mus_lshort_to_char((unsigned char *)(hbuf + 10), (short)wchans); mus_lint_to_char((unsigned char *)(hbuf + 12), wsrate); mus_lint_to_char((unsigned char *)(hbuf + 16), wsrate * wchans * mus_bytes_per_sample(samp_type)); /* added chans 10-Mar-99 */ mus_lshort_to_char((unsigned char *)(hbuf + 20), (short)(wchans * mus_bytes_per_sample(samp_type))); /* 22 short written above = bits/sample */ header_write(fd, hbuf, 24); return(err); } static const unsigned char I_JUNK[4] = {'J','U','N','K'}; static int read_riff_header(const char *filename, int fd) { /* we know we have checked for RIFF xxxx WAVE when we arrive here */ int chunkloc = 12, i; bool little = true, got_fmt = false; mus_long_t offset = 0; if (match_four_chars((unsigned char *)hdrbuf, I_RIFX)) little = false; /* big-endian data in this case, but I've never seen one */ little_endian = little; type_specifier = mus_char_to_uninterpreted_int((unsigned char *)(hdrbuf + 8)); sample_type = MUS_UNKNOWN_SAMPLE; srate = 0; chans = 0; fact_samples = 0; bits_per_sample = 0; for (i = 0; i < AUX_COMMENTS; i++) aux_comment_start[i] = 0; true_file_length = SEEK_FILE_LENGTH(fd); update_form_size = big_or_little_endian_int((unsigned char *)(hdrbuf + 4), little); while (true) { int chunksize; offset += chunkloc; if (offset >= true_file_length) break; if (seek_and_read(fd, (unsigned char *)hdrbuf, offset, 64) <= 0) break; chunksize = big_or_little_endian_int((unsigned char *)(hdrbuf + 4), little); if ((chunksize == 0) && /* can be empty data chunk */ (hdrbuf[0] == 0) && (hdrbuf[1] == 0) && (hdrbuf[2] == 0) && (hdrbuf[3] == 0)) break; if (chunksize < -1) break; if (match_four_chars((unsigned char *)hdrbuf, I_fmt_)) { got_fmt = true; update_framples_location = 12 + offset; read_riff_fmt_chunk(hdrbuf, little); } else { if ((match_four_chars((unsigned char *)hdrbuf, I_data)) && (data_location == 0)) { update_ssnd_location = offset + 4; data_location = offset + 8; data_size = big_or_little_endian_uint((unsigned char *)(hdrbuf + 4), little); /* was int 27-Jul-01 */ if (chunksize == 0) break; /* see aiff comment */ } else { if (match_four_chars((unsigned char *)hdrbuf, I_fact)) { fact_samples = big_or_little_endian_int((unsigned char *)(hdrbuf + 8), little); } else { static const unsigned char I_inst[4] = {'i','n','s','t'}; /* RIFF wants lower case, just to be different */ if (match_four_chars((unsigned char *)hdrbuf, I_inst)) { base_note = hdrbuf[8]; base_detune = hdrbuf[9]; /* rest is gain low-note high-note low-velocity high-velocity */ } else { if (match_four_chars((unsigned char *)hdrbuf, I_clm_)) { comment_start = offset + 8; comment_end = comment_start + chunksize - 1; /* end of comment not start of next chunk */ } else { if ((match_four_chars((unsigned char *)hdrbuf, I_LIST)) && (match_four_chars((unsigned char *)(hdrbuf + 8), I_INFO))) { aux_comment_start[0] = offset + 8; aux_comment_end[0] = offset + 8 + chunksize - 1; } else { if (match_four_chars((unsigned char *)hdrbuf, I_JUNK)) update_rf64_location = offset; } } } } } } chunkloc = (8 + chunksize); if (chunksize & 1) chunkloc++; /* extra null appended to odd-length chunks */ } if (!got_fmt) return(mus_error(MUS_HEADER_READ_FAILED, "%s: no fmt chunk?", filename)); if (data_location == 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: no data chunk?", filename)); if (data_size > true_file_length) { data_size = true_file_length - data_location; if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %lld?", filename, data_size)); } data_size = mus_bytes_to_samples(sample_type, data_size); return(MUS_NO_ERROR); } static void write_riff_clm_comment(int fd, const char *comment, int len, int extra) { int i = 0, j; write_four_chars((unsigned char *)hdrbuf, I_clm_); mus_lint_to_char((unsigned char *)(hdrbuf + 4), len + extra); i = 8; for (j = 0; j < len; j++) { if (i == HDRBUFSIZ) { header_write(fd, hdrbuf, HDRBUFSIZ); i = 0; } hdrbuf[i++] = comment[j]; } if (extra != 0) { if ((i + extra) > HDRBUFSIZ) { header_write(fd, hdrbuf, i); i = 0; } for (j = 0; j < extra; j++) hdrbuf[i++] = 0; } if (i > 0) { header_write(fd, hdrbuf, i); } } static int write_riff_header(int fd, int wsrate, int wchans, int siz, mus_sample_t samp_type, const char *comment, int len) { int j, extra = 0, err = MUS_NO_ERROR; data_location = 36 + 36 + 8; if (len != 0) { if ((len % 4) != 0) extra = (4 - (len % 4)); data_location += (8 + len + extra); } /* 36 = "RIFF" + size(4) + "WAVE" + "fmt " + size(4) + 16 for data */ /* second 36 is for "JUNK" chunk, 8 is data chunk header */ write_four_chars((unsigned char *)hdrbuf, I_RIFF); mus_lint_to_char((unsigned char *)(hdrbuf + 4), data_location + siz - 8); /* added -8 25-June-07 */ write_four_chars((unsigned char *)(hdrbuf + 8), I_WAVE); header_write(fd, hdrbuf, 12); /* add JUNK chunk for possible change to RF64 during write */ write_four_chars((unsigned char *)hdrbuf, I_JUNK); mus_lint_to_char((unsigned char *)(hdrbuf + 4), 28); for (j = 8; j < 36; j++) hdrbuf[j] = 0; header_write(fd, hdrbuf, 36); /* fmt chunk */ err = write_riff_fmt_chunk(fd, hdrbuf, samp_type, wsrate, wchans); /* include possible clm (comment) chunk */ if (len > 0) write_riff_clm_comment(fd, comment, len, extra); /* start the data chunk */ write_four_chars((unsigned char *)hdrbuf, I_data); mus_lint_to_char((unsigned char *)(hdrbuf + 4), siz); header_write(fd, hdrbuf, 8); return(err); } char *mus_header_riff_aux_comment(const char *name, mus_long_t *starts, mus_long_t *ends) { char *sc = NULL, *auxcom; if ((starts) && (starts[0] != 0)) { int j, fd, k, m; mus_long_t i, end; /* found a LIST+INFO chunk (and no other comment) */ fd = mus_file_open_read(name); if (fd == -1) return(NULL); i = starts[0]; end = ends[0]; sc = (char *)calloc(end - i + 2, sizeof(char)); j = 0; k = 4; lseek(fd, i, SEEK_SET); auxcom = (char *)calloc(end - i + 2, sizeof(char)); header_read(fd, (unsigned char *)auxcom, end - i + 1); CLOSE(fd, name); i += 4; while (i < end) { int len; for (m = 0; m < 4; m++) sc[j++] = auxcom[k++]; len = mus_char_to_lint((unsigned char *)(auxcom + k)); if ((len <= 0) || (len > end)) break; sc[j++] = ':'; sc[j++] = ' '; k += 4; for (m = 0; m < len; m++) if (auxcom[k] != 0) sc[j++] = auxcom[k++]; else k++; sc[j++] ='\n'; if (len & 1) { len++; k++; } i += (len + 8); } free(auxcom); } return(sc); } /* ------------------------------------ W64 ------------------------------------ * * soundforge -- just a quick hack until I get better documentation */ static int read_soundforge_header(const char *filename, int fd) { /* like RIFF but lowercase and 64-bit vals */ int i, off; mus_long_t offset, chunkloc; chunkloc = 12 * 2 + 16; offset = 0; sample_type = MUS_UNKNOWN_SAMPLE; srate = 0; chans = 0; fact_samples = 0; bits_per_sample = 0; for (i = 0; i < AUX_COMMENTS; i++) aux_comment_start[i] = 0; true_file_length = SEEK_FILE_LENGTH(fd); update_form_size = mus_char_to_llong((unsigned char *)(hdrbuf + 4 * 2)); while (true) { int chunksize; offset += chunkloc; if (offset >= true_file_length) break; if (seek_and_read(fd, (unsigned char *)hdrbuf, offset, 64) <= 0) break; chunksize = mus_char_to_llong((unsigned char *)(hdrbuf + 16)); if ((chunksize == 0) && /* can be empty data chunk? */ (hdrbuf[0] == 0) && (hdrbuf[1] == 0) && (hdrbuf[2] == 0) && (hdrbuf[3] == 0)) break; if (chunksize < 0) break; if (match_four_chars((unsigned char *)hdrbuf, I_fmt_)) { off = 16; original_sample_type = mus_char_to_lshort((unsigned char *)(hdrbuf + 8 + off)); chans = mus_char_to_lshort((unsigned char *)(hdrbuf + 10 + off)); srate = mus_char_to_lint((unsigned char *)(hdrbuf + 12 + off)); block_align = mus_char_to_lshort((unsigned char *)(hdrbuf + 20 + off)); bits_per_sample = mus_char_to_lshort((unsigned char *)(hdrbuf + 22 + off)); sample_type = wave_to_sndlib_format(original_sample_type, bits_per_sample, true); } else { if ((match_four_chars((unsigned char *)hdrbuf, I_data)) && (data_location == 0)) { data_location = offset + 16 + 8; data_size = mus_char_to_llong((unsigned char *)(hdrbuf + 16)); if (chunksize == 0) break; /* see aiff comment */ } else { if (match_four_chars((unsigned char *)hdrbuf, I_fact)) { fact_samples = mus_char_to_llong((unsigned char *)(hdrbuf + 8)); } } } chunkloc = chunksize % 8; if (chunkloc == 0) chunkloc = chunksize; else chunkloc = chunksize + 8 - chunkloc; /* I think they are rounding up to a multiple of 8 here (sigh) */ } if (data_location == 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: no data chunk?", filename)); if (data_size > true_file_length) { data_size = true_file_length - data_location; if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %lld?", filename, data_size)); } data_size = mus_bytes_to_samples(sample_type, data_size); return(MUS_NO_ERROR); } /* ------------------------------------ RF64 ------------------------------------ * * see http://www.ebu.ch/CMSimages/en/tec_doc_t3306_tcm6-42570.pdf. * * RF64 0xFFFFFFFF WAVE * ds64 size(32) RIFF-size(64) data-size(64) fact-samples(64) table-len table * fmt_ size format-data * data 0xFFFFFFFF data... * * if RIFF WAVE is being written with possibility of overflow size, use * RIFF size WAVE JUNK then the ds64 chunk as above * if size overflows, reset RIFF->RF64, JUNK->ds64, size->-1 twice etc * * JUNK size = 28 * all ints are little endian * */ static int read_rf64_header(const char *filename, int fd) { /* we've checked RF64 xxxx WAVE before getting here */ /* this is very similar (identical) to RIFF for the most part, but I decided it was cleanest to copy the code */ mus_long_t chunkloc; bool got_fmt = false, got_ds64 = false; mus_long_t offset; little_endian = true; type_specifier = mus_char_to_uninterpreted_int((unsigned char *)(hdrbuf + 8)); chunkloc = 12; offset = 0; sample_type = MUS_UNKNOWN_SAMPLE; srate = 0; chans = 0; fact_samples = 0; bits_per_sample = 0; { int i; for (i = 0; i < AUX_COMMENTS; i++) aux_comment_start[i] = 0; } true_file_length = SEEK_FILE_LENGTH(fd); update_form_size = -1; /* at hdrbuf+4 -> 0xFFFFFFFF */ while (true) { mus_long_t chunksize; offset += chunkloc; if (offset >= true_file_length) break; if (seek_and_read(fd, (unsigned char *)hdrbuf, offset, 64) <= 0) break; chunksize = mus_char_to_lint((unsigned char *)(hdrbuf + 4)); if ((chunksize == 0) && /* can be empty data chunk */ (hdrbuf[0] == 0) && (hdrbuf[1] == 0) && (hdrbuf[2] == 0) && (hdrbuf[3] == 0)) break; if (chunksize < -1) break; if (match_four_chars((unsigned char *)hdrbuf, I_ds64)) { /* RIFF form size | data size | fact samples */ update_form_size = mus_char_to_llong((unsigned char *)(hdrbuf + 8)); data_size = mus_char_to_llong((unsigned char *)(hdrbuf + 16)); fact_samples = (int)mus_char_to_llong((unsigned char *)(hdrbuf + 24)); update_rf64_location = offset + 8; got_ds64 = true; /* ignore "table" for now */ } else { if (match_four_chars((unsigned char *)hdrbuf, I_fmt_)) { got_fmt = true; update_framples_location = 12 + offset; read_riff_fmt_chunk(hdrbuf, true); } else { if ((match_four_chars((unsigned char *)hdrbuf, I_data)) && (data_location == 0)) { update_ssnd_location = offset + 4; data_location = offset + 8; /* chunksize (at hdrbuf + 4) here is -1 */ chunksize = data_size; if (chunksize <= 0) break; /* argh -- we need the ds64 chunk before this chunk */ } else { /* ignore possible fact, inst chunks */ if (match_four_chars((unsigned char *)hdrbuf, I_clm_)) { comment_start = offset + 8; comment_end = comment_start + chunksize - 1; /* end of comment not start of next chunk */ } else { if ((match_four_chars((unsigned char *)hdrbuf, I_LIST)) && (match_four_chars((unsigned char *)(hdrbuf + 8), I_INFO))) { aux_comment_start[0] = offset + 8; aux_comment_end[0] = offset + 8 + chunksize - 1; } } } } } chunkloc = (8 + chunksize); if (chunksize & 1) chunkloc++; /* extra null appended to odd-length chunks */ } if (!got_fmt) return(mus_error(MUS_HEADER_READ_FAILED, "%s: no fmt chunk?", filename)); if (!got_ds64) return(mus_error(MUS_HEADER_READ_FAILED, "%s: no ds64 chunk?", filename)); if (data_location == 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: no data chunk?", filename)); if (data_size > true_file_length) { data_size = true_file_length - data_location; if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %lld?", filename, data_size)); } data_size = mus_bytes_to_samples(sample_type, data_size); return(MUS_NO_ERROR); } static int write_rf64_header(int fd, int wsrate, int wchans, mus_long_t size, mus_sample_t samp_type, const char *comment, int len) { int extra = 0, err = MUS_NO_ERROR; data_location = 36 + 36 + 8; if (len != 0) { if ((len % 4) != 0) extra = (4 - (len % 4)); data_location += (8 + len + extra); } write_four_chars((unsigned char *)hdrbuf, I_RF64); mus_lint_to_char((unsigned char *)(hdrbuf + 4), -1); write_four_chars((unsigned char *)(hdrbuf + 8), I_WAVE); header_write(fd, hdrbuf, 12); /* ds64 chunk */ write_four_chars((unsigned char *)hdrbuf, I_ds64); mus_lint_to_char((unsigned char *)(hdrbuf + 4), 28); mus_llong_to_char((unsigned char *)(hdrbuf + 8), data_location + size - 8); /* -8 added 25-June-07 */ mus_llong_to_char((unsigned char *)(hdrbuf + 16), size); mus_llong_to_char((unsigned char *)(hdrbuf + 24), size); mus_lint_to_char((unsigned char *)(hdrbuf + 32), 0); /* "table size" */ header_write(fd, hdrbuf, 36); err = write_riff_fmt_chunk(fd, hdrbuf, samp_type, wsrate, wchans); if (len > 0) write_riff_clm_comment(fd, comment, len, extra); write_four_chars((unsigned char *)hdrbuf, I_data); mus_lint_to_char((unsigned char *)(hdrbuf + 4), -1); header_write(fd, hdrbuf, 8); return(err); } static int mus_header_convert_riff_to_rf64(const char *filename, mus_long_t size) { int err = MUS_NO_ERROR, fd; update_rf64_location = -1; update_ssnd_location = 0; /* mus_header_change_type copies the entire file, which is probably a bad idea in this case */ err = mus_header_read(filename); if (err != MUS_NO_ERROR) return(err); if ((update_ssnd_location == 0) || (update_rf64_location <= 0)) /* "JUNK" chunk has to be there already for this to work */ return(MUS_CANT_CONVERT); fd = mus_file_reopen_write(filename); if (fd == -1) return(false); /* change overall type to rf64 and set size to RIFF -1 */ write_four_chars((unsigned char *)hdrbuf, I_RF64); mus_lint_to_char((unsigned char *)(hdrbuf + 4), -1); header_write(fd, hdrbuf, 8); /* set data chunk's size to -1 */ lseek(fd, update_ssnd_location, SEEK_SET); mus_lint_to_char((unsigned char *)(hdrbuf + 4), -1); header_write(fd, hdrbuf, 4); /* convert the "JUNK" chunk to be a "ds64" chunk */ lseek(fd, update_rf64_location, SEEK_SET); write_four_chars((unsigned char *)hdrbuf, I_ds64); mus_lint_to_char((unsigned char *)(hdrbuf + 4), 28); mus_llong_to_char((unsigned char *)(hdrbuf + 8), data_location + size - 8); mus_llong_to_char((unsigned char *)(hdrbuf + 16), size); mus_llong_to_char((unsigned char *)(hdrbuf + 24), size); header_write(fd, hdrbuf, 36); CLOSE(fd, filename); return(true); } /* ------------------------------------ AVI ------------------------------------ * actually a video format, but it sometimes contains embedded 'wave' data * * RIFF xxx AVI * * LIST xxxx hdr1 LIST strl(?) strh | strf | strn etc * strf is the WAVE header starting with the sound format * LIST xxxx movi ##db|##wb -- wb subblocks have the audio data (these need to be collected as a single stream) * there are many complications that we make no effort to handle here * * described in http://www.rahul.net/jfm/avi.html */ static int read_avi_header(const char *filename, int fd) { static const unsigned char I_strf[4] = {'s','t','r','f'}; static const unsigned char I_movi[4] = {'m','o','v','i'}; /* we know we have checked for RIFF xxxx AVI when we arrive here */ int chunkloc, cksize, bits; bool happy = true; mus_long_t ckoff, cktotal, offset; type_specifier = mus_char_to_uninterpreted_int((unsigned char *)(hdrbuf + 8)); chunkloc = 12; offset = 0; sample_type = MUS_UNKNOWN_SAMPLE; srate = 0; chans = 1; true_file_length = SEEK_FILE_LENGTH(fd); while (happy) { int chunksize; offset += chunkloc; if (seek_and_read(fd, (unsigned char *)hdrbuf, offset, 32) <= 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s avi header: chunks confused at %lld", filename, offset)); chunksize = mus_char_to_lint((unsigned char *)(hdrbuf + 4)); if ((chunksize == 0) && /* can be empty data chunk? */ (hdrbuf[0] == 0) && (hdrbuf[1] == 0) && (hdrbuf[2] == 0) && (hdrbuf[3] == 0)) break; if (chunksize < 0) break; if (match_four_chars((unsigned char *)hdrbuf, I_LIST)) { ckoff = offset + 12; cktotal = 12; if (match_four_chars((unsigned char *)(hdrbuf + 8), I_movi)) { while (cktotal < chunksize) { lseek(fd, ckoff, SEEK_SET); header_read(fd, hdrbuf, 8); cksize = mus_char_to_lint((unsigned char *)(hdrbuf + 4)); if ((hdrbuf[2] == 'w') && (hdrbuf[3] == 'b')) { data_location = ckoff; if (srate != 0) happy = false; break; } ckoff += (8 + cksize); cktotal += (8 + cksize); } } else { while (cktotal < chunksize) { lseek(fd, ckoff, SEEK_SET); header_read(fd, hdrbuf, 8); cksize = mus_char_to_lint((unsigned char *)(hdrbuf + 4)); ckoff += (8 + cksize); cktotal += (8 + cksize); if (match_four_chars((unsigned char *)hdrbuf, I_LIST)) { mus_long_t ckoffr, cktotalr, rdsize; ckoffr = ckoff + 12; cktotalr = 12; while (cktotalr < cksize) { mus_long_t cksizer; lseek(fd, ckoffr, SEEK_SET); header_read(fd, hdrbuf, 8); cksizer = mus_char_to_lint((unsigned char *)(hdrbuf + 4)); ckoffr += (8 + cksizer); cktotalr += (8 + cksizer); if (match_four_chars((unsigned char *)hdrbuf, I_strf)) { if (cksizer < HDRBUFSIZ) rdsize = cksizer; else rdsize = HDRBUFSIZ; header_read(fd, hdrbuf, rdsize); original_sample_type = mus_char_to_lshort((unsigned char *)hdrbuf); chans = mus_char_to_lshort((unsigned char *)(hdrbuf + 2)); srate = mus_char_to_lint((unsigned char *)(hdrbuf + 4)); /* block_align = mus_char_to_lshort((unsigned char *)(hdrbuf + 12)); */ bits = mus_char_to_lshort((unsigned char *)(hdrbuf + 14)); /* only 16 bit linear little endian for now */ if ((bits == 16) && (original_sample_type == 1)) sample_type = MUS_LSHORT; if (data_location != 0) happy = false; break; } } } } } } chunkloc = (8 + chunksize); if (chunksize & 1) chunkloc++; /* extra null appended to odd-length chunks */ } if (data_location == 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: no movi chunk?", filename)); if (data_location > true_file_length) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_location %lld > file length: %lld", filename, data_location, true_file_length)); data_size = mus_bytes_to_samples(sample_type, true_file_length - data_location); return(MUS_NO_ERROR); } /* ------------------------------------ SoundFont 2.0 ------------------------------------ * * Emu's SoundFont(tm) format uses RIFF -- at ftp.creaf.com:/pub/emu/sf2_00a.ps) * * RIFF xxxx sfbk followed by * LIST xxxx INFO chunk (nothing of interest -- icmt subchunk might have comments) * LIST xxxx sdta chunk = data * smpl chunk (16 bit linear little-endian) * LIST xxxx pdta list chunk * shdr subchunk has srate at 40 (int), samples at 28 * * http://smurf.sourceforge.net/sfont_intro.php * http://www.hammersound.net/ */ static int soundfont_entries = 0; static int *soundfont_starts = NULL, *soundfont_ends = NULL, *soundfont_loop_starts = NULL, *soundfont_loop_ends = NULL; static int soundfont_size = 0; static char **soundfont_names = NULL; static void soundfont_entry(const char *name, int start, int end, int loop_start, int loop_end) { if (soundfont_entries == soundfont_size) { int i; if (soundfont_size == 0) { soundfont_size = 8; soundfont_starts = (int *)calloc(soundfont_size, sizeof(int)); soundfont_ends = (int *)calloc(soundfont_size, sizeof(int)); soundfont_loop_starts = (int *)calloc(soundfont_size, sizeof(int)); soundfont_loop_ends = (int *)calloc(soundfont_size, sizeof(int)); soundfont_names = (char **)calloc(soundfont_size, sizeof(char *)); } else { if (soundfont_size < 123123123) soundfont_size += 8; /* believe it or not, without the 123123123 shuffle, gcc complains at mus_header_read_1 [line 5519!] * that we are making a naughty assumption about overflows. */ soundfont_starts = (int *)realloc(soundfont_starts, soundfont_size * sizeof(int)); soundfont_ends = (int *)realloc(soundfont_ends, soundfont_size * sizeof(int)); soundfont_loop_starts = (int *)realloc(soundfont_loop_starts, soundfont_size * sizeof(int)); soundfont_loop_ends = (int *)realloc(soundfont_loop_ends, soundfont_size * sizeof(int)); soundfont_names = (char **)realloc(soundfont_names, soundfont_size * sizeof(char *)); } for (i = soundfont_entries; i < soundfont_size; i++) soundfont_names[i] = NULL; } if (soundfont_names[soundfont_entries] == NULL) soundfont_names[soundfont_entries] = (char *)calloc(20, sizeof(char)); strcpy(soundfont_names[soundfont_entries], name); soundfont_starts[soundfont_entries] = start; soundfont_ends[soundfont_entries] = end; soundfont_loop_starts[soundfont_entries] = loop_start; soundfont_loop_ends[soundfont_entries] = loop_end; soundfont_entries++; } int mus_header_sf2_entries(void) {return(soundfont_entries);} char *mus_header_sf2_name(int n) {return(soundfont_names[n]);} int mus_header_sf2_start(int n) {return(soundfont_starts[n]);} int mus_header_sf2_end(int n) {return(soundfont_ends[n]);} int mus_header_sf2_loop_start(int n) {return(soundfont_loop_starts[n]);} int mus_header_sf2_loop_end(int n) {return(soundfont_loop_ends[n]);} static int read_soundfont_header(const char *filename, int fd) { static const unsigned char I_sdta[4] = {'s','d','t','a'}; static const unsigned char I_shdr[4] = {'s','h','d','r'}; static const unsigned char I_pdta[4] = {'p','d','t','a'}; /* we know we have checked for RIFF xxxx sfbk when we arrive here */ int chunkloc, type, cksize, i, this_end, last_end; mus_long_t ckoff, offset; bool happy = true; type_specifier = mus_char_to_uninterpreted_int((unsigned char *)(hdrbuf + 8)); chunkloc = 12; offset = 0; soundfont_entries = 0; sample_type = MUS_LSHORT; srate = 0; chans = 1; last_end = 0; true_file_length = SEEK_FILE_LENGTH(fd); while (happy) { int chunksize; offset += chunkloc; if (seek_and_read(fd, (unsigned char *)hdrbuf, offset, 32) <= 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s soundfont header: chunks confused at %lld", filename, offset)); chunksize = mus_char_to_lint((unsigned char *)(hdrbuf + 4)); if ((chunksize == 0) && /* can be empty data chunk? */ (hdrbuf[0] == 0) && (hdrbuf[1] == 0) && (hdrbuf[2] == 0) && (hdrbuf[3] == 0)) break; if (chunksize < 0) break; if (match_four_chars((unsigned char *)hdrbuf, I_LIST)) { /* everything is squirreled away in LIST chunks in this format */ if (match_four_chars((unsigned char *)(hdrbuf + 8), I_pdta)) { /* go searching for I_shdr -- headers this complicated should be illegal. */ ckoff = offset + 12; lseek(fd, ckoff, SEEK_SET); while (srate == 0) { long long int bytes; bytes = (long long int)read(fd, hdrbuf, 8); if (bytes == 0) { happy = false; break; } i = 0; cksize = mus_char_to_lint((unsigned char *)(hdrbuf + 4)); ckoff += (8 + cksize); /* here we need to jump over subchunks! -- 4-Aug-97 */ if (match_four_chars((unsigned char *)hdrbuf, I_shdr)) { /* each sound: * 0: name * 20: start (in samples from start of bank) * 24: end * 28: loop start (also relative to start of bank) * 32: loop end * 36: sample rate * 40: pitch (60 = middle C) * 41: detune (cents) * 42: link (to other channel if any?) * 44: type (1 = mono, 2 = mono right, 4 = mono left, others (0x8000) apparently for ROM presets?) */ while (i < cksize) { header_read(fd, hdrbuf, 46); i += 46; type = mus_char_to_lshort((unsigned char *)(hdrbuf + 44)); if ((type == 1) && (mus_char_to_lint((unsigned char *)(hdrbuf + 24)) > 0)) { if (srate == 0) srate = mus_char_to_lint((unsigned char *)(hdrbuf + 36)); soundfont_entry((char *)(hdrbuf), mus_char_to_lint((unsigned char *)(hdrbuf + 20)), this_end = mus_char_to_lint((unsigned char *)(hdrbuf + 24)), mus_char_to_lint((unsigned char *)(hdrbuf + 28)), mus_char_to_lint((unsigned char *)(hdrbuf + 32))); if (this_end > last_end) last_end = this_end; } } happy = (data_location == 0); } else { if (ckoff >= offset + 8 + chunksize) break; lseek(fd, ckoff, SEEK_SET); } } } else { if (match_four_chars((unsigned char *)(hdrbuf + 8), I_sdta)) { /* assume smpl follows + subchunk size */ /* Convert 1.4 appears to create a separate smpl chunk */ data_location = offset + 20; /* LIST xxxx sdta smpl xxxx ... */ happy = (srate == 0); } } } chunkloc = (8 + chunksize); if (chunksize & 1) chunkloc++; /* extra null appended to odd-length chunks */ } if (srate == 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: srate == 0", filename)); if (data_location == 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: no sdta chunk?", filename)); if (last_end > 0) data_size = last_end; /* samples already */ else data_size = (true_file_length - data_location) / 2; return(MUS_NO_ERROR); } /* ------------------------------------ NIST ------------------------------------ * * code available in ogitools-v1.0.tar.gz at svr-ftp.eng.cam.ac.uk:comp.speech/sources * * 0: "NIST_1A" * 8: data_location as ASCII representation of integer (apparently always " 1024") * 16: start of complicated header -- see below for details * * The most recent version of the SPHERE package is available * via anonymous ftp from jaguar.ncsl.nist.gov [129.6.48.157] in the pub directory * in compressed tar form as "sphere-v.tar.Z" (where "v" is the version * code 2.6a last I looked). shortpack is also at this site. * * here's an example: * * NIST_1A * 1024 * database_id -s5 TIMIT * database_version -s3 1.0 * utterance_id -s8 aks0_sa1 * channel_count -i 1 * sample_count -i 63488 * sample_rate -i 16000 * sample_min -i -6967 * sample_max -i 7710 * sample_n_bytes -i 2 * sample_byte_format -s2 01 * sample_sig_bits -i 16 * end_head * * the sample_byte_format can be "10"=big-endian or "01"=little-endian, or "shortpack-v0"=compressed via shortpack * other formats are wavpack and shorten. * * another field is 'sample_coding' which can be pcm (i.e. linear), 'pcm, embedded-shorten-v1.09', mu-law, alaw, ulaw, pculaw etc -- * so unpredictable as to be totally useless. This means we sometimes try to decode shorten-encoded files because * we ignore this field. And worse, there's a 'channels_interleaved' field that (apparently) can be false. Tough. */ #define MAX_FIELD_LENGTH 80 static int decode_nist_value(char *str, int base, int end) { /* can be -i -r or -snnn where nnn = ascii rep of integer = len of string (!) */ /* we'll deal only with integer fields (and well-behaved string fields) */ int i, j; char value[MAX_FIELD_LENGTH]; memset((void *)value, 0, MAX_FIELD_LENGTH); i = base; while ((i < end) && (i < MAX_FIELD_LENGTH) && (str[i] != '-')) i++; /* look for -i or whatever */ while ((i < end) && (i < MAX_FIELD_LENGTH) && (str[i] != ' ')) i++; /* look for space after it */ i++; if (i >= MAX_FIELD_LENGTH) return(0); for (j = 0; i < end; j++, i++) value[j] = str[i]; value[j] = 0; if (value[0] =='s') return(MUS_NIST_SHORTPACK); sscanf(value, "%12d", &i); /* what is the correct way to use mus_long_ts here for the sample count? */ return(i); } static int read_nist_header(const char *filename, int fd) { char str[MAX_FIELD_LENGTH], name[MAX_FIELD_LENGTH]; bool happy = true; mus_long_t curbase; int k, hend, j, n, nm, samples, bytes, byte_format, idata_location = 0; type_specifier = mus_char_to_uninterpreted_int((unsigned char *)hdrbuf); /* the actual id is "NIST_1A" */ memset((void *)str, 0, MAX_FIELD_LENGTH); memset((void *)name, 0, MAX_FIELD_LENGTH); for (k = 8; k < 16; k++) str[k - 8] = hdrbuf[k]; sscanf(str, "%12d", &idata_location); /* always "1024" */ if (idata_location != 1024) return(mus_error(MUS_HEADER_READ_FAILED, "%s NIST data location: %d?", filename, idata_location)); data_location = 1024; n = 16; hend = INITIAL_READ_SIZE; k = 0; curbase = 0; samples = 0; bytes = 0; srate = 0; chans = 0; comment_start = 16; comment_end = 16; byte_format = 10; for (j = 0; j < MAX_FIELD_LENGTH; j++) str[j] =' '; while (happy) { /* much as in xIFF files, march through the file looking for the data we're after */ /* in this case we munch a character at a time... */ str[k] = hdrbuf[n]; if ((((str[k] == '\0') || (str[k] == '\n')) || ((curbase + n + 1) >= data_location)) || (k == 79)) { /* got a complete record (assuming no embedded newlines, of course) */ /* now look for a record we care about and decode it */ nm = 0; while ((nm < MAX_FIELD_LENGTH) && (str[nm] != ' ') && (str[nm] != '\0') && (str[nm] != '\n')) { name[nm] = str[nm]; nm++; } if (nm >= MAX_FIELD_LENGTH) { header_type = MUS_RAW; sample_type = MUS_UNKNOWN_SAMPLE; return(mus_error(MUS_UNSUPPORTED_HEADER_TYPE, "%s nist header: unreadable field (length = %d)?", filename, nm)); } name[nm] = 0; if (strcmp(name, "sample_rate") == 0) srate = decode_nist_value(str, nm, k); else if (strcmp(name, "channel_count") == 0) chans = decode_nist_value(str, nm, k); else if (strcmp(name, "end_head") == 0) {happy = false; comment_end = curbase + n - 9;} else if (strcmp(name, "sample_count") == 0) samples = decode_nist_value(str, nm, k); else if ((bytes == 0) && (strcmp(name, "sample_n_bytes") == 0)) bytes = decode_nist_value(str, nm, k); else if ((bytes == 0) && (strcmp(name, "sample_sig_bits") == 0)) {bytes = decode_nist_value(str, nm, k); bytes = (bytes >> 3);} else if (strcmp(name, "sample_byte_format") == 0) byte_format = decode_nist_value(str, nm, k); for (j = 0; j <= k; j++) str[j] =' '; k = 0; if ((curbase + n + 1) > 1024) happy = false; } else k++; n++; if (n >= hend) { long long int read_bytes; curbase += hend; n = 0; read_bytes = (long long int)read(fd, hdrbuf, HDRBUFSIZ); if (read_bytes < HDRBUFSIZ) return(mus_error(MUS_HEADER_READ_FAILED, "%s NIST header truncated?", filename)); hend = HDRBUFSIZ; } } data_size = samples * bytes; if (byte_format == MUS_NIST_SHORTPACK) { sample_type = MUS_UNKNOWN_SAMPLE; original_sample_type = MUS_NIST_SHORTPACK; } else { switch (bytes) { case 1: sample_type = MUS_MULAW; break; case 2: if (byte_format == 10) sample_type = MUS_BSHORT; else sample_type = MUS_LSHORT; break; case 3: if (byte_format == 10) sample_type = MUS_B24INT; else sample_type = MUS_L24INT; break; case 4: if (byte_format == 10) sample_type = MUS_BINT; else sample_type = MUS_LINT; break; default: sample_type = MUS_BYTE; break; } } true_file_length = SEEK_FILE_LENGTH(fd); if ((data_size > true_file_length) && (original_sample_type != MUS_NIST_SHORTPACK)) { data_size = true_file_length - data_location; if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %lld?", filename, data_size)); } data_size = mus_bytes_to_samples(sample_type, data_size); return(MUS_NO_ERROR); } static int write_nist_header(int fd, int wsrate, int wchans, mus_long_t size, mus_sample_t samp_type) { char *header; int datum; datum = mus_bytes_per_sample(samp_type); header = (char *)calloc(1024, sizeof(char)); snprintf(header, 1024, "NIST_1A\n 1024\nchannel_count -i %d\nsample_rate -i %d\nsample_n_bytes -i %d\nsample_byte_format -s2 %s\nsample_sig_bits -i %d\nsample_count -i %lld\nend_head\n", wchans, wsrate, datum, ((samp_type == MUS_BSHORT) || (samp_type == MUS_B24INT) || (samp_type == MUS_BINT)) ? "10" : "01", datum * 8, size / datum); header_write(fd, (unsigned char *)header, 1024); data_location = 1024; free(header); return(MUS_NO_ERROR); } /* ------------------------------------ BICSF ------------------------------------ * (actually, this is EBICSF and the old BICSF is called IRCAM below) * * 0-28: NeXT-compatible header, read by read_next_header above. * 28: bicsf magic number (107364 or trouble) * 32: srate as a 32-bit float * 36: chans * 40: sample type indicator (2 = 16-bit linear, 4 = 32-bit float) * 44: begin chunks, if any * * followed by AIFF-style chunked header info with chunks like: * * COMM size comment * MAXA size {max amps (up to 4)} (frample offsets) time-tag unix msec counter * CUE, PRNT, ENV etc * * except in Paul Lansky's "hybrid" headers, according to MixViews. */ static int read_bicsf_header(const char *filename, int fd) { int chunksize, chunkname, offset, chunkloc; bool happy = true; type_specifier = mus_char_to_uninterpreted_int((unsigned char *)(hdrbuf + 28)); header_type = MUS_BICSF; data_location = 1024; if (data_size == 0) data_size = (true_file_length - data_location); lseek(fd, 40, SEEK_SET); header_read(fd, hdrbuf, HDRBUFSIZ); original_sample_type = mus_char_to_bint((unsigned char *)hdrbuf); switch (original_sample_type) { case 2: sample_type = MUS_BSHORT; break; case 4: sample_type = MUS_BFLOAT; break; case 8: sample_type = MUS_BDOUBLE; break; default: break; } /* now check for a COMM chunk, setting the comment pointers */ chunkloc = 4; /* next header + magic number, srate, chans, packing, then chunks, I think */ offset = 40; while (happy) { if (((offset + chunkloc) >= data_location) || ((offset + chunkloc) < 40)) happy = false; else { offset += chunkloc; if (seek_and_read(fd, (unsigned char *)hdrbuf, offset, 32) <= 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s bicsf header: chunks confused at %d", filename, offset)); chunkname = mus_char_to_uninterpreted_int((unsigned char *)hdrbuf); chunksize = mus_char_to_bint((unsigned char *)(hdrbuf + 4)); if (chunksize < 0) break; if (match_four_chars((unsigned char *)hdrbuf, I_COMM)) { comment_start = 8 + offset; comment_end = comment_start + chunksize -1; happy = false; } else { if ((chunkname == 0) || (chunksize <= 0)) happy = false; } chunkloc = (8 + chunksize); } } return(MUS_NO_ERROR); /* from here we fall back into read_next_header */ } /* ------------------------------------ IRCAM ------------------------------------ * old-style BICSF -- added write option for Sun port 12-Dec-94 * * 0: 0x1a364 or variations thereof -- byte order gives big/little_endian decision, * ^ digit gives machine info, according to AFsp sources -- see IRCAM ints above * 4: srate as a 32-bit float * 8: chans * 12: sample type indicator (2 = 16-bit linear, 4 = 32-bit float) * according to new Sox (version 11), these packing modes are now bytes/sample in low short, code in high * so 1 = char, 0x10001 = alaw, 0x20001 = mulaw, 2 = short, 3 = 24bit?, 0x40004 = long, 4 = float (AFsp sez 4 can also be double) * 16: comment start -- how to tell if it's a real comment? * apparently these are separated as short code, short blocksize, then data * codes: 0 = end, 1 = maxamp, 2 = comment, 3 = pvdata, 4 = audioencode and codemax?? * 1024: data start * * apparently the byte order depends on the machine. * and yet... convert 1.4 makes a .sf file with little endian header, the VAX id, and big endian data? * Csound also uses the VAX magic number with little-endian unscaled floats! Argh. * even worse, Paul Lansky plops some version of this at the end of a NeXT header! Complete chaos... */ static int read_ircam_header(const char *filename, int fd) { short bloc; int offset; bool little, happy = true; type_specifier = mus_char_to_uninterpreted_int((unsigned char *)hdrbuf); if ((mus_char_to_lint((unsigned char *)hdrbuf) == I_IRCAM_VAX) || (mus_char_to_lint((unsigned char *)hdrbuf) == I_IRCAM_MIPS)) little = true; else little = false; little_endian = little; data_location = 1024; true_file_length = SEEK_FILE_LENGTH(fd); data_size = (true_file_length - 1024); original_sample_type = big_or_little_endian_int((unsigned char *)(hdrbuf + 12), little); sample_type = MUS_UNKNOWN_SAMPLE; if (original_sample_type == 2) { if (little) sample_type = MUS_LSHORT; else sample_type = MUS_BSHORT; } else if (original_sample_type == 4) { if (little) { if (mus_char_to_lint((unsigned char *)hdrbuf) == I_IRCAM_VAX) sample_type = MUS_LFLOAT_UNSCALED; /* Csound and MixViews */ else sample_type = MUS_LFLOAT; } else sample_type = MUS_BFLOAT; } else if (original_sample_type == 0x40004) { if (little) sample_type = MUS_LINT; else sample_type = MUS_BINT; } else if (original_sample_type == 0x10001) sample_type = MUS_ALAW; else if (original_sample_type == 0x20001) sample_type = MUS_MULAW; else if (original_sample_type == 1) sample_type = MUS_BYTE; else if (original_sample_type == 3) { if (little) sample_type = MUS_L24INT; else sample_type = MUS_B24INT; } else if (original_sample_type == 8) { if (little) sample_type = MUS_LDOUBLE; else sample_type = MUS_BDOUBLE; } srate = (int)big_or_little_endian_float((unsigned char *)(hdrbuf + 4), little); chans = big_or_little_endian_int((unsigned char *)(hdrbuf + 8), little); bloc = 16; offset = 0; while (happy) { short bcode, bsize; offset += bloc; if (seek_and_read(fd, (unsigned char *)hdrbuf, offset, 32) <= 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s ircam header: chunks confused at %d", filename, offset)); bcode = big_or_little_endian_short((unsigned char *)hdrbuf, little); bsize = big_or_little_endian_short((unsigned char *)(hdrbuf + 2), little); if (bcode == 2) { happy = false; comment_start = 4 + offset; comment_end = comment_start + bsize - 1; /* was -5? */ } bloc = bsize; if ((bsize <= 0) || (bcode <= 0) || ((offset + bloc) > 1023)) happy = false; } data_size = mus_bytes_to_samples(sample_type, data_size); return(MUS_NO_ERROR); } static int sndlib_format_to_ircam(mus_sample_t samp_type) { switch (samp_type) { case MUS_MULAW: return(0x20001); break; case MUS_ALAW: return(0x10001); break; case MUS_BSHORT: return(2); break; case MUS_BINT: return(0x40004); break; case MUS_BFLOAT: return(4); break; default: return(mus_error(MUS_UNSUPPORTED_SAMPLE_TYPE, "IRCAM header unsupported sample type: %d (%s)", samp_type, any_sample_type_name(samp_type))); break; } } static void write_ircam_comment(int fd, const char *comment, int len) { if (len > 0) { mus_bshort_to_char((unsigned char *)hdrbuf, 2); mus_bshort_to_char((unsigned char *)(hdrbuf + 2), (short)len); header_write(fd, hdrbuf, 4); header_write(fd, (unsigned char *)comment, len); } else { mus_bint_to_char((unsigned char *)hdrbuf, 0); header_write(fd, hdrbuf, 4); } len = 1024 - (len + 20); if (len > 0) { unsigned char *combuf; combuf = (unsigned char *)calloc(len, sizeof(unsigned char)); header_write(fd, combuf, len); free(combuf); } } static int write_ircam_header(int fd, int wsrate, int wchans, mus_sample_t samp_type, const char *comment, int len) { mus_bint_to_char((unsigned char *)hdrbuf, 0x2a364); /* SUN id */ mus_bfloat_to_char((unsigned char *)(hdrbuf + 4), (float)wsrate); mus_bint_to_char((unsigned char *)(hdrbuf + 8), wchans); mus_bint_to_char((unsigned char *)(hdrbuf + 12), sndlib_format_to_ircam(samp_type)); header_write(fd, hdrbuf, 16); data_location = 1024; write_ircam_comment(fd, comment, len); return(MUS_NO_ERROR); } /* ------------------------------------ 8SVX ------------------------------------- * (also known as IFF) * * very similar to AIFF: * "BODY" => [4] samples [n] data * "VHDR" => srate (short) * "CHAN" => chans * "ANNO" and "NAME" * * big_endian throughout */ static int read_8svx_header(const char *filename, int fd, bool bytewise) { static const unsigned char I_BODY[4] = {'B','O','D','Y'}; static const unsigned char I_CHAN[4] = {'C','H','A','N'}; static const unsigned char I_VHDR[4] = {'V','H','D','R'}; int offset, chunkloc; bool happy = true; type_specifier = mus_char_to_uninterpreted_int((unsigned char *)hdrbuf); chunkloc = 12; offset = 0; if (bytewise) sample_type = MUS_BYTE; else sample_type = MUS_BSHORT; srate = 0; chans = 1; true_file_length = SEEK_FILE_LENGTH(fd); update_form_size = mus_char_to_bint((unsigned char *)(hdrbuf + 4)); while (happy) { int chunksize; offset += chunkloc; if (seek_and_read(fd, (unsigned char *)hdrbuf, offset, 32) <= 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s 8svx header: chunks confused at %d", filename, offset)); chunksize = mus_char_to_bint((unsigned char *)(hdrbuf + 4)); if ((chunksize == 0) && /* can be empty data chunk? */ (hdrbuf[0] == 0) && (hdrbuf[1] == 0) && (hdrbuf[2] == 0) && (hdrbuf[3] == 0)) break; if (chunksize < 0) break; if (match_four_chars((unsigned char *)hdrbuf, I_CHAN)) { chans = mus_char_to_bint((unsigned char *)(hdrbuf + 8)); chans = (chans & 0x01) + ((chans & 0x02) >> 1) + ((chans & 0x04) >> 2) + ((chans & 0x08) >> 3); /* what in heaven's name is this? Each bit corresponds to a channel? */ } else { if (match_four_chars((unsigned char *)hdrbuf, I_VHDR)) { /* num_samples (int) at hdrbuf + 8 */ srate = mus_char_to_ubshort((unsigned char *)(hdrbuf + 20)); original_sample_type = hdrbuf[23]; if (original_sample_type != 0) sample_type = MUS_UNKNOWN_SAMPLE; } else { if ((match_four_chars((unsigned char *)hdrbuf, I_ANNO)) || (match_four_chars((unsigned char *)hdrbuf, I_NAME))) { comment_start = offset + 8; comment_end = comment_start + chunksize - 1; } else { if (match_four_chars((unsigned char *)hdrbuf, I_BODY)) { data_size = chunksize; data_location = offset + 12; happy = false; } } } } chunkloc = (8 + chunksize); if (chunksize & 1) chunkloc++; /* extra null appended to odd-length chunks */ } if (data_location == 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: no BODY chunk?", filename)); if (data_size > true_file_length) { data_size = true_file_length - data_location; if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %lld?", filename, data_size)); } data_size = mus_bytes_to_samples(sample_type, data_size); return(MUS_NO_ERROR); } /* ------------------------------------ VOC -------------------------------------- * * 0: "Creative Voice File" followed by a couple ctrl-Z ('32) (swapped data) * 20: header end (short) {8svx, 26 = data_offset, 0x10a = version, ((~version + 0x1234) & 0xffff) = 0x1129} * [20]: first block: * block code, 1 = data, 0 = end, 9 = data_16 (2 = continue, 3 = silence, 4 = marker, 5 = text, 6 = loop, 7 = loop-end, 8 = extended) * block len as 24 bit int(?) * if data, then rate code (byte), then data (assuming 8-bit unsigned, mono) * if data_16, long srate, byte: data size (8 or 16), byte chans * if text, ascii text (a comment) * if extended (8) precedes 1 (data): 8 4 then time constant (short), byte: packing code (0), byte chans (0 = mono) * * apparently always little_endian * updated extensively 29-Aug-95 from sox10 voc.c */ static int read_voc_header(const char *filename, int fd) { mus_long_t curbase; int voc_extended, bits, code; bool happy = true; sample_type = MUS_UBYTE; chans = 1; voc_extended = 0; true_file_length = SEEK_FILE_LENGTH(fd); curbase = mus_char_to_lshort((unsigned char *)(hdrbuf + 20)); if (true_file_length < curbase) return(mus_error(MUS_HEADER_READ_FAILED, "%s: block location %lld > file length: %lld", filename, curbase, true_file_length)); lseek(fd, curbase, SEEK_SET); header_read(fd, hdrbuf, HDRBUFSIZ); while (happy) { int type, len; type = (int)(hdrbuf[0]); len = (((int)hdrbuf[3]) << 16) + (((int)hdrbuf[2]) << 8) + (((int)hdrbuf[1])); if (type == 1) /* voc_data */ { data_size = len - 1; /* was -3 */ data_location = curbase + 6; if (voc_extended == 0) { srate = (int)(1000000.0 / (256 - ((int)(hdrbuf[4] & 0xff)))); original_sample_type = hdrbuf[5]; if (hdrbuf[5] == 0) sample_type = MUS_UBYTE; else sample_type = MUS_UNKNOWN_SAMPLE; } happy = false; } else { if (type == 9) /* voc_data_16 */ { data_size = len - 1; /* was -3 */ data_location = curbase + 6; srate = mus_char_to_lint((unsigned char *)(hdrbuf + 4)); bits = ((int)hdrbuf[8]); if (bits == 8) { code = mus_char_to_lshort((unsigned char *)(hdrbuf + 10)); if (code == 6) sample_type = MUS_ALAW; else if (code == 7) sample_type = MUS_MULAW; else sample_type = MUS_UBYTE; } else if (bits == 16) sample_type = MUS_LSHORT; else sample_type = MUS_UNKNOWN_SAMPLE; chans = (int)hdrbuf[9]; if (chans == 0) chans = 1; happy = false; } else { if (((len + curbase) < true_file_length) && (type != 0)) { if (type == 5) /* voc_text */ { comment_start = curbase + 4; comment_end = comment_start + len - 1; } else { if (type == 8) /* voc_extended */ { /* should voc_extended be set to 1 here? */ srate = (256000000 / (65536 - mus_char_to_lshort((unsigned char *)(hdrbuf + 4)))); if ((int)(hdrbuf[7]) == 0) chans = 1; else chans = 2; if ((int)(hdrbuf[6]) != 0) sample_type = MUS_UNKNOWN_SAMPLE; } /* I'd add loop support here if I had any example sound files to test with */ } if (seek_and_read(fd, (unsigned char *)hdrbuf, curbase + len + 4, HDRBUFSIZ) <= 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s voc header: ran off end of file", filename)); curbase += len; } else happy = false; } } } if (data_location == 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: no data(type 1 or 9) chunk?", filename)); if ((data_size > true_file_length) || (data_size < (mus_long_t)(true_file_length / 10))) /* some VOC files seem to have completely bogus lengths */ { data_size = true_file_length - data_location; if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %lld?", filename, data_size)); } data_size = mus_bytes_to_samples(sample_type, data_size); return(MUS_NO_ERROR); } /* ------------------------------------ TwinVQ ------------------------------------ * * from Audio Tools Library (atl.zip) at http://jfaul.de/atl. * a chunked header for proprietary (and apparently obsolete?) compressed data * * 0: "TWIN" * 4: version id (string) * 12: header size ["cardinal" -> bint] * common chunk header (4 of ID, bint size) * 24: channels (bint: 0=mono 1=stereo) * bitrate (bint) * 32: srate (bint khz 11, 22, 44 else *1000) * security (bint 0) * filesize (bint bytes) * possible chunks: NAME COMT AUTH (c) FILE ALBM DATA */ /* Monkey files start with "MAC ", but this is yet another compression-oriented format, I think (APE?) */ static int read_twinvq_header(const char *filename, int fd) { sample_type = MUS_UNKNOWN_SAMPLE; data_location = mus_char_to_bint((unsigned char *)(hdrbuf + 12)) + 16 + 8; chans = 1 + mus_char_to_bint((unsigned char *)(hdrbuf + 24)); srate = mus_char_to_bint((unsigned char *)(hdrbuf + 32)); if (srate == 11) srate = 11025; else if (srate == 22) srate = 22050; else if (srate == 44) srate = 44100; else srate = 48000; true_file_length = SEEK_FILE_LENGTH(fd); data_size = (true_file_length - data_location); if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %lld?", filename, data_size)); return(MUS_NO_ERROR); } /* ------------------------------------ SDIF ------------------------------------ * * not usable in this context -- even the apparently non-existent 1TDS (sampled data) * format consists of a sequence of chunks, each of any size. * Why invent an uncompressed format that makes random access impossible? */ static int read_sdif_header(const char *filename, int fd) { static const unsigned char I_1FQ0[4] = {'1','F','Q','0'}; static const unsigned char I_1STF[4] = {'1','S','T','F'}; static const unsigned char I_1PIC[4] = {'1','P','I','C'}; static const unsigned char I_1TRC[4] = {'1','T','R','C'}; static const unsigned char I_1HRM[4] = {'1','H','R','M'}; static const unsigned char I_1RES[4] = {'1','R','E','S'}; static const unsigned char I_1TDS[4] = {'1','T','D','S'}; /* samples -- all others are useless */ static const char *sdif_names[7] = {"fundamental frequency", "FFT", "spectral peak", "sinusoidal track", "harmonic track", "resonance", "unknown"}; int offset; bool happy = false; offset = 16; while (!happy) { int size; if (seek_and_read(fd, (unsigned char *)hdrbuf, offset, 32) <= 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s, sdif header: chunks confused at %d", filename, offset)); size = mus_char_to_bint((unsigned char *)(hdrbuf + 4)) + 8; if (match_four_chars((unsigned char *)hdrbuf, I_1TDS)) break; else { int type = 0; if (match_four_chars((unsigned char *)hdrbuf, I_1FQ0)) type = 0; else if (match_four_chars((unsigned char *)hdrbuf, I_1STF)) type = 1; else if (match_four_chars((unsigned char *)hdrbuf, I_1PIC)) type = 2; else if (match_four_chars((unsigned char *)hdrbuf, I_1TRC)) type = 3; else if (match_four_chars((unsigned char *)hdrbuf, I_1HRM)) type = 4; else if (match_four_chars((unsigned char *)hdrbuf, I_1RES)) type = 5; else type = 6; return(mus_error(MUS_HEADER_READ_FAILED, "this SDIF file contains %s data, not sampled sound", sdif_names[type])); } offset += size; } return(MUS_HEADER_READ_FAILED); } #if G7XX /* ------------------------------------ NVF ------------------------------------ */ static int read_nvf_header(const char *filename, int fd) { static const unsigned char I_VFMT[4] = {'V','F','M','T'}; /* Nomad II Creative NVF */ /* info from nvftools by Tom Mander: */ /* Numbers stored little-endian. bytes 0-3: "NVF " magic number bytes 4-7: 0x00000001 NVF version number? bytes 8-11: 0x00000020 size of rest of header bytes 12-15: "VFMT" VFMT chunk h bytes 16-19: 0x00000001 VFMT version number? bytes 20-23: 0x00000014 size of reset of VFMT header bytes 24-27: 0x00007D00 32000 bit/s bitrate bytes 28-29: 0x0001 channels bytes 30-31: 0x0000 unknown bytes 32-35: 0x00001F40 8000kHz sample rate bytes 36-39: 0x00003E80 16000 bytes 40-41: 0x0002 width in bytes of uncompressed data? bytes 42-43: 0x0010 width in bits of compressed data? The rest of the data is G.721 data nibble packing big-endian, 4bits per sample (nibble) single channel at 32kbit. When the Nomad records an NVF file it does it in 92 sample (46 byte) framples or 0.0115sec. */ if (mus_char_to_lint((unsigned char *)(hdrbuf + 4)) != 1) return(mus_error(MUS_HEADER_READ_FAILED, "%s: NVF[4] != 1", filename)); if (!(match_four_chars((unsigned char *)(hdrbuf + 12), I_VFMT))) return(mus_error(MUS_HEADER_READ_FAILED, "%s: no VFMT chunk", filename)); sample_type = MUS_UNKNOWN_SAMPLE; /* g721 --translate elsewhere */ chans = 1; srate = 8000; data_location = 44; true_file_length = SEEK_FILE_LENGTH(fd); data_size = (true_file_length - data_location) * 2; /* 4 bit samps? */ if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %lld?", filename, data_size)); return(MUS_NO_ERROR); } #endif /* ------------------------------------ ADC ------------------------------------ * also known as OGI format * TIMIT format is identical except it omits the sample type field (header size claims to be bytes) * * from ad.h and other files, ogitools-v1.0.tar.gz * we'll look for the big/little endian sequence (short) 8 1 1-or-2 given big/little decision * * 0: header size in shorts (8 = 16 bytes) (OGI says this is in bytes) * 2: version (1) * 4: chans * 6: rate (srate = 4000000/rate) * 8: samples (int) -- seems to be off by 2 -- are they counting ints here? * 12: sample type (0 = big-endian) * 16: data start */ static int read_adc_header(const char *filename, int fd) { bool little; little = (mus_char_to_uninterpreted_int((unsigned char *)(hdrbuf + 12)) != 0); /* 0 = big endian */ data_location = 16; if (little) sample_type = MUS_LSHORT; else sample_type = MUS_BSHORT; chans = big_or_little_endian_short((unsigned char *)(hdrbuf + 4), little); srate = 4000000 / big_or_little_endian_short((unsigned char *)(hdrbuf + 6), little); data_size = 2 * big_or_little_endian_int((unsigned char *)(hdrbuf + 8), little); comment_start = 0; comment_end = 0; true_file_length = SEEK_FILE_LENGTH(fd); if (data_size > true_file_length) { data_size = true_file_length - data_location; if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %lld?", filename, data_size)); } data_size = mus_bytes_to_samples(sample_type, data_size); return(MUS_NO_ERROR); } /* ------------------------------------ AVR -------------------------------------- * * 0: "2BIT" * 4: sample name (null padded ASCII) * 12: chans (short) (0 = mono, -1 = stereo) * 14: sample size (8 or 16 bit) (short) (value is 8, 12, or 16) * 16: sample type (signed or unsigned) (short) (0 = unsigned, -1 = signed) * 18: loop (on/off), 20: midi (-1 = no MIDI) * 22: srate * avr.txt has: * 22: Replay speed 0 = 5.485 Khz, 1 = 8.084 Khz, 2 = 10.971 Khz, 3 = 16.168 Khz, 4 = 21.942 Khz, 5 = 32.336 Khz, 6 = 43.885 Khz, 7 = 47.261 Khz * 23: sample rate in Hertz (as a 3 byte quantity??) * 26: length in samples * 30: loop beg, 34: loop end, 38: midi (keyboard split), 40: compression, 42: nada ("reserved"), 44: name * 64: comment (limited to 64 bytes) * 128: data start * * the Atari .avr files appear to be 8000 Hz, mono, 8-bit linear unsigned data with an unknown header of 128 words * apparently there was a change in format sometime in the 90's. * * The actual avr files I've found on the net are either garbled, or * something is wrong with this definition (taken from CMJ and www.wotsit.org's avr.txt). * SGI dmconvert assumes big-endian here -- this is an Atari format, so it's probably safe to assume big-endian. */ static int read_avr_header(const char *filename, int fd) { int dsize, dsigned, i; chans = mus_char_to_bshort((unsigned char *)(hdrbuf + 12)); if (chans == 0) chans = 1; else if (chans == -1) chans = 2; else return(mus_error(MUS_HEADER_READ_FAILED, "%s chans: %d", filename, chans)); data_location = 128; data_size = mus_char_to_bint((unsigned char *)(hdrbuf + 26)); srate = mus_char_to_ubshort((unsigned char *)(hdrbuf + 24)); dsize = mus_char_to_bshort((unsigned char *)(hdrbuf + 14)); dsigned = mus_char_to_bshort((unsigned char *)(hdrbuf + 16)); if (dsize == 16) { if (dsigned == 0) sample_type = MUS_UBSHORT; else sample_type = MUS_BSHORT; } else { if (dsize == 8) { if (dsigned == 0) sample_type = MUS_UBYTE; else sample_type = MUS_BYTE; } else return(mus_error(MUS_HEADER_READ_FAILED, "%s: unknown sample type", filename)); } if (seek_and_read(fd, (unsigned char *)hdrbuf, 64, 64) <= 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s avr header: ran off end of file", filename)); comment_start = 64; i = 0; while ((i < 64) && (hdrbuf[i] != 0)) i++; comment_end = 64 + (i - 1); true_file_length = SEEK_FILE_LENGTH(fd); if (data_size > true_file_length) { data_size = true_file_length - data_location; if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %lld?", filename, data_size)); } data_size = mus_bytes_to_samples(sample_type, data_size); return(MUS_NO_ERROR); } /* ------------------------------------ SNDT ------------------------------------- * * this taken from sndrtool.c (sox-10): (modified 6-Feb-98) * 0: "SOUND" (or off by two throughout if not "0x1a"?) * 5: 0x1a * 6-7: 0 * 8-11: nsamps (at 12) * 12-15: 0 * 16-19: nsamps * 20-21: srate (little endian short) (at 22) * 22-23: 0 * 24-25: 10 * 26-27: 4 * 28-> : "- File created by Sound Exchange" * .->95: 0 ? */ /* similar is Sounder format: * 0: 0 * 2: short srate (little endian) * 4: 10 * 6: 4 * then data * but this format can't be distinguished from a raw sound file */ static int read_sndt_header(const char *filename, int fd) { if (hdrbuf[4] != 'D') return(mus_error(MUS_HEADER_READ_FAILED, "%s: SNDT[4] != 'D'", filename)); sample_type = MUS_UBYTE; chans = 1; srate = mus_char_to_ulshort((unsigned char *)(hdrbuf + 20)); data_location = 126; data_size = mus_char_to_lint((unsigned char *)(hdrbuf + 8)); if (data_size < 0) data_size = mus_char_to_lint((unsigned char *)(hdrbuf + 10)); if (srate <= 1) srate = mus_char_to_ulshort((unsigned char *)(hdrbuf + 22)); true_file_length = SEEK_FILE_LENGTH(fd); if (data_size > true_file_length) { data_size = true_file_length - data_location; if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %lld?", filename, data_size)); } return(MUS_NO_ERROR); } /* ------------------------------------ Covox v8 ------------------------------------- * * 0: 377 125 377 252 377 125 377 252 x x 0's to 16 * then 8-bit unsigned data */ static int read_covox_header(const char *filename, int fd) { sample_type = MUS_UBYTE; chans = 1; data_location = 16; srate = 8000; true_file_length = SEEK_FILE_LENGTH(fd); data_size = true_file_length - data_location; if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %lld?", filename, data_size)); return(MUS_NO_ERROR); } /* ------------------------------------ SMP ------------------------------------- * * 0: "SOUND SAMPLE DATA " * 18: "2.1 " * 22-81: comment * 82-111: sample name * header 112 bytes * long samples (bytes = samples*2) * then data start * data * always little endian */ static int read_smp_header(const char *filename, int fd) { sample_type = MUS_LSHORT; chans = 1; comment_start = 22; comment_end = 81; data_location = 116; lseek(fd, 112, SEEK_SET); if (read(fd, hdrbuf, 4) != 4) return(mus_error(MUS_HEADER_READ_FAILED, "%s: SMP header truncated?", filename)); data_size = (mus_char_to_lint((unsigned char *)hdrbuf)); sample_type = MUS_LSHORT; /* just a guess */ srate = 8000; /* docs mention an srate floating around at the end of the file, but I can't find it in any example */ true_file_length = SEEK_FILE_LENGTH(fd); if ((data_size * 2) > true_file_length) { data_size = (true_file_length - data_location) / 2; if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %lld?", filename, data_size)); } return(MUS_NO_ERROR); } /* ------------------------------------ SPPACK ------------------------------------- * * from AF docs: * Bytes Type Contents * 0 160 char Text strings (2 * 80) * 160 80 char Command line * 240 2 int Domain (1-time, 2-freq, 3-qfreq) * 242 2 int Frample size * 244 4 float Sampling frequency * 252 2 int File identifier (i.e. #o100 #o303) * 254 2 int Data type (0xfc0e = sampled data file) * 256 2 int Resolution (in bits 8, 16) * 258 2 int Companding flag * 272 240 char Text strings (3 * 80) * 512 ... -- Audio data * * at least one program is writing these headers using little endian data... */ static int read_sppack_header(const char *filename, int fd) { int typ; data_location = 512; chans = 1; lseek(fd, 240, SEEK_SET); if (read(fd, hdrbuf, 22) != 22) return(mus_error(MUS_HEADER_READ_FAILED, "%s SPPACK header truncated?", filename)); typ = mus_char_to_bshort((unsigned char *)hdrbuf); sample_type = MUS_UNKNOWN_SAMPLE; if (typ == 1) { if (((hdrbuf[254]) == 252) && ((hdrbuf[255]) == 14)) /* #xfc and #x0e */ { int bits; float sr; typ = mus_char_to_bshort((unsigned char *)(hdrbuf + 18)); bits = mus_char_to_bshort((unsigned char *)(hdrbuf + 16)); sr = mus_char_to_bfloat((unsigned char *)(hdrbuf + 4)); srate = (int)sr; switch (typ) { case 1: if (bits == 16) sample_type = MUS_BSHORT; else sample_type = MUS_BYTE; break; case 2: sample_type = MUS_ALAW; break; case 3: sample_type = MUS_MULAW; break; default: sample_type = MUS_UNKNOWN_SAMPLE; break; } data_size = SEEK_FILE_LENGTH(fd); data_size = mus_bytes_to_samples(sample_type, data_size - 512); comment_start = 0; comment_end = 0; } } true_file_length = SEEK_FILE_LENGTH(fd); if (true_file_length < data_location) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_location %lld > file length: %lld", filename, data_location, true_file_length)); if (data_size > mus_bytes_to_samples(sample_type, true_file_length)) data_size = mus_bytes_to_samples(sample_type, true_file_length - data_location); return(MUS_NO_ERROR); } /* ------------------------------------ ESPS (Entropic Signal Processing System) ------------------------------------- * * specs at ftp.entropic.com (also known as "SD" format) * from AFgetInfoES.c: * * Bytes Type Contents * 8 -> 11 -- Header size (bytes) * 12 -> 15 int Sampled data record size * 16 -> 19 int File identifier: 0x00006a1a or 0x1a6a0000 * 40 -> 65 char File creation date * 124 -> 127 int Number of samples * 132 -> 135 int Number of doubles in a data record * 136 -> 139 int Number of floats in a data record * 140 -> 143 int Number of longs in a data record * 144 -> 147 int Number of shorts in a data record * 148 -> 151 int Number of chars in a data record * 160 -> 167 char User name * 333 -> H-1 -- "Generic" header items, including "record_freq" {followed by a "double8"=64-bit ?} * H -> ... -- Audio data */ static int read_esps_header(const char *filename, int fd) { char str[80]; bool happy = true; mus_long_t curbase, hend; int k, j, n, chars, floats, shorts, doubles; long long int bytes; bool little; little = (hdrbuf[18] == 0); if (little) data_location = mus_char_to_lint((unsigned char *)(hdrbuf + 8)); else data_location = mus_char_to_bint((unsigned char *)(hdrbuf + 8)); true_file_length = SEEK_FILE_LENGTH(fd); data_size = true_file_length - data_location; if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %lld?", filename, data_size)); srate = 8000; chans = 1; lseek(fd, 132, SEEK_SET); header_read(fd, hdrbuf, HDRBUFSIZ); if (little) { doubles = mus_char_to_lint((unsigned char *)hdrbuf); floats = mus_char_to_lint((unsigned char *)(hdrbuf + 4)); shorts = mus_char_to_lint((unsigned char *)(hdrbuf + 12)); chars = mus_char_to_lint((unsigned char *)(hdrbuf + 16)); } else { doubles = mus_char_to_bint((unsigned char *)hdrbuf); floats = mus_char_to_bint((unsigned char *)(hdrbuf + 4)); shorts = mus_char_to_bint((unsigned char *)(hdrbuf + 12)); chars = mus_char_to_bint((unsigned char *)(hdrbuf + 16)); } if (shorts != 0) { sample_type = ((little) ? MUS_LSHORT : MUS_BSHORT); chans = shorts; } else { if (doubles != 0) { sample_type = ((little) ? MUS_LDOUBLE_UNSCALED : MUS_BDOUBLE_UNSCALED); chans = doubles; } else { if (floats != 0) { sample_type = ((little) ? MUS_LFLOAT_UNSCALED : MUS_BFLOAT_UNSCALED); chans = floats; } else { if (chars != 0) { sample_type = MUS_BYTE; /* ?? */ chans = chars; } } } } /* search for "record_freq" to get srate */ lseek(fd, 333, SEEK_SET); header_read(fd, hdrbuf, HDRBUFSIZ); curbase = 333; hend = curbase + HDRBUFSIZ; k = 0; n = 0; for (j = 0; j < 80; j++) str[j] =' '; while (happy) { str[k] = hdrbuf[n]; if ((str[k] == 'q') || (str[k] == 3) || ((curbase + n + 1) >= data_location) || (k == 78)) { /* 3 = C-C marks end of record (?) */ str[k + 1] = 0; if (strcmp(str, "record_freq") == 0) { if (seek_and_read(fd, (unsigned char *)hdrbuf, curbase + n, 32) <= 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s esps header: ran off end of file", filename)); n = 0; if (little) srate = (int)mus_char_to_ldouble((unsigned char *)(hdrbuf + 8)); else srate = (int)mus_char_to_bdouble((unsigned char *)(hdrbuf + 8)); happy = false; } if ((curbase + n + 1) >= data_location) happy = false; k = 0; } else k++; n++; if (n >= hend) { curbase += hend; n = 0; bytes = read(fd, hdrbuf, HDRBUFSIZ); if (bytes != HDRBUFSIZ) break; hend = HDRBUFSIZ; } } if (srate == 0) srate = 8000; data_size = mus_bytes_to_samples(sample_type, data_size); return(MUS_NO_ERROR); } /* ------------------------------------ INRS ------------------------------------- * * from AFgetInfoIN.c: * * INRS-Telecommunications audio file: * Bytes Type Contents * 0 -> 3 float Sampling Frequency (VAX float format) * 6 -> 25 char Creation time (e.g. Jun 12 16:52:50 1990) * 26 -> 29 int Number of speech samples in the file (? -- old INRS files omit this) * The data in an INRS-Telecommunications audio file is in 16-bit integer (little-endian) * format. Header is always 512 bytes. Always mono. * */ static int read_inrs_header(const char *filename, int fd, int loc) { true_file_length = SEEK_FILE_LENGTH(fd); comment_start = 6; comment_end = 25; sample_type = MUS_LSHORT; srate = loc; chans = 1; data_location = 512; true_file_length = SEEK_FILE_LENGTH(fd); if (true_file_length < data_location) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_location %lld > file length: %lld", filename, data_location, true_file_length)); data_size = mus_bytes_to_samples(sample_type, true_file_length - data_location); return(MUS_NO_ERROR); } /* ------------------------------------ MAUD ------------------------------------- * * very similar to AIFF: * "MHDR" => 4: chunksize (32) * 8: samples * 12: bits * 14: ditto * 16: clock freq * 20: clock div (srate = freq/div) * 22: chan info (0 = mono, 1 = stereo) * 24: ditto(?!) * 26: format (0 = unsigned 8 or signed 16 (see bits), 2 = alaw, 3 = mulaw) * 28-40: unused * "MDAT" => data * "ANNO" => comment * * according to /usr/share/magic, this stands for "MacroSystem Audio" */ static int read_maud_header(const char *filename, int fd) { static const unsigned char I_MHDR[4] = {'M','H','D','R'}; static const unsigned char I_MDAT[4] = {'M','D','A','T'}; int offset, chunkloc; bool happy = true; type_specifier = mus_char_to_uninterpreted_int((unsigned char *)hdrbuf); chunkloc = 12; offset = 0; sample_type = MUS_BYTE; srate = 0; chans = 1; update_form_size = mus_char_to_bint((unsigned char *)(hdrbuf + 4)); while (happy) { int chunksize; offset += chunkloc; if (seek_and_read(fd, (unsigned char *)hdrbuf, offset, 32) <= 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s maud header: chunks confused at %d", filename, offset)); chunksize = mus_char_to_bint((unsigned char *)(hdrbuf + 4)); if ((chunksize == 0) && /* can be empty data chunk? */ (hdrbuf[0] == 0) && (hdrbuf[1] == 0) && (hdrbuf[2] == 0) && (hdrbuf[3] == 0)) break; if (chunksize < 0) break; if (match_four_chars((unsigned char *)hdrbuf, I_MHDR)) { int num, den; data_size = mus_char_to_bint((unsigned char *)(hdrbuf + 8)); num = mus_char_to_bint((unsigned char *)(hdrbuf + 16)); den = mus_char_to_bshort((unsigned char *)(hdrbuf + 20)); if (den == 0) den = 1; srate = (int)(num / den); num = mus_char_to_bshort((unsigned char *)(hdrbuf + 12)); den = mus_char_to_bshort((unsigned char *)(hdrbuf + 26)); if (num == 8) { switch (den) { case 0: sample_type = MUS_UBYTE; break; case 2: sample_type = MUS_ALAW; break; case 3: sample_type = MUS_MULAW; break; default: sample_type = MUS_UNKNOWN_SAMPLE; break; } } else sample_type = MUS_BSHORT; num = mus_char_to_bshort((unsigned char *)(hdrbuf + 22)); if (num == 0) chans = 1; else chans = 2; } else { if (match_four_chars((unsigned char *)hdrbuf, I_ANNO)) { comment_start = offset + 8; comment_end = comment_start + chunksize - 1; } else { if (match_four_chars((unsigned char *)hdrbuf, I_MDAT)) { data_location = offset + 12; happy = false; } } } chunkloc = (8 + chunksize); if (chunksize & 1) chunkloc++; /* extra null appended to odd-length chunks */ } if (data_location == 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: no MDAT chunk?", filename)); true_file_length = SEEK_FILE_LENGTH(fd); if (data_size > true_file_length) { data_size = true_file_length - data_location; if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %lld?", filename, data_size)); } data_size = mus_bytes_to_samples(sample_type, data_size); return(MUS_NO_ERROR); } /* ------------------------------------ CSL ------------------------------------- * * "Computerized Speech Labs -- this info taken from wavesurfer/snack * * very similar to AIFF: * 0: FORM * 4: DS16 (kinda weird) * 8: size (int le) * 12: chunks * HEDR or HDR8 * 4: size (int) * samp: short, chans: 1 at 36 if not (int) -1, chans: 2? * srate at 28 (le int?) * other chunks: SD_B, SDA_ SDAB with data bytes as data followed by data */ static int read_csl_header(const char *filename, int fd) { static const unsigned char I_HEDR[4] = {'H','E','D','R'}; static const unsigned char I_HDR8[4] = {'H','D','R','8'}; static const unsigned char I_SDA_[4] = {'S','D','A','_'}; static const unsigned char I_SDAB[4] = {'S','D','A','B'}; static const unsigned char I_SD_B[4] = {'S','D','_','B'}; static const unsigned char I_NOTE[4] = {'N','O','T','E'}; int offset, chunkloc; bool happy = true; type_specifier = mus_char_to_uninterpreted_int((unsigned char *)hdrbuf); chunkloc = 12; offset = 0; sample_type = MUS_LSHORT; srate = 0; chans = 1; update_form_size = mus_char_to_lint((unsigned char *)(hdrbuf + 8)); while (happy) { int chunksize; offset += chunkloc; if (seek_and_read(fd, (unsigned char *)hdrbuf, offset, 64) <= 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s csl header: chunks confused at %d", filename, offset)); chunksize = mus_char_to_lint((unsigned char *)(hdrbuf + 4)); if ((chunksize == 0) && /* can be empty data chunk? */ (hdrbuf[0] == 0) && (hdrbuf[1] == 0) && (hdrbuf[2] == 0) && (hdrbuf[3] == 0)) break; if (chunksize < 0) break; if ((match_four_chars((unsigned char *)hdrbuf, I_HEDR)) || (match_four_chars((unsigned char *)hdrbuf, I_HDR8))) { /* 8..20: date as ascii */ /* 32: data length (int) in bytes */ if ((mus_char_to_lshort((unsigned char *)(hdrbuf + 36)) != -1) && /* these are maxamps, -1=none */ (mus_char_to_lshort((unsigned char *)(hdrbuf + 38)) != -1)) chans = 2; srate = mus_char_to_lint((unsigned char *)(hdrbuf + 28)); } else { if (match_four_chars((unsigned char *)hdrbuf, I_NOTE)) { comment_start = offset + 8; comment_end = comment_start + chunksize - 1; } else { if ((match_four_chars((unsigned char *)hdrbuf, I_SDA_)) || (match_four_chars((unsigned char *)hdrbuf, I_SDAB)) || (match_four_chars((unsigned char *)hdrbuf, I_SD_B))) { data_location = offset + 8; data_size = mus_char_to_lint((unsigned char *)(hdrbuf + 4)); happy = false; } } } chunkloc = (8 + chunksize); if (chunksize & 1) chunkloc++; } if (data_location == 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: no SDxx chunk?", filename)); true_file_length = SEEK_FILE_LENGTH(fd); if (data_size > true_file_length) { data_size = true_file_length - data_location; if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %lld?", filename, data_size)); } data_size = mus_bytes_to_samples(sample_type, data_size); return(MUS_NO_ERROR); } /* ------------------------------------ snack SMP ------------------------------------- * * there's apparently yet another "smp" format (from nist??) * file = samp * sftot = 22050 * msb = last * nchans = 1 * preemph = none * born = snack * msb = last here -> little endian? * data at 1024 */ static int read_file_samp_header(const char *filename, int fd) { int i = 0; unsigned char *locbuf; data_location = 1024; chans = 1; srate = 8000; sample_type = MUS_LSHORT; lseek(fd, 10, SEEK_SET); locbuf = (unsigned char *)calloc(1024, sizeof(unsigned char)); header_read(fd, locbuf, 1024); while (i < 1024) { if (strncmp((char *)(locbuf + i), "sftot", 5) == 0) sscanf((const char *)(&locbuf[i + 6]), "%12d", &srate); if (strncmp((char *)(locbuf + i), "nchans", 6) == 0) sscanf((const char *)(&locbuf[i + 7]), "%12d", &chans); if (strncmp((char *)(locbuf + i), "msb", 3) == 0) if (strncmp((char *)(locbuf + i + 4), "first", 5) == 0) sample_type = MUS_BSHORT; while ((i < 1024) && (locbuf[i] != 10) && (locbuf[i] != 0)) i++; i++; } free(locbuf); true_file_length = SEEK_FILE_LENGTH(fd); if (true_file_length < data_location) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_location %lld > file length: %lld", filename, data_location, true_file_length)); data_size = mus_bytes_to_samples(sample_type, true_file_length - data_location); return(MUS_NO_ERROR); } /* ------------------------------------ Sound Designer I ------------------------------------- * * complicated and defined in terms of Pascal records, so the following is a stab in the dark: * * 0: 1336 (i.e. header size) * 764: comment (str255) * 1020: sample rate (long) * 1028: data size (short) * 1030: a code string describing the data type (i.e. "linear") (str32) * 1064: user comment (str255) * * file type: 'SFIL' * * always big_endian */ static int read_sd1_header(const char *filename, int fd) { int n; chans = 1; data_location = 1336; lseek(fd, 1020, SEEK_SET); if (read(fd, hdrbuf, 64) != 64) return(mus_error(MUS_HEADER_READ_FAILED, "%s Sound Designer I header truncated?", filename)); srate = mus_char_to_bint((unsigned char *)hdrbuf); n = mus_char_to_bshort((unsigned char *)(hdrbuf + 8)); if (n == 16) sample_type = MUS_BSHORT; else sample_type = MUS_BYTE; true_file_length = SEEK_FILE_LENGTH(fd); if (true_file_length < data_location) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_location %lld > file length: %lld", filename, data_location, true_file_length)); data_size = mus_bytes_to_samples(sample_type, true_file_length - data_location); n = ((unsigned char)hdrbuf[44]); if (n != 0) { comment_start = 1064; comment_end = comment_start + n - 1; } return(MUS_NO_ERROR); } /* ------------------------------------ PSION alaw ------------------------------------- * * 0: "ALawSoundFile**" * 16: version * 18: length (bytes) * 22: padding * 24: repeats * 26-32: nada * 32: data * * always mono 8-bit alaw 8000 Hz. All the examples on the psion net site appear to be little endian. */ static int read_psion_header(const char *filename, int fd) { if ((hdrbuf[13] != '*') || (hdrbuf[14] != '*')) return(mus_error(MUS_HEADER_READ_FAILED, "%s: PSION[13, 14] != '*'", filename)); chans = 1; data_location = 32; srate = 8000; sample_type = MUS_ALAW; data_size = mus_char_to_lint((unsigned char *)(hdrbuf + 18)); /* always little-endian? */ true_file_length = SEEK_FILE_LENGTH(fd); if (data_size > true_file_length) { data_size = true_file_length - data_location; if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %lld?", filename, data_size)); } data_size = mus_bytes_to_samples(sample_type, data_size); return(MUS_NO_ERROR); } /* ------------------------------------ Gravis Ultrasound Patch ------------------------------------- * * http://www.gravis.com/Public/sdk/PATCHKIT.ZIP * * header [128], instruments [62], layers [49], waveheaders (nested) * always little endian, actual files don't match exactly with any documentation * * Header block: * 0: "GF1PATCH100" or "GF1PATCH110" * 12: "ID#000002" * 22: comment (copyright notice) (60 bytes ASCIZ) * 82: number of instruments * 83: number of voices * 84: wave channels * 85: number of waves * 87: vol * 89: size? * 93: reserved (36? bytes) * * Instrument block: * 0: id * 2: name (16 bytes) * 18: size * 22: number of layers * 23: reserved (40? bytes) * * Layer block: * 0: "previous" * 1: id * 2: size * 6: number of wave samples * 10: reserved (40? bytes) * * Wave block: * 0: name (7 bytes ASCIZ) * 7: "fractions" * 8: data size of wave sample * 12: loop start * 16: loop end * 20: sample rate * 22: low freq * 26: high freq * 30: root freq * 34: tune * 36: balance * 37: envelope data (6+6 bytes I think) * 49: tremolo and vibrato data (6 bytes) * 55: mode bit 0: 8/16, 1: signed/unsigned * 56: scale freq * 58: scale factor * 60: reserved (36 bytes) * followed by data presumably */ static int read_gravis_header(const char *filename, int fd) { int mode; chans = hdrbuf[84]; if (chans == 0) chans = 1; comment_start = 22; comment_end = 81; lseek(fd, 239, SEEK_SET); /* try to jump to wave sample block (128+62+49) */ header_read(fd, hdrbuf, 128); srate = mus_char_to_ulshort((unsigned char *)(hdrbuf + 20)); data_size = mus_char_to_ulshort((unsigned char *)(hdrbuf + 8)); mode = hdrbuf[55]; if (mode & 1) { if (mode & 2) sample_type = MUS_ULSHORT; else sample_type = MUS_LSHORT; } else { if (mode & 2) sample_type = MUS_UBYTE; else sample_type = MUS_BYTE; } data_location = 337; true_file_length = SEEK_FILE_LENGTH(fd); if (data_size > true_file_length) { data_size = true_file_length - data_location; if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %lld?", filename, data_size)); } data_size = mus_bytes_to_samples(sample_type, data_size); return(MUS_NO_ERROR); } /* ------------------------------------ Goldwave ------------------------------------- * * http://web.cs.mun.ca/~chris3/goldwave/goldwave.html */ static int read_goldwave_header(const char *filename, int fd) { chans = 1; data_location = 28; sample_type = MUS_LSHORT; data_size = mus_char_to_lint((unsigned char *)(hdrbuf + 22)); true_file_length = SEEK_FILE_LENGTH(fd); if (true_file_length < data_location) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_location %lld > file length: %lld", filename, data_location, true_file_length)); if ((data_size <= 24) || (data_size > true_file_length)) data_size = (true_file_length - data_location) / 2; else data_size /= 2; srate = mus_char_to_lint((unsigned char *)(hdrbuf + 18)); return(MUS_NO_ERROR); } /* ------------------------------------ Sonic Resource Foundry ------------------------------------- * * more reverse engineering... * http://www.sfoundry.com/ */ static int read_srfs_header(const char *filename, int fd) { chans = 1; /* might be short at header[4] */ data_location = 32; true_file_length = SEEK_FILE_LENGTH(fd); if (true_file_length < data_location) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_location %lld > file length: %lld", filename, data_location, true_file_length)); data_size = (true_file_length - data_location) / 2; srate = mus_char_to_lint((unsigned char *)(hdrbuf + 6)); sample_type = MUS_LSHORT; return(MUS_NO_ERROR); } /* ------------------------------------ Quicktime ------------------------------------- * * infinitely complicated -- see Quicktime File Format doc from Apple. * there's no relation between this document and actual files -- a bizarre joke? */ static int read_qt_header(const char *filename, int fd) { chans = 1; data_location = 12; true_file_length = SEEK_FILE_LENGTH(fd); data_size = (true_file_length - data_location); if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %lld?", filename, data_size)); srate = 11025; /* ?? */ sample_type = MUS_UBYTE; return(MUS_NO_ERROR); } /* ------------------------------------ SBStudioII ------------------------------------- * * from a file created by Convert 1.4 * 0: SND * 8: file size - 8 * SNNA SNIN SNDT blocks: * * built in blocks, other names are SNIN, SNDT * need to scan for SNDT, block length, data * SNNA len name * supposedly ends with END (but my examples don't) * SNIN: * num (2), reserved (2), tuning (1), vol (2), type (2) bit 0: 1 = PCM, bit 1: 1 = 16, 0 = 8 (then loop data) * info from Pac.txt (pac.zip) at http://www.wotsit.org/music.htm */ static int read_sbstudio_header(const char *filename, int fd) { static const unsigned char I_SNIN[4] = {'S','N','I','N'}; static const unsigned char I_SNNA[4] = {'S','N','N','A'}; static const unsigned char I_SNDT[4] = {'S','N','D','T'}; int i, tmp; bool happy = true; unsigned char *bp; chans = 1; srate = 8000; /* no sampling rate field in this header */ sample_type = MUS_UNKNOWN_SAMPLE; true_file_length = SEEK_FILE_LENGTH(fd); i = 8; bp = (unsigned char *)(hdrbuf + 8); while (happy) { if (match_four_chars(bp, I_SNDT)) { data_size = mus_char_to_lint((unsigned char *)(bp + 4)); data_location = i + 8; happy = false; } else { if (match_four_chars(bp, I_SNIN)) { tmp = mus_char_to_lshort((unsigned char *)(bp + 15)); if ((tmp & 1) == 0) sample_type = MUS_UNKNOWN_SAMPLE; else { if ((tmp & 2) == 0) sample_type = MUS_BYTE; else sample_type = MUS_LSHORT; } i += 26; bp += 26; } else { if (match_four_chars(bp, I_SNNA)) { tmp = mus_char_to_lint((unsigned char *)(bp + 4)); i += tmp; bp += tmp; } else { i++; bp++; } } } if (i >= HDRBUFSIZ) { sample_type = MUS_UNKNOWN_SAMPLE; happy = false; } } if (data_location == 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: no SNDT chunk?", filename)); if ((data_size == 0) || (sample_type == MUS_UNKNOWN_SAMPLE)) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data size or sample type bogus", filename)); if (data_size > true_file_length) { data_size = true_file_length - data_location; if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %lld?", filename, data_size)); } data_size = mus_bytes_to_samples(sample_type, data_size); return(MUS_NO_ERROR); } /* ------------------------------------ Delusion Sound ------------------------------------- * * more reverse engineering... * from a file created by Convert 1.4 * 0: DDSF * 5: name (text) * 55: data * probaby similar to DMF format described in Dmf-form.txt but I don't see any other block names in the data */ static int read_delusion_header(const char *filename, int fd) { if ((hdrbuf[4] != 1) || (hdrbuf[5] > 128) || (hdrbuf[6] > 128) || (hdrbuf[7] > 128)) return(mus_error(MUS_HEADER_READ_FAILED, "%s DDSF name bogus", filename)); chans = 1; data_location = 55; true_file_length = SEEK_FILE_LENGTH(fd); data_size = (true_file_length - data_location); if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %lld?", filename, data_size)); srate = 8000; sample_type = MUS_LSHORT; data_size = mus_bytes_to_samples(sample_type, data_size); return(MUS_NO_ERROR); } /* ------------------------------------ Farandole Composer WaveSample ------------------------------------- * * 0: FSM 254 * libmodplug load_far.cpp uses: #define FARFILEMAGIC 0xFE524146 ("FAR="?) * 4: name (text) (32 bytes) * 36: 10, 13, 26 or something like that * 39: len? * 40: volume * 41: looping data * 49: type (0 = 8-bit, else 16) * 50: loop mode * 51: data * described in Fsm.txt and Far-form.txt http://www.wotsit.org/music.htm */ static int read_farandole_header(const char *filename, int fd) { chans = 1; data_location = 51; true_file_length = SEEK_FILE_LENGTH(fd); data_size = (true_file_length - data_location); if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %lld?", filename, data_size)); srate = 8000; if (hdrbuf[49] == 0) sample_type = MUS_BYTE; else sample_type = MUS_LSHORT; data_size = mus_bytes_to_samples(sample_type, data_size); return(MUS_NO_ERROR); } /* ------------------------------------ Yamaha TX-16W ------------------------------------- * * ftp://ftp.t0.or.at/pub/sound/tx16w/samples.yamaha * ftp://ftp.t0.or.at/pub/sound/tx16w/faq/tx16w.tec * http://www.t0.or.at/~mpakesch/tx16w/ * * from tx16w.c sox 12.15: (7-Oct-98) (Mark Lakata and Leigh Smith) * char filetype[6] "LM8953" * nulls[10], * dummy_aeg[6] * format 0x49 = looped, 0xC9 = non-looped * sample_rate 1 = 33 kHz, 2 = 50 kHz, 3 = 16 kHz * atc_length[3] if sample rate 0, [2]&0xfe = 6: 33kHz, 0x10:50, 0xf6: 16, depending on [5] but to heck with it * rpt_length[3] (these are for looped samples, attack and loop lengths) * unused[2] */ static int read_tx16w_header(const char *filename, int fd) { if ((hdrbuf[4] != '5') || (hdrbuf[5] != '3')) return(mus_error(MUS_HEADER_READ_FAILED, "%s TX16 magic number bogus", filename)); chans = 1; data_location = 32; true_file_length = SEEK_FILE_LENGTH(fd); data_size = (true_file_length - data_location); if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %lld?", filename, data_size)); srate = 16000; if (hdrbuf[23] == 1) srate = 33000; else if (hdrbuf[23] == 2) srate = 50000; else if (hdrbuf[23] == 3) srate = 16000; else if (hdrbuf[23] == 0) { if ((hdrbuf[26] & 0xFE) == 6) srate = 33000; else if ((hdrbuf[26] & 0xFE) == 0x10) srate = 50000; else if ((hdrbuf[26] & 0xFE) == 0xf6) srate = 16000; } original_sample_type = MUS_UNKNOWN_SAMPLE; sample_type = MUS_UNKNOWN_SAMPLE; data_size = (mus_long_t)((double)data_size / 1.5); if (hdrbuf[22] == 0x49) { loop_modes[0] = 1; loop_starts[0] = ((hdrbuf[26] & 1) << 16) + (hdrbuf[25] << 8) + hdrbuf[24]; loop_ends[0] = loop_starts[0] + ((hdrbuf[29] & 1) << 16) + (hdrbuf[28] << 8) + hdrbuf[27]; } return(MUS_NO_ERROR); } /* ------------------------------------ Yamaha SY-85 and SY-99 ------------------------------------- * * more reverse engineering... * 0: SY85 (SY80 is SY-99) SY85ALL SY80 SYALL * 5: name ("WAVE1") * (26 int len) * (33: comment or prompt?) * data in 16-bit little endian (?) */ static int read_sy85_header(const char *filename, int fd) { if ((hdrbuf[4] != ' ') && (hdrbuf[4] != 'A')) return(mus_error(MUS_HEADER_READ_FAILED, "%s: unknown magic number", filename)); chans = 1; data_location = 1024; true_file_length = SEEK_FILE_LENGTH(fd); data_size = (true_file_length - data_location); if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %lld?", filename, data_size)); srate = 8000; /* unknown */ sample_type = MUS_BSHORT; /* not right */ data_size = mus_bytes_to_samples(sample_type, data_size); return(MUS_NO_ERROR); } /* ------------------------------------ Kurzweil 2000 ------------------------------------- * * "PRAM" then header len as big endian int?? * from krz2tx.c (Mark Lakata) */ static int read_kurzweil_2000_header(const char *filename, int fd) { chans = 1; data_location = mus_char_to_bint((unsigned char *)(hdrbuf + 4)); true_file_length = SEEK_FILE_LENGTH(fd); data_size = (true_file_length - data_location); if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %lld?", filename, data_size)); srate = 44100; /* unknown */ sample_type = MUS_BSHORT; data_size = mus_bytes_to_samples(sample_type, data_size); return(MUS_NO_ERROR); } /* ------------------------------------ Korg ------------------------------------- * * "SMP1" -- guessing on the rest */ static int read_korg_header(const char *filename, int fd) { chans = 1; data_location = 70; true_file_length = SEEK_FILE_LENGTH(fd); data_size = (true_file_length - data_location); if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %lld?", filename, data_size)); srate = mus_char_to_bint((unsigned char *)(hdrbuf + 48)); sample_type = MUS_BSHORT; data_size = mus_bytes_to_samples(sample_type, data_size); return(MUS_NO_ERROR); } /* ------------------------------------ Maui ------------------------------------- * * "Maui" -- guessing on the rest */ static int read_maui_header(const char *filename, int fd) { lseek(fd, 420, SEEK_SET); if (read(fd, hdrbuf, 64) != 64) return(mus_error(MUS_HEADER_READ_FAILED, "%s truncated maui header?", filename)); chans = 1; data_location = 776; true_file_length = SEEK_FILE_LENGTH(fd); if (true_file_length < data_location) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_location %lld > file length: %lld", filename, data_location, true_file_length)); data_size = mus_char_to_lint((unsigned char *)(hdrbuf + 8)); if ((data_size * 2) > true_file_length) data_size = (true_file_length - data_location) / 2; srate = mus_char_to_lint((unsigned char *)(hdrbuf)); sample_type = MUS_LSHORT; return(MUS_NO_ERROR); } /* ------------------------------------ Impulse Tracker ------------------------------------- * * data from its2raw.c by Ben Collver * 0: IMPS * 4: filename (12 bytes) * 17: global vol * 18: flags (1: 16-bit or 8(0), 2: stereo or mono(0) * 19: default vol * 20: sample name (26 bytes) * 46: convert * 47: default pan * 48: length (samps) * 52: loop start * 56: loop end * 60: srate * 64: sustain loop start * 68: sustain loop end * 72: data location * 76: vib speed * 77: vib depth * 78: vib wave * 79: vib rate */ static int read_impulsetracker_header(const char *filename, int fd) { if (hdrbuf[18] & 4) chans = 2; else chans = 1; if (hdrbuf[18] & 2) sample_type = MUS_LSHORT; else sample_type = MUS_BYTE; data_location = mus_char_to_lint((unsigned char *)(hdrbuf + 72)); true_file_length = SEEK_FILE_LENGTH(fd); if (true_file_length < data_location) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_location %lld > file length: %lld", filename, data_location, true_file_length)); data_size = (true_file_length - data_location); srate = mus_char_to_lint((unsigned char *)(hdrbuf + 60)); data_size = mus_bytes_to_samples(sample_type, data_size); return(MUS_NO_ERROR); } #if 0 /* ------------------------------------ AKAI 3? ------------------------------------- */ static int read_akai3_header(const char *filename, int fd) { chans = 1; data_location = 192; true_file_length = SEEK_FILE_LENGTH(fd); data_size = (true_file_length - data_location); if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %lld?", filename, data_size)); if (hdrbuf[1] == 0) srate = 22050; else srate = 44100; sample_type = MUS_LSHORT; data_size = mus_bytes_to_samples(sample_type, data_size); return(MUS_NO_ERROR); } #endif /* ------------------------------------ AKAI 4 ------------------------------------- * * 1, 4, info from Paul Kellet -- lost the url ("MPC-2000") */ static int read_akai4_header(const char *filename, int fd) { chans = hdrbuf[21] + 1; data_location = 42; true_file_length = SEEK_FILE_LENGTH(fd); data_size = (true_file_length - data_location); if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %lld?", filename, data_size)); srate = mus_char_to_ulshort((unsigned char *)(hdrbuf + 40)); sample_type = MUS_LSHORT; data_size = mus_bytes_to_samples(sample_type, data_size); return(MUS_NO_ERROR); } /* ------------------------------------ PVF (portable voice format) ------------------------------------- * * info from mgetty-voice-1.1.22/voice/libpvf/lib.c * this is a modem-related interchange format * * PVF1\n * 1 11025 32\n * then data * PVF1 = binary data, PVF2 = ascii * chans | srate | sample size */ static int read_pvf_header(const char *filename, int fd) { char *buf; int bits, i; if (hdrbuf[4] != '\n') return(mus_error(MUS_HEADER_READ_FAILED, "PVF header messed up")); type_specifier = mus_char_to_uninterpreted_int((unsigned char *)hdrbuf); buf = (char *)(hdrbuf + 5); sscanf(buf, "%12d %12d %12d", &chans, &srate, &bits); if (chans < 1) chans = 1; if (srate < 0) srate = 8000; if (bits < 8) bits = 8; for (i = 6; i < INITIAL_READ_SIZE; i++) if (hdrbuf[i] == '\n') { data_location = i + 1; break; } if (data_location == 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s PVF header bad data location", filename)); if (match_four_chars((unsigned char *)hdrbuf, I_PVF2)) { sample_type = MUS_UNKNOWN_SAMPLE; /* ascii text */ return(mus_error(MUS_HEADER_READ_FAILED, "%s PVF header unknown sample type", filename)); } /* big endian data -- they're using htonl etc */ if (bits == 8) sample_type = MUS_BYTE; else if (bits == 16) sample_type = MUS_BSHORT; else sample_type = MUS_BINT; true_file_length = SEEK_FILE_LENGTH(fd); data_size = mus_bytes_to_samples(sample_type, true_file_length - data_location); return(MUS_NO_ERROR); } /* ------------------------------------ Ultratracker WaveSample ------------------------------------- * * 0..31: name (32 = ctrl-Z?) * 33: PMUWFD (but docs say this is "dos name" -- perhaps we can't recognize this header type reliably) * 44: 4 ints giving loop and size data * 60: vol * 61: "bidi" 0|8|24->8 bit else 16 -- but actual example has 0 with 16-bit * 62: finetune * 64: data (or 68?) * described in Ult-form.txt http://www.wotsit.org/music.htm */ static int read_ultratracker_header(const char *filename, int fd) { chans = 1; data_location = 64; true_file_length = SEEK_FILE_LENGTH(fd); if (true_file_length < data_location) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_location %lld > file length: %lld", filename, data_location, true_file_length)); data_size = (true_file_length - data_location); srate = 8000; sample_type = MUS_LSHORT; data_size = mus_bytes_to_samples(sample_type, data_size); return(MUS_NO_ERROR); } /* ------------------------------------ Sample dump exchange ------------------------------------- * * 0: SDX: * sdx2tx.c (Mark Lakata) reads from 4 for 26 (^z), then * version (1) * comment as pascal-style string (byte len, bytes chars) * then 23 bytes: * 0: packing (0 = pcm) * 1: midi channel * 2 + 256*[3]: sample number * 4: sample type (15: 16 bit unsigned(?), 8: 8bit unsigned(?) * 5: sample rate (big int?) * 9: sample length * 13: loop start * 17: loop end * 21: loop type * 22: reserved */ static int read_sample_dump_header(const char *filename, int fd) { int i, len; for (i = 4; i < HDRBUFSIZ; i++) if (hdrbuf[i] == 26) break; len = hdrbuf[i + 2]; if (len > 0) { comment_start = i + 3; comment_end = i + 3 + len; } seek_and_read(fd, (unsigned char *)hdrbuf, i + 3 + len, HDRBUFSIZ); srate = mus_char_to_lint((unsigned char *)(hdrbuf + 5)); loop_modes[0] = 0; if (hdrbuf[21] == 0) { loop_modes[0] = 1; loop_starts[0] = mus_char_to_lint((unsigned char *)(hdrbuf + 13)); loop_ends[0] = mus_char_to_lint((unsigned char *)(hdrbuf + 17)); } /* data_size = mus_char_to_lint((unsigned char *)(hdrbuf + 9)); */ if ((srate < 100) || (srate > 100000)) srate = 8000; chans = 1; data_location = i + 3 + len + 23; true_file_length = SEEK_FILE_LENGTH(fd); data_size = (true_file_length - data_location); if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %lld?", filename, data_size)); if (hdrbuf[0] == 0) sample_type = MUS_ULSHORT; else sample_type = MUS_UNKNOWN_SAMPLE; data_size = mus_bytes_to_samples(sample_type, data_size); return(MUS_NO_ERROR); } /* ------------------------------------ Digiplayer ST3 ------------------------------------- * * 0: 1 (use 'SCRS' at 76) * 1: name * 13: nada * 14: "paragraph" offset of sample data * 16: length in bytes (looks like #samples in the actual files...) * 20: loop start * 24: loop end * 28: vol * 29: ? * 30: 0 = unpacked, 1 = DP30ADPCM * 31: bits: 0 = loop, 1 = stereo (chans not interleaved!), 2 = 16-bit samples (little endian) * 32: freq * 36: nada * 40: nada * 42: 512 * 44: date? * 48: sample name (28 char ASCIZ) * 76: 'SCRS' * 80: data starts * * info from http://www.wotsit.org/ S3m-form.txt */ static int read_digiplayer_header(const char *filename, int fd) { chans = 1; data_location = 80; true_file_length = SEEK_FILE_LENGTH(fd); data_size = (true_file_length - data_location); if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %lld?", filename, data_size)); srate = 8000; sample_type = MUS_ULSHORT; if (hdrbuf[30] & 2) chans = 2; if (hdrbuf[30] & 1) sample_type = MUS_UNKNOWN_SAMPLE; else { if (hdrbuf[30] & 4) sample_type = MUS_UBYTE; /* may be backwards -- using Convert 1.4 output here */ } data_size = mus_bytes_to_samples(sample_type, data_size); return(MUS_NO_ERROR); } /* ------------------------------------ CSRE adf ------------------------------------- * * Info from Stuart Rosen * * 0-7: CSRE40 * 8: samples in file (long) * 12: center line(?) (long) * 16: start channel(?) (unsigned) * 18: bits -- 12 or 16 (unsigned) -- is 12 bit sample file packed? * 20: number system (0 = signed, 1 = unsigned) * 22: srate in kHz (float) * 26: peak sample in file (long) (can be 0) * 30-511: comment possibly * * probably always little-endian (S.R. reads each sample using sizeof(int) -> 16 bits I think) * if 12-bit unsigned we need to handle the offset somewhere */ static int read_adf_header(const char *filename, int fd) { int bits, numsys; lseek(fd, 0, SEEK_SET); if ((hdrbuf[4] != '4') || (hdrbuf[5] != '0')) return(mus_error(MUS_HEADER_READ_FAILED, "%s csre header bad magic number", filename)); if (read(fd, hdrbuf, 30) != 30) return(mus_error(MUS_HEADER_READ_FAILED, "%s csre header truncated?", filename)); chans = 1; numsys = mus_char_to_ulshort((unsigned char *)(hdrbuf + 20)); bits = mus_char_to_ulshort((unsigned char *)(hdrbuf + 18)); if ((bits == 16) || (bits == 12)) { if (numsys == 0) sample_type = MUS_LSHORT; else sample_type = MUS_ULSHORT; } else sample_type = MUS_UNKNOWN_SAMPLE; srate = (int)(1000 * mus_char_to_lfloat((unsigned char *)(hdrbuf + 22))); data_size = mus_char_to_lint((unsigned char *)(hdrbuf + 8)); data_location = 512; true_file_length = SEEK_FILE_LENGTH(fd); if (true_file_length < data_location) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_location %lld > file length: %lld", filename, data_location, true_file_length)); if (data_size > mus_bytes_to_samples(sample_type, true_file_length - data_location)) data_size = mus_bytes_to_samples(sample_type, true_file_length - data_location); return(MUS_NO_ERROR); } /* ------------------------------------ Diamondware ------------------------------------- * * info from Keith Weiner at DiamondWare (www.dw.com): * * 0-22: DWD Header Byte "DiamondWare Digitized\n\0" * 23: 1A (EOF to abort printing of file) * 24: Major version number * 25: Minor version number * 26-29: Unique sound ID (checksum XOR timestamp) * 30: Reserved * 31: Compression type (0 = none) * 32-33: Sampling rate (in Hz) * 34: Number of channels (1 = mono, 2 = stereo) (interleaved) * 35: Number of bits per sample (8, 16) (all data signed) * 36-37: Absolute value of largest sample in file * 38-41: length of data section (in bytes) * 42-45: # samples (16-bit stereo is 4 bytes/sample) * 46-49: Offset of data from start of file (in bytes) * 50-53: Reserved for future expansion (markers) * 54-55: Padding * 56:offset -- additional text: field = value * suggested fields: TITLE, ORGARTIST, GENRE, KEYWORDS, ORGMEDIUM, EDITOR, DIGITIZER, COMMENT, SUBJECT, COPYRIGHT, SOFTWARE, CREATEDATE * * since this is all Windows/DOS oriented, I'll assume little-endian byte order. */ static int read_diamondware_header(const char *filename, int fd) { chans = hdrbuf[34]; if (hdrbuf[31] == 0) { if (hdrbuf[35] == 8) sample_type = MUS_BYTE; else sample_type = MUS_LSHORT; } else { sample_type = MUS_UNKNOWN_SAMPLE; return(mus_error(MUS_HEADER_READ_FAILED, "%s unknown sample type", filename)); } srate = mus_char_to_ulshort((unsigned char *)(hdrbuf + 32)); data_size = mus_char_to_lint((unsigned char *)(hdrbuf + 38)); data_location = mus_char_to_lint((unsigned char *)(hdrbuf + 46)); true_file_length = SEEK_FILE_LENGTH(fd); if (true_file_length < data_location) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_location %lld > file length: %lld", filename, data_location, true_file_length)); if (data_size > true_file_length - data_location) data_size = true_file_length - data_location; data_size = mus_bytes_to_samples(sample_type, data_size); return(MUS_NO_ERROR); } /* ------------------------------------ Ensoniq Paris ------------------------------------- * _paf -> Ensoniq Paris? (this info from libaudiofile) * 0 paf (or fap) * 4 version (0) * 8 endianess (0 = big) * 12 rate (unsigned int) * 16 format (0: 16-bit linear, 24-bit linear) * 20 channels * 24 source (an encoded comment) * 2048 data (24 bit files are compressed) */ static int read_paf_header(const char *filename, int fd) { int form; bool little = false; sample_type = MUS_UNKNOWN_SAMPLE; if (mus_char_to_bint((unsigned char *)(hdrbuf + 8))) little = true; if (little) { srate = mus_char_to_ulint((unsigned char *)(hdrbuf + 12)); form = mus_char_to_ulint((unsigned char *)(hdrbuf + 16)); if (form == 0) sample_type = MUS_LSHORT; if (form == 2) sample_type = MUS_BYTE; chans = mus_char_to_ulint((unsigned char *)(hdrbuf + 20)); } else { srate = mus_char_to_ubint((unsigned char *)(hdrbuf + 12)); form = mus_char_to_ubint((unsigned char *)(hdrbuf + 16)); if (form == 0) sample_type = MUS_BSHORT; if (form == 2) sample_type = MUS_BYTE; chans = mus_char_to_ubint((unsigned char *)(hdrbuf + 20)); } data_location = 2048; true_file_length = SEEK_FILE_LENGTH(fd); if (true_file_length < data_location) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_location %lld > file length: %lld", filename, data_location, true_file_length)); if (sample_type != MUS_UNKNOWN_SAMPLE) data_size = mus_bytes_to_samples(sample_type, true_file_length - 2048); return(MUS_NO_ERROR); } /* ------------------------------------ Comdisco SPW ------------------------------------- * info from AFsp libtsp/AF/nucleus/AFgetSWpar.c * * header is text as in NIST: * * $SIGNAL_FILE 9\n (12 chars) * $USER_COMMENT * * $COMMON_INFO * SPW Version = 3.10 * System Type = (e.g. "sun4", "hp700") * Sampling Frequency = (e.g. "8000") * Starting Time = 0 * $DATA_INFO * Number of points = (e.g. "2000") * Signal Type = ("Double", "Float", "Fixed-point", "Integer", "Logical") * Fixed Point Format = <16, 0, t> <16, 16, t> <8, 8, t> <8, 0, t> (optional) * Complex Format = Real_Imag (optional) * $DATA ("ASCII", "BINARY") * * the fixed point is decoded as n = number of bits total per sample, m = integer bits, b = t: signed, u: unsigned * if $DATA ASCII, data is ascii text as in IEEE text files. * There are other complications as well. We'll just hack up a stop-gap until someone complains. */ static int read_comdisco_header(const char *filename, int fd) { /* need to grab a line at a time, call strcmp over and over. This is very tedious. */ char *line = NULL; int i, j, k, m, n, curend, offset, len, type, d_size = 0; bool happy = true, little, commenting; k = 15; line = (char *)calloc(256, sizeof(char)); little = false; offset = 0; type = 0; srate = 0; curend = INITIAL_READ_SIZE; commenting = false; while (happy) { for (i = 0; i < 256; i++) { if (k == curend) { offset += curend; if (read(fd, hdrbuf, HDRBUFSIZ) != HDRBUFSIZ) { free(line); return(mus_error(MUS_HEADER_READ_FAILED, "%s comdisco header truncated?", filename)); } k = 0; curend = HDRBUFSIZ; } if (hdrbuf[k] == '\n') { k++; break; } line[i] = hdrbuf[k++]; } line[i] = '\0'; if ((strcmp(line, "$DATA BINARY") == 0) || (strcmp(line, "$DATA ASCII") == 0)) { happy = false; data_location = offset + k; } if (strcmp(line, "$USER_COMMENT") == 0) { comment_start = offset + k; commenting = true; } else { if (commenting) { if (line[0] == '$') { comment_end = offset + k - 2 - strlen(line); commenting = false; } } } if (line[0] != '$') { char portion[32]; char value[32]; len = strlen(line); for (j = 0; j < 8; j++) portion[j] = line[j]; portion[8] ='\0'; for (j = 8; j < len; j++) if (line[j] == '=') break; for (n = 0, m = j + 2; m < len; m++, n++) value[n] = line[m]; value[n] ='\0'; if (strcmp(portion, "Sampling") == 0) sscanf(value, "%12d", &srate); else if (strcmp(portion, "Number o") == 0) sscanf(value, "%12d", &d_size); else if (strcmp(portion, "Signal T") == 0) {if (value[1] == 'o') type = 2; else if (value[1] == 'l') type = 1;} else if (strcmp(portion, "Fixed Po") == 0) {if (value[1] == '8') type = 3;} } } /* now clean up this mess */ if (data_location == 0) {free(line); return(mus_error(MUS_HEADER_READ_FAILED, "%s: no $DATA BINARY field?", filename));} if (srate == 0) {free(line); return(mus_error(MUS_HEADER_READ_FAILED, "%s: srate == 0", filename));} chans = 1; if (d_size != 0) data_size = (mus_long_t)d_size; switch (type) { case 0: if (little) sample_type = MUS_LSHORT; else sample_type = MUS_BSHORT; break; case 1: if (little) sample_type = MUS_LFLOAT; else sample_type = MUS_BFLOAT; break; case 2: if (little) sample_type = MUS_LDOUBLE; else sample_type = MUS_BDOUBLE; break; case 3: sample_type = MUS_BYTE; break; } true_file_length = SEEK_FILE_LENGTH(fd); if (data_size > mus_bytes_to_samples(sample_type, true_file_length - data_location)) data_size = mus_bytes_to_samples(sample_type, true_file_length - data_location); free(line); return(MUS_NO_ERROR); } /* ------------------------------------ MS ASF ------------------------------------- * * asf format is described at http://www.microsoft.com/asf/specs.htm * http://www.microsoft.com/asf/spec3/ASF0198ps.exe * * this header is completely insane */ static int read_asf_header(const char *filename, int fd) { /* a chunked sample type, so not really acceptable here or elsewhere -- needs to be unchunked */ int len, ilen = 0, i, j, bits = 0; bool asf_huge = false, present; /* apparently "huge" has some meaning in Windoze C */ len = mus_char_to_lint((unsigned char *)(hdrbuf + 16)); /* actually 64 bits */ i = (128+64) / 8; srate = 0; chans = 0; while (i < len) { seek_and_read(fd, (unsigned char *)hdrbuf, i, HDRBUFSIZ); if ((unsigned int)(hdrbuf[1]) == 0x29) switch (hdrbuf[0]) { case 0xd0: asf_huge = (hdrbuf[((128+64+128+64+64+64+64+32)/8)] & 2); break; case 0xd4: present = ((hdrbuf[16+8+16+8+8+ 4+4+4+4+ 4+4] >> 3) & 0x3); if (present) j = 16+8+16+8+8+ 4+4+4+4+ 4+4+ 4+ (4+4+4) + 2; else j = 16+8+16+8+8+ 4+4+4+4+ 4+4+ 4+ 2; srate = mus_char_to_lint((unsigned char *)(hdrbuf + j+11+36)); bits = mus_char_to_lint((unsigned char *)(hdrbuf + j+11+32)); chans = mus_char_to_ulshort((unsigned char *)(hdrbuf + j+65)); original_sample_type = mus_char_to_lint((unsigned char *)(hdrbuf + j+11)); break; default: break; } ilen = mus_char_to_lint((unsigned char *)(hdrbuf + 16)); if (ilen <= 0) break; if ((chans > 0) && (srate > 0)) break; i += ilen; } i = len; seek_and_read(fd, (unsigned char *)hdrbuf, i, HDRBUFSIZ); sample_type = MUS_UNKNOWN_SAMPLE; if (((unsigned int)(hdrbuf[1]) == 0x29) && ((unsigned int)(hdrbuf[0]) == 0xd2)) { int a_huge = 2; ilen = mus_char_to_lint((unsigned char *)(hdrbuf + 16)); if (asf_huge) a_huge = 4; data_location = i + 20 + a_huge + 2+4+3+1; if (bits == 0) bits = 8; sample_type = wave_to_sndlib_format(original_sample_type, bits, true); } else return(mus_error(MUS_HEADER_READ_FAILED, "%s: unknown sample type", filename)); data_size = ilen - data_location; true_file_length = SEEK_FILE_LENGTH(fd); if (data_size > true_file_length) { data_size = true_file_length - data_location; if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %lld?", filename, data_size)); } data_size = mus_bytes_to_samples(sample_type, data_size); return(MUS_NO_ERROR); } /* ------------------------------------ Sox ------------------------------------- * sox now has its own format (intended as an intermediate file) * 0: .SoX or .XoS * 4: header_bytes (int) * 8: num_samples (long long int) * 16: srate (double) * 24: chans (int) * 28: comment bytes (int) * 32: comment... [if any] * header_bytes: data (always 32-bit int in native format) */ static int read_sox_header(const char *filename, int fd) { int comment_len; mus_long_t samps; if (match_four_chars((unsigned char *)(hdrbuf + 0), I_dSoX)) { sample_type = MUS_LINTN; samps = mus_char_to_llong((unsigned char *)(hdrbuf + 8)); srate = (int)mus_char_to_ldouble((unsigned char *)(hdrbuf + 16)); little_endian = true; } else { /* untested */ sample_type = MUS_BINTN; samps = mus_char_to_blong((unsigned char *)(hdrbuf + 8)); srate = (int)mus_char_to_bdouble((unsigned char *)(hdrbuf + 16)); little_endian = false; } data_location = 4 + big_or_little_endian_int((unsigned char *)(hdrbuf + 4), little_endian); chans = big_or_little_endian_int((unsigned char *)(hdrbuf + 24), little_endian); comment_len = big_or_little_endian_int((unsigned char *)(hdrbuf + 28), little_endian); if (comment_len > 0) { comment_start = 32; comment_end = comment_start + comment_len; } true_file_length = SEEK_FILE_LENGTH(fd); data_size = (true_file_length - data_location); if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %lld?", filename, data_size)); data_size = mus_bytes_to_samples(sample_type, data_size); if (samps < data_size) data_size = samps; return(MUS_NO_ERROR); } /* ------------------------------------ Matlab 5 ------------------------------------- */ /* info from the matlab site, Gary Scavone's site, and wotsit.org "Mat-File Format" in matlab.zip * * 128 byte header starting with "MATLAB 5.0 MAT-file" * 124: version (normally 0x100) * 126: endianess (the chars 'M' and 'I') * data chunked much like aiff -- 8 bytes: type | number-of-bytes, followed by data * 4 bytes type: 1: s8 2: u8 3: s16 4: u16 5: s32 6: u32 * 7: IEEE 754 single 9: IEEE 754 double 12: s64 13: u64 * 14: array (15 compressed?) * 4 bytes size: (not including the tag) * array types: 6: double 7:float * * I'll assume a sound file is stored as a matlab array * and each separate array is a channel (non-interleaved, so if chans>1 we have to pre-translate it). * */ static int read_matlab_5_header(const char *filename, int fd) { int i, type, loc, size; /* bool swapped = false; */ comment_start = 0; comment_end = 124; for (i = 1; i < 124; i++) if (hdrbuf[i] == 0) { comment_end = i; break; } /* if (mus_char_to_lshort((unsigned char *)(hdrbuf + 126)) == 0x494d) swapped = true; */ /* byte swapping not handled yet */ type = mus_char_to_lint((unsigned char *)(hdrbuf + 128)); if (type != 14) return(mus_error(MUS_HEADER_READ_FAILED, "%s: unknown Matlab sample type (%d)", filename, type)); /* chunksize = mus_char_to_lint((unsigned char *)(hdrbuf + 132)); */ /* now grovel through the array header */ /* assume the "flags" are not interesting */ /* assume "dimensions" = number of samples, but we'll pick that up from the data size */ /* do we care about the original variable name? */ /* should we try to handle multiple signals in a file? as separate channels? */ loc = 136 + 32 + 8; size = mus_char_to_lint((unsigned char *)(hdrbuf + 172)); /* var name len -- need to round up to multiple of 8 */ i = size % 8; if (i == 0) loc += size; else loc += size + 8 - i; type = mus_char_to_lint((unsigned char *)(hdrbuf + loc)); if (type == 9) sample_type = MUS_LDOUBLE; else sample_type = MUS_LFLOAT; data_size = mus_char_to_lint((unsigned char *)(hdrbuf + loc + 4)); chans = 1; srate = 44100; /* a plausible guess */ true_file_length = SEEK_FILE_LENGTH(fd); return(MUS_NO_ERROR); } /* ------------------------------------ no header ------------------------------------- */ static int raw_header_srate = 44100; static int raw_header_chans = 2; static mus_sample_t raw_header_sample_type = MUS_BSHORT; static int read_no_header(int fd) { srate = raw_header_srate; chans = raw_header_chans; sample_type = raw_header_sample_type; data_location = 0; data_size = SEEK_FILE_LENGTH(fd); true_file_length = data_size; data_size = mus_bytes_to_samples(sample_type, data_size); return(MUS_NO_ERROR); } void mus_header_set_raw_defaults(int sr, int chn, mus_sample_t samp_type) { if (sr > 0) raw_header_srate = sr; if (chn > 0) raw_header_chans = chn; if (mus_is_sample_type(samp_type)) raw_header_sample_type = samp_type; } void mus_header_raw_defaults(int *sr, int *chn, mus_sample_t *samp_type) { (*sr) = raw_header_srate; (*chn) = raw_header_chans; (*samp_type) = raw_header_sample_type; } /* ------------------------------------ all together now ------------------------------------ */ static int mus_header_read_1(const char *filename, int fd) { static const unsigned char I_HCOM[4] = {'H','C','O','M'}; static const unsigned char I_FSSD[4] = {'F','S','S','D'}; static const unsigned char I_8SVX[4] = {'8','S','V','X'}; static const unsigned char I_16SV[4] = {'1','6','S','V'}; static const unsigned char I_VOC1[4] = {'t','i','v','e'}; static const unsigned char I_Soun[4] = {'S','o','u','n'}; static const unsigned char I_MAUD[4] = {'M','A','U','D'}; static const unsigned char I_mdat[4] = {'m','d','a','t'}; /* quicktime */ static const unsigned char I_sfbk[4] = {'s','f','b','k'}; /* SoundFont 2.0 */ static const unsigned char I_ATCH[4] = {'A','T','C','H'}; static const unsigned char I_NAL_[4] = {'N','A','L','_'}; static const unsigned char I__WAV[4] = {' ','S','A','M'}; static const unsigned char I_ondW[4] = {'o','n','d','W'}; static const unsigned char I_SDXc[4] = {'S','D','X',':'}; /* Sample dump exchange format */ static const unsigned char I_AVI_[4] = {'A','V','I',' '}; /* RIFF AVI */ static const unsigned char I_ones[4] = {(unsigned char)'\377',(unsigned char)'\377',(unsigned char)'\377',(unsigned char)'\377'}; static const unsigned char I_zeros[4] = {'\0','\0','\0','\0'}; static const unsigned char I_asf0[4] = {(unsigned char)'\321','\051',(unsigned char)'\342',(unsigned char)'\326'}; static const unsigned char I_asf1[4] = {(unsigned char)'\332','\065',(unsigned char)'\321','\021'}; static const unsigned char I_asf2[4] = {(unsigned char)'\220','\064','\000',(unsigned char)'\240'}; static const unsigned char I_asf3[4] = {(unsigned char)'\311','\003','\111',(unsigned char)'\276'}; static const unsigned char I_DS16[4] = {'D','S','1','6'}; /* CSL */ static const unsigned char I__sam[4] = {'=','s','a','m'}; static const unsigned char I_OggS[4] = {'O','g','g','S'}; /* Ogg-related files, apparently -- ogg123 has "vorbis" instead of "Speex" */ static const unsigned char I_fLaC[4] = {'f','L','a','C'}; /* FLAC */ static const unsigned char I_TTA1[4] = {'T','T','A','1'}; /* ttaenc */ static const unsigned char I_wvpk[4] = {'w','v','p','k'}; /* wavpack */ static const unsigned char I_MATL[4] = {'M','A','T','L'}; /* matlab 5.0 */ static const unsigned char I_AB_5[4] = {'A','B',' ','5'}; #define NINRS 7 static const unsigned int I_INRS[NINRS] = {0xcb460020, 0xd0465555, 0xfa460000, 0x1c470040, 0x3b470080, 0x7a470000, 0x9c470040}; static int inrs_srates[NINRS] = {6500, 6667, 8000, 10000, 12000, 16000, 20000}; /* returns 0 on success (at least to the extent that we can report the header type), -1 for error */ int i, loc = 0; long long int bytes; header_type = MUS_UNKNOWN_HEADER; sample_type = MUS_UNKNOWN_SAMPLE; comment_start = 0; comment_end = 0; data_size = 0; data_location = 0; if (loop_modes) { loop_modes[0] = 0; loop_modes[1] = 0; } bytes = (long long int)read(fd, hdrbuf, INITIAL_READ_SIZE); /* if it's a 0 length file we need to get out */ if (bytes < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: %s", filename, (errno) ? STRERROR(errno) : "bytes read < 0?")); if (bytes == 0) { header_type = MUS_RAW; srate = raw_header_srate; chans = raw_header_chans; sample_type = raw_header_sample_type; data_location = 0; true_file_length = 0; return(MUS_NO_ERROR); } if (bytes < 4) { header_type = MUS_RAW; return(read_no_header(fd)); } if ((match_four_chars((unsigned char *)hdrbuf, I_DSND)) || (match_four_chars((unsigned char *)hdrbuf, I_DECN))) { if (bytes < 24) return(mus_error(MUS_HEADER_READ_FAILED, "%s NeXT header truncated? found only %lld bytes", filename, bytes)); header_type = MUS_NEXT; return(read_next_header(filename, fd)); } if (match_four_chars((unsigned char *)hdrbuf, I_FORM)) { /* next 4 bytes are apparently the file size or something equally useless */ if (bytes < 12) return(mus_error(MUS_HEADER_READ_FAILED, "%s AIFF header truncated? found only %lld bytes", filename, bytes)); if (match_four_chars((unsigned char *)(hdrbuf + 8), I_AIFF)) { header_type = MUS_AIFF; return(read_aiff_header(filename, fd, 0)); } if (match_four_chars((unsigned char *)(hdrbuf + 8), I_AIFC)) { header_type = MUS_AIFC; return(read_aiff_header(filename, fd, 0)); } if (match_four_chars((unsigned char *)(hdrbuf + 8), I_8SVX)) { header_type = MUS_SVX; return(read_8svx_header(filename, fd, true)); } if (match_four_chars((unsigned char *)(hdrbuf + 8), I_16SV)) { header_type = MUS_SVX; return(read_8svx_header(filename, fd, false)); } if (match_four_chars((unsigned char *)(hdrbuf + 8), I_MAUD)) { header_type = MUS_MAUD; return(read_maud_header(filename, fd)); } /* apparently SAMP here -> sampled audio data (?) */ if (match_four_chars((unsigned char *)(hdrbuf + 4), I_DS16)) { header_type = MUS_CSL; return(read_csl_header(filename, fd)); } return(mus_error(MUS_HEADER_READ_FAILED, "%s: unrecognized \"FORM\" (i.e. AIFF) header", filename)); } if ((match_four_chars((unsigned char *)hdrbuf, I_RIFF)) || (match_four_chars((unsigned char *)hdrbuf, I_RIFX))) { if (bytes < 12) return(mus_error(MUS_HEADER_READ_FAILED, "%s RIFF header truncated? found only %lld bytes", filename, bytes)); if (match_four_chars((unsigned char *)(hdrbuf + 8), I_WAVE)) { header_type = MUS_RIFF; return(read_riff_header(filename, fd)); } if (match_four_chars((unsigned char *)(hdrbuf + 8), I_sfbk)) { header_type = MUS_SOUNDFONT; return(read_soundfont_header(filename, fd)); } if (match_four_chars((unsigned char *)(hdrbuf + 8), I_AVI_)) { header_type = MUS_AVI; return(read_avi_header(filename, fd)); } return(mus_error(MUS_HEADER_READ_FAILED, "%s: unrecognized \"RIFF\" (i.e. 'wave') header", filename)); } if (match_four_chars((unsigned char *)hdrbuf, I_RF64)) { header_type = MUS_RF64; if (bytes < 28) return(mus_error(MUS_HEADER_READ_FAILED, "%s RF64 header truncated? found only %lld bytes", filename, bytes)); if ((mus_char_to_lint((unsigned char *)(hdrbuf + 4)) != -1) || (!(match_four_chars((unsigned char *)(hdrbuf + 8), I_WAVE)))) return(mus_error(MUS_HEADER_READ_FAILED, "%s: messed up RF64 header", filename)); return(read_rf64_header(filename, fd)); } if ((equal_big_or_little_endian((unsigned char *)hdrbuf, I_IRCAM_VAX)) || (equal_big_or_little_endian((unsigned char *)hdrbuf, I_IRCAM_SUN)) || (equal_big_or_little_endian((unsigned char *)hdrbuf, I_IRCAM_MIPS)) || (equal_big_or_little_endian((unsigned char *)hdrbuf, I_IRCAM_NEXT))) { if (bytes < 24) return(mus_error(MUS_HEADER_READ_FAILED, "%s IRCAM header truncated? found only %lld bytes", filename, bytes)); header_type = MUS_IRCAM; return(read_ircam_header(filename, fd)); } if (match_four_chars((unsigned char *)hdrbuf, I_NIST)) { header_type = MUS_NIST; return(read_nist_header(filename, fd)); } if (match_four_chars((unsigned char *)hdrbuf, I_caff)) { if (bytes < 32) /* INITIAL_READ_SIZE */ return(mus_error(MUS_HEADER_READ_FAILED, "%s CAFF header truncated? found only %lld bytes", filename, bytes)); header_type = MUS_CAFF; return(read_caff_header(fd)); } if ((match_four_chars((unsigned char *)hdrbuf, I_MATL)) && (match_four_chars((unsigned char *)(hdrbuf + 4), I_AB_5))) { if (bytes < 128) /* INITIAL_READ_SIZE=256 */ return(mus_error(MUS_HEADER_READ_FAILED, "%s Matlab header truncated? found only %lld bytes", filename, bytes)); header_type = MUS_MATLAB; return(read_matlab_5_header(filename, fd)); } if (match_four_chars((unsigned char *)hdrbuf, I_SOUN)) { static const unsigned char I_D_SA[4] = {'D',' ','S','A'}; static const unsigned char I_MPLE[4] = {'M','P','L','E'}; if ((match_four_chars((unsigned char *)(hdrbuf + 4), I_D_SA)) && (match_four_chars((unsigned char *)(hdrbuf + 8), I_MPLE))) { header_type = MUS_SMP; return(read_smp_header(filename, fd)); } else { header_type = MUS_SNDT; return(read_sndt_header(filename, fd)); } } if ((match_four_chars((unsigned char *)hdrbuf, I_dSoX)) || (match_four_chars((unsigned char *)hdrbuf, I_XoSd))) { header_type = MUS_SOX; return(read_sox_header(filename, fd)); } if ((match_four_chars((unsigned char *)hdrbuf, I_VOC0)) && (match_four_chars((unsigned char *)(hdrbuf + 4), I_VOC1))) { if (bytes < 24) return(mus_error(MUS_HEADER_READ_FAILED, "%s VOC header truncated? found only %lld bytes", filename, bytes)); header_type = MUS_VOC; return(read_voc_header(filename, fd)); } if (match_four_chars((unsigned char *)hdrbuf, I_AVR_)) { header_type = MUS_AVR; return(read_avr_header(filename, fd)); } if (mus_char_to_bshort((unsigned char *)hdrbuf) == 1336) { header_type = MUS_SD1; return(read_sd1_header(filename, fd)); } if ((match_four_chars((unsigned char *)hdrbuf, I_ALaw)) && (match_four_chars((unsigned char *)(hdrbuf + 4), I_Soun))) { header_type = MUS_PSION; return(read_psion_header(filename, fd)); } if ((match_four_chars((unsigned char *)hdrbuf, I_GF1P)) && (match_four_chars((unsigned char *)(hdrbuf + 4), I_ATCH))) { header_type = MUS_GRAVIS; return(read_gravis_header(filename, fd)); } if ((match_four_chars((unsigned char *)hdrbuf, I_DSIG)) && (match_four_chars((unsigned char *)(hdrbuf + 4), I_NAL_))) { header_type = MUS_COMDISCO; return(read_comdisco_header(filename, fd)); } if ((match_four_chars((unsigned char *)hdrbuf, I_GOLD)) && (match_four_chars((unsigned char *)(hdrbuf + 4), I__WAV))) { header_type = MUS_GOLDWAVE; return(read_goldwave_header(filename, fd)); } if ((match_four_chars((unsigned char *)hdrbuf, I_Diam)) && (match_four_chars((unsigned char *)(hdrbuf + 4), I_ondW))) { header_type = MUS_DIAMONDWARE; return(read_diamondware_header(filename, fd)); } if (match_four_chars((unsigned char *)hdrbuf, I_SRFS)) { header_type = MUS_SRFS; return(read_srfs_header(filename, fd)); } if (match_four_chars((unsigned char *)hdrbuf, I_CSRE)) { header_type = MUS_ADF; return(read_adf_header(filename, fd)); } if (match_four_chars((unsigned char *)hdrbuf, I_fLaC)) { header_type = MUS_FLAC; return(MUS_NO_ERROR); } if (match_four_chars((unsigned char *)hdrbuf, I_ajkg)) { header_type = MUS_SHORTEN; return(MUS_NO_ERROR); } if (match_four_chars((unsigned char *)hdrbuf, I_TTA1)) { header_type = MUS_TTA; return(MUS_NO_ERROR); } if (match_four_chars((unsigned char *)hdrbuf, I_wvpk)) { header_type = MUS_WAVPACK; return(MUS_NO_ERROR); } if (match_four_chars((unsigned char *)hdrbuf, I_OggS)) { if ((hdrbuf[29] == 'v') && (hdrbuf[30] == 'o') && (hdrbuf[31] == 'r')) header_type = MUS_OGG; else { if ((hdrbuf[28] == 'S') && (hdrbuf[29] == 'p') && (hdrbuf[30] == 'e')) header_type = MUS_SPEEX; } return(MUS_NO_ERROR); } if ((match_four_chars((unsigned char *)hdrbuf, I_file)) && (match_four_chars((unsigned char *)(hdrbuf + 4), I__sam))) { header_type = MUS_FILE_SAMP; return(read_file_samp_header(filename, fd)); } if ((hdrbuf[0] == 0xf0) && (hdrbuf[1] == 0x7e) && (hdrbuf[3] == 0x01)) { header_type = MUS_MIDI_SAMPLE_DUMP; chans = 1; srate = (int)(1.0e9 / (float)((hdrbuf[7] + (hdrbuf[8] << 7) + (hdrbuf[9] << 14)))); data_size = (hdrbuf[10] + (hdrbuf[11] << 7) + (hdrbuf[12] << 14)); /* since this file type has embedded blocks, we have to translate it elsewhere */ return(MUS_NO_ERROR); } if (mus_char_to_ubint((unsigned char *)hdrbuf) == 0xAAAAAAAA) { header_type = MUS_MUS10; return(MUS_NO_ERROR); } if ((match_four_chars((unsigned char *)hdrbuf, I_SPIB)) || (match_four_chars((unsigned char *)hdrbuf, I_S___))) { header_type = MUS_IEEE; return(MUS_NO_ERROR); } if (match_four_chars((unsigned char *)hdrbuf, I_riff)) { header_type = MUS_SOUNDFORGE; return(read_soundforge_header(filename, fd)); } if ((match_four_chars((unsigned char *)hdrbuf, I_PVF1)) || (match_four_chars((unsigned char *)hdrbuf, I_PVF2))) { header_type = MUS_PVF; return(read_pvf_header(filename, fd)); } if (match_four_chars((unsigned char *)hdrbuf, I_MThd)) { header_type = MUS_MIDI; return(MUS_ERROR); } if (match_four_chars((unsigned char *)hdrbuf, I_SND_)) { header_type = MUS_SBSTUDIOII; return(read_sbstudio_header(filename, fd)); } if (match_four_chars((unsigned char *)hdrbuf, I_FSMt)) { header_type = MUS_FARANDOLE; return(read_farandole_header(filename, fd)); } if (match_four_chars((unsigned char *)hdrbuf, I_SDXc)) { header_type = MUS_SAMPLE_DUMP; return(read_sample_dump_header(filename, fd)); } if (match_four_chars((unsigned char *)hdrbuf, I_DDSF)) { header_type = MUS_DELUSION; return(read_delusion_header(filename, fd)); } if (match_four_chars((unsigned char *)hdrbuf, I_LM89)) { header_type = MUS_YAMAHA_TX16W; return(read_tx16w_header(filename, fd)); } if (match_four_chars((unsigned char *)hdrbuf, I_SY85)) { header_type = MUS_YAMAHA_SY85; return(read_sy85_header(filename, fd)); } if (match_four_chars((unsigned char *)hdrbuf, I_SY80)) { header_type = MUS_YAMAHA_SY99; return(read_sy85_header(filename, fd)); } if (match_four_chars((unsigned char *)hdrbuf, I_PRAM)) { header_type = MUS_KURZWEIL_2000; return(read_kurzweil_2000_header(filename, fd)); } if (match_four_chars((unsigned char *)hdrbuf, I_SMP1)) { header_type = MUS_KORG; return(read_korg_header(filename, fd)); } if (match_four_chars((unsigned char *)hdrbuf, I_Maui)) { header_type = MUS_MAUI; return(read_maui_header(filename, fd)); } if (match_four_chars((unsigned char *)hdrbuf, I_IMPS)) { header_type = MUS_IMPULSETRACKER; return(read_impulsetracker_header(filename, fd)); } if (match_four_chars((unsigned char *)(hdrbuf + 35), I_UWFD)) { header_type = MUS_ULTRATRACKER; return(read_ultratracker_header(filename, fd)); } if (match_four_chars((unsigned char *)(hdrbuf + 76), I_SCRS)) { header_type = MUS_DIGIPLAYER; return(read_digiplayer_header(filename, fd)); } if (match_four_chars((unsigned char *)hdrbuf, I_covox)) { header_type = MUS_COVOX; return(read_covox_header(filename, fd)); } if ((match_four_chars((unsigned char *)hdrbuf, I__PAF)) || (match_four_chars((unsigned char *)hdrbuf, I_FAP_))) { header_type = MUS_PAF; return(read_paf_header(filename, fd)); } if (match_four_chars((unsigned char *)hdrbuf, I_SDIF)) { header_type = MUS_SDIF; return(read_sdif_header(filename, fd)); } #if G7XX if (match_four_chars((unsigned char *)hdrbuf, I_NVF_)) { header_type = MUS_NVF; return(read_nvf_header(filename, fd)); } #endif if (match_four_chars((unsigned char *)hdrbuf, I_TWIN)) { header_type = MUS_TWINVQ; return(read_twinvq_header(filename, fd)); } /* ESPS is either 0x00006a1a or 0x1a6a0000 at byte 16 */ if (equal_big_or_little_endian((unsigned char *)(hdrbuf + 16), 0x00006a1a)) { header_type = MUS_ESPS; return(read_esps_header(filename, fd)); } if ((hdrbuf[252] == 64) && (hdrbuf[253] == 195)) /* #o100 and #o303 */ { header_type = MUS_SPPACK; return(read_sppack_header(filename, fd)); } if ((match_four_chars((unsigned char *)(hdrbuf + 65), I_FSSD)) && (match_four_chars((unsigned char *)(hdrbuf + 128), I_HCOM))) { header_type = MUS_HCOM; return(MUS_NO_ERROR); } #if MUS_LITTLE_ENDIAN if (mus_char_to_uninterpreted_int((unsigned char *)hdrbuf) == 0x01000800) #else if (mus_char_to_uninterpreted_int((unsigned char *)hdrbuf) == 0x00080001) #endif { header_type = MUS_ADC; return(read_adc_header(filename, fd)); } if ((match_four_chars((unsigned char *)hdrbuf, I_ones)) && (match_four_chars((unsigned char *)(hdrbuf + 12), I_FORM))) { /* possibly an OMF file with an embedded AIFF data file -- this is just a guess... */ header_type = MUS_OMF; return(read_aiff_header(filename, fd, 12)); /* another (apparently) along these lines is TOC */ } if ((match_four_chars((unsigned char *)hdrbuf, I_zeros)) && (match_four_chars((unsigned char *)(hdrbuf + 4), I_mdat))) { /* possibly quicktime?? */ header_type = MUS_QUICKTIME; return(read_qt_header(filename, fd)); } if ((hdrbuf[0] == 1) && (hdrbuf[1] == 4)) /* name follows --check? */ { header_type = MUS_AKAI4; return(read_akai4_header(filename, fd)); } #if 0 if ((hdrbuf[0] == 3) && (hdrbuf[16] == 128)) { header_type = MUS_AKAI4; return(read_akai3_header(filename, fd)); } #endif for (i = 0; i < NINRS; i++) { if (equal_big_or_little_endian((unsigned char *)hdrbuf, I_INRS[i])) { loc = inrs_srates[i]; header_type = MUS_INRS; return(read_inrs_header(filename, fd, loc)); } } if ((match_four_chars((unsigned char *)hdrbuf, I_asf0)) && (match_four_chars((unsigned char *)(hdrbuf + 4), I_asf1)) && (match_four_chars((unsigned char *)(hdrbuf + 8), I_asf2)) && (match_four_chars((unsigned char *)(hdrbuf + 12), I_asf3))) { header_type = MUS_ASF; return(read_asf_header(filename, fd)); } /* SMS files start with 767 (4-byte int, apparently in native order) */ /* try to catch mpeg... */ { int len; len = strlen(filename); if (len > 4) { if (strcmp((const char *)(filename + len - 4), ".mp3") == 0) { header_type = MUS_MPEG; return(MUS_NO_ERROR); } } } header_type = MUS_RAW; return(read_no_header(fd)); } static int local_error_type = MUS_NO_ERROR; static char *local_error_msg = NULL; static mus_error_handler_t *old_error_handler; static void local_mus_error(int type, char *msg) { local_error_type = type; if (local_error_msg) free(local_error_msg); if (msg) local_error_msg = mus_strdup(msg); else local_error_msg = NULL; } int mus_header_read(const char *name) { int fd, err = 0; fd = mus_file_open_read(name); if (fd == -1) return(mus_error(MUS_CANT_OPEN_FILE, "can't open %s: %s", name, STRERROR(errno))); old_error_handler = mus_error_set_handler(local_mus_error); err = mus_header_read_1(name, fd); CLOSE(fd, name); mus_error_set_handler(old_error_handler); if (err != MUS_NO_ERROR) return(mus_error(local_error_type, "%s", local_error_msg)); /* pass error info on up the chain now that we've cleaned up the open file descriptor */ return(err); } static mus_header_write_hook_t *mus_header_write_hook = NULL; mus_header_write_hook_t *mus_header_write_set_hook(mus_header_write_hook_t *new_hook) { mus_header_write_hook_t *old_hook; old_hook = mus_header_write_hook; mus_header_write_hook = new_hook; return(old_hook); } int mus_header_write(const char *name, mus_header_t type, int in_srate, int in_chans, mus_long_t loc, mus_long_t size_in_samples, mus_sample_t samp_type, const char *comment, int len) { /* the "loc" arg is a mistake -- just always set it to 0 */ int fd, err = MUS_NO_ERROR; mus_long_t siz; fd = mus_file_create(name); if (fd == -1) return(mus_error(MUS_CANT_OPEN_FILE, "can't write %s: %s", name, STRERROR(errno))); if (mus_header_write_hook) (*mus_header_write_hook)(name); siz = mus_samples_to_bytes(samp_type, size_in_samples); switch (type) { case MUS_RAW: case MUS_IRCAM: case MUS_NEXT: case MUS_RIFF: case MUS_RF64: case MUS_CAFF: break; default: if (siz > BIGGEST_4_BYTE_SIGNED_INT) { err = MUS_BAD_SIZE; siz = BIGGEST_4_BYTE_SIGNED_INT; } break; } switch (type) { case MUS_NEXT: err = mus_header_write_next_header(fd, in_srate, in_chans, loc, siz, samp_type, comment, len); break; case MUS_AIFC: err = write_aif_header(fd, in_srate, in_chans, siz, samp_type, comment, len, true); break; case MUS_AIFF: err = write_aif_header(fd, in_srate, in_chans, siz, samp_type, comment, len, false); break; case MUS_RF64: err = write_rf64_header(fd, in_srate, in_chans, siz, samp_type, comment, len); break; case MUS_CAFF: err = write_caff_header(fd, in_srate, in_chans, siz, samp_type); break; case MUS_IRCAM: err = write_ircam_header(fd, in_srate, in_chans, samp_type, comment, len); break; case MUS_NIST: err = write_nist_header(fd, in_srate, in_chans, siz, samp_type); break; case MUS_RIFF: err = write_riff_header(fd, in_srate, in_chans, siz, samp_type, comment, len); if (err != MUS_NO_ERROR) { CLOSE(fd, name); return(mus_error(err, "can't write %s header for %s (fd: %d, sample type: %s, srate: %d, chans: %d)", mus_header_type_name(type), name, fd, mus_sample_type_short_name(samp_type), in_srate, in_chans)); } break; case MUS_RAW: data_location = 0; data_size = mus_bytes_to_samples(samp_type, siz); srate = in_srate; chans = in_chans; header_type = MUS_RAW; sample_type = samp_type; break; default: CLOSE(fd, name); return(mus_error(MUS_UNSUPPORTED_HEADER_TYPE, "can't write %s header for %s", mus_header_type_name(type), name)); break; } CLOSE(fd, name); return(err); } int mus_write_header(const char *name, mus_header_t type, int in_srate, int in_chans, mus_long_t size_in_samples, mus_sample_t samp_type, const char *comment) { int len = 0; if (comment) len = strlen(comment); return(mus_header_write(name, type, in_srate, in_chans, 0, size_in_samples, samp_type, comment, len)); } int mus_header_change_data_size(const char *filename, mus_header_t type, mus_long_t size) /* in bytes */ { /* the read header at sample update (sound-close) time could be avoided if the * ssnd_location (etc) were saved and passed in -- perhaps an added optimized * header change data size? Means saving the relevant data, and exporting it * from headers.c. Can we guarantee consistency here? */ int fd, err = MUS_NO_ERROR; switch (type) { case MUS_AIFF: case MUS_AIFC: case MUS_NIST: case MUS_RIFF: case MUS_RF64: err = mus_header_read(filename); break; default: break; } if (err == MUS_ERROR) return(err); fd = mus_file_reopen_write(filename); if (fd == -1) return(mus_error(MUS_HEADER_WRITE_FAILED, "%s: %s", filename, STRERROR(errno))); if (size < 0) { CLOSE(fd, filename); return(mus_error(MUS_BAD_SIZE, "%s: change size to %lld?", filename, size)); } switch (type) { case MUS_NEXT: if (size > (mus_long_t)(BIGGEST_4_BYTE_UNSIGNED_INT)) { err = MUS_BAD_SIZE; size = BIGGEST_4_BYTE_UNSIGNED_INT; } lseek(fd, 8L, SEEK_SET); mus_bint_to_char((unsigned char *)(hdrbuf + 0), (unsigned int)size); header_write(fd, hdrbuf, 4); break; case MUS_AIFC: case MUS_AIFF: /* we apparently have to make sure the form size and the data size are correct * assumed here that we'll only be updating our own AIFF files * There are 3 such locations -- the second word of the file which is the overall form size, * the framples variable in the COMM chunk, and the chunk-size variable in the SSND chunk * an unexpected hassle for CLM is that we can open/close the output file many times if running mix, * so we have to update the various size fields taking into account the old size */ /* read sets current update_form_size, data_size, sample_type, update_framples_location, update_ssnd_location */ if (size > BIGGEST_4_BYTE_SIGNED_INT) { err = MUS_BAD_SIZE; mus_print("%s size: %lld is too large for %s headers", filename, size, mus_header_type_name(type)); size = BIGGEST_4_BYTE_SIGNED_INT; } lseek(fd, 4L, SEEK_SET); mus_bint_to_char((unsigned char *)hdrbuf, (int)size + update_form_size - mus_samples_to_bytes(sample_type, data_size)); /* cancel old data_size from previous possible write */ header_write(fd, hdrbuf, 4); lseek(fd, update_framples_location, SEEK_SET); mus_bint_to_char((unsigned char *)hdrbuf, (int)size / (chans * mus_bytes_per_sample(sample_type))); header_write(fd, hdrbuf, 4); lseek(fd, update_ssnd_location, SEEK_SET); mus_bint_to_char((unsigned char *)hdrbuf, (int)size + 8); header_write(fd, hdrbuf, 4); break; case MUS_RIFF: /* read sets current update_form_size, sample_type, data_size, update_ssnd_location */ if (size > BIGGEST_4_BYTE_SIGNED_INT) { CLOSE(fd, filename); return(mus_header_convert_riff_to_rf64(filename, size)); } lseek(fd, 4L, SEEK_SET); mus_lint_to_char((unsigned char *)hdrbuf, (int)size + update_form_size - mus_samples_to_bytes(sample_type, data_size)); header_write(fd, hdrbuf, 4); lseek(fd, update_ssnd_location, SEEK_SET); mus_lint_to_char((unsigned char *)hdrbuf, (int)size); header_write(fd, hdrbuf, 4); break; case MUS_RF64: /* read sets current update_form_size, sample_type, data_size, update_ssnd_location, update_rf64_location */ /* assume here that this really is an rf64 file (i.e. -1 for form size and data chunk size */ lseek(fd, update_rf64_location, SEEK_SET); mus_llong_to_char((unsigned char *)hdrbuf, data_location + size - 8); /* 25-June-07 */ mus_llong_to_char((unsigned char *)(hdrbuf + 8), size); mus_llong_to_char((unsigned char *)(hdrbuf + 16), size); header_write(fd, hdrbuf, 24); break; case MUS_IRCAM: case MUS_RAW: /* size is implicit in file size */ break; case MUS_NIST: /* read sets current srate, chans, sample_type */ if (size > BIGGEST_4_BYTE_SIGNED_INT) { err = MUS_BAD_SIZE; mus_print("%s size: %lld is too large for %s headers", filename, size, mus_header_type_name(type)); size = BIGGEST_4_BYTE_SIGNED_INT; } lseek(fd, 0L, SEEK_SET); write_nist_header(fd, mus_header_srate(), mus_header_chans(), size, mus_header_sample_type()); break; case MUS_CAFF: if (update_framples_location < 56) update_framples_location = 56; lseek(fd, update_framples_location, SEEK_SET); mus_blong_to_char((unsigned char *)(hdrbuf + 0), size); header_write(fd, hdrbuf, 8); break; default: CLOSE(fd, filename); return(mus_error(MUS_UNSUPPORTED_HEADER_TYPE, "mus_header_change_data_size: can't update %s headers", mus_header_type_name(type))); break; } CLOSE(fd, filename); return(err); } int mus_header_change_chans(const char *filename, mus_header_t type, int new_chans) { int err = MUS_NO_ERROR, fd; mus_long_t new_framples; switch (type) { case MUS_AIFF: case MUS_AIFC: case MUS_NIST: case MUS_RIFF: case MUS_RF64: err = mus_header_read(filename); break; default: break; } if (err == MUS_ERROR) return(err); fd = mus_file_reopen_write(filename); if (fd == -1) return(mus_error(MUS_CANT_OPEN_FILE, "mus_header_change_chans for %s failed: %s", filename, STRERROR(errno))); switch (type) { case MUS_NEXT: lseek(fd, 20L, SEEK_SET); mus_bint_to_char((unsigned char *)hdrbuf, new_chans); header_write(fd, hdrbuf, 4); break; case MUS_IRCAM: lseek(fd, 8L, SEEK_SET); if (little_endian) mus_lint_to_char((unsigned char *)hdrbuf, new_chans); else mus_bint_to_char((unsigned char *)hdrbuf, new_chans); header_write(fd, hdrbuf, 4); break; case MUS_NIST: lseek(fd, 0L, SEEK_SET); write_nist_header(fd, srate, new_chans, mus_bytes_per_sample(sample_type) * data_size, sample_type); /* header size is always 1024, so this is safe */ break; case MUS_AIFF: case MUS_AIFC: lseek(fd, update_framples_location - 2, SEEK_SET); new_framples = data_size / new_chans; mus_bshort_to_char((unsigned char *)hdrbuf, new_chans); mus_bint_to_char((unsigned char *)(hdrbuf + 2), new_framples); header_write(fd, hdrbuf, 6); break; case MUS_RIFF: case MUS_RF64: lseek(fd, update_framples_location - 2, SEEK_SET); if (little_endian) mus_lshort_to_char((unsigned char *)hdrbuf, new_chans); else mus_bshort_to_char((unsigned char *)hdrbuf, new_chans); header_write(fd, hdrbuf, 2); break; case MUS_CAFF: lseek(fd, 44L, SEEK_SET); mus_bint_to_char((unsigned char *)hdrbuf, new_chans); header_write(fd, hdrbuf, 4); /* we should probably also change bytes_per_packet at 36, but... */ break; default: break; } CLOSE(fd, filename); return(err); } int mus_header_change_srate(const char *filename, mus_header_t type, int new_srate) { int err = MUS_NO_ERROR, fd; switch (type) { case MUS_AIFF: case MUS_AIFC: case MUS_NIST: case MUS_RIFF: case MUS_RF64: err = mus_header_read(filename); break; default: break; } if (err == MUS_ERROR) return(err); fd = mus_file_reopen_write(filename); if (fd == -1) return(mus_error(MUS_CANT_OPEN_FILE, "mus_header_change_srate for %s failed: %s", filename, STRERROR(errno))); switch (type) { case MUS_NEXT: lseek(fd, 16L, SEEK_SET); mus_bint_to_char((unsigned char *)hdrbuf, new_srate); header_write(fd, hdrbuf, 4); break; case MUS_IRCAM: lseek(fd, 4L, SEEK_SET); if (little_endian) mus_lfloat_to_char((unsigned char *)hdrbuf, (float)new_srate); else mus_bfloat_to_char((unsigned char *)hdrbuf, (float)new_srate); header_write(fd, hdrbuf, 4); break; case MUS_NIST: lseek(fd, 0L, SEEK_SET); write_nist_header(fd, new_srate, chans, mus_bytes_per_sample(sample_type) * data_size, sample_type); break; case MUS_AIFF: case MUS_AIFC: lseek(fd, update_framples_location + 6, SEEK_SET); double_to_ieee_80((double)new_srate, (unsigned char *)hdrbuf); header_write(fd, hdrbuf, 10); break; case MUS_RIFF: case MUS_RF64: lseek(fd, update_framples_location, SEEK_SET); if (little_endian) mus_lint_to_char((unsigned char *)hdrbuf, new_srate); else mus_bint_to_char((unsigned char *)hdrbuf, new_srate); header_write(fd, hdrbuf, 4); break; case MUS_CAFF: lseek(fd, 20, SEEK_SET); mus_bdouble_to_char((unsigned char *)hdrbuf, (double)new_srate); header_write(fd, hdrbuf, 8); break; default: break; } CLOSE(fd, filename); return(err); } int mus_header_change_type(const char *filename, mus_header_t new_type, mus_sample_t new_format) { int err = MUS_NO_ERROR; /* open temp, write header, copy data, replace original with temp */ err = mus_header_read(filename); if (err == MUS_NO_ERROR) { if (header_type != new_type) { int ofd, ifd, len; long long int nbytes; mus_long_t loc; unsigned char *buf = NULL; char *new_file, *comment = NULL; if ((header_type == MUS_RIFF) && (new_type == MUS_RF64)) return(mus_header_convert_riff_to_rf64(filename, data_size)); len = strlen(filename) + 5; new_file = (char *)malloc(len * sizeof(char)); snprintf(new_file, len, "%s.tmp", filename); loc = mus_header_data_location(); if (new_type != MUS_RAW) { if (comment_end > comment_start) { mus_long_t clen; clen = comment_end - comment_start + 1; comment = (char *)calloc(clen + 1, sizeof(char)); ifd = mus_file_open_read(filename); lseek(ifd, comment_start, SEEK_SET); header_read(ifd, (unsigned char *)comment, clen); CLOSE(ifd, filename); } data_size = data_size * mus_bytes_per_sample(sample_type) / mus_bytes_per_sample(new_format); mus_write_header(new_file, new_type, srate, chans, data_size, new_format, comment); } else mus_file_create(new_file); ifd = mus_file_open_read(filename); lseek(ifd, loc, SEEK_SET); ofd = mus_file_reopen_write(new_file); lseek(ofd, 0L, SEEK_END); buf = (unsigned char *)calloc(8192, sizeof(unsigned char)); while ((nbytes = read(ifd, buf, 8192))) header_write(ofd, buf, (int)nbytes); CLOSE(ifd, filename); CLOSE(ofd, new_file); free(buf); if (comment) free(comment); rename(new_file, filename); free(new_file); } } return(err); } int mus_header_change_sample_type(const char *filename, mus_header_t type, mus_sample_t new_format) { int err = MUS_NO_ERROR, fd, fr; mus_long_t old_bytes; switch (type) { case MUS_AIFF: case MUS_AIFC: case MUS_NIST: case MUS_RIFF: case MUS_RF64: err = mus_header_read(filename); break; default: break; } if (err == MUS_ERROR) return(err); fd = mus_file_reopen_write(filename); if (fd == -1) return(mus_error(MUS_CANT_OPEN_FILE, "mus_header_change_sample_type for %s failed: %s", filename, STRERROR(errno))); switch (type) { case MUS_NEXT: lseek(fd, 12L, SEEK_SET); mus_bint_to_char((unsigned char *)hdrbuf, sndlib_format_to_next(new_format)); header_write(fd, hdrbuf, 4); break; case MUS_IRCAM: lseek(fd, 12L, SEEK_SET); mus_bint_to_char((unsigned char *)hdrbuf, sndlib_format_to_ircam(new_format)); header_write(fd, hdrbuf, 4); break; case MUS_NIST: lseek(fd, 0L, SEEK_SET); write_nist_header(fd, srate, chans, mus_bytes_per_sample(sample_type) * data_size, new_format); break; case MUS_AIFF: case MUS_AIFC: old_bytes = data_size * mus_bytes_per_sample(sample_type); lseek(fd, update_framples_location, SEEK_SET); mus_bint_to_char((unsigned char *)hdrbuf, old_bytes / (chans * mus_bytes_per_sample(new_format))); mus_bshort_to_char((unsigned char *)(hdrbuf + 4), sndlib_format_to_aiff_bits(new_format)); header_write(fd, hdrbuf, 6); if (header_type == MUS_AIFC) { const char *str; str = sndlib_format_to_aifc_name(new_format); lseek(fd, update_framples_location + 16, SEEK_SET); write_four_chars((unsigned char *)(hdrbuf + 0), (const unsigned char *)str); (*(unsigned char *)(hdrbuf + 4)) = 4; /* final pad null not accounted-for */ write_four_chars((unsigned char *)(hdrbuf + 5), (const unsigned char *)str); (*(unsigned char *)(hdrbuf + 9)) = 0; header_write(fd, hdrbuf, 10); } break; case MUS_RIFF: case MUS_RF64: lseek(fd, update_framples_location + 24, SEEK_SET); if (little_endian) mus_lshort_to_char((unsigned char *)hdrbuf, sndlib_format_to_aiff_bits(new_format)); else mus_bshort_to_char((unsigned char *)hdrbuf, sndlib_format_to_aiff_bits(new_format)); header_write(fd, hdrbuf, 2); lseek(fd, update_framples_location + 10, SEEK_SET); switch (new_format) { case MUS_MULAW: fr = 7; break; case MUS_ALAW: fr = 6; break; case MUS_UBYTE: case MUS_LSHORT: case MUS_L24INT: case MUS_LINT: case MUS_BSHORT: case MUS_B24INT: case MUS_BINT: fr = 1; break; case MUS_LFLOAT: case MUS_LDOUBLE: case MUS_BFLOAT: case MUS_BDOUBLE: fr = 3; break; default: fr = 0; break; } if (little_endian) mus_lshort_to_char((unsigned char *)hdrbuf, fr); else mus_bshort_to_char((unsigned char *)hdrbuf, fr); header_write(fd, hdrbuf, 2); break; default: break; } CLOSE(fd, filename); return(err); } int mus_header_change_location(const char *filename, mus_header_t type, mus_long_t new_location) { /* only Next/Sun changeable in this regard */ int err = MUS_NO_ERROR, fd; fd = mus_file_reopen_write(filename); if (fd == -1) return(mus_error(MUS_CANT_OPEN_FILE, "mus_header_change_location for %s failed: %s", filename, STRERROR(errno))); if (type == MUS_NEXT) { lseek(fd, 4L, SEEK_SET); mus_bint_to_char((unsigned char *)hdrbuf, new_location); header_write(fd, hdrbuf, 4); } CLOSE(fd, filename); return(err); } int mus_header_change_comment(const char *filename, mus_header_t type, const char *new_comment) { int err = MUS_NO_ERROR; err = mus_header_read(filename); if (err == MUS_NO_ERROR) { int fd; bool need_ripple = false; switch (type) { case MUS_IRCAM: { int len = 0; fd = mus_file_reopen_write(filename); lseek(fd, 16L, SEEK_SET); if (new_comment) len = strlen(new_comment); write_ircam_comment(fd, new_comment, len); CLOSE(fd, filename); } break; case MUS_NEXT: fd = mus_file_reopen_write(filename); lseek(fd, 24L, SEEK_SET); if (new_comment == NULL) write_next_comment(fd, new_comment, 0, data_location); /* erase old possibly */ else { if ((comment_start != comment_end) && ((int)(data_location - 24) >= (int)strlen(new_comment))) write_next_comment(fd, new_comment, strlen(new_comment), data_location); /* there's room to overwrite old comment */ else need_ripple = true; } CLOSE(fd, filename); break; default: need_ripple = true; break; } if (need_ripple) { /* open temp, write header, copy data, replace original with temp */ char *new_file; int ofd, ifd, len; mus_long_t loc; long long int nbytes; unsigned char *buf = NULL; len = strlen(filename) + 5; new_file = (char *)malloc(len * sizeof(char)); snprintf(new_file, len, "%s.tmp", filename); loc = mus_header_data_location(); mus_write_header(new_file, header_type, srate, chans, data_size, sample_type, new_comment); ifd = mus_file_open_read(filename); lseek(ifd, loc, SEEK_SET); ofd = mus_file_reopen_write(new_file); lseek(ofd, 0L, SEEK_END); buf = (unsigned char *)calloc(8192, sizeof(unsigned char)); while ((nbytes = read(ifd, buf, 8192))) header_write(ofd, buf, (int)nbytes); CLOSE(ifd, filename); CLOSE(ofd, new_file); free(buf); rename(new_file, filename); free(new_file); } } return(err); } bool mus_header_writable(mus_header_t type, mus_sample_t samp_type) /* MUS_IGNORE_SAMPLE to ignore sample type for this call */ { switch (type) { case MUS_NEXT: if (samp_type == MUS_UNKNOWN_SAMPLE) return(false); return(true); break; case MUS_NIST: if (samp_type == MUS_IGNORE_SAMPLE) return(true); switch (samp_type) { case MUS_BYTE: case MUS_BSHORT: case MUS_B24INT: case MUS_BINT: case MUS_LSHORT: case MUS_L24INT: case MUS_LINT: return(true); break; default: return(false); break; } break; case MUS_AIFC: if (samp_type == MUS_IGNORE_SAMPLE) return(true); switch (samp_type) { case MUS_BSHORT: case MUS_B24INT: case MUS_BINT: case MUS_BYTE: case MUS_MULAW: case MUS_ALAW: case MUS_BFLOAT: case MUS_BDOUBLE: case MUS_UBYTE: case MUS_UBSHORT: case MUS_LSHORT: case MUS_L24INT: case MUS_LINT: return(true); break; default: return(false); break; } break; case MUS_AIFF: if (samp_type == MUS_IGNORE_SAMPLE) return(true); switch (samp_type) { case MUS_BSHORT: case MUS_B24INT: case MUS_BINT: case MUS_BYTE: return(true); break; default: return(false); break; } break; case MUS_RIFF: case MUS_RF64: if (samp_type == MUS_IGNORE_SAMPLE) return(true); switch (samp_type) { case MUS_MULAW: case MUS_ALAW: case MUS_UBYTE: case MUS_LFLOAT: case MUS_LSHORT: case MUS_L24INT: case MUS_LINT: case MUS_LDOUBLE: return(true); break; default: return(false); break; } break; case MUS_IRCAM: if (samp_type == MUS_IGNORE_SAMPLE) return(true); switch (samp_type) { case MUS_MULAW: case MUS_ALAW: case MUS_BSHORT: case MUS_BINT: case MUS_BFLOAT: return(true); break; default: return(false); break; } break; case MUS_CAFF: if (samp_type == MUS_IGNORE_SAMPLE) return(true); switch (samp_type) { case MUS_MULAW: case MUS_ALAW: case MUS_BYTE: case MUS_LFLOAT: case MUS_LSHORT: case MUS_L24INT: case MUS_LINTN: case MUS_LDOUBLE: case MUS_BFLOAT: case MUS_BSHORT: case MUS_B24INT: case MUS_BINTN: case MUS_BDOUBLE: return(true); break; default: return(false); break; } break; case MUS_RAW: return(true); break; default: return(false); break; } return(false); } static char aifc_format[5]; /* try to give some info on sample types that aren't supported by sndlib */ const char *mus_header_original_sample_type_name(int samp_type, mus_header_t type) { switch (type) { case MUS_NEXT: switch (samp_type) { case 0: return("unspecified"); break; case 8: return("indirect"); break; case 9: return("nested"); break; case 10: return("dsp_core"); break; case 11: return("dsp_data_8"); break; case 12: return("dsp_data_16"); break; case 13: return("dsp_data_24"); break; case 14: return("dsp_data_32"); break; case 16: return("display"); break; case 17: return("mulaw_squelch"); break; case 18: return("emphasized"); break; case 19: return("compressed"); break; case 20: return("compressed_emphasized"); break; case 21: return("dsp_commands"); break; case 22: return("dsp_commands_samples"); break; case 23: return("adpcm_g721"); break; case 24: return("adpcm_g722"); break; case 25: return("adpcm_g723"); break; case 26: return("adpcm_g723_5"); break; case 28: return("aes"); break; case 29: return("delat_mulaw_8"); break; } break; case MUS_AIFC: case MUS_CAFF: aifc_format[4] = 0; #if MUS_LITTLE_ENDIAN snprintf(aifc_format, 5, "%c%c%c%c", samp_type & 0xff, (samp_type >> 8) & 0xff, (samp_type >> 16) & 0xff, (samp_type >> 24) & 0xff); #else snprintf(aifc_format, 5, "%c%c%c%c", (samp_type >> 24) & 0xff, (samp_type >> 16) & 0xff, (samp_type >> 8) & 0xff, samp_type & 0xff); #endif return(aifc_format); break; case MUS_PVF: if (type_specifier == mus_char_to_uninterpreted_int((unsigned const char *)I_PVF2)) return("ascii text"); break; case MUS_RIFF: case MUS_RF64: switch (samp_type) { case 2: return("ADPCM"); break; case 4: return("VSELP"); break; case 5: return("IBM_CVSD"); break; case 0x10: return("OKI_ADPCM"); break; case 0x11: return("DVI_ADPCM"); break; case 0x12: return("MediaSpace_ADPCM"); break; case 0x13: return("Sierra_ADPCM"); break; case 0x14: return("G723_ADPCM"); break; case 0x15: return("DIGISTD"); break; case 0x16: return("DIGIFIX"); break; case 0x17: return("Dialogic ADPCM"); break; case 0x18: return("Mediavision ADPCM"); break; case 0x19: return("HP cu codec"); break; case 0x20: return("Yamaha_ADPCM"); break; case 0x21: return("SONARC"); break; case 0x22: return("DSPGroup_TrueSpeech"); break; case 0x23: return("EchoSC1"); break; case 0x24: return("AudioFile_AF36"); break; case 0x25: return("APTX"); break; case 0x26: return("AudioFile_AF10"); break; case 0x27: return("prosody 1612"); break; case 0x28: return("lrc"); break; case 0x30: return("Dolby_Ac2"); break; case 0x31: return("GSM610"); break; case 0x32: return("MSN audio codec"); break; case 0x33: return("Antext_ADPCM"); break; case 0x34: return("Control_res_vqlpc"); break; case 0x35: return("DIGIREAL"); break; case 0x36: return("DIGIADPCM"); break; case 0x37: return("Control_res_cr10"); break; case 0x38: return("NMS_VBXADPCM"); break; case 0x39: return("oland rdac"); break; case 0x3a: return("echo sc3"); break; case 0x3b: return("Rockwell adpcm"); break; case 0x3c: return("Rockwell digitalk codec"); break; case 0x3d: return("Xebec"); break; case 0x40: return("G721_ADPCM"); break; case 0x41: return("G728 CELP"); break; case 0x42: return("MS G723"); break; case 0x50: return("MPEG"); break; case 0x52: return("RT24"); break; case 0x53: return("PAC"); break; case 0x55: return("Mpeg layer 3"); break; case 0x59: return("Lucent G723"); break; case 0x60: return("Cirrus"); break; case 0x61: return("ESS Tech pcm"); break; case 0x62: return("voxware "); break; case 0x63: return("canopus atrac"); break; case 0x64: return("G726"); break; case 0x65: return("G722"); break; case 0x66: return("DSAT"); break; case 0x67: return("DSAT display"); break; case 0x69: return("voxware "); break; case 0x70: return("voxware ac8 "); break; case 0x71: return("voxware ac10 "); break; case 0x72: return("voxware ac16"); break; case 0x73: return("voxware ac20"); break; case 0x74: return("voxware rt24"); break; case 0x75: return("voxware rt29"); break; case 0x76: return("voxware rt29hw"); break; case 0x77: return("voxware vr12 "); break; case 0x78: return("voxware vr18"); break; case 0x79: return("voxware tq40"); break; case 0x80: return("softsound"); break; case 0x81: return("voxware tq60 "); break; case 0x82: return("MS RT24"); break; case 0x83: return("G729A"); break; case 0x84: return("MVI_MVI2"); break; case 0x85: return("DF G726"); break; case 0x86: return("DF GSM610"); break; case 0x88: return("isaudio"); break; case 0x89: return("onlive"); break; case 0x91: return("sbc24"); break; case 0x92: return("dolby ac3 spdif"); break; case 0x97: return("zyxel adpcm"); break; case 0x98: return("philips lpcbb"); break; case 0x99: return("packed"); break; case 0x100: return("rhetorex adpcm"); break; case 0x101: return("Irat"); break; case 0x102: return("IBM_alaw?"); break; case 0x103: return("IBM_ADPCM?"); break; case 0x111: return("vivo G723"); break; case 0x112: return("vivo siren"); break; case 0x123: return("digital g273"); break; case 0x200: return("Creative_ADPCM"); break; case 0x202: return("Creative fastspeech 8"); break; case 0x203: return("Creative fastspeech 10"); break; case 0x220: return("quarterdeck"); break; case 0x300: return("FM_TOWNS_SND"); break; case 0x400: return("BTV digital"); break; case 0x680: return("VME vmpcm"); break; case 0x1000: return("OLIGSM"); break; case 0x1001: return("OLIADPCM"); break; case 0x1002: return("OLICELP"); break; case 0x1003: return("OLISBC"); break; case 0x1004: return("OLIOPR"); break; case 0x1100: return("LH codec"); break; case 0x1400: return("Norris"); break; case 0x1401: return("isaudio"); break; case 0x1500: return("Soundspace musicompression"); break; case 0x2000: return("DVM"); break; } break; default: break; } return("unknown"); /* NULL here isn't safe -- Sun segfaults */ } bool mus_header_no_header(const char *filename) { int fd; long long int bytes; bool ok = false; fd = mus_file_open_read(filename); if (fd == -1) return(mus_error(MUS_CANT_OPEN_FILE, "mus_header: can't open %s: %s", filename, STRERROR(errno))); bytes = (long long int)read(fd, hdrbuf, INITIAL_READ_SIZE); CLOSE(fd, filename); if (bytes > 4) ok = ((match_four_chars((unsigned char *)hdrbuf, I_DSND)) || (match_four_chars((unsigned char *)hdrbuf, I_DECN)) || (match_four_chars((unsigned char *)hdrbuf, I_FORM)) || (match_four_chars((unsigned char *)hdrbuf, I_RIFF)) || (match_four_chars((unsigned char *)hdrbuf, I_RIFX)) || (match_four_chars((unsigned char *)hdrbuf, I_RF64)) || (match_four_chars((unsigned char *)hdrbuf, I_caff)) || (equal_big_or_little_endian((unsigned char *)hdrbuf, I_IRCAM_VAX)) || (equal_big_or_little_endian((unsigned char *)hdrbuf, I_IRCAM_SUN)) || (equal_big_or_little_endian((unsigned char *)hdrbuf, I_IRCAM_MIPS)) || (equal_big_or_little_endian((unsigned char *)hdrbuf, I_IRCAM_NEXT)) || (match_four_chars((unsigned char *)hdrbuf, I_NIST)) || (match_four_chars((unsigned char *)hdrbuf, I_SOUN)) || (match_four_chars((unsigned char *)hdrbuf, I_VOC0)) || (match_four_chars((unsigned char *)hdrbuf, I_AVR_)) || (mus_char_to_bshort((unsigned char *)hdrbuf) == 1336) || (match_four_chars((unsigned char *)hdrbuf, I_ALaw)) || (match_four_chars((unsigned char *)hdrbuf, I_GF1P)) || (match_four_chars((unsigned char *)hdrbuf, I_DSIG)) || (match_four_chars((unsigned char *)hdrbuf, I_GOLD)) || (match_four_chars((unsigned char *)hdrbuf, I_Diam)) || (match_four_chars((unsigned char *)hdrbuf, I_SRFS)) || (match_four_chars((unsigned char *)hdrbuf, I_CSRE)) || (match_four_chars((unsigned char *)hdrbuf, I_file)) || ((hdrbuf[0] == 0xf0) && (hdrbuf[1] == 0x7e) && (hdrbuf[3] == 0x01)) || (equal_big_or_little_endian((unsigned char *)(hdrbuf + 16), 0x00006a1a)) || (match_four_chars((unsigned char *)hdrbuf, I_SPIB)) || (match_four_chars((unsigned char *)hdrbuf, I_S___)) || (match_four_chars((unsigned char *)hdrbuf, I_riff)) || (match_four_chars((unsigned char *)hdrbuf, I_PVF1)) || (match_four_chars((unsigned char *)hdrbuf, I_PVF2)) || (match_four_chars((unsigned char *)hdrbuf, I_MThd)) || (match_four_chars((unsigned char *)hdrbuf, I_SND_)) || (match_four_chars((unsigned char *)hdrbuf, I_FSMt)) || (match_four_chars((unsigned char *)hdrbuf, I_DDSF)) || (match_four_chars((unsigned char *)hdrbuf, I_LM89)) || (match_four_chars((unsigned char *)hdrbuf, I_SY85)) || (match_four_chars((unsigned char *)hdrbuf, I_SY80)) || (match_four_chars((unsigned char *)hdrbuf, I_PRAM)) || (match_four_chars((unsigned char *)(hdrbuf + 35), I_UWFD)) || (match_four_chars((unsigned char *)(hdrbuf + 76), I_SCRS)) || (match_four_chars((unsigned char *)hdrbuf, I_covox)) || (match_four_chars((unsigned char *)hdrbuf, I__PAF)) || (match_four_chars((unsigned char *)hdrbuf, I_FAP_)) || (match_four_chars((unsigned char *)hdrbuf, I_TWIN)) || (match_four_chars((unsigned char *)hdrbuf, I_IMPS)) || (match_four_chars((unsigned char *)hdrbuf, I_SMP1)) || (match_four_chars((unsigned char *)hdrbuf, I_Maui)) || (match_four_chars((unsigned char *)hdrbuf, I_SDIF)) || (match_four_chars((unsigned char *)hdrbuf, I_ajkg)) #if G7XX || (match_four_chars((unsigned char *)hdrbuf, I_NVF_)) #endif ); return(!ok); } void mus_header_set_aiff_loop_info(int *data) { /* include modes */ if (data) { loop_starts[0] = data[0]; loop_ends[0] = data[1]; loop_starts[1] = data[2]; loop_ends[1] = data[3]; base_note = data[4]; base_detune = data[5]; loop_modes[0] = data[6]; loop_modes[1] = data[7]; } else { loop_modes[0] = 0; loop_modes[1] = 0; } } bool mus_is_header_type(int n) { switch (n) { case MUS_NEXT: case MUS_AIFC: case MUS_RIFF: case MUS_RF64: case MUS_BICSF: case MUS_NIST: case MUS_INRS: case MUS_ESPS: case MUS_SVX: case MUS_VOC: case MUS_SNDT: case MUS_RAW: case MUS_SOX: case MUS_SMP: case MUS_AVR: case MUS_IRCAM: case MUS_SD1: case MUS_SPPACK: case MUS_MUS10: case MUS_HCOM: case MUS_PSION: case MUS_MAUD: case MUS_IEEE: case MUS_MATLAB: case MUS_ADC: case MUS_MIDI: case MUS_SOUNDFONT: case MUS_GRAVIS: case MUS_COMDISCO: case MUS_GOLDWAVE: case MUS_SRFS: case MUS_MIDI_SAMPLE_DUMP: case MUS_DIAMONDWARE: case MUS_ADF: case MUS_SBSTUDIOII: case MUS_DELUSION: case MUS_FARANDOLE: case MUS_SAMPLE_DUMP: case MUS_ULTRATRACKER: case MUS_YAMAHA_SY85: case MUS_YAMAHA_TX16W: case MUS_DIGIPLAYER: case MUS_COVOX: case MUS_AVI: case MUS_OMF: case MUS_QUICKTIME: case MUS_ASF: case MUS_YAMAHA_SY99: case MUS_KURZWEIL_2000: case MUS_AIFF: case MUS_PAF: case MUS_CSL: case MUS_FILE_SAMP: case MUS_PVF: case MUS_SOUNDFORGE: case MUS_TWINVQ: case MUS_AKAI4: case MUS_IMPULSETRACKER: case MUS_KORG: case MUS_CAFF: case MUS_MAUI: case MUS_SDIF: case MUS_OGG: case MUS_FLAC: case MUS_SPEEX: case MUS_MPEG: case MUS_SHORTEN: case MUS_TTA: case MUS_WAVPACK: #if G7XX case MUS_NVF: #endif return(true); break; } return(false); } bool mus_is_sample_type(int n) { switch (n) { case MUS_BSHORT: case MUS_MULAW: case MUS_BYTE: case MUS_BFLOAT: case MUS_BINT: case MUS_ALAW: case MUS_UBYTE: case MUS_B24INT: case MUS_BDOUBLE: case MUS_LSHORT: case MUS_LINT: case MUS_LFLOAT: case MUS_LDOUBLE: case MUS_UBSHORT: case MUS_ULSHORT: case MUS_L24INT: case MUS_BINTN: case MUS_LINTN: case MUS_BFLOAT_UNSCALED: case MUS_LFLOAT_UNSCALED: case MUS_BDOUBLE_UNSCALED: case MUS_LDOUBLE_UNSCALED: return(true); break; } return(false); } snd-16.1/maraca.rb0000644000076400007640000000742712306421672012121 0ustar bilbil# maraca.rb -- maraca.ins -> maraca.scm -> maraca.rb # Translator: Michael Scholz # Created: Fri Apr 22 23:29:22 CEST 2005 # Changed: Sat Feb 19 18:27:34 CET 2011 # Commentary: # # Perry Cook's maraca from CMJ vol 21 no 3 (Fall 97) p 44 translated # from CLM's maraca.ins # # Code: def maraca(start, dur, amp = 0.1, sound_decay = 0.95, system_decay = 0.999, probability = 0.0625, shell_freq = 3200.0, shell_reso = 0.96) temp = 0.0 shake_energy = 0.0 snd_level = 0.0 input = 0.0 output = Vct.new(2) coeffs = Vct.new(2) num_beans = 64 j = 0 sndamp = amp / 16384.0 srate4 = (mus_srate / 4.0).floor gain = ((log(num_beans) / log(4)) * 40.0) / num_beans coeffs[0] = -2.0 * shell_reso * cos(hz2radians(shell_freq)) coeffs[1] = shell_reso * shell_reso run_instrument(start, dur) do if temp < TWO_PI temp += hz2radians(20) shake_energy += 1.0 - cos(temp) end if j == srate4 temp = 0.0 j = 0 end j += 1 shake_energy *= system_decay if random(1.0) < probability snd_level = snd_level + gain * shake_energy end input = snd_level * (random(2.0) - 1.0) snd_level *= sound_decay input = input - output[0] * coeffs[0] - output[1] * coeffs[1] output[1], output[0] = output[0], input sndamp * (output[0] - output[1]) end end # maraca: vct2channel(maraca(0, 5, 0.5)) # cabasa: vct2channel(maraca(0, 5, 0.5, 0.95, 0.997, 0.5, 3000.0, 0.7)) def big_maraca(start, dur, amp = 0.1, sound_decay = 0.95, system_decay = 0.999, probability = 0.0625, shell_freqs = [3200.0], shell_resos = [0.96], randiff = 0.01, with_filters = true) temp = 0.0 temp1 = 0.0 resn = shell_freqs.length shake_energy = 0.0 snd_level = 0.0 input = 0.0 sum = 0.0 last_sum = 0.0 last_diff = 0.0 diff = 0.0 output = Vct.new(resn * 2) coeffs = Vct.new(resn * 2) basesf = Vct.new(resn) num_beans = 64 j = 0 sndamp = amp / 16384.0 srate4 = (mus_srate / 4.0).floor gain = ((log(num_beans) / log(4)) * 40.0) / num_beans resn.times do |i| basesf[i] = coeffs[i * 2] = -2.0 * shell_resos[i] * cos(hz2radians(shell_freqs[i])) coeffs[1 + i * 2] = shell_resos[i] * shell_resos[i] end run_instrument(start, dur) do if temp < TWO_PI temp += hz2radians(20) shake_energy += 1.0 - cos(temp) end if j == srate4 temp = 0.0 j = 0 end j += 1 shake_energy *= system_decay if random(1.0) < probability snd_level = snd_level + gain * shake_energy basesf.each_with_index do |val, i| coeffs[i * 2] = val + (random(2.0 * randiff) - randiff) end end input = snd_level * (random(2.0) - 1.0) snd_level *= sound_decay temp1 = input last_sum = sum sum = 0.0 resn.times do |i| input = temp1 input = input - output[i * 2] * coeffs[i * 2] - output[i * 2 + 1] * coeffs[i * 2 + 1] output[i * 2 + 1], output[i * 2] = output[i * 2], input sum += input end if with_filters last_diff, diff = diff, sum - last_sum temp1 = last_diff + diff else temp1 = sum end sndamp * temp1 end end # tambourine: big_maraca(0, 1, 0.25, 0.95, 0.9985, 0.03125, # [2300, 5600, 8100], [0.96, 0.995, 0.995], 0.01) # sleighbells: big_maraca(0, 2, 0.5, 0.97, 0.9994, 0.03125, # [2500, 5300, 6500, 8300, 9800], [0.999, 0.999, 0.999, 0.999, 0.999]) # sekere: big_maraca(0, 2, 0.5, 0.96, 0.999, .0625, [5500], [0.6]) # windchimes: big_maraca(0, 2, 0.5, 0.99995, 0.95, 0.001, # [2200, 2800, 3400], [0.995, 0.995, 0.995], 0.01, false) # maraca.rb ends here snd-16.1/snd-g1.h0000644000076400007640000004602712512761107011610 0ustar bilbil#ifndef SND_G1_H #define SND_G1_H void recolor_everything(widget_t w, gpointer color); /* -------- snd-ghelp.c -------- */ GtkWidget *snd_help(const char *subject, const char *help, with_word_wrap_t with_wrap); GtkWidget *snd_help_with_xrefs(const char *subject, const char *helpstr, with_word_wrap_t with_wrap, const char **xrefs, const char **urls); int help_text_width(const char *txt, int start, int end); void snd_help_append(const char *text); void snd_help_back_to_top(void); /* -------- snd-gdraw.c -------- */ void draw_line(graphics_context *ax, int x0, int y0, int x1, int y1); void draw_lines(graphics_context *ax, point_t *points, int num); void draw_points(graphics_context *ax, point_t *points, int num, int size); void fill_rectangle(graphics_context *ax, int x0, int y0, int width, int height); void erase_rectangle(chan_info *cp, graphics_context *ax, int x0, int y0, int width, int height); void fill_polygon(graphics_context *ax, int points, ...); void fill_polygons(graphics_context *ax, point_t *points, int num, int y0); void fill_two_sided_polygons(graphics_context *ax, point_t *points, point_t *points1, int num); void fill_polygon_from_array(graphics_context *ax, point_t *points, int npoints); void draw_picture(graphics_context *ax, picture_t *src, gint xsrc, gint ysrc, gint xdest, gint ydest, gint width, gint height); void draw_string(graphics_context *ax, int x0, int y0, const char *str, int len); void draw_rotated_axis_label(chan_info *cp, graphics_context *ax, const char *text, gint x0, gint y0); void draw_dot(graphics_context *ax, int x, int y, int size); void draw_colored_lines(chan_info *cp, graphics_context *ax, point_t *points, int num, int *colors, int axis_y0, color_t default_color); void setup_graphics_context(chan_info *cp, graphics_context *ax); void set_color_scale(mus_float_t val); void set_color_inverted(bool val); void set_color_cutoff(mus_float_t val); void set_color_map(int val); void set_spectro_hop(int val); void set_spectro_x_angle(mus_float_t val); void set_spectro_y_angle(mus_float_t val); void set_spectro_z_angle(mus_float_t val); void set_spectro_x_scale(mus_float_t val); void set_spectro_y_scale(mus_float_t val); void set_spectro_z_scale(mus_float_t val); void view_color_orientation_callback(GtkWidget * w, gpointer info); bool color_orientation_dialog_is_active(void); GtkWidget *make_color_orientation_dialog(bool managed); void reflect_spectro(void); void allocate_sono_rects(int size); void set_sono_rectangle(int j, int color, int x, int y, int width, int height); void draw_sono_rectangles(graphics_context *ax, int color, int jmax); void draw_spectro_line(graphics_context *ax, int color, int x0, int y0, int x1, int y1); void allocate_color_map(int colormap); void check_colormap_sizes(int size); void initialize_colormap(void); void reflect_color_list(bool setup_time); void set_with_gl(bool val, bool with_dialogs); void g_init_gxdraw(void); gchar* scale_double_format_callback(GtkScale *w, gdouble val, gpointer data); /* -------- snd-glistener.c -------- */ void color_listener(color_info *pix); void color_listener_text(color_info *pix); void handle_listener(bool new_state); bool listener_exists(void); int listener_height(void); int listener_width(void); void goto_listener(void); int save_listener_text(FILE *fp); void append_listener_text(int end, const char *msg); void listener_append(const char *msg); void listener_append_and_prompt(const char *msg); void clear_listener(void); void set_listener_text_font(void); bool listener_colorized(void); bool listener_set_colorized(bool val); void g_init_gxlistener(void); /* -------- snd-gmain.c -------- */ color_t get_in_between_color(color_t fg, color_t bg); void snd_doit(int argc, char **argv); void auto_update_restart(void); void save_colors(FILE *Fp); /* -------- snd-gmenu.c -------- */ GtkWidget *add_menu(void); void reflect_play_selection_stop(void); void g_init_gxmenu(void); GtkWidget *menu_widget(int which_menu); void check_menu_labels(int key, int state, bool extended); GtkWidget *get_help_menu_widget(void); void show_toolbar(void); void hide_toolbar(void); void add_tooltip(GtkWidget *w, const char *tip); void post_basic_popup_menu(void *ev); void post_lisp_popup_menu(void *ev); void post_selection_popup_menu(void *ev); widget_t make_file_print_dialog(bool managed, bool direct_to_printer); /* -------- snd-gfft.c -------- */ void set_fft_window_beta(mus_float_t val); void set_fft_window_alpha(mus_float_t val); void set_transform_size(mus_long_t val); void set_fft_window(mus_fft_window_t val); void set_wavelet_type(int val); GtkWidget *make_transform_dialog(bool managed); bool transform_dialog_is_active(void); void set_transform_type(int val); void make_transform_type_list(void); void set_spectrum_start(mus_float_t val); void set_spectrum_end(mus_float_t val); void set_show_transform_peaks(bool val); void set_fft_log_magnitude(bool val); void set_fft_with_phases(bool val); void set_fft_log_frequency(bool val); void set_transform_normalization(fft_normalize_t val); void set_show_selection_transform(bool show); void set_transform_graph_type(graph_type_t val); void reflect_peaks_in_transform_dialog(void); void reflect_log_freq_start_in_transform_dialog(void); void reflect_min_db_in_transform_dialog(void); gboolean spin_button_focus_callback(GtkWidget *w, GdkEventCrossing *ev, gpointer unknown); gboolean spin_button_unfocus_callback(GtkWidget *w, GdkEventCrossing *ev, gpointer unknown); void post_fft_popup_menu(void *ev); /* -------- snd-gregion.c -------- */ int update_region_browser(bool grf_too); void reflect_play_region_stop(int n); bool region_browser_is_active(void); void delete_region_and_update_browser(int n); void view_region_callback(GtkWidget *w, gpointer info); void allocate_region_rows(int n); bool region_dialog_is_active(void); void reflect_regions_in_region_browser(void); void reflect_no_regions_in_region_browser(void); void reflect_region_graph_style(void); int region_dialog_region(void); char *regrow_get_label(void *ur); int regrow_get_pos(void *ur); void g_init_gxregion(void); void view_files_add_directory(widget_t dialog, const char *dirname); bool view_files_has_files(void); void view_files_callback(GtkWidget *w, gpointer info); void view_files_unplay(void); /* -------- snd-gxbitmaps.c -------- */ const char **snd_icon_bits(void); enum {SND_PNG_LOCK, SND_PNG_STOP, SND_PNG_BOMB, SND_PNG_RIGHT_ARROW, SND_PNG_LEFT_ARROW, SND_PNG_BLANK, SND_PNG_SPEAKER}; cairo_surface_t *snd_icon(int which); /* -------- snd-gxcolormaps.c -------- */ char *colormap_name(int n); bool is_colormap(int n); int num_colormaps(void); void get_current_color(int colormap, int n, rgb_t *r, rgb_t *g, rgb_t *b); #if HAVE_GL rgb_t *color_map_reds(int index); rgb_t *color_map_greens(int index); rgb_t *color_map_blues(int index); #endif void g_init_gxcolormaps(void); void phases_rgb(float x, rgb_t *r, rgb_t *g, rgb_t *b); /* -------- snd-gchn.c -------- */ GtkWidget *channel_w(chan_info *cp); GtkWidget *channel_f(chan_info *cp); GtkWidget *channel_graph(chan_info *cp); bool channel_graph_is_visible(chan_info *cp); GtkWidget *channel_up_arrow(chan_info *cp); GtkWidget *channel_down_arrow(chan_info *cp); void channel_open_pane(chan_info *cp); void resize_sx(chan_info *cp); void resize_sy(chan_info *cp); void resize_sy_and_zy(chan_info *cp); void resize_sx_and_zx(chan_info *cp); void initialize_scrollbars(chan_info *cp); void set_z_scrollbars(chan_info *cp, axis_info *ap); void change_gzy(mus_float_t val, chan_info *cp); mus_float_t gsy_value(chan_info *cp); mus_float_t gsy_size(chan_info *cp); void reflect_edit_history_change(chan_info *cp); void reflect_edit_counter_change(chan_info *cp); gboolean graph_key_press(GtkWidget *w, GdkEventKey *event, gpointer data); int add_channel_window(snd_info *sound, int channel, int chan_y, int insertion, GtkWidget *main, fw_button_t arrows, bool with_events); void set_peak_numbers_font(chan_info *cp, graphics_context *ax); void set_bold_peak_numbers_font(chan_info *cp, graphics_context *ax); void set_tiny_numbers_font(chan_info *cp, graphics_context *ax); color_t get_foreground_color(graphics_context *ax); void set_foreground_color(graphics_context *ax, color_info *color); gc_t *copy_GC(chan_info *cp); gc_t *erase_GC(chan_info *cp); void cleanup_cw(chan_info *cp); void change_channel_style(snd_info *sp, channel_style_t new_style); void color_chan_components(color_t color, slider_choice_t which_component); void color_unselected_graphs(color_t color); void g_init_gxchn(void); /* -------- snd-gfind.c -------- */ void edit_find_callback(GtkWidget *w, gpointer info); void find_dialog(chan_info *cp); void find_dialog_set_label(const char *str); void stop_search_if_error(const char *msg, void *data); void errors_to_find_text(const char *msg, void *data); void find_dialog_stop_label(bool show_stop); bool find_dialog_is_active(void); void save_find_dialog_state(FILE *fd); void g_init_gxfind(void); /* -------- snd-gutils.c -------- */ bool set_tiny_font(const char *font); bool set_listener_font(const char *font); bool set_peaks_font(const char *font); bool set_bold_peaks_font(const char *font); bool set_axis_label_font(const char *font); bool set_axis_numbers_font(const char *font); int label_width(const char *txt, bool use_tiny_font); int number_width(const char *num, bool use_tiny_font); int number_height(PangoFontDescription *font); int label_height(bool use_tiny_font); int sg_text_width(const char *txt, PangoFontDescription *font); int mark_name_width(const char *txt); void clear_window(graphics_context *ax); void highlight_color(GtkWidget *w); void raise_dialog(GtkWidget *w); void set_button_label(GtkWidget *label, const char *str); void set_label(GtkWidget *label, const char *str); void check_for_event(void); void set_title(const char *title); void goto_window(GtkWidget *text); void gc_set_foreground(gc_t *gp, color_info *color); void gc_set_background(gc_t *gp, color_info *color); void gc_set_colors(gc_t *gp, color_info *col1, color_info *col2); gc_t *gc_new(void); void color_cursor(color_info *color); void color_marks(color_info *color); void color_selection(color_info *color); void color_data(color_info *color); void color_selected_data(color_info *color); void color_graph(color_info *color); void color_selected_graph(color_info *color); void set_mix_color(color_info *color); void widget_modify_bg(GtkWidget *w, GtkStateType type, color_t color); void widget_modify_fg(GtkWidget *w, GtkStateType type, color_t color); void widget_modify_base(GtkWidget *w, GtkStateType type, color_t color); color_t rgb_to_color(mus_float_t r, mus_float_t g, mus_float_t b); #if (!GTK_CHECK_VERSION(3, 0, 0)) GdkColor *rgb_to_gdk_color(color_t col); #endif void add_highlight_button_style(GtkWidget *w); void add_center_button_style(GtkWidget *w); void add_toolbar_style(GtkWidget *w); void add_menu_style(GtkWidget *w); void add_paned_style(GtkWidget *w); void add_red_scale_style(GtkWidget *w); void add_green_scale_style(GtkWidget *w); void add_blue_scale_style(GtkWidget *w); void add_white_button_style(GtkWidget *w); void add_listener_style(GtkWidget *w); void add_dialog_style(GtkWidget *w); void add_check_button_style(GtkWidget *w); void add_entry_style(GtkWidget *w); void recolor_graph(chan_info *cp, bool selected); void set_sensitive(GtkWidget *wid, bool val); void set_toggle_button(GtkWidget *wid, bool val, bool passed, void *data); #if GTK_CHECK_VERSION(3, 0, 0) int widget_height(GtkWidget *w); int widget_width(GtkWidget *w); #else guint16 widget_height(GtkWidget *w); guint16 widget_width(GtkWidget *w); #endif void set_widget_height(GtkWidget *w, guint16 height); void set_widget_width(GtkWidget *w, guint16 width); gint16 widget_x(GtkWidget *w); gint16 widget_y(GtkWidget *w); void set_widget_x(GtkWidget *w, gint16 x); void set_widget_y(GtkWidget *w, gint16 y); void set_widget_size(GtkWidget *w, guint16 width, guint16 height); void set_widget_position(GtkWidget *w, gint16 x, gint16 y); void set_user_data(GObject *obj, gpointer data); void set_user_int_data(GObject *obj, int data); void reset_user_int_data(GObject *obj, int data); gpointer get_user_data(GObject *obj); int get_user_int_data(GObject *obj); void set_stock_button_label(GtkWidget *w, const char *new_label); bool cursor_set_blinks(GtkWidget *w, bool blinks); char *sg_get_text(GtkWidget *w, int start, int end); void sg_text_insert(GtkWidget *w, const char *text); GtkWidget *make_scrolled_text(GtkWidget *parent, bool editable, int add_choice, bool resize); void sg_make_resizable(GtkWidget *w); idle_t add_work_proc(GSourceFunc func, gpointer data); GtkWidget *snd_gtk_dialog_new(void); GtkWidget *snd_gtk_highlight_label_new(const char *label); void widget_int_to_text(GtkWidget *w, int val); void widget_mus_long_t_to_text(GtkWidget *w, mus_long_t val); void ensure_scrolled_window_row_visible(widget_t list, int pos, int num_rows); slist *slist_new_with_title_and_table_data(const char *title, GtkWidget *parent, const char **initial_items, int num_items, widget_add_t paned, int t1, int t2, int t3, int t4); slist *slist_new(GtkWidget *parent, const char **initial_items, int num_items, widget_add_t paned); slist *slist_new_with_title(const char *title, GtkWidget *parent, const char **initial_items, int num_items, widget_add_t paned); void slist_clear(slist *lst); void slist_append(slist *lst, const char *name); void slist_moveto(slist *lst, int row); void slist_select(slist *lst, int row); #if GTK_CHECK_VERSION(3, 0, 0) cairo_t *make_cairo(GdkWindow *win); #else cairo_t *make_cairo(GdkDrawable *win); #endif void free_cairo(cairo_t *cr); void init_gtk(void); /* -------- snd-gsnd.c -------- */ int control_panel_height(snd_info *sp); GtkWidget *w_snd_pane(snd_info *sp); GtkWidget *w_snd_pane_box(snd_info *sp); GtkWidget *unite_button(snd_info *sp); void set_control_panel_play_button(snd_info *sp); void show_lock(snd_info *sp); void hide_lock(snd_info *sp); void start_bomb(snd_info *sp); void stop_bomb(snd_info *sp); void set_status(snd_info *sp, const char *str, bool update); void set_play_button(snd_info *sp, bool val); void play_button_pause(bool pausing); void syncb(snd_info *sp, int on); void set_amp(snd_info *sp, mus_float_t val); mus_float_t amp_to_scroll(mus_float_t minval, mus_float_t val, mus_float_t maxval); void set_expand(snd_info *sp, mus_float_t val); void set_contrast(snd_info *sp, mus_float_t val); void set_speed(snd_info *sp, mus_float_t val); void set_revlen(snd_info *sp, mus_float_t val); void set_revscl(snd_info *sp, mus_float_t val); void set_filter_order(snd_info *sp, int order); void set_filter_text(snd_info *sp, const char *str); void display_filter_env(snd_info *sp); void toggle_expand_button(snd_info *sp, bool state); void toggle_contrast_button(snd_info *sp, bool state); void toggle_reverb_button(snd_info *sp, bool state); void toggle_filter_button(snd_info *sp, bool state); void toggle_direction_arrow(snd_info *sp, bool state); void set_filter_in_dB(snd_info *sp, bool val); void set_filter_in_hz(snd_info *sp, bool val); void filter_env_changed(snd_info *sp, env *e); void color_filter_waveform(color_info *color); snd_info *add_sound_window(char *filename, read_only_t read_only, file_info *hdr); void set_sound_pane_file_label(snd_info *sp, const char *str); void snd_info_cleanup(snd_info *sp); void show_controls(snd_info *sp); void hide_controls(snd_info *sp); bool showing_controls(snd_info *sp); void show_all_controls(void); void hide_all_controls(void); void start_progress_report(chan_info *cp); void finish_progress_report(chan_info *cp); void progress_report(chan_info *cp, mus_float_t pct); void g_init_gxsnd(void); void reflect_sound_selection(snd_info *sp); void make_controls_dialog(void); void update_sound_label(snd_info *sp); GtkWidget *snd_entry_new(GtkWidget *container, GtkWidget *prev, snd_entry_bg_t with_white_background); GtkWidget *snd_entry_new_with_size(GtkWidget *container, int size); void connect_mouse_to_text(GtkWidget *text); /* -------- snd-gmix.c -------- */ void reflect_mix_change(int mix_id); GtkWidget *make_mix_dialog(void); void reflect_mix_play_stop(void); int mix_dialog_mix(void); void mix_dialog_set_mix(int id); /* -------- snd-genv.c -------- */ axis_info *enved_make_axis(const char *name, graphics_context *ax, int ex0, int ey0, int width, int height, mus_float_t xmin, mus_float_t xmax, mus_float_t ymin, mus_float_t ymax, printing_t printing); void display_enved_env_with_selection(env *e, const char *name, int x0, int y0, int width, int height, bool dots, printing_t printing); void set_enved_redo_sensitive(bool val); void set_enved_revert_sensitive(bool val); void set_enved_undo_sensitive(bool val); void set_enved_save_sensitive(bool val); void set_enved_show_sensitive(bool val); void enved_reflect_selection(bool on); void make_scrolled_env_list(void); void enved_reflect_peak_env_completion(snd_info *sp); void new_active_channel_alert(void); void env_redisplay(void); void env_redisplay_with_print(void); void update_enved_background_waveform(chan_info *cp); GtkWidget *create_envelope_editor(void); void set_enved_clipping(bool val); void reflect_enved_style(void); void set_enved_base(mus_float_t val); void set_enved_target(enved_target_t val); void set_enved_with_wave(bool val); void set_enved_in_dB(bool val); bool enved_dialog_is_active(void); void set_enved_filter_order(int order); void color_enved_waveform(color_info *pix); void g_init_gxenv(void); /* -------- snd-gfile.c -------- */ void cleanup_file_monitor(void); void *unmonitor_file(void *watcher); void monitor_sound(snd_info *sp); char *get_file_dialog_sound_attributes(file_data *fdat, int *srate, int *chans, mus_header_t *header_type, mus_sample_t *sample_type, mus_long_t *location, mus_long_t *samples, int min_chan); widget_t make_open_file_dialog(read_only_t read_only, bool managed); widget_t make_sound_save_as_dialog(bool managed); void make_channel_extract_dialog(int chan); widget_t make_selection_save_as_dialog(bool managed); widget_t make_region_save_as_dialog(bool managed); widget_t make_new_file_dialog(bool managed); widget_t make_mix_file_dialog(bool managed); widget_t make_insert_file_dialog(bool managed); GtkWidget *edit_header(snd_info *sp); void save_edit_header_dialog_state(FILE *fd); void set_open_file_play_button(bool val); void g_init_gxfile(void); void clear_deleted_snd_info(void *fd); void reflect_just_sounds(void); void save_file_dialog_state(FILE *fd); widget_t post_it(const char *subject, const char *str); void post_it_append(const char *str); void save_post_it_dialog_state(FILE *fd); void reflect_region_in_save_as_dialog(void); void reflect_selection_in_save_as_dialog(bool on); void save_edits_now(snd_info *sp); void unpost_unsaved_edits_if_any(snd_info *sp); void unpost_file_has_changed_if_any(snd_info *sp); void changed_file_dialog(snd_info *sp); void reflect_save_as_src(bool val); void reflect_save_as_auto_comment(bool val); void reflect_save_as_sound_selection(const char *sound_name); void add_drag_and_drop(GtkWidget *w, void (*drop_watcher)(GtkWidget *w, const char *message, int x, int y, void *data), void (*drag_watcher)(GtkWidget *w, const char *message, int x, int y, drag_style_t dtype, void *data), void *context); /* -------- snd-gprefs.c -------- */ widget_t make_preferences_dialog(void); #endif snd-16.1/snd-region.c0000644000076400007640000017174312603035272012561 0ustar bilbil#include "snd.h" #include "sndlib-strings.h" #include "clm2xen.h" #define REGION_FILE 1 #define REGION_DEFERRED 0 /* region data can be stored either in a temp file that is deleted when the region is deleted (hence must be copied upon insert or mix) * or as a descriptor of current chan/beg/num/edpos locs. The descriptor form is used until some use is made of the data * that requires a file anyway (e.g. mixing), or if the data the descriptor depends on is about to be flushed (e.g. the * underlying edit list is about to be cleared, or the file is being closed, etc). */ #define CLEAR_REGION_DATA 0 #define COMPLETE_DELETION 1 static int region_id_ctr = 0; typedef struct { int chans; mus_long_t len; chan_info **cps; int *edpos; } deferred_region; static deferred_region *free_deferred_region(deferred_region *dr) { if (dr) { if (dr->cps) free(dr->cps); if (dr->edpos) free(dr->edpos); free(dr); } return(NULL); } typedef struct region { int chans; mus_long_t framples; int srate; /* for file save (i.e. region->file) */ int header_type; /* for file save */ snd_info *rsp; char *name, *start, *end; /* for region browser */ char *filename; /* if region data is stored in a temp file */ int use_temp_file; /* REGION_FILE = in temp file 'filename', REGION_DEFERRED = in 'dr' */ mus_float_t maxamp; mus_long_t maxamp_position; snd_info *editor_copy; char *editor_name; int id; deferred_region *dr; /* REGION_DEFERRED descriptor */ peak_env_info **peak_envs; mus_long_t *begs, *lens; } region; static void deferred_region_to_temp_file(region *r); static void free_region(region *r, int complete) { /* if not complete, just clear out old data (edited region being saved) */ if (r) { if (complete == COMPLETE_DELETION) { if (r->editor_copy) { snd_info *sp; sp = r->editor_copy; sp->edited_region = NULL; r->editor_copy = NULL; } if (r->name) free(r->name); if (r->start) free(r->start); if (r->end) free(r->end); if (r->begs) free(r->begs); if (r->lens) free(r->lens); if (r->peak_envs) { int i; for (i = 0; i < r->chans; i++) if (r->peak_envs[i]) r->peak_envs[i] = free_peak_env_info(r->peak_envs[i]); free(r->peak_envs); r->peak_envs = NULL; } } if (r->use_temp_file == REGION_FILE) /* we can delete this temp file because all references copy first */ { if (r->filename) { snd_remove(r->filename, REMOVE_FROM_CACHE); free(r->filename); } r->filename = NULL; } if (r->use_temp_file == REGION_DEFERRED) r->dr = free_deferred_region(r->dr); if (r->rsp) { if ((r->rsp->chans) && (r->rsp->chans[0]->edits)) r->rsp->chans[0]->edits[0]->peak_env = NULL; r->rsp = completely_free_snd_info(r->rsp); } if (complete == COMPLETE_DELETION) free(r); } } static region **regions = NULL; static int regions_size = 0, regions_allocated_size = 0; void allocate_regions(int numreg) { int i; if (numreg > regions_allocated_size) { if (regions) { regions = (region **)realloc(regions, numreg * sizeof(region *)); for (i = regions_allocated_size; i < numreg; i++) regions[i] = NULL; } else regions = (region **)calloc(numreg, sizeof(region *)); regions_allocated_size = numreg; } if (regions_size > numreg) { for (i = numreg; i < regions_size; i++) if (regions[i]) { free_region(regions[i], COMPLETE_DELETION); regions[i] = NULL; } if (region_browser_is_active()) update_region_browser(true); } regions_size = numreg; } static void set_max_regions(int n) { if (n >= 0) { allocate_regions(n); allocate_region_rows(n); in_set_max_regions(n); } } int region_id_to_list_position(int id) { int i; if ((id >= 0) && (id < region_id_ctr)) for (i = 0; i < regions_size; i++) if ((regions[i]) && (regions[i]->id == id)) return(i); return(INVALID_REGION); } int region_list_position_to_id(int n) { if ((n >= 0) && (n < regions_size) && (regions[n])) return(regions[n]->id); return(INVALID_REGION); } static region *id_to_region(int id) { int i; if ((id >= 0) && (id < region_id_ctr)) for (i = 0; i < regions_size; i++) if ((regions[i]) && (regions[i]->id == id)) return(regions[i]); return(NULL); } bool region_ok(int id) { return(id_to_region(id) != NULL); } mus_long_t region_len(int n) { region *r; r = id_to_region(n); if (r) return(r->framples); return(0); } int region_chans(int n) { region *r; r = id_to_region(n); if (r) return(r->chans); return(0); } int region_srate(int n) { region *r; r = id_to_region(n); if (r) return(r->srate); return(0); } const char *region_file_name(int n) { region *r; r = id_to_region(n); if (r) return(r->name); return(NULL); } static void get_region_maxamp(region *r) { /* it exists as r->filename, so just use sndlib... */ mus_float_t *vals; mus_long_t *times; int i; mus_long_t maxpos; mus_float_t maxsamp; vals = (mus_float_t *)calloc(r->chans, sizeof(mus_float_t)); times = (mus_long_t *)calloc(r->chans, sizeof(mus_long_t)); mus_sound_maxamps(r->filename, r->chans, vals, times); maxpos = times[0]; maxsamp = vals[0]; for (i = 1; i < r->chans; i++) if (vals[i] > maxsamp) { maxsamp = vals[i]; maxpos = times[i]; } free(vals); free(times); r->maxamp = maxsamp; r->maxamp_position = maxpos; } mus_float_t region_maxamp(int n) { region *r; r = id_to_region(n); if (r) { if (r->maxamp < 0.0) { if (r->use_temp_file == REGION_DEFERRED) deferred_region_to_temp_file(r); get_region_maxamp(r); } return(r->maxamp); } return(0.0); } static mus_long_t region_maxamp_position(int n) { region *r; r = id_to_region(n); if (r) { if (r->maxamp < 0.0) { if (r->use_temp_file == REGION_DEFERRED) deferred_region_to_temp_file(r); get_region_maxamp(r); } return(r->maxamp_position); } return(-1); } static mus_float_t region_sample(int reg, int chn, mus_long_t samp) { region *r; r = id_to_region(reg); if (r) { if ((samp < r->framples) && (chn < r->chans)) { snd_fd *sf; mus_float_t val; deferred_region *drp; switch (r->use_temp_file) { case REGION_FILE: sf = init_region_read(samp, reg, chn, READ_FORWARD); val = read_sample(sf); free_snd_fd(sf); return(val); break; case REGION_DEFERRED: drp = r->dr; return(chn_sample(samp + r->begs[chn], drp->cps[chn], drp->edpos[chn])); break; } } } return(0.0); } mus_long_t region_current_location(snd_fd *fd) { region *r; r = id_to_region(fd->region); switch (r->use_temp_file) { case REGION_FILE: return(current_location(fd)); break; case REGION_DEFERRED: return(current_location(fd) - r->begs[0]); break; } return(-1); } static void region_samples(int reg, int chn, mus_long_t beg, mus_long_t num, mus_float_t *data) { region *r; r = id_to_region(reg); if (r) { if ((beg < r->framples) && (chn < r->chans)) { snd_fd *sf; deferred_region *drp; switch (r->use_temp_file) { case REGION_FILE: sf = init_region_read(beg, reg, chn, READ_FORWARD); samples_to_vct_with_reader(num, data, sf); free_snd_fd(sf); break; case REGION_DEFERRED: drp = r->dr; sf = init_sample_read_any_with_bufsize(beg + r->begs[chn], drp->cps[chn], READ_FORWARD, drp->edpos[chn], num); samples_to_vct_with_reader(num, data, sf); free_snd_fd(sf); break; } } } } static int first_region_active(void) { int i; for (i = 0; i < regions_size; i++) if (regions[i]) return(i); return(NO_REGIONS); } static int check_regions(void) { int act; act = first_region_active(); if (act == NO_REGIONS) reflect_no_regions_in_region_browser(); return(act); } static void make_region_readable(region *r) { snd_info *regsp; file_info *hdr; int i; if (r->use_temp_file == REGION_DEFERRED) deferred_region_to_temp_file(r); if (r->rsp) return; regsp = make_basic_snd_info(r->chans); regsp->nchans = r->chans; regsp->hdr = (file_info *)calloc(1, sizeof(file_info)); regsp->inuse = SOUND_READER; hdr = regsp->hdr; hdr->samples = r->framples * r->chans; hdr->srate = r->srate; hdr->chans = r->chans; hdr->comment = NULL; for (i = 0; i < r->chans; i++) { hdr = make_file_info(r->filename, FILE_READ_ONLY, FILE_NOT_SELECTED); if (hdr) { snd_io *io; int fd; chan_info *cp; cp = make_chan_info(NULL, i, regsp); cp->editable = false; regsp->chans[i] = cp; add_channel_data_1(cp, r->srate, r->framples, WITHOUT_GRAPH); cp->hookable = WITHOUT_HOOK; fd = snd_open_read(r->filename); snd_file_open_descriptors(fd, r->filename, hdr->sample_type, hdr->data_location, hdr->chans, hdr->type); io = make_file_state(fd, hdr, i, 0, FILE_BUFFER_SIZE); cp->sounds[0] = make_snd_data_file(r->filename, io, hdr, DONT_DELETE_ME, cp->edit_ctr, i); /* don't auto-delete! */ } else { Xen_error(Xen_make_error_type("IO-error"), Xen_list_3(C_string_to_Xen_string("can't read region file ~S, ~A"), C_string_to_Xen_string(r->filename), C_string_to_Xen_string(snd_open_strerror()))); } } r->rsp = regsp; } file_info *fixup_region_data(chan_info *cp, int chan, int pos) { /* for region browser labels */ if ((pos >= 0) && (pos < regions_size) && (regions[pos])) { region *r; r = regions[pos]; if (chan < r->chans) { snd_info *nsp; chan_info *ncp; make_region_readable(r); nsp = r->rsp; ncp = nsp->chans[chan]; cp->sounds = ncp->sounds; cp->sound_size = ncp->sound_size; cp->edits = ncp->edits; /* ?? is this safe ?? */ cp->edit_size = ncp->edit_size; cp->edit_ctr = ncp->edit_ctr; cp->edits[0]->samples = ncp->edits[0]->samples; cp->axis = ncp->axis; /* cp here is actually region sound chan 0 */ if ((r->peak_envs) && (r->peak_envs[chan])) cp->edits[0]->peak_env = r->peak_envs[chan]; else { if (cp->edits[0]->peak_env) cp->edits[0]->peak_env = NULL; } initialize_scrollbars(cp); return(nsp->hdr); } } return(NULL); } void for_each_region_chan_with_refint(void (*func)(chan_info *ncp, int *val), int *value) { /* used only in snd-io.c to remove dangling temp files (probably can't actually happen) */ int i; for (i = 0; i < regions_size; i++) { int chn; region *r; r = regions[i]; if ((r) && (r->rsp) && (r->use_temp_file == REGION_FILE)) for (chn = 0; chn < r->chans; chn++) { chan_info *cp; cp = r->rsp->chans[chn]; (*func)(cp, value); } } } region_state *region_report(void) { region_state *rs; int i, len; rs = (region_state *)calloc(1, sizeof(region_state)); len = regions_size; for (i = 0; i < regions_size; i++) if (!(regions[i])) { len = i; break; } rs->len = len; if (len == 0) return(rs); rs->name = (char **)calloc(len, sizeof(char *)); for (i = 0; i < len; i++) { region *r; char *reg_buf; r = regions[i]; reg_buf = (char *)calloc(LABEL_BUFFER_SIZE, sizeof(char)); snprintf(reg_buf, LABEL_BUFFER_SIZE, "%d: %s (%s:%s)", r->id, r->name, r->start, r->end); rs->name[i] = reg_buf; } return(rs); } char *region_description(int rg) { region *r; r = id_to_region(rg); if (r) return(mus_format("region data from %s (%s : %s)", r->name, r->start, r->end)); return(NULL); } void free_region_state(region_state *r) { if (r) { int i; for (i = 0; i < r->len; i++) if (r->name[i]) free(r->name[i]); if (r->name) free(r->name); free(r); } } int remove_region_from_list(int pos) /* region browser */ { int i, id; id = region_list_position_to_id(pos); if (id == INVALID_REGION) return(INVALID_REGION); stop_playing_region(id, PLAY_CLOSE); free_region(id_to_region(id), COMPLETE_DELETION); for (i = pos; i < regions_size - 1; i++) regions[i] = regions[i + 1]; regions[regions_size - 1] = NULL; return(check_regions()); } static void add_to_region_list(region *r) { int i, okr = -1; for (i = max_regions(ss) - 1; i >= 0; i--) { if (!(regions[i])) { okr = i; break; } } if (okr == -1) okr = max_regions(ss) - 1; if (regions[okr]) { stop_playing_region(regions[okr]->id, PLAY_CLOSE); free_region(regions[okr], COMPLETE_DELETION); } for (i = okr; i > 0; i--) regions[i] = regions[i - 1]; regions[0] = r; if (!r) check_regions(); } #define NOT_EDITABLE -2 static int paste_region_1(int n, chan_info *cp, bool add, mus_long_t beg, io_error_t *err, int start_chan, int *out_chans) { region *r; char *origin = NULL; int id = -1; io_error_t io_err; sync_info *si = NULL; r = id_to_region(n); if ((r == NULL) || (r->framples == 0)) return(INVALID_REGION); if (!(is_editable(cp))) { (*err) = IO_EDIT_HOOK_CANCELLATION; return(NOT_EDITABLE); } if (r->use_temp_file == REGION_DEFERRED) deferred_region_to_temp_file(r); si = sync_to_chan(cp); (*out_chans) = si->chans; if (add) { /* unfortunately we need to copy here since the region may fall off the region stack while we're still using the mix */ char *newname; newname = shorter_tempnam(temp_dir(ss), "snd_"); io_err = copy_file(r->filename, newname); if (io_err != IO_NO_ERROR) { (*err) = io_err; return(INVALID_REGION); } else { #if HAVE_FORTH origin = mus_format("%d %s %lld %s drop", n, S_integer_to_region, beg, S_mix_region); #endif #if HAVE_RUBY origin = mus_format("%s(%s(%d), %lld", to_proc_name(S_mix_region), to_proc_name(S_integer_to_region), n, beg); #endif #if HAVE_SCHEME || (!HAVE_EXTENSION_LANGUAGE) origin = mus_format("%s (%s %d) %lld", S_mix_region, S_integer_to_region, n, beg); #endif if (si->chans > 1) remember_temp(newname, si->chans); id = mix_file(beg, r->framples, si->chans, si->cps, newname, (si->chans > 1) ? MULTICHANNEL_DELETION : DELETE_ME, origin, with_mix_tags(ss), start_chan); free(origin); } if (newname) free(newname); } else { int i; char *tempfile = NULL; if (r->use_temp_file == REGION_FILE) { tempfile = snd_tempnam(); io_err = copy_file(r->filename, tempfile); if (io_err != IO_NO_ERROR) { if (si) si = free_sync_info(si); (*err) = io_err; return(INVALID_REGION); } else if (r->chans > 1) remember_temp(tempfile, r->chans); } #if HAVE_FORTH origin = mus_format("%d %s %lld %s drop", n, S_integer_to_region, beg, S_insert_region); #endif #if HAVE_RUBY origin = mus_format("%s(%s(%d), %lld", to_proc_name(S_insert_region), to_proc_name(S_integer_to_region), n, beg); #endif #if HAVE_SCHEME || (!HAVE_EXTENSION_LANGUAGE) origin = mus_format("%s (%s %d) %lld", S_insert_region, S_integer_to_region, n, beg); #endif for (i = 0; ((i < r->chans) && (i < si->chans)); i++) { chan_info *ncp; ncp = si->cps[i]; /* currently syncd chan that we might paste to */ if (file_insert_samples(beg, r->framples, tempfile, ncp, i, (r->chans > 1) ? MULTICHANNEL_DELETION : DELETE_ME, origin, ncp->edit_ctr)) update_graph(si->cps[i]); } free(origin); if ((r->use_temp_file == REGION_FILE) && (tempfile)) free(tempfile); } if (si) si = free_sync_info(si); return(id); } static io_error_t paste_region_2(int n, chan_info *cp, bool add, mus_long_t beg) { io_error_t err = IO_NO_ERROR; int chans = 0; paste_region_1(n, cp, add, beg, &err, 0, &chans); return(err); } io_error_t paste_region(int n, chan_info *cp) { return(paste_region_2(n, cp, false, cursor_sample(cp))); } io_error_t add_region(int n, chan_info *cp) { return(paste_region_2(n, cp, true, cursor_sample(cp))); } int define_region(sync_info *si, mus_long_t *ends) { /* now look at all sync'd channels, collect them into the current region */ /* we created the necessary pointers in create_selection above */ int i; mus_long_t len; chan_info *cp0; snd_info *sp0; region *r; deferred_region *drp; len = 0; for (i = 0; i < si->chans; i++) if (len < (ends[i] - si->begs[i])) len = ends[i] - si->begs[i]; len += 1; if (len <= 0) return(INVALID_REGION); cp0 = si->cps[0]; sp0 = cp0->sound; r = (region *)calloc(1, sizeof(region)); r->id = region_id_ctr++; if (regions[0]) add_to_region_list(r); else regions[0] = r; r->header_type = (sp0->hdr)->type; r->srate = snd_srate(sp0); r->maxamp = -1.0; r->maxamp_position = -1; r->editor_copy = NULL; r->name = mus_strdup(sp0->short_filename); r->chans = si->chans; r->framples = len; r->start = prettyf((double)(si->begs[0]) / (double)(r->srate), 2); r->end = prettyf((double)(ends[0]) / (double)(r->srate), 2); r->use_temp_file = REGION_DEFERRED; r->begs = (mus_long_t *)calloc(r->chans, sizeof(mus_long_t)); r->lens = (mus_long_t *)calloc(r->chans, sizeof(mus_long_t)); ss->deferred_regions++; r->dr = (deferred_region *)calloc(1, sizeof(deferred_region)); drp = r->dr; drp->chans = si->chans; drp->cps = (chan_info **)calloc(drp->chans, sizeof(chan_info *)); drp->edpos = (int *)calloc(drp->chans, sizeof(int)); drp->len = len; for (i = 0; i < drp->chans; i++) { drp->cps[i] = si->cps[i]; r->begs[i] = si->begs[i]; r->lens[i] = ends[i] - si->begs[i]; drp->edpos[i] = drp->cps[i]->edit_ctr; if (r->lens[i] > PEAK_ENV_CUTOFF) { peak_env_info *ep; ep = drp->cps[i]->edits[drp->edpos[i]]->peak_env; if ((ep) && (ep->completed)) { if (r->peak_envs == NULL) r->peak_envs = (peak_env_info **)calloc(r->chans, sizeof(peak_env_info *)); r->peak_envs[i] = peak_env_section(drp->cps[i], r->begs[i], r->lens[i], drp->edpos[i]); } } } reflect_regions_in_region_browser(); if (region_browser_is_active()) update_region_browser(true); return(r->id); } static void deferred_region_to_temp_file(region *r) { int i, datumb = 0; bool copy_ok; mus_long_t alloc_len, len = 0; snd_fd **sfs = NULL; snd_info *sp0; deferred_region *drp = NULL; mus_float_t **data = NULL; ss->deferred_regions--; drp = r->dr; len = drp->len; r->use_temp_file = REGION_FILE; r->filename = snd_tempnam(); sp0 = drp->cps[0]->sound; copy_ok = ((mus_header_writable(MUS_NEXT, sp0->hdr->sample_type)) && (r->chans == sp0->nchans) && (r->peak_envs != NULL) && ((drp->len - 1) == r->lens[0])); if (copy_ok) for (i = 0; i < r->chans; i++) if ((drp->edpos[i] != 0) || (drp->cps[i]->sound != sp0) || (r->begs[i] != r->begs[0]) || (r->lens[i] != (drp->len - 1)) || (r->peak_envs[i] == NULL)) { copy_ok = false; break; } if (copy_ok) { /* write next header with correct len * seek loc in sp0->filename (r->begs[0]) * copy len*data-size bytes * get max from amp envs */ mus_long_t err; datumb = mus_bytes_per_sample(sp0->hdr->sample_type); err = mus_write_header(r->filename, MUS_NEXT, r->srate, r->chans, drp->len * r->chans, sp0->hdr->sample_type, "region deferred temp"); if (err != MUS_NO_ERROR) snd_error("can't write region temp file %s: %s", r->filename, snd_io_strerror()); else { int fdi, fdo; mus_long_t oloc; oloc = mus_header_data_location(); fdo = snd_reopen_write(r->filename); lseek(fdo, oloc, SEEK_SET); fdi = mus_file_open_read(sp0->filename); if (fdi == -1) snd_error("can't read region's original sound? %s: %s", sp0->filename, snd_io_strerror()); else { mus_long_t j, data_size; char *buffer; lseek(fdi, sp0->hdr->data_location + r->chans * datumb * r->begs[0], SEEK_SET); data_size = drp->len * r->chans * datumb; if (data_size > REPORTING_SIZE) alloc_len = REPORTING_SIZE; else alloc_len = data_size; buffer = (char *)malloc(alloc_len * sizeof(char)); for (j = 0; j < data_size; j += alloc_len) { mus_long_t bytes; ssize_t n; bytes = data_size - j; if (bytes > alloc_len) bytes = alloc_len; /* read and write return 0 to indicate end of file, apparently */ n = read(fdi, buffer, bytes); if (n < 0) fprintf(stderr, "IO error while reading region temp file: %d %s\n", (int)n, strerror(errno)); if (n > 0) { n = write(fdo, buffer, bytes); if (n < 0) fprintf(stderr, "IO error while writing region temp file: %d %s\n", (int)n, strerror(errno)); } } free(buffer); snd_close(fdi, sp0->filename); } snd_close(fdo, r->filename); } } else { io_error_t io_err = IO_NO_ERROR; file_info *hdr = NULL; int ofd; hdr = make_temp_header(r->filename, r->srate, r->chans, 0, (char *)__func__); ofd = open_temp_file(r->filename, r->chans, hdr, &io_err); if (ofd == -1) snd_error("%s region temp file %s: %s", (io_err != IO_NO_ERROR) ? io_error_name(io_err) : "can't open", r->filename, snd_open_strerror()); else { sfs = (snd_fd **)calloc(r->chans, sizeof(snd_fd *)); data = (mus_float_t **)calloc(r->chans, sizeof(mus_float_t *)); datumb = mus_bytes_per_sample(hdr->sample_type); /* here if peak_envs, maxamp exists */ alloc_len = len; if (alloc_len > REPORTING_SIZE) alloc_len = REPORTING_SIZE; for (i = 0; i < r->chans; i++) { sfs[i] = init_sample_read_any(r->begs[i], drp->cps[i], READ_FORWARD, drp->edpos[i]); data[i] = (mus_float_t *)calloc(alloc_len, sizeof(mus_float_t)); } if ((r->chans == 1) && (r->lens[0] == (len - 1))) { snd_fd *sf; mus_float_t *d; sf = sfs[0]; d = data[0]; if (len <= REPORTING_SIZE) { samples_to_vct_with_reader(len, d, sf); mus_file_write(ofd, 0, len - 1, 1, data); } else { int k; sampler_set_safe(sf, len); for (k = 0; k < len; k += alloc_len) { mus_long_t kdur, n; int err; kdur = len - k; if (kdur > alloc_len) kdur = alloc_len; for (n = 0; n < kdur; n++) d[n] = read_sample(sf); err = mus_file_write(ofd, 0, kdur - 1, 1, data); if (err != MUS_NO_ERROR) break; } } } else { if (len <= REPORTING_SIZE) { for (i = 0; i < r->chans; i++) samples_to_vct_with_reader(len, data[i], sfs[i]); mus_file_write(ofd, 0, len - 1, r->chans, data); } else { int k; for (i = 0; i < r->chans; i++) sampler_set_safe(sfs[i], len); for (k = 0; k < len; k += alloc_len) { int err; mus_long_t kdur; kdur = len - k; if (kdur > alloc_len) kdur = alloc_len; for (i = 0; i < r->chans; i++) { mus_long_t n; snd_fd *p; mus_float_t *buf; buf = data[i]; p = sfs[i]; for (n = 0; n < kdur; n++) buf[n] = read_sample(p); } err = mus_file_write(ofd, 0, kdur - 1, r->chans, data); if (err != MUS_NO_ERROR) break; } } } close_temp_file(r->filename, ofd, hdr->type, len * r->chans * datumb); for (i = 0; i < r->chans; i++) free(data[i]); for (i = 0; i < r->chans; i++) free_snd_fd(sfs[i]); free(sfs); free(data); data = NULL; } hdr = free_file_info(hdr); } r->dr = free_deferred_region(r->dr); } void sequester_deferred_regions(chan_info *cp, int edit_top) { region *r; deferred_region *drp; int i; for (i = 0; i < regions_size; i++) { r = regions[i]; if ((r) && (r->use_temp_file == REGION_DEFERRED)) { int j; drp = r->dr; for (j = 0; j < drp->chans; j++) if ((drp->cps[j] == cp) && (drp->edpos[j] > edit_top)) { if (r->lens[j] > 1000000) status_report(cp->sound, "sequestering region %d...", r->id); deferred_region_to_temp_file(r); if (r->lens[j] > 1000000) clear_status_area(cp->sound); break; } } } } snd_fd *init_region_read(mus_long_t beg, int n, int chan, read_direction_t direction) { /* conjure up a reasonable looking ed list and sound list */ region *r; r = id_to_region(n); if ((r) && (chan < r->chans)) { if ((beg == 0) && (direction == READ_BACKWARD)) beg = r->framples - 1; if (r->use_temp_file == REGION_DEFERRED) { deferred_region *drp; drp = r->dr; return(init_sample_read_any(r->begs[chan] + beg, drp->cps[chan], direction, drp->edpos[chan])); } else { make_region_readable(r); return(init_sample_read(beg, r->rsp->chans[chan], direction)); } } return(NULL); } void cleanup_region_temp_files(void) { /* called upon exit to get rid of lingering region-related temp files */ int i; for (i = 0; i < regions_size; i++) { region *r; r = regions[i]; if ((r) && (r->use_temp_file == REGION_FILE) && (r->filename)) { snd_remove(r->filename, REMOVE_FROM_CACHE); free(r->filename); r->filename = NULL; } } } int snd_regions(void) { int i, num; num = 0; for (i = 0; i < regions_size; i++) if (regions[i]) num++; return(num); } /* (restore-region n chans len srate maxamp name start end filename [date-and-length]) */ void save_regions(FILE *fd) { int i; for (i = 0; i < regions_size; i++) { region *r; r = regions[i]; if (r) { io_error_t io_err; char *newname; char *ofile = NULL; if (r->use_temp_file == REGION_DEFERRED) deferred_region_to_temp_file(r); ofile = shorter_tempnam(save_dir(ss), "snd_save_"); newname = run_save_state_hook(ofile); free(ofile); io_err = copy_file(r->filename, newname); if (io_err != IO_NO_ERROR) { snd_warning("trying to save region %d (%s) in %s: %s, %s", r->id, r->filename, newname, io_error_name(io_err), strerror(ss->local_errno)); } else { #if HAVE_RUBY fprintf(fd, "%s(%d, %d, %lld, %d, %.4f, \"%s\", \"%s\", \"%s\", ", "restore_region", i, r->chans, r->framples, r->srate, r->maxamp, r->name, r->start, r->end); fprintf(fd, " \"%s\", [%d, %lld])\n", newname, (int)mus_sound_write_date(newname), mus_sound_length(newname)); #endif #if HAVE_SCHEME fprintf(fd, "(%s %d %d %lld %d %.4f \"%s\" \"%s\" \"%s\"", S_restore_region, i, r->chans, r->framples, r->srate, r->maxamp, r->name, r->start, r->end); fprintf(fd, " \"%s\" (list %d %lld))\n", newname, (int)mus_sound_write_date(newname), mus_sound_length(newname)); #endif #if HAVE_FORTH fprintf(fd, "%d %d %lld %d %.4f \"%s\" \"%s\" \"%s\"", i, r->chans, r->framples, r->srate, r->maxamp, r->name, r->start, r->end); fprintf(fd, " \"%s\" '( %d %lld ) %s drop\n", newname, (int)mus_sound_write_date(newname), mus_sound_length(newname), S_restore_region); #endif } free(newname); } } } void region_edit(int pos) { /* from region browser: * load region into temp file, load that into snd editor, * if 'save', save temp file and update region (browser also) (cancelling active display if any) * while editing, if delete in browser, cut backpointer in editor and signal it */ region *r = NULL; if ((pos >= 0) && (pos < regions_size) && (regions[pos])) r = regions[pos]; if (r) { if (r->editor_copy) snd_error("region %d already being edited", r->id); else { io_error_t io_err; char *temp_region_name; if (r->use_temp_file == REGION_DEFERRED) deferred_region_to_temp_file(r); temp_region_name = shorter_tempnam(temp_dir(ss), "region-"); io_err = copy_file(r->filename, temp_region_name); if (io_err == IO_NO_ERROR) { snd_info *sp; ss->open_requestor = FROM_REGION_EDIT; sp = snd_open_file(temp_region_name, FILE_READ_WRITE); if (sp) { r->editor_copy = sp; r->editor_name = mus_strdup(temp_region_name); sp->edited_region = r; /* save backpointer so subsequent save affects region if still legit */ /* also, since it's a temp file, if closed, delete temp */ } else snd_error("edit region: can't open region %d temp sound %s: %s!", r->id, temp_region_name, snd_io_strerror()); } else snd_error("edit region: can't save region %d in temp file (%s: %s)", r->id, temp_region_name, snd_io_strerror()); free(temp_region_name); } } else snd_error("edit region: no region at position %d!", pos); } void clear_region_backpointer(snd_info *sp) { if (sp->edited_region) { region *r; r = sp->edited_region; if (r) { snd_remove(r->editor_name, REMOVE_FROM_CACHE); free(r->editor_name); r->editor_name = NULL; r->editor_copy = NULL; } sp->edited_region = NULL; } } void save_region_backpointer(snd_info *sp) { /* region being edited, user chose 'save' */ region *r; int i; io_error_t io_err; r = sp->edited_region; /* update r's data in file, deleting old, redisplay if browser active etc */ if (r == regions[0]) deactivate_selection(); free_region(r, CLEAR_REGION_DATA); r->use_temp_file = REGION_FILE; r->maxamp = 0.0; r->maxamp_position = -1; r->framples = current_samples(sp->chans[0]); for (i = 0; i < sp->nchans; i++) { mus_float_t val; val = channel_maxamp(sp->chans[i], AT_CURRENT_EDIT_POSITION); if (val > r->maxamp) r->maxamp = val; if (r->lens[i] > PEAK_ENV_CUTOFF) { chan_info *cp; cp = sp->chans[i]; if (r->peak_envs[i]) free_peak_env_info(r->peak_envs[i]); /* if region file was edited, the peak_envs probably changed */ r->peak_envs[i] = copy_peak_env_info(cp->edits[0]->peak_env, false); } } /* make new region temp file */ r->filename = snd_tempnam(); io_err = copy_file(r->editor_name, r->filename); if (io_err != IO_NO_ERROR) { if (io_err == IO_CANT_OPEN_FILE) snd_error("can't find edited region temp file (%s: %s)", r->editor_name, snd_io_strerror()); else snd_error("can't make region temp file (%s: %s)", r->filename, snd_io_strerror()); } else { make_region_readable(r); if (region_browser_is_active()) update_region_browser(true); } } io_error_t save_region(int rg, const char *name, mus_sample_t samp_type, mus_header_t head_type, const char *comment) { region *r; io_error_t io_err = IO_NO_ERROR; r = id_to_region(rg); if (r->use_temp_file == REGION_DEFERRED) deferred_region_to_temp_file(r); io_err = snd_write_header(name, head_type, region_srate(rg), r->chans, r->chans * r->framples, samp_type, comment, NULL); if (io_err == IO_NO_ERROR) { mus_long_t oloc; int ofd; oloc = mus_header_data_location(); ofd = snd_reopen_write(name); if (ofd != -1) { int ifd; snd_file_open_descriptors(ofd, name, samp_type, oloc, r->chans, head_type); mus_file_set_clipping(ofd, clipping(ss)); lseek(ofd, oloc, SEEK_SET); /* copy r->filename with possible header/sample type changes */ ifd = snd_open_read(r->filename); if (ifd != -1) { mus_long_t iloc, framples, cursamples; int chans, i, err = 0, ioff; mus_float_t **bufs; chans = mus_sound_chans(r->filename); framples = mus_sound_samples(r->filename) / chans; iloc = mus_sound_data_location(r->filename); snd_file_open_descriptors(ifd, r->filename, mus_sound_sample_type(r->filename), iloc, chans, mus_sound_header_type(r->filename)); lseek(ifd, iloc, SEEK_SET); bufs = (mus_float_t **)calloc(chans, sizeof(mus_float_t *)); for (i = 0; i < chans; i++) bufs[i] = (mus_float_t *)calloc(FILE_BUFFER_SIZE, sizeof(mus_float_t)); if (((framples * chans * mus_sound_datum_size(r->filename)) >> 10) > disk_kspace(name)) snd_warning("not enough space to save region? -- need %lld bytes", framples * chans * mus_sound_datum_size(r->filename)); err = 0; for (ioff = 0; ioff < framples; ioff += FILE_BUFFER_SIZE) { if ((ioff + FILE_BUFFER_SIZE) < framples) cursamples = FILE_BUFFER_SIZE; else cursamples = (framples - ioff); mus_file_read(ifd, ioff, cursamples, chans, bufs); err = mus_file_write(ofd, 0, cursamples - 1, chans, bufs); if (err != MUS_NO_ERROR) { snd_warning("write error during %s", S_save_region); break; } } err = mus_file_close(ifd); for (i = 0; i < chans; i++) free(bufs[i]); free(bufs); if (err != 0) snd_warning("can't close %s input!", S_save_region); err = mus_file_close(ofd); if (ss->file_monitor_ok) { if (err != 0) snd_error("%s %d: %s %s", S_save_region, rg, r->filename, snd_io_strerror()); } else { #if USE_MOTIF if (err == 0) alert_new_file(); else #else if (err != 0) #endif snd_error("%s %d: %s %s", S_save_region, rg, r->filename, snd_io_strerror()); } } else snd_error("%s %d: %s %s", S_save_region, rg, r->filename, snd_io_strerror()); } else snd_error("%s %d: %s %s", S_save_region, rg, name, snd_io_strerror()); } else snd_error("%s %d: %s %s", S_save_region, rg, name, snd_io_strerror()); return(io_err); } /* ---------------------------------------- region objects ---------------------------------------- */ typedef struct { int n; } xen_region; #define Xen_to_xen_region(arg) ((xen_region *)Xen_object_ref(arg)) int xen_region_to_int(Xen n) { xen_region *mx; mx = Xen_to_xen_region(n); return(mx->n); } static Xen_object_type_t xen_region_tag; bool xen_is_region(Xen obj) { return(Xen_c_object_is_type(obj, xen_region_tag)); } static void xen_region_free(xen_region *v) {if (v) free(v);} Xen_wrap_free(xen_region, free_xen_region, xen_region_free) static char *xen_region_to_string(xen_region *v) { #define REGION_PRINT_BUFFER_SIZE 64 char *buf; if (v == NULL) return(NULL); buf = (char *)calloc(REGION_PRINT_BUFFER_SIZE, sizeof(char)); snprintf(buf, REGION_PRINT_BUFFER_SIZE, "#", v->n); return(buf); } Xen_wrap_print(xen_region, print_xen_region, xen_region_to_string) #if HAVE_FORTH || HAVE_RUBY static Xen g_xen_region_to_string(Xen obj) { char *vstr; Xen result; #define S_xen_region_to_string "region->string" Xen_check_type(xen_is_region(obj), obj, 1, S_xen_region_to_string, "a region"); vstr = xen_region_to_string(Xen_to_xen_region(obj)); result = C_string_to_Xen_string(vstr); free(vstr); return(result); } #endif #if (!HAVE_SCHEME) static bool xen_region_equalp(xen_region *v1, xen_region *v2) { return((v1 == v2) || (v1->n == v2->n)); } static Xen equalp_xen_region(Xen obj1, Xen obj2) { if ((!(xen_is_region(obj1))) || (!(xen_is_region(obj2)))) return(Xen_false); return(C_bool_to_Xen_boolean(xen_region_equalp(Xen_to_xen_region(obj1), Xen_to_xen_region(obj2)))); } #endif static xen_region *xen_region_make(int n) { xen_region *new_v; new_v = (xen_region *)malloc(sizeof(xen_region)); new_v->n = n; return(new_v); } Xen new_xen_region(int n) { xen_region *mx; if (n < 0) return(Xen_false); mx = xen_region_make(n); return(Xen_make_object(xen_region_tag, mx, 0, free_xen_region)); } #if HAVE_SCHEME static bool s7_xen_region_equalp(void *obj1, void *obj2) { return((obj1 == obj2) || (((xen_region *)obj1)->n == ((xen_region *)obj2)->n)); } static Xen s7_xen_region_length(s7_scheme *sc, Xen obj) { return(g_region_framples(obj, Xen_integer_zero)); } #endif static void init_xen_region(void) { #if HAVE_SCHEME xen_region_tag = s7_new_type_x(s7, "", print_xen_region, free_xen_region, s7_xen_region_equalp, NULL, NULL, NULL, s7_xen_region_length, NULL, NULL, NULL); #else #if HAVE_RUBY xen_region_tag = Xen_make_object_type("XenRegion", sizeof(xen_region)); #else xen_region_tag = Xen_make_object_type("Region", sizeof(xen_region)); #endif #endif #if HAVE_FORTH fth_set_object_inspect(xen_region_tag, print_xen_region); fth_set_object_dump(xen_region_tag, g_xen_region_to_string); fth_set_object_equal(xen_region_tag, equalp_xen_region); fth_set_object_free(xen_region_tag, free_xen_region); #endif #if HAVE_RUBY rb_define_method(xen_region_tag, "to_s", Xen_procedure_cast print_xen_region, 0); rb_define_method(xen_region_tag, "eql?", Xen_procedure_cast equalp_xen_region, 1); rb_define_method(xen_region_tag, "==", Xen_procedure_cast equalp_xen_region, 1); rb_define_method(xen_region_tag, "to_str", Xen_procedure_cast g_xen_region_to_string, 0); #endif } /* -------------------------------------------------------------------------------- */ static Xen g_integer_to_region(Xen n) { #define H_integer_to_region "(" S_integer_to_region " n) returns a region object corresponding to the given integer" Xen_check_type(Xen_is_integer(n), n, 1, S_integer_to_region, "an integer"); return(new_xen_region(Xen_integer_to_C_int(n))); } static Xen g_region_to_integer(Xen n) { #define H_region_to_integer "(" S_region_to_integer " id) returns the integer corresponding to the given region" Xen_check_type(xen_is_region(n), n, 1, S_region_to_integer, "a region"); return(C_int_to_Xen_integer(xen_region_to_int(n))); } static Xen snd_no_such_region_error(const char *caller, Xen n) { Xen_error(Xen_make_error_type("no-such-region"), Xen_list_3(C_string_to_Xen_string("~A: no such region, ~A"), C_string_to_Xen_string(caller), n)); return(Xen_false); } /* Xen pos, Xen chans, Xen len, Xen srate, Xen maxamp, Xen name, Xen start, Xen end, Xen filename, Xen date */ static Xen g_restore_region(Xen args) { /* internal function used by save-state mechanism -- not intended for external use */ region *r; int regn; Xen arg, pos, chans, len, srate, maxamp, name, start, end, filename, date; arg = args; pos = Xen_car(arg); Xen_check_type(Xen_is_integer(pos), pos, 1, S_restore_region, "a region id"); arg = Xen_cdr(arg); chans = Xen_car(arg); Xen_check_type(Xen_is_integer(chans), chans, 2, S_restore_region, "an integer"); arg = Xen_cdr(arg); len = Xen_car(arg); Xen_check_type(Xen_is_number(len), len, 3, S_restore_region, "an integer"); arg = Xen_cdr(arg); srate = Xen_car(arg); Xen_check_type(Xen_is_integer(srate), srate, 4, S_restore_region, "an integer"); arg = Xen_cdr(arg); maxamp = Xen_car(arg); Xen_check_type(Xen_is_double(maxamp), maxamp, 5, S_restore_region, "a double"); arg = Xen_cdr(arg); name = Xen_car(arg); Xen_check_type(Xen_is_string(name), name, 6, S_restore_region, "a string"); arg = Xen_cdr(arg); start = Xen_car(arg); Xen_check_type(Xen_is_string(start), start, 7, S_restore_region, "a string"); arg = Xen_cdr(arg); end = Xen_car(arg); Xen_check_type(Xen_is_string(end), end, 8, S_restore_region, "a string"); arg = Xen_cdr(arg); filename = Xen_car(arg); Xen_check_type(Xen_is_string(filename), filename, 9, S_restore_region, "a string"); arg = Xen_cdr(arg); date = Xen_car(arg); Xen_check_type(Xen_is_list(date) && (Xen_list_length(date) == 2), date, 10, S_restore_region, "a list: '(time bytes)"); check_saved_temp_file("region", filename, date); r = (region *)calloc(1, sizeof(region)); regn = Xen_integer_to_C_int(pos); if (regions[regn]) free_region(regions[regn], COMPLETE_DELETION); regions[regn] = r; r->id = region_id_ctr++; r->maxamp = Xen_real_to_C_double(maxamp); r->maxamp_position = -1; /* not saved/restored */ r->chans = Xen_integer_to_C_int(chans); r->rsp = NULL; r->editor_copy = NULL; r->editor_name = NULL; r->framples = Xen_llong_to_C_llong(len); r->srate = Xen_integer_to_C_int(srate); r->name = mus_strdup(Xen_string_to_C_string(name)); r->start = mus_strdup(Xen_string_to_C_string(start)); r->end = mus_strdup(Xen_string_to_C_string(end)); r->use_temp_file = REGION_FILE; r->filename = mus_strdup(Xen_string_to_C_string(filename)); reflect_regions_in_region_browser(); return(C_int_to_Xen_integer(r->id)); } static Xen g_insert_region(Xen reg_n, Xen samp_n, Xen snd_n, Xen chn_n) /* opt reg_n */ { #define H_insert_region "(" S_insert_region " region :optional (start-samp 0) snd chn): \ insert region data into snd's channel chn starting at start-samp" chan_info *cp; int rg; mus_long_t samp; io_error_t err = IO_NO_ERROR; Xen_check_type(xen_is_region(reg_n), reg_n, 1, S_insert_region, "a region id"); Xen_check_type(Xen_is_integer_or_unbound(samp_n), samp_n, 2, S_insert_region, "an integer"); Snd_assert_channel(S_insert_region, snd_n, chn_n, 3); cp = get_cp(snd_n, chn_n, S_insert_region); if (!cp) return(Xen_false); rg = Xen_region_to_C_int(reg_n); if (!(region_ok(rg))) return(snd_no_such_region_error(S_insert_region, reg_n)); samp = beg_to_sample(samp_n, S_insert_region); err = paste_region_2(rg, cp, false, samp); if (is_serious_io_error(err)) Xen_error(Xen_make_error_type("IO-error"), Xen_list_3(C_string_to_Xen_string(S_insert_region ": can't edit ~A (region access problem?), ~A"), C_string_to_Xen_string(cp->sound->filename), C_string_to_Xen_string(io_error_name(err)))); update_graph(cp); return(reg_n); } static Xen g_max_regions(void) { #define H_max_regions "(" S_max_regions "): max number of regions saved on the region list" return(C_int_to_Xen_integer(max_regions(ss))); } static Xen g_set_max_regions(Xen n) { int regs; Xen_check_type(Xen_is_integer(n), n, 1, S_set S_max_regions, "an integer"); regs = Xen_integer_to_C_int(n); if (regs < 0) Xen_out_of_range_error(S_set S_max_regions, 1, n, S_max_regions "negative?"); set_max_regions(regs); return(C_int_to_Xen_integer(max_regions(ss))); } static Xen g_is_region(Xen n) { #define H_is_region "(" S_is_region " reg): " PROC_TRUE " if region is active" return(C_bool_to_Xen_boolean((xen_is_region(n)) && (region_ok(Xen_region_to_C_int(n))))); } Xen g_region_framples(Xen n, Xen chan) { region *r; int rg, chn; #define H_region_framples "(" S_region_framples " reg :optional (chan 0)): region length in framples" Xen_check_type(xen_is_region(n), n, 1, S_region_framples, "a region"); Xen_check_type(Xen_is_integer_or_unbound(chan), chan, 2, S_region_framples, "an integer"); rg = Xen_region_to_C_int(n); if (!(region_ok(rg))) return(snd_no_such_region_error(S_region_framples, n)); if (!Xen_is_bound(chan)) return(C_llong_to_Xen_llong(region_len(rg))); chn = Xen_integer_to_C_int(chan); if ((chn < 0) || (chn >= region_chans(rg))) return(snd_no_such_channel_error(S_region_framples, Xen_list_1(n), chan)); r = id_to_region(rg); return(C_llong_to_Xen_llong(r->lens[chn] + 1)); } static Xen g_region_position(Xen n, Xen chan) { region *r; int rg, chn = 0; #define H_region_position "(" S_region_position " reg :optional (chan 0)): region's position in the original sound" Xen_check_type(xen_is_region(n), n, 1, S_region_position, "a region"); Xen_check_type(Xen_is_integer_or_unbound(chan), chan, 2, S_region_position, "an integer"); rg = Xen_region_to_C_int(n); if (!(region_ok(rg))) return(snd_no_such_region_error(S_region_position, n)); if (Xen_is_integer(chan)) chn = Xen_integer_to_C_int(chan); if ((chn < 0) || (chn >= region_chans(rg))) return(snd_no_such_channel_error(S_region_position, Xen_list_1(n), chan)); r = id_to_region(rg); return(C_llong_to_Xen_llong(r->begs[chn])); } typedef enum {REGION_SRATE, REGION_CHANS, REGION_MAXAMP, REGION_FORGET, REGION_MAXAMP_POSITION, REGION_HOME} region_field_t; static Xen region_get(region_field_t field, Xen n, const char *caller) { int rg; rg = Xen_region_to_C_int(n); if (!(region_ok(rg))) return(snd_no_such_region_error(caller, n)); switch (field) { case REGION_SRATE: return(C_int_to_Xen_integer(region_srate(rg))); break; case REGION_CHANS: return(C_int_to_Xen_integer(region_chans(rg))); break; case REGION_MAXAMP: return(C_double_to_Xen_real(region_maxamp(rg))); break; case REGION_MAXAMP_POSITION: return(C_llong_to_Xen_llong(region_maxamp_position(rg))); break; case REGION_FORGET: delete_region_and_update_browser(region_id_to_list_position(rg)); return(n); break; case REGION_HOME: { region *r; r = id_to_region(rg); if (r) return(Xen_list_3(C_string_to_Xen_string(r->name), C_llong_to_Xen_llong(r->begs[0]), C_llong_to_Xen_llong(r->lens[0]))); } break; default: break; } return(Xen_false); } Xen g_region_srate(Xen n) { #define H_region_srate "(" S_region_srate " reg): region (nominal) srate" Xen_check_type(xen_is_region(n), n, 1, S_region_srate, "a region"); return(region_get(REGION_SRATE, n, S_region_srate)); } Xen g_region_chans(Xen n) { #define H_region_chans "(" S_region_chans " reg): region channels" Xen_check_type(xen_is_region(n), n, 1, S_region_chans, "a region"); return(region_get(REGION_CHANS, n, S_region_chans)); } static Xen g_region_home(Xen n) { #define H_region_home "(" S_region_home " reg): a list with the region source sound name and position info" Xen_check_type(xen_is_region(n), n, 1, S_region_home, "a region"); return(region_get(REGION_HOME, n, S_region_home)); } Xen g_region_maxamp(Xen n) { #define H_region_maxamp "(" S_region_maxamp " reg): region maxamp" Xen_check_type(xen_is_region(n), n, 1, S_region_maxamp, "a region"); return(region_get(REGION_MAXAMP, n, S_region_maxamp)); } static Xen g_region_maxamp_position(Xen n) { #define H_region_maxamp_position "(" S_region_maxamp_position " reg): first sample where region maxamp occurs" Xen_check_type(xen_is_region(n), n, 1, S_region_maxamp_position, "a region"); return(region_get(REGION_MAXAMP_POSITION, n, S_region_maxamp_position)); } static Xen g_forget_region(Xen n) { #define H_forget_region "(" S_forget_region " reg): remove region from the region list" Xen_check_type(xen_is_region(n), n, 1, S_forget_region, "a region"); return(region_get(REGION_FORGET, n, S_forget_region)); } Xen g_play_region(Xen n, play_process_t back, Xen stop_proc) { int rg; region *r; rg = Xen_region_to_C_int(n); r = id_to_region(rg); if (r) { make_region_readable(r); play_region_1(rg, back, stop_proc); return(n); } return(snd_no_such_region_error(S_play, n)); } static Xen g_regions(void) { #define H_regions "(" S_regions "): current active regions (a list of region ids)" int i; Xen result; result = Xen_empty_list; for (i = (regions_size - 1); i >= 0; i--) if (regions[i]) result = Xen_cons(C_int_to_Xen_region(regions[i]->id), result); return(result); } static Xen g_make_region(Xen beg, Xen end, Xen snd_n, Xen chn_n) { #define H_make_region "(" S_make_region " :optional beg end snd chn): make a new region between beg and end in snd. \ If chn is " PROC_TRUE ", all chans are included, taking the snd sync field into account if it's not 0. If no args are passed, the current \ selection is used." int id = INVALID_REGION; if (max_regions(ss) <= 0) return(Xen_false); if (!Xen_is_bound(beg)) id = make_region_from_selection(); else { sync_info *si = NULL; snd_info *sp; mus_long_t ibeg, iend; mus_long_t *ends = NULL; int i; Xen_check_type(Xen_is_integer(beg), beg, 1, S_make_region, "an integer"); Xen_check_type(Xen_is_integer(end), end, 2, S_make_region, "an integer"); ibeg = beg_to_sample(beg, S_make_region); iend = beg_to_sample(end, S_make_region); if (Xen_is_true(chn_n)) { /* all chans and all sync'd chans if sync not 0 */ sp = get_sp(snd_n); if (sp) { int old_sync; old_sync = sp->sync; if (sp->sync == 0) { /* set up temp sync for snd_sync */ sp->sync = ss->sound_sync_max + 1; ss->sound_sync_max++; } si = snd_sync(sp->sync); sp->sync = old_sync; } else return(snd_no_such_sound_error(S_make_region, snd_n)); } else { chan_info *cp; cp = get_cp(snd_n, chn_n, S_make_region); si = make_simple_sync(cp, ibeg); } ends = (mus_long_t *)calloc(si->chans, sizeof(mus_long_t)); for (i = 0; i < si->chans; i++) { if (current_samples(si->cps[i]) - 1 < iend) ends[i] = current_samples(si->cps[i]) - 1; else ends[i] = iend; si->begs[i] = ibeg; if (ends[i] < ibeg) { free(ends); ends = NULL; si = free_sync_info(si); Xen_out_of_range_error(S_make_region, 1, end, "end < beg?"); } } if (ends) { id = define_region(si, ends); if (selection_creates_region(ss)) reactivate_selection(si->cps[0], si->begs[0], ends[0]); si = free_sync_info(si); free(ends); } } return(C_int_to_Xen_region(id)); } static Xen kw_header_type, kw_comment, kw_file, kw_sample_type; static void init_region_keywords(void) { kw_header_type = Xen_make_keyword("header-type"); kw_sample_type = Xen_make_keyword("sample-type"); kw_comment = Xen_make_keyword("comment"); kw_file = Xen_make_keyword("file"); } static void save_region_to_xen_error(const char *msg, void *data) { redirect_snd_error_to(NULL, NULL); Xen_error(CANNOT_SAVE, Xen_list_2(C_string_to_Xen_string(S_save_region ": can't save ~S"), C_string_to_Xen_string(msg))); } static Xen g_save_region(Xen n, Xen arg1, Xen arg2, Xen arg3, Xen arg4, Xen arg5, Xen arg6, Xen arg7, Xen arg8) { #define H_save_region "(" S_save_region " region file sample-type header-type comment): save region in file \ using sample-type (default depends on machine byte order), header-type (" S_mus_next "), and comment" char *name = NULL; const char *file = NULL, *com = NULL; int rg; mus_sample_t sample_type = MUS_OUT_SAMPLE_TYPE; mus_header_t header_type = MUS_NEXT; Xen args[8]; Xen keys[4]; int orig_arg[4] = {0, 0, 0, 0}; int vals; keys[0] = kw_file; keys[1] = kw_sample_type; keys[2] = kw_header_type; keys[3] = kw_comment; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; args[6] = arg7; args[7] = arg8; Xen_check_type(xen_is_region(n), n, 1, S_save_region, "a region id"); rg = Xen_region_to_C_int(n); if (!(region_ok(rg))) return(snd_no_such_region_error(S_save_region, n)); vals = mus_optkey_unscramble(S_save_region, 4, keys, args, orig_arg); if (vals > 0) { file = mus_optkey_to_string(keys[0], S_save_region, orig_arg[0], NULL); sample_type = (mus_sample_t)mus_optkey_to_int(keys[1], S_save_region, orig_arg[1], (int)sample_type); header_type = (mus_header_t)mus_optkey_to_int(keys[2], S_save_region, orig_arg[2], (int)header_type); com = mus_optkey_to_string(keys[3], S_save_region, orig_arg[3], NULL); } if (file == NULL) Xen_error(Xen_make_error_type("IO-error"), Xen_list_1(C_string_to_Xen_string(S_save_region ": no output file?"))); name = mus_expand_filename(file); if (!(mus_header_writable(header_type, sample_type))) { if (mus_header_writable(MUS_NEXT, sample_type)) header_type = MUS_NEXT; else { if (mus_header_writable(MUS_RIFF, sample_type)) header_type = MUS_RIFF; else header_type = MUS_RAW; } } redirect_snd_error_to(save_region_to_xen_error, NULL); /* could perhaps pass name here for free in case of error */ save_region(rg, name, sample_type, header_type, com); redirect_snd_error_to(NULL, NULL); if (name) free(name); return(args[orig_arg[0] - 1]); /* -> filename, parallel save-selection */ } static Xen g_mix_region(Xen reg_n, Xen chn_samp_n, Xen snd_n, Xen chn_n, Xen reg_chn) { #define H_mix_region "(" S_mix_region " region :optional (chn-samp 0) snd chn (region-chan " PROC_TRUE ")): \ mix region's channel region-chan (or all chans if region-chan is " PROC_TRUE ") into snd's channel chn starting at chn-samp; \ it returns a list of the new mixes" chan_info *cp; mus_long_t samp; io_error_t err = IO_NO_ERROR; int i, rg, id = -1, reg_chan = 0, reg_chans = 0; Xen result = Xen_empty_list; Xen_check_type(xen_is_region(reg_n), reg_n, 1, S_mix_region, "a region"); Xen_check_type(Xen_is_integer_or_unbound(chn_samp_n), chn_samp_n, 2, S_mix_region, "an integer"); Xen_check_type(Xen_is_integer_boolean_or_unbound(reg_chn), reg_chn, 5, S_mix_region, "an integer or " PROC_TRUE); Snd_assert_channel(S_mix_region, snd_n, chn_n, 3); rg = Xen_region_to_C_int(reg_n); if (!(region_ok(rg))) return(snd_no_such_region_error(S_mix_region, reg_n)); cp = get_cp(snd_n, chn_n, S_mix_region); if (!cp) return(Xen_false); if (Xen_is_bound(chn_samp_n)) samp = beg_to_sample(chn_samp_n, S_mix_region); else samp = cursor_sample(cp); if (Xen_is_integer(reg_chn)) reg_chan = Xen_integer_to_C_int(reg_chn); id = paste_region_1(rg, cp, true, samp, &err, reg_chan, ®_chans); /* id might legitmately be invalid mix id if with_mix_tags is #f or virtual mix not ok */ if (is_serious_io_error(err)) Xen_error(Xen_make_error_type("IO-error"), Xen_list_2(C_string_to_Xen_string(S_mix_region ": can't edit, ~A"), C_string_to_Xen_string(io_error_name(err)))); if (id == -1) return(Xen_false); for (i = 0; i < reg_chans; i++) result = Xen_cons(new_xen_mix(id + i), result); return(Xen_list_reverse(result)); } static Xen g_region_sample(Xen reg_n, Xen samp_n, Xen chn_n) { #define H_region_sample "(" S_region_sample " region samp :optional (chan 0)): region's sample at samp in chan" int rg, chan = 0; mus_long_t samp; Xen_check_type(xen_is_region(reg_n), reg_n, 1, S_region_sample, "a region"); Xen_check_type(Xen_is_integer(samp_n), samp_n, 2, S_region_sample, "an integer"); Xen_check_type(Xen_is_integer_or_unbound(chn_n), chn_n, 3, S_region_sample, "an integer"); if (Xen_is_integer(chn_n)) chan = Xen_integer_to_C_int(chn_n); rg = Xen_region_to_C_int(reg_n); if (!(region_ok(rg))) return(snd_no_such_region_error(S_region_sample, reg_n)); samp = beg_to_sample(samp_n, S_region_sample); if ((chan >= 0) && (chan < region_chans(rg))) return(C_double_to_Xen_real(region_sample(rg, chan, samp))); return(snd_no_such_channel_error(S_region_sample, Xen_list_1(reg_n), chn_n)); } Xen g_region_to_vct(Xen reg_n, Xen beg_n, Xen num, Xen chn_n, Xen v) { #define H_region_to_vct "(" S_region_to_vct " region :optional (beg 0) samps (chan 0) v): \ write region's samples starting at beg for samps in channel chan to " S_vct " v; return v (or create a new one)" int reg, chn = 0; mus_long_t len = 0; vct *v1 = xen_to_vct(v); Xen_check_type(xen_is_region(reg_n), reg_n, 1, S_region_to_vct, "a region"); Xen_check_type(Xen_is_integer_or_unbound(beg_n), beg_n, 2, S_region_to_vct, "an integer"); Xen_check_type(Xen_is_integer_or_unbound(num), num, 3, S_region_to_vct, "an integer"); Xen_check_type(Xen_is_integer_or_unbound(chn_n), chn_n, 4, S_region_to_vct, "an integer"); reg = Xen_region_to_C_int(reg_n); if (!(region_ok(reg))) return(snd_no_such_region_error(S_region_to_vct, reg_n)); if (Xen_is_integer(chn_n)) { chn = Xen_integer_to_C_int(chn_n); if ((chn < 0) || (chn >= region_chans(reg))) return(snd_no_such_channel_error(S_region_to_vct, Xen_list_1(reg_n), chn_n)); } if (Xen_is_integer(num)) { len = Xen_llong_to_C_llong(num); if (len < 0) Xen_out_of_range_error(S_region_to_vct, 2, num, "length < 0?"); } if ((len == 0) || (len > region_len(reg))) len = region_len(reg); if (len > 0) { mus_float_t *data; mus_long_t beg; beg = beg_to_sample(beg_n, S_region_to_vct); if (beg >= region_len(reg)) return(Xen_false); if (v1) { data = mus_vct_data(v1); if (len > mus_vct_length(v1)) len = mus_vct_length(v1); } else { if ((beg + len) > region_len(reg)) len = region_len(reg) - beg; data = (mus_float_t *)calloc(len, sizeof(mus_float_t)); } region_samples(reg, chn, beg, len, data); if (v1) return(v); else return(xen_make_vct(len, data)); } return(Xen_false); } static Xen g_region_graph_style(void) {return(C_int_to_Xen_integer(region_graph_style(ss)));} static Xen g_set_region_graph_style(Xen val) { int style; #define H_region_graph_style "(" S_region_graph_style "): graph style of the region dialog graph. \ The " S_region_graph_style " choices are " S_graph_lines ", " S_graph_dots ", " S_graph_filled ", " S_graph_lollipops ", \ and " S_graph_dots_and_lines "." Xen_check_type(Xen_is_integer(val), val, 1, S_set S_region_graph_style, "an integer"); style = Xen_integer_to_C_int(val); if (!is_graph_style(style)) Xen_out_of_range_error(S_set S_region_graph_style, 1, val, "unknown " S_lisp_graph_style); set_region_graph_style((graph_style_t)style); reflect_region_graph_style(); return(val); } Xen_wrap_any_args(g_restore_region_w, g_restore_region) Xen_wrap_4_optional_args(g_insert_region_w, g_insert_region) Xen_wrap_no_args(g_regions_w, g_regions) Xen_wrap_2_optional_args(g_region_framples_w, g_region_framples) Xen_wrap_2_optional_args(g_region_position_w, g_region_position) Xen_wrap_1_arg(g_region_srate_w, g_region_srate) Xen_wrap_1_arg(g_region_chans_w, g_region_chans) Xen_wrap_1_arg(g_region_home_w, g_region_home) Xen_wrap_1_arg(g_region_maxamp_w, g_region_maxamp) Xen_wrap_1_arg(g_region_maxamp_position_w, g_region_maxamp_position) Xen_wrap_9_optional_args(g_save_region_w, g_save_region) Xen_wrap_1_arg(g_forget_region_w, g_forget_region) Xen_wrap_4_optional_args(g_make_region_w, g_make_region) Xen_wrap_5_optional_args(g_mix_region_w, g_mix_region) Xen_wrap_3_optional_args(g_region_sample_w, g_region_sample) Xen_wrap_5_optional_args(g_region_to_vct_w, g_region_to_vct) Xen_wrap_1_arg(g_is_region_w, g_is_region) Xen_wrap_no_args(g_max_regions_w, g_max_regions) Xen_wrap_1_arg(g_set_max_regions_w, g_set_max_regions) Xen_wrap_no_args(g_region_graph_style_w, g_region_graph_style) Xen_wrap_1_arg(g_set_region_graph_style_w, g_set_region_graph_style) Xen_wrap_1_arg(g_integer_to_region_w, g_integer_to_region) Xen_wrap_1_arg(g_region_to_integer_w, g_region_to_integer) #if HAVE_SCHEME static s7_pointer acc_region_graph_style(s7_scheme *sc, s7_pointer args) {return(g_set_region_graph_style(s7_cadr(args)));} static s7_pointer acc_max_regions(s7_scheme *sc, s7_pointer args) {return(g_set_max_regions(s7_cadr(args)));} #endif void g_init_regions(void) { init_xen_region(); init_region_keywords(); Xen_define_procedure(S_restore_region, g_restore_region_w, 0, 0, 1, "internal func used in save-state, restores a region"); Xen_define_procedure(S_insert_region, g_insert_region_w, 2, 2, 0, H_insert_region); Xen_define_safe_procedure(S_regions, g_regions_w, 0, 0, 0, H_regions); Xen_define_safe_procedure(S_region_framples, g_region_framples_w, 1, 1, 0, H_region_framples); Xen_define_safe_procedure(S_region_position, g_region_position_w, 1, 1, 0, H_region_position); Xen_define_safe_procedure(S_region_srate, g_region_srate_w, 1, 0, 0, H_region_srate); Xen_define_safe_procedure(S_region_chans, g_region_chans_w, 1, 0, 0, H_region_chans); Xen_define_safe_procedure(S_region_home, g_region_home_w, 1, 0, 0, H_region_home); Xen_define_safe_procedure(S_region_maxamp, g_region_maxamp_w, 1, 0, 0, H_region_maxamp); Xen_define_safe_procedure(S_region_maxamp_position, g_region_maxamp_position_w, 1, 0, 0, H_region_maxamp_position); Xen_define_procedure(S_save_region, g_save_region_w, 2, 7, 0, H_save_region); Xen_define_procedure(S_forget_region, g_forget_region_w, 1, 0, 0, H_forget_region); Xen_define_procedure(S_make_region, g_make_region_w, 0, 4, 0, H_make_region); Xen_define_procedure(S_mix_region, g_mix_region_w, 1, 4, 0, H_mix_region); Xen_define_safe_procedure(S_region_sample, g_region_sample_w, 2, 1, 0, H_region_sample); Xen_define_safe_procedure(S_region_to_vct, g_region_to_vct_w, 1, 4, 0, H_region_to_vct); Xen_define_safe_procedure(S_is_region, g_is_region_w, 1, 0, 0, H_is_region); Xen_define_safe_procedure(S_integer_to_region, g_integer_to_region_w, 1, 0, 0, H_integer_to_region); Xen_define_safe_procedure(S_region_to_integer, g_region_to_integer_w, 1, 0, 0, H_region_to_integer); Xen_define_dilambda(S_max_regions, g_max_regions_w, H_max_regions, S_set S_max_regions, g_set_max_regions_w, 0, 0, 1, 0); Xen_define_dilambda(S_region_graph_style, g_region_graph_style_w, H_region_graph_style, S_set S_region_graph_style, g_set_region_graph_style_w, 0, 0, 1, 0); #if HAVE_SCHEME s7_symbol_set_access(s7, ss->max_regions_symbol, s7_make_function(s7, "[acc-" S_max_regions "]", acc_max_regions, 2, 0, false, "accessor")); s7_symbol_set_access(s7, ss->region_graph_style_symbol, s7_make_function(s7, "[acc-" S_region_graph_style "]", acc_region_graph_style, 2, 0, false, "accessor")); s7_symbol_set_documentation(s7, ss->max_regions_symbol, "*max-regions*: max number of regions saved on the region list"); s7_symbol_set_documentation(s7, ss->region_graph_style_symbol, "*region-graph-style*: graph style of the region dialog graph (graph-lines etc)"); #endif }

D¦‘P5‚ÆAg!õ’ÖŤèw…Ö@ÍÁŠ(õþüeäâXHhÕ•ú]„qÖ¬G“ •˜"w®NY9$HÖÖ£Ó Ó¹o”LšŽN½‚\ $O½¢Ýù¸¡·ÅGALüP÷.õTÝù½'¥FWÍq LƒÌa¤^Bü G,`Ö £‘z¡cžàÄàäŽ ¨@êj¬¸Ž^zòHp j—’iÌèMÕ Éð¨pã·6¯Ô‹:;n €qô”zE.ḭlu1ª( õt¿uÑ]ï÷¤Þˆ!`Ì ¾F˜ Ž †N½N”Pd™ü©›ÚoMÿ6*è\©WV3Çô]”»Þ&]^gfuƆ$€þRïÏ_R½gSÐõ~ HàÞ=_Îækô”zŸéëJƒϤÂŽßéùõÛÞë0íS/ˆ`ý•zíŸÐ›`ú[ˆƒ¯àÎz@AìÈ/\êµö`˜ùS/‚#†–¡×™G õ"Ç@É`áyÀJ*õbugˆV‹u©k¿vnp%ºCNêm_ÚŒÁ€!&ÓÄ—¡aX'JÙÑŠq_µ”z J>ྖî@ê ¤^°B@x9ÀhÁÊ+õZ ¦ ëÂv5R/’ ÓK½˜*À`¢¤^‰¤&'"b½+`4&+œv!`X¿ÇOɪhü›šš4Ê;C¸©øjg®Â1õ`IÖ†·FÀ•Œy¤^@©—Ý{h£`” õ¶wÇAT¿‡[1¯¼÷Ô¡JR„¬ü~Ò¦^ ÷ê+ ƒèLÖS©Dz¡OÎ'uD®¾î]ÕÒ€¦•ÔK›!¨, È0ÔLüX$ï›æ™jr/ÅPêEð…¾w2_×éÈÇO\縩×2`Ö``“¡Œý¨Z¨~:ÝåI½PrŠ €Ý õÚbq5Gt†=X…o)òR/QeúCPSP'†¤^@"Ô€Rï=+Á;}“ó FCÃa{y´Ö©=šôñl¼êu°A……µ/žp@8vï€-H½PeÛ©°¹>ßH½ 8’y0kJ•ÁŽbSØ2ž2zæ¸)© è#@H½X<óW©)Û˜Cÿû]R/c eð#ô5‘Ûf©ë 6$Ú\{ùÓÈ4έ‚Z@/­š5ºI¥Q„©€¾¶š¡e¤ÞAG!Ö ÂP¤^ ï½;ˆqÚ¤^ÊÔSùi©—ä@ä•Û´6˜Ú©› ©k!åxê ¤^°’6`í[õ¨vWºlt1öZÝl¥Ô»Ñ¾1€<¤×ЭÜÍ öé BðD(¿R/Ö”ë,R/â‹ø€ô¬é¤Þ²!©NÀ2R¥ÍÆÆx3Vœõ‚ù‹Is$—Pm¤9»R—ŒÓÓ|Îz2/–œ„R/*> õ` õŠßƒ€•©µ úãðŶ»k¾ûj•©ÑÀª‡ÔÛÕ¢nB‚Xl"kF°Ï—z1t ÚR/ èþM#`{aóïß¿G“fÄöc$O½³EN¨So¹e»)Qø(ʦ@ïÛ¡¯Ï?œ{@¢È–lÊ×ÜÐÝ3Âg0xŒV¼› TpÈ©@G 71Aêz­p`Q Íkj£Ô‹¡ 0›¬¹R¯Š††UU ¤^;$àà|‹©¿ŽXq@êåR5QyoZ•q{*Ý4ÂG»$©€ü¤Þ¸6Îxœý¤ìV¸Õà¿gzI;‡åK@êÀ^ñÞ½7:©§!ª..&¥S'YÒÀÃŽ¨©Aê­s#‹ßZiá—Ï Z0Ç»yÂYä$.u·‘ps®zMijѹ`f¦C?kã5Fø$êVÓo£a‹l©Í 1M«ôòßN)²¶î¹ý+MôÚWlüh!¡àhòi3Á?â¦í…­5δ@ïÙ%Ǿ]¾|‹Ê¡o¹i¤5ÜÌHÆÑŽÌñ|·ªÓÓü‚eV~ÿ×f/ëPé÷ŸªYþá#ÁR1øøîý\ªí½÷>á£][“ëÙyˆu¨Ž©xÿÆx¦»tˆy=‡fÖΙxw×(ìùæ×ž—;g÷¼‰þã€öÈ/ £ùc;˜–Êé?G ànâ·l&.+÷{u½œ—ór^ÎËy9/çå¼Üû˽ÿ¯¥€ü®¦ÞÙ#íÞ÷@@{?Ãaù߯tû|E^zM½_³lGþ’¸/Ý»swîÎݹ;wçîÜÝÏõŸÔ €Ô ýó‘ ä笀ü _Ûç sÈDz‘OÎ}‰ÑSïûPóo[•sÈÑ|rîKÄ1µjïbö¼TË!{òɹ/ÊCk«ÂûÿÎN5Ö¾tt‰y×Í/õèeiÞ8½|bˆîÿ®Ù©Þò/̾ÑÉ_/‘©°*üù“/%äF6.cÀûè-Ÿ¢;¿ëk2žýg~¦9qø (“¿7žõšsÖ T ¯ÿÞóÈÄûóòK¯?Y>°ý¿^Æ¡¾"Ï{|ü¥ùòïìü ‡.ãh§ºå±o£¿¾vÈ H½À-iuÿ—ög‚µ¸L´ËïZ>zñ5Sn_ÆòŽ*?ï±vk¯x%r­}×ö}í`gSl €ëMzîƒåƒ _#ïv+ƒ¦Þß•Ìg|@XË#ÀåÙêÇÿÝŸlަÀ‚·vë¹øjåûº£ö6Gà¹!ºñ]{ºÉŠ–©ô­m³O| ©÷Ã"ª' `õ¯•öŸÆE+ËD•¦ ;à?·ÞËWñ=ÀÑ£_zÛË(²‘OÎ} ©×°VD_o{Ïú‰{>·kÙ_³î}ø$²q¶ôWöüFE|>Ã8“KîK]DÞ廬N·êşмµ?>ü{_E¨½~Ák}¡ïÃ"ón6àûr~ñ³¶~PxíN?u0˲ã9ûç^ëý)ÀÙ—±|Å;ÿè-¯õ×þ7¢}ý'nùÜ=ñ] µýkt Áºf »±±ãð„R/ôï?Ä!—+}V]IEND®B`‚snd-16.1/pix/ampenvspectrum.png0000644000076400007640000011534611147553266014736 0ustar bilbil‰PNG  IHDRÜ^R÷osRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ 3$ÑJm¦ IDATxÚì½wœdU÷ÿ>禺UÕº{zz¦'À3ÀŒ °* †U|@eWÁücw}vM(+bX\1¬â³îªKR×´"‚$QA†0Àà “cç*Þt~œªîêfF—eà¼_¯ûªÛ·nUWßê:Ÿú|¿ßó=B)¥0 ƒáDšK`0 # ƒÁ`0b0 # ƒÁ`0b0 ƒƒÁ`01žZüà›.› a0b0ž /üoû5œwÞ/ÌÅ01 Çüǃ|þów† ;vL21Q3Å`Ä`0<>µZÄ¥—þŽ8ÖÍ6næ·¿Ýg.ŒÁˆÁ`x|~üãGxôÑ‘–– bsa F@ Ù˜¨ñµ¯Ý3O<@rá…w™‹c0b0Ì 7låþûû±p3Œ€ †ý0>^åë_¿·ñS«pH# # ƒáÀÜtÓvî¹§wp´nƒƒÁ°€{îéãýï¿¡åÈ|éí­rË-½æBŒ€ †ù\vÙ=ŒW8¹ýr9fïÞ’¹P# ƒaŽûîëㆶ-p ÃW&b0b0¸{à>¬ñ°ÌÇÌ`Ä`0̱iÓ0ÿõ_x÷Ñ**ƒƒáO’(¾üå»)—Ãý¸±À}ØF@ F@ ƒfß¾).¿üÁçÑ*"Ö‚}“11 @+.¾øŽ–#­[EÃ2b0b0æèïŸæÛß~ åãs ÜG3|esÝucæÂŒ€ Ït>úÑ[Ç}Ø œ‡þù·¿2Î`Ä`x&óðÃCüô§8€û°öã>,ÀiÜ F@ †g,ŸÿüÔë1m–x Ü‡Ó²o01ž‘Ü{o7Þx Yçû»! ¶ƒƒá™Ì×¾¶žÉÉêyµÿЕN¢'‰`jʬLh0b0<ã¸çž>nºi{‹ó…îÃ$SSŠo|ÃTbž~Øæ Ïe—ÝÃØX•ÇÏ}4E£¹ï¶|¼Ì÷4ƒq Ã3޹öÚ-ã>,Îû˜æ$B›{ï Is= F@ †g _þòÝÌÌÔyâÊ+»åX3|¥fï»öÚ€(R悌€ Ïvíšäª«6>ûXXqe·ˆ ã­á,ƒÁˆÁð´&Ž>ûÙ;ö#ûsà1?¤5öÝY¹òJS‰e0b0<íéíá;ßyà ܇uîC ÈD&b0b0<ݹè¢_¤ûØ_øÊn9î56Á7¿Y£¿ßäA F@ †§-<2Ìw¿ûðA¸{žÃ˜/&M÷á5nu ” >n,ˆÁˆÁð´åŸþé’D¤û°"ñ8îC4žG8ìÜ+™˜4ר`Ä`xÚqß}­=¯&÷ÑZeå‚+¡É\hÞƒq Ã!Ç}[àUcjóïà>äÅC,¬Àr8G';|¡¬ká ­]HR‚Ë_ºÆ¼ã@ †C‚É |àØ[‡Í÷&Œä7\,W‡±¤– V#dåHðÄ\u¯Õ®tC@¦±U÷ûpÁíð«mæ½31žTÊ1|³ÎÜ ß†ìÖóM÷6ÄCÓA{Øz Ž»7i°á>\GÏï ‘Ø6¸R‡­šÓCššã͹ ↘ä¿.DçE2°q¼ö›ðŽëÍûixêcBX†Cš}!üõ ØÅ_Wà¼GôÀOïj Ú èfô1á)ïG ¨çÕãU^¹Z<\W‹†%tØÊí§h-p ×@¶!dcãm@ âaˆ³påxöXcÁI=uÌ{m0b0üÉüˆeHv†’÷×á´lhÄ厪@äà¶xB«] örV6&Þaé»êá»! þH÷áιéòµã°„~øÂb,»åiü†ó€¹ð•ƒžÒÙp#aãþ¬~ê¯Ü%ø›“à_žcÞ¼ùÍof``€ãŽ;Ž7¿ù͹ÿ˜cŽ¡P(1ÆH¨Q~­\> f8CͰgz÷x![¢iƆ;Ý Ë ñŒ…\‘l”ÐE2%uÞa= ܵ¡wü îÃÑ-IšùÇÒ‰r -"΂‡Y-"’j¸!·ÅqL1—XÏ{Î$§ÏÛ·è‚Â_NÁjV˜Rßg,7Ýt7Üpqó¡}ˆÇœóë_ÿšÉI½^À¿øE# †§?! 1¿§ÄoÙÅ«YÌWñø {x#\½„”Sáæ ÄæzB.W&Ôý¥œl¨E£^ºNµæCˆQ¥õ É^©ëðû{ ¨òÇÍ:o¸§¾’žKÌ_¤Õ,\2½ù‰kL$d¬!ņûP ñ(0—hÏÁ€€So‡œ×½ NÊšÿ™g"_úÒ—(—ËœrÊ)œqÆ&„exær+R¤ÊjžÍ?r? ðJŽç«¤XÄ6~N?ólV3Á‚µÔíˆÆè\FʯQ°'Ù=tÖ²˜Ôtéj¹"AìV'ï±ô` ó1¶÷ÁÞƒYï£YyÕì¬Û†€l1_$Z…ÄÞOL´ˆÉDÃ}d!¬Q "¯ j€Å 1©ëó§—ÁWf ¡,áuyóôLá¶ÛnãöÛuÉùÅ_ü”y]F@ v¦x„´ƒlOˆÇ,í>ÚAj›Ðçàgcð‹P+áʬâ[ÂüÃ=Ýzr饗†!gœqǼá‰R¿Gˆg¡©ðK2ÁR*î2öð1O^Ĩ<™ù'°„‡9]\Ãj¶ñ ¯¢Ä$Ïbškˆé`’›b³’>XÂj¶2A‘—#ÔÆâÒn…nÙQ=ÇÉË)vÌy•„(¶‘ù„hÌžO¡FÅœhˆ†€ôŽÀæ?À}ȸgÎ}4ÃWNC!\›ëXè>ìqi6íµ¿ºY™5>®rìxÆ‚Øùˆ¤&Q(‚hS¨^AØh‡rYÿÖoèR|0e„äéÊý÷ßÏ 7ÜÀ'>ñ ¤|ê̾0òŒþj3®G6§Ñv˜êƒâKPñ÷}×C÷ÿ¥–úO¼±ï!¼ÿ`*ûœêxÁùì(”Ér)rÔå®Å§Ó-ïe:ú¿t·q8}L³ž HV3ÀmìÂabŸXŽB°„a->U–0À8–5ÅL­Øµð²uªƒ>*¥Ëgãj#dÕ [H¡§¤ßyDÚ¼[;·±µ®%µ0le·8»%|ÕÔ¥¦^5ó"R¿V™OˆÊ¶>?v{D}»m`bD¢ˆj6,+³~\B Ø(2Ô9:ʱÂN8ÜLïzÚP«ÕøÂ¾À™gžÉÚµkŸR¯ÏÈ¡ÈàȶC&[À.BW7Œï†R ˃õ_ƒîSaÉxàã°5†7\;ÿN»êÃÆa8öè¼îØEÒq:êE¿Ã꟦¾½ŸÊ_TñFb¢ö6F×%¬œÞÇÔØŒå×°¬>É–ôjbk7Á¿ç<úX±É^GV”hƹÃ>‰EŒÐ ró—,b•†äb–¨²ªÄN¹Š£ØFPw R.ËT/Cj1‰%éf},‡¸vÀX¹²HIÛ:g4òitÎÀGW]‰†  NÂú‡öã>ºZà>Ü·mì?çѺ/[DF,“feVC<È‚²qY—‹¢Â-ÔâÀÏT© ¥  d1Á©†Ô†RØÝ85þq&fB(^šíççt3 AÚˆÉ!ÍC=ĵ×ê…cN>ùd.¼ð±½ÿÏ=÷\¤”d2V¬XaäP&©T¾B ªUD*BmÝŠ稣 R!xè!Ü¿Ú@õškñ?ý¨U¨~ðýxŸÿ ²ïQ¢ïü;ɛ߇퀛o¥´êed_z|äLÊÙ“Èüëà«ï¦¶ýhÜý,òGÿÉ-Éû_‡=ð=¸ÔéÇ#ß¿¬»6í×ëäí6PÝ÷ P0 Õçü¢ŠŒ?w™©2¢_1¸¶F±2A4cóÈ‘ké‰úp‡6/?šcùQÙ¦/×à µ—¶Ò ŸËs’̔ۘÈY—lb$ZDà¸,‰Q‚ã…,އØ®#ïO±4êg«½:y¦Ø(žCž)&e”¨aØ.ÂWD¡òõ2±TâA‹FÄMPpÃûV±ÙïZ­¹f½­1Ÿ¤5,%ˆ‰\°ßú+ZÝHó%¤AE‰ˆYðÚêÔG<È‚UŒñ¨Sªe¡2Ù2µ})¤Ÿàeë¤âã•vüb•1¦ù”²¹Q8œË8ã(¦‰È›ú!GEüó?ÿ3oxÃ8ï¼ó°íǾW^y%q³téÒ']@Ìד?å%@Å1Ó7߬?ú(ƒçœCR­B0qÖY¨jÝDò¦ÿ…€Zþú ÔØ(ñ…ïeâç?E•§Qó Ê?ù * á«ï&úñH†{áÆ/Ã~ŸÉý˜äÛg“ì¦òëˆy1I?Dm†kÎDíé)ìÁïéžOí ÖÝ{ØšûPûôÅ1À.PÔ±vA˜rÝ ±[Q<â‹Ô@ɤÈNQIa»‹*ÃUj¤hc:Ž I¹5ÝÈ´•©y¨ŒÀo«RP“$B’õKtÊQvÕÇŒR¥Ä¿`q Ù ױIḟúà£ý(¯|å+yéK_ú”|F@‚ÚÎXY={+ع“ÒÝwcut P¿óNr¯zÉöíD6ý«¿‚}{Q·ÿï½ï…½;á{o};b´Ÿèúÿ‚÷ýèÝFxÝ(ù‹)üÅ Inÿ!å™ ™×ž ¿û9q©€|þ‘ˆ«ÿúRÄ/\KnÑ4Œd±O9¯{z]’Շ㬆|Ôዱöº°|9b-ÐçÁñGÃJ`¯Êæáh`ŸCØ&Ý@¿íX«c䞘ÀOá, ñÇ#Âlj¥ 0>ɨÌc-Šé,PžLÓÆ ‹fF]x^ÎÒ({ÛVcš%áÎ\' OЛZF‘ –0@n)y¦$L“£À$’„qÑNž) IBž)\ÒTÈ3…O•Œ(“•%Ò¢‚oWI¹5ìT„í7¶T„hS³´ØÛwnyi’ÇË}ØÏÆÎ%$y97øçö#m‘Ìiu'éAi6al<¥š†4Xù˜.k˜ÁJ72—Pð'‰ê6ãÒnÓ-™ HÑš`1Cìà$Œ²™AÞÇv¾Ëlb2ζš÷S”[n¹…»ï¾›l6Ë?øÁ§ìë4у@þêÕ ]z)é¿é8ŒÿË¿9ûlœžªÿ8öË_Ž}Ì1$Ÿø8ⵯG®] }^ú X÷,Ôg?ÈädDçºçÁÿò® ì×¼‹ô–ßì«!Ž{-îÈzÔöi8æµXÕ ·KŽÇ[2 ÷„Px"yÆøGÒv’‡œ#°WO鯬ÀzýrÙ¬„®}0Ét'ñª Ñrœ¿†‰TÃIöX„šl‡ç‡øÕ1 ¨¼°@{4€³3 ~LíŒãìY¾œEŒ(±e…MyaéöŒÒÍð‡EÇÒÁŽ8.E&(“AÊ„‚~¡¤¨‘¡L„M3H\²”(êxºŒ¨‘Â&"AR#E`»ÄXXIŒ²±°-‡ &X2&ú;¡±ÿ²]Écç|,œ÷1—ÿ°|pÚC¢£ôH(yì<«%÷!äBä‚\H³Ì7i„µlH,=‹ÞÍ”ªYbß"•«Ñ.ÇÙEÚ«°HŽ0ž´“²kt‹Al"&)°‚½t3È^VS¦q~ÍNa†eJrå·¨ù=ä{6⻟!ªI¿ñ ˆ«ßƒ*w`?kbçÕ0–…ÿý¿àÑÁxœz2Ä?‡±4<÷$Ää7õ9«G¤n…½¬|Tî@í±lÈ»`ˆÔJÜîFN¤} 23¡÷ã ÒÛ ½ *ìl„ЍO€íí#5]#¶-¼Ž¶z‰¤da­"#T3>)§FŽi¢¬MÊ®‘¥Ähº“4ÒT(‹ 9¦IQ£ŒÞ·‰¨&Ï1e2:‘Tñ±‰¨Æ£NŒ…CHŠ1u´€Ô…GdÙ„–ƒ ©,=<@tÇ΃_=‘ûp®×`·GºñaÜ›ýW[Ù Ò+Î~„–_ ó«´šeÈÖÜ~äÛL– ˆ6EΛ¦¥(»–ºý, G¸Û;‘¢œ §1¯¦Y"gŠ>z8šÍt1Ì#ašlâVnc7ÏaÅ{ˆÉ“Â&…é—ò?Å7ÞÈ}÷ÝG:æˆ#Ž`ãÆ9çðÃ'—Ë9”é4o{vG“·ßŽÿ—‰½t)n­†|ë[±?œñ邏àÈ#©}ô|‚5ÏÆ^¶õ™O234Eú¼wÀ×.¡6ãó&ü‡î&Ù;…õ’7áí»†@÷JÄÚ#P·MŠ“¹ CäŽÝ™À[`Ñ‹!_…í€XíìÞG2ÒŽ\W…Á!¢`>‚bU;I`'pâ L6$¿Y·Ö赸Š5 €{„Ä*×±G"¢Ãl r ·P9&MAMRP“ŒötR`’ e&¼"팓¦Â:yî’ g“ä ‡p6LåQoŒ£1öìý6161ö¬¸ÔñtE.5‘Ò‚£ÏI,[2þ­ûQS5®abËÄAkAÙ®kcù*ÔHÚu£FhÑœ…3ЊÈB½’-ç5/P([ÌŠ‰JÏoQ „B¤‘´ŽÂNEÅ{YAÊ«Ñ!Æ(YYbaÑÅ0]Á0w¹/¡“Qº£AvÛ‡Qd‚¥ôc1F+ÙC'£ÜÄ ÈR£—\Å=äyc¼œó©ã"°gÿ`ÓÁ¥—^J¹\æÔSOå _øÂlo+×]wSSºBñóŸÿ<–e9°;;õ·»ç=, EÌ ÓuÎ9Äå2•½{É~ò“$Õ*£ßú6™O~’dr’ê/EuÅQ,:ë,ê¯<™ZÏ*¬uÏ"øÂ÷éå¸o{òŸ u°ß|6âª@tâ±øë¯ƒ}œøìõ?Ñ-Ê_q,b×mºÚªs9ìø% C}_è!˜€xX«oC8À¤w@‡¯¦‰;çæH,†€ X+a}\¶%ȉB™oªŽŒl‘«MãÈ߭⩺=I—4$ ¡rPBè*¯Æ– õ@‰ ÂÆ!œ‡¦Ð4E Â&žuMш±¨ãÍwv¿ŽG$m¦î›!ºuϸ{ÿîÃ}lénª­NªXczQrzPW%k¥LP¶Ð?Û UBâȹ¥Ñ‰I,©Â)„Pú˜«Ë¥JÀ‚ØÕ” ÒJ@éù!¶¡”@z ž]gœv°!/¦(0É€½„“,IØÌѸÎ. Á$wÛ'²Š,KzÙ#Vâ‹*Ë襊O™ G².†¹•ÃIÓ‡à>62½H^BÇò/À2Äìu4üwqë­·r×]w!„ࢋ."›ÍòÖ·¾Õ„°žnxG € Cò¯~5VGao/þ«_»n“×^Káÿדּ¨Þy'Ããt^|1ÁC¡Výæ¿B=ø Õ]ä.ü[äø(áí÷3Óµ ÿªïúÝ£”g@îØ‰¿e#ÉXò6ðzQÃÀö]0ºF€m¿€µÀønö–aR«Ð}–F· £U½>w®!"•Æø9Žž|géç ÖOÇHÿ—ˆ …¸à‰:*WѦy á+ ÛŠˆ¤ $Z...E>U$u<ÒTˆ±qæ BÔ¬h´oî7‡8sûÂaðë ™¨?û°ì>Z6Û‡L¡LªXc¢«i°EDìX$žÔ«„ȳ¶ÂŽ#G꟥ÂN"zÊX*ÆŽ#”%|e Ü0@ЄĒ$–Ä’1¶ŠJ –Œµ;“!¾¨a㊀Z_Ìînr¯y HIî5¯AD"f²T"}Þyø'ŸÌèç?ÿª×PxÇ;yË[PG?ïøRú§Ï`å{èÛµ‡•SãÈl7µáa²¿º…ºñ4¸}½Äc îüä@M‚Xô£×¼(6öK@»EQEÇí›û´©¡Ã1ª! ¹Fl¿¹ÄjÔØ2 5»«¬éoÆøzKÆØNDZVô@çI|·ŠR‚P8øTA@%I“R5”Bô­âcéäø~Ä¡yÛ<Þ<ÖºßÜF7ÆLÿ¬ÿ rXmб煯ü\•t¾‚Ó"‹ ¤Á ëÔS‰/±“H»ŒŒÜ @HE5ã£XIŒã†ÔÒ)ì8‹êH‘ຑmãØ!®ÒâšX)„ÒùG†H$®ð¨âà’¡LˆCž)ŠL0ä,Æ¡žc#Kl÷ŽÔÂöÓ÷à‰:=ªL¹ÌÎÜ*Ö°…žxÛÄIt‰!–ÇÚ™ÌXm˰’˜­r;Ë™$þšmÕ TópLý¹(ïÓ„<@ŠÓÍ ðg`ýúõÜܘSö©O}êЈȘ·íÿ áÌ­5*lgéR‚ð<ðt³#«½Ü©§be2xÇKæ´Ó°ÚÛɾå-• ¢£ÿMo&عÓ&föîB¼øÅ¨ÍÛ(ÿþ~’D ¹ˆ*`×ÀwÉ´Òá%DÃ-(bйÕí&Ð=ºB+iˆÄD‹pL6öæ&hW[þ;ÚZö³Ì%z³è0‹¶aÙ±Žç§µSQBPU¾þ†n$ÁU]YäJb¡ÃWU|BBåP#E¨"©s­âÐ*­‚Ѿ ‡_ž!®$á>ö³Þ‡ë€;·l­V¤óü|:Bœ»!í„$# ñ* IDAT'ñ‚:6*#ˆ<›Tµ† –¤\<«Ž([àÙupÀœ8ÔV¤­ÿB),#Iôq‘àјò‰K0'&+Г6f¨ˆ49¦igœ1Ñ/ªt2J.šæ‘üZ=Á³2Ä–x5YJ,gcA;¡k³œ^ 3“lÌ>‡% °$`ŸZŽpÝñ ÓÕ6¶µµst°kèl_´‚³•Ôôy$ío„hÒz¥^+ÞðGQ«Õ¸ä’K8묳žr=¯Œ€üR8õTd: BP|Ç;°‹ET’~Ó›pFF¹ö;߉ں•¥–Åà§>…sî»hëïgò¢O052‚_L‘ï^Lµ¯·Ý#½j9Ñž>dΡ\ê#ÛÙC82H<"c°X$ , D¥ñb¬FèªÙN¼Ä\Ò·yŽƒu57÷›ç7#?3 ,¥¿¼§Ôì~³ül+Â’1Ê8nˆ²2• lE¬,ꉇDž C%–D í^š"1+ª1l w^¸«™Üå±ãªàpnKîÞ?ãÜqðÛ´ûð UêN6ÄÎéYñX¶9¸õ€tTÁñBª¾OJÔðâ:‘£+Ãl? ëH™K I¢CÆ:‚Â"FBçL,âÙB›…@’̆<ê1)jxÔg šÕo&éd”i?Gš ‹«ÖÏwÐÅ0Ýjšû½µt0Î2©…9FíNN`=éR…¹#X<ÎFû9¤U…öÒ8“±¤äŽÓ==‰ÚüIÆWýˆbêaùêÈ3õª.îð:Ìp\|ñÅüüç? »»›‡zè1çwÜqO©N¼F@ž$¬–r»f^¢XÄ+gïKwI¹Lû»ßwÒIÄ¿ú™·œM}÷nòÝÝÈbkûv¼e=°t1bÛ.[1zÅ7ñN|Ó7^C©F—Œ„¤,5% N cAU@£|…š¡ô ¯¦¯+Å\k ¯±5»Ç¦ãoóøþö}}¾ðŽÎ)ÏuE\²ˆ…E¢$~R%±$±m‘uJº‹ˆ­f£¦RTŸPiGY6±°æ9‘)ªQŠ_|6ÏüZ؃qØ “ç6¶¯ÝGº ·¨Ã&®øú5[2&q%¾¬’ ʤœi«‚› HE5°´ B!ÝGÍUŸI„TóDB’44>ž-=XxÜ"~Œ˜è·OW³¥¨‘¦2[Ý“ÑÎ8Œ2•É“rjt3HYŽË vÓQ™äâñ,fˆÃØÇ®àpRV¥Õ~˜„‰•EÖÌl!;\bÓâudÃÞPÑŽ<µÅ£tìHP^Iµëßð÷"ìË '­×_é|/3oyìÚµ‹«¯¾€7¾ñüÝßý?üðcÎûéOJǬZµŠóÎ;ψa?HIÛÉ'#loÝ:œž¬ÉIüînd‘Ç[±,‰=<Âøon£²äHÊëžOé†[‘v;aµB*W –’¤VEtu@Ú±i8b ä\¢{¨Œ÷AY»Ûaë5’ìæ|ºf§X—¹î±M¡h·Çî7ΗN¢{Ì[à[‡¿bÙÚ¡H_¬ÒJHI-NQ‹SXQ¬+¶, e „¥æ%͛ӻ;˽—wþiîc^ÞCÏûHµÕµxä*xÅ:n! çM#|E&.ã«*® ­„¬(iÁ@è¿‹KÄóÜ…úïkuÍÍ"žI2ïøÂswÑi‚Û¨b¨ÙÒhŸê¬˜4gò “~Æèb˜°ƒ¼3Iwr1ì^¼ŠµÅ3à ÑM{2NçÌ(Ó¥Á.Ý#ƒ0ãÏjgIi±KQÎëüÍ Bmþ(êÜ#‘÷<,ï‡V¤IÒyÆä/¿üröîÝ‹eYœþù¬Y³†5kÖ<æ¼7½éM&„exýð}ð}ýæôô@On«›i=wÉRÜ‘º>|>ޱǒ=ó,T­†W­’*¡^Ç äŠ%DD°º’ˆš7S×_ƒ”sËtËFåéìøj¾G+P•`ƒJ7Æ^ ¤Ûò˜TËØìíGXçH;A9Ï«kÇá)DM陫+¶¬$ÆJ|§ .Ø™©t™p9ÎP ÓÔ⾪òµ\zñ8˜Ê+w^å•åCºP!“/“)”qÛd1a‘5BJÖÈxeRªFF”u2Ü °D<'V2ë,ZÅ¡é8šÇš?·:“…¢1÷Þdzn¤éLšn¤9ÇÆ"Æ% nü§4«ÛÒTÈRšm“¥¤“–,b„ÅÁ}…et0Æ’h€=cY²‹§Y–ôb6#ź£AŠ•í‹—¦Èö—˜ñÛp³Þ£uèKS=˧}`vBô’:öÈFØÜý^x=p/póðº#aýïàì›õõ†²}ûv¾÷½ïðªW½ŠN8ázýF@qÒÏ{þsŸ‹Üw¿›¸Rzt;yÛ†®¨Õô ÙÕ õ㿺J-ˆ#|ËÆsT^5Û–8µðs52…òløÊiɧ¦ÈŠYJXvLF•¢á¤Â:í¿p o:ŽVg±P,Þ×*4ú/Ró¶ædL…˜}Žæ$L‹xž˜DØi*DØd(϶ŠigœÓÔ|½|cÃä*ÓléZÃ"Fè˜e2·‚T®Æ’ò ±]$ZfÓ9<‚[J–Oaf{/”Öu“•ýÈ„6É‘q¯‚ÀûÑ“^÷â‡úØzà÷¯…çn…Myxßµz-›gW_}5;wî$“Éð¡}è{ýF@q쎖$e{;ŽR tK’„Ð#}¢ôH/%(E”ï óº3PÕ*i×ÅM§¡^ÇòȺzå¾BºrÄPlcêÖ›(‚'ôf °cæz8y Çâ È9µQ® J*('ÑÂc7¢N‹Ci½õ@¸ ˉuÞ "ýD»”’œØ²‘NÛVD:UáŠ/G‰ƒtûÉ}´„¯š•Wé¼v é|QTx^61ƒPzàöe‡PçXBØMÑPJ»KÄ󄤙¸"yLèª)J‰YGÓ*,sÜhöÜf’½Õ±4«´š3üFM[ˆƒEŒO•‡,%Ú˜!Æ¢È& 3mb†"Ø3!¥b.5Iv¼ÌhÇŠÉ8…éÉŠ"©b[ô¬Ä¨ÃHäÕg|¶«Ñ•Û yºÂnà¿ÔU€÷‡] ño ~:üÝ×à‘›aÕ‰)<-?»{÷îåŠ+®àe/{¯xÅ+Œ€þgó'¾¯e_Ÿ{.T«¨Z G)¬$z‰Òãl¬EƒLJ?¦gø«—“Œ ”´ÂÂEh5ȸ`[õ!ïAƆ%y(dˆJ“Ì<¼Ë§¡-³‹0y-[3¿’(O— é‰YWÓ’¬·e¤]LJ±áÁÅÜ~Dz?Á}´æ>æÜGª­6+ MI2’|2EÎÖ}¼¢Ø&åÔHQÓ³èc‰H)»Ö˜C¯’J–ãÊ9aJǨ¹*µÖ¼ˆJqb!E‚-£ÙÜɬ€$Z€KÆ8"œ e5“ìI"u˜KÌÍ‘$³íalàâ’êxH²ªDh9“ ½r䋬U¡NÂT‚X6F±RÁ©[TVUi«VqûcÔÊ/.#vm>VÇ(bc3ðÆQÆêM#ÎL Xƒ; ¬‚ó"à7TSˆáï ¦!ùñ7¨Lô“ú‰ÿ&ħ¿ŽØ÷‡%=O»ÜÀÛßþöCó ¬uŸ™d^øBT’h—Çú6I*(Ö£TÊ×Yu„65ËÆvÛqÛÚpGJ¬lR–Þ .¤mH»Ð•‡LšpÏNÊ7߯—ÿVàÅÌUke¤v,i gÀMG ÁèÒÖ‚3+ ­Bã‚ëz"£ó¯W<é—?zÞ‡½ŸYç­î£ÂJjà9tEÜI¬$&¨º¤¨‘uK8*$¨»¾_%eiQ‰c‹ îbɘTª†gÕµCP.I¬gœ{nÇgçĉE莿ÒJpìpö~"I$I$gEƱC¤Ôbc íFâÄBEb¶“qÚ­€hˆNC6Vëy** eÕpã€È±‰C‹´ªP)òÑ©j VB>šÂžŠ Jp±±Æbä° ÏÅ `(몈‰vZpx#ɶ ðRˆžixT_šú_Tp†.jm;rI?lTϹ•d0 ß‚û£€k®¢´â´}ñRÔgÞzÛÇkײŸ¿‰‰ ¾þõ¯ð¢½ˆ}ûöñ‘|dÞ9]]]¼á o ££ƒŽŽ# †§B ,KOqž8‰ ³ømoGÖ븖…Œ"¥Rè%ce©FR$ík÷âùT¶ŽQ€ °\Èyà¸ËAуö4ô¡¡ºyaïŽj5çª4WLë™Õfg‰¨³¾w¿¼wÕ÷±¿†Xm°¥ë®®¼ªÎæ=šBâkäjc,’#t¤Çõ„Z=…«ÚqÜ$ ¤‰‹TT£›Ä!õºG½êA^½N[Û žS'‰%µ EXwP‰ÀuR©¾_Å–AèR«¥H"‰RÛŠHy5‰ÌåôjŸ)ÿøø]vÙeŒaÛ6—\r 'tÒcΞm¤ø‚¼àÿY@*• A K¿óù>Ñ/˜Ðít6 XíCmÎ#¡ó’Û!Ž{ðÿŽdç$Ó#.o\ƒÚz-â”wáŸô|øÔé$Û³Xú Ü;Óý™ïÿ«ðÔÏ™\tÑEœrÊ)û¦yÏ{Þógù}ýýý|ûÛßžü×®]ËgœÁW\Áàà ÿøÇøøK.¹)%===œ{î¹F@ ‚i±m°íÙ-CáôWcp¢.̲m„-ÁÚ­øÄH6…<Êö¨»x{!X߇¥YXÜKÛ`YåP9ª·þ’›–ð‹m«Â}ØÌ›„²¿Ü‡gãç*ó*¯f÷S>]¥IÚ£}ÑN¥:‘³§ÉµMc•cªS>B)2õ2¹ú4é ‚7S'¨¸€ïUqÊ!žWÇ ëTË>AÅÕyãx!2¥“îNaàèP1R&X®žSâ¼O"-I,‘J— ©tRŸX'ðäOÐyšÙË•€Ht©’ÙÆ™2It[›FËy¨¹®5Š¤ÒØBôãêh1iG Ã$PÓ¢Ò dÊúþ½@{ø¿‡=Ë«öêsópâ CòÈcRˆ¤h+DË)ÊŸSîÿ¼¿Bn»5<Ž<ó½ˆm÷ÂßžFR8E$ÿ÷ËT†¦È~úÓOÉÏÑ\0»ÿ¹Ï}îIùI’ðº×½Žç?ÿùÜwß}ìÚµ‹ë¯¿ž#<’w½ë]LOOsñÅsá…îWì.¸à|ßçÖ[oå–[ná´ÓN3bøï§øú×C½ŽˆcDë 1Õ´‰¾M§ÁÏRyt ÊêÆ9| n¡€X”ƒ¥9èô¡3 í>´çHl›©»¯à²ÝgPŠÜâq ÷Ñâ@šîÃkí¸›ÌÍ:oI §s52tÓ^™¢­:MÛÒ€LyŒxÚB?¬’é(!gÓ£º{®7SÇšŠ±íYK¨Nû¨P` ½ì®°tåTF•pë.q`éŸêv0:ë„K s)‘¥»£ÝÁ¬ £°” ¥t˜p¶E¿šÛo.Ôe û˜¸qžÔbBÒâÆÖ\1l)‚n.µRšs%Ä-âbcû»Ð¡¬aPÙÍ:ôµgŒT¥J²èîAf·j‘±À;lúõŸÜ ˜T”R¤òøþUÄ]ë°O-üðc$™edÎû[¬¾Mü/búß Š(ÿíûHåëˆtš¸\†8ž×âÉftt”o|ãÀ“ÛójÙ²e,[¶Œ 6°k×.Î:ë,®¿þúÙÖ(–eÇñ~Çñ¬sB$‰q †'‡ý~XUc„k– ©C_¶Oá-g“v]l×…Œ£Ã]['Ú3.äò$å:Ûvø¯ñgµŒ†Ù²dájƒN³ãîœx̆° ²ždQ¥J®w’ 3d¦ªäjUÊÃeD¨ð*5 G¨±⺅c…ˆTBì(lêd« QÅBÄ ËÕIteéûíØF5AÎ@Ÿ ×±‰q¡ÐíÝ›’Ì ES$f—ëP-·É‚ã‚ù¿G¶ˆ‰ÕpªEL’1‰—2i¸ŽæŠŒÍý)æz§Õû!zi€Æ¾ У'Àí©Ã€B €*îEND°ì­@ÔvÁp {ÕjRéͰ’¶5°þ¨G÷¡Ny+TGPwÜHeåëÉ2&îíÅ>ì°'ýóð•¯|…™™™Y'â8OÞ$Ê 6°mÛ6Î>ûì?Ûs1üÄÂDsÔ›‡¿f Þâň8Öaë½Hô­kƒßÆÌ¯ïâ_ƒÓ„®ä¸ÇË}¨yâÑt"™\•œÈÓ]£Ð7ŒST0*±ím#3$‰åDDI ¿½ôØ á´£B°¡vOnc M¡j»¡!¡ ‰éKa|Jµ¹oñMBG‹“Ï#*u¨%ó„fN” ‘ÍË+JèsE‹˜È’ dS¬Ç£¦ú/ØOZFh?.Åe®ÃssuÆrãœRck>I»Ya¬: JZX@,yÊ ÔÛI-9Y'Ù¹gw"¯½ŒdÈE-;~ò%â~(Ÿp,Ù;ÿ‹¸þÏ™XåqÔwÿ÷íƒÒ ê}$ƒÝÞN²};3×\Cñ‚ H¦¦ž‡H¥þÛÿíwïÞÍ•W^ @gg'Õj•M›6Í;gÑ¢E,^¼øÏþ»·oßÎ5×\ÃÙgŸÍ¦M›(‹œp üìg?£X,rß}÷Í[¸êøoyË[8á„8çœsøþ÷¿ÏqÇÇöíÛ9óÌ3€žzHß×­\öçXTc„‚}’kJGý‘òj¶ën#÷Ñè¸;»5Ä$›’´‘£½4NûÈ0%ÙgAFdF¡>êb9!bÍÑ Ó8QÙ?U…PÏ‚<ì0°RìCõ#jñì7üЇšég¯…é^˜‚ÁI¨³"’=-6¢c%nÁ‚¡Q‡éªn©æ÷Ćº«…Dø.éEÝ01å*Ôí™[Ã\â¦èÈFª#a[º´;Tó§)l¦R°@Dz¹܆ÄKÞ\" e¬6ö'Ñk×X ±™iU]UÝ]ýv÷éç·>û ‰ënAÎQ½ð|”Ïü²Tbüoÿ–øç?¹|9~©TÍþ3áöÛo§§'èWÿ³ŸýŒM›6±iÓ¦iç 200À¥—^ÊÂ… _—÷nlldÉ’%<óÌ3,^¼˜£>š³Î:‹Ÿþô§sÌ1, ›äœrÊ)tu97K–,Áó<žzê)Î;ï<#‰°—)1%W®Ø} êC›ÑmПžu^S"é2)‘&E–ĨJb¨„CÃX¾‡îl‡Tt#»,˜QS5ÿ²{œª å4˜nd’#’qغFËx*i¨6Æ a”Ò`·@ur½00U_;K`¹ZAúÁ‚Qʃدìá4lj~$$‡!7[û`4¥ Tƒó¥œëjùøb­íXsæÀö~¢ìl7 †P±8jÐ{Fjy(¡ÉËp´à\½ŽLÌC’‘€V *A‹|pãJ Bü|@N²ô¸1m`ãfd<½‚ºú·øýwLš6>‡ßgS]ЊõÝ›‘ÿïÊ‹HÎÿt…¦¤Ž: ù‰KQ@⤓°o» ÿé§QÒiüþ~ú>ô!ºx`Ú½öz*€û·`åÊ•vØavØaoØ¿Pccã¬ÉŠ---³î×»Þ5íñ²eËX¶lYdаwcíÚAV­Z³ûêÜ2_ S%–.“ȧ–°xbÒTI“!Eíݯ`Œú¨mmÈjSðZÙж¯ÆÑt¯3ÈÂÏZÐ*ëÖcçFð7¡v”;nk„R Œ5ÁÐVœ¾!ÊIãm'@ãAà4‚2"Ú<Ðûड़‘Ê–‹³ õÀ“ÀP ž½cÐ<›`Ërp Û.RN€m@lÉÁ°øXh\}0<ƒc°i†'¥2¶æb›àê`k q8ÖŠƒ¡©Z T Ègëø.~±‚£ûH5|ŽLúæâý0:u×Ê%xaK@VŠkÛx"(Âk«!™”ÀÈ4aJ‰S­`èqœÁ†®àŽù”Ý ­HÚ &‚œVo”¢ŽWíÁ*Åc—¿Ž’ã©1ôŸ>He´‹Ï¢zú©xýEÜSޤ|à (÷ýòÆ%ÙÖFùïÿ>øA´®.†Ï<cÞ<‚ÊSO1|Ï=t]=Þø8vO±|M÷íªU«Ø²e ñx|§„Á½DØ«ðå/ÿò W‹¼Ò¦%Nfg§›¯©*)%MŠ`I`áóPÛVà¨0wd=„èÅ>jóò ‘²% ’ЗÄî]-æ`ìw L ƒ×²èuÞšT»7¡·M `N@lÒ£AlãrS7n÷6\kú!§Bq’C` ASÆòÐ<sG w¹}n¥ñ ÒÇž‹Ž‚‰h„Ì ŒOÀÈtŽ@n90‚×׋36J¹X¢¤z¤÷;– ;`Î0òÐÚ¼G¥‚¿­opiW)Žç)ù6B…lÇðW§‚kÃÈ0d_ ȤPÀ}a²ZÅsÆóy$>¢±ÅûãXIÊÛ6ÒzÔ;àŠКÅ[÷ å¾>Õ \(R¶ ÜdŽ=Ò¿¡¤(x­ (Ž‹ŸÍ0ôÊF¼ (*ÕÆ&ͯ ²¹t)åÛoÇkj!µÿþ ½ÿý”=Äa‡QúÙϨlÜHû¿ü NOÝ+WÒª…ÁoDio'vàHÛ:þ‰ eË–-¬Zµ €w¼ãœp DˆðFcx¸ÌÖ­c„ùj‘W5õaêcÒd•2_êcêO4,ÆoéGЂÖ1è²ð«â;.ZÇ[¡<ÄþÍH¿!PRqDã`Œ€Q€dÒ#Ð<‚˜{ÖÖ­˜Ë‡æ¥`4A¶Í%è(ÂÜ<,E=xˆX_zs3¢ed:!5 Ù1(—߯ü<ŒÃchC9bCCxýý+Ž…ù+ R€æ´æ X„BFò0QDŽŽcär06†70€])?ãBhk†öLŒÃø(tõdU®@ÿúø~±ˆÚׇ@V*pÄ)pÒ»“×@Ìí×Aö"æ-Au]Ü|¹m+¢jã–Ë(ï¾€¾ÿ‰·g‡vl,ùô³è½}¨ñ8îËë)nëFK§©H‰õŽ^ý4™ã#ñÖC1¡XÄÿïÿ&–J!ëÔS©>þ8Åb‘¦O}¿R!70@æ‚ Ù,jCâÌ3I~:CW]…qþù¨ °ãÊ+ÑŽ9†ÄqÇáW*¨é4Ùw¾éyŒ=ò ï|çŸ|ßÞyçlÛ¶T*ŧ>õ©7ÕÿdD ö<øàV¯îe×w¡>ŒYÔG}äUfgõÑàc.Úѧâ”0ø;´!O££ 2‹ V«©ý uká2¬¹s!ÖCÚÛ†9Uä%ŒC'h,ˆ~xP~ÃHNÕ%s]¨T¡\A+I ¨ýÇJ™€†Îà:\ª6Ø6¢TÆ,•P bŽƒµì@ÐÍ`Id¡cÛº´ IDATm^p ¶<§RA)W0‹E´Bm|œ˜mcî·0àñ4´»`WaþX &ªUÔ|Q*á—J$FF0ÆÇñJ%.|46sañAà800€~ÈŠë" RCC(¶Mub‚ôÅ—0¶e+Ù /DrH+ä:¨û-&Q.£z±õëQ†‡±t£±u¿ý0N<‘Ôÿù?$>ašø¹MK—b55á !,@âÈ#I}6…§žÂ<óL?ñ ´¶6bW^I¬§½µ•셢ϟ´mÐ42_DeyM—\‚šÉ€”Ä–.ý“ÕÇàà ßùÎw8ôÐCihh˜td×°xñbR©ÔÞéž”RÊhjа7à°Ãná™gúêHCcz™’Z‰ß8Ö"$*&bˆC2†HÅHµ•hž—£y^Ž–yC´,¢y^޶f—N¥ƒ.æ‹ÛL¬?‡3Q¡:š'yô‘ÁDoÛÈñ¾a Ö×( IÀwœ "ì&êk^yæ™\vÙe“=7êqóÍ70wî\V®\H„<ùdo¦ÿjɃ3È£Þ÷Q×ë|f·ÁZôUÒRCâÈ&M’ j4ðv wÞy'[·nŲ,>ó™ÏÌJõ doG¤Ó#챫píµ¿cöè«Ù*î3J–Ô"¯¼I‡ù$ydŠ$R6i‘š4]¥ÉDê#ÂncÓ¦MÜu×]œtÒIwÜqoúÏH„=kÖ â8µž«»Êûez—A =¬¸[™V¶d²Û ¡MsœG¾¯«V­bëÖ­¤R).¿üò}â3Gÿ-öXÜu׋ìlºzµ¼´é½>Ðuô¸·“Ó<ž)‘HÚ¤”ÄdÁÄ(ï#ÂkAoo/·Ýv8ÎO:é¤}âsG>{$zzò<ôÐÖðÑ Ý5f¨½N}gï68©>2á:Êûˆ°û¸õÖ[éëë#sÁ°nݺiljóæÍ‹$B„7ƒƒ%º»ó»P 3ÌWÓ"¯´éê#;•4D^Ù¤”ì´’í‘úˆ°»(—Ë\{íµüñtvvòÄOL;§T*±mÛ6Î8ãŒ7MOˆ@"ì‘øÒ—~n½Z¿c†úЦ™®„© }ÓÂv3ÅÉ~5õ‘$@Dƒa·põÕWS*•øò—¿Ì‘G¹Ï|öH³G؃ñj꣎<^µæ•7Ía^‹ÀšŠ¼JG‘W^3ŠÅ"_ùÊW8ûì³9âˆ#ö©ÏH„=¿ÿ}?=ÔÍìŽóyÊôœ@}hÄkÝëH"S$iè;å}Dê#Âîâ+_ù ~ØOä _øBì[÷RD ö8¬]›£Rñyu߇9¥@´éõ®jêc²UmfªUm"e“ ó>¦*îFý="ìzzzøîw¿ ÀùçŸÿ¦®yõjˆ| ö8Üv[}øî.¢¯”z¿‡6éûˆ§ ³†îFy^OÜtÓMär9V®\¹SäU{{;mmmDˆðFá©§Ù´i¢NÏ–<’ˆ>½Þ†Ž^«y•)îÜë\4Dy^¼òÊ+Ü}÷Ý!¸øâ‹QU•µk×N;ç¿øÅdQÅO~ò“tuuE!ŸÝÝyr¹ÊPæô¼½.òj–¼D¦DÒÔêú}Ôj^Eê#Âîáûßÿ>ÝÝݤR)î¼óÎ}v¢ÿ {}´—é¡»õ¾:'ºj‚Yye굚W ÓÛÕݧ׼Š|^«ú€ „w_FD ö(üä'ÝL™­fª:óU]Ÿs -Tå)‡y]â`ÒÐC⨩È÷a÷Q«¸;þ|>ðD!ž€þp;v”Øuå]-leL+ÛnĽY›E%’δnƒ)Ò‘úˆ°›¨ï6øÙÏ~ËÚ·ýhDØcðüó£uÕwgš¯jK˜H8©@4sF¯ó:çy >j‘W™È÷á5á»ßý.===Ì›7oŸ)˜¸+)¥Œn‹{’ÉP,Vk·fH `±€8°@™sLH$ Ãl„¦¹Ã4ÏËÑ2oˆ–CÁv×8fÌ¡‹9t1—&š£ÄÁ»…ññqæÏŸÏøø8_þò—Ñu‘‘‘içtvvröÙgÍfÉd2oê1‰¢°"ìp¿N‹R‹¾Rƒýº˜^ó*Ìû¨ù>ÎòåËùð‡?LggçNçôöörß}÷pÔQGqØa‡E!Ÿ_ûÚZŠEŸÙ›GÕªî†Ç eÒy>yU3[Õ¢¯’)ÑE^Ex]`Û6_úÒ—øÛ¿ýÛYÉ£¦@þîïþnŸ—ˆ@"ìêãé§GëTG=ÔÔ‡„þßS j^e&v*ÙžÈIêÆ´’%‘úˆðZðùÏ€eË–qþùçGRg/ˆá/Š«®ÚÆô1º;[ñÄÚ1 lt#áÎê8¯¼JOF^Ñ@GØ-ô÷÷sË-·ðÑ~ôM_ž$R öôöÚÜvÛÖYÔG½ÿìû½¨ahÄ2…if«©È+£®dI&ÊûˆðšPó}Ì;—~ðƒÑ€DaOÁŽUJ3Ècf ¸LVáõT´RuZ™ö©šW6iš¦•lò>"ì.6oÞÌ]wÝ…‚C9„mÛ¶aÓÕlSSMMMDˆðF¢PðùÚ×¶Ó‹'Öû?´ðxÍ™n€¯¡SÝ)ò*ž)‘ÔõIÓUš4‰H}Dx ¸ýöÛééé!NóÀ°jÕ*ªÕê´s†‡‡àãÿø›²÷yD ö(¬_ïrê©ýlßž«# f¨­n­a B¼¦™­Ù"ɤMZL©È÷áµ`ãÆÜsÏ=\uÕU\rÉ%ÑÀÔ!úiá/‚;î(³}{ð™n®š™y^Ÿb…¢Rí‘ø#¢®æUyÒ÷‘ ÿ"ßG„ׂZÍ«®®..»ì²h@"‰°'àž{*\}˜÷ìŠ8f”qÆ$é <ÖŠ¯LF^¥wªy©»‡-[¶°jÕ*®¼òJTUeD&¬o¤„G‡«®*àº.c¼¶;›ó\¯#cR}ÏÓ|!‹n8Ä3%Rº1-l7Aý>Š°Û ù¶oßÎÒ¥K£¼ˆ@"ü¥á8põ7áó_­B^•:\KœéÿÐêˆÄa†ä¡JDly|!KŽÚFJ4ÖE^e"õa·‘Ëå¸é¦›èèè ··—ÞÞÞiç,\¸D"Ht»Dx#ðíïÀç¿øNЍF 3ó?fv!Aº0AÕÀ€—î?Î{™ÔbkZäU”uawqã7222Âòå˹á†xúé§w:çÇ?þ1ÅbÓ4ùêW¿ºÏŽUT7Ÿ=½pʰn;Ë0”Ãm?$عû FP‰7 š×513ØmÃ[VöòOw?3Yu·‰¦º×‹áOœEpïÜpà ‘óü 2Gø³áÅW ãT˜óX· (WÂ[Îfº©ªÞ×1sÛÖB‚ë…¦+= wžû]'›¿_y•ŠÈ#ÂnãŠ+®à ƒâÜsÏ$")¼ç2èòþo_θõêUFYL®ëEú!‘S©†¯k«F‘W^r¹ÿú¯ÿ 5¯ÚÛÛ£A‰$‰߮ƒåŸå—BwŽÀÕaH(Ë]Çl$bÔ=k:$Â׬Y·,x~Åi { Rv×^{-¥R‰… rñÅGH„7[úᜯÃÚ^Xû{puW‡k­jëû|Ìbªšu ‰FÑÁA>a9Tñ€@*ã‚'Ö(Üô@ô=DØ{·.ïãœsÎ!›ÍFƒòG ŠÂŠðšP¨Âgîƒqã› ¿ªÀGQÄv8êó<$Sá»0{6zH"BU à Ÿ’Lu%à[¿€Ï]™XôÝDøãqë­·ÒßßO&“aΜ9“¾TUt¨[–Esss4hDØHà¾WàŒýàÖ_Ã-¿ T¯„ëmáä>NôµZ‰Š¿Fµrúí(u™è"\« •J¨>!äCž‰ƒ£Â)_‡£—ÂçÞ­©èûаklذ{î¹!_øÂøÄ'>±Ó9¾ïsã7AÈ»ßýîhàˆÂx#ìþõIø»_­Ào& G`®jž2!‘TR8é;>øUðíPFxS Dü@&MVaÿE„© " jHí@Ráõ$Ãki†›> —}_vÏ}îs|ýë_§µµ•h@"áõÆKcðî'àÂðßÏ¿öÙ* 'ïÁP ”ØÙÝá‡$¡xA]YsÁ) Â(+E™R"JmaÊŸ^k  É£¾_2\JLúFn}tN^ £ï0ÂÎØ´iwÝu0Uq7ÂȉáUñó,î‚wþ6;ðÕ_Àšñpï'ññPH¨f+=T õ•Ht@S@ Ö”…BUUM ]]™*ö’ÂI+^C)\§ê'‚eÍøÈ]pÁ½Ñwav|ÿûß§»»›%K–ðÞ÷¾7HDx-¸i~¤JVVູ&øëß…aXžRæ*5œ´7‡Ç LïL«‡ª£¶ö)‚ð,Å 2Ë}¼ÐÇ6 TCòS ÆdÊÿnÖ‘…FP &Å”)Ë€çópýKptŽì,b"üÇü×^{-Ÿüä'I§ÓÑ DáA7>1|ò¾ÆeHÆË¼}ÄäòA·[/¦”CÐEà¬vÃÉ{[ DY"E8ÑWÃ Ü ŸGH~=(à ÐüÀ¾ïh¸ ŸWšÃÇvxé€T–ÿŸç›ßü&‹/æÂ /ü‹\Çgœ1MtÐAÁ¿”ãÐÐÐ0ItÏ>û,‹/fÛ¶mD(#½gê1¸r5šXЇÆߦÙ9в~0/ó5J›QÞËÓb±•yëD™ Ïó"§1L‰èáNbÄ)ñ$óhb˜FÙÂB–°21 $ÙÍôÉÕ§MPq-TË#¥çÍ5@bZ™üh R Úe'1¨šÁÄ\ƒ*ƒ©êì0½;­2ƒP¨{¬†¬"ÅôÊ&³™¯jªD™A&µh¬Ú\ó‡Œ1éQSþR d}üXh.ˆjd$|½Üâúü¤Waq³ä†$4D%áß”xüñÇyøá‡¸ì²ËhlüË$Í™3‡Õ«WS(x×»ÞÅŽ;èéé ½½ññq4Mã´ÓNã€Àó¼È„õæ°ƒjjBµÊyÈ.o J}`Íñ lú2Ì»ßü Jî?@ÿ{JÙGÐË× ¯a¸­á~œÌà^Î.EO î€ÕOÃy×ÀšK`› oû,T¯_ý?8|t~~ó?`®„_„­È5[±ß³k €=¸†‰w´Óú(Bþñÿ‘gžyf§_öƒƒƒ ðéOúÏÚä”SN™fÒªG[[À_L!íµR~ê)ŒÅ‹Q³Yªk×R~å²ý׸÷Þ‹›Lbz*¬YCñ¡‡H\qüû*F/þ %±ñÊgœFõ³_¡¡IÁÿûRþÔ·Iœv$|è4†µƒiú?ïA¹ù3ØþqhWÿ#Ê ῘBþïÓPŸ» ù‰+7Ãÿäaèà> ¿žý < ÜËaàå÷“ÜøKŠ2îC”ç¬G/8Ð ù®FaÊ€OÏþ]dìqÌ*kºVÐìå°Æ+lH.¡“^²ccü$û.:d±b™õÙ¥,c~Ua ÖÆ<¿«RaSbä%v”çà'Ú½~†e:í~?[ËóQ“~/«f‚vúy\9K­àI•¼šB˜’ªoN•%)‡J£æË€©0]¥Ž@j¤¡†DSoŠš©BêÉ ¦@dùh¯bšI êŒãJ©‘T2ü 4úTF-H€h$eÑ|4‚™®¢ ùˆ˜ÄLW±ü c¥,f¶J’—øe~-9O rûG³ð^Œ/~ñ‹d³Y.¿üòh@^üEO¼BâóÏP]»–î°L²?2Bî‹_D‰Åp·o§ø`47Ãè(Üñ=ÔйÄß½Ÿò¶­0–ûû& ™ BבŸX‰«èÄæ·#úž—Ä8âøúi0æQ^ÿ,Õ»®Àï‡Ñ_>ŽøÁø[Æð¶oG6Éý‰Q¦­4ÀÓÞa41L{©Ÿ²£‰a²ÞÝrŒÐYéå…ÄrE(’q5C†qiÅT«$•%â膃n: @$d@&Sµ¥bL–™¬~[¿®-ñ]lÇgyDà{˜ÌOÕ½g²n_ªîý’u¯™œqMñºýñ˜âÁóݤF¾”‚4ÄÓ%ü¢‚§«ˆ&IZŸ 8’@O;¤âydQàk mœ,cÜkÏA^ ‡O°•#ØÄ+䣙c/ý÷ÞË“O> ÀÕW_ ÈÞL õIÔÖVôC…»oÇ_zÚ;N„_ÿŒÂsÏ£­<îû¥-ƒˆ“ß…YéÆ]ýþWè#¿Enû‚äÛçó$…QëôVĈĞHR]Š ¾ÝŽwt¨*úÈù“·º8›†œüŠö7‡$©mÖ`WÂv çØX±U¡ÚnbREé¶Kdi¨Œbí(Ñ;§“f?‡•+³5½€vúÉôŒóJË"Ú >RbS|Ú Û;Æ ÑJ«„ Œ'3´0„åVè·Úiaˆ’ÇÑuš&k&.J¤™ Ÿv’HP¤‚Eš ,*(ŠiT1•*ºâ [ªéMN¼".R™mOÖMî3%êÈ'¾ rIÌòzõëWÛŸšåùñ¤«#“‘pÓ¨2QMC¬LwBƒXé )òªIâ±Mê0£NÃdȳ†Ã}¨¸Lp ?çWlç<ÆslŒf‘½W]uRJöß.ºè¢h@öV±{zÐZ[š†½e …§ž LTë×S|î92ï?¸.ÕļàD¥Œ•Ï#>ø¡Àçqûws©#߆ÿ£;È·/¢áÒKñnþ*?‹qâ ȾGe"‰ráEðãkð,”wœH¶£½å¹KI-,ÀvñrŒå@¯‰ŸYˆv8°MƒýV U G§RMÀÀV§` `‡Ž7aÁ¡À6Ì6Ä!ѣˆ†z¨‡Ú#ÁèÄ?H!>æ`,üý'FpT ͦ­2€Ó«â6htº½ ù-h–Kku‰JšjÒ¤Ãëc@i#¦–hóI6’PŠ´2H¿ÕNRÈ2ÆH¬‘4$(2(ZI3DL’†Iur;N‰”ȧD\)at3 ÝrP-oš  9]$g™ðg*‚Ä.Öõ*c¦Iýc»zïX‰1•¡ž²Ã55DFÒ¤£8>JÊ'Ÿ@w]'«Ñ(Fèó:Èjc´2HžAÃøŒs99†˜à7<É£læZ~ÆãÑŒ²âßÿýß'åW\qñx<”½Ö"‰·¼%ðw<ÿ<™÷¾cþ|ò?ü!Ú‘Gb|0åüŽ: õCp|¬Ê[ß ?¸ºöGu,ÊCÿ…WrÐVžƒµéi /÷âút{û÷Ïá/|;ÊèZ¼u}È–·¡6»ððf°&{LÊŽçÁ\Šù–fÔ€?u©Ž(^üÕA°å·o#v¬NŠ­¸ME, ä›Qß®‚³Æ`n<°íç2ð6Õ+ÀX3ÞMXêZ¿½,MR+`ö–lo$'±±ÀަNåéÜ;ªsh#d c¬o^JÃ4•†y¾ýÅ(1µLIÓÀ(:9£™FñPH²<=È IDATŒ¡à£á’e •EtR¡ù¥‚…‚‚ªzxBE•RøªBU7ñQ¶DU‚ý®Ô  –`ƒ4Dà±™ªœ[azn-j«úOdÝÝWŸ83«Þq^ß̰ÞÇR¬>¢«>éÐ ¯Ë‚r9)ÐÒ.¦_e‡2#mÓ¡÷±¥²˪Ьæñš¤M ÐÄ0¯°ˆfr´2È0M¨x41LÛy„ÍäxÉbÞÂKlåí9Ý÷|ãßÀ¶m>ø`Î>ûìh@öf1:;¾ÒÔDÓñÇj¤·—ÔE”ä¾÷=Ú®¾T•Òm·ÿøÇ‘RRýÖ¿`ýÓ?!U n½Þû>ÒËÞÿ!FK1ÎûÄÝWQ)$0N:ñ?wáv«h—ÿ üê&è3áØC1 ¿ TÃIïDý!ôé°ìhD[~-`ñq0ö<ôëx™¥ØøAÚÞ†Á/‘ÛkJû ì¿Ü…’ÙøC¬ }z‰fóôœý>êR‰U¬âvKô÷($ìä„‚\ªÒâP8(I C(–HHšÉá*ŠéÓÄ0®Ð0 ¼6)òØT°H‘GÁ§ŠI†qr’(ÊÄÐp‘tLªø …–¨à¢QÅÄSUla€ÝwR"¥ j™)Q4EóñMÏQB©J¤)¦Ê¸×;ÄõºÇõeMfF]ÍÎ;Ó1_¿o6©R}”– •ˆ>¶@ÆÛJóQ>V¼‚âûLhiõÚÄ[ÄB2Ê8~y%…@ÒN? Œ²‘Å´0D;ýl` : Œ²†çù7¶ÒAml%Åqôò[ÞÆ™(XÑlóò}¼ð œ~úé\sÍ5;ó¾÷½ÖÖVE™Œ~а§*šQ‡Šƒï“¾àôÖV*/¿Œœ;ýðñÿ{ª ¤Ž?žüþ'J< Ç€ûß÷#*uåYè÷ÞGyÍKøGžL¼8ŒûÌËxKŽÅ<ùDü»®D6Œ²° ~2‰EðÎwÂm«@Yó[á±2^±uÉ"xò`wBg#l{ÆQß¾ µÿ‘ dùÉ)Œjw-p` mìeØRµA›€MÀ<&6„3´‘Ñ´˜˜¢Œ2è£Íàç1ÇªØ ‰x‰´=A9#+ÇÈŠ1&i²Œ§DÁLÒÈ1ÊL¦Q4\ $'·kª£F&U$‚" b”ñPÑq&·Mª8è¸hXTpб1¨ WÕpб¨à _U(Çc¸Š†n;¨žì1„-ÑTßÉD¡É@™Ô¢ÌTݪ@„+‘jØ¢¶¾d{}äU½êÐwA 0=2‹:r„‚¤ A‰ùxjp­šáÒ ŒÒëw¢.MÊ0q§D¿ÑÎ|¶ÑYéåQóDš”aºè¡H‰ ƒ>:ècËhe6x…Ex¨42ÂóükÙÌ~lf%c§‹#£Yç2—Û6×]w®ërÈ!‡pùå—ÏZ¶äî»ïfppx<ÎG?úÑhàöòPŒyó‚MÓ¤á#AÚþô§!‘ ðÐC¤þ×û!'ÿÈ/I½÷"DK<ó,¹ªNÓåŸFÞûC ^ëÂKP¾{#vŸ‚ö¥ ~õþË£ðÁ¢ UÌÀ$…ŠAk’4lŒi¤Q[×¶kÏuÅÔù6žªRUM¤*0*Šîãh:¶f+–Ñ<—¢’@SÜ€l%0›Yb* ]¥RPÀkU"x1U hбt¤.Ф‹@µà±*=<]űtT<4ÏE‰cê¹Ïó1¤T~ØcÄv@^ZàÏñQЗ¸(!¤Dž ãT‹ñ š^r4“eŒv¯Ÿ’§j™ÌgóÙÆƒ¬¤~ºÜ6+ûÑ Œ2WnÇUFh`6ÑÈÏñ¥‰aÖòM6²‡ÊgIËJ3Ít`rH4½ŽÈçó\ýõ,]º”óÏ??”}@P˪Ù@„i’>ã Ô–d.GòÒKQçÌÁY¿íœsÈΙCþç?Ç]¼”ì§?Íø½÷áiâ^BåþûÑÜ£-­¤~üŸ$ÜãXŸûbeg,ïEdÊaÐrÁ\`DÜ È ˜/ÎØ q‚nw¥ÀžÎ S­Usdb†û+¡éfˆ©âƒ" ,P\?˜T­À1­H© ,µ8®MiU‘¾ÀST,Ye?†.ƒü [ ”ÂLÒ¨`í¤(‚mçUHÃÞÅþª0±U[)L¨ø†Â„–&!‹˜Õ*•¤$ì"E3Vr1¤MEµ&ÍWŠçcTl\MÃMh¨Š‡æ»”Òqá£{2&p,ÝqP¥‡°Ñ<óAr"†P$†c£ù.¦^Å1‚î'–[ ÔKèQðR¢ãLèÂÁ"ðý(ø¤™ ŠI’Œð‹¬ Í^ޱűÈ^¶çç¢5¸tÒ‹ÈKr ÍÌaN/Ýú<’¢À¿[”Ô8KØ@³Ÿã×ÊÛi"GšÖŠ0‚CÊÛ îõ ˜÷Ó៌®¼/š™^#jYç—^z)---Ñ ì2›¿Ä0ˆ~xpÁÍÍÐÜ €TUÒ]¾ÏÐÓO;÷<ÌcŽÅyi•sÎÅ8åÊë^B®|Òq(ÿæ×¨K¥8ñúÖä ðÊ-R-,‚Õ¤À¿¢9ô_”A6ƒè UD3AÔQ• Âk- )Úû]‚Þ•42¡Šñ™R42Ü®å¤ÅA˜Ax’÷ˆå`Œ‡¯- ª˜ÿ@•(øŠ *HSà‰ÀdUÁ–Q”e,ðs [L)Žz©`íDõ¤Q3qÕGèSf/E§bZ“¥!ptLu-æRÒã$Ü"2)¦Mªã¡é.ªêQ͘˜~Ýw°3.±j5æá'ôªƒåV0 ›r<†î;Äì2Šð1T_WPUóQ_(!Ñt7pø A`úÒqH${Òô§ã§D¤á‘f‚Ê2ŒÓÄ0A)û†hÉñBb9M ÓYíEu„¶ã=°àÛ Œ‚Ÿ=Í^»P<òBV¬XÁ¾ðÎ=÷Üj[ÅãñHì 2ëÅ׳ÂÌvÑÞN¼© ¡a8Ö‰'â¯]Kú¢÷¿ð"2Œƒ¢øÒKÄÓi´–ào؈žˆÃ‘oç×co\Ïøê_!|0%Xà ˆI0'‚FzŠøa”O1hq!=Tµ\‡Zb[m»aT«rûjç˜AÁC© „)–œ<ß+©ãY*X²‚T¾VÖÕƒžå5uQñ­ c]ÊÄÓÔi&®yÔH¦^T°¦¯ßWVchŠ‹)«UâÄubÅ2ªåQŠÅQLÍqqU ½ì÷K @fHý6€E%PµLª&ŒD‹Q@Ç!ËE+A–1Ú ê›ø …vÙObd‚¡Ž·a¼…¶1K©0Ïï&WÉRUM(¿ c0ÔÒB[u€ôð}Jig‚Ôhžr5F5ib UEÁØA¿¤y|6݉¯mB˜¿A<û68å!èûgÈ^ ™ÅÑLÂó<¾öµ¯ÉdxðÁ'ýøÇ?fõêÕÓÎ_¼x1§žzj4pû"ìR±èú4õ[²£© %'yÜq(GAãöíÄçÍCI$ˆmߎ>o4fQë¦tÇ÷(<õ4ÕR‰ÆDMèKÌl’1äèt4ÂüFØ>D¹2„3T@õA1AL„Q¦(µ²ãV¸(!1ÔÂVkõ§´éJsú9•‰ÉT’œœ/‰®9A´‘JÜGÁ/rWj”Ü8ßBõ<4\|MAA(­'I‹ŠoQöc¹¨ê4ÅQ&6ÍäUÛW&FY‰‘¤¼†aái*†°)%âhI—&w8ðs˜qtÕÁò*˜~ ¦TÍ#¡Ñ5_Uˆ›%4áæ($ªá¡K'ø“‰xVQĘÊÖ6§oKCL©=8&L FþjcP•ÿÂU5|MA‰ù¨q5æQŤà$)º *ž…£PAxnùÿ·wÞqrÕõÞÿN3uûf7›J IH¡„ð† -ÂEä%>”DQQÁ{Eî}ñÜ \|QxfC ˆ‘*j%u³Éf³›mSvú)¿ç3;Ùuׂ &xޯ׾vöÌ93;gÎü>óíX¤EÞ c WQ«â‘#RµJ Xäe˜¬ˆRòLdAÐo6PRMŒr\ȇ¸R¥q¨S–ÈÅ#~})…kªÕ4\ß’ñP+‹¾"=4ጆ‘ǰ8Œü=RXFZ#dø¶DT-‰@ QôÇøV¬ÄF'B‹CÄ“§•=ôÈ (Âcnù-rÚdzÙîfj“)~×p3ÜmLÏ—Xž†Uîejçn’j-¹É&-Û{Qúú—ÔÓÐÑOdCŽÞÓ›hèïG}ÉÅž #¦K´×?aã8àwÀ6àXºJð¢ ëÓ¾Ç|6ÿ^òOóÑ^¸p!6l`êÔ©lÙ²]æ¹Èß]6}ß¹PÕ1Û†oמ>N&ƒ›Ëaé:²XD+PëëÁöSo™Ôž‹›bè¾oâå< ¡ kH!¢®pÁT`rÂW—éÍ ½¸Q.¢~3GM€1ìÒÒGˆ>B@ŒB¡ï³LªÂ2òØŠ˜(ª‡®Øh†ã×]X¾u¢)nY…2ضBZiTÝõ³½¤EΉ0TöJBøz,r2BØËãª*yÂäˆ%ZmÚ˜5£þà&©ø‹µEÂ:ÑP–°›'¦ á¡Õ³ÕÐäp™£³ÏEUŽáŸa¡‹‘–‡¨Úr\‹cø˜a×Ô°•2,LþÿlRÂEEÁŬÔ×À¾Z›8<¢"KŒ!"åýJžF¥L]9K:ÑFý´”ºÉ)ÓД4 ùt­–\[ˆš¡$VVgpAœD1ÙQÆË*Dœj»}Žu— ;ñG t;€f@-A-AöQFüw¯‡·ÁÞ=ðÒï᢫a×F˜q"Xñ÷åÇzdÏ«›nº)@@þq˜sæ`zžo¥H‰ô<ßJQU_ ë %…ßþ–ȇNÁÉdi¡hJ%tEº”K5¡¥Æ’„CÈú8ég^F*bŠ}:ªó1B"Š/8êB`iØÉRsªÿ¯(#­sÄíÐ>KDÕ]ÃC„ü؉0÷¹Á\TTÏ%D]·!Ye”J&éBY(Òƒ¨¦ÈyŒR¹**9!ãùé¼%ÕdHÄЄC\füçÀ¯i)cPv ­LL U >¡ú!z¿uʰ[I!"R áU· /öUì—‘â!£d¤U2,.÷5œª€ ?Çp–Öp]éVïĪîSC 7ªcˆRXn–A«L3iÂÝyö¶f©ujóYÜ„ALÏíÍ¢Ú͘z«;š‹aÏËbõ +ŒœPöÝw[¤Ÿµ× ¼r/ˆÅø¢²¿±ç~KxŒN?­|Íÿ†º‹;!þQ8ÿlxþÿÂÊ@s¡T‚–ügö¶ÛnömæÍ›¸«ÙP”ª‹Kü kFoi¡áŸÀ-Ð\]d¡€.„oV”J C"HˆÅÉnz›T¯‹UÐÒE3!aùé®a Â`iЃ¦8ÒPÉ¿´QÌ¡‰J—>Â*1GÜ+`‚§{`z¨hÕT U¢+¶/0a‰.m4á mSÒ0ì2/GØÊ£i¦(‘-GY Žßò ãÅQ‹.5FÊŸ3âÙ˜e?“ÊÃO­u/”-4Í!ªeѱ‘Ž@UýTX“’_1î ­Œ!|Q¤‡ëøAtCÛ',‰ç*HO *.ºj‰}xŽKÑT¿àpØRüºÏ—E¸èŠ3FL\©¢IEx~QBÇöS~+â[Æ@ ‘¦„‰.mjd ÂQoZ7 ˜Fšx¡„>PÄnÊ’È•°v³TBn½K¢4¶ Ízõ÷.ôZˆ—;=è‰Á”!_ ¶© ù_jäVÝ ´¿¹Äðkv3€=;ý®Ûý1xøÅ)p¬ o瑟~Ô"F¶‘8°²¼žxâ Þzë-ZZZèïï§¿¿Ô>“'O& z’²¿Y+“&aNšžçÚõ<¤ã ¤çgh¹Ž_¾®U\fºIiÓ.Ĥ9„âq Óô[?EÂ~LEõ Þ‚˜!ˆPÚµ“\§ƒVËé°8¸ˆG(õïÅóŠhŠ_Æë¤ò[1„ª¸8žæg†) R rN<¨‰¤üö*ކ´ñˆßf^z‚rÁÀ4KXfÁoã"=ÊeÏS0Œ2!³¸ÏBðTì’o zC/ûi½¸HO`;:Ò¾x¨.¦^BU*VŠ”ØŽŽç)~¡¡fû ª/¤Ž£1>‘B1r~Ö›PP\áI4¿~DÏs#~‘¢]ÄÑ4jœáB¯V!bç03%„ô0Ü!”Ae ‚Œ´êw‘ÝQXÔ‹ÒçÁv æ$ ÔÛÔL‡†õ°¼íâè"ìÙiáÖPzÀÛ®Ý6›PÁä´ïîÚ,Æ·bº€èþ,›·@žûÄQ 7C¦æXËæ"Ó ?u3J]­G÷Ï:×uùÚ×¾†mÛ,\¸»îº‹_ýêWcöëìì¤P(‡¹å–[‚…+ýÏbÄ Óü“»F,`âuס+ šç¡8Š®á÷ÛpÁRý€ˆeB"a‹|Ç3dw”»`HaYÓ}k¥)µ!¨CK-ÔFI?ù†ô½fš!¡JL%¬ Ô[xš7èøÿú÷—*\,³€w0”2Šç‘³#å2rÔÔ¤Hxië§óþ‚_S w¨‰b&„U_@ ) ©ø6œç)¤òþ·Û†P?%G>Fº‚:sˆšÃ.é !´’C<ž!læž$WŒà”54ÍÁ² DÃY4áP²MJEÏQP„?×<Îc%k1F(„‰ Ä#¾Å‘0|‹%¢ùn²Æˆ„ÉïyQÓe_Kó¨ !hK@mY£´m3ÊPÙ¿*â"B#TF©QðJeDÒÏöRbˆ2fÄ_¤Õ^%åµ³DZrhe‡TW MZ/1†JŸ+¢ §¨¡å¤'hŠô73¤ó ¼²B­–¤¡¦ŸBÙ"›"]AÜÎPß0€p$™BœrÑ@:‚Y$"ÏP,‡ÈÂØ?@Q<_`¢Y4Í¡X Q*˜8e é 4ÅAÓBfÓ(áº*¶£c|K‰Ÿt`:¨šŸBì9¾x¸¶3ò„ÿz4Pý@¼,ù,C²ˆj»k´’6(EÏ/0Íãw(pñÛÝÔã É0¦â/þ´d÷úÖƒÞf·;ÓŒXôKèŠâ¶4¡ë›`#ÍéÄj·Ã› ›BÜ­ …çQ(l&Ô ÖSŠ›„ôùçAPU?l¼or²ÒÇiDôEkh¤öòË1„ðã+†F5oØRý€{, ñ¹-Û(î’˜¶i5hM@K &ÕÀ„(4ÕâH›ì[¯µ}Kex’ R§¡´Å‘ñJÛ6–——æ/Άp}E¼^=oSIQc§HíLÈ‘¨MÓ öS FŽ:„°±HQ*›ˆ¼¤œ3¨µ’4Öö¡åŠé1gˆz½ŸB>Œ–vðl…P¶HÄÍ2‹èy›|&Œgû‹w([ÄÈ–1d³X¢”7qKþ`-C/£†\TÍ%,ó˜N ÇÖpÊÂó­UõkfTá¢Jßrð<×õk)ªŸý…WIõUüƸø®JÅpôüÎÁªtýö3*û: 'G*bž¯ÜÎVŽ/àgOÕúBB0µ{+]žëËÐßïϱiš ©ßú#Ôh-Ðô×’X1±c;ì‰!ŽŸ‡Üþ<Î&ÐÎ\†¹k¥  ·,BµÚ‘Ê¼Æ h B¸»ÖàåjñæMDÑ~O.fHÚDc…^´õµeJ)·øXBÏ=‰#ËãÓ°/YIãï^¥pÆyè“'“½ð†fͦíÛߦôÒKh³g£¾Ks6Ö¬YSuW]uÕU455kK ã}‹Kœ|²o­Ø6ÂuÁ«üÏ_Á VB²¿ÞŒÖ:3Qƒ‹ú`ͨ³|k¥Ö‚úZÜAʲÒzE@£ Ój ¡Z°]gÇ&¡´@ »- Âj¡´cÂõ[‹„&–P“eè…˜3ä»·´2=LE§!ØM¹˜¡œ4°ó:ñhžÚp;¥c¦JDŠ9LJ^‘‘”³†RÆ(–Ñ ‡¸›A²)ç ?^aØ~U¾„( ;6vQ÷ƒòÂEÑ}w”@úî$áà:*ÒÕŒ®ª>Kª-PTéVÛÎû~·o‹çoŠô-Y€?¼íÉ=©S6IDATVDV¬áÛ%öÍ2)ŒØ6TÙÏ«ˆKFBo»ß@lóïߥúÙV{]Üí ªCéÚL= eï+¾°¸“ ÿ5¼N·'F²gˆBý¤CP×¾€Óz4Êq' ­û?åäÂ`i»q:ëp¦Ï%6ÛFÍuP¨­ÁKB¹-¤" _=Æg>N:A=eá}²C]²„Üÿº¹a=Úñ'0ðµ¯á|õ«x7Ü@ãå—Ó{ýõÔùËè“'“{ýuÂóç£ÖüõÁú¡¡!þó?ÿ€©S§rÉ%—ëF 4ÄRéû5.rxR“ƒ±fÏÁ¸ìrBºŽjèÑ}—¥@Xƒ¨ñZòkWãîÖP´Lo„YÍ0£Új`b=Ù—_õÝ&ˆ¸@;(um¸fbë$‚H}sj‚â@½Ó¡&–¢IËP3PhC'ŠJÈ‹Év’KG(¥L ËÁªÕ¨I¥ÈöF±Ô¢ä 'Bć(¤B¾%0è!5–BXzhy¤-ЄƒP¥ÿ²ÕÁð\dYõ[ä 9z¢E¸¾,HâÉ}ãu‡÷£"#õ{„€ ÷óªn#DcØ`tþ@L¼âøn-¼Š€ OIÌU>C•Ÿa÷Vš}=×’ w¹ˆ–í§ÛDoA¡ÅV˜,`g?´ë0g lz w»€ÙKà·?¥¸Ó¡™CÍ´©ˆßÄ(O8Ó,!º“È…ËQZç¡=ýCF ê)g`ýðäôÃÐ^Bý/~‚70qüihÛñ\ƒÂ‚EÔýË¿ ÿß·p/<냤´êF¼å§Z²„ÒÍ7S ‡‰ÎŸOö¡‡ðÚÛQ ò/¿LÇùç3ëõ×Qb1žx‚úsÏÝWÔû2Üó à /$ú§>€ü9‹eߪ]¼yÈ!×E±ía‹¿2©€aB8A~Çã„æ/AŸØSë|÷Vcš"PWG9ý6ÖV!Z'”)0q"¹76an=ä 4Ô CmÈuÛÑ{mjffÑ£­ä•ƒPiÁÀôKT¼f~7ñ ù½aÂ1Í®#:¸¯GÁR ØE5ÔH(7€Ø›Ç+*~³HœF «¹3Ó…—,#ÜJ+|ÏovY6SÊ&`o 슋ÉÝ·Ø{ 8•±·†Bm°ÝêœFôe\u_ßLE pä¾1¹£,ÿ1²ÙæŠÉð§Î©ü•ßÅÊm*bbT\ZÉʱ6ý=-` r g,DìÜ}OŒb÷#{2ؽQô+φ¯ Ý%ÐW.Güô»0} êÑ'#~÷˜“QO^Z,C¯M餣©?í4¼{¾‚¼èDôGã<öÞ1'bœ}.Þ7îÅ›½ˆÈ¥—‘ü1Ô‰Óìc8k×ú‚ñ©«‘Ñ(éžÌK/¥æÄi¿öZn¸­¹™U«Hœsæ”)7m¢ðƈóÎ{G—{¹\æŽ;îð-óD‚ÚÚZn¼ñÆQû†Á5×\€iš$‰`$à/²V, ,ëÏî;PC†ïÞŠhÕ!bàj! o u'À¢ƒaaLo†Æ&ìvÚêìLšO¹¢ôû„Ã*¡HÄf"ÄdT&Š?óPÖ£”ëˆö&}¡%óÀñ0²=Dzrˆ’G1 æÔf„bböwà¥JWâjàÅÁ:a騻» ;í/¾®/ ¥˜GÌxR]Ð׃Y_H*‹·£W„¦6†1o.ô'¡»zSàxûDDVÄÆðEBµõ¨¹ä Ptö HEL<­"NÁP¨eª­sp¨veö*ÿ4üì'¥ŒŸgW¬ÿº¼¼ßÞF* R#§·=à €W܃Zê‚~Z4›Dn;ö˜{,úæW(vCÑh£vB|ÿ-¸í“h‡…óÑQ¯¾ã'âžwîÌÉ|ôcðøÿ£XÓJô¤S uï%¹§ŸÈG/$tØa¤û{"«>Kü#ËI?ùΉ'a}4éŸþqö9GÉàÃãΟOýu×Qjo'tüñDÎ<€ÐÂ…XGù£}õ‰©=õÔw|}ÿâ¿à׿þ5·ÜrKU(FbÛ6wß}7³fÍâôÓO†@@þnHIìä“Ã5+bØ æ*ð2”øDÌóÃìf˜\bÈx Ù±Ýn†EGÂÄH»„ÖáZX“‚1ÉTtêÑp1(#Ü à b%û)wQkfƒ“F¨IÌ®·q3²¦ µöHw#,ºq; ¹”Â`»Â!¨‰@}vw@G\òqPµ`ÕOƒb8}ï=½Ì!=‰‚¢RO›|X} ö€ÛÝIèIB¶X„blÔ¶fÂsŽƒTaûèOA± %Ç Ê&ØH³g¡ªär°wö$+ç\ž ®î'Þ)©Xn%[KAfʸ Šˆ<È0¨E ¥§ˆUñöH i½{=2ù_y ‹$¥p#ÖŠóWœ|]-ñO^óà7qêf¡-9™Ü¾€¦7£~ø¼õɼ¹…ØŸÇ:j ÉÛ¿†±ì ˜4…ÁÏ|í¼•¨‡Áà7¿‰~É¿¢-_NaýzJ±ñKþÕ7‚>ë ƒÑ(Ö1Ç Mš„ÞÚJiçNšn½­© <ÄYgž:‹=êω¶6ÚÚÚÆ]׹ᆂÏy ï–Û«:—~´²•< —\‚@é[&a 'WÆÙ#'-ƒCfCSöó/cfcˆ9G@Ý\­¥ÿ”Ñ(¡8 NF-ubö ¢95`%ÀÌ¡:½Ø=”4¡ÄfC< &$À}{;…M(4Ó/®¬‹@¾2µÙ‰Ü°‹b9K±Q'Ö¸&[j˜Z/léFnéÂvr䣠Ϙ­‡‚Ùz7ýP›†X?lëFv bç‡(†\Jè-Mˆƒ?Éè³ ’0ö{ ƒë–É›e\ "çþ ˜r°³ ÔP*!÷ âô'‘Âìœî‡®ÌémDæ/†d ¤‹ûâFÜ\E@Î-âx­$¹=æ’gC õ¼Am8B.S@.9û¥_‘nm$¼âbÊ™ Æ’PXŒR[G¶kíš!ô©W^¡þü‹óRxè; 5´Ró‘åx©éž&Ý~;v:³gcwD£Ä>ô!Ô¶6”D¥¿Ÿð9ç`rˆoY~8ÆAù1¸yóÍžíoŸ5 µ¦¦Ú{.4uêß”êûØc±iÓ&€ê¬€@@öe©ºÁÂ'ž8"›¸’Õ¤¤/= Nƒ)µÐPCáÕ^´f±ÐQi©øeŠb"`#BSÑ µf–?D%á@KžÒËiìbXÓ † q˜Ev¸Ù¢fİk4¸@´!ÅDœÍ[(‹˜‡} ÔF°2NCMjûµ]x;wQÞÛEäè3| ÷BhÄR0!ç‹Bs?t"wwãtí¦˜M¢43ô4ôA¬ÒC‚†½Ð—ÂÄÞÝI1—ÁÖÞŒ£aB#䆠a4tC©€ìØë J©D±w/C™„ôpB­4|èT¿wZ: ¢­XD‹Þ|“r6‹aÄ/¹ ¯k/ˆ2N_iÕ£L™B~ýzŸúC»wShj æc#ò°BDN=üš5èÇ}qʇq’IЉ”ÓÎ3äWØÿë¥þãüþ÷ÔÜpêÁã 9óLÌC!ÐfÍBTÚmm˜Ó¦UG'èä7hÃoT:,Z}ý8ñº¿žÿ÷ÇqæÌ™Ì:ßd÷îÝ(ŠBkkkp†þÉ-ac6«µõD/¸BªŸÝehÓæ£ÌoõíÑ„ˆ£ÒˆŠŠ$‹‚íûuLrÈ©QêçÁPŸßókŠ‚;#‡µèdOƒºZp[Àn»‰PѦ Ö áD2P›„¦Ùh3ÆĘy4ÁJBmóК…©äAý}}XDNXͳ 6b­Ðœƒ|¦ä`0É,êÀVO^o/‰ó?“çC1M¾hä ÉÁAiÈdQ3B{ö ’IÜX }ÉI‹A>M]0µßwgÍ@L!K%ŒžÌÎN(°Î:–~ØOÕîíAÔLDq=œdcæ,Ìréyè§ŸCêÙg Ï›‹èë#qÔ±èñ8Ñ#Ž@65>ýtŒ£F›1¡(x(­­ˆæf—_ŽqðÁ6o¦ñúëÑ=„À:ýtB•Ú$B!jV¬@è:ú„ è#¦ø‰½¤Ôøè®¾£º[¿KŒ´>®½öÚ 0þ^"þpˆëº|æ3ŸaãÆ£Ú P(8餓ÆàljÇãÁý'ÄËçñ6®G«·ü>\a Oâ}H²9ˆRÈ@o^ÝBaÀúòÈ @_ :z|u=‘•a¶ÔB¹¹¤†pöôQY„—,Ïö{‹9‹/"‡r”’IlÏ#vì±~ÐÚsöõ&³m(–¹ùdš››QU•«¯¾z̾555Ajï{- »víâG?úј7ä™gžaÛ¶mcà[ßúo½õK–,áÐCEUU¤”ضM4åK_úÒ¸OlŒóÍ6àEJ1øAbù­æ¸:@œ2 å {/”@™6Í_è] eÊÉúĉ£/)ýÅTÊq­¡ýúœü¥®šá曚¶o¨YÀ~øÃræ™g¢( 6l`Þ¼y•Óçñßÿýßcö?á„‚žXïµ€ÜxãÜyçïøÖ¬YC.—cùòå´··óàƒŽÙgûöí<úè£ÄãqV­Z5î7†O}êSÁ»ò¾¯Zðð—ËåX¶l/¾ø"_|1ßþö·ƒ“²¿ HWW»víâ˜cŽyÇT,ÿl¯}ÇqÈf³c¶¯X±‚éÓ§£( ±Ø¾–Ñ<ÿüó466Ž)¨««ãœsÎ ÞÅ€€÷9?þñ«uL©¤ìgÈ{Íã?Δ)S8òÈ#ÇÜ—ÍfÙ³gϘíëÖ­ã‘GaëÖ­|ä#©nïììdíÚµLœ8qÜÜðÚÚZŽ;î¸à]8€Èd2œyæ™üò—¿ä²Ë.ãþûïG}ö€€<ðÀ\xá…XAÕôH¶mÛÆ¶mÛX¶lYu[oo/[¶l³ïo~óžxâ b± ,`×®]Lž<™½{÷²cǦM›ÆUW]5æ¸D"Áܹsƒ«$ àÈO~òN­T«···3mÚ´à¤ì¯²e˶nÝÊòåËß÷xÿý÷“Ë叿škˆÇãd2î¾ûn"‘W^y%‘Hä€yÁ¶mó¥/}‰Ûn»öövÖ­[7fŸ›nº ×uilläø@u{{{;×_=F¤63yòdôý4{% à@¤P(°lÙ2^xáêëëyíµ×ÆìÓÐФóþƒUÒÞÞÎC=Dãp*!pÿý÷sÁ‰D¸ûù曹ûæškªârýõ×0/xÇŽLŸ>€éÓ§Woäì³Ï÷Ø“O>™³Ï>›7²qãFÀO{¾é¦›8ÿüóG]ÈÃñžÏ~ö³ÔÕÕy¼h4Šx‡ïh¬Y³†^xX,ÆÏþs~ö³ŸÙg``€T*ÀªU«F­_ï±€|ò“ŸäÉ'Ÿ¬nëî¥ð}‘ÿ‡ë>º»»¨¼k×..¿üò¿êØU«Vqâ‰'ŽÙ>^æ˜mÛÜ~ûí\tÑEÕÚ™b±XÝ~íµ×Ž[;³jÕªʪ x·øÂ¾ÀgœÁÂ… Y¸papRöW9ñÄÙ½{÷ûú'ïÆ±º®óÅ/~‘7Þxƒ©S§rñÅ ¥äæ›o³6›å–[nàË_þ2ýýýìÞ½›—^z €[o½uÜXÑW\¸ÎÞw<þøã¬[·Žúúúq ö3ÆÆFúûû±,«ZÕFÉår …À\ü3¬^½º*BˆqEÀ²¬1ÅP_þò—¹ûî»I&“ãšíÃóvìØQu…½ôÒKÕ̵;î¸cL¶Ê‚ ˜]ir°?ó•¯|ÏóX¶lGý{Þ}FÑ¿ñoðÖ[o188Hss3·Þz+¥R‰o|ã …êÌáÞÞ^î»ï>,ËâŠ+® æoKù~§³³“I“&½gÇnݺ•[o½•OúÓ£¶?ðÀlÞ¼™I“&Jذa©TŠÓO?}TÂÀ03gÎ z¢¼ç<úè£\rÉ%„Ãaž}öÙqÓüö3 8ðéêêâ‰'žø£3þW_}•þþ~¾÷½ïqúé§cY÷Ýw;vìàCU´ÕÑÑA±XdÅŠã~¨[[[ƒŒ˜€¿™E‹±~ýz–.]ÊóÏ?œ@@Þ yäŽ8âfÍšõŽŽó<µk×røá‡ÿÉýž~úiz{{GmûÍo~ã>Цi|ðƒdÆŒÕûÒé4®ërá…²hÑ¢1‹Å‚¾h£xê©§8÷ÜsÑuë®»ÇqÆìsÙe—ÑØØˆ¢(ÔÖÖ'-€•»îº‹•+WÒÜÜ<æ¾x€¾¾¾1Ûÿã?þƒ¾¾>Î:ë¬qc2_|1sæÌ Nî?…B¥K—òÊ+¯pÁðÈ#Œ»ßðu‹Å‚þy€¨¬]»–M›6qÁ¼£ã\×å»ßý. .dþüùÕí·ß~;ƒƒƒ£‚ÿk×®eÍš5̘1ƒ+¯¼rÌcM:•³Î:+x3ÞüèG?âŒ3Îü”û¿6~HÀ@.—# ýU½‰†ë‰þ’ç®A?½ùñÇgîܹ<ýôÓ˜¦9ªPóÍ7ßdݺuÌ;—K/½tÌãMš4)艶’Éd8ãŒ3X³f —_~9ÿó?ÿô¼ $ àïËwÞÉ%—\BSSÓ¸÷ïÝ»—žžž1Ûö³ŸqÏ=÷°xñâQ‰Û¶mcÇŽ,Z´ˆ‹.ºhÌq---R™ûðîñôÓOsÚi§AÇÝ…`&zÀEOOmmmT<š››ÇÇôööòãÿxŒ Èx Ú¯~õ+B¡‹/®Ž+سg}}}y䑜{î¹cŽ«¯¯§­­-x³Þ¡%ûõ¯€K/½4p]H@Àûƒ‡zˆÃ;¬*<¿ýíoÙ¼yó˜ýžzê)^yåfÍšÅâÊ8Ûd2I±XÆ/ì¶pþÙ( §œrJuÚàÊ•+Ç|Y°,+¨= $ àÀà«_ý*—]v ïè¸ööv}ôÑq;ôôôp×]wpÝu׺Ïu]TU­vøCÞoq)%Çs ¯½öÚ˜iƒ?üð˜´ñ¹sçrÊ)§f û?Ï<ǫ́Áe) …w”޼gÏn»í66oÞÌG1jûC=„aÕži# …B\{íµäù}òÉ'Y±buuu¬^½ºj½ðyî¹çPeTóNÇqH§Ócöݱc÷ÝwBjkkyýõ×Y¼x1ÝÝݬ^½šh4Ê¿øÅ1ÇE"Î;ï¼ýâõΟ?Ÿ7Þxƒ•+Wòï|'¸ økH§Óü×ýWµù;åÁäãÿ8¹\Ž]»v¹óæÍ<ðÀhš6ªcÀš5kÈårÔÕÕñÙÏ~vÌq‹/71áoåÑGåâ‹/&‹ñÌ3ÏM økÉf³äóù?™eö÷¦¯¯¯ýëãºéî¸ã™7oõõõÕíëׯ§\.sÙe—ÛIààƒþ‹j|,XÀƹð yøá‡ƒ à#Hã ؈F£Õ± ïO<ñW^yå¸Ó9?þøqyúé§I&“<ýôÓÕôfðgÖ qüñÇÁÎÎN<Ï㪫®ª>ÏsÏ=ÇÛo¿M8fåÊ•ìܹsÔs„Ãá`\D`ìϼüòË,Y²ä·{÷n<ÏcòäÉvßo~ó›”J¥êß?øÁ8óÌ3ùüç?ÏòåË9묳ػwï¨cr¹\µÚùçŸÿg}ð>'•Jqï½÷ò¹Ï}.88 + à=åÅ_wxÙ»Í#<ÂÚµkikkû“órî¸ãX²dIФ3°@ö'H$Ü{ï½tvvrê©§þÑXËߋիW£ë:K—.eÇŽ¬^½š«®ºj\ñøÄ'>A}}=ßÿþ÷™0aÇsLð¦ý”༗Ô××sï½÷röÙgsçwÒÑÑÁ›o¾ù®>g.—«&'ÔÔÔL&ÿ¨¸ g›Y–E>ŸÞ°@@ö':;;« '£Ñ(Ùl68)€ìvØalذT*ųÏ>;ªæåßþíßxã7X±bO=õ©TŠööö`*f ûK—.å¿øÅkäÝbÚ´i,[¶Œ{ƒ>˜E‹Uïkii©6¼<ꨣhmmåž{îáÜsÏ¥µµ5x³þA= àÂêÕ«ùùÏΪU«‚‚Á@@þ™\X€H@@@@Àû‘ÿt aW•yG IEND®B`‚snd-16.1/pix/sceq23.png0000644000076400007640000000166411147553270012755 0ustar bilbil‰PNG  IHDR¼%Ïþs3PLTEÿÿÿððð   ÀÀÀ°°°ÐÐÐPPPàààppp@@@ ```000€€€ýKxQ pHYs  šœtIME× ;„ÈãîIDATXÃÕ˜‹’ƒ E FÑÿÿÚñ Õ¶êîf¦vD½„“ ă&Åÿ5Ô·¿B!^å( FJþß.ž0t‘£\ŒƒÝ'ÞÀ,^ 2W9ªfÑÂíâ+NÛÁUâ­P—…hîŽy)ÔC!úµDRªB!5¢Q‚­)u”” ÃZ(4ëí÷¬òaŽBûÅm€nwDGÂù]€þ›«|þç÷¸ÕÚ0 âç_.ôƒ Å­])ÀRùGÌóÛ‡`ß»hµÖÿsµzª™?'"ÿÆfpkSÚ%ãür®éë$ ×ÝÅÚ­{?ÒÊ¢@ ¨”Ò!À²‰vžßÎÚžÖÉàRÓÄ’°ªË®—;Zy¯JïVãÈ*Sp@œ_–y]—[ü}°=Îï\@íH+X>¥§ŽóËGeßnßXŽ|ˆO)o~°g×ÎfX»‹yöv‡Ý¢97ÇÁ€whõnIƒ›°_½°nÇ æð³+´™V_Šß„}ØÝE24>'ø»cÞåÚyL$#J“_“ÇäíøŒøMØ{˜É€–Y †Õ_ÓuüOc"J“‘˜ý{–›^ ó²v3/ÆMÈÈ F7ÄÎòRKù,¤_(h"Jç/ˆùu¿ñ¼\¥— ¾DM5ÍâÓwQº (3i¦òݘÑ_pF<­³¥2A.„ÇpK˜(ôþW:¢tð‚˜K3õY7µ¯tfòd@_ÿWfNˆ¦2^¹©¥…¥Ë€=1çn*i¦ÎÖô KâAÚ°ƒ!Ò „Ó=<}O(숙$×OçÄ¢vÙ@©vÞÖ6—Î\ÒL¯üêRž=•J‰Ý Ó’GµÍ[åÛ¦›Jð4vSL*‰·í„«Û~[(<ÒM½ê¢Rö”i6Ú¹ù¨›:Áù{GyGÝÔ &ÌÚá—´uS¯º¨8LýÞ)êQ7õª‹ŠucCs}a7Æã*¸žž×wç1*]|øîãnjB/*‚xÐ OŸ~ÞMMÙ_Brÿß?üÜèÓ7ü7ñ>䫸Ĥ3œøÑIEND®B`‚snd-16.1/pix/vardpy.png0000644000076400007640000004022711147553271013161 0ustar bilbil‰PNG  IHDRúöpL  pHYs:ÊduhtIMEÖ'Î¾Ì IDATxÚíy|SUúÿŸ›µÙ“fkÒ½)JRVÙ”]TQÀQ±#Ž *£ ~Eä7*¢"ˆ€à *«ˆàвƒÐ–î{›´Išfß·›ßCè’„=-çýêÉíIrsî'ç>çœgÁ \õÊú´ä4@ b ³ÅŒpO†)Pè.tá®ðM›Ë›]R—ÙoFý‹ˆ)Z5­ÉXr%­2|3—ÕuìÛcpá.gÀ¾uî€;b3â&ã¸X ¢2~§Ëí¢Ÿ·T·˜›;¼¹^nSQS“¾ õ/"¦pY])½Rª~¯ê¬OΓdJˆÇ—änn6Ïš0Ë„›:~Óf?‘ï ¸Pÿ"n>Þf/SÎô‚·ƒÑÝêæbÜ„Þ ¾ÐÔd$ ª%¡®¼:Nl?ûpÕUý™úø½~‡Éz¤ø`±Y}Ñ\¬9^sèÿBÝx’…Y´¬´ÄŸØ+n߆ÒþP"%‘Ibg¨:ŸÎŒ£™¶´T·‡Ááqx#a@€ø/†a‡Ç¨42ùL@  Œ*£$SÀ S Wî+¼ØÉxௗ#a¨{ÃIË„¨}j{à²Á>‹SùTüâSy¢2ktVd¹3IÌ ­ã0:Œ*cbßDÔËmPÜ¡¨9^£¯×§ I+>X\}´:mpZÙOe‚$ŒybÌ©ÏN‘(¤Ä¾‰Újíñ­Ç™&“ÇüiíOl{àß»´úhõ…ï/PÔ÷(ú®ÈeueÜ‘Ñÿîþ¨‡;ìtíi¿Ï/J]ék;»Ñn¬€Å‹ç'$H¯î­|>W0ªæZå—ÝK­Öœ8qÚl¶ =º`ˆkËÎÎ$‘H\ô¢«®®ª®®ºŠ7jhPNš4žËå\·©*NKOOÍÈHÿùç?„B¡Óér8ì7­c¼^ŸÃüÒ®,ƒB‰SsРTêuðÆ-))Ãqüº3@"Q5]CCã¸qcI$Rkk«L&«©©¾9ý¢Ñè\.—ËEz½ìv;‰Dâp˜·y?P"FP\\Ï<¸ß¢EKÎ&À`0ØlÎÍ1ßSSS¥R)’ìµ`4]®.`‚–””UTTϘq÷­‘»Ëå¦Ñ())I—ßÙ|>?>^ˆf«ˆëKzzêUÏY¯ËT•Œãxyy•D"òù|ÄAÇ-³Ù|óö•œNçŽ; ƃ>ˆ4Ñm¨¬¬Þ²å3J%óçÿƒËå¼ñÆ;T*å•W^€C‡~þᇟF޼ãÌ™sK–,4 çΕ—WÀ¬Yïß?çúËB¡ääô6M--:Çó×UbÔo¿ÝwÿýÓ¯K¿0Œììììììÿýï°råJ.—»mÛ¶óçÏ@~~¾B¡Ø¿ÿO?ý³gÏ6lÒSŒ³}ûW¯¾º tºV“ÉÌår^{íåeËVü5mkY¸pî¶m_®^½bÙ²S¦Lhhh\½z,[¶â†È@(I$²™3g&%ɵZ­J¥ŒæUgΜ»^r«ÕúÕW_9’Ðq~~þœ9sh4Úºu눧¯¼òJAAAð)’{ìó O¯Y³–U|pFÄöÄÔñ3†™ÍŽæfµÉdP*l6³×ëU(2£Y™±X¬ï¼³^«m ãçÍ{¸¡A¹sçn`±˜>:ÛívúéW7##-55yâÄñðò˯I¥âüüEíßÍëõwÊÊÊ‚·hll4/¥Ôëõ*• ‰)öùᇟòòú€N§7™Ìðý÷‡ëê~üñ×»îúÑ&'';Ø~ÇŽÝ~¿ÒÒRnˆÜ].CC}jjR¯^Ÿ|ò9ñ󪩩æp8"‘¸®®6¬!Dž=ûïR©dÿþƒååU{÷xä‘YP]]ûÇÇ[ZZŸ|r¡T*^¶lÅÂ…s‰—Ì;‡N§uö†wÞyçöíÛ¿øâ‹ììl‰”ýÇäç秤¤P('‹óóó…B!Ž<4»÷Ü3åÌ™óÄ •u|¼ ?¡I“Æs8ìÞ½{ÀãÿS©lº÷Þ©ñññ0~üØ"wÇE&cl6ërÛFÈåò f¤inœP|Šã‚‚‹>6wÜ1Äb±®[·Áï÷‡þRSS“ÂøNH$’W_}•é_|ñE‡óì³Ï€Ïç{þùç©TêO4mĈËH 68øX*•„®Ø47«™LF›ö×Yî“Åb\ “É6›-h-èõ‘q[[õo¿ýFõz}3gÞ7vìˆêêZ‹E EúÑ£'E¢x ÃBwÅ–.}I.Oxùåg;:‰DÚ¾}{ss³Ûí^¹r%ìß¿¿¤¤Äëõ>óÌ3ðÇ;vÌï÷Ï;‰©›1bÄu˜ŒEžª¦¦&'&Ê</“ye{rk×®8®¸8:ŸÏKIIÒju@ì—––Oœ8>>>Þét®]ûáÓO?«V½B&wOH¥R1 ›2eŠ×ëe³ÙÄÉŒ5jРA ƒÏç@nnnff&•J‰P^˘¦¡AÙÙ…¾¡D–;†‘²ßï_´h‡ÃV©”--ÚàHÂq'¸ÿaXBÂ¥ÛÓÔ©6mÚær¹)JÐvçñ:vp:çΫ­­}衇Bóù|BèÁ;‡ÃAbŠy{ö|Çf³m6›ÍÖéZ33Óãââ®âþF”;©¾¾Ùd20´]»¾MOO©4Án··±C®”ÄDùŠ/FÙ˜Á`,Z´ɤÛpøð/ãÆþùç#ãÇyÿý~ùe_Ÿ>½oÂçF¸¡8»ÝÜ¿vVVfkëE{]«Õðù‚ììtÙ]‹ˆ£»×ëõêõF¡P²2#b07͉ÀjµÒh4t©®»ÝNFqfåÎd2ÒÓS5meeU0¼#—}H„>Þ%¼ùb2h4”í9Š©*—Ëár9†íܹ‡F£ùý~bgëæ@§ÓЖâæÉL¦êõ¦¦&Í‚ó@­n ¨ïÝMî8.3™´Œ ùóÏ¿š›Û¨T*Fc0f3ªÈ‡èJDX™q:=d2(é Ã뽘 ÃH 99u¢[ÉJÅÜnwmm½ÇsÉ!‘F£y<Þ¦&%ê>D·2fh4ê€ý´Z]QQ‰Õzq'Õf³ÆÈÙûýþÊJ4‹¸ˆD|±8MUd²¹UUU¯¼òJðéljD$Q°Û¡é£fμ¯±QZ‡ÈÿAä˜o×ë]·nݬY³>úè£õë×AGŽÑëõ3fÌ›ÍVVV"‘(==Ýëõúàp8½zõ€sçÎùý~Ö¿ðx<÷ßðý,XPQQFÊ'Ož\·nÝ;#ãxSS“T*-**’H$©©©n·»¨¨x<^VVœ9sRRR0 “H$PYYÉçó‰ÇmŸ~ú©Çã þØ8 ÕjY,lܸñÙgŸåp8«W¯–ËåmÞáÝwß}àRRR>üÝwß †ÜÜÜùóç—––nܸññÇGro«y&“Í`p.|L(ŒW©” ÁKa Œ¯ˆp N?qâ¸3gΞøN§Ëf³·¶êu:=FÅq\£ÑNœ8^©TmÚ´í«¯¶tö†üq|Ë–Ï÷ìù¼³ùVkkkUU•Ñh´X,ñññGÕjµ3gÎ$|ôÑGb±š››zè¡Ã‡!Äü»²²ÒápÉd¯×«Óéî¼óκººÍ›7ïÞ½;š~4™Ln·Ûb±,]º~þù碢¢¼¼¼üqÞ¼y»wïf³Ù ×ëN'!}ؾ}{Ïž=—,Y/½ôÒ¤I“,XÐþ{}ùå—}úô ²8p€J¥N˜0áØ±c`6›y<1koóihhHII‰DrîÜ9­V;aÂHNN&2ö ¹_6º«Õz­Vãóy>,—'@ZZzCC}Ä·®­­'’àìß°¥¥•Ïç—€D"4hÀ;ײַ=û©Tl?~ü˜ü5¬Å2eúô)þËçó9N“ÉÔÐÐ`6›‰`+"^&ئ¾¾žiݺu«Á`àñxåååÄ›››»cÇŽÿüç?¡ŠÓ¦M‹Þ z÷Ýw ¶lÙòôÓO@bb¢X,ž6mÚéÓ§©TêñãÇ{ôèAH={özôèU«VMœ8±¥¥¥¹¹yáÂ…È"¿nrw8|z}KŸ>Y eÓ¦m‰‰2hh¨çóù2™¼¬ì Ìw™L:lØ ¨¬¬þ曽¡J-/¯ÊɉÌÒØ¨ª®®7nt‡r'‘Hƒ š?~kk+¡­ÜÜ\ …²iÓ¦Ç{¬ýKÒÓÓÇgϞݿè"O]]]vvöõ㫯¾ª×ë ­‡2dȆY¼x1q„Ë僑››[PP››[[[«P(D"QIIIBBBaa!a³!¹_Ç=8Ž»\n6ûRK¡PÈb±ÃLÚf̸›H€–˜(;vTK‹nÍšw S~Á‚G¼^߇nv¹\ å‰'æÀ† [”JÕ²e+–/ŽÍfíܹûÂ…’Õ«ßÎÏ<%%ª«kwíÚסÜ€D"ýë_ÿJHHx饗‚yfrrràðáÃ&L¸÷Þ{óóó@¡PdeeÕÔÔé $ÉâÅ‹sss—/_îóù˜L&ÑlõêÕ ùùùo½õ•Jýøã«ªªž}öÙ—^zI&“µ?ÔÔKND</èbsçÎ%>+;;{Ñ¢EÏ<ó ñ™™™$ÒÅÕ‚={öŒ9²½ÜÉd2iž’’Bì0O-Kzz:<ñÄ~øakkëÒ¥K‰‹Ïç{÷Ýwïºë.ƒ1wîÜO>ùdË–-÷ÜsϘ1cˆÊÏÏ1bÄm˜p+pœržrœU¿W½yç §m©®U£ÑÚlöuë6ÞyçØv×8y„ñZ­M§Ó÷è!»Éµ™<¯Je8p`ii©^¯5jT×êýªªªC‡¶û-Äï÷××WÆÇßðìïDm¦ÆÆš·ß^ŒU}çõ7.Võĉ30šQå­vš'¶Ÿˆ_@§Ó8•J‘Ëe ‹RRRu:-›ÍM¸…@Ü4"Ü\ü~8w®ÐdÒçäôØ´éã?ÿ<«R)êi4º@®r•T*Áq?‰ti?Ëåa. £Üc;tèÐk¯½ÖÙßÿýüüü÷ß]BÄuÝ].•JÊÈH¿'Òh4>_ ‰ÛÏV d2™Åb‰DÜР2™Äá°†a"‘0b~É_ýU­V‡¦Y eãÆãÆ[²dIh’r¯×{âĉMI"ÏuJKK9Nrr„ò;µµµ~¿ŸÈ·ž³gÏfddÃpá¡P(—ËÃ7«ªª"“Éá›)•J«Õ1™«N§S*•yyyá›Y­Ö . >ü6Ýi4ÌëõVW×:Çÿ2oÈN§³³ì.†±ÙlbIžD"±XL¿ßO§Çµ´´žúèðá×>~ûí·Ï?ÿü×_ ߬¢¢bûöí;vì¸Fw*•Ú¿ŽN×ZUUÌ~‰]&“›L—2sH$b‡ÃÉ`0äòD¹<ñ/5Görss¯´=F -¶óçÏ_¿~ý¶mÛ¿ðäÉ“cÇŽýóÏ?£©Jr×]w ´©©©™4iQ)$ &33³²²2|3‹ÅÂãñœNgøœm~¿ßãñ¤¤¤D,Z__?vìØúúúˆ_¶OŸ>m6D»ùèþ—!.8pàÔ©S³³s¤Ò„ïH"\ýs»ÝT*•Åbx¼&Sk˜™n>ûì³––ÈËË;þ<1@F¼)¿ð o¾ùfÄ7_¹reh%¦ö¨T*‰D2tèÐK …RYY9a„ºº•JU*URRRÄ+++ëÝ»wNNÎ… Â4;}úôàÁƒÓÒÒ"êX©TN:µ°°0|³/¾øâ‰'ž “ɺvW¹c‡·ªªþر>ŸG«ÕX­Öðžîç¾ûî ý#ÊüþÇñЊK²víÚ—_~¹¢¢"???¨›¯¿þºµµî¾ûn‡Ã‘ŸŸïp8î¾ûîˆ7¨hJëP©Ôð3 bâMŸâ8Íó… ˆôóm±cÇN˜0!|)‘o¾ùæïÿ{^^Þ¹sç"_u)hšv†Ïç£P(Ä¿]ŒÇ_]]•”$S(’·nýtðà<¨©©f±ØB¡°Có=..®®®&ôˆ^oêÑãÊbAÚ—Á¢jÁôéÓ§OŸ~]ºÀéte¨Tª×ë¥R©M݈úJ ÃårµÙ*b6›‰"JD©â%a˜7oÞ–-[Â[Gב]»v…ÙÂsôèÑ‘#GÞv ‘D]ÕøøËÜ¿âãã% —ËëßÍf{½Þ0ÓÐL:²³³Ã˜ª6lX´hLœ81XP©=ÿýï_}õUX°`ÁÇÜY³cÇŽžƒýû÷V&ëÐ’¹Ò²9' D™ÁI“&…ù*•ŠX§ºóÎ;þùçÛEîl6ƒN§?_TQQœ*Ɔ†úÒÒâÎnú*Usè_pó–Àd2}>_¬eO8wîÜÀ#6«®®V(WôÎÿüç?‰ZNá5jTh•ÖÎ>|8Qßï¶0f0 S(Ò].·Ãá ÑhAA‡±çÊËKÛX®¡åõWM||¼Ñh:p´¶ÛíA«‰B¡DYøö6$òŒ Ã0-ŽÃ,\¸pô豊`¡¯q¹\ F\è_ðwƒØív¢/°X¬hܘétºËåŠf9K§ÓEœbº{†¼¼¼6ÁƒÔÕÕeÉÂãr¹œNg°>kx›§gÏž·Ü1Œ¤R銊ŠËÊJ¾ÿþÀï¿ÿV[[#KºÍ÷ß±cG°ÝC=ôÕW_uج¦¦&3óâl{ĈÝß ŸÏ'pX,V˜•òÖÖÖ`™&“ys¢|>ŸÏç#&Ùt:F£Y­éõúà–pjjj·)81¼Ãc6ëûõëM"‘Ö¯ÿ˜pcT©”@.O,))ŽÁ¯´{÷nb«%¢«Bô466µ§Ãc6›9N4«™%7 F¥R‡Ã ßR&“577Góõ»¼ÜqÜëóùl6;—{©S„B“ÉŒÙÂLýúõs:„KÉÈȨ­­ÍÍÍEÆ+²ÝÃÁb1’’äJeShõ½¾U©l¼ºÑ›€B¡ÈÉÉÉÉÉ Ž²ÄÚvÌ^‡Ó™QZÛšÁ`?ãö>|ø®»î Ú•Ý î „‡p[¸M§ªññ‚>}zÝqÇÛý¾sssD‡ÄöŒ3æÈ‘#›MŸ>}ß¾}›…ù5¶´´H$gJ„»N‡ÍêëëÓÒÒˆÇ\.·3w£7ß|óùçŸx>ï¾û.QÔ;‡C¬»Yî$ÅjuÕÔ4-]ú4±2#“É»ÜCõ†}ûö…nâ<øìٳ훭[·.T(ûÛß~ùå—˜ýî ˆÆã GÕÕí²ª?]04)’펕”T¨ÕMññ¬ 6+3f³‰B¡DÜïNøýþh& ~¿¿ EßNJÇ¢ IDATž<ùàÁƒ› <øôéÓ·…1ãtz_V–B à;›=@ HKËèBß“F£E³Pss¦àƒ!bäâÈBÁN'‘2e€FÓÜ…¾gß¾}‹‹#/›F9à]#+V¬X±bEÄf¿ÿþû˜1cFožÜétz^^*•º2c6›u:á‹‹ŸÏM˜ØÉÉÉ탤þüóÏ6Þü .Ü´iS›f{÷î½çž{B¬Zµêå—_³Èǃã8á"z;®Ì`–˜˜8räˆáÃïHNNáó»Or¼µk×.]º4b³¯¿þú="“Ét:]g¡´¡H¥R"$%<á1C– Híýa@›y™Lî°Y4þúN§Óï÷·™˜Éd2µZ}[ÈÝï¥RsâÄ™ÌÌ …L"aݦAKKKĨm0™Lmv@‰‘î÷žñãÇw7àr÷zÅÅ%dr`Èܽ{÷×ÕÕ †êê*ƒ)“É­‚èZDp"p»ÝT*E&»¬„*Çãñø<?¦npv»ýÅ_ls_>îÙ³gyyyÄÀÖÑ£G?ýôÓmB¼£$³ÙÜeö,Nxး8 R!dKa%Ž7uæ{útÆñãƣźܙL‰„— ¼`„„Óét»Ý--Ú˜ú&,kݺu¡G¶oß|@ 4‘/…Â[‰suŒ3&šØû™3gîܹ3b3±XÜfÿèäÉ“Á2aØ¿ÄTP°iÓ¦ ´?. CÓz™L¦]Ø£ÜÍ5jÔü±YVVVÄä~ÝAîl6C(”–Vœýøã{ì±öÍüñ7F<"0/b³(<]Þv™,A&KÝ,¼ã7ÞX»vmìœOÿþýüñÇn™»«ËŒî@"‘].ŸNg~òÉÅDxGÄü½]‚ès>v4MBBÂõ|Ç÷Þƒ+LÑÜ%Fw¬ªªÞårp¹ìÏ>û,++‚x‰D¡P®c¨ÿuD¥R{mr¼ÄÅÅE“†B¡à8ü1èõz‘¨ãò€)))Á aöJ|æÌ™6µEo2Qæ|¬®®Ž¦XƒÕjÅ 6“Ùåäatw8¼n·£OŸžÉɉAÛÝh4ðxü¬¬^±ù•Ž;vàÀ´Ùg8p`‡wmJ¥f³9øÃX³fMgñDÒSâq˜-[‰DœÔÙ«#žC› Ñ«#33³ƒ »v :4¬æG @ såŽíÂrÇ0ŸÛíÖhZ._1ŒÎÊMÞr|ðÁüüüüüüÌ^ÖÐÐÐá<µ a²ÐÐh4™LFä9r»ÝZ­¶3GÄÄĦ¦¦ˆŸÕ»w`ذa§NêæSU#®wï,µZÛ&ñšô ºçT5...##møð;zöÌâóùÝ#Î%˜ÓýZàñxÑTÔ‰2þ5111´Øôõ¥¸¸8šÒ ‹%bR1èʱ¶‘åN&Ót:óéÓç§Nœ’’Êç ºnxÇĉ‰gÏž4hPgÍ‚ùaL&‹ÅêÌH5kÖ—_~´¶;[úˆr+'Ê„¬Ñºî^ A'ÐÝ»wwVŽÉdbFœá{ï½÷ÔSOuC¹ûýpöì9›Í4xp¿Í›·ªÕÍÕÕUt:](u¹o;hРhf«Á¤æ6›-...72ƒÁÍNó÷ß?yòäˆÍÖ¯_¿xñâkü²3fÌøöÛo#6‹²¾ áÜÍÒV–»Ëå¦Ó©ii)—ÿÐYB¡°;%Wꢔ——G³ÎƒˆVît:Ùï÷WVV›ÍŸïR´¯Õj­¯¯»¡gVWWŸÑ†ƒæçç_u’ ›ÍÞH¥Óén·Ûh4†7R‰µÈˆÎa÷Þ{ïž={"žU”;ÿ÷ß?1loÞ¼9š¢N;wî &õÑ#GÂçù …ƒ!Xî¦ÊB¡ôí›-Æ755‡D39¬V«Íf½q§ÕØØ¸uëÖΖ<ˆaغuë0 »:ÅHmmmøbÓ¦Mûî»ï4Møøã%K–¼÷Þ{&“©ë&L*¼C,–ôë—;cÆ}¹¹‚¥€o(gÏžý÷¿ÿÝÙ‰¢påùܤR©Ýnï,ÝîƒÇãY,–¢¢"¢æf˜É%‡Ã)((ˆXŠ#99¹   X¡3rrr"Ñ€aÆ>~Æ kAfeemذ!b¤ùСCßÿýøøøð{´l6›N§>|8bÅúÜÜÜ•+WvÝÊñ3øëëëRR³²Ò>ùä³`]U6›#‰:4ßéô¸6fq\\äîÿû¿ÿ‹Ø¦ºº:11‘Á`ê!<¿ƒ-f"X²d —ÛÖ‘ó—_~ùý÷ß#.0Ÿ8qB¡PD¬1_PPpöìÙˆiX***À¯¿þÑŠ+//?{öì[o½¦™N§;þ|vvvøµ›ÍvüøñôôôˆëQµµµ6›­M6²ö¨ÕêÆÆÆˆ™úôéóöÛow=¹{<.2™Zºƒ˜²ðx<&³ã*;»O|üe¶Ýî€úúâçáv»ûôéþs×®][^^^PP`2™–.]JÜÜG޹wïÞ¡C‡>ùä“ï¼óÎû￟žžLÖ>A¿~ý:tbëð¢îÝ»wÒ¤I¡¹$Ú7Û½{÷´iÓÚ,Ç6Óëõ………ãÆ óÕZZZJKKÇŽ¦Í×_^y………£F _-ìüùól6{Μ9á?¨M‚´6|ÿý÷£G¾ÒlÏ×Ùûò¦ÉÃa2qçÎÒét›Í¼¨¡5íF»sC† 6›/FX,‘HB£Ñø|An® 8ÿ¹f) ½‹&Ù]øYf”Jåã?Î ëåWWW·hÑ¢0…ëêêØlvø%óêêꃆoS^^¾ÁÞ½{9NøßÕ·ß~+‰ÂOŽ#~Pkkë¼yó:ó í~¶;¤§§&&ÊÝn7ƒÍ;›ÍN"‘7Z‡Ã d2™Íføý>°Ùì­­: ¶J[õêÕëÚS³3™ÌŒŒyÀY,VD/±ˆþ U©¿""~PVVV,× ½þrÇ0‰D%“±E‹çr¹*•R£Q‡w±Z-|>ßãq»ÝŸÏ‡a˜Ëå²ÙìT* ûöíkñè£^û›H¥Òˆæ¯L&‹«ºpáˆsÐëò­#~ÐC=t­Ì`©±Q­×·Ò锽{÷¤¦¦€L&w8anÙív"^Øh4oýºoßþ¿ÿ~„ÉìªNf]¨2H¤Û'\ëúÈÝn÷X­¦ÜÜ>ÐÒÒJÈ]­nⓊ‹‹:_°[,·ÛM¡\´†q/,<ߥ^W¯^݅ζ3g/$÷0x½^¯Ñhø!+3"&“aµZÚ·f0'N R|>±M&“›››rs/0 u="æäÎd2RS“5myyehxGg 3"‘ðÎ;Gµ?ž–†²c#ºÂT•Ïçñù<øüó¯I$R è®iüq_³fÝnÿïÿÛ¾Î^ ؽ{÷o¿ýöüóÏ'%%ùýþçž{ÎçóÅÇÇ¿òÊ+ðÆoyßzë­®ljäNÌϨƒE­Ö.Yò$477y½^•JÙýúbÍš5<ò‹Åzíµ×^~ùå6~»wïŽ_·nݺuë¦L™²aÆիWÓh´†††µk×2Œ3fî¸ùùùm6¼®;›6mš8q"‘qÓ÷HVTT¢Ó©“’Ä~øá±cÔÕÕêt-T*µýæ|W‡¨ ÍãñœNgûºK¿ýö±Jø]½üòËT*U§ÓíÙ³'t?«¸¸ø*î~Z­6šN.\ œ>}º{¤õŠ-¹;n dff°Ù,·Û¼é ñ))i¾ÃH$¹Í@w[&“iÇŽsæÌár¹Ó§Oÿì³Ïòóó?ÞáòŸF£)))ihhðx<%%%Æf³•”” ƒÁ0gΜ={ö ½^_RRô|®ªª FôíÚµkþüù¥¥¥z½þé§ŸV(jµº¤¤ÄëõÖ××F¨¬¬ ¶¯¬¬,))!Ž#¢’;• .—«®®Áï¿”¢(.Žá÷ûš›U¼„A"QCÿŒF‹Åb þT6lØòÊ+«Ú—†»õ}Ñnf‚^þÁrv8Ž“H$ŸÏ÷þûïÏ™3‡Ø`OLL|ýõ××­[7oÞ¼öÞ‘jµzòäÉüñǃ>xòäɧžzjÕªUƒáÁüâ‹/šššŠŠŠJJJššš¦OŸ¾gÏžG}ôÈ‘#0mÚ´ kî©S§T*Õ±cÇT*ÕèÑ£O:UVV–““óý÷ßÿío{à:4tèÐgŸ}¾ÿþûÇ|ÇŽ³fÍŠÁ®ŽQÛF£ååõ×h´gÏž:èv¸ŠÏwYD£Ñ¨§Óé\.¾ûî‡~ýrþñ‡V­zëµ×VÄT_Ìž=ûÍ7ß$‘H'N$ò455%'';θ¸¸W_}õõ×_g2™`þüùÏ>û¬X,Þ¼y3Œ;vРA[·nÕëõV«õÿû_›w~ì±ÇæÎ»hÑ¢´´´ùóçáª)))DŠ˜¾}ûr¹Ü)S¦äää >|„ Û·o/))3fLEÅ¥¼³#FŒøî»ïˆ¨„ÏÖˆ#@©Tîß¿À€K—.ݼyóŠ+œNçÔ©S—/_ÎårFãòåËC³¨"¹G@&“'&&•edd˜Í¦0þaQÂd2þõ¯E±ÖC† IIIÁq\.—ÿõÅe ÄÆ0ŸÏÏÏÏ·X,DÈO¨ƒ>”=iÒ$¯×+Ú¯êD×ëýñǯȣðž{î1›Í eêÔ©»ví Ÿ>}ºT*9sf÷›eÝ(cóxðúzÕñã§D"¡Çãöù|Wxã·ßŽ~þù×7nýóςؼ A­LJJJÐçóù)))Ä"#ñ˜€p—ÉdÁÇíÆ áΩV«‰_ a¦sîÿjnn~÷Ýwóòò‚éþ*++CÛ¸Ýn½^±(†aR©ô“O>a±Xƒ!š´ht'¼¬¬\&:`Ñ¢¥Dx‘}E D““-”±cGZ,‘H4hЀ۪—ßzë­™3gæçç_¸páóÏ?W*•ãÇv»}Ïž=K–,™={ö²eË4ͬY³–/_N„r/^¼xúôé|ðÁøñã ÿþ,kÖ¬YcÇŽu8»wïÖh4qqq»ví2›Íd2yß¾}{öìÑëõçÏŸ?tèÐĉËËË ÅG}„„•ÜÝn•J–H. ³çó<Ëå]©Üo[¸\î?ü|JÌB¬\¹råÊ•í_©ššZXXH<~饗‚ó â±Õ5}úôе ÔóW&w&“N¡‹ŠJ¸\N0¥ŽÝns8ìjus'óT/?âÏɹ˜宻ƑÉ$ÔïˆX”;‰DÊÊÊ´Ûí‹58k“Hº 8î¹ãŽNK·E#‚@ܲ•6›Çá,X ‹T*e}}]›JWG ÝÕýÑÙ5i¹c¦ÕÕjµÛíüå—Ÿ¤‘¡¨««½öÏöz&S#’ÀíƒÃáŽi¹;>NÓ»·‚F£mÙò©L–uuµ<_&“•——]—“Ðë :ÊßÍ!*Å´Üq܃ã¸Ïç Ï …l6;¼E”•UhµºàÞ{\\œX,Ñét.—óæ÷HJJóÆWjjj²ZÍÝUÙ E£QoµZƒžvR©,ü¦"ÈÅbH$⪪‡ÃZWõÚ7VÛÀáph4…B–JŒ8­Vc2™¤Ò[P„Z*•¸Ýöý)uuµ Ezw•»X,f³é8.—»µU‡ã¸T*mSŒ:F§ªR©˜Ý¶m_Þ¸ó`2™"‘Ãa{' 0  ZFFFp ìr'‘(6›Óh4çç?E¥RU*¥ÅbimÕ]ßó`±Øðxл^¯Ûn·z<>y¬Ë=À**j|>@Àݺuk¯^YÀãñÈd2•Jí°–ƒÝnw¹Ú¦ªãr9Tj¸Ïjnn¢ÑhLfœ@ @kóݛͮR5‘Éä=b"X9‚ÜN¯×ëÊÎî VëE_%‹Å"ÄËå‰&Þ(((ÁÙ—JÑú|Þㇾú÷3‹ÂGoR©T*•âñxUª& …Âf³nÝ]®ã,ü¶µdÜnR©r¹Ü;vN,⮪Ïår57«åòK¿N@@£ÑtºŽƒÍ0&ËÈ%û}¾gæÝ=}ú4&“…ãÞ0$—'…fÓh4½zõb±nAOÑhô²2õþ”¾}ûuÑâuQn·?==3äöÎër‹‹ËÉÉV«5¡uU C˜—à~|õK‹ÔªúgW¾ÿÞÏ7«êîœö€6mÚvÏ=S%‘ÃáܸqëÒ¥‹ÿZê1îÝ{0è¤Àd29®VÛµ=œD"qôV™Z­îN·¢R]só%B÷ÜsKºÀT•F£¦¥¥¦§§ÿöÛq±Xìp8ív[¸` 'ìÛ¹å_LjQ«vþRÆåÅ´€ÝîÀqÿÆ[~øÁP7nÇy<…Ba0˜ñññÞÔÔ,ðºô%ÏË`4Fµ\«Õ¶°XŒk ‰5„BQZZš\.Õh4.—Ëï÷çäô#“)^¯'ÖåŽaFר¨9r™LÒëõ aªwH¤Ç–®ðù¼Û>|“ÅâȓӉ¡ý/SÞßРl?’‘HäÔÔ4 â·ÔÒÒ"•Jºô%Çq<˜õ;<--Z‰L§wŸD»àr9-³P( ×·^ì ”»ÏÅÅ…B!ðà~Áð­VÃ`08ngæ;<ñÜë &[ ¼lŸhȼ/¾øú¾û¦mܸuäÈ;Bÿ5xðÆÆ:@t/œNf·;º†Ü].7FIN¾¬ü›ÍæóA|‡r ã³âðÚ‹ |^a$A÷ã0|øÐ¾}ûp8ì^½²ÚLØÏ;kµÚ>‘± Ñ]äî²Ùl]Fîqq”@//¯‹EAÿ¿ßo2;K`’•¥À½À¨À½–P_aBåí§¼^/›Í"ë…Âøn+Çñ`º‘ˆcÊMðÒ¹éÆŒ[­Öb`Æb1»†Ü)rŸ>½F“N§÷z}}“ë\)œB¡äå ®cx<ž””´.ø|Í–MË””4ׂ¼èô8·ÛZâ†HÖÐVfˆ‰¶D"{è¡“’äF©¼ÎNêwß=©[ÞÊ èˆX"rx‡ÉdonV›ÍÆÚÚj“IO$ÞèpeÆfs¢8TDÜn_LËÝåò+• ©©É½{+>ùäó`]U‡#KjkkB«Õ(I'¢+î ð6Õ”„B!—Ë ÝóoiQ×ÔÔ Þ¼%¤¥e†¯†Ò>›ñ …D"Ål«ÈuU9vaa1†aA±öá6›E§CYMn ÉÉa*Ôû|¾#GŽ„/}‘ËåB¡°KÊRR’är™Ïçå$DûµÃ¥L§ÓéóùÄbqß¾}oÚÉ…ÂÐÑN§³(w¹c)ÀÝnxâ‰'Øl–J¥ÔéZ¬V+Yì@&“ÉdrUÆ@ оpuu5…B‰XÊøº@§Óív»Õjí* ‘X}}“Ùlb0èß|óuFFH$R›ÍF"‘PâðÁëõú|¾6û!­­­ÉÉÉ¡îI@àØ±c&“ÉçóÆnx¦N …B¡Pl6[ŒÈ=º¡ÃáµÛ-ýúõîÑ#C¯7ü51Õòù‚Þ½û ŇƒÈIÔzû¬Ù.—«¤¤dÚ´i÷Þ{/Q.á†Â`0ˆêê2™L§Óu¹x½^Ok«árãLÄb1£t÷CÜŽãDnn"7…B¹…çƒaŽãÄ™Éd‰t]2ÏÝXc†Éddd¤«ÕÚªªêкªH^1Q·Ùëõ:&“yk+ÄS(” ­‹aƒÁp:,ëÖvQäMP‡••9|øP¹\F§ÇÝÚ1¿ßO,xro߀F£q8­V[__OÔɹqC;™L60™L§ÓyËS‚FSW•ÖÚjT©šçÎ}45†a õH^±©x¥RITnêpgöìÙ_~ù%ƒÁ¸ÿþûo肌Z­n“þßd2õéÓçÖÎY)‘º.\(b2ã²²Rþýïåô#îS4Éd¢Òž1¸D#“ÉÂßgÍšu£OÃívs¹Üöw˜ö«¢±%w—ËC&c E„¤u'“É|¾@,– ¹Ç ±`mb+ æ:'ü¿©TÌãñÔÔÔ%%Ƀ3k*•êñ¸U*”«º €a‡Ã‰Ù]ýØ’;FÍÍíÛÒ¢+))÷ûýyyý/ÿ*„ ÜBÔêF2™~Ì*(8;'l±˜cTî‰X"çæöÛ±cWeeµÃá¤^žÌçó¡VDôˆDÂØ•;ÁSO-€>øX¥jêê‘udÌDƒA/((r:Ýh q-¦X—û¼yÿ˜7ï÷Ý7‡N§çæöE× ÑG÷ ¿þúûï¿C=ˆ¸Fnf°ÕUÊýÿý¿×‚ÁMÄ5’‘‘ÓrÏÌÌ@ Ñå@y2Hî’;äŽ@ ¹#Hî’;äŽ@ ¹#Hî’;äŽ@rG ܈®ÏeÀv»C¯×¢NAtË=Àü~2ê#D·!À:ÝÙl&B}„è6462íŽ@SUÉ@rG º( Øð知¥å14V‘Èsæ<€® ’û aß¾ïï»ïî6é`o!ëÖm@rGr¿ôîݳ°°Øï÷ÝêÁ²³{ |tEÜo,~¿ïŽ;†ÜÚs “i(¡>’ûÍZ1ÎÆñ[Ò>h4‰í"¹ßÔ1Þëõ:oþçâ8^]]‰ä~•“{Ô$w3ˆv<ùä³FŽ6mÚ$8yòLIIùüùÿˆÒñÅÿ>÷\¾P:É=ÖápØ«W¯€ï¾ûáèÑ“#Góz}C† 68sæ¼Óé€Ñ£‡ ¦ââR…"½¦¦nðà<#®¦¦~Ê” ,ÖÅŠ»MMÍ55õ™™!—'èõ†’’rHJ’gd¤¡ÞFÆL¬Àf³m6Øl¶>ÚJüñÇ_kjêl6›ÍfÛ·ïàùó…ǎܲåS›Í¶mÛàv»¿ýv¯Z­%Fú-[>'ïÚµ¶n½øô§Ÿ~»ù•ŒÜ‘™<ù.‹E}zeg÷ ¾–N§‰ûÇ%ž¦¤$¡M%dÌÄJ¥*//·mÿR¨K–<Æáp`ùòÿ7ntø75jøÀ¹ðê««† ˜““ý裳`Ó¦O”ʦääDÔÏHî·¡0~Ù²ððÃöéÓ ^zieK‹nÍšwŸþ_2™ä÷˜ÍXºtqS“žyæIø«àϾ}ߟ;WXYYýøãÿÌÊÊT«5¯¼ò:·›xÚ§Oï„ êm$÷[ÌsÏå·9²jÕ+ÁÇ|>ÿÅŸ >•J/IvÁ‚G`úô)Ó§O œ1ãî3î>3fä˜1#Q'#Û@rG Â3f‹¹UÓê¸]VêŽè1›-FcëÍÿ\ÇQç_.›ÛÐbpÛÜ@Áx2–À)½RP×DI ðz]~¿ÿ–|zVV&ºÑÃÃx ’gãÎd'EÀTÒ*gÕïUõ¾õND0ŒL£1Åb¦XœpëÎäó¡»qT¸Y.#Íè4;ë•õheæŠ:4Ïã±£~è’¶;ê‚èQ(2^yåu Ãbä|[’û ä‘GBÐ¥A ‘$wÉ@rG ºàTU­ÖVV–¡NAt4m¤u wžœW)k€F‡/s©Ý<9Ï@[ˆØÂesó0ž›Õ±2 Í„›;»$SRå©êìM …TaôQÿ"b C‹AARiQ)“.«Ëé!Çq·Ííô8Qÿ"b ·Í³q§9‚2]Pê•õǾ=ær'€ØIDATG°RÞÇÛ<IEND®B`‚snd-16.1/pix/sceq43.png0000644000076400007640000000322511147553270012752 0ustar bilbil‰PNG  IHDR˜'®ssRGB®Îé3PLTEÿÿÿððð```   €€€@@@ààà ÀÀÀ°°°000PPPpppÐÐÐîLk pHYs  šœtIMEØ¥+ÂèIDAThÞí[‰–Û* exƒÿÿÚÇŽÀà8Ó™æYçL3#Z¯”¡+ «ð*1ºé7Ñ*¢Èm™ßDL¥ßôzkã'Hm6$3õ»ÐÅFg¹ozŸ„Dz2"—”H\€jóÀ/rßô>i«tÃí?¾+I•ÖØkÜ7]A†­Wfª¨à•¢Åã5î›>–ßK¬w¦ú´mþ…R©¨ÿåB`¦>\úÿ´“…P€X.ÛšÒyÓ÷XFÏ3 ´qþ°$6û;jÍSµYäyîã$I>vüEýÖ6o@g[Š ùH•¡ÙãfnÎsRX5OÐŽcsQg-ˆÀ’Ä>Œ?³fxIoÆx¬ù©àጜçÅ „Ḅ—”éñ u׿w8HbÓ¿£xܼØ2t^HTÅBU¼³á`O¥“‚zܸ/ƒô6\Ó 8oörÅÖ•±»¶{T7ú‚NþjE„| äPsÇÍxà³%&ù¦yÊ!µuÄÙ>NÜÙRûq½Åm°”ÆXu‡ÇkOÈþZé)&1úxltÐ?q ’·Õž%—ÅaYµb  ËÌ>KqšKL2Æ\o;¸Á‘.ë³ìÐÄUo“e›þ1Í•L”múkkÃ$Fowvh' ëGÉR“Ok3âB”U ËÌî"ƒ ÆD×0«dzÀ-d,áÎ^)˜í¸!NÚ&(Û?–kSLÖ¦…“û¼(1ú¡G•n­Åº†À‘Yré*_è;BàñJùœ<7…ÂѼÇ"Æï…ɘ۰žaòÙÉ0³ÿ ïf´¶Ö ˜$U:Ø:bïÁ[?H¢eÝ\×Fíü»‹¨-*_=¤ N%bçÁÄQ™ÙÍ:ï%é¸H­²g˜ iç”¶Á ÕÏÃôÖÖâ•ý£*€ ƒÊ6bY”†»V£$B¤lZùŽ=M w˜ÍuØæÙPh½˜nêåÁŠäã@¤' ÷s{ÍG¡Ë©ùlh˜¡~Ý­ É·žÏè &êZX›ðCÅçÐ0üÅ~¼4ÜM‰!AÔFrßXi˜Öœ®ñ0R«(„±NâP ÊÐSÃ`×gæ½ÆÜ¼1g 3JeÏ“|Ù?è ØB#eÊ~Ç0 ánNW›êHníâkžv¹¥luô\å³:~¸ "6ÑKNP=7Œ/þy/Þ57Q=ÃäE)Þ8n'ÿÎbD÷ŒNíAÀv DlÄ:K¹ánÔh•ÂD[cl€—€ãW¦œqtfA¤áA¤æ£&l9½aò^cî&úèº0 ÎNÅSÍD z$í®Ýõü £uΤƒ `kj/9ëˆu–JÃ]{Az5­äb™ýüÐ; ö?Ö5|Ãç¦ûY8;IY&7¤ • z6ÄÜ÷ü£)ªì$ ~5‘‰ªÉ8 ±Õu±dJ€œðiÎãï08kžá>tº¤:œä-m¼e–¼¶ÓóWŒÓe­üSî“"¥Ðs*)ANê<÷a r2/ úvÊcGùóU“XúÁ¯®âë C’úb ­®sôMJhC¿Þ.HñºqÛ.ôóO}M}—]`5Ðr_Äh¬×å¾é}*‰EPð)—oÑ3Î.DŸû¦w +ph 0“H² =e >úèÉ}8Óã¾éíxÝo­Zø=ò …]ûm˜‹‘ŒN3LeU?K”àiT®K#Þrßô.ô¿3 ¿7R>½ß†U6â5÷Mïe2|Ð+kó•0ôßhWîÿ‘üWè?µ".«%‰Å"IEND®B`‚snd-16.1/pix/fmeq45.png0000644000076400007640000000114311147553267012754 0ustar bilbil‰PNG  IHDR‹\®ÝF3PLTEÿÿÿ°°°ÀÀÀ```ÐÐЀ€€ðððPPPààà   ppp@@@ 000Ü»€ pHYs  šœtIME×  ,ª1ùHÃIDATHÇÅUY²¥ !ƒîµÍàEôaßz¶U‘!9‡L<ŠÑ4 )­y¯Šºßñüc-ÄpL$,ÿŽ:¢ÈÝq#8¹öGòär‘ fÓb˜Šaôåƒ J °ƒYÉì#+Á©‡ù2vÔ¦1¢ å?DÅÅY€é°qž0 žYWqû ˜ÍH»ÉœM}ã¸ØÔ¦qBÑÄ@ªøÌbžÚ¼á†|ÁMÝ¢¾.yA`ÛÑh=ÎÊ\ƒBA­'çA¼vY‡CñY@OÎ+ ìÕM*mq’%È`ûµ«Œ·qƒ¹ŒÚ4>( Õ³¼;§LvË9¯\§jë† 5­Œ…[T%ß‘÷†bä.e§·¥ŸtX‹Öë2¢»E¥ÅÍÏ*2‚D¼ž¦Ç,5TªžÀt‹jôãöx‰ X{šé^áK£Ò¸ÌQk,é;0Û=Fý6êjo•ž9“²Ó>^ËUQæöQ›£²“ÚV~ÿ&¥ëÊJx”“­–K…’·k­vãÿ‚*ĉ¯}—F*œSm¸m{×xM8É/Þ#{” Zx[Ül6Ë· ÷G˜ýëTôöi7:m1jøÒß.ôŠÕ?*Ü g™ÐÇzIEND®B`‚snd-16.1/pix/wt.png0000644000076400007640000000235411147553271012305 0ustar bilbil‰PNG  IHDR[”=Š8bKGDÿÿÿ ½§“ pHYs  šœtIME× ¶Û)ÛyIDATxÚíÝënœ0Ð8âý_™þ¨Hè–Ì<¶Ï‘*¥)e“ûc¸-ižçù €[}{ „-€°@Ø[a €°¶7H)}¥”T ¶ ÛÜSG ð×”œË½ë¯Ï, ³½ ¸ØÙ^ Ü…à„íMÖ«ÓF÷ña'Á v¶ó<ÿ„êQ—º^öÌòÂöÍ¡£ °¿ÜÔ l„-Âö®œˆ]Ìa €°¶Á¼^L¬]V¶pcȺ.[]„-Â@Ø lž2Õþœ„íΜíÈcX.Ës\]zä0€°-Ç–Y]Pa l¶Âa l„-ÂvŸsFØ[„ín=T¶Âa l¶Â@ØiŠö¹%¶غÈýŽöÄИԅ^9Œ l„-Ð!‡q„-€°@Ø[a €°]¤”ŠÜüPj=üûžFZåë¢6ƒu¶¥žêI¢W]:l# ƒ3ï}¹rÍæÖÆîh=ê³.jÓpg[³pËÀÚÀ#¬(¿³ºä×Úcc´ºL-ý°Ëôukº·u}ên˜õÀe½~hÌ^]Ž–½úš¹ÿ6b]ö愺ܓQ͇íSùéÀÒÍ>[—œº©Kº˜3.ý¢`÷±Kí>ÿ­¨‹° ]´×ÚB°Œ8™Ô%fÐû0›NÂvoBÕ˜lÖØuŽD3£ÖÅ1Û°„µOÀµ0¡kllsOȨKÌ&IØ6ÐÝÖXºÙ¸Jmêu•{¯1r]¦Ö'öÝmÒÆ :u©óžÍui(lKßn«ø1»^uAØÜú:» ´Îu¶„æJu¶îÚRgÏE]Ìa;ÈÄÎ]–˜5äÙ!™{sïš“*€Îa l„-Â@Ø l„-€°@Ø[a €°¶[a l(¢ËG™ÛeôÈaa l¶Â@Ø l„-Â@Ø[„-€°¶[a €°¶ÂvSJ)ë5¹Ëôêô3ÈRJ?Ï[}fya{ƒœ ÕùÃ…íVð]íN×ëÚ[Ç™õ d «°-¹Û¿^—C Àè>¾ÁI0€ÌÎö¨S]Bõ¨K]/[ºchQšHB3Ђ½8uSÀ¦V~Ð xÍ{#¾¶÷ÛïÜókël„-€°@Ø[a €°hNwèl¶„¹]÷ì'Š]]èS©ìØú~ÉO/œ¢¼YWŸoæƒÉaì -‘[_¿®ïÓ¬qá: ³ß‡.#@-öŒx7.Jnˆ…-Cu´¯ÇåöŽÓ½Û•Òcnˆ? Þïè“Ä.%&Ì2iÖ_ïæ:h—1¸ü}ùclŽ“%Î MQ&CÎÅÜåáŽ.ÙØë';Þ}¿dÎL‘Þ´3ß3Љ6Né#;r×ÓÕa¸£ Ú:†{f—sýÿB {¯Èg#ÜOg ð€?_ëU!µIEND®B`‚snd-16.1/pix/open-dialog.png0000644000076400007640000006412111147553270014050 0ustar bilbil‰PNG  IHDR¢Á¤ (Ì pHYs:ÊduhtIMEÖ 8£ IDATxÚìÝy\ŒÛðgZµÒ¢pIɾvÉÒu…Èu³${–ºTˆÒF«ºT•¢ÍÒB*¡RÖ\”(Ù‘µ´Oª™6TÓÌüþx¯ùÍ™•Ôx¾Ÿ™3ïyÏyÏyçé]fæ!=­ !Ä¿:e-.û]p(B¨³¢ŠË~!âÑ­Ï·:¾ºNY BuVTIöOî´£9„âó“V„Â0‡B?†Psg³í> F¡ÎÒŽ¨¢e®ÅQB">PÂ~/Ù?ÙÕÎÇ!ÔqD3ÞGsÜ‹¶%âºÚ¹âV„Pg…ˆvWá.Çks!>‡a!Äç„pP;XÊZü(~8¨ ÌŸÕÜK­žØb˜Cí‰q¬èÆþ¡ïŠg8KöOæ¾µúÍa®#A!„Ú[¾k0iÓÑ\»ƒ(úÙÎaÙOc9Nl‰ã>¢{lùÞÁOZQçà8åybËý¡.Ц0‡_o@<Äã…ueli=ÌÝú| ONQGŽïú±±OZQ'»qG7‡auÑÁB?Š4“A§§Áø¹„P熈N©Bâ™§Ué³4N B¨Ç)¯á(áÀ0Ù?ù„9žƒ „z$î_Æks!>‡a!„a!„0Ì!„†9„Â0‡BæBÃBa˜Ca˜C! s!„a!„ºüõàÖ¥§¿ÀA@?›éÓÇ´ºŒŒŒJ—õ‡JÍ``˜û®S>ý]!#㼆†.ž´"„†¹Ž‘•UÆA@ÃBa˜C¡.„· B,9ùöòåÄcÛm3¦¶°pxx ®î<šCõ$Ë—|©o|ø¾|ý²‰ŽNàèèXöÕÇËÊʪ««S^S^7l؆Gs¡ž§¸’â»s~€¿³:ÎDM8B.¯3økÓôéÓûöí«¬¬ü$;7ãVWd=ý^GseeOž<ý£ªóD£5¥¦¦S(ÔNYN¿s'ƒJ­êš†h®åΗ•}y’åïï5pà€æ]¿~Õ‹9Äñïºu+EEEñM‹ÚaŠÖº#—Oˆ‰ÖhŒ›>>ëf1e¥^hê/€’’‰¡ÿ†¹ŒŒ8VEëNÿžlûOZ'LkbbvvFFëRSÓ­¬œ¸ÏqÊÊ>ÆÄÄÛØló÷߯¬¬dm½‹(ÿûoOSÓîîNÊÊ-EtŽÕrÔZ½z)˜˜,Y²€gCII7>ÌܱÃÌÜ|“¡¡>kµãÇQWÿµ[‘ñpðàA¿üÒŸxZ\\wêàÁÀêê°±qš9ówSS£Ã‡÷geeûøhkÏÊÌ̪¨ ;v(11:((„L.‹ˆ8zåJ¬Ÿ_ð§OŸ¾ŽRœ™¿ÿeåÁÖÖŽ<›+++OM½|ãFbZÚ=77¯ÔÔt++Gžç•¬ŠQQgssóíì,m«ªªÃÃ#[X¸¤¤tÙ²õ3füÓ¦©ëê®)+ûˆïXÔ¦ÖöÚk­=Î÷Jz& u°\ß òLù÷WFò+êX kh,cýû¿ÐiwZut´y–Ÿ;—%+;DVvHdäÙ´´Œ¦&:((Èo//¯à¸HÔòj[¨Å³!oï=½…ÄìW©6m2ܱì]§ØÏÿüS[@@`„± £¼¼‚8öÔИBœ®>uêL¯^½`Æ ‰4|øP&“ùë¯ã@Ee0N'“?À¹s aa‘²²Ê²²Ê‘‘gÒÒ2ššš¸›[²dA¯^½ÆŒik»=..±¹1g¯èïLW÷O¢0!!ÚÖÖ¢…… èÿàAŠŒL••yü8•û8¡6R3uÑFÛ£I !!RE7{ ( ×:‘£§Íí²žtZ˜kîâÑ›7ïíí-)”\â™üZHHBCý³³s¦M›wûöݶ¯¶…Z<zþü…¸¸X'Ž×åË×tuu8Q@˜LæÇå £©‰F”«ª)//ç^’ý1ƒÁøÚy+ åñL~+$$D£5q4Ç 5µñ55µÍ9{Åwïrþ]¬woiî“PŽVDD„àüù(¼0‡:éÆN3³÷]¹ríöõº‹Ô•`â´©»\—4t°4©ç…¹æHHˆß¹“Ád2‰§Ÿ>}...™Þwï^ÓÖžµq£YUUuׯ³±rž IJJ>þ²7gäÈá }›{UQ±¯PvvÎ×Ò¨¢¢ÜæQºËÖùOÅÅ¥·o§7×F7®Ù_=d¯(''›’r‡õÒû÷y-,Ì2sæt|‹¢Ž«¯¯Ÿ:a˜±±ñ²mÎ'N¼iÛÉs€&,–”ž¥ ÑEßÂêP3Ä‘ñ?ñe½QYOÿøC+=ý¾››Wqqé³g/vïö”——€èèX))I_ß½4­‰cͬê«å®%**RYI-+û8oÞlî†ôôx{û—”àõë·ÄÁ „‡Gùú·c“õô±o;Ñ1Öc ‰U«ô¢£c¿^X¼»yóVç9F‰½üë(`ï||üVsìÀ¥K×lm-šsöŠË—ëzy>u*æýû¼°°È‚‚¢F¨5ÐhôÆèÕ«ùir|ȺÇÏŠþö¾±qãFA‘^‚"]õ%¬ö‡¹²²qq ""æãÇòK—þ€«WoÔÔÔR(Ô„„+wQCc²››cTÔ9uõÙžž~VV[‰S¡  °àà0?¿#»wÛõí+ǾföêDÄjyÖZ±bɦM–W®\Ÿ={wC®®¿ý6ESsÁܹz‘‘çFŒööí{ƒñøqVFÆÃo›³†X¸pþ×€{bb⪫kÂÂ" .îNß¿“ÉtvÞÚ«—èúõ«bbâàÚµ›55µqqˆ+qTjUTÔY¸q#õÓ§O³fÍpssŠŠ:«®>ÓÓÓ×Êj+3)é&«9°´4ݳgÿ¾}½¼««ÿª­=ûÒ¥kpõêõ¯c~™èXBÂVEgçË—/¶·ß££³BXXhöì_G˜ÇÂu–#¬׿•)ó—GnuLÜ´iÓ˜1c@Hºðõ¤§õOàÖç[¬¢dÿäæ~8O,éé/ˆI—•U¦P>à€ ¾×ÆI—‘Qáyc41ñò† ÛôÌ?“z-1vðàÁOŸ>€ÏŸ?“ÉdIIÉ‹)™2 rZÓ&;›X’y«-o«6þHzx G4üê>B¨Óéê.‡ ¶5b÷ͳyyœ¡pР_¨…ÌÛ‰‘ñ½ûƒa!ô]"…² ›to!Äç0Ì!„0Ì¡¯ðþBæB¨ÛÁ[m"#3!Tj~FÆy sü`úô1mù B?F[>ˆ'­!„a!„0Ì!„†9„†9„Â0‡BæBÃBa˜C! s!„a!„0Ì!„0Ì!„PÏÖÑ_(é?ÃÒ­hh袢Nµ±Š™™ ÷O¤àÈ£ŸyÿïÒ0::Ö8ymÇ>aff.­._ZúGáþÿƒÃêˆVg1-íòŠÃq îÿí†×æB|Ã\wQSS»v­qMM-ÂýâÓ鯯f))wŒÍèt:ÂýÿٵË--í¤¥ÝÛµË áþ߉ðD·°oßî}ûvã8 Üÿñ¤µÇÇ+**:eU4íÆ•••8ª¨Á0ÇÏ \\\¦L™Ò)aîÓ§O^^^ÚÚÚååå8¶¨Á“Ö©´ôMZÚåï·þ~ýú9;;»¹uÎÅ '''œ8Ô#ö sÝBÿþÃ[ýècG>.""Ò¹&‘H8k¨§ìÿæºÑ´–ø®ß‚ ¢P( …Á`øùùÅÄÄűBæþÃÁÁ!::šû1êz ˜L&ÏÙ —––>zôhcc#Fc_Œ¨«V­rss+**€—/_FÃE=Èw¹qóæÍ¦¦¦5kÖpF]lÀ€ÍÍN]]ûK+V¬`ÐÃÂÂXËx{{ãÀ"²ò]ÙhSíɽÔc~í-#‡; ⩤¤dÈ_ñ¤µµµµ£FzõêU·{äÈ--­?vóñ!—õqùkñ”*êÿó´>L¿é³Ûâì ?w›§î´PØn_>:uÄËl­6•‚]Ñ÷ÂÜõë×_¿~Ýñõ0™LOOOö×YknÕÖ­[{ÄìÊõígdáÌ^Røá]°—“å.Ÿ•™›Ù{úï³+Êϳ°#튉KüµÍß]è' s%%%ýõû¯ÔväJ__ÿ{¬¹U=%]©°°ˆ0{ÉéP_íE«…„@HHx΂Ñ!yþ$C„~vmÎËËKHHˆø)mˆŒŒ\¿~}NNÎ/¿üræÌ“œœœ”””hjj®\¹²¶¶ÖÃÃCAA!;;»oß¾îîî.\ðôô´µµONN^·nŽŽN@@@zzº‰‰‰»»;ÑÜ­[·äååÇŽËêÀ7Ø×|ïÞ½›7oææææææ†‡‡+++støøñã%%% < SRRâ¹Í- ™™™æææ?Þ¶m‘Ù¾ÕF¸û·ÿ™³`ëéˆ1jq§‚€g!»Øˆ šjJM…Á`Xÿí÷Ï…˜èƒ¶9&ž Íz˜¶ò/óÍ6®ðÏ…˜¢üwÂ"¢5U˜ÑñW˜+..¶³³£Óé4MTTÔÖÖVQQqíÚµëׯ)))###0000444339r$˜ššnذaΜ9L&ó?þØ»w¯­­í²eËÊËË£¢¢^¾|9nÜ855µøøø·oߎ5ÊÞÞ^RR²¨¨(==ÝÉɉ½ìk.--ˆˆ ccã-[¶$%%±/öîÝ»ýû÷À¤I“Ž9âááÁs+x.ùï `aáµkמ"‹‰Kœ;šÚ‹w™ë—}ðI|›“e¸P}±ÕÓ‡iÏŸdØì>%…y'ƒ0£+⣓ÖþýûgddÀ×à&rD±Ÿ¶ð<…©­­=}úôŒ3ˆLLLBBBÄÄÄ`öìÙ$iÔ¨QL&S]]TUUétzIIIcc£ŸŸßÎ;[èOTTTpp0‰D"‘H¡¡¡)))MMMì x{{/_¾œx|óæM—æ¶‚ç’„Å‹ Lœ8‘ÈgÚj£Ý € Ç\H$ž…eåw™ëS*ʮؽÄÄ@cÖ|a£&0ŒÊв0wíEÿft03º"þ s½{÷vuu}úôêÕ«¹­à¹$w'™Lf«v¿ V­©þ¢Âš*JÿAÊ< 9*zžy›“µrÎèGw›Íèú:;SL3º"> sõõõ³gÏÞ¶mÛÀ9^"î pÜ žöë×OHH(++‹(lll$ROµLMMÉrrrØ×,!!‘œœÌj´®®®°°}%}ûöýçŸXOß¼yÓÜVð\’§Ví¦ü>÷ý«ç¬§ï^=›6cÏBŽŠÒ}dc®gOŸ­ã¸uem5â’Ro^`FWħa®¸¸˜L&WWW1«¡¡¡±±z÷îýøñc&“yíÚ5øšGJTT´¢¢¢´´TBBbýúõ'Nœ`nß¾= ²‡È¶ÜBe­yÁ‚©©©ŽŽŽ………™™™vvv À–¢tÍš5nnn!!!oÞ¼ þðáCs[ÁsIöä§¬Ç .äÙèõoºÕ¯£·ÒÐ쟋1 :túõ‹gVm´àYû®%þ›ÑõâÙp Ii‡}Gi´Æ¦&Þ]µ­ =ìö±´òÞ¾€&ÌèŠø&Ì©¨¨hiiÍœ9óÅ‹“'O666¦P(àááajj:yòd ‰±cÇfdd455­[·níÚµ‰‰‰$ÉßߟÉdîØ±Ã××WLLÌØØ8"".]ºT]]}úôiâB…B!rè%%%qäÜcÇZó¼y󼽽Æ ö÷ß;88ˆŠŠ‘433öîÝ«¯¯oaa¡©©),,}úäå奭­]^^^RRâëë»yóæŽ¯VUUµû§FíV \\\¦L™ÂæRSSÇ/,,¬¡¡ñüùóNœkpô…9 ‡Ót0`Æ ²Z“Þ½{ÿ̳%#£"#ó 9úõëçìüß<­……!!!III4mñâÅt:½³æ¡îé{} ¢Õ|7í`ooF¥æÉÊ¡PrÛ²°ˆˆGIRRRHHñ×"::zĈùùùC† 鬹FˆÿÃ\LLÌ»wïDEE‰_æÆ˜UHHˆg"Ô   …B¡P †ŸŸ‘lÑ¢Eýû÷€¼¼¼iiéC‡•––BÛ~E?b\GÖ`ddÄÊP3hÐ aaaî_rçù˜˜˜ƒ:::†††¦¥¥™››»ºº¶e®âÃ0wñâÅŒŒŒC‡aÈÓ“GšNîĬƒ â™ÕÖÖ–L&KHHÀÍ›77oÞ¬©©I„9??¿I“&3FOOïçy§µñ8®Ù‹lÉÒÒÒÒ %%%9–áùÅ‹ëëëøð!111++K]]ÝÊÊ*--­Õ¹F¨›èÌksîîî«Vý›¦SEE…ç¡wbÖæ¡***êëë—••—ötuuÙW•‘‘Q[[ sæÌijj"“É8—ß„Á`ÄÄÄ8p€û%Ž‘€ùóç L˜0HJÛê\#ÄŸa.33SB¢¥4<³6—õÌ™3YYY£GNNNæ¾4uêT*•š’’"''Gœçò½o½Ñ‚'NØÛÛËÈÈp¿Ä1ò<[k„ø3ÌIII=}ÚRšNž‰Y›K„*++›­££³råJ*•31h|||VV–¬¬¬MbbâÏ¡Õe:~y޽)S¦ 6 êëë9^myäÛ8×ñg˜[µj•››[QQ¼|ùˆ7V¢UIIIîĬ<¡@xx¸´´ôÑ£Gi4G¶Ö˜˜777&“™““3}útŒq-œœÂïÏDGGS©Ô¦¦¦§OŸ>xð 00Ø2Ø67òìkka®ê†:ó„——W}}½šššªªêŒ3FýêÕ«~ýú;wNŸ>½téRKKË;vüòË/bbb›7o®¯¯¯ªª²°°’’rww'¡€¯¯¯œœ\eeåþýûâããàÂ…  èÝ»·³³³ADDDŸ>}äååÕÕÕ¹?<Á—¾éDII 1ø±±±úúúC‡MLL\¿~={îÔÄÄDâONSSÓš5k¸GžXÃÅ‹û÷ïK¬mß¾}Üs=fÌö[u=5O«¡¡á¥K—¨T*q¬1qâÄÇ÷”#2âAÇó´b†\ÔÏHXû?æim‰­­íäÉ“‹ŠŠššš(Ê©S§:øQþž¢oA ôóè‘aŽÉd8p@RRRRRrîܹyyy©©©?ÏÃŽß‚@è§Ò#SÞxyyyyyýœüãú)ÂÜϬƒß‚@OZBÃúqðBæø^žCÃÆ8„Ðà-ˆoA „a®')-}“–vÇ! s|«¤¤dÈ_Û¾|xß¾}ÎÎΦ¦¦?ôÃä­ˆŸÃ\~~~EE…””ÔüÑÅÃ÷ C¿õ["""ÂÂÂì%DžÖ)S¦Ì™3'::úÇïß¿7222dˆ€€€‘‘tR*HLÞŠø3Ì=yòÄÏÏvïÞpúôi--­óçÏ+++?K{ïÞ½½{÷Íž=›õcèÜ…©©©bbb‹-ª©©eË–}ùò…cIƒÁÝܾ}{Ô¨QbbbëׯÿôéŸMXoA¹¨ákžÖ°]ºtéСC}ûöå®äîînmmmii 111S¦LIHHX´h‘ŒŒ +[LLŒ»»»——Í!þ s'N433#ÂܶmÛ¦OŸž’’’——— ««[ZZáä䪪ªºeËàY8sæÌÍ›7“Édiiiòôô¬ªªâX’D"q4AtƒL&?yòäþýû·nÝrttÄ÷Ÿùn&OkAAÁŽ;Ö¯_íÚµ÷ïßsW´µµµ´´ôññQUU€Å‹?|øHÞšœœ¼wï^*•J$êݵk×Î;»þ’B]tÒÊ~ÎB#ÌŸ?_MMmÕªUQQQÁÁÁ$‰D"…††¦¤¤455ñ,ssóGeee1™ÌüüüaÆq/I§Ó9š š^±b…˜˜Øøñã]\\NŸ>ÍgöM· ZÀ‘§µÿþ»ví:åîñð IDATþ|NNΟþÉýk̘¼a˜kýðáÕ«W{öìa~ÕÐÐ $$ijTUUçÏŸ’‘‘¡©©Ù\uî#ö«BêêêÕÕÕ8Ç|8!!B¡¯ž:uj×®]Ä;LÞŠøCg~§µ´´”¸vüøñ $$$@TTÔÖ­[  ­­ííí}àÀ__ßyóæ‰ŠŠò,$Ö&((hjjºtéRâ)÷’‚‚‚D*eV`ooooo¯¦¦&,,þ<$%% 8ïBt\“´ò„™[QOÔùyZ /]ºD¥R‰?ï'N|üø14 æiE¸ÿCÎÓjkk;yò䢢¢¦¦& …rêÔ):ŽS‹ú:9Ì1™ÌHJJJJJÎ;7///55G!ôuòµ9//////V„ßÍ!„†9„Â0‡BæBÃBa˜Ca˜C! s!„a!„0Ì¡ïç{§jŬÃúax¦jí\˜€a˜C?wªÖN‡ XQ÷'„CÀÇDDDº LÀŠ~®£¹³gÏΘ1#$$dÒ¤I¢¢¢ .¤P(111S¦LIHHX´h‘ŒŒŒ‹‹ ±p^^ž““Óþýû ÀÊ®‚¾7///___ž ¹»»[[[[ZZ@sÓãîîîåå…Gsèç:š[°`ÁªU«ttt222Èd²¶¶¶µµuPPwO8ß[qq±N§Ñh¢¢¢¶¶¶ŠŠŠË`V„Gs-!²Õéé鉈ˆ())¹¸¸$&&òÌà mÈèŠ:]ÿþý322àÁƒ@¥R¹—Á¬æ¾Á¸qã>þüŸ°Ê–ë„Èè:a„ŒŒŒV3ºò¥I“fµºLié›Îü³& лwoWW×76·Ì™3g–.]:zôè'N,^¼˜çôaVÔƒöÿïæjjjÔÔÔš{3º¶eÓÒ.¯X1¼³š«¯¯Ÿ={öóçÏåääš[°">Ûÿ¿ËJˆSQˆŽŽ¶··ç™ÁšÉèŠ:GªÖââb2™\]]•• € X_û.a.88ØÞÞÞÞÞ~êÔ©zzzDÖ΋/VWW‡‡‡@lllSS“³³ó³gÏ""".\¸p÷î]âýösrpØ=`À⟃ÃîÎZmII‰¿¿?1àïÞ½--­™3g¾xñbòäÉÆÆÆÄŸ›7offfµ|}}ýüü<==‰¬<§oß¾}šššjjjS§N #°²ÿ Cè‡ïÿ,Ÿ§•D"åääŒ9²Õº?gFWö<•ff.ÄA;N××ߘ–vï÷ß§>&((øßƒv+ÌÓŠpÿo‹®ÈÓJ`?Íifte'((0{öŒö9F÷ÿnwÒZPP999­ž¿`FWÒÒRQQ!ÒÒR¸Ó#Üÿ;WgÞi­««SVV€eË–mÞ¼ùÈ‘#-,Œ]B]£3ܤ¤$^„Fñs˜Cߪ´ôMZÚe„û?†9þdfæøÑ_„pÿÿ.aNCC¯í÷z»ŽŽ<ú™÷ÿo‚?«‰âsæBæBÃBa˜C! s!„a!„0Ì!„†9„†9„Â0‡BæB¨è¿P"+;§ ¡î‰BÉÅ0÷³ %B?¡q‚'­!>‡a!„a!„0Ì!„†9„Â0‡BæBÃBa˜CýLø$µŒŒ,Î%BŽJ¥àÑBa˜C! s!„a!„0Ì!„†9„†9„Â0×<|ø¤¢¢²‹¥Ñh7nܪ¬¤tn÷ètzJÊ …ÚüË—úúúúŸjº†¹¦  ÈÅÅcÊ-öýþæÍT {ÿ£66Nwîd´PØnŸ>}öò:¬­½¤¼¼â[»×²#G´´}üXÞéc•šš>~üoÂÂòÚÏŸ¿l¡çX}úôYNN…DêC"õ?þ7QQÑVG57÷ƒ©©5‰ÔÇËëpaa1ää¼Þ¾ÝŽDê³oßÁvlc«ãÙö©ïÜýu+¤§õOàÖç[¬¢dÿäæ~ݪ—²²CZÎÁúDcc#‰D雓ó`äÈáðî]îºu›ÒÒ’„„„h4ÚÌ™ N:Êd2¹ UUU:ÒI&“) Ãj—'îîuÊjÛ¡°°ØÚÚqçÎíµµuvvWVRÞ½Ë,)!sæååó«Ã‡ôéÓgÈePTì;l˜*Ï¡æÕ/^;Á ’H$¢$'çõèÑSétŠ€À7ÿÑmy<Û>õßcà­~ ¢Õ÷fWèˆ×pD3à›/{±ˆˆˆp”øú­^½LHH„……W¬Xrð` pzwè/Æ×÷í7u¯SVÛII7BBü{÷–€èè#Ôóó oÞLå.ä9€~~ûNž~ütÛ677'ðò:,$$TTT >>{‰žðì!OFFëY‘eР }yòÀÌÌg cÆmt:}õêeÇ–””hn¨Û.;;ÇÆÆiÖ¬ßI$RPPˆ¤¤äóçw»`ê¿u€{÷Þ¼™š›û!7÷Cxx²²Rs3È]a˜ëLyyùòòr¬§òòrùù… ƒ»£¢­­ ™üVBB< à,^¬£¯oôáCAbbtVV¶ºú,+«­ii÷22:äI4äééKÔ8qBuuÍ·v5,,òÝ»Üýû÷À¤I3 óðpac^»ÿäIÖÔ©sllÌ>}úlg÷7N¡Ñh¢¢ ¶¶ŠŠ <{(#Ó‡÷EY¶£§´´ CC}II öX…<pÊ”I™™w(êÑ£á»w{Òh´ØØžK6sˆÚ\¯HÇVRxýzJQQÉ;WÛã¾iêÛ±?”–’#"b‚‚|ÀØØ|Ë«¤¤¸æf£.Â0×É9ÎûH$ÏBŽŠŠŠ úúFÇÚ°aˆ‹‹Àüùs&LË`0ÊÊ>º»{ùúzË«¨ fÕ57ßÜŽ®z{ûŸ<L<¾yóB¯^¢¬—/þS@@`âÄ D»Ã†©fd\€ž•Z¥¨¨À³‡Í…9ƒçííÞ\a c%++ãà`­ Ð×ØØ¼¼¼¢-£úõ‚cëñ«WoFšB<=z$|þüeË«­[§OŸÖ5Sߎý!*ê\pphpp(ëô¹©©©¹䨋ºÿnNUU…Jýÿ›ŠB¡*++ñ,ä¨xæLxVÖóÑ£§&'ßnîP(3ó™„„Dguõõë·¬wWŸ>½{õêų]&“) л·´«ëþÁƒµz°Ö²'¢íí­8¢!{a«cµjÕR¨®®i˨¶…«ëþÆÆFÖ‘lL};ö‡W¯ÞìÙãÀdVÿ> 57ƒ-ìKÃ\'˜;wÖóç/XOŸ=Ëž7O‹g!GEYY™ìì{::óV®ü‹ý=ÀNJJòéÓçÕÕ¾}åÿù'™õôÍ›wÍ-Y__?{ö¢mÛLX—ÿÛ'>þâ”)“† S%Öɳ°Õ±ª¯¯—’’TRØ–QmÕ³g/¼½ýƒ‚JKK1ŒŽ|¯íSߎýABB"9ù6“É$^­«ûTXXÜÜ ¶e_B澃Á yˆ§ff&11qt:ètú™3ç-,¶ð,‡=ÑÑ爊ááQÒÒRGú566Òh4Ö YM2nnŠŠJàåËW@£5À‘#aûölK÷Ø­Y³ÜÍÍ+$$âÍ›wÁÁ¡>p,Ïz\\\J&—UW×dee@CCccc#ϾyóÎÔÔúúõîæ¢£ÏQ©UMMMOŸ>ðàq``ÏBžc}.55XO`àqWW'‘æF•]S½{%t:ÝÄdû²e‹-š/^¼ÊÉyÓÂ&ðOÖ$¶}êÛÒsŽýaáÂ?RSÓ] ‹33ŸÙÙý­  Ïs¹ëbÜÁksRRB>w.bcõõ—:døð¡ŽŽ6{””ææ~سÇaèÐ!À³ðæÍÔ¦¦¦5kV€¯o œœle%eÿþ= }‰Õ^¼˜Ô¿¿ØØD¢‰}ûþ®¯¯WSû]UUeÆ Ñ£G¾zõf̘‘÷ï?*++wph½{ì¯îÝëRUUmaa'%%å8 €ˆˆ;;˨¨³pútœ³óN--Í™3uöïß3yòDccó‹cˆµrô°_?Å£Gã£ÏUWÿçšzbâ•õë7³‡›ÄÄÓ< yàáÃG?¹páãÆ9r8qÞÚÜP³¼}ûþèÑpðôô]³f…²²RvvqyëàÁÀuëVž?éÁƒÇ“==}bc¯_OHJºÉsšOÖ$~ÓÔ·ÜsîýA[{¶··û‡|}ƒæÍ›tPTT”ç rןÓÅøíãÁˆ[qqé²eëïÝ»›€¾|<¿ºÏ窫k||üÏœ ÇM@xÒŠø“¤¤„ÏÞïôU Ü„aýxùx-nâxÒŠÂ0‡BæBÃBa˜C! s!„a!„0Ì!„0Ì!„†9„Â0‡BæP ètzJÊö„aÝ_mmÝÞ½Þ{÷z§§ßk÷JJKÉÇŽÀa˜ãíõë·::+V­Ú°v­ÉÎÎû÷·ç‡ó˜L&‰ÔgÆŒù$RŸ)S´ˆòüüBkkG©±±ù»wßý7¶Ž ÓÒZÔŽ\ô-PUUëø SSÓÇÿMXX^CCûùó—ìƒÿÛoÚ&ŒurÚÁ3[Í‹¯,,ìI¤>ÞÞþE9ùâÞ½ÞDf¹;w2TT” ú…ud8dˆòІÉôˆ¼ëNN;BCTUU¶l±€qãFGE…P(Ô¼¼ü¼¼üS§Ž©¨ &ÎãÌÌLV®Ôk¡ó¶¶.––[}|ö²ŸI_»ÿÏ?ç=<|ˆØajj=wî,+«­!!þOždyxœ>}ZJʼ¼ü„„h]]æš»y3uófËêêšæ6¿-ýd?KKË04Ô—”” “ËJKÉsæÌ¼?ùþý›eîÜéÜêdñœ—V9šÎËË———c•ËËËåç¶½C†¹žç—_ú§§_‹Š:žšš6~ütâ–ýŒõ˜gŽzâ0gõê¥ìë”OHˆ.**±´tøoH=J"õ!‘ú„†žJI¹ÓÔÔDDº;Ìut–®ëÕöιÙËÊ>²çf_¼øO‰'=¬­­;}:vÆ b[LL CC#””Û¢¦6ŽH²Å“®®ëqs›ßv #&&îÀWâ8Œ ÄÄzM˜0ÖÙÙ6!áò7•Ó:{Ó‚‚‚uI$RÛ 1`˜ëajjj‰¿ùkÖ¬Èξ7bÄÐ ¶¶i¾&Ðh´óç/—áØ)++;w24ô+‹+4“wxiÓ¦¿>þ’–öm÷òZÈÍNôÉd–•}d0D6X>|hYY9÷ÁÎ7]ójµ"O'NDÛÛ[ÉÈô!ŽŒàkŽZ˜4I­ªª: àñ7€DêsãÆ­v4ÑÜØ›VUUaOðL¡P•••Ú^ˆ!Ã\sùòµ»wïûôéíã³÷Å‹W¬W‰ŒÅ<ó@³ŸÖ3²_?EîågÍúÝÏoߦMlGy<ò®U8|ÐÍÍ‹ýs'-7 mËÍÞ¯Ÿ¢PVÖsâicc#wFÑ66ל¶TŒ¿8eʤaÃT ¾¾^VVføð¡¯_¿e­aÈe3³M¬¿sçÎbÕå¸ÏÛ¼ð\GÓsçÎzþü«Ê³gÙóæiµ½C†¹fØ0ÕÍX'_oß¾ÿã÷ãÞ½¥?~Êd2¯]»I„$ž9ê‰{¬Äã/_êYÿ¶n5^½zë)ϼëÄJ~ÿ}ÚæÍ4535µ&­¨ ”–’_¿~Û\yŽÜììùäY%%%Ö¯_uâD4+.oß¾™;R°šc/d_Œçæ·±ŸÑÑç¨Ôª¦¦¦§OŸ?xð800„¸¢zŠXàîÝûÆÆµ‚‚B¶mÛÑÔDŸ2e"«{^Z|ÜM›™™ÄÄÄÑét ÓégΜ·°ØÒöB ?!> s#Gsrrohhhhh`}hÎÃÃÅÔÔÚÏ/Ø×wߨ±£22¼}ûþ›£>2òìùó—¼¼ÜàÝ»\âƒø..{--·8€8é ô~ùò5±Nžy×oÞLݵËýöí«$iáÂ?,,ìwîtÞ³Çqݺ•k×;:ÚôêÕ«¹ò¹Ù‰¨cgguNŸŽûûo;/KKû;výòË111#£õljk…[·ÐXÍmÙ²‘µþóç/À… W èOÜddßüØØD{{«Vû™˜xeýúÍì‘11ñ4lÛf²k—»µµã A?}úäà`ͱubbb§ Æ¡CûY…Üó2hÐ/çÎ%ÀéÓ±K—.êÕ«WËM>ÔÑÑÆÁa’ÒÀÜÜ{ö8‡·m/D|ß>Ü#ô”ò˜ëñÇǃñ;­]­§äÇ\÷OZQ;õ”ò˜ëa˜CíÔSrÈc®{Ä7ð¤!„a!„0Ì!„P·Å'׿Z½í£9„Â0‡BæBÃBa˜C¡ÎÇ߂•mÓÏNt«ïÿ´p²†¹vjõ‡!ñ«š8YOZù–››Û­[·º¾]­)55B¡¶½JYÙÇ“'OwAߺ¬!~Ú–ïÝP;v˜×"†¹ïâÀÇ'Ót¥ÏŸ?ûûÓÓ[_YÉãcÌ))w‚ƒÃtuךNœ8«¼¼Èä²  0++§ïÝ·.k¨ ðÍ µ¼ÃðG‹æ¾ ??¿+W®dffÎ;·‹›·²2mîOè¦M–&&†QQÇ õ VKKK@¿~Šk×.uYCü´-ínèÖ­4öô íØaº~Å0×cDEE;vìÒ¥Krrr?¤Í]`*,,®¬¤ JJJhiiZZni¹J—õ­'ê΃F&—mݺ³©ˆº~Røø(ßþÞÜÙ³gG=vìXxýúõ¦M›®\¹"))Ùr­ÐÐH*µŠJ­b2™ÎPW÷éàÁÀ¾}å_¾|-//çädqËëû÷¯÷ïßïüùK÷ï_þüe``¨µõÖÈȳ÷î=Ú´ÉÐÁÁ âã/æææ‹ŠŠðÌÔ•••uöï?$//·j•^\Ü…ùóç(**p,ùèQfjêÝ òó ‰Y¹{ËŽ»ç.\áÙI–«Wo˜®^­·gƒ¬¬Ì±c'ÓÓïŸ<Ô ç7!áò±c'õõ—……Eå伞5ë÷à`"¥!‹¿ÿ1!!¡ââRpwwjnócýiá9ª<¿ÕÙ‰ˆˆ)--kll|ò$ËßÿÀÀnÝJ'“ËŽøí·)K–,àY«å¦ëwQ<šëÖ¶oß>~üøuëÖ½xñÂÕÕuòäÉ3gÎlµÖß{ššntwwbeð´±Ù5sæï¦¦öÌÊÊöñ X±âß,®’’ëÖý›7þÏ?çff>+((ŠŠ:–˜åãXUU”tóáÃÌ;ÌÌÍ7ês77aÂX°³³02Z—ššneåDd›eWVö1&&ÞÆf›¿ÿ~ee%kë]Íõ–wÏyv’½ÊŸÎ]¶lч…²²2@¡P9â`÷1oÞì{÷UTP®]‹{ô(åýû»víe_ ´”¼{÷þ-[6¸¸Ø…–—W4·ì1Ž{T›ü–g'*ê\nn¾…³óΪªšðð( Òœ›˜,Y²€g­Vw˜®ßE1ÌukáááOŸ>UWWOLL´±±iK-ycãíååk×® þNÆÅ]ÔИLÒ®>uê Ï\ñbbb0wîL±cG1Œòò oï=½…ăjµumžåçÎ%†…EÉÊ‘•y6--£©‰ÎÝ[ŽC9îžóì$GE++Ó»w}úL\oâèíešíy«vì0KJºéã¸též2ѵµucÇŽf/ihhX´h±±‘¸¶íÈ1ªÍ ~˳#''›’r‡µÌû÷y¬ÇÄ’Íf2™ÉÉ· ®î3Ï$özz ¼½ýKJÈðúõ[ Ñ8?²G,Lüϱ_²žþñ‡Vzú}77¯ââÒgÏ^ìÞí)//ÇÝ[Ž÷wÏyv’»ÝqãF/Y²@JJ’ãŠ~7TW÷‰x›hi¹…}[JJÊ>~,¯©©ÍÎ΀††ÆÆFZ[6cT›ü–ggùòÅ^^þ§Nyÿ>/,,ª  ˆX¹¨¨He%µ¬ìã¼y³¹kµe‡éú]”ðçÖvß “‘éC¥VíÞm×·¯ìß¿ÛÁÁÍÙÙcÀ€~½z‰þõ×pvÞic³ëÈ‘°½{Gþðá“ÜÜÄ%dEE… ®@bâUÛ††MÍÊÊJ“GŒööíû‘#‡±NÊÊ>ÆÅ]€ˆˆíû÷ŸÀÕ«7úõSljjJH¸qq-úÃÍÍñðá£ÁÁa³gÏðöv#®šs÷–wωŽqtÒÐp5{CÄaï°aC&MšÐÍ' ÂÂ"ååå`Ò$µ… ÿ P¨¬mY°@[SScáÂÕ»wÛýúëx ûÓ§Cú[Ø@ŽQ5ëwîÁgoˆçì8;﨩©±·w•””صËföìÄÊW¬X²i“¥µõÖ Ör×ruu°³ki‡éš]tôèüžÖ?Ž<Õ'ÌýºU/»[foþF¥V­\¹ñêÕs¡ºYÙ!÷ï_6L•_7°GènïÍñŽhøCLˆÝéÓqS¦ÌUW×Z¹rImü¨mÏÝ@„׿P'“——+**™;wæÆk»yW‹ŠJàõë÷ìùiQ'Â!@,ÚÚ³JJzÆ}· f€¡¡é_­9xÐÿ6a˜C?»ÊÊ÷8OZBÃBÃBa˜C! s!„a!„0Ì!„†9„Â0‡Â0‡BæBÃBa˜C¡®Ðc~¡DVvÎBˆoÃþB:BOZBÃBÃBa˜C! s!„a!„0Ì!„†9„Â0‡B=;uzú œB„¾‡éÓÇ´ºŒŒŒJ—õ‡JÍ`üŒa¦O‡{$BKFf0•š×æèÓ22ÎkhèâI+Ba˜Ca˜C! s!Ô“á „:WròíåË ˆÇ¶ÛfLmaáðð@]Ýx4‡êI–/7øRßøð}ùúeÀÑѱì«?–••UWW§¼ §¼ oذ æB=Oq%Åwçü/fu:œ‰:šp.„\^gðצéÓ§÷íÛWYYùIvnÆ­ä.è ÍÑéô;w2¨Ôª®lŽB¡¶°LYÙÇ“'£Û¸Â–ÎÌ̪¬¤tñÒhM©©i-o#B윶Π<ìÕé@y¹ûáUóˆÃ«Ümµýüü’’’455û÷ïÿåË­ÃÜ·a2™jj¿ïÞí©««_QQÙ5ÍíÚ宫«Ïz&NÔ,/¯2¹,((ÔÊÊ‘£b~~!÷:[X¸¨¨dß¾ƒsæè²‡›ÔÔt‡=ǎصË=#ãA …íöùógÿ£zzëº>¼¢jÁÜ‘ÁþîÌšÿì{CË­^òëùÐõ¡¡¡þþþõõõôƆÆ&zô‡¯NZ?~*//çêêx¼Ëšóðp9z4œûU}ii)è×OqíÚþþG9*<ˆ»V 76ÒvìØîåu˜õRnîww¯«Wc…„„h´¦… W9âËd2¹ UT·{3ÅÅÅ­¬¶º»{ỵƒÁ<éº\KM„½P¤÷@Q¥™¿Eú¯Zgn¡©©Ùeýá«0qéÒE$©;4giiÊẕ Q±¹Õ6·°ˆˆ0Ç’ÁÁ¡K—.aa¡%K…w¡——[G¶´Ë†ñ‡«É¯K?ö¨$"ݳ:°]ún¤Rþôߨ#‡N€ÔÔTWêa®®îÓÁƒ}ûÊ¿|ùZ^^ÎÉÉæÒ¥¤cÇNêë/ ‹ÊÉy=kÖïÁÁ>22}=ÊLM½ûáCA~~a@À%¥ññC­­·FFž½wïѦM†V`ff[QQú­¡Óé —¯_O ž>{öÂÖöï¬¬çÆÆŽŽ6_{ÀÞÛ«Woøù[Xl¾x1éöí»+WêikÏ 9yÿþ#}'§Ī=ÊLMMÿð¡ ?¿ À[Ii wswïÞ_·nSAA‘®®ÎÁƒ{ f\\âüùsZègDÄéÒÒ²ÆÆÆ'O²üý½ÐòFqHI¹Ã~'~ìØÑ¡¡§€g!»ÐÐSTj•ZÅd2=<\âã/†X[o‹Œ~¬`0MM4⩪ª §Ø=âË—/oÞ¼···¤Pr‰dòk!!ÁÿtB £7|i´¦Ë—¯éêêpnž€0™ÌËÿÛÛ!åååÍõxÌ`0àÍ›÷ööVÊâ™ü–¸´ÏÑ+”¨©¯©©mîb{Åwïrþ]¬woiQQÑ6n‹²ò`â˜@¥V4g!×Ik@vöËiÓæÞ¾}—çˆÀóç/ˆ?Zµ?Òffï»råÚíëu©+ÀÄiSw¸.7hè`iRsŠŠ}…„³³_}}OÒTT”9–©­­;v´„„ø;L&“(üôésqqiçnÆíÛé#GWPèÛbo…²³s¾ö¶‘»·{öb÷nOyy9Và`7Âã|}ƒÛqƪ§·ˆ}mÄúY%$$¸z»½Äcöÿ _;€½óìÍqlÂ¥K×lm-8ÖÃzÊ^qùr]/¯Ã§NżŸYPPÔÂÂÜ›&&†ññèt:Ðéôóç/mÞ¼g!¸ºîM$*FGŸ“’’ôõõhl¤ÑhM<çBOo¡·÷á’’Rxýúíy\MùÿÇß÷Ü¥Û½íû¾/’¾"d'£˜±4vB3ÆöB5„²e›¡!ŒðÁéM!)k*E´«»oçžsÏýýqMß~ ™/}žûð¸ç|Î9ïóþ¼ÎûýÙn‰FÁQ½E´œ TJØlvMAæéý3òîU¬ÞšñÝwßÑYlŒŽ±Új ÇÿtžØØ51«Vm°²²`³µ¾ýöUCõGLLLÀÇÇ{ôè¹sçÞøø~~ƒ¶nÑÒb%'Ÿ€´´‹ææfgÏž€ääó¡¡sóòîÖÕÕ/^<÷=¬‰ãii×®ý©±ÀñãI‹Í=yò $%]¾|QlìÚˆˆèU«Ök®væÌ)ÇŸ€?ÿ¼hnn–žž©i‰›7ïûÔÔ? ##ËÊÊbèÐA11?íܹ'>>ÁÏoðÖ­1ꦧ€Ðйkׯzyue0½zõð÷÷KII€óç/XX˜“$yæLªæÂΜ9×xàªUËD"QxøZîÊ•a~~ƒ€Çã·¸3ÔÔÔjþ+9ùÜ„ cœœ—,Y½ÙÆÆêÙ³çáዜ ÅYY×IR5qb ìÞ`hhÈçó׬ 755NNN€´´ ss³³gÏiNµÇñÁƒ¿rp°ëׯ»»kIIi—.nÿ{ ¢3°Ï. 7oÆYZZ:ö9þû#0{ölww÷?n=†6œœ@+PÀeÙåÆM™q™‡þò·K42rºyó‚««s\ýµkÑ"éħ•‹¤:¶Ø1šœœ2Ú¬…2{ü nööö “ÉjjjtttR.åšëë³ïDrUþeïÙ;ÏÕÊEÒŸsDÍÔ >Òðà¦IèlŽ:xBBæ{x¸¯¹xâéÓæRhkkÍ¡¾’|NJìÐIëëTTT@QQ©‹‹ÊnˆÎ¬t<Þ¨r1R‰¤RY÷îƒà›o憅E¡'@ :2šãr9 ¥È¦¢CòJd@ PÒÚŽÚ£§ˆ@´ |~yNÎHæ>.x¶ftø8P­ˆ’V@2‡@ HæÉ@2‡@ HæÉ@ ™C $sñ¡øû³ >‰Iâó૯–üí)O_æúõ‡L@ Ú†ÿeZ'JZÄg’9d@ Ì!’9h>Ø²š††ŽØŒB>Ÿ‡ŒƒŒó¾¼³÷yNÇ’9ÍeuΧQS³NKk2Îß6N§]:'çV ÌBžƒ’V@2‡@ Ì!Äg ™ñ)RYY}ëÖý>}¼,-Í1 ½­ÿ˳gÏãâöVVV{zv šÄç îÝ}x÷ÞÃüü{"¡ØÅÕ¹w/ï®]Ý=»uQ(ð+W®±Ùl?¿Avv64 ÉÑÐÓÓ [~äð!‰Dâêê‚a4d ‰‰Çž<)ó÷v!=³´ô¡¤|}{/ ]bdd „W³³; jêqQ±››³P(ºÿaxøbSS$s•JUTTrõjŽL&—Ëåjµºwï6lØGy*â-žsîÜ ë””ÿÄíüõê­œ!}<}úÌÑÑÅt„BѨQ#þáÙEžS©„þOãrI‚$U*µ®®îÈ#ýôKŠZªäUôôÓ£ÏÑ£'?.ùŒe®}<£¦¦öð‘ã ¥”££¥«ÏÑÑÓÆ YÒéÓwòó)ŠBžJ£Ðh-nïÌf‘Ëñ½û±Ù†ÛöÅM™œsïúòE+®åÞ(/ÙÐÀ×xŽ@ ^µjÃåË7øš×ggcàÀ~% ¯îÙÕËPgÑ䱊K§y<>Ï …r™œ I5¨Åùcee?êËîÚŸ~.$UR©ô3¶IûÈÜõë7««kFô0ÈÃï‹îÃü½G~å«o •{+O"‘Bç†F3È^vpàðf¢F£¤Ûi•N©$~ݵÏÝ­ûõÇ×Å%Þ.¾µfÙÚÄ3‡–,+«(¿qãžT*£(jÛ¶¸€€1ÛöïÈÏ/¬­­ë„oÍ~}z’b‘œ­ßûË1Êòâ—žªÌú³¤¸ävî­ÂÂGB¡€¬yA^úƒ^÷ÜMÅ%9¡­ÍvssùŒmÒ>Ië›7ÇOøŠ q‘ˆ4†Ñ0:ÍÉÅö^ÁÃGÛØX«TªÆétº©©±––V'Ê; ‹ÍØœfw1è;E]}ǹÈêêš””´Ù³¿m›Ó]¹rÍÁÞ=ûÑ•ˆ9+ÿuæ@p`ÈÁ¤ýÁ_‡LJøfÚ·±Ëµµµúöí¾reXpð›×l ]µ0bÁ2ƒillø^ëB¡¸¸ø©‡‡³Ž÷ ‰3õâE•¹¹‰¶6»:OeU-¿ª&fÉdéý†[—ŸMËMŵt¸\:ƒnfjÜÅ:@V®ïÙ›Vú %›ˆ«ä$Éd2I’d0ŸKtt™{ø 0hFà‹ŠrWÒL:£è›èìÝ÷›X$«©}‰ÑhÃh SϘ>-8xNoVljÙ,•Ê´µµù|““Cxx(›Íþ¤5N­h7M@§ùS£q×k«ÞtI’»víÏÊÊær¹8Ž«T*‹µÜÃÃýc\dUUÍ/¿ìÞ²eg›ù4ƒÁIÎ:±{ÞµñQÓýƒç¯³xú²…ëæ.˜:rRÀ’ÙÛ›3 ÃÞÛÃgHÒÉÓa+BãýY©TjޑׯßÉʺI£ÑfÏžjdôÿ‚â{÷ŠRS3{÷þG÷î55/32®uéâatŠR5» ‚ rsïgeÝœ7ï[Û½ûppðx.·5(?.*÷Ã<š™UÃùãU¥OŽ>—œýï¾ úúëQFF†¥¥Oã¢7òÅ/¾™Ô“ÍÑÕ¥³Üi–G/_{ô豉‰±FæÊÊžmÙ²sÏž›7GO:ÁÖÖº°°(>þ@\ÜÞ ¢fÍšiffÚ\¢£'­b‰D¥Rñù"‘PÌç‹|ÑË—<Š¢ºy¹|ÙwêôQKÂf-]>+lù÷K–}?öëágΤAQTÓÖ–†Þðá“'Û·oÇŽ›÷xx¸1ÇñÏ#¦ÓtW(à­¿[­´¨qAAœ:•xøðÞ'EF.Íȸ,•Ê>ÒµYYY„„LoKkÌšýã¶U?o>¸qÂ É #æ}Ýâ²õKçO\´ b^ØœÅVVÆÚÚÜk×nÐét Ö‡-?yñøìYóRRμ åú÷ÑéÌ&ïuQQ) ìooïÚ½{7`³ h´j“Éìß¿'p8&F÷öîjfæD£Ñ;ŽÛäåå:TfnÏ÷Vo鞪`…„Lžæää`mm5dÈÀˆÍë«­]Ë$„Öèo™óÖ[x÷¦TªŠŠ*¥R©)ÁÉÉaÁ‚Ù¶ÐÖÖ<<ÜçÎýV¬mQãÚÅ%:z4×Ð ”ËñªÊÚû÷JJKž«Õ”Z @4€Ô¯ü¢Ô‰L.#W¯Þèãã=tè333M!‘‘ÑcÇ~Õ¯_ŸÆb§LæLj\ܾ°°…ŸG@—:|,(êêë²°ÛÙ-jìÝ{Á 7½kïÍ›£?žÌ@³ŠúiõÁ³ S¿˜>gÉ+Gdg_žöåô…‘ V.Šàpè¶¶63fü¹B.—„*vkì•KW'…Lܲ:F,–hi>>>yyyC‡öÇ0BSryy¥½½õ“'å4 ÇEE¼GCX¿*•\­î@-€·óò L.WQî=eƒ¥ÜÜòqãF›˜°X,æëÛëÆÀÁF¦>=©$--†Ñ!AMZаfXóýíÝÙvä]ûÈIªpœ,.*ïéÝwæô È7×x I’¢ÔL&3íüECC}ÿašÜá÷ßOääd4Û}âÄÀuë¶„…-$AI$AJÇ …\&K$eO^°YlÓ·‡ÇjµZóRâr90nÜh‹eggµ<9ùÜ￟ŒOÐ<¶„„×.]%IR3 yäÈ/0 ëÞ½EQ!h_{¯NU•Jõ–1b––æ99àÖ­; ñïzëÖ¸‰5G]¼x6*j9´h´¶7ËÑc‡Çœ¸ó·#GŽT(䎎C†ô600X¹:á·C)W“c"Ö³L÷ îeÜNúrÆÊKg‡Ý¾Ëå6ï0õõí®P( i4,/ï¯o×»òòòQÏžÞ!“J_^¹’ãååÉ`° ¶ö+ßsss6ÛÃèzz:àááimmíädÞŽþãÓ«ÇÕìln¨¯g©VÛÄÅl¼sç®BS%Š8"¼sÛAâ"¾D*ihh077355~=!U«ŸÂÂ[Ûßé-Ö¾N's”ŠR(.WO*«—É¥J%ãJW*J¹W(”2™B*•K$2‰X*Ix ‡J Œlm¬5%ØÚZëèp5¯©¦•xx¸½~F//O™LþøqñÚµOÇëšõ ·ûHú¦£2ÎŽÊ8 [{ |ûp9WWç¢7>c Ó××‹ŽŽµ··}ÓÖk|èkÞðï4ZÛ°{×ö‹ç¯ Þ—p€NgªT*…B½!võO1©Ùg'LMHúmRÀÔ„¤ßÆùMXýëªà/C&î92@¡7+ÊÚÚÂÎÎ:;;› 0’T™šZ㸨Ù>•••÷î=V©@©”@]]½ŽŽ‘R)}{SF#™J¥lGêæÙ%å?©Ê†:æÝ«:WNq2õ£ËOmܸcó/Û¶ýššø;«ºrÂྛÁÿ}gݽÛYYW\\œìíí˜Lf+Oñ¾.¡©}Næ’416öìæTßP#ËDB‰H( %BX$”…b>_Äk6Ô êë|ž°¢¢ŽÏ—tóêfiùê=É`0¦N”t¶YÉÉÉçf̘ÒBƒ…HìííÅår33¯4>‰ôŋʎӧ¬Ñ¸Æ‡:…ÌÃÀèíN›6!1ñxK-( ?¿1óçÿ`ccõörLMMÒÓ3ÿ,.~Ähl63vÝú•±‘!Á?„. 'I•X, š½cͽVþ1¬çðU;~ è3rÕÎÈé3/ _¶T¥Rêêê6Fúÿúúv …ÇŽöññ QTóøôË/¿T«áÂ…+-c±Xµµ/;TWÛèêéFxÒšeŠƒ›ÔEwôŒŒ¾ žRùÒ ÌIDAT>%à [+ {Wç.“‡öã<(¸”,8sèðî_;8ØYYY´^æÞ×%4µ¯3Fs,‹ÃeÖ××óù">_Ìç yåjëùôônš€¬_¿êôé”ÜÜ;[þýïÓ••UÿüçœÆ-b±äUÊsôdxøâÑ£Gde]‹ŒŒ~ñ¢2?ÿÞŠ«ÍÌLš¦{í>h^XXÜTãÔjAHv¼>)¢)K–,xù²~ÍšMe"‘8*jãGEš¶¹ššZ¡Pt÷îÀq¥R©lñ®ƒ‚&ÆÄlÙ¿?±¸øI||³gÏ E£5S6ÀÚÚÊÒÒpéìЙ!3fͬ¯¯·µµ¶²2žè?~éúЩç¯Ü1uxPÄöÓ‚¿õͶM›Ølº••UÓÔ¾QúíLMÙlm—n8.ÒX é1™ÌÀÀ€;wò‹‹«ÀÃÃ9#ã¢TŠ@}=Oc´¦÷Þq&–q8\m-VN^~QI™¢¼¿yQ]Ú}Äè1&~ýu gßþòòâú I‚åéµxÆãr}¥RÉb±X¬ÿÊIªšU‡¦[ZéÍj_;Ú¤}zZ-­,ÙÚÚwò jëªH‚¤(ŠRƒZM©)5E©U*Iª‚$I€Z!Ç…Bù„qNNMcc33Ó ά[·eïÞƒ\.W"‘ØÚÚ¤¥n:_">>Añùúö7n4lݺnóæ?ÿ¼; Ào÷îíZZZ'Ož€””4KK‹S§’àÔ©ä•+—µCƒ¥Z Ñ²fu Y³I¯½]9—/§nÚôóС£Œ 9mýeËþéâ⎎öÆ 2ä«ØØµ½{÷üþû…))ǯ^Íyý®×®„‹­ÐÕÕ]·ne@À0ð÷÷{Ýh <ÝŽ;4© ŒC§cžž––üÛ7.544˜ššR”ÚÁÁNWWǧmØ3+pöØÀ±«£¢~˜óý±#Ùl†½½Ž1™¯|æÊ•\HKKóò²70ÐëÓ禦¶j5Åçóîß/€›7ozz:hÄýñãÇîîV..ü‘âï?dÀµúîÞ½‰º66¦¦Fuuu =zäáasÿ~!äççwëæÀá°Ú±JËårgG=Ï. {Gâž„£­ÏÔ7¡DBW* Û¸R@œ,“gˆ1‡®¾¾½pg0è•«¤¤tïÞƒ°iÓÏAA“ì<(ŒO€íÛw͘1ù.1~ü˜k_»åIЏ,»Ü¸)3.óÐÂ_Þ· CCÇÖ/ZŸ––¾mÛ®¦3ºÞ‹Å1⋉-,Ì[WkrÀÂÂ[]º¸}l#¾sÑú÷2N‹7òºö}*´Æ8­ÿ-Š¢‚¤Ó1µ4úEQ”T*»{·dñOaVF[ZÙØXK$c ÚF(ÆÔÒÒe³õq\¤Pˆ(Š`±tÔjŠ dÆ`±t´µ q\„ãbƒÍáËå<s8&,G&ã„T[ÛÉäªTI*˜LŽFæ¸\3Íž,–‡c¬Pp\ôzŸF‹¼ó· þ†çTVV§¤œwvvL:yúÊÕ›C‰z‡é³ÍìXZ,@XYYUSYq5+«òeàAýƒ‚&¥§gzzv [ø^•« jßßû-ˆçQ35k·hÎǧç¾}¿¤ª5¡>ƒA×ÕÕÓÕÕiʽ½I¾Q>5*Þ)po±Æ'*ŽoldÁ0--V³-\.ÇÉÉrÕÒÈsçέ]A£¦ ·Ùì@Š"ärž\þß‹Òt/E‘ …@¡ü•Þ*;%¤ÒºÆ)Ri=@ý_Aï¯B^i4Ž‹^ïÊh{Œ =<ÜŸ<)ëÓ×wØðaéé™IiéAb4šP$®­­377sîân툤§gñÅCšjÜ;—‡h¥SuœÚ×>2gdd §§KQTãDœ·z6N§Óéô¦[ï4ôóçPXXìîîúÙ¯Dö™iÙßÐ> swwq H’000èÌ«l²ÙìûöìÙÉdÐh´þý}>,¬¬¬æóA°Ùl#{{;©Túðácmm¶·f~Ût§ŽVûÚGæètþO-‘H¼`„™sæ„ìÙó3 >s¥£¹ºº(•8ƒÁ¤uú…„étº®®Žæ»……™±±‘R©lœç€a“Éd2™ƒ`26W혵ïó\$]G‡KQ|Tù;›Ò}ê‹Ó|”Î`0Œ¶\3ªÖ>´®4øÜ_ÈÉ@|Ê™;DÅF}ˆ¢„55ëA‘qÞ>ÿiNÎÈÈs>š±rMy5<¸v2=d,ñÉñœÓ|èbTlÔ«žÖÿ}@t^ŸÚæÄg’9d@ Ì!’9@2‡@ HæÉ@ ™C HæÉ@ ™C $sd@ Ì!Ä›iù—½^_š@ >™¶pXÓuéZCf\fôŠè÷= @ Ú@UPÒŠ@ >sÌ!$sñ)ÃhLƒ?H. Š@ > DUhŠ‚ô;­Ñù?Vì¤zöãØýIEND®B`‚snd-16.1/pix/sceq26.png0000644000076400007640000000203411147553270012750 0ustar bilbil‰PNG  IHDRû"®_s3PLTEÿÿÿàààÀÀÀppp€€€    ÐÐа°°PPPððð```@@@000#/¹3 pHYs  šœtIME× &;‘Z‹Ë|IDAThÞÕ™‰–« @Ù"üÿ¯}¨ TAìHgúrf-‹7$! 9ˆÖN.#ß"wxo egN‰Ñ}8áúKT¿Ã{=<3©!„;ÿãdYnöHôºÎÆÊOé„ì)oa¾/£Ä¯[R,âIÓ(SÖÉÀÖ ŸÒk=c¹é.oi¾#¯XtxÓ(’l`Ž~ÈêJOå¶ðîóy /GÉ´_[F¤cŒ#¡ƒs[x Þ}À1NY× `‰Þšîm^*À§ZË =Í·ñ&`‡à ¨l"œü?ÑÛ×s~Ð ÄŒ™ûYJ%÷¡œN½m?U"¸ÉkfCFb<çSÚü|7‚ FJ䫵ŽS³ê¾|«ÔìâCÆ·aw·—µ­¤É+ý‡”H¿fØÐã|o^>Ãh´Yé×°Ž9Ô/uAw§Eôý¨nªkrÍ °ÿTzœoç Àk¦ŽÞMÇ1·`øÛú¥r%Ý¢2Dt¯‰'3F3ÁVÛ?ZVvì/sž™·>º =ηñ’ØL’Á>VóùqNS©Ù$(,%S¸{ ø:´ÅJ]¥ú Ò!_‘Q¥íæ° ¶yùĽâ\HkVô8_àÍ‘eTBÙóãjÖ1ëWüÕPm¢÷uo”) ÞèMôˆAkÀ³êY¯Àã-éÉ{¡ºë’eXø*Þb½ÁR.Ð]÷B}2laЯñª ÙÖ&‹ÚR³û¹>H%´¡Â²È nO^ Ýã½T â½'¯¶KqìdvÕÎõA*  0èWyó⚆½k÷s}2,|¯qæ\×­áÜ_»³¡Wûü¹uϰuïÈk^¸{=¿T‰áÜ¿ßÙbÎýI~ïÉ;a~73šÂ.»§0¥ d£ûS^L‰ÕÎ1ÏZ7«½ZdkÏxî—ïëþã0®fû¼å)/r \®%ò^aÁx¸ô çþtgóIÝ3¨‹–ǼH$å×7VkÏpîOΚWÝu¯B5qßãäò¾Ix ;÷/O;ûüT÷-^j›×­KÏpîÿ%ÝëP7pïó‚&öÚ‹˜_Çxî¯Ô•Ó]_SÕ¡Ú¸oðfy-^{«‘_‘úÓò–ž¼áîÒ“—3ÔİUü¢}½î=y'ùò:óëuïÉëóÂòFó¿±{G^>ù‹ 63óíáþˆ÷¶6)¡‹\a2IEND®B`‚snd-16.1/pix/pad1.png0000644000076400007640000006056211147553270012504 0ustar bilbil‰PNG  IHDRô äN§ãsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ 2!}€‡ IDATxÚìÝwX××ðï6–Žô*U±+DÔhìb,AÑ`‹Š{ì1þ¢ÆX°ÅšD&Qߨ56@EEìETTÞX¶¾ £+ ‚ìÂ.œÏóðèìÎÌÞ9SΔ;÷²nß¾,×××!„B´SFF¸úúzpww£hB!ZêÔ©8°) „Bˆö£„N!„PB'„B%tB!„¨÷c#äçàøñÿJ}>hÐðxÅ“ïßÍ›7EóæM˜ïE":ðñé ##C•:/O€“'Ï”ú|Èàp8 ŸI$DDD¢s瀗/_#"âúõëCC••)77±±qðòòd>»xñ2:wî6›™L†Ãã%š4q¯¶üäÉSܺu—îÞ½3¬­­ª4Ï .C&“¡G.´Bê4™L†ððtíÚ‘ù,:ú6ÜÝÀØØ¨Üi8ÌK­¬,Õ…ž––Ž-[~CAA¡Â gÆ)((„X,V˜N.—£  ;vìFRR²J˜’’ŠíÛw•*“\^z\¡°ëÖmVHðÅã–yóæ(**ú¤2%&&a÷î¿>[µj#¤R©Bœ$qµmh o°oßA…­Yók…¦½rå:n܈Vú]QQ„Â"Ú“ !užD"ÁêÕ>Ûµk_…ò^aa!8‚˜˜'Õs…îî 0nœ¿Òï’’RеkG˜šÖSøœÏçcÜ8DGßVz5›žžÁ ÛØXC__¯RoÜØ½œ2%£°P011f>—J¥`±XèÖ­ôôtß»› FBB"Žû]»v„¾¾>lm­¡§Wñ2éèð £ÃC~~ ô‘c°XÅß''§¢[·N077ý`câÕ«×̰±±,,Ì!‰—'€¹¹™ÂrÙÚÚT¸LYYY qêÑ£? 33 zzzÌFÇápàäTðúu®^½>_––066†…Eq9²³sàîÞºººJO D"Qñ†ÅåÂÑÑ)·³ÎMLL˜8dee#++›™‡½½ø|:JBj…´´täå ˜aggG°ÙÅ×ÒcÆŒÀë׉¥®øÓÒÒÁáp‘›› °´´¨Ð]î %ô'Oâ°sç@³fMСCÛ÷nBhè%´mÛ?þ8ï£óÊÉÉÁæÍ;ñòåk…†Ù³˜…¬ˆ˜˜'L™Z´hŠÏ?o¸}ûöí;ˆ¼¼<€›› 3M~~V­Ú€ððœ>ý/\\œéééXµjž>}†uë6ƒÇãaÖ¬)hÒ¤Q…Ëãææ77œ;ŠûaÇŽÝ;v$¸ÜâïÛw.\F]0gÎ4…[.—.]a†­¬,0nÜ(äääbß¾X»ög滑#' 4ô¸J6²uë6C"‘0É”ËåbÐ _tïÞÛ¶ý+W®ƒÃáàÑ£'èÖ­3¾ùÆpýz>¸¸ç ;ÁÌïÆhüóÏ¿oïÞŸà <]º|~ý†aà@fÛØXcüøÑàñxؾý$&&1óñôl‰É“ÇÑQ€¢5™|_q?}ú »vý¥pÛ³g7 < Ìy ùèÝ{||¾DJJÀÅÅ Ó¦M€¡¡aÕ:ÇcÎtuù ßÍœ9žž-Q¡ONNÅ›7IرãÝ­ß>}aúô‰ÐÑ©ø•Ùûeâóß•éÔ©sðñé…nÝ:Nœ8ˆˆHæêwÇŽ_1~üt…yÙÙÙbÇŽ_áë;›6ªôÙz‰yóf eËfxð Fáó?þØ«¤·mû7oÞFƒïûùùçµX¼xŽÊËT¯ž V¯^ÊœENŸ>Ý»wÆŠKðÇûÀçó1bÄ`…iz÷öFïÞÞÌ•~‰ÿû¿£3f<¿sç>àØ±ShÛ¶5®]‹TClN0*ÊsçÎ}*<¾P…´´txx´À¤IcÎ^{õêAGBH­0oÞLŒýM¥¦yöìîܹÏÜñ¬¶„¾dÉ/ ¹ˆÌÌ,ܹs‡_ çå 0bÄw¸wï!ž6êèð˜ Öe9uêìǯÐY,V¹·Ž?L\ïOWÖ«h\.÷£…ûX™Ê{ÍíÃ2q8:š®8ØzU^¹ÊbòaeŠƩDI%‹ÊúX¬Ë‹‡ŽŽ>\õ<—iPHÙwEâñþô<ï“—B4Á‡Ç¸’  ²Ž£;þòæS¡ãýÇFð÷ŸXæ òÆùá»ïFU{ð†ÿ©©iJ¿1bHܶ:ô[ævó‡Fú£F «ö2ùùù#''Wéw]»vDÓ¦iO$„*˜9s!+Þ÷Ù`±XÐÕÕ…žž.23“‘žž6› .—ö{B4.¡—pvvAaa>ôõõ!•JPT$*5Njł‰‰ *4_™¬üJxr¹R©r9µ`KHuãryprrF^^.¬­-‘’’¦4ñóxÅ ÜÞÞN%û}É8Jè• ££ƒ‚‚|×¼srr,õàÞÜÜ&&&ËåÐ××Cvv6¤Ri¹ó àAƒÊçßÿEŸ>}°}ûvÚ¹ ©f&&ÆHHxÅœœêC,+ŒÓ°¡;$’âÏŠ¯Ô³ÊgRRúôéƒW¯Êîòùóç˜0a&Nœˆ/^Њ y†^Q|>ÆÆÆÈÉÉf>{?¡s¹\B(|WÕ¾E‹fˆ‰yZî|Ÿ>}úÑßÞ¶mBCCáããƒÑ£GCOOùîÌ™3¸xñb™Ó¶iÓ~~~½‚víÚp¹\ÚZ‰Æ±°°DffºÂ~ÿþ¾oeeƒÜÜw ¼^=˜šÖƒPX@ù]ºÌÌLdff–û»ÿý7FŒ©TŠýû÷cáÂ…Ìw?ÿüs¹Ó/[¶ ::šùªœL&âE‹Ð»wotíÚ•62Rõ„ÎbIw’ðàéÈd²·ÏÁYËaN¡ÂNÛ¸qÄÇ?W˜ÞÊÊÇ8òó…¸r%üƒ+{~¹…6lΞ=ûÉ ×¼ysXXX(ýÎ×ןÐÿý÷_DEEaÆ àóù´Åµç‰ðàÔ€D"Ç…\HÅ4ps`Æssk€‚‚|…i ’’ ##ÉÛn†K—®¢¨¨ˆ§°°.. ËüýfÍš¡E‹O¯,Ëçó˼³·ÿ~¬[·‹/ÖØ„.—ËqñâEÀÄÄžžž´Q’ª%tv=Œo=EÍxòøôôLàälUªassËRɼäªÜÙÙ "‘b±2™:tPGW·rC¼~ýÑÑÑèÕ«ôõõ?:¾ƒƒÊÜéµÅ„ °råJL:µÌBTåsó¶h6°¸û§.Â×÷+ˆ%ï·X,†®®.òóJ%¥¦wssAVV ))­[·.5Ž™™Y¥ÊtêÔ)8::V(ÑóxþŒëÁÒÒPé´îîî8tèÂ-ñ«W¯ÂÄÄ„öòò‚¥¥%X,sr_[;vŒ®ÊIÍ$ô–-=Þ6,S:¡ …E000üäy»¸¸( ›˜˜(ìÔ@ñmû&MšÔ‰•åää'''8p»ví„ h &5ÂÌÌ;w)õ ½DNN^™'ù£l?wwwWº?Ôv]»vÅ¥K—Ð¥KÚèˆú:<~üPé-÷””T8;»Q”UlèС8zô(6mÚ„iÓ¦Q@HHMMÁë×/•~÷èQ,zöìAAª¢3f`ôèÑ”ÐI…PlçÎ=z´Ò |Ý»wGXX‰Z$33³Ò ¡„®rssahhXnï:„Úƒ*ÄJè„B%tB!„PB'5‚Ïç£Y³f¸}û6ƒB%tmNè^^^¸rå ƒZJ__ÞÞÞ8qâƒPB'„mÅåraooøøx ¡„N!„Ô‰Àº² 2™L­ý¥ËårÈår°ÙtŽDˆ¦ËåJ¥Ìðûÿ×4<€D"‡‡­8B ½<Û·oDZcǘáääd•ÎÿñãÇÆæÍ›i«"DC¤¤¤`̘1ÌðË—/5¶¬999Ë奚½%„ú&OžŒÉ“'3î®®´ö ©ålllpæÌf8((3fÌ ÀZI%÷‡%‰Ò?M¾½¥Ä… T2/©T ¹\N=ª%•JËÜ÷?µcBH ^¡§§§áÖ­»J;g€¦M›C(,¨ÁLKKCvv¶Jæuÿþ}$''cΜ9´•# ñäI,bbb”~Oí‘WÞ£GдiS ©¹„þèÑ8;—ݱ‘‘rr²k} <ˆ!C†ÐEꄬ¬L˜™™ÀÅÅ©ŒýÞ˜‚TIû÷ïWÚz«V­póæM$%%ÁÖÖ–EÊDU²U$<<}úôAAAZkÓ¿OWW÷½[œ„ÚÈÅÅ999ÈÊÊ¢`JèÕe̘18tèòòòªå÷z÷î/^ 66–‚O!”Ð !„B B!”Ðk›Þ½{ãìÙ³B!”еل °}ûv !„Jè„¢-âââÊl‡ƒJè„¢"##±k×.8p€‚A(¡×˜;w.‚:æâÅ‹èܹ3 ð×_Q@%tmwïÞ=´lÙ’^¹r%-ZD!¤H$055Eƒ ÷ÉóòõõUè òC6lÀ¬Y³(è„zuãp8Uî˜æÜ¹søòË/?:^Ÿ>}púôi :!ÕìÉ“'ÈÉÉAÛ¶m«÷ððÀ½{÷ “É(H„B(¡kºœœ”û)!„B B!”ÐkÒ_ý…‘#Gªýw6mÚ„iÓ¦QÀ ©&ãÇÇo¿ý¦’yeffÂÔÔl6Ž %tennŽôôtµÿŽ™™²²²(à„T“ŒŒ ˜™™©d^»víÂðáᣣC%”Ð !„JèD­ììì””T©iÆŒƒÝ»wSðÑ@iii077‡Ã)õÝ¿ÿþ‹ÁƒS%ôÚhüøñرcG¥¦ÉÏχ tðàAôíÛ†††¥¾300€@   JèÚ&55<@÷îÝ)„BjTyyúÙ³gHLLd†…Ba•ç) ‘••;;;Ú’Ñ@B¡‘‘‘Ìp\\œZÅbÁÞÞ pppPé¼mllлwoìÞ½cÆŒ¡•KênBúô©ÂŽ­Š„NÑü„~ñâÅjKè<ƒ Âþýû1gεœ0P들Î'ôÞ½{£wïÞÌpuU:óðð@XXîÝ»‡–-[ÒGH5ªW¯–,Y áôéÓR+Ñ3t5366äææR0!„PB'e322BãÆ)B¡„NTLOOj›¿\\\ðàÁ 6!j$•J!•JÁãñ(„z]4þ|¬^½šAˆ–‹Ell,|||(„:!„B(¡k” `åÊ•*§@ €õ¼DHƒÔÔTtéÒ…‚A(¡×¤””X[[«tžûöíƒêÕ«G&¤–+**‚T*¥¦ž %tB!„PB¯VŽŽŽxýú5‚Z®[·nHKKÃýû÷U>o@,S  %ôš²}ûvL˜0AH-Ççó!“ÉÔ’t}||pûöm…~)¡„N!„PB'šfÈ!¸~ý:^½zEÁ „JèD[ñxuÌBT†^[#„²dÉ’J¿צMDEEÁÙÙ™Hè ½¶5jþüóO !µØ¤I“°mÛ6 ¡„® ÿý÷š6m '''*W—.]péÒ%ZA„¨Áœ9s°nÝ: ¡„^›ðù|ðx¼JMgooÂÂBdddP Ñ2)))°²²¢@JèhÑ¢rssñòåK !„Jè„B¡„N!Z­{÷î £@Jè„RÓ1oÞ¼OšvذaØ¿?‘PB'„š‰6mÚP %tB!„¼SgZŠÛ²e‹JûCWêÚ‘ÕJNN¦þÐ ]¡×6“'Oƹsç˜?›OšOzz::„ &|Òô 4À³gÏ”~ƒÆWi9·oߎ‰'Ò–M…ý~òäÉÕöÛÿ÷ÿ‡ÁƒÓJ ”ÐUÅb)ü©b~Ÿbâĉjm¶‘ÅbA.—Ó–Mˆ ÷ý[·n¡aÆ066¦}‘PB'„mu÷î]¸ººÂÐЂA(¡B!„:!„B(¡B!”Ð !¤Î*((@ZZœ)„:!„h«ôôt<~ü;vÔ˜2YZZÂÙÙQQQ´‚%ôO•––Vå>‘ƒƒƒ@Á$„|cccXZZ–Ù¦©›¸‚Ê™:u*BCC«4kkk¤¤¤¨uGþü9\]]i…B]¡mTr+.22’‚A!”ÐIuKHH€ƒƒ‚: 33&&&àp8 B ½¶Y¼x1~þùg !uÀÁƒÑ»wo˜˜˜P0%tBÑd†††èܹ3NŸ>MÁ Õ¢ÎTŠ{ùò¥B—©EEE´ö ©åŠŠŠpçÎf8>>¾Ú~›ÇãÁÞÞ/^¼ A(¡«Òýû÷qíÚ5f¸   ÆÊ¢««‹fÍšáÖ­[øì³Ïh+$DM püøqføÁƒB ]ÛùøøÀÇLJþçŸ*=­[·ª¤?e===´lÙׯ_§„Nˆ™ššbÅŠÌpPPΟ?O!µ=C¯„§OŸ¢aÆBêG¡I“&B B´Y`` æÎ«qåjÓ¦ bbbŸŸO+‰PB¯­¸\.¤R)är9ƒÞe2d2™ÊçíááØØØ­D(¡5ûöÛoqòäI¤§§S0©A¾¾¾ˆ‰‰ÁÓ§O)„:!„B(¡«Lxx8lllШQ# !„JèÚ*//<ººº*™_ýúõ‘““ƒÜÜ\ .!„JèÚªmÛ¶HHH@RR®]»†ÆÃÌÌŒC!„º¶zúô)lmma``@Á „B ¼Ó½{w„……Q !„:ÑfãÇÇŽ;(„TÁo¿ý†ï¾ûN¥óLJJÂË—/Ñ®]»*ÏkÚ´i ¢E(¡W”P(ÄîÝ»1iÒ$ !uHtt4Ú´i£Òyæåå!;;õëׯò¼:t耈ˆZQ„zEÉårBOOO«ÊÝ¥K\ºt‰V !„PB'ÚlàÀ8zô(‚Bê€:Ó}jpp0Ž9 '''×x™6lØ___|óÍ7´%¢IIIð÷÷g†_¿~MA!”е]@@˜aWW×/“ŽŽD"m…„¨‰­­-BBB˜á   ̘1ƒCj%ºå^r¹,KëÊíââkkk\»vV"!5| !„ºèׯNœ8¡uå644„®®.õºFH V¸;H%tB!„PB×TiiiˆŠŠÂW_}¥–ù6 G…P(¤`R ‰l6l¶f&gÍš… 6Ð #”ÐkšH$Bnn.,,,Ô2¤¥¥A*•R° ©„Ç£U«VQ¶Øl6Ö/Ë?þˆåË—Úµk‡‡ÖŠå"šC"‘ ''æææZQ^KKKdffB&“iuÜ‹ŠŠ°mÛ6¸¹¹!::Ë–-Cnn.mTgz[»xñ"nß¾Í çää|tš¨¨(èèè U«VZ¿ü-[¶ÄÉ“'‰îÝ»kõ²äççÃÀÀЪU+¤¦¦bóæÍX°`íÑDANNþøãf8<<¼BÓegg#$$DkîþŒ1ýû÷Ç Aƒ˜}C½~ýwîÜÁ¤I“Я_?\ºt ›7oƼyóÀåriƒ¦+ôwg°îîîÌÇ£µ¯…V¯^]*q÷ìÙçÏŸ§àRx<žÂ~_P•™={6Ö¯_O+ä#6oެБM—.]±XLÁ¡+ôwš5k†fÍš1õá6z]tëÖ-Œ7®Ôçÿý÷&L˜€ÿýï°··§@f?¿Ÿ„gÏžÕH9<< ___ªKWèä};vÄ•+W´:™7iÒDéÉŸÏÇ!CðçŸÒŠ&UvøðaøùùQ ª‘X,VzçTGG"‘ˆD ¼¯sçθté’Ö–?** M›6-óîJëÖ­! ñèÑ#ZÙ¤J8€!C†hU™W¬X~øA+ã}þüy´lÙ²ÌG"ãÆS¨ A(¡WÚóçÏ5¾§%UJNNÆùóçQXX¨qe+((@^^¬­­ËÇÔÔK—.Å´iÓhã%uN‹-pÿþ}­,{JJ LLL «««ô{¼xñ‚V2%ôO÷÷ßcøðáµj™Æ;w*|vòäI,X°[¶lÁ­[·°yóf+÷›7o‡.]º|tÜÑ£GÓ­wB´Dnn.bccáååUæ8ŽŽŽàr¹5V‚:ÑHÆ Ã_ý…­[·ÂÛÛÞÞÞˆ‹‹Ã Aƒ0fÌÌŸ?—.]Ò¸«ô•+WbáÂ…×ÏÏ'Nœ çn¤Î™2e ¶nÝZês‰D‚U«VaÀ€ÈÍÍÕ¨}C àÅ‹hÑ¢E™ãØÛÛc„ øé§Ÿh%SB'ï333ƒ¥¥%BBB‚™3gÂËË‹y¼ ‰Ý­ÆÇÇÃÉÉ©BãÀßßÛ¶m£•Mê{{{$$$(|&•J±uëVDFFbùòå3f 6n܈üü|­Z6[[[¼yó†V2%tò¾Ã‡cРAe~onnWWWDGGkDy÷íÛ‡‘#GVjš-Z ==III´Â‰ÆØ·oüýýÕ6gggèèè 66pâÄ Ìš5 ®®®8|ø0Z´hÇ#..Nc*ÐýùçŸ5jm”Љ:ÁÍÍ ÷îÝÓˆ¦$ÃÂÂУGJMãâₜœdddÐ %•²zõjÌŸ?_-ó ©ô¶\666À?þˆS§NaÆŒèÖ­›Â»ø°téR<{ö ÙÙÙ5ïóçÏ£gÏž÷÷ßWÚ¡„þÑÏÛÛ»Î.ÿ°aÆÔÔÔ-Ç‹/`eeõIÍYzyyiÌ]¢=RRRÊ}›BÓYXXÀÃÃû÷ïÇÆ1pàÀRãØÚÚbÓ¦MøþûïµjÙñêÕ+ÚH)¡kÎYº¶˜0avìØQ£e¸zõ*5jôIdøûûcïÞ½´1“gjjЦM›âêÕ«Õò{ .ÄÞ½{Ñ¿ÿrÆ qýúõ‹Ke§±X,ôíÛ§N¢Š:©ŒÎ;#&&iii5òû‰066þäylÚ´©Rï¥?}ú™™™´ò‰JéëëÃÖÖyyyÓɈ¡¡!4h€û÷ïC*•Vûï ܺu ;w®TBoÑ¢îÝ»G%tRYïwUZÝRSSqùòå*5Áinn^áçè'OžÄúõë±iÓ&lß¾ÚŽ&*·zõjØÚÚjLy „K—.ÕÈIûùóçáææVªívuO¶oß^ê-Jè¤Îppp€­­-¢¢¢ªý·7oÞ\åVßLLLкuk„……•;ÞÑ£G-[¶ÀÏÏfffxúô)† ‚!C†`Æ ´1*éÒ¥K…FªnÓ¦MCPPÖıE‹(,,D\\\…§Y³f –,Y333¬^½K—.­•ÛXém-11Qá,”©ccc¸¸¸àþýûøì³ÏÀápªåw˜˜ˆ¶mÛVi>ººº°³³ÃóçÏËì¾  >„··7X,š7oŽæÍ›C,3Ï÷"""àíí%K–Tê!©Y"‘H¡mÿ]åææBGGzzz*/KEÛQ¨níڵâE‹ªõ7¥R)233aaaQéi­­­!‘H*ôhL(bçÎ8tèŽ?kkkôêÕ W®\Áœ9s°téR­î?¾Î&ô¨¨(…žÆA™ãFFF¢mÛ¶`±XtDDq÷bРAUzž]«V­*Õïù§jܸ1Nž<‰œœ˜˜˜”ú~ëÖ­ðôôD»ví>çñx033øøøÀÇÇ=zô@hh(mZB `ß¾}Ìð­[·Êÿòå˰¶¶†»»{ŠS÷îÝVæI¯:ÖË©S§pøðaµþÎÎ;Q¿~}ܸqCá"ÅÝÝË—/ǽ{÷о}ûZ³ëÌ-÷`íÚµÌ_ÉZ™ÐÐPtëÖú{/^ŒŸþù“¯¶·lÙRáñ#""P¿~}Ô¯__%e÷ôôÄ«W¯”žÑ/[¶ ^^^èÛ·o…æ5kÖ,ºý®EÌÌÌöûPP”8p Ž=ª5å=z4vïÞýÑñŽ=ªt7hÐ{öì©u}>Ð3tR!­[·FFFâãã+4~QQ®^½Šï¿ÿ?üðlll°sçNH$’r§ËÉÉÁ† 0gΪ¬ü[·nÅäÉ“>{óæ *u[¿M›6xùòeÕü'Dš4i‚ àøñãžæÙ³g¸zõ*ó÷±»‰A“&M>¹¼5Š+Êlñ2%%³fÍÂ?ÿüSæ]";;Û¶mÃØ±cËì_ýýýS§NáÀ˜5k]¡“º£qãÆX±bV­ZoooìÙ³‰„y‡U*•âÂ… ðöö†««+–.]Ê$s øööÒ¥KË}ú 22’š•­eŠŠŠpìØ1 <¸N.ÿ×_óçÏ#//¯Ìqd2&Mš„ððp¬]»Xºt)–.]Šyóæ!&&/^¬–òêéé᫯¾Â¡C‡>OOOÇ›7oÊí½í}íÛ·Gjjj­èš•:©0###tîÜ;vì@HHX,|||0uêTœ={cÆŒADDBBB”ž¥7mÚS§NÅ?þˆôôôR;aBB<<<ÔVþV­Z!%%gÏž…¾¾þ'¿ÿjccjV¶–‘Édxóæ êäòÛÛÛ#88¸ÜzóæÍCrr2BBBйsg…»[úúúøþûïqåÊ•r“zll,5jTåòr8ØØØ 11Qáó‰'bûöíž™™\\\póæMJèµÍëׯQTT„† R0>bÔ¨Q8sæ æÎ‹»wïbݺuíÁ©AƒðõõÅÆZ§ºyó&ŒÕw4nÜ{öìÁŠ+ª|µ¿fÍÚH­Ó·o_¥*=~üFFFmNyñâŸuëV™Í³ª²ƒ•¦M›"##ÉÉÉ€ÿý·Üž$Ë2a„JPB×III‰DûΨ&ruużyó>ú¼ªDÛ¶m1zôh(®wìØ±jéBqÀ€ؼy3ôõõ«<¯ùóçSR'µN·nÝ0eÊæ·P(Ę1c°iÓ&Lš4©Bûy=^ªìµk×`bbR¥ q^ aèС8rä1vìØOš×ªU«°páBJè„TVÆ Áãñƒ¯¿þ[¶lÚ×¢ÜW+{u••UkjÈÖuèСCÃgŸ}†õë×cË–-8tèV­Z¡Pˆààà ÷BתU+XZZ"$$DáóÜÜ\p¹\•œP¿Ÿˆ?ûì3ìÛ·Í›7ŸÏÿ¤ù¸¸¸àùóçZ½îª\˽AwØÛÛ•ù½¥¥%^kM@‚‚‚àèèHG·j°hÑ"ìØ±£Âï€k888àÆJ»¨¬ÍLLLðÙg­ËüžÇÓAQ‘P«–é—_~¡FƒÞ8p ˆ­[·ÂÇÇ?ýôS¥çáííþùÞÞÞàr¹J¥ SK¥WU´ ahh\¹r;v¬› ÝÜÜéJ¿ËÌÌBaaär9^½z…«W¯(|¯§§_£ ŸŸŸÄÄD$$$0Ï~×­[;;;Ú£«­­-Tz¶^݆ŽÙ³gÃÛÛFFFufÝñùº`±XHOWþ>~|ükxz¶‚X,Fhè5…¦–‹ŠŠÐªUkZž_ý3fÌ ò¶ÝPX·nÒÒÒ`kk ™L†»wïbõêÕ¹¬ººº˜:u*Ö®] ###…7têLB¿q#­[·FV–b+\2™ ÙÙYhØÐR©»TØ|¾n.|tt4.\‡R·†Hõø”¶œ5‰©©)<==__ß MsìØ1äææ2ÃîîÕt©©)HLL‹H$ŠïggçÀظ¸}ì´´|þùçJ.Ì4jyÒÓÓ«Üo)mïÞ½LsÉ¡¡¡èÑ£‡F—×ÈÈK—.ýhÏ¡¡¡Jµéèè`èСڛÐâ†>$—ËQXX|ËËåÁÉÉùù9 ãkׯ_¾w¥›¡PSÓâú¶qqO`hØ2ٻƇ„°Ù5[·}ûöðööÆôéÓ!‰`eeKKKÚÕ`üøñ0`À'÷QS{+V¬ÀàÁƒallŒììlL™2¯^½B÷îÝqãÆ ØÛÛ—êïC&“¡W¯^€¹sçÂÉÉ £GP\濫• k4¡gggAW—ˆD"dgçÀÂÂ\áj]"‘x·ðqqÏam]~­f‘H„ßÿ:uBóæÍ•Ž“‘‘ƒ¢oß¾ôª©1öööŸ<­¡¡! ý<{ö ë֭ìY³4ºM„»wï AƒÈÌÌ€T*…H$Vhƒ_,C.g2'ÿ))©hÒ¤y¹ó½pá’’’0|øð2Ç9~ü8X,úõëWérwêÔ }úôAPPd2fΜI±šðù|­k¬ÇÎÎ#GŽDpp0êÕ«‡K—.!;;çÏŸ/·©h6›Í,ë¾}ûpãÆ lܸÙÙÙHHHÀ7ß|£t:‹…I“&iFB€‚‚Bèéßf“H$Éd ·#òòrann>_çÏŸ‡¥¥ùGÛë^¶l<<<ð×_aêÔ©Jš+V¬@‡°~ýzBGG‡ö ¢õÜÜÜ*ÕC]M‘ËåLS¡r¹b±<žâa%557CDÄUdggÁÆÆú£w;¢££aii‰;v`„ ¥Æ9tèRRR —ËqäÈ‘O~Ë`úôé´±‘2ïâp¹\Œ7K–,Aûöí+ÕïPüx­]»v8sæL™ã©ªgO•%ôÜܸºz"** ùùù¨W¯t¿Ó%·æìím+ÔùƵk×ðóÏ?ãâÅ‹ÈÍÍUšÐïÞ½‹õë×c÷îÝ -Å-•ÕÛNrr2öîÝ[ª`B´IPPPv#“É K ¯o€ë×#ak[:YâÞ½ÛÐÑá2áÊóêÕ+XXX cÇŽX»v­ÒqbbbðÅ_@*•"**JỬ¬¬2Ûc/y†[¿~}ê™TH^^žÒ“JUâp8ðóó«ù„îààÈœqÀÖÖN¡k½zõÀápaoï¨ôVŒ:7®Ì&===™ç•ªpðàA 2DeóKMMÅ£GеkW•Íóúõë°³³SÙ{öW¯^…³³s•n7«;ޏpá¾úê+•ÍóÁƒ`³ÙhÚ´©Jæw÷î]èéé1Ý9V†*ÚÄþ†hÔè]Ç6ÙÙ9èØñ ¦n@ɾmnn;»ÒýÚ—TšSSSÓ2ßZ Â… TRN•ÛêáÇáëë«’^U¹Ÿ¿~ý hß¾½JNþ>üIM³ª;þ/^D³fÍTR"66•ê—BUuJª”ÐÛ·o6ûã­þØÙ™—sЗUø÷ˆ={öT¸™Ñ²˜™™1=o©Â­[·T:¿;wî`ß¾}*ç/¿ü‚Ï?ÿÝ»wWÉü–,Y‚^½zá‹/¾ÐØ8¦¤¤ ++K¥óܵkx<žÊ®Œ·mÛ •èÔËå" ໞÈäCWWeŒ!¯ðo:=zôPɕҷß~‹þýûkÔ¶úèÑ#üòË/ÐÕÕÕ¨ýüÒ¥KÇ?þXåy‰Åb<|øPe1SeügϞѣG«äÝó’ÇAS¦L©þ}³*[YUìlF_ß®R;ïûg­ÞÞÞ˜2e 7nŒ×¯_#??_¡6ñ–-[àííŸ~ú©ÒÏ7!•Çb±Ð°¡kö{~¥7PÜXO`` –-[†]»v1wZÞoœfáÂ…˜;w.Øl¶Æ6TBˆV%tu311Q¸uöå—_âË/¿T§Q£FÑ(LÉ« š¬S§N_ÛTâèééYã¯]Õfl6óçÏWøìĉ Ãëׯ§mU‹ös‡S£õ=ÊÓ«W¯jéK¢N'tmR=…©bG§8V:ûl'´Ï×ÖýœÍfktB¯'ô[B!Ú¯Î^¡Oœ8Q£Ëggg.c¯^½àìì¬Ñe422*·qMð)ï·’OÓ±cGk\¹Æ§qåruuÕØ¶=4õÞ¢E ¸¹¹ÕÈo³23ã•ÖXÑÑ1‹ÅBQ‘O?ƒžž œœ­ÚdŠk.ÊdåWzÑÑá}ôO.—##BTO""//Eá³S'Ã0p /Dâ¼N‚¬™qÿ;u¾¾_A,ÉW§äýóòp8l…&nËbll ‡„"¤"òóÓ!å«ç =$äD,c@IÂNMJW.İa¡§§ø:FTÔ-$%¥ A4mÚX2 Ž= 2ß=ÍÍÍŹsçСCê:•¨Lxx8ÓàX,ƱcÇàééÉœ½GGG###ƒy~—tìØ±Ì :oÞ¼ADD¾üò˽ÒLLLÂÕ g¤¼×´»‘áøfØ×hØÐEáóÌÌ,\¹rým“­½ÕZÆ›7o"55}úô)sœË—/C.——ê ’ÔM ‰Dpuu}›§¢••ÅTÆÎÊÊBhh(:uêÄ´Ë~ñâEp¹ÜrûPÿï¿ÿ`kk OOOµ–_%ÏЛv„fü¹yöÁ‘£§¡££}}Å÷P#"nàêÕHOÏÀ©SçðøñSµ-àÆ‘––†={ö(íîÓgoPPŠŠŠh«Ö999ؽ{w™ßoÙ²b±X#Ë~òäI…JS6l@ZZvïÞ””ܸqçÎCLL ÓšaÉv¸aÃH$¥¯~…B!‚‚‚––Vã5¼ÀÚ¹e©ý¾Y‡Aˆ“ ® Y³ÒíµoÚ´ééHMMÃÎ{ÔV¶èèhœ9s±±±Ø·oŸÒqΞ=‹ëׯ#22§OŸ¦®8pÉÉÉJ¿›;w.¦L™‚TKYÆŽ‹óçÏ(n©4$$=ÂöÑuëÖA*•âäÉ“ˆŽŽFDDD™o[ýù矈‹‹Ãÿý‡[·ni~B‹„HMJ€XTœ ¹Ù˜7Ñ,_öVjü˜˜X¸¹9cìØ‘°´4GzzºÚðôéÓ˜}ªp·çìÙ³˜sæL :3gÎĪU«  ÕZŽììl,X°@¡EÉÇ£~ýúèÕ«³¿]»v “'Oƽ{÷ “ÉÏ?ÿ-[¶Ä;w”Î;,, „¹¹9ž?®ÖåPI¥¸—aÏ–UønÆ >+æÇÍk1óÇu04® ­ÌiÇŒA[µ† mÜ7iÒmÛ¶Åßÿ ±XŒž={‚Íf#%%oÞ¼ŽŽzô袢"ìß¿@qÈÊn ÿóÏ?L!þþþ`³Ù8sæ RRRкuk4oÞ¯^½Â…   ¸‰Ù¸¸8…ò<|øëׯ‡Ö®]‹åË—kLüf̘¹sç"''!!!*mbX“ÄÜ‹Ææ Cafa¥÷ânÔü<ï;x´é'w”×  —ËÅöíig«!×®]Cll,3„³³3ºtéRj¾Ož<Áõë×Íš5ƒ——RSSqúôi°Ùløûû3w°222ðøñcbÏžwwkÜÝÝ‘””gggXXX ;;»Â]ªeË–ÁÆÆ†i¶UÓ+Òª5¡—TxûcÓ Ü¾‚¨«a˜¶p   x {áÂ¥ˆŽ¾ ]]><ˆÁÂ…³«u¯_¿Ž­[·bíÚµÔÿqÖéêÕ«±k×.üúë¯066‡ÃA`` ú÷ïÙ³gcìØ±H$‰DˆŠŠbj½¯^½}úôÁÎ;™yN:kÖ¬Á¬Y³«V­Â¢E‹Àb±Àb±pðàA°ÙlüñÇhÙ²%S†’ïµÅ‚ “Éâø)Ž;†#GŽ”ûØA¶<º…¥³GãÅÓx´éˆÿ­ß£z¦ÞÝ;þ>'OžbòäÙ˜={j…Z›S¥iÓ¦¡]»vû.tuïß, áááàñxøâ‹/°wï^4jÔ/^¼ÀÁƒñÛo¿¡qãÆðòòÂêÕ«1jÔ(œ9sŽŽŽˆŠŠ‚T*eNÆÀÆÆNNNxüø1¼¼¼pæÌèèèÀÆÆ, 2™ pttDzz:ŒŒŒöñ÷Ë€ @,£{÷îj¯i?|øpräââ⇮]»âùóçX»v-Þ¼yƒ¨¨(¸¸¸ÀÌì]å«‚‚Ž_I¸pá³SÿþûïðööƨQ£àææ†úõëcÍš58w‹oO¯X±ÞÞÞ˜={6ø|>z322·ß~ ooo¬Y³¦Æ—³IK/lù'wÁƒÛ7öNn°wtŇ}4tèÐÍ›7A|ü+,Y2O¡'u0`Ö®]‹E‹aëÖ­€Û·oÃÖÖVásñâÅÉd Ûi]ðù矃Ãá >>sæÌA||<þüóO4jÔ"‘¾¾¾€~øÖÖÖHOOGdd$ôôô0jÔ(üû￈Å÷yûâ` IDATßÏ<âr¹8tèºté???fNHHÀŸþ ™L´jÕ C† AëÖ­ ‡¶mÛ2e«W¯–.]ŠÙ³gÃÄijgφX,VIÇ5eñòò‚——,--‘›› ### :«V­ÂÙ³g±iÓ&ÀòåËáíí9sæ€ÇãaöìÙX°`ø|>–/_©TŠÈÈHôîý®Âç† 0qâDxxx¨½uA•$tžßNý\.›VÎGK¯¨g¦¼›D++KÃÔ´,,ÌÕ¾áÖ¯__¡²ÂW_}Uªç-///h>VSäååaóæÍðóóSèìøñã066Ɖ'Àb±`ll\¾¾~©Ž{ÒÓÓ™~¾}||ŒáÇÃÙÙß}÷Òù„††âÚµkÌðôéÓahhÈÜ"|ÿ` IJÚ!ggg…mŒËåâ§Ÿ~*u}œ)S¦(tðÀb±Ð¿•t,¢*NnX¿ëþ7ÓI‰/Ñæ åW%000Ÿ¯[[õ¿žª§§WªC‘+W®( á×_­“ûøÅ‹qåÊæ(~L„ÔÔT<{ö gÏž……Eñq¼äß•Ôô~_ÉU{AA1mÚ4„††âСC wìÞ¿ªÝ»w/3ܱcGdffÂÊÊ ¥úïP§÷߈Ð××DzeË>81í °3dz111 榦8xð ö\¡—1ay¹0®g +[픑‘ß~û©‘Ù·o_ÌŸ?&L`n5kÖ¬ÔtsæÌaúô-«Ñ.—˼’5`Às†/ aff†‘#G–ºM:jÔ(¬[·¾¾¾5rk‹¼Ó¨™'–nÜ‹U‹&¡ï×þ-ð÷ßãÕ«WÌþºaÃØÚÚÂÏÏæææ˜>}z©i>ûì3DDDÀÏÏIÔʘššÂÆÆ:uBÓ¦M1tèPøùù1½¿ùûûã×_Eff&îÞ½‹€€æ.U 777LŸ>EEEèÕ«—Æ6n£iªÜ°LDÄ tîú%óÜA*C&•÷¶?d6ä‰ò¦‰D`±Øàñ¸ïè©aM!“É››Ë óù|èéé!''r¹†††Šßñ¿»G¹\ÎÔ8766VÚI=JÕ\`±Xàp8àñxÉdÈÏÏ»ê”Ù=o~~>ôõõµêùzMQuÃ2))©((”½Qæ³Â|ô Š· ¹¬bqá묊듖©~……… MLL ‰PXX.— CCCäçç—zY2]Yûå–-[`mmÍœ(”' QTTæV}YÇŠÜÜ\Èd2hd+z5E­ ËtèÐQé׆ÄE…eNCg[šÍf£^½z¥>711)uµ­pvÈb)î}C‡-õYÉ B ‡óÑù ú5ÈÚÚêí~žýÞö 8¬|éSð4€žž^©æ†ù|>ø|~¹û—²éÞçééYjær¹Ìþ\rÌøpe4±‰^MG½­‘j5a !µTûöí)”Ћo×J$BZ#„¨T*ÒØ²I$¢Rò!ÊÉdRÍOèR©¨Ô3>BHíWPAA ¤6]¡—> ‘UÛ« „ÔV,Ki…#M&•JiÅòм‡¯± ýÂ…pZ©T£+ʹ¹”ª iii6`±¸xó&lvõ¿²daaGG'ˆDÊŸù"6ö)¸\zЍ¥¥5ê×wDbâKH¥@zzj©ƒD‹-h×o½z&hÔ¨a©„jaa}}}23o!/ï¶Ñpggg"ÅbãêÕëðõÕ/}”JE-d¢Óz[øùçS;vs}ãF:\\œáççÓ¢‡_W×Ƹ©ÞÛÛ: “u¾Ó̽gzxH-º@èÈzh.œÇã!$$à¡çõ¯r®Óépòä¯xþù÷Ñ´••Õ&Ë&9B$rìtÙ²D扼¼~]†UU á×ðì³O·:0ît…¾sç…~þüEtïÒB¡Ëå \½zÍèQ«ýúõGuu5rsslîÃtïÞ‰uLžEEEÈÏ¿Mj;Á$AAÁprrÂÕ«WZ„9:Šègùü«œët:ìÞýM …NQ:dee£ªªÊH'Þøý÷$›]’Þ bqûœišFRR"©ÜÕ…áÎ|•sKÜÐÚ:ôyó¢±nÝ ³÷888ÀÎNÄ4Nb±ööv(++Efæ-H¥ž6÷aq÷n~»—Ù)JäææÁÓ“8Lãï2 ð  %³©D"‡‡‡Må799‰‰¿ãÝwM£Ëçóáì¬WŠl6áὟgÏþ ww X,ÛÜ…10°+²³3Ú•FJÊu›l۫н½¥¨¨(Á¨Q£pãÆuÐ4 V«9çóy¶«ÐThm;½"w„Hd”•• ±Q­–‚Vk»ëÒ)JÛîüiµZ›.#ÁvÐé(TUéO,ëÒ¥ **ÊQWWg£²AµØÖÒ]ºøƒ¢´àñ¸ÈËË _ÊCÓ´Í*ô{²ÛÈR½ÇšÖH–—— //OP”l6wîä[œÆCY‡~âÄ/<86|nö¾Þ½#`g'ŸÏCYY ùâB+”••ÀÛÛ§ÝfߎâÀÁb±‘‘iòO€ÍfA­VA©$;D/êêê R5 k× 6ųʽ¤Äô9æõõ ×Û¶m@BÂIÌ;¹¹y¸pá†jÒ QWW6»€|eÁ’’’ Ñhàß¡ÏQ(¨©1~–¹Rih!ˆŠz +W®Çºu+ÀãñðÑGk¿Ç„Üëe¿¨¨b±#ù „Ç–¸¸8øû?Ñy ¢ÔMZ7Ÿ»¹I 6+c??Ì›÷: ((AA&Ó¾v-l6\.E1.ýÁ8……Eàr¹~ ¡NG¡¦¦¥¥¦;óO<ákÐ9_¾|1s½jÕ‡f¬ e ù¨©©…Z­†H$2yœ*ðw¡××70¾$¦ÐµZ5""Â;¬`÷:Z-…‚‚BˆD¢__ÛþÆN×î­jÉV·Ëë Š T*ýÜ4ÇEG»ÇÐ4©ÔRiÇ9m:;;A«Õ¢¾¾……EèÖ-øvœ|òß¾wK“JýBÓúoŸ•u ‰+4mç+ôŽÄÍÍ NN- t÷náî.±¹< …B•Yű% ‰+©é“ØÙÙA&«†TêÝ"ÌÑQüH–I$µ(··jkåHÜàííc³Nq|>íó÷ñôô2ú= _X,T*5êêT 3*ç´BïÛ7Npppxä>NHÈ\RC Fhhˆ™&ï‘*‹H$ÂÔ©/!$$ä‘ý11ï’JIx Âû› c³[÷a·Y…Þ½{ùº‚ t,ÓfY °Àz$Ë% ðÔS}È&<Ðh3²Ì¦Û&Ç&ºþ”$}bŽbðyX²nœ@ t<%9Jè–iZµâj!B]8mFÅü/õö€Ž&û!A#[‹Ûü2ÔÑ-÷P”+Ðß®x–Ÿ`R¡ßè‚··~×"â¬A ØZZ‹ uËÉ”•J8gØ!tðƒ+t•ª–ù¿OŸP³§)„ö!£dÈÓäµø=ûZ6BÂ}ààÚ…®V7BÓ¨!o™@°at<ÓžÔšF ” ;ű`t ˜NG£¾®ž¼X¡ÑðiÀŒ›X}]=”<ã²Ìãó ðÍ+ôâ¢rW7M Ø0®‘îÇxXEE5®_7~´/›ÍFäÀÞF;¦â„Žï,̸ŒdeÝA¹°Öh˜··;}Í+ô®Aþ îJÞ4`ÃÜæ•*ãa>¾R ú´É¸ÆLè¡Àl`}Ô, .!Õdx¿~½á#1~d/MSM¾nfºþâC Ø4\Óþ,4M=À¼7MæÊ „N†bkMZÚ€Ò5¶I.M:űÙ<ðxBòÆ-miëÈ‹ tNC ¥Px½°e¿N g´+mý¼‹¼d Ñh4dgGÂ#/“£° ¥,++Û~(‘I…ÎåòagGv)³¸¥4D¡: ­cjäx8µoE¡PhÑ&„¦†WI…Nx x4½8A::· Œ$ÎÖQèÁvq` ñd`8yÂ# ›fÁÏI ?'©UÒ³X¡=zèÛ·/FŽÙ!…KLLD—.]àçç÷H| ¹\Ž .`ܸq¤fZ’’R”—ËÌÞÓ¥‹_›,èPdsÁá˜ß^•¢4-œW%~ÿ=žžèÒ!é«Õj$$œÂ‹/NxdÞÉ?øq£È±Î&¸yóOPe2œÃa#,,Ô¦òÌå Àb™·Lé7]²ÝýX,²«8qùùùèׯRRRpñâÅÉÌ™3g——÷ÈTÚšš:tˆH¯•(((BÎö¡-þŠNøé§Ÿ!ÙÖ1šl6 :Öè_YY)nßn{ž2e6&Mšôô?jù²²rðÚks‘“s»Ãž¡R©ñÝwñT]ýî»xæt;BK2o•ãFûPĽˆº:Ûëàr¹“r¬ÓiqåÊUhµmÛ£åܹDLš4QQÿêœ2´vC~~><ˆ]»vÅbaøðáxñűXÌ(¶ÔÔT<ùä“FOGû+EEEÈÎn^óÚ«W/H$úy?š¦qöìÙ¦ÌÅàÁƒ™^|RRÇÛÛݺukRÈÉÉaÂ"""àââÒJ#¢Â¥K—˜k___C.—C&“A.—£ºº Ê•œœ ¥RÉä`]Ä®>pt54?åçdbQÔÿaþüy°³³E5ÚTžu:-(ʸ ××+!—ËÛœæþýqذásÔÔÔZGir´¸Ë—A¥k^ëæ;9WÜ7Ȭ«ªÃsŽý!dó‘––¸¸oñƯ™L799"‘aa=,nàîí8éêê‚Þ½›O–ÊÎÎAQ‘þ¤²îÝC •êw¨LOÿÓÀr3tè3ÌÿÙ³˜ßÝÜ$o}Ô—––™¬’¹~öY}síZüü|pãF:ÀÃà ={öh²•!3SßfùøH‰ ¶‡+€‹§¡s&MÓønÇûé æÎzÙæòLÓ0)ÇPQQ.¨Mi6C‡>ƒI“^µ …~{Ç;¶ðúõëxî¹ç˜˜ˆgžyÆl:2™ _}õx<Þ}B~}ô ..Ž9i‰¦i`úô騱c G«ÕbòäÉpssÃîÝ»[¤·bÅ ³ùøâ‹/P__oÞ+¯¼…BèèhŒ=Ž~=Abb"–-[†ãÇãÊ•+LcR^^N$×Ê46ªð寥4|Âú @vÆ5¬ˆ™‡ƒéoF™1ݹsÀçóñþû {÷ÆãÕW_iêxÖââÅß1nÜhTTÈšzµµrdgë;ƒÓ§¿Ì˜•¿þú{ПeÕr¦¥e€¦iüö["är}½Ž‰y"‘‘3c²–••ƒ~8Ì\?½{‡#5õ>BCõ§5ÅÇÿ„I“ÆÈE‰¶w4wÌæ+ýb:"Ç…AèÀGff6>ýt¶lÙnòþ9sÞCPPW<¸§Õ2óÍ>1×¥ƒ\®@¯^=‘‘‘‰}ûËå0Š?:úmܺ•‹ãÇO3²·nåbΜYˆ‹û%%¥é)•JDF>e2—.]ÆéÓçÀá4'óòîàõ×gà½÷cذAàóùMéQ¨¯o@ppW|ùeø|^S[A!##“k+\KNÄï¿Àœè`s88¼ï+l[»ï~°O†š–²\]]ƒíÛw1×ôÈÃPXXŒÜÜÛ:tÓ‘ëÖ-ÞÞRœ:õ+BB‚°w¯ÞÊãì섨¨·š”° ;w6×Í08k±wo<ž~º?öï?ÄtF'OþG ÝùWø‘±|±Xl,YÓ¢ÍR*ëpæÌ9¼ð‚eÓºVqŠëÓ§’’’ŒžãúW*++QQQØØXæ·çŸž™o‰ŒŒÄ¼yóµµµ˜={6¦OŸŽ#GŽàÌ™3Lœ;v ##ݺuCUU>ýôS&Ì’9íS§N˜Ëe2¡P(„÷Þ{•>Ë–-ÃéÓ§1sæLôî­ßiëĉˆ'’kE6~ô.ΜLÀ‰ÃßcÅ–o±rá,”ÝŦÝGMÆùþûƒàñx5깦NkÖlÂ’% qðàaF8jkå8uêWŒ72Y.üÿþw oÆÏ»ß|³Ìï Ø°ás¦“` 222±eËX½z)ÄbGÀÒ¥«±iÓj³ñ<<ܘ|é…Ÿàå剴´t8880 ýðáŒ?Æ@¡·•—_žØê=_ý%„BËæ‘÷í;„#G¾gæÉ“gpéÒeôêÕ^^ž˜;w6¼¼<¯¿¹\””ëèÞ=¯¼2‰Igøð`ΜYØ»7ÇŽ`~OH8‰ää³ =5õÂÂz`̘÷Y!õ6›ƒiÓ^bNzŒÿ ))×áéé‚‚BÄÅéÛ¬ÒÒrË¡%ù·°û¿«PŸƒÊŠ2ôèÕÛÖ,FŸC0fÒ “ñV¬ø”‘W¸|ù*œ ÓÑHLüƒQ艉— ;ÂÛ[гg/`ûöÝøðÃ…L§à³Ï¶#:úm¬Zµ¯½6…I/)é–¡ö²oßHI¹Ž©S'7Y”2qìØ L˜0¦½ÙþÌàõƒV`íÚåmV]]=Nw®B‹ÅˆŒŒ´ÊË m»£DBB‚ÁÜû½©sìÙ³S¦4èððp,X° É¤æcÑÔÁƒä•`ž˜å[P\R†?o\Á[“õÂûÑÆ8<=t4ãæ0‘H„ÚZ9ªªôS$K–,lõYãÇÁ«¯6›þÖ¬Ù (,,ÁȑϢÿ'™°!Cž±zY,˜‹áÛ—ž}òÉÆVãh4¦œ™™ µúáMAôêÕÓ*鸺º0ÊÜr))SfÿÅb0Ólœ·ß~«WoÄÿ»—ùíƒbš:Ë¢c›½¼<àêêB„Õ ~þÁx÷ƒõX»dŽìß…#ûwËåaGüoMw_âkoogP¿‡†î݃qùrŠÙç­]»=zè¿Ý;HH8 ¸{·À@Žïÿßjfn.›6}Â\—––¡¼¼õíÓ SVNÇX Û•—Ö͸zõ*úöí‹ . ÿþ ›7ÉÉÉAll,,X€€€ömj±}ûv 2¤Mq^xálÞ¼ÙdøÍ›7±{÷n,Z´R©~þëСC8vìsÏ矎˗/ÃËË«My%X¡ÈŸlÛ‡•ÿškɉÅ™4i<Ž=޼¼;Œp”––aÆŒ)«w£V«±s縹Iîk”5O7nƒ››³fMoW:iiéHL¼„Aƒ,°X,;¶ßì=«Wo@ppWL™ò"àüù$Lœ8K—þË`ÄæÌQ‹Ÿ›˜x iiéDX[aؘI`±Xø÷ü—Ìz¼ßÏ¢Eÿľ}?0×÷üþn$&^Brr*3Åf­} ZUèb±QQQX»v-/^ŒÁƒ#::š1›ú¹ä½{÷bÚ´i­*t„……aĈ÷õªç€ÇãÁÞÞcÇŽe„B!cš_·nAœÈÈHL:a7nDDDs]XXˆ½{÷bîܹŒBˆˆ0ˆ3xð`Ìš5 999°·7ô¤vvÖ/îÿý÷±xñbëçVß|óMÇ:‚uðõÂ'±3{<ܽ|0d”yÓïÁƒ‡!•zaà@½©µ¡¡kÖlÆŒSàèèÀ8@}øá*H$­¬ìíE¨¯¯câ)•u8xð°UMîúNäôë×..úúåèèÈ„UVV¡¾¾µµrÈårˆÅbh4Zäçßży¯þøã ŠŠŠYill„LV‰_~9‡ää”vçoùò5¸xñ”—ËðãǰnÝÌœ9ÝÀ„yüøit±H¡ñÅ&L˜0•iÜ»u ÆÇÿ, áá=ñË/çðñÇú©³©S'C*õÄË/OÄš5› æAccõ–Œ;·bĈ˜ß| +W~hðÌ#G~ÆàÁ‘ŒB íŽÕ«×ãæÍæÕ;wnm’sC«œ@ €H$„Tê‰0Ï4èi„‡÷497Jhfèè‰X±å[¬^ô­Žmõþõë·":úmæzÿþC())…³³X,@&«ÄŸfᇎbìØQȲ½äÏ?ŸFïÞaV5¹kµZ,]ºÿüçü¦Žw#£¨Õj5 %4 d²J8::B à#;;AAÌôÐúõ[ïÓ¹Ž÷µY+Áfs,ïäVUå]TÇçÛÃÞÞÔH ¡( äòbò"ÚÁåËWáúÄSp–è­$ŠÚjœ8ò=^þ?½CšŸ‚=»Ê¨—ûÆÛ/d@À4úr¹11Kóç¿o¾Ù‡­[ס¨¨çÏ'aÚ´ÉL›7ÿÑÑQ`±XX»v3rsõÓ8öزåSæ6!JKK!—× ¯¬¬‚@ haš>pàGèt:¤¦Þ`Ìn[·®ƒ½½]S^c Ñh%tÏ)/5õbc¿ wâñx˜0a $Wìܹ—/_ňÃpôèqìÚµ vv"z/÷?Øi­;ÅJǺqKáâàD*¤…(•Jh4äü‹û9špG5{vÿzüƒCá¤_5ài¯ÕXÙ"^yy–,YÉ\ù,ÓûßÿNâðáÿ!4´êêê1vì(ôí}ûaÈÌꙬ §0sæ4•`ùò5LzcÇŽ2¹ß瀬¬›f¬HxþùƒY˜8q:V¯^Š-[¾ôíùóß wÂܽû[æÞyó^G¿~}šäýKÆÒ³pá»8~ü4bb¢ R©ðÎ;ïÞyç-l߇;·…Nú£EE… ÎΦwkü=kAÓ”ÅiÆÆîBTÔ›ôsk›7ÿ[·®³ZžÙl ‹¡P˜^šæîîÖbÎõžBŸ6í%«äãÒ¥Ë èÓGï°9}ú›D¡…þÐ(,,†¿@+#[Ë×ñççßEFF&3*_µj=£Ð­YYæW/wm±-òĉÓqøð÷VËÅýmVYY–-ûÄb…N¶~%Ø îînmôÖ1b(&NÔ›ƒ%W¬_¿ÒªyÖé(x{{ðlS<{{;f=¶5 ÅgŸÅbÅ }gå­·fší‰¯¯·UåX*õÄ©S¿2²<~ü˜ØiŽB·nÁmŽåáánÕ\Œ;’)§HläÎIDATXìˆÍ›×X×äË€Ïw 5ÓBhšBCC y›DÅÑâ´ì"ÒKÌ;§cãKËálOFè–¢V«-vú":®9sˆ5{XááÁÓqГ„;·¹“žššŽþýúBK5ï‡Þ‹‚Á¦KáWèáï‡f!ÐÕ®ÍUf×b`÷§Ñ¨QD ü ‡@:@ ¢Ð ÂCÃÙEܦ%€Á¶1éåN ŒÐ @ t"ÿ›(¥Ç UµôIEND®B`‚snd-16.1/pix/fmeq18.png0000644000076400007640000000133111147553267012753 0ustar bilbil‰PNG  IHDRñ½ÅÈ3PLTEÿÿÿààà°°°ÀÀÀÐÐР  €€€```ppp@@@PPPððð000 * ô¼ pHYs  šœtIME×7'„‡X9IDATXÃÝ— ƒ †)Pæ'úÿíAÁY¡ÝL.»äÖd²ˆ}^ -‚1²EoîØ½§þƒÅðæ˜†ÜØÏ„\é¥Nó¥sˆïÜÃzïÁ|Ó*ýWÖ+_¨Öò.'O±ãc2–´~— Wð]«tIø¶õÊ •Û òȳÿ{Íç-~"­w¯ ÿž Öy€€yf1:LÁÆ­­S…aG#?©s(€;,X ¥ñ‡Ç….D¬¸p®¢\©>ÝGgìœ+{FŠÖ•|O.vYSGÈ/5jã/[,NéÓŠ‚áðàtAXqa\M¹RóH¤:q¹ÌÝ’.sºG Ù#.Ê¡Œ«ë„§áñ¸ÁÆ%•Ĩ1ƒ«œÞ «.Œ«)Wª{ #Ô§Ë3â=å+²Ê|Æ“Kgq¿Ì àKˆ¸“ÂP=8½V]WU®Ô4ñ‹"†G·ºC]:§WKàfÖ¤kñàôNXs¹p_)O†2`½vSmº†E®cz’¤ŽäógV—õC7X¤‹ø(††WÊâ%aÍ…s5åJ¥¢é¦ÒÅ?Ì(Ïqê§’uÚ&B·ØÍÓ î¹gƒêÁéý¢¸pî åL ££wëL¾@XÖÄ£B÷ÞΠ|$¡þÑ"–À &6R“2£x\èÂgQqa\]™¨Q:4L¥4bsT¸|ëÎcS·æÚiä‚8æQß(.'÷¥²ºèÈ·û[ˆq°ÏKŒ7ÏDq0ßbáÞvyŒ_ñÍDú‡ÿµßxïDIEND®B`‚snd-16.1/pix/peak-path.png0000644000076400007640000000510411267121476013522 0ustar bilbil‰PNG  IHDRàæ‚˜ÁksRGB®Îé pHYs  šœtIMEÙ  Çîç ÖIDATxÚíÝÝ’¢:€ÑØåû¿²}aEñ$°k]Íœ3Ú6à×Û€íëóù$âù³ èß{ü—×ë5þkùòôpC+Úõýz½&yÿ—µ:ÿ¬ð&ütt‰cRäÏç3Ã8è}ã3§NÐgÖùõzºŠmvˆhuˆhuˆè’:Ï׋'—mH<@-¹7ª¤²7žŒ­Îµ\?ð~ã®ì~ÀŪ@„«s~ñ@ "ÖY ‚ÖY ‚Ö9M.³ išÓ–‹Ö Öà<°Ä±Î ´Î ´ÎÉ4@»4§c¿Çâ}Õƒ08‡ ôüÃíK@CàÆiNõ~=§@Äœ®âˆXg4@…4§6Ÿ:"бç%€ˆu6AìLsjÿaª kpXâˆXgZgZçd  $Í©ý)Aˆ>8,qD¬³@­³@­³@­s:í$¡MÔ9h 3ß­vqÒœ®¸œîâ@œ·² ±Î ´Î ¨sÐ:'kÐÀ“Óœ"h€èƒóÀ Î&h€iN±—508wÀ Î&h€‹ÒœúYÖhÀà,Ðg¸Çà½Î²5p€Ñd‚NKo‰ž7ÚÒǦ™Ú@Á™Të2»ñâÆâ¡9,´{-ÓJ: tµšL†h·z©=Á82EÙO ´¡ø´R¨18 ô¡#@ Ô¨3uöàñý·Xäò»Õšã[ÞÖÃÓʽ:ÖùÝöj ÎD ´4)µL£Î½úB[¯eu&P  %2Íùi¶Ç:…ñ±¢Ñq2íykpæ¹öF•à™6^©3ú;ž€y‹]°Ôß=e_Ü,Íêl‚þqˆ,&XÂÔ¦iƒ3O 42:7Ð?Ó´LS1ÍvÙƒv÷å{Úç9Á™V4¦iÔF¦½ÄA ÛmÈ4g~ì}kÐØ5¶?&hz¦5ÂàÌ%þl~fÚ[Õ4ÑGi¯¸OH³Œ@³?Óòapæ–8Øœi+êŒ šè£´ãµÒlK"Ð4É´²œiÄG3mÅC1Ac”¾Uš“e š3GiÑ18#Є¥eZ©Â4õ3íSƒÕ4¡3m”ž¤ÙÖ@  Ôh3£Á™#,qpÆ(ýäuÆQ:bš“e š^FéçËàL7vNŸô¤ëðÔ™:’¼BÂÏKt0J_žfuF !\£ äB–8è¦Ñ'WÒŠ3 ENç®[Ó Kô7J«3 k´ó4Dl´ó4ÔitÝLœ è‚“„>þŠ*®UUWk–¼¢ó#øX£ ÎDf‰ƒîGéÝËêLp®ƒæÞZ[¯Û0AÃÙ£tùà¬Î4œÝè|¦-k ÐpY£3£´:#Ðb”ž¤Y鎓„ܼÑß?H3 ±,kÐ3K<"Ó Ð4€@ Ð4@x —Ùíø¥3ΛÔôŽ_Û(Ç-üíž8i‚>RçñÜ-ñ•}¤ÎãÛ.†þçʉ*n^Îwõ{ÜúϤàÇêçÆîùýä›_þzü6  èd¸ ¨mžž €FÞ‹©þüstŸt…«8*º$¬‹ÿæÚ"_þóÀ·ï8=€F¬A%Ð À~ù€ €-Îx'aùE{ÇoÁŽwΣ÷>óQ–?â}·Rç*©üký(Çm¿«¥â­ú£g àÊ:g¼mPZ¿¾+_×Zû÷=žø>f«sOSw› i¦ñ‚ÚÁ#[æx&¦áñä°ŽD@s×xðdïÖÏÕŸÌÍ—êJnEÆ;w¼Ž<Ùé[¯Ò™3‹[¼ø'ËÙ‹dr¼ý¼óµû)yU¾Pæ[ö#3øó"½æô÷ •(ûnE¨Cpr®íÇùšuÉÁ=ÿÃpù0-óû‡ù=Þùü†™Adr?G¾PæëNžíÈ“üaÍ?ädSôθŠ#ÿÄ[û¿º|›ãu>æ'Ö’{Ûµ—nã»Z¼çùϘùÐPòª\ÑQò€'Oï!8ßî_¬ŸZ|ª7dµIJŽÿèÍÅk1*ù ‰ÝjÇ «|&˜'p’‹§‰Š¯+{o–5=š»¹Ç[B¼±h<Ïί¯XûÇ;Îø•|ÝZ&o÷»vú±Ýw1¾ÌÃTÞñ³ÉΣÅKõI›Rö*ày’~^‰œ¹:x~Ésæaäÿšyäù‡T~?k«kßÅÏ<¹¡'¸@±~@z^[â@ žç=d¸‹*b"IEND®B`‚snd-16.1/pix/vf.png0000644000076400007640000015637711147553271012305 0ustar bilbil‰PNG  IHDR‘ö³sRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ-ìœÇg IDATxÚìwxNgÀïÊ^2%ö&öÖAíY¥ŠÔ,ŠÚ{V µ[£FkV­Ú­ÚjÕ^!D$!Kæ;Î÷Ç'y%’ØZÏïºrqÆ3ÞûœçÜÏ}?ãVØ8ØI%*{"Á‡ÄãøBüƒP—¨äɈ}?¢},¤"‚†k¾WÙþå\Ô÷S£8•pKHE /Œ5úék½pº¿”7'Žž†ê/”Nv)ý‰#™n†*/œöwåUî)bˆM0*BI/!iu’u’uÆ»sB J+ JJ¼ @ð¢DM9ËüØ;8# ¹JξØ+¨¬¡¼UAììó ¤\¥x‚2!3K­ cck$åœVBâAØ=”Ú$ è ¡A 5žÐ^}ŒöR"ÚÔœŒV‚åÇŽX—tâm¼sÚØWàŸ„›$RhïPƒpm Ç®“bнWu­`YŠ–…8—x›€ä0šØVÀFeÁ©„[„i£Ñ(T”±ÈGió|˜+Õ\L¼ƒ_rˆxÈ‚÷ƒ"M¤$“ššš+»,9)Io@ÒÓ¦¦¤°~ýz’’³Mùy§N$'%`Ð0¤Ùl))ɬ]»†’%KR­jµLi®^»ÊÅ‹éÚ¥ )ɉ0`ÐdÅ«6þ «%EÍŠ¡47G¡0*7…Baü¿”( í|HL0Áb0¤êA)¡àíÐΡµmJ!!Éž‹Ë‰wXÿèåT$ÞŠäoÿ`4U]éX°§.qàʤ*Îò»û>à©ñ £]-‚OúsIIÉêy±¾›Â‰«÷I- …Ý ñU/Üv‡ÞÇïØ?ÔªèÁÿŠUÂQeƒN2p11ˆ¿ãýˆÑ§<Ù–ÇEmÇÆÇ'‘D³¼$…I2Z\’”‹PB’$ útÝ#IvìÜÁãÇÙÏWi×¶  éõHºô¼¶ïØ™™cF¢\¹ròý·ƒ‚˜=g=â‹ÎŸËÒé1(õ¦ŠPÒ0¤¹FóØÚЩÅǸ;»¡T*Ÿû§Ž\>Å’‡{i…"¼%ÜTv”ÔäåŒïn‡ƒüoßà±:Íõ޵ÿ*wR#psQ‚'’´Äù‡¡Î«ÆÝÃw3GÌ”jžè“NŽ$UÒa¦PSÐÂ;•%¯K"$õɆT,•f”µ*@¬>‘ÛI1¹¡Û©¬ð0˃•ʤ',5š(mjkò™9b®Ô !§K"4õÉ-’ÞØSÆÊî|§‰ÿ+€ ä‡Ì¨Z¨…Ì\8ïw™e[×r?%ŠQÕ¿F}#ŽÀ˜;/P„Þ%¼pz¬fMì1RmhjêZ–b׎]ÊïOÎQ­pº9}Œ!Y‡•…%±Ê¶ç/­¯ÉXŠ$A/׆äíמïö¯ À!†vyjP¶xi¾ë?šŸla]È®îú‡T ‰REK°¥ä|\âÍI½޾¦+Emܰ7XpêÊ9R *Ð%¦¢²0/àÍ*B¥ÞØÈ$ C.Ç%‰4‹Ð`tìHNNÎ|;eòsÓ̘1Ó¨s$0è%Ù­*Iîîy6tó,`Öì9xy5àĉäÉ“‡Áß ¢hÑ"H’‰4K”g\£’Á`ÔÊ€¤W‚BR™eè HZá¼ÍVgÀÌLC¿O½ù\÷)¨•\Œ díƒ#(5jôq)hÃâHÍc-'Ñ(ÕÔu,K]»²Ìýe·Ãƒйm«ñÏå³Tô(H¬Y¿{ /ÇÆÆ†äG$Uµ#µ¸#÷b ¹y—Ø‹÷°´-„ÆÖRÎÛ˱õì<9rêkwm+5©É)ÄÔáou›‰{Îô 1¤c>u¬É– 53˜~Ik@O²!Ž•¡Z¨ g|/0oã2'Æ’\ÞuÝ|X[YP½ÈGèô:®ß¾Á£;áX•²ÆÓ9"#‹ÂÆ­(Š47@ðF;§J}š”r=Y¤´1B}º•˜Cz)Í *[“jcÓ‘ $ƒÅ‹3~ìXÊï¿o`Áüy-R$=_ÉØ&$I/Ÿ“g>u ê4E÷Ô ª0ºBÓþ”J¥ñºR‰…ÑÄÔêQï‹à-Z„’Aâ^h·Cï‚‚nòÄŠT-M¡è ÆÙÏi˜)Õ³õ@­T1°Koy#îÉœ(8îw–Â%óвÁ'4hPŸË·Øà»—'†î=‰àó?¦æjÌRt¨,Òó.c•ŸÄ„Dœ=†¿e$fÅŒc—eì ÑîóN¸jìQH`inB©äÉùRj%‚GºÅút¼SÒÐ%iy @|â‚-b1¯â‚ÆÒœü… ÐÊ­­œª³eß.Ö܆¶„Ö s<­òsäàA”®V¨m-Œ&­N¼4‚·`]”¹#L× Úô´ÿ}Ž&”¯­I)ƒ‚4žOHL ãÒ„„'™ò4è  ™\£† ®QL¬>ÒþU*Ò]¦Ê4%¨P ktI¸FoÙ5ºçôaþ<ÂÖ,Í5j)7*¹‡™†^2—š’ÄÆ¿¶qëA0 …'»<Ü »Þ.–{¡8ǙӤBZV©Mlt «Æ^aÉgµZ\,ŒS¯ƒFÞ^€˜”'˜[™Q P,c[Ð3µ†Dm2Þù½P%I¬Ý±­¤Ç»Åg8ÚçÁ¬EŸ¬}¦®’‰…ø´‘(ÕJ,œípwt¥O¦T¶.®}²ì_IÈg†e>{òٹਰæòµ«¨‹Ø¢Ô¨Lê)¼±6©2€"Í:Ë•"4êI/!)ÓÝ›9O¶I³Š4Ý#õdLwÍÏŸ…‹–`ooOËæÍ8pèsçÍgà×ý©R¥²qOaôdô™\£.MC«Ò2M+Ð’"m†Á8¨H«°!­±´z¡à-*B…Z¦€–%]Q¨Œ K©VÉSY2ºXRô©œ»Fm·²Ô¯Q‡BŠ`en‰Øu‘nåSÖ½8Ñ1ÑË“½NO\P‰£°ËW˜žE›r2ù<§®_„"j¹½ì ;Gû2tiØŽj±ÕPÛXp6Ô­N—šH>KGª”«ˆÚ\ƒÆÌ,Ý*™*>=˜a¸B¾¬×Ó·PSê9W 6.–Bù 0îëá„(bøóñ X8I”>•½=¨”&õÞ˜E(éyª g~?‡È¨ÈlïŸ0v ff*£¦Ó‡ÙÒÚ@vk Ÿ¶ÅSkR'Éo3ÁÄÇÇ3ÓgE ¦FõjŒ3Ž…‹—0tð`*”/gôdê $ݳ®Ñ´q> *!†¿.üƒµl Ê®R(Jy)Å­°;¤ E©Ó‹¹2‚·ÆíØPŽ…j ŒkJ•Ò¨ ‘7Hò{Hl|©:{Ž]äZÀ5RµZND\ãñ‘h¼lËádfGHDgý.ÅŘ@Ô±z\Ìí ˆ¸Á¯þ—ùãÂa %lHHJätЮ^ö%!(3' j+\ÿÇw´.lË“ÏÚ…„„'\9yœDÇ(|,~¥™y,’œ¼vžR%JP8H÷"øûÊ)B†®FßáöÝÇFƒ ‹P¥~F*Ädà]EÀõ`”bxB x‹ŠP•Õ¬QÑ‚·…B¡D©4†r²´´ÅÎNƒJi†Baì ÚŠô-^Þ"T§[„/¦-,,P©D4^ '´Z-©©Úg¡ ¥Â6;ìl@§•%wƒï‘ÇÑ;;Ó(0ff4¨@z½äääS„™,œ,cf¦A%Ü©AŽ @›ù¼^V›šéüÃá˜[¸gR„*•³´÷àYE¨1E¨V¡Ì¸|B¥T¢®Q@ | hTjT¦“eb²L3fÌ{é{¯^õã?ö¾“z/[¶š#&¼•²fÏþ‘©Sgey- à&ÞÞ}ñöî—éÚï¿ïÄÛ»/³fý ^4Á{úu›ðöîËÂ…ËLί^ýƒÊtÿ/¿¬ÃÛ»/Ë–­Âû“q²LúÎ2¸EÃÀ#Ù³g®ÓìßÄä8,ì~~o¬ŽÛ·ïfãÆ­Y^ûì³6Œ1(Ëk;v­õèÑ£ ýúõÌòÚèÑSðñ™ÌôééÔ©‡|þĉSÜÄÇg2ÅŠañâ¢% Þ9{÷$** ŸÉ88سfÍùZ›6Í7nX¦4íÛ·bàÀ¯øçŸ3B€ÿjEøìd™|‹µˆˆH–.]É×_÷bÀ€‘¯œŸN§çàÁ#4mÚˆ;þ 2òµjU£|ù²œ:uŽk×üåû?ý´5ŽŽy8yò EŠâÏ?÷`eeI—.ؼy;û÷F«Õÿ„%ŠQ¿~nÞ äèÑ“ØÙÙÒ©S{ëìøñSøúú±bźví„¥¥E¶õŠzÄöíÈÇ*”¥fÍj\¹r•³g/âææBëÖÍ3¥‹‹'~$ jÖ¬*ŸONNA¡P?¿qq%±²²2I·cÇŸXZZФICÑBo¤¤$Ôj5ùó{àéYšøxc¤ó  »:tÔ¤ >%OòæuË2¿ ~çÉ“ìííèØ±` ý³eËù>OÏÒÔ®]S<€w©ÕY­#T~¸®Q¥RE›6-ðô,ýRé7oÞέ[·åc…nܸÅ_ô&<ü!66ÖlÞ¼»wƒ¹pá2‡ÅÆÆZþóñ™—Öˆ¶0pàù|jª–E‹–ËJÑÜÜss3ll¬±°07y 66ÖÌ›·ø™­ÁÆÆ•J)ç©x€+T*•Iý8ÂåËWÐhŒåÏ»(Û< 6l`–×<=KÓ¬Y#“s>>sY¸pùõÞÝ æï£Ç2ýß_©w@Õª•¨_ÿãlÛTvüôÓJ’’’åvÇÏ?¯•ßïŒmêØ±“œ9sAý]*B¥ eÚ÷PX„€³³#ÎÎŽ/þÊ•käÏŸÏD‘”(QœGÓ»·7†ï¿_@bb!!a$$$R¹rùþŒ `èÐ|üñG„‡?døðñ ø-[6%66Žää:wî`R~Ñ¢…)Z´0Ë—¯19_¼xŠ/Âòåk2¥ÉKKK“ú]¼èKXØ*U*§g)<=Ke*kݺ¬ZµžË—}ñòjÅüù>T¬X€ÁƒÇpôèIâââ9zô$û÷oÏTæž=¿PËq -îî89WááÃH?J l¹â :“ŽŽàÍЧÏ7œ>}Ž””T:ÊŽ¿É× ÌOÁ‚2½çÙqúô9ºwÿww£µ|ŸmÛvÓ»·7÷ï‡Ò³gWùÞš5«áá‘W<„÷Ä"”×jÄd™×Ž­­­¼îkôè!ܺıc'‰ŽŽ‘ïËè"qrÊóÎëýóÏkñó»žAÑ_¥Aƒ³MÓ­Ûçtëö9 ´âðáÝ&×~øa&þÍ™3ç?~Äs;#\CÔ¨PkŒ–¾F£ÅÊÊ ƒA+Î[bÅŠÙ¾}7!!a Ô÷µä¹r坨ØXËÇuëÖ`þü|ûíL“÷½G®-ZX<ˆw„&óÎ2bÖèËrõªææælܸ•->ÉUšÚ2dHÿW*÷ر“ ’Ë|ñ⟹xñŠP„ï²#ªReµ×臻c…¿ÿ ¼¼ZáåÕŠØØXùÿz}ö[\ýþû~þy#F dâÄ‘ìÝ{PîYÚÚZãìì”)MÓ¦Ðétr^^­ º €»{^ÌÍÓ]bqÿ)Ÿ~Ú†°°xyµâðácÔªUMVfë~ðàß™,²§ey{nríÑ£hüüL~ë¬YßÊ÷Ϙ1Ÿ^½¼±µ5*É ~7)ëÂ…Ë&ù)R0KYÙØXãââü\YÞ¹s—{÷BDë¼u¯£cfoÄ‘#ÇMÞó?þØ'_›3çGºuû ?¿ëxyµâÁƒ‡,Z4‹áÃÇËm§[·t+³mÛ–&m>>>žV­šŠðN¡Fä¨\¿–4bë,î? e_ßeìÚµ ­6)ÇLììlÅÎ2A.HNN&)éù;^„…=$*ò •*—ÎÖ5jii)Æ‚ç ×뉋‹Ïñ¾K—|éÛw½÷LÇÿn Û.ʸŽP(5@ |(¡Ê4B½Jùa»F@ð¡)B ª´eƒj…Bú…§®kÒþAöè^S>*@¸F‚¬y±×j•R^WýÒ‹‡ÏÝ»bá¯@-[6æÓO[¾r>k×n`ÏžƒB A.\É“‡¿œuø²…vîü9‰‰)BúA¸¹9¼–|êÔ©M‰e…@‚,°²zyoÉK+ÂãÇOþPH_ ÈÚµ«áîþ¿WÎçúõëüóØ–K È ww7J–ìôváС}Q‰†AŽ$''‘””ðÊù4n\Ÿ&M Y Itº—óR¾‚&Ó É o±­èõZôz±›@ðºQ @(ÂW`ÅŠ54oÞAþ»s'ø¥óŠˆˆdÞ¼Eÿž~¾^Ïøñßeyíܹ‹üþûN“s‰‰‰Lú}¦{ãââeùÝ»wßäÚߟ yó&Û5eǾ}‡8rä˜É¹1c¦¼‘ß¿iÓ6“gß¼yFš,_¿råÍ›w eË—óÛ/_¾šÛ·ïÊÇññér 6•ÓÑ£'iÞ¼]»~%Zu.ˆŽŽ¡cÇîtìØ]Þ"L xߨ·ï§N{ãå¼Ò ߟî'>>žmÛ~•ϵnÝ9Ë0;¹!99__¿Åº?”‰§žéÚ¥K¾ôî=ˆ®]Ó@pð}FžLr²éV[wïÞcÆŒy² ‡ŸÀ!ý)Q¢ÇŸâèÑ“lÛö+=fذqŒ3WW—çÖ+$$,Ó6\o*îÙíÛw0à+6¬›Þ³JÛÄÖÏ/€U«Ö³mÛ¯ úôù†)SÆ/ŸG®:k×n`Ú´ÙÔ¨Q5K91o¾éOÉ’Å8qâ4ÿ}¾íë{^½¼ñõõcÇŽ?Ðéô¤¤¤ T*‰ˆˆ¤aÃz>| ÿ,--IHH¤zõ*ï§"|Ú þùç çÏ_ÊU\¯q㦚ì¼îïÀÞ½‡ðô,ÉG¨X±<ÕªUà—_Ö1nÜp\\œ)R¤––&ùüðÃ÷lذ•_Ý,7òÈÈ(~úéú÷ïÅäÉ3øôÓÖršÓ§ÏammEÍšÕ^ê7K’ÄwßÍaܸa™Â­œ?‰'N3xpNž<#Ÿ···£G®äÉcÿV^Ê™3°fÍ“žøfüh9‘víZ½RYcÇ~ËôéeKpÔ¨IÌžýÝKç·|ùjlmmèܹ—.ùÊç[¶lеõ1>ù¤}ûö0y®/ÊÞ½‡ º+¿gOß§üŸ¹xz––eõˆÅ‹fÀ€ÞLžìCûöéåž={kk+Ùµë/“Žà÷ß/`áÂÙïìã´wïAnÜdðà~$%%1oÞb† m:GÇ^·nÆ äÒ%_,,,äv¿mÛnªU«,¡€„„nܸÅÏ?/”Ïݸq sss|}ý(P ]ºt4ñöêåMÛ¶-hܸ-‹ͦT©±dÉ/4lXaÃ`oo‡³³mÚ4]£•Ëž=û™:u¼üAÌŽ«WýùñÇô±²§=êP6¬ÏàÁýä|Ö­ÛDrrJšõa†¥¥¥œ.c … gË‘¡}}ýä^»V«5Ióª½ôO>iÇ„ # {Àýû¡ÄÄÄpÿ~(®®.|óÍ(fÎü–«Wýñ÷àîÝ`žð˜1C9r0Múkäã3ï¥óÛ³g?¾¾×èÔéSNœ8Mhh8W¯úQ©Ry‚‚î²qã6þüÓhõ:–²eËPºt‰—*K¯×¡TªLÞ™3§ÈïOùòžò5­VG@ÀMM,è† ë¡P(¸q#I’Lò›>}"ff’“ßÝ ëiÓÆË•ÈÈ(¶nÝc•JeÒá¼uë6))bó Áóquu¡k׎´nÝY>×¼ycºwï’cZKKKJ•*‘æe,òJéw¦8¹s—˜6mâKç‘Qy*•Š,•é¥K¾ìÜù§Iܼ””Ôô¢V=çC0‘%K~l³S± IDAT6iä]º|F‰Å^ª®;ÊÁƒG0 DEEsçÎ]<<òÒ°a}8"»C##£ˆÇÆÆæí>TµÊD9Bþ_dä#–/_M¿~½^I >}n¹éøä–bÅŠ’'Oöï7ºå‚ƒïsîÜ%ºuûœ~XÊ€}äß5yòhɦM«^ª¬-š°uë.öí;dâ®ùúëÞinÅ&–NÓ¦ ³}wK—.A‹Ÿ°woz~‡eܸáïôõ¢¡ÒâââYµj=:]úþ¨bã An\£Ož$°kWº'jðà1„‡?x¡| *•"Ëk—.ùbccýÒßî7¦O:›æ}µ™zþV«¥lÙÒϽçÂ…Ë”(Qœ.]>KSpsL|ÎÏcΜ™;wº|>§Óé8wî"uëÖà»ïÆg°nàçw|ùܳÍoàÀ¯˜;w!Ë–-HËc6'Ž`üøáLŸ>‡ñãGõˆ³g/¾r÷‰§1lØJ–,þœëÓ‰ŒŒbéÒù9æõÛo[(UªU«VÊtmîÜi >¹s§¡×ظq+&Œ|æ·ÄÖÖ†3Œ3MK•*n"Ä„¼½;§ÝÛ‡9sÒå4uê,YN&Œ`Ú´9L˜0‚GsöìyFšmÝÿúëööv&å5hÐJV„£GÆÍÍ5GüþûNòåsÇÉÉ‘k×®›ä׬Ytºw»Þv„ilݺîaÁÁ÷X¼x.‡eݺ™îÛ·ïÇŸ@€F£!<ü!mÛ~!ŸkÜØ‹¼yݨ_ÿc~üq©Éµ§îúœhÖ¬1 ,aÕª_©T©öyÿ,BI’Ø¿ÿ°lØÚÚ°sç†lÓmÙ²/¯ô±©Fê3vì0"""MÆŸö´ÍÍÍéÕ«>>såtO•€§g)4šôH66Ö/^€~ýzš”õÙgmiÑ¢‰I111&³^¤÷bt7fÆÉ) ä“; O—YH’„—W+lllصk%Kãûï¿•ëøË/‹(R¤,…B—W+œØ´i•¼[úóÈ›× 33Ó¨ •*•“•Ç·è×/]I´k×ʤ#c0¸téJ.­ãŒ9‰‘#Ó½‡'fT©R/¯V(•JØ‘©îƒAžd“µ…XDž¼R¢D1fÍšš¥œžºÖ½¼ZáääÈæÍ«s”SÓ¦˜1c>>sMÞK€ ~¡Co¢£cãì·•+ËzV¬øÁä}êС<©çÒ%_“k3fLÆÂÂ<ÓLá·ÉÈ‘ßÈî*{Ö¬ù 0Žwïþ5’$1dÈX4¨ÃСÈŸ?íÛ·–Ó4jT>}ºcnnF×®Ÿ3oÞ"Z·îL“&^|üñGB㤹>}¾|ƘP P€¥¥Ó¦MÈôí|Êο=7_¼|ÿý·Y¦{(*ׯ%Û5Ÿ‡±lõžÿAF¨?}ú;wî‘-“ Z™Ìø¼¯+Bý‹2zôdºwÿ‚2eJ½–ü®\¹†F£ÆÓÓè¹éÝ{>>“Ä2Á¿Š§ê‡™Ï¥Àëlê;±Y(ðóÏks5­ÿC`„iLŸ>Qâ?€±÷üúzÐyóº²`ÁOøùкu3òäq‚üëŠL¦ü~è<ëÂü{y: öuáææ*¼&‚ÿ$b¯Q@ ‹P üwÐjµ&Ë8‚ vv¶Ô«WÛäÜߟ0Ù[øé|I"Ã9;wxfÙ˜P„Á‹Á`àáÃì±¶¶ü+P*UÔ¯ßI2XöèÑ#<<òÊ+\]Ý¡¡÷åsžžå_Z ¾Exõª? ÔªU]>ÏŒéëÔ*U*Oǎ툉‰eÖ¬2å1zôìííØ´iW®\“Ï; [Û׿XýÈ‘ã(âÅ‹¾ó—ãÊ•klÚ´aÃâììøÎê±zõoܼH½zµiÒ¤aZOí8û÷1¹¯H‘BôéóåsóÑëõLœ˜¾®³dÉâtïþÅ«÷¥K¾lÙ²C>îС¼´`æÌùÄÅÅÓ©S;*VLßV,""’ ŒK Æ!/®ÿî»Y™f€vëö9eÊ”|ï>,eÊ”Êvm®@ð>affƒR©Îq¹Qž]»v’÷5Œ‹‹ãÊ•kLœhºðÚÒÒ‚]»þ"*ê­[7Ë ¿eѢ׿—ã?ÿœ¡fÍj¯]0‚Å‹ç¼Pš|ùþ õêÕfÿþÃlÙ²{4 gΜ§wooRRR¹ví: ‰rØŸªU+å¨u:×®]gëÖ]¬[·L¶¨##£øâ‹ÞtêÔNKtêÔY† ÈãÇ1™Êª[÷/­sâçŸ×šÈ)8ø>ýúõ|©¼®_¿ÉæÍÛ±²J߸úüùKLœ8Š]»öàç€Z­–-Õðð‡tíÚñ¹ù¹¸81|ø ÀˆvÙ²ÕôèÑWWç×òÛwïÞKË–MÅL x ØØXcaaN—¾éÄÓïÁ{«Á‘ýÉ“9¶[ΦoAYùe´Î^7‘$'§0bÄ7”cˆìž«W¯6ýû÷’?ð ´¢oßlÚ´ÝdוŽpúô9¼¼êR­Zeþøc/“'ÆÚÚš ¦E•*9òöì9ÀÈ‘ß于ÖÖÖŒù A™®.\€þý{É2úòËþÄÅÅS¡BY*T(ûÂe½ =zt!$$ŒjÕ*›È©_¿ž :Öd<Œû´vìØ6 ýÚ¤Õ¢ÅgLœ8ŠC‡ŽÑ«W7yK;N'Ï$ëÞ½?÷î…˜ä5|ø ÙRKIIaüø©Œ9XÞ–íUINNæôé³Lš4J|¡rÀ`0 Õê077{¡tIIÉ&Q0Þ))©ètºwNJ«Õš°°°0 "`0HLLÂÒÒâ?³›—ñwëHIIÁÚÚ*G×½……%..®$%=19Ÿ7¯+ׯßÄÓ³üû«Gš,OfIMMÍÕ.ÎÎŽT¯^å?„ªU+|ÎÓ?ºÍ›"‡)Y²øK«äÏŸO¶2ßäât''§7ÚQÈ îîyqwÏ›åµùógdy>555Û<ׯßÌ©Sçäc¬7-W«Õ+fÜOvõ꟞›_HH üÄäÉcrµ‰vnéܹ6¬üO|âãŸd»ç+÷~Ù1ÜeËVqëÖmæÍóÉuãý‹èÒ¥uêÔz£¿Íšß8zô$ëׯx'ò_ºt%k×n$o^c¹&M¼èׯ§líܾ}‡aÃÆ3yòh×¼QNA88ØË‘à3rêÔY>ú¨Æ{ûÞýý÷q~üq«V-Éq" µµu&%`ggG‘"…HM}µ­ ßè‚úE‹f³{÷FvïÞÈÚµK_{þ?ýô‹Éñ‰§>|<‰‰9[Ÿ÷î…`ff.×o÷îi‘’uoå%x¶îo³¬“'rÊ•^°`>ll¬¹~ÝïðácÔ­[µZÅ¡Csófà+Õ- à&ÖÖV(_¶3>“ ²–Ó“' ¬]»1Û¼cbbY¶lÝ»‘I Ö¨Q•7n++à§nÖnÝ:±nÝ&ùÞíÛwÓ®]Kùøøñ¨^½Šì–þ·FrrÊsÿ®]»nb±¼«V­çÖ­Û/”æîÝ{¬_¿…±c‡qòäé7¾&ò«¯º¿3%ø”qã†Éï|ùY´(½>%Jc÷î™” À–-Û¹|Ù÷9y~÷^¿w7`÷ ïææÁ… —³ü»råšÉpÕ{eÍøt=«P(±²2º=zÌgŸ}ɽ{!øù]§e˦Œ; …BiØ4#íÚµdÆŒyüòËZùÜŒSLî¹~ý .gܸárYÙYž7nÜbÞ¼E& B£Ñ`nnžÉ÷ütÖæ²eóM" ”,Yœ)SÆÊVJvîŸùó}ä´£F ÎQ†GÓ¡ƒ7÷î…põª?-[6aܸá(•J“q4++K“û¤I£ä²žÝëúõ›²œrr¹¹¹Ò·oO¾ýv&7ñòªË7ßôC¥RQ¶¬'S¦Ì0Q†Ë–å¾IÁõë7井.]2ÍZs¡N8þ²‰|—/ÿâÅ‹2rä7Œ=YŽofmmmÜ9+Y¿~3'Ož69¿aÃJÊ•+ƒ7Ý»Mll]ºtÄÛûsÀ«ÐÜÜ\®Ç¬YSM>B~~T¬Xþ…]}ï+*•7·çoœíï€^ÿâᤶmÛÿ³#ë×oÎuºñã¿cöìïððÈË€}˜7oNNyP*• 4 KK ¦LËäÉ>øøL¢V­ê$'§0tèXyò›™™[·®ÃÚÚŠ¡CÇ2eÊXV­ZÏ®]{¨Q£*ß~;ss3Ž?ÅäÉ>¨T*Øa⮜7o±I¼ÊŸ~š'{ŒºvíCX˜ñ]tuuaÕªÅXZZÒ»÷ š5kÌâÅ+Ò>ö^Œ1Ð$:NÖïj±±q²%÷ùçŸfðT}Fll,³fM¥vítë¸I“ö±yóvóЭ['zôèÊ•+×:t,—/§GCY°`&*”%99…aÃÆÉ¦5 Û¶ýj"§Õ«×³sçªW¯ÂÔ©ãIMMeüøï(T¨þ¹€>}¾¤cÇö&ßø¬èÚõ+ÂÂÂpqqfõê%XZZþ€.]ú˜˜Äβ}ÿŒ£ÛÏëjccƒƒƒý+µÿ\ô‰¼Y¶lNNŽžÏgŸ}ÉÒ¥ó…œÞo;úDJJ ëÖmâ£jP¶légÞ¼øÜø”`\W[½z9$Ö‹rùòUÖ®Ýk×è³ÑO¾ûnuê|„B¡àèÑLœ8ŠÆÛrèÐ.ùÞñã¿£E‹&üïFW`RR:xóçŸ[xò$%*³téÚ´iÎÎ{¸s'˜!Cú?·ÌÍ›·óøq´Éቧ›Ä›ÌhÁNú=+W.ÆÓ³ôaÀ€>i¹ÕØÚÚйs‡çþÞ… —ñ믛ñð03xyÕ¥_¿^& ÄgÏþ‘²eËмyc“´>>s©^½ 7ÈQŽ`ÜT¿yóÆüï5åw³}ûnìÙ³…„„DНÄÒ¥óiÓ¦»výÅíÛwèÑ£ žž5Y¾üZ¶4†°4h$ýúõ¤lÙ2¹~‚ƒï1eÊLV­Z"ŸëÖ­/3fL&~yÖhrrŒIº­[wÒ¨QS”ʬ‡ªâãŸ`mm½}î&þç£O?~Š*U*½³Aï 'Nœ¢rå BN‚÷’;wî2dÈùøÌ™ Ô©“sìÃ~ø‰Í›·dâ¨V­ mÚ4 |yO ÌÿÂõʨ¿ûn6ã¡ÆÅÅgð ¸ÉJðE3fíÚ­·?þØËÂ…Ë6lÀ‘ï‚?±yóö49™ZúU«V¦M›”+WFŽ©Z³f5Y ¾Ӧ͖ãÆf”Ó‹¢Ó鈋‹ÊòÚõë7(R¤$öö…ß?×è»ÀÓ³*”ýόݼ)Ê”)EùòBN‚÷77Wzöì&kµ¹·oÙ²‰Éî@ÏÛuªhÑ—û`ÆÅÅcggË”)3©S§–‡1 à&{÷|m¿¿^½:,_¾æ…aRRjµ:K7ìÓºåÔTÞÄ$7rЉ‰Í±lƒÁ@tt,66VòR­o¿ÉÿþWSŸ¸i²û}⥡V«3Yäý>`kk|Я:ƒè¿ŽÓÛå}k'o‹ÀÀ ®\¹Æ;Áܺu›­[wáà`ŸãFVVVò20N‘ψB¡ nÝÿ™œ+[¶ ñññòÄ•JEÛ¶-r¬chh8§OŸ#22Š­[wQ©RyŠ+BþüܹÌÖ­»ä{ÿùç,sçNÃÍÍ…ÐÐ0yLoË–¯¼Õã©Sç0Œ›R?þÉzë;ÿäêUbbb±´´ Aƒåk¥K—äæÍ@âââñó»N»v­(_Þ0®~Zÿ#GޱhÑÊ–-M\\F9)iÛ¶å+?눈(ÜÝK²téúö퀫«+aaá²%¸eËÙ½žÈÞ½¹w/„={öS­ZeÊ—¯üïS„IIIâ 'žKbb"<ÄÒÒ‚¦MñàÁÃ\Mº<¸¯ÉqÓ¦ÒÆÏòš³É“ǘÜûÅغu<4~Ø2Lv377£_¿Y–•’’ƒéß¿'<$1Ñ8Vú¿ÿÕD«ÕÊ›RòÖýû÷bݺMrY Ì àV–u¯]»ffš-ÀãÇÿ‘ó<¸¿Éd¸‡#©Y³*`œh˜‘öí[±k×îߥI“†²4ZdcåI;ãÆwîl*§Œó<ÌÌÌ²Ü ÃÒÒ’¯¾2Ý?ø³ÏÚ™,²³³eÑ¢ÙÔ©SS>׿O~ý5k9éõz_ÒªUÓ\×åñãhììlÅú7Œ¡vž Û%¼oèõ*t:I(Â×ÁðáX²d®¬ø®^õgΜ…LŸ>Q¼io˜ˆˆH$ Òô ÉÉ)¹Ú:©{÷/èØ±-={ÌtÍÚÚš]»6¼p]¾ýö{† é/ÖÇa|/]^ x{ŠPEøÆY°` åÊy²m›1FWãÆ äÈãûöbçÎ=ò½ß|Ó—Ò¥K²gÏ~Š/Ê‚?¥}T,^>s ã³ÏÚšl6üäÉFJ8\­Z%zöìFll,cÇNåìÙ DGGcccC·nøè£âA¡W¬XCß¾=?~8[¶ìäĉSØÙÙqîÜEù<ÀرSYµj1~~|ÿýÖ¯ÿ… ‰Þ½ñóÏ ÅÛ“K$IbÁ‚Ÿ7n¸,ãU«Öãîž×$Ê@VôîíÍÞ½‡¸y3ÐD8ŠéÓ'ÈÇçÏ_bß¾C4jTŸñã‡3eÊLzöìJÁ‚ù…[<RSS‘¤ì{âfff²ËûE9pà§NcÒ¤Q¹ºÿþÃÌœ9_>nÙ²)ýû÷ÂÒÒ‚Õ«cÍš äÍëʆ ¿˜¤Ójµ4iÒž>}¾Ì6î«ÅÀ#‰Œ4î}éääÈâÅsä°L{öìgΜ…lÞ¼gg§çæÓ¿ÿ0||&½Ðûyé’/ûöb̘¡Ï½çÌ™óôí;GÇ<ò9¥RÉÁƒ;4hçÎ]ÄÛûs¾þº÷}·t:G˲Šð= X±¢|óM_“—#99 ‹T|}ý8|ø˜|íÖ­@ùÿÓ¦M$~4ëF’M rOÅŠåéÝÛ;ƒ•(‘ššóWWœœòbº¯\¹2&Ï«páB|ü±1xk¾|XYY‘7¯ùòyáç@`àlƒ4‡‡? R¥ò/¿òàÁ¿Y¾|µà57̘1?S„úÓ§ÏÑ ÁÇtïþÞÞŸÓ¸qÛLé4 ‡ï~ãò;ö[||&Q¬XÀ¡~̘)¬\¹€æÍ?¡yóOrÌ'*êÑ /kIMMÍ1>`rr mÛ¶dÊ”1Y^_¸pû÷æâÅ+o\Váá?þ;Ö®]*á¿Â4V«Mú°aŸÊ{Ì A_±k×_òñ•+W‘$)Sœ:AnÞ}… =?úDPÐÝL‘Ìsþ}‡ðó `äÈoظqëÿß~;“[·nÓ©Ó§&«¦OŸÃøñ#äã .EÓ¦8þ ,‘¯}ùå4nÜà…Êuqq’'„EDD2lظ4…3ÛÄÚ;tè(«Vý @£F¦e,XðçÏ_Ìà½úKKã§^½‘’’ @ß¾=ߘü2Ê)))™Ÿ~úEœœV­ZÏ¡CË×fÏž†»»?ÿ¼–?ÿÜÏ•+WéÚµÎÎN,X03“œ4øoïîB¾.ÜÝݾ/Ç튈ˆ”Ý·o1oÞbZ·ncbYYYaaaާgi*W® çãááþÒ® wnß’å£cÎnŸGö€ÄÄDƒ(P ŸåúþýPÂÃõˆ;w‚åÉ/“'Ï0±0O:k«ÍÕÕ™°°pôz=7n£Oo9R¶àíP§N-êÕ«-Ç {Ó Їýûãï`¢¯_¿Ihh8ùò¹c0ð÷À`ˆcÁ‚%Ìš5U¾wÖ¬(T¨îîy ©³\´haæÌ™F¿~C‰ˆˆÄÛ»3uëþZµªàèèȬYS4h‰‰‰²" bçÎ=rYüÍÑ£'X¹òW\\œMêѵk_¶n]K÷îý™0aVVÆNz‡ÞÔ­[;GY¬YóÇŽóïÞ½ ÞÞŸçÂz?*+B­VËÑ£'6lqqqÌŸ¿„Ù³§fÈ%J£pá‚´oߊ&M¼äk_=ŒíÛ×Ó¡C*U*Ï÷ß/`Ö¬©&±ûöÊâųåã#GŽsèÐQêÕûX(Â×ÁÌ™S˜8q Iin2w†7ÎF,V¬(UªTdÉãØ‚—×ÇüïÆIFÊçúõëIɒŨX±îînòy…‚\MòøY²d.ÇçépSñâEùúë^ “†PµjE\\œe%vøðqŠ/Æ’%¿0lØ×äÏot¥mÞ¼ÐÐð´Æ:¾ûÎ8.8aÂH&Mò‘ó«\¹‚<ñ `üøøøÌ%*ê1ŸÞ^(Áw@v1ßÎÎN899rÿ~¨Éù¥KçÓ¹s/vïÞÈ“'Oغu;vüFtt ~~7ؽ{oÏÂ5t:7o²bÅ“|ì™9s örùµk7°`ÁO´oߊúõë V«ððp—­¹§ètz´Z-îiUgþøÃXnBBgÏ^0Ù|ááÇiÄhòæu•cAΟ?ƒíÛÿÈQ_~ùÅs]£/ŠÁ ‘˜˜$×`ìØaòÿ}}ýð÷ƒƒïËòrssÅÒÒÒ$-·EËx®K—Žrìíí¨ZµR–ù-_¾š6mZàææ’fÖfêÔï³ü®ä¾Ó`eRI“Fÿ+d{úô9NžgggË!ýX¼x…|®S§v9ŽÁM:ž)Sfiœ=îääÈ´iÆ ;âââX¼x ägË–Ô©S‹Î;P¤H!Ú·o-—U¯^m||&aaaN—.Y±bI=æÎ†……‹Ïeذñ¤¤¤°fÍR®_¿‘mý<<Ü©^½Ês¯g”ÓÒ¥«X°À(§+~dèPã–±c‡1nœqLÐÖÖ–!C¾6©_ÇŽí(\¸ … $66V¾Ö¹sœåûòæu£G.,^¼'§ú¨eË–ÆÌL“íxÝÍ›”,Yü¹×9NõêUäq*Á“)SfÊãŠqqñtëö;wnxkå?#LNŽyFqïÄÎÎFóÜ´žžåquÍ]ŠK—|éÛwCŽÌçRàu6õÿ*¡„µµ†Úµk‰7è=ÁÜÜ .•¢E R¨p¿(•ïÿÌcƒA’'ndýÒ½òîþ‚÷Ÿþý{áåÕ KK 6lXùÁüvõ«6r öýBB£Q£Ñˆ%¢‚ÜQºt yLJðáâææòV6$x/;¬âñ àCF(B@ E(P„@ |€¼ôŒŠ˜˜Xt: @–––ÙFwxÓ¤¦jÑjcŃ¼×˜™Ù P¨þ]ŠðèÑ“"‘@ *V,Gµj•ßirŠ7(¼k$Iâ]Å9x¥9ö±±qܾ}GŒ¤E‹Oä˜yo’¥KWqù²¯IÈ 7xz&½³²_yÕµR©ÄÜ\׋@ 7¬÷l?F“)4Л*G ø×µ×ו‘µµîîy…DßW®\ÃÜÜ µZ›› ¶¶¶B(QF=zÌ­[·åàµ9ñçŸûLÂt]ºt7779ÂÃÛdË–8;;Ò AÝ7^ÖÚµ)Y²X–ròõõãìÙ󸸸ЦMs“kýu€ÐÐ0*W®øÜÐQ‚·¤Õj5vvâãû®Ðëu ÆÇiii)žÅ;$11ñ_Ußë×odëÊŒ£B…²˜›¿øvŠ‘üþûN9Ðrnx6°î£GÑo´c·k×_Ô¨Q…¼yÝ2]kß¾U–î혘Xöï?LÇŽí^[=ºtù,˲BB¸?„=ºrÿ~({÷¤iÓF€qCô¢E óÉ'^9rœÛ·ïÈÑ8ï@ ‚'*•*ÇèZ­î…áýû¡\¿~ƒ-špåʵW®gtt 11±)RˆC‡ŽPµj%9 íùó—äXxJ¥’ Œ±í.^¼BÁ‚ùå:¸¸8Q¡B9t:GžäÞ½û lmm(Uªùó{p‹ÐÐ0ÜÜ\)W®ŒIÇ!(è.aaá:t j×®™cýCCø%—/«‹lñEFFQ @~þÏÞY†Wqtø½÷ÆÝ!!@ @p+’(¬Xq(nÅJ±âZŠŠ·¸SÜK?ÜR<$HB„¸ë÷ã&›\¢ÐPÌû<<äÎìÎ̞ݳ3sæ'•ó2-~ FF†”*U2[^r¹…B££ƒJp_Aáê1c& !?üðwîx±qã6! úúzÔ©SóÀ>|\eÛ‡––&OžÍ³gÏÙ¶íO•òŽ?ɳgÏÙ¹soŽºâââøóÏý9ò—äØáСãÄÄÄàêZ†ƒ.nÊ'Höç+»áÈ‹þx{ûàí탯¯îîs=çCÇ•+×¥öy{ûSàyÍš5¦]»VT®ìÆÀ}PËfŽÜ¯_OjÖ¬JË–_Óºu ñ`E˜¿"ìÚµ#íÚµÂÈÈnÝ:Ñ®'r¹òÒ+TpÅÈÈGGÕ/¿ŠË3zôDé÷´iópp°OLT¬XAå·ƒƒӦͣbÅò”,é bÄ3fÌ$*TpÅѱ$FF†ÄÄĪ(=''eº«kÙõŒ;…råÊàììÄĉ3pqQ~Ý—)ã‚‹‹Ó²]@P0ïâÔææÍ;¸»W”¤Èd2¨Q£*MšxHÿªT©ôÖm<þááoÕöèèhNŸ>§’ö¿ÿQù°‹#::Fj›5±±oU‰-hB¾'^½ 毿NâææŠ¯¯NNŽlÛ¶›äädIá¼âäɳ*çUªT>}º1eÊúôÂü&¼e‚7×OŸ>ϨQƒ©T©ŽŽèêê0vì/žK‰6¨««áëëG¿~=騱-qqq 8MMM|}ý°´´`ܸ©øø<`É’UŒ3ŒòåËâââĪU‹3¡3))©ìÛwˆ2eJ£­­%nÈÄËë>+W®åàÁ£²råZvï>PàymÚ´$%%…êÕ«P½zU $KHã\ïë×_ÅíÛwY¹r-+W®å÷ß7Jyo®áéêê`ddmTÙ‚óç/±råZŒ066àܹ‹lݺ‹èèhV®\+â€rÚ·J•J×wŒ† ¿È¡˜³+o 3Ê–--µ/""‚:ujJ3SÇŸäÀ£¼båʵ$%%Içjiiæ¹ögdd$>øŠ€OÞjTWWW²²òòº»{EÊ—/‹\že.n` —«’300@&“agg[,<„| ¸¹•Ï1"400P™¢ÊnNpp(ÞÞ>ÒT–B¡†••ÏÊÊ++ ¬­-±¶ÎÚÖŸÏÖ6mZæšîéÙLåwnïz‡mr¤}ñE¾ø¢Nžõ¹¸8çù¬yx4È‘æêZ6×Ù €¦M=ò¬ÇÜÜ ss³\óÞfÔ+øŒ¡¾¾.ÎÎ¥èÑ£³4 T(”ƒáÔÔT (Uª$©©©ÒZjj*Ó§Ïcò䉊ŠbäÈñ,X0KšR¨’––†L&Ãݽ¢ô·L&Ë0éήåTª¤œ>5jóçÏ T©’Ô®] .ãïÈ7ß´¢cǶ”-ëBUIKK—îWf¤««›‡"ÔÄÍÍ5£ rÄ÷KÁ$$$JS¹EBN‚O—O¾W áï¿O«¤íܹWš¹¦Ú¿ÀöŒ9DÜ@ F„@ E(A>ÙÔhxxW®Üý@„†¾–?}êË“'>B(ˆìŽŠ ûöæùó—~›7ï¨Xy Ÿ•"LKKWÙû"øo±´´”bÁ¥¤¤’’*„ò°··ãÕ« bÓžúõëHޤß7_}Õ33Ó<··yaffýÁê."E(ÃÀØ\ÜÉb‚ŽˆÀôaG„©)Ū=ÆÆF"N Ø£¡¡ùÁê.E(—+°¶•@b|t±jB¡œS Å™LÁ‡ZUñ‚O…BŽ––¦„ X“œ,ÿ`ëëïU¾ 6®ËårJØ §Õ@ (^¼—íáaa\½r‰Ð¢£¢ˆŽŠ""<œ«W.$¤.|Føû²o_ÎxyÏŸ¿däÈñŒ9žää­«;ö?霑#ÇKި߆þ¹ÿÞBª-[¶Få÷¥KW¹yóÎ{“íߟfäÈñÜRyîÜElܸ=×¼ë×o1räø¢¶lÙÉÈ‘ãs µöQãââxòø!Î.e0’ÉÉtm–žFDl,1‰‰$$$ ¥õv‘’A&kAóô©¯ 67RRR(]ÚI²J~bbbéÚµUªT¤M›*é³fýÂàÁß0räxæÏŸ‘oÄë×oqåÊ5zõê¢Ò¯^ýë[^ï3|}ýhРn‘ËòÏ?0dH?é·—×}ôõõÞ›sl7·ò˜››~ð mÚ´È5 FPP0ëÖm¡ÿž„††1yòl¦OŸ(·ôDEEÓ«WNŸ¾ÀÑ£'hÜøËOCž=}’¯›·Dq÷:ß´Bþâ¹”§_§.qk7ñøÅsœK»¼U¹Û·nB[[›»ŠžK (BRSSóØqêÔ9ìííÞZ>}êËÒ¥«˜5kRŽðK;÷aÇŽuèêêЭ[G¦OŸ'¹ßËK©Tªä&¥eW‚gΜçõke0f…B!íMIIáÀ£€2Z}v¹|ùºô»re7J•*ÉË—Êekk+Žù €&M<ÐÓ{wŸ«¾¾~ܺuWú]³f5J”°æéS_´µµ°±ÉÚ>pîÜ%¾ø¢6—.]¥zõ*R@Þ°°p_Q¾|9¹pá2 44ô5!!¡ÿ+ƒVׯ_33“ 9]àõë0@aãÉoêÔ©™oÛ^qùòµr¸}Û ŸgØÙ•ȳ5))™èè*Ur#$$”IyaaáèëëQ©’ÁÁ¯Q(>\Ø´"õ{æ‹CIGwï ý]% ¸xíßaššBXØëçÏ›5±£†3vÔpæÎÌòõ9{údþܱm›72vÔpöìÚQ¨öl\÷»TÞØQÃILH`Ýï«Tö<®Z¾4ÇßkV.cì¨áüu숔wâøQ•òžùdmZ_¶d‘”>ñÇÑ9Ê;t`/cG gÃÚ5¢ç|ÄÄÄ2|øÀÿÄa÷¡CǸzõ&þþøûâç÷œ•+×°dÉJ)ÝÇÇ5k6HçÅÇ'Hyþþ¬[·…W¯‚ˆgíÚÍŒ?MÊ[´hY¡Û³qãv"""UÒbccUêZ¶l ±±±ÄÄÄòÛokˆ‹‹Wö=k6ðâ…ÒQýìÙ IHH”Êxòä)›6)û¿ÄÄ$üý™0aºÊˆþÞ½‡ôê5˜K—®Iu-XÑ:ÎÕ«7¤ô_~YBhhXד *§õë·¨\抈ˆäáÃÇ,\˜¿|ÌÍÍòôܸqÃ|C^}T# W8»”A~ö ¯»¹Wx憩i¼ˆŠÂÄÄT%ßJ *4$˜YÓ&3qÊt:tîŠB¡@SS‹&ÍZ`llR`[vnÛ‚B¡ ×wY‚Ÿ2ñGæ.ø•c‡ÒéÛnÒ4ë¡ý{0x6%lùò‹š|?j,u¿hÀÁ}{053C.“qãÚU•ò/˜Çâe«X¹l öö4ú²1ÉIIŒ>˜K–Ó ¡ jW¥K·žôú®?·o^gÇÖÍtêÒMô”‚OšLgé·o{½÷º.]ºF½zµ¨^½Š¤àÁÀ}8xð8§N”^är©©Ê55[Û|ûí7R9?þ8…°°p\]ËúšV­šÑ¬™ò½nÛ¶ð³Qýu’/¿¬¯’æì\ +«,¯;}ú %!!‘J•*`llÄ?üDUÑÓÓ¥S§v*ç®[·gçRhhdÊ­­-6¬?ÍQÕª•2¤Ÿ4ânÔȀ˗¯Ñ¼yciب‘g޹akk£"§q㦆µµ% Ö£lYFޝrÎ/¿,eÏžƒøú>ÃÃÓ-[~—¼uî܇;w¼Éä?þ?6mZýAŸÕbµ}Â÷©7±±Êé`”.¡J»”ÁÚ¦ÚÚÚ¸–/Ü~Ű°×ØÚÙ«?wAÁk –4òhL«¶Ê›þäñCttt¥9øÇHÇþ4}–²­ÁAT©ZMª+>>žçÏý°³wÀÚÚ†C†+¿ââ ½¤@PÄüòËR•HîõêÕÎ9&—coo‡¯¯IIɬXñ;/^•òoݺÃèÑC¥ßŽŽ%¥¿÷îÝòÎm‹ŽŽaÙ²5*†3·neýmooKUxüØ›!Cúæˆ{úKK LM UŸ……¹¤³S¡B9îÞ½‡¿¿2DYa''''³|ù\¼x%[Ûï2räà|Ï3f:µcâÄlܸR%oûöµ¬]» uºuëôÁŸb£wlÛLØë×h¨+GiáaÅ¢]­Û¶—þnÒ¬9·®g­',Y8Ÿi³æ½UyîU«‹KðÙ3xðw¬Xñ;cÆ(?÷ï?BëÖ-ÞºœÅ‹W0bÄ @^­Nü#'$$°jÕ:š4ñ 66–³g/±gÏ&©sïÑc࿾¶‹¯P¾|YÖ¯ß*E–WN×¾`çÎõ€r.»R\½z=úúztêÔ–%KV1uê8É ÐÏï111œ9sž–-¿þWmÓÑÑáåËÒÓÓ˜8qtŽcöì9Èùó—Y¸Pù¡Ç™3Ø»ws‘Ê©8Q¤ŠÐ­’;W/_ÄBK“tdqq9ŽI70À?è6_4PI¿së&;wŦ„ÒqôðÁý133“òµµµILL$8ègNýK+kê7ôÈ÷†'ÄÇôJJ[4.s~YŒ‘±1!!ÁhÇ(­œtuõˆ‰‰FO/oßd^wïpãÚUZ·Íš>H9Mª«§GLt´TWbb"FFÆ¢·|ÖìÙsß~[MBB"‘‘‘xxxâââÌÊ•‹hÞ¼ jjjxx(§ìV­ZLéÒNù–W£F®_¿%H£·#1nÜ4&Mš€¦¦G*@¯\¹P:GKK‹ví ˆÐ*»—%--ùßן˜È¦M;¨]»åË—ECC=_ƒ•ǽ ´­^½Ê¿²˜&Mš©²F˜@»vÝ9rd×o[r²œ””4"TÒwïÞA¾JÓÕÕ ÃBÕsëÖ] ÁˆS‹¸åý€ýÔh%÷*„Ö°vK–£(M´_jj"¯VKs‹\Ï}s ¯l9Õùë~‡Ðo`á#ù~TžyË׬˵.çÒ.yníhݶ½ÊTivÆÿ”û‚³¦––P‚‚â­¸“8wîbžùÁÁ!BHŸ­[7gûöÝlذ P®™Öÿ³—K‘+B™L†™¹ÉÉIøÕ¬-¹XS(Ø”(šš: …B<‘A1ÁÅÅIÅDÿM*V¬ Â*}"T¯^++Kâã2¡ gçRB¾Bår9ššZ8”tOž@PÌÑÔÔDSS8åþ\°³+!„ð¦Î"þKÒI'%9QHS RR’„‚ÏN¦¥â÷øŠ¦@ >OE(“É1·qÒ€ä¤à|1¡¦'nŒ X£tºýaVëŠLêYŠ;) ÜGXœHKKSq2/G444r¸–û¨¡@ (¾Èåòá‡‚âøœfx~û´a`€?IÉIÃ^¶¶öân ÿõK®¦@GGGBP¬Éô,ó‰(Ât"Â# ÁƦêaCRSÓð~ò}ÌÍ->Øøm  CK[;×èË@ øF£E]`Dx)©)8—vAGWuu ÔÕ5ÐÒÒ¹´ ±11<ÍðÉù6>ϸÿQ±ßºu[$9íÛwø_•uíÚM‚‚‚?I9+E‚™™yžù¥œœyú íÒÅóܸ&¶hEÍË—þøúúåû/%%åËïß»víÍ‘>{öBôõõÐ××cæÌù–óè‘7‡SI[°à·}ý6lãÅ‹—*iׯßâìÙ üÞÌŸ¿uu5IN¯Ø¾}÷;—·ÿž>õ-²ö]¿~‹3gÎôï@‘N`mmSàqµëÔãòÅóÔªSO%½_Ï®¼z¥ ibjÊÏ —`ieMïnøçîär×ýÁ×Í[æëP[92 gÞìéüs7+æ×‚%Ëq)S–}ºÓªÍ7¬\¶‡’%™:sfææœ8v„%‹~ÉPÚNhi‰)QÁ§Mll<¥J9ä™ñâ,,Ì¥°;…%<<‚éÓçѳggNŸVí,»wÀœ9S°µUö'NœböìL˜0:ß2ׯßJ•*•ñôÌ—ÏÏïññÊÈ92™Œ2eJðüùKìím !,,===lmmHMMåÉ“§üý÷iŒ ‰ÃÒÒB%$‘Ï3Éâ¶T©’hh(ã¥>}ê+ùQVWWÇÉÉQ¥®€€WDEEaddˆ••%III„…EššJt´Òª¸D ôõõò½Þ³g/²mÛRääädÉ/l||<~~/¤cMMM177ͼ&4ôµ”goo'ù‹MOOçáÃÇ9ä”––ÆãÇYƒ”,9¥øJºWAAÁåÚæLäGrr²ŠB622ÄÔÔúÓP„i©©È áP[]C#Wsî5²"@û=óeÆ”‰ü¶j-ë6ï`ãºßÑÖÖ¦Cç®…jËö­›¨ûEæÌ_$¥y6mÄÁ㧈çÁý{<~R9]põ2Ë–,dÊŒ9,Y4ŸƒÇO)_‚§ÞôíÙ…–­ÛŠÞRðÉ"“‘oˆ›´´t)ëÛpû¶½zuÉÕ0<îØ*ýÎüZF¾ k׎ôïÿ=k×.ÃÁÁŽÕ«×sýúMÜÝ+¡¥¥ÉàÁ}%§×:ô$66®ÐŠpΜEܺu‡6mZÐ¥Köï?Ê©S¥ü3æóè‘7 …‚ôtX¾|”—}DnbbÌ/¿Ì²â¶hÑ •s8Êÿþw–Þ½³Ó¦ÍcÊ”s´mÔ¨ ÈårjÖ¬F·n ¼33S•ºÖ¬ÙÀµk7? E¨®®NJr2`a‹ÎBÇA·ž}°±U©/œ=ÉãGò˜r C!W``˜ Æ^ßõ§ñ×ͳ.ö-§vâââÉPÌ ¸Œ`eôïß‹U«Öãåu¯PçX[[IÁ‡›5ûªPÆ9U«V–”à›tëÖmm¥KMM¥~ý:Rž££vôèÑ™L†¯ïsœœÿUä‡Áƒ¿ãòåkœ:uŽ.]:äy\:5¸ÿ¡Q>óã!“† ëåzÞƒ2$kj:4ô5½{wS9æôéó9áâÅ+˜9såË—ÅÕµl¡®åâÅ+Lš4SúðŠ Æ}°gªH¡…¥•´E"?®_»Â×Í[ª¤U©VƒsgOKÃ~¯;ªÖae˹rîÌiV¯ø¨È¾jÚŒÊîU󬣂[%®]¹Äž];¤´Þ߀²ZZ¬^ñ›ôUyëæuZµýFô>Aâéù5‡£S§v\ºtÚµk¼ÕG÷СýTF……%s/7Μ¹cd˜›7¯–F„ùñ6Óžahh€‘QÁQ؃ƒC©Zµ2ƒ}—mtîI«VÍ P´£¥fRR2Æ©?{ö"5jTáèÑ9Fè{sûö]¬­­èÖ­“J;>|Âߟ¢Go10P~XLœ8Sª+22’AƒFÐç±È§FÍÌÍùÇëÜ*åšÿèáÊ”-—#½Cç.üïÄqâbchס/_<—òkÔªƒšº:þ/^P«v]*VvÏ·õê7@SS“WY_’{Gÿ8M­¬økÎÎ.tüVùå3lä.œ=£œB05¥Y OLLMEÏ%¼%‡ÿÅÚµ›ˆŒŒÂÏï~~/prrä矧3`@oÖ®ÝÌ7ßtÏè„ûòå— Þ¹®.]:°té*,X (xLœ8¦Pç~÷]w/^NDD$Õ«WÁݽb £/3fü,­iZX˜³bÅÂ÷"ÃñãGñÝwC%«]33S† @×®í%ùT¨àŠ››+2™Œ£GO0oÞb)¯sçvÖ5aÂ(©¸uãú†8—v)ÒrwnÛŒL&§Cç.ERÞ©¿OðàÁ½BEÃÞuuµ|=ËÅääOhC}`€?&¦f9<Èår¬mJÁ­×rå-ˆÇ¢©©Iý†…:þÊåKØÚÙ¹",íR¶HÝÃÙÚÛ£®!FÈ@ðIŒ“IKKË¡³chdDzz:‘‘½1Š»NBB ôÚî^µ7¯_ãüÙÓhjj¢®®¥•¥œœ Õ¦kW.‘’¢ô X£VmiŠèê勤¦*¿>ôõõ©á'::ŠîÞ”n— ŒÐ70ÄÐЗ/ž“€áàŸûùaddĽ¼$¥_³¶2,Ëý¼°¶)ÁÃJV&&&”)§ônöú5¡!!9¼v¼ %%%™ÀÀâ3hºW©ŠV†\³Ë©|7BB‚qr.-žfA±$66–  J•*©’Ã;Êw¦Nš…š{þü%ÏŸgEe¯X±Bž®ÕÞ/¯û…Š:Q`sí&‰‰Y†IVV–8;—">>ÿ@œK™\‹ªÍ…ÅÇçÁÁ!ÔªU=gߟ”ÌիרZÕ]Ž[pp{£©©IõêU>}EŒ™¹EÇUr¯Êõ«—sŒî.]8GDx¸ò‡LÆ«W4káÉ…ógyøà>êjjîU«JîÛ½Sy\F„ì'Ò£O_vïÜΣ‡÷¥t™\FXØkê7ô`Õ²¥$e<È2¹ ™LηÝz`hhˆ¯ÏSΞ>É•K9pìR=Ö®&4$KK«ŒáÅ ?Úwü–‘ÃáñUR3Ëå4þºÕª×$$$˜SÿÅþ½råv–¯Ç³§O²cÛf*Vr'3¼÷­›×}Ù¹m3ë6ï‚_»z™#÷S¿¡gNýÍÁã§$Å|ê'pȈšüEƒFÔý¢mš7ÎQ—[ÅJô8PÆ1ìñm{Úwü…BNËVm(ï¦ íräà~®]¾Dµê5)S¶¦LçÒÅs9Ês,åĈ1?JŽz=›6bð°>°QcÇãXÊIJÿqâdÑ› ޙׯÃ)QÂ:ÏüÛ·ïbhhˆŽŽö[—=yòlíñõõSIŸ8q:-[~-Šܲe¿ÿ¾‘¾}{äY–¯¯2LŸ>AJkÔȳHaQall¬Ò¾Õ«•ÁƒÝÝ?~¿ËÍ›7¡yó&¹æíܹORÊyJŠ022ЧO}Ù¸q%~~Ï™:u®P„ùñäñ#¦ÿ4žˆ¥óß„„ø\ã¾ ®ÜòŒJß¾uól_¸é´ï¤4~q(éÈù³§xñü9öŽ…ª+¯øˆ …BR‚oCi—29¼Õg¦ßóº‹ÿË¿Ë"üärYŽˆÙIIIU…–={Ò¸q#ôõus(Â;wî1aBV¼@'§’ìß$ßò2ƒ½ž>}cc#*UªÀÉ“Yy‡ ûAЧ¦¦Æ‚3qs+‡‡''OÌ¡DÑ£Ç öíÛ¢Rvör”Óy¡ÌŸ¿„7nIi£G¥E‹¦ù¶1!!žÓ§³œ)DGÇH|^©´±C‡6ôíÛƒààfÍZÀÇ¥ófΜD:5ñòºÏ˜1“Hΰ¾/Q†iÓÆSªTI¢¢¢˜9s>'Ož ~ý:‘èeüúëJÎdsêлwWºwï\@ÛhÞ¼CÖ@ÂÅ™I“~ÀÖÖ†óç/1yòl||žñì™W¾å¼)ËLìY»vY±|ŠT™ïaæh/s”•ɯ fÆÜ_(騜CŸ3cŠÔÙ¿É­›×ÑÔÔµ|…ü_ÄÛùªÉ×¹zÎÿsÿiD˜û’Ž\8§ Ìkkç@·ž½‹Õ sv)ÃÝ;·¤m§SfÌ=¹ XÒ®gƈҫHÊ«\ÙˆˆHΜ¹¤³wïAúô鎽½-K—Î—Ž§}û>¼+s!9rÀ>}'§’ÌŸ?]JÛ°a[mŒOÈhŸ’ªU+ñå— xøð Ìž=™òåËf(žtìØ6メ!Ë—/Péž:u ¦³{÷&)dÓ•+×Y½z=sçN%**š:ujJ#â3æsóæ] ééé’òÏ,¯ E¨¥¥¥rÎGÙµk#G¦^½Úœõ•¦^³Ó³g¦N—g™aaáܺu—jÕÜ¥\-Zt”®/%%•¹s 6ì177ÃÜÜ CCåýÈŽ‹‹3ÚÚÚ8p4GÞ'¯ÕÕÕ)W¾~¾¾¼ $=cB†Ò»…£“s±ÞÜÛУ13§NÊšZŽiÜIËÖmÙºiééiÒÓ³u[ѳ Š—.]ãðáããåuI“fR¢„5ƒ}ÇÌ™?1wî"Ž9€““#ß}×=ßò2¬D³><¿úª7䨱¿9rä/åŒL¶­Ý»wÌvNz¡Úþúu;wî‘¶^´nÝü½È©V­ê:tœ7²”t׮ʵºnÝ:1oÞbÒ3æwíìJ0`€r¹&::†Í›wœœ"õU¥J•D.—qú4*rêׯöÒïë×oÑ´i;.]:!YvïÞI:G&“áëëGÕª•¸ÿ[·îÂ×÷“&ÍÄÓókjÖ¬öÉ<«ïÅXÆÐÐˆŠ•Ý {ýš”” krfææÅ^ ýãþ?w¥ß%lí°µ³/6íkÚ¬–VVÒt¯¦¦•«T½® ØQ²¤Íš©ZXgÙ Ú;wî)gGjW/Äl“}útãÅ‹¬%“Ì}t ~‰‰ ÑÑ1T¨PÿÀ ¥Ò‘ë×oKÊtðàQÖåêZ†îÝ;óêU°”V¥JÁ–ŸK—þœGÛm3Fu–jÆŒIP½zôõõxý:<›rT*™NÚâà`›mÏs–QÓÞ½[022ÀÏ磻$3×KûôéÆóçYr266V©»Fªœ?œòåË©Œ"/_¾(ü\\œ$gí––4kÖXºŸööv…ºn s~úé‡bÿ¬¾W«QSÓîåÕ××§fíâ=Œ¯ì.Ÿ èHMMååË€<óãââÞ©\kk+¬­­òÌ×ÓÓ£nÝšoU¦½½­ÔÙ¿IÅŠåßø WNùM˜0¦M¿àÆÛT®\8+n''Ç\§ó£B…Ü-ݵµµs”U¶lél»ä;b̯.[Û9òììl±³³Í³L##òW(äyÞSSã|ïU^×­©©AéÒNŸ·"Åci3tn”(aƒ¦¦ÆG{}sæLeáÂߤŽ9¿µ3ÁçI‘(´´Tü}n i ïÃÇ„¥¥––ŸìýÐÐPgܸ‘âÁ¼ÿ¡\!—šøØjêhhŠH±“E øü¡\®ÀÚ¡‚æÆïñtôŒ1·qÂø€$ÆG !r!@ ˆá{"&&š´ ³_™\†¾¾¸@ð“––.yQŠ+éé..ë{Q„ñññ„…½F]MMrý•ŽÒá­‘‘±ˆ–-ü‡¤¤¤“"!(Öhhè!—[“"¯599™°×¡˜˜š¢©©%yxHOO'!!ž'áPÒC£·s¾š””„LêêÅÓŒû‡‘ÃøçîmºõìC×½ÅS-(V_´ñŒþ‡ŠÐï™/Î¥]r½Hmm*VvçØ‘C|ݼå[•»}ËÆ·ŽGø_2ÑRþwâ8^wÄ6AqûÒV³0‚bOr²œ””´Rw‘*ÂȈŒ 1Òsv.ÍSïÇ89«*ÌŸgO'ìõkŒML¥€³sfLåòÅ󨩩qãÚUjÔ®C»ö ¬gÓú?¸ç•å.mÚìyhj*= OÿIIIØ;””‚O;šÔÔú«WàñecÝŸ§Þø<õæ©÷|Ÿz0pè÷Rب}Šï ͦM«™?ÉRWÕª•ÙµkC®yk×naøðT¬XžaÃ~àÅ‹—RôŠE‹VH± 5òü¼¡¥¥þþ/ ŒßwãÚªUWõd~ëæu:wéŽM ¥Çôaƒúbf–5ͪ¥¥MRR!ÁÁœ>õ7––VÔoè‘g÷íACS“6í:Hi#†€‘c¸|ñ<“¦Î’^ì.í[S¯AÃ#Ê7Ùºy=õê7 LY׌ÑcVH”ˆðp"#"ˆ‰‰!4$3s¥ïFS3s•6hhjbhh(z_A±A.—cnž÷’Æ?ÿ<½ {öDOO—NÚ²eËN•¼ ¦Ó£Ç·8pä­ÊŒ#88Dú= }HHˆQ^CCƒíÛ×bddH||-Zd½ƒÕª¹3uêxtt´9wîS¦Ì&553gKÇ;ö7/_púô9”3?¿þ:77W¢¢¢éßÿ{©ææf¬Y³}zô@óæMX½z=_~ـѣ‡¡®®Æöí»ùãMYýшÁ´lÙ”mÛþDKK‹õë·—¡üV©Î{÷2lXVˆ£ví<éß¿7ùOŸ6–{÷Êø±;v¬ÃÈÈ„„š7ï@tt 6¬Py¿Éĉc06ÎÝdݺeÝ;P¤ŠPM]u u‚ƒ^aa™{ø•ס!hkk£ó†Ûœù‹øqÔpBB”ñ¿¦ÎœËÅóg³¾¿íÊê¿ñãèá4hôe¾JÀ³M;~[¼€[³¼?6l`õºÍ êÛ“ÄDe¬­¥«þà/ePÌ/4`ÃÖ]”uuÅÜÜ‚ÐкtëÅ…sgX»f%3çÌÏm.Y„··r tÒcX¹v£ò+jã6õë%ç^¥ÃF޽¯à“§];¥Rº}Û+GÞìÙJC¸ޮ̣GOðüùKé÷üùYÁgW®\ÇÉ“ÊQI||<íÛ÷àðá]hkkIéû÷aõêõŒ1ˆ/¾¨ÍÉ“iÔÈS¥ž¨¨hV®\ËÛ°±±–F:§NdÔ¨ Ìšõ“VéÙ³çŒ1޵k—qýúmêÖ­%Õ·zõzöî=ˆ»{%Ο¿¬ÒŽzR·nMÂÂÂÙ±c/Çï–¬{3ëÊòå˪”7cÆ|Ο¿„‡Gý|ÏË;0!!víºsäÈ.´´”r3fññ Ò1ÉÉÉìÙs'O¼9~üDGÇH!™^¼ðçâÅ+‡°cǪUsëÐUŸœ"TŽ ­¹Ï‹§ÞO¨ä^I˜×¯^FWWŠ•«äzî¼…ªÃÿ²å\U~÷4”þƒ†º-CGŒÎ3oÅïr­kì„É*é­Ú(‡øçÏžàljSr-o”鹦kji±vÓvÑ+ E@ûö­U¦F³óÓOcsMOLLdĈ¬sž={NÓ¦_XWß¾=$%XøþÏ"ϩڳg/2hP–áÜÍ›YéGòÖ[\||ž1þ¯Y3m7î*¾ãüùKðññ”†L‘––Nxx$ IDEE+å%%%IJJ áá‘$&&}”ÏU‘+B…BAÙr剋‹åúÕËRPOuuuªÕ¨‰¶¶_l3 MôôõEO$|dôí;ŒI“”SˆéééìÞ}à½Õ•ššBDD$FF9—?*V,ψƒ¥ß#F –Ž ‹ --í­ ’ƛʌ3R2‹-ÏqL@À+ôõõ¤Èö‹¯ ti'Zµj&å´þ¨©©ÁÀ½yðà:´Q €œ¼xÇŽ= øñ:y/"êêê8}ù1Q£VmjÔª-z }‚4Z.QÂÿi€rîÜEéø””vîÜ˃9vìobbbiРîgñ¬Š ‚དྷ’B\\<ææf´kçI\\<::JµÄÄ$âââñðh )“‚ƒ—)SZ2ד¶v¼° IDATm[bgg›íc\ƒáÃ0aÂ6dب««³qãJ¢£c2Fp©ÄÅÅ3räââ⥩ÂjÕÜ%‚LÆŒ@¿~=Ù±c/ÑÑÊp[zzztîÜ z÷îʹs—2”]-j×VnéèÞ½.\É6zÌš–9rÑѱÄÅÅKmÎD)'åº_BBV›ÆÅÁƒGpp°cýú*–e2kÖ,¡jÕÊRZ‡m8xð(AAJCŸÉ“•[3²×•ù‘ðæ4gçÎí°µÍÝ€'S6Ÿµ"L'”äDñæhÒÓIKK÷âƒ+€¤ì±I'&&6_…ö.”/_N2¯“¦Mß~¶ÈÚÚkkË\óªUsWíØÔÒÈI]]¾}{äz^É’ö¹æ½¹‡ E‹&Òß:µÍWa—)S:Gz¹re(W®LžçõèÑ9×ô^½ºäšniižçue’[¾§g³7äj•!3µ|ËËT蹑]6Ÿ¯"LKÅïñÑb"Cˆ‰ ‚---®]»™w'¡¦†ºº˜<* Mš4zësÊ–u)¶^m>Šäé–Éä˜Û8 i~`^¿òA]ScK!ŒHrRÂGÕ^;ìÄ+ÆõÖç4nÜHîSQ„úFVBš˜°`?44µÅ½øÀ$ÆG !r!@ E(ÁgÊ{YOKK#99™W¯HNRšD+ lJØ¢¦¦öÑ…è>fÒÓ‘BŽ Å—O(B}zz:¡!Á$&&bcc+mMMM%Àÿ%ÉÉÉØÚÙtÞe‚^ò*0JîUÄó*ø¨HNN&22YBP¬ÑÐÐC.ÿ0ÖÉE>5ô*]=ììT‚H* ìì000äî[o]î¹3§¸ré»IO?âèáƒâi‚OŒ"U¿)))$$&`ewø3ssîßó">.mÕˆÕÏ|}$ïêêê”t,€¯ÏS®\º€¦¦&¦faa™ÿˆˆpB‚ƒÑÔÔÄÀÀ`œœKK¾üžz?‘¦‹´´´±³·Àÿå JØÚáÿòqqq˜˜šbjš{ˆšÌc‚⌺ººäÑE (®¤¦*HIIÿøaЫ@,- öÖ^­F-®]½œÃéæ ëxý:4c˜¬gë¶Ô«ßMëþàÊ勨©©áãó”:uëÑ¡s×|ëØ¾e'Ž¡L9WŒ  ACÚ|£ŒK¶fÅo$&)=€èèèЮ}GªV¯Éê¿Q²¤#>>O‰‰‰ÁÒÒ’ž}ú«”àϱÃñõõaúìŸÅ,(ÖÈd¼styà¿S„2àP„ÿ–ISgHû=óeþœÔ«ßÉ3f³qÝïhkk¨³Ó»ß@J²mËF-]gÓF’"œ» +|ɵ«—9t`U«×¤yËÖ,]ü —®ÀÂÂ’ŸgÏÀûÉ#d2åBî¼YÓxJ­:õø~ÔXñô ÁGN±ùL|@Ï.ðlêgSúöìòÞêzùâ9ßx~-Õ5æû!*ùe˺ba¡œzúý(jÕVz`ߺy=vötïõí:tÂÔÌL3j|TT´J䈢`úô |óg¥ò&ÉÉÉÄÄÄüGHË)!!øxÕcÂÃ#?oEhddŒ÷“ǘ™›ç{œ÷“Ç|ݼ¥JZßþƒùyötb3¼àW­¡úr4hô%kV.ãÐþ}8:9ÑoàBµÉ¾dIºtï©’6jìx†üŽÔŒ+*V"..¶På 6‚Ð`.œ?Ë‚y³˜¿ø7Ñ“ >j öö¶yæ?}ê[¨HæoräÈ_B¡M­Z5?~E`kgÏÕË—(íRCCió|ZZ‘øú>•¦³S¹JUfÏ_LZšò…Ó×7 ))+œCIGÆMšJRR"ššZù~Áôú®?r¹ ݌غk?5k×Å¥L9Ò3fõõ HɰV­Z½+UÎQ^­Úu©Z]y“ÌÌ-hݶ=_6½¨@õù꫆ܿÿ(—²zzzܾíõVe®_¿•Ó§ÏãëëG©R%™9S¡}Ö¬_hÔè F’¡üéܹÛ·¯¥S§Þ¬]» PÆÛkÑ¢}út'55•{÷æ¨ÃÅÅ™6mZ°pá2<<<©R¥=z|KÍšYJkæÌŸY¿~Eƈ9€aÃÆ²téÏôí;œõë³"ÅïØ±—={âêZ–›7ïdû¸x†¥¥y×Ûµk_æÎ&Yýzzv¦~}eÐÞQ£&°qãJéØåËçܹ‹ÔªUƒ]»öQ«ÖW9² €=røðNfÏ^@ƒu9r°¤ü:uêÍŽëèØ±—$§øøš7oOïÞOs.^¼‚]»öI¿_¾ôÏ&§IÒèÙß?aÃ~`éÒùœ9£ üâ…?VVøúú¡©©÷é(B---œ]\xüø!ººz(2¬ÕÒÒÓ‰‰‰ÆÑÑ #cãü÷ï?”¦3çFEÅ`jª|ßMMaÆŒIøúú‘˜˜ÄlÊQÇøñ#±²²dܸ‘Œ7’7nóÇ›(W® öÎèüçJeFGÇ«œQЉ‰•Ò•ý‰"G€ß·!**cc#ôô”þ‹ÍfïÞCÒH}Ë–Ò±—/_§nÝZRȬyó¦ImiÖì+INGŽüŃ2ä”")Î.'¥û‰§O} l㈃4è;éw£FžÒßû÷!2R9U‘#îå„ Ó™3gʧ55š‰‰‰)5kÕ!0À_Ú(W((_ÁMôà_!“É=z(¿ý¶}}=iÊÏÒÒ\eŠ·NüG::ÚüúëÜ\ó.\¸LLL,M›~IÕª•©Zµ2yJа8 ©©©r½ýúõÀÍÍ5×c‡ÍÚfiiñ†œj¼—ö-_þ;úúzR]ZZZøù=/–ÏÔ{Ý>amSB¼µÁgJHH(/_ðèÑ‚ƒC¹uë.::Ú”)SŸgDFFˆŽŽ·nÝÅÒқ…377cüø‘´mÛ£GÿÄÆÆ KK ”Ž1är9•*UÀÉ©$·nÝ”ë…?ý4“>}ºç[~ll÷ï?ÂÂ"kúÒÞ¾àþÌÞÞVª+sfoo‹––&ÚÚZ*í %%555|}ýxø0KN+–G¡PàäT’þ¹¦¦fÆèk< (—–*T(']/€••ææù[²[[[baažMN2*UrË!§ÄÄD&MšQ¨©Ñ¼xý: ''GI†¿ÿ¾ ssSIN«V­£}ûÖÌšõ eË–ÆÊêÃ9'a§Á{ááÃÇìÝ{ s6mÚ eÊ”æäɳܿÿ¹\Ï3||žñå— òU„vv%¨U+kô¢¥¥%YŒÒ%KVqñâU44Ô%E¸lÙÆÿ?{çÅõÅñïVúÒ¤HAŠbDcG#¨ÄØ1–Ÿ-v±÷{IŒ%F,Ñ{‹ˆ5Ø»bï 5Jé(mÙ¾¿?FV–j¡ÝÏ9{ÎÎkóæN¹sß¼wïÂÜ:Zسg ÒÒÞÙw??_dddb×®`&mÅ ÕÒ†ví|addȤ ðóS9Y¹r1/þƒÉkÖ¬Ú·W KöèÑiÏÛ»)23³ KÀårz?ƒ……9ví Æo¿Í‡ÃÁªUK1sæBˆÅ*ç»výÍLtY¼x.Ö¬ù;_Ÿ}P³¦J~M›6†­mAÅ=fÌp¬]û7nܸàñ¸Œ"\¿þüüó9mAJJZ‘rruuFv¶P-­gÏ®€¹s§ã·ßþ`ÚXµj îÞ}ÀÈéܹKèÚµZ´h‚ .£}û¶ÉÊÇ9<Ë«uSå¬#HLOÂÁŸqäH0¤Òœb+†„œ@xø Ô¬iƒÖ­[ÀѽÝùåLôË[ÐÕ7†™UmF9"ÎÉÄ?ÛÖ oàééo¿õ*´üÛ·‰HIÎB}/7(Ÿî[,c×®`4kÖuê¸Ïç9¹ìåËW¨]Û¹Ðü‹¯ Q£Ìw*‚øH¥lÈd ˆDïÕÒ @ (0g$?ž077,Ñ~"a”#J(‘žžbÜáVœþ*cÇ _˜.—ËÁá‹6¢êòIŠÐÄĉ =#ID>8-#!¡â¿ ºº:ÃÕÕ™NAа,èèhÁÌÌŒ¤Hˆû$×dATpEhll6›E$ˆ"033-ÖùA•Tæy7 ‚ ˆÊ }'‚ È"$¢ê"‘H!‘¼'A--}°X壒È"$‚ ÊòœWF!ATq¸\.tt´ID…F¡àâ3‡y$Eø¹‰‰‰%!eB ¨¹äúÚ°Ù,U¢"!•²”‹5º;JHpða5¼šÐÑÑ™™ã?)ôJEEKK 5K\^,!11¡J^ffæàp¸HHx[¬Ì7þ¶\!A¤? ÚÚZ°·/Ü;º““ ÄâlÄÇ'ÂØØZZü*'\\j#++£Då¯\¹^¤Ì*3îîžÉràææ‚ÔÔTdd¤*3Gòj{ïü÷ßkœ9scÆ /tNNŽhÒ¤a±í<|†GÂ0p`_&mÒ¤™ \òÅú>pà(¸¸8aΜijéýûG\\àe2) Œ°±±Ctt$$1ƒ³²ðìÙó"‡Nß½KGýúu™P@¥!,ìÆŒ™¢ÑéxPÐAÌ»k×./Q[ïß§#**æ#åøä‹ÊfÇŽ¿4¦ïÞ½ ;w!>>±@^‡~èÐÁ7©T†‹¢Àûà§Ÿþ‡6mº|•kÈ×·K¡}ÑüRó¤BÝ•Z¦¦¦aâÄ™èÓ§ºuëX¢:·nÝEhè5°X,(·Ñ£GWÔªåXJëP†††044„X,„P˜I&s5';û=¬¬jæFEg!!!¾ò q¹ÅFŸJe¥V„7oÞÁéÓ°|ù"ìÛwø#E²b±#F *q{ŽŽö¸té*¢¢bàà`‡óçCѦM+&Ó¦ˆ  /4wîtÀ¶m»1xpœ:uׯ߆›› úö퉜–,Y <¸¶mû:}ÏD½?zôîܹOOôìÙ­D}LK{‡U«TÊsêÔq ˜¼;wîãèÑÎÍ{÷îŽ:uÜpóæ]àß#'G˜={J™^<ŠãüùP¸¸Ôb‚åæÉP-³ùõ×ß™²yr€ðð :Èäuìè‡&M¾Å“'áØ·ï0¢¢¢1ožÊòœ0a$é~Õª¿˜WFF†˜8p „±:ÝÝk£aÃú8|øX‰û¨««??ܺu7÷¥HELL,‚ƒ1ýóóóÁºu‘žž;wî¡W¯Aøö[/&oòäÙ%Ùòõí _ßÎ?~F‰úwñâ¼yÇlïÜù!ÞâäɳÔú'æàÀªx’ùó<‚ÈÈhXZšÃÏÏÆÆFLž®®.`ùòÕpt´gÒk×®…eËV1#y{öìgò"""qîÜÅÊmΘ1Q¹Ö’6fÍš‚ºuÝѦMW˜˜¡uë–xüø jÔ0Åøñ`³9˜ˆo¾©ƒ'OÂmÛ¶ÆàÁý™iÞ11±ðòj‰¿þZ‰Þ½»ØçêÕaÞ¼8t¨äæxvv6¤R)ŒVV–HHH, „5ahh„ºuë!## \.r¹Œžü„FTC¦,H¥Ò"c¨Uu¬¬T«ò¬´üxx¸•©ÍZµ OO°Xl1ÊÑÜÜ ææª¡x±X‚§OÙ} ̘1QõöÏæ !A5¤ijj oïf˜;÷7x{7ÃÞ½!ª^p §§‡ààC¥-Ò†·w³‘â…B²³…ðön–ï¶ùÆ·hÑ,´kçÃäÍ[üw½:uÜqáÂÑÏv¾ž>}®Ö¿üÿårc­ª–B¡ŽŽöðönCCCµò€êÛp÷î]àìüaÄ­S'U åš5-±bůLzxøK$'§TnE˜ÿ€Þ½{‰ÆŽ àСݘ6m.¦M›€gÏÂqæÌ´oßïÞ½CÏžþX´Hõæ3~üt$&&ÁÁÁŽ1£çΆzõêhÜg~ûk ‰˜èèh¸¹Qà[¢hÂÃÃ!•JaggGÂøŒ ð?øøt†½½¸\.êÖuÏ'ójÑÒóOªÉOóæ™gQ²gߟnT³ì“«Ô1~²"”Éd˜2e"#£™í’L\qs« OO",0&MSa%‹””¥R‰W¯"Àf³àà`6›œó*ò†ñoÞ¼ shkkUkyÈårH¥2H$ÈdrˆDb°Ù,ðù|H¥RÈåªO#R©"‘\.§Dëù|d2¸\·—‹¾}{2ß÷X,”êŸÏÓøl“HÄËU}×Òâ33#Åb ¤RÕg±XÂLŽS*•‹%LºT*Njś͂HôaYÕ—|väÿä$‰ÁçóÀf³Áår •Ê ‰±}û?®&ƒüý»uë’“SѶmk<{ö»wo\»vë×oVÛÇeêΜ¹KÀãq!•J˜ô¤¤d`,ó*¥,XŠ¡C0–Ûù󡨹3¨Øz Iˆ‹‹‡µµæui99"\¿~ n¨Y³l¡¾?~Šœ35ÛÀÀ|>))©¨QÃÑѱ°µµ.Õ™7þ ¨–4hð X,ôõõITc’“S–öR©Œ¬î;v6le¶ýýûÁÅÅ kÖ,ǯ¿®ÀíÛ÷rï£øë¯­èÕ˃ÿÝðÔ©ƒ˜5k–,™Ï¤-\8“'Ïf&¿hiññï¿{ ~S /¯z€Ó§UßnÐ×W…ÍÚ°a+Ž?Ãô}óæµÌójÔ¨IÌŒÑk×naûöõÌsmÈÕ ü˜1SñÃí0~|\]Ñ¡Ã÷ð÷ÿp|³gO©© ìím ,³hܸA±r(ªLpð!ìÞ½::Úð÷ï‡ßÿuëºcÁ‚™˜2e6–. ÄàÁýàîþaˆ:$$H­M›6Âüù3rGàÆ2yÞÞM1kÖµg^pð6&óæ5€õëWbèбxûVµ–ØÂ ۷ÿ¥±ï¶¶ÖàptÊíZeyµnªœu$‰éI8øS Ž †TšSâ®\¹ŽÐÐkÌ$>Ÿ‡/þÃŽÐ¥K9„‹¯à›oê"4ô*ÒÓ3о};ôî=íÛ·…X¬š¨¢§§‹#ÁÐP5Á :ºèo„„àÉ“p„…=…¶¶6\\j¡qã†èС]¾a”ÄÄÄ"4ô“vÿþ#œžŸ ¾)tŸŽŽöÅ.†wrrИ^ÚuƒyPóæ-‹-çãÓ¦Ê_4õêÕ£;À?ö(¡ÒTTèãðôô(ò{=Qu°±±Â¶mëI_B–ý/P­(øú¶@K&‚ H~ôôtÕÖÌTG$)”J]Õ‡«6Ñ R„€;÷@")zb›Í†‘‘ ²³³ ‹*Ý1š˜ïgT*• 33£Ò›l6ééE¯Eãr¹hÚ´1êÕ£¡G‚ EH|¤ä8ðð¨Uh~æàp‡ØØp8•o½bÓ¦ÞÈÊJ/4_¡PàáÃǰµµªtÇæîî ¥RŠôôt¤§g@(Ì.TaÖ­ë‰ê}‚ H~AärÄb1tu¿Îú‘H.—[ä¢ßœx<3¦T*! ‹œ¾ž_9r¹\899A$P"22ÉÉɰ´´¨„çG†ÌÌ÷EäËñòåK5ï • ±8ÚÚZàr`mmƒˆˆWP(…úÇ-/¤R22È1›æÌùÇÄÞ½‹´Oœ8‡™3'îÝ{ˆ˜˜8 Ôwï>((x.u!ª&Ь:H$9 ‘•%¬3ƒ9ö‰mGŸ©” E9iÂOV„K–¬Äðáƒ_£ÙÙBlßþÆŒŽgÏ^ Nw9¢ò=zøðQìÝ{íÛ·CHÈ &PEŸ¨_¿nܸ[[kµ¼óïÞC¸wï!³]ØÓôé°qãvµ´1c†}u!ž´oßF£oÙŠJId°lÙ*ÆõZ=zt…¯o+Dópqqˆƒ™í#3~?[·öFÇŽß3ycÇ׸oMñÄÒÓ3 “ÉajjüUxûö=<{ö£G/S}@Àç¼sç>j×v†ŽŽŽÆ°0DÅE,#..R©|>¿RYø¯^E9$%‘HàêêR¦cz÷î=ú÷ ¾QS„£FMF@À`&TÕ‹¯¸®ØÐkYYÙ˜1c>üü|ð×_[0tèOÅÞ+!!'K­]\jaüø$'§bÙ²@¬Xñ+3[üÒ¥+hÖ¬ÑWS„Ož<éSç1uê¸2·Qœ ƒ»»+tt´Õê$$$âÚµ[‹ÅˆOÄÁƒGÀãqÑ¥K‡í³X,ðx<˜››!55 ïß¿‡µµLLŒATl222!—ËñôéóÜP2•σŒB¡(6ú„ƒƒ}©áË—¯°aÃ6,^<†¨å999Àݽ6s/‡†^CÍš–E¶—””Œõë·`ìØpw¯ýûÿÅæÍ;™Q§³g/"%E…Ãá W/¦n\\<._¾@åo³eËæÅ¼ @ 0€¡a"AÊBa‚‚ôôôçÿ.\†¯o+ܸqQQ1pvvB£F ˜Ž;w>Œ|y{7ƒ­­5àêÕˆS³Äx<._¾†+WnàæÍ»°¶® SSøùùRRRqöìE¦NݺîL´—'Ož!,ì”8 ‹Å.4è¸>ÜÜjøÖób±..NÌ˼›[mÆßô±c§™™U@NYYÙ8zô$ÓN­ZŽðòjTya¯^þ8zôÒÒÞPÅ5JuaêëëcèÐ U]€õêy U«€ÁƒûáòåëL;R©Ê*jÞ¼1”J^½ŠÌw£ªÖe ööïÿYYªÅËË—/DT”º)?xp¿Ï¾f*'G„¬¬løú¶bN¢D"R©ÒÑä.N.—3ý<¸²²²Kdåq8˜šš"))R© ¯^E0Ue#==·nÝ-â¬De&,ì´µµ —Ë™‘ß’”büøŸ6òƒ®Yó7lm­áïß©Èöž={ pwW=¬{öìŸÎ=z(þý÷8"#£˜õº …k×þqã ‹±zõ_̧‡7î@"‘¢M›ïÊ|l+V¬A‹M¨&ÊíØ±öEtt,&ÂÑÑ&&Æ8{ö"”JÀÎÎÛ·ï ÓÆºu›0gÎ4èëë!'GÄ( øã?ñóÏ““#‚P˜‰D‚ÌÌ,èè|X3½|ùjµÏ)‡Ç›ÍÆG`e¥z±8p ¯^½.Áù# @4W[[ «W/+¶ÎÍ›wššÆ(Â-[vbòä±00pÆ®]{ñþ}3c955 Û·ïÁ A}¡P(ÔŽ÷ܹKJÙhÐÀ«r*Bèܹ}¡yvC)=¢E‹¦ÌEö1;ëþx¡yëÖÞŸ]Hßï[h^a>S­­­0p`Ÿ"ß8¿ý¶I‘ûU*•ps««¶@¿R 7pyhÓÆ¯È2l6»RNíçóµÐ¼¹7ø|~±ÇTn…_Vò%<|V¨¢Ü¶m7lm­Ñ­[Ç[àoÞ¼U{x«†VÿC½zuÕ¢h°Ù¬ÜsÅÃĉ£ÅraaÏиqCtíZðݺu]±1J‡À¼ÔGEÅ`Ñ¢e8°/ZµjŽ“'ÏbÅŠ_```€þÙøøxHMMS›x׳ç@ˆÅbèëë¡AƒoàîîÊäõï??ÿ< ßß&&&J¥1bZ®]»…ñãG2Û«WoÀÛ·ñ̨D^ùÔÔ4œ>}®XÙòx„S§>(çW¯^cÔ¨Qåv-~QE8yòºÛ ‚(Àš5`ggƒnÝ:•ª^÷î1þÏ̶OgÀ¡CGѯ_/Æ™ENNzôø >>­*¼,Μ¹€-šÀß_u,þ¹±Ð¡Ìˆˆ( áCG±f͇yŸ>=0|øÀ"F´`h¨¾nØÂB5«±uko̘1¯_GæZ<ìØñ—Z™ÿ³ø8­°ŠX,:ÑQ°ÙìJ‘¨®×)Êr²—hùATq¸\tuuHD…&ϳL¹(áª(ÐÈÈhºªˆÏBlìÈdrATå—Ūr iiïðÏ?ª,y9;vôƒ““e¢ÔlÙ² Ba¶mÛ^½üѬYc|÷] LHNNÅóç/Ѳe3µô ¶2¹--Í ÄÕÄ­[÷pûö=fûÇ»h ±Tyòä.^üàÊî‡ÚªÖ­ˆEzzê×÷,´Ì«WÈÉ©Å<|ø(IƒáWføðñ8tèì½ñã§cÏžý8w.„ÜC¥båÊu˜5kÄbUL¸£V-GìÞ½M›6ªrÇóRiÑ.ÖìímÕ".”†¡CÇÂÙÙQMþöÛpvvbÚLIIÅîÝûп¯BÛyú4§N…§g&mñâX·nE…—q\\Ÿ¯]^™™YHOÏPëû÷ßûBWW))©àñxàóùxùRÀ·n]&Ò|XØS(ªogºººLðÜׯ#ÕÎ[bbRîK? YYÙÈÊÊBvv6ÀÙÙ‰‰@òß Ué…É‰Íæ|–k+<ü%$Õ½ÄãñáááªÖ÷˜˜X¼{÷&&&°´´­^Š0''çÏ_*ò­!..7oÞÅ… GáãÓ™ â˜ÇÉ“gñâÅ+µ65…U«þ¢§;Qb 󈔕• ¥²j.Ê{èjB©T–é¸ÃÃ_`Ø°Ë ~c]³f9óÿß#&æ &LYæþß¿ÿOž<ƒB¡@RR2X,6ZµjŽnÝ:B*•aûö=LY]]ôèÑ vèÚµºvíˆÌÌL*¿™£GCjjvïFf¦Ê™´©© X,fÏžŠ³g/áÌ™óåzMàr¹h×Î~~¾¥êsžb +Wn€Ëå">>а¡ú÷ï…¸|ù£µ´´Ð©S{x{7ŰaãÕž‹7î@‹MÀáp°dÉJxyÕƒH$Ô¬i‰éÓ'àúõ[8rä$ó¢Çb±ÐªU tëÖ{÷Ä;÷s!éé¨S§dQ„B!BC¯á‡Ú©¥:t„yÉÈ/§ààCÌK@vv6ôõõÑ»÷ÿP«V­ê£ôïßû“ùš››© çv#óù|89ÙÓÓ(õŠø4Zµjxø0¬Ð2‡EBB"ÆŽñIûêØÑË—¯Æ²e дi#&B}·n¡¥ÅG`à¦lHÈ „†^ƒƒƒtuu1hP_f.ÁرS‘˜˜„'OÂaeU#GLÄÔ©ãÁÁ1sædÆ‹ŠŠÁ¢EËàçç‹aÃÆ1–kS¦Œ…¹yáAo[¶lŽÀÀ¿0dHLŸ>àãÓýû÷ÂæÍ;´…‰èpëÖ]>| ÞÞM™úóçÿ†yóf¨µill„)SÆ¡F ¦½éÓ'àĉ³èÒå4oÞ„ èÞ}ºuëˆM›>D—ÉdX°`I‰åŸ‘‘…;÷P„³gOeþGGÇ`Á‚¥ðóóÅÿþ÷#&bÛ¶u°±±Æ¦M;pÿþÃê¥5‹ŒŒLµ±æ¢hذ>6¬¯¦ð4ѨQtéÒžJD‰Ù³ç€Æt''‡2'# räÈIÄÅÅcÔ¨!àp>};›Íf¾ájkë`ÿþ€Gž`Ò¤™L¹””T 2€±”4M¨366B\Ü[Ü»÷±"µ´´˜üþýG0ú …>>­«V-e¬·lvù¨$R„Qåß´YÅz0!ˆò&o$)B‚ >;<—"jž<Ï2墄IüADu†,B‚ ¾(™™YˆODíÚê±æ.^¼Âø¼ ШQƒbÛŠˆˆBdd4³Ý°a}~Rÿ^¼x…ÄÄD´jÕ¢È)¡H¿¯%áÝ»÷x÷î½Zx©û÷¡AƒoÊÔžL&óg/˜HöŸ‹·oþÞÞMËìr,B‚ > ‰‰Éxû6¾ÈŸ¦(ó%eÖ¬Eذa‹ZÚ®]{qýú-ܼy7oÞÁ©SçpæÌ…"Û‰ŒŒÆ®]{™:7oÞÁªUŸf-::wï>,÷ó‰¿þÚòÉí<~ü;wîUK›2eN™ÛËÊÊÆüùK>ûñ&''ãæÍ;jŽÈÉ"ü.\†ÐЫÌvFF=Ý¢„¼ÿÖÖV…æß¿ÿFF†%Ž‘—‡\.ÇüùKP§Ž^¾|¥–wèÐQìÞ½ zzª6¯]»‰S§ÎÁÏÏ·… @=깟Ÿ?³/6›­½A&“1Î5ò?lÙl6“®P(кµ7Z·n©¶/…B¥P(äLÐ[Ç´/•J™t‹Å¬]΋ªða_p¹(•JÈå JÆ Î‹Ø‡jRSÁGrþ¾çßWY‘JeLDàƒ£l©T¦æ$]%e!V¢[c´ õ}.'wwW¸»»VˆußUBΟ?À f»F 'zºD a±XE†X’ËåP(JFíèÑSèСtuu (ÂÇÿaþß»÷‡Ê¿Ùž‰‰1àôéó055Á·ßzá̙Àyó~CǎߣyóÆTn{ôø ÇïGNŽþþý˜vjÕrÄôé`oo‹7îà—_–ãÅ‹ÿù˜)sà@®^½‰ää&úÆÈ‘CЭ[G<}ŽE‹–3ŽÊÌ›7uëºãèÑSX¿~3ÓŽ§§&O‹ôô L:NNŒ,:uúƒEP¯^]¬XQ·ÀKÈüùKåjiiY³¦fþ˜×¯#púôyf;‘3æáÙ³¹Ê˜ƒ… g¡aÃúðóógÀ±c§ñúu$Ø.\¸Œ‹¯`Ô¨¡°··-²#FLD||B>9MGݺ¹!®F#,ì)nݺ+R„AT=ºuëxø°ðO—/_ÃåË×±té‚bÛ«W¯222qõê Èdr(öììlæÿÊ•¿1ÿE"ºw€'ö3i'NœÁ7ßxj|±¹qã6ôêÕ­X%Û¶­ËgÑÇ`Á‚¥Ø¶m=,--pêÔA P!®UR„A” =Á… W0qâ¨ùV(hÒä[x{7EFF&ÂÃ_`Þ¼ÅØ¹óo¦Ldd4> SS„ïß§£{÷þÌvJJ*† Pìþ¾ÿ¾F%5kÖLŸ>iiïææfعsC±íyyÕc”`IY±âWôèñ3<êêê‚5k–[ÏÛ»~þy³}úôÆ¢›8q&¤@.W0ÃÓy\¸pæjiW¯Þ@ӦߢC?x{7-Qß%)ÍX„"‘®®.eºVêÔù¦Ð8Š …â“—‘"$â«s÷îìÛwË—/*qË—¯#4ô*æÏÿš4ù?ÿ¼Pí ©TŠ÷ïÓ™tÿþŒ•&“ɰhÑòOê{vv6vîü› ˜ƒ‘#'aëÖuŸ]N™™™8~|ãáÖ­»˜;wq‰,hM,\¸ ýúõDóæM—.]Åòå«™ü¤¤dhiiáùó—000PS¬FF† \‡ŒŒ Ô©ã®fŠÅœ? uëzÀÎÎ0fÌ,\8 ÎÎ*Ë98øN:W¦~K$bˆÅ™ó"#£ao_ µjY“"$¢bqõêM„„GRR ž> Ç´isacc FbÁ‚¥pvv´is™ò¾¾­ðÃí m¯V-G\ºtU­Î÷ß«&×´oß'Ož…—W=xx¸áÏ?71Vß!ý˜:l6IIÉÌ÷Æ'OžaÇŽ ¼~‰iÓæÂß¿£$ ãíÛüóÏ~f&-‡ÃA¯^ªI;={vU럎ŽúôéQfÆÄ¼Á¾}‡Õ&ìtèàWæöÚ·oƒcÇNãðác ¦ì† é5kþF·nþ·o߃¿'&? `0~ú©Ö­Û„[·îbôèaŒåøîÝ{tìØ 6¬B@À @]±yó59å‘–öK–¬Äýû°xñïhÓ¦5ºvõ/´ß±±ÑpqqFNN¶ZºP˜ƒœ‘Zô!R„ATj×®…Þ½»«¥å íZµDÍj€š5-ŠlÏÖÖ#F ÂÛ·ñLš››j¨±eËf077ƒ««j ž……9ó¿_¿^pwÄ<Œí!«†­­­Ð»ww¦Ÿvv*+§mÛÖ–Œlؘ«|ÛÀʪ&Äb1@K‹OOÕ»¡C ,ìSÇ̬ìím!‰Ô†*`éÒ04yÌÝ»w†££=Ó==½b‡W4ø..µ4öÝÛ»jÔ0EV–J¡¸ºº !!1WN=gg'4hP‘‘Ñpvv‚\.ÇŠ¿ä*vmL:11o |軩©1îܹ¨f%~,'WW¤¦¦1Ç‘_îff5б%HMM͵•j£\î§»$EHÕ™LÎ,MÐDþ‰¥ÁÜÜ ææfóœË6³ÛÊÊVV–óòßÇÿÙl6¾ýÖKccc#yycaí{zzhlOKKKc{ÚÚÚ&—äM¶)/¯z¥’‘~ )ßó^ò—Ï“SÞyáp8jÿ?îkÞðg<Oãq,§¼}iiñ ”Ï·ê¤ …r¹rù‡‚<.ÐR„A”š5L˜˜Th¾½½-´´ø$(¢\IKK…@ ‹Å‚R©Äëב°µµþ,mÓ‚z‚¨æe¹DE"!!æËàr¹….ø¯–ŠÔDAØl8>X,.  „¨ô¨Lsö\.÷“'ÉT)EH„:5j˜ÁÞ¾´´T³‹úþB'hiiç^ËR8;»ªM4ÒÕ¥Y£AäƒÏç£]»ï ¯ÏƒHôžBT4t¶më°XÅň(û0))B‚¨b°X,èééB¡“0ˆJÏËOùÅöAa˜­àú7IDAT‚ ˆj )B‚ ¢ZCC£QÅËåxþü?QéÐÒâ—ÙÙ)B‚ $)Μ9KKÍXÌÍ- §§‡””dXXÔ¬öòJIIÂû÷4©èKÃãqao¤„B×z»»»“EXVÞ½{œœf;/4ATW´µµÕ|wr¹\p¹\8::!'' ×®ÝFýúßÀÒÒBafµ•S||"rr„Åú9%>‡µ§ 77W˜š@GG€×¯_B¡P¨=¯]]ÝH–•Ý»ƒqëÖ]f[(ÒUGPù422†‘‘£ô22T¯ård²ê»ÈP$æ.Ò&¾ …, "Q&œœœ™™ ‘HŒwïÒʵ_UBŽ€qã>D:>uê<]qDµÇÌÌ`hh‘(‡BT(Äâðù\@GG™™Yå÷ÂH§ƒ ª!ôõõÀçóH ^!²Ù,DDD@ZN.h² ATA22ÒqëÖ­Ü5,XXSm¢b÷b±ZZZàñx¤ ‚ø|˜››A(ÌP˜ƒ´´488ØAGG‡CT’’’‘-DFF&ŒŒ !”[_HD†ÍfC__2™ Ixÿ>nnµ™™zb±˜‰V^‰Ät‘|Ed2Äb îÝ{+«šP*•022,÷~‘"$ˆ*ˆ––¶Æ5‚5kZ#11 N044Brr bbb«µ¬rgÕ_TÙpyÈÌÌFzz4hXè‹)B‚ >>Ÿ‡6mZÁÎÎ^c¾›› óßÚÚõë×!¡_ {{«bJ|ýuàå¢~e29öìÙ_ßθ}ûžÆ2R© ;vÁ×·3>|LWA”‡{{[°X úѯÒýªE˜œœŒãÇÏàÂ…£ðñ錋(óæMBC¯ZæÂ…Ëxý:Rcû"‘OŸ†cÓ¦ôT$>‰¶m[ÃÑÑžAU˜J;4ª¥¥===y,pþ|(Ο¥3L|ûöm'EH¤¿ ‰È΢V-Ç•oÑ¢ Z´h¢1ﯿ6cß¾í¥îCŸ>ðcÇ_àóK¿–¥G8p lhYëNš4 “'­­u©ëŽ1K—.„‰Ié' ôí; Û·—^NË–­‚¯ïwhÔÈ«Ôûœ;w1úöí w÷Ú¥®;yòlLœ8*wM]ÉÙ¾}=!rÉÈÈ„RI>|‰Š‹@ ‹Åª<ŠPWWöö6ذa+¾û®`öì_pî\(¢£Ã¨YÓ6l…¯o«Ò—‡š5-Ë`eòQ³¦ø|~©ëòùü2íóSêêêêÀÜܬLuµµµaiiSS“2Yã––ÐÒ*œôõõQ£†I™ú«§§‡5LËTWG§lrú›8{ö",-ÍID…„Ãá£Q£úàp*‘"44`äÈ!¸yó.ú÷ï9rüý;1ejÔ0Á°a?áÎûøé§>t¦ ¢ÑÖÖF‹MID…DKËbqeåQ„`gg ;;[f»Q£Ê8:ÚÕï3ÁÁÛÀãñËT÷ðáÝeÞoYë®Zµzzºeª»yóZè—©îÞ½[Ë4|eد¬ý-lrSIÐ××/s]º¸ ‚(Š>AAEXÕ ¡Ù~ħ3dȰÙ,Ä&::vv6ežñ÷9Ëåxû6¡L3°óˆ‹{‹÷ï3`ll++u÷vb±¯^EÀÆÆJãhLlìdddÁÔÔ––€ÔÔ4$$$1eìím ‰ŠŠƒƒ]Ld~ <½˜Umm­2Ó$JÆÃ‡aر#r¹œI;zôägÝGIÚ;p W®\ÿ¤ý\¿~ë×oƲe« äedd`÷î`DGôëúäÉ3l߄ݻƒ±mÛ?ˆŠŠAJJ*¶nÝÝ»ƒ™ßæÍ;!“É Ô?~ü4Μ¹@SuU„oÞ¼…¿?\»v«Ð2‘‘Ñð÷ï‡Û·ïÓÙ&Šy£Ç† [‹,ÿ~¸uë. ì3pùòu4oÞ\î‡Á©M›v~Ö}”¤½þÙ¾}{~Ò~zöì†iÓÆiÌ33«%Kæ£^½:¨—W=,Y2ÆÆFxöìâââ‘‘‘%Kæ3¿7î@*-¨·lÙ…!CúÓÅô Tê¡Ñ#& (h ÆŒ™WWgÔ¨aZ Ì˜1S´ÆÃÖ­ëÊ|§N‡¶¶Z·öf¬²;÷",ì)ºtQ-™ú÷ßÀf³…I“fB™;;ÞÉÉ3gN†¹y >|LÍùŸŸ/† éððX¸p™Z{¿©9íHOÏÀúõ›±té&íþýGX°`)³]¯^Lž<&&Ƹté*V®\ÇäuïÞ}ûö,võÀ£ðêUfΜŒN¾/´Ü!ýÁf³Áb±àêªrŽž““ƒmÛþÁرÃÕfN …BlÙ² S§ŽS{‘ ª™"ÌÉÁÐP©T¥RYd‰DRh‚€•+C`àú^sÒJq=‰D"„†^Ã÷ß·)÷߯!•JáááV.}[¿~3Ž b¶{ôèŠ=º¢K—>jé0iÒLüûïæ;âåË×±k×^Lœ8 »w«•?sæÒÒÒаa}9¤±½<®\¹SSxx¸2i ,U+ÿøñSDDDÁÄÄ­[{3ŠÆŽ_ßVÅz-Ú±ã/lÛ¶R©T-}ëÖݸrå -DïÞþL‡ÃÉ-óœѲesµºOž„#==Í›7¡›·:+B‚ Š&;[ˆ½{jT„=P(,Eøûïk0mÚøRÕéÛwó?-íÚµó‡ÃAçÎ? OŸ¡L^Ÿ>=`cc]"Ù\½z£F -²\þáÌ«WobݺMù”Ñ3LŸ>¡Ìrpp°C¦011†­­•F95mÚ-[6+|#G¦‹¼º+B{{[ܹsÆÆFàr¹øûïm˜:u¢£ŸÀÄÄ`gg;wî£FÌAhâÅ‹ÿœœ‚´´w011ƦM;0yò,DE…1®èììlpçÎ}˜šš–ëõ¤¤dfÛÍÍ:::€çÏ_"'G07¯Á”‘Éd {àñ4ßúOŸ>‡¾¾ìímKÜ—””TÄÆÆÁÓÓ£À]DD$ ÜÜ>øˆýûïíððpÓøp×dµº¸ÔlÚ´FmfiÞpdóæÑ«×Kê?þ„­­5¼¼êÙÞàÁ£±sçßÐÖÖ*²ïÞ½‡\®€L&EPÐ~lÞ¼6W§aòäÙŸt}}[áÕ«XYÕT³ì„ÂlÛ¶M›6‚·wA9õï?ë×ÿACó¤åËbÅŠµ=zŒàééQ£†ª£/Y2«Vý…)SƔ٠Q=xüø)jÕrDllLLŒQ·®{ëiéÒù \I“FC__¯Üúúôi¸Ú$1ss3Œ3 —/_GhèUÈdr5eAAðê•*t›ÍÆ›7q”Ñ€#ЬY#¬[÷G‰ûräÈIL:/_Þ+ð~þü%ˆ‰‰Ehè @RR2ÒÓÓáãã]h{Íš5ÂÚµP9apq©ÿÎØºu7òô 5üý;A¡PàÀ5…Àçó`föá sçöL{99"LŸ>W®\GãÆ 4*ÁöíÛ2åÕÒŸ–pq©kk+lݺ+7]Œ·o˜rgÏ^Äõë·ðôés¬]û7îÏ\#[¶ìBhè5èèhC(¢_¿^žœ}ž„LEHDÅ¥aÃopûö]üøã€·w3èêª&Ê Ü+V¬EJJ* cÇkÖ&OÃÔÑÓÓ…³³S¶ÿüs#š5k¤q–)A",#999ÈÌL›MkøˆªKZÚ»¯¶/SSÌœ9 …*b<‡ÃÁ¸qTߢ֭[Á¬qär¹8Pµ˜¼uko´h¡ú†Îb±Àfº}ûB¹úü$ˆ*§e2BC/âåË$i‚øŒp8µÉùuÚÇKò—ãñŠö€BJR„Ÿ™V­ZC 0D:ž$i¢ZÚ~U‚ÅbCKK@'˜¨°ÙŸ¦Ê¾˜"lÙ²8>h”…¨n(²*wL?üÐbq\‚,ÂÒ “‰ “‰HÂQ%,Bz£%ª°EI" ‚ È"$¢Ü°²²€•• ) ƒ È"$‚ R„AAŠ ‚ HA)B‚ ‚ EHA_„Ë'ÞÄÆ#*:‚$CAT9’’’‹W„5Ì, ­­OÒ"‚ ªJå“â¡¶6­³'‚ ªZZ¿Ò7B‚ ¢ZCŠ ‚ EHA¤ ‚ ‚!AA"$‚ R„AAŠ ‚ ª8e^9±XL,¦¦&04 ‚ *³"¼ÿœI‚¥5ÁÙ\2Ä ‚ ª‚"d³ÙpwwÀ‹Å"I–¥R‡‹ ™LT¡ú&—Ë镇SA{F÷bÉïE%eÅ<‹,:%}¦–«"̃ÇÕ_K›N[1$&&ƒÇW@G‡_!ûŸ}}r¶^ ‰ps«]14›mm.,šÌÌ,de¥Ã@ ]!ûÇã€Ïãщ*†ØØ·04âƒÍþô þ³x׿r`³•tfŠàåÏ`kkÝ Ù?>ŸGG{:QÅðøñ“ «UÖª®‚NT¤¦% >>žžn¶<žœŒÂbxøðZx >ÿÓ úXEATkHA¤ ‚ ‚áW&;[ˆ –Â×·3ó{ðàñ'·›œœ‚Ñ£§ -íÝrD©TÂã‰ÚùýóÏ_tíijj¤R ?}ûSÛ>vì4öìÙÿUöµ}ûœ9sÙž3çWŒ9‰NJ9#•J1pà(µ´eËVáñã'ÅÖ6lš4iƒ;÷’"ü„„‡µuM\¸p”ùå¿iÊÂóç/±|ùŒ€•+×!&æ ]õ別¥¹ÚùMHH½{¿ØþfÏ^„ÈÈ(|>¢¢¢qéÒÕ|/ ÙÈÌÌú"ûŠOTÛÎÈÈ€P(d¶ýu6l¤“R^RÔÏUZÚ;ˆÅ’bënÞ¼Ó§O@FFf•’ ·"ufÆŒ‰Ìÿ)Sæ %%`aa†åËY7.î-ví ÆØ±Ãaoo‹~ýzaÍš¿±hÑL\¹rææfðòªÇ”_º4?ÿ¬z;>|<$)ÀÅ¥æÌ™Z Ìóç/ñüùèÖ­#ÝIŸýûÿűc§™íùógÀÉÉ!÷ÿDEÅôôt°~ýJ@VV6ÆŒ™ÊÔiܸ!ÆŒ†ôô Œ?7oÞAbb  Òß}ׂ îÞ½¹\Ž6m¾S˹qã6lØÊl:­Z5ÇÕ«7(áíÝLãýRôÆ®]Á0 7bcã””‚nÝ:NŸ>={ÀÁÁ ÎT«÷Çâñã§Ìö–-kÁår±|ùjL:l6»À=øìÙ ,[¶Š©Ó£GWtîÜaaÏ‹ví|0|øÀ‚?ÓŒèR°wïAœ¼‹¯€·wS :  1oÞb,Z4C†ŒÁŠ¿2u.^¼Œ]»‚Ñ·oüòËlÌœ¹ÃÿßÞ½ÇDuåqÿÞ††òPTª@©¥ÑÖW°YiuUì¤n«h PÝu\¥`Ç"BA,º‹¤`ŠFÓ–Jb²mD¥Á"¬Pá ÃìèÑÛZÑtü}î™{fNιçþæžsõ˜6ÍÖÖ2j&&&øàƒ(¨Õi033eéÍÍ-ÈÎÎåµAbâ~¸º:£¾þ:t:ü Ñ´ÃÖVÎë ¿ÇßßG°nÝ{ÐhÚÑÕÕ gç)OŒþ˜5ËѼ<Gàääˆðð,mÍš(äçç ¸¸[¶üM;Äb1ëƒaaK¯BJJ"Ë“™yv˜3çäå 9ùrs6mÚŽ“'ÓÁð„òòË ]ζëë¯cåÊ0œ;W†[·yÇÅXêïĉBttt²|ÅÅ¥8q¢«Vý‰áX]¹Rƒ¬¬\üøc9*+ÿƒ¶¶6(•¶¬ ŽiίºúdgcÛ7oÞâ½^UUƒ¼¼ÞÉÎ+c+«ÔÕý×€W™X¼¼++¯`hèñkCÃm¨TÉ8räà˜>G&³‚¥¥%nܸ…~¸€À@?öšTj©ÔÇŸéììÂÕ«×xõ¿¶;x0ÁÁlÕN‡«Wkye¯¨øK–,‚X,Æðð0>ýôïOáùtüН¯7¾ýöä£q;Yß,/¿ k^Ôßö2ìÝ»“m‹Åbtw÷L˜ú0ˆ»Fü•• ¹\þ\ï# !›°¿±´ää,Ï‹x8“ðmÝú®]«GQÑY–fllÄk«„„­€ðð˜9Ó¥kµÃøüóô‘A>¼<¯½ˆ7ß\@ü í ?Ñ_¼úŒ‰Ù…ÂvÜïïà`;;%.^¬@^ÞØ¯D"c^9âãcõŸ¸ü²¯^½3f¸=ußØØ¨ñŸ±±ñSûædö»"´°âþ} jkëXšÝÈ‚R©@CÃ6y{÷î=ÞÕÃïqwŸŽ5kÞeÛ§Ø7ÕŽŽN|óÍ¿áíí‰ÂÂSpt´ÔÖÖañâ…ì‘’’E‹Br¹5+ßæÍq [B½d8ŽCtô_°{÷>8:ÚÃÌÌ žž¯ÂÏoÛçÑDFÆLŸ>½ÖÓÓ‹¬¬\€«« /Tj{{;¶­P(pûö]À±cùˆ‰ÙÀÚ™Œ|KD{{„B#Ì™3‹WŸJ¥ææXXHÑÔtÉÉ)X¸prsO°¾©••%ºººàà`ÇK×hÚÑÒÒŠ¾¾>ÔÖÖÁÑщÖÖ2899ÂÇÇ‹íû( M™â€³g‹aii‰‚‚"„††ÀÆÆÇaölw^Ùår$ <=çðêöÑtÓÈ([îÜiBKK+êë¯ÃÍmêÃöÕ`Û¶ˆŒŒxØo{ “YQ ÔgÙ²·qüx>Ôê4––ššHLüââv±áP[[9vïNÐ{iÀK{ë­PˆD"¼ÿþŸ‘žžµú‹ÅHK;Œìì‘ážÃ‡à÷²ÛîÏDMM-`ïÞØ·/ VïAYÙyê)cX¾üm¶ebb__oÈdVps›Š––V^Ûoßþ1\]³{ö|†‚‚"€©©)ÒÒö23S°eËã¹ /DE­gÛ»vÅaÇŽ=hnnÁÚµïQxmnnSÑÛÛ…BŽÈÈ^¬[· AAþxçeøòËA¥J€5rrþ‰ôôÏÆôyk×¾‹C‡r™™ÂK¿té'|õÕ×ðòò€Z†£àá1‘‘HMÍä•ãàÁ}02"''ju6oÞø°>þ_¥Jàå [†Þýý}ŸëÊv²„Xºt/Íßß¶¶røù9£µõ>¯nããcáääÈÍÍc_6¿ø"›M3Éd2„‡¯`ùæÏ÷áÍûüÙÊ{A€.îÔ~ÜëhFaÄ~œ:•ÁÁ>½ÏœùK—.‚±‘fѤ\kT¥JÂ'Ÿl|ÿýy”•ÇÎÛÇõ^%%çáää¥ÒÎ }¢¹¹îî3è,¡GQÑ„„æÝ¨B‰9­5ªÇµk× z­Q‘È3Á„Zkô7–£´ôôú™' ÏŽk­ÑË—Ftô&l*ÝËu5ÈÞoXOš vgÕ¬Yî£ÞµJ!/«'‡O'" „£xýõ ””œ¦Š „Q=š>¡ËOkBy©½+ÂvM´ÃƒT›£èëí7èò ii}Ö16ì¹ðîî öRC¢³Ãð—k½ßÆù O700ðÂÞë¹á°n••ÕèîÑÃT,6ز TTTR#éñhµ#C¤Ó ãúÜn¤5võqêl¸_¶´(/ÿ Ú!Z@~4R©BÁ‹Yü乡V;Ϲ¯P«Lø¼bÌÏŠ=ê†àâbzld"ÒöÃßß›*â4î@hii ªÁgÄqœÁ=:A!Ç!88tR B™Ðè®QB! !„ „„BBB!„!!„BB¡@H!„P $„B&¯ß;ØÍ,ü ¥-,q…Õð Ö¢ QÏ#ÙÝYô)ÀÀkîÏÕt²pfm¬êhü‹RÊ8!Rø¼– ï=JfÓÕAØ83{åiÔ%[» žO½f±Ê-|f²°03UJ~e×Ýå&êy$›;vߊVè+¿;t`Ðì±F²´3½¨[ŠÙ$¸ó/IÍý£$,´"fÑ=.˜TMjµÆfÑ—ét!£±ÇÛ@@ϧ^óèg¨XØ èž«xTŠ}ΊkÛ&*8’Í\¥'~èÀ ÑáUWzikt½ó/Iísß­®l wmÜÇäÄ’ò˜˜ XzIýbŒ‰lR{z½,[HØtت¥­ÙyÞq…U{m±¶jJÊË‘¬îK¯ =ñï„°üÝ ‡…¹ÄÒ¶Þ.¸¤fjÔ$ýGøØ|ôùÉé¡û½0 ñ˜ŽAY ר²u×ô|î5ƈåjMWl¶­X×n“¿Ôø1+¬m¾ˆ^ó’j:ÉÈé <ño„ÐÔ£n„ˆƒÛaØ–ÈÑ›$µ›W_ôÑ7v#µkµ)M%©#ÉÕ!l\õ|î5¸“Úä`V d©-¬V}é5èÿ”«)ÿ,þš/€T«;‘¼d³4ðÄ﨩ßóVô¡ YCäèM”ZÄõ:÷1¬íþË_–zú'šÝ–’çú•úÖ1Øó¹×ãn:·ðÅÅžGg …µÑj`-lø¾8rhÝëy~þšEçc5• ,H*ïÎF¶Lß¾Xý¡ƒ4®i=@\éåLq[9}¤–þçÒÇðÍì ³· þÃtXLÅURÇ{3ñOÒ/Àž½!55”ú¢•mwJDÓ€»æÞäÚl!5Z È® ú$>cùÜ£ñŽÜ§P*¹“*‰Ï™¾ <¹#t¦³pZTÃÄÁ]JltÿS9ú¥–š[í®Œ—KK÷AäË™Þa`o!_o/Ïä:rÞsWÞD.owý›‘Sîyï•z%œ;†í³WfáÊÀzaÃ.,ÄF«±gÑÍð‹‘A›P¨„Ty_JåÝYɃÑ4-½/žÜ¿:(U Õp@ j¨ yUäè_”Ú‚' †§z4ÜØ:±‘—§ƒiÑ€ÏV·^->ÇRcmÃ{ Q5[HxsŸ´—T]G&Uaq¶‰~%Õr$/Z0}xrÿNè My3@‘â¿HCäè_í1¯±Yì·à4Ò«‰Ù]¯z`çË¥n€ðó»òF¢cÕKÏ‘Ik [1b.¤ÊÜq3ÝÈ8D߯Pu¿:ò ä®Èmyõ1€V2Ö}ÃåÜù¥.Çg7ͺµ ¿M8†Qj¸i!od{n7LeÞèǬaŽ“æ T¹;̸Uôm ÷Ÿ†îY8‘{ä•?öhÍïCwœ8¾Ë R˜§,Ç#5Q/ݹˆAËýßî±ÿ‡»ì¹_䕊ü¼<ñ—ÍÕ¬ísC|ü›|üD1£wÜ:ÎÆ!2ŒŒß>™¶fs›k[ï´}¶r=-À%B›{2mÃM¬âl^s¿Ý\D 0¿G÷¯,R.æ†ô£˜?Îv^°UN“kùáSÚhæ×aíòMŸÝ÷œ¹Ù$Z€™uØß`²7hÃE’¡V¯€ùCmÿ÷Úhf¶+z6ÕkiÔõ¶råÀýx<6K%ÑÜ1æ†a1 »«‰m7Qùßoç¼¾Ù¹¦Êây¦l0ÿ¶ZX.éG{ÐøÓg\zI´ÉÑÅ`Ÿ©úÑ Ç-â2À`ŒGK)Äëš sœÓ?¯ãÑ»6'¶Ýny†ò"¹[çµÑÌgWÏ›­ŸØv»9á<¹E #AI´“K>o¶~bÛí† 5|ôCy‘ÏÌÉ I´\#|Xy¶r–h掫ˆ{äŠúøK¢¸¶Ï¶m^°UÚ¸¨5ýq%Z€ùCm¡j'ѶPÔÍÞ½-À- 4.ç·E•hk«U%ã&™8#&{¬¶íq[¹‰°lõE yÂÀäqv‰~¯½^áVŸ.­ñÄÝjÖ¶*[}QÇK´ïœ®•`_²¬ŸÞ¶[Byñ¿*jH¯Æ&Ñ Ñ€D •ô¨VŒup …Q±–ÔiWC¬&Vn±°`yëÉ¥r=ÓF 0–-ÿÈYxÞlÍCh q6·`@n…ñ¶$Z€Éåbœ“Ckm>„¶”—êa¼ÂÙV-ÊŸÒ&74p¢½aJ]H€¶Ñbˆt±ùP\m´‚)pSßv$8(ÅHvù-äïç…¥àÚ8ûyÆlÛ§…Õl½ò‰»a÷Ù\QŸWUŸ€ ÐI´½$%ÇRXR ´aGÛdQ'ïu .û€ÎÏõ¿7ëG pÓ(gÊdßÖB‡×úM$'&ûËF®í¨-•+š'€æáu‰~î_ý¦¿êÛZßáu¥¼`apÙ¯Ö#ÑŽº/|¥<쾉?n7·Î}Ð뀱I´iD$Z©—“jÞ-H´Ü˜&R@¢Yh¥4‰$ÚIhFý±®T Ñ‚‹@¢•N$Z„o‰$Zh¢·À|„Ï$Z¹ ‰–éÒ¹¬ç9zT¢áçòz½Ô Ñn[Å&€_èu°Se‹¦¼~Iµíä‘èò2¼^¯!’î¾rÎâ]–€D{w桊$&-üš˜¥jh5Éu’íŽÛèdQUò‰V\¸ø] dÃí >2àÐCŠƒ íe*o“ò-ý!l‘háë gˆ£·èd\~tÒŒD;íÙz”’ß0˜ýA«OØññũώ»ëªU%7ü}îíH_Eï²ÈMÎßÊ@µ×í‡e/’hq´bæ}ãÏÈ7^Þl6ßþ/ý/žŒãk"Ñöf蟶›”üè¶êC«×¡äœº:ôÁ!Â+cUN}![}úö™)wH«DÛéN¯0}Ú«iSÜã:Á_^Tu5ÐElÛ]$K´ŽãôZ¸¯½‘Ö•’ïòÍO]£<»“' Ý½¯ðîñ­ßT”Dk?ï›ìgg¸O©†þUt”þ”Ž'cUÔ]æ|^-¾ÜñÓÙ}•Òç`º¾8· ñ; ðŽVƒîÿÓßàØöxuùÇj€¹ÉíÑû¥Ÿ•{ÎC7<ÇoÑÚiGï0ñNëÐgoa÷å;î6v¶QíÉѪç½_óG?½]>ècÃa ìKëñÞ+[×:¬ö¶÷âLÓ¡óèƒ@Û¯³k§>w÷«µL´¿vo^¡7GÆË¿3w»Øøñ~ö¹á/3£´ý/7ÿ|ÿä.•Ÿë¾¥úߥúü&÷yä&!í®½>Ç_‹Kµ»=û—24ü -ge]í.Õ¾;Øz|5o'yþkxÓҵǫ¶Ä/Œåò¦ÉçuÂñêÌáü+ðÝw=VÆÙÊ|j\þ4¯†¯sSbû–ZÍ©fÊjb͔ݫª/ÕæÛ9¿T¹Ï½Õ[>®®î 5•pÂÎÐpooU{¿T{«¡þ`uù.ZSª“ßNßÁCßr»h·uÕ°fæÞEúâ\~ÆÙ½‹žá´òßEþVŠÊ¥ôY U¢]My^µaa€&ž=bÐ!†Ü@ͨvÕnåª]µ[¹š™f˜&Ï `lÿ%ÚšÛ·ãÛÖú¼é€ûxæâi}0Ý·´O´›‘4÷ßžGÅôƒúÚ@µ+¼jWr…WíJ®ÚÏÜœ~´ŒM¢@¢€ëš€±i£`lg<3lߨ^FàrC¹΃ÍÿåtŒDûŵþù û–€áâì·çÁæÿr:fŽþ¢†{ÿêcm—€áâl®u6wlþ/§c$Z qœvxª€VåýBL¡†ýÒF Ð,ÎÊ(-ÀÀÞqV¨hÆãv€‹ÃG7'lü‘ü©Îp!À q6¼üó:< …sV®dÉtÒ×–\*>À&7TÞçœ(k΃ÞåtŒD[{¸/Œ Ýj h€«Bmœ5W‰ö—×å?“¯“é¹0g.ýpεPáŠåœ',8#ш&Y¤0OMN-ÿ+dë#rMË.@ÏŒÞp”BsWÃ$]¹éÂ<ñÈùâ, ÑpFÆ="wºË ‘±Ðßh¨³jý±A´íÚ$ZJV÷c=÷x«³r±5×Ïuµ¶š2„«Ê&0X{CÀO‡Ñüx®ËÖX°ÉéKjüÚxD‚ÊM×,NwR$ZäãKŽÌ-0.½ø—8 Êè]·æ~2`Úhº ——¤L ´ÀÀÇO‡0†¦‰$Zhh@¢€‹íŽq©PNölg?ƒÚ†¯àrÙtGœ]–åõzi©àšD«y€ý×ëàÐ8»Ùp+LÃß;ß,î•hU8­ê¥À/ŒÞ€D £$ÚxÐÙÕàúí±èIœë™L!Ÿ×5ñ4 µâ,@ŸV-aö Ÿ-P9±r‹¹ãö¯UÙ’[ϕựró²=gÙä”w„{ÿÿi£¬™X¿Ñ‚Éxü¥7Ä?ô£˜ÜëõŠcègÊêiY•+·›[0×"57§D p÷Œ»òô‰ÜSØ1àÂ2ÔwcÈÍ©à¦Þ?ñO0H‘D p÷\{U¨mÒ@+ÑÂŒï e-Àí„ÍJ>”`sbåVÊkkÒ@»¸3 àù5|ñé>»zHVýÄûŒ‹ZµÔåƒ5ôp“Í?Shõéƒà&ô:@¢‰$ZîÈX“Ë 8ªõþW<%œ¹íÊÉmÕO i£˜?ÎÆ5þ÷=¶×òÿ´ö=î§°`r[õ%Z€{ùŒ,»Ê”¯¿Vs®f^ÍóÕv æ¶U91tA¯ô89ÎRÙƒ—?/¯Vàqèú<ÖkôP«×À]Ä?å—û×J´ô¢Ð;A¯‰à¾qv-Àäq6ùgø"ùõ¸~Éþ[S*OX¸]® '†cc…#Èæbn}soaÁä¶ê'®7tyô4ÃF~¦>ÐêÓÀMèu€D -PàA$ ÑJ'Ó2ÖÀ]Ä7 ¯¦„ínå9+7—[[<[üô²dÁ’ëÑF p—8»ú39TíëõZ…ËxÎúÍÅkÛŒ³É,ÅöJ´p£ƒ||‚ãjâêEnÎÊMÄk[§V+Ï-ò›6¹‰`~RþU‘Êm4-Ô~[æØ"Np]lÕ¥!ùÀÛOƒ\–hæ×aíu™ “ëòÿÇð–ûãJ´3ëö¡è…>»¹ëG ´¿¶`”ƒö§ásˆø·)\¢˜Ù+°lu?Hvcý%˜Æk‹'®þ›Œ³å8î ´¿¨R 0Ð);ìÒÞ§vc]ÍY™¤“k+ü7·þpæäÖ%Z€»HŽüš›¡<ñÛÍÅ £á~[† ­6<º ÑÆÏö1°›;Ãhþt;ú 4çÎ0€»Û;âÇÌæ&ÆËÖo.·¶Õ •¥ò„€»ÇÙÕëÕ£e“—à±´;6WxzíêÉ·›¥Zò÷_I´ý¶ÀÄr¡MNÜד­0PW8½¦Kq/‰ÁnqæÍ F{á­5y ¦l­L†€›ÿsœ=ǧ#A²wo®—‚D µ7•{|×û³W’V]fÃŒ»|óP1‰Vž&ÏåVØ CmœS_}õ.ŒÞ0¨­¸¦ðÍ2k£ín?Sx ¡W`‰~Ù_R£zµ:¿—7±ü|®Ï”8Înm´ÀÆ•1SÆÜ0Ô~Ân<1¦•çˆÜÚ’3Ľisá8I¢•Àp£ ›|½câ·›«)Ãî­ß®×ŸÈ}ø°˜Œ~´ &€D‹L¦¨€D û¸3Œ®õpï‘ûŸ˜ûÄ6ð¶šs÷ 1·`r[õCÚhîgsWƒg­Òm8×·[Ì-˜ÜVýD‰€cåꑳŸ×ñ“iw¬¿¼`n[•%Z€;†×ò”qéG 0œ-O=Ú>û©S íÅ7|Ä ´KÐ}vô“ȳ“ ä`Î<Ô‡SGÏcúÑf?{•€]€iΟa¦<ƒH´3{–Ô ¯aÆMNl¯¿-Àf©ÜöëGâ[`Ęû »ñÄ8PÖ‡ŸÂ‚õÈ•J¢y!»—êÏ0wM¾Þ1ñÛÍÅ@¯ºNZÊ0Y9à­¤(6Tj$Zè%Ù74Á€) ÑŠMØ€$Ú“s@rs²’1H´¢Æ¿üÐ,ªyh»8O2,—&ç¡# à@¢eÔ$ ÑÊ…¨ah™%ÄÌÂDLh\ Ñ€DË4°©h›Îxƒ"&H´ ­Œâý‚/­³ ä|Ô ÀXž3%§Êç…úXQ  —D»J“‚Ú z Áae¾Wu«Úk»]ª€D˞ؤ)tŽkà‰öéaÜ÷è¾";dn‘÷EW“UÀð‰\á@¢íè|yW9€ÎwQ;Ñ:›Þ™ À ‰¸—1H´¥Ó¤æÞóSEîö Ü=Ñ—·àÚ+¥»í“É÷»»|£$ZøZMWWÝaCh@¢Í´}H³ÖUúlrÞ,•~äH´¢êö¶ZÅÉãÎW>úúÈ^ùoxp ÑÎv6õ‡¾J‘@¢ ²À­®IîYí›+o;­d|M%×yU3§O‡ºN´Î\ëÐ6ÅÝ+×ÀìÈÀH‰VBêç?tŠ­«\óüL]±Ï¿í €f‰öñ×·gˆK5_ OÌÓç¶¡söÜŸé¸æËvûÞ‘§\œh?¹ð«¸³o©£cMŸ+ýì~tÍôyMÒ[©úÙE›|åw¿>œ[dß(c4H´«ÓCå¹jßR'œ&û,C?'ï¡?™Bü4»hÏo0^Õ¡+¯Ì¸ñ”Ýîžâúôì':4™²š˜;ÙTžÞ~/Õ'ìXUýiø÷R}UÎòl»ßrÛº:î 6ÜE{(Õ/Õ¾ûwÜ[~`ÇL.çΚ7˜\p÷[j’­ ë£Yx¸_ý{_ŸÅäRš”hŸWmXØ ‰.z zÍÐwÿ¨Õ®Ú­\µ«v+W3ÓÜÇlÑnFÒÜ{³sÐfô'™)¹Â«v%WxÕ®äªý4úÑ06‰‰®chƦ€±ñ̰}c{ €;È å^86ÿ—Ó1í_Ôúç/ì[ †‹³ßž›ÿËé˜ ü9ú‹îý«Œµ] †‹³¹ÖÙÜy°ù¿œŽ‘h€ÆqØá© Z”÷ 1…öhH-@³8+£H´{ÇY¡@¢Ûe.>Ýœ°9ðGò§:Ã…ƒÆÙð~ðÏëð€ÎY¹’%ÓI7^[r©ø›ÜPy[œs¢¬94z—Ó1míá¾0‚t« ® µqÖ\%Ú_^—ÿL¾N¦çœ¹ôÃ9×B…+–sž°àtŒD šld‘Â<59µü¯d­È5-»=3zÀQ Í] “tå¦ óÄ#狳€D À÷ˆÜé.7`DÆ:@@¢ ÎªôÇѶkh(YÝõx<Þã ¬ÌÊÅÖ\?×ÕÚjÊ®*7šÀ`ía?Fóã¹.[cÁ&§/©ñkã *7]³T8ÝIhh/92K´À¸ô:à_â,0(£wÜšûÉ€ h£è.\^’25Ð?ÂÚ?ã‡9íIEND®B`‚snd-16.1/pix/sceq35.png0000644000076400007640000000314511147553270012754 0ustar bilbil‰PNG  IHDRùL˜–ád3PLTEÿÿÿÀÀÀ€€€ÐÐÐ ```PPP   ààà@@@pppððð°°°000^Q(I pHYs  šœtIME×  ¬›Ü9ÅIDATxÚí› “£ †ù´ èÿÿµÐîqÝkkf¶íÈk"‚>"ô?šž¹B„0ôm&0¢ H鈅Xæ !&Íî*ûKãwDHW‡/#œÒ‘0ÕWöÅ!ƒ÷3±ú³ŸnwÙ~6Mð½˜!)jýTu{ËvÌoßjŘq眛)¾®l–r0ÿ4u/˾Î(†ig~lJ›½c6 Ê6¯sàü(ÊÝë²/ëj†˜]‘0ñؾëùͶ˚®et*ÈnºOÈž›êq” HÛ w¤(¦9}oÎÍÞMC/ÈnºOÈ ›¬ ‘Â*YZ\ˆj‹)w€«x^!<œd »‘fíu©ê‚¬×½$›ˆ+~¸6tزLVɬYÏÌÕ“ 0HM·`Y>$&¯Ø¤™Ö ©Î+º [Ó}Ôë'‡ÈY8“óÅ·a¥Ë±‰‰AJ“¤23Û€ 3¢3\pŸêSQ×ËÖt‡Ú8 âòàó8mµS¾Jª kSLa4I³|P7L`U­p£×µÈ%>DnKô-ò]ª_Õõ²b&FLh=ÿQ|0;C°Ã$\‹ç«äèvVq!H¹Ñ„MÌvhà1©œm—ó! žFÏ^Kõs]øY-ÊŒ{»¼3þqÌ…˜X 2; m\%gÉ„r¿Ú?»z(ó¯ëZG±èá-ùÝ^4ÎãEKdYœ‹ôœE^–ÌAMv:Àÿ N¸;ÓdÐä&7h›¬’z¦,r›N¨y{²Ïo[žN¤8}Pr¡Ï!Üç þq©g„`2Ê\`³†as,×ù*iΦd9¥Tº¤}ýÈühW±ú [Šœšn‡ëýä ºˆaªº k»DQlܧüâÒÄný}Ü ﬽Öé*)µ˜4g.ˆqÑœÚɔΞ‰5f8zˆ\<Ö­H§²¬k&9¸WQ›á@–ÌÌæ‰+ç7ë=µKuAa;0'ŒÌT(+ÕD¡zsÝ+KKH&–÷MF芊3\ɤiÔµÃUít‹²"|æþ×UVƒìÆ+»z·îx1$T(TÒ>Uª¸¨Ôí&ÍaúºÙí{/Öí×jäE• Ö¼‡2&K¹"ÕÒ}BöŶ9“*‹h4áK¨¸\Ö•7u¯Ë¾ÚÔR(TZ;‹Xy£§º—dáf;Ü—ªWü?Òí*ÛÓfº/TØÔS·³l×TWy¡¢§žºÝeûßžJ •ÿ_öwLç·<&ô5F³.Äò{"w»…™Tþ¢Èî$ìB¾'rØ•|aŸo»Ÿç Vè¶Ûn»í¶Ûn{¿-ËM~™]¦?p³v•¼í¶ÛÞrv»@~¢5È϶ù"SÊŽ;ƒ'ëäO%Ÿ‹»DB–PÈ* Yç*‹Mh“ŠÊÔ®J¦Êø±–n%²ôÈ®NBV¹Ê¤É@¦ÏÿëdÕÁ†Uø±2ä:u®26 ¨Höü¿ @6¬zQ‡}Çí˜Á= Y@!OIÈ:W›„ȳçÿ§d]ò ~LØG8ïÜ“ò”„´È"{5<î#G(åÏȪä)üÙG°#3¸'!(ä) i3£ £4ÙÙ eÒ½ÏÏË’gðcÂ>úùùÀ HÈ Ù&!mbz,n¯›Ä>OùÇ ï3ÀóƲäø1Ÿ'Ìàž„<¢m²ÍUF˜-"Þ ÿX á}  Ë’gðãæt¼ {fpOBQÈ6 é‘EîÕb“yöü¿ @º÷àycEò~ÜœNg÷ð Ìàž„, M2 ‹îÕ¤*Íp[Ó*éÞg€çUÉ6ü¨Îë½>$dY-iòéÞgÏ«’m}IÈTí¤ÉòIÉ÷°Kä'Ú5ò¶Ûn»í-í Q{;ôv¡ÿžÈoÒçù? ÿ¿-?eœð:ŒIEND®B`‚snd-16.1/pix/gain.png0000644000076400007640000003006411147553267012575 0ustar bilbil‰PNG  IHDR,î H­) pHYs:ÊduhtIMEÖ*x£Ç IDATxÚíg@TWÚÇÏt¦ÐgèHGš¨lѵ!b$j6šQlàMìïFÍÆØ"‰]Q11Q¢Y £Qƒ *«A¥—™a†az½÷ýpÍ,‹ˆ( >¿OwîœÛžóüï)÷œóò4y¨mˆÄ"›Ã´`"žOEUE/·^mOLE=Ñ?‘cò¦.~TÜÏ«ŸÌVV€VÈÿ3¸Óp‘Qô”r¡üúéëT„“7^x€W‘±-)àMƈŒ*LÕ¥HT¹BNýï‘£J¢jå\ƒ0¹PV€VÀ ˜V¡•ËZS ËŽE¡RˆíÿŠP%Q)ó”žîžÏ;ŒÇåÙ2mye<°2´‚§¿'GÉá‰[SŠÎJ‡Q±æ"Dyº{¢ d@†«¾Wí`p0ÀÊÀ›Lɵ’ÑÑ££ÇÏKð ëÁÀ·¸-+Å 5èïêíXv¦ŽjóÈ`À[>XgÔa8ö¼Ç 3àFœÊ ’È$°†ù 3è0Ôštz7p‘›×TfÀ z½¾éN*ØÔ­’ªÜÃÜ£øQMÿª-¬µt°äØsÀJfŽ?Ý߈Œ¦ŸÒ©Ð^øl²DHFä`F°ÿ¯Xë•õ"šlú:©-¬u qí;©¯è‰ˆÐ¤Qo´÷´G8R7ª­­BrÑÓúŒ%Ï,Ö%0H ?ºŸÖ ­ÑÕ((Šg<Ò=2mÝ/ò‰ñi“B\Óôà‚? ‚FÅ»^oB(ÿ×|UƒÊÁ×!x\ð…¯/Œû¿ql;öÁú óC ˜:ÀÞÓlõú¡(2L–Wž§‘kœ_í$-‹°¦²¦à^é'ÓFÉtQ@vÉå—¾J 5rMÝ£º¾“ú¾Hükåd5|áð{÷Äåba—`ĕŕՅÕÎAί|’Dˆ!Lᨀ¢Ïðìs󇛹?åMZöŸ²‚óMÿ¥YÐlX© ÑâZ䉂=ƒÛsè˜1Sß¼–zíHò‘·¿íàëpf홀½ßê­SéÊo—7Ö6º‡»{ô÷@Ù¹Û±lX`13¤ÑÐXpá¿ïMÃI$Žpa÷€D&ÅÌ1ýœø¯‰!ÿáþ¡ûf;£gG#„¼yƒ¹Ì“¬æÙ%fÀš‹P$?*VãjBóçU߯Öt-žQZ-Õ;ë+ŸT‚q7¹H®nT·"½Z/­‘VÖ´œ3`<Ä<ˆb•T…"]—^¯“Öq#fÄ|˜½™:ŽaÏ;»µµMc£²xÃi]TA§+•ÊÿÅq\AÖ©õZ½Ö¨7^½z•Ê´`Êle ƹPN+# €ãx+—gZÛ@À …`ùœ:îþÝÊZ9&—TJ*ª*È`MèZ@„"! BxsyñÇz&Ó‚F£ƒ¥àÐëujµ¦½"$‘È ˜ð* /ÖN[‡­)•J½æÔ@[¡Ñ¨l6»cª£8ŽZÿˆßµètºŽ$%Íz^‚ŠŠª R||¼/N¦R©8ŽŸ={!#ã\\ÜØ1cF’H°~ÐÁ´].=¡žÙРݺugvöç%(,,:u*sÏž”øøØíÛ÷ Äq|Ïž½ÞpîÜïà1@ÒDxôè/³fMçpž[ôçäÜ4h BÈÛÛëÉ“2 Ã22ÎÅÆŽFÅÅ=}úWð  é S™’“!#( þ/ee~¸B«Õ"„bb]¹’ƒ*.~ìããE&“ããÇŸ<™‰úå—3ï¼3ü€êh»øòË­••Õ†%'/4(rÆŒi!ǵZ-ÑCåççciÉIN^âççýÑG H$ÒèÑoÿöÛÅää%ï¼3aÔ¨áà@BÊÓäÝÕÞ%拟OÈb± ºB¡l¶l0­@£Ñ8¶V«S©þ'Î’N§ûãn®i>aÞÉfõÌUUUB¡°éž .€+Ý©$¼ÿþW_}UVVÆf³:´qãFggg„Ð×_íì윒’‚Z¼xñ¶mÛ*++‡ 6kÖ,³zfÇñgBW)•J2™ “E€î!¢ӥ?ýô“i›Çã}ñÅæùÌîîŽM÷ :tÙ²et:=00ð½÷Þ³¶¶ÏÌZ„=€5kÖäæær¹\„PXXØÞ½{íííµZí;wV¯^-“ÉV­ZÅ`0z÷î .€;…'Ož¤§§9²éNƒ…Ú¸q£^¯×ëõ<F® ÂF(Þ»woÆŒ­¤Yµj†a•••B¡Ï绸¸Œ;vÈ!à1ˆ°øæ›o/^üÂdd2ÙÃÃÃÃÃ|÷믿>|ØÆÆæ«¯¾¿@„¯ÎÍ›7]]]ÝÜÜ^ê(—Ù³gðÁR©”Ïç[YY <ØÕÕ5&&|¾z½þÀ»wï~µÃi4ÇKKKkllÌÉÉ)**Ú¿TTÔ”)S`À "lûöí›={6…Biçy¬­­ÇŽ‹š3gÎõë×7mÚäèèèêê:uêTp)Dø\êêê*++.\ر§ŠŠŠˆˆxøðaUUŸÏ÷÷÷år¹...à^€ùŠP"‘|ùå—ĶN§{=ݹsg‡+€Á`„……………?¾¨¨(##C©TÊd²ØØØaÆ“æ(Bkkë+VÛ¯ÜB{)Ο?ß§OŸfcÇ;•J¥P(222<5xðàð6 Eºfy …âð$©³/‡aØ?þøÞ{ï½¶,ËÁÁ!111---44ôܹs|>?==Ý`0`n¼YmB½^¿yóæO?ý´«n`РAƒ BeddÌŸ?¿wïÞÎÎÎo¿ý¶‡‡øðFˆ°¶¶V£Ñ˜Ã(ÐØØØØØØâââêêêýû÷WTTÌŸ??88ØÊÊ DØ“Y³fM‹s>º ______¢Ãfß¾}.\ R©±±±aaaàŽ ÂHzzú”)SÌööæÏŸ___/‘HΜ9“’’ëîîÊb±À5A„=„ÌÌL³*Ÿ…Ëår¹Ü¥K—Æ;w§kµÚÍ›7·gDØõH$’íÛ·oÛ¶­Ýsll,BH¥Ra¶|ùrµZCÌ{z*=vºÚØØt»;g±Xg÷îÝ©©©$éË/¿äóùOž<‘ÉdÏ®Ê@Ih¾ìß¿ßÌ+¢/~A’Éññññññ¡uëÖ‰D"&“ÙúНˆ°ë1 ‡ž7o^Oz¨Ï>û !tëÖ-µZÍçó¹\î¼yó¼½½©T*81ˆÐ쨭­}òäIbbbÏ{´þýû#„bbbêëë¿ýö[•J…ãøúõëÁA„æÅæÍ›Ív¡·Ž‚ËåþóŸÿ¬©©Á0ŒÏç3™Ì©S§ZZZ*@„]ɵk×BCCß5 ‰ÙRiii*•*==].—ïÚµ«oß¾‹-Ͼ€úúzâËêЩLF£ñÀ©©©oZ.²X¬™3gâ8ŽaX^^Þ¬Y³FŽiii."|nmÊÔuyüøñ9§N§Û³gÏ’%K^ô ó„D"Q(”~ýúíß¿ÿ÷ßW(|>ßËË+99ÙÂÂV4v:—/_æñxÁÁÁ© eôèѡɓ'—––nݺ•Á`XYYõïßøðá`ag‘™™ùùçŸCŽ6ÃËËkóæÍ·oßæóù111Ç÷ööã€;’Ó§O2¤;Žy=X[[‡„„„„„Ìœ9óêÕ«ééé"‘(22rÚ´i`aPPPððáÃeË–Av¶…˜˜˜·ÞzK&“åææòùüÀÀÀàà`˜dÜUô„±£'OžŒ‹‹ë’`£Ýfoo?vìØ´´´¸¸8…B‘ššÊçóoܸa0À>P¾ùùù4- òòÕ "¶wïÞ‘‘áééÙ¿ÿððp0ˆðÅ4669rä“O>Œì,XP[[[RRrùò寿þ:>>><<ÜÉÉ b§‚ŸKffæÐ¡C9ddGáìììììLÄØ8yòä¡C‡Èd2‰DJJJrppû€›+J¥Ž3r±“ &RÕÖÖªTª-[¶QâBCCa’1ˆð)7nܘ;w.dák(B[¶lA¥¥¥]¸p¡¡¡aéÒ¥¾¾¾`œ7Z„·oßæñx½zõ‚,|ðù|Ng4¿úê«’’’#F°ÙìI“&µ?ƈðuƒa˜L&#¶_aɆ\ºtÉ4xÐét„К5kB/^T©TsçÎ¥Óé7n´´´5vJ¥ÒuëÖÛz½þe¿zõjtt4|ìrÞ~ûm„Є ÔjõªU«ÜÜÜ ÆìÙ³a¸n B;;;Ó:hû÷ï©cE"QIIIRRdžùÀd2·mÛVXX¨T*—/_®T*W®\I¥RýüüÀ8=­M(‹wïÞMÔ…s#00ýµǦM›0 klltss뤈t ®áÎ;ÞÞÞ05ÎüY¹r¥ÑhÕÕÕ|>êÔ©L&&RµHwjV]¾|¹ººzúôémÝ …âââ2`À€´´4™LV^^Îçó—/_–é®%¡Á`¸qãFBBäYw„˜35sæLâ‹¿M¿~ý<==‡ Æé6"‰Dð¸»ãàà––&•JoݺõèÑ£ÔÔÔèèèøøx"4kJJJ~úé§7‚÷ lllFމš3gεk×¾ùæ+++///s¡õ¦‹0''‡v ô<¢££ ðøñãÒÒRb’ñÈ‘#]]]A„fÄÅ‹»{`   1­qüøñ¿ÿþ{CCƒD"IHH æs€»©TºcÇŽ¯¾ú <õ P£F£Ñh4?ÿüóÙ³g äééÒSÙÜ?Q<|øÐÞÞþMnµ¿™XXXØØØÌ;wáÂ…Z­ö·ß~ãóù'NœP«Õ=o³. óòò®_¿þñǃS¾±¸ººš¾K:uêã?îÕ«—½½ý¸qãÜÝÝA„‹Á`8{öì›Ù]´Èĉ'NœXRR" ÷îÝ[UU5þü   î¾Ôe—Í¢øú믉íçÍ¢ …2™ÌÇÇœhŠÑ[¾wïÞóçÏã8þî»ïvßÅ×»F„gæÌ™ÄöæÍ›[Tà¡C‡V®\ >´BRR’D"ill<~üø–-[bccœœ `aa"|ÑU©T///b»Åiç΋ŒŒ´µµ?ZÇÎÎÎÎÎŽ’š‘‘QTT”žž®ÑhvíÚEÌ?¾ 7oÞT*•#FŒ^ŠØØX„N§Ãq|Á‚aaa£F²³³3çÛ6»Oz½þ»ï¾KNN†‰óÀ«A§Ó Æþýû£¢¢8ÎçŸÎçóKKKÅb1”„m"++ FÖ1½xüøñ¡µk×Êd2www‡cn‹ô™—ëêênݺ5oÞ